From c03e1cb4995048992e8991349fb4bde85a5236d4 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Tue, 7 Jun 2005 18:01:47 +0000 Subject: [PATCH] Sandbox of httpd/trunk/ for OpenSSL 0.9.7/mod_ssl fips integration development git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/fips-dev@188834 13f79535-47bb-0310-9956-ffa450edef68 --- trunk/.gdbinit | 277 + trunk/ABOUT_APACHE | 277 + trunk/Apache.dsw | 2006 ++ trunk/BuildBin.dsp | 97 + trunk/CHANGES | 14683 +++++++++++++++ trunk/INSTALL | 91 + trunk/InstallBin.dsp | 109 + trunk/LAYOUT | 201 + trunk/LICENSE | 673 + trunk/Makefile.in | 212 + trunk/Makefile.win | 804 + trunk/NOTICE | 17 + trunk/NWGNUmakefile | 397 + trunk/README | 90 + trunk/README.platforms | 98 + trunk/ROADMAP | 229 + trunk/STATUS | 511 + trunk/VERSIONING | 154 + trunk/acinclude.m4 | 530 + trunk/apachenw.mcp.zip | Bin 0 -> 189152 bytes trunk/build/NWGNUenvironment.inc | 320 + trunk/build/NWGNUhead.inc | 110 + trunk/build/NWGNUmakefile | 82 + trunk/build/NWGNUtail.inc | 320 + trunk/build/binbuild.sh | 206 + trunk/build/bsd_makefile | 33 + trunk/build/build-modules-c.awk | 81 + trunk/build/buildinfo.sh | 171 + trunk/build/config-stubs | 27 + trunk/build/default.pl | 496 + trunk/build/fastgen.sh | 89 + trunk/build/get-version.sh | 57 + trunk/build/httpd_roll_release | 136 + trunk/build/install-bindist.sh.in | 176 + trunk/build/install.sh | 123 + trunk/build/instdso.sh | 93 + trunk/build/library.mk | 21 + trunk/build/ltlib.mk | 22 + trunk/build/make_exports.awk | 163 + trunk/build/make_nw_export.awk | 90 + trunk/build/make_var_export.awk | 74 + trunk/build/mkconfNW.awk | 121 + trunk/build/mkdep.perl | 92 + trunk/build/mkdir.sh | 48 + trunk/build/nw_export.inc | 49 + trunk/build/nw_ver.awk | 39 + trunk/build/pkg/README | 16 + trunk/build/pkg/buildpkg.sh | 94 + trunk/build/pkg/pkginfo.in | 11 + trunk/build/prebuildNW.bat | 47 + trunk/build/program.mk | 22 + trunk/build/rpm/httpd.init | 126 + trunk/build/rpm/httpd.logrotate | 8 + trunk/build/rpm/httpd.spec.in | 519 + trunk/build/rules.mk.in | 235 + trunk/build/special.mk | 37 + trunk/build/sysv_makefile | 33 + trunk/build/win32/apache.ico | Bin 0 -> 1078 bytes trunk/build/win32/win32ver.awk | 138 + trunk/buildconf | 207 + trunk/config.layout | 324 + trunk/configure.in | 673 + trunk/docs/STATUS | 127 + trunk/docs/cgi-examples/printenv | 13 + trunk/docs/cgi-examples/test-cgi | 31 + trunk/docs/conf/charset.conv | 55 + trunk/docs/conf/extra/httpd-autoindex.conf.in | 93 + trunk/docs/conf/extra/httpd-dav.conf.in | 46 + trunk/docs/conf/extra/httpd-default.conf.in | 75 + trunk/docs/conf/extra/httpd-info.conf.in | 37 + trunk/docs/conf/extra/httpd-languages.conf.in | 139 + trunk/docs/conf/extra/httpd-manual.conf.in | 27 + trunk/docs/conf/extra/httpd-mpm.conf.in | 125 + .../extra/httpd-multilang-errordoc.conf.in | 52 + trunk/docs/conf/extra/httpd-ssl.conf.in | 231 + trunk/docs/conf/extra/httpd-userdir.conf.in | 28 + trunk/docs/conf/extra/httpd-vhosts.conf.in | 45 + trunk/docs/conf/httpd-win.conf | 489 + trunk/docs/conf/httpd.conf.in | 418 + trunk/docs/conf/magic | 382 + trunk/docs/conf/mime.types | 592 + trunk/docs/docroot/apache_pb.gif | Bin 0 -> 2326 bytes trunk/docs/docroot/apache_pb.png | Bin 0 -> 1385 bytes trunk/docs/docroot/apache_pb2.gif | Bin 0 -> 2414 bytes trunk/docs/docroot/apache_pb2.png | Bin 0 -> 1463 bytes trunk/docs/docroot/apache_pb2_ani.gif | Bin 0 -> 2160 bytes trunk/docs/docroot/index.html | 1 + trunk/docs/doxygen.conf | 52 + trunk/docs/error/HTTP_BAD_GATEWAY.html.var | 253 + trunk/docs/error/HTTP_BAD_REQUEST.html.var | 186 + trunk/docs/error/HTTP_FORBIDDEN.html.var | 326 + trunk/docs/error/HTTP_GONE.html.var | 370 + .../error/HTTP_INTERNAL_SERVER_ERROR.html.var | 395 + .../docs/error/HTTP_LENGTH_REQUIRED.html.var | 192 + .../error/HTTP_METHOD_NOT_ALLOWED.html.var | 186 + trunk/docs/error/HTTP_NOT_FOUND.html.var | 379 + .../docs/error/HTTP_NOT_IMPLEMENTED.html.var | 176 + .../error/HTTP_PRECONDITION_FAILED.html.var | 180 + .../HTTP_REQUEST_ENTITY_TOO_LARGE.html.var | 198 + .../docs/error/HTTP_REQUEST_TIME_OUT.html.var | 190 + .../error/HTTP_REQUEST_URI_TOO_LARGE.html.var | 190 + .../error/HTTP_SERVICE_UNAVAILABLE.html.var | 205 + trunk/docs/error/HTTP_UNAUTHORIZED.html.var | 292 + .../HTTP_UNSUPPORTED_MEDIA_TYPE.html.var | 176 + .../error/HTTP_VARIANT_ALSO_VARIES.html.var | 194 + trunk/docs/error/README | 36 + trunk/docs/error/contact.html.var | 104 + trunk/docs/error/include/bottom.html | 14 + trunk/docs/error/include/spacer.html | 2 + trunk/docs/error/include/top.html | 24 + trunk/docs/icons/README | 158 + trunk/docs/icons/a.gif | Bin 0 -> 246 bytes trunk/docs/icons/a.png | Bin 0 -> 293 bytes trunk/docs/icons/alert.black.gif | Bin 0 -> 242 bytes trunk/docs/icons/alert.black.png | Bin 0 -> 279 bytes trunk/docs/icons/alert.red.gif | Bin 0 -> 247 bytes trunk/docs/icons/alert.red.png | Bin 0 -> 298 bytes trunk/docs/icons/apache_pb.gif | Bin 0 -> 2326 bytes trunk/docs/icons/apache_pb.png | Bin 0 -> 1385 bytes trunk/docs/icons/apache_pb2.gif | Bin 0 -> 2414 bytes trunk/docs/icons/apache_pb2.png | Bin 0 -> 1463 bytes trunk/docs/icons/apache_pb2_ani.gif | Bin 0 -> 2160 bytes trunk/docs/icons/back.gif | Bin 0 -> 216 bytes trunk/docs/icons/back.png | Bin 0 -> 284 bytes trunk/docs/icons/ball.gray.gif | Bin 0 -> 233 bytes trunk/docs/icons/ball.gray.png | Bin 0 -> 277 bytes trunk/docs/icons/ball.red.gif | Bin 0 -> 205 bytes trunk/docs/icons/ball.red.png | Bin 0 -> 265 bytes trunk/docs/icons/binary.gif | Bin 0 -> 246 bytes trunk/docs/icons/binary.png | Bin 0 -> 296 bytes trunk/docs/icons/binhex.gif | Bin 0 -> 246 bytes trunk/docs/icons/binhex.png | Bin 0 -> 304 bytes trunk/docs/icons/blank.gif | Bin 0 -> 148 bytes trunk/docs/icons/blank.png | Bin 0 -> 195 bytes trunk/docs/icons/bomb.gif | Bin 0 -> 308 bytes trunk/docs/icons/bomb.png | Bin 0 -> 356 bytes trunk/docs/icons/box1.gif | Bin 0 -> 251 bytes trunk/docs/icons/box1.png | Bin 0 -> 308 bytes trunk/docs/icons/box2.gif | Bin 0 -> 268 bytes trunk/docs/icons/box2.png | Bin 0 -> 322 bytes trunk/docs/icons/broken.gif | Bin 0 -> 247 bytes trunk/docs/icons/broken.png | Bin 0 -> 305 bytes trunk/docs/icons/burst.gif | Bin 0 -> 235 bytes trunk/docs/icons/burst.png | Bin 0 -> 314 bytes trunk/docs/icons/c.gif | Bin 0 -> 242 bytes trunk/docs/icons/c.png | Bin 0 -> 285 bytes trunk/docs/icons/comp.blue.gif | Bin 0 -> 251 bytes trunk/docs/icons/comp.blue.png | Bin 0 -> 313 bytes trunk/docs/icons/comp.gray.gif | Bin 0 -> 246 bytes trunk/docs/icons/comp.gray.png | Bin 0 -> 304 bytes trunk/docs/icons/compressed.gif | Bin 0 -> 1038 bytes trunk/docs/icons/compressed.png | Bin 0 -> 315 bytes trunk/docs/icons/continued.gif | Bin 0 -> 214 bytes trunk/docs/icons/continued.png | Bin 0 -> 272 bytes trunk/docs/icons/dir.gif | Bin 0 -> 225 bytes trunk/docs/icons/dir.png | Bin 0 -> 272 bytes trunk/docs/icons/diskimg.gif | Bin 0 -> 167 bytes trunk/docs/icons/diskimg.png | Bin 0 -> 202 bytes trunk/docs/icons/down.gif | Bin 0 -> 163 bytes trunk/docs/icons/down.png | Bin 0 -> 232 bytes trunk/docs/icons/dvi.gif | Bin 0 -> 238 bytes trunk/docs/icons/dvi.png | Bin 0 -> 290 bytes trunk/docs/icons/f.gif | Bin 0 -> 236 bytes trunk/docs/icons/f.png | Bin 0 -> 282 bytes trunk/docs/icons/folder.gif | Bin 0 -> 225 bytes trunk/docs/icons/folder.open.gif | Bin 0 -> 242 bytes trunk/docs/icons/folder.open.png | Bin 0 -> 305 bytes trunk/docs/icons/folder.png | Bin 0 -> 272 bytes trunk/docs/icons/folder.sec.gif | Bin 0 -> 243 bytes trunk/docs/icons/folder.sec.png | Bin 0 -> 290 bytes trunk/docs/icons/forward.gif | Bin 0 -> 219 bytes trunk/docs/icons/forward.png | Bin 0 -> 284 bytes trunk/docs/icons/generic.gif | Bin 0 -> 221 bytes trunk/docs/icons/generic.png | Bin 0 -> 260 bytes trunk/docs/icons/generic.red.gif | Bin 0 -> 220 bytes trunk/docs/icons/generic.red.png | Bin 0 -> 262 bytes trunk/docs/icons/generic.sec.gif | Bin 0 -> 249 bytes trunk/docs/icons/generic.sec.png | Bin 0 -> 279 bytes trunk/docs/icons/hand.right.gif | Bin 0 -> 217 bytes trunk/docs/icons/hand.right.png | Bin 0 -> 280 bytes trunk/docs/icons/hand.up.gif | Bin 0 -> 223 bytes trunk/docs/icons/hand.up.png | Bin 0 -> 280 bytes trunk/docs/icons/icon.sheet.gif | Bin 0 -> 11977 bytes trunk/docs/icons/icon.sheet.png | Bin 0 -> 8898 bytes trunk/docs/icons/image1.gif | Bin 0 -> 274 bytes trunk/docs/icons/image1.png | Bin 0 -> 307 bytes trunk/docs/icons/image2.gif | Bin 0 -> 309 bytes trunk/docs/icons/image2.png | Bin 0 -> 355 bytes trunk/docs/icons/image3.gif | Bin 0 -> 286 bytes trunk/docs/icons/image3.png | Bin 0 -> 323 bytes trunk/docs/icons/index.gif | Bin 0 -> 268 bytes trunk/docs/icons/index.png | Bin 0 -> 316 bytes trunk/docs/icons/layout.gif | Bin 0 -> 276 bytes trunk/docs/icons/layout.png | Bin 0 -> 306 bytes trunk/docs/icons/left.gif | Bin 0 -> 172 bytes trunk/docs/icons/left.png | Bin 0 -> 235 bytes trunk/docs/icons/link.gif | Bin 0 -> 249 bytes trunk/docs/icons/link.png | Bin 0 -> 297 bytes trunk/docs/icons/movie.gif | Bin 0 -> 243 bytes trunk/docs/icons/movie.png | Bin 0 -> 258 bytes trunk/docs/icons/p.gif | Bin 0 -> 237 bytes trunk/docs/icons/p.png | Bin 0 -> 284 bytes trunk/docs/icons/patch.gif | Bin 0 -> 251 bytes trunk/docs/icons/patch.png | Bin 0 -> 295 bytes trunk/docs/icons/pdf.gif | Bin 0 -> 249 bytes trunk/docs/icons/pdf.png | Bin 0 -> 289 bytes trunk/docs/icons/pie0.gif | Bin 0 -> 188 bytes trunk/docs/icons/pie0.png | Bin 0 -> 242 bytes trunk/docs/icons/pie1.gif | Bin 0 -> 198 bytes trunk/docs/icons/pie1.png | Bin 0 -> 261 bytes trunk/docs/icons/pie2.gif | Bin 0 -> 198 bytes trunk/docs/icons/pie2.png | Bin 0 -> 253 bytes trunk/docs/icons/pie3.gif | Bin 0 -> 191 bytes trunk/docs/icons/pie3.png | Bin 0 -> 256 bytes trunk/docs/icons/pie4.gif | Bin 0 -> 193 bytes trunk/docs/icons/pie4.png | Bin 0 -> 239 bytes trunk/docs/icons/pie5.gif | Bin 0 -> 189 bytes trunk/docs/icons/pie5.png | Bin 0 -> 258 bytes trunk/docs/icons/pie6.gif | Bin 0 -> 186 bytes trunk/docs/icons/pie6.png | Bin 0 -> 253 bytes trunk/docs/icons/pie7.gif | Bin 0 -> 185 bytes trunk/docs/icons/pie7.png | Bin 0 -> 258 bytes trunk/docs/icons/pie8.gif | Bin 0 -> 173 bytes trunk/docs/icons/pie8.png | Bin 0 -> 233 bytes trunk/docs/icons/portal.gif | Bin 0 -> 254 bytes trunk/docs/icons/portal.png | Bin 0 -> 303 bytes trunk/docs/icons/ps.gif | Bin 0 -> 244 bytes trunk/docs/icons/ps.png | Bin 0 -> 287 bytes trunk/docs/icons/quill.gif | Bin 0 -> 267 bytes trunk/docs/icons/quill.png | Bin 0 -> 315 bytes trunk/docs/icons/right.gif | Bin 0 -> 172 bytes trunk/docs/icons/right.png | Bin 0 -> 233 bytes trunk/docs/icons/screw1.gif | Bin 0 -> 258 bytes trunk/docs/icons/screw1.png | Bin 0 -> 312 bytes trunk/docs/icons/screw2.gif | Bin 0 -> 263 bytes trunk/docs/icons/screw2.png | Bin 0 -> 318 bytes trunk/docs/icons/script.gif | Bin 0 -> 242 bytes trunk/docs/icons/script.png | Bin 0 -> 275 bytes trunk/docs/icons/small/README.txt | 6 + trunk/docs/icons/small/back.gif | Bin 0 -> 129 bytes trunk/docs/icons/small/back.png | Bin 0 -> 238 bytes trunk/docs/icons/small/binary.gif | Bin 0 -> 134 bytes trunk/docs/icons/small/binary.png | Bin 0 -> 242 bytes trunk/docs/icons/small/binhex.gif | Bin 0 -> 131 bytes trunk/docs/icons/small/binhex.png | Bin 0 -> 248 bytes trunk/docs/icons/small/blank.gif | Bin 0 -> 55 bytes trunk/docs/icons/small/blank.png | Bin 0 -> 90 bytes trunk/docs/icons/small/broken.gif | Bin 0 -> 139 bytes trunk/docs/icons/small/broken.png | Bin 0 -> 254 bytes trunk/docs/icons/small/burst.gif | Bin 0 -> 128 bytes trunk/docs/icons/small/burst.png | Bin 0 -> 194 bytes trunk/docs/icons/small/comp1.gif | Bin 0 -> 130 bytes trunk/docs/icons/small/comp1.png | Bin 0 -> 197 bytes trunk/docs/icons/small/comp2.gif | Bin 0 -> 131 bytes trunk/docs/icons/small/comp2.png | Bin 0 -> 194 bytes trunk/docs/icons/small/compressed.gif | Bin 0 -> 128 bytes trunk/docs/icons/small/compressed.png | Bin 0 -> 189 bytes trunk/docs/icons/small/continued.gif | Bin 0 -> 114 bytes trunk/docs/icons/small/continued.png | Bin 0 -> 214 bytes trunk/docs/icons/small/dir.gif | Bin 0 -> 132 bytes trunk/docs/icons/small/dir.png | Bin 0 -> 175 bytes trunk/docs/icons/small/dir2.gif | Bin 0 -> 122 bytes trunk/docs/icons/small/dir2.png | Bin 0 -> 161 bytes trunk/docs/icons/small/doc.gif | Bin 0 -> 191 bytes trunk/docs/icons/small/doc.png | Bin 0 -> 269 bytes trunk/docs/icons/small/forward.gif | Bin 0 -> 125 bytes trunk/docs/icons/small/forward.png | Bin 0 -> 244 bytes trunk/docs/icons/small/generic.gif | Bin 0 -> 116 bytes trunk/docs/icons/small/generic.png | Bin 0 -> 182 bytes trunk/docs/icons/small/generic2.gif | Bin 0 -> 127 bytes trunk/docs/icons/small/generic2.png | Bin 0 -> 158 bytes trunk/docs/icons/small/generic3.gif | Bin 0 -> 113 bytes trunk/docs/icons/small/generic3.png | Bin 0 -> 147 bytes trunk/docs/icons/small/image.gif | Bin 0 -> 126 bytes trunk/docs/icons/small/image.png | Bin 0 -> 178 bytes trunk/docs/icons/small/image2.gif | Bin 0 -> 138 bytes trunk/docs/icons/small/image2.png | Bin 0 -> 186 bytes trunk/docs/icons/small/index.gif | Bin 0 -> 145 bytes trunk/docs/icons/small/index.png | Bin 0 -> 206 bytes trunk/docs/icons/small/key.gif | Bin 0 -> 187 bytes trunk/docs/icons/small/key.png | Bin 0 -> 254 bytes trunk/docs/icons/small/movie.gif | Bin 0 -> 134 bytes trunk/docs/icons/small/movie.png | Bin 0 -> 202 bytes trunk/docs/icons/small/patch.gif | Bin 0 -> 182 bytes trunk/docs/icons/small/patch.png | Bin 0 -> 250 bytes trunk/docs/icons/small/ps.gif | Bin 0 -> 184 bytes trunk/docs/icons/small/ps.png | Bin 0 -> 254 bytes trunk/docs/icons/small/rainbow.gif | Bin 0 -> 3811 bytes trunk/docs/icons/small/rainbow.png | Bin 0 -> 2418 bytes trunk/docs/icons/small/sound.gif | Bin 0 -> 130 bytes trunk/docs/icons/small/sound.png | Bin 0 -> 176 bytes trunk/docs/icons/small/sound2.gif | Bin 0 -> 119 bytes trunk/docs/icons/small/sound2.png | Bin 0 -> 236 bytes trunk/docs/icons/small/tar.gif | Bin 0 -> 132 bytes trunk/docs/icons/small/tar.png | Bin 0 -> 227 bytes trunk/docs/icons/small/text.gif | Bin 0 -> 128 bytes trunk/docs/icons/small/text.png | Bin 0 -> 202 bytes trunk/docs/icons/small/transfer.gif | Bin 0 -> 124 bytes trunk/docs/icons/small/transfer.png | Bin 0 -> 186 bytes trunk/docs/icons/small/unknown.gif | Bin 0 -> 131 bytes trunk/docs/icons/small/unknown.png | Bin 0 -> 226 bytes trunk/docs/icons/small/uu.gif | Bin 0 -> 125 bytes trunk/docs/icons/small/uu.png | Bin 0 -> 217 bytes trunk/docs/icons/sound1.gif | Bin 0 -> 248 bytes trunk/docs/icons/sound1.png | Bin 0 -> 310 bytes trunk/docs/icons/sound2.gif | Bin 0 -> 221 bytes trunk/docs/icons/sound2.png | Bin 0 -> 297 bytes trunk/docs/icons/sphere1.gif | Bin 0 -> 285 bytes trunk/docs/icons/sphere1.png | Bin 0 -> 326 bytes trunk/docs/icons/sphere2.gif | Bin 0 -> 264 bytes trunk/docs/icons/sphere2.png | Bin 0 -> 322 bytes trunk/docs/icons/tar.gif | Bin 0 -> 219 bytes trunk/docs/icons/tar.png | Bin 0 -> 261 bytes trunk/docs/icons/tex.gif | Bin 0 -> 251 bytes trunk/docs/icons/tex.png | Bin 0 -> 295 bytes trunk/docs/icons/text.gif | Bin 0 -> 229 bytes trunk/docs/icons/text.png | Bin 0 -> 273 bytes trunk/docs/icons/transfer.gif | Bin 0 -> 242 bytes trunk/docs/icons/transfer.png | Bin 0 -> 319 bytes trunk/docs/icons/unknown.gif | Bin 0 -> 245 bytes trunk/docs/icons/unknown.png | Bin 0 -> 291 bytes trunk/docs/icons/up.gif | Bin 0 -> 164 bytes trunk/docs/icons/up.png | Bin 0 -> 234 bytes trunk/docs/icons/uu.gif | Bin 0 -> 236 bytes trunk/docs/icons/uu.png | Bin 0 -> 280 bytes trunk/docs/icons/uuencoded.gif | Bin 0 -> 236 bytes trunk/docs/icons/uuencoded.png | Bin 0 -> 280 bytes trunk/docs/icons/world1.gif | Bin 0 -> 228 bytes trunk/docs/icons/world1.png | Bin 0 -> 315 bytes trunk/docs/icons/world2.gif | Bin 0 -> 261 bytes trunk/docs/icons/world2.png | Bin 0 -> 339 bytes trunk/docs/man/ab.8 | 125 + trunk/docs/man/apachectl.8 | 92 + trunk/docs/man/apxs.8 | 244 + trunk/docs/man/dbmmanage.1 | 118 + trunk/docs/man/htcacheclean.8 | 74 + trunk/docs/man/htdbm.1 | 169 + trunk/docs/man/htdigest.1 | 57 + trunk/docs/man/htpasswd.1 | 146 + trunk/docs/man/httpd.8 | 119 + trunk/docs/man/logresolve.8 | 51 + trunk/docs/man/rotatelogs.8 | 133 + trunk/docs/man/suexec.8 | 48 + trunk/docs/manual/LICENSE | 202 + trunk/docs/manual/bind.html | 19 + trunk/docs/manual/bind.html.de | 164 + trunk/docs/manual/bind.html.en | 160 + trunk/docs/manual/bind.html.fr | 197 + trunk/docs/manual/bind.html.ja.euc-jp | 175 + trunk/docs/manual/bind.html.ko.euc-kr | 151 + trunk/docs/manual/bind.xml | 163 + trunk/docs/manual/bind.xml.de | 170 + trunk/docs/manual/bind.xml.fr | 194 + trunk/docs/manual/bind.xml.ja | 173 + trunk/docs/manual/bind.xml.ko | 152 + trunk/docs/manual/bind.xml.meta | 15 + trunk/docs/manual/configuring.html | 15 + trunk/docs/manual/configuring.html.de | 183 + trunk/docs/manual/configuring.html.en | 167 + trunk/docs/manual/configuring.html.ja.euc-jp | 169 + trunk/docs/manual/configuring.html.ko.euc-kr | 150 + trunk/docs/manual/configuring.xml | 199 + trunk/docs/manual/configuring.xml.de | 212 + trunk/docs/manual/configuring.xml.ja | 200 + trunk/docs/manual/configuring.xml.ko | 183 + trunk/docs/manual/configuring.xml.meta | 14 + trunk/docs/manual/content-negotiation.html | 11 + trunk/docs/manual/content-negotiation.html.en | 678 + .../manual/content-negotiation.html.ja.euc-jp | 727 + .../manual/content-negotiation.html.ko.euc-kr | 608 + trunk/docs/manual/content-negotiation.xml | 676 + trunk/docs/manual/content-negotiation.xml.ja | 714 + trunk/docs/manual/content-negotiation.xml.ko | 603 + .../docs/manual/content-negotiation.xml.meta | 13 + trunk/docs/manual/custom-error.html | 15 + trunk/docs/manual/custom-error.html.en | 204 + trunk/docs/manual/custom-error.html.es | 219 + trunk/docs/manual/custom-error.html.ja.euc-jp | 197 + trunk/docs/manual/custom-error.html.ko.euc-kr | 198 + trunk/docs/manual/custom-error.xml | 192 + trunk/docs/manual/custom-error.xml.es | 209 + trunk/docs/manual/custom-error.xml.ja | 186 + trunk/docs/manual/custom-error.xml.ko | 186 + trunk/docs/manual/custom-error.xml.meta | 14 + trunk/docs/manual/developer/API.html | 3 + trunk/docs/manual/developer/API.html.en | 1222 ++ trunk/docs/manual/developer/API.xml | 1238 ++ trunk/docs/manual/developer/API.xml.meta | 11 + trunk/docs/manual/developer/debugging.html | 3 + trunk/docs/manual/developer/debugging.html.en | 196 + trunk/docs/manual/developer/debugging.xml | 193 + .../docs/manual/developer/debugging.xml.meta | 11 + trunk/docs/manual/developer/documenting.html | 3 + .../docs/manual/developer/documenting.html.en | 84 + trunk/docs/manual/developer/documenting.xml | 84 + .../manual/developer/documenting.xml.meta | 11 + trunk/docs/manual/developer/filters.html | 3 + trunk/docs/manual/developer/filters.html.en | 210 + trunk/docs/manual/developer/filters.xml | 209 + trunk/docs/manual/developer/filters.xml.meta | 11 + trunk/docs/manual/developer/hooks.html | 3 + trunk/docs/manual/developer/hooks.html.en | 239 + trunk/docs/manual/developer/hooks.xml | 236 + trunk/docs/manual/developer/hooks.xml.meta | 11 + trunk/docs/manual/developer/index.html | 3 + trunk/docs/manual/developer/index.html.en | 73 + trunk/docs/manual/developer/index.xml | 76 + trunk/docs/manual/developer/index.xml.meta | 11 + trunk/docs/manual/developer/modules.html | 7 + trunk/docs/manual/developer/modules.html.en | 273 + .../manual/developer/modules.html.ja.euc-jp | 274 + trunk/docs/manual/developer/modules.xml | 272 + trunk/docs/manual/developer/modules.xml.ja | 272 + trunk/docs/manual/developer/modules.xml.meta | 12 + trunk/docs/manual/developer/request.html | 3 + trunk/docs/manual/developer/request.html.en | 260 + trunk/docs/manual/developer/request.xml | 258 + trunk/docs/manual/developer/request.xml.meta | 11 + .../docs/manual/developer/thread_safety.html | 3 + .../manual/developer/thread_safety.html.en | 285 + trunk/docs/manual/developer/thread_safety.xml | 291 + .../manual/developer/thread_safety.xml.meta | 11 + trunk/docs/manual/dns-caveats.html | 11 + trunk/docs/manual/dns-caveats.html.en | 239 + trunk/docs/manual/dns-caveats.html.ja.euc-jp | 241 + trunk/docs/manual/dns-caveats.html.ko.euc-kr | 223 + trunk/docs/manual/dns-caveats.xml | 228 + trunk/docs/manual/dns-caveats.xml.ja | 231 + trunk/docs/manual/dns-caveats.xml.ko | 209 + trunk/docs/manual/dns-caveats.xml.meta | 13 + trunk/docs/manual/dso.html | 11 + trunk/docs/manual/dso.html.en | 315 + trunk/docs/manual/dso.html.ja.euc-jp | 296 + trunk/docs/manual/dso.html.ko.euc-kr | 276 + trunk/docs/manual/dso.xml | 314 + trunk/docs/manual/dso.xml.ja | 294 + trunk/docs/manual/dso.xml.ko | 273 + trunk/docs/manual/dso.xml.meta | 13 + trunk/docs/manual/env.html | 11 + trunk/docs/manual/env.html.en | 405 + trunk/docs/manual/env.html.ja.euc-jp | 393 + trunk/docs/manual/env.html.ko.euc-kr | 373 + trunk/docs/manual/env.xml | 439 + trunk/docs/manual/env.xml.ja | 426 + trunk/docs/manual/env.xml.ko | 410 + trunk/docs/manual/env.xml.meta | 13 + trunk/docs/manual/faq/all_in_one.html | 11 + trunk/docs/manual/faq/all_in_one.html.en | 202 + .../docs/manual/faq/all_in_one.html.ja.euc-jp | 206 + .../docs/manual/faq/all_in_one.html.ko.euc-kr | 207 + trunk/docs/manual/faq/all_in_one.xml | 44 + trunk/docs/manual/faq/all_in_one.xml.ja | 46 + trunk/docs/manual/faq/all_in_one.xml.ko | 46 + trunk/docs/manual/faq/all_in_one.xml.meta | 13 + trunk/docs/manual/faq/categories.xml | 23 + trunk/docs/manual/faq/categories.xml.ja | 23 + trunk/docs/manual/faq/categories.xml.ko | 24 + trunk/docs/manual/faq/error.html | 11 + trunk/docs/manual/faq/error.html.en | 85 + trunk/docs/manual/faq/error.html.ja.euc-jp | 91 + trunk/docs/manual/faq/error.html.ko.euc-kr | 84 + trunk/docs/manual/faq/error.xml | 84 + trunk/docs/manual/faq/error.xml.ja | 89 + trunk/docs/manual/faq/error.xml.ko | 84 + trunk/docs/manual/faq/error.xml.meta | 13 + trunk/docs/manual/faq/index.html | 11 + trunk/docs/manual/faq/index.html.en | 49 + trunk/docs/manual/faq/index.html.ja.euc-jp | 49 + trunk/docs/manual/faq/index.html.ko.euc-kr | 47 + trunk/docs/manual/faq/index.xml | 47 + trunk/docs/manual/faq/index.xml.ja | 48 + trunk/docs/manual/faq/index.xml.ko | 47 + trunk/docs/manual/faq/index.xml.meta | 13 + trunk/docs/manual/faq/support.html | 11 + trunk/docs/manual/faq/support.html.en | 134 + trunk/docs/manual/faq/support.html.ja.euc-jp | 132 + trunk/docs/manual/faq/support.html.ko.euc-kr | 140 + trunk/docs/manual/faq/support.xml | 135 + trunk/docs/manual/faq/support.xml.ja | 134 + trunk/docs/manual/faq/support.xml.ko | 141 + trunk/docs/manual/faq/support.xml.meta | 13 + trunk/docs/manual/filter.html | 19 + trunk/docs/manual/filter.html.en | 80 + trunk/docs/manual/filter.html.es | 77 + trunk/docs/manual/filter.html.fr | 82 + trunk/docs/manual/filter.html.ja.euc-jp | 80 + trunk/docs/manual/filter.html.ko.euc-kr | 78 + trunk/docs/manual/filter.xml | 86 + trunk/docs/manual/filter.xml.es | 90 + trunk/docs/manual/filter.xml.fr | 88 + trunk/docs/manual/filter.xml.ja | 90 + trunk/docs/manual/filter.xml.ko | 84 + trunk/docs/manual/filter.xml.meta | 15 + trunk/docs/manual/glossary.html | 15 + trunk/docs/manual/glossary.html.de | 539 + trunk/docs/manual/glossary.html.en | 448 + trunk/docs/manual/glossary.html.es | 395 + trunk/docs/manual/glossary.html.ko.euc-kr | 364 + trunk/docs/manual/glossary.xml | 465 + trunk/docs/manual/glossary.xml.de | 567 + trunk/docs/manual/glossary.xml.es | 431 + trunk/docs/manual/glossary.xml.ko | 376 + trunk/docs/manual/glossary.xml.meta | 14 + trunk/docs/manual/handler.html | 15 + trunk/docs/manual/handler.html.en | 153 + trunk/docs/manual/handler.html.es | 166 + trunk/docs/manual/handler.html.ja.euc-jp | 157 + trunk/docs/manual/handler.html.ko.euc-kr | 149 + trunk/docs/manual/handler.xml | 163 + trunk/docs/manual/handler.xml.es | 173 + trunk/docs/manual/handler.xml.ja | 162 + trunk/docs/manual/handler.xml.ko | 157 + trunk/docs/manual/handler.xml.meta | 14 + trunk/docs/manual/howto/auth.html | 11 + trunk/docs/manual/howto/auth.html.en | 352 + trunk/docs/manual/howto/auth.html.ja.euc-jp | 384 + trunk/docs/manual/howto/auth.html.ko.euc-kr | 323 + trunk/docs/manual/howto/auth.xml | 364 + trunk/docs/manual/howto/auth.xml.ja | 388 + trunk/docs/manual/howto/auth.xml.ko | 334 + trunk/docs/manual/howto/auth.xml.meta | 13 + trunk/docs/manual/howto/cgi.html | 11 + trunk/docs/manual/howto/cgi.html.en | 555 + trunk/docs/manual/howto/cgi.html.ja.euc-jp | 544 + trunk/docs/manual/howto/cgi.html.ko.euc-kr | 503 + trunk/docs/manual/howto/cgi.xml | 568 + trunk/docs/manual/howto/cgi.xml.ja | 553 + trunk/docs/manual/howto/cgi.xml.ko | 519 + trunk/docs/manual/howto/cgi.xml.meta | 13 + trunk/docs/manual/howto/htaccess.html | 15 + trunk/docs/manual/howto/htaccess.html.en | 385 + .../docs/manual/howto/htaccess.html.ja.euc-jp | 383 + .../docs/manual/howto/htaccess.html.ko.euc-kr | 333 + trunk/docs/manual/howto/htaccess.html.pt-br | 375 + trunk/docs/manual/howto/htaccess.xml | 409 + trunk/docs/manual/howto/htaccess.xml.ja | 408 + trunk/docs/manual/howto/htaccess.xml.ko | 351 + trunk/docs/manual/howto/htaccess.xml.meta | 14 + trunk/docs/manual/howto/htaccess.xml.pt-br | 397 + trunk/docs/manual/howto/index.html | 11 + trunk/docs/manual/howto/index.html.en | 105 + trunk/docs/manual/howto/index.html.ja.euc-jp | 102 + trunk/docs/manual/howto/index.html.ko.euc-kr | 107 + trunk/docs/manual/howto/index.xml | 104 + trunk/docs/manual/howto/index.xml.ja | 101 + trunk/docs/manual/howto/index.xml.ko | 104 + trunk/docs/manual/howto/index.xml.meta | 13 + trunk/docs/manual/howto/public_html.html | 11 + trunk/docs/manual/howto/public_html.html.en | 161 + .../manual/howto/public_html.html.ja.euc-jp | 155 + .../manual/howto/public_html.html.ko.euc-kr | 156 + trunk/docs/manual/howto/public_html.xml | 164 + trunk/docs/manual/howto/public_html.xml.ja | 158 + trunk/docs/manual/howto/public_html.xml.ko | 161 + trunk/docs/manual/howto/public_html.xml.meta | 13 + trunk/docs/manual/howto/ssi.html | 11 + trunk/docs/manual/howto/ssi.html.en | 486 + trunk/docs/manual/howto/ssi.html.ja.euc-jp | 481 + trunk/docs/manual/howto/ssi.html.ko.euc-kr | 426 + trunk/docs/manual/howto/ssi.xml | 489 + trunk/docs/manual/howto/ssi.xml.ja | 481 + trunk/docs/manual/howto/ssi.xml.ko | 428 + trunk/docs/manual/howto/ssi.xml.meta | 13 + trunk/docs/manual/images/apache_header.gif | Bin 0 -> 4084 bytes trunk/docs/manual/images/custom_errordocs.png | Bin 0 -> 22907 bytes trunk/docs/manual/images/down.gif | Bin 0 -> 56 bytes trunk/docs/manual/images/favicon.ico | Bin 0 -> 1078 bytes trunk/docs/manual/images/feather.gif | Bin 0 -> 6471 bytes trunk/docs/manual/images/feather.png | Bin 0 -> 6345 bytes trunk/docs/manual/images/home.gif | Bin 0 -> 1465 bytes trunk/docs/manual/images/index.gif | Bin 0 -> 1540 bytes trunk/docs/manual/images/left.gif | Bin 0 -> 60 bytes trunk/docs/manual/images/mod_filter_new.gif | Bin 0 -> 2392 bytes trunk/docs/manual/images/mod_filter_old.gif | Bin 0 -> 1230 bytes trunk/docs/manual/images/mod_rewrite_fig1.gif | Bin 0 -> 3525 bytes trunk/docs/manual/images/mod_rewrite_fig1.png | Bin 0 -> 5597 bytes trunk/docs/manual/images/mod_rewrite_fig2.gif | Bin 0 -> 2553 bytes trunk/docs/manual/images/mod_rewrite_fig2.png | Bin 0 -> 4144 bytes trunk/docs/manual/images/pixel.gif | Bin 0 -> 61 bytes trunk/docs/manual/images/right.gif | Bin 0 -> 59 bytes trunk/docs/manual/images/ssl_intro_fig1.gif | Bin 0 -> 5738 bytes trunk/docs/manual/images/ssl_intro_fig1.png | Bin 0 -> 7325 bytes trunk/docs/manual/images/ssl_intro_fig2.gif | Bin 0 -> 2700 bytes trunk/docs/manual/images/ssl_intro_fig2.png | Bin 0 -> 3190 bytes trunk/docs/manual/images/ssl_intro_fig3.gif | Bin 0 -> 4020 bytes trunk/docs/manual/images/ssl_intro_fig3.png | Bin 0 -> 5487 bytes trunk/docs/manual/images/sub.gif | Bin 0 -> 6083 bytes trunk/docs/manual/images/up.gif | Bin 0 -> 57 bytes trunk/docs/manual/index.html | 27 + trunk/docs/manual/index.html.de | 101 + trunk/docs/manual/index.html.en | 100 + trunk/docs/manual/index.html.es | 108 + trunk/docs/manual/index.html.fr | 101 + trunk/docs/manual/index.html.ja.euc-jp | 100 + trunk/docs/manual/index.html.ko.euc-kr | 101 + trunk/docs/manual/index.html.pt-br | 100 + trunk/docs/manual/index.xml | 91 + trunk/docs/manual/index.xml.de | 92 + trunk/docs/manual/index.xml.es | 96 + trunk/docs/manual/index.xml.fr | 90 + trunk/docs/manual/index.xml.ja | 91 + trunk/docs/manual/index.xml.ko | 90 + trunk/docs/manual/index.xml.meta | 17 + trunk/docs/manual/index.xml.pt-br | 89 + trunk/docs/manual/install.html | 23 + trunk/docs/manual/install.html.de | 407 + trunk/docs/manual/install.html.en | 383 + trunk/docs/manual/install.html.es | 438 + trunk/docs/manual/install.html.fr | 429 + trunk/docs/manual/install.html.ja.euc-jp | 395 + trunk/docs/manual/install.html.ko.euc-kr | 360 + trunk/docs/manual/install.xml | 382 + trunk/docs/manual/install.xml.de | 399 + trunk/docs/manual/install.xml.es | 429 + trunk/docs/manual/install.xml.fr | 421 + trunk/docs/manual/install.xml.ja | 389 + trunk/docs/manual/install.xml.ko | 353 + trunk/docs/manual/install.xml.meta | 16 + trunk/docs/manual/invoking.html | 19 + trunk/docs/manual/invoking.html.de | 154 + trunk/docs/manual/invoking.html.en | 149 + trunk/docs/manual/invoking.html.es | 166 + trunk/docs/manual/invoking.html.ja.euc-jp | 159 + trunk/docs/manual/invoking.html.ko.euc-kr | 138 + trunk/docs/manual/invoking.xml | 144 + trunk/docs/manual/invoking.xml.de | 152 + trunk/docs/manual/invoking.xml.es | 161 + trunk/docs/manual/invoking.xml.ja | 151 + trunk/docs/manual/invoking.xml.ko | 132 + trunk/docs/manual/invoking.xml.meta | 15 + trunk/docs/manual/license.html | 3 + trunk/docs/manual/license.html.en | 238 + trunk/docs/manual/license.xml | 240 + trunk/docs/manual/license.xml.meta | 11 + trunk/docs/manual/logs.html | 11 + trunk/docs/manual/logs.html.en | 583 + trunk/docs/manual/logs.html.ja.euc-jp | 551 + trunk/docs/manual/logs.html.ko.euc-kr | 521 + trunk/docs/manual/logs.xml | 625 + trunk/docs/manual/logs.xml.ja | 585 + trunk/docs/manual/logs.xml.ko | 557 + trunk/docs/manual/logs.xml.meta | 13 + trunk/docs/manual/misc/index.html | 7 + trunk/docs/manual/misc/index.html.en | 80 + trunk/docs/manual/misc/index.html.ko.euc-kr | 76 + trunk/docs/manual/misc/index.xml | 78 + trunk/docs/manual/misc/index.xml.ko | 75 + trunk/docs/manual/misc/index.xml.meta | 12 + trunk/docs/manual/misc/perf-tuning.html | 7 + trunk/docs/manual/misc/perf-tuning.html.en | 1056 ++ .../manual/misc/perf-tuning.html.ko.euc-kr | 976 + trunk/docs/manual/misc/perf-tuning.xml | 1113 ++ trunk/docs/manual/misc/perf-tuning.xml.ko | 1042 ++ trunk/docs/manual/misc/perf-tuning.xml.meta | 12 + .../docs/manual/misc/relevant_standards.html | 7 + .../manual/misc/relevant_standards.html.en | 199 + .../misc/relevant_standards.html.ko.euc-kr | 191 + trunk/docs/manual/misc/relevant_standards.xml | 192 + .../manual/misc/relevant_standards.xml.ko | 184 + .../manual/misc/relevant_standards.xml.meta | 12 + trunk/docs/manual/misc/rewriteguide.html | 7 + trunk/docs/manual/misc/rewriteguide.html.en | 2102 +++ .../manual/misc/rewriteguide.html.ko.euc-kr | 2006 ++ trunk/docs/manual/misc/rewriteguide.xml | 2103 +++ trunk/docs/manual/misc/rewriteguide.xml.ko | 2006 ++ trunk/docs/manual/misc/rewriteguide.xml.meta | 12 + trunk/docs/manual/misc/security_tips.html | 7 + trunk/docs/manual/misc/security_tips.html.en | 350 + .../manual/misc/security_tips.html.ko.euc-kr | 343 + trunk/docs/manual/misc/security_tips.xml | 345 + trunk/docs/manual/misc/security_tips.xml.ko | 335 + trunk/docs/manual/misc/security_tips.xml.meta | 12 + trunk/docs/manual/mod/allmodules.xml | 87 + trunk/docs/manual/mod/allmodules.xml.de | 87 + trunk/docs/manual/mod/allmodules.xml.es | 87 + trunk/docs/manual/mod/allmodules.xml.ja | 87 + trunk/docs/manual/mod/allmodules.xml.ko | 87 + trunk/docs/manual/mod/beos.html | 15 + trunk/docs/manual/mod/beos.html.de | 108 + trunk/docs/manual/mod/beos.html.en | 106 + trunk/docs/manual/mod/beos.html.es | 111 + trunk/docs/manual/mod/beos.html.ko.euc-kr | 103 + trunk/docs/manual/mod/beos.xml | 102 + trunk/docs/manual/mod/beos.xml.de | 102 + trunk/docs/manual/mod/beos.xml.es | 109 + trunk/docs/manual/mod/beos.xml.ko | 98 + trunk/docs/manual/mod/beos.xml.meta | 14 + trunk/docs/manual/mod/core.html | 11 + trunk/docs/manual/mod/core.html.de | 3349 ++++ trunk/docs/manual/mod/core.html.en | 3190 ++++ trunk/docs/manual/mod/core.html.ja.euc-jp | 3212 ++++ trunk/docs/manual/mod/core.xml | 3138 ++++ trunk/docs/manual/mod/core.xml.de | 3289 ++++ trunk/docs/manual/mod/core.xml.ja | 3141 ++++ trunk/docs/manual/mod/core.xml.meta | 13 + trunk/docs/manual/mod/directive-dict.html | 11 + trunk/docs/manual/mod/directive-dict.html.en | 291 + .../manual/mod/directive-dict.html.ja.euc-jp | 301 + .../manual/mod/directive-dict.html.ko.euc-kr | 250 + trunk/docs/manual/mod/directive-dict.xml | 289 + trunk/docs/manual/mod/directive-dict.xml.ja | 295 + trunk/docs/manual/mod/directive-dict.xml.ko | 249 + trunk/docs/manual/mod/directive-dict.xml.meta | 13 + trunk/docs/manual/mod/directives.html | 19 + trunk/docs/manual/mod/directives.html.de | 428 + trunk/docs/manual/mod/directives.html.en | 429 + trunk/docs/manual/mod/directives.html.es | 431 + .../docs/manual/mod/directives.html.ja.euc-jp | 426 + .../docs/manual/mod/directives.html.ko.euc-kr | 423 + trunk/docs/manual/mod/directives.xml | 40 + trunk/docs/manual/mod/directives.xml.de | 40 + trunk/docs/manual/mod/directives.xml.es | 42 + trunk/docs/manual/mod/directives.xml.ja | 38 + trunk/docs/manual/mod/directives.xml.ko | 37 + trunk/docs/manual/mod/directives.xml.meta | 15 + trunk/docs/manual/mod/event.html | 3 + trunk/docs/manual/mod/event.html.en | 83 + trunk/docs/manual/mod/event.xml | 94 + trunk/docs/manual/mod/event.xml.meta | 11 + trunk/docs/manual/mod/index.html | 19 + trunk/docs/manual/mod/index.html.de | 198 + trunk/docs/manual/mod/index.html.en | 196 + trunk/docs/manual/mod/index.html.es | 199 + trunk/docs/manual/mod/index.html.ja.euc-jp | 184 + trunk/docs/manual/mod/index.html.ko.euc-kr | 177 + trunk/docs/manual/mod/index.xml | 37 + trunk/docs/manual/mod/index.xml.de | 37 + trunk/docs/manual/mod/index.xml.es | 41 + trunk/docs/manual/mod/index.xml.ja | 36 + trunk/docs/manual/mod/index.xml.ko | 36 + trunk/docs/manual/mod/index.xml.meta | 15 + trunk/docs/manual/mod/leader.html | 11 + trunk/docs/manual/mod/leader.html.de | 94 + trunk/docs/manual/mod/leader.html.en | 91 + trunk/docs/manual/mod/leader.html.ko.euc-kr | 91 + trunk/docs/manual/mod/leader.xml | 100 + trunk/docs/manual/mod/leader.xml.de | 102 + trunk/docs/manual/mod/leader.xml.ko | 98 + trunk/docs/manual/mod/leader.xml.meta | 13 + trunk/docs/manual/mod/mod_actions.html | 15 + trunk/docs/manual/mod/mod_actions.html.de | 168 + trunk/docs/manual/mod/mod_actions.html.en | 165 + .../manual/mod/mod_actions.html.ja.euc-jp | 173 + .../manual/mod/mod_actions.html.ko.euc-kr | 164 + trunk/docs/manual/mod/mod_actions.xml | 154 + trunk/docs/manual/mod/mod_actions.xml.de | 157 + trunk/docs/manual/mod/mod_actions.xml.ja | 158 + trunk/docs/manual/mod/mod_actions.xml.ko | 153 + trunk/docs/manual/mod/mod_actions.xml.meta | 14 + trunk/docs/manual/mod/mod_alias.html | 11 + trunk/docs/manual/mod/mod_alias.html.en | 376 + .../docs/manual/mod/mod_alias.html.ja.euc-jp | 385 + .../docs/manual/mod/mod_alias.html.ko.euc-kr | 354 + trunk/docs/manual/mod/mod_alias.xml | 364 + trunk/docs/manual/mod/mod_alias.xml.ja | 378 + trunk/docs/manual/mod/mod_alias.xml.ko | 341 + trunk/docs/manual/mod/mod_alias.xml.meta | 13 + trunk/docs/manual/mod/mod_asis.html | 11 + trunk/docs/manual/mod/mod_asis.html.en | 112 + trunk/docs/manual/mod/mod_asis.html.ja.euc-jp | 110 + trunk/docs/manual/mod/mod_asis.html.ko.euc-kr | 108 + trunk/docs/manual/mod/mod_asis.xml | 94 + trunk/docs/manual/mod/mod_asis.xml.ja | 93 + trunk/docs/manual/mod/mod_asis.xml.ko | 91 + trunk/docs/manual/mod/mod_asis.xml.meta | 13 + trunk/docs/manual/mod/mod_auth_basic.html | 11 + trunk/docs/manual/mod/mod_auth_basic.html.en | 130 + .../manual/mod/mod_auth_basic.html.ja.euc-jp | 133 + .../manual/mod/mod_auth_basic.html.ko.euc-kr | 128 + trunk/docs/manual/mod/mod_auth_basic.xml | 112 + trunk/docs/manual/mod/mod_auth_basic.xml.ja | 113 + trunk/docs/manual/mod/mod_auth_basic.xml.ko | 110 + trunk/docs/manual/mod/mod_auth_basic.xml.meta | 13 + trunk/docs/manual/mod/mod_auth_digest.html | 7 + trunk/docs/manual/mod/mod_auth_digest.html.en | 332 + .../manual/mod/mod_auth_digest.html.ko.euc-kr | 321 + trunk/docs/manual/mod/mod_auth_digest.xml | 343 + trunk/docs/manual/mod/mod_auth_digest.xml.ko | 329 + .../docs/manual/mod/mod_auth_digest.xml.meta | 12 + trunk/docs/manual/mod/mod_authn_alias.html | 3 + trunk/docs/manual/mod/mod_authn_alias.html.en | 121 + trunk/docs/manual/mod/mod_authn_alias.xml | 107 + .../docs/manual/mod/mod_authn_alias.xml.meta | 11 + trunk/docs/manual/mod/mod_authn_anon.html | 11 + trunk/docs/manual/mod/mod_authn_anon.html.en | 224 + .../manual/mod/mod_authn_anon.html.ja.euc-jp | 224 + .../manual/mod/mod_authn_anon.html.ko.euc-kr | 211 + trunk/docs/manual/mod/mod_authn_anon.xml | 208 + trunk/docs/manual/mod/mod_authn_anon.xml.ja | 207 + trunk/docs/manual/mod/mod_authn_anon.xml.ko | 196 + trunk/docs/manual/mod/mod_authn_anon.xml.meta | 13 + trunk/docs/manual/mod/mod_authn_dbm.html | 11 + trunk/docs/manual/mod/mod_authn_dbm.html.en | 136 + .../manual/mod/mod_authn_dbm.html.ja.euc-jp | 135 + .../manual/mod/mod_authn_dbm.html.ko.euc-kr | 131 + trunk/docs/manual/mod/mod_authn_dbm.xml | 119 + trunk/docs/manual/mod/mod_authn_dbm.xml.ja | 119 + trunk/docs/manual/mod/mod_authn_dbm.xml.ko | 113 + trunk/docs/manual/mod/mod_authn_dbm.xml.meta | 13 + trunk/docs/manual/mod/mod_authn_default.html | 11 + .../docs/manual/mod/mod_authn_default.html.en | 80 + .../mod/mod_authn_default.html.ja.euc-jp | 80 + .../mod/mod_authn_default.html.ko.euc-kr | 76 + trunk/docs/manual/mod/mod_authn_default.xml | 65 + .../docs/manual/mod/mod_authn_default.xml.ja | 65 + .../docs/manual/mod/mod_authn_default.xml.ko | 61 + .../manual/mod/mod_authn_default.xml.meta | 13 + trunk/docs/manual/mod/mod_authn_file.html | 11 + trunk/docs/manual/mod/mod_authn_file.html.en | 132 + .../manual/mod/mod_authn_file.html.ja.euc-jp | 142 + .../manual/mod/mod_authn_file.html.ko.euc-kr | 129 + trunk/docs/manual/mod/mod_authn_file.xml | 117 + trunk/docs/manual/mod/mod_authn_file.xml.ja | 125 + trunk/docs/manual/mod/mod_authn_file.xml.ko | 115 + trunk/docs/manual/mod/mod_authn_file.xml.meta | 13 + trunk/docs/manual/mod/mod_authnz_ldap.html | 3 + trunk/docs/manual/mod/mod_authnz_ldap.html.en | 940 + trunk/docs/manual/mod/mod_authnz_ldap.xml | 936 + .../docs/manual/mod/mod_authnz_ldap.xml.meta | 11 + trunk/docs/manual/mod/mod_authz_dbm.html | 7 + trunk/docs/manual/mod/mod_authz_dbm.html.en | 185 + .../manual/mod/mod_authz_dbm.html.ko.euc-kr | 170 + trunk/docs/manual/mod/mod_authz_dbm.xml | 169 + trunk/docs/manual/mod/mod_authz_dbm.xml.ko | 153 + trunk/docs/manual/mod/mod_authz_dbm.xml.meta | 12 + trunk/docs/manual/mod/mod_authz_default.html | 11 + .../docs/manual/mod/mod_authz_default.html.en | 80 + .../mod/mod_authz_default.html.ja.euc-jp | 79 + .../mod/mod_authz_default.html.ko.euc-kr | 78 + trunk/docs/manual/mod/mod_authz_default.xml | 65 + .../docs/manual/mod/mod_authz_default.xml.ja | 64 + .../docs/manual/mod/mod_authz_default.xml.ko | 63 + .../manual/mod/mod_authz_default.xml.meta | 13 + .../docs/manual/mod/mod_authz_groupfile.html | 11 + .../manual/mod/mod_authz_groupfile.html.en | 125 + .../mod/mod_authz_groupfile.html.ja.euc-jp | 132 + .../mod/mod_authz_groupfile.html.ko.euc-kr | 121 + trunk/docs/manual/mod/mod_authz_groupfile.xml | 110 + .../manual/mod/mod_authz_groupfile.xml.ja | 115 + .../manual/mod/mod_authz_groupfile.xml.ko | 106 + .../manual/mod/mod_authz_groupfile.xml.meta | 13 + trunk/docs/manual/mod/mod_authz_host.html | 11 + trunk/docs/manual/mod/mod_authz_host.html.en | 333 + .../manual/mod/mod_authz_host.html.ja.euc-jp | 347 + .../manual/mod/mod_authz_host.html.ko.euc-kr | 310 + trunk/docs/manual/mod/mod_authz_host.xml | 336 + trunk/docs/manual/mod/mod_authz_host.xml.ja | 341 + trunk/docs/manual/mod/mod_authz_host.xml.ko | 313 + trunk/docs/manual/mod/mod_authz_host.xml.meta | 13 + trunk/docs/manual/mod/mod_authz_owner.html | 11 + trunk/docs/manual/mod/mod_authz_owner.html.en | 185 + .../manual/mod/mod_authz_owner.html.ja.euc-jp | 187 + .../manual/mod/mod_authz_owner.html.ko.euc-kr | 182 + trunk/docs/manual/mod/mod_authz_owner.xml | 170 + trunk/docs/manual/mod/mod_authz_owner.xml.ja | 169 + trunk/docs/manual/mod/mod_authz_owner.xml.ko | 166 + .../docs/manual/mod/mod_authz_owner.xml.meta | 13 + trunk/docs/manual/mod/mod_authz_user.html | 11 + trunk/docs/manual/mod/mod_authz_user.html.en | 84 + .../manual/mod/mod_authz_user.html.ja.euc-jp | 83 + .../manual/mod/mod_authz_user.html.ko.euc-kr | 81 + trunk/docs/manual/mod/mod_authz_user.xml | 67 + trunk/docs/manual/mod/mod_authz_user.xml.ja | 66 + trunk/docs/manual/mod/mod_authz_user.xml.ko | 64 + trunk/docs/manual/mod/mod_authz_user.xml.meta | 13 + trunk/docs/manual/mod/mod_autoindex.html | 11 + trunk/docs/manual/mod/mod_autoindex.html.en | 893 + .../manual/mod/mod_autoindex.html.ja.euc-jp | 985 + .../manual/mod/mod_autoindex.html.ko.euc-kr | 835 + trunk/docs/manual/mod/mod_autoindex.xml | 941 + trunk/docs/manual/mod/mod_autoindex.xml.ja | 1024 ++ trunk/docs/manual/mod/mod_autoindex.xml.ko | 884 + trunk/docs/manual/mod/mod_autoindex.xml.meta | 13 + trunk/docs/manual/mod/mod_cache.html | 11 + trunk/docs/manual/mod/mod_cache.html.en | 435 + .../docs/manual/mod/mod_cache.html.ja.euc-jp | 441 + .../docs/manual/mod/mod_cache.html.ko.euc-kr | 347 + trunk/docs/manual/mod/mod_cache.xml | 417 + trunk/docs/manual/mod/mod_cache.xml.ja | 423 + trunk/docs/manual/mod/mod_cache.xml.ko | 346 + trunk/docs/manual/mod/mod_cache.xml.meta | 13 + trunk/docs/manual/mod/mod_cern_meta.html | 7 + trunk/docs/manual/mod/mod_cern_meta.html.en | 128 + .../manual/mod/mod_cern_meta.html.ko.euc-kr | 120 + trunk/docs/manual/mod/mod_cern_meta.xml | 120 + trunk/docs/manual/mod/mod_cern_meta.xml.ko | 112 + trunk/docs/manual/mod/mod_cern_meta.xml.meta | 12 + trunk/docs/manual/mod/mod_cgi.html | 11 + trunk/docs/manual/mod/mod_cgi.html.en | 247 + trunk/docs/manual/mod/mod_cgi.html.ja.euc-jp | 254 + trunk/docs/manual/mod/mod_cgi.html.ko.euc-kr | 234 + trunk/docs/manual/mod/mod_cgi.xml | 240 + trunk/docs/manual/mod/mod_cgi.xml.ja | 245 + trunk/docs/manual/mod/mod_cgi.xml.ko | 227 + trunk/docs/manual/mod/mod_cgi.xml.meta | 13 + trunk/docs/manual/mod/mod_cgid.html | 11 + trunk/docs/manual/mod/mod_cgid.html.en | 105 + trunk/docs/manual/mod/mod_cgid.html.ja.euc-jp | 98 + trunk/docs/manual/mod/mod_cgid.html.ko.euc-kr | 99 + trunk/docs/manual/mod/mod_cgid.xml | 100 + trunk/docs/manual/mod/mod_cgid.xml.ja | 93 + trunk/docs/manual/mod/mod_cgid.xml.ko | 92 + trunk/docs/manual/mod/mod_cgid.xml.meta | 13 + trunk/docs/manual/mod/mod_charset_lite.html | 7 + .../docs/manual/mod/mod_charset_lite.html.en | 209 + .../mod/mod_charset_lite.html.ko.euc-kr | 196 + trunk/docs/manual/mod/mod_charset_lite.xml | 199 + trunk/docs/manual/mod/mod_charset_lite.xml.ko | 186 + .../docs/manual/mod/mod_charset_lite.xml.meta | 12 + trunk/docs/manual/mod/mod_dav.html | 11 + trunk/docs/manual/mod/mod_dav.html.en | 268 + trunk/docs/manual/mod/mod_dav.html.ja.euc-jp | 274 + trunk/docs/manual/mod/mod_dav.html.ko.euc-kr | 263 + trunk/docs/manual/mod/mod_dav.xml | 255 + trunk/docs/manual/mod/mod_dav.xml.ja | 258 + trunk/docs/manual/mod/mod_dav.xml.ko | 248 + trunk/docs/manual/mod/mod_dav.xml.meta | 13 + trunk/docs/manual/mod/mod_dav_fs.html | 11 + trunk/docs/manual/mod/mod_dav_fs.html.en | 97 + .../docs/manual/mod/mod_dav_fs.html.ja.euc-jp | 89 + .../docs/manual/mod/mod_dav_fs.html.ko.euc-kr | 96 + trunk/docs/manual/mod/mod_dav_fs.xml | 87 + trunk/docs/manual/mod/mod_dav_fs.xml.ja | 76 + trunk/docs/manual/mod/mod_dav_fs.xml.ko | 83 + trunk/docs/manual/mod/mod_dav_fs.xml.meta | 13 + trunk/docs/manual/mod/mod_dav_lock.html | 7 + trunk/docs/manual/mod/mod_dav_lock.html.en | 101 + .../manual/mod/mod_dav_lock.html.ja.euc-jp | 105 + trunk/docs/manual/mod/mod_dav_lock.xml | 92 + trunk/docs/manual/mod/mod_dav_lock.xml.ja | 96 + trunk/docs/manual/mod/mod_dav_lock.xml.meta | 12 + trunk/docs/manual/mod/mod_dbd.html | 3 + trunk/docs/manual/mod/mod_dbd.html.en | 238 + trunk/docs/manual/mod/mod_dbd.xml | 218 + trunk/docs/manual/mod/mod_dbd.xml.meta | 11 + trunk/docs/manual/mod/mod_deflate.html | 11 + trunk/docs/manual/mod/mod_deflate.html.en | 382 + .../manual/mod/mod_deflate.html.ja.euc-jp | 383 + .../manual/mod/mod_deflate.html.ko.euc-kr | 366 + trunk/docs/manual/mod/mod_deflate.xml | 365 + trunk/docs/manual/mod/mod_deflate.xml.ja | 355 + trunk/docs/manual/mod/mod_deflate.xml.ko | 346 + trunk/docs/manual/mod/mod_deflate.xml.meta | 13 + trunk/docs/manual/mod/mod_dir.html | 11 + trunk/docs/manual/mod/mod_dir.html.en | 169 + trunk/docs/manual/mod/mod_dir.html.ja.euc-jp | 180 + trunk/docs/manual/mod/mod_dir.html.ko.euc-kr | 167 + trunk/docs/manual/mod/mod_dir.xml | 154 + trunk/docs/manual/mod/mod_dir.xml.ja | 164 + trunk/docs/manual/mod/mod_dir.xml.ko | 150 + trunk/docs/manual/mod/mod_dir.xml.meta | 13 + trunk/docs/manual/mod/mod_disk_cache.html | 11 + trunk/docs/manual/mod/mod_disk_cache.html.en | 178 + .../manual/mod/mod_disk_cache.html.ja.euc-jp | 174 + .../manual/mod/mod_disk_cache.html.ko.euc-kr | 175 + trunk/docs/manual/mod/mod_disk_cache.xml | 164 + trunk/docs/manual/mod/mod_disk_cache.xml.ja | 159 + trunk/docs/manual/mod/mod_disk_cache.xml.ko | 159 + trunk/docs/manual/mod/mod_disk_cache.xml.meta | 13 + trunk/docs/manual/mod/mod_dumpio.html | 7 + trunk/docs/manual/mod/mod_dumpio.html.en | 106 + .../docs/manual/mod/mod_dumpio.html.ja.euc-jp | 105 + trunk/docs/manual/mod/mod_dumpio.xml | 90 + trunk/docs/manual/mod/mod_dumpio.xml.ja | 89 + trunk/docs/manual/mod/mod_dumpio.xml.meta | 12 + trunk/docs/manual/mod/mod_echo.html | 11 + trunk/docs/manual/mod/mod_echo.html.en | 73 + trunk/docs/manual/mod/mod_echo.html.ja.euc-jp | 72 + trunk/docs/manual/mod/mod_echo.html.ko.euc-kr | 71 + trunk/docs/manual/mod/mod_echo.xml | 60 + trunk/docs/manual/mod/mod_echo.xml.ja | 59 + trunk/docs/manual/mod/mod_echo.xml.ko | 58 + trunk/docs/manual/mod/mod_echo.xml.meta | 13 + trunk/docs/manual/mod/mod_env.html | 11 + trunk/docs/manual/mod/mod_env.html.en | 117 + trunk/docs/manual/mod/mod_env.html.ja.euc-jp | 117 + trunk/docs/manual/mod/mod_env.html.ko.euc-kr | 114 + trunk/docs/manual/mod/mod_env.xml | 98 + trunk/docs/manual/mod/mod_env.xml.ja | 99 + trunk/docs/manual/mod/mod_env.xml.ko | 93 + trunk/docs/manual/mod/mod_env.xml.meta | 13 + trunk/docs/manual/mod/mod_example.html | 7 + trunk/docs/manual/mod/mod_example.html.en | 156 + .../manual/mod/mod_example.html.ko.euc-kr | 155 + trunk/docs/manual/mod/mod_example.xml | 141 + trunk/docs/manual/mod/mod_example.xml.ko | 138 + trunk/docs/manual/mod/mod_example.xml.meta | 12 + trunk/docs/manual/mod/mod_expires.html | 11 + trunk/docs/manual/mod/mod_expires.html.en | 247 + .../manual/mod/mod_expires.html.ja.euc-jp | 233 + .../manual/mod/mod_expires.html.ko.euc-kr | 225 + trunk/docs/manual/mod/mod_expires.xml | 231 + trunk/docs/manual/mod/mod_expires.xml.ja | 219 + trunk/docs/manual/mod/mod_expires.xml.ko | 211 + trunk/docs/manual/mod/mod_expires.xml.meta | 13 + trunk/docs/manual/mod/mod_ext_filter.html | 11 + trunk/docs/manual/mod/mod_ext_filter.html.en | 376 + .../manual/mod/mod_ext_filter.html.ja.euc-jp | 367 + .../manual/mod/mod_ext_filter.html.ko.euc-kr | 354 + trunk/docs/manual/mod/mod_ext_filter.xml | 355 + trunk/docs/manual/mod/mod_ext_filter.xml.ja | 344 + trunk/docs/manual/mod/mod_ext_filter.xml.ko | 330 + trunk/docs/manual/mod/mod_ext_filter.xml.meta | 13 + trunk/docs/manual/mod/mod_file_cache.html | 7 + trunk/docs/manual/mod/mod_file_cache.html.en | 212 + .../manual/mod/mod_file_cache.html.ko.euc-kr | 200 + trunk/docs/manual/mod/mod_file_cache.xml | 199 + trunk/docs/manual/mod/mod_file_cache.xml.ko | 190 + trunk/docs/manual/mod/mod_file_cache.xml.meta | 12 + trunk/docs/manual/mod/mod_filter.html | 3 + trunk/docs/manual/mod/mod_filter.html.en | 435 + trunk/docs/manual/mod/mod_filter.xml | 426 + trunk/docs/manual/mod/mod_filter.xml.meta | 11 + trunk/docs/manual/mod/mod_headers.html | 11 + trunk/docs/manual/mod/mod_headers.html.en | 354 + .../manual/mod/mod_headers.html.ja.euc-jp | 347 + .../manual/mod/mod_headers.html.ko.euc-kr | 337 + trunk/docs/manual/mod/mod_headers.xml | 343 + trunk/docs/manual/mod/mod_headers.xml.ja | 337 + trunk/docs/manual/mod/mod_headers.xml.ko | 330 + trunk/docs/manual/mod/mod_headers.xml.meta | 13 + trunk/docs/manual/mod/mod_ident.html | 7 + trunk/docs/manual/mod/mod_ident.html.en | 101 + .../docs/manual/mod/mod_ident.html.ko.euc-kr | 98 + trunk/docs/manual/mod/mod_ident.xml | 89 + trunk/docs/manual/mod/mod_ident.xml.ko | 85 + trunk/docs/manual/mod/mod_ident.xml.meta | 12 + trunk/docs/manual/mod/mod_imagemap.html | 7 + trunk/docs/manual/mod/mod_imagemap.html.en | 382 + .../manual/mod/mod_imagemap.html.ko.euc-kr | 363 + trunk/docs/manual/mod/mod_imagemap.xml | 359 + trunk/docs/manual/mod/mod_imagemap.xml.ko | 341 + trunk/docs/manual/mod/mod_imagemap.xml.meta | 12 + trunk/docs/manual/mod/mod_include.html | 7 + trunk/docs/manual/mod/mod_include.html.en | 806 + .../manual/mod/mod_include.html.ja.euc-jp | 789 + trunk/docs/manual/mod/mod_include.xml | 792 + trunk/docs/manual/mod/mod_include.xml.ja | 771 + trunk/docs/manual/mod/mod_include.xml.meta | 12 + trunk/docs/manual/mod/mod_info.html | 11 + trunk/docs/manual/mod/mod_info.html.en | 194 + trunk/docs/manual/mod/mod_info.html.ja.euc-jp | 188 + trunk/docs/manual/mod/mod_info.html.ko.euc-kr | 169 + trunk/docs/manual/mod/mod_info.xml | 174 + trunk/docs/manual/mod/mod_info.xml.ja | 169 + trunk/docs/manual/mod/mod_info.xml.ko | 153 + trunk/docs/manual/mod/mod_info.xml.meta | 13 + trunk/docs/manual/mod/mod_isapi.html | 7 + trunk/docs/manual/mod/mod_isapi.html.en | 337 + .../docs/manual/mod/mod_isapi.html.ko.euc-kr | 317 + trunk/docs/manual/mod/mod_isapi.xml | 321 + trunk/docs/manual/mod/mod_isapi.xml.ko | 303 + trunk/docs/manual/mod/mod_isapi.xml.meta | 12 + trunk/docs/manual/mod/mod_ldap.html | 3 + trunk/docs/manual/mod/mod_ldap.html.en | 633 + trunk/docs/manual/mod/mod_ldap.xml | 598 + trunk/docs/manual/mod/mod_ldap.xml.meta | 11 + trunk/docs/manual/mod/mod_log_config.html | 11 + trunk/docs/manual/mod/mod_log_config.html.en | 470 + .../manual/mod/mod_log_config.html.ja.euc-jp | 475 + .../manual/mod/mod_log_config.html.ko.euc-kr | 401 + trunk/docs/manual/mod/mod_log_config.xml | 487 + trunk/docs/manual/mod/mod_log_config.xml.ja | 493 + trunk/docs/manual/mod/mod_log_config.xml.ko | 421 + trunk/docs/manual/mod/mod_log_config.xml.meta | 13 + trunk/docs/manual/mod/mod_log_forensic.html | 7 + .../docs/manual/mod/mod_log_forensic.html.en | 162 + .../mod/mod_log_forensic.html.ja.euc-jp | 163 + trunk/docs/manual/mod/mod_log_forensic.xml | 146 + trunk/docs/manual/mod/mod_log_forensic.xml.ja | 148 + .../docs/manual/mod/mod_log_forensic.xml.meta | 12 + trunk/docs/manual/mod/mod_logio.html | 11 + trunk/docs/manual/mod/mod_logio.html.en | 91 + .../docs/manual/mod/mod_logio.html.ja.euc-jp | 91 + .../docs/manual/mod/mod_logio.html.ko.euc-kr | 92 + trunk/docs/manual/mod/mod_logio.xml | 76 + trunk/docs/manual/mod/mod_logio.xml.ja | 77 + trunk/docs/manual/mod/mod_logio.xml.ko | 78 + trunk/docs/manual/mod/mod_logio.xml.meta | 13 + trunk/docs/manual/mod/mod_mem_cache.html | 11 + trunk/docs/manual/mod/mod_mem_cache.html.en | 236 + .../manual/mod/mod_mem_cache.html.ja.euc-jp | 234 + .../manual/mod/mod_mem_cache.html.ko.euc-kr | 237 + trunk/docs/manual/mod/mod_mem_cache.xml | 217 + trunk/docs/manual/mod/mod_mem_cache.xml.ja | 213 + trunk/docs/manual/mod/mod_mem_cache.xml.ko | 212 + trunk/docs/manual/mod/mod_mem_cache.xml.meta | 13 + trunk/docs/manual/mod/mod_mime.html | 7 + trunk/docs/manual/mod/mod_mime.html.en | 938 + trunk/docs/manual/mod/mod_mime.html.ja.euc-jp | 937 + trunk/docs/manual/mod/mod_mime.xml | 901 + trunk/docs/manual/mod/mod_mime.xml.ja | 890 + trunk/docs/manual/mod/mod_mime.xml.meta | 12 + trunk/docs/manual/mod/mod_mime_magic.html | 3 + trunk/docs/manual/mod/mod_mime_magic.html.en | 274 + trunk/docs/manual/mod/mod_mime_magic.xml | 271 + trunk/docs/manual/mod/mod_mime_magic.xml.meta | 11 + trunk/docs/manual/mod/mod_negotiation.html | 7 + trunk/docs/manual/mod/mod_negotiation.html.en | 306 + .../manual/mod/mod_negotiation.html.ja.euc-jp | 300 + trunk/docs/manual/mod/mod_negotiation.xml | 286 + trunk/docs/manual/mod/mod_negotiation.xml.ja | 278 + .../docs/manual/mod/mod_negotiation.xml.meta | 12 + trunk/docs/manual/mod/mod_nw_ssl.html | 3 + trunk/docs/manual/mod/mod_nw_ssl.html.en | 97 + trunk/docs/manual/mod/mod_nw_ssl.xml | 81 + trunk/docs/manual/mod/mod_nw_ssl.xml.meta | 11 + trunk/docs/manual/mod/mod_proxy.html | 7 + trunk/docs/manual/mod/mod_proxy.html.en | 1203 ++ .../docs/manual/mod/mod_proxy.html.ja.euc-jp | 1202 ++ trunk/docs/manual/mod/mod_proxy.xml | 1189 ++ trunk/docs/manual/mod/mod_proxy.xml.ja | 1193 ++ trunk/docs/manual/mod/mod_proxy.xml.meta | 12 + trunk/docs/manual/mod/mod_proxy_ajp.html | 7 + trunk/docs/manual/mod/mod_proxy_ajp.html.en | 556 + .../manual/mod/mod_proxy_ajp.html.ja.euc-jp | 542 + trunk/docs/manual/mod/mod_proxy_ajp.xml | 539 + trunk/docs/manual/mod/mod_proxy_ajp.xml.ja | 525 + trunk/docs/manual/mod/mod_proxy_ajp.xml.meta | 12 + trunk/docs/manual/mod/mod_proxy_balancer.html | 7 + .../manual/mod/mod_proxy_balancer.html.en | 316 + .../mod/mod_proxy_balancer.html.ja.euc-jp | 317 + trunk/docs/manual/mod/mod_proxy_balancer.xml | 306 + .../docs/manual/mod/mod_proxy_balancer.xml.ja | 307 + .../manual/mod/mod_proxy_balancer.xml.meta | 12 + trunk/docs/manual/mod/mod_proxy_connect.html | 3 + .../docs/manual/mod/mod_proxy_connect.html.en | 62 + trunk/docs/manual/mod/mod_proxy_connect.xml | 52 + .../manual/mod/mod_proxy_connect.xml.meta | 11 + trunk/docs/manual/mod/mod_proxy_ftp.html | 3 + trunk/docs/manual/mod/mod_proxy_ftp.html.en | 61 + trunk/docs/manual/mod/mod_proxy_ftp.xml | 51 + trunk/docs/manual/mod/mod_proxy_ftp.xml.meta | 11 + trunk/docs/manual/mod/mod_proxy_http.html | 3 + trunk/docs/manual/mod/mod_proxy_http.html.en | 65 + trunk/docs/manual/mod/mod_proxy_http.xml | 55 + trunk/docs/manual/mod/mod_proxy_http.xml.meta | 11 + trunk/docs/manual/mod/mod_rewrite.html | 3 + trunk/docs/manual/mod/mod_rewrite.html.en | 1608 ++ trunk/docs/manual/mod/mod_rewrite.xml | 1622 ++ trunk/docs/manual/mod/mod_rewrite.xml.meta | 11 + trunk/docs/manual/mod/mod_setenvif.html | 11 + trunk/docs/manual/mod/mod_setenvif.html.en | 286 + .../manual/mod/mod_setenvif.html.ja.euc-jp | 280 + .../manual/mod/mod_setenvif.html.ko.euc-kr | 257 + trunk/docs/manual/mod/mod_setenvif.xml | 273 + trunk/docs/manual/mod/mod_setenvif.xml.ja | 265 + trunk/docs/manual/mod/mod_setenvif.xml.ko | 245 + trunk/docs/manual/mod/mod_setenvif.xml.meta | 13 + trunk/docs/manual/mod/mod_so.html | 11 + trunk/docs/manual/mod/mod_so.html.en | 190 + trunk/docs/manual/mod/mod_so.html.ja.euc-jp | 190 + trunk/docs/manual/mod/mod_so.html.ko.euc-kr | 174 + trunk/docs/manual/mod/mod_so.xml | 176 + trunk/docs/manual/mod/mod_so.xml.ja | 175 + trunk/docs/manual/mod/mod_so.xml.ko | 160 + trunk/docs/manual/mod/mod_so.xml.meta | 13 + trunk/docs/manual/mod/mod_speling.html | 11 + trunk/docs/manual/mod/mod_speling.html.en | 128 + .../manual/mod/mod_speling.html.ja.euc-jp | 127 + .../manual/mod/mod_speling.html.ko.euc-kr | 118 + trunk/docs/manual/mod/mod_speling.xml | 120 + trunk/docs/manual/mod/mod_speling.xml.ja | 118 + trunk/docs/manual/mod/mod_speling.xml.ko | 110 + trunk/docs/manual/mod/mod_speling.xml.meta | 13 + trunk/docs/manual/mod/mod_ssl.html | 3 + trunk/docs/manual/mod/mod_ssl.html.en | 1694 ++ trunk/docs/manual/mod/mod_ssl.xml | 1679 ++ trunk/docs/manual/mod/mod_ssl.xml.meta | 11 + trunk/docs/manual/mod/mod_status.html | 11 + trunk/docs/manual/mod/mod_status.html.en | 162 + .../docs/manual/mod/mod_status.html.ja.euc-jp | 154 + .../docs/manual/mod/mod_status.html.ko.euc-kr | 148 + trunk/docs/manual/mod/mod_status.xml | 144 + trunk/docs/manual/mod/mod_status.xml.ja | 135 + trunk/docs/manual/mod/mod_status.xml.ko | 130 + trunk/docs/manual/mod/mod_status.xml.meta | 13 + trunk/docs/manual/mod/mod_suexec.html | 11 + trunk/docs/manual/mod/mod_suexec.html.en | 80 + .../docs/manual/mod/mod_suexec.html.ja.euc-jp | 79 + .../docs/manual/mod/mod_suexec.html.ko.euc-kr | 81 + trunk/docs/manual/mod/mod_suexec.xml | 68 + trunk/docs/manual/mod/mod_suexec.xml.ja | 66 + trunk/docs/manual/mod/mod_suexec.xml.ko | 66 + trunk/docs/manual/mod/mod_suexec.xml.meta | 13 + trunk/docs/manual/mod/mod_unique_id.html | 11 + trunk/docs/manual/mod/mod_unique_id.html.en | 216 + .../manual/mod/mod_unique_id.html.ja.euc-jp | 214 + .../manual/mod/mod_unique_id.html.ko.euc-kr | 191 + trunk/docs/manual/mod/mod_unique_id.xml | 200 + trunk/docs/manual/mod/mod_unique_id.xml.ja | 199 + trunk/docs/manual/mod/mod_unique_id.xml.ko | 174 + trunk/docs/manual/mod/mod_unique_id.xml.meta | 13 + trunk/docs/manual/mod/mod_userdir.html | 11 + trunk/docs/manual/mod/mod_userdir.html.en | 175 + .../manual/mod/mod_userdir.html.ja.euc-jp | 185 + .../manual/mod/mod_userdir.html.ko.euc-kr | 161 + trunk/docs/manual/mod/mod_userdir.xml | 162 + trunk/docs/manual/mod/mod_userdir.xml.ja | 170 + trunk/docs/manual/mod/mod_userdir.xml.ko | 146 + trunk/docs/manual/mod/mod_userdir.xml.meta | 13 + trunk/docs/manual/mod/mod_usertrack.html | 3 + trunk/docs/manual/mod/mod_usertrack.html.en | 236 + trunk/docs/manual/mod/mod_usertrack.xml | 242 + trunk/docs/manual/mod/mod_usertrack.xml.meta | 11 + trunk/docs/manual/mod/mod_version.html | 11 + trunk/docs/manual/mod/mod_version.html.en | 150 + .../manual/mod/mod_version.html.ja.euc-jp | 148 + .../manual/mod/mod_version.html.ko.euc-kr | 150 + trunk/docs/manual/mod/mod_version.xml | 137 + trunk/docs/manual/mod/mod_version.xml.ja | 135 + trunk/docs/manual/mod/mod_version.xml.ko | 134 + trunk/docs/manual/mod/mod_version.xml.meta | 13 + trunk/docs/manual/mod/mod_vhost_alias.html | 3 + trunk/docs/manual/mod/mod_vhost_alias.html.en | 312 + trunk/docs/manual/mod/mod_vhost_alias.xml | 307 + .../docs/manual/mod/mod_vhost_alias.xml.meta | 11 + trunk/docs/manual/mod/module-dict.html | 11 + trunk/docs/manual/mod/module-dict.html.en | 117 + .../manual/mod/module-dict.html.ja.euc-jp | 119 + .../manual/mod/module-dict.html.ko.euc-kr | 109 + trunk/docs/manual/mod/module-dict.xml | 107 + trunk/docs/manual/mod/module-dict.xml.ja | 109 + trunk/docs/manual/mod/module-dict.xml.ko | 98 + trunk/docs/manual/mod/module-dict.xml.meta | 13 + trunk/docs/manual/mod/mpm_common.html | 11 + trunk/docs/manual/mod/mpm_common.html.de | 985 + trunk/docs/manual/mod/mpm_common.html.en | 912 + .../docs/manual/mod/mpm_common.html.ja.euc-jp | 980 + trunk/docs/manual/mod/mpm_common.xml | 949 + trunk/docs/manual/mod/mpm_common.xml.de | 1010 ++ trunk/docs/manual/mod/mpm_common.xml.ja | 983 + trunk/docs/manual/mod/mpm_common.xml.meta | 13 + trunk/docs/manual/mod/mpm_netware.html | 3 + trunk/docs/manual/mod/mpm_netware.html.en | 109 + trunk/docs/manual/mod/mpm_netware.xml | 106 + trunk/docs/manual/mod/mpm_netware.xml.meta | 11 + trunk/docs/manual/mod/mpm_winnt.html | 11 + trunk/docs/manual/mod/mpm_winnt.html.de | 93 + trunk/docs/manual/mod/mpm_winnt.html.en | 93 + .../docs/manual/mod/mpm_winnt.html.ja.euc-jp | 91 + trunk/docs/manual/mod/mpm_winnt.xml | 89 + trunk/docs/manual/mod/mpm_winnt.xml.de | 89 + trunk/docs/manual/mod/mpm_winnt.xml.ja | 87 + trunk/docs/manual/mod/mpm_winnt.xml.meta | 13 + trunk/docs/manual/mod/mpmt_os2.html | 3 + trunk/docs/manual/mod/mpmt_os2.html.en | 72 + trunk/docs/manual/mod/mpmt_os2.xml | 71 + trunk/docs/manual/mod/mpmt_os2.xml.meta | 11 + trunk/docs/manual/mod/perchild.html | 3 + trunk/docs/manual/mod/perchild.html.en | 265 + trunk/docs/manual/mod/perchild.xml | 270 + trunk/docs/manual/mod/perchild.xml.meta | 11 + trunk/docs/manual/mod/prefork.html | 11 + trunk/docs/manual/mod/prefork.html.de | 190 + trunk/docs/manual/mod/prefork.html.en | 175 + trunk/docs/manual/mod/prefork.html.ja.euc-jp | 187 + trunk/docs/manual/mod/prefork.xml | 169 + trunk/docs/manual/mod/prefork.xml.de | 181 + trunk/docs/manual/mod/prefork.xml.ja | 177 + trunk/docs/manual/mod/prefork.xml.meta | 13 + trunk/docs/manual/mod/quickreference.html | 19 + trunk/docs/manual/mod/quickreference.html.de | 765 + trunk/docs/manual/mod/quickreference.html.en | 746 + trunk/docs/manual/mod/quickreference.html.es | 749 + .../manual/mod/quickreference.html.ja.euc-jp | 681 + .../manual/mod/quickreference.html.ko.euc-kr | 692 + trunk/docs/manual/mod/quickreference.xml | 59 + trunk/docs/manual/mod/quickreference.xml.de | 61 + trunk/docs/manual/mod/quickreference.xml.es | 62 + trunk/docs/manual/mod/quickreference.xml.ja | 60 + trunk/docs/manual/mod/quickreference.xml.ko | 56 + trunk/docs/manual/mod/quickreference.xml.meta | 15 + trunk/docs/manual/mod/threadpool.html | 3 + trunk/docs/manual/mod/threadpool.html.en | 81 + trunk/docs/manual/mod/threadpool.xml | 94 + trunk/docs/manual/mod/threadpool.xml.meta | 11 + trunk/docs/manual/mod/worker.html | 11 + trunk/docs/manual/mod/worker.html.de | 169 + trunk/docs/manual/mod/worker.html.en | 176 + trunk/docs/manual/mod/worker.html.ja.euc-jp | 185 + trunk/docs/manual/mod/worker.xml | 185 + trunk/docs/manual/mod/worker.xml.de | 185 + trunk/docs/manual/mod/worker.xml.ja | 190 + trunk/docs/manual/mod/worker.xml.meta | 13 + trunk/docs/manual/mpm.html | 19 + trunk/docs/manual/mpm.html.de | 127 + trunk/docs/manual/mpm.html.en | 128 + trunk/docs/manual/mpm.html.es | 139 + trunk/docs/manual/mpm.html.ja.euc-jp | 133 + trunk/docs/manual/mpm.html.ko.euc-kr | 122 + trunk/docs/manual/mpm.xml | 115 + trunk/docs/manual/mpm.xml.de | 115 + trunk/docs/manual/mpm.xml.es | 124 + trunk/docs/manual/mpm.xml.ja | 120 + trunk/docs/manual/mpm.xml.ko | 107 + trunk/docs/manual/mpm.xml.meta | 15 + trunk/docs/manual/new_features_2_0.html | 27 + trunk/docs/manual/new_features_2_0.html.de | 263 + trunk/docs/manual/new_features_2_0.html.en | 243 + trunk/docs/manual/new_features_2_0.html.fr | 251 + .../manual/new_features_2_0.html.ja.euc-jp | 253 + .../manual/new_features_2_0.html.ko.euc-kr | 233 + trunk/docs/manual/new_features_2_0.html.pt-br | 242 + .../manual/new_features_2_0.html.ru.koi8-r | 252 + trunk/docs/manual/new_features_2_0.xml | 234 + trunk/docs/manual/new_features_2_0.xml.de | 256 + trunk/docs/manual/new_features_2_0.xml.fr | 238 + trunk/docs/manual/new_features_2_0.xml.ja | 239 + trunk/docs/manual/new_features_2_0.xml.ko | 219 + trunk/docs/manual/new_features_2_0.xml.meta | 17 + trunk/docs/manual/new_features_2_0.xml.pt-br | 238 + trunk/docs/manual/new_features_2_0.xml.ru | 248 + trunk/docs/manual/new_features_2_2.html | 11 + trunk/docs/manual/new_features_2_2.html.en | 172 + .../manual/new_features_2_2.html.ko.euc-kr | 126 + trunk/docs/manual/new_features_2_2.html.pt-br | 135 + trunk/docs/manual/new_features_2_2.xml | 161 + trunk/docs/manual/new_features_2_2.xml.ko | 118 + trunk/docs/manual/new_features_2_2.xml.meta | 13 + trunk/docs/manual/new_features_2_2.xml.pt-br | 128 + trunk/docs/manual/platform/ebcdic.html | 7 + trunk/docs/manual/platform/ebcdic.html.en | 584 + .../manual/platform/ebcdic.html.ko.euc-kr | 559 + trunk/docs/manual/platform/ebcdic.xml | 579 + trunk/docs/manual/platform/ebcdic.xml.ko | 552 + trunk/docs/manual/platform/ebcdic.xml.meta | 12 + trunk/docs/manual/platform/index.html | 7 + trunk/docs/manual/platform/index.html.en | 94 + .../docs/manual/platform/index.html.ko.euc-kr | 94 + trunk/docs/manual/platform/index.xml | 88 + trunk/docs/manual/platform/index.xml.ko | 88 + trunk/docs/manual/platform/index.xml.meta | 12 + trunk/docs/manual/platform/netware.html | 7 + trunk/docs/manual/platform/netware.html.en | 655 + .../manual/platform/netware.html.ko.euc-kr | 581 + trunk/docs/manual/platform/netware.xml | 653 + trunk/docs/manual/platform/netware.xml.ko | 592 + trunk/docs/manual/platform/netware.xml.meta | 12 + trunk/docs/manual/platform/perf-hp.html | 7 + trunk/docs/manual/platform/perf-hp.html.en | 105 + .../manual/platform/perf-hp.html.ko.euc-kr | 100 + trunk/docs/manual/platform/perf-hp.xml | 113 + trunk/docs/manual/platform/perf-hp.xml.ko | 107 + trunk/docs/manual/platform/perf-hp.xml.meta | 12 + trunk/docs/manual/platform/win_compiling.html | 7 + .../manual/platform/win_compiling.html.en | 426 + .../platform/win_compiling.html.ko.euc-kr | 423 + trunk/docs/manual/platform/win_compiling.xml | 427 + .../docs/manual/platform/win_compiling.xml.ko | 424 + .../manual/platform/win_compiling.xml.meta | 12 + trunk/docs/manual/platform/windows.html | 7 + trunk/docs/manual/platform/windows.html.en | 736 + .../manual/platform/windows.html.ko.euc-kr | 688 + trunk/docs/manual/platform/windows.xml | 729 + trunk/docs/manual/platform/windows.xml.ko | 689 + trunk/docs/manual/platform/windows.xml.meta | 12 + trunk/docs/manual/programs/ab.html | 7 + trunk/docs/manual/programs/ab.html.en | 198 + trunk/docs/manual/programs/ab.html.ko.euc-kr | 201 + trunk/docs/manual/programs/ab.xml | 193 + trunk/docs/manual/programs/ab.xml.ko | 194 + trunk/docs/manual/programs/ab.xml.meta | 12 + trunk/docs/manual/programs/apachectl.html | 7 + trunk/docs/manual/programs/apachectl.html.en | 151 + .../manual/programs/apachectl.html.ko.euc-kr | 144 + trunk/docs/manual/programs/apachectl.xml | 151 + trunk/docs/manual/programs/apachectl.xml.ko | 144 + trunk/docs/manual/programs/apachectl.xml.meta | 12 + trunk/docs/manual/programs/apxs.html | 7 + trunk/docs/manual/programs/apxs.html.en | 330 + .../docs/manual/programs/apxs.html.ko.euc-kr | 324 + trunk/docs/manual/programs/apxs.xml | 326 + trunk/docs/manual/programs/apxs.xml.ko | 320 + trunk/docs/manual/programs/apxs.xml.meta | 12 + trunk/docs/manual/programs/configure.html | 7 + trunk/docs/manual/programs/configure.html.en | 934 + .../manual/programs/configure.html.ko.euc-kr | 930 + trunk/docs/manual/programs/configure.xml | 947 + trunk/docs/manual/programs/configure.xml.ko | 934 + trunk/docs/manual/programs/configure.xml.meta | 12 + trunk/docs/manual/programs/dbmmanage.html | 7 + trunk/docs/manual/programs/dbmmanage.html.en | 191 + .../manual/programs/dbmmanage.html.ko.euc-kr | 172 + trunk/docs/manual/programs/dbmmanage.xml | 189 + trunk/docs/manual/programs/dbmmanage.xml.ko | 170 + trunk/docs/manual/programs/dbmmanage.xml.meta | 12 + trunk/docs/manual/programs/htcacheclean.html | 7 + .../docs/manual/programs/htcacheclean.html.en | 109 + .../programs/htcacheclean.html.ko.euc-kr | 113 + trunk/docs/manual/programs/htcacheclean.xml | 105 + .../docs/manual/programs/htcacheclean.xml.ko | 106 + .../manual/programs/htcacheclean.xml.meta | 12 + trunk/docs/manual/programs/htdbm.html | 3 + trunk/docs/manual/programs/htdbm.html.en | 281 + trunk/docs/manual/programs/htdbm.xml | 276 + trunk/docs/manual/programs/htdbm.xml.meta | 11 + trunk/docs/manual/programs/htdigest.html | 7 + trunk/docs/manual/programs/htdigest.html.en | 72 + .../manual/programs/htdigest.html.ko.euc-kr | 75 + trunk/docs/manual/programs/htdigest.xml | 69 + trunk/docs/manual/programs/htdigest.xml.ko | 70 + trunk/docs/manual/programs/htdigest.xml.meta | 12 + trunk/docs/manual/programs/htpasswd.html | 7 + trunk/docs/manual/programs/htpasswd.html.en | 215 + .../manual/programs/htpasswd.html.ko.euc-kr | 217 + trunk/docs/manual/programs/htpasswd.xml | 209 + trunk/docs/manual/programs/htpasswd.xml.ko | 210 + trunk/docs/manual/programs/htpasswd.xml.meta | 12 + trunk/docs/manual/programs/httpd.html | 7 + trunk/docs/manual/programs/httpd.html.en | 192 + .../docs/manual/programs/httpd.html.ko.euc-kr | 188 + trunk/docs/manual/programs/httpd.xml | 199 + trunk/docs/manual/programs/httpd.xml.ko | 191 + trunk/docs/manual/programs/httpd.xml.meta | 12 + trunk/docs/manual/programs/index.html | 11 + trunk/docs/manual/programs/index.html.en | 100 + trunk/docs/manual/programs/index.html.es | 100 + .../docs/manual/programs/index.html.ko.euc-kr | 96 + trunk/docs/manual/programs/index.xml | 96 + trunk/docs/manual/programs/index.xml.es | 94 + trunk/docs/manual/programs/index.xml.ko | 90 + trunk/docs/manual/programs/index.xml.meta | 13 + trunk/docs/manual/programs/logresolve.html | 7 + trunk/docs/manual/programs/logresolve.html.en | 72 + .../manual/programs/logresolve.html.ko.euc-kr | 69 + trunk/docs/manual/programs/logresolve.xml | 67 + trunk/docs/manual/programs/logresolve.xml.ko | 64 + .../docs/manual/programs/logresolve.xml.meta | 12 + trunk/docs/manual/programs/other.html | 7 + trunk/docs/manual/programs/other.html.en | 59 + .../docs/manual/programs/other.html.ko.euc-kr | 57 + trunk/docs/manual/programs/other.xml | 54 + trunk/docs/manual/programs/other.xml.ko | 52 + trunk/docs/manual/programs/other.xml.meta | 12 + trunk/docs/manual/programs/rotatelogs.html | 7 + trunk/docs/manual/programs/rotatelogs.html.en | 146 + .../manual/programs/rotatelogs.html.ko.euc-kr | 143 + trunk/docs/manual/programs/rotatelogs.xml | 140 + trunk/docs/manual/programs/rotatelogs.xml.ko | 136 + .../docs/manual/programs/rotatelogs.xml.meta | 12 + trunk/docs/manual/programs/suexec.html | 7 + trunk/docs/manual/programs/suexec.html.en | 61 + .../manual/programs/suexec.html.ko.euc-kr | 62 + trunk/docs/manual/programs/suexec.xml | 58 + trunk/docs/manual/programs/suexec.xml.ko | 58 + trunk/docs/manual/programs/suexec.xml.meta | 12 + trunk/docs/manual/rewrite/index.html | 3 + trunk/docs/manual/rewrite/index.html.en | 96 + trunk/docs/manual/rewrite/index.xml | 103 + trunk/docs/manual/rewrite/index.xml.meta | 11 + trunk/docs/manual/rewrite/rewrite_guide.html | 3 + .../docs/manual/rewrite/rewrite_guide.html.en | 789 + trunk/docs/manual/rewrite/rewrite_guide.xml | 783 + .../manual/rewrite/rewrite_guide.xml.meta | 11 + .../rewrite/rewrite_guide_advanced.html | 3 + .../rewrite/rewrite_guide_advanced.html.en | 1289 ++ .../manual/rewrite/rewrite_guide_advanced.xml | 1292 ++ .../rewrite/rewrite_guide_advanced.xml.meta | 11 + trunk/docs/manual/rewrite/rewrite_intro.html | 3 + .../docs/manual/rewrite/rewrite_intro.html.en | 165 + trunk/docs/manual/rewrite/rewrite_intro.xml | 167 + .../manual/rewrite/rewrite_intro.xml.meta | 11 + trunk/docs/manual/rewrite/rewrite_tech.html | 3 + .../docs/manual/rewrite/rewrite_tech.html.en | 167 + trunk/docs/manual/rewrite/rewrite_tech.xml | 171 + .../docs/manual/rewrite/rewrite_tech.xml.meta | 11 + trunk/docs/manual/sections.html | 11 + trunk/docs/manual/sections.html.en | 458 + trunk/docs/manual/sections.html.ja.euc-jp | 466 + trunk/docs/manual/sections.html.ko.euc-kr | 422 + trunk/docs/manual/sections.xml | 496 + trunk/docs/manual/sections.xml.ja | 479 + trunk/docs/manual/sections.xml.ko | 465 + trunk/docs/manual/sections.xml.meta | 13 + trunk/docs/manual/server-wide.html | 11 + trunk/docs/manual/server-wide.html.en | 99 + trunk/docs/manual/server-wide.html.ja.euc-jp | 99 + trunk/docs/manual/server-wide.html.ko.euc-kr | 93 + trunk/docs/manual/server-wide.xml | 118 + trunk/docs/manual/server-wide.xml.ja | 118 + trunk/docs/manual/server-wide.xml.ko | 112 + trunk/docs/manual/server-wide.xml.meta | 13 + trunk/docs/manual/sitemap.html | 19 + trunk/docs/manual/sitemap.html.de | 264 + trunk/docs/manual/sitemap.html.en | 262 + trunk/docs/manual/sitemap.html.es | 271 + trunk/docs/manual/sitemap.html.ja.euc-jp | 263 + trunk/docs/manual/sitemap.html.ko.euc-kr | 269 + trunk/docs/manual/sitemap.xml | 165 + trunk/docs/manual/sitemap.xml.de | 167 + trunk/docs/manual/sitemap.xml.es | 168 + trunk/docs/manual/sitemap.xml.ja | 166 + trunk/docs/manual/sitemap.xml.ko | 170 + trunk/docs/manual/sitemap.xml.meta | 15 + trunk/docs/manual/ssl/index.html | 7 + trunk/docs/manual/ssl/index.html.en | 57 + trunk/docs/manual/ssl/index.html.ja.euc-jp | 59 + trunk/docs/manual/ssl/index.xml | 56 + trunk/docs/manual/ssl/index.xml.ja | 56 + trunk/docs/manual/ssl/index.xml.meta | 12 + trunk/docs/manual/ssl/ssl_compat.html | 3 + trunk/docs/manual/ssl/ssl_compat.html.en | 226 + trunk/docs/manual/ssl/ssl_compat.xml | 261 + trunk/docs/manual/ssl/ssl_compat.xml.meta | 11 + trunk/docs/manual/ssl/ssl_faq.html | 3 + trunk/docs/manual/ssl/ssl_faq.html.en | 1017 ++ trunk/docs/manual/ssl/ssl_faq.xml | 1024 ++ trunk/docs/manual/ssl/ssl_faq.xml.meta | 11 + trunk/docs/manual/ssl/ssl_howto.html | 3 + trunk/docs/manual/ssl/ssl_howto.html.en | 282 + trunk/docs/manual/ssl/ssl_howto.xml | 291 + trunk/docs/manual/ssl/ssl_howto.xml.meta | 11 + trunk/docs/manual/ssl/ssl_intro.html | 7 + trunk/docs/manual/ssl/ssl_intro.html.en | 641 + .../docs/manual/ssl/ssl_intro.html.ja.euc-jp | 695 + trunk/docs/manual/ssl/ssl_intro.xml | 672 + trunk/docs/manual/ssl/ssl_intro.xml.ja | 725 + trunk/docs/manual/ssl/ssl_intro.xml.meta | 12 + trunk/docs/manual/stopping.html | 19 + trunk/docs/manual/stopping.html.de | 252 + trunk/docs/manual/stopping.html.en | 229 + trunk/docs/manual/stopping.html.es | 267 + trunk/docs/manual/stopping.html.ja.euc-jp | 254 + trunk/docs/manual/stopping.html.ko.euc-kr | 205 + trunk/docs/manual/stopping.xml | 225 + trunk/docs/manual/stopping.xml.de | 247 + trunk/docs/manual/stopping.xml.es | 263 + trunk/docs/manual/stopping.xml.ja | 246 + trunk/docs/manual/stopping.xml.ko | 203 + trunk/docs/manual/stopping.xml.meta | 15 + trunk/docs/manual/style/build.properties | 7 + trunk/docs/manual/style/common.dtd | 184 + trunk/docs/manual/style/css/manual-chm.css | 27 + .../manual/style/css/manual-loose-100pc.css | 155 + trunk/docs/manual/style/css/manual-print.css | 717 + .../manual/style/css/manual-zip-100pc.css | 23 + trunk/docs/manual/style/css/manual-zip.css | 24 + trunk/docs/manual/style/css/manual.css | 1017 ++ trunk/docs/manual/style/description.xml | 47 + trunk/docs/manual/style/faq.dtd | 35 + trunk/docs/manual/style/lang-targets.xml | 234 + trunk/docs/manual/style/lang/de.xml | 130 + trunk/docs/manual/style/lang/en.xml | 129 + trunk/docs/manual/style/lang/es.xml | 130 + trunk/docs/manual/style/lang/fr.xml | 130 + trunk/docs/manual/style/lang/ja.xml | 126 + trunk/docs/manual/style/lang/ko.xml | 132 + trunk/docs/manual/style/lang/pt-br.xml | 131 + trunk/docs/manual/style/lang/ru.xml | 116 + trunk/docs/manual/style/latex/atbeginend.sty | 80 + trunk/docs/manual/style/latex/common.xsl | 244 + .../manual/style/latex/directiveindex.xsl | 61 + trunk/docs/manual/style/latex/faq.xsl | 43 + trunk/docs/manual/style/latex/html.xsl | 323 + trunk/docs/manual/style/latex/latex.xsl | 376 + trunk/docs/manual/style/latex/manualpage.xsl | 35 + trunk/docs/manual/style/latex/moduleindex.xsl | 218 + .../manual/style/latex/quickreference.xsl | 140 + trunk/docs/manual/style/latex/synopsis.xsl | 346 + trunk/docs/manual/style/manual.de.xsl | 37 + trunk/docs/manual/style/manual.en.xsl | 37 + trunk/docs/manual/style/manual.es.xsl | 37 + trunk/docs/manual/style/manual.fr.xsl | 37 + trunk/docs/manual/style/manual.ja.xsl | 37 + trunk/docs/manual/style/manual.ko.xsl | 37 + trunk/docs/manual/style/manual.pt-br.xsl | 37 + trunk/docs/manual/style/manual.ru.xsl | 37 + trunk/docs/manual/style/manualpage.dtd | 27 + trunk/docs/manual/style/modulesynopsis.dtd | 76 + trunk/docs/manual/style/sitemap.dtd | 38 + trunk/docs/manual/style/xsl/common.xsl | 1148 ++ .../docs/manual/style/xsl/directiveindex.xsl | 130 + trunk/docs/manual/style/xsl/faq.xsl | 199 + trunk/docs/manual/style/xsl/hhc.xsl | 668 + trunk/docs/manual/style/xsl/hhp.xsl | 316 + trunk/docs/manual/style/xsl/indexpage.xsl | 210 + trunk/docs/manual/style/xsl/language.xsl | 658 + trunk/docs/manual/style/xsl/maf.xsl | 56 + trunk/docs/manual/style/xsl/manualpage.xsl | 87 + trunk/docs/manual/style/xsl/moduleindex.xsl | 333 + trunk/docs/manual/style/xsl/nroff.xsl | 448 + .../docs/manual/style/xsl/quickreference.xsl | 210 + trunk/docs/manual/style/xsl/sitemap.xsl | 242 + trunk/docs/manual/style/xsl/synopsis.xsl | 508 + trunk/docs/manual/style/xsl/typemap.xsl | 80 + .../docs/manual/style/xsl/util/allmodules.xml | 11 + .../manual/style/xsl/util/designations.xml | 11 + trunk/docs/manual/style/xsl/util/lf.xml | 3 + trunk/docs/manual/style/xsl/util/li-end.xml | 1 + trunk/docs/manual/style/xsl/util/li-start.xml | 1 + trunk/docs/manual/style/xsl/util/modtrans.xsl | 44 + trunk/docs/manual/style/xsl/util/nbsp.xml | 3 + trunk/docs/manual/style/xsl/util/tab.xml | 3 + trunk/docs/manual/style/xsl/util/ul-end.xml | 1 + trunk/docs/manual/style/xsl/util/ul-start.xml | 1 + trunk/docs/manual/suexec.html | 11 + trunk/docs/manual/suexec.html.en | 608 + trunk/docs/manual/suexec.html.ja.euc-jp | 609 + trunk/docs/manual/suexec.html.ko.euc-kr | 534 + trunk/docs/manual/suexec.xml | 598 + trunk/docs/manual/suexec.xml.ja | 598 + trunk/docs/manual/suexec.xml.ko | 527 + trunk/docs/manual/suexec.xml.meta | 13 + trunk/docs/manual/upgrading.html | 27 + trunk/docs/manual/upgrading.html.de | 110 + trunk/docs/manual/upgrading.html.en | 107 + trunk/docs/manual/upgrading.html.fr | 164 + trunk/docs/manual/upgrading.html.ja.euc-jp | 224 + trunk/docs/manual/upgrading.html.ko.euc-kr | 206 + trunk/docs/manual/upgrading.html.pt-br | 227 + trunk/docs/manual/upgrading.html.ru.koi8-r | 203 + trunk/docs/manual/upgrading.xml | 93 + trunk/docs/manual/upgrading.xml.de | 95 + trunk/docs/manual/upgrading.xml.ja | 208 + trunk/docs/manual/upgrading.xml.ko | 192 + trunk/docs/manual/upgrading.xml.meta | 17 + trunk/docs/manual/upgrading.xml.pt-br | 215 + trunk/docs/manual/upgrading.xml.ru | 200 + trunk/docs/manual/urlmapping.html | 11 + trunk/docs/manual/urlmapping.html.en | 285 + trunk/docs/manual/urlmapping.html.ja.euc-jp | 284 + trunk/docs/manual/urlmapping.html.ko.euc-kr | 245 + trunk/docs/manual/urlmapping.xml | 306 + trunk/docs/manual/urlmapping.xml.ja | 299 + trunk/docs/manual/urlmapping.xml.ko | 268 + trunk/docs/manual/urlmapping.xml.meta | 13 + trunk/docs/manual/vhosts/details.html | 7 + trunk/docs/manual/vhosts/details.html.en | 439 + .../docs/manual/vhosts/details.html.ko.euc-kr | 382 + trunk/docs/manual/vhosts/details.xml | 433 + trunk/docs/manual/vhosts/details.xml.ko | 377 + trunk/docs/manual/vhosts/details.xml.meta | 12 + trunk/docs/manual/vhosts/examples.html | 11 + trunk/docs/manual/vhosts/examples.html.en | 658 + .../manual/vhosts/examples.html.ja.euc-jp | 646 + .../manual/vhosts/examples.html.ko.euc-kr | 627 + trunk/docs/manual/vhosts/examples.xml | 634 + trunk/docs/manual/vhosts/examples.xml.ja | 622 + trunk/docs/manual/vhosts/examples.xml.ko | 602 + trunk/docs/manual/vhosts/examples.xml.meta | 13 + trunk/docs/manual/vhosts/fd-limits.html | 11 + trunk/docs/manual/vhosts/fd-limits.html.en | 126 + .../manual/vhosts/fd-limits.html.ja.euc-jp | 123 + .../manual/vhosts/fd-limits.html.ko.euc-kr | 120 + trunk/docs/manual/vhosts/fd-limits.xml | 124 + trunk/docs/manual/vhosts/fd-limits.xml.ja | 121 + trunk/docs/manual/vhosts/fd-limits.xml.ko | 119 + trunk/docs/manual/vhosts/fd-limits.xml.meta | 13 + trunk/docs/manual/vhosts/index.html | 15 + trunk/docs/manual/vhosts/index.html.de | 106 + trunk/docs/manual/vhosts/index.html.en | 106 + trunk/docs/manual/vhosts/index.html.ja.euc-jp | 101 + trunk/docs/manual/vhosts/index.html.ko.euc-kr | 104 + trunk/docs/manual/vhosts/index.xml | 107 + trunk/docs/manual/vhosts/index.xml.de | 106 + trunk/docs/manual/vhosts/index.xml.ja | 100 + trunk/docs/manual/vhosts/index.xml.ko | 101 + trunk/docs/manual/vhosts/index.xml.meta | 14 + trunk/docs/manual/vhosts/ip-based.html | 11 + trunk/docs/manual/vhosts/ip-based.html.en | 160 + .../manual/vhosts/ip-based.html.ja.euc-jp | 156 + .../manual/vhosts/ip-based.html.ko.euc-kr | 150 + trunk/docs/manual/vhosts/ip-based.xml | 162 + trunk/docs/manual/vhosts/ip-based.xml.ja | 158 + trunk/docs/manual/vhosts/ip-based.xml.ko | 149 + trunk/docs/manual/vhosts/ip-based.xml.meta | 13 + trunk/docs/manual/vhosts/mass.html | 7 + trunk/docs/manual/vhosts/mass.html.en | 445 + trunk/docs/manual/vhosts/mass.html.ko.euc-kr | 423 + trunk/docs/manual/vhosts/mass.xml | 437 + trunk/docs/manual/vhosts/mass.xml.ko | 412 + trunk/docs/manual/vhosts/mass.xml.meta | 12 + trunk/docs/manual/vhosts/name-based.html | 15 + trunk/docs/manual/vhosts/name-based.html.de | 266 + trunk/docs/manual/vhosts/name-based.html.en | 244 + .../manual/vhosts/name-based.html.ja.euc-jp | 269 + .../manual/vhosts/name-based.html.ko.euc-kr | 234 + trunk/docs/manual/vhosts/name-based.xml | 269 + trunk/docs/manual/vhosts/name-based.xml.de | 298 + trunk/docs/manual/vhosts/name-based.xml.ja | 289 + trunk/docs/manual/vhosts/name-based.xml.ko | 264 + trunk/docs/manual/vhosts/name-based.xml.meta | 14 + trunk/emacs-style | 12 + trunk/httpd.dsp | 128 + trunk/include/.indent.pro | 54 + trunk/include/ap_compat.h | 25 + trunk/include/ap_config.h | 252 + trunk/include/ap_config_layout.h.in | 58 + trunk/include/ap_listen.h | 102 + trunk/include/ap_mmn.h | 134 + trunk/include/ap_mpm.h | 177 + trunk/include/ap_provider.h | 54 + trunk/include/ap_regex.h | 135 + trunk/include/ap_regkey.h | 218 + trunk/include/ap_release.h | 70 + trunk/include/http_config.h | 1051 ++ trunk/include/http_connection.h | 139 + trunk/include/http_core.h | 648 + trunk/include/http_log.h | 333 + trunk/include/http_main.h | 58 + trunk/include/http_protocol.h | 690 + trunk/include/http_request.h | 373 + trunk/include/http_vhost.h | 109 + trunk/include/httpd.h | 1758 ++ trunk/include/mpm_common.h | 303 + trunk/include/scoreboard.h | 223 + trunk/include/util_cfgtree.h | 79 + trunk/include/util_charset.h | 48 + trunk/include/util_ebcdic.h | 78 + trunk/include/util_filter.h | 591 + trunk/include/util_ldap.h | 323 + trunk/include/util_md5.h | 70 + trunk/include/util_script.h | 142 + trunk/include/util_time.h | 85 + trunk/include/util_xml.h | 46 + trunk/libhttpd.dsp | 715 + trunk/modules/Makefile.in | 6 + trunk/modules/NWGNUmakefile | 74 + trunk/modules/README | 54 + trunk/modules/aaa/.indent.pro | 54 + trunk/modules/aaa/Makefile.in | 3 + trunk/modules/aaa/NWGNUauthbasc | 250 + trunk/modules/aaa/NWGNUauthdigt | 250 + trunk/modules/aaa/NWGNUauthnalias | 250 + trunk/modules/aaa/NWGNUauthnano | 250 + trunk/modules/aaa/NWGNUauthndbm | 249 + trunk/modules/aaa/NWGNUauthndef | 250 + trunk/modules/aaa/NWGNUauthnfil | 250 + trunk/modules/aaa/NWGNUauthnzldap | 264 + trunk/modules/aaa/NWGNUauthzdbm | 250 + trunk/modules/aaa/NWGNUauthzdef | 250 + trunk/modules/aaa/NWGNUauthzgrp | 250 + trunk/modules/aaa/NWGNUauthzusr | 250 + trunk/modules/aaa/NWGNUmakefile | 261 + trunk/modules/aaa/config.m4 | 54 + trunk/modules/aaa/mod_auth.h | 75 + trunk/modules/aaa/mod_auth_basic.c | 314 + trunk/modules/aaa/mod_auth_basic.dsp | 128 + trunk/modules/aaa/mod_auth_digest.c | 2059 +++ trunk/modules/aaa/mod_auth_digest.dsp | 128 + trunk/modules/aaa/mod_authn_alias.c | 209 + trunk/modules/aaa/mod_authn_anon.c | 214 + trunk/modules/aaa/mod_authn_anon.dsp | 128 + trunk/modules/aaa/mod_authn_dbm.c | 205 + trunk/modules/aaa/mod_authn_dbm.dsp | 128 + trunk/modules/aaa/mod_authn_default.c | 103 + trunk/modules/aaa/mod_authn_default.dsp | 128 + trunk/modules/aaa/mod_authn_file.c | 179 + trunk/modules/aaa/mod_authn_file.dsp | 128 + trunk/modules/aaa/mod_authnz_ldap.c | 1179 ++ trunk/modules/aaa/mod_authnz_ldap.dsp | 128 + trunk/modules/aaa/mod_authz_dbm.c | 283 + trunk/modules/aaa/mod_authz_dbm.dsp | 128 + trunk/modules/aaa/mod_authz_default.c | 115 + trunk/modules/aaa/mod_authz_default.dsp | 128 + trunk/modules/aaa/mod_authz_groupfile.c | 284 + trunk/modules/aaa/mod_authz_groupfile.dsp | 128 + trunk/modules/aaa/mod_authz_host.c | 322 + trunk/modules/aaa/mod_authz_host.dsp | 128 + trunk/modules/aaa/mod_authz_owner.c | 239 + trunk/modules/aaa/mod_authz_user.c | 129 + trunk/modules/aaa/mod_authz_user.dsp | 128 + trunk/modules/arch/netware/libprews.c | 80 + trunk/modules/arch/netware/mod_auth_basic.def | 1 + .../modules/arch/netware/mod_auth_digest.def | 1 + trunk/modules/arch/netware/mod_authn_anon.def | 1 + trunk/modules/arch/netware/mod_authn_dbm.def | 2 + .../arch/netware/mod_authn_default.def | 1 + trunk/modules/arch/netware/mod_authn_file.def | 3 + trunk/modules/arch/netware/mod_authz_dbm.def | 1 + .../arch/netware/mod_authz_default.def | 1 + .../arch/netware/mod_authz_groupfile.def | 2 + trunk/modules/arch/netware/mod_authz_user.def | 1 + trunk/modules/arch/netware/mod_cache.def | 5 + trunk/modules/arch/netware/mod_cern_meta.def | 1 + trunk/modules/arch/netware/mod_dav.def | 3 + trunk/modules/arch/netware/mod_disk_cache.def | 3 + trunk/modules/arch/netware/mod_echo.def | 2 + trunk/modules/arch/netware/mod_expires.def | 1 + trunk/modules/arch/netware/mod_file_cache.def | 2 + trunk/modules/arch/netware/mod_headers.def | 1 + trunk/modules/arch/netware/mod_info.def | 1 + trunk/modules/arch/netware/mod_logio.def | 2 + trunk/modules/arch/netware/mod_mem_cache.def | 3 + trunk/modules/arch/netware/mod_mime_magic.def | 1 + trunk/modules/arch/netware/mod_netware.c | 194 + trunk/modules/arch/netware/mod_nw_ssl.c | 1276 ++ trunk/modules/arch/netware/mod_proxy.def | 6 + .../arch/netware/mod_proxy_connect.def | 4 + trunk/modules/arch/netware/mod_proxy_ftp.def | 4 + trunk/modules/arch/netware/mod_proxy_http.def | 7 + trunk/modules/arch/netware/mod_rewrite.def | 1 + trunk/modules/arch/netware/mod_speling.def | 1 + trunk/modules/arch/netware/mod_status.def | 2 + trunk/modules/arch/netware/mod_unique_id.def | 1 + trunk/modules/arch/netware/mod_usertrack.def | 1 + .../modules/arch/netware/mod_vhost_alias.def | 2 + trunk/modules/arch/netware/moddavfs.def | 1 + trunk/modules/arch/win32/Makefile.in | 3 + trunk/modules/arch/win32/config.m4 | 9 + trunk/modules/arch/win32/mod_isapi.c | 1647 ++ trunk/modules/arch/win32/mod_isapi.dsp | 132 + trunk/modules/arch/win32/mod_isapi.h | 260 + trunk/modules/arch/win32/mod_win32.c | 574 + trunk/modules/cache/.indent.pro | 54 + trunk/modules/cache/Makefile.in | 3 + trunk/modules/cache/NWGNUdsk_cach | 266 + trunk/modules/cache/NWGNUmakefile | 246 + trunk/modules/cache/NWGNUmem_cach | 270 + trunk/modules/cache/NWGNUmod_cach | 269 + trunk/modules/cache/cache_cache.c | 171 + trunk/modules/cache/cache_cache.h | 112 + trunk/modules/cache/cache_hash.c | 290 + trunk/modules/cache/cache_hash.h | 161 + trunk/modules/cache/cache_pqueue.c | 290 + trunk/modules/cache/cache_pqueue.h | 160 + trunk/modules/cache/cache_storage.c | 328 + trunk/modules/cache/cache_util.c | 536 + trunk/modules/cache/config.m4 | 26 + trunk/modules/cache/mod_cache.c | 1047 ++ trunk/modules/cache/mod_cache.dsp | 168 + trunk/modules/cache/mod_cache.h | 320 + trunk/modules/cache/mod_cache.imp | 9 + trunk/modules/cache/mod_disk_cache.c | 822 + trunk/modules/cache/mod_disk_cache.dsp | 128 + trunk/modules/cache/mod_file_cache.c | 417 + trunk/modules/cache/mod_file_cache.dsp | 128 + trunk/modules/cache/mod_file_cache.exp | 1 + trunk/modules/cache/mod_mem_cache.c | 1087 ++ trunk/modules/cache/mod_mem_cache.dsp | 128 + trunk/modules/config5.m4 | 57 + trunk/modules/dav/fs/Makefile.in | 3 + trunk/modules/dav/fs/NWGNUmakefile | 273 + trunk/modules/dav/fs/config6.m4 | 23 + trunk/modules/dav/fs/dbm.c | 753 + trunk/modules/dav/fs/lock.c | 1517 ++ trunk/modules/dav/fs/mod_dav_fs.c | 108 + trunk/modules/dav/fs/mod_dav_fs.dsp | 152 + trunk/modules/dav/fs/repos.c | 2157 +++ trunk/modules/dav/fs/repos.h | 78 + trunk/modules/dav/lock/Makefile.in | 3 + trunk/modules/dav/lock/NWGNUmakefile | 261 + trunk/modules/dav/lock/config6.m4 | 17 + trunk/modules/dav/lock/locks.c | 1215 ++ trunk/modules/dav/lock/locks.h | 27 + trunk/modules/dav/lock/mod_dav_lock.c | 104 + trunk/modules/dav/main/Makefile.in | 3 + trunk/modules/dav/main/NWGNUmakefile | 271 + trunk/modules/dav/main/config5.m4 | 22 + trunk/modules/dav/main/dav.imp | 64 + trunk/modules/dav/main/liveprop.c | 140 + trunk/modules/dav/main/mod_dav.c | 4852 +++++ trunk/modules/dav/main/mod_dav.dsp | 164 + trunk/modules/dav/main/mod_dav.h | 2420 +++ trunk/modules/dav/main/props.c | 1121 ++ trunk/modules/dav/main/providers.c | 33 + trunk/modules/dav/main/std_liveprop.c | 194 + trunk/modules/dav/main/util.c | 2041 +++ trunk/modules/dav/main/util_lock.c | 791 + trunk/modules/debug/Makefile.in | 3 + trunk/modules/debug/NWGNUmakefile | 246 + trunk/modules/debug/NWGNUmodbucketeer | 250 + trunk/modules/debug/NWGNUmoddumpio | 250 + trunk/modules/debug/README | 1 + trunk/modules/debug/config.m4 | 7 + trunk/modules/debug/mod_bucketeer.c | 184 + trunk/modules/debug/mod_bucketeer.dsp | 128 + trunk/modules/debug/mod_dumpio.c | 214 + trunk/modules/debug/mod_dumpio.dsp | 128 + trunk/modules/echo/.indent.pro | 54 + trunk/modules/echo/Makefile.in | 3 + trunk/modules/echo/NWGNUmakefile | 261 + trunk/modules/echo/config.m4 | 9 + trunk/modules/echo/mod_echo.c | 105 + trunk/modules/echo/mod_echo.dsp | 128 + trunk/modules/experimental/.indent.pro | 54 + trunk/modules/experimental/Makefile.in | 3 + trunk/modules/experimental/NWGNUcharsetl | 260 + trunk/modules/experimental/NWGNUexample | 260 + trunk/modules/experimental/NWGNUmakefile | 246 + trunk/modules/experimental/NWGNUmod_filter | 250 + trunk/modules/experimental/README | 41 + trunk/modules/experimental/config.m4 | 17 + trunk/modules/experimental/mod_case_filter.c | 130 + .../modules/experimental/mod_case_filter_in.c | 160 + trunk/modules/experimental/mod_charset_lite.c | 1138 ++ .../modules/experimental/mod_charset_lite.dsp | 124 + .../modules/experimental/mod_charset_lite.exp | 1 + trunk/modules/experimental/mod_dbd.c | 461 + trunk/modules/experimental/mod_dbd.h | 57 + trunk/modules/experimental/mod_example.c | 1345 ++ trunk/modules/experimental/mod_filter.c | 848 + trunk/modules/filters/.indent.pro | 54 + trunk/modules/filters/Makefile.in | 3 + trunk/modules/filters/NWGNUdeflate | 281 + trunk/modules/filters/NWGNUextfiltr | 250 + trunk/modules/filters/NWGNUmakefile | 255 + trunk/modules/filters/config.m4 | 62 + trunk/modules/filters/mod_deflate.c | 1123 ++ trunk/modules/filters/mod_deflate.dsp | 128 + trunk/modules/filters/mod_deflate.exp | 1 + trunk/modules/filters/mod_ext_filter.c | 907 + trunk/modules/filters/mod_ext_filter.dsp | 128 + trunk/modules/filters/mod_ext_filter.exp | 1 + trunk/modules/filters/mod_include.c | 3842 ++++ trunk/modules/filters/mod_include.dsp | 132 + trunk/modules/filters/mod_include.exp | 1 + trunk/modules/filters/mod_include.h | 106 + trunk/modules/generators/.indent.pro | 54 + trunk/modules/generators/Makefile.in | 3 + trunk/modules/generators/NWGNUautoindex | 251 + trunk/modules/generators/NWGNUinfo | 250 + trunk/modules/generators/NWGNUmakefile | 250 + trunk/modules/generators/NWGNUmod_asis | 251 + trunk/modules/generators/NWGNUmod_cgi | 252 + trunk/modules/generators/NWGNUstatus | 250 + trunk/modules/generators/config5.m4 | 27 + trunk/modules/generators/mod_asis.c | 145 + trunk/modules/generators/mod_asis.dsp | 128 + trunk/modules/generators/mod_asis.exp | 1 + trunk/modules/generators/mod_autoindex.c | 2265 +++ trunk/modules/generators/mod_autoindex.dsp | 128 + trunk/modules/generators/mod_autoindex.exp | 1 + trunk/modules/generators/mod_cgi.c | 1233 ++ trunk/modules/generators/mod_cgi.dsp | 132 + trunk/modules/generators/mod_cgi.exp | 1 + trunk/modules/generators/mod_cgi.h | 59 + trunk/modules/generators/mod_cgid.c | 1787 ++ trunk/modules/generators/mod_cgid.exp | 1 + trunk/modules/generators/mod_info.c | 811 + trunk/modules/generators/mod_info.dsp | 128 + trunk/modules/generators/mod_info.exp | 1 + trunk/modules/generators/mod_status.c | 865 + trunk/modules/generators/mod_status.dsp | 128 + trunk/modules/generators/mod_status.exp | 1 + trunk/modules/generators/mod_status.h | 54 + trunk/modules/generators/mod_suexec.c | 138 + trunk/modules/generators/mod_suexec.h | 23 + trunk/modules/http/.indent.pro | 54 + trunk/modules/http/Makefile.in | 3 + trunk/modules/http/byterange_filter.c | 383 + trunk/modules/http/chunk_filter.c | 168 + trunk/modules/http/config2.m4 | 20 + trunk/modules/http/http_core.c | 254 + trunk/modules/http/http_etag.c | 221 + trunk/modules/http/http_filters.c | 1248 ++ trunk/modules/http/http_protocol.c | 1400 ++ trunk/modules/http/http_request.c | 557 + trunk/modules/http/mod_core.h | 83 + trunk/modules/http/mod_mime.c | 991 + trunk/modules/http/mod_mime.dsp | 128 + trunk/modules/http/mod_mime.exp | 1 + trunk/modules/ldap/Makefile.in | 3 + trunk/modules/ldap/NWGNUmakefile | 266 + trunk/modules/ldap/README.ldap | 47 + trunk/modules/ldap/config.m4 | 9 + trunk/modules/ldap/mod_ldap.dsp | 140 + trunk/modules/ldap/util_ldap.c | 2100 +++ trunk/modules/ldap/util_ldap_cache.c | 441 + trunk/modules/ldap/util_ldap_cache.h | 191 + trunk/modules/ldap/util_ldap_cache_mgr.c | 759 + trunk/modules/loggers/.indent.pro | 54 + trunk/modules/loggers/Makefile.in | 3 + trunk/modules/loggers/NWGNUforensic | 261 + trunk/modules/loggers/NWGNUmakefile | 247 + trunk/modules/loggers/NWGNUmodlogio | 261 + trunk/modules/loggers/config.m4 | 17 + trunk/modules/loggers/mod_log_config.c | 1522 ++ trunk/modules/loggers/mod_log_config.dsp | 128 + trunk/modules/loggers/mod_log_config.exp | 1 + trunk/modules/loggers/mod_log_config.h | 63 + trunk/modules/loggers/mod_log_forensic.c | 288 + trunk/modules/loggers/mod_log_forensic.dsp | 128 + trunk/modules/loggers/mod_log_forensic.exp | 1 + trunk/modules/loggers/mod_logio.c | 192 + trunk/modules/loggers/mod_logio.dsp | 128 + trunk/modules/mappers/.indent.pro | 54 + trunk/modules/mappers/Makefile.in | 3 + trunk/modules/mappers/NWGNUactions | 249 + trunk/modules/mappers/NWGNUimagemap | 250 + trunk/modules/mappers/NWGNUmakefile | 250 + trunk/modules/mappers/NWGNUrewrite | 250 + trunk/modules/mappers/NWGNUspeling | 249 + trunk/modules/mappers/NWGNUuserdir | 250 + trunk/modules/mappers/NWGNUvhost | 249 + trunk/modules/mappers/config9.m4 | 61 + trunk/modules/mappers/mod_actions.c | 221 + trunk/modules/mappers/mod_actions.dsp | 128 + trunk/modules/mappers/mod_actions.exp | 1 + trunk/modules/mappers/mod_alias.c | 484 + trunk/modules/mappers/mod_alias.dsp | 128 + trunk/modules/mappers/mod_alias.exp | 1 + trunk/modules/mappers/mod_dir.c | 247 + trunk/modules/mappers/mod_dir.dsp | 128 + trunk/modules/mappers/mod_dir.exp | 1 + trunk/modules/mappers/mod_imagemap.c | 894 + trunk/modules/mappers/mod_imagemap.dsp | 128 + trunk/modules/mappers/mod_imagemap.exp | 1 + trunk/modules/mappers/mod_negotiation.c | 3212 ++++ trunk/modules/mappers/mod_negotiation.dsp | 128 + trunk/modules/mappers/mod_negotiation.exp | 1 + trunk/modules/mappers/mod_rewrite.c | 4826 +++++ trunk/modules/mappers/mod_rewrite.dsp | 128 + trunk/modules/mappers/mod_rewrite.exp | 1 + trunk/modules/mappers/mod_rewrite.h | 30 + trunk/modules/mappers/mod_so.c | 431 + trunk/modules/mappers/mod_so.h | 27 + trunk/modules/mappers/mod_speling.c | 533 + trunk/modules/mappers/mod_speling.dsp | 128 + trunk/modules/mappers/mod_speling.exp | 1 + trunk/modules/mappers/mod_userdir.c | 369 + trunk/modules/mappers/mod_userdir.dsp | 128 + trunk/modules/mappers/mod_userdir.exp | 1 + trunk/modules/mappers/mod_vhost_alias.c | 457 + trunk/modules/mappers/mod_vhost_alias.dsp | 128 + trunk/modules/mappers/mod_vhost_alias.exp | 1 + trunk/modules/metadata/.indent.pro | 54 + trunk/modules/metadata/Makefile.in | 3 + trunk/modules/metadata/NWGNUcernmeta | 250 + trunk/modules/metadata/NWGNUexpires | 250 + trunk/modules/metadata/NWGNUheaders | 251 + trunk/modules/metadata/NWGNUmakefile | 253 + trunk/modules/metadata/NWGNUmimemagi | 250 + trunk/modules/metadata/NWGNUmodident | 250 + trunk/modules/metadata/NWGNUmodversion | 250 + trunk/modules/metadata/NWGNUuniqueid | 259 + trunk/modules/metadata/NWGNUusertrk | 250 + trunk/modules/metadata/config.m4 | 23 + trunk/modules/metadata/mod_cern_meta.c | 371 + trunk/modules/metadata/mod_cern_meta.dsp | 128 + trunk/modules/metadata/mod_cern_meta.exp | 1 + trunk/modules/metadata/mod_env.c | 179 + trunk/modules/metadata/mod_env.dsp | 128 + trunk/modules/metadata/mod_env.exp | 1 + trunk/modules/metadata/mod_expires.c | 563 + trunk/modules/metadata/mod_expires.dsp | 128 + trunk/modules/metadata/mod_expires.exp | 1 + trunk/modules/metadata/mod_headers.c | 748 + trunk/modules/metadata/mod_headers.dsp | 128 + trunk/modules/metadata/mod_headers.exp | 1 + trunk/modules/metadata/mod_ident.c | 352 + trunk/modules/metadata/mod_ident.dsp | 128 + trunk/modules/metadata/mod_ident.exp | 1 + trunk/modules/metadata/mod_mime_magic.c | 2477 +++ trunk/modules/metadata/mod_mime_magic.dsp | 128 + trunk/modules/metadata/mod_mime_magic.exp | 1 + trunk/modules/metadata/mod_setenvif.c | 586 + trunk/modules/metadata/mod_setenvif.dsp | 128 + trunk/modules/metadata/mod_setenvif.exp | 1 + trunk/modules/metadata/mod_unique_id.c | 367 + trunk/modules/metadata/mod_unique_id.dsp | 128 + trunk/modules/metadata/mod_unique_id.exp | 1 + trunk/modules/metadata/mod_usertrack.c | 453 + trunk/modules/metadata/mod_usertrack.dsp | 128 + trunk/modules/metadata/mod_usertrack.exp | 1 + trunk/modules/metadata/mod_version.c | 311 + trunk/modules/metadata/mod_version.dsp | 128 + trunk/modules/metadata/mod_version.exp | 1 + trunk/modules/proxy/.indent.pro | 58 + trunk/modules/proxy/CHANGES | 223 + trunk/modules/proxy/Makefile.in | 3 + trunk/modules/proxy/NWGNUmakefile | 249 + trunk/modules/proxy/NWGNUproxy | 272 + trunk/modules/proxy/NWGNUproxyajp | 273 + trunk/modules/proxy/NWGNUproxybalancer | 270 + trunk/modules/proxy/NWGNUproxycon | 256 + trunk/modules/proxy/NWGNUproxyftp | 267 + trunk/modules/proxy/NWGNUproxyhtp | 268 + trunk/modules/proxy/ajp.h | 462 + trunk/modules/proxy/ajp_header.c | 719 + trunk/modules/proxy/ajp_header.h | 165 + trunk/modules/proxy/ajp_link.c | 126 + trunk/modules/proxy/ajp_msg.c | 584 + trunk/modules/proxy/config.m4 | 42 + trunk/modules/proxy/libproxy.exp | 1 + trunk/modules/proxy/mod_proxy.c | 1874 ++ trunk/modules/proxy/mod_proxy.dsp | 140 + trunk/modules/proxy/mod_proxy.h | 656 + trunk/modules/proxy/mod_proxy_ajp.c | 469 + trunk/modules/proxy/mod_proxy_ajp.dsp | 160 + trunk/modules/proxy/mod_proxy_balancer.c | 897 + trunk/modules/proxy/mod_proxy_balancer.dsp | 136 + trunk/modules/proxy/mod_proxy_connect.c | 399 + trunk/modules/proxy/mod_proxy_connect.dsp | 136 + trunk/modules/proxy/mod_proxy_ftp.c | 1892 ++ trunk/modules/proxy/mod_proxy_ftp.dsp | 136 + trunk/modules/proxy/mod_proxy_http.c | 1550 ++ trunk/modules/proxy/mod_proxy_http.dsp | 136 + trunk/modules/proxy/proxy_util.c | 2055 +++ trunk/modules/ssl/Makefile.in | 38 + trunk/modules/ssl/NWGNUmakefile | 289 + trunk/modules/ssl/README | 107 + trunk/modules/ssl/README.dsov.fig | 346 + trunk/modules/ssl/README.dsov.ps | 1138 ++ trunk/modules/ssl/config.m4 | 131 + trunk/modules/ssl/mod_ssl.c | 516 + trunk/modules/ssl/mod_ssl.dsp | 328 + trunk/modules/ssl/mod_ssl.h | 52 + trunk/modules/ssl/ssl_engine_config.c | 1433 ++ trunk/modules/ssl/ssl_engine_dh.c | 208 + trunk/modules/ssl/ssl_engine_init.c | 1264 ++ trunk/modules/ssl/ssl_engine_io.c | 1608 ++ trunk/modules/ssl/ssl_engine_kernel.c | 1846 ++ trunk/modules/ssl/ssl_engine_log.c | 101 + trunk/modules/ssl/ssl_engine_mutex.c | 124 + trunk/modules/ssl/ssl_engine_pphrase.c | 789 + trunk/modules/ssl/ssl_engine_rand.c | 179 + trunk/modules/ssl/ssl_engine_vars.c | 784 + trunk/modules/ssl/ssl_expr.c | 82 + trunk/modules/ssl/ssl_expr.h | 104 + trunk/modules/ssl/ssl_expr_eval.c | 254 + trunk/modules/ssl/ssl_expr_parse.c | 1081 ++ trunk/modules/ssl/ssl_expr_parse.h | 27 + trunk/modules/ssl/ssl_expr_parse.y | 147 + trunk/modules/ssl/ssl_expr_scan.c | 1970 ++ trunk/modules/ssl/ssl_expr_scan.l | 224 + trunk/modules/ssl/ssl_private.h | 649 + trunk/modules/ssl/ssl_scache.c | 176 + trunk/modules/ssl/ssl_scache_dbm.c | 463 + trunk/modules/ssl/ssl_scache_dc.c | 176 + trunk/modules/ssl/ssl_scache_shmcb.c | 1343 ++ trunk/modules/ssl/ssl_toolkit_compat.h | 231 + trunk/modules/ssl/ssl_util.c | 348 + trunk/modules/ssl/ssl_util_ssl.c | 572 + trunk/modules/ssl/ssl_util_ssl.h | 80 + trunk/modules/test/.indent.pro | 54 + trunk/modules/test/Makefile.in | 3 + trunk/modules/test/README | 1 + trunk/modules/test/config.m4 | 9 + trunk/modules/test/mod_optional_fn_export.c | 48 + trunk/modules/test/mod_optional_fn_export.h | 19 + trunk/modules/test/mod_optional_fn_import.c | 55 + trunk/modules/test/mod_optional_hook_export.c | 44 + trunk/modules/test/mod_optional_hook_export.h | 24 + trunk/modules/test/mod_optional_hook_import.c | 45 + trunk/os/.indent.pro | 54 + trunk/os/Makefile.in | 4 + trunk/os/beos/Makefile.in | 5 + trunk/os/beos/beosd.c | 166 + trunk/os/beos/beosd.h | 60 + trunk/os/beos/config.m4 | 3 + trunk/os/beos/os.c | 37 + trunk/os/beos/os.h | 30 + trunk/os/bs2000/ebcdic.c | 210 + trunk/os/bs2000/ebcdic.h | 24 + trunk/os/bs2000/os.c | 143 + trunk/os/bs2000/os.h | 34 + trunk/os/config.m4 | 26 + trunk/os/netware/Apache.def | 5 + trunk/os/netware/apache.xdc | Bin 0 -> 128 bytes trunk/os/netware/modules.c | 105 + trunk/os/netware/os.h | 40 + trunk/os/netware/pre_nw.h | 70 + trunk/os/netware/util_nw.c | 105 + trunk/os/os2/Makefile.in | 5 + trunk/os/os2/config.m4 | 3 + trunk/os/os2/core.mk | 7 + trunk/os/os2/core_header.def | 19 + trunk/os/os2/os.h | 33 + trunk/os/os2/util_os2.c | 39 + trunk/os/tpf/TPFExport | 7 + trunk/os/tpf/ebcdic.c | 179 + trunk/os/tpf/ebcdic.h | 24 + trunk/os/tpf/os.c | 132 + trunk/os/tpf/os.h | 87 + trunk/os/tpf/samples/linkdll.jcl | 121 + trunk/os/tpf/samples/loadset.jcl | 58 + trunk/os/unix/Makefile.in | 5 + trunk/os/unix/config.m4 | 7 + trunk/os/unix/os.h | 36 + trunk/os/unix/unixd.c | 718 + trunk/os/unix/unixd.h | 109 + trunk/os/win32/BaseAddr.ref | 73 + trunk/os/win32/ap_regkey.c | 644 + trunk/os/win32/modules.c | 57 + trunk/os/win32/os.h | 123 + trunk/os/win32/util_win32.c | 186 + trunk/server/.indent.pro | 54 + trunk/server/Makefile.in | 86 + trunk/server/NWGNUmakefile | 251 + trunk/server/buildmark.c | 29 + trunk/server/config.c | 2166 +++ trunk/server/config.m4 | 15 + trunk/server/connection.c | 179 + trunk/server/core.c | 3807 ++++ trunk/server/core_filters.c | 960 + trunk/server/eoc_bucket.c | 55 + trunk/server/error_bucket.c | 74 + trunk/server/gen_test_char.c | 121 + trunk/server/gen_test_char.dsp | 94 + trunk/server/listen.c | 565 + trunk/server/log.c | 987 + trunk/server/main.c | 729 + trunk/server/mpm/MPM.NAMING | 15 + trunk/server/mpm/Makefile.in | 4 + trunk/server/mpm/beos/Makefile.in | 5 + trunk/server/mpm/beos/beos.c | 1207 ++ trunk/server/mpm/beos/beos.h | 26 + trunk/server/mpm/beos/config5.m4 | 7 + trunk/server/mpm/beos/mpm.h | 40 + trunk/server/mpm/beos/mpm_default.h | 76 + trunk/server/mpm/config.m4 | 63 + .../server/mpm/experimental/event/Makefile.in | 5 + .../server/mpm/experimental/event/config5.m4 | 6 + trunk/server/mpm/experimental/event/event.c | 2385 +++ trunk/server/mpm/experimental/event/fdqueue.c | 420 + trunk/server/mpm/experimental/event/fdqueue.h | 73 + trunk/server/mpm/experimental/event/mpm.h | 51 + .../mpm/experimental/event/mpm_default.h | 69 + trunk/server/mpm/experimental/event/pod.c | 109 + trunk/server/mpm/experimental/event/pod.h | 51 + .../mpm/experimental/leader/Makefile.in | 5 + trunk/server/mpm/experimental/leader/README | 15 + .../server/mpm/experimental/leader/config5.m4 | 6 + trunk/server/mpm/experimental/leader/leader.c | 1998 ++ trunk/server/mpm/experimental/leader/mpm.h | 52 + .../mpm/experimental/leader/mpm_default.h | 69 + .../mpm/experimental/perchild/Makefile.in | 5 + .../mpm/experimental/perchild/config5.m4 | 6 + trunk/server/mpm/experimental/perchild/mpm.h | 60 + .../mpm/experimental/perchild/mpm_default.h | 71 + .../mpm/experimental/perchild/perchild.c | 2051 +++ .../mpm/experimental/threadpool/Makefile.in | 5 + .../server/mpm/experimental/threadpool/README | 12 + .../mpm/experimental/threadpool/config5.m4 | 6 + .../server/mpm/experimental/threadpool/mpm.h | 51 + .../mpm/experimental/threadpool/mpm_default.h | 69 + .../server/mpm/experimental/threadpool/pod.c | 108 + .../server/mpm/experimental/threadpool/pod.h | 50 + .../mpm/experimental/threadpool/threadpool.c | 2252 +++ trunk/server/mpm/mpmt_os2/Makefile.in | 5 + trunk/server/mpm/mpmt_os2/config5.m4 | 5 + trunk/server/mpm/mpmt_os2/mpm.h | 34 + trunk/server/mpm/mpmt_os2/mpm_default.h | 59 + trunk/server/mpm/mpmt_os2/mpmt_os2.c | 577 + trunk/server/mpm/mpmt_os2/mpmt_os2_child.c | 480 + trunk/server/mpm/netware/mpm.h | 48 + trunk/server/mpm/netware/mpm_default.h | 114 + trunk/server/mpm/netware/mpm_netware.c | 1291 ++ trunk/server/mpm/prefork/Makefile.in | 5 + trunk/server/mpm/prefork/config.m4 | 3 + trunk/server/mpm/prefork/mpm.h | 51 + trunk/server/mpm/prefork/mpm_default.h | 65 + trunk/server/mpm/prefork/prefork.c | 1377 ++ trunk/server/mpm/winnt/Win9xConHook.c | 697 + trunk/server/mpm/winnt/Win9xConHook.def | 10 + trunk/server/mpm/winnt/Win9xConHook.dsp | 103 + trunk/server/mpm/winnt/Win9xConHook.h | 57 + trunk/server/mpm/winnt/child.c | 1157 ++ trunk/server/mpm/winnt/mpm.h | 40 + trunk/server/mpm/winnt/mpm_default.h | 80 + trunk/server/mpm/winnt/mpm_winnt.c | 1724 ++ trunk/server/mpm/winnt/mpm_winnt.h | 121 + trunk/server/mpm/winnt/nt_eventlog.c | 189 + trunk/server/mpm/winnt/service.c | 1346 ++ trunk/server/mpm/worker/Makefile.in | 5 + trunk/server/mpm/worker/config5.m4 | 6 + trunk/server/mpm/worker/fdqueue.c | 384 + trunk/server/mpm/worker/fdqueue.h | 64 + trunk/server/mpm/worker/mpm.h | 51 + trunk/server/mpm/worker/mpm_default.h | 69 + trunk/server/mpm/worker/pod.c | 110 + trunk/server/mpm/worker/pod.h | 50 + trunk/server/mpm/worker/worker.c | 2165 +++ trunk/server/mpm_common.c | 1153 ++ trunk/server/protocol.c | 1580 ++ trunk/server/provider.c | 98 + trunk/server/request.c | 1898 ++ trunk/server/scoreboard.c | 498 + trunk/server/util.c | 2130 +++ trunk/server/util_cfgtree.c | 47 + trunk/server/util_charset.c | 42 + trunk/server/util_debug.c | 128 + trunk/server/util_ebcdic.c | 112 + trunk/server/util_filter.c | 622 + trunk/server/util_md5.c | 172 + trunk/server/util_pcre.c | 224 + trunk/server/util_script.c | 704 + trunk/server/util_time.c | 240 + trunk/server/util_xml.c | 135 + trunk/server/vhost.c | 1065 ++ trunk/srclib/Makefile.in | 5 + trunk/srclib/pcre/AUTHORS | 6 + trunk/srclib/pcre/COPYING | 45 + trunk/srclib/pcre/ChangeLog | 1650 ++ trunk/srclib/pcre/INSTALL | 185 + trunk/srclib/pcre/LICENCE | 45 + trunk/srclib/pcre/Makefile.in | 20 + trunk/srclib/pcre/NEWS | 201 + trunk/srclib/pcre/NON-UNIX-USE | 244 + trunk/srclib/pcre/NWGNUmakefile | 267 + trunk/srclib/pcre/README | 427 + trunk/srclib/pcre/RunTest.in | 192 + trunk/srclib/pcre/config.hw | 107 + trunk/srclib/pcre/config.in | 107 + trunk/srclib/pcre/configure.in | 185 + trunk/srclib/pcre/dftables.c | 173 + trunk/srclib/pcre/dftables.dsp | 165 + trunk/srclib/pcre/dll.mk | 60 + trunk/srclib/pcre/doc/README_httpd | 6 + trunk/srclib/pcre/get.c | 357 + trunk/srclib/pcre/install-sh | 251 + trunk/srclib/pcre/internal.h | 752 + trunk/srclib/pcre/libpcre.def | 19 + trunk/srclib/pcre/libpcre.pc.in | 12 + trunk/srclib/pcre/libpcreposix.def | 24 + trunk/srclib/pcre/maketables.c | 146 + trunk/srclib/pcre/makevp.bat | 25 + trunk/srclib/pcre/mkinstalldirs | 40 + trunk/srclib/pcre/pcre-config.in | 66 + trunk/srclib/pcre/pcre.c | 9196 ++++++++++ trunk/srclib/pcre/pcre.def | 22 + trunk/srclib/pcre/pcre.dsp | 193 + trunk/srclib/pcre/pcre.hw | 239 + trunk/srclib/pcre/pcre.in | 239 + trunk/srclib/pcre/pcredemo.c | 324 + trunk/srclib/pcre/pcregrep.c | 673 + trunk/srclib/pcre/pcreposix.c | 316 + trunk/srclib/pcre/pcreposix.dsp | 154 + trunk/srclib/pcre/pcretest.c | 1786 ++ trunk/srclib/pcre/perltest | 211 + trunk/srclib/pcre/perltest8 | 208 + trunk/srclib/pcre/pgrep.c | 225 + trunk/srclib/pcre/printint.c | 461 + trunk/srclib/pcre/study.c | 484 + trunk/srclib/pcre/testdata/testinput1 | 3841 ++++ trunk/srclib/pcre/testdata/testinput2 | 1396 ++ trunk/srclib/pcre/testdata/testinput3 | 65 + trunk/srclib/pcre/testdata/testinput4 | 513 + trunk/srclib/pcre/testdata/testinput5 | 263 + trunk/srclib/pcre/testdata/testinput6 | 517 + trunk/srclib/pcre/testdata/testoutput1 | 6274 +++++++ trunk/srclib/pcre/testdata/testoutput2 | 5607 ++++++ trunk/srclib/pcre/testdata/testoutput3 | 115 + trunk/srclib/pcre/testdata/testoutput4 | 903 + trunk/srclib/pcre/testdata/testoutput5 | 1075 ++ trunk/srclib/pcre/testdata/testoutput6 | 1013 ++ trunk/srclib/pcre/ucp.c | 151 + trunk/srclib/pcre/ucp.h | 58 + trunk/srclib/pcre/ucpinternal.h | 91 + trunk/srclib/pcre/ucptable.c | 15105 ++++++++++++++++ trunk/srclib/pcre/ucptypetable.c | 93 + trunk/support/.indent.pro | 54 + trunk/support/Makefile.in | 67 + trunk/support/NWGNUab | 254 + trunk/support/NWGNUhtcacheclean | 252 + trunk/support/NWGNUhtdbm | 252 + trunk/support/NWGNUhtdigest | 252 + trunk/support/NWGNUhtpasswd | 252 + trunk/support/NWGNUlogres | 259 + trunk/support/NWGNUmakefile | 250 + trunk/support/NWGNUrotlogs | 251 + trunk/support/README | 62 + trunk/support/SHA1/README.sha1 | 34 + trunk/support/SHA1/convert-sha1.pl | 36 + trunk/support/SHA1/htpasswd-sha1.pl | 22 + trunk/support/SHA1/ldif-sha1.example | 19 + trunk/support/ab.c | 2165 +++ trunk/support/ab.dsp | 123 + trunk/support/abs.dsp | 134 + trunk/support/apachectl.in | 105 + trunk/support/apxs.in | 766 + trunk/support/check_forensic | 51 + trunk/support/checkgid.c | 110 + trunk/support/config.m4 | 104 + trunk/support/dbmmanage.in | 312 + trunk/support/envvars-std.in | 24 + trunk/support/htcacheclean.c | 1031 ++ trunk/support/htdbm.c | 582 + trunk/support/htdbm.dsp | 123 + trunk/support/htdigest.c | 291 + trunk/support/htdigest.dsp | 123 + trunk/support/htpasswd.c | 612 + trunk/support/htpasswd.dsp | 123 + trunk/support/list_hooks.pl | 100 + trunk/support/log_server_status.in | 78 + trunk/support/logresolve.c | 387 + trunk/support/logresolve.dsp | 123 + trunk/support/logresolve.pl.in | 225 + trunk/support/phf_abuse_log.cgi.in | 38 + trunk/support/rotatelogs.c | 261 + trunk/support/rotatelogs.dsp | 123 + trunk/support/split-logfile.in | 67 + trunk/support/suexec.c | 636 + trunk/support/suexec.h | 108 + trunk/support/utilitiesnw.def | 3 + trunk/support/win32/ApacheMonitor.c | 1765 ++ trunk/support/win32/ApacheMonitor.dsp | 131 + trunk/support/win32/ApacheMonitor.h | 75 + trunk/support/win32/ApacheMonitor.ico | Bin 0 -> 1078 bytes trunk/support/win32/ApacheMonitor.rc | 136 + trunk/support/win32/apache_header.bmp | Bin 0 -> 6498 bytes trunk/support/win32/aprun.ico | Bin 0 -> 318 bytes trunk/support/win32/apstop.ico | Bin 0 -> 318 bytes trunk/support/win32/srun.bmp | Bin 0 -> 246 bytes trunk/support/win32/sstop.bmp | Bin 0 -> 246 bytes trunk/support/win32/wintty.c | 369 + trunk/support/win32/wintty.dsp | 123 + trunk/test/.indent.pro | 54 + trunk/test/Makefile.in | 20 + trunk/test/README | 3 + trunk/test/check_chunked | 57 + trunk/test/cls.c | 182 + trunk/test/tcpdumpscii.txt | 50 + trunk/test/test-writev.c | 101 + trunk/test/test_find.c | 78 + trunk/test/test_limits.c | 200 + trunk/test/test_parser.c | 75 + trunk/test/test_select.c | 46 + trunk/test/time-sem.c | 591 + trunk/test/zb.c | 567 + 2412 files changed, 582545 insertions(+) create mode 100644 trunk/.gdbinit create mode 100644 trunk/ABOUT_APACHE create mode 100644 trunk/Apache.dsw create mode 100644 trunk/BuildBin.dsp create mode 100644 trunk/CHANGES create mode 100644 trunk/INSTALL create mode 100644 trunk/InstallBin.dsp create mode 100644 trunk/LAYOUT create mode 100644 trunk/LICENSE create mode 100644 trunk/Makefile.in create mode 100644 trunk/Makefile.win create mode 100644 trunk/NOTICE create mode 100644 trunk/NWGNUmakefile create mode 100644 trunk/README create mode 100644 trunk/README.platforms create mode 100644 trunk/ROADMAP create mode 100644 trunk/STATUS create mode 100644 trunk/VERSIONING create mode 100644 trunk/acinclude.m4 create mode 100644 trunk/apachenw.mcp.zip create mode 100644 trunk/build/NWGNUenvironment.inc create mode 100644 trunk/build/NWGNUhead.inc create mode 100644 trunk/build/NWGNUmakefile create mode 100644 trunk/build/NWGNUtail.inc create mode 100755 trunk/build/binbuild.sh create mode 100755 trunk/build/bsd_makefile create mode 100644 trunk/build/build-modules-c.awk create mode 100755 trunk/build/buildinfo.sh create mode 100755 trunk/build/config-stubs create mode 100644 trunk/build/default.pl create mode 100755 trunk/build/fastgen.sh create mode 100755 trunk/build/get-version.sh create mode 100755 trunk/build/httpd_roll_release create mode 100755 trunk/build/install-bindist.sh.in create mode 100755 trunk/build/install.sh create mode 100755 trunk/build/instdso.sh create mode 100644 trunk/build/library.mk create mode 100644 trunk/build/ltlib.mk create mode 100644 trunk/build/make_exports.awk create mode 100644 trunk/build/make_nw_export.awk create mode 100644 trunk/build/make_var_export.awk create mode 100644 trunk/build/mkconfNW.awk create mode 100644 trunk/build/mkdep.perl create mode 100755 trunk/build/mkdir.sh create mode 100644 trunk/build/nw_export.inc create mode 100644 trunk/build/nw_ver.awk create mode 100644 trunk/build/pkg/README create mode 100755 trunk/build/pkg/buildpkg.sh create mode 100644 trunk/build/pkg/pkginfo.in create mode 100755 trunk/build/prebuildNW.bat create mode 100644 trunk/build/program.mk create mode 100755 trunk/build/rpm/httpd.init create mode 100644 trunk/build/rpm/httpd.logrotate create mode 100644 trunk/build/rpm/httpd.spec.in create mode 100644 trunk/build/rules.mk.in create mode 100644 trunk/build/special.mk create mode 100755 trunk/build/sysv_makefile create mode 100644 trunk/build/win32/apache.ico create mode 100644 trunk/build/win32/win32ver.awk create mode 100755 trunk/buildconf create mode 100644 trunk/config.layout create mode 100644 trunk/configure.in create mode 100644 trunk/docs/STATUS create mode 100644 trunk/docs/cgi-examples/printenv create mode 100644 trunk/docs/cgi-examples/test-cgi create mode 100644 trunk/docs/conf/charset.conv create mode 100644 trunk/docs/conf/extra/httpd-autoindex.conf.in create mode 100644 trunk/docs/conf/extra/httpd-dav.conf.in create mode 100644 trunk/docs/conf/extra/httpd-default.conf.in create mode 100644 trunk/docs/conf/extra/httpd-info.conf.in create mode 100644 trunk/docs/conf/extra/httpd-languages.conf.in create mode 100644 trunk/docs/conf/extra/httpd-manual.conf.in create mode 100644 trunk/docs/conf/extra/httpd-mpm.conf.in create mode 100644 trunk/docs/conf/extra/httpd-multilang-errordoc.conf.in create mode 100644 trunk/docs/conf/extra/httpd-ssl.conf.in create mode 100644 trunk/docs/conf/extra/httpd-userdir.conf.in create mode 100644 trunk/docs/conf/extra/httpd-vhosts.conf.in create mode 100644 trunk/docs/conf/httpd-win.conf create mode 100644 trunk/docs/conf/httpd.conf.in create mode 100644 trunk/docs/conf/magic create mode 100644 trunk/docs/conf/mime.types create mode 100644 trunk/docs/docroot/apache_pb.gif create mode 100644 trunk/docs/docroot/apache_pb.png create mode 100644 trunk/docs/docroot/apache_pb2.gif create mode 100644 trunk/docs/docroot/apache_pb2.png create mode 100644 trunk/docs/docroot/apache_pb2_ani.gif create mode 100644 trunk/docs/docroot/index.html create mode 100644 trunk/docs/doxygen.conf create mode 100644 trunk/docs/error/HTTP_BAD_GATEWAY.html.var create mode 100644 trunk/docs/error/HTTP_BAD_REQUEST.html.var create mode 100644 trunk/docs/error/HTTP_FORBIDDEN.html.var create mode 100644 trunk/docs/error/HTTP_GONE.html.var create mode 100644 trunk/docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var create mode 100644 trunk/docs/error/HTTP_LENGTH_REQUIRED.html.var create mode 100644 trunk/docs/error/HTTP_METHOD_NOT_ALLOWED.html.var create mode 100644 trunk/docs/error/HTTP_NOT_FOUND.html.var create mode 100644 trunk/docs/error/HTTP_NOT_IMPLEMENTED.html.var create mode 100644 trunk/docs/error/HTTP_PRECONDITION_FAILED.html.var create mode 100644 trunk/docs/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var create mode 100644 trunk/docs/error/HTTP_REQUEST_TIME_OUT.html.var create mode 100644 trunk/docs/error/HTTP_REQUEST_URI_TOO_LARGE.html.var create mode 100644 trunk/docs/error/HTTP_SERVICE_UNAVAILABLE.html.var create mode 100644 trunk/docs/error/HTTP_UNAUTHORIZED.html.var create mode 100644 trunk/docs/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var create mode 100644 trunk/docs/error/HTTP_VARIANT_ALSO_VARIES.html.var create mode 100644 trunk/docs/error/README create mode 100644 trunk/docs/error/contact.html.var create mode 100644 trunk/docs/error/include/bottom.html create mode 100644 trunk/docs/error/include/spacer.html create mode 100644 trunk/docs/error/include/top.html create mode 100644 trunk/docs/icons/README create mode 100644 trunk/docs/icons/a.gif create mode 100644 trunk/docs/icons/a.png create mode 100644 trunk/docs/icons/alert.black.gif create mode 100644 trunk/docs/icons/alert.black.png create mode 100644 trunk/docs/icons/alert.red.gif create mode 100644 trunk/docs/icons/alert.red.png create mode 100644 trunk/docs/icons/apache_pb.gif create mode 100644 trunk/docs/icons/apache_pb.png create mode 100644 trunk/docs/icons/apache_pb2.gif create mode 100644 trunk/docs/icons/apache_pb2.png create mode 100644 trunk/docs/icons/apache_pb2_ani.gif create mode 100644 trunk/docs/icons/back.gif create mode 100644 trunk/docs/icons/back.png create mode 100644 trunk/docs/icons/ball.gray.gif create mode 100644 trunk/docs/icons/ball.gray.png create mode 100644 trunk/docs/icons/ball.red.gif create mode 100644 trunk/docs/icons/ball.red.png create mode 100644 trunk/docs/icons/binary.gif create mode 100644 trunk/docs/icons/binary.png create mode 100644 trunk/docs/icons/binhex.gif create mode 100644 trunk/docs/icons/binhex.png create mode 100644 trunk/docs/icons/blank.gif create mode 100644 trunk/docs/icons/blank.png create mode 100644 trunk/docs/icons/bomb.gif create mode 100644 trunk/docs/icons/bomb.png create mode 100644 trunk/docs/icons/box1.gif create mode 100644 trunk/docs/icons/box1.png create mode 100644 trunk/docs/icons/box2.gif create mode 100644 trunk/docs/icons/box2.png create mode 100644 trunk/docs/icons/broken.gif create mode 100644 trunk/docs/icons/broken.png create mode 100644 trunk/docs/icons/burst.gif create mode 100644 trunk/docs/icons/burst.png create mode 100644 trunk/docs/icons/c.gif create mode 100644 trunk/docs/icons/c.png create mode 100644 trunk/docs/icons/comp.blue.gif create mode 100644 trunk/docs/icons/comp.blue.png create mode 100644 trunk/docs/icons/comp.gray.gif create mode 100644 trunk/docs/icons/comp.gray.png create mode 100644 trunk/docs/icons/compressed.gif create mode 100644 trunk/docs/icons/compressed.png create mode 100644 trunk/docs/icons/continued.gif create mode 100644 trunk/docs/icons/continued.png create mode 100644 trunk/docs/icons/dir.gif create mode 100644 trunk/docs/icons/dir.png create mode 100644 trunk/docs/icons/diskimg.gif create mode 100644 trunk/docs/icons/diskimg.png create mode 100644 trunk/docs/icons/down.gif create mode 100644 trunk/docs/icons/down.png create mode 100644 trunk/docs/icons/dvi.gif create mode 100644 trunk/docs/icons/dvi.png create mode 100644 trunk/docs/icons/f.gif create mode 100644 trunk/docs/icons/f.png create mode 100644 trunk/docs/icons/folder.gif create mode 100644 trunk/docs/icons/folder.open.gif create mode 100644 trunk/docs/icons/folder.open.png create mode 100644 trunk/docs/icons/folder.png create mode 100644 trunk/docs/icons/folder.sec.gif create mode 100644 trunk/docs/icons/folder.sec.png create mode 100644 trunk/docs/icons/forward.gif create mode 100644 trunk/docs/icons/forward.png create mode 100644 trunk/docs/icons/generic.gif create mode 100644 trunk/docs/icons/generic.png create mode 100644 trunk/docs/icons/generic.red.gif create mode 100644 trunk/docs/icons/generic.red.png create mode 100644 trunk/docs/icons/generic.sec.gif create mode 100644 trunk/docs/icons/generic.sec.png create mode 100644 trunk/docs/icons/hand.right.gif create mode 100644 trunk/docs/icons/hand.right.png create mode 100644 trunk/docs/icons/hand.up.gif create mode 100644 trunk/docs/icons/hand.up.png create mode 100644 trunk/docs/icons/icon.sheet.gif create mode 100644 trunk/docs/icons/icon.sheet.png create mode 100644 trunk/docs/icons/image1.gif create mode 100644 trunk/docs/icons/image1.png create mode 100644 trunk/docs/icons/image2.gif create mode 100644 trunk/docs/icons/image2.png create mode 100644 trunk/docs/icons/image3.gif create mode 100644 trunk/docs/icons/image3.png create mode 100644 trunk/docs/icons/index.gif create mode 100644 trunk/docs/icons/index.png create mode 100644 trunk/docs/icons/layout.gif create mode 100644 trunk/docs/icons/layout.png create mode 100644 trunk/docs/icons/left.gif create mode 100644 trunk/docs/icons/left.png create mode 100644 trunk/docs/icons/link.gif create mode 100644 trunk/docs/icons/link.png create mode 100644 trunk/docs/icons/movie.gif create mode 100644 trunk/docs/icons/movie.png create mode 100644 trunk/docs/icons/p.gif create mode 100644 trunk/docs/icons/p.png create mode 100644 trunk/docs/icons/patch.gif create mode 100644 trunk/docs/icons/patch.png create mode 100644 trunk/docs/icons/pdf.gif create mode 100644 trunk/docs/icons/pdf.png create mode 100644 trunk/docs/icons/pie0.gif create mode 100644 trunk/docs/icons/pie0.png create mode 100644 trunk/docs/icons/pie1.gif create mode 100644 trunk/docs/icons/pie1.png create mode 100644 trunk/docs/icons/pie2.gif create mode 100644 trunk/docs/icons/pie2.png create mode 100644 trunk/docs/icons/pie3.gif create mode 100644 trunk/docs/icons/pie3.png create mode 100644 trunk/docs/icons/pie4.gif create mode 100644 trunk/docs/icons/pie4.png create mode 100644 trunk/docs/icons/pie5.gif create mode 100644 trunk/docs/icons/pie5.png create mode 100644 trunk/docs/icons/pie6.gif create mode 100644 trunk/docs/icons/pie6.png create mode 100644 trunk/docs/icons/pie7.gif create mode 100644 trunk/docs/icons/pie7.png create mode 100644 trunk/docs/icons/pie8.gif create mode 100644 trunk/docs/icons/pie8.png create mode 100644 trunk/docs/icons/portal.gif create mode 100644 trunk/docs/icons/portal.png create mode 100644 trunk/docs/icons/ps.gif create mode 100644 trunk/docs/icons/ps.png create mode 100644 trunk/docs/icons/quill.gif create mode 100644 trunk/docs/icons/quill.png create mode 100644 trunk/docs/icons/right.gif create mode 100644 trunk/docs/icons/right.png create mode 100644 trunk/docs/icons/screw1.gif create mode 100644 trunk/docs/icons/screw1.png create mode 100644 trunk/docs/icons/screw2.gif create mode 100644 trunk/docs/icons/screw2.png create mode 100644 trunk/docs/icons/script.gif create mode 100644 trunk/docs/icons/script.png create mode 100644 trunk/docs/icons/small/README.txt create mode 100644 trunk/docs/icons/small/back.gif create mode 100644 trunk/docs/icons/small/back.png create mode 100644 trunk/docs/icons/small/binary.gif create mode 100644 trunk/docs/icons/small/binary.png create mode 100644 trunk/docs/icons/small/binhex.gif create mode 100644 trunk/docs/icons/small/binhex.png create mode 100644 trunk/docs/icons/small/blank.gif create mode 100644 trunk/docs/icons/small/blank.png create mode 100644 trunk/docs/icons/small/broken.gif create mode 100644 trunk/docs/icons/small/broken.png create mode 100644 trunk/docs/icons/small/burst.gif create mode 100644 trunk/docs/icons/small/burst.png create mode 100644 trunk/docs/icons/small/comp1.gif create mode 100644 trunk/docs/icons/small/comp1.png create mode 100644 trunk/docs/icons/small/comp2.gif create mode 100644 trunk/docs/icons/small/comp2.png create mode 100644 trunk/docs/icons/small/compressed.gif create mode 100644 trunk/docs/icons/small/compressed.png create mode 100644 trunk/docs/icons/small/continued.gif create mode 100644 trunk/docs/icons/small/continued.png create mode 100644 trunk/docs/icons/small/dir.gif create mode 100644 trunk/docs/icons/small/dir.png create mode 100644 trunk/docs/icons/small/dir2.gif create mode 100644 trunk/docs/icons/small/dir2.png create mode 100644 trunk/docs/icons/small/doc.gif create mode 100644 trunk/docs/icons/small/doc.png create mode 100644 trunk/docs/icons/small/forward.gif create mode 100644 trunk/docs/icons/small/forward.png create mode 100644 trunk/docs/icons/small/generic.gif create mode 100644 trunk/docs/icons/small/generic.png create mode 100644 trunk/docs/icons/small/generic2.gif create mode 100644 trunk/docs/icons/small/generic2.png create mode 100644 trunk/docs/icons/small/generic3.gif create mode 100644 trunk/docs/icons/small/generic3.png create mode 100644 trunk/docs/icons/small/image.gif create mode 100644 trunk/docs/icons/small/image.png create mode 100644 trunk/docs/icons/small/image2.gif create mode 100644 trunk/docs/icons/small/image2.png create mode 100644 trunk/docs/icons/small/index.gif create mode 100644 trunk/docs/icons/small/index.png create mode 100644 trunk/docs/icons/small/key.gif create mode 100644 trunk/docs/icons/small/key.png create mode 100644 trunk/docs/icons/small/movie.gif create mode 100644 trunk/docs/icons/small/movie.png create mode 100644 trunk/docs/icons/small/patch.gif create mode 100644 trunk/docs/icons/small/patch.png create mode 100644 trunk/docs/icons/small/ps.gif create mode 100644 trunk/docs/icons/small/ps.png create mode 100644 trunk/docs/icons/small/rainbow.gif create mode 100644 trunk/docs/icons/small/rainbow.png create mode 100644 trunk/docs/icons/small/sound.gif create mode 100644 trunk/docs/icons/small/sound.png create mode 100644 trunk/docs/icons/small/sound2.gif create mode 100644 trunk/docs/icons/small/sound2.png create mode 100644 trunk/docs/icons/small/tar.gif create mode 100644 trunk/docs/icons/small/tar.png create mode 100644 trunk/docs/icons/small/text.gif create mode 100644 trunk/docs/icons/small/text.png create mode 100644 trunk/docs/icons/small/transfer.gif create mode 100644 trunk/docs/icons/small/transfer.png create mode 100644 trunk/docs/icons/small/unknown.gif create mode 100644 trunk/docs/icons/small/unknown.png create mode 100644 trunk/docs/icons/small/uu.gif create mode 100644 trunk/docs/icons/small/uu.png create mode 100644 trunk/docs/icons/sound1.gif create mode 100644 trunk/docs/icons/sound1.png create mode 100644 trunk/docs/icons/sound2.gif create mode 100644 trunk/docs/icons/sound2.png create mode 100644 trunk/docs/icons/sphere1.gif create mode 100644 trunk/docs/icons/sphere1.png create mode 100644 trunk/docs/icons/sphere2.gif create mode 100644 trunk/docs/icons/sphere2.png create mode 100644 trunk/docs/icons/tar.gif create mode 100644 trunk/docs/icons/tar.png create mode 100644 trunk/docs/icons/tex.gif create mode 100644 trunk/docs/icons/tex.png create mode 100644 trunk/docs/icons/text.gif create mode 100644 trunk/docs/icons/text.png create mode 100644 trunk/docs/icons/transfer.gif create mode 100644 trunk/docs/icons/transfer.png create mode 100644 trunk/docs/icons/unknown.gif create mode 100644 trunk/docs/icons/unknown.png create mode 100644 trunk/docs/icons/up.gif create mode 100644 trunk/docs/icons/up.png create mode 100644 trunk/docs/icons/uu.gif create mode 100644 trunk/docs/icons/uu.png create mode 100644 trunk/docs/icons/uuencoded.gif create mode 100644 trunk/docs/icons/uuencoded.png create mode 100644 trunk/docs/icons/world1.gif create mode 100644 trunk/docs/icons/world1.png create mode 100644 trunk/docs/icons/world2.gif create mode 100644 trunk/docs/icons/world2.png create mode 100644 trunk/docs/man/ab.8 create mode 100644 trunk/docs/man/apachectl.8 create mode 100644 trunk/docs/man/apxs.8 create mode 100644 trunk/docs/man/dbmmanage.1 create mode 100644 trunk/docs/man/htcacheclean.8 create mode 100644 trunk/docs/man/htdbm.1 create mode 100644 trunk/docs/man/htdigest.1 create mode 100644 trunk/docs/man/htpasswd.1 create mode 100644 trunk/docs/man/httpd.8 create mode 100644 trunk/docs/man/logresolve.8 create mode 100644 trunk/docs/man/rotatelogs.8 create mode 100644 trunk/docs/man/suexec.8 create mode 100644 trunk/docs/manual/LICENSE create mode 100644 trunk/docs/manual/bind.html create mode 100644 trunk/docs/manual/bind.html.de create mode 100644 trunk/docs/manual/bind.html.en create mode 100644 trunk/docs/manual/bind.html.fr create mode 100644 trunk/docs/manual/bind.html.ja.euc-jp create mode 100644 trunk/docs/manual/bind.html.ko.euc-kr create mode 100644 trunk/docs/manual/bind.xml create mode 100644 trunk/docs/manual/bind.xml.de create mode 100644 trunk/docs/manual/bind.xml.fr create mode 100644 trunk/docs/manual/bind.xml.ja create mode 100644 trunk/docs/manual/bind.xml.ko create mode 100644 trunk/docs/manual/bind.xml.meta create mode 100644 trunk/docs/manual/configuring.html create mode 100644 trunk/docs/manual/configuring.html.de create mode 100644 trunk/docs/manual/configuring.html.en create mode 100644 trunk/docs/manual/configuring.html.ja.euc-jp create mode 100644 trunk/docs/manual/configuring.html.ko.euc-kr create mode 100644 trunk/docs/manual/configuring.xml create mode 100644 trunk/docs/manual/configuring.xml.de create mode 100644 trunk/docs/manual/configuring.xml.ja create mode 100644 trunk/docs/manual/configuring.xml.ko create mode 100644 trunk/docs/manual/configuring.xml.meta create mode 100644 trunk/docs/manual/content-negotiation.html create mode 100644 trunk/docs/manual/content-negotiation.html.en create mode 100644 trunk/docs/manual/content-negotiation.html.ja.euc-jp create mode 100644 trunk/docs/manual/content-negotiation.html.ko.euc-kr create mode 100644 trunk/docs/manual/content-negotiation.xml create mode 100644 trunk/docs/manual/content-negotiation.xml.ja create mode 100644 trunk/docs/manual/content-negotiation.xml.ko create mode 100644 trunk/docs/manual/content-negotiation.xml.meta create mode 100644 trunk/docs/manual/custom-error.html create mode 100644 trunk/docs/manual/custom-error.html.en create mode 100644 trunk/docs/manual/custom-error.html.es create mode 100644 trunk/docs/manual/custom-error.html.ja.euc-jp create mode 100644 trunk/docs/manual/custom-error.html.ko.euc-kr create mode 100644 trunk/docs/manual/custom-error.xml create mode 100644 trunk/docs/manual/custom-error.xml.es create mode 100644 trunk/docs/manual/custom-error.xml.ja create mode 100644 trunk/docs/manual/custom-error.xml.ko create mode 100644 trunk/docs/manual/custom-error.xml.meta create mode 100644 trunk/docs/manual/developer/API.html create mode 100644 trunk/docs/manual/developer/API.html.en create mode 100644 trunk/docs/manual/developer/API.xml create mode 100644 trunk/docs/manual/developer/API.xml.meta create mode 100644 trunk/docs/manual/developer/debugging.html create mode 100644 trunk/docs/manual/developer/debugging.html.en create mode 100644 trunk/docs/manual/developer/debugging.xml create mode 100644 trunk/docs/manual/developer/debugging.xml.meta create mode 100644 trunk/docs/manual/developer/documenting.html create mode 100644 trunk/docs/manual/developer/documenting.html.en create mode 100644 trunk/docs/manual/developer/documenting.xml create mode 100644 trunk/docs/manual/developer/documenting.xml.meta create mode 100644 trunk/docs/manual/developer/filters.html create mode 100644 trunk/docs/manual/developer/filters.html.en create mode 100644 trunk/docs/manual/developer/filters.xml create mode 100644 trunk/docs/manual/developer/filters.xml.meta create mode 100644 trunk/docs/manual/developer/hooks.html create mode 100644 trunk/docs/manual/developer/hooks.html.en create mode 100644 trunk/docs/manual/developer/hooks.xml create mode 100644 trunk/docs/manual/developer/hooks.xml.meta create mode 100644 trunk/docs/manual/developer/index.html create mode 100644 trunk/docs/manual/developer/index.html.en create mode 100644 trunk/docs/manual/developer/index.xml create mode 100644 trunk/docs/manual/developer/index.xml.meta create mode 100644 trunk/docs/manual/developer/modules.html create mode 100644 trunk/docs/manual/developer/modules.html.en create mode 100644 trunk/docs/manual/developer/modules.html.ja.euc-jp create mode 100644 trunk/docs/manual/developer/modules.xml create mode 100644 trunk/docs/manual/developer/modules.xml.ja create mode 100644 trunk/docs/manual/developer/modules.xml.meta create mode 100644 trunk/docs/manual/developer/request.html create mode 100644 trunk/docs/manual/developer/request.html.en create mode 100644 trunk/docs/manual/developer/request.xml create mode 100644 trunk/docs/manual/developer/request.xml.meta create mode 100644 trunk/docs/manual/developer/thread_safety.html create mode 100644 trunk/docs/manual/developer/thread_safety.html.en create mode 100644 trunk/docs/manual/developer/thread_safety.xml create mode 100644 trunk/docs/manual/developer/thread_safety.xml.meta create mode 100644 trunk/docs/manual/dns-caveats.html create mode 100644 trunk/docs/manual/dns-caveats.html.en create mode 100644 trunk/docs/manual/dns-caveats.html.ja.euc-jp create mode 100644 trunk/docs/manual/dns-caveats.html.ko.euc-kr create mode 100644 trunk/docs/manual/dns-caveats.xml create mode 100644 trunk/docs/manual/dns-caveats.xml.ja create mode 100644 trunk/docs/manual/dns-caveats.xml.ko create mode 100644 trunk/docs/manual/dns-caveats.xml.meta create mode 100644 trunk/docs/manual/dso.html create mode 100644 trunk/docs/manual/dso.html.en create mode 100644 trunk/docs/manual/dso.html.ja.euc-jp create mode 100644 trunk/docs/manual/dso.html.ko.euc-kr create mode 100644 trunk/docs/manual/dso.xml create mode 100644 trunk/docs/manual/dso.xml.ja create mode 100644 trunk/docs/manual/dso.xml.ko create mode 100644 trunk/docs/manual/dso.xml.meta create mode 100644 trunk/docs/manual/env.html create mode 100644 trunk/docs/manual/env.html.en create mode 100644 trunk/docs/manual/env.html.ja.euc-jp create mode 100644 trunk/docs/manual/env.html.ko.euc-kr create mode 100644 trunk/docs/manual/env.xml create mode 100644 trunk/docs/manual/env.xml.ja create mode 100644 trunk/docs/manual/env.xml.ko create mode 100644 trunk/docs/manual/env.xml.meta create mode 100644 trunk/docs/manual/faq/all_in_one.html create mode 100644 trunk/docs/manual/faq/all_in_one.html.en create mode 100644 trunk/docs/manual/faq/all_in_one.html.ja.euc-jp create mode 100644 trunk/docs/manual/faq/all_in_one.html.ko.euc-kr create mode 100644 trunk/docs/manual/faq/all_in_one.xml create mode 100644 trunk/docs/manual/faq/all_in_one.xml.ja create mode 100644 trunk/docs/manual/faq/all_in_one.xml.ko create mode 100644 trunk/docs/manual/faq/all_in_one.xml.meta create mode 100644 trunk/docs/manual/faq/categories.xml create mode 100644 trunk/docs/manual/faq/categories.xml.ja create mode 100644 trunk/docs/manual/faq/categories.xml.ko create mode 100644 trunk/docs/manual/faq/error.html create mode 100644 trunk/docs/manual/faq/error.html.en create mode 100644 trunk/docs/manual/faq/error.html.ja.euc-jp create mode 100644 trunk/docs/manual/faq/error.html.ko.euc-kr create mode 100644 trunk/docs/manual/faq/error.xml create mode 100644 trunk/docs/manual/faq/error.xml.ja create mode 100644 trunk/docs/manual/faq/error.xml.ko create mode 100644 trunk/docs/manual/faq/error.xml.meta create mode 100644 trunk/docs/manual/faq/index.html create mode 100644 trunk/docs/manual/faq/index.html.en create mode 100644 trunk/docs/manual/faq/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/faq/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/faq/index.xml create mode 100644 trunk/docs/manual/faq/index.xml.ja create mode 100644 trunk/docs/manual/faq/index.xml.ko create mode 100644 trunk/docs/manual/faq/index.xml.meta create mode 100644 trunk/docs/manual/faq/support.html create mode 100644 trunk/docs/manual/faq/support.html.en create mode 100644 trunk/docs/manual/faq/support.html.ja.euc-jp create mode 100644 trunk/docs/manual/faq/support.html.ko.euc-kr create mode 100644 trunk/docs/manual/faq/support.xml create mode 100644 trunk/docs/manual/faq/support.xml.ja create mode 100644 trunk/docs/manual/faq/support.xml.ko create mode 100644 trunk/docs/manual/faq/support.xml.meta create mode 100644 trunk/docs/manual/filter.html create mode 100644 trunk/docs/manual/filter.html.en create mode 100644 trunk/docs/manual/filter.html.es create mode 100644 trunk/docs/manual/filter.html.fr create mode 100644 trunk/docs/manual/filter.html.ja.euc-jp create mode 100644 trunk/docs/manual/filter.html.ko.euc-kr create mode 100644 trunk/docs/manual/filter.xml create mode 100644 trunk/docs/manual/filter.xml.es create mode 100644 trunk/docs/manual/filter.xml.fr create mode 100644 trunk/docs/manual/filter.xml.ja create mode 100644 trunk/docs/manual/filter.xml.ko create mode 100644 trunk/docs/manual/filter.xml.meta create mode 100644 trunk/docs/manual/glossary.html create mode 100644 trunk/docs/manual/glossary.html.de create mode 100644 trunk/docs/manual/glossary.html.en create mode 100644 trunk/docs/manual/glossary.html.es create mode 100644 trunk/docs/manual/glossary.html.ko.euc-kr create mode 100644 trunk/docs/manual/glossary.xml create mode 100644 trunk/docs/manual/glossary.xml.de create mode 100644 trunk/docs/manual/glossary.xml.es create mode 100644 trunk/docs/manual/glossary.xml.ko create mode 100644 trunk/docs/manual/glossary.xml.meta create mode 100644 trunk/docs/manual/handler.html create mode 100644 trunk/docs/manual/handler.html.en create mode 100644 trunk/docs/manual/handler.html.es create mode 100644 trunk/docs/manual/handler.html.ja.euc-jp create mode 100644 trunk/docs/manual/handler.html.ko.euc-kr create mode 100644 trunk/docs/manual/handler.xml create mode 100644 trunk/docs/manual/handler.xml.es create mode 100644 trunk/docs/manual/handler.xml.ja create mode 100644 trunk/docs/manual/handler.xml.ko create mode 100644 trunk/docs/manual/handler.xml.meta create mode 100644 trunk/docs/manual/howto/auth.html create mode 100644 trunk/docs/manual/howto/auth.html.en create mode 100644 trunk/docs/manual/howto/auth.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/auth.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/auth.xml create mode 100644 trunk/docs/manual/howto/auth.xml.ja create mode 100644 trunk/docs/manual/howto/auth.xml.ko create mode 100644 trunk/docs/manual/howto/auth.xml.meta create mode 100644 trunk/docs/manual/howto/cgi.html create mode 100644 trunk/docs/manual/howto/cgi.html.en create mode 100644 trunk/docs/manual/howto/cgi.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/cgi.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/cgi.xml create mode 100644 trunk/docs/manual/howto/cgi.xml.ja create mode 100644 trunk/docs/manual/howto/cgi.xml.ko create mode 100644 trunk/docs/manual/howto/cgi.xml.meta create mode 100644 trunk/docs/manual/howto/htaccess.html create mode 100644 trunk/docs/manual/howto/htaccess.html.en create mode 100644 trunk/docs/manual/howto/htaccess.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/htaccess.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/htaccess.html.pt-br create mode 100644 trunk/docs/manual/howto/htaccess.xml create mode 100644 trunk/docs/manual/howto/htaccess.xml.ja create mode 100644 trunk/docs/manual/howto/htaccess.xml.ko create mode 100644 trunk/docs/manual/howto/htaccess.xml.meta create mode 100644 trunk/docs/manual/howto/htaccess.xml.pt-br create mode 100644 trunk/docs/manual/howto/index.html create mode 100644 trunk/docs/manual/howto/index.html.en create mode 100644 trunk/docs/manual/howto/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/index.xml create mode 100644 trunk/docs/manual/howto/index.xml.ja create mode 100644 trunk/docs/manual/howto/index.xml.ko create mode 100644 trunk/docs/manual/howto/index.xml.meta create mode 100644 trunk/docs/manual/howto/public_html.html create mode 100644 trunk/docs/manual/howto/public_html.html.en create mode 100644 trunk/docs/manual/howto/public_html.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/public_html.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/public_html.xml create mode 100644 trunk/docs/manual/howto/public_html.xml.ja create mode 100644 trunk/docs/manual/howto/public_html.xml.ko create mode 100644 trunk/docs/manual/howto/public_html.xml.meta create mode 100644 trunk/docs/manual/howto/ssi.html create mode 100644 trunk/docs/manual/howto/ssi.html.en create mode 100644 trunk/docs/manual/howto/ssi.html.ja.euc-jp create mode 100644 trunk/docs/manual/howto/ssi.html.ko.euc-kr create mode 100644 trunk/docs/manual/howto/ssi.xml create mode 100644 trunk/docs/manual/howto/ssi.xml.ja create mode 100644 trunk/docs/manual/howto/ssi.xml.ko create mode 100644 trunk/docs/manual/howto/ssi.xml.meta create mode 100644 trunk/docs/manual/images/apache_header.gif create mode 100644 trunk/docs/manual/images/custom_errordocs.png create mode 100644 trunk/docs/manual/images/down.gif create mode 100644 trunk/docs/manual/images/favicon.ico create mode 100644 trunk/docs/manual/images/feather.gif create mode 100644 trunk/docs/manual/images/feather.png create mode 100644 trunk/docs/manual/images/home.gif create mode 100644 trunk/docs/manual/images/index.gif create mode 100644 trunk/docs/manual/images/left.gif create mode 100644 trunk/docs/manual/images/mod_filter_new.gif create mode 100644 trunk/docs/manual/images/mod_filter_old.gif create mode 100644 trunk/docs/manual/images/mod_rewrite_fig1.gif create mode 100644 trunk/docs/manual/images/mod_rewrite_fig1.png create mode 100644 trunk/docs/manual/images/mod_rewrite_fig2.gif create mode 100644 trunk/docs/manual/images/mod_rewrite_fig2.png create mode 100644 trunk/docs/manual/images/pixel.gif create mode 100644 trunk/docs/manual/images/right.gif create mode 100644 trunk/docs/manual/images/ssl_intro_fig1.gif create mode 100644 trunk/docs/manual/images/ssl_intro_fig1.png create mode 100644 trunk/docs/manual/images/ssl_intro_fig2.gif create mode 100644 trunk/docs/manual/images/ssl_intro_fig2.png create mode 100644 trunk/docs/manual/images/ssl_intro_fig3.gif create mode 100644 trunk/docs/manual/images/ssl_intro_fig3.png create mode 100644 trunk/docs/manual/images/sub.gif create mode 100644 trunk/docs/manual/images/up.gif create mode 100644 trunk/docs/manual/index.html create mode 100644 trunk/docs/manual/index.html.de create mode 100644 trunk/docs/manual/index.html.en create mode 100644 trunk/docs/manual/index.html.es create mode 100644 trunk/docs/manual/index.html.fr create mode 100644 trunk/docs/manual/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/index.html.pt-br create mode 100644 trunk/docs/manual/index.xml create mode 100644 trunk/docs/manual/index.xml.de create mode 100644 trunk/docs/manual/index.xml.es create mode 100644 trunk/docs/manual/index.xml.fr create mode 100644 trunk/docs/manual/index.xml.ja create mode 100644 trunk/docs/manual/index.xml.ko create mode 100644 trunk/docs/manual/index.xml.meta create mode 100644 trunk/docs/manual/index.xml.pt-br create mode 100644 trunk/docs/manual/install.html create mode 100644 trunk/docs/manual/install.html.de create mode 100644 trunk/docs/manual/install.html.en create mode 100644 trunk/docs/manual/install.html.es create mode 100644 trunk/docs/manual/install.html.fr create mode 100644 trunk/docs/manual/install.html.ja.euc-jp create mode 100644 trunk/docs/manual/install.html.ko.euc-kr create mode 100644 trunk/docs/manual/install.xml create mode 100644 trunk/docs/manual/install.xml.de create mode 100644 trunk/docs/manual/install.xml.es create mode 100644 trunk/docs/manual/install.xml.fr create mode 100644 trunk/docs/manual/install.xml.ja create mode 100644 trunk/docs/manual/install.xml.ko create mode 100644 trunk/docs/manual/install.xml.meta create mode 100644 trunk/docs/manual/invoking.html create mode 100644 trunk/docs/manual/invoking.html.de create mode 100644 trunk/docs/manual/invoking.html.en create mode 100644 trunk/docs/manual/invoking.html.es create mode 100644 trunk/docs/manual/invoking.html.ja.euc-jp create mode 100644 trunk/docs/manual/invoking.html.ko.euc-kr create mode 100644 trunk/docs/manual/invoking.xml create mode 100644 trunk/docs/manual/invoking.xml.de create mode 100644 trunk/docs/manual/invoking.xml.es create mode 100644 trunk/docs/manual/invoking.xml.ja create mode 100644 trunk/docs/manual/invoking.xml.ko create mode 100644 trunk/docs/manual/invoking.xml.meta create mode 100644 trunk/docs/manual/license.html create mode 100644 trunk/docs/manual/license.html.en create mode 100644 trunk/docs/manual/license.xml create mode 100644 trunk/docs/manual/license.xml.meta create mode 100644 trunk/docs/manual/logs.html create mode 100644 trunk/docs/manual/logs.html.en create mode 100644 trunk/docs/manual/logs.html.ja.euc-jp create mode 100644 trunk/docs/manual/logs.html.ko.euc-kr create mode 100644 trunk/docs/manual/logs.xml create mode 100644 trunk/docs/manual/logs.xml.ja create mode 100644 trunk/docs/manual/logs.xml.ko create mode 100644 trunk/docs/manual/logs.xml.meta create mode 100644 trunk/docs/manual/misc/index.html create mode 100644 trunk/docs/manual/misc/index.html.en create mode 100644 trunk/docs/manual/misc/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/misc/index.xml create mode 100644 trunk/docs/manual/misc/index.xml.ko create mode 100644 trunk/docs/manual/misc/index.xml.meta create mode 100644 trunk/docs/manual/misc/perf-tuning.html create mode 100644 trunk/docs/manual/misc/perf-tuning.html.en create mode 100644 trunk/docs/manual/misc/perf-tuning.html.ko.euc-kr create mode 100644 trunk/docs/manual/misc/perf-tuning.xml create mode 100644 trunk/docs/manual/misc/perf-tuning.xml.ko create mode 100644 trunk/docs/manual/misc/perf-tuning.xml.meta create mode 100644 trunk/docs/manual/misc/relevant_standards.html create mode 100644 trunk/docs/manual/misc/relevant_standards.html.en create mode 100644 trunk/docs/manual/misc/relevant_standards.html.ko.euc-kr create mode 100644 trunk/docs/manual/misc/relevant_standards.xml create mode 100644 trunk/docs/manual/misc/relevant_standards.xml.ko create mode 100644 trunk/docs/manual/misc/relevant_standards.xml.meta create mode 100644 trunk/docs/manual/misc/rewriteguide.html create mode 100644 trunk/docs/manual/misc/rewriteguide.html.en create mode 100644 trunk/docs/manual/misc/rewriteguide.html.ko.euc-kr create mode 100644 trunk/docs/manual/misc/rewriteguide.xml create mode 100644 trunk/docs/manual/misc/rewriteguide.xml.ko create mode 100644 trunk/docs/manual/misc/rewriteguide.xml.meta create mode 100644 trunk/docs/manual/misc/security_tips.html create mode 100644 trunk/docs/manual/misc/security_tips.html.en create mode 100644 trunk/docs/manual/misc/security_tips.html.ko.euc-kr create mode 100644 trunk/docs/manual/misc/security_tips.xml create mode 100644 trunk/docs/manual/misc/security_tips.xml.ko create mode 100644 trunk/docs/manual/misc/security_tips.xml.meta create mode 100644 trunk/docs/manual/mod/allmodules.xml create mode 100644 trunk/docs/manual/mod/allmodules.xml.de create mode 100644 trunk/docs/manual/mod/allmodules.xml.es create mode 100644 trunk/docs/manual/mod/allmodules.xml.ja create mode 100644 trunk/docs/manual/mod/allmodules.xml.ko create mode 100644 trunk/docs/manual/mod/beos.html create mode 100644 trunk/docs/manual/mod/beos.html.de create mode 100644 trunk/docs/manual/mod/beos.html.en create mode 100644 trunk/docs/manual/mod/beos.html.es create mode 100644 trunk/docs/manual/mod/beos.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/beos.xml create mode 100644 trunk/docs/manual/mod/beos.xml.de create mode 100644 trunk/docs/manual/mod/beos.xml.es create mode 100644 trunk/docs/manual/mod/beos.xml.ko create mode 100644 trunk/docs/manual/mod/beos.xml.meta create mode 100644 trunk/docs/manual/mod/core.html create mode 100644 trunk/docs/manual/mod/core.html.de create mode 100644 trunk/docs/manual/mod/core.html.en create mode 100644 trunk/docs/manual/mod/core.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/core.xml create mode 100644 trunk/docs/manual/mod/core.xml.de create mode 100644 trunk/docs/manual/mod/core.xml.ja create mode 100644 trunk/docs/manual/mod/core.xml.meta create mode 100644 trunk/docs/manual/mod/directive-dict.html create mode 100644 trunk/docs/manual/mod/directive-dict.html.en create mode 100644 trunk/docs/manual/mod/directive-dict.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/directive-dict.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/directive-dict.xml create mode 100644 trunk/docs/manual/mod/directive-dict.xml.ja create mode 100644 trunk/docs/manual/mod/directive-dict.xml.ko create mode 100644 trunk/docs/manual/mod/directive-dict.xml.meta create mode 100644 trunk/docs/manual/mod/directives.html create mode 100644 trunk/docs/manual/mod/directives.html.de create mode 100644 trunk/docs/manual/mod/directives.html.en create mode 100644 trunk/docs/manual/mod/directives.html.es create mode 100644 trunk/docs/manual/mod/directives.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/directives.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/directives.xml create mode 100644 trunk/docs/manual/mod/directives.xml.de create mode 100644 trunk/docs/manual/mod/directives.xml.es create mode 100644 trunk/docs/manual/mod/directives.xml.ja create mode 100644 trunk/docs/manual/mod/directives.xml.ko create mode 100644 trunk/docs/manual/mod/directives.xml.meta create mode 100644 trunk/docs/manual/mod/event.html create mode 100644 trunk/docs/manual/mod/event.html.en create mode 100644 trunk/docs/manual/mod/event.xml create mode 100644 trunk/docs/manual/mod/event.xml.meta create mode 100644 trunk/docs/manual/mod/index.html create mode 100644 trunk/docs/manual/mod/index.html.de create mode 100644 trunk/docs/manual/mod/index.html.en create mode 100644 trunk/docs/manual/mod/index.html.es create mode 100644 trunk/docs/manual/mod/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/index.xml create mode 100644 trunk/docs/manual/mod/index.xml.de create mode 100644 trunk/docs/manual/mod/index.xml.es create mode 100644 trunk/docs/manual/mod/index.xml.ja create mode 100644 trunk/docs/manual/mod/index.xml.ko create mode 100644 trunk/docs/manual/mod/index.xml.meta create mode 100644 trunk/docs/manual/mod/leader.html create mode 100644 trunk/docs/manual/mod/leader.html.de create mode 100644 trunk/docs/manual/mod/leader.html.en create mode 100644 trunk/docs/manual/mod/leader.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/leader.xml create mode 100644 trunk/docs/manual/mod/leader.xml.de create mode 100644 trunk/docs/manual/mod/leader.xml.ko create mode 100644 trunk/docs/manual/mod/leader.xml.meta create mode 100644 trunk/docs/manual/mod/mod_actions.html create mode 100644 trunk/docs/manual/mod/mod_actions.html.de create mode 100644 trunk/docs/manual/mod/mod_actions.html.en create mode 100644 trunk/docs/manual/mod/mod_actions.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_actions.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_actions.xml create mode 100644 trunk/docs/manual/mod/mod_actions.xml.de create mode 100644 trunk/docs/manual/mod/mod_actions.xml.ja create mode 100644 trunk/docs/manual/mod/mod_actions.xml.ko create mode 100644 trunk/docs/manual/mod/mod_actions.xml.meta create mode 100644 trunk/docs/manual/mod/mod_alias.html create mode 100644 trunk/docs/manual/mod/mod_alias.html.en create mode 100644 trunk/docs/manual/mod/mod_alias.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_alias.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_alias.xml create mode 100644 trunk/docs/manual/mod/mod_alias.xml.ja create mode 100644 trunk/docs/manual/mod/mod_alias.xml.ko create mode 100644 trunk/docs/manual/mod/mod_alias.xml.meta create mode 100644 trunk/docs/manual/mod/mod_asis.html create mode 100644 trunk/docs/manual/mod/mod_asis.html.en create mode 100644 trunk/docs/manual/mod/mod_asis.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_asis.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_asis.xml create mode 100644 trunk/docs/manual/mod/mod_asis.xml.ja create mode 100644 trunk/docs/manual/mod/mod_asis.xml.ko create mode 100644 trunk/docs/manual/mod/mod_asis.xml.meta create mode 100644 trunk/docs/manual/mod/mod_auth_basic.html create mode 100644 trunk/docs/manual/mod/mod_auth_basic.html.en create mode 100644 trunk/docs/manual/mod/mod_auth_basic.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_auth_basic.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_auth_basic.xml create mode 100644 trunk/docs/manual/mod/mod_auth_basic.xml.ja create mode 100644 trunk/docs/manual/mod/mod_auth_basic.xml.ko create mode 100644 trunk/docs/manual/mod/mod_auth_basic.xml.meta create mode 100644 trunk/docs/manual/mod/mod_auth_digest.html create mode 100644 trunk/docs/manual/mod/mod_auth_digest.html.en create mode 100644 trunk/docs/manual/mod/mod_auth_digest.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_auth_digest.xml create mode 100644 trunk/docs/manual/mod/mod_auth_digest.xml.ko create mode 100644 trunk/docs/manual/mod/mod_auth_digest.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authn_alias.html create mode 100644 trunk/docs/manual/mod/mod_authn_alias.html.en create mode 100644 trunk/docs/manual/mod/mod_authn_alias.xml create mode 100644 trunk/docs/manual/mod/mod_authn_alias.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authn_anon.html create mode 100644 trunk/docs/manual/mod/mod_authn_anon.html.en create mode 100644 trunk/docs/manual/mod/mod_authn_anon.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authn_anon.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authn_anon.xml create mode 100644 trunk/docs/manual/mod/mod_authn_anon.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authn_anon.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authn_anon.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.html create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.html.en create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.xml create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authn_dbm.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authn_default.html create mode 100644 trunk/docs/manual/mod/mod_authn_default.html.en create mode 100644 trunk/docs/manual/mod/mod_authn_default.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authn_default.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authn_default.xml create mode 100644 trunk/docs/manual/mod/mod_authn_default.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authn_default.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authn_default.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authn_file.html create mode 100644 trunk/docs/manual/mod/mod_authn_file.html.en create mode 100644 trunk/docs/manual/mod/mod_authn_file.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authn_file.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authn_file.xml create mode 100644 trunk/docs/manual/mod/mod_authn_file.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authn_file.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authn_file.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authnz_ldap.html create mode 100644 trunk/docs/manual/mod/mod_authnz_ldap.html.en create mode 100644 trunk/docs/manual/mod/mod_authnz_ldap.xml create mode 100644 trunk/docs/manual/mod/mod_authnz_ldap.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.html create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.xml create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_dbm.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_default.html create mode 100644 trunk/docs/manual/mod/mod_authz_default.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_default.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authz_default.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_default.xml create mode 100644 trunk/docs/manual/mod/mod_authz_default.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authz_default.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_default.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.html create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.xml create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_groupfile.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_host.html create mode 100644 trunk/docs/manual/mod/mod_authz_host.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_host.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authz_host.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_host.xml create mode 100644 trunk/docs/manual/mod/mod_authz_host.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authz_host.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_host.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_owner.html create mode 100644 trunk/docs/manual/mod/mod_authz_owner.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_owner.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authz_owner.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_owner.xml create mode 100644 trunk/docs/manual/mod/mod_authz_owner.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authz_owner.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_owner.xml.meta create mode 100644 trunk/docs/manual/mod/mod_authz_user.html create mode 100644 trunk/docs/manual/mod/mod_authz_user.html.en create mode 100644 trunk/docs/manual/mod/mod_authz_user.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_authz_user.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_authz_user.xml create mode 100644 trunk/docs/manual/mod/mod_authz_user.xml.ja create mode 100644 trunk/docs/manual/mod/mod_authz_user.xml.ko create mode 100644 trunk/docs/manual/mod/mod_authz_user.xml.meta create mode 100644 trunk/docs/manual/mod/mod_autoindex.html create mode 100644 trunk/docs/manual/mod/mod_autoindex.html.en create mode 100644 trunk/docs/manual/mod/mod_autoindex.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_autoindex.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_autoindex.xml create mode 100644 trunk/docs/manual/mod/mod_autoindex.xml.ja create mode 100644 trunk/docs/manual/mod/mod_autoindex.xml.ko create mode 100644 trunk/docs/manual/mod/mod_autoindex.xml.meta create mode 100644 trunk/docs/manual/mod/mod_cache.html create mode 100644 trunk/docs/manual/mod/mod_cache.html.en create mode 100644 trunk/docs/manual/mod/mod_cache.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_cache.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_cache.xml create mode 100644 trunk/docs/manual/mod/mod_cache.xml.ja create mode 100644 trunk/docs/manual/mod/mod_cache.xml.ko create mode 100644 trunk/docs/manual/mod/mod_cache.xml.meta create mode 100644 trunk/docs/manual/mod/mod_cern_meta.html create mode 100644 trunk/docs/manual/mod/mod_cern_meta.html.en create mode 100644 trunk/docs/manual/mod/mod_cern_meta.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_cern_meta.xml create mode 100644 trunk/docs/manual/mod/mod_cern_meta.xml.ko create mode 100644 trunk/docs/manual/mod/mod_cern_meta.xml.meta create mode 100644 trunk/docs/manual/mod/mod_cgi.html create mode 100644 trunk/docs/manual/mod/mod_cgi.html.en create mode 100644 trunk/docs/manual/mod/mod_cgi.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_cgi.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_cgi.xml create mode 100644 trunk/docs/manual/mod/mod_cgi.xml.ja create mode 100644 trunk/docs/manual/mod/mod_cgi.xml.ko create mode 100644 trunk/docs/manual/mod/mod_cgi.xml.meta create mode 100644 trunk/docs/manual/mod/mod_cgid.html create mode 100644 trunk/docs/manual/mod/mod_cgid.html.en create mode 100644 trunk/docs/manual/mod/mod_cgid.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_cgid.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_cgid.xml create mode 100644 trunk/docs/manual/mod/mod_cgid.xml.ja create mode 100644 trunk/docs/manual/mod/mod_cgid.xml.ko create mode 100644 trunk/docs/manual/mod/mod_cgid.xml.meta create mode 100644 trunk/docs/manual/mod/mod_charset_lite.html create mode 100644 trunk/docs/manual/mod/mod_charset_lite.html.en create mode 100644 trunk/docs/manual/mod/mod_charset_lite.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_charset_lite.xml create mode 100644 trunk/docs/manual/mod/mod_charset_lite.xml.ko create mode 100644 trunk/docs/manual/mod/mod_charset_lite.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dav.html create mode 100644 trunk/docs/manual/mod/mod_dav.html.en create mode 100644 trunk/docs/manual/mod/mod_dav.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_dav.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_dav.xml create mode 100644 trunk/docs/manual/mod/mod_dav.xml.ja create mode 100644 trunk/docs/manual/mod/mod_dav.xml.ko create mode 100644 trunk/docs/manual/mod/mod_dav.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dav_fs.html create mode 100644 trunk/docs/manual/mod/mod_dav_fs.html.en create mode 100644 trunk/docs/manual/mod/mod_dav_fs.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_dav_fs.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_dav_fs.xml create mode 100644 trunk/docs/manual/mod/mod_dav_fs.xml.ja create mode 100644 trunk/docs/manual/mod/mod_dav_fs.xml.ko create mode 100644 trunk/docs/manual/mod/mod_dav_fs.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dav_lock.html create mode 100644 trunk/docs/manual/mod/mod_dav_lock.html.en create mode 100644 trunk/docs/manual/mod/mod_dav_lock.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_dav_lock.xml create mode 100644 trunk/docs/manual/mod/mod_dav_lock.xml.ja create mode 100644 trunk/docs/manual/mod/mod_dav_lock.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dbd.html create mode 100644 trunk/docs/manual/mod/mod_dbd.html.en create mode 100644 trunk/docs/manual/mod/mod_dbd.xml create mode 100644 trunk/docs/manual/mod/mod_dbd.xml.meta create mode 100644 trunk/docs/manual/mod/mod_deflate.html create mode 100644 trunk/docs/manual/mod/mod_deflate.html.en create mode 100644 trunk/docs/manual/mod/mod_deflate.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_deflate.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_deflate.xml create mode 100644 trunk/docs/manual/mod/mod_deflate.xml.ja create mode 100644 trunk/docs/manual/mod/mod_deflate.xml.ko create mode 100644 trunk/docs/manual/mod/mod_deflate.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dir.html create mode 100644 trunk/docs/manual/mod/mod_dir.html.en create mode 100644 trunk/docs/manual/mod/mod_dir.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_dir.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_dir.xml create mode 100644 trunk/docs/manual/mod/mod_dir.xml.ja create mode 100644 trunk/docs/manual/mod/mod_dir.xml.ko create mode 100644 trunk/docs/manual/mod/mod_dir.xml.meta create mode 100644 trunk/docs/manual/mod/mod_disk_cache.html create mode 100644 trunk/docs/manual/mod/mod_disk_cache.html.en create mode 100644 trunk/docs/manual/mod/mod_disk_cache.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_disk_cache.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_disk_cache.xml create mode 100644 trunk/docs/manual/mod/mod_disk_cache.xml.ja create mode 100644 trunk/docs/manual/mod/mod_disk_cache.xml.ko create mode 100644 trunk/docs/manual/mod/mod_disk_cache.xml.meta create mode 100644 trunk/docs/manual/mod/mod_dumpio.html create mode 100644 trunk/docs/manual/mod/mod_dumpio.html.en create mode 100644 trunk/docs/manual/mod/mod_dumpio.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_dumpio.xml create mode 100644 trunk/docs/manual/mod/mod_dumpio.xml.ja create mode 100644 trunk/docs/manual/mod/mod_dumpio.xml.meta create mode 100644 trunk/docs/manual/mod/mod_echo.html create mode 100644 trunk/docs/manual/mod/mod_echo.html.en create mode 100644 trunk/docs/manual/mod/mod_echo.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_echo.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_echo.xml create mode 100644 trunk/docs/manual/mod/mod_echo.xml.ja create mode 100644 trunk/docs/manual/mod/mod_echo.xml.ko create mode 100644 trunk/docs/manual/mod/mod_echo.xml.meta create mode 100644 trunk/docs/manual/mod/mod_env.html create mode 100644 trunk/docs/manual/mod/mod_env.html.en create mode 100644 trunk/docs/manual/mod/mod_env.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_env.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_env.xml create mode 100644 trunk/docs/manual/mod/mod_env.xml.ja create mode 100644 trunk/docs/manual/mod/mod_env.xml.ko create mode 100644 trunk/docs/manual/mod/mod_env.xml.meta create mode 100644 trunk/docs/manual/mod/mod_example.html create mode 100644 trunk/docs/manual/mod/mod_example.html.en create mode 100644 trunk/docs/manual/mod/mod_example.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_example.xml create mode 100644 trunk/docs/manual/mod/mod_example.xml.ko create mode 100644 trunk/docs/manual/mod/mod_example.xml.meta create mode 100644 trunk/docs/manual/mod/mod_expires.html create mode 100644 trunk/docs/manual/mod/mod_expires.html.en create mode 100644 trunk/docs/manual/mod/mod_expires.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_expires.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_expires.xml create mode 100644 trunk/docs/manual/mod/mod_expires.xml.ja create mode 100644 trunk/docs/manual/mod/mod_expires.xml.ko create mode 100644 trunk/docs/manual/mod/mod_expires.xml.meta create mode 100644 trunk/docs/manual/mod/mod_ext_filter.html create mode 100644 trunk/docs/manual/mod/mod_ext_filter.html.en create mode 100644 trunk/docs/manual/mod/mod_ext_filter.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_ext_filter.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_ext_filter.xml create mode 100644 trunk/docs/manual/mod/mod_ext_filter.xml.ja create mode 100644 trunk/docs/manual/mod/mod_ext_filter.xml.ko create mode 100644 trunk/docs/manual/mod/mod_ext_filter.xml.meta create mode 100644 trunk/docs/manual/mod/mod_file_cache.html create mode 100644 trunk/docs/manual/mod/mod_file_cache.html.en create mode 100644 trunk/docs/manual/mod/mod_file_cache.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_file_cache.xml create mode 100644 trunk/docs/manual/mod/mod_file_cache.xml.ko create mode 100644 trunk/docs/manual/mod/mod_file_cache.xml.meta create mode 100644 trunk/docs/manual/mod/mod_filter.html create mode 100644 trunk/docs/manual/mod/mod_filter.html.en create mode 100644 trunk/docs/manual/mod/mod_filter.xml create mode 100644 trunk/docs/manual/mod/mod_filter.xml.meta create mode 100644 trunk/docs/manual/mod/mod_headers.html create mode 100644 trunk/docs/manual/mod/mod_headers.html.en create mode 100644 trunk/docs/manual/mod/mod_headers.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_headers.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_headers.xml create mode 100644 trunk/docs/manual/mod/mod_headers.xml.ja create mode 100644 trunk/docs/manual/mod/mod_headers.xml.ko create mode 100644 trunk/docs/manual/mod/mod_headers.xml.meta create mode 100644 trunk/docs/manual/mod/mod_ident.html create mode 100644 trunk/docs/manual/mod/mod_ident.html.en create mode 100644 trunk/docs/manual/mod/mod_ident.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_ident.xml create mode 100644 trunk/docs/manual/mod/mod_ident.xml.ko create mode 100644 trunk/docs/manual/mod/mod_ident.xml.meta create mode 100644 trunk/docs/manual/mod/mod_imagemap.html create mode 100644 trunk/docs/manual/mod/mod_imagemap.html.en create mode 100644 trunk/docs/manual/mod/mod_imagemap.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_imagemap.xml create mode 100644 trunk/docs/manual/mod/mod_imagemap.xml.ko create mode 100644 trunk/docs/manual/mod/mod_imagemap.xml.meta create mode 100644 trunk/docs/manual/mod/mod_include.html create mode 100644 trunk/docs/manual/mod/mod_include.html.en create mode 100644 trunk/docs/manual/mod/mod_include.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_include.xml create mode 100644 trunk/docs/manual/mod/mod_include.xml.ja create mode 100644 trunk/docs/manual/mod/mod_include.xml.meta create mode 100644 trunk/docs/manual/mod/mod_info.html create mode 100644 trunk/docs/manual/mod/mod_info.html.en create mode 100644 trunk/docs/manual/mod/mod_info.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_info.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_info.xml create mode 100644 trunk/docs/manual/mod/mod_info.xml.ja create mode 100644 trunk/docs/manual/mod/mod_info.xml.ko create mode 100644 trunk/docs/manual/mod/mod_info.xml.meta create mode 100644 trunk/docs/manual/mod/mod_isapi.html create mode 100644 trunk/docs/manual/mod/mod_isapi.html.en create mode 100644 trunk/docs/manual/mod/mod_isapi.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_isapi.xml create mode 100644 trunk/docs/manual/mod/mod_isapi.xml.ko create mode 100644 trunk/docs/manual/mod/mod_isapi.xml.meta create mode 100644 trunk/docs/manual/mod/mod_ldap.html create mode 100644 trunk/docs/manual/mod/mod_ldap.html.en create mode 100644 trunk/docs/manual/mod/mod_ldap.xml create mode 100644 trunk/docs/manual/mod/mod_ldap.xml.meta create mode 100644 trunk/docs/manual/mod/mod_log_config.html create mode 100644 trunk/docs/manual/mod/mod_log_config.html.en create mode 100644 trunk/docs/manual/mod/mod_log_config.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_log_config.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_log_config.xml create mode 100644 trunk/docs/manual/mod/mod_log_config.xml.ja create mode 100644 trunk/docs/manual/mod/mod_log_config.xml.ko create mode 100644 trunk/docs/manual/mod/mod_log_config.xml.meta create mode 100644 trunk/docs/manual/mod/mod_log_forensic.html create mode 100644 trunk/docs/manual/mod/mod_log_forensic.html.en create mode 100644 trunk/docs/manual/mod/mod_log_forensic.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_log_forensic.xml create mode 100644 trunk/docs/manual/mod/mod_log_forensic.xml.ja create mode 100644 trunk/docs/manual/mod/mod_log_forensic.xml.meta create mode 100644 trunk/docs/manual/mod/mod_logio.html create mode 100644 trunk/docs/manual/mod/mod_logio.html.en create mode 100644 trunk/docs/manual/mod/mod_logio.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_logio.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_logio.xml create mode 100644 trunk/docs/manual/mod/mod_logio.xml.ja create mode 100644 trunk/docs/manual/mod/mod_logio.xml.ko create mode 100644 trunk/docs/manual/mod/mod_logio.xml.meta create mode 100644 trunk/docs/manual/mod/mod_mem_cache.html create mode 100644 trunk/docs/manual/mod/mod_mem_cache.html.en create mode 100644 trunk/docs/manual/mod/mod_mem_cache.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_mem_cache.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_mem_cache.xml create mode 100644 trunk/docs/manual/mod/mod_mem_cache.xml.ja create mode 100644 trunk/docs/manual/mod/mod_mem_cache.xml.ko create mode 100644 trunk/docs/manual/mod/mod_mem_cache.xml.meta create mode 100644 trunk/docs/manual/mod/mod_mime.html create mode 100644 trunk/docs/manual/mod/mod_mime.html.en create mode 100644 trunk/docs/manual/mod/mod_mime.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_mime.xml create mode 100644 trunk/docs/manual/mod/mod_mime.xml.ja create mode 100644 trunk/docs/manual/mod/mod_mime.xml.meta create mode 100644 trunk/docs/manual/mod/mod_mime_magic.html create mode 100644 trunk/docs/manual/mod/mod_mime_magic.html.en create mode 100644 trunk/docs/manual/mod/mod_mime_magic.xml create mode 100644 trunk/docs/manual/mod/mod_mime_magic.xml.meta create mode 100644 trunk/docs/manual/mod/mod_negotiation.html create mode 100644 trunk/docs/manual/mod/mod_negotiation.html.en create mode 100644 trunk/docs/manual/mod/mod_negotiation.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_negotiation.xml create mode 100644 trunk/docs/manual/mod/mod_negotiation.xml.ja create mode 100644 trunk/docs/manual/mod/mod_negotiation.xml.meta create mode 100644 trunk/docs/manual/mod/mod_nw_ssl.html create mode 100644 trunk/docs/manual/mod/mod_nw_ssl.html.en create mode 100644 trunk/docs/manual/mod/mod_nw_ssl.xml create mode 100644 trunk/docs/manual/mod/mod_nw_ssl.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy.html create mode 100644 trunk/docs/manual/mod/mod_proxy.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_proxy.xml create mode 100644 trunk/docs/manual/mod/mod_proxy.xml.ja create mode 100644 trunk/docs/manual/mod/mod_proxy.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.html create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.xml create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.xml.ja create mode 100644 trunk/docs/manual/mod/mod_proxy_ajp.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.html create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.xml create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.xml.ja create mode 100644 trunk/docs/manual/mod/mod_proxy_balancer.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy_connect.html create mode 100644 trunk/docs/manual/mod/mod_proxy_connect.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy_connect.xml create mode 100644 trunk/docs/manual/mod/mod_proxy_connect.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy_ftp.html create mode 100644 trunk/docs/manual/mod/mod_proxy_ftp.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy_ftp.xml create mode 100644 trunk/docs/manual/mod/mod_proxy_ftp.xml.meta create mode 100644 trunk/docs/manual/mod/mod_proxy_http.html create mode 100644 trunk/docs/manual/mod/mod_proxy_http.html.en create mode 100644 trunk/docs/manual/mod/mod_proxy_http.xml create mode 100644 trunk/docs/manual/mod/mod_proxy_http.xml.meta create mode 100644 trunk/docs/manual/mod/mod_rewrite.html create mode 100644 trunk/docs/manual/mod/mod_rewrite.html.en create mode 100644 trunk/docs/manual/mod/mod_rewrite.xml create mode 100644 trunk/docs/manual/mod/mod_rewrite.xml.meta create mode 100644 trunk/docs/manual/mod/mod_setenvif.html create mode 100644 trunk/docs/manual/mod/mod_setenvif.html.en create mode 100644 trunk/docs/manual/mod/mod_setenvif.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_setenvif.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_setenvif.xml create mode 100644 trunk/docs/manual/mod/mod_setenvif.xml.ja create mode 100644 trunk/docs/manual/mod/mod_setenvif.xml.ko create mode 100644 trunk/docs/manual/mod/mod_setenvif.xml.meta create mode 100644 trunk/docs/manual/mod/mod_so.html create mode 100644 trunk/docs/manual/mod/mod_so.html.en create mode 100644 trunk/docs/manual/mod/mod_so.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_so.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_so.xml create mode 100644 trunk/docs/manual/mod/mod_so.xml.ja create mode 100644 trunk/docs/manual/mod/mod_so.xml.ko create mode 100644 trunk/docs/manual/mod/mod_so.xml.meta create mode 100644 trunk/docs/manual/mod/mod_speling.html create mode 100644 trunk/docs/manual/mod/mod_speling.html.en create mode 100644 trunk/docs/manual/mod/mod_speling.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_speling.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_speling.xml create mode 100644 trunk/docs/manual/mod/mod_speling.xml.ja create mode 100644 trunk/docs/manual/mod/mod_speling.xml.ko create mode 100644 trunk/docs/manual/mod/mod_speling.xml.meta create mode 100644 trunk/docs/manual/mod/mod_ssl.html create mode 100644 trunk/docs/manual/mod/mod_ssl.html.en create mode 100644 trunk/docs/manual/mod/mod_ssl.xml create mode 100644 trunk/docs/manual/mod/mod_ssl.xml.meta create mode 100644 trunk/docs/manual/mod/mod_status.html create mode 100644 trunk/docs/manual/mod/mod_status.html.en create mode 100644 trunk/docs/manual/mod/mod_status.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_status.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_status.xml create mode 100644 trunk/docs/manual/mod/mod_status.xml.ja create mode 100644 trunk/docs/manual/mod/mod_status.xml.ko create mode 100644 trunk/docs/manual/mod/mod_status.xml.meta create mode 100644 trunk/docs/manual/mod/mod_suexec.html create mode 100644 trunk/docs/manual/mod/mod_suexec.html.en create mode 100644 trunk/docs/manual/mod/mod_suexec.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_suexec.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_suexec.xml create mode 100644 trunk/docs/manual/mod/mod_suexec.xml.ja create mode 100644 trunk/docs/manual/mod/mod_suexec.xml.ko create mode 100644 trunk/docs/manual/mod/mod_suexec.xml.meta create mode 100644 trunk/docs/manual/mod/mod_unique_id.html create mode 100644 trunk/docs/manual/mod/mod_unique_id.html.en create mode 100644 trunk/docs/manual/mod/mod_unique_id.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_unique_id.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_unique_id.xml create mode 100644 trunk/docs/manual/mod/mod_unique_id.xml.ja create mode 100644 trunk/docs/manual/mod/mod_unique_id.xml.ko create mode 100644 trunk/docs/manual/mod/mod_unique_id.xml.meta create mode 100644 trunk/docs/manual/mod/mod_userdir.html create mode 100644 trunk/docs/manual/mod/mod_userdir.html.en create mode 100644 trunk/docs/manual/mod/mod_userdir.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_userdir.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_userdir.xml create mode 100644 trunk/docs/manual/mod/mod_userdir.xml.ja create mode 100644 trunk/docs/manual/mod/mod_userdir.xml.ko create mode 100644 trunk/docs/manual/mod/mod_userdir.xml.meta create mode 100644 trunk/docs/manual/mod/mod_usertrack.html create mode 100644 trunk/docs/manual/mod/mod_usertrack.html.en create mode 100644 trunk/docs/manual/mod/mod_usertrack.xml create mode 100644 trunk/docs/manual/mod/mod_usertrack.xml.meta create mode 100644 trunk/docs/manual/mod/mod_version.html create mode 100644 trunk/docs/manual/mod/mod_version.html.en create mode 100644 trunk/docs/manual/mod/mod_version.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mod_version.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/mod_version.xml create mode 100644 trunk/docs/manual/mod/mod_version.xml.ja create mode 100644 trunk/docs/manual/mod/mod_version.xml.ko create mode 100644 trunk/docs/manual/mod/mod_version.xml.meta create mode 100644 trunk/docs/manual/mod/mod_vhost_alias.html create mode 100644 trunk/docs/manual/mod/mod_vhost_alias.html.en create mode 100644 trunk/docs/manual/mod/mod_vhost_alias.xml create mode 100644 trunk/docs/manual/mod/mod_vhost_alias.xml.meta create mode 100644 trunk/docs/manual/mod/module-dict.html create mode 100644 trunk/docs/manual/mod/module-dict.html.en create mode 100644 trunk/docs/manual/mod/module-dict.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/module-dict.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/module-dict.xml create mode 100644 trunk/docs/manual/mod/module-dict.xml.ja create mode 100644 trunk/docs/manual/mod/module-dict.xml.ko create mode 100644 trunk/docs/manual/mod/module-dict.xml.meta create mode 100644 trunk/docs/manual/mod/mpm_common.html create mode 100644 trunk/docs/manual/mod/mpm_common.html.de create mode 100644 trunk/docs/manual/mod/mpm_common.html.en create mode 100644 trunk/docs/manual/mod/mpm_common.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mpm_common.xml create mode 100644 trunk/docs/manual/mod/mpm_common.xml.de create mode 100644 trunk/docs/manual/mod/mpm_common.xml.ja create mode 100644 trunk/docs/manual/mod/mpm_common.xml.meta create mode 100644 trunk/docs/manual/mod/mpm_netware.html create mode 100644 trunk/docs/manual/mod/mpm_netware.html.en create mode 100644 trunk/docs/manual/mod/mpm_netware.xml create mode 100644 trunk/docs/manual/mod/mpm_netware.xml.meta create mode 100644 trunk/docs/manual/mod/mpm_winnt.html create mode 100644 trunk/docs/manual/mod/mpm_winnt.html.de create mode 100644 trunk/docs/manual/mod/mpm_winnt.html.en create mode 100644 trunk/docs/manual/mod/mpm_winnt.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/mpm_winnt.xml create mode 100644 trunk/docs/manual/mod/mpm_winnt.xml.de create mode 100644 trunk/docs/manual/mod/mpm_winnt.xml.ja create mode 100644 trunk/docs/manual/mod/mpm_winnt.xml.meta create mode 100644 trunk/docs/manual/mod/mpmt_os2.html create mode 100644 trunk/docs/manual/mod/mpmt_os2.html.en create mode 100644 trunk/docs/manual/mod/mpmt_os2.xml create mode 100644 trunk/docs/manual/mod/mpmt_os2.xml.meta create mode 100644 trunk/docs/manual/mod/perchild.html create mode 100644 trunk/docs/manual/mod/perchild.html.en create mode 100644 trunk/docs/manual/mod/perchild.xml create mode 100644 trunk/docs/manual/mod/perchild.xml.meta create mode 100644 trunk/docs/manual/mod/prefork.html create mode 100644 trunk/docs/manual/mod/prefork.html.de create mode 100644 trunk/docs/manual/mod/prefork.html.en create mode 100644 trunk/docs/manual/mod/prefork.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/prefork.xml create mode 100644 trunk/docs/manual/mod/prefork.xml.de create mode 100644 trunk/docs/manual/mod/prefork.xml.ja create mode 100644 trunk/docs/manual/mod/prefork.xml.meta create mode 100644 trunk/docs/manual/mod/quickreference.html create mode 100644 trunk/docs/manual/mod/quickreference.html.de create mode 100644 trunk/docs/manual/mod/quickreference.html.en create mode 100644 trunk/docs/manual/mod/quickreference.html.es create mode 100644 trunk/docs/manual/mod/quickreference.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/quickreference.html.ko.euc-kr create mode 100644 trunk/docs/manual/mod/quickreference.xml create mode 100644 trunk/docs/manual/mod/quickreference.xml.de create mode 100644 trunk/docs/manual/mod/quickreference.xml.es create mode 100644 trunk/docs/manual/mod/quickreference.xml.ja create mode 100644 trunk/docs/manual/mod/quickreference.xml.ko create mode 100644 trunk/docs/manual/mod/quickreference.xml.meta create mode 100644 trunk/docs/manual/mod/threadpool.html create mode 100644 trunk/docs/manual/mod/threadpool.html.en create mode 100644 trunk/docs/manual/mod/threadpool.xml create mode 100644 trunk/docs/manual/mod/threadpool.xml.meta create mode 100644 trunk/docs/manual/mod/worker.html create mode 100644 trunk/docs/manual/mod/worker.html.de create mode 100644 trunk/docs/manual/mod/worker.html.en create mode 100644 trunk/docs/manual/mod/worker.html.ja.euc-jp create mode 100644 trunk/docs/manual/mod/worker.xml create mode 100644 trunk/docs/manual/mod/worker.xml.de create mode 100644 trunk/docs/manual/mod/worker.xml.ja create mode 100644 trunk/docs/manual/mod/worker.xml.meta create mode 100644 trunk/docs/manual/mpm.html create mode 100644 trunk/docs/manual/mpm.html.de create mode 100644 trunk/docs/manual/mpm.html.en create mode 100644 trunk/docs/manual/mpm.html.es create mode 100644 trunk/docs/manual/mpm.html.ja.euc-jp create mode 100644 trunk/docs/manual/mpm.html.ko.euc-kr create mode 100644 trunk/docs/manual/mpm.xml create mode 100644 trunk/docs/manual/mpm.xml.de create mode 100644 trunk/docs/manual/mpm.xml.es create mode 100644 trunk/docs/manual/mpm.xml.ja create mode 100644 trunk/docs/manual/mpm.xml.ko create mode 100644 trunk/docs/manual/mpm.xml.meta create mode 100644 trunk/docs/manual/new_features_2_0.html create mode 100644 trunk/docs/manual/new_features_2_0.html.de create mode 100644 trunk/docs/manual/new_features_2_0.html.en create mode 100644 trunk/docs/manual/new_features_2_0.html.fr create mode 100644 trunk/docs/manual/new_features_2_0.html.ja.euc-jp create mode 100644 trunk/docs/manual/new_features_2_0.html.ko.euc-kr create mode 100644 trunk/docs/manual/new_features_2_0.html.pt-br create mode 100644 trunk/docs/manual/new_features_2_0.html.ru.koi8-r create mode 100644 trunk/docs/manual/new_features_2_0.xml create mode 100644 trunk/docs/manual/new_features_2_0.xml.de create mode 100644 trunk/docs/manual/new_features_2_0.xml.fr create mode 100644 trunk/docs/manual/new_features_2_0.xml.ja create mode 100644 trunk/docs/manual/new_features_2_0.xml.ko create mode 100644 trunk/docs/manual/new_features_2_0.xml.meta create mode 100644 trunk/docs/manual/new_features_2_0.xml.pt-br create mode 100644 trunk/docs/manual/new_features_2_0.xml.ru create mode 100644 trunk/docs/manual/new_features_2_2.html create mode 100644 trunk/docs/manual/new_features_2_2.html.en create mode 100644 trunk/docs/manual/new_features_2_2.html.ko.euc-kr create mode 100644 trunk/docs/manual/new_features_2_2.html.pt-br create mode 100644 trunk/docs/manual/new_features_2_2.xml create mode 100644 trunk/docs/manual/new_features_2_2.xml.ko create mode 100644 trunk/docs/manual/new_features_2_2.xml.meta create mode 100644 trunk/docs/manual/new_features_2_2.xml.pt-br create mode 100644 trunk/docs/manual/platform/ebcdic.html create mode 100644 trunk/docs/manual/platform/ebcdic.html.en create mode 100644 trunk/docs/manual/platform/ebcdic.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/ebcdic.xml create mode 100644 trunk/docs/manual/platform/ebcdic.xml.ko create mode 100644 trunk/docs/manual/platform/ebcdic.xml.meta create mode 100644 trunk/docs/manual/platform/index.html create mode 100644 trunk/docs/manual/platform/index.html.en create mode 100644 trunk/docs/manual/platform/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/index.xml create mode 100644 trunk/docs/manual/platform/index.xml.ko create mode 100644 trunk/docs/manual/platform/index.xml.meta create mode 100644 trunk/docs/manual/platform/netware.html create mode 100644 trunk/docs/manual/platform/netware.html.en create mode 100644 trunk/docs/manual/platform/netware.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/netware.xml create mode 100644 trunk/docs/manual/platform/netware.xml.ko create mode 100644 trunk/docs/manual/platform/netware.xml.meta create mode 100644 trunk/docs/manual/platform/perf-hp.html create mode 100644 trunk/docs/manual/platform/perf-hp.html.en create mode 100644 trunk/docs/manual/platform/perf-hp.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/perf-hp.xml create mode 100644 trunk/docs/manual/platform/perf-hp.xml.ko create mode 100644 trunk/docs/manual/platform/perf-hp.xml.meta create mode 100644 trunk/docs/manual/platform/win_compiling.html create mode 100644 trunk/docs/manual/platform/win_compiling.html.en create mode 100644 trunk/docs/manual/platform/win_compiling.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/win_compiling.xml create mode 100644 trunk/docs/manual/platform/win_compiling.xml.ko create mode 100644 trunk/docs/manual/platform/win_compiling.xml.meta create mode 100644 trunk/docs/manual/platform/windows.html create mode 100644 trunk/docs/manual/platform/windows.html.en create mode 100644 trunk/docs/manual/platform/windows.html.ko.euc-kr create mode 100644 trunk/docs/manual/platform/windows.xml create mode 100644 trunk/docs/manual/platform/windows.xml.ko create mode 100644 trunk/docs/manual/platform/windows.xml.meta create mode 100644 trunk/docs/manual/programs/ab.html create mode 100644 trunk/docs/manual/programs/ab.html.en create mode 100644 trunk/docs/manual/programs/ab.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/ab.xml create mode 100644 trunk/docs/manual/programs/ab.xml.ko create mode 100644 trunk/docs/manual/programs/ab.xml.meta create mode 100644 trunk/docs/manual/programs/apachectl.html create mode 100644 trunk/docs/manual/programs/apachectl.html.en create mode 100644 trunk/docs/manual/programs/apachectl.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/apachectl.xml create mode 100644 trunk/docs/manual/programs/apachectl.xml.ko create mode 100644 trunk/docs/manual/programs/apachectl.xml.meta create mode 100644 trunk/docs/manual/programs/apxs.html create mode 100644 trunk/docs/manual/programs/apxs.html.en create mode 100644 trunk/docs/manual/programs/apxs.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/apxs.xml create mode 100644 trunk/docs/manual/programs/apxs.xml.ko create mode 100644 trunk/docs/manual/programs/apxs.xml.meta create mode 100644 trunk/docs/manual/programs/configure.html create mode 100644 trunk/docs/manual/programs/configure.html.en create mode 100644 trunk/docs/manual/programs/configure.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/configure.xml create mode 100644 trunk/docs/manual/programs/configure.xml.ko create mode 100644 trunk/docs/manual/programs/configure.xml.meta create mode 100644 trunk/docs/manual/programs/dbmmanage.html create mode 100644 trunk/docs/manual/programs/dbmmanage.html.en create mode 100644 trunk/docs/manual/programs/dbmmanage.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/dbmmanage.xml create mode 100644 trunk/docs/manual/programs/dbmmanage.xml.ko create mode 100644 trunk/docs/manual/programs/dbmmanage.xml.meta create mode 100644 trunk/docs/manual/programs/htcacheclean.html create mode 100644 trunk/docs/manual/programs/htcacheclean.html.en create mode 100644 trunk/docs/manual/programs/htcacheclean.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/htcacheclean.xml create mode 100644 trunk/docs/manual/programs/htcacheclean.xml.ko create mode 100644 trunk/docs/manual/programs/htcacheclean.xml.meta create mode 100644 trunk/docs/manual/programs/htdbm.html create mode 100644 trunk/docs/manual/programs/htdbm.html.en create mode 100644 trunk/docs/manual/programs/htdbm.xml create mode 100644 trunk/docs/manual/programs/htdbm.xml.meta create mode 100644 trunk/docs/manual/programs/htdigest.html create mode 100644 trunk/docs/manual/programs/htdigest.html.en create mode 100644 trunk/docs/manual/programs/htdigest.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/htdigest.xml create mode 100644 trunk/docs/manual/programs/htdigest.xml.ko create mode 100644 trunk/docs/manual/programs/htdigest.xml.meta create mode 100644 trunk/docs/manual/programs/htpasswd.html create mode 100644 trunk/docs/manual/programs/htpasswd.html.en create mode 100644 trunk/docs/manual/programs/htpasswd.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/htpasswd.xml create mode 100644 trunk/docs/manual/programs/htpasswd.xml.ko create mode 100644 trunk/docs/manual/programs/htpasswd.xml.meta create mode 100644 trunk/docs/manual/programs/httpd.html create mode 100644 trunk/docs/manual/programs/httpd.html.en create mode 100644 trunk/docs/manual/programs/httpd.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/httpd.xml create mode 100644 trunk/docs/manual/programs/httpd.xml.ko create mode 100644 trunk/docs/manual/programs/httpd.xml.meta create mode 100644 trunk/docs/manual/programs/index.html create mode 100644 trunk/docs/manual/programs/index.html.en create mode 100644 trunk/docs/manual/programs/index.html.es create mode 100644 trunk/docs/manual/programs/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/index.xml create mode 100644 trunk/docs/manual/programs/index.xml.es create mode 100644 trunk/docs/manual/programs/index.xml.ko create mode 100644 trunk/docs/manual/programs/index.xml.meta create mode 100644 trunk/docs/manual/programs/logresolve.html create mode 100644 trunk/docs/manual/programs/logresolve.html.en create mode 100644 trunk/docs/manual/programs/logresolve.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/logresolve.xml create mode 100644 trunk/docs/manual/programs/logresolve.xml.ko create mode 100644 trunk/docs/manual/programs/logresolve.xml.meta create mode 100644 trunk/docs/manual/programs/other.html create mode 100644 trunk/docs/manual/programs/other.html.en create mode 100644 trunk/docs/manual/programs/other.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/other.xml create mode 100644 trunk/docs/manual/programs/other.xml.ko create mode 100644 trunk/docs/manual/programs/other.xml.meta create mode 100644 trunk/docs/manual/programs/rotatelogs.html create mode 100644 trunk/docs/manual/programs/rotatelogs.html.en create mode 100644 trunk/docs/manual/programs/rotatelogs.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/rotatelogs.xml create mode 100644 trunk/docs/manual/programs/rotatelogs.xml.ko create mode 100644 trunk/docs/manual/programs/rotatelogs.xml.meta create mode 100644 trunk/docs/manual/programs/suexec.html create mode 100644 trunk/docs/manual/programs/suexec.html.en create mode 100644 trunk/docs/manual/programs/suexec.html.ko.euc-kr create mode 100644 trunk/docs/manual/programs/suexec.xml create mode 100644 trunk/docs/manual/programs/suexec.xml.ko create mode 100644 trunk/docs/manual/programs/suexec.xml.meta create mode 100644 trunk/docs/manual/rewrite/index.html create mode 100644 trunk/docs/manual/rewrite/index.html.en create mode 100644 trunk/docs/manual/rewrite/index.xml create mode 100644 trunk/docs/manual/rewrite/index.xml.meta create mode 100644 trunk/docs/manual/rewrite/rewrite_guide.html create mode 100644 trunk/docs/manual/rewrite/rewrite_guide.html.en create mode 100644 trunk/docs/manual/rewrite/rewrite_guide.xml create mode 100644 trunk/docs/manual/rewrite/rewrite_guide.xml.meta create mode 100644 trunk/docs/manual/rewrite/rewrite_guide_advanced.html create mode 100644 trunk/docs/manual/rewrite/rewrite_guide_advanced.html.en create mode 100644 trunk/docs/manual/rewrite/rewrite_guide_advanced.xml create mode 100644 trunk/docs/manual/rewrite/rewrite_guide_advanced.xml.meta create mode 100644 trunk/docs/manual/rewrite/rewrite_intro.html create mode 100644 trunk/docs/manual/rewrite/rewrite_intro.html.en create mode 100644 trunk/docs/manual/rewrite/rewrite_intro.xml create mode 100644 trunk/docs/manual/rewrite/rewrite_intro.xml.meta create mode 100644 trunk/docs/manual/rewrite/rewrite_tech.html create mode 100644 trunk/docs/manual/rewrite/rewrite_tech.html.en create mode 100644 trunk/docs/manual/rewrite/rewrite_tech.xml create mode 100644 trunk/docs/manual/rewrite/rewrite_tech.xml.meta create mode 100644 trunk/docs/manual/sections.html create mode 100644 trunk/docs/manual/sections.html.en create mode 100644 trunk/docs/manual/sections.html.ja.euc-jp create mode 100644 trunk/docs/manual/sections.html.ko.euc-kr create mode 100644 trunk/docs/manual/sections.xml create mode 100644 trunk/docs/manual/sections.xml.ja create mode 100644 trunk/docs/manual/sections.xml.ko create mode 100644 trunk/docs/manual/sections.xml.meta create mode 100644 trunk/docs/manual/server-wide.html create mode 100644 trunk/docs/manual/server-wide.html.en create mode 100644 trunk/docs/manual/server-wide.html.ja.euc-jp create mode 100644 trunk/docs/manual/server-wide.html.ko.euc-kr create mode 100644 trunk/docs/manual/server-wide.xml create mode 100644 trunk/docs/manual/server-wide.xml.ja create mode 100644 trunk/docs/manual/server-wide.xml.ko create mode 100644 trunk/docs/manual/server-wide.xml.meta create mode 100644 trunk/docs/manual/sitemap.html create mode 100644 trunk/docs/manual/sitemap.html.de create mode 100644 trunk/docs/manual/sitemap.html.en create mode 100644 trunk/docs/manual/sitemap.html.es create mode 100644 trunk/docs/manual/sitemap.html.ja.euc-jp create mode 100644 trunk/docs/manual/sitemap.html.ko.euc-kr create mode 100644 trunk/docs/manual/sitemap.xml create mode 100644 trunk/docs/manual/sitemap.xml.de create mode 100644 trunk/docs/manual/sitemap.xml.es create mode 100644 trunk/docs/manual/sitemap.xml.ja create mode 100644 trunk/docs/manual/sitemap.xml.ko create mode 100644 trunk/docs/manual/sitemap.xml.meta create mode 100644 trunk/docs/manual/ssl/index.html create mode 100644 trunk/docs/manual/ssl/index.html.en create mode 100644 trunk/docs/manual/ssl/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/ssl/index.xml create mode 100644 trunk/docs/manual/ssl/index.xml.ja create mode 100644 trunk/docs/manual/ssl/index.xml.meta create mode 100644 trunk/docs/manual/ssl/ssl_compat.html create mode 100644 trunk/docs/manual/ssl/ssl_compat.html.en create mode 100644 trunk/docs/manual/ssl/ssl_compat.xml create mode 100644 trunk/docs/manual/ssl/ssl_compat.xml.meta create mode 100644 trunk/docs/manual/ssl/ssl_faq.html create mode 100644 trunk/docs/manual/ssl/ssl_faq.html.en create mode 100644 trunk/docs/manual/ssl/ssl_faq.xml create mode 100644 trunk/docs/manual/ssl/ssl_faq.xml.meta create mode 100644 trunk/docs/manual/ssl/ssl_howto.html create mode 100644 trunk/docs/manual/ssl/ssl_howto.html.en create mode 100644 trunk/docs/manual/ssl/ssl_howto.xml create mode 100644 trunk/docs/manual/ssl/ssl_howto.xml.meta create mode 100644 trunk/docs/manual/ssl/ssl_intro.html create mode 100644 trunk/docs/manual/ssl/ssl_intro.html.en create mode 100644 trunk/docs/manual/ssl/ssl_intro.html.ja.euc-jp create mode 100644 trunk/docs/manual/ssl/ssl_intro.xml create mode 100644 trunk/docs/manual/ssl/ssl_intro.xml.ja create mode 100644 trunk/docs/manual/ssl/ssl_intro.xml.meta create mode 100644 trunk/docs/manual/stopping.html create mode 100644 trunk/docs/manual/stopping.html.de create mode 100644 trunk/docs/manual/stopping.html.en create mode 100644 trunk/docs/manual/stopping.html.es create mode 100644 trunk/docs/manual/stopping.html.ja.euc-jp create mode 100644 trunk/docs/manual/stopping.html.ko.euc-kr create mode 100644 trunk/docs/manual/stopping.xml create mode 100644 trunk/docs/manual/stopping.xml.de create mode 100644 trunk/docs/manual/stopping.xml.es create mode 100644 trunk/docs/manual/stopping.xml.ja create mode 100644 trunk/docs/manual/stopping.xml.ko create mode 100644 trunk/docs/manual/stopping.xml.meta create mode 100644 trunk/docs/manual/style/build.properties create mode 100644 trunk/docs/manual/style/common.dtd create mode 100644 trunk/docs/manual/style/css/manual-chm.css create mode 100644 trunk/docs/manual/style/css/manual-loose-100pc.css create mode 100644 trunk/docs/manual/style/css/manual-print.css create mode 100644 trunk/docs/manual/style/css/manual-zip-100pc.css create mode 100644 trunk/docs/manual/style/css/manual-zip.css create mode 100644 trunk/docs/manual/style/css/manual.css create mode 100644 trunk/docs/manual/style/description.xml create mode 100644 trunk/docs/manual/style/faq.dtd create mode 100644 trunk/docs/manual/style/lang-targets.xml create mode 100644 trunk/docs/manual/style/lang/de.xml create mode 100644 trunk/docs/manual/style/lang/en.xml create mode 100644 trunk/docs/manual/style/lang/es.xml create mode 100644 trunk/docs/manual/style/lang/fr.xml create mode 100644 trunk/docs/manual/style/lang/ja.xml create mode 100644 trunk/docs/manual/style/lang/ko.xml create mode 100644 trunk/docs/manual/style/lang/pt-br.xml create mode 100644 trunk/docs/manual/style/lang/ru.xml create mode 100644 trunk/docs/manual/style/latex/atbeginend.sty create mode 100644 trunk/docs/manual/style/latex/common.xsl create mode 100644 trunk/docs/manual/style/latex/directiveindex.xsl create mode 100644 trunk/docs/manual/style/latex/faq.xsl create mode 100644 trunk/docs/manual/style/latex/html.xsl create mode 100644 trunk/docs/manual/style/latex/latex.xsl create mode 100644 trunk/docs/manual/style/latex/manualpage.xsl create mode 100644 trunk/docs/manual/style/latex/moduleindex.xsl create mode 100644 trunk/docs/manual/style/latex/quickreference.xsl create mode 100644 trunk/docs/manual/style/latex/synopsis.xsl create mode 100644 trunk/docs/manual/style/manual.de.xsl create mode 100644 trunk/docs/manual/style/manual.en.xsl create mode 100644 trunk/docs/manual/style/manual.es.xsl create mode 100644 trunk/docs/manual/style/manual.fr.xsl create mode 100644 trunk/docs/manual/style/manual.ja.xsl create mode 100644 trunk/docs/manual/style/manual.ko.xsl create mode 100644 trunk/docs/manual/style/manual.pt-br.xsl create mode 100644 trunk/docs/manual/style/manual.ru.xsl create mode 100644 trunk/docs/manual/style/manualpage.dtd create mode 100644 trunk/docs/manual/style/modulesynopsis.dtd create mode 100644 trunk/docs/manual/style/sitemap.dtd create mode 100644 trunk/docs/manual/style/xsl/common.xsl create mode 100644 trunk/docs/manual/style/xsl/directiveindex.xsl create mode 100644 trunk/docs/manual/style/xsl/faq.xsl create mode 100644 trunk/docs/manual/style/xsl/hhc.xsl create mode 100644 trunk/docs/manual/style/xsl/hhp.xsl create mode 100644 trunk/docs/manual/style/xsl/indexpage.xsl create mode 100644 trunk/docs/manual/style/xsl/language.xsl create mode 100644 trunk/docs/manual/style/xsl/maf.xsl create mode 100644 trunk/docs/manual/style/xsl/manualpage.xsl create mode 100644 trunk/docs/manual/style/xsl/moduleindex.xsl create mode 100644 trunk/docs/manual/style/xsl/nroff.xsl create mode 100644 trunk/docs/manual/style/xsl/quickreference.xsl create mode 100644 trunk/docs/manual/style/xsl/sitemap.xsl create mode 100644 trunk/docs/manual/style/xsl/synopsis.xsl create mode 100644 trunk/docs/manual/style/xsl/typemap.xsl create mode 100644 trunk/docs/manual/style/xsl/util/allmodules.xml create mode 100644 trunk/docs/manual/style/xsl/util/designations.xml create mode 100644 trunk/docs/manual/style/xsl/util/lf.xml create mode 100644 trunk/docs/manual/style/xsl/util/li-end.xml create mode 100644 trunk/docs/manual/style/xsl/util/li-start.xml create mode 100644 trunk/docs/manual/style/xsl/util/modtrans.xsl create mode 100644 trunk/docs/manual/style/xsl/util/nbsp.xml create mode 100644 trunk/docs/manual/style/xsl/util/tab.xml create mode 100644 trunk/docs/manual/style/xsl/util/ul-end.xml create mode 100644 trunk/docs/manual/style/xsl/util/ul-start.xml create mode 100644 trunk/docs/manual/suexec.html create mode 100644 trunk/docs/manual/suexec.html.en create mode 100644 trunk/docs/manual/suexec.html.ja.euc-jp create mode 100644 trunk/docs/manual/suexec.html.ko.euc-kr create mode 100644 trunk/docs/manual/suexec.xml create mode 100644 trunk/docs/manual/suexec.xml.ja create mode 100644 trunk/docs/manual/suexec.xml.ko create mode 100644 trunk/docs/manual/suexec.xml.meta create mode 100644 trunk/docs/manual/upgrading.html create mode 100644 trunk/docs/manual/upgrading.html.de create mode 100644 trunk/docs/manual/upgrading.html.en create mode 100644 trunk/docs/manual/upgrading.html.fr create mode 100644 trunk/docs/manual/upgrading.html.ja.euc-jp create mode 100644 trunk/docs/manual/upgrading.html.ko.euc-kr create mode 100644 trunk/docs/manual/upgrading.html.pt-br create mode 100644 trunk/docs/manual/upgrading.html.ru.koi8-r create mode 100644 trunk/docs/manual/upgrading.xml create mode 100644 trunk/docs/manual/upgrading.xml.de create mode 100644 trunk/docs/manual/upgrading.xml.ja create mode 100644 trunk/docs/manual/upgrading.xml.ko create mode 100644 trunk/docs/manual/upgrading.xml.meta create mode 100644 trunk/docs/manual/upgrading.xml.pt-br create mode 100644 trunk/docs/manual/upgrading.xml.ru create mode 100644 trunk/docs/manual/urlmapping.html create mode 100644 trunk/docs/manual/urlmapping.html.en create mode 100644 trunk/docs/manual/urlmapping.html.ja.euc-jp create mode 100644 trunk/docs/manual/urlmapping.html.ko.euc-kr create mode 100644 trunk/docs/manual/urlmapping.xml create mode 100644 trunk/docs/manual/urlmapping.xml.ja create mode 100644 trunk/docs/manual/urlmapping.xml.ko create mode 100644 trunk/docs/manual/urlmapping.xml.meta create mode 100644 trunk/docs/manual/vhosts/details.html create mode 100644 trunk/docs/manual/vhosts/details.html.en create mode 100644 trunk/docs/manual/vhosts/details.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/details.xml create mode 100644 trunk/docs/manual/vhosts/details.xml.ko create mode 100644 trunk/docs/manual/vhosts/details.xml.meta create mode 100644 trunk/docs/manual/vhosts/examples.html create mode 100644 trunk/docs/manual/vhosts/examples.html.en create mode 100644 trunk/docs/manual/vhosts/examples.html.ja.euc-jp create mode 100644 trunk/docs/manual/vhosts/examples.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/examples.xml create mode 100644 trunk/docs/manual/vhosts/examples.xml.ja create mode 100644 trunk/docs/manual/vhosts/examples.xml.ko create mode 100644 trunk/docs/manual/vhosts/examples.xml.meta create mode 100644 trunk/docs/manual/vhosts/fd-limits.html create mode 100644 trunk/docs/manual/vhosts/fd-limits.html.en create mode 100644 trunk/docs/manual/vhosts/fd-limits.html.ja.euc-jp create mode 100644 trunk/docs/manual/vhosts/fd-limits.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/fd-limits.xml create mode 100644 trunk/docs/manual/vhosts/fd-limits.xml.ja create mode 100644 trunk/docs/manual/vhosts/fd-limits.xml.ko create mode 100644 trunk/docs/manual/vhosts/fd-limits.xml.meta create mode 100644 trunk/docs/manual/vhosts/index.html create mode 100644 trunk/docs/manual/vhosts/index.html.de create mode 100644 trunk/docs/manual/vhosts/index.html.en create mode 100644 trunk/docs/manual/vhosts/index.html.ja.euc-jp create mode 100644 trunk/docs/manual/vhosts/index.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/index.xml create mode 100644 trunk/docs/manual/vhosts/index.xml.de create mode 100644 trunk/docs/manual/vhosts/index.xml.ja create mode 100644 trunk/docs/manual/vhosts/index.xml.ko create mode 100644 trunk/docs/manual/vhosts/index.xml.meta create mode 100644 trunk/docs/manual/vhosts/ip-based.html create mode 100644 trunk/docs/manual/vhosts/ip-based.html.en create mode 100644 trunk/docs/manual/vhosts/ip-based.html.ja.euc-jp create mode 100644 trunk/docs/manual/vhosts/ip-based.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/ip-based.xml create mode 100644 trunk/docs/manual/vhosts/ip-based.xml.ja create mode 100644 trunk/docs/manual/vhosts/ip-based.xml.ko create mode 100644 trunk/docs/manual/vhosts/ip-based.xml.meta create mode 100644 trunk/docs/manual/vhosts/mass.html create mode 100644 trunk/docs/manual/vhosts/mass.html.en create mode 100644 trunk/docs/manual/vhosts/mass.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/mass.xml create mode 100644 trunk/docs/manual/vhosts/mass.xml.ko create mode 100644 trunk/docs/manual/vhosts/mass.xml.meta create mode 100644 trunk/docs/manual/vhosts/name-based.html create mode 100644 trunk/docs/manual/vhosts/name-based.html.de create mode 100644 trunk/docs/manual/vhosts/name-based.html.en create mode 100644 trunk/docs/manual/vhosts/name-based.html.ja.euc-jp create mode 100644 trunk/docs/manual/vhosts/name-based.html.ko.euc-kr create mode 100644 trunk/docs/manual/vhosts/name-based.xml create mode 100644 trunk/docs/manual/vhosts/name-based.xml.de create mode 100644 trunk/docs/manual/vhosts/name-based.xml.ja create mode 100644 trunk/docs/manual/vhosts/name-based.xml.ko create mode 100644 trunk/docs/manual/vhosts/name-based.xml.meta create mode 100644 trunk/emacs-style create mode 100644 trunk/httpd.dsp create mode 100644 trunk/include/.indent.pro create mode 100644 trunk/include/ap_compat.h create mode 100644 trunk/include/ap_config.h create mode 100644 trunk/include/ap_config_layout.h.in create mode 100644 trunk/include/ap_listen.h create mode 100644 trunk/include/ap_mmn.h create mode 100644 trunk/include/ap_mpm.h create mode 100644 trunk/include/ap_provider.h create mode 100644 trunk/include/ap_regex.h create mode 100644 trunk/include/ap_regkey.h create mode 100644 trunk/include/ap_release.h create mode 100644 trunk/include/http_config.h create mode 100644 trunk/include/http_connection.h create mode 100644 trunk/include/http_core.h create mode 100644 trunk/include/http_log.h create mode 100644 trunk/include/http_main.h create mode 100644 trunk/include/http_protocol.h create mode 100644 trunk/include/http_request.h create mode 100644 trunk/include/http_vhost.h create mode 100644 trunk/include/httpd.h create mode 100644 trunk/include/mpm_common.h create mode 100644 trunk/include/scoreboard.h create mode 100644 trunk/include/util_cfgtree.h create mode 100644 trunk/include/util_charset.h create mode 100644 trunk/include/util_ebcdic.h create mode 100644 trunk/include/util_filter.h create mode 100644 trunk/include/util_ldap.h create mode 100644 trunk/include/util_md5.h create mode 100644 trunk/include/util_script.h create mode 100644 trunk/include/util_time.h create mode 100644 trunk/include/util_xml.h create mode 100644 trunk/libhttpd.dsp create mode 100644 trunk/modules/Makefile.in create mode 100644 trunk/modules/NWGNUmakefile create mode 100644 trunk/modules/README create mode 100644 trunk/modules/aaa/.indent.pro create mode 100644 trunk/modules/aaa/Makefile.in create mode 100644 trunk/modules/aaa/NWGNUauthbasc create mode 100644 trunk/modules/aaa/NWGNUauthdigt create mode 100644 trunk/modules/aaa/NWGNUauthnalias create mode 100644 trunk/modules/aaa/NWGNUauthnano create mode 100644 trunk/modules/aaa/NWGNUauthndbm create mode 100644 trunk/modules/aaa/NWGNUauthndef create mode 100644 trunk/modules/aaa/NWGNUauthnfil create mode 100644 trunk/modules/aaa/NWGNUauthnzldap create mode 100644 trunk/modules/aaa/NWGNUauthzdbm create mode 100644 trunk/modules/aaa/NWGNUauthzdef create mode 100644 trunk/modules/aaa/NWGNUauthzgrp create mode 100644 trunk/modules/aaa/NWGNUauthzusr create mode 100644 trunk/modules/aaa/NWGNUmakefile create mode 100644 trunk/modules/aaa/config.m4 create mode 100644 trunk/modules/aaa/mod_auth.h create mode 100644 trunk/modules/aaa/mod_auth_basic.c create mode 100644 trunk/modules/aaa/mod_auth_basic.dsp create mode 100644 trunk/modules/aaa/mod_auth_digest.c create mode 100644 trunk/modules/aaa/mod_auth_digest.dsp create mode 100644 trunk/modules/aaa/mod_authn_alias.c create mode 100644 trunk/modules/aaa/mod_authn_anon.c create mode 100644 trunk/modules/aaa/mod_authn_anon.dsp create mode 100644 trunk/modules/aaa/mod_authn_dbm.c create mode 100644 trunk/modules/aaa/mod_authn_dbm.dsp create mode 100644 trunk/modules/aaa/mod_authn_default.c create mode 100644 trunk/modules/aaa/mod_authn_default.dsp create mode 100644 trunk/modules/aaa/mod_authn_file.c create mode 100644 trunk/modules/aaa/mod_authn_file.dsp create mode 100644 trunk/modules/aaa/mod_authnz_ldap.c create mode 100644 trunk/modules/aaa/mod_authnz_ldap.dsp create mode 100644 trunk/modules/aaa/mod_authz_dbm.c create mode 100644 trunk/modules/aaa/mod_authz_dbm.dsp create mode 100644 trunk/modules/aaa/mod_authz_default.c create mode 100644 trunk/modules/aaa/mod_authz_default.dsp create mode 100644 trunk/modules/aaa/mod_authz_groupfile.c create mode 100644 trunk/modules/aaa/mod_authz_groupfile.dsp create mode 100644 trunk/modules/aaa/mod_authz_host.c create mode 100644 trunk/modules/aaa/mod_authz_host.dsp create mode 100644 trunk/modules/aaa/mod_authz_owner.c create mode 100644 trunk/modules/aaa/mod_authz_user.c create mode 100644 trunk/modules/aaa/mod_authz_user.dsp create mode 100644 trunk/modules/arch/netware/libprews.c create mode 100644 trunk/modules/arch/netware/mod_auth_basic.def create mode 100644 trunk/modules/arch/netware/mod_auth_digest.def create mode 100644 trunk/modules/arch/netware/mod_authn_anon.def create mode 100644 trunk/modules/arch/netware/mod_authn_dbm.def create mode 100644 trunk/modules/arch/netware/mod_authn_default.def create mode 100644 trunk/modules/arch/netware/mod_authn_file.def create mode 100644 trunk/modules/arch/netware/mod_authz_dbm.def create mode 100644 trunk/modules/arch/netware/mod_authz_default.def create mode 100644 trunk/modules/arch/netware/mod_authz_groupfile.def create mode 100644 trunk/modules/arch/netware/mod_authz_user.def create mode 100644 trunk/modules/arch/netware/mod_cache.def create mode 100644 trunk/modules/arch/netware/mod_cern_meta.def create mode 100644 trunk/modules/arch/netware/mod_dav.def create mode 100644 trunk/modules/arch/netware/mod_disk_cache.def create mode 100644 trunk/modules/arch/netware/mod_echo.def create mode 100644 trunk/modules/arch/netware/mod_expires.def create mode 100644 trunk/modules/arch/netware/mod_file_cache.def create mode 100644 trunk/modules/arch/netware/mod_headers.def create mode 100644 trunk/modules/arch/netware/mod_info.def create mode 100644 trunk/modules/arch/netware/mod_logio.def create mode 100644 trunk/modules/arch/netware/mod_mem_cache.def create mode 100644 trunk/modules/arch/netware/mod_mime_magic.def create mode 100644 trunk/modules/arch/netware/mod_netware.c create mode 100644 trunk/modules/arch/netware/mod_nw_ssl.c create mode 100644 trunk/modules/arch/netware/mod_proxy.def create mode 100644 trunk/modules/arch/netware/mod_proxy_connect.def create mode 100644 trunk/modules/arch/netware/mod_proxy_ftp.def create mode 100644 trunk/modules/arch/netware/mod_proxy_http.def create mode 100644 trunk/modules/arch/netware/mod_rewrite.def create mode 100644 trunk/modules/arch/netware/mod_speling.def create mode 100644 trunk/modules/arch/netware/mod_status.def create mode 100644 trunk/modules/arch/netware/mod_unique_id.def create mode 100644 trunk/modules/arch/netware/mod_usertrack.def create mode 100644 trunk/modules/arch/netware/mod_vhost_alias.def create mode 100644 trunk/modules/arch/netware/moddavfs.def create mode 100644 trunk/modules/arch/win32/Makefile.in create mode 100644 trunk/modules/arch/win32/config.m4 create mode 100644 trunk/modules/arch/win32/mod_isapi.c create mode 100644 trunk/modules/arch/win32/mod_isapi.dsp create mode 100644 trunk/modules/arch/win32/mod_isapi.h create mode 100644 trunk/modules/arch/win32/mod_win32.c create mode 100644 trunk/modules/cache/.indent.pro create mode 100644 trunk/modules/cache/Makefile.in create mode 100644 trunk/modules/cache/NWGNUdsk_cach create mode 100644 trunk/modules/cache/NWGNUmakefile create mode 100644 trunk/modules/cache/NWGNUmem_cach create mode 100644 trunk/modules/cache/NWGNUmod_cach create mode 100644 trunk/modules/cache/cache_cache.c create mode 100644 trunk/modules/cache/cache_cache.h create mode 100644 trunk/modules/cache/cache_hash.c create mode 100644 trunk/modules/cache/cache_hash.h create mode 100644 trunk/modules/cache/cache_pqueue.c create mode 100644 trunk/modules/cache/cache_pqueue.h create mode 100644 trunk/modules/cache/cache_storage.c create mode 100644 trunk/modules/cache/cache_util.c create mode 100644 trunk/modules/cache/config.m4 create mode 100644 trunk/modules/cache/mod_cache.c create mode 100644 trunk/modules/cache/mod_cache.dsp create mode 100644 trunk/modules/cache/mod_cache.h create mode 100644 trunk/modules/cache/mod_cache.imp create mode 100644 trunk/modules/cache/mod_disk_cache.c create mode 100644 trunk/modules/cache/mod_disk_cache.dsp create mode 100644 trunk/modules/cache/mod_file_cache.c create mode 100644 trunk/modules/cache/mod_file_cache.dsp create mode 100644 trunk/modules/cache/mod_file_cache.exp create mode 100644 trunk/modules/cache/mod_mem_cache.c create mode 100644 trunk/modules/cache/mod_mem_cache.dsp create mode 100644 trunk/modules/config5.m4 create mode 100644 trunk/modules/dav/fs/Makefile.in create mode 100644 trunk/modules/dav/fs/NWGNUmakefile create mode 100644 trunk/modules/dav/fs/config6.m4 create mode 100644 trunk/modules/dav/fs/dbm.c create mode 100644 trunk/modules/dav/fs/lock.c create mode 100644 trunk/modules/dav/fs/mod_dav_fs.c create mode 100644 trunk/modules/dav/fs/mod_dav_fs.dsp create mode 100644 trunk/modules/dav/fs/repos.c create mode 100644 trunk/modules/dav/fs/repos.h create mode 100644 trunk/modules/dav/lock/Makefile.in create mode 100644 trunk/modules/dav/lock/NWGNUmakefile create mode 100644 trunk/modules/dav/lock/config6.m4 create mode 100644 trunk/modules/dav/lock/locks.c create mode 100644 trunk/modules/dav/lock/locks.h create mode 100644 trunk/modules/dav/lock/mod_dav_lock.c create mode 100644 trunk/modules/dav/main/Makefile.in create mode 100644 trunk/modules/dav/main/NWGNUmakefile create mode 100644 trunk/modules/dav/main/config5.m4 create mode 100644 trunk/modules/dav/main/dav.imp create mode 100644 trunk/modules/dav/main/liveprop.c create mode 100644 trunk/modules/dav/main/mod_dav.c create mode 100644 trunk/modules/dav/main/mod_dav.dsp create mode 100644 trunk/modules/dav/main/mod_dav.h create mode 100644 trunk/modules/dav/main/props.c create mode 100644 trunk/modules/dav/main/providers.c create mode 100644 trunk/modules/dav/main/std_liveprop.c create mode 100644 trunk/modules/dav/main/util.c create mode 100644 trunk/modules/dav/main/util_lock.c create mode 100644 trunk/modules/debug/Makefile.in create mode 100644 trunk/modules/debug/NWGNUmakefile create mode 100644 trunk/modules/debug/NWGNUmodbucketeer create mode 100644 trunk/modules/debug/NWGNUmoddumpio create mode 100644 trunk/modules/debug/README create mode 100644 trunk/modules/debug/config.m4 create mode 100644 trunk/modules/debug/mod_bucketeer.c create mode 100644 trunk/modules/debug/mod_bucketeer.dsp create mode 100644 trunk/modules/debug/mod_dumpio.c create mode 100644 trunk/modules/debug/mod_dumpio.dsp create mode 100644 trunk/modules/echo/.indent.pro create mode 100644 trunk/modules/echo/Makefile.in create mode 100644 trunk/modules/echo/NWGNUmakefile create mode 100644 trunk/modules/echo/config.m4 create mode 100644 trunk/modules/echo/mod_echo.c create mode 100644 trunk/modules/echo/mod_echo.dsp create mode 100644 trunk/modules/experimental/.indent.pro create mode 100644 trunk/modules/experimental/Makefile.in create mode 100644 trunk/modules/experimental/NWGNUcharsetl create mode 100644 trunk/modules/experimental/NWGNUexample create mode 100644 trunk/modules/experimental/NWGNUmakefile create mode 100644 trunk/modules/experimental/NWGNUmod_filter create mode 100644 trunk/modules/experimental/README create mode 100644 trunk/modules/experimental/config.m4 create mode 100644 trunk/modules/experimental/mod_case_filter.c create mode 100644 trunk/modules/experimental/mod_case_filter_in.c create mode 100644 trunk/modules/experimental/mod_charset_lite.c create mode 100644 trunk/modules/experimental/mod_charset_lite.dsp create mode 100644 trunk/modules/experimental/mod_charset_lite.exp create mode 100644 trunk/modules/experimental/mod_dbd.c create mode 100644 trunk/modules/experimental/mod_dbd.h create mode 100644 trunk/modules/experimental/mod_example.c create mode 100644 trunk/modules/experimental/mod_filter.c create mode 100644 trunk/modules/filters/.indent.pro create mode 100644 trunk/modules/filters/Makefile.in create mode 100644 trunk/modules/filters/NWGNUdeflate create mode 100644 trunk/modules/filters/NWGNUextfiltr create mode 100644 trunk/modules/filters/NWGNUmakefile create mode 100644 trunk/modules/filters/config.m4 create mode 100644 trunk/modules/filters/mod_deflate.c create mode 100644 trunk/modules/filters/mod_deflate.dsp create mode 100644 trunk/modules/filters/mod_deflate.exp create mode 100644 trunk/modules/filters/mod_ext_filter.c create mode 100644 trunk/modules/filters/mod_ext_filter.dsp create mode 100644 trunk/modules/filters/mod_ext_filter.exp create mode 100644 trunk/modules/filters/mod_include.c create mode 100644 trunk/modules/filters/mod_include.dsp create mode 100644 trunk/modules/filters/mod_include.exp create mode 100644 trunk/modules/filters/mod_include.h create mode 100644 trunk/modules/generators/.indent.pro create mode 100644 trunk/modules/generators/Makefile.in create mode 100644 trunk/modules/generators/NWGNUautoindex create mode 100644 trunk/modules/generators/NWGNUinfo create mode 100644 trunk/modules/generators/NWGNUmakefile create mode 100644 trunk/modules/generators/NWGNUmod_asis create mode 100644 trunk/modules/generators/NWGNUmod_cgi create mode 100644 trunk/modules/generators/NWGNUstatus create mode 100644 trunk/modules/generators/config5.m4 create mode 100644 trunk/modules/generators/mod_asis.c create mode 100644 trunk/modules/generators/mod_asis.dsp create mode 100644 trunk/modules/generators/mod_asis.exp create mode 100644 trunk/modules/generators/mod_autoindex.c create mode 100644 trunk/modules/generators/mod_autoindex.dsp create mode 100644 trunk/modules/generators/mod_autoindex.exp create mode 100644 trunk/modules/generators/mod_cgi.c create mode 100644 trunk/modules/generators/mod_cgi.dsp create mode 100644 trunk/modules/generators/mod_cgi.exp create mode 100644 trunk/modules/generators/mod_cgi.h create mode 100644 trunk/modules/generators/mod_cgid.c create mode 100644 trunk/modules/generators/mod_cgid.exp create mode 100644 trunk/modules/generators/mod_info.c create mode 100644 trunk/modules/generators/mod_info.dsp create mode 100644 trunk/modules/generators/mod_info.exp create mode 100644 trunk/modules/generators/mod_status.c create mode 100644 trunk/modules/generators/mod_status.dsp create mode 100644 trunk/modules/generators/mod_status.exp create mode 100644 trunk/modules/generators/mod_status.h create mode 100644 trunk/modules/generators/mod_suexec.c create mode 100644 trunk/modules/generators/mod_suexec.h create mode 100644 trunk/modules/http/.indent.pro create mode 100644 trunk/modules/http/Makefile.in create mode 100644 trunk/modules/http/byterange_filter.c create mode 100644 trunk/modules/http/chunk_filter.c create mode 100644 trunk/modules/http/config2.m4 create mode 100644 trunk/modules/http/http_core.c create mode 100644 trunk/modules/http/http_etag.c create mode 100644 trunk/modules/http/http_filters.c create mode 100644 trunk/modules/http/http_protocol.c create mode 100644 trunk/modules/http/http_request.c create mode 100644 trunk/modules/http/mod_core.h create mode 100644 trunk/modules/http/mod_mime.c create mode 100644 trunk/modules/http/mod_mime.dsp create mode 100644 trunk/modules/http/mod_mime.exp create mode 100644 trunk/modules/ldap/Makefile.in create mode 100644 trunk/modules/ldap/NWGNUmakefile create mode 100644 trunk/modules/ldap/README.ldap create mode 100644 trunk/modules/ldap/config.m4 create mode 100644 trunk/modules/ldap/mod_ldap.dsp create mode 100644 trunk/modules/ldap/util_ldap.c create mode 100644 trunk/modules/ldap/util_ldap_cache.c create mode 100644 trunk/modules/ldap/util_ldap_cache.h create mode 100644 trunk/modules/ldap/util_ldap_cache_mgr.c create mode 100644 trunk/modules/loggers/.indent.pro create mode 100644 trunk/modules/loggers/Makefile.in create mode 100644 trunk/modules/loggers/NWGNUforensic create mode 100644 trunk/modules/loggers/NWGNUmakefile create mode 100644 trunk/modules/loggers/NWGNUmodlogio create mode 100644 trunk/modules/loggers/config.m4 create mode 100644 trunk/modules/loggers/mod_log_config.c create mode 100644 trunk/modules/loggers/mod_log_config.dsp create mode 100644 trunk/modules/loggers/mod_log_config.exp create mode 100644 trunk/modules/loggers/mod_log_config.h create mode 100644 trunk/modules/loggers/mod_log_forensic.c create mode 100644 trunk/modules/loggers/mod_log_forensic.dsp create mode 100644 trunk/modules/loggers/mod_log_forensic.exp create mode 100644 trunk/modules/loggers/mod_logio.c create mode 100644 trunk/modules/loggers/mod_logio.dsp create mode 100644 trunk/modules/mappers/.indent.pro create mode 100644 trunk/modules/mappers/Makefile.in create mode 100644 trunk/modules/mappers/NWGNUactions create mode 100644 trunk/modules/mappers/NWGNUimagemap create mode 100644 trunk/modules/mappers/NWGNUmakefile create mode 100644 trunk/modules/mappers/NWGNUrewrite create mode 100644 trunk/modules/mappers/NWGNUspeling create mode 100644 trunk/modules/mappers/NWGNUuserdir create mode 100644 trunk/modules/mappers/NWGNUvhost create mode 100644 trunk/modules/mappers/config9.m4 create mode 100644 trunk/modules/mappers/mod_actions.c create mode 100644 trunk/modules/mappers/mod_actions.dsp create mode 100644 trunk/modules/mappers/mod_actions.exp create mode 100644 trunk/modules/mappers/mod_alias.c create mode 100644 trunk/modules/mappers/mod_alias.dsp create mode 100644 trunk/modules/mappers/mod_alias.exp create mode 100644 trunk/modules/mappers/mod_dir.c create mode 100644 trunk/modules/mappers/mod_dir.dsp create mode 100644 trunk/modules/mappers/mod_dir.exp create mode 100644 trunk/modules/mappers/mod_imagemap.c create mode 100644 trunk/modules/mappers/mod_imagemap.dsp create mode 100644 trunk/modules/mappers/mod_imagemap.exp create mode 100644 trunk/modules/mappers/mod_negotiation.c create mode 100644 trunk/modules/mappers/mod_negotiation.dsp create mode 100644 trunk/modules/mappers/mod_negotiation.exp create mode 100644 trunk/modules/mappers/mod_rewrite.c create mode 100644 trunk/modules/mappers/mod_rewrite.dsp create mode 100644 trunk/modules/mappers/mod_rewrite.exp create mode 100644 trunk/modules/mappers/mod_rewrite.h create mode 100644 trunk/modules/mappers/mod_so.c create mode 100644 trunk/modules/mappers/mod_so.h create mode 100644 trunk/modules/mappers/mod_speling.c create mode 100644 trunk/modules/mappers/mod_speling.dsp create mode 100644 trunk/modules/mappers/mod_speling.exp create mode 100644 trunk/modules/mappers/mod_userdir.c create mode 100644 trunk/modules/mappers/mod_userdir.dsp create mode 100644 trunk/modules/mappers/mod_userdir.exp create mode 100644 trunk/modules/mappers/mod_vhost_alias.c create mode 100644 trunk/modules/mappers/mod_vhost_alias.dsp create mode 100644 trunk/modules/mappers/mod_vhost_alias.exp create mode 100644 trunk/modules/metadata/.indent.pro create mode 100644 trunk/modules/metadata/Makefile.in create mode 100644 trunk/modules/metadata/NWGNUcernmeta create mode 100644 trunk/modules/metadata/NWGNUexpires create mode 100644 trunk/modules/metadata/NWGNUheaders create mode 100644 trunk/modules/metadata/NWGNUmakefile create mode 100644 trunk/modules/metadata/NWGNUmimemagi create mode 100644 trunk/modules/metadata/NWGNUmodident create mode 100644 trunk/modules/metadata/NWGNUmodversion create mode 100644 trunk/modules/metadata/NWGNUuniqueid create mode 100644 trunk/modules/metadata/NWGNUusertrk create mode 100644 trunk/modules/metadata/config.m4 create mode 100644 trunk/modules/metadata/mod_cern_meta.c create mode 100644 trunk/modules/metadata/mod_cern_meta.dsp create mode 100644 trunk/modules/metadata/mod_cern_meta.exp create mode 100644 trunk/modules/metadata/mod_env.c create mode 100644 trunk/modules/metadata/mod_env.dsp create mode 100644 trunk/modules/metadata/mod_env.exp create mode 100644 trunk/modules/metadata/mod_expires.c create mode 100644 trunk/modules/metadata/mod_expires.dsp create mode 100644 trunk/modules/metadata/mod_expires.exp create mode 100644 trunk/modules/metadata/mod_headers.c create mode 100644 trunk/modules/metadata/mod_headers.dsp create mode 100644 trunk/modules/metadata/mod_headers.exp create mode 100644 trunk/modules/metadata/mod_ident.c create mode 100644 trunk/modules/metadata/mod_ident.dsp create mode 100644 trunk/modules/metadata/mod_ident.exp create mode 100644 trunk/modules/metadata/mod_mime_magic.c create mode 100644 trunk/modules/metadata/mod_mime_magic.dsp create mode 100644 trunk/modules/metadata/mod_mime_magic.exp create mode 100644 trunk/modules/metadata/mod_setenvif.c create mode 100644 trunk/modules/metadata/mod_setenvif.dsp create mode 100644 trunk/modules/metadata/mod_setenvif.exp create mode 100644 trunk/modules/metadata/mod_unique_id.c create mode 100644 trunk/modules/metadata/mod_unique_id.dsp create mode 100644 trunk/modules/metadata/mod_unique_id.exp create mode 100644 trunk/modules/metadata/mod_usertrack.c create mode 100644 trunk/modules/metadata/mod_usertrack.dsp create mode 100644 trunk/modules/metadata/mod_usertrack.exp create mode 100644 trunk/modules/metadata/mod_version.c create mode 100644 trunk/modules/metadata/mod_version.dsp create mode 100644 trunk/modules/metadata/mod_version.exp create mode 100644 trunk/modules/proxy/.indent.pro create mode 100644 trunk/modules/proxy/CHANGES create mode 100644 trunk/modules/proxy/Makefile.in create mode 100644 trunk/modules/proxy/NWGNUmakefile create mode 100644 trunk/modules/proxy/NWGNUproxy create mode 100644 trunk/modules/proxy/NWGNUproxyajp create mode 100644 trunk/modules/proxy/NWGNUproxybalancer create mode 100644 trunk/modules/proxy/NWGNUproxycon create mode 100644 trunk/modules/proxy/NWGNUproxyftp create mode 100644 trunk/modules/proxy/NWGNUproxyhtp create mode 100644 trunk/modules/proxy/ajp.h create mode 100644 trunk/modules/proxy/ajp_header.c create mode 100644 trunk/modules/proxy/ajp_header.h create mode 100644 trunk/modules/proxy/ajp_link.c create mode 100644 trunk/modules/proxy/ajp_msg.c create mode 100644 trunk/modules/proxy/config.m4 create mode 100644 trunk/modules/proxy/libproxy.exp create mode 100644 trunk/modules/proxy/mod_proxy.c create mode 100644 trunk/modules/proxy/mod_proxy.dsp create mode 100644 trunk/modules/proxy/mod_proxy.h create mode 100644 trunk/modules/proxy/mod_proxy_ajp.c create mode 100644 trunk/modules/proxy/mod_proxy_ajp.dsp create mode 100644 trunk/modules/proxy/mod_proxy_balancer.c create mode 100644 trunk/modules/proxy/mod_proxy_balancer.dsp create mode 100644 trunk/modules/proxy/mod_proxy_connect.c create mode 100644 trunk/modules/proxy/mod_proxy_connect.dsp create mode 100644 trunk/modules/proxy/mod_proxy_ftp.c create mode 100644 trunk/modules/proxy/mod_proxy_ftp.dsp create mode 100644 trunk/modules/proxy/mod_proxy_http.c create mode 100644 trunk/modules/proxy/mod_proxy_http.dsp create mode 100644 trunk/modules/proxy/proxy_util.c create mode 100644 trunk/modules/ssl/Makefile.in create mode 100644 trunk/modules/ssl/NWGNUmakefile create mode 100644 trunk/modules/ssl/README create mode 100644 trunk/modules/ssl/README.dsov.fig create mode 100644 trunk/modules/ssl/README.dsov.ps create mode 100644 trunk/modules/ssl/config.m4 create mode 100644 trunk/modules/ssl/mod_ssl.c create mode 100644 trunk/modules/ssl/mod_ssl.dsp create mode 100644 trunk/modules/ssl/mod_ssl.h create mode 100644 trunk/modules/ssl/ssl_engine_config.c create mode 100644 trunk/modules/ssl/ssl_engine_dh.c create mode 100644 trunk/modules/ssl/ssl_engine_init.c create mode 100644 trunk/modules/ssl/ssl_engine_io.c create mode 100644 trunk/modules/ssl/ssl_engine_kernel.c create mode 100644 trunk/modules/ssl/ssl_engine_log.c create mode 100644 trunk/modules/ssl/ssl_engine_mutex.c create mode 100644 trunk/modules/ssl/ssl_engine_pphrase.c create mode 100644 trunk/modules/ssl/ssl_engine_rand.c create mode 100644 trunk/modules/ssl/ssl_engine_vars.c create mode 100644 trunk/modules/ssl/ssl_expr.c create mode 100644 trunk/modules/ssl/ssl_expr.h create mode 100644 trunk/modules/ssl/ssl_expr_eval.c create mode 100644 trunk/modules/ssl/ssl_expr_parse.c create mode 100644 trunk/modules/ssl/ssl_expr_parse.h create mode 100644 trunk/modules/ssl/ssl_expr_parse.y create mode 100644 trunk/modules/ssl/ssl_expr_scan.c create mode 100644 trunk/modules/ssl/ssl_expr_scan.l create mode 100644 trunk/modules/ssl/ssl_private.h create mode 100644 trunk/modules/ssl/ssl_scache.c create mode 100644 trunk/modules/ssl/ssl_scache_dbm.c create mode 100644 trunk/modules/ssl/ssl_scache_dc.c create mode 100644 trunk/modules/ssl/ssl_scache_shmcb.c create mode 100644 trunk/modules/ssl/ssl_toolkit_compat.h create mode 100644 trunk/modules/ssl/ssl_util.c create mode 100644 trunk/modules/ssl/ssl_util_ssl.c create mode 100644 trunk/modules/ssl/ssl_util_ssl.h create mode 100644 trunk/modules/test/.indent.pro create mode 100644 trunk/modules/test/Makefile.in create mode 100644 trunk/modules/test/README create mode 100644 trunk/modules/test/config.m4 create mode 100644 trunk/modules/test/mod_optional_fn_export.c create mode 100644 trunk/modules/test/mod_optional_fn_export.h create mode 100644 trunk/modules/test/mod_optional_fn_import.c create mode 100644 trunk/modules/test/mod_optional_hook_export.c create mode 100644 trunk/modules/test/mod_optional_hook_export.h create mode 100644 trunk/modules/test/mod_optional_hook_import.c create mode 100644 trunk/os/.indent.pro create mode 100644 trunk/os/Makefile.in create mode 100644 trunk/os/beos/Makefile.in create mode 100644 trunk/os/beos/beosd.c create mode 100644 trunk/os/beos/beosd.h create mode 100644 trunk/os/beos/config.m4 create mode 100644 trunk/os/beos/os.c create mode 100644 trunk/os/beos/os.h create mode 100644 trunk/os/bs2000/ebcdic.c create mode 100644 trunk/os/bs2000/ebcdic.h create mode 100644 trunk/os/bs2000/os.c create mode 100644 trunk/os/bs2000/os.h create mode 100644 trunk/os/config.m4 create mode 100644 trunk/os/netware/Apache.def create mode 100644 trunk/os/netware/apache.xdc create mode 100644 trunk/os/netware/modules.c create mode 100644 trunk/os/netware/os.h create mode 100644 trunk/os/netware/pre_nw.h create mode 100644 trunk/os/netware/util_nw.c create mode 100644 trunk/os/os2/Makefile.in create mode 100644 trunk/os/os2/config.m4 create mode 100644 trunk/os/os2/core.mk create mode 100644 trunk/os/os2/core_header.def create mode 100644 trunk/os/os2/os.h create mode 100644 trunk/os/os2/util_os2.c create mode 100644 trunk/os/tpf/TPFExport create mode 100644 trunk/os/tpf/ebcdic.c create mode 100644 trunk/os/tpf/ebcdic.h create mode 100644 trunk/os/tpf/os.c create mode 100644 trunk/os/tpf/os.h create mode 100644 trunk/os/tpf/samples/linkdll.jcl create mode 100644 trunk/os/tpf/samples/loadset.jcl create mode 100644 trunk/os/unix/Makefile.in create mode 100644 trunk/os/unix/config.m4 create mode 100644 trunk/os/unix/os.h create mode 100644 trunk/os/unix/unixd.c create mode 100644 trunk/os/unix/unixd.h create mode 100644 trunk/os/win32/BaseAddr.ref create mode 100644 trunk/os/win32/ap_regkey.c create mode 100644 trunk/os/win32/modules.c create mode 100644 trunk/os/win32/os.h create mode 100644 trunk/os/win32/util_win32.c create mode 100644 trunk/server/.indent.pro create mode 100644 trunk/server/Makefile.in create mode 100644 trunk/server/NWGNUmakefile create mode 100644 trunk/server/buildmark.c create mode 100644 trunk/server/config.c create mode 100644 trunk/server/config.m4 create mode 100644 trunk/server/connection.c create mode 100644 trunk/server/core.c create mode 100644 trunk/server/core_filters.c create mode 100644 trunk/server/eoc_bucket.c create mode 100644 trunk/server/error_bucket.c create mode 100644 trunk/server/gen_test_char.c create mode 100644 trunk/server/gen_test_char.dsp create mode 100644 trunk/server/listen.c create mode 100644 trunk/server/log.c create mode 100644 trunk/server/main.c create mode 100644 trunk/server/mpm/MPM.NAMING create mode 100644 trunk/server/mpm/Makefile.in create mode 100644 trunk/server/mpm/beos/Makefile.in create mode 100644 trunk/server/mpm/beos/beos.c create mode 100644 trunk/server/mpm/beos/beos.h create mode 100644 trunk/server/mpm/beos/config5.m4 create mode 100644 trunk/server/mpm/beos/mpm.h create mode 100644 trunk/server/mpm/beos/mpm_default.h create mode 100644 trunk/server/mpm/config.m4 create mode 100644 trunk/server/mpm/experimental/event/Makefile.in create mode 100644 trunk/server/mpm/experimental/event/config5.m4 create mode 100644 trunk/server/mpm/experimental/event/event.c create mode 100644 trunk/server/mpm/experimental/event/fdqueue.c create mode 100644 trunk/server/mpm/experimental/event/fdqueue.h create mode 100644 trunk/server/mpm/experimental/event/mpm.h create mode 100644 trunk/server/mpm/experimental/event/mpm_default.h create mode 100644 trunk/server/mpm/experimental/event/pod.c create mode 100644 trunk/server/mpm/experimental/event/pod.h create mode 100644 trunk/server/mpm/experimental/leader/Makefile.in create mode 100644 trunk/server/mpm/experimental/leader/README create mode 100644 trunk/server/mpm/experimental/leader/config5.m4 create mode 100644 trunk/server/mpm/experimental/leader/leader.c create mode 100644 trunk/server/mpm/experimental/leader/mpm.h create mode 100644 trunk/server/mpm/experimental/leader/mpm_default.h create mode 100644 trunk/server/mpm/experimental/perchild/Makefile.in create mode 100644 trunk/server/mpm/experimental/perchild/config5.m4 create mode 100644 trunk/server/mpm/experimental/perchild/mpm.h create mode 100644 trunk/server/mpm/experimental/perchild/mpm_default.h create mode 100644 trunk/server/mpm/experimental/perchild/perchild.c create mode 100644 trunk/server/mpm/experimental/threadpool/Makefile.in create mode 100644 trunk/server/mpm/experimental/threadpool/README create mode 100644 trunk/server/mpm/experimental/threadpool/config5.m4 create mode 100644 trunk/server/mpm/experimental/threadpool/mpm.h create mode 100644 trunk/server/mpm/experimental/threadpool/mpm_default.h create mode 100644 trunk/server/mpm/experimental/threadpool/pod.c create mode 100644 trunk/server/mpm/experimental/threadpool/pod.h create mode 100644 trunk/server/mpm/experimental/threadpool/threadpool.c create mode 100644 trunk/server/mpm/mpmt_os2/Makefile.in create mode 100644 trunk/server/mpm/mpmt_os2/config5.m4 create mode 100644 trunk/server/mpm/mpmt_os2/mpm.h create mode 100644 trunk/server/mpm/mpmt_os2/mpm_default.h create mode 100644 trunk/server/mpm/mpmt_os2/mpmt_os2.c create mode 100644 trunk/server/mpm/mpmt_os2/mpmt_os2_child.c create mode 100644 trunk/server/mpm/netware/mpm.h create mode 100644 trunk/server/mpm/netware/mpm_default.h create mode 100644 trunk/server/mpm/netware/mpm_netware.c create mode 100644 trunk/server/mpm/prefork/Makefile.in create mode 100644 trunk/server/mpm/prefork/config.m4 create mode 100644 trunk/server/mpm/prefork/mpm.h create mode 100644 trunk/server/mpm/prefork/mpm_default.h create mode 100644 trunk/server/mpm/prefork/prefork.c create mode 100644 trunk/server/mpm/winnt/Win9xConHook.c create mode 100644 trunk/server/mpm/winnt/Win9xConHook.def create mode 100644 trunk/server/mpm/winnt/Win9xConHook.dsp create mode 100644 trunk/server/mpm/winnt/Win9xConHook.h create mode 100644 trunk/server/mpm/winnt/child.c create mode 100644 trunk/server/mpm/winnt/mpm.h create mode 100644 trunk/server/mpm/winnt/mpm_default.h create mode 100644 trunk/server/mpm/winnt/mpm_winnt.c create mode 100644 trunk/server/mpm/winnt/mpm_winnt.h create mode 100644 trunk/server/mpm/winnt/nt_eventlog.c create mode 100644 trunk/server/mpm/winnt/service.c create mode 100644 trunk/server/mpm/worker/Makefile.in create mode 100644 trunk/server/mpm/worker/config5.m4 create mode 100644 trunk/server/mpm/worker/fdqueue.c create mode 100644 trunk/server/mpm/worker/fdqueue.h create mode 100644 trunk/server/mpm/worker/mpm.h create mode 100644 trunk/server/mpm/worker/mpm_default.h create mode 100644 trunk/server/mpm/worker/pod.c create mode 100644 trunk/server/mpm/worker/pod.h create mode 100644 trunk/server/mpm/worker/worker.c create mode 100644 trunk/server/mpm_common.c create mode 100644 trunk/server/protocol.c create mode 100644 trunk/server/provider.c create mode 100644 trunk/server/request.c create mode 100644 trunk/server/scoreboard.c create mode 100644 trunk/server/util.c create mode 100644 trunk/server/util_cfgtree.c create mode 100644 trunk/server/util_charset.c create mode 100644 trunk/server/util_debug.c create mode 100644 trunk/server/util_ebcdic.c create mode 100644 trunk/server/util_filter.c create mode 100644 trunk/server/util_md5.c create mode 100644 trunk/server/util_pcre.c create mode 100644 trunk/server/util_script.c create mode 100644 trunk/server/util_time.c create mode 100644 trunk/server/util_xml.c create mode 100644 trunk/server/vhost.c create mode 100644 trunk/srclib/Makefile.in create mode 100644 trunk/srclib/pcre/AUTHORS create mode 100644 trunk/srclib/pcre/COPYING create mode 100644 trunk/srclib/pcre/ChangeLog create mode 100644 trunk/srclib/pcre/INSTALL create mode 100644 trunk/srclib/pcre/LICENCE create mode 100644 trunk/srclib/pcre/Makefile.in create mode 100644 trunk/srclib/pcre/NEWS create mode 100644 trunk/srclib/pcre/NON-UNIX-USE create mode 100644 trunk/srclib/pcre/NWGNUmakefile create mode 100644 trunk/srclib/pcre/README create mode 100755 trunk/srclib/pcre/RunTest.in create mode 100644 trunk/srclib/pcre/config.hw create mode 100644 trunk/srclib/pcre/config.in create mode 100644 trunk/srclib/pcre/configure.in create mode 100644 trunk/srclib/pcre/dftables.c create mode 100644 trunk/srclib/pcre/dftables.dsp create mode 100644 trunk/srclib/pcre/dll.mk create mode 100644 trunk/srclib/pcre/doc/README_httpd create mode 100644 trunk/srclib/pcre/get.c create mode 100755 trunk/srclib/pcre/install-sh create mode 100644 trunk/srclib/pcre/internal.h create mode 100644 trunk/srclib/pcre/libpcre.def create mode 100644 trunk/srclib/pcre/libpcre.pc.in create mode 100644 trunk/srclib/pcre/libpcreposix.def create mode 100644 trunk/srclib/pcre/maketables.c create mode 100644 trunk/srclib/pcre/makevp.bat create mode 100755 trunk/srclib/pcre/mkinstalldirs create mode 100644 trunk/srclib/pcre/pcre-config.in create mode 100644 trunk/srclib/pcre/pcre.c create mode 100644 trunk/srclib/pcre/pcre.def create mode 100644 trunk/srclib/pcre/pcre.dsp create mode 100644 trunk/srclib/pcre/pcre.hw create mode 100644 trunk/srclib/pcre/pcre.in create mode 100644 trunk/srclib/pcre/pcredemo.c create mode 100644 trunk/srclib/pcre/pcregrep.c create mode 100644 trunk/srclib/pcre/pcreposix.c create mode 100644 trunk/srclib/pcre/pcreposix.dsp create mode 100644 trunk/srclib/pcre/pcretest.c create mode 100755 trunk/srclib/pcre/perltest create mode 100755 trunk/srclib/pcre/perltest8 create mode 100644 trunk/srclib/pcre/pgrep.c create mode 100644 trunk/srclib/pcre/printint.c create mode 100644 trunk/srclib/pcre/study.c create mode 100644 trunk/srclib/pcre/testdata/testinput1 create mode 100644 trunk/srclib/pcre/testdata/testinput2 create mode 100644 trunk/srclib/pcre/testdata/testinput3 create mode 100644 trunk/srclib/pcre/testdata/testinput4 create mode 100644 trunk/srclib/pcre/testdata/testinput5 create mode 100644 trunk/srclib/pcre/testdata/testinput6 create mode 100644 trunk/srclib/pcre/testdata/testoutput1 create mode 100644 trunk/srclib/pcre/testdata/testoutput2 create mode 100644 trunk/srclib/pcre/testdata/testoutput3 create mode 100644 trunk/srclib/pcre/testdata/testoutput4 create mode 100644 trunk/srclib/pcre/testdata/testoutput5 create mode 100644 trunk/srclib/pcre/testdata/testoutput6 create mode 100644 trunk/srclib/pcre/ucp.c create mode 100644 trunk/srclib/pcre/ucp.h create mode 100644 trunk/srclib/pcre/ucpinternal.h create mode 100644 trunk/srclib/pcre/ucptable.c create mode 100644 trunk/srclib/pcre/ucptypetable.c create mode 100644 trunk/support/.indent.pro create mode 100644 trunk/support/Makefile.in create mode 100644 trunk/support/NWGNUab create mode 100644 trunk/support/NWGNUhtcacheclean create mode 100644 trunk/support/NWGNUhtdbm create mode 100644 trunk/support/NWGNUhtdigest create mode 100644 trunk/support/NWGNUhtpasswd create mode 100644 trunk/support/NWGNUlogres create mode 100644 trunk/support/NWGNUmakefile create mode 100644 trunk/support/NWGNUrotlogs create mode 100644 trunk/support/README create mode 100644 trunk/support/SHA1/README.sha1 create mode 100644 trunk/support/SHA1/convert-sha1.pl create mode 100644 trunk/support/SHA1/htpasswd-sha1.pl create mode 100644 trunk/support/SHA1/ldif-sha1.example create mode 100644 trunk/support/ab.c create mode 100644 trunk/support/ab.dsp create mode 100644 trunk/support/abs.dsp create mode 100644 trunk/support/apachectl.in create mode 100644 trunk/support/apxs.in create mode 100755 trunk/support/check_forensic create mode 100644 trunk/support/checkgid.c create mode 100644 trunk/support/config.m4 create mode 100644 trunk/support/dbmmanage.in create mode 100644 trunk/support/envvars-std.in create mode 100644 trunk/support/htcacheclean.c create mode 100644 trunk/support/htdbm.c create mode 100644 trunk/support/htdbm.dsp create mode 100644 trunk/support/htdigest.c create mode 100644 trunk/support/htdigest.dsp create mode 100644 trunk/support/htpasswd.c create mode 100644 trunk/support/htpasswd.dsp create mode 100755 trunk/support/list_hooks.pl create mode 100644 trunk/support/log_server_status.in create mode 100644 trunk/support/logresolve.c create mode 100644 trunk/support/logresolve.dsp create mode 100644 trunk/support/logresolve.pl.in create mode 100644 trunk/support/phf_abuse_log.cgi.in create mode 100644 trunk/support/rotatelogs.c create mode 100644 trunk/support/rotatelogs.dsp create mode 100644 trunk/support/split-logfile.in create mode 100644 trunk/support/suexec.c create mode 100644 trunk/support/suexec.h create mode 100644 trunk/support/utilitiesnw.def create mode 100644 trunk/support/win32/ApacheMonitor.c create mode 100644 trunk/support/win32/ApacheMonitor.dsp create mode 100644 trunk/support/win32/ApacheMonitor.h create mode 100644 trunk/support/win32/ApacheMonitor.ico create mode 100644 trunk/support/win32/ApacheMonitor.rc create mode 100644 trunk/support/win32/apache_header.bmp create mode 100644 trunk/support/win32/aprun.ico create mode 100644 trunk/support/win32/apstop.ico create mode 100644 trunk/support/win32/srun.bmp create mode 100644 trunk/support/win32/sstop.bmp create mode 100644 trunk/support/win32/wintty.c create mode 100644 trunk/support/win32/wintty.dsp create mode 100644 trunk/test/.indent.pro create mode 100644 trunk/test/Makefile.in create mode 100644 trunk/test/README create mode 100644 trunk/test/check_chunked create mode 100644 trunk/test/cls.c create mode 100644 trunk/test/tcpdumpscii.txt create mode 100644 trunk/test/test-writev.c create mode 100644 trunk/test/test_find.c create mode 100644 trunk/test/test_limits.c create mode 100644 trunk/test/test_parser.c create mode 100644 trunk/test/test_select.c create mode 100644 trunk/test/time-sem.c create mode 100644 trunk/test/zb.c diff --git a/trunk/.gdbinit b/trunk/.gdbinit new file mode 100644 index 0000000000..672b392c86 --- /dev/null +++ b/trunk/.gdbinit @@ -0,0 +1,277 @@ +# gdb macros which may be useful for folks using gdb to debug +# apache. Delete it if it bothers you. + +define dump_table + set $t = (apr_table_entry_t *)((apr_array_header_t *)$arg0)->elts + set $n = ((apr_array_header_t *)$arg0)->nelts + set $i = 0 + while $i < $n + if $t[$i].val == (void *)0L + printf "[%u] '%s'=>NULL\n", $i, $t[$i].key + else + printf "[%u] '%s'='%s'\n", $i, $t[$i].key, $t[$i].val + end + set $i = $i + 1 + end +end +document dump_table + Print the key/value pairs in a table. +end + + +define rh + run -f /home/dgaudet/ap2/conf/mpm.conf +end + +define ro + run -DONE_PROCESS +end + +define dump_string_array + set $a = (char **)((apr_array_header_t *)$arg0)->elts + set $n = (int)((apr_array_header_t *)$arg0)->nelts + set $i = 0 + while $i < $n + printf "[%u] '%s'\n", $i, $a[$i] + set $i = $i + 1 + end +end +document dump_string_array + Print all of the elements in an array of strings. +end + +define printmemn + set $i = 0 + while $i < $arg1 + if $arg0[$i] < 0x20 || $arg0[$i] > 0x7e + printf "~" + else + printf "%c", $arg0[$i] + end + set $i = $i + 1 + end +end + +define print_bkt_datacol + # arg0 == column name + # arg1 == format + # arg2 == value + # arg3 == suppress header? + set $suppressheader = $arg3 + + if !$suppressheader + printf " " + printf $arg0 + printf "=" + else + printf " | " + end + printf $arg1, $arg2 +end + +define dump_bucket_ex + # arg0 == bucket + # arg1 == suppress header? + set $bucket = (struct apr_bucket *)$arg0 + set $sh = $arg1 + set $refcount = -1 + + print_bkt_datacol "bucket" "%-9s" $bucket->type->name $sh + printf "(0x%08lx)", (unsigned long)$bucket + print_bkt_datacol "length" "%-6ld" (long)($bucket->length) $sh + print_bkt_datacol "data" "0x%08lx" $bucket->data $sh + + if !$sh + printf "\n " + end + + if (($bucket->type == &apr_bucket_type_eos) || \ + ($bucket->type == &apr_bucket_type_flush)) + + # metadata buckets, no content + print_bkt_datacol "contents" "%c" ' ' $sh + printf " " + print_bkt_datacol "rc" "n/%c" 'a' $sh + + else + if ($bucket->type == &ap_bucket_type_error) + + # metadata bucket, no content but it does have an error code in it + print_bkt_datacol "contents" "%c" ' ' $sh + set $status = ((ap_bucket_error *)$bucket->data)->status + printf " (status=%3d) ", $status + print_bkt_datacol "rc" "n/%c" 'a' $sh + + else + if (($bucket->type == &apr_bucket_type_file) || \ + ($bucket->type == &apr_bucket_type_pipe) || \ + ($bucket->type == &apr_bucket_type_socket)) + + # buckets that contain data not in memory (ie not printable) + + print_bkt_datacol "contents" "[**unprintable**%c" ']' $sh + printf " " + if $bucket->type == &apr_bucket_type_file + set $refcount = ((apr_bucket_refcount *)$bucket->data)->refcount + print_bkt_datacol "rc" "%d" $refcount $sh + end + + else + if (($bucket->type == &apr_bucket_type_heap) || \ + ($bucket->type == &apr_bucket_type_pool) || \ + ($bucket->type == &apr_bucket_type_mmap) || \ + ($bucket->type == &apr_bucket_type_transient) || \ + ($bucket->type == &apr_bucket_type_immortal)) + + # in-memory buckets + + if $bucket->type == &apr_bucket_type_heap + set $refcount = ((apr_bucket_refcount *)$bucket->data)->refcount + set $p = (apr_bucket_heap *)$bucket->data + set $data = $p->base+$bucket->start + + else + if $bucket->type == &apr_bucket_type_pool + set $refcount = ((apr_bucket_refcount *)$bucket->data)->refcount + set $p = (apr_bucket_pool *)$bucket->data + if !$p->pool + set $p = (apr_bucket_heap *)$bucket->data + end + set $data = $p->base+$bucket->start + + else + if $bucket->type == &apr_bucket_type_mmap + # is this safe if not APR_HAS_MMAP? + set $refcount = ((apr_bucket_refcount *)$bucket->data)->refcount + set $p = (apr_bucket_mmap *)$bucket->data + set $data = ((char *)$p->mmap->mm)+$bucket->start + + else + if (($bucket->type == &apr_bucket_type_transient) || \ + ($bucket->type == &apr_bucket_type_immortal)) + set $data = ((char *)$bucket->data)+$bucket->start + + end + end + end + end + + if $sh + printf " | [" + else + printf " contents=[" + end + set $datalen = $bucket->length + if $datalen > 17 + printmem $data 17 + printf "..." + set $datalen = 20 + else + printmemn $data $datalen + end + printf "]" + while $datalen < 20 + printf " " + set $datalen = $datalen + 1 + end + + if $refcount != -1 + print_bkt_datacol "rc" "%d" $refcount $sh + else + print_bkt_datacol "rc" "n/%c" 'a' $sh + end + + else + # 3rd-party bucket type + print_bkt_datacol "contents" "[**unknown**%c" ']' $sh + printf " " + print_bkt_datacol "rc" "n/%c" 'a' $sh + end + end + end + end + + printf "\n" + +end + +define dump_bucket + dump_bucket_ex $arg0 0 +end +document dump_bucket + Print bucket info +end + +define dump_brigade + set $bb = (apr_bucket_brigade *)$arg0 + set $bucket = $bb->list.next + set $sentinel = ((char *)((&($bb->list)) \ + - ((size_t) &((struct apr_bucket *)0)->link))) + printf "dump of brigade 0x%lx\n", (unsigned long)$bb + + printf " | type (address) | length | " + printf "data addr | contents | rc\n" + printf "----------------------------------------" + printf "----------------------------------------\n" + + if $bucket == $sentinel + printf "brigade is empty\n" + end + + set $j = 0 + while $bucket != $sentinel + printf "%2d", $j + dump_bucket_ex $bucket 1 + set $j = $j + 1 + set $bucket = $bucket->link.next + end + printf "end of brigade\n" +end +document dump_brigade + Print bucket brigade info +end + +define dump_filters + set $f = $arg0 + while $f + printf "%s(0x%lx): ctx=0x%lx, r=0x%lx, c=0x%lx\n", \ + $f->frec->name, (unsigned long)$f, (unsigned long)$f->ctx, \ + $f->r, $f->c + set $f = $f->next + end +end +document dump_filters + Print filter chain info +end + +define dump_process_rec + set $p = $arg0 + printf "process_rec=0x%lx:\n", (unsigned long)$p + printf " pool=0x%lx, pconf=0x%lx\n", \ + (unsigned long)$p->pool, (unsigned long)$p->pconf +end +document dump_process_rec + Print process_rec info +end + +define dump_server_rec + set $s = $arg0 + printf "name=%s:%d\n", \ + $s->server_hostname, $s->port + dump_process_rec($s->process) +end +document dump_server_rec + Print server_rec info +end + +define dump_servers + set $s = $arg0 + while $s + dump_server_rec($s) + printf "\n" + set $s = $s->next + end +end +document dump_servers + Print server_rec list info +end diff --git a/trunk/ABOUT_APACHE b/trunk/ABOUT_APACHE new file mode 100644 index 0000000000..f1a193cb3b --- /dev/null +++ b/trunk/ABOUT_APACHE @@ -0,0 +1,277 @@ + + The Apache HTTP Server Project + + http://httpd.apache.org/ + + February 2002 + +The Apache Project is a collaborative software development effort aimed +at creating a robust, commercial-grade, featureful, and freely-available +source code implementation of an HTTP (Web) server. The project is +jointly managed by a group of volunteers located around the world, using +the Internet and the Web to communicate, plan, and develop the server and +its related documentation. These volunteers are known as the Apache Group. +In addition, hundreds of users have contributed ideas, code, and +documentation to the project. This file is intended to briefly describe +the history of the Apache Group, recognize the many contributors, and +explain how you can join the fun too. + +In February of 1995, the most popular server software on the Web was the +public domain HTTP daemon developed by Rob McCool at the National Center +for Supercomputing Applications, University of Illinois, Urbana-Champaign. +However, development of that httpd had stalled after Rob left NCSA in +mid-1994, and many webmasters had developed their own extensions and bug +fixes that were in need of a common distribution. A small group of these +webmasters, contacted via private e-mail, gathered together for the purpose +of coordinating their changes (in the form of "patches"). Brian Behlendorf +and Cliff Skolnick put together a mailing list, shared information space, +and logins for the core developers on a machine in the California Bay Area, +with bandwidth and diskspace donated by HotWired and Organic Online. +By the end of February, eight core contributors formed the foundation +of the original Apache Group: + + Brian Behlendorf Roy T. Fielding Rob Hartill + David Robinson Cliff Skolnick Randy Terbush + Robert S. Thau Andrew Wilson + +with additional contributions from + + Eric Hagberg Frank Peters Nicolas Pioch + +Using NCSA httpd 1.3 as a base, we added all of the published bug fixes +and worthwhile enhancements we could find, tested the result on our own +servers, and made the first official public release (0.6.2) of the Apache +server in April 1995. By coincidence, NCSA restarted their own development +during the same period, and Brandon Long and Beth Frank of the NCSA Server +Development Team joined the list in March as honorary members so that the +two projects could share ideas and fixes. + +The early Apache server was a big hit, but we all knew that the codebase +needed a general overhaul and redesign. During May-June 1995, while +Rob Hartill and the rest of the group focused on implementing new features +for 0.7.x (like pre-forked child processes) and supporting the rapidly growing +Apache user community, Robert Thau designed a new server architecture +(code-named Shambhala) which included a modular structure and API for better +extensibility, pool-based memory allocation, and an adaptive pre-forking +process model. The group switched to this new server base in July and added +the features from 0.7.x, resulting in Apache 0.8.8 (and its brethren) +in August. + +After extensive beta testing, many ports to obscure platforms, a new set +of documentation (by David Robinson), and the addition of many features +in the form of our standard modules, Apache 1.0 was released on +December 1, 1995. + +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 2 April 2002: + + Greg Ames IBM Corporation, Research Triangle Park, NC, USA + Aaron Bannert California + Brian Behlendorf Collab.Net, California + Ken Coar IBM Corporation, Research Triangle Park, NC, USA + Mark J. Cox Red Hat, UK + Lars Eilebrecht Freelance Consultant, Munich, Germany + Ralf S. Engelschall Cable & Wireless Deutschland, Munich, Germany + Justin Erenkrantz University of California, Irvine + Roy T. Fielding Day Software, California + Tony Finch Covalent Technologies, California + Dean Gaudet Transmeta Corporation, California + Dirk-Willem van Gulik Covalent Technologies, California + Brian Havard Australia + Ian Holsman CNET, California + Ben Hyde Gensym, Massachusetts + Jim Jagielski jaguNET Access Services, Maryland + Manoj Kasichainula Collab.Net, California + Alexei Kosut Stanford University, California + Martin Kraemer Munich, Germany + Ben Laurie Freelance Consultant, UK + Rasmus Lerdorf Yahoo!, California + Daniel Lopez Ridruejo Covalent Technologies, California + Doug MacEachern Covalent Technologies, California + Aram W. Mirzadeh CableVision, New York + Chuck Murcko The Topsail Group, Pennsylvania + Brian Pane CNET Networks, California + Sameer Parekh California + David Reid UK + William A. Rowe, Jr. Covalent, Illinois + Wilfredo Sanchez Apple Computer, California + Cliff Skolnick California + Marc Slemko Canada + Joshua Slive Canada + Greg Stein California + Bill Stoddard IBM Corporation, Research Triangle Park, NC + Sander Striker The Netherlands + Paul Sutton Seattle + Randy Terbush Covalent Technologies, California + Jeff Trawick IBM Corporation, Research Triangle Park, NC + Cliff Woolley University of Virginia + +Apache Emeritus (old group members now off doing other things) + + Ryan Bloom California + Rob Hartill Internet Movie DB, UK + David Robinson Cambridge University, UK + Robert S. Thau MIT, Massachusetts + Andrew Wilson Freelance Consultant, UK + +Other major contributors + + Howard Fear (mod_include), Florent Guillaume (language negotiation), + Koen Holtman (rewrite of mod_negotiation), + Kevin Hughes (creator of all those nifty icons), + 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), + 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: +, and their authors frequently +contribute ideas, patches, and testing. + +Hundreds of people have made individual contributions to the Apache +project. Patch contributors are listed in the CHANGES file. +Frequent contributors have included Petr Lampa, Tom Tromey, James H. +Cloos Jr., Ed Korthof, Nathan Neulinger, Jason S. Clary, Jason A. Dour, +Michael Douglass, Tony Sanders, Brian Tao, Michael Smith, Adam Sussman, +Nathan Schrenk, Matthew Gray, and John Heidemann. + + ============================================================================ + +How to become involved in the Apache project + +There are several levels of contributing. If you just want to send +in an occasional suggestion/fix, then you can just use the bug reporting +form at . You can also subscribe +to the announcements mailing list (announce-subscribe@httpd.apache.org) which +we use to broadcast information about new releases, bugfixes, and upcoming +events. There's a lot of information about the development process (much of +it in serious need of updating) to be found at . + +If you'd like to become an active contributor to the Apache project (the +group of volunteers who vote on changes to the distributed server), then +you need to start by subscribing to the dev@httpd.apache.org mailing list. +One warning though: traffic is high, 1000 to 1500 messages/month. +To subscribe to the list, send an email to dev-subscribe@httpd.apache.org. +We recommend reading the list for a while before trying to jump in to +development. + + NOTE: The developer mailing list (dev@httpd.apache.org) is not + a user support forum; it is for people actively working on development + of the server code and documentation, and for planning future + directions. If you have user/configuration questions, send them + to users list or to the USENET + newsgroup "comp.infosystems.www.servers.unix".or for windows users, + the newsgroup "comp.infosystems.www.servers.ms-windows". + +There is a core group of contributors (informally called the "core") +which was formed from the project founders and is augmented from time +to time when core members nominate outstanding contributors and the +rest of the core members agree. The core group focus is more on +"business" issues and limited-circulation things like security problems +than on mainstream code development. The term "The Apache Group" +technically refers to this core of project contributors. + +The Apache project is a meritocracy -- the more work you have done, the more +you are allowed to do. The group founders set the original rules, but +they can be changed by vote of the active members. There is a group +of people who have logins on our server (apache.org) and access to the +CVS repository. Everyone has access to the CVS snapshots. Changes to +the code are proposed on the mailing list and usually voted on by active +members -- three +1 (yes votes) and no -1 (no votes, or vetoes) are needed +to commit a code change during a release cycle; docs are usually committed +first and then changed as needed, with conflicts resolved by majority vote. + +Our primary method of communication is our mailing list. Approximately 40 +messages a day flow over the list, and are typically very conversational in +tone. We discuss new features to add, bug fixes, user problems, developments +in the web server community, release dates, etc. The actual code development +takes place on the developers' local machines, with proposed changes +communicated using a patch (output of a unified "diff -u oldfile newfile" +command), and committed to the source repository by one of the core +developers using remote CVS. Anyone on the mailing list can vote on a +particular issue, but we only count those made by active members or people +who are known to be experts on that part of the server. Vetoes must be +accompanied by a convincing explanation. + +New members of the Apache Group are added when a frequent contributor is +nominated by one member and unanimously approved by the voting members. +In most cases, this "new" member has been actively contributing to the +group's work for over six months, so it's usually an easy decision. + +The above describes our past and current (as of July 2000) guidelines, +which will probably change over time as the membership of the group +changes and our development/coordination tools improve. + + ============================================================================ + +The Apache Software Foundation (www.apache.org) + +The Apache Software Foundation exists to provide organizational, legal, +and financial support for the Apache open-source software projects. +Founded in June 1999 by the Apache Group, the Foundation has been +incorporated as a membership-based, not-for-profit corporation in order +to ensure that the Apache projects continue to exist beyond the participation +of individual volunteers, to enable contributions of intellectual property +and funds on a sound basis, and to provide a vehicle for limiting legal +exposure while participating in open-source software projects. + +You are invited to participate in The Apache Software Foundation. We welcome +contributions in many forms. Our membership consists of those individuals +who have demonstrated a commitment to collaborative open-source software +development through sustained participation and contributions within the +Foundation's projects. Many people and companies have contributed towards +the success of the Apache projects. + + ============================================================================ + +Why Apache Is Free + +Apache exists to provide a robust and commercial-grade reference +implementation of the HTTP protocol. It must remain a platform upon which +individuals and institutions can build reliable systems, both for +experimental purposes and for mission-critical purposes. We believe the +tools of online publishing should be in the hands of everyone, and +software companies should make their money providing value-added services +such as specialized modules and support, amongst other things. We realize +that it is often seen as an economic advantage for one company to "own" a +market - in the software industry that means to control tightly a +particular conduit such that all others must pay. This is typically done +by "owning" the protocols through which companies conduct business, at the +expense of all those other companies. To the extent that the protocols of +the World Wide Web remain "unowned" by a single company, the Web will +remain a level playing field for companies large and small. Thus, +"ownership" of the protocol must be prevented, and the existence of a +robust reference implementation of the protocol, available absolutely for +free to all companies, is a tremendously good thing. + +Furthermore, Apache is an organic entity; those who benefit from it +by using it often contribute back to it by providing feature enhancements, +bug fixes, and support for others in public newsgroups. The amount of +effort expended by any particular individual is usually fairly light, but +the resulting product is made very strong. This kind of community can +only happen with freeware -- when someone pays for software, they usually +aren't willing to fix its bugs. One can argue, then, that Apache's +strength comes from the fact that it's free, and if it were made "not +free" it would suffer tremendously, even if that money were spent on a +real development team. + +We want to see Apache used very widely -- by large companies, small +companies, research institutions, schools, individuals, in the intranet +environment, everywhere -- even though this may mean that companies who +could afford commercial software, and would pay for it without blinking, +might get a "free ride" by using Apache. We would even be happy if some +commercial software companies completely dropped their own HTTP server +development plans and used Apache as a base, with the proper attributions +as described in the LICENSE file. + +Thanks for using Apache! + diff --git a/trunk/Apache.dsw b/trunk/Apache.dsw new file mode 100644 index 0000000000..eeb51c49df --- /dev/null +++ b/trunk/Apache.dsw @@ -0,0 +1,2006 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "httpd"=".\httpd.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "ApacheMonitor"=.\support\win32\ApacheMonitor.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "BuildBin"=.\BuildBin.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name httpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name ApacheMonitor + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv_ccs_modules + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv_ces_modules + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_actions + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_alias + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_asis + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_digest + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authn_anon + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authn_dbm + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authn_default + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authn_file + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authnz_ldap + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authz_dbm + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authz_default + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authz_groupfile + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authz_host + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_authz_user + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_autoindex + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_bucketeer + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_cern_meta + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_cgi + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_charset_lite + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_dav_fs + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_dir + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_disk_cache + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_dumpio + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_env + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_expires + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_ext_filter + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_file_cache + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_headers + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_ident + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_imagemap + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_include + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_info + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_isapi + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_logio + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_log_config + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_log_forensic + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_mem_cache + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_mime + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_mime_magic + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_negotiation + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_rewrite + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_setenvif + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_speling + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_status + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_unique_id + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_userdir + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_usertrack + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_version + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_vhost_alias + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy_connect + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy_ftp + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy_http + End Project Dependency + Begin Project Dependency + Project_Dep_Name ab + End Project Dependency + Begin Project Dependency + Project_Dep_Name htdbm + End Project Dependency + Begin Project Dependency + Project_Dep_Name htdigest + End Project Dependency + Begin Project Dependency + Project_Dep_Name htpasswd + End Project Dependency + Begin Project Dependency + Project_Dep_Name logresolve + End Project Dependency + Begin Project Dependency + Project_Dep_Name rotatelogs + End Project Dependency + Begin Project Dependency + Project_Dep_Name wintty + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy_ajp + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy_balancer + End Project Dependency +}}} + +############################################################################### + +Project: "InstallBin"=.\InstallBin.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name BuildBin + End Project Dependency +}}} + +############################################################################### + +Project: "ab"=.\support\ab.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "abs"=.\support\abs.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "apr"=.\srclib\apr\apr.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "apriconv"=".\srclib\apr-iconv\apriconv.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "aprutil"=".\srclib\apr-util\aprutil.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apriconv + End Project Dependency + Begin Project Dependency + Project_Dep_Name gen_uri_delims + End Project Dependency + Begin Project Dependency + Project_Dep_Name xml + End Project Dependency +}}} + +############################################################################### + +Project: "dftables"=.\srclib\pcre\dftables.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gen_test_char"=.\server\gen_test_char.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency +}}} + +############################################################################### + +Project: "gen_uri_delims"=".\srclib\apr-util\uri\gen_uri_delims.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "htdbm"=.\support\htdbm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "htdigest"=.\support\htdigest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "htpasswd"=.\support\htpasswd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "libapr"=.\srclib\apr\libapr.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "libapriconv"=".\srclib\apr-iconv\libapriconv.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency +}}} + +############################################################################### + +Project: "libapriconv_ccs_modules"=".\srclib\apr-iconv\ccs\libapriconv_ccs_modules.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv + End Project Dependency +}}} + +############################################################################### + +Project: "libapriconv_ces_modules"=".\srclib\apr-iconv\ces\libapriconv_ces_modules.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv + End Project Dependency +}}} + +############################################################################### + +Project: "libaprutil"=".\srclib\apr-util\libaprutil.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv + End Project Dependency + Begin Project Dependency + Project_Dep_Name gen_uri_delims + End Project Dependency + Begin Project Dependency + Project_Dep_Name xml + End Project Dependency +}}} + +############################################################################### + +Project: "libhttpd"=.\libhttpd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libapriconv + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name gen_test_char + End Project Dependency + Begin Project Dependency + Project_Dep_Name pcre + End Project Dependency +}}} + +############################################################################### + +Project: "logresolve"=.\support\logresolve.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "mod_actions"=.\modules\mappers\mod_actions.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_alias"=.\modules\mappers\mod_alias.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_asis"=.\modules\generators\mod_asis.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_auth_basic"=.\modules\aaa\mod_auth_basic.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_auth_digest"=.\modules\aaa\mod_auth_digest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authnz_ldap"=.\modules\aaa\mod_authnz_ldap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_ldap + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authn_anon"=.\modules\aaa\mod_authn_anon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authn_dbm"=.\modules\aaa\mod_authn_dbm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authn_default"=.\modules\aaa\mod_authn_default.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authn_file"=.\modules\aaa\mod_authn_file.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authz_dbm"=.\modules\aaa\mod_authz_dbm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authz_default"=.\modules\aaa\mod_authz_default.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authz_groupfile"=.\modules\aaa\mod_authz_groupfile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authz_host"=.\modules\aaa\mod_authz_host.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_authz_user"=.\modules\aaa\mod_authz_user.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_auth_basic + End Project Dependency +}}} + +############################################################################### + +Project: "mod_autoindex"=.\modules\generators\mod_autoindex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_bucketeer"=.\modules\debug\mod_bucketeer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_cache"=.\modules\cache\mod_cache.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_cern_meta"=.\modules\metadata\mod_cern_meta.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_cgi"=.\modules\generators\mod_cgi.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_charset_lite"=.\modules\experimental\mod_charset_lite.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_dav"=.\modules\dav\main\mod_dav.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_dav_fs"=.\modules\dav\fs\mod_dav_fs.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_dav + End Project Dependency +}}} + +############################################################################### + +Project: "mod_deflate"=.\modules\filters\mod_deflate.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_dir"=.\modules\mappers\mod_dir.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_disk_cache"=.\modules\cache\mod_disk_cache.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_cache + End Project Dependency +}}} + +############################################################################### + +Project: "mod_dumpio"=.\modules\debug\mod_dumpio.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_echo"=.\modules\echo\mod_echo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_env"=.\modules\metadata\mod_env.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_expires"=.\modules\metadata\mod_expires.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_ext_filter"=.\modules\filters\mod_ext_filter.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_file_cache"=.\modules\cache\mod_file_cache.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_headers"=.\modules\metadata\mod_headers.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_ident"=.\modules\metadata\mod_ident.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_imagemap"=.\modules\mappers\mod_imagemap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_include"=.\modules\filters\mod_include.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_info"=.\modules\generators\mod_info.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_isapi"=.\modules\arch\win32\mod_isapi.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_ldap"=.\modules\ldap\mod_ldap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_log_config"=.\modules\loggers\mod_log_config.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_log_forensic"=.\modules\loggers\mod_log_forensic.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_logio"=.\modules\loggers\mod_logio.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_mem_cache"=.\modules\cache\mod_mem_cache.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_cache + End Project Dependency +}}} + +############################################################################### + +Project: "mod_mime"=.\modules\http\mod_mime.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_mime_magic"=.\modules\metadata\mod_mime_magic.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_negotiation"=.\modules\mappers\mod_negotiation.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy"=.\modules\proxy\mod_proxy.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy_ajp"=.\modules\proxy\mod_proxy_ajp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy_balancer"=.\modules\proxy\mod_proxy_balancer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy_connect"=.\modules\proxy\mod_proxy_connect.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy_ftp"=.\modules\proxy\mod_proxy_ftp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy + End Project Dependency +}}} + +############################################################################### + +Project: "mod_proxy_http"=.\modules\proxy\mod_proxy_http.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency + Begin Project Dependency + Project_Dep_Name mod_proxy + End Project Dependency +}}} + +############################################################################### + +Project: "mod_rewrite"=.\modules\mappers\mod_rewrite.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_setenvif"=.\modules\metadata\mod_setenvif.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_speling"=.\modules\mappers\mod_speling.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_ssl"=.\modules\ssl\mod_ssl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_status"=.\modules\generators\mod_status.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_unique_id"=.\modules\metadata\mod_unique_id.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_userdir"=.\modules\mappers\mod_userdir.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_usertrack"=.\modules\metadata\mod_usertrack.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_version"=.\modules\metadata\mod_version.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "mod_vhost_alias"=.\modules\mappers\mod_vhost_alias.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libapr + End Project Dependency + Begin Project Dependency + Project_Dep_Name libaprutil + End Project Dependency + Begin Project Dependency + Project_Dep_Name libhttpd + End Project Dependency +}}} + +############################################################################### + +Project: "pcre"=.\srclib\pcre\pcre.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name dftables + End Project Dependency +}}} + +############################################################################### + +Project: "rotatelogs"=.\support\rotatelogs.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "wintty"=.\support\win32\wintty.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name apr + End Project Dependency + Begin Project Dependency + Project_Dep_Name aprutil + End Project Dependency +}}} + +############################################################################### + +Project: "xml"=".\srclib\apr-util\xml\expat\lib\xml.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/trunk/BuildBin.dsp b/trunk/BuildBin.dsp new file mode 100644 index 0000000000..9e3c15235e --- /dev/null +++ b/trunk/BuildBin.dsp @@ -0,0 +1,97 @@ +# Microsoft Developer Studio Project File - Name="BuildBin" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=BuildBin - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "BuildBin.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "BuildBin.mak" CFG="BuildBin - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "BuildBin - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "BuildBin - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "BuildBin - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "" +# PROP BASE Cmd_Line "NMAKE /f makefile.win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "\Apache21\bin\httpd.exe" +# PROP BASE Bsc_Name ".\Browse\BuildBin.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "" +# PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache21" LONG=Release _tryssl _tryzlib _dummy" +# PROP Rebuild_Opt "" +# PROP Target_File "\Apache21\bin\httpd.exe" +# PROP Bsc_Name ".\Browse\httpd.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "BuildBin - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "" +# PROP BASE Cmd_Line "NMAKE /f makefile.win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "\Apache21\bin\httpd.exe" +# PROP BASE Bsc_Name ".\Browse\BuildBin.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "" +# PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache21" LONG=Debug _tryssl _tryzlib _dummy" +# PROP Rebuild_Opt "" +# PROP Target_File "\Apache21\bin\httpd.exe" +# PROP Bsc_Name ".\Browse\httpd.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "BuildBin - Win32 Release" +# Name "BuildBin - Win32 Debug" + +!IF "$(CFG)" == "BuildBin - Win32 Release" + +!ELSEIF "$(CFG)" == "BuildBin - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\os\win32\BaseAddr.ref +# End Source File +# Begin Source File + +SOURCE=.\CHANGES +# End Source File +# Begin Source File + +SOURCE=.\Makefile.win +# End Source File +# Begin Source File + +SOURCE=.\STATUS +# End Source File +# End Target +# End Project diff --git a/trunk/CHANGES b/trunk/CHANGES new file mode 100644 index 0000000000..e358998d62 --- /dev/null +++ b/trunk/CHANGES @@ -0,0 +1,14683 @@ +Changes with Apache 2.1.5 + + [Remove entries to the current 2.0 section below, when backported] + + *) mod_cache: Fix 'Vary: *' behavior to be RFC compliant. PR 16125. + [Paul Querna] + + *) mod_cache: Rename 'generate_name' to 'ap_cache_generate_name'. + [Paul Querna] + + *) SECURITY: CAN-2005-1268 (cve.mitre.org) + mod_ssl: Fix possible crash on printing CRL details when + debugging is enabled, if configured to use a CRL from + a malicious source. PR 35081. [Marc Stern ] + + *) proxy FTP: Fix confusion about globbing characters which could lead + to getting a directory listing when a file was requested. PR 34512. + [Sean ] + + *) mod_mime_magic: Handle CRLF-format magic files so that it works with + the default installation on Windows. [Jeff Trawick] + + *) core: Allow multiple modules to register interest in a single + configuration command. [Paul Querna] + + *) EBCDIC: Handle chunked input from client or, with proxy, origin + server. [Jeff Trawick] + + *) authn_provider_alias: Adds the configuration block tag + + Authentication directives contained within this block can be + referenced as a new authProvider using the AuthBasicProvider or + AuthDigestProvider directive. These directives will be merged in to + the per_dir configuration just before the base provider is called. + [Brad Nicholes] + + *) ap_getword_conf: Fix backslashes at the end of configuration directives. + PR 34834. [Timo Viipuri ] + + *) mod_dbd: New additions: mod_dbd.c, mod_dbd.h, mod_dbd.xml + Provide module hooks for apr_dbd; optimise for httpd + threaded and non-threaded arch [Nick Kew] + + *) ab: SSL support rewritten, improved, and enabled if SSL is enabled + during the build; -f and -Z arguments added to specify SSL protocol + options. [Masaoki Kobayashi ] + + *) Support the suppress-error-charset setting, as with Apache 1.3.x. + PR 31274. [Jeff Trawick] + + *) Prevent hangs of child processes when writing to piped loggers at + the time of graceful restart. PR 26467. [Jeff Trawick] + + *) mod_info: Show the Quick Handler [Paul Querna] + + *) mod_ldap: Add the directive LDAPVerifyServerCert to specify + whether to force verification of the server certificate when + establishing an SSL connection to the LDAP server. + [Brad Nicholes] + + *) mod_proxy: Run mod_rewrite before mod_proxy in the translate_name + hook. [Paul Querna] + + *) Add AP_INIT_TAKE_ARGV for configuration commands. (minor MMN bump) + [Paul Querna] + + *) worker and event mpms: don't take down the whole server for a transient + thread creation failure. PR 34514 [Greg Ames] + + *) ap_get_local_host() rewritten for APR. [Jim Jagielski] + + *) Add the ap_vhost_iterate_given_conn function to expose the information + used in Name Based Virtual Hosting. (minor MMN bump) + [Paul Querna] + + *) Remove the never working ap_method_list_do and ap_method_list_vdo. + [Paul Querna] + + *) Added makefile and doc for building mod_ssl on the NetWare + platform. [Guenter Knauf, Brad Nicholes] + + *) mod_deflate: Merge the Vary header, isntead of Setting it. Fixes + applications that send the Vary Header themselves, and also apply + mod_defalte as an output filter. [Paul Querna] + + *) mod_rewrite: use buffered I/O for RewriteMap txt: files. This + can result in a major performance improvement when the files are + large. + [Greg Ames] + + *) Change the default (when not present in the config file) setting + for UseCanonicalName to Off. + [Joshua Slive] + + *) mod_userdir: The module no longer does any remapping unless the + UserDir directive is present in the config file. + [Joshua Slive] + + *) Massively simplify the distributed httpd.conf by removing + many features and many directives that are at their default + setting. Add a selection of example config excerpts for adding + extra features in the conf/extra/ directory. Install the + distributed config and the extra config examples in the + conf/original/ directory during make install. + [Joshua Slive, Justin Erenkrantz] + + *) NetWare: Reposition mod_asis, mod_actions, mod_cgi, mod_imagemap, + mod_userdir and mod_autoindex as shared modules rather than + built-in modules within the NetWare build. + [Brad Nicholes] + + *) Rename mod_imap to mod_imagemap. + [Paul Querna] + + *) util_ldap: Eliminate the load ordering of mod_ldap and mod_authnz_ldap + by changing the mod_ldap exported functions to optional functions. + [Brad Nicholes] + +Changes with Apache 2.1.4 + + *) Don't let a subrequest inherit headers describing the original request's + body. [Greg Ames] + + *) Fix Windows CompContext buff size miscalculation + [Allan Edwards] + + *) Add ReceiveBufferSize directive to control the TCP receive buffer. + [Eric Covener ] + + *) mod_proxy: Add proxy-sendextracrlf option to send an extra CRLF at the + end of the request body to work with really old HTTP servers. + [Justin Erenkrantz] + + *) util_ldap: Keep track of the number of attributes retrieved from + LDAP so that all the values can be properly cached even if the + value is NULL. PR 33901 [Brad Nicholes] + + *) mod_cache: Fix error where incoming Cache-Control would be ignored. + [Justin Erenkrantz] + + *) mod_cache: Correctly handle originally conditional requests. + [Sander Striker] + + *) mod_disk_cache: Correctly update cached headers on revalidated responses. + [Sander Striker, Justin Erenkrantz] + + *) worker MPM/mod_status: Support per-worker tracking of pid and + generation in the scoreboard so that mod_status can accurately + represent workers in processes which are gracefully terminating. + (major MMN bump) + [Jeff Trawick] + + *) Correctly export all mod_dav public functions. + [Branko Èibej ] + +Changes with Apache 2.1.3 + + *) mod_ssl: Add ssl_ext_lookup optional function for accessing + certificate extensions. [David Reid, Joe Orton] + + *) Add support for use of an external PCRE library; pass the + --with-pcre flag to configure. PR 27550. [Joe Orton, + Andres Salomon ] + + *) Renamed regex interfaces to be namespace-safe, and moved from + pcreposix.h header to ap_regex.h: regex_t->ap_regex_t, + regmatch_t->ap_regmatch_t; REG_*->AP_REG_*; functions + reg*->ap_reg*. PR 27550. [Andres Salomon , + Joe Orton] + + *) Only recompile buildmark.c when we have to relink httpd. + [Justin Erenkrantz] + + *) mod_cache: Fix up handling of revalidated responses. + [Justin Erenkrantz] + + *) mod_disk_cache: Properly load cached ETag from on-disk structures. + [Justin Erenkrantz] + + *) mod_authnz_ldap: Added an optional second parameter to AuthLDAPURL + to allow it to override the connection type set in mod_ldap. This + parameter can be set to NONE, SSL or TLS | STARTTLS. + [Brad Nicholes] + + *) Fix --with-apr=/usr and/or --with-apr-util=/usr. PR 29740. + [Max Bowsher ] + + *) mod_proxy: Fix ProxyRemoteMatch directive. PR 33170. + [Rici Lake ] + + *) mod_proxy: Fix incorrect decoding/unescaping for reverse proxies. + PR 32459, 15207. [Jim Jagielski] + + *) mod_cache: Add CacheStorePrivate and CacheStoreNoStore directive. + [Justin Erenkrantz] + + *) Add --enable-pie flag to configure, to build httpd as a Position + Independent Executable where supported (GCC/binutils). + [Joe Orton] + + *) proxy_balancer: Add in load-balancing via weighted traffic + byte count. [Jim Jagielski] + + *) mod_disk_cache: Cache r->err_headers_out headers. This allows CGI + scripts to be properly cached. [Justin Erenkrantz, Sander Striker] + + *) mod_ldap: Updated to use the new apr-util v1.1 apr_ldap_*_option() + API for the setting of server and client SSL certificates. Replaced + LDAPTrustedCA directive with LDAPTrustedGlobalCert and + LDAPTrustedClientCert directives to correctly support global certs + (CA certs / Netware client certs) and per connection client certs + as supported by Netware, OpenLDAP and Netscape/Mozilla. + [Graham Leggett] + + *) mod_cache: Remove unimplemented CacheForceCompletion directive. + [Justin Erenkrantz] + + *) support/check_forensic: Fix temp file usage + [Javier Fernandez-Sanguino Pen~a ] + + *) mod_ssl: Add SSLCADNRequestFile and SSLCADNRequestPath directives + which can be used to configure a specific list of CA names to send + in a client certificate request. PR 32848. + [Tim Taylor ] + + *) --with-module can now take more than one module to be statically + linked: --with-module=:,:,... + If the -subdirectory doesn't exist it will be created and + populated with a standard Makefile.in. [Erik Abele] + + *) Remove some compiler warnings within the LDAP modules [Graham Leggett] + + *) Add a build script to create a solaris package. [Graham Leggett] + + *) ap_http_scheme() replaced with ap_http_method() - this function + returns the scheme (http v.s. https). + [William Rowe] + + *) mod_proxy: Fix a request corruption problem and a buffering problem + which sometimes prevented proxy-sendchunks from working. + [Jeff Trawick] + + *) Fix the RPM spec file so that an RPM build now works. An RPM + build now requires system installations of APR and APR-util. + [Graham Leggett] + + *) Significantly simplify the load balancer scheduling algorithm + for the proxy BalancerMember weighting. loadfactors (lbfactors) + are now normalized with respect to each other. [Jim Jagielski] + + *) mod_dumpio: Added to the available module suite; it is an + I/O logging/dumping module. Placed in the (new) debug module + subdirectory. mod_bucketeer moved to that directory as well. + [Jim Jagielski] + + *) core: Add support for APR_TCP_DEFER_ACCEPT to defer accepting + of a connection until data is available. + [Paul Querna] + +Changes with Apache 2.1.2 + + *) mod_proxy: Respect errors reported by pre_connection hooks. + [Jeff Trawick] + + *) core: Error out on sections that are missing an argument instead of + silently consuming the section. PR 25460. + [Geoffrey Young, Paul Querna] + + *) mod_cache/mod_mem_cache/mod_disk_cache: Move out of experimental. + + *) Upgraded PCRE to version 5.0. [Brian Pane] + + *) mod_cgid: Catch configuration problem where two web server instances + share same ServerRoot but admin forgot to use ScriptSock. + [Jeff Trawick] + + *) mod_cgi: Ensure that all stderr is logged for a script which returns + a Location header to generate a non-local redirect. PR 20111. + [Joe Orton] + + *) Added the Event MPM to more efficiently handle clients during a + Keep Alive request. + [Paul Querna, Greg Ames] + +Changes with Apache 2.1.1 + + *) mod_proxy_http: Stream content better - always flush buffered data to + the client before blocking waiting for new data. PR 19954. + [Joe Orton] + + *) mod_ssl: Add support for command-line option "-t -DDUMP_CERTS" which + will dump the filenames of all configured SSL certificates to stdout. + [Joe Orton] + + *) mod_disk_cache: Remove a bunch of non-implemented garbage collection + and cache size directives that are now available through htcacheclean. + [Justin Erenkrantz] + + *) Add htcacheclean to support/ for assistance with mod_disk_cache. + [Andreas Steinmetz] + + *) mod_authnz_ldap: Added the directive "Requires ldap-filter" that + allows the module to authorize a user based on a complex LDAP + search filter. [Brad Nicholes] + + *) mod_usertrack: Run the fixups hook before other modules. + PR 29755. [Paul Querna] + + *) Allow mod_authnz_ldap authorization functionality to be used + without requiring the user to also be authenticated through + mod_authnz_ldap. This allows other authentication modules to + take advantage of LDAP authorization only [PR 28253] + [Jari Ahonen jah progress.com, Brad Nicholes] + + *) Log the client IP address when an error occurs disabling nagle on a + connection, but log at a severity of debug since this error + generally means that the connection was dropped before data was + sent. Log the client IP address when reporting errors in the core + output filter. [Jeff Trawick] + + *) Add ap_log_cerror() for logging messages associated with particular + client connections. [Jeff Trawick] + + *) core: Add a warning message if the request line read fails. + [Paul Querna] + + *) mod_rewrite: Removed the MaxRedirects option in favor of the + core LimitInternalRecursion directive. [André Malo] + + *) mod_info: Added listing of the Request Hooks and added more build + information like 'httpd -V' contains. Changed output to XHTML. + [Paul Querna] + + *) mod_info: Rewrote config tree walk using a recursive function. + Added ?config option. Added printout of config filename and line numbers. + [Rici Lake , Paul Querna] + + *) mod_proxy: Fix type error that prevents proxy-sendchunks from working. + [Justin Erenkrantz] + + *) mod_proxy: Fix data corruption by properly setting aside buckets. + [Justin Erenkrantz] + + *) mod_proxy: If a request has a blank body and has a 0 Content-Length + headers, pass that to the proxy. [Justin Erenkrantz] + + *) Recognize QSA flag in mod_rewrite again. + [Jan Kratochvil ] + + *) Restructured mod_auth_ldap to fit the new authentication model. + The module is now called authnz_ldap and has been moved out of + the modules/experimental area and into modules/aaa with the other + auth modules. Both the authn_ldap provider and the authz_ldap + handler are contained within the authnz_ldap module. The + authz_ldap handler introduces 3 new "requires" values for handling + authorization. These handlers are ldap-user, ldap-group and + ldap-dn. [Brad Nicholes] + + *) Fix some compiler warnings in proxy + [Geoffrey Young ] + + *) mod_ssl: Add SSL_CLIENT_V_REMAIN variable, representing the + number of days until the client cert expires. [Joe Orton] + + *) Add test_config hook, run only if httpd is invoked using -t. + [Joe Orton] + + *) Improve error handling for corrupted pid files. [Jeff Trawick] + + *) mod_proxy.c and proxy_util.c: Enable compiling on 2.0-HEAD + (for backwards compatibility): + Avoids mod_ssl.h (not included in 2.0-HEAD) and + use apr_socket_create_ex for 0.9.x + [Mladen Turk] + + *) Added proxy_ajp.c module for proxy support to ajp:// backends. + [Jean Frederic Clere] + + *) Fixes the build of proxy on Windows. Since the proxy_module is declared + as extern using AP_MODULE_DECLARE_DATA that expands to dllexport, there + is a LNK2001 error when building proxy_http. [Mladen Turk] + + *) Remove LDAP toolkit specific code from util_ldap and mod_auth_ldap. + [Graham Leggett] + + *) Remove deprecated/removed APR_STATUS_IS_SUCCESS(). [Justin Erenkrantz] + + *) perchild MPM: Fix thread safety problem in the use of longjmp(). + [Tsuyoshi SASAMOTO ] + + *) Add load balancer support to the scoreboard in preparation for + load balancing support in mod_proxy. [Mladen Turk] + + *) mod_nw_ssl: Added the directive NWSSLUpgradeable to mod_nw_ssl to + allow a non-secure connection to be upgraded to secure connections + [Brad Nicholes] + + *) core: Add Options= syntax to AllowOverride to specify which options + may be overridden in .htaccess files. PR 29310. + [Tom Alsberg , Paul Querna] + + *) ab: Handle long URLs with an error instead of an buffer overflow. + PR 28204. [Erik Weide , Paul Querna] + + *) mod_so, core: Add new command line options to print all loaded + modules. '-t -D DUMP_MODULES' and '-M' will show all static + and shared modules as loaded from the configuration file. + [Paul Querna] + + *) mod_autoindex: Add ShowForbidden to IndexOptions to list files + that are not shown because the subrequest returned 401 or 403. + PR 10575. [Paul Querna] + + *) mod_headers: implement "Early" processing option in post_read_request + to enable Header and RequestHeader directives to be used to set up + testcases for pre-fixups request phases [Nick Kew] + + *) mod_proxy: multiple bugfixes, principally support cookies in + ProxyPassReverse, and don't canonicalise URL passed to backend. + Documentation correspondingly updated. [Nick Kew ] + + *) mod_deflate: support gzip flags in inflate_out_filter + [Nick Kew ] + + *) Drop the ErrorHeader directive which turned out to be a misnomer. + Instead there's a new optional flag for the Header directive + ('always'), which keeps the former ErrorHeader functionality. + [André Malo] + + *) mod_deflate: Don't deflate responses with zero length + e.g. proxied 304's [Allan Edwards] + + *) now recognizes the module identifier in addition to the + file name. PR 29003. [Edward Rudd , André Malo] + + *) mod_ssl: Add "SSLHonorCipherOrder" directive to enable the + OpenSSL 0.9.7 flag which uses the server's cipher order rather + than the client's. PR 28665. + [Jim Schneider ] + + *) mod_ssl: Drop support for the CompatEnvVars argument to + SSLOptions, which was never actually implemented in 2.0. + [Joe Orton] + + *) Fix bug in mod_deflate that unconditionally sent deflate'd output + even when Accept-Encoding is not present. [Justin Erenkrantz] + + *) Pass environment variables through to piped loggers and start + them via the shell, resolving regressions since 1.3. PR 28815 + [Ken Coar, Jeff Trawick] + + *) External rewrite map responses are no longer limited to 2048 + bytes. [André Malo] + + *) Proxy server was deleting cookies that Apache had already + assigned if the origin server had set any cookies. PR 27023. + [Jim Jagielski] + + *) Removed old and unmaintained ap_add_named_module API and changed + the following APIs to return an error instead of hard exiting: + ap_add_module, ap_add_loaded_module, ap_setup_prelinked_modules, + and ap_process_resource_config. [André Malo] + + *) mod_headers: Allow %% in header values to represent a literal %. + [André Malo] + + *) mod_headers: Allow env clauses also for 'echo' and 'unset' actions. + [André Malo] + + *) mod_headers: Allow 'echo' also for ErrorHeaders. [André Malo] + + *) mod_deflate: New option for DEFLATE output file (force-gzip), + new output filter 'INFLATE' for uncompressing responses. + [Nick Kew , Ian Holsman] + + *) Added new module mod_version, which provides version dependent + configuration containers. [André Malo] + + *) mod_log_config now logs all Set-Cookie headers if the %{Set-Cookie}o + format is used. PR 27787. [André Malo] + + *) Allow Digest providers to return AUTH_DENIED to propagate a 401 + status and terminate the provider chain prior to checking the password. + [Geoffrey Young] + + *) mod_cgid: Don't allow Scriptsock to be specified inside VirtualHost; + Don't place script socket inside default server root instead of + actual server root. PR 27886. [Jeff Trawick] + + *) mod_proxy: Fix handling of non-200 success status codes when + "ProxyErrorOverride On" is configured. PR 20183. + [Marcus Janson , Joe Orton] + + *) Threaded MPMs for Unix and Win32: Add support for ThreadStackSize + directive (previously NetWare-only) to override default thread + stack size for threads which handle client connections. Required + for some third-party modules on platforms with small default + thread stack size. [Jeff Trawick] + + *) minor mod_auth_basic and mod_auth_digest sync. mod_auth_basic + now populates r->user with the (possibly unauthenticated) user, + and mod_auth_digest returns 500 when a provider returns + AUTH_GENERAL_ERROR. + [Geoffrey Young] + + *) The whole codebase was relicensed and is now available under + the Apache License, Version 2.0 (http://www.apache.org/licenses). + [Apache Software Foundation] + + *) Delete some make-generated files in the server directory during + "make clean" processing. PR 26552. [Jeff Trawick] + + *) Add core version query function (ap_get_server_revision) and + accompanying ap_version_t structure (minor MMN bump). + [André Malo] + + *) mod_rewrite: EOLs sent by external rewritemaps are now consumed + as whole. That way, on systems with more than one EOL character + rewritemap programs no longer need to switch stdout to binary + mode. PR 25635. [André Malo] + + *) mod_rewrite: Introduce the ability to force a content handler via + the [handler=...] flag. [André Malo] + + *) mod_rewrite: Introduce the RewriteCond -x check, which returns + true if the pattern is a file with execution permissions. + [André Malo] + + *) mod_rewrite: Allow proxying and RewriteRules in directory context + for subrequests. PR 14648, 15114. [André Malo] + + *) mod_rewrite: Allow setting of any valid HTTP response code. + PR 25917. [André Malo] + + *) mod_rewrite: Cookie creation now works locale independent. + [André Malo] + + *) mod_ssl: Add support for distributed session cache using 'distcache'. + [Geoff Thorpe ] + + *) mod_dav: Disallow requests with an unescaped hash character in + the Request-URI. PR 21779. [Amit Athavale ] + + *) mod_proxy with ProxyErrorOverride On in a reverse-proxy configuration + attaches a body to the 302 response and a wrong Content-Length header. + PR: 22951 [Ermanno Scaglione scaglione ..at.. starnetone.de] + + *) Bring ErrorHeader concept forward from 1.3, so that response + header fields can be set for return even on errors or external + redirects. [Ken Coar] + + *) Fix and parsing to require a closing '>' + in the initial container. PR 25414. + [Geoffrey Young ] + + *) Clean up httpd -V output: Instead of displaying the MPM source + directory, display the MPM name and some MPM properties. + [Geoffrey Young ] + + *) mod_ssl/mod_status: Re-enable support for output of SSL session + cache information in server-status page. [Joe Orton] + + *) mod_ssl: Remove the shmht session cache, shmcb should be used + instead. [Joe Orton] + + *) mod_logio: Account for some bytes handed to the network layer prior to + dropped connections. [Jeff Trawick] + + *) mod_autoindex: new directive IndexStyleSheet + [Tyler Riddle , Paul Querna ] + + *) Fix uninitialized gprof directory name in prefork MPM. PR 24450. + [Chris Knight ] + + *) Log an error when requests for URIs which fail to map to a valid + filesystem name are rejected with 403. [Jeff Trawick] + + *) Switch to APR 1.0 API. + + *) Major overhaul of mod_include's filter parser. The new parser code + is expected to be more robust and should catch all of the edge cases + that were not handled by the previous one. This includes a binary + incompatible change of mod_include's external API. [André Malo] + + *) mod_rewrite: Allow forced mimetypes [T=...] to get expanded. + PR 14223. [André Malo] + + *) mod_rewrite: Fix LA-U and LA-F lookups in directory context. Previously + the current rewrite state was just used as lookup path, which lead to + strange and often useless results. Related to PR 8493. [André Malo] + + *) Change Listen directive to bind to all addresses when a hostname is + not specified. [Justin Erenkrantz] + + *) Correct failure with Listen directives on machines with IPv6 enabled. + [Colm MacCárthaigh , Justin Erenkrantz] + + *) Fix a link failure in mod_ssl when the OpenSSL libraries contain + the ENGINE functions but the engine header files are missing. + [Cliff Woolley] + + *) mod_rewrite: RewriteRules in server context using the force + type feature [T=...] no longer disable MultiViews. [André Malo] + + *) mod_rewrite: Allow piped rewrite logs to be relative to ServerRoot. + [André Malo] + + *) mod_authz_groupfile: Strip trailing spaces of group names. This + hopefully saves some hours of searching for typos. PR 12863. + [André Malo] + + *) mod_actions: Propagate the handler name to the action script via + the REDIRECT_HANDLER environment variable. [André Malo] + + *) mod_actions: Introduce the "virtual" modifier to the Action directive, + which allows the use of handlers for virtual locations. PR 8431. + [André Malo] + + *) mod_speling: Recognize AcceptPathInfo setting for the particular + location. Default is to reject path information. PR 21059. + [André Malo] + + *) mod_ext_filter: Add the ability to filter request bodies. + [Philipp Reisner ] + + *) Fix some broken log messages in WinNT MPM. + [Juan Rivera ] + + *) prefork MPM: Use the right permissions for the directory created + for gprof support. [Jim Carlson ] + + *) Fix a compile failure with recent OpenSSL and picky compilers + (e.g., OpenSSL 0.9.7a and xlc_r on AIX). [Jeff Trawick] + + *) OpenSSL headers should be included as "openssl/ssl.h", and not rely on + the INCLUDE path to be defined properly. + PR 11310. [Geoff Thorpe ] + + *) Modify APACHE_CHECK_SSL_TOOLKIT to detect SSL-C. [Madhusudan Mathihalli] + + *) Replace the APACHE_CHECK_SSL_TOOLKIT method with a cleaner one, using + autoconf tools (AC_CHECK_HEADER, AC_CHECK_LIB etc). + [Geoff Thorpe ] + + *) change directive name from 'compressionlevel' to 'deflatecompressionlevel' + [Ian Holsman, André Malo] + + *) mod_negotiation: quality values are now parsed independent from + the current locale. level values are now really parsed as integers. + PR 17564. [André Malo] + + *) Extend mod_negotiation to evaluate the environment variables + no-gzip and gzip-only-text/html the same way as mod_deflate does. + [André Malo] + + *) mod_rewrite: Fix some problems reporting errors with mapping + programs (RewriteMap prg:/something). [Jeff Trawick] + + *) Return 413 if chunk-ext-header is too long rather than reading from + the truncated line. PR 15857. [Justin Erenkrantz] + + *) Allow restart of httpd to occur even with syntax errors in the config + file. PR 16813. [Justin Erenkrantz] + + *) Use APR_LAYOUT instead of APACHE_LAYOUT in configure. PR 15679. + [Justin Erenkrantz] + + *) Remove files on 'make distclean' that should be. PR 15592. + [Justin Erenkrantz] + + *) Allow apachectl to perform status with links and elinks as well. + [Justin Erenkrantz] + + *) mod_log_config change optional hook to return previous handler + [Ian Holsman] + + *) Forward port of mod_actions' ability to handle arbitrary methods + with the Script directive. [André Malo] + + *) Let suexec send a message to stderr, if it failed or its policy + was violated. This message appears in the error log and allows + for easier debugging. PR 5381, 7638, 8255, 10773. [André Malo] + + *) Modify buildconf to copy all required files into httpd's tree. + [Thom May ] + + *) Allow mod_dav to do weak entity comparison functions. + [Justin Erenkrantz] + + *) Move RFC 1413 ident requests from core to new module mod_ident. + [André Malo] + + *) Add mod_authz_owner - a forward port of "Require file-owner" + and "Require file-group", which was already present in version + 1.3.21. [André Malo] + + *) Add mod_dav_lock - a generic subset of the DAV locking implementation. + [Justin Erenkrantz] + + *) Replace some of the mutex locking in the worker MPM with + atomic operations for higher concurrency. [Brian Pane] + + *) Allow 'make depend' to work with non-GCC compilers. + [Justin Erenkrantz] + + *) If an httpd.conf has commented out AddModule directives, + apxs -i -a will add an un-commented AddModule directive for + the new module, which breaks the config. + PR: 11212 [Joe Orton] + + *) Fix mod_proxy handling of filtered input bodies. [Justin Erenkrantz] + + *) Move the check of the Expect request header field after the hook + for ap_post_read_request, since that is the only opportunity for + modules to handle Expect extensions. [Justin Erenkrantz] + + *) Rewrite of aaa modules to an authn/authz model. + [Dirk-Willem van Gulik, Justin Erenkrantz] + + + [Apache 2.1.0-dev includes those bug fixes and changes with the + Apache 2.0.xx tree as documented, and except as noted, below.] + +Changes with Apache 2.0.55 + + *) proxy HTTP: Rework the handling of request bodies to handle + chunked input and input filters which modify content length, and + avoid spooling arbitrary-sized request bodies in memory. + PR 15859. [Jeff Trawick] + +Changes with Apache 2.0.54 + + *) mod_cache: Add CacheIgnoreHeaders directive. PR 30399. + [Rüiger Plü ] + + *) mod_ldap: Added the directive LDAPConnectionTimeout to configure + the ldap socket connection timeout value. + [Brad Nicholes] + + *) worker MPM: Fix a problem which could cause httpd processes to + remain active after shutdown. [Jeff Trawick] + + *) Unix MPMs: Shut down the server more quickly when child processes are + slow to exit. [Joe Orton, Jeff Trawick] + + *) Remove formatting characters from ap_log_error() calls. These + were escaped as fallout from CAN-2003-0020. + [Eric Covener ] + + *) mod_ssl: If SSLUsername is used, set r->user earlier. PR 31418. + [David Reid] + + *) htdigest: Fix permissions of created files. PR 33765. [Joe Orton] + + *) core_input_filter: Move buckets to a persistent brigade instead of + creating a new brigade. This stop a memory leak when proxying a + Streaming Media Server. PR 33382. [Paul Querna] + + *) mod_win32: Ignore both PATH_INFO as well as PATH_TRANSLATED to avoid + hiccups from additional path information passed in non-utf-8 format. + [Richard Donkin ] + + *) mod_proxy: Fix ProxyRemoteMatch directive. PR 33170. + [Rici Lake ] + + *) mod_proxy: Respect errors reported by pre_connection hooks. + [Jeff Trawick] + + *) --with-module can now take more than one module to be statically + linked: --with-module=:,:,... + If the -subdirectory doesn't exist it will be created and + populated with a standard Makefile.in. [Erik Abele] + + *) Fix the RPM spec file so that an RPM build now works. An RPM + build now requires system installations of APR and APR-util. + Remove some arbitrary moving around of binaries - the RPM now + maps to the ASF build of httpd. + [Graham Leggett] + + *) mod_dumpio, an I/O logging/dumping module, added to the + modules/expermimental subdirectory. [Jim Jagielski] + + *) mod_auth_ldap: Handle the inconsistent way in which the MS LDAP + library handles special characters. PR 24437. [Jess Holle] + + *) Win32 MPM: Correct typo in debugging output. [William Rowe] + + *) conf: Remove AddDefaultCharset from the default configuration because + setting a site-wide default does more harm than good. PR 23421. + [Roy Fielding] + + *) Add charset to example CGI scripts. [Roy Fielding] + + *) mod_ssl: fail quickly if SSL connection is aborted rather than + making many doomed ap_pass_brigade calls. PR 32699. [Joe Orton] + + *) Remove compiled-in upper limit on LimitRequestFieldSize. + [Bill Stoddard] + + *) Start keeping track of time-taken-to-process-request again for + mod_status if ExtendedStatus is enabled. [Jim Jagielski] + + *) mod_proxy: Handle client-aborted connections correctly. PR 32443. + [Janne Hietamäki, Joe Orton] + + *) Fix handling of files >2Gb on all platforms (or builds) where + apr_off_t is larger than apr_size_t. PR 28898. [Joe Orton] + + *) mod_include: Fix bug which could truncate variable expansions + of N*64 characters by one byte. PR 32985. [Joe Orton] + + *) Correct handling of certain bucket types in ap_save_brigade, fixing + possible segfaults in mod_cgi with #include virtual. PR 31247. + [Joe Orton] + + *) Allow for the use of --with-module=foo:bar where the ./modules/foo + directory is local only. Assumes, of course, that the required + files are in ./modules/foo, but makes it easier to statically + build/log "external" modules. [Jim Jagielski] + + *) Util_ldap: Implemented the util_ldap_cache_getuserdn() API so that + ldap authorization only modules have access to the util_ldap + user cache without having to require ldap authentication as well. + PR 31898. [Jari Ahonen jah progress.com, Brad Nicholes] + + *) mod_auth_ldap: Added the directive "Requires ldap-attribute" that + allows the module to only authorize a user if the attribute value + specified matches the value of the user object. PR 31913 + [Ryan Morgan ] + + *) SECURITY: CAN-2004-0942 (cve.mitre.org) + Fix for memory consumption DoS in handling of MIME folded request + headers. [Joe Orton] + + *) SECURITY: CAN-2004-0885 (cve.mitre.org) + mod_ssl: Fix a bug which allowed an SSLCipherSuite setting to be + bypassed during an SSL renegotiation. PR 31505. + [Hartmut Keil , Joe Orton] + + *) mod_ssl: Fail at startup rather than segfault at runtime if a + client cert is configured with an encrypted private key. + PR 24030. [Joe Orton] + + *) apxs: fix handling of -Wc/-Wl and "-o mod_foo.so". PR 31448 + [Joe Orton] + + *) mod_ldap: Fix format strings to use %APR_PID_T_FMT instead of %d. + [Jeff Trawick] + + *) mod_cache: CacheDisable will only disable the URLs it was meant to + disable, not all caching. PR 31128. + [Edward Rudd , Paul Querna] + + *) mod_cache: Try to correctly follow RFC 2616 13.3 on validating stale + cache responses. [Justin Erenkrantz] + + *) mod_rewrite: Handle per-location rules when r->filename is unset. + Previously this would segfault or simply not match as expected, + depending on the platform. [Jeff Trawick] + + *) mod_rewrite: Fix 0 bytes write into random memory position. + PR 31036. [André Malo] + + *) mod_disk_cache: Do not store aborted content. PR 21492. + [Rüiger Plü ] + + *) mod_disk_cache: Correctly store cached content type. PR 30278. + [Rüiger Plü ] + + *) mod_ldap: prevent the possiblity of an infinite loop in the LDAP + statistics display. PR 29216. [Graham Leggett] + + *) mod_ldap: fix a bogus error message to tell the user which file + is causing a potential problem with the LDAP shared memory cache. + PR 31431 [Graham Leggett] + + *) mod_disk_cache: Do not store hop-by-hop headers. [Justin Erenkrantz] + + *) Fix the re-linking issue when purging elements from the LDAP cache + PR 24801. [Jess Holle ] + + *) mod_disk_cache: Fix races in saving responses. [Justin Erenkrantz] + + *) Fix Expires handling in mod_cache. [Justin Erenkrantz] + + *) Alter mod_expires to run at a different filter priority to allow + proper Expires storage by mod_cache. [Justin Erenkrantz] + +Changes with Apache 2.0.52 + + *) Use HTML 2.0
for error pages. PR 30732 [André Malo] + + *) Fix the global mutex crash when the global mutex is never allocated + due to disabled/empty caches. [Jess Holle ] + + *) Fix a segfault in the LDAP cache when it is configured switched + off. [Jess Holle ] + + *) SECURITY: CAN-2004-0811 (cve.mitre.org) + Fix merging of the Satisfy directive, which was applied to + the surrounding context and could allow access despite configured + authentication. PR 31315. [Rici Lake ] + + *) Fix the handling of URIs containing %2F when AllowEncodedSlashes + is enabled. Previously, such urls would still be rejected. + [Jeff Trawick, Bill Stoddard] + + *) mod_mem_cache: Fixed race condition causing segfault because of memory being + freed twice, or reused after being freed. + [J. Clar, W. Stoddard, G. Ames] + + *) Add -l option to rotatelogs to let it use local time rather than + UTC. PR 24417. [Ken Coar, Uli Zappe ] + + *) mod_log_config: Fix a bug which prevented request completion time + from being logged for I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE + processing. PR 29696. [Alois Treindl ] + +Changes with Apache 2.0.51 + + *) SECURITY: CAN-2004-0786 (cve.mitre.org) + Fix an input validation issue in apr-util which could be + triggered by malformed IPv6 literal addresses. [Joe Orton] + + *) SECURITY: CAN-2004-0747 (cve.mitre.org) + Fix buffer overflow in expansion of environment variables in + configuration file parsing. [André Malo] + + *) SECURITY: CAN-2004-0809 (cve.mitre.org) + mod_dav_fs: Fix a segfault in the handling of an indirect lock + refresh. PR 31183. [Joe Orton] + + *) mod_include no longer checks for recursion, because that's done + in the core. This allows for careful usage of recursive SSI. + [André Malo] + + *) Fix memory leak in the cache handling of mod_rewrite. PR 27862. + [chunyan sheng , André Malo] + + *) Include directives no longer refuse to process symlinks on + directories. Instead there's now a maximum nesting level + of included directories (128 as distributed). This is configurable + at compile time using the -DAP_MAX_INCLUDE_DIR_DEPTH switch. + PR 28492. [André Malo] + + *) Win32: apache -k start|restart|install|config can leave stranded + piped logger processes (eg, rotatelogs.exe) due to improper + server shutdown on these code paths. + [Bill Stoddard] + + *) SECURITY: CAN-2004-0751 (cve.mitre.org) + mod_ssl: Fix a segfault in the SSL input filter which could be + triggered if using "speculative" mode, for instance by a + proxy request to an SSL server. PR 30134. [Joe Orton] + + *) mod_rewrite: Add %{SSL:...} and %{HTTPS} variable lookups. + PR 30464. [Joe Orton, Madhusudan Mathihalli] + + *) mod_ssl: Add new 'ssl_is_https' optional function. [Joe Orton] + + *) Prevent CGI script output which includes a Content-Range header + from being passed through the byterange filter. [Joe Orton] + + *) Satisfy directives now can be influenced by a surrounding + container. PR 14726. [André Malo] + + *) mod_rewrite now officially supports RewriteRules in sections. + PR 27985. [André Malo] + + *) mod_disk_cache: Implement binary format for on-disk header files. + [Brian Akins , Justin Erenkrantz] + + *) mod_disk_cache: Optimize network performance of disk cache subsystem by + allowing zero-copy (sendfile) writes and other miscellaneous fixes. + [Justin Erenkrantz] + + *) mod_cache, mod_disk_cache, mod_mem_cache: Refactor cache modules, and + switch to the provider API instead of hooks. [Justin Erenkrantz] + + *) mod_autoindex: Don't truncate the directory listing if a stat() + call fails (for instance on a >2Gb file). PR 17357. + [Joe Orton] + + *) Makefile fix: httpd is linked against LIBS given to the + 'make' invocation. PR 7882. [Joe Orton] + + *) WinNT MPM: Fix a broken log message at termination. PR 28063. + [Eider Oliveira ] + + *) Prevent Win32 pool corruption at startup [Allan Edwards] + + *) mod_ssl: Add "SSLUserName" directive to set r->user based on a + chosen SSL environment variable. PR 20957. + [Martin v. Loewis ] + + *) suexec: Pass the SERVER_SIGNATURE envvar through to CGIs. + [Zvi Har'El ] + + *) apachectl: Fix a problem finding envvars if sbindir != bindir. + PR 30723. [Friedrich Haubensak ] + + *) mod_ssl: Build on RHEL 3. PR 18989. [Justin Erenkrantz] + + *) SECURITY: CAN-2004-0748 (cve.mitre.org) + mod_ssl: Fix a potential infinite loop. PR 29964. [Joe Orton] + + *) mod_ssl: Avoid startup failure after unclean shutdown if using shmcb. + PR 18989. [Joe Orton] + + *) mod_userdir: Ensure that the userdir identity is used for + suexec userdir access in a virtual host which has suexec configured. + PR 18156. [Joshua Slive] + + *) mod_rewrite no longer confuses the RewriteMap caches if + different maps defined in different virtual hosts use the + same map name. PR 26462. [André Malo] + + *) mod_setenvif: Remove "support" for Remote_User variable which + never worked at all. PR 25725. [André Malo] + + *) Backport from 2.1 / Regression from 1.3: mod_headers now knows + again the functionality of the ErrorHeader directive. But instead + using this misnomer additional flags to the Header directive were + introduced ("always" and "onsuccess", defaulting to the latter). + PR 28657. [André Malo] + + *) Use the higher performing 'httpready' Accept Filter on all platforms + except FreeBSD < 4.1.1. [Paul Querna] + + *) mod_usertrack: Escape the cookie name before pasting into the + regexp. [André Malo] + + *) Extend the SetEnvIf directive to capture subexpressions of the + matched value. [André Malo] + + *) Recursive Include directives no longer crash. The server stops + including configuration files after a certain nesting level (128 + as distributed). This is configurable at compile time using the + -DAP_MAX_INCLUDE_DEPTH switch. PR 28370. [André Malo] + + *) mod_dir: the trailing-slash behaviour is now configurable using the + DirectorySlash directive. [André Malo] + + *) Allow proxying of resources that are invoked via DirectoryIndex. + PR 14648, 15112, 29961. [André Malo] + + *) util_ldap: Switched the lock types on the shared memory cache + from thread reader/writer locks to global mutexes in order to + provide cross process cache protection. [Brad Nicholes] + + *) util_ldap: Reworked the cache locking scheme to eliminate duplicate + cache entries in the credentials cache due to race conditions. + [Brad Nicholes] + + *) util_ldap: Enhanced the util_ldap cache-info display to show more + detail about the contents and current state of the cache. + [Brad Nicholes] + + *) Enable the option to support anonymous shared memory in mod_ldap. + This makes the cache work on Linux again. [Graham Leggett] + + *) Enable special ErrorDocument value 'default' which restores the + canned server response for the scope of the directive. + [Geoffrey Young, André Malo] + + *) work around MSIE Digest auth bug - if AuthDigestEnableQueryStringHack + is set in r->subprocess_env allow mismatched query strings to pass. + PR 27758. [Paul Querna, Geoffrey Young] + + *) Accept URLs for the ServerAdmin directive. If the supplied + argument is not recognized as an URL, assume it's a mail address. + PR 28174. [André Malo, Paul Querna] + + *) initialize server arrays prior to calling ap_setup_prelinked_modules + so that static modules can push Defines values when registering + hooks just like DSO modules can ["Philippe M. Chiasson" ] + + *) Small fix to allow reverse proxying to an ftp server. Previously + an attempt to do this would try and connect to 0.0.0.0, regardless + of the server specified. PR 24922 + [Pascal Terjan ] + + *) Add the NOTICE file to the rpm spec file in compliance with the + Apache v2.0 license. [Graham Leggett] + + *) RPM spec file changes: changed default dependancy to link to db4 + instead of db3. Fixed complaints about unpackaged files. + [Graham Leggett] + +Changes with Apache 2.0.50 + + *) SECURITY: CAN-2004-0493 (cve.mitre.org) + Close a denial of service vulnerability identified by Georgi + Guninski which could lead to memory exhaustion with certain + input data. [Jeff Trawick] + + *) mod_cgi: Handle output on stderr during script execution on Unix + platforms; preventing deadlock when stderr output fills pipe buffer. + Also fixes case where stderr from nph- scripts could be lost. + PR 22030, 18348. [Joe Orton, Jeff Trawick] + + *) mod_alias now emits a warning if it detects overlapping *Alias* + directives. [André Malo] + + *) mod_rewrite no longer turns forward proxy requests into reverse proxy + requests. PR 28125 [ast domdv.de, André Malo] + + *) ap_set_sub_req_protocol and ap_finalize_sub_req_protocol are now + exported on Win32 and Netware as well (minor MMN bump). PR 28523. + [Edward Rudd , André Malo] + + *) Restore the ability to disable the use of AcceptEx on Win9x systems + automatically (broken in 2.0.49). PR 28529. [André Malo] + + *) now applies to all IP addresses for myhost + instead of just the first one reported by the resolver. This + corrects a regression since 1.3. [Jeff Trawick] + + *) util_ldap: allow relative paths for LDAPTrustedCA to be resolved + against ServerRoot PR#26602 [Brad Nicholes] + + *) SECURITY: CAN-2004-0488 (cve.mitre.org) + mod_ssl: Fix a buffer overflow in the FakeBasicAuth code for a + (trusted) client certificate subject DN which exceeds 6K in length. + [Joe Orton] + + *) mod_dav_fs: Fix MKCOL response for missing parent collections, which + caused issues for the Eclipse WebDAV extension. + PR 29034. [Joe Orton] + + *) mod_deflate: Fix memory consumption (which was proportional to the + response size). PR 29318. [Joe Orton] + + *) mod_ssl: Log the errors returned on failure to load or initialize + a crypto accelerator engine. [Joe Orton] + + *) Allow RequestHeader directives to be conditional. PR 27951. + [Vincent Deffontaines , André Malo] + + *) Allow LimitRequestBody to be reset to unlimited. PR 29106 + [André Malo] + + *) Fix a bunch of cases where the return code of the regex compiler + was not checked properly. This affects: mod_setenvif, mod_usertrack, + mod_proxy, mod_proxy_ftp and core. PR 28218. [André Malo] + + *) mod_ssl: Fix a potential segfault in the 'shmcb' session cache for + small cache sizes. PR 27751. [Geoff Thorpe ] + + *) Remove 2Gb log file size restriction on some 32-bit platforms. + PR 13511. [Joe Orton] + + *) mod_logio no longer removes the EOS bucket. PR 27928. + [Bojan Smojver ] + + *) htpasswd no longer refuses to process files that contain empty + lines. [André Malo] + + *) Regression from 1.3: At startup, suexec now will be checked for + availability, the setuid bit and user root. The works only if + httpd is compiled with the shipped APR version (0.9.5). + PR 28287. [André Malo] + + *) Unix MPMs: Stop dropping connections when the file descriptor + is at least FD_SETSIZE. [Jeff Trawick] + + *) Fix handling of IPv6 numeric strings in mod_proxy. [Jeff Trawick] + + *) mod_isapi: send_response_header() failed to copy status string's + last character. PR 20619. [Jesse Pelton ] + + *) Fix a segfault when requests for shared memory fails and returns + NULL. Fix a segfault caused by a lack of bounds checking on the + cache. PR 24801. [Graham Leggett] + + *) Throw an error message if an attempt is made to use the LDAPTrustedCA + or LDAPTrustedCAType directives in a VirtualHost. PR 26390 + [Brad Nicholes] + + *) Fix a potential segfault if the bind password in the LDAP cache + is NULL. PR 28250. [Jari Ahonen ] + + *) Quotes cannot be used around require group and require dn + directives, update the documentation to reflect this. Also add + quotes around the dn and group within debug messages, to make it + more obvious why authentication is failing if quotes are used in + error. PR 19304. [Graham Leggett] + + *) The Microsoft LDAP SDK escapes filters for us, stop util_ldap + from escaping filters twice when the backslash character is used. + PR 24437. [Jess Holle ] + + *) Overhaul handling of LDAP error conditions, so that the util_ldap_* + functions leave the connections in a sane state after errors have + occurred. PR 27748, 17274, 17599, 18661, 21787, 24595, 24683, 27134, + 27271 [Graham Leggett] + + *) mod_ldap calls ldap_simple_bind_s() to validate the user + credentials. If the bind fails, the connection is left + in an unbound state. Make sure that the ldap connection + record is updated to show that the connection is no longer + bound. [Brad Nicholes] + + *) Ensure that lines in the request which are too long are + properly terminated before logging. + [Tsurutani Naoki ] + + *) Update the bind credentials for the cached LDAP connection to + reflect the last bind. This prevents util_ldap from creating + unnecessary connections rather than reusing cached connections. + [Brad Nicholes] + + *) mod_isapi: GetServerVariable returned improperly terminated header + fields given "ALL_HTTP" or "ALL_RAW". PR 20656. + [Jesse Pelton ] + + *) mod_isapi: GetServerVariable("ALL_RAW") returned the wrong buffer + size. PR 20617. [Jesse Pelton ] + + *) mod_dav: Fix a problem that could cause crashes when manipulating + locks on some platforms. [Jeff Trawick] + + *) mod_headers no longer crashes if an empty header value should + be added. [André Malo] + + *) Fix segfault in mod_expires, which occured under certain + circumstances. PR 28047. [André Malo] + + *) htpasswd: use apr_temp_dir_get() and general cleanup + [Guenter Knauf , Thom May] + + *) mod_ssl: Fix memory leak in session cache handling. PR 26562 + [Madhusudan Mathihalli] + + *) mod_ssl: Fix potential segfaults when performing SSL shutdown from + a pool cleanup. PR 27945. [Joe Orton] + + *) Add forensic logging module (mod_log_forensic). + [Ben Laurie] + + *) logresolve: Allow size of log line buffer to be overridden at + build time (MAXLINE). PR 27793. [Jeff Trawick] + + *) Fix the comment delimiter in htdbm so that it correctly parses the + username comment. Also add a terminate function to allow NetWare + to pause the output before the screen is destroyed. + [Guenter Knauf , Brad Nicholes] + + *) Fix crash when Apache was started with no Listen directives. + [Michael Corcoran ] + + *) core_output_filter: Fix bug that could result in sending + garbage over the network when module handlers construct + bucket brigades containing multiple file buckets all referencing + the same open file descriptor. [Bojan Smojver] + + *) Fix memory corruption problem with ap_custom_response() function. + The core per-dir config would later point to request pool data + that would be reused for different purposes on different requests. + [Jeff Trawick, based on an old 1.3 patch submitted by Will Lowe] + + *) Win32: Tweak worker thread accounting routines to eliminate + server hang when number of Listen directives in httpd.conf + is greater than or equal to the setting of ThreadsPerChild. + [Bill Stoddard] + +Changes with Apache 2.0.49 + + *) SECURITY: CAN-2004-0174 (cve.mitre.org) + Fix starvation issue on listening sockets where a short-lived + connection on a rarely-accessed listening socket will cause a + child to hold the accept mutex and block out new connections until + another connection arrives on that rarely-accessed listening socket. + With Apache 2.x there is no performance concern about enabling the + logic for platforms which don't need it, so it is enabled everywhere + except for Win32. [Jeff Trawick] + + *) mod_cgid: Fix storage corruption caused by use of incorrect pool. + [Jeff Trawick] + + *) Win32: find_read_listeners was not correctly handling multiple + listeners on the Win32DisableAcceptEx path. [Bill Stoddard] + + *) Fix bug in mod_usertrack when no CookieName is set. PR 24483. + [Manni Wood ] + + *) Fix some piped log problems: bogus "piped log program '(null)' + failed" messages during restart and problem with the logger + respawning again after Apache is stopped. PR 21648, PR 24805. + [Jeff Trawick] + + *) Fixed file extensions for real media files and removed rpm extension + from mime.types. PR 26079. [Allan Sandfeld ] + + *) Remove compile-time length limit on request strings. Length is + now enforced solely with the LimitRequestLine config directive. + [Paul J. Reder] + + *) mod_ssl: Send the Close Alert message to the peer before closing + the SSL session. PR 27428. [Madhusudan Mathihalli, Joe Orton] + + *) SECURITY: CVE-2004-0113 (cve.mitre.org) + mod_ssl: Fix a memory leak in plain-HTTP-on-SSL-port handling. + PR 27106. [Joe Orton] + + *) mod_ssl: Fix bug in passphrase handling which could cause spurious + failures in SSL functions later. PR 21160. [Joe Orton] + + *) mod_log_config: Fix corruption of buffered logs with threaded + MPMs. PR 25520. [Jeff Trawick] + + *) Fix mod_include's expression parser to recognize strings correctly + even if they start with an escaped token. [André Malo] + + *) Add fatal exception hook for use by diagnostic modules. The hook + is only available if the --enable-exception-hook configure parm + is used and the EnableExceptionHook directive has been set to + "on". [Jeff Trawick] + + *) Allow mod_auth_digest to work with sub-requests with different + methods than the original request. PR 25040. + [Josh Dady ] + + *) fix "Expected > but saw " errors in nested, + argumentless containers. + ["Philippe M. Chiasson" ] + + *) mod_auth_ldap: Fix some segfaults in the cache logic. PR 18756. + [Matthieu Estrade , Brad Nicholes] + + *) mod_cgid: Restart the cgid daemon if it crashes. PR 19849 + [Glenn Nielsen ] + + *) The whole codebase was relicensed and is now available under + the Apache License, Version 2.0 (http://www.apache.org/licenses). + [Apache Software Foundation] + + *) Fixed cache-removal order in mod_mem_cache. + [Jean-Jacques Clar, Cliff Woolley] + + *) mod_setenvif: Fix the regex optimizer, which under circumstances + treated the supplied regex as literal string. PR 24219. + [André Malo] + + *) ap_mpm.h: Fix include guard of ap_mpm.h to reference mpm + instead of mmn. [André Malo] + + *) mod_rewrite: Catch an edge case, where strange subsequent RewriteRules + could lead to a 400 (Bad Request) response. [André Malo] + + *) Keep focus of ITERATE and ITERATE2 on the current module when + the module chooses to return DECLINE_CMD for the directive. + PR 22299. [Geoffrey Young ] + + *) Add support for IMT minor-type wildcards (e.g., text/*) to + ExpiresByType. PR#7991 [Ken Coar] + + *) Fix segfault in mod_mem_cache cache_insert() due to cache size + becoming negative. PR: 21285, 21287 + [Bill Stoddard, Massimo Torquati, Jean-Jacques Clar] + + *) core.c: If large file support is enabled, allow any file that is + greater than AP_MAX_SENDFILE to be split into multiple buckets. + This allows Apache to send files that are greater than 2gig. + Otherwise we run into 32/64 bit type mismatches in the file size. + [Brad Nicholes] + + *) proxy_http fix: mod_proxy hangs when both KeepAlive and + ProxyErrorOverride are enabled, and a non-200 response without a + body is generated by the backend server. (e.g.: a client makes a + request containing the "If-Modified-Since" and "If-None-Match" + headers, to which the backend server respond with status 304.) + [Graham Wiseman , Richard Reiner] + + *) mod_dav: Reject requests which include an unescaped fragment in the + Request-URI. PR 21779. [Amit Athavale ] + + *) Build array of allowed methods with proper dimensions, fixing + possible memory corruption. [Jeff Trawick] + + *) mod_ssl: Fix potential segfault on lookup of SSL_SESSION_ID. + PR 15057. [Otmar Lendl ] + + *) mod_ssl: Fix streaming output from an nph- CGI script. PR 21944 + [Joe Orton] + + *) mod_usertrack no longer inspects the Cookie2 header for + the cookie name. PR 11475. [Chris Darrochi ] + + *) mod_usertrack no longer overwrites other cookies. + PR 26002. [Scott Moore ] + + *) worker MPM: fix stack overlay bug that could cause the parent + process to crash. [Jeff Trawick] + + *) Win32: Add Win32DisableAcceptEx directive. This Windows + NT/2000/CP directive is useful to work around bugs in some + third party layered service providers like virus scanners, + VPN and firewall products, that do not properly handle + WinSock 2 APIs. Use this directive if your server is issuing + AcceptEx failed messages. + [Allan Edwards, Bill Rowe, Bill Stoddard, Jeff Trawick] + + *) Make REMOTE_PORT variable available in mod_rewrite. + PR 25772. [André Malo] + + *) Fix a long delay with CGI requests and keepalive connections on + AIX. [Jeff Trawick] + + *) mod_autoindex: Add 'XHTML' option in order to allow switching between + HTML 3.2 and XHTML 1.0 output. PR 23747. [André Malo] + + *) Add XHTML Document Type Definitions to httpd.h (minor MMN bump). + [André Malo] + + *) mod_ssl: Advertise SSL library version as determined at run-time rather + than at compile-time. PR 23956. [Eric Seidel ] + + *) mod_ssl: Fix segfault on a non-SSL request if the 'c' log + format code is used. PR 22741. [Gary E. Miller ] + + *) Fix build with parallel make. PR 24643. [Joe Orton] + + *) mod_rewrite: In external rewrite maps lookup keys containing + a newline now cause a lookup failure. PR 14453. + [Cedric Gavage , André Malo] + + *) Backport major overhaul of mod_include's filter parser from 2.1. + The new parser code is expected to be more robust and should + catch all of the edge cases that were not handled by the previous one. + The 2.1 external API changes were hidden by a wrapper which is + expected to keep the API backwards compatible. [André Malo] + + *) Add a hook (insert_error_filter) to allow filters to re-insert + themselves during processing of error responses. Enable mod_expires + to use the new hook to include Expires headers in valid error + responses. This addresses an RFC violation. It fixes PRs 19794, + 24884, and 25123. [Paul J. Reder] + + *) Add Polish translation of error messages. PR 25101. + [Tomasz Kepczynski ] + + *) Add AP_MPMQ_MPM_STATE function code for ap_mpm_query. (Not yet + supported for BeOS or OS/2 MPMs.) [Jeff Trawick, Brad Nicholes, + Bill Stoddard] + + *) Add mod_status hook to allow modules to add to the mod_status + report. [Joe Orton] + + *) Fix htdbm to generate comment fields in DBM files correctly. + [Justin Erenkrantz] + + *) mod_dav: Use bucket brigades when reading PUT data. This avoids + problems if the data stream is modified by an input filter. PR 22104. + [Tim Robbins , André Malo] + + *) Fix RewriteBase directive to not add double slashes. [André Malo] + + *) Improve 'configure --help' output for some modules. [Astrid Keßler] + + *) Correct UseCanonicalName Off to properly check incoming port number. + [Jim Jagielski] + + *) Fix slow graceful restarts with prefork MPM. [Joe Orton] + + *) Fix a problem with namespace mappings being dropped in mod_dav_fs; + if any property values were set which defined namespaces these + came out mangled in the PROPFIND response. PR 11637. + [Amit Athavale ] + + *) mod_dav: Return a WWW-auth header for MOVE/COPY requests where + the destination resource gives a 401. PR 15571. [Joe Orton] + + *) SECURITY: CVE-2003-0020 (cve.mitre.org) + Escape arbitrary data before writing into the errorlog. Unescaped + errorlogs are still possible using the compile time switch + "-DAP_UNSAFE_ERROR_LOG_UNESCAPED". [Geoffrey Young, André Malo] + + *) mod_autoindex / core: Don't fail to show filenames containing + special characters like '%'. PR 13598. [André Malo] + + *) mod_status: Report total CPU time accurately when using a threaded + MPM. PR 23795. [Jeff Trawick] + + *) Fix memory leak in handling of request bodies during reverse + proxy operations. PR 24991. [Larry Toppi ] + + *) Win32 MPM: Implement MaxMemFree to enable setting an upper + limit on the amount of storage used by the bucket brigades + in each server thread. [Bill Stoddard] + + *) Modified the cache code to be header-location agnostic. Also + fixed a number of other cache code bugs related to PR 15852. + Includes a patch submitted by Sushma Rai . + This fixes mod_mem_cache but not mod_disk_cache yet so I'm not + closing the PR since that is what they are using. [Paul J. Reder] + + *) complain via error_log when mod_include's INCLUDES filter is + enabled, but the relevant Options flag allowing the filter to run + for the specific resource wasn't set, so that the filter won't + silently get skipped. next remove itself, so the warning will be + logged only once [Stas Bekman, Jeff Trawick, Bill Rowe] + + *) mod_info: HTML escape configuration information so it displays + correctly. PR 24232. [Thom May] + + *) Restore the ability to add a description for directories that + don't contain an index file. (Broken in 2.0.48) [André Malo] + + *) Fix a problem with the display of empty variables ("SetEnv foo") in + mod_include. PR 24734 [Markus Julen ] + + *) mod_log_config: Log the minutes component of the timezone correctly. + PR 23642. [Hong-Gunn Chew ] + + *) mod_proxy: Fix cases where an invalid status-line could be sent + to the client. PR 23998. [Joe Orton] + + *) mod_ssl: Fix segfaults at startup if other modules which use OpenSSL + are also loaded. [Joe Orton] + + *) mod_ssl: Use human-readable OpenSSL error strings in logs; use + thread-safe interface for retrieving error strings. [Joe Orton] + + *) mod_expires: Initialize ExpiresDefault to NULL instead of "" to + avoid reporting an Internal Server error if it is used without + having been set in the httpd.conf file. PR: 23748, 24459 + [Andre Malo, Liam Quinn ] + + *) mod_autoindex: Don't omit the start tag if the SuppressIcon + option is set. PR 21668. [Jesse Tie-Ten-Quee ] + + *) mod_include no longer allows an ETag header on 304 responses. + PR 19355. [Geoffrey Young , André Malo] + + *) EBCDIC: Convert header fields to ASCII before sending (broken + since 2.0.44). [Martin Kraemer] + + *) Fix the inability to log errors like exec failure in + mod_ext_filter/mod_cgi script children. This was broken after + such children stopped inheriting the error log handle. + [Jeff Trawick] + + *) Fix mod_info to use the real config file name, not the default + config file name. [Aryeh Katz ] + + *) Set the scoreboard state to indicate logging prior to running + logging hooks so that server-status will show 'L' for hung loggers + instead of 'W'. [Jeff Trawick] + +Changes with Apache 2.0.48 + + *) SECURITY: CAN-2003-0789 (cve.mitre.org) + mod_cgid: Resolve some mishandling of the AF_UNIX socket used to + communicate with the cgid daemon and the CGI script. + [Jeff Trawick] + + *) SECURITY: CAN-2003-0542 (cve.mitre.org) + Fix buffer overflows in mod_alias and mod_rewrite which occurred + if one configured a regular expression with more than 9 captures. + [André Malo] + + *) mod_include: fix segfault which occured if the filename was not + set, for example, when processing some error conditions. + PR 23836. [Brian Akins , André Malo] + + *) fix the config parser to support .. containers (no + arguments in the opening tag) supported by httpd 1.3. Without + this change mod_perl 2.0's sections are broken. + ["Philippe M. Chiasson" ] + + *) mod_cgid: fix a hash table corruption problem which could + result in the wrong script being cleaned up at the end of a + request. [Jeff Trawick] + + *) Update httpd-*.conf to be clearer in describing the connection + between AddType and AddEncoding for defining the meaning of + compressed file extensions. [Roy Fielding] + + *) mod_rewrite: Don't die silently when failing to open RewriteLogs. + PR 23416. [André Malo] + + *) mod_rewrite: Fix mod_rewrite's support of the [P] option to send + rewritten request using "proxy:". The code was adding multiple "proxy:" + fields in the rewritten URI. PR: 13946. + [Eider Oliveira ] + + *) cache_util: Fix ap_check_cache_freshness to check max_age, smax_age, and + expires as directed in RFC 2616. [Thomas Castelle ] + + *) Ensure that ssl-std.conf is generated at configure time, and switch + to using the expanded config variables to work the same as + httpd-std.conf PR: 19611 + [Thom May] + + *) mod_ssl: Fix segfaults after renegotiation failure. PR 21370 + [Hartmut Keil ] + + *) mod_autoindex: If a directory contains a file listed in the + DirectoryIndex directive, the folder icon is no longer replaced + by the icon of that file. PR 9587. + [David Shane Holden ] + + *) Fixed mod_usertrack to not get false positive matches on the + user-tracking cookie's name. PR 16661. + [Manni Wood ] + + *) mod_cache: Fix the cache code so that responses can be cached + if they have an Expires header but no Etag or Last-Modified + headers. PR 23130. + [] + + *) mod_log_config: Fix %b log format to write really "-" when 0 bytes + were sent (e.g. with 304 or 204 response codes). [Astrid Keßler] + + *) Modify ap_get_client_block() to note if it has seen EOS. + [Justin Erenkrantz] + + *) Fix a bug, where mod_deflate sometimes unconditionally compressed the + content if the Accept-Encoding header contained only other tokens than + "gzip" (such as "deflate"). PR 21523. [Joe Orton, André Malo] + + *) Avoid an infinite recursion, which occured if the name of an included + config file or directory contained a wildcard character. PR 22194. + [André Malo] + + *) mod_ssl: Fix a problem setting variables that represent the + client certificate chain. PR 21371 [Jeff Trawick] + + *) Unix: Handle permissions settings for flock-based mutexes in + unixd_set_global|proc_mutex_perms(). Allow the functions to be + called for any type of mutex. PR 20312 [Jeff Trawick] + + *) ab: Work over non-loopback on Unix again. PR 21495. [Jeff Trawick] + + *) Fix a misleading message from the some of the threaded MPMs when + MaxClients has to be lowered due to the setting of ServerLimit. + [Jeff Trawick] + + *) Lower the severity of the "listener thread didn't exit" message + to debug, as it is of interest only to developers. PR 9011 + [Jeff Trawick] + + *) MPMs: The bucket brigades subsystem now honors the MaxMemFree setting. + [Cliff Woolley, Jean-Jacques Clar] + + *) Install config.nice into the build/ directory to make + minor version upgrades easier. [Joshua Slive] + + *) Fix mod_deflate so that it does not call deflate() without checking + first whether it has something to deflate. (Currently this causes + deflate to generate a fatal error according to the zlib spec.) + PR 22259. [Stas Bekman] + + *) mod_ssl: Fix FakeBasicAuth for subrequest. Log an error when an + identity spoof is encountered. + [Sander Striker] + + *) mod_rewrite: Ignore RewriteRules in .htaccess files if the directory + containing the .htaccess file is requested without a trailing slash. + PR 20195. [André Malo] + + *) ab: Overlong credentials given via command line no longer clobber + the buffer. [André Malo] + + *) mod_deflate: Don't attempt to hold all of the response until we're + done. [Justin Erenkrantz] + + *) Assure that we block properly when reading input bodies with SSL. + PR 19242. [David Deaves , William Rowe] + + *) Update mime.types to include latest IANA and W3C types. [Roy Fielding] + + *) mod_ext_filter: Set additional environment variables for use by + the external filter. PR 20944. [Andrew Ho, Jeff Trawick] + + *) Fix buildconf errors when libtool version changes. [Jeff Trawick] + + *) Remember an authenticated user during internal redirects if the + redirection target is not access protected and pass it + to scripts using the REDIRECT_REMOTE_USER environment variable. + PR 10678, 11602. [André Malo] + + *) mod_include: Fix a trio of bugs that would cause various unusual + sequences of parsed bytes to omit portions of the output stream. + PR 21095. [Ron Park , André Malo, Cliff Woolley] + + *) Update the header token parsing code to allow LWS between the + token word and the ':' seperator. [PR 16520] + [Kris Verbeeck , Nicel KM ] + + *) Eliminate creation of a temporary table in ap_get_mime_headers_core() + [Joe Schaefer ] + + *) Added FreeBSD directory layout. PR 21100. + [Sander Holthaus , André Malo] + + *) Fix NULL-pointer issue in ab when parsing an incomplete or non-HTTP + response. PR 21085. [Glenn Nielsen , André Malo] + + *) mod_rewrite: Perform child initialization on the rewrite log lock. + This fixes a log corruption issue when flock-based serialization + is used (e.g., FreeBSD). [Jeff Trawick] + + *) Don't respect the Server header field as set by modules and CGIs. + As with 1.3, for proxy requests any such field is from the origin + server; otherwise it will have our server info as controlled by + the ServerTokens directive. [Jeff Trawick] + +Changes with Apache 2.0.47 + + *) SECURITY: CAN-2003-0192 (cve.mitre.org) + Fixed a bug whereby certain sequences of per-directory + renegotiations and the SSLCipherSuite directive being used to + upgrade from a weak ciphersuite to a strong one could result in + the weak ciphersuite being used in place of the strong one. + [Ben Laurie] + + *) SECURITY: CAN-2003-0253 (cve.mitre.org) + Fixed a bug in prefork MPM causing temporary denial of service + when accept() on a rarely accessed port returns certain errors. + Reported by Saheed Akhtar . [Jeff Trawick] + + *) SECURITY: CAN-2003-0254 (cve.mitre.org) + Fixed a bug in ftp proxy causing denial of service when target + host is IPv6 but proxy server can't create IPv6 socket. Fixed by + the reporter. [Yoshioka Tsuneo ] + + *) SECURITY [VU#379828] Prevent the server from crashing when entering + infinite loops. The new LimitInternalRecursion directive configures + limits of subsequent internal redirects and nested subrequests, after + which the request will be aborted. PR 19753 (and probably others). + [William Rowe, Jeff Trawick, André Malo] + + *) core_output_filter: don't split the brigade after a FLUSH bucket if + it's the last bucket. This prevents creating unneccessary empty + brigades which may not be destroyed until the end of a keepalive + connection. + [Juan Rivera ] + + *) Add support for "streamy" PROPFIND responses. + [Ben Collins-Sussman ] + + *) mod_cgid: Eliminate a double-close of a socket. This resolves + various operational problems in a threaded MPM, since on the + second attempt to close the socket, the same descriptor was + often already in use by another thread for another purpose. + [Jeff Trawick] + + *) mod_negotiation: Introduce "prefer-language" environment variable, + which allows to influence the negotiation process on request basis + to prefer a certain language. [André Malo] + + *) Make mod_expires' ExpiresByType work properly, including for + dynamically-generated documents. [Ken Coar, Bill Stoddard] + +Changes with Apache 2.0.46 + + *) SECURITY: CAN-2003-0245 (cve.mitre.org) + Fixed a bug causing apr_pvsprintf() to crash by sending an overly + long string. This can be triggered remotely through mod_dav, + mod_ssl, and other mechanisms. + Reported by David Endler . [Joe Orton] + + *) SECURITY: CAN-2003-0189 (cve.mitre.org) + Fixed a denial-of-service vulnerability affecting basic + authentication on Unix platforms related to thread-safety in + apr_password_validate(). + Reported by John Hughes . + + *) Fix for mod_dav. Call the 'can_be_activity' callback, if provided, + when a MKACTIVITY request comes in. + [Ben Collins-Sussman ] + + *) Perform run-time query in apxs for apr and apr-util's includes. + [Justin Erenkrantz] + + *) run libtool from the apr install directory (in case that is different + from the apache install directory) [Jeff Trawick] + + *) configure.in: Play nice with libtool-1.5. [Wilfredo Sanchez] + + *) If mod_mime_magic does not know the content-type, do not attempt to + guess. PR 16908. [Andrew Gapon ] + + *) ssl session caching(shmht) : Fix a SEGV problem with SHMHT session + caching. PR 17864. + [Andreas Leimbacher , Madhusudan Mathihalli] + + *) Add a delete flag to htpasswd. + [Thom May] + + *) Fix mod_rewrite's handling of absolute URIs. The escaping routines + now work scheme dependent and the query string will only be + appended if supported by the particular scheme. [André Malo] + + *) Add another check for already compressed content in mod_deflate. + PR 19913. [Tsuyoshi SASAMOTO ] + + *) Fixes for VPATH builds; copying special.mk and any future .mk files + from the source tree as well as the build tree (now creates a usable + configuration for apxs), and eliminated redundant -I'nclude paths. + [William Rowe] + + *) Code fixes, constness corrections and ssl_toolkit_compat.h updates + for SSLC and OpenSSL toolkit compatibility. Still work remains to + be done to cripple features based on the limitations of RSA's binary + distribution of their SSL-C toolkit. + [William Rowe, Madhusudan Mathihalli, Jeff Trawick] + + *) Linux 2.4+: If Apache is started as root and you code + CoreDumpDirectory, coredumps are enabled via the prctl() syscall. + [Greg Ames] + + *) ap_get_mime_headers_core: allocate space for the trailing null + when folding is in effect. + PR 18170 [Peter Mayne ] + + *) Fix --enable-mods-shared=most and other variants. [Aaron Bannert] + + *) mod_log_config: Add the ability to log the id of the thread + processing the request via new %P formats. [Jeff Trawick] + + *) Use appropriate language codes for Czech (cs) and Traditional Chinese + (zh-tw) in default config files. PR 9427. [André Malo] + + *) mod_auth_ldap: Use generic whitespace character class when parsing + "require" directives, instead of literal spaces only. PR 17135. + [André Malo] + + *) Hook mod_rewrite's type checker before mod_mime's one. That way the + RewriteRule [T=...] Flag should work as expected now. PR 19626. + [André Malo] + + *) htpasswd: Check the processed file on validity. If a line is not empty + and not a comment, it must contain at least one colon. Otherwise exit + with error code 7. [Kris Verbeeck , Thom May] + + *) Fix a problem that caused httpd to be linked with incorrect flags + on some platforms when mod_so was enabled by default, breaking + DSOs on AIX. PR 19012 [Jeff Trawick] + + *) By default, use the same CC and CPP with which APR was built. + The user can override with CC and CPP environment variables. + [Jeff Trawick] + + *) Fix ap_construct_url() so that it surrounds IPv6 literal address + strings with []. This fixes certain types of redirection. + PR 19207. [Jeff Trawick] + + *) forward port of buffer overflow fixes for htdigest. [Thom May] + + *) Added AllowEncodedSlashes directive to permit control of whether + the server will accept encoded slashes ('%2f') in the URI path. + Default condition is off (the historical behaviour). This permits + environments in which the path-info needs to contain encoded + slashes. PR 543, 2389, 3581, 3589, 5687, 7066, 7865, 14639. [Ken Coar] + + *) When using Redirect in directory context, append requested query + string if there's no one supplied by configuration. PR 10961. + [André Malo] + + *) Unescape the supplied wildcard pattern in mod_autoindex. Otherwise + the pattern will not always match as desired. PR 12596. + [André Malo] + + *) mod_autoindex now emits and accepts modern query string parameter + delimiters (;). Thus column headers no longer contain unescaped + ampersands. PR 10880 [André Malo] + + *) Enable ap_sock_disable_nagle for Windows. This along with the + addition of APR_TCP_NODELAY_INHERITED to apr.hw will cause Nagle + to be disabled for Windows. [Allan Edwards] + + *) Correct a mis-correlation between mpm_common.c and mpm_common.h; + This patch reverts us to pre-2.0.46 behavior, using the + ap_sock_disable_nagle noop macro, because ap_sock_disable_nagle + was never compiled on Win32. [Allan Edwards, William Rowe] + + *) Fix a build problem with passing unsupported --enable-layout + args to apr and apr-util. This broke binbuild.sh as well as + user-specified layout parameters. PR 18649 [Justin Erenkrantz, + Jeff Trawick] + + *) If a Date response header was already set in the headers array, + this value was ignored in favour of the current time. This meant + that Date headers on proxied requests where rewritten when they + should not have been. PR: 14376 [Graham Leggett] + + *) Add code to buildconf that produces an httpd.spec file from + httpd.spec.in, using build/get-version.sh from APR. + [Graham Leggett] + + *) Fixed a segfault when multiple ProxyBlock directives were used. + PR: 19023 [Sami Tikka ] + + *) SECURITY: CAN-2003-0134 (cve.mitre.org) + OS2: Fix a Denial of Service vulnerability identified and + reported by Robert Howard that where device + names faulted the running OS2 worker process. The fix is + actually in APR 0.9.4. [Brian Havard] + + *) Forward port: Escape special characters (especially control + characters) in mod_log_config to make a clear distinction between + client-supplied strings (with special characters) and server-side + strings. This was already introduced in version 1.3.25. + [André Malo] + + *) mod_deflate: Check also err_headers_out for an already set + Content-Encoding: gzip header. This prevents gzip compressed content + from a CGI script from being compressed once more. PR 17797. + [André Malo] + +Changes with Apache 2.0.45 + + *) Fix possible segfaults under obscure error conditions within the + cgid daemon. [Jeff Trawick, William Rowe] + + *) SECURITY: CAN-2003-0132 (cve.mitre.org) + Close a Denial of Service vulnerability identified by David + Endler on all platforms. An unlimited + stream of newlines were acceptable between requests where each + would allocate an 80 byte buffer, leading very quickly to + memory exahustion. [Brian Pane] + + *) Added an rpm build script. + [Graham Leggett, Joe Orton ] + + *) Simpler, faster code path for request header scanning [Brian Pane] + + *) SECURITY: Eliminated leaks of several file descriptors to child + processes, such as CGI scripts. This fix depends on the APR library + release 0.9.2 or later (0.9.3 was distributed with the httpd + source tarball for Apache 2.0.45.) PR 17206 + [Christian Kratzer , Bjoern A. Zeeb ] + + *) Fix path handling of mod_rewrite, especially on non-unix systems. + There was some confusion between local paths and URL paths. + PR 12902. [André Malo] + + *) Prevent endless loops of internal redirects in mod_rewrite by + aborting after exceeding a limit of internal redirects. The + limit defaults to 10 and can be changed using the RewriteOptions + directive. PR 17462. [André Malo] + + *) Win32: Avoid busy wait (consuming all the CPU idle cycles) when + all worker threads are busy. + [Igor Nazarenko ] + + *) Keep the subrequest filter in place when a subrequest is + redirected. PR 15423. [Jeff Trawick] + + *) you can now specify the compression level for mod_deflate. + [Ian Holsman, Stephen Pierzchala , + Michael Schroepl ] + + *) mod_deflate: Extend the DeflateFilterNote directive to + allow accurate logging of the filter's in- and outstream. + [André Malo] + + *) Allow SSLMutex to select/use the full range of APR locking + mechanisms available to it. Also, fix the bug that SSLMutex uses + APR_LOCK_DEFAULT no matter what. PR 8122 [Jim Jagielski, + Martin Kutschker ] + + *) Restore the ability of htdigest.exe to create files that contain + more than one user. PR 12910. [André Malo] + + *) Improve binary compatibility of the core between debug (aka + maintainer-mode) and a non-debug compile. + [Sander Striker] + + *) mod_usertrack: don't set the cookie in subrequests. This works + around the problem that cookies were set twice during fast internal + redirects. PR 13211. [André Malo] + + *) mod_autoindex no longer forgets output format and enabled version + sort in linked column headers. [André Malo] + + *) Use .sv instead of .se as extension for Swedish documents in the + default configuration. PR 12877. [André Malo] + + *) Updated mod_ldap and mod_auth_ldap to support the Novell LDAP SDK SSL + and standardized the LDAP SSL support across the various LDAP SDKs. + Isolated the SSL functionality to mod_ldap rather than speading it + across mod_auth_ldap and mod_ldap. Also added LDAPTrustedCA + and LDAPTrustedCAType directives to mod_ldap to allow for a more + common method of specifying the SSL certificate. + [Dave Ward, Brad Nicholes] + + *) Fixed mod_ssl's SSLCertificateChain initialization to no longer + skip the first cert of the chain by default. This misbehavior + was introduced in 2.0.34. PR 14560 [Madhusudan Mathihalli] + + *) mod_cgi, mod_cgid, mod_ext_filter: Log errors when scripts cannot + be started on Unix because of such problems as bad permissions, + bad shebang line, etc. [Jeff Trawick] + + *) Fix 64-bit problem in mod_ssl input logic. + [Madhusudan Mathihalli ] + + *) Fix potential memory leaks in mod_deflate on malformed data. PR 16046. + [Justin Erenkrantz] + + *) Rewrite ap_xml_parse_input to use bucket brigades. PR 16134. + [Justin Erenkrantz] + + *) Fix segfault which occurred when a section in an included + configuration file was not closed. PR 17093. [André Malo] + + *) Enhance the behavior of mod_isapi's WriteClient() callback to + provide better emulation for isapi modules that presume that the + first WriteClient() call may send status and headers. An example + of WriteClient() abuse is the foxisapi module, which relies on + that assumpion and now works. [William Rowe, Milan Kosina] + + *) Check the return value of ap_run_pre_connection(). So if the + pre_connection phase fails (without setting c->aborted) + ap_run_process_connection is not executed. [Stas Bekman] + + *) Fixed a problem with mod_ldap which caused it to fault when caching + was disabled. Needed to make sure that the code did not + attempt to use the cache if it didn't exist. Also fixed some memory + leaks which were due to not releasing LDAP resources on error + conditions. [Brad Nicholes] + + *) Hook mod_proxy's fixup before mod_rewrite's fixup, so that by + mod_rewrite proxied URLs will not be escaped accidentally by + mod_proxy's fixup. PR 16368 [André Malo] + + *) While processing filters on internal redirects, remember seen EOS + buckets also in the request structure of the redirect issuer(s). This + prevents filters (such as mod_deflate) from adding garbage to the + response. PR 14451. [André Malo] + + *) suexec: Be more pedantic when cleaning environment. Clean it + immediately after startup. PR 2790, 10449. + [Jeff Stewart , André Malo] + + *) Fix apxs to insert LoadModule directives only outside of sections. + PR 8712, 9012. [André Malo] + + *) Fix suexec compile error under SUNOS4, where strerror() doesn't + exist. PR 5913, 9977. + [Jonathan W Miner ] + + *) Fix If header parsing when a non-mod_dav lock token is passed to it. + PR 16452. [Justin Erenkrantz] + + *) mod_auth_digest no longer tries to guess AuthDigestDomain, if it's + not specified. Now it assumes "/" as already documented. PR 16937. + [André Malo] + + *) Try to log an error if a piped log program fails. Try to + restart a piped log program in more failure situations. Fix an + existing problem with error handling in piped_log_spawn(). Use + new APR apr_proc_create() features to prevent Apache from starting + on Unix* in most cases where a piped log program can be started, + and add log messages for the other situations. *Other platforms + already failed Apache initialization if a piped log program + couldn't be started. PR 15761 [Jeff Trawick] + + *) Fix mod_cern_meta to not create empty metafiles when the + metafile searched for does not exist. PR 12353 + [Owen Rees ] + + *) Introduce debugging symbols for Win32 release builds, both .pdb + and .dbg files (older debuggers and Dr. Watson-type utilities + on WinNT or Win9x don't support the newer .pdb flavor.) + [Allen Edwards, William Rowe] + + *) Fix bug where 'Satisfy Any' without an AuthType lost all MIME + information (and more). Related to PR 9076. [André Malo] + + *) mod_file_cache: fix segfault serving mmaped cached files. + [Bill Stoddard] + + *) mod_file_cache: fixed a segfault when multiple MMapFile directives + were used. PR 16313. [Cliff Woolley] + + *) Fix a nasty segfault in mmap_bucket_setaside() caused by passing + an incompatible pointer type to mmap_bucket_destroy(void*). + [Gerard Eviston ] + + *) Enable the -n name parameter on NetWare to allow the + administrator to rename the Apache console screen + [Brad Nicholes] + + *) Fixed piped access logs on Win32 by disabling OTHER_CHILD + support by default in APR. More development is required + to deploy OTHER_CHILD on Win32. [William Rowe] + + *) Use saner default config values for suexec. PR 15713. + [Thom May ] + + *) mod_rewrite: Allow "RewriteEngine Off" even if no "Options FollowSymlinks" + (or SymlinksIfOwnermatch) is set. PR 12395. [André Malo] + + *) apxs: Include any special APR ld flags when linking the DSO. + This resolves problems on AIX when building a DSO with apxs+gcc. + [Jeff Trawick] + + *) Added character set support to mod_auth_LDAP to allow it to + convert extended characters used in the user ID to UTF-8 + before authenticating against the LDAP directory. The new + directive AuthLDAPCharsetConfig is used to specify the config + file that contains the character set conversion table. + [Brad Nicholes] + + *) Don't remove the Content-Length from responses in mod_proxy + PR: 8677 [Brian Pane] + + *) Ensure LDAP version is set to v3 on every bind. PR 14235. + [Sergey A. Lipnevich ] + + *) Fix mod_ldap to open an existing shared memory file should one + already exist. PR 12757. [Scooter Morris , + Graham Leggett] + + *) Fix the ulimit command used by apachectl on Tru64. PR 13609. + [Joseph Senulis , Jeff Trawick] + + *) Change the ulimit command used by apachectl on AIX so that it + works in all locales. [Jeff Trawick] + + *) mod_ext_filter: Fix a problem building argument lists which + occasionally caused exec to fail. PR 15491. [Jeff Trawick] + +Changes with Apache 2.0.44 + + *) mod_autoindex: Bring forward the IndexOptions IgnoreCase option + from Apache 1.3. PR 14276 + [David Shane Holden , William Rowe] + + *) mod_mime: Workaround to prevent a segfault if r->filename=NULL + [Brian Pane] + + *) Reorder the definitions for mod_ldap and mod_auth_ldap within + config.m4 to make sure the parent mod_ldap is defined first. + This ensures that mod_ldap comes before mod_auth_ldap in the + httpd.conf file, which is necessary for mod_auth_ldap to load. + PR 14256 [Graham Leggett] + + *) Fix the building of cgi command lines when the query string + contains '='. PR 13914 [Ville Skyttä , + Jeff Trawick] + + *) Rename CacheMaxStreamingBuffer to MCacheMaxStreamingBuffer. Move + implementation of MCacheMaxStreamingBuffer from mod_cache to + mod_mem_cache. MCacheMaxStreamingBuffer now defaults to the + lesser of 100,000 bytes or MCacheMaxCacheObjectSize. This should + eliminate the need for explicitly coding MCacheMaxStreamingBuffer + in most configurations. [Bill Stoddard] + + *) mod_cache: Fix PR 15113, a core dump in cache_in_filter when + a redirect occurs. The code was passing a format string and + integer to apr_pstrcat. Changed to apr_psprintf. + [Paul J. Reder] + + *) Replace APU_HAS_LDAPSSL_CLIENT_INIT with APU_HAS_LDAP_NETSCAPE_SSL + as set by apr-util in util_ldap.c. This should allow mod_ldap + to work with the Netscape/Mozilla LDAP library. [Øyvin Sømme + , Graham Leggett] + + *) Fix critical bug in new --enable-v4-mapped configure option + implementation which broke IPv4 listening sockets on some + systems. [hiroyuki hanai ] + + *) mod_setenvif: Fix BrowserMatchNoCase support for non-regex + patterns [André Malo ] + + *) Add version string to provider API. [Justin Erenkrantz] + + *) build: './configure && make' now works without an in-tree + apr and apr-util. [Wilfredo Sanchez] + + *) mod_negotiation: Set the appropriate mime response headers + (Content-Type, charset, Content-Language and Content-Encoding) + for negotated type-map "Body:" responses (such as the error + pages.) [André Malo ] + + *) mod_log_config: Allow '%%' escaping in CustomLog format + strings to insert a literal, single '%'. + [André Malo ] + + *) mod_autoindex: AddDescription directives for directories + now work as in Apache 1.3, where no trailing '/' is + specified on the directory name. Previously, the trailing + '/' *had* to be specified, which was incompatible with + Apache 1.3. PR 7990 [Jeff Trawick] + + *) Fix for PR 14556. The expiry calculations in mod_cache were + trying to perform "now + ((date - lastmod) * factor)" where + date == lastmod resulting in "now + 0". The code now follows + the else path (using the default expiration) if date is + equal to lastmod. [Sergey , Paul J. Reder] + + *) Use AP_DECLARE in the debug versions of ap_strXXX in case the + default calling convention is not the same as the one used by + AP_DECLARE. [Juan Rivera ] + + *) mod_cache: Don't cache response header fields designated + as hop-by-hop headers in HTTP/1.1 (RFC 2616 Section 13.5.1). + [Estrade Matthieu , Brian Pane] + + *) mod_cgid: Handle environment variables containing newlines. + PR 14550 [Piotr Czejkowski , Jeff + Trawick] + + *) Move mod_ext_filter out of experimental and into filters. + [Jeff Trawick] + + *) Fixed a memory leak in mod_deflate with dynamic content. + PR 14321 [Ken Franken ] + + *) Add --[enable|disable]-v4-mapped configure option to control + whether or not Apache expects to handle IPv4 connections + on IPv6 listening sockets. Either setting will work on + systems with the IPV6_V6ONLY socket option. --enable-v4-mapped + must be used on systems that always allow IPv4 connections on + IPv6 listening sockets. PR 14037 (Bugzilla), PR 7492 (Gnats) + [Jeff Trawick] + + *) This fixes a problem where the underlying cache code + indicated that there was one more element on the cache + than there actually was. This happened since element 0 + exists but is not used. This code allocates the correct + number of useable elements and reports the number of + actually used elements. The previous code only allowed + MCacheMaxObjectCount-1 objects to be stored in the + cache. [Paul J. Reder] + + *) mod_setenvif: Add SERVER_ADDR special keyword to allow + envariable setting according to the server IP address + which received the request. [Ken Coar] + + *) mod_cgid: Terminate CGI scripts when the client connection + drops. PR 8388 [Jeff Trawick] + + *) Rearrange OpenSSL engine initialization to support RAND + redirection on crypto accelerator. + [Frederic DONNAT ] + + *) Always emit Vary header if mod_deflate is involved in the + request. [Andre Malo ] + + *) mod_isapi: Stop unsetting the 'empty' query string result with + a NULL argument in ecb->lpszQueryString, eliminating segfaults + for some ISAPI modules. PR 14399 + [Detlev Vendt ] + + *) mod_isapi: Fix an issue where the HSE_REQ_DONE_WITH_SESSION + notification is received before the HttpExtensionProc() returns + HSE_STATUS_PENDING. This only affected isapi .dll's configured + with the ISAPIFakeAsync on directive. PR 11918 + [John DeSetto , William Rowe] + + *) mod_isapi: Fix the issue where all results from mod_isapi would + run through the core die handler resulting in invalid responses + or access log entries. PR 10216 [William Rowe] + + *) Improves the user friendliness of the CacheRoot processing + over my last pass. This version avoids the pool allocations + but doesn't avoid all of the runtime checks. It no longer + terminates during post-config processing. An error is logged + once per worker, indicating that the CacheRoot needs to be set. + [Paul J. Reder] + + *) Fix a bug where we keep files open until the end of a + keepalive connection, which can result in: + (24)Too many open files: file permissions deny server access + especially on threaded servers. [Greg Ames, Jeff Trawick] + + *) Fix a bug in which mod_proxy sent an invalid Content-Length + when a proxied URL was invoked as a server-side include within + a page generated in response to a form POST. [Brian Pane] + + *) Added code to process min and max file size directives and to + init the expirychk flag in mod_disk_cache. Added a clarifying + comment to cache_util. [Paul J. Reder] + + *) The value emitted by ServerSignature now mimics the Server HTTP + header as controlled by ServerTokens. [Francis Daly ] + + *) Gracefully handly retry situations in the SSL input filter, + by following the SSL libraries' retry semantics. + [William Rowe] + + *) Terminate CGI scripts when the client connection drops. This + fix only applies to some normal paths in mod_cgi. mod_cgid + is still busted. PR 8388 [Jeff Trawick] + + *) Fix a bug where 416 "Range not satisfiable" was being + returned for content that should have been redirected. + [Greg Ames] + + *) Fix memory leak in mod_ssl from internal SSL library allocations + within SSL_get_peer_certificate and X509_get_pubkey. + [Zvi Har'El + Madhusudan Mathihalli ]. + + *) mod_ssl uses free() inappropriately in several places, to free + memory which has been previously allocated inside OpenSSL. + Such memory should be freed with OPENSSL_free(), not with free(). + [Nadav Har'El , + Madhusudan Mathihalli ]. + + *) Emit a message to the error log when we return 404 because + the URI contained '%2f'. (This was previously nastily silent + and difficult to debug.) [Ken Coar] + + *) Fix streaming output from an nph- CGI script. CGI:IRC now + works. PR 8482 [Jeff Trawick] + + *) More accurate logging of bytes sent in mod_logio when + the client terminates the connection before the response + is completely sent [Bojan Smojver ] + + *) Fix some problems in the perchild MPM. + [Jonas Eriksson ] + + *) Change the CacheRoot processing to check for a required + value at config time. This saves a lot of wasted processing + if the mod_disk_cache module is loaded but no CacheRoot + was provided. This fix also adds code to log an error + and avoid useless pallocs and procesing when the computed + cache file name cannot be opened. This also updates the + docs accordingly. [Paul J. Reder] + + *) Introduce the EnableSendfile directive, allowing users of NFS + shares to disable sendfile mechanics when they either fail + outright or provide intermitantly corrupted data. PR + [William Rowe] + + *) Resolve the error "An operation was attempted on something + that is not a socket. : winnt_accept: AcceptEx failed. + Attempting to recover." for users of various firewall and + anti-virus software on Windows. PR 8325 [William Rowe] + + *) Add the ProxyBadHeader directive, which gives the admin some + control on how mod_proxy should handle bogus HTTP headers from + proxied servers. This allows 2.0 to "emulate" 1.3's behavior if + desired. [Jim Jagielski] + + *) Change the LDAP modules to export their symbols correctly + during a Windows build. Add dsp files for Windows. Update + README.ldap file for Windows build instructions. + [Andre Schild ] + + *) Performance improvements for the code that generates HTTP + response headers [Brian Pane] + + *) Add -S as a synonym for -t -DDUMP_VHOSTS. + [Thom May ] + + *) Fix a bug with dbm rewrite maps which caused the wrong value to + be used when the key was not found in the dbm. PR 13204 + [Jeff Trawick] + + *) Fix a problem with streaming script output and mod_cgid. + [Jeff Trawick] + + *) Add ap_register_provider/ap_lookup_provider API. + [John K. Sterling , Justin Erenkrantz] + +Changes with Apache 2.0.43 + + *) SECURITY: CVE-2002-0840 (cve.mitre.org) + HTML-escape the address produced by ap_server_signature() against + this cross-site scripting vulnerability exposed by the directive + 'UseCanonicalName Off'. Also HTML-escape the SERVER_NAME + environment variable for CGI and SSI requests. It's safe to + escape as only the '<', '>', and '&' characters are affected, + which won't appear in a valid hostname. Reported by Matthew + Murphy . [Brian Pane] + + *) Fix a core dump in mod_cache when it attemtped to store uncopyable + buckets. This happened, for instance, when a file to be cached + contained SSI tags to execute a CGI script (passed as a pipe + bucket). [Paul J. Reder] + + *) Ensure that output already available is flushed to the network + when the content-length filter realizes that no new output will + be available for a while. This helps some streaming CGIs as + well as some other dynamically-generated content. [Jeff Trawick] + + *) Fix a mutex problem in mod_ssl session cache support which + could lead to an infinite loop. PR 12705 + [Amund Elstad , Jeff Trawick] + + *) SECURITY: CVE-2002-1156 (cve.mitre.org) + Fix the exposure of CGI source when a POST request is sent to + a location where both DAV and CGI are enabled. [Ryan Bloom] + + *) Allow the UserDir directive to accept a list of directories. + This matches what Apache 1.3 does. Also add documentation for + this feature. [Jay Ball ] + + *) New Module: mod_logio. adds the ability to log bytes sent and + received. [Bojan Smojver ] + + *) SuExec needs to use the same default directory as the rest of + server, namely /usr/local/apache2. + [SangBeom han ] + + *) Get mod_auth_ldap to retry connections on LDAP_SERVER_DOWN. + [Thomas Bennett , Graham Leggett] + + *) Make sure the contents of the WWW-Authenticate header is + passed on a 4xx error by proxy. Previously all headers + were dropped, resulting in the browser being unable to + authenticate. [Dr Richard Reiner , + Richard Danielli , Graham Wiseman + , David Henderson + ] + + *) Make mod_cache's CacheMaxStreamingBuffer directive work + properly for virtual hosts that override server-wide mod_cache + setttings. [Matthieu Estrade ] + + *) Add -p option to apxs to allow programs to be compiled with apxs. + [Justin Erenkrantz] + +Changes with Apache 2.0.42 + + *) SECURITY: CAN-2002-1593 (cve.mitre.org) [CERT VU#406121] + mod_dav: Check for versioning hooks before using them. + [Greg Stein] + +Changes with Apache 2.0.41 + + *) The protocol version (eg: HTTP/1.1) in the request line parsing + is now case insensitive. [Jim Jagielski] + + *) Allow AddOutputFilterByType to add multiple filters per directive. + [Justin Erenkrantz] + + *) Remove warnings with Sun's Forte compiler. [Justin Erenkrantz] + + *) Fixed mod_disk_cache's generation of 304s + [Kris Verbeeck ] + + *) Add support for using fnmatch patterns in the final path + segment of an Include statement (eg.. include /foo/bar/*.conf). + and remove the noise on stderr during config dir processing. + [Joe Orton ] + + *) mod_cache: cache_storage.c. Add the hostname and any request + args to the key generated for caching. This provides a unique + key for each virtual host and for each request with unique + args. [Paul J. Reder, args code provided by Kris Verbeeck] + + *) mod_cache: Do not cache responses to GET requests with query + URLs if the origin server does not explicitly provide an + Expires header on the response (RFC 2616 Section 13.9) + [Kris Verbeeck ] + + *) Fix memory leak in core_output_filter. [Justin Erenkrantz] + + *) Update OpenSSL detection to work on Darwin. + [Sander Temme ] + + *) Update the xslt and css to give the documentation a more + modern style. + [André Malo , Gernot Winkler ] + + *) Fix some bucket memory leaks in the chunking code + [Joe Schaefer ] + + *) Add ModMimeUsePathInfo directive. [Justin Erenkrantz] + + *) mod_cache: added support for caching streamed responses (proxy, + CGI, etc) with optional CacheMaxStreamingBuffer setting [Brian Pane] + + *) Add image/x-icon to httpd.conf PR 10993. + [Ian Holsman, Peter Bieringer ] + + *) Fix FileETags none operation. PR 12207. + [Justin Erenkrantz, Andrew Ho ] + + *) Restored the experimental leader/followers MPM to working + condition and converted its thread synchronization from + mutexes to atomic CAS. [Brian Pane] + + *) Fix Logic on non-html file removal in mod_deflate + [Kris Verbeeck ] + + *) Fix "ab -g"'s truncated year: the last digit was cut off. + [Leon Brocard ] + + *) mod_rewrite can now sets cookies in err_headers, uses the correct + expiry date, and can now set the path as well + PR 12132,12181,12172. + [Ian Holsman / Rob Cromwell ] + + *) The content-length filter no longer tries to buffer up + the entire output of a long-running request before sending + anything to the client. [Brian Pane] + + *) Win32: Lower the default stack size from 1MB to 256K. This will + allow around 8000 threads to be started per child process. + 'EDITBIN /STACK:size apache.exe' can be used to change this + value directly in the apache.exe executable. + [Bill Stoddard] + + *) Win32: Implement ThreadLimit directive in the Windows MPM. + [Bill Stoddard] + + *) Remove CacheOn config directive since it is set but never checked. + No sense wasting cycles on unused code. Besides, the only truly + bug free code is deleted code. :) [Paul J. Reder] + + *) BufferLogs are now run-time enabled, and the log_config now has 2 new + callbacks to allow a 3rd party module to actually do the writing of the + log file [Ian Holsman] + + *) Correct ISAPIReadAheadBuffer to default to 49152, per mod_isapi docs. + [André Malo, Astrid Keßler ] + + *) Fix Segfault in mod_cache. [Kris Verbeeck ] + + *) Fix a null pointer dereference in the merge_env_dir_configs + function of the mod_env module. PR 11791 + [Paul J. Reder] + + *) New option to ServerTokens 'maj[or]'. Only show the major version + Also Surfaced this directive in the standard config (default FULL) + [Ian Holsman] + + *) Change mod_rewrite to use apr-util's dbm support for dbm rewrite + maps. The dbm type (e.g., ndbm, gdbm) can be specified on the + RewriteMap directive. PR 10644 [Jeff Trawick] + + *) Fixed mod_rewrite's RewriteMap prg: support so that request/response + pairs will no longer get out of sync with each other. PR 9534 + [Cliff Woolley] + + *) Fixes required to get quoted and escaped command args working in + mod_ext_filter. PR 11793 [Paul J. Reder] + + *) mod-proxy: handle proxied responses with no status lines + [JD Silvester , Brett Huttley ] + + *) Fix bug where environment or command line arguments containing + non-ASCII-7 characters would cause the Win32 child process creation + to fail. PR 11854 [William Rowe] + + *) Bug #11213.. make module loading error messages more informative + [Ian Darwin ] + + *) thread safety & proxy-ftp [Alexey Panchenko , Ian Holsman] + + *) mod_disk_cache works much better. This module should still + be considered experimental. [Eric Prud'hommeaux] + + *) Performance improvement for keepalive requests: when setting + aside a small file for potential concatenation with the next + response on the connection, set aside the file descriptor rather + than copying the file into the heap. [Brian Pane] + + *) Modified version check on openssl so that it finds the executable + first and then performs a check of the version, only warning the + user if they chose, or we selected, an old version of OpenSSL. + This change also allows the code to work for non-openssl libraries + selected via the --with-ssl=dir option, which can override the + automated library check in any case. [Roy Fielding] + +Changes with Apache 2.0.40 + + *) SECURITY: CAN-2002-0661 (cve.mitre.org) + Close a very significant security hole that + applies only to the Win32, OS2 and Netware platforms. Unix was not + affected, Cygwin may be affected. Certain URIs will bypass security + and allow users to invoke or access any file depending on the system + configuration. Without upgrading, a single .conf change will close + the vulnerability. Add the following directive in the global server + httpd.conf context before any other Alias or Redirect directives; + RedirectMatch 400 "\\\.\." + Reported by Auriemma Luigi . + [Brad Nicholes] + + *) SECURITY: CAN-2002-0654 (cve.mitre.org) + Close a path-revealing exposure in multiview type + map negotiation (such as the default error documents) where the + module would report the full path of the typemapped .var file when + multiple documents or no documents could be served based on the mime + negotiation. Reported by Auriemma Luigi . + [William Rowe] + + *) SECURITY: CAN-2002-0654 (cve.mitre.org) + Close a path-revealing exposure in cgi/cgid when we + fail to invoke a script. The modules would report "couldn't create + child process /path-to-script/script.pl" revealing the full path + of the script. Reported by Jim Race . + [Bill Stoddard] + + *) Set aside the apr-iconv and apr_xlate() features for the Win32 + build of 2.0.40 so development can be completed. A patch, from + + will be available for those that wish to work with apr-iconv. + [William Rowe] + + *) Fix proxy so that it is possible to access ftp: URLs via a proxy + chain. [Peter Van Biesen ] + + *) mod-deflate now checks to make sure that 'gzip-only-text/html' is + set to 1, so we can exclude things from the general case with + browsermatch. [Ian Holsman, Andre Schild ] + + *) Accept multiple leading /'s for requests within the DocumentRoot. + PR 10946 [William Rowe, David Shane Holden ] + + *) Solved the reports of .pdf byterange failures on Win32 alone. + APR's sendfile for the win32 platform collapses header and trailer + buffers into a single buffer. However, we destroyed the pointers + to the header buffer if a trailer buffer was present. PR 10781 + [William Rowe] + + *) mod_ext_filter: Add the ability to enable or disable a filter via + an environment variable. Add the ability to register a filter of + type other than AP_FTYPE_RESOURCE. [Jeff Trawick] + + *) Restore the ability to specify host names on Listen directives. + PR 11030. [Jeff Trawick, David Shane Holden ] + + *) When deciding on the default address family for listening sockets, + make sure we can actually bind to an AF_INET6 socket before + deciding that we should default to AF_INET6. This fixes a startup + problem on certain levels of OpenUNIX. PR 10235. [Jeff Trawick] + + *) Replace usage of atol() to parse strings when we might want a + larger-than-long value with apr_atoll(), which returns long long. + This allows HTTPD to deal with larger files correctly. + [Shantonu Sen ] + + *) mod_ext_filter: Ignore any content-type parameters when checking if + the response should be filtered. Previously, "intype=text/html" + wouldn't match something like "text/html;charset=8859_1". + [Jeff Trawick] + + *) mod_ext_filter: Set up environment variables for external programs. + [Craig Sebenik ] + + *) Modified the HTTP_IN filter to immediately append the EOS (end of + stream) bucket for C-L POST bodies, saving a roundtrip and allowing + the caller to determine that no content remains without prefetching + additional POST body. [William Rowe] + + *) Get proxy ftp to work over IPv6. [Shoichi Sakane ] + + *) Look for OpenSSL libraries in /usr/lib64. [Peter Poeml ] + + *) Update SuSE layout. [Peter Poeml ] + + *) Changes to the internationalized error documents: + Comment them out in the default config file to make the default + install as simple as possible; Correct the english 500 error to + be more understandable; Add a Swedish translation. + [Thomas Sjogren , + Erik Abele , Rich Bowen, Joshua Slive] + + *) Increase the limit on file descriptors per process in apachectl. + [Brian Pane] + + *) Fix a dependency error when building ApacheMonitor, so that Win32 + and MSVC now trust that the project is current (when it is). + [James Cox ] + + *) mod_ext_filter: don't segfault if content-type is not set. PR 10617. + [Arthur P. Smith , Jeff Trawick] + + *) APR-Util Renames pending have been completed [Thom May] + + *) Performance improvements for the code that reads request + headers (ap_rgetline_core() and related functions) [Brian Pane] + + *) Add a new directive: MaxMemFree. MaxMemFree makes it possible + to configure the maximum amount of memory the allocators will + hold on to for reuse. Anything over the MaxMemFree threshold + will be free()d. This directive is useful when uncommon large + peaks occur in memory usage. It should _not_ be used to mask + defective modules' memory use. [Sander Striker] + + *) Fixed the Content-Length filter so that HTTP/1.0 requests to CGI + scripts would not result in a truncated response. + [Ryan Bloom, Justin Erenkrantz, Cliff Woolley] + + *) Add a filter_init parameter to the filter registration functions + so that a filter can execute arbitrary code before the handlers + are invoked. This resolves a problem where mod_include requests + would incorrectly return a 304. [Justin Erenkrantz] + + *) Fix a long-standing bug in 2.0, CGI scripts were being called + with relative paths instead of absolute paths. Apache 1.3 used + absolute paths for everything except for SuExec, this brings back + that standard. [Ryan Bloom] + + *) Fix infinite loop due to two HTTP_IN filters being present for + internally redirected requests. PR 10146. [Justin Erenkrantz] + + *) Switch conn_rec->keepalive to an enumeration rather than a bitfield. + [Justin Erenkrantz] + + *) Fix mod_ext_filter to look in the main server for filter definitions + when running in a vhost if the filter definition is not found in + the vhost. PR 10147 [Jeff Trawick] + + *) Support WinNT CGI invocation through ScriptInterpreterSource + 'registry' for script interpreter paths and names with non-ascii + characters in the executable filepath. [William Rowe] + + *) Support the -w flag on to keep the Win32 console open on error. + [William Rowe] + + *) Normalize the hostname value in the request_rec to all-lowercase + [Perry Harrington ] + + *) Fix WinNT cgi 500 errors when QUERY_ARGS or other strings include + extended characters (non US-ASCII) in non-utf8 format. This brings + Win32 back into CGI/1.1 compliance, and leaves charset decoding up + to the cgi application itself. [William Rowe] + + *) Major overhaul of mod_dav, mod_dav_fs and the experimental/cache + modules to bring them up to the current apr/apr-util APIs. + [William Rowe] + + *) Fix segfault in mod_mem_cache most frequently observed when + serving the same file to multiple clients on an MP machine. + [Bill Stoddard] + + *) mod_rewrite can now set cookies (RewriteRule (.*) - [CO=name:$1:.domain]) + [Brian Degenhardt , Ian Holsman] + + *) Fix perchild to work with apachectl by adding -k support to perchild. + PR 10074 [Jeff Trawick] + + *) Fix a silly htpasswd.c logic error that incorrectly reported that + both -c and -n had been used. PR 9989 [Cliff Woolley] + + *) Fixed a mod_include error case in which no HTTP response was sent + to the client if an shtml document contained an unterminated SSI + directive [Brian Pane] + + *) Improve ap_get_client_block implementation by using APR-util brigade + helper functions and relying on current filter assumptions. + [Justin Erenkrantz] + +Changes with Apache 2.0.39 + + *) Fixed a build problem in htpasswd.c on Win32. + [Guenter Knauf , Cliff Woolley] + +Changes with Apache 2.0.38 + + *) Rewrite htpasswd to use APR. The removes the annoying warning about + tmpnam being unsafe. [Ryan Bloom] + + *) We must set the MIME-type for .shtml files to text/html if we want them + to be parsed for SSI tags. Add the config for that to the default + config file so that it is easier to enable .shtml parsing. + [Dave Dyer ] + + *) Fixed a problem with 'make install' on ReliantUnix. + [Jean-frederic Clere ] + + *) Make the default_handler catch all requests that aren't served by + another handler. This also gets us to return a 404 if a directory + is requested, there is no DirectoryIndex, and mod_autoindex isn't + loaded. [Justin Erenkrantz] + + *) Fixed the handling of nested if-statements in shtml files. + PR 9866 [Brian Pane] + + *) Allow 'make install DESTDIR=/path'. This allows packagers to install + into a directory different from the one that was configured. This + also mirrors the root= feature from 1.3. We cannot use prefix=, + because both APR and APR-util resolve their installation paths at + configuration time. This means that there is no variable prefix + to replace. [Andreas Hasenack ] + + *) AIX 4.3.2 and above: Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT. + These levels of AIX don't have a thundering herd problem with + accept(). [Jeff Trawick] + + *) prefork MPM: Ignore mutex errors during graceful restart. For + certain types of mutexes (particularly SysV semaphores), we + should expect to occasionally fail to obtain or release the + mutex during restart processing. [Jeff Trawick] + + *) Fix install-bindist.sh so that it finds any perl instead of just + early perl 5.x versions. This is consistent with a build/install + from source, and it allows the perl scripts installed by a bindist + to work on systems with perl 5.6. [Jeff Trawick] + + *) Fix apxs so that the makefile created by "apxs -g" works on AIX and + Tru64 (and probably some other platforms). [Jeff Trawick] + + *) Allow CGI scripts to return their Content-Length. This also fixes a + hang on HEAD requests seen on certain platforms (such as FreeBSD). + [Justin Erenkrantz] + + *) Added log rotation based on file size to the RotateLog support + utility. [Brad Nicholes] + + *) Fix some casting in mod_rewrite which broke random maps. + PR 9770 [Allan Edwards, Greg Ames, Jeff Trawick] + +Changes with Apache 2.0.37 + + *) allow POST method over SSL when per-directory client cert + authentication is used with 'SSLOptions +OptRenegotiate' enabled + and a client cert was found in the ssl session cache. + + *) 'SSLOptions +OptRengotiate' will use client cert in from the ssl + session cache when there is no cert chain in the cache. prior to + the fix this situation would result in a FORBIDDEN response and + error message "Cannot find peer certificate chain" + [Doug MacEachern] + + *) ap_finalize_sub_req_protocol() shouldn't send an EOS bucket if + one was already sent. PR 9644 [Jeff Trawick] + + *) Fix the display of the default name for the mime types config + file. PR 9729 [Matthew Brecknell ] + + *) Fix the working directory *for WinNT/2K/XP services only* to + change to the Apache directory (one level above the location + of Apache.exe, in the case that Apache.exe resides in bin/.) + Solves the case of ServerRoot /foo paths where /foo was not + on the same drive as /winnt/system32. [William Rowe] + + *) Make 2.0's "AcceptMutex" startup message now "completely" + match how 1.3 does it. [Jim Jagielski] + + *) Implement a fixed size memory cache using a priority queue + [Ian Holsman] + + *) Fix apxs to allow "apxs -q installbuilddir" and to allow + querying certain other variables from config_vars.mk. PR 9316 + [Jeff Trawick] + + *) Added the "detached" attribute to the cgi_exec_info_t internals + so that Win32 and Netware won't create a new window or console + for each CGI invoked. PR 8387 + [Brad Nicholes, William Rowe] + + *) Consolidated the command line parameters and attributes that are + manipulated by the optional function ap_cgi_build_command() in + mod_cgi into a single structure. + [Brad Nicholes] + + *) Get rid of uninitialized value errors with "apxs -q" on certain + variables. [Stas Bekman ] + + *) Fix apxs to allow it to work when the build directory is somewhere + besides server-root/build. PR 8453 + [Jeff Trawick and a host of others] + + *) Allow ap_discard_request_body to be called multiple times in the + same request. Essentially, ap_http_filter keeps track of whether + it has sent an EOS bucket up the stack, if so, it will only ever + send an EOS bucket for this request. + [Ryan Bloom, Justin Erenkrantz, Greg Stein] + + *) Remove all special mod_ssl URIs. This also fixes the bug where + redirecting (.*) will allow an SSL protected page to be viewed + without SSL. [Ryan Bloom] + + *) Fix the binary build install script so that the build logic + created by "apxs -g" will work when the user has a binary + build. [Jeff Trawick] + + *) Allow instdso.sh to work with full paths to the shared module. + [Justin Erenkrantz] + + *) NetWare: Enabled CGI functionality and added mod_cgi as a built + in module for NetWare [Brad Nicholes] + + *) Changed cgi and piped log behavior to accept 65536 characters + on Win32 (matching Linux) before deadlocking between outputing + client stdin, slurping the output from stdout and then the stderr + stream. PR 8179 [William Rowe] + + *) Fixed Win32 wintty.exe support to assure the window title is valid. + Elimiates possible gpfault or garbage title without the -t option. + [William Rowe] + + *) Rewrite mod_cgi, mod_cgid, and mod_proxy input handling to use + brigades and input filters. [Justin Erenkrantz] + + *) Allow ap_http_filter (HTTP_IN) to return EOS when there is no request + body. [Justin Erenkrantz] + + *) NetWare: Piping log entries through RotateLogs using the + CustomLogs directive is finally supported now that we have + the pipes and spawning functionality working. + [Brad Nicholes] + + *) SECURITY: CVE-2002-0392 (cve.mitre.org) [CERT VU#944335] + Detect overflow when reading the hex bytes forming a chunk line. + [Aaron Bannert] + + *) Allow RewriteMap prg:'s to take command-line arguments. PR 8464. + [James Tait ] + + *) Correctly return 413 when an invalid chunk size is given on + input. Also modify ap_discard_request_body to not do anything + on sub-requests or when the connection will be dropped. + [Justin Erenkrantz] + + *) Fix the TIME_* SSL var lookups to be threadsafe. PR 9469. + [Cliff Woolley] + + *) Ensure that apr_brigade_write() flushes in all of the cases that + it should to avoid conditions in some modules that could cause + large amounts of data to be buffered. [Cliff Woolley] + + *) Fix problem where mod_cache/mod_disk_cache was incorrectly + stripping the content_type from cached responses. + [Bill Stoddard] + + *) apachectl passes through any httpd options. Note: apachectl + should be used in preference to httpd since it ensures that any + appropriate environment variables have been set up. + [Jeff Trawick] + + *) Fix the combination of mod_cgid, mod_setuexec, and mod_userdir. + PR 7810 [Colm MacCarthaigh ] + + *) Fix suexec execution of CGI scripts from mod_include. + PR 7791, 8291 [Colm MacCarthaigh ] + + *) Fix segfaults at startup on some platforms when mod_auth_digest, + mod_suexec, or mod_ssl were used as DSO's due to the way they + were tracking the current init phase since DSO's get completely + unloaded and reloaded between phases. PR 9413. + [Tsuyoshi Sasamoto , Brad Nicholes] + + *) Fix mod_include's handling of regular expressions in + " and directives [Brian Pane] + + *) Fix some mod_include segfaults [Cliff Woolley, Brian Pane, Brad Nicholes] + + *) Update the "RedHat" Layout to match Red Hat Linux version 7. PR BZ-7422 + [Joe Orton] + + *) add compat layer to support RSA SSLC 1.x and 2.x in mod_ssl + [Jon Travis, John Barbee, William Rowe, Ryan Bloom, Doug MacEachern] + + *) Add a new parameter to the quick_handler hook to instruct + quick handlers to optionally do a lookup rather than actually + serve content. This is the first of several changes required fix + several problems with how quick handlers work with subrequests. + [Bill Stoddard] + + *) worker MPM: Get MaxRequestsPerChild to work again. [Jeff Trawick] + + *) [APR-related] The ordering of the default accept mutex method has + been changed to better match what's done in Apache 1.3. The ordering + is now (highest to lowest): pthread -> sysvsem -> fcntl -> flock. + [Jim Jagielski] + + *) Ensure that the build/ directory is created when using VPATH. + [Justin Erenkrantz] + + *) Add some popular types to the mime magic file. PR 7730. + [Linus Walleij , Justin Erenkrantz] + + *) Remove the single-byte socket reads for CGI headers [Brian Pane] + + *) When a proxied site was being served, Apache was replacing + the original site Server header with it's own, which is not + allowed by RFC2616. Fixed. [Graham Leggett] + + *) Fix a mod_cgid problem that left daemon processes stranded + in some server restart scenarios. [Jeff Trawick] + + *) Added exp_foo and rel_foo variables to config_vars.mk for + all Apache and Autoconf path variables (like --sysconfdir, + --sbindir, etc). exp_foo is the "expanded" version, which means + that all internal variable references have been interpolated. + rel_foo is the same as $exp_foo, only relative to $prefix if they + share a common path. [Aaron Bannert] + + *) Fix some restart/terminate problems in the worker MPM. Don't + drop connections during graceful restart. [Jeff Trawick] + + *) Change the header merging behaviour in proxy, as some headers + (like Set-Cookie) cannot be unmerged due to stray commas in + dates. [Graham Leggett] + + *) Be more vocal about what AcceptMutex values we allow, to make + us closer to how 1.3 does it. [Jim Jagielski] + + *) Get nph- CGI scripts working again. PRs 8902, 8907, 9983 + [Jeff Trawick] + + *) Upgraded PCRE library to latest version 3.9 [Brian Pane] + + *) Add accessor function to set r->content_type. From now on, + ap_rset_content_type() should be used to set r->content_type. + This change is required to properly implement the + AddOutputFilterByType configuration directive. + [Bill Stoddard, Sander Striker, Ryan Bloom] + + *) Add new M_FOO symbols for the WebDAV/DeltaV methods specified by + RFC 3253. Improved the method name/number mapping functions. + [Greg Stein] + + *) remove sock_enable_linger from connection.c [Ian Holsman] + + *) Fix for virtual host processing where the requested hostname + has a '.' at the end (PR 9187) [Ryan Cruse ] + + *) mod_dav's APIs for REPORT response handling was changed so that + providers can generate the content directly into the output filter + stack, rather than buffering the response into memory. [Greg Stein] + + *) Fix a hang condition with graceful restart and prefork MPM + in the situation where MaxClients is very high but + much fewer servers are actually started at the time of the + restart. [Jeff Trawick] + + *) Small performance fixes for mod_include [Brian Pane] + + *) Performance improvement for the error logger [Brian Pane] + + *) Change configure so that Solaris 8 and above have + SINGLE_LISTEN_UNSERIALIZED_ACCEPT defined by default. + according to sun people solaris 8+ doesn't have a thundering + herd problem [Ian Holsman] + + *) Allow URIs specifying CGI scripts to include '/' at the end + (e.g., /cgi-bin/printenv/) on AIX and Solaris (and other OSs + which ignore '/' at the end of the names of non-directories). + PR 10138 [Jeff Trawick] + + *) implement SSLSessionCache shmht and shmcb based on apr_rmm and + apr_shm. [Madhusudan Mathihalli ] + + *) Fix apxs -g handling. Move config_vars.mk from the top build + directory to the build directory. PR 10163 [Jeff Trawick] + + *) Fix some mod_include problems which broke evaluation of some + expressions. PR 10108 [Jeff Trawick] + + *) Fix the calculation of request time in mod_status. [Stas Bekman] + + *) Fix the calculation of thread_num in the worker score structure. + [Stas Bekman] + + *) Use apr_atomic operations in managing the mod_mem_cache + cache_objects for SMP scalability. (see USE_ATOMICS + preprocessor directive in mod_file_cache) + [Bill Stoddard] + + *) Add filehandle caching to mod_mem_cache. (see CACHE_FD + preprocessor directive in mod_file_cache) + [Bill Stoddard] + + *) Implement prototype mod_disk_cache for use with mod_cache. + [Bill Stoddard] + + *) Add a missing manualdir entry in the Debian config.layout. + [Thom May ] + + *) Stop installing libtool for APR and tell APR where it should place + its copy of libtool (via our installbuildpath layout variable). + [Justin Erenkrantz] + + *) New directive ProxyIOBufferSize. Sets the size of the buffer used + when reading from a remote HTTP server in proxy. [Graham Leggett] + + *) Modify receive/send loop in proxy_http and proxy_ftp so that + should it be necessary, the remote server socket is closed before + transmitting the last buffer (set by ProxyIOBufferSize) to the + client. This prevents the backend server from being forced to hang + around while the last few bytes are transmitted to a slow client. + Fix the case where no error checking was performed on the final + brigade in the loop. [Graham Leggett] + + *) Scrap CacheMaxExpireMin and CacheDefaultExpireMin. Change + CacheMaxExpire and CacheDefaultExpire to use seconds rather than + hours. [Graham Leggett, Bill Stoddard] + + *) New Directive SSIUndefinedEcho. to change the '(none)' echoed + for a undefined variable. [Ian Holsman] + + *) Proxy HTTP and CONNECT: Keep trying other addresses from the DNS + when we can't get a socket in the specified address family. We may + have gotten back an IPv6 address first and yet our system is not + configured to allow IPv6 sockets. [Jeff Trawick] + + *) Be more careful about recursively removing CVS directories. Make + sure that we aren't cd'ing to their home directory first. PR: 9993 + [Aaron Bannert, James LewisMoss ] + + *) Add a missing errordir entry in the Debian config.layout. PR: 10067 + [Dirk-Jan Faber , Aaron Bannert, + Thom May ] + + *) Rename the filter ordering priorities. The recent filtering fixes + have showcased problems with their usage. Therefore, we need to + rename them to increase the clarity. (CONTENT->RESOURCE, + HTTP_HEADER->CONTENT_SET/PROTOCOL) [Justin Erenkrantz] + +Changes with Apache 2.0.33 + + *) Fix a problem in the new --enable-layout functionality where + it wouldn't allow overrides from variables like --prefix, + --bindir, etc. [Thom May ] + + *) Fix a bug in the core input filter for AP_MODE_EXHAUSTIVE. It + no longer hangs around waiting for the socket to close before + returning exhaustive data. [Aaron Bannert] + + *) rename apr_exploded_time_t to apr_time_exp_t (as per renames pending) + [Thom May ] + + *) Change mod_ssl to always do a full startup/teardown on restarts. + this allows mod_ssl to be added to a server that is already + running and makes it possible to add/change certs/keys after the + server has been started. [Doug MacEachern] + + *) Introduce PassPhraseDialog "|/path/to/pipe" mechanism to mod_ssl. + This pipe must be a bidirectional 'console' style relay, which + mod_ssl prints all prompts to the pipe's stdin, and reads the + passphrases from the pipe's stdout. [William Rowe] + + *) Fix bug where --sysconfdir and --localstatedir were being + ignored. [Thom May , Aaron Bannert] + PR 9888 + + *) Fix --enable-layout to work again. Caution: When specifying + --enable-layout, common arguments like --prefix, --exec-prefix, + etc. will be ignored and the settings from the layout will be + used instead. [Thom May , Aaron Bannert] + PR 9124, 9873, 9885 + + *) New Directive for mod_proxy: ProxyRemoteMatch. This provides + regex pattern matching for the determination of which requests + to use the remote proxy for. [Jim Jagielski] + + *) Fix CustomLog bytes-sent with HTTP 0.9. [Justin Erenkrantz] + + *) Prevent Apache from ignoring SIGHUP due to some lingering 1.3 + cruft in piped logs and rewritemap child processes. + [William Rowe] + + *) All instances of apr_lock_t have been removed and converted + to one of the following new lock APIs: apr_thread_mutex.h, + apr_proc_mutex.h, or apr_global_mutex.h. No new code should + use the apr_lock.h API, as the old API will soon be deprecated. + [Aaron Bannert] + + *) Merged in changes to mod_ssl up through 2.8.7-1.3.23. + [Ralf S. Engelschall, Cliff Woolley] + + *) mod-include: make it handle flush'es and fix the 'false-alarm' + [Justin Erenkrantz, Brian Pane, Ian Holsman] + + *) ap_get_*_filter_handle() functions to allow 3rd party modules + to lookup filter handles so they can bypass the filter name + lookup when adding filters to a request (via ap_add_*_filter_handle()) + [Ryan Morgan ] + + *) Fix for multiple file buckets on Win32, where the first file + bucket would cause the immediate closure of the socket on any + non-keepalive requests. [Ryan Morgan ] + + *) Correct Win32 failure of mmap of a segment beyond start of the + file; fixes large SSL and similar transfers. [William Rowe] + PR 9898 + + *) Implement apr_proc_detach changes and allow -DNO_DETACH in the + multi-process mode to not "daemonize" while detaching from the + controlling terminal. This is necessary for Apache to work with + process-management tools like AIX's "System Resource Controller" + as well as Dan Bernstein's "daemontools". + [Jos Backus , Aaron Bannert] + + *) Convert mod_auth_digest to use the new apr_global_mutex_t + type. [Aaron Bannert] + + *) fix bug in mod-include where it wouldn't send a unmatched + part if it was at the end of a bucket [Ian Holsman] + + *) worker MPM: Improve logging of errors with the interface between + the listener thread and worker threads. [Jeff Trawick] + + *) Some browsers ignore cookies that have been merged into a + single Set-Cookie header. Set-Cookie and Set-Cookie2 headers + are now unmerged in the http proxy before being sent to the + client. [Graham Leggett] + + *) Fix a problem with proxy where each entry of a duplicated + header such as Set-Cookie would overwrite and obliterate the + previous value of the header, resulting in multiple header + values (like cookies) going missing. + [Graham Leggett, Joshua Slive] + + *) Add the server-limit and thread-limit values to the scoreboard + for the sake of third-party applications. + [Adam Sussman ] + + *) Fix segfault when proxy recieves an invalid HTTP response [Ian Holsman] + + *) OS/390: Get make install to properly copy DSO modules. + [Jeff Trawick] + + *) Win32: Fix bug in mod_status with displaying "Restart Time" + and "Server uptime". + [Bill Stoddard] + + *) Fix IPv6 name-based virtual hosts. [Jeff Trawick] + + *) Introduce AddOutputFilterByType directive. [Justin Erenkrantz] + + *) Fix DEBUG_CGI support in mod_cgi. PR 9670, 9671. + [David MacKenzie ] + + *) Fix incorrect check for script_in in mod_cgi. PR 9669. + [David MacKenzie ] + + *) Fix segfault and display error when SSLMutex file can not be + created. [Adam Sussman ] + + *) Add reference counting to mod_mem_cache cache objects to + better manage removing objects from the cache. + [Bill Stoddard] + + *) Change the verbage on the ScoreBoardFile in our default configs. + Also change the default to be commented out (unspecified) so we + get anonymous shared memory by default. [Aaron Bannert] + + *) Implement new ScoreBoardFile directive logic. This affects how + we create the scoreboard's shared memory segment. If the directive + is present, a name-based segment is created. If the directive is + not present, first an anonymous segment is created, and if that + fails, a name-based segment is created from a file of the name + DEFAULT_SCOREBOARD. This gives third-party applications the + ability to access our scoreboard. [Aaron Bannert] + + *) Allow mod_deflate to work with non-GET requests and properly send + Content-Lengths. [Sander Striker ] + + *) Fix ap_directory_merge() to correctly merge configs when there is + no block. [Justin Erenkrantz, William Rowe] + + *) Remove spurious debug messsages that are normal under HTTP + keep-alive logic. [Jeff Trawick, Justin Erenkrantz] + + *) Fix a bug in mod_cgid that would prevent proper shutdown death + of the cgid process. [Aaron Bannert] + + *) Add signal handling back in to the worker MPM for the one_process + (-X, -DDEBUG, -DONE_PROCESS) case. [Aaron Bannert] + + *) Performance: Reuse per-connection transaction pools in the + worker MPM, rather than destroying and recreating them. [Brian Pane] + + *) Remove all signals from the worker MPM's child process. Instead, + the parent uses the Pipe of Death for all communication with the + child processes. [Ryan Bloom] + +Changes with Apache 2.0.32 + + *) mod_negotiation: ForceLanguagePriority now uses 'Prefer' as the + default if the directive is not specified. This mirrors older + behavior without changes to the httpd.conf. [William Rowe] + + *) Win32: solve the win32 service problems in 2.0.31-alpha, by fixing + the service, mpm and logging code, and bugs in apr_file_open_stderr + and apr_file_dup2 functions. Win2K/XP services have no handles + associated for stdin/out/err, which caused unpredictable behavior + in the prior release. [William Rowe, Bill Stoddard] + + *) Win32: simplify the Application Event Log messages, since there isn't + likely to be 'more information in the error log' before an error log + has been opened. [William Rowe] + + *) Win32: substantial cleanup to the mpm_winnt code for legibility and + to follow the program flow of other MPMs. [Ryan Bloom, William Rowe] + + *) Win32: apache -k shutdown now behaves like apache -k stop. + [Bill Stoddard] + + *) Fix prefork to not kill the parent if a child hits a resource shortage + on accept(). [Greg Ames] + + *) Fix seg faults that occur when what should be the httpd request line + starts with \r\n followed by garbage. [Greg Ames] + + *) Allow statically linked support binaries with the new + --enable-static-support flag, and enable this behavior in + the binbuild script. Also add a new --enable-static-htdbm + flag. [Aaron Bannert] + + *) Allow mod_autoindex to serve symlinks if permitted and attempt to + do only one stat() call when generating the directory listings. + [Justin Erenkrantz] + + *) Fix resolve_symlink to save the original symlink name if known. + [Justin Erenkrantz] + + *) Be a bit more sane with regard to CanonicalNames. If the user has + specified they want to use the CanonicalName, but they have not + configured a port with the ServerName, then use the same port that + the original request used. [Ryan Bloom and Ken Coar] + + *) In core_input_filter, check for an empty brigade after + APR_BRIGADE_NORMALIZE(). Otherwise, we can get segfaults if a + client says it will post some data but we get FIN before any + data arrives. [Jeff Trawick] + + *) Not being able to bind to the socket is a fatal error. We should + print an error to the console, and return a non-zero status code. + With these changes, all of the Unix MPMs do that correctly. + [Ryan Bloom] + + *) suexec: Allow HTTPS and SSL_* environment variables to be passed + through to CGI scripts. PR 9163 + [Brian Reid , + Zvi Har'El ] + + *) binbuild.sh: Make sure that we use the expat from our source + tree so that there aren't any surprises on the target machine. + [Jeff Trawick] + + *) mod_cgid: Add retry logic for when the daemon can't fork fast + enough to keep up with new requests. Start using + HTTP_SERVER_UNAVAILABLE instead of HTTP_INTERNAL_SERVER_ERROR + when we can't talk to the daemon. [Jeff Trawick] + + *) apxs: LTFLAGS envvar can override default libtool options. Try + "LTFLAGS=' ' apxs -c mod_foo.c" to see what libtool does under + the covers. [Jeff Trawick] + + *) The Location: response header field, used for external + redirect, *must* be an absoluteURI. The Redirect directive + tested for that, but RedirectMatch didn't -- it would allow + almost anything through. Now it will try to turn an abs_path + into an absoluteURI, but it will correctly varf like Redirect + if the final redirection target isn't an absoluteURI. [Ken Coar] + +Changes with Apache 2.0.31 + + *) Create the scoreboard (in the parent) in a global pool context, + so it survives graceful restarts. This fixes a SEGV during + graceful restarts. [Aaron Bannert] + + *) Add a timeout option to the proxy code 'ProxyTimeout' + [Ian Holsman] + + *) FTP directory listings are now always retrieved in ASCII mode. + The FTP proxy properly escapes URI's and HTML in the generated + listing, and escapes the path components when talking to the FTP + server. It is now possible to browse the root directory by using + a url like: ftp://user@host/%2f/ (ported from apache_1.3.24) + Also, the last path component may contain wildcard characters + '*' and '?', and if they do, a directory listing is created instead + of a file retrieval. Example: ftp://user@host/httpd/server/*.c + [Martin Kraemer] + + *) Added single-listener unserialized accept support to the + worker MPM [Brian Pane] + + *) New Directive for mod_proxy: 'ProxyPreserveHost'. This passes + the incoming host header through to the proxied server + [Geoff ] + + *) New Directive Option for ProxyPass. It now can block a location + from being proxied [Jukka Pihl ] + + *) Don't let the default handler try to serve a raw directory. At + best you get gibberish. Much worse things can happen depending + on the OS. [Jeff Trawick] + + *) Change the pre_config hook to return a value. Modules can now emit + an error message and then cause the server to quit gracefully during + startup. This required a bump to the MMN. [Aaron Bannert] + + *) Fix some unix socket descriptor leaks in the handler side of + mod_cgid (the part that runs in the server process). Whack a + silly "close(-1)" in the handler too. [Jeff Trawick] + + *) Change the pre_mpm hook to return a value, so that scoreboard + init errors percolate up to code that knows how to exit + cleanly. This required a bump to the MMN. [Jeff Trawick] + + *) Add the socket back to the conn_rec and remove the create_connection + hook. The create_connection hook had a design flaw that did not + allow creating connections based on vhost info. [Bill Stoddard] + + *) Fixed PATH_INFO and QUERY_STRING from mod_negotiation results. + Resolves the common case of using negotation to resolve the request + /script/foo for /script.cgi/foo. [William Rowe] + + *) Added new functions ap_add_(input|output)_filter_handle to + allow modules to bypass the usual filter name lookup when + adding hard-coded filters to a request [Brian Pane] + + *) caching should now work on subrequests (still very experimental) + [Ian Holsman] + + *) The Win32 mpm_winnt now has a shared scoreboard. [William Rowe] + + *) Change ap_get_brigade prototype to use apr_off_t instead of apr_off_t*. + [Justin Erenkrantz] + + *) Refactor ap_rgetline so that it does not use an internal brigade. + Change ap_rgetline's prototype to return errors. [Justin Erenkrantz] + + *) Remove mod_auth_db. [Justin Erenkrantz] + + *) Do not install unnecessary pcre headers like config.h and internal.h. + [Joe Orton ] + + *) Change in quick_hanlder behavior for subrequests. it now passes DONE + (as it does for a normal request). quick_handled sub-requests now work + in mod-include [Ian Holsman] + + *) Change SUBREQ_CORE so that it is a 'HTTP_HEADER' filter instead of + 'CONTENT' one, as it needs to run AFTER all content headers + + *) Rename BeOS MPM directive RequestsPerThread to MaxRequestsPerThread. + [Lars Eilebrecht] + + *) Split out blocking from the mode in the input filters. + [Justin Erenkrantz] + + *) Fix a segfault in mod_include. [Justin Erenkrantz, Jeff Trawick] + + *) Cause Win32 to capture all child-worker process errors in + Apache to the main server error log, until the child can + open its own error logs. [William Rowe] + + *) HPUX 11.*: Do not kill the child process when accept() + returns ENOBUFS on HPUX 11.*. (ported from th 1.3 patch) + [Madhusudan Mathihalli , Bill Stoddard] + + *) Fix a problem in the parsing of the directive. + [Jeff Trawick] + + *) rewrite of mod_ssl input filter for better performance and less + memory usage [Doug MacEachern] + + *) allow quick_handler to be run on subrequests. [Ian Holsman] + + *) mod_dav now asks its provider to place content directly into the + filter stack when handling a GET request. The mod_dav/provider + API has changed, so providers need to be updated. [Greg Stein] + + *) Clear the output socket descriptor in unixd_accept() to make sure + we don't supply a bogus socket to the caller if the accept fails. + This caused problems with the worker MPM, which tried to process + the returned socket if it was non-NULL. [Brian Pane] + + *) Move a check for an empty brigade to the start of core input filter + to avoid segfaults. [Justin Erenkrantz, Jeff Trawick] + + *) Add FileETag directive to allow configurable control of what + data are used to form ETag values for file-based URIs. MMN + bumped to 20020111 because of fields added to the end of + the core_dir_config structure. [Ken Coar] + + *) Fix a segfault in mod_rewrite's logging code caused by passing the + wrong config to ap_get_remote_host(). [Jeff Trawick] + + *) Allow mod_cgid to work from a binary distribution install by + using 755 for the permissions on the log directory instead of + 750. [Jeff Trawick] + + *) Fixed a segfault that happened during graceful shutdown (or when + the httpd ran out of file descriptors) with the worker MPM [Brian Pane] + + *) Split all Win32 modules [excluding the core components mod_core, + mod_so, mod_win32 and the winnt mpm] into individual loadable + modules, so the administrator may individually disable the former + compiled-in modules by simply commenting out their LoadModule + directives. [William Rowe] + + *) Saved Win32 module authors and porters many future headaches, by + duplicating the appropriate .h files such as os.h into the include + directory, including in the build tree. [William Rowe] + + *) mod_ssl adjustments to help with using toolkits other than OpenSSL: + Use SSL functions/macros instead of directly dereferencing SSL + structures wherever possible. + Add type-casts for the cases where functions return a generic pointer. + Add $SSL/include to configure search path. + [Madhusudan Mathihalli ] + + *) Moved several pointers out of the shared Scoreboard so it is + more portable, and will present the vhost name across server + generation restarts. [William Rowe] + + *) Fix SSLPassPhraseDialog exec: and SSLRandomSeed exec: + [Doug MacEachern] + +Changes with Apache 2.0.30 + + *) Fix the main bug for FreeBSD and threaded MPM's. There are + still issues (see STATUS) but at least the server will now + run without crashing the machine. + [David Reid, Aaron Bannert, Justin Erenkrantz] + + *) Fix a typo in mod_deflate's m4 config section. + [albert chin ] + + *) Fix a couple of mod_proxy problems forwarding HTTP connections + and handling CONNECT: + (1) PR #9190 Proxy failed to connect to IPv6 hosts. + (2) Proxy failed to connect when the first IP address returned by + the resolver was unreachable but a secondary IP address was. + [Jeff Trawick] + + *) Fix the module identifer as shown in the docs for various core + modules (e.g., the identifer for mod_log_config was previously + listed as config_log_module). PR #9338 + [James Watson ] + + *) Fix LimitRequestBody directive by placing it in the HTTP + filter. [Justin Erenkrantz] + + *) Fix mod_proxy seg fault when the proxied server returns + an HTTP/0.9 response or a bogus status line. + [Adam Sussman] + + *) Prevent mod_proxy from truncating one character off the + end of the status line returned from the proxied server. + [Adam Sussman, Bill Stoddard] + + *) Eliminate loop in ap_proxy_string_read(). + [Adam Sussman, Bill Stoddard] + + *) Provide $0..$9 results from mod_include regex parsing. + [William Rowe] + + *) Allow mod-include to look for alternate start & end tags [Ian Holsman] + + *) Introduced the ForceLanguagePriority directive, to prevent + returning MULTIPLE_CHOICES or NONE_ACCEPTABLE in some cases, + when using Multiviews. [William Rowe] + + *) Fix a problem which prevented mod_cgid and suexec from working + together reliably [Greg Ames] + + *) Remove the call to exit() from within mod_auth_digest's post_config + phase. [Aaron Bannert] + + *) Fix a problem in mod_auth_digest that could potentially cause + problems with initialized static data on a system that uses DSOs. + [Aaron Bannert] + + *) Fix a segfault in the worker MPM that could happen during + child process exits. [Brian Pane, Aaron Bannert] + + *) Allow mod_auth_dbm to handle multiple DBM types [Ian Holsman] + + *) Fix matching of vhosts by ip address so we find IPv4 + vhost address when target address is v4-mapped form of + that address. [Jeff Trawick] + + *) More performance tweaks to the BNDM string-search algorithm + used to find "" is the last byte in a file [Brian Pane] + + *) Add back in the "suEXEC mechanism enabled (wrapper: /path/to/suexec)" + message that we had back in apache-1.3 and still have scattered + throughout our docs. [Aaron Bannert] + + *) Prevent the Win32 port from continuing after encountering an + error in the command line args to apache. [William Rowe] + + *) On a error in the proxy, make it write a line to the error log + [Ian Holsman] + + *) Various mod_ssl performance improvements [Doug MacEachern] + +Changes with Apache 2.0.29 + + *) Add buffering in core_output_filter to ensure that long + lists of small buckets don't cause small packet writes. + [Brian Pane, Ryan Bloom] + + *) Fix the installation target to make sure that the manual is + installed in the correct location. + [Yoshifumi Hiramatsu and + Gomez Henri ] + + *) Fix the cmd command for mod_include. When we are processing + a cmd command, we do not want to use the r->filename to set + the command name. The command comes from the SSI tag. To do this, + I added a variable to the function that builds the command line + in mod_cgi. This allows the include_cmd function to specify + the command line itself. [Ryan Bloom] + + *) Change open_logs hook to return a value, allowing you + to flag a error while opening logs + [Ian Holsman, Doug MacEachern] + + *) Change post_config hook to return a value, allowing you + to flag a error post config + [Ian Holsman, Jeff Trawick] + + *) Allow SUEXEC_BIN (the path to the suexec binary that is + hard-coded into the server) to be specified to the configure + script by the --with-suexec-bin parameter. [Aaron Bannert] + + *) Fix segv in worker MPM following accept on pipe-of-death + [Brian Pane] + + *) Add mod_deflate to experimental. + [Ian Holsman, Justin Erenkrantz] + + *) Bail out at configure time if an invalid MPM was specified. + [jean-frederic clere ] + + *) Prevent segv in ap_note_basic_auth_failure() when no AuthName is + configured [John Sterling ] + + *) Fix apxs to use sbindir. [Henri Gomez ] + + *) Fix a problem with IPv6 vhosts. PR #8118 [Jeff Trawick] + + *) Optimization for the BNDM string-search function in + mod_include. [Brian Pane] + + *) Fixed the behavior of the XBitHack directive. + [Taketo Kabe , Cliff Woolley] PR#8804 + + *) The threaded MPM for Unix has been removed. Use the worker + MPM instead. [various] + + *) APR-ize the resolver logic in mod_unique_id. This fixes a bug + in logging the error from a failed DNS lookup. [Jeff Trawick] + + *) Added the missing macros AP_INIT_TAKE13 and AP_INIT_TAKE123. + [Cliff Woolley] + + *) Get mod_cgid killed when a MPM exits due to a fatal error. + [Jeff Trawick] + + *) Fix a file descriptor leak in mod_include. When we include a + file, we use a sub-request, but we didn't destroy the sub-request + immediately, instead we waited until the original request was + done. This patch closes the sub-request as soon as the data is + done being generated. [Brian Pane ] + + *) Allow modules that add sockets to the ap_listeners list to + define the function that should be used to accept on that + socket. Each MPM can define their own function to use for + the accept function with the MPM_ACCEPT_FUNC macro. This + also abstracts out all of the Unix accept error handling + logic, which has become out of synch across Unix MPMs. + [Ryan Bloom] + + *) Fix a bug which would cause the response headers to be omitted + when sending a negotiated ErrorDocument because the required + filters were attached to the wrong request_rec. + [John Sterling ] + + *) Remove commas from the end of the macros that define + directives that are used by MPMs. Prior to this patch, + you would use these macros without commas, which was unlike + the macros for any other directives. Now, the caller provides + the comma rather than the macro providing it. This makes + the macros look more like the rest of the directives. + [Ryan Bloom and Cliff Woolley] + + *) Add 'redirect-carefully' environment option to disable sending + redirects under special circumstances. This is helpful for + Microsoft's WebFolders when accessing a directory resource via + DAV methods. [Justin Erenkrantz] + + *) Begin to abstract out the underlying transport layer. + The first step is to remove the socket from the conn_rec, + the server now lives in a context that is passed to the + core's input and output filters. This forces us to be very + careful when adding calls that use the socket directly, + because the socket isn't available in most locations. + [Ryan Bloom] + + *) Really reset the MaxClients value in worker and threaded + when the configured value is not a multiple of the number + of threads per child. We said we did previously but we + forgot to. [Jeff Trawick] + + *) Add Debian layout. [Daniel Stone ] + + *) If shared modules are requested and mod_so is not available, + produce a fatal config-time error. [Justin Erenkrantz] + + *) Improve http2env's performance by cutting the work it has to + do. [Brian Pane ] + + *) use new 'apr_hash_merge' function in mod_mime (performance fix) + [Brian Pane ] + +Changes with Apache 2.0.28 + + *) Fix infinite loop in mod_cgid.c. + [Dale Ghent , Brian Pane ] + + *) When no port is given in a "ServerName host" directive, the + server_rec->port is now set to zero, not 80. That allows for + run-time deduction of the correct server port (depending on + SSL/plain, and depending also on the current setting of + UseCanonicalName). This change makes redirections + work, even with https:// connections. As in Apache-1.3, the + connection's actual port number is never used, only the ServerName + setting or the client's Host: setting. Documentation updated + to reflect the change. [Martin Kraemer] + + *) Add a '%{note-name}e' argument to mod-headers, which works in + the same way as mod_log_confg. [Ian Holsman] + + *) Fix the spelling of the AP_MPMQ_MIN_SPARE_DAEMONS and + AP_MPMQ_MAX_REQUESTS_DAEMON macros in ap_mpm.h and all standard + MPMs. [Cliff Woolley] + + *) Introduce htdbm, a user management utility for db/dbm authorization + databases. [Mladen Turk ] + + *) Optimize usage of strlen and strcat in ap_directory_walk. + [Brian Pane ] + +Changes with Apache 2.0.27 + + *) Introduce an Apache mod_ssl initial configuration template + (ssl.conf, generated from ssl-std.conf). [Ralf S. Engelschall] + + *) Fixed a memory leak in the getline parsing code that could + be triggered by arbitrarily large header lines. Requests + from the core input filter for single lines are now limited + to HUGE_STRING_LEN (8192 bytes). [Aaron Bannert] + + *) Fix a truncation bug in how we print the port on the Via: header. + The routine that prints the Via: header now takes a length for + the port string. [Zvi Har'El ] + + *) Some syntax errors in mod_mime_magic's magic file can result + in a 500 error, which previously was unlogged. Now we log the + error. [Jeff Trawick] + + *) Add the support/checkgid helper app, which checks the run-time + validity of group identifiers usable in the Group directive. + [Ken Coar] + + *) Various --enable-so options have been fixed: --enable-so is + treated as "static"; explicit --enable-so=shared issues an error; + and explicit --enable-so fails with error on systems without + APR_HAS_DSO. [Aaron Bannert] + + *) Fix a segfault in the core input filter when the client socket + gets disconnected unexpectedly. [Cliff Woolley] + + *) Fix the reporting for child processes that die. This removes + all of the non-portable W* macros from Apache. + [Jeff Trawick and Ryan Bloom] + + *) Win32: Track and display "Parent Server Generation:" in + mod_status output. The generation will be bumped at + server graceful restart, when the child process exits + by hitting MaxRequestsPerChild or if the child + process exits abnormally. [Bill Stoddard] + + *) Win32: Fix problem where MaxRequestsPerChild directive was + not being picked up in favor of the default. Enable + the parent to start up a new child process immediately upon + the old child starting shutdown. + [Bill Stoddard] + + *) Fix some bungling of the remote port in rfc1413.c so that + IdentityCheck retrieves the proper user id instead of failing + and thus always returning "nobody." + [Dick Streefland ] + + *) Introduced thread saftey for mod_rewrite's internal cache. + [Brian Pane ] + + *) Simplified mod_env's directives to behave as most directives are + expected, in that UnsetEnv will not unset a SetEnv and PassEnv + directive following that UnsetEnv within the same container. + Also provides a runtime startup warning if a PassEnv configured + environment value is undefined. [William Rowe] + + *) The worker MPM is now completely ported to APR's new lock API. It + uses native APR types for thread mutexes, cross-process mutexes, + and condition variables. [Aaron Bannert] + + *) Sync up documentation to remove all references to the now deprecated + Port directive. [Justin Erenkrantz] + + *) Moved all ldap modules from the core to httpd-ldap sub-project + [Ryan Bloom] + + *) Exit when we can't listen on any of the configured ports. This + is the same behavior as 1.3, and it avoids having the MPMs to + deal with bogus ap_listen_rec structures. [Jeff Trawick] + + *) Cleanup the proxy code that creates a request to the origin + server. This change adds an optional hook, which allows modules + to gain control while the request is created if the proxy module + is loaded. The purpose of this hook is to allow modules to add + input and/or output filters to the request to the origin. While + I was at it, I made the core use this hook, so that proxy request + creation uses some of the code from the core. This can still be + greatly improved, but this is a good start. [Ryan Bloom] + +Changes with Apache 2.0.26 + + *) Port the MaxClients changes from the worker MPM to the threaded + MPM. [Ryan Bloom] + + *) Fix mod_proxy so that it handles chunked transfer-encoding and works + with the new input filtering system. [Justin Erenkrantz] + + *) Introduce the MultiviewsMatch directive, to allow the operator + to be flexible in recognizing Handlers and Filters filename + extensions as part of the Multiviews matching logic, strict with + MultiviewsMatch NegotiatedOnly to accept only filename extentions + that designate negotiated parameters, (content type, charset, etc.) + or MultiviewsAll for the 1.3 behavior of matching any files, even + if they have unregistered extensions. [William Rowe] + + *) Fixed the configure script to add a LoadModule directive to + the default httpd.conf for any module that was compiled + as a DSO. [Aaron Bannert ] + + *) rewrite mod_ssl input filtering to work with the new input filtering + system. [Justin Erenkrantz] + + *) prefork: Don't segfault when we are able to listen on some but + not all of the configured ports. [Jeff Trawick] + + *) Build mod_so even if no core modules are built shared. + [Aaron Bannert ] + + *) Introduce ap_directory_walk rewrite (with further optimizations + required) to adapt to the ap_process_request_internal() changes. + Optimized so subrequests and redirects now reuse previous section + merges, until we mismatch with the original directory_walk, and + precomputed r->finfo results will cause directory_walk to skip + the most expensive phases of the function. [William Rowe] + + *) Allow ApacheMonitor to connect to and control Apache on other + WinNT/2K machines. [Mladen Turk ] + + *) Remove the Port directive. In it's place, the Listen directive + is now a required directive, which tells Apache what port to + listen on. The ServerName directive has also been extended + to accept an optional port. If the port is specified to the + ServerName, the server will report that port whenever it + reports the port that it is listening on. This change was + made to ease configuration errors that stem from having a Port + directive, and a Listen directive. In that situation, the server + would only listen to the port specified by the Listen command, + which caused a lot of confusion to users. [Ryan Bloom] + + *) Added mod_mime_magic, mod_unique_id and mod_vhost_alias to the Win32 + build, as loadable modules. [William Rowe] + + *) Fix --enable-mods-shared processing. If most is specified, + then all modules that can be compiled as shared modules are. + [Aaron Bannert ] + + *) Update the mime.types file to map video/vnd.mpegurl to mxu + and add commonly used audio/x-mpegurl for m3u extensions. + [Heiko Recktenwald , Lars Eilebrecht] + + *) Eliminate the depreciated r->content_language, in favor of the array + r->content_languages introduced many years ago. Module authors must + substantially overhaul their modules, so this needs to be upgraded + if the module still relied on backwards-brokeness. [William Rowe] + + *) Allow configure help strings to work with autoconf 2.50+ and 2.13. + [Justin Erenkrantz] + + *) Rewrite the input filtering mechanisms to consolidate and reorganize + code. In short, core_input_filter does something now and + ap_http_filter is now only concerned with HTTP. [Justin Erenkrantz] + + *) Update the Win32 build to re-absorb mod_proxy and family. + [William Rowe] + + *) Resolved the build failure on Win32 using MSVC 5.0 (without the + current SDK.) [William Rowe] + + *) Some style changes to the code that does ProxyErrorOverride. Fixed + config merge behaviour. [Graham Leggett] + + *) Allow support programs to be compiled against a static version + of libapr. This allows the smaller support programs to be + relocated. [Aaron Bannert ] + + *) Update the mime.types file to the registered media types as + of 2001-09-25, and add mapping for xsl extension [Mark Cox] + + *) Fix MaxClients in the Worker MPM, so that it specifies the maximum + number of clients that can connect at the same time, instead of + specifying the maximum number of child processes. + [Aaron Bannert ] + + *) Switch proc_pthread AcceptMutex configuration directive to pthread to + be consistent with 1.3. [Justin Erenkrantz] + + *) Cache apr_explode_localtime() value for 15 seconds. + [Brian Pane ] + + *) Fix mod_include to not return ETag or Last-Modified headers. + [Ian Holsman ] + + *) Fix worker MPM's scoreboard logic. [Aaron Bannert ] + + *) Eliminate the wasteful run-time conversion of method names from strings + to numbers in places where the methods are known at compile time. + [Brian Pane ] + + *) Turn the worker MPM's queue into a LIFO. This may + improve cache-hit performance under some conditions. + [Aaron Bannert ] + + *) Switch back to SIGUSR1 for graceful restarts on all platforms that + support it. [Justin Erenkrantz] + + *) Cleanup the worker MPM. We no longer re-use transaction + pools. This incurs less overhead than shuffling the pools + around so that they can be re-used. Remove one of the + queue's condition variables. We just redefined the API to + state that you can't try to add more stuff than you allocated + segments for. [Aaron Bannert ] + + *) Fix SSL VPATH builds [Cody Sherr ] + + *) Fixed persistent connections when a request contains a body. + [Greg Stein] + + *) mod_dav uses a new API to speak to the backend provider for dead + property management. [Greg Stein] + + *) Remove the Win32 script-processing exception from mod_cgi, and + roll build_command_line/build_argv_list into a unified, overrideable + ap_cgi_build_command optional function. [William Rowe] + + *) Rewrite find_start_sequence to use a better search algorithm + to find the start tag. [Justin Erenkrantz] + + *) Fix a seg fault in mod_include. When we are generating an + internal redirect, we must set r->uri to "", not a bogus + string, and not NULL. [Ryan Bloom] + + *) Optimized location_walk, so subrequests, redirects and second passes + now reuse previous section merges on a by + basis, until we mismatch with the original location_walk. + [William Rowe] + + *) Back out the 1.45 change to util_script.c. This change made + us set the environment variable REQUEST_URI to the redirected + URI, instead of the originally requested URI. + [Taketo Kabe ] + + *) Make mod_include do lazy evaluation of potentially expensive to + compute variables. [Brian Pane ] + + *) Fix logging of bytes sent for HEAD requests. %b and %B should + log either - or 0, before this patch, they were both logging + the file size. [Taketo Kabe ] + + *) Make mod_include check for BYTE_CHECK_THRESHOLD per bucket rather + than per character. [Brian Pane ] + + *) Normalize the primary request, redirects and sub-requests to + run the same ap_process_request_internal for consistency in + robustness, behavior and security. [William Rowe] + + *) Fix a segfault with mod_include when r->path_info is not set + (which is the case with mod_proxy). [Ian Holsman ] + + *) Add -X functionality back. This indicates to all MPMs and any other + part of Apache that it should run in "debug" mode. [Justin Erenkrantz] + + *) Some initial support for the cygwin platform [prefork only]. + This is not to be confused with support for the WinNT/Win32 + platform, which is the recommended configuration for native + Win32 users. The cygwin platform support is recommended for + cygwin platform users. [Stipe Tolj ] + + *) Changed syntax of Set{Input|Output}Filter. The list of filters + must be semicolon delimited (if more than one filter is given.) + The Set{Input|Output}Filter directive now overrides a parent + container's directive (e.g. SetInputFilter in + will override any SetInputFilter directive in .) + This new syntax is more consistent with Add{Input|Output}Filter + directives defined in mod_mime. Also cures a bug in prior releases + where the Set{Input|Output}Filter directive would corrupt the + global configuration if the multiple directives were nested. + [William Rowe] + + *) Cured what's ailed mime for quite some time. If an AddSomething + was given in the configuration (Language, Charset, Handler or + Encoding) Apache would set the content type as given by AddType, + but refused to check the mime.types file if AddType wasn't given + for that specific extension. Setting the AddHandler for .html + without setting the AddType text/html html would cause Apache to + use the default content type. [William Rowe] + + *) Added some bulletproofing to memory allocation in the LDAP cache + code. [Graham Leggett] + +Changes with Apache 2.0.25 + + *) Move the installed /manual directory out of the /htdocs/ tree, so + that it can be kept more independently from the remaining document + root. The "Alias /manual ..." already allowed for easy projection + into existing private document trees. [Martin Kraemer] + + *) Add specified user attributes to the environment when using + mod_auth_ldap. This allows you to use mod_include to embed specified + user attributes in a page like so: + Hello , how are you? + [Graham Leggett] + + *) Fix a performance problem with the worker MPM. We now create + transaction pools once, and re-use them for each connection. + [Aaron Bannert ] + + *) Modfied mod_mime to prevent mod_negotation from serving a multiview + of a 'handler' or 'filter', so that any filename extension that does + not contribute to the negotiated metadata can't be served without + an explicit request. E.g., if the .Z extension is associated with + an unzip filter, the user request somefile.Z.html, mod_negotiation + won't serve it. It can serve somefile.Z.html when somefile.Z is + requested, since the .Z extension is explictly requested, if the + .html extension is associated with ContentType text/html. + [William Rowe] + + *) Introduce the AddInputFilter filter[;filter...] ext [ext...] + and corresponding AddOutputFilter syntax, to insert one or more + filters by mod_mime filename extension processing. + [William Rowe] + + *) Fix a growing connection pool in core_output_filter() for + keepalive requests. [Jeff Trawick] + + *) Moved split_and_pass_pretag_buckets back to being a + macro at Ryans's request. Removed the return from it + by setting and returning a return code instead. Updated + the code to check the return code from the macro and + do the right thing. [Paul J. Reder] + + *) Fix a segfault when a numeric value was received for Host:. + [Jeff Trawick] + + *) Add a function ap_remove_input_filter. This is to match + up with ap_remove_output_filter. [Ryan Bloom] + + *) Clean up location_walk, so that this step performs a minimum + amount of redundant effort (it must be run twice, but it will no + longer reparse all blocks when the request uri + hadn't changed.) [William Rowe] + + *) Eliminate proxy: (and all other 'special') processing from the + ap_directory_walk() phase. Modules that want to use special + walk logic should refer to the mod_proxy map_to_location example, + with it's proxy_walk and proxysection implementation. This makes + either directory_walk flavor much more legible, since that phase + only runs against real blocks. + [William Rowe] + + *) SECURITY: Fix a security problem in mod_include which would allow + an SSI document to be passed to the client unparsed. + [Cliff Woolley, Brian Pane] + + *) Introduce the map_to_storage hook, which allows modules to bypass + the directory_walk and file_walk for non-file requests. TRACE + shortcut moved to http_protocol.c as APR_HOOK_MIDDLE, and the + directory_walk/file_walk happen as APR_HOOK_VERY_LAST in core.c. + [William Rowe] + + *) Add the ability for mod_include to add the INCLUDES filter + if the file is configured for the server-parsed handler. + This makes the configuration for .shtml files much easier + to understand, and allows mod_include to honor Apache 1.3 + config files. Based on Doug MacEachern's patch to PHP + to do the same thing. [Ryan Bloom] + + *) force OpenSSL to ignore process local-caching and to always + get/set/delete sessions using mod_ssl's callbacks + [Madhusudan Mathihalli , + Geoff Thorpe ] + + *) Make the worker MPM shutdown and restart cleanly. This also + cleans up some race conditions, and gets the worker using + pools more cleanly. [Aaron Bannert ] + + *) Implement CRYPTO_set_locking_callback() in terms of apr_lock + for mod_ssl + [Madhusudan Mathihalli ] + + *) Fix for mod_include. Ryan's patch to check error + codes put a return in the wrong place. Also, the + include handler return code wasn't being checked. + I don't like macros with returns, so I converted + SPLIT_AND_PASS_PRETAG_BUCKETS into a function. + [Paul J. Reder ] + + *) fix segv in mod_mime if no AddTypes are configured + [John Sterling ] + + *) Enable ssl client authentication at SSL_accept time + [Madhusudan Mathihalli ] + + *) Fix a segfault in mod_include when the original request has no + associated filename (e.g., we're filtering the error document for + a bad URI). [Jeff Trawick] + + *) Fix a storage leak (a strdup() call) in mod_mime_magic. [Jeff Trawick] + + *) The prefork and OS/2 MPMs are overwriting the pid file when a second copy + of httpd is started and shuts down due to socket conflict. Moving the + call to ap_log_pid solves the problem. + + *) Changed the late-1.3 log_config substitution %c to %X, to log the + status of the closed connection, as it conflicts with the far more + common, historical ssl logging directive %...{var}c. [William Rowe] + + *) Added the common error/ tree to the build/install targets + (similar to the common icons/ tree) for the multi-language error + messages that Lars committed earlier. [William Rowe] + + *) Added a multi process, multi threaded OS/2 MPM mpmt_os2. [Brian Havard] + + *) Added a default commented-out mod_ldap and mod_auth_ldap + configuration to httpd-std.conf and httpd-win.conf + [Graham Leggett] + + *) Added documentation for mod_ldap and mod_auth_ldap. + [Graham Leggett] + + *) Enabled negative caching on attribute comparisons in the LDAP cache. + Fixed a problem where the default cache TTL was set in milliseconds + not microseconds causing the cache to time out almost immediately. + [Graham Leggett] + + *) Fixed all the #if APR_HAS_SHARED_MEMORY checks within the LDAP + module code to follow APR. [Graham Leggett] + + *) Fixed LDAP cleanup on graceful restarts. LDAP connections are now + cleaned up when the connection pool pool is cleaned up. + [Graham Leggett] + + *) Fix a minor issue with Jeff Trawick's mod_include + patch. Without this patch, the code will just allocate + more bytes in get_combined_directive than are needed. + [Paul Reder] + + *) Added the LDAP authentication module mod_auth_ldap. + [Dave Carrigan , Graham Leggett] + + *) Added the LDAP cache and connection pooling module mod_ldap. + [Dave Carrigan , Graham Leggett] + + *) Fix --enable-modules=all breakage with mod_auth_db and mod_auth_digest + by allowing a module to disable itself if its prerequisites are not + met. [Justin Erenkrantz] + +Changes with Apache 2.0.24 + + *) Fix a couple of issues in mod_include when the tag appeared at + offsets near 8192 in the file being parsed. [Jeff Trawick] + + *) Fix an assertion failure in mod_ssl when the keepalive timeout is + reached. [Jeff Trawick] + + *) Numerous improvements to the Win32 build system. Introduced command line + builds without requiring .mak files for MSVC 6.0 and later versions. + Improved .dsp file compatibility for both Visual Studio 5.0 and 6.0 users. + [William Rowe] + + *) Assorted corrections and improvements to the winnt_mpm startup code. Better + reporting of uninstalled services and other error conditions, and changed the + default service name to Apache2. [William Rowe] + + *) Numerous improvements to the Win32 ApacheMonitor utility, including winnt_mpm + compatibility with existing Apache 1.3 Win32 Apache management utilites. + [Mladen Turk , William Rowe] + + *) Fixed the segfaults in mod_mime introduced by hash tables in 2.0.20. + [William Rowe, Greg Ames] + + *) Rounded out the mod_mime Add/Remove pairs by adding RemoveLanguage + and RemoveCharset directives. [William Rowe] + + *) The Unix MPMs other than perchild now allow child server + processes to use the accept mutex when starting as root and + using SysV sems for the accept mutex. Previously, this + combination would lead to fatal errors in the child server + processes. perchild can't use SysV sems because of security + issues. [Jeff Trawick, Greg Ames] + + *) Added Win32 revision stamp resources to all http binaries + (including modules/ and support/ tools.) PR7322 [William Rowe] + + *) Fix ap_rvprintf to support more than 4K of data at one time. + [Cody Sherr ] + + *) We have always used the obsolete/deprecated Netscape syntax + for our tracking cookies; now the CookieStyle directive + allows the Webmaster to choose the Netscape, RFC2109, or + RFC2965 format. The new CookieDomain directive allows the + setting of the cookie's Domain= attribute, too. PR #s 5006, + 5023, 5920, 6140 [Ken Coar] + + *) Tweak server/Makefile so that the rules for generating exports.c + are compatible with make utilities which don't expand wildcards + in a dependency list (e.g., OS/390 make, certain levels of GNU + make). [Jeff Trawick] + + *) Install the SSL headers. [John Sterling ] + + *) Begin to sanitize the MPM configuration directives. Now, all + MPMs use the same functions for all common MPM directives. This + should make it easier to catch all bugs in these directives once. + [Cody Sherr ] + + *) Close a major resource leak. Every time we had issued a + graceful restart, we leaked a socket descriptor. + [Ryan Bloom] + + *) Fix a problem with the new method code. We need to cast + the 1 to an apr_int64_t or it will be treated as a 32-bit + integer, and it will wrap after being shifted 32 times. + [Cody Sherr and Ryan Morgan ] + + *) Fix a bug in mod_expires. Previous to this patch, if you + told mod_expires to add 604800 seconds to the last-modified + time, it actually added 604800 usec's to the last-modified time, + so that when looking at the response it looked like nothing + had been done. The root of the problem was that we always compute + time in usec's, but we ask users to input sec's. This means we + need to convert to usec's before using those values. + [Ryan Bloom] + + *) The worker MPM now handles shutdown and restart requests. It + definitely isn't perfect, but we do stop the servers correctly. + The biggest problem right now is that SIGHUP causes the server to + just die. [Ryan Bloom] + +Changes with Apache 2.0.23 + + *) Use the prefork MPM by default on Unix. [various] + + *) Added a systray icon monitor application for Win32. + [Mladen Turk ] + + *) mod_rewrite: Fix the line ending on some non-Unix systems for + messages written to the rewrite log. + [Richard Labennett ] + + *) All mod_autoindex query parsing is now quietly quashed with the + IndexOption IgnoreClient. The IndexOption SuppressColumnSorting + still drops the column sort 's for the column headers, but + IgnoreClient is required to ignore these Query options entirely. + [William Rowe] + + *) Introduced new mod_autoindex query argument parsing for F=[0|1|2] + to allow the client to select plain, FancyIndexing or HTMLTable + formatting, V=[0|1] to inhibit or enable version sorting, and + P=pattern to return only specific files. The old Query Arguments + were reorganized as C=f for sorting column 'f' (same N, D, S, or M + as before), and O=A|D for ordering ascending or descending. + [William Rowe] + + *) Fixed an error in mod_include's directive parsing routines which + caused #if, #elif, and #else expressions containing backslashes + to be improperly evaluated. [Cliff Woolley] + + *) Introduced new mod_autoindex IndexOptions flags: SuppressIcon to + drop the icon column, SuppressRules to drop the
elements, + and HTMLTable to create rudimentary HTML table listings (implies + FancyIndexing). [William Rowe] + + *) Re-introduced the mod_autoindex IndexOptions flag TrackModified + from Apache 1.3.15. This is needed for two reasons, first, given + multiple machines within a server farm, ETags and Last-Modified + stamps won't correspond from machine to machine, and second, many + Unixes don't capture changes to the date or time stamp of existing + files, since these don't modify the dirent itself. [William Rowe] + + *) Re-introduced the mod_autoindex IndexOptions flag FoldersFirst + and DirectoryWidth options from Apache 1.3.10. + [William Rowe, Ken Coar] + + *) Eliminated FancyIndexing directive, deprecated early in Apache + 1.3 by the IndexOptions FancyIndexing syntax. [William Rowe] + + *) mod_autoindex now excludes any file names that would result in + an error, other than a success or redirect. Also optimized + the parent directory, always included except in the URI '/'. + [William Rowe] + + *) Refactored mod_negotiation and mod_mime to help mod_dir accept + negotiated index pages, and prevent the server from defaulting + to an autoindex of the directory. mod_negotiation will now die + with a 500 Internal Error if it could match some filenames + (e.g. for mod_dir) but none can be served. mod_negotation now + refuses to serve any file with an extention that mod_mime doesn't + recognize, and wasn't part of the request. [William Rowe] + + *) Eliminate mod_cgi's handling of .exe files without the .exe file + extension. This is already handled by multiviews, if the admin + wishes to AddHandler .exe or define a content type handler and + associate .exe files with that content type. Multiviews must be + enabled to allow these to be served. [William Rowe] + + *) Speed up the server's response to a spike in incoming workload + or restarts by assigning empty scoreboard slots to new processes + when they are available. [Greg Ames] + + *) Add a handler to mod_includes.c. This handler is designed to + implement the XbitHack directive. This can't be done with a + fixup, because we need to check the content-type, which is + only available in the handler phase. [Ryan Bloom] + + *) Make the includes filter check return codes from filters lower in + the filter chain. If a lower level filter returns an error, then + the request needs to stop immediately. This allows mod_include to + stop parsing data once a lower filter recognizes an error. + [Ryan Bloom] + + *) Add the ability to extend the methods that Apache understands + and have those methods able in the httpd.conf. It uses + the same bit mask/shifted offset as the original HTTP methods + such as M_GET or M_POST, but expands the total bits from an int to + an ap_int64_t to handle more bits for new request methods than + an int provides. [Cody Sherr ] + + *) Fix broken mod_mime behavior in merging its arguments. Possible + cause of unexplicable crashes introduced in 2.0.20. [William Rowe] + + *) Solve many mod_ssl porting issues (too many to detail) with + help from the whole team, but most notably [Ralf S. Engelschall, + Madhusudan Mathihalli , + Doug MacEachern, William Rowe, Cliff Woolley] + + *) More stall fixes for the threaded & worker mpm's. + Make mod_status output more accurate. Don't + count workers in processes which aren't actively + serving requests. [Greg Ames] + + *) Win32: Get SSI exec cgi tag working. [Bill Stoddard] + + *) Add a single listener/multiple worker MPM. This MPM is + definately not fully correct, but it allows us to solve many + of the problems that exist in the threaded MPM. This is a + modified version of the threaded MPM. [Ryan Bloom] + + *) Improve content generation throughout Apache, providing closer + compliance with HTML 3.2, HTML 4.01 Transitional and XHTML 1.0 + Transitional specifications. [William Rowe] + +Changes with Apache 2.0.22 + + *) Fix a problem where the threaded MPM stalls after restarts or + segfaults. Also prevent multiple active processes from using + the same scoreboard slot. [Greg Ames] + + *) Apache/Win32 now fills in the service description with Apache's + server version string, including loaded and advertised modules. + [William Rowe] + + *) Improved support for the Win32 build, to recover gracefully from + missing apr or apr-util directories or the awk interpreter, + create the proper cgi-bin examples, including a test-cgi.bat, and + fix the perl shebang line for printenv.pl, when installing from + the build environment. [William Rowe] + + *) Fix a segfault in threaded.c caused by passing uninitialized + apr_thread_t * to apr_thread_join(). [Jeff Trawick] + + *) Use new APR number conversion functions to reduce CPU consumption + when setting the content length, and in mod_log_config. + [Brian Pane] + + *) Fix problem reported by Taketo Kabe + where HEAD response headers were being repeated twice for + files greater than 32K bytes (4*AP_MIN_BYTES_TO_WRITE). This + problem in the http_header filter was exposed by the recent rewrite + of the content_length filter. [Taketo Kabe, Bill Stoddard] + + *) Fix seg faults in mod_status with ExtendedStatus enabled, after + restarts. A garbage pointer to a vhost's server_rec from the + previous generation was being left around under certain + conditions. [Greg Ames] + + *) Fix a cosmetic problem with mod_include. Non-existant SSI vars + used to appear as '(none', without the closing paren. + [Günter Knauf ] + + *) Improve the exports generating awk script. In the past, we had + work around problems in the awk script by avoiding some #if and + #ifdefs. This has bitten us many times in generating the exports.c + file. This improvement allows corrects the header file parsing. + [Sander Striker ] + +Changes with Apache 2.0.21 + + *) Resolve the Win32 htpasswd bug, where a file that existed would be + overwritten, regardless of the -c flag. + [William Rowe, Mladen Turk ] + + *) Introduce connection sub-pools into ab. Truncating the lifetime + of these allocations means that ab no longer perpetually grows + its working set, running out of memory on large request attempts. + [William Rowe] + + *) Make scoreboard creation a hook. This allows management + modules to have access to the scoreboard at the time that it is + created, and at every restart request. + [Cody Sherr ] + + *) Changed AP_MPMQ_MAX_DAEMONS to refer to MaxClients and + added an AP_MPMQ_MAX_DAEMON_USED to refer to the highest + daemon index actually used in the scoreboard. I also + updated the pertinent calls. [Paul J. Reder] + + *) Win32: Prevent listening sockets from being inherited by + the Apache child process, CGI scripts, rotatelog process + etc. If the Apache child process segfaults, any processes + that the child started are not reaped. Prior to this fix, + these processes inherited the listening sockets which sometimes + prevented the restarted Apache child process from accepting + connections (ie, the server would hang). + [Bill Stoddard] + + *) Provide vhost and request strings when ExtendedStatus is on. + [Greg Ames] + + *) Fix some issues with the pod and prefork: check the pod *after* + processing a connection so that a server processing a time- + consuming request bails out as soon as practical; when the + parent process wakes up a server process via connect(), use an + APR timeout on the connect() so that we don't hang for a long + time if there aren't server processes around to do accept(). + [Jeff Trawick, Greg Ames] + + *) Performance improvement to mod_mime.c. find_ct() in mod_mime, + spends a lot of time in apr_table_get calls. Using the default + httpd.conf, the tables for languages and charsets are somewhat + large, so the time spent scanning them on each request is + significant. Replacing the tables with hash tables provides + a nice speedup. [Brian Pane ] + + *) Add two functions to allow modules to access random parts of the + scoreboard. This allows modules compiled for one MPM to access the + scoreboard, even if it the server was compiled for another MPM. + [Harrie Hazewinkel ] + +Changes with Apache 2.0.20 + + *) Fix problem in content-length filter where the filter would + buffer all the output from a CGI before sending any bytes + down the filter stack to the network. This problem would cause + significant memory consumption if the CGIs generated + lots of bytes. [Bill Stoddard] + + *) Get non-blocking CGI pipe reads working with the bucket brigades. + [Bill Stoddard] + + *) Fix seg fault on Windows when serving files cached with mod_file_cache. + [Bill Stoddard] + + *) Fix a bug in the threaded MPM that would cause it to kill off all + workers immediately after starting if the number of workers started + was above a certain threshold. [Ryan Bloom, Bill Stoddard] + +Changes with Apache 2.0.19 + + *) Fix problem with threaded MPM. The problem was that if each child + process was busy serving a single long-lived request and the server + was sent a graceful restart signal, the server would stop serving + requests. This would happen because each child process would wait to + die until the last thread was done, and the parent wouldn't spawn any + new children until a process died. Now, the parent looks at the fact + that the children are dying gracefully, and starts new children. + Those new children only start enough threads to compliment the number + of threads in the other child process that shares the same spot in + the scoreboard. In this way, we make sure to never go over + MaxClients. [Ryan Bloom] + + *) modified mod_negotiation and mod_autoindex to speed up by almost a + factor of two on apr_dir_read()-enhanced platforms, such as Win32 + and OS2, by calling ap_sub_request_lookup_dirent() with the results + already provided by apr_dir_read(). [William Rowe] + + *) mod_file_cache is now more robust to filtering and serves requests + slightly more efficiently. [Cliff Woolley] + + *) Fix problem handling FLUSH bucket in the chunked encoding filter. + Module was calling ap_rwrite() followed by ap_rflush() but the + served content was not being displayed in the browser. Inspection + of the output stream revealed that the first data chunk was + missing the trailing CRLF required by the RFC. [Bill Stoddard] + + *) apxs no longer generates ap_send_http_header() in the example handler + + *) Fix an ab problem which could cause a divide-by-zero exception + with certain invocations (e.g., ab -k -c 6 -n 100 localhost/). + [Ian Holsman ] + + *) Solve case-insensitive platforms' confusion about negotiated + filenames, allowing files of differnt case to match in choosing + the document to serve. [William Rowe] + + *) Fix brokenness when ThreadsPerChild is higher than the built-in + limit. We left ap_threads_per_child at the higher value which + led to segfaults when doing certain scoreboard operations. + [Jeff Trawick] + + *) Fix seg faults and/or missing output from mod_include. The + default_handler was using the subrequest pool for files and + MMAPs, even though the associated APR structures typically + live longer than the subrequest. [Greg Ames] + + *) Extend mod_setenvif to support specifying regular expressions + on the SetEnvIf (and SetEnvIfNoCase) directive attribute field. + Example: SetEnvIf ^TS* [a-z].* HAVE_TS + will cause HAVE_TS to be set if any of the request headers begins + with "TS" and has a value that begins with any character in the + set [a-z]. [Bill Stoddard] + + *) httpd children now re-bind themselves to a random CPU on + multiprocessor systems on AIX via bindprocessor() in 2.0. + [Victor J. Orlikowski] + + *) Fix htdigest. It would go into a loop in getline when adding + a second user. [Bill Stoddard] + + *) Win32 platforms now fully support mod_userdir options. [Will Rowe] + + *) Automatically generate httpd.exp for AIX. + DSOs now work again on AIX in 2.0 + [Victor J. Orlikowski] + + *) Add a new request hook, error_log. This phase allows modules + to act on the error log string _after_ it has been written + to the error log. The goal for this hook is to allow monitoring + modules to send the error string to the monitoring agent. + [Ryan Bloom] + + *) Modify mod_echo to make it use filters for input and output. + [Ryan Morgan ] + + *) Extend mod_headers to support conditional driven Header + add, append and set. Use SetEnvIf to set an envar and conditionally + add/append/set headers based on this envar thusly: + + SetEnvIf TSMyHeader value HAVE_TSMyHeader + Header add MyHeader "%t %D" env=HAVE_TSMyHeader + + If the request contains header "TSMyHeader: value" then header + MyHeader: "t=xxxxxxxxxx D=yyyy" will be sent on the response. + [Bill Stoddard] + + *) Extend mod_headers to support using format specifiers on Header + add, append and set header values. Two format specifiers are supported: + + %t - reports, in UTC microseconds since the epoch, when the + request was received. + + %D - reports the time, in microseconds, between when the request was + received and the response sent. + + Examples: + Header add MyHeader "This request served in %D microseconds. %t" + + results in a header being added to the response that looks like this: + + MyHeader: This request served in D=5438 microseconds. t=991424704447256 + + [Bill Stoddard] + + *) Fix reset_filter(). We need to be careful how we remove filters. + If we set r->output_filters to NULL, we also have to reset the + connection's filters. [John Sterling] + + *) Optimise reset_filter() in http_protocol.c. [Greg Stein] + + *) Add a check to ap_die() to make sure the filter stack is sane and + contains the correct basic filters when an error occurs. This fixes + a problem where headers are not being sent on error. [John Sterling] + + *) New Header directive 'echo' option. "Header echo regex" will + cause any headers received on the request that match regex to be + echoed to (included in) the response headers. + [Bill Stoddard] + + *) include/ap_compat.h tested and set APR_COMPAT_H instead of AP_COMPAT_H. + This prevented the inclusion of apr_compat.h. PR #7773 + [Oleg Broytmann ] + + *) Moved util_uri to the apr-util library. This required a bunch of + apr_name changes for the uri utility functions. [Justin Erenkrantz] + + *) Move the addition of default AP_HTTP_HTTP_HEADER filters to the + insert_filter phase so that other filters are not bypassed by default. + [Graham Leggett] + + *) Reimplement mod_headers as an output filter. mod_headers can now + add custom headers to inbound requests using the RequestHeader directive + and to responses using the same old Header directive. [Graham Leggett] + +Changes with Apache 2.0.18 + + *) Fix command-line processing so that if a bad argument is specified + Apache will exit. [Jeff Trawick] + + *) Change the make targets and rules to be consistent in all of the + Apache-owned source trees. [Roy Fielding] + + *) Fix processing of the TRACE method. Previously we passed bogus + parms to form_header_field() and it overlaid some vhost structures, + resulting in a segfault in check_hostalias(). + [Greg Ames, Jeff Trawick] + + *) Win32: Add support for reliable piped logs. If the logging process + goes down, Apache will automatically restart it. This function has + been part of Apache on Unix/Linux/BSD since the early v1.3 releases. + [Bill Stoddard] + + *) Do not start piped log processes during the config file + preflight. This change also circumvents a problem on + Windows where the rotatelog processes created during preflight + was not getting cleaned up properly. + [Bill Stoddard] + + *) add "Request Phase Participation" info to mod_info + [Doug MacEachern] + + *) Make first phase changes to the scoreboard data structures in + preparation for the rewriting of the scoreboard per my posted + design notes. [Paul J. Reder] + + *) Fix httpd's definition of LTFLAGS to be consistent with that of apr + and apr-util, allow it to be overridden by the configure command-line + (default="--silent") and introduce LT_LDFLAGS to replace what we were + formerly abusing as LTFLAGS. [Roy Fielding] + + *) Clean up the reporting of incorrect closing container tags. + [Barrie Slaymaker ] + + *) Simplify the configure process by moving all libtool stuff to APR + and moving hints.m4 inline. [Roy Fielding] + + *) Add the AP_DECLARE()/AP_CORE_DECLARE macros on the return types + of functions used by mod_proxy for export in the DLL + [Ian Holsman ] + + *) Prevent a hang when a cgi handled by mod_cgid tries to read a + request body from its stdin but no reqest body is being written to + the cgi. [Jeff Trawick] + + *) mod_log_config: %c connection status incorrectly logged + as "-" (non-keepalive) when MaxKeepAliveRequests is set to 0. + [Bill Stoddard] + + *) Get mod_cern_meta working under Windows + [Bill Stoddard] + + *) Create Files, and thus MMAPs, out of the request pool, not the + connection pool. This solves a small resource leak that had us + not closing files until a connection was closed. In order to do + this, at the end of the core_output_filter, we loop through the + brigade and convert any data we have into a single HEAP bucket + that we know will survive clearing the request_rec. + [Ryan Bloom, Justin Erenkrantz , + Cliff Woolley] + + *) Completely revamp configure so that it preserves the standard make + variables CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS and LIBS by moving + the configure additions to EXTRA_* variables. Also, allow the user + to specify NOTEST_* values for all of the above, which eliminates the + need for THREAD_CPPFLAGS, THREAD_CFLAGS, and OPTIM. Fix the setting + of INCLUDES and EXTRA_INCLUDES. Check flags as they are added to + avoid pointless duplications. Fix the order in which flags are given + on the compile and link lines. Remove obsolete macros APR_DOEXTRA, + AC_ADD_LIBRARY, AC_CHECK_DEFINE, APACHE_PASSTHRU, and APACHE_ONCE. + Added APR_SAVE_THE_ENVIRONMENT and APR_RESTORE_THE_ENVIRONMENT macros. + Renamed AC_TYPE_RLIM_T macro to APACHE_TYPE_RLIM_T. [Roy Fielding] + + *) Get mod_tls to compile/work better on Windows. PR #7612 + [Bernhard Schrenk ] + + *) Fix shutdown/restart hangs in the threaded MPM. + [Jeff Trawick, Greg Ames, Ryan Bloom] + + *) Removed the keptalive boolean from conn_rec because it is now only + used by a single routine and can be replaced by a local variable. + [Greg Stein, Ryan Bloom, Roy Fielding] + + *) Patch prefork to put enough of the signal processing back in so that + signals are all handled properly now. The previous patch fixed the + deadlock race condition, but broke the user directed signal handling. + This fixes it to work the way it did before my previous prefork patch + (primarily, SIGTERM is now working). + + *) Change how input filters decide how much data is returned to the + higher filter. We used to use a field in the conn_rec, with this + change, we use an argument to ap_get_brigade to determine how much + data is retrieved. [Ryan Bloom] + + *) Fix seg fault at start-up introduced by Ryan's change to enable + modules to specify their own logging tags. mod_log_config + registers an optional function, ap_register_log_handler(). + ap_register_log_handler() was being called by http_core before + the directive hash table was created. This patch creates the + directive hash table before ap_register_log_handler() is + registered as an optional function. + [jean-frederic clere ] + + *) Add ap_set_int_slot() function + [John K. Sterling ] + + *) Under certain circumstances, Apache did not supply the + right response headers when requiring authentication. + [Gertjan van Wingerde ] PR#7114 + (This is a port of the change that went into Apache 1.3.19.) + + *) Allow modules to specify their own logging tags. This basically + allows a module to tell mod_log_config that when %x is encountered + a specific function should be called. Currently, x can be any single + character. It may be more useful to make this a string at some point. + [Ryan Bloom] + +Changes with Apache 2.0.17 + + *) If a higher-level filter handles the byterange aspects of a + request, then the byterange filter should not try to redo the + work. The most common case of this happening, is a byterange + request going through the proxy, and the origin server handles + the byterange request. The proxy should ignore it. + [Graham Leggett ] + + *) Changed the threaded mpm to have child_main join to each of the + worker threads to make sure the kids are all gone before child_main + exits after a signal (cleanup from perform_idle_server_maintenance). + This is an extension of Ryans recent commit to make the child_main + the signal thread. + + *) Add more options to the ap_mpm_query function. This also allows MPMs to + report if their threads are dynamic or static. Finally, this also + implements a new API, ap_show_mpm, which returns the MPM that was + required into the core. [Harrie Hazewinkel ] + + *) Do not install the binaries from the support directory twice. + [jun-ichiro hagino ] + + *) The ap_f* functions should flush data to the filter that is passed + in, not the filter after the one passed in. + [Ryan Morgan ] + + *) Make ab work again by changing its native types to apr types and formats. + [Justin Erenkrantz ] + + *) Move the byterange filter and all of the supporting functions back + to the HTTP module. The byterange filter turned out to be very + HTTP specific, and it belongs in the HTTP module. [Greg Stein] + + *) Make clean, distclean, and extraclean consistently according to the + Gnu makefile guidelines. [Justin Erenkrantz ] + + *) Fix errors in the renaming of the apr_threadattr_detach_xxx functions. + This may have been causing problems stopping processes in the threaded + mpm's. [Greg Ames] + + *) Fix content-length in mod_negotiation to a long int representation. + [William Rowe] + + *) Remove BindAddress from the default config file. + [] + + *) Allow module authors to add a module to their Apache build using + --with-module, without re-running buildconf. The syntax is: + --with-module=module_type:/path/to/module.c + The configure script will copy the module.c file to + modules/module_type, and it will be added to the relevant Makefiles. + currently, this only works for static modules. [Ryan Bloom] + + *) Changes required to make prefork clean up idle children properly. + There was a window during which a starting worker deadlocks when + an idle cleanup arrives before it completes init. Apache then keeps + trying to cleanup the same deadlocked worker forever (until higher + pids come along, but it still will never reduce below the deadlocked + pid). Thus the number of children would not reduce to the correct + idle level. [Paul J. Reder] + +Changes with Apache 2.0.16 + + *) Change the default installation directory to /usr/local/apache2, + as now defined by the "Apache" layout in config.layout. [Marc Slemko] + + *) OS/2: Added support for building loadable modules as OS/2 DLLs. + [Brian Havard] + + *) Get MaxRequestsPerChild working with the Windows MPM. + [Bill Stoddard] + + *) Make generic hooks to work, with mod_generic_hook_import/export + experimental modules. [Ben Laurie, Will Rowe] + + *) Fix segfaults for configuration file syntax errors such as + "" followed by "" followed by "". [Jeff Trawick] + + *) Cleanup the --enable-layout option of configure. This makes + us use a consistent location for the config.layout file, and it + makes configure more portable. + [jun-ichiro hagino ] + + *) Changes to 'ab'; fixed int overrun's, added statistics, output in + csv/gnuplot format, rudimentary ssl support and various other tweaks + to make results more true to what is measured. The upshot of this it + turns out that 'ab' has often underreported the true performance of + apache. Often by a order of magnitude :-) See talk/paper of Sander + Temme at April ApacheCon 2001 for details. + [Dirk-Willem van Gulik] + + *) Clean up mod_cgid's temporary request pool. Besides fixing a + storage leak this ensures that some unnecessary pipes are closed. + [Jeff Trawick] + + *) Performance: Add quick_handler hook. This hook is called at the + very beginning of the request processing before location_walk, + translate_name, etc. This hook is useful for URI keyed content + caches like Mike Abbott's Quick Shortcut Cache. + [Bill Stoddard] + + *) top_module global variable renamed to ap_top_module [Perl] + + *) Move ap_set_last_modified to the core. This is a potentially + controversial change, because this is kind of HTTP specific. However + many protocols should be able to take advantage of this kind of + information. I expect that headers will need one more layer of + indirection for multi-protocol work, but this is a small step in + the right direction. [Ryan Bloom] + + *) Enable mod_status by default. This matches what Apache 1.3 does. + [Ed Korthof] + + *) Add a ScriptSock directive to the default config file. This is + only enabled when mod_cgid is used. + [Taketo Kabe ] + +Changes with Apache 2.0.15 + + *) Untangled the buildconf script and eliminated the need for build's + aclocal.m4, generated_lists, build.mk, build2.mk, and a host of other + libtool muck that is now under srclib/apr/build. [Roy Fielding] + + *) Win32: Don't accept more connections than we have worker threads + to handle. + [Bill Stoddard] + + *) Fix bug in the Unix threaded.c MPM that allowed child processes + to fork() new child processes. + [Bill Stoddard] + + *) SECURITY: Fix a major security problem with double-reverse lookup + checking. Previously, a client connecting over IPv4 would not be + matched properly when the server had an IPv6 listening socket. + PR #7407 [Taketo Kabe ] + + *) Change the way the beos MPM handles polling to allow it to stop and + restart. Problem was the sockets being polled were being reset by + the select call, so once it had accepted a connection it was no + longer listening on the UDP socket we use for shutdown instructions. + APR needs to be altered, patch on it's way. [David Reid] + + *) Empty out the brigade shared by ap_getline()/ap_get_client_block() + on error exit from ap_getline(). Some other code got upset because + the wrong data was in the brigade. [Greg Ames, Jeff Trawick] + + *) Handle ap_discard_request_body() being called more than once. + [Greg Ames, Jeff Trawick] + + *) Get rid of an inadvertent close of file descriptor 2 in + mod_mime_magic. [Greg Ames, Jeff Trawick] + + *) Add a hook, create_request. This hook allows modules to modify + a request while it is being created. This hook is called for all + request_rec's, main request, sub request, and internal redirect. + When this hook is called, the r->main, r->prev, r->next + pointers have been set, so modules can determine what kind of + request this is. [Ryan Bloom] + + *) Cleanup the build process a bit more. The Apache configure + script no longer creates its own helper scripts, it just + uses APR's. + [jean-frederic clere ] + + *) Stop the forced downgrade of the connection to HTTP/1.0 for + proxy requests. [Graham Leggett] + + *) Avoid using sscanf to determine the HTTP protocol number in + the common case because sscanf is a performance hog. From + Mike Abbot's Accelerating Apache patch number 6. + [Mike Abbot , Bill Stoddard] + + *) SECURITY: Fix a security exposure in mod_access. Previously when + IPv6 listening sockets were used, allow/deny-from-IPv4-address rules + were not evaluated properly (PR #7407). Also, add the ability to + specify IPv6 address strings with optional prefix length on Allow + and Deny. [Jeff Trawick] + + *) Enhance rotatelogs so that a UTC offset can be specified, and + the logfile name can be formatted using strftime(3). (Brought + forward from 1.3.) [Ken Coar] + + *) Reimplement the Windows MPM (mpm_winnt.c) to eliminate calling + DuplicateHandle on an IOCompletionPort (a practice which + MS "discourages"). The new model does not rely on associating + the completion port with the listening sockets, thus the + completion port can be completely managed within the child + process. A dedicated thread accepts connections off the network, + then calls PostQueuedCompletionStatus() to wake up worker + threads blocked on the completion port. + [Bill Stoddard] + + *) Bring forward the --suexec-umask option which allows the + builder to preset the umask for suexec processes. [Ken Coar] + + *) Add a -V flag to suexec, which causes it to display the + compile-time settings with which it was built. (Only + usable by root or the AP_HTTPD_USER username.) [Ken Coar] + + *) Mod_include should always unset the content-length if the file is + going to be passed through send_parsed_content. There is no to + determine if the content will change before actually scanning the + entire content. It is far safer to just remove the C-L as long + as we are scanning it. [Ryan Bloom] + + *) Make sure Apache sends WWW-Authenticate during a reverse proxy + request and not Proxy-Authenticate. + [Graham Leggett ] + +Changes with Apache 2.0.14 + + *) Fix content-length computation. We ONLY compute a content-length if + We are not in a 1.1 request and we cannot chunk, and this is a keepalive + or we already have all the data. [Ryan Bloom] + + *) Report unbounded containers in the config file. Previously, a typo + in the directive could result in the rest of the config + file being silently ignored, with undesired defaults used. + [Jeff Trawick] + + *) Make the old_write filter use the ap_f* functions for the buffering. + [Ryan Bloom] + + *) Move more code from the http module into the core server. This + is core code, basically the default handler, the default input + and output filters, and all of the core configuration directives. + All of this code is required in order for the server to work, with or + without HTTP. The server is closer to working without the HTTP + module, although there is still more to do. [Ryan Bloom] + + *) Fix a number of SGI compile warnings throughout the server. Fix some + bad parameters to apr_bucket_read(). Fix a bad statement in + ap_method_in_list(). For the mod_rewrite cache use apr_time_t + consistently; we were mixing apr_time_t and time_t in invalid ways + before. In load_file(), call apr_dso_error() instead of + apr_strerror() so that we get a more specific string on some platforms. + PR #6980 [Jeff Trawick] + + *) Allow modules to query the MPM about it's execution profile. This + query API can and should be extended in the future, but for now, + max_daemons, and threading or forking is a very good start. + [Jon Travis ] + + *) Modify mod_include to send blocks of data no larger than 9k. + Without this, mod_include will wait until the whole file is parsed, + or the first tag is found to send any data to the client. + [Paul J. Reder ] + + *) Fix mod_info, so that and directives are + not displayed twice when displaying the current configuration. + [Ryan Morgan ] + + *) Add config directives to override DEFAULT_ERROR_MSG and + DEFAULT_TIME_FORMAT. This was sent in as PR 6193. + [Dan Rench ] + + *) Get mod_info building and loading on Win32. [William Rowe] + + *) Begin to move protocol independant functions out of mod_http. The goal + is to have only functions that are HTTP specific in the http directory. + [Ryan Bloom] + +Changes with Apache 2.0.13 + + *) Don't assume that there will always be multiple calls to the byterange + filter. It is possible that we will need to do byteranges with only + one call to the filter. [Ryan Morgan ] + + *) Move the error_bucket definition from the http module to the + core server. Every protocol will need this ability, not just + HTTP. [Ryan Bloom] + +Changes with Apache 2.0.12 + + *) Modify mod_file_cache to save pre-formatted strings for + content-length and last-modified headers for performance. + [Mike Abbot ] + + *) Namespace protect IOBUFSIZ since it is exposed in the API. + [Jon Travis ] + + *) Use "Basic" authentication instead of "basic" in ab, as the spec + says we should. [Andre Breiler ] + + *) Fix a seg fault in mod_userdir.c. We used to use the pw structure + without ever filling it out. This fixes PR 7271. + [Taketo Kabe and + Cliff Woolley ] + + *) Add a couple of GCC attribute tags to printf style functions. + [Jon Travis ] + + *) Add the correct language tag for interoperation with the Taiwanese + versions of MSIE and Netscape. [Clive Lin ] PR#7142 + + *) Migrate the perchild MPM to use the new apr signal child, and + APR thread functions. [Ryan Bloom] + + *) Close one copy of the CGI's stdout before creating the new process. + The CGI will still have stdout, because we have already dup'ed it. + This keeps Apache from waiting forever to send the results of a CGI + process that has forked a long-lived child process. + [Taketo Kabe ] + + *) Remove the rest of the pthreads functions from the threaded MPM. + This requires the APR support for a signal thread that was just + added. [Ryan Bloom] + + *) Make mod_dir use a fixup for sending a redirect to the browser. + Before this, we were using a handler, which doesn't make much + sense, because the handler wasn't generating any data, it would + either return a redirect error code, or DECLINED. This fits the + current hooks better. [Ryan Morgan ] + + *) Make the threaded MPM use APR threads instead of pthreads. + [Ryan Bloom] + + *) Get mod_tls to the point where it actually appears to work in all cases. + [Ben Laurie] + + *) implement --enable-modules and --enable-mods-shared for "all" and + "most". [Greg Stein] + + *) Move the threaded MPM to use APR locks instead of pthread locks. + [Ryan Bloom] + + *) Rename mpmt_pthread to threaded. This is more in line with the + fact that mpmt_pthread shouldn't be using pthreads directly, and + it is a smaller name that doesn't tie into anything. + [Ryan Bloom] + + *) Rename the module structures so that the exported symbol matches + the file name, and it is easier to automate the installation + process (generating LoadModule directives from the module filenames). + [Martin Kraemer] + + *) Remove the coalesce filter. With the ap_f* functions, this filter + is no longer needed. [Ryan Bloom] + +Changes with Apache 2.0.11 + + *) Remove the dexter MPM. Perchild is the same basic idea, but it has the + added feature of allowing a uid/gid per child process. If no + uid/gid is specified, then Perchild behaves exactly like dexter. + [Ryan Bloom] + + *) Get perchild building again. [Ryan Bloom] + + *) Don't disable threads just because we are using the prefork MPM. + If somebody wants to compile without threads, they must now add + --disable-threads to the configure command line. [Ryan Bloom] + + *) Begin to move the calls to update_child_status into common code, so + that each individual MPM does not need to update the scoreboard itself. + [Ryan Bloom] + + *) Allow mod_tls to compile under Unix boxes where openssl has been + installed to the system include files. + [Gomez Henri ] + + *) Cleanup the mod_tls configure process. This should remove any need + to hand-edit any files. We require OpenSSL 0.9.6 or later, but + configure doesn't check that yet. [Ryan Bloom] + + *) Add a very early prototype of SSL support (in mod_tls.c). It is + vital that you read modules/tls/README before attempting to build + it. [Ben Laurie] + + *) Fix a potential seg fault on all platforms. David Reid fixed this + on BEOS, but the problem could happen anywhere, so we don't want + to #ifdef it. [Cliff Woolley ] + + *) Add new LogFormat directive, %D, to log time it takes to serve a + request in microseconds. [Bill Stoddard] + + *) Change AddInputFilter and AddOutputFilter to SetInputFilter and + SetOutputFilter. This corresponds nicely with the other Set + directives, which operate on containers while the Add* directives + tend to work directly on extensions. [Ryan Bloom] + + *) Cleanup the header handling a bit. This uses the apr_brigade_* + functions for the buffering so that we don't need to compute + the length of the headers before we actually create the header + buffer. [Ryan Bloom] + + *) Allow filters to buffer data using the ap_f* functions. These have + become macros that resolve directly to apr_brigade_*. + [Ryan Bloom] + + *) Get the Unix MPM's to do a graceful restart again. If we are going + to register a cleanup with ap_cleanup_scoreboard, then we have to + kill the cleanup with the same function, and that function can't be + static. [Ryan Bloom] + + *) Install all required header files. Without these, it was not + possible to compile some modules outside of the server. + [Ryan Bloom] + + *) Fix the AliasMatch directive in Apache 2.0. When we brought a patch + forward from 1.3 to 2.0, we missed a single line, which broke regex + aliases. [Ryan Bloom] + + *) We have a poor abstraction in the protocol. This is a temporary + hack to fix the bug, but it will need to be fixed for real. If + we find an error while sending out a custom error response, we back + up to the first non-OK request and send the data. Then, when we send + the EOS from finalize_request_protocol, we go to the last request, + to ensure that we aren't sending an EOS to a request that has already + received one. Because the data is sent on a different request than + the EOS, the error text never gets sent down the filter stack. This + fixes the problem by finding the last request, and sending the data + with that request. [Ryan Bloom] + + *) Make the server status page show the correct restart time, and + thus the proper uptime. [Ryan Bloom] + + *) Move the CGI creation logic from mod_include to mod_cgi(d). This + should reduce the amount of duplicate code that is required to + create CGI processes. + [Paul J. Reder ] + + *) ap_new_connection() closes the socket and returns NULL if a socket + call fails. Usually this is due to a connection which has been + reset. [Jeff Trawick] + + *) Move the Apache version information out of httpd.h and into release.h. + This is in preparation for the first tag with the new tag and release + system. [Ryan Bloom] + + *) Begin restructuring scoreboard code to enable adding back in + the ability to use IPC other than shared memory. + Get mod_status working on Windows again. [Bill Stoddard] + + *) Make mod_status work with 2.0. This will work for prefork, + mpmt_pthread, and dexter. [Ryan Bloom] + + *) Correct a typo in httpd.conf. + [Kunihiro Tanaka ] PR#7154 + + *) Really fix mod_rewrite map lookups this time. [Tony Finch] + + *) Get the correct IP address if ServerName isn't set and we can't + find a fully-qualified domain name at startup. + PR#7170 [Danek Duvall ] + + *) Make mod_cgid work with SuExec. [Ryan Bloom] + + *) Adopt apr user/group name features for mod_rewrite. Eliminates some + 'extra' stat's for user/group since they should never occur, and now + resolves the SCRIPT_USER and SCRIPT_GROUP, including on WinNT NTFS + volumes. [William Rowe] + + *) Adopt apr features to simplify mod_includes. This changes the + behavior of the USER_NAME variable, unknown uid's are now reported + as USER_NAME="" rather than the old user#000 result. + WinNT now resolves USER_NAME on NTFS volumes. [William Rowe] + + *) Adopt apr features for simplifing mod_userdir, and accept the new + Win32/OS2 exceptions without hiccuping. [William Rowe] + + *) Replace configure --with-optim option by using and saving the + environment variable OPTIM instead. This is needed because configure + options do not support multiple flags separated by spaces. + [Roy Fielding] + + *) Fix some byterange handling. If we get a byte range that looks like + "-999999" where that is past the end of the file, we should return + a PARTIAL CONTENT status code, and return the whole file as one big + byterange. This matches the 1.3 handling now. [Ryan Bloom] + + *) Make the error bucket a real meta-data bucket. This means that the + bucket length is 0, and a read returns NULL data. If one of these + buckets is passed down after the headers are sent, this data will + just be ignored. [Greg Stein] + + *) The prefork MPM wasn't killing child processes correctly if a restart + signal was received while the process was serving a request. The child + process would become the equivalent of a second parent process. If + we break out of the accept loop, then we need to do die after cleaning + up after ourselves. [Ryan Bloom] + + *) Change the Prefork MPM to use SIGWINCH instead of SIGUSR1 for graceful + restarts. [Ryan Bloom] + + *) Modify the apr_stat/lstat/getfileinfo calls within apache to use + the most optimal APR_FINFO_wanted bits. This spares Win32 from + performing very expensive owner, group and permission lookups + and allows the server to function until these apr_finfo_t fields + are implemented under Win32. [William Rowe] + + *) Support for typedsafe optional functions - that is functions exported by + optional modules, which, therefore, may or may not be present, depending + on configuration. See the experimental modules mod_optional_fn_{ex,im}port + for sample code. [Ben Laurie] + + *) filters can now report an HTTP error to the server. This is done + by sending a brigade where the first bucket is an error_bucket. + This bucket is a simple bucket that stores an HTTP error and + a string. Currently the string is not used, but it may be needed + to output an error log. The http_header_filter will find this + bucket, and output the error text, and then return + AP_FILTER_ERROR, which informs the server that the error web page + has already been sent. [Ryan Bloom] + + *) If we get an error, then we should remove all filters except for + those critical to serving a web page. This fixes a bug, where + error pages were going through the byterange filter, even though + that made no sense. [Ryan Bloom] + + *) Relax the syntax checking of Host: headers in order to support + iDNS. PR#6635 [Tony Finch] + + *) Cleanup the byterange filter to use the apr_brigade_partition + and apr_bucket_copy functions. This removes a lot of very messy + code, and hopefully makes this filter more stable. + [Ryan Bloom] + + *) Remove AddModule and ClearModuleList directives. Both of these + directives were used to ensure that modules could be enabled + in the correct order. That requirement is now gone, because + we use hooks to ensure that modules are in the correct order. + [Ryan Bloom] + + *) When SuExec is specified, we need to add it to the list of + targets to be built. If we don't, then any changes to the + configuration won't affect SuExec, unless 'make suexec' is + specifically run. [Ryan Bloom] + + *) Cleaned out open_file from mod_file_cache, as apr now accepts + the APR_XTHREAD argument to open a file for consumption by + parallel threads on win32. [William Rowe] + + *) Correct a bug in determining when we follow symlinks. The code + expected a stat -1 result, not an apr_status_t positive error. + Also check if the APR_FINFO_USER fields are valid before we + follow the link. [William Rowe] + + *) Move initgroupgs, ap_uname2id and ap_gname2id from util.c to + mpm_common.c. These functions are only valid on some platforms, + so they should not be in the main-line code. [Ryan Bloom] + + *) Remove ap_chdir_file(). This function is not thread-safe, + and nobody is currently using it. [Ryan Bloom] + + *) Do not try to run make depend if there are no .c files in the + current directory, doing so makes `make depend` fail. + [Ryan Bloom] + + *) Update highperformance.conf to work with either prefork or + pthreads mpms. [Greg Ames] + + *) Stop checking to see if this is a pipelined request if we know + for a fact that it isn't. Basically, if r->connection->keepalive == 0. + This keeps us from making an extra read call when serving a 1.0 + request. [Ryan Bloom and Greg Stein] + + *) Fix the handling of variable expansion look-ahead in mod_rewrite, + i.e. syntax like %{LA-U:REMOTE_USER}, and also fix the parsing of + more complicated nested RewriteMap lookups. PR#7087 [Tony Finch] + + *) Fix the RFC number mentioned when complaining about a missing + Host: header. PR#7079 [Alexey Toptygin ] + + *) Fix an endless loop in ab which occurred when ab was posting + and the server dropped the connection unexpectedly. + [Jeff Trawick] + + *) Fix a segfault while handling request bodies in ap_http_filter(). + This problem has been seen with mod_dav usage as well as with + requests where the body was just being discarded. [Jeff Trawick] + + *) Some adjustment on the handling and automatic setting (via + hints.m4) of various compilation flags (eg: CFLAGS). Also, + add the capability to specify flags (NOTEST_CFLAGS and + NOTEST_LDFLAGS) which are used to compile Apache, but + not used during the configuration process. Useful for + flags like "-Werror". [Jim Jagielski] + + *) Stop using environment variables to force debug mode or + no detach. We now use the -D command line argument to + specify the correct mode. -DONE_PROCESS and -DNO_DETACH. + [Greg Stein, Ryan Bloom] + + *) Change handlers to use hooks. [Ben Laurie] + + *) Stop returning copies of filenames from both apr_file_t and + apr_dir_t. We pstrdup the filenames that we store in the + actual structures, so we don't need to pstrdup the strings again. + [Ryan Bloom] + + *) mod_cgi: Fix some problems where the wrong error value was being + traced. [Jeff Trawick] + + *) EBCDIC: Fix some missing ASCII conversion on some protocol data. + [Jeff Trawick] + + *) Add generic hooks. [Ben Laurie] + + *) Use a real pool to dup the error log descriptor. [Ryan Bloom] + + *) Fix a segfault caused by mod_ext_filter when the external filter + program does not exist. [Jeff Trawick] + + *) Fix an output truncation error when on an HTTP >= 1.0 request an + object of size between DEFAULT_BUCKET_SIZE and AP_MIN_BYTES_TO_WRITE + was served through mod_charset_lite (or anything else that would + create a transient bucket in this size range). ap_bucket_make_heap() + silently failed (fixed), transient_setaside() discovered it, but + ap_save_brigade() ignored it (fixed). [Jeff Trawick] + + *) Ignore \r\n or \n when using PEEK mode for input filters. The problem + is that some browsers send extra lines at the end of POST requests, and + we don't want to delay sending data back to the user just because the + browser isn't well behaved. [Ryan Bloom] + + *) Get SuEXEC working again. We can't send absolute paths to suExec + because it refuses to execute those programs. SuEXEC also wasn't + always recognizing configuration changes made using the autoconf + setup. [Ryan Bloom] + + *) Allow the buildconf process to find the config.m4 files in the correct + order. Basically, we can now name config.m4 files as config\d\d.m4, + and we will sort them correctly when inserting them into the build + process. [Ryan Bloom] + + *) Get mod_cgid to use apr calls for creating the actual CGI process. + This also allows mod_cgid to use ap_os_create_priviledged_process, + thus allowing for SuExec execution from mod_cgid. Currently, we do + not support everything that standard SuExec supports, but at least + it works minimally now. [Ryan Bloom] + + *) Allow SuExec to be configured from the ./configure command line. + [Ryan Bloom] + + *) Update some of the docs in README and INSTALL to reflect some of + the changes in Apache 2.0 [Cliff Woolley ] + + *) If we get EAGAIN returned from the call to apr_sendfile, then we + need to call sendfile again. This gets us serving large files + such as apache_2.0a9.tar.gz on FreeBSD again. [Ryan Bloom] + + *) Get the support programs building cleanly again. + [Cliff Woolley ] + + *) The Apache/Win32 Apache.exe and dll's now live in bin. The + current directory logic now backs up over bin/ to determine the + server root from the Apache.exe path. + + *) Apache/Win32 now follows the standard conventions of mod_foo.so + loadable modules, dynamic libs are all named libfoo.dll, and the + makefile.win populates the include, lib and libexec directories. + + *) Apache is now IPv6-capable. On systems where APR supports IPv6, + Apache gets IPv6 listening sockets by default. Additionally, the + Listen, NameVirtualHost, and directives support IPv6 + numeric address strings (e.g., "Listen [fe80::1]:8080"). + [Jeff Trawick] + + *) Modify the install directory layout. Modules are now installed in + modules/. Shared libraries should be installed in libraries/, but + we don't have any of those on Unix yet. All install directories + are modifyable at configure time. [Ryan Bloom] + + *) Install all header files in the same directory on Unix. [Ryan Bloom] + + *) Get the functions in server/linked into the server, regardless of + which modules linked into the server. This uses the same hack + for Apache that we use for APR and apr-util to ensure all of the + necessary functions are linked. As a part of thise, the CHARSET_EBCDIC + was renamed to AP_CHARSET_EBCDIC for namespace protection, and to make + the scripts a bit easier. + [Ryan Bloom] + + *) Rework the RFC1413 handling to make it thread-safe, use a timeout + on the query, and remove IPv4 dependencies. [Jeff Trawick] + + *) Get all of the auth modules to the point that they will install and + be loadable into the server. Our new build/install mechanism expects + that all modules will have a common name format. The auth modules + didn't use that format, so we didn't install them properly. + [Ryan Bloom] + + *) API routines ap_pgethostbyname() and ap_pduphostent() are no longer + available. Use apr_getaddrinfo() instead. [Jeff Trawick] + + *) Get "NameVirtualHost *" working in 2.0. [Ryan Bloom] + + *) Return HTTP_RANGE_NOT_SATISFIABLE if the every range requested starts + after the end of the response. [Ryan Bloom] + + *) Get byterange requests working with responses that do not have a + content-length. Because of the way byterange requests work, we have to + have all of the data before we can actually do the byterange, so we + can compute the content-length in the byterange filter. + [Ryan Bloom] + + *) Get exe CGI's working again on Windows. + [Allan Edwards] + + *) Get mod_cgid and mod_rewrite to work as DSOs by changing the way + they keep track of whether or not their post config hook has been + called before. Instead of a static variable (which is replaced when + the DSO is loaded a second time), use userdata in the process pool. + [Jeff Trawick] + +Changes with Apache 2.0a9 + + *) Win32 now requires perl to complete the final install step for users + to build + install on Win32. Makefile.win now rewrites @@ServerRoot@ + and installs the conf, htdocs and htdocs/manual directories. + [William Rowe] + + *) Make mod_include use a hash table to associate directive tags with + functions. This allows modules to implement their own SSI tags easily. + The idea is simple enough, a module can insert it's own tag and function + combination into a hash table provided by mod_include. While mod_include + parses an SSI file, when it encounters a tag in the file, it does a + hash lookup to find the function that implements that tag, and passes + all of the relevant data to the function. That function is then + responsible for processing the tag and handing the remaining data back + to mod_include for further processing. + [Paul J. Reder ] + + *) Get rid of ap_new_apr_connection(). ap_new_connection() now has + fewer parameters: the local and remote socket addresses were removed + from the parameter list because all required information is available + via the APR socket. [Jeff Trawick] + + *) Distribution directory structure reorganized to reflect a + normal source distribution with external install targets. + [Roy Fielding] + + *) The MPMs that need multiple segments of shared memory now create + two apr_shmem_t variables, one for each shared memory allocation. + the problem is that we can't determine how much memory will be required + for shared memory allocations once we try to allocate more than one + variable. The MM code automatically aligns the shared memory allocations, + so we end up needing to pad the amount of shared memory we want based + on how many variables will be allocated out of the shared memory segment. + It is just easier to create a second apr_shmem_t variable, and two + shmem memory blocks. + [Ryan Bloom] + + *) Cleanup the export list a bit. This creates a single unified list of + functions exported by APR. The export list is generated at configure + time, and that list is then used to generate the exports.c file. + Because of the way the export list is generated, we only export those + functions that are valid on the platform we are building on. + [Ryan Bloom] + + *) Enable logging the cookie with mod_log_config + [Sander van Zoest ] + + *) Fix a segfault in mod_info when it reaches the end of the configuration. + [Jeff Trawick] + + *) Added lib/aputil/ as a placeholder for utility functions which are not + specific to the Apache HTTP Server (but do not make sense with APR). + The first utility is "apu_dbm": a set of functions to work with DBM + files. This first version can be compiled for SDBM or GDBM databases. + [Greg Stein] + + *) Complete re-write of mod_include. This makes mod_include a filter that + uses buckets directly. This has now served the FAQ correctly. + [Paul Reder ] + + *) Allow modules to specify the first filter in a sub_request when + making the sub_request. This keeps modules from having to change the + output_filter immediately after creating the sub-request, and therefore + skip the sub_req_output_filter. [Ryan Bloom] + + *) Update ab to accept URLs with IPv6 literal address strings (in the + format described in RFC 2732), and to build Host header fields in + the same format. This allows IPv6 literal address strings to be + used with ab. This support has been tested against Apache 1.3 with + the KAME patch, but Apache 2.0 does not yet work with this format + of the Host header field. [Jeff Trawick] + + *) Accomodate an out-of-space condition in the piped logs and the + rotatelogs.c code, and no longer churn log processes for this + condition. [Victor J. Orlikowski] + + *) Add support for partial writes with apr_sendfile() to core_output_filter. + [Greg Ames] + +Changes with Apache 2.0a8 + + *) Add a directive to mod_mime so that filters can be associated with + a given mime-type. + [Ryan Bloom] + + *) Get multi-views working again. We were setting the path_info + field incorrectly if we couldn't find the specified file. + [Ryan Bloom] + + *) Fix 304 processing. The core should never try to send the headers + down the filter stack. Always, just setup the table in the request + record, and let the header filter convert it to data that is ready + for the network. + [Ryan Bloom] + + *) More fixes for the proxy. There are still bugs in the proxy code, + but this has now proxied www.yahoo.com and www.ntrnet.net (my ISP) + successfully. + [Ryan Bloom] + + *) Fix params for apr_getaddrinfo() call in connect proxy handler. + [Chuck Murcko] + + *) APR: Add new apr_getopt_long function to handle long options. + [B. W. Fitzpatrick ] + + *) APR: Change apr_connect() to take apr_sockaddr_t instead of hostname. + Add generic apr_create_socket(). Add apr_getaddrinfo() for doing + hostname resolution/address string parsing and building + apr_sockaddr_t. Add apr_get_sockaddr() for getting the address + of one of the apr_sockaddr_t structures for a socket. Change + apr_bind() to take apr_sockaddr_t. [David Reid and Jeff Trawick] + + *) Remove the BUFF from the HTTP proxy. This is still a bit ugly, but + I have proxied pages with it, cleanup will commence soon. + [Ryan Bloom] + + *) Make the proxy work with filters. This isn't perfect, because we + aren't dealing with the headers properly. [Ryan Bloom] + + *) Do not send a content-length iff the C-L is 0 and this is a head + request. [Ryan Bloom] + + *) Make cgi-bin work as a regular directory when using mod_vhost_alias + with no VirtualScriptAlias directives. PR#6829 [Tony Finch] + + *) Remove BUFF from the PROXY connect handling. [Ryan Bloom] + + *) Get the default_handler to stop trying to deal with HEAD requests. + The idea is to let the content-length filter compute the C-L before + we try to send the data. If we can get the C-L correctly, then we + should send it in the HEAD response. + [Ryan Bloom] + + *) The Header filter can now determine if a body should be sent based + on r->header_only. The general idea of this is that if we delay + deciding to send the body, then we might be able to compute the + content-length correctly, which will help caching proxies to cache + our data better. Any handler that doesn't want to try to compute + the content-length can just send an EOS bucket without data and + everything will just work. + [Ryan Bloom] + + *) Add the referer to the error log if one is available. + [Markus Gyger ] + + *) Mod_info.c has now been ported to Apache 2.0. As a part of this + change, the root of the configuration tree has been exposed to modules + as ap_conftree. + [Ryan Morgan ] + + *) Get the core_output_filter to use the bucket interface directly. + This keeps us from calling the content-length filter multiple times + for a simple static request. + [Ryan Bloom] + + *) We are sending the content-type correctly now. + [Ryan Bloom and Will Rowe] + + *) APR on FreeBSD: Fix a bug in apr_sendfile() which caused us to report + a bogus bytes-sent value when the only thing being sent was trailers + and writev() returned an error (or EAGAIN). [Jeff Trawick] + + *) Get SINGLE_LISTEN_UNSERIALIZED_ACCEPT working again. This uses the + hints file to determine which platforms define + SINGLE_LISTEN_UNSERIALIZED_ACCEPT. + [Ryan Bloom] + + *) APR: add apr_get_home_directory() [Jeff Trawick] + + *) Initial import of 1.3-current mod_proxy. [Chuck Murcko] + + *) Not all platforms have INADDR_NONE defined by default. Apache + used to make this check and define INADDR_NONE if appropriate, + but APR needs the check too, and I suspect other applications will + as well. APR now defines APR_INADDR_NONE, which is always a valid + value on all platforms. + [Branko Èibej ] + + *) Destroy the pthread mutex in lock_intra_cleanup() for PR#6824. + [Shuichi Kitaguchi ] + + *) Relax the syntax checking of Host: headers in order to support + iDNS. PR#6635 [Tony Finch] + + *) When reading from file buckets we convert to an MMAP if it makes + sense. This also simplifies the default handler because the + default handler no longer needs to try to create MMAPs. + [Ryan Bloom] + + *) BUFF has been removed from the main server. The BUFF code will remain + in the code until it has been purged from the proxy module as well. + [Ryan Bloom] + + *) Byteranges have been completely re-written to be a filter. This + has been tested, and I believe it is working correctly, but it could + doesn't work for the Adobe Acrobat plug-in. The output almost matches + the output from 1.3, the only difference being that 1.3 includes + a content-length in the response, and this does not. + [Ryan Bloom] + + *) APR read/write functions and bucket read functions now operate + on unsigned integers, instead of signed ones. It doesn't make + any sense to use signed ints, because we return the error codes, + so if we have an error we should report 0 bytes read or written. + [Ryan Bloom] + + *) Always compute the content length, whether it is sent or not. + The reason for this, is that it allows us to correctly report + the bytes_sent when logging the request. This also simplifies + content-length filter a bit, and fixes the actual byte-reporing + code in mod_log_config.c + [Ryan Bloom] + + *) Remove AP_END_OF_BRIGADE definition. This does not signify what + it says, because it was only used by EOS and FLUSH buckets. Since + neither of those are required at the end of a brigade, this was + really signifying FLUSH_THE_DATA, but that can be determined better + by checking AP_BUCKET_IS_EOS() or AP_BUCKET_IS_FLUSH. EOS and FLUSH + buckets now return a length of 0, which is actually the amount of data + read, so they make more sense. + [Ryan Bloom] + + *) Allow the core_output_filter to save some data past the end of a + request. If we get an EOS bucket, we only send the data if it + makes sense to send it. This allows us to pipeline request + responses. As a part of this, we also need to allocate mmap + buckets out of the connection pool, not the request pool. This + allows the mmap to outlive the request. + [Ryan Bloom] + + *) Make blocking and non-blocking bucket reads work correctly for + sockets and pipes. These are the only bucket types that should + have non-blocking reads, because the other bucket types should + ALWAYS be able to return something immediately. + [Ryan Bloom] + + *) In the Apache/Win32 console window, accept Ctrl+C to stop the + server, but use Ctrl+Break to initiate a graceful restart + instead of duplicating behavior. [John Sterling] + + *) Patch mod_autoindex to set the Last-Modified header based on + the directory's mtime, and add the ETag header. [William Rowe] + + *) Merge the 1.3 patch to add support for logging query string in + such a way that "%m %U%q %H" is the same as "%r". + [Bill Stoddard] + + *) Port three log methods from mod_log_config 1.3 to 2.0: + CLF compliant '-' byte count, method and protocol. + [Bill Stoddard] + + *) Add a new LogFormat directive, %c, that will log connection + status at the end of the response as follows: + 'X' - connection aborted before the response completed. + '+' - connection may be kept-alive by the server. + '-' - connection will be closed by the server. + [Bill Stoddard] + + *) Expand APR for WinNT to fully accept and return utf-8 encoded + Unicode file names and paths for Win32, and tag the Content-Type + from mod_autoindex to reflect that charset if the feature + macro APR_HAS_UNICODE_FS is true. [William Rowe] + + *) Compute the content length (and add appropriate header field) for + the response when no content length is available and we can't use + chunked encoding. [Jeff Trawick] + + *) Changed ap_discard_request_body() to use REQUEST_CHUNKED_DECHUNK, + so that content input filters get dechunked data when using + the default handler. Also removed REQUEST_CHUNKED_PASS. + [Sascha Schumann] + + *) Add mod_ext_filter as an experimental module. This module allows + the administrator to use external programs as filters. Currently, + only filtering of output is supported. [Jeff Trawick] + + *) Most Apache functions work on EBCDIC machines again, as protocol + data is now translated (again). [Jeff Trawick] + + *) Introduce ap_xlate_proto_{to|from}_ascii() to clean up some of + the EBCDIC support. They are noops on ASCII machines, so this + type of translation doesn't have to be surrounded by #ifdef + CHARSET_EBCDIC. [Jeff Trawick] + + *) Fix mod_include. tag commands work again, and the server will + send the FAQ again. This also allows mod_include to set aside + buckets that include partial buckets. + [Ryan Bloom and David Reid] + + *) Add suexec support back. [Manoj Kasichainula] + + *) Lingering close now uses the socket directly instead of using + BUFF. This has been tested, but since all we can tell is that it + doesn't fail, this needs to be really hacked on. + [Ryan Bloom] + + *) Allow filters to modify headers and have those headers be sent to + the client. The idea is that we have an http_header filter that + actually sends the headers to the network. This removes the need + for the BUFF to send headers. + [Ryan Bloom] + + *) Charset translation: mod_charset_lite handles translation of + request bodies. Get rid of the xlate version of ap_md5_digest() + since we don't compute digests of filtered (e.g., translated) + response bodies this way anymore. (Note that we don't do it at + all at the present; somebody needs to write a filter to do so.) + [Jeff Trawick] + + *) Input filters and ap_get_brigade() now have a input mode parameter + (blocking, non-blocking, peek) instead of a length parameter. + [hackathon] + + *) Update the mime.types file to the registered media types as + of 2000-10-19. PR#6613 [Carsten Klapp , + Tony Finch] + + *) Namespace protect some macros declared in ap_config.h + [Ryan Bloom] + + *) Support HTTP header line folding with input filtering. + [Greg Ames] + + *) Mod_include works again. This should still be re-written, but at + least now we can serve an SHTML page again. + [Ryan Bloom] + + *) Begin to remove BUFF from the core. Currently, we keep a pointer + to both the BUFF and the socket in the conn_rec. Functions that + want to use the BUFF can, functions that want to use the socket, + can. They point to the same place. + [Ryan Bloom] + + *) apr_psprintf doesn't understand %lld as a format. Make it %ld. + [Tomas "Ögren" ] + + *) APR pipes on Unix and Win32 are now cleaned up automatically when the + associated pool goes away. (APR pipes on OS/2 were already had this + logic.) This resolvs a fatal file descriptor leak with CGIs. + [Jeff Trawick] + + *) The final line of the config file was not being read if there was + no \n at the end of it. This was caused by apr_fgets returning + APR_EOF even though we had read valid data. This is solved by + making cfg_getline check the buff that was returned from apr_fgets. + If apr_fgets return APR_EOF, but there was data in the buf, then we + return the buf, otherwise we return NULL. + [Ryan Bloom] + + *) Piped logs work again in the 2.0 series. + [Ryan Bloom] + + *) Restore functionality broken by the mod_rewrite security fix: + rewrite map lookup keys and default values are now expanded + so that the lookup can depend on the requested URI etc. + PR #6671 [Tony Finch] + + *) SECURITY: Tighten up the syntax checking of Host: headers to fix a + security bug in some mass virtual hosting configurations + that can allow a remote attacker to retrieve some files + on the system that should be inaccessible. [Tony Finch] + + *) Add a pool bucket type. This bucket is used for data allocated out + of a pool. If the pool is cleaned before the bucket is destroyed, then + the data is converted to a heap bucket, allowing it to survive the + death of the pool. + [Ryan Bloom] + + *) Add a flush bucket. This allows modules to signal that the filters + should all flush whatever data they currently have. There is no way + to actually force them to do this, so if a filter ignores this bucket, + that's life, but at least we can try with this. + [Ryan Bloom] + + *) Add an output filter for sub-requests. This filter just strips the + EOS bucket so that we don't confuse the main request's core output + filter by sending multiple EOS buckets. This change also makes sub + requests start to send EOS buckets when they are finished. + [Ryan Bloom] + + *) Make ap_bucket_(read|destroy|split|setaside) into macros. Also + makes ap_bucket_destroy a return void, which is okay because it + used to always return APR_SUCCESS, and nobody ever checked its + return value anyway. + [Cliff Woolley ] + + *) Remove the index into the bucket-type table from the buckets + structure. This has now been replaced with a pointer to the + bucket_type. Also add some macros to test the bucket-type. + [Ryan Bloom] + + *) Renamed all MODULE_EXPORT symbols to AP_MODULE_DECLARE and all symbols + for CORE_EXPORT to AP_CORE_DECLARE (namespace protecting the wrapper) + and retitled API_EXPORT as AP_DECLARE and APR_EXPORT as APR_DECLARE. + All _VAR_ flavors changes to _DATA to be absolutely clear. + [William Rowe] + + *) Add support for /, //, //servername and //server/sharename + parsing of blocks under Win32 and OS2. + [Tim Costello, William Rowe, Brian Harvard] + + *) Remove the function pointers from the ap_bucket type. They have been + replaced with a global table. Modules are allowed to register bucket + types and use then use those buckets. + [Ryan Bloom] + + *) mod_cgid: In the handler, shut down the Unix socket (only for write) + once we finish writing the request body to the cgi child process; + otherwise, the client doesn't hit EOF on stdin. Small request bodies + worked without this change (for reasons I don't understand), but large + ones didn't. [Jeff Trawick] + + *) Remove file bucket specific information from the ap_bucket type. + This has been moved to a file_bucket specific type that hangs off + the data pointer in the ap_bucket type. + [Ryan Bloom] + + *) Input filtering now has a third argument. This is the amount of data + to read from lower filters. This argument can be -1, 0, or a positive + number. -1 means give me all the data you have, I'll deal with it and + let you know if I need more. 0 means give me one line and one line + only. A positive number means I want no more than this much data. + + Currently, only 0 and a positive number are implemented. This allows + us to remove the remaining field from the conn_rec structure, which + has also been done. + [Ryan Bloom] + + *) Big cleanup of the input filtering. The goal is that http_filter + understands two conditions, headers and body. It knows where it is + based on c->remaining. If c->remaining is 0, then we are in headers, + and http_filter returns a line at a time. If it is not 0, then we are + in body, and http_filter returns raw data, but only up to c->remaining + bytes. It can return less, but never more. + [Greg Ames, Ryan Bloom, Jeff Trawick] + + *) mod_cgi: Write all of the request body to the child, not just what + the kernel would accept on the first write. [Jeff Trawick] + + *) Back out the change that moved the brigade from the core_output_filters + ctx to the conn_rec. Since all requests over a given connection + go through the same core_output_filter, the ctx pointer has the + correct lifetime. + [Ryan Bloom] + + *) Fix another bug in the send_the_file() read/write loop. A partial + send by apr_send would cause unsent data in the read buffer to + get clobbered. Complete making send_the_file handle partial + writes to the network. + [Bill Stoddard] + + *) Fix a couple of type fixes to allow compilation on AIX again + [Victor J. Orlikowski ] + + *) Fix bug in send_the_file() which causes offset to be ignored + if there are no headers to send. + [Bill Stoddard] + + *) Handle APR_ENOTIMPL returned from apr_sendfile in the core + filter. Useful for supporting Windows 9* with a binary + compiled on Windows NT. + [Bill Stoddard] + +Changes with Apache 2.0a7 + + *) Reimplement core_output_filter to buffer/save bucket brigades + across multiple calls to the core_filter. The brigade will be + sent when either MIN_BYTES_TO_SEND or MAX_IOVEC_TO_WRITE + thresholds are hit or the EOS bucket is received. + [Bill Stoddard] + + *) Create experimental filter (buffer_filter) that coalesces bytes + into one large buffer before invoking the next filter in the + chain. This filter is particularly useful with the current + implementation of mod_autoindex when it inserted above the + chunk_filter. mod_autoindex generates a lot of brigades that + containing buckets holding just a few bytes each. The + buffer_filter coalesces these buckets into a single large bucket. + [Bill Stoddard] + + *) Add apr_sendfile() support into the core_output_filter. + [Bill Stoddard] + + *) Add apr_sendv() support into the core_output_filter. + [Bill Stoddard] + + *) Fix mod_log_config so that it compiles cleanly with BUFFERED_LOGS + [Mike Abbott ] + + *) Remove ap_send_fb. This is no longer used in Apache, and it doesn't + make much sense, because Apache uses buckets instead of BUFFs now. + [Ryan Bloom] + + *) send_the_file now falls back to a read/write loop on platforms that + do not have sendfile. + [Ryan Bloom and Brian Havard] + + *) Install apachectl correctly, and substitute the proper values so + that it works again. [Ryan Bloom] + + *) Better(??) handle platforms that lack sendfile(). + [Jim Jagielski] + + *) APR now has UUID generation/formatting/parsing support. + [Greg Stein] + + *) Begin the http_filter. This is an input filter that understands + the absolute basic amount required to parse an HTTP Request. The + goal is to be able to split headers from request body before passing + the data back to the other filters. + [Ryan Bloom] + + *) Bring forward from 1.3.13 the config directory implementation + [Jim Jagielski] + + *) install apxs if it is created + [Ryan Bloom] + + *) Added APR_IS_STATUS_condition test macros to eliminate canonical error + conversions. [William Rowe] + + *) Now that we have ap_add_input_filter(), rename ap_add_filter() to + ap_add_output_filter(). [Jeff Trawick] + + *) Multiple build and configuration fixes + Build process: + + -add datadir and localstatedir substitutions + -fix layout name + -fix logfilename misspelling + -fix evaluation of installation dir variables and + -replace $foobar by $(foobar) to be usefull in the makefile + + Cross compile: + + -add rules for cross-compiling in rules.mk. Okay, rule to check for + $CC_FOR_BUILD is still missing + -use CHECK_TOOL instead of CHECK_PROG for ranlib + -add missing "AR=@AR@" to severaly Makefile.in's + -cache result for "struct rlimit" + -compile all helper programs with native and cross compiler + and use the native version to generate header file + ["Rüdiger" Kuhlmann ] + + *) Prepare our autoconf setup for autoconf 2.14a and for cross- + compiling. + ["Rüdiger" Kuhlmann ] + + *) Fix a bug where a client which only sends \n to delimit header + lines (netcat) gets a strange looking HTTP_NOT_IMPLEMENTED + message. Start working on ebcdic co-existance with input + filtering. + [William Rowe, Greg Ames] + + *) If mod_so is enabled in the server always create libexec, even + if there are no modules installed in this directory. This is a + requirement for APXS to work correctly. + [Ryan Bloom] + + *) Connection oriented output filters are now stored in the + conn_rec instead of the request_rec. This allows us to add the + output filter in the pre-connection phase instead of the + post_read_request phase, which keeps us from trying to write an + error page before we have a filter to write to the network. + [Ryan Bloom, Jeff Trawick, and Greg Ames] + + *) Cleaning up an mmap bucket no longer deletes the mmap. An + mmap can be used across multiple buckets (default_handler with + byte ranges, mod_file_cache, mod_mmap_static), so cleanup of + the mmap itself can't be associated with the bucket. + [Jeff Trawick] + + *) Add .dll caching directive ISAPICacheFile to mod_isapi. + [William Rowe] + + *) Radical surgery to improve mod_isapi support under Win32. + Includes a number of newer ServerSupportFunction calls, support + for ReadClient (in order to retrieve POSTs greater than 48KB), + and general bug fixes to more reliably load ISAPI .dll's and + prevent leaking handle resources. Note: There are still + discrepancies between IIS's and Apache's ServerVariables, and + async calls are still not supported. Additional warnings are + logged to facilitate debugging of unsupported ISAPI calls. + [William Rowe] + + *) Add input filtering to Apache. The basic idea for the input + filters is the same as the ideas for output filters. The biggest + difference is that instead of calling ap_pass_brigade, ap_get_brigade + should be called, and the order of execution for the filter itself is + different. When writing an output filter, a brigade is passed in, + and filters operate directly on that brigade, when done, they call + ap_pass_brigade. Input filters are the exact opposite. Because input + is not a push operation, filters first call ap_get_brigade. When this + function returns, the input filter will be left with a valid brigade. + The input filter should then operate on the brigade, and return. + [Ryan Bloom] + + *) Fix building on BSD/OS using its native make. The build system + falls back to the BSD .include directive on that host platform. + [Sascha Schumann] + + *) Expand dbmmanage to allow -d -m -s -p options for Crypt, MD5, + SHA1 and plaintext password encodings. Make feature tests a + bit more flexible. [William Rowe] + + *) Charset translation: mod_charset_lite handles output content + translation in a filter. mod_charset_lite no longer ignores + subrequests. A bunch of cruft related to BUFF's support for + translating request and response bodies was removed. + [Jeff Trawick] + + *) Move the addition of the CORE filter to the post_read_request + hook in http_core.c. This removes the need to add the filter in + multiple places and allows for an SSL module to be added much + simpler. [Ryan Bloom] + + *) SECURITY: CVE-2000-0913 (cve.mitre.org) + Fix a security problem that affects certain configurations of + mod_rewrite. If the result of a RewriteRule is a filename that + contains expansion specifiers, especially regexp backreferences + $0..$9 and %0..%9, then it may be possible for an attacker to + access any file on the web server. [Tony Finch] + + *) Fix a bug where errors that are detected during early request parsing + don't produce visible HTTP error messages at the browser, because + the core_filter wasn't present. [Greg Ames] + + *) Provide apr_socklen_t as a portability aid. + [Victor J. Orlikowski] + + *) Overhaul of dbmmanage to allow a groups arg (as in Apache 1.2) + as well as a comment arg to the add, adduser and update cmds. + update allows the user to clear or preserve pw/groups/comment. + Fixed a bug in dbmmanage that prevented the check option from + parsing a password followed by :group... text. Corrected the + seed calcualation for Win32 systems, and added -lsdbm support. + [William Rowe] + + *) Configured mod_auth_dbm to compile with sdbmlib under Win32. + [William Rowe] + + *) Avoid a segfault when parsing .htaccess files. An + uninitialized tree pointer was passed to ap_build_config(). + [Jeff Trawick] + + *) Change the way that inet_addr & inet_network are checked for + in APR's configure process to allow BeOS BONE to correctly + find them. With this change BeOS BONE now builds from source + with no problems. [David Reid] + + *) Fix a bug in apr_create_process() for Unix. The NULL signifying + the end of the parameters to execve() was stored in the wrong + location, overlaying the storage beyond the newargs[] array and + also passing uninitialized storage to execve(), which would + sometimes fail with EFAULT. [Jeff Trawick] + + *) Fix a bug parsing configuration file containers. With a sequence + like this in the config file + + + any stuff + + + (blank line) + any stuff + + + the second container would be terminated at the blank line due to + sediment in the buffer from reading the prior
and an + error message would be generated for the real for the + second container. Also due to this problem, any two characters + could be used for "] + + *) Fix chunking problem with CGI scripts. The general problem was that + the CGI modules were adding an EOS bucket and then the core added an + EOS bucket. The chunking filter finalizes the chunked response when it + encounters an EOS bucket. Because two EOS buckets were sent, we + finalized the response twice. The fix is to make sure we only send one + EOS, by utilizing a flag in the request_rec. + [Ryan Bloom] + + *) apr_put_os_file() now sets up the unget byte appropriately on Unix + and Win32. Previously, the first read from an apr_file_t set up via + apr_put_os_file() would return a '\0'. [Jeff Trawick] + + *) Mod_cgid now creates a single element bucket brigade, with a pipe + bucket, instead of using BUFF's and ap_r*. + [Ryan Bloom] + + *) APRVARS.in no longer overwrites the EXTRA_LIBS variable. + [Mike Abbott ] + + *) Remove ap_bopenf from buff code. This required modifying the file_cache + code to use APR file's directly instead of going through BUFFs. + [Ryan Bloom] + + *) Fix compile break on some platforms for mod_mime_magic.c + [John K. Sterling ] + + *) Fix merging of AddDefaultCharset directive. + PR #5872 (1.3) [Jun Kuriyama ] + + *) Minor revamp of the rlimit sections of code. We now test + explicitly for setrlimit and getrlimit. Also, unixd_set_rlimit() + is now "available" even if the platform doesn't support + the rlimit family (it's just a noop though). [Jim Jagielski] + + *) Migrate the pre-selection of which MPM to use for specific + platforms to hints.m4, which contains (or should contain) + all platform specific "hints". [Jim Jagielski] + + *) Remove IOLs from Apache. With filtering, IOLs are no longer necessary + [Ryan Bloom] + + *) Add tables with non-string/binary values to APR. + [Ken Coar] + + *) Fix some bad calls to ap_log_rerror() in mod_rewrite. + [Jeff Trawick] + + *) Update PCRE to version 3.2. [Ryan Bloom] + + *) Change the way buckets' destroy functions are called so that + they can be more directly used when changing the type of a + bucket in place. [Tony Finch] + + *) Add generic support for reference-counting the resources used by + buckets, and alter the HEAP and MMAP buckets to use it. Change + the way buckets are initialised to support changing the type of + buckets in place, and use it when setting aside TRANSIENT buckets. + Change the implementation of TRANSIENT buckets so that it can be + mostly shared with IMMORTAL buckets, which are now implemented. + [Tony Finch] + +Changes with Apache 2.0a6 + + *) Add support to Apache and APR for dsos on OS/390. [Greg Ames] + + *) Add a chunking filter to Apache. This brings us one step closer + to removing BUFF. [Ryan Bloom] + + *) ap_add_filter now adds filters in a LIFO fashion. The first filter + added to the stack is the last filter to be called. [Ryan Bloom] + + *) Apache 2.0 has been completely documented using Scandoc. The + docs can be generated by running 'make docs'. [Ryan Bloom] + + *) Add filtered I/O to Apache. This is based on bucket brigades, + Currently the buckets still use BUFF under the covers, but that + should change quickly. The only currently written filter is the + core filter which just calls ap_bwrite. [The Apache Group] + + *) APR locks on Unix: Let APR_LOCKALL locks work when APR isn't + built with thread support. [Jeff Trawick] + + *) Abort configuration if --with-layout was specified and there's + no layout definition file. [Ken Coar] + + *) Add support for '--with-port=n' option to configure. [Ken Coar] + + *) Add support for extension methods for the Allow response header + field, and an API routine for accessing r->allowed and the + list of extension methods in a unified manner. [Ken Coar] + + *) mod_cern_meta: fix broken file reading loop in scan_meta_file(). + [Rob Simonson ] + + *) Get xlate builds working again. The apr renaming in 2.0a5 broke + APACHE_XLATE builds. [Jeff Trawick] + + *) A configuration file parsing problem was fixed. When the + configuration file started with an IfModule/IfDefine container, + only the last statement in the container would be retained. + [Jeff Trawick] + +Changes with Apache 2.0a5 + + *) Perchild is serving pages after passing them to different child + processes. There are still a lot of bugs, but this does work. I + have made requests against the same installation of Apache, and had + different servers use different user IDs to serve the responses. + This change moves to using socketpair instead of an AF_UNIX socket. + [Ryan Bloom] + + *) Perchild MPM still doesn't work perfectly, but it is serving pages. + It can't seem to pass between child processes yet, but I think we + are closer now than before. This moves us back to using Unix + Domain Sockets. [Ryan Bloom] + + *) libapr functions and types renamed with apr_ prefix. + #include "apr_compat.h" for 1.3.x backwards compat + [Perl] + + *) Fix problems with APR sockaddr handling on Win32. It didn't always + return the right information on the local socket address. + [Gregory Nicholls ] + + *) ap_recv() on Win32: Set bytes-read to 0 on error. + [Gregory Nicholls ] + + *) Add an option to not detach from the controlling terminal without + going into single process mode. This allows for much easier + debugging of the process startup code. [Ryan Bloom] + + *) ab: don't use perror() to report the failure of an APR function. + [Jeff Trawick] + + *) Make dexter, mpmt_pthread, and perchild MPMs not destroy the + scoreboard on graceful restarts. + [Ryan Bloom] + + *) Fix segfault/SIGSEGV when running gzip from mod_mime_magic.c. + An invalid ap_proc_t was passed to ap_create_process(). + [Jeff Trawick] + + *) Allow modules to register filters. Those filters are still + never called, but this is a step in the right direction. + [Ryan Bloom and Greg Stein] + + *) Register the mod_cgid daemon process for cleanup so that it is + killed at termination if it does not die when the parent gets + SIGTERM. This change is to fix occasional problems where the + process stays around. Bugs in similar logic in mod_rewrite and + mod_include were also fixed. [Jeff Trawick] + + *) Fix a bug in the time handling. Basically, we were imploding a time + in ap_parseHTTPdate, but it had bogus data in the exploded time format. + Namely, tm_usec and tm_gmtoff were not filled out. ap_implode_time + uses those two fields to adjust the time value. Because of the HTTP + spec, both of those values can be zero'ed out safely. This fixes + the bug correctly. [Ryan Bloom] + + *) Fix a couple of place in the Windows code where the wrong error + code was being returned. [Gregory Nicholls ] + + *) Fix POOL_DEBUG (at least for prefork mpm). [Dean Gaudet] + + *) Added the APR_EOL_STR macro for platform dependent differences in + logfiles and other raw text (such as all APR files). Fixes logfiles + not terminated with cr/lf sequences in Win32. [William Rowe] + + *) Move all strings functions in APR to src/lib/apr/strings and create + apr_strings.h for the prototypes. [Ryan Bloom] + + *) APR lock fixes: when using SysV sems, flock(), or fcntl(), be sure + to repeat the syscall until we stop getting EINTR. I noticed a + related problem at termination (SIGTERM) on FreeBSD when using + fcntl(). Apache 1.3 had these new loops too. Also, make the flock() + implementation work properly with child init. Previously, ap_lock() + was essentially a no-op because all children were using different + locks and thus nobody ever blocked. [Jeff Trawick] + + *) The htdocs/ tree has been moved out of the CVS source tree into + a separate area for easier development. This has NO EFFECT on + end-users or Apache installations. [Ken Coar] + + *) Integrate the mod_dav module for WebDAV protocol handling. This + adds the dav and dav_fs modules, the SDBM library, and additional + XML handling utilities. [Greg Stein] + + *) Clean out obsolete names (from httpd.h) for the HTTP Status Codes + [Greg Stein] + + *) Update the lib/expat-lite/ library (bring forward changes from + the Apache 1.3 repository). [Greg Stein] + + *) If sizeof(long long) == sizeof(long), then prefer long in APR + configure.in. [Dave Hill ] + + *) Add ap_sendfile for Tru64 Unix. Also, add an error message for + machines where sendfile is detected, but nobody has written ap_sendfile. + [Dave Hill ] + + *) Compile fixes in mod_mmap_static. [Victor J. Orlikowski] + + *) ab would start up more connections than needed, then quit when the + desired number were finished. Also fixed a logic error involving + ab keepalives. [Victor J. Orlikowski] + + *) WinNT: Implement non-blocking pipes with timeouts to communicate + with CGIs. Apache 2.0a4 had non-blocking pipes but without + timeouts (i.e, if a timeout was specified, the pipe reverted to + a full blocking pipe). Now the behaviour is more in line with + Unix non-blocking pipes. + [Bill Stoddard] + + *) WinNT: Implement accept socket reuse. Using mod_file_cache to + cache open file handles along with accept socket reuse enables + Apache 2.0 to serve non-keepalive requests for static files at + 3x the rate of Apache 1.3.(e.g, Apache 1.3 will serve 400 rps + and Apache 2.0 will serve almost 1200 rps on my system). + [Bill Stoddard] + + *) Merge mod_mmap_static function into mod_file_cache. mod_file_cache + supports two config directives, mmapfile (same behavious as + mod_mmap_static) and cachefile. Use the cachefile directive + to cache open file handles. This directive only works on systems + that have implemented the ap_sendfile API. cachefile works today + on Windows NT, but has not been tested on any flavors of Unix. + [Bill Stoddard] + + *) Cleanup the configuration. With the last few changes the + configuration process automatically: + inherits information about how to build from APR. Allowing + APR to inform Apache that it should or should not use -ldl + + Detects which mod_cgi should be used mod_cgi or mod_cgid, + based on the threading model + + Apache calls APR's configure process before finishing it's + configuration processing, allowing for more information flow + between the two. + [Ryan Bloom] + + + *) Change Unix and Win32 ap_setsockopt() so that APR_SO_NONBLOCK + with non-zero argument makes the socket non-blocking. BeOS and + OS/2 already worked this way. [Jeff Trawick] + + *) ap_close() now calls ap_flush() for buffered files, so write + operations work a whole lot better on buffered files. + [Jeff Trawick] + + *) Fix error messages issued from MPMs which explain where to change + compiled-in limits (e.g., ThreadsPerChild, MaxClients, StartTreads). + [Greg Ames] + + *) ap_create_pipe() now leaves pipes in blocking state. (This helps + reduce the number of syscalls on Unix.) ap_set_pipe_timeout() is + now the way that the blocking state of a pipe is manipulated. + ap_block_pipe() is gone. [Jeff Trawick] + + *) Correct the problem where the only local host name that the IP stack + can discover are 'undotted' private names. If no fully qualified + domain name can be identified, the default ServerName will be set to + the machine's IP address string. A warning is always provided if the + ServerName not specified, but assumed. Solves PR6215 [William Rowe] + + *) Repair problems with config file processing which caused segfault + at init when virtual hosts were defined and which caused ServerName to + be ignored when there was no valid DNS setup. [Jeff Trawick] + + *) Removed pointless ap_is_aborted macro function. [Roy Fielding] + + *) Add ap_sendfile implementation for AIX + [Victor J. Orlikowski] + + *) Repair C++ compatibility in ap_config.h, apr_file_io.h, + apr_network_io.h, and apr_thread_proc.h. + [Tyler J. Brooks , Jeff Trawick] + + *) Bring the allocation and pool debugging code back into a working + state. This will need to be tested as so far it's only been used on + BeOS. [David Reid] + + *) Change configuration command setup to be properly typesafe when in + maintainer mode. Note that this requires a compiler that can initialise + unions. [Ben Laurie] + + *) Turn on buffering for config file reads. Part of this was to + repair buffered I/O support in Unix and implement buffered + ap_fgets() for all platforms. [Brian Havard, Jeff Trawick] + + *) Win32: Fix problem where UTC offset was not being set correctly + in the access log. Problem reported on news group by Jerry Baker. + [Bill Stoddard] + + *) Fix segfault when reporting this type of syntax error: + " without matching section", where + container is VirtualHost or Directory or whatever. + [Jeff Trawick] + + *) SECURITY: CAN-2000-1204 (cve.mitre.org) + Prevent the source code for CGIs from being revealed when + using mod_vhost_alias and the CGI directory is under the document root + and a user makes a request like http://www.example.com//cgi-bin/cgi + as reported in + [Tony Finch] + + *) Add support for the new Beos NetwOrking Environment (BONE) + [David Reid] + + *) xlate: ap_xlate_conv_buffer() now tells the caller when the + final input char is incomplete; ap_bwrite_xlate() now handles + incomplete final input chars. [Jeff Trawick] + + *) Yet another update to saferead/halfduplex stuff -- need to ensure + that a bhalfduplex call occurs before logging or else DNS and + such can delay the last packet of the response. [Dean Gaudet] + + *) Some syscall reduction in APR on unix -- don't seek when setting + up an mmap; and don't fcntl() more than once per socket. + [Dean Gaudet] + + *) When mod_cgid is started as root, the cgi daemon now switches + to the configured User/Group (like other httpd processes) + instead of continuing as root. [Jeff Trawick] + + *) The prefork MPM now uses an APR lock for the accept() mutex. + It has not been getting a lock at all recently. httpd -V now + displays APR's selection of the lock mechanism instead of the + symbols previously respected by prefork. [Jeff Trawick] + + *) Change the mmap() feature test to check only for existence. + The previous check required features not used by Apache. + [Greg Ames] + + *) Fix a couple of bugs in mod_cgid: The cgi arguments were + sometimes mangled. The len parm to accept() was not + initialized, leading sometimes to an endless loop of failed + accept() calls on OS/390 and anywhere else that failed the call + if the len was negative. Use for struct sockaddr_un + instead of declaring it ourselves to fix a compilation problem + on Solaris. [Jeff Trawick] + + *) Add Resource limiting code back into Apache 2.0. [Ryan Bloom] + + *) Fix zombie process problem with mod_cgi. [Jeff Trawick] + + *) Port mod_mmap_static to 2.0. Make it go faster. [Greg Ames] + + *) Fix storage overlay when loading dsos. Symptom: Apache dies at + initialization if ALLOC_DEBUG is defined; no known symptom + otherwise. [Jeff Trawick] + + *) Fix typo in configure script when checking for mod_so. bash + doesn't seem to have a problem but /bin/sh on Solaris does. + Symptom: "./configure: test: unknown operator ==" + [Jeff Trawick] + + *) Rebind the Win32 NT and 9x services control into the MPM. + All console, WinNT SCM and Win9x pseudo-service control code is + now wrapped within the WinNT MPM. + [William Rowe] + + *) Make a copy of getenv("PATH") before storing for later use. Some + getenv() implementations use the same storage for successive calls. + CGIs on OS/390 had a bad PATH due to this. [Jeff Trawick] + + *) Server Tokens work in 2.0 again. This also propogates the change + to allow just the product name in the server string using + PRODUCT_ONLY. + [Ryan Bloom] + +Changes with Apache 2.0a4 + + *) EBCDIC: Rearrange calls to ap_checkconv() so that most handlers + won't need to call it. [Greg Ames, Jeff Trawick] + + *) Move pre_config hook call to between configuration read and config + tree walk. This allows all modules to implement pre_config hooks + and know that they will be called at an appropriate time. + [Ryan Bloom] + + *) mod_cgi, mod_cgid: Make ScriptLog directive work again. + [Jeff Trawick] + + *) Add pre-config hooks back to all modules. + [Ryan Bloom] + + *) Fix a SIGSEGV in ap_md5digest(), which is used when you have + ContentDigest enabled and we can't/don't mmap the file. + [Jeff Trawick] + + *) We now report the correct line number for syntax errors in config + files. [Ryan Bloom, Greg Stein, Jeff Trawick] + + *) Brought mod_auth_digest up to synch with 1.3, fixed ap_time_t- + related bugs, and changed shmem/locking to use apr API. Shared-mem + is currently disabled, however, because of problems with graceful + restarts. [Ronald Tschalär] + + *) Fix corruption of IFS variable in --with-module= handling. + Depending on the user's shell or customization thereof, there + would be errors generating ap_config_auto.h later in the configure + procedure. [Jeff Trawick] + + *) mod_cgi: Restore logging of stderr from child process when ScriptLog + isn't used (as in 1.3), except that on Unix it is now logged via + ap_log_rerror() instead of by the child having STDERR_FILENO refer + to the error log. [Greg Ames, Jeff Trawick] + + *) Add '-D' argument processing for run time configuration defines. + [William Rowe] + + *) Organize http_main.c as independent code, such that no code or + global data is exported from it. WIN32 will dynamically link it + to the server core, so this will prevent mutual dependency. + [William Rowe] + + *) Add separate dynamic linkage tags APR_EXPORT(), APR_EXPORT_NONSTD() + and APR_VAR_EXPORT to correctly resolve apr functions and globals. + [William Rowe] + + *) Add Win9x service execution and Ctrl+C/Ctrl+Break/Shutdown handlers. + [William Rowe, Jan Just Keijser ] + + *) Add mod_charset_lite for configuring character set translation. + [Jeff Trawick] + + *) Add '-n' option to htpasswd to make it print its user:pw record + on stdout rather than having to frob a text file. [Ken Coar] + + *) Fix saferead. Basically, we flush the output buffer if a read on the + input will block. + [Ryan Bloom] + + *) APR: Add ap_xlate_get_sb() so that an app can find out whether or not + a conversion is single-byte only. [Jeff Trawick] + + *) BEOS: ap_shutdown should return APR_SUCCESS or errno. Note that + the BeOS 5.0 documentation says that shutdown doesn't work yet. + [Roy Fielding] + + *) Fix some minor errors where pid was being manipulated as an int + instead of the portable pid_t. [Roy Fielding] + + *) Fix some error log prints that were printing the pointer to a + structure rather than the pid within the structure. + [Jeff Trawick, Roy Fielding] + + *) ab: Fix a command-line processing bug; track bad headers in + err_response; support reading headers up to 2K. + [Ask Bjoern Hansen ] + + *) Fix ap_resolve_env() so that it handles new function added in a prior + alpha (see "Added the capability to do ${ENVVAR} constructs in the + config file.") as well as the constructs used by mod_rewrite. + [Paul Reder ] + + *) Apache 2.0 builds and runs on OS/390. [Jeff Trawick, Greg Ames] + + *) Change the EBCDIC support in functions for MD5, SHA1, and base 64 to use + APR to perform translation, instead of accessing the hard-coded tables + in 1.3's ebcdic.c. [Jeff Trawick] + + *) Fix some bugs (mostly lost 1.3 code) in ab's command-line processing. + [Jeff Trawick] + + *) Add the ability to hook into the config file reading phase. Basically + if a directive is specified EXEC_ON_READ, then when that directive is + read from the config file, the assocaited function is executed. This + should only be used for those directives that must muck with HOW the + server INTERPRETS the config. This should not be used for directives + that re-order or replace items in the config tree. Those changes should + be made in the pre-config step. + [Ryan Bloom] + + *) Add mod_example to the build system. + [Tony Finch] + + *) APR: Add ap_xlate_conv_byte() to convert one char between single- + byte character sets. [Jeff Trawick] + + *) Pick up various EBCDIC fixes from 1.3 (from Martin + Kraemer and Oliver Reh originally according to the change log). + [Jeff Trawick] + + *) Fix a couple of problems in RFC1413 support (controlled by the + IdentityCheck directive). Apache did not build the request string + properly and more importantly Apache would loop forever if the + would-be ident server dropped the connection before sending a + properly terminated response. [Jeff Trawick] + + *) apxs works in 2.0. + [Ryan Bloom] + + *) Reliable piped logs work in 2.0. + [Ryan Bloom] + + *) Introduce a hash table implementation into APR to be used for + replacing tables and other random data structures in Apache. + [Tony Finch] + + *) Add some more error reporting to htpasswd in the case of problems + generating or accessing the temporary file. Also, pass in a + buffer if the implementation knows how to use it (i.e., if L_tmpnam + is defined). [Ken Coar] + + *) Configure creates config.nice now containing your configure + options. Syntax: ./config.nice [--more-options] + [Sascha Schumann] + + *) Fix various return code problems in APR on Win32. For most of + these, APR was returning APR_EEXIST instead of GetLastError()/ + WSAGetLastError(). [Jeff Trawick] + + *) Make piped logs work again in version 2.0 + [Ryan Bloom] + + *) Add VPATH support to UNIX build system of Apache and APR. + [Sascha Schumann] + + *) Fix ap_tokenize_to_argv to respect the const arguments that are + passed to it. + [Ryan Bloom] + + *) Fix mm's memcpy/memset macros, pointer arithmetic was broken. + Patch submitted to author. + [Sascha Schumann] + + *) Fix mm configuration on Solaris 8 x86 and OS/390. Don't require + /sbin in PATH on FreeBSD (all submitted to rse previously) + [Jeff Trawick] + + *) Fix building Pthread-based MPMs on OpenBSD + [Sascha Schumann] PR#26 + + *) Fix ap_readdir() problem on systems where d_name[] field in + struct dirent is declared with only one byte. (This problem only + affected multithreaded builds.) This caused a segfault during + pool cleanup with mod_autoindex on Solaris (Solaris 8 x86, at + least). [Jeff Trawick] + + *) Fix some make-portability problems on at least Tru64, Irix + and UnixWare. + [Sascha Schumann] PR#18, PR#39 + + *) Add ap_sigwait() to support old-style sigwait() on systems + like OS/390 and UnixWare. + [Sascha Schumann] + + *) Add POSIX-thread flags for more platforms. + [Sascha Schumann] + + *) Fix some minor bugs in ap_strerror(). Teach ap_strerror() + (on Unix, at least) to handle resolver errors. Fix a bug in + the definition of APR_ENOMEM so that ap_strerror() can spit + out the correct error message for it. + [Jeff Trawick] + +Changes with Apache 2.0a3 + + *) mod_so reports ap_os_dso_error() if ap_dso_load() fails + [Doug MacEachern] + + *) API: *HOOK* macros now have an AP_ prefix + [Doug MacEachern] + + *) Win32: Eliminate redundant calls to initialize winsock. + [Tim Costello ] + + *) Fix bugs initializing ungetchar for pipes. + [Chia-liang Kao ] + + *) The ab program in the src/support directory is now portable using + APR. + [Ryan Bloom] + + *) Support directory is being compiled when the server is built + [Ryan Bloom] + + *) The configure option --with-program-name has been added to allow + developers to rename the executable at configure time. This also + changes the name of the config files to match the executable's name. + [Ryan Bloom] + + *) mod_autoindex: Add `IndexOptions +VersionSort', to nicely sort filenames + containing version numbers. [Martin Pool] + + *) ap_open(..,APR_OS_DEFAULT,..) uses perms 0666 instead of 0777 on + Unix; access_log and error_log now created with these perms; non- + Unix is unaffected [Jeff Trawick] + + *) Finished move of ap_md5 routines to apr_md5. Removed ap_md5.h. + Replaced more magic numbers with MD5_DIGESTSIZE. + [William Rowe, Roy Fielding] + + *) Win32: Get mod_auth_digest compiling and added to the Windows + build environment. Not tested and I'd be suprised if it + actually works. [Bill Stoddard] + + *) Revamp the Win32 make environment. Makefiles have been removed and + Apache.dsw created to bring together all the pieces. Create new file + os/win32/BaseAddr.ref to define module base addresses (to prevent + dll relocation at start-up). + [William Rowe, Greg Marr, Tim Costello, Bill Stoddard] + + *) [EBCDIC] Port Paul Gilmartin's CRLF patch from 1.3. This replaces most + of the \015, \012, and \015\012 constants with macros. + [Greg Ames] + + *) Add ap_xlate_open() et al for translation of text between different + character sets. The initial implementation requires iconv(). + [Jeff Trawick] + + *) More FAQs and answers from comp.infosystems.www.servers.unix. + [Joshua Slive ] + + *) CGI output is being timed out now. + [Ryan Bloom] + + *) Fix the problem with dieing quietly. dupfile now takes a pool which + is used by the new apr file. There is no reason to create a new file + with the same lifetime as the original file. + [Ryan Bloom] + + *) Win32: Attempt to eliminate dll relocation at start-up by specifying + module base addresses. This will help shooting seg faults + in the field. [William Rowe ] + + *) Update Apache on Windows documentation. Add new document + describing how to compile Apache on Windows. + [William Rowe ] + + *) ap_set_pipe_timeout(), ap_poll(), and APR_SO_TIMEOUT now take + microseconds instead of seconds. Some storage leaks and other + minor bugs in related code were fixed. [Jeff Trawick] + + *) Win32: First cut at getting mod_isapi working under 2.0 + [William Rowe ] + + *) First stab at getting mod_auth_digest working under 2.0 + quick change summary: + - moved the random byte generation (ap_generate_random_bytes) into APR + - now uses ap_time_t + - compiles and runs on linux + - tested with amaya + [Brian Martin ] + + *) Win32: Move the space stripping of physical service names + fix up from Apache 1.3. #include'ing "ap_mpm.h" fixes up an + unresolved symbol. Add dependency checking to the + CreateService call to ensure TCPIP and AFP (winsock) is started + before Apache. + [William Rowe ] + + *) Win32: Add code to perform latebinding on functions that may + not exist on all levels of Windows where Apache runs. This + is needed to allow Apache to start-up on Win95/98. All calls + to non portable functions should be protected with + ap_oslevel checks to prevent runtime segfaults. + [William Rowe ] + + *) Fix fallback default values for SHM_R and SHM_W [Martin Kraemer] + + *) Get lingering_close() working again. [Dean Gaudet, Jeff Trawick] + + *) Win32: Get non-blocking CGI pipe reads working under Windows NT. + This addresses PR 1623. Still need to address timing out runaway + CGI scripts. [Bill Stoddard] + + *) Win32: Make ap_stat Windows 95/98 friendly + [William Rowe ] + + *) Win32: Fix a bug in ap_get_oslevel which causes GetVersionEx() to + always fail. Need to initialise the dwOSVersionInfoSize member of the + OSVERSIONINFO struct before calling GetVersionEx, so GetVersionEx + always fails. + + The patch also enhances ap_get_oslevel (and the associated enum) to + handle selected service packs for NT4, and adds recognition for + Windows 2000. This is useful, eg. if we can recognise NT4 SP2 then + we can use ReadFileScatter and WriteFileGather in readwrite.c. + [Tim Costello ] + + *) Get mod_rewrite building and running, and mod_status building for Win NT + [Allan Edwards ] + + *) Patch to port mod_auth_db to the 2.0 api and also to support + Berlekey DB 3.0. It works for me with both Berkeley DB 3.0.55 and + 2.7.7. It should work with version 1 as well but I haven't tested it. + [Brian Martin ] + + *) Get APR DSO code working under Windows. Includes cross platform + fixes to mod_so.c. + [] + + *) Fix some of the Windows APR time functions. + [William Rowe] + + *) FAQ changes related to tidying up historical documents on the web site. + [Joshua Slive ] + + *) Move Windows DSO code into APR. + [Bill Stoddard] + + *) Eliminate apr_win.h and apr_winconfig.h (and the ugly #ifdefs they cause). + Now, apr.h and apr_config.h are generated from apr.hw and apr_config.hw + at build time. At this point, the server will not compile on Windows because + of the recent DSO commits. Fixing those next. + [Bill Rowe & Bill Stoddard] + + *) Added error checking for file I/O APR routines. + [Jon Travis ] + + *) APR: Don't use the values of resolver error codes for the + corresponding APR error codes. On Unix and Win32, return the + proper APR error code after a resolver error. [Jeff Trawick] + +Changes with Apache 2.0a2 + + *) Renamed the executable back to httpd on all platforms other + than Win32 + [Ryan Bloom] + + *) Allow BeOS to survive restarts, log properly and a few + small things it had problems with due to the way it setup + users and groups. [David Reid] + + *) Get mod_rewrite working with APR locks + [Paul Reder ] + + *) Actually remove the sempahore when the lock cleanup routine + is called on BeOS. [David Reid] + + *) Clear hook registrations between reads of the config file. + When DSOs are unloaded and re-loaded the old hook pointers may + no longer be valid. This fix eliminates potential segfaults. + [Allan Edwards ] + + *) Fix a problem with Sigfunc not being defined or bypassed + if sigaction() wasn't found. [Jim Jagielski] + + *) Fix the locking mechanism on BSD variants. They now use fcntl + locks. This allows the server to start and serve pages. + [Ryan Bloom] + + *) First cut at getting the Win32 installer to work + [William Rowe ] + + *) Get htpasswd compiling under Windows + [William Rowe ] + + *) Change the log message for a bind() failure to show the + interface and port number. [Jeff Trawick] + + *) Import the documentation from 1.3.12 and bring parts of it + up-to-date with respect to the changes that have occurred + in 2.0. + [Tony Finch] + + *) BeOS MPM updated. CGI bug on BeOS fixed. IP addresses + now logged correctly on BeOS. + [David Reid] + + *) Create one makefile for all Win32 distributions (NT/2000/95/98). + Makefile.win includes the same user interface as the old + Makefile.nt + [William Rowe , Jeff Trawick ] + + *) Win32 exec now uses COMSPEC environment string for command + shell path resolution. + [William Rowe ] PR#3715 + + *) Win32: ap_connect() was not returning correct error condition + PR5866 + [Allen Prescott ] + + *) Win32: ap_open() was broken on Win9x because an NT-specific + flag was passed to CreateFile. ap_puts() added an unnecessary + '\n'. + [Jeff Trawick ] + + *) Put in Korean and Norwegian index.html pages (2.0 and 1.3) + which where donated by Lee Kuk Hyun and Lorant Czaran. 'Fixed' + confusing ee/et name and made all extensions language/dialect + rather than country reflecting. Changed example files to + explicit reflect the ISO charset and added a few common + ones to the example config [dirkx] + + *) Extend external module capability. To use this, you call + configure with --with-module=path/to/mod1,path/to/mod2,etc. + [Ryan Bloom] + + *) Backported the various "default charset" fixes from 1.3.12, + including the AddDefaultCharset directive. [Jim Jagielski] + + *) Added the capability to do ${ENVVAR} constructs in the + config file. E.g. 'ServerAdmin ${POSTMASTER}'. As commited + it does this on a line by line basis; i.e. if the envvar + expands to something with spaces you have to protect it + by adding quotes around it (Unless of course you expect it + to contains more than one argument. Alternatively you + can compile it on a per token basis; which is what people + usually expect by setting RESOLVE_ENV_PER_TOKEN. But this + hampers fancier hacks. + [Dirk-Willem van Gulik] + + *) Changed the 'ErrorDocument' syntax in that it NO longer + supports the asymetric + + ErrorDocument 301 "Some message + + Note the opening " quote, without a closing quote. It now + has either the following syntaxes + + ErrorDocument XXX /local/uri + ErrorDocument XXX http://valid/url + ErrorDocument XXX "Some Message" + + The recognition heuristic is: if it has a space it + is a message. If it has no spaces and starts with a / + or is a valid URL then treat it that way. Otherwise it + is assumed to be a message. + + This breaks backward compatibility but makes live a hell + of a lot easier for GUI's and config file parsers. + [Dirk-Willem van Gulik] + + *) Changed 'CacheNegotiatedDocs' from its present/not-present + syntax into a 'on' or 'off' syntax. As it currently is the + only non nesting token which uses NO_ARGS and thus is an + absolute pain for any config interface automation. This + breaks backward compatibility. [Dirk-Willem van Gulik] + + *) Add ability to add external modules to the build process. This is + done with --with-module=/path/to/module. Modules can only be added + as static modules at this point. + [Ryan Bloom] + +Changes with Apache 2.0a1 + + *) Fix FreeBSD 3.3 core dump. + Basically, ap_initialize() needs to get called before + create_process(), since create_process() passes op_on structure + to semop() to get a lock, but op_on isn't initialized until + ap_initialize() calls setup_lock(). Here is a slight + rearrangement to main() which calls ap_initialize() earlier... + [Jeff Trawick ] + + *) Enable Apache to use sendfile/TransmitFile API + [Bill Stoddard, David Reid, Paul Reder] + + *) Re-Implement Win32 APR network I/O APIs and most of the file I/O + APIs. + [Bill Stoddard] + + *) Make file I/O and network I/O writev/sendv APIs consistent. + Eliminate use of ap_iovec_t and use Posix struct iovec. + Use seperate variable on ap_writev to set the number of iovecs + passed in and number of bytes written. + [Bill Stoddard] + + *) Adapt file iol to use APR functions. Replaced ap_open_file() + with ap_create_file_iol(). ap_create_file_iol() requires that + the file be opened prior to the call using ap_open(). + [Bill Stoddard] + + *) Port mod_include and mod_cgi to 2.0 + [Paul Reder, Bill Stoddard] + + *) ap_send{,v}, ap_recv, ap_sendfile API clarification -- + bytes_read/bytes_written is always valid (never -1). Plus + some fixes to buff.c to correct problems introduced by the + errno => ap_status_t changes a while back. Plus a fix to + chunked encoding introduced right at the beginning of 2.0. + [Dean Gaudet] + + *) Revamped UNIX build system to use autoconf and libtool. + [Manoj Kasichainula, Sascha Schumann] + + *) port mod_rewrite to 2.0. [Paul J. Reder ] + + *) SECURITY: More rigorous checking of Host: headers to fix security + problems with mass name-based virtual hosting (whether using mod_rewrite + or mod_vhost_alias). + [Ben Hyde, Tony Finch] + + *) Add back support for UseCanonicalName in containers. + [Manoj Kasichainula] + + *) Added APLOG_STARTUP log type. This allows us to write an error + message without any of the date and time information. As a part + of this change, I also removed all of the calls to fprintf(stderr + and replaced them with calls to ap_log_error using APLOG_STARTUP + writing to stderr is no longer portable, because we don't direct + stderr to the error log on all platforms. + [Ryan Bloom] + + *) Convert error logging functions to take errno as an argument. + This makes our error logs more portable, because some Windows API's + don't set errno. This change allows us to still output a valid + message on all of our platforms. + [Ryan Bloom] + + *) mod_mime_magic runs in 2.0-dev now. + [Paul Reder ] + + *) sendfile has been added to APR. + [John Zedlewski ] + + *) buff.c has been converted to no longer use errno. + [Manoj Kasichainula] + + *) mod_speling runs in 2.0-dev now: a bug in readdir_r handling and + interface adaption to APR functions did it. [Martin Kraemer] + + *) Support DSOs properly on 32-bit HP-UX 11.0 + [Dilip Khandekar ] + + *) Updated MM in APR source tree from version 1.0.8 to 1.0.11 + [Ralf S. Engelschall] + + *) Cleaned APR build environment integration and bootstrap APR + automatically for developers from src/Configure. + [Ralf S. Engelschall] + + *) Fixed building of src/support/htpasswd.c + [Ralf S. Engelschall] + + *) When generating the Location: header, mod_speling forgot + to escape the spelling-fixed uri. (Forw-Port from 1.3) + [Martin Kraemer] + + *) Moved mod_auth_digest.c from experimental to standard. [Roy Fielding] + + *) Change all pools to APR contexts. This is the first step to + incorporating APR into Apache. [Ryan Bloom] + + *) Move "handler not found" warning message to below the check + for a wildcard handler. [Dirk , Roy Fielding] + PR#2584, PR#2751, PR#3349, PR#3436, PR#3548, PR#4384, PR#4795, PR#4807 + + *) Support line-continuation feature in config.option file and + allow the loading of multiple option sections at once via + ``--with-option=,,...'' + [Ralf S. Engelschall] + + *) Rebuilt CVS repository with Apache 1.3.9 as basis. [Roy Fielding] + +Changes with Apache MPM + + *) Use asynchronous AcceptEx() and a completion port to accept and + dispatch connections to threads in Windows NT/2000. + [Bill Stoddard] + + *) Implement WINNT Win32 MPM from original Win32 code in http_main.c + [Bill Stoddard] + + *) Implement the APACI --with-option facility + (per default used the config.option file). + [Ralf S. Engelschall] + + *) MPM BEOS port. [David Reid ] + + *) Start to implement module-defined hooks that are a) fast and b) typesafe. + Replace pre_connection module call with a register_hook call and + implement pre_connection as a hook. The intent is that these hooks will + be extended to allow Apache to be multi-protocol, and also to allow the + calling order to be specified on a per-hook/per-module basis. + [Ben Laurie] + + *) Implement mpm_* methods as "modules". Each method gets its own + subdir in src/modules (eg: src/modules/prefork). Selection + of method uses Rule MPM_METHOD. [Jim Jagielski] + + *) Port the hybrid server from the apache-apr repository as + mpm_mpmt_pthread. [Manoj Kasichainula] + + *) os/unix/unixd.[ch]: detach, setuid, setgid, stuff which will be common + amongst the unix MPMs. + + *) mpm_prefork: throw away all the alarm/timeout crud; and clean up the + signal handling for the new world order. [Dean Gaudet] + + *) Crude ap_thread_mutex abstraction so that we get the pthread stuff out + of alloc.c for now. [Dean Gaudet] + + *) Handle partial large writes correctly. [Ben Laurie] + + *) Eliminate conn_rec's pointer to server. All it knows is the base server + based on IP/port. [Ben Laurie] + + *) Port a bunch of modules to the new module structure. + ["Michael H. Voase" ] + + *) I/O layering and BUFF revamp. See docs/buff.txt. [Dean Gaudet] + + *) Basic restructuring to introduce the MPM concept; includes various + changes to the module API... better described by + docs/initial_blurb.txt. [Dean Gaudet] + +Changes with Apache pthreads + + *) New buff option added: BO_TIMEOUT. It describes the timeout for + buff operations (generally over a network). + [Dean Gaudet, Ryan Bloom, Manoj Kasichainula] + + *) Created http_accept abstraction. Added 4 new functions (not exported): + init_accept(), begin_accepting_requests(), get_request(), + stop_accepting_requests() [Bill Stoddard] + + *) Fix to ap_rprintf call that allows mod_info to work properly. + [James Morris ] + + *) user and ap_auth_type fields were moved from connection_rec to + request_rec. [Ryan Bloom] + + *) Removed the ap_block_alarms and ap_unblock_alarm calls. These aren't + needed in a threaded server. + + *) Initial pthread implementation from from Dean's apache-nspr code. + [Bill Stoddard, Ryan Bloom] + + +Changes with Apache 1.3.9 + + *) Remove bogus error message when a redirect doesn't set Location. + Instead, use an empty string to avoid coredump if the error message + was supposed to include a location. [Roy Fielding] + + *) Don't allow configure to include mod_auth_digest unless it is + explicitly requested, even if the user asked for all modules. + [Roy Fielding] + + *) Translate module names to dll names for OS/2 so that they are no more + than 8 characters long and have an extension of "dll" instead of "so". + [Brian Havard] + + *) Print out pointer to Rule DEV_RANDOM when truerand lib not found. + Fix test-compile check to check for randbyte instead of trand32. + Use ap_base64encode_binary/decode instead of copy in mod_auth_digest.c + and tweak to make Amaya happier. [Ronald Tschalär] + + *) Ensure that the installed expat include files are world readable, + just like the other header files. [Martin Kraemer] + + *) Fixed generated AddModule adjustments in APACI's `configure' script + in order to allow (new) modules like mod_vhost_alias to be handled + correctly (which was touched by the adjustments for mod_alias). + [Ralf S. Engelschall] + + *) For binary builds, add -R flag to apachectl to work around the lack of + an absolute path to the ./libexec directory where the libhttp.ep file + is needed for SHARED_CORE architectures. [Randy Terbush] + + *) WIN32: Create the CGI script process as DETACHED. This may solve the + problem observed by some Win95/98 users where they get CGI script + output sent to the console. [Bill Stoddard] + + *) Fix (re)naming in the uuencode/decode section. The ap/ap_ + routines are now called ap_base64* and are 'plain' (i.e., no + pool access or anything clever). Inside util.c the routines acting + like pstrdup are called ap_pbase64encode() and ap_pbase64decode(). + The oddly named ap_uuencode(), ap_uudecode() are kept around for + now but deprecated. [dirkx] + + *) Clean up the base64 and SHA1 additions and make sure they are + represented in the ApacheCore.def, ApacheCoreOS2.def, and httpd.exp + files. [Roy Fielding] + + *) WIN32: Migrate to InstallShield 5.5 and provide a bit more error + checking. Allow compiling on VS 6.0. [Randy Terbush] + + *) Fixed assumption of absolute paths in binbuild.sh. [Tony Finch] + + *) Use TestCompile to search for the truerand library (rather than blindly + assuming its existence). If it is not found, complain (but do not + exit - yet). [Martin Kraemer] + + *) We forgot to add the new exported function names to + src/support/httpd.exp. [Bill Stoddard, Randy Terbush] + + *) Add description of -T command-line option to usage(). + [Ralf S. Engelschall] + + *) For "some" platforms (notably, EBCDIC based ones), libos needs to be + searched only AFTER libap has been searched, because libap needs + some symbols from libos. [Martin Kraemer] + + *) Fix conflict with original mod_digest related to the symbol of the + module dispatch list (which has to be unique for DSO and follow the + usual conventions for the installation procedure). + [Ralf S. Engelschall] + + *) Add a dbm-library check for the "usual places" (-ldbm, -lndbm, -ldb) + for other platforms as well. [Martin Kraemer] + + *) Make ap_sha1.c compile for EBCDIC platforms: replace remaining LONG + types by AP_LONG and replace reference to renamed variable 'ubuf' + by 'buffer'. [Martin Kraemer] + +Changes with Apache 1.3.8 [not released] + + *) Flush the output buffer immediately after sending an error or redirect + response, since the result may be needed by the client to abort a + long data transfer or restart a series of pipelined requests. + [Tom Vaughan , Roy Fielding] + + *) PORT: Improved compilation and DSO support on Sequent DYNIX/ptx. + [Ian Turner ] PR#4735 + + *) Local struct mmap in http_core.c conflicted with system structure + name on DYNIX -- changed to mmap_rec. [Roy Fielding] PR#4735 + + *) Added updated mod_digest as modules/experimental/mod_auth_digest. + [Ronald Tschalär ] + + *) Fix a memory leak where the module counts were getting messed + up across restarts. [David Harris ] + + *) CIDR addresses such as a.b.c.d/24 where d != 0 weren't handled + properly in mod_access. + ["Paul J. Reder" ] PR#4770 + + *) RewriteLock/RewriteMap didn't work properly with virtual hosts. + [Dmitry Khrustalev ] PR#3874 + + *) PORT: Support for compaq/tandem/com. + [Michael Ottati , dirkx] + + *) Added SHA1 password encryption support to easy migration from + Netscape servers. See support/SHA1 for more information. + Caused the separation of ap_md5.c into md5, sha1 and a general + ap_checkpass.c with just a validate_passwd routine. Added a + couple of flags to support/htpasswd. Some reuse of the to64() + function; hence renamed to ap_to64(). + [Dirk-Willem van Gulik, Clinton Wong ] + + *) Change for EBCDIC platforms (TPF and BS2000) to correctly deal + with ASCII/EBCDIC conversions in "ident" query. + [David McCreedy ] + + *) Get rid of redefinition warning on MAC_OS_X_SERVER platform. + Change "Power Macintosh" to Power* so if uname prints "Power Book" + we're still happy on Rhapsody platforms. [Wilfredo Sanchez] + + *) Fix SIGSEGV on some systems because the Vary fix below included + a call to table_do with a variable argument list that was not + NULL terminated. Replaced with better implementation. [Roy Fielding] + +Changes with Apache 1.3.7 [not released] + + *) The "Vary" response header field is now sanitised right before + the header is sent back to the client. Multiple "Vary" fields + are combined, and duplicate tokens (e.g., "Vary: host, host" or + "Vary: host, negotiate, host, accept-language") are reduced to + single instances. This is a better solution than the force-no-vary + one (which is still valid for clients that can't cope with Vary + at all). PR#3118 [Dean Gaudet, Roy Fielding, Ken Coar] + + *) Portability changes for BeOS. [David Reid ] + + *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at + least on Linux and FreeBSD for now. + [Rasmus Lerdorf] + + *) Win32: More apache -k restart work. Restarts are now honored + immediately and connections in the listen queue are -not- lost. + This is made possible by the use of the WSADuplicateSocket() + call. The listeners are opened in the parent, duplicated, then + the duplicates are passed to the child. The original listen sockets + are not closed by the parent across a restart, thus the listen queue + is preserved. + [Bill Stoddard ] + + *) Fix handling of case when a client has sent "Expect: 100-continue" + and we are going to respond with an error, but get stuck waiting to + discard the body in the pointless hope of preserving the connection. + [Roy Fielding, Joe Orton ] PR#4499, PR#3806 + + *) Fix 'configure' to work correctly with SysV-based versions of + 'tr' (consistent with Configure's use as well). [Jim Jagielski] + + *) apxs: Add "-S var=val" option which allows for override of CFG_* + built-in values. Add "-e" option which works like -i but doesn't + install the DSO; useful for editing httpd.conf with apxs. Fix + editing code so that multiple invocations of apxs -a will not + create duplicate LoadModule/AddModule entries; apxs can now be + used to re- enable/disable a module. [Wilfredo Sanchez] + + *) Win32: Update the server to use Winsock 2. Specifically, link with + ws2_32.lib rather than wsock32.lib. This gives us access to + WSADuplcateSocket() in addition to some other enhanced comm APIs. + Win 95 users may need to update their TCP/IP stack to pick up + Winsock 2. (See http://www.microsoft.com/windows95/downloads/) + [Bill Stoddard ] + + *) Win32: Redirect CGI script stderr (script debug info) into the + error.log when CGI scripts fail. This makes Apache on Win32 + behave more like Unix. + [Bill Stoddard ] + + *) Fixed `httpd' usage display: -D was missing. + [Ralf S. Engelschall] PR#4614 + + *) Fix `make r' test procedure in src/regex/: ap_isprint was not found. + [Ralf S. Engelschall] PR#4561, PR#4562 + + *) OS/2: Fix problem with accept lock semaphores where server would die with + "OS2SEM: Error 105 getting accept lock. Exiting!" + [Brian Havard] PR#4505 + + *) Add DSO support for DGUX 4.x using gcc. Tested on x86 platforms. + [Randy Terbush ] + + *) Add the new mass-vhost module (mod_vhost_alias.c) developed and + used by Demon Internet, Ltd. [Tony Finch ] + + *) Better GCC detection for DSO flags under Solaris 2 where the `cc' + command potentially _is_ GCC. [Ralf S. Engelschall] + + *) Fix apxs build issues on AIX + [Rasmus Lerdorf ] + + *) DocumentRoot Checking: Under previous versions, when Apache + first started up, it used to do a stat of each DocumentRoot to + see if it existed and was a directory. If not, then an error + message was printed. THIS HAS BEEN DISABLED. If DocumentRoot + does not exist, you will get error messages in error_log. If + the '-t' command line option is used (to check the configuration) + the check of DocumentRoot IS performed. An additional command + line option, '-T', has been added if you want to avoid the + DocumentRoot check even when checking the configuration. + [Jim Jagielski] + + *) Win32: The query switch "apache -S" didn't exit after showing the + vhost settings. That was inconsistent with the other query functions. + [Bill Stoddard - Fixed by Martin on Unix in 1.3.4] + + *) Win32: Changed behaviour of apache -k restart. + Previously, the server would drain all connections in the stack's + listen queue before honoring the restart. On a busy server, this + could take hours. Now, a restart is honored almost immediately. + All connections in Apache's queues are handled but connections in + the stack's listen queue are discarded. Restart triggered by + MaxRequestPerChild is unchanged. + [Bill Stoddard ] + + *) Win32: Eliminated unnecessary call to wait_for_multiple_objects in + the accept loop. Good for a 5% performance boost. Cleaned up + parent/child process management code. + [Bill Stoddard ] + + *) Added ceiling on file size for memory mapped files. + [John Giannandrea ] PR#4122 + + *) Fix ndbm.h include problems with brain-dead glibc >= 2.1 which + has ndbm.h in a non-standard db1/ subdir. PR#4431, PR#4528 + [Henri Gomez , Ralf S. Engelschall] + + *) Determine AP_BYTE_ORDER for ap_config_auto.h and already + use this at least for Expat. [Ralf S. Engelschall] + + *) Allow .module files to specify libraries with Lib:. + [Ben Laurie] + + *) Allow SetEnvIf[NoCase] to test environment variables as well + as header fields and request attributes. [Ken Coar] + + *) Fix mod_autoindex's handling of ScanHTMLTitles when file + content-types are "text/html;parameters". PR#4524 [Ken Coar] + + *) Remove "mxb" support from mod_negotiation -- it was a draft feature + never accepted into any standard, and it opens up certain DoS + attacks. [Koen Holtman ] + + *) TestCompile updated. We can now run programs and output the + results during the Configure process. [ Jim Jagielski] + + *) The source is now quad (long long) aware as needed. Specifically, + the Configure process determines the correct size of off_t and + *void. When the OS/platform/compiler supports quads, ap_snprintf() + provides for the 'q' format qualifier (if quads are not available, + 'q' is silently "demoted" to long). [Jim Jagielski] + + *) When the username or password fed to htpasswd is too long, include the + size limit in the error message. Also report illegal characters + (currently only ':') in the username. Add the size restrictions + to the man page. [Ken Coar] + + *) Fixed the configure --without-support option so it doesn't result in + an infinite loop. [Marc Slemko] + + *) Piped error logs could cause a segfault if an error occured + during configuration after a restart. + [Aidan Cully ] PR#4456 + + *) If a "Location" field was stored in r->err_headers_out rather + than r->headers_out, redirect processing wouldn't find it and + the server would core dump on ap_escape_html(NULL). Check both + tables and raise HTTP_INTERNAL_SERVER_ERROR with a log message + if Location isn't set. [Doug MacEachern, Ken Coar] + + *) Add RULE_EXPAT, the src/lib/ directory structure, and a modified copy + of the Expat 1.0.2 distribution. [Greg Stein] + + *) Replace regexec() calls with calls to a new API stub function + ap_regexec(). This solves problems with DSO modules which use the regex + library. [Jens-Uwe Mager , Ralf S. Engelschall] + + *) Add 'Request_Protocol' special keyword to mod_setenvif so that + environment variables can be set according to the protocol version + (e.g., HTTP/0.9 or HTTP/1.1) of the request. [Ken Coar] + + *) Add DSO support for OpenStep (Mach 4.2) platform. + [Ralf S. Engelschall, Rex Dieter ] PR#3997 + + *) Fix sed regex for generating ap_config_auto.h in src/Configure. + [Jan Gallo ] PR#3690, PR#4373 + + *) Switch to /bin/sh5 in APACI on Ultrix and friends to avoid problems with + their brain-dead /bin/sh. [Ralf S. Engelschall] PR#4372 + + *) Better DSO flags recognition on NetBSD platforms using ELF. + [Todd Vierling ] PR#4310 + + *) Always log months in english format for %t in mod_log_config. + [Petr Lampa ] PR#4366, 679 + + *) Support for server-parsed and multiview-determined ReadmeName and + HeaderName files in mod_autoindex. Removed the restriction on + "/"s in ReadmeName and HeaderName directives since the *sub_req* + routines will deal with the access issues. (It's now possible to + have {site|group|project|customer|...} wide readmes and headers.) + [Raymond S Brand , Ken Coar] PR#1574, 3026, 3529, + 3569, 4256 + + *) When stat() fails, don't assume anything about the contents of + the struct stat. [Ed Korthof ] + + *) It's OK for a semop to return EINTR, just loop around and try + again. [Dean Gaudet] + + *) Fix configuration engine re-entrant hangups, which solve a + handful of problems seen with mod_perl configuration sections + [Salvador Ortiz Garcia ] + + *) Mac OS and Mac OS X Server now use the appropriate custom layout + by default when building with APACI; allow for platform-specific + variable defaults in configure. [Wilfredo Sanchez] + + *) Do setgid() before initgroups() in http_main; some platforms + zap the grouplist when setgid() is called. This was fixed in + suexec earlier, but the main httpd code missed the change. + [Rob Saccoccio ] PR#2579 + + *) Add recognition of .tgz as a gzipped tarchive. + [Bertrand de Singly ] PR#2364 + + *) mod_include's fsize/flastmod should allow only relative paths, just + like "include file". [Jaroslav Benkovsky ] + + *) OS/2: Add support for building loadable modules using DLLs. + [Brian Havard] + + *) Add iconsdir, htdocsdir, and cgidir to config.layout. + [Wilfredo Sanchez] + + *) Fix minor but annoying bug with the test for Configuration.tmpl + being newer than Configuration so that it is less likely to fail + when using APACI and shadow sources. [Wilfredo Sanchez] + + *) PORT: Add initial support for Mac OS (versions 10.0 and + greater). Use Mac OS X Server layout for now. Clean up dyld code + in unix/os.c, and don't install the dyld error handlers, which + are no longer needed in Mac OS. [Wilfredo Sanchez] + + *) Rename Rhapsody layout to "Mac OS X Server". Change install + locations to appropriate ones for user-built (as opposed to + system) installs. [Wilfredo Sanchez] + + *) Modify mod_autoindex's handling of AddDescription so that the + behaviour matches the documentation. [Ken Coar] PR#1898, 3072. + + *) Add functionality to the install-bindist.sh script created by + binbuild.sh to use tar when copying distribution files to the + serverroot. This allows upgrading an existing installation + without nesting the new distribution in the old. + + install-bindist.sh now detects the local perl5 path to install + apxs and dbmmanage with proper path to perl interpreter. + + Add an install-binsupport target which copies the source files + for apxs and dbmmanage to bindist to allow these scripts to + be properly installed relative to the destination serverroot. + [Randy Terbush, Covalent Technologies, ] + + *) Fix intermittent SEGV in ap_proxy_cache_error() in + src/modules/proxy_util.c where a NULL filepointer and + temporary filename were closed and unlinked. + [Graham Leggett , + Tim Costello ] PR#3178 + + *) Fix inconsistent error messages reported by mod_proxy. + [Graham Leggett ] + + *) OS/2: Fix terminating CGIs that aren't compiled by EMX GCC when a + connection is aborted. [Brian Havard] + + *) Force the LANG envariable to the known state of "C" so that we + have assurance about how string manipulators (e.g., tr) will + function. [Ken Coar] PR#1630 + + *) Add a directive to allow customising of the tracking cookie name. + [Ken Coar] PR#2921, 4303 + + *) Add "force-no-vary" envariable to allow servers to work around + clients that choke on "Vary" fields in the response header. + [Ken Coar, Dmitry Khrustalev ] PR#4118 + + *) Fixed a bug in mod_dir that causes a child process will infinitely + recurse when it attemps to handle a request for a directory wnd the + value of the DirectoryIndex directive is a single dot. Also likely + to happen for anyother values of DirectoryIndex that will map back + to the same directory. The handler now only considers regular files + as being index candidates. No PR#s found. + [Raymond S Brand ] + + *) Ease configuration debugging by making TestCompile fall back to + using "make" if the $MAKE variable is unset [Martin Kraemer] + + *) Fixed the ServerSignature directive to work as documented. + [Raymond S Brand ] PR#4248 + + *) Add "opt" (SysV-style) layout to config.layout. [Raymond S Brand + ] + + *) Add APACI --without-execstrip option which can be used to disable the + stripping of executables on installation. This is very important for DSO + and debugging situations. [Ralf S. Engelschall] + + *) Add support for OS/2 (case insenstive filesystem, .exe suffix, etc) + to APACI files and related scripts. + [Yitzchak Scott-Thoennes , Ralf S. Engelschall] PR#4269 + + *) Add support for standalone mode in TPF + [Joe Moenich ] + + *) Fix number of bytes copied by read_connection() in src/support/ab.c + [Jim Cox ] PR#4271 + + *) Fix special RewriteCond "-s" pattern matching. + [Bob Finch ] + + *) Fix value quoting in src/Configure script for ap_config_auto.h + [Paul Sutton ] + + *) Make sure RewriteLock can be used only in the global context, (i.e. + outside of any sections) because it's a global facility of + the rewrite engine. [Ralf S. Engelschall] + + *) Fix the ownership delegation for proxy directory under `make install'. + [Ralf S. Engelschall] + + *) APACI would not correctly build suexec. [Maria Verina + ] PR#4260 + + *) mod_mime_magic passed only the first 4k of a file to + uncompress/gzip, but those tools sometimes do not produce + any output unless a sufficient portion of the compressed + file is input. Change to pass the entire file -- but + only read 4k of output. + [Marcin Cieslak ] PR#4097 + + *) "IndexOptions None" generated extra spaces at the end of each + line. [] PR#3770 + + *) The "100 Continue" response wasn't being sent after internal + redirects. [Jose KAHAN ] PR#3910, 3806, 3575 + + *) When padding the name with spaces for display, mod_autoindex would + count &, <, and > in their escaped width, messing up the display. + [Dean Gaudet] PR#4075, 3758 + + *) PORT: fixed a compilation problem on NEXT. + [Jacques Distler ] PR#4130 + + *) r->request_time wasn't being set properly in certain error conditions. + [Dean Gaudet] PR#4156 + + *) PORT: deal with UTS compiler error in http_protocol.c + [Dave Dykstra ] PR#4189 + + *) Add ap_vrprintf() function. [John Tobey ] PR#4246 + + *) Fix the mod_mime hash table to work properly with locales other + than C. [Dean Gaudet] PR#3427 + + *) Fix a memory leak which is exacerbated by certain configurations. + [Dean Gaudet] PR#4225 + + *) Prevent clobbering saved IFS values in APACI. [Jim Jagielski] + + *) Fix buffer overflows in ap_uuencode and ap_uudecode pointed out + by "Peter 'Luna' Altberg " and PR#3422 + [Peter 'Luna' Altberg , Ronald Tschalär] + + *) Make {Set,Unset,Pass}Env per-directory instead of per-server. + [Ben Laurie] + + *) Correct an apparent typo: on the Windows and MPE platforms, the + htpasswd utility was limiting passwords to only 8 characters. + [Ken Coar] + + *) EBCDIC platforms: David submitted patches for two bugs in the + MD5 digest port for EBCDIC machines: + a) the htdigest utility overwrote the old contents of the digest file + b) the Content-MD5 header value (ContentDigest directive) was wrong + when the returned file was not converted from EBCDIC, but was a + binary (e.g., image file) in the first place. + [David McCreedy ] + + *) support/htpasswd now permits the password to be specified on the + command line with the '-b' switch. This is useful when passwords + need to be maintained by scripts -- particularly in the Win32 + environment. [Ken Coar] + + *) Win32: Win32 multiple services patch. Added capability to install and + run multiple copies of apache as individual services. + + Example 1: + apache -n apache1 -i -f c:/httpd.conf + Installs apache as service 'apache1' and associates c:/httpd.conf + with that service. + net start apache1 + Starts apache1 service. + net stop apache1 + Stops apache1 service + + Example 2: + apache -n apache2 -i + Installs apache as service 'apache2'. httpd.conf is located under + the default server root (/apache/conf/httpd.conf). + net start apache2 + Starts apache2 service. + + Example 3: + apache -n apache3 -i -d c:/program files/apache + Install apache as service 'apache3' and sets server root to + c:/program files/apache. + + Example 4: + apache -n apache2 -k restart + Restart apache2 service + + [Keith Wannamaker, Ken Parzygnat, Bill Stoddard] + + *) Correct the signed/unsigned character handling for the MD5 routines; + mismatches were causing compilation problems with gcc -pedantic and + in the TPF cross-compilation. [Ken Coar] + + *) OS/2: Rework CGI handling to use spawn*() instead of fork/exec, achieving + a roughly 5 fold speed up. [Brian Havard] + + *) proxy ftp: instead of using the hardwired string "text/plain" as + a fallback type for files served by the ftp proxy, use the + ap_default_type() function to determine the configured type. + This allows for special configurations like + + DefaultType gargle/blurb + + Additionally, add the Content-Encoding: header to FTP proxy replies + when the encoding is defined (by the AddEncoding directive). + Because it was missing, it was almost impossible to browse compressed + files using the FTP proxy (works now perfectly in Communicator). + The ftp proxy now also returns the Date: and Server: header lines (if not + much else... This code is "somewhat" broken) like normal requests do. + [Martin Kraemer] + + *) Be more smart in APACI's configure script when determining the UID/GID + for User/Group directives and use the determined UID/GID to initialize + the permissions on the proxycachedir. + [Dirk-Willem van Gulik, Ralf S. Engelschall] + + *) Changed the forking-prior-to-cleanup in the proxy module to first + check wether it actually needs to collect garbage. This reduces + the number of fork()s from one/request to just the odd one an hour. + [Dirk-Willem van Gulik] + + *) Added proxy, auth and header support to src/support/ab.c. Added a + README file to src/support/ + [Dirk-Willem van Gulik] + + *) Don't hard-code the path to AWK in --shadow bootstrapping Makefile. + [Ralf S. Engelschall] PR#4050 + + *) Add support for DSO module compilation on BSD/OS 3.x. + [Randy Terbush, Covalent Technologies] + + *) Fix sed-substitutions in `make install': path elements like `httpd/conf' + (for instance from an APACI configure --sysconfdir=/etc/httpd/conf + option) were substituted with $(TARGET).conf, etc. Same for other strings + with dots where the dot wasn't matched as plain text. + [Ralf S. Engelschall] + + *) PORT: Add support for FreeBSD 4.x [Ralf S. Engelschall] + + *) Fix verbose output of APACI configure (option -v) + [Martin Kraemer, Ralf S. Engelschall] + +Changes with Apache 1.3.6 + + *) Removed new PassAllEnv code due to DSO problems. [Lars Eilebrecht] + +Changes with Apache 1.3.5 [not released] + + *) M_INVALID needed a value within the scope of METHODS so that unknown + methods can be access controlled. [Roy Fielding] PR#3821 + + *) Added PassAllEnv; makes server's entire environment available + to CGIs and SSIs executed within directive's scope. [Ken Coar] + + *) ap_uuencode() always added two trailing '='s and encoding of + 8 bit characters on a machine with signed char may produced + incorrect results. Additionally ap_uuencode() should now + work correctly on EBCDIC platforms. + [Ronald Tschalär ] PR#3411 + + *) WIN32: Binary installer now runs the configuration DLL before + the reboot prompt (which is only given if MSVCRT.DLL system + DLL is new or updated). This should avoid the configuration + directory being empty after installation. [Paul Sutton] + PR#3767, 3800, 3827, 3850, 3900, 3953, 3988 + + *) WIN32: Binary installer now creates Start menu options to start + and stop Apache as a console application and to uninstall + the Apache service on NT. [Paul Sutton] PR#3741 + + *) WIN32: Apache.exe now contains an icon. [Paul Sutton] + + *) 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 + ] + + *) PORT: AIX does not require the SHARED_CODE "hack" + [Ryan Bloom ] + + *) 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 ] PR#3872 + + *) ap_isxdigit was somehow neglected when adding the ap_isfoo() macros + for 8-bit safeness. [Dean Gaudet] + + *) PORT: 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 ] 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 ] 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 ] PR#3617 + + *) Make documentation and error messages of APACI's --activate-module=FILE + option more clear. [Jan Wolter ] 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 ] 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 , 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 ] + + *) Add support for \n and \t to mod_log_config, can be used to produce + more reliable logs with multiline entries. [Tony Finch ] + + *) Fixed a few compiler nits. [John Bley ] + + *) 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 , Jim Jagielski] + + *) OS/2 ap_os_canonical_filename()'s behaviour is improved: ap_assert() + is removed. This allows directives to work and + prevents invalid requests from killing the process. + [Brian Havard ] + + *) Reorganised FAQ document. + [Joshua Slive ] 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 ] + + *) 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, 4086 + + *) 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. [] + + *) Added a 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 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 ] 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), 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. + [Dean Gaudet, Roy Fielding, Martin Kraemer] + + *) Win32: Add new config directive, ScriptInterpreterSource, to enable + searching the Win32 registry for script interpreters. + [Bill Stoddard] + + *) Win32: The compiled-in default filename for the error log is now + error.log, which matches the default in the distributed httpd.conf. + [Paul Sutton] + + *) Win32: Any error messages from -i or -u command line options are now + displayed on the console output rather than sent to the error log. + Also the "Running Apache..." message is not output unless Apache is + going to serve requests. [Paul Sutton] + + *) Rework the MD5 authentication scheme to use FreeBSD's algorithm, + and use a private significator ('$apr1$') to mark passwords as + being smashed with our own algorithm. Also abstract the password + checking into a new ap_validate_password() routine. [Ken Coar] + + *) Win32: The filename validity checker now allows "COM" but refuses + access to "COM1" through "COM4". This allows filenames such + as "com.name" to be served. [Paul Sutton] PR#3769. + + *) BS2000: Adapt to the new ufork() system call interface which will + make subtasking easier on the OSD/POSIX mainframe environment. + [Martin Kraemer] + + *) Add a compatibility define for escape_uri() -> ap_escape_uri() to + ap_compat.h. [David White ] PR#3725 + + *) Make NDBM file suffix determination for mod_rewrite more accurate, i.e. + 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 + + *) Add ability to handle DES or MD5 authentication passwords. + [Ryan Bloom ] + + *) Fix O(n^2) memory consumption in mod_speling. [Dean Gaudet] + + *) SECURITY: Avoid some buffer overflow problems when escaping + quoted strings. (This overflow was on the heap and we believe + impossible to exploit.) [Rick Perry ] + + *) Let src/Configure be aware of CFLAGS options starting with plus + signs as it's the case for the HP/UX compiler. + [Doug Yatcilla ] PR#3681 + + *) Remove the hard-wire of TAR=tar (we now check for gtar and gnutar first) + and check to see if the tar we wind up with supports '-h'. + [Jim Jagielski] PR#3671 + + *) A consistent and conservative style for all shell scripts has been + implemented. Basically, all shell string tests use the traditional + hack of 'if [ "x$var" != "x" ]' or 'if [ "x$var" = "xstring" ]' + to protect against bare null variable strings (ie: wrapping both + sides with double quotes and prepending 'x'). 'x' was chosen + because it's more universal and hopefully easier for old shell + prgrammers, as well as being easier to search for in 'vi' (/x\$) :) + [Jim Jagielski] + + *) The status module now prints out both the main server generation as + well as the generation of each process. Also, the vhost info is + printed with '?notable'. [Jim Jagielski] + + *) Move src/main/md5c.c to src/ap/ap_md5c.c; it's httpd-neutral + and this makes its functions available to things in src/support. + [Ken Coar] + +Changes with Apache 1.3.4 + + *) Renamed macros status_drops_connection to ap_status_drops_connection + and vestigial scan_script_header to ap_scan_script_header_err, + mostly for aesthetic reasons. [Roy Fielding] + + *) The query switch "httpd -S" didn't exit after showing the + vhost settings. That was inconsistent with the other query functions. + [Martin Kraemer] + + *) Moved the MODULE_MAGIC_COOKIE from before the versions and + filename to the end of the STANDARD_MODULE_STUFF. Its + presence at the beginning prevented reporting of the filename + for modules compiled before 1 January 1999. [Ken Coar] + + *) SECURITY: ap_os_is_filename_valid() has been added to Win32 + to detect and prevent access to special DOS device file names. + [Paul Sutton, Ken Parzygnat] + + *) WIN32: Created new makefiles Makefile_win32.txt (normal build) + and Makefile_win32_debug.txt (debug build) that work on Win95. + Run each of the following from the src directory: + nmake /f Makefile_win32.txt # compiles normal build + nmake /f Makefile_win32.txt install # compiles and installs + nmake /f Makefile_win32.txt clean # removes compiled junk + nmake /f Makefile_win32_debug.txt # compiles debug build + nmake /f Makefile_win32_debug.txt install + nmake /f Makefile_win32_debug.txt clean + [Roy Fielding] + + *) Added binbuild.sh and findprg.sh helpers to make it easier for us + to build binary distributions. [Lars Eilebrecht] + + *) IndexOptions SuppressColumnSorting only turned off making + the column headers anchors; you could still change the display + order by manually adding a '?N=A' or similar query string to the + URL. Now SuppressColumnSorting locks in the sort order so + it can't be overridden this way. [Ken Coar] + + *) Added IndexOrderDefault directive to supply a default sort order + for FancyIndexed directory listings. [Ken Coar] PR#1699 + + *) Change the ap_assert macro to a variant that works on all platforms. + [Richard Prinz ] PR#2575 + + *) Make sure under ELF-based NetBSD (now) and OpenBSD (future) we don't + search for an underscore on dlsym() (as it's already the case + for FreeBSD 3.0). [Todd Vierling ] PR#2462 + + *) Small fix for mod_env.html: The module was documented as to be _not_ + compiled into Apache per default, although it _IS_ compiled into + Apache per default. [Sim Harbert ] PR#3572 + + *) Instead of fixing a bug in the generation procedure for config.status (a + backslash was missing) we remove the bug together with it's complete + context because the special cases of the past can now no longer occur + because of the recent magic for the --with-layout default. + [Ralf S. Engelschall] PR#3590 + + *) Make top-level Makefile aware of a parallel build procedures (make -j) by + making sure the src/support/ tools are _forced_ to be build last (they + depend on other libraries). + [Markus Theissinger ] + + *) Fix installation procedure: Now that os-inline.c is actually used (a + recently fixed bug prevented this) we need to also install os-include.c + in addition to os.h into the PREFIX/include/ location or building of + module DSOs with APXS fails. [Ralf S. Engelschall] PR#3527 + + *) Added MODULE_MAGIC_COOKIE as the first field in a module structure to + allow us to distinguish between a garbled DSO (or even a file which isn't + an Apache module DSO at all) and a DSO which doesn't match the current + Apache API. [Ralf S. Engelschall] PR#3152 + + *) Two minor enhancements to mod_rewrite: First RewriteRule now also + supports the ``nocase|NC'' flag (as RewriteCond already does for ages) to + match case insensitive (this especially avoids nasty patterns like + `[tT][eE][sS][tT]'). Second two additional internal map functions + `escape' and `unescape' were added which can be used to escape/unescape + to/from hex-encodings in URLs parts (this is especially useful in + combination with map lookups). + [Magnus Bodin, Ian Kallen, Ralf S. Engelschall] + + *) Renamed the macro escape_uri() to ap_escape_uri() which was + forgotten (because it was a macro) in the symbol renaming process. + [Ralf S. Engelschall] + + *) Fix some inconsistencies related to the scopes of directives. The only + user visible change is that the directives `UseCanonicalName' and + `ContentDigest' now use the (more correct) `Options' scope instead of + (less correct) `AuthConfig' scope. [Ralf S. Engelschall] + + *) Using DSO, the Server token was being mangled. Specifically, the + module's token was being added first before the Apache token. This + has been fixed. [Jim Jagielski] + + *) Major overhaul of mod_negotiation.c, part 2. + - properly handle "identity" within Accept-Encoding. + - allow encoded variants in RVSA negotiation and let them appear in + the Alternates field using the non-standard "encoding" tag-list. + - fixed both negotiation algorithms so that an explicitly accepted + encoding is preferred over no encoding if "identity" is not + included within Accept-Encoding. + - added ap_array_pstrcat() to alloc.c for efficient concatenation + of large substring sequences. + - replaced O(n^2) memory hogs in mod_negotiation with ap_array_pstrcat. + [Roy Fielding] + + *) Major overhaul of mod_negotiation.c, part 1. + - cleanups to mod_negotiation comments and code structure + - made compliant with HTTP/1.1 proposed standard (rfc2068) and added + support for everything in the upcoming HTTP/1.1 + revision (draft-ietf-http-v11-spec-rev-06.txt). + - language tag matching also handles tags with more than 2 + levels like x-y-z + - empty Accept, Accept-Language, Accept-Charset headers are + processed correctly; previously an empty header would make all + values acceptable instead of unacceptable. + - allowed for q values in Accept-Encoding + - added support for transparent content negotiation (rfc2295 and + rfc2296) (though we do not implement all features in these drafts, + e.g. no feature negotiation). Removed old experimental version. + - implemented 'structured entity tags' for better cache correctness + (structured entity tags ensure that caches which can deal with Vary + will (eventually) be updated if the set of variants on the server + is changed) + - this involved adding a vlist_validator element to request_rec + - this involved adding the ap_make_etag() function to the global API + - modified guessing of charsets used by Apache negotiation algorithm + to guess 'no charset' if the variant is not a text/* type + - added code to sort multiviews variants into a canonical order so that + negotiation results are consistent across backup/restores and mirrors + - removed possibility of a type map file resolving to another type map + file as its best variant + [Koen Holtman, Roy Fielding, Lars Eilebrecht] PR#3451, 3299, 1987 + + *) RFC2396 allows the syntax http://host:/path (with no port number) + but the proxy disallowed it (ap_proxy_canon_netloc()). + [David Kristol ] PR#3530 + + *) When modules update/modify the file name in the configfile_t structure, + syntax errors will report the updated name, not the original one. + [Fabien Coelho ] PR#3573 + + *) Correct some filename case assumptions from WIN32 to + CASE_BLIND_FILESYSTEM. [Brian Havard ] + + *) For %v log ServerName regardless of the UseCanonicalName + setting (similarly for %p). [Dean Gaudet] + + *) Configure was initializing the variables $OSDIR, $INCDIR and $SHELL + rather late (too late for some invocations of TestCompile). + This improves the make environment available to TestCompile and + the *.module scripts. [Martin Kraemer] + + *) The hashbang emulation code in ap_execve.c would interpret + #!/hashbang/scripts correctly, but failed to fall back to a + standard shell for scripts which did NOT start with #! + Now SHELL_PATH is started in these cases. [Martin Kraemer] + + *) PORT: Added the Cyberguard V2 port [Richard Stagg ] + PR#3336 + + *) Update APXS manual page: some -q option arguments were missing + and another was incorrect. [Mark Anderson ] PR#3553 + + *) Cleanup the command line options: `-?' was documented to show + the usage list but does it with an error because `?' is not a valid + command. OTOH a lot of users expect `-h' to print such a usage list and + instead are annoyed for ages by our huge unreadable list of directives. + So we now changed the command line options this way: + 1. `-L' => `-R' + Intent: we need `-L' to be free, and `-R' for the DSO run-time path is + very similar to the popular linker option. + 2. `-h' => `-L' + Intent: while -l gives the small list of modules, -L now gives the + large list of directives implemented by these modules. This is also + consistent with -v (short version info) and -V (large version info). + 3. `-?' => `-h' + Intent: it's now the expected option ;-) + The manual page was adjusted accordingly. + [Ralf S. Engelschall] PR#2714 + + *) Fixed problem of fclose() on an unopened file in suexec if LOG_EXEC + wasn't defined. [Rick Franchuk ] + + *) Removed recently introduced bugs and disfigurements in APACI: + o fixed argument line processing: using $args was broken: It was not + initialized and using args="$args $apc_option" and even args="$args + \"$apc_option\"" fails in the second processing round for any arguments + containing whitespaces. The only correct way is to use the construct + "$@" (but not possible here) or iterate _both_ times over the implicit + argument line (no argument to for-loop) which is what we now use. + o make --with-layout=Apache the default without creating + redundancy (copying the --with-layout block in the argument parsing + loop). We achieve this by using the "$@" construct together with the + `set' command to prepend --with-layout=Apache to the command line in + case --with-layout is not used. + o fixed auto-suffix handling now that config.layout exists. + Paths which are auto-suffixed are marked with a trailing plus sign in + config.layout and every path now can be marked this way (not only the + four paths for which we do it currently). Additionally the suffix is + no longer a static one. Instead it's now `/' where is + the argument of the --target option or per default `httpd'. + o allow also tabs (and only spaces) where we match whitespaces + o various fixes and cleanups related to used shell coding style + o made Jim happy by replacing `Written by' with `Initially written by' ;-) + o trimmed output of --help to fit into 80 columns + [Ralf S. Engelschall] + + *) Added two new core API functions, ap_single_module_configure() and + ap_single_module_init(), which are now used by mod_so to configure a module + after loading. [Ralf S. Engelschall] + + *) PORT: Add defines for USE_FLOCK_SERIALIZED_ACCEPT and + SINGLE_LISTEN_UNSERIALIZED_ACCEPT to NetBSD/OpenBSD section + of ap_config.h to allow serialized accept for multiport listens. + [Roy Fielding, Curt Sampson] PR#3120 + + *) PORT: Fixed a misplaced #endif for NetBSD/OpenBSD section + of ap_config.h that would skip several defines if DEFAULT_GROUP + was overridden. [Roy Fielding] + + *) PORT: The I86 version of DGUX has support for strncasecmp and + strcasecmp, so allow it in ap_config.h. [Amiel Lee Yee] PR#3247 + + *) Fix ordering of definitions in ap_config.h so that ap_inline is + defined before it might be used. [Victor Khimenko] + + *) PORT: Add Dynamic Shared Object (DSO) support for BSDI (v4.0). + [Tom Serkowski ] PR#3453 + + *) Make generation of src/Configuration.apaci more robust: It failed to + differenciate between modules when one module name was a postfix of + another (e.g. cgi vs. fastcgi). We now check for mod_XXX, libXXX and even + just XXX (think about totally non-standard names like "apache_ssl", too). + [Ralf S. Engelschall] PR#3380 + + *) In src/Configure remove the SERVER_SUBVERSION support (already deprecated + since 1.3b7) and make whitespace handling more robust (it failed horrible + when whitespaces were present in the arguments of -D options). + [Ralf S. Engelschall] PR#3240 + + *) Add APACI --shadow=DIR variant (in addition to --shadow). This now first + creates an external package shadow tree in DIR before the local build + shadow tree is generated under DIR. This way one can have the extracted + Apache distribution tree read-only on NFS or CDROM and still build Apache + from these sources. An automatically triggered VPATH-like mechanism is + provided through the TOP variable, too. + [Ralf S. Engelschall, Wilfredo Sanchez ] + + *) Fix negotiation so that a Vary response header is correctly + generated when, for a particular dimension, variants only vary + in having or not having a value for that dimension. [Paul Sutton] + + *) Fix negotiation so that we prefer an encoded variant over an + unencoded variant if the user-agent explicitly says it can + accept that encoding. Previously we always preferred the unencoded + variant. + [Paul Ausbeck , Paul Sutton] PR#3447 + + *) Fix APXS tool: query variables LIBS_SHLIB and TARGET were not recognized + and the usage page was inconsistent with the functionality and manpage. + [Ralf S. Engelschall] + + *) Allow special options -Wc,xxx and -Wl,xxx on APXS compile/link command. + They can occur multiple times and their arguments (`xxx') are passed AS + IS to the compiler/linker command. [Ralf S. Engelschall] + + *) Fixed possible (but harmless in practice) bug in the DBM lookup + procedure of mod_rewrite: very long keys were truncated. + [Ralf S. Engelschall] + + *) Added a generic --with-layout=[FILE:]ID option. ID here is a layout + identifier, currently "Apache" and "GNU" are pre-defined in the file + config.layout. Custom layouts are possible by using FILE:ID as the + argument where the layout ID is taken from FILE. + + The config.layout file consists of .. sections + where inside those sections "path_variable: path_value" pairs can be + specified. These lines are converted to path_variable='path_value'. + + *) Add a DefaultLanguage directive so that files missing a language + extension (e.g., .fr, .de) can be labelled as being some other + default language. DefaultLanguage can appear in and + containers as well as .htaccess files. [Paul Sutton] + PR#1180 + + *) Fix TARGET configuration when configuring and installing using + APACI configure. TARGET now defines the basename of the configuration + file, startup script, manual page, etc. log_error_core() now reports + the server binary name given by argv[0]. TARGET can now also be defined + with --target=TARGET parameter passed to APACI configure. + [Ralf Engelschall, Randy Terbush] + + *) mod_include.c:handle_perl() now properly tests for OPT_INCNOEXEC + rather than OPT_INCLUDES [Rainer Schoepf ] + + *) ap_md5_binary() was using sprintf() rather than a table lookup + to convert binary bytes to hex digits. + [Ronald Tschalär ] PR#3409 + + *) Fix SEGV in TCN negotiation if no variants are acceptable. + [Martin Plechsmid ] PR#1987 + + *) API: ap_exists_config_define() function is now "public" [Doug MacEachern] + + *) Fix documentation of `Action' directive: It can activate a CGI script + when either a handler or a MIME content type is triggered by the request. + [Andrew Pimlott ] PR#3340 + + *) Document the `add' command of `dbmmanage' in `dbmmanage.1' manpage. + [David MacKenzie ] PR#3394 + + *) Ignore a "ErrorDocument 401" directive with a full URL and write a + notice to the error log. It is not possible to send a 401 response + and a redirect at the same time. [Lars Eilebrecht] + + *) Fallback to native compilers for IRIX-32 platform. It seems that + a gcc 2.8.1 compiled apache is logging client addresses with all + bits set (255.255.255.255). This is the second such problem caused + by gcc 2.8.1 compiler. The first being broken semaphore locking. + [Randy Terbush] + + *) Updated mime.types to reflect current Internet media types + and include a URL to the registry. + [Manoj Kasichainula, Roy Fielding] PR#2380, 2286, 2246 + + *) SECURITY: Do a more complete check in mod_include to avoid + an infinite loop of recursive SSI includes. [Marc Slemko] PR#3323 + + *) Add APACI --suexec-docroot and --suexec-logfile options which can be + used to set the document root directory (DOC_ROOT) and the suexec + logfile (LOG_EXEC), respectively. Additionally the --layout option + was changed to show more information about the suEXEC setup. + [Lars Eilebrecht] PR#3316, 3357, 3361 + + *) Added the last two WebDAV status codes of 424 (Failed Dependency) + and 507 (Insufficient Storage) for use by third-party modules. + [Roy Fielding] + + *) Enabled all of the WebDAV method names for use by third-party + modules, Limit, and Script directives. That includes PATCH, + PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, and UNLOCK. + Improved mod_actions.c so that it can use any of the methods + defined in httpd.h. Added ap_method_number_of(method) for + getting the internal method number. [Roy Fielding] + + *) PORT: Add a port to the TPF OS. [Joe Moenich and + others at IBM] + + *) Fix problems with handling of UNC names (e.g., \\host\path) + on Win32. [Ken Parzygnat ] + + *) Rework os_canonical_*() on Win32 so it's simpler, more + robust, and works. [Ken Parzygnat ] + PR#2555, 2915, 3064, 3232 + + *) Work around incomplete implementation of strftime on Win32. + [Manoj Kasichainula, Ken Parzygnat ] + + *) Move a typedef to fix compile problems on Linux with 1.x kernels. + [Manoj Kasichainula] PR#3177 + + *) PORT: Add a port to the Concurrent PowerMAX OS. [Tom Horsley + ] + + *) WIN32: Log more explicit error messages if spawning an interpreted + script failed, including the command line used to attempt to execute + the interpreter and the Win32 error code returned. [Marc Slemko] + + *) Disable sending of error-notes on a 500 (Internal Server Error) response + since it often includes file path info. Enable sending of error-notes + on a 501 (Method Not Implemented). [Roy Fielding] PR#3173 + + *) http_config.c would respond with 501 (Method Not Implemented) if a + content type handler was specified but could not be found, which + should have been a 500 response. Likewise, mod_proxy.c would responsd + with a 501 if the URI scheme is unrecognized instead of the correct + response of 403 (Forbidden). [Roy Fielding] + + *) SECURITY: Eliminate DoS attack when a bad URI path contains what + looks like a printf format escape. [Marc Slemko, Studenten Net Twente] + + *) Fix in mod_autoindex: for files where the last modified time stamp was + unavailable, an empty string was printed which was 2 bytes short. + The size and description columns were therefore not aligned correctly. + [Martin Kraemer] (no PR#) + + *) Update BS2000 OS code to work with recent versions. Starting with + release A17, the child fork() must be replaced by a _rfork(). + (BS2000 only) [Martin Kraemer] + + *) Add the actual server_rec structure of the specific Vhost to the + scoreboard file and avoid a string copy (as well as allow some + further future enhancements). [Harrie Hazewinkel + ] + + *) Add APACI --permute-module=foo:bar option which can be used to + on-the-fly/batch permute the order of two modules (mod_foo and mod_bar) + in the Configuration[.apaci] file. Two special and important variants are + supported for the option argument: first BEGIN:foo which permutes module + mod_foo with the begin of the module list, i.e. it `moves' the module to + the begin of the list (gives it lowest priority). And second foo:END + which permutes mod_foo with the end of the module list, i.e. it `moves' + the module to the end of the list (gives it highest priority). + [Ralf S. Engelschall] + + *) Fix problem with 'apache -k shutdown' and startup event + synchronisation (Win32). [Ken Parzygnat ] + PR#3255 + + *) The config parser wasn't correctly noticing a missing '>' + on container start lines (e.g., it wouldn't spot + "] + PR#3279 + + *) Add a 'RemoveHandler' directive which will selectively remove + all handler associations for the specified file extensions. + [Ryan Bloom ] PR#1799. + + *) Properly handle & allow "nul" and ".*/null" in AccessConfig and + ResourceConfig directives on Win32. Also add a note to the effect + of 'useless User directive ignored on Win32' to the errorlog if + a User directive is encountered on Win32. + [Ken Parzygnat ] PR#2078, 2303. + + *) Fix multiple whitespace handling in imagemaps for mod_imap which was + broken since Apache 1.3.1 where we took out compressing of multiple + spaces in ap_cfg_getline(). + [Ivan Richwalski ] PR#3249 + + *) Fix Berkeley-DB/2.x support in mod_auth_db: The data structures were not + initialized correctly and the db_open() call used an invalid mode + parameter. [Ron Klatchko ] PR#3171 + + *) PORT: DSO support for UnixWare 7 + [Ralf S. Engelschall, Ron Record ] + + *) Merge the contents of the {srm,access}.conf-dist* files into the + httpd.conf-dist* files. The srm and access files now contain + only comments, and httpd.conf has all the combined contents in + a rational order. [Ken Coar] + + *) PORT: DSO/ELF support for FreeBSD 3.0. + [Ralf S. Engelschall, Dirk Froemberg ] + + *) Add a "default-handler" handler that calls the default_hander() + function which is normally called for static content. This allows + you to override a specific handler. [Marc Slemko] + + *) Further simplify checking for absolute paths by replacing an + hard-coded syntax check with a call to a routine we already created to + do this. [Ken Parzygnat ] PR#2976, 3074 + + *) Log an error if we encounter a malformed "require" directive + in mod_auth if we know that we know that no other module can + deal with it. [Marc Slemko] + + *) Remove ap_private_extern method of hiding conflicting symbols + on the NEXT platform because it is not correct for all versions, + and the versions for which it is correct are unknown. + [Wilfredo Sanchez ] + + *) Fix inheritance of IndexOptions NameWidth and remove unintended + restriction on +NameWidth, +IconHeight, and +IconWidth. [Ken Coar] + + *) Fix per-directory config merging for cases in which a 500 error + is encountered in an .htaccess file somewhere down the tree. + [Ken Coar] PR#2409 + + *) Minor performance improvement to ap_escape_html(). [Roy Fielding] + + *) Fixed a segmentation violation in mod_proxy when a response is + non-cachable. [Roy Fielding, traced by Doug Bloebaum]. PR#2950, 3056 + +Changes with Apache 1.3.3 + + *) Added a complete implementation of the Expect header field as + specified in rev-05 of HTTP/1.1. Disabled the 100 Continue + response when we already know the final status, which is mighty + useful for PUT responses that result in 302 or 401. [Roy Fielding] + + *) Remove extra trailing whitespace from the getline results as part + of the protocol processing, which is extra nice because it works + between continuation lines, is almost no cost in the normal case + of no extra whitespace, and saves memory. [Roy Fielding] + + *) Added new HTTP status codes and default response bodies from the + revised HTTP/1.1 (307, 416, 417), WebDAV (102, 207, 422, 423), and + HTTP Extension Framework (510) specifications. Did not add the + WebDAV 424 and 425 codes because they are bogus. We don't use any + of these codes yet, but they are now available to 3rd-party modules. + [Roy Fielding] + + *) Fix a possible race condition between timed-out requests and the + ap_bhalfduplex select that might result in an infinite loop on + platforms that do not validate the descriptor. [Roy Fielding] + + *) WIN32: Add "-k shutdown" and "-k restart" options to signal a + running Apache server [Paul Sutton] + + *) Fix mod_autoindex bug where directories got a size of "0k" instead + of "-". [Martin Plechsmid , Marc Slemko] + PR#3130 + + *) PORT: DRS 6000 machine. [Paul Debleecker ] + + *) Add the server signature text (from the core ServerSignature directive) + to the list of envariables available to scripts, SSI, and the like. + [Ken Coar] + + *) PORT: Fix sys/resource.h handling for SCO 3.x platform. + [M. Laak ] PR#3108 + + *) Fallback from sysconf-based to plain HZ-based `ticks per second' + calculation in mod_status for all systems which don't have POSIX + sysconf() (like UTS 2.1) and not only for the NEXT platform. + [Dave Dykstra ] PR#3055 + + *) Fix `require ...' directive parsing in mod_auth, mod_auth_dbm and + mod_auth_db by using ap_getword_white() (which uses ap_isspace()) + instead of ap_getword(..., ' ') (which parses only according to spaces + but not tabs). [James Morris , + Ralf S. Engelschall] PR#3105 + + *) Fix the SERVER_NAME variable under sub-request situations (where + `UseCanonicalName off' is used) like CGI's called from SSI pages or + RewriteCond variables by adopting r->hostname to sub-requests. + [James Grinter ] PR#3111 + + *) Fix stderr redirection under syslog-based error logging situation. + [Youichirou Koga ] PR#3095 + + *) Document `ErrorLog syslog:facility' variant of error logging. + [Youichirou Koga ] PR#3096 + + *) Fix http://localhost/ hints in top-level INSTALL document. + [Rob Jenson , Ralf S. Engelschall] PR#3088 + + *) Quote paths in default configuration files. [Wilfredo Sanchez] + + *) PORT: Remove extra HAVE_SYS_RESOURCE_H define for RHAPSODY since + it is now taken care of properly by the header file tests. + [Wilfredo Sanchez ] + + *) Fix problem with scripts and filehandle inheritance on Win32. + [Ken Parzygnat ] PR#2884, 2910 + + *) Win32 name canonicalisation could end up using the server's + working directory to fill in some blanks. [Ken Parzygnat + ] PR#3001 + + *) Correct invalid assumption by ap_sub_req_lookup_file() that all + absolute paths begin with "/" -- because they don't on Win32. + [Ken Parzygnat ] PR#2976, 3074 + + *) Add [REDIRECT_]VARIANTS environment variable to mod_speling + so that ErrorDocument 300 processors can reformat the list + if desired. [Ken Coar] PR#2859 + + *) Add +/- incremental prefixes to IndexOptions keywords, and + enable merging of multiple IndexOptions directives. [Ken Coar] + + *) PORT: Allow GuessOS to recognize Unixware 7.0.1 [Steve Cameron + ] + + *) Reconstructed the loop through multiple htaccess file names so + that missing files are not confused with unreadable files. + [Roy Fielding] + + *) The ap_pfopen and ap_pfdopen routines were failing to protect the + errno on an error, which leads to one error being mistaken for + another when reading non-existent .htaccess files. + [Jim Jagielski] + + *) OS/2: The new header tests get things right, need to update + ap_config.h. [Brian Havard] + + *) The Perl %ENV hash will now be setup by default when using the + mod_include `perl' command [Doug MacEachern] + + *) PORT: Add Pyramid DC/OSx support to configuration mechanism. + [Earle Ake ] + + *) PORT: Fix sys/resource.h handling for Amdahl's UTS 2.1 + [Dave Dykstra ] PR#3054 + + *) Correct comment in mod_log_config.c about its internals. + [Elf Sternberg ] + + *) Avoid possible line overflow in Configure: Use an awkfile to + handle the creation of modules.c [Jim Jagielski] + +Changes with Apache 1.3.2 + + *) Fix bug in ap_remove_module(), which caused problems for dso's + who were the top_module. [Doug MacEachern] + + *) Add support for Berkeley-DB/2.x (in addition to Berkeley-DB/1.x) to + mod_auth_db to both be friendly to users who wants to use this version + and to avoid problems under platforms where only version 2.x is present. + [Dan Jacobowitz , Ralf S. Engelschall] + + *) When using ap_log_rerror(), make the error message available to the + *ERROR_NOTES envariables by default. [Ken Coar] + + *) BS2000 platform only: get rid of the nasty BS2000AuthFile. + You now must define a BS2000Account name for the server User. + This has fewer security implications than the old approach. + [Martin Kraemer] + + *) Fix SHARED_CORE feature for HPUX platform: We now use extension `.sl' + instead of `.so' and `SHLIB_PATH' instead of `LD_LIBRARY_PATH' on this + platform to make the braindead HPUX linker happy. Notice, for the module + DSOs we don't have to use this, because these are loaded manually (and + not via HPUX' dld). [Ralf S. Engelschall] PR#2905, PR#2968 + + *) Remove 64 thread limit on Win32. + [Bill Stoddard ] + + *) Remove redundant substitutions in top-level Makefile.tmpl. + [Ralf S. Engelschall] + + *) Fix APACI's `Group' configuration adjustment - especially for Linux + platforms where `nogroup' exists in /etc/group. [Ralf S. Engelschall] + + *) Make PrintPath work generically instead of having one version + strictly for OS/2. [Jim Jagielski, Brian Havard] + + *) Fix the recently introduced C header file checking: We now use the C + pre-processor pass only (and no longer the complete compiler pass) to + determine whether a C header file exists or not. Because only this way + we're safe against inter-header dependencies (which caused horrible + portability problems). The only drawback is that we now have a CPP + configuration variable which has to be determined first (we do a similar + approach as GNU Autoconf does here). When all fails the user still has + the possibility to override it manually via APACI or src/Configuration. + As a fallback for the header check itself we can directly check the + existance of the file under /usr/include, too. + [Ralf S. Engelschall] PR#2777 + + *) PORT: Added RHAPSODY (Mac OS X Server) support. MAP_TMPFILE defined + as an alternate mechanism for mmap'd shared memory for RHAPSODY. + ap_private_extern defined to hide symbols that conflict with loaded + dynamic libraries on the NEXT and RHAPSODY platforms. + [Wilfredo Sanchez ] + + *) Delete PID file on clean shutdowns. + [Charles Randall ] PR#2947 + + *) Fix mod_auth_*.html documents: NSCA -> NCSA + [Youichirou Koga ] PR#2991 + + *) Fix INSTALL document: www.gnu.ai.mit.edu -> www.gnu.org + [Karl Berry ] PR#2994 + + *) Fix dbmmanage.1 manual page. + [Youichirou Koga ] PR#2992 + + *) Fix possible buffer overflow situation in suexec.c. + [Jeff Stewart ] PR#2790 + + *) Add some more LIBS for the SCO5 platform which are needed for the already + used -lprot. It's actually a bug in SCO5, of course. + [Ronald Record ] PR#2533 + + *) Fix documentation of ProxyPass/ProxyPassReverse according to the + trailing slash problem. [Jon Drukman ] PR#2933 + + *) Remove `-msym' option from LDFLAGS_SHLIB for the Digital UNIX (OSF/1) + platform, because it's only supported under version 4.0 and higher. But + because our GuessOS is still unaware of Digital UNIX versions and the + -msym is just to optimize the DSO statup time a little bit it's safe and + best when we leave it out now. [Ralf S. Engelschall] PR#2969 + + *) Fix the ap_log_error_old(), ap_log_unixerr() and ap_log_printf() + functions: First all three functions no longer fail on strings containing + "%" chars and second ap_log_printf() no longer does a double-formatting + (instead it directly passes through the message to be formatted to the + real internal formatting function). [Ralf S. Engelschall] PR#2941 + + *) Allow "Include" directives anywhere in the server config + files (but not .htaccess files). [Ken Coar] PR#2727 + + *) The proxy was refusing to serve CONNECT requests except to + port 443 (https://) and 563 (snews://). The new AllowCONNECT + directive allows the configuration of the ports to which a + CONNECT is allowed. [Sameer Parekh, Martin Kraemer] + + *) mod_expires will now act on content that is not sent from a file + on disk. Previously it would never add an Expires: header to + any response that did not come from a file on disk; the only + case where it still doesn't (and can't) add one for that type of + content is if you are using a modification date based setting. + [Marc Slemko, Paul Phillips ] + + *) Problems encountered during .htaccess parsing or CGI execution + that lead to a "500 Server Error" condition now provide explanatory + text (in the *ERROR_NOTES envariable) to ErrorDocument 500 scripts. + [Ken Coar] PR#1291 + + *) Add NameWidth keyword to IndexOptions directive so that the + width of the filename column is customisable. [Ken Coar, Dean Gaudet] + PR#1949, 2324. + + *) Recognize lowercase _and_ uppercase `uname' results under + SCO OpenServer. [David Coelho ] + + *) As duplicate "HTTP/1.0 200 OK" lines within the header seem to be + a common problem of (mis-administrated?) IIS servers, make the apache + proxy immune to these errors (and ignore the duplicates, but log + the fact to error_log). [Martin Kraemer], after the proposal in PR#2914 + + *) The ] PR#2866 + + *) Replace the inlined information grabbing stuff for the configuration + adjustment feature (no --without-confadjust) with calls to a new helper + script `buildinfo.sh' which is both more flexible and already proofed to + be more robust against platform differences. This mainly fixes the + recently occured ``sed: command garbled: ...'' problems. + [Ralf S. Engelschall] PR#2776, PR#2848 + + *) Make ab.c again pass ``gcc -Wall -Wshadow -Wpointer-arith -Wcast-align + -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline'' + without complains after we recently added the POST feature. + [Ralf S. Engelschall] + + *) Renamed is_HTTP_xxx() macros to ap_is_HTTP_xxx() name. They are used inside + modules as API functions and we forgot them at the big symbol renaming. + [Ralf S. Engelschall] + + *) Remove bad reference to non-existing SERVER_VERSION in mod_rewrite.html + [Youichirou Koga ] PR#2895 + + *) Dynamically size the filename column of mod_autoindex output. + [Dean Gaudet] + + *) Add the ability to do POST requests to the ab benchmarking tool. + [Kurt Sussman ] PR#2871 + + *) Bump up MAX_ENV_FLAGS in mod_rewrite.h from the too conservatice limit of + 5 to 10 because there are some users out there who always have 5 to 8 + variables in one RewriteRule and had to patch mod_rewrite.h for every + release. So 15 should be now more than enough, even for them. (I never + needed more than 4 in my RewriteRules ;-) + [Ralf S. Engelschall] + + *) Make the proxy generate and understand Via: headers + [Martin Kraemer] + + *) Change the proxy to use tables instead of array_headers for + the header lines. [Martin Kraemer] + + *) Make sure the config.status file is not overridden when just + ``configure --help'' is used. [Ralf S. Engelschall] PR#2844 + + *) Split MODULE_MAGIC_NUMBER into _MAJOR/_MINOR numbers. This should + provide a way to trace API changes that add functionality but do + not create a compatibility issue for precompiled modules, etc. + See include/ap_mmn.h for more details. [Randy Terbush] + + *) Fix suexec installation under `make install root=xxx' situation. + [Ralf S. Engelschall] + + *) Extend the output of the -V switch to include the paths of all + compiled-in configuration files, if they were overridden at + compile time, for least astonishment of the user. + [Martin Kraemer] + + *) When READing a request in ExtendedStatus mode, the "old" + vhost, request and client information is not displayed. + [Jim Jagielski] + + *) STATUS is no longer available. Full status information now + run-time configurable using the ExtendedStatus directive. + [Jim Jagielski] + + *) SECURITY: CVE-1999-1199 (cve.mitre.org) + Eliminate O(n^2) space DoS attacks (and other O(n^2) + cpu time attacks) in header parsing. Add ap_overlap_tables(), + a function which can be used to perform bulk update operations + on tables in a more efficient manner. [Dean Gaudet] + + *) SECURITY: Added compile-time and configurable limits for + various aspects of reading a client request to avoid some simple + denial of service attacks, including limits on maximum request-line + size (LimitRequestLine), number of header fields (LimitRequestFields), + and size of any one header field (LimitRequestFieldsize). Also added + a configurable directive LimitRequestBody for limiting the size of the + request message body. [Roy Fielding] + + *) Make status module aware of DNS and logging states, even if + STATUS not defined. [Jim Jagielski] + + *) Fix a problem with the new OS/2 mutexes. [Brian Havard] + + *) Enhance mod_speling so that CheckSpelling can be used in + containers and .htaccess files. [Ken Coar] + + *) API: new ap_custom_response() function for hooking into the + ErrorDocument mechanism at runtime [Doug MacEachern] + + *) API: new ap_uuencode() function [Doug MacEachern] + + *) API: scan_script_header_err_core() now "public" and renamed + ap_scan_script_header_err_core() [Doug MacEachern] + + *) The 'status' module will now show the process pid's and their + state even without full STATUS accounting. [Jim Jagielski] + + *) Restore the client IP address to the error log messages, this + was lost during the transition from 1.2 to 1.3. Add a new + function ap_log_rerror() which takes a request_rec * and + formats it appropriately. [Dean Gaudet] PR#2661 + + *) Cure ap_cfg_getline() of its nasty habit of compressing internal + whitespace in input lines -- including within quoted strings. + [Ken Coar] + but leading and trailing whitespace should continue to be + stripped [Martin Kraemer] + + *) Cleanup of the PrintPath/PrintPathOS2 helper functions. Avoid + the ugly use of an env. variable and use command-line args for + alternate $PATH. Make more like advanced 'type's as well. + [Jim Jagielski] + + *) The IRIXN32 Rule was being ignored. Configure now correctly adds + -n32 only if IRIXN32 says to. [Jim Jagielski, Alain St-Denis + ] PR#2736 + + *) Clean up a warning in mod_proxy. [Ralf S. Engelschall] + + *) Renamed __EMX__ (internal define of the gcc port under OS/2) to OS2 + following the same idea as "MSVC vs WIN32". Additionally the src/os/emx/ + directory was renamed to src/os/os2/ for consistency. + [Brian Havard, Ralf S. Engelschall] + + *) Add new Rule SHARED_CHAIN which can be used to enable linking of DSO + files (here modules) against other DSO files (here shared libraries). + This is done by determining a subset of LIBS which can be safely used for + linking the DSOs, i.e. PIC libs and shared libs. Currently the rule is + disabled for all platforms to avoid problems with this (experimental) + rule. But we provide it now for those people how ran into problems and + want to came out by forcing linking against DSOs. + [Ralf S. Engelschall] PR#2587 + + *) Fix suEXEC start message: Has to be of `notice' level to really get + printed together with the standard startup message because the `notice' + level is handled special inside ap_log_error() for startup messages. + [Ralf S. Engelschall] PR#2761 PR#2761 PR#2765 + + *) Add correct `model' MIME types from RFC2077 to mime.types file. + [Ralf S. Engelschall] PR#2732 + + *) Fixed examples in mod_rewrite.html document. + [Youichirou Koga , Ralf S. Engelschall] PR#2756 + + *) Allow ap_read_request errors to propagate through the normal request + handling loop so that the connection can be properly closed with + lingering_close, thus avoiding a potential TCP reset that would + cause the client to miss the HTTP error response. [Roy Fielding] + + *) One more portability fix for APACI shadow tree support: Swap order of awk + and sed in top-level configure script to avoid sed fails on some + platforms (for instance SunOS 4.1.3 and NCR SysV) because of the + non-newline-termined output of Awk. [Ralf S. Engelschall] PR#2729 + + *) PORT: NEC EWS4800 support. + [MATSUURA Takanori ] + + *) Fix a segfault in the proxy on OS/2. [Brian Havard] + + *) Fix Win32 part of ap_spawn_child() by providing a reasonable child_info + structure instead of just NULL. This fixes at least the RewriteMap + programs under Win32. [Marco De Michele ] PR#2483 + + *) Add workaround to top-level `configure' script for brain dead + `echo' commands which interpet escape sequences per default. + [Ralf S. Engelschall] PR#2654 + + *) Make sure that the path to the Perl interpreter is correctly + adjusted under `make install' also for the printenv CGI script. + [Ralf S. Engelschall] PR#2595 + + *) Update the mod_rewrite.html document to correctly reflect the situation + of the `proxy' (`[P]') feature. [Ralf S. Engelschall] PR#2679 + + *) Fix `install-includes' sub-target of `install' target in top-level + Makefile.tmpl: The umask+cp approach didn't work as expected (especially + for users which extracted the distribution under 'umask 077'), so replace + it by an explicit cp+chmod approach. + [Richard Lloyd, Curt Sampson, Ralf S. Engelschall] PR#2656 PR#2626 + + *) Fix `distclean' and `clean' targets in src/Makefile.tmpl to have same + behavior and to cleanup correctly even under enabled SHARED_CORE rule. + [Ralf S. Engelschall] + + *) Use a more straight forward and thus less problematic Sed command in + src/helper/mkdir.sh script. [Ralf S. Engelschall] + + *) Make sure the `configure' scripts doesn't fail when trying to guess the + domainname of the machine and there are multiple `domainname' and + `search' entries in /etc/resolv.conf. + [Ralf S. Engelschall] PR#2710 + + *) Add note about the SHARED_CORE requirement on some platforms also to the + INSTALL file because a lot of users don't read htdocs/manual/dso.html + first. [Ralf S. Engelschall] PR#2701 + + *) Fix document "hyperlink" for dso.html in src/Configuration.tmpl + [Knut A.Syed ] PR#2674 + + *) Modify mod_rewrite to update the Vary response field if the URL rewriting + engine does any manipulations or decisions based upon request fields. + [Ken Coar] PR#1644 + + *) Document the special APACI behavior for installation paths where + ``/apache'' is appended to paths under some (well defined, of course) + situations to prevent pollution of system locations with Apache files. + [Ralf S. Engelschall] PR#2660 + + *) Fixed problem with buffered response message not being sent for + the read_request error conditions of URI-too-long (414) and + malformed header fields (400). [Roy Fielding] PR#2646 + + *) Add support for the Max-Forwards: header line required by RFC2068 for + the TRACE method. This allows apache to TRACE along a chain of proxies + up to a predetermined depth. [Martin Kraemer] + + *) Fix SHARED_CORE rule: The CFLAGS_SHLIB variable is no longer doubled + (compilers complained) and the .so.V.R.P filename extension was adjusted + to correctly reflect the 1.3.2 version. + [Ralf S. Engelschall] PR#2644 + + *) SECURITY: Plug "..." and other canonicalization holes under OS/2. + [Brian Havard] + + *) PORT: implement serialized accepts for OS/2. [Brian Havard] + + *) mod_include had problems with the fsize and flastmod directives + under WIN32. Fix also avoids the minor security hole of using + ".." paths for fsize and flastmod. + [Manoj Kasichainula ] PR#2355 + + *) Fixed some Makefile dependency problems. [Dean Gaudet] + +Changes with Apache 1.3.1 + + *) Disable the incorrect entry for application/msword in the + mod_mime_magic "magic" file because it also matches other Office + documents. [Ralf S. Engelschall] PR#2608 + + *) Fix broken RANLIB handling in src/Configure (the entry from + src/Configuration.tmpl was ignored) and additionally force RANLIB to + /bin/true under HP/UX where ranlib exists but is deprecated. + [Ralf S. Engelschall] PR#2627 + + *) 'apachectl status' failed on some systems. + [Steve VanDevender , Lars Eilebrecht] PR#2613 + + *) Add new flags for ap_unparse_uri_components() to make it generate + the scheme://sitepart string only, or to omit the query string. + [Martin Kraemer] + + *) WIN32: Canonicalize ServerRoot before checking to see if it + is a valid directory. The failure to do this caused certain + ServerRoot settings (eg. "ServerRoot /apache") to be improperly + rejected. [Marc Slemko] + + *) Global renaming of C header files to both get rid of conflicts with third + party packages and to again reach consistency: + 1. conf.h -> ap_config.h + 2. conf_auto.h -> ap_config_auto.h \ these are now merged + 3. ap_config.h -> ap_config_auto.h / in the config process + 4. compat.h -> ap_compat.h + 5. apctype.h -> ap_ctype.h + Backward compatibility files for conf.h and compat.h were created. + + *) mod_mmap_static will no longer take action on requests unless at + least one "mmapfile" directive is present in the configuration. + This experimental module has to do some black magic to operate + inside the current API and thus creates side-effects for other + modules under some circumstances. + [Ralf S. Engelschall] + + *) Add conservative ticks around more egrep arguments in top-level configure + to avoid problems under brain-dead platforms like Digital UNIX (OSF1). + [Ralf S. Engelschall] PR#2596 + + *) mod_rewrite created RewriteLock files under the UID of the parent + process, thus the child processes had no write access to the files. + Now a chown() is done on the file to the uid of the children, + if applicable. [Lars Eilebrecht, Ralf S. Engelschall] PR#2341 + + *) Autogenerate some HAVE_XXXXX_H defines in conf_auto.h (determined via + TestCompile) instead of defining them manually in conf.h based on less + accurate platform definitions. This way we no longer have to fiddle with + OS-type and/or OS-version identifiers to discover whether a system header + file exists or not. Instead we now directly check for the existence of + those esoteric ones. + [Ralf S. Engelschall] PR#2093, PR#2361, PR#2377, PR#2434, + PR#2524, PR#2525, PR#2533, PR#2569 + + *) mod_setenvif (BrowserMatch* and friends) will now match a missing + field with "^$". [Ken Coar] + + *) Set the RTLD_GLOBAL dlopen mode parameter to allow dynamically loaded + modules to load their own modules dynamically. This improves mod_perl + and mod_php3 when these modules are loaded dynamically into Apache. + [Rasmus Lerdorf] + + *) Cache a proxied request in the event that the client cancels the + transfer, provided that the configured percentage of the file has + already been transferred. It works for HTTP transfers only. The + new configuration directive is called CacheForceCompletion. + [Glen Parker ] PR#2277 + + *) Add the "] + + *) Fix yet another signal-based race condition involving nested timers. + Signals suck. [Dean Gaudet] + + *) suexec's error messages have been clarified a little bit. [Ken Coar] + + *) Clean up some, but perhaps not all, 8-bit character set problems + with config file parsing, and URL parsing. We now define + ap_isdigit(), ap_isupper(), ... which cast to an (unsigned char). + This should work on most modern unixes. + [Dean Gaudet] PR#800, 2282, 2553 (and others) + + *) The "handler not found" error was issued in cases where the handler + really did exist, but was just declining to serve the request. + [John Van Essen ] PR#2529 + + *) Add Dynamic Shared Object (DSO) support for SCO5 (OpenServer 5.0.x). + [Ronald Record ] PR#2533 + + *) The APACI libexecdir was not extended with an "apache/" subdir + if the installation prefix didn't already contain "apache", but + it should be because the DSO files are Apache-specific. Now + libexecdir is treated the same way sysconfdir, datadir, localstatedir + and includedir are already treated. + [Charles Levert ] PR#2551 + + *) The parsing routine was incorrectly treating methods as + case-insensitive. [Ken Coar] + + *) The ap_bprintf() code neglected to test if there was an error on + the connection. ap_bflush() misdiagnosed a failure as a success. + [Dean Gaudet] + + *) add support for #perl arg interpolation in mod_include + [Doug MacEachern] + + *) API: Name changes of table_elts to ap_table_elts, is_table_empty + to ap_is_table_empty and bgetflag to ap_bgetflag. [Ben Laurie] + + *) PORT: Add UnixWare 7 support + [Vadim Kostoglodoff ] PR#2463 + + *) Fix the Guess-DSO-flags-from-Perl stuff in src/Configure: "perl" was + used instead of "$PERL" which contains the correctly determined Perl + interpreter (important for instance on systems where "perl" and "perl5" + exists, like BSDI or FreeBSD, etc). + [Ralf S. Engelschall] PR#2505 + + *) Move the initial suEXEC-related startup message from plain + fprintf()/stderr to a delayed ap_log_error()-based one to avoid problems + when Apache is started from inetd (instead of standalone). Under this + situation startup messages on stderr lead to problems (the line is sent + to the client in front of the requested document). + [Ralf S. Engelschall] PR#871, PR#1318 + + *) Add a flag so ap_fnmatch() can be used for case-blind pattern matching. + [Ken Coar, Dean Gaudet] + + *) WIN32: Don't collapse multiple slashes in PATH_INFO. + [Ben Laurie, Bill Stoddard ] PR#2274 + + *) WIN32 SECURITY: Eliminate trailing "."s in path components. These are + ignored by the Windows filesystem, and so can be used to bypass security. + [Ben Laurie, Alexei Kosut]. + + *) We now attempt to dump core when we get SIGILL. [Jim Jagielski] + + *) PORT: remove broken test for MAP_FILE in http_main.c. + [Wilfredo Sanchez ] + + *) PORT: Change support/apachectl to use "kill -0 $pid" to test if the + httpd is running. This should be more portable than figuring out + which of three dozen different versions of "ps" are installed. + [a cast of dozens] + + *) WIN32: If we can't figure out how to execute a file in a script + directory, bail out of the request with an error message. [W G Stoddard] + + *) WIN32 SECURITY: Eliminate directories consisting of three or more dots; + these are treated by Win32 as if they are ".." but are not detected by + other machinery within Apache. This is something of a kludge but + eliminates a security hole. [Manoj Kasichainula, Ben Laurie] + + *) Move ap_escape_quotes() from src/ap to src/main/util.c; it uses + pools and thus pollutes libap (until the pool stuff is moved there). + [Ken Coar] + + *) IndexIgnore should be case-blind on Win32 (and any other case-aware + but case-insensitive platforms). New #define for this added to conf.h + (CASE_BLIND_FILESYSTEM). [Ken Coar] PR#2455 + + *) Enable DSO support for OpenBSD in general, not only for 2.x, because it + also works for OpenBSD 1.x. [Ralf S. Engelschall] + + *) PORT: Fix compilation problem on ARM Linux. + [Sam Kington ] PR#2443 + + *) Let APACI's configure script determine some configuration parameters + (Group, Port, ServerAdmin, ServerName) via some intelligent tests to + remove some of the classical hurdles for new users when setting up + Apache. This is done per default because it is useful for the average + user. Package authors can use the --without-confadjust option to disable + these configuration adjustments. + [Ralf S. Engelschall] + + *) Added an EXTRA_DEPS configuration parameter which can be used + to add an extra Makefile dependency for the httpd target, for instance + to external third-party libraries, etc. + [Ralf S. Engelschall] + + *) Add .. sections to the core module (with same spirit + as .. sections) which can be used to skip or process + contained commands dependend of ``-D PARAMETER'' options on the command + line. This can be used to achieve logical conditions like instead of physically ones (e.g. ) + and thus especially can be used for conditionally loading DSO-based + modules via LoadModule, etc. [Ralf S. Engelschall] + + *) PORT: clean up a warning in mod_status for OS/2. [Brian Havard] + + *) Make table elements const. This may prevent obscure errors. [Ben Laurie] + + *) Fix parsing of FTP `SIZE' responses in proxy module: The newline was not + truncated which forced following HTTP headers to be data in the HTTP + reponse. [Ralf S. Engelschall, Charles Fu ] + PR#2412, 2367 + + *) Portability fix for APACI shadow tree support: Swap order of awk and sed + in top-level configure script to avoid sed fails on some platforms (for + instance SunOS 4.1.3 and NCR SysV) because of the non-newline-termined + output of Awk. [Bill Houle ] PR#2435 + + *) Improve performance of directory listings (mod_autoindex) by comparing + integer keys (last-modified and size) as integers rather than converting + them to strings first. Also use a set of explicit byte tests rather + than strcmp() to check for parent directory-ness of an entry. Oh, and + make sure the parent directory (if displayed) is *always* listed first + regardless of the sort key. Overall performance winnage should be good + in CPU time, instruction cache, and memory usage, particularly for large + directories. [Ken Coar] + + *) Add a tiny but useful goody to APACI's configure script: The generation + of a config.status script (as GNU Autoconf does) which remembers the used + configure command and hence can be used to restore the configuration by + just re-running this script or for remembering the configuration between + releases. + [Ralf S. Engelschall] + + *) Add httpd -t (test) option for running configuration syntax tests only. + If something is broken it complains and exits with a return code + non-equal to 0. This can be used manually by the user to check the Apache + configuration after editing and is also automatically used by apachectl + on (graceful) restart command to make sure Apache doesn't die on restarts + because of a configuration which is now broken since the last (re)start. + This way `apachectl restart' can be used inside cronjobs without having + to expect Apache to be falling down. Additionally the httpd -t can be run + via `apachectl configtest'. + [Ralf S. Engelschall] PR#2393 + + *) Minor display fix for "install" target of top-level Makefile: + the displayed installation command was incorrect although the + executed command was correct. Now they are in sync. + [Ralf S. Engelschall] PR#2402 + + *) Correct initialization of variable `allowed_globals' in http_main.c + [Justin Bradford ] PR#2400 + + *) Apache would incorrectly downcase the entire Content-Type passed from + CGIs. This affected server-push scripts and such which use + multipart/x-mixed-replace;boundary=ThisRandomString. + [Dean Gaudet] PR#2394 + + *) PORT: QNX update to properly guess 32-bit systems. + [Sean Boudreau ] PR#2390 + + *) Make sure the DSO emulation code for HPUX finds the proprietary shl_xxx() + functions which are in libdld under HPUX 9/10. + [Ralf S. Engelschall] PR#2378 + + *) Make sure the "install" target of the top-level Makefile doesn't break + because of a return code of 1 from an "if" (for instance under braindead + Ultrix the result code of an "if" construct is 1 if the "then" clause + didn't match). [Ralf S. Engelschall] + + *) Add an additional "dummy" target to the "$(LIB)" target in generated + modules/xxx/Makefile's to avoid problems with SVR4 Make under "full-DSO" + situation (no libxxx.a built, only mod_xxx.so's) where LIB and OBJS are + empty. [Ralf S. Engelschall, Dean Gaudet, Martin Kraemer] + + *) Replace two bad sprintf() calls with ap_snprintf() variants in + mod_rewrite. [Ralf S. Engelschall] + + *) Fix missing usage description for MetaFiles directive. + [David MacKenzie ] PR#2384 + + *) mod_log_config wouldn't let vhosts use log formats defined in the + main server. [Christof Damian ] PR#2090 + + *) mod_usertrack was corrupting the client hostname. As part of the + fix, the cookie values were slightly extended to include the + fully qualified hostname of the client. + [Dean Gaudet] PR#2190, 2229, 2366 + + *) Fix a typo in pool debugging code. [Alvaro Martinez Echevarria] + + *) mod_unique_id did not work on alpha linux (in general on any + architecture that has 64-bit time_t). + [Alvaro Martinez Echevarria] + + *) PORT: Make SCO 5 (and probably 3) compile again. [Ben Laurie] + + *) PORT: NCR MPRAS systems have the same bug with SIGHUP restart that + Solaris systems experience. So define WORKAROUND_SOLARIS_BUG. + [Klaus Weber ] PR#1973 + + *) Change "Options None" to "Options FollowSymLinks" in the + section of the default access.conf-dist + (and -win even though it doesn't matter there). This has better + performance, and more intuitive semantics. [Dean Gaudet] + + *) PORT: Updated support for UTS 2.1.2. + [Dave Dykstra ] PR#2320 + + *) Fix symbol export list (src/support/httpd.exp) after recent + API changes in the child spawning area. + [Jens-Uwe Mager ] + + *) Workaround for configure script and old `test' commands which do not + support the -x flag (for instance under platforms like Ultrix). This is + solved by another helper script findprg.sh which searches for Perl and + Awk like PrintPath but _via different names_. + [Ralf S. Engelschall] + + *) Remove the system() call from htpasswd.c, which eliminates a system + dependancy. ["M.D.Parker" ] PR#2332 + + *) PORT: Fix compilation failures on NEXTSTEP. + [Rex Dieter ] PR#2293, 2316 + + *) PORT: F_NDELAY is a typo, should have been FNDELAY. There's also + O_NDELAY on various systems. [Dave Dykstra ] PR#2313 + + *) PORT: helpers/GuessOS updates for various versions for NCR SVR4. + [juerg schreiner , + Bill Houle ] PR#2310 + + *) Fix recently introduced Win32 child spawning code in mod_rewrite.c which + was broken because of invalid ap_pstrcat() -> strcat() transformation. + [Ralf S. Engelschall] + + *) Proxy Cache Fixes: account for directory sizes, fork off garbage collection + to continue in background, use predefined types (off_t, size_t, time_t), + log the current cache usage percentage at LogLevel debug + [Martin Kraemer, based on discussion between Dean Gaudet & Dirk vanGulik] + +Changes with Apache 1.3.0 + + *) Using a type map file as a custom error document was not possible. + [Lars Eilebrecht] PR#1031 + + *) Avoid problems with braindead Awks by additionally searching for gawk + and nawk in APACI's configure script. + [Dave Dykstra , Ralf S. Engelschall] PR#2319 + + *) Rename md5.h to ap_md5.h to avoid conflicts with native MD5 on + some systems. [Randy Terbush] + + *) Change usage of perror()+fprintf(stderr,...) in mod_rewrite to + more proper ap_log_error() variants. + [Ralf S. Engelschall] + + *) Make sure the argument for the --add-module option to APACI's configure + script is of type [path/to/]mod_xxx.c because all calculations inside + configure and src/Configure depend on this. + [Ralf S. Engelschall] PR#2307 + + *) Changes usage of perror/fprintf to stderr to more proper ap_log_error + in mod_mime, mod_log_referer, mod_log_agent, and mod_log_config. + [Brian Behlendorf] + + *) Various OS/2 cleanups ["Brian Havard" ] + + *) PORT: QNX needed a #include ; and now it uses flock + serialized accept to handle multiple sockets. + [Rob Saccoccio ] PR#2295, 2296 + + *) Have NT properly set the directory for CGI scripts + (& other spawned children) + [W G Stoddard ] + + *) Propagate environment to CGI scripts correctly in Win32. + [W G Stoddard ] PR#2294 + + *) Some symbol renaming: + ap_spawn_child_err became ap_spawn_child + ap_spawn_child_err_buff became ap_bspawn_child + spawn_child was obsoleted and moved to compat.h + [Brian Behlendorf] + + *) Upgrade the child spawning code in mod_rewrite for the RewriteMap + programs: ap_spawn_child_err() is used and the Win32 case now uses + CreateProcess() instead of a low-level execl() (which caused problems in + the past under Win32). + [Ralf S. Engelschall] + + *) A few cosmetics and trivial enhancements to APXS to make the + generated Makefile more user friendly. [Ralf S. Engelschall] + + *) Proxy Fix: The proxy special failure routine ap_proxyerror() + was updated to use the normal apache error processing, thereby allowing + proxy errors to be treated by ErrorDocument's as well. For this + purpose, a new module-to-core communication variable "error-notes" + was introduced; the proxy (and possibly other modules) communicates + its error text using this variable. Its content is copied to a new + cgi-env-var REDIRECT_ERROR_NOTES for use by ErrorDocuments. + The old proxy special error routine ap_proxy_log_uerror() + was replaced by regular ap_log_error() calls, many messages were made + more informative. + [Martin Kraemer] PR#494, 1259 + + *) SECURITY: A possible buffer overflow in the ftp proxy was fixed. + [Martin Kraemer] + + *) Transform the configure message "You need root privileges for suEXEC" + from a fatal error into a (more friendly) warning because the building + ("make") of Apache we can allow, of course. Root privileges are needed + only for the installation step ("make install"). So make sure the + user is aware of this fact but let him proceed as long as he can. + [Ralf S. Engelschall] PR#2288 + + *) Renamed three more functions to common ap_ prefix which we missed at the + Big Symbol Renaming because they're #defines and not real C functions: + is_default_port(), default_port(), http_method(). + [Ralf S. Engelschall] + + *) A zero-length name after a $ in an SSI document should cause + just the $ to be in the expansion. This was broken during the + security fixes in 1.2.5. [Dean Gaudet] PR#1921, 2249 + + *) Call ap_destroy_sub_req() in ap_add_cgi_vars() to reclaim some + memory. [Rob Saccoccio ] PR#2252 + + *) Fix src/support/httpd.exp (DSO export file which is currently only + used under AIX) because of recent changes to function names. + [Ralf S. Engelschall] + +Changes with Apache 1.3b7 + + *) Make sure a MIME-type can be forced via a RewriteRule even when no + substitution takes place, for instance via the following rule: + ``RewriteRule ^myscript$ - [T=application/x-httpd-cgi]'' This was often + requested by users in the past to force a single script without a .cgi + extension and outside any cgi-bin dirs to be executed as a CGI program. + [Ralf S. Engelschall] PR#2254 + + *) A fix for protocol issues surrounding 400, 408, and + 414 responses. [Ed Korthof] + + *) Ignore MaxRequestsPerChild on WIN32. [Brian Behlendorf] + + *) Fix discrepancy in proxy_ftp.c which was causing failures when + trying to connect to certain ftpd's, such as anonftpd. + [Rick Ohnemus ] + + *) Make mod_rewrite use ap_open_piped_log() for RewriteLog directive's + logfile instead of fiddling around itself with child spawning stuff. + [Ralf S. Engelschall] + + *) Made RefererIgnore case-insensitive. + + *) Mod_log_agent, mod_log_referer now use ap_open_piped_log for piped logs. + [Brian Behlendorf] + + *) Replace use of spawn_child with ap_spawn_child_err_buff, to make everything + "safe" under Win32. In: mod_include.c, mod_mime_magic.c + [Brian Behlendorf] + + *) Improve RFC1413 support. [Bob Beck ] + + *) Fix support script `dbmmanage': It was unable to handle some sort + of passwords, especially passwords with "0" chars. + [Ralf S. Engelschall] PR#2242 + + *) WIN32: Clicking on "Last Modified" in a fancy index caused a crash. Fixed. + [Ben Laurie] PR#2238 + + *) WIN32: CGIs could cause a hang (because of a deadlock in the standard C + library), so CGI handling has been changed to use Win32 native handles + instead of C file descriptors. + [Ben Laurie and Bill Stoddard ] PR#1129, 1607 + + *) The proxy cache would store an incorrect content-length in the cached + file copy after a cache update. That resulted in repeated fetching + of the original copy instead of using the cached copy. + [Ernst Kloppenburg ] PR#2094 + + *) The Makefiles assumed that DSO files are build via $(LD). This + is broken for two reasons: First we never defined at least LD=ld + somewhere to make sure this works (it was silently assumed that most Make + provide a built-in LD definition - ARGL!) and second using the generic LD + variable is not the truth. Instead a special variable named LD_SHLIB is + reasonable because although "ld" is usually the default, the command for + building DSO files can be "libtool" or even "cc" on some systems. + [Ralf S. Engelschall] + + *) Replace the AddVersionPlatform directive with ServerTokens which + provides for more control over the format of the Server: + header line. SERVER_SUBVERSION is no longer supported; + all module should use the ap_add_version_component() + API function instead. [Jim Jagielski] + + *) Support for the NCR MP/RAS 3.0 + [John Withers ] + + *) The LDFLAGS_SHLIB_EXPORT variable of src/Configuration[.tmpl] was + not retrieved in src/Configure and thus was not useable. + [Ralf S. Engelschall] + + *) Various Makefile consistency cleanups: + - make OSDIR also automatically be relative to src/ like INCDIR + - SUBDIRS is now generated in src/Makefile only and not in + Makefile.config because it is a local define for this location. + - remove BROKEN_BPRINTF_FLAGS because is it no longer used inside + any Makefile but make sure that at least the "-K inline" is kept in + CFLAGS for SCO 5. + - update the "depend" targets in Makefile.tmpl files to use $(OSDIR), too. + - updated the dependencies theirself + - removed not existing SHLIB variable from "clean" targets + - replaced SHLIB_OBJS/SHLIBS_OBJ consistently with OBJS_PIC because OBJS + already exists and OBJS_PIC are also just plain objects and have not + directly to do with "shared" things. The only difference is that they + contain PIC. So OBJS_PIC is the more canonical name. + - Updated the Makefile-dependency lines for OBJS_PIC + - Removed the Makefile-dependency line in Configure to avoid double + definitions + - replaced ugly xx-so.o/xx.so-o hack with a clean and consistent usage + of xxx.lo as GNU libtool does with its PIC objects + - reduce local complexity in modules Makefile.tmpl by moving the last + existing target "depend" to the generation section in Configure, too. + - removed the historical $(SPACER) which was used in the past together + with BROKEN_BPRINTF_FLAGS to avoid zig-zags in the build process. This + is no longer needed. + - force the build and run of the gen_xxx programs under main/ as the + first step before building the objects because it looks cleaner + [Ralf S. Engelschall] + + *) WIN32: Make Win32 work again after the /dev/null DoS fix. + [Ben Laurie] + + *) WIN32: Check for buffer overflows in ap_os_canonical_filename. + [Ben Laurie] + + *) WIN32: Don't force ISAPI headers to finish with \n. + [Jim Patterson , Ben Laurie] PR#2060 + + *) When opening "configuration" files (like httpd.conf, htaccess + and htpasswd), Apache will not allow them to be non-/dev/null + device files. This closes a DoS hole. At the same time, + we use ap_pfopen to open these files to handle timeouts. + [Jim Jagielski, Martin Kraemer] + + *) Apache will now log the reason its httpd children exit if they exit + due to an unexpected signal. (It requires a new porting define, + SYS_SIGLIST, which if defined should point to a list of text + descriptions of the signals available. See PORTING.) [Dean Gaudet] + + *) WIN32: chdir() doesn't make sense in a multithreaded environment + like WIN32. Before, Win32 CGI's could have had sporadic failures + if a chdir call from one thread was made between another chdir call + and a spawn in another thread. So, for now don't chdir for CGI scripts + in WIN32. The current CGI "spec" is unclear as to whether it's + necessary. Long-term fix is to either serialize the chdir/spawn combo + or use WIN32 native calls to spawn a process. This temp fix was + necessary to remove this as a showstopper for 1.3's release. + [Brian Behlendorf] + + *) Cleanup the suEXEC support in APACI and make it more safe: + 1. Add big fat hint in INSTALL about risks and to read the + htdocs/manual/suexec.html document before using the suexec-related + configure options. + 2. Make sure the user has at least provided one --suexec-xxxx option + (specifies suEXEC parameters) in addition to --enable-suexec option. + If only --enable-suexec is given APACI stops with a hint to INSTALL + and htdocs/manual/suexec.html documents. + 3. Provide two additional --suexec-xxxx options to make the suEXEC + configuration complete (especially for package maintainers who else + had to patch the source tree) by providing ways to configure minimal + UID/GID and safe PATH, too. + [Ralf S. Engelschall] + + *) Cleanup of the `configure --shadow' process: + - make sure the configure script creates its temporary files in the + shadow tree to avoid conflicts with parallel configure runs + - removed unnecessary option "-r" from "rm" call for Makefiles + - make sure the configure scripts creates the shadow-wrapper Makefile + only when no shadow trees already exists + - make sure "make distclean" removes the shadow-wrapper Makefile but only + when no more shadow trees exists + - overhauled mkshadow.sh script: now its more IFS-safe and approx. twice + as fast (in the past it needed 70sec, now it runs just 38sec) + - make sure CVS does not complain about the created files + Makefille. and directories src. + [Ralf S. Engelschall] + + *) Added the ap_add_version_component() API routine and the + AddVersionPlatform core directive. The first allows modules to + declare themselves in the Server response header field value, + augmenting the SERVER_SUBVERSION define in the Configuration file + with run-time settings (more useful in a loadable-module environment). + AddVersionPlatform inserts a comment such as "(UNIX)" or "(Win32)" + into the server version string. [Ken Coar] PR#2056 + + *) Minor stability tweaks to avoid core dumps in ap_snprintf. + [Martin Kraemer] + + *) Emit the "Accept-Range" header for the default handler. + [Brian Behlendorf] PR#1464 + + *) Add a note to httpd.conf-dist that apache will on some systems fail + to start when the Group # is set to a negative or large positive value. + [Martin Kraemer] + + *) Make sure the module execution order is correct even when some modules + are loaded under runtime (`LoadModule') via the DSO mechanism: + 1. The list of loaded modules is now a dynamically allocated one + and not the original statically list from modules.c + 2. The loaded modules are now correctly setup by LoadModule for + later use by the AddModule command. + 3. When the DSO mechanism for modules is used APACI's `install' + target now enables all created `LoadModule' lines per default because + this is both already expected by the user _and_ needed to avoid + confusion with the next point and reduces the Makefile.tmpl complexity + 4. When the DSO mechanism for modules is used, APACI's `install' + target now additionally makes sure the module list is reconstructed + via a complete `ClearModuleList+AddModule...' entry. + 5. The support tool `apxs' now also makes sure an AddModule command + is added in addition to the LoadModule command. + 6. The modules.c generation was extended to now contain two + comments to make sure no one is confused by the confusing terminology + of loading/linking (we use load=link+load & link=activate instead of + the obvious load=activate & link=link :-( ) + This way now there is no longer a difference under execution time between + statically and dynamically linked modules. + [Ralf S. Engelschall] + + *) Fix the generated mod_xxx.c from "apxs -g -f xxx" after the + Big Symbol Renaming. [Ralf S. Engelschall] + + *) Add a comment to mod_example.c showing the format of a FLAG command + handler. [Ken Coar] + + *) Standardized the time format in mod_status to match that of other + places in the code (e.g. DATE_GMT). PR#1551 + + *) Fix handling of %Z in timefmt strings for those platforms with no time + zone information in their tm struct. [Paul Eggert ] + PR#754 + + *) Makes mod_rewrite, mod_log_config, mod_status and the ServerSignature + feature compatible with 'UseCanonicalName off' by changing + r->server->server_hostname to ap_get_server_name(). And I changed some + functions which use r->server->port to use ap_get_server_port() instead, + because if there's no Port directive in the config r->server->port is 0. + [Lars Eilebrecht] + + *) get/set_module_config are trivial enough to be better off inline. Worth + 1.5% performance boost. [Dean Gaudet] + + *) Fix off-by-one error in ap_proxy_date_canon() in proxy_util.c + when ensuring 'x' is at least 30-chars big. [Jim Jagielski, + Brian Behlendorf] + + *) [BS2000 security] BS2000 needs an extra authentication to initialize + the task environment to the unprivileged User id. Otherwise CGI scripts + would have a way to gain super user access. [Martin Kraemer] + + *) Fix debug log messages for BS2000/OSD: instead of logging the whole + absolute path, only log base name of logging source as is done + in unix. [Martin Kraemer] + + *) Ronald Tschalaer's Accept-Encoding patch - preserve the "x-" in + the encoding type from the Accept-Encoding header (if it's there) + and use it in the response, as that's probably what it'll be expecting. + [] + + *) Fix to mod_alias: translate_alias_redir is dealing with + a URI, not a filename, so the check for drive letters for win32 + and emx is not necessary. [Dean Gaudet] + + *) WIN32: Allow .cmd as an executable extension. + [Kari Likovuori ] PR#2146 + + *) Make Apache header files, and some variables, C++ friendly. + [Michael Anderson's ] + + *) Child processes can now "signal" (by exiting with a status + of APEXIT_CHILDFATAL) the parent process to abort and + shutdown the server if the error in the child process was + fatal enough. [Jim Jagielski] + + *) mod_autoindex's find_itme() was sensitive to MIME type case. + [Jim Jagielski] PR#2112 + + *) Make sure the referer_log and agent_log entries in the default httpd.conf + file are also adjusted for the actual relative installation paths. + [Ralf S. Engelschall] PR#2175 + + *) WIN32: Extensive overhaul of the way UNCs are handled. [Ben Laurie] + + *) WIN32: Make roots of filesystems (e.g. c:/) work. [Ben Laurie] + PR#1558 + + *) PORT: Various porting changes to support AIX 3.2, 4.1.5, 4.2 and 4.3. + Additionally the checks for finding the vendor DSO library were moved + from mod_so.c to Configure because first it needs $PLAT etc. and second + mod_so already uses an abstraction layer and does not fiddle with the + vendor functions itself. + [Jens-Uwe Mager, Ralf S. Engelschall] + + *) PORT: Some optimization defines for NetBSD + [Jaromir Dolecek ] PR#2165 + + *) PORT: Dynamic Shared Object (DSO) support for NetBSD. + [Jaromir Dolecek , Ralf S. Engelschall] PR#2158 + + *) Add Dynamic Shared Object (DSO) support for AIX (at least 4.2 but older + AIX variants should work fine, too. Even AIX 3.x should work). This is + accomplished by using the free DSO emulation code from Jens-Uwe Mager + which we put into a os/unix/os-dso-aix.c file. + [Ralf S. Engelschall] + + *) PORT: Fix compiler warnings under AIX >= 4.2 where the manual pages imply + that we should use NET_SIZE_T == int but the include files force size_t. + [Ralf S. Engelschall] + + *) Fix two bugs in select() handling in http_main.c. + [Roy Fielding] + + *) Suppress "error(0)" messages for ap_log_error() when the APLOG_NOERRNO + is unset (as it is in situations like timeouts) where it is unclear + whether errno is set or not. [Martin Kraemer] + + *) Just having APACI's localstatedir is too general and not enough for most + of the systems. 1.3b6 again required manual APACI patches by package + maintainers from Red Hat and FreeBSD because for their filesystem layout a + little bit more flexibility in configuring the paths is needed. Hence we + provide three additional configure options (--runtimedir, --logfiledir, + --proxycachedir) which now can be used for more granular adjustments if + --localstatedir is not enough to fit the particular needs. As a nice + side-effect this reduces some subdir fiddling in configure+Makefile.tmpl. + [Ralf S. Engelschall] + + *) Make the install root for "make install" in APACI's Makefile overrideable + by package authors. This way we are even more friendly to package + maintainers (especially Debian and Red Hat) who build for the real prefix + via "configure --prefix=/" but use a different local prefix via + "make root=/tmp/apache install" for rolling the package without bristling + the target location on their system. + [Ralf S. Engelschall] + + *) Workaround sed limitations in APACI's configure script by now + substituting in chunks of 50 commands (because for instance HPUX's vendor + sed has a limit of max. 98 commands) + [Ralf S. Engelschall] PR#2136 + + *) Adding SOCKS5 support and fixing existing SOCKS4 support. + [Ralf S. Engelschall] PR#2140 + + *) Manually fix some symbols which were not renamed to prefix ap_ in the BIG + RENAMING process because they are defined as pre-processor macros instead + of real functions: bputc, bgetc, piped_log_write_fd, piped_log_read_fd + [Ralf S. Engelschall] + + *) Workaround braindead AWK's when generating ap_config.h: The split() and + substr() functions cannot be nested under vendor AWK from Solaris 2.6. + [Ralf S. Engelschall] PR#2139 + + *) Various bugfixes and cleanups for the APACI configure script: + o fix IFS handling for _nested_ situation + o fix Perl interpreter search: take first one found instead of last one + o fix DSO consistency check + o print error messages to stderr instead of stdout + o add install-quiet for --shadow situation to Makefile stub + o reduce complexity by avoiding sed-hacks for rule and module list loops + [Ralf S. Engelschall] + + *) Fix DEBUG_CGI situation in mod_cgi.c [David MacKenzie] PR#2114 + + *) Make sure the input field separator (IFS) shell variable is explicitly + initialized correctly before _every_ `for' loop and also restored after + the loops. [Ralf S. Engelschall] + + *) Make sure that "make install" doesn't overwrite the `mime.types' and + `magic' files from an existing Apache installation. Because people often + customize these for own MIME and content types. + [Ralf S. Engelschall] + + *) PORT: Dynamic Shared Object (DSO) support for OpenBSD 2.x + [Peter Galbavy, Ralf S. Engelschall] PR#2109 + + *) Fix the path to the ScoreBoardFile in the install-config target, too. + [Ralf S. Engelschall] PR#2105 + + *) Let "configure" clear out the users parameters (provided as shell + variables) to avoid side-effects in "src/Configure" when the user + exported them (which is not needed, but some users do it). + [Ralf S. Engelschall] PR#2101 + + *) Provide backward compatibility from some old src/Configuration.tmpl + parameter names to the canonical Autoconf-style shell variable names. For + instance CFLAGS vs. EXTRA_CFLAGS. The EXTRA_xxx variants are accepted now + but a hint message is displayed. [Ralf S. Engelschall] + + *) Make sure that "make install" doesn't overwrite the DocumentRoot and + CGI scripts from an existing Apache installation. + [Ralf S. Engelschall, Jim Jagielski] PR#2084 + + *) Make `configure --compat' more "compatible" by first + let the libexecdir default to EPREFIX/libexec instead of EPREFIX/bin and + second by making sure the "avoid-bristling-suffix" /apache is not + appended to sysconfdir, datadir, localstatedir and includedir when + --compat is used. [Ralf S. Engelschall, Lars Eilebrecht] + + *) NeXT required strdup() in support/logresolve.c + [Francisco Tomei ] PR#2082 + + *) AIX required sys/select.h in support/ab.c + [Jens Schleusener ] PR#2081 + + *) Fix the path to the MimeMagicFile in the install-config target, too. + [Ralf S. Engelschall] PR#2089 + + *) PORT: Added HP-UX 11 patches [Jeff Earickson ] + + *) If you start apache with the -S command line option it will dump + out the parsed vhost settings. This is useful for folks trying + to figure out what is wrong with their vhost configuration. + (Other dumps may be added in the future.) [Dean Gaudet] + + *) Add %pA, %pI, and %pp codes to ap_vformatter (and hence ap_bprintf, + ap_snprintf, and ap_psprintf). See include/ap.h for docs. + [Dean Gaudet] + + *) Because /usr/local/apache is the default prefix the ``configure + --compat'' option no longer has to set prefix, again. This way the + --compat option honors a leading --prefix option. [Lars Eilebrecht] + + *) PORT: Cast the first argument of dlopen() in ap_os_dso_load() + to `char *' under OSF1 and FreeBSD 2.x where it is defined this way + to avoid "discard const" warnings. [Ralf S. Engelschall] + + *) If a specific handler is set for a file yet the request still + ends up being handled by the default handler, log an error + message before handling it. This catches things such as trying + to use SSIs without mod_include enabled. [Marc Slemko] + + *) Fix error logging for the startup case where ap_log_error() still uses + stderr as the target. Now the default log level is honored here, too. + [Ralf S. Engelschall] + + *) PORT: Make sure some AWK's don't fail in src/Configure with "string too + long" errors when generating the MODULES entry for src/Makefile + [Ben Hyde, Ralf S. Engelschall] + + *) Make sure src/Configure doesn't complain about the old directory + /usr/local/etc/httpd/ when APACI is used. [Lars Eilebrecht] + +Changes with Apache 1.3b6 + + *) PORT: Clean up warnings on Ultrix and HPUX. [Ben Hyde] + + *) Adding DSO support for the HP/UX platform by emulating the dlopen-style + interface via the similar but proprietary HP/UX shl_xxx-style system + calls. [Ralf S. Engelschall] + + *) PORT: Updated UnixWare 2.0.x and 2.1.x entries for DSO support and made + APACI Makefile.tmpl "install" target more robust for sensible UnixWare + Make. [Ralf S. Engelschall] + + *) ++++ THE BIG SYMBOL RENAMING ++++ + To avoid symbol clashes with third-party code compiled into the server, + we globally applied the prefix "ap_" to the following classes of + functions: + - Apache provided general functions (e.g., ap_cpystrn) + - Public API functions (e.g., palloc, bgets) + - Private functions which we can't make static (because of + cross-object usage) but should be (e.g., new_connection) + For backward source compatibility a new header file named compat.h was + created which provides defines for the old symbol names and can be used + by third-party module authors. + [The Apache Group] + + *) Added dynamic shared object (DSO) support for SVR4-derivates: The + problem under SVR4 is that there is no command flag to force the linker + to export the global symbols of the httpd executable therewith they are + available to the DSO's. Instead of problematic hacks like creating a + dummy.so file (containing dummy references to all global symbols) the + httpd binary is linked against, we use a clean trick stolen from Perl 5: + Placing the Apache core code itself into a DSO library named libhttpd.so. + This way the global symbols _HAVE_ to be exported and thus are available + to any manually loaded DSO's under runtime. To reduce the impact to the + user to null we go even further and create a stub httpd executable which + automatically keeps track of the DSO library loading itself and thus + hides the complete mechanism from the user. Although the generation of + this DSO library is automatically triggered for platforms which + essentially need it (mostly all SVR4-derivates) it can be also enabled + manually via the Rule SHARED_CORE. This can be interesting in the future + where we perhaps exploit this libhttpd.so mechanism for providing nifty + features like graceful upgrades, or whatever. + [Ralf S. Engelschall, Martin Kraemer] + + *) Build the libraries before building the rest of the tools. [Ben Hyde] + + *) Add "distclean" target to src/-Makefiles to provide "make distclean" also + inside the src subtree (i.e. for non-APACI users). Following GNU Makefile + conventions while "clean" removes only stuff created by "all" targets, + "distclean" additionally removes the stuff from the configuration + process. This way "make distclean" (hence the name) provides a fresh + source tree as it was for distribution. + [Ralf S. Engelschall] + + *) Allow top-level (APACI) Makefile to break on build errors + the same way the src/ subtree Makefiles breaks on them by replacing the + initial APACI sed-subdir-display-kludge with a more clean + variable-passing-solution: variable SDP can optionally hold the subdir + prefix which is consistently used for displaying the subdir movement. + This way even the top-level Makefile can stop correctly on errors as the + user expects. [Ralf S. Engelschall] + + *) Fixed ordering of argument checks for RewriteBase directive. + [Todd Eigenschink ] PR#2045 + + *) Change Win32 IS_MODULE to SHARED_MODULE to match Unix' method of + indicating that a module is being compiled for dynamic loading. Also + remove #define IS_MODULE from modules and add SHARED_MODULE define + to the mak/dsp files. [Alexei Kosut] + + *) Reduce logging level of "normal" warning messages to APLOG_INFO, + since we are now logging APLOG_WARNING by default. [Roy Fielding] + + *) PORT: OS/2 tweak to deal with multiple .exe targets. [Brian Havard] + + *) Add documentation file and src/Configuration.tmpl entry for the + experimental mod_mmap_static module. Because although it is and marked as + an experimental one it is distributed and thus should be documented and + prepared for configuration the same way as all others modules. + [Ralf S. Engelschall] + + *) Add query (-q) option to apxs support tool to be able to manually query + specific settings from apxs. This is needed for instance when you + manually want to access Apache's header files and you need to assemble + the -I option. Now you can do -I`apxs -q INCLUDEDIR`. + [Ralf S. Engelschall] + + *) Now src/Configure uses a fallback strategy for the shared object support + on platforms where no explicit information is available: If a Perl + installation exists we ask it about its shared object support and if it's + the dlopen-style one we shamelessly guess the compiler and linker flags + for creating shared objects from Perls knowledge. Of course, the user is + warning about what we are doing and informed that he should send us + the guessed flags when they work. [Ralf S. Engelschall] + + *) Provide APACI --without-support option to be able to disable the build + and installation of the support tools from the src/support/ area. + Although its useful to have these installed per default we should provide + a way to compile and install without them for backward-compatibility. + [Ralf S. Engelschall] + + *) Add of the new APache eXtenSion (apxs) support tool for building and + installing modules into an _already installed_ Apache package through the + dynamic shared object (DSO) mechanism [mod_so.c]. The trick here is that + this approach actually doesn't need the Apache source tree. The + (APACI-installed) server package is enough, because this now includes the + Apache C header files (PREFIX/include) and the new APXS tool + (SBINDIR/apxs). The intend is to provide a handy tool for third-party + module authors to build their Apache modules _OUTSIDE_ the Apache source + tree while avoiding them to fiddle around with the totally platform + dependend way of compiling DSO files. The tool supports all ranges of + modules, from trivial ones (single mod_foo.c) to complex ones (like PHP3 + which has a mod_php3.c plus a pre-built libmodphp3-so.a) and even can + on-the-fly generate a minimalistic Makefile and sample module for the + first step to provide both a quick success event and to demonstrate the + APXS mechanism to module authors. [Ralf S. Engelschall] + + *) Fix core dumps in use of CONNECT in proxy. + [] PR#1326, #1573, #1942 + + *) Modify the log directives in httpd.conf-dist files to use CustomLog + so that users have examples of how CustomLog can be used. + [Lars Eilebrecht] + + *) Add the new Apache Autoconf-style Interface (APACI) for the top-level of + the Apache distribution tree. Until Apache 1.3 there was no real + out-of-the-box batch-capable build and installation procedure for the + complete Apache package. This is now provided by a top-level "configure" + script and a corresponding top-level "Makefile.tmpl" file. The goal is + to provide a GNU Autoconf-style frontend which is capable to both drive + the old src/Configure stuff in batch and additionally installs the + package with a GNU-conforming directory layout. Any options from the old + configuration scheme are available plus a lot of new options for flexibly + customizing Apache. [Ralf S. Engelschall] + + *) The floating point ap_snprintf code wasn't threadsafe. + Had to remove the HAVE_CVT macro in order to do threadsafe + calling of the ?cvt() floating point routines. [Dean Gaudet] + + *) PORT: Add the SCO_SV port. [Jim Jagielski] PR#1962 + + *) PORT: IRIX needs the -n32 flag iff using the 'cc' compiler + [Jim Jagielski] PR#1901 + + *) BUG: Configure was using TCC and CC inconsistently. Make sure + Configure knows which CC we are using. [Jim Jagielski] + + *) "Options +Includes" wasn't correctly merged if "+IncludesNoExec" + was defined in a parent directory. [Lars Eilebrecht] + + *) API: ap_snprintf() code mutated into ap_vformatter(), which is + a generic printf-style routine that can call arbitrary output + routines. Use this to replace http_bprintf.c. Add new routines + psprintf(), pvsprintf() which allocate the exact amount of memory + required for a string from a pool. Use psprintf() to clean up + various bits of code which used ap_snprintf()/pstrdup(). + [Dean Gaudet] + + *) PORT: HAVE_SNPRINTF doesn't do anything any longer. This is because + ap_snprintf() has different semantics and formatting codes than + snprintf(). [Dean Gaudet] + + *) SIGXCPU and SIGXFSZ are now reset to SIG_DFL at boot-time. This + is necessary on at least Solaris where the /etc/rc?.d scripts + are run with these signals ignored, and "SIG_IGN" settings are + maintained across exec(). + [Rein Tollevik ] PR#2009 + + *) Fix the check for symbolic links in ``RewriteCond ... -l'': stat() was + used instead of lstat() and thus this flag didn't work as expected. + [Rein Tollevik ] PR#2010 + + *) Fix the proxy pass-through feature of mod_rewrite for the case of + existing QUERY_STRING now that mod_proxy was recently changed because of + the new URL parsing stuff. [Ralf S. Engelschall] + + *) A few changes to scoreboard definitions which helps gcc generate + better code. [Dean Gaudet] + + *) ANSI C doesn't guarantee that "int foo : 2" in a structure will + be a signed bitfield. So mark a few bitfields as signed to + ensure correct code. [Dean Gaudet] + + *) The default for HostnameLookups was changed to Off, but there + was a problem and it wasn't taking effect. [Dean Gaudet] + + *) PORT: Clean up undefined signals on some platforms (SCO, BeOS). + [Dean Gaudet] + + *) After a SIGHUP the listening sockets in the parent weren't + properly marked for closure on fork(). + [Jürgen Keil ] PR#2000 + + *) Allow %2F in two situations: 1) it is in the query part of the URI, + therefore not exposed to %2F -> '/' translations and 2) the request + is a proxy request, so we're not dealing with a local resource anyway. + Without this, the proxy would fail to work for any URL's with + %2f in them (occurs quite often in + http://.../cgi-bin/...?http%3A%2F%2F... references) [Martin Kraemer] + + *) Protect against FD_SETSIZE mismatches. [Dean Gaudet] + + *) Make the shared object compilation command more portable by avoiding + the direct combination of `-c' & `-o' which is not honored by some + compilers like UnixWare's cc. [Ralf S. Engelschall] + + *) WIN32: the proxy was creating filenames missing the last four + characters. While this normally doesn't stop anything from + working, it can result in extra collisions. + [Tim Costello ] PR#1890 + + *) Now mod_proxy uses the response string (in addition to the response status + code) from the already used FTP SIZE command to setup the Content-Length + header if available. [Ralf S. Engelschall] PR#1183 + + *) Reanimated the (still undocumented) proxy receive buffer size directive: + Renamed from ReceiveBufferSize to ProxyReceiveBufferSize because the old + name was really too generic, added documentation for this directive to + the mod_proxy.html and corrected the hyperlink to it in the + new_features_1.3.html document. [Ralf S. Engelschall] PR#1348 + + *) Fix a bug in the src/helpers/fp2rp script and make it a little bit + faster [Martin Kraemer] + + *) Make Configure die when you give it an unknown command switch. + [Ben Hyde] + + *) Add five new and fresh manpages for the support programs: dbmmanage.1, + suexec.8, htdigest.1, rotatelogs.8 and logresolve.8. Now all up-to-date + and per default compiled support programs have manual pages - just to + document our stuff a little bit more and to be able to do really + Unix-like installations ;-) [Ralf S. Engelschall] + + *) Major cleanups to the Configure script to make it and its generated + Makefiles again readable and maintainable: add SRCDIR option, removed + INCLUDES_DEPTH[0-2] kludge, cleanup of TARGET option, cleanup of + generated sections, consequently added Makefile headers with inheritance + information, added subdir movement messages for easier following where + the build process currently stays (more verbose then standard Make, less + verbose than GNU make), same style to comments in the Configure script, + added Apache license header, fixed a few bugs, etc. [Ralf S. Engelschall] + + *) Add the new ApacheBench program "ab" to src/support/: This is derived + from the ZeusBench benchmarking program and can be used to determine the + response performance of an Apache installation. This version is + officially licensed with Zeus Technology, Ltd. See the license agreement + statements in <199803171224.NAA24547 en1.engelschall.com> in apache-core. + [Ralf S. Engelschall] + + *) API: Various core functions that are definately not part of the API + have been made static, and a few have been marked API_EXPORT. Still + more have been marked CORE_EXPORT and are not intended for general + use by modules. [Doug MacEachern, Dean Gaudet] + + *) mod_proxy was not clearing the Proxy-Connection header from + requests; now it does. This did not violate any spec, however + causes poor interactions when you are talking to remote proxies. + [Marc Slemko] PR#1741 + + *) Various cleanups to the command line interface and manual pages. + [Ralf S. Engelschall] + + *) cfg_getline() was not properly handling lines that did not end + with a line termination character. [Marc Slemko] PR#1869, 1909 + + *) Performance tweak to mod_log_config. [Dmitry Khrustalev] + + *) Clean up some undocumented behavior of mod_setenvif related to + "merging" two SetEnvIf directives when they match the same header + and regex. Document that mod_setenvif will perform comparisons in + the order they appear in the config file. Optimize mod_setenvif by + doing more work at config time rather than at runtime. + [Dean Gaudet] + + *) src/include/ap_config.h now wraps it's #define's with #ifndef/#endif's + to allow for modules to overrule them and to reduce redefinition + warnings [Jim Jagielski] + + *) [PORT] For A/UX change the OS-#define for -DAUX to -DAUX3. + [Jim Jagielski] + + *) Making the hard-coded cross-module function call mime_find_ct() (from + mod_proxy to mod_mime) obsolete by making sure the API hook for MIME type + checking is really called even for proxy requests except for URLs with + HTTP schemes (because there we can optimize by not running the type + checking hooks due to the fact that the proxy gets the MIME Content-type + from the remote host later). This change cleans up mod_mime by removing + the ugly export kludge, makes the one-liner file mod_mime.h obsolete, and + especially unbundles mod_proxy and mod_mime. This way they both now can + be compiled as shared objects and are no longer tied together. + [Ralf S. Engelschall] + + *) util.c cleanup and speedup. [Dean Gaudet] + + *) API: Clarification, pstrndup() will always copy n bytes of the source + and NUL terminate at the (n+1)st byte. [Dean Gaudet] + + *) Mark module command_rec and handler_rec structures const so that they + end up in the read-only data section (and are friendlier to systems + that don't do optimistic memory allocation on fork()). [Dean Gaudet] + + *) Add check to the "Port" directive to make sure the specified + port is in the appropriate range. [Ben Hyde] + + *) Performance improvements to invoke_handler(). + [Dmitry Khrustalev ] + + *) Added support for building shared objects even for library-style modules + (which are built from more than one object file). This now provides the + ability to build mod_proxy as a shared object module. Additionally + modules like mod_example are now also supported for shared object + building because the generated Makefiles now no longer assume there is at + least one statically linked module. [Ralf S. Engelschall] + + *) API: Clarify usage of content_type, handler, content_encoding, + content_language and content_languages fields in request_rec. They + must always be lowercased; and the strings pointed to shouldn't + be modified (you must copy them to modify them). Fix a few bugs + related to this. [Dean Gaudet] + + *) API: Clarification: except for RAW_ARGS, all command handlers can + treat the char * parameters as permanent, and modifiable. There + is no need to pstrdup() them. Clean up some needless pstrdup(). + [Dean Gaudet] + + *) Now mod_so keeps track of which module shared objects with which names + are loaded and thus avoids multiple loading and unloading and irritating + error_log messages. [Ralf S. Engelschall] + + *) Prior to the existence of mod_setenv it was necessary to tweak the TZ + environment variable in the apache core. But that tweaking interferes + with mod_setenv. So don't tweak if the user has specified an explicit + TZ variable. [Jay Soffian ] PR#1888 + + *) rputs() did not calculate r->sent_bodyct properly. + [Siegmund Stirnweiss ] PR#1900 + + *) The CGI spec says that REMOTE_HOST should be set to the remote hosts's + name, or left unset if this value is unavailable. Apache was setting + it to the IP address when unavailable. + [Tony Finch ] PR#1925 + + *) Various improvements to the configuration and build support for compiling + modules as shared objects. Especially Solaris 2.x, SunOS 4.1, IRIX and + OSF1 support with GCC and vendor compilers was added. This way shared + object support is now provided out-of-the-box for FreeBSD, Linux, + Solaris, SunOS, IRIX and OSF1. In short: On all major platforms! + [Ralf S. Engelschall] + + *) Minor cleanup in http_main -- split QNX and OS2 specific "mmap" + scoreboard code into separate #defines -- USE_POSIX_SCOREBOARD + and USE_OS2_SCOREBOARD. [Dean Gaudet] + + *) Fix one more special locking problem for RewriteMap programs in + mod_rewrite: According to the documentation of flock(), "Locks are on + files, not file descriptors. That is, file descriptors duplicated + through dup(2) or fork(2) do not result in multiple instances of a lock, + but rather multiple references to a single lock. If a process holding a + lock on a file forks and the child explicitly unlocks the file, the + parent will lose its lock.". To overcome this we have to make sure the + RewriteLock file is opened _AFTER_ the childs were spawned which is now + the case by opening it in the child_init instead of the module_init API + hook. [Ralf S. Engelschall] PR#1029 + + *) Change to Location and LocationMatch semantics. LocationMatch no + longer lets a single slash match multiple adjacent slashes in the + URL. This change is for consistency with RewriteRule and + AliasMatch. Multiple slashes have meaning in URLs that they do + not have in (some) filesystems. Location on the other hand can + be considered a shorthand for a more complicated regex, and it + does match multiple slashes with a single slash -- which is + also consistent with the Alias directive. + [Dean Gaudet] related PR#1440 + + *) Fix bug with mod_mime_magic causing certain files, including files + of length 0, to result in no response from the server. + [Dean Gaudet] + + *) The Configure script now generates src/include/ap_config.h which + contains the set of defines used when Apache is compiled on a platform. + This file can then be included by external modules before including + any Apache header files in case they are being built separately from + Apache. Along with this change, a couple of minor changes were + made to make Apache's #defines coexist peacefully with any autoconf + defines an external module might have. [Rasmus Lerdorf] + + *) Fix mod_rewrite for the ugly API case where sections exist + but without any RewriteXXXXX directives. Here mod_rewrite is given no + chance by the API to initialize its per-server configuration and thus + receives the wrong one from the main server. This is now avoided by + remembering the server together with the config structure while + configuring and later assuming there is no config when we see a + difference between the remembered server and the one calling us. + [Ralf S. Engelschall] PR#1790 + + *) Fixed the DBM RewriteMap support for mod_rewrite: First the support now + is automatically disabled under configure time when the dbm_xxx functions + are not available. Second, two heavy source code errors in the DBM + support code were fixed. This makes DBM RewriteMap's usable again after + a long time of brokenness. [Ralf S. Engelschall] PR#1696 + + *) Now all configuration files support Unix-style line-continuation via + the trailing backslash ("\") character. This enables us to write down + complex or just very long directives in a more readable way. The + backslash character has to be really the last character before the + newline and it has not been prefixed by another (escaping) backslash. + [Ralf S. Engelschall] + + *) When using ProxyPass the ?querystring was not passed correctly. + [Joel Truher ] + + *) To deal with modules being compiled and [dynamically] linked + at a different time from the core, the SERVER_VERSION and + SERVER_BUILT symbols have been abstracted through the new + API routines apapi_get_server_version() and apapi_get_server_built(). + [Ken Coar] PR#1448 + + *) WIN32: Preserve trailing slash in canonical path (and hence + in PATH_INFO). [Paul Sutton, Ben Laurie] + + *) PORT: USE_PTHREAD_SERIALIZED_ACCEPT has proven unreliable + depending on the rev of Solaris and what mixture of modules + are in use. So it has been disabled, and Solaris is back to + using USE_FCNTL_SERIALIZED_ACCEPT. Users may experiment with + USE_PTHREAD_SERIALIZED_ACCEPT at their own risk, it may speed + up static content only servers. Or it may fail unpredictably. + [Dean Gaudet] PR#1779, 1854, 1904 + + *) mod_test_util_uri.c created which tests the logic in util_uri.c. + [Dean Gaudet] + + *) API: Rewrite of absoluteURI handling, and in particular how + absoluteURIs match vhosts. Unless a request is a proxy request, a + "http://host" url is treated as if a similar "Host:" header had been + supplied. This change was made to support future HTTP/1.x protocols + which may require clients to send absoluteURIs for all requests. + + In order to achieve this change subtle changes were made to the API. In a + request_rec, r->hostlen has been removed. r->unparsed_uri now exists so + that the unmodified uri can be retrieved easily. r->proxyreq is not set + by the core, modules must set it during the post_read_request or + translate_names phase. + + Plus changes to the virtualhost test suite for absoluteURI testing. + + This fixes several bugs with the proxy proxying requests to vhosts + managed by the same httpd. + [Dean Gaudet] + + *) API: Cleanup of code in http_vhost.c, and remove vhost matching + code from mod_rewrite. The vhost matching is now performed by a + globally available function matches_request_vhost(). [Dean Gaudet] + + *) Reduce memory usage, and speed up ServerAlias support. As a + side-effect users can list multiple ServerAlias directives + and they're all considered. + [Chia-liang Kao ] PR#1531 + + *) The "poly" directive in image maps did not include the borders of the + polygon, whereas the "rect" directive does. Fix this inconsistency. + [Konstantin Morshnev ] PR#1771 + + *) Make \\ behave as expected. [] + + *) Add the `%a' construct to LogFormat and CustomLog to log the client IP + address. [Todd Eigenschink ] PR#1885 + + *) API: A new source module main/util_uri.c; It contains a routine + parse_uri_components() and friends which breaks a URI into its component + parts. These parts are stored in a uri_components structure called + parsed_uri within each request_rec, and are available to all modules. + Additionally, an unparse routine is supplied which re-assembles the URI + components back to an URI, optionally hiding the username:password@ part + from ftp proxy requests, and other useful routines. Within the structure, + you find on a ready-for-use basis: + scheme; /* scheme ("http"/"ftp"/...) */ + hostinfo; /* combined [user[:password]@]host[:port] */ + user; /* user name, as in http://user:passwd@host:port/ */ + password; /* password, as in http://user:passwd@host:port/ */ + hostname; /* hostname from URI (or from Host: header) */ + port_str; /* port string (integer representation is in "port") */ + path; /* the request path (or "/" if only scheme://host was given) */ + query; /* Everything after a '?' in the path, if present */ + fragment; /* Trailing "#fragment" string, if present */ + This is meant to serve as the platform for *BIG* savings in + code complexity for the proxy module (and maybe the vhost logic). + [Martin Kraemer] + + *) Make all possible meta-construct expansions ($N, %N, %{NAME} and + ${map:key}) available for all location where a string is created in + mod_rewrite rewriting rulesets: 1st arg of RewriteCond, 2nd arg of + RewriteRule and for the [E=NAME:STRING] flag of RewriteRule. This way the + possible expansions are consequently usable at all string creation + locations. [Ralf S. Engelschall] + + *) Fix initialization of RewriteLogLevel (default now is 0 as documented + and not 1) and the per-virtual-server merging of directives. Now all + directives except `RewriteEngine' and `RewriteOption' are either + completely overridden (default) or completely inherited (when + `RewriteOptions inherit') is used. [Ralf S. Engelschall] PR#1325 + + *) Fix `RewriteMap' program lookup in situations where such maps are + defined but disabled (`RewriteEngine off') in per-server context. + [Ralf S. Engelschall] PR#1431 + + *) Fix bug introduced in 1.3b4-dev, config with no Port setting would cause + server to bind to port 0 rather than 80. [Dean Gaudet] + + *) Fix long-standing problem with RewriteMap _programs_ under Unix derivates + (like SunOS and FreeBSD) which don't accept the locking of pipes + directly. A new directive RewriteLock is introduced which can be used to + setup a separate locking file which then is used for synchronization. + [Ralf S. Engelschall] PR#1029 + + *) WIN32: The server root is obtained from the registry key + HKLM\SOFTWARE\Apache Group\Apache\ (version is currently + "1.3 beta"), unless overridden by the -d command line flag. The + value is stored by running "apache -i -d serverroot". [Paul Sutton] + + *) Merged os/win32/mod_dll.c into modules/standard/mod_so.c to support + dynamic loading on Win32 and Unix via the same module. [Paul Sutton] + + *) Now mod_rewrite no longer makes problematic assumptions on the characters + a username can contain when trying to expand it via /etc/passwd. + [Ralf S. Engelschall] + + *) The mod_setenvif BrowserMatch backwards compatibility command did not + work properly with spaces in the regex. [Ronald Tschalaer] PR#1825 + + *) Add new RewriteMap types: First, `rnd' which is equivalent to the `txt' + type but with a special post-processing for the looked-up value: It + parses it into alternatives according to `|' chars and then only one + particular alternative is chosen randomly (this is an essential + functionality needed for balancing between backend-servers when using + Apache as a Reverse Proxy. The looked up value here is a list of + servers). Second, `int' with the built-in maps named `tolower' and + `toupper' which can be used to map URL parts to a fixed case (this is an + essential feature to fix the case of server names when doing mass + virtual-hosting with the help of mod_rewrite instead of using + sections). [Ralf S. Engelschall, parts based on code from + Jay Soffian ] PR#1631 + + *) Add a new directive to mod_proxy similar to ProxyPass: `ProxyPassReverse'. + This directive lets Apache adjust the URL in Location-headers on HTTP + redirect responses sent by the remote server. This way the virtually + mapped area is no longer left on redirects and thus by-passed which is + especially essential when running Apache as a reverse proxy. + [Ralf S. Engelschall] + + *) Hide Proxy-Authorization from CGI/SSI/etc just like Authorization is + hidden. [Alvaro Martinez Echevarria] + + *) Apache will, when started with the -X (single process) debugging flag, + honor the SIGINT or SIGQUIT signals again now. This capability got lost + a while ago during OS/2 signal handling changes. + + *) [PORT] Work around the fact that NeXT runs on more than the + m68k chips in mod_status [Scott Anguish and Timothy Luoma + ] + + *) [PORT] Recognize FreeBSD versions so we can use the OS regex as well + as handling unsigned-chars for FreeBSD v3 and v2 [Andrey Chernov + and Jim] PR#1450 + + *) Use SA_RESETHAND or SA_ONESHOT when installing the coredump handlers. + In particular the handlers could trigger themselves into an infinite + loop if RLimitMem was used with a small amount of memory -- too small + for the signal stack frame to be set up. [Dean Gaudet] + + *) Fix problems with absoluteURIs introduced during 1.3b4. [Dean Gaudet, + Alvaro Martinez Echevarria ] + + *) Fix multiple UserDir problem introduced during 1.3b4-dev. + [Dean Gaudet] PR#1850 + + *) ap_cpystrn() had an off-by-1 error. + [Charles Fu ] PR#1847 + + *) API: As Ken suggested the check_cmd_context() function and related + defines are non-static now so modules can use 'em. [Martin Kraemer] + + *) mod_info would occasionally produce an unpaired in its + output. Fixed. [Martin Kraemer] + + *) By default AIX binds a process (and it's children) to a single + processor. httpd children now unbind themselves from that cpu + and re-bind to one selected at random via bindprocessor() + [Doug MacEachern] + + *) Linux 2.0 and above implement RLIMIT_AS, RLIMIT_DATA has almost no + effect. Work around it by using RLIMIT_AS for the RLimitMEM + directive. [Enrik Berkhan ] PR#1816 + + *) mod_mime_magic error message should indicate the filename when + reads fail. ["M.D.Parker" ] PR#1827 + + *) Previously Apache would permit to end (and + similary for Location and Directory), now this is diagnosed as an + error. Improve error messages for mismatched sections (, + , , , ...). + [Dean Gaudet, Martin Kraemer] + + *) is not permitted within (because of the + semantic ordering). [Dean Gaudet] PR#379 + + *) with wildcards was broken by the change in wildcard + semantics (* does not match /). To fix this, now + apply only to the basename of the request filename. This + fixes some other inconsistencies in semantics + (such as not working). [Dean Gaudet] PR#1817 + + *) Removed bogus "dist.tar" target from Makefile.tmpl and make sure + backup files are removed on "clean" target [Ralf S. Engelschall] + + *) PORT: Add -lm to LIBS for HPUX. [Dean Gaudet] PR#1639 + + *) Various errors from select() and accept() in child_main() would + result in an infinite loop. It seems these two tickle kernel + or library bugs occasionally, and result in log spammage and + a generally bad scene. Now the child exits immediately, + which seems to be a good workaround. + [Dean Gaudet] PR#1747, 1107, 588, 1787, 987, 588 + + *) Cleaned up some race conditions in unix child_main during + initialization. [Dean Gaudet] + + *) SECURITY: "UserDir /abspath" without a * in the path would allow + remote users to access "/~.." and bypass access restrictions + (but note /~../.. was handled properly). + [Lauri Jesmin ] PR#1701 + + *) API: os_is_path_absolute() now takes a const char * instead of a char *. + [Dean Gaudet] + +Changes with Apache 1.3b5 + + *) Source file dependencies in Makefile.tmpl files throughout the + source tree were updated to accurately reflect reality. + [Dean Gaudet] + + *) Preserve the content encoding given by the AddEncoding directive + when the client doesn't otherwise specify an encoding. + [Ronald Tschalaer ] + + *) Sort out problems with canonical filename handling happening too late. + [Dean Gaudet, Ben Laurie] + +Changes with Apache 1.3b4 + + *) The module structure was modified to include a *dynamic_load_handle + in the STANDARD_MODULE_STUFF portion, and the MODULE_MAGIC_NUMBER + has been bumped accordingly. [Paul Sutton] + + *) All BrowserMatch directives mentioned in + htdocs/manual/known_client_problems.html are in the default + configuration files. [Lars Eilebrecht] + + *) MiNT port update. [Jan Paul Schmidt] + + *) HTTP/1.1 requires x-gzip and gzip encodings be treated + equivalent, similarly for x-compress and compress. Apache + now ignores a leading x- when comparing encodings. It also + preserves the encoding the client requests (for example if + it requests x-gzip, then Apache will respond with x-gzip + in the Content-Encoding header). + [Ronald Tschalaer ] PR#1772 + + *) Fix a memory leak on keep-alive connections. [Igor Tatarinov] + + *) Added mod_so module to support dynamic loading of modules on Unix + (like mod_dld for Win32). This replaces mod_dld.c. Use SharedModule + instead of AddModule in Configuration to build shared modules + [Sameer Parekh, Paul Sutton] + + *) Minor cleanups to r->finfo handling in some modules. + [Dean Gaudet] + + *) Abstract read()/write() to ap_read()/ap_write(). + Makes it easier to add other types of IO code such as SFIO. + [Randy Terbush] + + *) API: Generalize default_port manipulations to make support of + different protocols easier. [Ben Laurie, Randy Terbush] + + *) There are many cases where users do not want Apache to form + self-referential urls using the "canonical" ServerName and Port. + The new UseCanonicalName directive (default on), if set to off + will cause Apache to use the client-supplied hostname and port. + API: Part of this change required a change to the construct_url() + prototype; and the addition of get_server_name() and + get_server_port(). + [Michael Douglass , Dean Gaudet] + PR#315, 459, 485, 1433 + + *) Yet another rearrangement of the source tree.. now all the common + header files are in the src/include directory. The -Imain -Iap + references in Makefiles have been changed to the simpler -Iinclude + instead. In addition to simplifying the build a little bit, this + also makes it clear when a module is referencing something in a + other than kosher manner (e.g., the proxy including mod_mime.h). + Module-private header files (the proxy, mod_mime, the regex library, + and mod_rewrite) have not been moved to src/include; nor have + the OS-abstraction files. [Ken Coar] + + *) Fix a bug where r->hostname didn't have the :port stripped + from it. [Dean Gaudet] + + *) Tweaked the headers_out table size, and the subprocess_env + table size guess in rename_original_environment(). Added + MAKE_TABLE_PROFILE which can help discover make_table() + calls that use too small an initial guess, see alloc.c. + [Dean Gaudet] + + *) Options and AllowOverride weren't properly merging in the main + server setting inside vhosts (only an issue when you have no + or other section containing an Options that affects + a request). Options +foo or -foo in the main_server wouldn't + affect the main_server's lookup defaults. [Dean Gaudet] + + *) Variable 'cwd' was being used pointlessly before being set. + [Ken Coar] PR#1738 + + *) r->allowed handling cleaned up in the standard modules. + [Dean Gaudet] + + *) Some case-sensitivity issues cleaned up to be consistent with + RFC2068. [Dean Gaudet] + + *) SIGURG doesn't exist everywhere. + [Mark Andrew Heinrich ] + + *) mod_unique_id was erroneously generating a second unique id when + an internal redirect occured. Such redirects occur, for example, + when processing a DirectoryIndex match. [Dean Gaudet] + + *) API: table_add, table_merge, and table_set include implicit pstrdup() + of the key and value. But in many cases this is not required + because the key/value is a constant, or the value has been built + by pstrcat() or other similar means. New routines table_addn, + table_mergen, and table_setn have been added to the API, these + routines do not pstrdup() their arguments. The core code and + standard modules were changed to take advantage of these routines. + The resulting server is up to 20% faster in some situations. + + Note that it is easy to get code subtly wrong if you pass a key/value + which is in a pool other than the pool of the table. The only + safe thing to do is to pass key/values which are in the pool of + the table, or in one of the ancestors of the pool of the table. + i.e. if the table is part of a subrequest, a value from the main + request's pool is OK since the subrequest pool is a sub_pool of the + main request's pool (and therefore has a lifespan at most as long as + the main pool). There is debugging code which can detect improper + usage, enabled by defining POOL_DEBUG. See alloc.c for more details. + [Dmitry Khrustalev , Dean Gaudet] + + *) More mod_mime_magic cleanup: fewer syscalls; should handle "files" + which don't exist on disk more gracefully; handles vhosts properly. + Update documentation to reflect the code -- if there's no + MimeMagicFile directive then the module is not enabled. + [Dean Gaudet] + + *) PORT: Some older *nix dialects cannot automatically start scripts + which begin with a #! interpreter line (the shell starts the scripts + appropriately on these platforms). Apache now supports starting of + "hashbang-scripts" when the NEED_HASHBANG_EMUL define is set. + [Martin Kraemer, with code from Peter Wemm + taken from tcsh] + + *) API: "typedef array_header table" removed from alloc.h, folks should + have been writing to use table as if it were an opaque type, but even + some standard modules got this wrong. By changing the definition + to "typedef struct table table" module authors will receive compile + time warnings that they're doing the wrong thing. This change + facilitates future changes with more sophisticated table + structures. Specifically, module authors should be using table_elts() + to get access to an array_header * for the table. [Dean Gaudet] + + *) API: Renamed new_connection() to avoid namespace collision with LDAP + library routines. [Ken Coar, Rasmus Lerdorf] + + *) WIN32: mod_speling is now available on the Win32 platform. + [Marc Slemko] + + *) For clarity the following compile time definition was changed: + + SAFE_UNSERIALIZED_ACCEPT -> SINGLE_LISTEN_UNSERIALIZED_ACCEPT + + Also, for example, HAVE_MMAP would mean to use mmap() scoreboards + and not be a general notice that the OS has mmap(). Now the + HAVE_MMAP/SHMGET #defines strictly are informational that the + OS has that method of shared memory; the type to use for + the scoreboard is a seperate #define (USE_MMAP_SCOREBOARD + and USE_SHMGET_SCOREBOARD). This allows outside modules to + determine if shared memory is available and allows Apache + to determine the best method to use for the scoreboard. + [Jim Jagielski] + + *) PORT: UnixWare 2.1.2 SMP appears to require USE_FCNTL_SERIALIZED_ACCEPT, + as do various earlier versions. It should be safe on all versions. + Unixware 1.x appears to have the same SIGHUP bug as solaris does with + the slack code. A few other cleanups for Unixware. + [Tom Hughes ] PR#1082, PR#1282, PR#1499, PR#1553 + + *) PORT: A/UX can handle single-listen accepts without mutex + locking, so we add SINGLE_LISTEN_UNSERIALIZED_ACCEPT. [Jim Jagielski] + + *) When die() happens we need to eat any request body if one exists. + Otherwise we can't continue with a keepalive session. This shows up + as a POST problem with MSIE 4.0, typically against pages which are + authenticated. [Roy Fielding] PR#1399 + + *) If you define SECURITY_HOLE_PASS_AUTHORIZATION then the Authorization + header will be passed to CGIs. This is generally a security hole, so + it's not a default. [Marc Slemko] PR#549 + + *) Fix Y2K problem with date printing in suexec log. + [Paul Eggert ] PR#1343 + + *) WIN32 deserves a pid file. [Ben Hyde] + + *) suexec errors now include the errno/description. [Marc Slemko] PR#1543 + + *) PORT: OSF/1 now uses USE_FLOCK_SERIALIZED_ACCEPT to solve PR#467. + The choice of flock vs. fcntl was made based on timings which showed that + even on non-NFS, non-exported filesystems fcntl() was an order of + magnitude slower. It also uses SINGLE_LISTEN_UNSERIALIZED_ACCEPT so + that single socket users will see no difference. [Dean Gaudet] PR#467 + + *) "File does not exist" error message was erroneously including the + errno. [Marc Slemko] + + *) Improve the warning message generated when a client drops the + connection (hits stop button, etc.) during a send. [Roy Fielding] + + *) Defining GPROF will disable profiling in the parent and enable it + in the children. If you're profiling under Linux this is pretty much + necessary because SIGPROF is lost across a fork(). [Dean Gaudet] + + *) htdigest and htpasswd needed slight tweaks to work on OS/2 and WIN32. + [Brian Havard] + + *) The NeXT cc (which is gcc hacked up) doesn't appear to support some + gcc functionality. Work around it. + [Keith Severson ] PR#1613 + + *) Some linkers complain when .o files contain no functions. + [Keith Severson ] PR#1614 + + *) Some const declarations in mod_imap.c that were added for debugging + purposes caused some compilers heartburn without adding any + significant value, so they've been removed. [Ken Coar] + + *) The src/main/*.h header files have had #ifndef wrappers added to + insulate them against duplicate calls if they get included through + multiple paths (e.g., in .c files as well as other .h files). + [Ken Coar] + + *) The libap routines now have a header file for their prototypes, + src/ap/ap.h, to ease their use in non-httpd applications. [Ken Coar] + + *) mod_autoindex with a plaintext header file would emit the
+     start-tag before the HTML preamble, rather than after the preamble
+     but before the header file contents.  [John Van Essen ]
+     PR#1667
+
+  *) SECURITY: Fix a possible buffer overflow in logresolve.  This is
+     only an issue on systems without a MAXDNAME define or where
+     the resolver returns domain names longer than MAXDNAME.  [Marc Slemko]
+
+  *) SECURITY: Eliminate possible buffer overflow in cfg_getline, which
+     is used to read various types of files such as htaccess and
+     htpasswd files.  [Marc Slemko]
+
+  *) SECURITY: Ensure that the buffer returned by ht_time is always
+     properly null terminated.  [Marc Slemko]
+
+  *) The "Connection" header could be sent back with multiple "close"
+     tokens.  Not an error, but a waste.
+     [] PR#1683
+
+  *) mod_rewrite's RewriteLog should behave like mod_log_config, it
+     shouldn't force hostname lookups.  [Dean Gaudet] PR#1684
+
+  *) "basic" auth needs a case-insensitive comparison.
+     [] PR#1666
+
+  *) For maximum portability, the environment passed to CGIs should
+     only contain variables whose names match the regex
+     /[a-zA-Z][a-zA-Z0-9_]*/.  This is now enforced by stamping
+     underscores over any character outside the regex.  This
+     affects HTTP_* variables, in a way that should be backward
+     compatible for all the standard headers; and affects variables
+     set with SetEnv/BrowserMatch and similar directives.
+     [Dean Gaudet]
+
+  *) mod_speling returned incorrect HREF's when an ambigous match
+     was found. Noticed by  (Soeren Ziehe)
+     [Soeren Ziehe , Martin Kraemer]
+
+  *) PORT: Apache now compiles & runs on an EBCDIC mainframe
+     (the Siemens BS2000/OSD family) in the POSIX subsystem
+     [Martin Kraemer]
+
+  *) PORT: Fix problem killing children when terminating.  Allow ^C
+     to shut down the server.  [Brian Havard]
+
+  *) pstrdup() is implicit in calls to table_* functions, so there's
+     no need to do it before calling.  Clean up a few cases.
+     [Marc Slemko, Dean Gaudet]
+
+  *) new -C and -c command line arguments
+     usage:
+     -C "directive" : process directive before reading config files
+     -c "directive" : process directive after reading config files
+     example:
+     httpd -C "PerlModule Apache::httpd_conf"
+     [Doug MacEachern, Martin Kraemer]
+
+  *) WIN32: Fix the execution of CGIs that are scripts and called 
+     with path info that does not have an '=' in.
+     (eg. http://server/cgi-bin/printenv?foobar)  
+     [Marc Slemko] PR#1591
+
+  *) WIN32: Fix a call to os_canonical_filename so it doesn't try to 
+     mess with fake filenames.  This fixes proxy caching on 
+     win32. PR#1265
+
+  *) SECURITY: General mod_include cleanup, including fixing several
+     possible buffer overflows and a possible infinite loop.
+     [Dean Gaudet, Marc Slemko]
+
+  *) SECURITY: Numerous changes to mod_imap in a general cleanup
+     including fixing a possible buffer overflow.  [Dean Gaudet]
+
+  *) WIN32: overhaul of multithreading code. Shutdowns are now graceful
+     (connections are not dropped). Code can handle graceful restarts
+     (but there is as yet no way to signal this to Apache). Various
+     other cleanups. [Paul Sutton]
+
+  *) The aplog_error changes specific to 1.3 introduced a buffer
+     overrun in the (now legacy) log_printf function.  Fixed.
+     [Dean Gaudet]
+
+  *) mod_digest didn't properly deal with proxy authentication.  It
+     also lacked a case-insensitive comparision of the "Digest"
+     token.  [Ronald Tschalaer ] PR#1599
+
+  *) A few cleanups in mod_status for efficiency.  [Dean Gaudet]
+
+  *) A few cleanups in mod_info to make it thread-safe, and remove an
+     off-by-5 bug that could hammer \0 on the stack. [Dean Gaudet]
+
+  *) no2slash() was O(n^2) in the length of the input.  Make it O(n).
+     [Dean Gaudet]
+
+  *) API: migration from strncpy() to our "enhanced" version called
+     ap_cpystrn() for performance and functionality reasons.
+     Located in libap.a.  [Jim Jagielski]
+
+  *) table_set() and table_unset() did not deal correctly with
+     multiple occurrences of the same key.
+     [Stephen Scheck , Ben Laurie] PR#1604
+
+  *) The AuthName must now be enclosed in quotes if it is to contain
+     spaces.  [Ken Coar] PR#1195
+
+  *) API: new function: ap_escape_quotes(). [Ken Coar] PR#1195
+
+  *) WIN32: Work around optimiser bug that killed ISAPI in release
+     versions. [Ben Laurie] PR#1533
+
+  *) PORT: Update the MPE port [Mark Bixby, Jim Jagielski]
+
+  *) Interim (slow) fix for p->sub_pool critical sections in
+     alloc.c (affects win32 only).  [Ben Hyde]
+
+  *) non-WIN32 was missing destroy_mutex definition.  [Ben Hyde]
+
+  *) send_fd_length() did not calculate total_bytes_sent properly.
+     [Ben Reser ] PR#1366
+
+  *) The bputc() macro was not properly integrated with the chunking
+     code; in many cases modules using bputc() could cause completely
+     bogus chunked output.  (Typically this will show up as problems
+     with Internet Explorer 4.0 reading a page, but other browsers
+     having no problem.) [Dean Gaudet]
+
+  *) Create LARGE_WRITE_THRESHOLD define which determines how many
+     bytes have to be supplied to bwrite() before it will consider
+     doing a writev() to assemble multiple buffers in one system
+     call.  This is critical for modules such as mod_include,
+     mod_autoindex, mod_php3 which all use bputc()/bputs() of smaller
+     strings in some cases.  The result would be extra effort
+     setting up writev(), and in many cases extra effort building
+     chunks.  The default is 31, it can be overriden at compile
+     time. [Dean Gaudet]
+
+  *) Move the gid switching code into the child so that log files
+     and pid files are opened with the root gid.
+     [Gregory A Lundberg ]
+
+  *) WIN32: Check for binaries by looking for the executable header
+     instead of counting control characters.
+     [Jim Patterson ] PR#1340
+
+  *) ap_snprintf() moved from main/util_snprintf.c to ap/ap_snprintf.c
+     so the functionality is available to applications other than the
+     server itself (like the src/support tools).  [Ken Coar]
+
+  *) ap_slack() moved out of main/util.c into ap/ap_slack.c as part of
+     the libap consolidation work.  [Ken Coar]
+
+  *) ap_snprintf() with a len of 0 behaved like sprintf().  This is not
+     useful, and isn't what the standards require.  Now it returns 0
+     and writes nothing.  [Dean Gaudet]
+
+  *) When an error occurs in fcntl() locking suggest the user look up
+     the docs for LockFile.  [Dean Gaudet]
+
+  *) Eliminate some dead code from writev_it_all().
+     [Igor Tatarinov ]
+
+  *) mod_autoindex had an fread() without checking the result code.
+     It also wouldn't handle "AddIconByType (TXT,/icons/text.gif text/*"
+     (note the missing closing paren) properly.  [Dean Gaudet]
+
+  *) It appears the "257th byte" bug (see
+     htdocs/manual/misc/known_client_problems.html#257th-byte) can happen
+     at the 256th byte as well.  Fixed.  [Dean Gaudet]
+
+  *) PORT: Fix mod_mime_magic under OS/2, no support for block devices.
+     [Brian Havard]
+
+  *) Fix memory corruption caused by allocating auth usernames in the
+     wrong pool.  [Dean Gaudet] PR#1500
+
+  *) Fix an off-by-1, and an unterminated string error in
+     mod_mime_magic.  [Dean Gaudet]
+
+  *) Fix a potential SEGV problem in mod_negotiation when dealing
+     with type-maps.  [Dean Gaudet]
+
+  *) Better glibc support under Linux.  [Dean Gaudet] PR#1542
+
+  *) "RedirectMatch gone /" would cause a SIGSEGV. [Dean Gaudet] PR#1319
+
+  *) WIN32: avoid overflows during file canonicalisations.
+     [] PR#1378
+
+  *) WIN32: set_file_slot() didn't detect absolute paths. [Ben Laurie]
+     PR#1511, 1508
+
+  *) WIN32: mod_status display header didn't match fields. [Ben Laurie]
+
+  *) The pthread_mutex_* functions return an error code, and don't
+     set errno.  [Igor Tatarinov ]
+
+  *) WIN32: Allow spaces to prefix the interpreter in #! lines.
+     [Ben Laurie] PR#1101
+
+  *) WIN32: Cure file leak in CGIs. [Peter Tillemans ] PR#1523
+
+  *) proxy_ftp: the directory listings generated by the proxy ftp module
+     now have a title in which the path components are clickable and allow
+     quick navigation to the clicked-on directory on the currently listed
+     ftp server. This also fixes a bug where the ".." directory links would
+     sometimes refer to the wrong directory.  [Martin Kraemer]
+
+  *) WIN32: Allocate the correct amount of memory for the scoreboard.
+     [Ben Hyde] PR#1387
+
+  *) WIN32: Only lowercase the part of the path that is real. [Ben Laurie]
+     PR#1505
+
+  *) Fix problems with timeouts in inetd mode and -X mode.  [Dean Gaudet]
+
+  *) Fix the spurious "(0)unknown error: mmap_handler: mmap failed"
+     error messages. [Ben Hyde]
+
+Changes with Apache 1.3b3
+
+  *) WIN32: Work around brain-damaged spawn calls that can't deal
+     with spaces and slashes.  [Ben Laurie]
+
+  *) WIN32: Fix the code so CGIs can use socket calls on Windows.  
+     The problem was that certain undocumented environment variables
+     needed for sockets to work under Win32 were not being passed.
+     [Frank Faubert ]
+
+  *) Add a "-V" command line flag to the httpd binary.  This 
+     flag shows some of the defines that Apache was compiled with.
+     It is useful for debugging purposes.  [Martin Kraemer]
+
+  *) Start separating the ap_*() routines into their own library, so they
+     can be used by items in src/support among other things.  
+     [Ken Coar] PR#512, 905, 1252, 1308 
+
+  *) Give a more informative error when no AuthType is set.
+     [Lars Eilebrecht]
+
+  *) Remove strtoul() use from mod_proxy because it isn't available
+     on all platforms.   [Marc Slemko] PR#1214
+
+  *) WIN32: Some Win32 systems terminated all responses after 16 kB. 
+     This turns out to be a bug in Winsock - select() doesn't always 
+     return the correct status.  [Ben Laurie]
+
+  *) Directives owned by http_core can now use the new check_cmd_context()
+     routine to ensure that they're not being used within a container
+     (e.g., ) where they're invalid.  [Martin Kraemer]
+
+  *) PORT: Recent changes made it necessary to add explicit prototype
+     for fgetc() and fgets() on SunOS 4.x.  [Martin Kraemer, Ben Hyde]
+
+  *) It was necessary to distinguish between resources which are
+     allocated in the parent, for cleanup in the parent, and resources
+     which are allocated in each child, for cleanup in each child.
+     A new pool was created which is passed to the module child_init
+     and child_exit functions; modules are free to register per-child
+     cleanups there.  This fixes a bug with reliable piped logs.
+     [Dean Gaudet]
+
+  *) mod_autoindex wasn't displaying the ReadmeName file at the bottom
+     unless it was also doing FancyIndexes, but it displayed the
+     HeaderName file at the top under all circumstances.  It now shows
+     the ReadmeName file for simple indices, too, as it should.  
+     [Ken Coar] PR#1373
+
+  *) http_core was mmap()ing even in cases where it wasn't going to
+     read the file.  [Ben Hyde ]
+
+  *) Complete rewrite ;-) of mod_rewrite's URL rewriting engine:
+     Now the rewriting engine (the heart of mod_rewrite) is organized more
+     straight-forward, first time well documented and reduced to the really
+     essential parts. All redundant cases were stripped off and processing now
+     is the same for both per-server and per-directory context with only a
+     minimum difference (the prefix stripping in per-dir context). As a
+     side-effect some subtle restrictions and two recently discovered problems
+     are gone: Wrong escaping of QUERY_STRING on redirects in per-directory
+     context and restrictions on the substitution URL on redirects.
+     Additionally some minor source cleanups were done. 
+     [Ralf S. Engelschall] 
+
+  *) Lars Eilebrecht wrote a whole new set of Apache Vhost Internals
+     documentation, examples, explanations and caveats. They live in a new
+     subdirectory htdocs/manual/vhost/. [Lars Eilebrecht ]
+
+  *) If ap_slack fails to allocate above the low slack line it's a good
+     indication that further problems will occur; it's a better indication
+     than many external libraries give us when we actually run out of
+     descriptors.  So report it to the user once per restart.
+     [Dean Gaudet] PR#1181
+
+  *) Change mod_include and mod_autoindex to use Y2K-safe date formats
+     by default.  [Ken Coar]
+
+  *) Add a "SuppressColumnSorting" option to the IndexOptions list,
+     which will keep the column heading from being links for sorting
+     the display.  [Ken Coar, suggested by Brian Tiemann ]
+     PR #1261
+
+  *) PORT: Update the LynxOS port.  [Marius Groeger ]
+
+  *) Fix logic error when issuing a mmap() failed message
+     with a non-zero MMAP_THRESHOLD.
+     [David Chambers ] PR#1294
+
+  *) Preserve handler value on ProxyPass'ed requests by not
+     calling find_types on a proxy'd request; fixes problems
+     where some ProxyPass'ed URLs weren't actually passed
+     to the proxy.
+     [Lars Eilebrecht] PR#870
+
+  *) Fix a byte ordering problem in mod_access which prevented
+     the old-style syntax (i.e. "a.b.c." to match a class C)
+     from working properly. [Dean Gaudet] PR#1248, 1328, 1384
+
+  *) Fix problem with USE_FLOCK_SERIALIZED_ACCEPT not working
+     properly. Each child needs to open the lockfile instead
+     of using the passed file-descriptor from the parent. 
+     [Jim Jagielski] PR#1056
+
+  *) Fix the error logging in mod_cgi; the recent error log changes
+     introduced a bug that prevented it from working correctly.
+     [M.D.Parker] PR#1352
+
+  *) Default to USE_FCNTL_SERIALIZED_ACCEPT on HPUX to properly 
+     handle multiple Listen directives.  [Marc Slemko] PR#872
+
+  *) Inherit a bugfix to fnmatch.c from FreeBSD sources.
+     ["[KOI8-R] áÎÄÒÅÊ þÅÒÎÏ×" ] PR#1311
+
+  *) When a configuration parse complained about a bad directive,
+     the logger would use whatever (unrelated) value was in errno.
+     errno is now forced to EINVAL first in this case.  [Ken Coar]
+
+  *) A sed command in the Configure script pushed the edge of POSIXness,
+     breaking on some systems.  [Bhaba R.Misra ] PR#1368
+
+  *) Solaris >= 2.5 was totally broken due to a mess up using pthread
+     mutexes.  [Roy Fielding, Dean Gaudet]
+
+  *) OS/2 Port updated; it should be possible to build OS/2 from the same
+     sources as Unix now.  [Brian Havard ]
+
+  *) Fix a year formatting bug in mod_usertrack.
+     [Paul Eggert ] PR#1342
+
+  *) A mild SIGTERM/SIGALRM race condition was eliminated.
+     [Dean Gaudet] PR#1211
+
+  *) Warn user that default path has changed if /usr/local/etc/httpd
+     is found on the system.  [Lars Eilebrecht]
+
+  *) Various mod_mime_magic bug fixes and cleanups: Uncompression
+     should work, it should work on WIN32, and a few resource
+     leaks and abort conditions are fixed.
+     [Dean Gaudet] PR#1205
+
+  *) PORT: On AIX 1.x files can't be named '@', fix the proxy cache
+     to use '%' instead of '@' in its encodings.
+     [David Schuler ] PR#1317
+
+  *) Improve the warning message generated when the "server is busy".
+     [Dean Gaudet] PR#1293
+
+  *) PORT: All ports which don't otherwise define DEF_WANTHSREGEX will
+     get Spencer regex by default.  This is to avoid having to
+     discover bugs in operating system libraries.  [Dean Gaudet]
+
+  *) PORT: "Fix" PR#467 by generating warnings on systems which we have
+     not been able to get working USE_*_SERIALIZED_ACCEPT settings for.
+     Document this a bit more in src/PORTING.  [Dean Gaudet] PR#467
+
+  *) Ensure that one copy of config warnings makes it to the
+     error_log.  [Dean Gaudet]
+
+  *) Invent new structure and associated methods to handle config file
+     reading. Add "custom" hook to use config file cfg_getline() on
+     something which is not a FILE*  [Martin Kraemer]
+
+  *) Make single-exe Windows install. [Ben Laurie and Eric Esselink]
+
+  *) WIN32: Make CGI work under Win95. [Ben Laurie and Paul Sutton]
+
+  *) WIN32: Make index.html and friends work under Win95. [Ben Laurie]
+
+  *) PORT: Solaris 2.4 needs Spencer regex, the system regex is broken.
+     [John Line ] PR#1321
+
+  *) Default pathname has been changed everywhere to /usr/local/apache
+     [Sameer ]
+
+  *) PORT: AIX now uses USE_FCNTL_SERIALIZED_ACCEPT.
+     [David Bronder ] PR#849
+
+  *) PORT: i386 AIX does not have memmove.
+     [David Schuler ] PR#1267
+
+  *) PORT: HPUX now defaults to using Spencer regex.
+     [Philippe Vanhaesendonck ,
+     Omar Del Rio ] PR#482, 1246
+
+  *) PORT: Some versions of NetBSD don't automatically define
+     __NetBSD__.  Workaround by defining NETBSD.
+     [Chris Craft ] PR#977
+
+  *) PORT: UnixWare 2.x requires -lgen for syslog.
+     [Hans Snijder ] PR#1249
+
+  *) PORT: ULTRIX appears to not have syslog.
+     [Lars Eilebrecht ]
+
+  *) PORT: Basic Gemini port (treat it like unixware212).
+     ["Pavel Yakovlev (Paul McHacker)" ]
+
+  *) PORT: All SVR4 systems now use NET_SIZE_T = size_t, and
+     use USE_SHMGET_SCOREBOARD.
+     [Martin Kraemer]
+
+  *) Various improvements in detecting config file errors (missing closing
+     directives for ,  etc. blocks, prohibiting global
+     server settings in  blocks, flagging unhandled multiple
+     arguments to ,  etc.)
+     [Martin Kraemer]
+
+  *) Add support to suexec wrapper program for mod_unique_id's UNIQUE_ID
+     variable to provide this one to suexec'd CGIs, too.
+     [M.D.Parker ] PR#1284
+
+  *) New support tool: src/support/split-logfile, a sample Perl script which
+     splits up a combined access log into separate files based on the
+     name of the virtual host (listed first in the log records by "%v").
+     [Ken Coar]
+
+Changes with Apache 1.3b2 (there is no 1.3b1)
+
+  *) TestCompile was not passing $LIBS [Dean Gaudet]
+
+  *) Makefile.tmpl was not using $CFLAGS in the link phase. 
+     [Martin Kraemer]
+
+  *) Add debugging code to alloc.c.  Defining ALLOC_DEBUG provides a
+     rudimentary memory debugger which can be used on live servers with
+     low impact -- it sets all allocated and freed memory bytes to 0xa5.
+     Defining ALLOC_USE_MALLOC will cause the alloc code to use malloc()
+     and free() for each object.  This is far more expensive and should
+     only be used for testing with tools such as Electric Fence and
+     Purify.  See main/alloc.c for more details.  [Dean Gaudet]
+
+  *) Configure uses a sh trap and didn't set its exitcode properly.
+     [Dean Gaudet] PR#1159
+
+  *) Yet another vhost revamp.  Add the NameVirtualHost directive which
+     explicitly lists the ip:port pairs that are to be used for name-vhosts.
+     From a given ip:port, regardless what the Host: header is, you can
+     only reach the vhosts defined on that ip:port.  The precedence of
+     vhosts was reversed to match other precedences in the config --
+     the earlier vhosts override the later vhosts.  All vhost matching was
+     moved into http_vhost.[ch].  [Dean Gaudet]
+
+  *) ap_inline can be used to force inlining.  GNUC __attribute__() can
+     be used for whatever reason is appropriate (i.e. format() warnings
+     for printf style functions).  Both are enabled only with
+     gcc >= 2.7.x (so that we have fewer support issues with older
+     versions).  [Dean Gaudet]
+
+  *) Fix support for Proxy Authentication (we were testing the response
+     status too early). [Marc Slemko]
+
+  *) CoreDumpDirectory directive directs where the core file is
+     written when a SIGSEGV, SIGBUS, SIGABORT or SIGABRT are
+     received.  [Marc Slemko, Dean Gaudet]
+
+  *) PORT: Support for Atari MINT.
+     [Jan Paul Schmidt ]
+
+  *) When booting, apache will now detach itself from stdin, stdout,
+     and stderr.  stderr will not be detached until after the config
+     files have been read so you will be able to see initial error
+     messages.  After that all errors are logged in the error_log.
+     This makes it more convenient to start apache via rsh, ssh,
+     or crontabs.  [Dean Gaudet] PR#523
+
+  *) mod_proxy was sending HTTP/1.1 responses to ftp requests by mistake.
+     Also removed the auto-generated link to www.apache.org that was the
+     source of so many misdirected bug reports.  [Roy Fielding, Marc Slemko]
+
+  *) send_fb would not detect aborted connections in some situations.
+     [Dean Gaudet]
+
+  *) mod_include would use uninitialized data when parsing certain
+     expressions involving && and ||. [Brian Slesinsky] PR#1139
+
+  *) mod_imap should only handle GET methods.  [Jay Bloodworth]
+
+  *) suexec.c wouldn't build without -DLOG_EXEC. [Jason A. Dour]
+
+  *) mod_autoindex improperly counted &escapes; as more than one
+     character in the description.  It also improperly truncated
+     descriptions that were exactly the maximum length.
+     [Martin Kraemer]
+
+  *) RedirectMatch was not properly escaping the result (PR#1155).  Also
+     "RedirectMatch /advertiser/(.*) $1" is now permitted.
+     [Dean Gaudet]
+
+  *) mod_include now uses symbolic names to check for request success
+     and return HTTP errors, and correctly handles all types of
+     redirections (previously it only did temporary redirect correctly).
+     [Ken Coar, Roy Fielding]
+
+  *) mod_userdir was modifying r->finfo in cases where it wasn't setting
+     r->filename.  Since those two are meant to be in sync with each other
+     this is a bug.  ["Paul B. Henson" ]
+
+  *) PORT: Support Unisys SVR4, whose uname returns mostly useless data.
+     ["Kaufman, Steven E" ]
+
+  *) Inetd mode (which is buggy) uses timeouts without having setup the
+     jmpbuffer. [Dean Gaudet] PR#1064
+
+  *) Work around problem under Linux where a child will start looping
+     reporting a select error over and over.
+     [Rick Franchuk ] PR#1107, 987, 588
+
+  *) Fixed error in proxy_util.c when looping through multiple host IP
+     addresses. [Lars Eilebrecht] PR#974
+
+  *) If BUFFERED_LOGS is defined then mod_log_config will do atomic
+     buffered writes -- that is, it will buffer up to PIPE_BUF (i.e. 4k)
+     bytes before writing, but it will never split a log entry across a
+     buffer boundary.  [Dean Gaudet]
+
+  *) API: the short_score record has been split into two pieces, one which
+     the parent writes on, and one which the child writes on.  As part of
+     this change the get_scoreboard_info() function was removed, and
+     scoreboard_image was exported.  This change fixes a race condition
+     in file based scoreboard systems, and speeds up changes involving the
+     scoreboard in earlier 1.3 development.  [Dean Gaudet]
+
+  *) API: New register_other_child() API (see http_main.h) which allows
+     modules to register children with the parent for maintenance.  It
+     is disabled by defining NO_OTHER_CHILD.  [Dean Gaudet]
+
+  *) API: New piped_log API (see http_log.h) which implements piped logs,
+     and will use register_other_child to implement reliable piped logs
+     when it is available.  The reliable piped logs part can be disabled
+     by defining NO_RELIABLE_PIPED_LOGS.  At the moment reliable piped
+     logs is only available on Unix. [Dean Gaudet]
+
+  *) API: set_last_modified() broken into set_last_modified(), set_etag(), and
+     meets_conditions().  This allows conditional HTTP selection to be
+     handled separately from the storing of the header fields, and provides
+     the ability for CGIs to set their own ETags for conditional checking.
+     [Ken Coar, Roy Fielding]  PR#895
+
+  *) Changes to mod_log_config to allow naming of format strings.
+     Format nicknames are defined with "LogFormat fmt nickname", and can
+     be used with "LogFormat nickname" and "CustomLog logtarget nickname".
+     [Ken Coar]
+
+  *) New module, "mod_speling", which can help find files even when 
+     the URL is slightly misspelled. [Martin Kraemer, Alexei Kosut]
+
+  *) API: New function child_terminate() triggers the child process to
+     exit, while allowing the child finish what it needs to for the
+     current request first.  
+     [Doug MacEachern, Alexei Kosut]
+
+  *) Windows now defaults to using full status reports with mod_status.
+     [Alexei Kosut] PR #1094
+
+  *) *Really* disable all mod_rewrite operations if the engine is off.
+     Some things (like RewriteMaps) were checked/performed even if they
+     weren't supposed to be.  [Ken Coar] PR #991
+
+  *) Implement a new timer scheme which eliminates the need to call alarm() all
+     the time.  Instead a counter in the scoreboard for each child is used to
+     show when the child has made forward progress.  The parent samples this
+     counter every scoreboard maintenance cycle, and issues SIGALRM if no
+     progress has been made in the timeout period.  This reduces the static
+     request best-case syscall count to 22 from 29.  This scheme is only
+     used by systems with memory-based scoreboards.  [Dean Gaudet]
+
+  *) The proxy now properly handles CONNECT requests which are sent
+     to proxy servers when using ProxyRemote.  [Marc Slemko] PR#1024
+
+  *) A script called apachectl has been added to the support 
+     directory.  This script allows you to do things such as 
+     "apachectl start" and "apachectl restart" from the command
+     line.  [Marc Slemko]
+
+  *) Modules and core routines are now put into libraries, which
+     simplifies the link line tremendously (among other advantages).
+     [Paul Sutton]
+
+  *) Some of the MD5 names defined in Apache have been renamed to have
+     an `ap_' prefix to avoid conflicts with routines supplied by
+     external libraries.  [Ken Coar]
+
+  *) Removal of mod_auth_msql.c from the distribution. There are many
+     other options for databases today. Rather than offer one option,
+     offer none at this time. mod_auth_msql and other SQL database
+     authentication modules can be found at the Apache Module Registry.
+     http://modules.apache.org/ It would be nice to offer a generic
+     mod_auth_sql option in the near future.
+
+  *) PORT: BeOS support added [Alexei Kosut]
+
+  *) Configure no longer accepts the -make option, since it creates
+     Makefile on the fly based on Makefile.tmpl and Configuration.
+
+  *) Apache now gracefully shuts down when it receives a SIGTERM, instead
+     of forcibly killing off all its processes and exiting without
+     cleaning up. [Alexei Kosut]
+
+  *) API: A new field in the request_rec, r->mtime, has been added to
+     avoid gratuitous parsing of date strings.  It is intended to hold
+     the last-modified date of the resource (if applicable).  An
+     update_mtime() routine has also been added to advance it if
+     appropriate.  [Roy Fielding, Ken Coar]
+
+  *) SECURITY: If a htaccess file can not be read due to bad permissions,
+     deny access to the directory with a HTTP_FORBIDDEN.  The previous
+     behavior was to ignore the htaccess file if it could not be read.
+     This change may make some setups with unreadable htaccess files
+     stop working.  [Marc Slemko] PR#817
+
+  *) Add aplog_error() providing a mechanism to define levels of
+     verbosity to the server error logging. This addition also provides
+     the ability to log errors using syslogd. Error logging is configurable
+     on a per-server basis using the LogLevel directive. Conversion
+     of log_*() in progress. [Randy Terbush]
+
+  *) Further enhance aplog_error() to not log filename, line number, and
+     errno information when it isn't applicable. [Ken Coar, Dean Gaudet]
+
+  *) WIN32: Canonicalise filenames under Win32. Short filenames are
+     converted to long ones. Backslashes are converted to forward
+     slashes. Case is converted to lower. Parts of URLs that do not
+     correspond to files are left completely alone. [Ben Laurie]
+
+  *) PORT: 2 new OSs added to the list of ports:
+      Encore's UMAX V: Arieh Markel 
+      Acorn RISCiX: Stephen Borrill 
+
+  *) Add the server version (SERVER_VERSION macro) to the "server
+     configured and running" entry in the error_log.  Also build an
+     object file at link-time that contains the current time
+     (SERVER_BUILT global const char[]), and include that in the
+     message.  [Ken Coar]
+
+  *) Set r->headers_out when sending responses from the proxy.
+     This fixes things such as the logging of headers sent from
+     the proxy.  [Marc Slemko] PR#659
+
+  *) support/httpd_monitor is no longer distributed because the 
+     scoreboard should not be file based if at all possible. Use
+     mod_status to see current server snapshot.
+
+  *) (set_file_slot): New function, allowing auth directives to be
+     independent of the server root, so the server documents can be
+     moved to a different directory or machine more easily.
+     [David J. MacKenzie]
+
+  *) If no TransferLog is given explicitly, decline
+     to log.  This supports coexistence with other logging modules,
+     such as the custom one that UUNET uses. [David J. MacKenzie]
+
+  *) Check for titles in server-parsed HTML files.
+     Ignore leading newlines and returns in titles.  The old behavior
+     of replacing a newline after  with a space causes the
+     title to be misaligned in the listing. [David J. MacKenzie]
+
+  *) Change mod_cern_meta to be configurable on a per-directory basis.
+     [David J. MacKenzie]
+
+  *) Add 'Include' directive to allow inclusion of configuration
+     files within configuration files. [Randy Terbush]
+
+  *) Proxy errors on connect() are logged to the error_log (nothing
+     new); now they include the IP address and port that failed
+     (*that's* new).   [Ken Coar, Marc Slemko] PR#352
+
+  *) Various architectures now define USE_MMAP_FILES which causes
+     the server to use mmap() for static files.  There are two
+     compile-time tunables MMAP_THRESHOLD (minimum number of bytes
+     required to use mmap(), default is 0), and MMAP_SEGMENT_SIZE (maximum
+     number of bytes written in one cycle from a single mmap()d object,
+     default 32768).  [Dean Gaudet]
+
+  *) API: Added post_read_request API phase which is run right after reading
+     the request from a client, or right after an internal redirect.  It is
+     useful for modules setting environment variables that depend only on
+     the headers/contents of the request.  It does not run during subrequests
+     because subrequests inherit pretty much everything from the main
+     request. [Dean Gaudet]
+
+  *) Added mod_unique_id which is used to generate a unique identifier for
+     each hit, available in the environment variable UNIQUE_ID.
+     [Dean Gaudet]
+
+  *) init_modules is now called after the error logs have been opened.  This
+     allows modules to emit information messages into the error logs.
+     [Dean Gaudet]
+
+  *) Fixed proxy-pass-through feature of mod_rewrite; Added error logging
+     information for case where proxy module is not available. [Marc Slemko]
+
+  *) PORT: Apache has need for mutexes to serialize its children around
+     accept.  In prior versions either fcntl file locking or flock file
+     locking were used.  The method is chosen by the definition of
+     USE_xxx_SERIALIZED_ACCEPT in conf.h.  xxx is FCNTL for fcntl(),
+     and FLOCK for flock().  New options have been added:
+        - SYSVSEM to use System V style semaphores
+        - PTHREAD to use POSIX threads (appears to work on Solaris only)
+        - USLOCK to use IRIX uslock
+     Based on timing various techniques, the following changes were made
+     to the defaults:
+        - Linux 2.x uses flock instead of fcntl
+        - Solaris 2.x uses pthreads
+        - IRIX uses SysV semaphores -- however multiprocessor IRIX boxes
+          work far faster if you -DUSE_USLOCK_SERIALIZED_ACCEPT
+     [Dean Gaudet, Pierre-Yves Kerembellec <Pierre-Yves.Kerembellec vtcom.fr>,
+     Martijn Koster <m.koster pobox.com>]
+
+  *) PORT: The semantics of accept/select make it very desirable to use
+     mutexes to serialize accept when multiple Listens are in use.  But
+     in the case where only a single socket is open it is sometimes
+     redundant to serialize accept().  Not all unixes do a good job with
+     potentially dozens of children blocked on accept() on the same
+     socket.  It's now possible to define SINGLE_LISTEN_UNSERIALIZED_ACCEPT and
+     the server will avoid serialization when listening on only one socket,
+     and use serialization when listening on multiple sockets.
+     [Dean Gaudet] PR#467
+
+  *) Configure changes: TestLib replaced by TestCompile, which has
+     some additional capability (such as doing a sanity check of
+     the compiler and flags selected); the version of Solaris is now
+     available via the #define value of SOLARIS2; IRIX n32bit libs
+     now supported and selectable by new Configuration Rule: IRIXN32;
+     We no longer default to -O2 optimization.  [Jim Jagielski]
+
+  *) Updated Configure: Configuration now uses AddModule to specify
+     module source or binary file location, relative to src directory.
+     Modules can be dropped into modules/extra, or in their own 
+     directory, and modules can come with a Makefile or Configure can 
+     create one.  Modules can add compiler or library information to 
+     generated Makefiles. [Paul Sutton]
+
+  *) Source core re-organisation: distributed modules are now in 
+     modules/standard. All other source code is in main. OS-specific
+     code is in os/{unix,emx,win32} directories. [Paul Sutton]
+
+  *) mod_browser has been removed, since it's replaced by mod_setenvif.
+     [Ken Coar]
+
+  *) Fix another long-standing bug in sub_req_lookup_file where it would
+     happily skip past access checks on subdirectories looked up with
+     relative paths.  (It's used by mod_dir, mod_negotiation,
+     and mod_include.) [Dean Gaudet]
+
+  *) directory_walk optimization to reduce an O(N*M) loop to O(N+M) where
+     N is the number of <Directory> sections, and M is the number of
+     components in the filename of an object.
+
+     To achieve this optimization the following config changes were made:
+        - Wildcards (* and ?, not the regex forms) in <Directory>s,
+          <Files>s, and <Location>s now treat a slash as a special
+          character.  For example "/home/*/public_html" previously would
+          match "/home/a/andrew/public_html", now it only matches things
+          like "/home/bob/public_html".  This mimics /bin/sh behaviour.
+        - It's possible now to use [] wildcarding in <Directory>, <Files>
+          or <Location>.
+        - Regex <Directory>s are applied after all non-regex <Directory>s.
+
+    [Dean Gaudet]
+
+  *) Fix a bug introduced in 1.3a1 directory_walk regarding .htaccess files
+     and corrupted paths.  [Dean Gaudet]
+
+  *) Enhanced and cleaned up the URL rewriting engine of mod_rewrite:
+     First the grouped parts of RewriteRule pattern matches (parenthesis!) can
+     be accessed now via backreferences $1..$9 in RewriteConds test-against
+     strings in addition to RewriteRules subst string. Second the grouped
+     parts of RewriteCond pattern matches (parenthesis!) can be accessed now
+     via backreferences %1..%9 both in following RewriteCond test-against
+     strings and RewriteRules subst string. This provides maximum flexibility
+     through the use of backreferences.
+     Additionally the rewriting engine was cleaned up by putting common
+     code to the new expand_backrefs_inbuffer() function. 
+     [Ralf S. Engelschall]
+
+  *) When merging the main server's <Directory> and <Location> sections into
+     a vhost, put the main server's first and the vhost's second.  Otherwise
+     the vhost can't override the main server.  [Dean Gaudet] PR#717
+
+  *) The <Directory> code would merge and re-merge the same section after
+     a match was found, possibly causing problems with some modules.
+     [Dean Gaudet]
+
+  *) ip-based vhosts are stored and queried using a hashing function, which
+     has been shown to improve performance on servers with many ip-vhosts.
+     Some other changes had to be made to accommodate this:
+        - the * address for vhosts now behaves like _default_
+        - the matching process now is:
+            - match an ip-vhost directly via hash (possibly matches main
+              server)
+            - if that fails, just pretend it matched the main server
+            - if so far only the main server has been matched, perform
+              name-based lookups (ServerName, ServerAlias, ServerPath)
+              *only on name-based vhosts*
+            - if they fail, look for _default_ vhosts
+     [Dean Gaudet, Dave Hankins <dhankins sugarat.net>]
+
+  *) dbmmanage overhaul:
+     - merge dbmmanage and dbmmanage.new functionality, remove dbmmanage.new 
+     - tie() to AnyDBM_File which will use one of DB_File, NDBM_File or
+       GDBM_File (-ldb, -lndbm, -lgdbm) (trying each in that order)
+     - provide better seed for rand
+     - prompt for password as per getpass(3) (turn off echo, read from
+       /dev/tty, etc.)
+     - use "newstyle" crypt based on $Config{osname} ($^O)
+     - will not add a user if already in database, use new `update' command
+       instead
+     - added `check' command to check a users' password
+     - added `import' command to convert existing password text-files or 
+       dbm files exported with `view'
+     - more descriptive usage, general cleanup, 'use strict' clean, etc.
+     [Doug MacEachern]
+
+  *) Added psocket() which is a pool form of socket(), various places within
+     the proxy weren't properly blocking alarms while registering the cleanup
+     for its sockets.  bclose() now uses pclose() and pclosesocket().  There
+     was a bug where the client socket was being close()d twice due a still
+     registered cleanup.  [Dean Gaudet]
+
+  *) A few cleanups were made to reduce time(), getpid(), and signal() calls.
+     [Dean Gaudet]
+
+  *) PORT: AIX >= 4.2 requires -lm due to libc changes.
+     [Jason Venner <jason idiom.com>] PR#667
+
+  *) Enable ``=""'' for RewriteCond directives to match against
+     the empty string. This is the preferred way instead of ``^$''.
+     [Ralf S. Engelschall]
+
+  *) Fixed an infinite loop in mod_imap for references above the server root
+     [Dean Gaudet] PR#748
+
+  *) mod_proxy now has a ReceiveBufferSize directive, similar to
+     SendBufferSize, so that the TCP window can be set appropriately
+     for LFNs. [Phillip A. Prindeville]
+
+  *) mod_browser has been replaced by the more general mod_setenvif
+     (courtesy of Paul Sutton).  BrowserMatch* directives are still
+     available, but are now joined by SetEnvIf*, UnSetEnvIf*, and
+     UnSetEnvIfZero directives.  [Ken Coar]
+
+  *) "HostnameLookups double" forces double-reverse DNS to succeed in
+     order for remote_host to be set (for logging, or for the env var
+     REMOTE_HOST).  The old define MAXIMUM_DNS has been deprecated.
+     [Dean Gaudet]
+
+  *) mod_access overhaul:
+     - Now understands network/netmask syntax (i.e.  10.1.0.0/255.255.0.0)
+       and cidr syntax (i.e. 10.1.0.0/16).  PR#762
+     - Critical path was sped up by pre-computing a few things at config time.
+     - The undocumented syntax "allow user-agents" was removed,
+       the replacement is "allow from env=foobar" combined with mod_browser.
+     - When used with hostnames it now forces a double-reverse lookup
+       no matter what the directory settings are.  This double-reverse
+       doesn't affect any of the other routines that use the remote
+       hostname.  In particular it's still passed to CGIs and the log
+       without the double-reverse check.  Related PR#860.
+     [Dean Gaudet]
+
+  *) When a large bwrite() occurs (larger than the internal buffer size),
+     while there is already something in the buffer, apache will combine
+     the large write and the buffer into a single writev().  (This is
+     in anticipation of using mmap() for reading files.)
+     [Dean Gaudet]
+
+  *) In obscure cases where a partial socket write occurred while chunking,
+     Apache would omit the chunk header/footer on the next block.  Cleaned
+     up other bugs/inconsistencies in error conditions in buff.c.  Fixed
+     a bug where a long pause in DNS lookups could cause the last packet
+     of a response to be unduly delayed.  [Roy Fielding, Dean Gaudet]
+
+  *) API: Added child_exit function to module structure.  This is called
+     once per "heavy-weight process" just before a server child exit()'s 
+     e.g. when max_requests_per_child is reached, etc.
+     [Doug MacEachern, Dean Gaudet]
+
+  *) mod_include cleanup showed that handle_else was being used to handle
+     endif.  It didn't cause problems, but it was cleaned up too.
+     [Howard Fear]
+
+  *) mod_cern_meta would attempt to find meta files for the directory itself
+     in some cases, but not in others.  It now avoids it in all cases.
+     [Dean Gaudet]
+
+  *) mod_mime_magic would core dump if there was a decompression error.
+     [Martin Kraemer <Martin.Kraemer mch.sni.de>] PR#904
+
+  *) PORT: some variants of DGUX require -lsocket -lnsl
+     [Alexander L Jones <alex systems-options.co.uk>] PR#732
+
+  *) mod_autoindex now allows sorting of FancyIndexed directory listings
+     by the various fields (name, size, et cetera), either in ascending
+     or descending order.  Just click on the column header.  [Ken Coar]
+
+  *) PORT: Various tweaks to eliminate pointer-int casting warnings on 64-bit
+     CPUs like the Alpha.  Apache still stores ints in pointers, but that's
+     the relatively safe direction.  [Dean Gaudet] PR#344
+
+  *) PORT: QNX mmap() support for faster/more reliable scoreboard handling.
+     [Igor N Kovalenko <infoh mail.wplus.net>] PR#683
+
+  *) child_main avoids an unneeded call to select() when there is only one
+     listening socket.  [Dean Gaudet]
+
+  *) In the event that the server is starved for idle servers it will
+     spawn 1, then 2, then 4, ..., then 32 servers each second,
+     doubling each second.  It'll also give a warning in the errorlog
+     since the most common reason for this is a poor StartServers
+     setting.  The define MAX_SPAWN_RATE can be used to raise/lower
+     the maximum.  [Dean Gaudet]
+
+  *) Apache now provides an effectively unbuffered connection for
+     CGI scripts.  This means that data will be sent to the client
+     as soon as the CGI pauses or stops output; previously, Apache would
+     buffer the output up to a fixed buffer size before sending, which
+     could result in the user viewing an empty page until the CGI finished
+     or output a complete buffer.  It is no longer necessary to use an
+     "nph-" CGI to get unbuffered output.  Given that most CGIs are written
+     in a language that by default does buffering (e.g. perl) this
+     shouldn't have a detrimental effect on performance.
+
+     "nph-" CGIs, which formerly provided a direct socket to the client
+     without any server post-processing, were not fully compatible with
+     HTTP/1.1 or SSL support.  As such they would have had to implement
+     the transport details, such as encryption or chunking, in order
+     to work properly in certain situations.  Now, the only difference
+     between nph and non-nph scripts is "non-parsed headers".
+     [Dean Gaudet, Sameer Parekh, Roy Fielding]
+
+  *) If a BUFF is switched from buffered to unbuffered reading the first
+     bread() will return whatever remained in the buffer prior to the
+     switch. [Dean Gaudet]
+
+Changes with Apache 1.3a1
+
+  *) Added another Configure helper script: TestLib. It determines
+     if a specified library exists.  [Jim Jagielski]
+
+  *) PORT: Allow for use of n32bit libraries under IRIX 6.x
+     [derived from patch from Jeff Hayes <jhayes aw.sgi.com>]
+     PR#721
+
+  *) PORT: Some architectures use size_t for various lengths in network
+     functions such as accept(), and getsockname().  The definition
+     NET_SIZE_T is used to control this. [Dean Gaudet]
+
+  *) PORT: Linux: Attempt to detect glibc based systems and include crypt.h
+     and -lcrypt.  Test for various db libraries (dbm, ndbm, db) when
+     mod_auth_dbm or mod_auth_db are included.  [Dean Gaudet]
+
+  *) PORT: QNX doesn't have initgroups() which support/suexec.c uses.
+     [Igor N Kovalenko <infoh mail.wplus.net>]
+
+  *) "force-response-1.0" now only applies to requests which are HTTP/1.0 to
+     begin with.  "nokeepalive" now works for HTTP/1.1 clients.  Added
+     "downgrade-1.0" which causes Apache to pretend it received a 1.0.
+     [Dean Gaudet] related PR#875
+
+  *) API: Correct child_init() slot declaration from int to void, to
+     match the init() declaration.  Update mod_example to use the new
+     hook.  [Ken Coar]
+
+  *) added transport handle slot (t_handle) to the BUFF structure
+     [Doug MacEachern]
+
+  *) get_client_block() returns wrong length if policy is
+     REQUEST_CHUNKED_DECHUNK.
+     [Kenichi Hori <ken d2.bs1.fc.nec.co.jp>] PR#815
+
+  *) Support the image map format of FrontPage.  For example:
+        rect /url.hrm 10 20 30 40
+     ["Chris O'Byrne" <obyrne iol.ie>] PR#807
+
+  *) PORT: -lresolv and -lsocks were in the wrong order for Solaris.
+     ["Darren O'Shaughnessy" <darren aaii.oz.au>] PR#846
+
+  *) AddModuleInfo directive for mod_info which allows you to annotate
+     the output of mod_info.  ["Lou D. Langholtz" <ldl usi.utah.edu>]
+
+  *) Added NoProxy directive to avoid using ProxyRemote for selected
+     addresses.  Added ProxyDomain directive to cause unqualified
+     names to be qualified by redirection.
+     [Martin Kraemer <Martin.Kraemer mch.sni.de>]
+
+  *) Support Proxy Authentication, and don't pass the Proxy-Authorize
+     header to the remote host in the proxy. [Sameer Parekh and
+     Wallace]
+
+  *) Upgraded mod_rewrite from 3.0.6+ to latest officially available version
+     3.0.9. This upgrade includes: fixed deadlooping on rewriting to same
+     URLs, fixed rewritelog(), fixed forced response code handling on
+     redirects from within .htaccess files, disabled pipe locking under
+     braindead SunOS 4.1.x, allow env variables to be set even on rules with
+     no substitution, bugfixed situations where HostnameLookups is off, made
+     mod_rewrite more thread-safe for NT port and fixed problem when creating
+     an empty query string via "xxx?".
+         This update also removes the copyright of Ralf S. Engelschall,
+     i.e. now mod_rewrite no longer has a shared copyright. Instead is is
+     exclusively copyrighted by the Apache Group now. This happened because
+     the author now has gifted mod_rewrite exclusively to the Apache Group and 
+     no longer maintains an external version.
+     [Ralf S. Engelschall]
+
+  *) API: Added child_init function to module structure.  This is called
+     once per "heavy-weight process" before any requests are handled.
+     See http_config.h for more details.  [Dean Gaudet]
+
+  *) Anonymous_LogEmail was logging on each subrequest.
+     [Dean Gaudet] PR#421, 868
+
+  *) API: Added is_initial_req() which tests if the request being
+     processed is the initial request, or a subrequest.
+     [Doug MacEachern]
+
+  *) Extended SSI (mod_include) now handles additional relops for
+     string comparisons (<, >, <=, and >=).  [Bruno Wolff III] PR#41
+
+  *) Configure fixed to correctly propagate user-selected options and
+     settings (such as CC and OPTIM) to Makefiles other than
+     src/Makefile (notably support/Makefile).  [Ken Coar] PR#666, #834
+
+  *) IndexOptions SuppressHTMLPreamble now causes the actual HTML of
+     directory indices to start with the contents of the HeaderName file
+     if there is one.  If there isn't one, the behaviour is unchanged.
+     [Ken Coar, Roy Fielding, Andrey A. Chernov]
+
+  *) WIN32: Modules can now be dynamically loaded DLLs using the
+     LoadModule/LoadFile directives. Note that module DLLs must be
+     compiled with the multithreaded DLL version of the runtime library.
+     [Alexei Kosut and Ben Laurie]
+
+  *) Automatic indexing removed from mod_dir and placed into mod_autoindex.
+     This allows the admin to completely remove automatic indexing
+     from the server, while still supporting the basic functions of
+     trailing-slash redirects and DirectoryIndex files.  Note that if
+     you're carrying over an old Configuration file and you use directory
+     indexing then you'll want to add:
+
+     Module autoindex_module    mod_autoindex.o
+
+     before mod_dir in your Configuration.  [Dean Gaudet]
+
+  *) popendir/pclosedir created to properly protect directory scanning.
+     [Dean Gaudet] PR#525
+
+  *) AliasMatch, ScriptAliasMatch and RedirectMatch directives added,
+     giving regex support to mod_alias. <DirectoryMatch>, <LocationMatch>
+     and <FilesMatch> sections added to succeed <DirectoryMatch ~>, etc...
+     [Alexei Kosut]
+
+  *) The AccessFileName directive can now take more than one filename.
+     ["Lou D. Langholtz" <ldl usi.utah.edu>]
+
+  *) The new mod_mime_magic can be used to "magically" determine the type
+     of a file if the extension is unknown.  Based on the unix file(1)
+     command.  [Ian Kluft <ikluft cisco.com>]
+
+  *) We now determine and display the time spent processing a
+     request if desired.  [Jim Jagielski]
+
+  *) mod_status: PID field of "dead" child slots no longer displays
+     main httpd process's PID.  [Jim Jagielski]
+
+  *) Makefile.nt added - to build all the bits from the command line:
+        nmake -f Makefile.nt
+         Doesn't yet work properly. [Ben Laurie]
+
+  *) Default text of 404 error is now "Not Found" rather than the
+     potentially misleading "File Not Found".  [Ken Coar]
+
+  *) CONFIG: "HostnameLookups" now defaults to off because it is far better
+     for the net if we require people that actually need this data to
+     enable it.  [Linus Torvalds]
+
+  *) directory_walk() is an expensive function, keep a little more state to
+     avoid needless string counting.  Add two new functions make_dirstr_parent
+     and make_dirstr_prefix which replace all existing uses of make_dirstr.
+     The new functions are a little less general than make_dirstr, but
+     work more efficiently (less memory, less string counting).
+     [Dean Gaudet]
+
+  *) EXTRA_LFLAGS was changed to EXTRA_LDFLAGS (and LFLAGS was changed
+     to LDFLAGS) to avoid complications with lex rules in make files.
+     [Dean Gaudet] PR#372
+
+  *) run_method optimized to avoid needless scanning over NULLs in the
+     module list.  [Dean Gaudet]
+
+  *) Revamp of (unix) scoreboard management code such that it avoids
+     unnecessary traversals of the scoreboard on each hit.  This is
+     particularly important for high volume sites with a large
+     HARD_SERVER_LIMIT.  Some of the previous operations were O(n^2),
+     and are now O(n).  See also SCOREBOARD_MAINTENANCE_INTERVAL in
+     httpd.h. [Dean Gaudet]
+
+  *) In configurations using multiple Listen statements it was possible for
+     busy sockets to starve other sockets of service.  [Dean Gaudet]
+
+  *) Added hook so standalone_main can be replaced at compile time
+     (define STANDALONE_MAIN)
+     [Doug MacEachern]
+
+  *) Lowest-level read/write functions in buff.c will be replaced with
+     the SFIO library calls sfread/sfwrite if B_SFIO is defined at
+     compile time.  The default sfio discipline will behave as apache
+     would without sfio compiled in.
+     [Doug MacEachern]
+
+  *) Enhance UserDir directive (mod_userdir) to accept a list of
+     usernames for the 'disable' keyword, and add 'enable user...' to
+     selectively *en*able userdirs if they're globally disabled.
+     [Ken Coar]
+
+  *) If NETSCAPE_DBM_COMPAT is defined in EXTRA_CFLAGS then Apache
+     will work with Netscape dbm files.  (dbmmanage will probably not
+     work however.) [Alexander Spohr <aspohr netmatic.com>] PR#444
+
+  *) Add a ListenBacklog directive to control the backlog parameter
+     passed to listen().  Also change the default to 511 from 512.
+     [Marc Slemko]
+
+  *) API: A new handler response DONE which informs apache that the
+     request has been handled and it can finish off quickly, similar to
+     how it handles errors. [Rob Hartill]
+
+  *) Turn off chunked encoding after sending terminating chunk/footer
+     so that we can't do it twice by accident. [Roy Fielding]
+
+  *) mod_expire also issues Cache-Control: max-age headers.
+     [Rob Hartill]
+
+  *) API: Added kill_only_once option for free_proc_chain so that it won't
+     aggressively try to kill off specific children.  For fastcgi.
+     [Stanley Gambarin <gambarin OpenMarket.com>]
+
+  *) mod_auth deals with extra ':' delimited fields.  [Marc Slemko]
+
+  *) Added IconHeight and IconWidth to mod_dir's IndexOptions directive.
+     When used together, these cause mod_dir to emit HEIGHT and WIDTH
+     attributes in the FancyIndexing IMG tags.  [Ken Coar]
+
+  *) PORT: Sequent and SONY NEWS-OS support added.  [Jim Jagielski]
+
+  *) PORT: Added Windows NT support
+     [Ben Laurie and Ambarish Malpani <ambarish valicert.com>]
+
+Changes with Apache 1.2.6
+
+  *) mod_include when using XBitHack Full would send ETags in addition to
+     sending Last-Modifieds.  This is incorrect HTTP/1.1 behaviour.
+     [Dean Gaudet] PR#1133
+
+  *) SECURITY: When a client connects to a particular port/addr, and
+     gives a Host: header ensure that the virtual host requested can
+     actually be reached via that port/addr.  [Ed Korthof <ed organic.com>]
+
+  *) Support virtual hosts with wildcard port and/or multiple ports
+     properly.  [Ed Korthof <ed organic.com>]
+
+  *) Fixed some case-sensitivity issues according to RFC2068.
+     [Dean Gaudet]
+
+  *) Set r->allowed properly in mod_asis.c, mod_dir.c, mod_info.c,
+     and mod_include.c.  [Dean Gaudet]
+
+  *) Variable 'cwd' was being used pointlessly before being set.
+     [Ken Coar] PR#1738
+
+  *) SIGURG doesn't exist on all platforms.
+     [Mark Andrew Heinrich <heinrich tinderbox.Stanford.EDU>]
+
+  *) When an error occurs during a POST, or other operation with a
+     request body, the body has to be read from the net before allowing
+     a keepalive session to continue.  [Roy Fielding] PR#1399
+
+  *) When an error occurs in fcntl() locking suggest the user look up
+     the docs for LockFile.  [Dean Gaudet]
+
+  *) table_set() and table_unset() did not deal correctly with
+     multiple occurrences of the same key. [Stephen Scheck
+     <sscheck infonex.net>, Ben Laurie] PR#1604
+
+  *) send_fd_length() did not calculate total_bytes_sent properly in error
+     cases.  [Ben Reser <breser regnow.com>] PR#1366
+
+  *) r->connection->user was allocated in the wrong pool causing corruption
+     in some cases when used with mod_cern_meta.  [Dean Gaudet] PR#1500
+
+  *) mod_proxy was sending HTTP/1.1 responses to ftp requests by mistake.
+     Also removed the auto-generated link to www.apache.org that was the
+     source of so many misdirected bug reports.  [Roy Fielding, Marc Slemko]
+
+  *) Multiple "close" tokens may have been set in the "Connection"
+     header, not an error, but a waste.
+     [<Ronald.Tschalaer psi.ch>] PR#1683
+
+  *) "basic" and "digest" auth tokens should be tested case-insensitive.
+     [<Ronald.Tschalaer psi.ch>] PR#1599, PR#1666
+
+  *) It appears the "257th byte" bug (see
+     htdocs/manual/misc/known_client_problems.html#257th-byte) can happen
+     at the 256th byte as well.  Fixed.  [Dean Gaudet]
+
+  *) mod_rewrite would not handle %3f properly in some situations.
+     [Ralf Engelschall]
+
+  *) Apache could generate improperly chunked HTTP/1.1 responses when
+     the bputc() or rputc() functions were used by modules (such as
+     mod_include).  [Dean Gaudet]
+
+  *) #ifdef wrap a few #defines in httpd.h to make life easier on
+     some ports.  [Ralf Engelschall]
+
+  *) Fix MPE compilation error in mod_usertrack.c.  [Mark Bixby]
+
+  *) Quote CC='$(CC)' to improve recurse make calls.  [Martin Kraemer]
+
+  *) Avoid B_ERROR redeclaration on sysvr4 systems.  [Martin Kraemer]
+
+Changes with Apache 1.2.5
+
+  *) SECURITY: Fix a possible buffer overflow in logresolve.  This is
+     only an issue on systems without a MAXDNAME define or where 
+     the resolver returns domain names longer than MAXDNAME.  [Marc Slemko]
+
+  *) Fix an improper length in an ap_snprintf call in proxy_date_canon().
+     [Marc Slemko]
+
+  *) Fix core dump in the ftp proxy when reading incorrectly formatted
+     directory listings.  [Marc Slemko]
+
+  *) SECURITY: Fix possible minor buffer overflow in the proxy cache.
+     [Marc Slemko]
+
+  *) SECURITY: Eliminate possible buffer overflow in cfg_getline, which
+     is used to read various types of files such as htaccess and 
+     htpasswd files.  [Marc Slemko]
+
+  *) SECURITY: Ensure that the buffer returned by ht_time is always
+     properly null terminated.  [Marc Slemko]
+
+  *) SECURITY: General mod_include cleanup, including fixing several
+     possible buffer overflows and a possible infinite loop.  This cleanup
+     was done against 1.3 code and then backported to 1.2, the result
+     is a large difference (due to indentation cleanup in 1.3 code).
+     Users interested in seeing a smaller set of relevant differences
+     should consider comparing against src/modules/standard/mod_include.c
+     from the 1.3b3 release.  Non-indentation changes to mod_include
+     between 1.2 and 1.3 were minimal.  [Dean Gaudet, Marc Slemko]
+
+  *) SECURITY: Numerous changes to mod_imap in a general cleanup
+     including fixing a possible buffer overflow.  This cleanup also
+     was done with 1.3 code as a basis, see the previous note
+     about mod_include.  [Dean Gaudet]
+
+  *) SECURITY: If a htaccess file can not be read due to bad 
+     permissions, deny access to the directory with a HTTP_FORBIDDEN.  
+     The previous behavior was to ignore the htaccess file if it could not
+     be read.  This change may make some setups with unreadable
+     htaccess files stop working.  PR#817  [Marc Slemko]
+
+  *) SECURITY: no2slash() was O(n^2) in the length of the input.  
+     Make it O(n).  This inefficiency could be used to mount a denial 
+     of service attack against the Apache server.  Thanks to 
+     Michal Zalewski <lcamtuf boss.staszic.waw.pl> for reporting
+     this.  [Dean Gaudet]
+
+  *) mod_include used uninitialized data for some uses of && and ||.
+     [Brian Slesinsky <bslesins wired.com>] PR#1139
+
+  *) mod_imap should decline all non-GET methods.
+     [Jay Bloodworth <jay pathways.sde.state.sc.us>]
+
+  *) suexec.c wouldn't build without -DLOG_EXEC. [Jason A. Dour]
+
+  *) mod_userdir was modifying r->finfo in cases where it wasn't setting
+     r->filename.  Since those two are meant to be in sync with each other
+     this is a bug.  ["Paul B. Henson" <henson intranet.csupomona.edu>]
+
+  *) mod_include did not properly handle all possible redirects from sub-
+     requests.  [Ken Coar]
+
+  *) Inetd mode (which is buggy) uses timeouts without having setup the
+     jmpbuffer. [Dean Gaudet] PR#1064
+
+  *) Work around problem under Linux where a child will start looping
+     reporting a select error over and over.
+     [Rick Franchuk <rickf transpect.net>] PR#1107
+
+Changes with Apache 1.2.4
+
+  *) The ProxyRemote change in 1.2.3 introduced a bug resulting in the proxy
+     always making requests with the full-URI instead of just the URI path.
+     [Marc Slemko, Roy Fielding]
+
+  *) Add -lm for AIX versions >= 4.2 to allow Apache to link properly
+     on this platform.  [Marc Slemko]
+
+Changes with Apache 1.2.3
+
+  *) The request to a remote proxy was mangled if it was generated as the
+     result of a ProxyPass directive. URL schemes other than http:// were not
+     supported when ProxyRemote was used. PR#260, PR#656, PR#699, PR#713,
+     PR#812 [Lars Eilebrecht]
+
+  *) Fixed proxy-pass-through feature of mod_rewrite; Added error logging
+     information for case where proxy module is not available. [Marc Slemko]
+
+  *) Force proxy to always respond as HTTP/1.0, which it was failing to
+     do for errors and cached responses.  [Roy Fielding]
+
+  *) PORT: Improved support for ConvexOS 11.  [Jeff Venters]
+
+Changes with Apache 1.2.2 [not released]
+
+  *) Fixed another long-standing bug in sub_req_lookup_file where it would
+     happily skip past access checks on subdirectories looked up with relative
+     paths.  (It's used by mod_dir, mod_negotiation, and mod_include.)
+     [Dean Gaudet]
+
+  *) Add lockfile name to error message printed out when
+     USE_FLOCK_SERIALIZED_ACCEPT is defined.
+     [Marc Slemko]
+
+  *) Enhanced the chunking and error handling inside the buffer functions.
+     [Dean Gaudet, Roy Fielding]
+
+  *) When merging the main server's <Directory> and <Location> sections into
+     a vhost, put the main server's first and the vhost's second.  Otherwise
+     the vhost can't override the main server.  [Dean Gaudet] PR#717
+
+  *) The <Directory> code would merge and re-merge the same section after
+     a match was found, possibly causing problems with some modules.
+     [Dean Gaudet]
+
+  *) Fixed an infinite loop in mod_imap for references above the server root.
+     [Dean Gaudet] PR#748
+
+  *) mod_include cleanup showed that handle_else was being used to handle
+     endif.  It didn't cause problems, but it was cleaned up too.
+     [Howard Fear]
+
+  *) Last official synchronization of mod_rewrite with author version (because
+     mod_rewrite is now directly developed by the author at the Apache Group):
+     o added diff between mod_rewrite 3.0.6+ and 3.0.9
+       minus WIN32/NT stuff, but plus copyright removement.
+       In detail:
+       - workaround for detecting infinite rewriting loops
+       - fixed setting of env vars when "-" is used as subst string
+       - fixed forced response code on redirects (PR#777)
+       - fixed cases where r->args is ""
+       - kludge to disable locking on pipes under braindead SunOS
+       - fix for rewritelog in cases where remote hostname is unknown
+       - fixed totally damaged request_rec walk-back loop
+     o remove static from local data and add static to global ones.
+     o replaced ugly proxy finding stuff by simple
+       find_linked_module("mod_proxy") call.
+     o added missing negation char on rewritelog()
+     o fixed a few comment typos
+     [Ralf S. Engelschall]
+
+  *) Anonymous_LogEmail was logging on each subrequest.
+     [Dean Gaudet] PR#421, PR#868
+
+  *) "force-response-1.0" now only applies to requests which are HTTP/1.0 to
+     begin with.  "nokeepalive" now works for HTTP/1.1 clients.  Added
+     "downgrade-1.0" which causes Apache to pretend it received a 1.0.
+     Additionally mod_browser now triggers during translate_name to workaround
+     a deficiency in the header_parse phase.
+     [Dean Gaudet] PR#875
+
+  *) get_client_block() returns wrong length if policy is 
+     REQUEST_CHUNKED_DECHUNK.
+     [Kenichi Hori <ken d2.bs1.fc.nec.co.jp>] PR#815
+
+  *) Properly treat <files> container like other containers in mod_info.
+     [Marc Slemko] PR#848
+
+  *) The proxy didn't treat the "Host:" keyword of the host header as case-
+     insensitive.  The proxy would corrupt the first line of a response from
+     an HTTP/0.9 server.  [Kenichi Hori <ken d2.bs1.fc.nec.co.jp>] PR#813,814
+
+  *) mod_include would log some bogus values occasionally.
+     [Skip Montanaro <skip calendar.com>, Marc Slemko] PR#797
+
+  *) PORT: The slack fd changes in 1.2.1 introduced a problem with SIGHUP
+     under Solaris 2.x (up through 2.5.1).  It has been fixed.
+     [Dean Gaudet] PR#832
+
+  *) API: In HTTP/1.1, whether or not a request message contains a body
+     is independent of the request method and based solely on the presence
+     of a Content-Length or Transfer-Encoding.  Therefore, our default
+     handlers need to be prepared to read a body even if they don't know
+     what to do with it; otherwise, the body would be mistaken for the
+     next request on a persistent connection.  discard_request_body()
+     has been added to take care of that.  [Roy Fielding] PR#378
+
+  *) API: Symbol APACHE_RELEASE provides a numeric form of the Apache
+     release version number, such that it always increases along the
+     same lines as our source code branching.  [Roy Fielding]
+
+  *) Minor oversight on multiple variants fixed.  [Paul Sutton] PR#94
+
+Changes with Apache 1.2.1
+
+  *) SECURITY: Don't serve file system objects unless they are plain files,
+     symlinks, or directories.  This prevents local users from using pipes
+     or named sockets to invoke programs for an extremely crude form of
+     CGI.  [Dean Gaudet]
+
+  *) SECURITY: HeaderName and ReadmeName were settable in .htaccess and
+     could contain "../" allowing a local user to "publish" any file on
+     the system.  No slashes are allowed now.  [Dean Gaudet]
+
+  *) SECURITY: It was possible to violate the symlink Options using mod_dir
+     (headers, readmes, titles), mod_negotiation (type maps), or
+     mod_cern_meta (meta files).  [Dean Gaudet]
+
+  *) SECURITY: Apache will refuse to run as "User root" unless
+     BIG_SECURITY_HOLE is defined at compile time.  [Dean Gaudet]
+
+  *) CONFIG: If a symlink pointed to a directory then it would be disallowed
+     if it contained a .htaccess disallowing symlinks.  This is contrary
+     to the rule that symlink permissions are tested with the symlink
+     options of the parent directory.  [Dean Gaudet] PR#353
+
+  *) CONFIG: The LockFile directive can be used to place the serializing
+     lockfile in any location.  It previously defaulted to /usr/tmp/htlock.
+     [Somehow it took four of us: Randy Terbush, Jim Jagielski, Dean Gaudet,
+     Marc Slemko]
+
+  *) Request processing now retains state of whether or not the request
+     body has been read, so that internal redirects and subrequests will
+     not try to read it twice (and block). [Roy Fielding]
+
+  *) Add a placeholder in modules/Makefile to avoid errors with certain
+     makes. [Marc Slemko]
+
+  *) QUERY_STRING was unescaped in mod_include, it shouldn't be.
+     [Dean Gaudet] PR#644
+
+  *) mod_include was not properly changing the current directory.
+     [Marc Slemko] PR#742
+
+  *) Attempt to work around problems with third party libraries that do not
+     handle high numbered descriptors (examples include bind, and
+     solaris libc).  On all systems apache attempts to keep all permanent
+     descriptors above 15 (called the low slack line).  Solaris users
+     can also benefit from adding -DHIGH_SLACK_LINE=256 to EXTRA_CFLAGS
+     which keeps all non-FILE * descriptors above 255.  On all systems
+     this should make supporting large numbers of vhosts with many open
+     log files more feasible.  If this causes trouble please report it,
+     you can disable this workaround by adding -DNO_SLACK to EXTRA_CFLAGS.
+     [Dean Gaudet] various PRs
+
+  *) Related to the last entry, network sockets are now opened before
+     log files are opened.  The only known case where this can cause
+     problems is under Solaris with many virtualhosts and many Listen
+     directives.  But using -DHIGH_SLACK_LINE=256 described above will
+     work around this problem.  [Dean Gaudet]
+
+  *) USE_FLOCK_SERIALIZED_ACCEPT is now default for FreeBSD, A/UX, and
+     SunOS 4.
+
+  *) Improved unix error response logging.  [Marc Slemko]
+
+  *) Update mod_rewrite from 3.0.5 to 3.0.6.  New ruleflag
+     QSA=query_string_append.  Also fixed a nasty bug in per-dir context:
+     when a URL http://... was used in conjunction with a special
+     redirect flag, e.g. R=permanent, the permanent status was lost.
+     [Ronald Tschalaer <Ronald.Tschalaer psi.ch>, Ralf S. Engelschall]
+
+  *) If an object has multiple variants that are otherwise equal Apache
+     would prefer the last listed variant rather than the first.
+     [Paul Sutton] PR#94
+
+  *) "make clean" at the top level now removes *.o.  [Dean Gaudet] PR#752
+
+  *) mod_status dumps core in inetd mode.  [Marc Slemko and Roy Fielding]
+     PR#566
+
+  *) pregsub had an off-by-1 in its error checking code. [Alexei Kosut]
+
+  *) PORT: fix rlim_t problems with AIX 4.2. [Marc Slemko] PR#333
+
+  *) PORT: Update UnixWare support for 2.1.2.
+     [Lawrence Rosenman <ler lerctr.org>] PR#511
+
+  *) PORT: NonStop-UX [Joachim Schmitz <schmitz_joachim tandem.com>] PR#327
+
+  *) PORT: Update ConvexOS support for 11.5.
+     [David DeSimone <fox convex.com>] PR#399
+
+  *) PORT: Support for DEC cc compiler under ULTRIX.
+     ["P. Alejandro Lopez-Valencia" <alejolo ideam.gov.co>] PR#388
+
+  *) PORT: Support for Maxion/OS SVR4.2 Real Time Unix. [no name given] PR#383
+
+  *) PORT: Workaround for AIX 3.x compiler bug in http_bprintf.c.  
+     [Marc Slemko] PR#725
+
+  *) PORT: fix problem compiling http_bprintf.c with gcc under SCO
+     [Marc Slemko] PR#695
+
+Changes with Apache 1.2
+
+Changes with Apache 1.2b11
+
+  *) Fixed open timestamp fd in proxy_cache.c [Chuck Murcko]
+
+  *) Added undocumented perl SSI mechanism for -DUSE_PERL_SSI and mod_perl.
+     [Doug MacEachern, Rob Hartill]
+
+  *) Proxy needs to use hard_timeout instead of soft_timeout when it is
+     reading from one buffer and writing to another, at least until it has
+     a custom timeout handler.  [Roy Fielding and Petr Lampa]
+
+  *) Fixed problem on IRIX with servers hanging in IdentityCheck,
+     apparently due to a mismatch between sigaction and setjmp.
+     [Roy Fielding] PR#502
+
+  *) Log correct status code if we timeout before receiving a request (408)
+     or if we received a request-line that was too long to process (414).
+     [Ed Korthof and Roy Fielding] PR#601
+
+  *) Virtual hosts with the same ServerName, but on different ports, were
+     not being selected properly.  [Ed Korthof]
+
+  *) Added code to return the requested IP address from proxy_host2addr()
+     if gethostbyaddr() fails due to reverse DNS lookup problems. Original
+     change submitted by Jozsef Hollosi <hollosi sbcm.com>.
+     [Chuck Murcko] PR#614
+
+  *) If multiple requests on a single connection are used to retrieve
+     data from different virtual hosts, the virtual host list would be
+     scanned starting with the most recently used VH instead of the first,
+     causing most virtual hosts to be ignored.
+     [Paul Sutton and Martin Mares] PR#610
+
+  *) The OS/2 handling of process group was broken by a porting patch for
+     MPE, so restored prior code for OS/2.  [Roy Fielding and Garey Smiley]
+
+  *) Inherit virtual server port from main server if none (or "*") is
+     given for VirtualHost.  [Dean Gaudet] PR#576
+
+  *) If the lookup for a DirectoryIndex name with content negotiation
+     has found matching variants, but none are acceptable, return the
+     negotiation result if there are no more DirectoryIndex names to lookup.
+     [Petr Lampa and Roy Fielding]
+
+  *) If a soft_timeout occurs after keepalive is set, then the main child
+     loop would try to read another request even though the connection
+     has been aborted.  [Roy Fielding]
+
+  *) Configure changes: Allow for whitespace at the start of a
+     Module declaration. Also, be more understanding about the
+     CC=/OPTIM= format in Configuration. Finally, fix compiler
+     flags if using HP-UX's cc compiler. [Jim Jagielski]
+
+  *) Subrequests and internal redirects now inherit the_request from the
+     original request-line. [Roy Fielding]
+
+  *) Test for error conditions before creating output header fields, since
+     we don't want the error message to include those fields.  Likewise,
+     reset the content_language(s) and content_encoding of the response
+     before generating or redirecting to an error message, since the new
+     message will have its own Content-* definitions. [Dean Gaudet]
+
+  *) Restored the semantics of headers_out (headers sent only with 200..299
+     and 304 responses) and err_headers_out (headers sent with all responses).
+     Avoid the overhead of copying tables if err_headers_out is empty
+     (the usual case).  [Roy Fielding]
+
+  *) Fixed a couple places where a check for the default Content-Type was
+     not properly checking both the value configured by the DefaultType
+     directive and the DEFAULT_TYPE symbol in httpd.h.  Changed the value
+     of DEFAULT_TYPE to match the documented default (text/plain).
+     [Dean Gaudet] PR#506
+
+  *) Escape the HTML-sensitive characters in the Request-URI that is
+     output for each child by mod_status. [Dean Gaudet and Ken Coar] PR#501
+
+  *) Properly initialize the flock structures used by the mutex locking
+     around accept() when USE_FCNTL_SERIALIZED_ACCEPT is defined.
+     [Marc Slemko]
+
+  *) The method for determining PATH_INFO has been restored to the pre-1.2b
+     (and NCSA httpd) definition wherein it was the extra path info beyond
+     the CGI script filename.  The environment variable FILEPATH_INFO has
+     been removed, and instead we supply the original REQUEST_URI to any
+     script that wants to be Apache-specific and needs the real URI path.
+     This solves a problem with existing scripts that use extra path info
+     in the ScriptAlias directive to pass options to the CGI script.
+     [Roy Fielding]
+
+  *) The _default_ change in 1.2b10 will change the behaviour on configs
+     that use multiple Listen statements for listening on multiple ports.
+     But that change is necessary to make _default_ consistent with other
+     forms of <VirtualHost>.  It requires such configs to be modified
+     to use <VirtualHost _default_:*>.  The documentation has been
+     updated.  [Dean Gaudet] PR#530
+
+  *) If an ErrorDocument CGI script is used to respond to an error
+     generated by another CGI script which has already read the message
+     body of the request, the server would block trying to read the
+     message body again.  [Rob Hartill]
+
+  *) signal() replacement conflicted with a define on QNX (and potentially
+     other platforms). Fixed. [Ben Laurie] PR#512
+
+Changes with Apache 1.2b10
+
+  *) Allow HTTPD_ROOT, SERVER_CONFIG_FILE, DEFAULT_PATH, and SHELL_PATH
+     to be configured via -D in Configuration.  [Dean Gaudet] PR#449
+
+  *) <VirtualHost _default_:portnum> didn't work properly.  [Dean Gaudet]
+
+  *) Added prototype for mktemp() for SUNOS4 [Marc Slemko]
+
+  *) In mod_proxy.c, check return values for proxy_host2addr() when reading
+     config, in case the hostent struct returned is trash.
+     [Chuck Murcko] PR #491
+
+  *) Fixed the fix in 1.2b9 for parsing URL query info into args for CGI
+     scripts.  [Dean Gaudet, Roy Fielding, Marc Slemko]
+
+Changes with Apache 1.2b9  [never announced]
+
+  *) Reset the MODULE_MAGIC_NUMBER to account for the unsigned port
+     changes and in anticipation of 1.2 final release.  [Roy Fielding]
+
+  *) Fix problem with scripts not receiving a SIGPIPE when client drops
+     the connection (e.g., when user presses Stop).  Apache will now stop
+     trying to send a message body immediately after an error from write.
+     [Roy Fielding and Nathan Kurz] PR#335
+
+  *) Rearrange Configuration.tmpl so that mod_rewrite has higher priority
+     than mod_alias, and mod_alias has higher priority than mod_proxy;
+     rearranged other modules to enhance understanding of their purpose
+     and relative order (and maybe even reduce some overhead).
+     [Roy Fielding and Sameer Parekh]
+
+  *) Fix graceful restart.  Eliminate many signal-related race
+     conditions in both forms of restart, and in SIGTERM.  See
+     htdocs/manual/stopping.html for details on stopping and
+     restarting the parent.  [Dean Gaudet]
+
+  *) Fix memory leaks in mod_rewrite, mod_browser, mod_include.  Tune
+     memory allocator to avoid a behaviour that required extra blocks to
+     be allocated.  [Dean Gaudet]
+
+  *) Allow suexec to access files relative to current directory but not
+     above.  (Excluding leading / or any .. directory.)  [Ken Coar]
+     PR#269, 319, 395
+
+  *) Fix suexec segfault when group doesn't exist. [Gregory Neil Shapiro]
+     PR#367, 368, 354, 453
+
+  *) Fix the above fix: if suexec is enabled, avoid destroying r->url
+     while obtaining the /~user and save the username in a separate data
+     area so that it won't be overwritten by the call to getgrgid(), and
+     fix some misuse of the pool string allocation functions.  Also fixes
+     a general problem with parsing URL query info into args for CGI scripts.
+     [Roy Fielding] PR#339, 367, 354, 453
+
+  *) Fix IRIX warning about bzero undefined. [Marc Slemko]
+
+  *) Fix problem with <Directory proxy:...>. [Martin Kraemer] PR#271
+
+  *) Corrected spelling of "authoritative".  AuthDBAuthoratative became
+     AuthDBAuthoritative. [Marc Slemko] PR#420
+
+  *) MaxClients should be at least 1. [Lars Eilebrecht] PR#375
+
+  *) The default handler now logs invalid methods or URIs (i.e. PUT on an
+     object that can't be PUT, or FOOBAR for some method FOOBAR that
+     apache doesn't know about at all).  Log 404s that occur in mod_include.
+     [Paul Sutton, John Van Essen]
+
+  *) If a soft timeout (or lingerout) occurs while trying to flush a
+     buffer or write inside buff.c or fread'ing from a CGI's output,
+     then the timeout would be ignored. [Roy Fielding] PR#373
+
+  *) Work around a bug in Netscape Navigator versions 2.x, 3.x and 4.0b2's
+     parsing of headers.  If the terminating empty-line CRLF occurs starting
+     at the 256th or 257th byte of output, then Navigator will think a normal
+     image is invalid.  We are guessing that this is because their initial
+     read of a new request uses a 256 byte buffer. We check the bytes written
+     so far and, if we are about to tickle the bug, we instead insert a
+     padding header of eminent bogosity. [Roy Fielding and Dean Gaudet] PR#232
+
+  *) Fixed SIGSEGV problem when a DirectoryIndex file is also the source
+     of an external redirection.  [Roy Fielding and Paul Sutton]
+
+  *) Configure would create a broken Makefile if the configuration file
+     contained a commented-out Rule.  [Roy Fielding]
+
+  *) Promote per_dir_config and subprocess_env from the subrequest to the
+     main request in mod_negotiation.  In particular this fixes a bug
+     where <Files> sections wouldn't properly apply to negotiated content.
+     [Dean Gaudet]
+
+  *) Fix a potential deadlock in mod_cgi script_err handling.
+     [Ralf S. Engelschall]
+
+  *) rotatelogs zero-pads the logfile names to improve alphabetic sorting.
+     [Mitchell Blank Jr]
+
+  *) Updated mod_rewrite to 3.0.4: Fixes HTTP redirects from within
+     .htaccess files because the RewriteBase was not replaced correctly.
+     Updated mod_rewrite to 3.0.5: Fixes problem with rewriting inside
+     <Directory> sections missing a trailing /.  [Ralf S. Engelschall]
+
+  *) Clean up Linux settings in conf.h by detecting 2.x versus 1.x.  For
+     1.x the settings are those of pre-1.2b8.  For 2.x we include
+     USE_SHMGET_SCOREBOARD (scoreboard in shared memory rather than file) and
+     HAVE_SYS_RESOURCE_H (enable the RLimit commands).
+     [Dean Gaudet] PR#336, PR#340
+
+  *) Redirect did not preserve ?query_strings when present in the client's
+     request.  [Dean Gaudet]
+
+  *) Configure was finding non-modules on EXTRA_LIBS. [Frank Cringle] PR#380
+
+  *) Use /bin/sh5 on ULTRIX.  [P. Alejandro Lopez-Valencia] PR#369
+
+  *) Add UnixWare compile/install instructions.  [Chuck Murcko]
+
+  *) Add mod_example (illustration of API techniques).  [Ken Coar]
+
+  *) Add macro for memmove to conf.h for SUNOS4. [Marc Slemko]
+
+  *) Improve handling of directories when filenames have spaces in them.
+     [Chuck Murcko]
+
+  *) For hosts with multiple IP addresses, try all additional addresses if
+     necessary to get a connect. Fail only if hostent address list is
+     exhausted. [Chuck Murcko]
+
+  *) More signed/unsigned port fixes.  [Dean Gaudet]
+
+  *) HARD_SERVER_LIMIT can be defined in the Configuration file now.
+     [Dean Gaudet]
+
+Changes with Apache 1.2b8
+
+  *) suexec.c doesn't close the log file, allowing CGIs to continue writing
+     to it.  [Marc Slemko]
+
+  *) The addition of <Location> and <File> directives made the
+     sub_req_lookup_simple() function bogus, so we now handle
+     the special cases directly.  [Dean Gaudet]
+
+  *) We now try to log where the server is dumping core when a fatal
+     signal is received.  [Ken Coar]
+
+  *) Improved lingering_close by adding a special timeout, removing the
+     spurious log messages, removing the nonblocking settings (they
+     are not needed with the better timeout), and adding commentary
+     about the NO_LINGCLOSE and USE_SO_LINGER issues.  NO_LINGCLOSE is
+     now the default for SunOS4, UnixWare, NeXT, and IRIX.  [Roy Fielding]
+
+  *) Send error messages about setsockopt failures to the server error
+     log instead of stderr.  [Roy Fielding]
+
+  *) Fix loopholes in proxy cache expiry vis a vis alarms. [Brian Moore]
+
+  *) Stopgap solution for CGI 3-second delay with server-side includes: if
+     processing a subrequest, allocate memory from r->main->pool instead
+     of r->pool so that we can avoid waiting for free_proc_chain to cleanup
+     in the middle of an SSI request.  [Dean Gaudet] PR #122
+
+  *) Fixed status of response when POST is received for a nonexistent URL
+     (was sending 405, now 404) and when any method is sent with a
+     full-URI that doesn't match the server and the server is not acting
+     as a proxy (was sending 501, now 403).  [Roy Fielding]
+
+  *) Host port changed to unsigned short. [Ken Coar] PR #276
+
+  *) Fix typo in command definition of AuthAuthoritative. [Ken Coar] PR #246
+
+  *) Defined USE_SHMGET_SCOREBOARD for shared memory on Linux.  [Dean Gaudet]
+
+  *) Report extra info from errno with many errors that cause httpd to exit.
+     spawn_child, popenf, and pclosef now have valid errno returns in the
+     event of an error.  Correct problems where errno was stomped on
+     before being reported.  [Dean Gaudet]
+
+  *) In the proxy, if the cache filesystem was full, garbage_coll() was
+     never called, and thus the filesystem would remain full indefinitely.
+     We now also remove incomplete cache files left if the origin server
+     didn't send a Content-Length header and either the client has aborted
+     transfer or bwrite() to client has failed. [Petr Lampa]
+
+  *) Fixed the handling of module and script-added header fields.
+     Improved the interface for sending header fields and reduced
+     the duplication of code between sending okay responses and errors.
+     We now always send both headers_out and err_headers_out, and
+     ensure that the server-reserved fields are not being overridden,
+     while not overriding those that are not reserved.  [Roy Fielding]
+
+  *) Moved transparent content negotiation fields to err_headers_out
+     to reflect above changes.  [Petr Lampa]
+
+  *) Fixed the determination of whether or not we should make the
+     connection persistent for all of the cases where some other part
+     of the server has already indicated that we should not.  Also
+     improved the ordering of the test so that chunked encoding will
+     be set whenever it is desired instead of only when KeepAlive
+     is enabled. Added persistent connection capability for most error
+     responses (those that do not indicate a bad input stream) when
+     accessed by an HTTP/1.1 client. [Roy Fielding]
+
+  *) Added missing timeouts for sending header fields, error responses,
+     and the last chunk of chunked encoding, each of which could have
+     resulted in a process being stuck in write forever.  Using soft_timeout
+     requires that the sender check for an aborted connection rather than
+     continuing after an EINTR.  Timeouts that used to be initiated before
+     send_http_header (and never killed) are now initiated only within or
+     around the routines that actually do the sending, and not allowed to
+     propagate above the caller.  [Roy Fielding]
+
+  *) mod_auth_anon required an @ or a . in the email address, not both.
+     [Dirk vanGulik]
+
+  *) per_dir_defaults weren't set correctly until directory_walk for
+     name-based vhosts.  This fixes an obscure bug with the wrong config
+     info being used for vhosts that share the same ip as the server.
+     [Dean Gaudet]
+
+  *) Improved generation of modules/Makefile to be more generic for
+     new module directories. [Ken Coar, Chuck Murcko, Roy Fielding]
+
+  *) Generate makefile dependency for Configuration based on the actual
+     name given when running the Configure process.  [Dean Gaudet]
+
+  *) Fixed problem with vhost error log not being set prior to
+     initializing virtual hosts. [Dean Gaudet]
+
+  *) Fixed infinite loop when a trailing slash is included after a type map
+     file URL (extra path info). [Petr Lampa]
+
+  *) Fixed server status updating of per-connection counters. [Roy Fielding]
+
+  *) Add documentation for DNS issues (reliability and security), and try
+     to explain the virtual host matching process.  [Dean Gaudet]
+
+  *) Try to continue gracefully by disabling the vhost if a DNS lookup
+     fails while parsing the configuration file.  [Dean Gaudet]
+
+  *) Improved calls to setsockopt.  [Roy Fielding]
+
+  *) Negotiation changes: Don't output empty content-type in variant list;
+     Output charset in variant list; Return sooner from handle_multi() if
+     no variants found; Add handling of '*' wildcard in Accept-Charset.
+     [Petr Lampa and Paul Sutton]
+
+  *) Fixed overlaying of request/sub-request notes and headers in
+     mod_negotiation.  [Dean Gaudet]
+
+  *) If two variants' charset quality are equal and one is the default
+     charset (iso-8859-1), then prefer the variant that was specifically
+     listed in Accept-Charset instead of the default.  [Petr Lampa]
+
+  *) Memory allocation problem in push_array() -- it would corrupt memory
+     when nalloc==0.  [Kai Risku <krisku tf.hut.fi> and Roy Fielding]
+
+  *) invoke_handler() doesn't handle mime arguments in content-type
+     [Petr Lampa] PR#160
+
+  *) Reduced IdentityCheck timeout to 30 seconds, as per RFC 1413 minimum.
+     [Ken Coar]
+
+  *) Fixed problem with ErrorDocument not working for virtual hosts
+     due to one of the performance changes in 1.2b7. [Dean Gaudet]
+
+  *) Log an error message if we get a request header that is too long,
+     since it may indicate a buffer overflow attack. [Marc Slemko]
+
+  *) Made is_url() allow "[-.+a-zA-Z0-9]+:" as a valid scheme and
+     not reject URLs without a double-slash, as per RFC2068 section 3.2.
+     [Ken Coar] PR #146, #187
+
+  *) Added table entry placeholder for new header_parser callback
+     in all of the distributed modules. [Ken Coar] PR #191
+
+  *) Allow for cgi files without the .EXE extension on them under OS/2.
+     [Garey Smiley] PR #59
+
+  *) Fixed error message when resource is not found and URL contains
+     path info. [Petr Lampa and Dean Gaudet] PR #40
+
+  *) Fixed user and server confusion over what should be a virtual host
+     and what is the main server, resulting in access to something
+     other than the name defined in the virtualhost directive (but
+     with the same IP address) failing. [Dean Gaudet]
+
+  *) Updated mod_rewrite to version 3.0.2, which: fixes compile error on
+     AIX; improves the redirection stuff to enable the users to generally
+     redirect to http, https, gopher and ftp; added TIME variable for
+     RewriteCond which expands to YYYYMMDDHHMMSS strings and added the
+     special patterns >STRING, <STRING and =STRING to RewriteCond, which
+     can be used in conjunction with %{TIME} or other variables to create
+     time-dependent rewriting rules. [Ralf S. Engelschall]
+
+  *) bpushfd() no longer notes cleanups for the file descriptors it is handed.
+     Module authors may need to adjust their code for proper cleanup to take
+     place (that is, call note_cleanups_for_fd()). This change fixes problems
+     with file descriptors being erroneously closed when the proxy module was
+     in use. [Ben Laurie]
+
+  *) Fix bug in suexec reintroduced by changes in 1.2b7 which allows
+     initgroups() to hose the group information needed for later
+     comparisons. [Randy Terbush]
+
+  *) Remove unnecessary call to va_end() in create_argv() which
+     caused a SEGV on some systems.
+
+  *) Use proper MAXHOSTNAMELEN symbol for limiting length of server name.
+     [Dean Gaudet]
+
+  *) Clear memory allocated for listeners. [Randy Terbush]
+
+  *) Improved handling of IP address as a virtualhost address and
+     introduced "_default_" as a synonym for the default vhost config.
+     [Dean Gaudet] PR #212
+
+Changes with Apache 1.2b7
+
+  *) Port to  UXP/DS(V20) [Toshiaki Nomura <nom yk.fujitsu.co.jp>]
+
+  *) unset Content-Length if chunked (RFC-2068) [Petr Lampa]
+
+  *) mod_negotiation fixes [Petr Lampa] PR#157, PR#158, PR#159
+     - replace protocol response numbers with symbols
+     - save variant-list into main request notes
+     - free allocated memory from subrequests
+     - merge notes, headers_out and err_headers_out
+
+  *) changed status check mask in proxy_http.c from "HTTP/#.# ### *" to
+     "HTTP/#.# ###*" to be more lenient about what we accept.
+     [Chuck Murcko]
+
+  *) more proxy FTP bug fixes:
+     - Changed send_dir() to remove user/passwd from displayed URL.
+     - Changed login error messages to be more descriptive.
+     - remove setting of SO_DEBUG socket option
+     - Make ftp_getrc() more lenient about multiline responses,
+       specifically, 230 responses which don't have continuation 230-
+       on each line). These seem to be all NT FTP servers, and while
+       perhaps questionable, they appear to be legal by RFC 959.
+     - Add missing kill_timeout() after transfer to user completes.
+     [Chuck Murcko]
+
+  *) Fixed problem where a busy server could hang when restarting
+     after being sent a SIGHUP due to child processes not exiting.
+     [Marc Slemko]
+
+  *) Modify mod_include escaping so a '\' only signifies an escaped
+     character if the next character is one that needs
+     escaping.  [Ben Laurie]
+
+  *) Eliminated possible infinite loop in mod_imap when relative URLs are
+     used with a 'base' directive that does not have a '/' in it.
+     [Marc Slemko, reported by Onno Witvliet <onno tc.hsa.nl>]
+
+  *) Reduced the default timeout from 1200 seconds to 300, and the
+     one in the sample configfile from 400 to 300.  [Marc Slemko]
+
+  *) Stop vbprintf from crashing if given a NULL string pointer;
+     print (null) instead.  [Ken Coar]
+
+  *) Don't disable Nagle algorithm if system doesn't have TCP_NODELAY.
+     [Marc Slemko and Roy Fielding]
+
+  *) Fixed problem with mod_cgi-generated internal redirects trying to
+     read the request message-body twice. [Archie Cobbs and Roy Fielding]
+
+  *) Reduced timeout on lingering close, removed possibility of a blocked
+     read causing the child to hang, and stopped logging of errors if
+     the socket is not connected (reset by client).  [Roy Fielding]
+
+  *) Rearranged main child loop to remove duplication of code in
+     select/accept and keep-alive requests, fixed several bugs regarding
+     checking scoreboard_image for exit indication and failure to
+     account for all success conditions and trap all error conditions,
+     prevented multiple flushes before closing the socket; close the entire
+     socket buffer instead of just one descriptor, prevent logging of
+     EPROTO and ECONNABORTED on platforms where supported, and generally
+     improved readability.  [Roy Fielding]
+
+  *) Extensive performance improvements. Cleaned up inefficient use of
+     auto initializers, multiple is_matchexp calls on a static string,
+     and excessive merging of response_code_strings. [Dean Gaudet]
+
+  *) Added double-buffering to mod_include to improve performance on
+     server-side includes. [Marc Slemko]
+
+  *) Several fixes for suexec wrapper. [Randy Terbush]
+     - Make wrapper work for files on NFS filesystem.
+     - Fix portability problem of MAXPATHLEN.
+     - Fix array overrun problem in clean_env().
+     - Fix allocation of PATH environment variable
+
+  *) Removed extraneous blank line is description of mod_status chars.
+     [Kurt Kohler]
+
+  *) Logging of errors from the call_exec routine simply went nowhere,
+     since the logfile fd has been closed, so now we send them to stderr.
+     [Harald T. Alvestrand]
+
+  *) Fixed core dump when DocumentRoot is a CGI.
+     [Ben Laurie, reported by <geddis tesserae.com>]
+
+  *) Fixed potential file descriptor leak in mod_asis; updated it and
+     http_core to use pfopen/pfclose instead of fopen/fclose.
+     [Randy Terbush and Roy Fielding]
+
+  *) Fixed handling of unsigned ints in ap_snprintf() on some chips such
+     as the DEC Alpha which is 64-bit but uses 32-bit ints.
+     [Dean Gaudet and Ken Coar]
+
+  *) Return a 302 response code to the client when sending a redirect
+     due to a missing trailing '/' on a directory instead of a 301; now
+     it is cacheable. [Markus Gyger]
+
+  *) Fix condition where, if a bad directive occurs in .htaccess, and
+     sub_request() goes first to this directory, then log_reason() will
+     SIGSEGV because it doesn't have initialized r->per_dir_config.
+     [PR#162 from Petr Lampa, fix by Marc Slemko and Dean Gaudet]
+
+  *) Fix handling of lang_index in is_variant_better().  This was
+     causing problems which resulted in the server sending the
+     wrong language document in some cases. [Petr Lampa]
+
+  *) Remove free() from clean_env() in suexec wrapper. This was nuking
+     the clean environment on some systems.
+
+  *) Tweak byteserving code (e.g. serving PDF files) to work around
+     bugs in Netscape Navigator and Microsoft Internet Explorer.
+     Emit Content-Length header when sending multipart/byteranges.
+     [Alexei Kosut]
+
+  *) Port to HI-UX/WE2. [Nick Maclaren]
+
+  *) Port to HP MPE operating system for HP 3000 machines
+     [Mark Bixby <markb cccd.edu>]
+
+  *) Fixed bug which caused a segmentation fault if only one argument
+     given to RLimit* directives. [Ed Korthof]
+
+  *) Continue persistent connection after 204 or 304 response. [Dean Gaudet]
+
+  *) Improved buffered output to the client by delaying the flush decision
+     until the BUFF code is actually about to read the next request.
+     This fixes a problem introduced in 1.2b5 with clients that send
+     an extra CRLF after a POST request. Also improved chunked output
+     performance by combining writes using writev() and removing as
+     many bflush() calls as possible.  NOTE: Platforms without writev()
+     must add -DNO_WRITEV to the compiler CFLAGS, either in Configuration
+     or Configure, unless we have already done so.  [Dean Gaudet]
+
+  *) Fixed mod_rewrite bug which truncated the rewritten URL [Marc Slemko]
+
+  *) Fixed mod_info output corruption bug introduced by buffer overflow
+     fixes. [Dean Gaudet]
+
+  *) Fixed http_protocol to correctly output all HTTP/1.1 headers, including
+     for the special case of a 304 response.  [Paul Sutton]
+
+  *) Improved handling of TRACE method by bypassing normal method handling
+     and header parsing routines; fixed Allow response to always allow TRACE.
+     [Dean Gaudet]
+
+  *) Fixed compiler warnings in the regex library. [Dean Gaudet]
+
+  *) Cleaned-up some of the generated HTML. [Ken Coar]
+
+Changes with Apache 1.2b6
+
+  *) Allow whitespace in imagemap mapfile coordinates. [Marc Slemko]
+
+  *) Fix typo introduced in fix for potential infinite loop around
+     accept() in child_main(). This change caused the rev to 1.2b6.
+     1.2b5 was never a public beta.
+
+Changes with Apache 1.2b5
+
+  *) Change KeepAlive semantics (On|Off instead of a number), add
+     MaxKeepAliveRequests directive. [Alexei Kosut]
+
+  *) Various NeXT compilation patches, as well as a change in
+     regex/regcomp.c since that file also used a NEXT define.
+     [Andreas Koenig]
+
+  *) Allow * to terminate the end of a directory match in mod_dir.
+     Allows /~* to match for both /~joe and /~joe/. [David Bronder]
+
+  *) Don't call can_exec() if suexec_enabled. Calling this requires
+     scripts executed by the suexec wrapper to be world executable, which
+     defeats one of the advantages of running the wrapper. [Randy Terbush]
+
+  *) Portability Fix: IRIX complained with 'make clean' about *pure* (removed)
+     [Jim Jagielski]
+
+  *) Migration from sprintf() to snprintf() to avoid buffer
+     overflows. [Marc Slemko]
+
+  *) Provide portable snprintf() implementation (ap_snprintf)
+     as well as *cvt family. [Jim Jagielski]
+
+  *) Portability Fix: NeXT lacks unistd.h so we wrap it's inclusion
+     [Jim Jagielski]
+
+  *) Remove mod_fastcgi.c from the distribution. This module appears
+     to be maintained more through the Open Market channels and should
+     continue to be easily available at http://www.fastcgi.com/
+
+  *) Fixed bug in modules/Makefile that wouldn't allow building in more
+     than one subdirectory (or cleaning, either). [Jeremy Laidman]
+
+  *) mod_info assumed that the config files were relative to ServerRoot.
+     [Ken the Rodent]
+
+  *) CGI scripts called as an error document resulting from failed
+     CGI execution would hang waiting for POST'ed data. [Rob Hartill]
+
+  *) Log reason when mod_dir returns access HTTP_FORBIDDEN
+     [Ken the Rodent]
+
+  *) Properly check errno to prevent display of a directory index
+     when server receives a long enough URL to confuse stat().
+     [Marc Slemko]
+
+  *) Several security enhancements to suexec wrapper. It is _highly_
+     recommended that previously installed versions of the wrapper
+     be replaced with this version.  [Randy Terbush, Jason Dour]
+
+        - ~user execution now properly restricted to ~user's home
+          directory and below.
+        - execution restricted to UID/GID > 100
+        - restrict passed environment to known variables
+        - call setgid() before initgroups() (portability fix)
+        - remove use of setenv() (portability fix)
+
+  *) Add HTTP/1.0 response forcing. [Ben Laurie]
+
+  *) Add access control via environment variables. [Ben Laurie]
+
+  *) Add rflush() function. [Alexei Kosut]
+
+  *) remove duplicate pcalloc() call in new_connection().
+
+  *) Fix incorrect comparison which could allow number of children =
+     MaxClients + 1 if less than HARD_SERVER_LIMIT. Also fix potential
+     problem if StartServers > HARD_SERVER_LIMIT. [Ed Korthof]
+
+  *) Updated support for OSes (MachTen, ULTRIX, Paragon, ISC, OpenBSD
+     AIX PS/2, CONVEXOS. [Jim Jagielski]
+
+  *) Replace instances of inet_ntoa() with inet_addr() for ProxyBlock.
+     It's more portable. [Martin Kraemer]
+
+  *) Replace references to make in Makefile.tmpl with $(MAKE).
+     [Chuck Murcko]
+
+  *) Add ProxyBlock directive w/IP address caching. Add IP address
+     caching to NoCache directive as well. ProxyBlock works with all
+     handlers; NoCache now also works with FTP for anonymous logins.
+     Still more code cleanup. [Chuck Murcko]
+
+  *) Add "header parse" API hook [Ben Laurie]
+
+  *) Fix byte ordering problems for REMOTE_PORT [Chuck Murcko]
+
+  *) suEXEC wrapper was freeing memory that had not been malloc'ed.
+
+  *) Correctly allow access and auth directives in <Files> sections in
+     server config files. [Alexei Kosut]
+
+  *) Fix bug with ServerPath that could cause certain files to be not
+     found by the server. [Alexei Kosut]
+
+  *) Fix handling of ErrorDocument so that it doesn't remove a trailing
+     double-quote from text and so that it properly checks for unsupported
+     status codes using the new index_of_response interface. [Roy Fielding]
+
+  *) Multiple fixes to the lingering_close code in order to avoid being
+     interrupted by a stray timeout, to avoid lingering on a connection
+     that has already been aborted or never really existed, to ensure that
+     we stop lingering as soon as any error condition is received, and to
+     prevent being stuck indefinitely if the read blocks.  Also improves
+     reporting of error conditions.  [Marc Slemko and Roy Fielding]
+
+  *) Fixed initialization of parameter structure for sigaction.
+     [<mgyger itr.ch>, Adrian Filipi-Martin]
+
+  *) Fixed reinitializing the parameters before each call to accept and
+     select, and removed potential for infinite loop in accept.
+     [Roy Fielding, after useful PR from <adrian virginia.edu>]
+
+  *) Fixed condition where, if a child fails to fork, the scoreboard would
+     continue to say SERVER_STARTING forever. Eventually, the main process
+     would refuse to start new children because count_idle_servers() will
+     count those SERVER_STARTING entries and will always report that there
+     are enough idle servers. [Phillip Vandry]
+
+  *) Fixed bug in bcwrite regarding failure to account for partial writes.
+     Avoided calling bflush() when the client is pipelining requests.
+     Removed unnecessary flushes from http_protocol. [Dean Gaudet]
+
+  *) Added description of "." mode in server-status [Jim Jagielski]
+
+Changes with Apache 1.2b4
+
+  *) Fix possible race condition in accept_mutex_init() that
+     could leave a small security hole open allowing files to be
+     overwritten in cases where the server UID has write permissions.
+     [Marc Slemko]
+
+  *) Fix awk compatibilty problem in Configure. [Jim Jagielski]
+
+  *) Fix portablity problem in util_script where ARG_MAX may not be
+     defined for some systems.
+
+  *) Add changes to allow compilation on Machten 4.0.3 for PowerPC.
+     [Randal Schwartz]
+
+  *) OS/2 changes to support an MMAP style scoreboard file and UNIX
+     style magic #! token for better script portability. [Garey Smiley]
+
+  *) Fix bug in suexec wrapper introduced in b3 that would cause failed
+     execution for ~userdir CGI. [Jason Dour]
+
+  *) Fix initgroups() business in suexec wrapper. [Jason Dour]
+
+  *) Fix month off by one in suexec wrapper logging.
+
+Changes with Apache 1.2b3:
+
+  *) Fix error in mod_cgi which could cause resources not to be properly
+     freed, or worse. [Dean Gaudet]
+
+  *) Fix find_string() NULL pointer dereference. [Howard Fear]
+
+  *) Add set_flag_slot() at the request of Dirk and others.
+     [Dirk vanGulik]
+
+  *) Sync mod_rewrite with patch level 10. [Ralf Engelschall]
+
+  *) Add changes to improve the error message given for invalid
+     ServerName parameters. [Dirk vanGulik]
+
+  *) Add "Authoritative" directive for Auth modules that don't
+     currently have it. This gives admin control to assign authoritative
+     control to an authentication scheme and allow "fall through" for
+     those authentication modules that aren't "Authoritative" thereby
+     allowing multiple authentication mechanisms to be chained.
+     [Dirk vanGulik]
+
+  *) Remove requirement for ResourceConfig/AccessConfig if not using
+     the three config file layout. [Randy Terbush]
+
+  *) Add PASV mode to mod_proxy FTP handler. [Chuck Murcko]
+
+  *) Changes to suexec wrapper to fix the following problems:
+     1.  symlinked homedirs will kill ~userdirs.
+     2.  initgroups() on Linux 2.0.x clobbers gr->grid.
+     3.  CGI command lines paramters problems
+     4.  pw-pwdir for "docroot check" still the httpd user's pw record.
+    [Randy Terbush, Jason Dour]
+
+  *) Change create_argv() to accept variable arguments. This fixes
+     a problem where arguments were not getting passed to the CGI via
+     argv[] when the suexec wrapper was active. [Randy Terbush, Jake Buchholz]
+
+  *) Collapse multiple slashes in path URLs to properly apply
+     handlers defined by <Location>. [Alexei Kosut]
+
+  *) Define a sane set of DEFAULT_USER and DEFAULT_GROUP values for AIX.
+
+  *) Improve the accuracy of request duration timings by setting
+     r->request_time in read_request_line() instead of read_request().
+     [Dean Gaudet]
+
+  *) Reset timeout while reading via get_client_block() in mod_cgi.c
+     Fixes problem with timed out transfers of large files. [Rasmus Lerdorf]
+
+  *) Add the ability to pass different Makefile.tmpl files to Configure
+     using the -make flag. [Rob Hartill]
+
+  *) Fix coredump triggered when sending a SIGHUP to the server caused
+     by an assertion failure, in turn caused by an uninitialised field in a
+     listen_rec.
+     [Ben Laurie]
+
+  *) Add FILEPATH_INFO variable to CGI environment, which is equal to
+     PATH_INFO from previous versions of Apache (in certain situations,
+     Apache 1.2's PATH_INFO will be different than 1.1's). [Alexei Kosut]
+     [later removed in 1.2b11]
+
+  *) Add rwrite() function to API to allow for sending strings of
+     arbitrary length. [Doug MacEachern]
+
+  *) Remove rlim_t typedef for NetBSD. Do older versions need this?
+
+  *) Defined rlim_t and WANTHSREGEX=yes and fixed waitpid() substitute for
+     NeXT. [Jim Jagielski]
+
+  *) Removed recent modification to promote the status code on internal
+     redirects, since the correct fix was to change the default log format
+     in mod_log_config so that it outputs the original status. [Rob Hartill]
+
+Changes with Apache 1.2b2:
+
+  *) Update set_signals() to use sigaction() for setting handlers.
+     This appears to fix a re-entrant problem in the seg_fault()
+     bus_error() handlers. [Randy Terbush]
+
+  *) Changes to allow mod_status compile for OS/2 [Garey Smiley]
+
+  *) changes for DEC AXP running OSF/1 v3.0. [Marc Evans]
+
+  *) proxy_http.c bugfixes:  [Chuck Murcko]
+        1) fixes possible NULL pointer reference w/NoCache
+        2) fixes NoCache behavior when using ProxyRemote (ProxyRemote
+           host would cache nothing if it was in the local domain,
+           and the local domain was in the NoCache list)
+        3) Adds Host: header when not available
+        4) Some code cleanup and clarification
+
+  *) mod_include.c bugfixes:
+        1) Fixed an ommission that caused include variables to not
+           be parsed in config errmsg directives [Howard Fear]
+        2) Remove HAVE_POSIX_REGEX cruft [Alexei Kosut]
+        3) Patch to fix compiler warnings [<perrot lal.in2p3.fr>]
+        4) Allow backslash-escaping to all quoted text
+           [Ben Yoshino <ben wiliki.eng.hawaii.edu>]
+        5) Pass variable to command line if not set in XSSI's env
+           [Howard Fear]
+
+  *) Fix infinite loop when processing Content-language lines in
+     type-map files. [Alexei Kosut]
+
+  *) Closed file-globbing hole in test-cgi script. [Brian Behlendorf]
+
+  *) Fixed problem in set_[user|group] that prevented CGI execution
+     for non-virtualhosts when suEXEC was enabled. [Randy Terbush]
+
+  *) Added PORTING information file.  [Jim Jagielski]
+
+  *) Added definitions for S_IWGRP and S_IWOTH to conf.h [Ben Laurie]
+
+  *) Changed default group to "nogroup" instead of "nobody" [Randy Terbush]
+
+  *) Fixed define typo of FCNTL_SERIALIZED_ACCEPT where
+     USE_FCNTL_SERIALIZED_ACCEPT was intended.
+
+  *) Fixed additional uses of 0xffffffff where INADDR_NONE was intended,
+     which caused problems of systems where socket s_addr is >32bits.
+
+  *) Added comment to explain (r->chunked = 1) side-effect in
+     http_protocol.c [Roy Fielding]
+
+  *) Replaced use of index() in mod_expires.c with more appropriate
+     and portable isdigit() test.  [Ben Laurie]
+
+  *) Updated Configure for ...
+        OS/2          (DEF_WANTHSREGEX=yes, other code changes)
+        *-dg-dgux*    (bad pattern match)
+        QNX           (DEF_WANTHSREGEX=yes)
+        *-sunos4*     (DEF_WANTHSREGEX=yes, -DUSEBCOPY)
+        *-ultrix      (new)
+        *-unixware211 (new)
+     and added some user diagnostic info.  [Ben Laurie]
+
+  *) In helpers/CutRule, replaced "cut" invocation with "awk" invocation
+     for better portability. [Jim Jagielski]
+
+  *) Updated helpers/GuessOS for ...
+        SCO 5            (recognize minor releases)
+        SCO UnixWare     (braindamaged uname, whatever-whatever-unixware2)
+        SCO UnixWare 2.1.1      (requires a separate set of #defines in conf.h)
+        IRIX64           (-sgi-irix64)
+        ULTRIX           (-unknown-ultrix)
+        SINIX            (-whatever-sysv4)
+        NCR Unix         (-ncr-sysv4)
+     and fixed something in helpers/PrintPath  [Ben Laurie]
+
+Changes with Apache 1.2b1
+
+  *) Not listed. See <http://www.apache.org/docs/new_features_1_2.html>
+
+Changes with Apache 1.1.1
+
+  *) Fixed bug where Cookie module would make two entries in the
+     logfile for each access [Mark Cox]
+
+  *) Fixed bug where Redirect in .htaccess files would cause memory
+     leak. [Nathan Neulinger]
+
+  *) MultiViews now works correctly with AddHandler [Alexei Kosut]
+
+  *) Problems with mod_auth_msql fixed [Dirk vanGulik]
+
+  *) Fix misspelling of "Anonymous_Authorative" directive in mod_auth_anon.
+
+Changes with Apache 1.1.0
+
+  *) Bring NeXT support up to date. [Takaaki Matsumoto]
+
+  *) Bring QNX support up to date. [Ben Laurie]
+
+  *) Make virtual hosts default to main server keepalive parameters.
+     [Alexei Kosut, Ben Laurie]
+
+  *) Allow ScanHTMLTitles to work with lowercase <title> tags. [Alexei Kosut]
+
+  *) Fix missing address family for connect, also remove unreachable statement
+     in mod_proxy. [Ben Laurie]
+
+  *) mod_env now turned on by default in Configuration.tmpl.
+
+  *) Bugs which were fixed:
+        a) yet more mod_proxy bugs [Ben Laurie]
+        b) CGI works again with inetd [Alexei Kosut]
+        c) Leading colons were stripped from passwords [<osm interguide.com>]
+        d) Another fix to multi-method Limit problem [<jk tools.de>]
+
+Changes with Apache 1.1b4
+
+  *) r->bytes_sent variable restored. [Robert Thau]
+
+  *) Previously broken multi-method <Limit> parsing fixed. [Robert Thau]
+
+  *) More possibly unsecure programs removed from the support directory.
+
+  *) More mod_auth_msql authentication improvements.
+
+  *) VirtualHosts based on Host: headers no longer conflict with the
+     Listen directive.
+
+  *) OS/2 compatibility enhancements. [Gary Smiley]
+
+  *) POST now allowed to directory index CGI scripts.
+
+  *) Actions now work with files of the default type.
+
+  *) Bugs which were fixed:
+        a) more mod_proxy bugs
+        b) early termination of inetd requests
+        c) compile warnings on several systems
+        d) problems when scripts stop reading output early
+
+Changes with Apache 1.1b3
+
+  *) Much of cgi-bin and all of cgi-src has been removed, due to
+     various security holes found and that we could no longer support
+     them.
+
+  *) The "Set-Cookie" header is now special-cased to not merge multiple
+     instances, since certain popular browsers can not handle multiple
+     Set-Cookie instructions in a single header. [Paul Sutton]
+
+  *) rprintf() added to buffer code, occurrences of sprintf removed.
+     [Ben Laurie]
+
+  *) CONNECT method for proxy module, which means tunneling SSL should work.
+     (No crypto needed)  Also a NoCache config directive.
+
+  *) Several API additions: pstrndup(), table_unset() and get_token()
+     functions now available to modules.
+
+  *) mod_imap fixups, in particular Location: headers are now complete
+     URL's.
+
+  *) New "info" module which reports on installed module set through a
+     special URL, a la mod_status.
+
+  *) "ServerPath" directive added - allows for graceful transition
+     for Host:-header-based virtual hosts.
+
+  *) Anonymous authentication module improvements.
+
+  *) MSQL authentication module improvements.
+
+  *) Status module design improved - output now table-based. [Ben Laurie]
+
+  *) htdigest utility included for use with digest authentication
+     module.
+
+  *) mod_negotiation: Accept values with wildcards to be treated with
+     less priority than those without wildcards at the same quality
+     value. [Alexei Kosut]
+
+  *) Bugs which were fixed:
+        a) numerous mod_proxy bugs
+        b) CGI early-termination bug [Ben Laurie]
+        c) Keepalives not working with virtual hosts
+        d) RefererIgnore problems
+        e) closing fd's twice in mod_include (causing core dumps on
+           Linux and elsewhere).
+
+Changes with Apache 1.1b2
+
+  *) Bugfixes:
+        a) core dumps in mod_digest
+        b) truncated hostnames/ip address in the logs
+        c) relative URL's in mod_imap map files
+
+Changes with Apache 1.1b1
+
+  *) Not listed. See <http://www.apache.org/docs/new_features_1_1.html>
+
+Changes with Apache 1.0.3
+
+  *) Internal redirects which occur in mod_dir.c now preserve the
+     query portion of a request (the bit after the question mark).
+     [Adam Sussman]
+
+  *) Escape active characters '<', '>' and '&' in html output in
+     directory listings, error messages and redirection links.
+     [David Robinson]
+
+  *) Apache will now work with LynxOS 2.3 and later [Steven Watt]
+
+  *) Fix for POSIX compliance in waiting for processes in alloc.c.
+     [Nick Williams]
+
+  *) setsockopt no longer takes a const declared argument [Martijn Koster]
+
+  *) Reset timeout timer after each successful fwrite() to the network.
+     This patch adds a reset_timeout() procedure that is called by
+     send_fd() to reset the timeout ever time data is written to the net.
+     [Nathan Schrenk]
+
+  *) timeout() signal handler now checks for SIGPIPE and reports
+     lost connections in a more user friendly way. [Rob Hartill]
+
+  *) Location of the "scoreboard" file which used to live in /tmp is
+     now configurable (for OSes that can't use mmap) via ScoreBoardFile
+     which works similar to PidFile (in httpd.conf) [Rob Hartill]
+
+  *) Include sys/resource.h in the correct place for SunOS4 [Sameer Parekh]
+
+  *) the pstrcat call in mod_cookies.c didn't have an ending NULL,
+     which caused a SEGV with cookies enabled
+
+  *) Output warning when MinSpareServers is set to <= 0 and change it to 1
+     [Rob Hartill]
+
+  *) Log the UNIX textual error returned by some system calls, in
+     particular errors from accept() [David Robinson]
+
+  *) Add strerror function to util.c for SunOS4 [Randy Terbush]
+
+Changes with Apache 1.0.2
+
+  *) patch to get Apache compiled on UnixWare 2.x, recommended as
+     a temporary measure, pending rewrite of rfc931.c. [Chuck Murcko]
+
+  *) Fix get_basic_auth_pw() to set the auth_type of the request.
+     [David Robinson]
+
+  *) past changes to http_config.c to only use the
+     setrlimit function on systems defining RLIMIT_NOFILE
+     broke the feature on SUNOS4. Now defines HAVE_RESOURCE
+     for SUNOS and prototypes the needed functions.
+
+  *) Remove uses of MAX_STRING_LEN/HUGE_STRING_LEN from several routines.
+     [David Robinson]
+
+  *) Fix use of pointer to scratch memory. [Cliff Skolnick]
+
+  *) Merge multiple headers from CGI scripts instead of taking last
+     one. [David Robinson]
+
+  *) Add support for SCO 5. [Ben Laurie]
+
+Changes with Apache 1.0.1
+
+  *) Silence mod_log_referer and mod_log_agent if not configured
+     [Randy Terbush]
+
+  *) Recursive includes can occur if the client supplies PATH_INFO data
+     and the server provider uses relative links; as file.html
+     relative to /doc.shtml/pathinfo is /doc.shtml/file.html. [David Robinson]
+
+  *) The replacement for initgroups() did not call {set,end}grent(). This
+     had two implications: if anything else used getgrent(), then
+     initgroups() would fail, and it was consuming a file descriptor.
+     [Ben Laurie]
+
+  *) On heavily loaded servers it was possible for the scoreboard to get
+     out of sync with reality, as a result of a race condition.
+     The observed symptoms are far more Apaches running than should
+     be, and heavy system loads, generally followed by catastrophic
+     system failure. [Ben Laurie]
+
+  *) Fix typo in license. [David Robinson]
+
+Changes with Apache 1.0.0                                        23 Nov 1995
+
+  *) Not listed. See <http://www.apache.org/docs/new_features_1_0.html>
+
+Changes with Apache 0.8.16                                       05 Nov 1995
+
+  *) New man page for 'httpd' added to support directory [David Robinson]
+
+  *) .htgroup files can have more than one line giving members for a
+     given group (each must have the group name in front), for NCSA
+     back-compatibility [Robert Thau]
+
+  *) Mutual exclusion around accept() is on by default for SVR4 systems
+     generally, since they generally can't handle multiple processes in
+     accept() on the same socket.  This should cure flaky behavior on
+     a lot of those systems.  [David Robinson]
+
+  *) AddType, AddEncoding, and AddLanguage directives take multiple
+     extensions on a single command line [David Robinson]
+
+  *) UserDir can be disabled for a given virtual host by saying
+     "UserDir disabled" in the <VirtualHost> section --- it was a bug
+     that this didn't work.  [David Robinson]
+
+  *) Compiles on QNX [Ben Laurie]
+
+  *) Corrected parsing of ctime time format [David Robinson]
+
+  *) httpd does a perror() before exiting if it can't log its pid
+     to the PidFile, to make diagnosing the error a bit easier.
+     [David Robinson]
+
+  *) <!--#include file="..."--> can no longer include files in the
+     parent directory, for NCSA back-compatibility.  [David Robinson]
+
+  *) '~' is *not* escaped in URIs generated for directory listings
+     [Roy Fielding]
+
+  *) Eliminated compiler warning in the imagemap module [Randy Terbush]
+
+  *) Fixed bug involving handling URIs with escaped %-characters
+     in redirects [David Robinson]
+
+Changes with Apache 0.8.15                                       14 Oct 1995
+
+  *) Switched to new, simpler license
+
+  *) Eliminated core dumps with improperly formatted DBM group files [Mark Cox]
+
+  *) Don't allow requests for ordinary files to have PATH_INFO [Ben Laurie]
+
+  *) Reject paths containing %-escaped '%' or null characters [David Robinson]
+
+  *) Correctly handles internal redirects to files with names containing '%'
+     [David Robinson]
+
+  *) Repunctuated some error messages [Aram Mirzadeh, Andrew Wilson]
+
+  *) Use geteuid() rather than getuid() to see if we have root privilege,
+     so that server correctly resets privilege if run setuid root.  [Andrew
+     Wilson]
+
+  *) Handle ftp: and telnet: URLs correctly in imagemaps (built-in module)
+     [Randy Terbush]
+
+  *) Fix relative URLs in imagemap files [Randy Terbush]
+
+  *) Somewhat better fix for the old "Alias /foo/ /bar/" business
+     [David Robinson]
+
+  *) Don't repeatedly open the ErrorLog if a bunch of <VirtualHost>
+     entries all name the same one. [David Robinson]
+
+  *) Fix directory listings with filenames containing unusual characters
+     [David Robinson]
+
+  *) Better URI-escaping for generated URIs in directories with filenames
+     containing unusual characters [Ben Laurie]
+
+  *) Fixed potential FILE* leak in http_main.c [Ben Laurie]
+
+  *) Unblock alarms on error return from spawn_child() [David Robinson]
+
+  *) Sample Config files have extra note for SCO users [Ben Laurie]
+
+  *) Configuration has note for HP-UX users [Rob Hartill]
+
+  *) Eliminated some bogus Linux-only #defines in conf.h [Aram Mirzadeh]
+
+  *) Nuked bogus #define in httpd.h [David Robinson]
+
+  *) Better test for whether a system has setrlimit() [David Robinson]
+
+  *) Calls update_child_status() after reopen_scoreboard() [David Robinson]
+
+  *) Doesn't send itself SIGHUP on startup when run in the -X debug-only mode
+     [Ben Laurie]
+
+Changes with Apache 0.8.14                                       19 Sep 1995
+
+  *) Compiles on SCO ODT 3.0 [Ben Laurie]
+
+  *) AddDescription works (better) [Ben Laurie]
+
+  *) Leaves an intelligible error diagnostic when it can't set group
+     privileges on standalone startup [Andrew Wilson]
+
+  *) Compiles on NeXT again --- the 0.8.13 RLIMIT patch was failing on
+     that machine, which claims to be BSD but does not support RLIMIT.
+     [Randy Terbush]
+
+  *) gcc -Wall no longer complains about an unused variable when util.c
+     is compiled with -DMINIMAL_DNS [Andrew Wilson]
+
+  *) Nuked another compiler warning for -Wall on Linux [Aram Mirzadeh]
+
+Changes with Apache 0.8.13                                       07 Sep 1995
+
+  *) Make IndexIgnore *work* (ooops) [Jarkko Torppa]
+
+  *) Have built-in imagemap code recognize & honor Point directive [James
+     Cloos]
+
+  *) Generate cleaner directory listings in directories with a mix of
+     long and short filenames [Rob Hartill]
+
+  *) Properly initialize dynamically loaded modules [Royston Shufflebotham]
+
+  *) Properly default ServerName for virtual servers [Robert Thau]
+
+  *) Rationalize handling of BSD in conf.h and elsewhere [Randy Terbush,
+     Paul Richards and a cast of thousands...]
+
+  *) On self-identified BSD systems (we don't try to guess any more),
+     allocate a few extra file descriptors per virtual host with setrlimit,
+     if we can, to avoid running out. [Randy Terbush]
+
+  *) Write 22-character lock file name into buffer with enough space
+     on startup [Konstantin Olchanski]
+
+  *) Use archaic setpgrp() interface on NeXT, which requires it [Brian
+     Pinkerton]
+
+  *) Suppress -Wall warning by casting const away in util.c [Aram Mirzadeh]
+
+  *) Suppress -Wall warning by initializing variable in negotiation code
+     [Tobias Weingartner]
+
+Changes with Apache 0.8.12                                       31 Aug 1995
+
+  *) Doesn't pause three seconds after including a CGI script which is
+     too slow to die off (this is done by not even trying to kill off
+     subprocesses, including the SIGTERM/pause/SIGKILL routine, until
+     after the entire document has been processed).  [Robert Thau]
+
+  *) Doesn't do SSI if Options Includes is off.  (Ooops).  [David Robinson]
+
+  *) Options IncludesNoExec allows inclusion of at least text/* [Roy Fielding]
+
+  *) Allows .htaccess files to override <Directory> sections naming the
+     same directory [David Robinson]
+
+  *) Removed an efficiency hack in sub_req_lookup_uri which was
+     causing certain extremely marginal cases (e.g., ScriptAlias of a
+     *particular* index.html file) to fail.  [David Robinson]
+
+  *) Doesn't log an error when the requested URI requires
+     authentication, but no auth header line was supplied by the
+     client; this is a normal condition (the client doesn't no auth is
+     needed here yet).  [Robert Thau]
+
+  *) Behaves more sanely when the name server loses its mind [Sean Welch]
+
+  *) RFC931 code compiles cleanly on old BSDI releases [Randy Terbush]
+
+  *) RFC931 code no longer passes out name of prior clients on current
+     requests if the current request came from a server that doesn't
+     do RFC931.  [David Robinson]
+
+  *) Configuration script accepts "Module" lines with trailing whitespace.
+     [Robert Thau]
+
+  *) Cleaned up compiler warning from mod_access.c [Robert Thau]
+
+  *) Cleaned up comments in mod_cgi.c [Robert Thau]
+
+Changes with Apache 0.8.11                                       24 Aug 1995
+
+  *) Wildcard <Directory> specifications work.  [Robert Thau]
+
+  *) Doesn't loop for buggy CGI on Solaris [Cliff Skolnick]
+
+  *) Symlink checks (FollowSymLinks off, or SymLinkIfOwnerMatch) always check
+     the file being requested itself, in addition to the directories leading
+     up to it. [Robert Thau]
+
+  *) Logs access failures due to symlink checks or invalid client address
+     in the error log [Roy Fielding, Robert Thau]
+
+  *) Symlink checks deal correctly with systems where lstat of
+     "/path/to/some/link/" follows the link.  [Thau, Fielding]
+
+  *) Doesn't reset DirectoryIndex to 'index.html' when
+     other directory options are set in a .htaccess file.  [Robert Thau]
+
+  *) Clarified init code and nuked bogus warning in mod_access.c
+     [Florent Guillaume]
+
+  *) Corrected several directives in sample srm.conf
+     --- includes corrections to directory indexing icon-related directives
+     (using unknown.gif rather than unknown.xbm as the DefaultIcon, doing
+     icons for encodings right, and turning on AddEncoding by default).
+     [Roy Fielding]
+
+  *) Corrected descriptions of args to AddIcon and AddAlt in command table
+     [James Cloos]
+
+  *) INSTALL & README mention "contributed modules" directory [Brian
+     Behlendorf]
+
+  *) Fixed English in the license language...  "for for" --> "for".
+     [Roy Fielding]
+
+  *) Fixed ScriptAlias/Alias interaction by moving ScriptAlias handling to
+     mod_alias.c, merging it almost completely with handling of Alias, and
+     adding a 'notes' field to the request_rec which allows the CGI module
+     to discover whether the Alias module has put this request through
+     ScriptAlias (which it needs to know for back-compatibility, as the old
+     NCSA code did not check Options ExecCGI in ScriptAlias directories).
+     [Robert Thau]
+
+Changes with Apache 0.8.10                                       18 Aug 1995
+
+  *) AllowOverride applies to the named directory, and not just
+     subdirectories.  [David Robinson]
+
+  *) Do locking for accept() exclusion (on systems that need it)
+     using a special file created for the purpose in /usr/tmp, and
+     not the error log; using the error log causes real problems
+     if it's NFS-mounted; this is known to be the cause of a whole
+     lot of "server hang" problems with Solaris.  [David Robinson;
+     thanks to Merten Schumann for help diagnosing the problem].
+
+Changes with Apache 0.8.9                                        12 Aug 1995
+
+  *) Compiles with -DMAXIMUM_DNS ---- ooops! [Henrik Mortensen]
+
+  *) Nested includes see environment variables of the including document,
+     for NCSA bug-compatibility (some sites have standard footer includes
+     which try to print out the last-modified date).  [Eric Hagberg/Robert
+     Thau]
+
+  *) <!--exec cgi="/some/uri/here"--> always treats the item named by the
+     URI as a CGI script, even if it would have been treated as something
+     else if requested directly, for NCSA back-compatibility.  (Note that
+     this means that people who know the name of the script can see the
+     code just by asking for it).  [Robert Thau]
+
+  *) New version of dbmmanage script included in support directory as
+     dbmmanage.new.
+
+  *) Check if scoreboard file couldn't be opened, and say so, rather
+     then going insane [David Robinson]
+
+  *) POST to CGI works on A/UX [Jim Jagielski]
+
+  *) AddIcon and AddAlt commands work properly [Rob Hartill]
+
+  *) NCSA server push works properly --- the Arena bug compatibility
+     workaround, which broke it, is gone (use -DARENA_BUG_WORKAROUND
+     if you still want the workaround).  [Rob Hartill]
+
+  *) If client didn't submit any Accept-encodings, ignore encodings in
+     content negotiation.  (NB this will all have to be reworked anyway
+     for the new HTTP draft).  [Florent Guillaume]
+
+  *) Don't dump core when trying to log timed-out requests [Jim Jagielski]
+
+  *) Really honor CacheNegotiatedDocs [Florent Guillaume]
+
+  *) Give Redirect priority over Alias, for NCSA bug compatibility
+     [David Robinson]
+
+  *) Correctly set PATH_TRANSLATED in all cases from <!--#exec cmd=""-->,
+     paralleling earlier bug fix for CGI [David Robinson]
+
+  *) If DBM auth is improperly configured, report a server error and don't
+     dump core.
+
+  *) Deleted FCNTL_SERIALIZED_ACCEPTS from conf.h entry for A/UX;
+     it seems to work well enough without it (even in a 10 hits/sec
+     workout), and the overhead for the locking under A/UX is
+     alarmingly high (though it is very low on other systems).
+     [Eric Hagberg, Jim Jagielski]
+
+  *) Fixed portability problems with mod_cookies.c [Cliff Skolnick]
+
+  *) Further de-Berklize mod_cookies.c; change the bogus #include.  [Brian
+     Behlendorf/Eric Hagberg]
+
+  *) More improvements to default Configuration for A/UX [Jim Jagielski]
+
+  *) Compiles clean on NEXT [Rob Hartill]
+
+  *) Compiles clean on SGI [Robert Thau]
+
+Changes with Apache 0.8.8                                        08 Aug 1995
+
+  *) SunOS library prototypes now never included unless explicitly
+     requested in the configuration (via -DSUNOS_LIB_PROTOTYPES);
+     people using GNU libc on SunOS are screwed by prototypes for the
+     standard library.
+
+     (Those who wish to compile clean with gcc -Wall on a standard
+     SunOS setup need the prototypes, and may obtain them using
+     -DSUNOS_LIB_PROTOTYPES.  Those wishing to use -Wall on a system
+     with nonstandard libraries are presumably competent to make their
+     own arrangements).
+
+  *) Strips trailing '/' characters off both args to the Alias command,
+     to make 'Alias /foo/ /bar/' work.
+
+Changes with Apache 0.8.7                                        03 Aug 1995
+
+  *) Don't hang when restarting with a child from 'TransferLog "|..."' running
+     [reported by David Robinson]
+
+  *) Compiles clean on OSF/1 [David Robinson]
+
+  *) Added some of the more recent significant changes (AddLanguage stuff,
+     experimental LogFormat support) to CHANGES file in distribution root
+     directory
+
+Changes with Apache 0.8.6                                        02 Aug 1995
+
+  *) Deleted Netscape reload workaround --- it's in violation of HTTP specs.
+     (If you actually wanted a conditional GET which bypassed the cache, you
+     couldn't get it). [Reported by Roy Fielding]
+
+  *) Properly terminate headers on '304 Not Modified' replies to conditional
+     GETs --- no browser we can find cares much, but the CERN proxy chokes.
+     [Reported by Cliff Skolnick; fix discovered independently by Rob Hartill]
+
+  *) httpd -v doesn't call itself "Shambhala".  [Reported by Chuck Murcko]
+
+  *) SunOS lib-function prototypes in conf.h conditionalized on __GNUC__,
+     not __SUNPRO_C (they're needed to quiet gcc -Wall, but acc chokes on 'em,
+     and older versions don't set the __SUNPRO_C preprocessor variable).  On
+     all other systems, these are never used anyway.  [Reported by Mark Cox].
+
+  *) Scoreboard file (/tmp/htstatus.*) no longer publically writable.
+
+Changes with Apache 0.8.5                                        01 Aug 1995
+
+  *) Added last-minute configurable log experiment, as optional module
+
+  *) Correctly set r->bytes_sent for HTTP/0.9 requests, so they get logged
+     properly.  (One-line fix to http_protocol.c).
+
+  *) Work around bogus behavior when reloading from Netscape.
+     It's Netscape's bug --- for some reason they expect a request with
+     If-modified-since: to not function as a conditional GET if it also
+     comes with Pragma: no-cache, which is way out of line with the HTTP
+     spec (according to Roy Fielding, the redactor).
+
+  *) Added parameter to set maximum number of server processes.
+
+  *) Added patches to make it work on A/UX.  A/UX is *weird*.  [Eric Hagberg,
+     Jim Jagielski]
+
+  *) IdentityCheck bugfix [Chuck Murcko].
+
+  *) Corrected cgi-src/Makefile entry for new imagemap script.  [Alexei Kosut]
+
+  *) More sample config file corrections; add extension to AddType for
+     *.asis, move AddType generic description to its proper place, and
+     fix miscellaneous typos. [ Alexei Kosut ]
+
+  *) Deleted the *other* reference to the regents from the Berkeley
+     legal disclaimer (everyplace).
+
+  *) Nuked Shambhala name from src/README; had already cleaned it out
+     of everywhere else.
+
+Changes with Apache 0.8.4
+
+  *) Changes to server-pool management parms --- renamed current
+     StartServers to MinSpareServers, created separate StartServers
+     parameter which means what it says, and renamed MaxServers to
+     MaxSpareServers (though the old name still works, for NCSA 1.4
+     back-compatibility).  The old names were generally regarded as
+     too confusing.  Also altered "docs" in sample config files.
+
+  *) More improvements to default config files ---
+     sample directives (commented out) for XBitHack, BindAddress,
+     CacheNegotiatedDocs, VirtualHost; decent set of AddLanguage
+     defaults, AddTypes for send-as-is and imagemap magic types, and
+     improvements to samples for DirectoryIndex [Alexei Kosut]
+
+  *) Yet more improvements to default config files --- changes to
+     Alexei's sample AddLanguage directives, and sample LanguagePriority
+     [ Florent Guillaume ]
+
+  *) Set config file locations properly if not set in httpd.conf
+     [ David Robinson ]
+
+  *) Don't escape URIs in internal redirects multiple times; don't
+     do that when translating PATH_INFO to PATH_TRANSLATED either.
+     [ David Robinson ]
+
+  *) Corrected spelling of "Required" in 401 error reports [Andrew Wilson]
+
+Changes with Apache 0.8.3
+
+  *) Edited distribution README to *briefly* summarize installation
+     procedures, and give a pointer to the INSTALL file in the src/
+     directory.
+
+  *) Upgraded imagemap script in cgi-bin to 1.8 version from more
+     recent NCSA distributions.
+
+  *) Bug fix to previous bug fix --- if .htaccess file and <Directory>
+     exist for the same directory, use both and don't segfault.  [Reported
+     by David Robinson]
+
+  *) Proper makefile dependencies [David Robinson]
+
+  *) Note (re)starts in error log --- reported by Rob Hartill.
+
+  *) Only call no2slash() after get_path_info() has been done, to
+     preserve multiple slashes in the PATH_INFO [NCSA compatibility,
+     reported by Andrew Wilson, though this one is probably a real bug]
+
+  *) Fixed mod_imap.c --- relative paths with base_uri referer don't
+     dump core when Referer is not supplied. [Randy Terbush]
+
+  *) Lightly edited sample config files to refer people to our documentation
+     instead of NCSA's, and to list Rob McCool as *original* author (also
+     deleted his old, and no doubt non-functional email address).  Would be
+     nice to have examples of new features...
+
+Changes with Apache 0.8.2                                        19 Jul 1995
+
+  *) Added AddLanuage code [Florent Guillaume]
+
+  *) Don't say "access forbidden" when a CGI script is not found.  [Mark Cox]
+
+  *) All sorts of problems when MultiViews finds a directory.  It would
+     be nice if mod_dir.c was robust enough to handle that, but for now,
+     just punt.  [reported by Brian Behlendorf]
+
+  *) Wait for all children on restart, to make sure that the old socket
+     is gone and we can reopen it.  [reported by Randy Terbush]
+
+  *) Imagemap module is enabled in default Configuration
+
+  *) RefererLog and UserAgentLog modules properly default the logfile
+     [Randy Terbush]
+
+  *) Mark Cox's mod_cookies added to the distribution as an optional
+     module (commented out in the default Configuration, and noted as
+     an experiment, along with mod_dld). [Mark Cox]
+
+  *) Compiles on ULTRIX (a continuing battle...). [Robert Thau]
+
+  *) Fixed nasty bug in SIGTERM handling [reported by Randy Terbush]
+
+  *) Changed "Shambhala" to "Apache" in API docs. [Robert Thau]
+
+  *) Added new, toothier legal disclaimer. [Robert Thau; copied from BSD
+     license]
+
+Changes with Apache 0.8.1
+
+  *) New imagemap module [Randy Terbush]
+
+  *) Replacement referer log module with NCSA-compatible RefererIgnore
+     [Matthew Gray again]
+
+  *) Don't mung directory listings with very long filenames.
+     [Florent Guillaume]
+
+Changes with Apache 0.8.0 (nee Shambhala 0.6.2)                  16 Jul 1995
+
+  *) New config script.  See INSTALL for info.  [Robert Thau]
+
+  *) Scoreboard mechanism for regulating the number of extant server
+     processes.  MaxServers and StartServers defaults are the same as
+     for NCSA, but the meanings are slightly different.  (Actually,
+     I should probably lower the MaxServers default to 10).
+
+     Before asking for a new connection, each server process checks
+     the number of other servers which are also waiting for a
+     connection.  If there are more than MaxServers, it quietly dies
+     off.  Conversely, every second, the root, or caretaker, process
+     looks to see how many servers are waiting for a new connection;
+     if there are fewer than StartServers, it starts a new one.  This
+     does not depend on the number of server processes already extant.
+     The accounting is arranged through a "scoreboard" file, named
+     /tmp/htstatus.*, on which each process has an independent file
+     descriptor (they need to seek without interference).
+
+     The end effect is that MaxServers is the maximum number of
+     servers on an *inactive* server machine, but more will be forked
+     off to handle unusually heavy loads (or unusually slow clients);
+     these will die off when they are no longer needed --- without
+     reverting to the overhead of full forking operation.  There is a
+     hard maximum of 150 server processes compiled in, largely to
+     avoid forking out of control and dragging the machine down.
+     (This is arguably too high).
+
+     In my server endurance tests, this mechanism did not appear to
+     impose any significant overhead, even after I forced it to put the
+     scoreboard file on a normal filesystem (which might have more
+     overhead than tmpfs).  [Robert Thau]
+
+  *) Set HTTP_FOO variables for SSI <!--#exec cmd-->s, not just CGI scripts.
+     [Cliff Skolnick]
+
+  *) Read .htaccess files even in directory with <Directory> section.
+     (Former incompatibility noted on mailing list, now fixed). [Robert
+     Thau]
+
+  *) "HEAD /" gives the client a "Bad Request" error message, rather
+     than trying to send no body *and* no headers.  [Cliff Skolnick].
+
+  *) Don't produce double error reports for some very obscure cases
+     mainly involving auth configuration (the "all modules decline to
+     handle" case which is a sure sign of a server bug in most cases,
+     but also happens when authentication is badly misconfigured).
+     [Robert Thau]
+
+  *) Moved FCNTL_SERIALIZED_ACCEPT defines into conf.h (that's what
+     it's *for*, and this sort of thing really shouldn't be cluttering
+     up the Makefile). [Robert Thau]
+
+  *) Incidental code cleanups in http_main.c --- stop dragging
+     sa_client around; just declare it where used.  [Robert Thau]
+
+  *) Another acc-related fix.  (It doesn't like const char
+     in some places...). [Mark Cox]
+
+Changes with Shambhala 0.6.1                                     13 Jul 1995
+
+  *) Fixed auth_name-related typos in http_core.c [Brian Behlendorf]
+     Also, fixed auth typo in http_protocol.c unmasked by this fix.
+
+  *) Compiles clean with acc on SunOS [Paul Sutton]
+
+  *) Reordered modules in modules.c so that Redirect takes priority
+     over ScriptAlias, for NCSA bug-compatibility [Rob Hartill] ---
+     believe it or not, he has an actual site with a ScriptAlias and
+     a Redirect declared for the *exact same directory*.  Even *my*
+     compatibility fetish wouldn't motivate me to fix this if the fix
+     required any effort, but it doesn't, so what the hey.
+
+  *) Fixed to properly default several server_rec fields for virtual
+     servers from the corresponding fields in the main server_rec.
+     [Cliff Skolnick --- 'port' was a particular irritant].
+
+  *) No longer kills off nph- child processes before they are
+     finished sending output. [Matthew Gray]
+
+Changes with Shambhala 0.6.0                                     10 Jul 1995
+
+  *) Two styles of timeout --- hard and soft.  soft_timeout()s just put
+     the connection to the client in an "aborted" state, but otherwise
+     allow whatever handlers are running to clean up.  hard_timeout()s
+     abort the request in progress completely; anything not tied to some
+     resource pool cleanup will leak.  They're still around because I
+     haven't yet come up with a more elegant way of handling
+     timeouts when talking to something that isn't the client.  The
+     default_handler and the dir_handler now use soft timeouts, largely
+     so I can test the feature.  [Robert Thau]
+
+  *) TransferLog "| my_postprocessor ..." seems to be there.  Note that
+     the case of log handlers dying prematurely is probably handled VERY
+     gracelessly at this point, and if the logger stops reading input,
+     the server will hang.  (It is known to correctly restart the
+     logging process on server restart; this is (should be!) going through
+     the same SIGTERM/pause/SIGKILL routine used to ding an errant CGI
+     script).  [Robert Thau]
+
+  *) asis files supported (new module).  [Robert Thau]
+
+  *) IdentityCheck code is compiled in, but has not been tested.  (I
+     don't know anyone who runs identd). [Robert Thau]
+
+  *) PATH_INFO and PATH_TRANSLATED are not set unless some real PATH_INFO
+     came in with the request, for NCSA bug-compatibility. [Robert Thau]
+
+  *) Don't leak the DIR * on HEAD request for a directory. [Robert Thau]
+
+  *) Deleted the block_alarms() stuff from dbm_auth; no longer necessary,
+     as timeouts are not in scope. [Robert Thau]
+
+  *) quoted-string args in config files now handled correctly (doesn't drop
+     the last character). [Robert Thau; reported by Randy Terbush]
+
+  *) Fixed silly typo in http_main.c which was suddenly fatal in HP-UX.
+     How the hell did it ever work? [Robert Thau; reported by Rob Hartill]
+
+  *) mod_core.c --- default_type returns DEFAULT_TYPE (the compile-time
+     default default type); the former default default behavior when all
+     type-checkers defaulted had been a core dump.  [Paul Sutton]
+
+  *) Copy filenames out of the struct dirent when indexing
+     directories.  (On Linux, readdir() returns a pointer to the same
+     memory area every time).  Fix is in mod_dir.c.  [Paul Sutton]
+
+Changes with Shambhala 0.5.3 [not released]
+
+  *) Default response handler notes "file not found" in the error log,
+     if the file was not found.  [Cliff Skolnick].
+
+  *) Another Cliff bug --- "GET /~user" now properly redirects (the userdir
+     code no longer sets up bogus PATH_INFO which fakes out the directory
+     handler). [Cliff Skolnick]
+
+Changes with Shambhala 0.5.2                                     06 Jul 1995
+
+  *) Changes to http_main.c --- root server no longer plays silly
+     games with SIGCHLD, and so now detects and replaces dying
+     children.  Child processes just die on SIGTERM, without taking
+     the whole process group with them.  Potential problem --- if any
+     child process refuses to die, we hang in restart.
+     MaxRequestsPerChild may still not work, but it certainly works
+     better than it did before this!  [Robert Thau]
+
+  *) mod_dir.c bug fixes: ReadmeName and HeaderName
+     work (or work better, at least); over-long description lines
+     properly terminated. [Mark Cox]
+
+  *) http_request.c now calls unescape_url() more places where it
+     should [Paul Sutton].
+
+  *) More directory handling bugs (reported by Cox)
+     Parent Directory link is now set correctly. [Robert Thau]
+
+Changes with Shambhala 0.5.1                                     04 Jul 1995
+
+  *) Generalized cleanup interface in alloc.c --- any function can be
+     registered with alloc.c as a cleanup for a resource pool;
+     tracking of files and file descriptors has been reimplemented in
+     terms of this interface, so I can give it some sort of a test.
+     [Robert Thau]
+
+  *) More changes in alloc.c --- new cleanup_for_exec() function,
+     which tracks down and closes all file descriptors which have been
+     registered with the alloc.c machinery before the server exec()s a
+     child process for CGI or <!--#exec-->.  CGI children now get
+     started with exactly three file descriptors open.  Hopefully,
+     this cures the problem Rob H. was having with overly persistent
+     CGI connections. [Robert Thau]
+
+  *) Mutual exclusion around the accept() in child_main() --- this is
+     required on at least SGI, Solaris and Linux, and is #ifdef'ed in
+     by default on those systems only (-DFCNTL_SERIALIZED_ACCEPT).
+     This uses fcntl(F_SETLK,...) on the error log descriptor because
+     flock() on that descriptor won't work on systems which have BSD
+     flock() semantics, including (I think) Linux 1.3 and Solaris.
+
+     This does work on SunOS (when the server is idle, only one
+     process in the pool is waiting on accept()); it *ought* to work
+     on the other systems. [Robert Thau]
+
+  *) FreeBSD and BSDI portability tweaks [Chuck Murcko]
+
+  *) sizeof(*sa_client) bugfix from [Rob Hartill]
+
+  *) pstrdup(..., NULL) returns NULL, [Randy Terbush]
+
+  *) block_alarms() to avoid leaking the DBM* in dbm auth (this should
+     be unnecessary if I go to the revised timeout-handling scheme).
+     [Robert Thau]
+
+  *) For NCSA bug-compatibility, set QUERY_STRING env var (to a null
+     string) even if none came in with the request.  [Robert Thau]
+
+  *) CHANGES file added to distribution ;-).
+
+Changes with Shambhala 0.4.5
+
+  *) mod_dld --- early dynamic loading support [rst]
+  *) Add wildcard content handlers for XBITHACK; default_hander now
+     invoked with that mechanism (as a handler hanging off mod_core) [rst]
+  *) XBITHACK supported as a wildcard content-handler, and 
+     configurable at run-time (not just at compile time, as in the
+     "patchy server" releases) [rst]
+
+Changes with Shambhala 0.4.4                                     30 Jun 1995
+
+  *) Fixed basic thinkos in mod_dbm_auth.c [rst, reported by Mark Cox]
+  *) Handle Addtype x/y .z [rst, reported by Cox]
+
+Changes with Shambhala 0.4.3
+
+  *) Fixed very dumb bug in mod_alias; "Alias" and "Redirect" are not
+     synonymous [rst, terbush]
+
+Changes with Shambhala 0.4.1                                     28 Jun 1995
+
+  *) First-cut virtual host implementation; some refit in the config
+     reading code, and log management, was necessary to support this [rst]
+  *) Sub-pool machinery, originally added to avoid excessive storage
+     allocation on listings of large directories (which turned out to
+     be the problem that the 0.3 storage accounting was added to
+     find).  Subrequests and mod_dir changed to use subpools.  [rst]
+  *) More memory debugging --- free list consistency checks. [rst]
+  *) Added err_headers to request_rec, with support elsewhere [rst]
+  *) Other fixes to minor bugs in mod_dir and mod_includes [rst, terbush]
+
+Changes with Shambhala 0.3                                       19 Jun 1995
+
+  *) Switch ONE_PROCESS to a runtime command-line option (-X)
+  *) Don't compile in mod_ai_backcompat by default
+  *) Switch name of server from Apache to Shambhala in Makefile
+  *) Add some accounting routines to track memory usage in the pools,
+     for debugging
+
+Changes with Shambhala 0.2
+
+  *) Set DOCUMENT_ROOT CGI variable
+  *) Add single-process debugging, as a compile-time option (ONE_PROCESS)
+  *) Add critical section protection to handling of cleanup structures 
+     in alloc.c [rst]
+  *) Significant code reorg within the server core to group related
+     functions together [rst]
+  *) Correctly handle clients that hang up before sending any request
+     [rst]
+  *) Replace dying child processes. [rst]
+
+Changes with Shambhala 0.1                                       12 Jun 1995
+
+   Major rewrite of the pre-existing "patchy server" codebase, by
+   Robert Thau (rst).  Significant portions of the server code, such
+   as configuration-file handling and HTTP authentication support,
+   were ripped out and rewritten from scratch.  Code that was not
+   completely rewritten was significantly altered.
+
+   Major changes with this release include:
+
+   *) Introduction of the module API; in request handling, the central 
+      machinery just dispatches to various modules, which actually do
+      most of the work.  Configuration handling is similar --- modules
+      declare their own commands, and the central machinery just
+      dispatches to them.  
+
+      API features from shambhala/0.1 were substantially unchanged in
+      Apache 1.0 and 1.1.  (1.0 API features not yet present in this
+      release, such as wildcard handlers and subpools, were added in
+      subsequent Shambhala releases, and were also generally rst's
+      work). 
+
+   *) This release included the following modules:
+
+      mod_access      (access control --- allow and deny directives),
+      mod_alias       (Alias and Redirect commands),
+      mod_auth        (straight HTTP authentication, based on flat-files)
+      mod_auth_dbm    (same, with dbm files)
+      mod_cgi         (CGI scripts and, in this release, ScriptAlias)
+      mod_common_log  (CLF access logs; later renamed mod_log_common)
+      mod_dir         (directory indexing)
+      mod_include     (server-side includes)
+      mod_mime        (AddType directives)
+      mod_negotiation (content negotiation)
+      mod_userdir     (support for users' public_html directories)
+
+      It also included a mod_ai_backcompat, which was a private hack
+      for back-compatibility with rst's own AI-lab servers.
+
+      All of these modules were substantially complete, and functional 
+      or nearly so (a few, which implemented features not in use at
+      Thau's site, required patches of a few lines).
+
+   *) sub-request machinery, to allow modules to determine how other
+      modules would assign MIME types to a given file, or optionally
+      serve its content (this is heavily used by mod_dir, mod_include
+      and mod_negotiation).
+
+   *) Resource pool system for keeping track of memory allocated and
+      files opened in service of a particular request.  Much of the
+      code in the modules (when they weren't rewrites) was adjusted to 
+      replace a pervasive convention of using fixed-size buffers on
+      the stack with an equally pervasive convention of using memory
+      allocated with palloc().
+
+   *) Reorganization of data structures associated with a given
+      request to eliminate use of global variables and the troublesome 
+      unmunge_name function (used in NCSA and early Apache releases to 
+      attempt to determine the URI which mapped to a given filename
+      --- a difficult proposition, given that it is easy to produce
+      setups in which multiple URIs map to the same file).
+
+   *) Source files renamed and rearranged
+
+   *) Very simple pre-forking behavior --- parent process forked off a 
+      fixed number of children, and then just waited for SIGHUP.
+
+   *) Other more minor changes too numerous to list.
+
+   This release included modified versions of a lot of code from the
+   Apache 0.6.4 public release, plus an early pre-forking patch
+   codeveloped by Robert Thau and Rob Hartill.
+
+Changes with Apache 0.7.3                                        20 Jun 1995
+
+   *) There were a bunch of changes between Apache 0.6.4 and 0.7.3 that
+      were incorporated by Rob Hartill on the main branch while Robert Thau
+      worked on the Shambhala rewrite above.  Most were merged into the
+      Shambala architecture after Apache 0.8.0.
+
+Changes with Apache 0.6.4                                        13 May 1995
+
+   *) Patches by Rob Hartill, Cliff Skolnick, Randy Terbush, Robert Thau,
+      and others.
+
+Changes with Apache 0.5.1                                        10 Apr 1995
+
+Changes with Apache 0.4                                          02 Apr 1995
+
+  *) Patches by Brian Behlendorf, Andrew Wilson, Robert Thau,
+     and Rob Hartill.
+
+Changes with Apache 0.3                                          24 Mar 1995
+
+  *) Patches by Robert Thau, David Robinson, Rob Hartill, and
+     Carlos Varela.
+
+Changes with Apache 0.2                                          18 Mar 1995
+
+  *) Based on NCSA httpd 1.3 by Rob McCool and patches by CERT,
+     Roy Fielding, Robert Thau, Nicolas Pioch, David Robinson,
+     Brian Behlendorf, Rob Hartill, and Cliff Skolnick.
diff --git a/trunk/INSTALL b/trunk/INSTALL
new file mode 100644
index 0000000000..7a17d3675b
--- /dev/null
+++ b/trunk/INSTALL
@@ -0,0 +1,91 @@
+
+  APACHE INSTALLATION OVERVIEW
+
+  Quick Start - Unix
+  ------------------
+
+  For complete installation documentation, see [ht]docs/manual/install.html or
+  http://httpd.apache.org/docs-2.1/install.html
+
+     $ ./configure --prefix=PREFIX
+     $ make
+     $ make install
+     $ PREFIX/bin/apachectl start
+
+     NOTES: * Replace PREFIX with the filesystem path under which 
+              Apache should be installed.  A typical installation
+              might use "/usr/local/apache2" for PREFIX (without the
+              quotes).
+
+            * If you are building on FreeBSD, be aware that threads will
+              be disabled and the prefork MPM will be used by default,
+              as threads do not work well with Apache on FreeBSD.  If
+              you wish to try a threaded Apache on FreeBSD anyway, use
+              "./configure --enable-threads".
+
+            * If you are building on Mac OS X (Darwin), make sure to
+              use libtool 1.4.2 or newer.
+
+            * If you are a developer building Apache directly from CVS,
+              you will need to run ./buildconf before running configure.
+
+  For a short impression of what possibilities you have, here is a
+  typical example which configures Apache for the installation tree
+  /sw/pkg/apache with a particular compiler and flags plus the two
+  additional modules mod_rewrite and mod_speling for later loading
+  through the DSO mechanism:
+
+     $ CC="pgcc" CFLAGS="-O2" \
+     ./configure --prefix=/sw/pkg/apache \
+     --enable-rewrite=shared \
+     --enable-speling=shared 
+
+  The easiest way to find all of the configuration flags for Apache 2.1
+  is to run ./configure --help.
+
+
+  Quick Start - Windows
+  ---------------------
+
+  For complete documentation, see [ht]docs/manual/platform/windows.html or
+  http://httpd.apache.org/docs-2.1/platform/windows.html.
+
+  The Apache/Win32 binaries are primarily distributed as a Windows Installer 
+  package (.msi), and may be available as a .zip file as well.  These packages 
+  are named apache-2.1.xx-win32-x86.msi and apache-2.1.xx-win32-x86.zip.  
+  Please choose the .msi package if at all possible.
+
+  If you have unpacked a source distribution (named httpd-2.1-xx.zip, without
+  any -win32-x86 notation) you must compile the package yourself, see the links
+  mentioned above.  Unless you intended to do this, please look again for the 
+  binary package from http://www.apache.org/dist/httpd/binaries/win32/ and
+  install that .msi (or .zip package, if you must.)
+
+  If you have unpacked this binary distribution from the .zip package, you 
+  _must_ edit the conf/httpd.conf file (with notepad or another text editor) 
+  to reflect the correct ServerName, Domain, and directory paths.  Search for 
+  the text "@@" to discover what you must edit.  To install and start the 
+  service after you have corrected the httpd.conf file, use the command
+
+    bin\Apache -k install
+    bin\Apache -k start
+
+  The .msi package configures the httpd.conf file, and installs and starts 
+  the Apache2 service for you.  It also installs plenty of useful shortcuts
+  and the taskbar ApacheMonitor.  We strongly encourage you to use it.
+
+
+  Postscript
+  ----------
+
+  The Apache HTTP Server group cannot field user's installation questions.
+  There are many valuable forums to help you get started.  Please refer your
+  questions to the appropriate forum, such as the Users Mailing List at
+  http://httpd.apache.org/userslist.html or the usenet newsgroups
+  comp.infosystems.www.servers.unix or
+  comp.infosystems.www.servers.ms-windows.
+
+  Thanks for using the Apache HTTP Server, version 2.1.
+
+                                     The Apache Software Foundation
+                                     http://www.apache.org/
diff --git a/trunk/InstallBin.dsp b/trunk/InstallBin.dsp
new file mode 100644
index 0000000000..258b88cafe
--- /dev/null
+++ b/trunk/InstallBin.dsp
@@ -0,0 +1,109 @@
+# Microsoft Developer Studio Project File - Name="InstallBin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=InstallBin - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "InstallBin.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "InstallBin.mak" CFG="InstallBin - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "InstallBin - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "InstallBin - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF  "$(CFG)" == "InstallBin - Win32 Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f InstallBin.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "\Apache21\bin\httpd.exe"
+# PROP BASE Bsc_Name "InstallBin.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache21" SHORT=R LONG=Release _install"
+# PROP Rebuild_Opt ""
+# PROP Target_File "\Apache21\bin\httpd.exe"
+# PROP Bsc_Name "Browse\httpd.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF  "$(CFG)" == "InstallBin - Win32 Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f InstallBin.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "\Apache21\bin\httpd.exe"
+# PROP BASE Bsc_Name "InstallBin.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line "NMAKE /f makefile.win INSTDIR="\Apache21" SHORT=D LONG=Debug _install"
+# PROP Rebuild_Opt ""
+# PROP Target_File "\Apache21\bin\httpd.exe"
+# PROP Bsc_Name ""
+# PROP Target_Dir ""
+
+!ENDIF 
+
+# Begin Target
+
+# Name "InstallBin - Win32 Release"
+# Name "InstallBin - Win32 Debug"
+
+!IF  "$(CFG)" == "InstallBin - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "InstallBin - Win32 Debug"
+
+!ENDIF 
+
+# Begin Source File
+
+SOURCE=..\logs\access.log
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\win32\BaseAddr.ref
+# End Source File
+# Begin Source File
+
+SOURCE=.\CHANGES
+# End Source File
+# Begin Source File
+
+SOURCE=..\logs\error.log
+# End Source File
+# Begin Source File
+
+SOURCE=..\conf\httpd.conf
+# End Source File
+# Begin Source File
+
+SOURCE=.\Makefile.win
+# End Source File
+# Begin Source File
+
+SOURCE=..\STATUS
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/LAYOUT b/trunk/LAYOUT
new file mode 100644
index 0000000000..8385e67f0f
--- /dev/null
+++ b/trunk/LAYOUT
@@ -0,0 +1,201 @@
+The httpd-2.1 Source Tree LAYOUT
+--------------------------------
+
+./ .................... Top-Level httpd-2.1 Root Directory
+
+  ABOUT_APACHE .......... Overview of the Apache HTTP Server
+  LAYOUT ................ This file describing the source tree
+  README ................ Overview of this distribution
+  STATUS ................ Current project activity and commentary
+
+build/ ................ Supporting tools for buildconf/configure
+
+  win32/ ................ Supporting tools for Win32 MSVC builds
+
+docs/ ................. Documentation and Examples
+
+  cgi-examples/ ......... 
+
+  conf/ ................. 
+
+  docroot/ .............. 
+
+  error/ ................ 
+
+    include/ .............. 
+
+  icons/ ................ 
+
+    small/ ................ 
+
+  man/ .................. 
+
+  manual/ ............... 
+
+    developer/ ............ 
+
+    faq/ .................. 
+
+    howto/ ................ 
+
+    images/ ............... 
+
+    misc/ ................. 
+
+    mod/ .................. 
+
+    platform/ ............. 
+
+    programs/ ............. 
+
+    search/ ............... 
+
+    ssl/ .................. 
+
+    style/ ................ 
+
+    vhosts/ ............... 
+
+include/ ................ 
+
+modules/ ................ Manditory and Add-In Apache stock modules
+
+  aaa/ .................... 
+
+  arch/ ................... 
+
+    netware/ ................ 
+
+    win32/ .................. 
+
+  cache/ .................. 
+
+  dav/ .................... 
+
+    fs/ ..................... 
+
+    main/ ................... 
+
+  echo/ ................... 
+
+  experimental/ ........... 
+
+  filters/ ................ 
+
+  generators/ ............. 
+
+  http/ ................... HTTP: protocol module
+
+  loggers/ ................ 
+
+  mappers/ ................ 
+
+  metadata/ ............... 
+
+  pop3/ ...................
+
+  private/ ................
+
+  proxy/ ..................
+
+  ssl/ .................... HTTPS: SSL v2/v3 and TLS v1 protocol module
+
+    README .................. Overview of mod_ssl
+    README.dsov.fig ......... Overview diagram of mod_ssl design
+    README.dsov.ps .......... Overview diagram of mod_ssl design
+    Makefile.in ............. Makefile template for Unix platform
+    config.m4 ............... Autoconf stub for the Apache config mechanism
+    mod_ssl.c ............... main source file containing API structures
+    mod_ssl.h ............... common header file of mod_ssl
+    ssl_engine_config.c ..... module configuration handling
+    ssl_engine_dh.c ......... DSA/DH support
+    ssl_engine_init.c ....... module initialization
+    ssl_engine_io.c ......... I/O support
+    ssl_engine_kernel.c ..... SSL engine kernel
+    ssl_engine_log.c ........ logfile support
+    ssl_engine_mutex.c ...... mutual exclusion support
+    ssl_engine_pphrase.c .... pass-phrase handling
+    ssl_engine_rand.c ....... PRNG support
+    ssl_engine_vars.c ....... Variable Expansion support
+    ssl_expr.c .............. expression handling main source
+    ssl_expr.h .............. expression handling common header
+    ssl_expr_scan.c ......... expression scanner automaton (pre-generated)
+    ssl_expr_scan.l ......... expression scanner source
+    ssl_expr_parse.c ........ expression parser automaton  (pre-generated)
+    ssl_expr_parse.h ........ expression parser header     (pre-generated)
+    ssl_expr_parse.y ........ expression parser source
+    ssl_expr_eval.c ......... expression machine evaluation
+    ssl_scache.c ............ session cache abstraction layer
+    ssl_scache_dbm.c ........ session cache via DBM file
+    ssl_scache_shmcb.c ...... session cache via shared memory cyclic buffer
+    ssl_scache_dc.c ......... session cache offloading via 'distcache'
+    ssl_util.c .............. utility functions
+    ssl_util_ssl.c .......... the OpenSSL companion source
+    ssl_util_ssl.h .......... the OpenSSL companion header
+    ssl_util_table.c ........ the hash table library source
+    ssl_util_table.h ........ the hash table library header
+
+  test/ ................... not distributed with released source tarballs
+
+os/ ..................... 
+
+  beos/ ................... 
+
+  bs2000/ ................. 
+
+  netware/ ................ 
+
+  os2/ .................... 
+
+  tpf/ .................... 
+
+    samples/ ................ 
+
+  unix/ ................... 
+
+  win32/ .................. 
+
+server/ ................. 
+
+  mpm/ .................... 
+
+    beos/ ................... 
+
+    experimental/ ........... 
+
+      leader/ ................. 
+
+      perchild/ ............... 
+
+      threadpool/ ............. 
+
+    mpmt_os2/ ............... 
+
+    netware/ ................ 
+
+    prefork/ ................ 
+
+    winnt/ .................. 
+
+    worker/ ................. 
+
+srclib/ ................... Additional Libraries
+
+  apr/ ...................... SEE srclib/apr/LAYOUT
+
+  apr-util/ ................. SEE srclib/apr/LAYOUT
+
+  pcre/ ..................... 
+
+    doc/ ...................... 
+
+    testdata/ ................. 
+
+support/ ................ Sources for Support Binaries
+
+  SHA1/ .................. Ancient SHA1 password conversion utilities
+
+  win32/ ................. Win32-only Support Applications
+
+test/ ................... not distributed with released source tarballs
+
diff --git a/trunk/LICENSE b/trunk/LICENSE
new file mode 100644
index 0000000000..c47d2d99c7
--- /dev/null
+++ b/trunk/LICENSE
@@ -0,0 +1,673 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+APACHE HTTP SERVER SUBCOMPONENTS: 
+
+The Apache HTTP Server includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses. 
+
+For the mod_mime_magic component:
+
+/*
+ * mod_mime_magic: MIME type lookup via file magic numbers
+ * Copyright (c) 1996-1997 Cisco Systems, Inc.
+ *
+ * This software was submitted by Cisco Systems to the Apache Group in July
+ * 1997.  Future revisions and derivatives of this source code must
+ * acknowledge Cisco Systems as the original contributor of this module.
+ * All other licensing and usage conditions are those of the Apache Group.
+ *
+ * Some of this code is derived from the free version of the file command
+ * originally posted to comp.sources.unix.  Copyright info for that program
+ * is included below as required.
+ * ---------------------------------------------------------------------------
+ * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone and
+ * Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on any
+ * computer system, and to alter it and redistribute it freely, subject to
+ * the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission.  Since few users ever read sources, credits
+ * must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.  Since few users ever read
+ * sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ * -------------------------------------------------------------------------
+ *
+ */
+
+
+For the  modules\mappers\mod_imap.c component:
+
+  "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
+
+For the  server\util_md5.c component:
+
+/************************************************************************
+ * NCSA HTTPd Server
+ * Software Development Group
+ * National Center for Supercomputing Applications
+ * University of Illinois at Urbana-Champaign
+ * 605 E. Springfield, Champaign, IL 61820
+ * httpd@ncsa.uiuc.edu
+ *
+ * Copyright  (C)  1995, Board of Trustees of the University of Illinois
+ *
+ ************************************************************************
+ *
+ * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
+ *
+ *  Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
+ *  Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
+ *     University (see Copyright below).
+ *  Portions of Content-MD5 code Copyright (C) 1991 Bell Communications 
+ *     Research, Inc. (Bellcore) (see Copyright below).
+ *  Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
+ *  Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
+ *
+ */
+
+
+/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
+/* (C) Copyright 1993,1994 by Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ *
+ * Permission to use, copy, modify, and distribute this material
+ * for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice
+ * appear in all copies, and that the name of Bellcore not be
+ * used in advertising or publicity pertaining to this
+ * material without the specific, prior written permission
+ * of an authorized representative of Bellcore.  BELLCORE
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
+ */
+
+For the  srclib\apr\include\apr_md5.h component: 
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+
+For the  srclib\apr\passwd\apr_md5.c component:
+
+/*
+ * This is work is derived from material Copyright RSA Data Security, Inc.
+ *
+ * The RSA copyright statement and Licence for that original material is
+ * included below. This is followed by the Apache copyright statement and
+ * licence for the modifications made to that material.
+ */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is"
+   without express or implied warranty of any kind.
+
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+ */
+/*
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
+ * MD5 crypt() function, which is licenced as follows:
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.  Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ */
+
+For the srclib\apr-util\crypto\apr_md4.c component:
+
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\include\apr_md4.h component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+For the srclib\apr-util\test\testdbm.c component:
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  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. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * This file came from the SDBM package (written by oz@nexus.yorku.ca).
+ * That package was under public domain. This file has been ported to
+ * APR, updated to ANSI C and other, newer idioms, and added to the Apache
+ * codebase under the above copyright and license.
+ */
+
+
+For the srclib\apr-util\test\testmd4.c component:
+
+ *
+ * This is derived from material copyright RSA Data Security, Inc.
+ * Their notice is reproduced below in its entirety.
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+ * rights reserved.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+For the srclib\apr-util\xml\expat\conftools\install-sh component:
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+
+For the srclib\pcre\install-sh component:
+
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+For the pcre component:
+
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 5 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2004 University of Cambridge
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
+
+End PCRE LICENCE
+
+
+For the test\zb.c component:
+
+/*                          ZeusBench V1.01
+			    ===============
+
+This program is Copyright (C) Zeus Technology Limited 1996.
+
+This program may be used and copied freely providing this copyright notice
+is not removed.
+
+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.
+
+     Written by Adam Twiss (adam@zeus.co.uk).  March 1996
+
+Thanks to the following people for their input:
+  Mike Belshe (mbelshe@netscape.com) 
+  Michael Campanella (campanella@stevms.enet.dec.com)
+
+*/
+
+For the expat xml parser component:
+
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+	
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+	
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====================================================================
diff --git a/trunk/Makefile.in b/trunk/Makefile.in
new file mode 100644
index 0000000000..6d8348d9f4
--- /dev/null
+++ b/trunk/Makefile.in
@@ -0,0 +1,212 @@
+
+SUBDIRS = srclib os server modules support
+CLEAN_SUBDIRS = test
+
+PROGRAM_NAME         = $(progname)
+PROGRAM_SOURCES      = modules.c
+PROGRAM_LDADD        = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
+PROGRAM_PRELINK      = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
+PROGRAM_DEPENDENCIES = \
+  server/libmain.la \
+  $(BUILTIN_LIBS) \
+  $(MPM_LIB) \
+  os/$(OS_DIR)/libos.la
+
+PROGRAMS        = $(PROGRAM_NAME)
+TARGETS         = $(PROGRAMS) $(shared_build) $(other_targets)
+INSTALL_TARGETS = install-conf install-htdocs install-error install-icons \
+	install-other install-cgi install-include install-suexec install-build \
+	install-man
+
+DISTCLEAN_TARGETS  = include/ap_config_auto.h include/ap_config_layout.h \
+	modules.c config.cache config.log config.status build/config_vars.mk \
+	build/rules.mk docs/conf/httpd-std.conf docs/conf/ssl-std.conf shlibtool
+EXTRACLEAN_TARGETS = configure include/ap_config_auto.h.in generated_lists \
+	httpd.spec
+
+include $(top_builddir)/build/rules.mk
+include $(top_srcdir)/build/program.mk
+
+install-conf:
+	@echo Installing configuration files ; \
+	if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir) ; \
+	fi ; \
+	if [ ! -d $(DESTDIR)$(sysconfdir)/extra ]; then \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir)/extra ; \
+	fi ; \
+	if [ ! -d $(DESTDIR)$(sysconfdir)/original ]; then \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir)/original ; \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir)/original/extra ; \
+	fi ; \
+	cd $(top_srcdir)/docs/conf; \
+	for i in mime.types magic; do \
+	    if test ! -f $(DESTDIR)$(sysconfdir)/$$i; then \
+	        $(INSTALL_DATA) $$i $(DESTDIR)$(sysconfdir); \
+	    fi; \
+	done; \
+	for j in $(top_srcdir)/docs/conf $(top_builddir)/docs/conf ; do \
+	    cd $$j ; \
+	    for i in httpd.conf extra/httpd-*.conf; do \
+	    	( \
+	    		n_lm=`awk 'BEGIN {n=0} /@@LoadModule@@/ {n+=1} END {print n}' < $$i`; \
+	    		if test $$n_lm -eq 0 -o "x$(DSO_MODULES)" = "x"; then \
+	    			sed -e 's#@@ServerRoot@@#$(prefix)#g' \
+	    				-e 's#@@Port@@#$(PORT)#g' \
+	    				-e '/@@LoadModule@@/d' \
+	    				< $$i; \
+	    		else \
+	    			sed -n -e '/@@LoadModule@@/q' \
+	    				-e 's#@@ServerRoot@@#$(prefix)#g' \
+	    				-e 's#@@Port@@#$(PORT)#g' \
+	    				-e 'p' \
+	    				< $$i; \
+	    			for j in $(DSO_MODULES) "^EOL^"; do \
+	    				if test $$j != "^EOL^"; then \
+	    					echo "LoadModule $${j}_module $(rel_libexecdir)/mod_$${j}.so"; \
+	    				fi; \
+	    			done; \
+	    			sed -e '1,/@@LoadModule@@/d' \
+	    				-e '/@@LoadModule@@/d' \
+	    				-e 's#@@ServerRoot@@#$(prefix)#g' \
+	    				-e 's#@@Port@@#$(PORT)#g' \
+	    				< $$i; \
+	    		fi \
+	    	) > $(DESTDIR)$(sysconfdir)/original/$$i; \
+	    	chmod 0644 $(DESTDIR)$(sysconfdir)/original/$$i; \
+		file=$$i; \
+	    	if [ "$$i" = "httpd.conf" ]; then \
+	    		file=`echo $$i|sed s/.*.conf/$(PROGRAM_NAME).conf/`; \
+	    	fi; \
+	    	if test ! -f $(DESTDIR)$(sysconfdir)/$$file; then \
+	    		$(INSTALL_DATA) $(DESTDIR)$(sysconfdir)/original/$$i $(DESTDIR)$(sysconfdir)/$$file; \
+	    	fi; \
+	    done ; \
+	done ; \
+	if test -f "$(builddir)/envvars-std"; then \
+	    cp -p envvars-std $(DESTDIR)$(sbindir); \
+	    if test ! -f $(DESTDIR)$(sbindir)/envvars; then \
+	        cp -p envvars-std $(DESTDIR)$(sbindir)/envvars ; \
+	    fi ; \
+	fi
+
+install-build:
+	@echo Installing build system files 
+	@test -d $(DESTDIR)$(installbuilddir) || $(MKINSTALLDIRS) $(DESTDIR)$(installbuilddir) 
+	@cp $(top_srcdir)/build/*.mk $(DESTDIR)$(installbuilddir); \
+	cp build/*.mk $(DESTDIR)$(installbuilddir); \
+	sed "/^LIBTOOL/s#/[^ ]*/libtool \(.*\)#`$(APR_CONFIG) --apr-libtool` $(LTFLAGS)#" \
+	    build/config_vars.mk > $(DESTDIR)$(installbuilddir)/config_vars.mk; \
+	cp $(top_srcdir)/build/instdso.sh $(DESTDIR)$(installbuilddir); \
+	cp $(top_builddir)/config.nice $(DESTDIR)$(installbuilddir);
+
+htdocs-srcdir = $(top_srcdir)/docs/docroot
+
+docs::
+	mkdir -p ./docs/api
+	srclib/apr/build/scandoc.pl -i./build/default.pl -p./docs/api/ ./include/*.h
+
+dox::
+	doxygen $(top_srcdir)/docs/doxygen.conf
+
+install-htdocs:
+	-@if [ -d $(DESTDIR)$(htdocsdir) ]; then \
+           echo "[PRESERVING EXISTING HTDOCS SUBDIR: $(DESTDIR)$(htdocsdir)]"; \
+        else \
+	    echo Installing HTML documents ; \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(htdocsdir) ; \
+	    test -d $(htdocs-srcdir) && (cd $(htdocs-srcdir) && cp -rp * $(DESTDIR)$(htdocsdir)) ; \
+	    cd $(DESTDIR)$(htdocsdir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null || true; \
+	fi
+
+install-error:
+	-@if [ -d $(DESTDIR)$(errordir) ]; then \
+           echo "[PRESERVING EXISTING ERROR SUBDIR: $(DESTDIR)$(errordir)]"; \
+        else \
+	    echo Installing error documents ; \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(errordir) ; \
+	    cd $(top_srcdir)/docs/error && cp -rp * $(DESTDIR)$(errordir) ; \
+	    test "x$(errordir)" != "x" && cd $(DESTDIR)$(errordir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null || true; \
+	fi
+
+install-icons:
+	-@if [ -d $(DESTDIR)$(iconsdir) ]; then \
+           echo "[PRESERVING EXISTING ICONS SUBDIR: $(DESTDIR)$(iconsdir)]"; \
+        else \
+	    echo Installing icons ; \
+	    $(MKINSTALLDIRS) $(DESTDIR)$(iconsdir) ; \
+	    cd $(top_srcdir)/docs/icons && cp -rp * $(DESTDIR)$(iconsdir) ; \
+	    test "x$(iconsdir)" != "x" && cd $(DESTDIR)$(iconsdir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null || true; \
+	fi
+
+install-cgi:
+	-@if [ -d $(DESTDIR)$(cgidir) ];then \
+	    echo "[PRESERVING EXISTING CGI SUBDIR: $(DESTDIR)$(cgidir)]"; \
+	else \
+	   echo Installing CGIs ; \
+	   $(MKINSTALLDIRS) $(DESTDIR)$(cgidir) ; \
+	   cd $(top_srcdir)/docs/cgi-examples && cp -rp * $(DESTDIR)$(cgidir) ; \
+	   test "x$(cgidir)" != "x" && cd $(DESTDIR)$(cgidir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null || true; \
+	fi
+
+install-other:
+	@test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir)
+	@test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir)
+	@for ext in dll x; do \
+		file=apachecore.$$ext; \
+		if test -f $$file; then \
+			cp -p $$file $(DESTDIR)$(libdir); \
+		fi; \
+	done; \
+	file=httpd.dll; \
+	if test -f $$file; then \
+		cp -p $$file $(DESTDIR)$(bindir); \
+	fi;
+
+install-include:
+	@echo Installing header files
+	@test -d $(DESTDIR)$(includedir) || $(MKINSTALLDIRS) $(DESTDIR)$(includedir)
+	@cp -p include/*.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/include/*.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/os/$(OS_DIR)/os.h $(DESTDIR)$(includedir)
+	@if test -f $(srcdir)/os/$(OS_DIR)/os-inline.c; then \
+            cp -p $(srcdir)/os/$(OS_DIR)/os-inline.c $(DESTDIR)$(includedir); \
+        fi;
+	@cp -p $(srcdir)/server/mpm/$(MPM_SUBDIR_NAME)/*.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/aaa/mod_auth.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/dav/main/mod_dav.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/filters/mod_include.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/generators/mod_cgi.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/generators/mod_status.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/loggers/mod_log_config.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/http/mod_core.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/proxy/mod_proxy.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/modules/ssl/mod_ssl.h $(DESTDIR)$(includedir)
+	@cp -p $(srcdir)/os/$(OS_DIR)/*.h $(DESTDIR)$(includedir)
+	@chmod 644 $(DESTDIR)$(includedir)/*.h
+
+install-man:
+	@echo Installing man pages and online manual
+	@test -d $(DESTDIR)$(mandir)      || $(MKINSTALLDIRS) $(DESTDIR)$(mandir)
+	@test -d $(DESTDIR)$(mandir)/man1 || $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man1
+	@test -d $(DESTDIR)$(mandir)/man8 || $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man8
+	@test -d $(DESTDIR)$(manualdir)   || $(MKINSTALLDIRS) $(DESTDIR)$(manualdir)
+	@cp -p $(top_srcdir)/docs/man/*.1 $(DESTDIR)$(mandir)/man1
+	@cp -p $(top_srcdir)/docs/man/*.8 $(DESTDIR)$(mandir)/man8
+	@(cd $(top_srcdir)/docs/manual && cp -rp * $(DESTDIR)$(manualdir))
+	@(cd $(DESTDIR)$(manualdir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null ) || true
+
+install-suexec:
+	@if test -f $(builddir)/support/suexec; then \
+            test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir); \
+            $(INSTALL_PROGRAM) $(top_builddir)/support/suexec $(DESTDIR)$(sbindir); \
+            chmod 4755 $(DESTDIR)$(sbindir)/suexec; \
+	fi
+
+suexec:
+	cd support && $(MAKE) suexec
+
+x-local-distclean:
+	@rm -rf autom4te.cache
+
+include $(top_srcdir)/os/os2/core.mk
diff --git a/trunk/Makefile.win b/trunk/Makefile.win
new file mode 100644
index 0000000000..c6b090cee9
--- /dev/null
+++ b/trunk/Makefile.win
@@ -0,0 +1,804 @@
+# Makefile for Windows NT and Windows 95/98/2000
+
+# Targets are:
+#   _apacher   - build Apache in Release mode
+#   _apached   - build Apache in Debug mode
+#   installr   - build and install a Release build
+#   installd   - build and install a Debug build
+#   clean      - remove (most) generated files
+#   _cleanr    - remove (most) files generated by a Release build
+#   _cleand    - remove (most) files generated by a Debug build
+#   _browse    - build the browse info file
+#
+# The following install defaults may be customized;
+#
+#   Option      Default
+#   INSTDIR     \Apache2
+#   PORT        80
+#   SERVERNAME  localhost
+#
+# For example;
+#
+#   nmake /f Makefile.win PORT=80 INSTDIR="d:\Program Files\Apache" installr
+#
+# Be aware that certain awk's will not accept backslahed names,
+# so the server root should be given in forward slashes (quoted),
+# preferably with the drive designation!
+
+default: _apacher
+
+!IF ("$(CTARGET)" == "") && EXIST("Apache.sln")
+CTARGET=/build
+!ENDIF
+
+!IF !EXIST("srclib\apr") || !EXIST("srclib\apr-util") || !EXIST("srclib\apr-iconv")
+!MESSAGE Please check out or download and unpack the Apache Portability Runtime
+!MESSAGE sources (apr, apr-iconv and apr-util) into your $(INSTDIR)\srclib dir.
+!MESSAGE Apache cannot build without these libraries!
+!MESSAGE 
+!ERROR Need $(INSTDIR)\srclib\  apr, apr-iconv and apr-util
+!ENDIF
+
+# Note; _tryssl: is only used by the msvc developer studio environment to 'fix up'
+#	the build, since conditional dependencies aren't supported.
+#
+!IF EXIST("srclib\openssl")
+!IF "$(LONG)" == "Debug"
+SSLBIN=out32dll.dbg
+!ELSE
+SSLBIN=out32dll
+!ENDIF
+
+_tryssl:
+!IF EXIST("modules\ssl\mod_ssl.mak")
+	cd modules\ssl
+	$(MAKE) $(MAKEOPT) -f mod_ssl.mak CFG="mod_ssl - Win32 $(LONG)" RECURSE=0 .\$(LONG)\mod_ssl.so
+	cd ..\..
+	cd support
+	$(MAKE) $(MAKEOPT) -f abs.mak CFG="abs - Win32 $(LONG)" RECURSE=0 .\$(LONG)\abs.exe
+	cd ..
+!ELSEIF EXIST("Apache.sln")
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project mod_ssl
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project abs
+!ELSE
+	@msdev Apache.dsw /USEENV /MAKE \
+		"mod_ssl - Win32 $(LONG)" \
+		"abs - Win32 $(LONG)" /NORECURSE $(CTARGET)
+!ENDIF
+
+!ELSE
+#     NOT EXIST("srclib\openssl")
+
+_tryssl:
+	@echo -----
+	@echo mod_ssl and ab/ssl will not build unless openssl is installed
+	@echo in srclib\openssl.  They must be precompiled using the 
+	@echo ms/ntdll.mak file, see srclib\openssl\INSTALL.W32.  The most
+	@echo recent version confirmed to build with mod_ssl and ab is 0.9.6h.
+	@echo Available from http://www.openssl.org/
+!ENDIF
+
+!IF EXIST("srclib\zlib")
+
+_tryzlib:
+!IF EXIST("modules\filters\mod_deflate.mak")
+	cd modules\filters
+	$(MAKE) $(MAKEOPT) -f mod_deflate.mak CFG="mod_deflate - Win32 $(LONG)" RECURSE=0 .\$(LONG)\mod_deflate.so
+	cd ..\..
+!ELSEIF EXIST("Apache.sln")
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project mod_deflate
+!ELSE
+	@msdev Apache.dsw /USEENV /MAKE \
+		"mod_deflate - Win32 $(LONG)" /NORECURSE $(CTARGET)
+!ENDIF
+
+!ELSE
+#     NOT EXIST("srclib\zlib")
+
+_tryzlib:
+	@echo -----
+	@echo mod_deflate will not build unless zlib is installed in srclib\zlib.  
+	@echo Version 1.2.1 and later available from http://www.gzip.org/zlib/
+	@echo built w/ nmake -f win32/Makefile.msc will satisfy this requirement.
+
+!ENDIF
+
+!IF "$(INSTDIR)" == ""
+INSTDIR=\Apache2
+!ENDIF
+!IF "$(SERVERNAME)" == ""
+SERVERNAME=localhost
+!ENDIF
+!IF "$(PORT)" == ""
+PORT=80
+!ENDIF 
+
+!IF "$(LONG)" == ""
+!MESSAGE
+!MESSAGE INSTDIR    = $(INSTDIR)
+!MESSAGE SERVERNAME = $(SERVERNAME)
+!MESSAGE PORT       = $(PORT)
+!MESSAGE
+!MESSAGE To change these options use 'nmake /f Makefile.win [option=value]'
+!MESSAGE Example: nmake /f Makefile.win PORT=8080
+!MESSAGE
+!MESSAGE
+!ENDIF
+
+!IFNDEF MAKEOPT
+# Only default the behavior if MAKEOPT= is omitted
+!IF "$(MAKE)" == "NMAKE"
+# Microsoft NMake options
+MAKEOPT=-nologo
+!ELSEIF "($MAKE)" == "make"
+# Borland make options?  Not really supported (yet)
+MAKEOPT=-s -N
+!ENDIF
+!ENDIF
+
+_dummy:
+
+_browse:
+	cd Browse
+	  bscmake.exe -nologo -Iu -o Apache.bsc *.sbr
+	cd ..
+
+_apacher: 
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release _build
+
+_apached: 
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=D LONG=Debug   _build
+
+installr: 
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release _build _install
+
+installd: 
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=D LONG=Debug   _build _install
+
+clean:	_cleanr _cleand
+	-if exist Browse\. rd /s Browse < << > nul
+y
+<<
+
+!IF EXIST("httpd.mak")
+
+_cleanr:
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release CTARGET=CLEAN _build
+
+_cleand:  
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=D LONG=Debug   CTARGET=CLEAN _build
+
+_build:
+	echo Building Win32 $(LONG) targets ($(SHORT) suffixes)
+	cd srclib\apr
+	 $(MAKE) $(MAKEOPT) -f apr.mak             CFG="apr - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f libapr.mak          CFG="libapr - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd srclib\apr-iconv
+	 $(MAKE) $(MAKEOPT) -f apriconv.mak  CFG="apriconv - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f libapriconv.mak  CFG="libapriconv - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+!IF "$(CTARGET)" == "CLEAN"
+	$(MAKE) $(MAKEOPT) /f build\modules.mk.win clean \
+		BUILD_MODE=$(LONG) BIND_MODE=shared API_SOURCE=.
+!ELSE
+	cd ccs
+	$(MAKE) /nologo /f Makefile.win all \
+		BUILD_MODE=$(LONG) BIND_MODE=shared
+	cd ..\ces
+	$(MAKE) /nologo /f Makefile.win all \
+		BUILD_MODE=$(LONG) BIND_MODE=shared
+	cd ..
+!ENDIF
+	cd ..\..
+	cd srclib\apr-util\uri
+	 $(MAKE) $(MAKEOPT) -f gen_uri_delims.mak  CFG="gen_uri_delims - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..\..
+	cd srclib\apr-util\xml\expat\lib
+	 $(MAKE) $(MAKEOPT) -f xml.mak             CFG="xml - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..\..
+	 $(MAKE) $(MAKEOPT) -f aprutil.mak         CFG="aprutil - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f libaprutil.mak      CFG="libaprutil - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd srclib\pcre
+	 $(MAKE) $(MAKEOPT) -f dftables.mak        CFG="dftables - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f pcre.mak            CFG="pcre - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd server
+	 $(MAKE) $(MAKEOPT) -f gen_test_char.mak   CFG="gen_test_char - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..
+	 $(MAKE) $(MAKEOPT) -f libhttpd.mak        CFG="libhttpd - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f httpd.mak           CFG="httpd - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+# build ldap prior to authnz_ldap
+	cd modules\ldap
+	 $(MAKE) $(MAKEOPT) -f mod_ldap.mak        CFG="mod_ldap - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\aaa
+	 $(MAKE) $(MAKEOPT) -f mod_auth_basic.mak  CFG="mod_auth_basic - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_auth_digest.mak CFG="mod_auth_digest - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authn_anon.mak  CFG="mod_authn_anon - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authn_dbm.mak   CFG="mod_authn_dbm - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authn_default.mak CFG="mod_authn_default - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authn_file.mak  CFG="mod_authn_file - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authz_dbm.mak   CFG="mod_authz_dbm - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authz_default.mak CFG="mod_authz_default - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authz_groupfile.mak CFG="mod_authz_groupfile - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authz_host.mak  CFG="mod_authz_host - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authz_user.mak  CFG="mod_authz_user - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_authnz_ldap.mak CFG="mod_authnz_ldap - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\arch\win32
+	 $(MAKE) $(MAKEOPT) -f mod_isapi.mak       CFG="mod_isapi - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..\..
+	cd modules\cache
+	 $(MAKE) $(MAKEOPT) -f mod_cache.mak       CFG="mod_cache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_file_cache.mak  CFG="mod_file_cache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_mem_cache.mak   CFG="mod_mem_cache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_disk_cache.mak  CFG="mod_disk_cache - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\dav\main
+	 $(MAKE) $(MAKEOPT) -f mod_dav.mak         CFG="mod_dav - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..\..
+	cd modules\dav\fs
+	 $(MAKE) $(MAKEOPT) -f mod_dav_fs.mak      CFG="mod_dav_fs - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..\..
+	cd modules\debug
+	 $(MAKE) $(MAKEOPT) -f mod_bucketeer.mak   CFG="mod_bucketeer - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_dumpio.mak      CFG="mod_dumpio - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\experimental
+	 $(MAKE) $(MAKEOPT) -f mod_charset_lite.mak CFG="mod_charset_lite - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\filters
+!IF EXIST("srclib\zlib")
+	 $(MAKE) $(MAKEOPT) -f mod_deflate.mak     CFG="mod_deflate - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+!ENDIF
+	 $(MAKE) $(MAKEOPT) -f mod_ext_filter.mak  CFG="mod_ext_filter - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_include.mak     CFG="mod_include - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\generators
+	 $(MAKE) $(MAKEOPT) -f mod_asis.mak        CFG="mod_asis - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_autoindex.mak   CFG="mod_autoindex - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_cgi.mak         CFG="mod_cgi - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_info.mak        CFG="mod_info - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_status.mak      CFG="mod_status - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\http
+	 $(MAKE) $(MAKEOPT) -f mod_mime.mak        CFG="mod_mime - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\loggers
+	 $(MAKE) $(MAKEOPT) -f mod_log_config.mak  CFG="mod_log_config - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_log_forensic.mak CFG="mod_log_forensic - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_logio.mak       CFG="mod_logio - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\mappers
+	 $(MAKE) $(MAKEOPT) -f mod_actions.mak     CFG="mod_actions - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_alias.mak       CFG="mod_alias - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_dir.mak         CFG="mod_dir - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_imagemap.mak    CFG="mod_imagemap - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_negotiation.mak CFG="mod_negotiation - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_rewrite.mak     CFG="mod_rewrite - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_speling.mak     CFG="mod_speling - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_userdir.mak     CFG="mod_userdir - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_vhost_alias.mak CFG="mod_vhost_alias - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\metadata
+	 $(MAKE) $(MAKEOPT) -f mod_cern_meta.mak   CFG="mod_cern_meta - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_env.mak         CFG="mod_env - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_expires.mak     CFG="mod_expires - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_headers.mak     CFG="mod_headers - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_ident.mak       CFG="mod_ident - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_mime_magic.mak  CFG="mod_mime_magic - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_setenvif.mak    CFG="mod_setenvif - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_unique_id.mak   CFG="mod_unique_id - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_usertrack.mak   CFG="mod_usertrack - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_version.mak     CFG="mod_version - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+	cd modules\proxy
+	 $(MAKE) $(MAKEOPT) -f mod_proxy.mak       CFG="mod_proxy - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_proxy_ajp.mak   CFG="mod_proxy_ajp - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_proxy_balancer.mak  CFG="mod_proxy_balancer - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_proxy_connect.mak CFG="mod_proxy_connect - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_proxy_ftp.mak   CFG="mod_proxy_ftp - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f mod_proxy_http.mak  CFG="mod_proxy_http - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+!IF EXIST("srclib\openssl")
+	cd modules\ssl
+	 $(MAKE) $(MAKEOPT) -f mod_ssl.mak         CFG="mod_ssl - Win32 $(LONG)" RECURSE=0 $(CTARGET) .\$(LONG)\mod_ssl.so
+	cd ..\..
+	cd support
+	 $(MAKE) $(MAKEOPT) -f abs.mak             CFG="abs - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..
+!ENDIF
+	cd support
+	 $(MAKE) $(MAKEOPT) -f ab.mak              CFG="ab - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f htdbm.mak           CFG="htdbm - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f htdigest.mak        CFG="htdigest - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f htpasswd.mak        CFG="htpasswd - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f logresolve.mak      CFG="logresolve - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f rotatelogs.mak      CFG="rotatelogs - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..
+	cd support\win32
+	 $(MAKE) $(MAKEOPT) -f ApacheMonitor.mak   CFG="ApacheMonitor - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	 $(MAKE) $(MAKEOPT) -f wintty.mak          CFG="wintty - Win32 $(LONG)" RECURSE=0 $(CTARGET)
+	cd ..\..
+
+!ELSEIF EXIST("Apache.sln")
+
+_cleanr:  
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release CTARGET="/clean" _build
+
+_cleand:  
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=D LONG=Debug   CTARGET="/clean" _build
+
+_build:
+	echo Building Win32 $(LONG) targets ($(SHORT) suffixes)
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project BuildBin
+!IF EXIST("srclib\openssl")
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project mod_ssl
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project abs
+!ENDIF
+!IF EXIST("srclib\zlib")
+	devenv Apache.sln /useenv $(CTARGET) $(LONG) /project mod_deflate
+!ENDIF
+
+!ELSE
+
+_cleanr:  
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=R LONG=Release CTARGET="/CLEAN" _build
+
+_cleand:  
+	@$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=D LONG=Debug   CTARGET="/CLEAN" _build
+
+_build:
+	@echo Building Win32 $(LONG) targets ($(SHORT) suffixes)
+	@msdev Apache.dsw /USEENV /MAKE \
+		"BuildBin - Win32 $(LONG)" $(CTARGET)
+!IF "$(CTARGET)" == "/CLEAN"
+	@cd srclib\apr-iconv
+	@$(MAKE) $(MAKEOPT) /f build\modules.mk.win clean \
+		BUILD_MODE=$(LONG) BIND_MODE=shared API_SOURCE=.
+	@cd ..\..
+!ENDIF
+!IF EXIST("srclib\openssl")
+	@msdev Apache.dsw /USEENV /MAKE \
+		"mod_ssl - Win32 $(LONG)" \
+		"abs - Win32 $(LONG)" /NORECURSE $(CTARGET)
+!ENDIF
+!IF EXIST("srclib\zlib")
+	@msdev Apache.dsw /USEENV /MAKE \
+		"mod_deflate - Win32 $(LONG)" /NORECURSE $(CTARGET)
+!ENDIF
+
+!ENDIF
+
+
+_copybin:
+	copy $(LONG)\httpd.$(src_exe) 				"$(inst_exe)" <.y
+	copy $(LONG)\libhttpd.$(src_dll) 			"$(inst_dll)" <.y
+	copy srclib\apr\$(LONG)\libapr-1.$(src_dll) 		"$(inst_dll)" <.y
+	copy srclib\apr-iconv\$(LONG)\libapriconv-1.$(src_dll) 	"$(inst_dll)" <.y
+	copy srclib\apr-util\$(LONG)\libaprutil-1.$(src_dll) 	"$(inst_dll)" <.y
+	copy modules\aaa\$(LONG)\mod_auth_basic.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_auth_digest.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authn_anon.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authn_dbm.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authn_default.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authn_file.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authz_dbm.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authz_default.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authz_groupfile.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authz_host.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authz_user.$(src_so) 	"$(inst_so)" <.y
+	copy modules\aaa\$(LONG)\mod_authnz_ldap.$(src_so)	"$(inst_so)" <.y
+	copy modules\arch\win32\$(LONG)\mod_isapi.$(src_so) 	"$(inst_so)" <.y
+	copy modules\cache\$(LONG)\mod_cache.$(src_so)		"$(inst_so)" <.y
+	copy modules\cache\$(LONG)\mod_file_cache.$(src_so) 	"$(inst_so)" <.y
+	copy modules\cache\$(LONG)\mod_mem_cache.$(src_so)	"$(inst_so)" <.y
+	copy modules\cache\$(LONG)\mod_disk_cache.$(src_so)	"$(inst_so)" <.y
+	copy modules\dav\fs\$(LONG)\mod_dav_fs.$(src_so) 	"$(inst_so)" <.y
+	copy modules\dav\main\$(LONG)\mod_dav.$(src_so)		"$(inst_so)" <.y
+	copy modules\debug\$(LONG)\mod_bucketeer.$(src_so)	"$(inst_so)" <.y
+	copy modules\debug\$(LONG)\mod_dumpio.$(src_so)		"$(inst_so)" <.y
+	copy modules\experimental\$(LONG)\mod_charset_lite.$(src_so)	"$(inst_so)" <.y
+!IF EXIST("srclib\zlib")
+	copy modules\filters\$(LONG)\mod_deflate.$(src_so) 	"$(inst_so)" <.y
+!IF EXIST("srclib\zlib\zlib1.$(src_dll)")
+	copy srclib\zlib\zlib1.$(src_dll)		 	"$(inst_dll)" <.y
+!ENDIF
+!ENDIF
+	copy modules\filters\$(LONG)\mod_ext_filter.$(src_so) 	"$(inst_so)" <.y
+	copy modules\filters\$(LONG)\mod_include.$(src_so) 	"$(inst_so)" <.y
+	copy modules\generators\$(LONG)\mod_asis.$(src_so) 	"$(inst_so)" <.y
+	copy modules\generators\$(LONG)\mod_autoindex.$(src_so) "$(inst_so)" <.y
+	copy modules\generators\$(LONG)\mod_cgi.$(src_so) 	"$(inst_so)" <.y
+	copy modules\generators\$(LONG)\mod_info.$(src_so) 	"$(inst_so)" <.y
+	copy modules\generators\$(LONG)\mod_status.$(src_so) 	"$(inst_so)" <.y
+	copy modules\http\$(LONG)\mod_mime.$(src_so) 		"$(inst_so)" <.y
+	copy modules\ldap\$(LONG)\mod_ldap.$(src_so)		"$(inst_so)" <.y
+	copy modules\loggers\$(LONG)\mod_log_config.$(src_so) 	"$(inst_so)" <.y
+	copy modules\loggers\$(LONG)\mod_log_forensic.$(src_so) "$(inst_so)" <.y
+	copy modules\loggers\$(LONG)\mod_logio.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_actions.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_alias.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_dir.$(src_so) 		"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_imagemap.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_negotiation.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_rewrite.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_speling.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_userdir.$(src_so) 	"$(inst_so)" <.y
+	copy modules\mappers\$(LONG)\mod_vhost_alias.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_cern_meta.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_env.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_expires.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_headers.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_ident.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_mime_magic.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_setenvif.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_unique_id.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_usertrack.$(src_so) 	"$(inst_so)" <.y
+	copy modules\metadata\$(LONG)\mod_version.$(src_so) 	"$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy.$(src_so) 		"$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy_ajp.$(src_so) 	"$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy_balancer.$(src_so) "$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy_connect.$(src_so) 	"$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy_ftp.$(src_so) 	"$(inst_so)" <.y
+	copy modules\proxy\$(LONG)\mod_proxy_http.$(src_so) 	"$(inst_so)" <.y
+!IF EXIST("srclib\openssl")
+	copy modules\ssl\$(LONG)\mod_ssl.$(src_so) 			"$(inst_so)" <.y
+	$(quiet)copy srclib\openssl\$(SSLBIN)\openssl.$(src_exe) 	"$(inst_exe)" <.y
+	$(quiet)copy srclib\openssl\$(SSLBIN)\libeay32.$(src_dll) 	"$(inst_dll)" <.y
+	$(quiet)copy srclib\openssl\$(SSLBIN)\ssleay32.$(src_dll) 	"$(inst_dll)" <.y
+	copy support\$(LONG)\abs.$(src_exe) 	"$(inst_exe)\ab.$(src_exe)" <.y
+!ELSE
+	copy support\$(LONG)\ab.$(src_exe) 				"$(inst_exe)" <.y
+!ENDIF
+	copy support\$(LONG)\htdbm.$(src_exe) 			"$(inst_exe)" <.y
+	copy support\$(LONG)\htdigest.$(src_exe) 		"$(inst_exe)" <.y
+	copy support\$(LONG)\htpasswd.$(src_exe) 		"$(inst_exe)" <.y
+	copy support\$(LONG)\logresolve.$(src_exe) 		"$(inst_exe)" <.y
+	copy support\$(LONG)\rotatelogs.$(src_exe) 		"$(inst_exe)" <.y
+	copy support\win32\$(LONG)\ApacheMonitor.$(src_exe) 	"$(inst_exe)" <.y
+	copy support\win32\$(LONG)\wintty.$(src_exe) 		"$(inst_exe)" <.y
+
+# First we create the tree and populate the README so that 
+# whatever happens, all licensing has already propagated.  
+# Then repeatedly invoke the _copybin build to copy the
+# real binaries, then pdb symbols, anf finally dbg syms.
+# Then hit docs of various sorts, then includes and libs,
+# and finally do the .conf magic.
+#
+_install:
+	echo Y >.y
+	echo A >.A
+	-mkdir "$(INSTDIR)"
+	-mkdir "$(INSTDIR)\bin"
+	-mkdir "$(INSTDIR)\bin\iconv"
+	-mkdir "$(INSTDIR)\cgi-bin"
+	-mkdir "$(INSTDIR)\conf"
+	-mkdir "$(INSTDIR)\conf\extra"
+	-mkdir "$(INSTDIR)\conf\original"
+	-mkdir "$(INSTDIR)\conf\original\extra"
+	-mkdir "$(INSTDIR)\error"
+	-mkdir "$(INSTDIR)\htdocs"
+	-mkdir "$(INSTDIR)\manual"
+	-mkdir "$(INSTDIR)\icons"
+	-mkdir "$(INSTDIR)\include"
+	-mkdir "$(INSTDIR)\lib"
+	-mkdir "$(INSTDIR)\logs"
+	-mkdir "$(INSTDIR)\modules"
+	-mkdir "$(INSTDIR)\proxy"
+	-mkdir "$(INSTDIR)\symbols"
+	-mkdir "$(INSTDIR)\symbols\exe"
+	-mkdir "$(INSTDIR)\symbols\dll"
+	-mkdir "$(INSTDIR)\symbols\so"
+	copy ABOUT_APACHE "$(INSTDIR)\ABOUT_APACHE.txt" <.y
+	copy CHANGES      "$(INSTDIR)\CHANGES.txt" <.y
+	copy INSTALL      "$(INSTDIR)\INSTALL.txt" <.y
+	copy LICENSE      "$(INSTDIR)\LICENSE.txt" <.y
+	copy README       "$(INSTDIR)\README.txt" <.y
+!IF EXIST("srclib\openssl")
+	type << >> "$(INSTDIR)\README.txt"
+
+  This binary distribution includes cryptographic software written by
+  Eric Young (eay@cryptsoft.com), software written by Tim Hudson 
+  (tjh@cryptsoft.com), and software developed by the OpenSSL Project 
+  for use in the OpenSSL Toolkit <http://www.openssl.org/>.
+<<
+	-awk -f <<script.awk < "srclib\openssl\LICENSE" >> "$(INSTDIR)\LICENSE.txt"
+BEGIN {
+    print "";
+    print "For the libeay32.dll, ssleay32.dll and certtool.exe components:";
+    print "";
+    while ( getline > 0 ) {
+	print $$0;
+   }
+}
+<<
+	copy << + srclib\openssl\NEWS "$(INSTDIR)\OPENSSL-NEWS.txt" <.y
+
+ Apache HTTP Server 2.0 Limited OpenSSL Distribution
+
+ This binary distribution includes the minimal components of OpenSSL required
+ to support mod_ssl for Apache HTTP Server version 2.0 (details are listed 
+ in OPENSSL-README.txt.)  For the complete list of CHANGES to this and later 
+ versions of OpenSSL, please refer to the definative source,
+ <http://www.openssl.org/news/changelog.html>, or see the CHANGES file in the
+ full binary or source distribution package from <http://www.openssl.org/>.
+
+ These OpenSSL binaries were built for distribution from the U.S. without 
+ support for the patented encryption methods IDEA, MDC-2 or RC5.
+
+--------------------------------------------------------------------------------
+<<
+	copy << + srclib\openssl\README "$(INSTDIR)\OPENSSL-README.txt" <.y
+
+ Apache HTTP Server 2.0 Limited OpenSSL Distribution
+
+ This binary installation of OpenSSL is a limited distribution of the documents
+ OPENSSL-LICENSE.txt, OPENSSL-NEWS.txt and OPENSSL-README.txt, and the binaries
+
+   libeay32.dll
+   ssleay32.dll
+   openssl.exe
+
+ These are the minimal libraries and tools required to use mod_ssl as 
+ distributed with Apache HTTP Server version 2.0.  No library link files, 
+ headers or sources are distributed with this binary distribution.  Please 
+ refer to the <http://www.openssl.org/> site for complete source or binary 
+ distributions.
+
+ These OpenSSL binaries were built for distribution from the U.S. without 
+ support for the patented encryption methods IDEA, MDC-2 or RC5.
+
+ The Apache HTTP Project only supports the binary distribution of these files
+ and development of the mod_ssl module.  We cannot provide support assistance
+ for using or configuring the OpenSSL package or these modules.  Please refer
+ all installation and configuration questions to the appropriate forum,
+ such as the user supported lists, <http://httpd.apache.org/userslist.html> 
+ the Apache HTTP Server user's list or <http://www.openssl.org/support/> the
+ OpenSSL support page.
+
+--------------------------------------------------------------------------------
+<<
+!ENDIF
+!IF EXIST("srclib\zlib")
+	type << >> "$(INSTDIR)\README.txt"
+
+  This binary distribution of mod_deflate.so includes zlib compression code
+  <http://www.gzip.org/zlib/> written by Jean-loup Gailly (jloup@gzip.org)
+  and Mark Adler (madler@alumni.caltech.edu) .
+<<
+	-awk -f <<script.awk < "srclib\zlib\README" >> "$(INSTDIR)\LICENSE.txt"
+BEGIN {
+    while ( getline > 0 ) {
+	if ( $$0 ~ /Copyright notice:/ ) {
+	    print "";
+	    print "For the mod_deflate zlib compression component:";
+	    while ( getline > 0 && $$0 !~ /^[^ ]/ ) {
+		print $$0;
+            }
+            exit 0;
+        }
+    }
+    exit 1;
+}
+<<
+!ENDIF
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=$(SHORT) LONG=$(LONG) \
+		_copybin src_exe=exe src_dll=dll src_so=so             \
+		inst_exe="$(INSTDIR)\bin"                              \
+		inst_dll="$(INSTDIR)\bin"                              \
+		inst_so="$(INSTDIR)\modules"
+	$(MAKE) $(MAKEOPT) -f Makefile.win SHORT=$(SHORT) LONG=$(LONG) \
+		_copybin src_exe=pdb src_dll=pdb src_so=pdb quiet="-"  \
+		inst_exe="$(INSTDIR)\bin"                              \
+		inst_dll="$(INSTDIR)\bin"                              \
+		inst_so="$(INSTDIR)\modules"
+	cd srclib\apr-iconv
+	$(MAKE) $(MAKEOPT) -f build\modules.mk.win install \
+		BUILD_MODE=$(LONG) BIND_MODE=shared API_SOURCE=. \
+		INSTALL_DIR="$(INSTDIR)\bin\iconv"
+	cd ..\..
+	copy docs\cgi-examples\printenv "$(INSTDIR)\cgi-bin\printenv.pl" <.y
+	-awk -f <<script.awk "docs/cgi-examples/printenv" > "$(INSTDIR)\cgi-bin\printenv.pl"
+    BEGIN { 
+	if ( "perl -e \"print $$^X;\"" | getline perlroot ) {
+	    gsub( /\\/, "/", perlroot );
+	    print "#!" perlroot;
+	}
+    }
+    {
+	if ( $$0 !~ /^#!/ ) {
+	    print $$0;
+	}
+    }
+<<
+	xcopy docs\error 	"$(INSTDIR)\error" /s /d < .a
+	xcopy docs\docroot 	"$(INSTDIR)\htdocs" /d < .a
+	xcopy docs\icons 	"$(INSTDIR)\icons" /s /d < .a
+	xcopy docs\manual 	"$(INSTDIR)\manual" /s /d < .a
+	xcopy srclib\apr-util\xml\expat\lib\expat.h 	"$(INSTDIR)\include" /d < .a
+	xcopy srclib\apr\include\*.h 			"$(INSTDIR)\include" /d < .a
+	xcopy srclib\apr-util\include\*.h 		"$(INSTDIR)\include" /d < .a
+	xcopy include\*.h 				"$(INSTDIR)\include" /d < .a
+	copy srclib\apr\Lib$(SHORT)\apr-1.lib 		"$(INSTDIR)\lib" <.y
+	copy srclib\apr\Lib$(SHORT)\apr_src.pdb 	"$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\Lib$(SHORT)\aprutil-1.lib 	"$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\Lib$(SHORT)\aprutil_src.pdb "$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\xml\expat\lib\Lib$(SHORT)\xml.lib "$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\xml\expat\lib\Lib$(SHORT)\xml_src.pdb "$(INSTDIR)\lib" <.y
+	copy srclib\apr\$(LONG)\libapr-1.lib 		"$(INSTDIR)\lib" <.y
+	copy srclib\apr\$(LONG)\libapr-1.exp 		"$(INSTDIR)\lib" <.y
+	copy srclib\apr-iconv\$(LONG)\libapriconv-1.lib	"$(INSTDIR)\lib" <.y
+	copy srclib\apr-iconv\$(LONG)\libapriconv-1.exp "$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\$(LONG)\libaprutil-1.lib 	"$(INSTDIR)\lib" <.y
+	copy srclib\apr-util\$(LONG)\libaprutil-1.exp 	"$(INSTDIR)\lib" <.y
+	copy $(LONG)\libhttpd.exp 			"$(INSTDIR)\lib" <.y
+	copy $(LONG)\libhttpd.lib 			"$(INSTDIR)\lib" <.y
+	copy modules\dav\main\$(LONG)\mod_dav.exp 	"$(INSTDIR)\lib" <.y
+	copy modules\dav\main\$(LONG)\mod_dav.lib 	"$(INSTDIR)\lib" <.y
+	copy docs\conf\magic "$(INSTDIR)\conf\original\magic" <.y
+	if not exist "$(INSTDIR)\conf\magic" \
+	    copy "$(INSTDIR)\conf\original\magic" "$(INSTDIR)\conf\magic"
+	copy docs\conf\mime.types "$(INSTDIR)\conf\original\mime.types" <.y
+	if not exist "$(INSTDIR)\conf\mime.types" \
+	    copy "$(INSTDIR)\conf\original\mime.types" "$(INSTDIR)\conf\mime.types"
+	copy docs\conf\httpd-win.conf "$(INSTDIR)\conf\original\httpd.conf" <.y
+	-awk -f <<script.awk "docs/conf/httpd-win.conf" "$(INSTDIR)" > "$(INSTDIR)\conf\original\httpd.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@@ServerRoot@@/, serverroot );
+	gsub( /@@ServerName@@/, "$(SERVERNAME)" );
+	gsub( /@@Port@@/, "$(PORT)" );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\httpd.conf" \
+	    copy "$(INSTDIR)\conf\original\httpd.conf" "$(INSTDIR)\conf\httpd.conf"
+	copy docs\conf\extra\httpd-autoindex.conf.in "$(INSTDIR)\conf\original\httpd-autoindex.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-autoindex.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-autoindex.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@exp_iconsdir@/, serverroot "/icons" );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-autoindex.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-autoindex.conf" "$(INSTDIR)\conf\extra\httpd-autoindex.conf"
+	copy docs\conf\extra\httpd-dav.conf.in "$(INSTDIR)\conf\original\httpd-dav.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-dav.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-dav.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@@ServerRoot@@/, serverroot );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-dav.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-dav.conf" "$(INSTDIR)\conf\extra\httpd-dav.conf"
+	copy docs\conf\extra\httpd-manual.conf.in "$(INSTDIR)\conf\original\httpd-manual.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-manual.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-manual.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@exp_manualdir@/, serverroot "/manual" );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-manual.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-manual.conf" "$(INSTDIR)\conf\extra\httpd-manual.conf"
+	copy docs\conf\extra\httpd-multilang-errordoc.conf.in "$(INSTDIR)\conf\original\httpd-multilang-errordoc.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-multilang-errordoc.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-multilang-errordoc.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@exp_errordir@/, serverroot "/error" );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-multilang-errordoc.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-multilang-errordoc.conf" "$(INSTDIR)\conf\extra\httpd-multilang-errordoc.conf"
+	copy docs\conf\extra\httpd-ssl.conf.in "$(INSTDIR)\conf\original\httpd-ssl.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-ssl.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-ssl.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@@ServerRoot@@/, serverroot );
+	gsub( /@exp_runtimedir@/, "logs" );
+	gsub( /@exp_htdocsdir@/, serverroot "/htdocs" );
+	gsub( /@exp_logfiledir@/, "logs" );
+	gsub( /@exp_sysconfdir@/, "conf" );
+	gsub( /@exp_cgidir@/, serverroot "/cgi-bin" );
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-ssl.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-ssl.conf" "$(INSTDIR)\conf\extra\httpd-ssl.conf"
+	copy docs\conf\extra\httpd-userdir.conf.in "$(INSTDIR)\conf\original\httpd-userdir.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-userdir.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-userdir.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /public_html/, "\"My Documents/My Website\"" );
+	gsub( /\/home/, "C:/WinNT/profiles" ); 
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-userdir.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-userdir.conf" "$(INSTDIR)\conf\extra\httpd-userdir.conf"
+	copy docs\conf\extra\httpd-mpm.conf.in "$(INSTDIR)\conf\original\httpd-mpm.conf" <.y
+	-awk -f <<script.awk "docs/conf/extra/httpd-mpm.conf.in" "$(INSTDIR)" > "$(INSTDIR)\conf\original\extra\httpd-mpm.conf"
+    BEGIN { 
+	serverroot = ARGV[2];
+	delete ARGV[2];
+	gsub( /\\/, "/", serverroot );
+	"cd" | getline root;
+	gsub( /^\//, substr( root, 1, 2 ) "/", serverroot );
+    }
+    {
+	gsub( /@rel_runtimedir@/, "logs/" );
+	gsub( /\/home/, "C:/WinNT/profiles" ); 
+	print $$0;
+    }
+<<
+	if not exist "$(INSTDIR)\conf\extra\httpd-mpm.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-mpm.conf" "$(INSTDIR)\conf\extra\httpd-mpm.conf"
+	copy docs\conf\extra\httpd-default.conf.in "$(INSTDIR)\conf\original\extra\httpd-default.conf" <.y
+	if not exist "$(INSTDIR)\conf\extra\httpd-default.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-default.conf" "$(INSTDIR)\conf\extra\httpd-default.conf"
+	copy docs\conf\extra\httpd-info.conf.in "$(INSTDIR)\conf\original\extra\httpd-info.conf" <.y
+	if not exist "$(INSTDIR)\conf\extra\httpd-info.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-info.conf" "$(INSTDIR)\conf\extra\httpd-info.conf"
+	copy docs\conf\extra\httpd-languages.conf.in "$(INSTDIR)\conf\original\extra\httpd-languages.conf" <.y
+	if not exist "$(INSTDIR)\conf\extra\httpd-languages.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-languages.conf" "$(INSTDIR)\conf\extra\httpd-languages.conf"
+	copy docs\conf\extra\httpd-vhosts.conf.in "$(INSTDIR)\conf\original\extra\httpd-vhosts.conf" <.y
+	if not exist "$(INSTDIR)\conf\extra\httpd-vhosts.conf" \
+	    copy "$(INSTDIR)\conf\original\extra\httpd-vhosts.conf" "$(INSTDIR)\conf\extra\httpd-vhosts.conf"
+	-awk -f <<script.awk "support/dbmmanage.in" >"$(INSTDIR)\bin\dbmmanage.pl"
+    { if ( $$0 ~ /^BEGIN \{ @AnyDBM_File::/ ) {
+	  sub( /ISA = qw\(.*\)/, "ISA = qw(SDBM_File)" ); 
+      }
+      if ( $$0 !~ /^#!@perlbin@/ )
+	  print $$0;
+    }
+<<
+	del .y
+	del .a
diff --git a/trunk/NOTICE b/trunk/NOTICE
new file mode 100644
index 0000000000..f074dd2219
--- /dev/null
+++ b/trunk/NOTICE
@@ -0,0 +1,17 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of this software were developed at the National Center
+for Supercomputing Applications (NCSA) at the University of
+Illinois at Urbana-Champaign.
+
+This software contains code derived from the RSA Data Security
+Inc. MD5 Message-Digest Algorithm, including various
+modifications by Spyglass Inc., Carnegie Mellon University, and
+Bell Communications Research, Inc (Bellcore).
+
+Regular expression support is provided by the PCRE library package,
+which is open source software, written by Philip Hazel, and copyright
+by the University of Cambridge, England. The original software is
+available from
+   ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
diff --git a/trunk/NWGNUmakefile b/trunk/NWGNUmakefile
new file mode 100644
index 0000000000..a763811850
--- /dev/null
+++ b/trunk/NWGNUmakefile
@@ -0,0 +1,397 @@
+#
+# Declare the sub-directories to be built here
+#
+
+SUBDIRS = \
+	$(APR_WORK) \
+	build \
+	support \
+	modules \
+	$(EOLIST) 
+
+#
+# Get the 'head' of the build environment.  This includes default targets and
+# paths to tools
+#
+
+include $(AP_WORK)\build\NWGNUhead.inc
+
+#
+# build this level's files
+
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS	+= \
+			$(APR)/include \
+			$(APRUTIL)/include \
+			$(AP_WORK)/include \
+			$(AP_WORK)/modules/filters/ \
+			$(AP_WORK)/modules/generators/ \
+			$(AP_WORK)/modules/http/ \
+			$(AP_WORK)/modules/loggers/ \
+			$(AP_WORK)/modules/mappers/ \
+			$(AP_WORK)/modules/proxy/ \
+			$(AP_WORK)/os/NetWare \
+			$(AP_WORK)/server/mpm/NetWare \
+			$(AP_WORK)/srclib/pcre \
+			$(NWOS) \
+			$(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS		+= \
+			$(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES	+= \
+			$(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS		+= \
+			$(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+		   	$(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+		   	$(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS	+= \
+			$(EOLIST)
+
+XCFLAGS		+= \
+			$(EOLIST)
+
+XDEFINES	+= \
+			$(EOLIST)
+
+XLFLAGS		+= \
+			$(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm.  If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME		= Apache2
+
+#
+# This is used by the link '-desc ' directive. 
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION	= Apache Web Server $(VERSION_STR)
+
+#
+# This is used by the '-threadname' directive.  If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME	= Apache
+
+#
+# This is used by the '-screenname' directive.  If left blank,
+# 'Apache for NetWare' Thread will be used.
+#
+NLM_SCREEN_NAME = Apache $(VERSION_STR) for NetWare
+
+
+#
+# If this is specified, it will override VERSION value in 
+# $(AP_WORK)\build\NWGNUenvironment.inc
+#
+NLM_VERSION		=
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE	= 65536
+ 
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM	= _LibCPrelude
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM	= _LibCPostlude
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM	= _LibCCheckUnload
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS		=  PSEUDOPREEMPTION
+
+#
+# If this is specified it will be linked in with the XDCData option in the def 
+# file instead of the default of $(NWOS)/apache.xdc.  XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA         = 
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+	$(OBJDIR)/Apache2.nlm \
+	$(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+	$(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+	$(OBJDIR)/buildmark.o \
+	$(OBJDIR)/config.o \
+	$(OBJDIR)/connection.o \
+	$(OBJDIR)/core.o \
+	$(OBJDIR)/core_filters.o \
+	$(OBJDIR)/eoc_bucket.o \
+	$(OBJDIR)/error_bucket.o \
+	$(OBJDIR)/http_core.o \
+	$(OBJDIR)/http_protocol.o \
+	$(OBJDIR)/http_request.o \
+	$(OBJDIR)/byterange_filter.o \
+	$(OBJDIR)/chunk_filter.o \
+	$(OBJDIR)/http_etag.o \
+	$(OBJDIR)/http_filters.o \
+	$(OBJDIR)/listen.o \
+	$(OBJDIR)/log.o \
+	$(OBJDIR)/main.o \
+	$(OBJDIR)/mod_authz_host.o \
+	$(OBJDIR)/mod_alias.o \
+	$(OBJDIR)/mod_dir.o \
+	$(OBJDIR)/mod_env.o \
+	$(OBJDIR)/mod_include.o \
+	$(OBJDIR)/mod_log_config.o \
+	$(OBJDIR)/mod_mime.o \
+	$(OBJDIR)/mod_negotiation.o \
+	$(OBJDIR)/mod_netware.o \
+	$(OBJDIR)/mod_setenvif.o \
+	$(OBJDIR)/mod_so.o \
+	$(OBJDIR)/modules.o \
+	$(OBJDIR)/mpm_common.o \
+	$(OBJDIR)/mpm_netware.o \
+	$(OBJDIR)/pcre.o \
+	$(OBJDIR)/protocol.o \
+	$(OBJDIR)/provider.o \
+	$(OBJDIR)/request.o \
+	$(OBJDIR)/scoreboard.o \
+	$(OBJDIR)/util.o \
+	$(OBJDIR)/util_cfgtree.o \
+	$(OBJDIR)/util_charset.o \
+	$(OBJDIR)/util_debug.o \
+	$(OBJDIR)/util_filter.o \
+	$(OBJDIR)/util_md5.o \
+	$(OBJDIR)/util_nw.o \
+	$(OBJDIR)/util_pcre.o \
+	$(OBJDIR)/util_script.o \
+	$(OBJDIR)/util_time.o \
+	$(OBJDIR)/util_xml.o \
+	$(OBJDIR)/vhost.o \
+	$(EOLIST)
+
+# Build in mod_nw_ssl if Winsock is being used
+ifndef USE_STDSOCKETS
+FILES_nlm_objs += $(OBJDIR)/mod_nw_ssl.o \
+	       $(EOLIST)
+endif
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+   	libcpre.o \
+	$(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+	aprlib \
+	Libc \
+	$(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+ 
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+	@netware.imp \
+	@$(APR)/aprlib.imp \
+	@libc.imp \
+	GetCurrentAddressSpace \
+	$(EOLIST)
+
+# Don't link with Winsock if standard sockets are being used
+ifndef USE_STDSOCKETS
+FILES_nlm_Ximports += @ws2nlm.imp \
+	       $(EOLIST)
+endif
+ 
+#   
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+	@$(NWOS)/httpd.imp \
+	$(EOLIST)
+	
+#   
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+		$(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the 
+# correct place.  (See $(AP_WORK)\build\NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+	-copy $(OBJDIR)\Apache2.nlm     $(INSTALL)\Apache2\*.*
+	-copy ABOUT_APACHE              $(INSTALL)\Apache2\*.*
+	-copy README                    $(INSTALL)\Apache2\*.*
+	-copy STATUS                    $(INSTALL)\Apache2\*.*
+	-copy LICENSE                   $(INSTALL)\Apache2\*.*
+	-copy CHANGES                   $(INSTALL)\Apache2\*.*
+	-copy support\dbmmanage.in      $(INSTALL)\Apache2\bin\dbmmanage.pl
+	-copy support\logresolve.pl.in  $(INSTALL)\Apache2\bin\logresolve.pl
+ifdef USE_STDSOCKETS	
+	-awk  -f build\mkconfnw.awk docs\conf\httpd.conf.in >$(INSTALL)\Apache2\conf\httpd.conf
+else
+	-awk  -v SSL=1 -f build\mkconfnw.awk docs\conf\httpd.conf.in >$(INSTALL)\Apache2\conf\httpd.conf
+endif	
+	$(CHKNOT) $(INSTALL)\Apache2\conf\extra\nul mkdir $(INSTALL)\Apache2\conf\extra
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-autoindex.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-autoindex.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-dav.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-dav.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-default.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-default.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-info.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-info.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-languages.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-languages.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-manual.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-manual.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-mpm.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-mpm.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-multilang-errordoc.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-multilang-errordoc.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-ssl.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-ssl.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-userdir.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-userdir.conf
+	-awk  -f build\mkconfnw.awk docs\conf\extra\httpd-vhosts.conf.in >$(INSTALL)\Apache2\conf\extra\httpd-vhosts.conf
+	-copy docs\conf\magic           $(INSTALL)\Apache2\conf\magic
+	-copy docs\conf\mime.types      $(INSTALL)\Apache2\conf\mime.types
+	-copy docs\conf\charset.conv    $(INSTALL)\Apache2\conf\charset.conv
+	-copy docs\cgi-examples\printenv $(INSTALL)\Apache2\cgi-bin\printenv.pl
+	@echo rem copying the docs directories > xc.bat
+	@echo xcopy docs\error $(INSTALL)\Apache2\error $(XCOPYSW) >> xc.bat
+	@echo xcopy docs\docroot $(INSTALL)\Apache2\htdocs $(XCOPYSW) >> xc.bat
+	@echo xcopy docs\icons $(INSTALL)\Apache2\icons $(XCOPYSW) >> xc.bat
+	@echo xcopy docs\man $(INSTALL)\Apache2\man $(XCOPYSW) >> xc.bat
+	@echo xcopy docs\manual $(INSTALL)\Apache2\manual $(XCOPYSW) >> xc.bat
+	$(CMD) xc.bat
+	$(DEL) xc.bat
+
+
+    
+installdev :: FORCE
+	-copy $(subst /,\,$(AP_WORK))\include\*.h           $(INSTALL)\Apache2\include\*.*
+	-copy $(subst /,\,$(AP_WORK))\os\netware\*.h        $(INSTALL)\Apache2\include\*.*
+	-copy $(subst /,\,$(NWOS))\*.imp                    $(INSTALL)\Apache2\lib\*.*
+	-copy $(subst /,\,$(APR))\include\*.h               $(INSTALL)\Apache2\include\*.*
+	-copy $(subst /,\,$(APRUTIL))\include\*.h           $(INSTALL)\Apache2\include\*.*
+	-copy $(subst /,\,$(APR))\*.imp                     $(INSTALL)\Apache2\lib\*.*
+	-copy $(subst /,\,$(NWOS))\*.xdc                    $(INSTALL)\Apache2\lib\*.*
+    
+prebuild :: FORCE
+	$(MAKE) -C server -f NWGNUMakefile
+	$(MAKE) -C srclib/pcre -f NWGNUMakefile
+	$(MAKE) -C $(APU_WORK)/uri -f NWGNUMakefile
+	$(CHKNOT) $(PREBUILD_INST)\nul          mkdir $(PREBUILD_INST)
+	-copy $(AP_WORK)\server\$(OBJDIR)\*.nlm $(PREBUILD_INST)\*.*
+	-copy $(AP_WORK)\srclib\pcre\$(basename $(OBJDIR))\*.nlm $(PREBUILD_INST)\*.*
+	-copy $(APU_WORK)\uri\$(basename $(OBJDIR))\*.nlm $(PREBUILD_INST)\*.*
+
+
+#
+# Any specialized rules here
+#
+
+vpath %.c server:modules/arch/netware:modules/http:modules/aaa:modules/mappers
+vpath %.c modules/generators:modules/metadata:modules/filters:modules/loggers
+vpath %.c os/netware:server/mpm/netware:srclib/pcre
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(AP_WORK)\build\NWGNUtail.inc
+
diff --git a/trunk/README b/trunk/README
new file mode 100644
index 0000000000..59217a37d9
--- /dev/null
+++ b/trunk/README
@@ -0,0 +1,90 @@
+
+                          Apache HTTP Server
+
+  What is it?
+  -----------
+
+  The Apache HTTP Server is a powerful and flexible HTTP/1.1 compliant
+  web server.  Originally designed as a replacement for the NCSA HTTP
+  Server, it has grown to be the most popular web server on the
+  Internet.  As a project of the Apache Software Foundation, the
+  developers aim to collaboratively develop and maintain a robust,
+  commercial-grade, standards-based server with freely available
+  source code.
+
+  The Latest Version
+  ------------------
+
+  Details of the latest version can be found on the Apache HTTP
+  server project page under http://httpd.apache.org/.
+
+  Documentation
+  -------------
+
+  The documentation available as of the date of this release is
+  included in HTML format in the docs/manual/ directory.  The most
+  up-to-date documentation can be found at
+  http://httpd.apache.org/docs-2.1/.
+
+  Installation
+  ------------
+
+  Please see the file called INSTALL.  Platform specific notes can be
+  found in README.platforms.
+
+  Licensing
+  ---------
+
+  Please see the file called LICENSE.
+
+  Contacts
+  --------
+
+     o If you want to be informed about new code releases, bug fixes,
+       security fixes, general news and information about the Apache server
+       subscribe to the apache-announce mailing list as described under
+       http://httpd.apache.org/lists.html#http-announce
+
+     o If you want freely available support for running Apache please join the
+       Apache user community by subscribing to Users Mailing List at
+       http://httpd.apache.org/userslist.html or one of the following USENET
+       newsgroups:
+       comp.infosystems.www.servers.unix
+       comp.infosystems.www.servers.ms-windows
+       Also available at: 
+       http://groups.google.com/groups?group=comp.infosystems.www.servers
+
+     o If you want commercial support for running Apache please contact
+       one of the companies and contractors which are listed at
+       http://www.apache.org/info/support.cgi
+
+     o If you have a concrete bug report for Apache please go to the
+       Apache Group Bug Database and submit your report:
+       http://httpd.apache.org/bug_report.html
+
+     o If you want to participate in actively developing Apache please
+       subscribe to the `dev@httpd.apache.org' mailing list as described at
+       http://www.apache.org/lists.html#http-dev
+
+  Acknowledgments
+  ----------------
+
+  We wish to acknowledge the following copyrighted works that
+  make up portions of the Apache software:
+
+  Portions of this software were developed at the National Center
+  for Supercomputing Applications (NCSA) at the University of
+  Illinois at Urbana-Champaign.
+
+  This software contains code derived from the RSA Data Security
+  Inc. MD5 Message-Digest Algorithm, including various
+  modifications by Spyglass Inc., Carnegie Mellon University, and
+  Bell Communications Research, Inc (Bellcore).
+
+  Regular expression support is provided by the PCRE library package, which
+  is open source software, written by Philip Hazel, and copyright by the
+  University of Cambridge, England.  The original software is available from
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+  Apache 2 relies heavily on the use of autoconf and libtool to provide
+  a build environment.
diff --git a/trunk/README.platforms b/trunk/README.platforms
new file mode 100644
index 0000000000..5307c104e1
--- /dev/null
+++ b/trunk/README.platforms
@@ -0,0 +1,98 @@
+
+                          Apache HTTP Server
+
+  Platform specific notes:
+  ------------------------
+
+================
+  Darwin (OS X):
+   Apache 2 relies heavily on the use of autoconf and libtool to
+   provide a build environment.  Darwin provides these tools as part
+   of the Developers Tools package. Under Darwin, however, GNUlibtool
+   is installed as 'glibtool' to avoid conflicting with the Darwin
+   'libtool' program.  Apache 2 knows about this so that's not a
+   problem.
+
+   As of OS X 10.2 (Jaguar), the bundled versions work perfectly. Partly
+   this is due to the fact that /bin/sh is now 'bash' and not 'zsh' as
+   well as the fact that the bundled versions are up-to-date: 
+   autoconf 2.52 and (g)libtool 1.4.2.
+
+   Earlier versions of OS X are not so fortunate, and the bundled tools
+   are not only older versions, but also, for the most part, do not work
+   well.  If you are interested in developing under Darwin, we
+   recommend that you obtain and install replacement versions of what
+   are normally installed on Darwin (and OS X, as of v10.1.5).  If
+   you build your own versions of autoconf 2.52 and libtool 1.4.2, be
+   aware that there are some Darwin specific patches to the official
+   code that still must be applied for them to fully work.  A useful
+   page to check out is:
+
+      http://fink.sourceforge.net/doc/porting/libtool.php
+
+   Pier Fumagalli also provides pre-built Darwin packages of the
+   patched autoconf and libtool suites, available at:
+
+      http://www.apache.org/~pier/macosx/
+
+   You will note that GNU libtool should actually be installed as
+   glibtool, to avoid conflict with a Darwin program of the same
+   name.  Pier's packages have this change already.  All files are
+   installed under /usr/local/ so to use these versions, and be sure
+   that /usr/local/bin is earlier in your PATH.
+
+   There have been some reports that autoconf 2.52 prevents Apache's
+   build system from correctly handling passing multi-value envvars
+   to the build system (eg: CFLAGS="-g -O3" ./configure),  causing
+   errors.  Use of bash does not seem to help in this situation.  If
+   this affects you, downgrading to autoconf 2.13 (which is installed
+   on Darwin) will help.
+
+==========
+  FreeBSD:
+   autoconf 2.52 creates scripts that are incompatible with the Posix
+   shell implementation (/bin/sh) on FreeBSD.  Be sure to use v2.13
+   of autoconf.
+
+   Threaded MPMs are not supported on FreeBSD 4.x.  Current releases of
+   FreeBSD 5.x (5.2 or later) support threaded MPMs correctly.  You must pass
+   '--enable-threads=yes' to APR's configure in order to enable threads.
+   Additionally, you must use libthr or libkse via libmap.conf as the default
+   libc_r is still broken as of this writing.  Please consult the man page for
+   libmap.conf for more details about configuring libthr or libkse.
+================
+  HP-UX:
+   The dlopen() system call in HP-UX has problems when loading/unloading
+   C++ modules. The problem can be resolved by using shl_load() instead
+   of dlopen(). This is fixed in the Apache 2.0.44 release.
+   To enable loading of C++ modules, the httpd binary has to be linked with
+   the following libraries :
+
+   HP-UX (11.0 / 11i):
+      When using shl_load        : "cpprt0_stub.s -lcl"
+      When using dlopen          : "cpprt0_stub.s -lcl -lCsup"
+
+   HP-UX (11i version 1.5 and greater):
+      When using dlopen/shl_load : "cpprt0_stub.s -lcl -lunwind"
+
+   The cpprt0_stub.s can be downloaded from the web site :
+      http://h21007.www2.hp.com/hpux-devtools/CXX/hpux-devtools.0107/0083.html
+
+   Compile cpprt0_stub.s with the PIC option
+     cc -c +z cpprt0_stub.s
+       - OR -
+     gcc -c -fPIC cpprt0_stub.s
+================
+  AIX, using the vendor C compiler with optimization:
+    There is an issue with compiling server/core.c with optimization enabled
+    which has been seen with C for AIX 5.0.2.3 and above.  (5.0.2.0, 5.0.2.1,
+    and 5.0.2.2 have an additional problem with Apache 2.0.x, so either upgrade 
+    the compiler or don't use optimization in order to avoid it.)
+
+    cc_r works fine with -O2 but xlc_r does not.  In order to use xlc_r with
+    -O2, apply the patch at 
+
+    http://www.apache.org/dist/httpd/patches/apply_to_2.0.49/aix_xlc_optimization.patch
+
+    (That patch works with many recent levels of Apache 2+.)
+
diff --git a/trunk/ROADMAP b/trunk/ROADMAP
new file mode 100644
index 0000000000..44de676798
--- /dev/null
+++ b/trunk/ROADMAP
@@ -0,0 +1,229 @@
+APACHE 2.x ROADMAP
+==================
+Last modified at [$Date$]
+
+
+WORKS IN PROGRESS
+-----------------
+
+    * Source code should follow style guidelines.
+      OK, we all agree pretty code is good.  Probably best to clean this
+      up by hand immediately upon branching a 2.1 tree.
+      Status: Justin volunteers to hand-edit the entire source tree ;)
+
+      Justin says:
+        Recall when the release plan for 2.0 was written:
+            Absolute Enforcement of an "Apache Style" for code.
+        Watch this slip into 3.0.
+
+      David says:
+        The style guide needs to be reviewed before this can be done.
+        http://httpd.apache.org/dev/styleguide.html
+        The current file is dated April 20th 1998!
+
+        OtherBill offers:
+          It's survived since '98 because it's welldone :-)  Suggest we
+          simply follow whatever is documented in styleguide.html as we
+          branch the next tree.  Really sort of straightforward, if you
+          dislike a bit within that doc, bring it up on the dev@httpd
+          list prior to the next branch.
+
+      So Bill sums up ... let's get the code cleaned up in CVS head.
+      Remember, it just takes cvs diff -b (that is, --ignore-space-change)
+      to see the code changes and ignore that cruft.  Get editing Justin :)
+
+    * Replace stat [deferred open] with open/fstat in directory_walk.
+      Justin, Ian, OtherBill all interested in this.  Implies setting up
+      the apr_file_t member in request_rec, and having all modules use
+      that file, and allow the cleanup to close it [if it isn't a shared,
+      cached file handle.]
+
+    * The Async Apache Server implemented in terms of APR.
+      [Bill Stoddard's pet project.]
+      Message-ID: <008301c17d42$9b446970$01000100@sashimi> (dev@apr)
+
+        OtherBill notes that this can proceed in two parts...
+
+           Async accept, setup, and tear-down of the request 
+           e.g. dealing with the incoming request headers, prior to
+           dispatching the request to a thread for processing.
+           This doesn't need to wait for a 2.x/3.0 bump.
+
+           Async delegation of the entire request processing chain
+           Too many handlers use stack storage and presume it is 
+           available for the life of the request, so a complete 
+           async implementation would need to happen 3.0 release.
+
+        Brian notes that async writes will provide a bigger
+        scalability win than async reads for most servers.
+        We may want to try a hybrid sync-read/async-write MPM
+        as a next step.  This should be relatively easy to
+        build: start with the current worker or leader/followers
+        model, but hand off each response brigade to a "completion
+        thread" that multiplexes writes on many connections, so
+        that the worker thread doesn't have to wait around for
+        the sendfile to complete.
+
+
+MAKING APACHE REPOSITORY-AGNOSTIC
+(or: remove knowledge of the filesystem)
+
+[ 2002/10/01: discussion in progress on items below; this isn't
+  planned yet ]
+
+    * dav_resource concept for an HTTP resource ("ap_resource")
+
+    * r->filename, r->canonical_filename, r->finfo need to
+      disappear. All users need to use new APIs on the ap_resource
+      object.
+      
+      (backwards compat: today, when this occurs with mod_dav and a
+       custom backend, the above items refer to the topmost directory
+       mapped by a location; e.g. docroot)
+
+      Need to preserve a 'filename'-like string for mime-by-name
+      sorts of operations.  But this only needs to be the name itself
+      and not a full path.
+
+      Justin: Can we leverage the path info, or do we not trust the
+              user?
+
+      gstein: well, it isn't the "path info", but the actual URI of
+              the resource. And of course we trust the user... that is
+              the resource they requested.
+              
+              dav_resource->uri is the field you want. path_info might
+              still exist, but that portion might be related to the
+              CGI concept of "path translated" or some other further
+              resolution.
+              
+              To continue, I would suggest that "path translated" and
+              having *any* path info is Badness. It means that you did
+              not fully resolve a resource for the given URI. The
+              "abs_path" in a URI identifies a resource, and that
+              should get fully resolved. None of this "resolve to
+              <here> and then we have a magical second resolution
+              (inside the CGI script)" or somesuch.
+   
+      Justin: Well, let's consider mod_mbox for a second.  It is sort of
+              a virtual filesystem in its own right - as it introduces
+              it's own notion of a URI space, but it is intrinsically
+              tied to the filesystem to do the lookups.  But, for the
+              portion that isn't resolved on the file system, it has
+              its own addressing scheme.  Do we need the ability to
+              layer resolution?
+
+    * The translate_name hook goes away
+
+      Wrowe altogether disagrees.  translate_name today even operates
+      on URIs ... this mechansim needs to be preserved.
+    
+    * The doc for map_to_storage is totally opaque to me. It has
+      something to do with filesystems, but it also talks about
+      security and per_dir_config and other stuff. I presume something
+      needs to happen there -- at least better doc.
+
+      Wrowe agrees and will write it up.
+
+    * The directory_walk concept disappears. All configuration is
+      tagged to Locations. The "mod_filesystem" module might have some
+      internal concept of the same config appearing in multiple
+      places, but that is handled internally rather than by Apache
+      core.
+
+      Wrowe suggests this is wrong, instead it's private to filesystem
+      requests, and is already invoked from map_to_storage, not the core
+      handler.  <Directory > and <Files > blocks are preserved as-is,
+      but <Directory > sections become specific to the filesystem handler
+      alone.  Because alternate filesystem schemes could be loaded, this
+      should be exposed, from the core, for other file-based stores to 
+      share. Consider an archive store where the layers become 
+      <Directory path> -> <Archive store> -> <File name>
+   
+      Justin: How do we map Directory entries to Locations?
+ 
+    * The "Location tree" is an in-memory representation of the URL
+      namespace. Nodes of the tree have configuration specific to that
+      location in the namespace.
+      
+      Something like:
+      
+      typedef struct {
+          const char *name;  /* name of this node relative to parent */
+
+          struct ap_conf_vector_t *locn_config;
+
+          apr_hash_t *children; /* NULL if no child configs */
+      } ap_locn_node;
+
+      The following config:
+      
+      <Location /server-status>
+          SetHandler server-status
+          Order deny,allow
+          Deny from all
+          Allow from 127.0.0.1
+      </Location>
+      
+      Creates a node with name=="server_status", and the node is a
+      child of the "/" node. (hmm. node->name is redundant with the
+      hash key; maybe drop node->name)
+      
+      In the config vector, mod_access has stored its Order, Deny, and
+      Allow configs. mod_core has stored the SetHandler.
+      
+      During the Location walk, we merge the config vectors normally.
+      
+      Note that an Alias simply associates a filesystem path (in
+      mod_filesystem) with that Location in the tree. Merging
+      continues with child locations, but a merge is never done
+      through filesystem locations. Config on a specific subdir needs
+      to be mapped back into the corresponding point in the Location
+      tree for proper merging.
+
+    * Config is parsed into a tree, as we did for the 2.0 timeframe,
+      but that tree is just a representation of the config (for
+      multiple runs and for in-memory manipulation and usage). It is
+      unrelated to the "Location tree".
+
+    * Calls to apr_file_io functions generally need to be replaced
+      with operations against the ap_resource. For example, rather
+      than calling apr_dir_open/read/close(), a caller uses
+      resource->repos->get_children() or somesuch.
+
+      Note that things like mod_dir, mod_autoindex, and mod_negotation
+      need to be converted to use these mechanisms so that their
+      functions will work on logical repositories rather than just
+      filesystems.
+
+    * How do we handle CGI scripts?  Especially when the resource may
+      not be backed by a file?  Ideally, we should be able to come up
+      with some mechanism to allow CGIs to work in a
+      repository-independent manner.
+
+      - Writing the virtual data as a file and then executing it?
+      - Can a shell be executed in a streamy manner?  (Portably?)
+      - Have an 'execute_resource' hook/func that allows the
+        repository to choose its manner - be it exec() or whatever.
+        - Won't this approach lead to duplication of code?  Helper fns?
+
+      gstein: PHP, Perl, and Python scripts are nominally executed by
+              a filter inserted by mod_php/perl/python. I'd suggest
+              that shell/batch scripts are similar.
+
+              But to ask further: what if it is an executable
+              *program* rather than just a script? Do we yank that out
+              of the repository, drop it onto the filesystem, and run
+              it? eeewwwww...
+              
+              I'll vote -0.9 for CGIs as a filter. Keep 'em handlers.
+
+      Justin: So, do we give up executing CGIs from virtual repositories?
+              That seems like a sad tradeoff to make.  I'd like to have
+              my CGI scripts under DAV (SVN) control.
+
+    * How do we handle overlaying of Location and Directory entries?
+      Right now, we have a problem when /cgi-bin/ is ScriptAlias'd and
+      mod_dav has control over /.  Some people believe that /cgi-bin/
+      shouldn't be under DAV control, while others do believe it
+      should be.  What's the right strategy?
diff --git a/trunk/STATUS b/trunk/STATUS
new file mode 100644
index 0000000000..7605ff2ef7
--- /dev/null
+++ b/trunk/STATUS
@@ -0,0 +1,511 @@
+APACHE 2.1 STATUS:                                              -*-text-*-
+Last modified at [$Date$]
+
+The current version of this file can be found at:
+http://svn.apache.org/repos/asf/httpd/httpd/trunk/STATUS
+
+Release history:
+    [NOTE that only Alpha/Beta releases occur in 2.1 development]
+
+    2.1.5   : in development
+    2.1.4   : not released.
+    2.1.3   : Released on  2/22/2005 as alpha.
+    2.1.2   : Released on 12/08/2004 as alpha.
+    2.1.1   : Released on 11/19/2004 as alpha.
+    2.1.0   : not released.
+
+Please consult the following STATUS files for information on related projects:
+
+    * http://svn.apache.org/repos/asf/apr/apr/trunk/STATUS
+    * http://svn.apache.org/repos/asf/apr/apr-util/trunk/STATUS
+    * http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/STATUS
+
+Contributors looking for a mission:
+
+    * Just do an egrep on "TODO" or "XXX" in the source.
+
+    * Review the bug database at: http://issues.apache.org/bugzilla/
+
+    * Review the "PatchAvailable" bugs in the bug database:
+
+      http://issues.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Apache+httpd-2.0&keywords=PatchAvailable
+
+      After testing, you can append a comment saying "Reviewed and tested".
+
+    * Open bugs in the bug database.
+
+CURRENT RELEASE NOTES:
+
+RELEASE SHOWSTOPPERS:
+
+    * Handling of non-trailing / config by non-default handler is broken
+      http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=105451701628081&w=2
+      jerenkrantz asks: Why should this block a release?
+
+    * the edge connection filter cannot be removed 
+      http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=105366252619530&w=2
+      jerenkrantz asks: Why should this block a release?
+      stas replies: because it requires a rewrite of the filters stack
+            implementation (you have suggested that) and once 2.2 is
+            released you can't do that anymore. 
+
+CURRENT VOTES:
+
+    * httpd-std.conf and friends
+
+      a) httpd-std.conf should be tailored by install (from src or
+         binbuild) even if user has existing httpd.conf
+         +1:   trawick, slive, gregames, ianh, Ken, wrowe, jwoolley, jim, nd,
+               erikabele
+           wrowe - prefer httpd.default.conf to avoid ambiguity with cvs
+
+      b) tailored httpd-std.conf should be copied by install to
+         sysconfdir/examples
+         -0:   striker
+
+      c) tailored httpd-std.conf should be installed to
+         sysconfdir/examples or manualdir/exampleconf/
+         +1:   slive, trawick, Ken, nd (prefer the latter), erikabele
+
+      d) Installing a set of default config files when upgrading a server
+         doesn't make ANY sense at all.
+         +1:   ianh - medium/big sites don't use 'standard config' anyway, as it
+                      usually needs major customizations
+         -1:   Ken, wrowe, jwoolley, jim, nd, erikabele
+           wrowe - diff is wonderful when comparing old/new default configs,
+                   even for customized sites that ianh mentions
+           jim - ... assuming that the default configs have been updated
+                     with the required inline docs to explain the
+                     changes
+
+    * If the parent process dies, should the remaining child processes
+      "gracefully" self-terminate. Or maybe we should make it a runtime
+      option, or have a concept of 2 parent processes (one being a 
+      "hot spare").
+      See: Message-ID: <3C58232C.FE91F19F@Golux.Com>
+
+      Self-destruct: Ken, Martin, Lars
+      Not self-destruct: BrianP, Ian, Cliff, BillS
+      Make it runtime configurable: Aaron, jim, Justin, wrowe, rederpj, nd
+
+      /* The below was a concept on *how* to handle the problem */
+      Have 2 parents: +1: jim
+                      -1: Justin, wrowe, rederpj, nd
+                      +0: Lars, Martin (while standing by, could it do
+                                        something useful?)
+
+    * Make the worker MPM the default MPM for threaded Unix boxes.
+      +1:   Justin, Ian, Cliff, BillS, striker, wrowe, nd
+      +0:   BrianP, Aaron (mutex contention is looking better with the
+            latest code, let's continue tuning and testing), rederpj, jim
+      -0:   Lars
+
+      pquerna: Do we want to change this for 2.2?
+
+RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
+
+    * Patches submitted to the bug database:
+      http://issues.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Apache+httpd-2.0&keywords=PatchAvailable
+
+    * The Event MPM does not work on Solaris 10. PR 34040.
+
+    * Filter stacks and subrequests, redirects and fast redirects.
+      There's at least one PR that suffers from the current unclean behaviour
+      (which lets the server send garbage): PR 17629
+      nd says: Every subrequest should get its own filter stack with the
+               subreq_core filter as bottom-most. That filter does two things:
+                 - swallow EOS buckets
+                 - redirect the data stream to the upper request's (rr->main)
+                   filter chain directly after the subrequest's starting
+                   point.
+               Once we have a clean solution, we can try to optimize
+               it, so that the server won't be slow down too much.
+
+    * RFC 2616 violations.
+      Closed PRs: 15857.
+      Open PRs: 15852, 15859, 15861, 15864, 15865, 15866, 15868, 15869,
+                15870, 16120, 16125, 16126, 16133, 16135, 16136, 16137,
+                16138, 16139, 16140, 16142, 16518, 16520, 16521, 
+      jerenkrantz says: need to decide how many we need to backport and/or
+                        if these rise to showstopper status.
+      wrowe suggests: it would be nice to see "MUST" v.s. "SHOULD" v.s. "MAY"
+                      out of this list, without reviewing them individually.
+
+    * There is a bug in how we sort some hooks, at least the pre-config
+      hook.  The first time we call the hooks, they are in the correct 
+      order, but the second time, we don't sort them correctly.  Currently,
+      the modules/http/config.m4 file has been renamed to 
+      modules/http/config2.m4 to work around this problem, it should moved
+      back when this is fixed.
+
+        OtherBill offers that this is a SERIOUS problem.  We do not sort
+        correctly by the ordering arguments passed to the register hook
+        functions.  This was proven when I reordered the open_logs hook
+        to attempt to open the error logs prior to the access logs.  Possibly
+        the entire sorting code needs to be refactored.
+
+    * pipes deadlock on all platforms with limited pipe buffers (e.g. both
+      Linux and Win32, as opposed to only Win32 on 1.3).  The right solution
+      is either GStein's proposal for a "CGI Brigade", or OtherBill's proposal
+      for "Poll Buckets" for "Polling Filter Chains".  Or maybe both :-)
+
+    * All handlers should always send content down even if r->header_only
+      is set.  If not, it means that the HEAD requests don't generate the
+      same headers as a GET which is wrong.
+
+    * exec cmd and suexec arg-passing enhancements
+      Status: Patches proposed
+      Message-ID: <20020526041748.A29148@prodigy.Redbrick.DCU.IE>
+      (see the "proc.patch" and "suexec-shell.patch" links in this message)
+
+    * The 2.0.36 worker MPM graceless shutdown changes work but are
+      a bit clunky on some platforms; eg, on Linux, the loop to
+      join each worker thread seems to hang, and the parent ends up
+      killing off the child with SIGKILL.  But at least it shuts down.
+
+    * --enable-mods-shared="foo1 foo2" is busted on Darwin.  Pier
+        posted a patch (Message-ID: <B8DBBE8D.575A%pier@betaversion.org>).
+
+    * We do not properly substitute the prefix-variables in the configuration
+      scripts or generated-configs.  (i.e. if sysconfdir is etc,
+      httpd-std.conf points to conf.)
+
+    * If any request gets through ap_process_request_internal() and is
+      scheduled to be served by the core handler, without a flag that this 
+      r->filename was tested by dir/file_walk, we need to 500 at the very 
+      end of the ap_process_request_internal() processing so sub_req-esters
+      know this request cannot be run.  This provides authors of older 
+      modules better compatibility, while still improving the security and 
+      robustness of 2.0. 
+
+        Status: still need to decide where this goes, OtherBill comments...
+        Message-ID: <065701c14526$495203b0$96c0b0d0@roweclan.net>
+        [Deleted comments regarding the ap_run_handler phase, as irrelevant
+            as BillS points out that "common case will be caught in
+  	    default_handler already (with the r->finfo.filetype == 0 check)"
+            and the issue is detecting this -before- we try to run the req.]
+
+	gregames says: can this happen somehow without a broken module
+            being involved?  If not, why waste cycles trying to defend against
+            potential broken modules?  It seems futile.
+        wrowe counters: no, it shouldn't happen unless the module is broken.
+            But the right answer is to fail the request up-front in dir/file
+            walk if the path was entirely invalid; and we can't do that either
+            UNTIL 2.1 or we break modules that haven't hooked map_to_storage.
+
+    * With AP_MODE_EXHAUSTIVE in the core, it is finally clear to me
+      how the Perchild MPM should be re-written.  It hasn't worked
+      correctly since filters were added because it wasn't possible to
+      get the content that had already been written and the socket at
+      the same time.  This mode lets us do that, so the MPM can be
+      fixed.
+
+    * Can a static httpd be built reliably?
+        Message-ID: <20020207142751.T31582@clove.org>
+
+    * Usage of APR_BRIGADE_NORMALIZE in core_input_filter should be
+      removed if possible.
+        Message-ID: <Pine.LNX.4.33.0201202232430.318-100000@deepthought.cs.virginia.edu>
+        Jeff wonders if we still care about this.  It is no longer an
+        API issue but simply an extra trip through the brigade.
+
+    * Get perchild to work on platforms other than Linux. This
+      will require a portable mechanism to pass data and file/socket
+      descriptors between vhost child groups. An API was proposed
+      on dev@apr:
+        Message-ID: <20020111115006.K1529@clove.org>
+
+    * Try to get libtool inter-library dependency code working on AIX.
+        Message-ID: <cm3n10lx555.fsf@rdu163-40-092.nc.rr.com>
+
+      Justin says: If we get it working on AIX, we can enable this
+                   on all platforms and clean up our build system
+                   somewhat.
+      Jeff says:   I thought I tested a patch for you sometime in
+                   January that you were going to commit within a few
+                   days.
+
+    * Handling of %2f in URIs.  Currently both 1.3 and 2.0
+      completely disallow %2f in the request URI path (see
+      ap_unescape_url() in util.c).  It's permitted and passed
+      through in the query string, however.  Roy says the
+      original reason for disallowing it, from five years ago,
+      was to protect CGI scripts that applied PATH_INFO to
+      a filesystem location and which might be tricked by
+      ..%2f..%2f(...).  We *should* allow path-info of the
+      form 'http://foo.com/index.cgi/path/to/path%2finfo'.
+      Since we've revamped a lot of our processing of path
+      segments, it would be nice to allow this, or at least
+      allow it conditionally with a directive.
+
+        OtherBill adds that %2f as the SECOND character of a multibyte
+        sequence causes the request to fail!  This happens notably in
+        the ja-jis encoding.
+
+    * FreeBSD, threads, and worker MPM.  All seems to work fine 
+      if you only have one worker process with many threads.  Add 
+      a second worker process and the accept lock seems to be
+      lost.  This might be an APR issue with how it deals with
+      the child_init hook (i.e. the fcntl lock needs to be resynced).
+      More examination and analysis is required.
+        Status: Works with FreeBSD 5.3. Does not work in previous versions.
+                This has also been reported on Cygwin.
+
+    * There is increasing demand from module writers for an API
+      that will allow them to control the server à la apachectl.
+      Reasons include sole-function servers that need to die if
+      an external dependency (e.g., a database) fails, et cetera.
+      Perhaps something in the (ever more abused) scoreboard?
+        
+             On the other hand, we already have a pipe that goes between parent
+             and child for graceful shutdown events, along with an API that
+             can be used to send a message down that pipe.  In threaded MPMs,
+             it is easy enough to make that one pipe be used for graceful
+             and graceless events, and it is also easy to open that pipe
+             to both parent and child for writing.  Then we just need to
+             figure out how to do graceless on non-threaded MPMs.
+
+    * Allow the DocumentRoot directive within <Location > scopes?  This
+      allows the beloved (crusty) Alias /foo/ /somepath/foo/ followed
+      by a <Directory /somepath/foo> to become simply 
+      <Location /foo/> DocumentRoot /somefile/foo (IMHO a bit more legible
+      and in-your-face.)  DocumentRoot unset would be accepted [and would
+      not permit content to be served, only virtual resources such as
+      server-info or server-status.
+      This proposed change would _not_ depricate Alias.
+        striker: See the thread starting with Message-ID:
+          JLEGKKNELMHCJPNMOKHOGEEJFBAA.striker@apache.org.
+
+    * Win32: Rotatelogs sometimes is not terminated when Apache
+      goes down hard.  FirstBill was looking at possibly tracking the 
+      child's-child processes in the parent process.
+        stoddard: Shared scoreboard might offer a good way for the parent 
+        to keep track of 'other child' processes and whack them if the child 
+        goes down.
+        Other thoughts on walking the process chain using the NT kernel
+        have also been proposed on APR.
+
+    * Eliminate unnecessary creation of pipes in mod_cgid
+
+    * Combine log_child and piped_log_spawn. Clean up http_log.c.
+      Common logging API.
+
+    * Platforms that do not support fork (primarily Win32 and AS/400)
+      Architect start-up code that avoids initializing all the modules 
+      in the parent process on platforms that do not support fork.
+
+    * There are still a number of places in the code where we are
+      losing error status (i.e. throwing away the error returned by a
+      system call and replacing it with a generic error code)
+
+    * Mass vhosting version of suEXEC.
+
+    * All DBMs suffer from confusion in support/dbmmanage (perl script) since 
+      the dbmmanage employs the first-matched dbm format.  This is not
+      necessarily the library that Apache was built with.  Aught to
+      rewrite dbmmanage upon installation to bin/ with the proper library 
+      for predictable mod_auth_dbm administration.
+        Questions; htdbm exists, time to kill dbmmanage, or does it remain
+                   useful as a perl dbm management example?  If we keep it,
+                   do we address the issue above?
+
+    * Integrate mod_dav.
+        Some additional items remaining:
+        - case_preserved_filename stuff
+            (use the new canonical name stuff?)
+        - find a new home for ap_text(_header)
+        - is it possible to remove the DAV: namespace stuff from util_xml?
+
+    * ap_core_translate() and its use by mod_mmap_static and mod_file_cache
+      are a bit wonky.  The function should probably be exposed as a utility 
+      function (such as ap_translate_url2fs() or ap_validate_fs_url() or 
+      something).  Another approach would be a new hook phase after
+      "translate" which would allow the module to munge what the
+      translation has decided to do.
+        Status: Greg +1 (volunteers)
+
+    * Explore use of a post-config hook for the code in http_main.c which
+      calls ap_fixup_virutal_hosts(), ap_fini_vhost_config(), and
+      ap_sort_hooks()  [to reduce the logic in main()]
+
+    * read the config tree just once, and process N times (as necessary)
+
+    * (possibly) use UUIDs in mod_unique_id and/or mod_usertrack
+
+    * (possibly) port the bug fix for PR 6942 (segv when LoadModule is put
+      into a VirtualHost container) to 2.0.
+
+    * shift stuff to mod_core.h
+
+    * callers of ap_run_create_request() should check the return value
+      for failure (Doug volunteers)
+
+    * Win32: Get Apache working on Windows 95/98. The following work
+        (at least) needs to be done:
+        - Document warning that OSR2 is required (for Crypt functions, in
+        rand.c, at least.)  This could be resolved with an SSL library, or
+        randomization in APR itself.
+        - Bring the Win9xConHook.dll from 1.3 into 2.0 (no sense till it
+        actually works) and add in a splash of Win9x service code.
+
+    * Fix the worker MPM to use POD to kill child processes instead
+      of ap_os_killpg, regardless of how they should die.
+
+    * Scoreboard structures could be changed in the future such that
+      proper alignment is not maintained, leading to segfaults on 
+      some systems.  Cliff posted a patch to deal with this issue but
+      later recanted. See this message to dev@apr.apache.org:
+      Message-ID: <Pine.LNX.4.44.0203011354090.16457-200000@deepthought
+                  .cs.virginia.edu>
+
+    * APXS either needs to be fixed completely for use when apr is out of tree,
+      or it should drop query mode altogether, and we just grow an 
+      httpd-config or similar arrangement. 
+      To quote a discussion in STATUS earlier:
+
+          thommay: this doesn't fix all the problems with apxs and out of
+                   tree apr/apr-util, but it's a good start. There's still the 
+                   query cases; but I'm beginning to think that in these cases 
+                   the app should be querying ap{r,u}-config directly
+          gstein: agreed. apxs should deprecate the -q flag
+          pquerna: I vote for a httpd-config, and to deprecate the -q flag.
+          minfrin: +1 for httpd-config, and to deprecate -q.
+
+TODO ISSUES REMAINING IN MOD_SSL:
+
+    * In order to use a DSO version of mod_ssl we have to link with
+      -lssl and -lcrypto. A workaround is in place right now where the
+      entire EXTRA_LIBS macro is being appended to the objects list, but
+      this is a hack. We should either revamp the APACHE_CHECK_SSL_TOOLKIT
+      autoconf function or come up with some other autoconf checks to
+      search for libssl and libcrypto and properly add them to mod_ssl's
+      link flags.
+
+    * SSL renegotiations in combination with POST request
+
+    * Port or dispose all code inside #if 0...#endif blocks that remain
+      from the porting effort.
+
+    * Do we need SSL_set_read_ahead()?
+
+    * the ssl_expr api is NOT THREAD SAFE.  race conditions exist:
+       -in ssl_expr_comp() if SSLRequire is used in .htaccess
+        (ssl_expr_info is global)
+       -is ssl_expr_eval() if there is an error
+        (ssl_expr_error is global)
+
+    * SSLRequire directive (parsing of) leaks memory
+
+    * Diffie-Hellman-Parameters for temporary keys are hardcoded in
+      ssl_engine_dh.c, while the comment in ssl_engine_kernel.c says:
+      "it is suggested that keys be changed daily or every 500
+      transactions, and more often if possible."
+
+    * ssl_var_lookup could be rewritten to be MUCH faster
+
+    * CRL callback should be pluggable
+
+    * session cache store should be pluggable
+
+    * init functions should return status code rather than ssl_die()
+
+    * ssl_engine_pphrase.c needs to be reworked so it is generic enough
+      to also decrypt proxy keys
+
+    * the shmcb code should just align its memory segment rather than
+      jumping through all the "safe" memcpy and memset hoops
+
+WISH LIST
+    * mod_proxy: Ability to run SSL over proxy gateway connections,
+      encrypting (or reencrypting) at the proxy.
+
+    * mod_cache: Handle ESI tags.
+
+    * mod_cache: Resolve issue of how to cache page fragements (or perhaps
+      -if- we want to cache page fragements). Today, mod_cache/mod_mem_cache
+      will cache #include 'virtual' requests (but not #include 'file'
+      requests). This was accomplished by making CACHE_IN a
+      CONTENT_SET-1 filter to force it to run before the SUBREQ_CORE
+      filter.  But now responses cannot be cached that include the
+      effects of having been run through CONTENT_SET filters
+      (mod_deflate, mod_expires, etc).  We could rerun all the
+      CONTENT_SET filters on the cached response, but this will not
+      work in all cases. For example, mod_expires relies on installing
+      the EXPIRATION filter during fixups. Contents served out of
+      mod_cache (out of the quick_handler) bypass -all- the request
+      line server hooks (Ryan really hated this. It is great for
+      performance, but bad because of the complications listed above).
+
+    mod_cache/mod_mem_cache/mod_disk_cache:
+
+    * mod_mem_cache: Consider adding a RevalidateTimeout directive to
+      specify time at which local cached content is to be revalidated
+      (ie, underlying file stat'ed to see if it has changed).
+
+    * mod_cache: CacheEnable/CacheDisable should accept regular expressions.
+      jerenkrantz says: Too slow.  Get regexs away from speedy caches by
+                        default.  Introduce a new CacheEnableRegex if you want.
+
+    * mod_mem_cache/mod_disk_cache: Need to be able to query cache
+      status (num of entries, cache object properties, etc.).
+      mod_status could be extended to query optional hooks defined
+      by modules for the purpose of reporting module status.
+      mod_cache (et. al.) could define optional hooks that are called
+      to collect status.  Status should be queryable by
+      HTTP or SNMP?
+      jerenkrantz says: Yawn.  Who cares.
+
+EXPERIMENTAL MODULES:
+
+    Experimental modules should eventually be be promoted to fully supported
+    status or removed from the repository entirely (ie, the
+    'experiment' failed). This section tracks what needs to happen to 
+    get the modules promoted to fully supported status.
+
+
+Other bugs that need fixing:
+
+    * MaxRequestsPerChild measures connections, not requests.
+        Until someone has a better way, we'll probably just rename it
+        "MaxConnectionsPerChild".
+    
+    * Regex containers don't work in an intutive way
+        Status: No one has come up with an efficient way to fix this
+        behavior. Dean has suggested getting rid of regex containers
+        completely.
+        OtherBill suggests: We at least seem to agree on eliminating
+                            the <Container ~ foo> forms, and using only
+                            <ContainerMatch foo> semantics.
+
+    * orig_ct in the byterange/multipart handling may not be
+      needed. Apache 1.3 just never stashed "multipart" into
+      r->content_type. We should probably follow suit since the
+      byterange stuff doesn't want the rest of the code to see the
+      multipart content-type; the other code should still think it is
+      dealing with the <orig_ct> stuff.
+        Status: Greg volunteers to investigate (esp. since he was most 
+                likely the one to break it :-)
+
+Binaries (probably not till beta):
+
+ Platform                      Avail.  Volunteer
+ ------------------------------------------------------------------
+ AIX 4.3.3                     no      Bill Stoddard
+ Mandrake 8.1                  no      open
+ FreeBSD 4.1                   no      open
+ hppa2.0w-hp-hpux11.00         no      Cliff Woolley
+ i386-pc-solaris2.8            no      Aaron Bannert
+ i386-unknown-freebsd4.5       no
+ i386-unknown-freebsd4.6       no      Cliff Woolley
+ i686-pc-linux-gnu-slackware81 no      Cliff Woolley
+ i686-pc-linux-gnu-rh70        no      Aaron Bannert
+ i686-pc-linux-gnu-rh73        no      Cliff Woolley
+ ia64-hp-hpux11.20             no
+ powerpc-apple-darwin5.5       no      Aaron Bannert
+ powerpc-unknown-linux-gnu     no      Graham Leggett
+ s390-ibm-linux                no      Greg Ames
+ sparc-sun-solaris2.8          no      Jim Jagielski
+ NetWare                       no      Brad Nicholes
+ OS/2                          no      Brian Havard
+ OS/390                        no      Greg Ames
+ Win32-x86                     no      William Rowe
diff --git a/trunk/VERSIONING b/trunk/VERSIONING
new file mode 100644
index 0000000000..3bfea278b1
--- /dev/null
+++ b/trunk/VERSIONING
@@ -0,0 +1,154 @@
+APACHE 2.x VERSIONING
+=====================
+Last modified at [$Date$]
+
+
+INTRODUCTION
+------------
+The Apache HTTP Server project must balance two competing and disjoint
+objectives: maintain stable code for third party authors, distributors and
+most importantly users so that bug and security fixes can be quickly adopted
+without significant hardship due to user-visible changes; and continue the
+development process that requires ongoing redesign to correct earlier
+oversights and to add additional features.
+
+The Apache HTTP Server, through version 2.0, used the Module Magic Number (MMN)
+to reflect API changes.  This had the shortcoming of often leaving users
+hunting to replace binary third party modules that were now incompatible.
+This also left module authors searching through the API change histories to
+determine the exact cause for the MMN change and whether their module was
+affected.
+
+With the simultaneous release of Apache 2.2-stable and Apache 2.3-development,
+the Apache HTTP Server project is moving towards a more predictable stable
+release cycle, while allowing forward progress to occur without concern
+for breaking the stable branch.  This document explains the rationale between
+the two versions and their behavior.
+
+
+STABLE RELEASES, 2.{even}.{revision}
+------------------------------------ 
+
+All even numbered releases will be considered stable revisions. 
+
+Stable revisions will retain forward compatiblity to the maximum
+possible extent.  Features may be added during minor revisions, and
+features may be deprecated by making appropriate notations in the
+documentation, but no features may be removed.
+
+In essence, that implies that you can upgrade from one minor revision
+to the next with a minimum of trouble.  In particular, this means:
+
+  * The Module API will retain forward compatibility.
+    It will not be necessary to update modules to work with new
+    revisions of the stable tree.
+
+  * The run-time configuration will be forward compatible.
+    No configuration changes will be necessary to work with new
+    revisions of the stable tree.
+
+  * Compile-time configuration will be forward compatible.
+    The configure command line options that work in one release
+    of the stable tree will also work in the next release.
+
+As always, it will be necessary to test any new release to assure
+that it works correctly with a particular configuration and a 
+particular set of modules, but every effort will be made to assure
+that upgrades are as smooth as possible.
+
+In addition, the following development restrictions will aid in 
+keeping the stable tree as safe as possible:
+
+  * No 'Experimental' modules; while it may be possible (based on API changes
+    required to support a given module) to load a 2.3-development module into
+    a 2.2-stable build of Apache, there are no guarantees.  Experimental 
+    modules will be introduced to the 2.3-development versions and either
+    added to 2.2-stable once they are proven and compatible, or deferred
+    to the 2.4-stable release if they cannot be incorporated in the current
+    stable release due to API change requirements.
+
+  * The stable CVS tree should not remain unstable at any time.  Atomic commits 
+    aught be used to introduce code from the development version to the stable 
+    tree.  At any given time a security release may be in preparation, 
+    unbeknownst to other contributors.  At any given time, testers may be
+    checking out CVS head to confirm that a bug has been corrected.  And as
+    all code was well-tested in development prior to committing to the stable
+    tree, there is really no reason for this tree to be broken for more than 
+    a few minutes during a lengthy commit.
+
+In order to avoid 'skipped' release numbers in the stable releases, the
+Release Manager will generally roll a release candidate (APACHE_#_#_#_RC#)
+tag.  Release Candidate tarballs will be announced to the
+stable-testers@httpd.apache.org for the stable tree.  Then, the participants
+will vote on the quality of the proposed release tarball.
+
+The final APACHE_#_#_# tag will not exist until the APACHE_#_#_#_RC# candidate
+has passed the usual votes to release that version.  Only then is the final
+tarball packaged, removing all -rc# designations from the version number, and
+tagging the tree with the release number.
+
+DEVELOPMENT RELEASES, 2.{odd}.{revision}
+-----------------------------------------
+
+All odd numbered releases designate the 'next' possible stable release,
+therefore the current development version will always be one greater than
+the current stable release.  Work proceeds on development releases, permitting
+the modification of the MMN at any time in order to correct deficiencies 
+or shortcomings in the API.  This means that modules from one development
+release to another may not be binary compatible, or may not successfully
+compile without modification to accomodate the API changes.
+
+The only 'supported' development release at any time will be the most
+recently released version.  Developers will not be answering bug reports
+of older development releases once a new release is available.  It becomes
+the resposibility of the reporter to use the latest development version
+to confirm that any issue still exists.
+
+Any new code, new API features or new ('experimental') modules may be
+promoted at any time to the next stable release, by a vote of the project
+contributors.  This vote is based on the technical stability of the new
+code and the stability of the interface.  Once moved to stable, that feature
+cannot change for the remainder of that stable release cycle, so the vote must
+reflect that the final decisions on the behavior and naming of that new
+feature were reached.  Vetos continue to apply to this choice of introducing
+the new work to the stable version.
+
+At any given time, when the quality of changes to the development branch
+is considered release quality, that version may become a candidate for the
+next stable release.  This includes some or all of the API changes, promoting
+experimental modules to stable or deprecating and eliminating older modules
+from the last stable release.  All of these choices are considered by the
+project as a group in the interests of promoting the stable release, so that
+any given change may be 'deferred' for a future release by the group, rather 
+than introduce unacceptable risks to adopting the next stable release.
+
+Third party module authors are strongly encouraged to test with the latest
+development version.  This assures that the module will be ready for the next
+stable release, but more importantly, the author can react to shortcomings
+in the API early enough to warn the dev@httpd.apache.org community of the
+shortcomings so that they can be addressed before the stable release.  The
+entire burden is on the module author to anticipate the needs of their module
+before the stable release is created.  Once a new stable release cycle has
+begun, that API will be present for the lifetime of the stable release.  Any
+desired changes in the stable versions must wait for inclusion into the next
+release cycle.
+
+When deciding to promote a development tree to being stable, a determination
+should be made whether the changes since the last stable version warrant a
+major version bump.  That is, if 2.2 is the current stable version and 2.3 is
+'ready' to become stable, the group needs to decide if the next stable
+version is 2.4 or 3.0.  One suggested rule of thumb is that if it requires
+too much effort to port a module from 2.2 to 2.4, then the stable version
+should be labeled 3.0.
+
+In order to ease the burden of creating development releases, the process
+for packaging a development releases is less formal than for the stable
+release.  This strategy reflects the fact that while in development, versions
+are cheap.  Development releases may be classified as alpha, beta, or GA
+to reflect the group's perceived stability of the tree.  Development releases
+may be made at any time by any committer.
+
+Please read the following link for a more detailed description of the
+development release strategy:
+
+http://httpd.apache.org/dev/release.html
diff --git a/trunk/acinclude.m4 b/trunk/acinclude.m4
new file mode 100644
index 0000000000..38d3993fd6
--- /dev/null
+++ b/trunk/acinclude.m4
@@ -0,0 +1,530 @@
+
+dnl APACHE_HELP_STRING(LHS, RHS)
+dnl Autoconf 2.50 can not handle substr correctly.  It does have 
+dnl AC_HELP_STRING, so let's try to call it if we can.
+dnl Note: this define must be on one line so that it can be properly returned
+dnl as the help string.
+AC_DEFUN(APACHE_HELP_STRING,[ifelse(regexp(AC_ACVERSION, 2\.1), -1, AC_HELP_STRING($1,$2),[  ]$1 substr([                       ],len($1))$2)])dnl
+
+dnl APACHE_SUBST(VARIABLE)
+dnl Makes VARIABLE available in generated files
+dnl (do not use @variable@ in Makefiles, but $(variable))
+AC_DEFUN(APACHE_SUBST,[
+  APACHE_VAR_SUBST="$APACHE_VAR_SUBST $1"
+  AC_SUBST($1)
+])
+
+dnl APACHE_FAST_OUTPUT(FILENAME)
+dnl Perform substitutions on FILENAME (Makefiles only)
+AC_DEFUN(APACHE_FAST_OUTPUT,[
+  APACHE_FAST_OUTPUT_FILES="$APACHE_FAST_OUTPUT_FILES $1"
+])
+
+dnl APACHE_GEN_CONFIG_VARS
+dnl Creates config_vars.mk
+AC_DEFUN(APACHE_GEN_CONFIG_VARS,[
+  APACHE_SUBST(abs_srcdir)
+  APACHE_SUBST(bindir)
+  APACHE_SUBST(sbindir)
+  APACHE_SUBST(cgidir)
+  APACHE_SUBST(logfiledir)
+  APACHE_SUBST(exec_prefix)
+  APACHE_SUBST(datadir)
+  APACHE_SUBST(localstatedir)
+  APACHE_SUBST(mandir)
+  APACHE_SUBST(libdir)
+  APACHE_SUBST(libexecdir)
+  APACHE_SUBST(htdocsdir)
+  APACHE_SUBST(manualdir)
+  APACHE_SUBST(includedir)
+  APACHE_SUBST(errordir)
+  APACHE_SUBST(iconsdir)
+  APACHE_SUBST(sysconfdir)
+  APACHE_SUBST(installbuilddir)
+  APACHE_SUBST(runtimedir)
+  APACHE_SUBST(proxycachedir)
+  APACHE_SUBST(other_targets)
+  APACHE_SUBST(progname)
+  APACHE_SUBST(prefix)
+  APACHE_SUBST(AWK)
+  APACHE_SUBST(CC)
+  APACHE_SUBST(CPP)
+  APACHE_SUBST(CXX)
+  APACHE_SUBST(CPPFLAGS)
+  APACHE_SUBST(CFLAGS)
+  APACHE_SUBST(CXXFLAGS)
+  APACHE_SUBST(LTFLAGS)
+  APACHE_SUBST(LDFLAGS)
+  APACHE_SUBST(LT_LDFLAGS)
+  APACHE_SUBST(SH_LDFLAGS)
+  APACHE_SUBST(HTTPD_LDFLAGS)
+  APACHE_SUBST(UTIL_LDFLAGS)
+  APACHE_SUBST(LIBS)
+  APACHE_SUBST(DEFS)
+  APACHE_SUBST(INCLUDES)
+  APACHE_SUBST(NOTEST_CPPFLAGS)
+  APACHE_SUBST(NOTEST_CFLAGS)
+  APACHE_SUBST(NOTEST_CXXFLAGS)
+  APACHE_SUBST(NOTEST_LDFLAGS)
+  APACHE_SUBST(NOTEST_LIBS)
+  APACHE_SUBST(EXTRA_CPPFLAGS)
+  APACHE_SUBST(EXTRA_CFLAGS)
+  APACHE_SUBST(EXTRA_CXXFLAGS)
+  APACHE_SUBST(EXTRA_LDFLAGS)
+  APACHE_SUBST(EXTRA_LIBS)
+  APACHE_SUBST(EXTRA_INCLUDES)
+  APACHE_SUBST(LIBTOOL)
+  APACHE_SUBST(SHELL)
+  APACHE_SUBST(MODULE_DIRS)
+  APACHE_SUBST(MODULE_CLEANDIRS)
+  APACHE_SUBST(PORT)
+  APACHE_SUBST(nonssl_listen_stmt_1)
+  APACHE_SUBST(nonssl_listen_stmt_2)
+  APACHE_SUBST(CORE_IMPLIB_FILE)
+  APACHE_SUBST(CORE_IMPLIB)
+  APACHE_SUBST(SH_LIBS)
+  APACHE_SUBST(SH_LIBTOOL)
+  APACHE_SUBST(MK_IMPLIB)
+  APACHE_SUBST(MKDEP)
+  APACHE_SUBST(INSTALL_PROG_FLAGS)
+  APACHE_SUBST(DSO_MODULES)
+  APACHE_SUBST(APR_BINDIR)
+  APACHE_SUBST(APR_INCLUDEDIR)
+  APACHE_SUBST(APR_VERSION)
+  APACHE_SUBST(APR_CONFIG)
+  APACHE_SUBST(APU_BINDIR)
+  APACHE_SUBST(APU_INCLUDEDIR)
+  APACHE_SUBST(APU_VERSION)
+  APACHE_SUBST(APU_CONFIG)
+
+  abs_srcdir="`(cd $srcdir && pwd)`"
+
+  echo creating config_vars.mk
+  test -d build || $mkdir_p build
+  > build/config_vars.mk
+  for i in $APACHE_VAR_SUBST; do
+    eval echo "$i = \$$i" >> build/config_vars.mk
+  done
+])
+
+dnl APACHE_GEN_MAKEFILES
+dnl Creates Makefiles
+AC_DEFUN(APACHE_GEN_MAKEFILES,[
+  $SHELL $srcdir/build/fastgen.sh $srcdir $ac_cv_mkdir_p $BSD_MAKEFILE $APACHE_FAST_OUTPUT_FILES
+])
+
+dnl ## APACHE_OUTPUT(file)
+dnl ## adds "file" to the list of files generated by AC_OUTPUT
+dnl ## This macro can be used several times.
+AC_DEFUN(APACHE_OUTPUT, [
+  APACHE_OUTPUT_FILES="$APACHE_OUTPUT_FILES $1"
+])
+
+dnl
+dnl APACHE_TYPE_RLIM_T
+dnl
+dnl If rlim_t is not defined, define it to int
+dnl
+AC_DEFUN(APACHE_TYPE_RLIM_T, [
+  AC_CACHE_CHECK([for rlim_t], ac_cv_type_rlim_t, [
+    AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+], [rlim_t spoon;], [
+      ac_cv_type_rlim_t=yes
+    ],[ac_cv_type_rlim_t=no
+    ])
+  ])
+  if test "$ac_cv_type_rlim_t" = "no" ; then
+      AC_DEFINE(rlim_t, int,
+          [Define to 'int' if <sys/resource.h> doesn't define it for us])
+  fi
+])
+
+dnl APACHE_MODPATH_INIT(modpath)
+AC_DEFUN(APACHE_MODPATH_INIT,[
+  current_dir=$1
+  modpath_current=modules/$1
+  modpath_static=
+  modpath_shared=
+  test -d $1 || $srcdir/build/mkdir.sh $modpath_current
+  > $modpath_current/modules.mk
+])dnl
+dnl
+AC_DEFUN(APACHE_MODPATH_FINISH,[
+  echo "DISTCLEAN_TARGETS = modules.mk" >> $modpath_current/modules.mk
+  echo "static = $modpath_static" >> $modpath_current/modules.mk
+  echo "shared = $modpath_shared" >> $modpath_current/modules.mk
+  if test ! -z "$modpath_static" -o ! -z "$modpath_shared"; then
+    MODULE_DIRS="$MODULE_DIRS $current_dir"
+  else
+    MODULE_CLEANDIRS="$MODULE_CLEANDIRS $current_dir"
+  fi
+  APACHE_FAST_OUTPUT($modpath_current/Makefile)
+])dnl
+dnl
+dnl APACHE_MODPATH_ADD(name[, shared[, objects [, ldflags[, libs]]]])
+AC_DEFUN(APACHE_MODPATH_ADD,[
+  if test -z "$3"; then
+    objects="mod_$1.lo"
+  else
+    objects="$3"
+  fi
+
+  if test -z "$module_standalone"; then
+    if test -z "$2"; then
+      # The filename of a convenience library must have a "lib" prefix:
+      libname="libmod_$1.la"
+      BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname"
+      modpath_static="$modpath_static $libname"
+      cat >>$modpath_current/modules.mk<<EOF
+$libname: $objects
+	\$(MOD_LINK) $objects $5
+EOF
+    else
+      apache_need_shared=yes
+      libname="mod_$1.la"
+      shobjects=`echo $objects | sed 's/\.lo/.slo/g'`
+      modpath_shared="$modpath_shared $libname"
+      cat >>$modpath_current/modules.mk<<EOF
+$libname: $shobjects
+	\$(SH_LINK) -rpath \$(libexecdir) -module -avoid-version $4 $objects $5
+EOF
+    fi
+  fi
+])dnl
+
+dnl
+dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
+dnl
+dnl default is one of:
+dnl   yes    -- enabled by default. user must explicitly disable.
+dnl   no     -- disabled under default, most, all. user must explicitly enable.
+dnl   most   -- disabled by default. enabled explicitly or with most or all.
+dnl   static -- enabled as static by default, must be explicitly changed.
+dnl   ""     -- disabled under default, most. enabled explicitly or with all.
+dnl
+dnl basically: yes/no is a hard setting. "most" means follow the "most"
+dnl            setting. otherwise, fall under the "all" setting.
+dnl            explicit yes/no always overrides.
+dnl
+AC_DEFUN(APACHE_MODULE,[
+  AC_MSG_CHECKING(whether to enable mod_$1)
+  define([optname],[--]ifelse($5,yes,disable,enable)[-]translit($1,_,-))dnl
+  AC_ARG_ENABLE(translit($1,_,-),APACHE_HELP_STRING(optname(),$2),,enable_$1=ifelse($5,,maybe-all,$5))
+  undefine([optname])dnl
+  _apmod_extra_msg=""
+  dnl When --enable-modules=most is set and the module was not explicitly
+  dnl requested, allow a module to disable itself if its pre-reqs fail.
+  if test "$module_selection" = "most" -a "$enable_$1" = "most"; then
+    _apmod_error_fatal="no"
+  else
+    _apmod_error_fatal="yes"
+  fi
+  if test "$enable_$1" = "static"; then
+    enable_$1=yes
+  elif test "$enable_$1" = "yes"; then
+    enable_$1=$module_default
+    _apmod_extra_msg=" ($module_selection)"
+  elif test "$enable_$1" = "most"; then
+    if test "$module_selection" = "most" -o "$module_selection" = "all"; then
+      enable_$1=$module_default
+      _apmod_extra_msg=" ($module_selection)"
+    elif test "$enable_$1" != "yes"; then
+      enable_$1=no
+    fi
+  elif test "$enable_$1" = "maybe-all"; then
+    if test "$module_selection" = "all"; then
+      enable_$1=$module_default
+      _apmod_extra_msg=" (all)"
+    else
+      enable_$1=no
+    fi
+  fi
+  if test "$enable_$1" != "no"; then
+    dnl If we plan to enable it, allow the module to run some autoconf magic
+    dnl that may disable it because of missing dependencies.
+    ifelse([$6],,:,[AC_MSG_RESULT([checking dependencies])
+                    $6
+                    AC_MSG_CHECKING(whether to enable mod_$1)
+                    if test "$enable_$1" = "no"; then
+                      if test "$_apmod_error_fatal" = "no"; then
+                        _apmod_extra_msg=" (disabled)"
+                      else
+                        AC_MSG_ERROR([mod_$1 has been requested but can not be built due to prerequisite failures])
+                      fi
+                    fi])
+  fi
+  AC_MSG_RESULT($enable_$1$_apmod_extra_msg)
+  if test "$enable_$1" != "no"; then
+    case "$enable_$1" in
+    shared*)
+      enable_$1=`echo $enable_$1|sed 's/shared,*//'`
+      sharedobjs=yes
+      shared=yes
+      DSO_MODULES="$DSO_MODULES $1"
+      ;;
+    *)
+      MODLIST="$MODLIST ifelse($4,,$1,$4)"
+      if test "$1" = "so"; then
+          sharedobjs=yes
+      fi
+      shared="";;
+    esac
+    define([modprefix], [MOD_]translit($1, [a-z-], [A-Z_]))
+    APACHE_MODPATH_ADD($1, $shared, $3,, [\$(]modprefix[_LDADD)])
+    APACHE_SUBST(modprefix[_LDADD])
+    undefine([modprefix])
+  fi
+])dnl
+
+dnl
+dnl APACHE_ENABLE_MODULES
+dnl
+AC_DEFUN(APACHE_ENABLE_MODULES,[
+  module_selection=default
+  module_default=yes
+
+  AC_ARG_ENABLE(modules,
+  APACHE_HELP_STRING(--enable-modules=MODULE-LIST,Space-separated list of modules to enable | "all" | "most"),[
+    for i in $enableval; do
+      if test "$i" = "all" -o "$i" = "most"; then
+        module_selection=$i
+      else
+        i=`echo $i | sed 's/-/_/g'`
+        eval "enable_$i=yes"
+      fi
+    done
+  ])
+  
+  AC_ARG_ENABLE(mods-shared,
+  APACHE_HELP_STRING(--enable-mods-shared=MODULE-LIST,Space-separated list of shared modules to enable | "all" | "most"),[
+    for i in $enableval; do
+      if test "$i" = "all" -o "$i" = "most"; then
+        module_selection=$i
+        module_default=shared
+      else
+        i=`echo $i | sed 's/-/_/g'`
+    	eval "enable_$i=shared"
+      fi
+    done
+  ])
+])
+
+AC_DEFUN(APACHE_REQUIRE_CXX,[
+  if test -z "$apache_cxx_done"; then
+    AC_PROG_CXX
+    AC_PROG_CXXCPP
+    apache_cxx_done=yes
+  fi
+])
+
+dnl
+dnl APACHE_CHECK_SSL_TOOLKIT
+dnl
+dnl Configure for the detected openssl/ssl-c toolkit installation, giving
+dnl preference to "--with-ssl=<path>" if it was specified.
+dnl
+AC_DEFUN(APACHE_CHECK_SSL_TOOLKIT,[
+if test "x$ap_ssltk_configured" = "x"; then
+  dnl initialise the variables we use
+  ap_ssltk_base=""
+  ap_ssltk_inc=""
+  ap_ssltk_lib=""
+  ap_ssltk_type=""
+
+  dnl Determine the SSL/TLS toolkit's base directory, if any
+  AC_MSG_CHECKING(for SSL/TLS toolkit base)
+  AC_ARG_WITH(sslc, APACHE_HELP_STRING(--with-sslc=DIR,RSA SSL-C SSL/TLS toolkit), [
+    dnl If --with-sslc specifies a directory, we use that directory or fail
+    if test "x$withval" != "xyes" -a "x$withval" != "x"; then
+      dnl This ensures $withval is actually a directory and that it is absolute
+      ap_ssltk_base="`cd $withval ; pwd`"
+    fi
+    ap_ssltk_type="sslc"
+  ])
+  AC_ARG_WITH(ssl, APACHE_HELP_STRING(--with-ssl=DIR,OpenSSL SSL/TLS toolkit), [
+    dnl If --with-ssl specifies a directory, we use that directory or fail
+    if test "x$withval" != "xyes" -a "x$withval" != "x"; then
+      dnl This ensures $withval is actually a directory and that it is absolute
+      ap_ssltk_base="`cd $withval ; pwd`"
+    fi
+  ])
+  if test "x$ap_ssltk_base" = "x"; then
+    AC_MSG_RESULT(none)
+  else
+    AC_MSG_RESULT($ap_ssltk_base)
+  fi
+
+  dnl Run header and version checks
+  saved_CPPFLAGS=$CPPFLAGS
+  if test "x$ap_ssltk_base" != "x"; then
+    ap_ssltk_inc="-I$ap_ssltk_base/include"
+    CPPFLAGS="$CPPFLAGS $ap_ssltk_inc"
+  fi
+  if test "x$ap_ssltk_type" = "x"; then
+    AC_MSG_CHECKING(for OpenSSL version)
+    dnl First check for manditory headers
+    AC_CHECK_HEADERS([openssl/opensslv.h openssl/ssl.h], [ap_ssltk_type="openssl"], [])
+    if test "$ap_ssltk_type" = "openssl"; then
+      dnl so it's OpenSSL - test for a good version
+      AC_TRY_COMPILE([#include <openssl/opensslv.h>],[
+#if !defined(OPENSSL_VERSION_NUMBER)
+#error "Missing openssl version"
+#endif
+#if  (OPENSSL_VERSION_NUMBER < 0x009060af) \
+ || ((OPENSSL_VERSION_NUMBER > 0x00907000) && (OPENSSL_VERSION_NUMBER < 0x0090702f))
+#error "Insecure openssl version " OPENSSL_VERSION_TEXT
+#endif],
+      [AC_MSG_RESULT(OK)],
+      [dnl Replace this with OPENSSL_VERSION_TEXT from opensslv.h?
+       AC_MSG_RESULT([not encouraging])
+       echo "WARNING: OpenSSL version may contain security vulnerabilities!"
+       echo "         Ensure the latest security patches have been applied!"
+      ])
+      dnl Look for additional, possibly missing headers
+      AC_CHECK_HEADERS(openssl/engine.h)
+      if test -n "$PKGCONFIG"; then
+        $PKGCONFIG openssl
+        if test $? -eq 0; then
+          ap_ssltk_inc="$ap_ssltk_inc `$PKGCONFIG --cflags-only-I openssl`"
+          CPPFLAGS="$CPPFLAGS $ap_ssltk_inc"
+        fi
+      fi
+    else
+      AC_MSG_RESULT([no OpenSSL headers found])
+    fi
+  fi
+  if test "$ap_ssltk_type" != "openssl"; then
+    dnl Might be SSL-C - report, then test anything relevant
+    AC_MSG_CHECKING(for SSL-C version)
+    AC_CHECK_HEADERS([sslc.h], [ap_ssltk_type="sslc"], [ap_ssltk_type=""])
+    if test "$ap_ssltk_type" = "sslc"; then
+      AC_MSG_CHECKING(for SSL-C version)
+      AC_TRY_COMPILE([#include <sslc.h>],[
+#if !defined(SSLC_VERSION_NUMBER)
+#error "Missing SSL-C version"
+#endif
+#if SSLC_VERSION_NUMBER < 0x2310
+#define stringize_ver(x) #x
+#error "Insecure SSL-C version " stringize_ver(SSLC_VERSION_NUMBER)
+#endif],
+      [AC_MSG_RESULT(OK)],
+      [dnl Replace this with SSLC_VERSION_NUMBER?
+       AC_MSG_RESULT([not encouraging])
+       echo "WARNING: SSL-C version may contain security vulnerabilities!"
+       echo "         Ensure the latest security patches have been applied!"
+      ])
+    else
+      AC_MSG_RESULT([no SSL-C headers found])
+    fi
+  fi
+  dnl restore
+  CPPFLAGS=$saved_CPPFLAGS
+  if test "x$ap_ssltk_type" = "x"; then
+    AC_MSG_ERROR([...No recognized SSL/TLS toolkit detected])
+  fi
+
+  dnl Run library and function checks
+  saved_LDFLAGS=$LDFLAGS
+  saved_LIBS=$LIBS
+  if test "x$ap_ssltk_base" != "x"; then
+    if test -d "$ap_ssltk_base/lib"; then
+      ap_ssltk_lib="$ap_ssltk_base/lib"
+    else
+      ap_ssltk_lib="$ap_ssltk_base"
+    fi
+    LDFLAGS="$LDFLAGS -L$ap_ssltk_lib"
+  fi
+  dnl make sure "other" flags are available so libcrypto and libssl can link
+  LIBS="$LIBS `$apr_config --libs`"
+  liberrors=""
+  if test "$ap_ssltk_type" = "openssl"; then
+    AC_CHECK_LIB(crypto, SSLeay_version, [], [liberrors="yes"])
+    AC_CHECK_LIB(ssl, SSL_CTX_new, [], [liberrors="yes"])
+    AC_CHECK_FUNCS(ENGINE_init)
+    AC_CHECK_FUNCS(ENGINE_load_builtin_engines)
+  else
+    AC_CHECK_LIB(sslc, SSLC_library_version, [], [liberrors="yes"])
+    AC_CHECK_LIB(sslc, SSL_CTX_new, [], [liberrors="yes"])
+    AC_CHECK_FUNCS(SSL_set_state)
+  fi
+  AC_CHECK_FUNCS(SSL_set_cert_store)
+  dnl restore
+  LDFLAGS=$saved_LDFLAGS
+  LIBS=$saved_LIBS
+  if test "x$liberrors" != "x"; then
+    AC_MSG_ERROR([... Error, SSL/TLS libraries were missing or unusable])
+  fi
+
+  dnl Adjust apache's configuration based on what we found above.
+  dnl (a) define preprocessor symbols
+  if test "$ap_ssltk_type" = "openssl"; then
+    AC_DEFINE(HAVE_OPENSSL, 1, [Define if SSL is supported using OpenSSL])
+  else
+    AC_DEFINE(HAVE_SSLC, 1, [Define if SSL is supported using SSL-C])
+  fi
+  dnl (b) hook up include paths
+  if test "x$ap_ssltk_inc" != "x"; then
+    APR_ADDTO(INCLUDES, [$ap_ssltk_inc])
+  fi
+  dnl (c) hook up linker paths
+  if test "x$ap_ssltk_lib" != "x"; then
+    APR_ADDTO(LDFLAGS, ["-L$ap_ssltk_lib"])
+    if test "x$ap_platform_runtime_link_flag" != "x"; then
+      APR_ADDTO(LDFLAGS, ["$ap_platform_runtime_link_flag$ap_ssltk_lib"])
+    fi
+  fi
+  # Put SSL libraries in SSL_LIBS.
+  if test "$ap_ssltk_type" = "openssl"; then
+    APR_SETVAR(SSL_LIBS, [-lssl -lcrypto])
+    if test -n "$PKGCONFIG"; then
+      $PKGCONFIG openssl
+      if test $? -eq 0; then
+        ap_ssltk_libdep=`$PKGCONFIG --libs openssl`
+        APR_ADDTO(SSL_LIBS, $ap_ssltk_libdep)
+      fi
+    fi
+  else
+    APR_SETVAR(SSL_LIBS, [-lsslc])
+  fi
+  APACHE_SUBST(SSL_LIBS)
+fi
+])
+
+dnl
+dnl APACHE_EXPORT_ARGUMENTS
+dnl Export (via APACHE_SUBST) the various path-related variables that
+dnl apache will use while generating scripts like autoconf and apxs and
+dnl the default config file.
+
+AC_DEFUN(APACHE_SUBST_EXPANDED_ARG,[
+  APR_EXPAND_VAR(exp_$1, [$]$1)
+  APACHE_SUBST(exp_$1)
+  APR_PATH_RELATIVE(rel_$1, [$]exp_$1, ${prefix})
+  APACHE_SUBST(rel_$1)
+])
+
+AC_DEFUN(APACHE_EXPORT_ARGUMENTS,[
+  APACHE_SUBST_EXPANDED_ARG(exec_prefix)
+  APACHE_SUBST_EXPANDED_ARG(bindir)
+  APACHE_SUBST_EXPANDED_ARG(sbindir)
+  APACHE_SUBST_EXPANDED_ARG(libdir)
+  APACHE_SUBST_EXPANDED_ARG(libexecdir)
+  APACHE_SUBST_EXPANDED_ARG(mandir)
+  APACHE_SUBST_EXPANDED_ARG(sysconfdir)
+  APACHE_SUBST_EXPANDED_ARG(datadir)
+  APACHE_SUBST_EXPANDED_ARG(installbuilddir)
+  APACHE_SUBST_EXPANDED_ARG(errordir)
+  APACHE_SUBST_EXPANDED_ARG(iconsdir)
+  APACHE_SUBST_EXPANDED_ARG(htdocsdir)
+  APACHE_SUBST_EXPANDED_ARG(manualdir)
+  APACHE_SUBST_EXPANDED_ARG(cgidir)
+  APACHE_SUBST_EXPANDED_ARG(includedir)
+  APACHE_SUBST_EXPANDED_ARG(localstatedir)
+  APACHE_SUBST_EXPANDED_ARG(runtimedir)
+  APACHE_SUBST_EXPANDED_ARG(logfiledir)
+  APACHE_SUBST_EXPANDED_ARG(proxycachedir)
+])
+
diff --git a/trunk/apachenw.mcp.zip b/trunk/apachenw.mcp.zip
new file mode 100644
index 0000000000000000000000000000000000000000..6e7e7224b328534b6c85754575375a52d75d8ef7
GIT binary patch
literal 189152
zcmY)U2|QHq8$OQPcP9HzQW4q8Qr20rWM7IRB*{)?kYVg=g;bUjX2KvLZ)>(`v9#f2
zkC-AkV@(Db4Zo+)_xt-Vuh&V>oO5R8-1qa`*L_{rGxk=jY$8ldOk7N7AEMPp17?q2
zn`L22PBLKP17}g!y}bQ=Y+clYy{|79abBM49qmH}uT|ah(YzrvbpzdNJF9Q`*di}q
zhTkkgW&C^~>ae%NtjgIhw)(THo!c|fYtwDfEmZJ-=hPr&-z%NKHH%~_^Pgobo7^}g
zcb(}LlR#Sg_WeiJjpy%|^)sJsYpgMs3R=sFFg|sV5%TD8Q)Ba4ea52;G1dd~LXR$K
z-v4ObSIYk04*Tt(TH+*e6xxCIn=FRNuJEa|Lqf{qN6xwzG^2cf;Z;e@e#dB@e>?ex
zMIlQ+(MB0p-f)aKvh>bjs&l0<wFlyW4gF+krM72Xv#BQa#Yrz-n*65A4+(XBRAhvf
z?X$|h=}7q#!hG)4cAzFhE6+W(<UeUw9(OKxfp9cUSR-)^X_w5fw9ZGmLs$G18pQ(A
z#!%9P4I(dL6FLH!LPwP|JDi}KWrIoTNr{jdj3_$Sb^SSkFQ_=aL;s!!lMy#n*V+Yn
z@snF7RRw<kXYY#je!5THTN(%K>Zhm8<<1_Q(2UwnF6P-SD)3-UA*?{7kPYMvU#mn+
zvTtHKp;$kJHrqVhiZ-~{CD_J3$;*$7d!sA!3VZTlTEEl1@mz~EVub>powOa#Q!t)H
z-GqkM8OGN8cYWg0DL;K71c8EyOY7psv(wdSyvqE$^4@ej>;`QU){x}nE&&D)ouB3g
zM?!T(6HHwE9y7n<ngVQYu`ffHrkTSU4>g*<*A>J{N)ajCQFvBrC`Pi3e49E>;QGlB
z87@IyjM-PRj!XBU+@Yoswvi=?tEn?Qoy<5TnwOu{)><EJ8k!<RqSoS#Svn=@%CsA>
zFr-AxMwKKP^W(Yo<2yJB+X{Fo`XQPmya8>$;P-q*+l16!oIP0Aa*z?>$3fM*LO<$v
zV8b|_%1JofwSSyM>HE*>#<S;%dB_D!{?KXu@Bb;OCASf+E|X=3dk%=@yioCH#>yp^
zIJmObB#mLD2~G9~+L+q-0$#H)bLHFm>of|s9cYulA)IezlnwC|-pO$>7;?XwmMwPn
zbZ)usC$|hL59}BdCrDcB`OjbC2T_EEgug>8_xNlu4bb7`hDHjcrLS(!qA$=x5Qb!-
zB8Zjn06GSvAVq@vyLQBfgYNNi97Ym2E}B}<TZ~pwJl#uCvF_B6lf4M_>|=DhmPQ(t
zam+3zPMk#P{ZAv+gSnFnr%1Dfzd*x;1x#IHEMhnR3LOofhIk1JsJhf*?oJMzEDZ<q
zLxIE=bZFv?={##xoE(mOs4jVixl<A+jTIbYL|B*b;01NbZz+Rl`b$XuUaUT8Fn+bS
zBj1~T0?t0ytI2<*O@3F4Z6#@yeHyWt5<<YIn!yGWvahfjBb+NlZ+25cA;FE91S!C}
zej@rTnJDx398r`91I%S<#9cJ_horoUxa&R1I?Y$Od#J83XU6p7A-p1KyDa!k2g*7$
z;pi_$rxxRAUZ-#yZyPI4n|4*1vz#yoVF;dY_Yw+<lYc|pequP~hbbUMEV#ooWsuuB
zVjt2j!8obIgx`pX>I6L?^r7wI)nB!hr27lej|au3kk_)Y%yj-Cf9sRbg67)m0%I<^
zT34J5NqlH6iE&GSrVW>a-1K3x6N~wb5N)y%gWa?$NSIK8v`Z{T7>VJSX@}q*$ciA2
zu1ogd=oFZ|)3J>lM1nj867oULyOLIJ>5#IMw_YE$ol2z%6TK}=q=x&DyIN~s3XFLl
zzuB&PMQgvXHFzp}pP7-N&eRHHQDn2<zR(&m4rTOWUzHS>9LvgJrpwYo;e05Lu#ej3
zEK1n38s~kk#H1EKrnnXkdH!OU5N%_|S(-5NeY)7obf*|Hv+lTJou>lB4dy6|%c5!!
zHni5(3ikNh1Su_79@$;~61cv-3F$!UFcbDjBX`^5F=lsxUD<+=wA#dGl$R?4%Z{}J
zkRiU96q2}wW<YB8oWH?EOdF?Ed<15fu<a$i<s@gX6r_&vaLW<+tb4Fia#+n?{O3wH
zO%A#iL*^Xb_Wp9?(kma>7}B0zB4Qveti)~fU^0WDX~Z(kF)b~XbOlltNy|bx*|W6C
zT4GMx%jsuz_)@=~!3njQJWM_TdA{JkXq`qBKG%D1996c)Zp2IFBDJ8Ev_e^iOQD8!
zJkK!s%9oEfoZ5KWSSAtEEGYzlbbh=etnR$itdrdCh?V$|cn$(9)DMLN5X=Pe7Tar#
zAU07h=xD+;<O5xUrTpX@#oMHKFiDWEp8+k7Hsv+R!cNSz=frY=WJ$$4qwf%XpqqZ|
zjUuk>?tJbnH3<MGP}Rgud%Z@nNv4{lNdhlG@O>`^_N@n-JDWRKII0LLhgkd+ux!`N
ziP0D*doih$R6;cB1eQH(`xGe+l!F9TTASOH05T8)a-gNmeT1-!;jLHWCF~wFV)h~U
zE3@O7$X-&zC_llV=7V)^ImT?krZ|aVK|igZ(}>|+w9D+Sq_s)9kNoYMzm#DG=s{Hw
zG7{YYC4r?sn8J9gWyEg8)W(ZDK)ayg0?iSWK<g=HGm^vU(?sCYjmAIloHWfcd7F75
zoC=K(4xLE#z2Zs;fBW<FyCs1#c`hRab*`Y8K-OBzDKKWi8F$4=k>V<LnYZQyA$Lfa
z=!;e&8Ui45u;<!B^w3@d+)5&FBC}JoFxd%moZyRCXcyorP<p;7tDJ2iSi!<X2**LY
z3j0H8FZk{Hv^mw1`p>^xVjGG?dzDfBBg9;@q7Z#FFKG17-m!vWQlQD!96wY|h(yaL
zdsy!Zbjsj_Y3K>E*su#)BLQF>AMRv-(hN%{KhA(A0M|g##7LBUqTJmMdA3e~^Jw|_
z8U9WLowNBnqrh0ajaOF#>7jw9mqT~%#Tt_|;%&WVmbCD)!SY>k2-1G{e{WB5h9sF0
zk3URXWzR%%65WVr{bclcY>+3gCdxe1@*hxrgk5wCM$1p?HpU6!dl)Z(I;PCcj}nB9
z?KvzlX+*6`rfF$?79&B?4PT^P$_yWPwxhJeAY>;(K6)_CgRN5n$4x`SK9C!s1znfu
z!PF^)J56(iMWJfqII1q8SO7FTBN`k09@-%2p+b|3`Hgr%d@}G$=tj_762XAziy2Ik
z<131nW140LICKgi-e<_0V2;jCDrPkj#|hE6COzSG$cYH%Jhhm^h#hwj%rF%?jupa5
z(2m28KyOipcL0Q@q1U=~W0`OoG#l6e;sp6yOPXQDbI>JdXJIF(f@p^<N$Fz8OM`xT
z1LlPm2pX7@wAIuu7Cbl3gr);mLk5IMjC@KLGhSAoAI}9yffuX@@z!V7#e47+r5f{q
z_ylPu;3JS5aU2604PPfaXid8CTgV*r@lXOIWk#S=9LGruf$>l@Ku$1gh)yP)7EK?<
zfJbrxP-@Hp+Lam&A2c^ekk`n0nAYPAFIem|(Ya}g@E{aQG(pBC@3ArD=)5BFcwQQ!
zERK^QOIHQB848&Y_mTUFu{;a}U4v!>r$M2Flh8hjoE*#C<b@}{p^ZaIFEUHgj9D2%
zfV;564<KKn9fp$H#e-+1AEl|mOHd@i6GcvqWx{7}iGvWm;b;g!EJ2zi8gnxE=*K{A
zoFEs1C(`6!Znzj?bRn8gCF@ihn=4mvYBSo3XzM4~$mEKsNgYE562qY=h{KN;pse5s
zzdKhE!kxvP34jjN16_enz>bx&i;2#tLc&MlJahuK1lS`)H)>uFg-VF?r;4j#Jv1Ew
zc@j)eYP7=3IF6^OiA)SRi<T>GEUw()L!suoR%Arufq=9&f+@rT*A<Z2hI^p3dwYsB
zc|XZL4<3dvH4a&wvnNj4Peo7kE)iDj+4Q+q;@^Otpz9}&Rm7eg;oU^(p%_pNq}+&T
zQ)(2S<d==#LhcgX2+V+La!DoECf25g#G4Vk{FJZ=_yE>ugtaIwxDy1qk{lARo;-$>
zCWJ$x011!!oor-plbPgkM{FX!;1kMh?%ctk)zqfe0<yY*8Apwyry*BAMJ&RPQzThE
zF(g?%RXt%fCAdQa%cjo_U`$?{W16!~Pn*Ao;0=j9j1Nh>Mlb-Sz$cP6WH0mqR3Yy?
zaThZO9X}Tzk|cm}fZ4DzkK?n@h~%q<%hrt(=qWHb@6Q4G<b=0Hx4DZ5C5NOuXQO
zhcOQz3GFkxyt0W|$QIN;O0u0Af!R*!B}St=AvMSWjs>(?UL@&XFG;G;%#N4i0c9*n
zvjA1(1*)h5ot*}tRT9TTI|EAH>R+iR7Bd+M1FXFSOF|9A1=L`IoB&wW#<YX52<;SX
z3h@%n0k`lFFyg=+#~L(ivD;v>Q{_0ziQfN!Wi^=x;)V}nIk7T0CYl6X4>0%miUz=2
zB7j*Z=q(`)c@`Fg-V#q~v(FRFQQ67=*>m6wv2n_rokCN8IN&Czf-r~<P4-~#6u|M*
zJm3|m9hB-?!VEXSL~THiF`#x4=(RLs7CaNET@kt_AcS*JAHfA#mpa3N7oxM#uE92-
z=v$DXDd<X84_0^fX|5HLuO)m1=7II$zDf;`OlmHeVbw<VNoIGRY1THm#e|Uf2#`1<
zq7h_nzx`KJ#EkA*Dc{Dum^9`!-LA=xmQU%={<ZC65t<sCNIOyxl5CtBHKjGp!4RQP
z?ox5qEox`>piz5yZ6<dCcXoGXcLYCX9IfCd+$cK9vWe6~>Y?>edO*zl`wBo}Xwg3y
z1|Q_9MNn*|{3P!*%Suvh@*Y#6g0)7HE=JK_qK$*D_;ckIO<$R1C6$BdGMo2XA0X}&
zaT}wNT+G@jf@5uz-Q5YW_7nibS&}9MXF?l9fW8ScJOIH@0&J3nI0?D$qS<LGWuAym
z1kfXL@Y_>aYdy3tkjg|5#zO;1?}2nIOvHx)JJ4EdD(K>96QhuMhqEt#(fD?HRux(x
zuAxm*jG6HgbUvC6PAq{jT@WikKTNv_4@2WX!%*V?2ekqKjMIRiDnTL2ef8iw7IC5g
z=<u*PM1H|<(o55(X-;&oMd4+rb|?)DU9lim1b6BuUUFCirO~%-@`^^eux0*-KbDzs
zfG$ka0PwX<2*r>S_YeT7@US#Mv(SHN#tLxCh_OdAz>t&nI2e+2JpgR^058eNxU@Z1
z1}i{16F3mkBc24Z51?IIEXQZwH1ZX?Cmi-?!wSG;D8?k!m;=DR2u;+Fb8C&aAeMuE
zislb6)P<^-)Wz}tLC|gD8qy?T024b6E#&N-0Jz-_J~Vr_fN@|LfeySJCi|PNJX8|D
znn3fnHsP!3>1fwt9BLG%#36>WKcAk;iq>uvnB;TkuSx#Lzr-<hDU6+h+7xG0ARz=6
z@;ePg7#{!`Hg_I?E&x}uO=q$bbPviVzX2e09@>AwuV5{X$u9K`_|e2d9fg+edEBO+
zfY%Em6-eU9y1s2UEr!YQT^E%w0Igy%EeGgoL*)29E(Ry=$nt&`wS-7P#U<`BF~sRQ
zAT4}nG;l199%Tla!6{;>>@zdj@q1=IBChdklLTAXWFl4FIxcHXp1siJU>)TkBN{$$
zu`e|2iOTNnh`T~Zz@vY<WIz5D|JYp02TTbN0*gv1?+e+2J$aIqW+&TXqHE=o*>=#V
z2<3mGC4m#cU6bgHQ3a411*JfBIoovvfiiK-0wxex2c{5*$}kjqIZTVR|E6u9H~37O
z=wfp0ohV){cP4k9nv_HcPgK?xC?{O>6KT`KYA6d#bK4-z3I8LaSOYBI<3tis^8c_<
zfA|#5_Xk4>j<x6`uslq-32`eUWK;K83Jo+nMfKSL93!wIbk(0WS5z>F<o}?v@CWCI
z4t}a5tSgD?De8&3m~mv^dUT3rCrcaOBuj8&ZHjtAZPF_9N^)&l1QL`kk^yzz+YW}#
zTZE?33DU$uVhIEk1TRr*;?tqJObbteBBXvg@LRk-wMz|aVudIa;o*{@|CG(6355W&
zJs?|H3O4hTr<t`?c;kezMnJD{_?a}aO2vmHa1a$>CT*Tfq&Fm-vn@<8F55=80FHJL
z%Q1DGYj_2EaCw8{M>wJ^nxLnES0jz1?0P$<3$`$!z1uBUEH%!LbJ+hR>Ok}MT&@CY
zAnW2Nz1JZ|qy>~JA;eEqBsmW)j*%u>5kC^F2&x1dfG-E4Jeg`rwXx@sE9MQN^ux{j
zme%5q9xq-h{dP^IS;E)K#J$^+f4}M2(3)o2oZVF`h~@b>lf@`Vn6+od9mJZzGtl9O
zi8DOA$E>{}2W6i3_EJ)5Cm;q<=3yGhFc7#0Xy<+~L|}=bvoJGs0~Sz@52s{My<q<r
zQM`Ly8biX+)IH-wDxOf`J)=$HhFAXVv60jYW|A3j+A23cI*lL;=~i-1f=P1MAnBpE
zfjFv7+d_|{cR@>M!tyrC-$r7fVCV?eJt4#lr-wZtl^T*_oaue)HYgV}74LUT`el(r
z5el8M!+``Vtx$0izEL2?B$4X-VtKA!-tHgk7snl=T?cLPGuE0A`DQPpz*r2&2Ktu+
zc%6nGj4x(4lEw+ptl<<uZ}UG>-t9_a1r9RK0e-ka6i3xu*uJBM*Q{aHU3*1AVCXqe
z`#s|nD#mZRVEd|d30tQ$h0HXpYwbOe%_fp^6F4QOv^i{$Cn1lC=`8ADtfxh47WypA
z^)T^-y%>;@K#W9zbj`opJ)xXM)5db1i?>CV^k^AoP&)}WFTNyotR~SI1iXcOFKq_8
z_Nnj<O`=hrGI)i4`uMK%q#djV`2%VfNOVDlCeN^Tif@JX(fXmKf6Sb)2Ds^3k}(th
z0Q~?h7WRhH0BsyJof%A+G3)z>>w@r{y}=lR8?+T8gznmFN*#*62{6MmgIY~k@SZWy
z!gJQhQ{qI11+2}fZM@S!YB)j6z@g)tmTnV{NYl(jwjdRu16VeoZ#mmEz&Zg{+;dRU
z@}BJPE<NnM+BrzePv|zrq%@F=)b4Ne;w5Vo|3M=zV0v^Gtd@pfnd#I74eVf7#X!7C
z-+z?u*cb$zgBAvFL(>4h>(C~IIiB56Z+bXv1&tHxkS57pObjm2Zk%9WD4Xbs0T9U4
zc_50+L>C*Pq{VXn<H#c!;rn94gGi0Ue$HRp;{V`Wq0A(Wx<C~7o{7|A2w<fs`#i(y
z*5r8KnL3nbDnL<ox<1VmR)z8j@)$}=EEDKWf}j~GK_vte@FiWG3>na!0>QUx5GhD<
zViylXfUZW1f<u5Xkq4$DCAo{4Axamc1;c9q72`00`QPaXhWyZeJm^)tuIc}Px02VD
zDI9qRpd`*uazsEaMGT`#JObpqXd??<V{9~&8UTk{><b5&;`p(0;m(Nz-`Y2{_>pRm
z!o!4U3?~qLQc}rV{{$U0c;m^M>G(xIt~ODrgkB;mfY4Hi?J#D$^aQslQ4$vZvtleT
zok|l_X8y-YIi5%J40l3GUK=O>;(3SOLK^pGvZ+k8W1kG}QYC0sG4g%17;E_?{fP$z
zbIf3Z2aAyeC=Gk~7^M2oW=dX7l;bdB17choNVSthU({e~F*Bfy>NH1q?cHuD<ed|H
zf_4Rt0@N`drI9Enz+lw{77_}mx${sdp%1m+-Jx`a&IXTyTFS?ed!znv!Y+`B!eacE
zw>8;(L5ZdW*JHCT)2%?>HQ<i4Jw7lEyfi(KQ4<0gy`Qqj&i<my|3^`LY!Z2&3wTZZ
zKsCu`&Fy>9-TgRpvr!%<XnF-ScW=*_WD<YBU_1K1G`Z}x{Uqv||HUV1HL@4PNq4l|
z`5CfQ6V!g{<odSxWxJwZdw0md;^L%>k0h+^S&lPViz9i7ruO2Xt+9k-G)!kS5(Zv1
z^T*XC=Al*nPCt)6LW=9|$bbFw?VsI$(*>A8TrW)n`lwaM9>ENI|B02HPowS=oN*qn
zvD~C-s04@^T4becTwTRL0z_Wl_9VpF%h_{wEhV=RQlLYAT0niF23<h&%+J}*C+xpH
z5&S1wr;!h|)dc5%iK}~cO?D^_O|OGE%0M`haCIYtc8RkHp_Vp=MkL6w7bO<67;)+g
z7;&`;<M@Dt{|>AcVc^sn0B<onNe*Eo2$c6#m>W6?1i@fRS9S-P(@2C0=K7xo7skl}
z<(&W_VEt_BKOruN6{l&!X$9LB*7D3iPUzEOU~gsf5+IrJl5|}FDDD7z8X(2`{gPKS
zML<6h7<r&KJH_dSpprsB!HN^=FrEortkYQ?b69>f{Up>vs6$i0<em6yV@=_fP3l*?
zH@<ss?;uUNjFL%>CLH^;D?%zsmdjitr&2@fm&KMb5`a_zMI?^SN97}@2%S(aG!F=c
z8GOah0Lzb6Yh-QXY!q%2XjA&v-@CFp$Q<qov{8EvEGt%c1ToF$4rH=!v}Pw059lQS
z_8JNc#NW_V{7kTljnX()AoVxF!)IeOQao6J8NdmYM?XN+d{kYc2Xm(|P8_i7P6(Ka
zK${rz0Wf8wdH-N2!kHFiS>Qt`06PH~{OG#WSe8ONZ@LgX50Gmd6`B}(J1Vq?rUvxM
zFwi<vgk5AB;nc%K0b~pMEhttQtb|lbNP-zb0q8deKbFVIPwn~c6WOo^4^z7`JIL(Q
zywn@YAW0-5pEj#0VeQq=y#fJb5-=jUGEtPC4#k2QX%!@J?*Qnq!i7*BP~4vJfYV9>
z=!$fe`~N{SlLX)|$k5qoRsg`(2%eZYQq;R$U#KN#PXX+D=mAR?km~p@%a3n=h8D!i
zwMo-CY5cH3qsOORV-h84j~j4tRqV0aQa3^-6j8~kFYn6APOO2Hu6JF^q8@?Rfj3|Z
zrUnPAC<784oP>r100rWJbKmWXLOvFrKqURMJzbN-*Scwj@Of<3aJVp)muPpWQ*1aK
zs@4iUNh&1RecxTubiYgWUYGfO7}f&HR2+jykz+Fw!tr34BC`8vpMkUlYBIi<2P}9F
zBUWHv9S3-{L0mv;B-A2j+z5RNjH^Juh7rY)C4D+SQVNU@O!5>m|JXcGCND6ZNK4Y{
z<ZTn$C{Cve6HqbxhSp@{rp9s~mo}4Z>QRC_5N(~nR`9)Sl1}|6*Em-a%!nR<oJnIf
z{P^_QGBMk!SK+32yE>4Xg*l-V5`?=Tq364?1v6ZoSp%Mbr_;cKX|SLqQ$Zuv3Y8dE
z0BU5<xIn#!)<2OQi409N=EAe!bb#r!2_&!AM5pMm9=a}Jh6xB^JwV2c{<qkG&BTjm
z1D*S<a&kvq;!GmVfS8S`04vS2TkEd`Nh9UW3rVy`9h%+*aSdto(L|xqg6#-v3Ww=0
zMw(Wq^v7%U@(n<9Ytk(Icy0sM!A4`BSkSb=a4WO-BbA6#L<8W5B9i6Urn!wofD<c1
zGyB2dXlp)*m%*`Nd2kYqd`q#XNDrXG%NtRD@qAQ&p!NDRGXW3nU?G9dr{Z0p-bY)S
z$X-KwCV>SeMrQ%i>LZYI4ik9c;ku#q#4cdO(T!=RVNNI;bXKqqxj=`Oq#5`b{GI{o
zi@Js;C&UUcZjU8-{|U4<VRvUObjulEpiZDUbN2X1B`LM#OJLV1QQ-ToC$#1D#rKLy
zF(;Vz)4&VJ0Ip&MS|h%TZ`aqGj)l*H-J}YnMzS0NsAO)?mVBT)|NOalklNf20<`00
zB?yq?BQz;L_A!R5wLE_(zpm#SiXD>v9&&-{iPSkli}y^J7G8jM9t2n0O-rdX@8APl
zDL7zHoFrBN=h}nWNF+j|m$m~nfUPRfC%KJeaiTOSU}!86Tri=j;LBJapP4y9J5&bb
zIzKQI#bB3HsQ?Pz+l%NTP#$0p<_q-pUaShqF6m0awxhKti;)b4%suSs{bk$R#F!8G
zAAB^QNf+R4wEvs$GzO;@UISRjMqs^Uf38n4769gl2*|ZCz}Uedt>l@E4hl1#iJFb{
z1Q3iDbWI5dcq;8*^kPS9FIHNO6`xeAQP7pr%)VjkO;>;m!Pc02CN<6>i$$%{*Sqb&
za4zJTv&Txas}zl+@J8&X(a1zHYCmxgc#tzCTETsd!i$MwNLk1c7==8O2_1Dwdz@2Z
ze>+)R`P7oS61`hxhAG}NMwi2+f75w~;?jD7okxmGjJP7lFQ=bG^NJy}QR}XJk@q%<
zWd;OJk!A-^0Y<lmAwMO1?K@e=ap5`X%)tK~#~vpDf|V4DU@!xM<pSG5WWx5LwQZyc
ziVoC2pkr}KZS|{UZ~A!{|6)gMZx1lP@{WJgr$^ZKo*C3)NcNZF0m@k0J(V%y(q{(f
zap+;nH3AE0X_qIaGpIM<JqWnywkUsC;hb~TC3H5h%#6f91ssNB-|comvW@DXQI-<>
zP~=xyF@~gJ$YH{eE6V5IfWwT1l9mlhxL_M;Esxxp-R%Q(<@gl4T7o`tgTSjGb#6<3
z*;AVIk+AkQR)HjI&lHg6N{y^o@SUi6g%xd-T1<6DF9G#t3UO8~V|ed*@VGP8r0Cw`
zAHy4y_Iq*0Y=vvz*G^ird~27t-!Y@dLH?iI?yiZUOuDz1{A3Hdq=&8S^K^m3;DRyu
zx66Z7Xk^!CnX=O2M@tj#fXyCNLKEn6D#~mrL{(xSF&NskNBkzsO{N34Ob&_wzF6Qy
zs%*hOd$hmPfA^lTd>dkD!K;m<O>hI$^9es0if0maynfk0?CCNpG!3jaIpA)K0n>>S
z`0H!`HoOJERtE>11f_xAW=_aP%O`=>C<R(0I}9|FCuEQlYXYhsSk(j#bP3pKV5F@w
z1Ir0)9f-ogU>WaUnTgiIBWUM=e3^z~SSB0YjpjuwFEj=COSMms%Juvrx_$2JkL9%5
zx}_58Pr183?mcuI8q(%K55}4~_MwDE?BeS4Vjq@el^?D|d~{T^VO+@b_g{SQ-z6)j
z{diH=$8`DUBSR(+Ms7UnUOOEA^)PCV*w&<-nX7MSHN5*$$Mx~d%bL+4+CXqo9x2jb
zsY$zY?F*rt>OQ;!E*)_PL)o4bFig8tR!%iCv$q=Fc-7<jxR_J@^Uyh^>B{mdfvBoH
z5`EFf_3@&4exUy|tKgv_EMw+*IhAwz=@DvMTuL4(?0R*c^MJgXjrV@-(2({|&9ZX;
zOI{bOh6_GbgQt1_l~nHEu@IqVGiOovc}Tl>#T5+4YlnxlLqgK>Nb5JZLC`-VD)LBL
z<ncg%DW$Ka<^FtY{2(7Xl*)2{>kT9DF?L;N!6(uS!7yQMbVysQ>tB!?AZs%@+kyT#
zy)HMa;pm4(;Pu;O5VY;pl04GxyI3`w?FY<iHskxOAO?dLKmTVg`~m*Yr1|~*1EQtI
zhDOA+pO#lKl);~sEoU{G;O0`-$CEw?FiYNX7FNT5cBUG^SCaGdNcAh;;F;>>$A+|>
z88cv5BMaj3STP2})w|%y6|tTmwD{Eu5b%Hl7+M_#?>&|So;mK($k52X>a+5y><iXb
zP9}A&c_icGErI@v)i=Rw%9CSYdgFz_oUT}dlP;R2;7+8Yl~Y{u!#vXVcYigTwXTyO
zIA32djfI_LaPsA8aFTZeoIJMZp$5Budk#*z_krsl^@-(GM!RKsB;6&0M(rlAuT|jn
zcV;lR@8v7YsV|pNV7M&@=5gnTx|+?PNJXRe=y`dN1ogl6YBu37)BOFP85n_u#+VZX
ziDS+NkIzYS0M8d>><SWJ+~?<yGugNRf{c>~@qYR>2cn#dO#~A<VK)LYv~m`FMN$d)
zim2IRu8%|X?MCmPvx|G2N4jy{ZhUCOb5;`Ez$mUN_y4-n(5StmbgMa!<V#%e^Z(7d
zehGYVS#d>q6=i$_1cZr8$RkBmiU;`PIBw;DFs(Jf)OGC(feG8!7#$jM-ai3`EgIm1
z<#u`0Y*y;)z!UfWQ31m{b>QBkf26?hdmXqpWKSOq%j&?rwsa2gw%AZ`uh{lca5gd&
z+`F)(1_F)kJP*?Ur3I9n`6gJtYj0<WpiI6PG-;29&Xj}snQI3z8^mUVl?#J4Inujl
ztY(8>nW-zMe%S%*ZL-1ytY5>0G_VS`4QtB%gO<|3J0y40!D4cd2dj8*@!yi7#asdl
zE!WP^UrKM|EGQ%`<MMKUnKu<p+MC4vyLqIp?<L^o;^i=K^FzFc)$oNX4RG`JhABvs
z^D0=7a&uPTnpn(5@W?xLe*TMVjPu};ACpPtRQ&3A6D|DXh;dPOj!yu^cGe4wi@O8!
zs_<qR8fs2UZr$X(DuzMEx0_9MN3~vDS`oMW8uxN?|G}-Xn@tGi_1E(O`}VWGA4m5p
z&-C#$X&kHfPtossGSP*unG)Q-K+Mumim0>idnDXaYv0!-{6KYN9X=D1qOV(gstGO2
zYiH<{qVG|3>orePmqiB{rxxF$@PvOgTz@aRcmX$CsM=V+{Y@Oa>rc0dOXb{rMsx1s
zpXe*2mf?Jc^-<;eM~hn{%Js8KV7IEQ2Blt?XW`DXUaF&7yWL?f&*ru=T58YrEep$o
ztMf`-osP1@c5Kd7-n$v2=d{LD7<$hg`*wtL&M&scqCLv9J}dpMJ{QN-z2Q<dx0jJ!
z=h(L=O!h3Nvme}Ru&i+tu6C|AW=k&~4Iu0IFset5!@5gdsu^SH3(uW*>jdjOYqs(g
zXBu2r7R>(MYMNZg`m+?!lr4J$)iR05;tH=0$6a~uwo+*R30uurPwxw_#?#UlBCGNA
zbVOt|<8S(4L^b1AdMLO`PcH#im(s}*)%cb4yp55)gfrVwiw$fycA^3($SZwO0iMV!
zl&F9><m}!;6`nc6yrg1F@bFAb@ubVWKfj^^N>H=a;KG3n%9DyM`NPgN4!gWU`Lzza
zdtg>dw@w~T9jhGFJ>!)*S#j^y52+@y!ultjfPJ&s{=kv0jBdTLN(LpJ^4wu}Mlhji
z@uX0FL=6a{HL7NEEla|^8U*?@aI`DBTNeDqbq|j{8+7TG9)E`4PS378zxzj!;#R%2
zq`3E=^U9KWW1Z73hfv^n6@xuP75v>vmmaSg4C;pUo3iBu-7B`fD9Vv-S9~oxf{P{*
z_x`Mc^9t+j;Q=M+*|?>V*p%+un~PxwZ@kAf)hX2DJ0}<JO|*NgL|fdgbJ;y1RJ9pk
za%PsgG#Z=M%{f+$=gKGn=T(J1>Q*v@GK!=@JjorXl@<%bh@?ro`?sbznz9wwr}-C8
zs(i+EO{QhH&c-y!%idVp35e65{jn3UZ!~MVP|a9PA1|)kVm@qqy=!tI`ww*|fNVHx
zw@{5|%GeaI#It97)Ue;>JmJe3Fn95pO%?x7QL+)EcyJMMha)6cf{a->)*088C)Jub
zwxHJkR2QS-GD5NlP91T!2u^l)tjE6)vzJ4i4OYBZ>8^5Y?c@j6>pK;<0s}L;np~}p
zxqo_36c7J(q|ZqESG?T0(DMrp?)*G{c|Tb0w(Z<6l$V-C*4?fOOplG$Bx19MNM(ix
zRPEk<@NWHmywXrcrRnH=j(b&|GNR|hwB5^<W7`JvW))w*KXfa+Y3CGj&9dL7igYae
z#JqxQ6wX<$Fn7Uc9(6Ga?JSq+X)XVOf9}XbN4b>TwkpSC=L1SVDAxZz{@jpF)sFnZ
zyY6>KwYH3M4Zr0^(vTeST;;<t!SZKiBXJKcGaa2Ap2=HwVydny>+sLtxL8G2L433f
zyghXHsfbuPYE}eqm~8xTOQ_rn{gPG1M!-@!*)hQ-V98R)-QUVV%HiRdaQS<*zk!3)
ziHBlx0Rj%Omp92~?Y|}M_e9BEOxc%EmD}VG>kfOmrKT4nYPDMLHb?cm=2i>S;QT85
zii)f|*<^yP<b2`yu_{K&WhVQ#x8+p3X3^P?RkxI59YbxO*wtN`AgO%|l6O1omL5xr
z$K|PphOypvmHFi7P{+d2?(Ed=JQ|htdf<ufX279OE$%BFYK^7U!)IQ79cX29fBmE3
zvUwzLK!Vs8Ej}lc?tF*RlvvYY%2adyg}mZETK*Tcir<;N%c+-kChcQ4j*We%ZGUxi
z(G@p&Y%DnB>6$C7Y^AJM=EM18?q;0hz{1=P)cEAVPr<u<G8r<GPM*pfQft>jzZQQW
zJ0efDq{FtZji3J>vYKzgx6L`2urHP%Bj3NIyk}J|A(V}^yHwfeYa3>#synqz3XaT~
zHLl4zN0fyv9E3iugfwN|=~W-Pb$zkHs_SX0OJK0)%*dbHO72=dr8h6t1zfptY}*%p
zInbeql*Pj-e7URv7b<>RYFw#&GIU2=C7(8w68nkl=Y;!$p5F<bT->X)iL33e5I3d0
zI-`-{ho>c`f1uYj&BvC`Z@UEtxN|J%whG!FYa5AFeS36a)&GcYW}IE&evv0p(Vk&c
z97_{x&n`O8=-q6WlF}Fh8{k~w<U{%L+RweYDt<whE8!U~{H&`Vi&}IJuWMYyH7<Xp
zPaWQ@yr<?~y?m*H7F!VV+0CGeJjK&ge(w_JJymh36K625-!rzqov0E0yck*3p3`3Y
zYeb5%Xl=BYSD9J%qafkQ1awg8W?Sr?E&OoaRqEHBN0kqL3N@h$V*>BRDJ*)M$F3s$
zD1|d@N7mIB=i`u$11AGcDQ!#s7)nna$ys8Sx^Irr=j?b!SCO4Q)+)k|JY?>p?N_Y7
zKO8S2C1Y#b`VJ+3x>sqT{)ct`6aD9A^MN`8L!+vrwu;pb$2@I{jtwM%ACxE<`qX(K
zg5%Y}&o0yx|NVAC7oGpl&%+cRlqnf?1B#^vct_{$xp;u6nF2ow)`6P9Z{h@iT(PY*
zcicLAdUoVwl+}&6;PEc_nVBf+*;Pl4n~O%aMc$Pyr#6KuX1<T8KEWk91t!W7({Rzl
zR+@{`nfUXu4$E~z(bBusw6WejmClBGvSk#Zczk5;G0xT7Gq-qj<j!N9ol~9vqJoVP
zsVY)?^Y&OY#to(0dB3d_Ysj*Akca25DeC1rs_bcP0!mK%dg>GYd&9an2h3k1-f@St
z{Om53?j!tvkEP{RXM=j|oW%d%;l1Bpzdt>(AF>>+x78`VJCliD>+Op4rnJ|uO;2ox
z{MG&6#W=k!vh*$`ld;yjHkRoP{oez;yaD%W{qNWdpKDp|l50abZUwGxlf1)g_kYsd
zhSzHMXK;1fme601v(vWva?GQG(x;`$nBR#&sZW?MRpK>*vO`BX4t(*WR2U|&iRzF1
zUFqO#y@%7zSoZT&ufFVi=}oQdTg^R!qv?Ngu;|$~7r*hjgUw3m!Q5Be5-0L5rv*F>
zk`7i4F6rvroUwJRXtS|=-0YjM<=Aspt#Q5BcyS!35PL<>l})?m<X^S(v1jTyGqII4
z?}M;RJ>{B@FS-B2Kx|=d5hFsypfY}y5>$FK(Q<K5O?UZ4m$AW8Ltvlgr<XS6A8d`>
z`nRkWb*$UvhIJkqA{`p<Fc!CImC=4z&&ZcPSC@JjjFm6<-!S;`T&C!dXW>xsYv$XL
zQ#MYY7RUM@J{vkmyq8(?`MJJ!wR&)yWnpvR@J6G5i|)z@>0=|6e-c}z>t1T(5;$x+
zi7nT4ueNdV8=jw}=?Ayj7N#~)alviKLUrwBeuhU;m35G=<X~jrZUd^p?YT|9-!N|@
zHD!`^C>U3-+v!obIzj^HGAC({!MI1dotFwjhDe1?RHH^}(<JteZYR1hL?_53w`uHL
z-cxhcso30W!Y3w_w}<YYkZ|3<9lPBeq%A(4KSffDZ1Os-!d`?~tiR}Up+M?<-d4XD
zX_ksUq#`aP$&;tAS2&5!o4qHO>va?BIH2?tr(Q7nlp&<nc3KCaR(LY|NLJ4V`?TD!
z?qf%G^OlOAPa-~a9v-f~`-qhNq0*SDN}STPakxvzhCS0ge(Z7I(FK8nKN|xIC!e`F
zRe$D53jZ4srF*(1XGFP1^Z_ef==)IrOQW1821B&RD7R&?>A#lvl2z^1;nCjAj^WlE
z+D$XJK0-)me``+U0L21lQ=xXcOasM#x%#%1%txPV4ZUjRatF1`XAaU&j7vl=50p0S
z+_KfH@Hpuzrr5S~2rvG0{Sw_z#p52oNpSntaP!jG2--qv?sI{)f(W+Vs?pQoQFFks
zZt!HSjX|S-g|6v9KD<=!+?O(m%bu~7+t@rGI^z7&!EN3wI9Iyq=?e!>b{*G<&nmN@
ztL}Co-fcLl4Q^mD0beeaNfduNdUL(QE3UoKx(z!uPk&uj8mn#T;xR4b@|AtESq<uU
zfvbyef2_YX(7Kp1`AmGVS#@*8rYux1WKAkKdK^y0T3tY<zW-F;{p3hi>=^?#!Red1
zT}@SIRARM{$g38QUs&e|?vciBjM8s6y!>?bw{f-GmS5huzvK#Zq7A+Ks1AxX_GvrU
z@Ro)Po-AE}YUHyo{XL`ZkS?9o=e%+&Xf$|mIC$gBtrI!M*Iu|k|Drw?Ozk3x<j0`Y
zKS?1rgo20jVbX|MXMwfvaK`Rnudvoz!HX4=b;FrdL8sG_@bhCoe!zFVMy;A^E<AIq
z8_%Y!S6Q#$PT#B@9cy=PDeGPDiMG8qclxg;HPKrA`A_vj3rp1ww_OUGr7i>w3+(Ey
z_)d_5U+LoC^V0fldYl%A=ov|$S^`bRB7&(alatMX(l6aTd5v^c%8%x~8+@2|<9I|;
z^8|m}%c09*ZVEZpB0@KApRWsDZE9oJVQ5J8f2+vg<UHA@d@UiCFQ2N5`tS9pZ+?a)
zXXUb`gPa$2TLZ1!ol>4Z87xVc<jY&)$gkvBlzo3$v*ieFh^QJ7jVkWuAG&-1;#V)n
zQ^f5!5nlYS_l}*`^G&6yOyBizJ-+6o;_>=*_f^{guklUKXYK~VErEKlz{+gn+v}wy
zJ-O+(>u(C4+~Gv5c9qAd1y2suOwy!+aphiWg@l15_R}r}{fmV!%itI30kJ(w6Bh<=
z>4zB>TW3{xpPZvU>gfK%t-|@%k{Nk%N&N9in|I${seA7K#@?u@4ZB=1rq&(4L~(dl
z_=D%lTi4G|D^2|>&@DrwmW!_Q8&dNd*XEtVA@Os@+o~n39~PMBH^k<{?03!~W?%fS
z;wv0|GT{C^#^Y&B$T?$;^TrxZ#(Kv}0+yQe(>+!i2{Yp(;(O1M3`U!#o#!_!=QmX5
zPnN}`=Gu*}$jwjGlsPMxJUe+NoU0ONJ+k%3c-|?vbEZ7znbN0_`LOKYFI{%dt-gA!
zNRF6y!cRd}G0$v;+8++4e5hDdaR`sEY&+9oyK`=Or^?+$>{!X2T)QT>7xep>70XuV
zo#S14-^Bd&St6_&Ma`*s67PE+G}K#agdTUuH!r7r=V6H-C|ewGsFxkzmyoU9*NUy%
ze?-o`CefR1-yd`9y7H+4i^1-X#cYzK9S2Ww&fM(=Jk{E@<4hQemBTwD#_Q6Gg;uen
zXG!*)zoz<vtdYQp1&NZAWmTeS#gC^{B~NyxOeQ+rd=oitp|~&`A6jaPd@zIWphvQ-
zOyV9k>jaPZg{wtgt37JTS-$kpBgJx`M<VO#s2opwlGB55dq?S)E|m!ix#X&s?QV|K
zE@I`Oq>v_;rb#z_mu1ydzX!K7TYGJH8%>={1v`-jpPu$7e+dbiT#eX#wcJZu=_M_D
zkfK`0NYR%YICVvu!Vq0k4MUneF}NH%ch*V+rp*jumur|4!+yvh<@~dJ2>*gIUTelO
zowm8`R!$N%&<~o(YQBGBIPr+<3$`98gcuu5zb+Dv7#w&Z_rpr-&*Z&G=}qo4Ga~Yr
zj<wQIQ)B9)Ep;AKqepbtkMss27-IdfbHZ472w%{NcEwNOaus=BkC^7~&Z=Jg{BwB=
zSF!!fYNVC9{e^7%3w{wqlz8p4_Pk0e>3C!h<$-REX#31<_t2hI$IAE4i)3s3qn;EJ
zO>TM5{-r9(O!{@^Ipo5-AO-D<FL5gaPR@!bH=nf;z3QL=HAic=NBQ!JX01H5vzAS@
zh^fzMD{!Do>HTeog?-b2NnscDuyOlA+x)O~?)0@c5o$k6Zs*#*YG`0=wA9ioT$Tb&
z!w2hoPx$;4YNbWxE<NyVIqc%;Z2i&L=I`wOm)6{#l23SM!*M`;r_0~e7KvsK*{lgw
zY3V<BCYU)Ld2Ey8bALR?7mks8zo%|kH_u4~_jQHz6^B%;pVdB^(W|I-E?8zJ^^DtR
z>-iV7Ez6`wR^($w>U5oldqeU}l~1Im+^agzhep?ko=Z%+uU`;Olse}p-Rvu!dHwBH
z(A(z!9T7pL4k5ga!b#1!&5xQNH0N(6G*3@BUsCm(MxC9$m-3-GH~;vY?8n7O<)QPx
zTiP1iqaSKVX7f+9T4fZsR2%Vb3XSPRA}T_QN<OM&+B=6j4vR=_ki>L47&a5dg)h|f
zyxc<GM0_17PtEW0CkD(Mn9oghJAOQseh%R?fAn!gaDCyZw&{L{<j1df`@1CD!y4$*
zUsKLB>Q78_6-w9t$-MB_?0BqVR&VAh7QI=nudT=(k4v_ux7>=vN1gizT(=iosiH~B
z#qU=GI(y_l-AYk0G6xM>H`dYM+Rwi0wcjN4y0vi^zc>+p5du|@t8%SciHB`*)}8ff
zX}CknAH$w4zZNzZ^Qqn9()~<CK{<Q*t;MQyZS14;EzE_M$Db%S8#cOcEsd^NNj<hw
z=L@@&dz>hbXb^Tg*RMVpwr6-pRXFmCuf#@SSy6Q1%|W%Dr}vM%)#Ur%k$HB0OXsYW
zDuZ|B)UArHv<R7wmdP7mZSj)g`4f+ZtG4hW`gbdgb6hw+ZRpe%O2yay=hdfq*94-F
zscX|TvnkxGnmoR@Mn7*uf_`$o_h*eNH!lb*DKu^_-FL&s$+j@Oe$Fije2z&uhBlAS
zHWy^v`ZM}Hblx~Ux9gEzaNT#=`}8LsGaDJ}23UdrN<}%165N8C=}i+sn}PMimT4zn
z_Sh~RJY8NX@^-S7?R4!6$+wevfZ@g_PEjO!@%)}&Exopm-Vb0)u*_vj^^)lA`&E<R
zB|#om$<aug9lbvI>a_xISTCowD9@MT>$hBu)zf}AQ0=uJ@c4#3nh0vVhp_9r_GSt_
z^`_ohTRyKL<Harfg4FWkahY}_j_0SAiUSXihS_Yc>HZ`id9okT@aJdyqb#S5j?55b
zWJf^K`S@LH5u)O^)tas-^7G#mo0z;w{?N<1x@}Pd(p}Pz=emLmqrJs$L=NO{fBXLG
z?OlOfRsqB1(7$rGZas?7DT}3ytO@EAdi*ZQA2fZC@qRr>djZx;@)xSaK4Gr0Y%~4v
zqi=Zq4fmrvDJGv;9T(>l11<zBi)Ua*{2#Clv$63xsfgeDwNidl>)wZJH`!}1?&j{y
zvux*htg^n>yeqJCLS9aWN8sqt$@TwQ)cA(~E<d(8?EQL*C*$hV>*l|neOv8J`|<wj
zS3OZBT=U%{zkP=v=nW%(Nn9cc8FJ(^j!Ar`w7WU=r$5~Z{hb^5xx<f%`EAARi|MQl
z#!NCiWn$WB<pb6CB<AOp4pt?7zGW>1)|59#OMd$iiC9zf@oCkb)Vs%~JvJ?_7KF*j
zN%no}TT`4<p@@HtzM>shte*X2InOM;$X3n55MB1gKX1r#j!CtI=;PtByDl@F9lBd@
zy?@0oLsutT(mOfkRP#sTr{{NuVot($&T!ayjaDG;te8Ud=RZq+cl`I9O+@bYLRL?b
zqHT6^tO$H6@*VM#vAC$lIcD!bk|$NLP}9b`y)pVa<vVPBNbJ22sZYR+?(}(Xr(q$Q
zd<r-5CzW|v^~I{{b@rDmQxWX7tuEgl<9g73g2~mtL|dgiiFIxWCEF=X<c)c{YHq4n
z#hTdTkfbm_{67#nvZz~i>X{LT<=%-nlZ9?X^p14r5T*3i*XrH#?4jA(-H}#`+7*qp
zm-dc+Xt*(&`m)Dy;^|-a(_cFSJY9d%PLT3nvOBJPlyQHbe<d-P`dXKE*$wx?#%Ll{
zE(n8I#$7L_ee>I_jObB>-zjd%(AOO4Eq~ro-C{e-f_649{KOp(Giv^e3;Mh{@q6jU
zNNw8mzd`-{cy$Cl+sOlWdt-Tl?Bw{Ha?#7^4_U6-HM{@+J>+j1iFsz<8N>xm{yW0!
z8{*c9{8f!co5u^B5#(NZ8#Sv@_kd^Z=?^{B?@eUHM9dZ}ch`T(2w&;G@g;*n$)Ma+
z%9^%qI`xSR!R%8(yQ5LM>SA&Q(BGc=DPBv&M|=H8&-~tNtKvAPzO6jEbp4cvMD@l!
zv(7&mYBgGJ+3VM4x3)YOH8oe)Kd`ZEEH5AL{=eX4&Fb({=lV=OfGT63s)=O(n^||a
zGBawPf8Ra!_E*#^%?L_|CfhbC$gowfoLn_hIK;^K9-J&zhYMUxk9lxzU#M%speWD1
zV4!UNoS}%x#j0$~|8dQhFJ$P8=4Nqyv*7zzl3Cr~KuKmKbQ)^%mCn^pT?^Ma=MdB}
zbSetv!|iiO)ExII6tB7TBiI>pHS|`~x38P23!@F^HwUfD=gKBjPtQfBo~ZwF)o?=3
ztzh!Vg7D{WtABnhYpvhxPh8E7xis+MbJd?)mZ#-*)(gl2tfk+(jtt^!2Bfxl-IKGB
z;Z5A@(CZK8qo?``Y7IS}1itfqU{<N%;x;~7()92URLW-=;&2B;Kok8O%wI?^f0}ya
zI{JBq!ywG>%wLwXPc$+guQhs^D=zt}Oi1PvK5t7(M`)wtY}gGHwQt8wrpjj0Oq^a1
zv?fn)Mg{k2#&$nv_ganSuii>KbS=^=vPpX-=)C$!|6KoIM)rdpvO~^?zPG3Po~>RD
zs;=KFf4O&#SBkjzW7SY+txl8tNp4Vl@S3ol<pxiy#|$=2t8G~7gH@!MlWLlln&Z`w
z(C)GR{zV&xV*7RwPsrqSWF_LkJLEpmX13=sM~kh=SMh^u(U&fIN9YccRmHX9wpK-&
z|CAtP^*a{qEe70h{EHte5|tuXxwf*Grvr7#CSS?n)nE8nEsYZe${RZ|-YB2&hu{D1
zY;Dx*Zm7#I$^KRcdvBR(I~T6~xM*DeXNBeDxbjZ7ovZvQg#GWT7$e7D-&)mNHmagt
zj{UBRI&Hskwrp`@_v%fp`f`JZG5<Myy#MX>4TJIpZy)%gabj(?$5-(Pe!in@M~5z7
zIdSTLsM^q3-<RO7_$J2eXodR%Ci&{pj>j@W@V3tr#OD|0$;N1>_m4{|&L}@BXnef(
z<%ZS#((gA79y1ac$)%m*+@()H8b@OWf4}z$bgvafD|zb-`ks2wjP0?=-Mn<QQqCa~
zm-YjG_xf8_QOmhoDicinW{2=cKjQk&oG7fZGH&PS=^MN5{`$4x#lnV2O~?G0i0$mr
z(&yG}H{Oa!@|*TvS{uB2P4iIm&Hgj{@N0+qM}bF|4HpJR`(@;Hq6c5j%zJlYz#sSi
zUz+kC?;3urKoy%9O_a<>6o(qV>l@q1^xfgYy~*lb!|IgSmz2)x)P)Y1oz#izWf%T@
zsY{NLrgZdy)0>0`IY!abl(=iW;qTKbr#2pci+XiuS6A@EwUc>>pw&kNL}V9NkQPcK
zsYdD}mEml(cz|X|@EGQ;DudciG@7soZ$2)*IW7{YC|@Nv&c|SwTNF1n8bEr_a`An0
z2XRzIk@8~J+|29Q|AqM_Cubcw9(QnXtFMeRS#WU6cM_*oJRjzZKGzpklub9RX?52s
zvRnIDxDwS?JLnKzS)${J@8umiA(=r7leXhdZ5Ef2$!R)$zIpxBK!r!JVYpHL{H6ZE
zhG&x=Du4AoHno1K%NGV~)Na&&*_t($j}F!d+3;^{7GKzPa-X`h5%VlC`bMGM^rXl0
z;1|;PvCfk2Wm&3t?`30ajrZ;|k})&AbAMu8eWbJJV$#k0=hmNg2=<Tkp3JlGY;dR6
zU-8f*)jJ2cmut~6uAAQ#4C|^}2l}qL_k<hkE~%_;)VsKVPw%8-CTprsQRLkiBAp*A
zev-2v+a=NDX_w=kRnNWbH@|LbZrpk}yRCI<vU=`@iD}s5+L9}sbcC*ZoWT;*iM`*u
z;p*(1D#mvB*o4X#sX6&eSKbON@k~lSpm4O8>n=}v`S!ISIhU9J@Et6<Db9ZDlfhd}
zTeBy_%C7@D7#H5o`QQ12Hw@07=+3`&qgM7v#ahlK!_(3Y%iEsZ;XBq{->$Q3$H$Qm
z>*Ul4h;B?uy#2#H_vMqzjj(66dh7w7dZkLe5vL#CkSe?b&4m@A6;7$eP?Sj$=lh;G
z6^{#3Z>i<^@;W`ZX>6IKD4Kjn%O-gd_vndc-*C#AbLxjrPzgUDM>WjmMBTY{L|sBo
zaz?RP$O)@h6JprKlQ(v7C!;!@QquakLf1GBp|a+H)FfM6-aGcjru_fVR=%(-uhq3S
z*rWB>Of%a^i<<V(gJPOhDf%QZ$O`YPnmhbv?F};`_!n)pd<jRFo9^D8VK_(|6}h(|
ze!Dt-;U!1Mjg0omDPQ@y^s=o*aNgtl9pmqJJig^#f{n}x=c6eK>4!yMd}+6fnz~XN
z>G{ew)G*bnz%0Jj$zyY@TC7c<qx@yNPyAA;^^sQN4|rdd*Mcs0K9P$D<3hCVe15a`
z_s%ba{jC2M<G(N@*nL`xe3kwm=H3D-s<z!5e=Gzkk#42CK^mn&l<o%U?x7U~q=t}A
z>F#cE=o*l2VWi8U2SopS(5KFMpZA>et#6(0zt-$~hCS@P2fg=wUDq$Jnc1!9UPbc+
zMsYN^H;eAsxm3_a_l)k!^2Nv3$+b7}uD!ic3x4H}%}t?T0nJM5EpBNdJsQU8WE1o>
znR5aE0S9BjcL}O+rEf3u8XmTV8K>62s<8y!&^>upo|>xa+v4QwuZxpTT@y6=a&2Q|
zz=mUl)21!KeYR9=uUgxG&di18oK5J2C9R^Ryxys!N1)9n6;r5X2Xd0_P=hHHY&@dh
zIGm44{(61O#$oaz*YEKUgBg>?fnKkk@njhMrL!=3DzPGTqWg+xoI^=~NaNmbZq5(>
z#8(z<-WU^+TTA3@&JeuLAj&TqLzy4{?bOv!@EsOY&VKhGFZvB(+U^I4kBw>ZIjV4Y
zoU`yDjMJYSMLI`f=U@mK_N5y!UmGt(dg5wUNVeTth-xZP1kC3;<>{b-_fsgPd5IbP
z54H-&pAIOzb3z%_4;ql76UzV-zUUKRBWVvAxTEh@sJB`6pqd3e(KLmWiEx6tELZPK
zwyMwC*T-sX6EPXADx!qX>F9dbZ0*xZNJN1{PFz`82{nfa9>}qgi3Se@ZHskju_31{
zRy_K4|56XMsGZ&@Nu|j$Cf9(8(E6*`zQnfXdSbXn9J)QR#YhH}G=J=CHVsdhjN-|=
z!d<k{p<8d^&qG9u8+M=HJmZ7Es-a8*w_tK&KqdqOGG@xvn_LJhdc9Gwu(Xr7MU9G;
z`cB_K#u*Z`zS#=m4d;HG)uZDhW&HvfuS)(}KU(j|f;$|tW=q9lu-t?ag<|ds;^Bau
zjeQWlh=L3CjQO{CU?S|kQbv6@mH)gUZ7%BPZ*P0_UcaS#<s6NBV7W9-Mc|X(n1Dv2
znrl41B^Raf>HHW|Th*bxYt*d6Se9T`+-;oPIa}#yYh4u}O}ITZY2G_ek9n+Z4Z)Hr
zAI{et<r6Y^T4iTPcxOh49>U>1f|vtG=h~PlsVsjPtqW~)OjYfO$&J)RXO1#>P>4wF
z7-)0YWSeIT;i_Q+7K*@j*_U7OuuirhCf+!;q9up|;f}f^Piri1DK>GL_X2HHLV3zw
z#LkSYz)yZ2nof+x-$&^7adhOHe(Z;_5+6|;pepN#$+s82?EgJ6H03&Ae7|hI(BhZs
zbZ}wUzOvmwd{+Kr?p0Z%$JO*~Wlf7H*t?fw7~7lDh)BA?bIFnD>_e$ka<3bwpc)oP
zFR=rD*~oU<H1gIcb0>m$*Cm}Z(6^l1yb|ixg8}SL>J*(O=APLQ%)#YQm<67=JM@6}
zf{i086}fv3;?8-(m)W3n=<SC#J)*-z)Z_z>Ppg2k6a&UyeDpy@^t)b=_aX;X<20rz
z%2~7V&}W0k5yT5S!JL7>Zga;9(jJU`H^}DoiyDK+-=u?#iGn$Eq{3vIqfn~cTxz^j
zfAsB(qz0tApOJ4vXt+lGE#HBv^0Sh^y=w_)q&f{*1fULUC4tqz38pZryn37zsbZsV
zSn=g?dIEl6%FmXM*1tM&7C4*rOzD^N8om8kSTL~4`_-lHZkk(x**P)ua#N&Ol>z!_
z*sUMmFd*j{c_z5|{Q_KbkLl{GgAWQYAR9Lzw`oMNcOmV(3tUbxQo-hZ14h1=3R|ZG
zAtI18m=gMtNwSY%7oBRBD;KR^fEAzn;2lquk&<?iU!+H}tJ2YVl{WmaN~)Ej03!<H
z07o}eS^wQG$tS)vV3}{1;LJbKnHSu1ppPk(av122DK6W8s;}ZCTS-E1->D?*!9qcn
z>~?-{)qIpN6yuYi&=)1P%<wS6;wK0#vmayBe8wqB?p9}?+aY7gk}N>`r6}@<<AUto
zqe(-#P04H=+&yOo*zp40@zEuo2I!)4#^81t)cQLkwBomKu6-N}sy%5Y6$F0n1=OSK
zolcf90~hxM=#=WFQ&$Uk<va3Y*_pJte#M*dBv*Ozi=2;ozDqOZLuF5a-6ma_R6o~R
zUQ=$}+||CUzoXE^r;9N5LNW~IJFkM<(1(-hUOE~jR``3K_5icaVHcQnk-)5Ls{&@-
zV|QTI^#HSOX$F{eq(axT4tN4)UG!sjzq0`l%p%bWrLfKWcc8Y(p#S{7og@z?&r&)+
z0hBOcV8#+2@cgETZqEb6%?y^cO*J1qhl&WqHUo#?E?P#>ZSR1yY()(>*w)a+ctS>M
zp6<)_%<PFC7WX&WrCz6x4bVsQ{b37UpA*VYrz;a569QYXvJ;_kF_C)i1a&-oh^frX
z@it=*<F|zmF<6o3BA>Ew@PZ$fmpz>*4+O2=TfHFes^gg{%8$I=4UO0X8Q|4z{+ZY}
zqwM`tVt+H_&Hp^H*Mt4f68jete@pBOPffVyNxjKtc&UagUOLaYiAu_He1(KxJrb{q
za3SnCeLE^+$)tUB6o*QS`%dFXM999#N8iA5YH-bq!Bk|q#yLGXtv=;ITeQixY_Lvz
z^JVEe0>k1{g1++>4hJDINp&^+?b0IwL1&Ie(+yVqjC*`f0%K$|`>PGOV}{IkVxi?v
z;Z?kPnvRZ=Q|r6r5fikTi&v&649vJs7dWJ(C1N<IFS(P6Bi@$jagT|4IjY&Nr=STz
zn_S$udu4`~T*^HVS_jd<pvf&f)XPN;J+zA6P{cm9XiDE8#XhV$@qq#5Oh$PQTu6VI
zeqy5#G`y2qGo~<{>C`F7lUO11<8x^LmpI2h`Ik_Gv$ITX_$U$k;iK)-Ryq*H*VXpt
zZ>nb_)^4SG(``cZSx9vilw`3>dYrc(8AbulT<pT>V{s<N+H#D&s1K5D`2`ES-E)01
z#l5@|{_zB{7OZ<%$C1`%%W(b>g9}tC#_!L}s26f}$w(e$nW7C+_SIZ*hMJmo)m$al
z8-!aR7LxBz!u2+CL=~BhTNE}_72leBXO!=_sF815M5<-NZ`LVDQ(Z0es0L*1-MK6C
z((XmPoiO;QNRw1iA8IC`d301-T%UNa1FY$b(K^^`J|Dj0V_V<W2<<hP51;oTDckEt
zd{>)3T@}vUo-<fjS8b>#v?1M<&U8DV=k%7j2!az~k3Vxx^gzjMfb+L!YRvY)_$jlM
z=RmCt4wBq;@Ce#Z)3%ykrAgC~)3TA1l%I;Ru~$5QCG<cQp{?nZ8P(PtHt(|yylJlw
zTyAE&U{ha|_lNI<4@vHi_jiHHf*fim8o(@g*h%X-(Y-ijKpu6;m@@8qg|{>5U%7QL
z-^~hrC@2T>WMyWSKnLZrK{z77giC}`DvkNFZ2J@Nie?`=L&wH|-)7i(O-e6T8{H41
z7OtbLUfBZ11yxL^s@8^;v2G@jPUhq{)r@5}-T39=#yOE&cX#06P%ESSdqK8}{0bsm
z;)q#Sh7`G=nkIl8*XauZShE$oEIZ?g#Uo>ZRMhZkkMgmtc*5kG{ehxqwyV#CJ9-5h
zSG+u;;&aU=EQ&I{GP;k<Md|}$UQ@?V>m1w|eixqf!ABGCTV>C$2)#jM{yjU=FI`B@
zq8+(}s(w_dLL2`=M!ZLgtE&xB#|U0IdS$%Z9%F*)1#9?S*Hrzf1!B-$`CRvd6(tEQ
z_0v?C1_q4qoW+P=nlEQuxUGALN@AoUIk`Kyl+7To`qW*k0VY2O_L37iv^!Ahcvng#
zduPHdH-W&nWhhFZ%v<}85bQymzXbq=)J6{4&D51#npARkXpXkCMR)C(0wGr%>g1Z9
zyMv+6yRA)1+u`<9ZdkX?fUrWZDg*Ai4iZi#1MuOVac(y!>mD8qHLT$Hn@<)~g4Pvq
zx%evwr#rrJ?OD%+GV>tr^wc#!e&tF<?k0FY%8F~`w`L2~roNx(tw667<V>mQeKUD{
zxEdW_YQ#pbDm;Mf9eTB+alTcSbJo;J_?q~LRKfYcibJ7ZA<m?3t`A#^f&zGOc7b1$
z*9S;Mt;bpZmZZ+PJFpOb>`tNs64<tIOW20mGLWhi>D9`ru*aiMc9J%1UI18dHvU?`
zTmwT!qm(5}u$6Ui+y>m}N5<Gn7U(I~K3H*NiuM&K@QGW$7M0<X=PKYA-MuHLp-E8i
zt(=e4A;bWn&OLFu{b~vtXB?)axEhxx8_t?aNTI!&5K4+&@3z>cV%wMWX>U>sC0L+$
z#pM-%yhCuPk`U)2;*w*jDANx%QF)xxGOOzj71wWA_*OQ5C%qfdZgT=il1^3nDig(n
z;i#h6L>;)%=faiPZNoYocu?~2yE17#GZQcymGp86thK{{KDY+aPN-j=jO|Ar&b?3j
zoxUMC+@V@DiOCc~L|ckdQ5*f4L#vj;iTO8ruagn%aa$$&_4l8`wRa|4wYP>_rCM_z
z|4KlTJ1EbY`V4G|^YKK{iB3%hH(ADT^=I|ISzbt57H3<%XEBDWDfs$97ig1xND`ID
z0ez!@*oU^D<S<8v6=|OhopegeL%~tt#sk`|p|<&M;$e0FCAW2WYC>6z1Qk!SwjI9h
zOH78-$L6?RNIE+ejMz@BaU%jC_(~rASF!44Gb|`BTcr0+D>~1~%V@nkmfL`{OT50a
z;gD|bqHBNSZA!>^kYn;~kj3j=OM;kbrtSrK0(o@Q;FX*}X4HnnxU=>!EfF#Q0|Bml
z@I$mDskD@3EUl$M&B&(|aT8NgxkASs?8-md-zeBgzRQ-^l3{+sdhns%)yS7T{XST=
z_a<sxC0GjR5E+_+ZB|6aEtrr*&#Ez<_eI7*eUrfwM}_9FOMZ_GeVFgVBVme=<f!Fd
z7>^=GyEK_xjsXnl8_5fl5xV47Irj5KbM7f3I|<8qL&`m0<9w9+V}XPg`AF)?C5NJ9
zd+2URgkT*A;Kd##KyWS&i$3?K3k6(Jd!MBYA7Gz3EL!tHUd2Wk8R6I+jA|)qlbiAT
zw_o{`4g>4CS4it1y^R&jSTupyGeMEXujRuKue>Py-PGNYTX8;24eLxG$AyFv#6+u}
z4KR=uB4|`j5WZYZNi(0w<wa);&Ex<SF#Xd}71uEf<<kv*_I>mg6cpT>xK<pT#A+~D
z(q5zp)-DOoIyaZVo**R^jV|=e#Q&`l3(TjmT!iWvCq;hhn=q|-e^)L5<$-mX3==gk
zPe|5@2ehDPrFs^01!e2r35smGJI-bI1&K>MMIp(xW@miXwos|yZMb`thb$OOhOs~6
z`7Ed)0CUuc=95Kr>9hh(&200R8XF}aTg++vYskv`F11^~g~tyqk%0lp`;Qf3#*|(T
zoqSg?N1--ho>n-Hq9DUhZ8HBj;<B%|I0RR&IZNBo7o8IN0t}NF*hf`EeKkHLUl8Mg
zSK9U)h@L<nTajf@LezWcndP?^nn!3S0!#)+7wfh>sz(-j95};kJ7cPTCR_rvWGVQw
zHPcsD78+!(li@yZn?)+nGVZoEI^bs6@|hw&tY@HIIBvWfAi$l-`&3+&=0!M_gY^`8
zYn!(%TK--cv&1DehjPUhqsQ|qzQdSpr{Pf{)}Sxi&suKz=IG3N2(K0-ii#_5`|Hl4
zo-qi8NXu?&eLTE-XzQ<VfkO(n_0KPxUey-$pp$eHo<<Zx$HOi~#t{>N6|)%yI~Qc?
zAs5=zlNPN{Sl`9SiZ#IFj4ZvcF;UfP6mEO6M|Ijodt~yPa7poA-p2}<I_0f{LnOQ>
zh(!7T&<zOxe3{Y!u-7g&S=Yu7EoiPMY(Pu^xxpMt%b3ODrQFa`j9->v8ss>3VJ*FL
z14uCr3a%l<5X(3|3ibigF$Fte)6iqy`FINEbvGEVis?y6?KVULWT5Gk9yQz?2BaNR
z>I)mD73ILSynr`#HG#|3Uod(lDh~To@@ArJiEVa%SJUiuNsam(2KI53qi}O-sMG9)
z`Gu|X=!<oGolx2~e|L8p<bM0&6Ubn2U|=)=Ytk1DN!G@VGVvL+%r;$}kn4L?;E{6W
zyLzuJzcn6l+O!^Wq9sKKGjBNz!Q`8dSajMRk9}Bhrv3VS{MJabsbpxXC2%h$ggsB9
z+vu}gPMR4YY0u=s$h?d3bLADNHH;hR0{47@ogC(N@etr8D1<B3YojUFOSMKM{#rRZ
zMajC`i8}5j^cWw@C`f~4O9SxTR|yYngXZ457fOV}9=W+c<(E$fEcf@j&p6tDR1)qj
zvfPW;reW~0?@F-!`LNZbj=Fv+$Y=5l`CwDY0o&%9MYDxAPdrMNu_%^esT&ZJ;*{2C
z8lGKTMO4)>N!f7jOTfAdi<G?9r5=>9iFzWc&^DK?XWnv1Tf|I!;%X=@B2Txov6~qq
zZW;+DPp{hnUM9D70xz#N<|}iUyGTgg^|vP_EoC%Q{AVh43k~AmxX<Aa8d;2(oD^GB
z!YH0#sIvM@aVUhZ_~GpkD_Vei-}S>?ZOw&6R0$iH6(CR6jI<bkJLYHRu}F#Te68R9
zeXU93186+IkLQ-Pcj8hoghQ&ZjFp!DlgZ$Eo~KD_iCw`&ZgG9u+&n$_#>nq^k>Fsh
zwNJrB_OX}MyIh0qtQc9Dbax!nlnCxuI^jinFArf`pp`diu<RA@LOrDeP9{Reyu0>(
z!gQ3BXWq|Zmb09nmi6^GKic>M(rUo?7m$|3-ytnQ>CQhPEsOsMX%$mj?@w?2gtWrl
zi&RM{$g1zHFpr(5NQWJW&)eYJbe5d6{mvwiFLy(HShx>aGQGMztfG@VD99e`I=yTK
zFzmG_!}Kx5(1Y=ZaBE?H`});MPy%*ujFaSecTDp261q)LK^HGZSMRLY)>_MB_$~eK
z<rDU<ngvv<3*Id9UNbVN9Vng1(A#c9+<s;KRioq^sufzB|EWe&U7p!@hb0M$TC4YP
zx&ikhe?E|w6ZcN|ik_~%Y#uHcGbtBZ&fEq@;Km1~*&h|@4xJ!tBGIUz{cqn@^;ujA
zHQ)4v2JLtIrdsA}0nO7Oz#?}M{$DL}%dg-3vB*^%Ye>qn`@YG>dz4>|v#;!q6&XER
z^=1wG%k1|g$!5;g+3yOv72P#H`wDNjLFGrvnFaBcM)^lYKQwDZ6sJ!Fim^^=q>G`T
z*E)36F@E+i#?H~xfI#YMzJdWhieAJ-Nn}C!Ms->V!c#+i{#lS=Z;2=h@ZVCiholzf
z4Uj9(UbmfS<kab^k3W*c$WU}cavMdu^Wk-v?m5urvv)~t)K}saJ0V-NO@l&#(0LHq
zvSNuX%n2Z~80>@%;vQ!w&w+X#Y}wQ^i)ak(^n8)gD=XoV_LnUY6@IhfhChv%DgDJ~
z0ROn#Ou*SS{bgI+@HZ|^OER-P5EI|dl#i^UzXww6D!RD|Hy}{UH~a1;eo-d$(Dil`
z-Y>9xF@B<2s`;Zcf5(BaK{#-eCUT>$v=oEYQa#%kf01FIm|rW3k1hXoG8104$O=ar
z&b>8@@hnR^{E>BlX0?1onE@Vt(-2f2<h0lKJ2KkyKx8a_xH~FeQELKv(+sU&xLtE>
znUPMPRf%~5rA~r;+ava203NF;eSq5Z9sJ#hXG-7Qso2N(3@jn#`iq3dxioW{LO3bF
zG8qwFK;QhLIKy|FR4l*?^ENH-DV08?a3jW&h8@Dgjd#RPk-ORJjg1ojp?B3R1?})2
z?z1oGFlP;9`n(}Lia1c>P_bJ*<h#{<-mW)YK>b;&D@Qss`$fkd*LKaUqKE^`vxcIi
zv+qMpA5Pg>+|-;J!BKK}@ZGeN4{YbeZvG?s3>)DzryE0Yknd>#Ae6~%8k{U<!9>_l
z<1J!ndb}~@*G^3C;y<!GFnf@6>0&On>?d<}y_XumxRcZt{8l_}1~XnF%w2!t)YkJl
z?;9VYf`<fc!EMCHQdEHxCQFZ6NJDX>Z?-!a9{jU9f)Cq3xGt_^*jeGpmX+%|TmP4u
zS{cT24y6{d0sgj+_b=4f0c=f&-#`Q77q%vG%;)CBgd5)9>j0e|Y+@f*vh<A(j-&hV
z**uT^69L>LgHxERRmPSUMd+1&@;vSZlh&N!t4kF;G$K*;X8G?LJHo7CyQfW#^Oqf5
z`qr#0Mw3Dr#@{6S8;Nu^dAi%bgv$epqo3<34_(h0F8TIXPh_si_*(bHqO<d*?jKO)
zlr^)SobflT%v%7&nf|XJ&Y3;j?)$7N@H*vE3*mGD3PrkJ0CtBTV?>P{68<dr>_^`G
zQSJ$M&>OeHdHZ>86=&wYS`|q*ju^dE=(wCQJs4i+Swh{~_QeX9L30PN!ZK%jf=h<-
zJCUDrW~?K8-}5V|)=UK#PP)-pwVXC&cssF)5*m>b)E2AC-RHILl#1mi!7GEl;9(fx
zwuFF<iPmj%4AV!ZR5|K8Z_`eyqU#IID?{%~MG6{Pmx4BG+cc^|+QK~ce^374BO*U>
zpd!uIqjR~PTN^jrSBt$J7i_!L&)70k5^wQlN*0TDC<b;poPBPb4O`yV7A4bM#CcAr
z>3fZI73zLFRcmK^dbGVpRgPF4v-mq-{Y3$a+0-{09Um!kjMYCD6WB>E<WTfgt?~v*
zgye-n!bwW#OFmtIp2iG|DqCs3UbZX_jB?o!yZe+SGTO<gtHF$1Bw-OvOPT#cMv}H`
zDWTuT0&`5brxj*AN774D1w^e+GhEt!Cj7n4DJ#Dc{y<@WuS&7OJ>g|gbX3^}DfAGh
zYmq2&dCOWfOH`)Y#$Y)u(%kxc1Ug-IlaEMtyn+H<!5e)mYVXtLjvqr|x0paN*vbtX
zyq!m{2+!=O;)cyxC}$S9pHl8qJ(w{GFgVoZO;EK>@S1qE>G`BBpHM|E%gxNv|2Ew=
zugF?C<CL_hiby%}#bsi&u#FYa(@>51GJYuxbt^AQDbDMS8sA5efsrhn2Z9Ne-(CyP
zQ@+b!l@^}QwA!fyB|y{Bl*yrPqT5Hc4}7{^MNh6Q>o>NVMP(+l{HA12h}o3}U($Sn
z+6mJV%^6%{foe$XDbuSCK5?R#;KC~gEw=V9`nm&}?ETPk4Qc^Q@_hKE&u(2?BM{c+
z4AKseYy8MjQ8{wyceC-Xs_(Qv);{xlP~(wnNCe&HXruA)wD{@?u+^7V*TC5$lDx>?
z@Iz@HRZ^%HmG7{7UT>J^A}De~>*`V2#n<~8)9QK~rZwfr+}REP3^7wu0$j`B>e1em
zdfGu$nP1q_n(EQA%y7Ze3vA%OW^xj~uuk2WO--p6E2F<)w>JrI%*+;eKCM_~aCJAe
zyhDHC5F`5?PsVh0HCOGcrOeQt91aEUoI99HE?lV}hzZq9?uI8?Q&{S`u*9%O3~CDq
z;!`Rz_EL*c9L>Kr!qdt7jq~g*<8|N(=%AB_Lp4aeo}Mh<;N~BM85tYin7AmwPNF%W
z+o9)(CSwoIN@}&XyF|XIpz=#|+aTOs%YU#2pCx2Smkpq<!Sb(2eQHR<CA+g5y;zq=
zA`*KZPXXXlUA50z?w*l@M`%o9^vu0>jdI2CMKUUUbci;TQd&7`2eTr^kCI2BTdG<s
zRx6iMoImL-u^ruRx(M3LIli%O_;?xwK29W^=Vcf?>6wL2BwCi`Qr!hsRJ<;Si2$60
z<H*L|_SwFYzAiVgjwzt|*ccJ@94OIxDeLV~>#$>2E0|_^;7oa8IA}EAbHHKWz=u#n
zyt_0^<j*7!Oj;z=IYfxCgCDN9Z^N@Ou6n|fq=;Pzapl7s@RV}Iw-5=Zx+Qpz@9DfX
z1Q|2GG4yz}OW<C(EEj;PQX9dsid%NMde6Owmcd^rCf|~jy~=pHd_TN%q}3mNZ|A05
zt0?d>sa+rE?$GF4Y!)j+DO_DQ(B!veMVf<I$IEroXQ(c)=BJ)fgC1;II`f%tO=Q5)
zEPjhuW+F`f1`;&jf3(qPc}~GZ=*pVooE3HWtQ*}~fvxXjP;!3IK#-RMa{{^mVfrd_
zNC%L}o?tT(BJ_BYlgJWlnw-k5&&ikwk1-5&*veB_X=3&GeK6wD>m~>P$Xu<xZT=(9
z6{)PBR>h6k_sw}M%(-g9`bH1o?--+l7f~?uR`A$`I7hva;UkQ3lTFtDkl8~NOTPyU
zbXKbThJyR9+$WcNgDLP<i_g`d3nh*8?X#yQLmWGSc(fg`kF?3=!Iuv?%^fLe0O~HV
zE2+~rnuxm*`#}x_`C{neA)J&Wf8y~?n8k#J@*?ym1n-dtDWgCPfi55WFfL=+<}I1P
z7EI3%+CQ}6+|CoGJqMPeL#K3K#}p5ieF)Bzawxc^XRrl<xCRI)Z?)t-CNk(zR!xT}
zs}f5GL2m>be|y2aefzZu$78GiGfk_(@g%=|pb&La<G6jm_F=M5=gPg!+$DBiz>1ea
zSV(9N1oWY15E|&0yfWyo^2(2LduZsvt4*fx&u_=6vncO)aqLD*H2JVG85G{^NqYb9
zu(_5l^os{z9Q8Ng-^ioP?keqUD-Ixhgeg-J1}_rGh~M50=>bbl1WgE;z?*du{3IJm
z-SO7SFB|IL_l9$=lSP-p<Qa9|kP)nm)S+HB13jx>2~Hl+KE*4N;>(d`oznt1Ysr$7
zigX5*aJD*QnM)ITLA<?#)dxZ@f|D>)lK3zvK`@+h!X>Tzooi;H2MuGh21=HcwO35K
zO|&y5!{61=Lfb#Gs}%phsu*3+<J*0hK+YRrqaS@sZRSUpkSpDWlwpqdU#LNLPv?br
z2-GxWh(|IV#3*gJ0mNbH(ZONA&KxKy%1k<A4Huw^Ib0%R6~E=4ygvGkHj~kY6dOG6
z%nJl$8`i%>WjaD!-DZh?deS-;Gzzi?RWDJE;EXkD#~4_*ukrK;BXJ`tOgg&2VkpHw
ztI<4eSB4y-F!RKhB0S~a#D>b1ATr1sfRHXBCb5-k);7Q_{_hlNy9!c~drf^xB3>@1
z|IY*b`E8Pa3h=^=&yfKhOXv3hPu}VEPXXSmb>1XE&{c;w;T?O`e-Yrl3iAF8@L-XT
zC!b^(<lFq2NmnS$Hbzm=$e(F_f0D5mCC6?~ov{b4J<$;!+!%RN2;LB+Jn_^aUN9BR
z^t#D6f8?s4nX|1VW|MmnL0D+U^<Zm*FXI7*9Xmfim5oa=veZ&+n*(iou?;q*WLl`#
zwW*!EwQie!)<@QG$iTbT4OCW0qH5d{i0o%bq-q0!<gfTLo9o)N=8Ya-lzNMW&I)~E
zCrkB9GKg(y<vwqX?1f*|Ue}5DBR}=Pq&%rpiXtsoV%p7HKACp6+P6wumwu1d@CBhl
zcbI;XR@a~vkV{Oe1Eg5R_h|PWrjfH=4Kb;M!y?2%&ieSntGj?!aC;kMe}tnq7K6>!
zpTo9af4U7?P#jCk-zm_l_#XItdYR4M6J<<}1ZtzLO{`O?2Eg<JGSZhlT^duBE;p~4
zo>E~K&Z9?}lHm@DG%#fWLG_9(Mg<9D)LVsjP!>wx+*+VAn7|E|2|jyU))luGvU)nO
zNmy0)DH{Vus)IqnW-0>k)^HG)08sfw6j*G3A`i79`pK=6{gqoU$LCm*oHt6jv7M#J
zo9muM3wzwh?kxWzw>x2Y@XreI_#s*xZSIRAiH?bpRNV+hPJdBYT8_-oomn`k4m&CX
zj7G}uE^&VHSc=A3@0ylyA~q9i>1tj|$Zys&Rg&!-Y!*eK?!tLwQQtsA4tE2TH;<XJ
z5!xM{P7xd~LsZY@!j%!a3-_|>8;BIO!i6RdXrA6?)aiL~yQn)+y^@>lDPlh2Vcoei
zsr%k`dy=#dm-wYM{U<zt@5AvD%-?z0mLr2RK}GO}pk%9iuy#j-zW!~-UZq`|TF0~8
zoENt+xu5qCKQW8@PtvDBK>7rIRRnqp?!Tkm$T424)TDG^*Zo(p=&|#E28%=>i3#B)
z=IEg`gjkdkYvPfy_J2@Ib!~NUm*N97qI@+r9h#!Vfgr)8<jW^Wn?bfZBjNu1rtZLH
zJ-@WC#S_hHKo6Mg24C8_mTP2uyr+on8y}i=qCG6Oh8V=!Z`w&1@7x>wLr1dB$_MC3
zMn&w25sC-&?C0>-<g;_?TQQ$UXK;9%RbMSx)XnUBQgZm{NNl_eCC|+GRrR@mv%tL=
zg{($5uB_hAv@}X=+1j?V0Fe`Bcs})kBVyS~N<=`Zl<yfJv6`Z;emMT&r~4ym^=t5d
z!~8)O`f5e?HU<pShl0b8{vq7ch;n<d$%r9ChyWYRzc*QYW|>ELgS@(BGppw@`oD{O
zMIB4ojFVBsAsBG_X400L2ON@zZ053Cehh|p1k6z(aUVG)h{&1ll5uw}I}Y6sUP*cs
z5k^S6!m#)P2-B+5c)!AQq3Q=exsy{6vicsMc}NgFpv&I^6w33^p;Zyb+z_2n)EEk;
zAJOJZ?<f5h$S4DhYZGe6&O`OG?{A#nC!_qh{MC{I$m@DA)>vI%l(E8fE&a1K6QCyz
zqj{HEKKLwlswvBdRCk(lS7ELnMzcSv(+S=j#?>!P)*;vfp`uHpfF;2Zm{#cWc_MIm
z=&iOZS%e=Ncp_E<wTZ<lMDYEK6K}cu`nI9Nn*g4RoZ(}|>+BII((_G?T_a?3ghI-Y
z+AI9IG0s_AWNGXFUWOotxt63(&KFw^dou+;ZlZD3)oyjuBmx!8){|sRqOULlxLx=2
zHZAy@iA+&s2u+7R1Md=(=|^w|=7e(!-hjj*pN<CaND->;WZW2T;Dq31H5mNLxP(Ur
zSPR(OgQ;7aUQxGlM%=qb0LV|@4+9nyirQI!Q&{JB(yPd(AJX=!#z|~dq3kO$l2V(f
zEMq@52i8|*#_7dX6V~%WJ$s{<?l&Ow{tKL}>6jOPcbyPbvdc+_4BWVkJ$~$WMmsBP
zs=nt5F1bw}^gyWm)i20*NB~7<%8b974FbBAc{gGiP1c8ECgh5dlWHdOfho$Rs>zU%
zzdRrZQVit`1a_NOiqQgcpn|T=>lfVq^1}6@D~$^gSW$;u1;c@7^sH-6t>hBa0de1#
zla&0OYGhaUq@G<dgJ}$KNgl=W>qB&H4f~mY?3%+jhUH_;EAe`sDTix?#n$1uKl`~F
z73J|!%d#$B>;2Xo=wos1VEBM!c+wX~Iyc+54%aFSm@TM_p(hL~u9Jlu?}*x*Q01)+
z$FbIQrWrA@vF_Z(-AV=pO?4e*Nraq{-Rt)poT>6fsD1r1Lf-j3rp<eJ{Ve3N!JaqO
z_({La=YimQ4@;K9QZQE<09A=jng7C)-__N^f2z{y2|DzR)=6kHe?k}XqVZRc82(4B
z9;BM^EJ*)WAlmCto}?s<V%9}-Z_}t-Ez)lg5ehF_MnX{gr;gfYD5>xU`8}{KqELO`
z<j3-gDTXR>aa!>%*T516C~<Y0=;L1KOqH}!#Z_e-Xg7^0ywDv!W69L3pIXy-<jSRS
z<P*$oH8@>=oE9C9F$wXoK8PkG7a&@wI!d^wc!%_Tr))0trFKQKta%N<<4wOmpCKt{
zz7G7SSkl|E(EaaKUUBiE5ABnva<cl8cCM0#Fr>RQ%9A%KMfjQcT!!DIZ!9!5C&O~g
z4+N%Ld`dm~fT4t#V%;=3#sb09cT{lqvSwlADDp01#;Y9;(3$KlW9RAR>$ux4YOU)h
z!?Tw8>(E9cs+7U$9Ea7em(KDtWsKDp6_=OL(#Fd;Ld1PHZv$LmY>?A3o%pP6&*AG~
z5!~aI5%gwOI;_54GeG4-!mIUPseGQ1{-N^e_@s;TsO=ahjBc&9JO0++$-R8D!8MV8
z0fv0-bQNuTXY;=dh6Jtt{}v44&IO@iPz?3F3q7tvx`%A_FCIO<$CE9P&_~#_1~kbC
zi`p^3HT4s^A0ZyHy7R=g7g%1-(I><0pB$-w<dEt!d;T-cc{X;0tC_ut3R*eZXSib=
z^=0+NVp;K^#o?V0X4F?#v1)k-1#EI~a)MD2(lMPdGZUbk^g5<DAxSC{e>9JarFt;0
z<i|%IX0Ebgi-rC9FStrC*O-si2;IlklXM#%#W$XER6kw<3QO)C6J~o9-<ZD7jAYT{
zAD5U-EPXYO6g~aIt?^Si5`4HpQD%Sem2S_ClU&khy|S58!zrI<R&Lrn0Qv|iUVJ&K
z|E5|ojiQiH9I-0X@OO;Y+zF%Dm&=GK*vh=LBG9@-9;b$1!b^?l#5cPZBXQBJOo?=&
z{5vaJc4u^3x+TY8y#_ML@-)=$9C=&s`;mdY7MpA>$T&&osV2pCmV{=4myBtyjnRFb
z{QN{Go}>Xso+Rhp2)}hpj<p$Lv*9tLfzOs4BjD7su>~^Bd@>5NJyb9X>?W{bfKgO&
z`AHP+02?tGW)Cs0x+h}QlEX!9Z7n>fb4WQpksXYZljB)Z%?Io@bL1iF)w~TH_zLX;
zIOil}%xGu@*nj-#u1sJN1#mWQx@~nam?Z~qU`{9hPzW&O6xS1iQMhH)?byjM&B1_Y
zg`XtiMfyBoM)`HsAb&65NM79IPT-@$A2La}{XxqBCs2E)jwEA%OOdIllS2XJ8<K9u
z2Chf4U$6=MCF7sRjQ&OiQ`Gfy0LhNRlhvaSqGh8u^J>H$yNW2S7DISE!!`kgY?k=y
z{NEvD^vgHG53Pqjctt)kB|#T?nM?50x#oeOb2vz#;&*dLGv$D0r^*3QS^gkrM5ZMt
zC^zgRqJX;>*8c@0$j6<LQS_|$X}<A$XO2?5-|n%}{z<c@(pJykD4OfD?<VpmS?F51
zVIlTblNK5m(NWl7@g!e4i!+akG7@8a$Z}8jF1oWZAEla3Qx`ff&W#0Z6J+OtzxwYE
zz_%qvlZ>s=tO<3v`~sH}^S?;y*v_`PhCcU^JCbb4KaDc`0(?)1ux;0oc?RQ8iQ62*
z)+^Dy*s#|UTUM!ahGD&?$eSjj*!=gK<{ftIpEr$q`Clk1(_~9g77JWs_{9kCoUo;W
zEu%x0tHOuQ*>eA9V|sIIN<CJFbm9k4*LyZ1tYi@8;3*5<A8{LYP1Yiu54Ygnt`Th|
zr6#O|oKg4Gh=+8SZq|vP<0m$h_&*C^c>2<TUVikj1nK*;R6oL({*kp;gL@Tn+WBJQ
z5s>fEkMhQrt9a$U_sW(*(<#qS^w@l~jFjc{{C1}0IJgz=!M4-voi`KBnKxhJ{v3cN
z8S7i%vrlARE#FBV2bHz<>{Zp+xel{e!EQo-WiuN@dnyHvtq_EYDZ=RVVL~%2<<RfU
z@Lu5T@60g5$UeFe56KL-XCU28e=@_Oc_IKa>?7};fPLxZE;)|y%J|6)ud52iR}4B<
zcp-3YL@8%ybrNlYM*FpfkBCQdSr@gHOugBtz(pH3+N@hY0@T9_D2SG*oEdD&qe)yb
z>Lhv+rb*O=srvGZl<m$he&M3Wu$I)OPfGG@u?c1q0GyXT0@%w4-Y<aVtI8HxUOVBW
z1MoR8Zm8-HkpXfLRyGqLh(6EkWp?%ZQN(7D70xUU>ta3z6tO(2t>PpER+CyUz6WkA
zhrHjoagt&nOB*y5pLK<k1Sn$TTJp6>5filgElXC6G*F#6@=emofp$}NC1iB`L^L-b
z-6%6Fz#}f+`yfFq+Tzlbi(uxh#U;008v*pNiThD8tZ78XH$&s2aMDOY)ra9zVg2ci
zLcs|rNs%b*j&(A?vou8(+?JRRhoKJtUpBX0)Cl}{&20wMyc+(p*d`E7z{vK0rh8#n
zXbW#CYZIh6Q{^exx?r3t`C&AE(h#nj@$?U4+t>Hb0O~pNH{Ix&>NT2h^Fij_Q>!2X
zhV=RX>K8EW%_^2YPo0q6{ly?ouQ&hB>@9s<M#K=@rm`6)c>ECJvRriJ=J3O-HtAKZ
z<l|q7Kg&|@?STiubtcs}lgmHE+uk{~muk6apm~cTaq6DkS&DjH!h6n#E@j(ga#&;R
zN#qrB`Z$;p^{~3GWwpHaDl298;z`1{)@d?eA7YM4+F7Fuu;QqFvY?~2KP>-bpLMlc
z*c9{<6g4BS(C=4hcxSRkq4!$`6liJyi{y^~41!HnscwjQB#KNPNn``8@T)K9#EDj7
zW`x%F!)ewM_c0%)%gVf~;e2MH6QRg|tMG-~8r3^W#a?v!FJy$6%g7S`WR5B?t~ch}
zc@;=7;~jdko_>!ZcO+^&da)bnU{G543wS(a8Gr{e2Xy|U)HM8sm0we%b$zs~^U7CF
zH8zF^CRR=N*?M>c)Yvxn>QvZPn_%z-5L4>vTo6)@l5uOk@#^E*buR+e*okLr;^Z2=
z*ad!OeodC@1Kr=6z6XI{!S$<E!B}*3mq`3Myz+M?^ZVwU7K2x6TnRB71Ad2MB+yjE
z9>#UKX({>z=o~|G?Dtk0C`)bdx07Y&wQ6U$9V;pPHj_}yf4Zi=)bYk;J`c%GR^v|{
z>@v>@@&RHA?h?Tq0oW`XQJMDqP4|w_^yb71;_2y?njhBBv+3iIu0_G^*P}9`X&-M0
zupWES{aSM$e;_EDY2csY&KMz!qJIb5ni&Fl1=|?^q6jwE+5QrfitO!LwbkS`#fkM*
z52a|I0juiugXG-+>`481X+0f;rLsKX?BJ4*w{JI+WIQ!5jL+W3+4K;d&^(0zxvR5n
zn3%h<LBJH{jL%|d)H~Is!X(%mpW8g?gvp#;0RytB<bC$_vr>>{641KAa)i)fu-7HT
z+1Zt@5M+$UKFu;(V+QbLpZkC5b_cG_<zt*14Qa>^6UGAtH4b<y?E|fMbOlGA)LALN
z^q>ivy|@+Y1!I*)Fp#H~SkgLc&EBgkvXZ+GH_aP<OUVr3+hthh<=eHK-<3oGPE$nd
z8mZ>JKS{YwOz=jdcq@M4Vn4wF#X)b%?M%Mvk*R!xrrYB`#J@Fv#s0ot#TlOq8xdVa
z-Z8yvO{n*~w%5yiqK!-CmSPCmz?zFPTpXXHJ@JrP1TY|lS|z$;?+cNo%XLvT4IR&P
z%K9^T2`f6_5)7}yn#Apc1Klriw;4#(yu&i$8y5|_ciHB#*Ua#Hcg=~YcUe=$vYbCG
zWnV=uw@H<Je|A%)Wi%E}I$<9ji)&S7cBFE!DcX~tVlu&iY5(R3aOE}9a%|*Plb-;p
z#B%SVA*gx(aNx<R!nj0UV4E7((b!<neqL<b2<ICEHdpreVCNY5FF8K&uZ&(z3}-5g
zI<Z#f$Ied;m}Ym#kS?(uvTK*vv;fj2HZ9O|5Mh4L`4I)#5ZU16@JiZ8p9+^<yOHJV
zL<1g4(J_!it(2ZgYuzpAlKAql=+r>zigoKiiJ5XGTaiwVs^b#rUaBn+%{rSB3pz;`
zWvM58x>J+lKXCLB0(G_bJiADpNeo4wNkoGbHUee|1e>;({j9)v+~v!D!gv;>cpLe!
zQW(-543og-2LLC4T#{zq$G!oPtpiK}AuL10lpN{|FTFpmSRoq82B7&8V+u@Z!)7Km
z|2pmW9&#||4QC$L_L(&2kaAW>pD2C-FfmE$n$PO9Ka^JEvIZa80@;GcYYYevooi(E
zykRcE=p-j<naX%cW5GLtNpI1@a`tF#QfaF<bpx10&uHd}a_X$qIxLP1#y{PQ)2+!>
zLyZf&xrf!(sQ>=z`FK!l188z~p!9(%#ZBnfD<2q_U>=rlO@#E3_<EgoX(t=&+6!JX
z+)+{YnTUY~$O{ql<$WzZ6ALVN(_Un6gu{g~D+pGQy-aaHx)Yl1JeH91Ehq3^QoV5l
zp8Jn7pkbm3@h%tN?(X_d9XaG2UywTDF>kZmC~ru)#|37Y#$#R`!~1iOil$MUDH;l=
zzmVH)^Lof6dOcr!y1}LI(D%Y{U(l^-r*gqfYhRGXgFK-HYfwMLw-Gt6l|!7Tt=xC)
z3=XE}TbC*tJlhN%j=VaSMouVpbTZ3<i{I?EYD?eQr<yTio+0jRFK_Vtq2+LN;iIt&
z^yT_Giv%-Q_`NZDXHAJ5J|De;3u)|$4f*ho7{EH6PQOJ;rM2nhM*|bgB~8TN<T%>R
zn~snSOxUx%6{8bc<1y4muUbZw=rgV2JncT+($$#%X<lyDaC+7U+bw<gOzAH#Jh7z?
zW@3@Ds8MhJ)Pu<Kn%RTT%|EU~-N858Q=!WEifMNYm`r1$AjFYJ6^VMuaGyN(i!v|n
zo!t2lACsZNUru5AM*eQ^r0IH2B09LFmuPHI%2TiH7qpz2ofv-D=tbr*2HjlCR!uQv
zlYGWC9AUsVp|uR`JOBa+xS?-zh@FtkAx7B>kR-Lgg0XV>SrkXdA0co#4N-LCCM=#I
zf2Xq79+=ua7$+i9PmWUhIHWA^i~p>C(R<C<9wa@k3xG-dvhEEvy+{uCDWCNIFqVS|
z@X_df?`TVZw%~g*{09;})k*`W4T1|z$~@r8;Fb0_H8{o+l7|E%V->jn7YKVCoejv6
z_G8WkKM8Q@qCUSj*Ko_-R0eSMp5Fo=4*|GhOvdbiEv(be;_A6sM@{%i`RXocDsfi~
zFJkl{v%fo_0sle2<O){KkJ-=WX16;D;9+Fhgkn{BymUKg38H5nUX#`CQ>4Y1E3d*W
zFA1V2%J+vqtv;px_{^_rl6By5>M)`5x?D+voJmw|Qkz!`rqG0i#ytG~0*a6jMMzco
z<g^+RdA-pB$Y9+*?hBH-^T(EW09x1ITD*Y~wI!Wzm!Nasi_|^bc-j<VkG5-HiM$IQ
z&sFN8w0Hv}R!gewOxdf&VZL3BkLA<Bi%c^ovz5A$KU!>O+#u!4!Hb@i^L7w>%-vJq
zgy=18e7jSf_L-P1CzbOK5c^xZD7G{DzqRNBBWlZ2Qg^~m`@Z1C?n=@sV-K`lD!yI5
zkNX;=?uj4mCxREvDupZ|`_41u)y55I?hUh*5PZLrHrtsj`)aSD;6?mOAzO$&^X|SK
zWM6(}7T)NGzY9kGfj9w+zP2+##*ghG`_?my)4}BX@g)Zq5UjI-$#~&;(mh89UEc{{
zuU!ef?aazjy-vMxi1+;V$&D)HzUjG2NSobB5Z|uXrpM7J*r`{~C$!v_&5y^Iibs8n
zM=9a!Zytz-BoY!dHL^%$9Zii)_c>)TJWmOJN<mi;G%Gr-!S?3nKbaW=dW7eevZ~%!
z3l2Db_qjx9rFtetonUz;Do%as`BfZgeRF@EY!m0RN?(SZc9#L6COVD}sAUHyeXI@2
z>wp1k!skKJ#W&I9v>kUkod0BCcn#tGyMaOEL-Icw7`~k(iEMVN-g{1K<CpOu>!ryj
z>voG?*7%BW)g-Sr9W=Aj4R4Kd?swyW$#IZAvCOSW12sKjQaE!(VXhi2jcMna5svzQ
zFZlwYk^d7T>{Idr$q4Va|IP?6hI#)JBYg3C&Lkk1R2yJ~Jy!k;M)=|~>MxA2ujCn$
z5jGuX`j3ooKatSCVuZI2?FBPi(f@ZDVSlZcF8^IdSfQ<XvRU5r_<zI1fTUP(qMlT*
z6+j7gI~oai0)DLKnNa`fIcG=x({nx!7#))63c5cp()>Le&u3fAObUK|E!pWKe?OXL
zC602}9dVJkp>qSmAxNg!hU{JeAJ+37Dn3Qj<bBe5MjpG(T)6;-3#mz}R1+TDhU(7=
zHwM?ob>O-w6dky=o!BleEFV=|eNnB`$1+Rnk$-dyVl1c}82>2R_dAj~ze-ZA>*op8
zC-a=VL*^N8tX5pn{YeDsr>250WI>Ytj@I4B>-Tsg(8E<mvizDJ#rns`BWd=!)HRD5
zww?rz;hXVb?)T~{^QznkxNEDU_=rH5L_ZI@SCi$t3FnyW{%=kKsicYk#|w+&+7JZZ
zNE{fDVv316?1mI<u8I4G0K{xIAVrd9CrtnJ&Dm+v_EF52)KKVo8sFsLok$f2iKfra
zpB(_{Z+tj`aDhsblK#W5vM3!~9eTA)dxQXg`aQo{^x-;LUKSv5Td-PtrZ4)AonP;U
zTYJ9Xdv(PT_r=(DOiNAwGN`-JzWFGqO?9wAW;yUx{aPH$UZBC;nNJ9fTLZ(g1DkFl
zR>IB_U1-jtsr#8bse2>Dy#eSLct+G6vuz(gG;MKvXS+QgNV-C?X7qJCM^H0pS}IDA
zDNkOpcL-+7oyrzq462+5K-xa48GS=Q#?xgoa{>gGn=PcaGps?2k$k%eo%<QU2-(lS
z=Ps@BVc(q8o!NNW24auDdx1o~v@l!r`F5M(9Y14}K5#CQnY}9G1_F0)yO|ZH>9z{w
zM*!jzaQ;4&8BAmZak{Z<4@9I#yC`-u`nOvi0f7o)-xa(_TNyr6Igi?+3+%qvG6r0c
zEpV|DDVAdkSp<G7)yM;Am!h}Qa$p9rN8jxMK0wn=_Yfd+OPsma;;mW9?M%BnHB;Gg
z&s_%j;ZQsGMfr9=R+2Utd+_e=+aN>K{v{CT+N!-@V+t+IH%B3ZQJMEgWVBkW#uO?h
zWnrsgHc@~rO|^+WG@u0b0>OM`Y05VXvxRi?>|_+oSwPO4z0&!pM9J$D5`)t&*sDAA
z+>Hmk%s<6PRi`!kzl5`G-%20L?h<2zQ(67@k&;d4_v`OuCpXTl?sveE*qk3sWH98a
zNho{kTa)5-fN(n^%^a8(#^T43r`MORt(G}LbV8?^^_bth=&{a#I?~zA{`LaO)%2F%
zKL74<F{hlzZflTfY=Ti^IX@U;V5R_k3CRRAofXo$7DEW%q2~_7sfxGRCN-V37v}7h
zDH{NpAe|YCLx5ue7TN?@v|E`P5Ij1&s>tR`z=%*IBpd{Utl_>S6`sE18=P|K%l^gT
za@(t6qx_t5ZGa(d81G$NTA3Da0{feP1H{RmG@5T7yb(Vv&0Boku3WaO>BUTyi!`Af
z4ypbp6Phpv@xL&kNx&C4k7RsEP9|)j<8Hp-Vu`ELm~C!@_X+*7xta4Id5+pPe(*<w
z|H~#c=*EB7gl4+kTRNpqk|UO@PD%0c=$8fUr+ODaIo<F9OtVBRcd<F_=&EW`ajeD1
z`uk-ef=BkpQ|!}%X2FbkpWB+QUjm;U7XFujT&?^Kll=pvn|!RN`wtoJWAQ&^xPR|k
z!%<HD2LfZ6QRvMYrt`*~>9qj+T{Ay?kYy$SY^}b^jJbIBwuh2Sfty?XEwTf8&`<J9
zI*o_m%PjYw<X7)EPa>j7tjT^Hr1U@TZz3Z{{6Hkoko2l+<Fzl+Ih%W)5il6r#$D|4
zvi^RGLN4=2q99W%8`ltHe{ie)&pwibq`x}TO!?@{SZMxoFN8m1u6;u6OhD%3MRT0<
zWY`JNd1NHs2&{1H`1H^HMqF`pOFM2BCo*&7XU+ICH0t`^0bO_1-bY=^=)V&J3*r<Y
z#J1O1Lbu1M=;8E&<Lc^|R%g6d1A0WNn*iNPO}?s9{M~d08QcDLCqB?P?>8k5nk<3w
zHyBvEhbQdNJ-Ky9ZxtNDo36qMF=82hhsAi%R8Q)AKS8q$&YL$NoHSxW7W=VGek4(x
z@qMey*7HHyGy?m{dgvrs7S3ywT<@h8nCmUKXsI6JUzR3HuXC5PzOR6MZ8-F#$cP((
z;C}LCP~XU^O%HkCZBTI0M)P)6W)Llhxvp@BcP3dZYK%`U4D02a`WlruYU;ghKh!--
ze|qF9_}=tEnGw((_Q&YX-2tGd^T8B(!ZXla{rP~{2X|DO_-30(7|%lg-d4p?cyR#O
zoOjQoV4&u;8MtaM+;#9Xs2SkjSp7j{iVb9^svD@_f}NYdh5;_n#pTbizXNQ<WQx-O
z|Avs;05t>r8+|%#YeYFd(-mA$l7qOc=UW9en>h;WBl)+29VGt-YMz9^U58hI{Q&>g
zJ6=Wsob4z725ROFgl!29g#g1f|5hM$&A%ynT=Q=k<-hp1pI7ZB0s%)N`8VLB!XK8K
z{e^#nZE5`C-{7v~f92nR>;2^43U-P+^!H#}Y~xF#wQ{Tj3@3bY+j$@x#B6DJ9oMfc
zL9RjecRe+Ww<6at*nn-0rcUoOBaSBGSCY^_OO%Lh2o%-sMWuSV4-gE7!aiXJY@3Th
zlf36tE5EXU385mr!g%ddr(M9`hdv?Xty@L_$jvpCG7V#}F#$#ug}XN(2kt}XDNLdE
zvEwbF71QP{7jWNweaR?OunOa(q_~wY8?tSXiiDHo-@D5+KdnV)CGL2dF{SFfMg;MD
zH9xc9e1_SQ_<K8mGO5-Td106b)0^7I90x3bFTI7mCxxpgGj{5OBWC%T&D_I@kg50f
zwfU-71`i}-ve$McV{}Zp!zM^lm2;<NBB<(m%<+nNtB|30GpUPth7$uOwt3I7K1a4p
zd3@mHg5l1c{md{K3;SpE+|HA*M{#S&QhkK~SE+vUm5G(Rm-?m9PS&G&;l^jRalM#s
z3LkjbifG2jky)O(K3U1N0RVK58DQOPerMet8@1<fW57JR6w^#dve>E&tHH3cnPgUB
zY;gPUy{9$=$$V?LfQ?LODWCtsT)@3m$LV;Oi~l0O24+6!O(3((64It45Rl{0{3^#m
zFfhkq>NdDt`v$O~$Sk||NU9se3tX&|se7ugZ>9n>S3Nn$VcT-)by*~EI$|>4aX9{K
z;6S4QQQ+qj$K&TN$o*{q+xxgA1UOqnsMjPE*fsolGZpJ-Wixf8uy`*h$6-WSeI8wA
zIqiA^w->2yAiJFWx@r<O@@VtxQwmT>c9xX?a(7H49FK>si;Bwu#~|=0NE8>t1OTHX
zQt=6#SsikPM-CiGDtuvH!e!pZU+aTpK5LygF^7P!=-5LG*@{$R5KG09;x2OJOAH;B
zMn`;gwWR~TYKS$$M&=LZ^KW#s`%LHG>E>IC0Nv~%yU0x=@M#;Mn@#WLzB=%4{bxr8
zeT8rMyJXWQkf>*?!7b+G;EzOThxOuA$qWlPts?Kxv3k)>oy$*grcPGr>uY;nigbQz
zaWCoO@GC%eGa-Q<G>;XOf4^OAzkl%R`?68iIM7UMpV<HV0~N&7p#&I+O!se|6VGE<
zbx6p(hmY99PAx^oZ|SSR@i2Lm6~YnTuR5kzx9bUbtLymlZRWGE3jaEjZGf4qgPh58
zz)YS3W^!EvkQ=f+?fs&42WYbQEyPPks0Dbt*h;S=Tr>CYU89nlF-A;DP_Dnd;Jp%=
zxJy17G1<)8j-emWFWR;@J~;#8l)j&5fl%-hCTCA8lzGQA{y}Mr|CUa?Yj|AL23Y8n
ztCI&4Sya?I$Ar`2zJodQJ<b4J#ywpoDL0r1)p`q@JA+<7I^K~A;rZe9vxW!{jsln*
z=$4&N+gA}lTQ?wuo*@HtBDodS7}Qe%Kyo08tu+d+h{shv$>y&v?<LnrD!Q7vz;m{6
z2}B<PcFWKus%w>8JN(U(*mpb)Z=FqgxnD8WP>|U-Dyn;Yj8PzQqrJENrJ*o6v_A;+
zRY}+o^)!d3Z%kZRvq8Sd;9FP1R8m<%ZDw%#c!+5a(j5alhMKT?BPuX@BiMVvQEFgf
zLom5vDH(S=2AKF@w{i9mF~A8MG&U>+e@=q40ow?$@xC_g(R^jvli0}#OXpNpXSok1
z7L!r0dctr1jZD4!=1LM=P)7mXh8j2>N^gXRj}&kaR?>TH;Aass?j<tdS(@F~ap-&-
z_*Guh|Btx80ITZz`hMY!bPLj{0uoAhcPQOTNJ)2hC<01KcOxkvDIp*tAl=;{-Q95J
z27mRB`+45?y3T#PSZnXS)?9OKWX&4mJ3b@h<smCL#L8v#waEkQSV2@4IAO0cbo8Bh
zVHw)~3|iI)s{u^F|MsrhF4zlkyQ(0{4186Rf5y&&-%b7ZAi=!w&p{%%_;!#W+=dPk
z1}y{UtbHyxpqqB;dKAG-HLksr@44&HcllO+GCjQE=ktf&9HKbP=x~xjbRv@9P%%v;
zY2idD@txN^ly8@I!jO&FtVe+l4c~c-374AGU^EQYs3B3gX!8!jIErZZ-f^s_eD_Ga
zW8(dzif$veJV%bqr-fyNvS!I$CQ9qs&~;3jL1eD3@!QZD5JT?}oMQ>P<AJzdLi6B9
z;v>ZT87hVRLjCMaG<mkN_%tKWk75*%!3Joyup9L0B)rxSMm0qUH|QJ3Y|9QSee0;A
znyep?G)`k{eVfKk0<UIw+@*6N?$R{i9G5{x{!5z;dcDwmx5kn$Z@Kf=;9IA$9m=P*
zh9y9CXh$)#CxPHX5+-4C@Y!ut^9?t64Ssp1YmGeA1Zry$t6MV$hm1adfeSbVJ7ee{
zX&QS8`bVmx>V$TZ?$W(^_Rx^%+q+f~G_*})=Y!r6d{u6;V2z@`ddJUS-u~_#!L9z@
zJL*{@-}a8v*hG_>A^|*uA8toT=Z_A)CO6`e3x=#)af!{)dvK1A6a<iUenQ3M`91Sw
zD9G{K-uiKiFu&NFg5n)cmlxgt97#8$1)l)lnyKp7AGkelZ)V=UVSjR*E~iBQGskJ}
z`J;qCBj7aLzw)T-k*AA0gqe1jJdqF#$$h`vC6NI~0W0}XvixPAeL$fLCHskw+qW@i
z`TR3D?KHGc$e~=G-2<t+xe4PBYS(q}K$I|}=70Cl6{irM)q3($zt`9Kr!N#p>@km6
z)KfVH*!Rz$`OmpXJxV%6XvGtE@=k0&ul=hNS=a=fh##wSw8YgaU5P@Nb8Tf3S;PC;
zm>nQ)rk}GUyNIG+Tx?>7IV>WhF~!1kc-mZi2V;6AZivi=qwousqXqTQ6ALlY2~*a!
zQMp9LR;Te`p2`8aLFUm78K@kr<gOFoVvhzSJ7t8<5p0*=bF`q{xKjTc7yE6dhpK<3
zN3=m}0lefXU2EtuTIilCg5;^4)1-y#>MV`U;^$*DNt-A}e6ShYL=`7|Q>>>0TRS+{
z9hckgP9b@kkV&^4Lb7Ncn*Wv4E{c(~3pKq03smQu>A_w95L}2T(~Bs1nokzGXNUog
zXT}O}wW}XOYhzX{J|hID2uT(@^aQ|;5X6Rn6Wq|whDPV6vr(*fSerc3w`{t-E5`l<
zaP`nlm2|DXCcHyKe}-;?FHf&J1OhfO!LJ~t>c|IOU_%*XB#Q-RAU=}<T<I%$ssWz5
zgd~bgPXqnO<}Oj>H(+&`_dT%Z<peE1{}uhZIP@p_wfX|<FZ636@ZPTOe%~e<KvTf9
z4sV5aS!bno4s>KBA=C?Y)8UwH_KA=!#GB}e$B6oT%OkLjG!C83jL=3C_mJ&-kk#Ey
z5$P7|4;>4?F;i9s_8pPxXf{vW@WJM<c*~a>$QPrddx?IGM)IlE#r;o6fNKu&e}M%2
zU4eD8I3yr{Z!YfuN5r^>Q_-mCz*Z(-7_j1xmy0V>PdxtMNm=^e2J>-UFqk8N!JGp+
zEp3#;p&g$&za7mf)f<79{W|^S;ZUVk&C7mA;O;}-PBYh3P^ydRt9UPo#li_&63y<R
zZa@GSS1oJY!SR?wckpQ#!hAspYO-)I=~qT<!YuVN(o)_Y9jd-;&u3u(a<4z0HRXGb
zA!&?VBE`VU@5IzE-(wmyD6lcHj_Vg{`ed+#WWx80v0dYwi=IsPkTZ#IOv9*x&zRdC
zs)eJfSi&Y7ombh|llWta;nR|B+7gub^4%>YQ!+!p*;8MlFC&tdRo&c2p$MzgKBP<T
zO`K9*`U4vVi9tK}_I+yZBUhk3;MPs$ylUANu;!^FLbp9IslU(bgs=`1?S45r#>s<1
z<unPoA@+hHdYQni!&%63zpn<K;2d$s{h>d<7YonEZsaa+LTk^|ZrhlF{`!(ZeQQsg
z4kldYH!?w}cbc^dy^+2y5n(Jd9d$JGK~wGyH`L*&w{5vpPE&f_(&{3(N_VPRY!82M
zZ69^YvXB@7W@Z@K5vr`ZrzDrj_CgvN-b1(0hqu}7!9l29@-!b!$6!vYCR3yKPhAAq
z=ws{RZ<ofwc>>ZE{Zf$(dC$2H3-Mj62Do(+%cYaQJL|u4U)f0!eZXzaU0TJMijp!}
zO))B1>Rdc_ab<HoTxi6KMstcZ3EO*w5dt4Qr0BoDJkirS-uYXcT^hsjTb%u4{tIfS
zR_3pJf~KCcd_rwGd(py;z6+IFT|ob)@i!4%WLxu(m@S39HVJy^H;Ap9Q7K{3=>Ws-
zKkRC&Gs?~scQ;PT_kG)}5M5#$Zs$=88KP4N(mr8)l2bA!Rz%^ldx@YJO^of9O)DAJ
z8PdObcBDsq+*~dGN6(I(57*F^eR#Ut5Be3-h)fDZUtXtarMWzxuVonj`}p~@z_9;@
zpXc9z;^#$L8UBy>`4mG-W?|VwwU9-&mMk(yBsVgJ;#EHtB@=DJaq`#i-DKsf%>ygK
z!&Jh|{jZj&{?g|ygp1th^W2mFO`o^t)&8IKc}XUT-PAK2|6QMliV^yAJc$mlRRFGr
zBc&##!>(v)`2|q);(C!5pAopkhILiq11+M3I}{uV1yQkS0Py@JG>G3-0Pv|myuFnr
z<1oi)h`{=^y#7(>0czbES$6C%hHW$f>jhg6!NSszR$BqF%<^3q#p!oOW($PUS;b>T
z2hW*{iHpODfYI-N!6Hb<EFZXFa0L2dNn-pz<E*BU{QgUvRh84PCOZx+yy9&wgPVjN
zVkJ=<-(Xb<p^@4*fiXF_8fgx*VEz&EIag9WYxfKo;G8y;!f>v#Zt#DW|BC-(bTgWJ
zOicRPD9}eU*_hl}-~~{K@Mo63`C;pX%)=L?g1I)a&h8d(`sA!U_4?J$kqiSD31e_u
zwTn#|_6yx07uyk&(;#$su<#hfS24BhC<^$9TK=@4g0SfX6581fI>OnX8=xZ$A2aR5
z*T$OgiwT}d8#nr`wm<YzTn&aQc+O0V#ie!&H2ygOGSp!A`Z)N|QMx@+oKYO6yVbsx
z8-+_WiQ9e&^B^VrIYW!`*kIL>l5`c<z}sF`*u{C7#H^SgF`l*ZdvF6{Kq#TD)bSf}
zzT^0P8F+y#$67rp|3sKGk_!C88}xln`M@r{g_JD@wJ!oN7Gi_om7Z4rl&F3)XMSK;
zq5x{6yO${2vcJH_qf!23;Ookwez=MT!>bpwmA<BCpvZGNdVE^$#E|8xo{u_x9nIKz
z<ys^`ISbs?ALcUV<Ut9Q1n0VU_`l+`W)t7bgAy#D#AJ#T-ig4x4mhm^Dge0_4YU|8
zf?hJHNqt;=nAnl@RkR#LB!atr%!)zv2THAyX9*)-;XsL)sCu2D!>A@bXdHB|bCT?%
z_iXWw^9O)h&#!$^Wc{0BDYCsk_I^)zTlzpC)dOA6p}h2=EjdFAP&C%{<h;ZWk<5Xs
zpNuyOX!o05j!abqVRiVE%aQSz(WqPdZJhv;d3^e6Np$henTMSwev_qkFrks9_J&T>
zZp#QKn6ump?M9n{&<>4u)4q|vFHc6nR*K<eR$iKM2cTmTsCyoSt#3vHdl;&JW<JZ}
z34gv>4&G2>MdZj$<f!d8156Y92FxlQoJ{I!@y#hyL5(mX9SSDK-1u<`9^*{P2}gI@
zG;hO_Z5Yes=ApF?cr6K}{ApfWTk_hhc?nhTEI@LgW!WkiD~Vv(@Dan3nT&k|=0^6!
zHSLTt#{G75WPz!l4mh&anJotJY@G1fYt@Pq6QxJi8P?v2r4MtBCNL@{u#_8xoHajx
z%yP@vY57ckrry{;yxwk0B4f@L(Z=11OMuC>9>#t`$UE2$<qb4Nee)!rEZuKO|0_&m
zD6o@hnacwM#8f)}!*=s`YMlJS;k(D%K@z<#J-3mc37fwoKNIB1@g{=OZX!QjnX}X;
z;ejKi#Kq>vYItwh9nx70?x>FCjCnsgrfc;*ivPZ@n4x;v8;i4z;}KS=u3TcD6h$^b
zrK3{%>PFb6N080j=V@OYrIBTox01+9-a~5aO@(H=)EO_hQeQn}$DGoh-2%0}AC<2w
zujK0;bae?}6N)h6*H~K}E%w}XtJa;F492R{`fP30^6n+WC?}_Z7$ZJvR)k%6h#h>>
z2zXf2!NWS$`tVfs9(@NJqg(ZJ%IFx>7ct^NEV4kkgeMK2Z7Sn362_?pQ20G)N1@FF
zyGdF<ZTfboL20_K+Lu3|1dN@oAHajF9}h}c$y1_wknch(V~CCkdbKpl%z%F-&WQgw
ztKTlX%TR9mfkvFE253l1N*(ZEB3AvJs>{4#_IYc)M8nHZF<cT<nK6i-&lcYpsIdIF
zuoGsctIO3UA(fFik_3=ZeA3_9J8*<d8wTSHI)dWF;UCP5Nf6hDtBw{s(VL((j7NKX
z(roV3vo1gboOwm@K*g-DK@_U4p|+MVvTiEaO`b-fM-dGtW{pf;D*Kk%o~9`)VT*7w
zsdvVA3uzcmPJ7dv+%f!qeKm~B`>%Ken|`tXj7KQh(qH*EmM8mmV%{(1YPnpHjz_a-
z3HT}t|K_l4`=zfh?M!p}Dl>)(OsSln^|ZG4mU+N+)%=O|#-@W2u1FrUu->rM9eKx;
z8s26)a(ef{m|H#mx#(Mc!euMWO|0~=UX@Y?&q>igNuJ&^7K>ykv$TLn_dkNYF&R|!
z0L;_>lLcSK|K~JM-B16O=E*E_L-X8F!TC+|oOEsbuQbn@8N7Q35yJp<*Wx+yf1r8l
zc>D#rbKda$40WWsW$OH!Bh~E@!GCb1KBKt@Xr9~o|GP9#J<9t3TSw~u8qE{0>F41;
zO}>OjWOIKc3UEgLD^UQuoUHCNjhVk<GUT@%scOGgcPA-LsE-c>4jBzM|D5{m#Q?}O
zi)~!d8+q`d?&4`VAbn;BczUzYbuHkg1EaU{#zkd&UFkpL>LiNmJId)isZ*{@DK!%*
z4-rNS1Pz4tr;A)-yMA#WA!dp!zPTW<FMkFdX5HM|6nzPxe7P?Z|Hcpy&tYrO(qh+?
zqO7(#Apl8If{6_Nh#AP8L6A%}0GbrAzroRc)ap!K*8vfV*sV?CXqfXWjUp{Ub0;DA
zAw5ry{B4Q5GPbLOP(B_JtMPKG;UnhTk#Lo{_{2!Mz2wW+_wMMw>V#=3u~NL6exmxu
zow{c6p!AEA!yhPWRc|hT?h#}=xV&~7xIDWJ7nxZkCE!-<{Dzg)4&FlDikNpvg!4&`
zI%knW?=Ri~8(Qdn)q7lTRN%ozNFv-04eLYrg`@<WGlU-~q`DNNjfFz*f6R2PD&v?(
zQiA3|fVvg$FGAglNJ>LZSXrHO;5am_?*lOH+*iGID<Ube`%*}8cLspnjaTMA`;A*s
z*zCrw_$KPNTk-a;e%9vTN~l{AeAV6i5z>EiD^f_Q{<aunW&Ja(??e8r#rXcvELPUa
zWxNR=3V;-f2BsFy3Y{Iv*f@LGRWc-hAVwnECHV_e=-6NYoyoLVMy1*DNE)H0x3!1I
z{-D@ARNQTOaBg^o;NnvP7TakQV48r&oDCgtC2~|PzCYjV>9E#r5wJ{Z60jur8<_}3
z6m|$o=vtxg{8JiG!v0^R0sly8!=Fd5fG`gynI!RkgyM&Cbgih<2zg;S{8;M2JHV^W
z)*k1t+O~0cgcbCQWxxQD;xcb#m#@xu^;wp6&j<Ugvnok_BD6*Lsv{PUvb~2MK`sw4
z32zfh8H{3H7U-^Ow%9i<RHKNmo5YF|<{Zn5Gz6r4uaQS>6?^v^PN5w$;X&xnfQ1?=
zZ@33vBfGCX9yS@|b)~Dr@?g2Ay=%On)?v&mYU*Rxf-z3&tVWhTXZXLg;n0`AZriXf
z6Z5LsuRHcdw}5z$MJchCwW=2zlwbG-f=VKJ>fBhphIt>>@IIQq#6JwA4>`>`>Mwf4
zplbSrRvh18ENGX~kvT<+vE__$>mNva{-tw?^_ObU6g`VGKsAMAxo}GmA=v0l#WmHz
zmzqBWYGi`+7=aqOen<ZzqC<<2j9Rz5HP2;rESB>>{y=~757-fMYiJ=_YbbqdXfazT
zsb(l?ss#yeC0Z!yI@GOl*-~QAp_ghAIy+jz0Jd(h0k=x4nvX$iOk;@waH~Yi+k}z=
zN4Y>Fx6=lR>M7jvXbDe(wK;IBkZK~dhB^Yb%4o@rTZL4UpM-aq1RRIDRW?S~=0I(?
zZWU5ZRxYPcz^&r+>Bg-xT5@CQEHSustF*5DcB|anRXZ4MX|&|Vt-@PLf~n7?_E!uV
zmy<<>iYk=23~u#6b!Zog#)AS#!Ts{*yaJ)W2|5|C)88{m>Mg_lQ+Aj@R!as0))8)O
zfqZaKNZqLzXAQpkWM)vT1;$T#i+=;u4G8NlrI8i<T6d}!)boEJm`+<=ifJa;3(XAO
zyrOo&XEjBq$dmJgj(}VMOuXkHJFHH*4=|uDDjO~o(gTF!ShIC5oVIKcLDa?uF#=yc
zak+i|u&Y0-u>Yen!#K*2O|2$X;%n=^5k<4_O~!@s+-9M)6CF|60`__R3r0mYT4%+I
z{28mmrmCTSs?io{jR&7LBb;(!*WT8o!S{k3rsV|Rk6xDIWEh%G<W)fSvzo`-O}$s?
zpI8!Bd{#6k7XOkVrHo3ooyLbp)6@@As8R^8E2gd5IQ-m_FeV7g`=27}T7u}UC&>&F
z+{3CC6B|YU6xAQ)OEmwvhNx0&XPSK6oCFO2n$f%;F{T`f+{Eb}fJ#M1FmI>`D!i=x
zjOF%tg7%k-#)_!aZ_nZ5P<nq3-+#8W_!=(0SHB&k1Tr!;du!j43U0+Q+ikouJf2!#
zTUBCvexYKh3vHVpNk<H$@-ZE^6mjVU@6{Loa{yfAKY!-#Oh1r+3Zk_#$Sf^E_}b+K
z$S;;C7cX-U<QH=X8N~k3Vcc@<1|vh-{k8(`gIWJB$rp-qLXct%+wcj#9Rp9ZI)*oh
zy*pIzd$?%d_e$SRt9z-XI)BbSSF1NSu>ZGQ^ZT3u06WXS@3(uP6>Mq;-s^;Nc*z~!
zx?O`P5232fnSJ|rI`KLT8j1{D88A&)=magqK;d*DcN3z`cNQ@B4j~vrl1=v_6t8c#
z(qaCpY<KpXm3K3%g61)I223WnB<`7wn6J^E^6IcoR)Up9n8jl6bB9d7Gk;CVOUo{a
zO8Z~0HF^oc5$R5!FdcT#<<&puehEahQ2ty+?MLTRf^%<2m~(GK0^CrtCh(N@8LW}f
zQ}$BflIOsZIA+4k<q}`D@U2NWdI>v@&HyfIe%xumV+ps?0Tyl7{b$QI=8p6xZ->pw
zobN?nV&G{O&`(t1Qbc_T$v`q-nvy!+jKO0+e<nK{S7%#@&il!H0Yog&^bn6sd~OOK
ztpe!o(AJiHXefhK2s$s16Np~0k)1rjBz8j8`|{0y>ftCoLkTM)2l0gTMwMrvUcTQY
zJ3y-F+%xdcYsmhKf%LiI5umAz0Ak-&0s$-ZJi@uTz5^7G3tpgj+>hEpAedz4^9+yw
z<uG$FC&(;&LRwJI)9I0`K0g1VSycWZ-ZN_D?^JO{nJZ~e_eaZL*bbKeYf6ddYms5@
zOUyDs={@HE!jk=>e2#kK&<D@!(cdyb0b12YZG4|8UxT~cZiWo`$3S7=x*e|;|E<am
z$(Ue#K?=V>!rS_cFk1Z|mZf{17cTfIZg@}mypm`GTEjrpU<i575)1YAU4}L`R-=X1
zwl5!TgtPOQL&=RB?gWRPp4gJ{Y&mzfhL!2SG-QU|9K`}g7EC^?h8^Awbsy%Y&SHop
zsqsZ9hd-4_m$O$8mz>R@Z3~j5vLWcMIu&LN;L4?_(Ujl1wddSAHp`{3o`zjhR9ac7
zS+9|g)fp?>3~beldd7(%oMBpGGY$j(!N7`_#BkRoDUH9b3R4iZDp5`!Uky%ntbU`k
zW;zFwTI@WXr|FH%?4e^`7mZTv_<Ie&@S;Y+w#-S+eFg+(qwgO&uD*iia&eH!z}+AK
zI6nvYv}q5h#?0Wv@j1gBse>h|NNoP9w5vt6rrc)LacNPldLTNXa*f}vEMW`zt!Keh
zJo&!vJEJ<|+1U?%+zYTKTGH}deDvh8{}+B#^ic6{Hc#&O?;=3+l^7hh0B24`G$X-n
z&gnAv^lI80ukHsT{y)={fvDG_|Do%2bt|Y8vi%_ZK$Oeq9l0Xn^Q7c=58kRPiUyyj
zd*c4eeSoHnA_+`gxg<7&cfFewMG5>f{h8>RUC1ZrbB@3LmDae;Tees~m!y_sf%y}{
zz9LS<RpHskBlZx*n+eZm(A()27nF5A&*v75Z*K7d@PVxt%+a&V-fYi;n0>cx#RuJ!
z&KG7avzTg1Q>&#}PRq+ak`RJs0Y)j17Sb{Ja`b@aMY7A50>6xX)RSzS(1_+ZJv^$%
ze+y|Xqj^Ds{+?N)ZQevGIMg-jNvQuX=g!Pm$oK{cB>d0tBt`Y1ivUq*qeBh!|MAia
z<cXQ;kj+t_z8^-`h5sul=w+1EZpQMVB2hhdTXV7+?H}n<Ixf80)<)uH5-X(C+h)#+
z%~}zwp9*SjEib?rUq;<MxK7aFIJoMEdB1?b;w4GkCJ-exCn^y0?(B)n{Z{l>!Jj!(
zT72tvPl)ZU`S>)NN!;3BI6>sk{z{`V#qm3hN+l}%fvIU!b_?;M9>;tiSHI$v)hY|$
znYRD>iQ&(4mM8Wv0?v{t-`#hN??O_F)mFHfj#*RB-?Ll*F-127r6MRnDg1_@q+M|M
zQxOo9a*8p{8j(d}^Hw{!yf|+<+4FR}j_xiJy<T(@y$^aSCnQh^tPLBxe`ekveb8nh
zhXJaacLi6pRI~D437nrPHbWyDv48g`V=9G6b>@WjBT-lJcIE`&sAaKyMv9P&DO#{J
z6{Lrh&%Zidr%|QFL<EFDiW0IwN|Q@tAj)d$RQ>%VM!-<&mCd#V%W9coI^6|YBf*Od
z>YCE(lfHxZy(;1ZLN7#m{X4M6kwSZ0RNhdO+fuSnIKYh-M}|x6t`9y`9q2Y%{<45%
zc`MIBvoA6@uxz;^gFY*)Ro<bRj~Hsm&)sc=zob`wXY%rwhXa}?jMj1erG?|?nj5fw
zdgL^}>1qL<X)3U-pFyqw|LBG}0<|GsyoM3JGi9u@pWlXBzbjqogmyBvsvhidu+t+y
zl+?BY<kUs{o1nzg@n8~1*Is{+bWw(0u{hi~Cl*0_!MAtO>}=0zl3y%^*hCZR;3^+F
z{tIS#*VqG=jo|%3{F8O|du<k#fK5$=Lq5^?<CV?*=&oNV4*!;otq}mE#Qt+Sw)Z#W
zD`YZ-fR;Cxb616$$>i)$mG;MKhT2>H-8U$&vHbxW>veRMHrsghL>=n<v){X)3MG9~
zO_X`GZ~1%-zV(9bwY8dWeKz7qc>f+`e*-C6;3d26Jpyhp*Koz#Y;9vA+I!GUb^F=U
z?li~!3N7P5e<x#()Mw?C=?$pm&;cpi24wuqO76Jo6-bi4NkJSmcY6?xqoMA9B&nP6
zazGh4D?gRo`opH@asI+NeaEEFh8lOwS_>@Rx<@68QcyZP(L058trUE;8UCNp)_ZOp
z4g#ki%>MtQInl6o84&<+&TS5Z|4aVm9)l?BCdkQr#>GDg_0|3#QW+r1Z%rzu0|aJ&
z5n<^eE(|`JA-%)9uBC|ve2s}tZS(N>F^~U9#k?0(YyP%O_=c#HIjs7`{O(I&n*``<
z>d1mq&oB8rDNv_f=rRX+BQELbYy{uhyp?%z=yLO++YPl<-{Yv*=GTvZBpU3!SZ%(#
z>sWA)>Rya0ZqJdV!tvh5aoZoLvA?sjbzN+Jt{o;|_hp2yy#&nn5#fnbq^)YQUzyXH
zAVjd-d8c9+%dvKNkG&TwJ+ee&CUfmhg?oPH<j){e=4Sy2n4LR5Wn>wmr0!YQoE|wf
zMIQxrPzU16lLGB0U9-oKVnUQ6@2IPOHYCvb7QRgQcqOncd^!GfW$_I~4=bIArLGFs
z9#HZIhc8Pmv{fY?kF0*{xf_fX8q}@wW+6kJ+*ZR|d4LKxaUXW0E19-wdwP<$!Wj&D
zdMTG9&i!|Cp%eQvF)D|K+#DMrIn-A2KUUne23FQ~9eW*Nc9iV+Hk9oCihuS&$U!MV
zuS?(VX}R2F8#sU~v#+6bod2h6JWjlyX0rigRavkGNT_{Hl}>&1_-5+)aNUYDX300S
zf?JO!EjR%yXOS~q%wi2Jq(PEf4qE;n&EQ2_>$cZseKVLXZSgxRoOgiOd5sWuaTu5j
zB2Ce*@;n_OtT7whr)RGdM;1vOJa|O)ChD7g%c)YNTlZZT`rp~-$;}Z-fBXLjJIr7B
zy4W3dDhGYzO>l;0q8c38m+^Jc+Xuk?z3)pe1U5=qv1FG?EpLJQiHI30^-GEs@7$^t
zOa+SV#%f$t@&lG1h0dFyNZLBaVS*hT*xn^CYi;k%(G(5oFGDjsfp-{C-W!gjZ6S8(
z{2JQt?Jl^m`>v!dyI*D%&>YXN=?XL|YMCSaQI`Z1Db?(FV|xl*CxNPqaMY7|z5t}G
z4bBJ)S71St2U6&~2Gj(lsMS&O&(ua-f#!cKubYSdvAo6^xm{k<6cwFK3<(692N3B3
zX$+8yKmWV9s4DPZbib^cHa|=qkoimD_&1z?ZcVR7ol)&k|95wgynqp2HmfN&Zt=)n
zFw4gWs@_U`Mar;Su84~r#}W-v&MjKxPEG7)Y^NDTO^$fzWJ}b-@lQ*KEk<Zc@{%7V
zcc#{rJihD`*WPQLKNb0m`SE@V17(KYgYc(_0XEo_>(~mew|JJ|O7a$T%$VsZG_USu
zljLi7WvZOmx(Z*4DQ?LyhgN!8z#0vI7_mjF4T1<iO%Do|y7y$yW>0wroH4yeJ0KsY
zeEG?g=B#=7aVEZGTJx+q|G$PaiW<lN4rk1r6F2E*dvMDicLp>n<SFOa@a<5qy>Hkc
z!h-?%Ho_xw1=b@6<W2UGj^Q4P{lt(*AVmF*T?Ezvj;GFyn`^x>B4L$OB`Cw}_~$5b
z6OTS`IidN?B+6Xy=p=^T`>y1*<B0o#IP}KUfrCc8eMu(7cpz#|bi$N+O}Vy)T!eRg
z28fiQ6YcpwC)x>b?MR~rO_cr!=IAwIuZuSiT<WdMfVS_WNXmoyh@2hYRJ^k=tXmuO
zz9wozB5>0wrq@<ZGje*B_Oogf>yKvBE8uC5;ThQ`#ICT`-pn|VQLPz4Yj3ufTqWV<
z#2Qb-=Jm?`J@1UOM+>FVAp~0}DP}&2Vm%3OiUxOv2O){#G*FW+V#QFj$2O&CkTzm1
zYJbB5NxQHX&F@G?fmKWtqc24}FHn<8Js?r^3eA7$XCrpXogawv9c$6C{2l(V1gH+w
zz75o*Sc{}UO$t7{ab<kv2CqO(I{R)9Salc8Z`7pVkdcj;YrrYk-Ka^i7H@1*6zx4X
zlKZHUTQ%wJU2At<{lHqh(b{Kt0Ij{#-_)ewOZ=g=&-nUxHR;^Dy<0UY)*>-qhDX7V
z-8CZgQ1xZ&&V`{q&BuExeGFPDyTlG%GHvh6M@wBzQMNN+hH6a`5xZY%khnE7i%unA
zu>T;t@#p^c;HU)J?}5zNcO}v2=a1i|cj02@B@l=VjU_e<bEYW!pV|lXyU0MvvSHP{
z00)ufKE6bwBe8;{LeAdR>CSy=*7Dr!WbzHUtMucyB$c}H^rQ;63peqOvG)%vnt|4x
z9zfYGO9;iyg1}Nva|;^Q2}c^Kbt`=LGE^(_?S~c>m$jyKPi&2)1}3p+p^M;-^3>9M
zhQSwvv%m31$pUYgp_pU!2mfk;aWGD^3vd5n6uEm*^`ztbV%(B{JN%H^vv%=6O)#5J
z$N${~b5GLr?^vV37~Q{I6w#F-smh-6-<Uqy^*wxA2b>(QO&x8Eo7wK~cZe4#F)Z~Q
zGImd&v-g~DD;<<D4%IC_s%_r0(4(WzVZ|906|W*0;5+!py2`5rCK8`9;UE0fp+xy(
z?xJY@cE|fy3dr&*Pwwa*de$T?pWPS<&5kh~pO6hTP5>6%>Zqp(d4o5~I*{YV{lO*r
z;zdT>rShg#Vn4bZyK7KqT+03s789qIEv6GcbCO#6ABoZR1?&n>JicA#5n@fICNTS+
zE3+Eec$<Nw1@c{Sjo>hAl^{DH4&@j*K;QVk@HRWD?)coJ{d;BmI}@jP2H7@9SWGTi
zys+Zv70?4CfaoEQddN#iMv{NGFGVkb+!3dMg~mBHNq&%L*r7>y+vP9RUe&bqeSG<r
zMZPcF=jfsOia)j$pG=A?rIDH4&OHL=sUK@Ub;E7qu!K48)6Glmh_9uLl#eKpN^A~g
z3Q`9ULUUn?lk%bq(U`F1Clc^;NKIg|5lpD%%P@aTR9*#f2<^lZx$c?1zL1D`by^=M
z$#hClP(XJ+wCVQoxCW1zqAqbtTNx`-bwA&{G^e%=jin&2nH+{?+i+S8@-!zvy}u3V
z_=CHcksOKwbrFOf4yjiJvj$bz+;ZAT&6*<Z%IC$PT@0+0#?w1+moB{`3T<KTaD<IJ
zHmsbi$96TIf>UUv5v_n-9U7lV%E>!ZwivBbIx^j%kt}BwCFty5;c8gSi$Wx%-I%2N
zjNZ_RNx68<nIzw!VL^rToHS=`bel`H)vGm+=ZKeVsAQ+kYnh=Wk$=9fw|n99xwr|Z
zmOiJnOHsr5+a`wK&Kd2fQ49#_3-;moo)7`_h7^Gb*Ks!AL6IEI#<bm~^<tvUrq-}X
zuNkWf!Sg4p_^e`H1o7@??#J>(eG}nLi4DugkyhE=@@L3-`>Zk*iYwGZ;Vgpu=kEUT
zY~keRvS)tELcfepO`eD}I-VPDP#;&NoV4*{=nHnI#r3rAyIV+eKNJ*w%#Mwt^~G6P
z(A2;Ef~oRdZWSZn_>?`tqm~r=;djTMD3j62<;h4{E=f|frOqED7@cjaf}CO-uC9Wp
z+r85JUsK(AsS-SwpKKnt7fsxEX{(F~X#ZJO_{-F7wLu+kWO__|d^`GdH^A@Hu1Wps
z;@0vvdu4o+-cLi@8{0W!H2U^4<rrbaI-ZwP5ic5xn;11blWabj$(=XpJ@6viEGgcU
zX~2F-6644ccFf~<GG>*EgY`HkWXHdaWqdnHDzzv6%ZQ%lQ~PlN9s&Ktr}pivJ#|Eh
z$U5xxu0=e8tJGQGKZr>*Jyk`r{UYksRo<+JR~u`C;%tDqS7s-s0smq6rP|uD7++Ya
zJ-Kx#J>xOA)z7>|MDb4|g8b{Ltf)8+PGlW3-Ypv<NOTu>{kld7_F-_3Ei<@D-16>m
zxXP`5By7>@#@~t}o5`l?FeR73GC)ee{NZ_K(rc{27|<P{hkd*XTdndWfIRb^fWg^8
zv1zFCW{L%=tiFy5XV;@THhQ<=hDn;QlDk?&kGf*z))2EcJg|qKbY^ULF!axe$ESY5
zFb}5Qq)w6Fp1A7xMJrJFDtFwYrq@*kW}%EF#8~BS>#LjriBRLv_(^FO+vme=uR3>;
z&S~jdl}$7`E+;2mWKVWP$V(0p!8&?z*)#S-cY9tZc8sN7?J@3Hf~gkO__l&$(9b9x
zby*W{b4sG?&)#<}G;t_z9uV?V#(rfrNm;<EPc?#8{GdHzK@rPZEZUBbI`n)Izb`QQ
zR|#{Wb7(8w;&aUSO8)=_0k!a>Chp(6<0ekE@I&Q6H>v58z>`y(LS>a@>f;{jBjt!g
zUzBd@2?F_H%uGql%eUHl;XkHgtb+p_1KU)rlJynW5g&h<?v}F@9+cYDou}(!f*&tF
zuIDC8PK|#pj!Hoh7w{Sd3wJxP-DPa+XGv%HLUl-075=#{JP8Te#^=IOE!>B-R|~`~
zlP{+?c;Ccszx+CV`0V_ddRI1Q3{9H|uF)5s<T~d$_p5K68lTgTrOz*U7bjTMM;}2{
zlJ+(yu9xB+R}XmVoo($VO))>IHzvo=tYK)sK77i_=*jMN^j%9_t@!yBW0070d$sp-
zBV@?UKN@O+AFvPy<K|o}_3OGacdZ{hwhH>)l9_W&YC%q_?7k%v<zI!(SKRAL*ikg_
z>pF&gmweTF%HG6qJ7{bi*ILe+-h~{-pM9wd&>nF&JU-X{;ymWah&twk@C>%OQ5Xl}
z-W@+U&SRrFHsP6dNFAmK!&H?j@0$;ctDVNnN>?+{EzNtv?Re>hk(PmKG^U#fG64^{
zDVG+%)!`h@hW$cpotTA?n1Sc`(bmuduYS&WE@`%Gr})%@{Q@QI%!2>Q**E>6c<XMi
zl;@G)ug{wAFIhHMwlBzSNBgRGa%KBY_j1(>TSo%&{NW+JuxomGsaYvWX9#Qffor(A
z#TIXMQV9p@k@M9$eDa4L@~M)fnN=XkS0LqT&_h%om#nv_M&HR-3rf>?dsm?%0+O$$
zFEm7l4+_EEmSC1+Rek(6e+V}|A6H~(El_3%CEbkOP|1;T3MpR=RcPp0m84I8G$iNX
zj%vXMxRwxH_xUNKLPa}<N}=6CdG0PDc!kYZd*hX6MkSFwiK<dq^fSu+HMCAUP%c5q
zW{YYH;kGh;Ng9<x7W-%5xQ5v48kx$Hz;g0#=q^{okZRz$_=N|kMJk&)<>d4g@j~0#
z>wHzC&vJ_3_ledTqB9Z}HyAtO`S3bb``5z@f^AuWcE?OI{>SKotFq&gTUBb_lT9hM
zx&(rLp9pL{VHj6xj#esGDcH&b=HG0g;ouKw+{>oDMkAQCqG6c#EN8Wy(_CKRKJcG^
zGpwed1y_$7dRDvCyRDy_&W(d#j_D=9AV40LB=APm0F)2pDzk0mLsKCMM9oKbK-^c^
z%<J;Vsmdj8dDJYPbRc4Aqg_pi|5#7!lQ`}`f9M?uB#k0BHbI7i{$OaO0#AJ{$;5T&
zQN=UktU5HJ#^MB7>nFRAjh+XZ$=%bnJD%RUMT@UQw_}gao!ccbZ3RAYRGUGxL<<dd
zc^D>2YlN`wPKr5;3*qK7GD`6jEKFpym7TaS5+K*ZguvG)pE7a`B6p7IJ;J<c7T@R>
z+>BxT_Z{GWmFLCiG@&o>z|@}HWxG;eu>KyuIP>YP&RotOXTjWv#)UP4sBmEDoZ^SG
z#A~znQyW;nQk8|*tgq+;rp!DTWSXgY)X6^5LLhN|Tl$0Yc!gx*z4x*tP7XPDd%R)c
z^A?4K&9G7ekrh5@yv<>O#mU0+c@s72xR4KlfzK0Hh!;kpk$MV&r)5sNAB_qM-MKA6
zkP}Y_D<TY@xM-O4`;Ow-?LG=05?JzVVy)od^Wf9&Q%zC`2|x2uc6<Fs#R*)C2Cf^;
z!l#ikL_|@lw$&IsK?AQa@U+5$3Lmg3l(*nfl+<6f*9k%EtOn&|X}OLgtiU&fR<;u0
z^G3x;ZWR;?qEWDG<M^Z31m{1!A}V;7iiwj2*T&Xz4|LH6d@n$q?P$ZaDByR9cq~=;
zSyqVd`s{pr+w$TBYvL~D-fq^`{UiH3Q^Ld$$VzvB#XSYv6mrYt&xQSsmpG7eScn<I
zIE-Kv{#Ro9bW4&zGa;Ena+=06qjvtMDe5`Bk<csj)Iv7vtW#dZ$`voT<5RaLAANJf
zRWK|#?%G|M+)PFfq_c!PYp&#G>FNAtW#MP5TT9W(A_)v-M--mcN4urJJKo;ZZ7ad?
z)YB&7{Xi6#m+%l(wy%=sS>xpsT^JEg@7Z~3dw6@OdGXA~RK8nbR1~d47?~k=zPexq
z%gj+9)7{_PT7Opa&+ae1rvM)Z5m6EH!Q<`#iOPq%DM=0QJp!FO>_k>+C<>lfYIRnS
ze3_(R({krfjHAtP5A+Wc2wf3wa!hLpq60i%YJFGS;IwD9CX5t>+|Z)}9aSI4cpt%i
zBZYsTbf)hl6_-%b$k9*KFQmbqn6kq9LjO$bNc&{&`rG7#9{*{^&ExGTW7LAIk|h3E
z-hB)SN@BbtDf7bu@2^*zLp>_HYdH-B$i>BPdRO*$W_z0Ax0mN;_D;=CaL2vt$*yY~
z74S0`Tn3v38XA6B9leVl6;wtKzUn?+-iS!IpHoCnOkx}eEo!so+JHdZm{jpHy^`D>
zuVD=<g()B&z6jY_-#=OYJX4e|4chQ$$W-hKLP>i$T#ay9^Xt_ri;lH7>GvQ)&hxv%
zU2#SP)Yt5n*Cc$Nk4RaK148j`nxBtmOMVFk>E^4nO!^f>o^cT&NzD&3XGpz$^%+qb
za=m>iN}pryIh3>BA+=-%We^<7;a`V3vGn%IA@Gb>Lr5)O&)n<n>qcKOK|OmNT1fzU
zQgH1<@R0M2-#p}!?#~*lV;zWBOc+7w_b57`bSG_{kfb{nI22*}=?>}UW0nxrv`l_*
z3Gz<ZZrmk|L%B65{2(n;+m6&yE#xO=uw6*q%C_t}V)Z4{RyE4Sk7F8R1(|wS&%(QY
zhZQTZe$ZK@XBZt^yZdw^AG!|bT3?MHuYbu?b{^6ZZ2Bbxx)%8dw(Qw8bMV?DWOW>#
zZ~c!Hv=lxv1O}Os&b;PlanJVm3u(j!o$0zK2ZPKEk7Q3eCl0>tP*x4ri5l10MuKQV
zP`dvTxahF?wCcoz&+ZHfBP6{ljc95A&)!zd^Iv=0<=1N&MU%ln(M$|#{TL9E3+aXV
z>6S3^5_I8*<ONE#Ftagb*p+_cGB7`qrxqSMvG`!y3lO1`S89}R7ZV0gWiO&@h|a8s
z6e{-CtY}w~v5}X%rQnu#rVr>h%vdh?u3{34&Unq$%e}x-&^&3pJMuC0($!$AVF7{e
z*qKnhLf-riitM~Gdyl`Zwq1pqNJZtkIgXdL|MCP{Ye849s6G3I25Q4_Q}ND#>2!#<
zHPc|$iVGQg-lMQ*IG6N%bc)XN4PmR!>;mNAAkFA=Gj#{cBr2z}-b1in2`$=%4<Lo4
zB`E|Y(>+!6etL<1=y-reXKg9721`7r&U(eY7PKufaZMbM;TEY}__Rj)Q@mZRE}nVV
zdaGz9axPOr%h5Dv&nM}ek=?qW$OSof-8z(_R)?yE0bC!E{U`0M7m>o(-)kS9;OvwI
zXq_;7{p7fVyL{R=j66X{>VO1EBZYj3c@58*KG|~~vsqitoxXZRC4J(fDdoPrl2$_Q
zbro`HB6;T=sp5AZM42Sn6z9(4uPO%_G)@^kBy-Z<j-J|fo|-lssr!+yP?yHV_3n;t
z4|in#eORl<?zLg%SHGC)APC2FbPA4pFRyJh75hY9_A+IHfsJ@zexXj6@&w^PWmnT6
zpHI+FE$dT)th~b^GPCyUJq8k`%Wt0yI)C>Q)YbEs%N4{U2tF&^UzwRmV=Z53e?D7G
zFe~)R>ra*)O7StzaOAST{@jUuJ7rXm8xE=Pd-{E&n_5K>;fcZ}0cE(#WtDOL+FFY6
zASpQZH0_L8>dsJ@Fm|pNT7=M{0n<m0ebS+@#;8PF;h`|vhGr!-xU}{k?n^`yn%60o
zn&Ku;#_ZoHaz(He+Sl@S$)7mQaKHvrI2h0~aG`*^cD~m3Exp)Lk5!NfhXm3>ex#v8
zAP$J`BayTQp6k`u34=Aj+D}=Lo+sDy>A{-8vM}MAK`f)0I`vFWpp4k*Q0CHA0mpus
zUisRbI#;Z<ADQOdSjF(XH!A^(61^OJ-mrD-Xcw9Al`Br_iuDEQ?Z~}I2S#pjI_Svl
zX0k@Ta5&k#Bx+h{Lvdl&EGX$oUEtLdEfR$_(w$x`>szdbiIbj&1i$x@LwOek*Q^mI
z5LP93h*%{T9zyxL@<GS-@=S^zsXyHF02m=OGbCTbG=H0Dv!$1jDo^QnnzU1lU!`|3
z^pq8UmK<AjRl_|Js@?7xqq=uCx#%iUi8X#H8*+)pcroE5xcnIwqC&0`)bOZ~yx!>2
zhR-aeq!n@BK-%OdEci)7D2Gks^;p2YE4sf_dtQ0nZ$%PFm#baaoj(-JUbc!@-z;E)
z{JhX_NTa6A%wpSfzq7`{jdZ4#i+igaak#)ogRY{yPR<y$5Ux<nxfh`qp*-g$Cr^um
zB>u$L@ryODa~t<%uZ63l;eo;(P2(?@2Lk7x+ZCv&WZJ(qEV~tPe@;9~G~6yHB$OCC
z<3)Bi^?Qzd{bszg(9rnUMX;H~<lCtUo5!e`c3g3%5tCD545taYXEA4`gz$QX^O#$&
zNAH@eS}#k0T+pT07xY)i?T9U2Zjnh;Y0Tdk5ngVK_jn9BoWm|n__UYQ9c~lbiknng
zlKpN*Z<lxGC7!OgT+raJvlXR3-f27#<nXV*{O&o$C(oXG{h%h{IOVNDlG6;@9bS`{
zaj1s}#K}|3$;;H|1EQv?<mSg5L90J!wL`2WIfK^ga@)QtlRX)2y#qPy+zv1Zvsu~o
z^l1!;=^b6z-R<GLP~bX3k~iFvA=)><Oi7g5G}6Fp!ntiER)nJ!aG%YQA?%<pm})Hg
z_$006Nt}qS4^f$0rhCW>6)V^dp~XrwRjcz=#{K2+EVh=~d#~yna=U2aWxbxe%**Or
zHy?WI&^H;mztZfyX5VjDG4+;2JHNE{I-B#pwsaYsDFT^QzZdsj&-nAN&J?v?TQR9*
zUB%=mk=6;yFV;qnGKK{X&UitGa3r4CSm_O;7ePI#r(Wy3hfhCMQBUPVAYV|{P)!C2
zk0Y4}DRKv{qyx^{!Nl}SOS!cMC&tkcv3sbyDdQ)N&{MVxw=;`n(*ZQ4*hg0IzAcHx
z4QAz-<brZ%p0z_)8)aEKop(?5ENn6woUgO6>PWf2p1OMpt{SafWTk%K5o}T+_VZFA
zrQIJWYcP&`dhfJkCQFA4Ud$_Io9>;0&6F46c^iKbwU=F(?`Rk+&C>qv1=)mB=+B<s
zXCZL#Bb!r$@(JlIg296&f#=^dr}zW(^f$PTL#7&g_a&biH?>Ae2FM5o7~}VQy~~cj
za>rd3WphtCiP00_Iq2uxUY?eFZ#2U#eO_0(&Vlr@wD1?LS%>6+^mScn)loM?zgKZ*
zm|!Pw5k-QvTlG2j&g7saIh*<p@42|j;OHc0Vbem3x{mjkS86-!J3;w*R3rrn16MZB
z-=#{rZ<zBA6u-p}Fih@TsFQo(RXIT|{-fQL;;UY1@DVR{|FZqkrsJque^O;wXxOMx
zf6`v3eQ}G?cl8kKl!9AxSfoIw!mT-sD&CupD^+K&(;DYwE@6gdzl@TRWAUfg<3sm{
zDUxH=VVtcovF9Y5zXtbUTU3?5ufDiWs<z21+kbv_#Y%=dA3$SK-x7zJ3&qpT^-3py
zZUYNNyNZ%3u8%C_rfqx2--{o%++`zwcYe^9)>HlxBN?-aa%%w5F7G*ppahm@%R#*K
z07=d`{}@lgkE_z0hcX<iA59fy;}#|6_yd>wnM~^)lmzb^E=MX%7~vT%+lOB<v|oI6
zd~U#JD!A*xLkAmo;_gQFyyDa$eIMjxH8v#b$-N)iCYKXJ(nG>p9lJCC`BP+D+yd5-
zvPx)9Z>7aq^_Mc4>R77O(0q1;wF{f2msyu!_v><J@#U+_DEi}vUIM_@Gw)Rj{frai
z{`3p7yuoA7!+VLX0hUJ5Eyf2QwD!8wTtg*Kyb_pODK-LVq(ddezhbGj?<R3=#p;MX
zR*PtDNhMg+_<z~j<A)0-4t#VtV?ww>-uFAa&yt<37h1zc{qKi|sSXK2W@GHjwwj-y
z^2YV);_U3>%jFRsKO$e0;9@xU!}9D;RC)2kmR_-1Q-RqFCB1~G*$>}A+x=kt0E=i`
z)K=ITAuvdo5*f$AeW{>mE4sn~EXXD9aW2feM?DxK3Jj{ETX58ht9K0L4V(sZ!Oe$(
zLEpZdb-x%PInzcHW)GNuSoDjF7(X>kQjWYaof!vTMbJ)w0hpu$LFMiTTlc-w`77eL
zaqu0RMzgBkk?R^f%y`VXpikBAd<Wt)o%=j~{|%fmPdz=)NnqIVoA6m;1=|a2<Ez9a
z<N~7sVrf33bNioaIc3KTUllLDO)fV5o?Og)Q2Sn>RG{6k*}Y|pRVyw0o|`<xA5)V)
zzquE!#cE&=p)h^>uw|IWMEih26Egu*gTDtwW2x7)WM;b(EOGiG)+@*e@CR_KGG}=P
zam^ruT-yT`<_{7~J}yq>N<CdrIFRG2L+zg^innt=G`i-{cKyi#gKIQ2I(_~x1~Hh!
zd)w71<`^5<mqueqF05<WnF5P)-`DsU@Emssb4|MHn=0IfzuKvC(RqJUimVB_+>)&*
zYF<~bFH2D7sy$m^c^oix@^;L)nr!-gf^mmBN+GfNfZ+UESBxpQT(tF-t{7{*;9JCt
z2Ye@(bDrCna}{TzE|cWn<rgrW7p_wfn@HfJ^ytkUanL(PqzN!xt}=3|<Ie*OV{S(b
zAG<rGV~awPPFN{5roG|XZ*v5Q9bV!4gnoh=17HzJ$HWy<Wsz2XJ_B}m<}`{#R8Z*7
zZ3$ouSo0N?JPMRKY)q$c7tcPM?F~<6$+J(kf+HP+PosDYi~*8rP-8%-g%h|I4O|C|
z0V_X^5P3>(jRD{lhV+H7U~f1s)EK~1db>^nbykCNa<|5S+sc43Ak+eC4B#mZqUp8o
z{L2_XI`-Qb;P49mZ^nS$@U9zU0O?r7`p^D-)?qIkNPeeRR%-v~^x1JpYpcb6yYP_9
zU&~)*enRNt*QaK?rUY+@On(9f0_hFH9D9^D&nGy}qo?`N_W=UL1Q9ZbRu1cx_T>ZG
z0Uj9dnRFIhcN5aQ?8&0iz4rIy1)gn+BiG}?LZ<S1R7SV?H)^II*UoI$)O8fOBU>up
z&Z>Q~_T!e)-fV0N^q)oMOodnYVZlL49yNc{Dq_uqRaJ6IwqAIGo43<+{bmX6@Qh6-
zl204W`?8rQK>OsS&Zq7%svfEDFV^sHrfc;h_|E8+GoJ&_=MS-K$0)wrpUk5NOi7p=
zuM<r$TujuTL^W;k*LaaQL44+g>fv&$uYKu!D)xn(ADJ&Zf3j~`N(_8cv9BAmwvw$M
zBFwU}tHV*Z>{_@Sy%R8A;ZR-zOtfNMw11jt>DV~_Fwq8Z5}D(aGq}YTB6cAbrWnK1
z+pm<5ZaYupDz!xKMc%a2gAH$tu{DRIX}_r-n4Kt+7Au$iUe|K2{aEohFRqTsPmejg
zF5X!pVV^!9;zIY)#5ljIIZ0wl&Qfb0=+Bky9!qxxYkKg{rUN*p_@25*P9~!5k2J-@
z^D8$P5F{RGb=lJQIgsW86QaWKhxzZQHAVbxmS;%ln_x|<{Rx;5jkha{g0Q}UHLb%;
zd<g2mm+n6M74&BDuT6PYaP>pZ-8Fw%5RDE0Zb3Am8uZX&!i2>Io!_wCWFw!dyBX^Y
zEyEgEP}^eRFG->!|F$5eRdPTeK9n}*z_^6Lh5!LS3b5lay~zo$oxWifR@T&7pEGW@
zq_0>Ft;(rBb1RCM71X7X&tb0BS5PM_l@;=P!CrY>?`ovYQy03eokZe14!f@U!BcQr
z-n;sRul`ZPf>TV^eMsFqJ{sSbaPny4wXEimh|l{TlU4|K&?j1X_mVTsz^Y)<T@JnL
z@F@wgpPk*&4X|u}G{;A@@1Cq!aR;*U(T5fXu~)i}c<NAzi4KyBf|1>sEr#tRFtW7n
zDN=GkRC8x2FV$VLky=BivkJK>b|L<n`{Im+Z>?j8?AY)m)}xx}`b(n%@>zs3)k;SX
zbOlp_eZHs&4oF@GbkE(`XN2I^DDq+hAK$}4J&XpXnU0fXMn!G-&q9v4AH<X#qoGEI
zrJt|J(CAR}3w$UQwBadVuhHE{R#As}npT4nr<8aax<;ql-c^;hMyK!#zJ^uxmnW-(
zhi20jR^V4%Je5iCKztBODlVeRkAl>tSG<EAupNsTf?uC7Je@1PW5O;CDKvuU_aZ<b
zHIb^}(@ZO_d--DrV&*Tf2He!PzgwLI7+bjG9e9~Gc;|er)j@7ms)!fS;H_;vr(F_)
zy>&&bfA=u_^FjZwz6guYvgL5@%EjrA73xWo%e>{4>MEO4W3h&g68_%LMwDmkRfh7Y
zI6=VA-<}H<r*=dYrvszv_HM=v7j@FMWTqJemC&~A_Egy|vH0P(c~`bH$2;HndU;@!
zX)w|pGdRIJhz9k2|A%vz+sXBo@x$DYnl<*gE>4Io=_>a3Wr9?@-rwuaWS$wBk_q0+
zr71gaUtD)uxGo~Jg-OKBzAk4z*u>vjU#cz%9{-LR&$7pPonbzuv#|Yr|FqTyXU7>#
z@P|$s(EW)zXKeEuFSPA%49tm=b%uM#%&G<}Br$m{v$O~hp_n{unMrlL4i)sJ?fKMe
z3^OJl_(5GE?5Ac-Y`dZ+E9lS<3cfH;h0qZwVb}>izzyntiyH5A&TaIe<y^R9#styI
zYt#~)d_}HAn}z^u^qL3_+J?Z}7*Koz@?lxW`x?cJ2^&=4Lr@L_@!8594L^BP>FDgC
zd9Z8e@fAN9ZpMdW)Wf{D-9mgJ5ufo*_^Nd7)K8_4@_wES6@-QXiDSO-U5JxaxI1Nt
zF69MiZqIbdrVgVNREg5^*&t>@ypS4Y)?SPgVb#^W*ZKW!ky@%mJp(Y`@*jUj`&5(P
z&zin&W=Fi+Q(@}J@vE<quV%Tg;NT+a$QpP9<Q+Jk$rxvW2WtLr50pnY3O@{!-#o<a
zj$3AJ3M60g4qmPVa)eaA1ovl2qaKp@PG4a|VfJSq;PMsUP%4CAQ@%Ef0*`+toHF!7
zxJn52V^2sqD_GCJ)k&H#>N$dyGG1%@vfFySk7P`=R?d3+_boZ+Paz#1nbe}?s{QWK
z1bLc!f+n@k_H^07D(}ayOeCEVt_s1CD^`r!ow{Lx`OmfY#xIF6YMK0py_x|l{OZ~O
zqxP_O3#{%@i)Y5ENu1`M*jpwyZPoQ|ZF6sU0RzA>iPLs~QwN)(@#+0?ckgb7cudjS
zA#UDaKjFhhhEIF1wV%61enmC+VvDz=<hhJpucXQuBqP7RW}0tUxaK~+x@MVY-oAF%
zKlf&y*JiyQX*<52_;r3gRaIjgFk{A<z^68c-RJTs0!E6cO@tj`rCW^Mh^5eYLLEJ~
z#peZ+PV}M<k+tHX)*Tgo#QXkgo`0?Oofo=(?sWh1@k9Bf)mh1r;CGq&z4*FJn6<=l
ziDYhIXMMFSIY*XN%CqtdE*g<_{Z)RSfX4;b>hY%9d09_{7qjTEfN+BUpBInD@(+O?
zK&J()8`s~bPA=R(T0jdt_26r0t&F1BV=Y&r5N>pI=RAxw$_4K8mxc57J0{LOdT|8q
z-7hF!7RNboc<{M8{5-ICaeA;BV3Ght003uGw)|euY%Wujv1{LJYctB^D7mbB=5ei+
z?=02Cvy_Zs8TPt^na4rq+Zzvoj^N^?>FWYd#%XqJZ7OV!tZYl)$<+1+zT#7pe-R55
z1Dnd@x#vSkM*&SD7kuLeIur3;RA0HCtiK}Lc0}1Nn-ZXXs3u1|haPEIKEoX@kjiRZ
z+*BE{RPO2E@q;6BDats-ot@)ey_v_pmZMj{yi{`Pfu6sJU|wj{DQ(+@a^vYmgt1rV
zH_VX>iFopsvVDs4!oltLE@Xzw0@Ea#FSqO`KPY!#20pj7aT^vi78u&x;EQRv4jxOK
zRXKTpl32{V1WUIyA!g5YphRu4m((9LnIOU-mkR7O<*&F4t7-Mog!f-p$&;g>$*eE-
zo-)bI3wYj-4P4wY_<xvt3$Q4=wQYDnLP0>fK?x}ZC8a?H1d)&w6$GS9q`O5*R6?4O
z?(S4lq`N^ta_E#8_|^c{ejfL;_xFGQd%PYVa}P7?UiS>Fd#&p_&+|GLL8qQ{tOsYS
zdD>`DX1wGgW_Hw2!n>qi9*^J{+TYaztSvoLA<^w(d*zH98-1DqYYFhWjd}fD%gGgk
zLhas}Zm+g@43gLo1A%z=8<+W`xt|MIw0u>s@vF^~xvc$4Vn9}&H|FMW-u&!X8~e0+
zs3TumA4$qaZMXxV@xjAR?K=m+;1`Yf0S2_W^5uS0DB@>Tz@c6i2*}**l{KcKE($M~
zj_JJhyoujqhL>t$-=KjaFo!zs3NIDmnz$lUqs3&2hBI!asw5S8_p2S-jQg*)UK<$M
zo}JbvG!TwDeXtXD)Fyl&ESBm0l@h^!_4A2YIX^#g)DotDAe{2WF)v{4Dg2uKW{2zm
zJ+<VB$!>$KYI2zLbRQE@p>xi2*wSJT(d~d9?8{kQ=M_}_iu2EaxXR*7ABc3LK{5#;
zM9+kX_&}t?vz>X5G<fu|1vq?C*1wJjU&%)~j=><oLBB=BO&5Pe#QKf=S2xO2oz6j~
zN6?d|@~);gmoW!;BBo@f3KA8hMLi1xSp(?0ScYe(T%^44@Sq^8*0?a^_1XB&Rn2rU
zrRNbJ2Tat)pj?}kV*_NUnSNtBFwqUs^w|fZ%@llBxA#Z66$Lh2a%ZCo`Kv~$cRW3F
zPC;ingKwE{Dg&d~hdVnQjBhOOP!R^PCPi^Fl9o?23bQ=Y;6(RE=Qn2IJ~!JLW=5a?
zrh0K!=gB?vldn`vIj72s&KK&p+GFDWYMMr1>pfJv6k>U$K8sw1k{P_|z9)B6r13uT
zoT@JpW%DD~SJQZ>EpD_b#**-bsyt1TJx|%p!rsg9;?;DpWb~*dEjSNCd3S;ei7ym6
zsteQdO8yzj=BMDi50@)N8rk_fa$5qr;~Mn95o=Br18_!($DC1a#W80D`UJ#i<MUI_
z=(w|UI#=gZb!URrK`$?n1xt;8j1AC<R1!iy0zT$zX>EbEjVA7fpe=C4mM7717dmpU
zl)lm#EeXwC{4F7Qa7T+E7|qwigAtPQ<m^w{aOZO6g#7?V*N{74jvipTSU<X3aDa`7
zuro+{H2Sc9W$9@a+2Tq_ZtJ+YFW((5bh7xmOCoK6S&ynD9{EeC{YbL}gxZ8{Z-0{Y
zu!h!O*rS1KrVXeY*W}C@SyPa=C|eW?lessdC*w>>A_4jImL%xHX`n5KJ!M)TU1iRw
zR_d%)81uOo<l*UJh7Hndw)g&=iI=b2_YEyJg$%8X9H93^DSv2ZHN|uG-@M|XWOKol
z8UNjancSdrkvZ!73eom+;*Tx#)n=`2BK)?Os!Y(rI2Ibn0*cMO!H9Y00dAB#)85s4
zu_MFZ)@X|^-TA7mv=;{%d43#kddM?D<f0gI9B`#SE{j3;m+P&RcHhQ2HPtMVwqz?!
z@bc&<BknrT)3BTM-g9Vl)mhn0IsIg|8igQ&p?ORZ{>O`D=Dk8*)_XK5lFTRt-Sn>3
zWh5Ok?Wmv;(n$;dZs`c{QZ-G`Wwe6s>`w_kNK2bc_$J<#w4f1W$r6map?So(E9lNY
zv$XjXTm~`j_yzevM<?S>rX5Q^8E}=La|BljIs-ZQ(ERbZ<99k4cPE|sILU*v5L_j{
z6D}%Q!(an5P)Rj{2WWImh_p80+6L(5Vt9k?<ZO_MKLZSXXg>TSpV%d6wEFX<&EIB>
zNfZQCC5H&P9%x3oey;5kI%5wB;ehhvhvYlyU8o9Ui@sSz8G1G)%IyL4ISAn|`WUqu
zjnK_u7+=fWOyI_6l3bVvAIF1TKY2XTF&H+{;?914f}v6}|9oTN-V~KC!G~)A&@$%y
z8$iq8veuKpmKff*;}<YYuM!Y*`iA`+q^L`|NhN0;(^sObTHlY?%iXeIWbF%xG+*1b
z{kn-uK?ZOuj_uu&Csb(6*!8Fex5xe^9b|L%mPtCLI45)Uu3oP_xA{Vm@MJQ?j3Ih_
zOXbTecbJ@pqcx4R$ucjNU~8HfOnB0&mt_K{aA-@T0+DGe(fr7?4Zr=f7%D|o5bjP_
z%nxv~)|aO^S^OdQfec5CQvQ4ZJr&7YU-&Uhws_h3N#6&}Q@x5A-KI~K@H4dS503K$
z^aDsz^;_%X;uROeoL=6?#>TN8P&URxWD$Dwt%{d<4w~AV`%GH6D*{T7UIpsz_|F^N
zjMGW(oK(n2l@y=BXfz6$k+7MdyvY1`_y$4c8EFR>`*tpcEcb3>f`!k2Bsjl1D0BC0
z&n#ZkJeiBXgytG%aIgqC8V0A&<RULU&x&X~#q;O60txpdtrA*f<+%dy#+`Zp1>7Xc
z%0Mc2<0brthn7(6+n#62&qhlOZ?J5541K<-m{qiHC%j`VMW9@3cj0SR(_MnCJEitq
zsoq`$+J@hymefoNd7~>iT#E!bq_8v2TU$0A=uz598n}J8+fr~C7n2#CK8V}aJ|#`<
zcq_EA&1cMF;M>dpwRiiC+?Te5CE6u#g<**yoaCaw3TmMxk_W;%-IoY}9)-^nAjk$i
zpZ1ufy*t{RDpE^@px@vOkwVbhfpSz%A_$G7)SfHd+1Su4$@b!6{+INHF6_+5i^dvM
zQeeC7gP7-2q89G~L0rDj<ANT}##C$BqF0x5*&glK2dPIWkDtG9|7w-0-ohY^Q-d#+
z`gPt$={1Ew6>A~l`IWeq_J`hF4ME%Z?aA?81wPfuf^kZbvc!CW%ugJZlh*t(Cc_pj
zhd!;fTn}=<RleQ!7kr%99BUuQ9zo=B`T!!2QeyD!KzI`?3nHBogevlZu-CMDmq|_c
zfRqNjZe~q0vh--{KNCc*F^HG;-D2+0YX5=cArz7Su^94oMa4g8Ara{KooSFj3Rf1d
zO-UHvdi|*}h?$nr46wK+K<LF!4M3NAJLdwcnj$Im9R)}SHY9~qAN}AW+gTC8EH}zd
zhXJcf73=D8D~ETFcks#->_yF=T|kBS2wrOyMLp3L;%ucD&0%Du+goo<id|#(qMl^F
zSgF42UPUP6jC!z0ZU6217?`8TCsb#N#Wy9*`k<v4x?%c8WCX<O9ac-7M%@zn`Z)Ed
zqoj<iXm3j7J1F<YB3+(Rol84kj~Z}EcgkH6BOKjb>Xtb!j6<W*YyRPENj!kA>dSB&
z#lAdrn$0l6hO@qaMj#rHwKdewPQB@tc%~1|W}0qm{Jx-44N!h%EBIwWUDG8MDDMu5
zG|$CrK<(p$P+ir7qRa7XU<Z@~^(RA`tc*0*=W(y-Re;zDo+5U;-BM&ad5R;D6!v|2
zwBpXrEjJt;>Yo5=w||k@jtR$y76qOh?u7{3O!z_CrI_@a>8Ue|&zJz33jUSoTv=v-
zx;ZTw8drlmJ>MXfY&s1oL!>z}9WCd(9+_SCgt=2t#QO4fj)t+s^iko9-rXPK>|{Ew
z0K!K+SrHAN51@TH7edmx9LLz6#)@ik1)z&AlNH|XUb>r>xhh{t*7{qf<YX*%#=5$;
z&r;!oZpOQv-u`h>HnUgZ&SI*xH{#V}a$@5)*U1pcP{PfJyDh`8oXi9!<)c6qnE1^%
zd_jEy1=KQ`<lvrA;{p2M0!2U<-Fqi{;FveR?z7*NG)MzWzV=v%e`hUe#@=pnC)U{B
z4o~o=-R8RDNU;y|{PY_Ud$qhM<z%AkFQB_3BguhiPDxwOZ=j4%og_85p=@#OVM5>Z
zBc>F~86HXm4G^nqS4gtmOE*Jf5|pqFoGj&(j$n)K!MQWI`zS26k%d3jZ_`G8W;U~y
zY)W$9XSN$~@9cKIvR0&N+_9{dR7xMdWk^qv64qTGoG*AY6|Q}GhbH4f6oR!%PN9%}
zZ!)-PVWtOG|H+7DKzbcZpZ^>EvqfVfMu2^*g+R?tw?8kHrts|t&jpw#15)n4nyoXh
zKA=&{eJj9ySjX6Je+PBw>(96W1P|a>*ub3U?5l>;#IKAiOr2%ryKwOJaJSA`D$iN&
z<B673b93%J_1lN<N`}`1)^cR7hkwpgxMB!@GTk>kn0oakSt_OUqeRlA9B~JQoDB*H
z<O9|u*>+)_Q-Fw>z6$Jv<)b1UD@2%~c$m0G{X+?u%ludfV#=!z;;_*N=NeH8VR0M{
z2)2l&U&QB<QjK>eQRapzns%{)okw5Cj=lEZgWS;Yp;3K#+bOw%xc!0%eyq}d>C!^n
ze5Lo6)0c)(6vLFX9abXs`VzZg-^S{j%##Ik)KNPU?z}LR{t07DvvAYa@&}zE>RBue
z%hrQ;Ys}~==gLfkm~2itI^Q^4ayOH1Cs;k6Tw-_9pbhV-3C2ea3!A2<=eBOm$U_&t
zlM|*WKQxS-rse!}ge+-ps&{a2%dyko=8I?OHxwzif1LP;J?wk0#*T9)<X$fK8P_uN
z$`9o`IWYU|MdxbRHf#AZeZj{q_sK68F<b>_r43zhN-|Gaibh{u0Ep>V?JnxkwtelN
zwBzmzagCg-%JPI?@o&W>1GY!y!prAco2E{LKs_ndSk>cL)yiNxDHD1Tmi5Mt*cxB>
z8f@jel6+qHE0$}7HC7s=XBpt9Ia!8{o$Xb@iFiB9tKCq-2TdCfV%iziQaN^Tny;Kp
zACT#U(3~A@>-Isz8-cW93k2r$Qws5qLTo~qMmd;Q(l&yeZ-RJ1WlU*~!3=dzi)AJB
zc7Vu7KxVB1>U-Jz!oE3Ly`vC)DqRK$AC&NvXV3|qy;2@|jUVGKj2UlNFMfJV8VXhV
zX3S!jrb22LX7fmbbA0ppj>VVKR09{XoPElow-LzP+974xRfpKjRu(OrEH$4iNR<{m
z;RK2I`_Gz%U7;oPZO|K2_co!wmz(BLfx(d{wd0Sdw}`^v0Jj&RE?}FP!a!^gNrn(j
zE7aoe1l?m2>yy<qw6$KIy4R|-P`4sHsJK99@424RlM2{%rTeM057rBw?mA4U{9ZzF
zOIPrOP^aSEq1p4F_Xtell__+{v*PrD>&S|Q8F$_7UWgQxYR}CUnUB#w<<l)Rlc=))
zQb8dh#(?i4>(KdcW{>8`zs?@u>s9>U1Pl20z1S=M2@P@43N{i<Ko(p5ne75N#7@|b
zWwh}>nLY4$|7rGkX14CBJDMWV-nC59aGB}ejV$`ILMlc7*qh4!s%~|^@kyhm1jHUG
zG?pEdVYTm<;%hS70Qdbkc(CM}6O2O88!+K@R!?B!Umi}R<Qy-}WMFB|H3hoI_D0&|
zz%LynzJ97(&$z!6;amzUPh!%3CBlPf!o24I_n~@j%6<J|#t;icF<iAY-TZ0wcJ!MU
z#rMeWZbv;Kctv*)HnJ?UfnPOR+zOdGI|@~+t6rVzlT&<rR*v;@^hA47TZ&ZVbp-j-
zTQnF_JPUi!zR;wB-`<pMY?wPOJzDOwb(3B|u>_>T>Q#be-s~n>La;mNZ*G24^{YnQ
zZWb8`3AOM+@6qB<oo3en&}n)As;h&NEMzRew}}&5j8H9kA%n9*m1BBaaqLcmLDL`O
z{cA2LuF;Y0an)tG<7ROWWm;dVnDvLI#2`n%zd#!Hs<|kG)rO!Y0(K5VEAE+KYUG+k
zx*;MS;cKH$(jK*$Nc`sZz{MM@Qe$XkoQWE%KLFMk{JRV~H%^g_5gR)Wa`EG{B;J&Z
zC$hzUB|*a7!FO3Bk47!^X7so_)lz;dNRcdE9MsE5pE&R?G};6c3ZY>yQ+sk`>i791
z1u>r_ZfmjhgeDkPvwJy+(*r#8hjfTZvi>n@e?a<V7Q1kYC(G?==82dc3$x_gnuInW
zAi+qxEzh5yt|Dst+ic>HZ}4H+X24e)W5B<6q-t-EKc%$wdUy6&mH}Nw3;b<`;E0FE
zsvbqgqZm5}%Ayd?`n2vf=G;3h?H0`1clIX~wEzH_T1T_uEjxd!Pj*mos;-?O(l81H
z=e{(cT1g=wA5?7_X3bo7K59yuxt#n=1CNX6IQ1|zr5le1sRy(FzoZ_#>nEv)-P3lz
zIgTV8p@^9qy)xl7mB+}cwnoVM!Ci)}GxtHFp}Vm5xowsP{y2Eo4wlnk+vPmDYgy35
zzP3}al3=(oe{)tI)xZ5SXN<fkMNqU1Id2TF?sK-9y+TqDFgW{uULzO^y$3S1P^KN4
zOo8_AaO!`9sq&*KF{T)OFTT1nH~fyFF`j1ZCG)hc48=|}TO1)vllGLX|MN_5MQBvC
zNe0c5x5eqh3WJ&0H-PQJF4;9QPtMjB%E(8@jtIvN$V&F%09Dj+O@Tj^;N~r@FL*W&
ztFBY^F<n+Dwel6qq|O+z=jSg(m8UKA@JZ*aB@lWV>FT?2pbzsj3BmRyhPYZoL|R4o
zzvy|HAT!H`GN(a5i>QzRdP8N;R)2@G__g5sY2>o5Cq(+ufXlq2<zW&>Kgi6kLSBZv
zc%{}6UKV@E?i5|=OkmP~B$zoP7|(H?$)*@8;D#fLB<wI~Aw>B)y`7J&M7*}&Aqb+1
z6PSEOf`mG9Q~j0ER-<5xp~yhLr<{1yzmVbk=j!V@$=R=Y-x~IQ@e0gb9br1ZNW62a
zo{aum_yf1yNN>vBjwIy<0da!1-M=WjD<ISx-$A+z60XV5x_Ub$FNZEc>!Je1Ye7t<
zG-UWarov&!{Cfe8Te4zPu<Y!91QzXmwzPVqGA0fO9_Ea`8w5&QG0gVe4gl@jLe&ik
z`8P4vgV@c64r#q!WBWLh$grXn8_ni}U*?S!q`4tD&CC86qC`UE&-G8|&1uzrT8dO!
ze?~_{{casjg3e{i2QtBfA+$V%z1fm#7Bz==dHa|~NO&G+E6c4d*DaFJTVy|qq;}~X
z-;05j&U`Q(G7I&Z*4@+;pS5DpB*Z4>$!^}%2oRRf=z*;z=NijD{{|Dzv>5PO*-Gx^
zE&n?D4Aej*BWfJZjl*OSB96k2<?kAf?nodm_w3wF*61Iwo*3UwmgQX>i-$D=sDu%F
zu@^97AhoUjk=m-jOprRrHya=XJPeB0X=Oh1;R)<;lx?&QPFy~FoO^w^N;@yvy~vTT
zq#gYLX9-Mm7?(D8l9XU7i5KEdg@IWY;yPs0Xmy-@@1JGzF^q7BH6-2!Z~hFO<OSpb
z$U-0+yz7SNb0I{5hWA+PSVJI-CVHv&x}O^A13}bxnq%gaosQkjqwQ|9Nm(8VNaf?2
zEJ7?#IF!2&7ho&UB*Dh-b*rSk1zsR>N*YB(PVw+IpUvH<@3Wo92D2uHMxnn{7zmp}
zt|h{sF>8L_pHNT>-csQ1H3cYl($LjqhRC@1jMy5*@}-f+$cS_Uzj2qmRD-*lXQ$=6
zmCeU5rzIr8>l}4J{b}mD?(f0VU+Pc4#Q&^6Ri)Sc@1T|dIDlHD?EeV0oMXdo<_kYg
zl*FcOF-)41Ky`3)u)~A(`4ly6Xd8~+ve*#fVGKuO8H9rf9pY>dkR&cMJVgAg3Cc$z
zS2>HiRD^Tw90zojjqSv7n&?-~N6gxKt|T8%t1t7u+A7wO%O_H_`%F3SiWO+l+ZiAD
z$Y=fkO(%UwvH<+NBSH)Jy)0ow776g{P+chHszPik=IHN$is91}K;=V>#pMuhl;V(+
zk|h>UW@YEw$A+Xs-{+EjHIo-}(`&&GOS)0#q4GOenNgTUC!w7D_+E0gw1!@`!CQN!
zw|%`Jl5xC-VY@~{5?<5pp!6aBvi0M&RW*;rF**o$&6JDg?X}zo9(aObnsGO%>cf5&
zI^r7f^#zC~9FkaS3}r1v(zZ+3%ROXd)nB|$PMl;G9Y5Pa?(1jU@Q4R_e1Tu@vBjLt
z^_~t;P}uc6I`EgE&Q_hDoVcY{r2c)$MXVV{R^y|PB^&fwByr+0fEyPk|Eu1SNB7C|
zv}3)aKPF+jg+@nQ*ef$XYreHL^=o*JXS(v==XRAbZ_UICCRPGbVsOA*_bcJKh+Mow
zxpJ8$a-dZaQ@o8#KjX+rCS+Wg;{1ezr2JkpdBKaSe)5O$P^->zV?li({Vf3&{qS4K
z_0HA9;^w~f`S8Vq4dqv}<{ZM~j>-=3{*!r9+o$T=X;ov#G)~JN|98koK_{ak2ypO6
zeh%cq&UM@<K8_iNPf<TyO)lAoaS1HFQk#pSBx5<AUm(T)O4@>51~P9b*oC-0D+MY?
zw>g%DpQ1YUf@)sQ>wP+GMN}q|hMO$i`FcH-O25Ik{YqeFS%5Kbc$5_b_;z{e6u#B4
z0r2fRDbCTVgmrZ4-gIJt-;~pdlEKD1{Kih#QH>jhOhBbPWx?=F*u0A8mLZ2>@wt5_
zsq#$Rv1<>+nJt~$D=M*vr6RNn=WMN160Bx;t*!z2??M&`rg|O&^f4KB36^Y3W)5z<
zd$ckmvfS_s0OT~NLnxuS`c3hxkDhj$26gAN`B+E#?sLo2FLC3+WbTG`Q>Ff{bN2pb
zJCcm^^?t4Z&8*laX}8$jdlpfK$<pm(r@5Gv-eF?U9ugCOEGEa6?O&A5_T$?cmu1&d
zO>g~?pZ4rE<e0GqS!c);Q^D0pARM@&uq>vg7sIgwqMYv!E8c870GI-3EtoAqIr|P`
zK7l3YjNC1|XG`{QK0S6oK**S52R*IhZofbyt)p;j*wh=jd^XuXiJDVI82E=(!9+EC
z`Y<LtwzrZS8`pPh{gqN(ySGtv9G`Hhi%@Rt+YD;OXF`Jwwt3DZg7$OX3Dxw=MUL76
z84A)#&tU|9YQn0eTh`Wwm~rBU==drIFPJ)hC^Z%PE6oMiCA2BineHzQ#^Cz{kzPUD
z(sDstB?4v?8I>PZ^_#W?L(i4>SatWul1`S1{!#sSi77cng(qnYB9efZFs)QD5r6mS
z&%!$q44M_xPW+;{&nvEPafP3l)CE2qocYXqLtsGjVXowjz=jI(HmNR6h`!ipiL?L6
z?^9b^$ak#x7W)sZ7}TME>Aa6(FBi40N+_5+EU%2EkP?KaNa@|Mw4s9Isv7j{q;8lX
zwNb!@LRP`sknZ%xqD&EIMNfO<x2h=VZupf(pf?OkRtiz1MKIL84B$<7L+P6$T=$Vv
z#C?%^KRt3a{EBzl0x;BABx!E|LydO6_Y(`d(wP^AUxOu;hAnBqd63>afGJFSgJ233
zY4gwYetHVdLokJ0?EG>8Ck!<>Vx@=!hT1Rz!4%2`95d92J^@3`b;?kmbmk*C3tA(X
zLayhys0$`P5kDwd_$gCpnD8r8nD*v`DI|OFy!Vqs5CbPnT+lw$y73yfq*$AI=3xnX
z{f(3A@Z2)!uk*I3)m28;B&nb?4o|mR-W+(`d}ajno)Ne5%{BM>c<r$(-<P~Jy5Ae{
zp}0m~^H`M5#pyk%HCjUYizb~MaL}iGo|0{ahh5rsk8YL1qaG~nph+4TUnqCwDWAt!
zU7uEoEE3|AXi9d}W_8%8U7lOsDio*Ip_(^~690_O;FvFtT}AN4BocGtgs@bFSJTHu
zujcftY8f*exHqEMSSqgXu;n(D<#Jywb>2$%sy^TALwJhrO{YRb*G0u6!U`Ygv=~tI
z)`X=eQi4)65e4Oe%NIka4;NhQe(3udrijkpcU?X%O4FmK!0*ZGCOw8Q`44^y-o3m3
zQSdIxQCKd&7S-@R#d$`NKj_7XQPK!i*Pvs3mH<d;F!KMVTI-9)d^XQ<g;R81U_sHU
zhiJQfR`+h<9i<((`R1d6c|s)`%3$Ag9i#x;Xvl8`huZ2qWxnlBvsN)?W1R1O?p?&e
z66xZ5{Y_&)<Q>`ZSa%)9woH9@=JA4<?ZUO2@9c47>;pRz)gfg)S|GvBqO(jT7Oj-H
z1igC|$uhOxmDP$><emMw(-u*>UF5E;TZG}8XwbV(VwWqC=I+ae_q59LxU+5{cO()m
z<AM`EfYJGmkG~^P2Cb|I(-=rIQuDzDM{Zm-bVLJ3SJpx(_1t~GH%vRoj~7^g;s?<g
za7nOCO(uu}^&oD?orTJM_GGm}NYcxCfF#|!^#_p!I{Pk3PyJ1jp4fIQNq@ZX7Ixp|
z*FcGY0RmZqxFV#&vQFZdDZeAKmRzTZ>@yiUt|PSXfzo%8#zGrHq~U?g1%ew+3Z?EX
z_bj78^+=(cw;X_$B8jEGUeVn8g!R@aJ7&EV{VaY-`wGaSCTUhPt1SAsyq$?}VYR+5
zQROlHg-R037!mv)+d#{XY_7@n#sC$kuV0y_@%=}2f%9)VdrzpOdZ{6R9A!csdD8i=
zL6j~l;~5>4f7p)QOR{Q0+$$r;_loYxy^_6otgTQ1_X^?Wm!{XNmRJR7=WYj?vk0^<
zxU({x4;1dGC{d5iqLaoBTkUsI1v<rX7*4u{byNQGYSiKCVbo*x2?zK@*2nE~(G``u
zMUjFuj@iPFs~iJJkk1ka0%g{>bVwkyU7nOD*pg+tnWu&eXPm<*wcd(BH3we9<&t@(
zFZF&;o?@)9D~Vn`_^N$QXC7yBR+x0kZxvRJU46)UuxGelKgpMe+m*p0V$&IWs6|&L
zb8dVpn^%v_1s-dT$maTi_lH;Pl*SQ|S3W~o?XRB9!EE2k7M{t$bZDzSZ0B9932)YL
zsnI0fu5xMRIOD)pu<w9fuHk8YB<TJ4#@&6R7}5ds_mu7a%e5V^^j@452@wfyUeB&R
z(ir_IGNI*zFeA@o+sVD!g{i?8gtMGe?j5<*?(J!C`x^!6Xg_vW#^I{T9w#sG>-z>*
zv+TKV0q&^?_lIXd>AP}``EwIpNEMJ6c(&pEP+g_jwmw<pzG~J%wx@1p9N^w3wvx96
z-G%mUWI%PWqlxz6rsOG@=jDh=PRa@;A9^5}-jtnP5vOSgxYY?4?5-5ty!fOwxO-jA
zQT#nMLhDhJK{o6#E|AX}t=_o9D)Wke$!&`n>TO?5f?g!N&K7B^ala66L|nhzo^~jE
z>?Kc5K92n7pUL-(&9Y`M2}I5Wf>1mUL3zs3xt}OPY*_?c7d)h_LD@pc;vu}0*q`j7
zQ)7>@maCLC(1f?M(+SWEJDxk*+KF-)aB0tP<UQyg-&hRCZlBl@aLBn8TRl5Md+1<>
zP&0#c+99TLp4!uzn8KR+g*Bp5F%Syp6gD4N+fy<@cg>RXg9>pipa+y}qi^vh^xSkB
z8*OUegjdq9T*BC@-YUU4gh!VI!r>0))O!ww<vrCSepQp!m`ZnZ&Znrk)8Q#y1@&;-
zYYCEiP{VU?UDN3AAg6_1JcoD>ypRM|nOnVh(!hKq!O*8n0sNWXrrf7IV%nPXbAV6H
zES5G}WHYT5zIR-yWSC*eALa4*fE__RQ{$h}Ip{QI=Zx2%ma21rnHAO_9u6;`5sn>%
z#||Eq?UIFdlpr;`Hee}tH*c^79C0z{-*x@G_`Q1B>i)-jmf1nR%#WwfD3xtqE|ns-
zjwM~?lrWDG3Omd>Rfg~0?;fhb2|7w6UDLKwoIy)z!Ez<*z;<0eu6)rCs2^2P?Da~6
z$BksaY9ZL#eSmS8mbO#=jOs<FNTmj3Mzm4`A%EU--a^}QM*37WM4^b^vkzqasXN0-
zTEzh-`^E=vouorll~;<B#}grFy_$7G&%p1%@5#MzBw35P{f|Z}>7!aiW0=|)s0Ro2
z_;TowE9h2`XFR3%V%D?z*vs?L`PV+&vmEzn91l%Nnn#HHcVM{Pf(|P+;@@gHiUcw3
zs|&`f6@+H$@gF^K{+51(#-&Rq5<q%d6`)YR2+`qn+4Fm|T4tJYFZt@-ZKrnjSo(Wu
zWaVU4v_^z|$rJtEdi=7Hy06Qu3|L4w#~k5G@lM~qnRl%WXKw4o(!;f0e8PzjI|r}a
zX9$>E`ZUoxzOgUKqcF<=_w3mvO&Vg{3|hDo9vcG}td)-V6bQczuVK2lo?r3emZv*x
zyLkYBDuQc44it6HQKHvl17~*zLZ9DuexYng2N>^_B<HU4A)vlh@4mT)Z9)0$HEDmr
z*$mwD=07@)O-_IOHuqP{F~+C3%uDC=9yWDvcDZC<$*Rov1KQ$^DV&X0u$MED>dVg9
z0z6j2H?aEPZO*vui`+Z+V5=o-fE>RXPI$m~Fa)zK!h5CEYT$C?N?m)r;C5m3yvngQ
zc4kdI`GWB9QV@;Sbir|kwI7W?zrlMVlaU#gXp}JKFp#mEDOJ(tm`HEnX$Scp;+G>y
zt$X^*dD|jP7}d^ZH^YN*@T}D=cvo{#Mj&ro3Lf)vRvu7ct+~_FLXB9wg$K}=g3-x(
za0}h*0c~yCyZh~7S0AL+;K&a+23)6>11L{K?fZ9pnnAO{>R%V0SeQ%Q-R^ojU65Y-
z@;XW@I*<)>&T(YEyER*T&1Zkp?GbZmZJ_+^*y~P*oj<iT6+BJ=@FB`vd1Oj37H`Xn
z6*O~-b)SPN>dF6ATl4k^06xi1|6_p9^1ki=9>AxB$L?mnX-~YKfz5gCpfpdutX}FJ
zj8JK$#IMP(32C#aV81$ybU5<^hY@<s{nn1{Xt$+T(&3F?zYqavg#VJ>RLy3l#U_P4
z5V7>*XOO#@dBxXc@otur80upKsf#(subxhVn?F6BF4+7F1|3D<wj6&NvI|M`L-apx
z#Ao6cDe<MCphG}x!gXfJmD=9dl4mHa`vyVgl3*t69_m(~bm^8sKH<LApLu)5&2_k2
zzk?<yw;_~fPSC<*#DDna&f@K>JkGECzuilS*nhbF5#z>5dKms97dPg^*I2R*Ljsm_
z5=c;Dt0}efCBH{??5RKDuR=VM5#?=bY6E!Ft$n;JXNKMdElQejdxJfnuM4aOzTcv*
zUE85v@zl_~yFVrV&5Gx6=NXzI&b2eW@0!kAj#Jql3Ll=wm)GIwkR%}wfX`*~5a~j1
z50FuHNEfKb&V&R71x;jAXB;EX7ge=*9BvP+Q~8GuwBi-Dp(6sSjhWS|-7j$7@~1Tx
zw$J*X>|;52qE7(;TEcT>>kFaxsDmZk(3l@0VlF~%z}q1Xe4~gU1#gHZQh6aJ38>Hj
zI%}Z3BL{Ed_E20v9=d}kLN0k;pLQC#;7#ahiw1+F2%8S^G8%<eetp`<Z&GI{3*ID2
z8x|*$i;^24>C>LuIolzQ_XWtC1A-~_Y3a{^p1J2yhwcozao;zMBH|MA07uYq2TsA8
zI)q^vcNfC2?6^-LUA?1#(FXkaz=r^xNiOz)vk>9=&>aw-GyY;9Ws-0jo)^6N)jq02
z{KP)Wgf4Z<x<edUSQtD=ijbe9Lo%UzjZ*MN1n-v@j{QZ3?jWkv08^_)zXXAvI|$hq
z0c$o-IuSkyezSV-^fE9cGQ__PTAWHlZoTRta}7f;)N*gspeir9Uk8HU7pGMXeyPCG
z$c@7N3NWiWvizCgsiBZ0Amk~-H%-LHED=-+W!VoZr8i&y2bGe%_4ibYD9ieog<wC$
zz`gy}JcjtlHxtoKNH(FWi5nj`y#wBxRX@{6Uer##dT`C=sLYOSs<c=>KQ_M>3m1GK
z0IEDhLt6v-nD?{NHt~2#0kyebW|oD$jji|`f|(z1Of&DcFkgiIS=#B_Tud}8Sx+`k
z3@TsBfkn))#dnLCCvy*Jv$hYqHT>&ThQtaCxdl6^Lc_N6R%#B{&~+<Cxlar8sMQ11
zjXIBJ%69`w#sd#C(Uyh?ppVOeT$)?IpS4B-AA6_}Q>0uOA(xKvuwJ4`ImdufU<BmS
znIs)qt*D?8(n$*-m*#4E{}@y$M||zbs-#i4_gueUCcLLlhR5A{3ArPS5M+jrSrD0F
zIX8bt);%<E9>@#}jDUE0=p-`)N6;~pTEE{Hkr^%x9cPA!K1V>i)6DR=vk<v%4{MX-
zp;rio-s@kAm6wLT4?UybGQ+HsV&$cww?_TI+2<#O-UCEUr<q|p#xRPjuL4gNy|z70
zdDhP7<(+cVl{}dGO}G0eoHulxP})LH^kgC#kKBA=q}fga<0OxK^J2%A@y!yFl3Sd1
zTod{Hik)bGp+xpQYW6WTjsQP?aSCELv#scS#H9P$u0PD+Q3e^P^xs(fG*5ejQ-_S$
zsNtr|^=HVKJcRec8;)mWRS9=ya4MF^44u`P9jwX|V?FN;MF5t|BeUC-J?CJpv0Jzt
zV+rB1dLv4hLLQy&+hhzg+(_SFs$GiS57-}mC|g`(7CpM%y}ww?e9PQwP}>$6dm-$2
z{6R*nQ?xGLbwhV$1~yO;qN`>7H}dw2NcDHVy@=5V5{Moy?<6Zz8z(`wGhsPIOa-}1
z;Ji7p3cf6E`CXJRWcE^=r_Mrow?bVE4$OYYzt(PBl6u%e`G4xahOEp=5Q&lVnIDOf
zp~OEYMg@C&@cF6OIL{o>)Nk7c@rWE_hwRAo>t=MPFn86?L4%thACp%0Ea$;M=saD8
zEUldjl2V5%SLB##+_Q$*TSdqInpo55Nm(f5rxB~aM5c<XS~esFX$e#k8&>LSYBrLw
zMkA|NoE4vGSHsWN%^(N9YDZxnhr2kPvKqIu)8Ah;g0Cfuml9+HXE23W`9#~q?|hzZ
z;&(o;g4qWn1;OWKfH!~P^H%R8_`C|h=jDY0KCh4Ol+UX``*^n~L_kdNTS^Sg;I);K
zS3mq|sjWJ$je&}@wL07X*A-`+L3#PBO3f*YSAep5@BvU(=j8)s_4Jbm!lzy(y7w80
zfL!XmY9Efa#^E3AX%#tc2m*WB<}&M3d)oEfe``;>>9hM;`fjL#VBqgC{$K1$%<ufL
zE2(;>6nf9zK+TEc&OC3813`PDW|!l9g0lz^Mbt<OssoK?LbV^euo-0^iR_T9K<rpC
z{9TiR<52s<|0%nY8JU3pMRp}2t1#1GW-|)k<-pkGfMgnDfHl6%)olqj?hO8;xnf2R
z4hnRVAeErWg4SK?2OzGv(B#3cxKPTmk-yw=V%6cLH{h4!2}Wxdb$sk0L1kP_*K;{p
z1KgOcGbzahXWRKudlb|lTfuc%<o)(%!E+QCfv1Qd{W&>V$@4u5pAl~(FECwowU^S0
z(p6&!w3kwO`s+dAGOV&Y0Cb7eqky-J3r+*>7NUZQi_n<+?BEgrHV4nF<z$(7Wc<it
z-^biHg~q&vQiIkAdyB1Lgvlysk61WBFDDf?C!dLqSpb}hSTeSPiR9(_>3$L{3rwdj
ztKfRSly-U8OC1B}a<Zvkw}KZq_*H*j6o}rEpeDK<3psPdq_z&f6y+7~-+{?i`R`*I
zbssStgkmutp3Jn*hD&)!8?wFf1Ion}k@WM44k`S-@dhu-5i;^QV?6M2<e*tILjV
zVWhQjvM!UD1MAgO<Ame5{{poddw`#k_9a#{nJ4czI)cFxLdrAcZbg^E-u)9#Y;3*F
zacH;hL`F=G)+)JxHYs9u;-@en5Hd-lUf@cIcDiuPoI;61*coa~KmxZR-)?7s9^dc=
z=-ouh-8jF8Q$N-KIUc^Xh#MK&9L`qNP9>EV)#fe^uzBTgnfb%c_OVW?I#4~5ofI|c
zNW;Sc(fgTE;(9xFv%3kVwMumz_}!pZ#)tVVz5?Nd%|!X(hY`K+UUiN8Y6Tg=CZIk=
zgl$sKnM*sw;GCt0b;$W+LYnw%y3X#(Ve`>wWdOCX7P<Rvp_oOC+KW_k*hAn9fVy25
zHPOxgh7cDk8T~}&*T()4nO{R_h@)mD9x@oGTV88G`5p$~^esJ#-!F@{QhESG6j$zA
z5b>)zvXjMhk9S+Vw|5%4MHj2{4OXoYoqyLkg5VG~UM;Nmt|hu-8Q`Skdk6bg*yRBo
zra1_k&7GV4fwimx-hkHh8NG4>hfVk|uN+k)0I@Gl!oAjzxle`z<@wvjpeE;TyW8Pd
z!O%k5CIv|1g)f1U;4KP*)2bYMZ2Ha;#9CrW+w-ede~$noi~OCC7rSsrz=gQyWw^8O
zkzpqJFroTmH}qs+Qy8)V?%J`2-_{r&$u8i5p0i~~m_uqr?Sd%G5sCqYIj0(mp+=w}
z>k=~c<dF{Tbe_Gv=h*h0+KsZa!t}~k6Cb?^r21uEKsjQCISpT(pKJnx+lD+Kxb0R&
ztROD3Kv6-~d@Q&v46Fx&+k!xPAh^}1PDcoCyM&U~Q4N}&r@1NCk+{#CF^?4@+YIk(
ze!rm^2K>uKSP7da8W|CSeYnw2!G6}$LLk`pGkko72V+HE;N1(!jZ>P}GlDXo@lS&N
z{i5_g3HDFi-Tx|?%lq0bU)UfLP2D!)2Mn1<{3@ucM*K2j^QP5-3J~Z;Mi6y6Ko|3z
zZJv9=z&J76S!?54PHP7Ljz87gyJMuB?Q3VpWsfQ33p!0}DKB~Aq<CZS8{zAI`t?%l
z17Uq)joKm4GrXlA*4|>IP6r%0#mU2`{R#4PAYV2Vq+3DwKbQ0|0qOPrEdD-I)1D~m
zNe!TPXS}y_4eRcmNz-PYhFZS*r_9ANxhY#7ArH;;l8Y`HCRkrH577;)kplUwR0t2Y
zSh|xei&J+|J)mdnR5^5|HuV3TUgX?5AY<ewX>iDzjW|<oQ2n6jwH*h01qbh!HoSC8
zLyN{W6!j%tSFJPGPUg5`fBSD+hl<AeDOd$iMaTVuTuQ&p!}2%XHsVJE-^Mn`(YNR7
zHvQx%qF+!CvqyXG7}Vhkc`>`@ZsKI;#fWDJ-qDCei|xCV7xn46yCc}J@rAezn}q<M
z&AtBkauw-?HK>|#Y0Q4$88Zsbq8gE$(Kp)Rw2c<z`|4&R#pKn4MePl2F3rxgqNlZW
zbJ;fYPcOTaxRv*}LzdMq${I>n!q(aMi?y9ZcSXh%d75CD1C5Cs!wWoJ_X>5agD-#f
z1Nh(Q+R|YOL$IaKNu}Rw+o59d3O}HQA@RvpG>GOx*15j4W$^Sf2eZz{ve+sGXAP0e
z*=cCs291CNxg5+6H%5>kWvc>WDCqZ?C##YSJU_cFch*g<9S_=<Pm;0~g$Z6l>9JRb
z6vouwXf5!jE{w_k^y?v6dOI$e{C(dBa>~|~5n6B>a2j`4YabNNoP7!|;daj+JX?hJ
zSsbVAw=!o(L^Ab6g+XhC)wrRc21uVkdjxw7K3K531sI<vpXsh*?Cs3i7QjUt3bMsP
zXAFOOjrZ8MofJ5O>-|a}7shaSSoz)rS8Fm7)E55yJcn8bH)f4^JN`-yM_a9PFlr99
z7)THU7;?cI{u`bjoC(f>m(DLrG@&j^JU|8wUEz#i!MAS%N0q0)9uzL`u3OTAR*-#p
zPY0Am30we9<WSS|4+OqF4^GUHWCPDAL088Wwct7VKp@Q=`o25@o%rY+j9BS&sHYKr
zR*MqhC$8%I@<iY>_z>oS=HUwVpp_Uw2IkK)I1f1EgC<TyMGUweT{j7$zz9*+|3p~o
z*j9Z}f@#;8V2)r0r=UtCrX|h!z2Gd)5XUF{f>|w52Q)kO;TYINa0(H;y`yRr{s-^O
z9I{H8cuj5!+ne#$9G(S%fPX~%GbOh%Jv<}6^<7EzNm1_B<!s37rZaZ#EsnWRK@R~@
z2Uem2z1Ix-?e*^4=hsnW+k!gbO?J@+<{Y<|$rj6z{N_j9m+=H_&Jy+KMz`=!n>$B8
zzOD8q3&Q`3rd&A7a~!tyEezzj#D{x<FyJ}j05`X4Go|ljJ;*rxc1r23ol<(*!+>0C
z!~sAR6>uXFO+0qk6_zv!S*GrJD1RiTRFG0Ve1}&CRj%a$Hh~4v#NZ|D`Y175>$qFj
z^^h26UV=eRxdPrq;qUZv)p~^@*MfV-m$wvBA4M;6(!x9<6_1R-BI}dlIV@jZAd~P!
ztB+y|@>QP~2j@Y2d20lb2`o@<BoZ^uJVp2AZ35?kA?~InV+{=pB2N|zXh$4D$D3#B
zDXt^f;xG#YCV=P@KvY_7CnNl%Gd!+?_hCWc&kkOv!3bu_3s3_3qgUWT<T?XOcmvQO
zgI+}01J=MCe!TMofdxBafQwuQ*B&zSyY(39HA4#i{VV$I7iBwQ{7{!jzn&Yi_}f3t
zQmJZ3jA#s0kQft;kD%RciejF5@tu4>Eipj}lcJ+9ybN<xKWfpJ&8b9oRB>LrAltb+
zKK~Co{B^)}stEQvhnAz2!}G(oaeCNRH_u(kYQG$A^Vxx5(|y-N{leFC;#?;q=JaE=
z6wQX@RQBpdj39y|DgGbW)_m7LS3Qqh|7s?>RUh)H=E;%~?w2ggb(HwI@58@aw3&^l
z!13o8{eH#lnt8d%c>kE~rDc_!Veeu79rB&x;uuq}alZ1U<efopCA80<#vHV&*oU1s
z&MrdjG+7zPxR1@)WheD67Wgh4?Pz3rjUQ^#AGF&GV#f`=mBVm><D3lRTOTxu4=aK7
zP0mBCCFR*gWxS=no8`yq-u4OVWisPx^7o@*wXBZWF1GcWJ5-OW$%e5Zauhm_R7J|w
zdx2i#WG*v{nMVhM$1ZL=dmH0dawF*ls)aW;Yu>lU+S#i>AfGVUNp?NXqkY1EO7~y<
z@xTAA+_xVcj~w0M4e_$nBFAfRP3^g1wvqnUjl`rvFKYkk$6+J;S#6{uSl4l&FH+D;
zn%xCHru;UL{<W_^jKY-kF#lyMLR`%Li$oVN6)s@D^kRC6T316*hpeTEp@o!t4K>$Q
zHOyUA<chTDm5W44|M$&&mvdbgY@2$p?9_or>(VQ;okqb(lgc|M{!kZ<Cko95byXgz
z40l&Oe3>OeuLUJ)gp8N2IxZJR7Gt4co=kql{wIE#x)o5Viz<#-G338}sItbIy@Xfc
zmKP5eX~b*@P%NC}KT3toYgqI@QHj&Oo~gK#)u0mns^02x=F>5z72=NBM;`k)|Bt?E
zStD}a@R^KabOl2WmiiPkD4~)=bel3(8MFhnm!bfv0BI?8!=EH|$Zz`|>hafceJCU7
zY<S`KB4+kGf_REpCw?ECj6eN8Z0*q?hQ)fQrSd?+n=xX0zaZbCB328V^UI06l(j`g
z_aF784Zm%vK!X3H95J}J^3?oJ->TU_=dK!inJzc{L-7FmRV0{9?y{oI-|ecPC`o#q
zCGB7=a)h)mplmG$H`UCvuO=3l*jLg)wGIew+KBmL{%S<xzU?Rf=zPUki5dFiZqD#V
zH$zZ)WjOK@^Sgz;5r8=-{8Rpoy+gX+%#Zp8VT<3nrTXP3bGx*QQXQvKm$Y0{ip3?K
zZHk>P_2<+-?TXQwh_3&6hbkPjxs_32gWF~j*k*?@<FeoNvF+D-#ZPu&+FV>A)$O|N
zyvQ?8EQ9nWcEge!*b%?W1!hzBlRw-JsM}X^uTH-_IG@>b2e=uJ-Ge8PGH=w9-2Z)p
zs>U1t;#GW^_G-qY<4fIke3za!32*g?<7}++yk4b2wTkuV3FddNIF>K#zSzIBD?Y~`
zFo@ub9gzN&FOI`_d9E>Sra+j2XmYlbYJaG0lVze_^8v$#ZMMS8*rjbr+}!6we-Zm9
zFU3#M7KL*r3v7&}=Z3E;O-0Urujj<!I88DoXJRqhX5R^HkfS=6%<zC6xni;@2F((k
zW$QK=LE-hx!20vpsTWad&T@4MsonX9yd3XG2kox79FgYZ&;C6EC}w((mpEA#jBrq#
z-RJjvarT@e$z_oEy}n!j{M&V3P!H8Ef~bdDZtCl#+kPiVsG0X)m1lQuhu4jF?`5a8
zCSyiR5MC2v>9!R|HJ7&LGx=&e6V_CD?CUIzu!f3_doJKrq|@DA8LjiV^2)BIV&-+Z
z+5b}3E37>z5byo<tqt0LRHOZ=fJ?x0{m1@3V3Qw^Q|9_+{0GurhQ+smbpN33%^;B*
zh(=Y4*+esen20!(5Lk<n36Jb27yf`wHfvKzF<coRPIZ=+o4AY*1WG;W6y~~fYmIDC
zLIZm{o~<UxrQUf{%yzwEAg~Iu9goOj9NEDe?gH5t1_D`;z)NoMxl&j7+}#h(n;`gq
z47eYde-1U=_t%5d=ckp@Ww_u(&=N#=+wqvsq(Cqq1A=*3wEa$mQ|+QeJGkU*gMs`M
z2Y8OPC_%jG0iV+XdCL>wJp}PM5a^7E^tR(=kF9FKo0w08%j&RsL35yi1+8c>w!L)8
zzo*V0oi|VEA8@_52L24dY8s)9&Y>3MP)%k;*^VD~htG+iEeZsm;m1LG`F`x1>E@R_
z^BY8qU8!XVvtx-?!`9%)>Uh30X&iHHX}Og<tsJnfc`L`2$*(2dRI1s?YPT*Fy;?1X
zwA^x<IjMh7mC(rNAMgGW?$vX)i1cKwgVuEnP!pPGi&jaRo%rp`?DIXa!b3`7H^=Q1
zf26o6kNYt2vsh~ixgY}xu){Hk9v&676m-u*Xs_>F9Y<lV5pF;5*E4-WYCEG#VndMe
zKFxb2&Nsr`Y@ImMd*v=|*=i+Es*25{bm8Uq=;$xj6wXe&GO|`cVMFo#Nr4?5RKA!C
zen7!XE8HENErM(c_88$rj`I64Td$pee`3yBV;BFoW<0r?BmS5(n$StPM<ZPNS-y5@
z%fE<s$DTj9GjT)iCJ-`8kr1=+D5tC}Qo(jUp|zNw>?)%8u<-k?BEnGxYJXcY(O|_&
z%Fh$3fwYHZc?qaeKLJ(hMN#7CK$Uv8!|M^G?DerK72om_P^Hpef?_fuSzZFF)TgW>
z#Lv&2wusVA+rfMcq}RRsUaVgU!x!K;iJyN?Ff}Q|1?Rc4COiv-Jidd35R$$gbYp$W
z4$gZLqz=Ulr<}Vvb3FXO5zX=vDqMv4zCXw%=WePWi&H_LAl<;^P5c7X{NNKJI)hRp
zm%R?>O$3ct<3wVw{sfXOFXe+xW`MnUhZn&wd8G(3`|;qjykzFaN|(m2;o)0g@4@ZL
z4HdLXi_bIUuH-cN%mQzEZBzKoh~r=vUAGM@(_e(;jNN@dHT{DPsWJl;%bk;9RRVv_
zy|aJWpcyP;1~7;78#m-Ai<VYe&0Pp2&;Qti&S$m5tY|5Jt$93eTs+L9)`PN$FjAGK
z>Ck!oUAHioKkt^^oDb4ycrU)gqNlLfQl!%(CDkN`zHS)1>p5~`{G1QJMH(Dnm$g&t
zmYx9Y%;5JdNpP|KUikLJb{o6_zLc5#aH6;kY<l3dtqE21)T|IQl3&;|(0ENT@V>Q=
z4{W@lU(BcXuA)olYC*YC&iD%OzvL-=3Y?S?7MP*6uXf<JfLkmkPI0+{zCi7_x@hgS
z*GMB!ZutH%7t$k);1iY~gE!qD7v2<s-$G7td5N?Y_{epy5f6IO0*LT?&n-}c>~aBR
zD-ekAt=#t-gC(uvfC%5^3S<ihi0~Jv5h8rBnev&fz^C9mga{u_%P)8I=@?u9N30Z=
zvwLoP-p3;RqY{K&7otxf!iQ_0kO?Q9`PhF2tq~%8xHc}T(zpDdNhX~3G|Ak;`8CPx
z5k5&W;qhM=s0SXRf$HwXf@<-d=<WPoIx#z3Y{MbS@#R2=R9MS9T<R56+K)UJokGlr
z4+CV;kzEZfBt#iBaK^<5*EIf4F#g0TE|?BZTz$NKmCsG=9=)_jo4;*0bLFW#8Y9;6
z_EjALfd<&jpT?GHGlh2@g2tZFE|R)vc0B$(kRa9Y%E$+sR<!;blV`)~zc}awNHDP`
z^|pCe?aWYz18y29i?-HurzRaanG;M=7}*e;!)YC>o*OB}%z!X@8EgUfyMvA>Gug(k
zW?xoTv)`k^0-k;Bb>bm~$Xyw8c^?0JfaIRQV}~QS3gwy-S9{uyXdioR?=G8wqS>+{
zt}e-sxC;SKh<aKyunlL}YVsw{b8Qe$4Enu@*u{kERsnnUp$+id?+IJPg_LkMB*Pg$
zw}{<R*NEM_BCQ9gavU09*(#Ki<2dsD_2BY3AxWYP7jy|)f@RBa2C;0VgvV0$w8)}?
zOMqpor==ZS^JLiq&#`)1z_Jywi&(axx`&8mD<#|ov1}R6oGx1@pXs(3Xo^_2Kr0#y
zLlwOr%a&;C!RfLEuJ_BbCC4FrJaZV%ysOYXBvbm@QzgX-lp~RKR)vNQ%-wi%Xua!H
zC(>(B)dyk5R&%?uQniQk)A2hb4+T;T@)tzf;i>Jewp7M5g7AfeUuL|XK)jmM8#jvm
z&piBZPEOj=Kc)kbXgJwu@1W%LvS7bOtJ`S7_!X8rMWm!-;S?8>dZZ;r<D+{`hN#WZ
zCHFs{Y|0WO_=?MZ{Rl`?Jo^W8rq4|bwaQ88otTe&xa!g8I2z!4g$ujUeOUI8BCmIT
zv6DcvHF((Q5r^SWJIfz!yyb9QHV$7Clw4`Qn)XeQk#Gaq7+<Mq{Ps=bY8~pUr?xDu
zTXxbiHP^_36)Im4R0G?Cch<6HWh<T)>Gc|s6Yan{rT&Z1tuI1n))R;dJHE{V?-tS0
z-!)~M)<3;l(u7cdc(<stToax|<@4C0>whBX<9N0QRV9oL_lU~|Yui7n-m*c4!z$(h
zpC4>jjD01zm|n39(kw!cRXYH-#%!`O^VhMkL|y14UirqeY?3?`{|yj2M%}g9tV~(!
zT-_`e-mxAyZSMKaZNcZZJm$8lU#d^RpB{P4h3F<(YS2^SKW%zL-%ojxq)yoxA3{Ui
z1j3!D{MN1mhAf8_Rr+HY0d&7C*r9>5T#aXpBhG(8_v*nQqWGuS*o?o!C-x@eU1{^*
zHZ1GF2SysA1sR|uGO0-bTanxs)83tjm>BFw5pxUN-jiFLR<yqtH9%*ve!IP4Ka;%z
zzAfyT)L(CJRdqtr$ES{yPjHAnP+hs^wLXgOupc1USXppA3x$k5l_{T#D!Ll%`bQ>j
zLb|OP;x-csf+a7GyNKQNx*c_7^I;IJ9JU>@(Vc15IIYER?nIHm#hlaR`xI(kXofYU
zUD!qecO-KbbSl~?FhEP4o-J}0ooemZ;2QD{q-KCujT*XaKj>o9eR*&VL$YhU+@<T~
z*ei;$1HtN8OO8`lUd^<C6Ib5(!Euh31fPQevo5wMWE$bwd2WoXVK!~y(#Ea2pR$jb
zaqWknad%18Qr|$olvPIVNpdL8c)xj~^h0dC8anWjqv~I?N9{NMz8jY!1Z68YIjAY^
z4Nhz>@>ik~;p&4{<S1U!hrZ0P;eV$zCXwxytIpT(L|dP!GN7d50mc{Q^!e@@-WrMw
z7yk#%iWNTo!K~Oe)E;40%(^mvYF6C*@(*UkQE0ft$#k_5z(=DO<#!(qKI#{eCk3Ds
z&i)8no~eo-wmeP~T$ds@y9(~)+my=x?&?LSkJJ9wjg2Lq8v&j1=(YbbopE2C<NqF=
zu_~<?B$x>h@XtJca}xb!H;$76xn+3w(Dw}mWff^Vb={Wb%p7^t)JASdD;V6HlKRMH
ztPC_K_|}YNH#?R77IhN2%j?py4tNzqCbn6`1`0a0XF{~CsQI1Bar^bKj#95{IK8$k
zUhX_h;9g?S_edCh5YV=~(YDbf<CfwbmIgNgf?3QnhAvNVQ{ZlNZ+i}3e2++i61HuG
z$O!M_U<bc@P$--t;?C4$=yGANJNhZ&r-e4fB^>70Pl&)?wWTP8cjO{>u?g>7o7R1l
z;c1T4%L5EjdyBCXSI7cmtu2F`JQm2qP}NkM-H7^V1PZC4USJR5fOGnqS0PugAodV$
zMpjexgEn|x=%{%MQB&0t!DJx@jZjWnfIWnJZ+H^*5r!L5+{A?WN^@bq_X2wer-MC&
z)l@M>Fz<prgo#1{vxj^&V-cK73eE#`S4Yif?1G$=J%qvWjG8LgL)hzh58;BGW4;5?
zCy?aUobDlf(%H>u&=Qf9fL`K6f-e6|N(yrFPLq-vykC<NOqS!&q96zA1@O!-M0qvb
zNYF_r;ivWG^rL4u_H>gXfhebY0w5xXA^(fb2p$2}E#mXuehzH+qt-h5j~WZ4B~u9a
z-vjJgERzv71-D9{r__gH>MJkY%Tv3ODo{mzF5O9(j7W(9?1&1h83~dat@gpNJPLJ6
zAXA(V8xz3M7HuRL`n2n@fBsX@1Cy^{QGQnV`=V^Ay7|*kZ5;XgqU=4%_XMfl>NN^M
zzbKyEBXmg-b4t2@eL)(?DnY}rlQ{E((Bo@IJ=AmO11_l=4g*n4Q(2a+TTiiUtTkCD
z2HUn9;a`@Z^mIs41{tiyp$6y!nXy^quxHb5WSpu44;iISFh>F<^AbAd^I%<9(b4|R
z*a%ezVQl1{2aJu3uK;5s^4J~B2bl7zsMDfypI(=ww2JqppB4PA9^acUxPOb^7?l^)
z<1aWO>hXJakL&RXeK^uK5cT-c*(de*!BOAq@q5wiLagXEvpJYx2w$T<gs)KsE$}re
zMc7~{Lh6C95e5|a8ev>V_!=P<9QzuzF(7=6+88=%gC(M6>zyJ~-ttj5<tEcN&yyPc
zZuD_WUFg&$jdUL|9rK0%G95EaBc|g$-Pc_fo;!>&cWV=NyCmVR!O`tr;r124S@n(!
zv5xZ?U&i&Af>>K2N<ufO1HmQA)IV)A@0UYm{#Oj|CCewh=1TDOT23B-ilVs^s3?F`
z15ms`wE+j_@!;nxU<+jYm<Hv&1qSXwoZ*(w2JLf~O20;nZcqfS!Z{I!^f>aN6oJ0B
zv}wUpyyhcp)i0GZ=mG<TuYWG2y6=W(|C2WVZy-GHy3v2C&d-n^)&F!C<oYF|kMw{L
zmHn!l>Fde5A3lo^Ir9#Tr*=ENE+s#VY4G8+(mHO-KP#1WpW@nB2l}a2pOZR2?=4_l
zs9${R{{y+eQcZ3mV?vRX`Z3u&k$}3*6jXC?4avRoeqOQscZG-->AiPoFLiBn=A^{A
zK^0pFvSNetj_xUbI4oYg74qzvZBA{GRz9MbEv%pU(sUhAh9!;$Wi9hxS}|Pf*ZsDE
z)8b@Z(te?&-Bln}>?-GBsi|dLhy&O8wg8P$GiuY75wnr;G5az?XV_v<?3f<4GU-CY
z7R}LEZPx!`?@i#L?Em%g8Ow}aS+X0uqDZ!EGbAZOg_L9}l_Yz%jIm6m%{ochTZvGQ
zvP82yikT#pL}i(3q6pI{W-|DF#;Eix=X<{2|2g0PIj`60^*k?TanC*XeSfa|dT-Y?
zeDAlZ>B`p)pYG;7x!EB)SBII%H@<G;`@K7FrtgY*k5F7QTK>wHgNI%ePXM*p(j)6c
zd>5+4I&`Dgh8cNAoX%SNNYgHx>vFWEI?S%z<vdR*cI;9^8rS3~%<(Cp#SiPZ{Or}+
zBUA=#(z#RbKYe@a0)OPuGDLp=gHUYPNwvM-B6&BVB%9Z}u!2HQ6cp_<)<mA_mV#vO
z|Lwk^@A9q*pRSs<qWXPK2ZHBJRjYZXs$So?rmBzh5Bqg)^Y4@9ih>jrfDSSzYFSxz
z`MkIq>eLpV7omfvzv0O}sh~yKQ_vSEaeepJaM}{&%aw36t9m3^MiSjzug4giUh`s&
z%+??*5C&0omAUiz#*xnPl-QQYwc{>^(I|Lfo+bNIV`cyD@*q8+Ikak;t2wmS5@-%-
z+~_OZO!WY=UryIj8ON!swp=`tz%xvgDSz~^e2osKb5&W!1^`0pcmP6cbN~pwcLE?J
z<IV-4J!Jrd4tjGzXyctZ5ZbH91);rqTo9sq%z;qWN9pnG3xE~+-}nct@c$bO2{``)
z7>bJfGYtKUr3B;h4>tdUN(r0A!$!&#K=VS~hM!3Ejq(R1V&^m`H2y@Q70dsCL|Uu<
z3z0}~sEMd{@eNS%al+qki6gIPh#!3OXy`R#>TcPM;nQ+tij435E080}Vdk$^^{iGF
zol&_WL*(WV9Kbxy*2i6EawlAd{#H3w=@b8*qoev`j=$BP8(iY~R_g32iwlCF#q1V`
zZ_3tT-j3F%sHIcEWWdq&%6L6U-QJG-+Bv<NzH`OQE3t%`q<VdsNi^RiIz#tP>9J;1
zSE}pn$G4APzw-I-W-@x~`m&z=s%>)W^t`so)#X1u?1<(c#m#>QeOIuLQc8KI2c&Td
zI*PY5`|=kmb}XKd+w8OP4*as#;_>yH_5qD0xBf#uPhKq@NGg5?gfruiRdbVoJ)6HA
zf14a$Df4qEMLzi;kleS)%v&hA)bLZhBOt2BZf4Cd-fXwmTtj>Dvj3$kA<u7s%2Q(V
zqAMkZ8sae9t0!}sP2WBUPcK?>v1^CkKZ32R+O`QH-aA7)L4!EYUiM@9rSFZe-hA3m
zy||69CZfMIzP=LTHolrAgT~k8pz$?VkcV2=QdbIvciq)J^(tnoO-0HtN@=cyrB%bx
z-LGx}Nyx}(B9MgqF!~rsLh{Oj>w0(YMmc;OHTzvjr}Y3aLL(jtRAv{~=kAF-8f!X!
z6!g5d0bA7k+*r`_YB~-?W&?iX_Pi3RxIM3vvY_X6$_4biek08FyhcWIdtMJmb9-Jt
zjF!#yy!OU}=9iAF_g~K3`H$yjcj|WhoSWrb!TfVVX=?&NJbO>`-xkkqeH!;aD4xBn
z`1X~TF>tmB#n(OdZQHibo3B^xYi82Nx<jo)KLZ^wz8~{r9MJPRhA*_$P6>=SJ$72H
zQ`)wE@8~C0xm#H2v+~a*W4jMN4Nm!o*4C+3UZ~w?ZM|sr*JMjA+tX`YySIKUHidpy
zt8{d@$C1-&?D-tD`T99ljG??R!EQx<09FZ$_R2nnol{pkeOJcT?eOTj9i>Vseq`di
zIoUAPoo7MQuC85MX+Zy#zs-W)BqKLDe;_ciTAG~c1KT{PZkzNf_v$L%k`Vk=B?e1h
zd$$CbM>;onp?lNq`#RrNwJ`<}=NtBh&1#3v3i2vX#_vD&|Cnz~3*>eGTGkdFyZiLy
zR@RG^0j7U92~eukm6!DExWt;_?=y6Cp`U#*T#1!+-NrM&pBTNFXIi=jpxO{I^I6eC
zRI}3zKXv;0kl)#~Jv`a|k!$&>qTbof){8uVO>Ru>$U>XksGNmbE1Q7UO0j>!!n9;q
z7Z50#*O9w(){25Y;1)Ds^}wNbrP(rrw_Em5z6|q5PWkSrB<6bFEf#qqpM3U{``VX~
zQj^bmjq4hhkG(E&JDuTVAZ=3n$%4Eze|zqW`rd*8{rHBEJm`SzU9QK*m@rV@-x5|#
zG_SaHS5FrH-QCM^v&i%n%Pj*XOJ!5CmhM;vwD%7#2D<F3@LLG~O^*iMr94GIMChEo
z<^rPBL1?qZofG3&^+0tI_p9;(hA+1=W$rwvIHITYi|&2_X0vbC*iBDvFTcJjx0ipD
z^@3jhQ`}zuE!MyG@@s4{eW15`yiAs>|9Ftw#os9c^dHM)x%!Vyc%c8dZy#6x@dhvy
z$QvpIeeP$o=ky=-Rk`|)%T(v|AFX-%k1-sc{^Os*!awRi-gUk9Q~!~*fvt1Tq=KMu
z<%{yKZq$FHo~`{-3aDp0{;hiUe|al^*MG8=pCx_SXIQ=C1!K`eu4~Vnb<aN|!C!RK
z8JYDDHTXLp-l^IT92{vnVFmYcZ#}#%aM#XKm*>s74+!DfKG=>-I`KT?V0G?##Kwef
z`EL`VlaWpn<uwfcS9vD0&sgaTDnsGR7FLE{o%u94r_k?UcT)Xo7EqHNDgQA7{kIDJ
zbuYT_FHNe1>`aflU3=BV>g*@A0Drg3)l-e*nBN{YPP}PD^N+;LTY!v6{^(fKJIE%g
zZT<kL+(XJdmHY6rwf4<qq-X5h(9N<&+D2%!%-YcS{a6j>6-V?U&0mG~0Z!+8fj1-l
z#i-&!_>{r^qS}vtKg3|x4L`WS=G)tQ{h7T}nQO<{02D1e0VrzQDBhyLrxsnEXLVZn
zj(%9WWA1NrpjeIWz4sFotun%DbwX=l^Prf@`3Z_x9w^!#ssY1MPlrA#>hv~Ojn+!m
zMvt10hJ@JkiV!2CUb~G|OO}g`>wkEuS@CM)qt4V}7w=z1wJ+M0$;}mKH|;s`YjM`*
zlY-yXV83eEo#2&CYqMV#*D)5VPaW9n00Px_xBJC{`W3oIDQB0BiUk8JaFcaKKW&#B
z8b$B&Iz4{c@SasDT)^~1k33wBm<PqWz$ZSk;~u@dd1Iw!P{s9mDEgyTQ~VaXsai_b
z1Ntx;pM^QKR1uP`<6GL<9hKa=?)B}*O^A`|F!i^euO@!4)mToAnxJ2H4Cy5<D{r<O
zFJxTbY#=N6Ev`c^w|vXyP4j{!UYj?~2dUSWo?W}$3B;pY0>O(v&4)_YaD7V37Cq$H
zR@j|*c-=IgrvP5I2v?k;9=7>)aal>Y(O)IXJbgf->{JssQ6`fz2!tzn#)FsN-ULlx
zGAVy@XS}veaG&oT+c)LsHm}$O24ua9fiKA&Tj0=h@bGWghu01*2W>@XQy)z4b-xF2
z^89bN3Z`P*BOdJjJmqHgVE0MYi`J)_xUP%YGAY-^{6W`S;jN!tZ>y9f|J3w0y!U6*
z+p(gvA;3}KQf@_S>aRnux)&!tE&sD1xCdPy2!cBn|E(bSTyr4)&#nT_NEOdOvFGf6
zHeZ$-{LkdeRt1SmUc~&O3!V~k11Myce$8m)I-9-mE-3{A(?xEdO0<UIviWW`Muj&J
z>(W)f2{+I+Pd2RRmzNxt!C&vOd~oT7<ksMO1qH8?OEX`Q?|bI%775IxTY)ZbNTTok
zug?#fAKb&gYpu8ZLQK5aaNjM#NXqx!RI|r+KW|Y?khj+0!GT*C5vc&s(3BnhQ<>>3
zXZ!C{mmfUj3WK>VfJ%byuTWV>=R#$m%a3`(R~MfC!(4b+MOn&bzMas!s*?wzH|9;O
zerfltub4L_xwqiRNK+mW_UiMz#Q7`458p?RQfQ+Zn+C8_<mo(C9@z7(!md3?=6wYk
z46R>dWSI)~Y+gi;w7bgII{4K6dc)ImUz^`-V?5+o>@Dwjc{x1*)X?jVrW#%TUXXK+
zJaUWB)4??n7ybIi1al0RcUYFZz2SaNMNF?{t5*8c?pk=^Y`XN-jBWatKj*DCqSt<!
z%y`4I!QQXfyiRi~QW#WlP$F8|&*sv4@2f`XKht{CkLn_%>mqQxwBCjN(6Rc$K#5P+
zruV<(9Gs(<wuc4)l6vWX?0(TX@HZm_$Jt+5pEh@KVup{jdX4Sw`s({~8rwCpGpg5l
zY3`8V1G1eA<gC`7T$~7RAa|zFXlIUZ`VjSa^kAFfZ6aArI@KTd2j%vs)<DJYbqCh?
zcD(<t22J;C9wv1UfPTAt`~o4r&xJ#G7qhnZTMXyg6Hi|}J^-vK_Qx!=Gyib%-FG|l
zx0QAgo{!uk7nnkY?OwU}@b_Hb5Ztz{%wv<_(tek_UzSM)LOgO~u5NAoa3*M{&G&Hm
ziu047w9=B%Zj7q>UTQE=08#|y>6K1+JKz~By=72$C*E$p*l?A)Nvc4P%Oa=1i$C*x
zmyEckZUGyYj`NSe)%8lIL;FDYtJJZ8jbh0;z>npCk_>Re9SYbl_KS2C(;;>zFm>wo
z1g1`C4%gI)7z0e5cs{qQhU7#+#erD&Cw;0@oqhwIsxpLw3U}auSRRyg0vf=oXMqNA
zkS@^6wWM-2fOWS64PbE_paJ|*>-C%lu;CJ}2C(6|4~rjOM&Ec#aPincJns|^#Kjkq
zOSS6HiT??1xuUH9ZqL$R-D;(Vo;?1G60jhV%Pj@|ecbZn#D8u~^xwiQmr#k-Jbe!z
zw~DCCI%be{SB@F+^gTfF7viCO*O~K0PV<c^A!K8=>9sqgu4@kAmHSm&OVlz4T!Xg8
z4&pvaD%tmA-w<4>McR!h?;FceoX&)ZpAmLI{LcvciU77(X)eHiA#?Wp_|pR{(27)`
z@Q+)Ox}4JFwV%iq4~L~kwcHL!$E#?Kh#x#0RTN$5_TqXMvXLEFtnxkbp8gqmA5$cW
zW=W2+YDyQm%-fn5-UGJg5lRl<8RuS?ImWqjQvmX$_ZN?$;M@D|f!5&0RS6O=hYnAC
z@bfl)9~Jxv8Pbvcw`vN9Zc0ASI`ZW~95HXi=fn9)xbN7pecpo}`FApgZWM1k<iM1_
z<+@&T33V6ZO2&L=W`Mj>m+q7E2*E5VuF&4IQKnZk^G7%60Cs;*y>L&xUE%XfOB81}
zRwqvSw41`CI<VC@x?Y_T8`~(cD9_?~>f=r)%bLhL?7!~I%-)T)LB>7z%sW{RDyZ+v
zf32X(xbWJVAWl+7Kjf4X+Rs-yS2=#&+f*1{4I2po{PW#k^3TqR1^iQ1{4e-t$v@<u
zZ~sI7DKGYue|`h}Q;)|#4dPGT2mEtC>S4QSO#y9{Z(=j@%9igUs2lwI{|`L>4?O=3
zf%$(6c>bzZ=D83&x#`Ih&i@j6mL2)ugr0Ha_oA)0A75WRe0Cok_wbf1)z4&NBx!Kg
z?}p5?6L(g1x0KO-vQNK+Z(ZgCj!9S6-sM(i8aSN=);}vVMGDcue9^)4m6?v^v>z?2
z!<9UX!2A0pA}>eW$w~{_8T5CV&GYE=cGbwv{d+2deL~nnznFasJGkE~UcLGRUt-qU
z1u|jA*M^@BZ?<`Pv!v&S-IUU!l}}^L{xGMZxSd<Ku^BP9e;p00v0Amy$pN>6Yf$=h
zp>*Te^-855Dq?feje`4*5B^XQ10|ip)juprM-@%H9$0%u^VDCC-`WtiSPo{t&g*-{
z1`8@SPM~7L?7iY#q;ZQ|vGF?i^i_4t8-=M82kjzSfg!-}7qkno(YZf#q)A{RrSW@i
z^Vwc*ZWDP|&jmK0+dS+7oA(txt7E_6aG8vcxxolXeEziYI@t`AS(~pKU3?^Y8*#KW
zf1-)!Kyl5;NXYlM3i`#MO<Y^Rk_*4a@l?6@k<$`8{Jfxfx3HhR&<XJAw-)=qWi#I1
zyn&~dqL%{~;pw+?F2W<xu2<Rzzgvr@U+{|C#46hdXeTH&+bji=S8<#AB#UYafQ-jS
zt<yzrW(9l0P%lls?46dmhCeij?0fD*+{T%~yAZcsa$K5@y)|b-F}+8R`iF9J(xYbn
zKlLE~MYXvUI~;!bS0CXGrS?{*|Dx%I!)<z5T>5uSFU~Px+g?!jKKd*)wM?(Y{lE@0
zp!2f*T2E`1n`5UUe<XHw1kYd;7=MNvf<y%{qX0(9^>W|~avzJd0`115CAYE(-%hr@
zYci|8_S*Q!dV^U1C*NHu7Ejop)&4tsum5I|5^t^9$2FkbTr3x6bLUlRZZ||eb4l~U
za`Oj+&vR|#EP|2ei}Nq|(0NO!^|`Uji;~yoTHV?HzCiLC>X2Cc)Uhc`?SylTnFF_e
z;|!0@cKi?y+Isb?FlhzPn^^zN`C>CogL)uJci-Fnhaq^>eiPiS*S8z(0zbsvyJafk
zEqAZ=1#SShwY@s|oW)`9Pm>KnKIKE)8c$+ni_I&Qj%zlqQ5m<*OXp;xk=sjrrx*iO
zNm1WTLnnT!qRJkG7_LXw0j0(@Ci5mVM<$s6?QuM!8z*-zpuj!s#hS9}<W*b@&2T*d
zAauFx{~8DdN{i*Y+t*i50SrB3@}|Z9WWk+cy-kNVniPuvm{GPTY!18@7S?j&-4C(-
zuCNtPOH64sKu7Tx<*fU0Wx!{RC!JONh*7Z8Aawjm-kjwAk<|#`Yau$VW`7x&2WjM|
zAKGJX4A~{}Q9bkV;Zu7-OU?jA>4Ij%t-*U@ijLg&n|saAzSn`CS>{$&y)k`KkWk2u
z{n3)+$8E_u(o%Nt#`l(-u5DiP+0M>wh9^hQa9eU(cP<Row;0d0<S2laoP+hCCC7V|
zr|Pt=jb)e709$SMTCsa8)1wMD^NXmH?(VtPz_yJb<9Xx?H{<zbJvZZd)U?}pC{qLk
z>ghZoX}#OS-&+H}ddA+l&#i5*FydM-?*ZkDJNLP@ZBK4(d-OWDwr#_$ZA&|Y+V<U&
zx!U&E_1xO_m-TbC?Mz;6Tl1<^9ME$*((L^o>p4~81Agi`VYd*tdQL+|27l6Xx|{VE
zdQO|6MPR}=xBqV^e1-IH`v2Eq<hqXkQ5ZS+XdWZuue?fCtcA#L4w_n6)_$_{?VKaZ
z=XgKwWvIdfK*_R0<D-{x`g`|`_4b#|%CCI>sZC37m+C{T*m`bul*n0#lD+U>QF2M`
zzl4%||0R^HQCyxUrv-lnO62Ofyb?LoCN6f*&p@3Wamu1^F5CJ3!_REz?p(!qMK7nX
zZ(45ee>l>U7;bZRIMTnfyKidXLgdFUmW1fA@SXt48(w7Cl<f*IvfDV>@bdAoH1@Hv
z)Ng&Q#ig%q6#G0HI*J)%r}D=g-g3oY5I82JecnQlp=h1)pZ&NqsM0gzH`@0AJzUe$
z`Wvt3=RaVUxBdlY8T{f%ZX4TBXVztW)2W~`hhtX4qgr?82S%f$x1p5NbNyQ<`99yc
zTZD%4#3&$jscI!Ak^>#z2TS)J<qeEJ;rCAZLa<ORXy~_!_hzazfl;267T5mZL&uCj
zp0j0@W7?qE#J#@Nz{}y#YyWpS#C^mRv8Sg(1fMLcdrG~Z5YKW;Wt&Eo-U2yxHR0#m
z;H|c)ksgO&kZ9qX%01f5cY0o(5x!|}LCr{h(~6pcoT!!G*uQy}g?r-1>zq6kMC<iF
z84=b^+B7fUMAb;R=_)~|9?}-Q(NPEwa+@EGme?m1D&3pC0qeVocoNY=oS$FcL=@(I
z36e0=g|n-&!u$aL0sdDwj5P1*L}_{+i|n(5w-q>Bhxar@mty`IS6|atEM6>rK$7V)
z|FmmH$Xj?s&^<e#qWwgbo;Uw=zFPl%$$?k%2aaOSn?-}Hwj-QGJi7ChH%gxo0$fD7
z|3Z^7(x~%+!{V<XuM#KJ`UQAT(*)Q$*p*!`l;(!8><It2<J{x&|H~0?o)_Kx0B!F^
zTnYOoIXm)mXr++0Cra4Xg0<^gQ}dHrbX`^6ptDP$C`zq}cOnyYdh#CebLCKcS<`8|
z56$VJ45i0KeIwh7Vnr@mXgoN!us3C{<L)0xqWl`O{XuTu>`Y!5*;>p)`PAtKSevJj
zTW7&f>z_{&#|u#+&m;t82j-?!>@3bSOx4Uj3sz2ZTm~<(y<-goj%~aJs)5`KgK!^t
zK)Cc+qPNi9zZw!Q4nABOxoNnQaE$ZUnq^MvXhTi$=U|ac-<e-KL;trLxYzOj;m`k4
z;9Lp9FYZ5E$*rl8?{<X{Zw=Pv)D#^W4`6-$^73)VH3hM(6?^`69CX`9voDjQMJAVO
zHB-zJ+Q)QzH}Yz2{^t)~=E;5^nV1wa4$weN<b4q>Nu;#L-Ua>j|4Hu|;b*BHJ#wle
zqZVS)e(e^4bF1CSQVCgTZMpZGg>^&5guO}Im;UnAh)XZW<)b|UEWbRno>LFs-*4eO
zb?>)fv$?cMz}@NRVcB}QzTd{OAKZzK%AAPXhvh76e0>!_Ea_?Jf7$O=z4`th$3kz<
znEczuLW{IxZ!L42*m1pI`m^=J$MKC8HH|%kb?PPO5GyNlrCi&;4W4=FzuJPQDU>eq
z*<QvB?e_@o(NlYJAoRmk*KWGS)tvqE5f<pW4&dBmykh%|FU#{E1RT2${s=hG6COvY
z|5Vr6*z1{A`m&ka&G*=cFOHY;HT&;VY%f(yqq>%)Dz_^e*XQu^Q0Lz*o^ba_D|u3L
z=v#el^~U-f?V_|YQ`itEbifyg5Dxf)pz6Kv-s!WzAQW_v0PkTem`Vbfr*pvbPT0*)
zKmMz9UQ5b||MI;5L89WOWrN342f!i<X8a<Ue1Fb2As{uL)N~3en7n;c{LXngM^Gi)
z$aM+H&thF|Xy$6_porfm?7bcoXD>dm52&$j7EMj?-Cz#rtLx}d^p8e>?HBQF6vktE
zqLuTFwL&Qp>DL|0yGp93>EyKs#$yVaf=zGl0J_VghFxnK8emh?NU;&s7g;0w(^;Me
zYPaucNVjjO5b1_)(*C`B=6Ln&)Q|s5W*g*QO=n)-Ig|G!tz`Ol*T)ixdW)MUB>ZP<
zn_kY2gia(_<xlrNMy!7I-tl5@k<%f$w5q7pExWJQ@E1E3Kb#HU^gdy6;m)8^CQ+z;
z)WU;}hIq~Zf6y)i8}Pe8!{AZd>;&OW@6lo&>~=x$6ki#~Fi~$7D4&+~CF{)sZIT5)
z+;u$HKT8FhgnF>$fYkYWG*{|8d-hZD!-Q4fBe+uM4-=v`y+`q+&L1WO7e6ExBfz`4
zQs<sCRa~j_?AbY~^Y;lnbrRk_2~IC6WflPmOz^UUjK}N8KYSB$db9J&r(iP+hC#t6
z%_*OHunl9gXJu<nZr1GHKL?zUL@8h_efP;P6AHg&I4mwU*`%zz7P{zh^VL<Tg~L@o
zl5y+2y)eLDH1JJ(THx1~d(TIbZKVNs%2)W6JK05sFEfB~<$H0J0S~KkV6|YFs?2SH
z#=rpt-$Dry#ay5{5^1<F<GrWpM>B8n-I_ldCyK7k_->pi_`Y^q<N=_*H1!nIcnio1
zG`yae9H=wAdulXljUSbp?9RNx)nE$1{$2}QFm@?l<e#-3A6Hx!x91`dZ%tI9y?{WT
z6l5z|U5Wz3b)}*LPLJ3JOfcOCH_P7p-WWa|x+dtaE&l#aL4)BD4hi6djupKy!*Wgp
z2}!ZLPv|~4P;DDM^rmY{r(*esm;HF!t~sF}oj|8cf;u%;;mafFF~OR?QNJU7a_4Kv
zANej^AT};`WSvc=^WPbK-04=Q`%KpM0d%FHEF1`f6u*V6hs(lkrAk*rvcS_B0(ugO
zTARWkT1lt))r38iA@1A<nI2(~Vc?eMz9~uI!{d#DS+%nUH>aCx;?1yBWToEna@%Kf
zB0)bo`Am0#PQJ4ip4Xw@b6e$5eV#AdrRRwwa}s;jWlh{cjiH;sw7A9YQ;UMkIQ#6{
z-fi3-Kl7~v@Uo^g9<GtBM&Q-1E#hvjDsW8fWI#0^w-x2O=`Sv7UoT34N&ryB^K|>8
zD&D`@Ma^2@;%{8kbT@Kc)CMl4%)6-Ft6Osnap@*o(GOV+x>-z8><uG-*J)pN&!p*m
zEBp5Xq!IeUznC>E4}mSSar{-_z~}t+7X80dLI3x)w@jbeH~v4Ty#?an1K?}}w?mL8
zn-g%6XD^Tg6iFenaA_f+k7H}D(j##9qiu9?p2Pw>#*E8n1@C?g2d^f|52cQ+%X8<>
zW$d%!HHDOJ2W`lKw*%L?Ozmf91o7!T`YX-2gV&!wJAgLu7WO^~=5#?;!mZ$}7FU4A
zEUH1V=-3Ydn#s$T7Tg{OsA+AeP9B4W^sJi$gaG$6{-V9R_ndD@8d`KcD+_sj&?=-Y
z^Id)F$parlG%B6}$*(o1=0PFwWGAa#a`rla1(_TCP+N(E`$o^jb#9P9Ss~Uw*(%7S
z9>EPxSr=!2;H5KYY%G+k9YY?E=b`_X%fUW!=3~E9Ik%tqq&Y7o1+-wdyjt=d{Z;jC
z0dVw*5+x=kaz2bgH^u9mwz+(4XL`W_hn%g?f8V~PU3lHjhyz?7=S4fyi-%vwzZSdQ
zpzO^AeQkbcgdnRNcZsZWw4Hpkx%b0bn?2$V)_*(j`@+*RB7SaM=Gh%5q4qbzsWHP}
z13W*{t3`qefel;5@hGnA+PjZ;xULLX;-q~8vEtSUQfNdKNd5vBTcTrYU&xD5o2Kq>
z;wdT++C+HBv)ryGE9-r@G5KbleMgnMK-f>2fiwXvtkFHcYGLu_gWDAIzANJ>^0z-Y
z7E*9|@QKo?)7#t#f9$q4sa@D@eOmn8exH?+{IV%v2+#iyH?6rK;CH<Dyfn^@rxBuB
zRUjwT1F410X~&kP{43hAuqX!#v*})f_fNOmasz1H`$IQfZVNP=BgvfN|K$BlsW*DX
z?nvWZNu6zK!Z(6p8+Jt+ujebzvy<A^E0#qX+Mgk?)f~5s`(V9y?-||aki=!BBVvdB
zuhopd4#9+2bNYm5BVHqws?#g@S`S)H{;to+ieFtSABO#Ho#znbJZ`I;1lQLi+4^E^
zPjCF|gaC7i4iid8-7{TD)N|A7k8r{Rki~eSpW<8pm&4_@&4Q2{7BKgl1M<7tj9w_?
z4ujvcl1y8`{#t<jZ8KWW7nlb2Hv;T$uHQ<*`3I2o{DEmnqmL>r`f7;gEz_HCzulJe
zwFbOx|8~<C7bcIoHC2_gM-`g2?aDZ`xLQ_BF@!Kv_7sWXto}GTvURGuJqv4OPfxj}
zoHf%ojbHaAiq04qV^3enyUrW47IP1ppI2<3Dcr5<|z1v2SD+u`S$cH;49O6{e^*
zmAXG`;h#CGueYR8+MhV33IO@p-sf()7gwRq+{T}p`u%dRP0H>)V0ERgmOOXZ3}YR8
znDQkeCQ5xI<-n?Q5~XwT;C*v>#?y;A19KI0lc~qsUyWt&teq2$_&DL-;#qd!$VZ~r
zlCHj&4&W8`=U=9`zimok-o^S8g|4Qz#dla*2V=m@kn?^)V8}dSSx|A*&okl`LPGTO
z_<{8JApiMFdu(IZvit2(Q&&!Gvk3Z=FG$D4)6a`vZ_ITsj2-Rl-pDHZ+!oO}Z(@?7
zFhBI9HSQ)jIPP4?PUS=Sj4SQK%C|eEeX89;)O{O!7Ie`^9Ez=P53_e&fm-@jxZ~sY
z+5Gws7pup&&CD3@H>}+BCS~a%Li2gaQZP#i?0=mLZc-zh48yHH*026&<|;c*i`l%i
z%)L)w;F<rF!BpC*<61L?6G9$A$ekao%Mw3tztC)~cf#+tjsVRT<Ccx1^F6TxF-NCm
zvfnMcy&?}gI<nk-bRV_k^1;+3OH_Wn94NBY%Yk8ndb#bWeXaLS6me}tz|cGQ@v-;5
z&w_sM=ypO+-yitAdrF~oK*2^Ur_uO8;k(6zqW#>$mioi2cbgZ7tj!L$)=iswFZc9R
zHvQIT-F5XZ?5|b4Q9qmhUGW~s-h+rU)e}URcT}^YxyqD2!!n(0>h$=@>9c#Mi<8Hx
zX3hAoO&^}xqju+Dw8CoNE4|xYuxC~Fj*@N9zmXqS)K<IiSY*1z>U^D(@y6Y$L)!z<
zPl1m-$%WSwDwY9(+^v>+yd=<=Z@pDRi^Gi*5bXh;r1gR6UH`i11ZDHXU(o8^NxhY?
zmOoJ$O1;><)1bJ!!n{?s;ri951pC`kx21aLQu>A8zQ8^7&=PvtKo8Iup8XK$0YZ;D
zy%#OsQqR=`3;@5M-UZKCRO(>>)yqDe<n+Ei(doUj?Nz4Wrt3aH4^VdLrt6$j3x8l9
zUddW>cQM!`cqh;U)XSdJ1N10V@z8UFfsX)sfF647;4^u8fZ%s=4?Um<==6S04{!^6
zP7lyyPR3R*dtMKaw@+(FJiyzzdVpKl8X|hI1$uy2ne%#p;PV#h0baMB6YbH<&S~6Y
zG4X;Qav1&<1|1UTD~8?XFSaT*KYt7mn)UC$AZB(vS2_y;F9MBQ`LD26!Ls!q#fQY1
ziCZu6swnPgN%Yn~GZ3$~KQfSVq50BBu%?zOgIh}CDzcr@^A&Y^P-C&G{SgV&lEP^0
z$2+)DiC_P4>QvM_^VbtES?@z$hG;(G`HqWEvqNeTBW^R{-%6U#SRXf%8=07t88JFJ
z1}mf1Oy9E@O~+R5@=^xRwqCYTuzc(ir2QmwyTswWz;nV}T;+m8%!I$a<9_G|3fFTY
zo(5hNn5sUOn07|sN#<gH%T@Idl?&RoymtW438ehty})w<A!fM>MBb7xl?%)8mR=v%
zfxm-Tt^%j>@LsOx#0Sb=xaBG;_&cuWMB2uvV$FHa3Gfqa_zS;^!kp)X=A7pQcbmX-
zBJB~+bAq=qsqB%9nsc5LX^%8Sz9=v7oN&~cmjhK%SSSa2crQ;5)bSb}>|R4n&sYI6
zDky;JSArOGyA7;u+D2dQL6q}lgO@(+t(^G=i$X89t``49@ILBalho^Vn(^r1&8dUX
zPXwukV4rGT@Pa_KqWaA#CqD2Le?wI`w4v%;Vy~CzuE}iqk_&}pyC*wkfBA8i+Hnzh
zuMoT;4OLw46#~~7_U4qHRd;;0SQMHoMg@LT`9yfg^InP1R_cz|{s3>Nn)6;6EuZsV
znHrk&ULnk@Q8iR8A&u&v{7M6V%Jp6uEq9RlluY@Vf#~)6?!7`-C`Ywx(v#=CLeOK6
zmYZ(ztK#Y?lazU?maz4}Cw059|7mrv*?Zht^eLeq9Xl^1&HiD>4rZa@=NTiYtreu0
zD@KJ=zPkJueQdM08;p1`19<+JBA4e2FXZ`~{$rjm@^W&uHrw!g#ToqtW<nk-RwMgF
z*CmJ8PID(5zcK<l4;=}J@AD)sVOB0l2s)0MCH0gfW6#*4U_9kX|HAF>IUV!HN~EBp
z%`+y_#iur&kM`@U0H&It26|az`%Z;ozgp!F-79`~uNAb6I?Z^Vl9blV_vDr|xFRAC
zfER^^nuMS#R>H-8y0F8a!l9N?&WXHtyfbl+-}0dwSOg=N9sUHCNs)|Yl)Fx(Sw|}P
zJILWr;DY$jEexbjpWJGdIQ%J#yXCwud@2o}Y+DTGGE#QnC)n@@xMdU<>1<m@xfcR=
zo4~tOrD2)iAh?t9Hl}qpve++&>&cSV3)aV#1?!{5;QRWp`el85;;oOCO1fp#_HG_y
z^9!`LtX*jPB&VmIoyiMzl)g>%GWPDDVK#HjuIBE>)JkEix=Kv<;cGu1GwZMT9uVlC
zj0(KiyAwB!9ZQKy@N%xnvw4eqGD`H_WA4nt1{F@m88*fc-`wPf^!OIHLBW3u0>J~=
z6HZQD#i!2jieqjncbMbw3NgCy!S_6mmtw@%3!TQlPIiiB%L|~a=4LxHN;Q5Rd_U4{
zyu~xe>iDhgq6twx&K{R!Jk9_mPXBekDsdj2c94<79oQWG#MA{Jt6XXZly*n41_qd6
zWt)^fFoGnz^weom?YGC<yOh7}6f-peVMXDs_Lc{O?=m|aLl1~OcyJsze4kHAItB7)
zQ(s4S6_(lDxiBUp7unQ(rS3%SpvL8L(Cf5E`;2H|B&vAGR$lu4CPLm-5fR($lc&Sh
zK5*!pcr3E`fWGYaKBr&j-FbsaPkqIfbGVudI2PM8_26mfN_ddG5>K3#atoR$EWowv
z3;uMuAL!4nX%+oG^`Y^;^?Uj(zRJ92o!#)I=$A*HV4e)cZhf*U#r5<wwpQE&Pepj(
zp|QyaSMeg#5AX_YZ2y%z5r)&dJ4Phu;$cSWSZYdY%j3PWS3ywhFZ)Vyfi0NFQ1!j(
zW`sePzvi{-?u0;}*-@)^N0w}CEgjp4o#~fv?zB8Pi(6b(pf;1fE?-b{^ms^}5u4r0
z7;L~7HQb4bH~T#6KW0rUUkWmHt{>J*OW6sgo;X!%S9T(G(Osy9fZf_R83ICAF7TZY
zw=!FMzfXVbr=?5QdK_BXy*REV`QEPCLYt{iFMD5JczH~j8HSG^3%QrDzpvmzK|%cf
zs8#-hhZ#}y*Ox!Xcf6hOHX(F*_spDnHKjXJum{t1|Mp_qR=Nmdf_|D@L3K-dok4__
zWOamY4xl%YtTIYo7)LvreewylV%pPGsEEX94RhOLpEi#21-m_lMyq)xN2{Yn`?4E<
z!*a~-kBBmY=_8wOsZe{#4fvKMtIT%3F*`zaQf#}}4$;2T9OF7;3vqMG!4i0KLq<Am
zhgEW+SYHl?KL*7#rin4lcLlzUitG6>O}$6zrMx5cQgv~086mJq5T;IQ%nH?*MIOSz
zA|SB|p$O(v8b7tfw8kGA0!OU%6-A!s=(84uD=PL~q}!A7drs0#jr@JZt(5XN5L9}K
z8Wj)4uRWj{1F?`5?>=G@msBybHC;ebr$|h74MEZREJrIwo;`eRz<B>QV{4(8bg`RX
z2hS=qgqUHpOuEDCFsn`7_B2gO2+lEc7Lu+rb|ytXCtq0AzK{=@g^}ofb!Eu)rs=YK
zOE5BQFGdWrGG=|c&LqE^S_`Qq!;KH&>?>Bd9$RlwyEbK7tcGClo2F`1U|fei>BYG+
zY0`^{`z5#v*`C^@ilD1#J~!<I(V7~CVCd7EHF<529j{XdlKnIE$qsafUFB5?Vux06
zw!>@89HylY1-14FuQ{w7yG!3)Up$Ym275h5wfkEW$%dxK%%fePqe#`12HPk5@ztaj
zd`Z$^h9O^(tuG9j$x&x%g~y+GL#4-)OEMzJ5!8}oH|>5tWGaV`b(jfbD9}w#3|*kx
zll?PGlG}9*A?=zdF=Pryg5?u#BgBlQ$CC!}=@7JSC11NPT9}Z*5r~1ZMHvosokbJJ
zz*gn(=>mot?E>gE1QE<KHru2+#Q4(=#(VnK4{DWalMwU<Rer)Lj5X^Z(~}lRX(e}M
zp<rmo%Jj5>BTOVsiQ<?TqUDtoqJfqmTxe9rh_a0t74&l-ZZ5$$B!y_E!}?tf`1|d^
z#&u)0Sq4lmS_8G>$>$a7lYIU5VADAmDHf9HLYtztCn3}l1hE-CVk#f(>C+@<YCSE5
z>Pd5?<Rs^0=HL+8L^$>g2f+#p&najNJGuKM?LA$Jfv1m?^(nQuA`O(J?}iy=j!C_$
z<)lBQA*o0k0rPc8ODfVVf?*3W{47Bxo+d{{B%w7Nt-6U`-J+aTu@IJQxLD(HjCITk
zwk4ySUP7wML<tgIgA?s2N^~1iNY+$Rzs6uvzfKX<*O4I1k%$$Hv0?Kw8t5qUSmtZL
zjB#YWB#S@XfMw5I&Tym)($cBUq@s-e?oMTQ#R*N8aro)OJxbv)mMAlnkpuP^#uTJg
zQKE4~9irIG@y5lR6|r$*&1P9~$wbX`Xo6cM->fY`nWM=zVz|-W$SAz~%F?N0jY=#p
zrX8)H5=-l+`s2(q#{_2WeEDba98H#CxTu)Stj;84)*dOvF^pZpLNTv4ld^C#R~sCq
z5_Vwu^VjqVR66!SaqZveg)|ubGD)18O<PBIpf%H5tS*f4AHOFW>@*|Ys8VkOyWK`f
zNzB9RChf>@6Rg$h7YKI1E@`x3JBJ2_M~IzyozZ}Er}~is=-X*36ffNCtRlWz%>@3w
z%pNiRPX&~zq-Y&U!CGCfM5~M{$k-aJRHHsSBGj^87&g?9X@#@Oa!ih{9a_?J5~C0!
z$<(CTP>0EJ+apCsH@dda5<<dJp>pNH<f)8y*qAdxp%D=)yBf#guhWl>Yh3#&q;o}`
zQta|NEA~-?frg^p=817xMS_zW3F4zJ!6$Pv`6)K!cuGs6q*jses53ztvnX~2YZp_8
zq5k5|yQ>46z)9Fme>ahuu*f(#C()QHnLLF@!TdAx-X1#usfWj?#qz~0VjpJgVy>X6
z(@kj?>HXv;iV9;-<Z27)e3wE#RaYe3IvInC(PF!VrbXTZc%$+;+3Zvg!aCPlHs9G-
zK-C^AfYD;xFt#y?v@rV4&zGXlX6wXQTS#I|*pH^$qT`yD;L_EJ5ac<IO^k+xtl=3v
z1)k^!&I%r2={UtaX`E_^6Q%Sgm1OLA`yfIu7QrxK%7?161sI2!;xq;NAjyFqLV7^I
z7L&9>J(@o!D_tNbGaZg_BuM$VVwHV%gQJv{pDg!AFWix_5gg5G$}!qYIu~C;_}kTq
zFk}+Pn6<V%_;Yx?RJ}QCFLN7X8QtREqfW=;I|Y&1908UIGv(eR3&o~OF&j|0Mmg5T
za5L8O@MWw+Ob1#l{VFYjGM3z~ZBA;PiKW|+2k~&6q1s^5Al?vyUXO(|CISr7U?$Lx
z(R-(Mall!N$@HwHIa9{TIay=;=>455Sm8`Vn*NQuHj5_D_sC&nV*$v3J?+W}fuNmz
zB?xJp#jGRY9R!Bv7(d}@*$##aSUhcXQF3j@7`)#JtJ285nV5yY#yw)2Hc1Hd+Z75C
z@E90CnLUhNx*W+F9KbR4S_}Di2~2g`6s0A3Ot**+n~0HR*)gkWDU|-ioUB@u0C*V+
zV8#)b11>`BbMQ%ibWd6f6`fRcb7*4IbE{Z11HZL5*(;-!?3O8)?BxyKmJ7b00yBi>
zPaTo4@1xJq2Eoc4thg&kv?T~~E_q7QawzCzFTB!MTr;@n(dv?dRqAf=Ds8k7Hk)IM
zikNwR)0|wjV;_uY*SAbM3}AQ&z;J*w;=Yc)V%U^Msm4N%IBREk`OK5m;f9PU`e&LX
zMK=khg%+GS!I5G4F$ZaGH;zz#m(K;K$C$Z@F}U>t8J*D%PuM_^ZcO56u=JUdv?^*F
zjHU=yB~cq8+_%0^cqR?Aj1|YcOhZt{a0yx^V)t1^jc}Gfa}&dmzK2moKTRTL<|HNP
zCJ6Mc4PGe(4o@EqMYRBjIjm`a(yUIuz)VV`2*;4E&q&zXt0<kF|6vT8mX!`G$#8>r
zY4!_Ox?yE|5;@X!>am0B>vMV#J?E`udyZlZ>XyX{$5=7FLyeg_p%F}1d!rd$gjnzf
z14yk#5wx!mqf}?g77tZoj?p~y+jh&(;w1&fY*j^roeKqn9SH)Bnru6UE4_<swc{%!
z*v-{S+0P1`yPY?_kQ=i6lRKz6xM)q3$mseR`9>=?DpWT-<<RXF;USDdx*sVnb1>No
zAM(&_Hfm3|UZ@;1hZaxydfXmCjZ2!;loa&O5GC&f&^oExFEY9gtJqV(5v)teo)J3p
zk@}J5ONY|>=ze54APSS}{bI<BMyZ}0aEYoh`)N38kmDscjY$E7ld3TCj5U8x``sm>
z*F3#wGcWEWR#S=+;Tg01l3HW=xX-A1!<d!qrHn<x-Xwdl!zq~v2*MQ$&3EY&Qgsc+
z9%a`WG)?fQYe~Wfw{`I$lQFOu8TJy!0YJWdm@PD;t@o1BwQ7})nK_M0s5+_&B2W1U
zsJbCVF($D_F?_KWEP3V;#w~gRS(<8<*32sEkyh3mOw`@cCHPpgoqrG?!Y7weB;ck_
z6fJa`QL#?#F_R0*=~1#SuvWCj`G^>3w8Q1_W3ZeIv|vsaQ7|V{DU}Si0`+lytn4=v
z^z5d5T^2^K?i3(|*CJQYw$md4vY-I6yjD4Bw5VQ=B~ac+(#<+e(gnn_Xd^)uBLeQ3
z2C+6Q4<?${L8)lDB&p_~*shk&SG2(ZR^(6!N9HxkTc>lDvy{O#9YOutyqn`TDunDW
zGiM0WH_+Jh4zgTU2-NWAGdOzfj96nv4`b>082NZ4%upj;0KF$00l14bV;?<_oP$U6
zq3vcQFxs(GpXFOJ;*zU$(xGU3qy%OKTZ$1$Pa${V`(gdIGqM;>i?0W6M~0gNRPkY~
z*!qpOgE~$=O`XJrXjTE@G6TcF>%R(o8KzH@qca^7$8_2S4As&61aS3Z3}ZD}$naN2
zlst?O3mOgukm3L!B^{TOg@U6t24j~u&(e{!eRONaWx(3gGZBI)*BN<^Kz-lZ4~y&J
ztPRYy3=w9mblV-i<2GWx0ay94xjms$CeNMVoaO9o3_a#cfGN(Tc6>h{(RN0Oqfs9r
z7Svi6!8jPM&DsZU174K&#I6jYV3l@lkywz1e-c{L4Ni1LigJ!;>#$sy;fx*hXi^A1
zL9j|Qq$p)I6HEI_e?yC=I?yI5gNgmR{d_YdJrp1=CA4%(DsyueJ&ooD?)@n3bXdZ=
zLcy7Qi~^u7O*BJl2+kZ_j5DWtE<xTUgm>{p>^!kslhmK(pJ?v=6$T(h6F|y4E~F$S
zXwAZAPWBuW0S6$MhNjq)h*{%gV&))#lzspyz7jLIMhT8C+mV5$?{|M%Ly1eARY$;P
zaxgM1RQR#aDa<1}Xo0k>oJ4nuVd600V_mvR3EM(!M<K!Mkzze3tR;HRW0dQJ*&9RM
z0oF&+{mE@N8cA)`r)zqQ^$kOv!`(vlnFm0)v??@^8A~$**Tr@E`(p!&YE6B7W41Gb
zJ?DB3S$^{l*JY&9mor>nm?lT-<ltW8<&vy2#$aP>d<FZmITou6d_rL0TlA7us26Cx
zR6MDGQj$2S24X2ZM<&LwT!LIs@#XZ&8Qo}sXmv@*7zi}_axhR3C>4M}Nt9MecOy;V
z^JFf^<0l29b<+hVZw|qG@ED^yIkswO2y>XmPa!5xWpp@!ZA?NYwbS_!YYhYu8-0b4
z_ni=!rLmDG>-$=7BAh-+!p&DW?8HyPCUpk^qG;2gfcWxPe1l5<HUzgm&ykH0s^6>t
zcGd>a6@GFGew+;M_v9vOEzWV<N1S7pd1Ay3CL-lC(Q}rznf{dal>UxX5ALRZlv;o%
zRnT<pSpil5&IF6wxE{E5AvhNY!ewLl*dh!gI*5<5`UTyzW}$^^gT0bI8`aCjtcq1$
z-R^|Qck>l8P%{*CQ?II6*~L(pu!&KOO>sIiOSK_)P%o2=Db*k(3ItrmpQKH%B3-4Q
z^L(OM{)qMt+;Cf|{>l2_8qcPilRfD~k}<Vl|D_O3NqD<X5d>L?v5ApjZ)XV8+sV3F
zuOI!+DgtY5FVh21mD8jMYAdNEtDnDUU9gFgUodlqW=!!T`)9cc6gdzUW6WY@V^rC2
zh6VlkyS6*o$G<|093S%+xgq&6P__gE!?a`^qbHC=DJp}sBNQA-lzNPIn!EfdlSzi^
zL}9{N4xF_rJVhFu8A$=OodF*@pi`Zt2O{k93QGaBePy(UNp6oUMkQ7T&=gq~jQN13
zM0HCJ(MS*`T<BqHohb*TE<_u_@4FGHfKiGyVns3aX;u^zZcJ+|bQL&N1P}~K1DfKW
zIHuk&LdfA*gIFjX#6lIWT*Q^;sKq{8HjwMx<O(;u^GpD>(N_?Alw%R2Q2)l~%vWk$
zB0^JA0Oe``LD?at8}l(%08|bFP+7-trw^3u;kfl7I3}?sfTsupp5m441#as_nnVd~
zAx92GLzN`}W*_qr*A|NSx**}4-#m2zrWhsxOyLKZVyyyJI*et?6k-h1H5f`Dv@r*v
zP0030K5QOGGe)KUr2@D^PYPD)4kq_&dnNX38VV5Iuq?5Nw%fbMl2KZY?L2DX$6U$K
zrEg)BfOw;w;+BZgO^}#LZtUG2<4T#rnP;>l5jENc6I=*N9C5ZMqn3^)D^aieU#<kJ
zZj9PNMr9bnX4hktInr!*MmrrgzLKC7Eja6>Dms%2;>T!!g)V@xp(yC2S*=<mJm_?f
zD5n-s^8`vs(yVsB&`df<x!e26tmtZ|;AjJI<Z<M$;PM;Br=z-jrh>a=X~*e~q*RbN
zP{Jqho2!q-s5a}<airJVKjQK-2SG4Y1*=svgx6{%NCZ1nMkBePK&qgofJ{tFk~_5|
zv4dis9Ib`|Or;MJ>=+yledyB1-zXisG{&DP78(aYNP_;F+>lWOA3K<h$af94M!c_i
z29MU7gpauv@{O)76z#)dRAStidJJEBJE?%WOm2^lbKmru@mi7N`;sPs_1vU(kzikX
zqkR7EY(!6X<KjkC?35rl196EB_z1EMSZFp>FC2)ZBu0Zeg;|hr-079bn?nK^wR%LI
zVf`Wy3L!x##80!Q43ko_X8927`oeZ&>@U=*z#eN2CQaen1^hEZpprL-6s(`<8OJQD
z|M-A=hGCNGl2A$QoWzvOc0q(I0mMOAe(QXWXpDeG<YI6vf=@r{zaVd>j1h?Cl9fY%
zth52L;!ZQ7OOhP3X8F^#$BqaWDgYXOnevYOjv7I7#8(NpsiB0C$2kV9ZGiBdq%X<Y
zqij10P0NfR<3ZqW&Adv(faS)=RAk72WpSN8V%P+hg{;qdq%vSD;?_8fWgVqVKlB!$
zAyUjEq087Ip$ZmX!vXm8lHSub$+C22Yg<2`f*HccfxvH#=PZv|!j@(nVxnm8s8+s7
zM|3AarUl7|(O|D;YycNHo*In<%m`8lP9rkA=Y!K11&~51!NZf<L6XQn%Ri}I11*Tm
z<H!SW*$KdfNE-C+3YWc|)uVzzf~Cd>xX(CMF4^$*ka%Mv;0cS_nv6BS-BO#~!*r!N
zfZ*Gi;z!B>>?jA^5Dj(v1qsO<WtJ0DmsU=B8knIH>%}moH&q%XOz!J8q774YldEcn
z#4-Hr&5Ts~B-uQ3mcRed)r1vaPGFX@wlcLCdzb;V*B}8BQu|Pnfa6%OTtU>?K#B87
zsad1S=ewp5N=UIrU<}!+jCgtuX%bI_qip+Tj?5h-$xO%OoGfROB)**=wZ@mvcmGvM
z?Ab;rN51~0xO`mZqyWlJRmj)XfDg3+Dc6{cQDQA)R-2zEwi$o&V{~kt#ucfLVKh0E
zcv3m|UhSE!<aWFvjA)C6a5TVDcBYS!%Bd@Y0d(g>vB#_x8;|>l_y%^$vOJlov@S|}
z61sLsgafOmwt)++A+cXWQjqBKn7>N1NEn-f5e2E10FY{t1gVx;7||^_PV}36ID(M^
zST#x`ClLiQUI}Xm;+$pRHsMdNA{XJ6`VP)upWRFYoF$&jO-~Uu+~5f=NLc_aA^=*Z
zNJ>=0M4~1@pu$6(Cj)S18Vvz17gT07NVSwCC#V;R&tzj(u*|`w*AKE%=9xs0X{n4>
z0@wLYazdsg->i!&|4hqWUj}h2fi?>keg)z)5|);Q<}b-0!n!n-P-<mv!IHtYqY}aE
zRr!L~8bHi-+F|DEh7fb@e$l=(j&hv>n;!%~2-*_5S@bSIc1406RF9;v8@4wwL58;^
z@pVR(KuK0kQU}1KXti0fVCUd4U9bo7WUH){q-YH}Tr`LjgWU+wo}@;ZMp3p3qmu4I
zI~@MHflDP|(OT&+04&hawMfZEI6DeNK>p;oOq4*h&a80X>$0YX&yVm8xJh+{L|<2#
zJp)TOCMj%HNp8qO@Qu0o!bjK5d<-6sZar?gBl(s}tYoMgSi8RTTObD7!hq6aX~?bd
z$&y+i)^f%wVHUCd8D#pvq?#nNkY-PvCZ}Yk3r=bl@jcc;!$#c*@O%efVO8518S9Kg
z9HHPv_53j_K^P<yD;Bd9Acj0!nem3cgY=TFOKz$N6i8Q_g{W=_K8yfg*cIeg;7N{|
zj!BOARzO&cNq&^B#B?n~c)B(*vWT4*(L~@!I0PR-fj8Tb9Ct*D7TO|V7%_GX2!fnR
z($vW$-AuG#%Z)$*Hy!f?$n>JvkWgf-P+g+6to1RBYK$IxE6A?6)7F$D0b@x>^3RCI
zE_%lg$lU|_WwJK7)SRiJ<b8BFsU;K5p99v9*S4<{i?|;LNDCI^Z#RG-$N~gG4gggo
zLHgDU=cX0{DOw*~BLjkGUw|spAbsmctEamI%2EX=3ziRK2@*sKAeL*_8vAmSZNt|j
z0WESV6e{$;Dv3-1*Pjnlgb@q);~+lIIvKDwEZ{7*fV23KMJfKth8q1a-}P8wj1k+4
zp%LD?@4#sQR5>8EW~hmP6Y?>OSt3junm)BEu}UL>pOD-0cC)n?2yp_b_N1=N)1)qZ
zJ6}IYRbVt@O<6k3E?OQn6@f$4O9N2ZO?yBW2B1<+ss)R=fA`K-zkx|ju{dE&4nW!l
zstclpl?QSTs^LpmzRbM<SKP^yJGww>rIC-L25`}yjvzZz1KhY*HlQrlu*Ne!g4pMG
zmw?Pl11TMkhN0|cmNe$~?6tVv34%P4a1@{{pK00PFqTkHliD+K5{tB}pkUXb*tC46
z*4)81%rGV!X6YuPf2$O2%*8-K5VVJ(53ZR&%5b3xadLNeI?apf;$@4Y#3iA1{ge9D
z5d2uYwKQi*tU4=bSdlyoE&`(c3^%ia0GXBHlH$d5RoW!g0%TSm&?KpY$tVpF6rJbD
zv!t0;G&d?S8Kqh4bMjVQWGc;&GEG8fwIrK^BtJT{ogeU(#T@ZiLDmkY5-pXUN*klB
zC_H`*KPfP4i<IG92I;OMimr7KHs!(1auP8Eq*S!4_-EJ6sBo-eQ~X!1(?ST%;4mgE
zH~n}J3F(s)@Cf*<{S1U-SWm95^9Nzai<G!k<ju^OP!YCAs13NMegm05aS9rzlvTUq
zSeS6EVW=PT4NZr>2LwWbv=K^la$Y7{z+5*$IM^=uoAT(rY-F8mEF>n5X#ygl01yc&
zk*?DRi;RgU{kr8q`u1y4%eMSR(K;121cXAHX$2Hxk`>?qwYq5dD5yd79pjkAc!5OS
z;qX>DfGlI;qw7@#`U>*lqkG>A0?M)iP?jdzJwO|+@aD;rIw6x9&9hs5L23m@p7M?b
znU!{^Kga_|Ya0rVaq~i{9Mif6&mu!RQOXD)Eb-)fH@*o>>bSuXwn%tS%iZRjM`KGA
zCWPt?LB>Fh*$$E`ZCm}8uNf6Xp3N5o$ra(AbPV5WJVv1o#fFA1i4~85u;UoE;iq%L
ziYQZw@Eu=;Ro8$#trJq(`V8R2p&)T`h?zor18Ait#fp$@B*L~0l>jN2#q@XN%Qpg{
z={o(QkF|*+s`fKbj8;8c@xwLG5Rkcr0=CkU+=6%W^~2gfyxB^Yrc81Zw-O+6YZ{|b
z|HiwAKU^;KjP)Yx3)aH<j>yINAv@*j5;<xyB4D@l*h&nO@XKBx$u%ZX==zwiUCj+9
zm+1zT!&mX;WFSC#r5~D;ISWNN22U!2OI(#E!rT<9T`v#V3d9<ZF$ZjAAL9^66t&=o
ziD~{>AWbL0gfLFh<yl(geZJ<zk$v6oY3^XJ2EpB@$Z2K?MzQ{l5|^{_71<$WFghTq
zx|~U+Ra3nZ2Qv`@MfSe@$Q+I=%Q_rq&fPB&LSm1cb&)j;qh2r8n21qlX#n681-D2;
zodlTgTGv=n5CvGWwt%I+ifKe^rB;)?K#CE)fdI$IvSk^a;KC22wDldwW=?{_&|?9#
zTiU%KY((2lcanKl6<_~atPsW+<lvWp?bc=~RW-$Af?9?d_YuAYH+FMq5k?o}Zg$eO
z0kX8?axzfRetR>dP=sMUKM04&ARKZ`LV&jcWRU{M0tc0$kYt3;EDU=zzeaU>DafU4
z2IUtc5QBvQ_T`p=fEw05gQGU|3HjOuk8|n1FF=-C09jgyfmqS@oBE{oEQCOn22mWF
z)+o%et{;g5@L33oLzhX0na+T*h>{HPV|>IlSk=bk9PyYH^)pjX4ue#BAYGl-MFoKn
z2rT-w(305GAX6U1jH5+@4A|JVE++Kb&hkpqSe7HMU(+k8Ul%PhlgL>FQY^zD#X<yx
zr6m4D)H<XPXIZQ=%NQ*DLAodjoq>QPY`}7JwpJi#n})cE&_J*<*)H}?;bf3wNixqe
zgeN#+<vBKNafT$lh=j`8fjN_apM=kDd<>giQwRf;MHNt%Hb7bQ$$1ndQbL9jCK)6f
zxz(WrMnAY>5Mcc$P|Xu(HBo{!$QNv*)lO+xk$9~!Xr-enU!|LYfVo-`fAD&OXwQj8
zSkHNmRh@8bO8d$*K$1foRfU5=Mkv^oAkve}(W=vCyNBwB<J#NCHY>hZ+>>i9-*enr
zCEp1tnZJ&}-^kB)2;ISig<6GI8$Jo9>?B!%sIl*Yk65r<A;1-ac%x|S3V<t<09Q^M
zUhJZag*t-D%qU$dR2Kl54JeOIY7xcyPB$*@xzIQb`(gu5j{)5Xz=|g=9%M}?HBqp~
zY6&8vPOfZ`k-SEwIwiJRXmq%09h`j#kd*@Tg?=&9L*jMjAk75bT7XFf#{$l>WoFU{
zpl*c&MMX&+LqWtEEI-JyNV8TlCHlE#3Sj^&GIgkWDZp3+RBf@!))^cFP!Mth1tEj}
zOYz_qWKVS`HG%w@q;9|XV;z7Rt~0XM$vwL@3#FNmPzexc39$JXOPM&@)2$ZddiuKl
zH+_KGaud4g+U=~zoO9*7bCS|EP{OKiGg26n`uCIEATB9g9U+W7hY^X<0E9$~=}eOc
zxAwi^!-yxxK~0Md?#O&#B`>27lik7cEXg!a6s5Ldk1olWO7sV1db#ZZ$)`d5=S*n@
zNtQ_3DrObPu>@fO_3jb(u~QYU)Iz{3H4FvXwff<O4!-<_E&%PUW2cG$4j>@Nq<m52
zQ;>6#V&@mNjWHCXBv~@da==-N$e`5#Ygc49Du^t|=SSjvph$e95M~J*%6Lh?1ByXo
zq`{25nNy!ppimMER>(M&O#>taH;Au-qu2XN_}b2hVHR6_QyMzkD9YLc*0cktb>(FE
z;|#UYe1u1U7rg&}%)NO$)NTAXYL~sTuOn*_vXe2>h7gkM+g-|%J!Q!>wxqI!EM=Ly
zBxOzZ3`5EqDxtEBWl+hU%w(AJneO{{&hL4i*R!41Ij`6AM?>K|-{rdA*L%BU=NeNf
z9mUs@j^AGXit8G0v#00Q$5mO~&D|JUQZNYewY5>mn+ef@H6MsK;JubD=5+7zh;y{W
zV<dpIyaCdZ&|05HWC7=v5uDpT#JlsCtpHfw1F&42lqXRpBfG+)m*p$jh$a&ZEjSmN
z)koO~wUsy^aR~tQ+35oe=u<6>)Ljwau>fRQ!!7LWGT3HyRX}iKUzs7mW8nmkWn)qh
z+$<}{S@udf-EDE;crBA&UB}x7(u<?*(*{`3CM}{=BuEl2l3J^p(>EIPqO4c6eTGS_
zd);>gm6P%)>TRHxcqke|=c^DpyF=(~Lo<?SR3!625SI%qsJ<&ZjtB#^QkKApO`xiT
z8#ca=`fA@L2})=yhFA}WiLpfkWeJNx%b?kTvTy)pai6p*_q}~W7MIo(hX$XJAe|je
zki+p!9BJXB3Q|;7MgXRWcSlVM(*nEM0aiNW2(mctodU3L*@17Sf?P+Z(O7AxCgkPC
zDDh*$RAtJ^l|Zlx3C^?ZfigtKoj7o*tk%3H30)lthiMA+thD3(3^a2orkzyeXYz9|
zkBs@~LQ?#sz}ooaHPU?BMz?#k_}zt(RAaI9FjifeO;%lnR3=@>!gS>am;+5(1jmv9
zQ1l}t8(1k`;N2#&y+5f8k<(%~GgvI}A3?)7vFXkRi)9m}P$gqM6fXiyCMwQpy^w9>
z3Ri^Os-NUD`HQsPDhXa<(_MF_WwQweOGRC8f#e^?OS^!vFiqsUuq~Zvk-)QqFK7id
z1YjLL63JH}G+zd@q=73!H5>u(c^#IZO<5XCzjVF--sCIt2+j$d3&WDJ+pZ-`?5?pm
zywq3*715Awi?b+9n;71R1+#>IECI=f`P&u;&|=@po)*P`I2F+Bs&#o+qZ;}28q3PL
z;o7(@#}VHCnhz|SiZt$indOfM#YB(vv+&7fN3*91N3&-jSoro;GV{q7Yo!|BOf!h#
ztFMsEvruK?gC#`jD3%48PL<M2@WV)N?gE`s*p(1x;ylYTpRUG~x)05XN~bc0A8f?-
zdSA!`?|(nQ+$u?Fg$_XcU3_t=RUcRo<~#hzw6O|XEsfh_;u5l{>{gIx%%=%M*t`j0
zb0CDxQLI+-%g?WCX(VG98t!5ah99OJT;X18o|FN1MZM8y!Ta$Iykf&WB!i1_0XM4O
zjNiqwMatzUB+jO8>=iG*vmi6@9=YBZgh1WtP`p=GNrSB+UAoa$(v>W@lRE;KblaVe
z-lPlQ*4jXID5N_Cz$H7{N){67d^`t+Eh4+dn{*2NLPyd!U@h};^8jlD`v|PST7-eM
zbV@!-Tkk&JCVbZ`7P4kWfEP};BOpQdP~2CJtyTCJrX_;fO6+0<qvcQ5%;Ij0-GkAG
zuu_mDwD>4Zx!bkXJ}n`-Qo)KI3kgFk6uNR1l+i*rF*;DXenMTWF%5iO{s<Pb=Vf)W
z(AqI*v>3D|b`L}c%0@A?jF%u*BuSECcZ`?hHra?qQamlAB~dGT*WxE5A%)n4Is(yT
zhY5q$zc}wrVg&MZbnPJkOa@4zVjwQWU0~vBg^N;rAsM>4SeVw?l@FR|D-I`Z#i&M4
zsM9g>;jEN>Ac^W*l|h5x6qeuZ6N|WsVIVuMRZZHG=*bYMq>N=qo3T9Lv>1TX;@NaU
zwiGT-EyE<*ogOvs8vq-Z$O&<?47j-SKwJ(q8OsLV4PzzvfCHlf=Fupr5va>T+wxue
zn2`)LGr_z9CzXshSz^KBklX+<*p&px84zjUwa}r9gQ5#AZfFxdpX1ueLyA&aVT5FZ
zs1q+c%pPU5BTUt9ylw*C5_=p$-ijem4#&3BU&6k!NfLx`2m#@c?$|%RvKNd|_cE<E
zLi#cr&C}I@99EhKHg2;492><%RgBOft3fe{&|TU_yGvuEnNM8jgX6X*@pb8{Q}lxF
zVbt~Fsag$El*pj#YyFX6cS~^xco#7ToM;gk%fU;G-JtS7;GED5vIW5g?1d@7vVbq(
zD0cT)I(1KjVB<M2INnyQb4Dst{XX0-OL-!<r7VGQB8Dp5pwc)q0jqLCY?xd&*e&k7
z6Zi3Z#|o$_4a|+#h2iJ6Tbm%&`UW?r2?E?Oxk~0`%N_Bt+xRV%2+eteZz2OJi5I5G
z1bMBUS(yMG@7l%l>kX{MqIfk*5cn;}g4if~gY4J%C%3zCaZPEt%L#Of(!j1SJeGkJ
zA4|kA19^!6vn6>FMY5w??UAutQ1n2YfH>h0<=V<VQYM%!#ArTQ-9=b@^_lZbrTCVt
zP#k#|i@<HciUD_F4ZoW?w?h{M?0i){93YB#kV$wEj9!GcUM^KRT(9xCE?kWx^yhpg
zCDxcg6D713b}dJnWE76m1p=$o@qSi>X#tOvd5ah_1<wTCx#KJ0m#d}zkQT+esjP_O
zC~?d|NcLrb)1`y$E)p?P0AFQ?D$5(NaE*YtoLLcAxCX@K0R3q!Gpfq*F<L2R$9dfq
zj!guBO6<nPn0F;ddO&6&>|)#xlBj|uJEM}p-r?%53b`nb3YlW5Xt+Nhi6SHbS}p*z
z<N~ymwkqBQc#+dxrYGyl<O?u}Y=9#+l6nDI>|?EDqc~CdF0>;_wDR99IMaSehYA=`
zxtKlS1pwGkVu>4&H`#*0W66%QTH<SocG*>6RlwJB7lVMNoHjJ&+*`TIUmETL8RWhq
zvlhN056iPT@MtwzHFkH)on08##&2!(JIv^A)X(N_p~~j&ktqtW;s$B6E*LGkF@e%y
zNT`{B%V7cjjc&$#Y+zLncS|Oo37<n{B<ny=X0%(9_YIj?!oQLau2UG$<(6E?zc?ry
zD~6<v$;fU(+_G#vk{gbqw!#c*hP}Hp4gqGgn;DjydI;8bSvb?)F8?k1++@bSHA7JK
z8uwCJBKC#rM{odZae`#1ezLeLS(E-;A#Fx7P`M*C08)?;Hmd-nD1&*6X89*<jwq&&
znk{IsbjG<W46qW8weaF^;wA7|RCTiL<>rGhYMSEQ6*t)lNBh|crYK3O5QPl@rMPXO
z3l~e=2is-giD;5t*Q8e>0bVz|p}QhY<leapezz<bPO05}>~P=v8KTUj*mja!cJ1VW
zr^5xVm0GuNt9X|<xGcFmKwt5?WN|1TIfGg<UULMSB`lhth-Tht10YVd+ve_o+lE*f
zu-lG~s`}0jj74iD5S-~K#Y&dI7a!PZ=ZfeZpUd`Ovbd}e?egPj`@rPMrtXEB9AC%W
z2@8t=UAj@XZ&Khgw@WI9w*dv|EHkLOn-@Gh3XQ>o>;P7)KzcU$1U$Y)NU(C#2n@Q4
z^+*XgZeWo4njYlMrodR}^<3Xpe+YGLx(z&GG@}IYaWEt5NFi<D&cp#uur8n2;m2!6
z6i>nZ<zo($7LEx6XL#8RyF1U)jeR1Ss@otNQNIUJ<m#>^NQ0r9D~4B$H~@Kb-ef<J
z?Z}LJ@!LRvtyWOLT(5U`MuW-1<mE8S9#;FE1&^jg1nI*4T_Ro6hqoAwi%gG<iA+m~
zjm+?h<^zehbleT<E7XGxY7~!^qu?6Hb(g2M(q#fjAr|tX%ljG-6fLN);3juS>}`&u
zkyd6f&iLetlju)F9K2iI@Ll@s$a^llQpPAgj2^`^NCyUL(3<n)9ulHew!6<5t{ohk
zSR^;H=cO^^LC7Fgisg#PTJNN6w|JXJ`Ogp-g<jFAGJNc*iUSM?3vfJQFuG7)5ufzv
zM#m_oJ45Y+XoirG<zur_$c|p`qB9k~SYRq~#dmdMiqmaUAzmC~b~!1<RbYvdf;fn^
z;TH8!!>5v{AP%6Cfc;f)7r(`&LjR=~`i`7yn4ltH%}S-%R!xY`2VQ*lk^r}AJ33Vn
z)QZCfA1VfeBA<YPW(p%Vqx@%EvBNh+Jd9%lD6e?0_>eBIe1n)s6GGwv$jos@;JD~C
zQo{c%Bm?_WnQ-Q+tT->|qo9CQutJ@5z1uxjO-@%|3<el#GO?>2%#}Cvq`5V*t3Fl@
zvL;BHwaFUF+Z=QZfuvcAp(P#30p^Mpm@B@}heLn{!Xhw|u=Z|{K6=poeO4k|bjxiQ
zNSeXv6<XU16lDkmP+(hqTCQZ`pA+VV6V8XrXzH?u>I$0C?byz44BzKZUCVCJd$>-D
z0cVAEk{y&RLXOCRy+vgUKR^*)X}8NiMc0h{_$1_B>V8;;)z`G44X4~@b(g@Rrl^~2
zG_zGHJ}iolMG8;_8U^s_7<IA_q$OTmfw4Gw8kBA=bCci{)W{KQ)|0|z8gcG&?p)a0
z)cxVwU=H_^en-%kNN%^|QVee903K#2W~vxeoEAVX1VXhP=t&4YVqKc72W$2!+;juG
z{OFO4Wp;wO8y7YeDzDcs_cHyt>1dGEQ72THqM$Rea|6Riwt)y7qM%k>MxhOTtzq3s
zM+)F$kjx-}m_PtEwGkaQn0K;ZX_Rg3J_`qNZ6(4Wi30XT^BzKz6+z$O;BpCf(F`=`
z#8Sl@+qK}^n!#6TgpfI;H7Z?=nP!CDP1S{n3k@@pmYypJP&P60X?KW0Ms=I@WqrMP
zjC_Msggju0a1it5-&f!W%x%eCgKf#+#pODDi_T3aFa(+e9A*X#K|mNJ7sLgXpDggf
z>>%(Ob^azmM{>>pSbvMtt=NmxmZ7@h#uH$^BQ%zRKdufps0I95e(-Cp*y<IDjNsRD
zO}qg+y@C`f4}*z4CQLRv+8|wxaTz+HKuz}G6EZCiz|X}&-*$s-=~MyVL@r)nEFLd~
z=L7!SLb~32Xb0lPyrTs?OJ)E&Xz+1#*Q@|bYG&x;j&V~?I65+IfPGVe$cKu?^NuBq
zHPAsYEXW;(+fkAk<UkNE-^DQ^%yw8XBA-9y)FK)+^)is$V>l#Fo)L-*8I5N_-o*<c
zZ$XLRP~%m3IHBWEh0ADbFY{$bSh{icD@5@?70#YM@pQxG^o8?|qxOKS;smZrArx2Y
zTN_CPD6TAeou>w7@*}fAsYpPEWDPp2GXv5g1sX%ak%<T)I5Kw90~UTOIW-0=nM#(<
zE@F&ghK&~;ow)iHt=NU{3da-!$0#s!V=pkSh(f}Ts7`(($+rGeTp5KBNEeDL?rlXR
z$vMa~`dJVr1x%`NlU$CraJiUb*<FlubXM|BCj^m+nEl~85lZCnwZ=(((kM_9`xvVl
zFgW)%4&8<a(iCF_5HTQ+V?kwt;--gAgV0AGkk-}b_+uheLlMObir4dL0}MD12!gVy
za%3bdMC;ufmh>tg2NH)7As+)4!nAe(&}1Z5I32<6e#(sxtXh56nJ9p+BAD5|T{f-R
z8EVjkbK`7Dr?NqB#cHy&+n^5^DCQ8^30wyHwAvu`w(3GVC{T{T({da1muAGK4d5~#
zBhjp%T@99fqH&8L#vnqF%nOp=p!~2t4?JvPsMq>|;JE_SBm$_(X6!NuxE37M5Snn+
zgK&UN2K0%3RyBEh&^u~OkSz1M8Sk)ApW4o8!Y~SBK?h`tLKTi1pNHQ~m4i|z=b8yn
z6CQeDWK0xFD<V)@Iki$vDs3yJ(-JVdaEkQ?bT2w;C6Uw(<=WyHd%8t?3IHLV${fzq
zIP@8A@m8$6Jc0|GjO3#preLA8q6QUyoB4CpK<L-yB02CWcm^sjgz49yN*UIjJOD)-
zj5NRrip*S!oaBS_G3taH-%d{6Wx8<;eYo;#%u&XGF9Df6Aa+n7c1D1l(4q-1J|Owv
zshwWYC22sgEDphPX&VvFl%P0*M*O)=sibp|0cp0PGX~gc$H2c;hR`n%#x5aa)E($i
z#BMSl+(jICz)@+-tTYQOf|_dEPXTxw;oV6c<CF05T)O~L=P<yDEWimXz=;P?lPD;x
z{1OJpL9vYG<go`FL-CK@!!Sd)_A+#9*(c{nU+M7J6yuz}73ZAh0n|h>&Y9j~*@xz~
zl&=Idp|LF=2?(RNH{2#e!C95;mIpMMhg_M+7hvVaymVw@*F^kS=sx(4xYlo^;K^}l
zm`Fm6C=8kgODC}6kSilr3hcIB0PG{A8#Eh5@VXIuz)BGXD`g9a$%Zf;!MOXS5xh%g
zs_e^FEka|-c+RnWJmXj#ew>a`O~6b#<063(^GU0*ZSJdNL!8`^8p|G=I|Ju$*v6ib
z%7}og!#o9B<Iq~-Bo_F^eNt97{m6{{GFB|WXxOAqwg>{82!$WgzpM}EI}Rr8ap=Ky
z#_%bsF?nSmSosvA7^RK|Tw{f=azprY5`<0$2p!#6lMMTq5IQC48g;)7IcvgX6%g<l
zurE_(h|E$DSwU-Gc!g!n(jMNkA9e|;{tG8)mXx#+fD;<qe42p^7|ap78=_s93eFdC
z6qsQdkjYfuhP!wUWd7KW7+lP8=<JJ5o(G#?FKk3P10Iyd<!WD;EMe@~K(dvg+pXNK
z8&lfl3q3e=j91!V1=L+&wuVE*DgnfoA6gz(U?Jfy6mg*L=Up>|YiR+c!?f}YWGJi;
zY`6gUN*tAoe5#Z;5Exw^2PzjSh)jiSKtkDKr4iiP^)7VufMR{q9vHgkpjm4=$<<vP
z127n;CWGd3J2}D7k~21^0O#8b4sB<QnmmrDB?+SjZGGQK<t{>8rQGsmO?YQ4^x%F&
z56+FDC5w89d>BUELbpW#y|~7Vkp=I^0^G4c1t_@0QxAhbivW5u9tik@<ir?I<iJ7^
zZwpJuu@jAU_F!}y+t0&W#<gzV?F9!#jh$%X#tVR=Pi9;Y3v3619|h5m>0}W}vyCrf
znFS5LJwAylPPQ)fs|PUeXM-9XJNjq~6CjEh^)WQB1xc>Ua0`$u_;eRW>=$U&a>EWJ
zM@VN%yL`gvQ)f37sn3Ru0jQ9n1b~5J-&We43--w<5f&cGp%t+;ffXlke@aOvZIx+6
zW`gAoAC)a4wF#bCDg(i&f`wqw!U>4N1c+j@a_w><eMB2T@`GT+;$Y7dGu-n8(kvuD
zxEQp;NE18Ub2mtp3)^sMUa@FJcaEJ{@Mg>*UgaUxZT^|g;GZx+sw@Sm@?MZT*H*$v
zQLV&`!DSc=ND-=RqX@L%WS|Ad-bQfniH(9@AkBDU0}FSL83@WnASl_;f<rUy^qTPl
zK|!ye?IclvHTvRIM5Ba+PXN@a_EYvir0fcjvO7e|;|M@qSfB4Ana6Hn7-82VHi#ce
z`Zf^0E_O8`!EA>DnZ7>XSS+6Iorp9DQm#X}_FfTO?j}GAg4a@>URAM=0e_YS{8=dL
zTV5A|t9=NNV$*8iJi--Vg%uf#0hdzv^0o=A0bbFAAY8(rksc;T<eA8)9&X^L1g=Pt
z`hkKdA{ZwUF-#4b6b0~3guy#OM{ibDtXk7mJo~aq0b{?k+P{(V&hD{fiR++?OZ_IL
zKo=Llyl(E&1xz8bA^sW~nxUf%YzInZ+my#~qq@x4!92ORvJV0WKKZa~OaRn64TuOG
zy+LS_MXg;55`x*zuvXCvPnnO64_Zd-;6w0LeV2g!hsxn15%Y@hl}&c9jKtRV@++;f
zT~^SpB{0w59j$=z1{6Rbf-_u;LKi%HK=62h;IY8{NnwyFkoNB{?S}$feQc@%fwkbs
z4m*ZBA~h4vF_p<m4#!h)!j0)4R9QgN5d{HN74C*;j6ygk2#T{HpL{^Ta&<4_V4~%5
z6dYA$5C%F1g?&~i?6YU5(^#_8HZekQ?{@|1H*y0>5dm+OtwJV>slYS<&k2`nzv2gZ
zX*g_GlYmWq{Lopqf?gx)_83(k?ynY9RZL>$)4k%X<lWg|r=bY!G|UFcV}a|0w`4>m
zVh+M4Amj=XO3oo&m9Pnj#)wKC+hK(vxDCdvIcT2wI5jyUqZ`oGmRmqO?~eU2g0H%Q
z=1GWC+XwYHs4}+DeJFi+6oRDXHv9DYNZ>%1y+HHqgFsocbtHX&+1;dt3u8!;U*RF~
zK)II39;W&P53m#l&^!X5c?Q9j9f5s@XpWYAJTHbFBvQWJHUSnS$`K$bRgn5XHRWy~
zBhlQAqa_tW671z|d*HY|eAv5rAbOC3_<OKr=p0l?O<)&EFZ@YOm-VHS6b7^<iUs@=
zB={!^;GYx$q;$4g0T5Km(Ri^B#ynL32A7~&+X$8{=Sm3F{K1lCCLF<v0;2e?nA^EF
z(?c;UkUVYBtj&O;ielVIdL<*l47&>ykM_y}w2O$(D`vIf?rg;oWe}{`T#QV(Bn2c7
z>{M9jUVtn)ijm+|L^}*`hMMGq6GWuXL;KC09{OlO=mWcex_O9n{mx3&2WwFnRv9&@
zAnHO89%TfKLL26lF6mbw9bdTdX)X*qDS&x~6jg|l?IB7gFw;&1Q0QcN8)_;haZ&OE
zY&7E*ZfcY5064N604W53l=|zCbb*CM1RRE9Z7fY*jge-8<(Kd|2RYgP#__{&5ed-O
zPh}iY9AMRzCPMuU%R6?9s^6gA_}<_THs+?Y$JNUUgMl)@q^n5e20NA$AcX_$*j0KZ
z(G?<}I51EmCeN;Yo77q>hmJ~Vt3Qb7(KPWE5VjFvumR{4Bt9IF_}D<=qZ=Kz56w7{
ziI>W=1Y<?Ku`iN7<71$1&l)CUAG;~7#<FaRl>jqV7R*@mWOKLV1dL>iNI0UD3M@r2
zc2kzPs~@_kOJ-O;JOL^*xtTlca1cJGP3ctTO}PQKO&NElC5sk53<Jd$b~OjWu4aEU
zovTVhsg{NO7vu!HVPQWG{pf@=cg9WGD6W1v-JM-94W%Xz!kWX}rM_|m0{Ej)g^z>g
zI=zB>yc-RT+T5t5RRYwi=rxb_ZcV_GL@-eJ;$UjUrApISq>KXAIpEn;Ou7KM7rD$z
zJ_#QkKyL@bqbcm7K|y5@4eKhP!4XvkFk`te2O&W|0c6P(!dvyrO#^g9W$2epWu1p`
zj;m_~3=|xjm3$OOfpNeZoiH`G4R*JK<QW8xLIIA#3>?LG@=R#~^xkUJ=(7QeZzeIo
zQKFT*?SZ4D#(AX^m<D9(fA58B+=1d-VOt3BL&dvl?6{LyZitaJSGq~Y;`E<o9FRva
zqB4<Om<P6&V4%!SYJ&0a<>Z5n2f|ekIgf1HI_T<o*!qWqiHaI9<Hw*HyGQ6Y0Y`xq
zYA<FV<pfBcjmbp#K`!vi)f9BeZ1B!lh<O^pj<p5JlMQ`ZG;d2RUJ4@*%+!|DPlO>a
z#ny7ug}WsSqYWIT8aRr3Y@oF6=q*^(*rE6)veE}l#z1fcTQVV)Q3p%RpLC5#r<W`(
zae1sQ84}DyBNPv&9!^xAqzDWJ%|JA-pwZcvVcRC;HVA1e7W7FJD|I);c;(ER*-ATX
z+fBV|gM~SXSB4aMAEd}L5b;<+QNM)^7z#IN9u?3$fuMO*qF@~15#XSBuV{jjsD=k%
z3vKiP02;K_4l|W0q7z4dfGpT<C3Ltp7%~^vY5`7q+kDG@vsc!BpQq;-k<sq5d`txB
zl4IjAys-Oc5i;Zf$dIF$-An@3x!`P>TNhy4?sB>^WXNi)1S{~38DSw$Aazy3U=L%C
zI<>^Ua|6i%ZCW|7P{g54Yac_9j$+$McUgv%p!_gn)WsscoiAW5|HDwu149V`LlzxJ
zP+TS(z<Z#eOgqztPP1a8ooZpDa#2iSL!lb%{wd6bYgp!<I03Ya9q2a>GUX^}(a|hg
zc&L29%-q+SpiG<FnwF)o{FD99p#(1THb^z@cEMp38W_Q2Jif*mBn!%-13XIw(jtw1
z<M_f2E=L7vUgjQyY#tJ14RB+d!9f`U$%6pNLxXH5j7%4ffk6+T#V6UN+2-G!4REr|
zxC{kKJU=9Z{iJ&YSk#x9mX7eAZ{Roi*iI{c{94rH?Dy<f{%-z+YiH0mI<n(FVK0{=
z)Y0NI*@4Vhw~2vDb*h5VEVf_s?);uA8av_LF)shnYJpDvTw>TU({FEMA3frbr)VnN
zd;9cVfvA(eW}#%#E#2rJueu#umL3ir>y`RKuq0Bl&bAw$Huh*lb@*%_Qc4xbA_>~g
z3V*fYEw}s>b;#pqU`^tOI~?+?nbqfK&ka6Z_pIUiYJ_(c$eyzo6g+!szf%6;+P{$!
zrb8Dszr?S8WA|#hl{s(0m01{&`(8Ck<!ExKwRM60S-ps3Wo4LSdLN(8z!5z92gX%@
zm6jYl$SH0jsZ;1G;=HS2G=ACV;m~FJVd`)Eo{GGbU;lK5mK>V4_x4ZCFK^yWzxc4$
zvtszT;=w1??+;yXg}Cy(YOHw2!ZrW$ScaqCh~R^_^uJ#a>c1MVP#sjEtaU#=#PwnK
z!Mp{|z88P~-aYp+DJ*@@=k~#BE^|+T8`~$nufDt4N$eb~HZK;+dcwCq$3=UHmiOgC
zhl2*;`J=tE-3}8qu^hwH6WH<6JMUyVhz4SmUmT0Uq!jU-+&!iHvm$e{9If+EO;*c4
z%hKZ5x~HpOdM;L{9(;9f6|?peWgL-^Y5@lCh5a4u118H^c+5}Xdw5Jw4a)SbNv`#W
zwQjYX=@~o!#Ce-T&hEjc&%;rJKT)Pn>+L*I&dsixxbg|!w;0Yu-?^Q8S@T<wb_3It
zd$T^y$M$~rugFa8SNEZi@tz8W?qAVbP47D8(_QuS$1(7`_$&^I4@W%?M9C^zRfeK&
zUVQy?wYx#8U1QDs`n8XjoKseDNj^r-+xprE3!etPP(}G{*tuBC9-mH1msxC3a?G+W
zNwsonQq4!Y3gc=pJ-v0IO)1VDKd9ve1GhfxU6iX(Pqit~#5D9Pnhpns9}FaY{W)=+
z*B&qUBT3dkQPJjdzzhE~){c(Jq(Ss3AwcqFY|rX?*680q^2EBmjtqZ#;H{kT;r+Sa
z`aA=o&Wj88T^{7mEZh3$-qXJHbAMF*rP0UI%Z<0IJ`0UFJ>MK7%@z{=h8KjVoI1ka
z*tFM6Jc4%W)kY2H8aCqwhN+n-r-Hx{GLw{YY|6vi-)=sQEk{k1^(c>jUv7AA8Zj%V
zy(;{~G$Zi|WhYJ3Yx3{!n`qmes8bfksGCEdwjK;@9ntvh->%WqV^*u?H&k!h5vB2N
zuI}<13o)Tw(LswW@hFe-+v+z~QGZ>!b}=}uvi?ib!fLR(c5}lun<~b&+aGUuIz$N%
z+_LrAzIid_{3vmnaBov{CnL>Xp!D5-_TNvXZD)K%ZMbT6_xp@!8a^>Z!v|NK*@w0J
zHeYo+N<&d|TR&G~*PgA}V>~Q^{3CG{?>C={iQxRrXYOCf`K%Cf`Nb=Jscii@x6}IA
ziOZvJ^$S$`i=WJeU;62ok{P%$?^iwNCJ?6R=*yj+ZPnVCeQBOQXsPHog(WxgSpaJE
z%UExg`@mdZvtI-%S9kNwIOdYylF@QpZ`a34>{|U%+3F4oB}sGVq+4IX!<2zlzu>5s
z_d}4*d8y|{dnBwhzT}>(^-1yaJ7=1@v?{2)Ruw$jRaYx@rv7H<^T(;SCHYpZRc5v8
z9C~)ou&A~UrJ=s!C&S0tBuo7$8!S%6Ie1Ln?``$<&&I=i3RBl~0+Z~=F&F_!%8_&v
z+roMtoer*%13l%#<u+x{HsWfb!4mU}LqqCAET?Bt$VZ3vlV@w2t-K$`3psgT{q(A0
zU(LH?r3-d^GZ!4DiOdNp6}Jhj33WW9H9b8qT3nmNl#4Z#O3XCY%o3ZjG6AY)ZSAh)
z7oZD$>yrXpS5sWyYunj<8bUYIw0)<R_d2Q6uNG=_{*L^nBH?jU$cZd*L&!;MFN(db
zyntZt?X(cGvXYfNQuiy2+v1YXp7kO<jOX#v1<$9!8RUVK4<>g0Q-}+EaTn)E7sOL-
z+Z{ISh(@yS57QieZG>@@3pvMiMgM4<S@RT_o4=QBi7+^<SgIH38Nd2i%<92vV(H2O
z4qW=nfGN%0DCVmZXOawK#9nKdUG=DcP3G3oy(G2Ws*H*95kOtM8E@t2?L7EsRq-Q9
zK%(!C`FdhfAA3?NR_uwPLCqJ>&qX$a2`Q)Mbp-Nf3{L-8jB@(m_quBj^L8_}Z|q1r
zo|~;GR|Q$4QuW;RhMi=o!J;Bn+=hNrANWjFU>^=$4O#j=zwEm8_R~;c^aXpuTI{1(
z2crgqAlK(ZJF3oouQE3u#w#x$=TgxZLb1d5bJ<S>ro>l28mcvACypO-i6G1hRp9wl
zv<Bf@M+@SWo4?m}+fQ_kTzFHWRNU8%bCGb*n9V)yUHg{pwUS4Mhal^>``+wDv+*J4
zGvkZomyC8f52n|KzS_T&$GDwfU{=tgQqg?WUhBixeKu#x>X8xiEV#5}CbD)kY=*#5
z{h#imJ~%-g^yMHNe{>l=FX}&;{cI&fjLKF@z47xH`nJ3G!yyIp;F_P*7Jf4`FChUz
zi~Zd=^@kUXll^vtzUX)u8;I-)WcVDPQMwVo^=`*rCDNOA`1-u_86NSYqRB&k8?tHG
zjyqYe((#W<s6iWM-f3O1DxUrCtcnh$6X&aPmLnbx1;8?<t~hx~cs642*zD6$`l3g;
zTIhQA-n^ioWx;M`W!!FF?e7hui?4Eguhb`Qmnd;1zUr_}=<^m%mObCJVyIH%6krVd
zX|hhEF;?a4LRYDT_o`=P(y;K4y05srt}K+?UVJ3=#i+qj6J|s8LFz`R_tkOo!XkOC
zNL}#i@_|DWD(mg;fg?U4JJ*_yK28h7y+ge+T=Wq9B3Rn}X%JPAIxrnlh;Q$F(wUL5
zs3C<!G&`@Yy>~yowsv6f_rE}^Ncihcs&lPMfmNH|^*8cu)09(#TXGL4obFTnHbVO_
zb=M3Itsgj8aevFksbG28(GXU$tYUu-Si&0ZP=`Ao&(3Hr-b=zhq`mub43T{@bc%E(
zMCw$icAK9AEv<!;l!t8oLJ`TDs=gvEI^yAAjQy5H%Tvyo6`^(K*wqZ-Y}z&Ma4IfL
zXV?Y45wzKEE(z?gilM>>Q53P%?0>LC^=7MAIu~f-6@HB`=_0dqFJHN~j7m_R;0*0J
z_d`lnU-z@lv!`Wc#%teji|+Nju19Cd5xxGWLoJg@n$o_07B!is-@YE&&bv9ERQ_w@
zlxko9>SjruMUR;FwR;5TTK_Y5H^*Lo@=Nqp`4k!O?|pmEr<tCUs#ExQwmKOf1wiM-
z8bL5UhKiX8OwURkIJo*WR)6S@?psW%(x>k;eI@u0<vS@{x%cedtocJ0G8BX@)?I(z
z)eJhlv4vBjy%Fs0>U=I1>AoI;IB87qcQAHzeD*88{I^aw*=nQ3d2g2jPhwxvH-+A0
zLe=nVkyqh}L)y(R8oEZD{W~_u4LJ|oT$-PKVxXM3bWF4Cs)lHlQaSPYTWh~9XR7Wi
zEUa;Bcg_on%^pDrKE8xe@woKx7n}UzwI`i5^NR3c!N$}H6~ejQ5kA!4iNU2rJu(#w
zq#FNS*K9TNHS#P^(m-9&>M4!4ei{1uj#Cn;y%Hg6PbJWSjs9~I148pQHX%su-v>K;
z>VJpSIfkg+Y04<mX6x=%oE$T!FBF?+wlT4N&1ZFS{{BlBdn>)x=iKU$xV}H@mA202
zqs_L97rxu0DWiX<Ikp(cr~aS1I34%cj9!Vu|5=<Ka(H5`R4!o>&^7N|JbxIRl~6vo
zx>?pN#G8MNOQq&zz{WfA6O!WZc_a?MR2Vk9@t@Z$F3tb`nze4euJp2_hqLK-@g~7j
zh3a~&bXEs@cFrM6tvTM~Es%d)+`D6m#;@k38-~`yI4pdXohFFSSHBGJq&zfLNp7l6
z81Msl;MNY<OLKJl-BqIE@;pf7pr)eYXn2`eM@ju*ZL!<Kl+G8Gu;SHz5<9_mfln%1
zx9||U7=PvWr}z4fZz436lN5)-KP0)!-Lx_#-}`u#3m3B@`gA?({Evqt(m)x-o8&vZ
zo;O;re`R-@+A_zl9MC+7={Yv~Kqwjga0hEzEr9$Wo3wht?2dNifvB!2%}3S@1hy65
z$+e7uHSHVj8MmUYsZ5UODs6@oq;V3koakc6<a?}6sy)N{tn`+#VjsraWtU@PUlqT4
z8k1F)V4QZ3JhF2dz5QsazwDuYl0lGhQmD0)`oqV6U$!el`iWhgND4jo_1SyXviy<%
z1kJ0wQ~w#7*M$QQq}^G=KYG>8fBxbu|Eq__lDeQuLim?LtK4lbp0oa>_x-u(;-lab
ze!?xq@pioc(;Z_T+bf2({mvg(X~s<_Z=d)LU{3WjPsU&l*Z9AC9cs<DDC1Ho;pF|$
z(erKC)}j!?$-DOR&CdDx51OU09EzSkByVS1Q$&2ZMbw%Z|06g8v#Rhuto&t^o_`i!
zvYWNAUu~TDi9fPKc63;{I(hATi(77)nx~=~Vw+VSUWBVN{sA2u8~3*p#-V#mk2SOY
z)(Bf$`}}>e^=<L<2G6Adoi)}KxsT3&t3@lS;8uFaoG;Wa^^OhRsrwyr$szeVBfjB$
z>GD@U2V+xf?M($v&)Vh0xr@$CuAM3#p*wa1UMGBR|C;U18BrNnB{HgW3=fRCz6is$
zw~x!a&b`Z2nXr!349gyy#$37-)_vtl4%V{!({0RUpU@P7eQmjCSTFZW&9mCS0*Ph$
z59ws_|9-_;J<m@l$sMSxOPr-M)W!3SvlPDxUK3!D9ideR={R|~rHPcaiO#KWx}Ys^
zZuGOOhUj)3@X@gDb5-}%$1gOl>JC2;IWDry{N#zfkTB(1X<vgBLfB?7u~b)3TpD-M
z!uw{erGhN{AI#!e`gi=J5@}~92FO;%Zq{YT3MIZ4#-2^Cym(6G<HX;OT?c;V{G!5#
zE7z4kXIMTYid24~<SY-aT4kEfBolXitlRu1c0IKuX7zKOR)Oiw`~Dh=ipqI2!S_9u
zE+%dcPW*pQ%`pULoqjTGmW;f47}Z(*X8W6GKQMIEO@HMOWVd(V&7mjy1y%9#hA%tq
z%ep!{{9&M6J2@^U)t-*Bdlrgf>{J@+SDbX9%K`CHK->pTe4<y%Ud)d0d*`3050lN#
zw_f6o=$so1pYiH$SJzjquaKBcrEHTYbUulwxfJiOcdECndNRy6{Bk3d^^0Ox_(?9M
zoXmb}51!;oodlc`w+fIDE{j9!k(aDzn#Lc-&uMrN5~dx_-6nV~)?V9Dg_+x{f{ED$
z-}n9HP<zh)@1NLwC*Qr-t~$TJ#{bh3Tf3}{#V<n+?zz_1w&`j1PGhxYcrAib<%>rP
zKdGXwO&6~$JaB(t|G!GzRq_hUD$2bhqS`xrowp2bD%5H%@kpYofwpRXY%ryEKKmwn
zHL_~qV3n1DRO!vC@8$1#H~slG{VNxSr8T4@R~qo5@f7{pqQTCT{%)oIT*q_BXB`=y
zR8?J!*{kBm70zVt8v{r3>jgX%yV<Ie&WwLjQAfq~B|k7huW%BHg*UD4pPRA~`Z8SO
zP36$m@A{FmRr&j$MS?D4;Il8ZM@5s~LYlvxyj9CN@5klwfKDByW-1=9s+gJga?QV1
z;xae?(0AQ@d!V8vSw#Q*--K*}qjTBeI|TuCLA_^Wepzj=Z&~g?knec<tky%hsE!-y
zqEnW?uJ$H{9+H`0c)_J;zhJKRaJ$m!*Snpozxxvwrs>O2U)^nfWhD=1YIl*GgGW^M
zVIPs93*sdO>F3M$WYdP&P@n(d*cl91o~e<yvx>T;`|wK*6qn=f+Wl&?j%ewxaelRY
zC>}RBse5Er@p1N9!s1l6BNz1;*J4zg*pYKdt{vLqo<?6x>dGq*D4w(bdBoku(hc>S
z%M4!NU;YvC#ZOwE;FEtGO1p85>*vrMX|{T3H0Hk5x!}GroIh#d9dO7a?g^Gos44s0
z`mRgk_PND^{u}cjpNnlBz7qV#j<`5-XlCHnj@wZEm(ALR7v<v>Gg;~eQKj>mk7`bA
z)gPZ3e}U|b3d74ephM={z@Oj?le%*MxP4uC{cPV@L{Q@TvuFA2gLE50-Xr^achP5k
zI9T0-aZ~lL6-S3YjYd|7@|3{*3Hy&%(6*sPfAlnOf-}}Ix4wNUYrZ<7i3pQQY;@}R
zU!|$K3*`Pd=LwqMM1S1S=^OrD^KBP?j=~hpXHPDlyP7d;5&ZFgz|}r>@h%M$ziOPf
zbt0U*U-;>lZIs|@?f*VmYc&xI{E>5JbfVbzr(p?Ohu7$ba0OA%y6(KZvY?dCiz$uS
zDigjDn)BgxdbkG<W}dzG(zk0F!d3S@h_oKdzfi7z(hbEp??wmf#_aF&{C-PCFDZV$
zA!_vN*4=zTN9i&1tLx9I8ikwrRAp@lzq^TS$#2)T9}MWtq>_eyh<+yn5!@`!)d$R?
zh}4z8U6m_r7PZTr3-1uh`uSDLy-EflUZ3peys$6hdGFR-^8b4uK}3AS{(tTxG@m51
z`WMF&waZ6^P|Q=Br{`6uv7tN;<a_aT+VoHVu^9fDr9+0k-P+`2nFFit<{vwKuL-y~
zq}!j(beBb(=Jgk^r~TDo@aVm&nX<w?fwTR0G7~Hc`@!@4TX;3pT7u>s@#cm@*>3_9
z$70kda1f0A;E-z1`jhw`>v}qQs4NAd^4~h6Gl6FRCFOWUK2z7^N-hv`QlT>v_l*if
zOYv|-;^7^lxA1|qljuU%oZg97u4&)@k%RH-gxSrji(rrRc?PHo6AuRVPp*9^d2t|K
zyV_zx=lp+TY(^ZlK3XOtVe*mHd2#Y)hf{mdxj&wOlXvX>^&x8y#j1D5Lhe^dztppH
zm|k{_RO$M%3P&FoYB>Tf2~f)K90Y!Gy(?ENF#MYT3CPK@SB#BpO^w}rf=6DgeV~@$
zd+t;Wu6tcs%z9t$i}i6c8gXzuXHWaNGg1~$=bU35sXY=4%SH7;Nuo~PQz5&Zyx*TB
zOR&@jrM!4q_h@#TN4(O1aarWS#}8zq!j=0x<rTRPJ1nM0)rwL-UO#%u>vm=0RMjPs
z(h2*n_R8dVck$By9+L0D&Ic|ylS%N<`zZP7O3~g{bGDy|f&f)6-PjMZX#xo*9+cZx
zC&Yku?PNW^eqr>>{nz^|;dgdkSUi>fuZR27Amd++T>K<d;j?k5uQ|}JFO2dLbY=Y4
zoQ;Ev=BAhUXCHZv4I%I1%*V6*OVKZk>=r_g-2X?|Uh*r>oWApnj$cXXk1j1SioU%>
z>{tJ<S(iy}2g~t@6q@Cr>2vIy>O}LFgw)dXqDDf+-<PTQ*}D5p;eo*@?b^h!!-r3y
zi>LHGO0OGcm{*5@O7_=oQjT~hsaM}HtP{fCPd5es<CQ+86FR@oRhKUcwaktHh{Xqj
zH&~x>fj+0lUvbs_4zEsGo^GDq239uh%475?G<4OHu0#F5yoq%1^E{>N7=X!rrqHpw
zV=MaEx6C(2EfbeCD>^&heEd26-Qo>fm*N@z2j{jQ>ij3>MR-2+zs<agj(rH98Rf2B
zy#CUdSa|6#Or1)ySNb{6+_&A`ob%x>b2*X!sQ3RL(9G51@c*gQYeQx(a5bs1b0zHR
z)bjW5FXIP}khwobn5$#EKOgk`v7uRuf9s$c_+a@qu!_XxwR@<icbia|S;GCdZH2P3
z^swtqw*LPbgen<*4%^PN0^Bx*tF(B;7t?WNUs7~TWYMy=w5BdUEn8DdIZTZ<cq#dF
zkG-w6l#+XXjk+M~EDim@%jry}8dm-Gba7Lr8ud)?aD9-L<d<Qs?QExGqoFF*k84Qe
z=?^7$!o6%xpK;9DL>s(PRaZ6sJn+#b@0->p@9zJa6vcbcfJ^=%l=PQUaiNrLFdgXx
z^Uq6pfP>yIzW?X%psUY)KECB;<Y@v{(fk|TjJLQmqPZ?-Pp72`^C>H<b?r}vz{*Ms
z>!Yu3cg86;$0sxMA|*I1ENNA+!ogAB@`}lvm1>7$Mbv`|y8c=<eEp;0)iYMXOwozm
zGc2+PEC0q{I3IlUViM{XfhV=3=hdUzMnw^tBDsiM4kcwZmC{4BD9>})qm6BXnH2s+
zPA?&m;MGKn$+A03@<wlND<9d*U;KKZ{nRi%XD#-{8QFJTt!oE!T<sjBDi6;S%3`e!
z98}855hhF{)mzu@+wJyP&7-|I-^=BhDQxFd><phP_i*0fG=HKo{M%lpPQ%XeqWs$^
zhhSTH0-3W_CyGAPbdWvfQ?94a9v;#geM)@Q^D6dEy5nk>Pv*s{J9iu@tHx;!VL=_4
z*+P9<JrLPlI4}Q7an2$!bB1{T;xGA5&g8j!_D%tMmhk^9_Nb*~4ji(%WpeM-0j<C0
zYR;5epS_<vxc}tM&wCZ8TWquDG8J}Q-GW>)9e3wSpjLIx<Pm$1jV1KNUS4pIuz6ya
zB`lEBm@PmOMX$G^m6DEGswQWOXFHvBuy*|GhS0t2>@2H1mrUJ4>4Ncl_yEJEjgxZm
zTot!WUeg@Y?A;u)$Rj_dPeep)uL|L^?N3{$krUD)rrnL=t61y>6m}2XN-m0*r?6I2
zmZ`5UpE=rn>dd*|vbTRcT8y&SNAl|v*Tos%#J{m~F>U+!q34xIsmw$y=V?Ywu3`t;
z!M^9Yywxho9T5;|&ecx2M-;tzv&u3(;_jp1o+TWW&gqr08a3=V>|v|nd)~-sy5r&0
z>Vvf>nTOwB>Wi1RDO=HVnp)K%l^A)QoOaxQ;6%oKhnzsy)6>M8?Du%?=p{O7Y>{tw
zY@1W#cobHb4`kZecGB{9d5zY}mc30@!Z}FfI_1nauyddMiaUPPZ}nD2=5tEwot_VC
zpU(EyHvH}IPRu|~?E^9V=ZDVMh^3jqO>@Md{kjueCvJ8k8pxFs(`a$=(}x-_m1uta
z<TN2JBFq#PKHO?8d-M2{@rTSBsaIHXXi{2V7B$}qoPl5O<SXoGygEL0{8Zl+_7shx
z50ZLc&Ys+Ns3K|U&`j9p#+wov;b&cT4^}_C#a(sw(CPrji?wx+{H@-7$A5gcBnAc@
zHN93bm3Q$e>(HJZBi5=rObfWB-$#7I61a^F!V)BWv=)D!D)iwJ<_{eBcAUK-E+i@R
zE3a5eT{ddWJCfVWk<C_6(DYc@UM>}5Z{-O)nL0j`-XNXyqlNj|YFa#jg}WcbRX@Uy
z%$Kk{?AulTX512)`Q1k&eJicuujPD6x6?m3Eo+oZFY~MPa(0<mY3)<@)C}#tdcEX*
zb!zPjBYJ8pZ1v+?>(4i)!_$-$NaFJM|N5!1y00KDexgqV@vT|U@|}U`%uDif%Vj&4
zOT25C=1HxhSDk%gFTOP=1?TR|Lj??fwOGEGJpI#c*t@^8S7P{E{@b>3?o{DK8z)i3
zw{8#qLPOh{>HY`r=bk?A3a&h)m6V!>RJ@nlmrMImaq_gF^4M9ApufXzr}F<)o!j-X
z_|lBV>96Hd^|_ztx3nB?WxQX`75}T3y4RMpdEv0+)qy9o^Xpff0$K)&XTNUVI86OH
z@O1WR^Ft0roXO|4_3Jq*CWOw<YlC$~uWJtnR`y#H?GCD;_f%1-7v!djh4=RM)i*0j
z2tJVg%^K0Qq89S;`;6V`gJI@lR+(9!c~cbIzMiCXZ;`R2Li5s|b<PhVt50sJJ5!5P
z3>EG4%VqX1Hx>)sD^4v@QlAKxX{=g%#+v!9kV{F~dQ&isEPXM&tnA>9TF8FAAf1VN
z$@vHKCtj2sx}|1`#!r$Ri)JZ;dkWnL%AW4uZye|@MYFf_!7>`(4VF6Xu*dww16Qn_
zPq5>|RjVfIeoxb*)<}k#{BPmz50^hVM3~}F8au@$nkjbP`CyVYwU={VnsMR4+-Mx-
zu^3H6sxp*Uy85lIG_N~G?ojHZS+jGe15*4h9G27F<L1|_^M+ViRxi3Kp0nqBMpN*M
zw5IEqsjjN6_XoqD{OB<ho@wT$%^RvkKWM6G8+otvg5s&CVt4M8=<^HSI+`wpmK(G4
z_HT1U{vvraJN`y@*E!>_3u;_nC>q)`>3wOAfmqpV`uIoVsq4%0_!9*WM6wn%ue#N)
zOM=-Te4;~t;)QD9%4wo_Ow?@E<}G(+J+-65vgZa`a_XD8&%0iv4VHK>Tx@%Iu;cTp
z+JXfM?~IWdeqdOeo3bi2g0_p%-S7HFMA1qIpJ#txZ)nqLyx7?&*PCtjHe*WY`KTWX
zCxzs1AHA1({<ikG3d=3WPd3sheTPCd14CbhG0F6K%a*^)%1XN2ZTb#!KDp(XQ{1H5
z&dFaXH=)hi!``m258)v#?_!SZx~d)$6cG@Sn($KXy(mAe=9@sNL&a0_{MrxIHor<6
zl_-1bxrT~Qdz8-7^2pSp>5s^%*GQkbi1X)T3X+kCXFsoo@T_qa+uccZx~(T{BXg?5
zq3`XW)ay~jrr<T_xkhKkg4QF#B4g@ZTPfeV<~v5-Um{~uLSj7)6}^Xt*$cKMDTZfp
z-z~NHn{$61%L{nW8`SVk_0^Q8Yi#|%(QGG&@5*P$_GwdJF}%}Wzmvs(R42`UqS_b4
z@%V!)^yR$T6q%`$qNmzXwW~8i?^kD)WJ-tLQb(1!)?SJjElM@zv);8yGGpg}UZ}Cl
zaS4N|L%&jVQP!i%=dqD>1}TBEa~0hN)8xIKx_d(URyFnPCd2o3+URA?H1L^3Js#ZC
zxjm^)ruj)kPJfM+Wi|<uFqsxf^pHp?3_|WAvL~&@;@;5ENi%ySdV|Vdt?o%txD~mF
zM%$Mn*=oK@<6og!1S46njGYP+v`I2wXQ7@{`>I~bd@wR*Mqi>d_`-DF6$!Pt>J?gh
za8j%KUK8FF*`TCX>S89UDcUQMtR~7UzGT`+Fg|9+LLzX=J9(vkl~y^eCp5;?>9lfK
zVxx5<SgUoFcc)pZvq^8FeHE3$7lcfn;g>+noQx;Bl4+U7pMx;*g~}-rdP}dX5GmEc
zV=*4YTaCTHcT2DvzYUz6;8*V>t6sP+(GhC49sGF8J7Gpb!Z7&4<ky=sx)O>r4J@6j
zdZ9);O;Zg5em~T&iKg%eaUc04rN=h?NxV~9VrxnysZcy+pWd}8kvoODDd+TfTZ8pd
zP<jt$8hF0Bq|BTsM3OfJ$+V0hm)nK%JL9`LZ6~>cT#{!5Bt|B45@(zwil-ZRJ24WS
zt()EwqcaVXv=*t(V-mWPhg#HV20P0#%xzJVG@BJ#)HE&db+A}UZctvzjHiUxWCLp_
zlSKWr9)IU~3E^oyhR)Lx?LiVL?c^iXRfZdGCo45mt_S~!gR9>T{`vYnbLT@n-dDl9
zQd;zQ+k>T3c=diy>4})c-J<w^9dFAI(qhzo^PbxzL_#)5WK>IRl)tw1{azDia;;{C
zIMw&{SZ%Oe%Hr-}ZWC@lKjw>m979qj>=I3rpS1VVT)Z#nN|;O@s%z1yE7GV7&Aqj*
zFeSoM5bvRo;v&)U>vHFmNSuesYpd5ZaiX`bPV{f_PItYXH}Cg!F6pJbRu?i+l!%=C
z#GkNgyY);jseC-i$}y~?N|$$Ly~sEaDb;DMm-1%yKnf!GVB0Ex%0SRq;*5v{e^5<F
z@bh5ao)2s^G_%PbUXR?Tdtr?0?doKZ@S5^wCa98WrzCJQC*M>tnjj=PQoK6mG09fd
zQg;dkQ;y5bh30kW_?XOyB(;BXxRh|K@nV~?1aZncH42kTqsgz)e5c64zR8H=T;;!<
znSY{E&?zVTz8<eDa*Z)8m0>X-u4wJ<HHkV3F9hYFz3cBi@6})~O<pwokKi}<2PzMI
zx|*$^e`AGC2h*3C{?1=!_2~LGdxoxWQFyw(MHKvpzRjNbSKmIkHvaT_lTNn(VyI+2
zSuL;b#T$EhpSL-Y`v*i(F7p|33;#t#o7DK1hp=yVV|SgY(Z!3}=~gs9+RLk7Ih8sG
zoCD%sgj|xtF*<tqJ}N(DW|Hu2UJL2vS6k`zZ`$C0X87s*Lh5*le?}~RUZKO&*~PbQ
zA|xX_btg7GI~ALg_8L<oDz5?_<F+Qp$e>c!mc`yRj-S|!8jQgD`K;vsZixt0n<bE|
z)#&|TU{uk~l8v_nOS7?cl%<H+c`W;)mYKW1*7Nl4S5_Wsd2UNo5T$h=$sO$x)b;sS
zD^nNi{wG>_&n(UBbx94jUBjemv2;gi+IKsNc7Y`LMoFtD2Bmazi0sty@z^4d*_Vw|
zsXhZ%@L{Aly#_NU@H=_6BtMmcGQ|IlDWM7y9SAo61M5%tYznS^OeZA8i*AAH7l>WY
z@|cA-*l1a!@SAbdVX-*UEWJMTg~E~-NiX!wxzQsU9dP}?C;$tvfL<k{d!D(G@3$s3
zG&V}1jq$FlEEtQLnMTi+xec7|1ZS}UJ^m*R>3r^gF-1{yvG4g8txnCl=Z{S`$#(=P
zpFTMR2Bz57C2!n)sg1lTf4%I?B8DmDUl(v=okPbCyjJa6DUGiVkPs`rJN$-j5-+FT
zAJBP$J;VX$;(`A@H&ghvi#;7#BG&BxT-~j~(mJ3vApg8YIil?9!Xjsl)!o&*LT3*t
z=NEQ}i4lgAjQ^F9eHS~3X34ydVk*77ul6M^BSoCgkRylPO6Q>x1b);j;ai|M%PX7>
z&k^Tij+>0UzVq;1-8oHE#zeiZy~lO`|5bnMt;jyz+iD#a2*=v^!Fvg98c^m+woie~
zVcX)c7>BOs@&dhtRL7Ra_&Kg~wr~Gi-Cs2#|JH<(%i<~`+S^fM@BY3gux@CyG0#ip
z4ispuWTc8UP)Q*S;LyuW<J`>2qVDDQDEb55JcQ$dSj#x#kxblOw=>%xCjW8f%XRKw
zs{GJW$a%+{KNq9atWm0DzFDfZX@BN$U#Nf0<Ez!7f1NqZBRTuY*!0`%m(ymh;q#U@
zW|iSQdi8&wxppVg=78kITszY-mnKI_w%W+N&aEx?1Cq&sec^RwAFgdp=*$#bv{*XE
z-4rMI4eQ*Esb1&onHJYC&UFs-X=c~cUH#y8^pMqzMr_0b^QyfDH=pGm3rHcxzm6g$
z-Mix<Pw5bIu;9{iVZS#g|4U}D_`am_eJ8=(?->QFZgzIF*;#=pDSRRat|PZfd;)K{
zUrLd0H$!x$9*w(jUo+_LaGOK5ko5h&$OcU5aO2ikP-M19WVJ$lPOqzmq?zhwP;bMR
z&TIX%QmTyEO${HNt(}Um^tvKns)X?yIWNuH`8B4RS6uJ8S6b?A{dCstOr~Aa_vJe_
zIKg<0H;&gw4SUK$ubMu6*~K`9j4j)bcTN`E)Z6!FExeMqbURO`%v9xJs~DoEvg0@|
z?RfYsuhfvOeXWjU!bFcG{(NbF_i3k#Wh&L*S#)OJzZ=0FbLHRqc;L;@udaK(rHg;x
zv#U=eanwqleRV1F>6Ibt)A40rq*iH4XNP`$xK*<F_~Y48Bl&0PYvF=Jp&xdYERu?g
z1FROyPd|NDctlG5D$zSX>!qRX^t@_0A=~n#<gDHIr!#du7e1y8mpmP{*!Sp|lLn8V
z3x2PXo_9zZ*Hg*LL8~y<g)?cT#gdhRR$)4^p)X~MK72zNl8^sgu9F$iQ6KXp^~~XX
z%ln)gSAIWbJ^M4=5PEAxNr&_AnSEEPH#?PYxk@Yf`SIJ+jI+f!C)<2CvvZkQ7LUp;
z(fRnp+ZaK+E5DlTmGZ9&_AA$(&v;i-{<TcNv}z?rqV~nYOYYjWmrE^YG5J#0wgnAs
z_x>=oE_o%Tc6)auhWf&$t7_1wwCnuF*5jgg7mE|!9=xHRxGFR~%cP?4!Z9_?J=yHu
zVc*H8d)m2_JbvE&Rx_FY&DN*wc**;{h^gB`$P2#@HgtV-JXn4rmo=LlCEs(f;lLHg
zmGqJqld^*sZ0}#bDp>x`qs_dyW3T<TYuf%QhyB^S<^fG+@$wZKZ|(``N9USFy?JFm
zWRLHB^ow)VY&Mf@dc{8L!PA!-i2Au6<WJFv4ZEPz&&nT{)P4)kgipVh$tfoET=Os#
zQ#SoeQ;O&Mw&};KN9NL!?s1e#D!)H#a7L+k$$RQ{jqF94OPxJG2d($tzVfANm1cH!
z@Ym^GPZp(z%nY0qGSaCbf<sSsn~WYUP7F}HxMBA3oi#)D?w5f%X3XPm8f}-ePc1*(
zYiRO+arK>XO)XEL*G^H8E=Z9Mp($OebO;b61dtL?q$6PH9i<3_4hazukkAu~G=b2r
z^j<;}q!($1CcVDsegF62eMo+L_Uz2g&dlza*)q$R=eJs`h8~^N2O{0;HE)76RYoP*
zr-Yo8b46{+K2E{_EbhjiHr|x^O~QZ+ZoGscLE|uu(&>U*PQ^U{s)O#BhvI3&tl`v)
zYO&PlMgTYLt%87Zl}1sRPrOl7JIxp{GXBbVRN$LN{)>=k<I0<N;vI{660ya=R5wy#
zAR+140RSBpDSz}eM9U=~(#jRYdMgPrJg9-OwsL4R<(ZX3rI9AO$tO!k!FjYh^BhF)
zL}0qn66@qWJZ->gU2y6K?ae?Ms}(Zd?tk&pt_ZUgu7can-_w9eG3~bpgarge3O|Rw
zk^6a=5Ys(Pfrq6|s6Ak-WwBlotBH6M!$S)Z1-bjTT?sH^>l$g7Bx;g9`hI#P#{QsP
z=^lfWS)Kp%!pAN&WKNl}Gxn0+a*JJUkTR9X|Lxb)VLgjK^)Kr1R<6r?Ew}I$z9i>e
z<yO4vnH+P(<q-8+Au8H`nin?obCKn$ZprZVGgo3a*^Rq3v)i-#S?Xcu$03?^Mg~7U
z%FFxqSY34bF0VrG_u32v(e-_4t<jMsPP*qss2y{^0Bg|=SQ39x%{29s1L^iFfnkIA
z9A&V45ZLg*r#s9L`qeyeMPPYsslebxQRQ4?(pquNTj3(4Bq?$Vm|?@gFBI@d1NqBO
zL<Q3@TQ34H>r^Rf2J1!L>@}b@e6h7cZ&ep>>1FZsu(pua#PmYJ!Pj$g35~FI2%_*z
zY4^Wrn$~42uO1`;(BELcRem1grrl#BN;pigulk_`7_wkkaPX4t%AF*zkJw~?rq=iR
z!%Tha8kBO}3<xabRo@l%LO;`7_W;24osc_XSypgpq=_)*OVIXelrqh$v(QVG^V23S
z)g+l_PlGe)T(Eo<TlRS^eluKq04?oNqo`=J7u*z6<_$?3amMRKH6flwKFCp)GK9XX
zB*nc0Rll2~{(d_V&&-^uXP6BiV;hE&fJH7ic`n?#SHedAgqjci429^7hkuuc0bil2
z)C_Sn1bU1R@`iM4k|9zv!lE+}1h26{BiW3H?7GLuW>F&@^$ac9GG2E()@VI{!XV%C
zucV3KH4v%rAApT~S<|9)3#lj<AfDROU~zF=H!4(;q09xhWQbcYc?ktr%y@JPc#fpU
zsz}Kvvd-*hvYxXK8KtXAX`tw67hV;F>JZ7GCf29vIkL$i7wvK<l}NEQj-M8SPIrkX
z4mG&-L-1Pu4=qf(3qz_4peGqyWD)Ly%kaRhAB@hDMY)jOa$C<oQpXYr<{y!9b+~AR
z;P??{nDiEBI?oZ7l2P3<Vtw2WQ8<1WY%{-2DLvX)YGxNOvv2f8nC=g)NZfjVM|OIq
zX1vS)v@ky%S>6M1k^>-hi8M-N?79up%D1f!F^V8{3PK@Ipf(87{1Ns`%Tx=Q42awM
zej+w+L<Nw7uUN(i7;+;)Y$afL9PSjgo{N3#l1l4Z0_IlJDEbn0>%bEX%*A%Og?r3s
z#XpmIJ$B0H*S$QPoTR}b&l)1_x9Dl2nLEr_0#PqFm2lAXASP4Po=_G5$Y2)ww0acN
z)1KAb`fYz!3F=nL8yGzjqtI)d!)n87fLKx9g>@RJ^>zN!E^)kpb(9WVfhb}Gc;6s0
zZ;fY6dsvGnwa0D65o^x=37rm-wP{k2(nNpG45?FvjFUiQ0Kbu>pNprJ&LJTib=QmX
z{akAKu;@^*iA@|e44KcnfgSA@DhD%UH8dy-_!U+e8Lgip8sGwcd}_uisVd&w!>sE_
z?((OUF?wn;5<U?A(Yi<S^&XhKA>oq)by?)Z!%cdqZ^J>c-)ks%GuEr9IM*8V{y@F+
zYID@6ESe8%L0N<LTY_3)_*F_V*VRZ5{4~c5w(?6I3T%O7uX^&%4}B5ft)J8qzPkbD
za(F)eLNhw<BLVivS?MzRp1@C{g__*i@8CZ0EDocLT9v(qMAqtL<LteFhz?)Q#yuXr
zndg!YF+z@eG&dw)dCo{1zA?37OzSQVP_N_CiFDsU-Cv;>(aJq&BheS0q+T>n<EC%t
zf1zxC-VCZH4(vtL=ouMqRh%ji=~`L^SM{Yv=S^|#>O*o3kZm!#T1nHi@vK?_=As<@
z@xrs5DpuXoOkA^(VgHa)SsWxvOXq2L1u1)5C(^Q*AUJd*rb(W#mLx)w&UGSsNS;_k
zC2~2gMN56BXXxfvV)~4}KAo1deST8)nZH!JCchS~s=KQ?MVO)EwucLVhG@O@r_&bU
z(N_~C{G~o+#P@2tFg3C?jzKA7Q#A`>T0p#gDW_1A2rBkfyxrY^D{XO?O8lDvE3`q?
zV49moqCJq4nTR660p9togn#xoOWI<rjy+ron3%6^VE%+!clQr%sQg+h>$F9!(NWqb
z-;4M&4MN19soj#6xYdf<*S|%VrzTd?T#U1Be@KAPyB3?7FYg-tIO@Q0bvz`18MV4U
zDKEvwT}>28STN|jG_bm~?{?IyY8ZSlH@pSMFC8Rc;-__?BcOXpv@Hns6T)x4#OZ!+
zp1sABS|2Vg@bemg)|RpI#|D^%bJCggidG^}Ih%HumS3${1{MMF<&<~iE>m7Pq3GXJ
z_p{N?#ATb~ADA^P^WJ{bvVntPK3+sk?OzP#j=0||?@gl@Fb>k2URoWMh)p+}4`43g
z)mi$PBo~{t*t<B}n-FX^y@Yzsu|3f)--H%)G@m&wgn5wKB)I)Non<=k?vO79-#gf)
zd@GiL!3Y!{H^Lm2h67;c8{0|1EGN>9&BT{8hDA+sTh3fbuJQh#8a93{30_^+%0ass
zx>n*cT@!j|t}kyUxW%G0Mgm>pg5ea%37_>Q4dMRp7iw;)(ZAA{@wt*mN_U@64m7b>
z3fi9Q*g*blBtZW=!$ty2jZ=6Q>9*O#h4<SE=R-A-!-RDiq8CSD>;pM7$_<4R%2j4L
z;hHF6>|Q_8D6z0vxeDUWtpJC6IATAR7ZoI>FAhJCir1dwS{ZKl-`5vRHKS>Nm^h@w
z-hvIJzEd#UJ)md*NiYe=6AjK?9};2j$T3L*CS|P;@vwJbHIh{C-P^nU1IPK4Tk{44
z@=n#D?|q?;e&2(r%<n3$@oC@nm1U(kt$|h@T^?b#5(*<3bMW`YjItlu=0X(v_)`5y
zPF8>zm2Boivv(U`Ct2};Wc%A<9{eAmyMV?o^45CwP%_VAApZ;2BG4C{8uD={lIfL(
zHf;;6w2(56uSQ0iBe%#G`R%UpdI*%gqOu|F<p%+}Z=iwfJ5kT#nZ9pb#sdB7k`AnH
z{LV*;8lAE;$jXe=1N*2pQ*QY-d@1ds61eb*W)Zq@i_WpG82tKuc=xKOY0|2mFXi1+
zxm;{B^RDp85Q5#<@I5BJ>N_h~BC)>6X{tydNx4?BZ?P$`r>vrO#+v*~*dN`zsR4d|
zf_lMx)cc!}UUmSh=*BjA=S3Jq&eD=<F<h^Vq<o`|rDZu5Qqo6_dG6b!QqYjNL0M93
z;2mVsPPcT?20v?ir~3jbMNRk6RJ0wAEc(c4infY-Q3NO5Z5dgL{F{+)HISqQ>7!z~
zDpPG|7AB)}_t7-$qY^QAV#4TVNLTp$Nkjyw{ic+st~R94gaidAt<lS~3Q5-q{zGIT
zG4FX1{OLBT&?-(k4^FB;O-ExuWvCP5js5rl3!27S#c3kpq=toZbAOV=5=F9*K9(i@
zCky{0PS(xTLCwa`R{vF>X$m)uSQ$!nqyYqWNUkT<OPSE(@vsm{oz)@}Nt7=$K5wQz
z`0WQ!9opm@Q!Y!_p_W+bJ*c}!_I_Vx!vnlU@c+Su;phLXEw^${H80!EHI<~N?9s;p
z;0x{vjxl2`gZnn)n`nqx9ahzY&H+A!ee16MrKMX+qwJA?AOt7aOchk*YdE!;L+j+5
zLeZZh<CANa+4oc4yva~t`1cd;@J>Ue{X0Wyr)GlRG|(&PXh^pWXmQ);Cd0aG`As(B
zUmHhnP&D^3(Jng^N|`Ts?mDb{Ni3|DKmFfV@qqZCTQDhVne~us*h%l(baQ)>`1KXn
za;_%)97wB&rA;pnpDB=VMX%kkkU3{XN&yT^dD=t7sXh4HOfWThhxiw*XJKJTFAqr*
z#Cik*E#&FtM~P^xf1V4aNKKuY32ITN|Ni$FlB*iJJ2=@XW}4qT;1hKylaq%NkRchw
z5;JNBd{W18aNc1Py8t3jV?9s#_Q%#a#*B!jh;iOZm!VOfvR;O;j1b+0I8u1{xv`S@
zDgUev(hD9WnnBaMwwi<2Hg?D}UB~&NK{A|3CVm;M{o&-e!dTWjHNt*GpTYlNh!Kld
zE*Bl+_mLnbM-`vkh&UwGXPu$ZyEpYk0?9RuTku)iT?PsD<;3gk$bqQGejjV*>1}Y!
zIkB>(lK6eH2CfO!s8YxieO93O@KWJ@_4q6Zi@b$s6a*z?Y<WUfzJI(<Yq0UlyNqjU
zUFehcvpikpJT%xY^(K&<txKO9LmY7d*rToJy^Y=Hj>V$}994U?YSl>pI&R~wB~*rS
zfV?o^R*F%xo~eb<VJ+V+le8=qq|Gj?L(2brR-?JQ7y!Vk_zh_sr)dR6C)MV-jcdc3
zg;-A0ucsZUHP*y@nM=!V8Rm#+t0!@-Dmac#DiO03P648M0jDMRU}go+AnHj4+?dNj
zC5Sm*&tiYA__t|}(D->Cv(KEgvz_fZ$fOY9#HsXle(iiG)vBR-UA*;r{6~20rACam
z$aU)1V^OkIgAa>LX}BPN3=O<5CsI2sY?Ng)Z2C!NyK+m^wTHDh7YM+%<OyWs<H~2S
z=qemomtw*Sl&EAz_@(fL0*3`7!ZN$W``z$GrdIEZ!4ra%c@@4r9K&DR0MJ<6Q-%+Y
zuFWI*`QQP=LYxn>hnsA3?CENeX`Z_bz_7=cy$NL6s7-59;u9q+G$totROSZ~L2lK7
zlK@%0D(JvcA1FQ9g}X4P5#Vzr(WvBu48g}YKZ{Z7ld{0vggi2tk6}Y&Da-emnWX+~
zEKxoEnGuO-fblNox=xk8Scny*;`OftsrJkk681D_b7>M;)o590T?e9k)*rfa7#-&S
z>X$XPFo8=gsWxoIeqYJO7<51Ul2NzWKj9e-acvOho%AolJ~zEHmR<stTYp#*Xxt_>
zsT#9)Z+wN_*WI(=QByhY^^7ZKOWLqvR%%2Qu@O6J2!*>hx_*x0TS+evfObAC5S#v;
zzb?c7yb>}NrtC}HSyoER$|-D6DyxnFdlhST8@yC4Qtga1Z~!&%k##>=^nkx^bGq3X
zX|xebRh0D5xXGgW30lJHwd$Ee><ZB^3dgsJ9g@U)8hFUOJ}Fdf0mKVi@QUsx@k{Uo
zaavQqR<)<=aC=Uovlx)t#KqCLmlO%k<!4~vR4))R;_e<q2t-rm(9sL%D;Yl!MAB^{
z9^HGce+{4;6&$E0Bw*{2uWZuyqPq6`ZpByE4ghyYj1lIpc0M(em?>5wKN{qsLs`A}
zaThpD)$?eWWkiKnK0l)D^t;POnvuhO@&zRO*`Win%gX>B1(joCDB&vq>}a@nkwliv
zSTMo!LxWo{4w6f@5{ZgLa1u>jWlW!DiRmP9B)24<i^#S3`fF5e1=!Zr-mCEBC5_QU
ztZIA3?Kq|<4WC7M#=fXp=No^chJi2K+R5~EIY9Z)D9u#2$(6)4BMxw$De0YXTkgd?
zI5HBsj+ELq_qE}#0#KD108q&o5I4ZaZVS&hAq3_}^lIe`mMS~2K&Gr2^e{SyP%2M;
zsvHP6Dnd1Rnm-c09Ot>2C<{Us8%I;?1GwD`QH$nfWZY;3(=u=(``N(T_{&-l*{GnQ
z1iOCbwNwqDS|<r=EtX0U$t0j`f1v(F=Vi>>)UR!o$SyclDVUZM#LlCRfM~>!q=wb*
zbsw1Hl%-?%GHhS$CiNupsmXDoG+!XG_&Wj?hcC^1v5Sz9`y$~G@<k+|=N(lc<R1a>
z-VW~oP1c!e*jb|9O>O+H!kT*F24juztpA6jZb@Y%Wi>Kk$=5bvRsXB`1rvOEae2_?
z^z$&Lb0RWH@tb<g2K(2=24{SvzFdzwV$mTErF{A9p?;d(RHTvOxO(wMx8x!%WsQK|
z;BV(P3>%Dde3ie(e7Tx8czh`p9$)YIP+YHJ1?}Tgg0@FX#0NDz#}p`998q6;+~Udf
zvc1>l5$vlfDK(7siDp|D4FVWKm92jZ>zKQ$RsAh;s5=yiHe-JPpdsB1`$tzdXokA_
zaZpC-dC-TAUPiYJ%{G#fr>v!?pbvZGj6JTe?VI7*XRIGiwIB4jzFcbx%0Al)H=?4Z
zsPIcFe4m=SdPZ-`tts7=xvY8(kqEf=I2wH(5`O-JZlgev3VUo3e%@X4x?!#`LE#{3
z(^C<>`*MsXtMGRB)7b)f*5ZrHu;W~_S9n*Deb!#vSXU|dFl_MeBvXRoa!j)PYD|*i
zMx17OwJ7lPUop^WpP5>s{9%lN!byy={CP}@;#CX+`0nE$HwvQsuYC!<bO0?Kzrjs`
z*EM|7E^sgdvjYCkv_8>S0Y55E>XvB1QL(1J3^V0trVuTEo4GwqZkPLraez-Pje6l_
z3|N*K$)#w3eiWl09m%O*5cmC?1wZT)b?!9);2D~KmzTfy#S0E3oko?a33E9ZMl{jB
zZbu@uVmM9nMTsU>SO--Jo+%<)*@gH;Xot1+s%jYh@lXJ{oeS9pY~P3;3iUlV`W9}L
z7J>nP;ye!xO}3AMFhI+V9)bZ5oN<#SbApO=L*i94+aRjp)JroQ+#ML2BOsC!oM)s=
z2N*nZOyLCcn<;Nlthjahv}sHKuUmegZQCR7S>faq0HH075RisXi7hm*)w->F;mHn0
zXg=z16^jr@n|6WR9(c+If{vetU$3bS4*+*1)0K?y6vU%BxG{*X@7!7g>1aG>LA;Lo
zC!&3iwdT_oExOI^62|w;C=49<iGq3^mLakcCx91{DJ8PaqORNuV!Bk!b&_g<EVn{X
zFX@bCi^RQ*ua(v##s5P`_h^`QN!FxC<fN!+fftpe8Z*?fv>-|qrBT>4R&Wl?0?RHY
zk}X7bY8i5}=A1HR0Yw&JX(BrgNREX^Sl%f0kEy;*RRx9-VWGc<LA1{pi>Pl^^7Xi`
zcQ>O8#zRz#7kho(=)Syeu<T7%xcZ}Eg+vWY{!hc~6o?u|oq1eE)UdKShpgX!HEb{J
zM|0Bt2@-dCw7zF&5y@a$%4u}v<dHR(eRh6b{$JO@i(t>KBY*cS%e1qrj_Iq371Oc%
z)1wkX`uFYFX`4AFFj4b72Dkr;E)YgPy6U}%vy8;jY3vMN0?bPltQs~@^I&dj$8I4G
zqGb&D&oX`<*Y!{H9{pGkOU{W+jZs|~*7(nO>J~%kR@f|%dyY;p|N4t>LF)-8VvZ6V
z{8aOz|Ix)nNYxxEK7d{G!ub)w_<hyf4g5wtfxSdDYU8oWws&xq>1+S4n=QiOGDh6O
zg7K%l3UJrc!m+kEqrgs$Qua8$?i&Bxo>!K&XLXXThJLS%BYz2&0Y5IBZtq1-C6FM3
zqcyN3hlW}r#^@V4WPf%v_7uQMq@(Cx=z}HRs*^c?hbQre(D9Chsp@lKUbYu`e1jYF
zh0+O)-4+1nQ)C9X=NaZcClN3$paQX}sR2DW63eyuKS`<O(Sg_|X|@H4AH%!{QAt`7
zoG?z+u`e75+=52}U&LmBzN~qo%fVYUe*8Wll8)%(*%3d6`y0e0gxU^GAq2bWKicLC
zOt@WG_)k=RjIaP-iwf5mEm6JsiRx|eDN)(K25p^Y)!r@6txp@3{{jZkEnlQdvr^NR
zXon*l;JkC@4s`tD?eK92_=tvnBDJoT^)Ec_s;>T@=X}zEy|qQdv?RV%hyk^f@+hr<
zauGl1PE>yF0E0w3-TFAKF>!LGEdRw5fG*64IDzpe3Dkx0Yz)zAe9<uYRB+Sb9h@w|
z0ccZP0lX|=Qtzg1k4Yqlv+#cP6jKNA+9DvjFUV3qe$)pFJ;^ZyTXpmhXLpjxq7v*%
zi>)A{RvnIpZC;5JnK~*Ti_DaN{rC*I|3eM%kC(pqF!1DM_VUIz+)-o%W9c}BtOXBC
zT%~-^LL^OCD;1~SbB>3$VPJ`0n8Zxp;k#nWLX2K;P`hTB->p^!_GbpkmNlwE)LF*k
z!F3jA{eE?CYIDNrT{L>yTI0ro(k-qG{qo@7S;^STS#nLSG@P0h%D}WgzHLYUHig3c
z`LV`m;kfHv&4OiP4{A_4eAC<`{)KHF`sx=oOA?l`#@M(YYDalKb%!Lw@Um8Ix-RHb
zm;NtH5Sist>9I)*iHfE3=5t}kBmw1%YVQ)!x-wG}ZqYytAK#!*{7QeqrU8dhzFw4O
zokAVD-HwZjf2=^Y7?Sl%xqF|V3Oia576Htnrf>@cs%jr}rw5m!ry!?@w?iArz1k*?
zqJb6U^W(e|_YD3#V}weR*5whW)+qf_y+fhBH3JS{iJmY+szTk!&RVjp=@73san&VC
zfqM~gx{M)GM;!=kD>~>#RvBb{qOu5d%b+hV2VhmvdU3iT=U#5VCtGz(!RXMPV(A<k
z;7ZKVB(~obC7EaOG>{g);*sc>GV;w%ins{(6ngIca>Nm}R#4;-6;wxto^sH|zCvf|
zyl)ddJt;)=5zhxTj#kwd79Hq#;I}{VOo+#ay48pml}3%NjI-Gl1AnyjKnmu^r0m`#
zWDKds(x5%+vm87@#kX|1wW@@h<h~=MP9lt$cPm^=q|te%yhNW4DQ0>)OsCPXUoSAQ
z*sajG7-{T~F`|*}31TQ3f69`Z^(qm`X>5YT#FtB(dzkW`5?6xIo~0qgX$OvJos}As
zn~JIGQ8xR(^&K*>ReRf2(yp1S20}!KeLM<OLHRXu-KS}iLxv>FnJS0q+f@$`eLI=I
zzTKbXWkPhq``>25TYTHA=3xe*l5cdmyT^s;Y3t2%$sgQen*^wTQ^WX+^1@g$<~g9F
ze8-x`l5n*YAy?Xf#Vce9jP@Kt&T>oY#8Km$7H(PJu+-cciKSO0bCHQfoSaTSiZb#e
z`)P5X-{EGDVIsBVI$B+;F7&u)f5iRP9x`e1-jN`RmKk9Ra7PGzLgcNQ$n(2Xr#$a5
z57^t=z^-MR>+=`=ag<Bw<VVQ`xl^ASoA~84Y722|y&1T%WRM8DmuY13;j5H@;>_vY
zdhI~@a?s3yDvr*W$yvT2QxnzWX9Ydo5JDK3$d{86D#XW@*fB-K3C)~LdsGPK_n;vp
zy)cdSPLTz$5izzos_A-7#}hI8I9?doXiml>lsem*6EZ7`I~eqjrtVpd+H=etZ7=fL
z6Q`Epjn8lC=0x(#Li%Y|hs7M)iw3;xKk^P>E%3SbW|Gvt!@1>!Uc5FmiZaXETgu|l
zRV6#+YQr69MbaK<Q9CPgD(8OIQ!f6jXO%rod;#3o+S%Dio`1BFd|zlS8E|E;R_%MB
z_4fH%avQOWxCBy@zg$mV{-Cw5wa9HBoonq!8Kn?qL&VjfMiEGjwm#(|E?^`J-iuJ^
zM$?>fMMLs`;d$9XXuTx3K?dPZGG8w#S2u7^UHU-F&GbtLrkJ{bxB}46c3{U~1X1rR
zaMmH7x_-5?yMC5O`2g`yC4E7aQ_nz#5y^3PE@u15!!w9<XR;}!8q<wa$_d_AvW4Ks
zn@U-cBN|C@2jRw^fRG5TdrQ5ro)LoPZr}AFHxR7!zEC%cElYou;FXa3GWbj>BeGK?
zi6Zz{38;<mNb9|J-WY!^3m5;}SGh8`YC;9Wk4^b?uMhZipF}A#V3O}cKNZCQ)J}aI
zwF`QB=3_lG(;rm%=+UC5?N+d??Cd?h^ze7}`ue8g243|I<pb`{*;;dy8BTtsiE86j
zFY18taxMd-qWyvO=G21mNuO4Pa01GQ4J*0=V{&i2ikHooQ1}gZmhvQbmf%nNybGR5
z)z6*2#pZ{T2`53^V%UI125;512fhZo7lB%qIO~FUXQmKR!&F!q<B>OV=~JXDm44FD
z?Sl0qarw-qvXLV<+@<bBCI6|onrr^XwGxqP;A>jF<c+8JeXq12&|K^KnI!SsvpxvX
z!)-85C{mvCDxGivvXpccvFooS0<rnVhDQY(nGm8k?3|RjZo!iaAKk>pR{*mfU+i?-
zEpugLj@3&WB<dv>a?IHESiFQJ4u~N|$aBbkelPn36!|^o@us+eOF{ng{zJ1Dq5y$s
ze(J-J%HfvuNbEZ|hHMWv-fVj}-e$MSGAWGJB<luvQei{6&N8>k#x3py(e5VW0Q~7O
zLJMNH1zce^gD8`cptp%A-M2|7ojrU30Cf?<E0Dw@AQH<WA`*Fapl^D6L2cN8jNJlE
z@l6Fx-Q8P=QJ5CVsE~pAcWt&4ILjVxZ<b(mGQD4zl*@tkl6<F^!;_mNu|2Cn@+ou!
z1a^_s9~u^d+tIay+i4OuZvI`p%ZG`m?lZ^j-}Rchsne``qIH4GHhUoYwP61|fus>7
zeU5@?^s~j~&~3P_ZlWriZ;`5q?>B1$rpyXoI}!8tJ#}*KJsFblM7{XJt36Ksu=~7-
zXOVOjD4mKzJI_4dRVP0~_VMHzJ4{D%jki$;lDNLg_kKc&FDziH(}1GCEzW9xZPy@<
zO+K@SD%S(tZD90@tlLn59mJP>UjU&ZDv{S?=7u$YvKNpi)g@M!_p6!UE9kK5tRdj%
z@<VCZxt_NNvhubss+;&>PeHXVJQ9g`yiWger7B<ALd3VIA!x6qyWlq>O+;r(OTuzT
z-@a)+Zz!OfD;x9XY25lVle$m4d!kR}msh%}@|ls?<ThV5llMgCfr-phO9t6sGQB&C
z^L}M}tM+CEM1-Cbqim^FuMCl9^(q<AH{SHiH@TQys&?H`*xpibB`D2Kc)D(!dV5^_
z@csA5ElbL6&KovYv-50wZc55E%iATZ#<}_E&Dg`Qr!%G(MuanvqJ7m~xI%e*`Y&hJ
z#0_I#Q26Glg-scD-Bm)~Il<d=#te6PVSZ)Hx|1=z>O6fUKYeshuB*OgtHkW8sU&#h
zkY$NaLn;jxYpY80<?8qPNx+%h-0VQG&S%zpYaQ2cRL>Gl?#}3Z2%=C?^ry0(RhD|4
zorN751mFCaHPokLzsglrN%gHG_jI^$PI}b!CPqYMaZmv-N}{-OgkYyC;|tx42VR?H
zJD+7fpJP0qqu&p#9i%P1`c-h%W;gUyZ+FlXtVA6^i{bL&&(+$q6W5!R3l?=p0?Y5p
z>9guJJf~h~TjsL4e|gM<P>MVt{*Dkzdj;|r^=3v6T3Sk(63w~i%+>P+=hD^l3|D0v
z24f**TdiXu*i*6bket1oaf};K0VY%nP-GM~N?g3L7?QqqHW`A2i4i1Lm^5bMXCapr
zuFm8x9c+m=Y8l(_&hwna)o`&Bj2pQxd$v8ag`XCd!Df^K`|lXZyrcT@W&g)~Nb+9m
zZb;T%jTgXf?5N#l9oQ@>?2ZWVH~&fh$Z~so+u8y%H(%s}4u-4K>>c5Q2hEepk3HSX
zqR-7%lZfj=brjDhljgJpMB3*13tRqi*_c$GyuqC%;o-kwOWCM4I+3&cHmzxcb@)*K
z=)+gN^X8t+p~I2Gkgw_acd9Z*8?$oFD>4VY437Nb9G@Tfe2xBEQ#m6ppFvoj>#YmS
z3rr%Qf6Yv{@4*re9Jg-n%cuP?p4qGw5sJ)eVsJNqpMS@_ig-n%jclR6@Q==d2{&1Q
zzaYE3uPe87w;$kJJFkc#rH%iZKkrfOa6#?{@(pDcYj;L!fs~t?fFFl9an^hK1d>~E
zL`7EOt$!%<H5%7R^{~02ro7QZKDJ)-)Q>4C{jHI=7zMAV;?i6AmGR`TG;_6lY^&bL
zm~_KvU~KW5ih+)Wf-UDy)!7>^%nDPN#HaPQ%odmOar1%%L1u*>1r5HmtoY&ys-z)r
z*^o+H)_vi}2{}!xFpCfQn=r{PbBDR5o#);P6ueop8aog#MJxE;rN(}e=QA{M>jy@-
zYXQ9-8s@*8oPuF+t3CEmQ4Y!s>S8Hdiwskh-1ObY>f2ayrA&8fOg?-XFglaC8kKOQ
zK_LZ=;Gz{6I?K6|`<yRQA-Cvz+JA8??STC8+^XUTgMHj!u-Blsg~(8h#k;zO`AVOr
z-`-7P-c9aaxJlgnZ;x-bYa#vpx6+a1qHL>TG^>ht7~UQV4K<j(W0ab!le{vKY(A-e
zDdrU9?if_*aBX$CO3eP!-R_%Rf52*QfL%|(YFB_==lN=TNMGcwRC01j^8Bo;4Q$5A
zUe@ou48mUODt_?o$$;~^U3JxOlO{0}1@{-<Y|E;C8%;3^5X_N|DS+?ih^s!t)hEQ&
z8^oL(!uB>$@rd^2c(->`w_U!LY-es36yGm!GRU|7Gs&Y;^V-jNgqX(Z)0~%;YE!-(
zgu97eE}F6exmlEZ>7;w<H^`*Vmc+Jmh9`WgEM6`NH&x07{gzb_lf878QK)=+>dSn^
z$lP3){;pE;^n~d`CpIWf{i!U?TMM3lV|3otef+2Lano-RTq;A>Q`DnMq08TbL1KcZ
zb#z%Kbc6ulyHr{NGu-QttE(Z(ucOVblxtovDkw-*Q4F0$Gd%d=xG(g0;N9^+pgr;d
zW!v3}mM5vK{-3NdzhGd8%1-_4Ay&mAkbi@<V~KFOS*3iC=*r>v2jgaW1v0v$W3B4x
zr91<VqRP+xtZY#@?dYGYOGbVU)PP2mOz*y_-~0E>hVt)@L~}3R)hNLm-*>8v^ZI;3
z$cK&^;1#<JX#Gj+Q1xXAXU8_H1SvUT%&dxEd;os$kc*YUCYYmta2VUQC?6Otp4jil
zdf^Dc|LD@*TH;*yl~cgaUF*&w859Xom1=hlwQk3kE*iOda1#9cKKe{y`kkwOOxa6T
z>ATwG%(SUbx$j)3H6wBGZb<aLYl|qAA}*lHPIr0C4S<-~C+}$pY<`W<@g*!4y*9-3
z?`h_xc^i(}iM^=nPBM)m*pD?yx%GRhY8~PdF<2<KORQL{p^T$3k~qa+m9}si_(s)P
z=Vs4Q=`iMVpdr2&xt5VbQb7_`kxJEL8MGGkJNv9!<KNxN!LCWWKIWHIzZ5}-582OR
zVlOn>6_#FIXnqgA`%CKdp7hpOywAaF=mnqg)24gU755(J-+P>P?{VA#%eRe=QiYuH
zM@xoRiI}+uhKe!=j3`Hq+-n`^Dg8pPb4KgsB3Ad)7|9!PVh5Z$7vI5(n9+FNK=q`i
z*P3&~IYv=5&F@BB@AHhkk~QLP{TiVh?tJG${pG39zX4KLNq{d)i{fV0CtDAAP?oZ$
z1x+p@O3w(IQHQunV|9QR-3VFP5AFPqTUML$5X>fD4#a~+NM+Pq7FfTVVG5fO#>uxW
z`w6HD9NtUDl+<rb``LFERgFVSFqMr!r_PgYQl5=s0p&)@k482##wEqnQ5|IMU^O7^
zc--hE{QLG%Yfv+D3Ksi&#C<&85qe#~{jEcB-#5-mQC@uq8wHngq;KuMkr_R(w68M{
zhZpc7DHF69wMdOO3$kGa-!gh?3I;@bZ+yY<;e0UV8<6-%SZ1gn26x|*H(pdb`WL;O
z!)xGLrQkUCu;`sKAhzL?a)}Oq_85?|r&`nk6|PccGt4?;G*-`ZFT$@E-FUsUr*-J9
z+9#nUO!5sy5!{s9MqLFW&8Gm<y9jM5b!jAZM%9t*l>$DveX!kmJ}>}WwV)}-pG>G0
zyHQ9kWT!>wN_VYV(G25HUbtSie0tNOBqQQv`N`TvlBy^z>(5Jjn&By5Qxr=2cUmN(
ze*#xwtWNg(YiTmVy+&AM^7{nzO=E-`>x6JlfbfJ1W9G@UD#8OKMTO0r@T}|l={4iv
z^V54~xP`e)7MxmPT`EOY@M+uA5WDfFyTO$MB!9FCoO*h-8M8BRtsX=^K7cgjNT>8-
z(5B;0X8@@JS3iXRTuo&IwF&%;gqrx5nl-9G8`>FpL26!1%`awSzK^zDO#IT*f3<P=
z8U4b>Mk(rw5!U$NseOWRW$~c8DczPZrllJSs!Og&aPtl%W%2*TPrkOJpE6iy93H$o
zeWq&<T%8Kgfj&c}<6^ero$m1EACJB9)oN$Cp0`4qk(;;w>t(h`jx{BjFDc6zC6IhI
z5|z?h7aHEAxi!PbmB)YoP<%f{V}B<_b7v?;YsYXR@ryCKD)T0r12n4MY;Ci*UM0N2
zV>a+X-mQI{RxjTqLD^Dg-GXi}iA+`=7|nmI*~_=(lP&VudxFe&Jq*f~mq!zjn@4lh
zG=v(c4<^F4P$2PmQUyFds{ZAg_UcTxvOW&Dx`o<nsWV@;amO9gmw>;IC|igQHl^WP
zd>e9Ces9HPi=f|llV>9aCNv$caZ_wn__83{_i#WU*VgR~;kXBz!qIlbGpR~kvKBtT
z#Ip7I_7~-}C+~6Y-LnkJ{1uJ$NE|r_>@BK&^Rr;wgdvz?hP4nwRW@ND@e}zAyCA!P
z+=^gF$c!{Pg+B*B8HdWS8<}u?(}R+&$9i;XY0tZ#nOmflhrMQdaq_HX;Srmf^wIYn
zM&(-X-UL)vU43ztD(H?wlzF}Lnl{(3bas(M>p@e8Z(Kpd5WijvLktE@p&!r@R7dT|
zqsM4eL&WZ{_JxsF%|m<wN|g69^cIv9%8JK7l|Kjm+&4t^)Mu4d*;`0CoN&o{tdaB2
zSgMpV4X}jf;fYh58xc;y6pfK2vd;EEV(6WkXdFbTeXMfzLr_qwoo%Zfh;!%7hby@c
zLAO;Dy{SCLIfeqlw{^m|ncHpqKsP_4c2W~}Qlm-a$g{J8pAX6vt}=)8Ngnt4J@5w!
z6v)MB8qWUQV!cdenJ!b2rx=R)M?5h2v&CGnq>5sEcGfo%8E-24@fPo<7Vms3v7dbB
zcD(z)sZSZBKD$#X<UHw@))Bi-E`CTh%5Zkr(sZ$HyWbG>ntsM!O$tORsl1y-i66YV
zzWOd?;PQCzY|SoU-(6nG&NpDyyGl%U>S@Ni%BM=|lR-;P&552nPpV7B4}*61@ZX6)
z=|lQm{#d81`*TO!S5n+p-nsq0viR610R_1ib~#dZ95UaTJ*?z2FT+*#lQuKvR|Nb*
znsX7EP=&BP-=!Ju<X=i?zGM$YDm{m=3kA76s-<?kj~AzYih4z5<d$xVWh&W@x`2=4
z?3<a)Z?kV_R*#W>2^Xmvx=}0^Y4|CNZ$QVhGbH}FSm~XW%#8SoN9`?v!lkfxC6Br;
zDBV`2wlnY4{Rldm+@`qGT=RYlvwgAOn4Auy^xU?LV#~1qkvgG!3F5(>G-X8b9`9S>
zF107zZ*5jyA4_(<cQW2@I|@v=94TAf-xLcyN~yqW8b{&CxjbPgttKOgzTg;K@8FZ(
z)r(uRuIlOCb>se1<rN2+Ud6r=w=xehzeZR!77!jmw;eQk$NhnO-epHsEY_RyEDWoE
z@&Lr*6zVIOaS*Q2dXsgAb<4(YtCso5Pf`}##L*uoHI?o$lS4pfZdWEJ6i3tU-Jeh+
z8{YCv{IjEc&`nPkSm!egdj(&~ccC<_)~275;mB)QP?#)t!P706NUbaAR=a>T%?)iT
zZp96}X#8AfmXY<QEf8YJW!dA@i5;)T$s;ECEivoD>8^$qPGdc6fmIxuY?l1FSy_+p
zx+2jYczDhW;c!)+4_r*yRTw2sl*cZOZl_O&u?$Po6z}9hflnq2D@Ia{flVt9)%?XV
zBDP}LgJZMLkiQzl8$K@s4cG%mi?Ez?f5%)`WcNB=cg+GJs+U|%lttfv%^4FVXmS*`
ztZ~Wi?mL9ZF3>!0Vkw!?Xv@evg&$CP_?`6NS_cc%1Gr}O-DaHmV8uMfq>UpQ-1{K5
z->?+&#t}WveUMb%kZcA-SwskByq4ht$o4i2HDAjRX3F-)osc%JVZmg>gIHR0L~h_y
z=&17cKAx;`L|<s%%8e}hXc<7`7oTjrCNHeus}(-G{+Z6tn9e@TVt-^#A$+Lb9HA`2
z!$s0~Ux?1{Nz`Yuocn%9BfJcLHSx_u(Irr!eOA4|b_@|NkH&A9Na(1tNQ$}t!(VeN
ze4evj`aKN<D}`P%WX+5RhpT^)#O$Fyupw86I^6pbuEo9+w`sgqPsmR8KGOSKwXx-8
zhzb3n%R%9C$0WK!UcARec0F9aORqPq4N@U&&2Q-WO@m`2Btn6+F89Z-pPILMJ!ojg
zWy&l+$vq;%w11{M(rOEibgGkm|BeX_c3U;bzwcI{{SS+G&70U5^0=wf(a2gt?%3O!
z^d^8f*_Los(;j(#8wOsi2*IdLujJFaq0&$O!M07WVCXzh#Ku5_9ABYO`aE00de#5d
zZ>n?e35%2r)yrM9&n}f3QO09+l;l8oueCjVRCDie!Hu^k8#34Q&^>YgrZ+Z-?VNVY
z+$=){=fmT^tt^c^t=&}nq2yy8=vrQp^VZ)%hFs4rlR{<xxd&5bn50TQA|qml7AtfA
zn~)~&qA%EkC2C@_X26pL-m5=X<YRt;)tadD5mxn2Ui5Q51^6>W#8)`Mjz6Y-UNdG6
z!hzZs^0)MvK|NclM#5T_i*F6QxCR`b?{iQvKp7U_{w65iw9Km@38FTklCv)9TR^Xi
zF<YEcv@R5`3xzF1py3~}Ray5lxH7`l7L!p8{%@t%&TiY$t;yW}rWbq$frgBz5%*7$
zMrFL0HJzm)(Yk5)z>sa;@06D1T`%vuQ}Plh=LNc;$w~sfy@Lld&9548GL<j@OY85s
z@9{E>80P(^U_kcCn)lh6l<rYT#dgUyEHZG6_(a457j10z01d6$+&crCsLlFT70zu6
z5k*f1bHj~CwZ832ZxgEci1M9e0hzw?J}&ZvYU;3WTBV2@G6XiDh5gpVl7Ki)3+&o}
z(*y}_KEKh1?5VdO-<Y|k`h9orVn}cJ&FhYl%H2@CRP!#V@TH7!)tl;=XrekmqH9~V
z3Kl|$>M%+sOlxX(vh}_Z+&1F^WcRL5rTn7YH&ZI3#9&d3L~k7$kkzAOs9_9q6m-``
zMq`zi!;OVvhy3TNtE{#?jWH1uhUiBYye6_9{tj((gu?BA!o2-GdFOQ@V^o?ID6iYp
zidqqmcJ~G$vrlRR_cKDDi{L0)HaGmE4OznH^R@&Vx}#V=bgIlc_|Qz<C4fCy7Y&Nn
zo~hRSlM#8OHSEDfZ8s+~;lbyk;asrjc~HiqySmtTpP<WRZeeOD+3uJ3{OEB=Rz)<`
zxlZ8o{U;%1rO8z0V~sKMg}-beD~Nru5Nt&b6;^Y2gv13`s{ZzX;KX$a<W4#U=4vi-
zJ7t8V=QmTy9k9gB7q7#(x-mFr6VlwkxITUSde`*zWr1z4o4kR|oJR4bONqy)b1sGx
zoVcPhR;>`L)g{lwBL(8*ipC`5B7Sw<$m1Dn^FQ(l%j?4)N}{e;Jrf?vAq8I<l8$c|
z3h63x)iDtWqCxU(-eV0vr2`Nw39X$7GPTvEoe@ttiW;Skc1>B9h~$daM5H!;QhFM}
z5?jecn-SBhHt|h*IzX1;n{knNNS3P2O-d74_gZ@yng~=ACrsK=hKl{E;T?{j0D_z<
zuU02J?s%Dd`!O@c=|GFgEnJ-P4sk>?ytCk;?@ghsY}Gj*m*P#POszzxKE_y^si3AY
zzehSmN>TzHxfV$re8)(dTeSsFL$dT@?b|H)>b3!|E=2C{H_H$8;MNz8{BLAgGOY!_
z{+#SOqI6b&oghLM5Uf2fF!B}Ubq%MSMv$JID_BfaXr|veS$aF&zRGZYN|EG;FJCa-
z=X1_4EJZpd7Z2b4gT1Q$bFvNtWzUZpE!#tp+H)v3R?HcTvqWJrI`wgi$7DflFpuLx
zOqX3_(-km~z!ca#c5>Mw_4(>80Ukgw4QSk8q)^!0J`mWhcG{|jOFg=r(LIpypCR*a
zu0FVQw0pWvZ-=cKfG3qUD1Qn%Xow%WHx$$(p7_qTq(Oa!x_s|o*D*G_=Ehi>&(+wD
z-}_2tTEmj0nrl;oI3D7zBX47;bkC&i--TewN<-{K^&N}hEnX*52DSdRiL$d&^NA9Z
zBa;%=XG48OwsUkFO->_$ZLy$h<2h$#sz=b!QU=-6;}Y2;GZ?FNiSIwV?$W113P$kH
zoTgKt2iwhQ(|Y&USDHi2MPdf}Jg^;O*VkhvY_g%8tZzJP<6p{r60cF`|76s#4R~Ak
zZVEPqoVyk_ni`$2d@=6pI!@+l`N|XL;5Zm8@BJA$9pqGdqj>g^!CYl#U*PM3Q}uz&
z!=oLuEJCHISu>9rwgh&EAoGSm_GYen;?gf|2QU2Hkl%p=G)_ho6c!tJQ+#W&5^XAw
z;l<ixI0_uDA}(8DCv@(-5GrBl35&o?8B#l_Zy2j-w-3XgmxUdo)MR0XNQVjeJC?h@
zc*DQOW8eYfQfFmv#!DRz&H8@{1a!ck63A=`Q#KcK@9*BpI_Nn?_Do6iOf?@o*u{Bv
z<LJ7BoDu`agcown`Y=N{Rm7W)?~x;Al7}a+V;8b5Ulm{c*5SA@hOt^<v!;e&tdUNU
z7sixMw}cly7dnPFq{5~QTSQ@%El7dTz`TBtiM~G0^WXQz|D1KD5zvK<7k-v=$R?ab
zlLFTN;#NP?-bu;Y0kjv(Al1wN?<w>OS>NR3Rc&P#zk9IhabdJ}+a!HcBnYI@+@1!Y
z@=))cilW<YJ{{M%PqS_8sPDnETsdyU87EA6aB5nu$upJYqU-!+tjh13hm3<uEKr(e
zw+U;TcYPyrq!e+$05%p*BReo-s5cR?x(FLv$uE+>Iw*T@)O1?nd+*ECnB`lV-o)#I
zuzO!{)n!Ir&Na`ROhX0j?tMwBE&~NQi(DOGFSU(BOH2<?uWGPYi)u*PdKPQv?n9Ca
z=`oE2=jKP+;A*s>b&+KxhSv5Q@pS88&&cO!(7|<r*T}3WQd3s$y5M6ZS+&5pok>yi
z3vyovfyrQ&bz5Qf0~+UV`es>5<1x3*g*TeP;zJzz!Plfx9;_RG*q8|0pp)HNsG%6O
zyHyxOC@{)cqL@0!oI++cImulhr5Ey`4+`;fs-KFv+c*P_V5cN5)9rRE`9`(`IRsV$
zx#*|?Ffc0XzxxGXAd*W;v`VqdBgD?#gn;MMWm~}3MUY;L7{Ewr+1;iJydJ$Xn<3pv
zan8P_QV~>ky~YtN5J0>wfxJY%)&{>CgNn)$v)~Q}v4#I51I?vg^GJyLT*d6d=z;4B
z8}cl&;P+4$Xd7BbC#wwW9a_T`w(JaI=%zl1nF>dPDDxi6WGv(PcsQvv^gw7iKj!J{
z>rvym+f-V1xnLeBs^~s&SR+uD%W55-(v$b`oyy~IzIbbR!EIkWcg1>;Ohe0h+=O<)
zcbS#N^<A)Wn)$N~Rsbnopt!LRO1~U2wPC1TXexJ5QADQ`OSGWC0`ZQoAV9Ry-3y!N
zBJTj}2JlSKRzMht7iJ0@=}H3+je_&<KVdt;lcRtY2&=qg{-S3^dEJ%>gj+5>`X%);
zuL5v#m^9A95y6p@%ux5`PZ-CmdP!<xa1iuymdybte`5Xal^sjH&m`NO!hyRbU(Gbc
zqiD0C)(csI!nN*`ilGv`AB?ai<WtY&v!TC2gD<@<7HtRs@jtnQw#Z@nX~LrBxjWzf
zVsYT;YPeB7fs6TGnAh&}HfGDwUgJN(ENhZs;<Quk_{d4&%hVD%A>wTZ1@rb?RnZZg
zw)OTuRDJ)P!2h{uFIW|=!C_nf0+lZ#P&MUJuxQUw6>URR3BCKP@IR;pdjPQv5$a=Y
z{a)3OV_invYuRk59Q~6Y?f2^W^vFw6elSX>krEbniIvHC{#U&iOq^k=orZ{rxh~^B
zu<)GlA>kB_KCfZ+Pus<nUXpPs%Jn{?R$rt0Bzs2w1YD=o5XgoWM}8!5REKU94>{In
zgueDCRz*jwiZd4RConj{oVg_2tNagCYAf<@jvTWyvF#phZy0)8jz(piR+lvCrrO1h
zuP$60yeHen|Kj$#7AH=`^pJ>YJMb@@vqBt8m{&QV<tVZ7KSavR&f#9W=0rpV^!$I@
zb)A_&L>)lPIkNpPM@`y`$X0S<yBfxg{xXq%@w=8igNQn@T?DQb2jUe=^$$7+h%MtM
z(%35YUtLsjhjCu7zB@8AD15b=?B~oa2s66#i<+5*i?B#r75%dvZ=j65krKyK9z7Jl
z->FzrKR;lzU4R`VFY)@ZB8?CCdh*ZJn+UIAo8r@kA;%i%``1!LR>gi?8VGI;${m<O
zO3RQD7RQJZVDi-es{q)yzl5uzCy2uJ$u9US0cdPa@{q7aJdwX8HUH&=zNXBEHc&nJ
zp>{U>AD@Kc<cUnMB{tbVeDipt7#i_fgjnQ{2;lnv6_Jno(>&Q0&t@@0yKti)gxk#i
z<OC}y5ytrg;4kB1rEw&L#S9`jht6ex^+;;ryM{f(CQ*<0^bG$Jm=60TP!;V>%sKWq
z{*Q6DI)jLqMTm^EJ2d!P$P8vpM07z!l*U~27g03KgDBoRL<#)*4*n|vm)7#;Az_7>
zkA%hCod2}Mi+P49Tj=N;2G=mN?opF^VmzX3sJKnNeR=3#2F^s~L=a)3J`$|@A^%lQ
zuA!F=4PYYjLZ5g8R<U!-u(mxzuxg(d%;Gq3N5(05aZRWyI+#dr7in;fxg9}-`3?zz
zqXlMXtN0f~H2U5?)s$M`*Jvk!zdcy!mh=2GVzn>p`R)Z9L+naer=D37pRMbCc+a8w
z8Py&3H|~%U(4;@qwqK>us9?v&uRG7b%!XDGONjjGB;#bx^Y^o%Zw9?!29*88IFpV}
zv662KhlHoTKn15%+^y`Zr@+IvDQKqDn0~bPy#6~xIO|ot*U5(7?Nn@T4BD;8X_+G(
zHR*l!a80Bty7YL}(w>2)b*^&4WHU}Ofx9Z2wL{VMMZ>S*9q&lbalf2<ckfTNzc{aC
znQE_F@GFsVy7T$oU82rQpI1JdYM1}7iW17He;;K-nZtwQl<U7c@ct!D_P+DWFGIo|
zOIf@*Q1dB`ztr7E-@8jS)lPC=dEpt2swQhj8Q3}BpZfQCHZ-P9u}rDHi{eTFZ0G!V
z>fguN(B=6oZ#0y-s_|#rkYn{drH9hy_6!>HS@CFSacZuDNY#|H%JA(9Vs{|BI=@Y@
za(Ml>=7%379}^4a><-dTh**rj`urE1B~J3OvOPoH@oJGhL+{b(rw67bU*A-{PgJgd
z5E?ui>Q%mH{TDp_on!)MRrKqfL42o?;Ez1if8f!QZ^MR!d6<|&ykJYx|8f8SU1x;7
z&}KI?A;vG+`g5O=(S#5aX;$dG(cm1nc*((2AD`a;g+;GAp19RwCs{RgS3==#N=9-r
z<BGdJs^q_WAX@Am1>D|f$P;e~{&Oi2R@~B5)GxO0)2BC~tLptZY(8r5CJ%P_$+Iek
zzLu&j=@oV>&DQ07IH~`?A<qBCIXAWc@r4-Z+{ir55+YOmMLZ|B@cZMrN@c8W3RFfS
zaII^9A@9Uc?bhX%Rt*)W2G@!d%cS~4FH3dYWQ!2_oX7tc`|~1@GV+1zjTIzaDZ})5
zzrX5F1==WD(uIuJW>YriC<Mtu&ekSNaM@%0<h)OIE#W@r6EPOM<3i(wxgniS#->(x
zl8)vAS_BF@B_^~x0Q&)6I<mJtzICTSt>g%`H96ds^&@p*wF($*sx@=#3UWGlB_v^*
zwQ$j)#@YWMsQXUQ@a?;nGvZ7RWB=aWKKFI3VsD*uVvL1IO16s3A())oc0PISl(~Mm
zdLK|SD5~Sg7Mm+6-Z~g8B{3DY@Q_}WlN^`6@K7pOJ>B%uUxRafzj?8Fbj|B-*{{gA
z<E`G44#T#0E#Gg7Drnh-U5#@KO?_H`+D=V)UWgRwZ%UapQn`$^%KH<kCG=0oZrCZQ
zn^w`a#)n^>7BV&|Zgif?^?Sz!xK8p5IhN!)pT9jn>}d6#BBJ@Qa8j9*n18qVvUk)T
z(CQu1Om|7YRaV{jsvsiPwLN{oKN!VSt$-4*aS|8JI<ismGp!P8t%R{X6gw9*ca{B6
zvlhN-(-=7PL<q;(%0Qrs-8Og`Rx`;d<QO>ay4Tvl+GKl7I+w5RZR@l3WVp*gw{Hh}
zsT=#%?)bL3G5IOmgo4o2`vs}PD0L&TbFbV=@>Xq%7<CKl<7EGQHE)~a|HIO^$20lA
z|G%|rk*tysMyXU1k`&u0m2yZb5i+H6iYZ}Zrlm+|4i$y1lAJ<^IkQd9Ip?r)+RSP)
z?7-Nt`QCkgzkl|)x81MT>v~<+>v~?#>$+d}eWUbur94*D{&~>gbr&BKcS<+>)5_e}
zAMa|6YaJQB@3q=VLYzNYw;>b0J^rRqc2|DIs5)f>{Z?5VoME37c0=4je<y(B68YXp
z$0WdF(V=IL2(LX=9}_(w=Zk(lIK;@9DJ18A`6-bxG{*mmSKldwi&Hibn3QcV<i{;f
z>4peaRZfcCH<%51zTND(@J#AKXqu}uYjBi}1aTZP^G+{b7snun$6I7C07Y%AV+GVm
z30OT-e`#&i7nJS0?C56;(f>7EqJAEpX+l#zs_12&$=f}<>`+M<Tu3m4rlsb0Us^qz
z1nuHm2PK?JJnGk<8B%g<A>;X}y5kMY(OT#FGfl9HKVE4Vb34^3<O8YsW<FvQ$^Q6=
z8lPqI<k?t5L%VbR-RnK*TNEv4&RJmFWPZH@MG_&nXiRoBeFuC<7(G~0VeGp)$XVjR
z(^K;+;v4$jrKuq%t!u`@rb*ikZlb##XCi8}%`ut{)H;i;#zfPcv8=g^?IbcVCQ*82
zw-c&_A3hTi5*r>hSYqabW^`ZND(zB@`teRhksA1Ll(&-ca(mhK@LSkG`kXT9{h1;)
z9DS|3i{;8OQ}eWO@ak>)+@9gw(>}&466(LE<7cCfHqcK`ou&i^#`+|lO@MaueTMq&
z<}JS7jpi7wB$bP{O3&~7aU4Hh5muZ&8Lsr*K7r`_JMv`RDQe$JX8+_lMMlqC&v%R}
zeoKG8=+zSy<vUVjEY|V5SU5Vhr-ZxTgYFSaeG*&*^?WQNedmjwE&W2pkth8WSLJ0_
zY6_|DZu9qJqdBeNY9(C7STjWPZ1~HGDn#0NW>{&uZ=AEkk9R)6r3CM394BmY?3W_%
ze&Q(aU_i$9>=yp>^Z&%#HjxyfHWqmg5XodUuYa;i5$Wb?*vspfe7+q{7>_h~vU@2T
zr0dr^r;d=Q)iA1pt=#6<#G;Os0dlK{ySm*+G|*?R845HF&R9n7Y=BhmOPvfS&SY)B
zM&rj;?T^QC<Y7EjV{ET+7<KM&Nx;sA<;8Q3^A<MKncM3!#<L0M&&^xBIP0^efonis
z&gLrFCU}11!wF@}*~Eq)@6r#ijQNSSb}z@o^u0?ru4RlI0=n#|1O72tafrjYc~?}1
z7Nqyc`G|k_INO1<#x=B-{wgx0N8N#AQkIM1TTu3!NEajQHwAZac|h9sy3}zyTkf9w
zO#S%@7voxKLYM_Zdm^n!T_%=am=kWg|7S<+>iyGokCaAYWL&q{JP#i(Z2|qP#9JII
zDOZ|)%=sM=8y!w61|f5@%#3O`W*KO?#w<tXypZXZD``Hy`^`a-S2;3>Pg1iPy^|Xw
zC=|gENrEW@MP&5nsA~xn+oZAYe8WTKp-f7IUvHBlW6_`nH)bP2d5eDs1Zs)5Nqc7$
zc|Tja7EjJwgd5e$JbNE0DbA#9uS*;Esl5%nzdG*2Y2FQS<qKfAq`O0-ik51B-OY{E
zXF}u~mMw2_Y5s}Iv)9E#&gDwmtfOadiL2A^Xk{eaU5>g!(YUzPyhp_xYuQlab4J<R
z==ue>dAZo`=*~fWsqt)7&w*}wxzc=#2+_#jdFh{)3V4@t?9^p9oB)Mr_8vA^GHS?+
zdXd_LcYkX~FsdDh6m2y((u}A~98c(RcQX$@JT#u8*li;*&_Xl&`X{{=Em1FuLCawd
z35YJfl=?N4sa$IYujkuXeoXJdpXsUit;qY5?|BmZG2FCa$?!`kO&y^={!*#(n*iIH
zlwr<PTx~?p?)so~tO2#$IEcTOSV6iej@JhiwRK`fMUg?pNgpX)KG8zFA+C@7HPM}G
zk$2kVaP4a8!rb9dU$=R`*hSgcAU+iUjBX>?#LAMqR(>3Zdo|Wj0vIV5m3PL)7~5D{
zu0(DYj~|ca-OnxtZM3vcLUi+Omg$a@Ry>Mduc{hxuB;feYPE{IDb{S6`?+<ZI$aGX
zv0MlZmFzUFem!os>dm#HR$R<6G{OF;50kF^&@ot2Xy7Cjl6vr;^Esx9$P7PDr0LMO
zTP)<~@V|*TdfpO$h`ysGo=@tZ3{YHceG7`SibMK{vt+<JOIW0ssZnref!TQ^El!%L
zBaT<#PJ+$fP;m+4eX_5iUg0nT%4B8OWopm;H*!M_=CM>dV-OEt&OObzE}qYs8aDrL
z)U%s^eRT-9G9Zme9}j==)4XTxIL{c{chVh9iSw-M=3ky~f2lNolA>*d9eM)jrc#{K
zKN+V;T1hVkO&HBepNvO+1w>Sc5E?h=L&_QLvJpLlCHV%I^98`fu#@~e#nrHTfRH0k
z77M!7aE2vxF}wOLXmBL)`bJq9V9v3U!oZXN9P@wQJm*V`L0$a8TOwui3vyA*S>qvE
z<`-h`POB>Nj?)M6m)>e157(Z4Ioeh84tLZD+t<GozqG$)dD=x0<>F-d7R0!&DKl+Y
zmDb|k<6f)FOo$06wJ}WCKMA%wB;eZl-Gl$ER$A`Yo21C_^NIofsNQe7q}2d%2u$w5
z@4G(@+-!LKGoZ`aQ<fr7L*A`l-QHgfFXmVt#-{r%gbr8$mQ!x1(HSX>J2a_^yDi4r
zNXg$Sf2+oZFLey!GwFF}qHl?lo?$IJ&Lzm2`7U1o1*!dA?cx&@xO&7zOWFCPpc~?A
zuNIbNP&889Ang7U>NV8dKS@%w49i<DujTucBQT7Ot_c8y^N71EW++l81_0&zDn!ZR
z#zSP~p<Xkk1-;SgV|U*agGPsPPp^854YPObzRwIy)GOA$Vffk;P(}Cj^OvsgjVD#z
z!BD^K?GD$)@%sU_2Fu<52yIyP^ybpY-4}C2>O>)6OoK4{gri>K4}>Yb`^?FHvafY4
z<M7Wxyv+sK8AV>kEv{9_NNKYoX#qesgJ9%qquRBQ(p-?<eY=FCx5RU3&jmt;xmRb?
zjs@kZo$wn|4@_!BiGa+(v5Ti7Gc=6<Sz1k6nF|>A{3bxsH~LE{GatF3leBSQMP?e;
zLUzRDg5XBDfG+;E^*?87*DXo6EApOkx(Z2`EYBvD-xPNw0=f}znR&0$pf}Q|V+?f_
zx%uCZj3o`^oHz*%s*gf-@-1$go}HwveNNrfP&$@#{Uq4-!fJscl?$NznH-p(B6a=&
z&`IU?iDWG`M8GF0?DpGeR6tpG%nUa|ReHxF774HlDDfe5wv|r@14NTfo;*Jo6-Uhl
zZL-Nd9e!J!{tQccj3E1n<*e^$O|H@6()cb)fywAGyIv~q#=z=-?%-V-7jtS3ue3D;
zYN5ADUCbLw;ebaU2iQTlw|I(sN6YuWQK0|ddVs7}?(eA<4en7F0fQyDy+3VXyh8fd
zPJLnlu7<doTMR1hMa{PHbMs6;adHKea@7X9YQN(o?P`8pm!fv~(_)a1G;7Cb=J+j*
zKrL6|%k4AY_&&*$ToBdFHeuHL_izQEoTG2Ff2EJ_`5LG-`E;>Vsz$Wv8N@rIEx&t-
zfBXE?n8eren!2pHvs?+56!yikVVHW=QsBv4*&Wtx76=%TL-FH2(8t#Ob566tVE}id
z1$*4VVYIm)NxzSeUv&o~&eTkG@gJ-HH2*ZpC;LKTc@|wk9IY_NgoT@8k;~8S_Dz#E
z5ysdV{c@$1#Jf(Y*y#D{Vvy7OkOu=w)K8&0Ph~}f7cxk>(q*reFr9{OHO9WTAnML+
ziefb1%pJVYAm;1DQWpW7t;&y!Q6KXum%@}ZGq%GYjYp5&M$%_CSUw-$gsKQ-Iwht-
zyv0T>jN<0E+J9U4&WvB?!RyCV53A$KbQun%d1sbQu>E)3!Aq>;oj1hdVIW$lPP~%4
zQuEr6ODmq#1|MF@!vG)~BfFbCfLI0m?Qruz3;?mYz>30&%}vc8jrVDo+E3D2qc7%I
zt0Ufe0<QY;Z}xVrW_~W9<qUxJN1)$Hj{v9i^1E-N+h&07@B&(JY+kfKmv*^-ctb4p
z=s(jS?!4Tt)y6*|`saAt$Q;esaQ`u*w;<=9SGpgUEC&YhrhM&N19N|Ya6J)q^GHJt
z3Fx2{oO?P%onrSjR$lAaristSipZ@289jL6wIA<n4zK)d*s)uNxFszf`1E&!BjA}#
zMN8HHg-!60vy*^t?r&~;3B=6OE)>v+-qZc;7N)xRODOZzNAl#cSVpCH1AvQhOO{W^
z<B0whbDjX#nkZf#{&4*r?&VSY1ZZHcNg1FE^Ih5UimTJ}|D^bG*KJ-cmVxXCgtuTy
zf4j!!b=?7a*W!EF-xPmSDOWlIkoD|F{_*f5WRAS?GhiFbt*igW=`}Ghe>G0%_)2O?
zBwftGC~E(%EV=XsB^iu5Rp|`bXpwt*qnal>pJe?8a!GBh;tMeHmkV75irsK}*W#ZK
ze!YH*$Rpi@c*h=X6*o}~wwNPTpX|6F+ifvAh}Sa4W!CfcyMcxA2w+sZin7wp>?f_}
zKz;89wM|NEfvEB|`Fwn+wl)C6(d5;OMF`blb0hFfVMjHx6j(V&h&2;xl=&_0;6K-&
zU+LmIS01th6Rj`@)NuFufSIF1gWbrf<IyN`DAT8we%W}13&c-o6Z+2HhUJgs&^Kxm
z4ObPTbDe>?cGOqiINAWN19+Mv+7Lk;-@_R)=eLdf^&VFw-FsCG;u^~=@#7>|0N2Xe
zgC0L9eLQ=00{>yl@ND(yAV6cMfW;d8*zhxer^G12KX)wa9ySkNyVRNHO7v9HQj^z0
zyc$m{DGOyb>Hc_^XN2vl3bWunS}dr#A|1JIY1k5#wgdiR90hEOu?kPDIq!{L)xM+k
zQ)4{OWF?`jT<K0@<cPW=uc~VhA9A6~M4jSuW#W+%Ht{a+s-m_KUkoY|AnqM)Fqty7
zouqwuPM(AnWm^zia@8ub8u;2{<WlbS_t7N-N(?|7-t*xcW9+CTOggQQ4I_<bj{!?e
zO1+q)Y6RnGSupgX9h16z#1$N12LIikJ{cQ+)dvVPiAAbLwWI6Gm2QsLE$@njh=%~)
zV)V?dmA_?^2Eb;(&GM=yD|ItF_T2aK%p_0lij5vDbUF#9oRA`KjF!%5?7i=`b$;$*
zENKBi3su>x9d(K0#S5tCJpg||rJG=f(gB>?u&S?yxMSfC9wOK$c((Do^o|1FT7<T&
zdpaI24dBuu(S*v^<C#N8Y$vVg@E`B!Mk{&B08}XOZqW~~B$Wbi+jG<)LaRX=>BY6$
zHp7XCt>E<lpmo*y$2&7ux(G05La*USE5G7R<lvHAfPr%@?EiZsD)0zy>VdwdR5bFW
z05Ia?4Hfrk>NxM=GxAy)Ps8phw}-s428U??wEoq&#eM&q-O48`Pylc1o(ZF@o#Cuj
znlFm8+E)n-ddKX<Y$vwl#hm8rEkAB#yuI!3mvME^?$hTb7k$sQUvJxw&A#~k?e0yc
zTeq5|W)0C@Ob&9A8xph5wc~ip+|W7(NjhsuA}k9e9&wAyn7YzYI_K*xre9O4A!Co9
zNCln!`uu`bT+Yky>q(>E+n~OV+~s?G<Nd&oha_R^DoscCi~f^b--8}b3tF%;C|so;
zy?eN&4VrPD`^}8mHrE6~J`Q*Rf@)|tO2nIr1Bz&o!%L<yQ~Uv@<A>uIO+=n((w+Yt
zeLOuivg=|1E$+u+5;$vHHv^BF-n&>gbh4<7c|x@b6ct};GJ!k@6=zOOiI}E=oQJmi
zf~aP5;ycMJo>tt^^?Vuf3D`47Dugg|2IIj&((46D%!%#sV1<nb%j97bS!kWFpRZIg
z3k=tP1|Le{m}R0X4?$bsNxp-$&(qDIPj*oQ<*3g4fDvHjDp(dqK<hg~uzbi1yp{sL
z@M205$h5O-0@3qlrSh<v!Zf&17L2L|OBh1IlC9{g>a~uwS!q|Ti6hs=TLrX&ShtzA
zyy;+Is7uk|co%KuZ=wg?J4v^_8$n@2#2MIyXH-4tr@3#7|Gr<SZ-Q2CDHsSMb3Sx}
zM)w6RW{8o8pgn=)rFFHRG8-jwZs584xC<*80?gEtTp5U{#<~HyPxUIOW9o5g#ETF0
z$q1P$Y>0OQqWDHCM(`^)s789JVJ2MoA}M?tZ^DjS!{20lXu-<=-Ie8f3&i9N2<+6|
ziyJ6Qr`uY}FB@w8hy3ES6#8H)D~5SoqX}fv<`UOYDM}N(V$lmXz?wKWAeVtHPN==I
z<+doZYi0e{`F@Q_;O2`6s2t<WqN#*vO)*!%Q8KeaB0s*q(n9k&ny*7uT^kUpS(_i9
z0KZ^Mw7lLt=b#$Nv~kmReArz)egkr|7sn3g7Y}4j;|JMomzay^<H1Bd+zuG<vT^tY
z!c>O|Q~B>wGw5piK@k`|wN7BwU{u`ouw^jx3wZqx*{r6Rg4sEZm(7sPAu{n=V8$u~
zpH*o-@1KHiKlXQ4#4SEVdu<rdP_6GHsX($mRDWKJy&0$)sY7U<*(!df&cb(ICV8yy
z-uE(smi0mjds{UDJdJhujDDlJdI{#m`RoE1hZ6P@?d7LjEISpsi>tq26;QZX^1#d=
z5TAUoyx*CBy8IaOoM_6F|0~o3hS1F)s|;$6u0!h(g-h$voNI?lzzX}2K@VHBw?I1d
zO2^jl&?jNR##f4lnLAsWKsNiJvkw+!)-WShZLVw$<CqI9IPs745V|xwm2lpl!(eLM
zk?wHh;`WQfSRRlIwNenGKkR(jgQ=Cs582uY;6F>`10WRo<gB}uz#IC=(|gWJPSOJN
z`V{dcVXh7_;Bta#9lag$ycdzb20gY;K)e2(;l<xXZv^SS4shPG0=z#0U&Ma3nGa<=
z1+)C>f*(RWbf9XE(tCKqjw^Whr$eXp&Cs0aMo=I53Y7mG)dY(1jh->3U!A-OVKcrw
zhhS$pEWAI}{lGTtRTsTToo7?ZmSW0gvq+s6SdI0F%GU{SzB{P+TRpF<fCl|}V)=<J
zQ{AEoWS!qd_>X|pgQDp<&bRozP_sy;a-q*b{>XhjI%r|l=h9i&_qz;G7%rw#V0B#f
zFb(d-(TzOz3lxSh>hFZMzF$ISqR(!F9Gmh}ksmwg0^4jeG4~(3!yta{JlQg0Gwg0U
zyM34~Ij|SeFglI@qW`i`0hd!aoWiAcb1zUXo7^3vbwYpM8@f19UvV_-E7-QJ!IY+V
zU-Sh$bcsS=OOlc^;h$!|<oe?Yy+Oxa>_s8l(6~{BECMyx&shU|Gk%_{QjOB$-`&Fk
z-grWtdgwFUrNNDPSqSzldzuON+7i8?cK+drS;E4lUS`W*^Jb7;Ymumaqg^9N`(kZV
z2KF<Ci9ABx)UhJdh3?B)s(q_ou^m8B>(`}m^&#ske}N)3-AvaY`<e_mPizea)M}$m
zfJHv6>}Dzlsn&y@%@zIL!WUVOOylL)_zz4D&~e|ht5Z(=Bc%!O;D^|)8;Q=NP0%Or
ztLKePWKMwlTR$DX%``A+1Qjp37am8S2@%l5E##*rGt`4n*AsL<Ib3;3mi}^K?iB+E
zkEW_$Ae;Qzz;(E(KmiT*x&_Uz%hv-zjk-@tdCLGwgh9#Y03<`HKz?EduLvGwx7>;c
zQxsO7#V)YRRUy-Qklh)T{u8$$)9<UvN$Q;N-Ce^MaAoUAXE8p_EjDyNFp*C|Gu59q
zwA5evP_6ZNd=V2p1VP9_MFnW)nt`HtCh!zR@Izm1`dFhRx(NjGyJok>ap@u~*`DhH
z=Hv96K%;&n*>3dB&unjnVxA+OlXs2^W8-h~cd>43df*wow2EI{8WnG=b93T-+8dx5
z3(v1~Kd>2jzC2j%Q?QLczK(^TC@z~?JC@&LK!yAehabH=VAZ8w{vj;PnC`goHpC-W
zdiH=gxs!$05qi4ttA?9E4*R<LXsXlOA&NTP_d%9vx=`N}l2j$4?V>5Lz`1|Eevqa>
z7id+7?ciWs@#i==-)JU)2&R6vg#|yE%9>?b)1QK4;qL}EGEG>Gpr@?2VDS`IKvUVl
zAu=Bm0JZaaWEHC7)cX2qe2i&XL~rBu&uAS%Vs1nX3ESTQMZcIzPNzjqD?>EH{03U)
zH;Qi3K!1L<&{~}7O+Z*tV>N?*ADfA8IX)Xn>-rk60T}4K0VLAPVutQ{CUWWiW=P|O
zQK5o({3Rf#GI@0-;E&)#qa<v|W)Z}wzS?yyF1Z4^4(Z;~0R8DG3XC?9odZsED~tm_
zK$Y^YL!S3U7;lCJ0aNQSI8}6l>C+H3jdvhNt1FHP>>!cMOzz8wO(VUH4N$dnp`y+F
zRE2uLZCZS9L4zy;xGuYY^DZb?Wd1(>@Y{mhCJ-vDJ8Z17;7V!CqT4>`Pv@HjX0&us
z`ttfqSr9M}=LkzaC6a95>&>xO_{eQ>x}BlxpMsD4Ue07<9<%WFQ!cT8T|UOaneP{<
z>xfd|C^&23L{3K(C-Nug_~Vxm!-?)D0J<z}u}eC-LPqPrFBXN<z@^(D?=M=I)GxA+
z{{*S#L(!_R(6nOc8?+h-@#h`d>z+Yz^Fvj~t&q#|bbn28;wC@?r~Nr-6U1l}h+9z7
zewYC%X@wrMBVr)f!kH||G2!Z3ej6hJT;7XdMe$!&K{1pEtdL#ko^65$n8D-x_^e%k
zaVqz-@b|E>Xj&J&doy5|`RxL$wKLScZ{elGu+8VW(>H^Wc=Q{PU_TSGz8y0Z{5_|D
z84wYH#t!u@TK<P3JHRd^h>!3w<DM-S8Bwxzl4x@@c2g<L=ad8is`U;u1fW;A#9&HZ
zvG7Zm37u<s*BI^4pR1X<w_l0<rf)$;%x@O_V%CH9XfN;aH3egbgZ|PFx!L@A$lKEu
zt*t|d+AuZ<7z8}<YL14Q*$%l`S+>;L*q~FzgMCjR)YG?`K{K*H4q*8|kgzP?mSXZ!
zW8(}$Km!Zhq7;aBf;+Hehl#KMVVy1+Mlu8ayHA=J&eTrh&vcUA)&@E7pMv+{w#PWO
zZh>Sy`7vd}N64%E0-e50k5Yn~w6#N@I1Kp9qtTRp&~frCR*pEImI)88d3(jKK5en)
z7bv%%Xjrc?fA1^!z@?RgAf$0$JJj_oV&!{>_ak6AKAy_D!+%%K!pD%G8G;GW-JA~n
z9~8fJ;*N691)94`nVUQjLD!Gge#6CX!sW4X#PzVv<H-bWDqs-rL-FA6f&iABMK@(H
zV5&v}AU1d1%cb=*>V9)p#xu+JXnA4$FW_c?0v+IM#q91Xa_RLqMW<og(wnI6Q|^31
zI_4K>wFh^76MDhca5ajlIH1D7FAnd6W;k-0ZYI1Fhy|K|p*I~5w%qX@y07r#Km<Q=
z0kL3pYlskyVy*aTM>1i>JPq3L%X5eiJrM#Bx_^z~B6r_!(HZ`k#?E8UFD{$meUx4b
zFj=ry0W3TP1!G296?HPh_d8ZW-$dPqiYfIh{AcpBJH~Xv+&zlry>A!Y>$!<(9Hr`H
zN8DP7pB_}r4pZIP;r*Hb-#qG6M5592#6LllxtBvhLyXZDXoiDSs$R>#4!CmE>qV{G
z*bo0;ID1rnEZ_wJ{wZVd@inH;_Q+qLB41>=2CU=)EI5O8ogl&KLLznIg#uL*<Ykfu
zq~o0wg%JNp$4=wlmAFa4wKt2=Z%U9wb<DcF1n~AoKM~S|2yO(04EdKqu-$+oq@OCr
zna))@!!BGrSG0!zCMXEu=sR|6t5_Uw^FJ`l+-wHj*HS=K=T!0lGwlolh?;r>FhCG{
zT<Y6>JrjHp*cVhkhuaGA_z=qfPwX~awd8cZSm~k7P}jAVo=_#cHiPL6Idvi1V=XT1
zO8&$dP@+cEsu{mM6Tq<DZY_`)#<COaf<3os%bc_ew_tVfH{FT<<QfaF+b{EGevWJc
z8J-4+E%uyyTg$GebIMHV9qE)6S9p#;TOJbQU2sUM1uMu-?AB;82vxw2pfSA8=DwHa
zn-KTkjnEw?g4e^+hrD5%9q!8F;)|5-o%h=MyXk5l1H{4`kS*b0&(JC~&1M1vh0VAK
zXj+A(haQk%`=G8?Tt8#6M3*J!5Gp*)XNp+(DKhcp1IE)0DN%BgsZ@1N2n)|T<aTZS
zqJ8?}7))6V--r!`0459-E~xOK8v%BZFLiMkS=a{gSo9CwR6FKO@_r>*Uf;<J<v+@1
z;R!d&s^t*1_clbnF~o>Jyjnagu<~&;L*Y>~Q{Is2J0$~we7G5)>j*7!H3%Uxjnm~%
z1Ci&YHDVmFV%XSowAVur;5RaB&DG_+SGqFG)%4nET9?_#cF6trQJqNN?!Gn_{tuZr
zwvIPIZ-M^ocPpaS=XItZE438`?-zRs6V*vUFR!dVP<<W`4s)uDg1{!^EF+owexqK+
zH`u<Nma`nF__ODm%l&<k%%jDZ{yg?@h~5n8&#B(C0ah8YFY=8aQ+kbw32y?4CYS1&
z>wcvYzWPcFH^_dS{p;dgsC<$}-5b=rQ;f1ZUT+fEt%bE)_E1IdjAEdfIhS7Ei>Y{z
zHd!1Xdq#Fd0b$erJr`Yn%~PAREd2UXh&Q|676R7(QN3LO=YMKLq}QI#QtevL><bH4
zGrQ~_<4X&)ze6ie2{e@u6{!4`Y(B)!d5t4u4^;d}xNFVI>`4J_+xNcj%wJOLU!ZG;
zu6{pE$F#Qq<N?>m^pgkRDVG*<ooPCZ{sqFYi@>yQWix1{!*VvbQ(O!E4h<fl7b>8I
zdccXl^2!Po#(Y!II*BF7O<3V6%-C)VzU&ZxC6XnV@aOY-^osl2Y5ZqIvHwG#3q<1m
zk;MlXm#a+R8NqP?jpqJi1d<SIt!W?<WdOjpOi;Q7IrZ4jdE?CAn{%{Jw8#cp_+`ag
z5Ra-G1w%|H-QTc4_0C8wWzKWzZS0v-{?4k{)*8SXsL0|ey!P0(?;LP-k4&&Lgi*)B
zkM<LN`7r>qiu2VfK$WbXRg2Wwf4NAFzelwZw9yaw>pz%@{&V=|GgAKzl$i%??;Qgb
zkQlIO3Qp_nkHRgLq)PR;uoG^k>v^9~HtVHg2iC%#0Vvl~{rU>w0mEYVV${zZ=S#ue
zY64p7KaI&dSRZFBYkj$V5Phy3t%GN+8uOzDvZwK1*`IHJphiCh!=Cdx>o1{z#4v@y
zq9r5%>CgTy_XlQI*|#8%`i@nsE%iJI%|A);UpFQ#K{GXz9AV-sQ|SULZ&q==>YjLT
z;g8zg50LJ_Ne-ej8hixlDY(3+nz0>w@3bXv;{m79A4=GpMBuWfS}_#tcs~3Kc*l<w
zgdDCvtP3kAG1yXj^~}CVnw=;*l0R(%Xo#$RZcTL7Lhm2V6pYz*W}iM1z_C}2ofIJV
z9B5cxV_~@GAF?@Eh<|}B_BmR-ftL=!nD)I>=agM|3E+Ox%LoP7%9}>Xl1-WIdV;!v
z<gfwXVuv_G007qfal6p9h5$lCj_ifNK+t(S37!n3FHhss5^xK&8Zsq(4MFy9Yvh|S
zX7~~Qyao=__2f^{MsZ?1(ArP8_@YDPl=*S()ptvI`r>KtAEoFa!uwZZ*k0(*b2Gg4
zV+~<r;yrFQKkCD?l_6NSYehcwCO>{t+W(q&<1JlxLyw)|GUxWn2tYnBX}>sHzx<16
z-H{VjzmaM7r3uvOt2KR{wOT@g^H1m(N4yq<KWgKxyUY`<S-h+W;LJX9e*&}41BjEF
zLVFbd`Hn*iw4dwU>TWhmej6=Vtr@r$)p1Ny719X()Zfmu9sy3=Jw&fvGxlS`8}jH!
z?czFAjVp}#VJS}=?ckyo>GfaIa1j#}x%3khus>)yM$cd?L~|!~(|^&kS!kwRq4xTR
zKI@i$fr?v)V>)Uh8-9Y~*+unC<%!y9xw%6>Xg>0SeJxRd!yNrbtI+|50H;<icy<^7
zI{f%`VOFn$U0v+LDW50csXkf22J{DdH}vejug@{R#yjrE&xvDR?oa^U9W30Fjy=}l
zp?5g(Up;A+Uhi0}khTc9+&i_2Z(RELGZ^tsIvUJZZ}|2TbdId_>_2U1i-+*woZKtA
z^>&9F*j3)bpP5X%F+fEfA3_g+U}05kZ|y>}vBUIp^C498l$JAi#!dj+;uqRcF@|MH
zjx}y>N$UyzJYXH%_ZKONE0gXqte@w-V(#yUPT-3!b7}+rBw&MtQfOzp8sB3$<VijK
zpy_t(#7))6H#X!e6CI0rai76AGW|`VwG)~G+T|g_P5knhGUS-=wa9KVH62Z(GA=69
zCIS+`xO4qeQT)2$Mo@NJoO1nKs&pEU%s=${Cd;Q1{l-4PR2_zSgl6t8-gt=?au^6A
z)?~&j1w`;uwAZ@dJTNmCD2I%;diT)+mOQ5MoC3rvrP<P*oDN>9_U#O={T4`Lilb~3
zg8T*jMh}D9i<bGY<mP6_X`B_{z#=^A5I_sk<ADN>@Gy{x=0zQZR@w_-8)wdG7($P&
zMBmBApdIK-E#12weh)t1<r#m~|LmqMJ5usrr8c_`44MvzOvw3#Tdke%sw7=aDlYgi
zRb05WxS;T<fBuJp4~4r=bi7|%P?$P~!chY1hNEU>-JG_si#x^^zmA1wg&rNOm#`~1
z@!%z|71iYMRS(t(@;)>P7G1@*>pWGwJ;kSFGh{8f-``lWV%Y?8w)HD}RNKBqK+{D3
zy(Xjpr6`Kp>S8Mct`GHnB0$<wVD7NZF`-y>jL=wMwSHk;dz;G@gIjaP2il$VTjSo_
zQW0k?T!0dh3S{M%ebHiDOBDsB`RuOyEwO`ucCmlBsEtrVjD$+cnj0;JbhH-~R`qfv
zxDfqDh2^h>$tk%vtD`-$@&L=bEuig3qu`R+uZJLB6vS@QW_B4=ZQyiKbXo;a6gUPg
z8n9t^`3bDlJ9z7b-+(muMMgTIEl*NA2x>d$7Py;N>kRu;HR+*->539qsSSONhnea8
zjCi9tw7MT70<bPSW3lrO0>i@BzaS5tr0AOie`>*A+ER=hVLdSWqGEQ6yiodsV<aP`
zEN<NNB7&Kfg8-gbQy%~i{#tuwxV7Q?T1;Ui6ir(hME9ydpnow;IWyk+AQ*r1;`*zQ
zN{Mmsgq#`mT3Z0zNSP}NEBA>47S(N+;;>{w{&s)(1qIL1a|pfDtXktgw^Sv;AD3@q
z2XBl~fdb{<GH8C1v^7YWBkvj6HJQD}Ch8n?+wU@H<-I1S$W}t=yc<OEv<!C|@$oAo
z!pmE~cp(+}cj`ry+>pdnq6-I<V0OV}TG#UPDWPC^bMZo^pg>0|9Oprj^B!j2oqWN~
zN40WMDFO^c)N#UuhkE1&=?@_<y@c&|Bw8qSJLnp^?t-d?4LilPg7jmDup~v2=3eB4
zdH96~qInD9i(7W?5c`&>XUUKq%rfZNGg`}V$qc~mWe#PwdWM>R%AjcI*fJjGee;uu
zmj7<mMz{N0ND_Ffet;-PJ#GsNFK<9Lx22FT=8LS_&E2G@aOTHd5qbyTI)Cu%J}0n3
zirGFw@<%T&KIAm#TdOK%9GH9J(zvSd=Z~F(pn~i&^B`9Fbw4itd}}(gO@DSfq;_lJ
zfV^=2Hw&M<;Fi4`g#gI%gN2(Z6=yFKUlYO5eY})_2{plkOw^R#Dr)kN;hyh2c8#Rz
zlq4H#Mj#%9wl*H~`3euY4b<yfaIls{j+?+r=Z|0;#{PAqWOJj$Pv}jurQCd5g79v}
z6r!1rZOXpyp?+-+;NoAo+H|E>5O+e+u=7PB?48J`V1L>wr_GGF8FJ?Y!c&Kld<g1G
zsQ&#fo&>D8^kn*<>|JFOcEi|_%l1X>>`_Ns>Q*O5&z;)A7hxAvp*6N+dp!YaQ8c;Q
z+v=0O4Z`+{UdpVZa;x$#a6EK*=|HCBdaa1dp8MJaN-#!BZo{rY)gDJIugAEW2xxoR
zA_rl^D;9n)|A#>zQJIC$Y2~gFhL94#tWQ*NcCAzwP~zOI`BZs)9F&DW?aEly;YHfQ
zjO3TUTd>su5tW{FTeiiK6+S~ZG}kgrrLQ$^!1>!2u12Sj_CasJFMy?WHlCqWw9Yzc
zr6bW4sB%8U?B8uTa0#~gmsJt9Eub0}ykTN>wJj#Vkx~RbHok9e*Q*gb7Jlp}a+|JY
zY<1K0#*Ug(PfId=8bLwOm--@_^~$?`P!MAE-zV`d;JxcYz3-O$RJ4Qak_mF`7B0FN
z+~pl*cml_aWuI1psh>rV?;1Pq7pAqgq<)~%Yl%lYxR?8{<+ipnQn3sV=b|6%vejfP
zDIscBm(AHBfqCa>^AEVvzb6}tmhMmpC#erxT~ur-jtvp2_G7uP*w^gl%^t0MC_)Bs
z{Z(u|(bmGKEvykc#Jg;E<b}j52qBDK1w!2|{?@9&*ale}_T#(bSX~}D5413$BtfKu
zk6w@JWg7qq4acZ!oPE4x&L(D8*;AvL>HW}s2~w}C!fWFQV8!O^e^1eKp1%s|Kcxjc
zX=FGD_z~3W=Bz`VFF@;TnJGO>smeopF->ipcWGZ3^?|<$@OOTNy`x>4W%5l%R*+-^
zaOcauw!2C-G)3^h(zVE@ZNfbP{2Cc{*;%+TG-?pEX*KM!sY#c&busvvH?AlRGP?)r
zn<yzh0lj#>D|6*hRKRmTjz_78rby-(3&#v4AHiezbpO=MqE?W~ZxXR%seTX?6jZVc
zvSNr3Qqgj=-Z18$nK<!B@Sqp<YQju``EclLWy+N@2hW4sA^WC7xEaS<%!4c~TWW36
zY#bFnLDkgWI$u+^ECrez`g80+EOtBqm}jA-MIlsD?F1Yi6jKor@%CpTnp(dKAq};B
z71pD={KQqLg#y~V{x-L%HGMv{cDe51mAiisHSdw3F=T&V*4h!asOqFmQzn|bUm_db
zWV0t3^>+_eXQ4N#b>m&_3A~>xkElbP_U{hsZ%b;U%9%lZd)$ilvgPs<>?vkWZl-&*
zw-|B==GQHU6Jg%9XdOs*V9>0|Y1rnTGez6k*Asy2Og+Sx>=$}Z!G$a1`B&I_o{%!A
zcx@;uKv=Wf2!bcm9aFU}_CtSyNo3<iM`Z~4bkvWRuzPL*nh`cWvpsV6m;(&J{OL<<
zaQPGPA1^J(T|As8ELag5<Rd;TpxqL`g;y;;Kr;jT8?;*EjwnO6Sub0p8rB&?H#A1{
z$JhS61%%gG#;XyJ)6o3gtMiQnWk_XJ)l(RsDsEk6jW)-FN3ho)bpH_{`Ew?Bx-~!M
zeLy-V+jPGc$E)B}M1d&b!C+;M)X9ZvC1Y8UlI9c~eMOGK68_uxZoB-JrB`>)c)Y?`
zl78o>J5cNwehFY{ocxqOveNI%$ODn=>NMSnKYx_@iyxjvJkg7UrNJQ0ot+!gen+Z8
zMx(0}-S75Sc>g5QnhqmEKFcWQ$L_!4C(b>4ZBHcIHwS{2mbXjzw+;t={z-S-<Jg^c
zS3|kfSwZsgfssWJq27d->?kjvw)m``!%J~|I_JLX*dn{3E*Zd;Fbd8@zD#rMxn53H
zT|;)eKHG=va?Zw{DSE-qv5WmBgC1O}eU5c|$e0DMHdcRn3iJ5_98PQ{yE#xQ3m7FE
zEqY|8Y_9v#O!bAl$#8OOj-zjlw&ug-kGht%ttk5Aou^6Zsf$<tR&Y;RpmA`?H<=Jo
zP`{~cDH(>XoY(&_8Fhs1T;F-@BjR^Hq1CLanNw_4d^9=lnf%we%(&X+3@nLTWq1Q;
zmg*x)Uv#a5SVrGyR_`_yd{PM=+A9o@{vP?|BO)(7UpXI*Aq@O1cMIH$!VI9K+Rs9R
z6XGkdR8jO@vB5xNgFkR|LcO>=wFQ#A=$d2=mjJkH1+?-1$Rnj`FOQ<6(Q7?N&)`-}
z<2f$0iZnfy^hLb|zHeE~h<x&*9wokV)Q_bwB3_N^@2+XBS)ECjGSl3mPC#9Cc#bQS
zmse`qT9lqIy1qC?!JhMssLL{&uLni8_H92qwr5+^DhbA`7E_HFPLXZaXX0CS!S6W?
z?YIH|^T#^@cPs%KGMDefGB!i<A|P)vIqAV4!LvCO>Fb$-=<*Da701?X#zatc8D^yK
zQ6yzIRJ2zWGU_48J|EMu>i1im7#V2&30KJddKp&-Q{Voqwnbr?f@-TlYjN>)17urW
z9{1QFsPwJu_$ge-?MEW3{f*t%O}b1qxp?<I<fUh@56`^eMrwC)kFcF@ZSEj&aS^;o
zVTnyHa!dYPU)!>#3go7jwg7}F;g0;WW!tTnkaJjg%kE=SHYP!gwvgql`~6NreP%NV
zes`7B>T~NU`1?Cb=aCtYot!SWqk~gEbBo9qpP`cvI8a?nc>QPS&u#Ap4B6S<fCRev
z8iX`RCd(C4`w%O6fh`qYg=E$6@|D?ho*TYE&&K+kPYrixwMOb2@vgE9egV-kpZmo@
za~5D_2kT|}Es5^NBoR$jtIYf~^r%IDgpPs;U=L#<z~ns|XVm+;S^$WS?3H<hkk~q0
zyu_8-mFg0fO{z|mijE84{$3db=^oY!C9a4Mv_vqK1|M%^YaDp&27yhb1Zbn*bMW91
znCb|cxzp3M-=uAh1_~N01+eEqrnZMZRPB*ee7ZdEkBWd6)<2Wp8h2``7+iQAUU!FO
z>DlFcdRI_sGE!|9qas>4wAWdv%WVR=Z-HRgW{@Xf)_IF5GvP-<6DYjhKQsx(Q59Ih
z`CN95LKCRlTRR0cOEQ4|gy3RUJOIwVV=4)Fj6z`hPi$gI>41Uqs+>?dp6cr(C#n2T
zGA6eCq$CSMhp3b8<;S7Yz$@)2xREAi9*nVT%)|tRu1K{S($haf)h^Cs_DkyQk6Q{&
zSqq0SOd$P0Pt#?)c=5{`kgOKm3^9HVC?Q_qv!jI0=}jO<t&qz*G4|wg=svvkFN6KL
z>DxzetZXX(ovT6hQqmU4bR(j*)~m)YG7#RQ8hX-L$lofA6d`kh_MfMaE4w4!tXa~q
zf?5FKMw@#_UKpy^2-2AHS2;UYO)Q6I$Xh-?Qi}%GxWjaSZHjiW#vORDyv)#nD4=AS
zjo@q1k7}0{1T_0;>-J<$lRp<f-BPBoi;=a}pW*F1pqp-X8i<rRhR$SY@SNR#mYkV3
zFM{wQb1~q3G5Fo)xcWQYo&HV5;05~Nfk#*xn1%N!cHW1naQO{u>bPTr=@jR+a*7z=
zAP5s;H_*Gbo1e-VPyeLyRip<*6i<R-KELFpA;X_rQ!Mt4M0mlc);i#plfDdse&LG0
zbz&bsc8AP=lj^pH)BwcvZ)@on_Hfr(gy$*PbCWq!_odM3k2&AdAP&OeyBki7T+v~0
z%~AK>PR?Bvs@ho$f-I%%d|S4L!tbh0<M{7vgA|))5GJ>*@FX;27YP!*0cDd)2+p?D
zifnfxr0NYq%AsnQVJGLdyn_P(qjajctP2?`DF)AaN4sRN45hR1$NK9`ThrG+0dE~o
z+ZPfIqYr|fRJ63twa2<cup3eRyDc-ODxgmqs*&w0QfC3JR{2?BU~}=Q3=wS;J5sBU
z(c}qGCMUPknF~Bs2wN9A^%|oHlx-U#w5%z2pQCj)%oO;rf?uGS8~f!&4i@_6_e$2z
z36DwM>}BC=Q{9?U!?kwvJ{SH;2{?sE(>gh-XW`60Y2dcyfDu?xWi7S2GyD{wvqU^&
zM}`3F4C~p#_0p8E*8{x7hVN=EeC)lutM7tpQ(Af{>!$!?NOzKFNBTc*UsY{LOR~>e
zRHzWqkd6VOwUXRN!Cd^wMrUuKg+n7KY8=0p9S#)5s=XPb&tVZ6=r_6xy`8On-rtJB
zW2dBpBOQ_PUYUeABZ5JPl<^X`=bhA`4RlG<LMh2SVBjgX)RE#dYdt#l8oRPfV0Ey0
z=G;A06ebAXKNHwm)V$UmvJxxtw;NOLHkCk?czaUAXAL=BOFBH_E=yxu*ygy1WAU)^
zYn560_|@T*aC@Z+Xk|=wN!@rLF#gaxC7u<+uM*9?HD9DF5f-rUKAHXl@hesICQ!rY
zL-+S~pP(j!2X8=0dmWV&zd|#fNYAVGm4-KhR6d`Fd;ftu!1#NIe!W=v$p$9<!4*l|
zgET|JHb00Ggxt;ovXX}A@cub=8Ml2gHvmnZx;;ca4GY#<W<+O*&&gLnT?a1|&ECc?
zp=VZAT^3u*K(HVGa15vU57x#Q0f3E0!2sbOS@~fPq+vt98WOwL2x!h7E{?(pi$>6;
zPn7vxh8AwDmB>a%lyD<>H?qrX1*t<lY6IJx80D)id{NX03cbLSrqu@H(O$<FwnVl0
z+);sOPQ4jeO^LHV=mR&B$I!b+qVv#9pVBMRwngk7Xr)rOqK+f!fJA&)cvnaA2K$%3
z{o{n;YjKAv<cKwqa*8-*j{1V|EIM&}4A?~0{RW|Jk27*7F1uu0v2JzrNdRB0@f97G
zJo?MR_d1hz*it$}XQvI=HJB<v-5mk#m!{1ole;yJFuq*#s<ZH|9}8dLY8ID<vR8$S
zB=t?13ZK4^4uWnu*(B+pvUH(m^-BiM3a{lgf#L)sH$zD7EW9~?YF}U1Vk5}qleW48
z^jZ@NenFnH!<u4d(Gj8Zp62A;mg%_#(qE6`hYI!EfmlL#+of)U*kc1T(pY|G*0ECE
z<#7Mmpg#=5TN?=9eAThYtj%y`FH~GyeMPx7WL$qvVzr6j5#9$RW}dQSz#hay0G8$c
z1+c99pC0^52ToZaSaQ+HSJGN*OaYI+_KC2pDj{md&&588Yh(LWcyRYl)m5}Qj%<aj
zJP8eZ8ec@)z{S_+mwtGSsnUhICWf8Y1#XQ70{_ikp0B#B0?oAPKs~LBezAcoXIN{T
zy>d1QXn@Zj_DMFR?31WHGY{D-=^Yzd2nhao<*PjwsA8a}N^)+ep(y(%(qgeBYv@;7
zcgVJF=KhB;-G_IwNE@HMwm}@xX^ikXG&LUH>W%C<%CPX(%5o&K%)^gT{}DaGIUo%_
z{)F?GjWN~z2=;&L>2?ZnXz#ZOFN0=`v83)1Ai~cUvfIfqp9D0ssr^|*It<`?&`P&?
z3pe)I-YtWmCgyN1d$`AN0-wsCIxLiM0ex%JIPIO%b^uKeI2Ea|JM{soGhyLZ_G2W^
z;ZZGptBAAARu@N3$Zd))Iehowf(E3&nv*}k_A3cFBQIVyWv7QFfSYNkfHodb)9g4y
z9ZYdSF~3r+Req=FEB!x5k!e;6Xx6nU-4V1-6Ad7J8>#iX_y`-VIJ5d-<`uAC@QF2|
z#7yw=5Hufbi9JjFYwl8}#1&E7LKf{P(^g|qr#zRdHb|n}`Uf;xH5NAmt2;_)jOp*$
zPyqf!8a+z{$|uQ>fOpT1;cj5K`2DR62X@-x6YzGOXv;mQ(GxIc!&1$!4i}BK7XLiW
zvd6V|Ue9yAHWpv(gnftypP|jUx5W^j3)&<NPNWoGAv6eXw2eE&`BQaHI3mbTt4Og3
zYy!=FDjhjbkzck*<LR~gmBnCvpP_Z+xU%zei+xR?96P_V_73`Gfz@S~Vu}tj#0thg
zT3el2+u6s$qeoWlgtT?fL{<lfzQ$qC6ry$1J(s2|FK0($3AeOcqUl-fe#23L)IOa1
zz4J{*acpcxL(lWZvyZc&#wWL?szFkBKY9;6x2rD(X7~DRqUOuwOHayf4{CnjN$mDS
z&_#8N%X89dBz2im%3Y2^GI$F$rI{<=<N<P$I}j%PGii|swjCFv+Dcmh^G0s2c*S-C
zGXG5GfEF7AxOIbTDb-}|Sp9Fj^0OhoXGlZnPnXI3YwTYDGGtGFrRX7F0N381iANkf
z^^CtqFr}I{QY)g-;h_j-`X9HMoxF;JBZDAQm{7gO9v~DOfg18t!3)3z2}@^z?*X{Y
z5MbZ-%x{sVfzyu&9r>tB+cBabr$Nw`6U7TDi}&F!&TEJxj${8xDe5E~e}%x#p28G^
zzd89pb$Ho8(e4<&TA(9Qy~>j7o^aFJMc@HNyUN}xMGb7_cJN2=(RYVB_o7yx(<8k8
zTN)&_f{~jcr$+Mzwg^8Zr4r_P7p3+Tzv>Z}{T<6rLi=D7B|B!4H@iORFakWDJHf63
z4A}Dd(CSG~dgz#5a=2bASmi1B{5GkKRIB3v3kF4v>=(|T!pz=LoEq<A*Q|K~_}_KS
zt_&V;;zd-UQ}>E3u8ax{4qux8%HFuT8S?%ciqmQrv=wrsF(L}6nk3o|f*hR8WM>dj
z+4KmVt=y({LK|RX?H{v&sdp0DCKkTfnf!fc_|XI~!iq6(A$bK{`CE-B`)(@e=?#GQ
ztQ}j9!G==MI@+OjPzgT+=uTS)dFa(#*fz+WmZ;xpr9*nqe2BK^UPi=K7~k=Du|liM
z^Y~BE+WCJ|9M_|>I7A>itpzp#8hawX0d9Edz$sUt>N|r62+P@dWVA41>N!xky8%CN
zg#O9^ny*qYpdxIv6)sOHx26}dxm{-|r)UlI)^;To$f<Xfy7P!#cCg^}cg5+)aS6c8
zAyaYGwmNkd{+6R}XbkL_JM7aYVwK;l{w3Hag;1V>a4fHG5R?v7@s3LFuoK!^Zu2`V
z*%iF+QCdOo2DC!5iM|#}W({T4cEqiFCcfrZUm^ZjM8A0C3uGLXhNp=ZC%TrkgohGg
zV9ZU}C(ziw6U2veud&*(OXa&UV?fj`b1k+_p*tu;YMsf1?UIkx2n<1GYU(h1Y%P%9
zT$?w&)uusO1k#ekiS`t2RDLno{9RBL0ek8-`psspSjxUj0Dy`0$@96MqgCB?fLY;+
ztZ@Ec(Qn{b*A$py)GGn)xQEXk;S9j)wJuPd_Y%IVLOz~>J<8-st^o9K`OTFrY~A#y
z;1A4*U2P^F-CE#rOkAx$0hofItn3H-Ed$Vi-Z%2oT~s4m*oAgo(x=Nnh1cbr3S`^F
z1Q5R{_p;D$)KJ{7&`R8(Q*SM?ppAvU7N_-l51~az19I64{#O@C=@()5ES<2#wCf5j
ziW(-lAa;=jP=cy{JFD>e*!1kzRWsNFZv0M?MUM~s!Wyo3YX{GWRLi6IY8wdI7A(2P
z#}ZBGRrNk_zQUjs+*%R1&=#qmZ0OwDmu`#bTJ3X!q=ExlDbM9wG@W16-rn>pU8v7K
zZ7MWGqzcZR_HfqYd0H>z*8Yo0du7onb3qRn{;57Cst}L*>Prc=J_bO80fwe?ChS%Y
zT4zV-v^85QYy>%a!wao({zYgny^_`I!f{{=;HJ$SLNejk->*<t!d=|+5z>CBZ>*%)
zj&cN`9DcpL)i$1m4)oZQB}*dqg!ixXAK`6IqBgDh(PmJ>r)NiWy1TYQ9vLAvwY6-2
z3f#I7MYJN85BtDBQQu!lYQ0o+>MCUZv7Sce1b}oq`&ArT?I;IUZDwD*cfKSn=zKoE
z&Xo?;B}H`rCCgxHXU9r;D#tz`l5HY;4lr-k?5&VWOprdNtG_d@{3XYJ6brzq)tTO9
zUo^ZW4k)`97CDCqXCC(sf~58C$%Jq?QgYV1*e$ixAq`uFm-wGX{3fHB2L}5F_Yzpr
za;PsJ_kI&5f{1>jEF>4l$A#e}@av|<Ln)kR5a0qy)$ja;y(QJl#X!vxK4XR8)uO#n
ziC5y;G3RX&xTmnGv$)n!q)IR{+a8)54}KRs*2M;Ubmx?v@Ce<>d%=FOs<8{2+N!H?
zP4r*$+amRfG@x{^?>~?P!+k)%@h{1#PGe;4r0S#Va<4cho2}-35z)?L9S=*=;Q)u5
z=rvr_L1nWlpp$sq!a3o`1Qs4M$tCR~iM*bRtp47y5$(2Ijk*OSX|6WJqk{5!6g>H9
zb$<G*(yPD*xz-w=);aF!s}RKpmXT@cD6Ly?BPEfQws6R$5xCh*`(mpFoKpc5brEDk
zNy;D#-}Gb-w-;&)q*Zr9$q_GCyy?7iLw?0eX>pqbZjdZRUy&xJvkS+?``lfbW9uvH
z2EzHtHi%)`1Z)uqD0#FbAi%so%LT4s(M^8<cvh;!cZWPb38Q)mZ{(xBj!co{*cC`2
zpjaD(((dpQ+blhA%KDV_tZjiUoQ554b!W$>kwE`>MueEQVeNmE0(tZi>~}Qqo8tvX
zr9IlRBs3F*zN3a=eNp4$pOCanN7%jR1y(RIwKY;{0T`|ESfbJ0d(Oho`b!_uThnW1
z19~Rhl6Eu9uP!~b|G1pfQCri@k<%pkv#<oTm(rlLm;D#wT+Yc(Kx+UuIg|nxh@3P-
z?p>@L3y5AXv3R+%LSo_dC&Qalx=HFm@C#cejuUIAku3ZPj;2TfBiSy;#cO0R<k<oa
zz}%98k)^LC*LFi&sm%O%_Bz4%7e~_)j;XR`AZQR&{5`-lzV_&n(gfa4ZMBUpwRi%S
z)r%Z=^1isjE`TNf$I-RNGyVPlL{y6CqFlC0$aR(EHe01q#7aqsRZ8hLmt>gD<x_64
za$C8rlH8J#dt-Aam*t+whOr`c!#2D9-rwIpdz`)B?{j^f%j@zyuh&YwFi+=K_#1?7
z*@rAquNokSudOHwS7QMjcFA3fWbvN^9LlZd)NDowpig;y75O18BDhr^)f{2o$>X)k
zb2{^na&wl?ib9)hK%;l^fi*L8ED@lJDRAr~zx+?Hpo~gVI@$T{H7O6Ui;_k!mU`$<
z0%Z*^jn2~;@@rke1drUREN2jbSv51Lv(T)~eR@s~*gX>S=Th-3t<RAsOoxQ1m*tKs
zS5<rL$xu9Iu{vsna(E~LmAzo7Qvtf05RPqpO=GPeksm$;VZA`j?*UZ#()cUNJtRmv
zW+JLKoIq+=Xv})2;&C=_%cJ(Gr%5S5yn_1sm_EJxRq^7aPq2mPb45wJ(x|_Un350w
z+aq<o+T?97){s!`N=yr(bSL*_@gAko;6HIOo~GuUV%=MC8$m$b>+($iF&YbXR^)`Q
z?WUunEw!s+NPoM5hgk)cYd@Zk@8eKhmYt2eA_&hvgE~*@NM9z%z`&*l9-Q~(RtTq~
z3yR96_OL2!<;wA<a}H(uS-<xF3g25$e}(v>e8Lpy9MszxwtSTme*KhI8BC98X#=oZ
z$DPYYUeuUuzhM{fF6j#K<sG{NR9$zg>7puzSKJ!VwvUCxG+P6CZbb8dXPGWaXW?f!
z{RSSh7TpoH6h`Sah}Hs58#f(b<&fnc0YtiS2N*rmmxT*qc5ivp(XI|UD;tEvK-@dq
z=(T&XuN_8tqxU~!3)1480lj-&OgK9KH4RX3wRJ8)x~L;te}!Ln)G3qRp9VzP7ZZSU
z9)@UKp-gG0JmuGeX`uz@c*7IVhx^KNcT@s$6iJkb@dCi=C;NGK_4CXRfbkj<a582T
zR#zVS+3d~>@OsM`_9oJD6<{hk0(1T{`B0Z!hk$-oS)o`mw##1f8np)Q*@oSChQ5CN
zVOgUd{|&i%0XF~Qyg3Bb75wK$S>>-2d52t~KlTV$bixWjCl;bBF98f~`&;)P;n%I#
zmb@8v))dQ>@>)5xw9v7|D$pOiO@O74bP+H*26{@4!=}EzSveju6c^D``<8VG)JduT
zJlbk+&xyLUd~LUo=iMe>ek1p{15B#Kp{x_!Atx}UKqcq?;IRh~LcrMm<MWp*N}XE7
z9jYI(S4(3VrQRa-2PY)K@t8&MbacX1yh<8#>&EZW%0IRhU4wo$PvG?qP_BpVC4dqh
z=56wAf@=Uv5E|wL{EvGE45ZOppS6Thb2<R1I>KGrD12``9bL_CrvkuyYBq#>HzXai
z>fJ@4y<l~8qHudEL4P(A!3Ger8#F+fCsh{GJb?B&v3oXgE0o&giTlVdsqUNbRiK|C
z;};7%BYXgU3E(vfd&6*BJyk1>3WxV_<%@{UFu&^Id3WxTw`8^PgJh}bt3H;}Yc+II
zCn5#fVgVbZQ+bTR01}7N8}2DNvxGzTMbJVVy!WDnH)~fYHvx~ZT#w(9>1ZW@sfAa1
zL4PPsigGbO&T%LJK;s(s3!zos;LDQihQJgs9dY+lTVoB{!}qQiViPdU9-QObKaz!v
zi;ZU&qVGQE-R27QZhlmH_Y%K>k??2qA1iT+2=9u}1HiBJHDzaz#0>QFvRkP!qnn?g
zbnLqJr&QaW!1t>;p+f-I0<a#%bt&~OSi55b;n&UQr^ubbcfMoSCx7!_u?%YtAg>%(
zfMQ}XUbDb1-(K67&2ac+RSiK8=@P}pz*bg{25_{`Y1;s1c|z-dTbtG%Upw}`>BU{;
zg>w48(ez701vOm@DZqhnRM>S<_Cll4I4}=Acrmmy8<C0e|IbEj78ZW_`O0zCp@O_4
ze8HH_VQ%P2wAaf!iZ>Z{qqTX5xb|NTyQ=QRI=(1e-KC0A@kzztl7QB{KMSz58js_@
zfL=WdFFz{0JQS@D#+8-3?csiw1R)V`J{ddt1d`Ejyo1ZWzbvd>CEWdGUn=U{zM7<T
z6cYgtLzprnH!onrxGvqT@?GrX8@PS|#B}Dz9k-)Qor9vwCeh_aFWr-qDnV8r!2AxI
z?K{kEj2QYd#pwRlaaA?lp1l1;<Gdk<qA=wBlHpYku$ebMtJp9C6Q-l<ULl=*m>wKT
z{vYLcohY9jszn>i-gS*K012iA6V}xL0R*^_-y!LE=)H64D-=_}V>h>~p;dnIC0Q<*
zY>yd{-w;oH^O}Df;2*Ar-t067DE0NwqkY^Qc&mKUA;=fTf?|@=O?rV<utZY1s5~Fe
z7+eSK3#Q6Hk{<Y<AR~>b1~fen{)byZ+MI`8;Qf~mqOUC9+XrGBm6g1Jvo>{#9!}K&
zz|Y!MS`n@nQ2aV%s&>jo1IWXj?kU?;#m}K7F4$!U4y6j<S7V`(mFVk``JY*g*8n#@
zndv#aA0h3XmHQ~F>cW%sLGcce+-*V{aPcQFo@v9_s&Woy=Fq_ZJQc}kT&f(ISL0^V
z{j@*4LtuukF%Rw`D!m|wbScfCXQFrRCWbR4UuQ|%@wP^jt+LdOfaT2EVb}oNZ@Cu-
zX5Sx<A}!zIP<*F6Esk~osP46pA4bubp7H5uM|yIPxX}P)#V6!zrj6$6f@-5+MVrD_
z4|0wlAdRMr!#z5}DVID-J37g>#vrTQ_ipA~8wem1m(U|X2CN`JdSsJ#mu01~TmZ|E
zc%!UxFV)%vK*8ix9zYR+n`0V*KNF!ar~la(-0yR<W&xYhsWLaM?M%<re6-4fr&o~7
zSZ*O2gD%$zYr4&$d|L9XvJ8AR^(FFz9Uk)m0JGEz*X^tTNI@U1P)*2&NIX~f1@bOE
zosOO@BHFUUcLD0cy8_dfr0+X86d!bjZdkif0#Er>hYJID>pM&7Uhb32ceuRKR{4y>
zecqkr$5axOKEw2168~yf{Ez!5mF}TF+P4sm9!mb*nOzf~#=qukx9H+iai=r<jpZ7_
zpeGCfrOw|3rFEqt&cOhO+rMI=n7E123k+5o<FM^5+FP%ymc;#tkVOO+oqolxYkUeI
z%Gu|#K}JFm5r_xjHdvw|{O<whc$}y*{29i{Scq$?&rg|uI5(>^M!a>?p=|91B6sSl
zYGr%<>ythfdbjK@><Q~9V15<7SfSkiqp|j~5Ux=H5@?0-O~U*D4epUOiS$`qtGw-(
zCAfpMZSBQBcf52tEDiZ>Rv4r9Cm(r;^8%3b&N}|Mw@&yLK(lTCg57$67}5v8uVz#7
z6<<<8TL0s3Y<Q=+J0k!Fy&*AAS(gU0hqBc^;Wi3841moXxHVDqngGC5vWnnwuhF%-
zpr2bHTMgjkVP7148|x)?NpKK2=cxdwAb{5d$mTaY0DR>HR9XtOnwa1z>3&Yt<{aOO
zexMLm4&bT@e`v@f!s+lOtk%fbOMUE_ZrNzi=SKW~RE`>8Nwk|Oy1ZRRdj=iLU~%wj
zsQj*2pobm4Re(B|3rH)r^K3#FAFr-D)Ld_#iMjL%ecg(CTU+=t2B@y;9kai)@PH%i
zO8B)>_s&u8Op)eVX}<mojVGIb1)|j>mrEHTgf2n)GlYJs$W{rk%Dh>MOvXH{&k0o<
zNjk@P$gyje&sgv2tdDov{0oCP{rkvMjKGj{+=9`zFh>HESl6D*E^`+Efg`w|MZPh|
zc?N(b@`!%Zj1)Be#?U@gmVnCjQXPVXgSQH!j&dklhRn@737LriT4F~>;Y*_Cwn`9M
zPG~i#jXVfC7#n_lR~X?kd4)1~l`M6JJ$VIS*D%$961T7>p$gy(YJ2yga3`RLc1*r<
zYCPl&{jpof-4%9huDjL#`(cM(U8<%w5HI^pIVKzP6sY5F95f4o#dI~$3N*srG&;b9
zPXAL`a{#>G;l};n0TG57qXmeZj&WBPqC-_}=XJKLmbS@jT;!YWh3p1Zg3kVXKm3hR
z;5!>O?m1iOc~&~$;$hjHpNGLiAGmy6IeuiM_cX(c&;h78Qb=CsVWE*9S18pBDV`@A
zF}}e2>_cUf27K-9s>|&*-vEpM8Q?W~Ikdae-u5PdRnkQe(%d^DUt=&@lLE>$8KMIG
z7hwN4bAR2r1^#8hmc=pb7P<wG?ISBvF$iQB`C;-&hsaY>@2nht2piuOHy!a@3F{EK
z0_HL=0ZT4)8?$tagZB*q6@PDKQ`jS5vu5WvdOJ^I+<}VyhvbP_=t-^ncH6uhN-gxI
zs;!=?+75ZxGg!v!sFf)2!ki~JE4h+HUBZ^Z4F0!c?N0kRY{UIh3uv$1Wr*R|am>e+
zIE=pD&Z>;(dJ$;u1vj^?H<hat)V^FcRr@le9&teJ?SGy(k(#q^Uc;IQ1im19G49>_
zYDL3)<t35l{<)zfkIGp+kx&_<9yS^oNwhZSW0-k4*37pdPwWJ*ZsBI+cXpyIqiW7`
zEMY%#FxPd_&2FpFoOF0L1(KnB81^Inm&_FX_cHJy>k<~Lv^3TO+vdD7&kx5$3hI6>
zGMwO14&pvoK+YP^f&I?S{<-S;ci|7dE-B?W;ilxLV&K&HxOf7L&XB9f;Y7RFhFZ_a
zyEOh+yDDb@xm@;XH!17!TA@lmd6+$&CV9IpxJV-J8n-p@zoa93DwRI8Iyxu#8+aMl
zZCIo}a*D97|0HL4uKW+WdgDtcT$<}8pD_69$FZJVR(J1xS%sPA@rmNW8Qr;*fWX`B
z-63IYx=%U#N`wE_h^923SwzXx_-oHaB`%JSPKz{_+;6@?cNGpuBel>Ij1qmUy0G1h
z-OlmR$L=co3jd4oYFpdxA33%a6j>XSfFLax^P}9UbAnB6857E|Dhjn#wNNYsB3qVQ
z!{SB;Bk4|g!Qwr??kp-%$GSMQOWp)|Q1%jPn%ami&tHnO)298&EQhXpgr5-*zZ-@D
z*N)*GcwMs1d#1=V#oaU=`jOdoA_YJP1t>tf)!?}!W5_0EquRY`<Hv4CG{moUC$m=_
z9GW6B83N0@SRHvdlEQKB;-|!p9&F*5`ui~bad&rKpQe&OFi`Y&+8u;<^|K1-^G7>0
zF355es4FvqO_eOG4cK~k2kMPfrh^IF)<JwzzkC$^^;C-LqjJU`_WML_8r@Eh8l#lM
z5bU%|hZgcidO0mNM!+4TK{aH<*HjHk=;;7)peF(n!?c}N{jnyB1C=XklXJK-b@YT`
z3fx%~17AT~%n4d9!>=jQ7UE@T^9=Gb+G0jvR7tE~4+_hgxqmS-#0~H6ltM#@7Vgu>
zQUsF64WldQsyV??E>DYIKn)Oc_UfVLIrq9bEB?p;Wz2J3?Ai3xnx@gm3_&ad9!e?y
zZ$p;AzBhxUoHz1x=Bs^1j}nSGCpb`Iu1v|Fw#FVz7TK}OQUs{qj+08nG2#rdJ{_~Z
z(f7qsPKJM;w2XIaTL=6-7QK1WAa6x^uvRQT>A$<f$+Mgo4GwIDeBekRwYE=Z@_jSJ
z8qjyP9q{}$v9+KoL7V(3HB~0MsIc}ipjE~U(bE&m8EVV651;m-x2ao6(OdP9@<f}K
zewiia_CEGe2QiD0_O$6+&y=A1<T(`EVY{`|Q229!?lu=F9`{Z+Sw9)9-oY=Z?^Y6b
ztxthO4!ZB!0H?>JP6}m;=)V0akp3%OH|bMp*4TMHq=z<U>PQOsL`cLY_U#mbE~8Yh
zX}f!XctqVXb3FteJL5#Er72)<>2#ETEWPE=-jpJcdzxXAPv&c-piT+t%Gho-S<bxu
z2H0cW4&<BqPbTQX*V^RF`OF~tOIolv3x~NK#(w8y1<M^N-%Qu54#1er;=$+=-9~L;
z9$X+?)Rw`9cgoR4YYKr_SE*9W_%|!5cZpIA<vxB+U;-qX%vXcNG=}d!dbbY8AtqzX
zhVm!-&+f377-ks)v0p-U$xMS|-d&FL$a>?8YT_L$UzNovGj<Pb{mI)EVT172KgisI
zTOsVMP0fEgo*opM2_i1%+>Zo%;_pRSy3i#vWqFQ`g}gg<3#^ZyZaK3bbcoKGrCi}g
zvKJ$2C4rIYTa+NF6jsttYx^$GEZO(9nGPclEz)w(2r8}kmJT~!dju!WOjV=r>-Law
zF6b@9z#Ww>)|_Y;D?qh`85t3-dZ_}27C=72W5i@Rbk0nqhEHt9gN>l<mbJJ}rTrmN
zS@T+1k<|bFcv#d*=yTVK!{{{mk1YGf<!I@o{6|{!e6l`0>6#ddMta`Ko`?E-j{K>4
zCmcABCnOQ6i-%8l&Cw+)U!?v63F~DOy=yv#RIez)z4kRzf81|%%+u_Z21Arrv;p{r
z<lzvppYC<v28cR8ripPkSpYj<IC6#=Y(7%%xZthDetvC4mL@jZC3ZDgP<<CRx(iBs
zD?9x@b@6dy)on>ZpkuWX5&L{aUdw3g1m4$j1b3V#v1fB$f0X64m*y{lJ0jHUT^l16
z8u#K?cy}jkqluljByE+T5Jj48#>&Fz#R_F~!qbm3;}v^%NrS;vvQ=_~b}exxa=ngv
z#=j4|TWSlc`8EeYV#@vz8e%0NG(fatA+%78SckCdSyPjw|C57F9a<p1eX^<m&h1!R
zEY59soR{M#IeA&eSETm%O1@S4V77pci$cr5StYl?xl|R&d|Jjo<wlmt0yE`e1z7Md
z=_4%<lMffndVYi_FK=%ux6Z?ruSTcJQ}DTWB&jVK+8aTJ0_!Ek$P8_TCC3|*vYB-4
zEg)TiY$~)U*PcQ}-jd`JjjVS-N8cjj=U9i>2jj4!9eQb$hWoZlx))$ul*oYzE22x2
z`muyhy=&y7Zbwct5k?CdKf+&b&ihk~=uZ;gP!QyIe}v=3P-iA$^FrbIOF{4Z?BlSr
zTl5B-l#{PZUftDmh>q~SE%{wZ)!Et@VX_eV=^ewMp4MK0J;x;;rt^Ws#Bsfj7(#8|
zTG!W%o^`a0?zP@d%l7Ed+NQOcBFRh>f_h!DFD+fXV}hl>P;<^TXuUu!PU?4$d5T^6
zEk#@?eyxB#MpzlGz8G|*R&;DZ^)0D)NP>%9Dck4hB1gp=qL$rL5iT2u0kJDQ|HvFg
zAD-C){B7jgWA@Wf4`k~>YkQ`f)(F0!KJr6fX~ajCa~Mn+S`oD(8i3tAhDK{)Ri=q(
zJ!TaDTiY5Z9TnU}4*r8G<Vdza*I)~{GolU?w!Vr4Q4F4oW={A?!Wde_Sfpk<mCU%9
zdkjpvhcV1YX3y8(rr+B-in0wi6zU0dQ2xs`KhUO1kQEy^%IixEa4`bIF21|We@QG~
zhp%m0gq#-*X3#e+il0j(OPt)J5g}0WVAitxLLksHr-ASqMR9PPwCSkcXbgOjx|YBo
zj?pb2eU+xVI)0KTdgrVtxlV>tz`y+@*^oSAIn}ebB<01ADj&-<K1;RXdSp4|<<ymq
zOOZDhux8gKEnwq15UKO}h%BQ$R33fBggDsuL6A(>!+5~sxxw276<1+I*@m)g+Pv7h
zXYEdeu~0`adus&cAd%VCB0WYR&SItC(k&ybQ<ByEzO-v2)c2CVez~#~=8<PF;V8LK
z!X1g}_Kb<m*x5r1$Tv2(v;-frKeA3Qv^`;Ob@#w+7#7Nud<O9=4oBUCl+e?WBScw3
zs%?`7<Eym&k>k>OL}*T$ESoDdV0W$?p_#jO{kD<$3Zb{m7ByC*P*46)KZt3{c?_#^
zZ1VgIVpD$XRhgfM9zUAkd_z*>FZr!1rMyL^&iSgKhnqf<17lLjQK6e}NG#G-l^%<&
zMsR0fVHa>HxdjBVgt0Hcee(iKa-pk*-e6pT9p*ZM<j8@qR>~WT8Rc|Sowd_NDm@#@
z|5$a5S5>4sG{x0ll|3xMr9?A---?81g?2PGJSF$57IJ#!@l>GSy6NJrn9A&xg~64)
zAHp>1npaVy%_g6=x8%Z4sf84T?XvBY3*1n4kI_fsNzue0U0(SrS!H<f4yC;Hi*$vb
z0aeD9N3DQe?Qkm4(vlYNK}6pINgd;YI#~;FA4!jWCBc>D<RVc=pxJWvMm^a&<dx)=
z;9|3Sg~=~k3kEChTm)PHw+A__B9+i&S@;!O<LD^euvFZ)c4J6tOph4!fYaMptSGS4
z9Z9Ix!LY63XnWZq@6ix8_?{J)*v?n1-92m7aTXi0okV*$g81{6Vais|zbb=p$H(d4
z?pHKI{?g=#;n^$h0;4bu43PU4SdZ7_HR&q}tHc?uqy2Qv5+zhA;O^m94)eF?lD?Z@
z;R$JlE35ze2Teoo<Zxjh(p2p{yC(Q3c)#w_Tf035Mz5JqlaBG@MRbQ|<1CRBRmF=}
zqHlk6<p^J5yRsY~R}bE7#1Wmg4R6&AsOi4FB*I@?Qo}dpm(=$}%H(-=(+QyR&}(zo
zTDx9?IF^Em5RBRWJ4FuAVc|BN>r11BL%et#MdK6yFjMb4Zc&X&37!k`9x`szl`7|1
z5@_~Eo~|*G>}wsucYlZA)TRb6bDBl7?tfILysF-g9OD<s(33In_^BuQ11sUtguC0X
z_w77&L42PsCoc$1NhO4x+Q()H#d*Q3KG4P87!Tq)tV&?413Fgq)6@~>=KX#VtqXLu
z2!Zx#3B>N*M!}$`nbiB=KG2l>k{j)IpBAb5mu_NA`5*NMeOf(53u>q+)Lpf^eOe#?
z&8f9fy3f@2gvF{&fi7x8gUj)+ksVoKr#7+Q5fxtZ6ixNRPMu>{DmTrMPUx>74B5`!
zvAtoj%o*skGdnN$+8n8A-VAinlW!lpEqHS8gGz^VIhxK+pm2=nse>Q}`2q7oG7`h}
zh>kcSu=8s?iu^vm+EE8on6nXoP)T}V^0pMEJv^lQePK0cTBc>-I(cOs@@MmHOfd$G
zXUo@Y2kyANMA$Wh#ou4An{k4Bfz;MD+Pxf?{ZhwoR3I+03x37GZKuZwK2r^t=Md|#
z_br4R=*X0lOWxq%ZH#|-q?5v1yG@8|?S!oVy!P)FUq))kT&5p8{TIbI1NmW!PsZz=
z49QF1WZroBNR#@`riT3H=a3BwSKp}%CieYvYV-7J-msJcyndY9XnCF)d>A$3RCdp!
zdF$kqCY8T<$@JnLjQf?(oC0F$)pwiG8DF4auQrcqQ?~dr7V_QQ+4Q0tzvcQWu^`fv
zQw`!P^)M}}Pg$^U@`V#K|4B2^N~B-*j|#&_)rXsiu<J<Au>o~f3~F}=>*Dh_tD`?=
zGN_G1*2C(oXyo~gM;j~meOI?w;a6`3+7ptZH>m`Xyx;||Ym19TE$;Ti_~(-K?nSef
zH2pAtDIJ+bTS37ltpeAyy3C?{5l&y^>iS%7KLybmw+C78EWD%v{j-l+elo-4qAJO|
zW!sEXl3^nZU0m|EouJ?7o1nN>U-6T0GvBm-8_9`$XvWEh<*{EKdegaxQxM~kc~=38
z(iaVYkNPAxd1uHwlOs>tfTL7%weDj6mW-=AQyLVX?Ln4I^r$<BG;UQfZ>%(IQ}3lj
zI4Ef$jX*aN=IEn}pCPx0D^KkZ?B?Qrqj>XI-)%sf-@~sK6quXzt7F2IAIZ*ULCPpf
z)|lcHI>N5rXVIygeJ{ElpmAdRMNw)RssO#{<kDzt*drJyIplOI->yy<AfQFj{e%&E
z*kH?ZU`3FU<;c+N$l`q~URrDe;#Y{<)dvYz*~OwU!qPx(%?2t=8yLFw2Tqmp)UMk|
z$E8OJt8}aiGI7Z-L50pFC~!q%zr3dH*}DDzoH+iOe~Ngfi5<7Y-|4~D%LuiruOUUb
zxs;?^M^x|LOz2w+CmbT5gwamdkS_t#q6lHqzmxRS)xp-lbHB<2pLTr4Dc>LVL>{-R
zRXStYr_Q0fX_J*W2EBtzbc;2`J;+~YXxVQ>Q&ysZ3ZO2z#_unQ`*ckDw?n0&s|DZ7
zO!}2c)Uee8`(cxQFKT`VKrE?kn>sj_^>fz)%-@Z(fI@f~{*zF0NygtmX1qem51RI?
zLWSo5s*NyOBu%3vkAA^`+dTCYJA4n2d+Fk&$~s(lY@}hzNN+S<D-~EPkKC(U_XhCE
z|D10BiBO7#1T2qFKgrzvju-vOT{PhQo%pt%$odR<s#4v0i2ZT>YQfI;X$p;p4z&sf
z&d(F4>WScIfeojyuRe~~rHdAqc00ZQL$cAli8<$Yb^lJx!P$gIxM5-D?ziK#oJhly
zZ03*7n*dG4;o754E<UhCn)zRbo)=eSnv414yILTp`rzfW)mu<sq)|=ZF5M;r(%)l^
zmDqgKfe@Tg4M&e$SG~J{*GhYc`8$oT-o4ewb_7V~+)hGJY(pMvA=hRty`IY<7XBS;
zygZ#{+8*O>*wUEJ&M-YfL0rf!XGYA2cs-Y=eh7bsyVJ32rpjdpYeqBgYg-|G(TfXv
z#8DLCf|+g1u2*|o5Q|l9r+S?>Xyw^;?@FWingusp7QQvrkF`uvKDPL;p>@}58<c<K
zXyed*qUndII0p{zCRlPkshBPa`bpR<^G))nFOEFZM0#4#b`3UlwALj<BJF3a<i*!4
zKWTL=RkodHzq9+@PS}Mm)A&kp;)iG<=j$hSeQgSU_U$>Os_{XRHQguwWHQ9<{X%Xj
z^WwX4!N9NBYQdHXcpg6x+x_5WK}TTixWKi_srr>tUKY@220|#dM!Wt^Y$vRNzP4f5
zojYnc1swMWU)G5|vw-~3i`4@Bi15&mV4#cq@XIz#rLPZ;^kWw?ik1%@YP^ifGTjxO
z^ccug0Ux`0SdiQQXvWC_@)MZtaaYV>h!E;7r>4+bwaJj#L4lb(3Um0C40n1_s1B6^
zv-oh<X!lC3!qZo)5#Cj8?)1MZ$P#10VDxeo#9BCWP%2AJgFNVKWH82h$ACFNK?C)a
zhE-pUUd_n^TA%)fw#&GQ3b~22AyamhKE|2(BG*#pME4>aO2-I|?}gtKp$i8@uHQ_&
zK5n2rPKorFob$RB3;qURkX(3ob<k)d(STzX3&f7<+-6QIywn)E)hBTcDRP|*^twvd
z$d<v~_&PprU!KTec8BlWccy9EzB4Xr>-T%dt2f6lo5fT{JuX&DH<mNBwolr&KJLOv
z)#z7S|C>A+|9IQJ9cnL=ww-wCbm@Y48%y;2o8M$4l}Khnjnl@=@3V3%RQaxP5h<N9
z)QD^#M6QlQM-O$bWP~udM%xHK$Gklg;%9wxJ5;=<(Wn0LfLiv{xgjmT9K>eSjxl}W
zlEZn39`IgS{6u-FfUNEC;3>hTui-KyQ@6Uw{9421<hd|g@pQ<N-j^mdTl!NkE)*Kt
zsb)JRkDK$kcifJw44YQr4?u>TzD-?Pa<6Hq#MbDpQo5@WD;pTz3-Jwpc2K%cVgYXy
zhAst7I63^anxoj~1wa<bi}8{<E7+9J!0VLGr?O)vsc;8;_}n^73v$Bg{-1@prf)mA
zKYf0!*6B7L<sH)>SRLq(OtIQnj(f&mX-P`4Qb3(u_^~{oT9;zA1#D(lO=#Dk9ZaD_
z>{$8fQ?g9ZO=*_s0Z$Vzs)Az+UyLv4%{R=jwH{COk|Z;s4mnW{@K1gb{ulCeU7E{}
zKL0#Jc0uxudD5#(1?@3N!%NCzK0y(zt4n${$b?y+AW`oBlH~^%zcerkLP9prj9s4e
zjqvwO)NOo*ifr?ZIQQsrtH0m`v14_h!70VcH^tXf6%OI2>vE@JXQ0)DGna@tPZyd%
z<4${qoR~dQ&ABfP>CU_`5J-dJlNdQ2ugtEwE6J8Dc~8fq=rsr)uRZva&Gdc@Y747F
zuX3{SDL8q`=etSO#cMGdT3Y^g_;#TVsiGT)T#WB#PrMdmq!mZuw3b{okgZGH$l^|3
zNS8C@c3EI6e5xut7}9nL;bXDzW5pVlCJks+Wjm$&h8G`Q9K6rgI1~N=(tsF!JvwzM
ziwE5y8CToDUPj{=3)F3OIQe^I20)|p|JW=lLRpvai+apT-ABzl10d7WLE(}C`lSN!
z>Brd=!B~%1FxH2!H{a#OZjI_#b#<$s6l|D07x4gM`g<mRoc(zZP*TgEa4FJH%=kd4
zC?YITzEOc*nKfLTc#3xf=w0F<ngx-R$}B~}zBa6hIBG*1oUbwvh*^hln)Y!l;0emv
zW4v0z>foAqt5mvvsbHP=9oT<hA4<axkH`7wTXWWbzVNE^Muu7JQlJh}<s(^C_i2!=
zbW1%rYzqo^_NPy{J-f7L_RzS~BUR9}j2|j0o)L?|HAw3|s!mWu-RTJ@QJx}$xEmoj
zf{!$F=!uRJ!_mdg6HZkw3XJXO*|G_zjJ#1UV1IwKRFL&rPPij4I6J~n>~dVXmCTKb
zDAr46!n2co5a1w)o>=?EQ@Y(iEkPw?*tIzcIwz5iIeG4SMiob~W{iHI6De9cb7XVs
z@0~ABPnoLlcy@D)4Yv-Xt!A|lANU$^qk+OVJUNeM68uZzV!^))rcTWn_j6F<-7gC0
zk>FrR?!kiF{sMJP{9j^jMx}{7d3x>I+kFe`D@-swzDouD5%Lw<m_Z;#NsGcLN?R>d
z7oKL$PW9u0ArGzgyr5=rG&sL}enndEHGVbYI&nXuIP%f)EB~pQPE|D=W%wL_Mj@nT
z`)n4vABQPH0{@dueiYK=_S~EM8Z)};dg7ufF^;z1vf=S+b`(agvFaV6oM5JSOV3=o
zt$eY7?|9c^50(`MB#*RJV)~yKrjD+r)@!}E!CqtdO`Z{}zi^`~C$Xu70kG07E9kRH
z6jAlef=my+cnHXI)syHp^{!-ebs#re&ZD=-piW}D%f?KN9jNAGiz<_D>?BMLb~-~M
zPcQ6K&jU5hppb6e?sOz05MrSwzIUEK^MNpd4TAGi$Hy7m;Ik8X#BS<|ponA19nxIN
zH_s~_XfD)e+-Y>CYMGMT4y3ZxtCpLC-!)VdKJkYKl&JWXUq0Vi?+d^n%gOr@fBUYO
zBA+5&|EX$VggJC;vfa{vFU3dmve?AFV2H(h!R;MT-;&WKzB-^Yj8T2FaCOkBxBk9|
z7VPgfmV@=R?$I6*p2K{7W%9#q9dmd(irDg^WOjkAY(_kEwY#1T$McvvRB--nJAvt_
zmFxqn6h`Vi3W4L}=L+R8Bm0&LZsb=!*jV157g4;l%~Y$&-mqgi^$tEWdCD6Yhn2;W
zSuOUqQQ6yxoU+^71yy^1E<I%48yk8KPl!0zGk8Q(`WVDdbsXV3qw9ndPPCpOuBpI_
zS4a3h=RdY(@~@Q)+)H`l+5Sq1{NAvm%Bg#f{r>iZlSW0=^QWPR8K3Xep^B$_aGLyq
zn_0LG2#>ag<@h<~LxDzV9l`Gs)=5w>Oe(j1L6(PHJlwqM`Zm(DI)-+&w_)g@d-n)C
z`0s?1!Rq}n#YR7QzH8LT9WQet;KIPzUsfIK-Z$;D`P`2RyNT?!hNG4FnL6~c3bZ(O
z&3{Y{_IudLc>`IWSavVsFHU^Z4OqG57b#?Xa70a^+rO0o8G09gV0OjxNi$l}FBl^6
zjmpgJwXtq(ShnlMX`m+#FBRlDRQ=lw=3DSxcmC4&O>cWoT^*q0dNwMT`!wH)@OQ7z
z{5@4t2|PUVOM}&f`W9YHugJ8cKm0EIheb$Ty7T5F*rkGv^U3@v=gk8C%=o8!W6D0E
zdt_MC^i_A%|A>iU?=lrp3~I%AeC5CUBR3@XstLz*1}lhT4xa+^gs$CIXvMm}1tqk5
zV_;B!Vd5f@TS-=Y6`4+H7`pK`6HE!cl=8PAv9MBmqbzn}d0;Tw6L4nNH$^jEEEMk9
zg4n_t^ZEW>2)@~l?79<CteAY~Aja(#zMRlF8nhewEs?sK%1q2`nc4tsdmqk^a_!Mi
z6Q-WvBxfUSn|sI|cOnd9QdnovI_1<=*MA+JDKYSUmJK^<T)X@I#4s?fuUXHugQ7LE
zJmzC_av{KkWS<TUM|F#5d&~CDUQ(ouTQ{C=Y~%j5;c{vpeui%TSMq`2=&Fj3!-=zi
zA{W4w;@y)Kc|bDB%@ccbE)D1dI;&<AJ4X>_i^A4p1xn%rzyO#fRf%_C3+3>#9XjO+
z`fx&op(nevHTHWoVFEN=4;;JSv5mlqn<WvGtZHQEW)3%8jtSS5n=u?70{Yz)X==~}
zuHujRBx;q;-a>ydgN-|x7nj3g-Iu0-#zn?vUZQLLZyE&GWnP-<NUI|R`A>dmLYdNi
zG*5Nhwt+6`^9P>o@zif-nNCY4u`e^_1gLBwbJAAhZt;|pDtl$XL8B^1j%r2W2NuBl
zgFd__US1+Hi*SBTE#9!S@axsqOQI4k6FvZ?9u^(U==l3__{gS7{fvlWlQJrGYL+Jm
zFBb1HWoFHAEpSUMs_EvcleQTVe<xi{(|Y;Y-y4qh_Xjn;rb6?S;`%Nb2FQYz3K$KZ
zW`|~wEe*?2DWa3Lo*fO3iEGC;vND^1HMY94zqXI=^IdkX`?4S&+KA`<SQ)-)E*k^Z
zror7h1?)b6_4^)ZN@#X}Fy*6Z?a_VPPwZ7k$W*F4AB&s>iuk?Bl#sphH7&w$Iy%#s
zuJ#R$B#1q`GyH&nZPbSD!H|9<^pM$7!AbbNI!#bDA;O=jZ8}Opv6wztmgl;w{9wU#
zgkwKAjx`-GBm8YvhHV5z(4~ToO4bp2R~S@UJT$&AwKFgBFFcYfqk06vRgZmA`X-W=
z;>`Fzv(03N(JavfR`}@lxbGukR=3^Us<5sZ#{9nMA2#7j)7hA~bvHS<)nGMKR33VM
zYvOsq59JBp(ZUUF8thGk+79V2tsNfh_oWlQp=mMA(Q)p}<DhOw)x>1>A4lxC?_a|c
zUp7tJ_MjsEtyaDHxdj!P6!DQ)bK>PzFgumD8jHJo;X$<OgPmQ(mJE#@UQ;vIWPDB_
z=E8$mL|q4!2>z^lu)1aYK^odild19*bWO@^d-KzOL}t_2s44Tm@GqwDTYKHJ#-&GS
zv%0@uj_AhTR27fdVa*~(O5Xguzv^VW>U9(@q6-0@>Yrf)T*;@ggtmG$dEvwt@MP<X
z%y6_?>9iSiaVL54@Eyzr?L#ws(L+2Sl2Kz>pZ?a^jigP=^u*|NAkUU$=3en8ppt2@
zV%xs2pRUP}yoY`lw2$#<KTr`Ldw#vKT8|p;L`C#iS{_Vkw$}s-%FW%qqoYUAwa6U3
zrO+0Lj=M`<{PJV=MBsXuz!^wx%c@CZKLrll53Egz<#h8nhhLzDNZo@jP44|7XMBdf
zOcQ4Lj2Q9c@r4UH&-iY@fLijE+V+?e86P?{Q&bW$f~T2STa=xOQkw@_4rtsfYV5Q&
z>8CAJ8fJYW5abgL-6C~<r(Us)vrB~T5Y@CR>TPcE9T%P6G6|oy*Gr^q?;>8O&6>Hs
zJ18z~X`Ul!e>`Pfi&JEl=asjbvn_^|$Ha0A=?7I=FFk2<@S?KTuWa!x5UzKV<K-yY
zxj8ZRQhL!wNb2_)*5HMNZMBZG9Hq2$v<m2JCJ%yl+rMKn!juU(5KdrDabD+u;Vuap
z^l@`*@_ijWqo%K+0n)$t^r9{Bs#u<AP)yng`Pm^nouPh%J#U?ZG;&KYV#m+q$o?JF
zYo6-wu*Thx*Yk-9weA(p_>0}9lo7$wKLw7LV-1jV;xFCl@lmz}YgrW{9lZz3)?^~?
zy*+h+^fROnpIy{y91up}jX%Hg&IT$rW0t;lMAJjSK~nxv7YJs;zK?Z&DHd<IT++(|
zB0#{Q2@?z){CtA@)cr*AJ)TzIrFV*A#kwxI_=~#5)TmLAbkAD-MRws%Yx0}d>Q(f8
z8P>AWt9tiZzPZhb^K{bDTPKTcn6feZ1RJ*6u(hl~LC+@+QQ9P=C0}@FCJxxzM|5*f
z2xpU?<-qU1QD2#I*9?-r_~3XnO17(4Smkcqzs*PH+=m?UNI1i`DYM22)b%u5#;fMU
zpTiwVa^N5R7I5Q?yXz6GP9bd|{O)Gta1!s%7We&{d4owj@E|OFJN6TtS$?g&)r<W@
zE(e!I+CyqS*au(;j1@r^i9Ei^<#*Q5C)&*Nf*Fu9Lc2p);APyu9(H>(la)VHO838H
zC4=hFYNos_m`LxBr<?@3y~5E2V~&dW#Ad*WIBEl=CW?pufvJAxU^XRo9g2HMmnQ^Z
zRTc@=?AnkVcukV}B7M_>74ASX*$%3g#7i1nW33~<XcM;Or~lbVrL_q;m6JA2tbfzu
zHkMKU9-jjQ9vL8y^0nC@sd;b4pUrsdF5#Gc#vesiWGavLR*KO85vjrmrGx!Cjdnzy
zvDt-bJM`+#KE&IVL3!-_W+w69`%?(?2{|V6O&A*NBXQ^hBWUgrbZcZE{$0)_`;RDx
zOjs*XC3UlMkWa&FA($yv4h~zdE}?flz5i1jUYZ^sYs=7w-~Oa7nNo5Z`7GRbDP#9K
z$d!_3y{OX*V)@!Fv*M~sykc{Uy)|xDTTiiR;aMOy;k=$=OUKhdX;QiIVFg%ww=nxI
z)PCxmPao>M<k*%*{Y0MVgYjW)tZpJt^+%Z4UQpGZL%UV2u1iN~1xtf$s44%&9S!aU
z{F5C-*ZAcii}Ka;r*eM<N#pF(cgutOGkGG!m769Q&pUmi%aZmM)zCRH(;sk|qH65Z
zIfoFRPf$R!rXl0vE0rn+P5F-8mGLSoJ^dEmT5SrXtdvUM83UDK)6Lr$3SnZMzu_n&
z=#xEonWK~5ho<d>K<wyly$>ygADQ9{p2P%p<w_1MdkwyhR{xSmyIcO>Gx)DgVb*H*
z7D23C4lVvuuwQfc;;eX!4XY={VJ;B6-A2~;Otoi5jQ9(+RRV=3@<I`=`#0qUB=T%8
zz;P-F>keVqkbLlzMqi+Gp%OXQ#48Vyw(N8~(89VlD^{3K7P9wST9egQ?rpyIn}In&
z8(oj?DbGP>hojzlz{x?_6TW&eY(YnkY?BV*G<y+mEhAJpzHk1TG{Tq}zmm|#zQoYS
zDSN|BqBYV#`SWCd%3EF0D@QCIN{f9QO=2BL6k)gM;7dh3Hk#)(SnsXEQtuP`-ZT8N
zzVT2Fk2x6m-4R^@%qYyKR-@V(ruge)ZTA+{kvZ{{hvUa+jfi9((_e3-`SztgT<!?Y
z21+tyA`3*dA?*5IYx34e<Q{e)kT6RQw!@r{=p(vx+?R(I+c8HAR$gyH4rcJmkGW1O
z3z9$OAk)Ham9b@DCfRA!Nk!}r?_-_ph}4DNI>Z$Ddq0c`)#?$t`{$ybg(fn^%9Sn^
zQ@YdEvc0+d8cLxv9dm+5+KEN4XU4hq9Yg!<XO=H~YJDQeIMs(dC%UU7t{KZg-hZxc
zJGH_LkUpxX{@PHU_Fee&Z}<aClD83)P#|iuW6O10%SN~8tu_x5f~Bg<A^axy+d)$2
zdSrJr^Hvb{RF=AEig_#;%lhQVXtw`qP4+?PsZfj=0n%IbvhT4DvjNgC97oJ1yj`bI
z?@u^)FO;*F2^XPC`fN=S7ep<0Ms-a7eT=zz!dLF(&_R><));Shz4pXJi>ROR8<LyU
zlYd{mxk=OF-uZXy&qTl3n|VFq=}&u;v(I<#y#M@5M+})4Dekf3jl*eo^1cSMCU}#<
z%)UM@CUhg_OkS}pY+^2^yf;l?j0TCfLXDBrh-sVELxMp}0t>wOPM5B#tS5!8c3lkU
zut<<ek89}2^S_yL#shyxXk$7bCa`*E78TGv+Y@AJRI))68NHvA6b4(<!HhX2fGavr
zhtY))J*-Y1Shf!CcI0>)-w#e)Po_@9lWkg07dAaiS+^7Zn#nPzo6VKT0OXePBw!fO
z_}sy5QVMqxTR3|^R>53zP9PJ<-PYxKUz#rL3GOG-y%x@ihfTd7gT%M&5@hn_ma_F^
zkO_xn641XPK&Ge;&%={9E)AZX=1;B6>9OZb4@eJ!3<yoSzs`x}NiO8|jilUGRx`GC
zbKXzqX(W?#VPoE;^R&`uW_dLDpD9O|S&N26bpPJ3hpmH|)yq9f&JcvCdtX-YvAZ%&
zm|E#}X1}mXkiBV4dK7KYdQPl7F*#26-F^VO0mKZYXy~04dm!uom<gVBspITM&H0oh
zeJ8O|uJ^Jfdg@vNYdWMOl099gF0);g!Rb49If*Osy_eUKMsFsNuO}x-H?SH#r>XRC
z={`ZxFwmKWWC!|JY`UOe%mCjMj7t|F@qzu@*%E(sva)F2P*89*0sfTPbcc>N*K34C
zh^*0fGh2y$3;8liEdQMN@h4-SsL)9Rjz)lFRULZFefk?ZFLFa(jxh&i7Sey89YX-!
zll`GsXzh%}S@d68j0MAe^DXJT?(mYCY>OY0kFvN1^YMkh;6}lHXLhlx2<wNW7yBZ$
zJemkZ&SjCq)(HzEIc(5t;EVa2gPn@7k#8j6<7wUy1=arI7ksm6^-C?mut{np+ekA*
z0p~w$iySN3Q9F7pmF5+8@3N-YZmzwt<*o5CBl*U(x<I%r*G980R^-<mQMcVhbF9gC
zA;Vn+8F4r^&@_I#Tf&nII~Ej$-)L06di%-5=ZhX}aCO=*LUDTsK^{M6)!x`saYQpL
zs+`Mp6&>-AYKCcE<E1iRBYqV@(N&s0TryFcydE8!Tp??m&rBv!X2R_5{u^D!_~$3m
zoxaWr<#4LWM$ybQbQdY-e*SlQweKz=`0zl{W^}uXtH|Q3<2}Y!(5ro-6`!3JC7bii
z&rU92OY6@JQ<Pv;MUk1j!iUQ$=(Hmhd3F(_XNH@6eb$OFoU+1;TiH>i1D`hbC1ugm
ztW&-qEXfIHs-8=sk1mR?DO({il>6=`<*WEB+}ah3X~GLy#+LH3mtgeOO+raG5B^{o
zh@hjkD+3>U(!z&Hn!O0Sl0nWly1NV#yg0n8N)|EVmH&&5Ft~bIs`z-gNCjP}4bC8Y
zH(Qh_g9eb?nw><7h<;kt#0WQo)*g|k1vbCqhWfoav(hxG?<74_>%U_i>~0d{??3#}
z%?iYu(@*U!f?~>l?iYTmYdmv;4uAMkEP<TLzs@F_>)~nw;g;)A^=@4L(z@i66x%ot
zH)%@bz5Hi%w~7O}1-q{o52BmwR5QpHHg}ih1PZ<HxRxoRw`%AXlP(%6Z@lO*`qcBn
z@3bVWriC0ifaWlZQYD;mZkhp!I<a?2XKv8#zaGG?sB2o7e?pz>qBXi%+*5(+JGIx9
zrk*jSbfoYu3CGiUm3rtl*HrSb&Ap+`m?xPGRsbZ~Gxm<(Iq5SXik3VqG?j$xCUn?)
zv6GecaK@ISMLOtFyZ2mv!<1$nWi&TcXx31EX0eH%^=qf?`Fxdje*HOVWBf=_z8blh
z!CG6@d>V^@J-jH?YNm<y3I3XdJz{PF(>9U1AOn-P`ttD<enEGzZrNGbVdco-U|l~L
z;O7Nr&dc7zorr%8_w{)_3A4O8M{xAWu$-vvWIg9~CGjp!qI;8;&FK7)Qf~W6ALx?}
zkk!vdC~;3x)g!v~rB<yf^viLbiLVuIVZKz?(0MuOoA`7~KkiNQ=G{cu3+@^G<<NP5
zcJy?z`ONQP4YWrZcr}nSp+!nbU@@MYj;T2uHe*FZfZ1|hZCd836U7h#97svE0oT#Q
z^PG0eYdw6Wa*T)j<f|_exr$M^Jj2P2%+qVf*)dnH%qCltIwiZIAtmU1bgu2`Xu>z$
z$*UG^x$l~E1|u^p9ohR2x7Vhq+NE3O@Fx7Xp^G;nW|O^1orxP*b*D*F-J_9*&_AJ^
zc3$MtQ3cHD4-9wZrJA?xE8p1{CtqdLU0Nvkxdh9JEA@i`>{h$!<f~@V8H)D@XyRPk
ziUA#>|I`RY@|kndrOa^Kw2CKWx=r8UJ5cW*1r=VTH>5JG|Jz3@(tfBdOR6kY#8c7i
zk8RV*FEKhDQB?B2Nx>_PI^QN$+gaQeCM&2A(KJ36Z>ho#(Y}L0rBqrPwB^F&$)i`e
zmT5@^3T*bu5mrY~#dFIw@>>QgD3hVUcGuCvWq)1PkLft@J>taIFxOWKpe$2i#H*wp
zYBJV1H4OeDsjG|LG+btcORJ5~S}#55!sQ=Dq#&c>-aF-e2;@L_lD;PJXWROZvTyta
zre+w&LWgwmEdzxET{eHtxpGjraC1|S0x{i8`0YP~S&w!rvGbfHc>?vdY4p95)MaY_
z6BTsbr&My%RW4F<v0gtULQ&&%aMSPAv(i3BlesEpII#3P(h?-cYbu@fa+8kCoo-ss
zj_<xAY&ZllYg~`Y+9%ZNNaLPl|F^!2R+uxCL>a%`X@zUA@Z5qee92(pNa$<p^DKXq
za6>mig2;-HL$j>IFqj$%U;K#Jd|Kqn{-?;5J=+7tX6~6W>L}sXfWfk@=)Uq)GBS`u
z($4Wb`&;^-hM_U#QmE56Ki+$?`a}f0SZvBTO{<|xw17702L)Db#tb5X9V(i%8@UyW
zsbR3r!lEtc%uuI@`@DAoTlSUWBdi*IVNS)>VG?StANZFI+;e@+?-kSj|CfG%(_X&t
zuW}bN*bkVDTHUe;c4WeIG68xPd+3uWh|}(qxrnEKk(*AoJom&?2^*P=_SNscVJ9eP
z0H(2#N%U5_ysb^T<(bdoG|D()8|okYX5lUNfd6!yhe_#<0OWQe^>o`Awx9oW^2R(2
zZaphie{!SEJ%BOH{gh~VhWEa14=KG%OM?A+$p}5Z5j>l$hDr6OM+O0l2@_DSM#kg0
zXF^<7iA|`;2X2#B+YiY@MI~roQ-jf6>>?@byVfQXSsDHCScT73N@|w^MB8NH>C{A#
z3A+@iQizGHiH74Vj8Hp*Wp}h@aAd~l!_4s~?2d~Sc(ED3MTI>rnNA*!_*Xf2m*vK3
zznV!k3#e&GbudRC60i61D=O!nfgvia>1o7>gD8bySC%3kqK=xNhuu&W2(6HHxbAab
z05E>Bx9wP(h*GmF!7?QfF21+S198sW&ZGi<T@;YB$uN^>`7>~_(PaE>LmdTGo4t$P
z=w_EV3d=c-|D|%DP&-)z^-9=2&V}tVFV8iaJjAQMv1@j#Id11tKB=Fmbk3}=@SGk{
z&<~8QL=n4e&T0P-_wVs;G5u7SYS^5$t&SXi{7)fis`p&r4slypn5ytrwoAuzDa(|<
zsnD)+Ffbs(9T?lQFzR-C>3RO1d%><b3gzj>*xeoHIJW4vlT+ZJZ(ItzdnamWW-l%Z
z&anBxK6CeFu1hq{KuDgs2F`Vfg+v^jENWl0@olyKQ%br>X`;qx2)lzd$F!l~3Gydk
zs3v#X=E}oo^(U>u`dv2AAMs4TYi-E6hKq?nX7D2rxA){JA%h(z?U!o(3dxiO*b9CT
zF?jTEOw(YSmQt-bBt|212TBmgcA}4|I`j8jT~BDbvz*3+m;GxnrkkP?E!VCL{4G(F
zsU~rsIaudzZt~Jjg=%)h@-zjn9fF8czsOJORT^(K0!?v8<UWdW;F2Dob(e~B6DjUz
zx`PX6!mj;RKwWm7q+UwW3+tv=ef+M)v@S-)c038{j8t5zv~9QAV@Q3CXt-bajsER>
zXJqqRj2bJN)|au`IPD_P!eA1Iv>u*=B~XE$`APSB%x^U(rkel++i8emR>{Izdh-3g
zM>Ipu%s&P*x5GyfVKZlnTx3yvq$z6?Zh68*mEwS56_UQxKXsACSmIS&Cl7j`ER1Ux
zBoJtYRv&Hb)*}gf$%wzbGmOImX#!W2Zl*2Xg!W5B&%}ak>^8{4(*!r@-)!vUX%D86
zM}Pda7QA(yPR_j@vZgAY&@Z+usUG^fLBQ^HMV;C@{8vx#w|6>utp^!Ryr%h{)c?!A
zaFmWX=G4Fm*^ryq<Yksgi^PE64{EWiM{nn*c1q5zd4U4$=aUyLLMoz|<y%}Q|4?EF
zH-qZT&W6osf|2V<2lapy`+DvJI;eO$*-QTM0ENj0JlYr0t{Paf-(TaL@rE@X5Ty2=
z_^uVQ{;|=9#--$mI|px!79U0T9p$te_3@9;-7e|jpK-1SC?O`*-;>n3q+eoDzdh{3
zbj$KxY|tl7IcF}xCU3AG0%f#0KQ>Zs931*I&}5SVglgxuZ+%2i5=ieBTdLTEa23F!
z`!Bfd#(m$obnm41lUJKg7)7a?q^@GSk8svgopzxrb%j0mw2MeL<`T*a08$C{fyD+f
ztZ+HZ3w-J_n;e{DvNI6&^^r}6rBVIk5(SW~xtR2_edhfULFNCIbS>aawr|{dN=Q!e
zI#iU3NYNbDe3i{tPC0~1d?h)h5wS6I`ab%wd`K#6eH1B&lnT9O3zI{ZBt+X-T8JIQ
zhOz(qUH|R6_P*DBy@%($@8|b>?)!fBKKG?+VU}5N$$oa<)hQy4H}g$(L39kd-Pr}n
z6Lz*)E}X!<+@QpKbr$j&WcnrzIe0f__(#|3S@v)<<&b3S`;+J7Cy*D!^0$06K@G-8
z7JOF7t_dv*Q-3N%Pr@8l(wypcFVVZUmg9+p^Sh+**J)Pu##pSY06o6!&=!@)8285f
z<SdF{JSJp;kUeHI$?V)q51GyV<vsvjcf=_R9=X`_N!Iw|F;H+IpWDiQ-TF8DZGayS
z;0~P!2TO~ZNY>ZlIsp_ub}o}l-n&Hq%g;eE&8&38>U*l0o^sF&GB!lFuXj_B;K3(g
zJmC8=bdYnvbSk=8nn|2{=_34LZOoF9csoB6q91K9KThRX=D@SM=RR%4hXxDig98qK
zWmLN;nPY51cquX@?D;RYIibvVKe8!P#H)AQLSncs-WaXxA*E?9hFTa?0b*1OVdFMS
zoSk@lFh)94B{ly>8|rVqRRUqrvXD{xn;`36vQ93%AJOqm^{})L`l-GuKu6s{$CY`u
z1a|^QE8`<&H)j9Dnq2wQ;{a{Gx)XTO(pE=}Zs-Ec&~u;k@n`>dCZq?DK7HBFc|xrL
z2T5i%uh?f*GmGKN*MnZmv%=0*e*!9tRKR6J!3j;u!aU7C_Ch3oJ`fRqaOxl&Y%E_N
z)4=<r3ecJ!^ceoj%uYbweg>&vr5$yKxwnJ!OjBHsru70i#ABqK=Yh~O%)33A&kl<>
zu0TRw+{YWT<h8daa3Ri#<*gYbL~YEsM$guC?&~dn%+a?iOhd#WL;x;id24x6n(mEF
zeoQ{ciYViB*Mg}WqAs$b%X9ylB!0ykCa3GhQGk`=w})n;e}!FrhT!%T=GoAlM3hP5
zU|DcVp5R3gD1aGH=z`PaLKkz~!C!~JEFA|23t(ZX{D_l6sbP^l4z_*dso$n)B78zB
zPZaoAFt^igaJt!EM;~3#F>3N+%O-aLE=n_6s)Q#E)k3<G(Vy0ALa6>;Ow;95H92+Q
z59sOoSF}|q7YonKnp;*VWr}Qvf%%ij7soq+E2MB?*1dK&4b0t^H8f;7#;73#H108^
z0=KBy=`_ydZUgT$-)cZ<Kc;_rSKM}Sg_C?S{8g-modN#q^l#Hd65?!kIxN}Y5tF^K
zq5vj`3h0|DKTN3IemC}G3_|u1ZKg^=4Ww7KmlDgI@L-bz@kl*y=VW#Fj25Phkt9GP
z^E<5B!?SmMAeVpfT>!sXarbSw#e_OJBhk*3DK3IB?D(68%X@*iW@Ds$FzzJSSdvou
zM_ycTwGbV$JdBNzmJZ*B@4^-wl0`t(+$v!r=wF7R8xS#gAqLFS{o^5C*mgJdS{@?{
zl6?u3cq(}w!Btw1Fnp+q2Y&f7?+&0iy6i`mt^{0+q=sD%I2OYzTDF%eEsS-z;3{Q3
zDMPdl`vz4^+2o}^vSKe-x*Dz1yQpsbQ61=leG^VEsKEvWYd}%6G%QoM*vf>V9rx7{
zhImNy!I>1!wOJA8-f=^kqTt>4R0!XLvxRh1%a7mFQ*9?)a3PxAWc7ugQ@+gR-rQbA
zy1;<NryG!*DRRMGfptEkfC|m2YzOnlZ^D&7TPBIp?&^2zs)yShQ4kwiRo{g7gD^9w
zw`rd-Y*OaN?L12&PXrAe%ca5Uc1#lotm4nfZOlX#iY#^Je%Xqbjs^7siR9Va$^^;I
z9_itPgb&_)tJK@vy{kC;@O!b6V4(pj=~*Vlx}MWLMMNEe9e_D$n24+sn&Lie4w0zq
zAcYrTbqXwazyju>ZNi7w?0vwu4Rl7wv8Pl|)jMkd{DeW1J{Vg#!FmjQe_+cNk%}Z%
zSzX7VN_eh?Ye0&UWB36vXXGL1)t;G2fm1}#kyvbSwK28ZtY@7FH&R>GknlZl8&BAn
z^3Unge`ZcI`E|SpOYD^s7QKMFzC*Y?c66(NE>2QAC1(X%h~QZ$yS;jnYSR|=4=*Y*
zy{R4QSjb&eatJrU?#rEE-JDr?K&B>|^$>FEGBS^(zsY*%5Gt47@tz$eefj`wY%Iz2
zrjd>BaQFHpTtBUkoz))mT&b$b{75_6-OFo1#wLDXuoK<q&;9zXdJBKe|FTnPqCG5H
zwjrXJyZ6bN#1DR)Rtupo6H8qw-n38(HE2~5e1>bpiW{Q~`fhiOw%sE>dLMB#eDuoN
zI^l5f75hcIpQg3Z!~`{Kiz~qQyQ(OS9HXzNoQ-yxa!<^AnMQc{<eA#k+IPma1*K3#
zOY>_bBWo{5Mp9U;xg^$q8y0WGfA9+5<J@X#XR5SixWPhzHZC;p9~!}S43O{bWj>2*
zzbeQof8BQ{#mmunsU%-OSGP54Qk?fvG|Yo<`=}MI=$RBq7_qIdu83y07+ohl&sm&P
z;ZN0jW5jA+O@@eOubTq;zunsNGNPJ@XfSr{QMeg4y|f{^yyA!JoYY+x<F@S6qyi?t
z5>FoNUh(%^i<ZD{k-xHWV^c(8o%Xz}Rd3<qZE-v*nU?6Lg;7x4_XW1mfDoYZuPWBr
zRyyx^71thD|Bw;KodX5VU_~a|-TRy#W=qn^!JYi?iQm?r3Vt#=*dr6)5TTp$85(?9
z_Y-;WAnr{G^xj+oj6)1x?uWBQI`IdYF<i+3`P5(k&abO3k4mWxw|mxrV`Ww@v@l+Q
z<Q)G=1%}ohrFRJ|m^eO|=+~};)5B=RwBJfk4(p?YTZ-oFu(|SuF71nPQX}xWJM`Qi
z|IP78OTEvD2EF<TVp+ug^UOD-U)iworYZi*tsLUndpQIJrvR5_IDr#ur--}=f~iZ#
zi(%^u1cAIKhZyvCPA~0i<k~x)8M5I=ldak-QN0S;J6;I{Z`Jl8E@_u5ieBO>t$MVN
zn0<mwR(^I$)lrIYg?JbC{2^q$2FSM&c$|q>n~$(}|Ge*{mAQjDW%uu&_j$hZ_mySF
zG}ihcuXqN@ka52+!@aQt=~%1u5ahNEbO+aBqYT19>$~0ayTpvpbUF~yy0;a2$;=hh
zm~i#lEgs=?sSlA)$B!l5Izl1MRhYANpLYU_t@~HCC6m}1__cWNcx^mQL4a0dapC5?
zJvZSwqh=$u;y~?7U~KXDqGPkvS%5~tQ6seEIY=2U2n<suf8Wv}=4gi?RTF>i6_yk3
zh)PW}BUmsWPbM{NmP}M_wa=bT`l*AB1#5i<)coTC#A*hX)2@#Ap(d^%BZ%-*cF;uS
z`1J3D;@EP&8J2(gY_&7o*H=C$;WX&gBWh8h;6N;g9c&a2)jcxksgzXZEMz8n-nr3x
zj+Aed#wD0Dn-BU82D2Cbnj)@eY9Cb)>Fu1;dVk}SiMd+0Yx@^;O?$39WmPu^en|ZN
zCDj~P9)$}*GF+f+()jT_xK6A26IG_83m6;KRMAa++U=SeJh|qihTMMw9L)cwzeczV
z0jlK6P595i&>Z+r5LX2mt_=<Kpd%yNH$IS_d5`I~^^<B<n1}qAQQSp|w>rYca~b8i
z<mGD&S~&J&E5Uoa68YbsUQRVB=MBk#7vzIEL_LZ0hypKY#~RRKXMB`;;og*L!)erJ
z(6#EldKr(zjy*!jn~SrGk{s>=#tg0!skw)`fY)QLOg1w=QV)t_vEf^guTKy77{zi@
zsBh{E)`>)p)=CD<zYo{DWx-#QPnv^nm<@YTGt7drKzfqX5~^lv&j#A5K7=e|{N~&;
zY9!D5(-!=w(irOp11B&QZwyTloBeVmv_#%Ej6zI^95w0{gqd37e;?apS&=<fW+Pq)
zsF;S5l)+<G`y)3I)(yvWzxFKpn)AoLUJi~wAbM>puIHKNe~$YKC@)aXE~C~2DI__T
zw<S|K3?u1FvRs=3FmB&y82KQ|nPpUmo!WRt*zoAAs@j(XHozExGv9I75UPYj=a*5r
z_N+{5=|s`uZ8JynNcEu8Cd}=ttrcqQmHdb8Z<?(QX^S7bfc2C0ZBb=(Ac10f0fG@h
z4?+~C1nL2fPAyh$v#Qtd2fz5>?E0bXhgpQOSTJ;v4v<df9H*rsjjw<OaFmxBzike>
zfd8o3MfPyXH$>M`Sw&0~qTw$+%)>@sLqE#IKa01|mL+=d7xboxWbsNXH9732ab%;q
zNv$2;lxrbxm+z2SGF+50IA))-s}Ac!q65i$_RY#M3srXZ0XdvSy*b{S9!hwRN)Aae
z_0_2XA7L{Ir-t`2OXR5XEKnEf2<!W}`z9yua_j8waihV(8xJe?@+Srs=s*dUvY<rR
z)o~G8xp~n+A91m^18aiMsL-WadBktWfSs8vLxk-Ku<<6qlE<&@9n*c!S#7B<b}51k
z67{?yh;7X+rvqlA@@;i%zph>dHG1JQ^7SpjwB~%5`U(oWG^&U4!*apjiJ#}{!66nS
zl-FsDrbS!k=sS)C6GN_hZnY}w=^#&al+M~P?cUA3OlLFAW=jdvf)jcQK?}SH(E3)2
z-F9%mTY%Q;_S}M<xttAo{YGU0bM{&9C_m&qa_nLnHm@8Vs|+mb%xv(`z(`8JCDlg%
z2?2}cri~e0xvK$LE#I{$sbgTxqd3XrpJ{U1awpD?2$#bO_2rC)KSqGDdEN6U{xMH`
zB7Bv<V~e7(9^@n5H!Hu$eyv$9OztlG*-^)}dm8}`{xjnKH~W@NwIIvbm9v{)21Txp
z7LQE%)=*x_WTNIWzvYP00MV_H?(}|{WS`&B$3Fk@A@jlCIo@@M`@B%F@$cMh4R+g5
zX!#+h6NA6=E$=~kLBG&ylOs6=f&%T=PO6Bc+e28+(R%ntS_d9ag!0et57)*bcQHq)
zsNeTs-$p@a1TOgMh-*%Itl-CNP-E-}6eL3hx_wUzdz1^$z<CpfXB&jYjFMQvk<Iu`
zqQ2gSB7|LKo!CkTW5ezV%^MzYtjmM%+N|BCwDD=PfNnzy>&{pk7lt3shaBT0aa};%
z*x{DXix)o8u$*nW*&N!s97L$XmI6)cQ`b%))}TqVF5y}+;V45;1PhAqAIEY~gn)+3
z;7vkXrgGW8;oGpo-jJ5oE~AQQ<_@g@<mOhG8%y>wto%}W*S+A1_*2iZAu>JFKK`?+
zj==>M%x8;fT9DNep|D{T*LA&GK-c$R$~ASzx`306F7!_E`!iES)>t-*ePFI75AJt8
zwK{_vAFGGCYJSG%eQW!5Jq-RG{GOT-mjewOeO;c`*lRu|0=n<=;ugNqzA55boEB8Q
zx@Z?cnf>6tBJwTWGp^v^xV}^i>RTQ5Y@95S2(NEsL4~WQ>>5Gqf4JRns$;YMc8qTf
zzh9pGsXr8qE#kcB%pr%W=E0|$v3nKC&{R6un6Im`NXzW*;pM-10n<riSPG6nd3^`m
zPVso%1v+3Algd&M&9M(L`Im#+6zd(K)^Bck9HfABLV*PXT`QOPb4TU!;Ju^jm`uiW
zQh#qlE`r2Mb9xusBa-kRf(rQ2ThO5Rm&NNxY~GzDh~>icC@RRkUcw&=BO!ej3%40i
zpp@M_(JJjf%^^A%aLuVA64Z#%-eW=|?5yuf;4CVriK4z?p?ln~{SLp~Kf{<eJc{Mm
ztl_oAk7xa$5gq$nEHjZ@)`#Vo>UKzFtvsMeiqm@S<&r`E@2PDq0jnQ!7*JyPx5B=<
z4;LXebS>-z5*AASvs*&X6ft$8eH7x6+uYdbrKnpS*h&pu?I^0TW!!d5)3kU+Ij|05
z6lbBS*cux(e~=l_gA$+PyH^{~fwpF&jZS@OoEnFyd~5N>XEC{CT{V^T^K+)l*ucg7
zMNqmAE4nP`xEf@7O~&)N026Qts9Uze`~ePT=q{1dQ$Lx0z?$68O?PLPj<5BK{)j1%
z1kXw9yy*bzIs&8A(8~U2UA6uV5|+3d8gbmFE8<neZKog}QBIC97mt?jqytawkx)uF
z!4DMde!ZyjG}u41{CT!+@i<L)qVUG4=;c{8$bAegzn-4UFK4?#GewRq;nHo0=!C}t
z`VC8^g!GcwqgSR!MBv8yW(gl!^`Gvwz`MpbFFgT)2D^<FGCdeBpc_~sMH%XUIGxAY
z6wNVH*xU&yF*Q)gQuojdqyv5SYU*h&YpeR0c<!2U)6_#}u(2Qos|<oq3T8&k5o3l*
zqW$5K;3R#8pfKTR>4szs2&MYqMG`gyp1%lZXO5yar>3@4Rvh97svUgV9{da=g&857
zLF=2}^r;iVta7LA|Cvj&9fDbYUhz7_i{%G+n4hjA@mllyjv8MB2P@mFFtlX<K5kfw
zk4*{;S+jov8{$?_74kVH@+}eWfsS&x))kg4ptla*r@%0JzT?=+GZ|HypIP0b%cz%C
z&?5R>H{poZD2Iq?RNi~wu+6%1kd`?(_w>F;x=ZIc#i_ck3MvrZ+2=4F|Gerte|_I|
z(zaLVp$K!5CZu3Hw;?@#eR(G^k`(Tsg52XZ;PaXIDP9e%b_E5`UQ{jmm4OyKjC1X0
zUs+^@Gm~Y93?5SCUo4m+imD=3^(1ah*h-d`dwW{gk`Bh1I25me*y#rj?(rGg&F|VR
z+)!$JRI?5A1j{;>IpUTrP^BtRu*pee&Tb&MO%c^?*Ef>__wz8Ib>Pq$eqzY9!Eznm
zy*(Y)WtRuPCJ+b9=g$U=V?$Q=ySHch<DnxTE)T{V;y---okJ{1j%t-Py0>FJiQGN8
z2Ro-K+&~L0+*8xY<7lWe#z=hAS-B<aL<VUvUIiai0k&IbaHOw>S<W+<??d+&(il0q
zm@Ru+m=nM?2w_nn5W<YK%psFm9>GXB8`*D(FtzE(C+KA4UQNtIvd<9tv$)-K>EzD<
zciYc))u-ATG5=P*VPi;lZk(EQb{Eyg`f1RC_Ns_hb)$LBi{PL|(2zX;Qxzoa3XWV=
zK^%e7gJY-N)oIzLH;r}bM}8?wYyph;)gGaww7p;lbF}4z&jG$DD;dD__k8}QMA>x=
zoRk(<ePQ3o9;GBkk*d0>hwr1dV=RylW@7oJKqsJX$DB>ekI=XX7JT;ixxlwHlqbUV
z7sVs;3`Yy@vjuYa6U<j`z(WE05VzbBdj<#Xsja<`#m3GlbBH~2Hns|w@U;!1hrBH=
z?RCvBIMa^G@K1*~rbyA(vi5lLD{>%J|D3rGQa!bm^fABA|68LW{?c(>4cPj$2f&LG
zdMcAo*w`wizB%*}%h^zJN3v-{)1tpmEk_C!8EsZ%&l*uy)gE?)e;07_=e;U+==h^x
zd2XaoUj1cxb?tc7%qG6We?iWQMD(8O^VEb0SJDYj+J@*~UboLx3Kzl>OLuVh&9C4T
z)1=0yU1jC8WVB>tWRzu2-adX{IC5&wl_@!yKQkR=wm{PVe|E^cO8;-~Sj@$c@K6tb
Z%jl4p)2@n2|H)*buLHFG2Rche=6_IWu|@y@

literal 0
HcmV?d00001

diff --git a/trunk/build/NWGNUenvironment.inc b/trunk/build/NWGNUenvironment.inc
new file mode 100644
index 0000000000..ea3ded6b12
--- /dev/null
+++ b/trunk/build/NWGNUenvironment.inc
@@ -0,0 +1,320 @@
+#
+# Setup needed Tools and Libraries
+#
+
+ifeq "$(wildcard $(AP_WORK)\NWGNUcustom.ini)" "$(AP_WORK)\NWGNUcustom.ini"
+include $(AP_WORK)\NWGNUcustom.ini
+CUSTOM_INI = $(AP_WORK)\NWGNUcustom.ini
+endif
+
+ifndef VERBOSE
+.SILENT:
+endif
+
+#
+# Treat like an include
+#
+ifndef EnvironmentDefined
+
+#
+# simple macros for parsing makefiles
+#
+EOLIST:=
+EMPTY :=
+COMMA := ,
+SPACE := $(EMPTY) $(EMPTY)
+
+#
+# Base environment
+#
+
+# Try and handle case issues
+ifndef NOVELLLIBC
+ifdef NovellLibC
+NOVELLLIBC = $(NovellLibC)
+endif
+endif
+
+ifndef NOVELLLIBC
+NOVELLLIBC = C:/novell/ndk/libc
+endif
+
+# This is a placeholder
+# ifndef LDAPSDK
+# LDAPSDK = C:/novell/ndk/cldapsdk
+# endif
+
+# This is a placeholder
+# ifndef ZLIBSDK
+# ZLIBSDK = C:/novell/ndk/zlibsdk
+# endif
+
+ifndef METROWERKS
+METROWERKS = C:\Program Files\Metrowerks\CodeWarrior
+endif
+
+# If LM_LICENSE_FILE isn't defined, define a variable that can be used to
+# restart make with it defined
+ifndef LM_LICENSE_FILE
+NO_LICENSE_FILE = NO_LICENSE_FILE
+endif
+
+#
+# Set the Release type that you want to build, possible values are:
+#
+#  debug		- full debug switches are set
+#  noopt		- normal switches are set (default)
+#  optimized	- optimization switches are set
+
+ifdef reltype
+RELEASE=$(reltype)
+endif
+
+ifdef RELTYPE
+RELEASE=$(RELTYPE)
+endif
+
+ifdef debug
+RELEASE=debug
+endif
+
+ifdef DEBUG
+RELEASE=debug
+endif
+
+ifdef optimized
+RELEASE=optimized
+endif
+
+ifdef OPTIMIZED
+RELEASE=optimized
+endif
+
+ifndef RELEASE
+RELEASE = optimized
+endif
+
+ifeq "$(RELEASE)" "debug"
+OBJDIR = Debug.o
+endif
+
+ifeq "$(RELEASE)" "noopt"
+OBJDIR = Noopt
+endif
+
+ifeq "$(RELEASE)" "optimized"
+OBJDIR = Release.o
+endif
+
+#
+# Setup compiler information
+#
+
+# MetroWerks NLM tools
+CC		= mwccnlm
+CPP		= mwccnlm
+LINK	= mwldnlm
+LIB		= mwldnlm -type library -w nocmdline
+
+ifdef IPV6
+ifndef USE_STDSOCKETS
+USE_STDSOCKETS=1
+endif
+endif
+
+NOVI	= $(NOVELLLIBC)\imports
+
+INCDIRS 	= $(NOVELLLIBC)\include;$(NOVELLLIBC)\include\nks;$(NOVELLLIBC)\include\winsock;
+ifneq "$(LDAPSDK)" ""
+INCDIRS := $(INCDIRS);$(LDAPSDK)/inc
+endif
+ifneq "$(ZLIBSDK)" ""
+INCDIRS := $(INCDIRS);$(ZLIBSDK)
+endif
+
+DEFINES		= -DNETWARE 
+ifndef USE_STDSOCKETS
+DEFINES += -DUSE_WINSOCK
+endif
+ifndef DEBUG
+DEFINES += -DNDEBUG
+endif
+
+#
+# MetroWerks static Libraries
+
+CLIB3S	= $(METROWERKS)\Novell Support\Metrowerks Support\Libraries\Runtime\mwcrtl.lib
+MATH3S	=
+PLIB3S	= $(METROWERKS)\Novell Support\Metrowerks Support\Libraries\MSL C++\MWCPP.lib
+
+# Base compile flags
+# and prefix or precompiled header added here.
+
+# The default flags are as follows:
+#
+# -c                    compile only, no link
+# -nosyspath            treat #include <...> like #include "..."
+# -Cpp_exceptions off   disable C++ exceptions
+# -RTTI off             disable C++ run-time typing information
+# -align 4              align on 4 byte bounderies
+# -w nocmdline          disable command-line driver/parser warnings
+# -proc PII             generate code base on Pentium II instruction set
+# -inst mmx             use MMX extensions (Not used)
+
+CFLAGS = -c -nosyspath -Cpp_exceptions off -RTTI off -align 4 -w nocmdline -proc PII 
+
+# -g                    generate debugging information
+# -O0                   level 0 optimizations
+
+ifeq "$(RELEASE)" "debug"
+CFLAGS += -g -O0
+endif
+
+# -O4,p                 level 4 optimizations, optimize for speed
+ifeq "$(RELEASE)" "optimized"
+CFLAGS += -O4,p
+endif
+
+# -prefix pre_nw.h      #include pre_nw.h for all files
+
+CFLAGS += -prefix pre_nw.h
+
+
+PATH:=$(PATH);$(METROWERKS)\bin;$(METROWERKS)\Other Metrowerks Tools\Command Line Tools
+
+#
+# Declare major project deliverables output directories here
+#
+
+ifdef DEST
+INSTALL = $(DEST)
+ifeq (\, $(findstring \,$(INSTALL)))
+INSTDIRS = $(DEST)
+endif
+endif
+
+ifdef dest
+INSTALL = $(dest)
+ifeq (\, $(findstring \,$(INSTALL)))
+INSTDIRS = $(dest)
+endif
+endif
+
+ifndef INSTALL
+INSTALL = $(AP_WORK)\Dist
+INSTDIRS = $(AP_WORK)\Dist
+endif
+
+# Add support for building IPV6 alongside
+ifneq "$(IPV6)" ""
+DEFINES += -DNW_BUILD_IPV6
+INCDIRS := $(NOVELLLIBC)\include\winsock\IPV6;$(INCDIRS)
+
+ifneq "$(findstring IPV6,$(OBJDIR))" "IPV6"
+OBJDIR := $(OBJDIR)_IPV6
+endif
+        
+ifneq "$(findstring IPV6,$(INSTALL))" "IPV6"
+INSTALL := $(INSTALL)_IPV6
+endif        
+
+ifneq "$(findstring IPV6,$(INSTDIRS))" "IPV6"
+INSTDIRS := $(INSTDIRS)_IPV6
+endif
+
+endif
+
+INSTDEVDIRS := \
+    $(INSTDIRS) \
+	$(INSTALL)\Apache2\include \
+	$(INSTALL)\Apache2\lib \
+
+INSTDIRS += \
+	$(INSTALL)\Apache2 \
+	$(INSTALL)\Apache2\bin \
+	$(INSTALL)\Apache2\cgi-bin \
+	$(INSTALL)\Apache2\conf \
+	$(INSTALL)\Apache2\error \
+	$(INSTALL)\Apache2\htdocs \
+	$(INSTALL)\Apache2\icons \
+	$(INSTALL)\Apache2\logs \
+	$(INSTALL)\Apache2\man \
+	$(INSTALL)\Apache2\manual \
+	$(INSTALL)\Apache2\modules \
+
+#
+# Declare Command and tool macros here
+#
+
+# Os2LibPath is an extra check to see if we are on NT
+ifdef Os2LibPath
+OS = Windows_NT
+endif
+
+ifeq "$(OS)" "Windows_NT"
+CMD=cmd /C
+CHK=cmd /C if exist
+CHKNOT=cmd /C if not exist
+DEL = del /F
+DELTREE = cmd /C rd /s/q
+WINNT=1
+XCOPYSW = /E
+else
+CMD=command /C
+CHK=command /C if exist
+CHKNOT=command /C if not exist
+DEL = del
+DELTREE = deltree /y
+XCOPYSW = /E /Y
+endif
+
+
+#
+# Setup base C compiler flags
+#
+
+#
+# Common directories
+#
+
+STDMOD		= $(AP_WORK)/modules
+NWOS		= $(AP_WORK)/os/netware
+SERVER		= $(AP_WORK)/server
+SRC		= $(AP_WORK)
+APR		= $(APR_WORK)
+APRUTIL		= $(APU_WORK)
+APULDAP		= $(APU_WORK)/ldap
+SUPMOD		= $(AP_WORK)/support
+PCRE		= $(AP_WORK)/srclib/pcre
+APRTEST		= $(APR_WORK)/test
+HTTPD		= $(AP_WORK)/modules/http
+XML		= $(APU_WORK)/xml
+PREBUILD_INST   = $(AP_WORK)\nwprebuild
+
+#
+# Internal Libraries
+#
+
+APRLIB		= $(APR)/$(OBJDIR)/aprlib.lib
+APRUTLIB	= $(APRUTIL)/$(OBJDIR)/aprutil.lib
+APULDAPLIB	= $(APULDAP)/$(OBJDIR)/apuldap.lib
+STMODLIB	= $(STDMOD)/$(OBJDIR)/stdmod.lib
+PCRELIB		= $(PCRE)/$(OBJDIR)/pcre.lib
+NWOSLIB		= $(NWOS)/$(OBJDIR)/netware.lib
+SERVLIB		= $(SERVER)/$(OBJDIR)/server.lib
+HTTPDLIB	= $(HTTPD)/$(OBJDIR)/httpd.lib
+XMLLIB		= $(XML)/$(OBJDIR)/xmllib.lib
+
+#
+# Additional general defines
+#
+
+EnvironmentDefined = 1
+endif # ifndef EnvironmentDefined
+
+# This is always set so that it will show up in lower directories
+
+ifdef Path
+Path = $(PATH)
+endif
+
diff --git a/trunk/build/NWGNUhead.inc b/trunk/build/NWGNUhead.inc
new file mode 100644
index 0000000000..cdbaf2728f
--- /dev/null
+++ b/trunk/build/NWGNUhead.inc
@@ -0,0 +1,110 @@
+#
+# Obtain the global build environment
+#
+
+include $(AP_WORK)\build\NWGNUenvironment.inc
+
+#
+# Define base targets and rules
+# 
+
+TARGETS = libs nlms install clobber_libs clobber_nlms clean installdev
+
+.PHONY : $(TARGETS) default all help $(NO_LICENSE_FILE)
+
+# Here is where we will use the NO_LICENSE_FILE variable to see if we need to
+# restart the make with it defined
+
+ifdef NO_LICENSE_FILE
+
+default: NO_LICENSE_FILE
+
+all: NO_LICENSE_FILE
+
+install :: NO_LICENSE_FILE
+
+installdev :: NO_LICENSE_FILE
+
+NO_LICENSE_FILE :
+	$(MAKE) $(MAKECMDGOALS) -f NWGNUmakefile RELEASE=$(RELEASE) DEST="$(INSTALL)" LM_LICENSE_FILE="$(METROWERKS)\license.dat"
+
+else # LM_LICENSE_FILE must be defined so use the real targets
+
+default: $(SUBDIRS) libs nlms
+
+all: $(SUBDIRS) libs nlms install
+
+$(TARGETS) :: $(SUBDIRS)
+
+install :: nlms $(INSTDIRS)
+
+installdev :: $(INSTDEVDIRS)
+
+$(INSTDIRS) ::
+	$(CHKNOT) $@\NUL mkdir $@
+
+$(INSTDEVDIRS) ::
+	$(CHKNOT) $@\NUL mkdir $@
+
+endif #NO_LICENSE_FILE check
+
+help :
+	@echo targets for RELEASE=$(RELEASE):
+	@echo (default) . . . . libs nlms
+	@echo all . . . . . . . does everything (libs nlms install)
+	@echo libs. . . . . . . builds all libs
+	@echo nlms. . . . . . . builds all nlms
+	@echo install . . . . . builds libs and nlms and copies install files to
+	@echo                   "$(INSTALL)"
+	@echo installdev. . . . copies headers and files needed for development to
+	@echo                   "$(INSTALL)"
+	@echo clean . . . . . . deletes $(OBJDIR) dirs, *.err, and *.map
+	@echo clobber_all . . . deletes all possible output from the make
+	@echo clobber_install . deletes all files in $(INSTALL)
+	@$(CMD) echo.
+	@echo Multiple targets can be used on a single nmake command line -
+	@echo (i.e. $(MAKE) clean all)
+	@$(CMD) echo.
+	@echo You can also specify RELEASE=debug, RELEASE=noopt, or RELEASE=optimized
+	@echo The default is RELEASE=optimized
+
+clobber_all :: clean clobber_install clobber_prebuild
+
+clobber_install ::
+	-$(DELTREE) $(INSTALL) 2>NUL
+        
+clobber_prebuild ::
+	$(CHK) $(PREBUILD_INST)\*.* $(DEL) $(PREBUILD_INST)\*.*
+	-$(DELTREE) $(PREBUILD_INST) 2> NUL
+
+#
+# build recursive targets
+#
+
+$(SUBDIRS) : FORCE
+ifneq "$(MAKECMDGOALS)" "clean"
+	$(CMD) echo.
+	@echo Building $(CURDIR)/$@
+endif
+	$(MAKE) -C $@ $(MAKECMDGOALS) -f NWGNUmakefile RELEASE=$(RELEASE) DEST="$(INSTALL)" LM_LICENSE_FILE="$(LM_LICENSE_FILE)"
+	$(CMD) echo.
+
+FORCE:
+
+#
+# Standard targets
+#
+
+clean :: $(SUBDIRS)
+	@echo Cleaning up $(CURDIR)
+	-$(DELTREE) $(OBJDIR) 2> NUL
+	$(CHK) *.err $(DEL) *.err
+	$(CHK) *.map $(DEL) *.map
+	$(CHK) *.d $(DEL) *.d
+	$(CHK) *.tmp $(DEL) *.tmp
+	$(CHK) xc.bat $(DEL) xc.bat
+	-$(DELTREE) $(OBJDIR) 2> NUL
+
+$(OBJDIR) ::
+	$(CHKNOT) $(OBJDIR)\nul mkdir $(OBJDIR)
+
diff --git a/trunk/build/NWGNUmakefile b/trunk/build/NWGNUmakefile
new file mode 100644
index 0000000000..582c2c9332
--- /dev/null
+++ b/trunk/build/NWGNUmakefile
@@ -0,0 +1,82 @@
+#
+# Declare the sub-directories to be built here
+#
+
+SUBDIRS = \
+	$(EOLIST) 
+
+#
+# Get the 'head' of the build environment.  This includes default targets and
+# paths to tools
+#
+
+include $(AP_WORK)\build\NWGNUhead.inc
+
+#
+# build this level's files
+
+FILES_prebuild_headers = \
+	$(APR)/include/apr.h \
+	$(APRUTIL)/include/apu.h \
+	$(APRUTIL)/include/apr_ldap.h \
+	$(PCRE)/config.h \
+	$(PCRE)/pcre.h \
+	$(EOLIST) 
+    
+nlms :: $(NWOS)/httpd.imp
+
+$(NWOS)/httpd.imp : make_nw_export.awk nw_export.i
+	@echo Generating $(subst /,\,$@)
+	awk -f make_nw_export.awk nw_export.i | sort >$(NWOS)/httpd.imp
+    
+nw_export.i : nw_export.inc $(FILES_prebuild_headers) cc.opt
+	@echo Generating $(subst /,\,$@)
+	$(CC) $< @cc.opt
+	
+cc.opt : NWGNUmakefile $(AP_WORK)\build\NWGNUenvironment.inc $(AP_WORK)\build\NWGNUtail.inc $(AP_WORK)\build\NWGNUhead.inc
+	$(CHK) $@ $(DEL) $@
+	@echo -P >> $@
+	@echo -EP >> $@
+	@echo -nosyspath >> $@
+	@echo -w nocmdline >> $@
+	@echo $(DEFINES) >> $@
+	@echo -DCORE_PRIVATE >> $@
+	@echo -I..\include >> $@
+	@echo -I..\modules\http >> $@
+	@echo -I..\modules\aaa >> $@
+	@echo -I..\os\netware >> $@
+	@echo -I..\server\mpm\netware >> $@
+	@echo -I$(APR)\include >> $@
+	@echo -I$(APRUTIL)\include >> $@
+	@echo -ir $(NOVELLLIBC) >> $@
+
+$(APR)/include/%.h: $(subst /,\,$(APR))\include\%.hnw
+	@echo Creating $(subst /,\,$@)
+	copy $< $(subst /,\,$(APR))\include\$(@F)
+
+$(APRUTIL)/include/%.h: $(subst /,\,$(APRUTIL))\include\%.hnw
+	@echo Creating $(subst /,\,$@)
+	copy $< $(subst /,\,$(APRUTIL))\include\$(@F)
+
+$(PCRE)/%.h: $(subst /,\,$(PCRE))\%.hw
+	@echo Creating $(subst /,\,$@)
+	copy $< $(subst /,\,$(PCRE))\$(@F)
+
+#
+# You can use this target if all that is needed is to copy files to the
+# installation area
+#
+install :: nlms FORCE
+	
+
+clean ::
+	$(CHK) nw_export.i                                  $(DEL) nw_export.i
+	$(CHK) cc.opt                                       $(DEL) cc.opt
+	$(CHK) NWGNUversion.inc                             $(DEL) NWGNUversion.inc
+	$(CHK) $(subst /,\,$(APR))\include\apr.h            $(DEL) $(subst /,\,$(APR))\include\apr.h
+	$(CHK) $(subst /,\,$(APRUTIL))\include\apu.h        $(DEL) $(subst /,\,$(APRUTIL))\include\apu.h
+	$(CHK) $(subst /,\,$(APRUTIL))\include\apr_ldap.h   $(DEL) $(subst /,\,$(APRUTIL))\include\apr_ldap.h
+	$(CHK) $(subst /,\,$(PCRE))\config.h                $(DEL) $(subst /,\,$(PCRE))\config.h
+	$(CHK) $(subst /,\,$(PCRE))\pcre.h                  $(DEL) $(subst /,\,$(PCRE))\pcre.h
+	$(CHK) $(subst /,\,$(NWOS))\httpd.imp               $(DEL) $(subst /,\,$(NWOS))\httpd.imp
+    
diff --git a/trunk/build/NWGNUtail.inc b/trunk/build/NWGNUtail.inc
new file mode 100644
index 0000000000..3a44d646f3
--- /dev/null
+++ b/trunk/build/NWGNUtail.inc
@@ -0,0 +1,320 @@
+#
+# This contains final targets and should be included at the end of any
+# NWGNUmakefile file
+#
+
+#
+# If we are going to create an nlm, make sure we have assigned variables to
+# use during the link.
+#
+echo NLM_NAME=$(NLM_NAME)
+ifndef NLM_NAME
+NLM_NAME = $(TARGET_nlm)
+endif
+
+ifndef NLM_DESCRIPTION
+NLM_DESCRIPTION = $(NLM_NAME)
+endif
+
+ifndef NLM_THREAD_NAME
+NLM_THREAD_NAME = $(NLM_NAME) Thread
+endif
+
+ifndef NLM_SCREEN_NAME
+NLM_SCREEN_NAME = DEFAULT
+endif
+
+ifndef NLM_COPYRIGHT
+NLM_COPYRIGHT = Copyright 2000-2005 The Apache Software Foundation or its licensors as applicable.  Licensed under the Apache License Version 2.0.
+endif
+
+#
+# Create dependency lists based on the files available
+#
+
+CCOPT_DEPENDS 	= \
+				$(AP_WORK)\build\NWGNUhead.inc \
+				$(AP_WORK)\build\NWGNUenvironment.inc \
+				$(AP_WORK)\build\NWGNUtail.inc \
+				NWGNUmakefile \
+				$(CUSTOM_INI) \
+				$(EOLIST)
+
+CPPOPT_DEPENDS	= \
+				$(AP_WORK)\build\NWGNUhead.inc \
+				$(AP_WORK)\build\NWGNUenvironment.inc \
+				$(AP_WORK)\build\NWGNUtail.inc \
+				NWGNUmakefile \
+				$(CUSTOM_INI) \
+				$(EOLIST)
+
+$(NLM_NAME)_LINKOPT_DEPENDS	= \
+				$(TARGET_lib) \
+				$(AP_WORK)\build\NWGNUenvironment.inc \
+				NWGNUmakefile \
+				$(AP_WORK)\build\NWGNUtail.inc \
+				$(CUSTOM_INI) \
+				$(VERSION_INC) \
+				$(EOLIST)
+
+ifeq "$(words $(strip $(TARGET_lib)))" "1"
+LIB_NAME					= $(basename $(notdir $(TARGET_lib)))
+$(LIB_NAME)_LIBLST_DEPENDS	= \
+				$(FILES_lib_objs) \
+				$(AP_WORK)\build\NWGNUenvironment.inc \
+				NWGNUmakefile \
+				$(AP_WORK)\build\NWGNUtail.inc \
+				$(CUSTOM_INI) \
+				$(EOLIST)
+endif
+
+ifeq "$(wildcard NWGNU$(LIB_NAME))" "NWGNU$(LIB_NAME)"
+$(LIB_NAME)_LIBLST_DEPENDS	+= NWGNU$(LIB_NAME)
+endif
+
+ifeq "$(wildcard NWGNU$(NLM_NAME))" "NWGNU$(NLM_NAME)"
+$(NLM_NAME)_LINKOPT_DEPENDS	+= NWGNU$(NLM_NAME)
+CCOPT_DEPENDS 	+= NWGNU$(NLM_NAME)
+CPPOPT_DEPENDS 	+= NWGNU$(NLM_NAME)
+endif
+
+#
+# Generic compiler rules
+#
+
+$(AP_WORK)\build\NWGNUversion.inc : $(AP_WORK)\include\ap_release.h $(AP_WORK)\build\nw_ver.awk
+	@echo Generating $(subst /,\,$@)
+	awk -f $(AP_WORK)\build\nw_ver.awk $(AP_WORK)\include\ap_release.h > $(AP_WORK)\build\NWGNUversion.inc
+
+-include $(AP_WORK)\build\NWGNUversion.inc
+
+ifneq "$(strip $(VERSION_STR))" ""
+VERSION_INC = $(AP_WORK)\build\NWGNUversion.inc
+else
+VERSION		= 2,0,0
+VERSION_STR	= 2.0.0
+endif
+
+
+ifeq "$(words $(strip $(TARGET_nlm)))" "1"
+
+$(OBJDIR)/%.o: %.c $(OBJDIR)\$(NLM_NAME)_cc.opt
+	@echo Compiling $<
+	$(CC) $< -o=$(OBJDIR)\$(@F) @$(OBJDIR)\$(NLM_NAME)_cc.opt
+
+$(OBJDIR)\$(NLM_NAME)_cc.opt: $(CCOPT_DEPENDS)
+	$(CHK) $@ $(DEL) $@
+	@echo Generating $@
+ifneq "$(strip $(CFLAGS))" ""
+	@echo $(CFLAGS) >> $@
+endif
+ifneq "$(strip $(XCFLAGS))" ""
+	@echo $(XCFLAGS) >> $@
+endif
+ifneq "$(strip $(XINCDIRS))" ""
+	@echo $(foreach xincdir,$(strip $(subst ;,$(SPACE),$(XINCDIRS))),-I$(xincdir)) >> $@
+endif
+ifneq "$(strip $(INCDIRS))" ""
+	@echo $(foreach incdir,$(strip $(subst ;,$(SPACE),$(INCDIRS))),-I$(incdir)) >> $@
+endif
+ifneq "$(strip $(DEFINES))" ""
+	@echo $(DEFINES) >> $@
+endif
+ifneq "$(strip $(XDEFINES))" ""
+	@echo $(XDEFINES) >> $@
+endif
+
+$(OBJDIR)/%.o: %.cpp $(OBJDIR)\cpp.opt
+	@echo Compiling $<
+	$(CPP) $< -o=$(OBJDIR)\$(@F) @$(OBJDIR)\cpp.opt
+
+$(OBJDIR)\cpp.opt: $(CPPOPT_DEPENDS)
+	$(CHK) $@ $(DEL) $@
+	@echo Generating $@
+ifneq "$(strip $(CFLAGS))" ""
+	@echo $(CFLAGS) >> $@
+endif
+ifneq "$(strip $(XCFLAGS))" ""
+	@echo $(XCFLAGS) >> $@
+endif
+ifneq "$(strip $(XINCDIRS))" ""
+	@echo $(foreach xincdir,$(strip $(subst ;,$(SPACE),$(XINCDIRS))),-I$(xincdir)) >> $@
+endif
+ifneq "$(strip $(INCDIRS))" ""
+	@echo $(foreach incdir,$(strip $(subst ;,$(SPACE),$(INCDIRS))),-I$(incdir)) >> $@
+endif
+ifneq "$(strip $(DEFINES))" ""
+	@echo $(DEFINES) >> $@
+endif
+ifneq "$(strip $(XDEFINES))" ""
+	@echo $(XDEFINES) >> $@
+endif
+
+endif # one target nlm
+
+#
+# Rules to build libraries
+#
+
+# If we only have one target library then build it
+
+ifeq "$(words $(strip $(TARGET_lib)))" "1"
+
+$(TARGET_lib) : $(OBJDIR)\$(LIB_NAME)_lib.lst
+	@echo Generating $@
+	$(CHK) $(OBJDIR)\$(@F) $(DEL) $(OBJDIR)\$(@F)
+	$(LIB) -o $(OBJDIR)\$(@F) @$?
+
+$(OBJDIR)\$(LIB_NAME)_lib.lst: $($(LIB_NAME)_LIBLST_DEPENDS)
+	$(CHK) $@ $(DEL) $@
+	@echo Generating $@
+ifneq "$(strip $(FILES_lib_objs))" ""
+	@echo $(foreach objfile,$(FILES_lib_objs),$(subst /,\,$(objfile)) ) >> $@
+endif
+
+else # We must have more than one target library so load the individual makefiles
+
+$(OBJDIR)/%.lib: NWGNU% $(AP_WORK)\build\NWGNUhead.inc $(AP_WORK)\build\NWGNUtail.inc $(AP_WORK)\build\NWGNUenvironment.inc FORCE
+	@echo Calling $<
+	$(MAKE) -f $< $(MAKECMDGOALS) RELEASE=$(RELEASE)
+
+endif
+
+#
+# Rules to build nlms.
+#
+
+vpath libcpre.o $(NOVELLLIBC)\imports
+
+# If we only have one target NLM then build it
+ifeq "$(words $(strip $(TARGET_nlm)))" "1"
+
+$(TARGET_nlm) : $(FILES_nlm_objs) $(FILES_nlm_libs) $(OBJDIR)\$(NLM_NAME)_link.opt
+	@echo Linking $@
+	$(LINK) @$(OBJDIR)\$(NLM_NAME)_link.opt
+
+# This will force the link option file to be rebuilt if we change the
+# corresponding makefile
+
+$(OBJDIR)\$(NLM_NAME)_link.opt : $($(NLM_NAME)_LINKOPT_DEPENDS)
+	$(CHK) $(OBJDIR)\$(@F) $(DEL) $(OBJDIR)\$(@F)
+	$(CHK) $(OBJDIR)\$(NLM_NAME)_link.def $(DEL) $(OBJDIR)\$(NLM_NAME)_link.def
+	@echo Generating $@
+	@echo -warnings off >> $@
+	@echo -zerobss >> $@
+	@echo -desc "$(NLM_DESCRIPTION)" >> $@
+	@echo -o $(TARGET_nlm) >> $@
+ifneq "$(FILE_nlm_copyright)" ""
+	@-type $(FILE_nlm_copyright) >> $@
+else
+	@echo -copy "$(NLM_COPYRIGHT)" >> $@
+endif
+ifeq "$(RELEASE)" "debug"
+	@echo -g >> $@
+	@echo -sym internal >> $@
+	@echo -sym codeview4 >> $@
+	@echo -osym $(OBJDIR)\$(NLM_NAME).sym >> $@
+else
+	@echo -sym internal >> $@
+endif
+	@echo -screenname "$(NLM_SCREEN_NAME)" >> $@
+ifneq "$(NLM_VERSION)" ""
+	@echo -nlmversion=$(NLM_VERSION) >> $@
+else
+	@echo -nlmversion=$(VERSION) >> $@
+endif
+	@echo -l $(NWOS) >> $@
+	@echo -l $(AP)/$(OBJDIR) >> $@
+	@echo -l $(APR)/$(OBJDIR) >> $@
+	@echo -l $(APRUTIL)/$(OBJDIR) >> $@
+	@echo -l $(PCRE)/$(OBJDIR) >> $@
+	@echo -l $(HTTPD)/$(OBJDIR) >> $@
+	@echo -l $(SERVER)/$(OBJDIR) >> $@
+	@echo -l $(STDMOD)/$(OBJDIR) >> $@
+	@echo -l $(NWOS)/$(OBJDIR) >> $@
+	@echo -l "$(METROWERKS)/Novell Support/Metrowerks Support/Libraries/Runtime" >> $@
+	@echo -l "$(METROWERKS)/Novell Support/Metrowerks Support/Libraries/MSL C++" >> $@
+ifneq "$(IPV6)" ""
+	@echo -l $(NOVELLLIBC)\include\winsock\IPV6 >> $@
+endif
+	@echo -l $(NOVELLLIBC)/imports >> $@
+ifneq "$(LDAPSDK)" ""
+	@echo -l $(LDAPSDK)/lib/nlm >> $@
+endif
+	@echo -l $(APULDAP)/$(OBJDIR) >> $@
+	@echo -l $(XML)/$(OBJDIR) >> $@
+	@echo -nodefaults >> $@
+	@echo -map $(OBJDIR)\$(NLM_NAME).map>> $@
+	@echo -threadname "$(NLM_THREAD_NAME)" >> $@
+ifneq "$(NLM_STACK_SIZE)" ""
+	@echo -stacksize $(subst K,000,$(subst k,K,$(strip $(NLM_STACK_SIZE)))) >> $@
+else
+	@echo -stacksize 64000 >> $@
+endif
+ifneq "$(NLM_ENTRY_SYM)" ""
+	@echo -entry $(NLM_ENTRY_SYM) >> $@
+endif
+ifneq "$(NLM_EXIT_SYM)" ""
+	@echo -exit $(NLM_EXIT_SYM) >> $@
+endif
+ifneq "$(NLM_CHECK_SYM)" ""
+	@echo -check $(NLM_CHECK_SYM) >> $@
+endif
+ifneq "$(NLM_FLAGS)" ""
+	@echo -flags $(NLM_FLAGS) >> $@
+endif
+ifneq "$(strip $(XLFLAGS))" ""
+	@echo $(XLFLAGS) >> $@
+endif
+ifneq "$(strip $(FILES_nlm_objs))" ""
+	@echo $(foreach objfile,$(strip $(FILES_nlm_objs)),$(subst /,\,$(objfile))) >> $@
+endif
+ifneq "$(FILES_nlm_libs)" ""
+	@echo $(foreach libfile, $(notdir $(strip $(FILES_nlm_libs))),-l$(subst /,\,$(libfile))) >> $@
+endif
+	@echo -commandfile $(OBJDIR)\$(NLM_NAME)_link.def >> $@
+ifneq "$(FILE_nlm_msg)" ""
+	@echo Messages $(FILE_nlm_msg) >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+ifneq "$(FILE_nlm_hlp)" ""
+	@echo Help $(FILE_nlm_hlp) >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+ifneq "$(FILES_nlm_modules)" ""
+	@echo module $(foreach module,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_modules))),$(subst /,\,$(module))) >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+ifneq "$(FILES_nlm_Ximports)" ""
+	@echo Import $(foreach import,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_Ximports))),$(subst /,\,$(import))) >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+ifneq "$(FILES_nlm_exports)" ""
+	@echo Export $(foreach export,$(subst $(SPACE),$(COMMA),$(strip $(FILES_nlm_exports))),$(subst /,\,$(export))) >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+
+# if APACHE_UNIPROC is defined, don't include XDCData
+ifndef APACHE_UNIPROC
+ifneq "$(string $(XDCDATA))" ""
+	@echo XDCData $(XDCDATA) >> $(OBJDIR)\$(NLM_NAME)_link.def
+else
+	@echo XDCData $(NWOS)\apache.xdc >> $(OBJDIR)\$(NLM_NAME)_link.def
+endif
+endif
+
+else # more than one target so look for individual makefiles.
+
+# Only include these if NO_LICENSE_FILE isn't set to prevent excessive
+# recursion
+
+ifndef NO_LICENSE_FILE
+
+$(OBJDIR)/%.nlm: NWGNU% $(AP_WORK)\build\NWGNUhead.inc $(AP_WORK)\build\NWGNUtail.inc $(AP_WORK)\build\NWGNUenvironment.inc $(CUSTOM_INI) $(VERSION_INC) FORCE
+	@echo Calling $<
+	$(MAKE) -f $< $(MAKECMDGOALS) RELEASE=$(RELEASE)
+	$(CMD) echo.
+
+else
+
+$(TARGET_nlm):
+
+endif # NO_LICENSE_FILE
+
+endif
+
diff --git a/trunk/build/binbuild.sh b/trunk/build/binbuild.sh
new file mode 100755
index 0000000000..15ee27ea7a
--- /dev/null
+++ b/trunk/build/binbuild.sh
@@ -0,0 +1,206 @@
+#!/bin/sh
+# 	
+# Copyright 1999-2005 The Apache Software Foundation or its licensors, as
+# applicable.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# binbuild.sh - Builds an Apache binary distribution.
+# Initially written by Lars Eilebrecht <lars apache.org>.
+
+OS=`./build/config.guess`
+PRINTPATH="build/PrintPath"
+APFULLDIR=`pwd`
+BUILD_DIR="$APFULLDIR/bindist"
+DEFAULT_DIR="/usr/local/apache2"
+APDIR="$APFULLDIR"
+APDIR=`basename $APDIR`
+CONFIGPARAM="--enable-layout=Apache --prefix=$BUILD_DIR --enable-mods-shared=most --with-expat=$APFULLDIR/srclib/apr-util/xml/expat --enable-static-support"
+VER=`echo $APDIR | sed s/httpd-//`
+TAR="`$PRINTPATH tar`"
+GZIP="`$PRINTPATH gzip`"
+COMPRESS="`$PRINTPATH compress`"
+MD5="`$PRINTPATH md5`"
+if [ x$MD5 = x ]; then
+  OPENSSL="`$PRINTPATH openssl`"
+  if [ x$OPENSSL != x ]; then
+    MD5="$OPENSSL md5"
+  fi
+fi
+
+if [ x$1 != x ]; then
+  USER=$1
+else
+  USER="`build/buildinfo.sh -n %u@%h%d`"
+fi
+
+if [ ! -f ./ABOUT_APACHE ]; then
+  echo "ERROR: The current directory contains no valid Apache distribution."
+  echo "Please change the directory to the top level directory of a freshly"
+  echo "unpacked Apache 2.0 source distribution and re-execute the script"
+  echo "'./build/binbuild.sh'." 
+  exit 1;
+fi
+
+if [ -d ./CVS ]; then
+  echo "ERROR: The current directory is a CVS checkout of Apache."
+  echo "Only a standard Apache 2.0 source distribution should be used to"
+  echo "create a binary distribution."
+  exit 1;
+fi
+
+echo "Building Apache $VER binary distribution..."
+echo "Platform is \"$OS\"..."
+
+( echo "Build log for Apache binary distribution" && \
+  echo "----------------------------------------------------------------------" && \
+  ./configure $CONFIGPARAM && \
+  echo "----------------------------------------------------------------------" && \
+  make clean && \
+  rm -rf bindist install-bindist.sh *.bindist
+  echo "----------------------------------------------------------------------" && \
+  make && \
+  echo "----------------------------------------------------------------------" && \
+  make install root="bindist/" && \
+  echo "----------------------------------------------------------------------" && \
+  make clean && \
+  echo "----------------------------------------------------------------------" && \
+  echo "[EOF]" \
+) 2>&1 | tee build.log
+
+if [ ! -f ./bindist/bin/httpd ]; then
+  echo "ERROR: Failed to build Apache. See \"build.log\" for details."
+  exit 1;
+fi
+
+echo "Binary image successfully created..."
+
+./bindist/bin/httpd -v
+
+echo "Creating supplementary files..."
+
+( echo " " && \
+  echo "Apache $VER binary distribution" && \
+  echo "================================" && \
+  echo " " && \
+  echo "This binary distribution is usable on a \"$OS\"" && \
+  echo "system and was built by \"$USER\"." && \
+  echo "" && \
+  echo "The distribution contains all standard Apache modules as shared" && \
+  echo "objects. This allows you to enable or disable particular modules" && \
+  echo "with the LoadModule/AddModule directives in the configuration file" && \
+  echo "without the need to re-compile Apache." && \
+  echo "" && \
+  echo "See \"INSTALL.bindist\" on how to install the distribution." && \
+  echo " " && \
+  echo "NOTE: Please do not send support-related mails to the address mentioned" && \
+  echo "      above or to any member of the Apache Group! Support questions" && \
+  echo "      should be directed to the forums mentioned at" && \
+  echo "      http://httpd.apache.org/lists.html#http-users" && \
+  echo "      where some of the Apache team lurk, in the company of many other" && \
+  echo "      Apache gurus who should be able to help." && \
+  echo "      If you think you found a bug in Apache or have a suggestion please" && \
+  echo "      visit the bug report page at http://httpd.apache.org/bug_report.html" && \
+  echo " " && \
+  echo "----------------------------------------------------------------------" && \
+  ./bindist/bin/httpd -V && \
+  echo "----------------------------------------------------------------------" \
+) > README.bindist
+cp README.bindist ../httpd-$VER-$OS.README
+
+( echo " " && \
+  echo "Apache $VER binary installation" && \
+  echo "================================" && \
+  echo " " && \
+  echo "To install this binary distribution you have to execute the installation" && \
+  echo "script \"install-bindist.sh\" in the top-level directory of the distribution." && \
+  echo " " && \
+  echo "The script takes the ServerRoot directory into which you want to install" && \
+  echo "Apache as an option. If you omit the option the default path" && \
+  echo "\"$DEFAULT_DIR\" is used." && \
+  echo "Make sure you have write permissions in the target directory, e.g. switch" && \
+  echo "to user \"root\" before you execute the script." && \
+  echo " " && \
+  echo "See \"README.bindist\" for further details about this distribution." && \
+  echo " " && \
+  echo "Please note that this distribution includes the complete Apache source code." && \
+  echo "Therefore you may compile Apache yourself at any time if you have a compiler" && \
+  echo "installation on your system." && \
+  echo "See \"INSTALL\" for details on how to accomplish this." && \
+  echo " " \
+) > INSTALL.bindist
+
+sed -e "s%\@default_dir\@%$DEFAULT_DIR%" \
+    -e "s%\@ver\@%$VER%" \
+    -e "s%\@os\@%$OS%" \
+    build/install-bindist.sh.in > install-bindist.sh
+    
+chmod 755 install-bindist.sh
+
+sed -e "s%$BUILD_DIR%$DEFAULT_DIR%" \
+    -e "s%^ServerAdmin.*%ServerAdmin you@your.address%" \
+    -e "s%#ServerName.*%#ServerName localhost%" \
+    bindist/conf/httpd-std.conf > bindist/conf/httpd.conf
+cp bindist/conf/httpd.conf bindist/conf/httpd-std.conf
+
+for one_file in apachectl envvars envvars-std; do
+    sed -e "s%$BUILD_DIR%$DEFAULT_DIR%" \
+        bindist/bin/$one_file > bindist/bin/$one_file.tmp
+    mv bindist/bin/$one_file.tmp bindist/bin/$one_file
+done
+
+echo "Creating distribution archive and readme file..."
+ 
+if [ ".`grep -i error build.log > /dev/null`" != . ]; then
+  echo "ERROR: Failed to build Apache. See \"build.log\" for details."
+  exit 1;
+else
+  if [ "x$TAR" != "x" ]; then
+    case "x$OS" in
+      x*os390*) $TAR -cfU ../httpd-$VER-$OS.tar -C .. httpd-$VER;;
+      *) (cd .. && $TAR -cf httpd-$VER-$OS.tar httpd-$VER);;
+    esac
+    if [ "x$GZIP" != "x" ]; then
+      $GZIP -9 ../httpd-$VER-$OS.tar
+      ARCHIVE=../httpd-$VER-$OS.tar.gz
+    elif [ "x$COMPRESS" != "x" ]; then
+      $COMPRESS ../httpd-$VER-$OS.tar
+      ARCHIVE=../httpd-$VER-$OS.tar.Z
+    else
+      echo "WARNING: Could not find a 'gzip' program!"
+      echo "       tar archive is not compressed."
+      ARCHIVE=../httpd-$VER-$OS.tar
+    fi
+  else
+    echo "ERROR: Could not find a 'tar' program!"
+    echo "       Please execute the following commands manually:"
+    echo "         tar -cf ../httpd-$VER-$OS.tar ."
+    echo "         gzip -9 ../httpd-$VER-$OS.tar"
+  fi
+
+  if [ "x$MD5" != "x" ]; then
+    $MD5 $ARCHIVE > $ARCHIVE.md5
+  fi
+
+  if [ -f $ARCHIVE ] && [ -f ../httpd-$VER-$OS.README ]; then
+    echo "Ready."
+    echo "You can find the binary archive ($ARCHIVE)"
+    echo "and the readme file (httpd-$VER-$OS.README) in the"
+    echo "parent directory."
+    exit 0;
+  else
+    echo "ERROR: Archive or README is missing."
+    exit 1;
+  fi
+fi
diff --git a/trunk/build/bsd_makefile b/trunk/build/bsd_makefile
new file mode 100755
index 0000000000..c3b8131101
--- /dev/null
+++ b/trunk/build/bsd_makefile
@@ -0,0 +1,33 @@
+#! /bin/sh
+#
+# Copyright 2000-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# The build environment was provided by Sascha Schumann.
+
+# cwd must be top_srcdir
+test -f build/bsd_makefile || exit 2
+
+test -f bsd_converted && exit 0
+
+tmpfile=`mktemp /tmp/bsd_makefile.XXXXXX 2>/dev/null` || tmpfile="tmp.$$"
+for i in build/*.mk; do
+    sed 's/^include \(.*\)/.include "\1"/' $i >$tmpfile \
+        && cp $tmpfile $i
+done
+rm -f $tmpfile
+
+touch bsd_converted
+exit 0
diff --git a/trunk/build/build-modules-c.awk b/trunk/build/build-modules-c.awk
new file mode 100644
index 0000000000..fda31c2860
--- /dev/null
+++ b/trunk/build/build-modules-c.awk
@@ -0,0 +1,81 @@
+# Copyright 1999-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+BEGIN {
+    RS = " "
+    modules[n++] = "core"
+    pmodules[pn++] = "core"
+} 
+{
+    modules[n] = $1;
+    pmodules[pn] = $1;
+    gsub("\n","",modules[n]);
+    gsub("\n","",pmodules[pn]);
+    ++n;
+    ++pn;
+} 
+END {
+    print "/*"
+    print " * modules.c --- automatically generated by Apache"
+    print " * configuration script.  DO NOT HAND EDIT!!!!!"
+    print " */"
+    print ""
+    print "#include \"ap_config.h\""
+    print "#include \"httpd.h\""
+    print "#define CORE_PRIVATE"
+    print "#include \"http_config.h\""
+    print ""
+    for (i = 0; i < pn; ++i) {
+        printf ("extern module %s_module;\n", pmodules[i])
+    }
+    print ""
+    print "/*"
+    print " *  Modules which implicitly form the"
+    print " *  list of activated modules on startup,"
+    print " *  i.e. these are the modules which are"
+    print " *  initially linked into the Apache processing"
+    print " *  [extendable under run-time via AddModule]"
+    print " */"
+    print "module *ap_prelinked_modules[] = {"
+    for (i = 0 ; i < n; ++i) {
+        printf "  &%s_module,\n", modules[i]
+    }
+    print "  NULL"
+    print "};"
+    print ""
+    print "/*"
+    print " *  We need the symbols as strings for <IfModule> containers"
+    print " */"
+    print ""
+    print "ap_module_symbol_t ap_prelinked_module_symbols[] = {"
+    for (i = 0; i < n; ++i) {
+        printf ("  {\"%s_module\", &%s_module},\n", modules[i], modules[i])
+    }
+    print "  {NULL, NULL}"
+    print "};"
+    print ""
+    print "/*"
+    print " *  Modules which initially form the"
+    print " *  list of available modules on startup,"
+    print " *  i.e. these are the modules which are"
+    print " *  initially loaded into the Apache process"
+    print " *  [extendable under run-time via LoadModule]"
+    print " */"
+    print "module *ap_preloaded_modules[] = {"
+    for (i = 0; i < pn; ++i) {
+        printf "  &%s_module,\n", pmodules[i]
+    }
+    print "  NULL"
+    print "};"
+    print ""
+}
diff --git a/trunk/build/buildinfo.sh b/trunk/build/buildinfo.sh
new file mode 100755
index 0000000000..6de75fa476
--- /dev/null
+++ b/trunk/build/buildinfo.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+#
+# Copyright 2000-2005 The Apache Software Foundation or its licensors, as
+# applicable.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# buildinfo.sh -- Determine Build Information
+# Initially written by Ralf S. Engelschall <rse@apache.org>
+# for the Apache's Autoconf-style Interface (APACI) 
+
+#
+#   argument line handling
+#
+error=no
+if [ $# -ne 1 -a $# -ne 2 ]; then
+    error=yes
+fi
+if [ $# -eq 2 -a "x$1" != "x-n" ]; then
+    error=yes
+fi
+if [ "x$error" = "xyes" ]; then
+    echo "$0:Error: invalid argument line"
+    echo "$0:Usage: $0 [-n] <format-string>"
+    echo "Where <format-string> can contain:"
+    echo "   %u ...... substituted by determined username    (foo)"
+    echo "   %h ...... substituted by determined hostname    (bar)"
+    echo "   %d ...... substituted by determined domainname  (.com)"
+    echo "   %D ...... substituted by determined day         (DD)"
+    echo "   %M ...... substituted by determined month       (MM)"
+    echo "   %Y ...... substituted by determined year        (YYYYY)"
+    echo "   %m ...... substituted by determined monthname   (Jan)"
+    exit 1
+fi
+if [ $# -eq 2 ]; then
+    newline=no
+    format_string="$2"
+else
+    newline=yes
+    format_string="$1"
+fi
+
+#
+#   initialization
+#
+username=''
+hostname=''
+domainname=''
+time_day=''
+time_month=''
+time_year=''
+time_monthname=''
+
+#
+#   determine username
+#
+username="$LOGNAME"
+if [ "x$username" = "x" ]; then
+    username="$USER"
+    if [ "x$username" = "x" ]; then
+        username="`(whoami) 2>/dev/null |\
+                   awk '{ printf("%s", $1); }'`"
+        if [ "x$username" = "x" ]; then
+            username="`(who am i) 2>/dev/null |\
+                       awk '{ printf("%s", $1); }'`"
+            if [ "x$username" = "x" ]; then
+                username='unknown'
+            fi
+        fi
+    fi
+fi
+
+#
+#   determine hostname and domainname
+#
+hostname="`(uname -n) 2>/dev/null |\
+           awk '{ printf("%s", $1); }'`"
+if [ "x$hostname" = "x" ]; then
+    hostname="`(hostname) 2>/dev/null |\
+               awk '{ printf("%s", $1); }'`"
+    if [ "x$hostname" = "x" ]; then
+        hostname='unknown'
+    fi
+fi
+case $hostname in
+    *.* )
+        domainname=".`echo $hostname | cut -d. -f2-`"
+        hostname="`echo $hostname | cut -d. -f1`"
+        ;;
+esac
+if [ "x$domainname" = "x" ]; then
+    if [ -f /etc/resolv.conf ]; then
+        domainname="`egrep '^[ 	]*domain' /etc/resolv.conf | head -1 |\
+                     sed -e 's/.*domain//' \
+                         -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                         -e 's/^\.//' -e 's/^/./' |\
+                     awk '{ printf("%s", $1); }'`"
+        if [ "x$domainname" = "x" ]; then
+            domainname="`egrep '^[ 	]*search' /etc/resolv.conf | head -1 |\
+                         sed -e 's/.*search//' \
+                             -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                             -e 's/ .*//' -e 's/	.*//' \
+                             -e 's/^\.//' -e 's/^/./' |\
+                         awk '{ printf("%s", $1); }'`"
+        fi
+    fi
+fi
+
+#
+#   determine current time
+#
+time_day="`date '+%d' | awk '{ printf("%s", $1); }'`"
+time_month="`date '+%m' | awk '{ printf("%s", $1); }'`"
+time_year="`date '+%Y' 2>/dev/null | awk '{ printf("%s", $1); }'`"
+if [ "x$time_year" = "x" ]; then
+    time_year="`date '+%y' | awk '{ printf("%s", $1); }'`"
+    case $time_year in
+        [5-9][0-9]) time_year="19$time_year" ;;
+        [0-4][0-9]) time_year="20$time_year" ;;
+    esac
+fi
+case $time_month in
+    1|01) time_monthname='Jan' ;;
+    2|02) time_monthname='Feb' ;;
+    3|03) time_monthname='Mar' ;;
+    4|04) time_monthname='Apr' ;;
+    5|05) time_monthname='May' ;;
+    6|06) time_monthname='Jun' ;;
+    7|07) time_monthname='Jul' ;;
+    8|08) time_monthname='Aug' ;;
+    9|09) time_monthname='Sep' ;;
+      10) time_monthname='Oct' ;;
+      11) time_monthname='Nov' ;;
+      12) time_monthname='Dec' ;;
+esac
+
+#
+#   create result string
+#
+if [ "x$newline" = "xyes" ]; then
+    echo $format_string |\
+    sed -e "s;%u;$username;g" \
+        -e "s;%h;$hostname;g" \
+        -e "s;%d;$domainname;g" \
+        -e "s;%D;$time_day;g" \
+        -e "s;%M;$time_month;g" \
+        -e "s;%Y;$time_year;g" \
+        -e "s;%m;$time_monthname;g"
+else
+    echo "${format_string}&" |\
+    sed -e "s;%u;$username;g" \
+        -e "s;%h;$hostname;g" \
+        -e "s;%d;$domainname;g" \
+        -e "s;%D;$time_day;g" \
+        -e "s;%M;$time_month;g" \
+        -e "s;%Y;$time_year;g" \
+        -e "s;%m;$time_monthname;g" |\
+    awk '-F&' '{ printf("%s", $1); }'
+fi
+
diff --git a/trunk/build/config-stubs b/trunk/build/config-stubs
new file mode 100755
index 0000000000..425dc80268
--- /dev/null
+++ b/trunk/build/config-stubs
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+#
+# Find all config files (config*.m4) and map them into lines with the
+# form: NUM? '0' ' ' PATH
+#
+# For example:
+#
+#  50 ./modules/generators/config5.m4
+#  0 ./modules/aaa/config.m4
+#  10 ./example/config1.m4
+#
+# These lines are sorted, then the first field is removed. Thus, we
+# have a set of paths sorted on the config-number (if present). All
+# config files without a number are sorted before those with a number.
+#
+
+configfiles=`find . -name "config*.m4" | \
+	sed 's#\(.*/config\)\(.*\).m4#\20 \1\2.m4#' | \
+	sort | \
+	sed 's#.* ##'`
+
+for configfile in $configfiles; do
+    if [ -r $configfile ]; then
+        echo "sinclude($configfile)"
+    fi
+done
diff --git a/trunk/build/default.pl b/trunk/build/default.pl
new file mode 100644
index 0000000000..4a73b77821
--- /dev/null
+++ b/trunk/build/default.pl
@@ -0,0 +1,496 @@
+<<
+# Scandoc template file.
+#
+# This is an example set of templates that is designed to create several 
+# different kinds of index files. It generates a "master index" which intended 
+# for use with a frames browser; A "package index" which is the root page of 
+# the index, and then "package files" containing documentation for all of the 
+# classes within a single package.
+
+######################################################################
+
+## For quick and superficial customization, 
+## simply change these variables
+
+$project_name     = '[Apache]';
+$company_logo     = '<img src="../images/ScanDocBig.jpg">'; # change this to an image tag.
+$copyright        = '© 2000 [Apache Software Foundation]';
+$image_directory  = "../images/";
+$bullet1_image    = $image_directory . "ball1.gif";
+$bullet2_image    = $image_directory . "ball2.gif";
+$bgcolor1         = "#FFFFFF";
+$bgcolor2         = "#FFFFFF";
+
+######################################################################
+
+## Begin generating frame index file.
+
+file "index.html";
+>><html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; iso-8859-1">
+    <title>$project_name
+  
+  
+    
+    
+    
+      <body bgcolor="$bgcolor2" stylesrc="index.html">
+        <p>Some Documentation</p>
+      </body>
+    
+  
+
+<<
+
+######################################################################
+
+## Begin generating master index file (left-hand frame).
+
+file "master.html";
+>>
+  
+    Master Index
+  
+  
+    
+

+ Master Index +

+

+ + +<< + +## For each package, generate an index entry. + +foreach $p (packages()) { + $_ = $p->url; + s/\s/%20/g; + >>$(p.name)
+

+ << + foreach $e ($p->classes()) { + $_ = $e->url; + s/\s/%20/g; + >>
  • $(e.fullname) + << + } + foreach $e ($p->globals()) { + $_ = $e->url; + s/\s/%20/g; + >>
  • $(e.fullname) + << + } + >>
  • << +} + +>> + To-Do List
    +
    +
    +

    + + +<< + +###################################################################### + +## Begin generating package index file + +file "packages.html"; +>> + + $project_name -- Packages + + + +
    $company_logo +

    Documentation for $project_name

    +
    +

    Package List

    +<< + +## For each package, generate an index entry. + +foreach $p (packages()) { + $_ = $p->url; + s/\s/%20/g; + >>$(p.name)
    + << +} + +>> +

    +


    + $copyright
    + Generated by ScanDoc $majorVersion.$minorVersion
    + Last Updated: $date
    + + + +<< + +###################################################################### + +## Generate "To-do list" + +file "to-do.html"; +>> + + $project_name -- To-Do list + + + + $company_logo + +

    To-do list for $project_name

    +<< + +if (&todolistFiles()) { + >>

    + << + foreach $f (&todolistFiles()) { + my @m = &todolistEntries( $f ); + if ($f =~ /([^\/]+)$/) { $f = $1; } + >>$f:

      + << + foreach $text (@m) { + if ($text) { + print "
    • ", &processDescription( $text ), "\n"; + } + } + >>
    + << + } +} + +>> +
    + $copyright
    + Generated by ScanDoc $majorVersion.$minorVersion
    + Last Updated: $date
    + + +<< + +###################################################################### + +## Generate individual files for each package. + +my $p; +foreach $p (packages()) { + file $p->name() . ".html"; + >> + + $project_name -- $(p.name) + + +
    + $project_name +

    +

    + +

    Package Name: $(p.name)

    + +<< + +## Generate class and member index at the top of the file. + +foreach $c ($p->classes()) { + >>

    + $(c.fullname)

    +
      + << + foreach $m ($c->members()) { + >>
    • $(m.longname) + << + } + >>
    + << +} + +>> +
    +<< + +## Generate detailed class documentation +foreach $c ($p->classes()) { + ## Output searchable keyword list + if ($c->keywords()) { + print "\n"; + } + + >>
    + +

    $(c.fullname)

    + + + + + << + + # Output author tag + if ($c->author()) { + >><< + >><< + } + + # Output package version + if ($c->version()) { + >><< + >><< + } + + # Output Source file + if ($c->sourcefile()) { + >><< + >><< + } + + # Output base class list + if ($c->baseclasses()) { + >> + + << + } + + # Output subclasses list + if ($c->subclasses()) { + >> + << + } + + # Output main class description + >> +
    +
    Author:$(c.author)
    Version:$(c.version)
    Source:$(c.sourcefile)
    Base classes:<< + my @t = (); + foreach $b ($c->baseclasses()) { + my $name = $b->name(); + if ($url = $b->url()) { + push @t, "$name"; + } + else { push @t, $name; } + } + print join( ', ', @t ); + >>
    Subclasses:<< + my @t = (); + foreach $s ($c->subclasses()) { + my $name = $s->name(); + if ($url = $s->url()) { + push @t, "$name"; + } + else { push @t, $name; } + } + print join( ', ', @t ); + >>
    +

    + << + print &processDescription( $c->description() ); + + # Output "see also" information + if ($c->seealso()) { + >>

    See Also
    + << + my @r = (); + foreach $a ($c->seealso()) { + my $name = $a->name(); + if ($url = $a->url()) { + push @r, "$name"; + } + else { push @r, $name; } + } + print join( ',', @r ); + >>

    + << + } + + # Output class member index + if ($c->members()) { + print "

    Member Index

    \n"; + print "
      "; + foreach $m ($c->members()) { + >>
    • $(m.fullname) + << + } + >>
    << + } + + # Output class member variable documentation + if ($c->membervars()) { + print "

    Class Variables

    \n"; + print "
    \n"; + foreach $m ($c->membervars()) { &variable( $m ); } + print "
    \n"; + } + + # Output class member function documentation + if ($c->memberfuncs()) { + print "

    Class Methods

    \n"; + print "
    \n"; + foreach $m ($c->memberfuncs()) { &function( $m ); } + print "
    \n"; + } +} + +# Output global variables +if ($p->globalvars()) { + >>

    Global Variables

    +
    + << + foreach $m ($p->globalvars()) { &variable( $m ); } + print "
    \n"; +} + +# Output global functions +if ($p->globalfuncs()) { + >>

    Global Functions

    +
    + << + foreach $m ($p->globalfuncs()) { &function( $m ); } + print "
    \n"; +} + +>> +
    + $copyright
    + Generated by ScanDoc $majorVersion.$minorVersion
    + Last Updated: $date
    + + +<< +} # end of foreach (packages) loop + +###################################################################### + +## Subroutine to generate documentation for a member function or global function + +sub function { + local ($f) = @_; + + if ($f->keywords()) { + >> + << + } + >> + +
    +
    + $(f.fullname); +
    + << + print &processDescription( $f->description() ); + >> +

    + << + if ($f->params()) { + >> +
    Parameters
    + + << + foreach $a ($f->params()) { + >> + << + } + >>
    + $(a.name)<< + print &processDescription( $a->description() ); + >>
    + << + } + + if ($f->returnValue()) { + >>
    Return Value +
    << + print &processDescription( $f->returnValue() ); + >>

    << + } + + if ($f->exceptions()) { + >>

    Exceptions
    + + << + foreach $a ($f->exceptions()) { + >> + << + } + >>

    + $(a.name)<< + print &processDescription( $a->description() ); + >>

    + << + } + + if ($f->seealso()) { + >>
    See Also
    + << + my @r = (); + foreach $a ($f->seealso()) { + my $name = $a->name(); + if ($url = $a->url()) { + push @r, "$name"; + } + else { push @r, $name; } + } + print join( ',', @r ); + >>

    << + } + >>

    + << +} + +###################################################################### + +## Subroutine to generate documentation for a member variable or global variable. + +sub variable { + local ($v) = @_; + + if ($v->keywords()) { + print ""; + } + + >> + +
    + $(v.fullname); +
    + <description() );>> +

    + << + if ($v->seealso()) { + >>
    See Also
    + << + $comma = 0; + foreach $a ($v->seealso()) { + if ($comma) { print ","; } + $comma = 1; + >>$(a.name) + << + } + >>

    + << + } + >>

    + << +} + +###################################################################### + +sub processDescription { + local ($_) = @_; + + s/^\s+//; # Remove whitespace from beginning + s/\s+$/\n/; # Remove whitespace from end + s/\n\n/

    \n/g; # Replace multiple CR's with paragraph markers + s:\@heading(.*)\n:

    $1

    :; # Handle heading text + + # Handle embedded image tags + s:\@caution:

    :; + s:\@warning:

    :; + s:\@bug:

    :; + s:\@tip:

    :; + + return $_; +} diff --git a/trunk/build/fastgen.sh b/trunk/build/fastgen.sh new file mode 100755 index 0000000000..28c6e57b2e --- /dev/null +++ b/trunk/build/fastgen.sh @@ -0,0 +1,89 @@ +#! /bin/sh +# +# Copyright 2000-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +srcdir=$1 +shift + +mkdir_p=$1 +shift + +bsd_makefile=$1 +shift + +top_srcdir=`(cd $srcdir; pwd)` +top_builddir=`pwd` + +if test "$mkdir_p" = "yes"; then + mkdir_p="mkdir -p" +else + mkdir_p="$top_srcdir/build/mkdir.sh" +fi + +if test "$bsd_makefile" = "yes"; then + (cd $top_srcdir; ./build/bsd_makefile) + + for makefile in $@; do + echo "creating $makefile" + dir=`echo $makefile|sed 's%/*[^/][^/]*$%%'` + + if test -z "$dir"; then + real_srcdir=$top_srcdir + real_builddir=$top_builddir + dir="." + else + $mkdir_p "$dir/" + real_srcdir=$top_srcdir/$dir + real_builddir=$top_builddir/$dir + fi + cat - $top_srcdir/$makefile.in <$makefile +top_srcdir = $top_srcdir +top_builddir = $top_builddir +srcdir = $real_srcdir +builddir = $real_builddir +VPATH = $real_srcdir +EOF + + touch $dir/.deps + done +else + for makefile in $@; do + echo "creating $makefile" + dir=`echo $makefile|sed 's%/*[^/][^/]*$%%'` + + if test -z "$dir"; then + real_srcdir=$top_srcdir + real_builddir=$top_builddir + dir="." + else + $mkdir_p "$dir/" + real_srcdir=$top_srcdir/$dir + real_builddir=$top_builddir/$dir + fi + cat - $top_srcdir/$makefile.in <$makefile +top_srcdir = $top_srcdir +top_builddir = $top_builddir +srcdir = $real_srcdir +builddir = $real_builddir +VPATH = $real_srcdir +EOF + + touch $dir/.deps + done +fi diff --git a/trunk/build/get-version.sh b/trunk/build/get-version.sh new file mode 100755 index 0000000000..e3ba69c513 --- /dev/null +++ b/trunk/build/get-version.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# +# Copyright 2003-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# extract version numbers from a header file +# +# USAGE: get-version.sh CMD VERSION_HEADER PREFIX +# where CMD is one of: all, major, libtool +# where PREFIX is the prefix to {MAJOR|MINOR|PATCH}_VERSION defines +# +# get-version.sh all returns a dotted version number +# get-version.sh major returns just the major version number +# get-version.sh libtool returns a version "libtool -version-info" format +# + +if test $# != 3; then + echo "USAGE: $0 CMD INCLUDEDIR PREFIX" + echo " where CMD is one of: all, major" + exit 1 +fi + +major_sed="/#define.*$3_MAJORVERSION/s/^.*\([0-9][0-9]*\).*$/\1/p" +minor_sed="/#define.*$3_MINORVERSION/s/^.*\([0-9][0-9]*\).*$/\1/p" +patch_sed="/#define.*$3_PATCHLEVEL/s/^[^0-9]*\([0-9][0-9a-z-]*\).*$/\1/p" +mmn_sed="/#define.*$3_MAJOR/s/^[^0-9]*\([0-9][0-9]*\).*$/\1/p" +major="`sed -n $major_sed $2`" +minor="`sed -n $minor_sed $2`" +patch="`sed -n $patch_sed $2`" +mmn="`sed -n $mmn_sed $2`" + +if test "$1" = "all"; then + echo ${major}.${minor}.${patch} +elif test "$1" = "major"; then + echo ${major} +elif test "$1" = "mmn"; then + echo ${mmn} +elif test "$1" = "libtool"; then + # Yes, ${minor}:${patch}:${minor} is correct due to libtool idiocy. + echo ${minor}:${patch}:${minor} +else + echo "ERROR: unknown version CMD ($1)" + exit 1 +fi diff --git a/trunk/build/httpd_roll_release b/trunk/build/httpd_roll_release new file mode 100755 index 0000000000..67c3443c76 --- /dev/null +++ b/trunk/build/httpd_roll_release @@ -0,0 +1,136 @@ +#!/bin/sh +# +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export CVSROOT=cvs.apache.org:/home/cvs + +if [ "x$1" = "xhelp" -o "x$2" = "x" ]; then + echo "Usage: ./httpd_roll_release tag log_name [user]" + echo "tag the tag to use when checking out the repository" + echo "log_name the name of a file to log the results to." + echo "user An optional user name to use when siging the release" + exit +else + TAG=$1 +fi + +LOG_NAME=`pwd`/$2 + +USER=$3 + +REPO="httpd-2.0" +WORKING_DIR=`echo "$REPO" | sed -e 's/[\-\.]/./g'` +WORKING_TAG=`echo "$TAG" | sed -e 's/APACHE_2_1_/./'` +WORKING_DIR="$WORKING_DIR$WORKING_TAG" + +START_DIR=`echo "$PWD"` + +# Check out the correct repositories. +echo "Checking out repository $REPO into $WORKING_DIR using tag $TAG" + +umask 022 +echo Checking out httpd-2.0 > $LOG_NAME +cvs checkout -r $TAG -d $WORKING_DIR $REPO >> $LOG_NAME +cd $WORKING_DIR/srclib +echo "Checking out apr, and apr-util" >> $LOG_NAME +cvs checkout -r $TAG apr apr-util >> $LOG_NAME +cd $START_DIR/$WORKING_DIR + +# Make sure the master site's FAQ is up-to-date. It doesn't hurt to do this +# all the time. :-) +echo "REMEMBER TO UPDATE THE SITE'S FAQ!!" +#(cd /www/httpd.apache.org/docs-2.1/faq/; cvs update) + +# Now update the FAQ in the tarball via a download from the master site. +# The FAQ contains SSI tags too complex for the expand.pl script to handle. +rm -f docs/manual/faq/*.html +links -source http://httpd.apache.org/docs-2.1/faq/index.html?ONEPAGE \ + > docs/manual/faq/index.html + +# Create the configure scripts +echo "Creating the configure script" +cd $START_DIR/$WORKING_DIR + +echo >> $LOG_NAME +echo "Running ./buildconf" >> $LOG_NAME +./buildconf >> $LOG_NAME + +echo >> $LOG_NAME +echo "Fixup the timestamps preventing remake of generated files." >> $LOG_NAME +touch modules/ssl/ssl_expr_parse.c >> $LOG_NAME +touch modules/ssl/ssl_expr_parse.h >> $LOG_NAME +touch modules/ssl/ssl_expr_scan.c >> $LOG_NAME + +# Remove any files we don't distribute with our code +rm -f STATUS + +echo >> $LOG_NAME +echo "Removing files that we don't distribute" +echo "Removing files that we don't distribute" >> $LOG_NAME +find . -name ".cvsignore" -exec rm {} \; >> $LOG_NAME +find . -type d -name "CVS" | xargs rm -rf >> $LOG_NAME +find . -type d -name "autom4te.cache" | xargs rm -rf >> $LOG_NAME + +# expand SSI directives in the manual +echo "Making sure people can read the manual (expanding SSI's)" + +echo >> $LOG_NAME +echo "Making sure people can read the manual (expanding SSI's)" >> $LOG_NAME +( cd docs/manual ; chmod +x expand.pl ; ./expand.pl ; rm ./expand.pl ) >> $LOG_NAME + +# Time to roll the tarball +echo "Rolling the tarballs" + +cd $START_DIR +echo >> $LOG_NAME +echo "Rolling the tarball" >> $LOG_NAME +tar cvf $WORKING_DIR-alpha.tar $WORKING_DIR >> $LOG_NAME +cp -p $WORKING_DIR-alpha.tar x$WORKING_DIR-alpha.tar +gzip -9 $WORKING_DIR-alpha.tar +mv x$WORKING_DIR-alpha.tar httpd.tar +compress httpd.tar +mv httpd.tar.Z $WORKING_DIR-alpha.tar.Z + +# Test the tarballs +echo "Testing the tarball" + +echo >> $LOG_NAME +echo "Testing the tarball $WORKING_DIR-alpha.tar.gz" >> $LOG_NAME +gunzip -c $WORKING_DIR-alpha.tar.gz | tar tvf - >> $LOG_NAME +zcat $WORKING_DIR-alpha.tar.Z | tar tvf - >> $LOG_NAME + +# remember the CHANGES file +echo "Copying the CHANGES file to this directory" +cp $WORKING_DIR/CHANGES . + +# cleanup +echo "Cleaning up my workspace" +rm -fr $WORKING_DIR + +if [ "x$USER" != "x" ]; then + USER="-u $USER" +fi + +echo Signing the tarballs + +echo "Signing the tarballs" >> $LOG_NAME +pgp -sba $WORKING_DIR-alpha.tar.gz $USER +pgp -sba $WORKING_DIR-alpha.tar.Z $USER + +pgp $WORKING_DIR-alpha.tar.gz.asc $WORKING_DIR-alpha.tar.gz >> $LOG_NAME +pgp $WORKING_DIR-alpha.tar.Z.asc $WORKING_DIR-alpha.tar.Z >> $LOG_NAME + +echo "Don't forget to make the tarballs available by copying them to the" +echo "/www/httpd.apache.org/dev/dist directory." diff --git a/trunk/build/install-bindist.sh.in b/trunk/build/install-bindist.sh.in new file mode 100755 index 0000000000..ca6860417d --- /dev/null +++ b/trunk/build/install-bindist.sh.in @@ -0,0 +1,176 @@ +#!/bin/sh +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Usage: install-bindist.sh [ServerRoot] +# This script installs the Apache binary distribution and +# was automatically created by binbuild.sh. + +lmkdir() +{ + path="" + dirs=`echo $1 | sed -e 's%/% %g'` + mode=$2 + + set -- ${dirs} + + for d in ${dirs} + do + path="${path}/$d" + if test ! -d "${path}" ; then + mkdir ${path} + if test $? -ne 0 ; then + echo "Failed to create directory: ${path}" + exit 1 + fi + chmod ${mode} ${path} + fi + done +} + +lcopy() +{ + from=$1 + to=$2 + dmode=$3 + fmode=$4 + + test -d ${to} || lmkdir ${to} ${dmode} + (cd ${from} && tar -cf - *) | (cd ${to} && tar -xf -) + + if test "X${fmode}" != X ; then + find ${to} -type f -print | xargs chmod ${fmode} + fi + if test "X${dmode}" != X ; then + find ${to} -type d -print | xargs chmod ${dmode} + fi +} + +## +## determine path to (optional) Perl interpreter +## +PERL=no-perl5-on-this-system +perls='perl5 perl' +path=`echo $PATH | sed -e 's/:/ /g'` +found_perl=0 + +for dir in ${path} ; do + for pperl in ${perls} ; do + if test -f "${dir}/${pperl}" ; then + if `${dir}/${pperl} -v >/dev/null 2>&1` ; then + PERL="${dir}/${pperl}" + found_perl=1 + break + fi + fi + done + if test $found_perl = 1 ; then + break + fi +done + +if [ .$1 = . ] +then + SR=@default_dir@ +else + SR=$1 +fi +echo "Installing binary distribution for platform @os@" +echo "into directory $SR ..." +lmkdir $SR 755 +lmkdir $SR/proxy 750 +lmkdir $SR/logs 755 +lmkdir $SR/build 755 +lcopy bindist/build $SR/build 750 750 +lcopy bindist/man $SR/man 755 644 +if [ -d bindist/modules ] +then + lcopy bindist/modules $SR/modules 750 750 +fi +lcopy bindist/include $SR/include 755 644 +lcopy bindist/icons $SR/icons 755 644 +lcopy bindist/manual $SR/manual 755 644 +lcopy bindist/cgi-bin $SR/cgi-bin 750 750 +if [ -f $SR/bin/envvars ] +then + echo "[Preserving existing envvars settings.]" + cp -p $SR/bin/envvars ./envvars.orig + HAD_ENVVARS=yes +else + HAD_ENVVARS=no +fi +lcopy bindist/bin $SR/bin 750 750 +if [ $HAD_ENVVARS = yes ] +then + cp -p ./envvars.orig $SR/bin/envvars + rm ./envvars.orig +fi +lcopy bindist/lib $SR/lib 750 750 +if [ -d $SR/conf ] +then + echo "[Preserving existing configuration files.]" + cp bindist/conf/*-std.conf $SR/conf/ +else + lcopy bindist/conf $SR/conf 750 640 + sed -e "s%@default_dir@%$SR%" $SR/conf/httpd-std.conf > $SR/conf/httpd.conf +fi +if [ -d $SR/htdocs ] +then + echo "[Preserving existing htdocs directory.]" +else + lcopy bindist/htdocs $SR/htdocs 755 644 +fi +if [ -d $SR/error ] +then + echo "[Preserving existing error documents directory.]" +else + lcopy bindist/error $SR/error 755 644 +fi + +sed -e "s;^#!\@perlbin\@.*;#!$PERL;" -e "s;\@exp_installbuilddir\@;$SR/build;" \ + support/apxs.in > $SR/bin/apxs +PRE=`grep "^prefix = " bindist/build/config_vars.mk` +PRE=`echo $PRE | sed -e "s;prefix = ;;"` +sed -e "s;$PRE;$SR;" bindist/build/config_vars.mk > $SR/build/config_vars.mk +sed -e "s;^#!/.*;#!$PERL;" bindist/bin/dbmmanage > $SR/bin/dbmmanage +sed -e "s%@default_dir@%$SR%" \ + -e "s%^HTTPD=.*$%HTTPD=\"$SR/bin/httpd -d $SR\"%" bindist/bin/apachectl > $SR/bin/apachectl +sed -e "s%@default_dir@%$SR%" \ + bindist/bin/envvars-std > $SR/bin/envvars-std +if [ $HAD_ENVVARS = no ] +then + cp -p $SR/bin/envvars-std $SR/bin/envvars +fi + +echo "Ready." +echo " +--------------------------------------------------------+" +echo " | You now have successfully installed the Apache @ver@ |" +echo " | HTTP server. To verify that Apache actually works |" +echo " | correctly you should first check the (initially |" +echo " | created or preserved) configuration files: |" +echo " | |" +echo " | $SR/conf/httpd.conf" +echo " | |" +echo " | You should then be able to immediately fire up |" +echo " | Apache the first time by running: |" +echo " | |" +echo " | $SR/bin/apachectl start " +echo " | |" +echo " | Thanks for using Apache. The Apache Group |" +echo " | http://www.apache.org/ |" +echo " +--------------------------------------------------------+" +echo " " diff --git a/trunk/build/install.sh b/trunk/build/install.sh new file mode 100755 index 0000000000..6195768bd6 --- /dev/null +++ b/trunk/build/install.sh @@ -0,0 +1,123 @@ +#!/bin/sh +# +# Copyright 1999-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# install.sh -- install a program, script or datafile +# +# Based on `install-sh' from the X Consortium's X11R5 distribution +# as of 89/12/18 which is freely available. +# Cleaned up for Apache's Autoconf-style Interface (APACI) +# by Ralf S. Engelschall + +# +# put in absolute paths if you don't have them in your path; +# or use env. vars. +# +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +# +# parse argument line +# +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +ext="" +src="" +dst="" +while [ "x$1" != "x" ]; do + case $1 in + -c) instcmd="$cpprog" + shift; continue + ;; + -m) chmodcmd="$chmodprog $2" + shift; shift; continue + ;; + -o) chowncmd="$chownprog $2" + shift; shift; continue + ;; + -g) chgrpcmd="$chgrpprog $2" + shift; shift; continue + ;; + -s) stripcmd="$stripprog" + shift; continue + ;; + -S) stripcmd="$stripprog $2" + shift; shift; continue + ;; + -e) ext="$2" + shift; shift; continue + ;; + *) if [ "x$src" = "x" ]; then + src=$1 + else + dst=$1 + fi + shift; continue + ;; + esac +done +if [ "x$src" = "x" ]; then + echo "install.sh: no input file specified" + exit 1 +fi +if [ "x$dst" = "x" ]; then + echo "install.sh: no destination specified" + exit 1 +fi + +# +# If destination is a directory, append the input filename; if +# your system does not like double slashes in filenames, you may +# need to add some logic +# +if [ -d $dst ]; then + dst="$dst/`basename $src`" +fi + +# Add a possible extension (such as ".exe") to src and dst +src="$src$ext" +dst="$dst$ext" + +# Make a temp file name in the proper directory. +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name +$instcmd $src $dsttmp + +# And set any options; do chmod last to preserve setuid bits +if [ "x$chowncmd" != "x" ]; then $chowncmd $dsttmp; fi +if [ "x$chgrpcmd" != "x" ]; then $chgrpcmd $dsttmp; fi +if [ "x$stripcmd" != "x" ]; then $stripcmd $dsttmp; fi +if [ "x$chmodcmd" != "x" ]; then $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. +$rmcmd $dst +$mvcmd $dsttmp $dst + +exit 0 + diff --git a/trunk/build/instdso.sh b/trunk/build/instdso.sh new file mode 100755 index 0000000000..c3e1b76df9 --- /dev/null +++ b/trunk/build/instdso.sh @@ -0,0 +1,93 @@ +#!/bin/sh +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# instdso.sh - install Apache DSO modules +# +# we use this instead of libtool --install because: +# 1) on a few platforms libtool doesn't install DSOs exactly like we'd +# want (weird names, doesn't remove DSO first) +# 2) we never want the .la files copied, so we might as well copy +# the .so files ourselves + +if test "$#" != "3"; then + echo "wrong number of arguments to instdso.sh" + echo "Usage: instdso.sh SH_LIBTOOL-value dso-name path-to-modules" + exit 1 +fi + +SH_LIBTOOL=`echo $1 | sed -e 's/^SH_LIBTOOL=//'` +DSOARCHIVE=$2 +DSOARCHIVE_BASENAME=`basename $2` +TARGETDIR=$3 +DSOBASE=`echo $DSOARCHIVE_BASENAME | sed -e 's/\.la$//'` +TARGET_NAME="$DSOBASE.so" + +SYS=`uname -s` + +if test "$SYS" = "AIX" +then + # on AIX, shared libraries remain in storage even when + # all processes using them have exited; standard practice + # prior to installing a shared library is to rm -f first + CMD="rm -f $TARGETDIR/$TARGET_NAME" + echo $CMD + $CMD || exit $? +fi + +CMD="$SH_LIBTOOL --mode=install cp $DSOARCHIVE $TARGETDIR/" +echo $CMD +$CMD || exit $? + +if test "$SYS" = "OS/2" +then + # on OS/2, aplibtool --install doesn't copy the .la files & we can't + # rename DLLs to have a .so extension or they won't load so none of the + # steps below make sense. + exit 0 +fi + +DLNAME=`grep "^dlname" $TARGETDIR/$DSOARCHIVE_BASENAME | sed -e "s/dlname='\([^']*\)'/\1/"` +LIBRARY_NAMES=`grep "library_names" $TARGETDIR/$DSOARCHIVE_BASENAME | sed -e "s/dlname='\([^']*\)'/\1/"` +LIBRARY_NAMES=`echo $LIBRARY_NAMES | sed -e "s/ *$DLNAME//g"` + +if test -z "$DLNAME" +then + echo "Warning! dlname not found in $TARGETDIR/$DSOARCHIVE_BASENAME." + echo "Assuming installing a .so rather than a libtool archive." + exit 0 +fi + +if test -n "$LIBRARY_NAMES" +then + for f in $LIBRARY_NAMES + do + rm -f $TARGETDIR/$f + done +fi + +if test "$DLNAME" != "$TARGET_NAME" +then + mv $TARGETDIR/$DLNAME $TARGETDIR/$TARGET_NAME +fi + +rm -f $TARGETDIR/$DSOARCHIVE_BASENAME +rm -f $TARGETDIR/$DSOBASE.a +rm -f $TARGETDIR/lib$DSOBASE.a +rm -f $TARGETDIR/lib$TARGET_NAME + +exit 0 diff --git a/trunk/build/library.mk b/trunk/build/library.mk new file mode 100644 index 0000000000..6cee6d2b30 --- /dev/null +++ b/trunk/build/library.mk @@ -0,0 +1,21 @@ +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +LTLIBRARY_OBJECTS = $(LTLIBRARY_SOURCES:.c=.lo) $(LTLIBRARY_OBJECTS_X) + +$(LTLIBRARY_NAME): $(LTLIBRARY_OBJECTS) $(LTLIBRARY_DEPENDENCIES) + $(LINK) -static $(LTLIBRARY_LDFLAGS) $(LTLIBRARY_OBJECTS) $(LTLIBRARY_LIBADD) diff --git a/trunk/build/ltlib.mk b/trunk/build/ltlib.mk new file mode 100644 index 0000000000..5ab0750498 --- /dev/null +++ b/trunk/build/ltlib.mk @@ -0,0 +1,22 @@ +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +TARGETS = $(LTLIBRARY_NAME) + +include $(top_builddir)/build/rules.mk +include $(top_srcdir)/build/library.mk + diff --git a/trunk/build/make_exports.awk b/trunk/build/make_exports.awk new file mode 100644 index 0000000000..aa69b257ad --- /dev/null +++ b/trunk/build/make_exports.awk @@ -0,0 +1,163 @@ +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +BEGIN { + printf("/*\n") + printf(" * THIS FILE WAS AUTOGENERATED BY make_exports.awk\n") + printf(" *\n") + printf(" * This is an ugly hack that needs to be here, so\n") + printf(" * that libtool will link all of the APR functions\n") + printf(" * into server regardless of whether the base server\n") + printf(" * uses them.\n") + printf(" */\n") + printf("\n") + printf("#define CORE_PRIVATE\n") + printf("\n") + + for (i = 1; i < ARGC; i++) { + file = ARGV[i] + sub("([^/]*[/])*", "", file) + printf("#include \"%s\"\n", file) + } + + printf("\n") + printf("const void *ap_ugly_hack = NULL;\n") + printf("\n") + + TYPE_NORMAL = 0 + TYPE_HEADER = 1 + + stackptr = 0 +} + +function push(line) { + stack[stackptr] = line + stackptr++ +} + +function do_output() { + printf("/*\n") + printf(" * %s\n", FILENAME) + printf(" */\n") + + for (i = 0; i < stackptr; i++) { + printf("%s\n", stack[i]) + } + + stackptr = 0 + + printf("\n"); +} + +function enter_scope(type) { + scope++ + scope_type[scope] = type + scope_stack[scope] = stackptr + delete scope_used[scope] +} + +function leave_scope() { + used = scope_used[scope] + + if (!used) + stackptr = scope_stack[scope] + + scope-- + if (used) { + scope_used[scope] = 1 + + if (!scope) + do_output() + } +} + +function add_symbol(symbol) { + if (!index(symbol, "#")) { + push("const void *ap_hack_" symbol " = (const void *)" symbol ";") + scope_used[scope] = 1 + } +} + +/^[ \t]*AP[RU]?_(CORE_)?DECLARE[^(]*[(][^)]*[)]([^ ]* )*[^(]+[(]/ { + sub("[ \t]*AP[RU]?_(CORE_)?DECLARE[^(]*[(][^)]*[)][ \t]*", "") + sub("[(].*", "") + sub("([^ ]* (^([ \t]*[(])))+", "") + + add_symbol($0) + next +} + +/^[ \t]*AP_DECLARE_HOOK[^(]*[(][^)]*/ { + split($0, args, ",") + symbol = args[2] + sub("^[ \t]+", "", symbol) + sub("[ \t]+$", "", symbol) + + add_symbol("ap_hook_" symbol) + add_symbol("ap_hook_get_" symbol) + add_symbol("ap_run_" symbol) + next +} + +/^[ \t]*APR_POOL_DECLARE_ACCESSOR[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_POOL_DECLARE_ACCESSOR[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_pool_get") + next +} + +/^[ \t]*APR_DECLARE_INHERIT_SET[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_DECLARE_INHERIT_SET[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_inherit_set") + next +} + +/^[ \t]*APR_DECLARE_INHERIT_UNSET[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_DECLARE_INHERIT_UNSET[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_inherit_unset") + next +} + +/^#[ \t]*if(ndef| !defined[(])([^_]*_)*H/ { + enter_scope(TYPE_HEADER) + next +} + +/^#[ \t]*if([n]?def)? / { + enter_scope(TYPE_NORMAL) + push($0) + next +} + +/^#[ \t]*endif/ { + if (scope_type[scope] == TYPE_NORMAL) + push($0) + + leave_scope() + next +} + +/^#[ \t]*else/ { + push($0) + next +} + +/^#[ \t]*elif/ { + push($0) + next +} + + diff --git a/trunk/build/make_nw_export.awk b/trunk/build/make_nw_export.awk new file mode 100644 index 0000000000..4640ff696e --- /dev/null +++ b/trunk/build/make_nw_export.awk @@ -0,0 +1,90 @@ +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Based on apr's make_export.awk, which is +# based on Ryan Bloom's make_export.pl + +BEGIN { + printf(" (APACHE2)\n") +} + +# List of functions that we don't support, yet?? +#/ap_some_name/{next} + +function add_symbol (sym_name) { + if (count) { + found++ + } + gsub (/ /, "", sym_name) + line = line sym_name ",\n" + + if (count == 0) { + printf(" %s", line) + line = "" + } +} + +/^[ \t]*AP([RU]|_CORE)?_DECLARE[^(]*[(][^)]*[)]([^ ]* )*[^(]+[(]/ { + sub("[ \t]*AP([RU]|_CORE)?_DECLARE[^(]*[(][^)]*[)][ \t]*", "") + sub("[(].*", "") + sub("([^ ]* (^([ \t]*[(])))+", "") + + add_symbol($0) + next +} + +/^[ \t]*AP_DECLARE_HOOK[^(]*[(][^)]*/ { + split($0, args, ",") + symbol = args[2] + sub("^[ \t]+", "", symbol) + sub("[ \t]+$", "", symbol) + + add_symbol("ap_hook_" symbol) + add_symbol("ap_hook_get_" symbol) + add_symbol("ap_run_" symbol) + next +} + +/^[ \t]*APR_POOL_DECLARE_ACCESSOR[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_POOL_DECLARE_ACCESSOR[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_pool_get") + next +} + +/^[ \t]*APR_DECLARE_INHERIT_SET[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_DECLARE_INHERIT_SET[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_inherit_set") + next +} + +/^[ \t]*APR_DECLARE_INHERIT_UNSET[^(]*[(][^)]*[)]/ { + sub("[ \t]*APR_DECLARE_INHERIT_UNSET[^(]*[(]", "", $0) + sub("[)].*$", "", $0) + add_symbol("apr_" $0 "_inherit_unset") + next +} + +/^[ \t]*(extern[ \t]+)?AP[RU]?_DECLARE_DATA .*;$/ { + varname = $NF; + gsub( /[*;]/, "", varname); + gsub( /\[.*\]/, "", varname); + add_symbol(varname); +} + +#END { +# printf(" %s", line) +#} diff --git a/trunk/build/make_var_export.awk b/trunk/build/make_var_export.awk new file mode 100644 index 0000000000..be150d4710 --- /dev/null +++ b/trunk/build/make_var_export.awk @@ -0,0 +1,74 @@ +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Based on apr's make_export.awk, which is +# based on Ryan Bloom's make_export.pl + +/^#[ \t]*if(def)? (AP[RU]?_|!?defined).*/ { + if (old_filename != FILENAME) { + if (old_filename != "") printf("%s", line) + macro_no = 0 + found = 0 + count = 0 + old_filename = FILENAME + line = "" + } + macro_stack[macro_no++] = macro + macro = substr($0, length($1)+2) + count++ + line = line "#ifdef " macro "\n" + next +} + +/^#[ \t]*endif/ { + if (count > 0) { + count-- + line = line "#endif /* " macro " */\n" + macro = macro_stack[--macro_no] + } + if (count == 0) { + if (found != 0) { + printf("%s", line) + } + line = "" + } + next +} + +function add_symbol (sym_name) { + if (count) { + found++ + } + for (i = 0; i < count; i++) { + line = line "\t" + } + line = line sym_name "\n" + + if (count == 0) { + printf("%s", line) + line = "" + } +} + +/^[ \t]*(extern[ \t]+)?AP[RU]?_DECLARE_DATA .*;$/ { + varname = $NF; + gsub( /[*;]/, "", varname); + gsub( /\[.*\]/, "", varname); + add_symbol(varname); +} + +END { + printf("%s", line) +} diff --git a/trunk/build/mkconfNW.awk b/trunk/build/mkconfNW.awk new file mode 100644 index 0000000000..b65c1682a5 --- /dev/null +++ b/trunk/build/mkconfNW.awk @@ -0,0 +1,121 @@ +# Copyright 2002-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +BEGIN { + + A["ServerRoot"] = "SYS:/APACHE2" + A["Port"] = "80" + A["cgidir"] = "cgi-bin" + A["logfiledir"] = "logs" + A["htdocsdir"] = "htdocs" + A["sysconfdir"] = "conf" + A["iconsdir"] = "icons" + A["manualdir"] = "manual" + A["runtimedir"] = "logs" + A["errordir"] = "error" + A["proxycachedir"] = "proxy" + + B["htdocsdir"] = A["ServerRoot"]"/"A["htdocsdir"] + B["iconsdir"] = A["ServerRoot"]"/"A["iconsdir"] + B["manualdir"] = A["ServerRoot"]"/"A["manualdir"] + B["errordir"] = A["ServerRoot"]"/"A["errordir"] + B["proxycachedir"] = A["ServerRoot"]"/"A["proxycachedir"] + B["cgidir"] = A["ServerRoot"]"/"A["cgidir"] + B["listen_stmt_1"] = "Listen "A["Port"] + B["listen_stmt_2"] = "" +} + +/@@LoadModule@@/ { + print "#LoadModule actions_module modules/actions.nlm" + print "#LoadModule auth_basic_module modules/authbasc.nlm" + print "#LoadModule auth_digest_module modules/authdigt.nlm" + print "#LoadModule authn_anon_module modules/authnano.nlm" + print "#LoadModule authn_dbm_module modules/authndbm.nlm" + print "#LoadModule authn_default_module modules/authndef.nlm" + print "#LoadModule authn_file_module modules/authnfil.nlm" + print "#LoadModule authz_dbm_module modules/authzdbm.nlm" + print "#LoadModule authz_default_module modules/authzdef.nlm" + print "#LoadModule authz_groupfile_module modules/authzgrp.nlm" + print "#LoadModule authz_user_module modules/authzusr.nlm" + print "#LoadModule asis_module modules/mod_asis.nlm" + print "LoadModule autoindex_module modules/autoindex.nlm" + print "#LoadModule cern_meta_module modules/cernmeta.nlm" + print "#LoadModule cgi_module modules/mod_cgi.nlm" + print "#LoadModule dav_module modules/mod_dav.nlm" + print "#LoadModule dav_fs_module modules/moddavfs.nlm" + print "#LoadModule dav_lock_module modules/moddavlk.nlm" + print "#LoadModule expires_module modules/expires.nlm" + print "#LoadModule ext_filter_module modules/extfiltr.nlm" + print "#LoadModule file_cache_module modules/filecach.nlm" + print "#LoadModule headers_module modules/headers.nlm" + print "#LoadModule ident_module modules/modident.nlm" + print "#LoadModule imagemap_module modules/imagemap.nlm" + print "#LoadModule info_module modules/info.nlm" + print "#LoadModule log_forensic_module modules/forensic.nlm" + print "#LoadModule logio_module modules/modlogio.nlm" + print "#LoadModule mime_magic_module modules/mimemagi.nlm" + print "#LoadModule proxy_module modules/proxy.nlm" + print "#LoadModule proxy_connect_module modules/proxycon.nlm" + print "#LoadModule proxy_http_module modules/proxyhtp.nlm" + print "#LoadModule proxy_ftp_module modules/proxyftp.nlm" + print "#LoadModule rewrite_module modules/rewrite.nlm" + print "#LoadModule speling_module modules/speling.nlm" + print "#LoadModule status_module modules/status.nlm" + print "#LoadModule unique_id_module modules/uniqueid.nlm" + print "#LoadModule usertrack_module modules/usertrk.nlm" + print "#LoadModule version_module modules/modversion.nlm" + print "#LoadModule userdir_module modules/userdir.nlm" + print "#LoadModule vhost_alias_module modules/vhost.nlm" + print "" + next +} + +match ($0,/@@.*@@/) { + s=substr($0,RSTART+2,RLENGTH-4) + sub(/@@.*@@/,A[s],$0) +} + +match ($0,/@rel_.*@/) { + s=substr($0,RSTART+5,RLENGTH-6) + sub(/@rel_.*@/,A[s],$0) +} + +match ($0,/@exp_.*@/) { + s=substr($0,RSTART+5,RLENGTH-6) + sub(/@exp_.*@/,B[s],$0) +} + +match ($0,/@nonssl_.*@/) { + s=substr($0,RSTART+8,RLENGTH-9) + sub(/@nonssl_.*@/,B[s],$0) +} + +{ + print +} + + +END { + if (SSL) { + print + print "#" + print "# SecureListen: Allows you to securely bind Apache to specific IP addresses " + print "# and/or ports." + print "#" + print "# Change this to SecureListen on specific IP addresses as shown below to " + print "# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)" + print "#" + print "#SecureListen 443 \"SSL CertificateDNS\"" + } +} diff --git a/trunk/build/mkdep.perl b/trunk/build/mkdep.perl new file mode 100644 index 0000000000..10815d2483 --- /dev/null +++ b/trunk/build/mkdep.perl @@ -0,0 +1,92 @@ +#!/usr/bin/perl +# +# $Id$ +# +# Created: Thu Aug 15 11:57:33 1996 too +# Last modified: Mon Dec 27 09:23:56 1999 too +# +# Copyright (c) 1996-1999 Tomi Ollila. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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. + +die "Usage: mkdep CPP-command [CPP options] file1 [file2...]\n" + if ($#ARGV < 1); + +$cmdl = shift(@ARGV); + +$cmdl = "$cmdl " . shift (@ARGV) while ($ARGV[0] =~ /^-[A-Z]/); + +while ($file = shift(@ARGV)) +{ + $file =~ s/\.o$/.c/; + + open(F, "$cmdl $file|"); + + &parseout; + + close(F); +} + + +sub initinit +{ + %used = (); + $of = $file; + $of =~ s/\.c$/.lo/; + $str = "$of:\t$file"; + $len = length $str; +} + +sub initstr +{ + $str = "\t"; + $len = length $str; +} + +sub parseout +{ + &initinit; + while () + { + s/\\\\/\//g; + next unless (/^# [0-9]* "(.*\.h)"/); + + next if ($1 =~ /^\//); + + next if $used{$1}; + + $used{$1} = 1; + + $nlen = length($1) + 1; + + if ($len + $nlen > 72) + { + print $str, "\\\n"; + &initstr; + $str = $str . $1; + } + else { $str = $str . " " . $1; } + + $len += $nlen; + + } + print $str, "\n"; +} diff --git a/trunk/build/mkdir.sh b/trunk/build/mkdir.sh new file mode 100755 index 0000000000..889667b820 --- /dev/null +++ b/trunk/build/mkdir.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Copyright 1999-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# mkdir.sh -- make directory hierarchy +# +# Based on `mkinstalldirs' from Noah Friedman +# as of 1994-03-25, which was placed in the Public Domain. +# Cleaned up for Apache's Autoconf-style Interface (APACI) +# by Ralf S. Engelschall + +umask 022 +errstatus=0 +for file in ${1+"$@"} ; do + set fnord `echo ":$file" |\ + sed -e 's/^:\//%/' -e 's/^://' -e 's/\// /g' -e 's/^%/\//'` + shift + pathcomp= + for d in ${1+"$@"}; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + ?: ) pathcomp="$pathcomp/" + continue ;; + esac + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" || errstatus=$? + fi + pathcomp="$pathcomp/" + done +done +exit $errstatus + diff --git a/trunk/build/nw_export.inc b/trunk/build/nw_export.inc new file mode 100644 index 0000000000..94d9a45a5a --- /dev/null +++ b/trunk/build/nw_export.inc @@ -0,0 +1,49 @@ +/* Must include ap_config.h first so that we can redefine + the standard prototypes macros after it messes with + them. */ +#include "ap_config.h" + +/* Define all of the standard prototype macros as themselves + so that httpd.h will not mess with them. This allows + them to pass untouched so that the AWK script can pick + them out of the preprocessed result file. */ +#define AP_DECLARE AP_DECLARE +#define AP_CORE_DECLARE AP_CORE_DECLARE +#define AP_DECLARE_NONSTD AP_DECLARE_NONSTD +#define AP_CORE_DECLARE_NONSTD AP_CORE_DECLARE_NONSTD +#define AP_DECLARE_HOOK AP_DECLARE_HOOK +#define AP_DECLARE_DATA AP_DECLARE_DATA +#undef APACHE_OS_H + +#include "httpd.h" + +/* Preprocess all of the standard HTTPD headers. */ +#include "ap_compat.h" +#include "ap_listen.h" +#include "ap_mmn.h" +#include "ap_mpm.h" +#include "ap_provider.h" +#include "ap_release.h" +#include "http_config.h" +#include "http_connection.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_vhost.h" +#include "mpm_common.h" +#include "ap_regex.h" +#include "scoreboard.h" +#include "util_cfgtree.h" +#include "util_charset.h" +#include "util_ebcdic.h" +#include "util_filter.h" +/*#include "util_ldap.h"*/ +#include "util_md5.h" +#include "util_script.h" +#include "util_time.h" +#include "util_xml.h" + +#include "mod_core.h" +#include "mod_auth.h" diff --git a/trunk/build/nw_ver.awk b/trunk/build/nw_ver.awk new file mode 100644 index 0000000000..59304a244c --- /dev/null +++ b/trunk/build/nw_ver.awk @@ -0,0 +1,39 @@ +# Copyright 2002-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +BEGIN { + + # fetch Apache version numbers from input file and writes them to STDOUT + + while ((getline < ARGV[1]) > 0) { + if (match ($0, /^#define AP_SERVER_MAJORVERSION_NUMBER /)) { + ver_major = $3; + } + else if (match ($0, /^#define AP_SERVER_MINORVERSION_NUMBER /)) { + ver_minor = $3; + } + else if (match ($0, /^#define AP_SERVER_PATCHLEVEL_NUMBER/)) { + ver_patch = $3; + } + else if (match ($0, /^#define AP_SERVER_ADD_STRING /)) { + ver_str_release = substr($3, 2, length($3) - 2); + } + } + ver = ver_major "," ver_minor "," ver_patch; + ver_str = ver_major "." ver_minor "." ver_patch ver_str_release; + + print "VERSION = " ver ""; + print "VERSION_STR = " ver_str ""; + +} diff --git a/trunk/build/pkg/README b/trunk/build/pkg/README new file mode 100644 index 0000000000..147c1f1e58 --- /dev/null +++ b/trunk/build/pkg/README @@ -0,0 +1,16 @@ +The script in this directory will attempt to build a Solaris package +out of a source tree for httpd. + +To build a package, make sure you are in the root of the source tree, +and run: + +build/pkg/buildpkg.sh + +A Solaris package called httpd---local.gz will be +created in the root of the source tree. + +By default, the script will attempt to find a system installed version of +APR and APR-util v1. You may override the location of apr or apr-util like so: + +build/pkg/buildpkg.sh --with-apr=some/other/path --with-apr-util=some/other/path + diff --git a/trunk/build/pkg/buildpkg.sh b/trunk/build/pkg/buildpkg.sh new file mode 100755 index 0000000000..4dd7d81756 --- /dev/null +++ b/trunk/build/pkg/buildpkg.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# Copyright 2000-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +# buildpkg.sh: This script builds a Solaris PKG from the source tree +# provided. + +LAYOUT=Apache +PREFIX=/usr/local/apache2 +TEMPDIR=/var/tmp/$USER/httpd-root +rm -rf $TEMPDIR + +apr_config=`which apr-1-config` +apu_config=`which apu-1-config` + +while test $# -gt 0 +do + # Normalize + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case "$1" in + --with-apr=*) + apr_config=$optarg + ;; + esac + + case "$1" in + --with-apr-util=*) + apu_config=$optarg + ;; + esac + + shift +done + +if [ ! -f "$apr_config" -a ! -f "$apr_config/configure.in" ]; then + echo "The apr source directory / apr-1-config could not be found" + echo "Usage: buildpkg [--with-apr=[dir|file]] [--with-apr-util=[dir|file]]" + exit 1 +fi + +if [ ! -f "$apu_config" -a ! -f "$apu_config/configure.in" ]; then + echo "The apu source directory / apu-1-config could not be found" + echo "Usage: buildpkg [--with-apr=[dir|file]] [--with-apr-util=[dir|file]]" + exit 1 +fi + +./configure --enable-layout=$LAYOUT \ + --with-apr=$apr_config \ + --with-apr-util=$apu_config \ + --enable-mods-shared=all \ + --with-devrandom \ + --with-ldap --enable-ldap --enable-authnz-ldap \ + --enable-cache --enable-disk-cache --enable-mem-cache \ + --enable-ssl --with-ssl \ + --enable-deflate --enable-cgid \ + --enable-proxy --enable-proxy-connect \ + --enable-proxy-http --enable-proxy-ftp + +make +make install DESTDIR=$TEMPDIR +. build/pkg/pkginfo +cp build/pkg/pkginfo $TEMPDIR$PREFIX + +current=`pwd` +cd $TEMPDIR$PREFIX +echo "i pkginfo=./pkginfo" > prototype +find . -print | grep -v ./prototype | grep -v ./pkginfo | pkgproto | awk '{print $1" "$2" "$3" "$4" root bin"}' >> prototype +mkdir $TEMPDIR/pkg +pkgmk -r $TEMPDIR$PREFIX -d $TEMPDIR/pkg + +cd $current +pkgtrans -s $TEMPDIR/pkg $current/$NAME-$VERSION-$ARCH-local +gzip $current/$NAME-$VERSION-$ARCH-local + +rm -rf $TEMPDIR + diff --git a/trunk/build/pkg/pkginfo.in b/trunk/build/pkg/pkginfo.in new file mode 100644 index 0000000000..928dad4636 --- /dev/null +++ b/trunk/build/pkg/pkginfo.in @@ -0,0 +1,11 @@ +PKG="ASFhttpd" +NAME="httpd" +ARCH="@target_cpu@" +VERSION="@HTTPD_VERSION@" +CATEGORY="application" +VENDOR="Apache Software Foundation" +EMAIL="dev@httpd.apache.org" +PSTAMP="dev@httpd.apache.org" +BASEDIR="@prefix@" +CLASSES="none" + diff --git a/trunk/build/prebuildNW.bat b/trunk/build/prebuildNW.bat new file mode 100755 index 0000000000..0ce59f1e66 --- /dev/null +++ b/trunk/build/prebuildNW.bat @@ -0,0 +1,47 @@ +@echo off + +if not "%NovellLibC%" == "" goto CheckNDK +set NovellLibC=\novell\ndk\libc +@echo Could not find the NovellLibC environment variable +@echo Setting NovellLibC = %NovellLibC% +@echo --------------------- + +:CheckNDK +if exist %NovellLibC%\include\netware.h goto NDKOK +@echo The path to the NDK "%NovellLibC%" is invalid. +@echo Please set then NovellLibC environment variable to the location of the NDK +@echo --------------------- +goto Done + +:NDKOK +@echo # As part of the pre-build process, the utilities GenChars.NLM +@echo # (Gen Test Chars) and DFTables.NLM (dftables) must be built, +@echo # copied to a NetWare server and run using the following commands: +@echo # +@echo # "sys:\genchars >sys:\test_char.h" +@echo # "sys:\dftables >sys:\chartables.c" +@echo # +@echo # The files "sys:\test_chars.h" and "sys:\chartables.c" must be +@echo # copied to "httpd\os\netware" on the build machine. + +@echo Fixing up the APR headers +copy ..\srclib\apr\include\apr.hnw ..\srclib\apr\include\apr.h + +@echo Fixing up the APR-Util headers +copy ..\srclib\apr-util\include\apu.hnw ..\srclib\apr-util\include\apu.h +copy ..\srclib\apr-util\include\apr_ldap.hnw ..\srclib\apr-util\include\apr_ldap.h + +@echo Fixing up the pcre headers +copy ..\srclib\pcre\config.hw ..\srclib\pcre\config.h +copy ..\srclib\pcre\pcre.hw ..\srclib\pcre\pcre.h + +@echo Generating the import lists... +set MWCIncludes=..\include;..\modules\http;..\modules\aaa;..\os\netware;..\server\mpm\netware;..\srclib\apr\include;..\srclib\apr-util\include;+%NovellLibC% +mwccnlm -P nw_export.inc -d NETWARE -d CORE_PRIVATE -EP +awk -f make_nw_export.awk nw_export.i |sort >..\os\netware\httpd.imp + +rem cd ..\srclib\apr\build +rem call prebuildnw.bat + +:Done +pause diff --git a/trunk/build/program.mk b/trunk/build/program.mk new file mode 100644 index 0000000000..3b5d2abef2 --- /dev/null +++ b/trunk/build/program.mk @@ -0,0 +1,22 @@ +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +PROGRAM_OBJECTS = $(PROGRAM_SOURCES:.c=.lo) + +$(PROGRAM_NAME): $(PROGRAM_DEPENDENCIES) $(PROGRAM_OBJECTS) + $(PROGRAM_PRELINK) + $(LINK) $(PROGRAM_LDFLAGS) $(PROGRAM_OBJECTS) $(PROGRAM_LDADD) diff --git a/trunk/build/rpm/httpd.init b/trunk/build/rpm/httpd.init new file mode 100755 index 0000000000..218b69d1b1 --- /dev/null +++ b/trunk/build/rpm/httpd.init @@ -0,0 +1,126 @@ +#!/bin/bash +# +# Copyright 2003-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Startup script for the Apache Web Server +# +# chkconfig: - 85 15 +# description: Apache is a World Wide Web server. It is used to serve \ +# HTML files and CGI. +# processname: httpd +# pidfile: /var/run/httpd.pid +# config: /etc/httpd/conf/httpd.conf + +# Source function library. +. /etc/rc.d/init.d/functions + +if [ -f /etc/sysconfig/httpd ]; then + . /etc/sysconfig/httpd +fi + +# This will prevent initlog from swallowing up a pass-phrase prompt if +# mod_ssl needs a pass-phrase from the user. +INITLOG_ARGS="" + +# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server +# with the thread-based "worker" MPM; BE WARNED that some modules may not +# work correctly with a thread-based MPM; notably PHP will refuse to start. + +# Path to the apachectl script, server binary, and short-form for messages. +apachectl=/usr/sbin/apachectl +httpd=${HTTPD-/usr/sbin/httpd} +prog=httpd +RETVAL=0 + +# check for 1.3 configuration +check13 () { + CONFFILE=/etc/httpd/conf/httpd.conf + GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|" + GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|" + GONE="${GONE}AccessConfig|ResourceConfig)" + if grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then + echo + echo 1>&2 " Apache 1.3 configuration directives found" + echo 1>&2 " please read @docdir@/migration.html" + failure "Apache 1.3 config directives test" + echo + exit 1 + fi +} + +# The semantics of these two functions differ from the way apachectl does +# things -- attempting to start while running is a failure, and shutdown +# when not running is also a failure. So we just do it the way init scripts +# are expected to behave here. +start() { + echo -n $"Starting $prog: " + check13 || exit 1 + daemon $httpd $OPTIONS + RETVAL=$? + echo + [ $RETVAL = 0 ] && touch /var/lock/subsys/httpd + return $RETVAL +} +stop() { + echo -n $"Stopping $prog: " + killproc $httpd + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/httpd /var/run/httpd.pid +} +reload() { + echo -n $"Reloading $prog: " + check13 || exit 1 + killproc $httpd -HUP + RETVAL=$? + echo +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status $httpd + RETVAL=$? + ;; + restart) + stop + start + ;; + condrestart) + if [ -f /var/run/httpd.pid ] ; then + stop + start + fi + ;; + reload) + reload + ;; + graceful|help|configtest|fullstatus) + $apachectl $@ + RETVAL=$? + ;; + *) + echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}" + exit 1 +esac + +exit $RETVAL diff --git a/trunk/build/rpm/httpd.logrotate b/trunk/build/rpm/httpd.logrotate new file mode 100644 index 0000000000..dd0ce1b9a9 --- /dev/null +++ b/trunk/build/rpm/httpd.logrotate @@ -0,0 +1,8 @@ +/var/log/httpd/*log { + missingok + notifempty + sharedscripts + postrotate + /bin/kill -HUP `cat /var/run/httpd.pid 2>/dev/null` 2> /dev/null || true + endscript +} diff --git a/trunk/build/rpm/httpd.spec.in b/trunk/build/rpm/httpd.spec.in new file mode 100644 index 0000000000..2862de48bb --- /dev/null +++ b/trunk/build/rpm/httpd.spec.in @@ -0,0 +1,519 @@ +%define contentdir /var/www +%define suexec_caller apache +%define mmn APACHE_MMN + +%ifarch ia64 +# disable debuginfo on IA64 +%define debug_package %{nil} +%endif + +Summary: Apache HTTP Server +Name: httpd +Version: APACHE_VERSION +Release: APACHE_RELEASE +URL: http://httpd.apache.org/ +Vendor: Apache Software Foundation +Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.gz +License: Apache License, Version 2.0 +Group: System Environment/Daemons +BuildRoot: %{_tmppath}/%{name}-root +BuildPrereq: apr-devel, apr-util-devel, openldap-devel, db4-devel, expat-devel, findutils, perl, pkgconfig +BuildPrereq: /usr/bin/apr-1-config, /usr/bin/apu-1-config +Requires: apr >= 1.0.2, apr-util >= 1.0.2, gawk, /usr/share/magic.mime, /usr/bin/find, openldap +Prereq: /sbin/chkconfig, /bin/mktemp, /bin/rm, /bin/mv +Prereq: sh-utils, textutils, /usr/sbin/useradd +Provides: webserver +Provides: httpd-mmn = %{mmn} +Conflicts: thttpd +Obsoletes: apache, secureweb, mod_dav + +%description +Apache is a powerful, full-featured, efficient, and freely-available +Web server. Apache is also the most popular Web server on the +Internet. + +%package devel +Group: Development/Libraries +Summary: Development tools for the Apache HTTP server. +Obsoletes: secureweb-devel, apache-devel +Requires: libtool, httpd = %{version} +Requires: apr-devel >= 1.0.2, apr-util-devel >= 1.0.2 + +%description devel +The httpd-devel package contains the APXS binary and other files +that you need to build Dynamic Shared Objects (DSOs) for Apache. + +If you are installing the Apache HTTP server and you want to be +able to compile or develop additional modules for Apache, you need +to install this package. + +%package manual +Group: Documentation +Summary: Documentation for the Apache HTTP server. +Obsoletes: secureweb-manual, apache-manual + +%description manual +The httpd-manual package contains the complete manual and +reference guide for the Apache HTTP server. The information can +also be found at http://httpd.apache.org/docs/. + +%package -n mod_ssl +Group: System Environment/Daemons +Summary: SSL/TLS module for the Apache HTTP server +Serial: 1 +BuildPrereq: openssl-devel +Prereq: openssl, dev, /bin/cat +Requires: httpd, make, httpd-mmn = %{mmn} + +%description -n mod_ssl +The mod_ssl module provides strong cryptography for the Apache Web +server via the Secure Sockets Layer (SSL) and Transport Layer +Security (TLS) protocols. + +%prep +%setup -q + +# Safety check: prevent build if defined MMN does not equal upstream MMN. +vmmn=`echo MODULE_MAGIC_NUMBER_MAJOR | cpp -include \`pwd\`/include/ap_mmn.h | grep -e '^[0-9]'` +if test x${vmmn} != x%{mmn}; then + : Error: Upstream MMN is now ${vmmn}, packaged MMN is %{mmn}. + : Update the mmn macro and rebuild. + exit 1 +fi + +# regenerate configure scripts +./buildconf + +# Before configure; fix location of build dir in generated apxs +%{__perl} -pi -e "s:\@exp_installbuilddir\@:%{_libdir}/httpd/build:g" \ + support/apxs.in + +%build + +if pkg-config openssl ; then + # configure -C barfs with trailing spaces in CFLAGS + CFLAGS="$RPM_OPT_FLAGS `pkg-config --cflags openssl | sed 's/ *$//'`" + AP_LIBS="$AP_LIBS `pkg-config --libs openssl`" +else + CFLAGS="$RPM_OPT_FLAGS" + AP_LIBS="-lssl -lcrypto" +fi +export CFLAGS +export AP_LIBS + +function mpmbuild() +{ +mpm=$1; shift +mkdir $mpm; pushd $mpm +cat > config.cache < prefork.mods +./worker/httpd -l | grep -v worker > worker.mods +if ! diff -u prefork.mods worker.mods; then + : Different modules built into httpd binaries, will not proceed + exit 1 +fi + +%install +rm -rf $RPM_BUILD_ROOT + +pushd prefork +make DESTDIR=$RPM_BUILD_ROOT install +popd +# install worker binary +install -m 755 worker/httpd $RPM_BUILD_ROOT%{_sbindir}/httpd.worker + +# mod_ssl bits +for suffix in crl crt csr key prm; do + mkdir $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/ssl.${suffix} +done + +# Makefiles for certificate management +#for ext in crt crl; do +# install -m 644 ./build/rpm/mod_ssl-Makefile.${ext} \ +# $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/ssl.${ext}/Makefile.${ext} +#done +#ln -s ../../../usr/share/ssl/certs/Makefile $RPM_BUILD_ROOT/etc/httpd/conf + +# for holding mod_dav lock database +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/dav + +# create a prototype session cache +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/mod_ssl +touch $RPM_BUILD_ROOT%{_localstatedir}/cache/mod_ssl/scache.{dir,pag,sem} + +# move the build directory to within the library directory +mv $RPM_BUILD_ROOT%{contentdir}/build $RPM_BUILD_ROOT%{_libdir}/httpd/build + +# fix up config_vars file: relocate the build directory into libdir; +# reference correct libtool from apr; remove references to RPM build root. +sed -e "s|%{contentdir}/build|%{_libdir}/httpd/build|g" \ + -e "/AP_LIBS/d" -e "/abs_srcdir/d" \ + -e "/^LIBTOOL/s|/[^ ]*/libtool|`/usr/bin/apr-1-config --apr-libtool`|" \ + -e "/^EXTRA_INCLUDES/s|-I$RPM_BUILD_DIR[^ ]* ||g" \ + < prefork/build/config_vars.mk \ + > $RPM_BUILD_ROOT%{_libdir}/httpd/build/config_vars.mk + +# Make the MMN accessible to module packages +echo %{mmn} > $RPM_BUILD_ROOT%{_includedir}/httpd/.mmn + +# docroot +mkdir $RPM_BUILD_ROOT%{contentdir}/html +rm -r $RPM_BUILD_ROOT%{contentdir}/manual/style +rm $RPM_BUILD_ROOT%{contentdir}/manual/*/*.xml + +# logs +rmdir $RPM_BUILD_ROOT%{_sysconfdir}/httpd/logs +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/log/httpd + +# symlinks for /etc/httpd +ln -s ../..%{_localstatedir}/log/httpd $RPM_BUILD_ROOT/etc/httpd/logs +ln -s ../..%{_localstatedir}/run $RPM_BUILD_ROOT/etc/httpd/run +ln -s ../..%{_libdir}/httpd/modules $RPM_BUILD_ROOT/etc/httpd/modules +ln -s ../..%{_libdir}/httpd/build $RPM_BUILD_ROOT/etc/httpd/build + +# install SYSV init stuff +mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d +install -m755 ./build/rpm/httpd.init \ + $RPM_BUILD_ROOT/etc/rc.d/init.d/httpd +%{__perl} -pi -e "s:\@docdir\@:%{_docdir}/%{name}-%{version}:g" \ + $RPM_BUILD_ROOT/etc/rc.d/init.d/httpd + +# install log rotation stuff +mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d +install -m644 ./build/rpm/httpd.logrotate \ + $RPM_BUILD_ROOT/etc/logrotate.d/httpd + +# Remove unpackaged files +rm -rf $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.exp \ + $RPM_BUILD_ROOT%{contentdir}/htdocs/* \ + $RPM_BUILD_ROOT%{contentdir}/cgi-bin/* + +%pre +# Add the "apache" user +/usr/sbin/useradd -c "Apache" -u 48 \ + -s /sbin/nologin -r -d %{contentdir} apache 2> /dev/null || : + +%triggerpostun -- apache < 2.0 +/sbin/chkconfig --add httpd + +%post +# Register the httpd service +/sbin/chkconfig --add httpd + +%preun +if [ $1 = 0 ]; then + /sbin/service httpd stop > /dev/null 2>&1 + /sbin/chkconfig --del httpd +fi + +%post -n mod_ssl +/sbin/ldconfig ### is this needed? +umask 077 + +if [ ! -f %{_sysconfdir}/httpd/conf/ssl.key/server.key ] ; then +%{_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 1024 > %{_sysconfdir}/httpd/conf/ssl.key/server.key 2> /dev/null +fi + +FQDN=`hostname` +if [ "x${FQDN}" = "x" ]; then + FQDN=localhost.localdomain +fi + +if [ ! -f %{_sysconfdir}/httpd/conf/ssl.crt/server.crt ] ; then +cat << EOF | %{_bindir}/openssl req -new -key %{_sysconfdir}/httpd/conf/ssl.key/server.key -x509 -days 365 -out %{_sysconfdir}/httpd/conf/ssl.crt/server.crt 2>/dev/null +-- +SomeState +SomeCity +SomeOrganization +SomeOrganizationalUnit +${FQDN} +root@${FQDN} +EOF +fi + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) + +%doc ABOUT_APACHE README CHANGES LICENSE NOTICE + +%dir %{_sysconfdir}/httpd +%{_sysconfdir}/httpd/modules +%{_sysconfdir}/httpd/logs +%{_sysconfdir}/httpd/run +%dir %{_sysconfdir}/httpd/conf +%config(noreplace) %{_sysconfdir}/httpd/conf/httpd.conf +%{_sysconfdir}/httpd/conf/httpd-std.conf +%config(noreplace) %{_sysconfdir}/httpd/conf/highperformance.conf +%{_sysconfdir}/httpd/conf/highperformance-std.conf +%config(noreplace) %{_sysconfdir}/httpd/conf/magic +%config(noreplace) %{_sysconfdir}/httpd/conf/mime.types + +%config %{_sysconfdir}/logrotate.d/httpd +%config %{_sysconfdir}/rc.d/init.d/httpd + +%{_sbindir}/ab +%{_sbindir}/htcacheclean +%{_sbindir}/htdbm +%{_sbindir}/htdigest +%{_sbindir}/htpasswd +%{_sbindir}/logresolve +%{_sbindir}/httpd +%{_sbindir}/httpd.worker +%{_sbindir}/apachectl +%{_sbindir}/rotatelogs +%attr(4510,root,%{suexec_caller}) %{_sbindir}/suexec + +%dir %{_libdir}/httpd +%dir %{_libdir}/httpd/modules +# everything but mod_ssl.so: +%{_libdir}/httpd/modules/mod_[a-r]*.so +%{_libdir}/httpd/modules/mod_s[petu]*.so +%{_libdir}/httpd/modules/mod_[t-z]*.so + +%dir %{contentdir} +%dir %{contentdir}/cgi-bin +%dir %{contentdir}/html +%dir %{contentdir}/icons +%dir %{contentdir}/error +%dir %{contentdir}/error/include +%{contentdir}/icons/* +%{contentdir}/error/README +%config(noreplace) %{contentdir}/error/*.var +%config(noreplace) %{contentdir}/error/include/*.html + +%attr(0700,root,root) %dir %{_localstatedir}/log/httpd + +%attr(0700,apache,apache) %dir %{_localstatedir}/lib/dav + +%{_mandir}/man1/* +%{_mandir}/man8/ab* +%{_mandir}/man8/rotatelogs* +%{_mandir}/man8/logresolve* +%{_mandir}/man8/suexec* +%{_mandir}/man8/apachectl.8* +%{_mandir}/man8/httpd.8* +%{_mandir}/man8/htcacheclean.8* + +%files manual +%defattr(-,root,root) +%{contentdir}/manual +%{contentdir}/error/README + +%files -n mod_ssl +%defattr(-,root,root) +%{_libdir}/httpd/modules/mod_ssl.so +%config(noreplace) %{_sysconfdir}/httpd/conf/ssl.conf +%{_sysconfdir}/httpd/conf/ssl-std.conf +%attr(0700,root,root) %dir %{_sysconfdir}/httpd/conf/ssl.crl +%attr(0700,root,root) %dir %{_sysconfdir}/httpd/conf/ssl.crt +%attr(0700,root,root) %dir %{_sysconfdir}/httpd/conf/ssl.csr +%attr(0700,root,root) %dir %{_sysconfdir}/httpd/conf/ssl.key +%attr(0700,root,root) %dir %{_sysconfdir}/httpd/conf/ssl.prm +#%config %{_sysconfdir}/httpd/conf/Makefile +#%dir %{_sysconfdir}/httpd/conf/ssl.* +%attr(0700,apache,root) %dir %{_localstatedir}/cache/mod_ssl +%attr(0600,apache,root) %ghost %{_localstatedir}/cache/mod_ssl/scache.dir +%attr(0600,apache,root) %ghost %{_localstatedir}/cache/mod_ssl/scache.pag +%attr(0600,apache,root) %ghost %{_localstatedir}/cache/mod_ssl/scache.sem + +%files devel +%defattr(-,root,root) +%{_includedir}/httpd +%{_sysconfdir}/httpd/build +%{_sbindir}/apxs +%{_sbindir}/checkgid +%{_sbindir}/dbmmanage +%{_sbindir}/envvars* +%{_mandir}/man8/apxs.8* +%dir %{_libdir}/httpd/build +%{_libdir}/httpd/build/*.mk +%{_libdir}/httpd/build/instdso.sh +%{_libdir}/httpd/build/config.nice + +%changelog +* Thu Dec 16 2004 Graham Leggett 2.1.3-dev +- Changed build to use external apr and apr-util + +* Thu May 20 2004 Graham Leggett 2.0.50-dev +- Changed default dependancy to link to db4 instead of db3. +- Fixed complaints about unpackaged files. + +* Sat Apr 5 2003 Graham Leggett 2.0.46-dev +- Moved mime.types back to the default location. +- Added mod_ldap and friends, mod_cache and friends. +- Added openldap dependancy. + +* Sun Mar 30 2003 Graham Leggett 2.0.45-1 +- Created generic Apache rpm spec file from that donated by Redhat. +- Removed Redhat specific patches and boilerplate files. +- Removed SSL related Makefiles. + +* Mon Feb 24 2003 Joe Orton 2.0.40-21 +- add security fix for CAN-2003-0020; replace non-printable characters + with '!' when printing to error log. +- disable debuginfo on IA64. + +* Tue Feb 11 2003 Joe Orton 2.0.40-20 +- disable POSIX semaphores to support 2.4.18 kernel (#83324) + +* Wed Jan 29 2003 Joe Orton 2.0.40-19 +- require xmlto 0.0.11 or later +- fix apr_strerror on glibc2.3 + +* Wed Jan 22 2003 Tim Powers 2.0.40-18 +- rebuilt + +* Thu Jan 16 2003 Joe Orton 2.0.40-17 +- add mod_cgid and httpd binary built with worker MPM (#75496) +- allow choice of httpd binary in init script +- pick appropriate CGI module based on loaded MPM in httpd.conf +- source /etc/sysconfig/httpd in apachectl to get httpd choice +- make "apachectl status" fail gracefully when links isn't found (#78159) + +* Mon Jan 13 2003 Joe Orton 2.0.40-16 +- rebuild for OpenSSL 0.9.7 + +* Fri Jan 3 2003 Joe Orton 2.0.40-15 +- fix possible infinite recursion in config dir processing (#77206) +- fix memory leaks in request body processing (#79282) + +* Thu Dec 12 2002 Joe Orton 2.0.40-14 +- remove unstable shmht session cache from mod_ssl +- get SSL libs from pkg-config if available (Nalin Dahyabhai) +- stop "apxs -a -i" from inserting AddModule into httpd.conf (#78676) + +* Wed Nov 6 2002 Joe Orton 2.0.40-13 +- fix location of installbuilddir in apxs when libdir!=/usr/lib + +* Wed Nov 6 2002 Joe Orton 2.0.40-12 +- pass libdir to configure; clean up config_vars.mk +- package instdso.sh, fixing apxs -i (#73428) +- prevent build if upstream MMN differs from mmn macro +- remove installed but unpackaged files + +* Wed Oct 9 2002 Joe Orton 2.0.40-11 +- correct SERVER_NAME encoding in i18n error pages (thanks to Andre Malo) + +* Wed Oct 9 2002 Joe Orton 2.0.40-10 +- fix patch for CAN-2002-0840 to also cover i18n error pages + +* Wed Oct 2 2002 Joe Orton 2.0.40-9 +- security fixes for CAN-2002-0840 and CAN-2002-0843 +- fix for possible mod_dav segfault for certain requests + +* Tue Sep 24 2002 Gary Benson +- updates to the migration guide + +* Wed Sep 4 2002 Nalin Dahyabhai 2.0.40-8 +- link httpd with libssl to avoid library loading/unloading weirdness + +* Tue Sep 3 2002 Joe Orton 2.0.40-7 +- add LoadModule lines for proxy modules in httpd.conf (#73349) +- fix permissions of conf/ssl.*/ directories; add Makefiles for + certificate management (#73352) + +* Mon Sep 2 2002 Joe Orton 2.0.40-6 +- provide "httpd-mmn" to manage module ABI compatibility + +* Sun Sep 1 2002 Joe Orton 2.0.40-5 +- fix SSL session cache (#69699) +- revert addition of LDAP support to apr-util + +* Mon Aug 26 2002 Joe Orton 2.0.40-4 +- set SIGXFSZ disposition to "ignored" (#69520) +- make dummy connections to the first listener in config (#72692) + +* Mon Aug 26 2002 Joe Orton 2.0.40-3 +- allow "apachectl configtest" on a 1.3 httpd.conf +- add mod_deflate +- enable LDAP support in apr-util +- don't package everything in /var/www/error as config(noreplace) + +* Wed Aug 21 2002 Bill Nottingham 2.0.40-2 +- add trigger (#68657) + +* Mon Aug 12 2002 Joe Orton 2.0.40-1 +- update to 2.0.40 + +* Wed Jul 24 2002 Joe Orton 2.0.36-8 +- improve comment on use of UserDir in default config (#66886) + +* Wed Jul 10 2002 Joe Orton 2.0.36-7 +- use /sbin/nologin as shell for apache user (#68371) +- add patch from CVS to fix possible infinite loop when processing + internal redirects + +* Wed Jun 26 2002 Gary Benson 2.0.36-6 +- modify init script to detect 1.3.x httpd.conf's and direct users + to the migration guide + +* Tue Jun 25 2002 Gary Benson 2.0.36-5 +- patch apachectl to detect 1.3.x httpd.conf's and direct users + to the migration guide +- ship the migration guide + +* Fri Jun 21 2002 Joe Orton +- move /etc/httpd2 back to /etc/httpd +- add noindex.html page and poweredby logo; tweak default config + to load noindex.html if no default "/" page is present. +- add patch to prevent mutex errors on graceful restart + +* Fri Jun 21 2002 Tim Powers 2.0.36-4 +- automated rebuild + +* Wed Jun 12 2002 Joe Orton 2.0.36-3 +- add patch to fix SSL mutex handling + +* Wed Jun 12 2002 Joe Orton 2.0.36-2 +- improved config directory patch + +* Mon May 20 2002 Joe Orton +- initial build; based heavily on apache.spec and mod_ssl.spec +- fixes: #65214, #58490, #57376, #61265, #65518, #58177, #57245 diff --git a/trunk/build/rules.mk.in b/trunk/build/rules.mk.in new file mode 100644 index 0000000000..369b525990 --- /dev/null +++ b/trunk/build/rules.mk.in @@ -0,0 +1,235 @@ +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was originally provided by Sascha Schumann. + +@ap_make_include@ @ap_make_delimiter@$(top_builddir)/build/config_vars.mk@ap_make_delimiter@ + +# Combine all of the flags together in the proper order so that +# the user-defined flags can always override the configure ones, if needed. +# Note that includes are listed after the flags because -I options have +# left-to-right precedence and CPPFLAGS may include user-defined overrides. +# +ALL_CFLAGS = $(EXTRA_CFLAGS) $(NOTEST_CFLAGS) $(CFLAGS) +ALL_CPPFLAGS = $(DEFS) $(EXTRA_CPPFLAGS) $(NOTEST_CPPFLAGS) $(CPPFLAGS) +ALL_CXXFLAGS = $(EXTRA_CXXFLAGS) $(NOTEST_CXXFLAGS) $(CXXFLAGS) +ALL_LDFLAGS = $(EXTRA_LDFLAGS) $(NOTEST_LDFLAGS) $(LDFLAGS) +ALL_LIBS = $(EXTRA_LIBS) $(NOTEST_LIBS) $(LIBS) +ALL_INCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) + +# Compile commands + +BASE_CC = $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(ALL_INCLUDES) +BASE_CXX = $(CXX) $(ALL_CXXFLAGS) $(ALL_CPPFLAGS) $(ALL_INCLUDES) + +COMPILE = $(BASE_CC) @PICFLAGS@ +CXX_COMPILE = $(BASE_CXX) @PICFLAGS@ + +SH_COMPILE = $(LIBTOOL) --mode=compile $(BASE_CC) @SHLTCFLAGS@ -c $< && touch $@ +SH_CXX_COMPILE = $(LIBTOOL) --mode=compile $(BASE_CXX) @SHLTCFLAGS@ -c $< && touch $@ + +LT_COMPILE = $(LIBTOOL) --mode=compile $(COMPILE) @LTCFLAGS@ -c $< && touch $@ +LT_CXX_COMPILE = $(LIBTOOL) --mode=compile $(CXX_COMPILE) @LTCFLAGS@ -c $< && touch $@ + +# Link-related commands + +LINK = $(LIBTOOL) --mode=link $(CC) $(ALL_CFLAGS) @PILDFLAGS@ $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ +SH_LINK = $(SH_LIBTOOL) --mode=link $(CC) $(ALL_CFLAGS) $(LT_LDFLAGS) $(ALL_LDFLAGS) $(SH_LDFLAGS) $(CORE_IMPLIB) $(SH_LIBS) -o $@ +MOD_LINK = $(LIBTOOL) --mode=link $(CC) $(ALL_CFLAGS) -static $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ + +# Cross compile commands + +# Helper programs + +MKINSTALLDIRS = $(abs_srcdir)/build/mkdir.sh +INSTALL = $(LIBTOOL) --mode=install $(abs_srcdir)/build/install.sh -c +INSTALL_DATA = $(INSTALL) -m 644 +INSTALL_PROGRAM = $(INSTALL) -m 755 $(INSTALL_PROG_FLAGS) + +# +# Standard build rules +# +all: all-recursive +depend: depend-recursive +clean: clean-recursive +distclean: distclean-recursive +extraclean: extraclean-recursive +install: install-recursive +shared-build: shared-build-recursive + +all-recursive install-recursive depend-recursive: + @otarget=`echo $@|sed s/-recursive//`; \ + list=' $(BUILD_SUBDIRS) $(SUBDIRS)'; \ + for i in $$list; do \ + if test -d "$$i"; then \ + target="$$otarget"; \ + echo "Making $$target in $$i"; \ + if test "$$i" = "."; then \ + made_local=yes; \ + target="local-$$target"; \ + fi; \ + (cd $$i && $(MAKE) $$target) || exit 1; \ + fi; \ + done; \ + if test "$$otarget" = "all" && test -z '$(TARGETS)'; then \ + made_local=yes; \ + fi; \ + if test "$$made_local" != "yes"; then \ + $(MAKE) "local-$$otarget" || exit 1; \ + fi + +clean-recursive distclean-recursive extraclean-recursive: + @otarget=`echo $@|sed s/-recursive//`; \ + list='$(CLEAN_SUBDIRS) $(SUBDIRS)'; \ + for i in $$list; do \ + if test -d "$$i"; then \ + target="$$otarget"; \ + echo "Making $$target in $$i"; \ + if test "$$i" = "."; then \ + made_local=yes; \ + target="local-$$target"; \ + fi; \ + (cd $$i && $(MAKE) $$target); \ + fi; \ + done; \ + if test "$$otarget" = "all" && test -z '$(TARGETS)'; then \ + made_local=yes; \ + fi; \ + if test "$$made_local" != "yes"; then \ + $(MAKE) "local-$$otarget"; \ + fi + +shared-build-recursive: + @if test `pwd` = "$(top_builddir)"; then \ + $(PRE_SHARED_CMDS) ; \ + fi; \ + list='$(SUBDIRS)'; for i in $$list; do \ + target="shared-build"; \ + if test "$$i" = "."; then \ + made_local=yes; \ + target="local-shared-build"; \ + fi; \ + if test "$$i" != "srclib"; then \ + (cd $$i && $(MAKE) $$target) || exit 1; \ + fi; \ + done; \ + if test -f 'modules.mk'; then \ + if test -n '$(SHARED_TARGETS)'; then \ + echo "Building shared: $(SHARED_TARGETS)"; \ + if test "$$made_local" != "yes"; then \ + $(MAKE) "local-shared-build" || exit 1; \ + fi; \ + fi; \ + fi; \ + if test `pwd` = "$(top_builddir)"; then \ + $(POST_SHARED_CMDS) ; \ + fi + +local-all: $(TARGETS) + +local-shared-build: $(SHARED_TARGETS) + +local-depend: x-local-depend + @if test -n "`ls $(srcdir)/*.c 2> /dev/null`"; then \ + rm -f .deps; \ + list='$(srcdir)/*.c'; \ + for i in $$list; do \ + $(MKDEP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) $$i | sed 's/\.o:/.lo:/' >> .deps; \ + done; \ + fi + +local-clean: x-local-clean + rm -f *.o *.lo *.slo *.obj *.a *.la $(CLEAN_TARGETS) $(TARGETS) + rm -rf .libs + +local-distclean: local-clean x-local-distclean + rm -f .deps Makefile $(DISTCLEAN_TARGETS) + +local-extraclean: local-distclean x-local-extraclean + @if test -n "$(EXTRACLEAN_TARGETS)"; then \ + echo "rm -f $(EXTRACLEAN_TARGETS)"; \ + rm -f $(EXTRACLEAN_TARGETS) ; \ + fi + +program-install: $(TARGETS) $(SHARED_TARGETS) + @if test -n '$(PROGRAMS)'; then \ + test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir); \ + list='$(PROGRAMS)'; for i in $$list; do \ + $(INSTALL_PROGRAM) $$i $(DESTDIR)$(sbindir); \ + done; \ + fi + +local-install: program-install $(INSTALL_TARGETS) + +# to be filled in by the actual Makefile if extra commands are needed +x-local-depend x-local-clean x-local-distclean x-local-extraclean: + +# +# Implicit rules for creating outputs from input files +# +CXX_SUFFIX = cpp +SHLIB_SUFFIX = so + +.SUFFIXES: +.SUFFIXES: .S .c .$(CXX_SUFFIX) .lo .o .s .y .l .slo .def .la + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.c.lo: + $(LT_COMPILE) + +.s.lo: + $(LT_COMPILE) + +.c.slo: + $(SH_COMPILE) + +.$(CXX_SUFFIX).lo: + $(LT_CXX_COMPILE) + +.$(CXX_SUFFIX).slo: + $(SH_CXX_COMPILE) + +.y.c: + $(YACC) $(YFLAGS) $< && mv y.tab.c $*.c + if test -f y.tab.h; then \ + if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ + else :; fi + +.l.c: + $(LEX) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ + +# Makes an import library from a def file +.def.la: + $(LIBTOOL) --mode=compile $(MK_IMPLIB) -o $@ $< + +# +# Dependencies +# +@ap_make_include@ @ap_make_delimiter@$(builddir)/.deps@ap_make_delimiter@ + +.PHONY: all all-recursive install-recursive local-all $(PHONY_TARGETS) \ + shared-build shared-build-recursive local-shared-build \ + depend depend-recursive local-depend x-local-depend \ + clean clean-recursive local-clean x-local-clean \ + distclean distclean-recursive local-distclean x-local-distclean \ + extraclean extraclean-recursive local-extraclean x-local-extraclean \ + install local-install $(INSTALL_TARGETS) + diff --git a/trunk/build/special.mk b/trunk/build/special.mk new file mode 100644 index 0000000000..87a2e67bcb --- /dev/null +++ b/trunk/build/special.mk @@ -0,0 +1,37 @@ +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +all: all-recursive + +include $(builddir)/modules.mk +TARGETS = $(static) +SHARED_TARGETS = $(shared) +INSTALL_TARGETS = install-modules + +install-modules: + @test -d $(DESTDIR)$(libexecdir) || $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir) + @builtin='$(BUILTIN_LIBS)'; \ + has_mod_so=`echo $$builtin|sed 's/^.*libmod_so.*$$/has_mod_so/'`; \ + if [ "x$$has_mod_so" = "xhas_mod_so" ]; then \ + list='$(shared)'; \ + for i in $$list; do \ + $(top_srcdir)/build/instdso.sh SH_LIBTOOL='$(SH_LIBTOOL)' $$i $(DESTDIR)$(libexecdir); \ + done; \ + fi + +include $(top_builddir)/build/rules.mk + diff --git a/trunk/build/sysv_makefile b/trunk/build/sysv_makefile new file mode 100755 index 0000000000..4d2ddae282 --- /dev/null +++ b/trunk/build/sysv_makefile @@ -0,0 +1,33 @@ +#! /bin/sh +# +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# The build environment was provided by Sascha Schumann. + +# cwd must be top_srcdir +test -f build/sysv_makefile || exit 2 + +test -f bsd_converted || exit 1 + +tmpfile=`mktemp /tmp/sysv_makefile.XXXXXX 2>/dev/null` || tmpfile="tmp.$$" +for i in build/*.mk; do + sed 's/^\.include "\(.*\)"/include \1/' $i >$tmpfile \ + && cp $tmpfile $i +done +rm -f $tmpfile + +rm bsd_converted +exit 0 diff --git a/trunk/build/win32/apache.ico b/trunk/build/win32/apache.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfb4f63ab622055cb72c4dae0b5e92d26ae69293 GIT binary patch literal 1078 zcmcIju};G<5PfNjzyl;ZLo=cN148YPHBuKO_?iYWFw)gSz9dT!18avebg)1XR-S9KOj6Gk zv(uF?DA~qy)uqsq?SBu?ZfF0LSxo!ltk!;7(v2^M`Y@jj)s>+aX)7CtJXpN@_u>m5 z^6Q(<(`Ut<|5q3t@_x~ge#?Xw=j8oxE*N!X0zt6dH?Na%a#iS#N zIAsQ@2yB>iMCD06QF?h^cc7uFX{Q>vdCQyb&RrKzZe8u-UP=OmJHp+!58k;4g7 0) { + if (match ($0, /^.*Copyright /)) { + copyright = substr($0, RLENGTH + 1); + } + if (match ($0, /^#define AP_SERVER_MAJORVERSION_NUMBER [^*]/)) { + ver_major = $3; + } + else if (match ($0, /^#define AP_SERVER_MINORVERSION_NUMBER [^*]/)) { + ver_minor = $3; + } + else if (match ($0, /^#define AP_SERVER_PATCHLEVEL_NUMBER [^*]/)) { + ver_patch = $3; + } + else if (match ($0, /^#define AP_SERVER_ADD_STRING [^"]+"/)) { + ver_patch_modifier = substr($3, 2, length($3) - 2); + } + } + + ver = ver_major "." ver_minor "." ver_patch ver_patch_modifier; + verc = ver_major "," ver_minor "," ver_patch; + if (build) { + sub(/-.*/, "", verc) + verc = verc "," build; + } else if (sub(/-dev/, ",0", verc)) { + ff = ff + 2; + } else if (!sub(/-alpha/, ",10", verc) \ + && !sub(/-beta/, ",100", verc) \ + && !sub(/-gold/, ",200", verc)) { + sub(/-.*/, "", verc); + verc = verc "," 0; + } + + if (length(vendor)) { + ff = ff + 8; + } + + if (length(icon)) { + print "1 ICON DISCARDABLE \"" icon "\""; + } + print "1 VERSIONINFO"; + print " FILEVERSION " verc ""; + print " PRODUCTVERSION " verc ""; + print " FILEFLAGSMASK 0x3fL"; + print "#if defined(_DEBUG)" + print " FILEFLAGS 0x" sprintf("%02x", ff + 1) "L"; + print "#else" + print " FILEFLAGS 0x" sprintf("%02x", ff) "L"; + print "#endif" + print " FILEOS 0x40004L"; + print " FILETYPE 0x1L"; + print " FILESUBTYPE 0x0L"; + print "BEGIN"; + print " BLOCK \"StringFileInfo\""; + print " BEGIN"; + print " BLOCK \"040904b0\""; + print " BEGIN"; + print " VALUE \"Comments\", "\ + "\"Licensed under the Apache License, Version 2.0 (the \"\"License\"\"); "\ + "you may not use this file except in compliance with the License. "\ + "You may obtain a copy of the License at\\r\\n\\r\\n"\ + "http://www.apache.org/licenses/LICENSE-2.0\\r\\n\\r\\n"\ + "Unless required by applicable law or agreed to in writing, "\ + "software distributed under the License is distributed on an "\ + "\"\"AS IS\"\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, "\ + "either express or implied. See the License for the specific "\ + "language governing permissions and limitations under the License.\\0\""; + print " VALUE \"CompanyName\", \"Apache Software Foundation\\0\""; + print " VALUE \"FileDescription\", \"" desc "\\0\""; + print " VALUE \"FileVersion\", \"" ver "\\0\""; + print " VALUE \"InternalName\", \"" file "\\0\""; + print " VALUE \"LegalCopyright\", \"Copyright " copyright "\\0\""; + print " VALUE \"OriginalFilename\", \"" file "\\0\""; + if (vendor) { + print " VALUE \"PrivateBuild\", \"" vendor "\\0\""; + } + if (special) { + print " VALUE \"SpecialBuild\", \"" vendor "\\0\""; + } + print " VALUE \"ProductName\", \"Apache HTTP Server\\0\""; + print " VALUE \"ProductVersion\", \"" ver "\\0\""; + print " END"; + print " END"; + print " BLOCK \"VarFileInfo\""; + print " BEGIN"; + print " VALUE \"Translation\", 0x409, 1200"; + print " END"; + print "END"; +} diff --git a/trunk/buildconf b/trunk/buildconf new file mode 100755 index 0000000000..89cff05b7f --- /dev/null +++ b/trunk/buildconf @@ -0,0 +1,207 @@ +#!/bin/sh +# +# Copyright 1999-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# buildconf: Build the support scripts needed to compile from a +# checked-out version of the source code. + +# set a couple of defaults for where we should be looking for our support libs. +# can be overridden with --with-apr=[dir] and --with-apr-util=[dir] + +apr_src_dir="srclib/apr ../apr" +apu_src_dir="srclib/apr-util ../apr-util" + +while test $# -gt 0 +do + # Normalize + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case "$1" in + --with-apr=*) + apr_src_dir=$optarg + ;; + esac + + case "$1" in + --with-apr-util=*) + apu_src_dir=$optarg + ;; + esac + + shift +done + +# +# Check to be sure that we have the srclib dependencies checked-out +# + +should_exit=0 +apr_found=0 +apu_found=0 + +for dir in $apr_src_dir +do + if [ -d "${dir}" -a -f "${dir}/build/apr_common.m4" ]; then + echo "found apr source: ${dir}" + apr_src_dir=$dir + apr_found=1 + break + fi +done + +if [ $apr_found -lt 1 ]; then + echo "" + echo "You don't have a copy of the apr source in srclib/apr. " + echo "Please get the source using the following instructions," + echo "or specify the location of the source with " + echo "--with-apr=[path to apr] :" + echo "" + echo " svn co http://svn.apache.org/repos/asf/apr/apr/trunk srclib/apr" + echo "" + should_exit=1 +fi + +for dir in $apu_src_dir +do + if [ -d "${dir}" -a -f "${dir}/Makefile.in" ]; then + echo "found apr-util source: ${dir}" + apu_src_dir=$dir + apu_found=1 + break + fi +done + +if [ $apu_found -lt 1 ]; then + echo "" + echo "You don't have a copy of the apr-util source in srclib/apr-util. " + echo "Please get one the source using the following instructions, " + echo "or specify the location of the source with " + echo "--with-apr-util=[path to apr-util]:" + echo "" + echo " svn co http://svn.apache.org/repos/asf/apr/apr-util/trunk srclib/apr-util" + echo "" + should_exit=1 +fi + +if [ $should_exit -gt 0 ]; then + exit 1 +fi + +# These are temporary until Roy finishes the other build changes +# +touch .deps +rm -f aclocal.m4 +rm -f generated_lists +rm -f srclib/pcre/aclocal.m4 + +# Remove autoconf 2.5x cache directories +rm -rf autom4te*.cache srclib/pcre/autom4te*.cache + +case "`uname`" in +*BSD/OS*) + ./build/bsd_makefile;; +esac +# +# end temporary stuff + +apr_configure="$apr_src_dir/configure" +aprutil_configure="$apu_src_dir/configure" +pcre_configure="srclib/pcre/configure" +config_h_in="include/ap_config_auto.h.in" + +cross_compile_warning="warning: AC_TRY_RUN called without default to allow cross compiling" + +if [ -d srclib/apr ]; then + echo rebuilding $apr_configure + (cd srclib/apr && ./buildconf) || { + echo "./buildconf failed for apr" + exit 1 + } + rm -f srclib/apr/apr.spec +fi + +if [ -d srclib/apr-util ]; then + echo rebuilding $aprutil_configure + (cd srclib/apr-util && ./buildconf) || { + echo "./buildconf failed for apr-util" + exit 1 + } + rm -f srclib/apr-util/apr-util.spec +fi + +echo copying build files +cp $apr_src_dir/build/config.guess $apr_src_dir/build/config.sub \ + $apr_src_dir/build/PrintPath $apr_src_dir/build/apr_common.m4 \ + $apr_src_dir/build/find_apr.m4 $apu_src_dir/build/find_apu.m4 build + +# Remove any libtool files so one can switch between libtool 1.3 +# and libtool 1.4 by simply rerunning the buildconf script. +(cd build ; rm -f ltconfig ltmain.sh) + +# Optionally copy libtool-1.3.x files +if [ -f $apr_src_dir/build/ltconfig ]; then + cp $apr_src_dir/build/ltconfig build +fi +if [ -f $apr_src_dir/build/ltmain.sh ]; then + cp $apr_src_dir/build/ltmain.sh build +fi + +echo rebuilding $pcre_configure +(cd srclib/pcre && ${AUTOCONF:-autoconf}) + +echo rebuilding $config_h_in +rm -f $config_h_in +${AUTOHEADER:-autoheader} 2>&1 | grep -v "$cross_compile_warning" + +echo rebuilding configure +rm -f config.cache +${AUTOCONF:-autoconf} 2>&1 | grep -v "$cross_compile_warning" + +# Remove autoconf 2.5x cache directories +rm -rf autom4te*.cache srclib/pcre/autom4te*.cache + +if [ -f `which cut` ]; then + echo rebuilding rpm spec file + ( VMMN=`build/get-version.sh mmn include/ap_mmn.h MODULE_MAGIC_NUMBER` + REVISION=`build/get-version.sh all include/ap_release.h AP_SERVER` + VERSION=`echo $REVISION | cut -d- -s -f1` + RELEASE=`echo $REVISION | cut -d- -s -f2` + if [ "x$VERSION" = "x" ]; then + VERSION=$REVISION + RELEASE=1 + fi + cat ./build/rpm/httpd.spec.in | \ + sed -e "s/APACHE_VERSION/$VERSION/" \ + -e "s/APACHE_RELEASE/$RELEASE/" \ + -e "s/APACHE_MMN/$VMMN/" \ + > httpd.spec ) +fi + +# ensure that the mod_ssl expression parser sources are never regenerated +# when running make +echo fixing timestamps for mod_ssl sources +cd modules/ssl +touch ssl_expr_parse.y +sleep 1 +touch ssl_expr_parse.c ssl_expr_parse.h ssl_expr_scan.l +sleep 1 +touch ssl_expr_scan.c +cd ../.. + +exit 0 diff --git a/trunk/config.layout b/trunk/config.layout new file mode 100644 index 0000000000..03cb8f5930 --- /dev/null +++ b/trunk/config.layout @@ -0,0 +1,324 @@ +## +## config.layout -- Pre-defined Installation Path Layouts +## +## Hints: +## - layouts can be loaded with configure's --enable-layout=ID option +## - when no --enable-layout option is given, the default layout is `Apache' +## - a trailing plus character (`+') on paths is replaced with a +## `/' suffix where is currently hardcoded to 'apache2'. +## (This may become a configurable parameter at some point.) +## + +# Classical Apache path layout. + + prefix: /usr/local/apache2 + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/bin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/modules + mandir: ${prefix}/man + sysconfdir: ${prefix}/conf + datadir: ${prefix} + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include + localstatedir: ${prefix} + runtimedir: ${localstatedir}/logs + logfiledir: ${localstatedir}/logs + proxycachedir: ${localstatedir}/proxy + + +# GNU standards conforming path layout. +# See FSF's GNU project `make-stds' document for details. + + prefix: /usr/local + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec + mandir: ${prefix}/man + sysconfdir: ${prefix}/etc+ + datadir: ${prefix}/share+ + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include+ + localstatedir: ${prefix}/var+ + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/log + proxycachedir: ${localstatedir}/proxy + + +# Mac OS X Server (Rhapsody) + + prefix: /Local/Library/WebServer + exec_prefix: /usr + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: /System/Library/Apache/Modules + mandir: ${exec_prefix}/share/man + sysconfdir: ${prefix}/Configuration + datadir: ${prefix} + installbuilddir: /System/Library/Apache/Build + errordir: /System/Library/Apache/Error + iconsdir: /System/Library/Apache/Icons + manualdir: /System/Library/Apache/Manual + htdocsdir: ${datadir}/Documents + cgidir: ${datadir}/CGI-Executables + includedir: /System/Library/Frameworks/Apache.framework/Versions/2.0/Headers + localstatedir: /var + runtimedir: ${prefix}/Logs + logfiledir: ${prefix}/Logs + proxycachedir: ${prefix}/ProxyCache + + +# Darwin/Mac OS Layout + + prefix: /usr + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec+ + mandir: ${prefix}/share/man + datadir: /Library/WebServer + sysconfdir: /etc+ + installbuilddir: ${prefix}/share/httpd/build + errordir: ${prefix}/share/httpd/error + iconsdir: ${prefix}/share/httpd/icons + htdocsdir: ${datadir}/Documents + manualdir: ${datadir}/share/httpd/manual + cgidir: ${datadir}/CGI-Executables + includedir: ${prefix}/include+ + localstatedir: /var + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/log+ + proxycachedir: ${runtimedir}/proxy + + +# Red Hat Linux 7.x layout + + prefix: /usr + exec_prefix: ${prefix} + bindir: ${prefix}/bin + sbindir: ${prefix}/sbin + libdir: ${prefix}/lib + libexecdir: ${prefix}/lib/apache + mandir: ${prefix}/man + sysconfdir: /etc/httpd/conf + datadir: /var/www + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/html + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include/apache + localstatedir: /var + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/log/httpd + proxycachedir: ${localstatedir}/cache/httpd + + +# According to the /opt filesystem conventions + + prefix: /opt/apache + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec + mandir: ${prefix}/man + sysconfdir: /etc${prefix} + datadir: ${prefix}/share + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include + localstatedir: /var${prefix} + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/logs + proxycachedir: ${localstatedir}/proxy + + +# BeOS layout... + + prefix: /boot/home/apache + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/bin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec + mandir: ${prefix}/man + sysconfdir: ${prefix}/conf + datadir: ${prefix} + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include + localstatedir: ${prefix} + runtimedir: ${localstatedir}/logs + logfiledir: ${localstatedir}/logs + proxycachedir: ${localstatedir}/proxy + + +# SuSE 6.x layout + + prefix: /usr + exec_prefix: ${prefix} + bindir: ${prefix}/bin + sbindir: ${prefix}/sbin + libdir: ${prefix}/lib + libexecdir: ${prefix}/lib/apache + mandir: ${prefix}/share/man + sysconfdir: /etc/httpd + datadir: /usr/local/httpd + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include/apache + localstatedir: /var/lib/httpd + runtimedir: /var/run + logfiledir: /var/log/httpd + proxycachedir: /var/cache/httpd + + +# BSD/OS layout + + prefix: /var/www + exec_prefix: /usr/contrib + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/bin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec/apache + mandir: ${exec_prefix}/man + sysconfdir: ${prefix}/conf + datadir: ${prefix} + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${exec_prefix}/include/apache + localstatedir: /var + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/log/httpd + proxycachedir: ${localstatedir}/proxy + + +# Solaris 8 Layout + + prefix: /usr/apache + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/bin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec + mandir: ${exec_prefix}/man + sysconfdir: /etc/apache + datadir: /var/apache + installbuilddir: ${datadir}/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/htdocs + manualdir: ${datadir}/manual + cgidir: ${datadir}/cgi-bin + includedir: ${exec_prefix}/include + localstatedir: ${prefix} + runtimedir: /var/run + logfiledir: ${datadir}/logs + proxycachedir: ${datadir}/proxy + + +# OpenBSD Layout + + prefix: /var/www + exec_prefix: /usr + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/lib/apache/modules + mandir: ${exec_prefix}/share/man + sysconfdir: ${prefix}/conf + datadir: ${prefix} + installbuilddir: ${prefix}/build + errordir: ${prefix}/error + iconsdir: ${prefix}/icons + htdocsdir: ${prefix}/htdocs + manualdir: ${datadir}/manual + cgidir: ${prefix}/cgi-bin + includedir: ${exec_prefix}/lib/apache/include + localstatedir: ${prefix} + runtimedir: ${prefix}/logs + logfiledir: ${prefix}/logs + proxycachedir: ${prefix}/proxy + + +# FreeBSD Layout + + prefix: /usr/local + exec_prefix: ${prefix} + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec/apache2 + mandir: ${prefix}/man + sysconfdir: ${prefix}/etc/apache2 + datadir: ${prefix}/www + installbuilddir: ${prefix}/share/apache2/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${datadir}/data + manualdir: ${prefix}/share/doc/apache2 + cgidir: ${datadir}/cgi-bin + includedir: ${prefix}/include/apache2 + localstatedir: /var + runtimedir: ${localstatedir}/run + logfiledir: ${localstatedir}/log + proxycachedir: ${datadir}/proxy + + +# Debian layout + + prefix: + exec_prefix: ${prefix}/usr + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/lib/apache2/modules + mandir: ${exec_prefix}/share/man + sysconfdir: ${prefix}/etc/apache2 + datadir: ${exec_prefix}/share/apache2 + iconsdir: ${datadir}/icons + htdocsdir: ${prefix}/usr/share/apache2/default-site/htdocs + manualdir: ${htdocsdir}/manual + cgidir: ${prefix}/usr/lib/cgi-bin + includedir: ${exec_prefix}/include/apache2 + localstatedir: ${prefix}/var/run + runtimedir: ${prefix}/var/run + logfiledir: ${prefix}/var/log/apache2 + proxycachedir: ${prefix}/var/cache/apache2/proxy + infodir: ${exec_prefix}/share/info + installbuilddir: ${prefix}/etc/apache2/build + errordir: ${datadir}/error + diff --git a/trunk/configure.in b/trunk/configure.in new file mode 100644 index 0000000000..c7e43e9a32 --- /dev/null +++ b/trunk/configure.in @@ -0,0 +1,673 @@ +dnl +dnl Autoconf configuration for Apache httpd +dnl +dnl Use ./buildconf to produce a configure script +dnl + +AC_PREREQ(2.13) +AC_INIT(ABOUT_APACHE) + +AC_CONFIG_HEADER(include/ap_config_auto.h) +AC_CONFIG_AUX_DIR(build) + +dnl # +dnl # Include our own M4 macros along with those for APR and libtool +dnl # +sinclude(build/apr_common.m4) +sinclude(build/find_apr.m4) +sinclude(build/find_apu.m4) +sinclude(acinclude.m4) + +dnl XXX we can't just use AC_PREFIX_DEFAULT because that isn't subbed in +dnl by configure until it is too late. Is that how it should be or not? +dnl Something seems broken here. +AC_PREFIX_DEFAULT(/usr/local/apache2) + +dnl Get the layout here, so we can pass the required variables to apr +APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir]) + +dnl reparse the configure arguments. +APR_PARSE_ARGUMENTS + +dnl export expanded and relative configure argument variables +APACHE_EXPORT_ARGUMENTS + +dnl Save user-defined environment settings for later restoration +dnl +APR_SAVE_THE_ENVIRONMENT(CPPFLAGS) +APR_SAVE_THE_ENVIRONMENT(CFLAGS) +APR_SAVE_THE_ENVIRONMENT(CXXFLAGS) +APR_SAVE_THE_ENVIRONMENT(LDFLAGS) +APR_SAVE_THE_ENVIRONMENT(LIBS) +APR_SAVE_THE_ENVIRONMENT(INCLUDES) + +dnl Generate ./config.nice for reproducing runs of configure +dnl +APR_CONFIG_NICE(config.nice) + +nl=' +' +dnl Check that mkdir -p works +APR_MKDIR_P_CHECK($top_srcdir/build/mkdir.sh) + +dnl ## Run configure for packages Apache uses + +dnl shared library support for these packages doesn't currently +dnl work on some platforms + +AC_CANONICAL_SYSTEM + +orig_prefix="$prefix" + +echo $ac_n "${nl}Configuring Apache Portable Runtime library ...${nl}" + +APR_FIND_APR("$srcdir/srclib/apr", "./srclib/apr", 1, 1) + +if test "$apr_found" = "no"; then + AC_MSG_ERROR([APR not found. Please read the documentation.]) +fi + +if test "$apr_found" = "reconfig"; then + APR_SUBDIR_CONFIG(srclib/apr, + [$apache_apr_flags --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir --datadir=$datadir --with-installbuilddir=$installbuilddir], + [--enable-layout=*|\'--enable-layout=*]) + dnl We must be the first to build and the last to be cleaned + AP_BUILD_SRCLIB_DIRS="apr $AP_BUILD_SRCLIB_DIRS" + AP_CLEAN_SRCLIB_DIRS="$AP_CLEAN_SRCLIB_DIRS apr" +fi + +APR_SETIFNULL(CC, `$apr_config --cc`) +APR_SETIFNULL(CPP, `$apr_config --cpp`) +APR_ADDTO(CFLAGS, `$apr_config --cflags`) +APR_ADDTO(CPPFLAGS, `$apr_config --cppflags`) +APR_ADDTO(LDFLAGS, `$apr_config --ldflags`) +SHLIBPATH_VAR=`$apr_config --shlib-path-var` +APR_BINDIR=`$apr_config --bindir` +APR_INCLUDEDIR=`$apr_config --includedir` +APR_VERSION=`$apr_config --version` +APR_CONFIG="$APR_BINDIR/apr-`echo ${APR_VERSION} | sed 's,\..*,,'`-config" + +echo $ac_n "${nl}Configuring Apache Portable Runtime Utility library...${nl}" + +APR_FIND_APU("$srcdir/srclib/apr-util", "./srclib/apr-util", 1, 1) + +if test "$apu_found" = "no"; then + AC_MSG_ERROR([APR-util not found. Please read the documentation.]) +fi + +# Catch some misconfigurations: +case ${apr_found}.${apu_found} in +reconfig.yes) + AC_MSG_ERROR([Cannot use an external APR-util with the bundled APR]) + ;; +yes.reconfig) + AC_MSG_ERROR([Cannot use an external APR with the bundled APR-util]) + ;; +esac + +if test "$apu_found" = "reconfig"; then + APR_SUBDIR_CONFIG(srclib/apr-util, + [--with-apr=../apr --prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir], + [--enable-layout=*|\'--enable-layout=*]) + dnl We must be the last to build and the first to be cleaned + AP_BUILD_SRCLIB_DIRS="$AP_BUILD_SRCLIB_DIRS apr-util" + AP_CLEAN_SRCLIB_DIRS="apr-util $AP_CLEAN_SRCLIB_DIRS" +fi + +APR_ADDTO(LDFLAGS, `$apu_config --ldflags`) +APU_BINDIR=`$apu_config --bindir` +APU_INCLUDEDIR=`$apu_config --includedir` +APU_VERSION=`$apu_config --version` +APU_CONFIG="$APU_BINDIR/apu-`echo ${APU_VERSION} | sed 's,\..*,,'`-config" + +dnl In case we picked up CC and CPP from APR, get that info into the +dnl config cache so that PCRE uses it. Otherwise, CC and CPP used for +dnl PCRE and for our config tests will be whatever PCRE determines. +AC_PROG_CC +AC_PROG_CPP + +if test "x${cache_file}" = "x/dev/null"; then + # Likewise, ensure that CC and CPP are passed through to the pcre + # configure script iff caching is disabled (the autoconf 2.5x default). + export CC; export CPP +fi + +dnl Absolute source/build directory +abs_srcdir=`(cd $srcdir && pwd)` +abs_builddir=`pwd` + +AC_ARG_WITH(pcre, +APACHE_HELP_STRING(--with-pcre=PATH,Use external PCRE library)) + +case $with_pcre in +yes) AC_PATH_PROG(PCRE_CONFIG, pcre-config, false) ;; + /*) if test -d "$with_pcre" && test -x "$with_pcre/bin/pcre-config"; then + PCRE_CONFIG=$with_pcre/bin/pcre-config + elif test -x "$with_pcre"; then + PCRE_CONFIG=$with_pcre + fi + + if $PCRE_CONFIG --version >&/dev/null; then :; else + AC_MSG_ERROR([Did not find pcre-config script at $PCRE_CONFIG]) + fi + ;; +*) PCRE_CONFIG=false ;; +esac + +if test "$PCRE_CONFIG" != "false"; then + AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) + APR_ADDTO(CFLAGS, [`$PCRE_CONFIG --cflags`]) + APR_ADDTO(LIBS, [`$PCRE_CONFIG --libs`]) +else + # Build the bundled PCRE + AC_MSG_NOTICE([Configuring PCRE regular expression library]) + + APR_SUBDIR_CONFIG(srclib/pcre, + [--prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir]) + + APR_ADDTO(AP_LIBS, [$abs_builddir/srclib/pcre/libpcre.la]) + APR_ADDTO(CPPFLAGS, [-I$abs_builddir/srclib/pcre]) + + AP_BUILD_SRCLIB_DIRS="$AP_BUILD_SRCLIB_DIRS pcre" + AP_CLEAN_SRCLIB_DIRS="$AP_CLEAN_SRCLIB_DIRS pcre" +fi + +echo $ac_n "${nl}Configuring Apache httpd ...${nl}" + +dnl If the source dir is not equal to the build dir, +dnl then we are running in VPATH mode. + +APR_ADDTO(INCLUDES, [-I.]) + +if test "$abs_builddir" != "$abs_srcdir"; then + APR_ADDTO(INCLUDES, [-I\$(top_builddir)/include]) +fi + +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/os/\$(OS_DIR) -I\$(top_srcdir)/server/mpm/\$(MPM_SUBDIR_NAME) -I\$(top_srcdir)/modules/http -I\$(top_srcdir)/modules/filters -I\$(top_srcdir)/modules/proxy -I\$(top_srcdir)/include -I\$(top_srcdir)/modules/generators -I\$(top_srcdir)/modules/mappers]) + +# apr/apr-util --includes may pick up system paths for dependent +# libraries, so ensure these are later in INCLUDES than local source +# directories. +APR_ADDTO(INCLUDES, `$apr_config --includes`) +APR_ADDTO(INCLUDES, `$apu_config --includes`) + +echo $ac_n "${nl}Applying OS-specific hints for httpd ...${nl}" + +case $host in + *os2*) + # Use a custom made libtool replacement + echo "using aplibtool" + LIBTOOL="$abs_srcdir/srclib/apr/build/aplibtool" + SH_LIBTOOL="$LIBTOOL --shared --export-all" + SH_LIBS="\$(ALL_LIBS)" + CORE_IMPLIB_FILE="ApacheCoreOS2.la" + CORE_IMPLIB="$abs_srcdir/server/$CORE_IMPLIB_FILE" + MK_IMPLIB="emximp" + other_targets="$other_targets os2core" + INSTALL_PROG_FLAGS="-e .exe" + SHLTCFLAGS="" + LTCFLAGS="" + ;; + *) + if test "x$LTFLAGS" = "x"; then + LTFLAGS='--silent' + fi + my_libtool=`$apr_config --apr-libtool` + LIBTOOL="$my_libtool \$(LTFLAGS)" + libtoolversion=`$my_libtool --version` + case $libtoolversion in + *1.[[45]]*) + SH_LIBTOOL='$(LIBTOOL)' + SHLTCFLAGS="-prefer-pic" + LTCFLAGS="-prefer-non-pic -static" + ;; + *) + SH_LIBTOOL='$(SHELL) $(top_builddir)/shlibtool $(LTFLAGS)' + SHLTCFLAGS="" + LTCFLAGS="" + ;; + esac + ;; +esac +APACHE_SUBST(SHLTCFLAGS) +APACHE_SUBST(LTCFLAGS) + +AP_SIG_GRACEFUL=USR1 + +case $host in + *-apple-aux3*) + APR_SETVAR(APACHE_MPM, [prefork]) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + *-beos*) + APR_SETVAR(APACHE_MPM, [beos]) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + *os2-emx*) + APR_SETVAR(APACHE_MPM, [mpmt_os2]) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + *-linux-*) + case `uname -r` in + 2.0* ) + AP_SIG_GRACEFUL=WINCH + ;; + 2.[[2-9]]* ) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + * ) + ;; + esac + ;; + *486-*-bsdi* | *-netbsd* | *-freebsd* | *-apple-darwin* | *-dec-osf* | *-qnx) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + *-solaris2*) + dnl This is a hack -- we should be using AC_TRY_RUN instead + ap_platform_runtime_link_flag="-R" + dnl solaris 8 and above don't have a thundering herd + dnl not sure about rev's before this one. + case `uname -r` in + 5.[567]*) + ;; + * ) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + esac + ;; + *cygwin*) + APR_SETVAR(APACHE_MPM, [prefork]) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; + *aix*) + aixver=`echo $host | sed 's/^[[^0-9]]*//' | sed 's/\.//g'` + if test $aixver -ge 4320; then + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + fi + ;; + *os390*) + APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1]) + ;; +esac + +APR_SETVAR(AP_NONBLOCK_WHEN_MULTI_LISTEN, [1]) + +dnl +dnl Process command line arguments. This is done early in the process so the +dnl user can get feedback quickly in case of an error. +dnl +dnl ### need to move some of the arguments "up here" + +dnl ## Check for programs + +AC_PATH_PROG(RM, rm) +AC_PATH_PROG(PKGCONFIG, pkg-config) +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_LN_S +AC_CHECK_TOOL(RANLIB, ranlib, true) +dnl AC_PATH_PROG(PERL_PATH, perl) +AC_CHECK_PROGS(LYNX_PATH,[lynx links elinks], [lynx]) + +dnl various OS checks that apparently set required flags +AC_AIX +AC_ISC_POSIX +AC_MINIX + +dnl Check for what we can generate dependency files with +APR_CHECK_DEPEND + +dnl ## Check for libraries + +dnl ## Check for header files + +dnl I think these are just used all over the place, so just check for +dnl them at the base of the tree. If some are specific to a single +dnl directory, they should be moved (Comment #Spoon) + +dnl Regarding standard header files: AC_HEADER_STDC doesn't set symbols +dnl HAVE_STRING_H, HAVE_STDLIB_H, etc., so those are checked for +dnl explicitly so that the normal HAVE_xxx_H symbol is defined. + +AC_HEADER_STDC +AC_CHECK_HEADERS( \ +string.h \ +limits.h \ +unistd.h \ +sys/socket.h \ +pwd.h \ +grp.h \ +strings.h \ +sys/prctl.h \ +sys/processor.h \ +sys/sem.h +) +AC_HEADER_SYS_WAIT + +dnl ## Check for typedefs, structures, and compiler characteristics. + +AC_C_CONST +if test "x$GCC" = "xyes"; then + AC_DEFINE([AP_HAVE_DESIGNATED_INITIALIZER], 1, + [Define if the compiler supports designated initializers]) +fi + +dnl ## Check for library functions +AC_SEARCH_LIBS(sqrt, m) + +dnl See Comment #Spoon + +AC_CHECK_FUNCS( \ +getpwnam \ +getgrnam \ +initgroups \ +bindprocessor \ +prctl \ +timegm \ +) + +dnl ## Check for the tm_gmtoff field in struct tm to get the timezone diffs +AC_CACHE_CHECK([for tm_gmtoff in struct tm], ac_cv_struct_tm_gmtoff, +[AC_TRY_COMPILE([#include +#include ], [struct tm tm; tm.tm_gmtoff;], + ac_cv_struct_tm_gmtoff=yes, ac_cv_struct_tm_gmtoff=no)]) +if test "$ac_cv_struct_tm_gmtoff" = "yes"; then + AC_DEFINE(HAVE_GMTOFF, 1, [Define if struct tm has a tm_gmtoff field]) +fi + +dnl ## Set up any appropriate OS-specific environment variables for apachectl + +case $host in + *aix*) + # for 32-bit builds, increase MAXDATA to allow lots of threads + if test x$OBJECT_MODE != x64; then + OS_SPECIFIC_VARS="LDR_CNTRL=\"MAXDATA=0x80000000\" ; export LDR_CNTRL ;" + fi + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS AIXTHREAD_SCOPE=S ; export AIXTHREAD_SCOPE" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; AIXTHREAD_MUTEX_DEBUG=OFF ; export AIXTHREAD_MUTEX_DEBUG" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; AIXTHREAD_RWLOCK_DEBUG=OFF ; export AIXTHREAD_RWLOCK_DEBUG" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; AIXTHREAD_COND_DEBUG=OFF ; export AIXTHREAD_COND_DEBUG" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; SPINLOOPTIME=1000 ; export SPINLOOPTIME" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; YIELDLOOPTIME=8 ; export YIELDLOOPTIME" + OS_SPECIFIC_VARS="$OS_SPECIFIC_VARS ; MALLOCMULTIHEAP=considersize,heaps:8 ; export MALLOCMULTIHEAP" + ;; + *os390*) + OS_SPECIFIC_VARS="export _CEE_RUNOPTS=\"STACK(,,ANY)\" ; export _EDC_ADD_ERRNO2=1" + ;; + *) + OS_SPECIFIC_VARS="" +esac + +AC_ARG_WITH(port,APACHE_HELP_STRING(--with-port=PORT,Port on which to listen (default is 80)), + [if test "$withval" = "yes"; then AC_MSG_ERROR('option --with-port requires a value (the TCP port number)'); else PORT="$withval"; fi], + [PORT=80]) + +APR_CHECK_APR_DEFINE(APR_HAVE_IPV6) + +AC_ARG_ENABLE(v4-mapped,APACHE_HELP_STRING(--enable-v4-mapped,Allow IPv6 sockets to handle IPv4 connections), +[ + v4mapped=$enableval +], +[ + case $host in + *freebsd5*|*netbsd*|*openbsd*) + v4mapped=no + ;; + *) + v4mapped=yes + ;; +esac +]) + +if test $v4mapped = "yes" -a $ac_cv_define_APR_HAVE_IPV6 = "yes"; then + AC_DEFINE(AP_ENABLE_V4_MAPPED, 1, + [Allow IPv4 connections on IPv6 listening sockets]) +fi + +AC_ARG_ENABLE(exception-hook,APACHE_HELP_STRING(--enable-exception-hook,Enable fatal exception hook), +[ + AC_DEFINE(AP_ENABLE_EXCEPTION_HOOK, 1, + [Allow modules to run hook after a fatal exception]) +])dnl + +AC_ARG_ENABLE(maintainer-mode,APACHE_HELP_STRING(--enable-maintainer-mode,Turn on debugging and compile time warnings), +[ + APR_ADDTO(CPPFLAGS, -DAP_DEBUG) +])dnl + +dnl Conditionally enable PIE support for GNU toolchains. +AC_ARG_ENABLE(pie,APACHE_HELP_STRING(--enable-pie,Build httpd as a Position Independent Executable)) +if test "$enable_pie" = "yes"; then + AC_CACHE_CHECK([whether $CC accepts PIE flags], [ap_cv_cc_pie], [ + save_CFLAGS=$CFLAGS + save_LDFLAGS=$LDFLAGS + CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + AC_TRY_RUN([static int foo[30000]; int main () { return 0; }], + [ap_cv_cc_pie=yes], [ap_cv_cc_pie=no], [ap_cv_cc_pie=yes]) + CFLAGS=$save_CFLAGS + LDFLAGS=$save_LDFLAGS + ]) + if test "$ap_cv_cc_pie" = "yes"; then + PICFLAGS="-fPIE" + PILDFLAGS="-pie" + else + AC_ERROR([--enable-pie requested but $CC failed using PIE flags]) + fi +fi +AC_SUBST(PICFLAGS) +AC_SUBST(PILDFLAGS) + +prefix="$orig_prefix" +APACHE_ENABLE_MODULES + +dnl reading config stubs +esyscmd(./build/config-stubs .) + +APACHE_SUBST(progname) +APACHE_SUBST(MPM_LIB) +APACHE_SUBST(OS) +APACHE_SUBST(OS_DIR) +APACHE_SUBST(BUILTIN_LIBS) +APACHE_SUBST(SHLIBPATH_VAR) +APACHE_SUBST(OS_SPECIFIC_VARS) + +PRE_SHARED_CMDS='echo ""' +POST_SHARED_CMDS='echo ""' + +dnl apache_need_shared tells us if Apache modules are being built as DSOs + +if test "$apache_need_shared" = "yes"; then + if test -f $ac_aux_dir/ltconfig; then + $SHELL $ac_aux_dir/ltconfig --output=shlibtool --disable-static --srcdir=$ac_aux_dir --cache-file=./config.cache $ac_aux_dir/ltmain.sh + fi + shared_build="shared-build" +fi + +dnl enable_so tells us if *any* modules can be built as DSOs + +if test "$enable_so" = "yes"; then + case $host in + *-ibm-aix*) + HTTPD_LDFLAGS="$HTTPD_LDFLAGS -Wl,-uXML_Parse -Wl,-bE:$abs_builddir/server/httpd.exp" + SH_LDFLAGS="$SH_LDFLAGS \$(EXTRA_LDFLAGS) \$(EXTRA_LIBS)" + UTIL_LDFLAGS="$UTIL_LDFLAGS -Wl,-uXML_Parse" + ;; + *beos) + SH_LDFLAGS='$(top_builddir)/_APP_' + PRE_SHARED_CMDS='ln -s $(top_builddir)/httpd $(top_builddir)/_APP_' + POST_SHARED_CMDS='rm $(top_builddir)/_APP_' + ;; + *os390) + HTTPD_LDFLAGS="$HTTPD_LDFLAGS --main=$abs_srcdir/server/main.o --core-dll=$abs_srcdir/apachecore.dll" + SH_LDFLAGS="$SH_LDFLAGS --core-dll=$abs_srcdir/apachecore.dll" + esac +fi + +APACHE_SUBST(PRE_SHARED_CMDS) +APACHE_SUBST(POST_SHARED_CMDS) +APACHE_SUBST(shared_build) + +AC_ARG_WITH(program-name, +APACHE_HELP_STRING(--with-program-name,alternate executable name),[ + progname="$withval" ], [ + progname="httpd"] ) + +# SuExec parameters +AC_ARG_WITH(suexec-bin, +APACHE_HELP_STRING(--with-suexec-bin,Path to suexec binary),[ + AC_DEFINE_UNQUOTED(SUEXEC_BIN, "$withval", [Path to suexec binary] ) +] ) + +AC_ARG_WITH(suexec-caller, +APACHE_HELP_STRING(--with-suexec-caller,User allowed to call SuExec),[ + AC_DEFINE_UNQUOTED(AP_HTTPD_USER, "$withval", [User allowed to call SuExec] ) ] ) + +AC_ARG_WITH(suexec-userdir, +APACHE_HELP_STRING(--with-suexec-userdir,User subdirectory),[ + AC_DEFINE_UNQUOTED(AP_USERDIR_SUFFIX, "$withval", [User subdirectory] ) ] ) + +AC_ARG_WITH(suexec-docroot, +APACHE_HELP_STRING(--with-suexec-docroot,SuExec root directory),[ + AC_DEFINE_UNQUOTED(AP_DOC_ROOT, "$withval", [SuExec root directory] ) ] ) + +AC_ARG_WITH(suexec-uidmin, +APACHE_HELP_STRING(--with-suexec-uidmin,Minimal allowed UID),[ + AC_DEFINE_UNQUOTED(AP_UID_MIN, $withval, [Minimum allowed UID] ) ] ) + +AC_ARG_WITH(suexec-gidmin, +APACHE_HELP_STRING(--with-suexec-gidmin,Minimal allowed GID),[ + AC_DEFINE_UNQUOTED(AP_GID_MIN, $withval, [Minimum allowed GID] ) ] ) + +AC_ARG_WITH(suexec-logfile, +APACHE_HELP_STRING(--with-suexec-logfile,Set the logfile),[ + AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file] ) ] ) + +AC_ARG_WITH(suexec-safepath, +APACHE_HELP_STRING(--with-suexec-safepath,Set the safepath),[ + AC_DEFINE_UNQUOTED(AP_SAFE_PATH, "$withval", [safe shell path for SuExec] ) ] ) + +AC_ARG_WITH(suexec-umask, +APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[ + AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] ) + +dnl APR should go after the other libs, so the right symbols can be picked up +AP_LIBS="$AP_LIBS `$apu_config --link-libtool --libs` `$apr_config --link-libtool --libs`" +APACHE_SUBST(AP_LIBS) +APACHE_SUBST(AP_BUILD_SRCLIB_DIRS) +APACHE_SUBST(AP_CLEAN_SRCLIB_DIRS) + +AC_DEFINE(AP_USING_AUTOCONF, 1, + [Using autoconf to configure Apache]) + +if test "$SINGLE_LISTEN_UNSERIALIZED_ACCEPT" = "1"; then + AC_DEFINE(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, 1, + [This platform doesn't suffer from the thundering herd problem]) +fi + +if test "$AP_NONBLOCK_WHEN_MULTI_LISTEN" = "1"; then + AC_DEFINE(AP_NONBLOCK_WHEN_MULTI_LISTEN, 1, + [Listening sockets are non-blocking when there are more than 1]) +fi + +AC_DEFINE_UNQUOTED(AP_SIG_GRACEFUL, SIG$AP_SIG_GRACEFUL, [Signal used to gracefully restart]) +AC_DEFINE_UNQUOTED(AP_SIG_GRACEFUL_STRING, "SIG$AP_SIG_GRACEFUL", [Signal used to gracefully restart (as a quoted string)]) +AC_DEFINE_UNQUOTED(AP_SIG_GRACEFUL_SHORT, $AP_SIG_GRACEFUL, [Signal used to gracefully restart (without SIG prefix)]) +AP_SIG_GRACEFUL_SHORT=$AP_SIG_GRACEFUL +AP_SIG_GRACEFUL=SIG$AP_SIG_GRACEFUL_SHORT +AC_SUBST(AP_SIG_GRACEFUL) +AC_SUBST(AP_SIG_GRACEFUL_STRING) +AC_SUBST(AP_SIG_GRACEFUL_SHORT) + +APACHE_FAST_OUTPUT(Makefile modules/Makefile srclib/Makefile) +APACHE_FAST_OUTPUT(os/Makefile server/Makefile) +APACHE_FAST_OUTPUT(support/Makefile srclib/pcre/Makefile) + +if test -d ./test; then + APACHE_FAST_OUTPUT(test/Makefile) +fi + +dnl ## Finalize the variables +echo $ac_n "${nl}Restore user-defined environment settings...${nl}" + +APR_RESTORE_THE_ENVIRONMENT(CPPFLAGS, EXTRA_) +APR_RESTORE_THE_ENVIRONMENT(CFLAGS, EXTRA_) +APR_RESTORE_THE_ENVIRONMENT(CXXFLAGS, EXTRA_) +APR_RESTORE_THE_ENVIRONMENT(LDFLAGS, EXTRA_) +APR_RESTORE_THE_ENVIRONMENT(LIBS, EXTRA_) +APR_RESTORE_THE_ENVIRONMENT(INCLUDES, EXTRA_) + +echo $ac_n "${nl}Construct makefiles and header files...${nl}" + +APACHE_GEN_CONFIG_VARS + +dnl ## Build modules.c +rm -f modules.c +echo $MODLIST | $AWK -f $srcdir/build/build-modules-c.awk > modules.c + +APR_EXPAND_VAR(ap_prefix, $prefix) +AC_DEFINE_UNQUOTED(HTTPD_ROOT, "${ap_prefix}", + [Root directory of the Apache install area]) +AC_DEFINE_UNQUOTED(SERVER_CONFIG_FILE, "${rel_sysconfdir}/${progname}.conf", + [Location of the config file, relative to the Apache root directory]) +AC_DEFINE_UNQUOTED(AP_TYPES_CONFIG_FILE, "${rel_sysconfdir}/mime.types", + [Location of the MIME types config file, relative to the Apache root directory]) +AC_DEFINE_UNQUOTED(APACHE_MPM_DIR, "$MPM_DIR", + [Location of the source for the current MPM]) + +perlbin=`$ac_aux_dir/PrintPath perl` +if test "x$perlbin" = "x"; then + perlbin="/replace/with/path/to/perl/interpreter" +fi +AC_SUBST(perlbin) + +dnl If we are running on BSD/OS, we need to use the BSD .include syntax. + +BSD_MAKEFILE=no +ap_make_include=include +ap_make_delimiter=' ' +case $host in +*bsdi*) + # Check whether they've installed GNU make + if make --version > /dev/null 2>&1; then + true + else + BSD_MAKEFILE=yes + ap_make_include=.include + ap_make_delimiter='"' + fi + ;; +esac +AC_SUBST(ap_make_include) +AC_SUBST(ap_make_delimiter) + +dnl Ensure that docs/conf is created. +test -d docs/conf||$mkdir_p docs/conf + +dnl Ensure that the httpd version is included +HTTPD_VERSION=`$abs_srcdir/build/get-version.sh all $abs_srcdir/include/ap_release.h AP_SERVER` +AC_SUBST(HTTPD_VERSION) + +AC_OUTPUT($APACHE_OUTPUT_FILES docs/conf/httpd.conf docs/conf/extra/httpd-autoindex.conf docs/conf/extra/httpd-dav.conf docs/conf/extra/httpd-default.conf docs/conf/extra/httpd-info.conf docs/conf/extra/httpd-languages.conf docs/conf/extra/httpd-manual.conf docs/conf/extra/httpd-mpm.conf docs/conf/extra/httpd-multilang-errordoc.conf docs/conf/extra/httpd-ssl.conf docs/conf/extra/httpd-userdir.conf docs/conf/extra/httpd-vhosts.conf include/ap_config_layout.h support/apxs support/apachectl support/dbmmanage support/envvars-std support/log_server_status support/logresolve.pl support/phf_abuse_log.cgi support/split-logfile build/rules.mk build/pkg/pkginfo,[true],[ + APACHE_GEN_MAKEFILES +]) + +case $MPM_SUBDIR_NAME in +*experimental*) + echo "" + echo "" + echo "============================================================" + echo " WARNING: THE '${APACHE_MPM}' MPM IS EXPERIMENTAL" + echo "============================================================" + echo " The selected MPM might not be fully functional!" + echo "" + echo " Development of this MPM is not complete. Do not use this" + echo " MPM unless you are a programmer willing to help fix it." + echo "" + echo " If you are looking for a stable server, you should not use" + echo " the '${APACHE_MPM}' MPM until it is moved out of experimental." + echo "============================================================" + echo "" + echo "" + ;; +esac diff --git a/trunk/docs/STATUS b/trunk/docs/STATUS new file mode 100644 index 0000000000..17ac78a6e7 --- /dev/null +++ b/trunk/docs/STATUS @@ -0,0 +1,127 @@ +Apache HTTP Server 2.1 Documentation Status File. +Last modified: $Date$ + +For more information on how to contribute to the Apache Documentation +Project, please see http://httpd.apache.org/docs-project/ + + ------------------------------ + +Decisions pending +================= + +Things That Need Fixing +======================= + +- Windows platform docs are in desperate need of rewrites/updates for 2.0. + - Bill Rowe and Bill Stoddard are good contacts for tech questions. + - "using apache" has been done, "compiling apache" is still open + - hints on uninstalling apache (exit monitor, close directories, + registry entries etc) (PR 10154) + - FAQ: UTF-8 config and URL encoding for non-ascii characters. + - FAQ: AcceptEx failed / virusscanner, firewall fun + +- New Auth system + - Much clean-up and enhancement of aaa howto + - Independent note on how to upgrade to new auth system + +- modules docs + - mod_suexec: very little documentation + - mod_rewrite: explain, when which variables are actually available + (PR 16402) + +- MPM documentation + - explain what the following command line options do + (perhaps in the developer/debugging docs): + -D DEBUG + -D ONE_PROCESS + one-process-mode == no threads, i.e. only one + process handling the requests in a single loop? + -D NO_DETACH (not in every MPM avail.) + no daemon, but detached from terminal? + -D FOREGROUND (not in every MPM avail.) + ? + +- Individual docs will need some cleanup. + - misc/perf-tuning.html - needs major rewrite for 2.0 + - misc/rewriteguide.html - needs cleaning in 1.3 and 2.0 + - platform/ebcdic.xml - needs major rework for 2.0 + +- API documentation + - Ben Laurie has written some hooks documentation + - authn provider API documentation could be useful + +- SSL docs need serious update and enhancement + - compat docs are wrong + - no basic how to setup ssl doc + mads said he was working on this, but... + +- How does fit into sections.html? + +Documentation improvements +========================== + +* htdbm documentation has been added and just needs peer review (plus + translations). + +* Missing documentation for the support program checkgid + +* New user docs: Directory Handling (mod_dir/mod_autoindex/etc) + +* Enhancements to the DTD/XSL: + - tag that links to the glossary and uses some special + style in the css. + - New index: directives by context, including listing which directives + are available for each AllowOverride setting. + - New index: backout modules by type (aaa, mappers, loggers etc.) + probably by introducing a element in modulesynopsis + - Use a tag like in place of for things like the + listing. + - in progress + - add letter links to glossary and quickreference, + perhaps also a term overview (sidebar) + - remove

     elements. Use 
    and elements to get + a similar effect. + +* Improving the documentation of the documentations' build system + itself (requirements, procedures) + +* Improving the "security docs" + - More content and better organisation + - mod_dav ressources are owned by the httpd + +* Making site-specific enhancements easier, including a documented + and robust way for 3P module docco to be added -- and have it + survive a server docco upgrade + + - This could be something a simple and hackish as a manual/extra/ + directory (a la the 1.3 src/modules/extra/ directory) and a + script in the support directory that scans the files there and + updates the manual indices. (We do something like that now for + httpd.conf file with apxs [LoadModule, etc.].) + +* Provide example solutions for the mapping of encodings, especially + for .gz etc. (also in regard to our default configuration) + +* Several features in Apache require write-access to the filesystem. + Examples: CacheRoot, DavLockDB, ScriptLog + We should treat the things consistently in the docs, and perhaps + suggest the use of directory like /usr/local/apache2/var/ that is + httpd-writable. + +* Change the name 'Apache' to 'Apache HTTP Server' or 'http'. + +LaTeX Todo list +================== + +- Dozens of other little problems with presentation, cross-referencing, + etc. + +- Cleanup xsl to make it more readable. Almost everything + that is currently in latex.xsl should probably be moved to common.xsl. + There may be a license problem with the atbeginend.sty file, since + latex style files rarely have explict licenses. At worst, we can + drop this and manually adjust the relevant spacing. + +- Reduce the size of the pdf (both bytes and pages) in any way possible. + +- Translations. diff --git a/trunk/docs/cgi-examples/printenv b/trunk/docs/cgi-examples/printenv new file mode 100644 index 0000000000..e4c2140bcf --- /dev/null +++ b/trunk/docs/cgi-examples/printenv @@ -0,0 +1,13 @@ +#!/usr/local/bin/perl +## +## printenv -- demo CGI program which just prints its environment +## + +print "Content-type: text/plain; charset=iso-8859-1\n\n"; +foreach $var (sort(keys(%ENV))) { + $val = $ENV{$var}; + $val =~ s|\n|\\n|g; + $val =~ s|"|\\"|g; + print "${var}=\"${val}\"\n"; +} + diff --git a/trunk/docs/cgi-examples/test-cgi b/trunk/docs/cgi-examples/test-cgi new file mode 100644 index 0000000000..e27f857523 --- /dev/null +++ b/trunk/docs/cgi-examples/test-cgi @@ -0,0 +1,31 @@ +#!/bin/sh + +# disable filename globbing +set -f + +echo "Content-type: text/plain; charset=iso-8859-1" +echo + +echo CGI/1.0 test script report: +echo + +echo argc is $#. argv is "$*". +echo + +echo SERVER_SOFTWARE = $SERVER_SOFTWARE +echo SERVER_NAME = $SERVER_NAME +echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE +echo SERVER_PROTOCOL = $SERVER_PROTOCOL +echo SERVER_PORT = $SERVER_PORT +echo REQUEST_METHOD = $REQUEST_METHOD +echo HTTP_ACCEPT = "$HTTP_ACCEPT" +echo PATH_INFO = "$PATH_INFO" +echo PATH_TRANSLATED = "$PATH_TRANSLATED" +echo SCRIPT_NAME = "$SCRIPT_NAME" +echo QUERY_STRING = "$QUERY_STRING" +echo REMOTE_HOST = $REMOTE_HOST +echo REMOTE_ADDR = $REMOTE_ADDR +echo REMOTE_USER = $REMOTE_USER +echo AUTH_TYPE = $AUTH_TYPE +echo CONTENT_TYPE = $CONTENT_TYPE +echo CONTENT_LENGTH = $CONTENT_LENGTH diff --git a/trunk/docs/conf/charset.conv b/trunk/docs/conf/charset.conv new file mode 100644 index 0000000000..3cd6fa9d89 --- /dev/null +++ b/trunk/docs/conf/charset.conv @@ -0,0 +1,55 @@ + +# Lang-abbv Charset Language +#--------------------------------- +en ISO-8859-1 English +UTF-8 utf8 UTF-8 +Unicode ucs Unicode +th Cp874 Thai +ja SJIS Japanese +ko Cp949 Korean +zh Cp950 Chinese-Traditional +zh-cn GB2312 Chinese-Simplified +zh-tw Cp950 Chinese +cs ISO-8859-2 Czech +hu ISO-8859-2 Hungarian +hr ISO-8859-2 Croation +pl ISO-8859-2 Polish +ro ISO-8859-2 Romanian +sr ISO-8859-2 Serbian +sk ISO-8859-2 Slovak +sl ISO-8859-2 Slovenian +sq ISO-8859-2 Albanian +bg ISO-8859-5 Bulgarian +be ISO-8859-5 Byelorussian +mk ISO-8859-5 Macedonian +ru ISO-8859-5 Russian +uk ISO-8859-5 Ukrainian +ca ISO-8859-1 Catalan +de ISO-8859-1 German +da ISO-8859-1 Danish +fi ISO-8859-1 Finnish +fr ISO-8859-1 French +es ISO-8859-1 Spanish +is ISO-8859-1 Icelandic +it ISO-8859-1 Italian +nl ISO-8859-1 Dutch +no ISO-8859-1 Norwegian +pt ISO-8859-1 Portuguese +sv ISO-8859-1 Swedish +af ISO-8859-1 Afrikaans +eu ISO-8859-1 Basque +fo ISO-8859-1 Faroese +gl ISO-8859-1 Galician +ga ISO-8859-1 Irish +gd ISO-8859-1 Scottish +mt ISO-8859-3 Maltese +eo ISO-8859-3 Esperanto +el ISO-8859-7 Greek +tr ISO-8859-9 Turkish +he ISO-8859-8 Hebrew +iw ISO-8859-8 Hebrew +ar ISO-8859-6 Arabic +et ISO-8859-1 Estonian +lv ISO-8859-2 Latvian +lt ISO-8859-2 Lithuanian + \ No newline at end of file diff --git a/trunk/docs/conf/extra/httpd-autoindex.conf.in b/trunk/docs/conf/extra/httpd-autoindex.conf.in new file mode 100644 index 0000000000..13b400d1ad --- /dev/null +++ b/trunk/docs/conf/extra/httpd-autoindex.conf.in @@ -0,0 +1,93 @@ +# +# Directives controlling the display of server-generated directory listings. +# +# Required modules: mod_autoindex, mod_alias +# +# To see the listing of a directory, the Options directive for the +# directory must include "Indexes", and the directory must not contain +# a file matching those listed in the DirectoryIndex directive. +# + +# +# IndexOptions: Controls the appearance of server-generated directory +# listings. +# +IndexOptions FancyIndexing VersionSort + +# We include the /icons/ alias for FancyIndexed directory listings. If +# you do not use FancyIndexing, you may comment this out. +# +Alias /icons/ "@exp_iconsdir@/" + + + Options Indexes MultiViews + AllowOverride None + Order allow,deny + Allow from all + + +# +# AddIcon* directives tell the server which icon to show for different +# files or filename extensions. These are only displayed for +# FancyIndexed directories. +# +AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip + +AddIconByType (TXT,/icons/text.gif) text/* +AddIconByType (IMG,/icons/image2.gif) image/* +AddIconByType (SND,/icons/sound2.gif) audio/* +AddIconByType (VID,/icons/movie.gif) video/* + +AddIcon /icons/binary.gif .bin .exe +AddIcon /icons/binhex.gif .hqx +AddIcon /icons/tar.gif .tar +AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv +AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip +AddIcon /icons/a.gif .ps .ai .eps +AddIcon /icons/layout.gif .html .shtml .htm .pdf +AddIcon /icons/text.gif .txt +AddIcon /icons/c.gif .c +AddIcon /icons/p.gif .pl .py +AddIcon /icons/f.gif .for +AddIcon /icons/dvi.gif .dvi +AddIcon /icons/uuencoded.gif .uu +AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl +AddIcon /icons/tex.gif .tex +AddIcon /icons/bomb.gif core + +AddIcon /icons/back.gif .. +AddIcon /icons/hand.right.gif README +AddIcon /icons/folder.gif ^^DIRECTORY^^ +AddIcon /icons/blank.gif ^^BLANKICON^^ + +# +# DefaultIcon is which icon to show for files which do not have an icon +# explicitly set. +# +DefaultIcon /icons/unknown.gif + +# +# AddDescription allows you to place a short description after a file in +# server-generated indexes. These are only displayed for FancyIndexed +# directories. +# Format: AddDescription "description" filename +# +#AddDescription "GZIP compressed document" .gz +#AddDescription "tar archive" .tar +#AddDescription "GZIP compressed tar archive" .tgz + +# +# ReadmeName is the name of the README file the server will look for by +# default, and append to directory listings. +# +# HeaderName is the name of a file which should be prepended to +# directory indexes. +ReadmeName README.html +HeaderName HEADER.html + +# +# IndexIgnore is a set of filenames which directory indexing should ignore +# and not include in the listing. Shell-style wildcarding is permitted. +# +IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t + diff --git a/trunk/docs/conf/extra/httpd-dav.conf.in b/trunk/docs/conf/extra/httpd-dav.conf.in new file mode 100644 index 0000000000..c4be814a13 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-dav.conf.in @@ -0,0 +1,46 @@ +# +# Distributed authoring and versioning (WebDAV) +# +# Required modules: mod_dav, mod_dav_fs, mod_setenvif, mod_alias +# mod_auth_digest, mod_authn_file +# + +# The following example gives DAV write access to a directory called +# "uploads" under the ServerRoot directory. +# +# The User/Group specified in httpd.conf needs to have write permissions +# on the directory where the DavLockDB is placed and on any directory where +# "Dav On" is specified. + +DavLockDB "@@ServerRoot@@/var/DavLock" + +Alias /uploads "@@ServerRoot@@/uploads" + + + Dav On + + AuthType Digest + AuthName DAV-upload + # You can use the htdigest program to create the password database: + # htdigest -c "@@ServerRoot@@/user.passwd" DAV-upload admin + AuthUserFile "@@ServerRoot@@/user.passwd" + + # Allow universal read-access, but writes are restricted + # to the admin user. + + require user admin + + + +# +# The following directives disable redirects on non-GET requests for +# a directory that does not include the trailing slash. This fixes a +# problem with several clients that do not appropriately handle +# redirects for folders with DAV methods. +# +BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully +BrowserMatch "MS FrontPage" redirect-carefully +BrowserMatch "^WebDrive" redirect-carefully +BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully +BrowserMatch "^gnome-vfs/1.0" redirect-carefully +BrowserMatch "^XML Spy" redirect-carefully diff --git a/trunk/docs/conf/extra/httpd-default.conf.in b/trunk/docs/conf/extra/httpd-default.conf.in new file mode 100644 index 0000000000..efeca0520f --- /dev/null +++ b/trunk/docs/conf/extra/httpd-default.conf.in @@ -0,0 +1,75 @@ +# +# This configuration file reflects default settings for Apache HTTP Server. +# +# You may change these, but chances are that you may not need to. +# + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + +# +# UseCanonicalName: Determines how Apache constructs self-referencing +# URLs and the SERVER_NAME and SERVER_PORT variables. +# When set "Off", Apache will use the Hostname and Port supplied +# by the client. When set "On", Apache will use the value of the +# ServerName directive. +# +UseCanonicalName Off + +# +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# ServerTokens +# This directive configures what you return as the Server HTTP response +# Header. The default is 'Full' which sends information about the OS-Type +# and compiled in modules. +# Set to one of: Full | OS | Minor | Minimal | Major | Prod +# where Full conveys the most information, and Prod the least. +# +ServerTokens Full + +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (internal error documents, FTP directory +# listings, mod_status and mod_info output etc., but not CGI generated +# documents or custom error documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +ServerSignature On + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off diff --git a/trunk/docs/conf/extra/httpd-info.conf.in b/trunk/docs/conf/extra/httpd-info.conf.in new file mode 100644 index 0000000000..db316c032e --- /dev/null +++ b/trunk/docs/conf/extra/httpd-info.conf.in @@ -0,0 +1,37 @@ +# +# Get information about the requests being processed by the server +# and the configuration of the server. +# +# Required modules: mod_status (for the server-status handler), +# mod_info (for the server-info handler) + +# +# Allow server status reports generated by mod_status, +# with the URL of http://servername/server-status +# Change the ".example.com" to match your domain to enable. + + + SetHandler server-status + Order deny,allow + Deny from all + Allow from .example.com + + +# +# 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 + +# +# Allow remote server configuration reports, with the URL of +# http://servername/server-info (requires that mod_info.c be loaded). +# Change the ".example.com" to match your domain to enable. +# + + SetHandler server-info + Order deny,allow + Deny from all + Allow from .example.com + diff --git a/trunk/docs/conf/extra/httpd-languages.conf.in b/trunk/docs/conf/extra/httpd-languages.conf.in new file mode 100644 index 0000000000..e7452bfdf4 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-languages.conf.in @@ -0,0 +1,139 @@ +# +# Settings for hosting different languages. +# +# Required modules: mod_mime, mod_negotiation + +# DefaultLanguage and AddLanguage allows you to specify the language of +# a document. You can then use content negotiation to give a browser a +# file in a language the user can understand. +# +# Specify a default language. This means that all data +# going out without a specific language tag (see below) will +# be marked with this one. You probably do NOT want to set +# this unless you are sure it is correct for all cases. +# +# * It is generally better to not mark a page as +# * being a certain language than marking it with the wrong +# * language! +# +# DefaultLanguage nl +# +# Note 1: The suffix does not have to be the same as the language +# keyword --- those with documents in Polish (whose net-standard +# language code is pl) may wish to use "AddLanguage pl .po" to +# avoid the ambiguity with the common suffix for perl scripts. +# +# Note 2: The example entries below illustrate that in some cases +# the two character 'Language' abbreviation is not identical to +# the two character 'Country' code for its country, +# E.g. 'Danmark/dk' versus 'Danish/da'. +# +# Note 3: In the case of 'ltz' we violate the RFC by using a three char +# specifier. There is 'work in progress' to fix this and get +# the reference data for rfc1766 cleaned up. +# +# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl) +# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de) +# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja) +# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn) +# Norwegian (no) - Polish (pl) - Portugese (pt) +# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv) +# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW) +# +AddLanguage ca .ca +AddLanguage cs .cz .cs +AddLanguage da .dk +AddLanguage de .de +AddLanguage el .el +AddLanguage en .en +AddLanguage eo .eo +AddLanguage es .es +AddLanguage et .et +AddLanguage fr .fr +AddLanguage he .he +AddLanguage hr .hr +AddLanguage it .it +AddLanguage ja .ja +AddLanguage ko .ko +AddLanguage ltz .ltz +AddLanguage nl .nl +AddLanguage nn .nn +AddLanguage no .no +AddLanguage pl .po +AddLanguage pt .pt +AddLanguage pt-BR .pt-br +AddLanguage ru .ru +AddLanguage sv .sv +AddLanguage zh-CN .zh-cn +AddLanguage zh-TW .zh-tw + +# LanguagePriority allows you to give precedence to some languages +# in case of a tie during content negotiation. +# +# Just list the languages in decreasing order of preference. We have +# more or less alphabetized them here. You probably want to change this. +# +LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW + +# +# ForceLanguagePriority allows you to serve a result page rather than +# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback) +# [in case no accepted languages matched the available variants] +# +ForceLanguagePriority Prefer Fallback + +# +# Commonly used filename extensions to character sets. You probably +# want to avoid clashes with the language extensions, unless you +# are good at carefully testing your setup after each change. +# See http://www.iana.org/assignments/character-sets for the +# official list of charset names and their respective RFCs. +# +AddCharset us-ascii.ascii .us-ascii +AddCharset ISO-8859-1 .iso8859-1 .latin1 +AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen +AddCharset ISO-8859-3 .iso8859-3 .latin3 +AddCharset ISO-8859-4 .iso8859-4 .latin4 +AddCharset ISO-8859-5 .iso8859-5 .cyr .iso-ru +AddCharset ISO-8859-6 .iso8859-6 .arb .arabic +AddCharset ISO-8859-7 .iso8859-7 .grk .greek +AddCharset ISO-8859-8 .iso8859-8 .heb .hebrew +AddCharset ISO-8859-9 .iso8859-9 .latin5 .trk +AddCharset ISO-8859-10 .iso8859-10 .latin6 +AddCharset ISO-8859-13 .iso8859-13 +AddCharset ISO-8859-14 .iso8859-14 .latin8 +AddCharset ISO-8859-15 .iso8859-15 .latin9 +AddCharset ISO-8859-16 .iso8859-16 .latin10 +AddCharset ISO-2022-JP .iso2022-jp .jis +AddCharset ISO-2022-KR .iso2022-kr .kis +AddCharset ISO-2022-CN .iso2022-cn .cis +AddCharset Big5.Big5 .big5 .b5 +AddCharset cn-Big5 .cn-big5 +# For russian, more than one charset is used (depends on client, mostly): +AddCharset WINDOWS-1251 .cp-1251 .win-1251 +AddCharset CP866 .cp866 +AddCharset KOI8 .koi8 +AddCharset KOI8-E .koi8-e +AddCharset KOI8-r .koi8-r .koi8-ru +AddCharset KOI8-U .koi8-u +AddCharset KOI8-ru .koi8-uk .ua +AddCharset ISO-10646-UCS-2 .ucs2 +AddCharset ISO-10646-UCS-4 .ucs4 +AddCharset UTF-7 .utf7 +AddCharset UTF-8 .utf8 +AddCharset UTF-16 .utf16 +AddCharset UTF-16BE .utf16be +AddCharset UTF-16LE .utf16le +AddCharset UTF-32 .utf32 +AddCharset UTF-32BE .utf32be +AddCharset UTF-32LE .utf32le +AddCharset euc-cn .euc-cn +AddCharset euc-gb .euc-gb +AddCharset euc-jp .euc-jp +AddCharset euc-kr .euc-kr +#Not sure how euc-tw got in - IANA doesn't list it??? +AddCharset EUC-TW .euc-tw +AddCharset gb2312 .gb2312 .gb +AddCharset iso-10646-ucs-2 .ucs-2 .iso-10646-ucs-2 +AddCharset iso-10646-ucs-4 .ucs-4 .iso-10646-ucs-4 +AddCharset shift_jis .shift_jis .sjis \ No newline at end of file diff --git a/trunk/docs/conf/extra/httpd-manual.conf.in b/trunk/docs/conf/extra/httpd-manual.conf.in new file mode 100644 index 0000000000..d20a93f086 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-manual.conf.in @@ -0,0 +1,27 @@ +# +# Provide access to the documentation on your server as +# http://yourserver.example.com/manual/ +# The documentation is always available at +# http://httpd.apache.org/docs-2.1/ +# +# Required modules: mod_alias, mod_setenvif, mod_negotiation +# + +AliasMatch ^/manual(?:/(?:de|en|es|fr|ja|ko|pt-br|ru))?(/.*)?$ "@exp_manualdir@$1" + + + Options Indexes + AllowOverride None + Order allow,deny + Allow from all + + + SetHandler type-map + + + SetEnvIf Request_URI ^/manual/(de|en|es|fr|ja|ko|pt-br|ru)/ prefer-language=$1 + RedirectMatch 301 ^/manual(?:/(de|en|es|fr|ja|ko|pt-br|ru)){2,}(/.*)?$ /manual/$1$2 + + LanguagePriority en de es fr ja ko pt-br ru + ForceLanguagePriority Prefer Fallback + diff --git a/trunk/docs/conf/extra/httpd-mpm.conf.in b/trunk/docs/conf/extra/httpd-mpm.conf.in new file mode 100644 index 0000000000..3f7b1b88a9 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-mpm.conf.in @@ -0,0 +1,125 @@ +# +# Server-Pool Management (MPM specific) +# + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# +# Note that this is the default PidFile for most MPMs. +# + + PidFile @rel_runtimedir@/httpd.pid + + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# + + +LockFile @rel_logfiledir@/accept.lock + + + +# +# Only one of the below sections will be relevant on your +# installed httpd. Use "apachectl -l" to find out the +# active mpm. +# + +# prefork MPM +# StartServers: number of server processes to start +# MinSpareServers: minimum number of server processes which are kept spare +# MaxSpareServers: maximum number of server processes which are kept spare +# MaxClients: maximum number of server processes allowed to start +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 10 + MaxClients 150 + MaxRequestsPerChild 0 + + +# worker MPM +# StartServers: initial number of server processes to start +# MaxClients: maximum number of simultaneous client connections +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# ThreadsPerChild: constant number of worker threads in each server process +# MaxRequestsPerChild: maximum number of requests a server process serves + + StartServers 2 + MaxClients 150 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadsPerChild 25 + MaxRequestsPerChild 0 + + +# perchild MPM +# NumServers: constant number of server processes +# StartThreads: initial number of worker threads in each server process +# MinSpareThreads: minimum number of worker threads which are kept spare +# MaxSpareThreads: maximum number of worker threads which are kept spare +# MaxThreadsPerChild: maximum number of worker threads in each server process +# MaxRequestsPerChild: maximum number of connections per server process + + NumServers 5 + StartThreads 5 + MinSpareThreads 5 + MaxSpareThreads 10 + MaxThreadsPerChild 20 + MaxRequestsPerChild 0 + + +# WinNT MPM +# ThreadsPerChild: constant number of worker threads in the server process +# MaxRequestsPerChild: maximum number of requests a server process serves + + ThreadsPerChild 250 + MaxRequestsPerChild 0 + + +# BeOS MPM +# StartThreads: how many threads do we initially spawn? +# MaxClients: max number of threads we can have (1 thread == 1 client) +# MaxRequestsPerThread: maximum number of requests each thread will process + + StartThreads 10 + MaxClients 50 + MaxRequestsPerThread 10000 + + +# NetWare MPM +# ThreadStackSize: Stack size allocated for each worker thread +# StartThreads: Number of worker threads launched at server startup +# MinSpareThreads: Minimum number of idle threads, to handle request spikes +# MaxSpareThreads: Maximum number of idle threads +# MaxThreads: Maximum number of worker threads alive at the same time +# MaxRequestsPerChild: Maximum number of requests a thread serves. It is +# recommended that the default value of 0 be set for this +# directive on NetWare. This will allow the thread to +# continue to service requests indefinitely. + + ThreadStackSize 65536 + StartThreads 250 + MinSpareThreads 25 + MaxSpareThreads 250 + MaxThreads 1000 + MaxRequestsPerChild 0 + MaxMemFree 100 + + +# OS/2 MPM +# StartServers: Number of server processes to maintain +# MinSpareThreads: Minimum number of idle threads per process, +# to handle request spikes +# MaxSpareThreads: Maximum number of idle threads per process +# MaxRequestsPerChild: Maximum number of connections per server process + + StartServers 2 + MinSpareThreads 5 + MaxSpareThreads 10 + MaxRequestsPerChild 0 + diff --git a/trunk/docs/conf/extra/httpd-multilang-errordoc.conf.in b/trunk/docs/conf/extra/httpd-multilang-errordoc.conf.in new file mode 100644 index 0000000000..d3192508b5 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-multilang-errordoc.conf.in @@ -0,0 +1,52 @@ +# +# The configuration below implements multi-language error documents through +# content-negotiation. +# +# Required modules: mod_alias, mod_include, mod_negotiation +# +# We use Alias to redirect any /error/HTTP_.html.var response to +# our collection of by-error message multi-language collections. We use +# includes to substitute the appropriate text. +# +# You can modify the messages' appearance without changing any of the +# default HTTP_.html.var files by adding the line: +# +# Alias /error/include/ "/your/include/path/" +# +# which allows you to create your own set of files by starting with the +# @exp_errordir@/include/ files and copying them to /your/include/path/, +# even on a per-VirtualHost basis. The default include files will display +# your Apache version number and your ServerAdmin email address regardless +# of the setting of ServerSignature. + +Alias /error/ "@exp_errordir@/" + + + AllowOverride None + Options IncludesNoExec + AddOutputFilter Includes html + AddHandler type-map var + Order allow,deny + Allow from all + LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr + ForceLanguagePriority Prefer Fallback + + +ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var +ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var +ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var +ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var +ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var +ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var +ErrorDocument 410 /error/HTTP_GONE.html.var +ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var +ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var +ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var +ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var +ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var +ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var +ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var +ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var +ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var +ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var + diff --git a/trunk/docs/conf/extra/httpd-ssl.conf.in b/trunk/docs/conf/extra/httpd-ssl.conf.in new file mode 100644 index 0000000000..9b181165ee --- /dev/null +++ b/trunk/docs/conf/extra/httpd-ssl.conf.in @@ -0,0 +1,231 @@ +# +# This is the Apache server configuration file providing SSL support. +# It contains the configuration directives to instruct the server how to +# serve pages over an https connection. For detailing information about these +# directives see +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# + +# +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the SSL library. +# The seed data should be of good random quality. +# WARNING! On some platforms /dev/random blocks if not enough entropy +# is available. This means you then cannot use the /dev/random device +# because it would lead to very long connection times (as long as +# it requires to make more entropy available). But usually those +# platforms additionally provide a /dev/urandom device which doesn't +# block. So, if available, use this one instead. Read the mod_ssl User +# Manual for more details. +# +#SSLRandomSeed startup file:/dev/random 512 +#SSLRandomSeed startup file:/dev/urandom 512 +#SSLRandomSeed connect file:/dev/random 512 +#SSLRandomSeed connect file:/dev/urandom 512 + + +# +# When we also provide SSL we have to listen to the +# standard HTTP port (see above) and to the HTTPS port +# +# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two +# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443" +# +Listen 443 + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# +# Some MIME-types for downloading Certificates and CRLs +# +AddType application/x-x509-ca-cert .crt +AddType application/x-pkcs7-crl .crl + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog builtin + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First the mechanism +# to use and second the expiring timeout (in seconds). +#SSLSessionCache dbm:@exp_runtimedir@/ssl_scache +SSLSessionCache shmcb:@exp_runtimedir@/ssl_scache(512000) +SSLSessionCacheTimeout 300 + +# Semaphore: +# Configure the path to the mutual exclusion semaphore the +# SSL engine uses internally for inter-process synchronization. +SSLMutex file:@exp_runtimedir@/ssl_mutex + +## +## SSL Virtual Host Context +## + + + +# General setup for the virtual host +DocumentRoot "@exp_htdocsdir@" +ServerName www.example.com:443 +ServerAdmin you@example.com +ErrorLog @exp_logfiledir@/error_log +TransferLog @exp_logfiledir@/access_log + +# SSL Engine Switch: +# Enable/Disable SSL for this virtual host. +SSLEngine on + +# SSL Cipher Suite: +# List the ciphers that the client is permitted to negotiate. +# See the mod_ssl documentation for a complete list. +SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + +# Server Certificate: +# Point SSLCertificateFile at a PEM encoded certificate. If +# the certificate is encrypted, then you will be prompted for a +# pass phrase. Note that a kill -HUP will prompt again. Keep +# in mind that if you have both an RSA and a DSA certificate you +# can configure both in parallel (to also allow the use of DSA +# ciphers, etc.) +SSLCertificateFile @exp_sysconfdir@/server.crt +#SSLCertificateFile @exp_sysconfdir@/server-dsa.crt + +# Server Private Key: +# If the key is not combined with the certificate, use this +# directive to point at the key file. Keep in mind that if +# you've both a RSA and a DSA private key you can configure +# both in parallel (to also allow the use of DSA ciphers, etc.) +SSLCertificateKeyFile @exp_sysconfdir@/server.key +#SSLCertificateKeyFile @exp_sysconfdir@/server-dsa.key + +# Server Certificate Chain: +# Point SSLCertificateChainFile at a file containing the +# concatenation of PEM encoded CA certificates which form the +# certificate chain for the server certificate. Alternatively +# the referenced file can be the same as SSLCertificateFile +# when the CA certificates are directly appended to the server +# certificate for convinience. +#SSLCertificateChainFile @exp_sysconfdir@/server-ca.crt + +# Certificate Authority (CA): +# Set the CA certificate verification path where to find CA +# certificates for client authentication or alternatively one +# huge file containing all of them (file must be PEM encoded) +# Note: Inside SSLCACertificatePath you need hash symlinks +# to point to the certificate files. Use the provided +# Makefile to update the hash symlinks after changes. +#SSLCACertificatePath @exp_sysconfdir@/ssl.crt +#SSLCACertificateFile @exp_sysconfdir@/ssl.crt/ca-bundle.crt + +# Certificate Revocation Lists (CRL): +# Set the CA revocation path where to find CA CRLs for client +# authentication or alternatively one huge file containing all +# of them (file must be PEM encoded) +# Note: Inside SSLCARevocationPath you need hash symlinks +# to point to the certificate files. Use the provided +# Makefile to update the hash symlinks after changes. +#SSLCARevocationPath @exp_sysconfdir@/ssl.crl +#SSLCARevocationFile @exp_sysconfdir@/ssl.crl/ca-bundle.crl + +# Client Authentication (Type): +# Client certificate verification type and depth. Types are +# none, optional, require and optional_no_ca. Depth is a +# number which specifies how deeply to verify the certificate +# issuer chain before deciding the certificate is not valid. +#SSLVerifyClient require +#SSLVerifyDepth 10 + +# Access Control: +# With SSLRequire you can do per-directory access control based +# on arbitrary complex boolean expressions containing server +# variable checks and other lookup directives. The syntax is a +# mixture between C and Perl. See the mod_ssl documentation +# for more details. +# +#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ +# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ +# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ +# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ +# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ +# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +# + +# SSL Engine Options: +# Set various options for the SSL engine. +# o FakeBasicAuth: +# Translate the client X.509 into a Basic Authorisation. This means that +# the standard Auth/DBMAuth methods can be used for access control. The +# user name is the `one line' version of the client's X.509 certificate. +# Note that no password is obtained from the user. Every entry in the user +# file needs this password: `xxj31ZMTZzkVA'. +# o ExportCertData: +# This exports two additional environment variables: SSL_CLIENT_CERT and +# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the +# server (always existing) and the client (only existing when client +# authentication is used). This can be used to import the certificates +# into CGI scripts. +# o StdEnvVars: +# This exports the standard SSL/TLS related `SSL_*' environment variables. +# Per default this exportation is switched off for performance reasons, +# because the extraction step is an expensive operation and is usually +# useless for serving static content. So one usually enables the +# exportation for CGI and SSI requests only. +# o StrictRequire: +# This denies access when "SSLRequireSSL" or "SSLRequire" applied even +# under a "Satisfy any" situation, i.e. when it applies access is denied +# and no other module can change it. +# o OptRenegotiate: +# This enables optimized SSL connection renegotiation handling when SSL +# directives are used in per-directory context. +#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + +# SSL Protocol Adjustments: +# The safe and default but still SSL/TLS standard compliant shutdown +# approach is that mod_ssl sends the close notify alert but doesn't wait for +# the close notify alert from client. When you need a different shutdown +# approach you can use one of the following variables: +# o ssl-unclean-shutdown: +# This forces an unclean shutdown when the connection is closed, i.e. no +# SSL close notify alert is send or allowed to received. This violates +# the SSL/TLS standard but is needed for some brain-dead browsers. Use +# this when you receive I/O errors because of the standard approach where +# mod_ssl sends the close notify alert. +# o ssl-accurate-shutdown: +# This forces an accurate shutdown when the connection is closed, i.e. a +# SSL close notify alert is send and mod_ssl waits for the close notify +# alert of the client. This is 100% SSL/TLS standard compliant, but in +# practice often causes hanging connections with brain-dead browsers. Use +# this only for browsers where you know that their SSL implementation +# works correctly. +# Notice: Most problems of broken clients are also related to the HTTP +# keep-alive facility, so you usually additionally want to disable +# keep-alive for those clients, too. Use variable "nokeepalive" for this. +# Similarly, one has to force some clients to use HTTP/1.0 to workaround +# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and +# "force-response-1.0" for this. +BrowserMatch ".*MSIE.*" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + +# Per-Server Logging: +# The home of a custom SSL log file. Use this when you want a +# compact non-error SSL logfile on a virtual host basis. +CustomLog @exp_logfiledir@/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + + diff --git a/trunk/docs/conf/extra/httpd-userdir.conf.in b/trunk/docs/conf/extra/httpd-userdir.conf.in new file mode 100644 index 0000000000..f424dd437d --- /dev/null +++ b/trunk/docs/conf/extra/httpd-userdir.conf.in @@ -0,0 +1,28 @@ +# Settings for user home directories +# +# Required module: mod_userdir + +# +# UserDir: The name of the directory that is appended onto a user's home +# directory if a ~user request is received. Note that you must also set +# the default access control for these directories, as in the example below. +# +UserDir public_html + +# +# Control access to UserDir directories. The following is an example +# for a site where these directories are restricted to read-only. +# + + AllowOverride FileInfo AuthConfig Limit Indexes + Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec + + Order allow,deny + Allow from all + + + Order deny,allow + Deny from all + + + diff --git a/trunk/docs/conf/extra/httpd-vhosts.conf.in b/trunk/docs/conf/extra/httpd-vhosts.conf.in new file mode 100644 index 0000000000..bd59a127d7 --- /dev/null +++ b/trunk/docs/conf/extra/httpd-vhosts.conf.in @@ -0,0 +1,45 @@ +# +# Virtual Hosts +# +# If you want to maintain multiple domains/hostnames on your +# machine you can setup VirtualHost containers for them. Most configurations +# use only name-based virtual hosts so the server doesn't need to worry about +# IP addresses. This is indicated by the asterisks in the directives below. +# +# Please see the documentation at +# +# for further details before you try to setup virtual hosts. +# +# You may use the command line option '-S' to verify your virtual host +# configuration. + +# +# Use name-based virtual hosting. +# +NameVirtualHost *:80 + +# +# VirtualHost example: +# Almost any Apache directive may go into a VirtualHost container. +# The first VirtualHost section is used for all requests that do not +# match a ServerName or ServerAlias in any block. +# + + ServerAdmin webmaster@dummy-host.example.com + DocumentRoot /www/docs/dummy-host.example.com + ServerName dummy-host.example.com + ServerAlias www.dummy-host.example.com + ErrorLog @rel_logfiledir@/dummy-host.example.com-error_log + CustomLog @rel_logfiledir@/dummy-host.example.com-access_log common + + + + ServerAdmin webmaster@dummy-host2.example.com + DocumentRoot /www/docs/dummy-host2.example.com + ServerName dummy-host2.example.com + ErrorLog @rel_logfiledir@/dummy-host2.example.com-error_log + CustomLog @rel_logfiledir@/dummy-host2.example.com-access_log common + + + + diff --git a/trunk/docs/conf/httpd-win.conf b/trunk/docs/conf/httpd-win.conf new file mode 100644 index 0000000000..e8f2aab46a --- /dev/null +++ b/trunk/docs/conf/httpd-win.conf @@ -0,0 +1,489 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "logs/foo.log" +# with ServerRoot set to "@@ServerRoot@@" will be interpreted by the +# server as "@@ServerRoot@@/logs/foo.log". +# +# NOTE: Where filenames are specified, you must use forward slashes +# instead of backslashes (e.g., "c:/apache" instead of "c:\apache"). +# If a drive letter is omitted, the drive on which Apache.exe is located +# will be used by default. It is recommended that you always supply +# an explicit drive letter in absolute paths, however, to avoid +# confusion. +# + +# ThreadsPerChild: constant number of worker threads in the server process +# MaxRequestsPerChild: maximum number of requests a server process serves +ThreadsPerChild 250 +MaxRequestsPerChild 0 + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to point the LockFile directive +# at a local disk. If you wish to share the same ServerRoot for multiple +# httpd daemons, you will need to change at least LockFile and PidFile. +# +ServerRoot "@@ServerRoot@@" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses (0.0.0.0) +# +#Listen 12.34.56.78:80 +Listen @@Port@@ + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +LoadModule actions_module modules/mod_actions.so +LoadModule alias_module modules/mod_alias.so +LoadModule asis_module modules/mod_asis.so +LoadModule auth_basic_module modules/mod_auth_basic.so +#LoadModule auth_digest_module modules/mod_auth_digest.so +#LoadModule authn_anon_module modules/mod_authn_anon.so +#LoadModule authn_dbm_module modules/mod_authn_dbm.so +LoadModule authn_default_module modules/mod_authn_default.so +LoadModule authn_file_module modules/mod_authn_file.so +#LoadModule authz_dbm_module modules/mod_authz_dbm.so +LoadModule authz_default_module modules/mod_authz_default.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule autoindex_module modules/mod_autoindex.so +#LoadModule cern_meta_module modules/mod_cern_meta.so +LoadModule cgi_module modules/mod_cgi.so +#LoadModule dav_module modules/mod_dav.so +#LoadModule dav_fs_module modules/mod_dav_fs.so +#LoadModule deflate_module modules/mod_deflate.so +LoadModule dir_module modules/mod_dir.so +LoadModule env_module modules/mod_env.so +#LoadModule expires_module modules/mod_expires.so +#LoadModule file_cache_module modules/mod_file_cache.so +#LoadModule headers_module modules/mod_headers.so +LoadModule imagemap_module modules/mod_imagemap.so +LoadModule include_module modules/mod_include.so +#LoadModule info_module modules/mod_info.so +LoadModule isapi_module modules/mod_isapi.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule mime_module modules/mod_mime.so +#LoadModule mime_magic_module modules/mod_mime_magic.so +#LoadModule proxy_module modules/mod_proxy.so +#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so +#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so +#LoadModule proxy_connect_module modules/mod_proxy_connect.so +#LoadModule proxy_http_module modules/mod_proxy_http.so +#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so +LoadModule negotiation_module modules/mod_negotiation.so +#LoadModule rewrite_module modules/mod_rewrite.so +LoadModule setenvif_module modules/mod_setenvif.so +#LoadModule speling_module modules/mod_speling.so +#LoadModule status_module modules/mod_status.so +#LoadModule unique_id_module modules/mod_unique_id.so +LoadModule userdir_module modules/mod_userdir.so +#LoadModule usertrack_module modules/mod_usertrack.so +#LoadModule vhost_alias_module modules/mod_vhost_alias.so +#LoadModule ssl_module modules/mod_ssl.so + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin @@ServerAdmin@@ + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +ServerName @@ServerName@@:@@Port@@ + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "@@ServerRoot@@/htdocs" + +# +# Each directory to which Apache has access can be configured with respect +# to which services and features are allowed and/or disabled in that +# directory (and its subdirectories). +# +# First, we configure the "default" to be a very restrictive set of +# features. +# + + Options FollowSymLinks + AllowOverride None + Order deny,allow + Deny from all + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# This should be changed to whatever you set DocumentRoot to. +# + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs-2.1/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Order allow,deny + Allow from all + + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Order allow,deny + Deny from all + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog logs/error.log + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + CustomLog logs/access.log common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + #CustomLog logs/access.log combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "@@ServerRoot@@/cgi-bin/" + + + +# +# "@@ServerRoot@@/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Order allow,deny + Allow from all + + +# +# Apache parses all CGI scripts for the shebang line by default. +# This comment line, the first line of the script, consists of the symbols +# pound (#) and exclamation (!) followed by the path of the program that +# can execute this specific script. For a perl script, with perl.exe in +# the C:\Program Files\Perl directory, the shebang line should be: + + #!c:/program files/perl/perl + +# Note you _must_not_ indent the actual shebang line, and it must be the +# first line of the file. Of course, CGI processing must be enabled by +# the appropriate ScriptAlias or Options ExecCGI directives for the files +# or directory in question. +# +# However, Apache on Windows allows either the Unix behavior above, or can +# use the Registry to match files by extention. The command to execute +# a file of this type is retrieved from the registry by the same method as +# the Windows Explorer would use to handle double-clicking on a file. +# These script actions can be configured from the Windows Explorer View menu, +# 'Folder Options', and reviewing the 'File Types' tab. Clicking the Edit +# button allows you to modify the Actions, of which Apache 1.3 attempts to +# perform the 'Open' Action, and failing that it will try the shebang line. +# This behavior is subject to change in Apache release 2.0. +# +# Each mechanism has it's own specific security weaknesses, from the means +# to run a program you didn't intend the website owner to invoke, and the +# best method is a matter of great debate. +# +# To enable the this Windows specific behavior (and therefore -disable- the +# equivilant Unix behavior), uncomment the following directive: +# +#ScriptInterpreterSource registry +# +# The directive above can be placed in individual blocks or the +# .htaccess file, with either the 'registry' (Windows behavior) or 'script' +# (Unix behavior) option, and will override this server default option. +# + +# +# DefaultType: the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +DefaultType text/plain + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig conf/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For files that include their own HTTP headers: + #AddHandler send-as-is asis + + # For server-parsed imagemap files: + #AddHandler imap-file map + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + #AddType text/html .shtml + #AddOutputFilter INCLUDES .shtml + + +# +# The mod_mime_magic module allows the server to use various hints from the +# contents of the file itself to determine its type. The MIMEMagicFile +# directive tells the module where the hint definitions are located. +# +#MIMEMagicFile conf/magic + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall is used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# +#EnableMMAP off +#EnableSendfile off + +# Supplemental configuration +# +# The configuration files in the conf/extra/ directory can be +# included to add extra features or to modify the default configuration of +# the server, or you may simply copy their contents here and change as +# necessary. + +# Server-pool management (MPM specific) +#Include conf/extra/httpd-mpm.conf + +# Multi-language error messages +#Include conf/extra/httpd-multilang-errordoc.conf + +# Fancy directory listings +#Include conf/extra/httpd-autoindex.conf + +# Language settings +#Include conf/extra/httpd-languages.conf + +# User home directories +#Include conf/extra/httpd-userdir.conf + +# Real-time info on requests and configuration +#Include conf/extra/httpd-info.conf + +# Virtual hosts +#Include conf/extra/httpd-vhosts.conf + +# Local access to the Apache HTTP Server Manual +#Include conf/extra/httpd-manual.conf + +# Distributed authoring and versioning (WebDAV) +#Include conf/extra/httpd-dav.conf + +# Various default settings +#Include conf/extra/httpd-default.conf + +# Secure (SSL/TLS) connections +#Include conf/extra/httpd-ssl.conf +# +# Note: The following must must be present to support +# starting without SSL on platforms with no /dev/random equivalent +# but a statically compiled-in mod_ssl. +# + +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin + diff --git a/trunk/docs/conf/httpd.conf.in b/trunk/docs/conf/httpd.conf.in new file mode 100644 index 0000000000..286b20dbb4 --- /dev/null +++ b/trunk/docs/conf/httpd.conf.in @@ -0,0 +1,418 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so "@rel_logfiledir@/foo.log" +# with ServerRoot set to "@@ServerRoot@@" will be interpreted by the +# server as "@@ServerRoot@@/@rel_logfiledir@/foo.log". + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to point the LockFile directive +# at a local disk. If you wish to share the same ServerRoot for multiple +# httpd daemons, you will need to change at least LockFile and PidFile. +# +ServerRoot "@@ServerRoot@@" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses (0.0.0.0) +# +#Listen 12.34.56.78:80 +Listen @@Port@@ + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +@@LoadModule@@ + + + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# . On SCO (ODT 3) use "User nouser" and "Group nogroup". +# . On HPUX you may not be able to use shared memory as nobody, and the +# suggested workaround is to create a user www and use that user. +# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET) +# when the value of (unsigned)Group is above 60000; +# don't use Group #-1 on these systems! +# +User nobody +Group #-1 + + + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin you@example.com + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "@exp_htdocsdir@" + +# +# Each directory to which Apache has access can be configured with respect +# to which services and features are allowed and/or disabled in that +# directory (and its subdirectories). +# +# First, we configure the "default" to be a very restrictive set of +# features. +# + + Options FollowSymLinks + AllowOverride None + Order deny,allow + Deny from all + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# This should be changed to whatever you set DocumentRoot to. +# + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs-2.1/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Order allow,deny + Allow from all + + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Order allow,deny + Deny from all + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog @rel_logfiledir@/error_log + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + CustomLog @rel_logfiledir@/access_log common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + #CustomLog @rel_logfiledir@/access_log combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "@exp_cgidir@/" + + + + + # + # ScriptSock: On threaded servers, designate the path to the UNIX + # socket used to communicate with the CGI daemon of mod_cgid. + # + #Scriptsock @rel_runtimedir@/cgisock + + +# +# "@exp_cgidir@" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Order allow,deny + Allow from all + + +# +# DefaultType: the default MIME type the server will use for a document +# if it cannot otherwise determine one, such as from filename extensions. +# If your server contains mostly text or HTML documents, "text/plain" is +# a good value. If most of your content is binary, such as applications +# or images, you may want to use "application/octet-stream" instead to +# keep browsers from trying to display binary files as though they are +# text. +# +DefaultType text/plain + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig @rel_sysconfdir@/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For files that include their own HTTP headers: + #AddHandler send-as-is asis + + # For server-parsed imagemap files: + #AddHandler imap-file map + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + #AddType text/html .shtml + #AddOutputFilter INCLUDES .shtml + + +# +# The mod_mime_magic module allows the server to use various hints from the +# contents of the file itself to determine its type. The MIMEMagicFile +# directive tells the module where the hint definitions are located. +# +#MIMEMagicFile @rel_sysconfdir@/magic + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall is used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# +#EnableMMAP off +#EnableSendfile off + +# Supplemental configuration +# +# The configuration files in the @rel_sysconfdir@/extra/ directory can be +# included to add extra features or to modify the default configuration of +# the server, or you may simply copy their contents here and change as +# necessary. + +# Server-pool management (MPM specific) +#Include @rel_sysconfdir@/extra/httpd-mpm.conf + +# Multi-language error messages +#Include @rel_sysconfdir@/extra/httpd-multilang-errordoc.conf + +# Fancy directory listings +#Include @rel_sysconfdir@/extra/httpd-autoindex.conf + +# Language settings +#Include @rel_sysconfdir@/extra/httpd-languages.conf + +# User home directories +#Include @rel_sysconfdir@/extra/httpd-userdir.conf + +# Real-time info on requests and configuration +#Include @rel_sysconfdir@/extra/httpd-info.conf + +# Virtual hosts +#Include @rel_sysconfdir@/extra/httpd-vhosts.conf + +# Local access to the Apache HTTP Server Manual +#Include @rel_sysconfdir@/extra/httpd-manual.conf + +# Distributed authoring and versioning (WebDAV) +#Include @rel_sysconfdir@/extra/httpd-dav.conf + +# Various default settings +#Include @rel_sysconfdir@/extra/httpd-default.conf + +# Secure (SSL/TLS) connections +#Include @rel_sysconfdir@/extra/httpd-ssl.conf +# +# Note: The following must must be present to support +# starting without SSL on platforms with no /dev/random equivalent +# but a statically compiled-in mod_ssl. +# + +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin + diff --git a/trunk/docs/conf/magic b/trunk/docs/conf/magic new file mode 100644 index 0000000000..0de73361fb --- /dev/null +++ b/trunk/docs/conf/magic @@ -0,0 +1,382 @@ +# Magic data for mod_mime_magic Apache module (originally for file(1) command) +# The module is described in /manual/mod/mod_mime_magic.html +# +# The format is 4-5 columns: +# Column #1: byte number to begin checking from, ">" indicates continuation +# Column #2: type of data to match +# Column #3: contents of data to match +# Column #4: MIME type of result +# Column #5: MIME encoding of result (optional) + +#------------------------------------------------------------------------------ +# Localstuff: file(1) magic for locally observed files +# Add any locally observed files here. + +#------------------------------------------------------------------------------ +# end local stuff +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Java + +0 short 0xcafe +>2 short 0xbabe application/java + +#------------------------------------------------------------------------------ +# audio: file(1) magic for sound formats +# +# from Jan Nicolai Langfeldt , +# + +# Sun/NeXT audio data +0 string .snd +>12 belong 1 audio/basic +>12 belong 2 audio/basic +>12 belong 3 audio/basic +>12 belong 4 audio/basic +>12 belong 5 audio/basic +>12 belong 6 audio/basic +>12 belong 7 audio/basic + +>12 belong 23 audio/x-adpcm + +# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format +# that uses little-endian encoding and has a different magic number +# (0x0064732E in little-endian encoding). +0 lelong 0x0064732E +>12 lelong 1 audio/x-dec-basic +>12 lelong 2 audio/x-dec-basic +>12 lelong 3 audio/x-dec-basic +>12 lelong 4 audio/x-dec-basic +>12 lelong 5 audio/x-dec-basic +>12 lelong 6 audio/x-dec-basic +>12 lelong 7 audio/x-dec-basic +# compressed (G.721 ADPCM) +>12 lelong 23 audio/x-dec-adpcm + +# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM" +# AIFF audio data +8 string AIFF audio/x-aiff +# AIFF-C audio data +8 string AIFC audio/x-aiff +# IFF/8SVX audio data +8 string 8SVX audio/x-aiff + +# Creative Labs AUDIO stuff +# Standard MIDI data +0 string MThd audio/unknown +#>9 byte >0 (format %d) +#>11 byte >1 using %d channels +# Creative Music (CMF) data +0 string CTMF audio/unknown +# SoundBlaster instrument data +0 string SBI audio/unknown +# Creative Labs voice data +0 string Creative\ Voice\ File audio/unknown +## is this next line right? it came this way... +#>19 byte 0x1A +#>23 byte >0 - version %d +#>22 byte >0 \b.%d + +# [GRR 950115: is this also Creative Labs? Guessing that first line +# should be string instead of unknown-endian long...] +#0 long 0x4e54524b MultiTrack sound data +#0 string NTRK MultiTrack sound data +#>4 long x - version %ld + +# Microsoft WAVE format (*.wav) +# [GRR 950115: probably all of the shorts and longs should be leshort/lelong] +# Microsoft RIFF +0 string RIFF audio/unknown +# - WAVE format +>8 string WAVE audio/x-wav +# MPEG audio. +0 beshort&0xfff0 0xfff0 audio/mpeg +# C64 SID Music files, from Linus Walleij +0 string PSID audio/prs.sid + +#------------------------------------------------------------------------------ +# c-lang: file(1) magic for C programs or various scripts +# + +# XPM icons (Greg Roelofs, newt@uchicago.edu) +# ideally should go into "images", but entries below would tag XPM as C source +0 string /*\ XPM image/x-xbm 7bit + +# this first will upset you if you're a PL/1 shop... (are there any left?) +# in which case rm it; ascmagic will catch real C programs +# C or REXX program text +0 string /* text/plain +# C++ program text +0 string // text/plain + +#------------------------------------------------------------------------------ +# compress: file(1) magic for pure-compression formats (no archives) +# +# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc. +# +# Formats for various forms of compressed data +# Formats for "compress" proper have been moved into "compress.c", +# because it tries to uncompress it to figure out what's inside. + +# standard unix compress +0 string \037\235 application/octet-stream x-compress + +# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver) +0 string \037\213 application/octet-stream x-gzip + +# According to gzip.h, this is the correct byte order for packed data. +0 string \037\036 application/octet-stream +# +# This magic number is byte-order-independent. +# +0 short 017437 application/octet-stream + +# XXX - why *two* entries for "compacted data", one of which is +# byte-order independent, and one of which is byte-order dependent? +# +# compacted data +0 short 0x1fff application/octet-stream +0 string \377\037 application/octet-stream +# huf output +0 short 0145405 application/octet-stream + +# Squeeze and Crunch... +# These numbers were gleaned from the Unix versions of the programs to +# handle these formats. Note that I can only uncrunch, not crunch, and +# I didn't have a crunched file handy, so the crunch number is untested. +# Keith Waclena +#0 leshort 0x76FF squeezed data (CP/M, DOS) +#0 leshort 0x76FE crunched data (CP/M, DOS) + +# Freeze +#0 string \037\237 Frozen file 2.1 +#0 string \037\236 Frozen file 1.0 (or gzip 0.5) + +# lzh? +#0 string \037\240 LZH compressed data + +#------------------------------------------------------------------------------ +# frame: file(1) magic for FrameMaker files +# +# This stuff came on a FrameMaker demo tape, most of which is +# copyright, but this file is "published" as witness the following: +# +0 string \ +# and Anna Shergold +# +0 string \ +0 string \14 byte 12 (OS/2 1.x format) +#>14 byte 64 (OS/2 2.x format) +#>14 byte 40 (Windows 3.x format) +#0 string IC icon +#0 string PI pointer +#0 string CI color icon +#0 string CP color pointer +#0 string BA bitmap array + + +#------------------------------------------------------------------------------ +# lisp: file(1) magic for lisp programs +# +# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com) +0 string ;; text/plain 8bit +# Emacs 18 - this is always correct, but not very magical. +0 string \012( application/x-elc +# Emacs 19 +0 string ;ELC\023\000\000\000 application/x-elc + +#------------------------------------------------------------------------------ +# mail.news: file(1) magic for mail and news +# +# There are tests to ascmagic.c to cope with mail and news. +0 string Relay-Version: message/rfc822 7bit +0 string #!\ rnews message/rfc822 7bit +0 string N#!\ rnews message/rfc822 7bit +0 string Forward\ to message/rfc822 7bit +0 string Pipe\ to message/rfc822 7bit +0 string Return-Path: message/rfc822 7bit +0 string Path: message/news 8bit +0 string Xref: message/news 8bit +0 string From: message/rfc822 7bit +0 string Article message/news 8bit +#------------------------------------------------------------------------------ +# msword: file(1) magic for MS Word files +# +# Contributor claims: +# Reversed-engineered MS Word magic numbers +# + +0 string \376\067\0\043 application/msword +0 string \333\245-\0\0\0 application/msword + +# disable this one because it applies also to other +# Office/OLE documents for which msword is not correct. See PR#2608. +#0 string \320\317\021\340\241\261 application/msword + + + +#------------------------------------------------------------------------------ +# printer: file(1) magic for printer-formatted files +# + +# PostScript +0 string %! application/postscript +0 string \004%! application/postscript + +# Acrobat +# (due to clamen@cs.cmu.edu) +0 string %PDF- application/pdf + +#------------------------------------------------------------------------------ +# sc: file(1) magic for "sc" spreadsheet +# +38 string Spreadsheet application/x-sc + +#------------------------------------------------------------------------------ +# tex: file(1) magic for TeX files +# +# XXX - needs byte-endian stuff (big-endian and little-endian DVI?) +# +# From + +# Although we may know the offset of certain text fields in TeX DVI +# and font files, we can't use them reliably because they are not +# zero terminated. [but we do anyway, christos] +0 string \367\002 application/x-dvi +#0 string \367\203 TeX generic font data +#0 string \367\131 TeX packed font data +#0 string \367\312 TeX virtual font data +#0 string This\ is\ TeX, TeX transcript text +#0 string This\ is\ METAFONT, METAFONT transcript text + +# There is no way to detect TeX Font Metric (*.tfm) files without +# breaking them apart and reading the data. The following patterns +# match most *.tfm files generated by METAFONT or afm2tfm. +#2 string \000\021 TeX font metric data +#2 string \000\022 TeX font metric data +#>34 string >\0 (%s) + +# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com) +#0 string \\input\ texinfo Texinfo source text +#0 string This\ is\ Info\ file GNU Info text + +# correct TeX magic for Linux (and maybe more) +# from Peter Tobias (tobias@server.et-inf.fho-emden.de) +# +0 leshort 0x02f7 application/x-dvi + +# RTF - Rich Text Format +0 string {\\rtf application/rtf + +#------------------------------------------------------------------------------ +# animation: file(1) magic for animation/movie formats +# +# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8) +# MPEG file +0 string \000\000\001\263 video/mpeg +# +# The contributor claims: +# I couldn't find a real magic number for these, however, this +# -appears- to work. Note that it might catch other files, too, +# so BE CAREFUL! +# +# Note that title and author appear in the two 20-byte chunks +# at decimal offsets 2 and 22, respectively, but they are XOR'ed with +# 255 (hex FF)! DL format SUCKS BIG ROCKS. +# +# DL file version 1 , medium format (160x100, 4 images/screen) +0 byte 1 video/unknown +0 byte 2 video/unknown +# Quicktime video, from Linus Walleij +# from Apple quicktime file format documentation. +4 string moov video/quicktime +4 string mdat video/quicktime + diff --git a/trunk/docs/conf/mime.types b/trunk/docs/conf/mime.types new file mode 100644 index 0000000000..3485692d11 --- /dev/null +++ b/trunk/docs/conf/mime.types @@ -0,0 +1,592 @@ +# This is a comment. I love comments. + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# MIME type Extensions +application/activemessage +application/andrew-inset ez +application/applefile +application/atom+xml atom +application/atomicmail +application/batch-smtp +application/beep+xml +application/cals-1840 +application/cnrp+xml +application/commonground +application/cpl+xml +application/cybercash +application/dca-rft +application/dec-dx +application/dvcs +application/edi-consent +application/edifact +application/edi-x12 +application/eshop +application/font-tdpfr +application/http +application/hyperstudio +application/iges +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/iotp +application/ipp +application/isup +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/macwriteii +application/marc +application/mathematica +application/mathml+xml mathml +application/msword doc +application/news-message-id +application/news-transmission +application/ocsp-request +application/ocsp-response +application/octet-stream bin dms lha lzh exe class so dll dmg +application/oda oda +application/ogg ogg +application/parityfec +application/pdf pdf +application/pgp-encrypted +application/pgp-keys +application/pgp-signature +application/pkcs10 +application/pkcs7-mime +application/pkcs7-signature +application/pkix-cert +application/pkix-crl +application/pkixcmp +application/postscript ai eps ps +application/prs.alvestrand.titrax-sheet +application/prs.cww +application/prs.nprend +application/prs.plucker +application/qsig +application/rdf+xml rdf +application/reginfo+xml +application/remote-printing +application/riscos +application/rtf +application/sdp +application/set-payment +application/set-payment-initiation +application/set-registration +application/set-registration-initiation +application/sgml +application/sgml-open-catalog +application/sieve +application/slate +application/smil smi smil +application/srgs gram +application/srgs+xml grxml +application/timestamp-query +application/timestamp-reply +application/tve-trigger +application/vemmi +application/vnd.3gpp.pic-bw-large +application/vnd.3gpp.pic-bw-small +application/vnd.3gpp.pic-bw-var +application/vnd.3gpp.sms +application/vnd.3m.post-it-notes +application/vnd.accpac.simply.aso +application/vnd.accpac.simply.imp +application/vnd.acucobol +application/vnd.acucorp +application/vnd.adobe.xfdf +application/vnd.aether.imp +application/vnd.amiga.ami +application/vnd.anser-web-certificate-issue-initiation +application/vnd.anser-web-funds-transfer-initiation +application/vnd.audiograph +application/vnd.blueice.multipass +application/vnd.bmi +application/vnd.businessobjects +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.cinderella +application/vnd.claymore +application/vnd.commerce-battelle +application/vnd.commonspace +application/vnd.contact.cmsg +application/vnd.cosmocaller +application/vnd.criticaltools.wbs+xml +application/vnd.ctc-posml +application/vnd.cups-postscript +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.curl +application/vnd.cybank +application/vnd.data-vision.rdz +application/vnd.dna +application/vnd.dpgraph +application/vnd.dreamfactory +application/vnd.dxr +application/vnd.ecdis-update +application/vnd.ecowin.chart +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +application/vnd.enliven +application/vnd.epson.esf +application/vnd.epson.msf +application/vnd.epson.quickanime +application/vnd.epson.salt +application/vnd.epson.ssf +application/vnd.ericsson.quickcall +application/vnd.eudora.data +application/vnd.fdf +application/vnd.ffsns +application/vnd.fints +application/vnd.flographit +application/vnd.framemaker +application/vnd.fsc.weblaunch +application/vnd.fujitsu.oasys +application/vnd.fujitsu.oasys2 +application/vnd.fujitsu.oasys3 +application/vnd.fujitsu.oasysgp +application/vnd.fujitsu.oasysprs +application/vnd.fujixerox.ddd +application/vnd.fujixerox.docuworks +application/vnd.fujixerox.docuworks.binder +application/vnd.fut-misnet +application/vnd.grafeq +application/vnd.groove-account +application/vnd.groove-help +application/vnd.groove-identity-message +application/vnd.groove-injector +application/vnd.groove-tool-message +application/vnd.groove-tool-template +application/vnd.groove-vcard +application/vnd.hbci +application/vnd.hhe.lesson-player +application/vnd.hp-hpgl +application/vnd.hp-hpid +application/vnd.hp-hps +application/vnd.hp-pcl +application/vnd.hp-pclxl +application/vnd.httphone +application/vnd.hzn-3d-crossword +application/vnd.ibm.afplinedata +application/vnd.ibm.electronic-media +application/vnd.ibm.minipay +application/vnd.ibm.modcap +application/vnd.ibm.rights-management +application/vnd.ibm.secure-container +application/vnd.informix-visionary +application/vnd.intercon.formnet +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo +application/vnd.intu.qfx +application/vnd.irepository.package+xml +application/vnd.is-xpr +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.jisp +application/vnd.kde.karbon +application/vnd.kde.kchart +application/vnd.kde.kformula +application/vnd.kde.kivio +application/vnd.kde.kontour +application/vnd.kde.kpresenter +application/vnd.kde.kspread +application/vnd.kde.kword +application/vnd.kenameaapp +application/vnd.koan +application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop +application/vnd.llamagraphics.life-balance.exchange+xml +application/vnd.lotus-1-2-3 +application/vnd.lotus-approach +application/vnd.lotus-freelance +application/vnd.lotus-notes +application/vnd.lotus-organizer +application/vnd.lotus-screencam +application/vnd.lotus-wordpro +application/vnd.mcd +application/vnd.mediastation.cdkey +application/vnd.meridian-slingshot +application/vnd.micrografx.flo +application/vnd.micrografx.igx +application/vnd.mif mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf +application/vnd.mobius.dis +application/vnd.mobius.mbk +application/vnd.mobius.mqy +application/vnd.mobius.msl +application/vnd.mobius.plc +application/vnd.mobius.txf +application/vnd.mophun.application +application/vnd.mophun.certificate +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry +application/vnd.ms-asf +application/vnd.ms-excel xls +application/vnd.ms-lrm +application/vnd.ms-powerpoint ppt +application/vnd.ms-project +application/vnd.ms-tnef +application/vnd.ms-works +application/vnd.ms-wpl +application/vnd.mseq +application/vnd.msign +application/vnd.music-niff +application/vnd.musician +application/vnd.netfpx +application/vnd.noblenet-directory +application/vnd.noblenet-sealer +application/vnd.noblenet-web +application/vnd.novadigm.edm +application/vnd.novadigm.edx +application/vnd.novadigm.ext +application/vnd.obn +application/vnd.osa.netdeploy +application/vnd.palm +application/vnd.pg.format +application/vnd.pg.osasli +application/vnd.powerbuilder6 +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.previewsystems.box +application/vnd.publishare-delta-tree +application/vnd.pvi.ptid1 +application/vnd.pwg-multiplexed +application/vnd.pwg-xhtml-print+xml +application/vnd.quark.quarkxpress +application/vnd.rapid +application/vnd.s3sms +application/vnd.sealed.net +application/vnd.seemail +application/vnd.shana.informed.formdata +application/vnd.shana.informed.formtemplate +application/vnd.shana.informed.interchange +application/vnd.shana.informed.package +application/vnd.smaf +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.street-stream +application/vnd.svd +application/vnd.swiftview-ics +application/vnd.triscape.mxs +application/vnd.trueapp +application/vnd.truedoc +application/vnd.ufdl +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.vcx +application/vnd.vectorworks +application/vnd.vidsoft.vidconference +application/vnd.visio +application/vnd.visionary +application/vnd.vividence.scriptfile +application/vnd.vsf +application/vnd.wap.sic +application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo +application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf +application/vnd.wv.csp+wbxml +application/vnd.xara +application/vnd.xfdl +application/vnd.yamaha.hv-dic +application/vnd.yamaha.hv-script +application/vnd.yamaha.hv-voice +application/vnd.yellowriver-custom-menu +application/voicexml+xml vxml +application/watcherinfo+xml +application/whoispp-query +application/whoispp-response +application/wita +application/wordperfect5.1 +application/x-bcpio bcpio +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-gzip +application/x-hdf hdf +application/x-javascript js +application/x-koan skp skd skt skm +application/x-latex latex +application/x-netcdf nc cdf +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/x400-bp +application/xhtml+xml xhtml xht +application/xslt+xml xslt +application/xml xml xsl +application/xml-dtd dtd +application/xml-external-parsed-entity +application/zip zip +audio/32kadpcm +audio/amr +audio/amr-wb +audio/basic au snd +audio/cn +audio/dat12 +audio/dsr-es201108 +audio/dvi4 +audio/evrc +audio/evrc0 +audio/g722 +audio/g.722.1 +audio/g723 +audio/g726-16 +audio/g726-24 +audio/g726-32 +audio/g726-40 +audio/g728 +audio/g729 +audio/g729D +audio/g729E +audio/gsm +audio/gsm-efr +audio/l8 +audio/l16 +audio/l20 +audio/l24 +audio/lpc +audio/midi mid midi kar +audio/mpa +audio/mpa-robust +audio/mp4a-latm +audio/mpeg mpga mp2 mp3 +audio/parityfec +audio/pcma +audio/pcmu +audio/prs.sid +audio/qcelp +audio/red +audio/smv +audio/smv0 +audio/telephone-event +audio/tone +audio/vdvi +audio/vnd.3gpp.iufp +audio/vnd.cisco.nse +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.digital-winds +audio/vnd.everad.plj +audio/vnd.lucent.voice +audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 +audio/vnd.nuera.ecelp7470 +audio/vnd.nuera.ecelp9600 +audio/vnd.octel.sbc +audio/vnd.qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.vmx.cvsd +audio/x-aiff aif aiff aifc +audio/x-alaw-basic +audio/x-mpegurl m3u +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin +application/vnd.rn-realmedia rm +audio/x-wav wav +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +image/g3fax +image/gif gif +image/ief ief +image/jpeg jpeg jpg jpe +image/naplps +image/png png +image/prs.btif +image/prs.pti +image/svg+xml svg +image/t38 +image/tiff tiff tif +image/tiff-fx +image/vnd.cns.inf2 +image/vnd.djvu djvu djv +image/vnd.dwg +image/vnd.dxf +image/vnd.fastbidsheet +image/vnd.fpx +image/vnd.fst +image/vnd.fujixerox.edmics-mmr +image/vnd.fujixerox.edmics-rlc +image/vnd.globalgraphics.pgb +image/vnd.mix +image/vnd.ms-modi +image/vnd.net-fpx +image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff +image/x-cmu-raster ras +image/x-icon ico +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +message/delivery-status +message/disposition-notification +message/external-body +message/http +message/news +message/partial +message/rfc822 +message/s-http +message/sip +message/sipfrag +model/iges igs iges +model/mesh msh mesh silo +model/vnd.dwf +model/vnd.flatland.3dml +model/vnd.gdl +model/vnd.gs-gdl +model/vnd.gtw +model/vnd.mts +model/vnd.parasolid.transmit.binary +model/vnd.parasolid.transmit.text +model/vnd.vtu +model/vrml wrl vrml +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/voice-message +text/calendar ics ifb +text/css css +text/directory +text/enriched +text/html html htm +text/parityfec +text/plain asc txt +text/prs.lines.tag +text/rfc822-headers +text/richtext rtx +text/rtf rtf +text/sgml sgml sgm +text/t140 +text/tab-separated-values tsv +text/uri-list +text/vnd.abc +text/vnd.curl +text/vnd.dmclientscript +text/vnd.fly +text/vnd.fmi.flexstor +text/vnd.in3d.3dml +text/vnd.in3d.spot +text/vnd.iptc.nitf +text/vnd.iptc.newsml +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage +text/vnd.net2phone.commcenter.command +text/vnd.sun.j2me.app-descriptor +text/vnd.wap.si +text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-setext etx +text/xml +text/xml-external-parsed-entity +video/bmpeg +video/bt656 +video/celb +video/dv +video/h261 +video/h263 +video/h263-1998 +video/h263-2000 +video/jpeg +video/mp1s +video/mp2p +video/mp2t +video/mp4v-es +video/mpv +video/mpeg mpeg mpg mpe +video/nv +video/parityfec +video/pointer +video/quicktime qt mov +video/smpte292m +video/vnd.fvt +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.nokia.interleaved-multimedia +video/vnd.objectvideo +video/vnd.vivo +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/trunk/docs/docroot/apache_pb.gif b/trunk/docs/docroot/apache_pb.gif new file mode 100644 index 0000000000000000000000000000000000000000..3a1c139fc4247ec7e770fdaab961fb3692c953fb GIT binary patch literal 2326 zcmeH``#aS60)Ri?F~*GRoWb@r$c#H_jN6u#)66_>GY!UILM{ophO`}&oUt=FmBNTY z$`ICVA7j^+h#i;OQDc-ga!qS+8Gc0FW4f z)Bt1yAj_Q32!U{ zRIo-qQptb-t7{uBm(~px;>}n!KArWR1^>`Cf~is&A3~v0s8aF}M#nn9GGt0d7v`yb z*>S>eMWL(I627?MNllQ7BkqHq)M=1k z=&Ky&zXVh2hPE6DHG1$Mj#+!@W<|fAeonA2iB#Un#%N(&&W1dtI~9BfQ#)e2X=lF^XcGT}q=AoZ{H^5&_C+Pv zN&hQZTYONvvH2qVcG~jIh^yqZXMG0jauI~J<^%?yjPC{pb>Ylqd7Qgl5*ph^Ulf=T ztUu|ceZK)dM=IDKg~q~CZoH&Cb~-~Z=;&lvYG{6Kc>2z^;Sv327g?kssFZ=dw}0cH zdw$mEtN!A<`J8^&z3 zt~SwiD6S8)Rjrr!Kx<)&vBl1-$xbOvcBi~nxrDC!TBPace;L%k*DDqrZ4t4XvN(& zu%4H=wkn0>)>bWw*7qy^XgxfL8hEr{3=!aT@x^9eDj^ytk&Chl$kO(lBLUN|dQ6Gs zqR_gQC$$$-23%rt``_I(>C3A7dOXT9Z$frk_k~-Ys+P;@AA_2Pg%%8=^ZRrL+?~|f zW&~d`K5oo!G0s}dw|gtsI8gBY`D(2K(S?RiMa{{iIhO(d)G0SJjuwocN&dl=)Ns$! zkAoL^`msv}wXFIo9^Egsd~xDITuw=a{)ty}PeNiaZ{?=q1Ff-;&+#A?LvlJm+3a2z z0EU`idSaEFK|F|qEq^5hpn?C2d=DQ+H3YkO^OBqUex<5bLo z9(N*aTe0*iA?|UPIVvKLCc?9Ag1I16-HvOfbsA#dH4-dk3 zhnz>*3E(FdLU+yVpuPUsliM=aeNjZUS*@XX3Z53T6iR8-2uO=XFwVs0@AhefEv8q zeI*^7gje{cZVN8?oK%ZT=2#U=<_Ih7M^R~)Ja%@QBEHt-Nj+won-qIvXTfK$!wnkr z2MQ*#TaAN%Ohqz*uQYER7$<|Jgd}A|ZL~mb$%8Fh^ z{1s=ft;T@}n?u#1Sd8|0dAq@XlaA<)Sy)vu-xZB|?3vPJ`3#PxQkI=}-aLquKdtW{ zRsg5o;PBjI;EgPh^zTEWZ?enGho=a|_a2#rB5>rG$ipb8~ZRYin9sS|J!1|3Vo5F#x?%5Z#agaH4}82`=y&d$cYy~Z&B z|6>6EoB;pt0RQJo@7{af)}_w>0G#hijQ;>*=Y*W^Qe*!B7ytkOKp?+w00001VoOIv z9|a8%y#N3Nw@E}nRCwC$n2U0wI21&+5=byvIT4S5BHR4`Uv9Sq81N(ZOwFvP%AE%o zkez$fx21{@FTM2AOOHrW4~}u;2>0;F|3mI{=G?_6%s}af-c=97>iFD}W~yAu9H%>J zrQI@+s6`2;z*T+ zwX-R}K*(XpWb}h{C<~`f4~8WU7;Ofem}nRf&Ej)2gLsiXG7oy`&r&c(;gBmOMbN>A z#Gx$h&LsvKKd8gt$Wk>*%W#mWPQ~h=EE_byWFkE`Gl&oCINtrzpZS}mK*9Z!=b7-0 zZ!;f)judQJ6f#z5B(1ymA=$^+0Mz-P7rg@(Y4!Q^$_)V>K# z@cx)onlyoKWZ>M8Cf5kX+9i9z#Ci>1(f4l2K(Z0o6i;n~>Ca_pRaG}o>uc}P7VrbE zAB(~|!?|R&cv31B#&Tt5Mh2`E;Ww@$%RCrl0`cTRY^Tf{Dq;W!PYjLs>}}XV7eB_# z!}OzM7A9h!WFvzVhEh1aVZgMJe}N5Lt_Pi~YUBVl4GjSbq461FvP3@oD6HJAwh?Z% z2a;Fo)X#4NB%020;p@7pW;f_cgF{O<)L1WoVTeI#ZBZ1D&8myGd2V5k=rD<_cE*tG zP*)9OGID^Jl5x!-hr7$_%+tFdQs5VgY(tAKsE3I|0>Qp$$$>%Xa|C6i0Sr6$^nLyq z1?&>h{YXQG0YEG`zz=W)?$mW?J(STDWf@W2#(=@y`bu-Iu3tXTeL|bJ`PlD|EA6Kt z{Q-JgKKq6pUO8R)_grt{s+_`G)AGK>y3m3{b>a|7)Lb*#x=FSOnzjhXU~f=}!`20L z7a%kX2wy&Gg{429Yd_v%#fLKn<;1|A=>`MgEGYm3{{&2T!^Svq7+21;c-C#p+f5$E zzEI(kAriQ11tBr$PKqz*+kVm#LMnRJ*MYA;W(LP^7`&||Zpjt8Wd0LFGJTr%deFnL zhEb=)1PT>bP+uy$+pRG;8b^HM!Fq8cF<3mdWYF_NJMp=J5E(3neDQUE@aLWfH0z9;auw~Hi`#BHF%UUwH zBMCN=R!0hq|JWBkO#WmP#K_cov3h`v)$jJ5-zP8hBZ3jaT+od?=q3c?>HZpnC5}57 z+>-=bIRy-~L)<8bF)F8=h*=TW4{V`;M1x532aeW`5Qt#5$r8c^2HgU|N)v=FgZ<$! zEewf4%8AtO<<&g+c&sNJ60)#m>Wj!?!2T!(#pI0;S)>#7PN5y(3CVv*bmKb0T~~xr zRo#L?ci|(?5qSS~nZe<==E0VPRE3J~c}z60he)=7JGeOVKq@)&fE-dYL9<4T)w7G7^nN~DX)5G{ rGrM}bkL6^)UC^IE@X|{!{bl+Odo{L8_lJExo!OHH@#L?0Fsk3g9+0-%#kV)Kf zB;Lm)WsWj{mw{t4P$v62PSD1Gl%MytKqmW{WF7!lXrYR@A&Wof$BRdoD9^7)O~QCHc4FgyAz zQb5%gl_(rvaK8#TJvXRH!;vTpQg6AUnl4lLD1^g@2VkU(Xd}+G!}4q7PCruL1BX}~ zn%__Cf`!@Yjtibl_yC1_JNf5WLZ~uEo}|U%%z!2`dPMaki^@Z$BlXRQ{^KxsS~ae) zlwumx%n1G|s&RGhWp|Kj#+in3D(6)e()iEl@-u8Sff7w(OQTZm=d_qe&#{a{0Hkpk zd3~jNVEi=K*pl@q!mG~imPQW~M;_q~)~slH^x7<>ZG&wgt{Mx3+)=cdqA(vy`RlC) zIa*5ndx=y3oI55zDs1qBzgl%3gaA!mB^0?eSac9tJUbBD_wNb6B z5Y=BHl$rboqrsa_)1K0b*Ru01Ndlku0|=$W(vd?6ibRQfCat`Zll~Odu|H!`~`V*Sk|_A2T>nj+?l04FK{py$X_NM2MU^ zWo{S{Ncox!*mgVc48Zb(k+K{_TbKyQNKADLN2y@=1Vm1I~mNk5D z0iKr^7kpn^lf_&*IqSSRGsYu%Oy?I-qsO3~~?Q_Y?Qgd!o4AT` zy#1OX<>B~LkBO+T67llGwN(;& z5cY>(Zs+x+8pmeJ=iqm(J?@D}N*qJXB((gy?3S^wzj)_?JM7fN$+1NN(P%I zS?H@FlXx)=8PJ!)DAZ9?{^XKI;lu_;0(DV)hi3^Uw=U+|La!AGBb3?#anaR(o^+!0 zO_G^9!r;2w`>KGj@WLY11a3&f;w}@@<9zj%hZ;llPw}u9bsa9xTP+=u+U^*tFu1eP z(O)e2*~l>0&>;a*4`SKgFV|YWxZ2D@vrk(&Z?BLezWxE4HihSVm?9^^m~}+nk*)I~ z`l{hwue2?A09j?xgz`wEfw;2wJJ-!fT-D2h9HjbKr)JhmOkJwsLN?ke@WY$Jz~7RL zvxtcil-2^b1@O$hdY82q-^;atbN=&?En!s{X17r`(*;WL-K$NAdxP&ex&I>0 z`DR`5&>M_^3+EgRE{6M1!cRPMn`YaFz$-kwOTo&xcT&bmNkd?< z%iFaAq?u9ya(M|B{sG9PuVpEwiuLx;nx+?4pFY<^!F>~$Tz7h!y!pL&AMyK-=hvT) XqiYh{4~%{)S#O;4Fm;B(z`p+hpbw|G literal 0 HcmV?d00001 diff --git a/trunk/docs/docroot/apache_pb2.png b/trunk/docs/docroot/apache_pb2.png new file mode 100644 index 0000000000000000000000000000000000000000..28baa70fb8ce678b9e4a5eecb6697d43315f413a GIT binary patch literal 1463 zcmV;o1xWgdP)?tZ*WOVL-Hq z-(g}92I(XDpqCzJU{W6D*41q~NU3qyX>CNOI@d)GeeX{;GEn$M91=%{st{U%gF$pU zLzO2IWY z_?2KWpH(4S42{8Y!?an{1JEMCC)!}v<+^tl111Dk3?|R>GIwQHcFrB6dKnkcjts1= z;^Io7`7*;?kRe{lPxQS_85kx4lj7MnFqaA3%OHMThL&Y{3AHYF4ru{DVEi}?-b$_| zqs5&@Gcbm03OO=htSEkCA4%&0UTGffEPqTOZRBQC32z~=a|g|c0UR7Ll+H1?VFxw* z8fzYwU($7K1RN?x2C*0#VbzKOtBrZC4a}xDhOf8o6<2!W#9*f?wbR+i0V+!x0u;K^ z6)2NE>cg+Wo6}+&VV8+_HBR+h8*CBGp_?_NYuh$dG*#?`%kwOo-JmiB4lUh~qhA0+ z6$+*I!!SIys`e`U|BkRnv{*z&J7b7;$g`4VGH`%cB}303hr7dSZF#xebz@%W?vf!QxNHF-GHA{UALq+%QVJmkJ?rzp z&u=q><2MZ6mlC&R2i3Fw6GJq8T=u+Di`D}ed90W~p+g6Cz4oWm5`(32#0PH7lM9hS za$Cxv=1Uv#v4Rj7BvU^5xjy@#PhY!bARg06`ZpElOR}Vg0N<=KOCmU5E;Ze5!1cDS`XeH%L$7LIru*2MPN~3 ze-sME3Yv27~RUAXdmQw!g4H82jNp3|4wD zCH~MpEcf=xSk04qJtd582D#|D61Hw z0tOUBfk1+S-~x&SL~C3SM3!QOXpu#$q^Jl_P2Pa#lysIef84qE`|kbbeDjl^ue--q z90ma$VD4B%r@H`6NJvOH(8R^XB_$;Z1cDNvsi>%E*=W$xa;LNNPG3dm(7vIeTEW=b z$uU96B+yK*&70g9K3T%n0J;W*Ye0zxRbkUL0-)(cFSJI6A0+jVXo3#O+Zj1 zNPa}jndq7e@vm z%UKo4E?(^-jvl||cBj)>DrrnGhyny+R!-SPJmufdn#`T0c?8|79Wgxx)B3-yi2rW& z>p}&k{9s#O(5If<;%ARm>6wvjl?Ov5X{)hNHU`(K-v~u>knQMx7DKT>oO7E3a3_?S`)65Tg-T4pZ( z3DN<;pLH?02Mdi9=CInI2=TI8TcEnM%==JQjGA-C(6{OF&_NeI#&@sGE0CM~c-I5w#?rjvV$Cn)}x4_9-eO^a7ghYm?CQv)A7BAVS`Z-{#R)Sz61^o1`wj^qI<=nfK#iyh*|qVvEGBOsiO)ZY|7`j)ulDklXZ)e=@-Y1>4<(x$U0Gcz)^n9- z;0!uQZDfj%f!EKekB!ocZCzPyr6xbf+i_EOnG%wzP0e_Dp3~m(op2X+o2P5eNNE5) z;b-yT4`)-Vxw2Yjk>|S6a$Hr?&8E>B=~Q+*eoM+ktd8zTjQtOW?}MWu6H0R&WEYUA ztm~kD8sBN|vuq-;_6x!2NYVP>JC%Xzx3@PHxUzFu7_0V!0~lJK*{ztH(qy}Ai` z^Pg9WD^D%yST-rMi-;U+nelbT5LC__HttYJ*J~ZYTgIPt`Zh9EJLO&72$(XNd49C> zN?++Nw>ur~bY=+Lzk16Z8J7;=sZJ@@k44D)=2 z!OHDk>D0Ov_s^emds@-3C}vOnnlxSKrl74J8TZGmT{%wu)SI%86OxAN=0B9JmY$CG zKB}=Z&2Pm!@D$pAl1c5B1H5*1%_Y{QtN0Rk$2vo||N2eE!i7Ohx|0PziTHUCQa`6R z9lIaG=@wpo|M>f+7Dq@*E`{vEu-7a2+(!Cfci!~Bj5_pbey6%Hu8Dl^E_g$r+0c2P z0G8pGi(u;~2G&#M0Sl$;bcrv9GUz_A4+ogKJ|l32UKDUFi$mFl-*(%}Xdo`_=L3Ya1-npB~|tkM=t|3B1_0%uEQ21F|4W1Sol|gPS1I#-HQ96|C=h5Q!1S^{rq1F(0%;(a#jEW zfB_C&&SXTm-v$wlXY>4s3-|+o2hcpO6E=0kDopfpcJZPGxEqBD0E^NgrCpAkC|H1c zQE2W21QMb;GEyiUgSF6sc_M_O`iRhmHJfIWSZ-g_yp4ffPMdZJ_ZUJleOyfNHx#z(&2@S$Iz7E`4{xi`G#AItUyU@aig}AF;wB}7)a

    It works!

    \ No newline at end of file diff --git a/trunk/docs/doxygen.conf b/trunk/docs/doxygen.conf new file mode 100644 index 0000000000..9ff8250b23 --- /dev/null +++ b/trunk/docs/doxygen.conf @@ -0,0 +1,52 @@ +PROJECT_NAME=Apache + +#INPUT=srclib/apr +INPUT=. +RECURSIVE=YES +FILE_PATTERNS=*.h + +OUTPUT_DIRECTORY=docs/dox + +ENABLE_PREPROCESSING=YES +MACRO_EXPANSION=YES +QUIET=YES +EXPAND_ONLY_PREDEF=YES +#EXPAND_AS_DEFINED= +# not sure why this doesn't work as EXPAND_AS_DEFINED, it should! +PREDEFINED="APR_DECLARE(x)=x" \ + "APR_DECLARE_NONSTD(x)=x" \ + "AP_DECLARE_HOOK(ret,name,args)=ret name args;" \ + "AP_DECLARE(x)=x" \ + "AP_DECLARE_NONSTD(x)=x" \ + "APR_HAS_THREADS" \ + "APR_HAS_MMAP" \ + APR_HAS_INLINE \ + APR_HAS_FLOCK_SERIALIZE \ + APR_HAS_SYSVSEM_SERIALIZE \ + APR_HAS_POSIXSEM_SERIALIZE \ + APR_HAS_FCNTL_SERIALIZE \ + APR_HAS_PROC_PTHREAD_SERIALIZE \ + APR_HAS_RWLOCK_SERIALIZE \ + APR_HAS_SHARED_MEMORY \ + APR_HAS_SENDFILE \ + APR_HAS_FORK \ + APR_HAS_RANDOM \ + APR_HAS_XLATE \ + APR_HAS_OTHER_CHILD \ + APR_HAS_DSO \ + APR_HAS_SO_ACCEPTFILTER \ + APR_HAS_UNICODE_FS \ + APR_HAS_PROC_INVOKED \ + APR_HAS_USER \ + APR_HAS_LARGE_FILES \ + APR_HAS_XTHREAD_FILES \ + DOXYGEN= \ + APU_DECLARE_DATA= \ + __pre_nw__= \ + "APU_DECLARE(x)=x" + +OPTIMIZE_OUTPUT_FOR_C=YES + +FULL_PATH_NAMES=YES +# some autoconf guru needs to make configure set this correctly... +STRIP_FROM_PATH=/var/www/lxr/source diff --git a/trunk/docs/error/HTTP_BAD_GATEWAY.html.var b/trunk/docs/error/HTTP_BAD_GATEWAY.html.var new file mode 100644 index 0000000000..6840e96297 --- /dev/null +++ b/trunk/docs/error/HTTP_BAD_GATEWAY.html.var @@ -0,0 +1,253 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Proxy server obdr¾el od nadøazeného + serveru chybnou odpovìï. + + + + + + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der Proxy-Server erhielt eine fehlerhafte Antwort + eines übergeordneten Servers oder Proxies. + + + + + + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The proxy server received an invalid + response from an upstream server. + + + + + + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El servidor origen recibió información + inválida por parte del servidor destino. + + + + + + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Le serveur proxy a reçu une réponse + incorrecte de la part d'un serveur supérieur. + + + + + + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il server proxy ha ricevuto una risposta + non valida dal server precedente. + + + + + + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%W%m%/%7%5!<%P$O>eN.%5!<%P$+$iIT@5$J1~Ez$r + + + + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ÇÁ·Ï½Ã ¼­¹ö°¡ ´õ À­ÂÊÀÇ ¼­¹ö·ÎºÎÅÍ À߸øµÈ ÀÀ´äÀ» ¹Þ¾Ò½À´Ï´Ù. + + + + + + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De proxy server heeft een ongeldig + antwoord ontvangen van een gecontacteerde server. + + + + + + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Serwer otrzyma³ nieprawid³ow± odpowied¼ + od kolejnego serwera. + + + + + + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O servidor proxy recebeu uma resposta + inválida do servidor destino. + + + + + + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Serverul proxy a primit un raspuns invalid + de la serverul precedent. + + + + + + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Proxyservern mottog ett felaktigt svar från + en tidigare server. + + + + + + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Vekil (proxy) sunucu üstbirim (upstream) sunucusundan + anlamsız bir cevap aldı. + + + + + + + +----------tr-- diff --git a/trunk/docs/error/HTTP_BAD_REQUEST.html.var b/trunk/docs/error/HTTP_BAD_REQUEST.html.var new file mode 100644 index 0000000000..195cdd31dc --- /dev/null +++ b/trunk/docs/error/HTTP_BAD_REQUEST.html.var @@ -0,0 +1,186 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Vá¹ prohlí¾eè (nebo proxy server) vyslal po¾adavek, + kterému tento server nerozumìl. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Ihr Browser (oder Proxy) hat eine ungültige Anfrage + gesendet, die vom Server nicht beantwortet werden kann. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + Your browser (or proxy) sent a request that + this server could not understand. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El navegador ha solicitado una operación + que no puede ser procesada por el servidor. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Votre navigateur (ou votre proxy) a envoyé + une demande que ce serveur n'a pas comprise. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il tuo browser (o il proxy) ha inviato a + questo server una richiesta incomprensibile. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B$*;H$$$N%V%i%&%6(B ($B$^$?$O%W%m%/%7(B) + $B$,!"%5!<%P$NM}2r$G$-$J$$%j%/%(%9%H$rAw?.$7$^$7$?!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ºê¶ó¿ìÀú ¶Ç´Â ÇÁ·Ï½Ã°¡ + ÀÌ ¼­¹ö°¡ ó¸®ÇÒ ¼ö ¾ø´Â À߸øµÈ ¿äûÀ» º¸³Â½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Uw browser (of proxy) stuurde een vraag die + deze server niet kon begrijpen. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Twoja przegl±darka (lub serwer po¶rednicz±cy) wys³a³ ¿±danie, + którego ten serwer nie potrafi obs³u¿yæ. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + Seu "browser" (ou o servidor proxy) enviou uma + requisição inválida ao servidor. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Browserul (sau proxy-ul) dumneavoastra a trimis + serverului o cerere ce nu poate fi procesata. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Din webbläsare eller proxy skickade en förfrågan + som denna server inte kunde förstå. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Gezgininiz (veya vekil sunucunuz) bu sunucunun + tanımadığı + bir istemde bulundu. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_FORBIDDEN.html.var b/trunk/docs/error/HTTP_FORBIDDEN.html.var new file mode 100644 index 0000000000..9ac4d72e0b --- /dev/null +++ b/trunk/docs/error/HTTP_FORBIDDEN.html.var @@ -0,0 +1,326 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + + + Nemáte právo pro pøístup do po¾adovaného adresáøe. Buï neexistuje ¾ádný + dokument s obsahem (tzv. index), nebo je adresáø chránìn proti ètení. + + + + Nemáte právo pro pøístup k po¾adovanému objektu. + Buï je chránìn proti ètení, nebo není serverem èitelný. + + + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + + + Der Zugriff auf das angeforderte Verzeichnis ist nicht möglich. + Entweder ist kein Index-Dokument vorhanden oder das Verzeichnis + ist zugriffsgeschützt. + + + + Der Zugriff auf das angeforderte Objekt ist nicht möglich. + Entweder kann es vom Server nicht gelesen werden oder es + ist zugriffsgeschützt. + + + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + + + You don't have permission to access the requested directory. + There is either no index document or the directory is read-protected. + + + + You don't have permission to access the requested object. + It is either read-protected or not readable by the server. + + + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + + + Usted no tiene permiso para accesar a la dirección + solicitada. Existe la posibilidad de que el directorio + este protegido contra lectura o que no exista la + documentación requerida. + + + + Usted no tiene permiso de accesar al objeto solicitado. + Existe la posibilidad de que este protegido contra + lectura o que no haya podido ser leido por el servidor. + + + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + + + Vous n'avez pas le droit d'accéder au répertoire + demandé. Soit il n'y a pas de document index soit le répertoire + est protégé. + + + + Vous n'avez pas le droit d'accéder à l'objet + demandé. Soit celui-ci est protégé, soit il ne peut + être lu par le serveur. + + + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + + + Non disponi dei permessi necessari per accedere alla + directory richiesta oppure non esiste il documento indice. + + + + Non disponi dei permessi necessari per accedere all'oggetto + richiesto, oppure l'oggetto non può essere letto dal server. + + + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + + + $BMW5a$5$l$?%G%#%l%/%H%j$X$N%"%/%;%98"8B$,$"$j$^$;$s!#(B + $B%$%s%G%C%/%9%I%-%e%a%s%H$,B8:_$7$J$$$+!"(B + $B%G%#%l%/%H%j$NFI$_9~$_$,5v2D$5$l$F$$$^$;$s!#(B + + + + $BMW5a$5$l$?%*%V%8%'%/%H$X$N%"%/%;%98"$,$"$j$^$;$s!#(B + $BFI$_9~$_$,5v2D$5$l$F$$$J$$$+!"(B + $B%5!<%P$,FI$_9~$_$K<:GT$7$?$+$G$7$g$&!#(B + + + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + + + ¿äûÇÑ µð·ºÅ丮¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Â ±ÇÇÑÀÌ ¾ø½À´Ï´Ù. + µð·ºÅ丮¿¡ ù ÆäÀÌÁö°¡ ¾ø°Å³ª ¾Æ´Ï¸é Àб⠺¸È£°¡ µÇ¾î ÀÖ½À´Ï´Ù. + + + + ¿äûÇÑ °´Ã¼¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Â ±ÇÇÑÀÌ ¾ø½À´Ï´Ù. + Àб⠺¸È£°¡ µÇ¾î Àְųª À¥¼­¹ö°¡ ÀÐÀ» ¼ö ¾øµµ·Ï µÇ¾î ÀÖ½À´Ï´Ù. + + + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + + + U hebt niet de toestemming om toegang te krijgen tot de gevraagde map. + Er is of wel geen index document of de map is beveiligd tegen lezen. + + + + U hebt niet de toestemming om toegang te krijgen tot de gevraagde map. + Die is ofwel beveiligd tegen lezen of onleesbaar door de server. + + + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + + + Nie masz prawa dostêpu do ¿±danego katalogu. W katalogu nie + ma indeksu lub katalog jest zabezpieczony przed odczytem. + + + + Nie masz dostêpu do ¿±danego obiektu. Jest on zabezpieczony + przed odczytem lub nie mo¿e byæ odczytany przez serwer. + + + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + + + Você não tem permissão para acessar o + diretório requisitado. + Pode não existir o arquivo de índice ou + o diretório pode estar protegido contra leitura. + + + + Você não tem premissão para acessar o + objeto requisitado. Ele pode estar protegido contra leitura ou + não ser legível pelo servidor. + + + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + + + Nu aveti permisiunea sa accesati directorul cerut. + Nu este nici un document index sau directorul este protejat la citire. + + + + Nu aveti permisiunea sa accesati obiectul cerut. + Este protejat la citire sau nu poate fi citit de server. + + + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + + + Du har inte tillräckliga rättigheter för att få + tillgång till den önskade katalogen. Det existerar inget + indexdokument eller så är katalogen lässkyddad. + + + + Du har inte tillräckliga rättigheter för att få + tillgång till det önskade objektet. Objektet är + lässkyddat eller inte läsbart för servern. + + + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + + + Talep ettiğiniz dizine erişim izniniz yok. + Ya belirteç doküman yok, ya da dizin okumaya karşı korumalı. + + + + Talep ettiğiniz dizine erişim izniniz yok. + Dizin, ya okumaya karşı korumalı, ya da sunucu taraf?ndan + okunamıyor. + + + + +----------tr-- diff --git a/trunk/docs/error/HTTP_GONE.html.var b/trunk/docs/error/HTTP_GONE.html.var new file mode 100644 index 0000000000..6b66e3c4bf --- /dev/null +++ b/trunk/docs/error/HTTP_GONE.html.var @@ -0,0 +1,370 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Po¾adované URL ji¾ není na tomto serveru k dispozici, ani není k dispozici + ¾ádná adresa k pøesmìrování. + + + + Informujte, prosím, autora + ">odkazující + stránky, ¾e odkaz je zastaralý. + + + + Pokud jste následovali odkaz z cizí stránky, kontaktujte, prosím, + jejího autora. + + + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der angeforderte URL existiert auf dem Server nicht mehr + und wurde dauerhaft entfernt. + Eine Weiterleitungsadresse ist nicht verfügbar. + + + + Bitte informieren Sie den Autor der + ">verweisenden + Seite, dass der Link nicht mehr aktuell ist. + + + + Falls Sie einem Link von einer anderen Seite gefolgt sind, + informieren Sie bitte den Autor dieser Seite hierüber. + + + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The requested URL is no longer available on this server and there is no + forwarding address. + + + + Please inform the author of the + ">referring + page that the link is outdated. + + + + If you followed a link from a foreign page, please contact the + author of this page. + + + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + Los recursos solicitados ya no están disponibles en + este servidor y no existe una dirección alternativa. + + + + Le solicitamos que comunique al autor de la + ">página referente que el enlace está obsoleto. + + + + Si usted siguió el enlace desde una página externa, + por favor contacte con el autor de esa página. + + + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + L'URL demandée n'est plus accessible sur ce serveur et il + n'y a pas d'adresse de suite. + + + + Nous vous prions d'informer l'auteur de + ">la + page en question que la référence n'est plus actuelle. + + + + Si vous avez suivi une référence issue d'une page autre, + veuillez contacter l'auteur de cette page. + + + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + L'URL richiesto non è più disponibile su questo server + e non esistono indirizzi verso i quali sia possibile inoltrare + la richiesta. + + + + Per favore, informa l'autore della + ">pagina + di provenienza che il link non è più valido. + + + + Se sei arrivato da una pagina esterna, informa l'autore della + pagina di provenienza che il link non è più valido. + + + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $BMW5a$5$l$?(B URL $B$O4{$KK\%5!<%P$G$OMxMQ$G$-$^$;$s$7!"(B + $B0\F0@h$b$o$+$j$^$;$s!#(B + + + + " + >$B;2>H85%Z!<%8(B$B$NCx + + $BB>$N%Z!<%8$+$i$N%j%s%/$rC)$C$F$-$?>l9g$O!"(B + $B$=$N%Z!<%8$NCx + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¿äûÇÑ URLÀº ´õ ÀÌ»ó ÀÌ ¼­¹ö¿¡ ³²¾ÆÀÖÁö ¾ÊÀ¸¸ç, + ±× °´Ã¼°¡ ¿Å°ÜÁø ´Ù¸¥ URL ¿ª½Ã ³²¾ÆÀÖÁö ¾Ê½À´Ï´Ù. + + + + ">ÀÌÀü + ÆäÀÌÁöÀÇ ¸¸µçÀÌ¿¡°Ô ÁÖ¼Ò°¡ À߸øµÇ¾ú´Ù°í ¾Ë·ÁÁֽñ⠹ٶø´Ï´Ù. + + + + ´Ù¸¥ ÆäÀÌÁöÀÇ ¸µÅ©¸¦ µû¶ó¿À¼Ì´Ù¸é, ±× ÆäÀÌÁöÀÇ ¸¸µçÀÌ¿¡°Ô ¿¬¶ôÀ» ÇϽñâ + ¹Ù¶ø´Ï´Ù. + + + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De gevraagde URL is niet langer beschikbaar op deze server en er is geen + doorverwijsadres. + + + + Gelieve aan de auteur van + ">deze pagina + te melden dat deze link niet langer actueel is. + + + + Indien u deze link hebt gekregen van een andere pagina, gelieve + de auteur van deze pagina te contacteren. + + + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Poszukiwany zasób nie jest ju¿ dostêpny na tym serwerze i nie + podano nowego adresu zasobu. + + + + Prosimy poinformowaæ autora + ">referuj±cej + strony o nieaktualnym linku. + + + + Je¶li pod±¿y³e¶ za linkiem z innej strony skontaktuj siê z jej + autorem. + + + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + A URL solicitada não está disponível neste servidor + e não existe um endereço alternativo. + + + + Por favor informe o autor da + ">página + referida que a URL está desatualizada. + + + + Se você seguiu um "link" de uma página externa, por favor + entre em contato com o autor desta página e o informe sobre a + mudança do "link". + + + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + URL-ul cerut nu mai este disponibil pe acest server si nu + exista o adresa de inaintare. + + + + Va rugam informati autorul + ">paginii + referite ca link-ul nu mai este de actualitate. + + + + Va rugam contactati autorul acestei pagini daca ati urmat + un link dintr-o pagina externa. + + + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Den önskade adressen är inte längre tillgänglig hos + denna server och det finns inte någon adress för vidarebefodran. + + + + Vänligen informera författaren bakom + ">den aktuella + sidan att länken är inaktuell. + + + + Om du följde en länk från en extern sida, vänligen + kontakta författaren av den sidan. + + + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Talep ettiğiniz URL bu sunucu üzerinde barındırılmıyor + ve herhangi bir yöneltme de mevcut değil. + + + + Lütfen + ">referans sayfanın + yazarına, bu bağlantının güncel + olmadığını bildirin. + + + + Yabancı bir sayfadan bu bağlantıyı izlediyseniz, + lütfen sözkonusu sayfanın yazarı ile iletişime geçin. + + + + +----------tr-- diff --git a/trunk/docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var b/trunk/docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var new file mode 100644 index 0000000000..195c74d748 --- /dev/null +++ b/trunk/docs/error/HTTP_INTERNAL_SERVER_ERROR.html.var @@ -0,0 +1,395 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + + + Nastala vnitøní chyba a server nebyl schopen + dokonèit Vá¹ po¾adavek. + + + + Chybová zpráva +
    + + + + Nastala vnitøní chyba a server nebyl schopen + dokonèit Vá¹ po¾adavek. Buï je server + pøetí¾en, nebo do¹lo k chybì v CGI skriptu. + + + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + + + Die Anfrage kann nicht beantwortet werden, da im Server + ein interner Fehler aufgetreten ist. + + + + Fehlermeldung: +
    + + + + Die Anfrage kann nicht beantwortet werden, da im Server + ein interner Fehler aufgetreten ist. + Der Server ist entweder überlastet oder ein Fehler in + einem CGI-Skript ist aufgetreten. + + + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + + + The server encountered an internal error and was + unable to complete your request. + + + + Error message: +
    + + + + The server encountered an internal error and was + unable to complete your request. Either the server is + overloaded or there was an error in a CGI script. + + + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + + + El servidor encontro un error interno y fue + imposible completar su solicitud. + + + + Mensaje de error: +
    + + + + El servidor encontro un error interno y fue + imposible completar su solicitud. + Existe tambien la posibilidad de que el servidor + este sobrecargado o de algún error en un + programa de CGI. + + + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + + + Le serveur a èté victime d'une erreur interne et n'a pas + été capable de faire aboutir votre requête. + + + + Message d'erreur: +
    + + + + Le serveur a èté victime d'une erreur interne et n'a pas + été capable de faire aboutir votre requête. + Soit le server est surchargé soit il s'agit d'une erreur dans + le script CGI. + + + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + + + Il server ha generato un errore interno e non è + in grado di soddisfare la richiesta. + + + + Messaggio di errore: +
    + + + + Il server ha generato un errore interno e non è + in grado di soddisfare la richiesta. Il server potrebbe + essere sovraccarico oppure si è verificato un + errore in uno script CGI. + + + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + + + $B%5!<%PFbIt$G>c32$,H/@8$7!"(B + $B%j%/%(%9%H$K1~$($k$3$H$,$G$-$^$;$s$G$7$?!#(B + + + + Error message: +
    + + + + $B%5!<%PFbIt$G>c32$,H/@8$7!"(B + $B%j%/%(%9%H$K1~$($k$3$H$,$G$-$^$;$s$G$7$?!#(B + $B%5!<%P$,2aIi2Y$G$"$k$+!"(B + CGI $B%9%/%j%W%H$K%(%i!<$,$"$j$^$9!#(B + + + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + + + ¼­¹ö¿¡ ³»ºÎ ¿À·ù°¡ ¹ß»ýÇÏ¿© ¿äûÀ» ³¡±îÁö ó¸®ÇÏÁö ¸øÇß½À´Ï´Ù. + + + + ¿À·ù ³»¿ë: +
    + + + + ¼­¹ö¿¡ ³»ºÎ ¿À·ù°¡ »ý°Ü ¿äûÀ» ³¡±îÁö ó¸®ÇÏÁö ¸øÇß½À´Ï´Ù. + ¼­¹ö¿¡ °úºÎÇÏ°¡ °É·È°Å³ª ¾Æ´Ï¸é CGI ÇÁ·Î±×·¥¿¡ ¿À·ù°¡ ÀÖ¾ú½À´Ï´Ù. + + + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + + + + + Foutbericht: +
    + + + + De server kreeg een interne fout en kon + uw vraag niet beantwoorden. De server is overbelast + of er was een fout in een CGI script. + + + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + + + Serwer napotka³ b³±d wewnêtrzny i nie jest w stanie + zrealizowaæ twojego ¿±dania. + + + + Informacja o b³êdzie: +
    + + + + Serwer napotka³ b³±d wewnêtrzny i nie jest w stanie + zrealizowaæ twojego ¿±dania. Serwer jest przeci±¿ony lub + napotka³ na b³±d w skrypcie CGI. + + + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + + + O servidor encontrou um erro interno e não pode + completar sua requisição. + + + + Mensagem de Erro: +
    + + + + O servidor encontrou um erro interno e não + foi possível completar sua requisição. + O servidor está sobrecarregado ou existe um + erro em um script CGI. + + + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + + + Serverul a intalnit o eroare interna si nu a + putut rezolva cererea dumneavoastra. + + + + Mesajul de eroare : +
    + + + + Serverul a intalnit o eroare interna si nu a + putut rezolva cererea dumneavoastra. Serverul este + supraincarcat sau a fost o eroare intr-un script CGI. + + + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + + + Servern råkade ut för ett internt fel och det var inte möjligt + att slutföra din begäran. + + + + Felmeddelande: +
    + + + + Servern råkade ut för ett internt fel och det var inte möjligt + att slutföra din begäran. Servern är antingen överbelastad + eller så innehåller CGI-skriptet fel. + + + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + + + Sunucu içine bir hata oluştu ve sunucu talebinize hizmet vermekte başarılı olamadı. + + + + Hata mesajı: +
    + + + + Sunucu içine bir hata oluştu ve sunucu talebinize hizmet vermekte başarılı olamadı. + Ya sunucuya çok yüklenildi, ya da CGI betiklerinde hata belirdi. + + + + +----------tr-- diff --git a/trunk/docs/error/HTTP_LENGTH_REQUIRED.html.var b/trunk/docs/error/HTTP_LENGTH_REQUIRED.html.var new file mode 100644 index 0000000000..9d6b15667d --- /dev/null +++ b/trunk/docs/error/HTTP_LENGTH_REQUIRED.html.var @@ -0,0 +1,192 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Po¾adavek metodou + vy¾aduje korektní hlavièku Content-Length. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Die Anfrage kann nicht beantwortet werden. + Bei Verwendung der -Methode + muß ein korrekter Content-Length-Header + angegeben werden. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + A request with the + method requires a valid Content-Length header. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + Una solicitud con el método + necesita una cabecera Content-Length válida. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Une requête utilisant la méthode nécessite un header valable + Content-Length (indiquant la longueur). + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Una richiesta con il metodo + + richiede che venga specificato un header Content-Length + valido. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + + $B%a%=%C%I$N%j%/%(%9%H$G$O!"(B + $B@5$7$$(B Content-Length $B%X%C%@$,I,MW$K$J$j$^$9!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¹æ½ÄÀ» ¾²´Â + ¿äûÀº ¿Ã¹Ù¸¥ Content-Length Çì´õµµ ÇÔ²² º¸³»¾ß¸¸ ÇÕ´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Een vraag met het + type methode heeft een correcte Content-Length lijn nodig. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + ¯±danie + wymaga poprawnego nag³ówka Content-Length. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + Uma requisição + do método + requer um cabeçalho Content-Length válido. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + O cerere cu metoda + necesita un header Content-Length valid. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + En förfrågan med + metoden kräver ett korrekt Content-Length huvud. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + metodunu kullanan bir talep + geçerli bir Content-Length (içerik uzunluğu) başlığı gerektirir. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_METHOD_NOT_ALLOWED.html.var b/trunk/docs/error/HTTP_METHOD_NOT_ALLOWED.html.var new file mode 100644 index 0000000000..4316dc1c9d --- /dev/null +++ b/trunk/docs/error/HTTP_METHOD_NOT_ALLOWED.html.var @@ -0,0 +1,186 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Metoda + není pro po¾adované URL povolena. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Die -Methode + ist für den angeforderten URL nicht erlaubt. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The + method is not allowed for the requested URL. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El + método utilizado por su solicitud no está + permitido por el enlace. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + La méthode + n'est pas utilisable pour l'URL requise. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il metodo + non è consentito per l'URL richiesto. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + + $B%a%=%C%I$O!"MW5a$5$l$?(B URL $B$KBP$7$F$O5v2D$5$l$F$$$^$;$s!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¹æ½ÄÀº + ¿äûÇÑ URL¿¡ »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Het + type methode is niet toegelaten voor de gevraagde URL. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Metoda + jest niedozwolona dla podanego URLa. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O método + não é permitido para a URL requisitada. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Metoda + nu este permisa pentru URL-ul cerut. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + + metoden är inte tillåten för den förfrågade + adressen. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + yöntemi talep ettiğiniz URL için kullanılamaz. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_NOT_FOUND.html.var b/trunk/docs/error/HTTP_NOT_FOUND.html.var new file mode 100644 index 0000000000..3b77bee7c8 --- /dev/null +++ b/trunk/docs/error/HTTP_NOT_FOUND.html.var @@ -0,0 +1,379 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Po¾adované URL nebylo na tomto serveru nalezeno. + + + + Zdá se, ¾e odkaz na + ">odkazující + stránce je chybný nebo zastaralý. Informujte, prosím, autora + ">této stránky + o chybì. + + + + Pokud jste zadal(a) URL ruènì, zkontrolujte, prosím, + zda jste zadal(a) URL správnì, a zkuste to znovu. + + + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der angeforderte URL konnte auf dem Server nicht gefunden werden. + + + + Der Link auf der + ">verweisenden + Seite scheint falsch oder nicht mehr aktuell zu sein. + Bitte informieren Sie den Autor + ">dieser Seite + über den Fehler. + + + + Sofern Sie den URL manuell eingegeben haben, + überprüfen Sie bitte die Schreibweise und versuchen Sie es erneut. + + + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The requested URL was not found on this server. + + + + The link on the + ">referring + page seems to be wrong or outdated. Please inform the author of + ">that page + about the error. + + + + If you entered the URL manually please check your + spelling and try again. + + + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El enlace requerido no ha sido localizado en + este servidor. + + + + El enlace en la + ">página + referente parece tener algun error o ha expirado. Por favor + comunique al autor de + ">la + página el error. + + + + Si usted proporcionó el enlace de manera manual le solicitamos + que por favor revise los datos e intentelo de nuevo. + + + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + L'URL requise n'a pu etre trouvée sur ce serveur. + + + + La référence sur + ">la page + citée + semble être erronée ou perimée. Nous vous prions + d'informer l'auteur de + ">cette page + de cette erreur. + + + + Si vous avez tapé l'URL à la main, veuillez vérifier + l'orthographe et réessayer. + + + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + L'URL richiesto non esiste su questo server. + + + + Il link della + ">pagina da cui + sei arrivato potrebbe essere errato o non essere più valido. + Per favore, informa dell'errore l'autore della + ">pagina. + + + + Se hai scritto l'URL a mano, per favore controlla che + non ci siano errori. + + + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $BMW5a$5$l$?(B URL $B$OK\%5!<%P$G$O8+$D$+$j$^$;$s$G$7$?!#(B + + + + "> + $B;2>H85%Z!<%8(B$B$N%j%s%/$,4V0c$C$F$$$k$+!"8E$/$J$C$F$7$^$C$F$$$k$h$&$G$9!#(B + " + >$B%Z!<%8(B$B$NCx + + $B$b$7l9g$O!"DV$j$r3NG'$7$F:FEY$*;n$72<$5$$!#(B + + + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¿äûÇÑ URLÀ» ÀÌ ¼­¹ö¿¡¼­ ãÀ» ¼ö ¾ø½À´Ï´Ù. + + + + ">ÀÌÀü + ÆäÀÌÁö¿¡ ÀÖ´Â ¸µÅ©°¡ À߸øµÇ¾ú°Å³ª ¿À·¡µÇ¾î ¾ø¾îÁø °Í °°½À´Ï´Ù. + ">±× ÆäÀÌÁö¸¦ + ¸¸µçÀÌ¿¡°Ô ÀÌ »ç½ÇÀ» ¾Ë·ÁÁֽñ⠹ٶø´Ï´Ù. + + + + URLÀ» Á÷Á¢ ÀÔ·ÂÇÏ¼Ì´Ù¸é ¹Ù¸£°Ô ÀÔ·ÂÇϼ̴ÂÁö È®ÀÎÇÏ½Ã°í ´Ù½Ã ½ÃµµÇϽñâ + ¹Ù¶ø´Ï´Ù. + + + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De gevraagde URL was niet gevonden op deze server. + + + + De link op + ">deze pagina + pagina is verkeerd of achterhaald. Gelieve de auteur van + ">die pagina + in te lichten over deze fout. + + + + Indien u de URL manueel hebt ingevuld, gelieve uw + spelling te controleren en probeer opnieuw. + + + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Nie znaleziono ¿±danego URLa na tym serwerze. + + + + Odno¶nik na + ">referuj±cej stronie + wydaje siê byæ nieprawid³owy lub nieaktualny. Poinformuj autora + ">tej strony + o problemie. + + + Je¶li wpisa³e¶ URLa rêcznie, sprawd¼, czy nie siê nie pomyli³e¶. + + + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + A URL requisitada não foi encontrada neste servidor. + + + + O link na + ">página + referida parece estar com algum erro ou desatualizado. Por favor informe o + autor ">desta + página sobre o erro. + + + + Se você digitou o endereço (URL) manualmente, + por favor verifique novamente a sintaxe do endereço. + + + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + URL-ul cerut nu a fost gasit pe acest server. + + + + Link-ul de pe + ">pagina + de unde ati venit pare a fi gresit sau invechit. Va rugam informati autorul + ">acestei pagini + despre eroare. + + + + Daca ati introdus URL-ul manual, va rugam verificati + corectitudinea si incercati din nou. + + + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Den efterfrågade adressen hittades inte på denna server. + + + + Länken på den + ">tidigare sidan + verkar vara felaktig eller inaktuell. Vänligen informera författaren av + ">sidan + om felet. + + + + Om du skrev in adressen manuellt så kontrollera din stavning och + försök igen. + + + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Talep ettiğiniz URL, sunucu üzerinde bulunmuyor. + + + + ">Referans sayfa + üzerindeki bağlantı güncel değil. + Lütfen ">referans sayfa'nın + yazarını konuyla ilgili bilgilendirin. + + + + URL'i kendiniz elle girdiyseniz, yazımınızı denetleyip tekrar deneyin. + + + + +----------tr-- diff --git a/trunk/docs/error/HTTP_NOT_IMPLEMENTED.html.var b/trunk/docs/error/HTTP_NOT_IMPLEMENTED.html.var new file mode 100644 index 0000000000..9e980eecba --- /dev/null +++ b/trunk/docs/error/HTTP_NOT_IMPLEMENTED.html.var @@ -0,0 +1,176 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Server nepodporuje akci po¾adovanou prohlí¾eèem. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Die vom Browser angeforderte Aktion wird vom Server + nicht unterstützt. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The server does not support the action requested by the browser. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El navegador está solicitando una acción + que no puede ser procesada. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Le serveur n'est pas en mesure d'effectuer l'action + requise par le navigateur. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il server non supporta il tipo di azione richiesta dal browser. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%V%i%&%6$NMW5a$7$?%"%/%7%g%s$O!"%5%]!<%H$7$F$$$^$;$s!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ºê¶ó¿ìÀú°¡ º¸³½ ¿äûÀ» ÀÌ ¼­¹ö°¡ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De server ondersteunt de actie, gevraagd door de browser, niet. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Ten serwer nie obs³uguje ¿±dania przes³anego przez przegl±darkê. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O servidor não suporta a ação requisitada pelo + seu "browser". + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Serverul nu suporta actiunea ceruta de browser. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Servern stödjer inte den handling som önskades + av webbläsaren. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Sunucu, gezgin tarafından talep edilen yöntemi desteklemiyor. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_PRECONDITION_FAILED.html.var b/trunk/docs/error/HTTP_PRECONDITION_FAILED.html.var new file mode 100644 index 0000000000..31faf17317 --- /dev/null +++ b/trunk/docs/error/HTTP_PRECONDITION_FAILED.html.var @@ -0,0 +1,180 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Vstupní podmínka pro po¾adavek o zadané URL nesplnila pozitivní + vyhodnocení. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Die für den Abruf der angeforderten URL notwendige + Vorbedingung wurde nicht erfüllt. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The precondition on the request for the URL failed positive evaluation. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + La precondición para que exista una + conexión a la dirección solicitada es falsa. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + La précondition pour l'URL requise a été + évaluée négativement. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + I criteri di precondizione per consentire l'invio dell'URL + richiesto non sono stati soddisfatti. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B;XDj$5$l$?(B URL $B$X$N%j%/%(%9%H$K$*$1$k;vA0>r7o$,K~$?$5$l$^$;$s$G$7$?!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¹Ì¸® ÁÖ¾îÁø Á¶°ÇÀÌ ¸¸Á·µÇÁö ¾Ê¾Æ¼­ URL ¿äûÀ» ó¸®ÇÒ ¼ö ¾ø½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Een startvoorwaarde werd niet voldaan bij verwerking van de vraag naar de URL. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Warunek wstêpny dla URLa nie zosta³ spe³niony. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + A condição necessária para a + requisição da URL foi avaliada como falsa. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Preconditionarea pentru cererea URL-ului nu a fost evaluata pozitiv. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Den nödvändiga förutsättningen för + adressförfrågan passerade inte utvärderingen + med acceptabelt resultat. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + URL talebinin önşartı, olumlu süreci + başarısızlıkla sonlandırdı. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var b/trunk/docs/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var new file mode 100644 index 0000000000..7215e0c48b --- /dev/null +++ b/trunk/docs/error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var @@ -0,0 +1,198 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Metoda + nedovoluje pøenos dat nebo objem dat + pøesahuje kapacitní limit. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Die bei der Anfrage übermittelten Daten sind für + die -Methode + nicht erlaubt oder die Datenmenge hat das Maximum überschritten. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The + method does not allow the data transmitted, or the data volume + exceeds the capacity limit. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + Los recursos establecidos no permiten peticiones con + el método + suministrado por su solicitud, o, la cantidad de datos + provistos exceden los límites de capacidad. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + La méthode + n'autorise pas le transfert de ces données ou bien le volume + des données excède la limite de capacité. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il metodo + non consente di trasferire dati, oppure la quantità di dati + richiesti è eccessiva. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + + $B%a%=%C%I$,%G!<%?$NAw?.$r5v2D$7$F$$$J$$$+!"(B + $B%G!<%?NL$,5vMFNL$rD6$($F$$$^$9!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¹æ½ÄÀÇ + ¿äûÀ¸·Î´Â ³»¿ëÀ» º¸³¾ ¼ö ¾ø°Å³ª, ¶Ç´Â º¸³»¿Â ³»¿ëÀÌ ±× ¹æ½Ä¿¡¼­ Çã¿ëÇÏ´Â + ÃÖ´ë ±æÀ̸¦ ³Ñ¾ú½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Het type methode laat niet toe + data te versturen of het datavolume is groter dan maximaal toegelaten. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Metoda + nie zezwala na typ przesy³anych danych lub rozmiar danych przekracza + ustalony limit. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O método + não permite a transmissão dos dados, + ou o volume de dados excede a capacidade limite. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Metoda + nu permite transmiterea datelor, sau volumul de date + depaseste limita capacitatii. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + metoden tillåter + inte den skickade datan eller så överskrider datavolymen + kapacitetsnivån. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + yöntemi iletilen + veri tipini desteklemez, ya da veri hacmi kapasite limitlerini aşıyor. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_REQUEST_TIME_OUT.html.var b/trunk/docs/error/HTTP_REQUEST_TIME_OUT.html.var new file mode 100644 index 0000000000..8acdfca4d2 --- /dev/null +++ b/trunk/docs/error/HTTP_REQUEST_TIME_OUT.html.var @@ -0,0 +1,190 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Server uzavøel sí»ové spojení, proto¾e prohlí¾eè + nedokonèil po¾adavek ve stanoveném èase. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der Server konnte nicht mehr länger auf die Beendigung + der Browseranfrage warten; die Netzwerkverbindung wurde + vom Server geschlossen. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The server closed the network connection because the browser + didn't finish the request within the specified time. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El servidor ha cerrado la conexión de red + debido a que el navegador no terminó la solicitud + dentro del tiempo especificado. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Le serveur a fermé la connection car le navigateur n'a pas + fini la requête dans le temps spécifié. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il server ha chiuso la connessione in quanto è stato + superato il limite di tempo entro il quale il browser avrebbe + dovuto eseguire la richiesta. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%V%i%&%6$,;XDj;~4V0JFb$K%j%/%(%9%H$r40N;$7$J$+$C$?$N$G!"(B + $B%5!<%P$O@\B3$r@Z$j$^$7$?!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ºê¶ó¿ìÀú°¡ ³Ê¹« ¿À·§µ¿¾È ¿äûÀ» ³¡³»Áö ¾Ê¾Æ¼­ ¼­¹ö°¡ ³×Æ®¿öÅ© ¿¬°áÀ» + °­Á¦·Î ²÷¾ú½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De server heeft de netwerkverbinding gesloten omdat de browser + de vraag niet heeft beëindigd binnen een gestelde tijd. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Serwer zamkn±³ po³±czenie sieciowe poniewa¿ przegl±darka + nie zakoñczy³a operacji w przewidywanym czasie. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O servidor encerrou a conexão porque o "browser" + não finalizou a requisição dentro + do tempo limite. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Serverul a terminat conexiunea cu browserul pentru ca acesta + nu a terminat cererea in limita timpului specificat. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Servern stängde förbindelsen därför att + webbläsaren inte avslutade förfrågan inom + förbestämd tid. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Sunucu ağ bağlantısını kapattı çünkü gezgin + talebini belirlenmiş süre içinde tamamlayamadı. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_REQUEST_URI_TOO_LARGE.html.var b/trunk/docs/error/HTTP_REQUEST_URI_TOO_LARGE.html.var new file mode 100644 index 0000000000..8cac2a9db7 --- /dev/null +++ b/trunk/docs/error/HTTP_REQUEST_URI_TOO_LARGE.html.var @@ -0,0 +1,190 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Délka po¾adovaného URL pøesahuje kapacitní limit tohoto + serveru. Po¾adavek nemù¾e být zpracován. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der bei der Anfrage übermittelte URI überschreitet + die maximale Länge. + Die Anfrage kann nicht ausgeführt werden. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The length of the requested URL exceeds the capacity limit for + this server. The request cannot be processed. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + Su solicitud no puede procesarse debido a que la + longitud del enlace excede la capacidad límite del + servidor. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + La longueur de l'URL demandée excède la limite de + capacitè pour ce serveur. Nous ne pouvons donner suite + à votre requête. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + La lunghezza dell'indirizzo (URL) trasmesso supera il + limite massimo imposto da questo server. + La richiesta non può essere soddisfatta. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%j%/%(%9%H$N(B URL $B$ND9$5$,!"07$($kD9$5$rD6$($F$$$^$9!#(B + $B%j%/%(%9%H$N=hM}$rB3$1$i$l$^$;$s!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¿äûÇÑ URLÀÌ ³Ê¹« ±æ¾î¼­ ÀÌ ¼­¹ö°¡ ó¸®ÇÒ ¼ö ¾ø½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De lengte van de aangeboden URL overschreidt het maximum + voor deze server. De vraag kan niet verwerkt worden. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + D³ugo¶æ ¿±danego URLa przekracza limit ustanowiony dla tego + serwera. ¯±danie nie mo¿e zostaæ zrealizowane. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O tamanho do endereço (URL) excede a capacidade limite + desse servidor. A requisição não pode ser + processada. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Lungimea URL-ului cerut depaseste limita capacitatii pentru + acest server. Cererea nu poate fi procesata. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Längden på adressen som efterfrågas överskrider + kapacitetsgränsen för denna server. Förfrågan kan + inte verkställas. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Talep edilen URL'nin uzunluğu, sunucunun kapasite limitlerini aşıyor. + Talep işlenemiyor. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_SERVICE_UNAVAILABLE.html.var b/trunk/docs/error/HTTP_SERVICE_UNAVAILABLE.html.var new file mode 100644 index 0000000000..cffa681caa --- /dev/null +++ b/trunk/docs/error/HTTP_SERVICE_UNAVAILABLE.html.var @@ -0,0 +1,205 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Server doèasnì nemù¾e zpracovat Vá¹ po¾adavek + kvùli údr¾bì nebo kapacitním problémùm. + Zkuste to, prosím, pozdìji. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der Server ist derzeit nicht in der Lage die Anfrage + zu bearbeiten. Entweder ist der Server derzeit überlastet + oder wegen Wartungsarbeiten nicht verfügbar. + Bitte versuchen Sie es später wieder. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The server is temporarily unable to service your + request due to maintenance downtime or capacity + problems. Please try again later. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El servidor no puede atender su solicitud por + el momento debido a problemas de mantenimiento + o de capacidad. + + Le solicitamos que por favor repita la operación + más tarde. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + En raison de travaux de maintenance ou de problèmes + de capacité le serveur n'est pas en mesure de répondre + à votre requête pour l'instant. Veuillez réessayer + plus tard. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il server in questo momento non è in grado di + soddisfare la richiesta per motivi di manutenzione + o di sovraccarico del sistema. + Per favore, riprova più tardi. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%a%s%F%J%s%9$GDd;_Cf$+!"%5!<%P$N=hM}G=NO$NLdBj$N$?$a!"(B + $B8=:_%j%/%(%9%H$K1~$8$k$3$H$,$G$-$^$;$s!#(B + $B8e$[$I:FEY$*;n$72<$5$$!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + °ü¸® ÀÛ¾÷À̳ª ¿ë·® ¹®Á¦·Î ¼­¹ö°¡ Àá½Ãµ¿¾È ¿äûÀ» ó¸®ÇÒ ¼ö ¾ø½À´Ï´Ù. + ³ªÁß¿¡ ´Ù½Ã ½ÃµµÇØÁֽñ⠹ٶø´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De server kan tijdelijk uw vraag niet verwerken + door onderhoud of problemen met de capaciteit van de server. + Gelieve later nog eens opnieuw te proberen. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Serwer nie mo¿e zrealizowaæ twojego ¿±dania + ze wzglêdu na konserwacjê lub zbyt du¿e obci±¿enie. + Prosimy spróbowaæ pó¼niej. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O servidor está temporariamente fora de serviço + para manutanção ou devido a problemas de capacidade. + Por favor tente acessar mais tarde. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Serverul nu poate, temporar, sa raspunda cererii + dumneavoastra datorita intretinerii acestuia sau a + unor probleme de capacitate. Va rugam incercati mai tarziu. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Servern är för tillfället oförmögen att + utföra din förfrågan på grund av underhåll + eller kapacitetsbegränsningar. Vänligen försök + igen senare. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Sunucu, kendi içindeki çeşitli sorunlardan ötürü, + bir süreliğine taleplerinize cevap veremeyecek. + Lütfen daha sonra tekrar deneyin. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_UNAUTHORIZED.html.var b/trunk/docs/error/HTTP_UNAUTHORIZED.html.var new file mode 100644 index 0000000000..b5fb0e4dc9 --- /dev/null +++ b/trunk/docs/error/HTTP_UNAUTHORIZED.html.var @@ -0,0 +1,292 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Server nemohl ovìøit, ¾e jste autorizován(a) k pøístupu + k URL "". + Buï jste dodal(a) neplatné povìøení (napø. chybné heslo) nebo Vá¹ + prohlí¾eè neumí dodat po¾adované ovìøení. + + + + V pøípadì, ¾e smíte po¾adovat tento dokument, zkontrolujte, prosím, + Va¹i u¾ivatelskou identifikaci a heslo a zkuste to znovu. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Der Server konnte nicht verifizieren, ob Sie autorisiert sind, + auf den URL "" zuzugreifen. + Entweder wurden falsche Referenzen (z.B. ein falsches Passwort) + angegeben oder ihr Browser versteht nicht, wie die geforderten + Referenzen zu übermitteln sind. + + + + Sofern Sie für den Zugriff berechtigt sind, überprüfen + Sie bitte die eingegebene User-ID und das Passwort und versuchen Sie + es erneut. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + This server could not verify that you are authorized to access + the URL "". + You either supplied the wrong credentials (e.g., bad password), or your + browser doesn't understand how to supply the credentials required. + + + + In case you are allowed to request the document, please + check your user-id and password and try again. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + El servidor no puede certificar que usted este autorizado + para acceder al enlace "". + Usted pudo suministrar información errónea accidentalmente + (ejem. una contraseña inválida) o, el navegador no sabe + como suministrar la información requerida. + + + + En caso de que a usted le este permitido el uso del + documento requerido, le solicitamos de la manera más atenta + que por favor vuelva a intentar la operación suministrando + nuevamente su identificador y su contraseña. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Ce server n'a pas été en mesure de vérifier que + vous êtes autorisé à accéder à cette + URL "". + + Vous avez ou bien fourni des coordonnées erronées + (p.ex. mot de passe inexact) ou bien votre navigateur ne parvient + pas à fournir les données exactes. + + + + Si vous êtez autorisé à requérir le document, + veuillez vérifier votre nom d'utilisateur et votre mot de passe + et réessayer. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Questo server non può verificare l'autorizzazione + all'accesso a "". + Questo errore potrebbe essere causato da credenziali errate + (nome utente o password errata) oppure da un browser che non + riesce a comunicare il nome utente e la password in modo corretto. + + + + Nel caso in cui ritieni di aver diritto ad accedere al documento, + controlla il nome utente e la password forniti e riprova. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + URL "" + $B$X$N%"%/%;%98"8B$,$"$k$3$H$r3NG'$G$-$^$;$s$G$7$?!#(B + $B4V0c$C$?;q3J>pJs(B ($BNc$($P!"8m$C$?%Q%9%o!<%I(B) $B$rF~NO$7$?$+!"(B + $B%V%i%&%6$,I,MW$J;q3J>pJs$rAw?.$9$kJ}K!$rM}2r$7$F$$$J$$$+$G$9!#(B + + + + $B%I%-%e%a%s%H$rMW5a$G$-$kH&$G$"$k>l9g$O!"(B + $B%f!<%6(B ID $B$H%Q%9%o!<%I$r:F3NG'$7$F2<$5$$!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ÀÌ ¼­¹ö°¡ "" URLÀ» + Á¢±ÙÇÒ ¼ö ÀÖ´Â ±ÇÇÑÀÌ ÀÖ´ÂÁö È®ÀÎÇÏÁö ¸øÇß½À´Ï´Ù. + À߸øµÈ ÀÎÁõ Á¤º¸(°¡·É, À߸øµÈ ¾ÏÈ£)¸¦ º¸³Â°Å³ª ¾Æ´Ï¸é + »ç¿ëÇϽô ºê¶ó¿ìÀú°¡ ÇÊ¿äÇÑ ÀÎÁõ Á¤º¸¸¦ ¾î¶»°Ô º¸³»´ÂÁö ¸ð¸£´Â °ÍÀÔ´Ï´Ù. + + + + ÀÌ ¹®¼­¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï Çã°¡¸¦ ¹Þ¾Ò´Âµ¥µµ ÀÌ·±´Ù¸é, + »ç¿ëÀÚ ID¿Í ¾ÏÈ£¸¦ È®ÀÎÇÏ½Ã°í ´Ù½Ã ½ÃµµÇϽñ⠹ٶø´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De server kon niet controleren of u gemachtigd bent om toegang te krijgen + tot de URL "". + U hebt zich onvoldoende geauthenticeerd ( vb : verkeerd paswoord ), of + uw browser is niet in staat de nodige authentificatiegegevens door te geven. + + + + Indien u toch gemachtigd bent toegang te krijgen tot het document, + controleer uw gebruikersnaam en paswoord en probeer opnieuw. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Serwer nie mo¿e zweryfikowaæ, ¿e masz uprawnienia dostêpu do + URLa "". + Nie poda³e¶ prawid³owych danych autoryzacyjnych (np. has³a), + lub twoja przegl±darka nie potrafi ich przes³aæ. + + + + Je¶li masz prawo dostêpu do ¿±danego dokumentu, sprad¼ + podan± nazwê u¿ytkownika i has³o. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + Este servidor não pode autorizar o seu acesso à URL + "". + Você deve ter fornecido dados incorretos (ex. senha errada), ou o seu + "browser" não fornece as credenciais necessárias. + + + + No caso de você realmente possuir permissão para este documento, + por favor checar seu login e sua senha e tentar novamente. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Acest server nu a putut verifica daca sunteti autorizat sa accesati + URL-ul "". + Ati furnizat parametrii de acreditare gresiti (ex: parola gresita), sau browserul + dumneavoastra nu poate furniza aceste detalii de acreditare. + + + + In cazul in care nu va este permis sa cereti un document, va rugam + sa va verificati numele de utilizator si parola si sa incercati din nou. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Servern kunde inte verifiera att du har tillåtelse att besöka + adressen "". + Antingen angav du felaktiga uppgifter (ex. fel lösenord) eller så + stödjer inte din webbläsare detta autentiseringssätt. + + + + Om du har tillåtelse att besöka sidan, vänligen kontrollera ditt + användarnamn samt lösenord och försök igen. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Sunucu bu dokümana erişim izninizi doğrulayamadı. + Ya kimliğiniz doğrulanamadı (örneğin hatalı parola girdiniz), + ya da gezgininiz bu işlemi yerine getiremiyor. + + + + Eğer bu dokümana erişme izniniz varsa, lütfen kimliğinizi + ve parolanızı kontrol edip, tekrar deneyin. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var b/trunk/docs/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var new file mode 100644 index 0000000000..d6e5ac0201 --- /dev/null +++ b/trunk/docs/error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var @@ -0,0 +1,176 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Server nepodporuje typ prostøedku (media) pøeneseného v po¾adavku. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Das bei der Anfrage übermittelte Format (Media Type) + wird vom Server nicht unterstützt. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + The server does not support the media type transmitted in the request. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + Los datos de su solicitud no se encuentran en + un formato aceptado por este recurso. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Le serveur ne supporte pas le type de média utilisé + dans votre requête. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Il server non è in grado di gestire il + tipo del formato dei dati trasmesso nella richiesta. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%j%/%(%9%H$G;XDj$5$l$?%a%G%#%"%?%$%W$O%5%]!<%H$5$l$F$$$^$;$s!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¿äûÀ¸·Î º¸³»¿Â ¹Ìµð¾î Çü½ÄÀ» ÀÌ ¼­¹ö°¡ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + De server ondersteunt het gevraagde formaat ( media type ) niet. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Serwer nie zna typu danych przes³anych w ¿±daniu. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + O servidor não suporta o tipo de mídia + transmitida nesta requisição. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + Serverul nu suporta tipul de date trimise in cerere. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + Servern stödjer inte den mediatyp som skickats i förfrågan. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Sunucu, talep içinde iletilen ortam türünü desteklemiyor. + + +----------tr-- diff --git a/trunk/docs/error/HTTP_VARIANT_ALSO_VARIES.html.var b/trunk/docs/error/HTTP_VARIANT_ALSO_VARIES.html.var new file mode 100644 index 0000000000..df53f3b180 --- /dev/null +++ b/trunk/docs/error/HTTP_VARIANT_ALSO_VARIES.html.var @@ -0,0 +1,194 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- + + + Varianta po¾adované entity má sama více variant. Pøístup není mo¾ný. + + +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- + + + Ein Zugriff auf das angeforderte Objekt bzw. einer + Variante dieses Objektes ist nicht möglich, da es ebenfalls + ein variables Objekt darstellt. + + +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- + + + A variant for the requested entity + is itself a negotiable resource. + Access not possible. + + +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- + + + No es posible tener acceso debido a que + una variante de la solicitud es por si + misma un recurso negociable. + + +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- + + + Une variante pour l'entité requise + est elle-même une ressource négociable. + L'accès est impossible. + + +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- + + + Non è possibile accedere all'entità + richiesta perché ` essa stessa + una risorsa negoziabile. + + +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- + + + $B%j%/%(%9%H$5$l$?$b$N$N(B variant + $B$O$=$l<+BN$b$^$?!"%M%4%7%(!<%7%g%s2DG=$J%j%=!<%9$G$9!#(B + $B%"%/%;%9$G$-$^$;$s$G$7$?!#(B + + +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- + + + ¿äûÇÑ °´Ã¼ÀÇ ÇüÅ ¶ÇÇÑ ¿©·¯ ÇüŸ¦ °¡Áö°í À־ + Á¢±ÙÀÌ ºÒ°¡´ÉÇÕ´Ï´Ù. + + +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- + + + Een variant van het gevraagde object + is op zich ook een te onderhandelen variant. + Toegang is niet mogelijk. + + +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- + + + Wariant ¿±danego zasobu jest równie¿ zasobem negocjowalnym. + Dostêp jest niemo¿liwy. + + +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- + + + Uma variante da entidade de requisição + é por si mesma um recurso negociável. + Acesso não é possível. + + +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- + + + O varianta pentru entitatea ceruta + este ea insasi o resursa negociabila. + Accesul nu este posibil. + + +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- + + + En variant av den förfrågade enheten är i + sig själv en giltig resurs. Åtkomst är inte + möjlig. + + +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- + + + Talep edilen elemanın bir değişkeninin kendisi zaten paylaşılır bir kaynak. + Erişim mümkün değil. + + +----------tr-- diff --git a/trunk/docs/error/README b/trunk/docs/error/README new file mode 100644 index 0000000000..c2c1754926 --- /dev/null +++ b/trunk/docs/error/README @@ -0,0 +1,36 @@ + + Multi Language Custom Error Documents + ------------------------------------- + + The 'error' directory contains HTTP error messages in multiple languages. + If the preferred language of a client is available it is selected + automatically via the MultiViews feature. This feature is enabled + by default via the Options, Language and ErrorDocument directives. + + You may configure the design and markup of the documents by modifying + the HTML files in the directory 'error/include'. + + Supported Languages: + + +-----------------------+------------------------------------------+ + | Language | Contributed by | + +-----------------------+------------------------------------------+ + | Brazilian (pt-br) | Ricardo Leite | + | Czech (cs) | Marcel Kolaja | + | Dutch (nl) | Peter Van Biesen | + | English (en) | Lars Eilebrecht | + | French (fr) | Cecile de Crecy | + | German (de) | Lars Eilebrecht | + | Italian (it) | Luigi Rosa | + | Korean (ko) | Jaeho Shin | + | Polish (pl) | Tomasz Kepczynski | + | Romanian (ro) | Andrei Besleaga | + | Spanish (es) | Karla Quintero | + | Swedish (sv) | Thomas Sjögren | + | Turkish (tr) | Emre Sokullu | + +-----------------------+------------------------------------------+ + (Please see http://httpd.apache.org/docs-project/ if you would + like to contribute the pages in an additional language.) + + + Copyright (c) 2001-2004 The Apache Software Foundation. All rights reserved. diff --git a/trunk/docs/error/contact.html.var b/trunk/docs/error/contact.html.var new file mode 100644 index 0000000000..ee2157e718 --- /dev/null +++ b/trunk/docs/error/contact.html.var @@ -0,0 +1,104 @@ +Content-language: cs +Content-type: text/html; charset=ISO-8859-2 +Body:----------cs-- +Pokud si myslíte, ¾e toto je chyba serveru, kontaktujte, prosím, +">webmastera. +----------cs-- + +Content-language: de +Content-type: text/html; charset=ISO-8859-1 +Body:----------de-- +Sofern Sie dies für eine Fehlfunktion des Servers halten, +informieren Sie bitte den +">Webmaster +hierüber. +----------de-- + +Content-language: en +Content-type: text/html; charset=ISO-8859-1 +Body:----------en-- +If you think this is a server error, please contact +the ">webmaster. +----------en-- + +Content-language: es +Content-type: text/html; charset=ISO-8859-1 +Body:----------es-- +Por favor contacte con el +">webmaster +en caso de que usted crea que existe un error en el servidor. +----------es-- + +Content-language: fr +Content-type: text/html; charset=ISO-8859-1 +Body:----------fr-- +Si vous pensez qu'il s'agit d'une erreur du serveur, veuillez contacter le +">gestionnaire du site. +----------fr-- + +Content-language: it +Content-type: text/html; charset=ISO-8859-1 +Body:----------it-- +Se pensi che questo sia un errore del server, per favore contatta il +">webmaster. +----------it-- + +Content-language: ja +Content-type: text/html; charset=ISO-2022-JP +Body:----------ja-- +$B%5!<%P!<$N>c32$H;W$o$l$k>l9g$O!"(B" +>$B%&%'%V4IM}$B$^$G$4O"Mm$/$@$5$$!#(B +----------ja-- + +Content-language: ko +Content-type: text/html; charset=EUC-KR +Body:----------ko-- +¸¸¾à ÀÌ°ÍÀÌ ¼­¹ö ¿À·ù¶ó°í »ý°¢µÇ¸é, +">À¥ °ü¸®ÀÚ¿¡°Ô ¿¬¶ôÇϽñ⠹ٶø´Ï´Ù. +----------ko-- + +Content-language: nl +Content-type: text/html; charset=ISO-8859-1 +Body:----------nl-- +Indien u van oordeel bent dat deze server in fout is, gelieve +de ">webmaster te contacteren. +----------nl-- + +Content-language: pl +Content-type: text/html; charset=ISO-8859-2 +Body:----------pl-- +Je¶li my¶lisz, ¿e jest to b³±d tego serwera, skontaktuj siê z +">administratorem. +----------pl-- + +Content-language: pt-br +Content-type: text/html; charset=ISO-8859-1 +Body:-------pt-br-- +Se você acredita ter encontrado um problema no servidor, +por favor entre em contato com o +">webmaster. +-------pt-br-- + +Content-language: ro +Content-type: text/html; charset=ISO-8859-1 +Body:----------ro-- +Va rugam sa il contactati pe +">webmaster +in cazul in care credeti ca aceasta este o eroare a serverului. +----------ro-- + +Content-language: sv +Content-type: text/html; charset=ISO-8859-1 +Body:----------sv-- +Om du tror att detta beror på ett serverfel, vänligen kontakta +">webbansvarig. +----------sv-- + +Content-language: tr +Content-type: text/html; charset=ISO-8859-9 +Body:----------tr-- +Bunun bir sunucu hatası olduğunu düşünüyorsanız, lütfen +">site +yöneticisi ile iletişime geçin. +----------tr-- diff --git a/trunk/docs/error/include/bottom.html b/trunk/docs/error/include/bottom.html new file mode 100644 index 0000000000..e8522b6e9b --- /dev/null +++ b/trunk/docs/error/include/bottom.html @@ -0,0 +1,14 @@ +

    +

    + +

    + +

    Error

    +
    +
    + +
    +
    +
    + + diff --git a/trunk/docs/error/include/spacer.html b/trunk/docs/error/include/spacer.html new file mode 100644 index 0000000000..7d5e59531b --- /dev/null +++ b/trunk/docs/error/include/spacer.html @@ -0,0 +1,2 @@ +

    +

    diff --git a/trunk/docs/error/include/top.html b/trunk/docs/error/include/top.html new file mode 100644 index 0000000000..04b73b51b8 --- /dev/null +++ b/trunk/docs/error/include/top.html @@ -0,0 +1,24 @@ +"?> + +" xml:lang=""> + +<!--#echo encoding="none" var="TITLE" --> +" /> + + + + +

    +

    diff --git a/trunk/docs/icons/README b/trunk/docs/icons/README new file mode 100644 index 0000000000..66523b609a --- /dev/null +++ b/trunk/docs/icons/README @@ -0,0 +1,158 @@ +Public Domain Icons + + These icons were originally made for Mosaic for X and have been + included in the NCSA httpd and Apache server distributions in the + past. They are in the public domain and may be freely included in any + application. The originals were done by Kevin Hughes + (kevinh@kevcom.com). + + Many thanks to Andy Polyakov for tuning the icon colors and adding a + few new images. If you'd like to contribute additions or ideas to + this set, please let me know. + + Almost all of these icons are 20x22 pixels in size. There are + alternative icons in the "small" directory that are 16x16 in size, + provided by Mike Brown (mike@hyperreal.org). + +Suggested Uses + +The following are a few suggestions, to serve as a starting point for ideas. +Please feel free to tweak and rename the icons as you like. + + a.gif + This might be used to represent PostScript or text layout + languages. + + alert.black.gif, alert.red.gif + These can be used to highlight any important items, such as a + README file in a directory. + + back.gif, forward.gif + These can be used as links to go to previous and next areas. + + ball.gray.gif, ball.red.gif + These might be used as bullets. + + binary.gif + This can be used to represent binary files. + + binhex.gif + This can represent BinHex-encoded data. + + blank.gif + This can be used as a placeholder or a spacing element. + + bomb.gif + This can be used to represent core files. + + box1.gif, box2.gif + These icons can be used to represent generic 3D applications and + related files. + + broken.gif + This can represent corrupted data. + + burst.gif + This can call attention to new and important items. + + c.gif + This might represent C source code. + + comp.blue.gif, comp.red.gif + These little computer icons can stand for telnet or FTP + sessions. + + compressed.gif + This may represent compressed data. + + continued.gif + This can be a link to a continued listing of a directory. + + down.gif, up.gif, left.gif, right.gif + These can be used to scroll up, down, left and right in a + listing or may be used to denote items in an outline. + + dvi.gif + This can represent DVI files. + + f.gif + This might represent FORTRAN or Forth source code. + + folder.gif, folder.open.gif, folder.sec.gif + The folder can represent directories. There is also a version + that can represent secure directories or directories that cannot + be viewed. + + generic.gif, generic.sec.gif, generic.red.gif + These can represent generic files, secure files, and important + files, respectively. + + hand.right.gif, hand.up.gif + These can point out important items (pun intended). + + image1.gif, image2.gif, image3.gif + These can represent image formats of various types. + + index.gif + This might represent a WAIS index or search facility. + + layout.gif + This might represent files and formats that contain graphics as + well as text layout, such as HTML and PDF files. + + link.gif + This might represent files that are symbolic links. + + movie.gif + This can represent various movie formats. + + p.gif + This may stand for Perl or Python source code. + + pie0.gif ... pie8.gif + These icons can be used in applications where a list of + documents is returned from a search. The little pie chart images + can denote how relevant the documents may be to your search + query. + + patch.gif + This may stand for patches and diff files. + + portal.gif + This might be a link to an online service or a 3D world. + + ps.gif, quill.gif + These may represent PostScript files. + + screw1.gif, screw2.gif + These may represent CAD or engineering data and formats. + + script.gif + This can represent any of various interpreted languages, such as + Perl, python, TCL, and shell scripts, as well as server + configuration files. + + sound1.gif, sound2.gif + These can represent sound files. + + sphere1.gif, sphere2.gif + These can represent 3D worlds or rendering applications and + formats. + + tex.gif + This can represent TeX files. + + text.gif + This can represent generic (plain) text files. + + transfer.gif + This can represent FTP transfers or uploads/downloads. + + unknown.gif + This may represent a file of an unknown type. + + uuencoded.gif + This can stand for uuencoded data. + + world1.gif, world2.gif + These can represent 3D worlds or other 3D formats. diff --git a/trunk/docs/icons/a.gif b/trunk/docs/icons/a.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb23d971f4ce99b43dcadc7179deab4e3f55d2fd GIT binary patch literal 246 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2nHIbDd^F&3SUp#HU#9hW!Rw()J9@9Pc4|E2W2srx z@ZjD%n_KH1+_viO4gW0IG)3`1D5IB^&A~|*Z0siQ)e*Jc?U}v(RZqm-rsn%xldEMP i9?8v^arV~QxusXc{Vzw0+BY`Y83|alcZ6{=SOWlx{aaiB literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/a.png b/trunk/docs/icons/a.png new file mode 100644 index 0000000000000000000000000000000000000000..c1840256dcf85ae97807b18bb7d6cc05eb0f95ed GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1lBbJfNX0GJa~F9JC~&X@gfql0Xk*MNVLbcRJ~&Y0-gRzE zrj_%zEUEOI{8@GD>6)F#+gXz>SQ{p8TqWVUY;yR_lqm~zIyOE?l#q=2$n?6i-nXCi zXOQfbx(R00TVG7(ocDz>?~G*qvz$l8K-!lN`jBehsZAsfWYa7fK8(M!(H)lmpeEhtIN cO-e0NFtoHZ^?C8-2+#%wPgg&ebxsLQ07e&Tg#Z8m literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/alert.black.gif b/trunk/docs/icons/alert.black.gif new file mode 100644 index 0000000000000000000000000000000000000000..eaecd2172a091ee2994c73f33e784e336b23b58b GIT binary patch literal 242 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2sTRBTd^F&3SUp#HU#9hW!Eiwp#*PQqrY@^+(mQa9 zIq>=_)6J=N(?l8rJU#@b9ZU?|#8k#|TH+FuDboTL$LCUaCvA&aeP+vAqk{>XuXw(F ebwjlD^Y4l5CwY+}}V#>(}+e%YC`G9tD6 z<&>04);Dfl>^kL$*$OX@lhto@l!QXAdZw&9sN4A?$yR>aXGxPKmyi?175+0@L8L7oO3fUlDhC^y*iC%Jku8u-*YC%bA zZc=KIf}y3QDTCrq7DfgJW(FOg=?oy-8JM#&cJ29GAmOljuG+p#>+^!)qA83W53Y$i zRmV;6*!V8-#*VCuOa*@qH0ND;#mM2YBw&+P*rb-FJO^IOEcFdnw_3sy#i%{~=Eb~? osgHMN$4+)vHJp`EcP`!U`}1doVY%uqk+$u`wANvs|`dJjBCm zYHZeQ&^+Z#kK>_)WtCM`Ry~n%aeS##yLaq3JVT9R*+xUQU=P7_CPBxJu`rjfklrw} z;fPBRck;5G4h$D2@;nVV0Ce0U!voj7bSr^2g_XEQlsM<-=BDPAFoa}e7Aqtcl_&tI z%shpXj8uh!(xjZsWQCOc+{Da0Jq7R7GN6P8TBKlTX=&>7;>!`B4Gf;HelF{r5}E+k7-OOU literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/apache_pb.gif b/trunk/docs/icons/apache_pb.gif new file mode 100644 index 0000000000000000000000000000000000000000..3a1c139fc4247ec7e770fdaab961fb3692c953fb GIT binary patch literal 2326 zcmeH``#aS60)Ri?F~*GRoWb@r$c#H_jN6u#)66_>GY!UILM{ophO`}&oUt=FmBNTY z$`ICVA7j^+h#i;OQDc-ga!qS+8Gc0FW4f z)Bt1yAj_Q32!U{ zRIo-qQptb-t7{uBm(~px;>}n!KArWR1^>`Cf~is&A3~v0s8aF}M#nn9GGt0d7v`yb z*>S>eMWL(I627?MNllQ7BkqHq)M=1k z=&Ky&zXVh2hPE6DHG1$Mj#+!@W<|fAeonA2iB#Un#%N(&&W1dtI~9BfQ#)e2X=lF^XcGT}q=AoZ{H^5&_C+Pv zN&hQZTYONvvH2qVcG~jIh^yqZXMG0jauI~J<^%?yjPC{pb>Ylqd7Qgl5*ph^Ulf=T ztUu|ceZK)dM=IDKg~q~CZoH&Cb~-~Z=;&lvYG{6Kc>2z^;Sv327g?kssFZ=dw}0cH zdw$mEtN!A<`J8^&z3 zt~SwiD6S8)Rjrr!Kx<)&vBl1-$xbOvcBi~nxrDC!TBPace;L%k*DDqrZ4t4XvN(& zu%4H=wkn0>)>bWw*7qy^XgxfL8hEr{3=!aT@x^9eDj^ytk&Chl$kO(lBLUN|dQ6Gs zqR_gQC$$$-23%rt``_I(>C3A7dOXT9Z$frk_k~-Ys+P;@AA_2Pg%%8=^ZRrL+?~|f zW&~d`K5oo!G0s}dw|gtsI8gBY`D(2K(S?RiMa{{iIhO(d)G0SJjuwocN&dl=)Ns$! zkAoL^`msv}wXFIo9^Egsd~xDITuw=a{)ty}PeNiaZ{?=q1Ff-;&+#A?LvlJm+3a2z z0EU`idSaEFK|F|qEq^5hpn?C2d=DQ+H3YkO^OBqUex<5bLo z9(N*aTe0*iA?|UPIVvKLCc?9Ag1I16-HvOfbsA#dH4-dk3 zhnz>*3E(FdLU+yVpuPUsliM=aeNjZUS*@XX3Z53T6iR8-2uO=XFwVs0@AhefEv8q zeI*^7gje{cZVN8?oK%ZT=2#U=<_Ih7M^R~)Ja%@QBEHt-Nj+won-qIvXTfK$!wnkr z2MQ*#TaAN%Ohqz*uQYER7$<|Jgd}A|ZL~mb$%8Fh^ z{1s=ft;T@}n?u#1Sd8|0dAq@XlaA<)Sy)vu-xZB|?3vPJ`3#PxQkI=}-aLquKdtW{ zRsg5o;PBjI;EgPh^zTEWZ?enGho=a|_a2#rB5>rG$ipb8~ZRYin9sS|J!1|3Vo5F#x?%5Z#agaH4}82`=y&d$cYy~Z&B z|6>6EoB;pt0RQJo@7{af)}_w>0G#hijQ;>*=Y*W^Qe*!B7ytkOKp?+w00001VoOIv z9|a8%y#N3Nw@E}nRCwC$n2U0wI21&+5=byvIT4S5BHR4`Uv9Sq81N(ZOwFvP%AE%o zkez$fx21{@FTM2AOOHrW4~}u;2>0;F|3mI{=G?_6%s}af-c=97>iFD}W~yAu9H%>J zrQI@+s6`2;z*T+ zwX-R}K*(XpWb}h{C<~`f4~8WU7;Ofem}nRf&Ej)2gLsiXG7oy`&r&c(;gBmOMbN>A z#Gx$h&LsvKKd8gt$Wk>*%W#mWPQ~h=EE_byWFkE`Gl&oCINtrzpZS}mK*9Z!=b7-0 zZ!;f)judQJ6f#z5B(1ymA=$^+0Mz-P7rg@(Y4!Q^$_)V>K# z@cx)onlyoKWZ>M8Cf5kX+9i9z#Ci>1(f4l2K(Z0o6i;n~>Ca_pRaG}o>uc}P7VrbE zAB(~|!?|R&cv31B#&Tt5Mh2`E;Ww@$%RCrl0`cTRY^Tf{Dq;W!PYjLs>}}XV7eB_# z!}OzM7A9h!WFvzVhEh1aVZgMJe}N5Lt_Pi~YUBVl4GjSbq461FvP3@oD6HJAwh?Z% z2a;Fo)X#4NB%020;p@7pW;f_cgF{O<)L1WoVTeI#ZBZ1D&8myGd2V5k=rD<_cE*tG zP*)9OGID^Jl5x!-hr7$_%+tFdQs5VgY(tAKsE3I|0>Qp$$$>%Xa|C6i0Sr6$^nLyq z1?&>h{YXQG0YEG`zz=W)?$mW?J(STDWf@W2#(=@y`bu-Iu3tXTeL|bJ`PlD|EA6Kt z{Q-JgKKq6pUO8R)_grt{s+_`G)AGK>y3m3{b>a|7)Lb*#x=FSOnzjhXU~f=}!`20L z7a%kX2wy&Gg{429Yd_v%#fLKn<;1|A=>`MgEGYm3{{&2T!^Svq7+21;c-C#p+f5$E zzEI(kAriQ11tBr$PKqz*+kVm#LMnRJ*MYA;W(LP^7`&||Zpjt8Wd0LFGJTr%deFnL zhEb=)1PT>bP+uy$+pRG;8b^HM!Fq8cF<3mdWYF_NJMp=J5E(3neDQUE@aLWfH0z9;auw~Hi`#BHF%UUwH zBMCN=R!0hq|JWBkO#WmP#K_cov3h`v)$jJ5-zP8hBZ3jaT+od?=q3c?>HZpnC5}57 z+>-=bIRy-~L)<8bF)F8=h*=TW4{V`;M1x532aeW`5Qt#5$r8c^2HgU|N)v=FgZ<$! zEewf4%8AtO<<&g+c&sNJ60)#m>Wj!?!2T!(#pI0;S)>#7PN5y(3CVv*bmKb0T~~xr zRo#L?ci|(?5qSS~nZe<==E0VPRE3J~c}z60he)=7JGeOVKq@)&fE-dYL9<4T)w7G7^nN~DX)5G{ rGrM}bkL6^)UC^IE@X|{!{bl+Odo{L8_lJExo!OHH@#L?0Fsk3g9+0-%#kV)Kf zB;Lm)WsWj{mw{t4P$v62PSD1Gl%MytKqmW{WF7!lXrYR@A&Wof$BRdoD9^7)O~QCHc4FgyAz zQb5%gl_(rvaK8#TJvXRH!;vTpQg6AUnl4lLD1^g@2VkU(Xd}+G!}4q7PCruL1BX}~ zn%__Cf`!@Yjtibl_yC1_JNf5WLZ~uEo}|U%%z!2`dPMaki^@Z$BlXRQ{^KxsS~ae) zlwumx%n1G|s&RGhWp|Kj#+in3D(6)e()iEl@-u8Sff7w(OQTZm=d_qe&#{a{0Hkpk zd3~jNVEi=K*pl@q!mG~imPQW~M;_q~)~slH^x7<>ZG&wgt{Mx3+)=cdqA(vy`RlC) zIa*5ndx=y3oI55zDs1qBzgl%3gaA!mB^0?eSac9tJUbBD_wNb6B z5Y=BHl$rboqrsa_)1K0b*Ru01Ndlku0|=$W(vd?6ibRQfCat`Zll~Odu|H!`~`V*Sk|_A2T>nj+?l04FK{py$X_NM2MU^ zWo{S{Ncox!*mgVc48Zb(k+K{_TbKyQNKADLN2y@=1Vm1I~mNk5D z0iKr^7kpn^lf_&*IqSSRGsYu%Oy?I-qsO3~~?Q_Y?Qgd!o4AT` zy#1OX<>B~LkBO+T67llGwN(;& z5cY>(Zs+x+8pmeJ=iqm(J?@D}N*qJXB((gy?3S^wzj)_?JM7fN$+1NN(P%I zS?H@FlXx)=8PJ!)DAZ9?{^XKI;lu_;0(DV)hi3^Uw=U+|La!AGBb3?#anaR(o^+!0 zO_G^9!r;2w`>KGj@WLY11a3&f;w}@@<9zj%hZ;llPw}u9bsa9xTP+=u+U^*tFu1eP z(O)e2*~l>0&>;a*4`SKgFV|YWxZ2D@vrk(&Z?BLezWxE4HihSVm?9^^m~}+nk*)I~ z`l{hwue2?A09j?xgz`wEfw;2wJJ-!fT-D2h9HjbKr)JhmOkJwsLN?ke@WY$Jz~7RL zvxtcil-2^b1@O$hdY82q-^;atbN=&?En!s{X17r`(*;WL-K$NAdxP&ex&I>0 z`DR`5&>M_^3+EgRE{6M1!cRPMn`YaFz$-kwOTo&xcT&bmNkd?< z%iFaAq?u9ya(M|B{sG9PuVpEwiuLx;nx+?4pFY<^!F>~$Tz7h!y!pL&AMyK-=hvT) XqiYh{4~%{)S#O;4Fm;B(z`p+hpbw|G literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/apache_pb2.png b/trunk/docs/icons/apache_pb2.png new file mode 100644 index 0000000000000000000000000000000000000000..28baa70fb8ce678b9e4a5eecb6697d43315f413a GIT binary patch literal 1463 zcmV;o1xWgdP)?tZ*WOVL-Hq z-(g}92I(XDpqCzJU{W6D*41q~NU3qyX>CNOI@d)GeeX{;GEn$M91=%{st{U%gF$pU zLzO2IWY z_?2KWpH(4S42{8Y!?an{1JEMCC)!}v<+^tl111Dk3?|R>GIwQHcFrB6dKnkcjts1= z;^Io7`7*;?kRe{lPxQS_85kx4lj7MnFqaA3%OHMThL&Y{3AHYF4ru{DVEi}?-b$_| zqs5&@Gcbm03OO=htSEkCA4%&0UTGffEPqTOZRBQC32z~=a|g|c0UR7Ll+H1?VFxw* z8fzYwU($7K1RN?x2C*0#VbzKOtBrZC4a}xDhOf8o6<2!W#9*f?wbR+i0V+!x0u;K^ z6)2NE>cg+Wo6}+&VV8+_HBR+h8*CBGp_?_NYuh$dG*#?`%kwOo-JmiB4lUh~qhA0+ z6$+*I!!SIys`e`U|BkRnv{*z&J7b7;$g`4VGH`%cB}303hr7dSZF#xebz@%W?vf!QxNHF-GHA{UALq+%QVJmkJ?rzp z&u=q><2MZ6mlC&R2i3Fw6GJq8T=u+Di`D}ed90W~p+g6Cz4oWm5`(32#0PH7lM9hS za$Cxv=1Uv#v4Rj7BvU^5xjy@#PhY!bARg06`ZpElOR}Vg0N<=KOCmU5E;Ze5!1cDS`XeH%L$7LIru*2MPN~3 ze-sME3Yv27~RUAXdmQw!g4H82jNp3|4wD zCH~MpEcf=xSk04qJtd582D#|D61Hw z0tOUBfk1+S-~x&SL~C3SM3!QOXpu#$q^Jl_P2Pa#lysIef84qE`|kbbeDjl^ue--q z90ma$VD4B%r@H`6NJvOH(8R^XB_$;Z1cDNvsi>%E*=W$xa;LNNPG3dm(7vIeTEW=b z$uU96B+yK*&70g9K3T%n0J;W*Ye0zxRbkUL0-)(cFSJI6A0+jVXo3#O+Zj1 zNPa}jndq7e@vm z%UKo4E?(^-jvl||cBj)>DrrnGhyny+R!-SPJmufdn#`T0c?8|79Wgxx)B3-yi2rW& z>p}&k{9s#O(5If<;%ARm>6wvjl?Ov5X{)hNHU`(K-v~u>knQMx7DKT>oO7E3a3_?S`)65Tg-T4pZ( z3DN<;pLH?02Mdi9=CInI2=TI8TcEnM%==JQjGA-C(6{OF&_NeI#&@sGE0CM~c-I5w#?rjvV$Cn)}x4_9-eO^a7ghYm?CQv)A7BAVS`Z-{#R)Sz61^o1`wj^qI<=nfK#iyh*|qVvEGBOsiO)ZY|7`j)ulDklXZ)e=@-Y1>4<(x$U0Gcz)^n9- z;0!uQZDfj%f!EKekB!ocZCzPyr6xbf+i_EOnG%wzP0e_Dp3~m(op2X+o2P5eNNE5) z;b-yT4`)-Vxw2Yjk>|S6a$Hr?&8E>B=~Q+*eoM+ktd8zTjQtOW?}MWu6H0R&WEYUA ztm~kD8sBN|vuq-;_6x!2NYVP>JC%Xzx3@PHxUzFu7_0V!0~lJK*{ztH(qy}Ai` z^Pg9WD^D%yST-rMi-;U+nelbT5LC__HttYJ*J~ZYTgIPt`Zh9EJLO&72$(XNd49C> zN?++Nw>ur~bY=+Lzk16Z8J7;=sZJ@@k44D)=2 z!OHDk>D0Ov_s^emds@-3C}vOnnlxSKrl74J8TZGmT{%wu)SI%86OxAN=0B9JmY$CG zKB}=Z&2Pm!@D$pAl1c5B1H5*1%_Y{QtN0Rk$2vo||N2eE!i7Ohx|0PziTHUCQa`6R z9lIaG=@wpo|M>f+7Dq@*E`{vEu-7a2+(!Cfci!~Bj5_pbey6%Hu8Dl^E_g$r+0c2P z0G8pGi(u;~2G&#M0Sl$;bcrv9GUz_A4+ogKJ|l32UKDUFi$mFl-*(%}Xdo`_=L3Ya1-npB~|tkM=t|3B1_0%uEQ21F|4W1Sol|gPS1I#-HQ96|C=h5Q!1S^{rq1F(0%;(a#jEW zfB_C&&SXTm-v$wlXY>4s3-|+o2hcpO6E=0kDopfpcJZPGxEqBD0E^NgrCpAkC|H1c zQE2W21QMb;GEyiUgSF6sc_M_O`iRhmHJfIWSZ-g_yp4ffPMdZJ_ZUJleOyfNHx#z(&2@S$Iz7E`4{xi`G#AItUyU@aig}AF;wB}7)a8 zTBKlTX=%!!_>+Z^fq{`h2V@1vb_Ql|iCuU8DGPkc5-<+lz3AMXubFeq{lvP)Ggp6^Q($uOC~PM5!3Knu5hd8zzVA-2Z^g;lkQyz{qtht`EC{l FYXAcbPG|rC literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/back.png b/trunk/docs/icons/back.png new file mode 100644 index 0000000000000000000000000000000000000000..2d8d353bbc7d6adb82b273b25d3dae725c7112a9 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#R|IeH`Gc7I6*w`2- zwpDWP2O!0mjE56cA(Nrx9qvI~p!6wdxLzImj= zanJh4s&h`5%dX*-2>G_uA+t!s>+8>g&37bjzr3n{_RQ*&i&kXKY@HcdA-Fb}|K$Ch zzjy6ZEt8xYpO?-lq4J>m&nuuMVI{5+CC>S|xv6<23?Uhr#R`c?)Gf$x;BUPcG zG$|)DSs^7qH!(9$Pr*C23@G7Inx2tbtfP<(;$=9bW|rtB=jZAu1g931q~<227AY87 WTAKR2_;Lhj1B0ilpUXO@geCx0RA-$4 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/ball.gray.gif b/trunk/docs/icons/ball.gray.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb84268c4ccf0146e661f51e63fc7d958d39111f GIT binary patch literal 233 zcmZ?wbhEHb6k!l!c+9}?|Ns9pKy>EJ?%lg*&YaoN(UF#x78)9AY;4Sc4JiKe3(3eV zR!A%=Q2NWsw3(v(5*CkrD310#bD$U2a#7+72kPI#`~Yw`N*?)jcGYB&?6 zl*5^v5@j;O_zpaf^Qf7s_EE`__xyKmPTmvoe(9bH{5w=PbF!#4X}t_l`&F_3!G;Q* IP6h^R09S}j761SM literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/ball.gray.png b/trunk/docs/icons/ball.gray.png new file mode 100644 index 0000000000000000000000000000000000000000..7b756f2d82dee472e1faafe53abc04ca1cccb9ca GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DY*cj5Z5#RLEy}pGrM>1o;h=7 zM@L6mT3TpmsIjpzP)S{Pq6d&-O!9Vj;rw`W=^G%&+0(@_q~ca`f`a^+Ih@IbyLR|C z7%k^$4RvCj+j>|_&EaY6CF=yA?O*&fjCI#CozrgTe~DWM4fO8H?_ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/ball.red.gif b/trunk/docs/icons/ball.red.gif new file mode 100644 index 0000000000000000000000000000000000000000..a8425cb574b1e4250b8cd35656432245cf4b51c8 GIT binary patch literal 205 zcmZ?wbhEHb6k!l!IK;s49|&g7{BLZ0=KudR1_V(2=NFQZS*(y)RH6W+GV>HlGEx-^ zN|SOjlND0(a}zW3^c1{P%YYIdrRf=|#X1VvAYO(;YG#REa(=FkLU3w9NosCVYLSAW zrKKr@;!hSv1_ovZ9grm;+ZmW0EOy=bXK>1Mb*$?2=q7RLtBj2b0*O~xQ!1DFD^5{O pJnUyaTmRk(8|hQW8HD_tlL9-OLb*IseTr8`t-rA*Y$5}LH2|rsMHm18 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/ball.red.png b/trunk/docs/icons/ball.red.png new file mode 100644 index 0000000000000000000000000000000000000000..05f3e50629c6d930c77e762fce2fe2c6e0ba0e25 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#R|Noyk^S`k%kWK>% zGBC(-)@T4J#w2fd7uFy7FOLH`&YmugAr-fh6BOiI+73mmX>wu=NL#RQlD5x<01sBB zGpkmtc*K;-#i_Z|X{MK#Ucs`--Wpdr1jNI`XY5>O;Fxk-gPCDFH|O(oRcDadVI{5+ zCC>S|xv6<23?Uhr#R`c?)Gf$x;BUPcGG$|)DSs^7qH!(9$Pr*C23@G7Inx2tb ytfP<(;$=9bW|rtB=jZAu1g931q~<227AY87TAKR2_;Lhj1B0ilpUXO@geCyzSyzq# literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/binary.gif b/trunk/docs/icons/binary.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a15cbae04ccda7ee515f0e56360afc5a0dba7a5 GIT binary patch literal 246 zcmZ?wbhEHb6k!l!IK;s4|Ns9pKy>EJ%$YNdjg1*#K=GenNJeI{LSj*g0+7ngQz*$u zRVXM;%E?StNXgGl%*@kM@J=lQN_do}XQUSEC}e|p84jtLC3?yExjG8LsRbpexk;%- z3Wk=JrVNTdSr{1@7#VaxR)B10V9xZ|wdbROfWzv!D*Gb21Y#8#gjW{Ev9DOlxiI_H z)^#HHvm9UiDQlh^nDJt>gl6-T1rM0J@~%VW#e jit!gMUf+_g-~76GhV}Y)-JD*HO`g_*&g~t+oD9|gOVnOa literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/binary.png b/trunk/docs/icons/binary.png new file mode 100644 index 0000000000000000000000000000000000000000..c5119d1e1ea26c01d09aa3cf2fa936989a543056 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#RLEy}pGc#w-G&VK{ z3SZ^1dYPzKY!0^ck#nB%+)~>Czxe^sqA_8;*1v1wy+Y{h!W@g+}zZ>5{8hB%wmPaq7nrl zm6@kdl98%VP@0sJnXHhKpPQJOr>EeZS_YKxC{52uE!I)U2Jtc+QZq~RlJj$Q6oOL= fN>X!^Qi~J}EiFxbUVJ$Mw1L6X)z4*}Q$iB}M9gd? literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/binhex.gif b/trunk/docs/icons/binhex.gif new file mode 100644 index 0000000000000000000000000000000000000000..62d0363108d2585b7574f1eafa0749ae48e15f5b GIT binary patch literal 246 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWsLS&DhwO0R|NR`GsU;7Aqtcl_&tI%shpX zj8uh!(xjZsWQCOc+{Da0Jq7R7GN6P8 zTBKlTX=%!!_>+Z^fq{`h2V@1vb_V85k6n8{8VES7o~yDia@YFk=4>QQyf+b%kUIiE6v`j kq<41P{%f~vu3nm((IxdxXZmdxm!@WCGePSPUrq*V0OwX&D*ylh literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/binhex.png b/trunk/docs/icons/binhex.png new file mode 100644 index 0000000000000000000000000000000000000000..eff532202d39384c325bb87f35478a993322ca7b GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#RL15<0nQ3Wh#>U1# z;af%-tU!t}$=lt9^+*28<3LW9r;B4q#jVu7i<}1(cwAy1ddVzkQvMQukS9U$_xejJ zQMz9gK2*rKJAIzAVC4k?%dWNnvq|Df><72pK5<6>)mc^D;q6 z=31#uZPE>|)f;wyJAA)xR|L0i?~BQfX@{7Drl=S#V(K{$v^A{6HKN2hKQ}iuuY@5a zBePf`v8Y4=NM+_Jlw_nT6qF|AWF{-5LrY6jpBG<_0BvCKboFyt=akR{0Ce|o#{d8T literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/blank.gif b/trunk/docs/icons/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ccf01e1983e40365a9ab9f373b6fc497c8603cd GIT binary patch literal 148 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ pvM@3*Ff!-Xz$Dz$zw-23{>5{)-0I$ZZ_jW3Hcv(dYXE)}F?;|3 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/blank.png b/trunk/docs/icons/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..3802c03c9c8351d0983ca8750eba2cb1c17a4420 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0$P6TZ_3OC;Ddqs55Z5#R|2MvLU<7g*lf2zs z82>Zr-UD)YJY5_^DsCkwEZ_z5A{ZELyTj~(tgsT-h!W@g+}zZ>5{8hB%wmPaq7nrl zm6@kdl98%VP@0sJnXHhKpPQJOr>EeZS_YKxC{52uE!I)U2Jtc+QZq~RlJj$Q6oOL= fN>X!^Qi~J}EiFxbUVJ$Mw1L6X)z4*}Q$iB}S=%`= literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/bomb.gif b/trunk/docs/icons/bomb.gif new file mode 100644 index 0000000000000000000000000000000000000000..270fdb1c064a678acb8764f49dfab1e4930a437c GIT binary patch literal 308 zcmZ?wbhEHb6k!l!c+9}?9|+DEp8*nQ&g|a3d*;lU9UUEMX=$OMp~l9>3>ZN1pI=Bu zX0bwIQHcVO%FI(J$w*ZwC{4=AOjbzA&rQtC(^K$HEdxq;l%{8-7V9WvgLoMZshK5u z$@#fD3c;xbC8@bdsYMEgmX@Xria%Kx85o!tbU=22T*biBZ*bCc`Hl#c1H12gmgUBI zw%rtC;M!28($IJJckPX3ES?w2x?Bo89sFpnv51;GTC)?h;TiA$0@sFrUdir9fOkb>zt{bzE;`1Aq>0nv_CTVK7LtMGqaBGac%}zsr|X5CcYWJ z_MO@Cq9tdSvr_f8f17kC@0s(WBk9!%by?|m>~3jpZJn0eK<*4Hag8W(&d<$F%`0ID z$;d2LNGvK*08*KG3MCn-3I(M}Ihn}{DfzjHnR$8&-l=6k36IkBjMQQsg=`Qn!yz@Z pL@zl%S4SZ@wV)(5Hz~D9!O+su)aS*QBS0G%JYD@<);T3K0RXm{gZuyh literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/box1.gif b/trunk/docs/icons/box1.gif new file mode 100644 index 0000000000000000000000000000000000000000..65dcd002eafc0513dd4e7f6d54ca1d82345aa4be GIT binary patch literal 251 zcmZ?wbhEHb6k!l!IK;s4|Ns9pKy>EJ%$YNdjg1**8Z)FBGcYhH{__jT$ShV!EGkg| zQki)QB^jv-1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz!(9+VBLGdRGBLf2?gAUMi29WIx%y|;K?))=oQ+_D9Ws|kbwV3Cb!G;~l zr6S87EaNL&_a?hVeW3t@!}Ye?nKK^#j99avpyTG(I#$(nk_Jvoof)on^{`p)&3!-P v58tszhQ3zU#BLwgx4CO~=RuzOzlQVSzZ;^Bd|G^1BFxnCE`Z|dwK(Wu%S;>ma{6yCIZTmQXIZvEpmE!TmtV>dWc7~O>MwB?`=jNv7 zl`w>4WELwV7L_Ofsmwful8jV^g3_d%%w&a>{M^LMJUs>P)H0xiM`?OSYO#(&Hi(zu rkeXSdmzEJ%$YNdjg1**8Z)FBGcYhH{__jT$ShV!EGkg| zQki)QB^jv-1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz!(9+VBLGdRGBLf2?gAUMi29WIx%=I3-_IxxDa9BN8WnZTCdBN+UN;`V5 zvvyudlx5MGf7Niu+lB8<68M>}CwT0+Sa%>{VugiRTa(75mo;unPcK^%`XY`u`0=&t zU!@MXG|VX05I^^VF*R2EaBhQ*t$*G8!m22pl=_-R+Zy(Sw)W(nhPLXS$-P|O(_IV& Nt>?_0!_UcJ4FEU+X8-^I literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/box2.png b/trunk/docs/icons/box2.png new file mode 100644 index 0000000000000000000000000000000000000000..26d14325d970a9e93f5e08cdf7e7422dc3cf1055 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5Z5#RLEy}pGc#w-G&VM7 zm}$(AW(<^E+t^bCq!^RD-Cfwl5<6Z4Ic1(Mjv*DdT+bPD9Z?WzNnCHBu;*S<@bT~^ zz6uHZz1In3a~^!19%K6N>hX}|Z}qDarDtqyj$nVAF!Lk}r=rLyrjwT9adsQ z!=?dU5LV(EQR1ARo12?S*(y)RH6W+GV>HlGEx-^N|SOjlND0(a}zW3^c1{P z%YYIdrRf=|#X1VvAYO(;YG#REa(=FkLU3w9NosCVYLSAWrKPFQi!VojHZXX)`njxg HN@xNAQ@VK0 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/broken.gif b/trunk/docs/icons/broken.gif new file mode 100644 index 0000000000000000000000000000000000000000..9f8cbe9f7604077bbd3a2bc8bc3a5bb5f569b838 GIT binary patch literal 247 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2Sr)tYd^F&3SUp#HU#9hW!Rw()J9@9Pc4`>z_|O^T zk}LelhjUMZx0Uz%<6KNN%O7PlP1)n6a$s{L_l_mk)%DU^kLsajo literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/broken.png b/trunk/docs/icons/broken.png new file mode 100644 index 0000000000000000000000000000000000000000..e8fd150a339f8928e416ae7f2f631440060cd7fe GIT binary patch literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1o~MgrNX0GRvj=$(DDW^l*l%*+5)P4F(7_|%@@@V~wx~em z$mKRXug>r;)0li|*}d7B#dFj*&#dj~m|ivKy8GWi_UYV_zaxC-@@R&gX-V#TcUM-X znLEWyCHN5Atg6q)!lN`jBehsZAsfWYa7fK8 o(M!(H)lmpeEhtINO-e0NFtoHZ^?C8-2+#%wPgg&ebxsLQ0MRjSH2?qr literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/burst.gif b/trunk/docs/icons/burst.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbdcf575f78a5ebbd3eeac5bbd9f963962ab664f GIT binary patch literal 235 zcmZ?wbhEHb6k!l!IK;s49|+DEpZWiPW*S3UTAH!3F#{MV{__jT$ShV!EGkg|Qki)Q zB^jv-1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXn zDYZz!(9+VBLGdRGBLf2ygAT}iknIf2aT>es{4+SUl4tW3o}3LYCJ5%-`ZlvqY)y_i zON{zvlk8Qc_r#nUUz;+oS7*8wAfNp1ThKa>J&QI6cbF|deBP(?&CiC}j@vi=I#{!y ctx@66$5l65-@mTg36FLd3o%#&030@6>Hq)$ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/burst.png b/trunk/docs/icons/burst.png new file mode 100644 index 0000000000000000000000000000000000000000..2329898f2a4b89a0297f36374a18f81e2232d0b7 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#R|NlQ@JTr|UEiKL1 z*cd3hHr8YbkYY^oc6VX@k^k~IkW=F6;uunKtG9nQZ-W63YrG);0}mdCAh!kOj=uzM z{$Afy$h2jLRpj?SjQ>KIeHSq?Z#|F`{kn1P%-qt`Z%UrrSyXymX~paAmohJy)QT8= z7iwgz(mK!LfAEd(QmJQU?^Vm(bql`h7VYR>vQkX)ITzpGdmYbMn-xTs%0*6F0JJ}> z#5JPCIX^cyHLrvrBqOs}A+e}L0Z3)$DU@WSDio9^XnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2sTRBTd^F&3SUp#HU#9hWL3V*Bp^eh6>z=a~rmo~; z@m;PwF+98fv}{9yhQgnc16&t10u@Ug6@{;Ldlgz{Obt2`rF%DR+wn(!`wtpSjoH_A d@zm!TvfmF~E%;F4@aA{Bxj;^{Ha{nWH2?tDSDF9- literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/c.png b/trunk/docs/icons/c.png new file mode 100644 index 0000000000000000000000000000000000000000..41593b36b36dd8f23c15b81779af794ce72e0e2c GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1l&6bhNX4zCeHVETC~&w$HlAWR#%Qvs;pAKUV1IAt|G)Re z=@lq^zR=2}x^zjFeV6Oqj|L699w%~Vz5A!tu=vjItnQGni*GGboU-@WE3xZE4F4}( ziIo4bL}7w-?-c3AH|=+40&NK^ag8W(&d<$F%`0ID$;d2LNGvK*08*KG3MCn-3I(M} zIhn}{DfzjHnR$8&-l=6k36IkBjMQQsg=`Qn!yz@ZL@zl%S4SZ@wV)(5Hz~D9!O+su V)aS*QBS0G%JYD@<);T3K0RR+AY-<1j literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/comp.blue.gif b/trunk/docs/icons/comp.blue.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8d76a8c23f018497587e3f99b1ca6de51b3f31c GIT binary patch literal 251 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWz6d|FpC;V`F26w3!SH42u8!LNYRo6%va| z6o6D_oCMz{sEjG@SutI|Fl`#I8I43{F+7+RH9?U^n~B&57a> z9SY`avJ)3cpWb!+X3wWT_Y&^C>j_NskYN&^eSY~d0}D@y<%x+OBE#9DLr=Z++8Ul6 x7HBJQ=EA9jH5MFGT$gJ@mp5m{0_#-#wxuc*35QMb=U457e-D7YXCOLU#$QD literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/comp.blue.png b/trunk/docs/icons/comp.blue.png new file mode 100644 index 0000000000000000000000000000000000000000..60ff156deb9e9379f5dd717fa5cb41a3136e096b GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5Z5#RL15<0nQ3SKr=_JC z8yhpE%>+u?yh>6BQjAI7?k?F!$q5QPryLhB97z&qVJtKVmQm4? zV@TtYlAi4}^AN`}!>}|B0f!j^hZ}shnQRbE&2(61$TEY~V8hI%jt&f6D|YU-_As1q zGJwU*afM9Av?KuzmQ~^gBAu(68Ur+sJX8ocbwG-Xm65@;M&szRTgD|oi^ED>BTAg} zb8}PkN*F>iGK&=wi%JxLRA!z+Nk*zdL1|J>X0k#`er{rBo}PktY8g<%qclAuwOB_X v8^p_SNX;zKOU}>LQ3y^gC`rvtN-a__w6rw!dGX~4&;|xiS3j3^P6Hl zGEx-^N|SOjlND0(a}zW3^c1{P%YYIdrRf=|#X1VvAYO(;YG#REa(=FkLU3w9NosCV zYLSAWrKKr@;!hSv1_nk39gr0u+ZmWMC3fBUXK*TF)m~Py1H0L0ZcY^U=uj|Uqn)@& z`t+`&H+w$)xtDP7U5{X*hYXYW?DNZyDNHgr!s_U-Hfnv#g)JxEX01=i4l~r{ICH)$ lVU2;d{qukWdt+~JZ}<_zu;TaoO4H0{QT5pN7)DM8YXGT7UX1_% literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/comp.gray.png b/trunk/docs/icons/comp.gray.png new file mode 100644 index 0000000000000000000000000000000000000000..01538f8f3162eee18d9a4d5487b22b3395daccfe GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#RL15<0nQ3SK8ygz~ zg=fECuntHuCV9KNu>Qz@c^t^e@^oogUn=@%A+ z&nljl9Jb=&`yHr$7s$*tXCKcR~zb9Y$pOIk&(AKaL*N775{M_8syb^|x zjLc$%#G(=fAeEV?P?C|VP*9qblbNiLlAoKHnWv}VomvKz@F-2sNG;Y;$OiE;98xn& o^pf*)brgbA3rbRRlTwQm3@t59eO`Py0y(5j?VVxWbZa?#}6Rb z^C4&mE(8ey7I`1M2JeEG;9*JiK{cogDnVhj&IhN#x!@!?SgZIT8pH*WAfQr!56}P? zAOQ@hO=)Venboj4_SAdly?75B%ShF$^D16p6ihnx&Uq)^!Jt?x>cx2xFCZgZJ=DW_ zhzF;Vnqq_|C9#;}U}{sET5N_bWHFyp6;;@N9LvZ#b)pWoE-9E4ry?rg_Jm@s!YM?- z_2>sN*-bmRKOwjwsVPQiQnHjB987IWQw!#tr5W>yb1);hAICBhaRU0vbxFabgE-Jf zI!yz}#c~?WZD}R_ASSzM2bs7qHzYO12+dAnk%NP&O=;MPteR=YeBi}sB=_T3Mgsdd z%-8tdmW)qmHpf@7+Sq7wJ@(F8V>|2!@rI@pL)%Sa4ik>0`8n`PG>cNN~PuHj#2TU&K?b$PjISFN2mlgUm*z2muv zKiQEemq|xslYK+k{%BxyxHmh}7Dc}w4}4S#{SXahUj#9ESDbc zOOHnflF24it!!Ke)S!Xtuzwj6iq1sMV&VMamBiM~1Dk->?y_AKLvKGkd3CL_zUO(} z{{Gh4ox9inc{4lTIae9-XIHj->p*v3PgZ}I-!Gd(0R3W>2Z59 z@wZv>Co5WRejm!z{yeqNojm@2_0WZ-{JG+hhh&B-mUxe ZEb;5(orN8>^?I=Ddd=ePr!Oz#=sza7#nJ!( literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/compressed.png b/trunk/docs/icons/compressed.png new file mode 100644 index 0000000000000000000000000000000000000000..de7276dbc08d599e67cbac9e87ac4c6c3b3e0c8a GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#R|Nl2O1`;!8&P-!q zFg7*@$|S^}R|ZmyN#5=*Y>8<*YJr?0PZ!6Kid(Vg9Jv}41XwR{S~;|-8|28lz3$;t zXp%elTYlmD9wn36l{FI2gaf@AZ@FZ%`$}wSw(YAvw{!E9OBrV6p%oVzq+%S3eW!M< zoS|L8A-bYP>dPT^o0+rD*E~Ht=iu}iH~#FHROfSUXV|2!DSsHQzn040q7nQSXnRVo`|#kjl(cD9K1wC@4+J$xK#A$FVdQ&MBb@0M4;< AOaK4? literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/continued.gif b/trunk/docs/icons/continued.gif new file mode 100644 index 0000000000000000000000000000000000000000..b0ffb7e0cc026c1e0c383a17044f5aabcf4b5d91 GIT binary patch literal 214 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWsLS&DhwO0R|NR`GsU;7Aqtcl_&tI%shpX zj8uh!(xjZsWQCOc+{Da0Jq7R7GN6P8 zTBKlTX=%!!_>+Z^fq{`h2V@1vb_QloiCuU88JzN5z4yk{OJ&c!6gd(UCY?Un$r?Nn?=Lqvv3P#w6Kw&mW_iT|AE}uhs$W)G1T8U1# z;af%-tU!t}$=lt9^+*28<3Ns=r;B4q#jUl+Hu4@&;9)qZe}*Bk*&?Z_W1iBNX~N&) zRj2J?x_{^JH8BzID<7uGteta}Y0t4$tUJCfn$CLW_vG#U43W(5{8hB%wmPaq7nrlm6@kdl98%VP@0sJnXHhKpPQJOr>EeZ zS_YKxC{52uE!I)U2Jtc+QZq~RlJj$Q6oOL=N>X!^Qi~J}EiFxbUVJ$Mw1L6X)z4*} HQ$iB}OB7<- literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/dir.gif b/trunk/docs/icons/dir.gif new file mode 100644 index 0000000000000000000000000000000000000000..48264601ae0655bbb5b5539e54ab9c4c52c0ca96 GIT binary patch literal 225 zcmZ?wbhEHb6k!l!IK;s49|+FOJoEqm%rs*lV1NO|e|{kunZ*i;MI{PADl<=^BqLR! zpfo8bGg%=eKQ}QmPfx)+wG1fXQJS8STCAgx4dP`uq-K`rCFkerCyg@&WtvAFs%+oyn@vrAN+!2FgA&7LgdM$msG{jgj*VKw;b&W_&MNEp LeCV-eWUvMRho4eP literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/dir.png b/trunk/docs/icons/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..6b97905067e6b9b10af40be23f8e9aca47cbd456 GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#R|NlQTb7q<`5CFxT zZO^L$DaIskcNdoajGKW#j<2VSV@SoVuN0m5O_!5>WcW6F(#Pr0naYmPe zTtEmXM}v(bdk2$3fKj7ytIrA@Ef!Wa9vv@%1v!TfJjmf;Jm)8yXsnjg1)?7!-f9FajwC9S{Lh z>%g3ov1`u<0SU!(nu}i;Yy3QD%o~;&6sNIJ$7<(=jB`2*wc^*kKX!MUzH`b~=d*lv zms~enUYT?*-b7U^DmQd>f|AU>HTUzbRT)eKynygkW{*rDjP6lfL{kKE1 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/diskimg.png b/trunk/docs/icons/diskimg.png new file mode 100644 index 0000000000000000000000000000000000000000..11f34e681bd5a1844eac7d033ed47abb97114a4a GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5Z40-4#=^v{Qv)d|Ni|m zXU=SBXfQT521*u$Z_ol#j7i?^F6?579j}3$1Wy;okcwNi=M1?T40u`}&Uvc%c3sEj z3)&^?`O5T^cJ9ku%qI9}dB1>DMz-ptFpqPR6MN1@9PhPz{#31aXNTSyr}~~k_s1$J x4wCYlzNFfI^S&*+B#!g#S>23JDjUOIu-vUOFb=Zs-37FZ!PC{xWt~$(69BpZN%{Z) literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/down.gif b/trunk/docs/icons/down.gif new file mode 100644 index 0000000000000000000000000000000000000000..a354c871cd0b1871aea54b437a9fcd88608b6945 GIT binary patch literal 163 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz@*gEzw-23{>5`lI=eR?ORw&$xvkW+F!$q5ITU;VdF*zmu;!SP=`GxPs?Hnwl|JUnOWB_t&38C2~V z3Yq-YGVp41haGPGZ3omDR^l2_;+&tGo0?a`5R#EutdLk#q5z~a^At)lQWXkHlX5bX z6;kqZ6EpMl6ueW*fD#_1=^3fTIttk!UWP+zW{F;Mey)x}aB4wGYHm_$k%FP6rK!)0 SFGqkjFnGH9xvXXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2i59!|d^F&3SUp#HpXaXk2Sl>&JZ}wUn<}Oew2Ebh zy5WrhZnywi7`v{UmEc1RMWQW;i796*RD-1HnCY( abURyR&WU;9JD3;O#qV)F(-6+dU=09`UszZG literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/dvi.png b/trunk/docs/icons/dvi.png new file mode 100644 index 0000000000000000000000000000000000000000..19c417f227b9e86f0a483ac268a148ed3cd59c3c GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1yr+v}NX4zza~F9V6a<(rL@$&R7GOVcfN9n{`^irgvU)oI zR++RWm?r1XYK$1 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/f.gif b/trunk/docs/icons/f.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbe353c28223f727deb5144a964b67aa52081e42 GIT binary patch literal 236 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2@fN%Gd^F&3SUp#HU#9hW!Rw()I|5y1O%gw{Qrk-4 za}Co**45@VTn>y2mrF4=IdgU;Y~koUdn&jyIjm;NN)0XFePuTmPrrRp@1UjePH&g! XquWjAXkF)P`eAc{t#G$ICxbNr*wRvL literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/f.png b/trunk/docs/icons/f.png new file mode 100644 index 0000000000000000000000000000000000000000..c946f5b3165874522c62a888a08e931a2ccfc198 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1xTlL_NX4zC=MM57P~c%cu;#%bmJUXTlt!{&!;W9esImIbK(y!FIqZ3$lUNHQ{FG1*!VZoy8mr$Uwr0+ z$41eg3?I{_I@XCfnENWsw3($we0 Smm@$M7(8A5T-G@yGywom3u*rV literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/folder.gif b/trunk/docs/icons/folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..48264601ae0655bbb5b5539e54ab9c4c52c0ca96 GIT binary patch literal 225 zcmZ?wbhEHb6k!l!IK;s49|+FOJoEqm%rs*lV1NO|e|{kunZ*i;MI{PADl<=^BqLR! zpfo8bGg%=eKQ}QmPfx)+wG1fXQJS8STCAgx4dP`uq-K`rCFkerCyg@&WtvAFs%+oyn@vrAN+!2FgA&7LgdM$msG{jgj*VKw;b&W_&MNEp LeCV-eWUvMRho4eP literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/folder.open.gif b/trunk/docs/icons/folder.open.gif new file mode 100644 index 0000000000000000000000000000000000000000..30979cb52855157110d56344ce09ff29ad726585 GIT binary patch literal 242 zcmZ?wbhEHblx7fPIK;s49|+FOJoEqm?%lg*rWpeP0~jd&^9#wyELKP?Dp3GZnRyB& z8L0{drAaxN$qFg?xrv#1dJ5jDWk3m!()5hfVjYES5HG_aHM2x7IX_oNAvm?5BsDiF zwMfCx($bVc@h1x-0|OI-4#<3v?F`JR8oTcNGdShBI#=y=&2-5G4yn89^Q6URrb|x} zc)e?b^5WuCck>TOH!hekVIgPfp~Qt9URLv4mOfysiDC|%v8Jjt&35m)a4xxmqX+dL h7rU*#p8HYSdByGb-x-@{1*yNCydwGFlv>A_(~JC>i%fGbFeRAl7JSN_ ze>2P50^@uKkLcUZ$9I^g31vYo+O~PVI{5+CC>S|xv6<2 z3?Uhr#R`c?)Gf$x;BUPcGG$|)DSs^7qH!(9$Pr*C23@G7Inx2tbtfP<(;$=9b qW|rtB=jZAu1g931q~<227AY87TAKR2_;Lhj1B0ilpUXO@geCx6PjQd{ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/folder.png b/trunk/docs/icons/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..6b97905067e6b9b10af40be23f8e9aca47cbd456 GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#R|NlQTb7q<`5CFxT zZO^L$DaIskcNdoajGKW#j<2VSV@SoVuN0m5O_!5>WcW6F(#Pr0naYmPe zTtEmXM}v(bdk2$3fKj7ytIrA@Ef!Wa9vv@%1v!TfJjmf;JmX0k#`er{rBo}PktY8g<%qclAuwOB_X8^p_SNX;zKOU}>LQ3y^g zC`rvtN-a__w6rv3Q2fcl$iTqNpaV3W0c1M^bDG7jJO2z$dEVUl?ms=DL1^Wsd7@M%Ug(28~s77{U`|*wVGy10zEuITRMgTe~DWM4fNjh1f literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/forward.gif b/trunk/docs/icons/forward.gif new file mode 100644 index 0000000000000000000000000000000000000000..b2959b4c85c612f74f3ed207b3c8e09ce906fd70 GIT binary patch literal 219 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWsLS&DhwO0R|NR`GsU;7Aqtcl_&tI%shpX zj8uh!(xjZsWQCOc+{Da0Jq7R7GN6P8 zTBKlTX=%!!_>+Z^fq{`h2V@1vb_QlYiCuU8wX}SU+2eAh_5B^k_ROg-0w+{X^b?$Q zKX`{e+d0=|9tjPPcd_Mu)Ml%7PAUBP*kHbKD+5<3&kBD{#@jg@+pgRzznQIiy36?2 IL4Jr&u&xxLv0rETyYUgS);|wSIr|N7TXZ+^Rys;!xv*$)%g4?o{?ItqmT{aWjLf}mgptt=jtc~rxui?<|d^UDHvK> Vn)as+4tgQu&X%Q~loCIDh7W^4ce literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/generic.gif b/trunk/docs/icons/generic.gif new file mode 100644 index 0000000000000000000000000000000000000000..de60b2940f90cc3bef3e16e2d20b39aa00807327 GIT binary patch literal 221 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf20T#RVd^F&3SUp#HU#9hW!Rw()J9@9Pc4`>z_|O^T zk}LelhjUMZx0Uz%<6KNNmX9Z{SfkK*HucgE9k$hhnp--1%Xa$c7hcewUAg{5?%98; H3=Gx)qghVl literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/generic.png b/trunk/docs/icons/generic.png new file mode 100644 index 0000000000000000000000000000000000000000..0227cabb5ce99df7839ccd94bea389260541bee4 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-%qo<2wNX4yW12$%6HU$F_7N*2Rmf#Bv2SwZr91kTd>*(y{ z?0Na<5mPD`m*&a?Gnzbn9CsP_PE}xd;lU=Zk-)%^>LRk6lgIS}(6F!)*N775{M_8s zyb^|xjLc$%#G(=fAeEV?P?C|VP*9qblbNiLlAoKHnWv}VomvKz@F-2sNG;Y;$OiE; s98xn&^pf*)brgbA3rbRRlTwQm3@t59eO`Py0vky)&eSX80_q%!jq zN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1K}l+E zQfiTcp{1oMgW^vXMg|6E1|5+3Aln(3{XKT=`CK62xLURGi22&%H?LKSN;oNN&RD)A zj7{+T9dF5syeno$->jSG&*;OMYO`?t3LV4QtJ8%g=XgyGN!I7?Roi$yd81>RNCW@e KDqbH325SH#15FnI literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/generic.red.png b/trunk/docs/icons/generic.red.png new file mode 100644 index 0000000000000000000000000000000000000000..be63249beb5be105a84eb123ff3e15b6f46bbe61 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#R|Nl=*`#*DL8Uur| zu`y8C`ofi`K#DQR+ueorNB+y>K#qf_i(^Q|tz-i>W@a`80}&Rc#8j5xlMDw#+zcEK zB`jO9a;0XEq?8m_Di@dZVHZ}`i8Go?(xsdmwJ*F~7;u1r!Tp?gdc()_SAb@PmAFQf zIOpf)rskC}gk)qEDvky)&eSX80_q%!jq zN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1K}l+E zQfiTcp{1oMgW^vXMg|5Z1|5+3Aln(3b0VTHIq;y*eT9 pbHuxO``>OATea-a%QUllYxjTS@>KR}wi0z>>0oj07UpEI1^}8@T=4(^ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/generic.sec.png b/trunk/docs/icons/generic.sec.png new file mode 100644 index 0000000000000000000000000000000000000000..0bd3d96bdcd6c1f71503491294c48905ba27f41f GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#R|Nl2O1`;!8&P-!q zFg7*@$|S^}R|ZmyN#5=*Y>8<*YJnU-PZ!6Kid)GXyrLo{yu1kvO$w@xj_RSIEWw%# z2SZ#991kTdi;9Sl=$Scf8e6KCru6KCGrT-}RCgIW_p-9i?d|Pt>`U?RE-dtBwiIFz z{h=)LVAUlLpvhq+t`Q~9`MJ5Nc_j=X8JWcjiA5y}Kq@m&p(GL>)K7L=ssCZ!fB7+PAI`n>pZ1ZV?; Mr>mdKI;Vst02Q@Ye*gdg literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/hand.right.gif b/trunk/docs/icons/hand.right.gif new file mode 100644 index 0000000000000000000000000000000000000000..5cdbc7206da8856227e36b9d8f1fe5668e162607 GIT binary patch literal 217 zcmZ?wbhEHb6k!l!IK;s49|+FOJoEqm%rs*LB%t`uFC-(gSRt{fL;*-;<|&k9q$(7Y zCgo%%E2QM-CT8a8DR`%r0VO<2(=$?wbriBeybOob%o4ri{9GM{;M9VW)ZC=hA_YTB zOH&5LpDc_F3``6 z1P@2d%A8Z(d*Iop;+0_slQ(LVa73?qy!_*&UOA1|IbCl>b_(7P3tlzje1;bjgEav1 C5>Ye& literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/hand.right.png b/trunk/docs/icons/hand.right.png new file mode 100644 index 0000000000000000000000000000000000000000..93035c658ab61cbfc29e9afbd281a0266436f916 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQak}ZA+Bfs|Nnnx=FBu>pn&%Z zNgp7^nB?v5!Ys(+^9jg_@N{tuskoJ#aDeq+J%iAhg@z87%uN3Mmv39YFxq*sq*Jo< z<}l-yur_8_C-30KOHcikuNxS+_|AjMLJ9}7fN9&z9F?^ zrUV1SjAq%bGN%~s0PP4Xag8W(&d<$F%`0ID$;d2LNGvK*08*KG3MCn-3I(M}Ihn}{ zDfzjHnR$8&-l=6k36IkBjMQQsg=`Qn!yz@ZL@zl%S4SZ@wV)(5Hz~D9!O+su)aS*Q RBS0G%JYD@<);T3K0RYZoUZ4N~ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/hand.up.gif b/trunk/docs/icons/hand.up.gif new file mode 100644 index 0000000000000000000000000000000000000000..85a5d683177b439d3bd52a5fbe4f4b88e6b36a51 GIT binary patch literal 223 zcmZ?wbhEHb6k!l!IK;s49|+FOJoEqm%rs*LB%t`uFC-(gSRt{fL;*-;<|&k9q$(7Y zCgo%%E2QM-CT8a8DR`%r0VO<2(=$?wbriBeybOob%o4ri{9GM{;M9VW)ZC=hA_YTB zOH&5LpDc_F3``6slVT^wp$^;wzNj zocQ$p=uWvS+vn$eP!`KQ9AC&Oq&a`zGo|*%R}=iZ3~#^S+W54PQak}ZA+Bfs|Nnnx=FBu>pn&%Z zNgp7^nB?v5!Ys(+^9jg_@N{tuskoJ#;K24L;nFLH4wJ(w{~J!;R_J?q)>h%uD;|ZP zrbfRQn2U2>UE$?9Gcj?ZgOQ1es7ISWuQtP``nIMM778Z|O!Y)o+%(aVS#jD-EJY?i zgO8a(^N6gx_}5iGfOdqHxJHyX=jZ08=9MsnWMmdABo>t@0IAG8g_4X^g@V$goXli} zl>FSp%sf2>@6ht2u Q5ugnWp00i_>zopr0N09MC;$Ke literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/icon.sheet.gif b/trunk/docs/icons/icon.sheet.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad1686e44808e4eea393f203c7d91538612eefe1 GIT binary patch literal 11977 zcmV;)E;i9eNk%w1Vc-D_0)zkn|NsC0%$fhpGyj>H|7K?YGc(Np|IEzH%$YO0yStg0 z|CyPYnPxMYW&ntYh-S?HW@gN0W@ctHnPvb0RaI3pGcy30%mA4)0A`s0W-|aYW&i*H z000000000000000A^uKOXlZjGVRCdJX>%ZHZXk4MWgu{MVr*$+AY^ZCVQFqIAWLO- zX>K4$b!TX0b1WchWp-(9Xh3CYbS`6WZ7d*DWpH$5ZDM6|ATc>PH2@*`1OWg51^_Go z0002s0Sp2F1^=KSj$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ$!t2G(5Q4u zt=2Z94c57Jbq!xrSezYad1i2Vl`geKT`f9=ebeIhcKwyc$G&!dYcqgkSA#%-MR_EJ zbY5(ce3FzZifTQ2m_Le|mzyY`jYOh`k2s}nVOo2vOmdj8t*~ISaDH2Wa&@$Wxw&et zaItv0vw_03Yrtj4nY6aX!MDTJx6W+Pz;VRQjk~p}!n}Ud+}`9@(X!gs(&;wmd!S3L z!_cGCXWWkSp0UcT1>ENDp1@Ou_~rBGgPB2j0ng~G#*l?WbG{62B1jJsMo_%=Ed+Sz zBSU8MDF2eYgHKg`4SU=Sq&9D1xIlGG`8y;2=ty2+-&Wr1sp| z+*p&)L!mrrx{P;qE30!7D_W(xwO&_&{k)0{yOM2Ii3Qo>JQ%8~Lbr5L*(ICO;i{?@ z_kvA3w_^)}KT4SJ(V0TC+XE?^m?+L z6!wPC#e7FIzNGl)+46zyJRL1}NZw1QuxEfe0q3 z;QxXQHt67k5Jo8BgcMe2;f4KGpy7rbZumrpAZqwwh#g{RA`B#!=tPPfeh9#eFveH` z02Qnlgof zW;df2035)|0XgbeB>-Q2Rc4k-Sc#*PY$D;NnsA;O;{?UP8mALmk_adjf)XmKm75k}C73-@+NhMQRIq`o ztHP+}tF*$JgqxRUS}U!63h5~nUsV^Zi(nR8sH@19ha#bhqM59%ksi5#qRPH7C;uzV z4jV0uxfYOZGEa1xB6kav8$q>~4WMoT=*kePm|BoYZKKo{s%We?POC+^<+jVhwW#vj zFTMbD`=Y?p_Ufs>d@K;A0})Wb@ErpHFaV|#Ox%K-JPNEa3LN9;F~J9Kpf3RYetZJJ zgC3kR!3MiL@DyA|q=d-{0FVI06hOsc zS~9_E=DTzWxMJ$9)`5z!CAdkL%x}aRZf#Kk7hjyG+DwaTEYgzD7D8nrR z%Xe@4V$6B_ZORB^r`d$r3q*i+cdxYVb;gE|5bE4uPo1=^fgjMF#q0B@7uW% zZVFv-=C5>-_`I(;?s(6xR{oUNL*ofK>T=tAx~VkU&AR6=vI4c!rIXBe;Us7J`w{g< zzxeF5lf5{`xm!=X(MUf(grMgd@4XO4o?Lp;qYGaA=E;)|qw~Wf5q-U-LeC+u%jKCd z(NQ|e{M1nMU;2m_HA$h*a3PZx0{!>DvdxcL3*b)ecE<(EQIL0F;@MFk01+KYm=qBOS;l2CKPYajusCb|WR(1beV-JQI)LKe30 zRT2D@6fWnx6B6N6>36Rj6;~lLf$U(+YfCvO5 z!X{ZRpP^2Ylth>%O@+x!@@tc2Tcmn4?J zdh?s$45v89NzQVb^PK2Rr#jck&UU)D6TRqDBI=rl7XMT)dAFlv~7g4Cg7 z(T++{I)qs^w4{d#g)Ig$(|3^ODD5bYX;gs?*W`3C;_0bR%K;X&B!!@d>CHfd!kKRf zHKZtU2|QR6!^t=`7)ZSiQDU-FZZOhVB*@8i_q1qD}C!6l~NeO5+|*FsL5x*x>t~*^{|KSC}S2QSeWcpqlmTa zM7B{3u|(FOYJtmN;p)-CF0QhZb&O9;yHS&@X0*ymOkU#>oU@X|t*n)(T%Gb+wyIS! zdS%Q*(JGhRp47OZWUXgaJBHpib*Hjr4QYk*Q=HVaHvg!oZd`~_+sP1hAHjkyVE-`F zt@_3@-OWZZHj)tORx32=^^SS_%2}wm7rTjAk4q1Vp8b{@u!c9x;SPKF!ypc^h(}D~jj?D*7&ljPuoRI*~1b`_& z`N=Xwq@A41s1O>t%K)}ctg;B^ddx4yI=1qTNky&&h-r*Y)>Nh9%w`!jKs6O5-;C3A zWh^f)&Utps$2xW4)EqE%xTAn_Wz-iBP~M#+<5~HxHA|u9WBf`Ygd1c zp0h0EBmo3)&-Z%81fMOT> zOEqSYl+m;RHS2g}s$O-gU7cjJi3w$slysb-?L}7T`rEqZGy!cmV{Qw3P{uYkvPr$> z+8J4Da_ZLw=H2QHFs_oTVjQFI4R1GYduH;(HMj@9>typ0)n$A(z|Wm-b&tA2R+8B3 z$W(40ZeZT@&VaoUX7N?KdEePKq?5JGK}-{z;IG1)r{6tTG&TI#52w(nwnPDQ9j)T| z#`py^zHxI4@#4~MHNO{l;~bH^4vxc`4XLY9Y`L@}Qb6l)Fup56TDKlruIc|P=< z)0@#f@AoBN)n^(b(RPDQI=Gh}NM@nBhkpii${}uKoK^jCH|+G*HO{!ak6Y&l;5)zk zPT)HDi0sJ%L!wjt1|+uSI=&Bw*m>xGy#aVt=4H$*y{X!urAYjPcMvThgC5e(h0D7L}B( z@oJyDm$yCn2VDO8*uOmQ4di>YO|bKAM-%AzzGLCb9@68tclj$FePmjP+8c4RP!2CoNwwBlen zFnjj5e9&`hN~SNF=YJ-6f_j#ML8xsrNP|iUXf+5E=i(}jS0f%Ga!FVZ4g*G7xFuZJ zG&&d{8F+uwCwW%Lgk|V-Rg!XPb7vx$b%2J3@{@&KIEPx;H*F{&q=ZV9bV_L zrL=fJkcWCGh~Hy5$N~j~h)RYC9{Tpcsmx zIEtiLil%sqsF;eXxQeXUivOL^*`2#qcEQOXgH-I$FpWgUh?RM6E`I)P_J6;`XjkGs%SvEd7Nc2iUp5;P@V zo6!wTb&z_%4$e12#bJ=y)fYBZRWQ*D{&-9CH4bAnkrY$xALUmS& z63HFGCPNHbEclt9pO$!0HlinrKN|`}ly)-#5Ti00qyDu432>u0dZQ6mC^Ob@>$W2y zN={ywCVOLR;}%6hN(wW&qyb>0(37K3ngC8(HdOX&n@C6_Cw88f zMp^oVuE79I8lz~sr1u!5Zi=HVw*k0!rATlofAelLGc;J3K4udKT3UEtdPPpNJYpJ1 zO{Z{X8V>=$0F2tGjGCql;5Rn^4lk=(A7OKNKs>SM|xOzrp z3WrD9s`m)1u{x`lQK?OOt4tcHr0|B2sHwOUgt#*SpK5cXDz1!kE{h{QXM(DKWO0WE zM6OB*(0Z*5AgxE?rW+umigK;=>Mm(BKUG+#xbrnT7O>!YD;*exLUOQbsIVmpVN<#- zsA`5|c!gyXulm|x)@rdbIULD(%N%ZXeQCo9GUAqhM^$b$angwL9@I*YMz3bi%+ zME`xbhe?nt6Y#4WptYZ}ojL%ZhiZfz^mZ`&v@8w<-F#eT#ykOSXxiri+@oXu7(pTey=ExN*3-TR6L0Vuu4Nh8J48F&hJX zYr2WxsK6V%X;U`ATfFn?y51#A4SNHNh_zAXv6+OtJPW;)B)xagiHTS?F9x>Li@nQ> zQx6-VuXKqAO1@uYzRAj->bt(|+rIAmzVI8r@;kruTfg>uzxbQK`n$jU+rR$%zyAOn zzydtL1YE!de832tzzV#;3d~qyrdisEQ0y3v+zXHYRKe+(!J?I$BQ;+d+!3EZjiq22 z*VvqPb-^P{k00{}?GhgRR7>b61(+4X!-)*^7@P@JcsLAI9SM<88JZWlJ07W8cO_Lp z9Kt^Q8fj@W8>t;hTwMcMlMM-yw~>$;5yhQ(6HRQ8Ch1is5s>;w#m)6oRg9TeHB~Xi zRfsUe54^<~wZx?9eoVoZhQL{-30{@iSd#EqedU;m$zObI$8%g$by>(;xl~i>$870W zK&e!6C72_z7R&XN@kIuOxfjj%$2#d+;Z?^|0m*gj$6?8vGg()I`Ic&Fm;Z1HoCU>| z^`*)bESF4)Rg3k>Gl3Pi99i}?%YYe}yoH;FT*~4I8J=0oEdk0N0moWF%qB(0UpdHN zSzM4A%A-{ft8B`E?92U>%l0VDza^B`yippZ%a}aLy?m6^T+V_y&EjlYANiPiEKs&7 zT}8Z`+{MaL0nfg9#;(c36M4^93DCm~8n=0y-M|xFT+o_{mA2d&5i!IHEf)-(6u?1~ z5&g^)J({T5&y!Hh0(s0AtzXVD!4O=HH$%fg2|XW7lsEj2?pRAZDjgUs!7PEamM~aq zgH$tZ!Q_~o3&y}e9n?ZS)I?p>Mt#&sozzOb)HKs#PM|+ftv~Tu0sr6Xp7oTp5+Wim zlw(J>pIJ))U>(+CJpltSw6XH7OZL6rv;kqwoPp9IVT7e!ZJ}Q+)^<(SWu0Vbjbwnb z)7}BrZr#)+vek0^Wg1$ic750ClGk$v0DBFg6|w=08rY$50ER{YXqUc!7$R|fyM}$( zy_(o#z1WORI*+|(Aj-19vZ$2(6t9PNu(|=bvm%~C*q#k(&yu*J-PZflwUV~iFIo>w z>ely)trlh3k0;#F`mGqqBAwmXN~YOAFaf&_*x`GGjt#U7YG!GQuCKt_we;Gru%_4g ztxbB;wN0U|TBt)n-PH}&`t#e`U2g2{N`t$x_dTP=E!>gn*Z-M--1J9ai(0$^VBY(! z!@gqGTpgyn3j^-`-URSAXFcEa-QX`U-16$EgT>mcJxkO(Ew7Dl6}#M%qqf_KM1NCc zx~tm|9@hM`Eql$ZM!=@z-K5g(N;Imv{_O%XrUj4ZyA2Vq25!Aj)hf^Zxupx_J@DWy z{^C0nCTBA9Rx(ra*ux3IQ?gc_#;+g9m)M7_HUA8N(1WXR$PJTsDj=M+D zq&8mTt9#(*s^9pHfpO-pXq%=(Zk^+MhEYxgY5v}8K1FRlxRK}x~j^iYbF;R;I za$CMlOMPhm>7YL0qVBRs5UERA<5nK4YHD$h+vSIG=|hw0NAQ7v4yI0<>$+a(ZFlHO zP9CN{*)oi;HIBN*UUxFS2+BSIvz`R6W2(1KhIRev)K0qD-Rt2l;EaCW%TeW$J>2+2&v;F8V-!` zP2Mw~y>N&nwky{#?7gL|(UpLHK@O6N)~@x84P zB8jDHiIe#C0pB3`4c?e*gD?ANYbl z_=I2hhJW~opZI}4jTBVEChWuu6~T{Bn;UG>5d4LG5FR^z%cSM_@yK72-@&2ZUk^;2 zi%|N_Ow#|A!>fNd&nU;BZ=9(=oiI#bub@+F?87GI#%UaoxnGd>cvLB@#Fsf&Pj#5V zMaba7`=FK38Y%p;`I$y_{IB`YegXVqJXEWR#wvZuz0Ab%92nlu$E+Ftk#NXRY5vbh zl{<;d26f5koL`R-|3u0DZmG$^DVCw+(f{;i6zts2AYg2UNN#6Yo+xRyqw2OZO^@*H zu5kM5axEzIiCDSR5jRsRhfduJ$U{<}R%ebmr8ckLS~K~(MP=fzu*(FZ+v%!!O|<=b z-*db!C7#jw*pi*xmYa_nA6y_Hp`TsP)L`M=BA{87lqy%UZ0YhP%$PD~(yVFoCeEBXck=A% z^C!@tLWdG9YV;^lG!>RIZORm*)2K_KN_9%L>eHl7ur|fG<15&K3b|&rSOEaqv}(^* zxOi4AT()lE#s$#UEZwzswGMfk*X~}68x9-@yMyqCyAl27m5cW;;J_3a(|xOWBIUZ0 zF++}g`6I({ne}d#IJj_x)T&bhIGva?WXq5L`uz-XblTb#aii5exwq5axkHM*-P!lV z9T65VZ@!@Q3fl+Y?jT*-c!BKN3mk~t`#0JN;>S;5EPeX%wcslV5b)r=@ZlcI>`pJ= zG~(sXnYTuKz8`hf#rGX&+y7}dL2DHxwjgW(OkiLE3o58!gLz5FphT9r_ud0&T}UBE zJIn>yhoOy<-+uhL_8&a~LYG#F1wx2mSPedCV2v4emg8c*aR?uDUxg^*Y!-r*+zR^b z7vyU?zIXzRN9qV+0SKbyoQatD^&pp3R*7YW063Qxm`+x}0Gep3Rc1y~*4LSs&1ETx zYf6r}B5Yp)u;-p^Vz=D|fnLyEoD0lZ2yc8AdZ-(IEudg@&n*hunQ1bh=%j7B2_B}M z%9$LBDfU+wi|+&orKij>+QwOc?s-6X9a?q>*%#!SXRN0?=5BR zu+<8CkzwhwTJ4R++RF@L_2TIys`85aP`2U?YVHNuYB2CvwjwMjygC}%>z*9$x*&ZG zGYMA2f*Ceqr#BYRF+_E)rrM}Y_V^;7&oYc2pARQ|fCUTh`$TOC>s&6noEZvVyNNk< zvk-|gOY|McawamBBhTw>k|{nHZM@aKOptj9M^J$UHD3*&yq+Rm^sMc22<(1i({O57 zBzr6*UQ9RrbjhJE`R~g9x~=i6gqc^eHhANG9*hg=)>C#Of zNcTf^N}aN_>Hiq5Z2NA5h5#Sx5ec2@d+kmjP|J?{12vyLh9 z$yaYGpQpQDbIsUKiz}oj@Cv$5sTQIBN8l$O8gaHeCR|aGVyo)s+SIj_{1gl z&<6g3TmSaHs6B#+kw{?_V-&qu#xAyiEK#Y*8poK%InuF?cDy4V^Qgx?^0AM8{39R( zDab(*vXF*6Bq9^3$VD=;k&b*MBqJ%wNm8a5RA+fy%c6C`auXV(jl8A!)8OGSqp)98xBy1(QgMuE&?go4(C0MkIg54r0u|}VhBwCv&}t@apxrF!KJ#IOg#Kco_Cjbd zEB^t}fR19K!7PSF4~h&+kdzDKv}P!%5ejj}fD^}b20PXO3Pfz98#0xGN}*xXG2pZl zm&gZCS8CFE@-wKY$mvgSSPfTf0;T|QDpG3-k1^rPW@)v^**9&)AY*ltQqyv8)Bir}kATl!b9niU;_-K!Vm7-0PRtqkyM+a))%E+ zEkIg}h+`U}}^@l7D4fj}73Lo5$+$i{Z%QjSUIN zB{t2FeY`^l`)PX~&To@V^JIB~LBBUfr9<*UM&a!4SQ~!C$Z*Gm7 z^ZemRfBDXS{xhKYN#Kvcanp~}7y&{pYEd(qGXY~+ski)SIy+j-R;IL=EloyGUpaHM zmbEr-t!MU$XVjt=50urZ=(hP6(KdbbtG(>$O{==nxQ?lV>(%U7Kl`B3=Jd*ZJ?d2V z$Zshjck0Ad*5(Y_P+bg zZgpFG;P9rCylXvcg9{tK+9q|l)l6(|JImjY1~{?>9&mK0TjS1dcfmgnau_;@(DwFT zzLzm<+ff|P{`UB)Ieu=8V;bGkrui3P^YBo&oNrGmHw$x}aad28=>HyO^^`{*a%vOY z-8qL1p`&i-o|F0K1Wvi8hu&$e%RJd#S2{cl9%(dI=*%AEH;jvo^l`_T?evQI+mqgQ zrqfv#{^~EXv92YH>pkl;pF6YLRCK`~T_delIMi-FnJE^riql~{5FHOSITtz0mFM#1 zfn51&{|?)4E2EItXn3%*xao;McuYy(dDDZC^&EaZ>|-zc+0(xEw!b~@bFcf|^S<}K z|2^=7FZ|&Xzxc*KKJt^V{N*#h`Oben^rJ8R=~KV@*1taXv)_A=K9iz>b!Ksni8N_y zPyGH{rtHjL&Lc!NukVZ}G-v3`i`t@`?0jxv^FQ48^B=pDtN*M1C078}T^is6LtxZb zsS#RT6lguvMxmYp>Hw%iAOkJ9UIb$Rkd|lpm0LNLZ&B4Q)==Tp5?Y}V3IZA?p-G+L7RD7N zJRuXFl^N>Q5w2nV9Tq{&;aRbtIq~6QX_OS=As3cmBD|Gp8N(pHVROY{B>-YqIpR-2 zVlOOWAmrc=9-wR?U}#z3Ygtt%ves?wlQ!(2I#5cHW0^vSn;A`pDLE%C(tRm4M zB4(YSDOQ(dIg=s$6)o~0b$uT&E|+o%AXc#z{Mp|)pwlv@#Gy!+c4e3U`BpT>mM}U* zo9LpD*#ZHEp!R(uIEJG*jw3miqdA@?$oO$dhMW0olZ z1fXO_X4g<+L$|bKnz@*f6(w{nkN?kq=ecSX3t3(E(*pUgS$=R!qjC zOUlVp9$r?~!^e$YRpt+`YybkRKw(5#)p?j)o{yDrr3858SDsc)9@O;6iR9rN;&qV{Q^+=69OKXx(kKrX|W~PY^rdKkndfQtTMr;Zs zk3q?)*`{o60ByF~UfPy$vJbVLMcUY$=e6FPZD;8b=K{6mVK~}!VhfXa+toFkfkmg< zsbqCZWrDOM zj7fPm6nLHh&czFvego#}DxbiKZTYo)Otu zXoZqbh92jCrd@&>4|GBbU3TMwT4#?{fJ+k5hL-4za_5nLXOfbckhWw?-e^hoC}&iF z0^HA&dFXvI<-L5^qX?;$5-5@$W_~WIl8Wg9B~Xi=5Z^UiVhm_{y5~lqXt;D~dyZ+0 z!suF3sF})Uhwf+Iv8kKBDT#3eV-yBl)~TK5sf>E(qR!h~z8RL{%$l0ozD25Y5vqSV zsi1})qvENFiejg7D5UynpWW~;VtE4Oy5 zw|*{8lNa`1Fz!PpM4~vjLqN=l`$cRrPS!5Eq8##~L7n2pE}##R z;HsEHVriB;g%rqs6cmVG6$S$aN+SwhpaiCD3|807x}Yl#mdduG3u<7@!sO42EX)!u zGOC{@EMZjTqA${H$1)fNdF|4&;%srk z7_wB-R+QETVjcG2R)K9e4dT;QZ6k2)N_{OXN<$<#);6_mGWKm%;np7lE;b2n781$d zLha$I6=12YiYT@$UL-a0{Agn_3QsDExVlQ%Ua5---^e#%IAI3T(NnFeLN$fQi*GcT^rA}k= zzAyZGQE$cKF={M}(f_Zz_OJi`F8~Ly01q$$7q9^zaP__8d|`$0Deyd!#R69aRJ>U~ z`ecE@;~m+jP23{}tI(5GFrWGt2v??q$wonnutavmWn_o2j!+Z2elk7Q>kk|1b&QF_P%@+3>(-Z$1x?IjNjvXBCg=ER)faOd1R4axMd>ZhrA%s7f#&h=777 z0Bt}R1F|bCvuj#0HLG(7GnqRp=UA#rI+N8MMa!t@P_htbb3b>r3Cv1R^9>Lgbt02AV!yOvt6Y}Jbd)wUTzBb%7B(C| zHkCESU?`d;=QbuQ>0f`flgzVo$O>e)(T5FnLQ~H%vs`1hP<<{pB+n`AkajBHGgRC* z58QHog0@#jhhT5%Q7%BZgtv5iaF2y`Ry+6n*w0!6-EfmY45hXx_ysS^3VM5RT`Q!5 zaR209=eC!5+hue`g*Yi;$To+58-YJ6Yv<#{wYLEjYD>CyYj0|G+j1rEcA0j!TUV-O zL%14CI0=_(gdezFf;bYdaA$|nRK)3|hWL1^>07gSeVDx1=>ChF56IVpqcog%Q5PdSxWxs_izmS?$^Z#kEDxtD)A zn1{KTk2#r_xtX6iny0y%uQ{8yxtqUv{GM;7)uO)g7Qqsu!`|ySG^{VKFCXNq!cLNj z3_AOQVf(5?_tDecR>S!Upc^VWB>@x*qT*-i0m)+Q$7%u6E|pu|EIWN{(So}B-v5H} z?rf!xY|kFz3|5u`in=0p?O~Bss8^sR?QH9+dJXb}=dNuVHr3=#E$qhCAN&E{_5l;l zBCH#G>2|N>3L(~(ZT$iTD=hEv`XT3jIu{_~A?EGs0{i5$l@N*`Uv00p*A%ipqOZ^H z72@FdZf+)S5-2G9BrdzIUoEe{6jNcYwxl_#%ERpZLXQ2)|54U!y=YUVT4V7GGjSB-7`Ncp z+ylS`kUc`cN=pt3Vch-M^HJKXJ?pT&dYkdvv$b~!emw*V-9L=o-#r|~inkyPtYpC7 z>k)Mva^1ZJ;oHv~&(X^1$s+F=w=n+WLk#4jlio`{D#^U_kQX-%fTGX>aYF+xV|hg#!}NYLw{REbL#EqT{V*t#5}(5Uq82CwV?Dp z@$3BoWB`LFk^r$;Uq|UxK0l03aOa~L`fJnN_rCRGf1vyp-*-RjhyP0k*9PmrvNA*xy%}x zhXb_hy?DKgOy;IdtJmzddsLVlU!swF={m}M3*=o})bpoAv@v%GfHs)ZB=sZ(MTNDf z!WGsf76x^8Hc9yj8hQsuT1qOqk_S`N=ZDG?=<}*lSahg3yEU~76XkoAt9$u{*>zTi z8?3wxYU*6NtoqW^8sixpTg2?L=W~0F+GO=e{tFH&o;g;0aNNlZAOBbPY&sD=*YgdZ z9f*&JDA_AZA6abPrkK~^S%LU|M`=AbtrqsEMI?)3cwI7i^Xe*S_<1L;Z` z!79BBMw+;gn7U17YQnULGiQl9a^~=acT!)-n>uHmL@6>Hq+U#`5FNAu6EQLiAWAHX zHS5keheUYXmd}Wur&>Q91({T7l_)I9k%cPtK-FUq-$aX6g%|o3ror)DT{k| b@W92JKaW1W`t|JFyMGTqzWn*9LI40ePu4mb literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/icon.sheet.png b/trunk/docs/icons/icon.sheet.png new file mode 100644 index 0000000000000000000000000000000000000000..b875cb6b1c15e5a9cce993b50a1f47ce08852f45 GIT binary patch literal 8898 zcmaKS2Qb{<*S9RItZ31@Nc2t+J)(su5f(w%M0C~?y=Dm_goq%Bl86#zZKCW7*6Put zx5XlfL|tWBbzi^#%=`SFndf=mJ9oZk&gY)_-kEdnIcLr}H|d_a5d(+^L_tBpV0=ga zJ_W@kJOu^dGA-o=!t*4p|JkE?|mFccFa$kjHn8 z^mzf0@lO;KLKMdOy4Inyn-3XWKB;`Y9_%Kn);zqL$LwBnv0tRnYY&CU@^3xJ_m%If zT3k$If<~^$*H%;r)5Z!7QT#pUr2M-B%+Y~dd8C{r{kpU+^T4)AYNGp|?Xq@2c7#S@ zW-P4MQMWgFMXpPadXlO@BU&OL=TqfoO>l@6KJ$(gKrZlu_?NF|UyFX0H{F@?Yy+V+ z?3YpBIf!2D_WU=7uMIq9x8!JIU#V(nop$})U4Bg_s9Z8h3LNIgZYye5m6-QyjoO4p zn@_D2lzwycNs8)ksA-4eb2Y?InxPOW<8KS+qYwk2E&ulj47+VfSTQOS>Y!}75Hbi( zG{7qBjNWqtgnGF02=Aufeq%VZokcj%zXXlCE8LYW1F-$&Zlswvoh{Qd_O?`WFMu>!lOtX3i{Hir$;CM;Z?uT*Ujix456g3SAt*e!&Q{aq||26H3z4yF{za+24Z4{$fh)HX$jV~Sjgac}Snox5EWQy^)9OAg9+gniB zMi#+|uu_r`j9hrt)*fOj@@OLoOTBd#(1^#qIMz=l=|ePaWkx=xbD-HPJX`NUnQzMb zLz%gL8%A0O#{*CAe2LSfU)Ua7xDkF0+2yp>@jEaY;0DyXeZ>%16P~{!ljb z1S-v!W4e={in{TE#=Pk(bHbwvFQPJCWSDR3Y-Nl!zK)tVAhXm%)7I>L;jkzH7I|+< zm|$d!Ed@b|o1jozcw#@K7@Oa`q?2)nC?8~p_N{R81tgvt20eo7XlviTlqZSKIK)kyv8VeI9p%j5$4*VrSs=6fhf>iVc_?9Ecmdk6tpF9TSNBi z`1}xt^TB+r$GemAZJKvmdWBE;{n?{}s@iBA4J=mO>!O*SSwLEt?STRuOIEaw`KI%0 zw&nOoGTL1{eC*mu=(Er?r??P~UJ1hA^Yo!djb6Fxl=~`^y0~Yxbdin-&9uv@%LOb0 z?7GZU|Ic}<&L!i!PrtUBnYP}$Cbj+(EX!jXQ_8&Dx2#aRn|z4d7krm!`+uS3@OY?Fv=2M)D*DP$Y?C$myQjPV=b5rNp=%4(B?Ti#{4Dca$} zF7yUZx~dhEkmw{D;)4kGwJ&}*6n=}T2;~*TzjO@$sTm?V=q3I6mH?nrPqfs@!0<6s zu$c%4gb6o5zMP`*&FT@(v3#_ka;H?0VwpogZTO+_UO2gD?}3KFmLw9PYmN8Gy^Z!l zzUg+7MfRP@2_vOL?`gjWid8|vB3rESfoNU)`-nR1T?wu!{O6dz4cD9+IJ)=BC9e(F zv?ZWBX6T7(X6s5W&Yr^E6Ns{|EjVNHcYlVVv8r0%og%7;of}`p5S7EJqJ72|f0nv) ztY=?H4F`V}+hX04ZJmC!qeiBM1-V5UQv7SYLV(m=LCs?KWr-G^!X+Ja2u|tXNS<^? z<2yW?dSI$4YD-hph;b}ABYP3FE;ASBm}g1Xj^)iLS+>f(>dYJ|U`&npt`hRl!nylN zTT9kA%!6<1hYodzjq3+#OZ-|tJ!7_Cv9L9C@~b98=M+8-B>a|?8@&6%cSmqzz!%C9 zpBPnP=3j4HJfdXj6#e4V1I%cW-Seu+ATJ=ZA!X~7e&_8Bv*gWVEqrZaWH5l2Z7bwf zP1hAw)s?z|(A^c0BKD&$QKX3N{L$&chZ!(Fm;sS!%!4Y+7#=o@VFqY5XyQB3&&l((g-CHdL5ftLT%sJQl%ff4t8t^IIO6)+k3WZ1Fy+CliFzu{tsJBcD! zyWmOMoF;bE^S@o{{~MbAD@F-vJ|kZ$SpKCmKn_p(=pviAxRr03OVOR72H@G~ukiBJ zt0q!UHBRdLtbR9tlew6APZM(uphS?BewuA?g(f5(g-_-*BLw&rCn+yTtEP|FRE|S^ zgjUwvirIf$bLGo1O?loY!z$>L#w@3c{R}I}JK+=2sjR;EXHMF{iM$>!U^8o)hRpoSh(C(U~bpY^ANfa3Dw2|rHE2fWGLQ|XGel>#=sUFJ0N*KAuVy$7yQ*$)%Aj)T0+LdG~^UWMd zQhL+7uR!PKI-4$T%xI0_B~EmveWnY&m0!#IN{|A7i%(BB$H%`j;Gb9D6?zn5<&6sY zl$_!W7!UztuTA*5+@tNogL2ljzMHi1ss{FS9<@`K5b94=6)XKl_Go zrfja3NK_%+DT}-Muj|%iaGx7rO~E84epJigbPh6K?9dx|-+;?Zc$RnzjO;p; z2c@Jvh~|ZaS*#CVYPjAMxx-USgIAz!k_jm{!z7N7Xn%`FImC|yid=kUJ_jEy$2Wow zmn%n4-W{RtSA?zGq=h`na7=?Cnhl~B@waUNd7v4eyx`W(=ft=cTzYv_^sZmmlfB7i zvsSV5q6|IA_#pv>x@75&FP4fqW(%f`G-e-RJcy;0ZdtTEXDG@;Ii*_F4NBeKXO|F# zrJ_)~?2&ACyPv=9uejPcH{0O*#R))m^j0Q#k-`qO4@ErY_?rVDyRq0sXOJir>EA`| zsKe#_k(}1}p^<=H2KdgxnFPD$k3$5+*w*8_+9;J(CGDT9-prx*NB|J-dykPjEIld? z(xf^tg+IHjRdBEEvG=3L9B{M&6@2>)vR#C&F4Y}5<)s>vi5vUkDjh#BHC^r}Md;kV z#7Yui4Wa=e5*mfc)NKKW)dGR z`&i{KrU^^U=UVZr3etqh?BLvvuBpQ=ZMUiqHBxI3iKJ!a1bzM_N-2^I89)_XfI-U% z0A-&y|GI^6>oN~ISvIi1j5R+DeYgF=blc{c=BguMCVz@^_|R?t9NB8Qv|>}B9`Ib` zf7+STu-Ainf@(s3pASo-rgwRaqZMnVbNuwX9DmCyygU}=9rqNx z`$nQx2P!gn{Kb5`N4Ib!(Mv%?@z6F$aoD(6`RXJ=EJZhCb6h_SUX_(ZfjXZ|D>qMEz`4>6^qA0@$eQ5-HE5ry z`iX0jGEC&8ME2D8q$LQU$yYo(yNtLTeqZ1JSEZ<&?bEZu)r!mr*Uk*kd zEh)Trd!*n+zC$FMD+!?FW&zNtYFe1JcR10SWsTB29VVyH08*0|?%8<$dp5D8+o3AZ zZ{A$X3HfOj>pG!W6%*f5ZO9P%5#I)7C|PUi93+XmoR_^gyrv_*SsnsL*R=7JdcxaG z-2rhRcfdA+!1~hSi7kAEZ@m&CKh}tS*WQTLkdpR$mNRsl6~%c8c(9R{ZDZ*Ubjc~8 zy)2>0!eujEpIsybHKsRfZZ7isaJ{DPm6B}0Y} zKsXLUKT|nFJ-a`b>TR2;wgOOsJF|>@-vppz;++aq1xkNR1>XS(Xc61dS1nrBB-k&X zP)Ne(jK9U3L2xnhN0ue;KM={kn|j;m?IPBQfNKTeS1P%-y)capdiX_tK%9T#+N+4& z5G-)(hT+r9;BrQw3}NFW+MZt7`q@JO$ep-WPWv$k@#8a^s(Lz^sOV zICQmsLVrm#LkzvQYM??TFrh^l$L=%db^aDWo}44|(4%V>QQ}`jY~$8bm#fUAa=WKwH7!_+fF_HzpN!*qxxr z4MM{EtHoFiTbM(~U`PdC+re+rD06htxuwlQBdrq8nA2_daaasigWS>jK;kW2>^#o=d1c*}XK!@lS_dPo-+&!aIc4(nZD;=`%^ImF zE^MGw^+V*!|JQdcv-Asgj|q+^A4od4<$Jpp)bfYq6*>(>w+Q%Ynh0pzGo0r$@KpK@ z+mn$wSWR+-J2{}8gVHPTOZ4Ujg{_);vSb}?q#IZq%bDjExl`je+hL>F4nIQcz2(D zhxnyrM-e`z`r`P9m1X0sSLr^w`jXg*bW)jTBbF6fKU0F^`#PTJxAA5g$l*`#h?@w4 zkD)_YZk}9osA>QfEC~bBYS=*1wF)n#(7T|GYKYcWl$70r6XPlqi7I@e&Pz0FYo~Im z0KsmLRces|v*zgE%ni4!7M;}JGZfYSzM3`c3Ks&8o|4vHxK7|d+@%K``mlyP zi=PWT#>}14xb$fOI{fDWhY5V7(0Xi^SxYfCm7z@r_dAMtx>>CZzWTQ|;-vtUiqAkk zRYJ>YI6P5~62;{4a_%`lqUNTp81Ab4Rs`w21drgh5Wzi}ckS2eMPhUr3wZAL-18-4`AGP#Et05WOdq*u1#t(WKq%7Ob;6<+44%*VAiJ_G_7#)* z$8-xa4$>nr`=CvCrS&0z991#*>0Lm|2f43XS;=DyDuJpb@z< z^qq)hof1L%HK$s{<-b{nUxO-jad+SS|I`GS7ikoa8au}<_`!y~dVhzhvUYzh(Y#+z zT3>tW`rA#gNI#%D*KTc`$MRO69_^Q1F-m=O0UDugq5i5n9<9i;#sCf9xt#9H)b`}T z^>T)yUBIX)*fnx+qD*Co*ck-N(BK?mKYMJ9xF*J}dP&=1jrnt*xE1u%tx2a`-ZYhf z579cw$-kvmKpd)jf*Q9WEKS(h2LjpwC10QNM`e9kbruK_9%W(IoV*%sXw>jZ>d0Gu zYQfzbnD#ROuC(52GA{jf^J+QYvr0viA%5HF7lr;~Fn>hnQOA|333qAdF>Sp@j+JeW zXy=ccvv7mRfc{1)qs)17>{}u_{vYn&YRS%~zaf(@0L!gKMMt5{)K;fgI;{7aq)yVL zs>fQBvY(IX$)gP}1FV*uSI&L{W;Pj0gKyln2>SFZg5*8=AB78 zFXbFMwBh3D!32oC8_YZ`6^qDN(G)(SI18L@ZOmN2V2lYsd}fwnZ?c zgCW@&q5#_Xj6c7VL_5Oo`8*E2jIZd>T6*-NrDyk!LiBEZ zC(4o!6Pl|LjQiaqCLRJY*>#lme*BXovA_*GMMA1IjCBu;I{bc`Ta@_cAYQi(#>J(Sl`@|vzXvIg#37Zet z=|&PCT&fAX^WssF3cSbMt^z4Ze}F^3EI7X}E?+)00pmkIi=pe`8R2?-7-3P-wQ`)bR;uc=`Y6j3w1MT4$qqrCZH5u z?E52i*I_`)?x!;uz8HnPJHA;IdLjy}B3v%Zw)}T241lK(H zxwp~EMYVOPGe6b$VSJP5pM+xeG_p)NMBa#w8h6){#oW6ZfNAt zk8Q3`-<;_oJ=1zk11Ecgsm_e}eX%?~FPoSWM}B7G;TDyqpQ&d(y43XU5J2A9H4>BG zK-tl-#xAV)UMCdEVJ?O9D1P?}_jK4-oSN=x?Z10VU(+$K{Q97Rw{wxv40p5ByB_|UEL`PuQn7mL)7R&B8}Ic;vBv0AlZc$%>wmLt2s?N46>?Y z_2}lPpoUQ)9B5Cu;*}OkwlO*6=gVgR-m*X6bVL}Ulg*s5mW%lpoM$-P^5mn-KUT15 zu3#pP|Fj*=`9K$cpdx`T!k$};aZJ}yH&JE9C<}8S1a9=1SOv}p9!Imn{j?6)(MPsc zb7-$0;u3iu8T>bS_`CQ8RS%|2PUxiVor|&JVtF5B{D&owF1bWnM~6nw0dbLoBMwzi;cwUK^BdWm@aR-pwii)< zv5pScnXDYiD5YG!@~?0DA2!vAiaUSrbVKcdM&to|e<|d#&uyf(--EYRJF8CAd#=MH z8Kewr&KOMxNlIf@lT#80`d;Cxfn>7Go?LZz)^0;XYFj|_pJYz5-Ch@OBT}UBK+eSc zj-(mTU$D_N%0`Qyf3=%MZqK%H{fmKybk=W=0*8W?>CazKv#)*TEaX>zyLV?TW;{vs zynV$>YKsq5H_RQfaTLD6uob=`-Ri1lzx+5-x$b;#=M9VP+=$~n$h?a+-T)d_SkJ$D zbH94p8&^GjpXbSk;g|FULVK9dkF!otqo=xXL81g_D4c%(s12v6V0+Y$8=O{bfL7t9 z7rRbHoHdigJWdT(gW&5W4M-;P-6`5OU{axP~na)Gh8w=7a#X?2H)i(*dwUW3==Q4!ZlKDJS9JXP8 zIht-*e{tp!;nGG3B)*ZQO?#jm_WH0x2-%FmIKkqh8vCeJB1GH6%(G-{GqRl*T`5Cu zt;*X1FPaiGVSXewnVPAo{$GrTHX^ed5gz-dd_xR+1t*dl2YC%)M-1#fxa+lZkf!{P zm3{Zxjh(FV4be3<9P#zoP=tC$((L#89tQUwydx-Lw;a^X-w3GXMP4RG^Z*%mRgl>1 zse|=sRS@5?@Arv!l5y@IudC#){#IAd=AlYuk2Hv)IDt%w6Xu0suTgDO&{?P8<6xk4 z5fh~KeLQha7^!A^lz>NLdmG1vkwId+BWJg$gJb}SyfLPD6?{nsN(Per!N{@I43L(p ziOjbEd}lBh9%hO+D5ph_c z+!s2{s>Q6Cq3HBqRrrzrNHo(;O8A8TU~zX-FdaEF(@W0#B^hqlx-&BbZd*}e%)l1Q zEDRZ1=C@}VWv&e17Ns9WLD?CdOLq>|Q6G+(E-J<{3#sfl)vG9y8|7^)B_)z*=r(2O zU2Xpc6UD*cf=Ul(pp-*%z7*POdN=s0rjky{u=`JejbBsBkHb3z^K+O4xBUTyKl*FZ zd{4Nh|0&^yWziih3&a<9pUm%?{x6aAzb>wO=StcBC;J0BafR&}827X$#h;TEi{xsH zS3$24*CTk7eV3rjhn3(YtO$*kl$;WvhRIk!UqX=CBL}TJ{7$h$L3y!2Ei)7U zs|-cwtDm!`Uw#=swSR2X^vR^>m6OR@nen=d`-!1qQ|T*&bUQ(Mz6U+pi2n37VQ07FUfaa}lcR4SM1>lh)6mBCVH~hvwNDQfE%T(m zs={zHs|+MuTyZ>7xqO|q*2nnn+2g(bhXN0&40am9Om@D$e^4{@c=w2~-Z5wsz z3EggK&9O8nF^rMeS@{M#<@(L-+r_&8#6NEVey+NIb8BNCI-JHY|1h2!K zG4njQ^TV+^-GfVL+==N2jMyMruO1AsTB-zL+6$6&$DNkX9m44D{;1DJpV^R4!&0wc z_5sc{A+SZFVegy>FXyyMeFUHBlOHOBW4Gw~i#FvgP=LaZ&*khPca{v->5plN+_jsq zc@IkAV(bc-LzV!`B-U!jW3%ZfDuO9>qn_VxPlSU4xNUGBnoq)vVDOA6~<|0A7?TC0*i8J zrbB4JhhgbK+w&Zh@==BOhaOhboFU9A+5_!daXN{B^HXjZ;G+MrV!-jSrZ#qyK*#q9 zTzf+pCcbEn|HjB334%MsXJB7rR@uNXk3(FxjV z&Bdw$r@>3Q3-J~&PFl3TxfAceJu=To6a0f9mn#1kqM=;0~^3wrG1=_2&R&-alhR95J&Yw*RwogjA)*Qe4# w-v4kOw_H5~WnKJyrG>0qVS%o`k6ib%7 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/image1.gif b/trunk/docs/icons/image1.gif new file mode 100644 index 0000000000000000000000000000000000000000..01e442bfa92332ec1c6f6a3a1310a41da8be5cb4 GIT binary patch literal 274 zcmZ?wbhEHb6k!l!c+9}?9|+DE|4&Oh1EkNKnF$1G493RB3^;(|KfjQS%wmPaq7nrl zm6@kdl98%VP@0sJnXHhKpPQJOr>EeZS_YKxC{52uE!I)U2Jtc+QZq~RlJj$Q6oOL= zN>X!^Qi~J}EiFwM6o0ZXGB7YR=zwelxr%`$x8Q`Q<}TB46{|}Ro;FH4vD|TwVqCRu z(oHG-o-GnG^BH|*TNeaW6tnVAVoo@j5?96H;J7r$On>@QlgzzoTd%A$K6Qt0Rl^Fa tT+{HAkBVmGwl?ql^5gHGE#Ge!M>NIeRkegTICnX-n>O`N&=O>@1_0HcVjBPe literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/image1.png b/trunk/docs/icons/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..c1374fde333a1ea462d2edb9fac7c8eecaf9711a GIT binary patch literal 307 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{Dd_;85Z5#R|NlQ@{68%XM4ve` z6A026jE#+f^8L>jwgV}~ByV>Yj<$PKtALyoPZ!6Kid)GE4Gn#48qJN)p3LWRnvA1W z9-MLGoDs$6ZfFs_fq7ks0kg-nHYUf#F4-2$&KnH{N;*v456qA~R*+`gl*yB5#?07~ znaIOtpjLO0Z^6oA1&0;Rdi zGK&=wi%JxLRA!z+Nk*zdL1|J>X0k#`er{rBo}PktY8g<%qclAuwOB_X8^p_SNX;zK nOU}>LQ3y^gC`rvtN-a__w6rw!dGX~4&;|xiS3j3^P6AFlZ-6WvSM=7VP{@&>xS8Bwhc1-A7qQa*6llSbi$3t0`pjwvYB~D2%9p5teUK9 z!JHj-nw2N%{)ee19sAhWn7?J+(8*}hLs;X|rU4J$iGeWf`wdw5G*d!uZZa9_W^ ocG{GwRjPF}8>Y#Xb1hynfA)0M4)%aGYyBN0JvVI*5@fIj0DN?8ZvX%Q literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/image2.png b/trunk/docs/icons/image2.png new file mode 100644 index 0000000000000000000000000000000000000000..606d4fb87e58bdb5db8af12d5cafa4827c431540 GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DU|@95Z5#R|Nl2O1`=n^oS8Xu zW*QJMFc=#fGt4~0Fw>a97|3I2EqLq*q!^RD-CelluOB%8do4%+U{1`*LO=iJ~AapHTPC@S~GuWUk|h9cV6asQ;#2atq8p&cHr~emks&x zC-m>MJ6W~XDSb5fY%{q&DAqJF!@KCxl372Qw{_b-&$X4w1Uf6M#5JPCIX^cyHLrvr zBqOs}A+e}L0Z3)$DU@WSDio9^3he!($l^D4LHYfmjv4i)2j@WJuw z(xQEj48%`M?cSeKc2$dA;a$a_s7`|)|JgXI)5;nenzd@X8XG%`OT79!SOcd{3$T;) Lm^~+0kii-Nb17t& literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/image3.png b/trunk/docs/icons/image3.png new file mode 100644 index 0000000000000000000000000000000000000000..701fb1e1359e4fbd3f0d4c1428c1e9f809a5447d GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DY*cj5Z5#R|Nl2O1`;!8&P-!q zFg7-3n0ba_rZIytkjJp;v=K-pW0JSK3+Kn1OWy!Fg`O^sAr-fhIar$+*c3Q|n3zIC zS%Nhg4u-HA$Hv6OOm#Tq=+)QMG-=|*i3ZQk%rrjeqflVBttBfssL8-Fj776?=EJ8? zpL(28(h%lYut|1NzF}4EmAPFv^4d3@#P561_n=8KbLh* G2~7Z9eQS;Y literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/index.gif b/trunk/docs/icons/index.gif new file mode 100644 index 0000000000000000000000000000000000000000..162478fb3a7f690884b1527488a27a9d34ab497b GIT binary patch literal 268 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIWz6de`8}~1{hHM=NFQZS*(y)RH6W+GV>Hl zGEx-^N|SOjlND0(a}zW3^c1{P%YYIdrRf=|#X1VvAYO(;YG#REa(=FkLU3w9NosCV zYLSAWrKKr@;!hSv1_nk39gr0u+ZmYaJ$CK+XdvLQdala8OzZQ4*F%+d^j>G}%y8WC zp)<%eSG-8|P1Cu@LU&KQy{J}XRik+(=tTM=GYuMB5h}jym8(tr{ zTHty08q@pqX@{qpFA8HkpSQf;)z`l$D#)_MC9vJG&E2N2-g4rU9Qz@c^t?o^K@|xskr5P?jr9I1&)Tq@CE7Y8n)sS_yVFMA1M7^ zU(}HMrT$kE3-49y<}iouLVsVTt3y~&%;(tp6RhW!zMW}qaBTJqjdNR= zpI$3jr}9f+Yt+pZe*>O>VG0zBw(0jh{Y!Z6w-4U_ksFuK=lLY^@8(A(CZ07r1c5FH zD{+k|an8@pP0cG|2+7DSR!A%=Q2NWsw3($we0mm@$M7(8A5T-G@yGywo_ C$9f$A literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/layout.gif b/trunk/docs/icons/layout.gif new file mode 100644 index 0000000000000000000000000000000000000000..c96338a15228f70b4fa5753ff93db7d70f1123cc GIT binary patch literal 276 zcmZ?wbhEHb6k!l!c+9}?9|+DE|2H;1^Z)-$AV@P#I|JkyGvEM<|NKHSGK&=wi%JxL zRA!z+Nk*zdL1|J>X0k#`er{rBo}PktY8g<%qclAuwOB_X8^p_SNX;zKOU}>LQ3y^g zC`rvtN-a__w6rv3Q2fcl$iTqNpaZfI}mo*BX ubMM=^lVvk>^@~}aS-AV^f3&VBD9tXZudR+|59;m-w3jTH=pio1U=0AHb6^Gl literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/layout.png b/trunk/docs/icons/layout.png new file mode 100644 index 0000000000000000000000000000000000000000..0a97c1c475f364f66ad30ec78a081a22e60f5109 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{Dd_;85Z5#R|NlQ@{NLCZNY4a< zG~={0K%OyBKHl{GR3OEeEaktaVuGay_tzkLBouVskoTsvV=-Z zPF!4EPF@aQ8rL$_+0xA|-Di(pnxw0xrR8wOL}Byd#mq-|czMmt3O_a&_8#;}=5R=E z+EQX7te%yV;MD{+k|an8@pP0cG|2+7DS zR!A%=Q2NWsw3($we0mm@$M7(8A5T-G@yGywq6*JeTh literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/left.gif b/trunk/docs/icons/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..279e6710d4961d7644ea2e3e39e6afd300147aa8 GIT binary patch literal 172 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz@**Nzw-3iM{+%$5nXSNI_AHs_0#Z5ammWC>ec*qNb!1QNo>>3 NI{94w6cGjnYXFzvI#mDw literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/left.png b/trunk/docs/icons/left.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e2404a811ad62eb3c5f705ba265e273661d7d5 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0$P6TZ_3OC;DYgKg5Z5#R{{xxVb(YlvDaIsk zcNfP0OuF}g979hR$B>F!$q5aNVhYa~lOz?kF+P$~_;>ig0gfYQ9M13^JriI!K_;S? zH-w-63J(VZ!&+6&{hg;CMguj6mAFQfIOpf)rskC}gk)qEDvky)&eSX80_q%!jq zN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1K}l+E zQfiTcp{1oMgW^vXMg|5Z1|5+3Aln(3b0T)_`4k}HuzIfQzD(=$g4aWpcJy9n?OYMK z<3neVTdwpcAKpI=-d5i4k8cuSl8s+i>=HJ`A>=Y=gWs~oHD8<*YC&S2E{-7;w|vhXqT$m zk0QMrQE@zFI{IE`rv3Zjxj?dJ5}%4lQ`WtHpj}}lt`Q~9`MJ5Nc_j=X8JWcjiA5y} zKq@m&p(GL>)K g7L=ssCZ!fB7+PAI`n>pZ1ZV?;r>mdKI;Vst02>Qy2LJ#7 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/movie.gif b/trunk/docs/icons/movie.gif new file mode 100644 index 0000000000000000000000000000000000000000..003518377414735b97dd78c435daa795c9136526 GIT binary patch literal 243 zcmZ?wbhEHb6k!l!IK;s4|Ns9pKy>EJ%$YOO($b8LjTyi|@tVo`|#kjl(c zD9K1wC@4+J$xK#A$0Aq je4J*Rr#@1aJXdjR@wJsoZ!aBYW^HV0ZfO+YWUvMRZ1!36 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/movie.png b/trunk/docs/icons/movie.png new file mode 100644 index 0000000000000000000000000000000000000000..5615180de885fdad381d4dc6702eaec6ef4a378c GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#RLEy}pGc#w-OiN2M zHZ}&zbP8DI0x8BMZ+92A#Izl?K#rxSi(^Q|tz?hpCKk3f6;lImP0=GIj7)|C#=2*3 z-nbE=!>hxUrnS(hGeCiZC4lwIR;F_)ysb=Z3~8z+uN05GjsqGJR^l2_;+&tGo0?a` z5R#EutdLk#q5z~a^At)lQWXkHlX5bX6;kqZ6EpMl6ueW*fD#_1=^3fTIttk!UWP+z qW{F;Mey)x}aB4wGYHm_$k%FP6rK!)0FGqkjFnGH9xvXXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf22^PEdd^F&3SUp#HU#9hWLHC{`p^eh6ea~4tRaf(| z_%3JAe*U`SyKG~C!;gtpQxXFgX({TuJQm*75*apCqqytJp{nC4Q*X#X Y_^R}pPJ1}};XQE`%{%V$b23;10Di_)fB*mh literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/p.png b/trunk/docs/icons/p.png new file mode 100644 index 0000000000000000000000000000000000000000..3fbe0e8801e4eeb7179e4d8845690c7d86cfb010 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1q^FBxNX4zCeW!U3DDXIMZsHbJVAD|IR;c_xbC!vtOw}7} z+sJe7&ra(eYY03QSYe|zJ(F|k%Hxam7Oi>}HYxJJ)v7+mg?R_U_g?;d%P;rh{x2_b z8f`Uwo-n4yNGslH`rHV#B&@_WqQp5rH#aq}gdrp&vsfXqs6+usW#%cAWTYw-lqTh5 zCM%@m=O$+6=_z=pmH{O^O4Bn^i**#TLA(ry)XWmSbP0l+XkKuy<#B literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/patch.gif b/trunk/docs/icons/patch.gif new file mode 100644 index 0000000000000000000000000000000000000000..39bc90e7953103a7fb4d6dbbd3efcfc1cc8de759 GIT binary patch literal 251 zcmZ?wbhEHb6k!l!IK;s49|+RY&iwyBbLPx61_oneV+Jr#{O1>vky)&eSX80_q%!jq zN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1K}l+E zQfiTcp{1oMgW^vXMg|5Z1|5+3Aln(3^CEWb`4k}HuzIfQzD(=$g4aWpcJy9n?OYMK z<3neVTdwpcAKpI=-eOD+8f(7P$v8QjjESn*)KFqotJLnbYDxf$LnDLk)v8Bb)9>m( q*HL9Yo3!quRNC&zr)@sV$^5d;vQo}swQXy+(HAuD>9yx%um%8r)mtS1 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/patch.png b/trunk/docs/icons/patch.png new file mode 100644 index 0000000000000000000000000000000000000000..808ed7865fe85986e4a15b5038aba0397f6e041d GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#R|Nl=*0}?Z5&P-!q zFg7*@%H%vd6#}Fflf2zs*b>ur)B-tio-U3d6}OT(SeqHx6gYyIm_kEYf;AZqhPWCy z9!gji6%irPGjrNBwp1-m>Di4lw6wImyb_jmaR_K=HqPj3a$rc@#Sp3FH>E>qCih0( zLoEyn##bbm8v0T^nwi)b%sZ4GPVBT-1=XGxPKmyi?175+0@L8L7oO3fUlDhC^y*iC%Jku8u-*YC%bA dZc=KIf}y3Qsn3fqM}Rgkc)I$ztaD0e0s!bdTx|dV literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pdf.gif b/trunk/docs/icons/pdf.gif new file mode 100644 index 0000000000000000000000000000000000000000..c88fd777c4b2a85b930eb4a6b68440c88536289a GIT binary patch literal 249 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2ITpM2d^F&3SUp#HpXaXk2Sl>&JZ}wU>twhgl(8#J z&4;IaU+5wAJaJ`3 kwKt!oQbM;s-=_PA@BRCyb&avi?yYTZ7J^Yx{G1Hd067U;U;qFB literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pdf.png b/trunk/docs/icons/pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..516142bb47bca0ec5906b6cc7547e68812835107 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1oTrOpNX4z(a~F9V6nI<%!z!k6axf<(FrK_!ujZY(#_-;H zXJ^ip(Yl%HCW6YQj@(_b3RAMzsC<@4-dL1o`-|Jc>#OMlSBb`U!?jOJlD@}sE5+CM zY)#O&{+qIBdY)#y>_R_8TBKlT WX=&>7;>!`B4Gf;HelF{r5}E+$&SK#J literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie0.gif b/trunk/docs/icons/pie0.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f7a0ae7a703000c365896477c32f9f1434d14ca GIT binary patch literal 188 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz+~Oizw-23{>3JXu0=Fn+uq4rbVj_b$!S{Jq*b>ox4e@+uPSrG fY~A@idsi_sTAZ5D!6YVVJJJ1GWyGRRCI)K&$B{!c literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie0.png b/trunk/docs/icons/pie0.png new file mode 100644 index 0000000000000000000000000000000000000000..12e0200c97f4174cb32e46b48c7446947628e11c GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)#z(kc6`Rn5OhHFV)Avj=|BU*N?apKobz*YQ}ap~LNYRo6%va|6o6D_o-Xz~tJ~zw-23{>3JXu0=3z*v`4OaPFr@>FpEKG8&zNm_A7^cehR7 q{3odT-{ZSYE(_O7ykRZyxV`aZjoH-0n$0tdUlfJ#w+AvXSOWl+b4fP< literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie1.png b/trunk/docs/icons/pie1.png new file mode 100644 index 0000000000000000000000000000000000000000..c44c793ed8b2aab446b8fcb47039c33209cd52c9 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2Pm*NoWM&Rtlul2^fKOQWNy ziLnWz$FioA0Vb1#JNWsw3($we0mm@$M7(8A5T-G@yGywn-Xz~tJ~zw-23{>3JXu0=3z*v`4OaPFtZ*%}klI+l54ZqwVk=`G`N qqqzCzcVC|^a=f79z@jnzl=39bRIB-cn#w!p?CVf&?+9dIum%8pzDGL% literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie2.png b/trunk/docs/icons/pie2.png new file mode 100644 index 0000000000000000000000000000000000000000..e0b7167d913cc7c6e6bc35d3dac8496bcf15b1bd GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2PmVgVh(9%c@np$a=0dU<$# z8z#+h*u>~%)Y{h8c!sl=VW#9RhAcY<_gKlcQ{}1#K(oS1Tq8=H^K)}k^GX;(GBS%5 z5{pU{fK+ClLP!lN`jBehsZAsfWYa7fK8(M!(H k)lmpeEhtINO-e0NFtoHZ^?C8-2+#%wPgg&ebxsLQ03Qudga7~l literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie3.gif b/trunk/docs/icons/pie3.gif new file mode 100644 index 0000000000000000000000000000000000000000..4db9d023eda78f499c5e5efb7d6739d0d450652d GIT binary patch literal 191 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz+~6czw-23{>3JXu0=3z*v`4OaPFtZ*%}klI+l54ZqwVk=`G`N iqqzCzcW*N`uLwVHCM7ial+@(%Il4wxJnexD4AuaG3PW-L literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie3.png b/trunk/docs/icons/pie3.png new file mode 100644 index 0000000000000000000000000000000000000000..820a3c35fa9f6652703d8e9e9e45378cf9090af3 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2PmVgVh(9%c@np$a=0dV82A zCpt_rHW684WU`uZg}Dh=ieCoHi8B{i13ojhY?M|Js$8E9G%l>fHKN2hKQ}iuuY@5a zBePf`v8Y4=NM+_Jlw_nT6qF|AWF{-5LrY6jpBG<_0BvCKboFyt=akR{09h|mF#rGn literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie4.gif b/trunk/docs/icons/pie4.gif new file mode 100644 index 0000000000000000000000000000000000000000..93471fdd885b4e54a6ebcfb68fa98626f3d43d75 GIT binary patch literal 193 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz~s==zw-23{>3JXu0=3z*v`4OaPFtZ*%}klI+l54ZqwVk=`G`N kqqzCzv6IghDLmwE@Ojtg`DD^c7sH|;f6tbO23!o*02@O^$p8QV literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie4.png b/trunk/docs/icons/pie4.png new file mode 100644 index 0000000000000000000000000000000000000000..35490d857c7f2fa89b7924a3ad65e40085b7e27a GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2PmVgVh(9%c@np$a=0)H~M* zEfP=SyW%t9C&LminTfl$lsN)*hn2WSlsM<-=BDPAFoa}e7Aqtcl_&tI%shpXj8uh! z(xjZsWQCOc+{Da0Jq7R7GN6P8TBKlT WX=&>7;>!`B4Gf;HelF{r5}E*K=S>9w literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie5.gif b/trunk/docs/icons/pie5.gif new file mode 100644 index 0000000000000000000000000000000000000000..57aee93f0707a6fea58637c351c4ac1dae6459cf GIT binary patch literal 189 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz+}_Yzw-23{>3JXu0=3z*v`4OaPFtZ*%}klI+l54ZqwVk=`G`N gqqzCzdnff4?UOy9X2YesW54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2PmVgVh(9%c@np$a=0dSh6X z4m+r%U(uRyN=M-2mMqZ|J3?1CJTu5x8^vHM&u~9L?)tr5555Bp3@dSsC~?lu%}vcK zVF<~{ELKP?Dp3GZnRyB&8L0{drAaxN$qFg?xrv#1dJ5jDWk3m!()5hfVjYES5HG_a rHM2x7IX_oNAvm?5BsDiFwMfCx($duD#g`*M8yGxY{an^LB{Ts5*X~xb literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie6.gif b/trunk/docs/icons/pie6.gif new file mode 100644 index 0000000000000000000000000000000000000000..0dc327b569730e90421c3fae883b17691b8b9219 GIT binary patch literal 186 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz+~Cezw-23{>3JXu0=3z*v`4OaPFtZ*%}klI+l54ZqwVk=`G`N dBfa+_^}iWi*Dq8}v{CBqS-80Up#c|zH2^QW54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_2PmVgVh(9%c@np$a=0yt39t zwYn8Co@CQF$)eKuY)ura3A@H#hAcY!lN`jBehsZAsfWYa7fK8(M!(H k)lmpeEhtINO-e0NFtoHZ^?C8-2+#%wPgg&ebxsLQ0P!18A^-pY literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie7.gif b/trunk/docs/icons/pie7.gif new file mode 100644 index 0000000000000000000000000000000000000000..8661337f067f9933eb0ef9bb4ccd77dd8bdb0b10 GIT binary patch literal 185 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz+}3JXu0=3z*v`4OaPFkWM->GJsune#*ygc&t5eqP cin@0;&wnp$nZ|PQtB_G$pA6d$4F(2l04BFX#Q*>R literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie7.png b/trunk/docs/icons/pie7.png new file mode 100644 index 0000000000000000000000000000000000000000..6bfa2d06ae2be70d6e378b84f66a88bc1ef6d5ec GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQk(%kA+Bfsg8+~>)5HEZkYY^o zc6VV)Ls8Z>t_26K=qwPperZi8FHelNbV1H(#OBTAg}b8}Pk zN*F>iGK&=wi%JxLRA!z+Nk*zdL1|J>X0k#`er{rBo}PktY8g<%qclAuwOB_X8^p_S rNX;zKOU}>LQ3y^gC`rvtN-a__w6rw!dGX~4&;|xiS3j3^P6-Xz@*dDzw-23{>3JXu4R1A-L;ud>%okkhl!IyUaie(+qXfR+ave> Q)*p2%lMkH{VP&ue01>A?od5s; literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/pie8.png b/trunk/docs/icons/pie8.png new file mode 100644 index 0000000000000000000000000000000000000000..716cf2822bf1cbb2f46fff422d0a7388f99e2806 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0$P6TZ_3OC;DYgKg5Z5#R{{xxVb(YlvDaIsk zcNfP0OuF}g9DPq0$B>F!$q5ITBK9F> literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/portal.gif b/trunk/docs/icons/portal.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e6e506e004caddde40da13470f5b566c4ebd3e4 GIT binary patch literal 254 zcmZ?wbhEHb6k!l!IK;s49|+DEp8*m;Fw=PE%$df<#taM$ivRpVGBS%55{pU{fK+Cl zLP!lN`jBehsZAsfWYa7fK8(M!(H)lmpeEhtIN zO-e0NFtoHZWl;Rd!pOkD#GnH-odIM!19M@xy5abNeolJ^dKQ(i&E!y0oZhYAIz1P__bl`CXaRbu>JEQyKU^X{_%FW>4o vqif4-qpv>D{n{&Y~ zGmVXnfs!_c&Fg>^W0JSK3%gii$7>)b+0(@_q~ccTIYYh%1)kQ2^OiD;KVb2jw;)kf zB2nCDeZHpes|EkREUn~pxN79Vx>R7!jJb}M+bzzs`Y*Z?6})Mg%$ z`&97jtL=|la)xe?YfkO>mAZ6ljnIuI_Ugyh(`v()3jwVQD{+k|an8@pP0cG|2+7DS zR!A%=Q2NWsw3($we0mm@$M7(8A5T-G@yGywp!BXJJ^ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/ps.gif b/trunk/docs/icons/ps.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f565bc1db7ebc72bc372381239f378780df5487 GIT binary patch literal 244 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2=@z^8d^F&3SUp#HpXaXk2Sl>&JZ}wU>twhgl(8#J z&4;IaU+5wAJ;6lrj$UyQTKrXC=eAut`Q_@GqDYq{i?eZ? fuRb@A(YSxEI~f$8&tS>vF?`AKxHx{oVylS|xv6<23?Uhr#R`c?)Gf$x;BUPcG zG$|)DSs^7qH!(9$Pr*C23@G7Inx2tbtfP<(;$=9bW|rtB=jZAu1g931q~<227AY87 WTAKR2_;Lhj1B0ilpUXO@geCx=%V}r; literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/quill.gif b/trunk/docs/icons/quill.gif new file mode 100644 index 0000000000000000000000000000000000000000..818a5cdc7e0f1d073cea1f9771b6d94737d34183 GIT binary patch literal 267 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaN2}Co~($1tA&onkRW?*1Y{O1>vky)&eSX80_ zq%!jqN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1 zK}l+EQfiTcp{1oMgW^vXMg|5(1|6X33?SPXnCmij?fGaR;jntH+P+NdaQBLW*w$93 zLXW4dLa(j`>C2pYt0=I?YR#HS>z@C9sN+1ND~Ts;Qmd-42b05628YQhH#GTgelWA? zX*ztt@0IAG8g_4X^g@V$goXli}l>FSp%sf2>@6ht2u5ugnWp00i_>zopr09j6Rvj6}9 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/right.gif b/trunk/docs/icons/right.gif new file mode 100644 index 0000000000000000000000000000000000000000..b256e5f75fb1f5467251abbf9442f338892e6ab5 GIT binary patch literal 172 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk?9f#N^Ekc`Y?g~Xx~1t67~r%;lSs!&jxl#`jP zkdmL9n3<=i;GJ3ql<+7`&qyuSQOE}IG8|GfOZ1ZSb9EGgQwvH`bCXhw6bvmbO&Jt_ zvM@3*Ff!-Xz@**Nzw)%~qgf4szES6oR(^g_8+4;}QR+O8Rat3Y55;}UDY3n~ OBkprQ{}oXN25SJF!$q5ZiY6@v=57`v#7>@8a{9qRN&+y3J;SYb;e}|)X4p(Iw zUNz2QWMz=@;;}4gDD?+w4J&btC~?lu%}vcKVF<~{ELKP?Dp3GZnRyB&8L0{drAaxN z$qFg?xrv#1dJ5jDWk3m!()5hfVjYES5HG_aHM2x7IX_oNAvm?5BsDiFwMfCx($duD T#g`*M8yGxY{an^LB{Ts5Aj(LZ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/screw1.gif b/trunk/docs/icons/screw1.gif new file mode 100644 index 0000000000000000000000000000000000000000..af6ba2b097bda90209dd1d3d392fccdb7bcfa629 GIT binary patch literal 258 zcmZ?wbhEHb6k!l!IK;s4|Ns9pKy>EJ%$YNdjg1*#K=GenNJeI{LSj*g0+7ngQz*$u zRVXM;%E?StNXgGl%*@kM@J=lQN_do}XQUSEC}e|p84jtLC3?yExjG8LsRbpexk;%- z3Wk=JrVNTdSr{1@7#VaxR)B10U@n!|b?2W!n^SiVYewRG7AFm!*eRWl9lSzTtP=4S z(YLfe5`E@s3_lC29c$pLc?<`iz?;NP}q&5N72t!=+B{M{uprRc!*Z9v<@N?apK zobz*YQ}ap~LNYRo6%va|6o6D_oEJ%$YNdjg1*#K=GenNJeI{LSj*g0+7ngQz*$u zRVXM;%E?StNXgGl%*@kM@J=lQN_do}XQUSEC}e|p84jtLC3?yExjG8LsRbpexk;%- z3Wk=JrVNTdSr{1@7#VaxR)B10V6O7mwdbROfWzv!D*H06&kJ4;Roc;eowd{9p;(CH zi7%4jOn=^)>HKMOOmxr@^Rrv9(Zj|os#X5-Q4yu|;5S>$t1~+pUK<~i5YtS$=vU@u yeU(L%F~&2zjqBi^) literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/screw2.png b/trunk/docs/icons/screw2.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7d2cf65e999a28311dc28eec53eac318d20eeb GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DWL$L5Z5#RLEy}pGc#w-G&VK{ z3SZ^1dv-+ z<)`}k9I>}Oe^SqWuHSBt&vg^ex$d`k*3Fcqv6LswiisihMn%4oXXH#($%9G;-_%x0 zI5)->PN=#zQI08g(Z?S*(y)RH6W+GV>HlGEx-^N|SOjlND0(a}zW3^c1{P%YYId zrRf=|#X1VvAYO(;YG#REa(=FkLU3w9NosCVYLSAWrKPFQi!VojHZXX)`njxgN@xNA DzPfgG literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/script.gif b/trunk/docs/icons/script.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8a853bc5828cf534c4c46a0efbf4b1d7d3c52fc GIT binary patch literal 242 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2sTRBTd^F&3SUp#HU#9hW!Rw()J3?6|OcFmLXwbvQ z;yXWN*R#T&@77%j8VV0WP6%GqkhE;|xp+C~4`X#h&eoZ4tM=c%ZhDQk{(Ri#ES<}4 d7Yj^x^9CF~_};qCSmD=yXLEt#WPVNtYXEP%SK9yp literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/script.png b/trunk/docs/icons/script.png new file mode 100644 index 0000000000000000000000000000000000000000..2520570a775d4ed6898317d00aefbaf63f8b379e GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1fTxRNNX4zSeFr%i3^`bG6VHbTtZQhw(U9=pbZ%$Ugzsmw zWg;eAOPpZ*&|rGfluv=7*XO1iI}1--Qx_Fx^Y<)Q3)}Q}oiG1yE%|z2zKZt?=KpV` zRtEpn?f{w{R^l2_;+&tGo0?a`5R#EutdLk#q5z~a^At)lQWXkHlX5bX6;kqZ6EpMl z6ueW*fD#_1=^3fTIttk!UWP+zW{F;Mey)x}aB4wGYHm_$k%FP6rK!)0FGqkjFnGH9 KxvXl+r>Ez@fddR+p!k!8k%57gK?lSGsbyex zi`aFC_kd@D&y?=4?(Pes3MEI<1Y!g8G%~jxUU1@6RIiH;$6BEo^BN2cqBwk-7hXtI c(vnrUxMBN-xh<~83yn{BaU>KdGcs5M0L&38p8x;= literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/back.png b/trunk/docs/icons/small/back.png new file mode 100644 index 0000000000000000000000000000000000000000..2257df2140d3bd07fb6173d33167b365714c4906 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?ydCNUr978H@ zwN5Y;I;0@rdOvMXN2-_cog;qQvrM*Gy7^6DzERmOqB%1ns)#jzgBT-|U(f9~hw4Ar zpEyw$TDT#rlzqdik2#8=QyP7jG%dU#vrj;had~XSH;JEupWbVKnpJXX>EVS_(s=xm zr?oLiSiTf)u+}wRUvj{u+iG{+)M!u1TT}i{Jm`8N`NeycSnmg7yOwhkCVOO8JN!f4l^cQ-w>w;1ST22WQ%mvv4FO#st;Uc3MR literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/binary.gif b/trunk/docs/icons/small/binary.gif new file mode 100644 index 0000000000000000000000000000000000000000..995f79b9b10d5a49fd6e6d9f641d3bb65cfffa02 GIT binary patch literal 134 zcmV;10D1pMNk%w1VGsZi0HXf@|Ns9vIXP=4 o#kZK`47H){6`LuGH;j-%Jne!zs_mH6LPMOYA{Q)|S&IY!JF>VnX#fBK literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/binary.png b/trunk/docs/icons/small/binary.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2e1b073d62786ba186eb440908f86852839429 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?yd8<8L978H@ zwN6mvYjzNDy+7gV)sV2z$qTY9SXXTl3qLLTDr=&KUZ77X^R87w_qlyoRo-l9`IjRL?D73h=0P*6y9g6B1K# ziOVEwUdEOs%O3f$rd07rCfTu-Ok=hP2>3M3sW@?CJI9QFdoOPc+x*t p1+u{=%?$@@pDs(RakraW$82xbyly4;PoT3IJYD@<);T3K0RWRGS{VQU literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/binhex.gif b/trunk/docs/icons/small/binhex.gif new file mode 100644 index 0000000000000000000000000000000000000000..3d54a5458e6edfde1f60b8a35d549e3af1552ffd GIT binary patch literal 131 zcmV-}0DS*PNk%w1VGsZi0HXf@|Ns9vIXP=NV?p<;}t+_F|n1vIhdG61y)fInX+{xz%o-MD*`-pgKX5xCVZ_5 lPsPf~hJ=DqCWLWTOyuOYZ1$d>Ba9hs3_k!%1skspbw=XFPD;yQ2*-xB zgoI*yQI%ntpj-15_^92AoeW0r;JN-R&&-|_`zr>U4u~*G7;hF8=jgjlX30tF`d9(Q y=*_sgrUQ~}FW*UMJ>33J{0+PM{l}iXT&FX4I4j@G8(e1q0000e#^gj&X!xZAVnu4@CeN-d>06V1HFU9}> literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/broken.png b/trunk/docs/icons/small/broken.png new file mode 100644 index 0000000000000000000000000000000000000000..79c998c8c3111f187ac1d586b4c5101534ca0d0e GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?ydD}f*978H@ z)lS&W+w36Va$l+IfTF5G>=TxgsxnGN+~G{BH&QJYaatF)EMRep_hEj0;Lo`mIR>|8 z%JyziF8`+fOH7J)=ayM(GmbY(yOjwEopU^O?83)GCz3i37atRJIQYlxz~pv^zxs>{ z;rr`~1&%9K9B8#QnU(a>LPoAz`RFA*Hsyc>#tkA2%6+b}S3K6f^r#N9tI^W7nwV|+ zTbtuY%vSZ8f(HWqID-#zw+ZtXU9D5zKIQQ@HVHQqejb+scAys+JYD@<);T3K0RWxM BTo3>N literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/burst.gif b/trunk/docs/icons/small/burst.gif new file mode 100644 index 0000000000000000000000000000000000000000..d882ceba9cbf05051d5081f2e102ebff5f24edac GIT binary patch literal 128 zcmZ?wbhEHb6krfwSoELaz<~priULty691oD&Y82+%PWWh3>1H|FoGC5AOfV8f!UQ~ z*PVX`hZb>6bP*BCs6S}H;Vd99C5S^ubKfnY9r=Gl6W4NkFT36}`PFx$95FVrz#Gvo Z(|nHUXljWp;?_Q1GLa!b)18UI8UVh_DDeOQ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/burst.png b/trunk/docs/icons/small/burst.png new file mode 100644 index 0000000000000000000000000000000000000000..2b21436c78eb254526ce54349170863cb136d5a8 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZJ#gTFrlLTUm&E_)mUHGT z_3{GA2nX~{0#b}g-tI1JiD^4(ft+Yh7srr_TgeFr*druk6nK^k1Ri4$aK3ROfaL^7 zP>`9K8Iw^j$0;jFgqJ`Oni0Vzyy|%Y#xz>0#>6I2OhSCDvtvU kl&=I{U`%55*63hiuwBIa#*q8iR-iQup00i_>zopr0A~t1EC2ui literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/comp1.gif b/trunk/docs/icons/small/comp1.gif new file mode 100644 index 0000000000000000000000000000000000000000..712f36afdb27370918ce1eb008be6073aba769e6 GIT binary patch literal 130 zcmV-|0Db>QNk%w1VGsZi0HXf@|NsA#l$5~0z$qaZT4Q55rOtD`-T(jqA^8LW00062 zEC2ui01yBW0009=D7xJKFt$LdB@lxJ4RqIg#Z8m literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/comp1.png b/trunk/docs/icons/small/comp1.png new file mode 100644 index 0000000000000000000000000000000000000000..6d8c3459ed08a21c1d7cc50afbad7a1abd5471b4 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUJ#gT_lqpmG|NpP4C=r#M zY`OGY@!oqt$zwq`CITtOByV>YcCo~c*Fa9Rr;B4q#jWIo1I#WlF);^t*c}}inFS8J zUO2i?;7o!ycZ0#9ODtRqvsxT@!WO8Bhbt(XnwprHTy1Pr)D>ZA;0bdSTQG;=Lc#>L ov;`iD9vhVdX74r>m|<;87h-29Pxjp00i_>zopr06UjHhX4Qo literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/comp2.gif b/trunk/docs/icons/small/comp2.gif new file mode 100644 index 0000000000000000000000000000000000000000..7759eb11f95a4bb3803ca55eae6c3ff8fd100b96 GIT binary patch literal 131 zcmV-}0DS*PNk%w1VGsZi0HXf@|Ns9O7#M_vgsrWuz`(##T3U0)=KufzA^8LW000C4 zEC2ui01yBW0009>NV?qqFg8)DEpK4KIl+xqbkqNgD~s^aKww; lWe8G`jyjbQNm3FtI?)idj0B1>qD63^77l^1cw9^X06XYXE$jdQ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/comp2.png b/trunk/docs/icons/small/comp2.png new file mode 100644 index 0000000000000000000000000000000000000000..57f7ad197b8e18ceb981ecdb30a05611720acfbe GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUJ#gTFgoH#(OUv4|YybcM z9~2c;eC#<;a^D=?L?FeOji_2J;mN5pjX-!C6mBTe9h@q>&CzYj( mqxlM(sG&g%casAHGs8MFfm+4rr^P@!7(8A5T-G@yGywoMl{}6B literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/compressed.gif b/trunk/docs/icons/small/compressed.gif new file mode 100644 index 0000000000000000000000000000000000000000..d3b156072ac0b62c0248694d2d05791379e34927 GIT binary patch literal 128 zcmZ?wbhEHb6krfwSoELa|NsBl+1YdE%sFu2!277EYykl;1`tsE$->CMz|5cn;(*jL zFuPjpx+AC8q?t7P$~sH6D{%rMQ(HBiPS!|-)_OUXyj2ijRTh5h@?e)dzw#N~vZiai c6)G%M%rgTM8yr{}o0lx>>ev_S%EVv|0H!@EhyVZp literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/compressed.png b/trunk/docs/icons/small/compressed.png new file mode 100644 index 0000000000000000000000000000000000000000..43acd8b943dadffd426aabaa42e86df0891b0274 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZJ#gSac6RohIdlI1|NlNJ zDqBFni-BQ<`NyR|1&m4F?k;SJX*+6xoG?!p$B>F!$q5b&ZW?EE)-WVXI7+e|V-jdv zm>>|+<;dy6Z6GbJ-DuLrAnCJCp>6ZVjhr(cCgr?gO0$rZUfm#h=-9C}3T{ds8zqj& iB&&7EHZ?gp2r(3X<=P(@v3?8C1_n=8KbLh*2~7Y3^*sCl literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/continued.gif b/trunk/docs/icons/small/continued.gif new file mode 100644 index 0000000000000000000000000000000000000000..e1c9f2cfa68034f0439e336d3b3903deb44a0883 GIT binary patch literal 114 zcmV-&0FD1gNk%w1VGsZi0HXf@|Ns9vIXP=|;7%PM|whF~X2*V%{U5E|8iMaEOD$ U0n_;{NXL`HRB1Y&&_@CQJD2_|n*aa+ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/continued.png b/trunk/docs/icons/small/continued.png new file mode 100644 index 0000000000000000000000000000000000000000..db17c424650859f7b8f2117ce08ce4e78888e1b9 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?ydHtR)jv*Dd z&R*D&GNR2Uen0VOOkQ~&?~ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/dir.png b/trunk/docs/icons/small/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd6256bdbb781ad96d26b02870c8dabb1622f5f GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZJ#gT_|2ymc-&?z5L2bCV zwYI7(P$v7ROxnB?v5!j_n}qZY{V@N{tuskoJUY@=v{0SD`W_*6!7548*XJ9zi% zGyU#Q;FuCu+Mq0HYu{RTEKU4Vh0?||QA_tvUAX_^>Py$klAL*~Lv|O7nuyn2n47&`btTS3j3^P6t>yewCRwrrVbz0%P@q&p!pQbR!HK;_&hjwjs0n_k|_ba-tRk+K#r}ai(^Q|t>gp+CIe|{=?xYPl4^Q-=h_Z2^6;EG zc1*3$Xu1{p00i_>zopr E0QN;PK>z>% literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/doc.gif b/trunk/docs/icons/small/doc.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fcf18db2a89a540716c06e734cc564cdf08375a GIT binary patch literal 191 zcmZ?wbhEHb6krfw_{0DLmX?;;+1WikJ?GAyd;a|S|NsAif{H&`7#SGY85IA?BvmT- zCKi=s=IMDCC8p-47CHDPXXpj{dFr{OGU$Lz0GV|Nmr2Y%6}#@Zv(3<4F35AuIl!xvcWvVE3&b1Cxh RG|&8^tTFrSX;&r&YXB6~L|Om< literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/doc.png b/trunk/docs/icons/small/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..c560df21d3c48dffb288d24f7f7a4212bc15b531 GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah+3ye&|Y znRhqvklAa_-HUlDQ{^5UJ>x9Bl!3*|^xU0>)$?<^#Td%XbyXBwSQ5@pZJ#7&v`DpZ zRh!4;?n6mS9apj(u;&oEFK4InMJ|iS@;{5uk&DmYd{4N2Tke$W;`_fhef`S#YjS@0 zbV>iUKo_c%xJHyX=jZ08=9MrcRVw%<7L{b?>3J6=rsk#=Irt`L=mqbayAUSJ1# Omci52&t;ucLK6Uk;AJ2H literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/forward.gif b/trunk/docs/icons/small/forward.gif new file mode 100644 index 0000000000000000000000000000000000000000..2997466eb4de77500cbe27060b1a590f251102ab GIT binary patch literal 125 zcmZ?wbhEHb6krfwSoEL4($X?JJG-Z+=fHsj=gysDfC0syEQ|~c%nUjp0gze-W+#hX zTmETtFwSL&2y5Nl=5irbM5W{Lcb21_)0{VRxK0$bkc%jd_Yl5)#{CVW($PnOg`QH9 VToX4n&1RWCdxjo&kqQHYH2_Q8aRPp4rmu`- zG>KU7gl)k=|E;BlOv-&$y9#`6vF)B)6cA=BXY+OC5eHS-Zx>pBs5U#Q9}`W@RONcM sBH`auwM){DlN|k3SBw7lI9Sj4rp(KBi<{n8pu-tFUHx3vIVCg!0GNGUY5)KL literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/generic.gif b/trunk/docs/icons/small/generic.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8da6ff92c3103d440aa34c842efce51ddd2d55c GIT binary patch literal 116 zcmV-)0E_=eNk%w1VGsZi0HXf@|Ns9vIXP=CMz|5cn;(*jL zFuPc2E&As#5ERnD*ARJtfp=NqymCk7r$B>F!$q5NT2@MRQ;cScoXLBB9C9ot* za5zZv_z1KWuF#m0cz`2SLOSSNf(Wm$h)7BT1H3mVwz!V%Hr- z1E&XvCVaS5R(RiAy>mgUql=e;(y~pho8&ujXu&V@o)YW0l^; H!e9*mJvSwK literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/generic3.png b/trunk/docs/icons/small/generic3.png new file mode 100644 index 0000000000000000000000000000000000000000..aa38963afa2abcadb18fceb583aa705aae9b9acd GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?bJ#gSac6RprsHkiK0WSuI zd1=SofKrS}-tI0e{TVj{fgB@G7srr_TgeFxjH(I(42C^Zrc4n{ e&3OOfw2*gItqmas!g_N~w>q49yG@Lf!5RRR*e}ok literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/image.png b/trunk/docs/icons/small/image.png new file mode 100644 index 0000000000000000000000000000000000000000..d92f0a5fcc45d6a98f9a3c92864e9b1cb4d68c46 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUJ#gSac6N48PtX7V|KCSN zwImz9zh()PRC_T0I*?*a@^*J&7fbAT4di%ux;TbZ+)7SxU|Yi)(6-8YieMC9YKy32 z#fE@^*J&7fbAT4dkSFx;TbZ+)7SxU}IBgI(qbIBj>RK!v@0{ z3Ov&<6=)o86g^U)r&CbKYAAA9B63cIj6}qdJD0pfotq^k8hVmaA1ko6P1s_Rc=$pR zo0#Hu7vT*_#{(3_)mK<1uoX|3G-;9&Gc&`kkHQ80#fCe9_Az+6`njxgN@xNAHjzb! literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/key.gif b/trunk/docs/icons/small/key.gif new file mode 100644 index 0000000000000000000000000000000000000000..8dfd6c09de379a7fb7e78f3d06b5e2dbc959b109 GIT binary patch literal 187 zcmZ?wbhEHb6krfw_{0DLmX?;;+1WikJ?GAyd;a|S|NsAif{H&`7#SGY85IA?BvmT- zCKi=s=IMDCC8p-47CHDPXXpj{dFr{OGU$Lz0GV|Nmr2YX6}#@ZFYAcxF>N}S-D%%k z#wa;mSK3`9k(pCGM`QUUra7VZmHVu_rmbdA-1QFo2l NCU4lW(}RJ*8UX)gL+=0p literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/key.png b/trunk/docs/icons/small/key.png new file mode 100644 index 0000000000000000000000000000000000000000..1a45f67df3115e1caa9ed558cabe24553cd87e44 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ahvt0^r(6dQ?I{WEEqt7^yVQ*WnHIiyWVwMM@}B{Z{={c_>F*D&e;LZV z=#-1A_w2(4834KPd%5^!VBym-!XW)`njxgN@xNA6%Sw| literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/movie.gif b/trunk/docs/icons/small/movie.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b4a42e7a0eec8e4508903e9bd49cd966e966e21 GIT binary patch literal 134 zcmZ?wbhEHb6krfwSoEL4($X?JJG-Z+=fHsj=gysb{`@%u7%2W^VPs%nX3zogKx!G7 zy*+mMeAYkV+1#MabHG}Fse$nzdz^H8ru>rzC6{fBxi)IB^anlsy)r`O#>SQkwF`?k i-+B_~9;vx~3vcGG7n{Cov&^1%&M%y6veyh225SHs|1u2# literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/movie.png b/trunk/docs/icons/small/movie.png new file mode 100644 index 0000000000000000000000000000000000000000..7c126042c9aa4e013f543244b0c281e540b06d53 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?ydCi_Kjv*Dd zu1?&@d)R=7q!eTc&D)5IHA6<$y`u@`%#5a*Q)JecWT3x1vvLV+xFmDnh0y_QvEk9 zk1ty0yE++lh0WicVE5%idU(O!q(`NdKh#6mjUp`ty!>_N0G-3&>FVdQ&MBb@08;c! A#sB~S literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/patch.gif b/trunk/docs/icons/small/patch.gif new file mode 100644 index 0000000000000000000000000000000000000000..100484e59822e79e22ab469fecd4a39052a66875 GIT binary patch literal 182 zcmZ?wbhEHb6krfw_{6|qX=$0Ao!!&ZbMD-^=g*)2|Nox>3>1H|FfuT(F)03%Nvc%v zO)M(O%+vEON=(g7EpqTp&d>|?^VD-mWzYes2AOpTmr2ad8N2S7sdgD9bMoA>*d;jA zG*oa~#%+fN-d&1Z?m{=gQq9|Qen-8 z3J6=rsk#=Irt`L=mqbayAUSJ3LjKR~@&t;ucLK6U8FkJNj literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/ps.gif b/trunk/docs/icons/small/ps.gif new file mode 100644 index 0000000000000000000000000000000000000000..fa4bcfce30f5fb3f62e65f0c989ac15be60a49b9 GIT binary patch literal 184 zcmZ?wbhEHb6krfw_{0DLmX?;;+1WikJ?GAyd;a|S|NsAif{H&`7#SGY85IA?BvmT- zCKi=s=IMDCC8p-47CHDPXXpj{dFr{OGU$Lz0GV|Nmr2a76}#@ZALB7tB+7HkIql96D6GMaovr)0~p+w&0R?vcik1 Ky{BB67_0$$w?x1I literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/ps.png b/trunk/docs/icons/small/ps.png new file mode 100644 index 0000000000000000000000000000000000000000..5c604230d07d4611118d95d9c0d916c99e095104 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+AhlV6%Y$%Xi7H0%^4+qSGG;O#OJpRn4nlh0!@qvq=JH3Qqpd$a@#YU;cEJ+@c~^ z)v43g`Bi+-3gT;<>ayW(QsDVR26@FBdk(e=NV6Y^c0Jm%`MTH2qX`vkRlm;8U)3dP z@a);css;v*DZ4W-=kT8B13F2i#5JPCIX^cy yHLrvrsZzl=v8W_7PtUt3F*P@}$iX)`Loe9RQ_m%}@B%x?cMP7celF{r5}E)dJz-1$ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/rainbow.gif b/trunk/docs/icons/small/rainbow.gif new file mode 100644 index 0000000000000000000000000000000000000000..8216b89bade87b795a7345329da487735f3e07eb GIT binary patch literal 3811 zcmX9*2|QHo+ddH{AxoAlA=?Pq8Eb=SjP)JMn6Xa`Ml#0M*kcR^Nimp;vQxd3HA&gG zP{>{hMJ1K2r{2-6a=6k2nDoQqb?SX0=ifo1OVxD)*A%?C=kWsLqNg*gMnlaOlHxTOc20< zz!KXE2Y^c~F~0BUQJ^eB8vwL{tO*bUf-x+@CIAvQ*$SYR z&94POIgkkeEO$8&lw%=q08CD13E=<$2jOfb2w@M|2>=kr4#Qe70Dyr29t80$Py)OL z0M|f30t6+1A-3%hJN6ulhyTQ80pJ`vHvpD`bO4}(pdgD20D>TzRnZ`bW~%{~3v0mA zv*01tc8+DhIt0`L*dMDFWL=iM0o&SGAekKnAcHZio~?}mHvhk4U6}o-vkUuQ06YiD zR#Yp|w6yc|^G?~>CRdM`9LWn~Fzkx#EN)tel!*A>@%LA#thBFDynC1OFGZ_fOG~0j z!l%^-{rItQM+c;n+}(}pL!B8ob4Fl9fcS!_Ix*ok<#u}J^l9KV5Wg6ou)OkKXLS|x z2_w5MD;x4XL}g3Gb$3?|l#Bco8OimRiv;QDuEJaJL-d*ML~g28hWV*q<5t)GlCuv5 z5{tvD{H>44nNO^u4gt^CCpdzEn$wBT6^}*AbKTURC+jExgqY2c8ibWBh!_jr1VNSj+5_ zp*2yT57lD%aNQo+A+u1w3bd6cf9h*Kj}N4Y9(vfjaO$8D{5SmSd!yTmm$xdjBR`%f zA7q+8y&C;Rsj-OI^E8wG{nQXm#R^G{-G)!9xpyw+#2fN1siC_n%#W#pRSEN*f2n_u zY63767tK{LJ%x@aLn-7U^17ssd2DejTM&9ORZ8hPJnES9HQ?n&)E_NT zN6w(Z@?Om@K9^DLVOZ&?&PzDwnBKHkK0mM!^(x0OAzAmu^#taDf|c<`^D6<uj6|Y%%DOL(v@tY|+Aw)l?I3cCNKRBTjtCrVn_-h%?cGew=uk2$MXjYD} zA3OPIgpviV6oEt6a^d9`rd*sHS^x~zJFP&_BYGEu^UuMEc?4JW7kZMHf27t%y-gGM ziT~QtEq4DPzzR`Fp8*~W2Vc}^aIxPaB;Ts6 z`zI;F6U`CLu$0LnUGkrDmBthppe{Hka(XR2_Y-qGQLjhc0^Y)Dg!V4X1RdUn7b%LU$dF-mY_O zcAYZ~_vSHKH5T8VR66w0BG>F|gHOWR0p`Kiw?}=&0pDb9SGjFfD4sK(rYJD;%pONS zUqYA7u(voXcy}cUR1?wwAC-%>K#~s~p9gZB;DMF)){{hc{f84>Ji?iQ`YysRqFQxh ze)AFcC2kfVW13UQ7Qrg^^jCd-mS*U$X}Im7nO5$+`q-}_r;U2%KA;UuClLQ67<0aU z!woIx<5jgS^AyVa#89$a&-7S+{qET*F$ey7@@-3LF;SJGcG!zE0q|*VSN+G>oQa4c z7e4=!oHx818nC7B?WI>?))U2NqVM~Ae<4()&yA5hrrW*02|RqV7(U|JE#>p$YLV$T zIzINZhxn5>N>A;5j>YdS`|SVXJb0G4J0e(ZD%&mBU<;|swG{KfsY|t%3D|5DiYZ)I z*DEZ)`lnG`D{DgQXiOvLJ@u549VgwABV$Bot)Qs{=a=>K-KX7cXzp9pNBV~aA^(!? z0~#SSdcwW>W1A)6yix+*<-JXB5uwIEUfo%8>r+t9Ql*5rF5YB{+U|yyF@?QEU;4rN zvoaY{}F4+jl5k8=GIY!8}5^F~Xc5H8a(s8r+vNK0~+Q zM`rR`aCVQwC3@7aZ{FfLFUfR+v_#zAPLpz~;h8fMmRvwPZbjLYTpF^HT|?Y46Y@LD zbq;E!%GGjM|C2?@oJYO-lv>KIm1+pKt;L>EUeQPt-)?m3q=jo0at5C`7pL~(2XB?? zDj)yKoO97axc>7C{Ly#xrEV>9UrU(^ro_idBb0S&CxZzxqeq7~pkYsK>J;Oc#!uHD z2jv$}-G2IP=_z^<3xBV0N0qa6x*kbSWX33^9QAT@DaIfaBGNJ?M;i`)hV|&2;?7ym zTISQt?|rkmX_$3*Me*QIfsNwYJpQv#bG%@VEd5VLVH>TdTBEPQFAqhiD|9@O-d94N z+z1>|&NtZ=yc2J^<%oR!a`FX#CZ$&jQ){_;+S4{mnp`XT0Or(2d+eI~rS5~V@xW4G z{TRtSIHEvJeRBHe;~`sz+qYKLgQkx^xqN%(Qpzju@1&9OF?Yq-yW2y;#j_L0lFIhE z>3T}{m$TjmS z59mqmj}7HC70Y~kV=~BSf7nnj+ayI?+F*=7Gue40Y&M0gcw@32@O>Nlb*g64E`Db< zx2BgeZKX)^+`cj<}BrgL>P30~YbyOSQty`|}~>ic&$^6r{#F<>`7E8jvmyWfPj|A;@fc2;vGk+V63TQP~E z&+k46?>5l&-pAT;;7r~NNFs21T9;oR4>jEM3mL@CA{`el`G*%dhV(dwItv?Ax?3O( z0$m9493B=s29?utfIa+)?-n`R9Vm9egEgQgn+HU}Nn zW-}tb7>NW|QFBn~!jTB`;UaS%uBb6Xyo9A&(+7DJR=c4(9Xjcz&VlVx)X{aehw3J& zZHL4#GkU9&2GcJ}OzEm9Uk;k}+pEz7Yv}*+2raaR=JyL7f+iovB^yn-?>8s&wUH{$ zAtFT3$0fqJccK4sopWlAaj6XZFVM4;BM=ZL6VhXEV9E0OUJCux4yN-+zgIUb^b9@O%n(O@t^2cZhht_OD)T$9?VpQ0JBWbp~kgVMg>QEva_~YrS<4tsr)3M(+~T zfUb54hl`+J5cmJ}h)$ZNlf@}UVwqp3l$W^)u~<_4AZ2|m8Ga}xTsI|42Ytma#({>; z$_TjI7SJr}B+Nzq%bhK8j_P|Hse%G-1tAp*vIj-uI!^^f889g6);a}o#zd*hG#9Da zEA87?(!_k|$efm-_*}7*xEloyt2sqtzB&|Hd}bQJae?qSZE(={aK+V{bS=@9gqI(+ z0@I=*9^)lb6aR>ue><2Pf0xftC+S%s_Txu5SMW8%3SEb-B!3m9fc=XCs-an;*R$xM z$LBATDf&i**O%Nfe-M(j&XbOS?ujaS$L2^8kb-I09ObgNQ(+<$OAI YQf)BD<7dvMP-NGBf&PAQ3ILe=54mLULI3~& literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/rainbow.png b/trunk/docs/icons/small/rainbow.png new file mode 100644 index 0000000000000000000000000000000000000000..175053cb4335738d0e0a4f7f93e745acbef90443 GIT binary patch literal 2418 zcmW+&3sh5A7QGPu9|dGcKolyX(OO=#-~gqRuL+_QkhZo;5~*nXlmS$dNNEx<8U+dX znIL|OAR29pidZARq!gUkAPtBG5g0+iAfG@`xDfJY?(2GM-FNOjd+&44S@*5=PR7U4 z9ql~q0053LjHpBa%rO)%vLT^Wo9fUCfEhP_OHwq@K>*X!(V_!)AOP?VfK*rpKp6y7 z2&sUEQYwTqfC@!607@k2%>aM_8HjHKo&JV_5JDlMm6SlR9fFsH)ph`1A~B)c4hWP3 zAqQxQloo2yIS3x2P!T}^fC8cn;6cbkgh>E7lY|1u3BDXaZ&(5Va`%SN8zEr;3WZ1* z20$1LBb3mFND>_Y7)UgOoj)Nr-9+C2 zmO%*s5(u3T7XT+1kJfky;|VoDE+~QY2v(zQH!?s)APo@1l0$S@VgnTl1f~ObzBU9^{+8e;YqxnUoM>7ahC4%$eHHZAMq->AoJw0W@eR{s8=G%j{Otta@6F=w;m#Oy&)m@ecQU*G+v^it?Z4y!+NGUpHABOQjn(Y!bl|vj zTK(~0XnM{sY1P@0O*y1WW#!Y6pUM`Ob;)nYhlhtT`M&u5!RI$$w*F2uQSKIQ$~T!z zN6I3#&ZA~;KceCrmrM1+387p3gRsgSm5C$%y7jtG-v)C?hn)kg=0(Al9u}t4wYF>f z*SY<9^@@mDJ~KP(V=QLurUcmcSR{jn+R4o$iFEJb0lrTDnz@eQCt~yv*^3 zJFWNI`X9S>`}Xb5uhyQ===9YF>#X)$zO#AO-Mu|+olNr}VY-Z|T^&ERZJk^8iK902 zZS$x0b2tqDl`bb!le{=f54)WUxwvH&s|>dc5M2>ge_s83>@)d+uBtxzva+LL0#R_d zxGmypx_iL-^;4_&FYc`E>gfr#D<%C>UL~AJe)!c11)v>JYc2-lYxcfQwc=m6bXReB z$W~U6r+MZ-kgE!@WS17p_E^iN*EFSSeyd!>3yNYEda?^C6kk&7GOO#a!F0Ffo;;!Z zA(8uTcDzOF$L5<(3NQGw{r$ieSKb`uNO};deryG{t!Qm0ad@uA)AYxx8_Sf|BAy@io6L6(-n$ifjA~iL;98&R+F*RZmg{ zKVv*K%Is-`s;I$x{an4(s;AL2xy{#}x>0svc4UiH;uY+3bsToYc+1NsmA9Wwt2sE7 zFHBH))AVK~qxxle?vd;t3fy`^3i?S8;=q*lEVvo zm$RBR?0*M$GleCaqe+MMg|sp~&MVK^QvSo#COgoUqjKh((4Y>^e)nT4+Z8pv1WX?j z?aDJ_FDjByD8#HY-W3EvL0%9)}l(cDCOo zFJ(B_$aXDZTy$mFk*yxR%+09LsA>-EJm~pRg69{#fwjANU*AaH$s z?b3T7Pum(<>Jr8aS4PY@w)GEIDYdA&hqc@Ly(Dby_Ur^zy!Vq2Xu(Bat}hCd1{QX+ z)J%zN<6!ih{ZKJ@H0(TJX!!{XF5D>y3VCOcn8bq&GQ}WE`~{E5xMp84MK1J7W)~;} z`B53WO)cH_(;aENc09!(5w+tH{N{`(ReJUXGM+N#+sO(nJS)c+bXNPk#nws{`crsQ zj%>JCUEw5%;V@m2xWX5<9ikv2b!n@5AJZ%|HN`qCm8|MdSCwD>+*-k=QQcfBX#|uE^mSdunp48Hj{X`W+SCm`E%XOih27t30l^z z@rt2iPq{%wOs#3?no*Y-4)blVwSRd-KW~%>i%l)>`hI<^3VoY3>pYi#mj3y3R${gC z;GC)Qma_S#(nhf6LgS7Xp=*!gE(7@Be13gbG|42MPctU5y&Qv#5>v}?yW=P}RDDl+ z?l(1_xe&UUho8AdXbkiAdY=(2%WEpc1$QwlQok_f&ydZJPhdT)1!I+>%T_Qa&OtZ* zaYfH;`#o(=GrnTR`H9Z}_JLk_>5w1+PZ4FCj zRyT%4#uh3Io}%xMI@UPak0f)CLo?^A?n%$wpYYM+O-6~a>VcH^x%Ir}^^}p(%VjCE zCXQS+4W*sWIh=IFtEIu1-$TD~ppPD{$5Zrmzl%=z^l>ANnoh*-=XQ0CH?-C1OYx5E tj+}Fo6WHJY&ybTexggfpRTu`K*RHrL-%qveGoYUi5EC62RTaU`{Xff*$Fl$c literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/sound.gif b/trunk/docs/icons/small/sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..a7a89ffd9ed29c24e1759e48291cadb875f6562a GIT binary patch literal 130 zcmV-|0Db>QNk%w1VGsZi0HXf@|NsAUb92DJz}B3c_ZS$h0022kN&o-=A^8LW00062 zEC2ui01yBW0009=D7xJKa0M|0iNY9L?>oRm4WtwVAYcqvtDHa_pF~g>Zy?Whj|;FJ k&6i_@dN;{osSB_y&_-ah8I>H<4WSc3QKFczSdah!J59YUXaE2J literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/sound.png b/trunk/docs/icons/small/sound.png new file mode 100644 index 0000000000000000000000000000000000000000..6e3e95d3d01a390c8ae57bd8ac4631f69b36d526 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDUJ#gSaadGkg|NpPene$yj zVl4xMrI!~_a;MO(Fd)U4xup za(G0$g7wn#kbk>gTe~DWM4fl?XO@ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/sound2.gif b/trunk/docs/icons/small/sound2.gif new file mode 100644 index 0000000000000000000000000000000000000000..07706e07b86d25525e8e7fcb8cd2d8b10c235d49 GIT binary patch literal 119 zcmZ?wbhEHb6krfwSoEL4($X?JJG-Z+=fHsj=gysDfC0syEQ|~c%nUjp0gze-W*duL zK7aHX7^e#>G_TrlZjM+_!c@ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/sound2.png b/trunk/docs/icons/small/sound2.png new file mode 100644 index 0000000000000000000000000000000000000000..bc46eb48fe59bce696319655f7377566780f44fc GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?yc}qQA978H@ zl}_{(Y&H;R-T(H941YvIKtn5^)+z?p&_GrmF$orfhy%_%d*l?hcqaIteD`~H>}<`` z+7UJOr#>za?|yWC=^j^Q24!E)84{td<~GDJm@>Q;O^{#T>LgUe`pWrf5aT?PXQkO6 z&DLvj&wBgtaM{$vi~A(>U+A=2NU(@99Mt+cv-Ni5;fr~Vyf4m0@0cRGW}#?HefONN jyHy&_9;tY#a810L)68h)2`*irgBd(s{an^LB{Ts50xwq0 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/tar.gif b/trunk/docs/icons/small/tar.gif new file mode 100644 index 0000000000000000000000000000000000000000..59c3ffb9a5f0dcbcc0052a6dc8b428f4b033d316 GIT binary patch literal 132 zcmV-~0DJ#ONk%w1VGsZi0HXf@|Ns9vIXP=H^|M=26Efy0jDoCS8nDw3MpHX8$hcs!0R5&$~~!7=6l literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/tar.png b/trunk/docs/icons/small/tar.png new file mode 100644 index 0000000000000000000000000000000000000000..12f0347bf9cd2d5131184de55dae0238ece29e4b GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^JZv^(q?yd2>8n978H@ z^-kO<$fPLXdf!N_a9SZ>r&?HIiewbqw8RwQSrV2JO$(2iZ4htR)$n|W%A4osZ}Xp+ zc>ihE!$qn3fz_AeW^Ouun!~Z7uhg;drNY`HJ03qxp2_fH_Jz$SnzpxHKfy7_l2azC zNnpmp13~g?(-m_%Bj02>mwsK;#dCj+-pOKx9{a5f2U9ZKR6ac0e?E)D|K`iJ6O~u* bk!DC*uX6R!hdNuJI~hD({an^LB{Ts5S|wX9 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/text.gif b/trunk/docs/icons/small/text.gif new file mode 100644 index 0000000000000000000000000000000000000000..66ceefbc8c46837738701f2ab48d202b4df62686 GIT binary patch literal 128 zcmV-`0Du2SNk%w1VGsZi0HXf@|Ns9vIXP=L7D<;z<5S%P>S%fZDrUCEXNey i3D;T)3BKR#h$>>1MhO4_ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/transfer.gif b/trunk/docs/icons/small/transfer.gif new file mode 100644 index 0000000000000000000000000000000000000000..d460d3fffe6c7cf99f9928a6304bd6067fa6f03d GIT binary patch literal 124 zcmZ?wbhEHb6krfwSoELa|NsBl+1YdE%sFu2!26b#_fb*V0s;&S42nNl7#SFt8FYYb zph}<+v!lhXJ92tWnn|;-tg}?R5+@)rwN=wel2yVXs`a9jYseiJzdNRf|2w!nNYjwY cpMNxu+d;~6|%{an^LB{Ts5fPFec literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/small/unknown.gif b/trunk/docs/icons/small/unknown.gif new file mode 100644 index 0000000000000000000000000000000000000000..7bf0bbc10a654c44b34856884713f88e202b3d5d GIT binary patch literal 131 zcmV-}0DS*PNk%w1VGsZi0HXf@|Ns9vIXP=NV?p<;}t+_F|o}`C)Qk76hx+MVW0-gHlm8q0>wI1hP+I5AqX7Z lsY3_=D?$QFWeCnFftzz@X-$72T1yV?|sLV6}lnkK4Y>!dZUK}|Hh-+|MVTf_I9qvr-K@2cm%Py$u^d^x%y4$>fbG$v-tE`TXoeJZ(@K f4p@7|h& z&1|tK|FFBsWSazuo9ss%95_N7yPR21$abm!v)XcOugIIYBf`6%eqrn2RL?y7X5LJo P>li#;{an^LB{Ts5e;iKN literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sound1.gif b/trunk/docs/icons/sound1.gif new file mode 100644 index 0000000000000000000000000000000000000000..8efb49f55d6a370df44ad6e3269f6f966ffe25f6 GIT binary patch literal 248 zcmZ?wbhEHb6k!l!IK;s49|(+%&;0*?=FFLyGiRnTFc=#fGcYhH{__jT$ShV!EGkg| zQki)QB^jv-1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz!(9+VBLGdRGBLf2ygAUMi29WIx%-I^d?))<_JM1*!l}uu2Kl{c)an9BQ z8Fjp~isqGPnlRppzAozM@n_rZ?DB^@TMqI1Z!lq-XpvS})uOfhlGZ1!vqC)g^DkYQ rbCHkPIiy`w;vU-;D{*7rCt7AIb`rH-)ly|T)gs(25}jS#oD9|g^MhHm literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sound1.png b/trunk/docs/icons/sound1.png new file mode 100644 index 0000000000000000000000000000000000000000..7a766be6cc8038c54605beca648425afa090b17a GIT binary patch literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5Z5#R|Nl2O1`=n^oS8Xu zW*P&7v9U2w^6&fe4}lb8lDE4HyI5k!Yal1f)5S5Q;#P9P0bU^q304K2Z%mGCjvSkp zGz2mzop~2>K!GE1nuaKc0aNIP>C>$>MHyI`CB0%|rZo732?TR;a4~fzFI%GGxRsID zxLNAhglS=OST-_oTsr$eY_n+d9OlAEt3wlWIF=_fFszZ5Ue4}nQwFp(ti&~<#5q4V zH#M(>AtWQSSRt{fL;*-;<|&k9q$(7YCgo%%E2QM-CT8a8DR`%r0VO<2(=$?wbriBe uybOob%o4ri{9GM{;M9VW)ZC=hA_YTBOH-d0UycB6VDNPHb6Mw<&;$S_1!QFa literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sound2.gif b/trunk/docs/icons/sound2.gif new file mode 100644 index 0000000000000000000000000000000000000000..48e6a7fb2faeb6ba254a87945246f5ca5980583b GIT binary patch literal 221 zcmZ?wbhEHb6k!l!IK;s4|Ns9pKy>EJ%$YOO($b8LjTyi|@tVo`|#kjl(c zD9K1wC@4+J$xK#A$~K Lz}Ywz1_o;YcDqp^ literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sound2.png b/trunk/docs/icons/sound2.png new file mode 100644 index 0000000000000000000000000000000000000000..45112909398771bab1ed7004379521ae610cf191 GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#RLEy}pGc#w-OiN2M zHZ}&zbP8DI0x8BMZ+92A#Izl?Ku&_Ei(^Q|t<>{-c^e!!SQDfoAC&E6?Af^N;4SUG zzwRG89eny;aaTTU&(PfMZRY*lN7gZ;|G;XMlGFoRRvdB^_2T*)A>87wZ}xsuWBh?x z>7p{ScMQ&#d)_%^HhIaeJ>MA)rzz$wIyt8aXjfQ?Yeb22er|4RUI{};MrN@>Vo`|# zkjl(cD9K1wC@4+J$xK#A$FVdQ&MBb@0N#3S761SM literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sphere1.gif b/trunk/docs/icons/sphere1.gif new file mode 100644 index 0000000000000000000000000000000000000000..7067070da2786b9842212ff1ce2307fb404407ce GIT binary patch literal 285 zcmZ?wbhEHb6k!l!c+9}?9|&g7{BLZ0=KudQXU@!=IWvuc!PwZC0S8e0=NFQZS*(y) zRH6W+GV>HlGEx-^N|SOjlND0(a}zW3^c1{P%YYIdrRf=|#X1VvAYO(;YG#REa(=Fk zLU3w9NosCVYLSAWrKKr@;!hSv1_ovZ9gvM6S23_u6rAu}z1QM(uhlIPp`JtRT@DHy zZ8JL^S8aON%CRcz&DRnUR>3@1XNE@hlZ*^I1j}_C#yT z68XztxyIW*eK)gq&Gg$oObhE&HaxGaZep#g4-2m9Y;B7#>??2R@5{BXndV`dHEXt- HAcHjk`1fN- literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sphere1.png b/trunk/docs/icons/sphere1.png new file mode 100644 index 0000000000000000000000000000000000000000..2198ae89ec4cd38ae9dedec1849543cd304e3451 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{Dd_;85Z5#R|Noyk^S`k%kUn$f z%*>fH(-;_xjg5iwjq7qh11ZKNZ+91twtG{nfShtq7srr_TfOHM`5Fv(S|57p>}C|M z2x6I6*sQxi(A!o~L6PNB^5!+O4}4s$uRmAfK>v)*T|u&)>5Db{dsn6Ety=YM;_D?- zmfh}U@Ls-kIrs7tH#ZB&`?nnGJEY-~=2N1WXwC9%lT>!DRYvd2&zo;dpFR284|dMD zou73>=R1Gm1UezC#5JPCIX^cyHLrvrBqOs}A+e}L0Z3)$DU@WSDio9^XGxPKmyi?175+0@L8L7oO3fUlDhC^y*iC%Jku8u-*YC%bA zZc=KIf}y3QDTCrq7DfgJW(FOg=?oy-8JMdxcJ29GAmOljuG+p#>+^!wLzQ;)UT5um zk+|bSXOMfYd{L=zjsF9o(~1rvGBq{}GB`LmSXvkRdn%jF4af{C6R?=uy5ZaLzjm9G zwH8$Kxi4iXD)_78aNoVF=4GE7r)afPMP*}_m05#Wld*D7Z?_kl#}r$ALGzij95@-Q E0diYklmGw# literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/sphere2.png b/trunk/docs/icons/sphere2.png new file mode 100644 index 0000000000000000000000000000000000000000..257632ba46db43a6f3fdee93a6dc61dd26d8efe5 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5Z5#R|Noyk^S`k%n4X!& zz+h}_43y-(^*$9yF(!GtyReHTcDx31$~;{hLn>~Co;%2SK!L|0F#H0qR!M`>3kI&e z;ws?_1J1L0U(5H=xl~{EWP(dI(XMUMndxmH0wf>G1E8? zam-K4J(L>xd4ZuA+uE}i7JWEzLngn%$U%f{!NLjaj`rV~A3o`YXRGp8rc@@=bFG{Q zKLTA4R^l2_;+&tGo0?a`5R#EutdLk#q5z~a^At)lQWXkHlX5bX6;kqZ6EpMl6ueW* zfD#_1=^3fTIttk!UWP+zW{F;Mey)x}aB4wGYHm_$k%FP6rK!)0FGqkjFnGH9xvX6w literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/tar.gif b/trunk/docs/icons/tar.gif new file mode 100644 index 0000000000000000000000000000000000000000..4032c1bd3d407abddd0f0e8801e3091726574171 GIT binary patch literal 219 zcmZ?wbhEHb6k!l!_{6~Q|NsB}`}gnOy*n%{)ZE;h0R|NRxrAh77As^X=jSPa=sbmz zj8uh!(xjZsWQCOc+{Da0Jq1HcOH&2!)H0x~M`?OSYO#(&Hi(zukeXSdmz{U7WG~8yuhh5Zb<@7 z`xV^^pIq^?J6sl`b?E$;oi=gneQc#~{w%G2Eo$=bQcK8x IUrq*V0QdG)RsaA1 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/tar.png b/trunk/docs/icons/tar.png new file mode 100644 index 0000000000000000000000000000000000000000..6c40521ff80f9282f16938e6fbfd5c7ab43bd008 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5ZC|z|L@ z=H~J@7dil?B0XIkLn?0N_8jCrpuls)uaR|=V{1f%=%qLI!Ru8xR$kFBHgcTJ6MB?Y zDOKBT#f}AgUb!5wy!z%GL(Q>U3Tx9De4f^8ee2qFD}d!I$Fygy`3ZT?TjN9hzc4;r zFP3%6gNYAliBE}ZM2T~LZf*7|f#x!Jy85}Sb4q9e0MnaZ ACIA2c literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/tex.gif b/trunk/docs/icons/tex.gif new file mode 100644 index 0000000000000000000000000000000000000000..45e43233b845960c59aa8933251d6d745b324031 GIT binary patch literal 251 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2c^13&d^F&3SUp#HU#6xa!*tin>9Z0|^A1!l(>hWb zZ!PfsEZ4Gxo$}LGGYd#m9-20(LPaIeg)1oN=Z{6M>Y}HwOe>foy~6k})9y8|ETZxl nuQycuR$g`V{oCDj`rkkOugz?zPGxp)?{Kpc$nTBfWUvMReehfo literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/tex.png b/trunk/docs/icons/tex.png new file mode 100644 index 0000000000000000000000000000000000000000..906622d3844661a0928730801e5dbe6c06b26da2 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-1il>WXNX4z(zJt666nKtoI%KL7aD>5i14Gca`76aUqU64w zw&HQR^+YJhF~r&TVX^6=3;wn99AE7X?w;#mGxH!rU(AZ+fQ?te4~XVCi?0j2>g37t za__da(YyD4Sgou7!*e71PDYpg($82muBZa-3oCJrC~?lu%}vcKVF<~{ELKP?Dp3GZ znRyB&8L0{drAaxN$qFg?xrv#1dJ5jDWk3m!()5hfVjYES5HG_aHM2x7IX_oNAvm?5 fBsDiFwMfCx($duD#g`*M8yGxY{an^LB{Ts5f|+Yh literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/text.gif b/trunk/docs/icons/text.gif new file mode 100644 index 0000000000000000000000000000000000000000..4c623909fbfb54658f19186beec8d362f87e233b GIT binary patch literal 229 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf25f;1ld^F&3SUp#HU#9hW!Rw()J9@9P7P`C+IwEjh zoojbq@AhdAxLane{lx8+w_BW5Lq@1~%@UylHdfUEOTOIP6XtsB<@c_)dDA0}cD??? QSNCCuzu3fEy_^iz0A2r7i2wiq literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/text.png b/trunk/docs/icons/text.png new file mode 100644 index 0000000000000000000000000000000000000000..34d0edf86e4702601cababe0759021b1c0dc6337 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#RL15<0na0M(K(W_% zWKIGp#w2fd7nc5vn}I-%pQnpsNX4zGeFu3N6ggNj6Zy3b!W-PA3>N;M6=SQnXYO@_ z-;T!?a=uhpwK8MntX;+W?>5hf44Ee<>R-E<$^H9@d7|4zcdXps_v@hgQRc`u&!uXD zl+-JMCWn={MwB?`=jNv7l`w>4WELwV7L_Ofsmwful8jV^g3_d%%w&a>{M^LMJUs>P z)H0xiM`?OSYO#(&Hi(zukeXSdmzvky)&eSX80_q%!jq zN-|Ov3QCi5GLscj@^ce2^Yj$FQ_Fx79;N9Ssl_@9*&tqqLuzJ;UUGh}jzVy1K}l+E zQfiTcp{1oMgW^vXMg|5Z1|5+3Aln(3Q#G`%?loA)#Gq@m*=ucI?DJZ$h{7jq60EN$ z%~d?lR>S0McO~B8j-}Ir=et8&oIMkM8Y@liURvT6>$dvF%11Mo3W@nQRp?BsQ#|oZ hcdptv6Cq9pYXE?dSF`{C literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/transfer.png b/trunk/docs/icons/transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..efaf17b682fc991783918932e9ea9edc715e7ddd GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DbWC*5Z5#R|Nl2O1`;!8&P-!q zFg7*@$|S^}R|ZmyN#5=*Y>8<*YJr?GPZ!6Kid(7Y4sx<6@~~dmZ@}tvfXiqHFUvEV zMiB+(sHVTuH%N){|Mu_q?_r!!eCUkyW3}aHckF!iJ=!aB%~rops^1e5#7b+WBG3C3 z1?gulxw?hvMF;~QSK6{KTN1yfFU+@?)33kHEn43Ae*GCGqkb1z_kRpL-^94T%#|tx zx*)8?HKN2hKQ}iuuY@5aBePf`v8Y4=NM+_Jlw_nT6qF|AWF{-5LrY6jpBG<_0BvCKboFyt=akR{ E05jQfJOBUy literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/unknown.gif b/trunk/docs/icons/unknown.gif new file mode 100644 index 0000000000000000000000000000000000000000..32b1ea23fb6f6195f1bb17adf9c3cb2cc29dfefa GIT binary patch literal 245 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf285X53oh^1 zKW>&-5jAtkp-JEQEv1zUHl91`xN@`LTGNM(dGW_4H_kXFe`nde&k0Pwmh>bVe^Aqp zn*VkF`rX~8eNQH~NZvgrA+!7Mou#}$yTVFbBTAg}b8}PkN*F>iGK&=wi%JxLRA!z+ zNk*zdL1|J>X0k#`er{rBo}PktY8g<%qclAuwOB_X8^p_SNX;zKOU}>LQ3y^gC`rvt bN-a__w6rw!dGX~4&;|xiS3j3^P6-Xz@*&Mzw-23{>5{AIi%LijXHkMRw1HyNzyFOS#mnvM?d*oFAHE` Gum%9J?KeFD literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/up.png b/trunk/docs/icons/up.png new file mode 100644 index 0000000000000000000000000000000000000000..a69ea00c5b70706a98fda039b8e92afa35829e1f GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0$P6TZ_3OC;DYgKg5Z5#R{{xxVb(YlvDaIsk zcNfP0OuF}g90N}m$B>F!$q5Hog&KY^Gc!NtXJdP2&%^WPzl6k(|HcL<{^uub_+Q_! z@ZW!CHX8XnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2@fN%Gd^F&3SUp#HpJvB@7K6@PEKNyM9n&%bmCrCe zcjss6%XbLBY-{hkn53brAS;k_~V>SO;rqEX_zty4nJbR|}ofI+Ll^r*| X^nl%z(d&ZmxB6;I8Lw|y#bCN(!>$jR;n}YIb+6~?|Mcv1 zl8b7RW?Z)P#Rs4TVI{5+CC>S|xv6<23?Uhr#R`c?)Gf$x;BUPcGG$|)DSs^7q zH!(9$Pr*C23@G7Inx2tbtfP<(;$=9bW|rtB=jZAu1g931q~<227AY87TAKR2_;Lhj O1B0ilpUXO@geCychGTF5 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/uuencoded.gif b/trunk/docs/icons/uuencoded.gif new file mode 100644 index 0000000000000000000000000000000000000000..4387d529f69f77810347be63429d13ff38bcb2c1 GIT binary patch literal 236 zcmZ?wbhEHb6k!l!IK;s4|Ns9p|NqaNIn&tKm;nhW{__jT$ShV!EGkg|Qki)QB^jv- z1*J(jnaK(%`MHUid3p-osbxS3kJ9vv)M6clY!ENQAvLo^FF8L~MXnDYZz! z(9+VBLGdRGBLf2?gAT|RknIf2@fN%Gd^F&3SUp#HpJvB@7K6@PEKNyM9n&%bmCrCe zcjss6%XbLBY-{hkn53brAS;k_~V>SO;rqEX_zty4nJbR|}ofI+Ll^r*| X^nl%z(d&ZmxB6;I8Lw|y#bCN(!>$jR;n}YIb+6~?|Mcv1 zl8b7RW?Z)P#Rs4TVI{5+CC>S|xv6<23?Uhr#R`c?)Gf$x;BUPcGG$|)DSs^7q zH!(9$Pr*C23@G7Inx2tbtfP<(;$=9bW|rtB=jZAu1g931q~<227AY87TAKR2_;Lhj O1B0ilpUXO@geCychGTF5 literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/world1.gif b/trunk/docs/icons/world1.gif new file mode 100644 index 0000000000000000000000000000000000000000..05b4ec205884f16202e290b83db7c36ec660a73e GIT binary patch literal 228 zcmZ?wbhEHb6k!l!SjfQe|Ns9p|Nk@0G-hC6Q2gf?l95@gkXTfr0HiYW6iPBu6$(m| zax#+@Qu1>XGxPKmyi?175+0@L8L7oO3fUlDhC^y*iC%Jku8u-*YC%bAZc=KIf}y3Q zDTCrq7DfgJMg|?A=?own8JLoL`d3=Lojq&DmV<08H)chf_{g}X9%4v)7BSC#N7g2- z#f}=s?(`k{vcq_8jpbY)WyV!4N-Aq^MwZQ4x?oEC?F~i2;bkXPZnEj*mSpYLJUDmD atT54C`TIV6aAK=hU_0K-zaxNw!5RQ*npTkj literal 0 HcmV?d00001 diff --git a/trunk/docs/icons/world1.png b/trunk/docs/icons/world1.png new file mode 100644 index 0000000000000000000000000000000000000000..3a65c00d8468f2455e5edd5b494fd4b5f39b7172 GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0#0(_&>W54PQak}ZA+Bfsg8;)!W1v7p;}(zx z#w2fd7iK{opHDzewWo_?NX4z>ga(FZ|JfUs++Ahs@a*h~7tB00m&0^#A2?vGo%NKB z?R08prX^3<<+Nqz5-Y5XjY~}rUtT)XcsldR%+;49=bh#1_DQc0WmAf8TibOeZ9`X2 z)Yi6xC8;SXe9ZZ2DJhK1`L|B3;N>~vzd4L~?MC0Vjkh_N82D>-k8Ed+xCeAbScz*y ziF1B#Zfaf$Lr6wuu|i@|i2{(y%u^`INL45(P0GnkR!GUuP0Y;GQ}9kL14?+5re~xU y>nLP{co`0EJ%$YM8W*Rf388d)^;y=HTjLc$%#G(=fAeEV? zP?C|VP*9qblbNiLlAoKHnWv}VomvKz@F-2sNG;Y;$OiE;98xn&^pf*)brgbA3rbRR zlTwQm3@t5985DoAFfuSOGU$NJ2ieZRTp_XR&O5bJ*Ohi!T+-@^=jL?!gy~R6SmeCA7ufyx{6*ATcJslr}JKu)ixi(^Q|t=RJi1rICmusGO>D6D376H$o2#Gw4| zM&Ivz)%M3WLVL?3o|SmLO#f8b7tQ`*&m42{>8IPZ8Qwm5CUD^7n+uj^L2avddr7|( zI8@r{=k#Nb+ujpB?GsP2)Xkl<RUDr}%b9ZV}q- zS0~#2V*a7sQ?35-|2ilA!AADOJ}aGDK!=5uxJHyX=jZ08=9MsnWMmdABo>t@0IAG8 zg_4X^g@V$goXli}l>FSp%sf2>@6ht2u5ugnWp00i_>zopr0H=3?nE(I) literal 0 HcmV?d00001 diff --git a/trunk/docs/man/ab.8 b/trunk/docs/man/ab.8 new file mode 100644 index 0000000000..aa1c7ab2d5 --- /dev/null +++ b/trunk/docs/man/ab.8 @@ -0,0 +1,125 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "AB" 8 "2004-11-14" "Apache HTTP Server" "ab" + +.SH NAME +ab \- Apache HTTP server benchmarking tool + +.SH "SYNOPSIS" + +.PP +\fBab\fR [ -\fBA\fR \fIauth-username\fR:\fIpassword\fR ] [ -\fBc\fR \fIconcurrency\fR ] [ -\fBC\fR \fIcookie-name\fR=\fIvalue\fR ] [ -\fBd\fR ] [ -\fBe\fR \fIcsv-file\fR ] [ -\fBg\fR \fIgnuplot-file\fR ] [ -\fBh\fR ] [ -\fBH\fR \fIcustom-header\fR ] [ -\fBi\fR ] [ -\fBk\fR ] [ -\fBn\fR \fIrequests\fR ] [ -\fBp\fR \fIPOST-file\fR ] [ -\fBP\fR \fIproxy-auth-username\fR:\fIpassword\fR ] [ -\fBq\fR ] [ -\fBs\fR ] [ -\fBS\fR ] [ -\fBt\fR \fItimelimit\fR ] [ -\fBT\fR \fIcontent-type\fR ] [ -\fBv\fR \fIverbosity\fR] [ -\fBV\fR ] [ -\fBw\fR ] [ -\fBx\fR \fI-attributes\fR ] [ -\fBX\fR \fIproxy\fR[:\fIport\fR] ] [ -\fBy\fR \fI-attributes\fR ] [ -\fBz\fR \fI + + odd + + + + + + + + + + odd + + + + &lf; + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/sitemap.xsl b/trunk/docs/manual/style/xsl/sitemap.xsl new file mode 100644 index 0000000000..d3712498a1 --- /dev/null +++ b/trunk/docs/manual/style/xsl/sitemap.xsl @@ -0,0 +1,242 @@ + + + + + +]> + + + + + + + + + &lf; + + &lf; + &lf; + +
    +
    +

    + +

    &lf; + + &lf; + + +
    &lf; + + +
    + +
      &lf; + + + +
    • + + + + + +
    • &lf; +
      + +
    • + + + +
    • &lf; +
      +
      +
      +
    &lf; +
    + + +

    + +

    &lf; + +
      &lf; + +
    • + +
    • &lf; +
      +
    &lf; +
    +
    &lf; +
    + + +
    &lf; + + &lf; + + +
    + + + + + + + +
  • + + separate + + + + + + + + + + + + + + + +
  • &lf; +
    + + + + + + + +&lf; + +
    + +

    + + + + + + + + + + +

    &lf; + + +
      + +
    + + + + + + &lf; +
    +
    + + + + + + + + + + - + + + + + + + + + + - + + + + + + + + + +
    diff --git a/trunk/docs/manual/style/xsl/synopsis.xsl b/trunk/docs/manual/style/xsl/synopsis.xsl new file mode 100644 index 0000000000..ee9319b56d --- /dev/null +++ b/trunk/docs/manual/style/xsl/synopsis.xsl @@ -0,0 +1,508 @@ + + + + + +]> + + + + + + + + + &lf; + + &lf; + &lf; + +
    &lf; +
    +

    + + + + + + + + + + + + + + + + + + + + +

    &lf; + + &lf; + + +
    -attributes\fR ] [http://]\fIhostname\fR[:\fIport\fR]/\fIpath\fR + + +.SH "SUMMARY" + +.PP +ab is a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server\&. It is designed to give you an impression of how your current Apache installation performs\&. This especially shows you how many requests per second your Apache installation is capable of serving\&. + + +.SH "OPTIONS" + + +.TP +-A \fIauth-username\fR:\fIpassword\fR +Supply BASIC Authentication credentials to the server\&. The username and password are separated by a single : and sent on the wire base64 encoded\&. The string is sent regardless of whether the server needs it (\fIi\&.e\&.\fR, has sent an 401 authentication needed)\&. +.TP +-c \fIconcurrency\fR +Number of multiple requests to perform at a time\&. Default is one request at a time\&. +.TP +-C \fIcookie-name\fR=\fIvalue\fR +Add a Cookie: line to the request\&. The argument is typically in the form of a \fIname\fR=\fIvalue\fR pair\&. This field is repeatable\&. +.TP +-d +Do not display the "percentage served within XX [ms] table"\&. (legacy support)\&. +.TP +-e \fIcsv-file\fR +Write a Comma separated value (CSV) file which contains for each percentage (from 1% to 100%) the time (in milliseconds) it took to serve that percentage of the requests\&. This is usually more useful than the 'gnuplot' file; as the results are already 'binned'\&. +.TP +-g \fIgnuplot-file\fR +Write all measured values out as a 'gnuplot' or TSV (Tab separate values) file\&. This file can easily be imported into packages like Gnuplot, IDL, Mathematica, Igor or even Excel\&. The labels are on the first line of the file\&. +.TP +-h +Display usage information\&. +.TP +-H \fIcustom-header\fR +Append extra headers to the request\&. The argument is typically in the form of a valid header line, containing a colon-separated field-value pair (\fIi\&.e\&.\fR, "Accept-Encoding: zip/zop;8bit")\&. +.TP +-i +Do HEAD requests instead of GET\&. +.TP +-k +Enable the HTTP KeepAlive feature, \fIi\&.e\&.\fR, perform multiple requests within one HTTP session\&. Default is no KeepAlive\&. +.TP +-n \fIrequests\fR +Number of requests to perform for the benchmarking session\&. The default is to just perform a single request which usually leads to non-representative benchmarking results\&. +.TP +-p \fIPOST-file\fR +File containing data to POST\&. +.TP +-P \fIproxy-auth-username\fR:\fIpassword\fR +Supply BASIC Authentication credentials to a proxy en-route\&. The username and password are separated by a single : and sent on the wire base64 encoded\&. The string is sent regardless of whether the proxy needs it (\fIi\&.e\&.\fR, has sent an 407 proxy authentication needed)\&. +.TP +-q +When processing more than 150 requests, ab outputs a progress count on stderr every 10% or 100 requests or so\&. The -q flag will suppress these messages\&. +.TP +-s +When compiled in (ab -h will show you) use the SSL protected https rather than the http protocol\&. This feature is experimental and \fIvery\fR rudimentary\&. You probably do not want to use it\&. +.TP +-S +Do not display the median and standard deviation values, nor display the warning/error messages when the average and median are more than one or two times the standard deviation apart\&. And default to the min/avg/max values\&. (legacy support)\&. +.TP +-t \fItimelimit\fR +Maximum number of seconds to spend for benchmarking\&. This implies a -n 50000 internally\&. Use this to benchmark the server within a fixed total amount of time\&. Per default there is no timelimit\&. +.TP +-T \fIcontent-type\fR +Content-type header to use for POST data\&. +.TP +-v \fIverbosity\fR +Set verbosity level - 4 and above prints information on headers, 3 and above prints response codes (404, 200, etc\&.), 2 and above prints warnings and info\&. +.TP +-V +Display version number and exit\&. +.TP +-w +Print out results in HTML tables\&. Default table is two columns wide, with a white background\&. +.TP +-x \fI-attributes\fR +String to use as attributes for
    \&. Attributes are inserted
    \&. +.TP +-X \fIproxy\fR[:\fIport\fR] +Use a proxy server for the requests\&. +.TP +-y \fI-attributes\fR +String to use as attributes for \&. +.TP +-z \fI + + + + + + + + + + + + + +&lf; + + + + + + + + + + + + + + + header + + + + odd + + + + +&lf; + + + + + + + + +
      + + + + up-A + + + lo-A + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + top +
    +
    + + + + + + + + + + ( + + + + + + ) + + + + + + + + + + + + [ + + ] + + + + + + + + + + + + + + + +  + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + Unknown element: + &lf; + Is the document valid (try `build validate-xml`)? + + + + + + + +
    + + + +

    +
    +
  • +
    +
    +
    + + +
    + + + +
    + + + + + + + + + + + + + + + | + + + +   + +   + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _blank + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/directiveindex.xsl b/trunk/docs/manual/style/xsl/directiveindex.xsl new file mode 100644 index 0000000000..e923e3a665 --- /dev/null +++ b/trunk/docs/manual/style/xsl/directiveindex.xsl @@ -0,0 +1,130 @@ + + + + + +]> + + + + + + + + + &lf; + + + + + + + + + + + + + +
    +

    + +

    &lf; + + &lf; + + &lf; + + +

    + + + + +

    &lf; +
    &lf; + +
    +
      &lf; + + + + +
    +
    &lf; + + &lf; + + +
    + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + < + + > + +
  • &lf; +
    + + + + + + + + + +
    + + +
    diff --git a/trunk/docs/manual/style/xsl/faq.xsl b/trunk/docs/manual/style/xsl/faq.xsl new file mode 100644 index 0000000000..05ebd0fe0d --- /dev/null +++ b/trunk/docs/manual/style/xsl/faq.xsl @@ -0,0 +1,199 @@ + + + + + +]> + + + + + + + + + &lf; + + + + + no-sidebar + + + + +
    +
    +

    + +

    &lf; + + &lf; + + +
    &lf; + + +
    + + +
      + +
    +
    + + +
      +
    • + + + + + +
    • &lf; + + +
    +
    +
    + + +

    + +

    + +
      + +
    • + +
    • +
      +
    +
    +
    &lf; +
    + + + + + +
    &lf; + + &lf; + + +
    + + + + + + +&lf; + +
    &lf; + + +

    + + + +

    &lf; + +
    + +
    +
    + + + + +
    + + + + + + + + + +
    + + + + + + + + + + + + + + +
    +
    + +
    &lf; +
    + + + + + + + + + + +
  • + + + + + +
  • &lf; +
    + + + + + + + + + + + + +
    diff --git a/trunk/docs/manual/style/xsl/hhc.xsl b/trunk/docs/manual/style/xsl/hhc.xsl new file mode 100644 index 0000000000..5b5dbfbd56 --- /dev/null +++ b/trunk/docs/manual/style/xsl/hhc.xsl @@ -0,0 +1,668 @@ + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<html><head> +<title>Apache HTTP Server Documentation</title> +</head>&lf; + +<body>&lf; + + +<object type="text/site properties">&lf;&tab; + +<param name="Window Styles" value="0x800027">&lf;&tab; +<param name="Font" value=" + +">&lf; +</object>&lf; + +&ul.start; &lf; + + + &li.start; + + + + + + &li.end; &lf; + + + + &li.start; + + + &lf;&tab; + + &ul.start; &lf;&tab; + + + + + &ul.end; &lf; + &li.end; &lf;&tab; + &lf; + +&ul.end; &lf; + +</body></html>&lf; + + + + + + + + +&li.start; + + + + + + + + + + + + + + + + + sitemap.html + + + + + + + + + + + + + + + +&li.end; &lf;&tab; + + + + + + + + + + + + + sitemap.html + + + + + + + + + + + + + + + + + + + + + + + + + + + &lf;&tab;&tab;&tab; + &ul.start; &lf;&tab;&tab;&tab; + + + &li.start; + + + + + + + + + + + + &li.end; &lf;&tab;&tab; + + + &ul.end; &lf;&tab; + + + + + + + + + + + + + + - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +&li.start; + + + + + + + + + + + + + + + + + + + + + + + + + +&li.end; &lf;&tab; + + + + + + + + + + + +&li.start; + + + + + + + + + + + + + + + +&li.end; &lf;&tab; + + + + + + + + + + + + + &lf;&tab;&tab; + + &ul.start; &lf;&tab;&tab; + + + + &li.start; + + + + + + + + + + + + &li.end; &lf;&tab;&tab; + + + + + + &li.start; + + + + < + + > + + + + + + + + + + + + + + + + &li.end; &lf;&tab;&tab; + + + + + + &li.start; + + + + < + + > + + + + + + + + + + + + + + + + &li.end; &lf;&tab;&tab; + + + &ul.end; &lf;&tab; + + + + + + + + + + + + + + + + + + + + + + + + +<object type="text/sitemap">&lf; + + +<param name="Name" value=" + + + +">&lf; + + + + <param name="Local" value=" + + + + ">&lf; + + + +<param name="ImageNumber" value=" + + + + + + + + + + + + + + + + + + +">&lf; + + +</object> + + + + + + + + + + +<object type="text/sitemap">&lf;&tab;&tab; +<param name="Name" value=" + + + +">&lf;&tab; +</object> + + + + + + + + + + + + + + + + index.html# + + + + + index.html + + + + + + + + + + + + + + + + + + + + + + &amp; + + + + + + + + + + + + + + + + + + + + + + + + + &lt; + + + + + + + &gt; + + + + + + + &quot; + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/hhp.xsl b/trunk/docs/manual/style/xsl/hhp.xsl new file mode 100644 index 0000000000..58aad47515 --- /dev/null +++ b/trunk/docs/manual/style/xsl/hhp.xsl @@ -0,0 +1,316 @@ + + + + + +]> + + + + + + + + + + + + + + + + + +[OPTIONS]&lf; +Binary TOC=No&lf; +Compatibility=1.0&lf; + + +Compiled file=httpd-docs- + +. + +.chm&lf; + +Contents file=toc.hhc&lf; +Default Window=Main&lf; +Default topic=index.html&lf; + + +Display compile progress=Yes&lf; +Enhanced decompilation=Yes&lf; + + +Full-text search=Yes&lf; +Language= +&lf; + + +Title= +&lf;&lf; + + +[WINDOWS]&lf; +Main= + + +" + +", + + +"toc.hhc", + + +, + + +"index.html", + + +"index.html", + + +,, + + +,, + + + + + +, + + +180, + + + + + +, + + +[0,0,600,380], + + + + + + +, + + +, + + +, + + +,,,0&lf;&lf; + + + +[FILES]&lf; + + +style\css\manual.css&lf; +style\css\manual-loose-100pc.css&lf; + + +manual.hhp&lf; + + + + + + + +&lf; + + + + + + + + + + + + + index.html + + + + index.html + + + + + + + +&lf; + + + + + + + + +mod\ + +.html&lf; + + + + + + + + + + + + + + + + + + + + + + + + 0x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/indexpage.xsl b/trunk/docs/manual/style/xsl/indexpage.xsl new file mode 100644 index 0000000000..71a2f9dd54 --- /dev/null +++ b/trunk/docs/manual/style/xsl/indexpage.xsl @@ -0,0 +1,210 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + &lf; + + &lf; + &lf; + +
    +

    + +

    &lf; + + &lf; + +
    + + &lf; + +
    -attributes\fR +String to use as attributes for \&. + +.SH "BUGS" + +.PP +There are various statically declared buffers of fixed length\&. Combined with the lazy parsing of the command line arguments, the response headers from the server and other external inputs, this might bite you\&. + +.PP +It does not implement HTTP/1\&.x fully; only accepts some 'expected' forms of responses\&. The rather heavy use of strstr(3) shows up top in profile, which might indicate a performance problem; \fIi\&.e\&.\fR, you would measure the ab performance rather than the server's\&. + diff --git a/trunk/docs/man/apachectl.8 b/trunk/docs/man/apachectl.8 new file mode 100644 index 0000000000..a4865d2bd3 --- /dev/null +++ b/trunk/docs/man/apachectl.8 @@ -0,0 +1,92 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "APACHECTL" 8 "2005-05-03" "Apache HTTP Server" "apachectl" + +.SH NAME +apachectl \- Apache HTTP Server Control Interface + +.SH "SYNOPSIS" + +.PP +When acting in pass-through mode, apachectl can take all the arguments available for the httpd binary\&. + +.PP +\fBapachectl\fR [ \fIhttpd-argument\fR ] + +.PP +When acting in SysV init mode, apachectl takes simple, one-word commands, defined below\&. + +.PP +\fBapachectl\fR \fIcommand\fR + + +.SH "SUMMARY" + +.PP +apachectl is a front end to the Apache HyperText Transfer Protocol (HTTP) server\&. It is designed to help the administrator control the functioning of the Apache httpd daemon\&. + +.PP +The apachectl script can operate in two modes\&. First, it can act as a simple front-end to the httpd command that simply sets any necessary environment variables and then invokes httpd, passing through any command line arguments\&. Second, apachectl can act as a SysV init script, taking simple one-word arguments like start, restart, and stop, and translating them into appropriate signals to httpd\&. + +.PP +If your Apache installation uses non-standard paths, you will need to edit the apachectl script to set the appropriate paths to the httpd binary\&. You can also specify any necessary httpd command line arguments\&. See the comments in the script for details\&. + +.PP +The apachectl script returns a 0 exit value on success, and >0 if an error occurs\&. For more details, view the comments in the script\&. + + +.SH "OPTIONS" + +.PP +Only the SysV init-style options are defined here\&. Other arguments are defined on the httpd manual page\&. + + +.TP +start +Start the Apache httpd daemon\&. Gives an error if it is already running\&. This is equivalent to apachectl -k start\&. +.TP +stop +Stops the Apache httpd daemon\&. This is equivalent to apachectl -k stop\&. +.TP +restart +Restarts the Apache httpd daemon\&. If the daemon is not running, it is started\&. This command automatically checks the configuration files as in configtest before initiating the restart to make sure the daemon doesn't die\&. This is equivalent to apachectl -k restart\&. +.TP +fullstatus +Displays a full status report from mod_status\&. For this to work, you need to have mod_status enabled on your server and a text-based browser such as lynx available on your system\&. The URL used to access the status report can be set by editing the STATUSURL variable in the script\&. +.TP +status +Displays a brief status report\&. Similar to the fullstatus option, except that the list of requests currently being served is omitted\&. +.TP +graceful +Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is started\&. This differs from a normal restart in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This means that if used in a log rotation script, a substantial delay may be necessary to ensure that the old log files are closed before processing them\&. This command automatically checks the configuration files as in configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. +.TP +configtest +Run a configuration file syntax test\&. It parses the configuration files and either reports Syntax Ok or detailed information about the particular syntax error\&. This is equivalent to apachectl -t\&. + +.PP +The following option was available in earlier versions but has been removed\&. + + +.TP +startssl +To start httpd with SSL support, you should edit your configuration file to include the relevant directives and then use the normal apachectl start\&. + diff --git a/trunk/docs/man/apxs.8 b/trunk/docs/man/apxs.8 new file mode 100644 index 0000000000..c234392591 --- /dev/null +++ b/trunk/docs/man/apxs.8 @@ -0,0 +1,244 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "APXS" 8 "2004-10-01" "Apache HTTP Server" "apxs" + +.SH NAME +apxs \- APache eXtenSion tool + +.SH "SYNOPSIS" + +.PP +\fBapxs\fR -\fBg\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] -\fBn\fR \fImodname\fR + +.PP +\fBapxs\fR -\fBq\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] \fIquery\fR \&.\&.\&. + +.PP +\fBapxs\fR -\fBc\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] [ -\fBo\fR \fIdsofile\fR ] [ -\fBI\fR \fIincdir\fR ] [ -\fBD\fR \fIname\fR=\fIvalue\fR ] [ -\fBL\fR \fIlibdir\fR ] [ -\fBl\fR \fIlibname\fR ] [ -\fBWc,\fR\fIcompiler-flags\fR ] [ -\fBWl,\fR\fIlinker-flags\fR ] \fIfiles\fR \&.\&.\&. + +.PP +\fBapxs\fR -\fBi\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] [ -\fBn\fR \fImodname\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-file\fR \&.\&.\&. + +.PP +\fBapxs\fR -\fBe\fR [ -\fBS\fR \fIname\fR=\fIvalue\fR ] [ -\fBn\fR \fImodname\fR ] [ -\fBa\fR ] [ -\fBA\fR ] \fIdso-file\fR \&.\&.\&. + + +.SH "SUMMARY" + +.PP +apxs is a tool for building and installing extension modules for the Apache HyperText Transfer Protocol (HTTP) server\&. This is achieved by building a dynamic shared object (DSO) from one or more source or object \fIfiles\fR which then can be loaded into the Apache server under runtime via the LoadModule directive from mod_so\&. + +.PP +So to use this extension mechanism your platform has to support the DSO feature and your Apache httpd binary has to be built with the mod_so module\&. The apxs tool automatically complains if this is not the case\&. You can check this yourself by manually running the command + +.nf + + $ httpd -l + +.fi + +.PP +The module mod_so should be part of the displayed list\&. If these requirements are fulfilled you can easily extend your Apache server's functionality by installing your own modules with the DSO mechanism by the help of this apxs tool: + +.nf + + $ apxs -i -a -c mod_foo\&.c + gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo\&.c + ld -Bshareable -o mod_foo\&.so mod_foo\&.o + cp mod_foo\&.so /path/to/apache/modules/mod_foo\&.so + chmod 755 /path/to/apache/modules/mod_foo\&.so + [activating module `foo' in /path/to/apache/etc/httpd\&.conf] + $ apachectl restart + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start + [Tue Mar 31 11:27:55 1998] [debug] mod_so\&.c(303): loaded module foo_module + /path/to/apache/sbin/apachectl restart: httpd started + $ _ + +.fi + +.PP +The arguments \fIfiles\fR can be any C source file (\&.c), a object file (\&.o) or even a library archive (\&.a)\&. The apxs tool automatically recognizes these extensions and automatically used the C source files for compilation while just using the object and archive files for the linking phase\&. But when using such pre-compiled objects make sure they are compiled for position independent code (PIC) to be able to use them for a dynamically loaded shared object\&. For instance with GCC you always just have to use -fpic\&. For other C compilers consult its manual page or at watch for the flags apxs uses to compile the object files\&. + +.PP +For more details about DSO support in Apache read the documentation of mod_so or perhaps even read the src/modules/standard/mod_so\&.c source file\&. + + +.SH "OPTIONS" + +.SS "Common Options" + + +.TP +-n \fImodname\fR +This explicitly sets the module name for the -i (install) and -g (template generation) option\&. Use this to explicitly specify the module name\&. For option -g this is required, for option -i the apxs tool tries to determine the name from the source or (as a fallback) at least by guessing it from the filename\&. + +.SS "Query Options" + + +.TP +-q +Performs a query for apxs's knowledge about certain settings\&. The \fIquery\fR parameters can be one or more of the following strings: CC, CFLAGS, CFLAGS_SHLIB, INCLUDEDIR, LD_SHLIB, LDFLAGS_SHLIB, LIBEXECDIR, LIBS_SHLIB, SBINDIR, SYSCONFDIR, TARGET\&. .PP Use this for manually determining settings\&. For instance use INC=-I`apxs -q INCLUDEDIR` .PP inside your own Makefiles if you need manual access to Apache's C header files\&. + +.SS "Configuration Options" + + +.TP +-S \fIname\fR=\fIvalue\fR +This option changes the apxs settings described above\&. + +.SS "Template Generation Options" + + +.TP +-g +This generates a subdirectory \fIname\fR (see option -n) and there two files: A sample module source file named mod_\fIname\fR\&.c which can be used as a template for creating your own modules or as a quick start for playing with the apxs mechanism\&. And a corresponding Makefile for even easier build and installing of this module\&. + +.SS "DSO Compilation Options" + + +.TP +-c +This indicates the compilation operation\&. It first compiles the C source files (\&.c) of \fIfiles\fR into corresponding object files (\&.o) and then builds a dynamically shared object in \fIdsofile\fR by linking these object files plus the remaining object files (\&.o and \&.a) of \fIfiles\fR\&. If no -o option is specified the output file is guessed from the first filename in \fIfiles\fR and thus usually defaults to mod_\fIname\fR\&.so\&. +.TP +-o \fIdsofile\fR +Explicitly specifies the filename of the created dynamically shared object\&. If not specified and the name cannot be guessed from the \fIfiles\fR list, the fallback name mod_unknown\&.so is used\&. +.TP +-D \fIname\fR=\fIvalue\fR +This option is directly passed through to the compilation command(s)\&. Use this to add your own defines to the build process\&. +.TP +-I \fIincdir\fR +This option is directly passed through to the compilation command(s)\&. Use this to add your own include directories to search to the build process\&. +.TP +-L \fIlibdir\fR +This option is directly passed through to the linker command\&. Use this to add your own library directories to search to the build process\&. +.TP +-l \fIlibname\fR +This option is directly passed through to the linker command\&. Use this to add your own libraries to search to the build process\&. +.TP +-Wc,\fIcompiler-flags\fR +This option passes \fIcompiler-flags\fR as additional flags to the libtool --mode=compile command\&. Use this to add local compiler-specific options\&. +.TP +-Wl,\fIlinker-flags\fR +This option passes \fIlinker-flags\fR as additional flags to the libtool --mode=link command\&. Use this to add local linker-specific options\&. + +.SS "DSO Installation and Configuration Options" + + +.TP +-i +This indicates the installation operation and installs one or more dynamically shared objects into the server's \fImodules\fR directory\&. +.TP +-a +This activates the module by automatically adding a corresponding LoadModule line to Apache's httpd\&.conf configuration file, or by enabling it if it already exists\&. +.TP +-A +Same as option -a but the created LoadModule directive is prefixed with a hash sign (#), \fIi\&.e\&.\fR, the module is just prepared for later activation but initially disabled\&. +.TP +-e +This indicates the editing operation, which can be used with the -a and -A options similarly to the -i operation to edit Apache's httpd\&.conf configuration file without attempting to install the module\&. + +.SH "EXAMPLES" + +.PP +Assume you have an Apache module named mod_foo\&.c available which should extend Apache's server functionality\&. To accomplish this you first have to compile the C source into a shared object suitable for loading into the Apache server under runtime via the following command: + +.nf + + $ apxs -c mod_foo\&.c + /path/to/libtool --mode=compile gcc \&.\&.\&. -c mod_foo\&.c + /path/to/libtool --mode=link gcc \&.\&.\&. -o mod_foo\&.la mod_foo\&.slo + $ _ + +.fi + +.PP +Then you have to update the Apache configuration by making sure a LoadModule directive is present to load this shared object\&. To simplify this step apxs provides an automatic way to install the shared object in its "modules" directory and updating the httpd\&.conf file accordingly\&. This can be achieved by running: + +.nf + + $ apxs -i -a mod_foo\&.la + /path/to/instdso\&.sh mod_foo\&.la /path/to/apache/modules + /path/to/libtool --mode=install cp mod_foo\&.la /path/to/apache/modules + \&.\&.\&. + chmod 755 /path/to/apache/modules/mod_foo\&.so + [activating module `foo' in /path/to/apache/conf/httpd\&.conf] + $ _ + +.fi + +.PP +This way a line named + +.nf + + LoadModule foo_module modules/mod_foo\&.so + +.fi + +.PP +is added to the configuration file if still not present\&. If you want to have this disabled per default use the -A option, \fIi\&.e\&.\fR + +.nf + + $ apxs -i -A mod_foo\&.c + +.fi + +.PP +For a quick test of the apxs mechanism you can create a sample Apache module template plus a corresponding Makefile via: + +.nf + + $ apxs -g -n foo + Creating [DIR] foo + Creating [FILE] foo/Makefile + Creating [FILE] foo/modules\&.mk + Creating [FILE] foo/mod_foo\&.c + Creating [FILE] foo/\&.deps + $ _ + +.fi + +.PP +Then you can immediately compile this sample module into a shared object and load it into the Apache server: + +.nf + + $ cd foo + $ make all reload + apxs -c mod_foo\&.c + /path/to/libtool --mode=compile gcc \&.\&.\&. -c mod_foo\&.c + /path/to/libtool --mode=link gcc \&.\&.\&. -o mod_foo\&.la mod_foo\&.slo + apxs -i -a -n "foo" mod_foo\&.la + /path/to/instdso\&.sh mod_foo\&.la /path/to/apache/modules + /path/to/libtool --mode=install cp mod_foo\&.la /path/to/apache/modules + \&.\&.\&. + chmod 755 /path/to/apache/modules/mod_foo\&.so + [activating module `foo' in /path/to/apache/conf/httpd\&.conf] + apachectl restart + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start + [Tue Mar 31 11:27:55 1998] [debug] mod_so\&.c(303): loaded module foo_module + /path/to/apache/sbin/apachectl restart: httpd started + $ _ + +.fi + diff --git a/trunk/docs/man/dbmmanage.1 b/trunk/docs/man/dbmmanage.1 new file mode 100644 index 0000000000..88e4a7057e --- /dev/null +++ b/trunk/docs/man/dbmmanage.1 @@ -0,0 +1,118 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "DBMMANAGE" 1 "2004-12-10" "Apache HTTP Server" "dbmmanage" + +.SH NAME +dbmmanage \- Manage user authentication files in DBM format + +.SH "SYNOPSIS" + +.PP +\fBdbmmanage\fR [ \fIencoding\fR ] \fIfilename\fR add|adduser|check|delete|update \fIusername\fR [ \fIencpasswd\fR [ \fIgroup\fR[,\fIgroup\fR\&.\&.\&.] [ \fIcomment\fR ] ] ] + +.PP +\fBdbmmanage\fR \fIfilename\fR view [ \fIusername\fR ] + +.PP +\fBdbmmanage\fR \fIfilename\fR import + + +.SH "SUMMARY" + +.PP +dbmmanage is used to create and update the DBM format files used to store usernames and password for basic authentication of HTTP users via mod_authn_dbm\&. Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by dbmmanage\&. This program can only be used when the usernames are stored in a DBM file\&. To use a flat-file database see htpasswd\&. + +.PP +This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the httpd manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. + + +.SH "OPTIONS" + + +.TP +\fIfilename\fR +The filename of the DBM format file\&. Usually without the extension \&.db, \&.pag, or \&.dir\&. +.TP +\fIusername\fR +The user for which the operations are performed\&. The \fIusername\fR may not contain a colon (:)\&. +.TP +\fIencpasswd\fR +This is the already encrypted password to use for the update and add commands\&. You may use a hyphen (-) if you want to get prompted for the password, but fill in the fields afterwards\&. Additionally when using the update command, a period (\&.) keeps the original password untouched\&. +.TP +\fIgroup\fR +A group, which the user is member of\&. A groupname may not contain a colon (:)\&. You may use a hyphen (-) if you don't want to assign the user to a group, but fill in the comment field\&. Additionally when using the update command, a period (\&.) keeps the original groups untouched\&. +.TP +\fIcomment\fR +This is the place for your opaque comments about the user, like realname, mailaddress or such things\&. The server will ignore this field\&. + +.SS "Encodings" + + +.TP +-d +crypt encryption (default, except on Win32, Netware) +.TP +-m +MD5 encryption (default on Win32, Netware) +.TP +-s +SHA1 encryption +.TP +-p +plaintext (\fInot recommended\fR) + +.SS "Commands" + + +.TP +add +Adds an entry for \fIusername\fR to \fIfilename\fR using the encrypted password \fIencpasswd\fR\&. dbmmanage passwords\&.dat add rbowen foKntnEF3KSXA +.TP +adduser +Asks for a password and then adds an entry for \fIusername\fR to \fIfilename\fR\&. dbmmanage passwords\&.dat adduser krietz +.TP +check +Asks for a password and then checks if \fIusername\fR is in \fIfilename\fR and if it's password matches the specified one\&. dbmmanage passwords\&.dat check rbowen +.TP +delete +Deletes the \fIusername\fR entry from \fIfilename\fR\&. dbmmanage passwords\&.dat delete rbowen +.TP +import +Reads \fIusername\fR:\fIpassword\fR entries (one per line) from STDIN and adds them to \fIfilename\fR\&. The passwords already have to be crypted\&. +.TP +update +Same as the adduser command, except that it makes sure \fIusername\fR already exists in \fIfilename\fR\&. dbmmanage passwords\&.dat update rbowen +.TP +view +Just displays the contents of the DBM file\&. If you specify a \fIusername\fR, it displays the particular record only\&. dbmmanage passwords\&.dat view + +.SH "BUGS" + +.PP +One should be aware that there are a number of different DBM file formats in existence, and with all likelihood, libraries for more than one format may exist on your system\&. The three primary examples are SDBM, 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 \fIfilename\fR is the same format that dbmmanage expects to see\&. dbmmanage currently has no way of determining what type of DBM file it is looking at\&. If used against the wrong format, 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 +dbmmanage has a list of DBM format preferences, defined by the @AnyDBM::ISA array near the beginning of the program\&. Since we prefer the Berkeley DB 2 file format, the order in which dbmmanage will look for system libraries is Berkeley DB 2, then NDBM, then GDBM and then SDBM\&. The first library found will be the library dbmmanage will attempt to use for all DBM file transactions\&. This ordering is slightly different than the standard @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 +One can usually use the file program supplied with most Unix systems to see what format a DBM file is in\&. + diff --git a/trunk/docs/man/htcacheclean.8 b/trunk/docs/man/htcacheclean.8 new file mode 100644 index 0000000000..2ef2c73120 --- /dev/null +++ b/trunk/docs/man/htcacheclean.8 @@ -0,0 +1,74 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "HTCACHECLEAN" 8 "2004-11-10" "Apache HTTP Server" "htcacheclean" + +.SH NAME +htcacheclean \- Clean up the disk cache + +.SH "SYNOPSIS" + +.PP +\fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBr\fR ] [ -\fBn\fR ] -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR + +.PP +\fBhtcacheclean\fR -\fBb\fR [ -\fBn\fR ] [ -\fBi\fR ] -\fBd\fR\fIinterval\fR -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR + + +.SH "SUMMARY" + +.PP +htcacheclean is used to keep the size of mod_disk_cache's storage within a certain limit\&. This tool can run either manually or in daemon mode\&. When running in daemon mode, it sleeps in the background and checks the cache directories at regular intervals for cached content to be removed\&. You can stop the daemon cleanly by sending it a TERM or INT signal\&. + + +.SH "OPTIONS" + + +.TP +-d\fIinterval\fR +Daemonize and repeat cache cleaning every \fIinterval\fR minutes\&. This option is mutually exclusive with the -D, -v and -r options\&. To shutdown the daemon cleanly, just send it a SIGTERM or SIGINT\&. +.TP +-D +Do a dry run and don't delete anything\&. This option is mutually exclusive with the -d option\&. +.TP +-v +Be verbose and print statistics\&. This option is mutually exclusive with the -d option\&. +.TP +-r +Clean thoroughly\&. This assumes that the Apache web server is not running (otherwise you may get garbage in the cache)\&. This option is mutually exclusive with the -d option\&. +.TP +-n +Be nice\&. This causes slower processing in favour of other processes\&. htcacheclean will sleep from time to time so that (a) the disk IO will be delayed and (b) the kernel can schedule other processes in the meantime\&. +.TP +-p\fIpath\fR +Specify \fIpath\fR as the root directory of the disk cache\&. This should be the same value as specified with the CacheRoot directive\&. +.TP +-l\fIlimit\fR +Specify \fIlimit\fR as the total disk cache size limit\&. The value is expressed in bytes by default (or attaching B to the number)\&. Attach K for Kbytes or M for MBytes\&. +.TP +-i +Be intelligent and run only when there was a modification of the disk cache\&. This option is only possible together with the -d option\&. + +.SH "EXIT STATUS" + +.PP +htcacheclean returns a zero status ("true") if all operations were successful, 1 otherwise\&. + diff --git a/trunk/docs/man/htdbm.1 b/trunk/docs/man/htdbm.1 new file mode 100644 index 0000000000..20ec67faaa --- /dev/null +++ b/trunk/docs/man/htdbm.1 @@ -0,0 +1,169 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "HTDBM" 1 "2005-03-26" "Apache HTTP Server" "htdbm" + +.SH NAME +htdbm \- Manipulate DBM password databases + +.SH "SYNOPSIS" + +.PP +\fBhtdbm\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBx\fR ] \fIfilename\fR \fIusername\fR + +.PP +\fBhtdbm\fR -\fBb\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR \fIpassword\fR + +.PP +\fBhtdbm\fR -\fBn\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIusername\fR + +.PP +\fBhtdbm\fR -\fBnb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIusername\fR \fIpassword\fR + +.PP +\fBhtdbm\fR -\fBv\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR + +.PP +\fBhtdbm\fR -\fBvb\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBt\fR ] [ -\fBv\fR ] \fIfilename\fR \fIusername\fR \fIpassword\fR + +.PP +\fBhtdbm\fR -\fBx\fR [ -\fBT\fR\fIDBTYPE\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] \fIfilename\fR \fIusername\fR + +.PP +\fBhtdbm\fR -\fBl\fR [ -\fBT\fR\fIDBTYPE\fR ] + + +.SH "SUMMARY" + +.PP +htdbm is used to manipulate the DBM format files used to store usernames and password for basic authentication of HTTP users via mod_auth_dbm\&. See the dbmmanage documentation for more information about these DBM files\&. + + +.SH "OPTIONS" + + +.TP +-b +Use batch mode; \fIi\&.e\&.\fR, get the password from the command line rather than prompting for it\&. This option should be used with extreme care, since \fBthe password is clearly visible\fR on the command line\&. +.TP +-c +Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is rewritten and truncated\&. This option cannot be combined with the -n option\&. +.TP +-n +Display the results on standard output rather than updating a database\&. This option changes the syntax of the command line, since the \fIpasswdfile\fR argument (usually the first one) is omitted\&. It cannot be combined with the -c option\&. +.TP +-m +Use MD5 encryption for passwords\&. On Windows, Netware and TPF, this is the default\&. +.TP +-d +Use crypt() encryption for passwords\&. The default on all platforms but Windows, Netware and TPF\&. Though possibly supported by htdbm on all platforms, it is not supported by the httpd server on Windows, Netware and TPF\&. +.TP +-s +Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. +.TP +-p +Use plaintext passwords\&. Though htdbm will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows, Netware and TPF\&. +.TP +-l +Print each of the usernames and comments from the database on stdout\&. +.TP +-t +Interpret the final parameter as a comment\&. When this option is specified, an additional string can be appended to the command line; this string will be stored in the "Comment" field of the database, associated with the specified username\&. +.TP +-v +Verify the username and password\&. The program will print a message indicating whether the supplied password is valid\&. If the password is invalid, the program exits with error code 3\&. +.TP +-x +Delete user\&. If the username exists in the specified DBM file, it will be deleted\&. +.TP +\fIfilename\fR +The filename of the DBM format file\&. Usually without the extension \&.db, \&.pag, or \&.dir\&. If -c is given, the DBM file is created if it does not already exist, or updated if it does exist\&. +.TP +\fIusername\fR +The username to create or update in \fIpasswdfile\fR\&. If \fIusername\fR does not exist in this file, an entry is added\&. If it does exist, the password is changed\&. +.TP +\fIpassword\fR +The plaintext password to be encrypted and stored in the DBM file\&. Used only with the -b flag\&. +.TP +-T\fIDBTYPE\fR +Type of DBM file (SDBM, GDBM, DB, or "default")\&. + +.SH "BUGS" + +.PP +One should be aware that there are a number of different DBM file formats in existence, and with all likelihood, libraries for more than one format may exist on your system\&. The three primary examples are SDBM, NDBM, GNU GDBM, and Berkeley/Sleepycat DB 2/3/4\&. Unfortunately, all these libraries use different file formats, and you must make sure that the file format used by \fIfilename\fR is the same format that htdbm expects to see\&. htdbm currently has no way of determining what type of DBM file it is looking at\&. If used against the wrong format, 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 +One can usually use the file program supplied with most Unix systems to see what format a DBM file is in\&. + +.SH "EXIT STATUS" + +.PP +htdbm returns a zero status ("true") if the username and password have been successfully added or updated in the DBM File\&. htdbm returns 1 if it encounters some problem accessing files, 2 if there was a syntax problem with the command line, 3 if the password was entered interactively and the verification entry didn't match, 4 if its operation was interrupted, 5 if a value is too long (username, filename, password, or final computed record), 6 if the username contains illegal characters (see the Restrictions section), and 7 if the file is not a valid DBM password file\&. + +.SH "EXAMPLES" + +.nf + + htdbm /usr/local/etc/apache/\&.htdbm-users jsmith + +.fi + +.PP +Adds or modifies the password for user jsmith\&. The user is prompted for the password\&. If executed on a Windows system, the password will be encrypted using the modified Apache MD5 algorithm; otherwise, the system's crypt() routine will be used\&. If the file does not exist, htdbm will do nothing except return an error\&. + +.nf + + htdbm -c /home/doe/public_html/\&.htdbm jane + +.fi + +.PP +Creates a new file and stores a record in it for user jane\&. The user is prompted for the password\&. If the file exists and cannot be read, or cannot be written, it is not altered and htdbm will display a message and return an error status\&. + +.nf + + htdbm -mb /usr/web/\&.htdbm-all jones Pwd4Steve + +.fi + +.PP +Encrypts the password from the command line (Pwd4Steve) using the MD5 algorithm, and stores it in the specified file\&. + +.SH "SECURITY CONSIDERATIONS" + +.PP +Web password files such as those managed by htdbm should \fInot\fR be within the Web server's URI space -- that is, they should not be fetchable with a browser\&. + +.PP +The use of the -b option is discouraged, since when it is used the unencrypted password appears on the command line\&. + +.SH "RESTRICTIONS" + +.PP +On the Windows and MPE platforms, passwords encrypted with htdbm are limited to no more than 255 characters in length\&. Longer passwords will be truncated to 255 characters\&. + +.PP +The MD5 algorithm used by htdbm is specific to the Apache software; passwords encrypted using it will not be usable with other Web servers\&. + +.PP +Usernames are limited to 255 bytes and may not include the character :\&. + diff --git a/trunk/docs/man/htdigest.1 b/trunk/docs/man/htdigest.1 new file mode 100644 index 0000000000..fd6598f889 --- /dev/null +++ b/trunk/docs/man/htdigest.1 @@ -0,0 +1,57 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "HTDIGEST" 1 "2003-11-25" "Apache HTTP Server" "htdigest" + +.SH NAME +htdigest \- manage user files for digest authentication + +.SH "SYNOPSIS" + +.PP +\fBhtdigest\fR [ -\fBc\fR ] \fIpasswdfile\fR \fIrealm\fR \fIusername\fR + + +.SH "SUMMARY" + +.PP +htdigest is used to create and update the flat-files used to store usernames, realm and password for digest authentication of HTTP users\&. Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by htdigest\&. + +.PP +This manual page only lists the command line arguments\&. For details of the directives necessary to configure digest authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. + + +.SH "OPTIONS" + + +.TP +-c +Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is deleted first\&. +.TP +\fIpasswdfile\fR +Name of the file to contain the username, realm and password\&. If -c is given, this file is created if it does not already exist, or deleted and recreated if it does exist\&. +.TP +\fIrealm\fR +The realm name to which the user name belongs\&. +.TP +\fIusername\fR +The user name to create or update in \fIpasswdfile\fR\&. If \fIusername\fR does not exist is this file, an entry is added\&. If it does exist, the password is changed\&. + diff --git a/trunk/docs/man/htpasswd.1 b/trunk/docs/man/htpasswd.1 new file mode 100644 index 0000000000..6ecfb52d6e --- /dev/null +++ b/trunk/docs/man/htpasswd.1 @@ -0,0 +1,146 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "HTPASSWD" 1 "2003-11-25" "Apache HTTP Server" "htpasswd" + +.SH NAME +htpasswd \- Manage user files for basic authentication + +.SH "SYNOPSIS" + +.PP +\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBm\fR ] [ -\fBD\fR ] \fIpasswdfile\fR \fIusername\fR + +.PP +\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBd\fR | -\fBp\fR | -\fBs\fR ] [ -\fBD\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR + +.PP +\fBhtpasswd\fR -\fBn\fR [ -\fBm\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] \fIusername\fR + +.PP +\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] \fIusername\fR \fIpassword\fR + + +.SH "SUMMARY" + +.PP +htpasswd is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users\&. If htpasswd cannot access a file, such as not being able to write to the output file or not being able to read the file in order to update it, it returns an error status and makes no changes\&. + +.PP +Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by htpasswd\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage\&. + +.PP +htpasswd encrypts passwords using either a version of MD5 modified for Apache, or the system's crypt() routine\&. Files managed by htpasswd may contain both types of passwords; some user records may have MD5-encrypted passwords while others in the same file may have passwords encrypted with crypt()\&. + +.PP +This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. + + +.SH "OPTIONS" + + +.TP +-b +Use batch mode; \fIi\&.e\&.\fR, get the password from the command line rather than prompting for it\&. This option should be used with extreme care, since \fBthe password is clearly visible\fR on the command line\&. +.TP +-c +Create the \fIpasswdfile\fR\&. If \fIpasswdfile\fR already exists, it is rewritten and truncated\&. This option cannot be combined with the -n option\&. +.TP +-n +Display the results on standard output rather than updating a file\&. This is useful for generating password records acceptable to Apache for inclusion in non-text data stores\&. This option changes the syntax of the command line, since the \fIpasswdfile\fR argument (usually the first one) is omitted\&. It cannot be combined with the -c option\&. +.TP +-m +Use MD5 encryption for passwords\&. On Windows, Netware and TPF, this is the default\&. +.TP +-d +Use crypt() encryption for passwords\&. The default on all platforms but Windows, Netware and TPF\&. Though possibly supported by htpasswd on all platforms, it is not supported by the httpd server on Windows, Netware and TPF\&. +.TP +-s +Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. +.TP +-p +Use plaintext passwords\&. Though htpasswd will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows, Netware and TPF\&. +.TP +-D +Delete user\&. If the username exists in the specified htpasswd file, it will be deleted\&. +.TP +\fIpasswdfile\fR +Name of the file to contain the user name and password\&. If -c is given, this file is created if it does not already exist, or rewritten and truncated if it does exist\&. +.TP +\fIusername\fR +The username to create or update in \fIpasswdfile\fR\&. If \fIusername\fR does not exist in this file, an entry is added\&. If it does exist, the password is changed\&. +.TP +\fIpassword\fR +The plaintext password to be encrypted and stored in the file\&. Only used with the -b flag\&. + +.SH "EXIT STATUS" + +.PP +htpasswd returns a zero status ("true") if the username and password have been successfully added or updated in the \fIpasswdfile\fR\&. htpasswd returns 1 if it encounters some problem accessing files, 2 if there was a syntax problem with the command line, 3 if the password was entered interactively and the verification entry didn't match, 4 if its operation was interrupted, 5 if a value is too long (username, filename, password, or final computed record), 6 if the username contains illegal characters (see the Restrictions section), and 7 if the file is not a valid password file\&. + +.SH "EXAMPLES" + +.nf + + htpasswd /usr/local/etc/apache/\&.htpasswd-users jsmith + +.fi + +.PP +Adds or modifies the password for user jsmith\&. The user is prompted for the password\&. If executed on a Windows system, the password will be encrypted using the modified Apache MD5 algorithm; otherwise, the system's crypt() routine will be used\&. If the file does not exist, htpasswd will do nothing except return an error\&. + +.nf + + htpasswd -c /home/doe/public_html/\&.htpasswd jane + +.fi + +.PP +Creates a new file and stores a record in it for user jane\&. The user is prompted for the password\&. If the file exists and cannot be read, or cannot be written, it is not altered and htpasswd will display a message and return an error status\&. + +.nf + + htpasswd -mb /usr/web/\&.htpasswd-all jones Pwd4Steve + +.fi + +.PP +Encrypts the password from the command line (Pwd4Steve) using the MD5 algorithm, and stores it in the specified file\&. + +.SH "SECURITY CONSIDERATIONS" + +.PP +Web password files such as those managed by htpasswd should \fInot\fR be within the Web server's URI space -- that is, they should not be fetchable with a browser\&. + +.PP +The use of the -b option is discouraged, since when it is used the unencrypted password appears on the command line\&. + +.SH "RESTRICTIONS" + +.PP +On the Windows and MPE platforms, passwords encrypted with htpasswd are limited to no more than 255 characters in length\&. Longer passwords will be truncated to 255 characters\&. + +.PP +The MD5 algorithm used by htpasswd is specific to the Apache software; passwords encrypted using it will not be usable with other Web servers\&. + +.PP +Usernames are limited to 255 bytes and may not include the character :\&. + diff --git a/trunk/docs/man/httpd.8 b/trunk/docs/man/httpd.8 new file mode 100644 index 0000000000..8c24dec788 --- /dev/null +++ b/trunk/docs/man/httpd.8 @@ -0,0 +1,119 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "HTTPD" 8 "2004-07-10" "Apache HTTP Server" "httpd" + +.SH NAME +httpd \- Apache Hypertext Transfer Protocol Server + +.SH "SYNOPSIS" + +.PP +\fBhttpd\fR [ -\fBd\fR \fIserverroot\fR ] [ -\fBf\fR \fIconfig\fR ] [ -\fBC\fR \fIdirective\fR ] [ -\fBc\fR \fIdirective\fR ] [ -\fBD\fR \fIparameter\fR ] [ -\fBe\fR \fIlevel\fR ] [ -\fBE\fR \fIfile\fR ] [ \fB-k\fR start|restart|graceful|stop ] [ -\fBR\fR \fIdirectory\fR ] [ -\fBh\fR ] [ -\fBl\fR ] [ -\fBL\fR ] [ -\fBS\fR ] [ -\fBt\fR ] [ -\fBv\fR ] [ -\fBV\fR ] [ -\fBX\fR ] [ -\fBM\fR ] + +.PP +On Windows systems, the following additional arguments are available: + +.PP +\fBhttpd\fR [ -\fBk\fR install|config|uninstall ] [ -\fBn\fR \fIname\fR ] [ -\fBw\fR ] + + +.SH "SUMMARY" + +.PP +httpd is the Apache HyperText Transfer Protocol (HTTP) server program\&. It is designed to be run as a standalone daemon process\&. When used like this it will create a pool of child processes or threads to handle requests\&. + +.PP +In general, httpd should not be invoked directly, but rather should be invoked via apachectl on Unix-based systems or as a service on Windows NT, 2000 and XP and as a console application on Windows 9x and ME\&. + + +.SH "OPTIONS" + + +.TP +-d \fIserverroot\fR +Set the initial value for the ServerRoot directive to \fIserverroot\fR\&. This can be overridden by the ServerRoot directive in the configuration file\&. The default is /usr/local/apache2\&. +.TP +-f \fIconfig\fR +Uses the directives in the file \fIconfig\fR on startup\&. If \fIconfig\fR does not begin with a /, then it is taken to be a path relative to the ServerRoot\&. The default is conf/httpd\&.conf\&. +.TP +-k start|restart|graceful|stop +Signals httpd to start, restart, or stop\&. See Stopping Apache for more information\&. +.TP +-C \fIdirective\fR +Process the configuration \fIdirective\fR before reading config files\&. +.TP +-c \fIdirective\fR +Process the configuration \fIdirective\fR after reading config files\&. +.TP +-D \fIparameter\fR +Sets a configuration \fIparameter \fRwhich can be used with sections in the configuration files to conditionally skip or process commands at server startup and restart\&. +.TP +-e \fIlevel\fR +Sets the LogLevel to \fIlevel\fR during server startup\&. This is useful for temporarily increasing the verbosity of the error messages to find problems during startup\&. +.TP +-E \fIfile\fR +Send error messages during server startup to \fIfile\fR\&. +.TP +-R \fIdirectory\fR +When the server is compiled using the SHARED_CORE rule, this specifies the \fIdirectory\fR for the shared object files\&. +.TP +-h +Output a short summary of available command line options\&. +.TP +-l +Output a list of modules compiled into the server\&. This will \fBnot\fR list dynamically loaded modules included using the LoadModule directive\&. +.TP +-L +Output a list of directives together with expected arguments and places where the directive is valid\&. +.TP +-M +Dump a list of loaded Static and Shared Modules\&. +.TP +-S +Show the settings as parsed from the config file (currently only shows the virtualhost settings)\&. +.TP +-t +Run syntax tests for configuration files only\&. The program immediately exits after these syntax parsing tests with either a return code of 0 (Syntax OK) or return code not equal to 0 (Syntax Error)\&. If -D \fIDUMP\fR_\fIVHOSTS \fRis also set, details of the virtual host configuration will be printed\&. If -D \fIDUMP\fR_\fIMODULES \fR is set, all loaded modules will be printed\&. +.TP +-v +Print the version of httpd, and then exit\&. +.TP +-V +Print the version and build parameters of httpd, and then exit\&. +.TP +-X +Run httpd in debug mode\&. Only one worker will be started and the server will not detach from the console\&. + +.PP +The following arguments are available only on the Windows platform: + + +.TP +-k install|config|uninstall +Install Apache as a Windows NT service; change startup options for the Apache service; and uninstall the Apache service\&. +.TP +-n \fIname\fR +The \fIname\fR of the Apache service to signal\&. +.TP +-w +Keep the console window open on error so that the error message can be read\&. + diff --git a/trunk/docs/man/logresolve.8 b/trunk/docs/man/logresolve.8 new file mode 100644 index 0000000000..3efd062fcf --- /dev/null +++ b/trunk/docs/man/logresolve.8 @@ -0,0 +1,51 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "LOGRESOLVE" 8 "2003-11-25" "Apache HTTP Server" "logresolve" + +.SH NAME +logresolve \- Resolve IP-addresses to hostnames in Apache log files + +.SH "SYNOPSIS" + +.PP +\fBlogresolve\fR [ -\fBs\fR \fIfilename\fR ] [ -\fBc\fR ] < \fIaccess_log\fR > \fIaccess_log\&.new\fR + + +.SH "SUMMARY" + +.PP +logresolve is a post-processing program to resolve IP-addresses in Apache's access logfiles\&. To minimize impact on your nameserver, logresolve has its very own internal hash-table cache\&. This means that each IP number will only be looked up the first time it is found in the log file\&. + +.PP +Takes an Apache log file on standard input\&. The IP addresses must be the first thing on each line and must be seperated from the remainder of the line by a space\&. + + +.SH "OPTIONS" + + +.TP +-s \fIfilename\fR +Specifies a filename to record statistics\&. +.TP +-c +This causes logresolve to apply some DNS checks: after finding the hostname from the IP address, it looks up the IP addresses for the hostname and checks that one of these matches the original address\&. + diff --git a/trunk/docs/man/rotatelogs.8 b/trunk/docs/man/rotatelogs.8 new file mode 100644 index 0000000000..a8875f751f --- /dev/null +++ b/trunk/docs/man/rotatelogs.8 @@ -0,0 +1,133 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "ROTATELOGS" 8 "2004-06-20" "Apache HTTP Server" "rotatelogs" + +.SH NAME +rotatelogs \- Piped logging program to rotate Apache logs + +.SH "SYNOPSIS" + +.PP +\fBrotatelogs\fR [ -\fBl\fR ] \fIlogfile\fR [ \fIrotationtime\fR [ \fIoffset\fR ]] | [ \fIfilesize\fRM ] + + +.SH "SUMMARY" + +.PP +rotatelogs is a simple program for use in conjunction with Apache's piped logfile feature\&. For example: + +.nf + + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common + +.fi + +.PP +This creates the files /var/logs/logfile\&.nnnn where nnnn is the system time at which the log nominally starts (this time will always be a multiple of the rotation time, so you can synchronize cron scripts with it)\&. At the end of each rotation time (here after 24 hours) a new log is started\&. + +.nf + + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common + +.fi + +.PP +This configuration will rotate the logfile whenever it reaches a size of 5 megabytes\&. + +.nf + + ErrorLog "|bin/rotatelogs /var/logs/errorlog\&.%Y-%m-%d-%H_%M_%S 5M" + +.fi + +.PP +This configuration will rotate the error logfile whenever it reaches a size of 5 megabytes, and the suffix to the logfile name will be created of the form errorlog\&.YYYY-mm-dd-HH_MM_SS\&. + + +.SH "OPTIONS" + + +.TP +-l +Causes the use of local time rather than GMT as the base for the interval\&. Note that using -l in an environment which changes the GMT offset (such as for BST or DST) can lead to unpredictable results! +.TP +\fIlogfile\fR +The path plus basename of the logfile\&. If \fIlogfile\fR includes any '%' characters, it is treated as a format string for strftime(3)\&. Otherwise, the suffix \fI\&.nnnnnnnnnn\fR is automatically added and is the time in seconds\&. Both formats compute the start time from the beginning of the current period\&. +.TP +\fIrotationtime\fR +The time between log file rotations in seconds\&. +.TP +\fIoffset\fR +The number of minutes offset from UTC\&. If omitted, zero is assumed and UTC is used\&. For example, to use local time in the zone UTC -5 hours, specify a value of -300 for this argument\&. +.TP +\fIfilesize\fRM +The maximum file size in megabytes followed by the letter M to specify size rather than time\&. Use this parameter in place of both rotationtime and offset\&. + +.SH "PORTABILITY" + +.PP +The following logfile format string substitutions should be supported by all strftime(3) implementations, see the strftime(3) man page for library-specific extensions\&. + +.Ip "\(bu \s-1%A\s0 \- full weekday name (localized) + +.Ip "\(bu \s-1%a\s0 \- 3-character weekday name (localized) + +.Ip "\(bu \s-1%B\s0 \- full month name (localized) + +.Ip "\(bu \s-1%b\s0 \- 3-character month name (localized) + +.Ip "\(bu \s-1%c\s0 \- date and time (localized) + +.Ip "\(bu \s-1%d\s0 \- 2-digit day of month + +.Ip "\(bu \s-1%H\s0 \- 2-digit hour (24 hour clock) + +.Ip "\(bu \s-1%I\s0 \- 2-digit hour (12 hour clock) + +.Ip "\(bu \s-1%j\s0 \- 3-digit day of year + +.Ip "\(bu \s-1%M\s0 \- 2-digit minute + +.Ip "\(bu \s-1%m\s0 \- 2-digit month + +.Ip "\(bu \s-1%p\s0 \- am/pm of 12 hour clock (localized) + +.Ip "\(bu \s-1%S\s0 \- 2-digit second + +.Ip "\(bu \s-1%U\s0 \- 2-digit week of year (Sunday first day of week) + +.Ip "\(bu \s-1%W\s0 \- 2-digit week of year (Monday first day of week) + +.Ip "\(bu \s-1%w\s0 \- 1-digit weekday (Sunday first day of week) + +.Ip "\(bu \s-1%X\s0 \- time (localized) + +.Ip "\(bu \s-1%x\s0 \- date (localized) + +.Ip "\(bu \s-1%Y\s0 \- 4-digit year + +.Ip "\(bu \s-1%y\s0 \- 2-digit year + +.Ip "\(bu \s-1%Z\s0 \- time zone name + +.Ip "\(bu \s-1%%\s0 \- literal `%' + diff --git a/trunk/docs/man/suexec.8 b/trunk/docs/man/suexec.8 new file mode 100644 index 0000000000..bcc4e7abea --- /dev/null +++ b/trunk/docs/man/suexec.8 @@ -0,0 +1,48 @@ +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.\" DO NOT EDIT! Generated from XML source. +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "SUEXEC" 8 "2003-12-02" "Apache HTTP Server" "suexec" + +.SH NAME +suexec \- Switch user before executing external programs + +.SH "SYNOPSIS" + +.PP +\fBsuexec\fR -\fBV\fR + + +.SH "SUMMARY" + +.PP +suexec is used by the Apache HTTP Server to switch to another user before executing CGI programs\&. In order to achieve this, it must run as root\&. Since the HTTP daemon normally doesn't run as root, the suexec executable needs the setuid bit set and must be owned by root\&. It should never be writable for any other person than root\&. + +.PP +For further information about the concepts and and the security model of suexec please refer to the suexec documentation (http://httpd\&.apache\&.org/docs-2\&.1/suexec\&.html)\&. + + +.SH "OPTIONS" + + +.TP +-V +If you are root, this option displays the compile options of suexec\&. For security reasons all configuration options are changeable only at compile time\&. + diff --git a/trunk/docs/manual/LICENSE b/trunk/docs/manual/LICENSE new file mode 100644 index 0000000000..57bc88a15a --- /dev/null +++ b/trunk/docs/manual/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/trunk/docs/manual/bind.html b/trunk/docs/manual/bind.html new file mode 100644 index 0000000000..c2af6387d2 --- /dev/null +++ b/trunk/docs/manual/bind.html @@ -0,0 +1,19 @@ +URI: bind.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: bind.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: bind.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: bind.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: bind.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/bind.html.de b/trunk/docs/manual/bind.html.de new file mode 100644 index 0000000000..da8bfeda7a --- /dev/null +++ b/trunk/docs/manual/bind.html.de @@ -0,0 +1,164 @@ + + + +Anbindung - Apache HTTP Server + + + + + +
    <-
    +

    Anbindung

    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko 

    +
    + +

    Konfiguration der vom Apache verwendeten Adressen und Ports.

    +
    + +
    top
    +
    +

    Überblick

    + + + + +

    Beim Start bindet sich der Apache an bestimmte Adressen und Ports + der lokalen Maschine und wartet auf eingehende Anfragen. + Standardmäßig lauscht er an allen Adressen des Systems. + Es muss ihm jedoch mitgeteilt werden, an bestimmten Ports zu lauschen + oder nur an ausgewählten Adressen, bzw. einer Kombination aus + beidem. Dies wird oft mit der Funktionalität virtueller Hosts + kombiniert, die bestimmt, wie der Apache auf verschiedene IP-Adressen, + Hostnamen und Ports reagiert.

    + +

    Die Direktive Listen + weist den Server an, eingehende Anfragen nur an bestimmten Ports oder + Adress/Port-Kombinationen zu akzeptieren. Wenn bei der Listen-Direktive nur eine Portnummer + angegeben wird, dann lauscht der Server auf allen Netzwerkinterfaces an + dem angegebenen Port. Ist auch eine IP-Adresse angegeben, dann lauscht der + Server an der angegebenen Schnittstelle auf dem angegebenen Port. Es + können mehrere Listen-Anweisungen verwendet werden, um + eine Reihe von Adressen und Ports anzugeben, an denen gelauscht werden + soll. Der Server wird dann auf Anfragen an jeder der abgehörten + Adressen und Ports antworten.

    + +

    Um beispielsweise den Server zu veranlassen, sowohl an Port 80, als + auch an Port 8000 Verbindungen zu akzeptieren, geben Sie an:

    + +

    + Listen 80
    + Listen 8000 +

    + +

    Um den Server Verbindungen an zwei bestimmten + Netzwerkinterfaces und Ports zu akzeptieren zu lassen, geben Sie an:

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6-Adressen müssen wie im folgenden Beispiel in eckigen + Klammern angegeben werden:

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    +
    top
    +
    +

    Betrachtung von IPv6-Besonderheiten

    + + +

    Eine wachsende Anzahl von Plattformen implementiert IPv6. Die APR + unterstützt IPv6 auf den meisten dieser Plattformen und + ermöglicht dem Apache, IPv6-Sockets zu verwenden und Anfragen zu + behandeln, die über IPv6 gesendet wurden.

    + +

    Für Apache-Administratoren kommt erschwerend die Frage hinzu, ob + IPv6-Sockets sowohl IPv4- als auch IPv6-Verbindungen + handhaben können. Zum Betrieb von IPv4-Verbindungen an + IPv6-Sockets werden auf IPv6 abgebildete IPv4-Adressen + (Anm.d.Ü.: so genannete IPv4-gemappte IPv6-Adressen) + verwendet, welche standardmäßig auf den meisten Plattformen + erlaubt sind. Unter FreeBSD, NetBSD und OpenBSD jedoch sind sie + standardmäßig deaktiviert, um den Systemgrundsätzen dieser + Plattformen zu entsprechen. Doch selbst auf Systemen, wo dies + standardmäßig dekativiert ist, kann dieses Verhalten mit einem + speziellen configure-Parameter für den Apache + geändert werden.

    + +

    Auf der anderen Seite ist die Verwendung von gemappten Adressen bei + einigen Plattformen wie Linux und True64 der einzige + Weg, sowohl IPv4 wie auch IPv6 zu verwenden. Wenn Sie möchten, dass + der Apache IPv4- und IPv6-Verbindungen mit einem Minimum an Sockets + behandelt, was die Verwendung von IPv4-gemappten IPv6-Adressen + erfordert, dann müssen Sie die configure-Option --enable-v4-mapped angeben.

    + +

    --enable-v4-mapped ist die Voreinstellung auf allen + Plattformen außer FreeBSD, NetBSD und OpenBSD, so dass Ihr Apache + wahrscheinlich so übersetzt wurde.

    + +

    Geben Sie wie in dem folgenden Beispiel bei allen Listen-Anweisungen eine IPv4-Adresse + an, wenn Sie möchten, dass Ihr Apache lediglich IPv4-Adressen + behandelt, unabhängig davon, was Ihre Plattform und die APR + unterstützen:

    + +

    + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +

    + +

    Wenn Sie möchten, dass der Apache IPv4- und IPv6-Verbindungen an + separaten Sockets behandelt (d.h. IPv4-gemappte Adressen deaktiviert + werden sollen) und Ihre Plattform es unterstützt, dann müssen + Sie die configure-Option + --disable-v4-mapped angeben. + Unter FreeBSD, NetBSD und OpenBSD ist --disable-v4-mapped + voreingestellt.

    +
    top
    +
    +

    Das Zusammenspiel mit virtuellen Hosts

    + + +

    Listen implementiert keine + virtuellen Hosts. Es teilt dem Hauptserver lediglich mit, an welchen + Adressen und Ports er zu lauschen hat. Werden keine <VirtualHost>-Container + verwendet, verhält sich der Server bei allen angenommenen Anfragen + gleich. <VirtualHost>-Abschnitte können jedoch + dazu verwendet werden, ein unterschiedliches Verhalten für eine oder + mehrere Adressen und Ports festzulegen. Um einen virtuellen Host + einzurichten, muss dem Server zunächst mitgeteilt werden, an den + betreffenden Adressen und Ports zu lauschen. Dann sollte ein <VirtualHost>-Abschnitt für + eine bestimmte Adresse und einen Port erstellt werden, um das Verhalten + dieses virtuellen Hosts festzulegen. Beachten Sie bitte, dass auf einen + <VirtualHost> nicht + zugegriffen werden kann, wenn er für eine Adresse und einen Port + eingerichtet wurde, an dem der Server nicht lauscht.

    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/bind.html.en b/trunk/docs/manual/bind.html.en new file mode 100644 index 0000000000..daea12dc76 --- /dev/null +++ b/trunk/docs/manual/bind.html.en @@ -0,0 +1,160 @@ + + + +Binding - Apache HTTP Server + + + + + +
    <-
    +

    Binding

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko 

    +
    + +

    Configuring Apache to listen on specific addresses and ports.

    +
    + +
    top
    +
    +

    Overview

    + + + + + +

    When Apache starts, it binds to some port and address on + the local machine and waits for incoming requests. By default, + it listens to all addresses on the machine. However, it needs to + be told to listen on specific ports, or to listen on only selected + addresses, or a combination. This is often combined with the + Virtual Host feature which determines how Apache responds to + different IP addresses, hostnames and ports.

    + +

    The Listen + directive tells the server to accept + incoming requests only on the specified port or + address-and-port combinations. If only a port number is + specified in the Listen + directive, the server + listens to the given port on all interfaces. If an IP address + is given as well as a port, the server will listen on the given + port and interface. Multiple Listen directives may be used to + specify a number of addresses and ports to listen on. The + server will respond to requests from any of the listed + addresses and ports.

    + +

    For example, to make the server accept connections on both + port 80 and port 8000, use:

    + +

    + Listen 80
    + Listen 8000 +

    + +

    To make the server accept connections on two specified + interfaces and port numbers, use

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6 addresses must be surrounded in square brackets, as in the + following example:

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    +
    top
    +
    +

    Special IPv6 Considerations

    + + +

    A growing number of platforms implement IPv6, and APR supports + IPv6 on most of these platforms, allowing Apache to allocate IPv6 + sockets and handle requests which were sent over IPv6.

    + +

    One complicating factor for Apache administrators is whether or + not an IPv6 socket can handle both IPv4 connections and IPv6 + connections. Handling IPv4 connections with an IPv6 socket uses + IPv4-mapped IPv6 addresses, which are allowed by default on most + platforms but are disallowed by default on FreeBSD, NetBSD, and + OpenBSD in order to match the system-wide policy on those + platforms. But even on systems where it is disallowed by default, a + special configure parameter can change this behavior + for Apache.

    + +

    On the other hand, on some platforms such as Linux and Tru64 the + only way to handle both IPv6 and IPv4 is to use + mapped addresses. If you want Apache to handle IPv4 and IPv6 connections + with a minimum of sockets, which requires using IPv4-mapped IPv6 + addresses, specify the --enable-v4-mapped configure option.

    + +

    --enable-v4-mapped is the default on all platforms but + FreeBSD, NetBSD, and OpenBSD, so this is probably how your Apache was + built.

    + +

    If you want Apache to handle IPv4 connections only, regardless of + what your platform and APR will support, specify an IPv4 address on all + Listen directives, as in the + following examples:

    + +

    + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +

    + +

    If your platform supports it and you want Apache to handle IPv4 and + IPv6 connections on separate sockets (i.e., to disable IPv4-mapped + addresses), specify the --disable-v4-mapped configure option. --disable-v4-mapped is the + default on FreeBSD, NetBSD, and OpenBSD.

    +
    top
    +
    +

    How This Works With Virtual Hosts

    + + +

    Listen does not implement + Virtual Hosts. It only tells the + main server what addresses and ports to listen to. If no + <VirtualHost> + directives are used, the server will behave + the same for all accepted requests. However, + <VirtualHost> + can be used to specify a different behavior + for one or more of the addresses and ports. To implement a + VirtualHost, the server must first be told to listen to the + address and port to be used. Then a + <VirtualHost> section + should be created for a specified address and port to set the + behavior of this virtual host. Note that if the + <VirtualHost> + is set for an address and port that the + server is not listening to, it cannot be accessed.

    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/bind.html.fr b/trunk/docs/manual/bind.html.fr new file mode 100644 index 0000000000..58ad0876ec --- /dev/null +++ b/trunk/docs/manual/bind.html.fr @@ -0,0 +1,197 @@ + + + +Liaison - Serveur Apache HTTP + + + + + +
    <-
    +

    Liaison

    +
    +

    Langues Disponibles:  de  | + en  | + fr  | + ja  | + ko 

    +
    +
    Cette traduction peut être périmée. Verifiez la version + Anglaise pour les changements récents.
    + +

    Configuration des adresses et ports sur lesquels Apache écoute.

    +
    + +
    top
    +
    +

    Informations générales

    + + + + + +

    Au moment de son démarrage, Apache se lie à un port et à une + adresse IP sur la machine locale et se met en attente de requètes. + Par défaut, Apache écoute sur toutes les adresses de la machine. + Apache accepte d'écouter sur un ou plusieurs ports spécifiques, + sur une seule ou plusieurs adresses, ou encore sur une combinaison port-adresse. + Il est fréquent d'utiliser ces possibilités avec les fonctionnalités + de Serveurs Virtuels, qui permettent de faire répondre le serveur de + manière différente en fonction de l'adresse IP, du nom d'hôte ou + du port.

    + +

    Le serveur interprète la directive + Listen + en acceptant les requètes seulement sur le port ou la combinaison + adresse IP + port passée en argument. Dans le cas où seul un port + est spécifié avec la directive + Listen, + le serveur se met à l'écoute sur le port spécifié, sur toutes + les interfaces et adresses de la machine. Si une adresse IP est + spécifiée en plus du port, le serveur n'écoute que sur l'adresse + et le port spécifié. Il est possible de configurer plusieurs adresses + et ports avec la directives + Listen + pour écoute par le serveur. Le serveur répond aux requètes faites + à toutes les adresses et ports énumérés.

    + + +

    Par exemple, pour que le serveur accepte les connexions sur + les ports 80 et 8000, spécifiez :

    + +

    + Listen 80
    + Listen 8000 +

    + +

    Pour qu'Apache accepte les connexions sur deux combinaisons + adresses + ports, spécifiez :

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    Les adresses IPv6 sont acceptées, pourvu qu'elles soient spécifiées + entre crochets de la façon suivante :

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    +
    top
    +
    +

    Considérations Spéciales avec IPv6

    + + +

    De plus en plus de plate-formes implémentent IPv6. APR + supporte IPv6 sur la plupart d'entre elles, si bien qu'Apache + peut assigner des interfaces de connexions IPv6 et répondre aux + requètes utilisant IPv6.

    + +

    Une complication possible pour les administrateurs Apache est de + savoir si une interface de connexion IPv6 peut répondre aux deux types de + connexions IPv4 et IPv6. + Manipuler les connexions IPv4 avec une interface de connexion IPv6 + suppose l'utilisation d'adresses IPv6 mappées en IPv4, ce qui est + le cas par defaut sur la plupart des plate-formes, à l'exeption de FreeBSD, + NetBSD, et OpenBSD, cela en raison des politiques systèmes de ces plate-formes. + Mème sur des systèmes où cette fonctionnalité n'est pas activée par + défaut, une option de compilation permet de changer ce + fonctionnement pour Apache.

    +

    Pour qu'Apache puisse gérer à la fois les connexions IPv4 et IPv6 + avec un minimum d'interfaces de connexions, il faut permettre l'utilisation + des adresses + IPv6 mappées en IPv4, ce qui est possible en spécifiant l'option + + de compilation --enable-v4-mapped et en utilisant la + directive Listen + comme suit:

    + +

    + Listen 80 +

    + +

    Si --enable-v4-mapped a été spécifié à la compilation, + les directives Listen + de la configuration par défaut sont de la forme ci-dessus. + --enable-v4-mapped est l'option de compilation + par défaut sur toutes les plate-formes, sauf FreeBSD, NetBSD, et + OpenBSD.

    + + +

    Pour qu'Apache ne manipule que les connexions IPv4, en ignorant l'éventuel + support IPv6 de la plate-forme ou d'APR, une adresse IPv4 peut être + spécifié pour toutes les directives + Listen, + comme dans les exemples suivantss:

    + +

    + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +

    + +

    Pour qu'Apache manipule les connexions IPv4 et IPv6 sur des interfaces + différentes (c'est-à-dire, pour ne pas accepter les addresse IPv6 mappées + en IPv4), spécifier l'option de compilation --disable-v4-mapped + et utiliser des directives Listen + spécifiques telles que:

    +

    + Listen [::]:80
    + Listen 0.0.0.0:80 +

    + +

    Avec --disable-v4-mapped, la directive + Listen à l'intérieur + du fichier de configuration par défaut créé par Apache utilise la forme + ci-dessus. + --disable-v4-mapped est l'option de compilation par défaut sous + FreeBSD, NetBSD, et OpenBSD.

    +
    top
    +
    +

    Faire fonctionner tout ceci avec les Serveurs Virtuels

    + + +

    Listen + n'implémente aucun Serveur Virtuel. Cette directive sert simplement + à informer le serveur principal sur quels addresses et ports écouter. + Dans le cas où aucune section + <VirtualHost> + n'est utilisée, le serveur répondra de la mème manière pour toutes + les requètes qu'il acceptera. Cependant des sections + <VirtualHost> + peuvent être utilisées pour qu'Apache réagisse de façon différente à + une requète selon l'adresse ou le port. Avant d'implémenter + un Serveur Virtuel au moyen de la directive + <VirtualHost>, la directive + Listen + doit tre utilisée pour que le serveur écoute sur l'adresse + ou le port spécifié. Une section + <VirtualHost> + peut alors être utilisée pour définir la réaction du Serveur Virtuel pour une + adresse et un port spécifique. À noter que si un Serveur Virtuel est + positionné au moyen de la directive + <VirtualHost> + sur une adresse et un port sur lesquels le serveur n'est pas à l'écoute, + le Serveur Virtuel ne sera pas accessible.

    +
    +
    +

    Langues Disponibles:  de  | + en  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/bind.html.ja.euc-jp b/trunk/docs/manual/bind.html.ja.euc-jp new file mode 100644 index 0000000000..a24ca03f36 --- /dev/null +++ b/trunk/docs/manual/bind.html.ja.euc-jp @@ -0,0 +1,175 @@ + + + +¥Ð¥¤¥ó¥É - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Ð¥¤¥ó¥É

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko 

    +
    + +

    Apache ¤¬»ÈÍѤ¹¤ë¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÎÀßÄê¤ò¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ³µÍ×

    + + + + + +

    Apache ¤Ïµ¯Æ°»þ¤Ë¡¢¥í¡¼¥«¥ë¥Þ¥·¥ó¤Î¤¢¤ë¥Ý¡¼¥È¤¢¤è¤Ó¥¢¥É¥ì¥¹ + ¤ËÂФ·¤ÆÀܳ¤·¡¢¥ê¥¯¥¨¥¹¥È¤¬Íè¤ë¤Î¤òÂÔ¤Á¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥Þ¥·¥ó¤Î¤¹¤Ù¤Æ¤Î¥¢¥É¥ì¥¹¤ËÂФ·¤Æ listen ¤·¤Þ¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢ÆÃÄê¤Î¥Ý¡¼¥È¤«¡¢ÆÃÄê¤Î¥¢¥É¥ì¥¹¤Î¤ß¤«¡¢ + ¤Þ¤¿¤Ï¤½¤ì¤é¤ÎÁȤ߹ç¤ï¤»¤Î¤¤¤º¤ì¤«¤ò listen ¤¹¤ë¤è¤¦¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢°Û¤Ê¤ë IP ¥¢¥É¥ì¥¹¡¢¥Û¥¹¥È̾¡¢¥Ý¡¼¥È¤ËÂФ¹¤ë Apache + ¤Î±þÅúÊýË¡¤ò·èÄꤹ¤ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥Èµ¡Ç½¤ÈÁȤ߹ç¤ï¤»¤Æ»È¤ï¤ì¤Þ¤¹¡£

    + +

    Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ÆÃÄê¤Î¥Ý¡¼¥È¤ä¥¢¥É¥ì¥¹¡¦¥Ý¡¼¥È¤ÎÁȤ«¤é¤Î¤ßÆþ¤Ã¤Æ¤¯¤ë + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£ + ¤â¤·¥Ý¡¼¥ÈÈÖ¹æ¤Î¤ß¤¬ Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢ + ¤¹¤Ù¤Æ¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ÎÍ¿¤¨¤é¤ì¤¿¥Ý¡¼¥ÈÈÖ¹æ¤ò + listen ¤·¤Þ¤¹¡£ IP ¥¢¥É¥ì¥¹¤¬¥Ý¡¼¥ÈÈÖ¹æ¤ÈƱ»þ¤ËÍ¿¤¨¤é¤ì¤¿¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤ÏÍ¿¤¨¤é¤ì¤¿¥Ý¡¼¥È¤È¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò listen ¤·¤Þ¤¹¡£ + Ê£¿ô¤Î Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÍѤ¤¤Æ + ¤¤¤¯¤Ä¤«¤Î listen ¤¹¤ë¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¥ê¥¹¥È¤µ¤ì¤¿¥¢¥É¥ì¥¹¤ä¥Ý¡¼¥È¤«¤é¤Î¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤Ë + ÂФ·¤Æ±þÅú¤·¤Þ¤¹¡£

    + +

    ¤¿¤È¤¨¤Ð¡¢¥Ý¡¼¥È 80 ¤È 8000 ¤ÎξÊý¤ËÂФ·¤Æ¤ÎÀܳ¤ò¼õ¤±ÉÕ¤±¤ë¤Ë¤Ï

    + +

    + Listen 80
    + Listen 8000 +

    + +

    ¤È¤·¤Þ¤¹¡£ + Æó¤Ä¤Î»ØÄꤵ¤ì¤¿¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤È¥Ý¡¼¥ÈÈÖ¹æ¤ËÂФ·¤Æ¤ÎÀܳ¤ò¼õ¤±ÉÕ¤±¤ë¤Ë¤Ï¡¢ +

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    ¤È¤·¤Þ¤¹¡£ + IPv6 ¥¢¥É¥ì¥¹¤Ï¡¢³Ñ³ç¸Ì¤Ç¼¡¤ÎÎã¤Î¤è¤¦¤Ë°Ï¤Þ¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    +
    top
    +
    +

    IPv6 ¤ÎÆõ­»ö¹à

    + + +

    ¿¤¯¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç IPv6 ¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤­¤Æ¤¤¤Æ¡¢ + APR ¤Ï¤³¤ì¤é¤Î¤Û¤È¤ó¤É¤Ç IPv6 ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤Î¤Ç¡¢ + Apache ¤Ï IPv6 ¥½¥±¥Ã¥È¤ò³ä¤êÅö¤Æ¤Æ IPv6 + ·Ðͳ¤ÇÁ÷¤é¤ì¤Æ¤­¤¿¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    IPv6 ¥½¥±¥Ã¥È¤¬ IPv4 ¤È IPv6 ¥³¥Í¥¯¥·¥ç¥ó¤ÎξÊý¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤ë¤« + ¤É¤¦¤«¤Ï¡¢Apache ´ÉÍý¼Ô¤Ë¤È¤Ã¤ÆÌñ²ð¤ÊÌäÂê¤Ç¤¹¡£ + IPv4 ¥³¥Í¥¯¥·¥ç¥ó¤ò IPv6 ¥½¥±¥Ã¥È¤Ç°·¤¦¾ì¹ç¤Ï¡¢ + IPv4 ¥Þ¥Ã¥×¤µ¤ì¤¿ IPv6 ¥¢¥É¥ì¥¹¤ò»ÈÍѤ·¤Æ¤¤¤Æ¡¢ + ¤Û¤È¤ó¤É¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç»ÈÍѲÄǽ¤Ç¤¹¤¬¡¢ + FreeBSD, NetBSD, OpenBSD ¤Ç¤Ï¡¢¥·¥¹¥Æ¥àÁ´ÂΤȤ·¤Æ¤Î¥Ý¥ê¥·¡¼¤È¤ÎÀ°¹çÀ­¤«¤é¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï»ÈÍÑÉԲĤËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¥Ç¥Õ¥©¥ë¥È¤Ç»ÈÍÑÉԲĤΥץé¥Ã¥È¥Û¡¼¥à¤Ç¤¢¤Ã¤Æ¤â¡¢ + ÆÃÊÌ¤Ê configure ¤Î + ÀßÄê¥Ñ¥é¥á¡¼¥¿¤Ç Apache ¤ÎµóÆ°¤òÊѲ½¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    °ìÊý¤Ç¡¢Linux ¤ä Tru64 ¤È¤¤¤Ã¤¿¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç IPv4 ¤È IPv6 + ¤ÎξÊý¤ò°·¤¦¤Ë¤Ï¡¢¥Þ¥Ã¥×¥È¥¢¥É¥ì¥¹¤ò»ÈÍѤ¹¤ë°Ê³°¤ÎÊýË¡¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + IPv4 ¤È IPv6 ¤Î¥³¥Í¥¯¥·¥ç¥ó¤òºÇ¾®¸Â¤Î¥½¥±¥Ã¥È¤Ç°·¤¤¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢ + IPv4 ¥Þ¥Ã¥×¤Î IPv6 ¥¢¥É¥ì¥¹¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¡¢ + --enable-v4-mapped configure + ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    --enable-v4-mapped ¤Ï¡¢ + FreeBSD, NetBSD, OpenBSD °Ê³°¤ÎÁ´¤Æ¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¤ª¤½¤é¤¯¤ª¼ê¸µ¤Î Apache ¤Ï¤³¤ÎÀßÄê¤Ç¥Ó¥ë¥É¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤ä APR ¤¬²¿¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤«¤Ë´Ø¤ï¤é¤º¡¢ + IPv4 ¥³¥Í¥¯¥·¥ç¥ó¤Î¤ß¤ò°·¤¦¤è¤¦¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + ¼¡¤ÎÎã¤Î¤è¤¦¤ËÁ´¤Æ¤Î + Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + IPv4 ¥¢¥É¥ì¥¹¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +

    + +

    ¾ò·ï¤òËþ¤¿¤¹¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¡¢Apache ¤¬ + IPv4 ¤È IPv6 ¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¸ÄÊ̤Υ½¥±¥Ã¥È¤Ç°·¤¦¤è¤¦¤Ë¤·¤¿¤¤¾ì¹ç + (¤Ä¤Þ¤ê IPv4 ¥Þ¥Ã¥×¤Î¥¢¥É¥ì¥¹¤ò̵¸ú¤Ë¤·¤¿¤¤¾ì¹ç) + ¤Ï¡¢--disable-v4-mapped + configure + ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Æ¡¢¼¡¤Î¤è¤¦¤Ë¸ÄÊÌ»ØÄê¤Î + Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£ + --disable-v4-mapped ¤Ï¡¢ + FreeBSD, NetBSD, OpenBSD ¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£

    +
    top
    +
    +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤Æ¤É¤¦Æ¯¤¯¤Î¤«

    + + +

    Listen + ¤Ç¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬¼ÂÁõ¤µ¤ì¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + Listen ¤Ïñ¤Ë¥á¥¤¥ó¥µ¡¼¥Ð¤Ë¤É¤Î¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ò listen ¤¹¤Ù¤­¤«¤ò + ¶µ¤¨¤ë¤À¤±¤Ç¤¹¡£ + <VirtualHost> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»È¤ï¤ì¤Ê¤¤¾ì¹ç¤Ï¡¢ + ¼õ¤±Æþ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤¹¤Ù¤Æ¤ËÂФ·¤ÆÁ´¤¯Æ±¤¸µóÆ°¤ò¤·¤Þ¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é + <VirtualHost> + ¤ò»È¤Ã¤Æ¡¢ + °ì¤Ä°Ê¾å¤Î¥¢¥É¥ì¥¹¤ä¥Ý¡¼¥È¤ËÂФ·¤Æ°Û¤Ê¤ëµóÆ°¤ò¤¹¤ë¤è¤¦¤Ë + »ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + VirtualHost ¤ò¼ÂÁõ¤¹¤ë¤Ë¤Ï¡¢»ÈÍѤ¹¤ë¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ò + ¤Þ¤º½é¤á¤Ë¥µ¡¼¥Ð¤ËÄÌÃΤ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤½¤·¤Æ¡¢¤½¤Î»ØÄꤷ¤¿¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤Ç¤Î + ¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎµóÆ°¤òÀßÄꤹ¤ë¤¿¤á¤Ë¡¢ + <VirtualHost> + ¥»¥¯¥·¥ç¥ó¤òºî¤ê¤Þ¤¹¡£¤â¤· + <VirtualHost> + ¤¬ listen ¤·¤Æ¤¤¤Ê¤¤¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ËÂФ·¤Æ + ÀßÄꤵ¤ì¤Æ¤·¤Þ¤¦¤È¡¢ + ¤½¤ì¤Ë¤Ï¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/bind.html.ko.euc-kr b/trunk/docs/manual/bind.html.ko.euc-kr new file mode 100644 index 0000000000..cf17ab84d0 --- /dev/null +++ b/trunk/docs/manual/bind.html.ko.euc-kr @@ -0,0 +1,151 @@ + + + +ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ (Binding) - Apache HTTP Server + + + + + +
    <-
    +

    ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ (Binding)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ¾ÆÆÄÄ¡°¡ ƯÁ¤ ÁÖ¼Ò¿Í Æ÷Æ®¿¡¼­ ¼­ºñ½ºÇϵµ·Ï ¼³Á¤Çϱâ.

    +
    + +
    top
    +
    +

    °³¿ä

    + + + + + +

    ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ¸é ¾ÆÆÄÄ¡´Â ÄÄÇ»ÅÍÀÇ ¾î¶² Æ÷Æ®¿Í ÁÖ¼Ò¿¡ + ¿¬°áÇÏ¿©, µé¾î¿À´Â ¿äûÀ» ±â´Ù¸°´Ù. ±âº»ÀûÀ¸·Î ¾ÆÆÄÄ¡´Â + ÄÄÇ»ÅÍÀÇ ¸ðµç ÁÖ¼Ò¿¡¼­ ±â´Ù¸°´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ ƯÁ¤ Æ÷Æ®³ª + ¼±ÅÃÇÑ ÁÖ¼Ò¸¸À» ±â´Ù¸®°Ô ÇؾßÇÒ °æ¿ì°¡ ÀÖ´Ù. ¶Ç ÀÌ ¹®Á¦´Â + ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ´Ù¸¥ IP ÁÖ¼Ò, È£½ºÆ®¸í, Æ÷Æ®¿¡ ¹ÝÀÀÇÒÁö¸¦ + °áÁ¤ÇÏ´Â °¡»óÈ£½ºÆ® ±â´É°úµµ °ü·ÃµÇÀÖ´Ù.

    + +

    Listen Áö½Ã¾î´Â + ¼­¹ö°¡ ƯÁ¤ Æ÷Æ®³ª ÁÖ¼Ò¿Í Æ÷Æ® Á¶ÇÕ¿¡¼­¸¸ ¿äûÀ» ¹Þ°Ô + ÇÑ´Ù. Listen + Áö½Ã¾î¿¡ Æ÷Æ® ¹øÈ£¸¸ ÁöÁ¤Çϸé, ¼­¹ö´Â ¸ðµç ÀÎÅÍÆäÀ̽º¿¡¼­ + ÁöÁ¤ÇÑ Æ÷Æ®¸¦ ±â´Ù¸°´Ù. ¿©·¯ Listen Áö½Ã¾î·Î ±â´Ù¸± ¿©·¯ + ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù. ¼­¹ö´Â ¿­°ÅÇÑ ÁÖ¼Ò¿Í Æ÷Æ®·Î + ¿äûÀÌ µé¾î¿À¸é ÀÀ´äÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, ¼­¹ö°¡ 80¹ø°ú 8000¹ø Æ÷Æ® ¸ðµÎ¿¡¼­ ¿¬°áÀ» + ¹Þµµ·Ï ÇÏ·Á¸é:

    + +

    + Listen 80
    + Listen 8000 +

    + +

    ¼­¹ö°¡ ÁöÁ¤ÇÑ µÎ ÀÎÅÍÆäÀ̽º¿Í Æ÷Æ®¿¡¼­ ¿¬°áÀ» ±â´Ù¸®µµ·Ï + ÇÏ·Á¸é,

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6 ÁÖ¼Ò´Â ´ÙÀ½°ú °°ÀÌ ´ë°ýÈ£·Î ¹­¾î¾ß ÇÑ´Ù:

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    +
    top
    +
    +

    IPv6¿¡¼­ Ưº°È÷ °í·ÁÇÒ Á¡

    + + +

    IPv6¸¦ ±¸ÇöÇÑ Ç÷¡ÆûÀÌ ´Ã°í ÀÖ°í APRÀÌ À̵é Ç÷¡Æû ´ëºÎºÐ¿¡¼­ + IPv6¸¦ Áö¿øÇϱ⶧¹®¿¡, ¾ÆÆÄÄ¡´Â IPv6 ¼ÒÄÏÀ» ÇÒ´çÇÏ¿© IPv6·Î + ¹ÞÀº ¿äûÀ» ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ °ü¸®ÀÚ¿¡°Ô º¹ÀâÇÑ ºÎºÐÀº IPv6 ¼ÒÄÏÀÌ IPv4 ¿¬°á°ú + IPv6 ¿¬°áÀ» ¸ðµÎ ó¸®ÇÒ ¼ö ÀÖ´À³Ä´Â Á¡ÀÌ´Ù. ´ëºÎºÐÀÇ Ç÷¡Æû¿¡¼­´Â + IPv4-´ëÀÀ(mapped) IPv6 ÁÖ¼Ò¸¦ »ç¿ëÇÏ¿© IPv6 ¼ÒÄÏ¿¡¼­ IPv4 + ¿¬°áÀ» ¹ÞÁö¸¸, FreeBSD¿Í NetBSD¿Í OpenBSDÀº ½Ã½ºÅÛÀüü Á¤Ã¥¶§¹®¿¡ + ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö ¾Ê´Â´Ù. ±×·¯³ª ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö¾Ê´Â + ½Ã½ºÅÛÀÌ¶óµµ ¾ÆÆÄÄ¡¸¦ À§ÇØ Æ¯º°ÇÑ ¼³Á¤ ÆĶó¹ÌÅÍ·Î º¯°æÇÒ + ¼ö ÀÖ´Ù.

    + +

    ¹Ý¸é ¸®´ª½º¿Í Tru64 °°Àº ÀϺΠÇ÷¡Æû¿¡¼­ IPv4¿Í IPv6À» + ¸ðµÎ ó¸®ÇÏ·Á¸é ´ëÀÀ ÁÖ¼Ò¸¦ »ç¿ëÇؾ߸¸ + ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ ÃÖ¼ÒÇÑÀÇ ¼ÒÄÏÀ» »ç¿ëÇÏ¿© IPv4 ¿¬°á°ú IPv6 + ¿¬°áÀ» ¸ðµÎ ¹Þµµ·ÏÇÏ·Á¸é, IPv4-´ëÀÀ IPv6 ÁÖ¼Ò¸¦ »ç¿ëÇÏ°í + configure ¿É¼Ç + --enable-v4-mapped¸¦ ÁöÁ¤ÇÑ´Ù.

    + +

    --enable-v4-mapped´Â FreeBSD, NetBSD, OpenBSD¸¦ + Á¦¿ÜÇÑ ¸ðµç Ç÷¡Æû¿¡¼­ ±âº»°ªÀÌ°í, ¾Æ¸¶µµ ´ç½ÅÀÇ ¾ÆÆÄÄ¡µµ + ¸¶Âù°¡ÁöÀÏ °ÍÀÌ´Ù.

    + +

    Ç÷¡Æû°ú APRÀÇ Áö¿ø¿©ºÎ¿Í °ü°è¾øÀÌ ¾ÆÆÄÄ¡°¡ IPv4 ¿¬°á¸¸À» + ¹Þµµ·ÏÇÏ·Á¸é, ´ÙÀ½ ¿¹Á¦¿Í °°ÀÌ ¸ðµç Listen Áö½Ã¾î¿¡ IPv4 ÁÖ¼Ò¸¦ + »ç¿ëÇÑ´Ù:

    + +

    + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +

    + +

    Ç÷¡Æû¿¡¼­ Áö¿øÇÏ¸ç ¾ÆÆÄÄ¡°¡ ¼­·Î ´Ù¸¥ ¼ÒÄÏÀ¸·Î IPv4 + ¿¬°á°ú IPv6 ¿¬°áÀ» ¹Þµµ·ÏÇÏ·Á¸é (Áï IPv4-´ëÀÀ ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸·Á¸é), configure + ¿É¼Ç --disable-v4-mapped¸¦ + ÁöÁ¤ÇÑ´Ù. --disable-v4-mapped´Â FreeBSD, NetBSD, + OpenBSD¿¡¼­ ±âº»°ªÀÌ´Ù.

    + +
    top
    +
    +

    °¡»óÈ£½ºÆ®¿Í ¾î¶»°Ô ¿¬°üµÇ³ª

    + + +

    ListenÀº + °¡»óÈ£½ºÆ®¸¦ ¸¸µéÁö ¾Ê´Â´Ù. ÀÌ´Â ´ÜÁö ÁÖ¼­¹ö°¡ + ¾î¶² ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ±â´Ù¸±Áö¸¸ ¾Ë·ÁÁØ´Ù. <VirtualHost> Áö½Ã¾î¸¦ + »ç¿ëÇÏÁö ¾ÊÀ¸¸é, ¼­¹ö´Â ¹ÞÀº ¸ðµç ¿äûÀ» ¶È°°ÀÌ Ã³¸®ÇÑ´Ù. + ±×·¯³ª <VirtualHost>·Î ¿©·¯ ÁÖ¼Ò¿Í Æ÷Æ®¿¡ + ´ëÇØ ´Ù¸¥ ÇൿÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. °¡»óÈ£½ºÆ®¸¦ ¸¸µé·Á¸é + ¸ÕÀú ¼­¹ö¿¡°Ô »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ¾Ë·ÁÁà¾ß ÇÑ´Ù. ±×¸®°í + ƯÁ¤ ÁÖ¼Ò¿Í Æ÷Æ®¿¡ ´ëÇÑ °¡»óÈ£½ºÆ®ÀÇ ÇൿÀ» ÁöÁ¤ÇÒ + <VirtualHost> + ¼½¼ÇÀÌ ÇÊ¿äÇÏ´Ù. ÁÖ¼­¹ö°¡ ±â´Ù¸®Áö¾Ê´Â ÁÖ¼Ò¿Í Æ÷Æ®¸¦ »ç¿ëÇÏ´Â + <VirtualHost>´Â + Á¢±ÙÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/bind.xml b/trunk/docs/manual/bind.xml new file mode 100644 index 0000000000..c939818e46 --- /dev/null +++ b/trunk/docs/manual/bind.xml @@ -0,0 +1,163 @@ + + + + + + + + + + Binding + + +

    Configuring Apache to listen on specific addresses and ports.

    +
    + + Virtual Hosts + DNS Issues + +
    + Overview + + + + core + mpm_common + + + VirtualHost + Listen + + + + +

    When Apache starts, it binds to some port and address on + the local machine and waits for incoming requests. By default, + it listens to all addresses on the machine. However, it needs to + be told to listen on specific ports, or to listen on only selected + addresses, or a combination. This is often combined with the + Virtual Host feature which determines how Apache responds to + different IP addresses, hostnames and ports.

    + +

    The Listen + directive tells the server to accept + incoming requests only on the specified port or + address-and-port combinations. If only a port number is + specified in the Listen + directive, the server + listens to the given port on all interfaces. If an IP address + is given as well as a port, the server will listen on the given + port and interface. Multiple Listen directives may be used to + specify a number of addresses and ports to listen on. The + server will respond to requests from any of the listed + addresses and ports.

    + +

    For example, to make the server accept connections on both + port 80 and port 8000, use:

    + + + Listen 80
    + Listen 8000 +
    + +

    To make the server accept connections on two specified + interfaces and port numbers, use

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6 addresses must be surrounded in square brackets, as in the + following example:

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + +
    + +
    + Special IPv6 Considerations + +

    A growing number of platforms implement IPv6, and APR supports + IPv6 on most of these platforms, allowing Apache to allocate IPv6 + sockets and handle requests which were sent over IPv6.

    + +

    One complicating factor for Apache administrators is whether or + not an IPv6 socket can handle both IPv4 connections and IPv6 + connections. Handling IPv4 connections with an IPv6 socket uses + IPv4-mapped IPv6 addresses, which are allowed by default on most + platforms but are disallowed by default on FreeBSD, NetBSD, and + OpenBSD in order to match the system-wide policy on those + platforms. But even on systems where it is disallowed by default, a + special configure parameter can change this behavior + for Apache.

    + +

    On the other hand, on some platforms such as Linux and Tru64 the + only way to handle both IPv6 and IPv4 is to use + mapped addresses. If you want Apache to handle IPv4 and IPv6 connections + with a minimum of sockets, which requires using IPv4-mapped IPv6 + addresses, specify the --enable-v4-mapped + configure option.

    + +

    --enable-v4-mapped is the default on all platforms but + FreeBSD, NetBSD, and OpenBSD, so this is probably how your Apache was + built.

    + +

    If you want Apache to handle IPv4 connections only, regardless of + what your platform and APR will support, specify an IPv4 address on all + Listen directives, as in the + following examples:

    + + + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +
    + +

    If your platform supports it and you want Apache to handle IPv4 and + IPv6 connections on separate sockets (i.e., to disable IPv4-mapped + addresses), specify the --disable-v4-mapped + configure option. --disable-v4-mapped is the + default on FreeBSD, NetBSD, and OpenBSD.

    +
    + +
    + How This Works With Virtual Hosts + +

    Listen does not implement + Virtual Hosts. It only tells the + main server what addresses and ports to listen to. If no + VirtualHost + directives are used, the server will behave + the same for all accepted requests. However, + VirtualHost + can be used to specify a different behavior + for one or more of the addresses and ports. To implement a + VirtualHost, the server must first be told to listen to the + address and port to be used. Then a + VirtualHost section + should be created for a specified address and port to set the + behavior of this virtual host. Note that if the + VirtualHost + is set for an address and port that the + server is not listening to, it cannot be accessed.

    +
    +
    + diff --git a/trunk/docs/manual/bind.xml.de b/trunk/docs/manual/bind.xml.de new file mode 100644 index 0000000000..d7fe9cfce7 --- /dev/null +++ b/trunk/docs/manual/bind.xml.de @@ -0,0 +1,170 @@ + + + + + + + + + + Anbindung + + +

    Konfiguration der vom Apache verwendeten Adressen und Ports.

    +
    + + Virtuelle Hosts + Probleme bezüglich DNS und + Apache + +
    + Überblick + + + + core + mpm_common + + + VirtualHost + Listen + + + +

    Beim Start bindet sich der Apache an bestimmte Adressen und Ports + der lokalen Maschine und wartet auf eingehende Anfragen. + Standardmäßig lauscht er an allen Adressen des Systems. + Es muss ihm jedoch mitgeteilt werden, an bestimmten Ports zu lauschen + oder nur an ausgewählten Adressen, bzw. einer Kombination aus + beidem. Dies wird oft mit der Funktionalität virtueller Hosts + kombiniert, die bestimmt, wie der Apache auf verschiedene IP-Adressen, + Hostnamen und Ports reagiert.

    + +

    Die Direktive Listen + weist den Server an, eingehende Anfragen nur an bestimmten Ports oder + Adress/Port-Kombinationen zu akzeptieren. Wenn bei der Listen-Direktive nur eine Portnummer + angegeben wird, dann lauscht der Server auf allen Netzwerkinterfaces an + dem angegebenen Port. Ist auch eine IP-Adresse angegeben, dann lauscht der + Server an der angegebenen Schnittstelle auf dem angegebenen Port. Es + können mehrere Listen-Anweisungen verwendet werden, um + eine Reihe von Adressen und Ports anzugeben, an denen gelauscht werden + soll. Der Server wird dann auf Anfragen an jeder der abgehörten + Adressen und Ports antworten.

    + +

    Um beispielsweise den Server zu veranlassen, sowohl an Port 80, als + auch an Port 8000 Verbindungen zu akzeptieren, geben Sie an:

    + + + Listen 80
    + Listen 8000 +
    + +

    Um den Server Verbindungen an zwei bestimmten + Netzwerkinterfaces und Ports zu akzeptieren zu lassen, geben Sie an:

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6-Adressen müssen wie im folgenden Beispiel in eckigen + Klammern angegeben werden:

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + +
    + +
    + Betrachtung von IPv6-Besonderheiten + +

    Eine wachsende Anzahl von Plattformen implementiert IPv6. Die APR + unterstützt IPv6 auf den meisten dieser Plattformen und + ermöglicht dem Apache, IPv6-Sockets zu verwenden und Anfragen zu + behandeln, die über IPv6 gesendet wurden.

    + +

    Für Apache-Administratoren kommt erschwerend die Frage hinzu, ob + IPv6-Sockets sowohl IPv4- als auch IPv6-Verbindungen + handhaben können. Zum Betrieb von IPv4-Verbindungen an + IPv6-Sockets werden auf IPv6 abgebildete IPv4-Adressen + so genannete IPv4-gemappte IPv6-Adressen + verwendet, welche standardmäßig auf den meisten Plattformen + erlaubt sind. Unter FreeBSD, NetBSD und OpenBSD jedoch sind sie + standardmäßig deaktiviert, um den Systemgrundsätzen dieser + Plattformen zu entsprechen. Doch selbst auf Systemen, wo dies + standardmäßig dekativiert ist, kann dieses Verhalten mit einem + speziellen configure-Parameter für den Apache + geändert werden.

    + +

    Auf der anderen Seite ist die Verwendung von gemappten Adressen bei + einigen Plattformen wie Linux und True64 der einzige + Weg, sowohl IPv4 wie auch IPv6 zu verwenden. Wenn Sie möchten, dass + der Apache IPv4- und IPv6-Verbindungen mit einem Minimum an Sockets + behandelt, was die Verwendung von IPv4-gemappten IPv6-Adressen + erfordert, dann müssen Sie die + configure-Option --enable-v4-mapped angeben.

    + +

    --enable-v4-mapped ist die Voreinstellung auf allen + Plattformen außer FreeBSD, NetBSD und OpenBSD, so dass Ihr Apache + wahrscheinlich so übersetzt wurde.

    + +

    Geben Sie wie in dem folgenden Beispiel bei allen Listen-Anweisungen eine IPv4-Adresse + an, wenn Sie möchten, dass Ihr Apache lediglich IPv4-Adressen + behandelt, unabhängig davon, was Ihre Plattform und die APR + unterstützen:

    + + + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +
    + +

    Wenn Sie möchten, dass der Apache IPv4- und IPv6-Verbindungen an + separaten Sockets behandelt (d.h. IPv4-gemappte Adressen deaktiviert + werden sollen) und Ihre Plattform es unterstützt, dann müssen + Sie die configure-Option + --disable-v4-mapped angeben. + Unter FreeBSD, NetBSD und OpenBSD ist --disable-v4-mapped + voreingestellt.

    +
    + +
    + Das Zusammenspiel mit virtuellen Hosts + +

    Listen implementiert keine + virtuellen Hosts. Es teilt dem Hauptserver lediglich mit, an welchen + Adressen und Ports er zu lauschen hat. Werden keine VirtualHost-Container + verwendet, verhält sich der Server bei allen angenommenen Anfragen + gleich. VirtualHost-Abschnitte können jedoch + dazu verwendet werden, ein unterschiedliches Verhalten für eine oder + mehrere Adressen und Ports festzulegen. Um einen virtuellen Host + einzurichten, muss dem Server zunächst mitgeteilt werden, an den + betreffenden Adressen und Ports zu lauschen. Dann sollte ein VirtualHost-Abschnitt für + eine bestimmte Adresse und einen Port erstellt werden, um das Verhalten + dieses virtuellen Hosts festzulegen. Beachten Sie bitte, dass auf einen + VirtualHost nicht + zugegriffen werden kann, wenn er für eine Adresse und einen Port + eingerichtet wurde, an dem der Server nicht lauscht.

    +
    +
    + diff --git a/trunk/docs/manual/bind.xml.fr b/trunk/docs/manual/bind.xml.fr new file mode 100644 index 0000000000..ec795a60db --- /dev/null +++ b/trunk/docs/manual/bind.xml.fr @@ -0,0 +1,194 @@ + + + + + + + + + + Liaison + + +

    Configuration des adresses et ports sur lesquels Apache écoute.

    +
    + + Serveurs Virtuels + Problémes DNS + +
    + Informations générales + + + + core + mpm_common + + + VirtualHost + Listen + + + + +

    Au moment de son démarrage, Apache se lie à un port et à une + adresse IP sur la machine locale et se met en attente de requètes. + Par défaut, Apache écoute sur toutes les adresses de la machine. + Apache accepte d'écouter sur un ou plusieurs ports spécifiques, + sur une seule ou plusieurs adresses, ou encore sur une combinaison port-adresse. + Il est fréquent d'utiliser ces possibilités avec les fonctionnalités + de Serveurs Virtuels, qui permettent de faire répondre le serveur de + manière différente en fonction de l'adresse IP, du nom d'hôte ou + du port.

    + +

    Le serveur interprète la directive + Listen + en acceptant les requètes seulement sur le port ou la combinaison + adresse IP + port passée en argument. Dans le cas où seul un port + est spécifié avec la directive + Listen, + le serveur se met à l'écoute sur le port spécifié, sur toutes + les interfaces et adresses de la machine. Si une adresse IP est + spécifiée en plus du port, le serveur n'écoute que sur l'adresse + et le port spécifié. Il est possible de configurer plusieurs adresses + et ports avec la directives + Listen + pour écoute par le serveur. Le serveur répond aux requètes faites + à toutes les adresses et ports énumérés.

    + + +

    Par exemple, pour que le serveur accepte les connexions sur + les ports 80 et 8000, spécifiez :

    + + + Listen 80
    + Listen 8000 +
    + +

    Pour qu'Apache accepte les connexions sur deux combinaisons + adresses + ports, spécifiez :

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    Les adresses IPv6 sont acceptées, pourvu qu'elles soient spécifiées + entre crochets de la façon suivante :

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + +
    + +
    + Considérations Spéciales avec IPv6 + +

    De plus en plus de plate-formes implémentent IPv6. APR + supporte IPv6 sur la plupart d'entre elles, si bien qu'Apache + peut assigner des interfaces de connexions IPv6 et répondre aux + requètes utilisant IPv6.

    + +

    Une complication possible pour les administrateurs Apache est de + savoir si une interface de connexion IPv6 peut répondre aux deux types de + connexions IPv4 et IPv6. + Manipuler les connexions IPv4 avec une interface de connexion IPv6 + suppose l'utilisation d'adresses IPv6 mappées en IPv4, ce qui est + le cas par defaut sur la plupart des plate-formes, à l'exeption de FreeBSD, + NetBSD, et OpenBSD, cela en raison des politiques systèmes de ces plate-formes. + Mème sur des systèmes où cette fonctionnalité n'est pas activée par + défaut, une option de compilation permet de changer ce + fonctionnement pour Apache.

    +

    Pour qu'Apache puisse gérer à la fois les connexions IPv4 et IPv6 + avec un minimum d'interfaces de connexions, il faut permettre l'utilisation + des adresses + IPv6 mappées en IPv4, ce qui est possible en spécifiant l'option + + de compilation --enable-v4-mapped et en utilisant la + directive Listen + comme suit:

    + + + Listen 80 + + +

    Si --enable-v4-mapped a été spécifié à la compilation, + les directives Listen + de la configuration par défaut sont de la forme ci-dessus. + --enable-v4-mapped est l'option de compilation + par défaut sur toutes les plate-formes, sauf FreeBSD, NetBSD, et + OpenBSD.

    + + +

    Pour qu'Apache ne manipule que les connexions IPv4, en ignorant l'éventuel + support IPv6 de la plate-forme ou d'APR, une adresse IPv4 peut être + spécifié pour toutes les directives + Listen, + comme dans les exemples suivantss:

    + + + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +
    + +

    Pour qu'Apache manipule les connexions IPv4 et IPv6 sur des interfaces + différentes (c'est-à-dire, pour ne pas accepter les addresse IPv6 mappées + en IPv4), spécifier l'option de compilation --disable-v4-mapped + et utiliser des directives Listen + spécifiques telles que:

    + + Listen [::]:80
    + Listen 0.0.0.0:80 +
    + +

    Avec --disable-v4-mapped, la directive + Listen à l'intérieur + du fichier de configuration par défaut créé par Apache utilise la forme + ci-dessus. + --disable-v4-mapped est l'option de compilation par défaut sous + FreeBSD, NetBSD, et OpenBSD.

    +
    + +
    + Faire fonctionner tout ceci avec les Serveurs Virtuels + +

    Listen + n'implémente aucun Serveur Virtuel. Cette directive sert simplement + à informer le serveur principal sur quels addresses et ports écouter. + Dans le cas où aucune section + VirtualHost + n'est utilisée, le serveur répondra de la mème manière pour toutes + les requètes qu'il acceptera. Cependant des sections + VirtualHost + peuvent être utilisées pour qu'Apache réagisse de façon différente à + une requète selon l'adresse ou le port. Avant d'implémenter + un Serveur Virtuel au moyen de la directive + VirtualHost, la directive + Listen + doit tre utilisée pour que le serveur écoute sur l'adresse + ou le port spécifié. Une section + VirtualHost + peut alors être utilisée pour définir la réaction du Serveur Virtuel pour une + adresse et un port spécifique. À noter que si un Serveur Virtuel est + positionné au moyen de la directive + VirtualHost + sur une adresse et un port sur lesquels le serveur n'est pas à l'écoute, + le Serveur Virtuel ne sera pas accessible.

    +
    +
    + diff --git a/trunk/docs/manual/bind.xml.ja b/trunk/docs/manual/bind.xml.ja new file mode 100644 index 0000000000..1bf205dee8 --- /dev/null +++ b/trunk/docs/manual/bind.xml.ja @@ -0,0 +1,173 @@ + + + + + + + + + + $B%P%$%s%I(B + + +

    Apache $B$,;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj$r$7$^$9!#(B

    +
    + + $B%P!<%A%c%k%[%9%H(B + DNS $B$NLdBj(B + +
    + $B35MW(B + + + + core + mpm_common + + + VirtualHost + Listen + + + + +

    Apache $B$O5/F0;~$K!"%m!<%+%k%^%7%s$N$"$k%]!<%H$"$h$S%"%I%l%9(B + $B$KBP$7$F@\B3$7!"%j%/%(%9%H$,Mh$k$N$rBT$A$^$9!#(B + $B%G%U%)%k%H$G$O%^%7%s$N$9$Y$F$N%"%I%l%9$KBP$7$F(B listen $B$7$^$9!#(B + $B$7$+$7$J$,$i!"FCDj$N%]!<%H$+!"FCDj$N%"%I%l%9$N$_$+!"(B + $B$^$?$O$=$l$i$NAH$_9g$o$;$N$$$:$l$+$r(B listen $B$9$k$h$&$K$9$kI,MW$,$"$j$^$9!#(B + $B$3$l$O!"0[$J$k(B IP $B%"%I%l%9!"%[%9%HL>!"%]!<%H$KBP$9$k(B Apache + $B$N1~EzJ}K!$r7hDj$9$k%P!<%A%c%k%[%9%H5!G=$HAH$_9g$o$;$F;H$o$l$^$9!#(B

    + +

    Listen + $B%G%#%l%/%F%#%V$G!"FCDj$N%]!<%H$d%"%I%l%9!&%]!<%H$NAH$+$i$N$_F~$C$F$/$k(B + $B%j%/%(%9%H$rListen + $B%G%#%l%/%F%#%V$G;XDj$5$l$?>l9g$O!"(B + $B$9$Y$F$N%$%s%?!<%U%'!<%9$NM?$($i$l$?%]!<%HHV9f$r(B + listen $B$7$^$9!#(B IP $B%"%I%l%9$,%]!<%HHV9f$HF1;~$KM?$($i$l$?>l9g$O!"(B + $B%5!<%P$OM?$($i$l$?%]!<%H$H%$%s%?!<%U%'!<%9$r(B listen $B$7$^$9!#(B + $BJ#?t$N(B Listen $B%G%#%l%/%F%#%V$rMQ$$$F(B + $B$$$/$D$+$N(B listen $B$9$k%"%I%l%9$H%]!<%H$r;XDj$G$-$^$9!#(B + $B%5!<%P$O%j%9%H$5$l$?%"%I%l%9$d%]!<%H$+$i$N$9$Y$F$N%j%/%(%9%H$K(B + $BBP$7$F1~Ez$7$^$9!#(B

    + +

    $B$?$H$($P!"%]!<%H(B 80 $B$H(B 8000 $B$NN>J}$KBP$7$F$N@\B3$r + + + Listen 80
    + Listen 8000 +
    + +

    $B$H$7$^$9!#(B + $BFs$D$N;XDj$5$l$?%$%s%?%U%'!<%9$H%]!<%HHV9f$KBP$7$F$N@\B3$r + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    $B$H$7$^$9!#(B + IPv6 $B%"%I%l%9$O!"3Q3g8L$G + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + +

    + +
    + IPv6 $B$NFC5-;v9`(B + +

    $BB?$/$N%W%i%C%H%[!<%`$G(B IPv6 $B$,%5%]!<%H$5$l$F$-$F$$$F!"(B + APR $B$O$3$l$i$N$[$H$s$I$G(B IPv6 $B$r%5%]!<%H$7$F$$$k$N$G!"(B + Apache $B$O(B IPv6 $B%=%1%C%H$r3d$jEv$F$F(B IPv6 + $B7PM3$GAw$i$l$F$-$?%j%/%(%9%H$r07$&$3$H$,$G$-$^$9!#(B

    + +

    IPv6 $B%=%1%C%H$,(B IPv4 $B$H(B IPv6 $B%3%M%/%7%g%s$NN>J}$r07$&$3$H$,$G$-$k$+(B + $B$I$&$+$O!"(BApache $B4IM}l9g$O!"(B + IPv4 $B%^%C%W$5$l$?(B IPv6 $B%"%I%l%9$r;HMQ$7$F$$$F!"(B + $B$[$H$s$I$N%W%i%C%H%[!<%`$G$O%G%U%)%k%H$G;HMQ2DG=$G$9$,!"(B + FreeBSD, NetBSD, OpenBSD $B$G$O!"%7%9%F%`A4BN$H$7$F$N%]%j%7!<$H$N@09g@-$+$i!"(B + $B%G%U%)%k%H$G$O;HMQIT2D$K@_Dj$5$l$F$$$^$9!#(B + $B$3$l$i$N%G%U%)%k%H$G;HMQIT2D$N%W%i%C%H%[!<%`$G$"$C$F$b!"(B + $BFCJL$J(B configure $B$N(B + $B@_Dj%Q%i%a!<%?$G(B Apache $B$N5sF0$rJQ2=$5$;$k$3$H$,$G$-$^$9!#(B

    + +

    $B0lJ}$G!"(BLinux $B$d(B Tru64 $B$H$$$C$?%W%i%C%H%[!<%`$G(B IPv4 $B$H(B IPv6 + $B$NN>J}$r07$&$K$O!"%^%C%W%H%"%I%l%9$r;HMQ$9$k(B$B0J30$NJ}K!$O$"$j$^$;$s(B$B!#(B + IPv4 $B$H(B IPv6 $B$N%3%M%/%7%g%s$r:G>.8B$N%=%1%C%H$G07$$$?$$$N$G$"$l$P!"(B + IPv4 $B%^%C%W$N(B IPv6 $B%"%I%l%9$r;HMQ$9$kI,MW$,$"$j!"(B + --enable-v4-mapped configure + $B%*%W%7%g%s$r;XDj$7$^$9!#(B

    + +

    --enable-v4-mapped $B$O!"(B + FreeBSD, NetBSD, OpenBSD $B0J30$NA4$F$N%W%i%C%H%[!<%`$G$N%G%U%)%k%H$G$9!#(B + $B$G$9$+$i!"$*$=$i$/$* + +

    $B%W%i%C%H%U%)!<%`$d(B APR $B$,2?$r%5%]!<%H$9$k$+$K4X$o$i$:!"(B + IPv4 $B%3%M%/%7%g%s$N$_$r07$&$h$&$K$7$?$$>l9g$O!"(B + $BListen $B%G%#%l%/%F%#%V$G(B + IPv4 $B%"%I%l%9$r;XDj$7$F$/$@$5$$!#(B

    + + + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +
    + +

    $B>r7o$rK~$?$9%W%i%C%H%[!<%`$G!"(BApache $B$,(B + IPv4 $B$H(B IPv6 $B$N%3%M%/%7%g%s$r8DJL$N%=%1%C%H$G07$&$h$&$K$7$?$$>l9g(B + ($B$D$^$j(B IPv4 $B%^%C%W$N%"%I%l%9$rL58z$K$7$?$$>l9g(B) + $B$O!"(B--disable-v4-mapped + configure + $B%*%W%7%g%s$r;XDj$7$F!"Listen + $B%G%#%l%/%F%#%V$r;HMQ$7$F$/$@$5$$!#(B + --disable-v4-mapped $B$O!"(B + FreeBSD, NetBSD, OpenBSD $B%W%i%C%H%[!<%`$G$N%G%U%)%k%H$G$9!#(B

    +
    + +
    + $B%P!<%A%c%k%[%9%H$KBP$7$F$I$&F/$/$N$+(B + +

    Listen + $B$G%P!<%A%c%k%[%9%H$,VirtualHost + $B%G%#%l%/%F%#%V$,;H$o$l$J$$>l9g$O!"(B + $BVirtualHost + $B$r;H$C$F!"(B + $B0l$D0J>e$N%"%I%l%9$d%]!<%H$KBP$7$F0[$J$k5sF0$r$9$k$h$&$K(B + $B;XDj$9$k$3$H$,$G$-$^$9!#(B + VirtualHost $B$rVirtualHost + $B%;%/%7%g%s$r:n$j$^$9!#$b$7(B + VirtualHost + $B$,(B listen $B$7$F$$$J$$%"%I%l%9$H%]!<%H$KBP$7$F(B + $B@_Dj$5$l$F$7$^$&$H!"(B + $B$=$l$K$O%"%/%;%9$G$-$J$$$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    +
    diff --git a/trunk/docs/manual/bind.xml.ko b/trunk/docs/manual/bind.xml.ko new file mode 100644 index 0000000000..c2a22e3dc5 --- /dev/null +++ b/trunk/docs/manual/bind.xml.ko @@ -0,0 +1,152 @@ + + + + + + + + + + ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ (Binding) + + +

    ¾ÆÆÄÄ¡°¡ ƯÁ¤ ÁÖ¼Ò¿Í Æ÷Æ®¿¡¼­ ¼­ºñ½ºÇϵµ·Ï ¼³Á¤Çϱâ.

    +
    + + °¡»óÈ£½ºÆ® + DNS ¹®Á¦ + +
    + °³¿ä + + + + core + mpm_common + + + VirtualHost + Listen + + + + +

    ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ¸é ¾ÆÆÄÄ¡´Â ÄÄÇ»ÅÍÀÇ ¾î¶² Æ÷Æ®¿Í ÁÖ¼Ò¿¡ + ¿¬°áÇÏ¿©, µé¾î¿À´Â ¿äûÀ» ±â´Ù¸°´Ù. ±âº»ÀûÀ¸·Î ¾ÆÆÄÄ¡´Â + ÄÄÇ»ÅÍÀÇ ¸ðµç ÁÖ¼Ò¿¡¼­ ±â´Ù¸°´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ ƯÁ¤ Æ÷Æ®³ª + ¼±ÅÃÇÑ ÁÖ¼Ò¸¸À» ±â´Ù¸®°Ô ÇؾßÇÒ °æ¿ì°¡ ÀÖ´Ù. ¶Ç ÀÌ ¹®Á¦´Â + ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ´Ù¸¥ IP ÁÖ¼Ò, È£½ºÆ®¸í, Æ÷Æ®¿¡ ¹ÝÀÀÇÒÁö¸¦ + °áÁ¤ÇÏ´Â °¡»óÈ£½ºÆ® ±â´É°úµµ °ü·ÃµÇÀÖ´Ù.

    + +

    Listen Áö½Ã¾î´Â + ¼­¹ö°¡ ƯÁ¤ Æ÷Æ®³ª ÁÖ¼Ò¿Í Æ÷Æ® Á¶ÇÕ¿¡¼­¸¸ ¿äûÀ» ¹Þ°Ô + ÇÑ´Ù. Listen + Áö½Ã¾î¿¡ Æ÷Æ® ¹øÈ£¸¸ ÁöÁ¤Çϸé, ¼­¹ö´Â ¸ðµç ÀÎÅÍÆäÀ̽º¿¡¼­ + ÁöÁ¤ÇÑ Æ÷Æ®¸¦ ±â´Ù¸°´Ù. ¿©·¯ Listen Áö½Ã¾î·Î ±â´Ù¸± ¿©·¯ + ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù. ¼­¹ö´Â ¿­°ÅÇÑ ÁÖ¼Ò¿Í Æ÷Æ®·Î + ¿äûÀÌ µé¾î¿À¸é ÀÀ´äÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, ¼­¹ö°¡ 80¹ø°ú 8000¹ø Æ÷Æ® ¸ðµÎ¿¡¼­ ¿¬°áÀ» + ¹Þµµ·Ï ÇÏ·Á¸é:

    + + + Listen 80
    + Listen 8000 +
    + +

    ¼­¹ö°¡ ÁöÁ¤ÇÑ µÎ ÀÎÅÍÆäÀ̽º¿Í Æ÷Æ®¿¡¼­ ¿¬°áÀ» ±â´Ù¸®µµ·Ï + ÇÏ·Á¸é,

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6 ÁÖ¼Ò´Â ´ÙÀ½°ú °°ÀÌ ´ë°ýÈ£·Î ¹­¾î¾ß ÇÑ´Ù:

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + +
    + +
    + IPv6¿¡¼­ Ưº°È÷ °í·ÁÇÒ Á¡ + +

    IPv6¸¦ ±¸ÇöÇÑ Ç÷¡ÆûÀÌ ´Ã°í ÀÖ°í APRÀÌ À̵é Ç÷¡Æû ´ëºÎºÐ¿¡¼­ + IPv6¸¦ Áö¿øÇϱ⶧¹®¿¡, ¾ÆÆÄÄ¡´Â IPv6 ¼ÒÄÏÀ» ÇÒ´çÇÏ¿© IPv6·Î + ¹ÞÀº ¿äûÀ» ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ °ü¸®ÀÚ¿¡°Ô º¹ÀâÇÑ ºÎºÐÀº IPv6 ¼ÒÄÏÀÌ IPv4 ¿¬°á°ú + IPv6 ¿¬°áÀ» ¸ðµÎ ó¸®ÇÒ ¼ö ÀÖ´À³Ä´Â Á¡ÀÌ´Ù. ´ëºÎºÐÀÇ Ç÷¡Æû¿¡¼­´Â + IPv4-´ëÀÀ(mapped) IPv6 ÁÖ¼Ò¸¦ »ç¿ëÇÏ¿© IPv6 ¼ÒÄÏ¿¡¼­ IPv4 + ¿¬°áÀ» ¹ÞÁö¸¸, FreeBSD¿Í NetBSD¿Í OpenBSDÀº ½Ã½ºÅÛÀüü Á¤Ã¥¶§¹®¿¡ + ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö ¾Ê´Â´Ù. ±×·¯³ª ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö¾Ê´Â + ½Ã½ºÅÛÀÌ¶óµµ ¾ÆÆÄÄ¡¸¦ À§ÇØ Æ¯º°ÇÑ ¼³Á¤ ÆĶó¹ÌÅÍ·Î º¯°æÇÒ + ¼ö ÀÖ´Ù.

    + +

    ¹Ý¸é ¸®´ª½º¿Í Tru64 °°Àº ÀϺΠÇ÷¡Æû¿¡¼­ IPv4¿Í IPv6À» + ¸ðµÎ ó¸®ÇÏ·Á¸é ´ëÀÀ ÁÖ¼Ò¸¦ »ç¿ëÇؾ߸¸ + ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ ÃÖ¼ÒÇÑÀÇ ¼ÒÄÏÀ» »ç¿ëÇÏ¿© IPv4 ¿¬°á°ú IPv6 + ¿¬°áÀ» ¸ðµÎ ¹Þµµ·ÏÇÏ·Á¸é, IPv4-´ëÀÀ IPv6 ÁÖ¼Ò¸¦ »ç¿ëÇÏ°í + configure ¿É¼Ç + --enable-v4-mapped¸¦ ÁöÁ¤ÇÑ´Ù.

    + +

    --enable-v4-mapped´Â FreeBSD, NetBSD, OpenBSD¸¦ + Á¦¿ÜÇÑ ¸ðµç Ç÷¡Æû¿¡¼­ ±âº»°ªÀÌ°í, ¾Æ¸¶µµ ´ç½ÅÀÇ ¾ÆÆÄÄ¡µµ + ¸¶Âù°¡ÁöÀÏ °ÍÀÌ´Ù.

    + +

    Ç÷¡Æû°ú APRÀÇ Áö¿ø¿©ºÎ¿Í °ü°è¾øÀÌ ¾ÆÆÄÄ¡°¡ IPv4 ¿¬°á¸¸À» + ¹Þµµ·ÏÇÏ·Á¸é, ´ÙÀ½ ¿¹Á¦¿Í °°ÀÌ ¸ðµç Listen Áö½Ã¾î¿¡ IPv4 ÁÖ¼Ò¸¦ + »ç¿ëÇÑ´Ù:

    + + + Listen 0.0.0.0:80
    + Listen 192.170.2.1:80 +
    + +

    Ç÷¡Æû¿¡¼­ Áö¿øÇÏ¸ç ¾ÆÆÄÄ¡°¡ ¼­·Î ´Ù¸¥ ¼ÒÄÏÀ¸·Î IPv4 + ¿¬°á°ú IPv6 ¿¬°áÀ» ¹Þµµ·ÏÇÏ·Á¸é (Áï IPv4-´ëÀÀ ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸·Á¸é), configure + ¿É¼Ç --disable-v4-mapped¸¦ + ÁöÁ¤ÇÑ´Ù. --disable-v4-mapped´Â FreeBSD, NetBSD, + OpenBSD¿¡¼­ ±âº»°ªÀÌ´Ù.

    + +
    + +
    + °¡»óÈ£½ºÆ®¿Í ¾î¶»°Ô ¿¬°üµÇ³ª + +

    ListenÀº + °¡»óÈ£½ºÆ®¸¦ ¸¸µéÁö ¾Ê´Â´Ù. ÀÌ´Â ´ÜÁö ÁÖ¼­¹ö°¡ + ¾î¶² ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ±â´Ù¸±Áö¸¸ ¾Ë·ÁÁØ´Ù. VirtualHost Áö½Ã¾î¸¦ + »ç¿ëÇÏÁö ¾ÊÀ¸¸é, ¼­¹ö´Â ¹ÞÀº ¸ðµç ¿äûÀ» ¶È°°ÀÌ Ã³¸®ÇÑ´Ù. + ±×·¯³ª VirtualHost·Î ¿©·¯ ÁÖ¼Ò¿Í Æ÷Æ®¿¡ + ´ëÇØ ´Ù¸¥ ÇൿÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. °¡»óÈ£½ºÆ®¸¦ ¸¸µé·Á¸é + ¸ÕÀú ¼­¹ö¿¡°Ô »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ¾Ë·ÁÁà¾ß ÇÑ´Ù. ±×¸®°í + ƯÁ¤ ÁÖ¼Ò¿Í Æ÷Æ®¿¡ ´ëÇÑ °¡»óÈ£½ºÆ®ÀÇ ÇൿÀ» ÁöÁ¤ÇÒ + VirtualHost + ¼½¼ÇÀÌ ÇÊ¿äÇÏ´Ù. ÁÖ¼­¹ö°¡ ±â´Ù¸®Áö¾Ê´Â ÁÖ¼Ò¿Í Æ÷Æ®¸¦ »ç¿ëÇÏ´Â + VirtualHost´Â + Á¢±ÙÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    +
    +
    + diff --git a/trunk/docs/manual/bind.xml.meta b/trunk/docs/manual/bind.xml.meta new file mode 100644 index 0000000000..f08c64c7ba --- /dev/null +++ b/trunk/docs/manual/bind.xml.meta @@ -0,0 +1,15 @@ + + + + bind + / + . + + + de + en + fr + ja + ko + + diff --git a/trunk/docs/manual/configuring.html b/trunk/docs/manual/configuring.html new file mode 100644 index 0000000000..3ec3186dbc --- /dev/null +++ b/trunk/docs/manual/configuring.html @@ -0,0 +1,15 @@ +URI: configuring.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: configuring.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: configuring.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: configuring.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/configuring.html.de b/trunk/docs/manual/configuring.html.de new file mode 100644 index 0000000000..27f8106ea6 --- /dev/null +++ b/trunk/docs/manual/configuring.html.de @@ -0,0 +1,183 @@ + + + +Konfigurationsdateien - Apache HTTP Server + + + + + +
    <-
    +

    Konfigurationsdateien

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + +

    Dieses Dokument beschreibt die Dateien, die zur Konfiguration des Apache + HTTP Servers verwendet werden.

    +
    + +
    top
    +
    +

    Hauptkonfigurationsdateien

    + + + +

    Der Apache wird konfiguriert, indem Direktiven in einfache Textdateien + eingetragen werden. Die Hauptkonfigurationsdatei heißt + üblicherweise httpd.conf. Der Ablageort dieser Datei + wird bei der Kompilierung festgelegt, kann jedoch mit der + Befehlszeilenoption -f überschrieben werden. Durch + Verwendung der Direktive Include + können außerdem weitere Konfigurationsdateien hinzugefügt + werden. Zum Einfügen von mehreren Konfigurationsdateien können + Platzhalter verwendet werden. Jede Direktive darf in jeder dieser + Konfigurationsdateien angegeben werden. Änderungen in den + Hauptkonfigurationsdateien werden vom Apache nur beim Start oder Neustart + erkannt.

    + +

    Der Server liest auch eine Datei mit MIME-Dokumenttypen ein. Der + Name dieser Datei wird durch die Direktive TypesConfig bestimmt. Die Voreinstellung + ist mime.types.

    +
    top
    +
    +

    Syntax der Konfigurationsdateien

    + + +

    Die Konfigurationsdateien des Apache enthalten eine Direktive pro Zeile. + Der Backslash "\" läßt sich als letztes Zeichen in einer Zeile + dazu verwenden, die Fortsetzung der Direktive in der nächsten Zeile + anzuzeigen. Es darf kein weiteres Zeichen oder Whitespace zwischen dem + Backslash und dem Zeilenende folgen.

    + +

    In den Konfigurationsdateien wird bei den Direktiven nicht zwischen + Groß- und Kleinschreibung unterschieden. Bei den Argumenten der + Direktiven wird dagegen oftmals zwischen Groß- und Kleinschreibung + differenziert. Zeilen, die mit dem Doppelkreuz "#" beginnen, werden als + Kommentare betrachtet und ignoriert. Kommentare dürfen + nicht am Ende einer Zeile nach der Direktive + eingefügt werden. Leerzeilen und Whitespaces vor einer Direktive + werden ignoriert. Dadurch lassen sich Direktiven zur besseren Lesbarbeit + einrücken.

    + +

    Sie können die Syntax Ihrer Konfigurationsdateien auf Fehler + prüfen, ohne den Server zu starten, indem Sie apachectl + configtest oder die Befehlszeilenoption -t + verwenden.

    +
    top
    +
    +

    Module

    + + + + +

    Der Apache ist ein modularer Server. Das bedeutet, dass nur die abolute + Grundfunktionalität im Kernserver enthalten ist. Weitergehende + Fähigkeiten sind mittels Modulen verfügbar, + die in den Apache geladen werden können. Standardmäßig + wird bei der Kompilierung ein Satz von Basismodulen (Anm.d.Ü.: die so + genannten Base-Module) in den Server eingebunden. Wenn der + Server für die Verwendung von dynamisch + ladbaren Modulen kompiliert wurde, dann können Module separat + kompiliert und jederzeit mittels der Direktive LoadModule hinzugefügt werden. + Andernfalls muss der Apache neu kompiliert werden, um Module + hinzuzufügen oder zu entfernen. Konfigurationsanweisungen können + abhängig vom Vorhandensein eines bestimmten Moduls eingesetzt werden, + indem sie in einen <IfModule>-Block eingeschlossen werden.

    + +

    Um zu sehen, welche Module momentan in den Server einkompiliert sind, + kann die Befehlszeilenoption -l verwendet werden.

    +
    top
    +
    +

    Der Gültigkeitsbereich von Direktiven

    + + + + +

    Direktiven in den Hauptkonfigurationsdateien gelten für den + gesamten Server. Wenn Sie die Konfiguration nur für einen Teil des + Servers verändern möchten, können Sie den + Gültigkeitsbereich der Direktiven beschränken, indem Sie diese + in <Directory>-, + <DirectoryMatch>-, + <Files>-, + <FilesMatch>-, + <Location>- oder + <LocationMatch>-Abschnitte eingefügen. + Diese Abschnitte begrenzen die Anwendung der umschlossenen Direktiven + auf bestimmte Pfade des Dateisystems oder auf + bestimmte URLs. Sie können für eine fein abgestimmte + Konfiguration auch ineinander verschachtelt werden.

    + + +

    Der Apache besitzt die Fähigkeit, mehrere verschiedene Websites + gleichzeitig zu bedienen. Dies wird virtuelles + Hosten genannt. Direktiven können auch in ihrem + Gültigkeitsgereich eingeschränkt werden, indem sie innerhalb + eines <VirtualHost>-Abschnittes angegeben werden. + Sie werden dann nur auf Anfragen für eine bestimmte Website + angewendet.

    + +

    Obwohl die meisten Direktiven in jedem dieser Abschnitte platziert + werden können, ergeben einige Direktiven in manchen Kontexten + keinen Sinn. Direktiven zur Prozesssteuerung beispielsweise + dürfen nur im Kontext des Hauptservers angegeben werden. Prüfen + Sie den Kontext der + Direktive, um herauszufinden, welche Direktiven in welche Abschnitte + eingefügt werden können. Weitere Informationen finden Sie unter + "Wie Directory-, Location- und Files-Abschnitte + arbeiten".

    + +
    top
    +
    +

    .htaccess-Dateien

    + + + + +

    Der Apache ermöglicht die dezentrale Verwaltung der + Konfiguration mittes spezieller Dateien innerhalb des + Web-Verzeichnisbaums. Diese speziellen Dateien heißen + gewöhnlich .htaccess, mit der Direktive AccessFileName kann jedoch auch ein anderer + Name festgelegt werden. In .htaccess-Dateien angegebene + Direktiven werden auf das Verzeichnis und dessen Unterverzeichnisse + angewendet, in dem die Datei abgelegt ist. .htaccess-Dateien + folgen der gleichen Syntax wie die Hauptkonfigurationsdateien. Da + .htaccess-Dateien bei jeder Anfrage eingelesen werden, + werden Änderungen in diesen Dateien sofort wirksam.

    + +

    Prüfen Sie den Kontext der Direktive, um + herauszufinden, welche Direktiven in .htaccess-Dateien + angegeben werden können. Darüber hinaus steuert der + Serveradministrator mit der Einstellung der Direktive AllowOverride in den + Hauptkonfigurationsdateien welche Direktiven in + .htaccess-Dateien verwendet werden dürfen.

    + +

    Weitere Informationen über .htaccess-Dateien finden + Sie in der .htaccess-Einführung.

    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/configuring.html.en b/trunk/docs/manual/configuring.html.en new file mode 100644 index 0000000000..39a6a41d3c --- /dev/null +++ b/trunk/docs/manual/configuring.html.en @@ -0,0 +1,167 @@ + + + +Configuration Files - Apache HTTP Server + + + + + +
    <-
    +

    Configuration Files

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + +

    This document describes the files used to configure the Apache +HTTP server.

    +
    + +
    top
    +
    +

    Main Configuration Files

    + + + +

    Apache is configured by placing directives in plain text + configuration files. The main configuration file is usually called + httpd.conf. The location of this file is set at + compile-time, but may be overridden with the -f + command line flag. In addition, other configuration files may be + added using the Include + directive, and wildcards can be used to include many configuration + files. Any directive may be placed in any of these configuration + files. Changes to the main configuration files are only + recognized by Apache when it is started or restarted.

    + +

    The server also reads a file containing mime document types; + the filename is set by the TypesConfig directive, + and is mime.types by default.

    +
    top
    +
    +

    Syntax of the Configuration Files

    + + +

    Apache configuration files contain one directive per line. + The back-slash "\" may be used as the last character on a line + to indicate that the directive continues onto the next line. + There must be no other characters or white space between the + back-slash and the end of the line.

    + +

    Directives in the configuration files are case-insensitive, + but arguments to directives are often case sensitive. Lines + that begin with the hash character "#" are considered + comments, and are ignored. Comments may not be + included on a line after a configuration directive. Blank lines + and white space occurring before a directive are ignored, so + you may indent directives for clarity.

    + +

    You can check your configuration files for syntax errors + without starting the server by using apachectl + configtest or the -t command line + option.

    +
    top
    +
    +

    Modules

    + + + + +

    Apache is a modular server. This implies that only the most + basic functionality is included in the core server. Extended + features are available through modules which can be loaded + into Apache. By default, a base set of modules is + included in the server at compile-time. If the server is + compiled to use dynamically loaded + modules, then modules can be compiled separately and added at + any time using the LoadModule + directive. + Otherwise, Apache must be recompiled to add or remove modules. + Configuration directives may be included conditional on a + presence of a particular module by enclosing them in an <IfModule> block.

    + +

    To see which modules are currently compiled into the server, + you can use the -l command line option.

    +
    top
    +
    +

    Scope of Directives

    + + + + +

    Directives placed in the main configuration files apply to + the entire server. If you wish to change the configuration for + only a part of the server, you can scope your directives by + placing them in <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, and <LocationMatch> + sections. These sections limit the application of the + directives which they enclose to particular filesystem + locations or URLs. They can also be nested, allowing for very + fine grained configuration.

    + +

    Apache has the capability to serve many different websites + simultaneously. This is called Virtual + Hosting. Directives can also be scoped by placing them + inside <VirtualHost> + sections, so that they will only apply to requests for a + particular website.

    + +

    Although most directives can be placed in any of these + sections, some directives do not make sense in some contexts. + For example, directives controlling process creation can only + be placed in the main server context. To find which directives + can be placed in which sections, check the Context of the + directive. For further information, we provide details on How Directory, Location and Files sections + work.

    +
    top
    +
    +

    .htaccess Files

    + + + + +

    Apache allows for decentralized management of configuration + via special files placed inside the web tree. The special files + are usually called .htaccess, but any name can be + specified in the AccessFileName + directive. Directives placed in .htaccess files + apply to the directory where you place the file, and all + sub-directories. The .htaccess files follow the + same syntax as the main configuration files. Since + .htaccess files are read on every request, changes + made in these files take immediate effect.

    + +

    To find which directives can be placed in + .htaccess files, check the Context of the + directive. The server administrator further controls what + directives may be placed in .htaccess files by + configuring the AllowOverride + directive in the main configuration files.

    + +

    For more information on .htaccess files, see + the .htaccess tutorial.

    +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/configuring.html.ja.euc-jp b/trunk/docs/manual/configuring.html.ja.euc-jp new file mode 100644 index 0000000000..3d460eba73 --- /dev/null +++ b/trunk/docs/manual/configuring.html.ja.euc-jp @@ -0,0 +1,169 @@ + + + +ÀßÄê¥Õ¥¡¥¤¥ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ÀßÄê¥Õ¥¡¥¤¥ë

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï¡¢Apache HTTP ¥µ¡¼¥Ð¤òÀßÄꤹ¤ë¤Î¤Ë»ÈÍѤ¹¤ë¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤Æ +µ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥á¥¤¥ó¤ÎÀßÄê¥Õ¥¡¥¤¥ë

    + + + +

    Apache ¤Ï ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö ¤òÀßÄê¥Õ¥¡¥¤¥ë¤Ëʿʸ¤Ç½ñ¤¯¤³¤È¤Ë¤è¤êÀßÄꤷ¤Þ¤¹¡£ + ¥á¥¤¥ó¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ÏÉáÄÌ¤Ï httpd.conf ¤È¤¤¤¦Ì¾Á°¤Ç¤¹¡£ + ¤³¤Î¥Õ¥¡¥¤¥ë¤Î°ÌÃ֤ϥ³¥ó¥Ñ¥¤¥ë»þ¤ËÀßÄꤵ¤ì¤Þ¤¹¤¬¡¢¥³¥Þ¥ó¥É¥é¥¤¥ó¤Î + -f ¥Õ¥é¥°¤Ë¤è¤ê¾å½ñ¤­¤Ç¤­¤Þ¤¹¡£ + ¤Þ¤¿¡¢Â¾¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ò Include + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤ÆÄɲäǤ­¡¢¥ï¥¤¥ë¥É¥«¡¼¥É¤ò»ÈÍѤ·¤Æ¿¿ô¤Î + ÀßÄê¥Õ¥¡¥¤¥ë¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤É¤ó¤Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤â¡¢¤³¤ì¤é¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤É¤ì¤Ë¤Ç¤âÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Apache ¤Ïµ¯Æ°»þ¤«ºÆµ¯Æ°»þ¤Î¤ß¥á¥¤¥óÀßÄê¥Õ¥¡¥¤¥ë¤ÎÊѹ¹¤òǧ¼±¤·¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤Ï MIME + ¥É¥­¥å¥á¥ó¥È¥¿¥¤¥×¤ò´Þ¤ó¤Ç¤¤¤ë¥Õ¥¡¥¤¥ë¤âÆɤ߹þ¤ß¤Þ¤¹¡£¥Õ¥¡¥¤¥ë̾¤Ï + TypesConfig + ¤ÇÀßÄꤵ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï mime.types + ¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ÀßÄê¥Õ¥¡¥¤¥ë¤Î¹½Ê¸

    + + +

    Apache ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤Ï 1 ¹Ô¤Ë 1 ¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤«¤é¤Ê¤ê¤Þ¤¹¡£ + ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å "\" ¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¼¡¤Î¹Ô¤Ë·Ñ³¤·¤Æ¤¤¤ë¤³¤È¤ò + ¼¨¤¹¤¿¤á¤Ë¹Ô¤ÎºÇ¸å¤Îʸ»ú¤È¤·¤Æ»È¤ï¤ì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¹Ô¤ÎºÇ¸å¤È¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Î´Ö¤Ë¾¤Îʸ»ú¤ä¶õÇò¤¬¤¢¤Ã¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£ +

    + +

    ÀßÄê¥Õ¥¡¥¤¥ë¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¤¬¡¢ + °ú¿ô¤Ë¤Ï¤·¤Ð¤·¤Ð¶èÊ̤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£¥Ï¥Ã¥·¥åʸ»ú "#" + ¤Ç»Ï¤Þ¤ë¹Ô¤Ï¥³¥á¥ó¥È¤È¸«¤Ê¤µ¤ì¤Æ̵»ë¤µ¤ì¤Þ¤¹¡£ + ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸å¤Î¹Ô¤Ç¤Ï¥³¥á¥ó¥È¤¬´Þ¤Þ¤ì¤Æ¤¤¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÁ°¤Î¶õ¹Ô¤È¶õÇò¤Ï̵»ë¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + ¤ï¤«¤ê¤ä¤¹¤¯¤¹¤ë¤¿¤á¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£ +

    + +

    ÀßÄê¥Õ¥¡¥¤¥ë¤Î¹½Ê¸¥¨¥é¡¼¤Ï¡¢ + apachectl configtest + ¤«¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó + -t ¤ò»È¤Ã¤ÆÄ´¤Ù¤é¤ì¤Þ¤¹¡£

    +
    top
    +
    +

    ¥â¥¸¥å¡¼¥ë

    + + + + +

    Apache ¤Ï¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤¿¥µ¡¼¥Ð¤Ç¤¹¡£ + ¥³¥¢¥µ¡¼¥Ð¤Ë¤ÏºÇ¤â´ðËÜŪ¤Êµ¡Ç½¤À¤±¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£³ÈÄ¥µ¡Ç½¤Ï + Apache ¤Ë¥í¡¼¥É¤µ¤ì¤ë¥â¥¸¥å¡¼¥ë¤È¤·¤ÆÍøÍѲÄǽ¤Ç¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥â¥¸¥å¡¼¥ë¤Î + Base ¥»¥Ã¥È (´ðËÜ¥»¥Ã¥È) ¤¬ + ¥µ¡¼¥Ð¤Ë´Þ¤Þ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¤¬Æ°Åª¥í¡¼¥É¥â¥¸¥å¡¼¥ë¤ò»È¤¦¤è¤¦¤Ë¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥â¥¸¥å¡¼¥ë¤òÊ̤˥³¥ó¥Ñ¥¤¥ë¤·¤Æ¡¢¤¤¤Ä¤Ç¤â + LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤ÆÄɲäǤ­¤Þ¤¹¡£ + ¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥â¥¸¥å¡¼¥ë¤ÎÄɲääºï½ü¤ò¤¹¤ë¤¿¤á¤Ë¤Ï Apache + ¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï <IfModule> + ¥Ö¥í¥Ã¥¯¤ËÆþ¤ì¤ë¤³¤È¤ÇÆÃÄê¤Î¥â¥¸¥å¡¼¥ë¤¬Â¸ºß¤¹¤ë¤È¤­¤À¤± + ÀßÄê¥Õ¥¡¥¤¥ë¤Ë´Þ¤Þ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó -l ¤ò»È¤Ã¤Æ¸½»þÅÀ¤Ç + ¤É¤Î¥â¥¸¥å¡¼¥ë¤¬¥µ¡¼¥Ð¤Ë¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈÏ°Ï

    + + + + +

    ¥á¥¤¥óÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥ÐÁ´ÂΤËŬÍѤµ¤ì¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Î°ìÉôʬ¤ÎÀßÄê¤À¤±¤òÊѹ¹¤·¤¿¤¤¾ì¹ç¤Ï <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, <LocationMatch> + ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤ËÃÖ¤¯¤³¤È¤ÇŬÍÑÈϰϤò·è¤á¤é¤ì¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¥»¥¯¥·¥ç¥ó¤Ï¤½¤ÎÃæ¤Ë¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈϰϤò + ÆÃÄê¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃÖ¤ä URL ¤Ë¸ÂÄꤷ¤Þ¤¹¡£ + Èó¾ï¤ËºÙγÅÙ¤ÎÀßÄê¤ò²Äǽ¤Ë¤¹¤ë¤¿¤á¤Ë¡¢ + ¥»¥¯¥·¥ç¥ó¤òÆþ¤ì»Ò¤Ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ¤ÏƱ»þ¤Ë¿¤¯¤Î°ã¤¦¥¦¥§¥Ö¥µ¥¤¥È¤ò°·¤¦Ç½ÎϤ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È ¤È¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¡£ + ÆÃÄê¤Î¥¦¥§¥Ö¥µ¥¤¥È¤Ë¤Î¤ßŬÍѤµ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + <VirtualHost> + ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤ËÃÖ¤¯¤³¤È¤Ç¤âŬÍÑÈϰϤòÊѤ¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤Û¤È¤ó¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤É¤Î¥»¥¯¥·¥ç¥ó¤Ë¤Ç¤â½ñ¤±¤Þ¤¹¤¬¡¢ + Ãæ¤Ë¤Ï¥³¥ó¥Æ¥­¥¹¥È¤Ë¤è¤Ã¤Æ¤Ï°ÕÌ£¤ò¤Ê¤µ¤Ê¤¤¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢¥×¥í¥»¥¹¤ÎºîÀ®¤òÀ©¸æ¤·¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥á¥¤¥ó¥µ¡¼¥Ð¤Î + ¥³¥ó¥Æ¥­¥¹¥È¤Ë¤Î¤ß½ñ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¤É¤Î¥»¥¯¥·¥ç¥ó¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¤«¤òÃΤ뤿¤á¤Ë¤Ï + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î ¥³¥ó¥Æ¥­¥¹¥È ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£¾Ü¤·¤¤¾ðÊó¤Ï¡¢ + Directory, Location, Files + ¥»¥¯¥·¥ç¥ó¤ÎÆ°ºîË¡¤Ë¤¢¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    .htaccess ¥Õ¥¡¥¤¥ë

    + + + + +

    Apache ¤Ç¤Ï¥¦¥§¥Ö¥Ä¥ê¡¼¤ÎÃæ¤ËÃÖ¤«¤ì¤¿ÆÃÊ̤ʥե¡¥¤¥ë¤ò»È¤Ã¤Æ + ÈóÃæ±û½¸¸¢Åª¤ÊÀßÄê´ÉÍý¤ò¤Ç¤­¤Þ¤¹¡£¤½¤ÎÆÃÊ̤ʥե¡¥¤¥ë¤ÏÉáÄÌ¤Ï + .htaccess ¤È¤¤¤¦Ì¾Á°¤Ç¡¢ + AccessFileName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤É¤ó¤Ê̾Á°¤Ë¤Ç¤â»ØÄê¤Ç¤­¤Þ¤¹¡£ + .htaccess + ¥Õ¥¡¥¤¥ë¤Ë½ñ¤«¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Õ¥¡¥¤¥ë¤òÃÖ¤¤¤¿ + ¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤ÎÁ´¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + .htaccess + ¥Õ¥¡¥¤¥ë¤Ï¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ÇÆɤ߹þ¤Þ¤ì¤ë¤¿¤á¡¢ + Êѹ¹¤Ï¤¹¤°¤ËÈ¿±Ç¤µ¤ì¤Þ¤¹¡£

    + +

    ¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ .htaccess + ¥Õ¥¡¥¤¥ë¤Ë½ñ¤±¤ë¤«¤òÄ´¤Ù¤ë¤Ë¤Ï¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥³¥ó¥Æ¥­¥¹¥È + ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£¥µ¡¼¥Ð´ÉÍý¼Ô¤Ï¤µ¤é¤Ë¥á¥¤¥óÀßÄê¥Õ¥¡¥¤¥ë¤Î + AllowOverride + ¤òÀßÄꤹ¤ë¤³¤È¤Ç¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò .htaccess + ¥Õ¥¡¥¤¥ë¤Ë½ñ¤±¤ë¤è¤¦¤Ë¤¹¤ë¤«¤òÀ©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤Ë´Ø¤¹¤ë¾Ü¤·¤¤¾ðÊó¤Ï + .htaccess ¥Á¥å¡¼¥È¥ê¥¢¥ë + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/configuring.html.ko.euc-kr b/trunk/docs/manual/configuring.html.ko.euc-kr new file mode 100644 index 0000000000..d1d18eac95 --- /dev/null +++ b/trunk/docs/manual/configuring.html.ko.euc-kr @@ -0,0 +1,150 @@ + + + +¼³Á¤ÆÄÀÏ - Apache HTTP Server + + + + + +
    <-
    +

    ¼³Á¤ÆÄÀÏ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¼³Á¤ÇÏ´Â ÆÄÀϵéÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ÁÖ¼³Á¤ÆÄÀÏ

    + + + +

    ÀÏ¹Ý ¹®¼­ ÆÄÀÏÀÎ ¼³Á¤ÆÄÀÏ¿¡ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ¼³Á¤ÇÑ´Ù. ÁÖ¼³Á¤ÆÄÀÏÀ» º¸Åë httpd.conf¶ó°í + ºÎ¸¥´Ù. ÀÌ ÆÄÀÏÀÇ À§Ä¡´Â ÄÄÆÄÀϽà Á¤ÇØÁö³ª, -f + ¸í·ÉÇà ¿É¼ÇÀ¸·Î ÁöÁ¤ÇØÁÙ ¼ö ÀÖ´Ù. ¶Ç ´Ù¸¥ ¼³Á¤ÆÄÀÏÀ» Include Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Æ÷ÇÔÇÒ + ¼ö ÀÖ°í, ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ¿© ¸¹Àº ¼³Á¤ÆÄÀÏÀ» Æ÷ÇÔÇÒ ¼öµµ + ÀÖ´Ù. ÀÌ °æ¿ì Áö½Ã¾î¸¦ ¾î¶² ¼³Á¤ÆÄÀÏ¿¡³ª »ç¿ëÇصµ µÈ´Ù. + ÁÖ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÏ¸é ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϰųª Àç½ÃÀÛÇÑ ÀÌÈÄ¿¡ + ¹Ý¿µµÈ´Ù.

    + +

    ¼­¹ö´Â mime ¹®¼­Å¸ÀÔÀ» ´ãÀº ÆÄÀϵµ Àд´Ù. ÆÄÀϸíÀº + TypesConfig Áö½Ã¾î·Î + ¼³Á¤ÇÏ°í, ±âº»°ªÀº mime.typesÀÌ´Ù.

    +
    top
    +
    +

    ¼³Á¤ÆÄÀÏ ¹®¹ý

    + + +

    ¾ÆÆÄÄ¡ ¼³Á¤ÆÄÀÏÀº ÇÑÁÙ¿¡ ÇÑ Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ÁÙ ¸¶Áö¸· + ¹®ÀÚ°¡ ¹é½½·¡½¬ "\"À̸é Áö½Ã¾î°¡ ´ÙÀ½ ÁÙ¿¡¼­ °è¼ÓµÊÀ» ¶æÇÑ´Ù. + ÀÌ °æ¿ì ¹é½½·¡½¬ µÚ¿¡ ¾î¶² ¹®ÀÚ³ª °ø¹éµµ ³ª¿À¸é ¾ÈµÈ´Ù.

    + +

    ¼³Á¤ÆÄÀÏÀÇ Áö½Ã¾î´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö ¾ÊÁö¸¸, Áö½Ã¾îÀÇ + ¾Æ±Ô¸ÕÆ®´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏ´Â °æ¿ì°¡ ÀÖ´Ù. Çؽ¬¹®ÀÚ "#"·Î + ½ÃÀÛÇÏ´Â ÁÙÀº ÁÖ¼®À¸·Î ¹«½ÃÇÑ´Ù. ÁÖ¼®À» ¼³Á¤ Áö½Ã¾î¿Í °°Àº + ÁÙ¿¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. ºóÁÙ°ú Áö½Ã¾î ¾Õ¿¡ ³ª¿À´Â + °ø¹éÀº ¹«½ÃÇϹǷÎ, °£°áÇÏ°Ô º¸À̵µ·Ï Áö½Ã¾î¸¦ ÁÙµéÀÓÇÒ(indent) + ¼ö ÀÖ´Ù.

    + +

    apachectl configtest³ª -t ¸í·ÉÇà + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏÁö ¾Ê°íµµ ¼³Á¤ÆÄÀÏÀÇ ¹®¹ý + ¿À·ù¸¦ °Ë»çÇÒ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ¸ðµâ

    + + + + +

    ¾ÆÆÄÄ¡´Â ¸ðµâÈ­µÈ ¼­¹ö´Ù. ÀÌ´Â ¸Å¿ì ±âº»ÀûÀÎ ±â´É¸¸ÀÌ + ¼­¹ö Çٽɿ¡ Æ÷ÇÔµÇÀÖÀ½À» ¶æÇÑ´Ù. ¾ÆÆÄÄ¡´Â ¸ðµâÀ» Àоîµé¿©¼­ ±â´ÉÀ» + È®ÀåÇÑ´Ù. ±âº»ÀûÀ¸·Î ÄÄÆÄÀÏÇÏ¸é ¼­¹ö¿¡ base ¸ðµâµéÀÌ Æ÷ÇԵȴÙ. + ¼­¹ö¸¦ µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â ¸ðµâÀ» + »ç¿ëÇÒ ¼ö ÀÖ°Ô ÄÄÆÄÀÏÇÏ¿´´Ù¸é ¸ðµâÀ» µû·Î ÄÄÆÄÀÏÇÏ¿© ¾Æ¹«¶§³ª + LoadModule Áö½Ã¾î·Î + Ãß°¡ÇÒ ¼ö ÀÖ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ¸ðµâÀ» Ãß°¡Çϰųª »©±âÀ§ÇØ + ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. ¼³Á¤ Áö½Ã¾î¸¦ IfModule ºí·ÏÀ¸·Î °¨½Î¼­ ƯÁ¤ + ¸ðµâÀÌ ÀÖ´Â °æ¿ì¿¡¸¸ ¼±ÅÃÀûÀ¸·Î ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÇöÀç ¼­¹ö¿¡ ¾î¶² ¸ðµâÀÌ ÄÄÆÄÀϵÇÀÖ´ÂÁö º¸·Á¸é -l + ¸í·ÉÇà ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.

    +
    top
    +
    +

    Áö½Ã¾î Àû¿ë¹üÀ§

    + + + + +

    ÁÖ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î´Â ¼­¹ö Àüü¿¡ Àû¿ëµÈ´Ù. Áö½Ã¾î°¡ + ¼­¹öÀÇ ÀϺο¡¸¸ Àû¿ëµÇ°Ô ÇÏ·Á¸é Áö½Ã¾î¸¦ <Directory>, <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, <LocationMatch> ¼½¼Ç ¾È¿¡ µÎ¾î¾ßÇÑ´Ù. + ÀÌ ¼½¼ÇµéÀº ±×µéÀÌ °¨½Î´Â Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ ÆÄÀϽýºÅÛÀ̳ª + URLÀÇ Æ¯Á¤ À§Ä¡·Î ÇÑÁ¤ÇÑ´Ù. ¶Ç, ¼­·Î °ãÃļ­ »ç¿ëÇÒ ¼ö Àֱ⶧¹®¿¡ + ¸Å¿ì ¼¼¹ÐÇÑ ¼³Á¤ÀÌ °¡´ÉÇÏ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ¿©·¯ ´Ù¸¥ À¥»çÀÌÆ®¸¦ µ¿½Ã¿¡ ¼­ºñ½ºÇÏ´Â + ´É·ÂÀÌ ÀÖ´Ù. À̸¦ °¡»óÈ£½ºÆ®¶ó°í ÇÑ´Ù. + Áö½Ã¾î¸¦ + <VirtualHost> + ¼½¼Ç ¾È¿¡ µÎ¾î ƯÁ¤ À¥»çÀÌÆ®¿¡¸¸ Áö½Ã¾î¸¦ Àû¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    Áö½Ã¾î´Â ´ëºÎºÐ ¾î¶² ¼½¼Ç¿¡ ³ª¿Íµµ µÇÁö¸¸, ¾î¶² Áö½Ã¾î´Â + ƯÁ¤ Àå¼Ò¿¡¼­ Àǹ̰¡ ¾ø´Ù. ¿¹¸¦ µé¾î ÇÁ·Î¼¼½º »ý¼ºÀ» Á¶ÀýÇÏ´Â + Áö½Ã¾î´Â ÁÖ¼­¹ö¼³Á¤ Àå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î°¡ + ¾î¶² ¼½¼Ç¿¡ À§Ä¡ÇÒ ¼ö ÀÖ´ÂÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ È®ÀÎÇ϶ó. + ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â ¾î¶»°Ô Directory, + Location, Files ¼½¼ÇÀÌ µ¿ÀÛÇϳª¸¦ Âü°íÇ϶ó.

    +
    top
    +
    +

    .htaccess ÆÄÀÏ

    + + + + +

    ¾ÆÆÄÄ¡´Â Ưº°ÇÑ ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¼³Á¤À» + ³ª´²¼­(ºÐ±ÇÀûÀ¸·Î) °ü¸®ÇÒ ¼ö ÀÖ´Ù. ÀÌ Æ¯º°ÇÑ ÆÄÀÏÀ» º¸Åë + .htaccess¶ó°í ºÎ¸£Áö¸¸, À̸§Àº AccessFileName Áö½Ã¾î·Î + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î´Â + ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ Àû¿ëµÈ´Ù. + .htaccess ÆÄÀÏÀº ÁÖ¼³Á¤ÆÄÀÏ°ú °°Àº ¹®¹ýÀ» + µû¸¥´Ù. .htaccess ÆÄÀÏÀº ¸Å ¿äû¶§¸¶´Ù Àб⶧¹®¿¡ + ÆÄÀÏÀ» ¼öÁ¤Çϸé Áï½Ã È¿°ú¸¦ º¼ ¼ö ÀÖ´Ù.

    + +

    ¾î¶² Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡ »ç¿ëÇÒ ¼ö + ÀÖ´ÂÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó. ¼­¹ö °ü¸®ÀÚ´Â ÁÖ¼³Á¤ÆÄÀÏÀÇ AllowOverride Áö½Ã¾î·Î + .htaccess ÆÄÀÏ¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + Á¶ÀýÇÒ ¼ö ÀÖ´Ù.

    + +

    .htaccess ÆÄÀÏ¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â + .htaccess ÅõÅ丮¾óÀ» + Âü°íÇ϶ó.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/configuring.xml b/trunk/docs/manual/configuring.xml new file mode 100644 index 0000000000..e5a05e716e --- /dev/null +++ b/trunk/docs/manual/configuring.xml @@ -0,0 +1,199 @@ + + + + + + + + + + Configuration Files + + +

    This document describes the files used to configure the Apache +HTTP server.

    +
    + +
    + Main Configuration Files + + + mod_mime + + + IfDefine + Include + TypesConfig + + + +

    Apache is configured by placing directives in plain text + configuration files. The main configuration file is usually called + httpd.conf. The location of this file is set at + compile-time, but may be overridden with the -f + command line flag. In addition, other configuration files may be + added using the Include + directive, and wildcards can be used to include many configuration + files. Any directive may be placed in any of these configuration + files. Changes to the main configuration files are only + recognized by Apache when it is started or restarted.

    + +

    The server also reads a file containing mime document types; + the filename is set by the TypesConfig directive, + and is mime.types by default.

    +
    + +
    + Syntax of the Configuration Files + +

    Apache configuration files contain one directive per line. + The back-slash "\" may be used as the last character on a line + to indicate that the directive continues onto the next line. + There must be no other characters or white space between the + back-slash and the end of the line.

    + +

    Directives in the configuration files are case-insensitive, + but arguments to directives are often case sensitive. Lines + that begin with the hash character "#" are considered + comments, and are ignored. Comments may not be + included on a line after a configuration directive. Blank lines + and white space occurring before a directive are ignored, so + you may indent directives for clarity.

    + +

    You can check your configuration files for syntax errors + without starting the server by using apachectl + configtest or the -t command line + option.

    +
    + +
    + Modules + + + + mod_so + + + IfModule + LoadModule + + + +

    Apache is a modular server. This implies that only the most + basic functionality is included in the core server. Extended + features are available through modules which can be loaded + into Apache. By default, a base set of modules is + included in the server at compile-time. If the server is + compiled to use dynamically loaded + modules, then modules can be compiled separately and added at + any time using the LoadModule + directive. + Otherwise, Apache must be recompiled to add or remove modules. + Configuration directives may be included conditional on a + presence of a particular module by enclosing them in an IfModule block.

    + +

    To see which modules are currently compiled into the server, + you can use the -l command line option.

    +
    + +
    + Scope of Directives + + + + Directory + DirectoryMatch + Files + FilesMatch + Location + LocationMatch + VirtualHost + + + +

    Directives placed in the main configuration files apply to + the entire server. If you wish to change the configuration for + only a part of the server, you can scope your directives by + placing them in Directory, DirectoryMatch, Files, FilesMatch, Location, and LocationMatch + sections. These sections limit the application of the + directives which they enclose to particular filesystem + locations or URLs. They can also be nested, allowing for very + fine grained configuration.

    + +

    Apache has the capability to serve many different websites + simultaneously. This is called Virtual + Hosting. Directives can also be scoped by placing them + inside VirtualHost + sections, so that they will only apply to requests for a + particular website.

    + +

    Although most directives can be placed in any of these + sections, some directives do not make sense in some contexts. + For example, directives controlling process creation can only + be placed in the main server context. To find which directives + can be placed in which sections, check the Context of the + directive. For further information, we provide details on How Directory, Location and Files sections + work.

    +
    + +
    + .htaccess Files + + + + AccessFileName + AllowOverride + + + +

    Apache allows for decentralized management of configuration + via special files placed inside the web tree. The special files + are usually called .htaccess, but any name can be + specified in the AccessFileName + directive. Directives placed in .htaccess files + apply to the directory where you place the file, and all + sub-directories. The .htaccess files follow the + same syntax as the main configuration files. Since + .htaccess files are read on every request, changes + made in these files take immediate effect.

    + +

    To find which directives can be placed in + .htaccess files, check the Context of the + directive. The server administrator further controls what + directives may be placed in .htaccess files by + configuring the AllowOverride + directive in the main configuration files.

    + +

    For more information on .htaccess files, see + the .htaccess tutorial.

    +
    +
    diff --git a/trunk/docs/manual/configuring.xml.de b/trunk/docs/manual/configuring.xml.de new file mode 100644 index 0000000000..d013c20598 --- /dev/null +++ b/trunk/docs/manual/configuring.xml.de @@ -0,0 +1,212 @@ + + + + + + + + + + Konfigurationsdateien + + +

    Dieses Dokument beschreibt die Dateien, die zur Konfiguration des Apache + HTTP Servers verwendet werden.

    +
    + +
    + Hauptkonfigurationsdateien + + + mod_mime + + + IfDefine + Include + TypesConfig + + + +

    Der Apache wird konfiguriert, indem Direktiven in einfache Textdateien + eingetragen werden. Die Hauptkonfigurationsdatei heißt + üblicherweise httpd.conf. Der Ablageort dieser Datei + wird bei der Kompilierung festgelegt, kann jedoch mit der + Befehlszeilenoption -f überschrieben werden. Durch + Verwendung der Direktive Include + können außerdem weitere Konfigurationsdateien hinzugefügt + werden. Zum Einfügen von mehreren Konfigurationsdateien können + Platzhalter verwendet werden. Jede Direktive darf in jeder dieser + Konfigurationsdateien angegeben werden. Änderungen in den + Hauptkonfigurationsdateien werden vom Apache nur beim Start oder Neustart + erkannt.

    + +

    Der Server liest auch eine Datei mit MIME-Dokumenttypen ein. Der + Name dieser Datei wird durch die Direktive TypesConfig bestimmt. Die Voreinstellung + ist mime.types.

    +
    + +
    + Syntax der Konfigurationsdateien + +

    Die Konfigurationsdateien des Apache enthalten eine Direktive pro Zeile. + Der Backslash "\" läßt sich als letztes Zeichen in einer Zeile + dazu verwenden, die Fortsetzung der Direktive in der nächsten Zeile + anzuzeigen. Es darf kein weiteres Zeichen oder Whitespace zwischen dem + Backslash und dem Zeilenende folgen.

    + +

    In den Konfigurationsdateien wird bei den Direktiven nicht zwischen + Groß- und Kleinschreibung unterschieden. Bei den Argumenten der + Direktiven wird dagegen oftmals zwischen Groß- und Kleinschreibung + differenziert. Zeilen, die mit dem Doppelkreuz "#" beginnen, werden als + Kommentare betrachtet und ignoriert. Kommentare dürfen + nicht am Ende einer Zeile nach der Direktive + eingefügt werden. Leerzeilen und Whitespaces vor einer Direktive + werden ignoriert. Dadurch lassen sich Direktiven zur besseren Lesbarbeit + einrücken.

    + +

    Sie können die Syntax Ihrer Konfigurationsdateien auf Fehler + prüfen, ohne den Server zu starten, indem Sie apachectl + configtest oder die Befehlszeilenoption -t + verwenden.

    +
    + +
    + Module + + + + mod_so + + + IfModule + LoadModule + + + +

    Der Apache ist ein modularer Server. Das bedeutet, dass nur die abolute + Grundfunktionalität im Kernserver enthalten ist. Weitergehende + Fähigkeiten sind mittels Modulen verfügbar, + die in den Apache geladen werden können. Standardmäßig + wird bei der Kompilierung ein Satz von Basismodulen die so + genannten Base-Module in den Server eingebunden. Wenn der + Server für die Verwendung von dynamisch + ladbaren Modulen kompiliert wurde, dann können Module separat + kompiliert und jederzeit mittels der Direktive LoadModule hinzugefügt werden. + Andernfalls muss der Apache neu kompiliert werden, um Module + hinzuzufügen oder zu entfernen. Konfigurationsanweisungen können + abhängig vom Vorhandensein eines bestimmten Moduls eingesetzt werden, + indem sie in einen IfModule-Block eingeschlossen werden.

    + +

    Um zu sehen, welche Module momentan in den Server einkompiliert sind, + kann die Befehlszeilenoption -l verwendet werden.

    +
    + +
    + Der Gültigkeitsbereich von Direktiven + + + + Directory + DirectoryMatch + Files + FilesMatch + Location + LocationMatch + VirtualHost + + + +

    Direktiven in den Hauptkonfigurationsdateien gelten für den + gesamten Server. Wenn Sie die Konfiguration nur für einen Teil des + Servers verändern möchten, können Sie den + Gültigkeitsbereich der Direktiven beschränken, indem Sie diese + in Directory-, + DirectoryMatch-, + Files-, + FilesMatch-, + Location- oder + LocationMatch-Abschnitte eingefügen. + Diese Abschnitte begrenzen die Anwendung der umschlossenen Direktiven + auf bestimmte Pfade des Dateisystems oder auf + bestimmte URLs. Sie können für eine fein abgestimmte + Konfiguration auch ineinander verschachtelt werden.

    + + +

    Der Apache besitzt die Fähigkeit, mehrere verschiedene Websites + gleichzeitig zu bedienen. Dies wird virtuelles + Hosten genannt. Direktiven können auch in ihrem + Gültigkeitsgereich eingeschränkt werden, indem sie innerhalb + eines VirtualHost-Abschnittes angegeben werden. + Sie werden dann nur auf Anfragen für eine bestimmte Website + angewendet.

    + +

    Obwohl die meisten Direktiven in jedem dieser Abschnitte platziert + werden können, ergeben einige Direktiven in manchen Kontexten + keinen Sinn. Direktiven zur Prozesssteuerung beispielsweise + dürfen nur im Kontext des Hauptservers angegeben werden. Prüfen + Sie den Kontext der + Direktive, um herauszufinden, welche Direktiven in welche Abschnitte + eingefügt werden können. Weitere Informationen finden Sie unter + "Wie Directory-, Location- und Files-Abschnitte + arbeiten".

    + +
    + +
    + .htaccess-Dateien + + + + AccessFileName + AllowOverride + + + +

    Der Apache ermöglicht die dezentrale Verwaltung der + Konfiguration mittes spezieller Dateien innerhalb des + Web-Verzeichnisbaums. Diese speziellen Dateien heißen + gewöhnlich .htaccess, mit der Direktive AccessFileName kann jedoch auch ein anderer + Name festgelegt werden. In .htaccess-Dateien angegebene + Direktiven werden auf das Verzeichnis und dessen Unterverzeichnisse + angewendet, in dem die Datei abgelegt ist. .htaccess-Dateien + folgen der gleichen Syntax wie die Hauptkonfigurationsdateien. Da + .htaccess-Dateien bei jeder Anfrage eingelesen werden, + werden Änderungen in diesen Dateien sofort wirksam.

    + +

    Prüfen Sie den Kontext der Direktive, um + herauszufinden, welche Direktiven in .htaccess-Dateien + angegeben werden können. Darüber hinaus steuert der + Serveradministrator mit der Einstellung der Direktive AllowOverride in den + Hauptkonfigurationsdateien welche Direktiven in + .htaccess-Dateien verwendet werden dürfen.

    + +

    Weitere Informationen über .htaccess-Dateien finden + Sie in der .htaccess-Einführung.

    +
    +
    diff --git a/trunk/docs/manual/configuring.xml.ja b/trunk/docs/manual/configuring.xml.ja new file mode 100644 index 0000000000..ae68f06f62 --- /dev/null +++ b/trunk/docs/manual/configuring.xml.ja @@ -0,0 +1,200 @@ + + + + + + + + + + $B@_Dj%U%!%$%k(B + + +

    $B$3$NJ8=q$G$O!"(BApache HTTP $B%5!<%P$r@_Dj$9$k$N$K;HMQ$9$k%U%!%$%k$K$D$$$F(B +$B5-=R$7$F$$$^$9!#(B

    +
    + +
    + $B%a%$%s$N@_Dj%U%!%$%k(B + + + mod_mime + + + IfDefine + Include + TypesConfig + + + +

    Apache $B$O(B $B%G%#%l%/%F%#%V(B $B$r@_Dj%U%!%$%k$KJ?J8$G=q$/$3$H$K$h$j@_Dj$7$^$9!#(B + $B%a%$%s$N@_Dj%U%!%$%k$OIaDL$O(B httpd.conf $B$H$$$&L>A0$G$9!#(B + $B$3$N%U%!%$%k$N0LCV$O%3%s%Q%$%k;~$K@_Dj$5$l$^$9$,!"%3%^%s%I%i%$%s$N(B + -f $B%U%i%0$K$h$j>e=q$-$G$-$^$9!#(B + $B$^$?!"B>$N@_Dj%U%!%$%k$r(B Include + $B%G%#%l%/%F%#%V$K$h$C$FDI2C$G$-!"%o%$%k%I%+!<%I$r;HMQ$7$FB??t$N(B + $B@_Dj%U%!%$%k$rDI2C$9$k$3$H$,$G$-$^$9!#(B + $B$I$s$J%G%#%l%/%F%#%V$b!"$3$l$i$N@_Dj%U%!%$%k$I$l$K$G$bF~$l$k$3$H$,$G$-$^$9!#(B + Apache $B$O5/F0;~$+:F5/F0;~$N$_%a%$%s@_Dj%U%!%$%k$NJQ99$rG'<1$7$^$9!#(B

    + +

    $B%5!<%P$O(B MIME + $B%I%-%e%a%s%H%?%$%W$r4^$s$G$$$k%U%!%$%k$bFI$_9~$_$^$9!#%U%!%$%kL>$O(B + TypesConfig + $B$G@_Dj$5$l!"%G%U%)%k%H$G$O(B mime.types + $B$K$J$C$F$$$^$9!#(B

    +
    + +
    + $B@_Dj%U%!%$%k$N9=J8(B + +

    Apache $B$N@_Dj%U%!%$%k$O(B 1 $B9T$K(B 1 $B$D$N%G%#%l%/%F%#%V$+$i$J$j$^$9!#(B + $B%P%C%/%9%i%C%7%e(B "\" $B$O%G%#%l%/%F%#%V$,$NJ8;z$d6uGr$,$"$C$F$O$$$1$^$;$s!#(B +

    + +

    $B@_Dj%U%!%$%k$N%G%#%l%/%F%#%V$OBgJ8;z>.J8;z$r6hJL$7$^$;$s$,!"(B + $B0z?t$K$O$7$P$7$P6hJL$9$k$b$N$,$"$j$^$9!#%O%C%7%eJ8;z(B "#" + $B$G;O$^$k9T$O%3%a%s%H$H8+$J$5$l$FL5;k$5$l$^$9!#(B + $B@_Dj%G%#%l%/%F%#%V$N8e$N9T$G$O%3%a%s%H$,4^$^$l$F$$$F$O(B$B$$$1$^$;$s(B$B!#%G%#%l%/%F%#%V$NA0$N6u9T$H6uGr$OL5;k$5$l$^$9$N$G!"(B + $B$o$+$j$d$9$/$9$k$?$a$K%G%#%l%/%F%#%V$r%$%s%G%s%H$7$F$b9=$$$^$;$s!#(B +

    + +

    $B@_Dj%U%!%$%k$N9=J8%(%i!<$O!"(B + apachectl configtest + $B$+%3%^%s%I%i%$%s%*%W%7%g%s(B + -t $B$r;H$C$FD4$Y$i$l$^$9!#(B

    +
    + +
    + $B%b%8%e!<%k(B + + + + mod_so + + + IfModule + LoadModule + + + +

    Apache $B$O%b%8%e!<%k2=$5$l$?%5!<%P$G$9!#(B + $B%3%"%5!<%P$K$O:G$b4pK\E*$J5!G=$@$1$,4^$^$l$F$$$^$9!#3HD%5!G=$O(B + Apache $B$K%m!<%I$5$l$k(B$B%b%8%e!<%k(B$B$H$7$FMxMQ2DG=$G$9!#%G%U%)%k%H$G$O!"%3%s%Q%$%k;~$K%b%8%e!<%k$N(B + Base $B%;%C%H(B ($B4pK\%;%C%H(B) $B$,(B + $B%5!<%P$K4^$^$l$^$9!#%5!<%P$,(B$BF0E*%m!<%I(B$B%b%8%e!<%k$r;H$&$h$&$K%3%s%Q%$%k$5$l$F$$$k>l9g$O!"(B + $B%b%8%e!<%k$rJL$K%3%s%Q%$%k$7$F!"$$$D$G$b(B + LoadModule + $B%G%#%l%/%F%#%V$r;H$C$FDI2C$G$-$^$9!#(B + $B$=$&$G$J$$>l9g$O!"%b%8%e!<%k$NDI2C$d:o=|$r$9$k$?$a$K$O(B Apache + $B$r:F%3%s%Q%$%k$9$kI,MW$,$"$j$^$9!#@_Dj%G%#%l%/%F%#%V$O(B IfModule + $B%V%m%C%/$KF~$l$k$3$H$GFCDj$N%b%8%e!<%k$,B8:_$9$k$H$-$@$1(B + $B@_Dj%U%!%$%k$K4^$^$l$k$h$&$K$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B%3%^%s%I%i%$%s%*%W%7%g%s(B -l $B$r;H$C$F8=;~E@$G(B + $B$I$N%b%8%e!<%k$,%5!<%P$K%3%s%Q%$%k$5$l$F$$$k$+$rCN$k$3$H$,$G$-$^$9!#(B

    +
    + +
    + $B%G%#%l%/%F%#%V$NE,MQHO0O(B + + + + Directory + DirectoryMatch + Files + FilesMatch + Location + LocationMatch + VirtualHost + + + +

    $B%a%$%s@_Dj%U%!%$%k$K$"$k%G%#%l%/%F%#%V$O%5!<%PA4BN$KE,MQ$5$l$^$9!#(B + $B%5!<%P$N0lItJ,$N@_Dj$@$1$rJQ99$7$?$$>l9g$O(B Directory, DirectoryMatch, Files, FilesMatch, Location, LocationMatch + $B%;%/%7%g%s$NCf$KCV$/$3$H$GE,MQHO0O$r7h$a$i$l$^$9!#(B + $B$3$l$i$N%;%/%7%g%s$O$=$NCf$K$"$k%G%#%l%/%F%#%V$NE,MQHO0O$r(B + $BFCDj$N%U%!%$%k%7%9%F%`$N0LCV$d(B URL $B$K8BDj$7$^$9!#(B + $BHs>o$K:YN3EY$N@_Dj$r2DG=$K$9$k$?$a$K!"(B + $B%;%/%7%g%s$rF~$l;R$K$9$k$3$H$b$G$-$^$9!#(B

    + +

    Apache $B$OF1;~$KB?$/$N0c$&%&%'%V%5%$%H$r07$&G=NO$,$"$j$^$9!#(B + $B$3$l$O(B $B%P!<%A%c%k%[%9%H(B $B$H8F$P$l$F$$$^$9!#(B + $BFCDj$N%&%'%V%5%$%H$K$N$_E,MQ$5$l$k$h$&$K$9$k$?$a$K!"(B + $B%G%#%l%/%F%#%V$O(B + VirtualHost + $B%;%/%7%g%s$NCf$KCV$/$3$H$G$bE,MQHO0O$rJQ$($k$3$H$,$G$-$^$9!#(B

    + +

    $B$[$H$s$I$N%G%#%l%/%F%#%V$O$I$N%;%/%7%g%s$K$G$b=q$1$^$9$,!"(B + $BCf$K$O%3%s%F%-%9%H$K$h$C$F$O0UL#$r$J$5$J$$$b$N$b$"$j$^$9!#(B + $BNc$($P!"%W%m%;%9$N:n@.$r@)8f$7$F$$$k%G%#%l%/%F%#%V$O%a%$%s%5!<%P$N(B + $B%3%s%F%-%9%H$K$N$_=q$/$3$H$,$G$-$^$9!#(B + $B$I$N%G%#%l%/%F%#%V$r$I$N%;%/%7%g%s$K=q$/$3$H$,$G$-$k$+$rCN$k$?$a$K$O(B + $B%G%#%l%/%F%#%V$N(B $B%3%s%F%-%9%H(B $B$rD4$Y$F$/$@$5$$!#>\$7$$>pJs$O!"(B + Directory, Location, Files + $B%;%/%7%g%s$NF0:nK!(B$B$K$"$j$^$9!#(B

    +
    + +
    + .htaccess $B%U%!%$%k(B + + + + AccessFileName + AllowOverride + + + +

    Apache $B$G$O%&%'%V%D%j!<$NCf$KCV$+$l$?FCJL$J%U%!%$%k$r;H$C$F(B + $BHsCf1{=88"E*$J@_Dj4IM}$r$G$-$^$9!#$=$NFCJL$J%U%!%$%k$OIaDL$O(B + .htaccess $B$H$$$&L>A0$G!"(B + AccessFileName + $B%G%#%l%/%F%#%V$G$I$s$JL>A0$K$G$b;XDj$G$-$^$9!#(B + .htaccess + $B%U%!%$%k$K=q$+$l$?%G%#%l%/%F%#%V$O%U%!%$%k$rCV$$$?(B + $B%G%#%l%/%H%j$H$=$NA4$F$N%5%V%G%#%l%/%H%j$KE,MQ$5$l$^$9!#(B + .htaccess + $B%U%!%$%k$O$9$Y$F$N%j%/%(%9%H$GFI$_9~$^$l$k$?$a!"(B + $BJQ99$O$9$0$KH?1G$5$l$^$9!#(B

    + +

    $B$I$N%G%#%l%/%F%#%V$,(B .htaccess + $B%U%!%$%k$K=q$1$k$+$rD4$Y$k$K$O!"%G%#%l%/%F%#%V$N(B$B%3%s%F%-%9%H(B + $B$rD4$Y$F$/$@$5$$!#%5!<%P4IM}AllowOverride + $B$r@_Dj$9$k$3$H$G$I$N%G%#%l%/%F%#%V$r(B .htaccess + $B%U%!%$%k$K=q$1$k$h$&$K$9$k$+$r@)8f$9$k$3$H$,$G$-$^$9!#(B

    + +

    .htaccess $B%U%!%$%k$K4X$9$k>\$7$$>pJs$O(B + .htaccess $B%A%e!<%H%j%"%k(B + $B$r;2>H$7$F$/$@$5$$!#(B

    +
    +
    diff --git a/trunk/docs/manual/configuring.xml.ko b/trunk/docs/manual/configuring.xml.ko new file mode 100644 index 0000000000..e7afcfb825 --- /dev/null +++ b/trunk/docs/manual/configuring.xml.ko @@ -0,0 +1,183 @@ + + + + + + + + + + ¼³Á¤ÆÄÀÏ + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¼³Á¤ÇÏ´Â ÆÄÀϵéÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    + ÁÖ¼³Á¤ÆÄÀÏ + + + mod_mime + + + IfDefine + Include + TypesConfig + + + +

    ÀÏ¹Ý ¹®¼­ ÆÄÀÏÀÎ ¼³Á¤ÆÄÀÏ¿¡ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ¼³Á¤ÇÑ´Ù. ÁÖ¼³Á¤ÆÄÀÏÀ» º¸Åë httpd.conf¶ó°í + ºÎ¸¥´Ù. ÀÌ ÆÄÀÏÀÇ À§Ä¡´Â ÄÄÆÄÀϽà Á¤ÇØÁö³ª, -f + ¸í·ÉÇà ¿É¼ÇÀ¸·Î ÁöÁ¤ÇØÁÙ ¼ö ÀÖ´Ù. ¶Ç ´Ù¸¥ ¼³Á¤ÆÄÀÏÀ» Include Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Æ÷ÇÔÇÒ + ¼ö ÀÖ°í, ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ¿© ¸¹Àº ¼³Á¤ÆÄÀÏÀ» Æ÷ÇÔÇÒ ¼öµµ + ÀÖ´Ù. ÀÌ °æ¿ì Áö½Ã¾î¸¦ ¾î¶² ¼³Á¤ÆÄÀÏ¿¡³ª »ç¿ëÇصµ µÈ´Ù. + ÁÖ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÏ¸é ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϰųª Àç½ÃÀÛÇÑ ÀÌÈÄ¿¡ + ¹Ý¿µµÈ´Ù.

    + +

    ¼­¹ö´Â mime ¹®¼­Å¸ÀÔÀ» ´ãÀº ÆÄÀϵµ Àд´Ù. ÆÄÀϸíÀº + TypesConfig Áö½Ã¾î·Î + ¼³Á¤ÇÏ°í, ±âº»°ªÀº mime.typesÀÌ´Ù.

    +
    + +
    + ¼³Á¤ÆÄÀÏ ¹®¹ý + +

    ¾ÆÆÄÄ¡ ¼³Á¤ÆÄÀÏÀº ÇÑÁÙ¿¡ ÇÑ Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ÁÙ ¸¶Áö¸· + ¹®ÀÚ°¡ ¹é½½·¡½¬ "\"À̸é Áö½Ã¾î°¡ ´ÙÀ½ ÁÙ¿¡¼­ °è¼ÓµÊÀ» ¶æÇÑ´Ù. + ÀÌ °æ¿ì ¹é½½·¡½¬ µÚ¿¡ ¾î¶² ¹®ÀÚ³ª °ø¹éµµ ³ª¿À¸é ¾ÈµÈ´Ù.

    + +

    ¼³Á¤ÆÄÀÏÀÇ Áö½Ã¾î´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö ¾ÊÁö¸¸, Áö½Ã¾îÀÇ + ¾Æ±Ô¸ÕÆ®´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏ´Â °æ¿ì°¡ ÀÖ´Ù. Çؽ¬¹®ÀÚ "#"·Î + ½ÃÀÛÇÏ´Â ÁÙÀº ÁÖ¼®À¸·Î ¹«½ÃÇÑ´Ù. ÁÖ¼®À» ¼³Á¤ Áö½Ã¾î¿Í °°Àº + ÁÙ¿¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. ºóÁÙ°ú Áö½Ã¾î ¾Õ¿¡ ³ª¿À´Â + °ø¹éÀº ¹«½ÃÇϹǷÎ, °£°áÇÏ°Ô º¸À̵µ·Ï Áö½Ã¾î¸¦ ÁÙµéÀÓÇÒ(indent) + ¼ö ÀÖ´Ù.

    + +

    apachectl configtest³ª -t ¸í·ÉÇà + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏÁö ¾Ê°íµµ ¼³Á¤ÆÄÀÏÀÇ ¹®¹ý + ¿À·ù¸¦ °Ë»çÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    + ¸ðµâ + + + + mod_so + + + IfModule + LoadModule + + + +

    ¾ÆÆÄÄ¡´Â ¸ðµâÈ­µÈ ¼­¹ö´Ù. ÀÌ´Â ¸Å¿ì ±âº»ÀûÀÎ ±â´É¸¸ÀÌ + ¼­¹ö Çٽɿ¡ Æ÷ÇÔµÇÀÖÀ½À» ¶æÇÑ´Ù. ¾ÆÆÄÄ¡´Â ¸ðµâÀ» Àоîµé¿©¼­ ±â´ÉÀ» + È®ÀåÇÑ´Ù. ±âº»ÀûÀ¸·Î ÄÄÆÄÀÏÇÏ¸é ¼­¹ö¿¡ base ¸ðµâµéÀÌ Æ÷ÇԵȴÙ. + ¼­¹ö¸¦ µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â ¸ðµâÀ» + »ç¿ëÇÒ ¼ö ÀÖ°Ô ÄÄÆÄÀÏÇÏ¿´´Ù¸é ¸ðµâÀ» µû·Î ÄÄÆÄÀÏÇÏ¿© ¾Æ¹«¶§³ª + LoadModule Áö½Ã¾î·Î + Ãß°¡ÇÒ ¼ö ÀÖ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ¸ðµâÀ» Ãß°¡Çϰųª »©±âÀ§ÇØ + ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. ¼³Á¤ Áö½Ã¾î¸¦ IfModule ºí·ÏÀ¸·Î °¨½Î¼­ ƯÁ¤ + ¸ðµâÀÌ ÀÖ´Â °æ¿ì¿¡¸¸ ¼±ÅÃÀûÀ¸·Î ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÇöÀç ¼­¹ö¿¡ ¾î¶² ¸ðµâÀÌ ÄÄÆÄÀϵÇÀÖ´ÂÁö º¸·Á¸é -l + ¸í·ÉÇà ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.

    +
    + +
    + Áö½Ã¾î Àû¿ë¹üÀ§ + + + + Directory + DirectoryMatch + Files + FilesMatch + Location + LocationMatch + VirtualHost + + + +

    ÁÖ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î´Â ¼­¹ö Àüü¿¡ Àû¿ëµÈ´Ù. Áö½Ã¾î°¡ + ¼­¹öÀÇ ÀϺο¡¸¸ Àû¿ëµÇ°Ô ÇÏ·Á¸é Áö½Ã¾î¸¦ Directory, DirectoryMatch, Files, FilesMatch, Location, LocationMatch ¼½¼Ç ¾È¿¡ µÎ¾î¾ßÇÑ´Ù. + ÀÌ ¼½¼ÇµéÀº ±×µéÀÌ °¨½Î´Â Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ ÆÄÀϽýºÅÛÀ̳ª + URLÀÇ Æ¯Á¤ À§Ä¡·Î ÇÑÁ¤ÇÑ´Ù. ¶Ç, ¼­·Î °ãÃļ­ »ç¿ëÇÒ ¼ö Àֱ⶧¹®¿¡ + ¸Å¿ì ¼¼¹ÐÇÑ ¼³Á¤ÀÌ °¡´ÉÇÏ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ¿©·¯ ´Ù¸¥ À¥»çÀÌÆ®¸¦ µ¿½Ã¿¡ ¼­ºñ½ºÇÏ´Â + ´É·ÂÀÌ ÀÖ´Ù. À̸¦ °¡»óÈ£½ºÆ®¶ó°í ÇÑ´Ù. + Áö½Ã¾î¸¦ + VirtualHost + ¼½¼Ç ¾È¿¡ µÎ¾î ƯÁ¤ À¥»çÀÌÆ®¿¡¸¸ Áö½Ã¾î¸¦ Àû¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    Áö½Ã¾î´Â ´ëºÎºÐ ¾î¶² ¼½¼Ç¿¡ ³ª¿Íµµ µÇÁö¸¸, ¾î¶² Áö½Ã¾î´Â + ƯÁ¤ Àå¼Ò¿¡¼­ Àǹ̰¡ ¾ø´Ù. ¿¹¸¦ µé¾î ÇÁ·Î¼¼½º »ý¼ºÀ» Á¶ÀýÇÏ´Â + Áö½Ã¾î´Â ÁÖ¼­¹ö¼³Á¤ Àå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î°¡ + ¾î¶² ¼½¼Ç¿¡ À§Ä¡ÇÒ ¼ö ÀÖ´ÂÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ È®ÀÎÇ϶ó. + ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â ¾î¶»°Ô Directory, + Location, Files ¼½¼ÇÀÌ µ¿ÀÛÇϳª¸¦ Âü°íÇ϶ó.

    +
    + +
    + .htaccess ÆÄÀÏ + + + + AccessFileName + AllowOverride + + + +

    ¾ÆÆÄÄ¡´Â Ưº°ÇÑ ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¼³Á¤À» + ³ª´²¼­(ºÐ±ÇÀûÀ¸·Î) °ü¸®ÇÒ ¼ö ÀÖ´Ù. ÀÌ Æ¯º°ÇÑ ÆÄÀÏÀ» º¸Åë + .htaccess¶ó°í ºÎ¸£Áö¸¸, À̸§Àº AccessFileName Áö½Ã¾î·Î + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î´Â + ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ Àû¿ëµÈ´Ù. + .htaccess ÆÄÀÏÀº ÁÖ¼³Á¤ÆÄÀÏ°ú °°Àº ¹®¹ýÀ» + µû¸¥´Ù. .htaccess ÆÄÀÏÀº ¸Å ¿äû¶§¸¶´Ù Àб⶧¹®¿¡ + ÆÄÀÏÀ» ¼öÁ¤Çϸé Áï½Ã È¿°ú¸¦ º¼ ¼ö ÀÖ´Ù.

    + +

    ¾î¶² Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡ »ç¿ëÇÒ ¼ö + ÀÖ´ÂÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó. ¼­¹ö °ü¸®ÀÚ´Â ÁÖ¼³Á¤ÆÄÀÏÀÇ AllowOverride Áö½Ã¾î·Î + .htaccess ÆÄÀÏ¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + Á¶ÀýÇÒ ¼ö ÀÖ´Ù.

    + +

    .htaccess ÆÄÀÏ¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â + .htaccess ÅõÅ丮¾óÀ» + Âü°íÇ϶ó.

    +
    +
    diff --git a/trunk/docs/manual/configuring.xml.meta b/trunk/docs/manual/configuring.xml.meta new file mode 100644 index 0000000000..201286fae5 --- /dev/null +++ b/trunk/docs/manual/configuring.xml.meta @@ -0,0 +1,14 @@ + + + + configuring + / + . + + + de + en + ja + ko + + diff --git a/trunk/docs/manual/content-negotiation.html b/trunk/docs/manual/content-negotiation.html new file mode 100644 index 0000000000..3fbf5ee048 --- /dev/null +++ b/trunk/docs/manual/content-negotiation.html @@ -0,0 +1,11 @@ +URI: content-negotiation.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: content-negotiation.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: content-negotiation.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/content-negotiation.html.en b/trunk/docs/manual/content-negotiation.html.en new file mode 100644 index 0000000000..9e3422187b --- /dev/null +++ b/trunk/docs/manual/content-negotiation.html.en @@ -0,0 +1,678 @@ + + + +Content Negotiation - Apache HTTP Server + + + + + +
    <-
    +

    Content Negotiation

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    Apache supports content negotiation as described in + the HTTP/1.1 specification. It can choose the best + representation of a resource based on the browser-supplied + preferences for media type, languages, character set and + encoding. It also implements a couple of features to give + more intelligent handling of requests from browsers that send + incomplete negotiation information.

    + +

    Content negotiation is provided by the + mod_negotiation module, which is compiled in + by default.

    +
    + +
    top
    +
    +

    About Content Negotiation

    + +

    A resource may be available in several different + representations. For example, it might be available in + different languages or different media types, or a combination. + One way of selecting the most appropriate choice is to give the + user an index page, and let them select. However it is often + possible for the server to choose automatically. This works + because browsers can send, as part of each request, information + about what representations they prefer. For example, a browser + could indicate that it would like to see information in French, + if possible, else English will do. Browsers indicate their + preferences by headers in the request. To request only French + representations, the browser would send

    + +

    Accept-Language: fr

    + +

    Note that this preference will only be applied when there is + a choice of representations and they vary by language.

    + +

    As an example of a more complex request, this browser has + been configured to accept French and English, but prefer + French, and to accept various media types, preferring HTML over + plain text or other text types, and preferring GIF or JPEG over + other media types, but also allowing any other media type as a + last resort:

    + +

    + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +

    + +

    Apache supports 'server driven' content negotiation, as + defined in the HTTP/1.1 specification. It fully supports the + Accept, Accept-Language, + Accept-Charset andAccept-Encoding + request headers. Apache also supports 'transparent' + content negotiation, which is an experimental negotiation + protocol defined in RFC 2295 and RFC 2296. It does not offer + support for 'feature negotiation' as defined in these RFCs.

    + +

    A resource is a conceptual entity + identified by a URI (RFC 2396). An HTTP server like Apache + provides access to representations 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 negotiable and each of its + representations is termed a variant. The ways + in which the variants for a negotiable resource vary are called + the dimensions of negotiation.

    +
    top
    +
    +

    Negotiation in Apache

    + +

    In order to negotiate a resource, the server needs to be + given information about each of the variants. This is done in + one of two ways:

    + +
      +
    • Using a type map (i.e., a *.var + file) which names the files containing the variants + explicitly, or
    • + +
    • Using a 'MultiViews' search, where the server does an + implicit filename pattern match and chooses from among the + results.
    • +
    + +

    Using a type-map file

    + +

    A type map is a document which is associated with the + handler named type-map (or, for + backwards-compatibility with older Apache configurations, the + MIME type application/x-type-map). Note that to + use this feature, you must have a handler set in the + configuration that defines a file suffix as + type-map; this is best done with

    + +

    AddHandler type-map .var

    + +

    in the server configuration file.

    + +

    Type map files should have the same name as the resource + which they are describing, and have an entry for each available + variant; these entries 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 shown below. + This file would be named foo.var, as it describes + a resource named foo.

    + +

    + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +

    +

    Note also that a typemap file will take precedence over the + filename's extension, even when Multiviews is on. 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):

    + +

    + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +

    + +

    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. 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.

    + +

    The full list of headers recognized is available in the mod_negotation + typemap documentation.

    + + +

    Multiviews

    + +

    MultiViews is a per-directory option, meaning it + can be set with an Options + directive within a <Directory>, <Location> or <Files> section in + httpd.conf, or (if AllowOverride is properly set) in + .htaccess files. Note that Options All + does not set MultiViews; you have to ask for it by + name.

    + +

    The effect of MultiViews is as follows: if the + server receives a request for /some/dir/foo, if + /some/dir has MultiViews enabled, and + /some/dir/foo does not exist, then the + server reads the directory looking for files named foo.*, and + effectively fakes up a 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.

    + +

    MultiViews may also apply to searches for the file + named by the DirectoryIndex directive, if the + server is trying to index a directory. If the configuration files + specify

    +

    DirectoryIndex index

    +

    then the server will arbitrate between index.html + and index.html3 if both are present. If neither + are present, and index.cgi is there, the server + will run it.

    + +

    If one of the files found when reading the directory does not + have an extension recognized by mod_mime to designate + its Charset, Content-Type, Language, or Encoding, then the result + depends on the setting of the MultiViewsMatch directive. This + directive determines whether handlers, filters, and other + extension types can participate in MultiViews negotiation.

    + +
    top
    +
    +

    The Negotiation Methods

    + +

    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 invokes one of two methods to decide on the + 'best' variant to return, if any. It is not necessary to know + any of the details of how negotiation actually takes place in + order to use Apache's content negotiation features. However the + rest of this document explains the methods used for those + interested.

    + +

    There are two negotiation methods:

    + +
      +
    1. Server driven negotiation with the Apache + algorithm is used in the normal case. The Apache + algorithm is explained in more detail below. When this + algorithm is used, Apache can sometimes 'fiddle' the quality + factor of a particular dimension to achieve a better result. + The ways Apache can fiddle quality factors is explained in + more detail below.
    2. + +
    3. Transparent content negotiation is used + when the browser specifically requests this through the + mechanism defined in RFC 2295. This negotiation method gives + the browser full control over deciding on the 'best' variant, + the result is therefore dependent on the specific algorithms + used by the browser. As part of the transparent negotiation + process, the browser can ask Apache to run the 'remote + variant selection algorithm' defined in RFC 2296.
    4. +
    + +

    Dimensions of Negotiation

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DimensionNotes
    Media TypeBrowser indicates preferences with the Accept + header field. Each item can have an associated quality factor. + Variant description can also have a quality factor (the "qs" + parameter).
    LanguageBrowser 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.
    EncodingBrowser indicates preference with the + Accept-Encoding header field. Each item can have + a quality factor.
    CharsetBrowser 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.
    + + +

    Apache Negotiation Algorithm

    + +

    Apache can use the following algorithm to select the 'best' + variant (if any) to return to the browser. This algorithm is + not further configurable. It operates as follows:

    + +
      +
    1. First, for each dimension of the negotiation, check the + appropriate Accept* header field and assign a + quality to each variant. If the Accept* header for + any dimension implies that this variant is not acceptable, + eliminate it. If no variants remain, go to step 4.
    2. + +
    3. + Select the 'best' variant by a process of elimination. Each + of the following tests is applied in order. Any variants + not selected at each test are eliminated. After each test, + if only one variant remains, select it as the best match + and proceed to step 3. If more than one variant remains, + move on to the next test. + +
        +
      1. Multiply the quality factor from the Accept + header with the quality-of-source factor for this variants + media type, and select the variants with the highest + value.
      2. + +
      3. Select the variants with the highest language quality + factor.
      4. + +
      5. Select the variants with the best language match, + using either the order of languages in the + Accept-Language header (if present), or else + the order of languages in the LanguagePriority + directive (if present).
      6. + +
      7. Select the variants with the highest 'level' media + parameter (used to give the version of text/html media + types).
      8. + +
      9. Select variants with the best charset media + parameters, as given on the Accept-Charset + header line. Charset ISO-8859-1 is acceptable unless + explicitly excluded. Variants with a text/* + media type but not explicitly associated with a particular + charset are assumed to be in ISO-8859-1.
      10. + +
      11. Select those variants which have associated charset + media parameters that are not ISO-8859-1. If + there are no such variants, select all variants + instead.
      12. + +
      13. 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 and non-encoded variants, + select only the unencoded variants. If either all + variants are encoded or all variants are not encoded, + select all variants.
      14. + +
      15. Select the variants with the smallest content + length.
      16. + +
      17. Select the first variant of those remaining. This + will be either the first listed in the type-map file, or + when variants are read from the directory, the one whose + file name comes first when sorted using ASCII code + order.
      18. +
      +
    4. + +
    5. The algorithm has now selected one 'best' variant, so + return it as the response. The HTTP response header + Vary is set to indicate the dimensions of + negotiation (browsers and caches can use this information when + caching the resource). End.
    6. + +
    7. 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 dimensions of variance.
    8. +
    + +
    top
    +
    +

    Fiddling with Quality + Values

    + +

    Apache sometimes changes the quality values from what would + be expected by a strict interpretation of the Apache + negotiation algorithm above. This is to get a better result + from the algorithm for browsers which do not send full or + accurate information. Some of the most popular browsers send + Accept header information which would otherwise + result in the selection of the wrong variant in many cases. If a + browser sends full and correct information these fiddles will not + be applied.

    + +

    Media Types and Wildcards

    + +

    The Accept: request header indicates preferences + for media types. It can also include 'wildcard' media types, such + as "image/*" or "*/*" where the * matches any string. So a request + including:

    + +

    Accept: image/*, */*

    + +

    would indicate that any type starting "image/" is acceptable, + as is any other type. + Some browsers routinely send wildcards in addition to explicit + types they can handle. For example:

    + +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */* +

    +

    The intention of this is to indicate that the explicitly listed + types are preferred, but if a different representation is + available, that is ok too. Using explicit quality values, + what the browser really wants is something like:

    +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 +

    +

    The explicit types have no quality factor, so they default to a + preference of 1.0 (the highest). The wildcard */* is given a + low preference of 0.01, so other types will only be returned if + no variant matches an explicitly listed type.

    + +

    If the Accept: header contains no q + factors at all, Apache sets the q value of "*/*", if present, to + 0.01 to emulate the desired behavior. It also sets the q value of + wildcards of the format "type/*" to 0.02 (so these are preferred + over matches against "*/*". If any media type on the + Accept: header contains a q factor, these special + values are not applied, so requests from browsers which + send the explicit information to start with work as expected.

    + + +

    Language Negotiation Exceptions

    + +

    New in Apache 2.0, some exceptions have been added to the + negotiation algorithm to allow graceful fallback when language + negotiation fails to find a match.

    + +

    When a client requests a page on your server, but the server + cannot find a single page that matches the + Accept-language sent by + the browser, the server will return either a "No Acceptable + Variant" or "Multiple Choices" response to the client. To avoid + these error messages, it is possible to configure Apache to ignore + the Accept-language in these cases and provide a + document that does not explicitly match the client's request. The + ForceLanguagePriority + directive can be used to override one or both of these error + messages and substitute the servers judgement in the form of the + LanguagePriority + directive.

    + +

    The server will also attempt to match language-subsets when no + other match can be found. For example, if a client requests + documents with the language en-GB for British + English, the server is not normally allowed by the HTTP/1.1 + standard to match that against a document that is marked as simply + en. (Note that it is almost surely a configuration + error to include en-GB and not en in the + Accept-Language header, since it is very unlikely + that a reader understands British English, but doesn't understand + English in general. Unfortunately, many current clients have + default configurations that resemble this.) However, if no other + language match is possible and the server is about to return a "No + Acceptable Variants" error or fallback to the LanguagePriority, the server + will ignore the subset specification and match en-GB + against en documents. Implicitly, Apache will add + the parent language to the client's acceptable language list with + a very low quality value. But note that if the client requests + "en-GB; q=0.9, fr; q=0.8", and the server has documents + designated "en" and "fr", then the "fr" document will be returned. + This is necessary to maintain compliance with the HTTP/1.1 + specification and to work effectively with properly configured + clients.

    + +

    In order to support advanced techniques (such as cookies or + special URL-paths) to determine the user's preferred language, + since Apache 2.0.47 mod_negotiation recognizes + the environment variable + prefer-language. If it exists and contains an + appropriate language tag, mod_negotiation will + try to select a matching variant. If there's no such variant, + the normal negotiation process applies.

    + +

    Example

    + SetEnvIf Cookie "language=(.+)" prefer-language=$1 +

    + +
    top
    +
    +

    Extensions to Transparent Content +Negotiation

    + +

    Apache extends the transparent content negotiation protocol (RFC +2295) as follows. A new {encoding ..} element is used in +variant lists to label variants which are available with a specific +content-encoding only. The implementation of the RVSA/1.0 algorithm +(RFC 2296) is extended to recognize encoded variants in the list, and +to use them as candidate variants whenever their encodings are +acceptable according to the Accept-Encoding request +header. The RVSA/1.0 implementation does not round computed quality +factors to 5 decimal places before choosing the best variant.

    +
    top
    +
    +

    Note on hyperlinks and naming conventions

    + +

    If you are using language negotiation you can choose between + different naming conventions, because files can have more than + one extension, and the order of the extensions is normally + irrelevant (see the mod_mime documentation + for details).

    + +

    A typical file has a MIME-type extension (e.g., + html), maybe an encoding extension (e.g., + gz), and of course a language extension + (e.g., en) when we have different + language variants of this file.

    + +

    Examples:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    Here some more examples of filenames together with valid and + invalid hyperlinks:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FilenameValid hyperlinkInvalid hyperlink
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    Looking at the table above, you will notice that it is always + possible to use the name without any extensions in a hyperlink + (e.g., foo). The advantage is that you + can hide the actual type of a document rsp. file and can change + it later, e.g., from html to + shtml or cgi without changing any + hyperlink references.

    + +

    If you want to continue to use a MIME-type in your + hyperlinks (e.g. foo.html) the language + extension (including an encoding extension if there is one) + must be on the right hand side of the MIME-type extension + (e.g., foo.html.en).

    +
    top
    +
    +

    Note on Caching

    + +

    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 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.

    + +

    For requests which come from a HTTP/1.0 compliant client + (either a browser or a cache), the directive CacheNegotiatedDocs 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.

    + +

    For HTTP/1.1 clients, Apache sends a Vary HTTP + response header to indicate the negotiation dimensions for the + response. Caches can use this information to determine whether a + subsequent request can be served from the local copy. To + encourage a cache to use the local copy regardless of the + negotiation dimensions, set the force-no-vary environment variable.

    + +
    top
    +
    +

    More Information

    + +

    For more information about content negotiation, see Alan + J. Flavell's Language + Negotiation Notes. But note that this document may not be + updated to include changes in Apache 2.0.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/content-negotiation.html.ja.euc-jp b/trunk/docs/manual/content-negotiation.html.ja.euc-jp new file mode 100644 index 0000000000..286fdf122c --- /dev/null +++ b/trunk/docs/manual/content-negotiation.html.ja.euc-jp @@ -0,0 +1,727 @@ + + + +¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    Apache ¤Ï HTTP/1.1 ¤Îµ¬³Ê¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò + ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£ + ¥Ö¥é¥¦¥¶¤Ë¤è¤êÄ󶡤µ¤ì¤¿¥á¥Ç¥£¥¢¥¿¥¤¥×¡¢ + ¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ÎÍ¥Àè·¹¸þ¤Ë´ð¤Å¤¤¤Æ¡¢ + ºÇŬ¤Ê¥ê¥½¡¼¥¹¤Îɽ¸½¤òÁªÂò¤Ç¤­¤Þ¤¹¡£ + ¤Þ¤¿¡¢ÉÔ´°Á´¤Ê¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¾ðÊó¤òÁ÷¤Ã¤Æ¤¯¤ë¥Ö¥é¥¦¥¶¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ò + ¤â¤Ã¤È¸­¤¯¼è¤ê°·¤¨¤ë¤è¤¦¡¢¤¤¤¯¤Ä¤«µ¡Ç½¤â¼ÂÁõ¤·¤Æ¤¢¤ê¤Þ¤¹¡£

    + +

    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ï + mod_negotiation + ¥â¥¸¥å¡¼¥ë¤Ë¤è¤Ã¤ÆÄ󶡤µ¤ì¤Æ¤¤¤Æ¡¢¥Ç¥Õ¥©¥ë¥È¤ÇÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ë¤Ä¤¤¤Æ

    + +

    ¥ê¥½¡¼¥¹¤Ï¡¢´ö¤Ä¤«°Û¤Ê¤Ã¤¿É½¸½¤ÇÍøÍѤǤ­¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢°Û¤Ê¤ë¸À¸ì¤ä°Û¤Ê¤ë¥á¥Ç¥£¥¢¥¿¥¤¥×¡¢ + ¤Þ¤¿¤Ï¤½¤ì¤é¤ÎÁȤ߹ç¤ï¤»¤ÇÍøÍѤǤ­¤ë¤«¤âÃΤì¤Þ¤»¤ó¡£ + ¤â¤Ã¤È¤âŬ¤·¤¿ÁªÂò¤ò¤¹¤ëÊýË¡¤Î°ì¤Ä¤Ë¤Ï¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¥Ú¡¼¥¸¤ò + ¥æ¡¼¥¶¤Ë¸«¤»¤Æ¡¢¥æ¡¼¥¶¤ËÁª¤ó¤Ç¤â¤é¤¦ÊýË¡¤¬¤¢¤ê¤Þ¤¹¡£ + ¤·¤«¤·¡¢¥µ¡¼¥Ð¤¬¼«Æ°Åª¤ËÁª¤Ö¤³¤È¤¬¤Ç¤­¤ë¾ì¹ç¤¬Â¿¤¯¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥Ö¥é¥¦¥¶¤¬¥ê¥¯¥¨¥¹¥ÈËè¤Ë¡¢ + ¤É¤Îɽ¸½¤òÓϹ¥¤¹¤ë¤«¤È¤¤¤¦¾ðÊó¤òÁ÷¤ë¤³¤È¤ÇÆ°ºî¤·¤Æ¤¤¤Þ¤¹¡£ + Î㤨¤Ð¥Ö¥é¥¦¥¶¤Ï¡¢²Äǽ¤Ê¤é¥Õ¥é¥ó¥¹¸ì¤Ç¾ðÊó¤ò¸«¤¿¤¤¡¢ + ÉÔ²Äǽ¤Ê¤é¤½¤ÎÂå¤ï¤ê¤Ë±Ñ¸ì¤Ç¤â¤è¤¤¤È¡¢ + ¼«Ê¬¤ÎÓϹ¥¤òÃΤ餻¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥Ö¥é¥¦¥¶¤Ï¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤Ç¼«Ê¬¤ÎÍ¥Àè·¹¸þ¤òÃΤ餻¤Þ¤¹¡£ + ¥Õ¥é¥ó¥¹¸ì¤Î¤ß¤Îɽ¸½¤òÍ׵᤹¤ë¾ì¹ç¤Ï¡¢¥Ö¥é¥¦¥¶¤Ï¼¡¤òÁ÷¤ê¤Þ¤¹¡£

    + +

    Accept-Language: fr

    + +

    ¤³¤ÎÍ¥Àè·¹¸þ¤Ï¡¢ÁªÂò²Äǽ¤Êɽ¸½¤¬Â¸ºß¤·¤Æ¡¢ + ¸À¸ì¤Ë¤è¤Ã¤ÆÍÍ¡¹¤Êɽ¸½¤¬¤¢¤ë¾ì¹ç¤Ë¤Î¤ßŬÍѤµ¤ì¤ë + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¤â¤Ã¤ÈÊ£»¨¤Ê¥ê¥¯¥¨¥¹¥È¤ÎÎã¤òµó¤²¤Þ¤·¤ç¤¦¡£ + ¤³¤Î¥Ö¥é¥¦¥¶¤Ï¥Õ¥é¥ó¥¹¸ì¤È±Ñ¸ì¤ò¼õ¤±ÉÕ¤±¤ë¡¢¤·¤«¤·¥Õ¥é¥ó¥¹¸ì¤ò¹¥¤à¡¢ + ¤½¤·¤ÆÍÍ¡¹¤Ê¥á¥Ç¥£¥¢¥¿¥¤¥×¤ò¼õ¤±ÉÕ¤±¤ë¤¬¡¢ + ¥×¥ì¥¤¥ó¥Æ¥­¥¹¥È¤ä¾¤Î¥¿¥¤¥×¤è¤ê¤Ï HTML ¤ò¹¥¤à¡¢ + ¾¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¤è¤ê¤Ï GIF ¤ä JPEG ¤ò¹¥¤à¡¢¤·¤«¤·ºÇ½ª¼êÃʤȤ·¤Æ + ¾¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¤â¼õ¤±ÉÕ¤±¤ë¡¢¤ÈÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +

    + +

    Apache ¤Ï HTTP/1.1 µ¬³Ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë 'server + driven' ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£ + Accept, Accept-Language, + Accept-Charset, Accept-Encoding + ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ò´°Á´¤Ë¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£Apache ¤Ï + 'transparent' ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤â¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¤¬¡¢ + ¤³¤ì¤Ï RFC 2295 ¤È RFC 2296 ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë»î¸³Åª¤Ê + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¥×¥í¥È¥³¥ë¤Ç¤¹¡£ + ¤³¤ì¤é¤Î RFC¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë 'feature negotiation' + ¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£

    + +

    ¥ê¥½¡¼¥¹¤È¤Ï URI + ¤ÇÆÃÄꤵ¤ì¤ë³µÇ°¾å¤Î¤â¤Î¤Î¤³¤È¤Ç¤¹ (RFC 2396)¡£ Apache + ¤Î¤è¤¦¤Ê HTTP ¥µ¡¼¥Ð¤Ï¡¢¤½¤Î̾Á°¶õ´Ö¤ÎÃæ¤Ç¤Î + ¥ê¥½¡¼¥¹¤Îɽ¸½¤Ø¤Î¥¢¥¯¥»¥¹¤òÄ󶡤·¤Þ¤¹¡£ + ¤½¤ì¤¾¤ì¤Îɽ¸½¤Ï + ÄêµÁ¤µ¤ì¤¿¥á¥Ç¥£¥¢¥¿¥¤¥×¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°Åù¤Î + ÉÕ°¤·¤¿¡¢¥Ð¥¤¥ÈÎó¤Î·Á¼°¤Ç¤¹¡£ + ¤½¤ì¤¾¤ì¤Î¥ê¥½¡¼¥¹¤Ï¤¢¤ë»þÅÀ¤Ç 0 ¸Ä¡¢1 ¸Ä¡¢¤½¤ì°Ê¾å¤Îɽ¸½¤È + ´ØÏ¢ÉÕ¤±¤é¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£Ê£¿ô¤Îɽ¸½¤¬ÍøÍѤǤ­¤ë¾ì¹ç¤Ï¡¢ + ¥ê¥½¡¼¥¹¤Ï¥Í¥´¥·¥¨¡¼¥·¥ç¥ó²Äǽ¤Ç¤¢¤ë¤È¤µ¤ì¡¢ + ¸Ä¡¹¤Îɽ¸½¤Ï variant ¤È¸Æ¤Ð¤ì¤Þ¤¹¡£ + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó²Äǽ¤Ê¥ê¥½¡¼¥¹¤Î variant ¤¬°Û¤Ê¤ë¡¢ + ¤½¤Î¾õÂÖ¤ò»Ø¤·¤Æ¡¢ + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¼¡¸µ¤È¸Æ¤Ó¤Þ¤¹¡£

    +
    top
    +
    +

    Apache ¤Ë¤ª¤±¤ë¥Í¥´¥·¥¨¡¼¥·¥ç¥ó

    + +

    ¥ê¥½¡¼¥¹¤ò¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï variant ¤½¤ì¤¾¤ì¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤òÃΤäƤª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï°Ê²¼¤ÎÆó¤Ä¤ÎÊýË¡¤Î¤É¤Á¤é¤«¤Ç¹Ô¤ï¤ì¤Þ¤¹¡£

    + +
      +
    • ¥¿¥¤¥×¥Þ¥Ã¥× + (¤¹¤Ê¤ï¤Á *.var ¥Õ¥¡¥¤¥ë) + ¤ò»È¤¦ÊýË¡¡£ ¤³¤ì¤Ï variant + ¤òÌÀ¼¨Åª¤Ëµó¤²¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤ò»ØÄꤷ¤Þ¤¹¡£
    • + +
    • 'Multiviews' + ¤ò»È¤Ã¤Æ¡¢¥µ¡¼¥Ð¤¬°ÅÌÛ¤ÎÆâ¤Ë¥Õ¥¡¥¤¥ë̾¤Ë¥Ñ¥¿¡¼¥ó¾È¹ç¤ò + ¹Ô¤Ê¤Ã¤Æ¤½¤Î·ë²Ì¤«¤éÁªÂò¤¹¤ëÊýË¡¡£
    • +
    + +

    type-map ¥Õ¥¡¥¤¥ë¤ò»È¤¦

    + +

    ¥¿¥¤¥×¥Þ¥Ã¥×¤Ï type-map ¥Ï¥ó¥É¥é + (¤â¤·¤¯¤Ï¡¢¸Å¤¤ Apache + ¤ÎÀßÄê¤È²¼°Ì¸ß´¹¤Ç¤¢¤ë MIME ¥¿¥¤¥× + application/x-type-map) + ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Ç¤¹¡£ + ¤³¤Îµ¡Ç½¤ò»È¤¦¤¿¤á¤Ë¤Ï¡¢¤¢¤ë¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤ò + type-map + ¤È¤·¤ÆÄêµÁ¤¹¤ë¤è¤¦¤Ê¥Ï¥ó¥É¥é¤ò¡¢ + ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤ËÃÖ¤¯É¬Íפ¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤ì¤Ï

    + +

    AddHandler type-map .var

    + +

    ¤ò¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ë½ñ¤¯¤³¤È¤¬°ìÈÖÎɤ¤ÊýË¡¤Ç¤¹¡£

    + +

    ¥¿¥¤¥×¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤Ïµ­½Ò¤¹¤ë¥ê¥½¡¼¥¹¤ÈƱ¤¸Ì¾Á°¤ò»ý¤Ã¤Æ¤¤¤Æ¡¢ + ÍøÍѲÄǽ¤Ê variant ¤½¤ì¤¾¤ì¤Î¥¨¥ó¥È¥ê¤ò»ý¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¤³¤Î¥¨¥ó¥È¥ê¤ÏϢ³¤·¤¿ HTTP ¤Î¥Ø¥Ã¥À¹Ô¤Ç¹½À®¤µ¤ì¤Þ¤¹¡£ + °Û¤Ê¤ë variant ¤Î¤¿¤á¤Î¥¨¥ó¥È¥ê¤Ï¶õ¹Ô¤Ç¶èÀÚ¤é¤ì¤Æ¤¤¤Þ¤¹¡£ + ¥¨¥ó¥È¥êÃæ¤Ë¶õ¹Ô¤¬Ê£¿ô¤¢¤Ã¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£ + ½¬´·Åª¤Ë¤Ï¡¢¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤ÏÁ´ÂΤò·ë¹ç¤·¤¿¤â¤Î¤Î¥¨¥ó¥È¥ê¤«¤é»Ï¤Þ¤ê¤Þ¤¹ + (¤·¤«¤·¤³¤ì¤Ïɬ¿Ü¤Ç¤Ï¤Ê¤¯¡¢¤¢¤Ã¤¿¤È¤·¤Æ¤â̵»ë¤µ¤ì¤ë¤â¤Î¤Ç¤¹)¡£ + ¼¡¤ËÎã¤ò¼¨¤·¤Þ¤¹¡£¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¥ê¥½¡¼¥¹ foo + ¤òµ­½Ò¤·¤Æ¤¤¤ë¤Î¤Ç¡¢foo.var ¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +

    +

    ¤¿¤È¤¨ MultiViews ¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢ + ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤è¤ê¥¿¥¤¥×¥Þ¥Ã¥×¤ÎÊý¤¬Í¥À踢¤ò»ý¤Ä¤È¤¤¤¦¤³¤È¤Ë¤â + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + variant ¤ÎÉʼÁ¤¬°ã¤¦¤È¤­¤Ï¡¢¤³¤Î²èÁü¤Î¤è¤¦¤Ë (JPEG, GIF, ASCII + ¥¢¡¼¥È¤¬¤¢¤ê¤Þ¤¹) ¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î "qs" + ¥Ñ¥é¥á¡¼¥¿¤Ç»ØÄꤵ¤ì¤Þ¤¹¡£

    + +

    + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +

    + +

    qs ÃͤÎÈÏ°Ï¤Ï 0.000 ¤«¤é 1.000 ¤Ç¤¹¡£qs Ãͤ¬ + 0.000 ¤Î variant ¤Ï·è¤·¤Æ + ÁªÂò¤µ¤ì¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£'qs' ÃͤΤʤ¤ variant + ¤Ï qs ÃÍ 1.0 ¤ò Í¿¤¨¤é¤ì¤Þ¤¹¡£qs + ¥Ñ¥é¥á¡¼¥¿¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ÎǽÎϤ˴ط¸Ìµ¤¯¡¢Â¾¤Î variant ¤È + Èæ³Ó¤·¤¿¤È¤­¤Î variant + ¤ÎÁêÂÐŪ¤Ê¡ÖÉʼÁ¡×¤ò¼¨¤·¤Þ¤¹¡£ + Î㤨¤Ð¡¢¼Ì¿¿¤òɽ¸½¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤Ï JPEG + ¥Õ¥¡¥¤¥ë¤ÎÊý¤¬ÉáÄÌ¤Ï ASCII + ¥Õ¥¡¥¤¥ë¤è¤ê¤â¹â¤¤ÉʼÁ¤Ë¤Ê¤ê¤Þ¤¹¡£¤·¤«¤·¡¢¥ê¥½¡¼¥¹¤¬¸µ¡¹ + ASCII ¥¢¡¼¥È¤Çɽ¸½¤µ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢ASCII ¥Õ¥¡¥¤¥ë¤Î + Êý¤¬ JPEG ¥Õ¥¡¥¤¥ë¤è¤ê¤â¹â¤¤ÉʼÁ¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ë¡¢qs + ¤Ï ɽ¸½¤µ¤ì¤ë¥ê¥½¡¼¥¹¤ÎÀ­¼Á¤Ë¤è¤Ã¤Æ variant + Ëè¤ËÆÃÍ­¤ÎÃͤò¼è¤ê¤Þ¤¹¡£

    + +

    ǧ¼±¤µ¤ì¤ë¥Ø¥Ã¥À¤Î°ìÍ÷¤Ï + mod_negotiation + ¥É¥­¥å¥á¥ó¥È¤Ë¤¢¤ê¤Þ¤¹¡£

    + + +

    Multiviews

    + +

    MultiViews ¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤Î¥ª¥×¥·¥ç¥ó¤Ç¡¢ + httpd.conf¥Õ¥¡¥¤¥ë¤Î + <Directory>, + <Location>, + <Files> + ¥»¥¯¥·¥ç¥óÃæ¤ä¡¢(AllowOverride + ¤¬Å¬ÀÚ¤ÊÃÍ¤Ë ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È) .htaccess + ¥Õ¥¡¥¤¥ë¤Ç Options + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤ÆÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Options All ¤Ï + MultiViews + ¤ò¥»¥Ã¥È¤·¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ÌÀ¼¨Åª¤Ë + ¤½¤Î̾Á°¤ò½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    MultiViews ¤Î¸ú²Ì¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹: + ¥µ¡¼¥Ð¤¬ /some/dir/foo + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤ê¡¢/some/dir ¤Ç + MultiViews ¤¬Í­¸ú¤Ç¤¢¤Ã¤Æ¡¢ + /some/dir/foo ¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¡¢ + ¥µ¡¼¥Ð¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤òÆɤó¤Ç foo.* + ¤Ë¤¢¤Æ¤Ï¤Þ¤ëÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤òõ¤·¡¢ + »ö¼Â¾å¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤ò¥Þ¥Ã¥×¤¹¤ë¥¿¥¤¥×¥Þ¥Ã¥×¤òºî¤ê¤Þ¤¹¡£ + ¤½¤Î¤È¤­¡¢¥á¥Ç¥£¥¢¥¿¥¤¥×¤È¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ï¡¢¤½¤Î¥Õ¥¡¥¤¥ë̾¤ò + ľÀÜ»ØÄꤷ¤¿¤È¤­¤ÈƱ¤¸¤â¤Î¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£ + ¤½¤ì¤«¤é¥¯¥é¥¤¥¢¥ó¥È¤ÎÍ×µá¤Ë°ìÈֹ礦¤â¤Î¤òÁª¤Ó¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤¬¥Ç¥£¥ì¥¯¥È¥ê¤Îº÷°ú¤òºî¤í¤¦¤È¤·¤Æ¤¤¤ë¾ì¹ç¡¢ + MultiViews + ¤Ï DirectoryIndex + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤òõ¤¹²áÄø¤Ë¤â + ŬÍѤµ¤ì¤Þ¤¹¡£ÀßÄê¥Õ¥¡¥¤¥ë¤Ë

    +

    DirectoryIndex index

    +

    ¤¬½ñ¤«¤ì¤Æ¤¤¤Æ¡¢index.html ¤È + index.html3 ¤¬ + ξÊý¸ºß¤·¤Æ¤¤¤ë¤È¡¢¥µ¡¼¥Ð¤Ï¤½¤ÎÃ椫¤é¤É¤Á¤é¤«¤òŬÅö¤ËÁª¤Ó¤Þ¤¹¡£ + ¤â¤·¤½¤ÎξÊý¤¬Â¸ºß¤»¤º¤Ë index.cgi + ¤¬Â¸ºß¤·¤Æ¤¤¤ë¤È¡¢ ¥µ¡¼¥Ð¤Ï¤½¤ì¤ò¼Â¹Ô¤·¤Þ¤¹¡£

    + +

    ¤â¤·¥Ç¥£¥ì¥¯¥È¥ê¤òÆɤó¤Ç¤¤¤ëºÝ¤Ë¡¢ + ʸ»ú¥»¥Ã¥È¡¢¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¡¢¸À¸ì¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò + »ØÄꤹ¤ë¤¿¤á¤Î mod_mime + ¤Çǧ¼±¤Ç¤­¤ë³ÈÄ¥»Ò¤ò»ý¤¿¤Ê¤¤¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ë¤È¡¢·ë²Ì¤Ï + MultiViewsMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤Ë°Í¸¤·¤Þ¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥Ï¥ó¥É¥é¡¢¥Õ¥£¥ë¥¿¡¢Â¾¤Î¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¥¿¥¤¥×¤Î¤É¤ì¤¬ + MultiViews ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ç»ÈÍѤǤ­¤ë¤«¤ò·èÄꤷ¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥Í¥´¥·¥¨¡¼¥·¥ç¥óÊýË¡

    + +

    Apache ¤Ï¥ê¥½¡¼¥¹¤Î variant ¤Î°ìÍ÷¤ò¡¢¥¿¥¤¥×¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤« + ¥Ç¥£¥ì¥¯¥È¥êÆâ¤Î¥Õ¥¡¥¤¥ë̾¤«¤é¤«¤Ç¼èÆÀ¤·¤¿¸å¡¢ + ¡ÖºÇŬ¤Ê¡× variant ¤ò·èÄꤹ¤ë¤¿¤á¤ËÆó¤Ä¤ÎÊýË¡¤Î + ¤É¤Á¤é¤«¤òµ¯Æ°¤·¤Þ¤¹¡£ + Apache ¤Î¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Îµ¡Ç½¤ò»È¤¦¤¿¤á¤Ë¡¢ + ¤É¤Î¤è¤¦¤Ë¤·¤Æ¤³¤ÎÄ´Ä䤬¹Ô¤ï¤ì¤ë¤«¾ÜºÙ¤òÃΤëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢¤³¤Îʸ½ñ¤Î»Ä¤ê¤Ç¤Ï´Ø¿´¤Î¤¢¤ë¿Í¤Î¤¿¤á¤Ë¡¢ + »ÈÍѤµ¤ì¤Æ¤¤¤ëÊýË¡¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥Í¥´¥·¥¨¡¼¥·¥ç¥óÊýË¡¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹¡£

    + +
      +
    1. Ä̾ï¤Ï Apache ¤Î¥¢¥ë¥´¥ê¥º¥à¤òÍѤ¤¤¿ Server + driven negotiation ¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£Apache + ¤Î¥¢¥ë¥´¥ê¥º¥à¤Ï¸å¤Ë¾ÜºÙ¤ËÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤¬»ÈÍѤµ¤ì¤¿¾ì¹ç¡¢Apache + ¤Ï¤è¤êÎɤ¤·ë²Ì¤Ë¤Ê¤ë¤è¤¦¤Ë¡¢ÆÃÄê¤Î¼¡¸µ¤Ë¤ª¤¤¤ÆÉʼÁ¤ÎÃͤò + ¡ÖÊѤ¨¤ë¡×¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Apache + ¤¬ÉʼÁ¤ÎÃͤòÊѤ¨¤ëÊýË¡¤Ï¸å¤Ç¾ÜºÙ¤ËÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
    2. + +
    3. RFC 2295 + ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëµ¡¹½¤òÍѤ¤¤Æ¥Ö¥é¥¦¥¶¤¬Æä˻ØÄꤷ¤¿¾ì¹ç¡¢ + transparent content negotiation + ¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¥Í¥´¥·¥¨¡¼¥·¥ç¥óÊýË¡¤Ç¤Ï¡¢¡ÖºÇŬ¤Ê¡× + variant ¤Î·èÄê¤ò¥Ö¥é¥¦¥¶¤¬´°Á´¤ËÀ©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢·ë²Ì¤Ï¥Ö¥é¥¦¥¶¤¬»ÈÍѤ·¤Æ¤¤¤ë¥¢¥ë¥´¥ê¥º¥à¤Ë°Í¸¤·¤Þ¤¹¡£ + Transparent negotiation ¤Î½èÍý¤Î²áÄø¤Ç¡¢¥Ö¥é¥¦¥¶¤Ï RFC 2296 + ¤Ç ÄêµÁ¤µ¤ì¤Æ¤¤¤ë 'remote variant selection algorithm' + ¤ò¼Â¹Ô¤¹¤ë¤è¤¦¤ËÍê¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    4. +
    + +

    ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¼¡¸µ

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¼¡¸µÀâÌÀ
    ¥á¥Ç¥£¥¢¥¿¥¤¥×¥Ö¥é¥¦¥¶¤Ï Accept + ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ÇÍ¥Àè·¹¸þ¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥¢¥¤¥Æ¥à¤½¤ì¤¾¤ì¤Ï¡¢´ØÏ¢¤·¤¿ÉʼÁ¿ôÃͤò»ý¤Ä¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + variant ¤ÎÀâÌÀ¤âÉʼÁ¿ôÃͤò»ý¤Ä¤³¤È¤¬¤Ç¤­¤Þ¤¹ + ("qs" ¥Ñ¥é¥á¡¼¥¿¤ò¤´Í÷²¼¤µ¤¤)¡£
    ¸À¸ì¥Ö¥é¥¦¥¶¤Ï Accept-Language + ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ÇÍ¥Àè·¹¸þ¤ò»ØÄꤷ¤Þ¤¹¡£ + Í×ÁǤ½¤ì¤¾¤ì¤ËÉʼÁ¿ôÃͤò»ý¤¿¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + variants ¤Ï 0 ¤« 1 ¤Ä¤«¤½¤ì°Ê¾å¤Î¸À¸ì¤È + ´ØÏ¢¤Å¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¥Ö¥é¥¦¥¶¤Ï Accept-Encoding + ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ÇÍ¥Àè·¹¸þ¤ò»ØÄꤷ¤Þ¤¹¡£ + Í×ÁǤ½¤ì¤¾¤ì¤ËÉʼÁ¿ôÃͤò»ý¤¿¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    ʸ»ú¥»¥Ã¥È¥Ö¥é¥¦¥¶¤Ï Accept-Charset + ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ÇÍ¥Àè·¹¸þ¤ò»ØÄꤷ¤Þ¤¹¡£ + Í×ÁǤ½¤ì¤¾¤ì¤ËÉʼÁ¿ôÃͤò»ý¤¿¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + variant ¤Ï¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î¥Ñ¥é¥á¡¼¥¿¤È¤·¤Æʸ»ú¥»¥Ã¥È¤ò + »ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
    + + +

    Apache ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¥¢¥ë¥´¥ê¥º¥à

    + +

    ¥Ö¥é¥¦¥¶¤ËÊÖ¤¹¡ÖºÇŬ¤Ê¡×variant ¤ò (¤â¤·¤¢¤ì¤Ð) ÁªÂò¤¹¤ë¤è¤¦¤Ë + Apache ¤Ï¼¡¤Î¥¢¥ë¥´¥ê¥º¥à¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤òÀßÄê¤Ë¤è¤êÊѹ¹¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ¼¡¤Î¤è¤¦¤ËÆ°ºî¤·¤Þ¤¹:

    + +
      +
    1. ¤Þ¤º¤Ï¤¸¤á¤Ë¡¢¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¼¡¸µ¤½¤ì¤¾¤ì¤Ë¤Ä¤¤¤ÆŬÀÚ¤Ê + Accept* ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤òÄ´¤Ù¡¢ + variant ¤½¤ì¤¾¤ì¤ËÉʼÁ¤ò³ä¤êÅö¤Æ¤Þ¤¹¡£ + ¤â¤·¤¢¤ë¼¡¸µ¤Î Accept* ¥Ø¥Ã¥À¤Ç¤½¤Î variant + ¤¬µöÍƤǤ­¤Ê¤¤¤³¤È¤¬¼¨¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤òºï½ü¤·¤Þ¤¹¡£ + variant ¤¬°ì¤Ä¤â»Ä¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥¹¥Æ¥Ã¥× 4 ¤Ë¹Ô¤­¤Þ¤¹¡£
    2. + +
    3. + ¾ÃµîË¡¤Ç¡ÖºÇŬ¤Ê¡× variant ¤òÁª¤Ó¤Þ¤¹¡£ + ¼¡¤Î¥Æ¥¹¥È¤¬½çÈÖ¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + ¥Æ¥¹¥È¤ÇÁªÂò¤µ¤ì¤Ê¤«¤Ã¤¿ variant ¤Ïºï½ü¤µ¤ì¤Æ¤¤¤­¤Þ¤¹¡£ + ¥Æ¥¹¥È¸å variant ¤¬°ì¤Ä¤À¤±»Ä¤Ã¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤òºÇŬ¤Ê¤â¤Î¤È¤·¤Æ + ¥¹¥Æ¥Ã¥× 3 ¤Ë¿Ê¤ß¤Þ¤¹¡£ + Ê£¿ô variant ¤¬»Ä¤Ã¤Æ¤¤¤ì¤Ð¡¢¼¡¤Î¥Æ¥¹¥È¤Ë¿Ê¤ß¤Þ¤¹¡£ + +
        +
      1. variant ¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¤ÎÉʼÁ¿ôÃÍ¤È Accept + ¥Ø¥Ã¥À¤ÎÉʼÁ¿ôÃͤȤÎÀѤò·×»»¤·¤Æ¡¢ºÇ¹âÃͤΠvariant + ¤òÁª¤Ó¤Þ¤¹¡£
      2. + +
      3. ¸À¸ìÉʼÁ¿ôÃͤ¬ºÇ¹â¤Î variant ¤òÁª¤Ó¤Þ¤¹¡£
      4. + +
      5. (¤â¤·¤¢¤ì¤Ð) Accept-Language ¥Ø¥Ã¥À¤Î¸À¸ì½ç¤«¡¢ + (¤â¤·¤¢¤ì¤Ð) + LanguagePriority + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸À¸ì½ç¤ÇºÇŬ¤Ê¸À¸ì¤Î variant ¤òÁª¤Ó¤Þ¤¹¡£
      6. + +
      7. ºÇ¹â¡Ö¥ì¥Ù¥ë¡×¤Î¥á¥Ç¥£¥¢¥Ñ¥é¥á¡¼¥¿ + (text/html ¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î¥Ð¡¼¥¸¥ç¥ó¤òÍ¿¤¨¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹) + ¤ò»ý¤Ä variant ¤òÁª¤Ó¤Þ¤¹¡£
      8. + +
      9. Accept-Charset ¥Ø¥Ã¥À¹Ô¤ÇÍ¿¤¨¤é¤ì¤Æ¤¤¤ëºÇ¹â¤Îʸ»ú¥»¥Ã¥È + ¥á¥Ç¥£¥¢¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä variant ¤òÁª¤Ó¤Þ¤¹¡£ + ÌÀ¼¨Åª¤Ë½ü³°¤µ¤ì¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢ISO-8859-1 + ¤¬µöÍƤµ¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + text/* ¥á¥Ç¥£¥¢¥¿¥¤¥×¤Ç¤¢¤ë¤±¤ì¤É¤â + ÆÃÄê¤Îʸ»ú¥»¥Ã¥È¤ËÌÀ¼¨Åª¤Ë´ØÏ¢¤Å¤±¤é¤ì¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤ + variant ¤Ï ISO-8859-1 ¤Ç¤¢¤ë¤È²¾Äꤵ¤ì¤Þ¤¹¡£
      10. + +
      11. ISO-8859-1 ¤Ç¤Ï¤Ê¤¤Ê¸»ú¥»¥Ã¥È¥á¥Ç¥£¥¢¥Ñ¥é¥á¡¼¥¿¤È + ´ØÏ¢¤Å¤±¤é¤ì¤Æ¤¤¤ë variant ¤òÁª¤Ó¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê variant ¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢Âå¤ï¤ê¤ËÁ´¤Æ¤Î + variant ¤òÁª¤Ó¤Þ¤¹¡£
      12. + +
      13. ºÇŬ¤Ê¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î variant ¤òÁª¤Ó¤Þ¤¹¡£ + ¤â¤· user-agent ¤¬µöÍƤ¹¤ë¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤¬¤¢¤ì¤Ð¡¢ + ¤½¤Î variant ¤Î¤ß¤òÁª¤Ó¤Þ¤¹¡£ + ¤½¤¦¤Ç¤Ï¤Ê¤¯¡¢¤â¤·¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿¤â¤Î¤È¤½¤¦¤Ç¤Ê¤¤ + variant ¤¬º®¤¶¤Ã¤Æ¸ºß¤·¤Æ¤¤¤¿¤é¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤Ê¤¤ + variant ¤Î¤ß¤òÁª¤Ó¤Þ¤¹¡£ + variant ¤¬Á´Éô¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ë¤« + variant ¤¬Á´Éô¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤Ê¤¤¤È¤¤¤¦¾ì¹ç¤Ï¡¢ + Á´¤Æ¤Î variant ¤òÁª¤Ó¤Þ¤¹¡£
      14. + +
      15. ÆâÍƤκǤâû¤¤ variant ¤òÁª¤Ó¤Þ¤¹¡£
      16. + +
      17. »Ä¤Ã¤Æ¤¤¤ë variant ¤ÎºÇ½é¤Î¤â¤Î¤òÁª¤Ó¤Þ¤¹¡£ + ¥¿¥¤¥×¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎºÇ½é¤Ë¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤ë¤«¡¢ + variant ¤¬¥Ç¥£¥ì¥¯¥È¥ê¤«¤éºÇ½é¤ËÆɤ߹þ¤Þ¤ì¤ë»þ¤Ë + ASCII½ç¤Ç¥½¡¼¥È¤·¤Æ¥Õ¥¡¥¤¥ë̾¤¬ÀèƬ¤Ë¤Ê¤Ã¤¿¤«¡¢¤Î¤É¤Á¤é¤«¤Ç¤¹¡£
      18. +
      +
    4. + +
    5. ¥¢¥ë¥´¥ê¥º¥à¤ò»È¤Ã¤Æ°ì¤Ä¤Î¡ÖºÇŬ¤Ê¡×variant ¤òÁª¤Ó¤Þ¤·¤¿¤Î¤Ç¡¢ + ¤½¤ì¤ò±þÅú¤È¤·¤ÆÊÖ¤·¤Þ¤¹¡£¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¼¡¸µ¤ò»ØÄꤹ¤ë¤¿¤á¤Ë + HTTP ¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À Vary ¤¬ÀßÄꤵ¤ì¤Þ¤¹ + (¥ê¥½¡¼¥¹¤Î¥­¥ã¥Ã¥·¥å¤ò¤¹¤ë»þ¤Ë¡¢ + ¥Ö¥é¥¦¥¶¤ä¥­¥ã¥Ã¥·¥å¤Ï¤³¤Î¾ðÊó¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹)¡£ + °Ê¾å¤Ç½ª¤ï¤ê¡£
    6. + +
    7. ¤³¤³¤ËÍ褿¤È¤¤¤¦¤³¤È¤Ï¡¢variant ¤¬°ì¤Ä¤âÁªÂò¤µ¤ì¤Ê¤«¤Ã¤¿ + (¥Ö¥é¥¦¥¶¤¬µöÍƤ¹¤ë¤â¤Î¤¬¤Ê¤«¤Ã¤¿¤¿¤á) ¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + 406 ¥¹¥Æ¡¼¥¿¥¹ ("No Acceptable representation" ¤ò°ÕÌ£¤¹¤ë) + ¤¬¡¢ÍøÍѲÄǽ¤Ê variant ¤Î¥ê¥¹¥È¤Î¤Ä¤¤¤¿ HTML + ¥É¥­¥å¥á¥ó¥È¤È¤È¤â¤ËÊÖ¤µ¤ì¤Þ¤¹¡£ + Áê°ã¤Î¼¡¸µ¤ò¼¨¤¹ HTTP Vary ¥Ø¥Ã¥À¤âÀßÄꤵ¤ì¤Þ¤¹¡£
    8. +
    + +
    top
    +
    +

    ÉʼÁ¤ÎÃͤòÊѤ¨¤ë

    + +

    ¾åµ­¤Î Apache ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¥¢¥ë¥´¥ê¥º¥à¤Î¸·³Ê¤Ê²ò¼á¤Ç + ÆÀ¤é¤ì¤ë¤Ç¤¢¤í¤¦Ãͤ«¤é¡¢Apache ¤ÏÉʼÁ¿ôÃͤò»þ¡¹ÊѤ¨¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¤³¤Î¥¢¥ë¥´¥ê¥º¥à¤Ç´°Á´¤Ç¤Ï¤Ê¤¤¡¢¤¢¤ë¤¤¤ÏÀµ³Î¤Ç¤Ê¤¤¾ðÊó¤òÁ÷¤ë + ¥Ö¥é¥¦¥¶¸þ¤±¤Ë¤è¤ê¤è¤¤·ë²Ì¤òÆÀ¤ë¤¿¤á¤Ë¹Ô¤ï¤ì¤Þ¤¹¡£ + ¤«¤Ê¤ê¥Ý¥Ô¥å¥é¡¼¤Ê¥Ö¥é¥¦¥¶¤Ç¡¢¤â¤·¤Ê¤¤¤È´Ö°ã¤Ã¤¿ variant + ¤òÁªÂò¤¹¤ë·ë²Ì¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤è¤¦¤Ê Accept + ¥Ø¥Ã¥À¾ðÊó¤òÁ÷¤ë¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£ + ¥Ö¥é¥¦¥¶¤¬´°Á´¤ÇÀµ¤·¤¤¾ðÊó¤òÁ÷¤Ã¤Æ¤¤¤ì¤Ð¡¢ + ¤³¤Î¿ôÃÍÊѲ½¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£

    + +

    ¥á¥Ç¥£¥¢¥¿¥¤¥×¤È¥ï¥¤¥ë¥É¥«¡¼¥É

    + +

    Accept: ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ï¥á¥Ç¥£¥¢¥¿¥¤¥×¤ÎÍ¥Àè·¹¸þ¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï¤Þ¤¿¡¢"image/*" ¤ä "*/*" + ¤È¤¤¤Ã¤¿¡Ö¥ï¥¤¥ë¥É¥«¡¼¥É¡×¥á¥Ç¥£¥¢¥¿¥¤¥×¤ò´Þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤³¤Ç * ¤ÏǤ°Õ¤Îʸ»úÎó¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¼¡¤Î:

    + +

    Accept: image/*, */*

    + +

    ¤ò´Þ¤à¥ê¥¯¥¨¥¹¥È¤Ï¡¢"image/" ¤Ç¤Ï¤¸¤Þ¤ë¥¿¥¤¥×Á´¤Æ¤¬µöÍƤǤ­¤ë¡¢ + ¤½¤·¤Æ¾¤Î¤É¤ó¤Ê¥¿¥¤¥×¤âµöÍƤǤ­¤ë + (¤³¤Î¾ì¹ç¤Ï¤¸¤á¤Î "image/*" ¤Ï¾éĹ¤Ë¤Ê¤ê¤Þ¤¹) + ¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + °·¤¦¤³¤È¤Î¤Ç¤­¤ëÌÀ¼¨Åª¤Ê¥¿¥¤¥×¤Ë²Ã¤¨¤Æ¡¢µ¡³£Åª¤Ë + ¥ï¥¤¥ë¥É¥«¡¼¥É¤òÁ÷¤ë¥Ö¥é¥¦¥¶¤â¤¢¤ê¤Þ¤¹¡£Î㤨¤Ð:

    + +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */* +

    +

    ¤³¤¦¤¹¤ë¤³¤È¤ÎÁÀ¤¤¤Ï¡¢ÌÀ¼¨Åª¤Ë¥ê¥¹¥È¤·¤Æ¤¤¤ë¥¿¥¤¥×¤¬Í¥À褵¤ì¤ë¤±¤ì¤É¤â¡¢ + °Û¤Ê¤ëɽ¸½¤¬ÍøÍѲÄǽ¤Ç¤¢¤ì¤Ð¤½¤ì¤Ç¤âÎɤ¤¡¢¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢¾å¤Î´ðËÜŪ¤Ê¥¢¥ë¥´¥ê¥º¥à¤Ç¤Ï¡¢ + */* ¥ï¥¤¥ë¥É¥«¡¼¥É¤Ï¾¤ÎÁ´¤Æ¤Î¥¿¥¤¥×¤ÈÁ´¤¯Æ±Åù¤Ê¤Î¤ÇÍ¥À褵¤ì¤Þ¤»¤ó¡£ + ¥Ö¥é¥¦¥¶¤Ï */* ¤Ë¤â¤Ã¤ÈÄ㤤ÉʼÁ (Í¥Àè) + ÃͤòÉÕ¤±¤Æ¥ê¥¯¥¨¥¹¥È¤òÁ÷¤ë¤Ù¤­¤Ê¤Î¤Ç¤¹¡£Î㤨¤Ð:

    +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 +

    +

    ÌÀ¼¨Åª¤Ê¥¿¥¤¥×¤Ë¤ÏÉʼÁ¿ôÃͤ¬ÉÕ¤±¤é¤ì¤Æ¤¤¤Þ¤»¤ó¤Î¤Ç¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Î 1.0 (ºÇ¹âÃÍ) ¤ÎÍ¥Àè¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥ï¥¤¥ë¥É¥«¡¼¥É */* ¤ÏÄ㤤ͥÀèÅÙ 0.01 ¤òÍ¿¤¨¤é¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢ + ÌÀ¼¨Åª¤Ë¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤ë¥¿¥¤¥×¤Ë¹çÃפ¹¤ë variant ¤¬¤Ê¤¤¾ì¹ç¤Ë¤Î¤ß¡¢ + ¾¤Î¥¿¥¤¥×¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    ¤â¤· Accept: ¥Ø¥Ã¥À¤¬ q ÃͤòÁ´¤¯´Þ¤ó¤Ç¤¤¤Ê¤±¤ì¤Ð¡¢ + ˾¤ß¤ÎµóÆ°¤ò¤¹¤ë¤¿¤á¤Ë¡¢ + Apache ¤Ï "*/*" ¤¬¤¢¤ì¤Ð 0.01 ¤Î q ÃͤòÀßÄꤷ¤Þ¤¹¡£ + ¤Þ¤¿¡¢"type/*" ¤Î·Á¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¤Ë¤Ï 0.02 ¤Î q ÃͤòÀßÄꤷ¤Þ¤¹ + (¤Ç¤¹¤«¤é¤³¤ì¤é¤Ï "*/*" ¤Î¥Þ¥Ã¥Á¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹)¡£ + ¤â¤· Accept: ¥Ø¥Ã¥ÀÃæ¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î¤É¤ì¤«¤¬ q + Ãͤò´Þ¤ó¤Ç¤¤¤ì¤Ð¡¢¤³¤ì¤é¤ÎÆüì¤ÊÃͤÏŬ±þ¤µ¤ì¤º¡¢ + Àµ¤·¤¤¾ðÊó¤òÁ÷¤ë¥Ö¥é¥¦¥¶¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤Ï´üÂÔÄ̤ê¤Ë + Æ°ºî¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + + +

    ¸À¸ì¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ÎÎã³°½èÍý

    + +

    Apache 2.0 ¤Ç¤Ï¿·¤¿¤Ë¡¢¸À¸ì¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤¬Å¬¹ç¤¹¤ë¤â¤Î¤ò + ¸«¤Ä¤±¤ë¤Î¤Ë¼ºÇÔ¤·¤¿»þ¤Ë¡¢Í¥²í¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤Ç¤­¤ë¤è¤¦¤Ê + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¥¢¥ë¥´¥ê¥º¥à¤¬´ö¤Ä¤«Äɲ䵤ì¤Þ¤·¤¿¡£

    + +

    ¥µ¡¼¥Ð¤Î¥Ú¡¼¥¸¤ò¥¯¥é¥¤¥¢¥ó¥È¤¬¥ê¥¯¥¨¥¹¥È¤·¤¿¤±¤ì¤É¤â¡¢ + ¥Ö¥é¥¦¥¶¤ÎÁ÷¤Ã¤Æ¤­¤¿ Accept-Language ¤Ë¹çÃפ¹¤ë¥Ú¡¼¥¸¤¬°ì¤Ä¤â + ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¡¢¥µ¡¼¥Ð¤Ï "No Acceptable Variant" + ¤« "Multiple Choices" ¥ì¥¹¥Ý¥ó¥¹¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤·¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤òÊÖ¤µ¤Ê¤¤¤è¤¦¤Ë¡¢ + ¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï Apache ¤¬ Accept-Language ¤ò̵»ë¤·¤Æ¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ËÌÀ¼¨Åª¤Ë¤Ï¹çÃפ·¤Ê¤¤¥É¥­¥å¥á¥ó¥È¤ò + Ä󶡤¹¤ë¤è¤¦¤ËÀßÄê¤Ç¤­¤Þ¤¹¡£ + ForceLanguagePriority + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¤³¤ì¤é¤Î¥¨¥é¡¼¤Î°ì¤Ä¤«Î¾Êý¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤¹¤ë¤¿¤á¤Ë + »ÈÍѤǤ­¤Æ¡¢ + LanguagePriority + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÆâÍƤò»È¤Ã¤Æ¥µ¡¼¥Ð¤ÎȽÃǤòÂå¹Ô¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤Ï¾¤ËŬ¹ç¤¹¤ë¤â¤Î¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢ + ¸À¸ì¥µ¥Ö¥»¥Ã¥È¤ÇŬ¹ç¤¹¤ë¤â¤Î¤ò»î¤½¤¦¤È¤â¤·¤Þ¤¹¡£ + Î㤨¤Ð¥¯¥é¥¤¥¢¥ó¥È¤¬±Ñ¹ñ±Ñ¸ì¤Ç¤¢¤ë en-GB ¸À¸ì¤Ç + ¥É¥­¥å¥á¥ó¥È¤ò¥ê¥¯¥¨¥¹¥È¤·¤¿¾ì¹ç¡¢¥µ¡¼¥Ð¤Ï HTTP/1.1 + µ¬³Ê¤Ç¤Ï¡¢Ã±¤Ë en ¤È¥Þ¡¼¥¯¤µ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤ò + ¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤È¤¹¤ë¤³¤È¤ÏÄ̾ï¤Ïµö¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ + (±Ñ¹ñ±Ñ¸ì¤ÏÍý²ò¤Ç¤­¤ë¤±¤É°ìÈÌŪ¤Ê±Ñ¸ì¤ÏÍý²ò¤Ç¤­¤Ê¤¤¤È¤¤¤¦Æɤ߼ê¤Ï + ¹Í¤¨¤é¤ì¤Ê¤¤¤Î¤Ç¡¢Accept-Language ¥Ø¥Ã¥À¤Ç en-GB + ¤ò´Þ¤ó¤Ç en ¤ò´Þ¤Þ¤Ê¤¤¤Î¤Ï¤Û¤Ü³Î¼Â¤ËÀßÄê¤Î´Ö°ã¤¤¤Ç¤¢¤ë¡¢ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤Ç¤¹¤¬ÉÔ¹¬¤Ê¤³¤È¤Ë¡¢Â¿¤¯¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç + ¤³¤Î¤è¤¦¤ÊÀßÄê¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£) + ¤·¤«¤·¤Ê¤¬¤é¡¢Â¾¤Î¸À¸ì¤Ë¤Ï¥Þ¥Ã¥Á¤»¤º¡¢"No Acceptable Variants" + ¥¨¥é¡¼¤òÊÖ¤·¤¿¤ê¡¢ + LanguagePriority + ¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + ¥µ¥Ö¥»¥Ã¥È»ØÄê¤ò̵»ë¤·¤Æ¡¢en-GB ¤ò en + ¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + Apache ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ÎµöÍƸÀ¸ì¥ê¥¹¥È¤Ë°ÅÌÛ¤Ë + Èó¾ï¤ËÄ㤤ÉʼÁÃͤοƸÀ¸ì¤ò²Ã¤¨¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤·¤«¤·¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬ "en-GB; q=0.9, fr; q=0.8" ¤È¥ê¥¯¥¨¥¹¥È¤·¤Æ¡¢ + ¥µ¡¼¥Ð¤¬ "en" ¤È "fr" ¤ÈÀ߷פµ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤ò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + "fr" ¥É¥­¥å¥á¥ó¥È¤¬ÊÖ¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤Î¤è¤¦¤Ê½èÍý¤Ï¡¢HTTP 1.1 µ¬³Ê¤È¤ÎÀ°¹çÀ­¤ò°Ý»ý¤·¤Æ¡¢ + ŬÀÚ¤ËÀßÄꤵ¤ì¤¿¥¯¥é¥¤¥¢¥ó¥È¤È¤â¤­¤Á¤ó¤ÈÆ°ºî¤¹¤ë¤¿¤á¤Ë + ɬÍפǤ¹¡£

    + +

    ¤è¤ê¹âÅ٤ʥƥ¯¥Ë¥Ã¥¯ (Cookie ¤äÆüì¤Ê URL ¥Ñ¥¹Åù) + ¤Ë¤ª¤¤¤Æ¤â¥æ¡¼¥¶¤Î¸À¸ìÁªÂò¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¡¢ + Apache 2.0.47 ¤«¤é¤Ï¡¢mod_negotiation + ¤¬´Ä¶­ÊÑ¿ô prefer-language + ¤òǧ¼±¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¤³¤ÎÊÑ¿ô¤¬Â¸ºß¤·¤Æ¡¢Å¬ÀڤʸÀ¸ì¥¿¥°¤¬ÂåÆþ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + mod_negotiation ¤Ï¹çÃפ¹¤ë variant + ¤òÁªÂò¤·¤è¤¦¤È¤·¤Þ¤¹¡£¹çÃפ¹¤ë¤â¤Î¤¬Ìµ¤±¤ì¤Ð¡¢ + Ä̾ï¤Î¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¼ê½ç¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£

    + +

    Example

    + SetEnvIf Cookie "language=(.+)" prefer-language=$1 +

    + +
    top
    +
    +

    Transparent Content Negotiation +¤Î³ÈÄ¥

    + +

    Apache ¤Ï transparent content negotiation ¥×¥í¥È¥³¥ë +(RFC 2295) ¤ò¼¡¤Î¤è¤¦¤Ë³ÈÄ¥¤·¤Æ¤¤¤Þ¤¹¡£ +ÆÃÄê¤Î¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î¤ß¤¬ÍøÍѲÄǽ¤Ç¤¢¤ë variant +¤Ë°õ¤òÉÕ¤±¤ë¤¿¤á¤Ë¡¢¿·¤¿¤Ë {encoding ..} +Í×ÁǤò variant ¥ê¥¹¥ÈÃæ¤Ë»È¤Ã¤Æ¤¤¤Þ¤¹¡£ +¥ê¥¹¥ÈÃæ¤Î¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿ variant ¤òǧ¼±¤·¡¢ +Accept-Encoding ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ë½¾¤Ã¤ÆµöÍƤµ¤ì¤ë +¥¨¥ó¥³¡¼¥É¤ò¤â¤Ã¤¿ variant ¤Ï¡¢¤É¤ì¤Ç¤â¸õÊä variant +¤È¤·¤Æ»ÈÍѤ¹¤ë¤è¤¦¤Ë¡¢ +RVSA/1.0 ¥¢¥ë¥´¥ê¥º¥à (RFC 2296) ¤Î¼ÂÁõ¤¬³ÈÄ¥¤µ¤ì¤Þ¤·¤¿¡£ +RVSA/1.0 ¤Î¼ÂÁõ¤Ç¤Ï¡¢ºÇŬ¤Ê variant ¤¬¸«¤Ä¤«¤ë¤Þ¤Ç¡¢ +·×»»¤·¤¿ÉʼÁ¿ôÃͤϾ®¿ôÅÀ°Ê²¼ 5 ·å¤Þ¤Ç´Ý¤á¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ¥ê¥ó¥¯¤È̾Á°¤ÎÊÑ´¹¤Ë´Ø¤¹¤ëÃí°ÕÅÀ

    + +

    ¸À¸ì¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥Õ¥¡¥¤¥ë¤¬°ì¤Ä°Ê¾å¤Î³ÈÄ¥»Ò¤ò»ý¤Æ¤Æ¡¢ + ³ÈÄ¥»Ò¤Î½çÈÖ¤ÏÄ̾ï¤Ï¹Í褵¤ì¤Ê¤¤ + (¾ÜºÙ¤Ï mod_mime + ¤ò»²¾È) ¤Î¤Ç¡¢ + ´ö¤Ä¤«¤Î°Û¤Ê¤ë̾Á°¤ÎÊÑ´¹¤òÁª¤Ù¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ŵ·¿Åª¤Ê¥Õ¥¡¥¤¥ë¤Ç¤Ï¡¢MIME ¥¿¥¤¥×³ÈÄ¥»Ò (Î㤨¤Ð + html) ¤ò»ý¤Ã¤Æ¤¤¤Æ¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°³ÈÄ¥»Ò + (Î㤨¤Ð gz) ¤ò»ý¤Ã¤Æ¤¤¤ë¤«¤â¤·¤ì¤Ê¤¯¤Æ¡¢ + ¤³¤Î¥Õ¥¡¥¤¥ë¤Ë°Û¤Ê¤ë¸À¸ì variant ¤òÍÑ°Õ¤·¤Æ¤¤¤ì¤Ð¡¢ + ¤â¤Á¤í¤ó¸À¸ì³ÈÄ¥»Ò (Î㤨¤Ð en) + ¤ò»ý¤Ã¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£

    + +

    Îã:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    ¥Õ¥¡¥¤¥ë̾¤È¡¢¤½¤ì¤ËÂФ·¤Æ»È¤¨¤ë¥ê¥ó¥¯¤È»È¤¨¤Ê¤¤¥ê¥ó¥¯¤ÎÎã¤Ç¤¹:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥Õ¥¡¥¤¥ë̾»È¤¨¤ë¥ê¥ó¥¯»È¤¨¤Ê¤¤¥ê¥ó¥¯
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    ¾å¤Îɽ¤ò¸«¤Æ¡¢³ÈÄ¥»Ò¤Ê¤·¤Î¥ê¥ó¥¯ (Î㤨¤Ð foo) + ¤¬¤¤¤Ä¤Ç¤â»È¤¨¤ë¤³¤È¤Ëµ¤¤¬ÉÕ¤¯¤Ç¤·¤ç¤¦¡£ + ¤³¤ÎÍøÅÀ¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ±þÅú¤¹¤ë¥Õ¥¡¥¤¥ë¤Î + ¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤ò±£Ê䷤ơ¢¥ê¥ó¥¯¤Î»²¾È¤òÊѹ¹¤¹¤ë¤³¤È¤Ê¤¯ + ¸å¤«¤é¥Õ¥¡¥¤¥ë¤òÊѹ¹¤Ç¤­¤ë¡¢ + Î㤨¤Ð html ¤«¤é shtml + ¤Ë¡¢¤¢¤ë¤¤¤Ï cgi ¤ËÊѹ¹¤Ç¤­¤ëÅÀ¤Ç¤¹¡£

    + +

    ¥ê¥ó¥¯¤Ë MIME ¥¿¥¤¥×¤ò»È¤¤Â³¤±¤¿¤¤ (Î㤨¤Ð + foo.html)»þ¤Ï¡¢¸À¸ì³ÈÄ¥»Ò¤Ï + (¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°³ÈÄ¥»Ò¤â¤¢¤ì¤Ð¤½¤ì¤â´Þ¤á¤Æ) + MIME ¥¿¥¤¥×³ÈÄ¥»Ò¤Î±¦Â¦¤Ë¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó + (Î㤨¤Ð foo.html.en)¡£

    +
    top
    +
    +

    ¥­¥ã¥Ã¥·¥å¤Ë´Ø¤¹¤ëÃí°Õ»ö¹à

    + +

    ¥­¥ã¥Ã¥·¥å¤¬°ì¤Ä¤Îɽ¸½¤òÊݸ¤·¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + ¥ê¥¯¥¨¥¹¥È URL ¤È´ØÏ¢¤Å¤±¤é¤ì¤Æ¤¤¤Þ¤¹¡£ + ¼¡¤Ë¤½¤Î URL ¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿»þ¤Ë¡¢¥­¥ã¥Ã¥·¥å¤Ï + Êݸ¤µ¤ì¤Æ¤¤¤ëɽ¸½¤ò»ÈÍѤǤ­¤Þ¤¹¡£¤·¤«¤·¡¢ + ¥ê¥½¡¼¥¹¤¬¥µ¡¼¥Ð¤Ç¥Í¥´¥·¥¨¡¼¥·¥ç¥ó²Äǽ¤Ç¤¢¤ì¤Ð¡¢ + ºÇ½é¤Î¥ê¥¯¥¨¥¹¥È¤Ç¥­¥ã¥Ã¥·¥å¤µ¤ì¤Æ³¤¯¥­¥ã¥Ã¥·¥å¥Ò¥Ã¥È¤Ç¤Ï + ´Ö°ã¤Ã¤¿±þÅú¤òÊÖ¤·¤Æ¤·¤Þ¤¦¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤«¤Í¤Þ¤»¤ó¡£ + ¤³¤ì¤òËɤ°¤¿¤á¤Ë¡¢Apache ¤Ï¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î + ¸å¤ËÊÖ¤µ¤ì¤¿±þÅúÁ´¤Æ¤Ë¡¢HTTP/1.0 ¥¯¥é¥¤¥¢¥ó¥È¤Ç¤Ï + ¥­¥ã¥Ã¥·¥åÉÔ²Äǽ¤Î°õ¤ò¤Ä¤±¤Þ¤¹¡£ + ¤Þ¤¿¡¢¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤µ¤ì¤¿±þÅú¤Î¥­¥ã¥Ã¥·¥å¤ò²Äǽ¤Ë¤¹¤ë + HTTP/1.1 ¥×¥í¥È¥³¥ë¤Îµ¡Ç½¤â Apache ¤Ï¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£

    + +

    HTTP/1.0 ½àµò¤Î¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤Ï¡¢ + (¥Ö¥é¥¦¥¶¤Ç¤¢¤í¤¦¤È¥­¥ã¥Ã¥·¥å¤Ç¤¢¤í¤¦¤È) + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò¼õ¤±¤¿±þÅú¤Î¥­¥ã¥Ã¥·¥å¤òµö¤¹¤¿¤á¤Ë¡¢ + CacheNegotiatedDocs + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤǤ­¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤ä¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¡¢ + °ú¿ô¤ò¤È¤ê¤Þ¤»¤ó¡£ + HTTP/1.1 ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤Ï¸úÎϤò»ý¤Á¤Þ¤»¤ó¡£

    + +

    HTTP/1.1 ¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¤Ï¡¢¥ì¥¹¥Ý¥ó¥¹¤Î¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¼¡¸µ + ¤ò¼¨¤¹¤¿¤á¤Ë Vary HTTP ¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À¤òÁ÷¤ê¤Þ¤¹¡£ + ¥­¥ã¥Ã¥·¥å¤Ï¡¢¤³¤ì¤ò»È¤Ã¤Æ¸å³¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¥í¡¼¥«¥ë¥³¥Ô¡¼¤Ç±þÅú¤Ç¤­¤ë¤« + ¤É¤¦¤«¤ò·èÄê¤Ç¤­¤Þ¤¹¡£ + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¼¡¸µ¤È¤Ï´Ø·¸¤Ê¤·¤Ë¥í¡¼¥«¥ë¥³¥Ô¡¼¤Î»ÈÍѤòÍ¥À褹¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢ + force-no-vary ´Ä¶­ÊÑ¿ô¤ò + ÀßÄꤷ¤Þ¤¹¡£

    + +
    top
    +
    +

    ÄɲþðÊó

    + +

    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ë´Ø¤¹¤ëÄɲþðÊó¤Ï¡¢ + Alan J. Flavell ¤µ¤ó¤ÎLanguage + Negotiation Notes ¤ò¤´Í÷²¼¤µ¤¤¡£¤Ç¤¹¤¬¡¢ + Apache 2.0 ¤Ç¤ÎÊѹ¹ÅÀ¤ò´Þ¤à¤¿¤á¤Ë¤Ï¹¹¿·¤µ¤ì¤Æ¤¤¤Ê¤¤¤«¤â¤·¤ì¤Ê¤¤ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/content-negotiation.html.ko.euc-kr b/trunk/docs/manual/content-negotiation.html.ko.euc-kr new file mode 100644 index 0000000000..1e0036f1fa --- /dev/null +++ b/trunk/docs/manual/content-negotiation.html.ko.euc-kr @@ -0,0 +1,608 @@ + + + +³»¿ëÇù»ó (Content Negotiation) - Apache HTTP Server + + + + + +
    <-
    +

    ³»¿ëÇù»ó (Content Negotiation)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + +

    ¾ÆÆÄÄ¡´Â HTTP/1.1 ±Ô¾à¿¡ ±â¼úµÈ ³»¿ëÇù»ó(content + negotiation)À» Áö¿øÇÑ´Ù. ³»¿ëÇù»óÀº media type, ¾ð¾î, ¹®ÀÚÁýÇÕ, + ÀÎÄÚµù µî¿¡ ´ëÇØ ºê¶ó¿ìÀú°¡ Á¦°øÇÑ ¼±È£µµ¿¡ µû¶ó ÀÚ¿øÀÇ + °¡Àå ÀûÇÕÇÑ Ç¥ÇöÀ» ¼±ÅÃÇÑ´Ù. ¶Ç ºÒ¿ÏÀüÇÑ Çù»ó Á¤º¸¸¦ º¸³»´Â + ºê¶ó¿ìÀúÀÇ ¿äûÀ» Áö´ÉÀûÀ¸·Î ó¸®ÇÏ´Â ±â´Éµµ ÀÖ´Ù.

    + +

    ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵǴ mod_negotiation + ¸ðµâÀÌ ³»¿ëÇù»ó ±â´ÉÀ» Á¦°øÇÑ´Ù.

    +
    + +
    top
    +
    +

    ³»¿ëÇù»ó¿¡ ´ëÇØ

    + +

    ÀÚ¿øÀº ¿©·¯ ´Ù¸¥ Ç¥ÇöÀ» °¡Áú ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´Ù¸¥ + ¾ð¾î³ª ´Ù¸¥ media type ȤÀº µÑ ¸ðµÎ°¡ ´Ù¸¥ Ç¥ÇöµéÀÌ ÀÖÀ» + ¼ö ÀÖ´Ù. °¡Àå Àû´çÇÑ Ç¥ÇöÀ» ¼±ÅÃÇÏ´Â ÇÑ°¡Áö ¹æ¹ýÀº »ç¿ëÀÚ¿¡°Ô + ¸ñ·Ï ÆäÀÌÁö¸¦ º¸¿©ÁÖ°í ¼±ÅÃÇÏ°Ô ÇÏ´Â °ÍÀÌ´Ù. ±×·¯³ª ¼­¹ö°¡ + ÀÚµ¿À¸·Î ¼±ÅÃÇÏ´Â °Íµµ °¡´ÉÇÏ´Ù. ÀÌ´Â ºê¶ó¿ìÀú°¡ ¿äûÀÇ + ÀϺηΠ±×µéÀÌ ¼±È£Çϴ ǥÇö¿¡ ´ëÇÑ Á¤º¸¸¦ º¸³»±â¶§¹®¿¡ + °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î, ºê¶ó¿ìÀú´Â °¡´ÉÇÑÇÑ ºÒ¾î·Î, ±×·¯³ª + ¾ø´Ù¸é ¿µ¾î·Î Á¤º¸¸¦ º¸°í½Í´Ù°í ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù. ºê¶ó¿ìÀú´Â + ¿äûÀÇ Çì´õ·Î ±×µéÀÇ ±âÈ£¸¦ ³ªÅ¸³½´Ù. ¿ÀÁ÷ ºÒ¾î·ÎµÈ Ç¥Çö¸¸À» + ¿äûÇÑ´Ù¸é ºê¶ó¿ìÀú´Â ´ÙÀ½°ú °°ÀÌ º¸³½´Ù.

    + +

    Accept-Language: fr

    + +

    ÀÌ·± ±âÈ£´Â Ç¥ÇöÀÌ ¾ð¾îº°·Î ´Ù¸¦ °æ¿ì¿¡¸¸ °í·ÁµÈ´Ù.

    + +

    ´ÙÀ½Àº ´õ º¹ÀâÇÑ ¿äûÀÇ ¿¹·Î ºê¶ó¿ìÀú°¡ ºÒ¾î¿Í ¿µ¾î¸¦ + ¹ÞÀ» ¼ö ÀÖÁö¸¸, ºÒ¾î¸¦ ´õ ¼±È£ÇÏ°í, ¿©·¯ media typeÀ» ¹ÞÀ» + ¼ö ÀÖÁö¸¸, ÀÏ¹Ý ÅؽºÆ® º¸´Ù´Â HTML, ´Ù¸¥ media type º¸´Ù´Â + GIF¿Í JPEGÀ» ¼±È£ÇÑ´Ù°í ¾Ë·ÁÁØ´Ù.

    + +

    + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +

    + +

    ¾ÆÆÄÄ¡´Â HTTP/1.1 ±Ô¾à¿¡ Á¤ÀÇµÈ '¼­¹ö ÁÖµµ(server driven)' + ³»¿ëÇù»óÀ» Áö¿øÇÑ´Ù. ¾ÆÆÄÄ¡´Â Accept, + Accept-Language, Accept-Charset, + Accept-Encoding ¿äû Çì´õ¸¦ ¸ðµÎ Áö¿øÇÑ´Ù. + ¶Ç, ¾ÆÆÄÄ¡´Â RFC 2295¿Í RFC 2296¿¡ Á¤ÀÇµÈ ½ÇÇèÀûÀÎ ³»¿ëÇù»óÀÎ + 'ÀÚ¿¬½º·¯¿î(transparent)' ¿äû Çì´õµµ Áö¿øÇÑ´Ù. ±×·¯³ª ÀÌ + RFC¿¡ Á¤ÀÇµÈ '±â´É Çù»ó(feature negotiation)'Àº Áö¿øÇÏÁö + ¾Ê´Â´Ù.

    + +

    ÀÚ¿ø(resource)Àº (RFC 2396) URI·Î ±¸º°ÇÏ´Â + °³³äÀûÀÎ Á¸Àç´Ù. ¾ÆÆÄÄ¡¿Í °°Àº À¥¼­¹ö´Â ÀÚ¿øÀÇ + Ç¥Çö(representations)À» Á¦°øÇÑ´Ù. Ç¥ÇöÀº + ÁöÁ¤µÈ media type, ¹®ÀÚÁýÇÕ, ÀÎÄÚµù µîÀ» °¡Áø ¹ÙÀÌÆ®µé·Î + µÇÀÖ´Ù. ÀÚ¿øÀº ¿©·¯ Ç¥Çö°ú (¶§·Î´Â ¾øÀ» ¼öµµ ÀÖ´Ù) ¿¬°üµÈ´Ù. + ÀÚ¿ø¿¡ ¿©·¯ Ç¥ÇöÀÌ ÀÖ´Ù¸é ÀÚ¿øÀ» + Çù»ó°¡´ÉÇÏ´Ù°í(negotiable) ºÎ¸£¸ç, À̶§ + °¢ Ç¥ÇöÀ» º¯Çü(variant)À̶ó°í ÇÑ´Ù. + Çù»ó°¡´ÉÇÑ ÀÚ¿øÀÇ º¯Çü Á¾·ù¸¦ Çù»óÀÇ + ¹üÀ§(dimension)¶ó°í ÇÑ´Ù.

    +
    top
    +
    +

    ¾ÆÆÄÄ¡ÀÇ Çù»ó

    + +

    ÀÚ¿øÀ» Çù»óÇϱâÀ§ÇØ ¼­¹ö´Â °¢ º¯Çü¿¡ ´ëÇÑ Á¤º¸°¡ ÇÊ¿äÇÏ´Ù. + ´ÙÀ½ µÎ°¡Áö ¹æ¹ýÁß Çϳª·Î Á¤º¸¸¦ ¾ò´Â´Ù:

    + +
      +
    • º¯ÇüÀ» ´ãÀº ÆÄÀϵéÀ» Á÷Á¢ ¿­°ÅÇÑ type mapÀ» (¿¹¸¦ + µé¾î, *.var ÆÄÀÏ) »ç¿ëÇϰųª,
    • + +
    • Á÷Á¢ ÁöÁ¤ÇÏÁö¾Ê¾Æµµ ¼­¹ö°¡ ÆÄÀÏ¸í¿¡¼­ ±ÔÄ¢À» ã¾Æ¼­ + °á°ú¸¦ ¼±ÅÃÇÏ´Â 'MultiViews'¸¦ »ç¿ëÇÑ´Ù.
    • +
    + +

    type-map ÆÄÀÏ »ç¿ëÇϱâ

    + +

    type mapÀº type-mapÀ̶õ Çڵ鷯¿Í ¿¬°áµÈ + (ȤÀº ÀÌÀü ¾ÆÆÄÄ¡ ¼³Á¤°ú ȣȯÀ» À§ÇØ MIME typeÀÌ + application/x-type-mapÀÎ) ¹®¼­´Ù. ÀÌ ±â´ÉÀ» + »ç¿ëÇÏ·Á¸é ¼³Á¤¿¡¼­ type-map Çڵ鷯¿¡ ´ëÇÑ + ÆÄÀÏ È®ÀåÀÚ¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù. ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ + ¼³Á¤ÇÏ´Â °ÍÀÌ ÁÁ´Ù.

    + +

    AddHandler type-map .var

    + +

    Type map ÆÄÀÏÀº ÇØ´çÇÏ´Â ÀÚ¿ø°ú À̸§ÀÌ °°¾Æ¾ß ÇÏ°í, + °¢ º¯Çü¿¡ ´ëÇÑ Ç׸ñÀÌ ÀÖ¾î¾ß ÇÑ´Ù. Ç׸ñÀº ¿©·¯ HTTPÇü½Ä + Çì´õ ÁÙ·Î ±¸¼ºµÈ´Ù. º¯Çü¿¡ ´ëÇÑ °¢°¢ÀÇ Ç׸ñµéÀº ºóÁÙ·Î + ±¸ºÐÇÑ´Ù. Ç׸ñ¾È¿¡¼­ ºóÁÙÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. (ÀÌ·¸°Ô ÇÒ + ÇÊ¿ä°¡ ¾ø°í, À־ ¹«½ÃÇÏÁö¸¸) ¿©·¯ Ç׸ñÀÌ °øÅëÀ¸·Î °¡Áö°í + ÀÖ´Â ³»¿ëÀ¸·Î map ÆÄÀÏÀ» ½ÃÀÛÇÏ´Â °ÍÀÌ º¸ÅëÀÌ´Ù. ´ÙÀ½Àº + map ÆÄÀÏ ¿¹´Ù. ÀÌ ÆÄÀÏÀÇ À̸§Àº foo.var·Î, + foo¶ó´Â ÀÚ¿øÀ» ¼³¸íÇÑ´Ù.

    + +

    + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +

    +

    typemap ÆÄÀÏÀÌ ÆÄÀϸí È®ÀåÀÚ º¸´Ù, ½ÉÁö¾î Multiviews¸¦ + »ç¿ëÇÏ¿©µµ, ¿ì¼±±ÇÀ» °¡ÁüÀ» ÁÖÀÇÇ϶ó. º¯ÇüÀÌ ¼­·Î ´Ù¸¥ Ç°ÁúÀ» + °¡Áø´Ù¸é, ´ÙÀ½°ú °°ÀÌ (JPEG, GIF, ASCII-art¿¡ ÇØ´çÇÏ´Â) + media type¿¡ "qs" ÆĶó¹ÌÅÍ·Î Ç°Áú(source quality)À» Ç¥½ÃÇÒ + ¼ö ÀÖ´Ù:

    + +

    + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +

    + +

    qs °ªÀº 0.000¿¡¼­ 1.000 »çÀÌ´Ù. qs °ªÀÌ 0.000ÀÎ º¯ÇüÀº + Àý´ë ¼±ÅõÇÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó. 'qs' °ªÀÌ ¾ø´Â º¯ÇüÀº 1.0À¸·Î + Ãë±ÞµÈ´Ù. qs °ªÀº Ŭ¶óÀ̾ðÆ®ÀÇ ´É·Â°ú´Â °ü°è¾øÀÌ ´Ù¸¥ º¯Çüµé°ú + ºñ±³ÇÏ¿© ±× º¯ÇüÀÇ »ó´ëÀûÀÎ 'Ç°Áú'À» ³ªÅ¸³½´Ù. ¿¹¸¦ µé¾î, + »çÁøÀ» ³ªÅ¸³»·Á´Â °æ¿ì JPEG ÆÄÀÏÀÌ ASCII ÆÄÀϺ¸´Ù´Â Ç×»ó + ³ôÀº Ç°ÁúÀ» °¡Áø´Ù. ±×·¯³ª ÀÚ¿øÀÌ ¿ø·¡ ASCII art¿´´Ù¸é + ASCII Ç¥ÇöÀÌ JPEG Ç¥Çöº¸´Ù ´õ ³ôÀº Ç°ÁúÀ» °¡Áú ¼ö ÀÖ´Ù. + ±×·¯¹Ç·Î ¾î¶² º¯ÇüÀÇ qs °ªÀº Ç¥ÇöÇÏ·Á´Â ÀÚ¿øÀÇ ¼ºÁú¿¡ + µû¶ó ´Ù¸£´Ù.

    + +

    Áö¿øÇÏ´Â ¸ðµç Çì´õ ¸ñ·ÏÀº mod_negotation + typemap ¹®¼­¸¦ Âü°íÇ϶ó.

    + + +

    Multiviews

    + +

    MultiViews´Â µð·ºÅ丮º° ¿É¼ÇÀ̹ǷÎ, + httpd.confÀÇ + <Directory>, + <Location>, + <Files> + ¼½¼Ç ȤÀº (AllowOverride°¡ + ÀûÀýÈ÷ ¼³Á¤µÇ¾ú´Ù¸é) .htaccess ÆÄÀÏÀÇ + Options Áö½Ã¾î¿¡ ¼³Á¤ÇÒ + ¼ö ÀÖ´Ù. Options AllÀº MultiViews¸¦ + Æ÷ÇÔÇÏÁö¾ÊÀ½À» ÁÖÀÇÇ϶ó. µû·Î Á÷Á¢ ½áÁà¾ß ÇÑ´Ù.

    + +

    MultiViews¸¦ »ç¿ëÇÏ¸é ´ÙÀ½°ú °°Àº ÀÏÀÌ ÀϾ´Ù: + ¼­¹ö°¡ /some/dir/foo¿¡ ´ëÇÑ ¿äûÀ» ¹Þ°í + /some/dir/foo¿¡ MultiViews°¡ µ¿ÀÛÇϸç + /some/dir/foo°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì, + ¼­¹ö´Â µð·ºÅ丮¿¡¼­ À̸§ÀÌ foo.*ÀÎ ÆÄÀϵéÀ» ¸ðµç Æ÷ÇÔÇÏ´Â + °¡»óÀÇ type mapÀ» ¸¸µç´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¿äûÇÑ media type°ú + content-encodingÀ» °¡Áö°í ÀÌÁß¿¡ °¡Àå ÀûÇÕÇÑ °ÍÀ» ¼±ÅÃÇÑ´Ù.

    + +

    MultiViews´Â ¼­¹ö°¡ µð·ºÅ丮¸¦ ÂüÁ¶ÇÒ¶§ + ÆÄÀÏÀ» ã´Â DirectoryIndex Áö½Ã¾î¿¡µµ + Àû¿ëµÈ´Ù. ¼³Á¤ÆÄÀÏÀÌ ´ÙÀ½°ú °°´Ù¸é,

    +

    DirectoryIndex index

    +

    index.html°ú index.html3ÀÌ + ¸ðµÎ ÀÖ´Ù¸é ¼­¹ö´Â ÀÌµÑ Áß¿¡ Çϳª¸¦ °áÁ¤ÇÑ´Ù. µÑ ¸ðµÎ ¾ø°í + index.cgi°¡ ÀÖ´Ù¸é, ¼­¹ö´Â ±×°ÍÀ» ½ÇÇàÇÑ´Ù.

    + +

    µð·ºÅ丮¸¦ ÀÐÀ»¶§ ÆÄÀÏÁß Çϳª°¡ Charset, Content-Type, + Language, Encoding¸¦ ÆÇ´ÜÇÏ´Â mod_mimeÀÌ ¸ð¸£´Â + È®ÀåÀÚ¸¦ °¡Áø´Ù¸é, °á°ú´Â MultiViewsMatch Áö½Ã¾î ¼³Á¤¿¡ + ´Þ·Ç´Ù. ÀÌ Áö½Ã¾î´Â Çڵ鷯, ÇÊÅÍ, ´Ù¸¥ È®ÀåÇüµéÀÌ MultiViews + Çù»ó¿¡ Âü¿©ÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    + +
    top
    +
    +

    Çù»ó¹æ¹ý

    + +

    ¾ÆÆÄÄ¡°¡ type-map ÆÄÀÏÀ̳ª µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀϸíµé·Î + ÁÖ¾îÁø ÀÚ¿ø¿¡ ´ëÇÑ º¯Çü ¸ñ·ÏÀ» ¾ò°ÔµÇ¸é 'ÃÖÀûÀÇ' º¯ÇüÀ» + °áÁ¤ÇϱâÀ§ÇØ µÎ ¹æ¹ýÁß Çϳª¸¦ »ç¿ëÇÑ´Ù. ¾ÆÆÄÄ¡ ³»¿ëÇù»ó + ±â´ÉÀ» »ç¿ëÇϱâÀ§ÇØ Á¤È®È÷ Çù»óÀÌ ¾î¶»°Ô ÀϾ´ÂÁö ÀÚ¼¼È÷ + ¾Ë ÇÊ¿ä´Â ¾ø´Ù. ±×·¯³ª ±Ã±ÝÇÑ »ç¶÷À» À§ÇØ ÀÌ ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    µÎ°¡Áö Çù»ó¹æ¹ýÀÌ ÀÖ´Ù:

    + +
      +
    1. ¾ÆÆÄÄ¡ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© ¼­¹ö°¡ ÁÖµµÇÏ´Â + Çù»óÀº ÀϹÝÀûÀÎ °æ¿ì¿¡ »ç¿ëÇÑ´Ù. ¾ÆÆÄÄ¡ ¾Ë°í¸®ÁòÀº + ¾Æ·¡¼­ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù. ÀÌ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â + ´õ ³ªÀº °á°ú¸¦ ¾ò±âÀ§ÇØ Á¾Á¾ ƯÁ¤ ¹üÀ§ÀÇ + Ç°Áú°è¼ö(quality factor)¸¦ 'Á¶ÀÛÇÑ´Ù'. ¾ÆÆÄÄ¡°¡ Ç°Áú°è¼ö¸¦ + Á¶ÀÛÇÏ´Â ¹æ¹ýÀº ¾Æ·¡¼­ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.
    2. + +
    3. ÀÚ¿¬½º·¯¿î(Transparent) ³»¿ëÇù»óÀº + ºê¶ó¿ìÀú°¡ RFC 2295¿¡ Á¤ÀÇµÈ ¹æ¹ýÀ¸·Î ¿äûÇÒ °æ¿ì¿¡¸¸ + »ç¿ëÇÑ´Ù. ÀÌ Çù»ó¹æ¹ýÀº 'ÃÖÀûÀÇ' º¯ÇüÀ» °áÁ¤ÇÒ ±ÇÇÑÀ» + ºê¶ó¿ìÀú¿¡°Ô ºÎ¿©ÇÑ´Ù. ±×·¡¼­ °á°ú´Â ºê¶ó¿ìÀúÀÇ ¾Ë°í¸®Áò¿¡ + ´Þ·È´Ù. ÀÚ¿¬½º·¯¿î Çù»ó°úÁ¤Áß¿¡ ºê¶ó¿ìÀú´Â ¾ÆÆÄÄ¡¿¡°Ô + RFC 2296¿¡ Á¤ÀÇµÈ '¿ø°Ý º¯Çü¼±Åà ¾Ë°í¸®Áò(remote variant + selection algorithm)'À» ¿äûÇÒ ¼ö ÀÖ´Ù.
    4. +
    + +

    Çù»óÀÇ ¹üÀ§

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¹üÀ§¼³¸í
    Media Typeºê¶ó¿ìÀú´Â Accept Çì´õ·Î ¼±È£¸¦ ³ªÅ¸³½´Ù. + °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀÇ ¼³¸íµµ Ç°Áú°è¼ö¸¦ + ("qs" ÆĶó¹ÌÅÍ) °¡Áú ¼ö ÀÖ´Ù.
    Languageºê¶ó¿ìÀú´Â Accept-Language Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀº + ¿©·¯ ¾ð¾î¸¦ °¡Áú (ȤÀº ¾Æ¹« ¾ð¾îµµ ¾øÀ») ¼ö ÀÖ´Ù.
    Encodingºê¶ó¿ìÀú´Â Accept-Encoding Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù.
    Charsetºê¶ó¿ìÀú´Â Accept-Charset Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀº + media typeÀÇ ÆĶó¹ÌÅÍ·Î ¹®ÀÚÁýÇÕÀ» ³ªÅ¸³¾ ¼ö ÀÖ´Ù.
    + + +

    ¾ÆÆÄÄ¡ Çù»ó ¾Ë°í¸®Áò

    + +

    ¾ÆÆÄÄ¡´Â ºê¶ó¿ìÀú¿¡°Ô º¸³¾ 'ÃÖÀûÀÇ' º¯ÇüÀ» (ÀÖ´Ù¸é) + ¼±ÅÃÇϱâÀ§ÇØ ¾Æ·¡ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÑ´Ù. ÀÌ ¾Ë°í¸®ÁòÀº º¯°æÇÒ + ¼ö ¾ø´Ù. ´ÙÀ½¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù:

    + +
      +
    1. ¸ÕÀú, Çù»óÀÇ °¢ ¹üÀ§¿¡ ´ëÇØ ÇØ´çÇÏ´Â Accept* + Çì´õ¸¦ °Ë»çÇÏ°í, °¢ º¯Çü¿¡ Ç°Áú°ªÀ» ¸Å±ä´Ù. ¾î¶² ¹üÀ§ÀÇ + Accept* Çì´õ°¡ ¹Þ¾ÆµéÀÌÁö ¾Ê´Â º¯ÇüÀº Èĺ¸¿¡¼­ + Á¦¿ÜÇÑ´Ù. ¾î¶² º¯Çüµµ ³²Áö¾ÊÀ¸¸é 4 ´Ü°è·Î °£´Ù.
    2. + +
    3. + Èĺ¸¿¡¼­ Çϳª¾¿ Á¦¿ÜÇÏ¿© 'ÃÖÀûÀÇ' º¯ÇüÀ» ã´Â´Ù. ´ÙÀ½ + °¢ °Ë»ç´Â ¼ø¼­´ë·Î ÀϾ´Ù. °¢ °Ë»ç¿¡¼­ ¼±ÅõÇÁö¾ÊÀº + º¯ÇüÀº Á¦¿ÜµÈ´Ù. °¢ °Ë»çÈÄ ÇÑ º¯Çü¸¸ ³²À¸¸é À̸¦ ÃÖÀûÀÇ + º¯ÇüÀ¸·Î ¼±ÅÃÇÏ°í 3 ´Ü°è·Î °£´Ù. ¿©·¯ º¯ÇüÀÌ ³²À¸¸é + ´ÙÀ½ °Ë»ç¸¦ ÁøÇàÇÑ´Ù. + +
        +
      1. Accept Çì´õÀÇ Ç°Áú°è¼ö¿Í º¯ÇüÀÇ + media type¿¡ ´ëÇÑ Ç°Áú°ªÀ» °öÇÏ¿© °¡Àå ³ôÀº °ªÀ» + °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      2. + +
      3. °¡Àå ³ôÀº ¾ð¾î(language) Ç°Áú°è¼ö¸¦ °¡Áø º¯ÇüÀ» + ¼±ÅÃÇÑ´Ù.
      4. + +
      5. Accept-Language Çì´õ¿¡ (ÀÖ´Ù¸é) + ³ª¿Â ¾ð¾îÀÇ ¼ø¼­ ȤÀº LanguagePriority + Áö½Ã¾î¿¡ (ÀÖ´Ù¸é) ³ª¿Â ¾ð¾îÀÇ ¼ø¼­¸¦ °¡Áö°í °¡Àå + ÀûÇÕÇÑ ¾ð¾î¸¦ °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      6. + +
      7. °¡Àå ³ôÀº (text/html media typeÀÇ ¹öÀüÀ» ³ªÅ¸³»´Â) + 'level' media ÆĶó¹ÌÅ͸¦ °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      8. + +
      9. Accept-Charset Çì´õ¸¦ °¡Áö°í °¡Àå + ÀûÇÕÇÑ charset media ÆĶó¹ÌÅ͸¦ °¡Áø º¯ÇüÀ» ã´Â´Ù. + Çì´õ°¡ ¾ø´Ù¸é ISO-8859-1 ¹®ÀÚÁýÇÕÀ» °¡Àå ¼±È£ÇÑ´Ù. + text/* media typeÀ» °¡ÁöÁö¸¸ ¸í½ÃÀûÀ¸·Î + ƯÁ¤ ¹®ÀÚÁýÇÕ°ú ¿¬°áµÇÁö¾ÊÀº º¯ÇüÀº ISO-8859-1·Î + °¡Á¤ÇÑ´Ù.
      10. + +
      11. ISO-8859-1ÀÌ ¾Æ´Ñ charset media ÆĶó¹ÌÅ͸¦ + °¡Áø º¯ÇüµéÀ» ¼±ÅÃÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é, ´ë½Å ¸ðµç + º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      12. + +
      13. °¡Àå ÀûÇÕÇÑ ÀÎÄÚµùÀ» °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù. + user-agent¿¡ ÀûÇÕÇÑ ÀÎÄÚµùÀ» °¡Áø º¯ÇüÀÌ ÀÖ´Ù¸é ±× + º¯Çü¸¸À» ¼±ÅÃÇÑ´Ù. ±×·¸Áö¾Ê°í ÀÎÄÚµùµÈ º¯Çü°ú ÀÎÄÚµù¾ÈµÈ + º¯ÇüÀÌ °°ÀÌ ÀÖ´Ù¸é ÀÎÄÚµù¾ÈµÊ º¯Çü¸¸À» ¼±ÅÃÇÑ´Ù. º¯ÇüÀÌ + ¸ðµÎ ÀÎÄÚµùµÇ¾ú°Å³ª ¸ðµÎ ÀÎÄÚµù¾ÈµÈ °æ¿ì ¸ðµç º¯ÇüÀ» + ¼±ÅÃÇÑ´Ù.
      14. + +
      15. content length°¡ °¡Àå ÀûÀº º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      16. + +
      17. ³²Àº °ÍÁß Ã¹¹øÀç º¯ÇüÀ» ¼±ÅÃÇÑ´Ù. ÀÌ´Â type-map + ÆÄÀÏÀÇ ¾Õ¿¡ ³ª¿Ô°Å³ª, µð·ºÅ丮¿¡¼­ º¯ÇüÀ» ÀÐÀº °æ¿ì + ÆÄÀϸíÀ» ASCII ÄÚµå ¼ø¼­·Î ÇÏ¿© ¾Õ¿¡ ³ª¿À´Â °ÍÀÌ´Ù.
      18. +
      +
    4. + +
    5. ÀÌÁ¦ ¾Ë°í¸®ÁòÀÌ 'ÃÖÀûÀÇ' º¯ÇüÀ» ¼±ÅÃÇß´Ù. ÀÌ°ÍÀ» ÀÀ´äÀ¸·Î + º¸³½´Ù. HTTP ÀÀ´ä Çì´õ Vary´Â Çù»óÀÇ ¹üÀ§¸¦ + ³ªÅ¸³»°Ô µÈ´Ù. (ºê¶ó¿ìÀú¿Í ij½¬´Â ÀÚ¿øÀ» ij½¬ÇÒ¶§ ÀÌ Á¤º¸¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.) ³¡.
    6. + +
    7. ÀÌ ´Ü°è¿¡ µµ´ÞÇß´Ù¸é (¸ðµÎ ºê¶ó¿ìÀú°¡ ¹ÞÁö¸øÇϱ⠶§¹®¿¡) + ¾î¶² º¯Çüµµ ¼±ÅÃÀÌ ¾ÈµÈ °æ¿ì´Ù. ("No acceptable + representation"¸¦ ¶æÇÏ´Â) »óÅ 406°ú ³»¿ëÀ¸·Î »ç¿ë°¡´ÉÇÑ + º¯ÇüÀÇ ¸ñ·ÏÀ» ´ãÀº HTML ¹®¼­¸¦ ÀÀ´äÀ» º¸³½´Ù. ¶Ç, HTML + Vary Çì´õ´Â º¯ÇüÀÇ ¹üÀ§¸¦ ³ªÅ¸³½´Ù.
    8. +
    + +
    top
    +
    +

    Ç°Áú°è¼ö Á¶ÀÛÇϱâ

    + +

    ¾ÆÆÄÄ¡´Â Á¾Á¾ À§ÀÇ ¾ÆÆÄÄ¡ Çù»ó ¾Ë°í¸®ÁòÀ» ¾ö°ÝÈ÷ ÁöÅ°Áö¾Ê°í + Ç°Áú°è¼ö¸¦ º¯°æÇÑ´Ù. ÀÌÀ¯´Â ¿ÏÀüÇÏ°í Á¤È®ÇÑ Á¤º¸¸¦ º¸³»Áö¾Ê´Â + ºê¶ó¿ìÀú¿¡°Ô (¾Ë°í¸®ÁòÀÇ) ´õ ³ªÀº °á°ú¸¦ º¸³»±â À§Çؼ­´Ù. + ³Î¸® ¾²ÀÌ´Â ºê¶ó¿ìÀúÁß ÀϺδ ÀÚÁÖ À߸øµÈ º¯ÇüÀ» ¼±ÅÃÇϵµ·Ï + Accept Çì´õ¸¦ º¸³½´Ù. ºê¶ó¿ìÀú°¡ ¿ÏÀüÇÏ°í ¿Ã¹Ù¸¥ + Á¤º¸¸¦ º¸³½´Ù¸é, Á¶ÀÛÀ» ÇÏÁö¾Ê´Â´Ù.

    + +

    Media Type°ú ¿ÍÀϵåÄ«µå

    + +

    Accept: ¿äû Çì´õ´Â media type¿¡ ´ëÇÑ ¼±È£¸¦ + ³ªÅ¸³½´Ù. ¶Ç, *´Â ¾î¶² ¹®ÀÚ¿­ÀÌ¶óµµ °¡´ÉÇϱ⶧¹®¿¡ "image/*"³ª + "*/*" °°ÀÌ '¿ÍÀϵåÄ«µå' media typeÀ» »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. ±×·¡¼­ + ´ÙÀ½°ú °°Àº ¿äûÀº:

    + +

    Accept: image/*, */*

    + +

    "image/"·Î ½ÃÀÛÇÏ´Â ¾î¶² type°ú ´Ù¸¥ ¾î¶² typeµµ °¡´ÉÇÔÀ» + ÀǹÌÇÑ´Ù. ¾î¶² ºê¶ó¿ìÀú´Â + ÀÚ½ÅÀÌ ½ÇÁ¦·Î ´Ù·ê ¼ö ÀÖ´Â type¿¡ Ãß°¡·Î ¿ÍÀϵåÄ«µå¸¦ º¸³½´Ù. + ¿¹¸¦ µé¸é:

    + +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */* +

    +

    ÀÌÀ¯´Â Á÷Á¢ ¿­°ÅÇÑ typeÀ» ¼±È£ÇÏÁö¸¸ ´Ù¸¥ Ç¥ÇöÀÌ ÀÖ´Ù¸é + ±×°Íµµ ±¦ÂúÀ½À» ³ªÅ¸³»±â À§Çؼ­´Ù. ºê¶ó¿ìÀú°¡ ½ÇÁ¦·Î ¿øÇÑ + °ÍÀº ´ÙÀ½°ú °°ÀÌ ¸í½ÃÀûÀ¸·Î Ç°Áú°ªÀ» »ç¿ëÇÑ °ÍÀÌ´Ù.

    +

    + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 +

    +

    Á÷Á¢ ¿­°ÅÇÑ typeÀº Ç°Áú°è¼ö°¡ ¾ø¾î¼­ ±âº»°ªÀÎ (°¡Àå ³ôÀº) + 1.0À» °¡Áø´Ù. ¿ÍÀϵåÄ«µå */*´Â ³·Àº ¼±È£µµ 0.01À» °¡Áö¹Ç·Î + Á÷Á¢ ¿­°ÅÇÑ type¿¡ ¸Â´Â º¯ÇüÀÌ ¾ø´Â °æ¿ì¿¡¸¸ ´Ù¸¥ typeµéÀÌ + »ç¿ëµÈ´Ù.

    + +

    Accept: Çì´õ¿¡ q °è¼ö°¡ ÀüÇô ¾ø°í + "*/*"°¡ ÀÖ´Ù¸é, ¾ÆÆÄÄ¡´Â ¹Ù¶÷Á÷ÇÑ ÇൿÀ» À§ÇØ q °ªÀ¸·Î 0.01À» + ÁöÁ¤ÇÑ´Ù. ¶Ç, "type/*" ÇüÅÂÀÇ ¿ÍÀϵåÄ«µå¿¡´Â ("*/*"º¸´Ù´Â + ´õ ¼±È£Çϵµ·Ï) 0.02¸¦ ÁöÁ¤ÇÑ´Ù. Accept: Çì´õ¿¡¼­ + q °è¼ö¸¦ °¡Áö´Â media typeÀÌ ÀÖ´Ù¸é ÀÌ·± Ưº°ÇÑ °ªÀ» Ãß°¡ÇÏÁö + ¾Ê´Â´Ù. ±×·¡¼­ ¸í½ÃÀûÀÎ Á¤º¸¸¦ º¸³»´Â ºê¶ó¿ìÀúÀÇ + ¿äûÀº ¿äûÇѵ¥·Î ó¸®ÇÑ´Ù.

    + + +

    ¾ð¾î(language) Çù»óÀÇ ¿¹¿Ü

    + +

    ¾ÆÆÄÄ¡ 2.0Àº ¾ð¾î Çù»óÀÌ ½ÇÆÐÇÑ °æ¿ì ºÎµå·´°Ô º¹±¸ÇϱâÀ§ÇØ + Çù»ó ¾Ë°í¸®Áò¿¡ »õ·Î ¿¹¿Ü¸¦ ¸î°³ Ãß°¡Çß´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡ ÆäÀÌÁö¸¦ ¿äûÇßÀ»¶§ ¼­¹ö°¡ ºê¶ó¿ìÀú°¡ + º¸³½ Accept-language¿¡ ¸Â´Â ÆäÀÌÁö¸¦ ´Ü ÇÑ°³¸¸ + ãÀ¸¸é ¹®Á¦°¡ ¾øÁö¸¸, ±×·¯Áö ¾ÊÀº °æ¿ì ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô + "No Acceptable Variant"³ª "Multiple Choices" ÀÀ´äÀ» º¸³½´Ù. + ÀÌ·± ¿À·ù¹®À» ÇÇÇϱâÀ§ÇØ ÀÌ °æ¿ì Accept-language¸¦ + ¹«½ÃÇÏ°í Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ¸íÈ®È÷ ¸ÂÁö´Â ¾ÊÁö¸¸ ¹®¼­¸¦ + º¸³»µµ·Ï ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ForceLanguagePriority + Áö½Ã¾î´Â ¼­¹ö°¡ ÀÌ·± ¿À·ù¹®Áß Çϳª ȤÀº µÑ´Ù¸¦ ¹«½ÃÇÏ°í + LanguagePriority + Áö½Ã¾î·Î ÆÇ´ÜÇϵµ·Ï ÇÑ´Ù.

    + +

    ¶Ç, ¼­¹ö´Â ¸Â´Â ¾ð¾î¸¦ ¸øãÀº °æ¿ì ºÎ¸ð¾ð¾î¸¦ ãÀ» ¼öµµ + ÀÖ´Ù. ¿¹¸¦ µé¾î Ŭ¶óÀ̾ðÆ®°¡ ¿µ±¹¿µ¾î¸¦ ¶æÇÏ´Â + en-GB ¾ð¾î·Î ¹®¼­¸¦ ¿äûÇÑ °æ¿ì, HTTP/1.1 Ç¥ÁØ¿¡ + µû¸£¸é ¼­¹ö´Â enÀ¸·Î¸¸ Ç¥½ÃµÈ ¹®¼­¸¦ ÀϹÝÀûÀ¸·Î + ¼±ÅÃÇÏÁö ¸øÇÑ´Ù. (±×·¡¼­ ¿µ±¹¿µ¾î¸¦ ÀÌÇØÇÏ´Â µ¶ÀÚ°¡ ÀϹÝÀûÀÎ + ¿µ¾îµµ ÀÌÇØÇÒ ¼ö ÀÖÀ¸¹Ç·Î Accept-Language Çì´õ¿¡ + en-GB¸¸ Æ÷ÇÔÇÏ°í enÀ» Æ÷ÇÔÇÏÁö¾ÊÀ¸¸é + °ÅÀÇ È®½ÇÈ÷ À߸øµÈ ¼³Á¤ÀÓÀ» À¯ÀÇÇ϶ó. ºÒÇàÈ÷µµ ÇöÀç ¸¹Àº + Ŭ¶óÀ̾ðÆ®µéÀº ÀÌ·± ½ÄÀ¸·Î ±âº»¼³Á¤µÇÀÖ´Ù.) ´Ù¸¥ ¾ð¾î¸¦ + ãÁö ¸øÇÏ¿© ¼­¹ö°¡ "No Acceptable Variants" ¿À·ù¸¦ º¸³»°Å³ª + LanguagePriority·Î + µ¹¾Æ°¡¾ß ÇÑ´Ù¸é, ¼­¹ö´Â ÇÏÀ§¾ð¾î ±Ô¾àÀ» ¹«½ÃÇÏ°í + en-GB¸¦ en ¹®¼­¿¡ ´ëÀÀÇÑ´Ù. + ¾Ï¹¬ÀûÀ¸·Î ¾ÆÆÄÄ¡´Â ºÎ¸ð¾ð¾î¸¦ ¸Å¿ì ³·Àº Ç°Áú°ªÀ¸·Î + Ŭ¶óÀ̾ðÆ®ÀÇ Çã¿ë¾ð¾î ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù. ±×·¯³ª Ŭ¶óÀ̾ðÆ®°¡ + "en-GB; q=0.9, fr; q=0.8"À» ¿äûÇÏ°í ¼­¹ö¿¡ "en"°ú "fr" + ¹®¼­°¡ ÀÖ´Ù¸é, "fr" ¹®¼­°¡ ¼±ÅõÊÀ» ÁÖÀÇÇ϶ó. ÀÌ´Â HTTP/1.1 + Ç¥ÁØÀ» ÁöÅ°°í, ¿Ã¹Ù·Î ¼³Á¤µÈ Ŭ¶óÀ̾ðÆ®¿Í È¿À²ÀûÀ¸·Î + µ¿ÀÛÇϱâÀ§ÇÔÀÌ´Ù.

    + +

    »ç¿ëÀÚ°¡ ¼±È£ÇÏ´Â ¾ð¾î¸¦ ¾Ë¾Æ³»±âÀ§ÇÑ (ÄíÅ°³ª Ưº°ÇÑ + URL-°æ·Î °°Àº) °í±Þ ±â¹ýÀ» Áö¿øÇϱâÀ§ÇØ ¾ÆÆÄÄ¡ 2.0.47ºÎÅÍ + mod_negotiationÀº prefer-language¶ó´Â + ȯ°æº¯¼ö¸¦ ÀνÄÇÑ´Ù. ÀÌ È¯°æº¯¼ö°¡ + Á¸ÀçÇÏ°í ÀûÀýÇÑ ¾ð¾îű׸¦ Æ÷ÇÔÇÑ´Ù¸é, + mod_negotiationÀº ÇØ´çÇÏ´Â º¯ÇüÀ» ¼±ÅÃÇÏ·Á°í + ½ÃµµÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ Çù»ó°úÁ¤À» ½ÃÀÛÇÑ´Ù.

    + +

    ¿¹Á¦

    + SetEnvIf Cookie "language=(.+)" prefer-language=$1 +

    + +
    top
    +
    +

    ÀÚ¿¬½º·¯¿î(transparent) ³»¿ëÇù»óÀÇ È®Àå

    + +

    ¾ÆÆÄÄ¡´Â ´ÙÀ½°ú °°ÀÌ ÀÚ¿¬½º·¯¿î ³»¿ëÈ®Àå ÇÁ·ÎÅäÄÝÀ» (RFC 2295) +È®ÀåÇÑ´Ù. º¯Çü ¸ñ·ÏÀÇ »õ·Î¿î {encoding ..}´Â ƯÁ¤ +content-encodingÀ» °¡Áø º¯Çü¸¸À» ÁöĪÇÑ´Ù. RVSA/1.0 ¾Ë°í¸®ÁòÀº +(RFC 2296) ¸ñ·Ï¿¡¼­ ÀÎÄÚµùµÈ º¯ÇüÀ» ÀνÄÇÒ ¼ö ÀÖ°í, ÀÎÄÚµùÀÌ +Accept-Encoding ¿äû Çì´õ¿¡ ¸Â´Â °æ¿ì ÀÎÄÚµùµÈ +º¯Çüµéµµ È帷Π»ç¿ëÇϵµ·Ï È®ÀåµÇ¾ú´Ù. RVSA/1.0 ±¸ÇöÀº ÃÖÀûÀÇ +º¯ÇüÀ» ã±â Àü¿¡ °è»êµÈ Ç°Áú°è¼ö¸¦ ¼Ò¼öÁ¡ 5ÀÚ¸®¿¡¼­ ¹Ý¿Ã¸²ÇÏÁö +¾Ê´Â´Ù.

    +
    top
    +
    +

    ÇÏÀÌÆÛ¸µÅ©¿Í À̸§±ÔÄ¢¿¡ ´ëÇÏ¿©

    + +

    ¾ð¾î(language) Çù»óÀ» »ç¿ëÇÑ´Ù¸é ÆÄÀÏÀº ¿©·¯ È®ÀåÀÚ¸¦ + °¡Áö°í È®ÀåÀÚÀÇ ¼ø¼­´Â º¸Åë °ü°è¾øÀ¸¹Ç·Î ÆÄÀÏ¸í¿¡ ¿©·¯ ´Ù¸¥ + À̸§±ÔÄ¢À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. (ÀÚ¼¼ÇÑ ³»¿ëÀº mod_mime ¹®¼­¸¦ + Âü°íÇ϶ó.)

    + +

    ÀüÇüÀûÀÎ ÆÄÀÏÀº MIME-type È®ÀåÀÚ (¿¹¸¦ µé¾î, + html), °æ¿ì¿¡ µû¶ó encoding È®ÀåÀÚ (¿¹¸¦ + µé¾î, gz), ÆÄÀÏ¿¡ ¿©·¯ ¾ð¾î º¯ÇüÀÌ ÀÖ´Â + °æ¿ì ¹°·Ð ¾ð¾î È®ÀåÀÚ¸¦ (¿¹¸¦ µé¾î, en) + °¡Áø´Ù.

    + +

    ¿¹Á¦:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    ´ÙÀ½Àº ¸î¸î ÆÄÀϸí°ú ±× ÆÄÀÏ¿¡ ´ëÇÑ À¯È¿ÇÏ°í À¯È¿ÇÏÁö¾ÊÀº + ÇÏÀÌÆÛ¸µÅ©¸¦ º¸ÀδÙ:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ÆÄÀϸíÀ¯È¿ÇÑ ÇÏÀÌÆÛ¸µÅ©À¯È¿ÇÏÁö¾ÊÀº ÇÏÀÌÆÛ¸µÅ©
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    À§ Ç¥¸¦ º¸¸é ÇÏÀÌÆÛ¸µÅ©¿¡ ¾î¶² È®ÀåÀÚµµ ¾ø´Â À̸§À» + (¿¹¸¦ µé¾î, foo) Ç×»ó »ç¿ëÇÒ ¼ö ÀÖÀ½À» + ¾Ë ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀåÁ¡Àº ¹®¼­ÀÇ ½ÇÁ¦ Á¾·ù¸¦ ¼û±æ ¼ö À־, + ¿¹¸¦ µé¾î ÇÏÀÌ·¯¸µÅ© ÂüÁ¶¸¦ ¼öÁ¤ÇϾʰí + html ÆÄÀÏÀ» shtmlÀ̳ª + cgi·Î º¯°æÇÒ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù.

    + +

    °è¼Ó ÇÏÀÌÆÛ¸µÅ©¿¡ MIME-typeÀ» (¿¹¸¦ µé¾î, + foo.html) »ç¿ëÇÏ°í ½Í´Ù¸é (encoding È®ÀåÀÚ°¡ + ÀÖ´Ù¸é À̰͵µ Æ÷ÇÔÇÏ¿©) ¾ð¾î È®ÀåÀÚ¸¦ MIME-type È®ÀåÀÚº¸´Ù + ¿À¸¥ÂÊ¿¡ (¿¹¸¦ µé¾î, foo.html.en) + µÎ¾î¾ßÇÑ´Ù.

    +
    top
    +
    +

    ij½¬¿¡ ´ëÇÏ¿©

    + +

    ij½¬°¡ Ç¥ÇöÀ» ÀúÀåÇϸé Ç¥Çö°ú ¿äû URLÀ» ¿¬°ü½ÃŲ´Ù. + ´ÙÀ½¹ø ±× URLÀ» ¿äûÇϸé ij½¬´Â ÀúÀåµÈ Ç¥ÇöÀ» »ç¿ëÇÑ´Ù. + ±×·¯³ª ¼­¹ö¿Í Çù»óÀÌ °¡´ÉÇÑ ÀÚ¿øÀÎ °æ¿ì ù¹ø° ¿äûÇÑ º¯Çü¸¸ + ij½¬µÇ¾î ÀÌÈÄ ¿äûÀº ij½¬µÈ À߸øµÈ ÀÀ´äÀ» ¾òÀ» ¼ö ÀÖ´Ù. + À̸¦ ¸·±âÀ§ÇØ ¾ÆÆÄÄ¡´Â º¸Åë ³»¿ëÇù»óÈÄ ¹ÝȯµÇ´Â ¸ðµç ¿äû¿¡ + HTTP/1.0 Ŭ¶óÀ̾ðÆ®°¡ ij½¬¸¦ ¸øÇϵµ·Ï Ç¥½Ã¸¦ ÇÑ´Ù. ¶Ç, ¾ÆÆÄÄ¡´Â + Çù»óÇÑ ÀÀ´äÀÇ Ä³½¬¸¦ Çã¿ëÇÏ´Â HTTP/1.1 ÇÁ·ÎÅäÄÝÀÇ ±â´ÉÀ» + Áö¿øÇÑ´Ù.

    + +

    CacheNegotiatedDocs + Áö½Ã¾î´Â HTTP/1.0 ȣȯ Ŭ¶óÀ̾ðÆ®(ºê¶ó¿ìÀú ȤÀº ij½¬)°¡ + º¸³½ ¿äû¿¡ ´ëÇØ Çù»óÇÑ ÀÀ´äÀ» ij½¬ÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + ¼­¹ö³ª °¡»óÈ£½ºÆ® ¼³Á¤¿¡ »ç¿ëÇϸç, ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¾Ê´Â´Ù. + ÀÌ Áö½Ã¾î´Â HTTP/1.1 Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû°ú´Â °ü°è°¡ ¾ø´Ù.

    + +

    HTTP/1.1 Ŭ¶óÀ̾ðÆ®¿¡°Ô ¾ÆÆÄÄ¡´Â ÀÀ´äÀÇ Çù»ó ¹üÀ§¸¦ + ¾Ë·ÁÁÖ´Â Vary HTTP ÀÀ´äÇì´õ¸¦ º¸³½´Ù. ÀÌ Á¤º¸¸¦ + »ç¿ëÇÏ¿© ´ÙÀ½ ¿äûÀ» ij½¬µÈ º¹»çº»À¸·Î ´ëüÇÒ ¼ö ÀÖ´ÂÁö + ÆÇ´ÜÇÒ ¼ö ÀÖ´Ù. Çé»óÀÇ ¹üÀ§¿Í °ü°è¾øÀÌ Ä³½¬µÈ º¹»çº»À» + ±ÇÇÑ´Ù¸é force-no-vary ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +
    top
    +
    +

    ´Ù¸¥ Á¤º¸

    + +

    ³»¿ëÇù»ó¿¡ ´ëÇÑ ´Ù¸¥ Á¤º¸´Â Alan J. Flavell°¡ ¾´ Language + Negotiation Notes¸¦ Âü°íÇ϶ó. ±×·¯³ª ÀÌ ¹®¼­´Â ¾ÆÁ÷ + ¾ÆÆÄÄ¡ 2.0ÀÇ º¯È­¸¦ ¹Ý¿µÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/content-negotiation.xml b/trunk/docs/manual/content-negotiation.xml new file mode 100644 index 0000000000..500511403d --- /dev/null +++ b/trunk/docs/manual/content-negotiation.xml @@ -0,0 +1,676 @@ + + + + + + + + + +Content Negotiation + + + +

    Apache supports content negotiation as described in + the HTTP/1.1 specification. It can choose the best + representation of a resource based on the browser-supplied + preferences for media type, languages, character set and + encoding. It also implements a couple of features to give + more intelligent handling of requests from browsers that send + incomplete negotiation information.

    + +

    Content negotiation is provided by the + mod_negotiation module, which is compiled in + by default.

    +
    + +
    About Content Negotiation + +

    A resource may be available in several different + representations. For example, it might be available in + different languages or different media types, or a combination. + One way of selecting the most appropriate choice is to give the + user an index page, and let them select. However it is often + possible for the server to choose automatically. This works + because browsers can send, as part of each request, information + about what representations they prefer. For example, a browser + could indicate that it would like to see information in French, + if possible, else English will do. Browsers indicate their + preferences by headers in the request. To request only French + representations, the browser would send

    + +Accept-Language: fr + +

    Note that this preference will only be applied when there is + a choice of representations and they vary by language.

    + +

    As an example of a more complex request, this browser has + been configured to accept French and English, but prefer + French, and to accept various media types, preferring HTML over + plain text or other text types, and preferring GIF or JPEG over + other media types, but also allowing any other media type as a + last resort:

    + + + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +
    + +

    Apache supports 'server driven' content negotiation, as + defined in the HTTP/1.1 specification. It fully supports the + Accept, Accept-Language, + Accept-Charset andAccept-Encoding + request headers. Apache also supports 'transparent' + content negotiation, which is an experimental negotiation + protocol defined in RFC 2295 and RFC 2296. It does not offer + support for 'feature negotiation' as defined in these RFCs.

    + +

    A resource is a conceptual entity + identified by a URI (RFC 2396). An HTTP server like Apache + provides access to representations 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 negotiable and each of its + representations is termed a variant. The ways + in which the variants for a negotiable resource vary are called + the dimensions of negotiation.

    +
    + +
    Negotiation in Apache + +

    In order to negotiate a resource, the server needs to be + given information about each of the variants. This is done in + one of two ways:

    + +
      +
    • Using a type map (i.e., a *.var + file) which names the files containing the variants + explicitly, or
    • + +
    • Using a 'MultiViews' search, where the server does an + implicit filename pattern match and chooses from among the + results.
    • +
    + +
    Using a type-map file + +

    A type map is a document which is associated with the + handler named type-map (or, for + backwards-compatibility with older Apache configurations, the + MIME type application/x-type-map). Note that to + use this feature, you must have a handler set in the + configuration that defines a file suffix as + type-map; this is best done with

    + +AddHandler type-map .var + +

    in the server configuration file.

    + +

    Type map files should have the same name as the resource + which they are describing, and have an entry for each available + variant; these entries 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 shown below. + This file would be named foo.var, as it describes + a resource named foo.

    + + + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +
    +

    Note also that a typemap file will take precedence over the + filename's extension, even when Multiviews is on. 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):

    + + + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +
    + +

    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. 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.

    + +

    The full list of headers recognized is available in the mod_negotation + typemap documentation.

    +
    + +
    Multiviews + +

    MultiViews is a per-directory option, meaning it + can be set with an Options + directive within a Directory, Location or Files section in + httpd.conf, or (if AllowOverride is properly set) in + .htaccess files. Note that Options All + does not set MultiViews; you have to ask for it by + name.

    + +

    The effect of MultiViews is as follows: if the + server receives a request for /some/dir/foo, if + /some/dir has MultiViews enabled, and + /some/dir/foo does not exist, then the + server reads the directory looking for files named foo.*, and + effectively fakes up a 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.

    + +

    MultiViews may also apply to searches for the file + named by the DirectoryIndex directive, if the + server is trying to index a directory. If the configuration files + specify

    +DirectoryIndex index +

    then the server will arbitrate between index.html + and index.html3 if both are present. If neither + are present, and index.cgi is there, the server + will run it.

    + +

    If one of the files found when reading the directory does not + have an extension recognized by mod_mime to designate + its Charset, Content-Type, Language, or Encoding, then the result + depends on the setting of the MultiViewsMatch directive. This + directive determines whether handlers, filters, and other + extension types can participate in MultiViews negotiation.

    +
    +
    + +
    The Negotiation Methods + +

    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 invokes one of two methods to decide on the + 'best' variant to return, if any. It is not necessary to know + any of the details of how negotiation actually takes place in + order to use Apache's content negotiation features. However the + rest of this document explains the methods used for those + interested.

    + +

    There are two negotiation methods:

    + +
      +
    1. Server driven negotiation with the Apache + algorithm is used in the normal case. The Apache + algorithm is explained in more detail below. When this + algorithm is used, Apache can sometimes 'fiddle' the quality + factor of a particular dimension to achieve a better result. + The ways Apache can fiddle quality factors is explained in + more detail below.
    2. + +
    3. Transparent content negotiation is used + when the browser specifically requests this through the + mechanism defined in RFC 2295. This negotiation method gives + the browser full control over deciding on the 'best' variant, + the result is therefore dependent on the specific algorithms + used by the browser. As part of the transparent negotiation + process, the browser can ask Apache to run the 'remote + variant selection algorithm' defined in RFC 2296.
    4. +
    + +
    Dimensions of Negotiation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DimensionNotes
    Media TypeBrowser indicates preferences with the Accept + header field. Each item can have an associated quality factor. + Variant description can also have a quality factor (the "qs" + parameter).
    LanguageBrowser 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.
    EncodingBrowser indicates preference with the + Accept-Encoding header field. Each item can have + a quality factor.
    CharsetBrowser 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.
    +
    + +
    Apache Negotiation Algorithm + +

    Apache can use the following algorithm to select the 'best' + variant (if any) to return to the browser. This algorithm is + not further configurable. It operates as follows:

    + +
      +
    1. First, for each dimension of the negotiation, check the + appropriate Accept* header field and assign a + quality to each variant. If the Accept* header for + any dimension implies that this variant is not acceptable, + eliminate it. If no variants remain, go to step 4.
    2. + +
    3. + Select the 'best' variant by a process of elimination. Each + of the following tests is applied in order. Any variants + not selected at each test are eliminated. After each test, + if only one variant remains, select it as the best match + and proceed to step 3. If more than one variant remains, + move on to the next test. + +
        +
      1. Multiply the quality factor from the Accept + header with the quality-of-source factor for this variants + media type, and select the variants with the highest + value.
      2. + +
      3. Select the variants with the highest language quality + factor.
      4. + +
      5. Select the variants with the best language match, + using either the order of languages in the + Accept-Language header (if present), or else + the order of languages in the LanguagePriority + directive (if present).
      6. + +
      7. Select the variants with the highest 'level' media + parameter (used to give the version of text/html media + types).
      8. + +
      9. Select variants with the best charset media + parameters, as given on the Accept-Charset + header line. Charset ISO-8859-1 is acceptable unless + explicitly excluded. Variants with a text/* + media type but not explicitly associated with a particular + charset are assumed to be in ISO-8859-1.
      10. + +
      11. Select those variants which have associated charset + media parameters that are not ISO-8859-1. If + there are no such variants, select all variants + instead.
      12. + +
      13. 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 and non-encoded variants, + select only the unencoded variants. If either all + variants are encoded or all variants are not encoded, + select all variants.
      14. + +
      15. Select the variants with the smallest content + length.
      16. + +
      17. Select the first variant of those remaining. This + will be either the first listed in the type-map file, or + when variants are read from the directory, the one whose + file name comes first when sorted using ASCII code + order.
      18. +
      +
    4. + +
    5. The algorithm has now selected one 'best' variant, so + return it as the response. The HTTP response header + Vary is set to indicate the dimensions of + negotiation (browsers and caches can use this information when + caching the resource). End.
    6. + +
    7. 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 dimensions of variance.
    8. +
    +
    +
    + +
    Fiddling with Quality + Values + +

    Apache sometimes changes the quality values from what would + be expected by a strict interpretation of the Apache + negotiation algorithm above. This is to get a better result + from the algorithm for browsers which do not send full or + accurate information. Some of the most popular browsers send + Accept header information which would otherwise + result in the selection of the wrong variant in many cases. If a + browser sends full and correct information these fiddles will not + be applied.

    + +
    Media Types and Wildcards + +

    The Accept: request header indicates preferences + for media types. It can also include 'wildcard' media types, such + as "image/*" or "*/*" where the * matches any string. So a request + including:

    + +Accept: image/*, */* + +

    would indicate that any type starting "image/" is acceptable, + as is any other type. + Some browsers routinely send wildcards in addition to explicit + types they can handle. For example:

    + + + Accept: text/html, text/plain, image/gif, image/jpeg, */* + +

    The intention of this is to indicate that the explicitly listed + types are preferred, but if a different representation is + available, that is ok too. Using explicit quality values, + what the browser really wants is something like:

    + + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 + +

    The explicit types have no quality factor, so they default to a + preference of 1.0 (the highest). The wildcard */* is given a + low preference of 0.01, so other types will only be returned if + no variant matches an explicitly listed type.

    + +

    If the Accept: header contains no q + factors at all, Apache sets the q value of "*/*", if present, to + 0.01 to emulate the desired behavior. It also sets the q value of + wildcards of the format "type/*" to 0.02 (so these are preferred + over matches against "*/*". If any media type on the + Accept: header contains a q factor, these special + values are not applied, so requests from browsers which + send the explicit information to start with work as expected.

    +
    + +
    Language Negotiation Exceptions + +

    New in Apache 2.0, some exceptions have been added to the + negotiation algorithm to allow graceful fallback when language + negotiation fails to find a match.

    + +

    When a client requests a page on your server, but the server + cannot find a single page that matches the + Accept-language sent by + the browser, the server will return either a "No Acceptable + Variant" or "Multiple Choices" response to the client. To avoid + these error messages, it is possible to configure Apache to ignore + the Accept-language in these cases and provide a + document that does not explicitly match the client's request. The + ForceLanguagePriority + directive can be used to override one or both of these error + messages and substitute the servers judgement in the form of the + LanguagePriority + directive.

    + +

    The server will also attempt to match language-subsets when no + other match can be found. For example, if a client requests + documents with the language en-GB for British + English, the server is not normally allowed by the HTTP/1.1 + standard to match that against a document that is marked as simply + en. (Note that it is almost surely a configuration + error to include en-GB and not en in the + Accept-Language header, since it is very unlikely + that a reader understands British English, but doesn't understand + English in general. Unfortunately, many current clients have + default configurations that resemble this.) However, if no other + language match is possible and the server is about to return a "No + Acceptable Variants" error or fallback to the LanguagePriority, the server + will ignore the subset specification and match en-GB + against en documents. Implicitly, Apache will add + the parent language to the client's acceptable language list with + a very low quality value. But note that if the client requests + "en-GB; q=0.9, fr; q=0.8", and the server has documents + designated "en" and "fr", then the "fr" document will be returned. + This is necessary to maintain compliance with the HTTP/1.1 + specification and to work effectively with properly configured + clients.

    + +

    In order to support advanced techniques (such as cookies or + special URL-paths) to determine the user's preferred language, + since Apache 2.0.47 mod_negotiation recognizes + the environment variable + prefer-language. If it exists and contains an + appropriate language tag, mod_negotiation will + try to select a matching variant. If there's no such variant, + the normal negotiation process applies.

    + + Example + SetEnvIf Cookie "language=(.+)" prefer-language=$1 + +
    +
    + +
    Extensions to Transparent Content +Negotiation + +

    Apache extends the transparent content negotiation protocol (RFC +2295) as follows. A new {encoding ..} element is used in +variant lists to label variants which are available with a specific +content-encoding only. The implementation of the RVSA/1.0 algorithm +(RFC 2296) is extended to recognize encoded variants in the list, and +to use them as candidate variants whenever their encodings are +acceptable according to the Accept-Encoding request +header. The RVSA/1.0 implementation does not round computed quality +factors to 5 decimal places before choosing the best variant.

    +
    + +
    Note on hyperlinks and naming conventions + +

    If you are using language negotiation you can choose between + different naming conventions, because files can have more than + one extension, and the order of the extensions is normally + irrelevant (see the mod_mime documentation + for details).

    + +

    A typical file has a MIME-type extension (e.g., + html), maybe an encoding extension (e.g., + gz), and of course a language extension + (e.g., en) when we have different + language variants of this file.

    + +

    Examples:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    Here some more examples of filenames together with valid and + invalid hyperlinks:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FilenameValid hyperlinkInvalid hyperlink
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    Looking at the table above, you will notice that it is always + possible to use the name without any extensions in a hyperlink + (e.g., foo). The advantage is that you + can hide the actual type of a document rsp. file and can change + it later, e.g., from html to + shtml or cgi without changing any + hyperlink references.

    + +

    If you want to continue to use a MIME-type in your + hyperlinks (e.g. foo.html) the language + extension (including an encoding extension if there is one) + must be on the right hand side of the MIME-type extension + (e.g., foo.html.en).

    +
    + +
    Note on Caching + +

    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 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.

    + +

    For requests which come from a HTTP/1.0 compliant client + (either a browser or a cache), the directive CacheNegotiatedDocs 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.

    + +

    For HTTP/1.1 clients, Apache sends a Vary HTTP + response header to indicate the negotiation dimensions for the + response. Caches can use this information to determine whether a + subsequent request can be served from the local copy. To + encourage a cache to use the local copy regardless of the + negotiation dimensions, set the force-no-vary environment variable.

    + +
    + +
    More Information + +

    For more information about content negotiation, see Alan + J. Flavell's Language + Negotiation Notes. But note that this document may not be + updated to include changes in Apache 2.0.

    +
    + +
    diff --git a/trunk/docs/manual/content-negotiation.xml.ja b/trunk/docs/manual/content-negotiation.xml.ja new file mode 100644 index 0000000000..5d2b10b029 --- /dev/null +++ b/trunk/docs/manual/content-negotiation.xml.ja @@ -0,0 +1,714 @@ + + + + + + + + + +$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + + + +

    Apache $B$O(B HTTP/1.1 $B$N5,3J$K5-=R$5$l$F$$$k%3%s%F%s%H%M%4%7%(!<%7%g%s$r(B + $B%5%]!<%H$7$F$$$^$9!#(B + $B%V%i%&%6$K$h$jDs6!$5$l$?%a%G%#%"%?%$%W!"(B + $B8@8l!"J8;z%;%C%H!"%(%s%3!<%G%#%s%0$NM%@h798~$K4p$E$$$F!"(B + $B:GE,$J%j%=!<%9$NI=8=$rA*Br$G$-$^$9!#(B + $B$^$?!"IT40A4$J%M%4%7%(!<%7%g%s>pJs$rAw$C$F$/$k%V%i%&%6$+$i$N%j%/%(%9%H$r(B + $B$b$C$H8-$/ + +

    $B%3%s%F%s%H%M%4%7%(!<%7%g%s$O(B + mod_negotiation + $B%b%8%e!<%k$K$h$C$FDs6!$5$l$F$$$F!"%G%U%)%k%H$GAH$_9~$^$l$F$$$^$9!#(B

    +
    + +
    $B%3%s%F%s%H%M%4%7%(!<%7%g%s$K$D$$$F(B + +

    $B%j%=!<%9$O!"4v$D$+0[$J$C$?I=8=$GMxMQ$G$-$k>l9g$,$"$j$^$9!#(B + $BNc$($P!"0[$J$k8@8l$d0[$J$k%a%G%#%"%?%$%W!"(B + $B$^$?$O$=$l$i$NAH$_9g$o$;$GMxMQ$G$-$k$+$bCN$l$^$;$s!#(B + $B$b$C$H$bE,$7$?A*Br$r$9$kJ}K!$N0l$D$K$O!"%$%s%G%C%/%9%Z!<%8$r(B + $B%f!<%6$K8+$;$F!"%f!<%6$KA*$s$G$b$i$&J}K!$,$"$j$^$9!#(B + $B$7$+$7!"%5!<%P$,<+F0E*$KA*$V$3$H$,$G$-$k>l9g$,B?$/$"$j$^$9!#(B + $B$3$l$O!"%V%i%&%6$,%j%/%(%9%HKh$K!"(B + $B$I$NI=8=$rSO9%$9$k$+$H$$$&>pJs$rAw$k$3$H$GF0:n$7$F$$$^$9!#(B + $BNc$($P%V%i%&%6$O!"2DG=$J$i%U%i%s%98l$G>pJs$r8+$?$$!"(B + $BIT2DG=$J$i$=$NBe$o$j$K1Q8l$G$b$h$$$H!"(B + $B<+J,$NSO9%$rCN$i$;$k$3$H$,$G$-$^$9!#(B + $B%V%i%&%6$O%j%/%(%9%H$N%X%C%@$G<+J,$NM%@h798~$rCN$i$;$^$9!#(B + $B%U%i%s%98l$N$_$NI=8=$rMW5a$9$k>l9g$O!"%V%i%&%6$O + +Accept-Language: fr + +

    $B$3$NM%@h798~$O!"A*Br2DG=$JI=8=$,B8:_$7$F!"(B + $B8@8l$K$h$C$FMM!9$JI=8=$,$"$k>l9g$K$N$_E,MQ$5$l$k(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B

    + +

    $B$b$C$HJ#;($J%j%/%(%9%H$NNc$r5s$2$^$7$g$&!#(B + $B$3$N%V%i%&%6$O%U%i%s%98l$H1Q8l$r$N%?%$%W$h$j$O(B HTML $B$r9%$`!"(B + $BB>$N%a%G%#%"%?%$%W$h$j$O(B GIF $B$d(B JPEG $B$r9%$`!"$7$+$7:G=*$N%a%G%#%"%?%$%W$b + + + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +
    + +

    Apache $B$O(B HTTP/1.1 $B5,3J$GDj5A$5$l$F$$$k(B 'server + driven' $B%3%s%F%s%H%M%4%7%(!<%7%g%s$r%5%]!<%H$7$F$$$^$9!#(B + Accept, Accept-Language, + Accept-Charset, Accept-Encoding + $B%j%/%(%9%H%X%C%@$r40A4$K%5%]!<%H$7$F$$$^$9!#(BApache $B$O(B + 'transparent' $B%3%s%F%s%H%M%4%7%(!<%7%g%s$b%5%]!<%H$7$F$$$^$9$,!"(B + $B$3$l$O(B RFC 2295 $B$H(B RFC 2296 $B$GDj5A$5$l$F$$$k;n83E*$J(B + $B%M%4%7%(!<%7%g%s%W%m%H%3%k$G$9!#(B + $B$3$l$i$N(B RFC$B$GDj5A$5$l$F$$$k(B 'feature negotiation' + $B$O%5%]!<%H$7$F$$$^$;$s!#(B

    + +

    $B%j%=!<%9(B$B$H$O(B URI + $B$GFCDj$5$l$k35G0>e$N$b$N$N$3$H$G$9(B (RFC 2396)$B!#(B Apache + $B$N$h$&$J(B HTTP $B%5!<%P$O!"$=$NL>A06u4V$NCf$G$N(B + $B%j%=!<%9$N(B$BI=8=(B$B$X$N%"%/%;%9$rDs6!$7$^$9!#(B + $B$=$l$>$l$NI=8=$O(B + $BDj5A$5$l$?%a%G%#%"%?%$%W!"J8;z%;%C%H!"%(%s%3!<%G%#%s%0Ey$N(B + $BIUB0$7$?!"%P%$%HNs$N7A<0$G$9!#(B + $B$=$l$>$l$N%j%=!<%9$O$"$k;~E@$G(B 0 $B8D!"(B1 $B8D!"$=$l0J>e$NI=8=$H(B + $B4XO"IU$1$i$l$k2DG=@-$,$"$j$^$9!#J#?t$NI=8=$,MxMQ$G$-$k>l9g$O!"(B + $B%j%=!<%9$O(B$B%M%4%7%(!<%7%g%s2DG=$G$"$k(B$B$H$5$l!"(B + $B8D!9$NI=8=$O(B variant $B$H8F$P$l$^$9!#(B + $B%M%4%7%(!<%7%g%s2DG=$J%j%=!<%9$N(B variant $B$,0[$J$k!"(B + $B$=$N>uBV$r;X$7$F!"(B + $B%M%4%7%(!<%7%g%s$N(B$B$B$H8F$S$^$9!#(B

    +
    + +
    Apache $B$K$*$1$k%M%4%7%(!<%7%g%s(B + +

    $B%j%=!<%9$r%M%4%7%(!<%7%g%s$9$k$?$a$K$O!"(B + $B%5!<%P$O(B variant $B$=$l$>$l$K$D$$$F$N>pJs$rCN$C$F$*$/I,MW$,$"$j$^$9!#(B + $B$3$l$O0J2<$NFs$D$NJ}K!$N$I$A$i$+$G9T$o$l$^$9!#(B

    + +
      +
    • $B%?%$%W%^%C%W(B + ($B$9$J$o$A(B *.var $B%U%!%$%k(B) + $B$r;H$&J}K!!#(B $B$3$l$O(B variant + $B$rL@<(E*$K5s$2$F$$$k%U%!%$%k$r;XDj$7$^$9!#(B
    • + +
    • 'Multiviews' + $B$r;H$C$F!"%5!<%P$,0EL[$NFb$K%U%!%$%kL>$K%Q%?!<%s>H9g$r(B + $B9T$J$C$F$=$N7k2L$+$iA*Br$9$kJ}K!!#(B
    • +
    + +
    type-map $B%U%!%$%k$r;H$&(B + +

    $B%?%$%W%^%C%W$O(B type-map $B%O%s%I%i(B + ($B$b$7$/$O!"8E$$(B Apache + $B$N@_Dj$H2<0L8_49$G$"$k(B MIME $B%?%$%W(B + application/x-type-map) + $B$K4XO"IU$1$i$l$?%I%-%e%a%s%H$G$9!#(B + $B$3$N5!G=$r;H$&$?$a$K$O!"$"$k%U%!%$%k$N3HD%;R$r(B + type-map + $B$H$7$FDj5A$9$k$h$&$J%O%s%I%i$r!"(B + $B@_Dj%U%!%$%kCf$KCV$/I,MW$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$3$l$O(B

    + +AddHandler type-map .var + +

    $B$r%5!<%P@_Dj%U%!%$%kCf$K=q$/$3$H$,0lHVNI$$J}K!$G$9!#(B

    + +

    $B%?%$%W%^%C%W%U%!%$%k$O5-=R$9$k%j%=!<%9$HF1$8L>A0$r;}$C$F$$$F!"(B + $BMxMQ2DG=$J(B variant $B$=$l$>$l$N%(%s%H%j$r;}$C$F$$$kI,MW$,$"$j$^$9!#(B + $B$=$7$F!"$3$N%(%s%H%j$OO"B3$7$?(B HTTP $B$N%X%C%@9T$G9=@.$5$l$^$9!#(B + $B0[$J$k(B variant $B$N$?$a$N%(%s%H%j$O6u9T$G6h@Z$i$l$F$$$^$9!#(B + $B%(%s%H%jCf$K6u9T$,J#?t$"$C$F$O$$$1$^$;$s!#(B + $B=,47E*$K$O!"%^%C%W%U%!%$%k$OA4BN$r7k9g$7$?$b$N$N%(%s%H%j$+$i;O$^$j$^$9(B + ($B$7$+$7$3$l$OI,?\$G$O$J$/!"$"$C$?$H$7$F$bL5;k$5$l$k$b$N$G$9(B)$B!#(B + $Bfoo + $B$r5-=R$7$F$$$k$N$G!"(Bfoo.var $B$H$$$&L>A0$K$J$j$^$9!#(B

    + + + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +
    +

    $B$?$H$((B MultiViews $B$r;HMQ$9$k$h$&$K$J$C$F$$$?$H$7$F$b!"(B + $B%U%!%$%kL>$N3HD%;R$h$j%?%$%W%^%C%W$NJ}$,M%@h8"$r;}$D$H$$$&$3$H$K$b(B + $BCm0U$7$F$/$@$5$$!#(B + variant $B$NIJ + + + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +
    + +

    qs $BCM$NHO0O$O(B 0.000 $B$+$i(B 1.000 $B$G$9!#(Bqs $BCM$,(B + 0.000 $B$N(B variant $B$O7h$7$F(B + $BA*Br$5$l$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B'qs' $BCM$N$J$$(B variant + $B$O(B qs $BCM(B 1.0 $B$r(B $BM?$($i$l$^$9!#(Bqs + $B%Q%i%a!<%?$O%/%i%$%"%s%H$NG=NO$K4X78L5$/!"B>$N(B variant $B$H(B + $BHf3S$7$?$H$-$N(B variant + $B$NAjBPE*$J!VIJ + +

    $BG'<1$5$l$k%X%C%@$N0lMw$O(B + mod_negotiation + $B%I%-%e%a%s%H$K$"$j$^$9!#(B

    +
    + +
    Multiviews + +

    MultiViews $B$O%G%#%l%/%H%jKh$N%*%W%7%g%s$G!"(B + httpd.conf$B%U%!%$%k$N(B + Directory, + Location, + Files + $B%;%/%7%g%sCf$d!"(B(AllowOverride + $B$,E,@Z$JCM$K(B $B@_Dj$5$l$F$$$k$H(B) .htaccess + $B%U%!%$%k$G(B Options + $B%G%#%l%/%F%#%V$K$h$C$F@_Dj$9$k$3$H$,$G$-$^$9!#(B + Options All $B$O(B + MultiViews + $B$r%;%C%H$7$J$$$3$H$KCm0U$7$F$/$@$5$$!#L@<(E*$K(B + $B$=$NL>A0$r=q$/I,MW$,$"$j$^$9!#(B

    + +

    MultiViews $B$N8z2L$O0J2<$N$h$&$K$J$j$^$9(B: + $B%5!<%P$,(B /some/dir/foo + $B$X$N%j%/%(%9%H$r/some/dir $B$G(B + MultiViews $B$,M-8z$G$"$C$F!"(B + /some/dir/foo $B$,B8:_(B$B$7$J$$(B$B>l9g!"(B + $B%5!<%P$O%G%#%l%/%H%j$rFI$s$G(B foo.* + $B$K$"$F$O$^$kA4$F$N%U%!%$%k$rC5$7!"(B + $B;ve$=$l$i$N%U%!%$%k$r%^%C%W$9$k%?%$%W%^%C%W$r:n$j$^$9!#(B + $B$=$N$H$-!"%a%G%#%"%?%$%W$H%3%s%F%s%H%(%s%3!<%G%#%s%0$O!"$=$N%U%!%$%kL>$r(B + $BD>@\;XDj$7$?$H$-$HF1$8$b$N$,3d$jEv$F$i$l$^$9!#(B + $B$=$l$+$i%/%i%$%"%s%H$NMW5a$K0lHV9g$&$b$N$rA*$S$^$9!#(B

    + +

    $B%5!<%P$,%G%#%l%/%H%j$N:w0z$r:n$m$&$H$7$F$$$k>l9g!"(B + MultiViews + $B$O(B DirectoryIndex + $B%G%#%l%/%F%#%V$G;XDj$5$l$?%U%!%$%k$rC5$92aDx$K$b(B + $BE,MQ$5$l$^$9!#@_Dj%U%!%$%k$K(B

    +DirectoryIndex index +

    $B$,=q$+$l$F$$$F!"(Bindex.html $B$H(B + index.html3 $B$,(B + $BN>J}B8:_$7$F$$$k$H!"%5!<%P$O$=$NCf$+$i$I$A$i$+$rE,Ev$KA*$S$^$9!#(B + $B$b$7$=$NN>J}$,B8:_$;$:$K(B index.cgi + $B$,B8:_$7$F$$$k$H!"(B $B%5!<%P$O$=$l$r + +

    $B$b$7%G%#%l%/%H%j$rFI$s$G$$$k:]$K!"(B + $BJ8;z%;%C%H!"%3%s%F%s%H%?%$%W!"8@8l!"%(%s%3!<%G%#%s%0$r(B + $B;XDj$9$k$?$a$N(B mod_mime + $B$GG'<1$G$-$k3HD%;R$r;}$?$J$$%U%!%$%k$,8+$D$+$k$H!"7k2L$O(B + MultiViewsMatch + $B%G%#%l%/%F%#%V$N@_Dj$K0MB8$7$^$9!#$3$N%G%#%l%/%F%#%V$O(B + $B%O%s%I%i!"%U%#%k%?!"B>$N%U%!%$%k3HD%;R%?%$%W$N$I$l$,(B + MultiViews $B%M%4%7%(!<%7%g%s$G;HMQ$G$-$k$+$r7hDj$7$^$9!#(B

    +
    +
    + +
    $B%M%4%7%(!<%7%g%sJ}K!(B + +

    Apache $B$O%j%=!<%9$N(B variant $B$N0lMw$r!"%?%$%W%^%C%W%U%!%$%k$+(B + $B%G%#%l%/%H%jFb$N%U%!%$%kL>$+$i$+$G\:Y$rCN$kI,MW$O$"$j$^$;$s!#(B + $B$7$+$7$J$,$i!"$3$NJ8=q$N;D$j$G$O4X?4$N$"$k?M$N$?$a$K!"(B + $B;HMQ$5$l$F$$$kJ}K!$K$D$$$F@bL@$7$F$$$^$9!#(B

    + +

    $B%M%4%7%(!<%7%g%sJ}K!$OFs$D$"$j$^$9!#(B

    + +
      +
    1. $BDL>o$O(B Apache $B$N%"%k%4%j%:%`$rMQ$$$?(B Server + driven negotiation $B$,;HMQ$5$l$^$9!#(BApache + $B$N%"%k%4%j%:%`$O8e$K>\:Y$K@bL@$5$l$F$$$^$9!#(B + $B$3$N%"%k%4%j%:%`$,;HMQ$5$l$?>l9g!"(BApache + $B$O$h$jNI$$7k2L$K$J$k$h$&$K!"FCDj$N\:Y$K@bL@$5$l$F$$$^$9!#(B
    2. + +
    3. RFC 2295 + $B$GDj5A$5$l$F$$$k5!9=$rMQ$$$F%V%i%&%6$,FC$K;XDj$7$?>l9g!"(B + transparent content negotiation + $B$,;HMQ$5$l$^$9!#$3$N%M%4%7%(!<%7%g%sJ}K!$G$O!"!V:GE,$J!W(B + variant $B$N7hDj$r%V%i%&%6$,40A4$K@)8f$9$k$3$H$,$G$-$^$9!#(B + $B$G$9$+$i!"7k2L$O%V%i%&%6$,;HMQ$7$F$$$k%"%k%4%j%:%`$K0MB8$7$^$9!#(B + Transparent negotiation $B$N=hM}$N2aDx$G!"%V%i%&%6$O(B RFC 2296 + $B$G(B $BDj5A$5$l$F$$$k(B 'remote variant selection algorithm' + $B$r +
    + +
    $B%M%4%7%(!<%7%g%s$N<!85(B + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B + + $B@bL@(B
    $B%a%G%#%"%?%$%W(B$B%V%i%&%6$O(B Accept + $B%X%C%@%U%#!<%k%I$GM%@h798~$r;XDj$7$^$9!#(B + $B%"%$%F%`$=$l$>$l$O!"4XO"$7$?IJ +
    $B8@8l(B$B%V%i%&%6$O(B Accept-Language + $B%X%C%@%U%#!<%k%I$GM%@h798~$r;XDj$7$^$9!#(B + $BMWAG$=$l$>$l$KIJe$N8@8l$H(B + $B4XO"$E$1$k$3$H$,$G$-$^$9!#(B
    $B%(%s%3!<%G%#%s%0(B$B%V%i%&%6$O(B Accept-Encoding + $B%X%C%@%U%#!<%k%I$GM%@h798~$r;XDj$7$^$9!#(B + $BMWAG$=$l$>$l$KIJ +
    $BJ8;z%;%C%H(B$B%V%i%&%6$O(B Accept-Charset + $B%X%C%@%U%#!<%k%I$GM%@h798~$r;XDj$7$^$9!#(B + $BMWAG$=$l$>$l$KIJ +
    +
    + +
    Apache $B%M%4%7%(!<%7%g%s%"%k%4%j%:%`(B + +

    $B%V%i%&%6$KJV$9!V:GE,$J!W(Bvariant $B$r(B ($B$b$7$"$l$P(B) $BA*Br$9$k$h$&$K(B + Apache $B$O + +

      +
    1. $B$^$:$O$8$a$K!"%M%4%7%(!<%7%g%s$N$l$K$D$$$FE,@Z$J(B + Accept* $B%X%C%@%U%#!<%k%I$rD4$Y!"(B + variant $B$=$l$>$l$KIJAccept* $B%X%C%@$G$=$N(B variant + $B$,5vMF$G$-$J$$$3$H$,<($5$l$F$$$l$P!"$=$l$r:o=|$7$^$9!#(B + variant $B$,0l$D$b;D$C$F$$$J$1$l$P!"%9%F%C%W(B 4 $B$K9T$-$^$9!#(B
    2. + +
    3. + $B>C5nK!$G!V:GE,$J!W(B variant $B$rA*$S$^$9!#(B + $B +
    4. variant $B$N%a%G%#%"%?%$%W$NIJAccept + $B%X%C%@$NIJ + +
    5. $B8@8lIJ + +
    6. ($B$b$7$"$l$P(B) Accept-Language $B%X%C%@$N8@8l=g$+!"(B + ($B$b$7$"$l$P(B) + LanguagePriority + $B%G%#%l%/%F%#%V$N8@8l=g$G:GE,$J8@8l$N(B variant $B$rA*$S$^$9!#(B
    7. + +
    8. $B:G9b!V%l%Y%k!W$N%a%G%#%"%Q%i%a!<%?(B + (text/html $B%a%G%#%"%?%$%W$N%P!<%8%g%s$rM?$($k$?$a$K;H$o$l$^$9(B) + $B$r;}$D(B variant $B$rA*$S$^$9!#(B
    9. + +
    10. Accept-Charset $B%X%C%@9T$GM?$($i$l$F$$$k:G9b$NJ8;z%;%C%H(B + $B%a%G%#%"%Q%i%a!<%?$r;}$D(B variant $B$rA*$S$^$9!#(B + $BL@<(E*$K=|30$5$l$F$$$J$$8B$j!"(BISO-8859-1 + $B$,5vMF$5$l$k$h$&$K$J$C$F$$$^$9!#(B + text/* $B%a%G%#%"%?%$%W$G$"$k$1$l$I$b(B + $BFCDj$NJ8;z%;%C%H$KL@<(E*$K4XO"$E$1$i$l$F$$$k$o$1$G$O$J$$(B + variant $B$O(B ISO-8859-1 $B$G$"$k$H2>Dj$5$l$^$9!#(B
    11. + +
    12. ISO-8859-1 $B$G$O$J$$(B$BJ8;z%;%C%H%a%G%#%"%Q%i%a!<%?$H(B + $B4XO"$E$1$i$l$F$$$k(B variant $B$rA*$S$^$9!#(B + $B$=$N$h$&$J(B variant $B$,$J$$>l9g$O!"Be$o$j$KA4$F$N(B + variant $B$rA*$S$^$9!#(B
    13. + +
    14. $B:GE,$J%(%s%3!<%G%#%s%0$N(B variant $B$rA*$S$^$9!#(B + $B$b$7(B user-agent $B$,5vMF$9$k%(%s%3!<%G%#%s%0$,$"$l$P!"(B + $B$=$N(B variant $B$N$_$rA*$S$^$9!#(B + $B$=$&$G$O$J$/!"$b$7%(%s%3!<%I$5$l$?$b$N$H$=$&$G$J$$(B + variant $B$,:.$6$C$FB8:_$7$F$$$?$i%(%s%3!<%I$5$l$F$$$J$$(B + variant $B$N$_$rA*$S$^$9!#(B + variant $B$,A4It%(%s%3!<%I$5$l$F$$$k$+(B + variant $B$,A4It%(%s%3!<%I$5$l$F$$$J$$$H$$$&>l9g$O!"(B + $BA4$F$N(B variant $B$rA*$S$^$9!#(B
    15. + +
    16. $BFbMF$N:G$bC;$$(B variant $B$rA*$S$^$9!#(B
    17. + +
    18. $B;D$C$F$$$k(B variant $B$N:G=i$N$b$N$rA*$S$^$9!#(B + $B%?%$%W%^%C%W%U%!%$%k$N:G=i$K%j%9%H$5$l$F$$$k$+!"(B + variant $B$,%G%#%l%/%H%j$+$i:G=i$KFI$_9~$^$l$k;~$K(B + ASCII$B=g$G%=!<%H$7$F%U%!%$%kL>$,@hF,$K$J$C$?$+!"$N$I$A$i$+$G$9!#(B
    19. +
    + + +
  • $B%"%k%4%j%:%`$r;H$C$F0l$D$N!V:GE,$J!W(Bvariant $B$rA*$S$^$7$?$N$G!"(B + $B$=$l$r1~Ez$H$7$FJV$7$^$9!#%M%4%7%(!<%7%g%s$NVary $B$,@_Dj$5$l$^$9(B + ($B%j%=!<%9$N%-%c%C%7%e$r$9$k;~$K!"(B + $B%V%i%&%6$d%-%c%C%7%e$O$3$N>pJs$r;H$&$3$H$,$G$-$^$9(B)$B!#(B + $B0J>e$G=*$o$j!#(B
  • + +
  • $B$3$3$KMh$?$H$$$&$3$H$O!"(Bvariant $B$,0l$D$bA*Br$5$l$J$+$C$?(B + ($B%V%i%&%6$,5vMF$9$k$b$N$,$J$+$C$?$?$a(B) $B$H$$$&$3$H$G$9!#(B + 406 $B%9%F!<%?%9(B ("No Acceptable representation" $B$r0UL#$9$k(B) + $B$,!"MxMQ2DG=$J(B variant $B$N%j%9%H$N$D$$$?(B HTML + $B%I%-%e%a%s%H$H$H$b$KJV$5$l$^$9!#(B + $BAj0c$NVary $B%X%C%@$b@_Dj$5$l$^$9!#(B
  • + +
    +
    + +
    $BIJ<A$NCM$rJQ$($k(B + +

    $B>e5-$N(B Apache $B%M%4%7%(!<%7%g%s%"%k%4%j%:%`$N873J$J2rpJs$rAw$k(B + $B%V%i%&%68~$1$K$h$j$h$$7k2L$rF@$k$?$a$K9T$o$l$^$9!#(B + $B$+$J$j%]%T%e%i!<$J%V%i%&%6$G!"$b$7$J$$$H4V0c$C$?(B variant + $B$rA*Br$9$k7k2L$K$J$C$F$7$^$&$h$&$J(B Accept + $B%X%C%@>pJs$rAw$k$b$N$b$"$j$^$9!#(B + $B%V%i%&%6$,40A4$G@5$7$$>pJs$rAw$C$F$$$l$P!"(B + $B$3$N?tCMJQ2=$OE,MQ$5$l$^$;$s!#(B

    + +
    $B%a%G%#%"%?%$%W$H%o%$%k%I%+!<%I(B + +

    Accept: $B%j%/%(%9%H%X%C%@$O%a%G%#%"%?%$%W$NM%@h798~$r;XDj$7$^$9!#(B + $B$3$l$O$^$?!"(B"image/*" $B$d(B "*/*" + $B$H$$$C$?!V%o%$%k%I%+!<%I!W%a%G%#%"%?%$%W$r4^$`$3$H$,$G$-$^$9!#(B + $B$3$3$G(B * $B$OG$0U$NJ8;zNs$K%^%C%A$7$^$9!#(B + $B$G$9$+$i!" + +Accept: image/*, */* + +

    $B$r4^$`%j%/%(%9%H$O!"(B"image/" $B$G$O$8$^$k%?%$%WA4$F$,5vMF$G$-$k!"(B + $B$=$7$FB>$N$I$s$J%?%$%W$b5vMF$G$-$k(B + ($B$3$N>l9g$O$8$a$N(B "image/*" $B$O>iD9$K$J$j$^$9(B) + $B$3$H$r<($7$^$9!#(B + $B07$&$3$H$N$G$-$kL@<(E*$J%?%$%W$K2C$($F!"5!3#E*$K(B + $B%o%$%k%I%+!<%I$rAw$k%V%i%&%6$b$"$j$^$9!#Nc$($P(B:

    + + + Accept: text/html, text/plain, image/gif, image/jpeg, */* + +

    $B$3$&$9$k$3$H$NA@$$$O!"L@<(E*$K%j%9%H$7$F$$$k%?%$%W$,M%@h$5$l$k$1$l$I$b!"(B + $B0[$J$kI=8=$,MxMQ2DG=$G$"$l$P$=$l$G$bNI$$!"$H$$$&$3$H$G$9!#(B + $B$7$+$7$J$,$i!">e$N4pK\E*$J%"%k%4%j%:%`$G$O!"(B + */* $B%o%$%k%I%+!<%I$OB>$NA4$F$N%?%$%W$HA4$/F1Ey$J$N$GM%@h$5$l$^$;$s!#(B + $B%V%i%&%6$O(B */* $B$K$b$C$HDc$$IJ + + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 + +

    $BL@<(E*$J%?%$%W$K$OIJl9g$K$N$_!"(B + $BB>$N%?%$%W$,JV$5$l$^$9!#(B

    + +

    $B$b$7(B Accept: $B%X%C%@$,(B q $BCM$rA4$/4^$s$G(B$B$$$J$1$l$P(B$B!"(B + $BK>$_$N5sF0$r$9$k$?$a$K!"(B + Apache $B$O(B "*/*" $B$,$"$l$P(B 0.01 $B$N(B q $BCM$r@_Dj$7$^$9!#(B + $B$^$?!"(B"type/*" $B$N7A$N%o%$%k%I%+!<%I$K$O(B 0.02 $B$N(B q $BCM$r@_Dj$7$^$9(B + ($B$G$9$+$i$3$l$i$O(B "*/*" $B$N%^%C%A$h$j$bM%@h$5$l$^$9(B)$B!#(B + $B$b$7(B Accept: $B%X%C%@Cf$N%a%G%#%"%?%$%W$N$I$l$+$,(B q + $BCM$r4^$s$G$$$l$P!"$3$l$i$NFC$B$5$l$:(B$B!"(B + $B@5$7$$>pJs$rAw$k%V%i%&%6$+$i$N%j%/%(%9%H$O4|BTDL$j$K(B + $BF0:n$9$k$h$&$K$J$j$^$9!#(B

    +
    + +
    $B8@8l%M%4%7%(!<%7%g%s$NNc30=hM}(B + +

    Apache 2.0 $B$G$O?7$?$K!"8@8l%M%4%7%(!<%7%g%s$,E,9g$9$k$b$N$r(B + $B8+$D$1$k$N$K<:GT$7$?;~$K!"M%2m$K%U%)!<%k%P%C%/$G$-$k$h$&$J(B + $B%M%4%7%(!<%7%g%s%"%k%4%j%:%`$,4v$D$+DI2C$5$l$^$7$?!#(B

    + +

    $B%5!<%P$N%Z!<%8$r%/%i%$%"%s%H$,%j%/%(%9%H$7$?$1$l$I$b!"(B + $B%V%i%&%6$NAw$C$F$-$?(B Accept-Language $B$K9gCW$9$k%Z!<%8$,0l$D$b(B + $B8+$D$+$i$J$+$C$?>l9g$K!"%5!<%P$O(B "No Acceptable Variant" + $B$+(B "Multiple Choices" $B%l%9%]%s%9$r%/%i%$%"%s%H$KJV$7$^$9!#(B + $B$3$l$i$N%(%i!<%a%C%;!<%8$rJV$5$J$$$h$&$K!"(B + $B$3$N$h$&$J>l9g$K$O(B Apache $B$,(B Accept-Language $B$rL5;k$7$F!"(B + $B%/%i%$%"%s%H$N%j%/%(%9%H$KL@<(E*$K$O9gCW$7$J$$%I%-%e%a%s%H$r(B + $BDs6!$9$k$h$&$K@_Dj$G$-$^$9!#(B + ForceLanguagePriority + $B%G%#%l%/%F%#%V$O!"$3$l$i$N%(%i!<$N0l$D$+N>J}$r%*!<%P!<%i%$%I$9$k$?$a$K(B + $B;HMQ$G$-$F!"(B + LanguagePriority + $B%G%#%l%/%F%#%V$NFbMF$r;H$C$F%5!<%P$NH=CG$rBe9T$9$k$h$&$K$G$-$^$9!#(B

    + +

    $B%5!<%P$OB>$KE,9g$9$k$b$N$,8+$D$+$i$J$1$l$P!"(B + $B8@8l%5%V%;%C%H$GE,9g$9$k$b$N$r;n$=$&$H$b$7$^$9!#(B + $BNc$($P%/%i%$%"%s%H$,1Q9q1Q8l$G$"$k(B en-GB $B8@8l$G(B + $B%I%-%e%a%s%H$r%j%/%(%9%H$7$?>l9g!"%5!<%P$O(B HTTP/1.1 + $B5,3J$G$O!"C1$K(B en $B$H%^!<%/$5$l$F$$$k%I%-%e%a%s%H$r(B + $B%^%C%A$9$k$b$N$H$9$k$3$H$ODL>o$O5v$5$l$F$$$^$;$s!#(B + ($B1Q9q1Q8l$OM}2r$G$-$k$1$I0lHLE*$J1Q8l$OM}2r$G$-$J$$$H$$$&FI$_en-GB + $B$r4^$s$G(B en $B$r4^$^$J$$$N$O$[$\3N$N8@8l$K$O%^%C%A$;$:!"(B"No Acceptable Variants" + $B%(%i!<$rJV$7$?$j!"(B + LanguagePriority + $B$K%U%)!<%k%P%C%/$7$h$&$H$7$F$$$k$H$-$O!"(B + $B%5%V%;%C%H;XDj$rL5;k$7$F!"(Ben-GB $B$r(B en + $B$K%^%C%A$7$^$9!#(B + Apache $B$O%/%i%$%"%s%H$N5vMF8@8l%j%9%H$K0EL[$K(B + $BHs>o$KDc$$IJl9g$O!"(B + "fr" $B%I%-%e%a%s%H$,JV$5$l$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$3$N$h$&$J=hM}$O!"(BHTTP 1.1 $B5,3J$H$N@09g@-$r0];}$7$F!"(B + $BE,@Z$K@_Dj$5$l$?%/%i%$%"%s%H$H$b$-$A$s$HF0:n$9$k$?$a$K(B + $BI,MW$G$9!#(B

    + +

    $B$h$j9bEY$J%F%/%K%C%/(B (Cookie $B$dFCmod_negotiation + $B$,(B$B4D6-JQ?t(B prefer-language + $B$rG'<1$9$k$h$&$K$J$j$^$7$?!#(B + $B$3$NJQ?t$,B8:_$7$F!"E,@Z$J8@8l%?%0$,BeF~$5$l$F$$$k$N$G$"$l$P!"(B + mod_negotiation $B$O9gCW$9$k(B variant + $B$rA*Br$7$h$&$H$7$^$9!#9gCW$9$k$b$N$,L5$1$l$P!"(B + $BDL>o$N%M%4%7%(!<%7%g%s + + Example + SetEnvIf Cookie "language=(.+)" prefer-language=$1 + +

    +
    + +
    Transparent Content Negotiation +$B$N3HD%(B + +

    Apache $B$O(B transparent content negotiation $B%W%m%H%3%k(B +(RFC 2295) $B$r{encoding ..} +$BMWAG$r(B variant $B%j%9%HCf$K;H$C$F$$$^$9!#(B +$B%j%9%HCf$N%(%s%3!<%I$5$l$?(B variant $B$rG'<1$7!"(B +Accept-Encoding $B%j%/%(%9%H%X%C%@$K=>$C$F5vMF$5$l$k(B +$B%(%s%3!<%I$r$b$C$?(B variant $B$O!"$I$l$G$b8uJd(B variant +$B$H$7$F;HMQ$9$k$h$&$K!"(B +RVSA/1.0 $B%"%k%4%j%:%`(B (RFC 2296) $B$N.?tE@0J2<(B 5 $B7e$^$G4]$a$^$;$s!#(B

    +
    + +
    $B%j%s%/$HL>A0$NJQ49$K4X$9$kCm0UE@(B + +

    $B8@8l%M%4%7%(!<%7%g%s$r;H$C$F$$$k>l9g$O!"(B + $B%U%!%$%k$,0l$D0J>e$N3HD%;R$r;}$F$F!"(B + $B3HD%;R$N=gHV$ODL>o$O9MN8$5$l$J$$(B + ($B>\:Y$O(B mod_mime + $B$r;2>H(B) $B$N$G!"(B + $B4v$D$+$N0[$J$kL>A0$NJQ49$rA*$Y$k$3$H$K$J$j$^$9!#(B

    + +

    $BE57?E*$J%U%!%$%k$G$O!"(BMIME $B%?%$%W3HD%;R(B ($BNc$($P(B + html) $B$r;}$C$F$$$F!"%(%s%3!<%G%#%s%03HD%;R(B + ($BNc$($P(B gz) $B$r;}$C$F$$$k$+$b$7$l$J$/$F!"(B + $B$3$N%U%!%$%k$K0[$J$k8@8l(B variant $B$rMQ0U$7$F$$$l$P!"(B + $B$b$A$m$s8@8l3HD%;R(B ($BNc$($P(B en) + $B$r;}$C$F$$$k$G$7$g$&!#(B

    + +

    $BNc(B:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    $B%U%!%$%kL>$H!"$=$l$KBP$7$F;H$($k%j%s%/$H;H$($J$$%j%s%/$NNc$G$9(B:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%U%!%$%kL>(B$B;H$($k%j%s%/(B$B;H$($J$$%j%s%/(B
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    $B>e$NI=$r8+$F!"3HD%;R$J$7$N%j%s%/(B ($BNc$($P(B foo) + $B$,$$$D$G$b;H$($k$3$H$K5$$,IU$/$G$7$g$&!#(B + $B$3$NMxE@$O!"%I%-%e%a%s%H$H$7$F1~Ez$9$k%U%!%$%k$N(B + $BH$rJQ99$9$k$3$H$J$/(B + $B8e$+$i%U%!%$%k$rJQ99$G$-$k!"(B + $BNc$($P(B html $B$+$i(B shtml + $B$K!"$"$k$$$O(B cgi $B$KJQ99$G$-$kE@$G$9!#(B

    + +

    $B%j%s%/$K(B MIME $B%?%$%W$r;H$$B3$1$?$$(B ($BNc$($P(B + foo.html)$B;~$O!"8@8l3HD%;R$O(B + ($B%(%s%3!<%G%#%s%03HD%;R$b$"$l$P$=$l$b4^$a$F(B) + MIME $B%?%$%W3HD%;R$N1&B&$K$J$1$l$P$J$j$^$;$s(B + ($BNc$($P(B foo.html.en)$B!#(B

    +
    + +
    $B%-%c%C%7%e$K4X$9$kCm0U;v9`(B + +

    $B%-%c%C%7%e$,0l$D$NI=8=$rJ]B8$7$F$$$k$H$-$O!"(B + $B%j%/%(%9%H(B URL $B$H4XO"$E$1$i$l$F$$$^$9!#(B + $B + +

    HTTP/1.0 $B=`5r$N%/%i%$%"%s%H$+$i$N%j%/%(%9%H$KBP$7$F$O!"(B + ($B%V%i%&%6$G$"$m$&$H%-%c%C%7%e$G$"$m$&$H(B) + $B%M%4%7%(!<%7%g%s$rCacheNegotiatedDocs + $B%G%#%l%/%F%#%V$r;HMQ$G$-$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$O!"%5!<%P@_Dj%U%!%$%k$d%P!<%A%c%k%[%9%H$K=q$/$3$H$,$G$-!"(B + $B0z?t$r$H$j$^$;$s!#(B + HTTP/1.1 $B%/%i%$%"%s%H$+$i$N%j%/%(%9%H$K$O8zNO$r;}$A$^$;$s!#(B

    + +

    HTTP/1.1 $B%/%i%$%"%s%H$KBP$7$F$O!"%l%9%]%s%9$N%M%4%7%(!<%7%g%sVary HTTP $B%l%9%]%s%9%X%C%@$rAw$j$^$9!#(B + $B%-%c%C%7%e$O!"$3$l$r;H$C$F8eB3$N%j%/%(%9%H$KBP$7$F%m!<%+%k%3%T!<$G1~Ez$G$-$k$+(B + $B$I$&$+$r7hDj$G$-$^$9!#(B + $B%M%4%7%(!<%7%g%sforce-no-vary $B4D6-JQ?t(B$B$r(B + $B@_Dj$7$^$9!#(B

    + +
    + +
    $BDI2C>pJs(B + +

    $B%3%s%F%s%H%M%4%7%(!<%7%g%s$K4X$9$kDI2C>pJs$O!"(B + Alan J. Flavell $B$5$s$N(BLanguage + Negotiation Notes $B$r$4Mw2<$5$$!#$G$9$,!"(B + Apache 2.0 $B$G$NJQ99E@$r4^$`$?$a$K$O99?7$5$l$F$$$J$$$+$b$7$l$J$$(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    + +
    diff --git a/trunk/docs/manual/content-negotiation.xml.ko b/trunk/docs/manual/content-negotiation.xml.ko new file mode 100644 index 0000000000..6226c77fad --- /dev/null +++ b/trunk/docs/manual/content-negotiation.xml.ko @@ -0,0 +1,603 @@ + + + + + + + + + +³»¿ëÇù»ó (Content Negotiation) + + + +

    ¾ÆÆÄÄ¡´Â HTTP/1.1 ±Ô¾à¿¡ ±â¼úµÈ ³»¿ëÇù»ó(content + negotiation)À» Áö¿øÇÑ´Ù. ³»¿ëÇù»óÀº media type, ¾ð¾î, ¹®ÀÚÁýÇÕ, + ÀÎÄÚµù µî¿¡ ´ëÇØ ºê¶ó¿ìÀú°¡ Á¦°øÇÑ ¼±È£µµ¿¡ µû¶ó ÀÚ¿øÀÇ + °¡Àå ÀûÇÕÇÑ Ç¥ÇöÀ» ¼±ÅÃÇÑ´Ù. ¶Ç ºÒ¿ÏÀüÇÑ Çù»ó Á¤º¸¸¦ º¸³»´Â + ºê¶ó¿ìÀúÀÇ ¿äûÀ» Áö´ÉÀûÀ¸·Î ó¸®ÇÏ´Â ±â´Éµµ ÀÖ´Ù.

    + +

    ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵǴ mod_negotiation + ¸ðµâÀÌ ³»¿ëÇù»ó ±â´ÉÀ» Á¦°øÇÑ´Ù.

    +
    + +
    ³»¿ëÇù»ó¿¡ ´ëÇØ + +

    ÀÚ¿øÀº ¿©·¯ ´Ù¸¥ Ç¥ÇöÀ» °¡Áú ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´Ù¸¥ + ¾ð¾î³ª ´Ù¸¥ media type ȤÀº µÑ ¸ðµÎ°¡ ´Ù¸¥ Ç¥ÇöµéÀÌ ÀÖÀ» + ¼ö ÀÖ´Ù. °¡Àå Àû´çÇÑ Ç¥ÇöÀ» ¼±ÅÃÇÏ´Â ÇÑ°¡Áö ¹æ¹ýÀº »ç¿ëÀÚ¿¡°Ô + ¸ñ·Ï ÆäÀÌÁö¸¦ º¸¿©ÁÖ°í ¼±ÅÃÇÏ°Ô ÇÏ´Â °ÍÀÌ´Ù. ±×·¯³ª ¼­¹ö°¡ + ÀÚµ¿À¸·Î ¼±ÅÃÇÏ´Â °Íµµ °¡´ÉÇÏ´Ù. ÀÌ´Â ºê¶ó¿ìÀú°¡ ¿äûÀÇ + ÀϺηΠ±×µéÀÌ ¼±È£Çϴ ǥÇö¿¡ ´ëÇÑ Á¤º¸¸¦ º¸³»±â¶§¹®¿¡ + °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î, ºê¶ó¿ìÀú´Â °¡´ÉÇÑÇÑ ºÒ¾î·Î, ±×·¯³ª + ¾ø´Ù¸é ¿µ¾î·Î Á¤º¸¸¦ º¸°í½Í´Ù°í ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù. ºê¶ó¿ìÀú´Â + ¿äûÀÇ Çì´õ·Î ±×µéÀÇ ±âÈ£¸¦ ³ªÅ¸³½´Ù. ¿ÀÁ÷ ºÒ¾î·ÎµÈ Ç¥Çö¸¸À» + ¿äûÇÑ´Ù¸é ºê¶ó¿ìÀú´Â ´ÙÀ½°ú °°ÀÌ º¸³½´Ù.

    + +Accept-Language: fr + +

    ÀÌ·± ±âÈ£´Â Ç¥ÇöÀÌ ¾ð¾îº°·Î ´Ù¸¦ °æ¿ì¿¡¸¸ °í·ÁµÈ´Ù.

    + +

    ´ÙÀ½Àº ´õ º¹ÀâÇÑ ¿äûÀÇ ¿¹·Î ºê¶ó¿ìÀú°¡ ºÒ¾î¿Í ¿µ¾î¸¦ + ¹ÞÀ» ¼ö ÀÖÁö¸¸, ºÒ¾î¸¦ ´õ ¼±È£ÇÏ°í, ¿©·¯ media typeÀ» ¹ÞÀ» + ¼ö ÀÖÁö¸¸, ÀÏ¹Ý ÅؽºÆ® º¸´Ù´Â HTML, ´Ù¸¥ media type º¸´Ù´Â + GIF¿Í JPEGÀ» ¼±È£ÇÑ´Ù°í ¾Ë·ÁÁØ´Ù.

    + + + Accept-Language: fr; q=1.0, en; q=0.5
    + Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1 +
    + +

    ¾ÆÆÄÄ¡´Â HTTP/1.1 ±Ô¾à¿¡ Á¤ÀÇµÈ '¼­¹ö ÁÖµµ(server driven)' + ³»¿ëÇù»óÀ» Áö¿øÇÑ´Ù. ¾ÆÆÄÄ¡´Â Accept, + Accept-Language, Accept-Charset, + Accept-Encoding ¿äû Çì´õ¸¦ ¸ðµÎ Áö¿øÇÑ´Ù. + ¶Ç, ¾ÆÆÄÄ¡´Â RFC 2295¿Í RFC 2296¿¡ Á¤ÀÇµÈ ½ÇÇèÀûÀÎ ³»¿ëÇù»óÀÎ + 'ÀÚ¿¬½º·¯¿î(transparent)' ¿äû Çì´õµµ Áö¿øÇÑ´Ù. ±×·¯³ª ÀÌ + RFC¿¡ Á¤ÀÇµÈ '±â´É Çù»ó(feature negotiation)'Àº Áö¿øÇÏÁö + ¾Ê´Â´Ù.

    + +

    ÀÚ¿ø(resource)Àº (RFC 2396) URI·Î ±¸º°ÇÏ´Â + °³³äÀûÀÎ Á¸Àç´Ù. ¾ÆÆÄÄ¡¿Í °°Àº À¥¼­¹ö´Â ÀÚ¿øÀÇ + Ç¥Çö(representations)À» Á¦°øÇÑ´Ù. Ç¥ÇöÀº + ÁöÁ¤µÈ media type, ¹®ÀÚÁýÇÕ, ÀÎÄÚµù µîÀ» °¡Áø ¹ÙÀÌÆ®µé·Î + µÇÀÖ´Ù. ÀÚ¿øÀº ¿©·¯ Ç¥Çö°ú (¶§·Î´Â ¾øÀ» ¼öµµ ÀÖ´Ù) ¿¬°üµÈ´Ù. + ÀÚ¿ø¿¡ ¿©·¯ Ç¥ÇöÀÌ ÀÖ´Ù¸é ÀÚ¿øÀ» + Çù»ó°¡´ÉÇÏ´Ù°í(negotiable) ºÎ¸£¸ç, À̶§ + °¢ Ç¥ÇöÀ» º¯Çü(variant)À̶ó°í ÇÑ´Ù. + Çù»ó°¡´ÉÇÑ ÀÚ¿øÀÇ º¯Çü Á¾·ù¸¦ Çù»óÀÇ + ¹üÀ§(dimension)¶ó°í ÇÑ´Ù.

    +
    + +
    ¾ÆÆÄÄ¡ÀÇ Çù»ó + +

    ÀÚ¿øÀ» Çù»óÇϱâÀ§ÇØ ¼­¹ö´Â °¢ º¯Çü¿¡ ´ëÇÑ Á¤º¸°¡ ÇÊ¿äÇÏ´Ù. + ´ÙÀ½ µÎ°¡Áö ¹æ¹ýÁß Çϳª·Î Á¤º¸¸¦ ¾ò´Â´Ù:

    + +
      +
    • º¯ÇüÀ» ´ãÀº ÆÄÀϵéÀ» Á÷Á¢ ¿­°ÅÇÑ type mapÀ» (¿¹¸¦ + µé¾î, *.var ÆÄÀÏ) »ç¿ëÇϰųª,
    • + +
    • Á÷Á¢ ÁöÁ¤ÇÏÁö¾Ê¾Æµµ ¼­¹ö°¡ ÆÄÀÏ¸í¿¡¼­ ±ÔÄ¢À» ã¾Æ¼­ + °á°ú¸¦ ¼±ÅÃÇÏ´Â 'MultiViews'¸¦ »ç¿ëÇÑ´Ù.
    • +
    + +
    type-map ÆÄÀÏ »ç¿ëÇϱâ + +

    type mapÀº type-mapÀ̶õ Çڵ鷯¿Í ¿¬°áµÈ + (ȤÀº ÀÌÀü ¾ÆÆÄÄ¡ ¼³Á¤°ú ȣȯÀ» À§ÇØ MIME typeÀÌ + application/x-type-mapÀÎ) ¹®¼­´Ù. ÀÌ ±â´ÉÀ» + »ç¿ëÇÏ·Á¸é ¼³Á¤¿¡¼­ type-map Çڵ鷯¿¡ ´ëÇÑ + ÆÄÀÏ È®ÀåÀÚ¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù. ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ + ¼³Á¤ÇÏ´Â °ÍÀÌ ÁÁ´Ù.

    + +AddHandler type-map .var + +

    Type map ÆÄÀÏÀº ÇØ´çÇÏ´Â ÀÚ¿ø°ú À̸§ÀÌ °°¾Æ¾ß ÇÏ°í, + °¢ º¯Çü¿¡ ´ëÇÑ Ç׸ñÀÌ ÀÖ¾î¾ß ÇÑ´Ù. Ç׸ñÀº ¿©·¯ HTTPÇü½Ä + Çì´õ ÁÙ·Î ±¸¼ºµÈ´Ù. º¯Çü¿¡ ´ëÇÑ °¢°¢ÀÇ Ç׸ñµéÀº ºóÁÙ·Î + ±¸ºÐÇÑ´Ù. Ç׸ñ¾È¿¡¼­ ºóÁÙÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. (ÀÌ·¸°Ô ÇÒ + ÇÊ¿ä°¡ ¾ø°í, À־ ¹«½ÃÇÏÁö¸¸) ¿©·¯ Ç׸ñÀÌ °øÅëÀ¸·Î °¡Áö°í + ÀÖ´Â ³»¿ëÀ¸·Î map ÆÄÀÏÀ» ½ÃÀÛÇÏ´Â °ÍÀÌ º¸ÅëÀÌ´Ù. ´ÙÀ½Àº + map ÆÄÀÏ ¿¹´Ù. ÀÌ ÆÄÀÏÀÇ À̸§Àº foo.var·Î, + foo¶ó´Â ÀÚ¿øÀ» ¼³¸íÇÑ´Ù.

    + + + URI: foo
    +
    + URI: foo.en.html
    + Content-type: text/html
    + Content-language: en
    +
    + URI: foo.fr.de.html
    + Content-type: text/html;charset=iso-8859-2
    + Content-language: fr, de
    +
    +

    typemap ÆÄÀÏÀÌ ÆÄÀϸí È®ÀåÀÚ º¸´Ù, ½ÉÁö¾î Multiviews¸¦ + »ç¿ëÇÏ¿©µµ, ¿ì¼±±ÇÀ» °¡ÁüÀ» ÁÖÀÇÇ϶ó. º¯ÇüÀÌ ¼­·Î ´Ù¸¥ Ç°ÁúÀ» + °¡Áø´Ù¸é, ´ÙÀ½°ú °°ÀÌ (JPEG, GIF, ASCII-art¿¡ ÇØ´çÇÏ´Â) + media type¿¡ "qs" ÆĶó¹ÌÅÍ·Î Ç°Áú(source quality)À» Ç¥½ÃÇÒ + ¼ö ÀÖ´Ù:

    + + + URI: foo
    +
    + URI: foo.jpeg
    + Content-type: image/jpeg; qs=0.8
    +
    + URI: foo.gif
    + Content-type: image/gif; qs=0.5
    +
    + URI: foo.txt
    + Content-type: text/plain; qs=0.01
    +
    + +

    qs °ªÀº 0.000¿¡¼­ 1.000 »çÀÌ´Ù. qs °ªÀÌ 0.000ÀÎ º¯ÇüÀº + Àý´ë ¼±ÅõÇÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó. 'qs' °ªÀÌ ¾ø´Â º¯ÇüÀº 1.0À¸·Î + Ãë±ÞµÈ´Ù. qs °ªÀº Ŭ¶óÀ̾ðÆ®ÀÇ ´É·Â°ú´Â °ü°è¾øÀÌ ´Ù¸¥ º¯Çüµé°ú + ºñ±³ÇÏ¿© ±× º¯ÇüÀÇ »ó´ëÀûÀÎ 'Ç°Áú'À» ³ªÅ¸³½´Ù. ¿¹¸¦ µé¾î, + »çÁøÀ» ³ªÅ¸³»·Á´Â °æ¿ì JPEG ÆÄÀÏÀÌ ASCII ÆÄÀϺ¸´Ù´Â Ç×»ó + ³ôÀº Ç°ÁúÀ» °¡Áø´Ù. ±×·¯³ª ÀÚ¿øÀÌ ¿ø·¡ ASCII art¿´´Ù¸é + ASCII Ç¥ÇöÀÌ JPEG Ç¥Çöº¸´Ù ´õ ³ôÀº Ç°ÁúÀ» °¡Áú ¼ö ÀÖ´Ù. + ±×·¯¹Ç·Î ¾î¶² º¯ÇüÀÇ qs °ªÀº Ç¥ÇöÇÏ·Á´Â ÀÚ¿øÀÇ ¼ºÁú¿¡ + µû¶ó ´Ù¸£´Ù.

    + +

    Áö¿øÇÏ´Â ¸ðµç Çì´õ ¸ñ·ÏÀº mod_negotation + typemap ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    Multiviews + +

    MultiViews´Â µð·ºÅ丮º° ¿É¼ÇÀ̹ǷÎ, + httpd.confÀÇ + Directory, + Location, + Files + ¼½¼Ç ȤÀº (AllowOverride°¡ + ÀûÀýÈ÷ ¼³Á¤µÇ¾ú´Ù¸é) .htaccess ÆÄÀÏÀÇ + Options Áö½Ã¾î¿¡ ¼³Á¤ÇÒ + ¼ö ÀÖ´Ù. Options AllÀº MultiViews¸¦ + Æ÷ÇÔÇÏÁö¾ÊÀ½À» ÁÖÀÇÇ϶ó. µû·Î Á÷Á¢ ½áÁà¾ß ÇÑ´Ù.

    + +

    MultiViews¸¦ »ç¿ëÇÏ¸é ´ÙÀ½°ú °°Àº ÀÏÀÌ ÀϾ´Ù: + ¼­¹ö°¡ /some/dir/foo¿¡ ´ëÇÑ ¿äûÀ» ¹Þ°í + /some/dir/foo¿¡ MultiViews°¡ µ¿ÀÛÇϸç + /some/dir/foo°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì, + ¼­¹ö´Â µð·ºÅ丮¿¡¼­ À̸§ÀÌ foo.*ÀÎ ÆÄÀϵéÀ» ¸ðµç Æ÷ÇÔÇÏ´Â + °¡»óÀÇ type mapÀ» ¸¸µç´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¿äûÇÑ media type°ú + content-encodingÀ» °¡Áö°í ÀÌÁß¿¡ °¡Àå ÀûÇÕÇÑ °ÍÀ» ¼±ÅÃÇÑ´Ù.

    + +

    MultiViews´Â ¼­¹ö°¡ µð·ºÅ丮¸¦ ÂüÁ¶ÇÒ¶§ + ÆÄÀÏÀ» ã´Â DirectoryIndex Áö½Ã¾î¿¡µµ + Àû¿ëµÈ´Ù. ¼³Á¤ÆÄÀÏÀÌ ´ÙÀ½°ú °°´Ù¸é,

    +DirectoryIndex index +

    index.html°ú index.html3ÀÌ + ¸ðµÎ ÀÖ´Ù¸é ¼­¹ö´Â ÀÌµÑ Áß¿¡ Çϳª¸¦ °áÁ¤ÇÑ´Ù. µÑ ¸ðµÎ ¾ø°í + index.cgi°¡ ÀÖ´Ù¸é, ¼­¹ö´Â ±×°ÍÀ» ½ÇÇàÇÑ´Ù.

    + +

    µð·ºÅ丮¸¦ ÀÐÀ»¶§ ÆÄÀÏÁß Çϳª°¡ Charset, Content-Type, + Language, Encoding¸¦ ÆÇ´ÜÇÏ´Â mod_mimeÀÌ ¸ð¸£´Â + È®ÀåÀÚ¸¦ °¡Áø´Ù¸é, °á°ú´Â MultiViewsMatch Áö½Ã¾î ¼³Á¤¿¡ + ´Þ·Ç´Ù. ÀÌ Áö½Ã¾î´Â Çڵ鷯, ÇÊÅÍ, ´Ù¸¥ È®ÀåÇüµéÀÌ MultiViews + Çù»ó¿¡ Âü¿©ÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    +
    +
    + +
    Çù»ó¹æ¹ý + +

    ¾ÆÆÄÄ¡°¡ type-map ÆÄÀÏÀ̳ª µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀϸíµé·Î + ÁÖ¾îÁø ÀÚ¿ø¿¡ ´ëÇÑ º¯Çü ¸ñ·ÏÀ» ¾ò°ÔµÇ¸é 'ÃÖÀûÀÇ' º¯ÇüÀ» + °áÁ¤ÇϱâÀ§ÇØ µÎ ¹æ¹ýÁß Çϳª¸¦ »ç¿ëÇÑ´Ù. ¾ÆÆÄÄ¡ ³»¿ëÇù»ó + ±â´ÉÀ» »ç¿ëÇϱâÀ§ÇØ Á¤È®È÷ Çù»óÀÌ ¾î¶»°Ô ÀϾ´ÂÁö ÀÚ¼¼È÷ + ¾Ë ÇÊ¿ä´Â ¾ø´Ù. ±×·¯³ª ±Ã±ÝÇÑ »ç¶÷À» À§ÇØ ÀÌ ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    µÎ°¡Áö Çù»ó¹æ¹ýÀÌ ÀÖ´Ù:

    + +
      +
    1. ¾ÆÆÄÄ¡ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© ¼­¹ö°¡ ÁÖµµÇÏ´Â + Çù»óÀº ÀϹÝÀûÀÎ °æ¿ì¿¡ »ç¿ëÇÑ´Ù. ¾ÆÆÄÄ¡ ¾Ë°í¸®ÁòÀº + ¾Æ·¡¼­ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù. ÀÌ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â + ´õ ³ªÀº °á°ú¸¦ ¾ò±âÀ§ÇØ Á¾Á¾ ƯÁ¤ ¹üÀ§ÀÇ + Ç°Áú°è¼ö(quality factor)¸¦ 'Á¶ÀÛÇÑ´Ù'. ¾ÆÆÄÄ¡°¡ Ç°Áú°è¼ö¸¦ + Á¶ÀÛÇÏ´Â ¹æ¹ýÀº ¾Æ·¡¼­ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.
    2. + +
    3. ÀÚ¿¬½º·¯¿î(Transparent) ³»¿ëÇù»óÀº + ºê¶ó¿ìÀú°¡ RFC 2295¿¡ Á¤ÀÇµÈ ¹æ¹ýÀ¸·Î ¿äûÇÒ °æ¿ì¿¡¸¸ + »ç¿ëÇÑ´Ù. ÀÌ Çù»ó¹æ¹ýÀº 'ÃÖÀûÀÇ' º¯ÇüÀ» °áÁ¤ÇÒ ±ÇÇÑÀ» + ºê¶ó¿ìÀú¿¡°Ô ºÎ¿©ÇÑ´Ù. ±×·¡¼­ °á°ú´Â ºê¶ó¿ìÀúÀÇ ¾Ë°í¸®Áò¿¡ + ´Þ·È´Ù. ÀÚ¿¬½º·¯¿î Çù»ó°úÁ¤Áß¿¡ ºê¶ó¿ìÀú´Â ¾ÆÆÄÄ¡¿¡°Ô + RFC 2296¿¡ Á¤ÀÇµÈ '¿ø°Ý º¯Çü¼±Åà ¾Ë°í¸®Áò(remote variant + selection algorithm)'À» ¿äûÇÒ ¼ö ÀÖ´Ù.
    4. +
    + +
    Çù»óÀÇ ¹üÀ§ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¹üÀ§¼³¸í
    Media Typeºê¶ó¿ìÀú´Â Accept Çì´õ·Î ¼±È£¸¦ ³ªÅ¸³½´Ù. + °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀÇ ¼³¸íµµ Ç°Áú°è¼ö¸¦ + ("qs" ÆĶó¹ÌÅÍ) °¡Áú ¼ö ÀÖ´Ù.
    Languageºê¶ó¿ìÀú´Â Accept-Language Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀº + ¿©·¯ ¾ð¾î¸¦ °¡Áú (ȤÀº ¾Æ¹« ¾ð¾îµµ ¾øÀ») ¼ö ÀÖ´Ù.
    Encodingºê¶ó¿ìÀú´Â Accept-Encoding Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù.
    Charsetºê¶ó¿ìÀú´Â Accept-Charset Çì´õ·Î ¼±È£¸¦ + ³ªÅ¸³½´Ù. °¢ Ç׸ñÀº Ç°Áú°è¼ö¸¦ °¡Áú ¼ö ÀÖ´Ù. º¯ÇüÀº + media typeÀÇ ÆĶó¹ÌÅÍ·Î ¹®ÀÚÁýÇÕÀ» ³ªÅ¸³¾ ¼ö ÀÖ´Ù.
    +
    + +
    ¾ÆÆÄÄ¡ Çù»ó ¾Ë°í¸®Áò + +

    ¾ÆÆÄÄ¡´Â ºê¶ó¿ìÀú¿¡°Ô º¸³¾ 'ÃÖÀûÀÇ' º¯ÇüÀ» (ÀÖ´Ù¸é) + ¼±ÅÃÇϱâÀ§ÇØ ¾Æ·¡ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÑ´Ù. ÀÌ ¾Ë°í¸®ÁòÀº º¯°æÇÒ + ¼ö ¾ø´Ù. ´ÙÀ½¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù:

    + +
      +
    1. ¸ÕÀú, Çù»óÀÇ °¢ ¹üÀ§¿¡ ´ëÇØ ÇØ´çÇÏ´Â Accept* + Çì´õ¸¦ °Ë»çÇÏ°í, °¢ º¯Çü¿¡ Ç°Áú°ªÀ» ¸Å±ä´Ù. ¾î¶² ¹üÀ§ÀÇ + Accept* Çì´õ°¡ ¹Þ¾ÆµéÀÌÁö ¾Ê´Â º¯ÇüÀº Èĺ¸¿¡¼­ + Á¦¿ÜÇÑ´Ù. ¾î¶² º¯Çüµµ ³²Áö¾ÊÀ¸¸é 4 ´Ü°è·Î °£´Ù.
    2. + +
    3. + Èĺ¸¿¡¼­ Çϳª¾¿ Á¦¿ÜÇÏ¿© 'ÃÖÀûÀÇ' º¯ÇüÀ» ã´Â´Ù. ´ÙÀ½ + °¢ °Ë»ç´Â ¼ø¼­´ë·Î ÀϾ´Ù. °¢ °Ë»ç¿¡¼­ ¼±ÅõÇÁö¾ÊÀº + º¯ÇüÀº Á¦¿ÜµÈ´Ù. °¢ °Ë»çÈÄ ÇÑ º¯Çü¸¸ ³²À¸¸é À̸¦ ÃÖÀûÀÇ + º¯ÇüÀ¸·Î ¼±ÅÃÇÏ°í 3 ´Ü°è·Î °£´Ù. ¿©·¯ º¯ÇüÀÌ ³²À¸¸é + ´ÙÀ½ °Ë»ç¸¦ ÁøÇàÇÑ´Ù. + +
        +
      1. Accept Çì´õÀÇ Ç°Áú°è¼ö¿Í º¯ÇüÀÇ + media type¿¡ ´ëÇÑ Ç°Áú°ªÀ» °öÇÏ¿© °¡Àå ³ôÀº °ªÀ» + °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      2. + +
      3. °¡Àå ³ôÀº ¾ð¾î(language) Ç°Áú°è¼ö¸¦ °¡Áø º¯ÇüÀ» + ¼±ÅÃÇÑ´Ù.
      4. + +
      5. Accept-Language Çì´õ¿¡ (ÀÖ´Ù¸é) + ³ª¿Â ¾ð¾îÀÇ ¼ø¼­ ȤÀº LanguagePriority + Áö½Ã¾î¿¡ (ÀÖ´Ù¸é) ³ª¿Â ¾ð¾îÀÇ ¼ø¼­¸¦ °¡Áö°í °¡Àå + ÀûÇÕÇÑ ¾ð¾î¸¦ °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      6. + +
      7. °¡Àå ³ôÀº (text/html media typeÀÇ ¹öÀüÀ» ³ªÅ¸³»´Â) + 'level' media ÆĶó¹ÌÅ͸¦ °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      8. + +
      9. Accept-Charset Çì´õ¸¦ °¡Áö°í °¡Àå + ÀûÇÕÇÑ charset media ÆĶó¹ÌÅ͸¦ °¡Áø º¯ÇüÀ» ã´Â´Ù. + Çì´õ°¡ ¾ø´Ù¸é ISO-8859-1 ¹®ÀÚÁýÇÕÀ» °¡Àå ¼±È£ÇÑ´Ù. + text/* media typeÀ» °¡ÁöÁö¸¸ ¸í½ÃÀûÀ¸·Î + ƯÁ¤ ¹®ÀÚÁýÇÕ°ú ¿¬°áµÇÁö¾ÊÀº º¯ÇüÀº ISO-8859-1·Î + °¡Á¤ÇÑ´Ù.
      10. + +
      11. ISO-8859-1ÀÌ ¾Æ´Ñ charset media ÆĶó¹ÌÅ͸¦ + °¡Áø º¯ÇüµéÀ» ¼±ÅÃÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é, ´ë½Å ¸ðµç + º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      12. + +
      13. °¡Àå ÀûÇÕÇÑ ÀÎÄÚµùÀ» °¡Áø º¯ÇüÀ» ¼±ÅÃÇÑ´Ù. + user-agent¿¡ ÀûÇÕÇÑ ÀÎÄÚµùÀ» °¡Áø º¯ÇüÀÌ ÀÖ´Ù¸é ±× + º¯Çü¸¸À» ¼±ÅÃÇÑ´Ù. ±×·¸Áö¾Ê°í ÀÎÄÚµùµÈ º¯Çü°ú ÀÎÄÚµù¾ÈµÈ + º¯ÇüÀÌ °°ÀÌ ÀÖ´Ù¸é ÀÎÄÚµù¾ÈµÊ º¯Çü¸¸À» ¼±ÅÃÇÑ´Ù. º¯ÇüÀÌ + ¸ðµÎ ÀÎÄÚµùµÇ¾ú°Å³ª ¸ðµÎ ÀÎÄÚµù¾ÈµÈ °æ¿ì ¸ðµç º¯ÇüÀ» + ¼±ÅÃÇÑ´Ù.
      14. + +
      15. content length°¡ °¡Àå ÀûÀº º¯ÇüÀ» ¼±ÅÃÇÑ´Ù.
      16. + +
      17. ³²Àº °ÍÁß Ã¹¹øÀç º¯ÇüÀ» ¼±ÅÃÇÑ´Ù. ÀÌ´Â type-map + ÆÄÀÏÀÇ ¾Õ¿¡ ³ª¿Ô°Å³ª, µð·ºÅ丮¿¡¼­ º¯ÇüÀ» ÀÐÀº °æ¿ì + ÆÄÀϸíÀ» ASCII ÄÚµå ¼ø¼­·Î ÇÏ¿© ¾Õ¿¡ ³ª¿À´Â °ÍÀÌ´Ù.
      18. +
      +
    4. + +
    5. ÀÌÁ¦ ¾Ë°í¸®ÁòÀÌ 'ÃÖÀûÀÇ' º¯ÇüÀ» ¼±ÅÃÇß´Ù. ÀÌ°ÍÀ» ÀÀ´äÀ¸·Î + º¸³½´Ù. HTTP ÀÀ´ä Çì´õ Vary´Â Çù»óÀÇ ¹üÀ§¸¦ + ³ªÅ¸³»°Ô µÈ´Ù. (ºê¶ó¿ìÀú¿Í ij½¬´Â ÀÚ¿øÀ» ij½¬ÇÒ¶§ ÀÌ Á¤º¸¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.) ³¡.
    6. + +
    7. ÀÌ ´Ü°è¿¡ µµ´ÞÇß´Ù¸é (¸ðµÎ ºê¶ó¿ìÀú°¡ ¹ÞÁö¸øÇϱ⠶§¹®¿¡) + ¾î¶² º¯Çüµµ ¼±ÅÃÀÌ ¾ÈµÈ °æ¿ì´Ù. ("No acceptable + representation"¸¦ ¶æÇÏ´Â) »óÅ 406°ú ³»¿ëÀ¸·Î »ç¿ë°¡´ÉÇÑ + º¯ÇüÀÇ ¸ñ·ÏÀ» ´ãÀº HTML ¹®¼­¸¦ ÀÀ´äÀ» º¸³½´Ù. ¶Ç, HTML + Vary Çì´õ´Â º¯ÇüÀÇ ¹üÀ§¸¦ ³ªÅ¸³½´Ù.
    8. +
    +
    +
    + +
    Ç°Áú°è¼ö Á¶ÀÛÇϱâ + +

    ¾ÆÆÄÄ¡´Â Á¾Á¾ À§ÀÇ ¾ÆÆÄÄ¡ Çù»ó ¾Ë°í¸®ÁòÀ» ¾ö°ÝÈ÷ ÁöÅ°Áö¾Ê°í + Ç°Áú°è¼ö¸¦ º¯°æÇÑ´Ù. ÀÌÀ¯´Â ¿ÏÀüÇÏ°í Á¤È®ÇÑ Á¤º¸¸¦ º¸³»Áö¾Ê´Â + ºê¶ó¿ìÀú¿¡°Ô (¾Ë°í¸®ÁòÀÇ) ´õ ³ªÀº °á°ú¸¦ º¸³»±â À§Çؼ­´Ù. + ³Î¸® ¾²ÀÌ´Â ºê¶ó¿ìÀúÁß ÀϺδ ÀÚÁÖ À߸øµÈ º¯ÇüÀ» ¼±ÅÃÇϵµ·Ï + Accept Çì´õ¸¦ º¸³½´Ù. ºê¶ó¿ìÀú°¡ ¿ÏÀüÇÏ°í ¿Ã¹Ù¸¥ + Á¤º¸¸¦ º¸³½´Ù¸é, Á¶ÀÛÀ» ÇÏÁö¾Ê´Â´Ù.

    + +
    Media Type°ú ¿ÍÀϵåÄ«µå + +

    Accept: ¿äû Çì´õ´Â media type¿¡ ´ëÇÑ ¼±È£¸¦ + ³ªÅ¸³½´Ù. ¶Ç, *´Â ¾î¶² ¹®ÀÚ¿­ÀÌ¶óµµ °¡´ÉÇϱ⶧¹®¿¡ "image/*"³ª + "*/*" °°ÀÌ '¿ÍÀϵåÄ«µå' media typeÀ» »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. ±×·¡¼­ + ´ÙÀ½°ú °°Àº ¿äûÀº:

    + +Accept: image/*, */* + +

    "image/"·Î ½ÃÀÛÇÏ´Â ¾î¶² type°ú ´Ù¸¥ ¾î¶² typeµµ °¡´ÉÇÔÀ» + ÀǹÌÇÑ´Ù. ¾î¶² ºê¶ó¿ìÀú´Â + ÀÚ½ÅÀÌ ½ÇÁ¦·Î ´Ù·ê ¼ö ÀÖ´Â type¿¡ Ãß°¡·Î ¿ÍÀϵåÄ«µå¸¦ º¸³½´Ù. + ¿¹¸¦ µé¸é:

    + + + Accept: text/html, text/plain, image/gif, image/jpeg, */* + +

    ÀÌÀ¯´Â Á÷Á¢ ¿­°ÅÇÑ typeÀ» ¼±È£ÇÏÁö¸¸ ´Ù¸¥ Ç¥ÇöÀÌ ÀÖ´Ù¸é + ±×°Íµµ ±¦ÂúÀ½À» ³ªÅ¸³»±â À§Çؼ­´Ù. ºê¶ó¿ìÀú°¡ ½ÇÁ¦·Î ¿øÇÑ + °ÍÀº ´ÙÀ½°ú °°ÀÌ ¸í½ÃÀûÀ¸·Î Ç°Áú°ªÀ» »ç¿ëÇÑ °ÍÀÌ´Ù.

    + + Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01 + +

    Á÷Á¢ ¿­°ÅÇÑ typeÀº Ç°Áú°è¼ö°¡ ¾ø¾î¼­ ±âº»°ªÀÎ (°¡Àå ³ôÀº) + 1.0À» °¡Áø´Ù. ¿ÍÀϵåÄ«µå */*´Â ³·Àº ¼±È£µµ 0.01À» °¡Áö¹Ç·Î + Á÷Á¢ ¿­°ÅÇÑ type¿¡ ¸Â´Â º¯ÇüÀÌ ¾ø´Â °æ¿ì¿¡¸¸ ´Ù¸¥ typeµéÀÌ + »ç¿ëµÈ´Ù.

    + +

    Accept: Çì´õ¿¡ q °è¼ö°¡ ÀüÇô ¾ø°í + "*/*"°¡ ÀÖ´Ù¸é, ¾ÆÆÄÄ¡´Â ¹Ù¶÷Á÷ÇÑ ÇൿÀ» À§ÇØ q °ªÀ¸·Î 0.01À» + ÁöÁ¤ÇÑ´Ù. ¶Ç, "type/*" ÇüÅÂÀÇ ¿ÍÀϵåÄ«µå¿¡´Â ("*/*"º¸´Ù´Â + ´õ ¼±È£Çϵµ·Ï) 0.02¸¦ ÁöÁ¤ÇÑ´Ù. Accept: Çì´õ¿¡¼­ + q °è¼ö¸¦ °¡Áö´Â media typeÀÌ ÀÖ´Ù¸é ÀÌ·± Ưº°ÇÑ °ªÀ» Ãß°¡ÇÏÁö + ¾Ê´Â´Ù. ±×·¡¼­ ¸í½ÃÀûÀÎ Á¤º¸¸¦ º¸³»´Â ºê¶ó¿ìÀúÀÇ + ¿äûÀº ¿äûÇѵ¥·Î ó¸®ÇÑ´Ù.

    +
    + +
    ¾ð¾î(language) Çù»óÀÇ ¿¹¿Ü + +

    ¾ÆÆÄÄ¡ 2.0Àº ¾ð¾î Çù»óÀÌ ½ÇÆÐÇÑ °æ¿ì ºÎµå·´°Ô º¹±¸ÇϱâÀ§ÇØ + Çù»ó ¾Ë°í¸®Áò¿¡ »õ·Î ¿¹¿Ü¸¦ ¸î°³ Ãß°¡Çß´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡ ÆäÀÌÁö¸¦ ¿äûÇßÀ»¶§ ¼­¹ö°¡ ºê¶ó¿ìÀú°¡ + º¸³½ Accept-language¿¡ ¸Â´Â ÆäÀÌÁö¸¦ ´Ü ÇÑ°³¸¸ + ãÀ¸¸é ¹®Á¦°¡ ¾øÁö¸¸, ±×·¯Áö ¾ÊÀº °æ¿ì ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô + "No Acceptable Variant"³ª "Multiple Choices" ÀÀ´äÀ» º¸³½´Ù. + ÀÌ·± ¿À·ù¹®À» ÇÇÇϱâÀ§ÇØ ÀÌ °æ¿ì Accept-language¸¦ + ¹«½ÃÇÏ°í Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ¸íÈ®È÷ ¸ÂÁö´Â ¾ÊÁö¸¸ ¹®¼­¸¦ + º¸³»µµ·Ï ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ForceLanguagePriority + Áö½Ã¾î´Â ¼­¹ö°¡ ÀÌ·± ¿À·ù¹®Áß Çϳª ȤÀº µÑ´Ù¸¦ ¹«½ÃÇÏ°í + LanguagePriority + Áö½Ã¾î·Î ÆÇ´ÜÇϵµ·Ï ÇÑ´Ù.

    + +

    ¶Ç, ¼­¹ö´Â ¸Â´Â ¾ð¾î¸¦ ¸øãÀº °æ¿ì ºÎ¸ð¾ð¾î¸¦ ãÀ» ¼öµµ + ÀÖ´Ù. ¿¹¸¦ µé¾î Ŭ¶óÀ̾ðÆ®°¡ ¿µ±¹¿µ¾î¸¦ ¶æÇÏ´Â + en-GB ¾ð¾î·Î ¹®¼­¸¦ ¿äûÇÑ °æ¿ì, HTTP/1.1 Ç¥ÁØ¿¡ + µû¸£¸é ¼­¹ö´Â enÀ¸·Î¸¸ Ç¥½ÃµÈ ¹®¼­¸¦ ÀϹÝÀûÀ¸·Î + ¼±ÅÃÇÏÁö ¸øÇÑ´Ù. (±×·¡¼­ ¿µ±¹¿µ¾î¸¦ ÀÌÇØÇÏ´Â µ¶ÀÚ°¡ ÀϹÝÀûÀÎ + ¿µ¾îµµ ÀÌÇØÇÒ ¼ö ÀÖÀ¸¹Ç·Î Accept-Language Çì´õ¿¡ + en-GB¸¸ Æ÷ÇÔÇÏ°í enÀ» Æ÷ÇÔÇÏÁö¾ÊÀ¸¸é + °ÅÀÇ È®½ÇÈ÷ À߸øµÈ ¼³Á¤ÀÓÀ» À¯ÀÇÇ϶ó. ºÒÇàÈ÷µµ ÇöÀç ¸¹Àº + Ŭ¶óÀ̾ðÆ®µéÀº ÀÌ·± ½ÄÀ¸·Î ±âº»¼³Á¤µÇÀÖ´Ù.) ´Ù¸¥ ¾ð¾î¸¦ + ãÁö ¸øÇÏ¿© ¼­¹ö°¡ "No Acceptable Variants" ¿À·ù¸¦ º¸³»°Å³ª + LanguagePriority·Î + µ¹¾Æ°¡¾ß ÇÑ´Ù¸é, ¼­¹ö´Â ÇÏÀ§¾ð¾î ±Ô¾àÀ» ¹«½ÃÇÏ°í + en-GB¸¦ en ¹®¼­¿¡ ´ëÀÀÇÑ´Ù. + ¾Ï¹¬ÀûÀ¸·Î ¾ÆÆÄÄ¡´Â ºÎ¸ð¾ð¾î¸¦ ¸Å¿ì ³·Àº Ç°Áú°ªÀ¸·Î + Ŭ¶óÀ̾ðÆ®ÀÇ Çã¿ë¾ð¾î ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù. ±×·¯³ª Ŭ¶óÀ̾ðÆ®°¡ + "en-GB; q=0.9, fr; q=0.8"À» ¿äûÇÏ°í ¼­¹ö¿¡ "en"°ú "fr" + ¹®¼­°¡ ÀÖ´Ù¸é, "fr" ¹®¼­°¡ ¼±ÅõÊÀ» ÁÖÀÇÇ϶ó. ÀÌ´Â HTTP/1.1 + Ç¥ÁØÀ» ÁöÅ°°í, ¿Ã¹Ù·Î ¼³Á¤µÈ Ŭ¶óÀ̾ðÆ®¿Í È¿À²ÀûÀ¸·Î + µ¿ÀÛÇϱâÀ§ÇÔÀÌ´Ù.

    + +

    »ç¿ëÀÚ°¡ ¼±È£ÇÏ´Â ¾ð¾î¸¦ ¾Ë¾Æ³»±âÀ§ÇÑ (ÄíÅ°³ª Ưº°ÇÑ + URL-°æ·Î °°Àº) °í±Þ ±â¹ýÀ» Áö¿øÇϱâÀ§ÇØ ¾ÆÆÄÄ¡ 2.0.47ºÎÅÍ + mod_negotiationÀº prefer-language¶ó´Â + ȯ°æº¯¼ö¸¦ ÀνÄÇÑ´Ù. ÀÌ È¯°æº¯¼ö°¡ + Á¸ÀçÇÏ°í ÀûÀýÇÑ ¾ð¾îű׸¦ Æ÷ÇÔÇÑ´Ù¸é, + mod_negotiationÀº ÇØ´çÇÏ´Â º¯ÇüÀ» ¼±ÅÃÇÏ·Á°í + ½ÃµµÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ Çù»ó°úÁ¤À» ½ÃÀÛÇÑ´Ù.

    + + ¿¹Á¦ + SetEnvIf Cookie "language=(.+)" prefer-language=$1 + +
    +
    + +
    ÀÚ¿¬½º·¯¿î(transparent) ³»¿ëÇù»óÀÇ È®Àå + +

    ¾ÆÆÄÄ¡´Â ´ÙÀ½°ú °°ÀÌ ÀÚ¿¬½º·¯¿î ³»¿ëÈ®Àå ÇÁ·ÎÅäÄÝÀ» (RFC 2295) +È®ÀåÇÑ´Ù. º¯Çü ¸ñ·ÏÀÇ »õ·Î¿î {encoding ..}´Â ƯÁ¤ +content-encodingÀ» °¡Áø º¯Çü¸¸À» ÁöĪÇÑ´Ù. RVSA/1.0 ¾Ë°í¸®ÁòÀº +(RFC 2296) ¸ñ·Ï¿¡¼­ ÀÎÄÚµùµÈ º¯ÇüÀ» ÀνÄÇÒ ¼ö ÀÖ°í, ÀÎÄÚµùÀÌ +Accept-Encoding ¿äû Çì´õ¿¡ ¸Â´Â °æ¿ì ÀÎÄÚµùµÈ +º¯Çüµéµµ È帷Π»ç¿ëÇϵµ·Ï È®ÀåµÇ¾ú´Ù. RVSA/1.0 ±¸ÇöÀº ÃÖÀûÀÇ +º¯ÇüÀ» ã±â Àü¿¡ °è»êµÈ Ç°Áú°è¼ö¸¦ ¼Ò¼öÁ¡ 5ÀÚ¸®¿¡¼­ ¹Ý¿Ã¸²ÇÏÁö +¾Ê´Â´Ù.

    +
    + +
    ÇÏÀÌÆÛ¸µÅ©¿Í À̸§±ÔÄ¢¿¡ ´ëÇÏ¿© + +

    ¾ð¾î(language) Çù»óÀ» »ç¿ëÇÑ´Ù¸é ÆÄÀÏÀº ¿©·¯ È®ÀåÀÚ¸¦ + °¡Áö°í È®ÀåÀÚÀÇ ¼ø¼­´Â º¸Åë °ü°è¾øÀ¸¹Ç·Î ÆÄÀÏ¸í¿¡ ¿©·¯ ´Ù¸¥ + À̸§±ÔÄ¢À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. (ÀÚ¼¼ÇÑ ³»¿ëÀº mod_mime ¹®¼­¸¦ + Âü°íÇ϶ó.)

    + +

    ÀüÇüÀûÀÎ ÆÄÀÏÀº MIME-type È®ÀåÀÚ (¿¹¸¦ µé¾î, + html), °æ¿ì¿¡ µû¶ó encoding È®ÀåÀÚ (¿¹¸¦ + µé¾î, gz), ÆÄÀÏ¿¡ ¿©·¯ ¾ð¾î º¯ÇüÀÌ ÀÖ´Â + °æ¿ì ¹°·Ð ¾ð¾î È®ÀåÀÚ¸¦ (¿¹¸¦ µé¾î, en) + °¡Áø´Ù.

    + +

    ¿¹Á¦:

    + +
      +
    • foo.en.html
    • + +
    • foo.html.en
    • + +
    • foo.en.html.gz
    • +
    + +

    ´ÙÀ½Àº ¸î¸î ÆÄÀϸí°ú ±× ÆÄÀÏ¿¡ ´ëÇÑ À¯È¿ÇÏ°í À¯È¿ÇÏÁö¾ÊÀº + ÇÏÀÌÆÛ¸µÅ©¸¦ º¸ÀδÙ:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ÆÄÀϸíÀ¯È¿ÇÑ ÇÏÀÌÆÛ¸µÅ©À¯È¿ÇÏÁö¾ÊÀº ÇÏÀÌÆÛ¸µÅ©
    foo.html.enfoo
    + foo.html
    -
    foo.en.htmlfoofoo.html
    foo.html.en.gzfoo
    + foo.html
    foo.gz
    + foo.html.gz
    foo.en.html.gzfoofoo.html
    + foo.html.gz
    + foo.gz
    foo.gz.html.enfoo
    + foo.gz
    + foo.gz.html
    foo.html
    foo.html.gz.enfoo
    + foo.html
    + foo.html.gz
    foo.gz
    + +

    À§ Ç¥¸¦ º¸¸é ÇÏÀÌÆÛ¸µÅ©¿¡ ¾î¶² È®ÀåÀÚµµ ¾ø´Â À̸§À» + (¿¹¸¦ µé¾î, foo) Ç×»ó »ç¿ëÇÒ ¼ö ÀÖÀ½À» + ¾Ë ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀåÁ¡Àº ¹®¼­ÀÇ ½ÇÁ¦ Á¾·ù¸¦ ¼û±æ ¼ö À־, + ¿¹¸¦ µé¾î ÇÏÀÌ·¯¸µÅ© ÂüÁ¶¸¦ ¼öÁ¤ÇϾʰí + html ÆÄÀÏÀ» shtmlÀ̳ª + cgi·Î º¯°æÇÒ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù.

    + +

    °è¼Ó ÇÏÀÌÆÛ¸µÅ©¿¡ MIME-typeÀ» (¿¹¸¦ µé¾î, + foo.html) »ç¿ëÇÏ°í ½Í´Ù¸é (encoding È®ÀåÀÚ°¡ + ÀÖ´Ù¸é À̰͵µ Æ÷ÇÔÇÏ¿©) ¾ð¾î È®ÀåÀÚ¸¦ MIME-type È®ÀåÀÚº¸´Ù + ¿À¸¥ÂÊ¿¡ (¿¹¸¦ µé¾î, foo.html.en) + µÎ¾î¾ßÇÑ´Ù.

    +
    + +
    ij½¬¿¡ ´ëÇÏ¿© + +

    ij½¬°¡ Ç¥ÇöÀ» ÀúÀåÇϸé Ç¥Çö°ú ¿äû URLÀ» ¿¬°ü½ÃŲ´Ù. + ´ÙÀ½¹ø ±× URLÀ» ¿äûÇϸé ij½¬´Â ÀúÀåµÈ Ç¥ÇöÀ» »ç¿ëÇÑ´Ù. + ±×·¯³ª ¼­¹ö¿Í Çù»óÀÌ °¡´ÉÇÑ ÀÚ¿øÀÎ °æ¿ì ù¹ø° ¿äûÇÑ º¯Çü¸¸ + ij½¬µÇ¾î ÀÌÈÄ ¿äûÀº ij½¬µÈ À߸øµÈ ÀÀ´äÀ» ¾òÀ» ¼ö ÀÖ´Ù. + À̸¦ ¸·±âÀ§ÇØ ¾ÆÆÄÄ¡´Â º¸Åë ³»¿ëÇù»óÈÄ ¹ÝȯµÇ´Â ¸ðµç ¿äû¿¡ + HTTP/1.0 Ŭ¶óÀ̾ðÆ®°¡ ij½¬¸¦ ¸øÇϵµ·Ï Ç¥½Ã¸¦ ÇÑ´Ù. ¶Ç, ¾ÆÆÄÄ¡´Â + Çù»óÇÑ ÀÀ´äÀÇ Ä³½¬¸¦ Çã¿ëÇÏ´Â HTTP/1.1 ÇÁ·ÎÅäÄÝÀÇ ±â´ÉÀ» + Áö¿øÇÑ´Ù.

    + +

    CacheNegotiatedDocs + Áö½Ã¾î´Â HTTP/1.0 ȣȯ Ŭ¶óÀ̾ðÆ®(ºê¶ó¿ìÀú ȤÀº ij½¬)°¡ + º¸³½ ¿äû¿¡ ´ëÇØ Çù»óÇÑ ÀÀ´äÀ» ij½¬ÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + ¼­¹ö³ª °¡»óÈ£½ºÆ® ¼³Á¤¿¡ »ç¿ëÇϸç, ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¾Ê´Â´Ù. + ÀÌ Áö½Ã¾î´Â HTTP/1.1 Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû°ú´Â °ü°è°¡ ¾ø´Ù.

    + +

    HTTP/1.1 Ŭ¶óÀ̾ðÆ®¿¡°Ô ¾ÆÆÄÄ¡´Â ÀÀ´äÀÇ Çù»ó ¹üÀ§¸¦ + ¾Ë·ÁÁÖ´Â Vary HTTP ÀÀ´äÇì´õ¸¦ º¸³½´Ù. ÀÌ Á¤º¸¸¦ + »ç¿ëÇÏ¿© ´ÙÀ½ ¿äûÀ» ij½¬µÈ º¹»çº»À¸·Î ´ëüÇÒ ¼ö ÀÖ´ÂÁö + ÆÇ´ÜÇÒ ¼ö ÀÖ´Ù. Çé»óÀÇ ¹üÀ§¿Í °ü°è¾øÀÌ Ä³½¬µÈ º¹»çº»À» + ±ÇÇÑ´Ù¸é force-no-vary ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +
    + +
    ´Ù¸¥ Á¤º¸ + +

    ³»¿ëÇù»ó¿¡ ´ëÇÑ ´Ù¸¥ Á¤º¸´Â Alan J. Flavell°¡ ¾´ Language + Negotiation Notes¸¦ Âü°íÇ϶ó. ±×·¯³ª ÀÌ ¹®¼­´Â ¾ÆÁ÷ + ¾ÆÆÄÄ¡ 2.0ÀÇ º¯È­¸¦ ¹Ý¿µÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/content-negotiation.xml.meta b/trunk/docs/manual/content-negotiation.xml.meta new file mode 100644 index 0000000000..98539b1d01 --- /dev/null +++ b/trunk/docs/manual/content-negotiation.xml.meta @@ -0,0 +1,13 @@ + + + + content-negotiation + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/custom-error.html b/trunk/docs/manual/custom-error.html new file mode 100644 index 0000000000..3ee0877190 --- /dev/null +++ b/trunk/docs/manual/custom-error.html @@ -0,0 +1,15 @@ +URI: custom-error.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: custom-error.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: custom-error.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: custom-error.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/custom-error.html.en b/trunk/docs/manual/custom-error.html.en new file mode 100644 index 0000000000..0d8048ae48 --- /dev/null +++ b/trunk/docs/manual/custom-error.html.en @@ -0,0 +1,204 @@ + + + +Custom Error Responses - Apache HTTP Server + + + + + +
    <-
    +

    Custom Error Responses

    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + +

    Additional functionality allows webmasters to configure the response + of Apache to some error or problem.

    + +

    Customizable responses can be defined to be activated in the event of + a server detected error or problem.

    + +

    If a script crashes and produces a "500 Server Error" response, + then this response can be replaced with either some friendlier text or by + a redirection to another URL (local or external).

    +
    + +
    top
    +
    +

    Behavior

    + + +

    Old Behavior

    + + +

    NCSA httpd 1.3 would return some boring old error/problem message + which would often be meaningless to the user, and would provide no + means of logging the symptoms which caused it.

    + + +

    New Behavior

    + + +

    The server can be asked to:

    + +
      +
    1. Display some other text, instead of the NCSA hard coded + messages, or
    2. + +
    3. redirect to a local URL, or
    4. + +
    5. redirect to an external URL.
    6. +
    + +

    Redirecting to another URL can be useful, but only if some + information can be passed which can then be used to explain and/or log + the error/problem more clearly.

    + +

    To achieve this, Apache will define new CGI-like environment + variables:

    + +

    + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +

    + +

    Note the REDIRECT_ prefix.

    + +

    At least REDIRECT_URL and + REDIRECT_QUERY_STRING will be passed to the + new URL (assuming it's a cgi-script or a cgi-include). The + other variables will exist only if they existed prior to + the error/problem. None of these will be + set if your ErrorDocument is an + external redirect (anything starting with a + scheme name like http:, even if it refers to the same host + as the server).

    + +
    top
    +
    +

    Configuration

    + + +

    Use of ErrorDocument is enabled + for .htaccess files when the + AllowOverride is set accordingly.

    + +

    Here are some examples...

    + +

    + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +

    + +

    The syntax is,

    + +

    + ErrorDocument <3-digit-code> <action> +

    + +

    where the action can be,

    + +
      +
    1. Text to be displayed. Prefix the text with a quote + ("). Whatever follows the quote is displayed. Note: + the (") prefix isn't displayed.
    2. + +
    3. An external URL to redirect to.
    4. + +
    5. A local URL to redirect to.
    6. +
    +
    top
    +
    +

    Custom Error Responses and Redirects

    + + +

    Apache's behavior to redirected URLs has been modified so + that additional environment variables are available to a + script/server-include.

    + +

    Old behavior

    + + +

    Standard CGI vars were made available to a script which + has been redirected to. No indication of where the + redirection came from was provided.

    + + +

    New behavior

    + + +

    A new batch of environment variables will be initialized + for use by a script which has been redirected to. Each new + variable will have the prefix REDIRECT_. + REDIRECT_ environment variables are created from + the CGI environment variables which existed prior to the + redirect, they are renamed with a REDIRECT_ + prefix, i.e., HTTP_USER_AGENT becomes + REDIRECT_HTTP_USER_AGENT. In addition to these + new variables, Apache will define REDIRECT_URL + and REDIRECT_STATUS to help the script trace its + origin. Both the original URL and the URL being redirected to + can be logged in the access log.

    + +

    If the ErrorDocument specifies a local redirect to a CGI + script, the script should include a "Status:" + header field in its output in order to ensure the propagation + all the way back to the client of the error condition that + caused it to be invoked. For instance, a Perl ErrorDocument + script might include the following:

    + +

    + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +

    + +

    If the script is dedicated to handling a particular error + condition, such as 404 Not Found, it can + use the specific code and error text instead.

    + +

    Note that the script must emit an appropriate + Status: header (such as 302 Found), if the + response contains a Location: header (in order to issue a + client side redirect). Otherwise the Location: header may + have no effect.

    + +
    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/custom-error.html.es b/trunk/docs/manual/custom-error.html.es new file mode 100644 index 0000000000..b97c38f2e7 --- /dev/null +++ b/trunk/docs/manual/custom-error.html.es @@ -0,0 +1,219 @@ + + + +Respuestas de error personalizadas - Servidor HTTP Apache + + + + + +
    <-
    +

    Respuestas de error personalizadas

    +
    +

    Idiomas disponibles:  en  | + es  | + ja  | + ko 

    +
    + +

    Apache ofrece la posibilidad de que los webmasters puedan + configurar las respuestas que muestra el servidor Apache cuando se + producen algunos errores o problemas.

    + +

    Las respuestas personalizadas pueden definirse para activarse + en caso de que el servidor detecte un error o problema.

    + +

    Si un script termina de forma anormal y se produce una respuesta + "500 Server Error", esta respuesta puede ser sustituida por otro + texto de su elección o por una redirección a otra URL + (local o externa).

    +
    + +
    top
    +
    +

    Comportamiento

    + + +

    Comportamiento anterior

    + + +

    NCSA httpd 1.3 devolvía mensajes antiguos del error o + problema encontrado que con frecuencia no tenían + significado alguno para el usuario, y que no incluían en + los logs información que diera pistas sobre las causas de + lo sucedido.

    + + +

    Comportamiento actual

    + + +

    Se puede hacer que el servidor siga uno de los siguientes + comportamientos:

    + +
      +
    1. Desplegar un texto diferente, en lugar de los mensajes de + la NCSA, o
    2. + +
    3. redireccionar la petición a una URL local, o
    4. + +
    5. redireccionar la petición a una URL externa.
    6. +
    + +

    Redireccionar a otra URL puede resultar de utilidad, pero + solo si con ello se puede también pasar alguna + información que pueda explicar el error o problema y/o + registrarlo en el log correspondiente más claramente.

    + +

    Para conseguir esto, Apache define ahora variables de entorno + similares a las de los CGI:

    + +

    + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +

    + +

    Tenga en cuenta el prefijo REDIRECT_.

    + +

    Al menos REDIRECT_URL y + REDIRECT_QUERY_STRING se pasarán a la nueva + URL (asumiendo que es un cgi-script o un cgi-include). Las otras + variables existirán solo si existían antes de aparecer + el error o problema. Ninguna de estas variables + se creará si en la directiva ErrorDocument ha especificado una + redirección externa (cualquier cosa que empiece + por un nombre de esquema del tipo http:, incluso si + se refiere al mismo servidor).

    + +
    top
    +
    +

    Configuración

    + + +

    El uso de ErrorDocument + está activado para los ficheros .htaccess cuando AllowOverride tiene el valor + adecuado.

    + +

    Aquí hay algunos ejemplos más...

    + +

    + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +

    + +

    La sintaxis es,

    + +

    + ErrorDocument <3-digit-code> <action> +

    + +

    donde action puede ser,

    + +
      +
    1. Texto a mostrar. Ponga antes del texto que quiere que se + muestre unas comillas ("). Lo que sea que siga a las comillas se + mostrará. Nota: las comillas (") no se + muestran.
    2. + +
    3. Una URL local a la que se redireccionará la + petición.
    4. + +
    5. Una URL externa a la que se redireccionará la + petición.
    6. +
    +
    top
    +
    +

    Mesajes de error personalizados y redirecciones

    + + +

    El comportamiento de Apache en cuanto a las redirecciones ha + cambiado para que puedan usarse más variables de entorno con + los script/server-include.

    + +

    Antiguo comportamiento

    + + +

    Las variables CGI estándar estaban disponibles para el + script al que se hacía la redirección. No se incluía + ninguna indicación sobre la precedencia de la + redirección.

    + + +

    Nuevo comportamiento

    + + +

    Un nuevo grupo de variables de entorno se inicializa para que + las use el script al que ha sido redireccionado. Cada + nueva variable tendrá el prefijo REDIRECT_. + Las variables de entorno REDIRECT_ se crean a + partir de de las variables de entorno CGI que existen antes de + la redirección, se les cambia el nombre + añadiéndoles el prefijo REDIRECT_, por + ejemplo, HTTP_USER_AGENT pasa a ser + REDIRECT_HTTP_USER_AGENT. Además, para esas + nuevas variables, Apache definirá REDIRECT_URL + y REDIRECT_STATUS para ayudar al script a seguir su + origen. Tanto la URL original como la URL a la que es redirigida + la petición pueden almacenarse en los logs de acceso.

    + +

    Si ErrorDocument especifica una redirección local a un + script CGI, el script debe incluir una campo de cabeceraa + "Status:" en el resultado final para asegurar que + es posible hacer llegar al cliente de vuelta la condición + de error que lo provocó. Por ejemplo, un script en Perl + para usar con ErrorDocument podría incluir lo + siguiente:

    + +

    + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +

    + +

    Si el script tiene como fin tratar una determinada + condición de error, por ejemplo + 404 Not Found, se pueden usar los + códigos de error y textos específicos en su lugar.

    + +

    Tenga en cuenta que el script debe incluir un campo + de cabecera Status: apropiado (como + 302 Found), si la respuesta contiene un campo de + cabecera Location: (para poder enviar una + redirección que se interprete en el cliente). De otra + manera, la cabecera + Location: puede que no tenga efecto.

    + +
    +
    +

    Idiomas disponibles:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/custom-error.html.ja.euc-jp b/trunk/docs/manual/custom-error.html.ja.euc-jp new file mode 100644 index 0000000000..b150fc5dfd --- /dev/null +++ b/trunk/docs/manual/custom-error.html.ja.euc-jp @@ -0,0 +1,197 @@ + + + +¥«¥¹¥¿¥à¥¨¥é¡¼¥ì¥¹¥Ý¥ó¥¹ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥«¥¹¥¿¥à¥¨¥é¡¼¥ì¥¹¥Ý¥ó¥¹

    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + +

    ¥¦¥§¥Ö¥Þ¥¹¥¿¡¼¤¬²¿¤é¤«¤Î¥¨¥é¡¼¤äÌäÂê¤ËÂФ¹¤ë + Apache ¤ÎÈ¿±þ¤òÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ëÄɲõ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤¬¥¨¥é¡¼¤äÌäÂê¤òȯ¸«¤·¤¿¾ì¹ç¤ÎÈ¿±þ¤ò¡¢ + ¥«¥¹¥¿¥Þ¥¤¥º¤·¤ÆÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤¬¼ºÇÔ¤·¤Æ "500 Server Error" + ¤òȯÀ¸¤µ¤»¤¿¤È¤·¤Þ¤¹¡£¤³¤Î¾ì¹ç¤ÎÈ¿±þ¤ò¡¢¤è¤ê¹¥¤Þ¤·¤¤¥Æ¥­¥¹¥È¤ä¡¢Ê̤Π+ URL (ÆâÉôµÚ¤Ó³°Éô) ¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó¤ËÃÖ¤­´¹¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    +
    + +
    top
    +
    +

    Æ°ºî

    + + +

    ¸Å¤¤Æ°ºî

    + + +

    NCSA httpd 1.3 ¤Ï¡¢¸Å¤¯¤ÆÂà¶þ¤Ê¥¨¥é¡¼/ÌäÂê¥á¥Ã¥»¡¼¥¸¤ò + ÊÖ¤·¤Æ¤¤¤Þ¤·¤¿¡£¤½¤ì¤Ï¤·¤Ð¤·¤Ð¥æ¡¼¥¶¤Ë¤Ï̵°ÕÌ£¤Ç¤¢¤ê¡¢ + ¤Þ¤¿¤½¤ì¤òȯÀ¸¤µ¤»¤¿¸¶°ø¤òµ­Ï¿¤¹¤ëÊýË¡¤âÄ󶡤·¤Æ¤¤¤Þ¤»¤ó¤Ç¤·¤¿¡£

    + + +

    ¿·¤·¤¤Æ°ºî

    + + +
      +
    1. NCSA ¤Î¥Ï¡¼¥É¥³¡¼¥É¤µ¤ì¤¿¥á¥Ã¥»¡¼¥¸¤ÎÂå¤ï¤ê¤Ë + ¾¤Î¥Æ¥­¥¹¥È¤òɽ¼¨
    2. + +
    3. ¥í¡¼¥«¥ë¤Î URL ¤Ë¥ê¥À¥¤¥ì¥¯¥È
    4. + +
    5. ³°Éô¤Î URL ¤Ë¥ê¥À¥¤¥ì¥¯¥È
    6. +
    + +

    ¤¹¤ë¤è¤¦¤Ë¥µ¡¼¥Ð¤òÀßÄê¤Ç¤­¤Þ¤¹¡£

    + +

    Ê̤ΠURL ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤³¤È¤ÏÌò¤ËΩ¤Á¤Þ¤¹¤¬¡¢ + ¤½¤ì¤ÏÀâÌÀ¤ò¤·¤¿¤ê¡¢¤è¤êÌÀ³Î¤Ë¸í¤ê/ÌäÂê¤òµ­Ï¿¤·¤¿¤ê¤¹¤ë¤¿¤á¤Ë + ²¿¤«¾ðÊó¤òÅÁ¤¨¤é¤ì¤ë¤È¤­¤Ë¸Â¤ê¤Þ¤¹¡£

    + +

    ¤³¤ì¤ò¼Â¸½¤¹¤ë¤¿¤á¤Ë¡¢ Apache ¤Ï¿·¤·¤¯ CGI ¤Î¤è¤¦¤Ê´Ä¶­ÊÑ¿ô¤ò + ÄêµÁ¤·¤Þ¤¹:

    + +

    + REDIRECT_HTTP_ACCEPT=*/*, image/gif, + image/x-xbitmap, image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX + A.09.05 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +

    + +

    Ƭ¤ËÉÕ¤¯ REDIRECT_ ¤ËÃíÌܤ·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¾¯¤Ê¤¯¤È¤â REDIRECT_URL ¤È + REDIRECT_QUERY_STRING ¤Ï¿·¤·¤¤ URL (CGI ¥¹¥¯¥ê¥×¥È¤« + CGI ¥¤¥ó¥¯¥ë¡¼¥É¤Ç¤¢¤ë¤È²¾Äꤵ¤ì¤Þ¤¹) ¤ËÅϤµ¤ì¤Þ¤¹¡£ + ¾¤ÎÊÑ¿ô¤Ï¡¢¥¨¥é¡¼¤äÌäÂ꤬µ¯¤­¤ëÁ°¤Ë¸ºß¤·¤¿¾ì¹ç¤Ë¤À¤±Â¸ºß¤·¤Þ¤¹¡£ + ¤â¤·¤¢¤Ê¤¿¤ÎÀßÄꤷ¤¿ ErrorDocument ¤¬ ³°Éô¥ê¥À¥¤¥ì¥¯¥È + (¤¹¤Ê¤ï¤Á¡¢http: + ¤Î¤è¤¦¤ÊÂηÏ̾¤«¤é»Ï¤Þ¤ë¤¹¤Ù¤Æ¤Î¤â¤Î¡£¤¿¤È¤¨Æ±¤¸¥Û¥¹¥È¤ò»Ø¤·¤Æ¤¤¤Æ¤â) + ¤Ê¤é¤Ð¡¢¤³¤ì¤é¤Ï¤Þ¤Ã¤¿¤¯ÀßÄꤵ¤ì¤Þ¤»¤ó¡£

    + +
    top
    +
    +

    ÀßÄê

    + + +

    AllowOverride ¤¬Å¬ÀÚ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢ + .htaccess ¥Õ¥¡¥¤¥ë¤Ç ErrorDocument + ¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤³¤Ë¡¢¤¤¤¯¤Ä¤«¤ÎÎã¤òµó¤²¤Þ¤¹¡£

    + +

    + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +

    + +

    ¹½Ê¸

    + +

    + ErrorDocument <3-digit-code> <action> +

    + +

    action (Æ°ºî) ¤Ï¡¢

    + +
      +
    1. ɽ¼¨¤µ¤ì¤ë¤Ù¤­¥Æ¥­¥¹¥È¡£¥Æ¥­¥¹¥È¤Ë¤Ï°úÍÑÉä (") ¤ò¤Ä¤±¤Þ¤¹¡£ + °úÍÑÉä¤Î¸å¤Ë³¤¯¤â¤Î¤¬²¿¤Ç¤âɽ¼¨¤µ¤ì¤Þ¤¹¡£ + Ãí°Õ : (") ¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó
    2. + +
    3. ¥ê¥À¥¤¥ì¥¯¥ÈÀè¤Î³°Éô URL
    4. + +
    5. ¥ê¥À¥¤¥ì¥¯¥ÈÀè¤Î¥í¡¼¥«¥ë URL
    6. +
    +
    top
    +
    +

    ¥«¥¹¥¿¥à¥¨¥é¡¼¥ì¥¹¥Ý¥ó¥¹¤È¥ê¥À¥¤¥ì¥¯¥È

    + + +

    ¥¹¥¯¥ê¥×¥È/SSI ¤ËÄɲäδĶ­ÊÑ¿ô¤¬ÍøÍѲÄǽ¤Ë¤Ê¤ë¤è¤¦¤Ë¡¢ + ¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿ URL ¤ËÂФ¹¤ë Apache ¤ÎÆ°ºî¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿¡£

    + +

    ¸Å¤¤Æ°ºî

    + + +

    ¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿¥¹¥¯¥ê¥×¥È¤Ïɸ½à¤Î CGI + ´Ä¶­ÊÑ¿ô¤òÍøÍѲÄǽ¤Ç¤·¤¿¡£¤·¤«¤·¡¢¤É¤³¤«¤é¥ê¥À¥¤¥ì¥¯¥È + ¤µ¤ì¤¿¤«¤Î¾ðÊó¤ÏÄ󶡤µ¤ì¤Æ¤¤¤Þ¤»¤ó¤Ç¤·¤¿¡£

    + + +

    ¿·¤·¤¤Æ°ºî

    + + +

    ¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿Àè¤Î¥¹¥¯¥ê¥×¥È¤¬»ÈÍѲÄǽ¤Ê¤è¤¦¤Ë¡¢ + ¿·¤·¤¤¤¿¤¯¤µ¤ó¤Î´Ä¶­ÊÑ¿ô¤¬½é´ü²½¤µ¤ì¤Þ¤¹¡£¿·¤·¤¤ÊÑ¿ô¤Ï¡¢¤½¤ì¤¾¤ì + REDIRECT_ ¤Ç»Ï¤Þ¤ê¤Þ¤¹¡£ + REDIRECT_ ¤Ç»Ï¤Þ¤ë´Ä¶­ÊÑ¿ô¤Ï¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤ëÁ°¤Ë¸ºß¤·¤Æ¤¤¤¿ + CGI ´Ä¶­ÊÑ¿ô¤ÎƬ¤Ë REDIRECT_ ¤òÉÕ¤±¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£ + ¤¹¤Ê¤ï¤Á¡¢HTTP_USER_AGENT ¤Ï + REDIRECT_HTTP_USER_AGENT ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¿·¤·¤¤ÊÑ¿ô¤Ë²Ã¤¨¤Æ¡¢Apache ¤Ï¡¢ + ¥¹¥¯¥ê¥×¥È¤¬¥ê¥À¥¤¥ì¥¯¥È¸µ¤Î¥È¥ì¡¼¥¹¤ò½õ¤±¤ë¤¿¤á¤Ë + REDIRECT_URL ¤È REDIRECT_STATUS + ¤òÄêµÁ¤·¤Þ¤¹¡£¥¢¥¯¥»¥¹¥í¥°¤Ë¤Ï¸µ¤Î URL ¤È¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿ URL + ¤ÎξÊý¤¬µ­Ï¿¤µ¤ì¤Þ¤¹¡£

    + +

    ErrorDocument ¤¬ CGI ¥¹¥¯¥ê¥×¥È¤Ø¤Î¥í¡¼¥«¥ë¥ê¥À¥¤¥ì¥¯¥È¤ò + »ØÄꤷ¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤ì¤òµ¯Æ°¤¹¤ë¤³¤È¤Ë¤Ê¤Ã¤¿¥¨¥é¡¼¤Î¾õÂÖ¤ò + ¥¯¥é¥¤¥¢¥ó¥È¤Þ¤Ç³Î¼Â¤ËÅÁ¤¨¤ë¤¿¤á¤Ë "Status:" + ¥Ø¥Ã¥À¤ò´Þ¤à¤Ù¤­¤Ç¤¹¡£Î㤨¤Ð¡¢ErrorDocument ÍѤΠPerl + ¥¹¥¯¥ê¥×¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤ò´Þ¤à¤«¤â¤·¤ì¤Þ¤»¤ó¡£ +

    + +

    + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +

    + +

    ¥¹¥¯¥ê¥×¥È¤¬ 404 Not Found ¤Î¤è¤¦¤Ê + ÆÃÄê¤Î¥¨¥é¡¼¥³¥ó¥Ç¥£¥·¥ç¥ó¤ò°·¤¦¤¿¤á¤À¤±¤Ë»È¤ï¤ì¤ë¾ì¹ç¤Ï¡¢ + Âå¤ï¤ê¤ËÆÃÄê¤Î¥³¡¼¥É¤È¥¨¥é¡¼¥Æ¥­¥¹¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/custom-error.html.ko.euc-kr b/trunk/docs/manual/custom-error.html.ko.euc-kr new file mode 100644 index 0000000000..82f8b1495d --- /dev/null +++ b/trunk/docs/manual/custom-error.html.ko.euc-kr @@ -0,0 +1,198 @@ + + + +»ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä - Apache HTTP Server + + + + + +
    <-
    +

    »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ja  | + ko 

    +
    + +

    À¥¸¶½ºÅÍ´Â ¿À·ù³ª ¹®Á¦°¡ ¹ß»ýÇßÀ»¶§ ¾ÆÆÄÄ¡ÀÇ ÀÀ´äÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼­¹ö°¡ ¿À·ù³ª ¹®Á¦¸¦ ¹ß°ßÇßÀ»¶§ º¸³¾ »ç¿ëÀÚÁ¤ÀÇ ÀÀ´äÀ» + Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.

    + +

    ½ºÅ©¸³Æ®°¡ Á×Àº °æ¿ì "500 Server Error" ÀÀ´ä ´ë½Å »ç¿ëÀÚ¿¡°Ô + ´õ Ä£±ÙÇÑ ¹®±¸¸¦ »ç¿ëÇϰųª ´Ù¸¥ (°°Àº »çÀÌÆ®³ª ¿ÜºÎ »çÀÌÆ®ÀÇ) + URL·Î ¸®´ÙÀÌ·º¼ÇÀ» ÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    Çൿ

    + + +

    ÀÌÀü Çൿ

    + + +

    NCSA httpd 1.3Àº »ç¿ëÀÚ¿¡°Ô ¹«ÀǹÌÇÏ°í Áö·çÇÑ ¿À·ù¹®À» + º¸³Â´Ù. ¹®Á¦°¡ ¹ß»ýÇÑ ÀÌÀ¯¸¦ ·Î±×¿¡ ³²±æ ¼öµµ ¾ø¾ú´Ù.

    + + +

    »õ·Î¿î Çൿ

    + + +

    ¼­¹ö´Â ´ÙÀ½°ú °°Àº ÀÏÀ» ÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    1. NCSAÀÇ °íÁ¤µÈ ¹®±¸ ´ë½Å ´Ù¸¥ ¹®±¸¸¦ º¸¿©Áְųª
    2. + +
    3. °°Àº »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇϰųª
    4. + +
    5. ¿ÜºÎ »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    6. +
    + +

    ´Ù¸¥ »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇÏ´Â °ÍÀÌ À¯¿ëÇÒ ¼ö ÀÖÁö¸¸, + ÀÌ °æ¿ì ¹®Á¦¸¦ ¼³¸íÇϰųª ·Î±×Çϴµ¥ ÇÊ¿äÇÑ Á¤º¸Áß ÀϺθ¸ + Àü´ÞµÈ´Ù.

    + +

    ¿À·ù¿¡ ´ëÇÑ Á¤º¸¸¦ Àü´ÞÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â CGI½ÄÀÇ »õ·Î¿î + ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù:

    + +

    + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +

    + +

    REDIRECT_ Á¢µÎ»ç¿¡ ÁÖ¸ñÇ϶ó.

    + +

    ÃÖ¼ÒÇÑ REDIRECT_URL°ú + REDIRECT_QUERY_STRINGÀº (cgi-script³ª + cgi-includeÀÏ) »õ URL·Î ³Ñ°ÜÁø´Ù. ´Ù¸¥ º¯¼ö´Â ¿À·ù°¡ + ¹ß»ýÇϱâ ÀÌÀü¿¡ (¿ªÁÖ; À̸§¿¡¼­ REDIRECT_¸¦ + »« ȯ°æº¯¼ö°¡) Á¸ÀçÇÑ °æ¿ì¿¡¸¸ ÀÖ´Ù. + ErrorDocument°¡ + ¿ÜºÎ·Î (°°Àº ¼­¹ö¶óµµ http:¿Í + °°Àº ½ºÅ´(scheme)À¸·Î ½ÃÀÛÇÑ´Ù¸é) ¸®´ÙÀÌ·º¼ÇÇÑ´Ù¸é + ÀÌÁß ¾î¶² °Íµµ ¼³Á¤µÇÁö ¾Ê´Â´Ù.

    + +
    top
    +
    +

    ¼³Á¤

    + + +

    AllowOverride°¡ + ÀûÀýÈ÷ ¼³Á¤µÇ¾ú´Ù¸é .htaccess ÆÄÀÏ¿¡¼­ + ErrorDocument¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù.

    + +

    ´ÙÀ½Àº ¿¹ÀÌ´Ù...

    + +

    + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +

    + +

    ¹®¹ýÀº,

    + +

    + ErrorDocument <3-digit-code> <action> +

    + +

    °¡´ÉÇÑ actionÀº,

    + +
      +
    1. Ãâ·ÂÇÒ ¹®±¸. µû¿ÈÇ¥ (")¸¦ ¹®±¸ ¾Õ¿¡ ºÙÀδÙ. µÚ¿¡ ³ª¿À´Â + µû¿ÈÇ¥´Â Ãâ·ÂµÈ´Ù. ÁÖÀÇ: ¾Õ¿¡ ºÙÀº µû¿ÈÇ¥ (")´Â Ãâ·ÂµÇÁö + ¾Ê´Â´Ù.
    2. + +
    3. ¸®´ÙÀÌ·º¼ÇÇÒ ¿ÜºÎ URL.
    4. + +
    5. ¸®´ÙÀÌ·º¼ÇÇÒ ³»ºÎ URL.
    6. +
    +
    top
    +
    +

    »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä°ú ¸®´ÙÀÌ·º¼Ç

    + + +

    URL·Î ¸®´ÙÀÌ·º¼ÇÇÏ´Â ¾ÆÆÄÄ¡ ÇൿÀº + ½ºÅ©¸³Æ®/server-include¿¡ ȯ°æº¯¼ö¸¦ ´õ ³Ñ°ÜÁÖµµ·Ï º¯°æµÇ¾ú´Ù.

    + +

    ÀÌÀü Çൿ

    + + +

    ¸®´ÙÀÌ·º¼ÇµÇ´Â ½ºÅ©¸³Æ®¿¡ Ç¥ÁØ CGI º¯¼öµéÀÌ ³Ñ¾î°£´Ù. + ¾îµð¿¡¼­ ¸®´ÙÀÌ·º¼ÇÀÌ ÀϾ´ÂÁö ¾Ë ¼ö ¾ø´Ù.

    + + +

    »õ·Î¿î Çൿ

    + + +

    ¸®´ÙÀÌ·º¼ÇµÈ ½ºÅ©¸³Æ®´Â »õ·Î¿î ȯ°æº¯¼öµéÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù. ¸ðµÎ ¾Õ¿¡ REDIRECT_°¡ ºÙ¾îÀÖ´Ù. + REDIRECT_ ȯ°æº¯¼ö´Â ¿ø·¡ CGI ȯ°æº¯¼ö¸í + ¾Õ¿¡ REDIRECT_¸¦ ºÙ¿©¼­ ¸¸µç´Ù. ¿¹¸¦ + µé¾î, HTTP_USER_AGENT´Â + REDIRECT_HTTP_USER_AGENT°¡ µÇ¾ú´Ù. ÀÌ·± º¯¼ö¿¡ + Ãß°¡·Î ½ºÅ©¸³Æ®°¡ ¿ø·¡ URLÀ» ¾Ëµµ·Ï ¾ÆÆÄÄ¡´Â + REDIRECT_URL°ú REDIRECT_STATUS¸¦ + Á¤ÀÇÇÑ´Ù. ¿ø·¡ URL°ú ¸®´ÙÀÌ·º¼ÇµÈ URL ¸ðµÎ Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +

    ErrorDocument°¡ °°Àº ¼­¹ö¿¡ ÀÖ´Â CGI ½ºÅ©¸³Æ®·Î + ¸®´ÙÀÌ·º¼ÇÇÑ´Ù¸é, ½ºÅ©¸³Æ®´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¿À·ù »óȲÀ» + È®½ÇÈ÷ Àü´ÞÇϱâÀ§ÇØ Ãâ·Â¿¡ "Status:" Çì´õ + Çʵ带 Æ÷ÇÔÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, Perl·Î ÀÛ¼ºÇÑ ErrorDocument + ½ºÅ©¸³Æ®´Â ´ÙÀ½°ú °°´Ù:

    + +

    + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +

    + +

    404 Not Found¿Í °°Àº ƯÁ¤ ¿À·ù + »óȲ¿¡ ´ëÇÑ ½ºÅ©¸³Æ®¶ó¸é, ´ë½Å (¿ªÁÖ; °íÁ¤µÈ) + ƯÁ¤ »óÅÂÄÚµå¿Í ¿À·ù¹®À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    (Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» ¿äûÇϱâÀ§ÇØ) ÀÀ´ä¿¡ + Location: Çì´õ¸¦ Æ÷ÇÔÇÑ´Ù¸é, ½ºÅ©¸³Æ®´Â + ¹Ýµå½Ã (302 Found °°Àº) ÀûÀýÇÑ + Status: Çì´õ¸¦ Ãâ·ÂÇØ¾ß ÇÔÀ» ÁÖÀÇÇ϶ó. ±×·¸Áö¾ÊÀ¸¸é + Location: Çì´õ°¡ ¾Æ¹« ¼Ò¿ë¾ø°Ô µÉ ¼ö ÀÖ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/custom-error.xml b/trunk/docs/manual/custom-error.xml new file mode 100644 index 0000000000..8777b36fab --- /dev/null +++ b/trunk/docs/manual/custom-error.xml @@ -0,0 +1,192 @@ + + + + + + + + + + Custom Error Responses + + +

    Additional functionality allows webmasters to configure the response + of Apache to some error or problem.

    + +

    Customizable responses can be defined to be activated in the event of + a server detected error or problem.

    + +

    If a script crashes and produces a "500 Server Error" response, + then this response can be replaced with either some friendlier text or by + a redirection to another URL (local or external).

    +
    + +
    + Behavior + +
    + Old Behavior + +

    NCSA httpd 1.3 would return some boring old error/problem message + which would often be meaningless to the user, and would provide no + means of logging the symptoms which caused it.

    +
    + +
    + New Behavior + +

    The server can be asked to:

    + +
      +
    1. Display some other text, instead of the NCSA hard coded + messages, or
    2. + +
    3. redirect to a local URL, or
    4. + +
    5. redirect to an external URL.
    6. +
    + +

    Redirecting to another URL can be useful, but only if some + information can be passed which can then be used to explain and/or log + the error/problem more clearly.

    + +

    To achieve this, Apache will define new CGI-like environment + variables:

    + + + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +
    + +

    Note the REDIRECT_ prefix.

    + +

    At least REDIRECT_URL and + REDIRECT_QUERY_STRING will be passed to the + new URL (assuming it's a cgi-script or a cgi-include). The + other variables will exist only if they existed prior to + the error/problem. None of these will be + set if your ErrorDocument is an + external redirect (anything starting with a + scheme name like http:, even if it refers to the same host + as the server).

    +
    +
    + +
    + Configuration + +

    Use of ErrorDocument is enabled + for .htaccess files when the + AllowOverride is set accordingly.

    + +

    Here are some examples...

    + + + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +
    + +

    The syntax is,

    + + + ErrorDocument <3-digit-code> <action> + + +

    where the action can be,

    + +
      +
    1. Text to be displayed. Prefix the text with a quote + ("). Whatever follows the quote is displayed. Note: + the (") prefix isn't displayed.
    2. + +
    3. An external URL to redirect to.
    4. + +
    5. A local URL to redirect to.
    6. +
    +
    + +
    + Custom Error Responses and Redirects + +

    Apache's behavior to redirected URLs has been modified so + that additional environment variables are available to a + script/server-include.

    + +
    + Old behavior + +

    Standard CGI vars were made available to a script which + has been redirected to. No indication of where the + redirection came from was provided.

    +
    + +
    + New behavior + +

    A new batch of environment variables will be initialized + for use by a script which has been redirected to. Each new + variable will have the prefix REDIRECT_. + REDIRECT_ environment variables are created from + the CGI environment variables which existed prior to the + redirect, they are renamed with a REDIRECT_ + prefix, i.e., HTTP_USER_AGENT becomes + REDIRECT_HTTP_USER_AGENT. In addition to these + new variables, Apache will define REDIRECT_URL + and REDIRECT_STATUS to help the script trace its + origin. Both the original URL and the URL being redirected to + can be logged in the access log.

    + +

    If the ErrorDocument specifies a local redirect to a CGI + script, the script should include a "Status:" + header field in its output in order to ensure the propagation + all the way back to the client of the error condition that + caused it to be invoked. For instance, a Perl ErrorDocument + script might include the following:

    + + + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +
    + +

    If the script is dedicated to handling a particular error + condition, such as 404 Not Found, it can + use the specific code and error text instead.

    + +

    Note that the script must emit an appropriate + Status: header (such as 302 Found), if the + response contains a Location: header (in order to issue a + client side redirect). Otherwise the Location: header may + have no effect.

    +
    +
    +
    diff --git a/trunk/docs/manual/custom-error.xml.es b/trunk/docs/manual/custom-error.xml.es new file mode 100644 index 0000000000..d043efd073 --- /dev/null +++ b/trunk/docs/manual/custom-error.xml.es @@ -0,0 +1,209 @@ + + + + + + + + + + Respuestas de error personalizadas + + +

    Apache ofrece la posibilidad de que los webmasters puedan + configurar las respuestas que muestra el servidor Apache cuando se + producen algunos errores o problemas.

    + +

    Las respuestas personalizadas pueden definirse para activarse + en caso de que el servidor detecte un error o problema.

    + +

    Si un script termina de forma anormal y se produce una respuesta + "500 Server Error", esta respuesta puede ser sustituida por otro + texto de su elección o por una redirección a otra URL + (local o externa).

    +
    + +
    + Comportamiento + +
    + Comportamiento anterior + +

    NCSA httpd 1.3 devolvía mensajes antiguos del error o + problema encontrado que con frecuencia no tenían + significado alguno para el usuario, y que no incluían en + los logs información que diera pistas sobre las causas de + lo sucedido.

    +
    + +
    + Comportamiento actual + +

    Se puede hacer que el servidor siga uno de los siguientes + comportamientos:

    + +
      +
    1. Desplegar un texto diferente, en lugar de los mensajes de + la NCSA, o
    2. + +
    3. redireccionar la petición a una URL local, o
    4. + +
    5. redireccionar la petición a una URL externa.
    6. +
    + +

    Redireccionar a otra URL puede resultar de utilidad, pero + solo si con ello se puede también pasar alguna + información que pueda explicar el error o problema y/o + registrarlo en el log correspondiente más claramente.

    + +

    Para conseguir esto, Apache define ahora variables de entorno + similares a las de los CGI:

    + + + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +
    + +

    Tenga en cuenta el prefijo REDIRECT_.

    + +

    Al menos REDIRECT_URL y + REDIRECT_QUERY_STRING se pasarán a la nueva + URL (asumiendo que es un cgi-script o un cgi-include). Las otras + variables existirán solo si existían antes de aparecer + el error o problema. Ninguna de estas variables + se creará si en la directiva ErrorDocument ha especificado una + redirección externa (cualquier cosa que empiece + por un nombre de esquema del tipo http:, incluso si + se refiere al mismo servidor).

    +
    +
    + +
    + Configuración + +

    El uso de ErrorDocument + está activado para los ficheros .htaccess cuando AllowOverride tiene el valor + adecuado.

    + +

    Aquí hay algunos ejemplos más...

    + + + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +
    + +

    La sintaxis es,

    + + + ErrorDocument <3-digit-code> <action> + + +

    donde action puede ser,

    + +
      +
    1. Texto a mostrar. Ponga antes del texto que quiere que se + muestre unas comillas ("). Lo que sea que siga a las comillas se + mostrará. Nota: las comillas (") no se + muestran.
    2. + +
    3. Una URL local a la que se redireccionará la + petición.
    4. + +
    5. Una URL externa a la que se redireccionará la + petición.
    6. +
    +
    + +
    + Mesajes de error personalizados y redirecciones + +

    El comportamiento de Apache en cuanto a las redirecciones ha + cambiado para que puedan usarse más variables de entorno con + los script/server-include.

    + +
    + Antiguo comportamiento + +

    Las variables CGI estándar estaban disponibles para el + script al que se hacía la redirección. No se incluía + ninguna indicación sobre la precedencia de la + redirección.

    +
    + +
    + Nuevo comportamiento + +

    Un nuevo grupo de variables de entorno se inicializa para que + las use el script al que ha sido redireccionado. Cada + nueva variable tendrá el prefijo REDIRECT_. + Las variables de entorno REDIRECT_ se crean a + partir de de las variables de entorno CGI que existen antes de + la redirección, se les cambia el nombre + añadiéndoles el prefijo REDIRECT_, por + ejemplo, HTTP_USER_AGENT pasa a ser + REDIRECT_HTTP_USER_AGENT. Además, para esas + nuevas variables, Apache definirá REDIRECT_URL + y REDIRECT_STATUS para ayudar al script a seguir su + origen. Tanto la URL original como la URL a la que es redirigida + la petición pueden almacenarse en los logs de acceso.

    + +

    Si ErrorDocument especifica una redirección local a un + script CGI, el script debe incluir una campo de cabeceraa + "Status:" en el resultado final para asegurar que + es posible hacer llegar al cliente de vuelta la condición + de error que lo provocó. Por ejemplo, un script en Perl + para usar con ErrorDocument podría incluir lo + siguiente:

    + + + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +
    + +

    Si el script tiene como fin tratar una determinada + condición de error, por ejemplo + 404 Not Found, se pueden usar los + códigos de error y textos específicos en su lugar.

    + +

    Tenga en cuenta que el script debe incluir un campo + de cabecera Status: apropiado (como + 302 Found), si la respuesta contiene un campo de + cabecera Location: (para poder enviar una + redirección que se interprete en el cliente). De otra + manera, la cabecera + Location: puede que no tenga efecto.

    +
    +
    +
    + diff --git a/trunk/docs/manual/custom-error.xml.ja b/trunk/docs/manual/custom-error.xml.ja new file mode 100644 index 0000000000..87a96a0313 --- /dev/null +++ b/trunk/docs/manual/custom-error.xml.ja @@ -0,0 +1,186 @@ + + + + + + + + + + $B%+%9%?%`%(%i!<%l%9%]%s%9(B + + +

    $B%&%'%V%^%9%?!<$,2?$i$+$N%(%i!<$dLdBj$KBP$9$k(B + Apache $B$NH?1~$r@_Dj$G$-$k$h$&$K$9$kDI2C5!G=$rDs6!$7$^$9!#(B

    + +

    $B%5!<%P$,%(%i!<$dLdBj$rH/8+$7$?>l9g$NH?1~$r!"(B + $B%+%9%?%^%$%:$7$FDj5A$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B%9%/%j%W%H$Nl9g$NH?1~$r!"$h$j9%$^$7$$%F%-%9%H$d!"JL$N(B + URL ($BFbIt5Z$S30It(B) $B$X$N%j%@%$%l%/%7%g%s$KCV$-49$($k$3$H$,$G$-$^$9!#(B +

    +
    + +
    + $BF0:n(B + +
    + $B8E$$F0:n(B + +

    NCSA httpd 1.3 $B$O!"8E$/$FB`6~$J%(%i!<(B/$BLdBj%a%C%;!<%8$r(B + $BJV$7$F$$$^$7$?!#$=$l$O$7$P$7$P%f!<%6$K$OL50UL#$G$"$j!"(B + $B$^$?$=$l$rH/@8$5$;$?860x$r5-O?$9$kJ}K!$bDs6!$7$F$$$^$;$s$G$7$?!#(B

    +
    + +
    + $B?7$7$$F0:n(B + +
      +
    1. NCSA $B$N%O!<%I%3!<%I$5$l$?%a%C%;!<%8$NBe$o$j$K(B + $BB>$N%F%-%9%H$rI=<((B
    2. + +
    3. $B%m!<%+%k$N(B URL $B$K%j%@%$%l%/%H(B
    4. + +
    5. $B30It$N(B URL $B$K%j%@%$%l%/%H(B
    6. +
    + +

    $B$9$k$h$&$K%5!<%P$r@_Dj$G$-$^$9!#(B

    + +

    $BJL$N(B URL $B$K%j%@%$%l%/%H$9$k$3$H$OLr$KN)$A$^$9$,!"(B + $B$=$l$O@bL@$r$7$?$j!"$h$jL@3N$K8m$j(B/$BLdBj$r5-O?$7$?$j$9$k$?$a$K(B + $B2?$+>pJs$rEA$($i$l$k$H$-$K8B$j$^$9!#(B

    + +

    $B$3$l$r + + + REDIRECT_HTTP_ACCEPT=*/*, image/gif, + image/x-xbitmap, image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX + A.09.05 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +
    + +

    $BF,$KIU$/(B REDIRECT_ $B$KCmL\$7$F$/$@$5$$!#(B

    + +

    $B>/$J$/$H$b(B REDIRECT_URL $B$H(B + REDIRECT_QUERY_STRING $B$O?7$7$$(B URL (CGI $B%9%/%j%W%H$+(B + CGI $B%$%s%/%k!<%I$G$"$k$H2>Dj$5$l$^$9(B) $B$KEO$5$l$^$9!#(B + $BB>$NJQ?t$O!"%(%i!<$dLdBj$,5/$-$kA0$KB8:_$7$?>l9g$K$@$1B8:_$7$^$9!#(B + $B$b$7$"$J$?$N@_Dj$7$?(B ErrorDocument $B$,(B $B30It(B$B%j%@%$%l%/%H(B + ($B$9$J$o$A(B$B!"(Bhttp: + $B$N$h$&$JBN7OL>$+$i;O$^$k$9$Y$F$N$b$N!#$?$H$(F1$8%[%9%H$r;X$7$F$$$F$b(B) + $B$J$i$P!"$3$l$i$O(B$B$^$C$?$/(B$B@_Dj$5$l$^$;$s!#(B

    +
    +
    + +
    + $B@_Dj(B + +

    AllowOverride $B$,E,@Z$K@_Dj$5$l$F$$$l$P!"(B + .htaccess $B%U%!%$%k$G(B ErrorDocument + $B$r;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$3$K!"$$$/$D$+$NNc$r5s$2$^$9!#(B

    + + + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +
    + +

    $B9=J8(B

    + + + ErrorDocument <3-digit-code> <action> + + +

    action ($BF0:n(B) $B$O!"(B

    + +
      +
    1. $BI=<($5$l$k$Y$-%F%-%9%H!#%F%-%9%H$K$O0zMQId(B (") $B$r$D$1$^$9!#(B + $B0zMQId$N8e$KB3$/$b$N$,2?$G$bI=<($5$l$^$9!#(B + $BCm0U(B : (") $B$OI=<($5$l$^$;$s(B
    2. + +
    3. $B%j%@%$%l%/%H@h$N30It(B URL
    4. + +
    5. $B%j%@%$%l%/%H@h$N%m!<%+%k(B URL
    6. +
    +
    + +
    + $B%+%9%?%`%(%i!<%l%9%]%s%9$H%j%@%$%l%/%H(B + +

    $B%9%/%j%W%H(B/SSI $B$KDI2C$N4D6-JQ?t$,MxMQ2DG=$K$J$k$h$&$K!"(B + $B%j%@%$%l%/%H$5$l$?(B URL $B$KBP$9$k(B Apache $B$NF0:n$,JQ99$5$l$^$7$?!#(B

    + +
    + $B8E$$F0:n(B + +

    $B%j%@%$%l%/%H$5$l$?%9%/%j%W%H$OI8=`$N(B CGI + $B4D6-JQ?t$rMxMQ2DG=$G$7$?!#$7$+$7!"$I$3$+$i%j%@%$%l%/%H(B + $B$5$l$?$+$N>pJs$ODs6!$5$l$F$$$^$;$s$G$7$?!#(B

    +
    + +
    + $B?7$7$$F0:n(B + +

    $B%j%@%$%l%/%H$5$l$?@h$N%9%/%j%W%H$,;HMQ2DG=$J$h$&$K!"(B + $B?7$7$$$?$/$5$s$N4D6-JQ?t$,=i4|2=$5$l$^$9!#?7$7$$JQ?t$O!"$=$l$>$l(B + REDIRECT_ $B$G;O$^$j$^$9!#(B + REDIRECT_ $B$G;O$^$k4D6-JQ?t$O%j%@%$%l%/%H$5$l$kA0$KB8:_$7$F$$$?(B + CGI $B4D6-JQ?t$NF,$K(B REDIRECT_ $B$rIU$1$F:n@.$5$l$^$9!#(B + $B$9$J$o$A(B$B!"(BHTTP_USER_AGENT $B$O(B + REDIRECT_HTTP_USER_AGENT $B$K$J$j$^$9!#(B + $B$3$l$i$N?7$7$$JQ?t$K2C$($F!"(BApache $B$O!"(B + $B%9%/%j%W%H$,%j%@%$%l%/%H85$N%H%l!<%9$r=u$1$k$?$a$K(B + REDIRECT_URL $B$H(B REDIRECT_STATUS + $B$rDj5A$7$^$9!#%"%/%;%9%m%0$K$O85$N(B URL $B$H%j%@%$%l%/%H$5$l$?(B URL + $B$NN>J}$,5-O?$5$l$^$9!#(B

    + +

    ErrorDocument $B$,(B CGI $B%9%/%j%W%H$X$N%m!<%+%k%j%@%$%l%/%H$r(B + $B;XDj$7$F$$$k>l9g$O!"$=$l$r5/F0$9$k$3$H$K$J$C$?%(%i!<$N>uBV$r(B + $B%/%i%$%"%s%H$^$G3N"Status:" + $B%X%C%@$r4^$`$Y$-$G$9!#Nc$($P!"(BErrorDocument $BMQ$N(B Perl + $B%9%/%j%W%H$O0J2<$N$h$&$J$b$N$r4^$`$+$b$7$l$^$;$s!#(B +

    + + + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +
    + +

    $B%9%/%j%W%H$,(B 404 Not Found $B$N$h$&$J(B + $BFCDj$N%(%i!<%3%s%G%#%7%g%s$r07$&$?$a$@$1$K;H$o$l$k>l9g$O!"(B + $BBe$o$j$KFCDj$N%3!<%I$H%(%i!<%F%-%9%H$r;HMQ$9$k$3$H$,$G$-$^$9!#(B

    +
    +
    +
    diff --git a/trunk/docs/manual/custom-error.xml.ko b/trunk/docs/manual/custom-error.xml.ko new file mode 100644 index 0000000000..04dbfcf48d --- /dev/null +++ b/trunk/docs/manual/custom-error.xml.ko @@ -0,0 +1,186 @@ + + + + + + + + + + »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä + + +

    À¥¸¶½ºÅÍ´Â ¿À·ù³ª ¹®Á¦°¡ ¹ß»ýÇßÀ»¶§ ¾ÆÆÄÄ¡ÀÇ ÀÀ´äÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼­¹ö°¡ ¿À·ù³ª ¹®Á¦¸¦ ¹ß°ßÇßÀ»¶§ º¸³¾ »ç¿ëÀÚÁ¤ÀÇ ÀÀ´äÀ» + Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.

    + +

    ½ºÅ©¸³Æ®°¡ Á×Àº °æ¿ì "500 Server Error" ÀÀ´ä ´ë½Å »ç¿ëÀÚ¿¡°Ô + ´õ Ä£±ÙÇÑ ¹®±¸¸¦ »ç¿ëÇϰųª ´Ù¸¥ (°°Àº »çÀÌÆ®³ª ¿ÜºÎ »çÀÌÆ®ÀÇ) + URL·Î ¸®´ÙÀÌ·º¼ÇÀ» ÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    + Çൿ + +
    + ÀÌÀü Çൿ + +

    NCSA httpd 1.3Àº »ç¿ëÀÚ¿¡°Ô ¹«ÀǹÌÇÏ°í Áö·çÇÑ ¿À·ù¹®À» + º¸³Â´Ù. ¹®Á¦°¡ ¹ß»ýÇÑ ÀÌÀ¯¸¦ ·Î±×¿¡ ³²±æ ¼öµµ ¾ø¾ú´Ù.

    +
    + +
    + »õ·Î¿î Çൿ + +

    ¼­¹ö´Â ´ÙÀ½°ú °°Àº ÀÏÀ» ÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    1. NCSAÀÇ °íÁ¤µÈ ¹®±¸ ´ë½Å ´Ù¸¥ ¹®±¸¸¦ º¸¿©Áְųª
    2. + +
    3. °°Àº »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇϰųª
    4. + +
    5. ¿ÜºÎ »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    6. +
    + +

    ´Ù¸¥ »çÀÌÆ®ÀÇ URL·Î ¸®´ÙÀÌ·º¼ÇÇÏ´Â °ÍÀÌ À¯¿ëÇÒ ¼ö ÀÖÁö¸¸, + ÀÌ °æ¿ì ¹®Á¦¸¦ ¼³¸íÇϰųª ·Î±×Çϴµ¥ ÇÊ¿äÇÑ Á¤º¸Áß ÀϺθ¸ + Àü´ÞµÈ´Ù.

    + +

    ¿À·ù¿¡ ´ëÇÑ Á¤º¸¸¦ Àü´ÞÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â CGI½ÄÀÇ »õ·Î¿î + ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù:

    + + + REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, + image/jpeg
    + REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.05 + 9000/712)
    + REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
    + REDIRECT_QUERY_STRING=
    + REDIRECT_REMOTE_ADDR=121.345.78.123
    + REDIRECT_REMOTE_HOST=ooh.ahhh.com
    + REDIRECT_SERVER_NAME=crash.bang.edu
    + REDIRECT_SERVER_PORT=80
    + REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
    + REDIRECT_URL=/cgi-bin/buggy.pl +
    + +

    REDIRECT_ Á¢µÎ»ç¿¡ ÁÖ¸ñÇ϶ó.

    + +

    ÃÖ¼ÒÇÑ REDIRECT_URL°ú + REDIRECT_QUERY_STRINGÀº (cgi-script³ª + cgi-includeÀÏ) »õ URL·Î ³Ñ°ÜÁø´Ù. ´Ù¸¥ º¯¼ö´Â ¿À·ù°¡ + ¹ß»ýÇϱâ ÀÌÀü¿¡ À̸§¿¡¼­ REDIRECT_¸¦ + »« ȯ°æº¯¼ö°¡ Á¸ÀçÇÑ °æ¿ì¿¡¸¸ ÀÖ´Ù. + ErrorDocument°¡ + ¿ÜºÎ·Î (°°Àº ¼­¹ö¶óµµ http:¿Í + °°Àº ½ºÅ´(scheme)À¸·Î ½ÃÀÛÇÑ´Ù¸é) ¸®´ÙÀÌ·º¼ÇÇÑ´Ù¸é + ÀÌÁß ¾î¶² °Íµµ ¼³Á¤µÇÁö ¾Ê´Â´Ù.

    +
    +
    + +
    + ¼³Á¤ + +

    AllowOverride°¡ + ÀûÀýÈ÷ ¼³Á¤µÇ¾ú´Ù¸é .htaccess ÆÄÀÏ¿¡¼­ + ErrorDocument¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù.

    + +

    ´ÙÀ½Àº ¿¹ÀÌ´Ù...

    + + + ErrorDocument 500 /cgi-bin/crash-recover
    + ErrorDocument 500 "Sorry, our script crashed. Oh dear"
    + ErrorDocument 500 http://xxx/
    + ErrorDocument 404 /Lame_excuses/not_found.html
    + ErrorDocument 401 /Subscription/how_to_subscribe.html +
    + +

    ¹®¹ýÀº,

    + + + ErrorDocument <3-digit-code> <action> + + +

    °¡´ÉÇÑ actionÀº,

    + +
      +
    1. Ãâ·ÂÇÒ ¹®±¸. µû¿ÈÇ¥ (")¸¦ ¹®±¸ ¾Õ¿¡ ºÙÀδÙ. µÚ¿¡ ³ª¿À´Â + µû¿ÈÇ¥´Â Ãâ·ÂµÈ´Ù. ÁÖÀÇ: ¾Õ¿¡ ºÙÀº µû¿ÈÇ¥ (")´Â Ãâ·ÂµÇÁö + ¾Ê´Â´Ù.
    2. + +
    3. ¸®´ÙÀÌ·º¼ÇÇÒ ¿ÜºÎ URL.
    4. + +
    5. ¸®´ÙÀÌ·º¼ÇÇÒ ³»ºÎ URL.
    6. +
    +
    + +
    + »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä°ú ¸®´ÙÀÌ·º¼Ç + +

    URL·Î ¸®´ÙÀÌ·º¼ÇÇÏ´Â ¾ÆÆÄÄ¡ ÇൿÀº + ½ºÅ©¸³Æ®/server-include¿¡ ȯ°æº¯¼ö¸¦ ´õ ³Ñ°ÜÁÖµµ·Ï º¯°æµÇ¾ú´Ù.

    + +
    + ÀÌÀü Çൿ + +

    ¸®´ÙÀÌ·º¼ÇµÇ´Â ½ºÅ©¸³Æ®¿¡ Ç¥ÁØ CGI º¯¼öµéÀÌ ³Ñ¾î°£´Ù. + ¾îµð¿¡¼­ ¸®´ÙÀÌ·º¼ÇÀÌ ÀϾ´ÂÁö ¾Ë ¼ö ¾ø´Ù.

    +
    + +
    + »õ·Î¿î Çൿ + +

    ¸®´ÙÀÌ·º¼ÇµÈ ½ºÅ©¸³Æ®´Â »õ·Î¿î ȯ°æº¯¼öµéÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù. ¸ðµÎ ¾Õ¿¡ REDIRECT_°¡ ºÙ¾îÀÖ´Ù. + REDIRECT_ ȯ°æº¯¼ö´Â ¿ø·¡ CGI ȯ°æº¯¼ö¸í + ¾Õ¿¡ REDIRECT_¸¦ ºÙ¿©¼­ ¸¸µç´Ù. ¿¹¸¦ + µé¾î, HTTP_USER_AGENT´Â + REDIRECT_HTTP_USER_AGENT°¡ µÇ¾ú´Ù. ÀÌ·± º¯¼ö¿¡ + Ãß°¡·Î ½ºÅ©¸³Æ®°¡ ¿ø·¡ URLÀ» ¾Ëµµ·Ï ¾ÆÆÄÄ¡´Â + REDIRECT_URL°ú REDIRECT_STATUS¸¦ + Á¤ÀÇÇÑ´Ù. ¿ø·¡ URL°ú ¸®´ÙÀÌ·º¼ÇµÈ URL ¸ðµÎ Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +

    ErrorDocument°¡ °°Àº ¼­¹ö¿¡ ÀÖ´Â CGI ½ºÅ©¸³Æ®·Î + ¸®´ÙÀÌ·º¼ÇÇÑ´Ù¸é, ½ºÅ©¸³Æ®´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¿À·ù »óȲÀ» + È®½ÇÈ÷ Àü´ÞÇϱâÀ§ÇØ Ãâ·Â¿¡ "Status:" Çì´õ + Çʵ带 Æ÷ÇÔÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, Perl·Î ÀÛ¼ºÇÑ ErrorDocument + ½ºÅ©¸³Æ®´Â ´ÙÀ½°ú °°´Ù:

    + + + ...
    + print "Content-type: text/html\n";
    + printf "Status: %s Condition Intercepted\n", $ENV{"REDIRECT_STATUS"};
    + ... +
    + +

    404 Not Found¿Í °°Àº ƯÁ¤ ¿À·ù + »óȲ¿¡ ´ëÇÑ ½ºÅ©¸³Æ®¶ó¸é, ´ë½Å °íÁ¤µÈ + ƯÁ¤ »óÅÂÄÚµå¿Í ¿À·ù¹®À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    (Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» ¿äûÇϱâÀ§ÇØ) ÀÀ´ä¿¡ + Location: Çì´õ¸¦ Æ÷ÇÔÇÑ´Ù¸é, ½ºÅ©¸³Æ®´Â + ¹Ýµå½Ã (302 Found °°Àº) ÀûÀýÇÑ + Status: Çì´õ¸¦ Ãâ·ÂÇØ¾ß ÇÔÀ» ÁÖÀÇÇ϶ó. ±×·¸Áö¾ÊÀ¸¸é + Location: Çì´õ°¡ ¾Æ¹« ¼Ò¿ë¾ø°Ô µÉ ¼ö ÀÖ´Ù.

    +
    +
    +
    diff --git a/trunk/docs/manual/custom-error.xml.meta b/trunk/docs/manual/custom-error.xml.meta new file mode 100644 index 0000000000..cd88703fca --- /dev/null +++ b/trunk/docs/manual/custom-error.xml.meta @@ -0,0 +1,14 @@ + + + + custom-error + / + . + + + en + es + ja + ko + + diff --git a/trunk/docs/manual/developer/API.html b/trunk/docs/manual/developer/API.html new file mode 100644 index 0000000000..a8a3c492a4 --- /dev/null +++ b/trunk/docs/manual/developer/API.html @@ -0,0 +1,3 @@ +URI: API.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/API.html.en b/trunk/docs/manual/developer/API.html.en new file mode 100644 index 0000000000..a09a5f2f52 --- /dev/null +++ b/trunk/docs/manual/developer/API.html.en @@ -0,0 +1,1222 @@ + + + +Apache 1.3 API notes - Apache HTTP Server + + + + + +
    <-
    +

    Apache 1.3 API notes

    +
    +

    Available Languages:  en 

    +
    + +

    Warning

    +

    This document has not been updated to take into account changes made + in the 2.0 version of the Apache HTTP Server. Some of the information may + still be relevant, but please use it with care.

    +
    + +

    These are some notes on the Apache API and the data structures you have + to deal with, etc. They are not yet nearly complete, but hopefully, + they will help you get your bearings. Keep in mind that the API is still + subject to change as we gain experience with it. (See the TODO file for + what might be coming). However, it will be easy to adapt modules + to any changes that are made. (We have more modules to adapt than you + do).

    + +

    A few notes on general pedagogical style here. In the interest of + conciseness, all structure declarations here are incomplete -- the real + ones have more slots that I'm not telling you about. For the most part, + these are reserved to one component of the server core or another, and + should be altered by modules with caution. However, in some cases, they + really are things I just haven't gotten around to yet. Welcome to the + bleeding edge.

    + +

    Finally, here's an outline, to give you some bare idea of what's coming + up, and in what order:

    + + +
    + +
    top
    +
    +

    Basic concepts

    +

    We begin with an overview of the basic concepts behind the API, and how + they are manifested in the code.

    + +

    Handlers, Modules, and Requests

    +

    Apache breaks down request handling into a series of steps, more or + less the same way the Netscape server API does (although this API has a + few more stages than NetSite does, as hooks for stuff I thought might be + useful in the future). These are:

    + +
      +
    • URI -> Filename translation
    • +
    • Auth ID checking [is the user who they say they are?]
    • +
    • Auth access checking [is the user authorized here?]
    • +
    • Access checking other than auth
    • +
    • Determining MIME type of the object requested
    • +
    • `Fixups' -- there aren't any of these yet, but the phase is intended + as a hook for possible extensions like SetEnv, which don't really fit well elsewhere.
    • +
    • Actually sending a response back to the client.
    • +
    • Logging the request
    • +
    + +

    These phases are handled by looking at each of a succession of + modules, looking to see if each of them has a handler for the + phase, and attempting invoking it if so. The handler can typically do one + of three things:

    + +
      +
    • Handle the request, and indicate that it has done so by + returning the magic constant OK.
    • + +
    • Decline to handle the request, by returning the magic integer + constant DECLINED. In this case, the server behaves in all + respects as if the handler simply hadn't been there.
    • + +
    • Signal an error, by returning one of the HTTP error codes. This + terminates normal handling of the request, although an ErrorDocument may + be invoked to try to mop up, and it will be logged in any case.
    • +
    + +

    Most phases are terminated by the first module that handles them; + however, for logging, `fixups', and non-access authentication checking, + all handlers always run (barring an error). Also, the response phase is + unique in that modules may declare multiple handlers for it, via a + dispatch table keyed on the MIME type of the requested object. Modules may + declare a response-phase handler which can handle any request, + by giving it the key */* (i.e., a wildcard MIME type + specification). However, wildcard handlers are only invoked if the server + has already tried and failed to find a more specific response handler for + the MIME type of the requested object (either none existed, or they all + declined).

    + +

    The handlers themselves are functions of one argument (a + request_rec structure. vide infra), which returns an integer, + as above.

    + + +

    A brief tour of a module

    +

    At this point, we need to explain the structure of a module. Our + candidate will be one of the messier ones, the CGI module -- this handles + both CGI scripts and the ScriptAlias config file command. It's actually a great deal + more complicated than most modules, but if we're going to have only one + example, it might as well be the one with its fingers in every place.

    + +

    Let's begin with handlers. In order to handle the CGI scripts, the + module declares a response handler for them. Because of ScriptAlias, it also has handlers for the + name translation phase (to recognize ScriptAliased URIs), the type-checking phase (any + ScriptAliased request is typed + as a CGI script).

    + +

    The module needs to maintain some per (virtual) server information, + namely, the ScriptAliases in + effect; the module structure therefore contains pointers to a functions + which builds these structures, and to another which combines two of them + (in case the main server and a virtual server both have ScriptAliases declared).

    + +

    Finally, this module contains code to handle the ScriptAlias command itself. This particular + module only declares one command, but there could be more, so modules have + command tables which declare their commands, and describe where + they are permitted, and how they are to be invoked.

    + +

    A final note on the declared types of the arguments of some of these + commands: a pool is a pointer to a resource pool + structure; these are used by the server to keep track of the memory which + has been allocated, files opened, etc., either to service a + particular request, or to handle the process of configuring itself. That + way, when the request is over (or, for the configuration pool, when the + server is restarting), the memory can be freed, and the files closed, + en masse, without anyone having to write explicit code to track + them all down and dispose of them. Also, a cmd_parms + structure contains various information about the config file being read, + and other status information, which is sometimes of use to the function + which processes a config-file command (such as ScriptAlias). With no further ado, the + module itself:

    + +

    + /* Declarations of handlers. */
    +
    + int translate_scriptalias (request_rec *);
    + int type_scriptalias (request_rec *);
    + int cgi_handler (request_rec *);
    +
    + /* Subsidiary dispatch table for response-phase
    +  * handlers, by MIME type */
    +
    + handler_rec cgi_handlers[] = {
    + + { "application/x-httpd-cgi", cgi_handler },
    + { NULL }
    +
    + };
    +
    + /* Declarations of routines to manipulate the
    +  * module's configuration info. Note that these are
    +  * returned, and passed in, as void *'s; the server
    +  * core keeps track of them, but it doesn't, and can't,
    +  * know their internal structure.
    +  */
    +
    + void *make_cgi_server_config (pool *);
    + void *merge_cgi_server_config (pool *, void *, void *);
    +
    + /* Declarations of routines to handle config-file commands */
    +
    + extern char *script_alias(cmd_parms *, void *per_dir_config, char *fake, + char *real);
    +
    + command_rec cgi_cmds[] = {
    + + { "ScriptAlias", script_alias, NULL, RSRC_CONF, TAKE2,
    + "a fakename and a realname"},
    + { NULL }
    +
    + };
    +
    + module cgi_module = { +

      STANDARD_MODULE_STUFF,
    +  NULL,                     /* initializer */
    +  NULL,                     /* dir config creator */
    +  NULL,                     /* dir merger */
    +  make_cgi_server_config,   /* server config */
    +  merge_cgi_server_config,  /* merge server config */
    +  cgi_cmds,                 /* command table */
    +  cgi_handlers,             /* handlers */
    +  translate_scriptalias,    /* filename translation */
    +  NULL,                     /* check_user_id */
    +  NULL,                     /* check auth */
    +  NULL,                     /* check access */
    +  type_scriptalias,         /* type_checker */
    +  NULL,                     /* fixups */
    +  NULL,                     /* logger */
    +  NULL                      /* header parser */
    +};
    + +
    top
    +
    +

    How handlers work

    +

    The sole argument to handlers is a request_rec structure. + This structure describes a particular request which has been made to the + server, on behalf of a client. In most cases, each connection to the + client generates only one request_rec structure.

    + +

    A brief tour of the request_rec

    +

    The request_rec contains pointers to a resource pool + which will be cleared when the server is finished handling the request; + to structures containing per-server and per-connection information, and + most importantly, information on the request itself.

    + +

    The most important such information is a small set of character strings + describing attributes of the object being requested, including its URI, + filename, content-type and content-encoding (these being filled in by the + translation and type-check handlers which handle the request, + respectively).

    + +

    Other commonly used data items are tables giving the MIME headers on + the client's original request, MIME headers to be sent back with the + response (which modules can add to at will), and environment variables for + any subprocesses which are spawned off in the course of servicing the + request. These tables are manipulated using the ap_table_get + and ap_table_set routines.

    + +
    +

    Note that the Content-type header value cannot + be set by module content-handlers using the ap_table_*() + routines. Rather, it is set by pointing the content_type + field in the request_rec structure to an appropriate + string. e.g.,

    +

    + r->content_type = "text/html"; +

    +
    + +

    Finally, there are pointers to two data structures which, in turn, + point to per-module configuration structures. Specifically, these hold + pointers to the data structures which the module has built to describe + the way it has been configured to operate in a given directory (via + .htaccess files or <Directory> sections), for private data it has built in the + course of servicing the request (so modules' handlers for one phase can + pass `notes' to their handlers for other phases). There is another such + configuration vector in the server_rec data structure pointed + to by the request_rec, which contains per (virtual) server + configuration data.

    + +

    Here is an abridged declaration, giving the fields most commonly + used:

    + +

    + struct request_rec {
    +
    + pool *pool;
    + conn_rec *connection;
    + server_rec *server;
    +
    + /* What object is being requested */
    +
    + char *uri;
    + char *filename;
    + char *path_info; +

    char *args;           /* QUERY_ARGS, if any */
    +struct stat finfo;    /* Set by server core;
    +                       * st_mode set to zero if no such file */

    + char *content_type;
    + char *content_encoding;
    +
    + /* MIME header environments, in and out. Also,
    +  * an array containing environment variables to
    +  * be passed to subprocesses, so people can write
    +  * modules to add to that environment.
    +  *
    +  * The difference between headers_out and
    +  * err_headers_out is that the latter are printed
    +  * even on error, and persist across internal
    +  * redirects (so the headers printed for
    +  * ErrorDocument handlers will have + them).
    +  */
    +
    + table *headers_in;
    + table *headers_out;
    + table *err_headers_out;
    + table *subprocess_env;
    +
    + /* Info about the request itself... */
    +
    +

    int header_only;     /* HEAD request, as opposed to GET */
    +char *protocol;      /* Protocol, as given to us, or HTTP/0.9 */
    +char *method;        /* GET, HEAD, POST, etc. */
    +int method_number;   /* M_GET, M_POST, etc. */
    +
    +

    + /* Info for logging */
    +
    + char *the_request;
    + int bytes_sent;
    +
    + /* A flag which modules can set, to indicate that
    +  * the data being returned is volatile, and clients
    +  * should be told not to cache it.
    +  */
    +
    + int no_cache;
    +
    + /* Various other config info which may change
    +  * with .htaccess files
    +  * These are config vectors, with one void*
    +  * pointer for each module (the thing pointed
    +  * to being the module's business).
    +  */
    +
    +

    void *per_dir_config;   /* Options set in config files, etc. */
    +void *request_config;   /* Notes on *this* request */

    +
    + }; +

    + + +

    Where request_rec structures come from

    +

    Most request_rec structures are built by reading an HTTP + request from a client, and filling in the fields. However, there are a + few exceptions:

    + +
      +
    • If the request is to an imagemap, a type map (i.e., a + *.var file), or a CGI script which returned a local + `Location:', then the resource which the user requested is going to be + ultimately located by some URI other than what the client originally + supplied. In this case, the server does an internal redirect, + constructing a new request_rec for the new URI, and + processing it almost exactly as if the client had requested the new URI + directly.
    • + +
    • If some handler signaled an error, and an ErrorDocument + is in scope, the same internal redirect machinery comes into play.
    • + +
    • Finally, a handler occasionally needs to investigate `what would + happen if' some other request were run. For instance, the directory + indexing module needs to know what MIME type would be assigned to a + request for each directory entry, in order to figure out what icon to + use.

      + +

      Such handlers can construct a sub-request, using the + functions ap_sub_req_lookup_file, + ap_sub_req_lookup_uri, and ap_sub_req_method_uri; + these construct a new request_rec 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 checks if the + sub-request is for a file in the same directory as the original + request).

      + +

      (Server-side includes work by building sub-requests and then actually + invoking the response handler for them, via the function + ap_run_sub_req).

      +
    • +
    + + +

    Handling requests, declining, and returning + error codes

    +

    As discussed above, each handler, when invoked to handle a particular + request_rec, has to return an int to indicate + what happened. That can either be

    + +
      +
    • OK -- the request was handled successfully. This may or + may not terminate the phase.
    • + +
    • DECLINED -- no erroneous condition exists, but the module + declines to handle the phase; the server tries to find another.
    • + +
    • an HTTP error code, which aborts handling of the request.
    • +
    + +

    Note that if the error code returned is REDIRECT, then + the module should put a Location in the request's + headers_out, to indicate where the client should be + redirected to.

    + + +

    Special considerations for response + handlers

    +

    Handlers for most phases do their work by simply setting a few fields + in the request_rec structure (or, in the case of access + checkers, simply by returning the correct error code). However, response + handlers have to actually send a request back to the client.

    + +

    They should begin by sending an HTTP response header, using the + function ap_send_http_header. (You don't have to do anything + special to skip sending the header for HTTP/0.9 requests; the function + figures out on its own that it shouldn't do anything). If the request is + marked header_only, that's all they should do; they should + return after that, without attempting any further output.

    + +

    Otherwise, they should produce a request body which responds to the + client as appropriate. The primitives for this are ap_rputc + and ap_rprintf, for internally generated output, and + ap_send_fd, to copy the contents of some FILE * + straight to the client.

    + +

    At this point, you should more or less understand the following piece + of code, which is the handler which handles GET requests + which have no more specific handler; it also shows how conditional + GETs can be handled, if it's desirable to do so in a + particular response handler -- ap_set_last_modified checks + against the If-modified-since value supplied by the client, + if any, and returns an appropriate code (which will, if nonzero, be + USE_LOCAL_COPY). No similar considerations apply for + ap_set_content_length, but it returns an error code for + symmetry.

    + +

    + int default_handler (request_rec *r)
    + {
    + + int errstatus;
    + FILE *f;
    +
    + if (r->method_number != M_GET) return DECLINED;
    + if (r->finfo.st_mode == 0) return NOT_FOUND;
    +
    + if ((errstatus = ap_set_content_length (r, r->finfo.st_size))
    +     || + (errstatus = ap_set_last_modified (r, r->finfo.st_mtime)))
    + return errstatus;
    +
    + f = fopen (r->filename, "r");
    +
    + if (f == NULL) {
    + + log_reason("file permissions deny server access", r->filename, r);
    + return FORBIDDEN;
    +
    + }
    +
    + register_timeout ("send", r);
    + ap_send_http_header (r);
    +
    + if (!r->header_only) send_fd (f, r);
    + ap_pfclose (r->pool, f);
    + return OK;
    +
    + } +

    + +

    Finally, if all of this is too much of a challenge, there are a few + ways out of it. First off, as shown above, a response handler which has + not yet produced any output can simply return an error code, in which + case the server will automatically produce an error response. Secondly, + it can punt to some other handler by invoking + ap_internal_redirect, which is how the internal redirection + machinery discussed above is invoked. A response handler which has + internally redirected should always return OK.

    + +

    (Invoking ap_internal_redirect from handlers which are + not response handlers will lead to serious confusion).

    + + +

    Special considerations for authentication + handlers

    +

    Stuff that should be discussed here in detail:

    + +
      +
    • Authentication-phase handlers not invoked unless auth is + configured for the directory.
    • + +
    • Common auth configuration stored in the core per-dir + configuration; it has accessors ap_auth_type, + ap_auth_name, and ap_requires.
    • + +
    • Common routines, to handle the protocol end of things, at + least for HTTP basic authentication + (ap_get_basic_auth_pw, which sets the + connection->user structure field + automatically, and ap_note_basic_auth_failure, + which arranges for the proper WWW-Authenticate: + header to be sent back).
    • +
    + + +

    Special considerations for logging + handlers

    +

    When a request has internally redirected, there is the question of + what to log. Apache handles this by bundling the entire chain of redirects + into a list of request_rec structures which are threaded + through the r->prev and r->next pointers. + The request_rec which is passed to the logging handlers in + such cases is the one which was originally built for the initial request + from the client; note that the bytes_sent field will only be + correct in the last request in the chain (the one for which a response was + actually sent).

    + +
    top
    +
    +

    Resource allocation and resource pools

    +

    One of the problems of writing and designing a server-pool server is + that of preventing leakage, that is, allocating resources (memory, open + files, etc.), without subsequently releasing them. The resource + pool machinery is designed to make it easy to prevent this from happening, + by allowing resource to be allocated in such a way that they are + automatically released when the server is done with them.

    + +

    The way this works is as follows: the memory which is allocated, file + opened, etc., to deal with a particular request are tied to a + resource pool which is allocated for the request. The pool is a + data structure which itself tracks the resources in question.

    + +

    When the request has been processed, the pool is cleared. At + that point, all the memory associated with it is released for reuse, all + files associated with it are closed, and any other clean-up functions which + are associated with the pool are run. When this is over, we can be confident + that all the resource tied to the pool have been released, and that none of + them have leaked.

    + +

    Server restarts, and allocation of memory and resources for per-server + configuration, are handled in a similar way. There is a configuration + pool, which keeps track of resources which were allocated while reading + the server configuration files, and handling the commands therein (for + instance, the memory that was allocated for per-server module configuration, + log files and other files that were opened, and so forth). When the server + restarts, and has to reread the configuration files, the configuration pool + is cleared, and so the memory and file descriptors which were taken up by + reading them the last time are made available for reuse.

    + +

    It should be noted that use of the pool machinery isn't generally + obligatory, except for situations like logging handlers, where you really + need to register cleanups to make sure that the log file gets closed when + the server restarts (this is most easily done by using the function ap_pfopen, which also arranges for the + underlying file descriptor to be closed before any child processes, such as + for CGI scripts, are execed), or in case you are using the + timeout machinery (which isn't yet even documented here). However, there are + two benefits to using it: resources allocated to a pool never leak (even if + you allocate a scratch string, and just forget about it); also, for memory + allocation, ap_palloc is generally faster than + malloc.

    + +

    We begin here by describing how memory is allocated to pools, and then + discuss how other resources are tracked by the resource pool machinery.

    + +

    Allocation of memory in pools

    +

    Memory is allocated to pools by calling the function + ap_palloc, which takes two arguments, one being a pointer to + a resource pool structure, and the other being the amount of memory to + allocate (in chars). Within handlers for handling requests, + the most common way of getting a resource pool structure is by looking at + the pool slot of the relevant request_rec; hence + the repeated appearance of the following idiom in module code:

    + +

    + int my_handler(request_rec *r)
    + {
    + + struct my_structure *foo;
    + ...
    +
    + foo = (foo *)ap_palloc (r->pool, sizeof(my_structure));
    +
    + } +

    + +

    Note that there is no ap_pfree -- + ap_palloced memory is freed only when the associated resource + pool is cleared. This means that ap_palloc does not have to + do as much accounting as malloc(); all it does in the typical + case is to round up the size, bump a pointer, and do a range check.

    + +

    (It also raises the possibility that heavy use of + ap_palloc could cause a server process to grow excessively + large. There are two ways to deal with this, which are dealt with below; + briefly, you can use malloc, and try to be sure that all of + the memory gets explicitly freed, or you can allocate a + sub-pool of the main pool, allocate your memory in the sub-pool, and clear + it out periodically. The latter technique is discussed in the section + on sub-pools below, and is used in the directory-indexing code, in order + to avoid excessive storage allocation when listing directories with + thousands of files).

    + + +

    Allocating initialized memory

    +

    There are functions which allocate initialized memory, and are + frequently useful. The function ap_pcalloc has the same + interface as ap_palloc, but clears out the memory it + allocates before it returns it. The function ap_pstrdup + takes a resource pool and a char * as arguments, and + allocates memory for a copy of the string the pointer points to, returning + a pointer to the copy. Finally ap_pstrcat is a varargs-style + function, which takes a pointer to a resource pool, and at least two + char * arguments, the last of which must be + NULL. It allocates enough memory to fit copies of each of + the strings, as a unit; for instance:

    + +

    + ap_pstrcat (r->pool, "foo", "/", "bar", NULL); +

    + +

    returns a pointer to 8 bytes worth of memory, initialized to + "foo/bar".

    + + +

    Commonly-used pools in the Apache Web + server

    +

    A pool is really defined by its lifetime more than anything else. + There are some static pools in http_main which are passed to various + non-http_main functions as arguments at opportune times. Here they + are:

    + +
    +
    permanent_pool
    +
    never passed to anything else, this is the ancestor of all pools
    + +
    pconf
    +
    +
      +
    • subpool of permanent_pool
    • + +
    • created at the beginning of a config "cycle"; exists + until the server is terminated or restarts; passed to all + config-time routines, either via cmd->pool, or as the + "pool *p" argument on those which don't take pools
    • + +
    • passed to the module init() functions
    • +
    +
    + +
    ptemp
    +
    +
      +
    • sorry I lie, this pool isn't called this currently in + 1.3, I renamed it this in my pthreads development. I'm + referring to the use of ptrans in the parent... contrast + this with the later definition of ptrans in the + child.
    • + +
    • subpool of permanent_pool
    • + +
    • created at the beginning of a config "cycle"; exists + until the end of config parsing; passed to config-time + routines via cmd->temp_pool. Somewhat of a + "bastard child" because it isn't available everywhere. + Used for temporary scratch space which may be needed by + some config routines but which is deleted at the end of + config.
    • +
    +
    + +
    pchild
    +
    +
      +
    • subpool of permanent_pool
    • + +
    • created when a child is spawned (or a thread is + created); lives until that child (thread) is + destroyed
    • + +
    • passed to the module child_init functions
    • + +
    • destruction happens right after the child_exit + functions are called... (which may explain why I think + child_exit is redundant and unneeded)
    • +
    +
    + +
    ptrans
    +
    +
      +
    • should be a subpool of pchild, but currently is a + subpool of permanent_pool, see above
    • + +
    • cleared by the child before going into the accept() + loop to receive a connection
    • + +
    • used as connection->pool
    • +
    +
    + +
    r->pool
    +
    +
      +
    • for the main request this is a subpool of + connection->pool; for subrequests it is a subpool of + the parent request's pool.
    • + +
    • exists until the end of the request (i.e., + ap_destroy_sub_req, or in child_main after + process_request has finished)
    • + +
    • note that r itself is allocated from r->pool; + i.e., r->pool is first created and then r is + the first thing palloc()d from it
    • +
    +
    +
    + +

    For almost everything folks do, r->pool is the pool to + use. But you can see how other lifetimes, such as pchild, are useful to + some modules... such as modules that need to open a database connection + once per child, and wish to clean it up when the child dies.

    + +

    You can also see how some bugs have manifested themself, such as + setting connection->user to a value from + r->pool -- in this case connection exists for the + lifetime of ptrans, which is longer than + r->pool (especially if r->pool is a + subrequest!). So the correct thing to do is to allocate from + connection->pool.

    + +

    And there was another interesting bug in mod_include + / mod_cgi. You'll see in those that they do this test + to decide if they should use r->pool or + r->main->pool. In this case the resource that they are + registering for cleanup is a child process. If it were registered in + r->pool, then the code would wait() for the + child when the subrequest finishes. With mod_include this + could be any old #include, and the delay can be up to 3 + seconds... and happened quite frequently. Instead the subprocess is + registered in r->main->pool which causes it to be + cleaned up when the entire request is done -- i.e., after the + output has been sent to the client and logging has happened.

    + + +

    Tracking open files, etc.

    +

    As indicated above, resource pools are also used to track other sorts + of resources besides memory. The most common are open files. The routine + which is typically used for this is ap_pfopen, which takes a + resource pool and two strings as arguments; the strings are the same as + the typical arguments to fopen, e.g.,

    + +

    + ...
    + FILE *f = ap_pfopen (r->pool, r->filename, "r");
    +
    + if (f == NULL) { ... } else { ... }
    +

    + +

    There is also a ap_popenf routine, which parallels the + lower-level open system call. Both of these routines arrange + for the file to be closed when the resource pool in question is + cleared.

    + +

    Unlike the case for memory, there are functions to close files + allocated with ap_pfopen, and ap_popenf, namely + ap_pfclose and ap_pclosef. (This is because, on + many systems, the number of files which a single process can have open is + quite limited). It is important to use these functions to close files + allocated with ap_pfopen and ap_popenf, since to + do otherwise could cause fatal errors on systems such as Linux, which + react badly if the same FILE* is closed more than once.

    + +

    (Using the close functions is not mandatory, since the + file will eventually be closed regardless, but you should consider it in + cases where your module is opening, or could open, a lot of files).

    + + +

    Other sorts of resources -- cleanup functions

    +

    More text goes here. Describe the the cleanup primitives in terms of + which the file stuff is implemented; also, spawn_process.

    + +

    Pool cleanups live until clear_pool() is called: + clear_pool(a) recursively calls destroy_pool() + on all subpools of a; then calls all the cleanups for + a; then releases all the memory for a. + destroy_pool(a) calls clear_pool(a) and then + releases the pool structure itself. i.e., + clear_pool(a) doesn't delete a, it just frees + up all the resources and you can start using it again immediately.

    + + +

    Fine control -- creating and dealing with sub-pools, with + a note on sub-requests

    +

    On rare occasions, too-free use of ap_palloc() and the + associated primitives may result in undesirably profligate resource + allocation. You can deal with such a case by creating a sub-pool, + allocating within the sub-pool rather than the main pool, and clearing or + destroying the sub-pool, which releases the resources which were + associated with it. (This really is a rare situation; the only + case in which it comes up in the standard module set is in case of listing + directories, and then only with very large directories. + Unnecessary use of the primitives discussed here can hair up your code + quite a bit, with very little gain).

    + +

    The primitive for creating a sub-pool is ap_make_sub_pool, + which takes another pool (the parent pool) as an argument. When the main + pool is cleared, the sub-pool will be destroyed. The sub-pool may also be + cleared or destroyed at any time, by calling the functions + ap_clear_pool and ap_destroy_pool, respectively. + (The difference is that ap_clear_pool frees resources + associated with the pool, while ap_destroy_pool also + deallocates the pool itself. In the former case, you can allocate new + resources within the pool, and clear it again, and so forth; in the + latter case, it is simply gone).

    + +

    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 ap_sub_req_... functions) is + ap_destroy_sub_req, 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 someplace a + little less volatile (for instance, the filename in its + request_rec structure).

    + +

    (Again, under most circumstances, you shouldn't feel obliged to call + this function; only 2K of memory or so are allocated for a typical sub + 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 + ap_destroy_... functions).

    + +
    top
    +
    +

    Configuration, commands and the like

    +

    One of the design goals for this server was to maintain external + compatibility with the NCSA 1.3 server --- that is, to read the same + configuration files, to process all the directives therein correctly, and + in general to be a drop-in replacement for NCSA. On the other hand, another + design goal was to move as much of the server's functionality into modules + which have as little as possible to do with the monolithic server core. The + only way to reconcile these goals is to move the handling of most commands + from the central server into the modules.

    + +

    However, just giving the modules command tables is not enough to divorce + them completely from the server core. The server has to remember the + commands in order to act on them later. That involves maintaining data which + is private to the modules, and which can be either per-server, or + per-directory. Most things are per-directory, including in particular access + control and authorization information, but also information on how to + determine file types from suffixes, which can be modified by + AddType and DefaultType directives, and so forth. In general, + the governing philosophy is that anything which can be made + configurable by directory should be; per-server information is generally + used in the standard set of modules for information like + Aliases and Redirects which come into play before the + request is tied to a particular place in the underlying file system.

    + +

    Another requirement for emulating the NCSA server is being able to handle + the per-directory configuration files, generally called + .htaccess files, though even in the NCSA server they can + contain directives which have nothing at all to do with access control. + Accordingly, after URI -> filename translation, but before performing any + other phase, the server walks down the directory hierarchy of the underlying + filesystem, following the translated pathname, to read any + .htaccess files which might be present. The information which + is read in then has to be merged with the applicable information + from the server's own config files (either from the <Directory> sections in + access.conf, or from defaults in srm.conf, which + actually behaves for most purposes almost exactly like <Directory + />).

    + +

    Finally, after having served a request which involved reading + .htaccess files, we need to discard the storage allocated for + handling them. That is solved the same way it is solved wherever else + similar problems come up, by tying those structures to the per-transaction + resource pool.

    + +

    Per-directory configuration structures

    +

    Let's look out how all of this plays out in mod_mime.c, + which defines the file typing handler which emulates the NCSA server's + behavior of determining file types from suffixes. What we'll be looking + at, here, is the code which implements the AddType and AddEncoding commands. These commands can appear in + .htaccess files, so they must be handled in the module's + private per-directory data, which in fact, consists of two separate + tables for MIME types and encoding information, and is declared as + follows:

    + +
    typedef struct {
    +    table *forced_types;      /* Additional AddTyped stuff */
    +    table *encoding_types;    /* Added with AddEncoding... */
    +} mime_dir_config;
    + +

    When the server is reading a configuration file, or <Directory> section, which includes + one of the MIME module's commands, it needs to create a + mime_dir_config structure, so those commands have something + to act on. It does this by invoking the function it finds in the module's + `create per-dir config slot', with two arguments: the name of the + directory to which this configuration information applies (or + NULL for srm.conf), and a pointer to a + resource pool in which the allocation should happen.

    + +

    (If we are reading a .htaccess file, that resource pool + is the per-request resource pool for the request; otherwise it is a + resource pool which is used for configuration data, and cleared on + restarts. Either way, it is important for the structure being created to + vanish when the pool is cleared, by registering a cleanup on the pool if + necessary).

    + +

    For the MIME module, the per-dir config creation function just + ap_pallocs the structure above, and a creates a couple of + tables to fill it. That looks like this:

    + +

    + void *create_mime_dir_config (pool *p, char *dummy)
    + {
    + + mime_dir_config *new =
    + + (mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config));
    +
    +
    + new->forced_types = ap_make_table (p, 4);
    + new->encoding_types = ap_make_table (p, 4);
    +
    + return new;
    +
    + } +

    + +

    Now, suppose we've just read in a .htaccess file. We + already have the per-directory configuration structure for the next + directory up in the hierarchy. If the .htaccess file we just + read in didn't have any AddType + or AddEncoding commands, its + per-directory config structure for the MIME module is still valid, and we + can just use it. Otherwise, we need to merge the two structures + somehow.

    + +

    To do that, the server invokes the module's per-directory config merge + function, if one is present. That function takes three arguments: the two + structures being merged, and a resource pool in which to allocate the + result. For the MIME module, all that needs to be done is overlay the + tables from the new per-directory config structure with those from the + parent:

    + +

    + void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv)
    + {
    + + mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv;
    + mime_dir_config *subdir = (mime_dir_config *)subdirv;
    + mime_dir_config *new =
    + + (mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config));
    +
    +
    + new->forced_types = ap_overlay_tables (p, subdir->forced_types,
    + + parent_dir->forced_types);
    +
    + new->encoding_types = ap_overlay_tables (p, subdir->encoding_types,
    + + parent_dir->encoding_types);
    +
    +
    + return new;
    +
    + } +

    + +

    As a note -- if there is no per-directory merge function present, the + server will just use the subdirectory's configuration info, and ignore + the parent's. For some modules, that works just fine (e.g., for + the includes module, whose per-directory configuration information + consists solely of the state of the XBITHACK), and for those + modules, you can just not declare one, and leave the corresponding + structure slot in the module itself NULL.

    + + +

    Command handling

    +

    Now that we have these structures, we need to be able to figure out how + to fill them. That involves processing the actual AddType and AddEncoding commands. To find commands, the server looks in + the module's command table. That table contains information on how many + arguments the commands take, and in what formats, where it is permitted, + and so forth. That information is sufficient to allow the server to invoke + most command-handling functions with pre-parsed arguments. Without further + ado, let's look at the AddType + command handler, which looks like this (the AddEncoding command looks basically the same, and won't be + shown here):

    + +

    + char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext)
    + {
    + + if (*ext == '.') ++ext;
    + ap_table_set (m->forced_types, ext, ct);
    + return NULL;
    +
    + } +

    + +

    This command handler is unusually simple. As you can see, it takes + four arguments, two of which are pre-parsed arguments, the third being the + per-directory configuration structure for the module in question, and the + fourth being a pointer to a cmd_parms structure. That + structure contains a bunch of arguments which are frequently of use to + some, but not all, commands, including a resource pool (from which memory + can be allocated, and to which cleanups should be tied), and the (virtual) + server being configured, from which the module's per-server configuration + data can be obtained if required.

    + +

    Another way in which this particular command handler is unusually + simple is that there are no error conditions which it can encounter. If + there were, it could return an error message instead of NULL; + this causes an error to be printed out on the server's + stderr, followed by a quick exit, if it is in the main config + files; for a .htaccess file, the syntax error is logged in + the server error log (along with an indication of where it came from), and + the request is bounced with a server error response (HTTP error status, + code 500).

    + +

    The MIME module's command table has entries for these commands, which + look like this:

    + +

    + command_rec mime_cmds[] = {
    + + { "AddType", add_type, NULL, OR_FILEINFO, TAKE2,
    + "a mime type followed by a file extension" },
    + { "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2,
    + + "an encoding (e.g., gzip), followed by a file extension" },
    +
    + { NULL }
    +
    + }; +

    + +

    The entries in these tables are:

    +
      +
    • The name of the command
    • +
    • The function which handles it
    • +
    • a (void *) pointer, which is passed in the + cmd_parms structure to the command handler --- + this is useful in case many similar commands are handled by + the same function.
    • + +
    • A bit mask indicating where the command may appear. There + are mask bits corresponding to each + AllowOverride option, and an additional mask + bit, RSRC_CONF, indicating that the command may + appear in the server's own config files, but not in + any .htaccess file.
    • + +
    • A flag indicating how many arguments the command handler + wants pre-parsed, and how they should be passed in. + TAKE2 indicates two pre-parsed arguments. Other + options are TAKE1, which indicates one + pre-parsed argument, FLAG, which indicates that + the argument should be On or Off, + and is passed in as a boolean flag, RAW_ARGS, + which causes the server to give the command the raw, unparsed + arguments (everything but the command name itself). There is + also ITERATE, which means that the handler looks + the same as TAKE1, but that if multiple + arguments are present, it should be called multiple times, + and finally ITERATE2, which indicates that the + command handler looks like a TAKE2, but if more + arguments are present, then it should be called multiple + times, holding the first argument constant.
    • + +
    • Finally, we have a string which describes the arguments + that should be present. If the arguments in the actual config + file are not as required, this string will be used to help + give a more specific error message. (You can safely leave + this NULL).
    • +
    + +

    Finally, having set this all up, we have to use it. This is ultimately + done in the module's handlers, specifically for its file-typing handler, + which looks more or less like this; note that the per-directory + configuration structure is extracted from the request_rec's + per-directory configuration vector by using the + ap_get_module_config function.

    + +

    + int find_ct(request_rec *r)
    + {
    + + int i;
    + char *fn = ap_pstrdup (r->pool, r->filename);
    + mime_dir_config *conf = (mime_dir_config *)
    + + ap_get_module_config(r->per_dir_config, &mime_module);
    +
    + char *type;
    +
    + if (S_ISDIR(r->finfo.st_mode)) {
    + + r->content_type = DIR_MAGIC_TYPE;
    + return OK;
    +
    + }
    +
    + if((i=ap_rind(fn,'.')) < 0) return DECLINED;
    + ++i;
    +
    + if ((type = ap_table_get (conf->encoding_types, &fn[i])))
    + {
    + + r->content_encoding = type;
    +
    + /* go back to previous extension to try to use it as a type */
    + fn[i-1] = '\0';
    + if((i=ap_rind(fn,'.')) < 0) return OK;
    + ++i;
    +
    + }
    +
    + if ((type = ap_table_get (conf->forced_types, &fn[i])))
    + {
    + + r->content_type = type;
    +
    + }
    +
    + return OK; +
    + } +

    + + +

    Side notes -- per-server configuration, + virtual servers, etc.

    +

    The basic ideas behind per-server module configuration are basically + the same as those for per-directory configuration; there is a creation + function and a merge function, the latter being invoked where a virtual + server has partially overridden the base server configuration, and a + combined structure must be computed. (As with per-directory configuration, + the default if no merge function is specified, and a module is configured + in some virtual server, is that the base configuration is simply + ignored).

    + +

    The only substantial difference is that when a command needs to + configure the per-server private module data, it needs to go to the + cmd_parms data to get at it. Here's an example, from the + alias module, which also indicates how a syntax error can be returned + (note that the per-directory configuration argument to the command + handler is declared as a dummy, since the module doesn't actually have + per-directory config data):

    + +

    + char *add_redirect(cmd_parms *cmd, void *dummy, char *f, char *url)
    + {
    + + server_rec *s = cmd->server;
    + alias_server_conf *conf = (alias_server_conf *)
    + + ap_get_module_config(s->module_config,&alias_module);
    +
    + alias_entry *new = ap_push_array (conf->redirects);
    +
    + if (!ap_is_url (url)) return "Redirect to non-URL";
    +
    + new->fake = f; new->real = url;
    + return NULL;
    +
    + } +

    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/API.xml b/trunk/docs/manual/developer/API.xml new file mode 100644 index 0000000000..de63ae1c1a --- /dev/null +++ b/trunk/docs/manual/developer/API.xml @@ -0,0 +1,1238 @@ + + + + + + + + +Developer Documentation + +Apache 1.3 API notes + + + Warning +

    This document has not been updated to take into account changes made + in the 2.0 version of the Apache HTTP Server. Some of the information may + still be relevant, but please use it with care.

    +
    + +

    These are some notes on the Apache API and the data structures you have + to deal with, etc. They are not yet nearly complete, but hopefully, + they will help you get your bearings. Keep in mind that the API is still + subject to change as we gain experience with it. (See the TODO file for + what might be coming). However, it will be easy to adapt modules + to any changes that are made. (We have more modules to adapt than you + do).

    + +

    A few notes on general pedagogical style here. In the interest of + conciseness, all structure declarations here are incomplete -- the real + ones have more slots that I'm not telling you about. For the most part, + these are reserved to one component of the server core or another, and + should be altered by modules with caution. However, in some cases, they + really are things I just haven't gotten around to yet. Welcome to the + bleeding edge.

    + +

    Finally, here's an outline, to give you some bare idea of what's coming + up, and in what order:

    + + +
    + +
    Basic concepts +

    We begin with an overview of the basic concepts behind the API, and how + they are manifested in the code.

    + +
    Handlers, Modules, and Requests +

    Apache breaks down request handling into a series of steps, more or + less the same way the Netscape server API does (although this API has a + few more stages than NetSite does, as hooks for stuff I thought might be + useful in the future). These are:

    + +
      +
    • URI -> Filename translation
    • +
    • Auth ID checking [is the user who they say they are?]
    • +
    • Auth access checking [is the user authorized here?]
    • +
    • Access checking other than auth
    • +
    • Determining MIME type of the object requested
    • +
    • `Fixups' -- there aren't any of these yet, but the phase is intended + as a hook for possible extensions like SetEnv, which don't really fit well elsewhere.
    • +
    • Actually sending a response back to the client.
    • +
    • Logging the request
    • +
    + +

    These phases are handled by looking at each of a succession of + modules, looking to see if each of them has a handler for the + phase, and attempting invoking it if so. The handler can typically do one + of three things:

    + +
      +
    • Handle the request, and indicate that it has done so by + returning the magic constant OK.
    • + +
    • Decline to handle the request, by returning the magic integer + constant DECLINED. In this case, the server behaves in all + respects as if the handler simply hadn't been there.
    • + +
    • Signal an error, by returning one of the HTTP error codes. This + terminates normal handling of the request, although an ErrorDocument may + be invoked to try to mop up, and it will be logged in any case.
    • +
    + +

    Most phases are terminated by the first module that handles them; + however, for logging, `fixups', and non-access authentication checking, + all handlers always run (barring an error). Also, the response phase is + unique in that modules may declare multiple handlers for it, via a + dispatch table keyed on the MIME type of the requested object. Modules may + declare a response-phase handler which can handle any request, + by giving it the key */* (i.e., a wildcard MIME type + specification). However, wildcard handlers are only invoked if the server + has already tried and failed to find a more specific response handler for + the MIME type of the requested object (either none existed, or they all + declined).

    + +

    The handlers themselves are functions of one argument (a + request_rec structure. vide infra), which returns an integer, + as above.

    +
    + +
    A brief tour of a module +

    At this point, we need to explain the structure of a module. Our + candidate will be one of the messier ones, the CGI module -- this handles + both CGI scripts and the ScriptAlias config file command. It's actually a great deal + more complicated than most modules, but if we're going to have only one + example, it might as well be the one with its fingers in every place.

    + +

    Let's begin with handlers. In order to handle the CGI scripts, the + module declares a response handler for them. Because of ScriptAlias, it also has handlers for the + name translation phase (to recognize ScriptAliased URIs), the type-checking phase (any + ScriptAliased request is typed + as a CGI script).

    + +

    The module needs to maintain some per (virtual) server information, + namely, the ScriptAliases in + effect; the module structure therefore contains pointers to a functions + which builds these structures, and to another which combines two of them + (in case the main server and a virtual server both have ScriptAliases declared).

    + +

    Finally, this module contains code to handle the ScriptAlias command itself. This particular + module only declares one command, but there could be more, so modules have + command tables which declare their commands, and describe where + they are permitted, and how they are to be invoked.

    + +

    A final note on the declared types of the arguments of some of these + commands: a pool is a pointer to a resource pool + structure; these are used by the server to keep track of the memory which + has been allocated, files opened, etc., either to service a + particular request, or to handle the process of configuring itself. That + way, when the request is over (or, for the configuration pool, when the + server is restarting), the memory can be freed, and the files closed, + en masse, without anyone having to write explicit code to track + them all down and dispose of them. Also, a cmd_parms + structure contains various information about the config file being read, + and other status information, which is sometimes of use to the function + which processes a config-file command (such as ScriptAlias). With no further ado, the + module itself:

    + + + /* Declarations of handlers. */
    +
    + int translate_scriptalias (request_rec *);
    + int type_scriptalias (request_rec *);
    + int cgi_handler (request_rec *);
    +
    + /* Subsidiary dispatch table for response-phase
    +  * handlers, by MIME type */
    +
    + handler_rec cgi_handlers[] = {
    + + { "application/x-httpd-cgi", cgi_handler },
    + { NULL }
    +
    + };
    +
    + /* Declarations of routines to manipulate the
    +  * module's configuration info. Note that these are
    +  * returned, and passed in, as void *'s; the server
    +  * core keeps track of them, but it doesn't, and can't,
    +  * know their internal structure.
    +  */
    +
    + void *make_cgi_server_config (pool *);
    + void *merge_cgi_server_config (pool *, void *, void *);
    +
    + /* Declarations of routines to handle config-file commands */
    +
    + extern char *script_alias(cmd_parms *, void *per_dir_config, char *fake, + char *real);
    +
    + command_rec cgi_cmds[] = {
    + + { "ScriptAlias", script_alias, NULL, RSRC_CONF, TAKE2,
    + "a fakename and a realname"},
    + { NULL }
    +
    + };
    +
    + module cgi_module = { +
      STANDARD_MODULE_STUFF,
    +  NULL,                     /* initializer */
    +  NULL,                     /* dir config creator */
    +  NULL,                     /* dir merger */
    +  make_cgi_server_config,   /* server config */
    +  merge_cgi_server_config,  /* merge server config */
    +  cgi_cmds,                 /* command table */
    +  cgi_handlers,             /* handlers */
    +  translate_scriptalias,    /* filename translation */
    +  NULL,                     /* check_user_id */
    +  NULL,                     /* check auth */
    +  NULL,                     /* check access */
    +  type_scriptalias,         /* type_checker */
    +  NULL,                     /* fixups */
    +  NULL,                     /* logger */
    +  NULL                      /* header parser */
    +};
    +
    +
    +
    + +
    How handlers work +

    The sole argument to handlers is a request_rec structure. + This structure describes a particular request which has been made to the + server, on behalf of a client. In most cases, each connection to the + client generates only one request_rec structure.

    + +
    A brief tour of the request_rec +

    The request_rec contains pointers to a resource pool + which will be cleared when the server is finished handling the request; + to structures containing per-server and per-connection information, and + most importantly, information on the request itself.

    + +

    The most important such information is a small set of character strings + describing attributes of the object being requested, including its URI, + filename, content-type and content-encoding (these being filled in by the + translation and type-check handlers which handle the request, + respectively).

    + +

    Other commonly used data items are tables giving the MIME headers on + the client's original request, MIME headers to be sent back with the + response (which modules can add to at will), and environment variables for + any subprocesses which are spawned off in the course of servicing the + request. These tables are manipulated using the ap_table_get + and ap_table_set routines.

    + + +

    Note that the Content-type header value cannot + be set by module content-handlers using the ap_table_*() + routines. Rather, it is set by pointing the content_type + field in the request_rec structure to an appropriate + string. e.g.,

    + + r->content_type = "text/html"; + +
    + +

    Finally, there are pointers to two data structures which, in turn, + point to per-module configuration structures. Specifically, these hold + pointers to the data structures which the module has built to describe + the way it has been configured to operate in a given directory (via + .htaccess files or Directory sections), for private data it has built in the + course of servicing the request (so modules' handlers for one phase can + pass `notes' to their handlers for other phases). There is another such + configuration vector in the server_rec data structure pointed + to by the request_rec, which contains per (virtual) server + configuration data.

    + +

    Here is an abridged declaration, giving the fields most commonly + used:

    + + + struct request_rec {
    +
    + pool *pool;
    + conn_rec *connection;
    + server_rec *server;
    +
    + /* What object is being requested */
    +
    + char *uri;
    + char *filename;
    + char *path_info; +
    char *args;           /* QUERY_ARGS, if any */
    +struct stat finfo;    /* Set by server core;
    +                       * st_mode set to zero if no such file */
    + char *content_type;
    + char *content_encoding;
    +
    + /* MIME header environments, in and out. Also,
    +  * an array containing environment variables to
    +  * be passed to subprocesses, so people can write
    +  * modules to add to that environment.
    +  *
    +  * The difference between headers_out and
    +  * err_headers_out is that the latter are printed
    +  * even on error, and persist across internal
    +  * redirects (so the headers printed for
    +  * ErrorDocument handlers will have + them).
    +  */
    +
    + table *headers_in;
    + table *headers_out;
    + table *err_headers_out;
    + table *subprocess_env;
    +
    + /* Info about the request itself... */
    +
    +
    int header_only;     /* HEAD request, as opposed to GET */
    +char *protocol;      /* Protocol, as given to us, or HTTP/0.9 */
    +char *method;        /* GET, HEAD, POST, etc. */
    +int method_number;   /* M_GET, M_POST, etc. */
    +
    +
    + /* Info for logging */
    +
    + char *the_request;
    + int bytes_sent;
    +
    + /* A flag which modules can set, to indicate that
    +  * the data being returned is volatile, and clients
    +  * should be told not to cache it.
    +  */
    +
    + int no_cache;
    +
    + /* Various other config info which may change
    +  * with .htaccess files
    +  * These are config vectors, with one void*
    +  * pointer for each module (the thing pointed
    +  * to being the module's business).
    +  */
    +
    +
    void *per_dir_config;   /* Options set in config files, etc. */
    +void *request_config;   /* Notes on *this* request */
    +
    + }; +
    +
    + +
    Where request_rec structures come from +

    Most request_rec structures are built by reading an HTTP + request from a client, and filling in the fields. However, there are a + few exceptions:

    + +
      +
    • If the request is to an imagemap, a type map (i.e., a + *.var file), or a CGI script which returned a local + `Location:', then the resource which the user requested is going to be + ultimately located by some URI other than what the client originally + supplied. In this case, the server does an internal redirect, + constructing a new request_rec for the new URI, and + processing it almost exactly as if the client had requested the new URI + directly.
    • + +
    • If some handler signaled an error, and an ErrorDocument + is in scope, the same internal redirect machinery comes into play.
    • + +
    • Finally, a handler occasionally needs to investigate `what would + happen if' some other request were run. For instance, the directory + indexing module needs to know what MIME type would be assigned to a + request for each directory entry, in order to figure out what icon to + use.

      + +

      Such handlers can construct a sub-request, using the + functions ap_sub_req_lookup_file, + ap_sub_req_lookup_uri, and ap_sub_req_method_uri; + these construct a new request_rec 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 checks if the + sub-request is for a file in the same directory as the original + request).

      + +

      (Server-side includes work by building sub-requests and then actually + invoking the response handler for them, via the function + ap_run_sub_req).

      +
    • +
    +
    + +
    Handling requests, declining, and returning + error codes +

    As discussed above, each handler, when invoked to handle a particular + request_rec, has to return an int to indicate + what happened. That can either be

    + +
      +
    • OK -- the request was handled successfully. This may or + may not terminate the phase.
    • + +
    • DECLINED -- no erroneous condition exists, but the module + declines to handle the phase; the server tries to find another.
    • + +
    • an HTTP error code, which aborts handling of the request.
    • +
    + +

    Note that if the error code returned is REDIRECT, then + the module should put a Location in the request's + headers_out, to indicate where the client should be + redirected to.

    +
    + +
    Special considerations for response + handlers +

    Handlers for most phases do their work by simply setting a few fields + in the request_rec structure (or, in the case of access + checkers, simply by returning the correct error code). However, response + handlers have to actually send a request back to the client.

    + +

    They should begin by sending an HTTP response header, using the + function ap_send_http_header. (You don't have to do anything + special to skip sending the header for HTTP/0.9 requests; the function + figures out on its own that it shouldn't do anything). If the request is + marked header_only, that's all they should do; they should + return after that, without attempting any further output.

    + +

    Otherwise, they should produce a request body which responds to the + client as appropriate. The primitives for this are ap_rputc + and ap_rprintf, for internally generated output, and + ap_send_fd, to copy the contents of some FILE * + straight to the client.

    + +

    At this point, you should more or less understand the following piece + of code, which is the handler which handles GET requests + which have no more specific handler; it also shows how conditional + GETs can be handled, if it's desirable to do so in a + particular response handler -- ap_set_last_modified checks + against the If-modified-since value supplied by the client, + if any, and returns an appropriate code (which will, if nonzero, be + USE_LOCAL_COPY). No similar considerations apply for + ap_set_content_length, but it returns an error code for + symmetry.

    + + + int default_handler (request_rec *r)
    + {
    + + int errstatus;
    + FILE *f;
    +
    + if (r->method_number != M_GET) return DECLINED;
    + if (r->finfo.st_mode == 0) return NOT_FOUND;
    +
    + if ((errstatus = ap_set_content_length (r, r->finfo.st_size))
    +     || + (errstatus = ap_set_last_modified (r, r->finfo.st_mtime)))
    + return errstatus;
    +
    + f = fopen (r->filename, "r");
    +
    + if (f == NULL) {
    + + log_reason("file permissions deny server access", r->filename, r);
    + return FORBIDDEN;
    +
    + }
    +
    + register_timeout ("send", r);
    + ap_send_http_header (r);
    +
    + if (!r->header_only) send_fd (f, r);
    + ap_pfclose (r->pool, f);
    + return OK;
    +
    + } +
    + +

    Finally, if all of this is too much of a challenge, there are a few + ways out of it. First off, as shown above, a response handler which has + not yet produced any output can simply return an error code, in which + case the server will automatically produce an error response. Secondly, + it can punt to some other handler by invoking + ap_internal_redirect, which is how the internal redirection + machinery discussed above is invoked. A response handler which has + internally redirected should always return OK.

    + +

    (Invoking ap_internal_redirect from handlers which are + not response handlers will lead to serious confusion).

    +
    + +
    Special considerations for authentication + handlers +

    Stuff that should be discussed here in detail:

    + +
      +
    • Authentication-phase handlers not invoked unless auth is + configured for the directory.
    • + +
    • Common auth configuration stored in the core per-dir + configuration; it has accessors ap_auth_type, + ap_auth_name, and ap_requires.
    • + +
    • Common routines, to handle the protocol end of things, at + least for HTTP basic authentication + (ap_get_basic_auth_pw, which sets the + connection->user structure field + automatically, and ap_note_basic_auth_failure, + which arranges for the proper WWW-Authenticate: + header to be sent back).
    • +
    +
    + +
    Special considerations for logging + handlers +

    When a request has internally redirected, there is the question of + what to log. Apache handles this by bundling the entire chain of redirects + into a list of request_rec structures which are threaded + through the r->prev and r->next pointers. + The request_rec which is passed to the logging handlers in + such cases is the one which was originally built for the initial request + from the client; note that the bytes_sent field will only be + correct in the last request in the chain (the one for which a response was + actually sent).

    +
    +
    + +
    Resource allocation and resource pools +

    One of the problems of writing and designing a server-pool server is + that of preventing leakage, that is, allocating resources (memory, open + files, etc.), without subsequently releasing them. The resource + pool machinery is designed to make it easy to prevent this from happening, + by allowing resource to be allocated in such a way that they are + automatically released when the server is done with them.

    + +

    The way this works is as follows: the memory which is allocated, file + opened, etc., to deal with a particular request are tied to a + resource pool which is allocated for the request. The pool is a + data structure which itself tracks the resources in question.

    + +

    When the request has been processed, the pool is cleared. At + that point, all the memory associated with it is released for reuse, all + files associated with it are closed, and any other clean-up functions which + are associated with the pool are run. When this is over, we can be confident + that all the resource tied to the pool have been released, and that none of + them have leaked.

    + +

    Server restarts, and allocation of memory and resources for per-server + configuration, are handled in a similar way. There is a configuration + pool, which keeps track of resources which were allocated while reading + the server configuration files, and handling the commands therein (for + instance, the memory that was allocated for per-server module configuration, + log files and other files that were opened, and so forth). When the server + restarts, and has to reread the configuration files, the configuration pool + is cleared, and so the memory and file descriptors which were taken up by + reading them the last time are made available for reuse.

    + +

    It should be noted that use of the pool machinery isn't generally + obligatory, except for situations like logging handlers, where you really + need to register cleanups to make sure that the log file gets closed when + the server restarts (this is most easily done by using the function ap_pfopen, which also arranges for the + underlying file descriptor to be closed before any child processes, such as + for CGI scripts, are execed), or in case you are using the + timeout machinery (which isn't yet even documented here). However, there are + two benefits to using it: resources allocated to a pool never leak (even if + you allocate a scratch string, and just forget about it); also, for memory + allocation, ap_palloc is generally faster than + malloc.

    + +

    We begin here by describing how memory is allocated to pools, and then + discuss how other resources are tracked by the resource pool machinery.

    + +
    Allocation of memory in pools +

    Memory is allocated to pools by calling the function + ap_palloc, which takes two arguments, one being a pointer to + a resource pool structure, and the other being the amount of memory to + allocate (in chars). Within handlers for handling requests, + the most common way of getting a resource pool structure is by looking at + the pool slot of the relevant request_rec; hence + the repeated appearance of the following idiom in module code:

    + + + int my_handler(request_rec *r)
    + {
    + + struct my_structure *foo;
    + ...
    +
    + foo = (foo *)ap_palloc (r->pool, sizeof(my_structure));
    +
    + } +
    + +

    Note that there is no ap_pfree -- + ap_palloced memory is freed only when the associated resource + pool is cleared. This means that ap_palloc does not have to + do as much accounting as malloc(); all it does in the typical + case is to round up the size, bump a pointer, and do a range check.

    + +

    (It also raises the possibility that heavy use of + ap_palloc could cause a server process to grow excessively + large. There are two ways to deal with this, which are dealt with below; + briefly, you can use malloc, and try to be sure that all of + the memory gets explicitly freed, or you can allocate a + sub-pool of the main pool, allocate your memory in the sub-pool, and clear + it out periodically. The latter technique is discussed in the section + on sub-pools below, and is used in the directory-indexing code, in order + to avoid excessive storage allocation when listing directories with + thousands of files).

    +
    + +
    Allocating initialized memory +

    There are functions which allocate initialized memory, and are + frequently useful. The function ap_pcalloc has the same + interface as ap_palloc, but clears out the memory it + allocates before it returns it. The function ap_pstrdup + takes a resource pool and a char * as arguments, and + allocates memory for a copy of the string the pointer points to, returning + a pointer to the copy. Finally ap_pstrcat is a varargs-style + function, which takes a pointer to a resource pool, and at least two + char * arguments, the last of which must be + NULL. It allocates enough memory to fit copies of each of + the strings, as a unit; for instance:

    + + + ap_pstrcat (r->pool, "foo", "/", "bar", NULL); + + +

    returns a pointer to 8 bytes worth of memory, initialized to + "foo/bar".

    +
    + +
    Commonly-used pools in the Apache Web + server +

    A pool is really defined by its lifetime more than anything else. + There are some static pools in http_main which are passed to various + non-http_main functions as arguments at opportune times. Here they + are:

    + +
    +
    permanent_pool
    +
    never passed to anything else, this is the ancestor of all pools
    + +
    pconf
    +
    +
      +
    • subpool of permanent_pool
    • + +
    • created at the beginning of a config "cycle"; exists + until the server is terminated or restarts; passed to all + config-time routines, either via cmd->pool, or as the + "pool *p" argument on those which don't take pools
    • + +
    • passed to the module init() functions
    • +
    +
    + +
    ptemp
    +
    +
      +
    • sorry I lie, this pool isn't called this currently in + 1.3, I renamed it this in my pthreads development. I'm + referring to the use of ptrans in the parent... contrast + this with the later definition of ptrans in the + child.
    • + +
    • subpool of permanent_pool
    • + +
    • created at the beginning of a config "cycle"; exists + until the end of config parsing; passed to config-time + routines via cmd->temp_pool. Somewhat of a + "bastard child" because it isn't available everywhere. + Used for temporary scratch space which may be needed by + some config routines but which is deleted at the end of + config.
    • +
    +
    + +
    pchild
    +
    +
      +
    • subpool of permanent_pool
    • + +
    • created when a child is spawned (or a thread is + created); lives until that child (thread) is + destroyed
    • + +
    • passed to the module child_init functions
    • + +
    • destruction happens right after the child_exit + functions are called... (which may explain why I think + child_exit is redundant and unneeded)
    • +
    +
    + +
    ptrans
    +
    +
      +
    • should be a subpool of pchild, but currently is a + subpool of permanent_pool, see above
    • + +
    • cleared by the child before going into the accept() + loop to receive a connection
    • + +
    • used as connection->pool
    • +
    +
    + +
    r->pool
    +
    +
      +
    • for the main request this is a subpool of + connection->pool; for subrequests it is a subpool of + the parent request's pool.
    • + +
    • exists until the end of the request (i.e., + ap_destroy_sub_req, or in child_main after + process_request has finished)
    • + +
    • note that r itself is allocated from r->pool; + i.e., r->pool is first created and then r is + the first thing palloc()d from it
    • +
    +
    +
    + +

    For almost everything folks do, r->pool is the pool to + use. But you can see how other lifetimes, such as pchild, are useful to + some modules... such as modules that need to open a database connection + once per child, and wish to clean it up when the child dies.

    + +

    You can also see how some bugs have manifested themself, such as + setting connection->user to a value from + r->pool -- in this case connection exists for the + lifetime of ptrans, which is longer than + r->pool (especially if r->pool is a + subrequest!). So the correct thing to do is to allocate from + connection->pool.

    + +

    And there was another interesting bug in mod_include + / mod_cgi. You'll see in those that they do this test + to decide if they should use r->pool or + r->main->pool. In this case the resource that they are + registering for cleanup is a child process. If it were registered in + r->pool, then the code would wait() for the + child when the subrequest finishes. With mod_include this + could be any old #include, and the delay can be up to 3 + seconds... and happened quite frequently. Instead the subprocess is + registered in r->main->pool which causes it to be + cleaned up when the entire request is done -- i.e., after the + output has been sent to the client and logging has happened.

    +
    + +
    Tracking open files, etc. +

    As indicated above, resource pools are also used to track other sorts + of resources besides memory. The most common are open files. The routine + which is typically used for this is ap_pfopen, which takes a + resource pool and two strings as arguments; the strings are the same as + the typical arguments to fopen, e.g.,

    + + + ...
    + FILE *f = ap_pfopen (r->pool, r->filename, "r");
    +
    + if (f == NULL) { ... } else { ... }
    +
    + +

    There is also a ap_popenf routine, which parallels the + lower-level open system call. Both of these routines arrange + for the file to be closed when the resource pool in question is + cleared.

    + +

    Unlike the case for memory, there are functions to close files + allocated with ap_pfopen, and ap_popenf, namely + ap_pfclose and ap_pclosef. (This is because, on + many systems, the number of files which a single process can have open is + quite limited). It is important to use these functions to close files + allocated with ap_pfopen and ap_popenf, since to + do otherwise could cause fatal errors on systems such as Linux, which + react badly if the same FILE* is closed more than once.

    + +

    (Using the close functions is not mandatory, since the + file will eventually be closed regardless, but you should consider it in + cases where your module is opening, or could open, a lot of files).

    +
    + +
    Other sorts of resources -- cleanup functions +

    More text goes here. Describe the the cleanup primitives in terms of + which the file stuff is implemented; also, spawn_process.

    + +

    Pool cleanups live until clear_pool() is called: + clear_pool(a) recursively calls destroy_pool() + on all subpools of a; then calls all the cleanups for + a; then releases all the memory for a. + destroy_pool(a) calls clear_pool(a) and then + releases the pool structure itself. i.e., + clear_pool(a) doesn't delete a, it just frees + up all the resources and you can start using it again immediately.

    +
    + +
    Fine control -- creating and dealing with sub-pools, with + a note on sub-requests +

    On rare occasions, too-free use of ap_palloc() and the + associated primitives may result in undesirably profligate resource + allocation. You can deal with such a case by creating a sub-pool, + allocating within the sub-pool rather than the main pool, and clearing or + destroying the sub-pool, which releases the resources which were + associated with it. (This really is a rare situation; the only + case in which it comes up in the standard module set is in case of listing + directories, and then only with very large directories. + Unnecessary use of the primitives discussed here can hair up your code + quite a bit, with very little gain).

    + +

    The primitive for creating a sub-pool is ap_make_sub_pool, + which takes another pool (the parent pool) as an argument. When the main + pool is cleared, the sub-pool will be destroyed. The sub-pool may also be + cleared or destroyed at any time, by calling the functions + ap_clear_pool and ap_destroy_pool, respectively. + (The difference is that ap_clear_pool frees resources + associated with the pool, while ap_destroy_pool also + deallocates the pool itself. In the former case, you can allocate new + resources within the pool, and clear it again, and so forth; in the + latter case, it is simply gone).

    + +

    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 ap_sub_req_... functions) is + ap_destroy_sub_req, 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 someplace a + little less volatile (for instance, the filename in its + request_rec structure).

    + +

    (Again, under most circumstances, you shouldn't feel obliged to call + this function; only 2K of memory or so are allocated for a typical sub + 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 + ap_destroy_... functions).

    +
    +
    + +
    Configuration, commands and the like +

    One of the design goals for this server was to maintain external + compatibility with the NCSA 1.3 server --- that is, to read the same + configuration files, to process all the directives therein correctly, and + in general to be a drop-in replacement for NCSA. On the other hand, another + design goal was to move as much of the server's functionality into modules + which have as little as possible to do with the monolithic server core. The + only way to reconcile these goals is to move the handling of most commands + from the central server into the modules.

    + +

    However, just giving the modules command tables is not enough to divorce + them completely from the server core. The server has to remember the + commands in order to act on them later. That involves maintaining data which + is private to the modules, and which can be either per-server, or + per-directory. Most things are per-directory, including in particular access + control and authorization information, but also information on how to + determine file types from suffixes, which can be modified by + AddType and DefaultType directives, and so forth. In general, + the governing philosophy is that anything which can be made + configurable by directory should be; per-server information is generally + used in the standard set of modules for information like + Aliases and Redirects which come into play before the + request is tied to a particular place in the underlying file system.

    + +

    Another requirement for emulating the NCSA server is being able to handle + the per-directory configuration files, generally called + .htaccess files, though even in the NCSA server they can + contain directives which have nothing at all to do with access control. + Accordingly, after URI -> filename translation, but before performing any + other phase, the server walks down the directory hierarchy of the underlying + filesystem, following the translated pathname, to read any + .htaccess files which might be present. The information which + is read in then has to be merged with the applicable information + from the server's own config files (either from the Directory sections in + access.conf, or from defaults in srm.conf, which + actually behaves for most purposes almost exactly like <Directory + />).

    + +

    Finally, after having served a request which involved reading + .htaccess files, we need to discard the storage allocated for + handling them. That is solved the same way it is solved wherever else + similar problems come up, by tying those structures to the per-transaction + resource pool.

    + +
    Per-directory configuration structures +

    Let's look out how all of this plays out in mod_mime.c, + which defines the file typing handler which emulates the NCSA server's + behavior of determining file types from suffixes. What we'll be looking + at, here, is the code which implements the AddType and AddEncoding commands. These commands can appear in + .htaccess files, so they must be handled in the module's + private per-directory data, which in fact, consists of two separate + tables for MIME types and encoding information, and is declared as + follows:

    + + +
    typedef struct {
    +    table *forced_types;      /* Additional AddTyped stuff */
    +    table *encoding_types;    /* Added with AddEncoding... */
    +} mime_dir_config;
    +
    + +

    When the server is reading a configuration file, or Directory section, which includes + one of the MIME module's commands, it needs to create a + mime_dir_config structure, so those commands have something + to act on. It does this by invoking the function it finds in the module's + `create per-dir config slot', with two arguments: the name of the + directory to which this configuration information applies (or + NULL for srm.conf), and a pointer to a + resource pool in which the allocation should happen.

    + +

    (If we are reading a .htaccess file, that resource pool + is the per-request resource pool for the request; otherwise it is a + resource pool which is used for configuration data, and cleared on + restarts. Either way, it is important for the structure being created to + vanish when the pool is cleared, by registering a cleanup on the pool if + necessary).

    + +

    For the MIME module, the per-dir config creation function just + ap_pallocs the structure above, and a creates a couple of + tables to fill it. That looks like this:

    + + + void *create_mime_dir_config (pool *p, char *dummy)
    + {
    + + mime_dir_config *new =
    + + (mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config));
    +
    +
    + new->forced_types = ap_make_table (p, 4);
    + new->encoding_types = ap_make_table (p, 4);
    +
    + return new;
    +
    + } +
    + +

    Now, suppose we've just read in a .htaccess file. We + already have the per-directory configuration structure for the next + directory up in the hierarchy. If the .htaccess file we just + read in didn't have any AddType + or AddEncoding commands, its + per-directory config structure for the MIME module is still valid, and we + can just use it. Otherwise, we need to merge the two structures + somehow.

    + +

    To do that, the server invokes the module's per-directory config merge + function, if one is present. That function takes three arguments: the two + structures being merged, and a resource pool in which to allocate the + result. For the MIME module, all that needs to be done is overlay the + tables from the new per-directory config structure with those from the + parent:

    + + + void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv)
    + {
    + + mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv;
    + mime_dir_config *subdir = (mime_dir_config *)subdirv;
    + mime_dir_config *new =
    + + (mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config));
    +
    +
    + new->forced_types = ap_overlay_tables (p, subdir->forced_types,
    + + parent_dir->forced_types);
    +
    + new->encoding_types = ap_overlay_tables (p, subdir->encoding_types,
    + + parent_dir->encoding_types);
    +
    +
    + return new;
    +
    + } +
    + +

    As a note -- if there is no per-directory merge function present, the + server will just use the subdirectory's configuration info, and ignore + the parent's. For some modules, that works just fine (e.g., for + the includes module, whose per-directory configuration information + consists solely of the state of the XBITHACK), and for those + modules, you can just not declare one, and leave the corresponding + structure slot in the module itself NULL.

    +
    + +
    Command handling +

    Now that we have these structures, we need to be able to figure out how + to fill them. That involves processing the actual AddType and AddEncoding commands. To find commands, the server looks in + the module's command table. That table contains information on how many + arguments the commands take, and in what formats, where it is permitted, + and so forth. That information is sufficient to allow the server to invoke + most command-handling functions with pre-parsed arguments. Without further + ado, let's look at the AddType + command handler, which looks like this (the AddEncoding command looks basically the same, and won't be + shown here):

    + + + char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext)
    + {
    + + if (*ext == '.') ++ext;
    + ap_table_set (m->forced_types, ext, ct);
    + return NULL;
    +
    + } +
    + +

    This command handler is unusually simple. As you can see, it takes + four arguments, two of which are pre-parsed arguments, the third being the + per-directory configuration structure for the module in question, and the + fourth being a pointer to a cmd_parms structure. That + structure contains a bunch of arguments which are frequently of use to + some, but not all, commands, including a resource pool (from which memory + can be allocated, and to which cleanups should be tied), and the (virtual) + server being configured, from which the module's per-server configuration + data can be obtained if required.

    + +

    Another way in which this particular command handler is unusually + simple is that there are no error conditions which it can encounter. If + there were, it could return an error message instead of NULL; + this causes an error to be printed out on the server's + stderr, followed by a quick exit, if it is in the main config + files; for a .htaccess file, the syntax error is logged in + the server error log (along with an indication of where it came from), and + the request is bounced with a server error response (HTTP error status, + code 500).

    + +

    The MIME module's command table has entries for these commands, which + look like this:

    + + + command_rec mime_cmds[] = {
    + + { "AddType", add_type, NULL, OR_FILEINFO, TAKE2,
    + "a mime type followed by a file extension" },
    + { "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2,
    + + "an encoding (e.g., gzip), followed by a file extension" },
    +
    + { NULL }
    +
    + }; +
    + +

    The entries in these tables are:

    +
      +
    • The name of the command
    • +
    • The function which handles it
    • +
    • a (void *) pointer, which is passed in the + cmd_parms structure to the command handler --- + this is useful in case many similar commands are handled by + the same function.
    • + +
    • A bit mask indicating where the command may appear. There + are mask bits corresponding to each + AllowOverride option, and an additional mask + bit, RSRC_CONF, indicating that the command may + appear in the server's own config files, but not in + any .htaccess file.
    • + +
    • A flag indicating how many arguments the command handler + wants pre-parsed, and how they should be passed in. + TAKE2 indicates two pre-parsed arguments. Other + options are TAKE1, which indicates one + pre-parsed argument, FLAG, which indicates that + the argument should be On or Off, + and is passed in as a boolean flag, RAW_ARGS, + which causes the server to give the command the raw, unparsed + arguments (everything but the command name itself). There is + also ITERATE, which means that the handler looks + the same as TAKE1, but that if multiple + arguments are present, it should be called multiple times, + and finally ITERATE2, which indicates that the + command handler looks like a TAKE2, but if more + arguments are present, then it should be called multiple + times, holding the first argument constant.
    • + +
    • Finally, we have a string which describes the arguments + that should be present. If the arguments in the actual config + file are not as required, this string will be used to help + give a more specific error message. (You can safely leave + this NULL).
    • +
    + +

    Finally, having set this all up, we have to use it. This is ultimately + done in the module's handlers, specifically for its file-typing handler, + which looks more or less like this; note that the per-directory + configuration structure is extracted from the request_rec's + per-directory configuration vector by using the + ap_get_module_config function.

    + + + int find_ct(request_rec *r)
    + {
    + + int i;
    + char *fn = ap_pstrdup (r->pool, r->filename);
    + mime_dir_config *conf = (mime_dir_config *)
    + + ap_get_module_config(r->per_dir_config, &mime_module);
    +
    + char *type;
    +
    + if (S_ISDIR(r->finfo.st_mode)) {
    + + r->content_type = DIR_MAGIC_TYPE;
    + return OK;
    +
    + }
    +
    + if((i=ap_rind(fn,'.')) < 0) return DECLINED;
    + ++i;
    +
    + if ((type = ap_table_get (conf->encoding_types, &fn[i])))
    + {
    + + r->content_encoding = type;
    +
    + /* go back to previous extension to try to use it as a type */
    + fn[i-1] = '\0';
    + if((i=ap_rind(fn,'.')) < 0) return OK;
    + ++i;
    +
    + }
    +
    + if ((type = ap_table_get (conf->forced_types, &fn[i])))
    + {
    + + r->content_type = type;
    +
    + }
    +
    + return OK; +
    + } +
    +
    + +
    Side notes -- per-server configuration, + virtual servers, <em>etc</em>. +

    The basic ideas behind per-server module configuration are basically + the same as those for per-directory configuration; there is a creation + function and a merge function, the latter being invoked where a virtual + server has partially overridden the base server configuration, and a + combined structure must be computed. (As with per-directory configuration, + the default if no merge function is specified, and a module is configured + in some virtual server, is that the base configuration is simply + ignored).

    + +

    The only substantial difference is that when a command needs to + configure the per-server private module data, it needs to go to the + cmd_parms data to get at it. Here's an example, from the + alias module, which also indicates how a syntax error can be returned + (note that the per-directory configuration argument to the command + handler is declared as a dummy, since the module doesn't actually have + per-directory config data):

    + + + char *add_redirect(cmd_parms *cmd, void *dummy, char *f, char *url)
    + {
    + + server_rec *s = cmd->server;
    + alias_server_conf *conf = (alias_server_conf *)
    + + ap_get_module_config(s->module_config,&alias_module);
    +
    + alias_entry *new = ap_push_array (conf->redirects);
    +
    + if (!ap_is_url (url)) return "Redirect to non-URL";
    +
    + new->fake = f; new->real = url;
    + return NULL;
    +
    + } +
    +
    +
    + +
    diff --git a/trunk/docs/manual/developer/API.xml.meta b/trunk/docs/manual/developer/API.xml.meta new file mode 100644 index 0000000000..6fd15b2013 --- /dev/null +++ b/trunk/docs/manual/developer/API.xml.meta @@ -0,0 +1,11 @@ + + + + API + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/debugging.html b/trunk/docs/manual/developer/debugging.html new file mode 100644 index 0000000000..f7977f5ec6 --- /dev/null +++ b/trunk/docs/manual/developer/debugging.html @@ -0,0 +1,3 @@ +URI: debugging.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/debugging.html.en b/trunk/docs/manual/developer/debugging.html.en new file mode 100644 index 0000000000..46aff0b91c --- /dev/null +++ b/trunk/docs/manual/developer/debugging.html.en @@ -0,0 +1,196 @@ + + + +Debugging Memory Allocation in APR - Apache HTTP Server + + + + + +
    <-
    +

    Debugging Memory Allocation in APR

    +
    +

    Available Languages:  en 

    +
    + +

    The allocation mechanism's within APR have a number of debugging modes + that can be used to assist in finding memory problems. This document + describes the modes available and gives instructions on activating + them.

    +
    + +
    top
    +
    +

    Available debugging options

    +

    Allocation Debugging - ALLOC_DEBUG

    + + +
    Debugging support: Define this to enable code which + helps detect re-use of free()d memory and other such + nonsense.
    + +

    The theory is simple. The FILL_BYTE (0xa5) + is written over all malloc'd memory as we receive it, and + is written over everything that we free up during a + clear_pool. We check that blocks on the free list always + have the FILL_BYTE in them, and we check during + palloc() that the bytes still have FILL_BYTE + in them. If you ever see garbage URLs or whatnot containing lots + of 0xa5s then you know something used data that's been + freed or uninitialized.

    + + +

    Malloc Support - ALLOC_USE_MALLOC

    + + +
    If defined all allocations will be done with + malloc() and free()d appropriately at the + end.
    + +

    This is intended to be used with something like Electric + Fence or Purify to help detect memory problems. Note that if + you're using efence then you should also add in ALLOC_DEBUG. + But don't add in ALLOC_DEBUG if you're using Purify because + ALLOC_DEBUG would hide all the uninitialized read errors + that Purify can diagnose.

    + + +

    Pool Debugging - POOL_DEBUG

    +
    This is intended to detect cases where the wrong pool is + used when assigning data to an object in another pool.
    + +

    In particular, it causes the table_{set,add,merge}n + routines to check that their arguments are safe for the + apr_table_t they're being placed in. It currently only works + with the unix multiprocess model, but could be extended to others.

    + + +

    Table Debugging - MAKE_TABLE_PROFILE

    + + +
    Provide diagnostic information about make_table() calls + which are possibly too small.
    + +

    This requires a recent gcc which supports + __builtin_return_address(). The error_log output will be a + message such as:

    +

    + table_push: apr_table_t created by 0x804d874 hit limit of 10 +

    + +

    Use l *0x804d874 to find the + source that corresponds to. It indicates that a apr_table_t + allocated by a call at that address has possibly too small an + initial apr_table_t size guess.

    + + +

    Allocation Statistics - ALLOC_STATS

    + + +
    Provide some statistics on the cost of allocations.
    + +

    This requires a bit of an understanding of how alloc.c works.

    + +
    top
    +
    +

    Allowable Combinations

    + +

    Not all the options outlined above can be activated at the + same time. the following table gives more information.

    + + + + + + + + + + + + + + + + +
    + ALLOC DEBUGALLOC USE MALLOCPOOL DEBUGMAKE TABLE PROFILEALLOC STATS
    ALLOC DEBUG-NoYesYesYes
    ALLOC USE MALLOCNo-NoNoNo
    POOL DEBUGYesNo-YesYes
    MAKE TABLE PROFILEYesNoYes-Yes
    ALLOC STATSYesNoYesYes-
    + +

    Additionally the debugging options are not suitable for + multi-threaded versions of the server. When trying to debug + with these options the server should be started in single + process mode.

    +
    top
    +
    +

    Activating Debugging Options

    + +

    The various options for debugging memory are now enabled in + the apr_general.h header file in APR. The various options are + enabled by uncommenting the define for the option you wish to + use. The section of the code currently looks like this + (contained in srclib/apr/include/apr_pools.h)

    + +

    + /*
    + #define ALLOC_DEBUG
    + #define POOL_DEBUG
    + #define ALLOC_USE_MALLOC
    + #define MAKE_TABLE_PROFILE
    + #define ALLOC_STATS
    + */
    +
    + typedef struct ap_pool_t {
    + + union block_hdr *first;
    + union block_hdr *last;
    + struct cleanup *cleanups;
    + struct process_chain *subprocesses;
    + struct ap_pool_t *sub_pools;
    + struct ap_pool_t *sub_next;
    + struct ap_pool_t *sub_prev;
    + struct ap_pool_t *parent;
    + char *free_first_avail;
    +
    + #ifdef ALLOC_USE_MALLOC
    + + void *allocation_list;
    +
    + #endif
    + #ifdef POOL_DEBUG
    + + struct ap_pool_t *joined;
    +
    + #endif
    + + int (*apr_abort)(int retcode);
    + struct datastruct *prog_data;
    +
    + } ap_pool_t; +

    + +

    To enable allocation debugging simply move the #define + ALLOC_DEBUG above the start of the comments block and rebuild + the server.

    + +

    Note

    +

    In order to use the various options the server must + be rebuilt after editing the header file.

    +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/debugging.xml b/trunk/docs/manual/developer/debugging.xml new file mode 100644 index 0000000000..ab83b10131 --- /dev/null +++ b/trunk/docs/manual/developer/debugging.xml @@ -0,0 +1,193 @@ + + + + + + + + +Developer Documentation + +Debugging Memory Allocation in APR + + +

    The allocation mechanism's within APR have a number of debugging modes + that can be used to assist in finding memory problems. This document + describes the modes available and gives instructions on activating + them.

    +
    + +
    Available debugging options +
    + Allocation Debugging - ALLOC_DEBUG + + Debugging support: Define this to enable code which + helps detect re-use of free()d memory and other such + nonsense. + +

    The theory is simple. The FILL_BYTE (0xa5) + is written over all malloc'd memory as we receive it, and + is written over everything that we free up during a + clear_pool. We check that blocks on the free list always + have the FILL_BYTE in them, and we check during + palloc() that the bytes still have FILL_BYTE + in them. If you ever see garbage URLs or whatnot containing lots + of 0xa5s then you know something used data that's been + freed or uninitialized.

    +
    + +
    + Malloc Support - ALLOC_USE_MALLOC + + If defined all allocations will be done with + malloc() and free()d appropriately at the + end. + +

    This is intended to be used with something like Electric + Fence or Purify to help detect memory problems. Note that if + you're using efence then you should also add in ALLOC_DEBUG. + But don't add in ALLOC_DEBUG if you're using Purify because + ALLOC_DEBUG would hide all the uninitialized read errors + that Purify can diagnose.

    +
    + +
    Pool Debugging - POOL_DEBUG + This is intended to detect cases where the wrong pool is + used when assigning data to an object in another pool. + +

    In particular, it causes the table_{set,add,merge}n + routines to check that their arguments are safe for the + apr_table_t they're being placed in. It currently only works + with the unix multiprocess model, but could be extended to others.

    +
    + +
    + Table Debugging - MAKE_TABLE_PROFILE + + Provide diagnostic information about make_table() calls + which are possibly too small. + +

    This requires a recent gcc which supports + __builtin_return_address(). The error_log output will be a + message such as:

    + + table_push: apr_table_t created by 0x804d874 hit limit of 10 + + +

    Use l *0x804d874 to find the + source that corresponds to. It indicates that a apr_table_t + allocated by a call at that address has possibly too small an + initial apr_table_t size guess.

    +
    + +
    + Allocation Statistics - ALLOC_STATS + + Provide some statistics on the cost of allocations. + +

    This requires a bit of an understanding of how alloc.c works.

    +
    +
    + +
    Allowable Combinations + +

    Not all the options outlined above can be activated at the + same time. the following table gives more information.

    + + + + + + + + + + + + + + + + + + +
    ALLOC DEBUGALLOC USE MALLOCPOOL DEBUGMAKE TABLE PROFILEALLOC STATS
    ALLOC DEBUG-NoYesYesYes
    ALLOC USE MALLOCNo-NoNoNo
    POOL DEBUGYesNo-YesYes
    MAKE TABLE PROFILEYesNoYes-Yes
    ALLOC STATSYesNoYesYes-
    + +

    Additionally the debugging options are not suitable for + multi-threaded versions of the server. When trying to debug + with these options the server should be started in single + process mode.

    +
    + +
    Activating Debugging Options + +

    The various options for debugging memory are now enabled in + the apr_general.h header file in APR. The various options are + enabled by uncommenting the define for the option you wish to + use. The section of the code currently looks like this + (contained in srclib/apr/include/apr_pools.h)

    + + + /*
    + #define ALLOC_DEBUG
    + #define POOL_DEBUG
    + #define ALLOC_USE_MALLOC
    + #define MAKE_TABLE_PROFILE
    + #define ALLOC_STATS
    + */
    +
    + typedef struct ap_pool_t {
    + + union block_hdr *first;
    + union block_hdr *last;
    + struct cleanup *cleanups;
    + struct process_chain *subprocesses;
    + struct ap_pool_t *sub_pools;
    + struct ap_pool_t *sub_next;
    + struct ap_pool_t *sub_prev;
    + struct ap_pool_t *parent;
    + char *free_first_avail;
    +
    + #ifdef ALLOC_USE_MALLOC
    + + void *allocation_list;
    +
    + #endif
    + #ifdef POOL_DEBUG
    + + struct ap_pool_t *joined;
    +
    + #endif
    + + int (*apr_abort)(int retcode);
    + struct datastruct *prog_data;
    +
    + } ap_pool_t; +
    + +

    To enable allocation debugging simply move the #define + ALLOC_DEBUG above the start of the comments block and rebuild + the server.

    + + Note +

    In order to use the various options the server must + be rebuilt after editing the header file.

    +
    +
    +
    + diff --git a/trunk/docs/manual/developer/debugging.xml.meta b/trunk/docs/manual/developer/debugging.xml.meta new file mode 100644 index 0000000000..6f1984fe8c --- /dev/null +++ b/trunk/docs/manual/developer/debugging.xml.meta @@ -0,0 +1,11 @@ + + + + debugging + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/documenting.html b/trunk/docs/manual/developer/documenting.html new file mode 100644 index 0000000000..0731e2d359 --- /dev/null +++ b/trunk/docs/manual/developer/documenting.html @@ -0,0 +1,3 @@ +URI: documenting.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/documenting.html.en b/trunk/docs/manual/developer/documenting.html.en new file mode 100644 index 0000000000..cbb00617df --- /dev/null +++ b/trunk/docs/manual/developer/documenting.html.en @@ -0,0 +1,84 @@ + + + +Documenting Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Documenting Apache 2.0

    +
    +

    Available Languages:  en 

    +
    + +

    Apache 2.0 uses Doxygen to + document the APIs and global variables in the the code. This will explain + the basics of how to document using Doxygen.

    +
    +
    top
    +
    +

    Brief Description

    +

    To start a documentation block, use /**
    + To end a documentation block, use */

    + +

    In the middle of the block, there are multiple tags we can + use:

    + +

    + Description of this functions purpose
    + @param parameter_name description
    + @return description
    + @deffunc signature of the function
    +

    + +

    The deffunc is not always necessary. DoxyGen does not + have a full parser in it, so any prototype that use a macro in the + return type declaration is too complex for scandoc. Those functions + require a deffunc. An example (using &gt; rather + than >):

    + +

    + /**
    +  * return the final element of the pathname
    +  * @param pathname The path to get the final element of
    +  * @return the final element of the path
    +  * @tip Examples:
    +  * <pre>
    +  * "/foo/bar/gum" -&gt; "gum"
    +  * "/foo/bar/gum/" -&gt; ""
    +  * "gum" -&gt; "gum"
    +  * "wi\\n32\\stuff" -&gt; "stuff"
    +  * </pre>
    +  * @deffunc const char * ap_filename_of_pathname(const char *pathname)
    +  */ +

    + +

    At the top of the header file, always include:

    +

    + /**
    +  * @package Name of library header
    +  */ +

    + +

    Doxygen uses a new HTML file for each package. The HTML files are named + {Name_of_library_header}.html, so try to be concise with your names.

    + +

    For a further discussion of the possibilities please refer to + the Doxygen site.

    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/documenting.xml b/trunk/docs/manual/developer/documenting.xml new file mode 100644 index 0000000000..d615583c3f --- /dev/null +++ b/trunk/docs/manual/developer/documenting.xml @@ -0,0 +1,84 @@ + + + + + + + + +Developer Documentation + +Documenting Apache 2.0 + + +

    Apache 2.0 uses Doxygen to + document the APIs and global variables in the the code. This will explain + the basics of how to document using Doxygen.

    +
    + +
    Brief Description +

    To start a documentation block, use /**
    + To end a documentation block, use */

    + +

    In the middle of the block, there are multiple tags we can + use:

    + + + Description of this functions purpose
    + @param parameter_name description
    + @return description
    + @deffunc signature of the function
    +
    + +

    The deffunc is not always necessary. DoxyGen does not + have a full parser in it, so any prototype that use a macro in the + return type declaration is too complex for scandoc. Those functions + require a deffunc. An example (using &gt; rather + than >):

    + + + /**
    +  * return the final element of the pathname
    +  * @param pathname The path to get the final element of
    +  * @return the final element of the path
    +  * @tip Examples:
    +  * <pre>
    +  * "/foo/bar/gum" -&gt; "gum"
    +  * "/foo/bar/gum/" -&gt; ""
    +  * "gum" -&gt; "gum"
    +  * "wi\\n32\\stuff" -&gt; "stuff"
    +  * </pre>
    +  * @deffunc const char * ap_filename_of_pathname(const char *pathname)
    +  */ +
    + +

    At the top of the header file, always include:

    + + /**
    +  * @package Name of library header
    +  */ +
    + +

    Doxygen uses a new HTML file for each package. The HTML files are named + {Name_of_library_header}.html, so try to be concise with your names.

    + +

    For a further discussion of the possibilities please refer to + the Doxygen site.

    +
    +
    + diff --git a/trunk/docs/manual/developer/documenting.xml.meta b/trunk/docs/manual/developer/documenting.xml.meta new file mode 100644 index 0000000000..fca30d7e4a --- /dev/null +++ b/trunk/docs/manual/developer/documenting.xml.meta @@ -0,0 +1,11 @@ + + + + documenting + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/filters.html b/trunk/docs/manual/developer/filters.html new file mode 100644 index 0000000000..c65dc946ac --- /dev/null +++ b/trunk/docs/manual/developer/filters.html @@ -0,0 +1,3 @@ +URI: filters.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/filters.html.en b/trunk/docs/manual/developer/filters.html.en new file mode 100644 index 0000000000..fc865cd700 --- /dev/null +++ b/trunk/docs/manual/developer/filters.html.en @@ -0,0 +1,210 @@ + + + +How filters work in Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    How filters work in Apache 2.0

    +
    +

    Available Languages:  en 

    +
    + +

    Warning

    +

    This is a cut 'n paste job from an email + (<022501c1c529$f63a9550$7f00000a@KOJ>) and only reformatted for + better readability. It's not up to date but may be a good start for + further research.

    +
    +
    + +
    top
    +
    +

    Filter Types

    +

    There are three basic filter types (each of these is actually broken + down into two categories, but that comes later).

    + +
    +
    CONNECTION
    +
    Filters of this type are valid for the lifetime of this connection. + (AP_FTYPE_CONNECTION, AP_FTYPE_NETWORK)
    + +
    PROTOCOL
    +
    Filters of this type are valid for the lifetime of this request from + the point of view of the client, this means that the request is valid + from the time that the request is sent until the time that the response + is received. (AP_FTYPE_PROTOCOL, + AP_FTYPE_TRANSCODE)
    + +
    RESOURCE
    +
    Filters of this type are valid for the time that this content is used + to satisfy a request. For simple requests, this is identical to + PROTOCOL, but internal redirects and sub-requests can change + the content without ending the request. (AP_FTYPE_RESOURCE, + AP_FTYPE_CONTENT_SET)
    +
    + +

    It is important to make the distinction between a protocol and a + resource filter. A resource filter is tied to a specific resource, it + may also be tied to header information, but the main binding is to a + resource. If you are writing a filter and you want to know if it is + resource or protocol, the correct question to ask is: "Can this filter + be removed if the request is redirected to a different resource?" If + the answer is yes, then it is a resource filter. If it is no, then it + is most likely a protocol or connection filter. I won't go into + connection filters, because they seem to be well understood. With this + definition, a few examples might help:

    + +
    +
    Byterange
    +
    We have coded it to be inserted for all requests, and it is removed + if not used. Because this filter is active at the beginning of all + requests, it can not be removed if it is redirected, so this is a + protocol filter.
    + +
    http_header
    +
    This filter actually writes the headers to the network. This is + obviously a required filter (except in the asis case which is special + and will be dealt with below) and so it is a protocol filter.
    + +
    Deflate
    +
    The administrator configures this filter based on which file has been + requested. If we do an internal redirect from an autoindex page to an + index.html page, the deflate filter may be added or removed based on + config, so this is a resource filter.
    +
    + +

    The further breakdown of each category into two more filter types is + strictly for ordering. We could remove it, and only allow for one + filter type, but the order would tend to be wrong, and we would need to + hack things to make it work. Currently, the RESOURCE filters + only have one filter type, but that should change.

    +
    top
    +
    +

    How are filters inserted?

    +

    This is actually rather simple in theory, but the code is + complex. First of all, it is important that everybody realize that + there are three filter lists for each request, but they are all + concatenated together. So, the first list is + r->output_filters, then r->proto_output_filters, + and finally r->connection->output_filters. These correspond + to the RESOURCE, PROTOCOL, and + CONNECTION filters respectively. The problem previously, was + that we used a singly linked list to create the filter stack, and we + started from the "correct" location. This means that if I had a + RESOURCE filter on the stack, and I added a + CONNECTION filter, the CONNECTION filter would + be ignored. This should make sense, because we would insert the connection + filter at the top of the c->output_filters list, but the end + of r->output_filters pointed to the filter that used to be + at the front of c->output_filters. This is obviously wrong. + The new insertion code uses a doubly linked list. This has the advantage + that we never lose a filter that has been inserted. Unfortunately, it comes + with a separate set of headaches.

    + +

    The problem is that we have two different cases were we use subrequests. + The first is to insert more data into a response. The second is to + replace the existing response with an internal redirect. These are two + different cases and need to be treated as such.

    + +

    In the first case, we are creating the subrequest from within a handler + or filter. This means that the next filter should be passed to + make_sub_request function, and the last resource filter in the + sub-request will point to the next filter in the main request. This + makes sense, because the sub-request's data needs to flow through the + same set of filters as the main request. A graphical representation + might help:

    + +
    +Default_handler --> includes_filter --> byterange --> ...
    +
    + +

    If the includes filter creates a sub request, then we don't want the + data from that sub-request to go through the includes filter, because it + might not be SSI data. So, the subrequest adds the following:

    + +
        
    +Default_handler --> includes_filter -/-> byterange --> ...
    +                                    /
    +Default_handler --> sub_request_core
    +
    + +

    What happens if the subrequest is SSI data? Well, that's easy, the + includes_filter is a resource filter, so it will be added to + the sub request in between the Default_handler and the + sub_request_core filter.

    + +

    The second case for sub-requests is when one sub-request is going to + become the real request. This happens whenever a sub-request is created + outside of a handler or filter, and NULL is passed as the next filter to + the make_sub_request function.

    + +

    In this case, the resource filters no longer make sense for the new + request, because the resource has changed. So, instead of starting from + scratch, we simply point the front of the resource filters for the + sub-request to the front of the protocol filters for the old request. + This means that we won't lose any of the protocol filters, neither will + we try to send this data through a filter that shouldn't see it.

    + +

    The problem is that we are using a doubly-linked list for our filter + stacks now. But, you should notice that it is possible for two lists to + intersect in this model. So, you do you handle the previous pointer? + This is a very difficult question to answer, because there is no "right" + answer, either method is equally valid. I looked at why we use the + previous pointer. The only reason for it is to allow for easier + addition of new servers. With that being said, the solution I chose was + to make the previous pointer always stay on the original request.

    + +

    This causes some more complex logic, but it works for all cases. My + concern in having it move to the sub-request, is that for the more + common case (where a sub-request is used to add data to a response), the + main filter chain would be wrong. That didn't seem like a good idea to + me.

    +
    top
    +
    +

    Asis

    +

    The final topic. :-) Mod_Asis is a bit of a hack, but the + handler needs to remove all filters except for connection filters, and + send the data. If you are using mod_asis, all other + bets are off.

    +
    top
    +
    +

    Explanations

    +

    The absolutely last point is that the reason this code was so hard to + get right, was because we had hacked so much to force it to work. I + wrote most of the hacks originally, so I am very much to blame. + However, now that the code is right, I have started to remove some + hacks. Most people should have seen that the reset_filters + and add_required_filters functions are gone. Those inserted + protocol level filters for error conditions, in fact, both functions did + the same thing, one after the other, it was really strange. Because we + don't lose protocol filters for error cases any more, those hacks went away. + The HTTP_HEADER, Content-length, and + Byterange filters are all added in the + insert_filters phase, because if they were added earlier, we + had some interesting interactions. Now, those could all be moved to be + inserted with the HTTP_IN, CORE, and + CORE_IN filters. That would make the code easier to + follow.

    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/filters.xml b/trunk/docs/manual/developer/filters.xml new file mode 100644 index 0000000000..5b4115b314 --- /dev/null +++ b/trunk/docs/manual/developer/filters.xml @@ -0,0 +1,209 @@ + + + + + + + + +Developer Documentation + +How filters work in Apache 2.0 + + + Warning +

    This is a cut 'n paste job from an email + (<022501c1c529$f63a9550$7f00000a@KOJ>) and only reformatted for + better readability. It's not up to date but may be a good start for + further research.

    +
    +
    + +
    Filter Types +

    There are three basic filter types (each of these is actually broken + down into two categories, but that comes later).

    + +
    +
    CONNECTION
    +
    Filters of this type are valid for the lifetime of this connection. + (AP_FTYPE_CONNECTION, AP_FTYPE_NETWORK)
    + +
    PROTOCOL
    +
    Filters of this type are valid for the lifetime of this request from + the point of view of the client, this means that the request is valid + from the time that the request is sent until the time that the response + is received. (AP_FTYPE_PROTOCOL, + AP_FTYPE_TRANSCODE)
    + +
    RESOURCE
    +
    Filters of this type are valid for the time that this content is used + to satisfy a request. For simple requests, this is identical to + PROTOCOL, but internal redirects and sub-requests can change + the content without ending the request. (AP_FTYPE_RESOURCE, + AP_FTYPE_CONTENT_SET)
    +
    + +

    It is important to make the distinction between a protocol and a + resource filter. A resource filter is tied to a specific resource, it + may also be tied to header information, but the main binding is to a + resource. If you are writing a filter and you want to know if it is + resource or protocol, the correct question to ask is: "Can this filter + be removed if the request is redirected to a different resource?" If + the answer is yes, then it is a resource filter. If it is no, then it + is most likely a protocol or connection filter. I won't go into + connection filters, because they seem to be well understood. With this + definition, a few examples might help:

    + +
    +
    Byterange
    +
    We have coded it to be inserted for all requests, and it is removed + if not used. Because this filter is active at the beginning of all + requests, it can not be removed if it is redirected, so this is a + protocol filter.
    + +
    http_header
    +
    This filter actually writes the headers to the network. This is + obviously a required filter (except in the asis case which is special + and will be dealt with below) and so it is a protocol filter.
    + +
    Deflate
    +
    The administrator configures this filter based on which file has been + requested. If we do an internal redirect from an autoindex page to an + index.html page, the deflate filter may be added or removed based on + config, so this is a resource filter.
    +
    + +

    The further breakdown of each category into two more filter types is + strictly for ordering. We could remove it, and only allow for one + filter type, but the order would tend to be wrong, and we would need to + hack things to make it work. Currently, the RESOURCE filters + only have one filter type, but that should change.

    +
    + +
    How are filters inserted? +

    This is actually rather simple in theory, but the code is + complex. First of all, it is important that everybody realize that + there are three filter lists for each request, but they are all + concatenated together. So, the first list is + r->output_filters, then r->proto_output_filters, + and finally r->connection->output_filters. These correspond + to the RESOURCE, PROTOCOL, and + CONNECTION filters respectively. The problem previously, was + that we used a singly linked list to create the filter stack, and we + started from the "correct" location. This means that if I had a + RESOURCE filter on the stack, and I added a + CONNECTION filter, the CONNECTION filter would + be ignored. This should make sense, because we would insert the connection + filter at the top of the c->output_filters list, but the end + of r->output_filters pointed to the filter that used to be + at the front of c->output_filters. This is obviously wrong. + The new insertion code uses a doubly linked list. This has the advantage + that we never lose a filter that has been inserted. Unfortunately, it comes + with a separate set of headaches.

    + +

    The problem is that we have two different cases were we use subrequests. + The first is to insert more data into a response. The second is to + replace the existing response with an internal redirect. These are two + different cases and need to be treated as such.

    + +

    In the first case, we are creating the subrequest from within a handler + or filter. This means that the next filter should be passed to + make_sub_request function, and the last resource filter in the + sub-request will point to the next filter in the main request. This + makes sense, because the sub-request's data needs to flow through the + same set of filters as the main request. A graphical representation + might help:

    + + +
    +Default_handler --> includes_filter --> byterange --> ...
    +
    +
    + +

    If the includes filter creates a sub request, then we don't want the + data from that sub-request to go through the includes filter, because it + might not be SSI data. So, the subrequest adds the following:

    + + +
        
    +Default_handler --> includes_filter -/-> byterange --> ...
    +                                    /
    +Default_handler --> sub_request_core
    +
    +
    + +

    What happens if the subrequest is SSI data? Well, that's easy, the + includes_filter is a resource filter, so it will be added to + the sub request in between the Default_handler and the + sub_request_core filter.

    + +

    The second case for sub-requests is when one sub-request is going to + become the real request. This happens whenever a sub-request is created + outside of a handler or filter, and NULL is passed as the next filter to + the make_sub_request function.

    + +

    In this case, the resource filters no longer make sense for the new + request, because the resource has changed. So, instead of starting from + scratch, we simply point the front of the resource filters for the + sub-request to the front of the protocol filters for the old request. + This means that we won't lose any of the protocol filters, neither will + we try to send this data through a filter that shouldn't see it.

    + +

    The problem is that we are using a doubly-linked list for our filter + stacks now. But, you should notice that it is possible for two lists to + intersect in this model. So, you do you handle the previous pointer? + This is a very difficult question to answer, because there is no "right" + answer, either method is equally valid. I looked at why we use the + previous pointer. The only reason for it is to allow for easier + addition of new servers. With that being said, the solution I chose was + to make the previous pointer always stay on the original request.

    + +

    This causes some more complex logic, but it works for all cases. My + concern in having it move to the sub-request, is that for the more + common case (where a sub-request is used to add data to a response), the + main filter chain would be wrong. That didn't seem like a good idea to + me.

    +
    + +
    Asis +

    The final topic. :-) Mod_Asis is a bit of a hack, but the + handler needs to remove all filters except for connection filters, and + send the data. If you are using mod_asis, all other + bets are off.

    +
    + +
    Explanations +

    The absolutely last point is that the reason this code was so hard to + get right, was because we had hacked so much to force it to work. I + wrote most of the hacks originally, so I am very much to blame. + However, now that the code is right, I have started to remove some + hacks. Most people should have seen that the reset_filters + and add_required_filters functions are gone. Those inserted + protocol level filters for error conditions, in fact, both functions did + the same thing, one after the other, it was really strange. Because we + don't lose protocol filters for error cases any more, those hacks went away. + The HTTP_HEADER, Content-length, and + Byterange filters are all added in the + insert_filters phase, because if they were added earlier, we + had some interesting interactions. Now, those could all be moved to be + inserted with the HTTP_IN, CORE, and + CORE_IN filters. That would make the code easier to + follow.

    +
    +
    + diff --git a/trunk/docs/manual/developer/filters.xml.meta b/trunk/docs/manual/developer/filters.xml.meta new file mode 100644 index 0000000000..a256a27ae1 --- /dev/null +++ b/trunk/docs/manual/developer/filters.xml.meta @@ -0,0 +1,11 @@ + + + + filters + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/hooks.html b/trunk/docs/manual/developer/hooks.html new file mode 100644 index 0000000000..49fe68e8dd --- /dev/null +++ b/trunk/docs/manual/developer/hooks.html @@ -0,0 +1,3 @@ +URI: hooks.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/hooks.html.en b/trunk/docs/manual/developer/hooks.html.en new file mode 100644 index 0000000000..da26c308d2 --- /dev/null +++ b/trunk/docs/manual/developer/hooks.html.en @@ -0,0 +1,239 @@ + + + +Apache 2.0 Hook Functions - Apache HTTP Server + + + + + +
    <-
    +

    Apache 2.0 Hook Functions

    +
    +

    Available Languages:  en 

    +
    + +

    Warning

    +

    This document is still in development and may be partially out of + date.

    +
    + +

    In general, a hook function is one that Apache will call at + some point during the processing of a request. Modules can + provide functions that are called, and specify when they get + called in comparison to other modules.

    +
    + +
    top
    +
    +

    Creating a hook function

    +

    In order to create a new hook, four things need to be + done:

    + +

    Declare the hook function

    +

    Use the AP_DECLARE_HOOK macro, which needs to be given + the return type of the hook function, the name of the hook, and the + arguments. For example, if the hook returns an int and + takes a request_rec * and an int and is + called do_something, then declare it like this:

    +

    + AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n)) +

    + +

    This should go in a header which modules will include if + they want to use the hook.

    + + +

    Create the hook structure

    +

    Each source file that exports a hook has a private structure + which is used to record the module functions that use the hook. + This is declared as follows:

    + +

    + APR_HOOK_STRUCT(
    + + APR_HOOK_LINK(do_something)
    + ...
    +
    + ) +

    + + +

    Implement the hook caller

    +

    The source file that exports the hook has to implement a + function that will call the hook. There are currently three + possible ways to do this. In all cases, the calling function is + called ap_run_hookname().

    + +

    Void hooks

    +

    If the return value of a hook is void, then all the + hooks are called, and the caller is implemented like this:

    + +

    + AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n)) +

    + +

    The second and third arguments are the dummy argument + declaration and the dummy arguments as they will be used when + calling the hook. In other words, this macro expands to + something like this:

    + +

    + void ap_run_do_something(request_rec *r, int n)
    + {
    + + ...
    + do_something(r, n);
    +
    + } +

    + + +

    Hooks that return a value

    +

    If the hook returns a value, then it can either be run until + the first hook that does something interesting, like so:

    + +

    + AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED) +

    + +

    The first hook that does not return DECLINED + stops the loop and its return value is returned from the hook + caller. Note that DECLINED is the tradition Apache + hook return meaning "I didn't do anything", but it can be + whatever suits you.

    + +

    Alternatively, all hooks can be run until an error occurs. + This boils down to permitting two return values, one of + which means "I did something, and it was OK" and the other + meaning "I did nothing". The first function that returns a + value other than one of those two stops the loop, and its + return is the return value. Declare these like so:

    + +

    + AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED) +

    + +

    Again, OK and DECLINED are the traditional + values. You can use what you want.

    + + + +

    Call the hook callers

    +

    At appropriate moments in the code, call the hook caller, + like so:

    + +

    + int n, ret;
    + request_rec *r;
    +
    + ret=ap_run_do_something(r, n); +

    + +
    top
    +
    +

    Hooking the hook

    +

    A module that wants a hook to be called needs to do two + things.

    + +

    Implement the hook function

    +

    Include the appropriate header, and define a static function + of the correct type:

    + +

    + static int my_something_doer(request_rec *r, int n)
    + {
    + + ...
    + return OK;
    +
    + } +

    + + +

    Add a hook registering function

    +

    During initialisation, Apache will call each modules hook + registering function, which is included in the module + structure:

    + +

    + static void my_register_hooks()
    + {
    + + ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE);
    +
    + }
    +
    + mode MODULE_VAR_EXPORT my_module =
    + {
    + + ...
    + my_register_hooks /* register hooks */
    +
    + }; +

    + + +

    Controlling hook calling order

    +

    In the example above, we didn't use the three arguments in + the hook registration function that control calling order. + There are two mechanisms for doing this. The first, rather + crude, method, allows us to specify roughly where the hook is + run relative to other modules. The final argument control this. + There are three possible values: APR_HOOK_FIRST, + APR_HOOK_MIDDLE and APR_HOOK_LAST.

    + +

    All modules using any particular value may be run in any + order relative to each other, but, of course, all modules using + APR_HOOK_FIRST will be run before APR_HOOK_MIDDLE + which are before APR_HOOK_LAST. Modules that don't care + when they are run should use APR_HOOK_MIDDLE. (I spaced + these out so people could do stuff like APR_HOOK_FIRST-2 + to get in slightly earlier, but is this wise? - Ben)

    + +

    Note that there are two more values, + APR_HOOK_REALLY_FIRST and APR_HOOK_REALLY_LAST. These + should only be used by the hook exporter.

    + +

    The other method allows finer control. When a module knows + that it must be run before (or after) some other modules, it + can specify them by name. The second (third) argument is a + NULL-terminated array of strings consisting of the names of + modules that must be run before (after) the current module. For + example, suppose we want "mod_xyz.c" and "mod_abc.c" to run + before we do, then we'd hook as follows:

    + +

    + static void register_hooks()
    + {
    + + static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };
    +
    + ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE);
    +
    + } +

    + +

    Note that the sort used to achieve this is stable, so + ordering set by APR_HOOK_ORDER is preserved, as far + as is possible.

    + +

    Ben Laurie, 15th August 1999

    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/hooks.xml b/trunk/docs/manual/developer/hooks.xml new file mode 100644 index 0000000000..2d262de9b2 --- /dev/null +++ b/trunk/docs/manual/developer/hooks.xml @@ -0,0 +1,236 @@ + + + + + + + + +Developer Documentation + +Apache 2.0 Hook Functions + + + Warning +

    This document is still in development and may be partially out of + date.

    +
    + +

    In general, a hook function is one that Apache will call at + some point during the processing of a request. Modules can + provide functions that are called, and specify when they get + called in comparison to other modules.

    +
    + +
    Creating a hook function +

    In order to create a new hook, four things need to be + done:

    + +
    Declare the hook function +

    Use the AP_DECLARE_HOOK macro, which needs to be given + the return type of the hook function, the name of the hook, and the + arguments. For example, if the hook returns an int and + takes a request_rec * and an int and is + called do_something, then declare it like this:

    + + AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n)) + + +

    This should go in a header which modules will include if + they want to use the hook.

    +
    + +
    Create the hook structure +

    Each source file that exports a hook has a private structure + which is used to record the module functions that use the hook. + This is declared as follows:

    + + + APR_HOOK_STRUCT(
    + + APR_HOOK_LINK(do_something)
    + ...
    +
    + ) +
    +
    + +
    Implement the hook caller +

    The source file that exports the hook has to implement a + function that will call the hook. There are currently three + possible ways to do this. In all cases, the calling function is + called ap_run_hookname().

    + +
    Void hooks +

    If the return value of a hook is void, then all the + hooks are called, and the caller is implemented like this:

    + + + AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n)) + + +

    The second and third arguments are the dummy argument + declaration and the dummy arguments as they will be used when + calling the hook. In other words, this macro expands to + something like this:

    + + + void ap_run_do_something(request_rec *r, int n)
    + {
    + + ...
    + do_something(r, n);
    +
    + } +
    +
    + +
    Hooks that return a value +

    If the hook returns a value, then it can either be run until + the first hook that does something interesting, like so:

    + + + AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED) + + +

    The first hook that does not return DECLINED + stops the loop and its return value is returned from the hook + caller. Note that DECLINED is the tradition Apache + hook return meaning "I didn't do anything", but it can be + whatever suits you.

    + +

    Alternatively, all hooks can be run until an error occurs. + This boils down to permitting two return values, one of + which means "I did something, and it was OK" and the other + meaning "I did nothing". The first function that returns a + value other than one of those two stops the loop, and its + return is the return value. Declare these like so:

    + + + AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED) + + +

    Again, OK and DECLINED are the traditional + values. You can use what you want.

    +
    +
    + +
    Call the hook callers +

    At appropriate moments in the code, call the hook caller, + like so:

    + + + int n, ret;
    + request_rec *r;
    +
    + ret=ap_run_do_something(r, n); +
    +
    +
    + +
    Hooking the hook +

    A module that wants a hook to be called needs to do two + things.

    + +
    Implement the hook function +

    Include the appropriate header, and define a static function + of the correct type:

    + + + static int my_something_doer(request_rec *r, int n)
    + {
    + + ...
    + return OK;
    +
    + } +
    +
    + +
    Add a hook registering function +

    During initialisation, Apache will call each modules hook + registering function, which is included in the module + structure:

    + + + static void my_register_hooks()
    + {
    + + ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE);
    +
    + }
    +
    + mode MODULE_VAR_EXPORT my_module =
    + {
    + + ...
    + my_register_hooks /* register hooks */
    +
    + }; +
    +
    + +
    Controlling hook calling order +

    In the example above, we didn't use the three arguments in + the hook registration function that control calling order. + There are two mechanisms for doing this. The first, rather + crude, method, allows us to specify roughly where the hook is + run relative to other modules. The final argument control this. + There are three possible values: APR_HOOK_FIRST, + APR_HOOK_MIDDLE and APR_HOOK_LAST.

    + +

    All modules using any particular value may be run in any + order relative to each other, but, of course, all modules using + APR_HOOK_FIRST will be run before APR_HOOK_MIDDLE + which are before APR_HOOK_LAST. Modules that don't care + when they are run should use APR_HOOK_MIDDLE. (I spaced + these out so people could do stuff like APR_HOOK_FIRST-2 + to get in slightly earlier, but is this wise? - Ben)

    + +

    Note that there are two more values, + APR_HOOK_REALLY_FIRST and APR_HOOK_REALLY_LAST. These + should only be used by the hook exporter.

    + +

    The other method allows finer control. When a module knows + that it must be run before (or after) some other modules, it + can specify them by name. The second (third) argument is a + NULL-terminated array of strings consisting of the names of + modules that must be run before (after) the current module. For + example, suppose we want "mod_xyz.c" and "mod_abc.c" to run + before we do, then we'd hook as follows:

    + + + static void register_hooks()
    + {
    + + static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };
    +
    + ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE);
    +
    + } +
    + +

    Note that the sort used to achieve this is stable, so + ordering set by APR_HOOK_ORDER is preserved, as far + as is possible.

    + +

    Ben Laurie, 15th August 1999

    +
    +
    +
    + diff --git a/trunk/docs/manual/developer/hooks.xml.meta b/trunk/docs/manual/developer/hooks.xml.meta new file mode 100644 index 0000000000..7d0d8d6913 --- /dev/null +++ b/trunk/docs/manual/developer/hooks.xml.meta @@ -0,0 +1,11 @@ + + + + hooks + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/index.html b/trunk/docs/manual/developer/index.html new file mode 100644 index 0000000000..5f97bff8c6 --- /dev/null +++ b/trunk/docs/manual/developer/index.html @@ -0,0 +1,3 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/index.html.en b/trunk/docs/manual/developer/index.html.en new file mode 100644 index 0000000000..3e103abd5e --- /dev/null +++ b/trunk/docs/manual/developer/index.html.en @@ -0,0 +1,73 @@ + + + +Developer Documentation for Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Developer Documentation for Apache 2.0

    +
    +

    Available Languages:  en 

    +
    + +

    Many of the documents on these Developer pages are lifted + from Apache 1.3's documentation. While they are all being + updated to Apache 2.0, they are in different stages of + progress. Please be patient, and point out any discrepancies or + errors on the developer/ pages directly to the + dev@httpd.apache.org mailing list.

    +
    + +
    top
    +
    top
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/index.xml b/trunk/docs/manual/developer/index.xml new file mode 100644 index 0000000000..58ff7b542f --- /dev/null +++ b/trunk/docs/manual/developer/index.xml @@ -0,0 +1,76 @@ + + + + + + + + + + +Developer Documentation for Apache 2.0 + + +

    Many of the documents on these Developer pages are lifted + from Apache 1.3's documentation. While they are all being + updated to Apache 2.0, they are in different stages of + progress. Please be patient, and point out any discrepancies or + errors on the developer/ pages directly to the + dev@httpd.apache.org mailing list.

    +
    + +
    Topics + +
    + +
    External Resources + +
    +
    + diff --git a/trunk/docs/manual/developer/index.xml.meta b/trunk/docs/manual/developer/index.xml.meta new file mode 100644 index 0000000000..26f1bf7ac0 --- /dev/null +++ b/trunk/docs/manual/developer/index.xml.meta @@ -0,0 +1,11 @@ + + + + index + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/modules.html b/trunk/docs/manual/developer/modules.html new file mode 100644 index 0000000000..cb7b1dbfaf --- /dev/null +++ b/trunk/docs/manual/developer/modules.html @@ -0,0 +1,7 @@ +URI: modules.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: modules.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/developer/modules.html.en b/trunk/docs/manual/developer/modules.html.en new file mode 100644 index 0000000000..2f91ee9a48 --- /dev/null +++ b/trunk/docs/manual/developer/modules.html.en @@ -0,0 +1,273 @@ + + + +Converting Modules from Apache 1.3 to Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Converting Modules from Apache 1.3 to Apache 2.0

    +
    +

    Available Languages:  en  | + ja 

    +
    + +

    This is a first attempt at writing the lessons I learned + when trying to convert the mod_mmap_static module to Apache + 2.0. It's by no means definitive and probably won't even be + correct in some ways, but it's a start.

    +
    + +
    top
    +
    +

    The easier changes ...

    + +

    Cleanup Routines

    +

    These now need to be of type apr_status_t and return a + value of that type. Normally the return value will be + APR_SUCCESS unless there is some need to signal an error in + the cleanup. Be aware that even though you signal an error not all code + yet checks and acts upon the error.

    + + +

    Initialisation Routines

    +

    These should now be renamed to better signify where they sit + in the overall process. So the name gets a small change from + mmap_init to mmap_post_config. The arguments + passed have undergone a radical change and now look like

    + +
      +
    • apr_pool_t *p
    • +
    • apr_pool_t *plog
    • +
    • apr_pool_t *ptemp
    • +
    • server_rec *s
    • +
    + + +

    Data Types

    +

    A lot of the data types have been moved into the APR. This means that some have had + a name change, such as the one shown above. The following is a brief + list of some of the changes that you are likely to have to make.

    + +
      +
    • pool becomes apr_pool_t
    • +
    • table becomes apr_table_t
    • +
    + +
    top
    +
    +

    The messier changes...

    + +

    Register Hooks

    +

    The new architecture uses a series of hooks to provide for + calling your functions. These you'll need to add to your module + by way of a new function, static void register_hooks(void). + The function is really reasonably straightforward once you + understand what needs to be done. Each function that needs + calling at some stage in the processing of a request needs to + be registered, handlers do not. There are a number of phases + where functions can be added, and for each you can specify with + a high degree of control the relative order that the function + will be called in.

    + +

    This is the code that was added to mod_mmap_static:

    +
    +static void register_hooks(void)
    +{
    +    static const char * const aszPre[]={ "http_core.c",NULL };
    +    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
    +    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
    +};
    + +

    This registers 2 functions that need to be called, one in + the post_config stage (virtually every module will need this + one) and one for the translate_name phase. note that while + there are different function names the format of each is + identical. So what is the format?

    + +

    + ap_hook_phase_name(function_name, + predecessors, successors, position); +

    + +

    There are 3 hook positions defined...

    + +
      +
    • HOOK_FIRST
    • +
    • HOOK_MIDDLE
    • +
    • HOOK_LAST
    • +
    + +

    To define the position you use the position and then modify + it with the predecessors and successors. Each of the modifiers + can be a list of functions that should be called, either before + the function is run (predecessors) or after the function has + run (successors).

    + +

    In the mod_mmap_static case I didn't care about the + post_config stage, but the mmap_static_xlat + must be called after the core module had done it's name + translation, hence the use of the aszPre to define a modifier to the + position HOOK_LAST.

    + + +

    Module Definition

    +

    There are now a lot fewer stages to worry about when + creating your module definition. The old defintion looked + like

    + +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD_MODULE_STUFF,
    +    /* initializer */
    +    /* dir config creater */
    +    /* dir merger --- default is to override */
    +    /* server config */
    +    /* merge server config */
    +    /* command handlers */
    +    /* handlers */
    +    /* filename translation */
    +    /* check_user_id */
    +    /* check auth */
    +    /* check access */
    +    /* type_checker */
    +    /* fixups */
    +    /* logger */
    +    /* header parser */
    +    /* child_init */
    +    /* child_exit */
    +    /* post read-request */
    +};
    + +

    The new structure is a great deal simpler...

    +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD20_MODULE_STUFF,
    +    /* create per-directory config structures */
    +    /* merge per-directory config structures  */
    +    /* create per-server config structures    */
    +    /* merge per-server config structures     */
    +    /* command handlers */
    +    /* handlers */
    +    /* register hooks */
    +};
    + +

    Some of these read directly across, some don't. I'll try to + summarise what should be done below.

    + +

    The stages that read directly across :

    + +
    +
    /* dir config creater */
    +
    /* create per-directory config structures */
    + +
    /* server config */
    +
    /* create per-server config structures */
    + +
    /* dir merger */
    +
    /* merge per-directory config structures */
    + +
    /* merge server config */
    +
    /* merge per-server config structures */
    + +
    /* command table */
    +
    /* command apr_table_t */
    + +
    /* handlers */
    +
    /* handlers */
    +
    + +

    The remainder of the old functions should be registered as + hooks. There are the following hook stages defined so + far...

    + +
    +
    ap_hook_post_config
    +
    this is where the old _init routines get + registered
    + +
    ap_hook_http_method
    +
    retrieve the http method from a request. (legacy)
    + +
    ap_hook_open_logs
    +
    open any specified logs
    + +
    ap_hook_auth_checker
    +
    check if the resource requires authorization
    + +
    ap_hook_access_checker
    +
    check for module-specific restrictions
    + +
    ap_hook_check_user_id
    +
    check the user-id and password
    + +
    ap_hook_default_port
    +
    retrieve the default port for the server
    + +
    ap_hook_pre_connection
    +
    do any setup required just before processing, but after + accepting
    + +
    ap_hook_process_connection
    +
    run the correct protocol
    + +
    ap_hook_child_init
    +
    call as soon as the child is started
    + +
    ap_hook_create_request
    +
    ??
    + +
    ap_hook_fixups
    +
    last chance to modify things before generating content
    + +
    ap_hook_handler
    +
    generate the content
    + +
    ap_hook_header_parser
    +
    lets modules look at the headers, not used by most modules, because + they use post_read_request for this
    + +
    ap_hook_insert_filter
    +
    to insert filters into the filter chain
    + +
    ap_hook_log_transaction
    +
    log information about the request
    + +
    ap_hook_optional_fn_retrieve
    +
    retrieve any functions registered as optional
    + +
    ap_hook_post_read_request
    +
    called after reading the request, before any other phase
    + +
    ap_hook_quick_handler
    +
    called before any request processing, used by cache modules.
    + +
    ap_hook_translate_name
    +
    translate the URI into a filename
    + +
    ap_hook_type_checker
    +
    determine and/or set the doc type
    +
    + +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/modules.html.ja.euc-jp b/trunk/docs/manual/developer/modules.html.ja.euc-jp new file mode 100644 index 0000000000..6860644e02 --- /dev/null +++ b/trunk/docs/manual/developer/modules.html.ja.euc-jp @@ -0,0 +1,274 @@ + + + +¥â¥¸¥å¡¼¥ë¤Î Apache 1.3 ¤«¤é Apache 2.0 ¤Ø¤Î°Ü¿¢ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥â¥¸¥å¡¼¥ë¤Î Apache 1.3 ¤«¤é Apache 2.0 ¤Ø¤Î°Ü¿¢

    +
    +

    Available Languages:  en  | + ja 

    +
    + +

    ¤³¤Îʸ½ñ¤Ï mod_mmap_static ¥â¥¸¥å¡¼¥ë¤ò Apache 2.0 ÍѤ˰ܿ¢¤·¤¿»þ¤Ë + ³Ø¤ó¤À·Ð¸³¤ò¤â¤È¤Ë½ñ¤¤¤¿¡¢ºÇ½é¤Î¼ê°ú¤­½ñ¤Ç¤¹¡£¤Þ¤À¤Þ¤À´°Á´¤¸¤ã¤Ê¤¤¤·¡¢ + ¤Ò¤ç¤Ã¤È¤¹¤ë¤È´Ö°ã¤Ã¤Æ¤¤¤ëÉôʬ¤â¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢ + ¼è¤Ã³Ý¤ê¤Ë¤Ï¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    +
    + +
    top
    +
    +

    ´Êñ¤ÊÊѹ¹ÅÀ

    + +

    ¥¯¥ê¡¼¥ó¥Ê¥Ã¥× ¥ë¡¼¥Á¥ó

    +

    ¥¯¥ê¡¼¥ó¥Ê¥Ã¥×¥ë¡¼¥Á¥ó¤Ï apr_status_t ·¿¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢apr_status_t ·¿¤ÎÃͤòÊÖ¤µ¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ + ¥¯¥ê¡¼¥ó¥Ê¥Ã¥×Ãæ¤Î¥¨¥é¡¼¤òÄÌÃΤ¹¤ëɬÍפ¬¤Ê¤±¤ì¤Ð¡¢ÊÖ¤êÃͤÏÉáÄÌ¡¢ + ARP_SUCCESS ¤Ç¤¹¡£¤¿¤È¤¨¥¨¥é¡¼¤òÄÌÃΤ·¤¿¤È¤·¤Æ¤â¡¢ + ¤¹¤Ù¤Æ¤Î¥³¡¼¥É¤¬¤½¤ÎÄÌÃΤò¥Á¥§¥Ã¥¯¤·¤¿¤ê¡¢ + ¥¨¥é¡¼¤Ë±þ¤¸¤¿Æ°ºî¤ò¤¹¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¤³¤È¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£

    + + + +

    ½é´ü²½¥ë¡¼¥Á¥ó

    + +

    ½é´ü²½¥ë¡¼¥Á¥ó¤Ï½èÍýÁ´ÂΤ«¤é¸«¤Æ¤·¤Ã¤¯¤ê¤¯¤ë¤è¤¦¤Ê°ÕÌ£¤òɽ¤¹¤è¤¦¤Ë¡¢ + ̾Á°¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿¡£¤Ç¤¹¤«¤é¡¢mmap_init ¤«¤é mmap_post_config + ¤Î¤è¤¦¤Ë¤Á¤ç¤Ã¤ÈÊѹ¹¤µ¤ì¤Þ¤·¤¿¡£ + ÅϤµ¤ì¤ë°ú¿ô¤ÏÂçÉý¤ËÊѹ¹¤µ¤ì¡¢¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£

    + +
      +
    • apr_pool_t *p
    • +
    • apr_pool_t *plog
    • +
    • apr_pool_t *ptemp
    • +
    • server_rec *s
    • +
    + + +

    ¥Ç¡¼¥¿·¿

    +

    ¥Ç¡¼¥¿·¿¤Î¤Û¤È¤ó¤É¤Ï APR ¤Ë°Ü¤µ¤ì¤Þ¤·¤¿¡£¤Ä¤Þ¤ê¡¢ + ¤¤¤¯¤Ä¤«¤Î̾Á°¤¬Á°½Ò¤Î¤è¤¦¤ËÊѹ¹¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + »Ü¤¹¤Ù¤­Êѹ¹ÅÀ¤Î´Êñ¤Ê°ìÍ÷¤ò°Ê²¼¤Ë¼¨¤·¤Þ¤¹¡£

    + +
      +
    • pool becomes apr_pool_t
    • +
    • table becomes apr_table_t
    • +
    + +
    top
    +
    +

    ¤â¤Ã¤ÈÌñ²ð¤ÊÊѹ¹ÅÀ¡Ä

    + +

    ¥Õ¥Ã¥¯¤ÎÅÐÏ¿

    +

    ¿·¤·¤¤¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤ÏºîÀ®¤·¤¿´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤Î¤Ë + °ìÏ¢¤Î¥Õ¥Ã¥¯¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤Î¥Õ¥Ã¥¯¤Ï¡¢¿·¤·¤¤´Ø¿ô + static void register_hooks(void) ¤ò»È¤Ã¤ÆÅÐÏ¿¤¹¤ë¤è¤¦¡¢ + ¥â¥¸¥å¡¼¥ë¤Ë½ñ¤­Â­¤µ¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤Î´Ø¿ô¤Ï¡¢¤Ê¤Ë¤ò¤¹¤Ù¤­¤«°ìöÍý²ò¤·¤Æ¤·¤Þ¤¨¤Ð¡¢ + ½½Ê¬¤Ë¤ï¤«¤ê¤ä¤¹¤¤¤â¤Î¤Ç¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤Î¤¢¤ë¥¹¥Æ¡¼¥¸¤Ç¸Æ¤Ó½Ð¤µ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤ + ´Ø¿ô¤ÏÅÐÏ¿¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥Ï¥ó¥É¥é¤ÏÅÐÏ¿¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£ + ´Ø¿ô¤òÅÐÏ¿¤Ç¤­¤ë¥Õ¥§¡¼¥º¤Ï¤¿¤¯¤µ¤ó¤¢¤ê¤Þ¤¹¡£ + ¤½¤ì¤¾¤ì¤Î¥Õ¥§¡¼¥º¤Ç¡¢´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ÁêÂÐŪ¤Ê½çÈ֤ϡ¢ + ¤«¤Ê¤ê¤ÎÄøÅÙÀ©¸æ¤Ç¤­¤Þ¤¹¡£

    + +

    °Ê²¼¤Ï¡¢mod_mmap_static ¤ËÄɲä·¤¿¥³¡¼¥É¤Ç¤¹:

    + +
    +static void register_hooks(void)
    +{
    +    static const char * const aszPre[]={ "http_core.c",NULL };
    +    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
    +    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
    +};
    + +

    ¤³¤³¤Ç¤Ï¸Æ¤Ó¤À¤¹¤Ù¤­Æó¤Ä¤Î´Ø¿ô¤òÅÐÏ¿¤·¤Æ¤¤¤Þ¤¹¡£°ì¤Ä¤Ï + post_config ¥¹¥Æ¡¼¥¸ÍÑ (¤Û¤È¤ó¤É¤¹¤Ù¤Æ¤Î¥â¥¸¥å¡¼¥ë + ¤Ï¤³¤ì¤¬É¬ÍפǤ¹) ¤Ç¡¢¤â¤¦°ì¤Ä¤Ï translate_name ¥Õ¥§¡¼¥ºÍѤǤ¹¡£ + ¤½¤ì¤¾¤ì¤Î´Ø¿ô¤Ï̾Á°¤Ï°ã¤¦¤±¤ì¤É¤â·Á¼°¤ÏƱ¤¸¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤ì¤Ç¤Ï¡¢·Á¼°¤Ï¤É¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¤«?

    + +

    + ap_hook_phase_name(function_name, + predecessors, successors, position); +

    + +

    »°¤Ä¤Î°ÌÃÖ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡Ä

    + +
      +
    • HOOK_FIRST
    • +
    • HOOK_MIDDLE
    • +
    • HOOK_LAST
    • +
    + +

    °ÌÃÖ¤òÄêµÁ¤¹¤ë¤Ë¤Ï¡¢¾åµ­¤Î¡Ö°ÌÃ֡פò»ØÄꤷ¡¢ + ½¤¾þ»Ò¤Ç¤¢¤ë¡ÖÀè¹Ô¡×¤È¡Ö¸å¹Ô¡×¤Ç¼ê¤ò²Ã¤¨¤Þ¤¹¡£ + ¡ÖÀè¹Ô¡×¡Ö¸å¹Ô¡×¤Ï¡¢¸Æ¤Ð¤ì¤ë¤Ù¤­´Ø¿ô¤Î¥ê¥¹¥È¤Ç¤¹¡£ + ¡ÖÀè¹Ô¡×¤Ï´Ø¿ô¤Î¼Â¹ÔÁ°¤Ë¸Æ¤Ð¤ì¤ë¤â¤Î¤Ç¡¢ + ¡Ö¸å¹Ô¡×¤Ï¼Â¹Ô¸å¤Ë¸Æ¤Ð¤ì¤ë¤â¤Î¤Ç¤¹¡£

    + +

    mod_mmap_static ¤Î¾ì¹ç¡¢post_config + ¥¹¥Æ¡¼¥¸¤Ç¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¤¬¡¢ + mmap_static_xlat ¤¬ core ¥â¥¸¥å¡¼¥ë¤¬Ì¾Á°¤ÎÊÑ´¹¤ò¼Â¹Ô¤·¤¿¸å¤Ë + ¸Æ¤Ð¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤½¤³¤Ç aszPre ¤ò»È¤Ã¤Æ HOOK_LAST ¤Î½¤¾þ»Ò¤òÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£

    + + +

    ¥â¥¸¥å¡¼¥ë¤ÎÄêµÁ

    +

    ¥â¥¸¥å¡¼¥ë¤ÎÄêµÁ¤òºîÀ®¤¹¤ëºÝ¤ËÃí°Õ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤ + ¥¹¥Æ¡¼¥¸¤Î¿ô¤Ï·ã¸º¤·¤Æ¤¤¤Þ¤¹¡£¸Å¤¤ÄêµÁ¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤·¤¿¡£

    + +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD_MODULE_STUFF,
    +    /* initializer */
    +    /* dir config creater */
    +    /* dir merger --- default is to override */
    +    /* server config */
    +    /* merge server config */
    +    /* command handlers */
    +    /* handlers */
    +    /* filename translation */
    +    /* check_user_id */
    +    /* check auth */
    +    /* check access */
    +    /* type_checker */
    +    /* fixups */
    +    /* logger */
    +    /* header parser */
    +    /* child_init */
    +    /* child_exit */
    +    /* post read-request */
    +};
    + +

    ¿·¤·¤¤¹½Â¤ÂΤϤȤäƤ⥷¥ó¥×¥ë¤Ç¤¹¡Ä

    +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD20_MODULE_STUFF,
    +    /* create per-directory config structures */
    +    /* merge per-directory config structures  */
    +    /* create per-server config structures    */
    +    /* merge per-server config structures     */
    +    /* command handlers */
    +    /* handlers */
    +    /* register hooks */
    +};
    + +

    ¤³¤Î¤¦¤Á¤Î¤¤¤¯¤Ä¤«¤Ï¸Å¤¤¤â¤Î¤«¤é¿·¤·¤¤¤â¤Î¤ËľÀÜÆɤßÂؤ¨¤é¤ì¤ë¤â¤Î¤Ç¡¢ + ¤¤¤¯¤Ä¤«¤Ï¤½¤¦¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤É¤¦¤¹¤ì¤Ð¤¤¤¤¤Î¤«¤òÍ×Ì󤷤Ƥߤޤ¹¡£

    + +

    ľÀÜÆɤßÂؤ¨¤é¤ì¤ë¥¹¥Æ¡¼¥¸:

    + +
    +
    /* ¥Ç¥£¥ì¥¯¥È¥êÀßÄêºîÀ®´Ø¿ô */
    +
    /* ¥Ç¥£¥ì¥¯¥È¥êËèÀßÄ깽¤ÂκîÀ® */
    + +
    /* ¥µ¡¼¥ÐÀßÄêºîÀ®´Ø¿ô */
    +
    /* ¥µ¡¼¥ÐËèÀßÄ깽¤ÂκîÀ® */
    + +
    /* ¥Ç¥£¥ì¥¯¥È¥êÀßÄê¥Þ¡¼¥¸´Ø¿ô */
    +
    /* ¥Ç¥£¥ì¥¯¥È¥êËèÀßÄ깽¤ÂÎ¥Þ¡¼¥¸ */
    + +
    /* ¥µ¡¼¥ÐÀßÄê¥Þ¡¼¥¸´Ø¿ô */
    +
    /* ¥µ¡¼¥ÐËèÀßÄ깽¤ÂκîÀ®¥Þ¡¼¥¸ */
    + +
    /* ¥³¥Þ¥ó¥É¡¦¥Æ¡¼¥Ö¥ë */
    +
    /* ¥³¥Þ¥ó¥É apr_table_t */
    + +
    /* ¥Ï¥ó¥É¥é */
    +
    /* ¥Ï¥ó¥É¥é */
    +
    + +

    ¸Å¤¤´Ø¿ô¤Î»Ä¤ê¤Î¤â¤Î¤Ï¥Õ¥Ã¥¯¤È¤·¤ÆÅÐÏ¿¤µ¤ì¤ë¤Ù¤­¤Ç¤¹¡£ + ¸½»þÅÀ¤Ç¼¡¤Î¤è¤¦¤Ê¥Õ¥Ã¥¯¡¦¥¹¥Æ¡¼¥¸¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡Ä

    + +
    +
    ap_hook_post_config
    +
    (°ÊÁ°¤Î _init ¥ë¡¼¥Á¥ó¤¬ÅÐÏ¿¤µ¤ì¤ë¤Ù¤­¾ì½ê¤Ç¤¹)
    + +
    ap_hook_http_method
    +
    (¥ê¥¯¥¨¥¹¥È¤«¤é HTTP ¥á¥½¥Ã¥É¤ò¼èÆÀ¤·¤Þ¤¹ (¸ß´¹ÍÑ))
    + +
    ap_hook_open_logs
    +
    (ÆÃÄê¤Î¥í¥°¤Î¥ª¡¼¥×¥ó)
    + +
    ap_hook_auth_checker
    +
    (¥ê¥½¡¼¥¹¤¬¸¢¸Â¤òɬÍפȤ¹¤ë¤«¤É¤¦¤«¤Î³Îǧ)
    + +
    ap_hook_access_checker
    +
    (¥â¥¸¥å¡¼¥ë¸ÇÍ­¤ÎÀ©Ìó¤Î³Îǧ)
    + +
    ap_hook_check_user_id
    +
    (¥æ¡¼¥¶ ID ¤È¥Ñ¥¹¥ï¡¼¥É¤Î³Îǧ)
    + +
    ap_hook_default_port
    +
    (¥µ¡¼¥Ð¤Î¥Ç¥Õ¥©¥ë¥È¡¦¥Ý¡¼¥È¤Î¼èÆÀ)
    + +
    ap_hook_pre_connection
    +
    (½èÍý¤ÎľÁ°¤ËɬÍפʤ³¤È¤ò¼Â¹Ô¡£¤¿¤À¤· accept ľ¸å¤Ë¸Æ¤Ð¤ì¤ë)
    + +
    ap_hook_process_connection
    +
    (¥×¥í¥È¥³¥ë¤Î½èÍý)
    + +
    ap_hook_child_init
    +
    (»Ò¥×¥í¥»¥ëµ¯Æ°Ä¾¸å)
    + +
    ap_hook_create_request
    +
    (??)
    + +
    ap_hook_fixups
    +
    (±þÅúÆâÍƤÎÀ¸À®¤òÊѹ¹¤¹¤ë¥é¥¹¥È¡¦¥Á¥ã¥ó¥¹)
    + +
    ap_hook_handler
    +
    (±þÅúÆâÍƤÎÀ¸À®)
    + +
    ap_hook_header_parser
    +
    (¥â¥¸¥å¡¼¥ë¤Ë¥Ø¥Ã¥À¤Î¾È²ñ¤ò¤µ¤»¤ë¡£¤Û¤È¤ó¤É¤Î¥â¥¸¥å¡¼¥ë¤Ç¤Ï»È¤ï¤ì¤Þ¤»¤ó¡£post_read_request ¤ò»È¤¤¤Þ¤¹)
    + +
    ap_hook_insert_filter
    +
    (¥Õ¥£¥ë¥¿¡¦¥Á¥§¥¤¥ó¤Ë¥Õ¥£¥ë¥¿¤òÁÞÆþ)
    + +
    ap_hook_log_transaction
    +
    (¥ê¥¯¥¨¥¹¥È¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤òµ­Ï¿¤¹¤ë)
    + +
    ap_hook_optional_fn_retrieve
    +
    (¥ª¥×¥·¥ç¥ó¤È¤·¤ÆÅÐÏ¿¤µ¤ì¤¿´Ø¿ô¤Î¼èÆÀ)
    + +
    ap_hook_post_read_request
    +
    (¥ê¥¯¥¨¥¹¥È¤òÆɤߤ³¤ó¤À¸å¡¢Â¾¤Î¥Õ¥§¡¼¥º¤ÎÁ°¤Ë¸Æ¤Ð¤ì¤ë)
    + +
    ap_hook_quick_handler
    +
    ¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤¬»Ï¤Þ¤ëÁ°¤Ë¸Æ¤Ð¤ì¤ë¡£¥­¥ã¥Ã¥·¥å¥â¥¸¥å¡¼¥ë¤¬ + »ÈÍѤ·¤Æ¤¤¤ë
    + +
    ap_hook_translate_name
    +
    (URI ¤ò¥Õ¥¡¥¤¥ë̾¤ËÊÑ´¹¤¹¤ë)
    + +
    ap_hook_type_checker
    +
    (ʸ½ñ·¿¤Î·èÄê¤ÈÀßÄê¡£¤¢¤ë¤¤¤Ï¤½¤ÎÊÒÊý)
    +
    + +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/modules.xml b/trunk/docs/manual/developer/modules.xml new file mode 100644 index 0000000000..4ddfbbedab --- /dev/null +++ b/trunk/docs/manual/developer/modules.xml @@ -0,0 +1,272 @@ + + + + + + + + +Developer Documentation + +Converting Modules from Apache 1.3 to Apache 2.0 + + +

    This is a first attempt at writing the lessons I learned + when trying to convert the mod_mmap_static module to Apache + 2.0. It's by no means definitive and probably won't even be + correct in some ways, but it's a start.

    +
    + +
    The easier changes ... + +
    Cleanup Routines +

    These now need to be of type apr_status_t and return a + value of that type. Normally the return value will be + APR_SUCCESS unless there is some need to signal an error in + the cleanup. Be aware that even though you signal an error not all code + yet checks and acts upon the error.

    +
    + +
    Initialisation Routines +

    These should now be renamed to better signify where they sit + in the overall process. So the name gets a small change from + mmap_init to mmap_post_config. The arguments + passed have undergone a radical change and now look like

    + +
      +
    • apr_pool_t *p
    • +
    • apr_pool_t *plog
    • +
    • apr_pool_t *ptemp
    • +
    • server_rec *s
    • +
    +
    + +
    Data Types +

    A lot of the data types have been moved into the APR. This means that some have had + a name change, such as the one shown above. The following is a brief + list of some of the changes that you are likely to have to make.

    + +
      +
    • pool becomes apr_pool_t
    • +
    • table becomes apr_table_t
    • +
    +
    +
    + +
    The messier changes... + +
    Register Hooks +

    The new architecture uses a series of hooks to provide for + calling your functions. These you'll need to add to your module + by way of a new function, static void register_hooks(void). + The function is really reasonably straightforward once you + understand what needs to be done. Each function that needs + calling at some stage in the processing of a request needs to + be registered, handlers do not. There are a number of phases + where functions can be added, and for each you can specify with + a high degree of control the relative order that the function + will be called in.

    + +

    This is the code that was added to mod_mmap_static:

    +
    +static void register_hooks(void)
    +{
    +    static const char * const aszPre[]={ "http_core.c",NULL };
    +    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
    +    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
    +};
    +
    + +

    This registers 2 functions that need to be called, one in + the post_config stage (virtually every module will need this + one) and one for the translate_name phase. note that while + there are different function names the format of each is + identical. So what is the format?

    + + + ap_hook_phase_name(function_name, + predecessors, successors, position); + + +

    There are 3 hook positions defined...

    + +
      +
    • HOOK_FIRST
    • +
    • HOOK_MIDDLE
    • +
    • HOOK_LAST
    • +
    + +

    To define the position you use the position and then modify + it with the predecessors and successors. Each of the modifiers + can be a list of functions that should be called, either before + the function is run (predecessors) or after the function has + run (successors).

    + +

    In the mod_mmap_static case I didn't care about the + post_config stage, but the mmap_static_xlat + must be called after the core module had done it's name + translation, hence the use of the aszPre to define a modifier to the + position HOOK_LAST.

    +
    + +
    Module Definition +

    There are now a lot fewer stages to worry about when + creating your module definition. The old defintion looked + like

    + +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD_MODULE_STUFF,
    +    /* initializer */
    +    /* dir config creater */
    +    /* dir merger --- default is to override */
    +    /* server config */
    +    /* merge server config */
    +    /* command handlers */
    +    /* handlers */
    +    /* filename translation */
    +    /* check_user_id */
    +    /* check auth */
    +    /* check access */
    +    /* type_checker */
    +    /* fixups */
    +    /* logger */
    +    /* header parser */
    +    /* child_init */
    +    /* child_exit */
    +    /* post read-request */
    +};
    +
    + +

    The new structure is a great deal simpler...

    +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD20_MODULE_STUFF,
    +    /* create per-directory config structures */
    +    /* merge per-directory config structures  */
    +    /* create per-server config structures    */
    +    /* merge per-server config structures     */
    +    /* command handlers */
    +    /* handlers */
    +    /* register hooks */
    +};
    +
    + +

    Some of these read directly across, some don't. I'll try to + summarise what should be done below.

    + +

    The stages that read directly across :

    + +
    +
    /* dir config creater */
    +
    /* create per-directory config structures */
    + +
    /* server config */
    +
    /* create per-server config structures */
    + +
    /* dir merger */
    +
    /* merge per-directory config structures */
    + +
    /* merge server config */
    +
    /* merge per-server config structures */
    + +
    /* command table */
    +
    /* command apr_table_t */
    + +
    /* handlers */
    +
    /* handlers */
    +
    + +

    The remainder of the old functions should be registered as + hooks. There are the following hook stages defined so + far...

    + +
    +
    ap_hook_post_config
    +
    this is where the old _init routines get + registered
    + +
    ap_hook_http_method
    +
    retrieve the http method from a request. (legacy)
    + +
    ap_hook_open_logs
    +
    open any specified logs
    + +
    ap_hook_auth_checker
    +
    check if the resource requires authorization
    + +
    ap_hook_access_checker
    +
    check for module-specific restrictions
    + +
    ap_hook_check_user_id
    +
    check the user-id and password
    + +
    ap_hook_default_port
    +
    retrieve the default port for the server
    + +
    ap_hook_pre_connection
    +
    do any setup required just before processing, but after + accepting
    + +
    ap_hook_process_connection
    +
    run the correct protocol
    + +
    ap_hook_child_init
    +
    call as soon as the child is started
    + +
    ap_hook_create_request
    +
    ??
    + +
    ap_hook_fixups
    +
    last chance to modify things before generating content
    + +
    ap_hook_handler
    +
    generate the content
    + +
    ap_hook_header_parser
    +
    lets modules look at the headers, not used by most modules, because + they use post_read_request for this
    + +
    ap_hook_insert_filter
    +
    to insert filters into the filter chain
    + +
    ap_hook_log_transaction
    +
    log information about the request
    + +
    ap_hook_optional_fn_retrieve
    +
    retrieve any functions registered as optional
    + +
    ap_hook_post_read_request
    +
    called after reading the request, before any other phase
    + +
    ap_hook_quick_handler
    +
    called before any request processing, used by cache modules.
    + +
    ap_hook_translate_name
    +
    translate the URI into a filename
    + +
    ap_hook_type_checker
    +
    determine and/or set the doc type
    +
    +
    +
    +
    + diff --git a/trunk/docs/manual/developer/modules.xml.ja b/trunk/docs/manual/developer/modules.xml.ja new file mode 100644 index 0000000000..bf2911af3f --- /dev/null +++ b/trunk/docs/manual/developer/modules.xml.ja @@ -0,0 +1,272 @@ + + + + + + + + +Developer Documentation + +$B%b%8%e!<%k$N(B Apache 1.3 $B$+$i(B Apache 2.0 $B$X$N0\?"(B + + +

    $B$3$NJ8=q$O(B mod_mmap_static $B%b%8%e!<%k$r(B Apache 2.0 $BMQ$K0\?"$7$?;~$K(B + $B3X$s$@7P83$r$b$H$K=q$$$?!":G=i$N +

    + +
    $B4JC1$JJQ99E@(B + +
    $B%/%j!<%s%J%C%W(B $B%k!<%A%s(B +

    $B%/%j!<%s%J%C%W%k!<%A%s$O(B apr_status_t $B7?$G$"$kI,MW$,$"$j$^$9!#(B + $B$=$7$F!"(Bapr_status_t $B7?$NCM$rJV$5$J$/$F$O$J$j$^$;$s!#(B + $B%/%j!<%s%J%C%WCf$N%(%i!<$rDLCN$9$kI,MW$,$J$1$l$P!"JV$jCM$OIaDL!"(B + ARP_SUCCESS $B$G$9!#$?$H$(%(%i!<$rDLCN$7$?$H$7$F$b!"(B + $B$9$Y$F$N%3!<%I$,$=$NDLCN$r%A%'%C%/$7$?$j!"(B + $B%(%i!<$K1~$8$?F0:n$r$9$k$o$1$G$O$J$$$3$H$K5$$r$D$1$F$/$@$5$$!#(B

    +
    + + +
    $B=i4|2=%k!<%A%s(B + +

    $B=i4|2=%k!<%A%s$O=hM}A4BN$+$i8+$F$7$C$/$j$/$k$h$&$J0UL#$rI=$9$h$&$K!"(B + $BL>A0$,JQ99$5$l$^$7$?!#$G$9$+$i!"(Bmmap_init $B$+$i(B mmap_post_config + $B$N$h$&$K$A$g$C$HJQ99$5$l$^$7$?!#(B + $BEO$5$l$k0z?t$OBgI}$KJQ99$5$l!" + +

      +
    • apr_pool_t *p
    • +
    • apr_pool_t *plog
    • +
    • apr_pool_t *ptemp
    • +
    • server_rec *s
    • +
    +
    + +
    $B%G!<%?7?(B +

    $B%G!<%?7?$N$[$H$s$I$O(B APR $B$K0\$5$l$^$7$?!#$D$^$j!"(B + $B$$$/$D$+$NL>A0$,A0=R$N$h$&$KJQ99$5$l$F$$$^$9!#(B + $B;\$9$Y$-JQ99E@$N4JC1$J0lMw$r0J2<$K<($7$^$9!#(B

    + +
      +
    • pool becomes apr_pool_t
    • +
    • table becomes apr_table_t
    • +
    +
    +
    + +
    $B$b$C$HLq2p$JJQ99E@!D(B + +
    $B%U%C%/$NEPO?(B +

    $B?7$7$$%"!<%-%F%/%A%c$G$O:n@.$7$?4X?t$r8F$S=P$9$N$K(B + $B0lO"$N%U%C%/$r;HMQ$7$^$9!#$3$N%U%C%/$O!"?7$7$$4X?t(B + static void register_hooks(void) $B$r;H$C$FEPO?$9$k$h$&!"(B + $B%b%8%e!<%k$K=q$-B-$5$J$/$F$O$J$j$^$;$s!#(B + $B$3$N4X?t$O!"$J$K$r$9$Y$-$+0lC6M}2r$7$F$7$^$($P!"(B + $B==J,$K$o$+$j$d$9$$$b$N$G$9!#(B + $B%j%/%(%9%H$N=hM}$N$"$k%9%F!<%8$G8F$S=P$5$J$/$F$O$J$i$J$$(B + $B4X?t$OEPO?$9$kI,MW$,$"$j$^$9!#%O%s%I%i$OEPO?$9$kI,MW$O$"$j$^$;$s!#(B + $B4X?t$rEPO?$G$-$k%U%'!<%:$O$?$/$5$s$"$j$^$9!#(B + $B$=$l$>$l$N%U%'!<%:$G!"4X?t$r8F$S=P$9AjBPE*$J=gHV$O!"(B + $B$+$J$j$NDxEY@)8f$G$-$^$9!#(B

    + +

    $B0J2<$O!"(Bmod_mmap_static $B$KDI2C$7$?%3!<%I$G$9(B:

    + +
    +static void register_hooks(void)
    +{
    +    static const char * const aszPre[]={ "http_core.c",NULL };
    +    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
    +    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
    +};
    +
    + +

    $B$3$3$G$O8F$S$@$9$Y$-Fs$D$N4X?t$rEPO?$7$F$$$^$9!#0l$D$O(B + post_config $B%9%F!<%8MQ(B ($B$[$H$s$I$9$Y$F$N%b%8%e!<%k(B + $B$O$3$l$,I,MW$G$9(B) $B$G!"$b$&0l$D$O(B translate_name $B%U%'!<%:MQ$G$9!#(B + $B$=$l$>$l$N4X?t$OL>A0$O0c$&$1$l$I$b7A<0$OF1$8$G$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$=$l$G$O!"7A<0$O$I$N$h$&$K$J$C$F$$$k$G$7$g$&$+(B?

    + + + ap_hook_phase_name(function_name, + predecessors, successors, position); + + +

    $B;0$D$N0LCV$,Dj5A$5$l$F$$$^$9!D(B

    + +
      +
    • HOOK_FIRST
    • +
    • HOOK_MIDDLE
    • +
    • HOOK_LAST
    • +
    + +

    $B0LCV$rDj5A$9$k$K$O!">e5-$N!V0LCV!W$r;XDj$7!"(B + $B=$>~;R$G$"$k!V@h9T!W$H!V8e9T!W$G + +

    mod_mmap_static $B$N>l9g!"(Bpost_config + $B%9%F!<%8$G$OI,MW$"$j$^$;$s$,!"(B + mmap_static_xlat $B$,(B core $B%b%8%e!<%k$,L>A0$NJQ49$r$B8F$P$l$J$1$l$P$J$j$^$;$s(B$B!#(B + $B$=$3$G(B aszPre $B$r;H$C$F(B HOOK_LAST $B$N=$>~;R$rDj5A$7$F$$$^$9!#(B

    +
    + +
    $B%b%8%e!<%k$NDj5A(B +

    $B%b%8%e!<%k$NDj5A$r:n@.$9$k:]$KCm0U$7$J$1$l$P$J$i$J$$(B + $B%9%F!<%8$N?t$O7c8:$7$F$$$^$9!#8E$$Dj5A$O + +

    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD_MODULE_STUFF,
    +    /* initializer */
    +    /* dir config creater */
    +    /* dir merger --- default is to override */
    +    /* server config */
    +    /* merge server config */
    +    /* command handlers */
    +    /* handlers */
    +    /* filename translation */
    +    /* check_user_id */
    +    /* check auth */
    +    /* check access */
    +    /* type_checker */
    +    /* fixups */
    +    /* logger */
    +    /* header parser */
    +    /* child_init */
    +    /* child_exit */
    +    /* post read-request */
    +};
    + + +

    $B?7$7$$9=B$BN$O$H$C$F$b%7%s%W%k$G$9!D(B

    +
    +module MODULE_VAR_EXPORT module_name_module =
    +{
    +    STANDARD20_MODULE_STUFF,
    +    /* create per-directory config structures */
    +    /* merge per-directory config structures  */
    +    /* create per-server config structures    */
    +    /* merge per-server config structures     */
    +    /* command handlers */
    +    /* handlers */
    +    /* register hooks */
    +};
    +
    + +

    $B$3$N$&$A$N$$$/$D$+$O8E$$$b$N$+$i?7$7$$$b$N$KD>@\FI$_BX$($i$l$k$b$N$G!"(B + $B$$$/$D$+$O$=$&$G$O$"$j$^$;$s!#$I$&$9$l$P$$$$$N$+$rMWLs$7$F$_$^$9!#(B

    + +

    $BD>@\FI$_BX$($i$l$k%9%F!<%8(B:

    + +
    +
    /* $B%G%#%l%/%H%j@_Dj:n@.4X?t(B */
    +
    /* $B%G%#%l%/%H%jKh@_Dj9=B$BN:n@.(B */
    + +
    /* $B%5!<%P@_Dj:n@.4X?t(B */
    +
    /* $B%5!<%PKh@_Dj9=B$BN:n@.(B */
    + +
    /* $B%G%#%l%/%H%j@_Dj%^!<%84X?t(B */
    +
    /* $B%G%#%l%/%H%jKh@_Dj9=B$BN%^!<%8(B */
    + +
    /* $B%5!<%P@_Dj%^!<%84X?t(B */
    +
    /* $B%5!<%PKh@_Dj9=B$BN:n@.%^!<%8(B */
    + +
    /* $B%3%^%s%I!&%F!<%V%k(B */
    +
    /* $B%3%^%s%I(B apr_table_t */
    + +
    /* $B%O%s%I%i(B */
    +
    /* $B%O%s%I%i(B */
    +
    + +

    $B8E$$4X?t$N;D$j$N$b$N$O%U%C%/$H$7$FEPO?$5$l$k$Y$-$G$9!#(B + $B8=;~E@$G + +

    +
    ap_hook_post_config
    +
    ($B0JA0$N(B _init $B%k!<%A%s$,EPO?$5$l$k$Y$->l=j$G$9(B)
    + +
    ap_hook_http_method
    +
    ($B%j%/%(%9%H$+$i(B HTTP $B%a%=%C%I$r + +
    ap_hook_open_logs
    +
    ($BFCDj$N%m%0$N%*!<%W%s(B)
    + +
    ap_hook_auth_checker
    +
    ($B%j%=!<%9$,8"8B$rI,MW$H$9$k$+$I$&$+$N3NG'(B)
    + +
    ap_hook_access_checker
    +
    ($B%b%8%e!<%k8GM-$N@)Ls$N3NG'(B)
    + +
    ap_hook_check_user_id
    +
    ($B%f!<%6(B ID $B$H%Q%9%o!<%I$N3NG'(B)
    + +
    ap_hook_default_port
    +
    ($B%5!<%P$N%G%U%)%k%H!&%]!<%H$N + +
    ap_hook_pre_connection
    +
    ($B=hM}$ND>A0$KI,MW$J$3$H$r8e$K8F$P$l$k(B)
    + +
    ap_hook_process_connection
    +
    ($B%W%m%H%3%k$N=hM}(B)
    + +
    ap_hook_child_init
    +
    ($B;R%W%m%;%k5/F0D>8e(B)
    + +
    ap_hook_create_request
    +
    (??)
    + +
    ap_hook_fixups
    +
    ($B1~EzFbMF$N@8@.$rJQ99$9$k%i%9%H!&%A%c%s%9(B)
    + +
    ap_hook_handler
    +
    ($B1~EzFbMF$N@8@.(B)
    + +
    ap_hook_header_parser
    +
    ($B%b%8%e!<%k$K%X%C%@$N>H2q$r$5$;$k!#$[$H$s$I$N%b%8%e!<%k$G$O;H$o$l$^$;$s!#(Bpost_read_request $B$r;H$$$^$9(B)
    + +
    ap_hook_insert_filter
    +
    ($B%U%#%k%?!&%A%'%$%s$K%U%#%k%?$rA^F~(B)
    + +
    ap_hook_log_transaction
    +
    ($B%j%/%(%9%H$K$D$$$F$N>pJs$r5-O?$9$k(B)
    + +
    ap_hook_optional_fn_retrieve
    +
    ($B%*%W%7%g%s$H$7$FEPO?$5$l$?4X?t$N + +
    ap_hook_post_read_request
    +
    ($B%j%/%(%9%H$rFI$_$3$s$@8e!"B>$N%U%'!<%:$NA0$K8F$P$l$k(B)
    + +
    ap_hook_quick_handler
    +
    $B%j%/%(%9%H$N=hM}$,;O$^$kA0$K8F$P$l$k!#%-%c%C%7%e%b%8%e!<%k$,(B + $B;HMQ$7$F$$$k(B
    + +
    ap_hook_translate_name
    +
    (URI $B$r%U%!%$%kL>$KJQ49$9$k(B)
    + +
    ap_hook_type_checker
    +
    ($BJ8=q7?$N7hDj$H@_Dj!#$"$k$$$O$=$NJRJ}(B)
    +
    +
    +
    + diff --git a/trunk/docs/manual/developer/modules.xml.meta b/trunk/docs/manual/developer/modules.xml.meta new file mode 100644 index 0000000000..850ae5ce82 --- /dev/null +++ b/trunk/docs/manual/developer/modules.xml.meta @@ -0,0 +1,12 @@ + + + + modules + /developer/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/developer/request.html b/trunk/docs/manual/developer/request.html new file mode 100644 index 0000000000..547707246a --- /dev/null +++ b/trunk/docs/manual/developer/request.html @@ -0,0 +1,3 @@ +URI: request.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/request.html.en b/trunk/docs/manual/developer/request.html.en new file mode 100644 index 0000000000..f4a664d68c --- /dev/null +++ b/trunk/docs/manual/developer/request.html.en @@ -0,0 +1,260 @@ + + + +Request Processing in Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Request Processing in Apache 2.0

    +
    +

    Available Languages:  en 

    +
    + +

    Warning

    +

    Warning - this is a first (fast) draft that needs further + revision!

    +
    + +

    Several changes in Apache 2.0 affect the internal request + processing mechanics. Module authors need to be aware of these + changes so they may take advantage of the optimizations and + security enhancements.

    + +

    The first major change is to the subrequest and redirect + mechanisms. There were a number of different code paths in + Apache 1.3 to attempt to optimize subrequest or redirect + behavior. As patches were introduced to 2.0, these + optimizations (and the server behavior) were quickly broken due + to this duplication of code. All duplicate code has been folded + back into ap_process_request_internal() to prevent + the code from falling out of sync again.

    + +

    This means that much of the existing code was 'unoptimized'. + It is the Apache HTTP Project's first goal to create a robust + and correct implementation of the HTTP server RFC. Additional + goals include security, scalability and optimization. New + methods were sought to optimize the server (beyond the + performance of Apache 1.3) without introducing fragile or + insecure code.

    +
    + +
    top
    +
    +

    The Request Processing Cycle

    +

    All requests pass through ap_process_request_internal() + in request.c, including subrequests and redirects. If a module + doesn't pass generated requests through this code, the author is cautioned + that the module may be broken by future changes to request + processing.

    + +

    To streamline requests, the module author can take advantage + of the hooks offered to drop out of the request cycle early, or + to bypass core Apache hooks which are irrelevant (and costly in + terms of CPU.)

    +
    top
    +
    +

    The Request Parsing Phase

    +

    Unescapes the URL

    +

    The request's parsed_uri path is unescaped, once and only + once, at the beginning of internal request processing.

    + +

    This step is bypassed if the proxyreq flag is set, or the + parsed_uri.path element is unset. The module has no further + control of this one-time unescape operation, either failing to + unescape or multiply unescaping the URL leads to security + reprecussions.

    + + +

    Strips Parent and This Elements from the + URI

    +

    All /../ and /./ elements are + removed by ap_getparents(). This helps to ensure + the path is (nearly) absolute before the request processing + continues.

    + +

    This step cannot be bypassed.

    + + +

    Initial URI Location Walk

    +

    Every request is subject to an + ap_location_walk() call. This ensures that + <Location> sections + are consistently enforced for all requests. If the request is an internal + redirect or a sub-request, it may borrow some or all of the processing + from the previous or parent request's ap_location_walk, so this step + is generally very efficient after processing the main request.

    + + +

    translate_name

    +

    Modules can determine the file name, or alter the given URI + in this step. For example, mod_vhost_alias will + translate the URI's path into the configured virtual host, + mod_alias will translate the path to an alias path, + and if the request falls back on the core, the DocumentRoot is prepended to the request resource.

    + +

    If all modules DECLINE this phase, an error 500 is + returned to the browser, and a "couldn't translate name" error is logged + automatically.

    + + +

    Hook: map_to_storage

    +

    After the file or correct URI was determined, the + appropriate per-dir configurations are merged together. For + example, mod_proxy compares and merges the appropriate + <Proxy> sections. + If the URI is nothing more than a local (non-proxy) TRACE + request, the core handles the request and returns DONE. + If no module answers this hook with OK or DONE, + the core will run the request filename against the <Directory> and <Files> sections. If the request + 'filename' isn't an absolute, legal filename, a note is set for + later termination.

    + + +

    URI Location Walk

    +

    Every request is hardened by a second + ap_location_walk() call. This reassures that a + translated request is still subjected to the configured + <Location> sections. + The request again borrows some or all of the processing from its previous + location_walk above, so this step is almost always very + efficient unless the translated URI mapped to a substantially different + path or Virtual Host.

    + + +

    Hook: header_parser

    +

    The main request then parses the client's headers. This + prepares the remaining request processing steps to better serve + the client's request.

    + +
    top
    +
    +

    The Security Phase

    +

    Needs Documentation. Code is:

    + +
    +switch (ap_satisfies(r)) {
    +case SATISFY_ALL:
    +case SATISFY_NOSPEC:
    +    if ((access_status = ap_run_access_checker(r)) != 0) {
    +        return decl_die(access_status, "check access", r);
    +    }
    +
    +    if (ap_some_auth_required(r)) {
    +        if (((access_status = ap_run_check_user_id(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check user.  No user file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +
    +        if (((access_status = ap_run_auth_checker(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check access.  No groups file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +    }
    +    break;
    +
    +case SATISFY_ANY:
    +    if (((access_status = ap_run_access_checker(r)) != 0)) {
    +        if (!ap_some_auth_required(r)) {
    +            return decl_die(access_status, "check access", r);
    +        }
    +
    +        if (((access_status = ap_run_check_user_id(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check user.  No user file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +
    +        if (((access_status = ap_run_auth_checker(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check access.  No groups file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +    }
    +    break;
    +}
    +
    top
    +
    +

    The Preparation Phase

    +

    Hook: type_checker

    +

    The modules have an opportunity to test the URI or filename + against the target resource, and set mime information for the + request. Both mod_mime and + mod_mime_magic use this phase to compare the file + name or contents against the administrator's configuration and set the + content type, language, character set and request handler. Some modules + may set up their filters or other request handling parameters at this + time.

    + +

    If all modules DECLINE this phase, an error 500 is + returned to the browser, and a "couldn't find types" error is logged + automatically.

    + + +

    Hook: fixups

    +

    Many modules are 'trounced' by some phase above. The fixups + phase is used by modules to 'reassert' their ownership or force + the request's fields to their appropriate values. It isn't + always the cleanest mechanism, but occasionally it's the only + option.

    + +
    top
    +
    +

    The Handler Phase

    +

    This phase is not part of the processing in + ap_process_request_internal(). Many + modules prepare one or more subrequests prior to creating any + content at all. After the core, or a module calls + ap_process_request_internal() it then calls + ap_invoke_handler() to generate the request.

    + +

    Hook: insert_filter

    +

    Modules that transform the content in some way can insert + their values and override existing filters, such that if the + user configured a more advanced filter out-of-order, then the + module can move its order as need be. There is no result code, + so actions in this hook better be trusted to always succeed.

    + + +

    Hook: handler

    +

    The module finally has a chance to serve the request in its + handler hook. Note that not every prepared request is sent to + the handler hook. Many modules, such as mod_autoindex, + will create subrequests for a given URI, and then never serve the + subrequest, but simply lists it for the user. Remember not to + put required teardown from the hooks above into this module, + but register pool cleanups against the request pool to free + resources as required.

    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/request.xml b/trunk/docs/manual/developer/request.xml new file mode 100644 index 0000000000..72d5cf68b0 --- /dev/null +++ b/trunk/docs/manual/developer/request.xml @@ -0,0 +1,258 @@ + + + + + + + + +Developer Documentation + +Request Processing in Apache 2.0 + + + Warning +

    Warning - this is a first (fast) draft that needs further + revision!

    +
    + +

    Several changes in Apache 2.0 affect the internal request + processing mechanics. Module authors need to be aware of these + changes so they may take advantage of the optimizations and + security enhancements.

    + +

    The first major change is to the subrequest and redirect + mechanisms. There were a number of different code paths in + Apache 1.3 to attempt to optimize subrequest or redirect + behavior. As patches were introduced to 2.0, these + optimizations (and the server behavior) were quickly broken due + to this duplication of code. All duplicate code has been folded + back into ap_process_request_internal() to prevent + the code from falling out of sync again.

    + +

    This means that much of the existing code was 'unoptimized'. + It is the Apache HTTP Project's first goal to create a robust + and correct implementation of the HTTP server RFC. Additional + goals include security, scalability and optimization. New + methods were sought to optimize the server (beyond the + performance of Apache 1.3) without introducing fragile or + insecure code.

    +
    + +
    The Request Processing Cycle +

    All requests pass through ap_process_request_internal() + in request.c, including subrequests and redirects. If a module + doesn't pass generated requests through this code, the author is cautioned + that the module may be broken by future changes to request + processing.

    + +

    To streamline requests, the module author can take advantage + of the hooks offered to drop out of the request cycle early, or + to bypass core Apache hooks which are irrelevant (and costly in + terms of CPU.)

    +
    + +
    The Request Parsing Phase +
    Unescapes the URL +

    The request's parsed_uri path is unescaped, once and only + once, at the beginning of internal request processing.

    + +

    This step is bypassed if the proxyreq flag is set, or the + parsed_uri.path element is unset. The module has no further + control of this one-time unescape operation, either failing to + unescape or multiply unescaping the URL leads to security + reprecussions.

    +
    + +
    Strips Parent and This Elements from the + URI +

    All /../ and /./ elements are + removed by ap_getparents(). This helps to ensure + the path is (nearly) absolute before the request processing + continues.

    + +

    This step cannot be bypassed.

    +
    + +
    Initial URI Location Walk +

    Every request is subject to an + ap_location_walk() call. This ensures that + Location sections + are consistently enforced for all requests. If the request is an internal + redirect or a sub-request, it may borrow some or all of the processing + from the previous or parent request's ap_location_walk, so this step + is generally very efficient after processing the main request.

    +
    + +
    translate_name +

    Modules can determine the file name, or alter the given URI + in this step. For example, mod_vhost_alias will + translate the URI's path into the configured virtual host, + mod_alias will translate the path to an alias path, + and if the request falls back on the core, the DocumentRoot is prepended to the request resource.

    + +

    If all modules DECLINE this phase, an error 500 is + returned to the browser, and a "couldn't translate name" error is logged + automatically.

    +
    + +
    Hook: map_to_storage +

    After the file or correct URI was determined, the + appropriate per-dir configurations are merged together. For + example, mod_proxy compares and merges the appropriate + Proxy sections. + If the URI is nothing more than a local (non-proxy) TRACE + request, the core handles the request and returns DONE. + If no module answers this hook with OK or DONE, + the core will run the request filename against the Directory and Files sections. If the request + 'filename' isn't an absolute, legal filename, a note is set for + later termination.

    +
    + +
    URI Location Walk +

    Every request is hardened by a second + ap_location_walk() call. This reassures that a + translated request is still subjected to the configured + Location sections. + The request again borrows some or all of the processing from its previous + location_walk above, so this step is almost always very + efficient unless the translated URI mapped to a substantially different + path or Virtual Host.

    +
    + +
    Hook: header_parser +

    The main request then parses the client's headers. This + prepares the remaining request processing steps to better serve + the client's request.

    +
    +
    + +
    The Security Phase +

    Needs Documentation. Code is:

    + +
    +switch (ap_satisfies(r)) {
    +case SATISFY_ALL:
    +case SATISFY_NOSPEC:
    +    if ((access_status = ap_run_access_checker(r)) != 0) {
    +        return decl_die(access_status, "check access", r);
    +    }
    +
    +    if (ap_some_auth_required(r)) {
    +        if (((access_status = ap_run_check_user_id(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check user.  No user file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +
    +        if (((access_status = ap_run_auth_checker(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check access.  No groups file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +    }
    +    break;
    +
    +case SATISFY_ANY:
    +    if (((access_status = ap_run_access_checker(r)) != 0)) {
    +        if (!ap_some_auth_required(r)) {
    +            return decl_die(access_status, "check access", r);
    +        }
    +
    +        if (((access_status = ap_run_check_user_id(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check user.  No user file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +
    +        if (((access_status = ap_run_auth_checker(r)) != 0)
    +            || !ap_auth_type(r)) {
    +            return decl_die(access_status, ap_auth_type(r)
    +                          ? "check access.  No groups file?"
    +                          : "perform authentication. AuthType not set!",
    +                          r);
    +        }
    +    }
    +    break;
    +}
    +
    +
    + +
    The Preparation Phase +
    Hook: type_checker +

    The modules have an opportunity to test the URI or filename + against the target resource, and set mime information for the + request. Both mod_mime and + mod_mime_magic use this phase to compare the file + name or contents against the administrator's configuration and set the + content type, language, character set and request handler. Some modules + may set up their filters or other request handling parameters at this + time.

    + +

    If all modules DECLINE this phase, an error 500 is + returned to the browser, and a "couldn't find types" error is logged + automatically.

    +
    + +
    Hook: fixups +

    Many modules are 'trounced' by some phase above. The fixups + phase is used by modules to 'reassert' their ownership or force + the request's fields to their appropriate values. It isn't + always the cleanest mechanism, but occasionally it's the only + option.

    +
    +
    + +
    The Handler Phase +

    This phase is not part of the processing in + ap_process_request_internal(). Many + modules prepare one or more subrequests prior to creating any + content at all. After the core, or a module calls + ap_process_request_internal() it then calls + ap_invoke_handler() to generate the request.

    + +
    Hook: insert_filter +

    Modules that transform the content in some way can insert + their values and override existing filters, such that if the + user configured a more advanced filter out-of-order, then the + module can move its order as need be. There is no result code, + so actions in this hook better be trusted to always succeed.

    +
    + +
    Hook: handler +

    The module finally has a chance to serve the request in its + handler hook. Note that not every prepared request is sent to + the handler hook. Many modules, such as mod_autoindex, + will create subrequests for a given URI, and then never serve the + subrequest, but simply lists it for the user. Remember not to + put required teardown from the hooks above into this module, + but register pool cleanups against the request pool to free + resources as required.

    +
    +
    +
    + diff --git a/trunk/docs/manual/developer/request.xml.meta b/trunk/docs/manual/developer/request.xml.meta new file mode 100644 index 0000000000..744d10fee5 --- /dev/null +++ b/trunk/docs/manual/developer/request.xml.meta @@ -0,0 +1,11 @@ + + + + request + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/developer/thread_safety.html b/trunk/docs/manual/developer/thread_safety.html new file mode 100644 index 0000000000..02f067e7c3 --- /dev/null +++ b/trunk/docs/manual/developer/thread_safety.html @@ -0,0 +1,3 @@ +URI: thread_safety.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/developer/thread_safety.html.en b/trunk/docs/manual/developer/thread_safety.html.en new file mode 100644 index 0000000000..457cc3fc4d --- /dev/null +++ b/trunk/docs/manual/developer/thread_safety.html.en @@ -0,0 +1,285 @@ + + + +Apache 2.0 Thread Safety Issues - Apache HTTP Server + + + + + +
    <-
    +

    Apache 2.0 Thread Safety Issues

    +
    +

    Available Languages:  en 

    +
    + +

    When using any of the threaded mpms in Apache 2.0 it is important + that every function called from Apache be thread safe. When linking in 3rd + party extensions it can be difficult to determine whether the resulting + server will be thread safe. Casual testing generally won't tell you this + either as thread safety problems can lead to subtle race conditons that + may only show up in certain conditions under heavy load.

    +
    + +
    top
    +
    +

    Global and static variables

    +

    When writing your module or when trying to determine if a module or + 3rd party library is thread safe there are some common things to keep in + mind.

    + +

    First, you need to recognize that in a threaded model each individual + thread has its own program counter, stack and registers. Local variables + live on the stack, so those are fine. You need to watch out for any + static or global variables. This doesn't mean that you are absolutely not + allowed to use static or global variables. There are times when you + actually want something to affect all threads, but generally you need to + avoid using them if you want your code to be thread safe.

    + +

    In the case where you have a global variable that needs to be global and + accessed by all threads, be very careful when you update it. If, for + example, it is an incrementing counter, you need to atomically increment + it to avoid race conditions with other threads. You do this using a mutex + (mutual exclusion). Lock the mutex, read the current value, increment it + and write it back and then unlock the mutex. Any other thread that wants + to modify the value has to first check the mutex and block until it is + cleared.

    + +

    If you are using APR, have a look + at the apr_atomic_* functions and the + apr_thread_mutex_* functions.

    + +
    top
    +
    +

    errno

    +

    This is a common global variable that holds the error number of the + last error that occurred. If one thread calls a low-level function that + sets errno and then another thread checks it, we are bleeding error + numbers from one thread into another. To solve this, make sure your + module or library defines _REENTRANT or is compiled with + -D_REENTRANT. This will make errno a per-thread variable + and should hopefully be transparent to the code. It does this by doing + something like this:

    + +

    + #define errno (*(__errno_location())) +

    + +

    which means that accessing errno will call + __errno_location() which is provided by the libc. Setting + _REENTRANT also forces redefinition of some other functions + to their *_r equivalents and sometimes changes + the common getc/putc macros into safer function + calls. Check your libc documentation for specifics. Instead of, or in + addition to _REENTRANT the symbols that may affect this are + _POSIX_C_SOURCE, _THREAD_SAFE, + _SVID_SOURCE, and _BSD_SOURCE.

    +
    top
    +
    +

    Common standard troublesome functions

    +

    Not only do things have to be thread safe, but they also have to be + reentrant. strtok() is an obvious one. You call it the first + time with your delimiter which it then remembers and on each subsequent + call it returns the next token. Obviously if multiple threads are + calling it you will have a problem. Most systems have a reentrant version + of of the function called strtok_r() where you pass in an + extra argument which contains an allocated char * which the + function will use instead of its own static storage for maintaining + the tokenizing state. If you are using APR you can use apr_strtok().

    + +

    crypt() is another function that tends to not be reentrant, + so if you run across calls to that function in a library, watch out. On + some systems it is reentrant though, so it is not always a problem. If + your system has crypt_r() chances are you should be using + that, or if possible simply avoid the whole mess by using md5 instead.

    + +
    top
    +
    +

    Common 3rd Party Libraries

    +

    The following is a list of common libraries that are used by 3rd party + Apache modules. You can check to see if your module is using a potentially + unsafe library by using tools such as ldd(1) and + nm(1). For PHP, for example, + try this:

    + +

    + % ldd libphp4.so
    + libsablot.so.0 => /usr/local/lib/libsablot.so.0 (0x401f6000)
    + libexpat.so.0 => /usr/lib/libexpat.so.0 (0x402da000)
    + libsnmp.so.0 => /usr/lib/libsnmp.so.0 (0x402f9000)
    + libpdf.so.1 => /usr/local/lib/libpdf.so.1 (0x40353000)
    + libz.so.1 => /usr/lib/libz.so.1 (0x403e2000)
    + libpng.so.2 => /usr/lib/libpng.so.2 (0x403f0000)
    + libmysqlclient.so.11 => /usr/lib/libmysqlclient.so.11 (0x40411000)
    + libming.so => /usr/lib/libming.so (0x40449000)
    + libm.so.6 => /lib/libm.so.6 (0x40487000)
    + libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x404a8000)
    + libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x404e7000)
    + libcrypt.so.1 => /lib/libcrypt.so.1 (0x40505000)
    + libssl.so.2 => /lib/libssl.so.2 (0x40532000)
    + libcrypto.so.2 => /lib/libcrypto.so.2 (0x40560000)
    + libresolv.so.2 => /lib/libresolv.so.2 (0x40624000)
    + libdl.so.2 => /lib/libdl.so.2 (0x40634000)
    + libnsl.so.1 => /lib/libnsl.so.1 (0x40637000)
    + libc.so.6 => /lib/libc.so.6 (0x4064b000)
    + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000) +

    + +

    In addition to these libraries you will need to have a look at any + libraries linked statically into the module. You can use nm(1) + to look for individual symbols in the module.

    +
    top
    +
    +

    Library List

    +

    Please drop a note to dev@httpd.apache.org + if you have additions or corrections to this list.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LibraryVersionThread Safe?Notes
    ASpell/PSpell ?
    Berkeley DB3.x, 4.xYesBe careful about sharing a connection across threads.
    bzip2 YesBoth low-level and high-level APIs are thread-safe. However, + high-level API requires thread-safe access to errno.
    cdb ?
    C-Client Perhapsc-client uses strtok() and + gethostbyname() which are not thread-safe on most C + library implementations. c-client's static data is meant to be shared + across threads. If strtok() and + gethostbyname() are thread-safe on your OS, c-client + may be thread-safe.
    cpdflib ?
    libcrypt ?
    Expat YesNeed a separate parser instance per thread
    FreeTDS ?
    FreeType ?
    GD 1.8.x ?
    GD 2.0.x ?
    gdbm NoErrors returned via a static gdbm_error + variable
    ImageMagick5.2.2YesImageMagick docs claim it is thread safe since version 5.2.2 (see Change log). +
    Imlib2 ?
    libjpegv6b?
    libmysqlclient YesUse mysqlclient_r library variant to ensure thread-safety. For + more information, please read http://www.mysql.com/doc/en/Threaded_clients.html.
    Ming0.2a?
    Net-SNMP5.0.x?
    OpenLDAP2.1.xYesUse ldap_r library variant to ensure + thread-safety.
    OpenSSL0.9.6gYesRequires proper usage of CRYPTO_num_locks, + CRYPTO_set_locking_callback, + CRYPTO_set_id_callback
    liboci8 (Oracle 8+)8.x,9.x?
    pdflib5.0.xYesPDFLib docs claim it is thread safe; changes.txt indicates it + has been partially thread-safe since V1.91: http://www.pdflib.com/products/pdflib/index.html.
    libpng1.0.x?
    libpng1.2.x?
    libpq (PostgreSQL)7.xYesDon't share connections across threads and watch out for + crypt() calls
    Sablotron0.95?
    zlib1.1.4YesRelies upon thread-safe zalloc and zfree functions Default is to + use libc's calloc/free which are thread-safe.
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/developer/thread_safety.xml b/trunk/docs/manual/developer/thread_safety.xml new file mode 100644 index 0000000000..db8ff09c8b --- /dev/null +++ b/trunk/docs/manual/developer/thread_safety.xml @@ -0,0 +1,291 @@ + + + + + + + + +Developer Documentation + +Apache 2.0 Thread Safety Issues + + +

    When using any of the threaded mpms in Apache 2.0 it is important + that every function called from Apache be thread safe. When linking in 3rd + party extensions it can be difficult to determine whether the resulting + server will be thread safe. Casual testing generally won't tell you this + either as thread safety problems can lead to subtle race conditons that + may only show up in certain conditions under heavy load.

    +
    + +
    Global and static variables +

    When writing your module or when trying to determine if a module or + 3rd party library is thread safe there are some common things to keep in + mind.

    + +

    First, you need to recognize that in a threaded model each individual + thread has its own program counter, stack and registers. Local variables + live on the stack, so those are fine. You need to watch out for any + static or global variables. This doesn't mean that you are absolutely not + allowed to use static or global variables. There are times when you + actually want something to affect all threads, but generally you need to + avoid using them if you want your code to be thread safe.

    + +

    In the case where you have a global variable that needs to be global and + accessed by all threads, be very careful when you update it. If, for + example, it is an incrementing counter, you need to atomically increment + it to avoid race conditions with other threads. You do this using a mutex + (mutual exclusion). Lock the mutex, read the current value, increment it + and write it back and then unlock the mutex. Any other thread that wants + to modify the value has to first check the mutex and block until it is + cleared.

    + +

    If you are using APR, have a look + at the apr_atomic_* functions and the + apr_thread_mutex_* functions.

    + +
    + +
    errno +

    This is a common global variable that holds the error number of the + last error that occurred. If one thread calls a low-level function that + sets errno and then another thread checks it, we are bleeding error + numbers from one thread into another. To solve this, make sure your + module or library defines _REENTRANT or is compiled with + -D_REENTRANT. This will make errno a per-thread variable + and should hopefully be transparent to the code. It does this by doing + something like this:

    + + + #define errno (*(__errno_location())) + + +

    which means that accessing errno will call + __errno_location() which is provided by the libc. Setting + _REENTRANT also forces redefinition of some other functions + to their *_r equivalents and sometimes changes + the common getc/putc macros into safer function + calls. Check your libc documentation for specifics. Instead of, or in + addition to _REENTRANT the symbols that may affect this are + _POSIX_C_SOURCE, _THREAD_SAFE, + _SVID_SOURCE, and _BSD_SOURCE.

    +
    + +
    Common standard troublesome functions +

    Not only do things have to be thread safe, but they also have to be + reentrant. strtok() is an obvious one. You call it the first + time with your delimiter which it then remembers and on each subsequent + call it returns the next token. Obviously if multiple threads are + calling it you will have a problem. Most systems have a reentrant version + of of the function called strtok_r() where you pass in an + extra argument which contains an allocated char * which the + function will use instead of its own static storage for maintaining + the tokenizing state. If you are using APR you can use apr_strtok().

    + +

    crypt() is another function that tends to not be reentrant, + so if you run across calls to that function in a library, watch out. On + some systems it is reentrant though, so it is not always a problem. If + your system has crypt_r() chances are you should be using + that, or if possible simply avoid the whole mess by using md5 instead.

    + +
    + +
    Common 3rd Party Libraries +

    The following is a list of common libraries that are used by 3rd party + Apache modules. You can check to see if your module is using a potentially + unsafe library by using tools such as ldd(1) and + nm(1). For PHP, for example, + try this:

    + + + % ldd libphp4.so
    + libsablot.so.0 => /usr/local/lib/libsablot.so.0 (0x401f6000)
    + libexpat.so.0 => /usr/lib/libexpat.so.0 (0x402da000)
    + libsnmp.so.0 => /usr/lib/libsnmp.so.0 (0x402f9000)
    + libpdf.so.1 => /usr/local/lib/libpdf.so.1 (0x40353000)
    + libz.so.1 => /usr/lib/libz.so.1 (0x403e2000)
    + libpng.so.2 => /usr/lib/libpng.so.2 (0x403f0000)
    + libmysqlclient.so.11 => /usr/lib/libmysqlclient.so.11 (0x40411000)
    + libming.so => /usr/lib/libming.so (0x40449000)
    + libm.so.6 => /lib/libm.so.6 (0x40487000)
    + libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x404a8000)
    + libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x404e7000)
    + libcrypt.so.1 => /lib/libcrypt.so.1 (0x40505000)
    + libssl.so.2 => /lib/libssl.so.2 (0x40532000)
    + libcrypto.so.2 => /lib/libcrypto.so.2 (0x40560000)
    + libresolv.so.2 => /lib/libresolv.so.2 (0x40624000)
    + libdl.so.2 => /lib/libdl.so.2 (0x40634000)
    + libnsl.so.1 => /lib/libnsl.so.1 (0x40637000)
    + libc.so.6 => /lib/libc.so.6 (0x4064b000)
    + /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000) +
    + +

    In addition to these libraries you will need to have a look at any + libraries linked statically into the module. You can use nm(1) + to look for individual symbols in the module.

    +
    + +
    Library List +

    Please drop a note to dev@httpd.apache.org + if you have additions or corrections to this list.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LibraryVersionThread Safe?Notes
    ASpell/PSpell ?
    Berkeley DB3.x, 4.xYesBe careful about sharing a connection across threads.
    bzip2 YesBoth low-level and high-level APIs are thread-safe. However, + high-level API requires thread-safe access to errno.
    cdb ?
    C-Client Perhapsc-client uses strtok() and + gethostbyname() which are not thread-safe on most C + library implementations. c-client's static data is meant to be shared + across threads. If strtok() and + gethostbyname() are thread-safe on your OS, c-client + may be thread-safe.
    cpdflib ?
    libcrypt ?
    Expat YesNeed a separate parser instance per thread
    FreeTDS ?
    FreeType ?
    GD 1.8.x ?
    GD 2.0.x ?
    gdbm NoErrors returned via a static gdbm_error + variable
    ImageMagick5.2.2YesImageMagick docs claim it is thread safe since version 5.2.2 (see Change log). +
    Imlib2 ?
    libjpegv6b?
    libmysqlclient YesUse mysqlclient_r library variant to ensure thread-safety. For + more information, please read http://www.mysql.com/doc/en/Threaded_clients.html.
    Ming0.2a?
    Net-SNMP5.0.x?
    OpenLDAP2.1.xYesUse ldap_r library variant to ensure + thread-safety.
    OpenSSL0.9.6gYesRequires proper usage of CRYPTO_num_locks, + CRYPTO_set_locking_callback, + CRYPTO_set_id_callback
    liboci8 (Oracle 8+)8.x,9.x?
    pdflib5.0.xYesPDFLib docs claim it is thread safe; changes.txt indicates it + has been partially thread-safe since V1.91: http://www.pdflib.com/products/pdflib/index.html.
    libpng1.0.x?
    libpng1.2.x?
    libpq (PostgreSQL)7.xYesDon't share connections across threads and watch out for + crypt() calls
    Sablotron0.95?
    zlib1.1.4YesRelies upon thread-safe zalloc and zfree functions Default is to + use libc's calloc/free which are thread-safe.
    +
    +
    diff --git a/trunk/docs/manual/developer/thread_safety.xml.meta b/trunk/docs/manual/developer/thread_safety.xml.meta new file mode 100644 index 0000000000..8f0bb9a3b6 --- /dev/null +++ b/trunk/docs/manual/developer/thread_safety.xml.meta @@ -0,0 +1,11 @@ + + + + thread_safety + /developer/ + .. + + + en + + diff --git a/trunk/docs/manual/dns-caveats.html b/trunk/docs/manual/dns-caveats.html new file mode 100644 index 0000000000..9996161f96 --- /dev/null +++ b/trunk/docs/manual/dns-caveats.html @@ -0,0 +1,11 @@ +URI: dns-caveats.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: dns-caveats.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: dns-caveats.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/dns-caveats.html.en b/trunk/docs/manual/dns-caveats.html.en new file mode 100644 index 0000000000..55bdf28f15 --- /dev/null +++ b/trunk/docs/manual/dns-caveats.html.en @@ -0,0 +1,239 @@ + + + +Issues Regarding DNS and Apache - Apache HTTP Server + + + + + +
    <-
    +

    Issues Regarding DNS and Apache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    This page could be summarized with the statement: don't + configure Apache in such a way that it relies on DNS resolution + for parsing of the configuration files. If Apache requires DNS + resolution to parse the configuration files then your server + may be subject to reliability problems (ie. it might not boot), + or denial and theft of service attacks (including users able + to steal hits from other users).

    +
    + +
    top
    +
    +

    A Simple Example

    + + +

    + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    In order for Apache to function properly, it absolutely needs + to have two pieces of information about each virtual host: the + ServerName and at least one + IP address that the server will bind and respond to. The above + example does not include the IP address, so Apache must use DNS + to find the address of www.abc.dom. If for some + reason DNS is not available at the time your server is parsing + its config file, then this virtual host will not be + configured. It won't be able to respond to any hits + to this virtual host (prior to Apache version 1.2 the server + would not even boot).

    + +

    Suppose that www.abc.dom has address 10.0.0.1. + Then consider this configuration snippet:

    + +

    + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    This time Apache needs to use reverse DNS to find the + ServerName for this virtualhost. If that reverse + lookup fails then it will partially disable the virtualhost + (prior to Apache version 1.2 the server would not even boot). + If the virtual host is name-based then it will effectively be + totally disabled, but if it is IP-based then it will mostly + work. However, if Apache should ever have to generate a full + URL for the server which includes the server name, then it will + fail to generate a valid URL.

    + +

    Here is a snippet that avoids both of these problems:

    + +

    + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    +
    top
    +
    +

    Denial of Service

    + + +

    There are (at least) two forms that denial of service + can come in. If you are running a version of Apache prior to + version 1.2 then your server will not even boot if one of the + two DNS lookups mentioned above fails for any of your virtual + hosts. In some cases this DNS lookup may not even be under your + control; for example, if abc.dom is one of your + customers and they control their own DNS, they can force your + (pre-1.2) server to fail while booting simply by deleting the + www.abc.dom record.

    + +

    Another form is far more insidious. Consider this + configuration snippet:

    + +

    + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +

    + +

    Suppose that you've assigned 10.0.0.1 to + www.abc.dom and 10.0.0.2 to + www.def.dom. Furthermore, suppose that + def.dom has control of their own DNS. With this + config you have put def.dom into a position where + they can steal all traffic destined to abc.dom. To + do so, all they have to do is set www.def.dom to + 10.0.0.1. Since they control their own DNS you can't stop them + from pointing the www.def.dom record wherever they + wish.

    + +

    Requests coming in to 10.0.0.1 (including all those where + users typed in URLs of the form + http://www.abc.dom/whatever) will all be served by + the def.dom virtual host. To better understand why + this happens requires a more in-depth discussion of how Apache + matches up incoming requests with the virtual host that will + serve it. A rough document describing this is available.

    +
    top
    +
    +

    The "main server" Address

    + + +

    The addition of name-based + virtual host support in Apache 1.1 requires Apache to know + the IP address(es) of the host that httpd + is running on. To get this address it uses either the global + ServerName + (if present) or calls the C function gethostname + (which should return the same as typing "hostname" at the + command prompt). Then it performs a DNS lookup on this address. + At present there is no way to avoid this lookup.

    + +

    If you fear that this lookup might fail because your DNS + server is down then you can insert the hostname in + /etc/hosts (where you probably already have it so + that the machine can boot properly). Then ensure that your + machine is configured to use /etc/hosts in the + event that DNS fails. Depending on what OS you are using this + might be accomplished by editing /etc/resolv.conf, + or maybe /etc/nsswitch.conf.

    + +

    If your server doesn't have to perform DNS for any other + reason then you might be able to get away with running Apache + with the HOSTRESORDER environment variable set to + "local". This all depends on what OS and resolver libraries you + are using. It also affects CGIs unless you use + mod_env to control the environment. It's best + to consult the man pages or FAQs for your OS.

    +
    top
    +
    +

    Tips to Avoid These Problems

    + + +
      +
    • + use IP addresses in + VirtualHost +
    • + +
    • + use IP addresses in + Listen +
    • + +
    • + ensure all virtual hosts have an explicit + ServerName +
    • + +
    • create a <VirtualHost _default_:*> + server that has no pages to serve
    • +
    +
    top
    +
    +

    Appendix: Future Directions

    + + +

    The situation regarding DNS is highly undesirable. For + Apache 1.2 we've attempted to make the server at least continue + booting in the event of failed DNS, but it might not be the + best we can do. In any event, requiring the use of explicit IP + addresses in configuration files is highly undesirable in + today's Internet where renumbering is a necessity.

    + +

    A possible work around to the theft of service attack + described above would be to perform a reverse DNS lookup on the + IP address returned by the forward lookup and compare the two + names -- in the event of a mismatch, the virtualhost would be + disabled. This would require reverse DNS to be configured + properly (which is something that most admins are familiar with + because of the common use of "double-reverse" DNS lookups by + FTP servers and TCP wrappers).

    + +

    In any event, it doesn't seem possible to reliably boot a + virtual-hosted web server when DNS has failed unless IP + addresses are used. Partial solutions such as disabling + portions of the configuration might be worse than not booting + at all depending on what the webserver is supposed to + accomplish.

    + +

    As HTTP/1.1 is deployed and browsers and proxies start + issuing the Host header it will become possible to + avoid the use of IP-based virtual hosts entirely. In this case, + a webserver has no requirement to do DNS lookups during + configuration. But as of March 1997 these features have not + been deployed widely enough to be put into use on critical + webservers.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dns-caveats.html.ja.euc-jp b/trunk/docs/manual/dns-caveats.html.ja.euc-jp new file mode 100644 index 0000000000..f09647e167 --- /dev/null +++ b/trunk/docs/manual/dns-caveats.html.ja.euc-jp @@ -0,0 +1,241 @@ + + + +DNS ¤È Apache ¤Ë¤Þ¤Ä¤ï¤ëÃí°Õ»ö¹à - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    DNS ¤È Apache ¤Ë¤Þ¤Ä¤ï¤ëÃí°Õ»ö¹à

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ËÜʸ½ñ¤ÎÆâÍƤϼ¡¤Î°ì¸À¤Ë¿Ô¤­¤Þ¤¹¡£¡ÖApache ¤¬ÀßÄê¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤à¤È¤­¤Ë + DNS ¤ò»ÈÍѤ¹¤ëɬÍפ¬¤Ê¤¤¤è¤¦¤Ë¤·¤Æ²¼¤µ¤¤¡×¡£Apache ¤¬ÀßÄê¥Õ¥¡¥¤¥ë¤ò + Æɤ߹þ¤à¤È¤­¤Ë DNS ¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¡¢¿®ÍêÀ­¤ÎÌäÂê + (µ¯Æ°¤·¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó) ¤ä¥µ¡¼¥Ó¥¹µñÈݤäÅðÍÑ¥¢¥¿¥Ã¥¯ + (¾¤Î¥æ¡¼¥¶¤«¤é¥Ò¥Ã¥È¤òÅð¤à¤³¤È¤ò´Þ¤ß¤Þ¤¹) + ¤ÎÌäÂê¤ËľÌ̤¹¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    ´Êñ¤ÊÎã

    + + +

    + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    Apache ¤¬Àµ¾ï¤Ëµ¡Ç½¤¹¤ë¤Ë¤Ï¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Ëɬ¤ºÆó¤Ä¤Î + ¾ðÊó¤¬É¬Íפˤʤê¤Þ¤¹¡£¤½¤ì¤Ï¡¢ + ServerName + ¤È¡¢¤½¤Î¥µ¡¼¥Ð¤¬±þÅú¤¹¤ë¤¿¤á¤Î IP (ºÇÄã°ì¤Ä) ¤Ç¤¹¡£ + ¾åµ­Îã¤Ç¤Ï IP ¥¢¥É¥ì¥¹¤ò´Þ¤ó¤Ç¤¤¤Þ¤»¤ó¤Î¤Ç¡¢Apache ¤Ï DNS + ¤ò»ÈÍѤ·¤Æ www.abc.dom ¤ò¸«¤Ä¤±¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ²¿¤é¤«¤ÎÍýͳ¤ÇÀßÄê¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤ó¤Ç¤¤¤ë¤È¤­¤Ë DNS + ¤¬ÍøÍѤǤ­¤Ê¤«¤Ã¤¿¾ì¹ç¡¢ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÏÀßÄꤵ¤ì¤Þ¤»¤ó¡£ + ¤½¤·¤Æ¡¢¤½¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ¹¤ë¥Ò¥Ã¥È¤Ë¤Ï±þÅú¤¬¤Ê¤µ¤ì¤Þ¤»¤ó + (Apache 1.2 °ÊÁ°¤Ç¤Ïµ¯Æ°¤¹¤é¤·¤Þ¤»¤ó)¡£

    + +

    www.abc.dom ¤Î¥¢¥É¥ì¥¹¤¬ 10.0.0.1 + ¤À¤È¤·¤Þ¤¹¡£¤Ç¤Ï¡¢¼¡¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ¹Í¤¨¤Æ¤ß¤Þ¤·¤ç¤¦¡£

    + +

    + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    ¸½ºß¤Î¥ê¥ê¡¼¥¹¤Ç¤Ï Apache ¤Ï DNS µÕ°ú¤­¤ò»ÈÍѤ·¤Æ + ¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î ServerName + ¤ò¸«¤Ä¤±¤Þ¤¹¡£ + ¤½¤ÎµÕ°ú¤­¤¬¼ºÇÔ¤·¤¿¾ì¹ç¤ÏÉôʬŪ¤Ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò̵¸ú¤Ë¤·¤Þ¤¹ + (Apache 1.2 ¤è¤êÁ°¤Ç¤Ïµ¯Æ°¤¹¤é¤·¤Þ¤»¤ó)¡£ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬Ì¾Á°¥Ù¡¼¥¹¤Ç¤¢¤ì¤Ð´°Á´¤Ë̵¸ú¤Ë¤Ê¤ê¤Þ¤¹¤¬¡¢ + IP ¥Ù¡¼¥¹¤Ç¤¢¤ì¤Ð³µ¤ÍÆ°ºî¤·¤Þ¤¹¡£¤·¤«¤·¤Ê¤¬¤é¡¢¥µ¡¼¥Ð̾¤ò + ´Þ¤à´°Á´¤Ê URL ¤òÀ¸À®¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¾ì¹ç¤Ï¡¢Àµ¤·¤¤ URL + ¤ÎÀ¸À®¤¬¤Ç¤­¤Þ¤»¤ó¡£

    + +

    ¼¡¤ÎÎã¤Ï¾åµ­¤ÎÌäÂê¤ò²ò·è¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    +
    top
    +
    +

    ¥µ¡¼¥Ó¥¹µñÈÝ

    + + +

    ¥µ¡¼¥Ó¥¹µñÈݤ¬µ¯¤³¤ë¾ì¹ç¡¢(¾¯¤Ê¤¯¤È¤â) Æó¤Ä¤Î¥±¡¼¥¹¤¬¤¢¤ê¤Þ¤¹¡£ + Apache 1.2 ¤è¤êÁ°¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¾ì¹ç¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¤¿¤á¤Î + ¾åµ­¤ÎÆó¤Ä¤Î DNS ¸¡º÷¤Î¤¦¤Á°ì¤Ä¼ºÇÔ¤¹¤ì¤Ðµ¯Æ°¤¹¤é¤·¤Þ¤»¤ó¡£ + ¤½¤·¤Æ¤³¤Î DNS ¸¡º÷¤¬¼«Ê¬¤ÎÀ©¸æ²¼¤Ë¤¹¤é¤Ê¤¤¾ì¹ç¤â¤¢¤ê¤¨¤Þ¤¹¡£ + Î㤨¤Ð¡¢abc.dom ¤¬¸ÜµÒ¤Î¥µ¡¼¥Ð¤Î°ì¤Ä¤Ç¡¢ + DNS ¤Ï¸ÜµÒ¼«¿È¤Ç´ÉÍý¤·¤Æ¤¤¤ë¾ì¹ç¡¢Ã±¤Ë + www.abc.dom ¥ì¥³¡¼¥É¤òºï½ü¤¹¤ë¤À¤±¤Ç¡¢ + (1.2 ¤è¤êÁ°¤Î) ¥µ¡¼¥Ð¤òµ¯Æ°ÉÔǽ¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤â¤¦°ì¤Ä¤Î¥±¡¼¥¹¤Ï¡¢¤è¤êµ¤ÉÕ¤­¤Ë¤¯¤¤¤â¤Î¤Ç¤¹¡£ + ¼¡¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ¹Í¤¨¤Æ¤ß¤Þ¤·¤ç¤¦¡£

    + +

    + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +

    + +

    10.0.0.1 ¤ò www.abc.dom ¤Ë¡¢ + 10.0.0.2 ¤ò www.def.dom ¤Ë³ä¤êÅö¤Æ¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£ + ¤Þ¤¿¡¢def.dom ¤Ï¸ÜµÒ¼«¿È¤Î DNS + ¤ÎÀ©¸æ²¼¤Ë¤¢¤ë¤È¤·¤Þ¤¹¡£¤³¤ÎÀßÄê¤Ç¡¢abc.dom + ¤Ë¸þ¤±¤é¤ì¤¿¥È¥é¥Õ¥£¥Ã¥¯Á´¤Æ¤òÃ¥¤¦¤³¤È¤¬¤Ç¤­¤ë°ÌÃÖ¤Ë + def.dom ¤òÀßÃ֤Ǥ­¤Æ¤¤¤Þ¤¹¡£¸å¤Ïñ¤Ë + www.def.dom ¤¬ 10.0.0.1 ¤ò»²¾È¤¹¤ë¤è¤¦¤Ë + ÀßÄꤹ¤ë¤À¤±¤Ç¤¹¡£DNS ¤Ï¸ÜµÒ¦¤Î DNS ¤Ç¥³¥ó¥È¥í¡¼¥ë¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢ + www.def.dom ¥ì¥³¡¼¥É¤¬¹¥¤­¤Ê¾ì½ê¤ò»Ø¤¹¤è¤¦¤Ë + ÀßÄê¤Ç¤­¤Æ¤·¤Þ¤¦¤Î¤ò»ß¤á¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£

    + +

    10.0.0.1 ¤ËÂФ¹¤ë¥ê¥¯¥¨¥¹¥È + (http://www.abc.dom/whatever ·Á¼°¤Î URL + ¤òÆþÎϤ·¤¿¥æ¡¼¥¶¤«¤é¤Î¤â¤ÎÁ´¤Æ¤ò´Þ¤ß¤Þ¤¹) + ¤Ï¡¢def.dom ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç±þÅú¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ê¤³¤È¤¬²¿¸Îµ¯¤³¤ë¤«¤â¤Ã¤ÈÎɤ¯ÃΤ뤿¤á¤Ë¤Ï¡¢ + ±þÅú¤ÎɬÍפʥС¼¥Á¥ã¥ë¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¡¢ + Apache ¤¬¤É¤Î¤è¤¦¤ËÀ°¹çÀ­¤ò³ÎÊݤ¹¤ë¤«¤Ë¤Ä¤¤¤Æ¡¢ + ¿¼¤¤µÄÏÀ¤¬É¬Íפˤʤê¤Þ¤¹¡£¤ª¤ª¤¶¤Ã¤Ñ¤ÊÀâÌÀ¤Ï¤³¤Á¤é¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ¡Ö¼ç¥µ¡¼¥Ð¡×¥¢¥É¥ì¥¹

    + + +

    Apache 1.1 ¤Ç¤Î ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥µ¥Ý¡¼¥È Äɲäκݤˡ¢ + Apache ¤Ï httpd ¤Î¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¥Û¥¹¥È¤Î IP + ¥¢¥É¥ì¥¹¤òÃΤëɬÍפ¬½Ð¤Æ¤­¤Þ¤·¤¿¡£¤³¤Î¥¢¥É¥ì¥¹¤òÆÀ¤ë¤¿¤á¤Ë¡¢ + (¤â¤·¤¢¤ì¤Ð) ¥°¥í¡¼¥Ð¥ë¤Ê + ServerName ¤ò»ÈÍѤ¹¤ë¤«¡¢ + C ¸À¸ì¤Î´Ø¿ô gethostname (¥³¥Þ¥ó¥É¥×¥í¥ó¥×¥È¤Ç + hostname ¤È¥¿¥¤¥×¤·¤¿¤È¤­¤ÈƱ¤¸¤â¤Î¤òÊÖ¤·¤Þ¤¹) + ¤ò¸Æ¤Ó½Ð¤¹¤«¤ò¤·¤Þ¤¹¡£ + ¤½¤Î¸å¡¢ÆÀ¤é¤ì¤¿¥¢¥É¥ì¥¹¤Ç DNS ¸¡º÷¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ¸½ºß¤Î¤È¤³¤í¡¢¤³¤Î DNS ¸¡º÷¤ò²óÈò¤¹¤ëÊýË¡¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    DNS ¥µ¡¼¥Ð¤¬¥À¥¦¥ó¤·¤Æ¡¢¤³¤Î¸¡º÷¤¬¤Ç¤­¤Ê¤¤»öÂÖ¤¬µ¯¤³¤ë¤³¤È¤ò + ¶²¤ì¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢/etc/hosts + ¤Ë¥Û¥¹¥È̾¤òµ­½Ò¤·¤Æ¤ª¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹ + (¥Þ¥·¥ó¤¬Àµ¾ï¤Ëµ¯Æ°¤¹¤ë¤è¤¦¤Ë´û¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó)¡£ + ¤½¤Î¾ì¹ç¡¢DNS »²¾È¤¬¼ºÇÔ¤·¤¿¾ì¹ç¤Ë¥Þ¥·¥ó¤¬ /etc/hosts + ¤ò»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤷ¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤ÎÊýË¡¤Ï¡¢¤É¤Î OS ¤ò»ÈÍѤ·¤Æ¤¤¤ë¤«¤Ë°Í¸¤·¤Þ¤¹¤¬¡¢ + /etc/resolv.conf ¤« /etc/nsswitch.conf + ¤òÊÔ½¸¤¹¤ë¤³¤È¤ÇÀßÄê¤Ç¤­¤Þ¤¹¡£

    + +

    ¤â¤·Â¾¤ÎÍýͳ¤Ç DNS ¤òÍøÍѤ¹¤ëɬÍפ¬¤Ê¤¤¾ì¹ç¤Ï¡¢ + HOSTRESORDER ´Ä¶­ÊÑ¿ô¤ò¡Ö local + ¡×¤ËÀßÄꤹ¤ë¤³¤È¤Ç¤½¤Î¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£°Ê¾å¤³¤ì¤é¤Î»öÊÁ¤Ï¡¢¤É¤ó¤Ê + OS ¡¢¥ì¥¾¥ë¥Ð¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ·¤Æ¤¤¤ë¤«¤Ë°Í¸¤·¤Þ¤¹¡£¤Þ¤¿¡¢ + mod_env ¤ò»ÈÍѤ·¤Æ´Ä¶­ÊÑ¿ô¤òÀ©¸æ¤·¤Ê¤¤¸Â¤ê¡¢ + CGI ¤Ë¤â±Æ¶Á¤òÍ¿¤¨¤Þ¤¹¡£man ¥Ú¡¼¥¸¤ä»ÈÍѤ·¤Æ¤¤¤ë OS + ¤Î FAQ ¤ÇÄ´¤Ù¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    °Ê¾å¤ÎÌäÂê¤ò²ò·è¤¹¤ëÊýË¡

    + + +
      +
    • + VirtualHost + ¤Ç IP ¥¢¥É¥ì¥¹¤ò»ÈÍѤ¹¤ë¡£ +
    • + +
    • + Listen + ¤Ç IP ¥¢¥É¥ì¥¹¤ò»ÈÍѤ¹¤ë¡£ +
    • + +
    • + Á´¤Æ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬ÌÀ¼¨Åª¤Ë + ServerName + ¤ò»ý¤Ä¤è¤¦¤Ë¤¹¤ë¡£ +
    • + +
    • ²¿¤â±þÅú¤·¤Ê¤¤ + <VirtualHost _default_:*> + ¥µ¡¼¥Ð¤òºî¤ë¡£
    • +
    +
    top
    +
    +

    ÉÕÏ¿: ¾­ÍèŪ¤ÊÊý¸þÀ­

    + + +

    DNS ¤Ë´Ø¤·¤Æ¡¢¸½¾õ¤ÏÁ´¤¯µ¹¤·¤¯¤¢¤ê¤Þ¤»¤ó¡£Apache 1.2 ¤Ç¡¢ + DNS ¤Î¥¤¥Ù¥ó¥È¤¬¼ºÇÔ¤·¤Æ¤â¾¯¤Ê¤¯¤È¤âµ¯Æ°¥×¥í¥»¥¹¤¬Â³¤¯¤è¤¦¤Ë¤·¤Þ¤·¤¿¤¬¡¢ + ¤³¤ì¤¬ºÇ¹â¤Î²ò·èÊýË¡¤Ç¤Ï¤Ê¤¤¤Ç¤·¤ç¤¦¡£¥¢¥É¥ì¥¹¤ÎºÆ³ä¤êÅö¤Æ¤¬É¬Í×ÉÔ²ÄÈò + ¤È¤Ê¤Ã¤Æ¤¤¤ëº£Æü¤Î¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ë¤ª¤¤¤Æ¤Ï¡¢ + ÀßÄê¥Õ¥¡¥¤¥ë¤ÎÃæ¤ÇÌÀ¼¨Åª¤Ê IP ¥¢¥É¥ì¥¹¤òÍ׵᤹¤ë»ÅÍͤϡ¢ + Á´¤¯µ¹¤·¤¯¤¢¤ê¤Þ¤»¤ó¡£

    + +

    ÅðÍѤΥµ¡¼¥Ó¥¹¥¢¥¿¥Ã¥¯¤Ë´Ø¤·¤Æ¹Ô¤Ê¤¦¤Ù¤­»ö¤Ï¡¢ + DNS ½ç°ú¤­¤ò¹Ô¤Ê¤Ã¤ÆÆÀ¤é¤ì¤¿¥¢¥É¥ì¥¹¤ËÂФ¹¤ë DNS + µÕ°ú¤­¤ò¹Ô¤Ê¤Ã¤Æ¡¢Æó¤Ä¤Î̾Á°¤òÈæ³Ó¤¹¤ë¤³¤È¤Ç¤¹¡£ + ¤³¤ÎÆó¤Ä¤¬°ìÃפ·¤Ê¤±¤ì¤Ð¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï̵¸ú¤Ë¤Ê¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¤³¤¦¤¹¤ë¤¿¤á¤Ë¤ÏµÕ°ú¤­ DNS ¤¬Å¬ÀÚ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹ + (FTP ¥µ¡¼¥Ð¤ä TCP ¥é¥Ã¥Ñ¡¼¤Î¤ª¤«¤²¤Ç¡ÖÆó½ÅµÕ°ú¤­¡×DNS ¤Ï°ìÈÌŪ¤Ë + ¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢´ÉÍý¼Ô¤Ë¤Ï¤ªÆëÀ÷¤ß¤â¤Î¤Ç¤·¤ç¤¦)¡£

    + +

    IP ¥¢¥É¥ì¥¹¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Ê¤¯¤Æ DNS ¤¬¼ºÇÔ¤·¤¿¾ì¹ç¤Ï¡¢ + ¤É¤¦¤·¤Æ¤â¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¿®ÍêÀ­¤ò³ÎÊݤ·¤Æ + µ¯Æ°¤µ¤»¤ë¤³¤È¤ÏÉÔ²Äǽ¤Î¤è¤¦¤Ç¤¹¡£ + ÀßÄê¤Î°ìÉô¤ò̵¸ú¤Ë¤¹¤ë¤È¤¤¤¦¤è¤¦¤ÊÉôʬŪ¤Ê²ò·è¤Ç¤Ï¡¢ + ¥µ¡¼¥Ð¤¬²¿¤ò¤¹¤ë¤è¤¦¤Ë¤¹¤ë¤«¤Ë¤â¤è¤ê¤Þ¤¹¤¬¡¢ + ¤½¤Î¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤Ê¤¤¤è¤ê³Î¼Â¤Ë°­¤¤¾õ¶·¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    + +

    HTTP/1.1 ¤¬³«È¯¤µ¤ì¡¢¥Ö¥é¥¦¥¶¤ä¥×¥í¥­¥·¤¬ Host + ¥Ø¥Ã¥À¤òȯ¹Ô¤¹¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤Î¤Ç¡¢IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + Á´¤¯»ÈÍѤ·¤Ê¤¯¤Æ¤âºÑ¤à¤è¤¦¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤³¤Î¾ì¹ç¡¢¥¦¥§¥Ö¥µ¡¼¥Ð¤ÏÀßÄêÃæ¤Ë DNS »²¾È¤ò¤·¤Ê¤¯¤Æ¤âºÑ¤ß¤Þ¤¹¡£ + ¤·¤«¤· 1997 ǯ 3 ·î»þÅÀ¤Î¾õ¶·¤Ç¤Ï¡¢ + ¾¦ÍÑ¥ì¥Ù¥ë¤Î¥¦¥§¥Ö¥µ¡¼¥Ð¤Ç»ÈÍѤǤ­¤ë¤Û¤É¤Ë¤Ï¡¢ + ¤³¤ì¤é¤Îµ¡Ç½¤Ï¹­¤¯³«È¯¤¬¿Ê¤ó¤Ç¤¤¤Þ¤»¤ó¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dns-caveats.html.ko.euc-kr b/trunk/docs/manual/dns-caveats.html.ko.euc-kr new file mode 100644 index 0000000000..b3296d2d4e --- /dev/null +++ b/trunk/docs/manual/dns-caveats.html.ko.euc-kr @@ -0,0 +1,223 @@ + + + +DNS¿Í ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ »çÇ× - Apache HTTP Server + + + + + +
    <-
    +

    DNS¿Í ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ »çÇ×

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­¸¦ ÇÑ ¹®ÀåÀ¸·Î ¿ä¾àÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏÀ» + ÀÐÀ»¶§ DNS¸¦ ÀÇÁ¸ÇÏÁö¾Êµµ·Ï Ç϶ó. ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏÀ» Àдµ¥ + DNS°¡ ÇÊ¿äÇÏ´Ù¸é ¼­¹ö´Â ½Å·Ú¼º ¹®Á¦ (½ÃÀÛÀÌ ¾ÈµÉ ¼öµµ ÀÖ´Ù) + ȤÀº ¼­ºñ½º°ÅºÎ °ø°Ý°ú (»ç¿ëÀÚ°¡ ´Ù¸¥ »ç¿ëÀÚ¿¡ ´ëÇÑ Á¢±ÙÀ» + °¡·Îä´Â °ÍÀ» Æ÷ÇÔÇÏ¿©) ¼­ºñ½ºµµµÏ(theft of service) °ø°Ý¿¡ + ½Ã´Þ¸± ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    °£´ÜÇÑ ¿¹Á¦

    + + +

    + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§Çؼ­´Â °¢ °¡»óÈ£½ºÆ®¿¡ + ´ëÇØ µÎ°¡Áö Á¤º¸°¡ Àý´ëÀûÀ¸·Î ÇÊ¿äÇÏ´Ù. ÀÌ Á¤º¸´Â + ServerName°ú ¼­¹ö°¡ + ±â´Ù¸®°í ÀÀ´äÇÒ ÃÖ¼Ò ÇÑ°³ÀÇ IP ÁÖ¼ÒÀÌ´Ù. ÀÌ ¿¹´Â IP ÁÖ¼Ò°¡ + ¾ø±â¶§¹®¿¡, ¾ÆÆÄÄ¡´Â DNS¸¦ »ç¿ëÇÏ¿© www.abc.domÀÇ + ÁÖ¼Ò¸¦ ã¾Æ¾ß ÇÑ´Ù. ¼­¹ö°¡ ¼³Á¤ÆÄÀÏÀ» ÀÐÀ»¶§ ¾î¶² ÀÌÀ¯¿¡¼­°Ç + DNS¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù¸é °¡»óÈ£½ºÆ®¸¦ ¸¸µé ¼ö ¾ø´Ù. + ÀÌ °¡»óÈ£½ºÆ®´Â ¿äû¿¡ ÀÀ´äÇÒ ¼ö ¾ø´Ù. (¾ÆÆÄÄ¡ 1.2 ÀÌÀü + ¹öÀü¿¡¼­´Â ½ÉÁö¾î ¼­¹ö°¡ ºÎÆõµ ¾ÈÇÑ´Ù.)

    + +

    www.abc.domÀÇ ÁÖ¼Ò°¡ 10.0.0.1À̶ó°í °¡Á¤ÇÏÀÚ. + ±×¸®°í ´ÙÀ½ ¼³Á¤À» º¸¶ó:

    + +

    + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    + +

    ÀÌÁ¦ ¾ÆÆÄÄ¡´Â ÀÌ °¡»óÈ£½ºÆ®ÀÇ ServerNameÀ» + ã±âÀ§ÇØ ¿ªDNS¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ¿ªÃ£±â°¡ ½ÇÆÐÇÏ¸é ¾ÆÆÄÄ¡´Â + °¡»óÈ£½ºÆ®¸¦ ºÎºÐÀûÀ¸·Î ²ö´Ù. (¾ÆÆÄÄ¡ 1.2 ÀÌÀü ¹öÀü¿¡¼­´Â + ½ÉÁö¾î ¼­¹ö°¡ ºÎÆõµ ¾ÈÇÑ´Ù.) Áï, ÀÌ °æ¿ì À̸§±â¹Ý + °¡»óÈ£½ºÆ®¶ó¸é °¡»óÈ£½ºÆ®´Â ¿ÏÀüÈ÷ µ¿ÀÛÇÏÁö¾Ê°í, ip±â¹ÝÀ̶ó¸é + ´ëºÎºÐ µ¿ÀÛÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ ¼­¹ö¸íÀ» Æ÷ÇÔÇÏ¿© ¼­¹öÀÇ + Àüü URLÀ» ¸¸µé¾î¾ß ÇÑ´Ù¸é Á¤»óÀûÀÎ URLÀ» ¸¸µéÁö ¸øÇÑ´Ù.

    + +

    ¾Æ·¡ °æ¿ì ÀÌ µÎ°¡Áö ¹®Á¦°¡ ¾ø´Ù.

    + +

    + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +

    +
    top
    +
    +

    ¼­ºñ½º°ÅºÎ (Denial of Service)

    + + +

    (ÃÖ¼ÒÇÑ) µÎ°¡Áö Á¾·ùÀÇ ¼­ºñ½º°ÅºÎ°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. + ¾ÆÆÄÄ¡ 1.2 ÀÌÀü ¹öÀüÀÇ °æ¿ì ¾î¶² °¡»óÈ£½ºÆ®¿¡¼­¶óµµ + À§¿¡¼­ ¸»ÇÑ µÎ DNS °Ë»öÀÌ ½ÇÆÐÇÏ¸é ¼­¹ö°¡ ÄÑÁöÁöµµ ¾Ê´Â´Ù. + DNS°¡ ´ç½ÅÀÇ ±ÇÇÑ ¹ÛÀÇ ¹®Á¦ÀÏ ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, + abc.domÀÌ °í°´ »çÀÌÆ®ÀÌ°í °í°´ÀÌ ÀÚ½ÅÀÇ DNS¸¦ + °ü¸®ÇÑ´Ù¸é, www.abc.dom ·¹Äڵ带 Áö¿ì±â¸¸ Çصµ + (1.2 ÀÌÀü) ¼­¹ö´Â ½ÃÀÛÇÏÁö ¸øÇÑ´Ù.

    + +

    ÈξÀ ´õ ±³È°ÇÑ ¹æ¹ýµµ ÀÖ´Ù. ´ÙÀ½ ¼³Á¤À» »ìÆ캸ÀÚ:

    + +

    + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +

    + +

    ´ç½ÅÀÌ www.abc.dom¿¡ 10.0.0.1, + www.def.dom¿¡ 10.0.0.2¸¦ ÇÒ´çÇß´Ù°í ÇÏÀÚ. + ¶Ç, def.domÀº ÀÚü DNS¸¦ »ç¿ëÇÑ´Ù°í °¡Á¤ÇÏÀÚ. + ÀÌ ¼³Á¤°ú ÇÔ²² def.domÀ» abc.domÀ¸·Î + °¡´Â ¸ðµç Åë½ÅÀ» °¡·Îç ¼ö ÀÖ´Â Àå¼Ò¿¡ µÎ¾ú´Ù. ±×·¸´Ù¸é ±×µéÀº + www.def.domÀ» 10.0.0.1·Î ¼³Á¤Çϱ⸸ ÇÏ¸é µÈ´Ù. + ±×µéÀÌ ÀÚü DNS¸¦ »ç¿ëÇϱ⶧¹®¿¡ ´ç½ÅÀº ±×µéÀÌ ¿øÇϴµ¥·Î + www.def.dom ·¹Äڵ带 ¼³Á¤ÇÏ´Â °ÍÀ» ¸·À» ¼ö + ¾ø´Ù.

    + +

    (»ç¿ëÀÚ°¡ http://www.abc.dom/whatever Çü½ÄÀÇ + URLÀ» ÀÔ·ÂÇÏ´Â °æ¿ì¸¦ Æ÷ÇÔÇÏ¿©) 10.0.0.1·Î ¿À´Â ¸ðµç ¿äûÀ» + def.dom °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÏ°Ô µÈ´Ù. ¿Ö ÀÌ·± + ÀÏÀÌ ÀϾ´ÂÁö ÀÌÇØÇÏ·Á¸é ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô °¡»óÈ£½ºÆ®·Î + ¿À´Â ¿äûÀ» ó¸®ÇÏ´ÂÁö¿¡ ´ëÇÑ ¼³¸íÀÌ ÇÊ¿äÇÏ´Ù. + ¿©±â¿¡ ´ë°­ ¼³¸íµÇÀÖ´Ù.

    +
    top
    +
    +

    "ÁÖ¼­¹ö" ÁÖ¼Ò

    + + +

    ¾ÆÆÄÄ¡ 1.1¿¡¼­ À̸§±â¹Ý + °¡»óÈ£½ºÆ® Áö¿øÀÌ Æ÷ÇԵǾú±â¶§¹®¿¡ ¾ÆÆÄÄ¡´Â À¥¼­¹ö¸¦ + ½ÇÇàÇϴ ȣ½ºÆ®ÀÇ IP ÁÖ¼Ò(µé)¸¦ ¾Ë ÇÊ¿ä°¡ »ý°å´Ù. ÀÌ ÁÖ¼Ò´Â + (ÀÖ´Ù¸é) Àü¿ª ServerName + ȤÀº C ÇÔ¼ö gethostnameÀ¸·Î (¸í·ÉÇÁ·ÒÇÁÆ®¿¡ + "hostname"À» ÀÔ·ÂÇßÀ»¶§¿Í °°Àº °á°ú) ¾ò´Â´Ù. ±×·¯¸é ÀÌ ÁÖ¼Ò·Î + DNS °Ë»öÀ» ÇÑ´Ù. ÇöÀç ÀÌ °Ë»öÀº ÇÇÇÒ ¼ö ¾ø´Ù.

    + +

    DNS ¼­¹ö°¡ Á׾ ÀÌ °Ë»öÀÌ ½ÇÆÐÇÒ °Í °°´Ù¸é + /etc/hosts¿¡ È£½ºÆ®¸íÀ» Áý¾î³ÖÀ» ¼ö ÀÖ´Ù. + (ÄÄÇ»ÅÍ°¡ Á¤»óÀûÀ¸·Î ºÎÆõǾú´Ù¸é ¾Æ¸¶ ÀÌ¹Ì µé¾îÀÖÀ» °ÍÀÌ´Ù.) + ±×¸®°í DNS°¡ ½ÇÆÐÇÏ¸é ¼­¹ö°¡ /etc/hosts¸¦ + »ç¿ëÇÏ´ÂÁö È®ÀÎÇ϶ó. »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦¿¡ µû¶ó + /etc/resolv.conf ȤÀº /etc/nsswitch.conf¸¦ + ¼öÁ¤ÇÏ¸é µÉ °ÍÀÌ´Ù.

    + +

    ¼­¹ö°¡ ¾î¶² ÀÌÀ¯¿¡¼­°Ç DNS¸¦ °Ë»öÇÏ¸é ¾ÈµÈ´Ù¸é + HOSTRESORDER ȯ°æº¯¼ö¸¦ "local"·Î ¼³Á¤ÇÏ°í + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. mod_env¸¦ + »ç¿ëÇÏ¿© ȯ°æÀ» º¯°æÇÏÁö ¾Ê´Â´Ù¸é ÀÌ È¯°æº¯¼ö´Â + CGI¿¡µµ ¿µÇâÀ» ÁØ´Ù. ¿î¿µÃ¼Á¦ÀÇ manpage³ª FAQ¸¦ Âü°íÇÏ´Â + °ÍÀÌ ÁÁ´Ù.

    +
    top
    +
    +

    ÀÌ ¹®Á¦¸¦ ÇÇÇϱâÀ§ÇÑ ÆÁ

    + + +
      +
    • + VirtualHost¿¡ IP + ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó +
    • + +
    • + Listen¿¡ + IP ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó +
    • + +
    • + ¸ðµç °¡»óÈ£½ºÆ®´Â ¸í½ÃÀûÀ¸·Î + ServerNameÀ» + °¡Áö°Ô Ç϶ó +
    • + +
    • ¾î¶² ÆäÀÌÁöµµ ¼­ºñ½ºÇÏÁö¾Ê´Â + <VirtualHost _default_:*> ¼­¹ö¸¦ + ¸¸µé¾î¶ó
    • +
    +
    top
    +
    +

    ºÎ·Ï: ¾ÕÀ¸·Î´Â

    + + +

    DNS¿Í °ü·ÃµÈ »óȲÀº ¸Å¿ì ¹Ù¶÷Á÷ÇÏÁö ¸øÇÏ´Ù. ¾ÆÆÄÄ¡ 1.2¿¡¼­ + ¿ì¸®´Â DNS°¡ ½ÇÆÐÇÑ °æ¿ì¿¡µµ ÃÖ¼ÒÇÑ ¼­¹ö°¡ ÄÑÁöµµ·Ï ³ë·ÂÇßÁö¸¸ + °á°ú´Â ³ª»¦´Ù. ¾î·µç ¼³Á¤ÆÄÀÏ¿¡ Á÷Á¢ IP ÁÖ¼Ò¸¦ ¿ä±¸ÇÏ´Â + °ÍÀº ¹øÈ£¸¦ ´Ù½Ã ¼³Á¤ÇؾßÇÒ ¿äÁò ÀÎÅͳݿ¡ ¸Å¿ì ¹Ù¶÷Á÷ÇÏÁö + ¸øÇÏ´Ù.

    + +

    À§¿¡¼­ ¼³¸íÇÑ ¼­ºñ½ºµµµÏ °ø°ÝÀ» ¸·´Â ÇÑ°¡Áö ¹æ¹ýÀº °Ë»öÇÑ + IP ÁÖ¼Ò¿¡ ´Ù½Ã ¿ªDNS °Ë»öÀ» ÇÏ¿© µÎ À̸§À» ºñ±³ÇÏ´Â °ÍÀÌ´Ù. + ¼­·Î ´Ù¸¥ °æ¿ì °¡»óÈ£½ºÆ®¸¦ °¡µ¿ÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù. ÀÌ ¹æ¹ýÀº + ¿ªDNS°¡ ¿Ã¹Ù·Î ¼³Á¤µÇ¾ß ÇÑ´Ù. (FTP ¼­¹ö³ª TCP wrapper°¡ + "Áߺ¹-¿ª" DNS °Ë»öÀ» ÀÚÁÖ »ç¿ëÇϱ⶧¹®¿¡ ´ëºÎºÐÀÇ °ü¸®ÀÚ¿¡°Ô + Àͼ÷ÇÒ °ÍÀÌ´Ù.)

    + +

    ¾î·µç IP ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö¾ÊÀ¸¸é DNS°¡ ½ÇÆÐÇÑ °æ¿ì °¡»óÈ£½ºÆ® + À¥¼­¹ö¸¦ ¹ÏÀ» ¼ö ÀÖ°Ô ½ÃÀÛÇÒ ¼ö ¾ø´Ù. ¼³Á¤ÀÇ ÀϺθ¦ ¹«½ÃÇÏ´Â + °Í°ú °°Àº ºÎºÐÀûÀÎ ÇØ°áÃ¥Àº À¥¼­¹ö Àüü¸¦ ½ÃÀÛÇÏÁö¾Ê´Â °Íº¸´Ù + ´õ ³ª»Ü ¼öµµ ÀÖ´Ù.

    + +

    HTTP/1.1ÀÌ ³ª¿Ô°í ºê¶ó¿ìÀú¿Í ÇÁ·Ï½Ã°¡ Host + Çì´õ¸¦ º¸³»±â ½ÃÀÛÇßÀ¸¹Ç·Î IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ¿ÏÀüÈ÷ + »ç¿ëÇÏÁö¾Ê´Â °ÍÀÌ °¡´ÉÇØÁú °ÍÀÌ´Ù. ±×·¯¸é À¥¼­¹ö´Â ¼³Á¤Áß¿¡¼­ + DNS °Ë»öÀ» ÇÒ ÇÊ¿ä°¡ ¾ø¾îÁø´Ù. ±×·¯³ª 1997³â 3¿ù¿¡´Â Áß¿äÇÑ + À¥¼­¹ö¿¡ Æ÷ÇÔÇÒ Á¤µµ·Î À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ ³Î¸® »ç¿ëµÇÁö + ¾Ê¾Ò´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dns-caveats.xml b/trunk/docs/manual/dns-caveats.xml new file mode 100644 index 0000000000..a7d4a1da1c --- /dev/null +++ b/trunk/docs/manual/dns-caveats.xml @@ -0,0 +1,228 @@ + + + + + + + + + + Issues Regarding DNS and Apache + + +

    This page could be summarized with the statement: don't + configure Apache in such a way that it relies on DNS resolution + for parsing of the configuration files. If Apache requires DNS + resolution to parse the configuration files then your server + may be subject to reliability problems (ie. it might not boot), + or denial and theft of service attacks (including users able + to steal hits from other users).

    +
    + +
    + A Simple Example + + + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    In order for Apache to function properly, it absolutely needs + to have two pieces of information about each virtual host: the + ServerName and at least one + IP address that the server will bind and respond to. The above + example does not include the IP address, so Apache must use DNS + to find the address of www.abc.dom. If for some + reason DNS is not available at the time your server is parsing + its config file, then this virtual host will not be + configured. It won't be able to respond to any hits + to this virtual host (prior to Apache version 1.2 the server + would not even boot).

    + +

    Suppose that www.abc.dom has address 10.0.0.1. + Then consider this configuration snippet:

    + + + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    This time Apache needs to use reverse DNS to find the + ServerName for this virtualhost. If that reverse + lookup fails then it will partially disable the virtualhost + (prior to Apache version 1.2 the server would not even boot). + If the virtual host is name-based then it will effectively be + totally disabled, but if it is IP-based then it will mostly + work. However, if Apache should ever have to generate a full + URL for the server which includes the server name, then it will + fail to generate a valid URL.

    + +

    Here is a snippet that avoids both of these problems:

    + + + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    +
    + +
    + Denial of Service + +

    There are (at least) two forms that denial of service + can come in. If you are running a version of Apache prior to + version 1.2 then your server will not even boot if one of the + two DNS lookups mentioned above fails for any of your virtual + hosts. In some cases this DNS lookup may not even be under your + control; for example, if abc.dom is one of your + customers and they control their own DNS, they can force your + (pre-1.2) server to fail while booting simply by deleting the + www.abc.dom record.

    + +

    Another form is far more insidious. Consider this + configuration snippet:

    + + + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +
    + +

    Suppose that you've assigned 10.0.0.1 to + www.abc.dom and 10.0.0.2 to + www.def.dom. Furthermore, suppose that + def.dom has control of their own DNS. With this + config you have put def.dom into a position where + they can steal all traffic destined to abc.dom. To + do so, all they have to do is set www.def.dom to + 10.0.0.1. Since they control their own DNS you can't stop them + from pointing the www.def.dom record wherever they + wish.

    + +

    Requests coming in to 10.0.0.1 (including all those where + users typed in URLs of the form + http://www.abc.dom/whatever) will all be served by + the def.dom virtual host. To better understand why + this happens requires a more in-depth discussion of how Apache + matches up incoming requests with the virtual host that will + serve it. A rough document describing this is available.

    +
    + +
    + The "main server" Address + +

    The addition of name-based + virtual host support in Apache 1.1 requires Apache to know + the IP address(es) of the host that httpd + is running on. To get this address it uses either the global + ServerName + (if present) or calls the C function gethostname + (which should return the same as typing "hostname" at the + command prompt). Then it performs a DNS lookup on this address. + At present there is no way to avoid this lookup.

    + +

    If you fear that this lookup might fail because your DNS + server is down then you can insert the hostname in + /etc/hosts (where you probably already have it so + that the machine can boot properly). Then ensure that your + machine is configured to use /etc/hosts in the + event that DNS fails. Depending on what OS you are using this + might be accomplished by editing /etc/resolv.conf, + or maybe /etc/nsswitch.conf.

    + +

    If your server doesn't have to perform DNS for any other + reason then you might be able to get away with running Apache + with the HOSTRESORDER environment variable set to + "local". This all depends on what OS and resolver libraries you + are using. It also affects CGIs unless you use + mod_env to control the environment. It's best + to consult the man pages or FAQs for your OS.

    +
    + +
    + Tips to Avoid These Problems + +
      +
    • + use IP addresses in + VirtualHost +
    • + +
    • + use IP addresses in + Listen +
    • + +
    • + ensure all virtual hosts have an explicit + ServerName +
    • + +
    • create a <VirtualHost _default_:*> + server that has no pages to serve
    • +
    +
    + +
    + Appendix: Future Directions + +

    The situation regarding DNS is highly undesirable. For + Apache 1.2 we've attempted to make the server at least continue + booting in the event of failed DNS, but it might not be the + best we can do. In any event, requiring the use of explicit IP + addresses in configuration files is highly undesirable in + today's Internet where renumbering is a necessity.

    + +

    A possible work around to the theft of service attack + described above would be to perform a reverse DNS lookup on the + IP address returned by the forward lookup and compare the two + names -- in the event of a mismatch, the virtualhost would be + disabled. This would require reverse DNS to be configured + properly (which is something that most admins are familiar with + because of the common use of "double-reverse" DNS lookups by + FTP servers and TCP wrappers).

    + +

    In any event, it doesn't seem possible to reliably boot a + virtual-hosted web server when DNS has failed unless IP + addresses are used. Partial solutions such as disabling + portions of the configuration might be worse than not booting + at all depending on what the webserver is supposed to + accomplish.

    + +

    As HTTP/1.1 is deployed and browsers and proxies start + issuing the Host header it will become possible to + avoid the use of IP-based virtual hosts entirely. In this case, + a webserver has no requirement to do DNS lookups during + configuration. But as of March 1997 these features have not + been deployed widely enough to be put into use on critical + webservers.

    +
    +
    diff --git a/trunk/docs/manual/dns-caveats.xml.ja b/trunk/docs/manual/dns-caveats.xml.ja new file mode 100644 index 0000000000..5d4a39e8d6 --- /dev/null +++ b/trunk/docs/manual/dns-caveats.xml.ja @@ -0,0 +1,231 @@ + + + + + + + + + + DNS $B$H(B Apache $B$K$^$D$o$kCm0U;v9`(B + + +

    $BK\J8=q$NFbMF$Ol9g!"?.Mj@-$NLdBj(B + ($B5/F0$7$J$$$+$b$7$l$^$;$s(B) $B$d%5!<%S%95qH]$dEpMQ%"%?%C%/(B + ($BB>$N%f!<%6$+$i%R%C%H$rEp$`$3$H$r4^$_$^$9(B) + $B$NLdBj$KD>LL$9$k$+$b$7$l$^$;$s!#(B

    +
    + +
    + $B4JC1$JNc(B + + + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    Apache $B$,@5>o$K5!G=$9$k$K$O!"%P!<%A%c%k%[%9%HKh$KI,$:Fs$D$N(B + $B>pJs$,I,MW$K$J$j$^$9!#$=$l$O!"(B + ServerName + $B$H!"$=$N%5!<%P$,1~Ez$9$k$?$a$N(B IP ($B:GDc0l$D(B) $B$G$9!#(B + $B>e5-Nc$G$O(B IP $B%"%I%l%9$r4^$s$G$$$^$;$s$N$G!"(BApache $B$O(B DNS + $B$r;HMQ$7$F(B www.abc.dom $B$r8+$D$1$J$1$l$P$J$j$^$;$s!#(B + $B2?$i$+$NM}M3$G@_Dj%U%!%$%k$rFI$_9~$s$G$$$k$H$-$K(B DNS + $B$,MxMQ$G$-$J$+$C$?>l9g!"(B + $B%P!<%A%c%k%[%9%H$O(B$B@_Dj$5$l$^$;$s(B$B!#(B + $B$=$7$F!"$=$N%P!<%A%c%k%[%9%H$KBP$9$k%R%C%H$K$O1~Ez$,$J$5$l$^$;$s(B + (Apache 1.2 $B0JA0$G$O5/F0$9$i$7$^$;$s(B)$B!#(B

    + +

    www.abc.dom $B$N%"%I%l%9$,(B 10.0.0.1 + $B$@$H$7$^$9!#$G$O!" + + + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    $B8=:_$N%j%j!<%9$G$O(B Apache $B$O(B DNS $B5U0z$-$r;HMQ$7$F(B + $B$3$N%P!<%A%c%k%[%9%H$N(B ServerName + $B$r8+$D$1$^$9!#(B + $B$=$N5U0z$-$,<:GT$7$?>l9g$OItJ,E*$K%P!<%A%c%k%[%9%H$rL58z$K$7$^$9(B + (Apache 1.2 $B$h$jA0$G$O5/F0$9$i$7$^$;$s(B)$B!#(B + $B%P!<%A%c%k%[%9%H$,L>A0%Y!<%9$G$"$l$P40A4$KL58z$K$J$j$^$9$,!"(B + IP $B%Y!<%9$G$"$l$P35$MF0:n$7$^$9!#$7$+$7$J$,$i!"%5!<%PL>$r(B + $B4^$`40A4$J(B URL $B$r@8@.$7$J$1$l$P$J$i$J$$>l9g$O!"@5$7$$(B URL + $B$N@8@.$,$G$-$^$;$s!#(B

    + +

    $Be5-$NLdBj$r2r7h$7$F$$$^$9!#(B

    + + + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    +
    + +
    + $B%5!<%S%95qH](B + +

    $B%5!<%S%95qH]$,5/$3$k>l9g!"(B($B>/$J$/$H$b(B) $BFs$D$N%1!<%9$,$"$j$^$9!#(B + Apache 1.2 $B$h$jA0$rl9g!"%P!<%A%c%k%[%9%H$N$?$a$N(B + $B>e5-$NFs$D$N(B DNS $B8!:w$N$&$A0l$D<:GT$9$l$P5/F0$9$i$7$^$;$s!#(B + $B$=$7$F$3$N(B DNS $B8!:w$,<+J,$N@)8f2<$K$9$i$J$$>l9g$b$"$j$($^$9!#(B + $BNc$($P!"(Babc.dom $B$,8\5R$N%5!<%P$N0l$D$G!"(B + DNS $B$O8\5R<+?H$G4IM}$7$F$$$k>l9g!"C1$K(B + www.abc.dom $B%l%3!<%I$r:o=|$9$k$@$1$G!"(B + (1.2 $B$h$jA0$N(B) $B%5!<%P$r5/F0ITG=$K$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$b$&0l$D$N%1!<%9$O!"$h$j5$IU$-$K$/$$$b$N$G$9!#(B + $B + + + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +
    + +

    10.0.0.1 $B$r(B www.abc.dom $B$K!"(B + 10.0.0.2 $B$r(B www.def.dom $B$K3d$jEv$F$F$$$k$H$7$^$9!#(B + $B$^$?!"(Bdef.dom $B$O8\5R<+?H$N(B DNS + $B$N@)8f2<$K$"$k$H$7$^$9!#$3$N@_Dj$G!"(Babc.dom + $B$K8~$1$i$l$?%H%i%U%#%C%/A4$F$rC%$&$3$H$,$G$-$k0LCV$K(B + def.dom $B$r@_CV$G$-$F$$$^$9!#8e$OC1$K(B + www.def.dom $B$,(B 10.0.0.1 $B$r;2>H$9$k$h$&$K(B + $B@_Dj$9$k$@$1$G$9!#(BDNS $B$O8\5RB&$N(B DNS $B$G%3%s%H%m!<%k$5$l$F$$$k$N$G!"(B + www.def.dom $B%l%3!<%I$,9%$-$J>l=j$r;X$9$h$&$K(B + $B@_Dj$G$-$F$7$^$&$N$r;_$a$5$;$k$3$H$,$G$-$^$;$s!#(B

    + +

    10.0.0.1 $B$KBP$9$k%j%/%(%9%H(B + (http://www.abc.dom/whatever $B7A<0$N(B URL + $B$rF~NO$7$?%f!<%6$+$i$N$b$NA4$F$r4^$_$^$9(B) + $B$O!"(Bdef.dom $B%P!<%A%c%k%[%9%H$G1~Ez$5$l$^$9!#(B + $B$3$N$h$&$J$3$H$,2?8N5/$3$k$+$b$C$HNI$/CN$k$?$a$K$O!"(B + $B1~Ez$NI,MW$J%P!<%A%c%k%[%9%H$X$N%j%/%(%9%H$KBP$7$F!"(B + Apache $B$,$I$N$h$&$K@09g@-$r3NJ]$9$k$+$K$D$$$F!"(B + $B?<$$5DO@$,I,MW$K$J$j$^$9!#$*$*$6$C$Q$J@bL@$O(B$B$3$A$i(B$B$K5-=R$5$l$F$$$^$9!#(B

    +
    + +
    + $B!V<g%5!<%P!W%"%I%l%9(B + +

    Apache 1.1 $B$G$N(B $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$N%5%]!<%H(B $BDI2C$N:]$K!"(B + Apache $B$O(B httpd $B$NServerName $B$r;HMQ$9$k$+!"(B + C $B8@8l$N4X?t(B gethostname ($B%3%^%s%I%W%m%s%W%H$G(B + hostname $B$H%?%$%W$7$?$H$-$HF1$8$b$N$rJV$7$^$9(B) + $B$r8F$S=P$9$+$r$7$^$9!#(B + $B$=$N8e!"F@$i$l$?%"%I%l%9$G(B DNS $B8!:w$r9T$J$$$^$9!#(B + $B8=:_$N$H$3$m!"$3$N(B DNS $B8!:w$r2sHr$9$kJ}K!$O$"$j$^$;$s!#(B

    + +

    DNS $B%5!<%P$,%@%&%s$7$F!"$3$N8!:w$,$G$-$J$$;vBV$,5/$3$k$3$H$r(B + $B62$l$F$$$k$N$G$"$l$P!"(B/etc/hosts + $B$K%[%9%HL>$r5-=R$7$F$*$/$3$H$,$G$-$^$9(B + ($B%^%7%s$,@5>o$K5/F0$9$k$h$&$K4{$K@_Dj$5$l$F$$$k$+$b$7$l$^$;$s(B)$B!#(B + $B$=$N>l9g!"(BDNS $B;2>H$,<:GT$7$?>l9g$K%^%7%s$,(B /etc/hosts + $B$r;HMQ$9$k$h$&$K@_Dj$7$F$$$k$3$H$r3NG'$7$F$/$@$5$$!#(B + $B$=$NJ}K!$O!"$I$N(B OS $B$r;HMQ$7$F$$$k$+$K0MB8$7$^$9$,!"(B + /etc/resolv.conf $B$+(B /etc/nsswitch.conf + $B$rJT=8$9$k$3$H$G@_Dj$G$-$^$9!#(B

    + +

    $B$b$7B>$NM}M3$G(B DNS $B$rMxMQ$9$kI,MW$,$J$$>l9g$O!"(B + HOSTRESORDER $B4D6-JQ?t$r!V(B local + $B!W$K@_Dj$9$k$3$H$G$=$N$h$&$K$G$-$^$9!#0J>e$3$l$i$N;vJA$O!"$I$s$J(B + OS $B!"%l%>%k%P%i%$%V%i%j$r;HMQ$7$F$$$k$+$K0MB8$7$^$9!#$^$?!"(B + mod_env $B$r;HMQ$7$F4D6-JQ?t$r@)8f$7$J$$8B$j!"(B + CGI $B$K$b1F6A$rM?$($^$9!#(Bman $B%Z!<%8$d;HMQ$7$F$$$k(B OS + $B$N(B FAQ $B$GD4$Y$k$HNI$$$G$7$g$&!#(B

    +
    + +
    + $B0J>e$NLdBj$r2r7h$9$kJ}K!(B + +
      +
    • + VirtualHost + $B$G(B IP $B%"%I%l%9$r;HMQ$9$k!#(B +
    • + +
    • + Listen + $B$G(B IP $B%"%I%l%9$r;HMQ$9$k!#(B +
    • + +
    • + $BA4$F$N%P!<%A%c%k%[%9%H$,L@<(E*$K(B + ServerName + $B$r;}$D$h$&$K$9$k!#(B +
    • + +
    • $B2?$b1~Ez$7$J$$(B + <VirtualHost _default_:*> + $B%5!<%P$r:n$k!#(B
    • +
    +
    + +
    + $BIUO?(B: $B>-MhE*$JJ}8~@-(B + +

    DNS $B$K4X$7$F!"8=>u$OA4$/59$7$/$"$j$^$;$s!#(BApache 1.2 $B$G!"(B + DNS $B$N%$%Y%s%H$,<:GT$7$F$b>/$J$/$H$b5/F0%W%m%;%9$,B3$/$h$&$K$7$^$7$?$,!"(B + $B$3$l$,:G9b$N2r7hJ}K!$G$O$J$$$G$7$g$&!#%"%I%l%9$N:F3d$jEv$F$,I,MWIT2DHr(B + $B$H$J$C$F$$$k:#F|$N%$%s%?!<%M%C%H$K$*$$$F$O!"(B + $B@_Dj%U%!%$%k$NCf$GL@<(E*$J(B IP $B%"%I%l%9$rMW5a$9$k;EMM$O!"(B + $BA4$/59$7$/$"$j$^$;$s!#(B

    + +

    $BEpMQ$N%5!<%S%9%"%?%C%/$K4X$7$F9T$J$&$Y$-;v$O!"(B + DNS $B=g0z$-$r9T$J$C$FF@$i$l$?%"%I%l%9$KBP$9$k(B DNS + $B5U0z$-$r9T$J$C$F!"Fs$D$NL>A0$rHf3S$9$k$3$H$G$9!#(B + $B$3$NFs$D$,0lCW$7$J$1$l$P%P!<%A%c%k%[%9%H$OL58z$K$J$k$h$&$K$7$^$9!#(B + $B$3$&$9$k$?$a$K$O5U0z$-(B DNS $B$,E,@Z$K@_Dj$5$l$F$$$kI,MW$,$"$j$^$9(B + (FTP $B%5!<%P$d(B TCP $B%i%C%Q!<$N$*$+$2$G!VFs=E5U0z$-!W(BDNS $B$O0lHLE*$K(B + $B$J$C$F$$$^$9$N$G!"4IM} + +

    IP $B%"%I%l%9$,;HMQ$5$l$F$$$J$/$F(B DNS $B$,<:GT$7$?>l9g$O!"(B + $B$I$&$7$F$b%P!<%A%c%k%[%9%H%&%'%V%5!<%P$r?.Mj@-$r3NJ]$7$F(B + $B5/F0$5$;$k$3$H$OIT2DG=$N$h$&$G$9!#(B + $B@_Dj$N0lIt$rL58z$K$9$k$H$$$&$h$&$JItJ,E*$J2r7h$G$O!"(B + $B%5!<%P$,2?$r$9$k$h$&$K$9$k$+$K$b$h$j$^$9$,!"(B + $B$=$N%5!<%P$,5/F0$7$J$$$h$j3Nu67$K$J$k$G$7$g$&!#(B

    + +

    HTTP/1.1 $B$,3+H/$5$l!"%V%i%&%6$d%W%m%-%7$,(B Host + $B%X%C%@$rH/9T$9$k$h$&$K$J$C$?$N$G!"(BIP $B%Y!<%9$N%P!<%A%c%k%[%9%H$r(B + $BA4$/;HMQ$7$J$/$F$b:Q$`$h$&$K$J$k$+$b$7$l$^$;$s!#(B + $B$3$N>l9g!"%&%'%V%5!<%P$O@_DjCf$K(B DNS $B;2>H$r$7$J$/$F$b:Q$_$^$9!#(B + $B$7$+$7(B 1997 $BG/(B 3 $B7n;~E@$N>u67$G$O!"(B + $B>&MQ%l%Y%k$N%&%'%V%5!<%P$G;HMQ$G$-$k$[$I$K$O!"(B + $B$3$l$i$N5!G=$O9-$/3+H/$,?J$s$G$$$^$;$s!#(B

    +
    +
    diff --git a/trunk/docs/manual/dns-caveats.xml.ko b/trunk/docs/manual/dns-caveats.xml.ko new file mode 100644 index 0000000000..5d2c7ebf37 --- /dev/null +++ b/trunk/docs/manual/dns-caveats.xml.ko @@ -0,0 +1,209 @@ + + + + + + + + + + DNS¿Í ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ »çÇ× + + +

    ÀÌ ¹®¼­¸¦ ÇÑ ¹®ÀåÀ¸·Î ¿ä¾àÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏÀ» + ÀÐÀ»¶§ DNS¸¦ ÀÇÁ¸ÇÏÁö¾Êµµ·Ï Ç϶ó. ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏÀ» Àдµ¥ + DNS°¡ ÇÊ¿äÇÏ´Ù¸é ¼­¹ö´Â ½Å·Ú¼º ¹®Á¦ (½ÃÀÛÀÌ ¾ÈµÉ ¼öµµ ÀÖ´Ù) + ȤÀº ¼­ºñ½º°ÅºÎ °ø°Ý°ú (»ç¿ëÀÚ°¡ ´Ù¸¥ »ç¿ëÀÚ¿¡ ´ëÇÑ Á¢±ÙÀ» + °¡·Îä´Â °ÍÀ» Æ÷ÇÔÇÏ¿©) ¼­ºñ½ºµµµÏ(theft of service) °ø°Ý¿¡ + ½Ã´Þ¸± ¼ö ÀÖ´Ù.

    +
    + +
    + °£´ÜÇÑ ¿¹Á¦ + + + <VirtualHost www.abc.dom>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§Çؼ­´Â °¢ °¡»óÈ£½ºÆ®¿¡ + ´ëÇØ µÎ°¡Áö Á¤º¸°¡ Àý´ëÀûÀ¸·Î ÇÊ¿äÇÏ´Ù. ÀÌ Á¤º¸´Â + ServerName°ú ¼­¹ö°¡ + ±â´Ù¸®°í ÀÀ´äÇÒ ÃÖ¼Ò ÇÑ°³ÀÇ IP ÁÖ¼ÒÀÌ´Ù. ÀÌ ¿¹´Â IP ÁÖ¼Ò°¡ + ¾ø±â¶§¹®¿¡, ¾ÆÆÄÄ¡´Â DNS¸¦ »ç¿ëÇÏ¿© www.abc.domÀÇ + ÁÖ¼Ò¸¦ ã¾Æ¾ß ÇÑ´Ù. ¼­¹ö°¡ ¼³Á¤ÆÄÀÏÀ» ÀÐÀ»¶§ ¾î¶² ÀÌÀ¯¿¡¼­°Ç + DNS¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù¸é °¡»óÈ£½ºÆ®¸¦ ¸¸µé ¼ö ¾ø´Ù. + ÀÌ °¡»óÈ£½ºÆ®´Â ¿äû¿¡ ÀÀ´äÇÒ ¼ö ¾ø´Ù. (¾ÆÆÄÄ¡ 1.2 ÀÌÀü + ¹öÀü¿¡¼­´Â ½ÉÁö¾î ¼­¹ö°¡ ºÎÆõµ ¾ÈÇÑ´Ù.)

    + +

    www.abc.domÀÇ ÁÖ¼Ò°¡ 10.0.0.1À̶ó°í °¡Á¤ÇÏÀÚ. + ±×¸®°í ´ÙÀ½ ¼³Á¤À» º¸¶ó:

    + + + <VirtualHost 10.0.0.1>
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    + +

    ÀÌÁ¦ ¾ÆÆÄÄ¡´Â ÀÌ °¡»óÈ£½ºÆ®ÀÇ ServerNameÀ» + ã±âÀ§ÇØ ¿ªDNS¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ¿ªÃ£±â°¡ ½ÇÆÐÇÏ¸é ¾ÆÆÄÄ¡´Â + °¡»óÈ£½ºÆ®¸¦ ºÎºÐÀûÀ¸·Î ²ö´Ù. (¾ÆÆÄÄ¡ 1.2 ÀÌÀü ¹öÀü¿¡¼­´Â + ½ÉÁö¾î ¼­¹ö°¡ ºÎÆõµ ¾ÈÇÑ´Ù.) Áï, ÀÌ °æ¿ì À̸§±â¹Ý + °¡»óÈ£½ºÆ®¶ó¸é °¡»óÈ£½ºÆ®´Â ¿ÏÀüÈ÷ µ¿ÀÛÇÏÁö¾Ê°í, ip±â¹ÝÀ̶ó¸é + ´ëºÎºÐ µ¿ÀÛÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ ¼­¹ö¸íÀ» Æ÷ÇÔÇÏ¿© ¼­¹öÀÇ + Àüü URLÀ» ¸¸µé¾î¾ß ÇÑ´Ù¸é Á¤»óÀûÀÎ URLÀ» ¸¸µéÁö ¸øÇÑ´Ù.

    + +

    ¾Æ·¡ °æ¿ì ÀÌ µÎ°¡Áö ¹®Á¦°¡ ¾ø´Ù.

    + + + <VirtualHost 10.0.0.1>
    + ServerName www.abc.dom
    + ServerAdmin webgirl@abc.dom
    + DocumentRoot /www/abc
    + </VirtualHost> +
    +
    + +
    + ¼­ºñ½º°ÅºÎ (Denial of Service) + +

    (ÃÖ¼ÒÇÑ) µÎ°¡Áö Á¾·ùÀÇ ¼­ºñ½º°ÅºÎ°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. + ¾ÆÆÄÄ¡ 1.2 ÀÌÀü ¹öÀüÀÇ °æ¿ì ¾î¶² °¡»óÈ£½ºÆ®¿¡¼­¶óµµ + À§¿¡¼­ ¸»ÇÑ µÎ DNS °Ë»öÀÌ ½ÇÆÐÇÏ¸é ¼­¹ö°¡ ÄÑÁöÁöµµ ¾Ê´Â´Ù. + DNS°¡ ´ç½ÅÀÇ ±ÇÇÑ ¹ÛÀÇ ¹®Á¦ÀÏ ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, + abc.domÀÌ °í°´ »çÀÌÆ®ÀÌ°í °í°´ÀÌ ÀÚ½ÅÀÇ DNS¸¦ + °ü¸®ÇÑ´Ù¸é, www.abc.dom ·¹Äڵ带 Áö¿ì±â¸¸ Çصµ + (1.2 ÀÌÀü) ¼­¹ö´Â ½ÃÀÛÇÏÁö ¸øÇÑ´Ù.

    + +

    ÈξÀ ´õ ±³È°ÇÑ ¹æ¹ýµµ ÀÖ´Ù. ´ÙÀ½ ¼³Á¤À» »ìÆ캸ÀÚ:

    + + + <VirtualHost www.abc.dom>
    +   ServerAdmin webgirl@abc.dom
    +   DocumentRoot /www/abc
    + </VirtualHost>
    +
    + <VirtualHost www.def.dom>
    +   ServerAdmin webguy@def.dom
    +   DocumentRoot /www/def
    + </VirtualHost> +
    + +

    ´ç½ÅÀÌ www.abc.dom¿¡ 10.0.0.1, + www.def.dom¿¡ 10.0.0.2¸¦ ÇÒ´çÇß´Ù°í ÇÏÀÚ. + ¶Ç, def.domÀº ÀÚü DNS¸¦ »ç¿ëÇÑ´Ù°í °¡Á¤ÇÏÀÚ. + ÀÌ ¼³Á¤°ú ÇÔ²² def.domÀ» abc.domÀ¸·Î + °¡´Â ¸ðµç Åë½ÅÀ» °¡·Îç ¼ö ÀÖ´Â Àå¼Ò¿¡ µÎ¾ú´Ù. ±×·¸´Ù¸é ±×µéÀº + www.def.domÀ» 10.0.0.1·Î ¼³Á¤Çϱ⸸ ÇÏ¸é µÈ´Ù. + ±×µéÀÌ ÀÚü DNS¸¦ »ç¿ëÇϱ⶧¹®¿¡ ´ç½ÅÀº ±×µéÀÌ ¿øÇϴµ¥·Î + www.def.dom ·¹Äڵ带 ¼³Á¤ÇÏ´Â °ÍÀ» ¸·À» ¼ö + ¾ø´Ù.

    + +

    (»ç¿ëÀÚ°¡ http://www.abc.dom/whatever Çü½ÄÀÇ + URLÀ» ÀÔ·ÂÇÏ´Â °æ¿ì¸¦ Æ÷ÇÔÇÏ¿©) 10.0.0.1·Î ¿À´Â ¸ðµç ¿äûÀ» + def.dom °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÏ°Ô µÈ´Ù. ¿Ö ÀÌ·± + ÀÏÀÌ ÀϾ´ÂÁö ÀÌÇØÇÏ·Á¸é ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô °¡»óÈ£½ºÆ®·Î + ¿À´Â ¿äûÀ» ó¸®ÇÏ´ÂÁö¿¡ ´ëÇÑ ¼³¸íÀÌ ÇÊ¿äÇÏ´Ù. + ¿©±â¿¡ ´ë°­ ¼³¸íµÇÀÖ´Ù.

    +
    + +
    + "ÁÖ¼­¹ö" ÁÖ¼Ò + +

    ¾ÆÆÄÄ¡ 1.1¿¡¼­ À̸§±â¹Ý + °¡»óÈ£½ºÆ® Áö¿øÀÌ Æ÷ÇԵǾú±â¶§¹®¿¡ ¾ÆÆÄÄ¡´Â À¥¼­¹ö¸¦ + ½ÇÇàÇϴ ȣ½ºÆ®ÀÇ IP ÁÖ¼Ò(µé)¸¦ ¾Ë ÇÊ¿ä°¡ »ý°å´Ù. ÀÌ ÁÖ¼Ò´Â + (ÀÖ´Ù¸é) Àü¿ª ServerName + ȤÀº C ÇÔ¼ö gethostnameÀ¸·Î (¸í·ÉÇÁ·ÒÇÁÆ®¿¡ + "hostname"À» ÀÔ·ÂÇßÀ»¶§¿Í °°Àº °á°ú) ¾ò´Â´Ù. ±×·¯¸é ÀÌ ÁÖ¼Ò·Î + DNS °Ë»öÀ» ÇÑ´Ù. ÇöÀç ÀÌ °Ë»öÀº ÇÇÇÒ ¼ö ¾ø´Ù.

    + +

    DNS ¼­¹ö°¡ Á׾ ÀÌ °Ë»öÀÌ ½ÇÆÐÇÒ °Í °°´Ù¸é + /etc/hosts¿¡ È£½ºÆ®¸íÀ» Áý¾î³ÖÀ» ¼ö ÀÖ´Ù. + (ÄÄÇ»ÅÍ°¡ Á¤»óÀûÀ¸·Î ºÎÆõǾú´Ù¸é ¾Æ¸¶ ÀÌ¹Ì µé¾îÀÖÀ» °ÍÀÌ´Ù.) + ±×¸®°í DNS°¡ ½ÇÆÐÇÏ¸é ¼­¹ö°¡ /etc/hosts¸¦ + »ç¿ëÇÏ´ÂÁö È®ÀÎÇ϶ó. »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦¿¡ µû¶ó + /etc/resolv.conf ȤÀº /etc/nsswitch.conf¸¦ + ¼öÁ¤ÇÏ¸é µÉ °ÍÀÌ´Ù.

    + +

    ¼­¹ö°¡ ¾î¶² ÀÌÀ¯¿¡¼­°Ç DNS¸¦ °Ë»öÇÏ¸é ¾ÈµÈ´Ù¸é + HOSTRESORDER ȯ°æº¯¼ö¸¦ "local"·Î ¼³Á¤ÇÏ°í + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. mod_env¸¦ + »ç¿ëÇÏ¿© ȯ°æÀ» º¯°æÇÏÁö ¾Ê´Â´Ù¸é ÀÌ È¯°æº¯¼ö´Â + CGI¿¡µµ ¿µÇâÀ» ÁØ´Ù. ¿î¿µÃ¼Á¦ÀÇ manpage³ª FAQ¸¦ Âü°íÇÏ´Â + °ÍÀÌ ÁÁ´Ù.

    +
    + +
    + ÀÌ ¹®Á¦¸¦ ÇÇÇϱâÀ§ÇÑ ÆÁ + +
      +
    • + VirtualHost¿¡ IP + ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó +
    • + +
    • + Listen¿¡ + IP ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó +
    • + +
    • + ¸ðµç °¡»óÈ£½ºÆ®´Â ¸í½ÃÀûÀ¸·Î + ServerNameÀ» + °¡Áö°Ô Ç϶ó +
    • + +
    • ¾î¶² ÆäÀÌÁöµµ ¼­ºñ½ºÇÏÁö¾Ê´Â + <VirtualHost _default_:*> ¼­¹ö¸¦ + ¸¸µé¾î¶ó
    • +
    +
    + +
    + ºÎ·Ï: ¾ÕÀ¸·Î´Â + +

    DNS¿Í °ü·ÃµÈ »óȲÀº ¸Å¿ì ¹Ù¶÷Á÷ÇÏÁö ¸øÇÏ´Ù. ¾ÆÆÄÄ¡ 1.2¿¡¼­ + ¿ì¸®´Â DNS°¡ ½ÇÆÐÇÑ °æ¿ì¿¡µµ ÃÖ¼ÒÇÑ ¼­¹ö°¡ ÄÑÁöµµ·Ï ³ë·ÂÇßÁö¸¸ + °á°ú´Â ³ª»¦´Ù. ¾î·µç ¼³Á¤ÆÄÀÏ¿¡ Á÷Á¢ IP ÁÖ¼Ò¸¦ ¿ä±¸ÇÏ´Â + °ÍÀº ¹øÈ£¸¦ ´Ù½Ã ¼³Á¤ÇؾßÇÒ ¿äÁò ÀÎÅͳݿ¡ ¸Å¿ì ¹Ù¶÷Á÷ÇÏÁö + ¸øÇÏ´Ù.

    + +

    À§¿¡¼­ ¼³¸íÇÑ ¼­ºñ½ºµµµÏ °ø°ÝÀ» ¸·´Â ÇÑ°¡Áö ¹æ¹ýÀº °Ë»öÇÑ + IP ÁÖ¼Ò¿¡ ´Ù½Ã ¿ªDNS °Ë»öÀ» ÇÏ¿© µÎ À̸§À» ºñ±³ÇÏ´Â °ÍÀÌ´Ù. + ¼­·Î ´Ù¸¥ °æ¿ì °¡»óÈ£½ºÆ®¸¦ °¡µ¿ÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù. ÀÌ ¹æ¹ýÀº + ¿ªDNS°¡ ¿Ã¹Ù·Î ¼³Á¤µÇ¾ß ÇÑ´Ù. (FTP ¼­¹ö³ª TCP wrapper°¡ + "Áߺ¹-¿ª" DNS °Ë»öÀ» ÀÚÁÖ »ç¿ëÇϱ⶧¹®¿¡ ´ëºÎºÐÀÇ °ü¸®ÀÚ¿¡°Ô + Àͼ÷ÇÒ °ÍÀÌ´Ù.)

    + +

    ¾î·µç IP ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö¾ÊÀ¸¸é DNS°¡ ½ÇÆÐÇÑ °æ¿ì °¡»óÈ£½ºÆ® + À¥¼­¹ö¸¦ ¹ÏÀ» ¼ö ÀÖ°Ô ½ÃÀÛÇÒ ¼ö ¾ø´Ù. ¼³Á¤ÀÇ ÀϺθ¦ ¹«½ÃÇÏ´Â + °Í°ú °°Àº ºÎºÐÀûÀÎ ÇØ°áÃ¥Àº À¥¼­¹ö Àüü¸¦ ½ÃÀÛÇÏÁö¾Ê´Â °Íº¸´Ù + ´õ ³ª»Ü ¼öµµ ÀÖ´Ù.

    + +

    HTTP/1.1ÀÌ ³ª¿Ô°í ºê¶ó¿ìÀú¿Í ÇÁ·Ï½Ã°¡ Host + Çì´õ¸¦ º¸³»±â ½ÃÀÛÇßÀ¸¹Ç·Î IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ¿ÏÀüÈ÷ + »ç¿ëÇÏÁö¾Ê´Â °ÍÀÌ °¡´ÉÇØÁú °ÍÀÌ´Ù. ±×·¯¸é À¥¼­¹ö´Â ¼³Á¤Áß¿¡¼­ + DNS °Ë»öÀ» ÇÒ ÇÊ¿ä°¡ ¾ø¾îÁø´Ù. ±×·¯³ª 1997³â 3¿ù¿¡´Â Áß¿äÇÑ + À¥¼­¹ö¿¡ Æ÷ÇÔÇÒ Á¤µµ·Î À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ ³Î¸® »ç¿ëµÇÁö + ¾Ê¾Ò´Ù.

    +
    +
    diff --git a/trunk/docs/manual/dns-caveats.xml.meta b/trunk/docs/manual/dns-caveats.xml.meta new file mode 100644 index 0000000000..dec5aad3db --- /dev/null +++ b/trunk/docs/manual/dns-caveats.xml.meta @@ -0,0 +1,13 @@ + + + + dns-caveats + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/dso.html b/trunk/docs/manual/dso.html new file mode 100644 index 0000000000..3d86148e79 --- /dev/null +++ b/trunk/docs/manual/dso.html @@ -0,0 +1,11 @@ +URI: dso.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: dso.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: dso.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/dso.html.en b/trunk/docs/manual/dso.html.en new file mode 100644 index 0000000000..51156c2408 --- /dev/null +++ b/trunk/docs/manual/dso.html.en @@ -0,0 +1,315 @@ + + + +Dynamic Shared Object (DSO) Support - Apache HTTP Server + + + + + +
    <-
    +

    Dynamic Shared Object (DSO) Support

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    The Apache HTTP Server is a modular program where the + administrator can choose the functionality to include in the + server by selecting a set of modules. The modules can be + statically compiled into the httpd binary when the + server is built. Alternatively, modules can be compiled as + Dynamic Shared Objects (DSOs) that exist separately from the + main httpd binary file. DSO modules may be + compiled at the time the server is built, or they may be + compiled and added at a later time using the Apache Extension + Tool (apxs).

    + +

    This document describes how to use DSO modules as well as + the theory behind their use.

    +
    + +
    top
    +
    +

    Implementation

    + + + +

    The DSO support for loading individual Apache modules is based + on a module named mod_so which must be statically + compiled into the Apache core. It is the only module besides + core which cannot be put into a DSO + itself. Practically all other distributed Apache modules can then + be placed into a DSO by individually enabling the DSO build for + them via configure's + --enable-module=shared option as discussed + in the install documentation. After a + module is compiled into a DSO named mod_foo.so you + can use mod_so's LoadModule command in your + httpd.conf file to load this module at server startup + or restart.

    + +

    To simplify this creation of DSO files for Apache modules + (especially for third-party modules) a new support program + named apxs (APache + eXtenSion) is available. It can be used to build DSO based + modules outside of the Apache source tree. The idea is + simple: When installing Apache the configure's + make install procedure installs the Apache C + header files and puts the platform-dependent compiler and + linker flags for building DSO files into the apxs + program. This way the user can use apxs to compile + his Apache module sources without the Apache distribution + source tree and without having to fiddle with the + platform-dependent compiler and linker flags for DSO + support.

    +
    top
    +
    +

    Usage Summary

    + +

    To give you an overview of the DSO features of Apache 2.0, + here is a short and concise summary:

    + +
      +
    1. + Build and install a distributed Apache module, say + mod_foo.c, into its own DSO + mod_foo.so: + +

      +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +

      +
    2. + +
    3. + Build and install a third-party Apache module, say + mod_foo.c, into its own DSO + mod_foo.so: + +

      +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c \
      + + --enable-foo=shared
      +
      +$ make install +

      +
    4. + +
    5. + Configure Apache for later installation of shared + modules: + +

      +$ ./configure --enable-so
      +$ make install +

      +
    6. + +
    7. + Build and install a third-party Apache module, say + mod_foo.c, into its own DSO + mod_foo.so outside of the Apache + source tree using apxs: + +

      +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +

      +
    8. +
    + +

    In all cases, once the shared module is compiled, you must + use a LoadModule + directive in httpd.conf to tell Apache to activate + the module.

    +
    top
    +
    +

    Background

    + +

    On modern Unix derivatives there exists a nifty mechanism + usually called dynamic linking/loading of Dynamic Shared + Objects (DSO) which provides a way to build a piece of + program code in a special format for loading it at run-time + into the address space of an executable program.

    + +

    This loading can usually be done in two ways: Automatically + by a system program called ld.so when an + executable program is started or manually from within the + executing program via a programmatic system interface to the + Unix loader through the system calls + dlopen()/dlsym().

    + +

    In the first way the DSO's are usually called shared + libraries or DSO libraries and named + libfoo.so or libfoo.so.1.2. They + reside in a system directory (usually /usr/lib) + and the link to the executable program is established at + build-time by specifying -lfoo to the linker + command. This hard-codes library references into the executable + program file so that at start-time the Unix loader is able to + locate libfoo.so in /usr/lib, in + paths hard-coded via linker-options like -R or in + paths configured via the environment variable + LD_LIBRARY_PATH. It then resolves any (yet + unresolved) symbols in the executable program which are + available in the DSO.

    + +

    Symbols in the executable program are usually not referenced + by the DSO (because it's a reusable library of general code) + and hence no further resolving has to be done. The executable + program has no need to do anything on its own to use the + symbols from the DSO because the complete resolving is done by + the Unix loader. (In fact, the code to invoke + ld.so is part of the run-time startup code which + is linked into every executable program which has been bound + non-static). The advantage of dynamic loading of common library + code is obvious: the library code needs to be stored only once, + in a system library like libc.so, saving disk + space for every program.

    + +

    In the second way the DSO's are usually called shared + objects or DSO files and can be named with an + arbitrary extension (although the canonical name is + foo.so). These files usually stay inside a + program-specific directory and there is no automatically + established link to the executable program where they are used. + Instead the executable program manually loads the DSO at + run-time into its address space via dlopen(). At + this time no resolving of symbols from the DSO for the + executable program is done. But instead the Unix loader + automatically resolves any (yet unresolved) symbols in the DSO + from the set of symbols exported by the executable program and + its already loaded DSO libraries (especially all symbols from + the ubiquitous libc.so). This way the DSO gets + knowledge of the executable program's symbol set as if it had + been statically linked with it in the first place.

    + +

    Finally, to take advantage of the DSO's API the executable + program has to resolve particular symbols from the DSO via + dlsym() for later use inside dispatch tables + etc. In other words: The executable program has to + manually resolve every symbol it needs to be able to use it. + The advantage of such a mechanism is that optional program + parts need not be loaded (and thus do not spend memory) until + they are needed by the program in question. When required, + these program parts can be loaded dynamically to extend the + base program's functionality.

    + +

    Although this DSO mechanism sounds straightforward there is + at least one difficult step here: The resolving of symbols from + the executable program for the DSO when using a DSO to extend a + program (the second way). Why? Because "reverse resolving" DSO + symbols from the executable program's symbol set is against the + library design (where the library has no knowledge about the + programs it is used by) and is neither available under all + platforms nor standardized. In practice the executable + program's global symbols are often not re-exported and thus not + available for use in a DSO. Finding a way to force the linker + to export all global symbols is the main problem one has to + solve when using DSO for extending a program at run-time.

    + +

    The shared library approach is the typical one, because it + is what the DSO mechanism was designed for, hence it is used + for nearly all types of libraries the operating system + provides. On the other hand using shared objects for extending + a program is not used by a lot of programs.

    + +

    As of 1998 there are only a few software packages available + which use the DSO mechanism to actually extend their + functionality at run-time: Perl 5 (via its XS mechanism and the + DynaLoader module), Netscape Server, etc. Starting + with version 1.3, Apache joined the crew, because Apache + already uses a module concept to extend its functionality and + internally uses a dispatch-list-based approach to link external + modules into the Apache core functionality. So, Apache is + really predestined for using DSO to load its modules at + run-time.

    +
    top
    +
    +

    Advantages and Disadvantages

    + +

    The above DSO based features have the following + advantages:

    + +
      +
    • The server package is more flexible at run-time because + the actual server process can be assembled at run-time via + LoadModule + httpd.conf configuration commands instead of + configure options at build-time. For instance + this way one is able to run different server instances + (standard & SSL version, minimalistic & powered up + version [mod_perl, PHP3], etc.) with only one Apache + installation.
    • + +
    • The server package can be easily extended with + third-party modules even after installation. This is at least + a great benefit for vendor package maintainers who can create + a Apache core package and additional packages containing + extensions like PHP3, mod_perl, mod_fastcgi, + etc.
    • + +
    • Easier Apache module prototyping because with the + DSO/apxs pair you can both work outside the + Apache source tree and only need an apxs -i + command followed by an apachectl restart to + bring a new version of your currently developed module into + the running Apache server.
    • +
    + +

    DSO has the following disadvantages:

    + +
      +
    • The DSO mechanism cannot be used on every platform + because not all operating systems support dynamic loading of + code into the address space of a program.
    • + +
    • The server is approximately 20% slower at startup time + because of the symbol resolving overhead the Unix loader now + has to do.
    • + +
    • The server is approximately 5% slower at execution time + under some platforms because position independent code (PIC) + sometimes needs complicated assembler tricks for relative + addressing which are not necessarily as fast as absolute + addressing.
    • + +
    • Because DSO modules cannot be linked against other + DSO-based libraries (ld -lfoo) on all platforms + (for instance a.out-based platforms usually don't provide + this functionality while ELF-based platforms do) you cannot + use the DSO mechanism for all types of modules. Or in other + words, modules compiled as DSO files are restricted to only + use symbols from the Apache core, from the C library + (libc) and all other dynamic or static libraries + used by the Apache core, or from static library archives + (libfoo.a) containing position independent code. + The only chances to use other code is to either make sure the + Apache core itself already contains a reference to it or + loading the code yourself via dlopen().
    • +
    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dso.html.ja.euc-jp b/trunk/docs/manual/dso.html.ja.euc-jp new file mode 100644 index 0000000000..3ae45498b5 --- /dev/null +++ b/trunk/docs/manual/dso.html.ja.euc-jp @@ -0,0 +1,296 @@ + + + +ưŪ¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È (DSO) ¥µ¥Ý¡¼¥È - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ưŪ¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È (DSO) ¥µ¥Ý¡¼¥È

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Apache HTTP ¥µ¡¼¥Ð¤Ï¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤¿¥×¥í¥°¥é¥à¤Ç¡¢ + ´ÉÍý¼Ô¤¬¥â¥¸¥å¡¼¥ë¤òÁªÂò¤¹¤ë¤³¤È¤Ç¥µ¡¼¥Ð¤ËÁȤ߹þ¤àµ¡Ç½¤òÁª¤Ö¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥â¥¸¥å¡¼¥ë¤Ï¥µ¡¼¥Ð¤¬¥Ó¥ë¥É¤µ¤ì¤ë¤È¤­¤Ë httpd ¥Ð¥¤¥Ê¥ê¤Ë + ÀÅŪ¤ËÁȤ߹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤â¤·¤¯¤Ï¡¢httpd ¥Ð¥¤¥Ê¥ê¤È¤Ï + Ê̤˸ºß¤¹¤ëưŪ¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È (ÌõÃí: Dynamic Shared Object) + (DSO) ¤È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤³¤È¤â + ¤Ç¤­¤Þ¤¹¡£DSO ¥â¥¸¥å¡¼¥ë¤Ï¥µ¡¼¥Ð¤¬¥Ó¥ë¥É¤µ¤ì¤ë¤È¤­¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤¿¤ê¡¢ + Apache ³ÈÄ¥¥Ä¡¼¥ë (apxs) ¤ò + »È¤Ã¤Æ¸å¤Ç¥³¥ó¥Ñ¥¤¥ë¤·¤ÆÄɲä·¤¿¤ê¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Îʸ½ñ¤Ï DSO ¥â¥¸¥å¡¼¥ë¤Î»È¤¤Êý¤È¡¢»ÅÁȤߤˤĤ¤¤Æ + ÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¼ÂÁõ

    + + + +

    ¸Ä¡¹¤Î Apache ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë¤¿¤á¤Î DSO ¥µ¥Ý¡¼¥È¤Ï + mod_so.c ¤È¤¤¤¦¥â¥¸¥å¡¼¥ë¤Îµ¡Ç½¤Ë´ð¤Å¤¤¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥â¥¸¥å¡¼¥ë ¤Ï Apache ¤Î¥³¥¢¤ËÀÅŪ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤ì¤Ï core.c °Ê³°¤Ç¤Ï DSO ¤Ë¤Ç¤­¤Ê¤¤Í£°ì¤Î + ¥â¥¸¥å¡¼¥ë¤Ç¤¹¡£»ö¼Â¾å¡¢Â¾¤Î¤¹¤Ù¤Æ¤Î Apache ¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢ + ¥¤¥ó¥¹¥È¡¼¥ë¤Îʸ½ñ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢ + configure ¤Î + --enable-module=shared ¥ª¥×¥·¥ç¥ó¤Ç¤½¤ì¤¾¤ì¤ò + DSO ¥Ó¥ë¥É¤Ë¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢DSO ¥â¥¸¥å¡¼¥ë¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + mod_foo.so ¤Î¤è¤¦¤Ê DSO ¤Ë¥â¥¸¥å¡¼¥ë¤¬¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤ì¤Ð¡¢ + httpd.conf ¥Õ¥¡¥¤¥ëÃæ¤Ç mod_so ¤Î + LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤³¤È¤Ç¥µ¡¼¥Ð¤Îµ¯Æ°¤äºÆµ¯Æ°»þ¤Ë¤³¤Î¥â¥¸¥å¡¼¥ë¤ò + ¥í¡¼¥É¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ¥â¥¸¥å¡¼¥ëÍѤΠ(Æä˥µ¡¼¥É¥Ñ¡¼¥Æ¥£¥â¥¸¥å¡¼¥ë¤Î) DSO ¥Õ¥¡¥¤¥ë¤Î + ºîÀ®¤ò´Êñ¤Ë¤¹¤ë¤¿¤á¤Ë¡¢apxs + (APache eXtenSion) ¤È¤¤¤¦¿·¤·¤¤¥µ¥Ý¡¼¥È¥×¥í¥°¥é¥à¤¬¤¢¤ê¤Þ¤¹¡£ + Apache ¤Î¥½¡¼¥¹¥Ä¥ê¡¼¤Î³°¤Ç DSO ¥â¥¸¥å¡¼¥ë¤ò¥Ó¥ë¥É¤¹¤ë¤¿¤á¤Ë + »È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£È¯ÁÛ¤Ïñ½ã¤Ç¤¹: Apache ¤Î¥¤¥ó¥¹¥È¡¼¥ë»þ¤Î + configure¡¢make install ¤Î¤È¤­¤Ë Apache ¤Î + C ¥Ø¥Ã¥À¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¡¢DSO ¥Ó¥ë¥ÉÍѤΥץé¥Ã¥È¥Õ¥©¡¼¥à°Í¸¤Î + ¥³¥ó¥Ñ¥¤¥é¤È¥ê¥ó¥«¤Î¥Õ¥é¥°¤ò apxs ¥×¥í¥°¥é¥à¤ËÄɲä·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥æ¡¼¥¶¤¬ Apache ¤ÎÇÛÉÛ¥½¡¼¥¹¥Ä¥ê¡¼¤Ê¤·¤Ç¡¢¤µ¤é¤Ë + DSO ¥µ¥Ý¡¼¥È¤Î¤¿¤á¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à°Í¸¤Î¥³¥ó¥Ñ¥¤¥é¤ä¥ê¥ó¥«¤Î + ¥Õ¥é¥°¤ò¤¤¤¸¤ë¤³¤È¤Ê¤¯ Apache ¤Î¥â¥¸¥å¡¼¥ë¤Î¥½¡¼¥¹¤ò¥³¥ó¥Ñ¥¤¥ë + ¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    »ÈÍÑË¡¤Î³µÍ×

    + +

    Apache 2.0 ¤Î DSO µ¡Ç½¤Î³µÎ¬¤òÃΤ뤳¤È¤¬¤Ç¤­¤ë¤¿¤á¤Î¡¢ + û¤¯´Ê·é¤Ê³µÍפǤ¹:

    + +
      +
    1. + ÇÛÉÛ¤µ¤ì¤Æ¤¤¤ë Apache ¥â¥¸¥å¡¼¥ë¡¢²¾¤Ë mod_foo.c + ¤È¤·¤Æ¡¢¤½¤ì¤ò DSO mod_foo.so ¤Ë¥Ó¥ë¥É¡¢¥¤¥ó¥¹¥È¡¼¥ë: + +

      +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +

      +
    2. + +
    3. + ¥µ¡¼¥É¥Ñ¡¼¥Æ¥£ Apache ¥â¥¸¥å¡¼¥ë¡¢²¾¤Ë mod_foo.c + ¤È¤·¤Æ¡¢¤½¤ì¤ò DSO mod_foo.so ¤Ë¥Ó¥ë¥É¡¢¥¤¥ó¥¹¥È¡¼¥ë: + +

      +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c \
      + + --enable-foo=shared
      +
      +$ make install +

      +
    4. + +
    5. + ¶¦Í­¥â¥¸¥å¡¼¥ë¤Î ¸å¡¹¤Î¥¤¥ó¥¹¥È¡¼¥ë ¤Î¤¿¤á¤Ë + Apache ¤òÀßÄê: + +

      +$ ./configure --enable-so
      +$ make install +

      +
    6. + +
    7. + ¥µ¡¼¥É¥Ñ¡¼¥Æ¥£ Apache ¥â¥¸¥å¡¼¥ë¡¢²¾¤Ë mod_foo.c + ¤È¤·¤Æ¡¢¤½¤ì¤ò apxs ¤ò»È¤Ã¤Æ + Apache ¥½¡¼¥¹¥Ä¥ê¡¼¤Î³°¤Ç DSO ¤Ë¥Ó¥ë¥É¡¢¥¤¥ó¥¹¥È¡¼¥ë: + +

      +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +

      +
    8. +
    + +

    ¤É¤Î¾ì¹ç¤Ë¤ª¤¤¤Æ¤â¡¢¶¦Í­¥â¥¸¥å¡¼¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤¿¸å¤Ç¡¢ + httpd.conf ¤Ç + LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ Apache ¤¬¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë + ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ÇØ·Ê

    + +

    ºÇ¶á¤Î Unix ·Ï¤Î OS ¤Ë¤Ï ưŪ¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È (DSO) + ¤ÎưŪ¥ê¥ó¥¯/¥í¡¼¥É¤È¤¤¤¦µ¤¤Î¤­¤¤¤¿µ¡¹½¤¬ + ¸ºß¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢¼Â¹Ô»þ¤Ë¥×¥í¥°¥é¥à¤Î¥¢¥É¥ì¥¹¶õ´Ö¤Ë + ¥í¡¼¥É¤Ç¤­¤ë¤è¤¦¤ÊÆÃÊ̤ʷÁ¼°¤Ç¥×¥í¥°¥é¥à¤ò¥Ó¥ë¥É¤¹¤ë¤³¤È¤ò + ²Äǽ¤Ë¤·¤Þ¤¹¡£

    + +

    ¤³¤Î¥í¡¼¥É¤ÏÆó¤Ä¤ÎÊýË¡¤Ç¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹: ¼Â¹Ô¥×¥í¥°¥é¥à¤¬ + µ¯Æ°¤µ¤ì¤¿¤È¤­¤Ë ld.so ¤È¤¤¤¦¥·¥¹¥Æ¥à¥×¥í¥°¥é¥à + ¤Ë¤è¤ê¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ëÊýË¡¤È¡¢¼Â¹Ô¥×¥í¥°¥é¥àÃ椫¤é¡¢¥·¥¹¥Æ¥à¥³¡¼¥ë + dlopen()/dlsym() ¤Ë¤è¤ë Unix ¥í¡¼¥À¤Ø¤Î + ¥×¥í¥°¥é¥à¥·¥¹¥Æ¥à¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò»È¤Ã¤Æ¼êÆ°¤Ç¹Ô¤Ê¤¦ÊýË¡¤È¤¬ + ¤¢¤ê¤Þ¤¹¡£

    + +

    ºÇ½é¤ÎÊýË¡¤Ç¤Ï DSO ¤ÏÉáÄ̤϶¦Í­¥é¥¤¥Ö¥é¥ê¤ä DSO + ¥é¥¤¥Ö¥é¥ê ¤È¸Æ¤Ð¤ì¤Æ¤¤¤Æ¡¢DSO ¤Î̾Á°¤Ï + libfoo.so ¤ä libfoo.so.1.2 ¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï¥·¥¹¥Æ¥à¥Ç¥£¥ì¥¯¥È¥ê (Ä̾ï /usr/lib) ¤Ë¸ºß¤·¡¢ + ¼Â¹Ô¥×¥í¥°¥é¥à¤Ø¤Î¥ê¥ó¥¯¤Ï¥Ó¥ë¥É»þ¤Ë -lfoo ¤ò¥ê¥ó¥«¤Ë + »ØÄꤹ¤ë¤³¤È¤Ç³ÎΩ¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¥é¥¤¥Ö¥é¥ê¤Ø¤Î»²¾È¤¬¼Â¹Ô¥×¥í¥°¥é¥à¤Î + ¥Õ¥¡¥¤¥ë¤Ë½ñ¤­¹þ¤Þ¤ì¤Æ¡¢µ¯Æ°»þ¤Ë Unix ¤Î¥í¡¼¥À¤¬ /usr/lib ¤ä¡¢ + ¥ê¥ó¥«¤Î -R ¤Î¤è¤¦¤Ê¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¥Ï¡¼¥É¥³¡¼¥É¤µ¤ì¤¿¥Ñ¥¹¡¢ + ´Ä¶­ÊÑ¿ô LD_LIBRARY_PATH ¤Ë¤è¤êÀßÄꤵ¤ì¤¿¥Ñ¥¹¡¢¤ÎÃ椫¤é + libfoo.so ¤Î¾ì½ê¤ò¸«¤Ä¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤½¤ì¤«¤é¡¢ + ¼Â¹Ô¥×¥í¥°¥é¥àÃæ¤Î (¤Þ¤À̤²ò·è¤Î) ¥·¥ó¥Ü¥ë¤ò DSO ¤Ë¤¢¤ë¥·¥ó¥Ü¥ë¤Ç + ²ò·è¤·¤Þ¤¹¡£

    + +

    ÉáÄÌ¤Ï¼Â¹Ô¥×¥í¥°¥é¥àÃæ¤Î¥·¥ó¥Ü¥ë¤Ï DSO ¤«¤é¤Ï»²¾È¤µ¤ì¤Þ¤»¤ó + (DSO ¤Ï°ìÈÌŪ¤Ê¥³¡¼¥É¤Ë¤è¤ëºÆÍøÍѲÄǽ¤Ê¥é¥¤¥Ö¥é¥ê¤Ç¤¹¤Î¤Ç)¡£ + ¤Ç¤¹¤«¤é¡¢¤µ¤é¤Ê¤ë¥·¥ó¥Ü¥ë¤Î²ò·è¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£ + ¥·¥ó¥Ü¥ë¤Ï Unix ¥í¡¼¥À¤Ë¤è¤ê´°Á´¤Ê²ò·è¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¤Î¤Ç¡¢¼Â¹Ô¥Õ¥¡¥¤¥ë¼«¿È¤Ï + ²¿¤â¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤»¤ó¡£(¼ÂºÝ¤Î¤È¤³¤í¡¢ÀÅŪ¤Ç¤Ê¤¤ÊýË¡¤Ç¥ê¥ó¥¯¤µ¤ì¤Æ¤¤¤ë + ¤¹¤Ù¤Æ¤Î¼Â¹Ô¥×¥í¥°¥é¥à¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë³«»ÏÍѤΥ³¡¼¥É¤Î°ìÉô¤Ë + ld.so ¤òµ¯Æ°¤¹¤ë¥³¡¼¥É¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹)¡£¤è¤¯»È¤ï¤ì¤ë + ¥é¥¤¥Ö¥é¥ê¤ÎưŪ¥í¡¼¥É¤ÎÍøÅÀ¤ÏÌÀ¤é¤«¤Ç¤¹¡£¥é¥¤¥Ö¥é¥ê¤Î¥³¡¼¥É¤Ï + ¥·¥¹¥Æ¥à¥é¥¤¥Ö¥é¥ê¤Ë libc.so ¤Î¤è¤¦¤Ë¤·¤Æ°ìÅÙÊݸ¤¹¤ë¤À¤±¤Ç¤è¤¯¡¢ + ¥×¥í¥°¥é¥à¤Î¤¿¤á¤ËɬÍפʥǥ£¥¹¥¯¤ÎÎΰè¤òÀáÌ󤹤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Æó¤Ä¤á¤ÎÊýË¡¤Ç¤Ï DSO ¤ÏÉáÄ̤϶¦Í­¥ª¥Ö¥¸¥§¥¯¥È¤ä + DSO ¥Õ¥¡¥¤¥ë¤È¸Æ¤Ð¤ì¤Æ¤¤¤Æ¡¢Ç¤°Õ¤Î³ÈÄ¥»Ò¤òÉÕ¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹ + (¤¿¤À¤·¡¢É¸½àŪ¤Ê̾Á°¤Ï foo.so ¤Ç¤¹)¡£ + ¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤ÏÄ̾ï¤Ï¥×¥í¥°¥é¥àÀìÍѤΥǥ£¥ì¥¯¥È¥ê¤ËÃÖ¤«¤ì¡¢ + ¤³¤ì¤é¤ò»È¤¦¼Â¹Ô¥×¥í¥°¥é¥à¤Ø¤Î¥ê¥ó¥¯¤Ï¼«Æ°Åª¤Ë¤Ï¤µ¤ì¤Þ¤»¤ó¡£ + ¤Ç¤¹¤Î¤Ç¡¢¼Â¹Ô¥×¥í¥°¥é¥à¤Ï dlopen() ¤ò»È¤Ã¤Æ + ¼Â¹Ô»þ¤Ë¼êÆ°¤Ç DSO ¤ò¥×¥í¥°¥é¥à¤Î¥¢¥É¥ì¥¹¶õ´Ö¤Ë¥í¡¼¥É¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î»þÅÀ¤Ç¤Ï¼Â¹Ô¥×¥í¥°¥é¥à¤ËÂФ·¤Æ DSO ¤Î¥·¥ó¥Ü¥ë¤Î²ò·è¤Ï¹Ô¤Ê¤ï¤ì¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢¤½¤ÎÂå¤ï¤ê¤Ë Unix ¤Î¥í¡¼¥À¤¬ DSO ¤Î (¤Þ¤À̤²ò·è¤Î) ¥·¥ó¥Ü¥ë¤ò + ¼Â¹Ô¥×¥í¥°¥é¥à¤Ë¤è¤ê¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤¿¥·¥ó¥Ü¥ë¤È´û¤Ë¥í¡¼¥É¤µ¤ì¤¿ + DSO ¥é¥¤¥Ö¥é¥ê¤Ë¤è¤ê¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤¿¥·¥ó¥Ü¥ë (Æäˡ¢¤É¤³¤Ë¤Ç¤â¤¢¤ë + libc.so ¤Î¤¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë) ¤Ç¼«Æ°Åª¤Ë²ò·è¤·¤Þ¤¹¡£ + ¤³¤¦¤¹¤ë¤³¤È¤Ç¡¢DSO ¤ÏºÇ½é¤«¤éÀÅŪ¤Ë¥ê¥ó¥¯¤µ¤ì¤Æ¤¤¤¿¤«¤Î¤è¤¦¤Ë¡¢ + ¼Â¹Ô¥×¥í¥°¥é¥à¤Î¥·¥ó¥Ü¥ë¤òÃΤ뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ºÇ¸å¤Ë¡¢DSO ¤Î API ¤òÍøÅÀ¤òÀ¸¤«¤¹¤¿¤á¤Ë¡¢¥×¥í¥°¥é¥à¤Ï + ¸å¤Ç¥Ç¥£¥¹¥Ñ¥Ã¥Á¥Æ¡¼¥Ö¥ë¤Ê¤É¤Ç¥·¥ó¥Ü¥ë¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¡¢ + dlsym() ¤ò»È¤Ã¤Æ¤¤¤¯¤Ä¤«¤Î¥·¥ó¥Ü¥ë¤ò²ò·è¤·¤Þ¤¹¡£ + ¤¹¤Ê¤ï¤Á: ¼Â¹Ô¥×¥í¥°¥é¥à¤ÏɬÍפʤ¹¤Ù¤Æ¤Î¥·¥ó¥Ü¥ë¤ò¼êÆ°¤Ç²ò·è¤·¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£¤³¤Îµ¡¹½¤ÎÍøÅÀ¤Ï¥×¥í¥°¥é¥à¤Î¥ª¥×¥·¥ç¥Ê¥ë¤ÊÉôʬ¤Ï + ɬÍפˤʤë¤Þ¤Ç¥í¡¼¥É¤¹¤ëɬÍפ¬¤Ê¤¤ (¤À¤«¤é¥á¥â¥ê¤â¾ÃÈñ¤·¤Ê¤¤) + ¤³¤È¤Ç¤¹¡£É¬Íפʤé¤Ð¡¢´ðËÜ¥×¥í¥°¥é¥à¤Îµ¡Ç½¤ò³ÈÄ¥¤¹¤ë¤¿¤á¤Ë + ¤³¤ì¤é¤ÎÉôʬ¤òưŪ¤Ë¥í¡¼¥É¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î DSO µ¡¹½¤Ï´Êñ¤Ê¤è¤¦¤Ë¸«¤¨¤Þ¤¹¤¬¡¢¾¯¤Ê¤¯¤È¤â°ì¤ÄÆñ¤·¤¤ÅÀ¤¬ + ¤¢¤ê¤Þ¤¹: ¥×¥í¥°¥é¥à¤ò³ÈÄ¥¤¹¤ë¤¿¤á¤Ë DSO ¤ò»È¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¡¢ + DSO ¤¬¼Â¹Ô¥×¥í¥°¥é¥à¤«¤é¥·¥ó¥Ü¥ë¤ò²ò·è¤¹¤ëÅÀ¤Ç¤¹ (ÆóÈÖÌܤÎÊýË¡)¡£ + ¤³¤ì¤Ï¤Ê¤¼¤Ç¤·¤ç¤¦¤«¡£¤½¤ì¤Ï¡¢DSO ¤Î¥·¥ó¥Ü¥ë¤ò¼Â¹Ô¥×¥í¥°¥é¥à¤Î + ¥·¥ó¥Ü¥ë¤«¤é¡ÖµÕ²ò·è¡×¤¹¤ë¤È¤¤¤¦¤Î¤Ï¥é¥¤¥Ö¥é¥ê¤ÎÀß·× + (¥é¥¤¥Ö¥é¥ê¤Ï¤½¤ì¤ò»ÈÍѤ¹¤ë¥×¥í¥°¥é¥à¤Î¤³¤È¤Ï²¿¤â + ÃΤé¤Ê¤¤) ¤ËÈ¿¤·¤Æ¤¤¤Æ¡¢¤³¤Îµ¡Ç½¤Ï¤¹¤Ù¤Æ¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë + ¤¢¤ë¤ï¤±¤Ç¤Ï¤Ê¤¯¡¢É¸½à²½¤â¤µ¤ì¤Æ¤¤¤Ê¤¤¤«¤é¤Ç¤¹¡£ + ¼ÂºÝ¤Ë¤Ï¼Â¹Ô¥×¥í¥°¥é¥à¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥·¥ó¥Ü¥ë¤ÏºÆ¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤ë¤³¤È¤Ï + ¤¢¤Þ¤ê¤Ê¤¯¡¢DSO ¤«¤é»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£¥ê¥ó¥«¤Ë¥°¥í¡¼¥Ð¥ë¥·¥ó¥Ü¥ë¤¹¤Ù¤Æ¤ò + ¥¨¥¯¥¹¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë¤µ¤»¤ëÊýË¡¤ò¸«¤Ä¤±¤ë¤³¤È¤¬¡¢¼Â¹Ô»þ¤Ë¥×¥í¥°¥é¥à¤ò + ³ÈÄ¥¤¹¤ë¤¿¤á¤Ë DSO ¤ò»È¤¦¤È¤­¤Î°ìÈÖ¤ÎÌäÂê¤Ç¤¹¡£

    + +

    ¶¦Í­¥é¥¤¥Ö¥é¥ê¤Î¥¢¥×¥í¡¼¥Á¤¬ÉáÄ̤ÎÊýË¡¤Ç¤¹¡£DSO µ¡¹½¤Ï¤½¤Î¤¿¤á¤Ë + À߷פµ¤ì¤¿¤â¤Î¤Ç¤¹¤«¤é¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ÎÊýË¡¤Ï¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤¬ + Ä󶡤¹¤ë¤Û¤È¤ó¤É¤¹¤Ù¤Æ¤Î¼ïÎà¤Î¥é¥¤¥Ö¥é¥ê¤Ç»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£ + °ìÊý¡¢¥×¥í¥°¥é¥à¤Î³ÈÄ¥¤Î¤¿¤á¤Ë¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È¤ò»ÈÍѤ¹¤ë¡¢¤È¤¤¤¦Êý¤Ï + ¤¢¤Þ¤ê»È¤ï¤ì¤Æ¤¤¤Þ¤»¤ó¡£

    + +

    1998 ǯ¤Î»þÅÀ¤Ç¡¢¼Â¹Ô»þ¤Ë¼ÂºÝ¤Ëµ¡Ç½³ÈÄ¥¤Î¤¿¤á¤Ë DSO µ¡¹½¤ò»È¤Ã¤Æ¤¤¤ë + ¥½¥Õ¥È¥¦¥§¥¢¥Ñ¥Ã¥±¡¼¥¸¤Ï¾¯¤·¤À¤±¤Ç¤·¤¿: Perl 5 (XS µ¡¹½¤È DnaLoader ¥â¥¸¥å¡¼¥ë + ¤Ë¤è¤ë¤â¤Î)¡¢Netscape ¥µ¡¼¥Ð¤Ê¤É¤Ç¤¹¡£Apache ¤Ï¤¹¤Ç¤Ë + ¥â¥¸¥å¡¼¥ë¤Î³µÇ°¤ò»È¤Ã¤Æµ¡Ç½³ÈÄ¥¤ò¤·¤Æ¤¤¤Æ¡¢ÆâÉôŪ¤Ë¥Ç¥£¥¹¥Ñ¥Ã¥Á¥ê¥¹¥È¤Ë + ´ð¤Å¤¤¤¿³°Éô¥â¥¸¥å¡¼¥ë¤Î Apache ¥³¥¢µ¡Ç½¤Ø¤Î¥ê¥ó¥¯¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤Þ¤·¤¿¤Î¤Ç¡¢ + ¥Ð¡¼¥¸¥ç¥ó 1.3 ¤«¤é¡¢Apache ¤â DSO µ¡¹½¤ò»È¤¦Ãç´Ö¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + Apache ¤Ï¼Â¹Ô»þ¤Ë DSO ¤ò»È¤Ã¤Æ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë¤è¤¦¤Ë¤¹¤Ç¤Ë + ±¿Ì¿ÉÕ¤±¤é¤ì¤Æ¤¤¤¿¤Î¤Ç¤¹¡£

    +
    top
    +
    +

    ÍøÅÀ¤È·çÅÀ

    + +

    ¾åµ­¤Î DSO ¤Ë´ð¤Å¤¤¤¿µ¡Ç½¤Ï°Ê²¼¤ÎÍøÅÀ¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¼ÂºÝ¤Î¥µ¡¼¥Ð¥×¥í¥»¥¹¤òÁȤßΩ¤Æ¤ë¤¿¤á¤Ë¡¢ + ¥Ó¥ë¥É»þ¤Ë configure ¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¦Âå¤ï¤ê¤Ë + ¼Â¹Ô»þ¤Ë httpd.conf ¤ÎÀßÄêÍÑ¥³¥Þ¥ó¥É + LoadModule + ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¤Î¤Ç¡¢¥µ¡¼¥Ð¥Ñ¥Ã¥±¡¼¥¸¤Î½ÀÆðÀ­¤¬¹â¤Þ¤ê¤Þ¤·¤¿¡£ + ¤¿¤È¤¨¤Ð¡¢°ì¤Ä¤Î Apache ¤Î¥¤¥ó¥¹¥È¡¼¥ë¤«¤é + °ã¤¦¹½À®¤Î¥µ¡¼¥Ð (ɸ½àÈÇ¤È SSL ÈÇ¡¢ºÇ¾®¹½À®¤È³ÈÄ¥ÈÇ [mod_perl, PHP3] + ¤Ê¤É) ¤ò¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    • + +
    • ¥¤¥ó¥¹¥È¡¼¥ë¤Î¸å¤Ç¤¢¤Ã¤Æ¤â¡¢¥µ¡¼¥Ð¤Î¥Ñ¥Ã¥±¡¼¥¸¤ò¥µ¡¼¥É¥Ñ¡¼¥Æ¥£ + ¥â¥¸¥å¡¼¥ë¤Ç´Êñ¤Ë³ÈÄ¥¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤³¤ì¤Ï¡¢Apache ¥³¥¢ + ¥Ñ¥Ã¥±¡¼¥¸¤È¡¢PHP3, mod_perl, mod_fastcgi ¤Ê¤É ¤ÎÄɲäΠ+ ¥Ñ¥Ã¥±¡¼¥¸¤òºîÀ®¤Ç¤­¤ë¤Î¤Ç¡¢¾¯¤Ê¤¯¤È¤â¥Ù¥ó¥À¤Î¥Ñ¥Ã¥±¡¼¥¸´ÉÍý¼Ô¤Ë¤È¤Ã¤Æ + Â礭¤ÊÍøÅÀ¤¬¤¢¤ê¤Þ¤¹¡£
    • + +
    • Apache ¥â¥¸¥å¡¼¥ë¤Î³«È¯¤¬´Êñ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï DSO ¤È apxs ¤ÎÁȤ߹ç¤ï¤»¤Ë¤è¤ê¡¢Apache ¥½¡¼¥¹¥Ä¥ê¡¼¤Î + ³°¤Çºî¶È¤Ç¤­¡¢³«È¯Ãæ¤Î¥â¥¸¥å¡¼¥ë¤Î¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤ò + ¼Â¹ÔÃæ¤Î Apache ¥µ¡¼¥Ð¤ËÁȤ߹þ¤à¤¿¤á¤Ë apxs -i ¤È + apachectl restart ¤ò¹Ô¤Ê¤¦¤À¤±¤ÇÎɤ¯¤Ê¤ë¤«¤é¤Ç¤¹¡£
    • +
    + +

    DSO ¤Ë¤Ï°Ê²¼¤Î·çÅÀ¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¤¹¤Ù¤Æ¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤¬¥×¥í¥°¥é¥à¤Î¥¢¥É¥ì¥¹¶õ´Ö¤Ë + ¥³¡¼¥É¤òưŪ¥í¡¼¥É¤¹¤ë¤³¤È¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤ï¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢ + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤è¤Ã¤Æ¤Ï DSO µ¡¹½¤Ï»È¤¨¤Þ¤»¤ó¡£
    • + +
    • Unix ¤Î¥í¡¼¥À¤¬¥·¥ó¥Ü¥ë¤Î²ò·è¤ò¤¹¤ëɬÍפ¬¤Ç¤­¤¿¤Î¤Ç¡¢ + ¤½¤Î¥ª¡¼¥Ð¥Ø¥Ã¥É¤Ë¤è¤ê¥µ¡¼¥Ð¤Îµ¯Æ°»þ´Ö¤¬Ìó 20% ÃÙ¤¯¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
    • + +
    • °ÌÃÖÈó°Í¸¥³¡¼¥É (PIC) (ÌõÃí position independent code) ¤Ï + ÁêÂÐ¥¢¥É¥ì¥¹¤Î¤¿¤á¤ËÊ£»¨¤Ê¥¢¥»¥ó¥Ö¥é¤Î¥È¥ê¥Ã¥¯¤¬É¬Íפʤ³¤È¤¬¤¢¤ê¡¢ + ¤½¤ì¤Ïɬ¤º¤·¤âÀäÂÐ¥¢¥É¥ì¥¹¤ÈƱ¤¸¤¯¤é¤¤¤Î®ÅÙ¤¬¤Ç¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤Î¤Ç¡¢ + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤è¤Ã¤Æ¤Ï¥µ¡¼¥Ð¤Î¼Â¹Ô®ÅÙ¤¬Ìó 5% ÃÙ¤¯¤Ê¤ê¤Þ¤¹¡£
    • + +
    • DSO ¥â¥¸¥å¡¼¥ë¤Ï¤¹¤Ù¤Æ¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¾¤Î DSO ¤Ë´ð¤Å¤¤¤¿ + ¥é¥¤¥Ö¥é¥ê¤ËÂФ·¤Æ¥ê¥ó¥¯¤Ç¤­¤ë (ld -lfoo) + ¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤Î¤Ç (¤¿¤È¤¨¤Ð¡¢a.out ¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¤Ï + ¤³¤Îµ¡Ç½¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢ELF ¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤Ï¤¢¤ê¤Þ¤¹)¡¢ + ¤¹¤Ù¤Æ¤Î¼ïÎà¤Î¥â¥¸¥å¡¼¥ë¤Ë DSO µ¡¹½¤ò»È¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¸À¤¤´¹¤¨¤ë¤È¡¢DSO ¥Õ¥¡¥¤¥ë¤È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥â¥¸¥å¡¼¥ë¤Î + »È¤¨¤ë¥·¥ó¥Ü¥ë¤Ï¡¢ + Apache ¤Î¥³¥¢¤Î¥·¥ó¥Ü¥ë¡¢C ¥é¥¤¥Ö¥é¥ê (libc) ¤È + Apache ¥³¥¢¤¬»È¤Ã¤Æ¤¤¤ë¾¤Î¤¹¤Ù¤Æ¤ÎÀÅŪ¤Ê¥é¥¤¥Ö¥é¥ê¤ÈưŪ¥é¥¤¥Ö¥é¥ê¤Î + ¥·¥ó¥Ü¥ë¡¢PIC ¤Ë¤è¤ëÀÅŪ¤Ê¥é¥¤¥Ö¥é¥ê (libfoo.a) ¤Î + ¥·¥ó¥Ü¥ë¤Î¤ß¤ËÀ©¸Â¤µ¤ì¤Þ¤¹¡£¤½¤Î¾¤Î¥³¡¼¥É¤ò»È¤¦ÊýË¡¤Ï¡¢ + Apache ¥³¥¢¼«¿È¤¬¤¹¤Ç¤Ë¤½¤Î¥³¡¼¥É¤Ø¤Î»²¾È¤¬¤¢¤ë¤è¤¦¤Ë¤¹¤ë¤«¡¢ + dlopen () ¤ò»È¤Ã¤Æ¥³¡¼¥É¤ò¼«Ê¬¼«¿È¤Ç¥í¡¼¥É¤¹¤ë¤«¤Î + ¤É¤Á¤é¤«¤·¤«¤¢¤ê¤Þ¤»¤ó¡£
    • +
    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dso.html.ko.euc-kr b/trunk/docs/manual/dso.html.ko.euc-kr new file mode 100644 index 0000000000..4aee09d50d --- /dev/null +++ b/trunk/docs/manual/dso.html.ko.euc-kr @@ -0,0 +1,276 @@ + + + +µ¿Àû°øÀ¯°´Ã¼ (DSO) Áö¿ø - Apache HTTP Server + + + + + +
    <-
    +

    µ¿Àû°øÀ¯°´Ã¼ (DSO) Áö¿ø

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â °ü¸®ÀÚ°¡ ¸ðµâµéÀ» ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» °áÁ¤ÇÒ ¼ö ÀÖ´Â ¸ðµâÈ­µÈ ÇÁ·Î±×·¥ÀÌ´Ù. ¼­¹ö¸¦ ÄÄÆÄÇÒ¶§ + httpd ½ÇÇàÆÄÀÏ¿¡ Á¤ÀûÀ¸·Î ¸ðµâÀ» ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù. ¾Æ´Ï¸é ¸ðµâÀ» httpd ½ÇÇàÆÄÀÏ°ú + ºÐ¸®ÇÏ¿© µ¿Àû°øÀ¯°´Ã¼(Dynamic Shared Objects, DSO)·Î ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù. DSO ¸ðµâÀº ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ ÄÄÆÄÀÏÇϰųª, Apache + Extension Tool (apxs)À» + »ç¿ëÇÏ¿© ³ªÁß¿¡ ÄÄÆÄÀÏÇÏ¿© Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ¹®¼­´Â DSO ¸ðµâ »ç¿ë¹ý°ú ¹è°æ ÀÌ·ÐÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ±¸Çö

    + + + +

    ¾ÆÆÄÄ¡ Çٽɿ¡ Á¤ÀûÀ¸·Î ÄÄÆÄÀÏÇؾßÇÒ + mod_so.c¶ó´Â ¸ðµâÀº ¾ÆÆÄÄ¡ ¸ðµâÀ» + ÀоîµéÀ̱âÀ§ÇÑ DSO¸¦ Áö¿øÇÑ´Ù. + ÀÌ ¸ðµâÀº core¸¦ Á¦¿ÜÇÏ°í DSO°¡ + µÉ ¼ö ¾ø´Â À¯ÀÏÇÑ ¸ðµâÀÌ´Ù. ½ÇÁ¦·Î ´Ù¸¥ ¸ðµç ¾ÆÆÄÄ¡ ¸ðµâÀº + ¼³Ä¡ ¹®¼­¿¡¼­ ¼³¸íÇÑ + configureÀÇ --enable-module=shared + ¿É¼ÇÀ» »ç¿ëÇÏ¿© DSO·Î ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. ¸ðµâÀ» + mod_foo.so¿Í °°ÀÌ DSO·Î ÄÄÆÄÀÏÇÑÈÄ httpd.conf + ÆÄÀÏ¿¡ mod_soÀÇ + LoadModule ¸í·É¾î¸¦ + »ç¿ëÇÏ¿© ¼­¹ö ½ÃÀ۽à ȤÀº Àç½ÃÀ۽à ±× ¸ðµâÀ» ÀоîµéÀÏ ¼ö + ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¸ðµâ(ƯÈ÷ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ)·Î »ç¿ëÇÒ DSO ÆÄÀÏÀ» ½±°Ô + ¸¸µé±âÀ§ÇØ apxs (APache + eXtenSion)¶ó´Â »õ·Î¿î Áö¿ø ÇÁ·Î±×·¥ÀÌ ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº + ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ DSO·Î »ç¿ëÇÒ ¸ðµâÀ» + ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇÑ´Ù. °³³äÀº ½±´Ù. ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÒ¶§ + configure¿Í make installÀÌ + ¾ÆÆÄÄ¡ C Çì´õÆÄÀÏÀ» ¼³Ä¡ÇÏ°í, DSO ÆÄÀÏÀ» ÄÄÆÄÀÏÇϱâÀ§ÇÑ + Ç÷¡Æû ƯÀ¯ÀÇ ÄÄÆÄÀÏ·¯ ¿É¼Ç°ú ¸µÄ¿ ¿É¼ÇÀ» apxs + ÇÁ·Î±×·¥¿¡ ±â·ÏÇÑ´Ù. ±×·¡¼­ apxs¸¦ »ç¿ëÇÏ´Â »ç¿ëÀÚ´Â + ¾ÆÆÄÄ¡ ¹èÆ÷º» ¼Ò½º Æ®¸®¾øÀÌ, ¶Ç DSO Áö¿øÀ» À§ÇÑ Ç÷¡Æû ƯÀ¯ÀÇ + ÄÄÆÄÀÏ·¯ ¿É¼Ç¿Í ¸µÄ¿ ¿É¼Ç¿¡ ½Å°æÀ» ¾²Áö¾Ê°í ÀÚ½ÅÀÇ ¾ÆÆÄÄ¡ + ¸ðµâ ¼Ò½º¸¦ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    »ç¿ë¹ý ¿ä¾à

    + +

    Apache 2.0ÀÇ DSO ±â´É¿¡ ´ëÇÑ Âª°í °£·«ÇÑ ¿ä¾àÀÌ´Ù:

    + +
      +
    1. + ¹èÆ÷º»¿¡ ÀÖ´Â ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. ¿¹¸¦ µé¾î mod_foo.c¸¦ DSO + mod_foo.so·Î: + +

      +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +

      +
    2. + +
    3. + Á¦»ïÀÚ°¡ ¸¸µç ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. ¿¹¸¦ µé¾î mod_foo.c¸¦ DSO + mod_foo.so·Î: + +

      +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c --enable-foo=shared
      +$ make install +

      +
    4. + +
    5. + °øÀ¯ ¸ðµâÀ» ³ªÁß¿¡ »ç¿ëÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÏ´Â + °æ¿ì: + +

      +$ ./configure --enable-so
      +$ make install +

      +
    6. + +
    7. + Á¦»ïÀÚ°¡ ¸¸µç ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. apxs¸¦ »ç¿ëÇÏ¿© + ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ mod_foo.c¸¦ + DSO mod_foo.so·Î: + +

      +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +

      +
    8. +
    + +

    ¸ðµç °æ¿ì ÀÏ´Ü °øÀ¯ ¸ðµâÀÌ ÄÄÆÄÀϵǸé, httpd.conf¿¡ + LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ ±× ¸ðµâÀ» ÀоîµéÀÌ°Ô ¸¸µç´Ù.

    +
    top
    +
    +

    ¹è°æÁö½Ä

    + +

    Çö´ëÀûÀÎ À¯´Ð½º·ù¿¡´Â µ¿Àû°øÀ¯°´Ã¼ (DSO)ÀÇ + µ¿Àû ¸µÅ·/·Îµù(dynamic linking/loading)À̶ó°í ÇÏ¿©, Ưº°ÇÑ + Çü½ÄÀÇ ½ÇÇàÄÚµå Á¶°¢À» ¸¸µé¾î ½ÇÇàÁßÀÎ ½ÇÇàÇÁ·Î±×·¥ÀÇ + ÁÖ¼Ò°ø°£¿¡ ÀоîµéÀÌ´Â ¸ÚÁø ±â´ÉÀÌ ÀÖ´Ù.

    + +

    º¸Åë µÎ°¡Áö ¹æ¹ýÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Ù. Çϳª´Â ½ÇÇàÇÁ·Î±×·¥ÀÌ + ½ÃÀÛÇÒ¶§ ld.so¶ó´Â ½Ã½ºÅÛ ÇÁ·Î±×·¥ÀÌ ÀÚµ¿À¸·Î + ÀоîµéÀÌ´Â °æ¿ì°í, ´Ù¸¥ Çϳª´Â ½ÇÇàÁßÀÎ ÇÁ·Î±×·¥ÀÌ + dlopen()/dlsym() ½Ã½ºÅÛÈ£Ãâ·Î À¯´Ð½º ·Î´õ(loader)ÀÇ + ½Ã½ºÅÛ ÀÎÅÍÆäÀ̽ºÀ» »ç¿ëÇÏ¿© Á÷Á¢ ÀоîµéÀÌ´Â °æ¿ì´Ù.

    + +

    ù¹ø° °æ¿ì DSO¸¦ º¸Åë °øÀ¯¶óÀ̺귯¸®(shared libraries) + ȤÀº DSO ¶óÀ̺귯¸®¶ó°í ºÎ¸£¸ç, ÆÄÀÏÀº + libfoo.so³ª libfoo.so.1.2 °°Àº + À̸§À» °¡Áø´Ù. À̵éÀº ½Ã½ºÅÛ µð·ºÅ丮(º¸Åë /usr/lib)¿¡ + ÀÖ°í, ÄÄÆÄÀϽà ¸µÄ¿ ¸í·É¾î¿¡ -lfoo¸¦ ÁÖ¾î + ½ÇÇàÆÄÀÏ°ú ¿¬°áÇÑ´Ù. ÀÌ·¸°Ô Á÷Á¢ ½áÁØ ¶óÀ̺귯¸®´Â ½ÇÇàÆÄÀÏ¿¡ + ÂüÁ¶µÇ¿©¼­, ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÒ¶§ ¸µÄ¿ ¿É¼Ç -R·Î + Á÷Á¢ ÁöÁ¤ÇÑ °æ·Î, ȯ°æº¯¼ö LD_LIBRARY_PATH·Î + ÁöÁ¤ÇÑ °æ·Î ȤÀº /usr/lib¿¡¼­ À¯´Ð½º ·Î´õ°¡ + libfoo.so¸¦ ãÀ» ¼ö ÀÖ´Ù. ±×·¯¸é ½ÇÇàÇÁ·Î±×·¥ÀÇ + (¾ÆÁ÷ ¸øãÀº(unresolved)) ½Éº¼(symbol)À» DSO¿¡¼­ ã°ÔµÈ´Ù.

    + +

    DSO´Â º¸Åë ½ÇÇàÇÁ·Î±×·¥ÀÇ ½Éº¼À» ãÁö¾Ê±â ¶§¹®¿¡ (DSO°¡ + Àç»ç¿ë°¡´ÉÇÑ ÀϹÝÀûÀÎ ÄÚµå ¶óÀ̺귯¸®À̹ǷÎ) ã±â´Â ¿©±â¼­ + ³¡³­´Ù. À¯´Ð½º ·Î´õ°¡ ½Éº¼ ã±â¸¦ ¿ÏÀüÈ÷ ´ã´çÇϹǷΠ½ÇÇàÇÁ·Î±×·¥ÀÌ + Á÷Á¢ DSO¿¡¼­ ½Éº¼À» ãÀ» ÇÊ¿ä°¡ ¾ø´Ù. (»ç½Ç ld.so¸¦ + ºÎ¸£´Â ÄÚµå´Â Á¤ÀûÀÌ ¾Æ´Ñ ¸ðµç ½ÇÇàÇÁ·Î±×·¥¿¡ ¸µÅ©µÇ´Â ½ÇÇà½Ã + ½ÃÀÛÄÚµåÀÇ ÀϺδÙ.) °øÅëµÈ ¶óÀ̺귯¸® Äڵ带 µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â + ÀåÁ¡Àº ¸íÈ®ÇÏ´Ù. ¶óÀ̺귯¸® Äڵ尡 ¸ðµç ÇÁ·Î±×·¥¿¡ Áߺ¹Çؼ­ + ÀúÀåµÇ´Â ´ë½Å libc.so¿Í °°Àº ½Ã½ºÅÛ ¶óÀ̺귯¸®¿¡ + Çѹø¸¸ ÀúÀåµÇ±â ¶§¹®¿¡ µð½ºÅ© °ø°£ÀÌ Àý¾àµÈ´Ù.

    + +

    µÎ¹ø° °æ¿ì DSO¸¦ º¸Åë °øÀ¯°´Ã¼(shared objects) + ȤÀº DSO ÆÄÀÏÀ̶ó°í ºÎ¸£°í, (±ÔÄ¢»ó À̸§Àº + foo.soÀÌÁö¸¸) ÆÄÀÏÀÇ È®ÀåÀÚ´Â ÀÚÀ¯·Ó´Ù. ÀÌ + ÆÄÀϵéÀº º¸Åë ÇÁ·Î±×·¥ ÀÚü µð·ºÅ丮¿¡ À§Ä¡ÇÏ°í ½ÇÇàÇÁ·Î±×·¥¿¡ + ÀÚµ¿À¸·Î ¿¬°áµÇÁö ¾Ê´Â´Ù. ´ë½Å ½ÇÇàÇÁ·Î±×·¥Àº ½ÇÇà½Ã + dlopen()À» »ç¿ëÇÏ¿© DSO¸¦ ÁÖ¼Ò°ø°£¿¡ + Á÷Á¢ Àоîµé¿©¾ß ÇÑ´Ù. À̶§ ½ÇÇàÇÁ·Î±×·¥Àº DSO¿¡¼­ ½Éº¼À» + ãÁö ¾Ê´Â´Ù. ´ë½Å ¾Õ¿¡¼­ º» À¯´Ð½º ·Î´õ´Â ÀÚµ¿À¸·Î ½ÇÇàÆÄÀÏ°ú + ½ÇÇàÆÄÀÏÀÌ ÀÌ¹Ì ÀоîµéÀÎ DSO ¶óÀ̺귯¸®(ƯÈ÷ Ç×»ó Á¸ÀçÇÏ´Â + libc.soÀÇ ¸ðµç ½Éº¼)¿¡¼­ DSOÀÇ (¾ÆÁ÷ ¸øãÀº) + ½Éº¼À» ã´Â´Ù. ±×·¡¼­ DSO´Â ¸¶Ä¡ óÀ½ºÎÅÍ ½ÇÇàÇÁ·Î±×·¥¿¡ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ°Í°ú °°ÀÌ ½ÇÇàÆÄÀÏÀÇ ½Éº¼À» ¾Ë°ÔµÈ´Ù.

    + +

    DSOÀÇ API¸¦ ÀÌ¿ëÇϱâÀ§Çؼ­ ¸¶Áö¸·À¸·Î ½ÇÇàÇÁ·Î±×·¥Àº + dlsym()À¸·Î DSO¿¡¼­ ƯÁ¤ ½Éº¼À» ã¾Æ¼­, ¾ÕÀ¸·Î + »ç¿ëÇϱâÀ§ÇØ µð½ºÆÐÄ¡(dispatch) Ç¥ µî¿¡ ÀúÀåÇÑ´Ù. + ´Ù¸¥ ¸»·Î ½ÇÇàÇÁ·Î±×·¥Àº »ç¿ëÇÒ ¸ðµç ½Çº¼À» Á÷Á¢ ã¾Æ¾ßÇÑ´Ù. + ÀÌ·± ±¸Á¶ÀÇ ÀåÁ¡Àº ÇÁ·Î±×·¥ÀÇ ÀϺθ¦ ÇÁ·Î±×·¥ÀÌ + ÇÊ¿äÇÒ¶§±îÁö ÀоîµéÀÌÁö ¾Ê¾Æµµ (±×·¡¼­ ¸Þ¸ð¸®¸¦ ³¶ºñÇÏÁö + ¾Ê°Ô) µÈ´Ù´Â Á¡ÀÌ´Ù. ±âº» ÇÁ·Î±×·¥ÀÇ ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ + ÇÊ¿äÇÑ °æ¿ì ÀÌ ºÎºÐÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Ù.

    + +

    ÀÌ·± DSO ±¸Á¶°¡ ÀÚ¿¬½º·´°Ô º¸ÀÌÁö¸¸, ÃÖ¼ÒÇÑ ¾î·Á¿î Á¡ÀÌ + ÇÑ°¡ÁöÀÖ´Ù. ÇÁ·Î±×·¥À» È®ÀåÇϱâÀ§ÇØ DSO¸¦ »ç¿ëÇÒ¶§ DSO°¡ + ½ÇÇàÇÁ·Î±×·¥ÀÇ ½Éº¼À» ã´Â ÀÏÀÌ´Ù. ¿Ö? DSO°¡ ½ÇÇàÇÁ·Î±×·¥ÀÇ + ½Éº¼À» "¿ªÀ¸·Î ã´Â °Í"Àº (¶óÀ̺귯¸®´Â ÀÚ½ÅÀ» »ç¿ëÇÏ´Â ÇÁ·Î±×·¥¿¡ + ´ëÇØ ¸ð¸¥´Ù´Â) ¶óÀ̺귯¸® ¼³°è¿¡ ¹ÝÇϸç, ¸ðµç Ç÷¡Æû¿¡¼­ + Áö¿øµÇÁö¾Ê°í Ç¥ÁØÈ­µÇÁöµµ ¾Ê¾Ò±â ¶§¹®ÀÌ´Ù. ½ÇÁ¦·Î ½ÇÇàÆÄÀÏÀÇ + Àü¿ª½Éº¼(global symbol)Àº º¸Åë ÀͽºÆ÷Æ®(export)µÇÁö ¾Ê±â¶§¹®¿¡ + DSO°¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. DSO¸¦ »ç¿ëÇÏ¿© ½ÇÇàÁß ÇÁ·Î±×·¥À» È®ÀåÇÏ·Á¸é + ¸µÄ¿¿¡°Ô ¸ðµç Àü¿ª½Éº¼À» ÀͽºÆ÷Æ®Çϵµ·Ï °­Á¦ÇÏ´Â °ÍÀÌ ÁÖµÈ + ÇØ°áÃ¥ÀÌ´Ù.

    + +

    °øÀ¯¶óÀ̺귯¸®´Â DSO ¹æ½ÄÀÇ ¼³°è¿øÄ¢´ë·Î ÀüÇüÀûÀ̱⶧¹®¿¡ + ¿î¿µÃ¼Á¦°¡ Á¦°øÇÏ´Â °ÅÀÇ ¸ðµç Á¾·ùÀÇ ¶óÀ̺귯¸®°¡ »ç¿ëÇÑ´Ù. + ¹Ý´ë·Î ¸¹Àº ÇÁ·Î±×·¥Àº ÇÁ·Î±×·¥À» È®ÀåÇϱâÀ§ÇØ °øÀ¯°´Ã¼¸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.

    + +

    1998³â ½ÇÇàÁß ½ÇÁ¦·Î ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ DSO ±¸Á¶¸¦ »ç¿ëÇÑ + ¼ÒÇÁÆ®¿þ¾î ÆÐÅ°Áö´Â (XS ±¸Á¶¿Í DynaLoader ¸ðµâÀ» »ç¿ëÇÑ) + Perl 5, Netscape Server µîÀ¸·Î µå¹°¾ú´Ù. ¾ÆÆÄÄ¡´Â + ÀÌ¹Ì ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ ¸ðµâ °³³äÀ» »ç¿ëÇß°í ¿ÜºÎ ¸ðµâÀ» + ¾ÆÆÄÄ¡ Çٽɱâ´É¿¡ ¿¬°áÇϱâÀ§ÇØ ³»ºÎÀûÀ¸·Î µð½ºÆÐÄ¡¸ñ·ÏÀ» + ÀÌ¿ëÇÑ Á¢±Ù¹æ¹ýÀ» »ç¿ëÇ߱⶧¹®¿¡ 1.3 ¹öÀüºÎÅÍ ÀÌ ´ë¿­¿¡ ÇÕ·ùÇß´Ù. + ±×·¡¼­ ¾ÆÆÄÄ¡´Â ½ÇÇàÁß ¸ðµâÀ» ÀоîµéÀ̴µ¥ DSO¸¦ »ç¿ëÇϵµ·Ï + ¿î¸íÁö¿öÁ³´Ù.

    +
    top
    +
    +

    Àå´ÜÁ¡

    + +

    ¾Õ¿¡¼­ ¸»ÇÑ DSO¸¦ »ç¿ëÇÏ¸é ´ÙÀ½°ú °°Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ½ÇÁ¦ ¼­¹ö ÇÁ·Î¼¼½º°¡ ÄÄÆÄÀϽà configure + ¿É¼Ç´ë½Å httpd.confÀÇ LoadModuleÀ» »ç¿ëÇÏ¿© ½ÇÇàÁß¿¡ + °áÇյǹǷΠ¼­¹ö ÆÐÅ°Áö ½ÇÇàÀÌ ´õ À¯¿¬ÇÏ´Ù. ¿¹¸¦ µé¾î ÇѹøÀÇ + ¾ÆÆÄÄ¡ ¼³Ä¡¸¸À¸·Î ´Ù¸¥ ¼­¹ö(Ç¥ÁØ ¹öÀü°ú SSL ¹öÀü, ÃÖ¼ÒÈ­ + ¹öÀü°ú ±â´ÉÃß°¡ ¹öÀü [mod_perl, PHP3] µî)¸¦ ½ÇÇàÇÒ + ¼ö ÀÖ´Ù.
    • + +
    • ¼­¹ö´Â ¼³Ä¡ÈÄ¿¡µµ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» »ç¿ëÇÏ¿© ½±°Ô + È®ÀåÇÒ ¼ö ÀÖ´Ù. ÃÖ¼ÒÇÑ ±â¾÷ÀÇ ÆÐÅ°Áö Á¦ÀÛÀÚ´Â ¾ÆÆÄÄ¡ ÇÙ½É + ÆÐÅ°Áö¿Í º°µµ·Î PHP3, mod_perl, mod_fastcgi µîÀ» + Ãß°¡ ÆÐÅ°Áö·Î ¸¸µé ¼ö À־ Å« À̵æÀÌ´Ù.
    • + +
    • DSO¿Í apxs¸¦ °¡Áö°í ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ + ÀÛ¾÷ÇÏ°í apxs -i¿Í apachectl restart + ¸í·É¾î¸¸À¸·Î ÇöÀç °³¹ßÇÑ ¸ðµâÀÇ »õ ¹öÀüÀ» ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ + ¼­¹ö¿¡ ¹Ý¿µÇÒ ¼ö À־ ´õ ½±°Ô ¾ÆÆÄÄ¡ ¸ðµâÀ» °³¹ßÇÒ ¼ö + ÀÖ´Ù.
    • +
    + +

    DSO´Â ´ÙÀ½°ú °°Àº ´ÜÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ÇÁ·Î±×·¥ÀÇ ÁÖ¼Ò°ø°£¿¡ Äڵ带 µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â ±â´ÉÀ» + Áö¿øÇÏÁö¾Ê´Â ¿î¿µÃ¼Á¦°¡ Àֱ⠶§¹®¿¡ ¸ðµç Ç÷¡Æû¿¡¼­ DSO¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • + +
    • À¯´Ð½º ·Î´õ°¡ ½Éº¼À» ã¾Æ¾ßÇϱ⠶§¹®¿¡ ¼­¹ö ½ÃÀÛÀÌ + ¾à 20% Á¤µµ ´Ê¾îÁø´Ù.
    • + +
    • ¼­¹ö´Â À§Ä¡µ¶¸³ÄÚµå(position independent code, PIC) + ¶§¹®¿¡ Àý´ëÁÖ¼ÒÁöÁ¤(absolute addressing)º¸´Ù ´À¸° + »ó´ëÁÖ¼ÒÁöÁ¤(relative addressing)ÀÇ º¹ÀâÇÑ ¾î¼Àºí·¯ ±â¹ýÀÌ + ÇÊ¿äÇϹǷΠ¾î¶² Ç÷¡Æû¿¡¼­ ½ÇÇà½Ã ¾à 5% Á¤µµ ´Ê´Ù.
    • + +
    • DSO ¸ðµâÀ» ´Ù¸¥ DSO±â¹Ý ¶óÀ̺귯¸®(ld -lfoo)¿¡ + ¸µÅ©ÇÒ ¼ö ¾ø´Â Ç÷¡ÆûÀÌ Àֱ⶧¹®¿¡ (¿¹¸¦ µé¾î ELF±â¹Ý + Ç÷¡ÆûÀº Áö¿øÇÏÁö¸¸ a.out±â¹Ý Ç÷¡ÆûÀº º¸Åë ÀÌ ±â´ÉÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù) ¸ðµç Á¾·ùÀÇ ¸ðµâ¿¡ DSO¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù. + ´Ù¸¥ ¸»·Î DSO ÆÄÀÏ·Î ÄÄÆÄÀÏÇÏ´Â ¸ðµâÀº ¾ÆÆÄÄ¡ Çٽɰú ¾ÆÆÄÄ¡ + ÇÙ½ÉÀÌ »ç¿ëÇÏ´Â C ¶óÀ̺귯¸®(libc)¿Í ´Ù¸¥ + µ¿Àû/Á¤Àû ¶óÀ̺귯¸®, À§Ä¡µ¶¸³Äڵ带 ´ã°í ÀÖ´Â Á¤Àû ¶óÀ̺귯¸® + ¾ÆÄ«À̺ê(libfoo.a)ÀÇ ½Éº¼¸¸À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ´Ù¸¥ Äڵ带 »ç¿ëÇÏ·Á¸é ¾ÆÆÄÄ¡ ÇÙ½ÉÀÌ ±×°ÍÀ» ÂüÁ¶ÇÏ´øÁö, + dlopen()À¸·Î Á÷Á¢ Äڵ带 Àоîµé¿©¾ß ÇÑ´Ù.
    • +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/dso.xml b/trunk/docs/manual/dso.xml new file mode 100644 index 0000000000..f9860a634e --- /dev/null +++ b/trunk/docs/manual/dso.xml @@ -0,0 +1,314 @@ + + + + + + + + + + Dynamic Shared Object (DSO) Support + + +

    The Apache HTTP Server is a modular program where the + administrator can choose the functionality to include in the + server by selecting a set of modules. The modules can be + statically compiled into the httpd binary when the + server is built. Alternatively, modules can be compiled as + Dynamic Shared Objects (DSOs) that exist separately from the + main httpd binary file. DSO modules may be + compiled at the time the server is built, or they may be + compiled and added at a later time using the Apache Extension + Tool (apxs).

    + +

    This document describes how to use DSO modules as well as + the theory behind their use.

    +
    + + +
    Implementation + + + +mod_so + + +LoadModule + + + +

    The DSO support for loading individual Apache modules is based + on a module named mod_so which must be statically + compiled into the Apache core. It is the only module besides + core which cannot be put into a DSO + itself. Practically all other distributed Apache modules can then + be placed into a DSO by individually enabling the DSO build for + them via configure's + --enable-module=shared option as discussed + in the install documentation. After a + module is compiled into a DSO named mod_foo.so you + can use mod_so's LoadModule command in your + httpd.conf file to load this module at server startup + or restart.

    + +

    To simplify this creation of DSO files for Apache modules + (especially for third-party modules) a new support program + named apxs (APache + eXtenSion) is available. It can be used to build DSO based + modules outside of the Apache source tree. The idea is + simple: When installing Apache the configure's + make install procedure installs the Apache C + header files and puts the platform-dependent compiler and + linker flags for building DSO files into the apxs + program. This way the user can use apxs to compile + his Apache module sources without the Apache distribution + source tree and without having to fiddle with the + platform-dependent compiler and linker flags for DSO + support.

    +
    + +
    Usage Summary + +

    To give you an overview of the DSO features of Apache 2.0, + here is a short and concise summary:

    + +
      +
    1. + Build and install a distributed Apache module, say + mod_foo.c, into its own DSO + mod_foo.so: + + +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +
      +
    2. + +
    3. + Build and install a third-party Apache module, say + mod_foo.c, into its own DSO + mod_foo.so: + + +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c \
      + + --enable-foo=shared
      +
      +$ make install +
      +
    4. + +
    5. + Configure Apache for later installation of shared + modules: + + +$ ./configure --enable-so
      +$ make install +
      +
    6. + +
    7. + Build and install a third-party Apache module, say + mod_foo.c, into its own DSO + mod_foo.so outside of the Apache + source tree using apxs: + + +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +
      +
    8. +
    + +

    In all cases, once the shared module is compiled, you must + use a LoadModule + directive in httpd.conf to tell Apache to activate + the module.

    +
    + +
    Background + +

    On modern Unix derivatives there exists a nifty mechanism + usually called dynamic linking/loading of Dynamic Shared + Objects (DSO) which provides a way to build a piece of + program code in a special format for loading it at run-time + into the address space of an executable program.

    + +

    This loading can usually be done in two ways: Automatically + by a system program called ld.so when an + executable program is started or manually from within the + executing program via a programmatic system interface to the + Unix loader through the system calls + dlopen()/dlsym().

    + +

    In the first way the DSO's are usually called shared + libraries or DSO libraries and named + libfoo.so or libfoo.so.1.2. They + reside in a system directory (usually /usr/lib) + and the link to the executable program is established at + build-time by specifying -lfoo to the linker + command. This hard-codes library references into the executable + program file so that at start-time the Unix loader is able to + locate libfoo.so in /usr/lib, in + paths hard-coded via linker-options like -R or in + paths configured via the environment variable + LD_LIBRARY_PATH. It then resolves any (yet + unresolved) symbols in the executable program which are + available in the DSO.

    + +

    Symbols in the executable program are usually not referenced + by the DSO (because it's a reusable library of general code) + and hence no further resolving has to be done. The executable + program has no need to do anything on its own to use the + symbols from the DSO because the complete resolving is done by + the Unix loader. (In fact, the code to invoke + ld.so is part of the run-time startup code which + is linked into every executable program which has been bound + non-static). The advantage of dynamic loading of common library + code is obvious: the library code needs to be stored only once, + in a system library like libc.so, saving disk + space for every program.

    + +

    In the second way the DSO's are usually called shared + objects or DSO files and can be named with an + arbitrary extension (although the canonical name is + foo.so). These files usually stay inside a + program-specific directory and there is no automatically + established link to the executable program where they are used. + Instead the executable program manually loads the DSO at + run-time into its address space via dlopen(). At + this time no resolving of symbols from the DSO for the + executable program is done. But instead the Unix loader + automatically resolves any (yet unresolved) symbols in the DSO + from the set of symbols exported by the executable program and + its already loaded DSO libraries (especially all symbols from + the ubiquitous libc.so). This way the DSO gets + knowledge of the executable program's symbol set as if it had + been statically linked with it in the first place.

    + +

    Finally, to take advantage of the DSO's API the executable + program has to resolve particular symbols from the DSO via + dlsym() for later use inside dispatch tables + etc. In other words: The executable program has to + manually resolve every symbol it needs to be able to use it. + The advantage of such a mechanism is that optional program + parts need not be loaded (and thus do not spend memory) until + they are needed by the program in question. When required, + these program parts can be loaded dynamically to extend the + base program's functionality.

    + +

    Although this DSO mechanism sounds straightforward there is + at least one difficult step here: The resolving of symbols from + the executable program for the DSO when using a DSO to extend a + program (the second way). Why? Because "reverse resolving" DSO + symbols from the executable program's symbol set is against the + library design (where the library has no knowledge about the + programs it is used by) and is neither available under all + platforms nor standardized. In practice the executable + program's global symbols are often not re-exported and thus not + available for use in a DSO. Finding a way to force the linker + to export all global symbols is the main problem one has to + solve when using DSO for extending a program at run-time.

    + +

    The shared library approach is the typical one, because it + is what the DSO mechanism was designed for, hence it is used + for nearly all types of libraries the operating system + provides. On the other hand using shared objects for extending + a program is not used by a lot of programs.

    + +

    As of 1998 there are only a few software packages available + which use the DSO mechanism to actually extend their + functionality at run-time: Perl 5 (via its XS mechanism and the + DynaLoader module), Netscape Server, etc. Starting + with version 1.3, Apache joined the crew, because Apache + already uses a module concept to extend its functionality and + internally uses a dispatch-list-based approach to link external + modules into the Apache core functionality. So, Apache is + really predestined for using DSO to load its modules at + run-time.

    +
    + +
    Advantages and Disadvantages + +

    The above DSO based features have the following + advantages:

    + +
      +
    • The server package is more flexible at run-time because + the actual server process can be assembled at run-time via + LoadModule + httpd.conf configuration commands instead of + configure options at build-time. For instance + this way one is able to run different server instances + (standard & SSL version, minimalistic & powered up + version [mod_perl, PHP3], etc.) with only one Apache + installation.
    • + +
    • The server package can be easily extended with + third-party modules even after installation. This is at least + a great benefit for vendor package maintainers who can create + a Apache core package and additional packages containing + extensions like PHP3, mod_perl, mod_fastcgi, + etc.
    • + +
    • Easier Apache module prototyping because with the + DSO/apxs pair you can both work outside the + Apache source tree and only need an apxs -i + command followed by an apachectl restart to + bring a new version of your currently developed module into + the running Apache server.
    • +
    + +

    DSO has the following disadvantages:

    + +
      +
    • The DSO mechanism cannot be used on every platform + because not all operating systems support dynamic loading of + code into the address space of a program.
    • + +
    • The server is approximately 20% slower at startup time + because of the symbol resolving overhead the Unix loader now + has to do.
    • + +
    • The server is approximately 5% slower at execution time + under some platforms because position independent code (PIC) + sometimes needs complicated assembler tricks for relative + addressing which are not necessarily as fast as absolute + addressing.
    • + +
    • Because DSO modules cannot be linked against other + DSO-based libraries (ld -lfoo) on all platforms + (for instance a.out-based platforms usually don't provide + this functionality while ELF-based platforms do) you cannot + use the DSO mechanism for all types of modules. Or in other + words, modules compiled as DSO files are restricted to only + use symbols from the Apache core, from the C library + (libc) and all other dynamic or static libraries + used by the Apache core, or from static library archives + (libfoo.a) containing position independent code. + The only chances to use other code is to either make sure the + Apache core itself already contains a reference to it or + loading the code yourself via dlopen().
    • +
    + +
    + +
    diff --git a/trunk/docs/manual/dso.xml.ja b/trunk/docs/manual/dso.xml.ja new file mode 100644 index 0000000000..38139e4b91 --- /dev/null +++ b/trunk/docs/manual/dso.xml.ja @@ -0,0 +1,294 @@ + + + + + + + + + + $BF0E*6&M-%*%V%8%'%/%H(B (DSO) $B%5%]!<%H(B + + +

    Apache HTTP $B%5!<%P$O%b%8%e!<%k2=$5$l$?%W%m%0%i%`$G!"(B + $B4IM}httpd $B%P%$%J%j$K(B + $B@EE*$KAH$_9~$`$3$H$,$G$-$^$9!#$b$7$/$O!"(Bhttpd $B%P%$%J%j$H$O(B + $BJL$KB8:_$9$kF0E*6&M-%*%V%8%'%/%H(B ($BLuCm(B: Dynamic Shared Object) + (DSO) $B$H$7$F%3%s%Q%$%k$9$k$3$H$b(B + $B$G$-$^$9!#(BDSO $B%b%8%e!<%k$O%5!<%P$,%S%k%I$5$l$k$H$-$K%3%s%Q%$%k$7$?$j!"(B + Apache $B3HD%%D!<%k(B (apxs) $B$r(B + $B;H$C$F8e$G%3%s%Q%$%k$7$FDI2C$7$?$j$G$-$^$9!#(B

    + +

    $B$3$NJ8=q$O(B DSO $B%b%8%e!<%k$N;H$$J}$H!";EAH$_$K$D$$$F(B + $B@bL@$7$^$9!#(B

    +
    + + +
    $B<BAu(B + + + +mod_so + + +LoadModule + + + +

    $B8D!9$N(B Apache $B%b%8%e!<%k$r%m!<%I$9$k$?$a$N(B DSO $B%5%]!<%H$O(B + mod_so.c $B$H$$$&%b%8%e!<%k$N5!G=$K4p$E$$$F$$$^$9!#(B + $B$3$N%b%8%e!<%k(B $B$O(B Apache $B$N%3%"$K@EE*$KAH$_9~$^$l$F$$$kI,MW$,$"$j$^$9!#(B + $B$=$l$O(B core.c $B0J30$G$O(B DSO $B$K$G$-$J$$M#0l$N(B + $B%b%8%e!<%k$G$9!#;ve!"B>$N$9$Y$F$N(B Apache $B$N%b%8%e!<%k$O!"(B + $B%$%s%9%H!<%k$NJ8=q(B$B$G@bL@$5$l$F$$$k$h$&$K!"(B + configure $B$N(B + --enable-module=shared $B%*%W%7%g%s$G$=$l$>$l$r(B + DSO $B%S%k%I$K$9$k$3$H$K$h$j!"(BDSO $B%b%8%e!<%k$K$9$k$3$H$,$G$-$^$9!#(B + mod_foo.so $B$N$h$&$J(B DSO $B$K%b%8%e!<%k$,%3%s%Q%$%k$5$l$l$P!"(B + httpd.conf $B%U%!%$%kCf$G(B mod_so $B$N(B + LoadModule + $B%G%#%l%/%F%#%V$r;H$&$3$H$G%5!<%P$N5/F0$d:F5/F0;~$K$3$N%b%8%e!<%k$r(B + $B%m!<%I$9$k$h$&$K$G$-$^$9!#(B

    + +

    Apache $B%b%8%e!<%kMQ$N(B ($BFC$K%5!<%I%Q!<%F%#%b%8%e!<%k$N(B) DSO $B%U%!%$%k$N(B + $B:n@.$r4JC1$K$9$k$?$a$K!"(Bapxs + (APache eXtenSion) $B$H$$$&?7$7$$%5%]!<%H%W%m%0%i%`$,$"$j$^$9!#(B + Apache $B$N%=!<%9%D%j!<$N(B$B30$G(B DSO $B%b%8%e!<%k$r%S%k%I$9$k$?$a$K(B + $B;H$&$3$H$,$G$-$^$9!#H/A[$OC1=c$G$9(B: Apache $B$N%$%s%9%H!<%k;~$N(B + configure$B!"(Bmake install $B$N$H$-$K(B Apache $B$N(B + C $B%X%C%@$r%$%s%9%H!<%k$7!"(BDSO $B%S%k%IMQ$N%W%i%C%H%U%)!<%`0MB8$N(B + $B%3%s%Q%$%i$H%j%s%+$N%U%i%0$r(B apxs $B%W%m%0%i%`$KDI2C$7$^$9!#(B + $B$3$l$K$h$j!"%f!<%6$,(B Apache $B$NG[I[%=!<%9%D%j!<$J$7$G!"$5$i$K(B + DSO $B%5%]!<%H$N$?$a$N%W%i%C%H%U%)!<%`0MB8$N%3%s%Q%$%i$d%j%s%+$N(B + $B%U%i%0$r$$$8$k$3$H$J$/(B Apache $B$N%b%8%e!<%k$N%=!<%9$r%3%s%Q%$%k(B + $B$G$-$k$h$&$K$J$j$^$9!#(B

    +
    + +
    $B;HMQK!$N35MW(B + +

    Apache 2.0 $B$N(B DSO $B5!G=$N35N,$rCN$k$3$H$,$G$-$k$?$a$N!"(B + $BC;$/4J7i$J35MW$G$9(B:

    + +
      +
    1. + $BG[I[$5$l$F$$$k(B Apache $B%b%8%e!<%k!"2>$K(B mod_foo.c + $B$H$7$F!"$=$l$r(B DSO mod_foo.so $B$K%S%k%I!"%$%s%9%H!<%k(B: + + +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +
      +
    2. + +
    3. + $B%5!<%I%Q!<%F%#(B Apache $B%b%8%e!<%k!"2>$K(B mod_foo.c + $B$H$7$F!"$=$l$r(B DSO mod_foo.so $B$K%S%k%I!"%$%s%9%H!<%k(B: + + +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c \
      + + --enable-foo=shared
      +
      +$ make install +
      +
    4. + +
    5. + $B6&M-%b%8%e!<%k$N(B $B8e!9$N%$%s%9%H!<%k(B $B$N$?$a$K(B + Apache $B$r@_Dj(B: + + +$ ./configure --enable-so
      +$ make install +
      +
    6. + +
    7. + $B%5!<%I%Q!<%F%#(B Apache $B%b%8%e!<%k!"2>$K(B mod_foo.c + $B$H$7$F!"$=$l$r(B apxs $B$r;H$C$F(B + Apache $B%=!<%9%D%j!<$N(B$B30$G(B DSO $B$K%S%k%I!"%$%s%9%H!<%k(B: + + +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +
      +
    8. +
    + +

    $B$I$N>l9g$K$*$$$F$b!"6&M-%b%8%e!<%k$r%3%s%Q%$%k$7$?8e$G!"(B + httpd.conf $B$G(B + LoadModule + $B%G%#%l%/%F%#%V$r;H$C$F(B Apache $B$,%b%8%e!<%k$r;HMQ$9$k$h$&$K(B + $B$7$J$1$l$P$J$j$^$;$s!#(B

    +
    + +
    $BGX7J(B + +

    $B:G6a$N(B Unix $B7O$N(B OS $B$K$O(B $BF0E*6&M-%*%V%8%'%/%H(B (DSO) + $B$NF0E*%j%s%/(B/$B%m!<%I$H$$$&5$$N$-$$$?5!9=$,(B + $BB8:_$7$^$9!#$3$l$O!" + +

    $B$3$N%m!<%I$OFs$D$NJ}K!$G9T$J$&$3$H$,$G$-$^$9(B: $Bld.so $B$H$$$&%7%9%F%`%W%m%0%i%`(B + $B$K$h$j<+F0E*$K9T$J$o$l$kJ}K!$H!"dlopen()/dlsym() $B$K$h$k(B Unix $B%m!<%@$X$N(B + $B%W%m%0%i%`%7%9%F%`$N%$%s%?%U%'!<%9$r;H$C$F + +

    $B:G=i$NJ}K!$G$O(B DSO $B$OIaDL$O(B$B6&M-%i%$%V%i%j(B$B$d(B DSO + $B%i%$%V%i%j(B $B$H8F$P$l$F$$$F!"(BDSO $B$NL>A0$O(B + libfoo.so $B$d(B libfoo.so.1.2 $B$N$h$&$K$J$C$F$$$^$9!#(B + $B$3$l$i$O%7%9%F%`%G%#%l%/%H%j(B ($BDL>o(B /usr/lib) $B$KB8:_$7!"(B + $B-lfoo $B$r%j%s%+$K(B + $B;XDj$9$k$3$H$G3NN)$5$l$^$9!#$3$l$K$h$j%i%$%V%i%j$X$N;2>H$,/usr/lib $B$d!"(B + $B%j%s%+$N(B -R $B$N$h$&$J%*%W%7%g%s$K$h$j%O!<%I%3!<%I$5$l$?%Q%9!"(B + $B4D6-JQ?t(B LD_LIBRARY_PATH $B$K$h$j@_Dj$5$l$?%Q%9!"$NCf$+$i(B + libfoo.so $B$N>l=j$r8+$D$1$k$3$H$,$G$-$^$9!#$=$l$+$i!"(B + $B + +

    $BIaDL$OH$5$l$^$;$s(B + (DSO $B$O0lHLE*$J%3!<%I$K$h$k:FMxMQ2DG=$J%i%$%V%i%j$G$9$N$G(B)$B!#(B + $B$G$9$+$i!"$5$i$J$k%7%s%\%k$N2r7h$OI,MW$"$j$^$;$s!#(B + $B%7%s%\%k$O(B Unix $B%m!<%@$K$h$j40A4$J2r7h$,9T$J$o$l$^$9$N$G!"ld.so $B$r5/F0$9$k%3!<%I$,4^$^$l$F$$$^$9(B)$B!#$h$/;H$o$l$k(B + $B%i%$%V%i%j$NF0E*%m!<%I$NMxE@$OL@$i$+$G$9!#%i%$%V%i%j$N%3!<%I$O(B + $B%7%9%F%`%i%$%V%i%j$K(B libc.so $B$N$h$&$K$7$F0lEYJ]B8$9$k$@$1$G$h$/!"(B + $B%W%m%0%i%`$N$?$a$KI,MW$J%G%#%9%/$NNN0h$r@aLs$9$k$3$H$,$G$-$^$9!#(B

    + +

    $BFs$D$a$NJ}K!$G$O(B DSO $B$OIaDL$O(B$B6&M-%*%V%8%'%/%H(B$B$d(B + DSO $B%U%!%$%k(B$B$H8F$P$l$F$$$F!"G$0U$N3HD%;R$rIU$1$k$3$H$,$G$-$^$9(B + ($B$?$@$7!"I8=`E*$JL>A0$O(B foo.so $B$G$9(B)$B!#(B + $B$3$l$i$N%U%!%$%k$ODL>o$O%W%m%0%i%`@lMQ$N%G%#%l%/%H%j$KCV$+$l!"(B + $B$3$l$i$r;H$&dlopen() $B$r;H$C$F(B + $Blibc.so $B$N$9$Y$F$N%7%s%\%k(B) $B$G<+F0E*$K2r7h$7$^$9!#(B + $B$3$&$9$k$3$H$G!"(BDSO $B$O:G=i$+$i@EE*$K%j%s%/$5$l$F$$$?$+$N$h$&$K!"(B + $B + +

    $B:G8e$K!"(BDSO $B$N(B API $B$rMxE@$r@8$+$9$?$a$K!"%W%m%0%i%`$O(B + $B8e$G%G%#%9%Q%C%A%F!<%V%k(B$B$J$I(B$B$G%7%s%\%k$r;H$&$3$H$,$G$-$k$h$&$K!"(B + dlsym() $B$r;H$C$F$$$/$D$+$N%7%s%\%k$r2r7h$7$^$9!#(B + $B$9$J$o$A(B: $BCHq$7$J$$(B) + $B$3$H$G$9!#I,MW$J$i$P!"4pK\%W%m%0%i%`$N5!G=$r3HD%$9$k$?$a$K(B + $B$3$l$i$NItJ,$rF0E*$K%m!<%I$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$N(B DSO $B5!9=$O4JC1$J$h$&$K8+$($^$9$,!">/$J$/$H$b0l$DFq$7$$E@$,(B + $B$"$j$^$9(B: $B%W%m%0%i%`$r3HD%$9$k$?$a$K(B DSO $B$r;H$C$F$$$k$H$-$K!"(B + DSO $B$, + +

    $B6&M-%i%$%V%i%j$N%"%W%m!<%A$,IaDL$NJ}K!$G$9!#(BDSO $B5!9=$O$=$N$?$a$K(B + $B@_7W$5$l$?$b$N$G$9$+$i!#$7$?$,$C$F!"$=$NJ}K!$O%*%Z%l!<%F%#%s%0%7%9%F%`$,(B + $BDs6!$9$k$[$H$s$I$9$Y$F$N + +

    1998 $BG/$N;~E@$G!"/$7$@$1$G$7$?(B: Perl 5 (XS $B5!9=$H(B DnaLoader $B%b%8%e!<%k(B + $B$K$h$k$b$N(B)$B!"(BNetscape $B%5!<%P(B$B$J$I(B$B$G$9!#(BApache $B$O$9$G$K(B + $B%b%8%e!<%k$N35G0$r;H$C$F5!G=3HD%$r$7$F$$$F!"FbItE*$K%G%#%9%Q%C%A%j%9%H$K(B + $B4p$E$$$?30It%b%8%e!<%k$N(B Apache $B%3%"5!G=$X$N%j%s%/$r9T$J$C$F$$$^$7$?$N$G!"(B + $B%P!<%8%g%s(B 1.3 $B$+$i!"(BApache $B$b(B DSO $B5!9=$r;H$&Cg4V$K$J$j$^$7$?!#(B + Apache $B$O +

    + +
    $BMxE@$H7gE@(B + +

    $B>e5-$N(B DSO $B$K4p$E$$$?5!G=$O0J2<$NMxE@$,$"$j$^$9(B:

    + +
      +
    • $Bconfigure $B$N%*%W%7%g%s$r;H$&Be$o$j$K(B + $Bhttpd.conf $B$N@_DjMQ%3%^%s%I(B + LoadModule + $B$r;H$&$3$H$,$G$-$^$9$N$G!"%5!<%P%Q%C%1!<%8$N=@Fp@-$,9b$^$j$^$7$?!#(B + $B$?$H$($P!"0l$D$N(B Apache $B$N%$%s%9%H!<%k$+$i(B + $B0c$&9=@.$N%5!<%P(B ($BI8=`HG$H(B SSL $BHG!":G>.9=@.$H3HD%HG(B [mod_perl, PHP3] + $B$J$I(B) $B$r + +
    • $B%$%s%9%H!<%k$N8e$G$"$C$F$b!"%5!<%P$N%Q%C%1!<%8$r%5!<%I%Q!<%F%#(B + $B%b%8%e!<%k$G4JC1$K3HD%$G$-$k$h$&$K$J$j$^$7$?!#$3$l$O!"(BApache $B%3%"(B + $B%Q%C%1!<%8$H!"(BPHP3, mod_perl, mod_fastcgi $B$J$I(B $B$NDI2C$N(B + $B%Q%C%1!<%8$r:n@.$G$-$k$N$G!">/$J$/$H$b%Y%s%@$N%Q%C%1!<%84IM} + +
    • Apache $B%b%8%e!<%k$N3+H/$,4JC1$K$J$j$^$9!#(B + $B$3$l$O(B DSO $B$H(B apxs $B$NAH$_9g$o$;$K$h$j!"(BApache $B%=!<%9%D%j!<$N(B + $B30$G:n6H$G$-!"3+H/Cf$N%b%8%e!<%k$N?7$7$$%P!<%8%g%s$r(B + $Bapxs -i $B$H(B + apachectl restart $B$r9T$J$&$@$1$GNI$/$J$k$+$i$G$9!#(B
    • +
    + +

    DSO $B$K$O0J2<$N7gE@$,$"$j$^$9(B:

    + +
      +
    • $B$9$Y$F$N%*%Z%l!<%F%#%s%0%7%9%F%`$,%W%m%0%i%`$N%"%I%l%96u4V$K(B + $B%3!<%I$rF0E*%m!<%I$9$k$3$H$r%5%]!<%H$7$F$$$k$o$G$O$J$$$N$G!"(B + $B%W%i%C%H%U%)!<%`$K$h$C$F$O(B DSO $B5!9=$O;H$($^$;$s!#(B
    • + +
    • Unix $B$N%m!<%@$,%7%s%\%k$N2r7h$r$9$kI,MW$,$G$-$?$N$G!"(B + $B$=$N%*!<%P%X%C%I$K$h$j%5!<%P$N5/F0;~4V$,Ls(B 20% $BCY$/$J$C$F$$$^$9!#(B
    • + +
    • $B0LCVHs0MB8%3!<%I(B (PIC) ($BLuCm(B position independent code) $B$O(B + $BAjBP%"%I%l%9$N$?$a$KJ#;($J%"%;%s%V%i$N%H%j%C%/$,I,MW$J$3$H$,$"$j!"(B + $B$=$l$OI,$:$7$b@dBP%"%I%l%9$HF1$8$/$i$$$NB.EY$,$G$k$o$1$G$O$"$j$^$;$s$N$G!"(B + $B%W%i%C%H%U%)!<%`$K$h$C$F$O%5!<%P$N + +
    • DSO $B%b%8%e!<%k$O$9$Y$F$N%W%i%C%H%U%)!<%`$GB>$N(B DSO $B$K4p$E$$$?(B + $B%i%$%V%i%j$KBP$7$F%j%s%/$G$-$k(B (ld -lfoo) + $B$H$$$&$o$1$G$O$"$j$^$;$s$N$G(B ($B$?$H$($P!"(Ba.out $B$N%W%i%C%H%U%)!<%`$G$O(B + $B$3$N5!G=$O$"$j$^$;$s$,!"(BELF $B$N%W%i%C%H%U%)!<%`$K$O$"$j$^$9(B)$B!"(B + $B$9$Y$F$Nlibc) $B$H(B + Apache $B%3%"$,;H$C$F$$$kB>$N$9$Y$F$N@EE*$J%i%$%V%i%j$HF0E*%i%$%V%i%j$N(B + $B%7%s%\%k!"(BPIC $B$K$h$k@EE*$J%i%$%V%i%j(B (libfoo.a) $B$N(B + $B%7%s%\%k$N$_$K@)8B$5$l$^$9!#$=$NB>$N%3!<%I$r;H$&J}K!$O!"(B + Apache $B%3%"<+?H$,$9$G$K$=$N%3!<%I$X$N;2>H$,$"$k$h$&$K$9$k$+!"(B + dlopen () $B$r;H$C$F%3!<%I$r<+J,<+?H$G%m!<%I$9$k$+$N(B + $B$I$A$i$+$7$+$"$j$^$;$s!#(B
    • +
    + +
    + +
    diff --git a/trunk/docs/manual/dso.xml.ko b/trunk/docs/manual/dso.xml.ko new file mode 100644 index 0000000000..6212bf3530 --- /dev/null +++ b/trunk/docs/manual/dso.xml.ko @@ -0,0 +1,273 @@ + + + + + + + + + + µ¿Àû°øÀ¯°´Ã¼ (DSO) Áö¿ø + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â °ü¸®ÀÚ°¡ ¸ðµâµéÀ» ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» °áÁ¤ÇÒ ¼ö ÀÖ´Â ¸ðµâÈ­µÈ ÇÁ·Î±×·¥ÀÌ´Ù. ¼­¹ö¸¦ ÄÄÆÄÇÒ¶§ + httpd ½ÇÇàÆÄÀÏ¿¡ Á¤ÀûÀ¸·Î ¸ðµâÀ» ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù. ¾Æ´Ï¸é ¸ðµâÀ» httpd ½ÇÇàÆÄÀÏ°ú + ºÐ¸®ÇÏ¿© µ¿Àû°øÀ¯°´Ã¼(Dynamic Shared Objects, DSO)·Î ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù. DSO ¸ðµâÀº ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ ÄÄÆÄÀÏÇϰųª, Apache + Extension Tool (apxs)À» + »ç¿ëÇÏ¿© ³ªÁß¿¡ ÄÄÆÄÀÏÇÏ¿© Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ¹®¼­´Â DSO ¸ðµâ »ç¿ë¹ý°ú ¹è°æ ÀÌ·ÐÀ» ¼³¸íÇÑ´Ù.

    +
    + + +
    ±¸Çö + + + +mod_so + + +LoadModule + + + +

    ¾ÆÆÄÄ¡ Çٽɿ¡ Á¤ÀûÀ¸·Î ÄÄÆÄÀÏÇؾßÇÒ + mod_so.c¶ó´Â ¸ðµâÀº ¾ÆÆÄÄ¡ ¸ðµâÀ» + ÀоîµéÀ̱âÀ§ÇÑ DSO¸¦ Áö¿øÇÑ´Ù. + ÀÌ ¸ðµâÀº core¸¦ Á¦¿ÜÇÏ°í DSO°¡ + µÉ ¼ö ¾ø´Â À¯ÀÏÇÑ ¸ðµâÀÌ´Ù. ½ÇÁ¦·Î ´Ù¸¥ ¸ðµç ¾ÆÆÄÄ¡ ¸ðµâÀº + ¼³Ä¡ ¹®¼­¿¡¼­ ¼³¸íÇÑ + configureÀÇ --enable-module=shared + ¿É¼ÇÀ» »ç¿ëÇÏ¿© DSO·Î ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. ¸ðµâÀ» + mod_foo.so¿Í °°ÀÌ DSO·Î ÄÄÆÄÀÏÇÑÈÄ httpd.conf + ÆÄÀÏ¿¡ mod_soÀÇ + LoadModule ¸í·É¾î¸¦ + »ç¿ëÇÏ¿© ¼­¹ö ½ÃÀ۽à ȤÀº Àç½ÃÀ۽à ±× ¸ðµâÀ» ÀоîµéÀÏ ¼ö + ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¸ðµâ(ƯÈ÷ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ)·Î »ç¿ëÇÒ DSO ÆÄÀÏÀ» ½±°Ô + ¸¸µé±âÀ§ÇØ apxs (APache + eXtenSion)¶ó´Â »õ·Î¿î Áö¿ø ÇÁ·Î±×·¥ÀÌ ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº + ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ DSO·Î »ç¿ëÇÒ ¸ðµâÀ» + ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇÑ´Ù. °³³äÀº ½±´Ù. ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÒ¶§ + configure¿Í make installÀÌ + ¾ÆÆÄÄ¡ C Çì´õÆÄÀÏÀ» ¼³Ä¡ÇÏ°í, DSO ÆÄÀÏÀ» ÄÄÆÄÀÏÇϱâÀ§ÇÑ + Ç÷¡Æû ƯÀ¯ÀÇ ÄÄÆÄÀÏ·¯ ¿É¼Ç°ú ¸µÄ¿ ¿É¼ÇÀ» apxs + ÇÁ·Î±×·¥¿¡ ±â·ÏÇÑ´Ù. ±×·¡¼­ apxs¸¦ »ç¿ëÇÏ´Â »ç¿ëÀÚ´Â + ¾ÆÆÄÄ¡ ¹èÆ÷º» ¼Ò½º Æ®¸®¾øÀÌ, ¶Ç DSO Áö¿øÀ» À§ÇÑ Ç÷¡Æû ƯÀ¯ÀÇ + ÄÄÆÄÀÏ·¯ ¿É¼Ç¿Í ¸µÄ¿ ¿É¼Ç¿¡ ½Å°æÀ» ¾²Áö¾Ê°í ÀÚ½ÅÀÇ ¾ÆÆÄÄ¡ + ¸ðµâ ¼Ò½º¸¦ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    »ç¿ë¹ý ¿ä¾à + +

    Apache 2.0ÀÇ DSO ±â´É¿¡ ´ëÇÑ Âª°í °£·«ÇÑ ¿ä¾àÀÌ´Ù:

    + +
      +
    1. + ¹èÆ÷º»¿¡ ÀÖ´Â ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. ¿¹¸¦ µé¾î mod_foo.c¸¦ DSO + mod_foo.so·Î: + + +$ ./configure --prefix=/path/to/install --enable-foo=shared
      +$ make install +
      +
    2. + +
    3. + Á¦»ïÀÚ°¡ ¸¸µç ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. ¿¹¸¦ µé¾î mod_foo.c¸¦ DSO + mod_foo.so·Î: + + +$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c --enable-foo=shared
      +$ make install +
      +
    4. + +
    5. + °øÀ¯ ¸ðµâÀ» ³ªÁß¿¡ »ç¿ëÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÏ´Â + °æ¿ì: + + +$ ./configure --enable-so
      +$ make install +
      +
    6. + +
    7. + Á¦»ïÀÚ°¡ ¸¸µç ¾ÆÆÄÄ¡ ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â + °æ¿ì. apxs¸¦ »ç¿ëÇÏ¿© + ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ mod_foo.c¸¦ + DSO mod_foo.so·Î: + + +$ cd /path/to/3rdparty
      +$ apxs -c mod_foo.c
      +$ apxs -i -a -n foo mod_foo.la +
      +
    8. +
    + +

    ¸ðµç °æ¿ì ÀÏ´Ü °øÀ¯ ¸ðµâÀÌ ÄÄÆÄÀϵǸé, httpd.conf¿¡ + LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ ±× ¸ðµâÀ» ÀоîµéÀÌ°Ô ¸¸µç´Ù.

    +
    + +
    ¹è°æÁö½Ä + +

    Çö´ëÀûÀÎ À¯´Ð½º·ù¿¡´Â µ¿Àû°øÀ¯°´Ã¼ (DSO)ÀÇ + µ¿Àû ¸µÅ·/·Îµù(dynamic linking/loading)À̶ó°í ÇÏ¿©, Ưº°ÇÑ + Çü½ÄÀÇ ½ÇÇàÄÚµå Á¶°¢À» ¸¸µé¾î ½ÇÇàÁßÀÎ ½ÇÇàÇÁ·Î±×·¥ÀÇ + ÁÖ¼Ò°ø°£¿¡ ÀоîµéÀÌ´Â ¸ÚÁø ±â´ÉÀÌ ÀÖ´Ù.

    + +

    º¸Åë µÎ°¡Áö ¹æ¹ýÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Ù. Çϳª´Â ½ÇÇàÇÁ·Î±×·¥ÀÌ + ½ÃÀÛÇÒ¶§ ld.so¶ó´Â ½Ã½ºÅÛ ÇÁ·Î±×·¥ÀÌ ÀÚµ¿À¸·Î + ÀоîµéÀÌ´Â °æ¿ì°í, ´Ù¸¥ Çϳª´Â ½ÇÇàÁßÀÎ ÇÁ·Î±×·¥ÀÌ + dlopen()/dlsym() ½Ã½ºÅÛÈ£Ãâ·Î À¯´Ð½º ·Î´õ(loader)ÀÇ + ½Ã½ºÅÛ ÀÎÅÍÆäÀ̽ºÀ» »ç¿ëÇÏ¿© Á÷Á¢ ÀоîµéÀÌ´Â °æ¿ì´Ù.

    + +

    ù¹ø° °æ¿ì DSO¸¦ º¸Åë °øÀ¯¶óÀ̺귯¸®(shared libraries) + ȤÀº DSO ¶óÀ̺귯¸®¶ó°í ºÎ¸£¸ç, ÆÄÀÏÀº + libfoo.so³ª libfoo.so.1.2 °°Àº + À̸§À» °¡Áø´Ù. À̵éÀº ½Ã½ºÅÛ µð·ºÅ丮(º¸Åë /usr/lib)¿¡ + ÀÖ°í, ÄÄÆÄÀϽà ¸µÄ¿ ¸í·É¾î¿¡ -lfoo¸¦ ÁÖ¾î + ½ÇÇàÆÄÀÏ°ú ¿¬°áÇÑ´Ù. ÀÌ·¸°Ô Á÷Á¢ ½áÁØ ¶óÀ̺귯¸®´Â ½ÇÇàÆÄÀÏ¿¡ + ÂüÁ¶µÇ¿©¼­, ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÒ¶§ ¸µÄ¿ ¿É¼Ç -R·Î + Á÷Á¢ ÁöÁ¤ÇÑ °æ·Î, ȯ°æº¯¼ö LD_LIBRARY_PATH·Î + ÁöÁ¤ÇÑ °æ·Î ȤÀº /usr/lib¿¡¼­ À¯´Ð½º ·Î´õ°¡ + libfoo.so¸¦ ãÀ» ¼ö ÀÖ´Ù. ±×·¯¸é ½ÇÇàÇÁ·Î±×·¥ÀÇ + (¾ÆÁ÷ ¸øãÀº(unresolved)) ½Éº¼(symbol)À» DSO¿¡¼­ ã°ÔµÈ´Ù.

    + +

    DSO´Â º¸Åë ½ÇÇàÇÁ·Î±×·¥ÀÇ ½Éº¼À» ãÁö¾Ê±â ¶§¹®¿¡ (DSO°¡ + Àç»ç¿ë°¡´ÉÇÑ ÀϹÝÀûÀÎ ÄÚµå ¶óÀ̺귯¸®À̹ǷÎ) ã±â´Â ¿©±â¼­ + ³¡³­´Ù. À¯´Ð½º ·Î´õ°¡ ½Éº¼ ã±â¸¦ ¿ÏÀüÈ÷ ´ã´çÇϹǷΠ½ÇÇàÇÁ·Î±×·¥ÀÌ + Á÷Á¢ DSO¿¡¼­ ½Éº¼À» ãÀ» ÇÊ¿ä°¡ ¾ø´Ù. (»ç½Ç ld.so¸¦ + ºÎ¸£´Â ÄÚµå´Â Á¤ÀûÀÌ ¾Æ´Ñ ¸ðµç ½ÇÇàÇÁ·Î±×·¥¿¡ ¸µÅ©µÇ´Â ½ÇÇà½Ã + ½ÃÀÛÄÚµåÀÇ ÀϺδÙ.) °øÅëµÈ ¶óÀ̺귯¸® Äڵ带 µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â + ÀåÁ¡Àº ¸íÈ®ÇÏ´Ù. ¶óÀ̺귯¸® Äڵ尡 ¸ðµç ÇÁ·Î±×·¥¿¡ Áߺ¹Çؼ­ + ÀúÀåµÇ´Â ´ë½Å libc.so¿Í °°Àº ½Ã½ºÅÛ ¶óÀ̺귯¸®¿¡ + Çѹø¸¸ ÀúÀåµÇ±â ¶§¹®¿¡ µð½ºÅ© °ø°£ÀÌ Àý¾àµÈ´Ù.

    + +

    µÎ¹ø° °æ¿ì DSO¸¦ º¸Åë °øÀ¯°´Ã¼(shared objects) + ȤÀº DSO ÆÄÀÏÀ̶ó°í ºÎ¸£°í, (±ÔÄ¢»ó À̸§Àº + foo.soÀÌÁö¸¸) ÆÄÀÏÀÇ È®ÀåÀÚ´Â ÀÚÀ¯·Ó´Ù. ÀÌ + ÆÄÀϵéÀº º¸Åë ÇÁ·Î±×·¥ ÀÚü µð·ºÅ丮¿¡ À§Ä¡ÇÏ°í ½ÇÇàÇÁ·Î±×·¥¿¡ + ÀÚµ¿À¸·Î ¿¬°áµÇÁö ¾Ê´Â´Ù. ´ë½Å ½ÇÇàÇÁ·Î±×·¥Àº ½ÇÇà½Ã + dlopen()À» »ç¿ëÇÏ¿© DSO¸¦ ÁÖ¼Ò°ø°£¿¡ + Á÷Á¢ Àоîµé¿©¾ß ÇÑ´Ù. À̶§ ½ÇÇàÇÁ·Î±×·¥Àº DSO¿¡¼­ ½Éº¼À» + ãÁö ¾Ê´Â´Ù. ´ë½Å ¾Õ¿¡¼­ º» À¯´Ð½º ·Î´õ´Â ÀÚµ¿À¸·Î ½ÇÇàÆÄÀÏ°ú + ½ÇÇàÆÄÀÏÀÌ ÀÌ¹Ì ÀоîµéÀÎ DSO ¶óÀ̺귯¸®(ƯÈ÷ Ç×»ó Á¸ÀçÇÏ´Â + libc.soÀÇ ¸ðµç ½Éº¼)¿¡¼­ DSOÀÇ (¾ÆÁ÷ ¸øãÀº) + ½Éº¼À» ã´Â´Ù. ±×·¡¼­ DSO´Â ¸¶Ä¡ óÀ½ºÎÅÍ ½ÇÇàÇÁ·Î±×·¥¿¡ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ°Í°ú °°ÀÌ ½ÇÇàÆÄÀÏÀÇ ½Éº¼À» ¾Ë°ÔµÈ´Ù.

    + +

    DSOÀÇ API¸¦ ÀÌ¿ëÇϱâÀ§Çؼ­ ¸¶Áö¸·À¸·Î ½ÇÇàÇÁ·Î±×·¥Àº + dlsym()À¸·Î DSO¿¡¼­ ƯÁ¤ ½Éº¼À» ã¾Æ¼­, ¾ÕÀ¸·Î + »ç¿ëÇϱâÀ§ÇØ µð½ºÆÐÄ¡(dispatch) Ç¥ µî¿¡ ÀúÀåÇÑ´Ù. + ´Ù¸¥ ¸»·Î ½ÇÇàÇÁ·Î±×·¥Àº »ç¿ëÇÒ ¸ðµç ½Çº¼À» Á÷Á¢ ã¾Æ¾ßÇÑ´Ù. + ÀÌ·± ±¸Á¶ÀÇ ÀåÁ¡Àº ÇÁ·Î±×·¥ÀÇ ÀϺθ¦ ÇÁ·Î±×·¥ÀÌ + ÇÊ¿äÇÒ¶§±îÁö ÀоîµéÀÌÁö ¾Ê¾Æµµ (±×·¡¼­ ¸Þ¸ð¸®¸¦ ³¶ºñÇÏÁö + ¾Ê°Ô) µÈ´Ù´Â Á¡ÀÌ´Ù. ±âº» ÇÁ·Î±×·¥ÀÇ ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ + ÇÊ¿äÇÑ °æ¿ì ÀÌ ºÎºÐÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Ù.

    + +

    ÀÌ·± DSO ±¸Á¶°¡ ÀÚ¿¬½º·´°Ô º¸ÀÌÁö¸¸, ÃÖ¼ÒÇÑ ¾î·Á¿î Á¡ÀÌ + ÇÑ°¡ÁöÀÖ´Ù. ÇÁ·Î±×·¥À» È®ÀåÇϱâÀ§ÇØ DSO¸¦ »ç¿ëÇÒ¶§ DSO°¡ + ½ÇÇàÇÁ·Î±×·¥ÀÇ ½Éº¼À» ã´Â ÀÏÀÌ´Ù. ¿Ö? DSO°¡ ½ÇÇàÇÁ·Î±×·¥ÀÇ + ½Éº¼À» "¿ªÀ¸·Î ã´Â °Í"Àº (¶óÀ̺귯¸®´Â ÀÚ½ÅÀ» »ç¿ëÇÏ´Â ÇÁ·Î±×·¥¿¡ + ´ëÇØ ¸ð¸¥´Ù´Â) ¶óÀ̺귯¸® ¼³°è¿¡ ¹ÝÇϸç, ¸ðµç Ç÷¡Æû¿¡¼­ + Áö¿øµÇÁö¾Ê°í Ç¥ÁØÈ­µÇÁöµµ ¾Ê¾Ò±â ¶§¹®ÀÌ´Ù. ½ÇÁ¦·Î ½ÇÇàÆÄÀÏÀÇ + Àü¿ª½Éº¼(global symbol)Àº º¸Åë ÀͽºÆ÷Æ®(export)µÇÁö ¾Ê±â¶§¹®¿¡ + DSO°¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. DSO¸¦ »ç¿ëÇÏ¿© ½ÇÇàÁß ÇÁ·Î±×·¥À» È®ÀåÇÏ·Á¸é + ¸µÄ¿¿¡°Ô ¸ðµç Àü¿ª½Éº¼À» ÀͽºÆ÷Æ®Çϵµ·Ï °­Á¦ÇÏ´Â °ÍÀÌ ÁÖµÈ + ÇØ°áÃ¥ÀÌ´Ù.

    + +

    °øÀ¯¶óÀ̺귯¸®´Â DSO ¹æ½ÄÀÇ ¼³°è¿øÄ¢´ë·Î ÀüÇüÀûÀ̱⶧¹®¿¡ + ¿î¿µÃ¼Á¦°¡ Á¦°øÇÏ´Â °ÅÀÇ ¸ðµç Á¾·ùÀÇ ¶óÀ̺귯¸®°¡ »ç¿ëÇÑ´Ù. + ¹Ý´ë·Î ¸¹Àº ÇÁ·Î±×·¥Àº ÇÁ·Î±×·¥À» È®ÀåÇϱâÀ§ÇØ °øÀ¯°´Ã¼¸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.

    + +

    1998³â ½ÇÇàÁß ½ÇÁ¦·Î ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ DSO ±¸Á¶¸¦ »ç¿ëÇÑ + ¼ÒÇÁÆ®¿þ¾î ÆÐÅ°Áö´Â (XS ±¸Á¶¿Í DynaLoader ¸ðµâÀ» »ç¿ëÇÑ) + Perl 5, Netscape Server µîÀ¸·Î µå¹°¾ú´Ù. ¾ÆÆÄÄ¡´Â + ÀÌ¹Ì ±â´ÉÀ» È®ÀåÇϱâÀ§ÇØ ¸ðµâ °³³äÀ» »ç¿ëÇß°í ¿ÜºÎ ¸ðµâÀ» + ¾ÆÆÄÄ¡ Çٽɱâ´É¿¡ ¿¬°áÇϱâÀ§ÇØ ³»ºÎÀûÀ¸·Î µð½ºÆÐÄ¡¸ñ·ÏÀ» + ÀÌ¿ëÇÑ Á¢±Ù¹æ¹ýÀ» »ç¿ëÇ߱⶧¹®¿¡ 1.3 ¹öÀüºÎÅÍ ÀÌ ´ë¿­¿¡ ÇÕ·ùÇß´Ù. + ±×·¡¼­ ¾ÆÆÄÄ¡´Â ½ÇÇàÁß ¸ðµâÀ» ÀоîµéÀ̴µ¥ DSO¸¦ »ç¿ëÇϵµ·Ï + ¿î¸íÁö¿öÁ³´Ù.

    +
    + +
    Àå´ÜÁ¡ + +

    ¾Õ¿¡¼­ ¸»ÇÑ DSO¸¦ »ç¿ëÇÏ¸é ´ÙÀ½°ú °°Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ½ÇÁ¦ ¼­¹ö ÇÁ·Î¼¼½º°¡ ÄÄÆÄÀϽà configure + ¿É¼Ç´ë½Å httpd.confÀÇ LoadModuleÀ» »ç¿ëÇÏ¿© ½ÇÇàÁß¿¡ + °áÇյǹǷΠ¼­¹ö ÆÐÅ°Áö ½ÇÇàÀÌ ´õ À¯¿¬ÇÏ´Ù. ¿¹¸¦ µé¾î ÇѹøÀÇ + ¾ÆÆÄÄ¡ ¼³Ä¡¸¸À¸·Î ´Ù¸¥ ¼­¹ö(Ç¥ÁØ ¹öÀü°ú SSL ¹öÀü, ÃÖ¼ÒÈ­ + ¹öÀü°ú ±â´ÉÃß°¡ ¹öÀü [mod_perl, PHP3] µî)¸¦ ½ÇÇàÇÒ + ¼ö ÀÖ´Ù.
    • + +
    • ¼­¹ö´Â ¼³Ä¡ÈÄ¿¡µµ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» »ç¿ëÇÏ¿© ½±°Ô + È®ÀåÇÒ ¼ö ÀÖ´Ù. ÃÖ¼ÒÇÑ ±â¾÷ÀÇ ÆÐÅ°Áö Á¦ÀÛÀÚ´Â ¾ÆÆÄÄ¡ ÇÙ½É + ÆÐÅ°Áö¿Í º°µµ·Î PHP3, mod_perl, mod_fastcgi µîÀ» + Ãß°¡ ÆÐÅ°Áö·Î ¸¸µé ¼ö À־ Å« À̵æÀÌ´Ù.
    • + +
    • DSO¿Í apxs¸¦ °¡Áö°í ¾ÆÆÄÄ¡ ¼Ò½º Æ®¸® ¹Û¿¡¼­ + ÀÛ¾÷ÇÏ°í apxs -i¿Í apachectl restart + ¸í·É¾î¸¸À¸·Î ÇöÀç °³¹ßÇÑ ¸ðµâÀÇ »õ ¹öÀüÀ» ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ + ¼­¹ö¿¡ ¹Ý¿µÇÒ ¼ö À־ ´õ ½±°Ô ¾ÆÆÄÄ¡ ¸ðµâÀ» °³¹ßÇÒ ¼ö + ÀÖ´Ù.
    • +
    + +

    DSO´Â ´ÙÀ½°ú °°Àº ´ÜÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ÇÁ·Î±×·¥ÀÇ ÁÖ¼Ò°ø°£¿¡ Äڵ带 µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â ±â´ÉÀ» + Áö¿øÇÏÁö¾Ê´Â ¿î¿µÃ¼Á¦°¡ Àֱ⠶§¹®¿¡ ¸ðµç Ç÷¡Æû¿¡¼­ DSO¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • + +
    • À¯´Ð½º ·Î´õ°¡ ½Éº¼À» ã¾Æ¾ßÇϱ⠶§¹®¿¡ ¼­¹ö ½ÃÀÛÀÌ + ¾à 20% Á¤µµ ´Ê¾îÁø´Ù.
    • + +
    • ¼­¹ö´Â À§Ä¡µ¶¸³ÄÚµå(position independent code, PIC) + ¶§¹®¿¡ Àý´ëÁÖ¼ÒÁöÁ¤(absolute addressing)º¸´Ù ´À¸° + »ó´ëÁÖ¼ÒÁöÁ¤(relative addressing)ÀÇ º¹ÀâÇÑ ¾î¼Àºí·¯ ±â¹ýÀÌ + ÇÊ¿äÇϹǷΠ¾î¶² Ç÷¡Æû¿¡¼­ ½ÇÇà½Ã ¾à 5% Á¤µµ ´Ê´Ù.
    • + +
    • DSO ¸ðµâÀ» ´Ù¸¥ DSO±â¹Ý ¶óÀ̺귯¸®(ld -lfoo)¿¡ + ¸µÅ©ÇÒ ¼ö ¾ø´Â Ç÷¡ÆûÀÌ Àֱ⶧¹®¿¡ (¿¹¸¦ µé¾î ELF±â¹Ý + Ç÷¡ÆûÀº Áö¿øÇÏÁö¸¸ a.out±â¹Ý Ç÷¡ÆûÀº º¸Åë ÀÌ ±â´ÉÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù) ¸ðµç Á¾·ùÀÇ ¸ðµâ¿¡ DSO¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù. + ´Ù¸¥ ¸»·Î DSO ÆÄÀÏ·Î ÄÄÆÄÀÏÇÏ´Â ¸ðµâÀº ¾ÆÆÄÄ¡ Çٽɰú ¾ÆÆÄÄ¡ + ÇÙ½ÉÀÌ »ç¿ëÇÏ´Â C ¶óÀ̺귯¸®(libc)¿Í ´Ù¸¥ + µ¿Àû/Á¤Àû ¶óÀ̺귯¸®, À§Ä¡µ¶¸³Äڵ带 ´ã°í ÀÖ´Â Á¤Àû ¶óÀ̺귯¸® + ¾ÆÄ«À̺ê(libfoo.a)ÀÇ ½Éº¼¸¸À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ´Ù¸¥ Äڵ带 »ç¿ëÇÏ·Á¸é ¾ÆÆÄÄ¡ ÇÙ½ÉÀÌ ±×°ÍÀ» ÂüÁ¶ÇÏ´øÁö, + dlopen()À¸·Î Á÷Á¢ Äڵ带 Àоîµé¿©¾ß ÇÑ´Ù.
    • +
    + +
    + +
    diff --git a/trunk/docs/manual/dso.xml.meta b/trunk/docs/manual/dso.xml.meta new file mode 100644 index 0000000000..318174a753 --- /dev/null +++ b/trunk/docs/manual/dso.xml.meta @@ -0,0 +1,13 @@ + + + + dso + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/env.html b/trunk/docs/manual/env.html new file mode 100644 index 0000000000..1bc4533824 --- /dev/null +++ b/trunk/docs/manual/env.html @@ -0,0 +1,11 @@ +URI: env.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: env.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: env.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/env.html.en b/trunk/docs/manual/env.html.en new file mode 100644 index 0000000000..b683edf276 --- /dev/null +++ b/trunk/docs/manual/env.html.en @@ -0,0 +1,405 @@ + + + +Environment Variables in Apache - Apache HTTP Server + + + + + +
    <-
    +

    Environment Variables in Apache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    The Apache HTTP Server provides a mechanism for storing + information in named variables that are called environment + variables. This information can be used to control various + operations such as logging or access control. The variables are + also used as a mechanism to communicate with external programs + such as CGI scripts. This document discusses different ways to + manipulate and use these variables.

    + +

    Although these variables are referred to as environment + variables, they are not the same as the environment + variables controlled by the underlying operating system. + Instead, these variables are stored and manipulated in an + internal Apache structure. They only become actual operating + system environment variables when they are provided to CGI + scripts and Server Side Include scripts. If you wish to + manipulate the operating system environment under which the + server itself runs, you must use the standard environment + manipulation mechanisms provided by your operating system + shell.

    +
    + +
    top
    +
    +

    Setting Environment Variables

    + + + +

    Basic Environment Manipulation

    + + +

    The most basic way to set an environment variable in Apache + is using the unconditional SetEnv directive. Variables may also be passed from + the environment of the shell which started the server using the + PassEnv directive.

    + + +

    Conditional Per-Request Settings

    + + +

    For additional flexibility, the directives provided by + mod_setenvif allow environment variables to be set on a + per-request basis, conditional on characteristics of particular + requests. For example, a variable could be set only when a + specific browser (User-Agent) is making a request, or only when + a specific Referer [sic] header is found. Even more flexibility + is available through the mod_rewrite's RewriteRule which uses the + [E=...] option to set environment variables.

    + + +

    Unique Identifiers

    + + +

    Finally, mod_unique_id sets the environment variable + UNIQUE_ID for each request to a value which is + guaranteed to be unique across "all" requests under very + specific conditions.

    + + +

    Standard CGI Variables

    + + +

    In addition to all environment variables set within the + Apache configuration and passed from the shell, CGI scripts and + SSI pages are provided with a set of environment variables + containing meta-information about the request as required by + the CGI + specification.

    + + +

    Some Caveats

    + + +
      +
    • It is not possible to override or change the standard CGI + variables using the environment manipulation directives.
    • + +
    • When suexec is used to launch + CGI scripts, the environment will be cleaned down to a set of + safe variables before CGI scripts are launched. The + list of safe variables is defined at compile-time in + suexec.c.
    • + +
    • For portability reasons, the names of environment + variables may contain only letters, numbers, and the + underscore character. In addition, the first character may + not be a number. Characters which do not match this + restriction will be replaced by an underscore when passed to + CGI scripts and SSI pages.
    • +
    + +
    top
    +
    +

    Using Environment Variables

    + + + + +

    CGI Scripts

    + + +

    One of the primary uses of environment variables is to + communicate information to CGI scripts. As discussed above, the + environment passed to CGI scripts includes standard + meta-information about the request in addition to any variables + set within the Apache configuration. For more details, see the + CGI tutorial.

    + + +

    SSI Pages

    + + +

    Server-parsed (SSI) documents processed by mod_include's + INCLUDES filter can print environment variables + using the echo element, and can use environment + variables in flow control elements to makes parts of a page + conditional on characteristics of a request. Apache also + provides SSI pages with the standard CGI environment variables + as discussed above. For more details, see the SSI tutorial.

    + + +

    Access Control

    + + +

    Access to the server can be controlled based on the value of + environment variables using the allow from env= + and deny from env= directives. In combination with + SetEnvIf, this + allows for flexible control of access to the server based on + characteristics of the client. For example, you can use these + directives to deny access to a particular browser (User-Agent). +

    + + +

    Conditional Logging

    + + +

    Environment variables can be logged in the access log using + the LogFormat + option %e. In addition, the decision on whether + or not to log requests can be made based on the status of + environment variables using the conditional form of the + CustomLog + directive. In combination with SetEnvIf this allows for flexible control of which + requests are logged. For example, you can choose not to log + requests for filenames ending in gif, or you can + choose to only log requests from clients which are outside your + subnet.

    + + +

    Conditional Response Headers

    + + +

    The Header + directive can use the presence or + absence of an environment variable to determine whether or not + a certain HTTP header will be placed in the response to the + client. This allows, for example, a certain response header to + be sent only if a corresponding header is received in the + request from the client.

    + + + +

    External Filter Activation

    + + +

    External filters configured by mod_ext_filter + using the ExtFilterDefine directive can + by activated conditional on an environment variable using the + disableenv= and enableenv= options.

    + + +

    URL Rewriting

    + + +

    The %{ENV:...} form of TestString in + the RewriteCond + allows mod_rewrite's rewrite + engine to make decisions conditional on environment variables. + Note that the variables accessible in mod_rewrite without the + ENV: prefix are not actually environment + variables. Rather, they are variables special to mod_rewrite + which cannot be accessed from other modules.

    + +
    top
    +
    +

    Special Purpose Environment Variables

    + + +

    Interoperability problems have led to the introduction of + mechanisms to modify the way Apache behaves when talking to + particular clients. To make these mechanisms as flexible as + possible, they are invoked by defining environment variables, + typically with BrowserMatch, though SetEnv and PassEnv could also be used, for example.

    + +

    downgrade-1.0

    + + +

    This forces the request to be treated as a HTTP/1.0 request + even if it was in a later dialect.

    + + +

    force-gzip

    + +

    If you have the DEFLATE filter activated, this + environment variable will ignore the accept-encoding setting of + your browser and will send compressed output unconditionally.

    + +

    force-no-vary

    + + +

    This causes any Vary fields to be removed from + the response header before it is sent back to the client. Some + clients don't interpret this field correctly; setting this + variable can work around this problem. Setting this variable + also implies force-response-1.0.

    + + +

    force-response-1.0

    + + +

    This forces an HTTP/1.0 response to clients making an HTTP/1.0 + request. It was originally + implemented as a result of a problem with AOL's proxies. Some + HTTP/1.0 clients may not behave correctly when given an HTTP/1.1 + response, and this can be used to interoperate with them.

    + + + +

    gzip-only-text/html

    + + +

    When set to a value of "1", this variable disables the DEFLATE + output filter provided by mod_deflate for + content-types other than text/html. If you'd rather + use statically compressed files; mod_negotiation + evaluates the variable as well (not only for gzip, but for all + encodings that differ from "identity").

    + + +

    no-gzip

    + +

    When set, the DEFLATE filter of + mod_deflate will be turned off and + mod_negotiation will refuse to deliver encoded + resources.

    + + + +

    nokeepalive

    + + +

    This disables KeepAlive + when set.

    + + + +

    prefer-language

    + +

    This influences mod_negotiation's behaviour. If + it contains a language tag (such as en, ja + or x-klingon), mod_negotiation tries + to deliver a variant with that language. If there's no such variant, + the normal negotiation process + applies.

    + + + +

    redirect-carefully

    + + +

    This forces the server to be more careful when sending a redirect + to the client. This is typically used when a client has a known + problem handling redirects. This was originally implemented as a + result of a problem with Microsoft's WebFolders software which has + a problem handling redirects on directory resources via DAV + methods.

    + + + +

    suppress-error-charset

    + + +

    Available in versions 2.2 and later

    + +

    When Apache issues a redirect in response to a client request, + the response includes some actual text to be displayed in case + the client can't (or doesn't) automatically follow the redirection. + Apache ordinarily labels this text according to the character set + which it uses, which is ISO-8859-1.

    +

    However, if the redirection is to a page that uses a different + character set, some broken browser versions will try to use the + character set from the redirection text rather than the actual page. + This can result in Greek, for instance, being incorrectly rendered.

    +

    Setting this environment variable causes Apache to omit the character + set for the redirection text, and these broken browsers will then correctly + use that of the destination page.

    + + + +
    top
    +
    +

    Examples

    + + +

    Changing protocol behavior with misbehaving clients

    + + +

    We recommend that the following lines be included in + httpd.conf to deal with known client problems.

    +
    +#
    +# The following directives modify normal HTTP response behavior.
    +# The first directive disables keepalive for Netscape 2.x and browsers that
    +# spoof it. There are known problems with these browser implementations.
    +# The second directive is for Microsoft Internet Explorer 4.0b2
    +# which has a broken HTTP/1.1 implementation and does not properly
    +# support keepalive when it is used on 301 or 302 (redirect) responses.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# The following directive disables HTTP/1.1 responses to browsers which
    +# are in violation of the HTTP/1.0 spec by not being able to grok a
    +# basic 1.1 response.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + + +

    Do not log requests for images in the access log

    + + +

    This example keeps requests for images from appearing in the + access log. It can be easily modified to prevent logging of + particular directories, or to prevent logging of requests + coming from particular hosts.

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + + +

    Prevent "Image Theft"

    + + +

    This example shows how to keep people not on your server + from using images on your server as inline-images on their + pages. This is not a recommended configuration, but it can work + in limited circumstances. We assume that all your images are in + a directory called /web/images.

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Allow browsers that do not send Referer info
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    For more information about this technique, see the + ApacheToday tutorial " + Keeping Your Images from Adorning Other Sites".

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/env.html.ja.euc-jp b/trunk/docs/manual/env.html.ja.euc-jp new file mode 100644 index 0000000000..6725ef11ba --- /dev/null +++ b/trunk/docs/manual/env.html.ja.euc-jp @@ -0,0 +1,393 @@ + + + +Apache ¤Î´Ä¶­ÊÑ¿ô - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¤Î´Ä¶­ÊÑ¿ô

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Apache HTTP ¥µ¡¼¥Ð¤Ï´Ä¶­ÊÑ¿ô¤È¸Æ¤Ð¤ì¤ë¡¢Ì¾Á°¤Î¤Ä¤¤¤¿ + ÊÑ¿ô¤Ë¾ðÊó¤òµ­²±¤¹¤ë»ÅÁȤߤòÄ󶡤·¤Æ¤¤¤Þ¤¹¡£¤³¤Î¾ðÊó¤Ï¥í¥°¼ý½¸¤ä + ¥¢¥¯¥»¥¹À©¸æ¤Ê¤É¤Î¤¤¤í¤¤¤í¤ÊÁàºî¤òÀ©¸æ¤¹¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤ÎÊÑ¿ô¤Ï CGI ¥¹¥¯¥ê¥×¥È¤Ê¤É¤Î³°Éô¥×¥í¥°¥é¥à¤ÈÄÌ¿®¤¹¤ë¤¿¤á¤Ë¤â + »È¤ï¤ì¤Þ¤¹¡£¤³¤Îʸ½ñ¤Ï¤½¤ì¤é¤ÎÊÑ¿ô¤ÎÁàºîÊýË¡¤È»ÈÍÑÊýË¡¤ò¤¤¤¯¤Ä¤« + ¾Ò²ð¤·¤Þ¤¹¡£

    + +

    ¤³¤ì¤é¤ÎÊÑ¿ô¤Ï´Ä¶­ÊÑ¿ô¤È¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥° + ¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤ÆÀ©¸æ¤µ¤ì¤Æ¤¤¤ë´Ä¶­ÊÑ¿ô¤ÈƱ¤¸¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¼ÂºÝ¤Ï¡¢¤³¤ì¤é¤ÎÊÑ¿ô¤Ï Apache ¤ÎÆâÉô¹½Â¤¤ÎÃæ¤Ëµ­²±¤µ¤ì¡¢Áàºî¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤½¤ì¤é¤Ï¡¢CGI ¤ä SSI ¥¹¥¯¥ê¥×¥È¤ËÅϤµ¤ì¤¿¤È¤­¤À¤±¡¢¼ÂºÝ¤Î + ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î´Ä¶­ÊÑ¿ô¤Ë¤Ê¤ê¤Þ¤¹¡£¥µ¡¼¥Ð¼«¿È¤¬ + ¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î´Ä¶­¤òÁàºî¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¥·¥§¥ë¤¬Ä󶡤·¤Æ¤¤¤ëɸ½à¤Î´Ä¶­ÊÑ¿ô¤Î + ÁàºîÊýË¡¤ò»È¤ï¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    ´Ä¶­ÊÑ¿ô¤ÎÀßÄê

    + + + +

    ´ðËÜŪ¤Ê´Ä¶­¤ÎÁàºî

    + + +

    Apache ¤Ë¤ª¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë°ìÈÖ´ðËÜŪ¤ÊÊýË¡¤Ï¡¢ + ̵¾ò·ï¤Ë´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë SetEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¤¹¡£ + PassEnv + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢Apache ¤¬µ¯Æ°¤µ¤ì¤¿¥·¥§¥ë¤Î + ´Ä¶­ÊÑ¿ô¤òÅϤ¹¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + + +

    ¥ê¥¯¥¨¥¹¥ÈËè¤Ë¾ò·ï¤Ë´ð¤Å¤¤¤ÆÀßÄꤹ¤ë

    + + +

    ¤è¤ê½ÀÆðÀ­¤ò¹â¤á¤ë¤¿¤á¤Ë¡¢mod_setenvif + ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢¥ê¥¯¥¨¥¹¥È¤Î + ÆÃÀ­¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢ÆÃÄê¤Î¥Ö¥é¥¦¥¶ + (User-Agent) ¤Î¥ê¥¯¥¨¥¹¥È¤äÆÃÄê¤Î Referer [°Õ¿ÞŪ¤ÊÄÖ¤ê¤Ç¤¹] + (ÌõÃí: Àµ¤·¤¤ÄÖ¤ê¤Ï referrer ¤Ç¤¹¤¬¡¢HTTP ¤Î»ÅÍÍ¤Ç¤Ï Referer + ¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹) ¥Ø¥Ã¥À¤¬¸«¤Ä¤«¤Ã¤¿¤È¤­¤Î¤ßÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + mod_rewrite ¤Î RewriteRule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤ª¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë [E=...] + ¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + ¤è¤ê½ÀÆð¤ÊÀßÄê¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +

    °ì°Õ¤Ê¼±ÊÌ»Ò

    + + +

    mod_unique_id ¤Ï¡¢Èó¾ï¤Ë¸Â¤é¤ì¤¿¾ò·ï¤Î²¼¤Ç + ¡Ö¤¹¤Ù¤Æ¡×¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤Ä¤¤¤Æ¡¢°ì°Õ¤Ç¤¢¤ë¤³¤È¤¬Êݾڤµ¤ì¤Æ¤¤¤ëÃͤò´Ä¶­ÊÑ¿ô + UNIQUE_ID ¤ËÀßÄꤷ¤Þ¤¹¡£

    + + +

    ɸ½à CGI ÊÑ¿ô

    + + +

    Apache ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ÇÀßÄꤵ¤ì¤¿´Ä¶­ÊÑ¿ô¤È¥·¥§¥ë¤«¤éÅϤµ¤ì¤ë + ´Ä¶­ÊÑ¿ô¤Ë²Ã¤¨¤Æ¡¢CGI ¥¹¥¯¥ê¥×¥È¤È SSI ¥Ú¡¼¥¸¤Ë¤Ï CGI ¤Î»ÅÍͤÇÍ׵ᤵ¤ì¤Æ¤¤¤ë¡¢ + ¥ê¥¯¥¨¥¹¥È¤Î¥á¥¿¾ðÊó¤ò»ý¤Ã¤¿´Ä¶­ÊÑ¿ô¤ÎÁȤ¬Ä󶡤µ¤ì¤Þ¤¹¡£

    + + +

    ¤¤¤¯¤Ä¤«¤ÎÃí°Õ

    + + +
      +
    • ´Ä¶­¤òÁàºî¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æɸ½à CGI + ÊÑ¿ô¤ò¾å½ñ¤­¤·¤¿¤êÊѹ¹¤·¤¿¤ê¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£
    • + +
    • CGI ¥¹¥¯¥ê¥×¥È¤òµ¯Æ°¤¹¤ë¤¿¤á¤Ë suexec + ¤¬»ÈÍѤµ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢CGI ¥¹¥¯¥ê¥×¥È¤¬µ¯Æ°¤¹¤ë¤¿¤á¤Ë¡¢´Ä¶­ÊÑ¿ô¤Ï°ÂÁ´¤Ê´Ä¶­ÊÑ¿ô¤ÎÁȤËÀ°Íý¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î°ÂÁ´¤Ê´Ä¶­ÊÑ¿ô¤Î½¸¹ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥ë»þ¤Ë suexec.c + ¤ÇÄêµÁ¤µ¤ì¤Þ¤¹¡£
    • + +
    • °Ü¿¢À­¤Î¤¿¤á¤Ë¡¢´Ä¶­ÊÑ¿ô¤Î̾Á°¤Ï¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¡¢ + ¿ô»ú¤È¥¢¥ó¥À¡¼¥¹¥³¥¢ (ÌõÃí: '_') ¤À¤±¤«¤éÀ®¤ê¤Þ¤¹¡£ + ¤µ¤é¤Ë¡¢ºÇ½é¤Îʸ»ú¤Ï¿ô»ú¤Ç¤¢¤Ã¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£ + ¤³¤ÎÀ©¸Â¤Ë¹ç¤ï¤Ê¤¤Ê¸»ú¤Ï CGI ¥¹¥¯¥ê¥×¥È¤È SSI + ¥Ú¡¼¥¸¤ËÅϤµ¤ì¤ë¤È¤­¤Ë¥¢¥ó¥À¡¼¥¹¥³¥¢¤ËÃÖ´¹¤µ¤ì¤Þ¤¹¡£
    • +
    + +
    top
    +
    +

    ´Ä¶­ÊÑ¿ô¤Î»ÈÍÑ

    + + + + +

    CGI ¥¹¥¯¥ê¥×¥È

    + + +

    ´Ä¶­ÊÑ¿ô¤Î¼ç¤ÊÍøÍÑË¡¤Î°ì¤Ä¤Ï¡¢CGI ¥¹¥¯¥ê¥×¥È¤Ë¾ðÊó¤òÅÁ¤¨¤ë¤³¤È¤Ç¤¹¡£ + ¾å¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢CGI ¥¹¥¯¥ê¥×¥È¤ËÅϤµ¤ì¤ë´Ä¶­ÊÑ¿ô¤Ï Apache + ¤ÎÀßÄê¤Ë¤è¤êÀßÄꤵ¤ì¤ëÊÑ¿ô¤Ë²Ã¤¨¤Æ¡¢¥ê¥¯¥¨¥¹¥È¤Îɸ½à¤Î¥á¥¿¾ðÊó¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£ + ¾ÜºÙ¤Ï CGI ¥Á¥å¡¼¥È¥ê¥¢¥ë + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + +

    SSI ¥Ú¡¼¥¸

    + + +

    mod_include ¤Î INCLUDES ¥Õ¥£¥ë¥¿¤Ç½èÍý¤µ¤ì¤ë + server-parsed (SSI) ¥É¥­¥å¥á¥ó¥È¤Ç¤Ï¡¢echo + Í×ÁǤò»ÈÍѤ¹¤ë¤È´Ä¶­ÊÑ¿ô¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£ + ¤Þ¤¿¡¢¥Ú¡¼¥¸¤Î¤¢¤ëÉôʬ¤¬¥ê¥¯¥¨¥¹¥È¤ÎÀ­¼Á¤Ë±þ¤¸¤ÆÊѹ¹¤µ¤ì¤ë¤è¤¦¤Ë¡¢ + ´Ä¶­ÊÑ¿ô¤ò¥Õ¥í¡¼À©¸æÍ×ÁǤǻȤ¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¾ÜºÙ¤Ï + SSI ¥Á¥å¡¼¥È¥ê¥¢¥ë ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + +

    ¥¢¥¯¥»¥¹À©¸æ

    + + +

    allow from env= ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È deny from env= + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹¤ò´Ä¶­ÊÑ¿ô¤ÎÃͤÇÀ©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + SetEnvIf + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÎÆÃÀ­¤Ë´ð¤Å¤¤¤Æ + ¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹À©¸æ¤ò½ÀÆð¤Ë¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ÆÃÄê¤Î¥Ö¥é¥¦¥¶ (User-Agent) + ¤«¤é¤Î¥¢¥¯¥»¥¹¤òµñÈݤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +

    ¾ò·ïÉÕ¤­¥í¥°µ­Ï¿

    + + +

    LogFormat + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥ª¥×¥·¥ç¥ó %e + ¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢´Ä¶­ÊÑ¿ô¤ò¥¢¥¯¥»¥¹¥í¥°¤Ëµ­Ï¿¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤µ¤é¤Ë¡¢ + CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¾ò·ïʬ´ô¼°¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + ´Ä¶­ÊÑ¿ô¤ÎÃͤˤè¤Ã¤Æ¥ê¥¯¥¨¥¹¥È¤ò¥í¥°¤Ëµ­Ï¿¤¹¤ë¤«¤É¤¦¤«¤ò·è¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + SetEnvIf + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¡¢ + ¤É¤Î¥ê¥¯¥¨¥¹¥È¤ò¥í¥°¤Ëµ­Ï¿¤¹¤ë¤«¤ò½ÀÆð¤ËÀ©¸æ¤¹¤ë¤³¤È¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ + gif ¤Ç½ª¤ï¤ë¥Õ¥¡¥¤¥ë̾¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¥í¥°¤Ëµ­Ï¿¤·¤Ê¤¤¡¢ + °ã¤¦¥µ¥Ö¥Í¥Ã¥È¤Î¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤À¤±¤ò¥í¥°¤Ëµ­Ï¿¤¹¤ë¡¢ + ¤È¤¤¤¦ÁªÂò¤¬²Äǽ¤Ç¤¹¡£

    + + +

    ¾ò·ïÉÕ¤­±þÅú¥Ø¥Ã¥À

    + + +

    Header + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï´Ä¶­ÊÑ¿ô¤Î¸ºß¤äÉԺߤˤè¤Ã¤Æ¥¯¥é¥¤¥¢¥ó¥È¤Ø¤Î±þÅú¤ËÆÃÄê¤Î + HTTP ¥Ø¥Ã¥À¤òÉÕ¤±¤ë¤«¤É¤¦¤«¤ò·è¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È + ¤Ë¤¢¤ë¥Ø¥Ã¥À¤¬¤¢¤ë¾ì¹ç¤Ë¤Î¤ßÆÃÄê¤Î±þÅú¥Ø¥Ã¥À¤òÁ÷¤ë¡¢¤È¤¤¤¦¤è¤¦¤Ê¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + + + +

    ³°Éô¥Õ¥£¥ë¥¿¤ÎŬÍÑ

    + + +

    ExtFilterDefine + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ + mod_ext_filter ¤ÇÀßÄꤵ¤ì¤ë³°Éô¥Õ¥£¥ë¥¿¤Ï¡¢ + disableenv= ¤È enableenv= + ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¡¢´Ä¶­ÊÑ¿ô¤Ë¤è¤ë¾ò·ïÉÕ¤­Å¬ÍѤ¬¤Ç¤­¤Þ¤¹¡£

    + + +

    URL ¤Î½ñ¤­´¹¤¨

    + + +

    RewriteCond + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Çɾ²Áʸ»úÎó¤È¤·¤Æ + %{ENV:...} ¼°¤ò»ØÄꤹ¤ë¤³¤È¤Ç¡¢mod_rewrite + ¤Î½ñ¤­´¹¤¨¥¨¥ó¥¸¥ó¤¬´Ä¶­ÊÑ¿ô¤Ë´ð¤¤¤Æ¾ò·ïʬ´ô¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + mod_rewrite ¤¬»ÈÍѲÄǽ¤ÊÊÑ¿ô¤Ç ENV: ¤¬Á°¤Ë¤Ä¤¤¤Æ¤¤¤Ê¤¤ÊÑ¿ô¤Ï¡¢ + ¼ÂºÝ¤Ï´Ä¶­ÊÑ¿ô¤Ç¤Ï¤Ê¤¤¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤ì¤é¤Ï¾¤Î¥â¥¸¥å¡¼¥ë¤«¤é¤Ï»ÈÍѤǤ­¤Ê¤¤ mod_rewrite ÍѤÎÆÃÊ̤ÊÊÑ¿ô¤Ç¤¹¡£ +

    + +
    top
    +
    +

    ÆÃÊ̤ÊÌÜŪ¤Î´Ä¶­ÊÑ¿ô

    + + +

    ¸ß´¹À­¤ÎÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¡¢ÆÃÄê¤Î¥¯¥é¥¤¥¢¥ó¥È¤ÈÄÌ¿®¤·¤Æ¤¤¤ë¤È¤­¤Ï + Apache ¤ÎÆ°ºî¤òÊѹ¹¤Ç¤­¤ëµ¡¹½¤¬Æ³Æþ¤µ¤ì¤Þ¤·¤¿¡£¤Ç¤­¤ë¤À¤±½ÀÆð¤Ë¤¹¤ë¤¿¤á¤Ë¡¢ + ¤³¤ì¤é¤Îµ¡¹½¤Ï´Ä¶­ÊÑ¿ô¤òÄêµÁ¤¹¤ë¤³¤È¤Ç¸Æ¤Ó½Ð¤µ¤ì¤Þ¤¹¡£ÉáÄ̤ϡ¢ + BrowserMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¤¬¡¢¤¿¤È¤¨¤Ð SetEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä PassEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤â»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    downgrade-1.0

    + + +

    ¤³¤ì¤ò»ØÄꤹ¤ë¤³¤È¤Ç¡¢¥ê¥¯¥¨¥¹¥È¤¬ HTTP/1.0 + ¤è¤ê¿·¤·¤¤¥×¥í¥È¥³¥ë¤Î¾ì¹ç¤Ç¤â¡¢HTTP/1.0 ¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + + +

    force-gzip

    + +

    DEFLATE ¥Õ¥£¥ë¥¿¤¬»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ë¡¢ + ¤³¤Î´Ä¶­ÊÑ¿ô¤Ï¥Ö¥é¥¦¥¶¤Î accept-encoding ¤ÎÀßÄê¤ò̵»ë¤·¤Æ¾ï¤Ë + °µ½Ì¤µ¤ì¤¿½ÐÎϤòÁ÷¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    force-no-vary

    + + +

    ±þÅú¥Ø¥Ã¥À¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ëÁ°¤Ë Vary + ¥Õ¥£¡¼¥ë¥É¤ò¼è¤ê½ü¤­¤Þ¤¹¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤ÎÃæ¤Ë¤Ï¤³¤Î¥Õ¥£¡¼¥ë¥É¤òÀµ¤·¤¯²ò¼á¤·¤Ê¤¤¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ÎÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤Ç¤½¤ÎÌäÂê¤ò²óÈò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ÎÊÑ¿ô¤òÀßÄꤹ¤ë¤È¡¢force-response-1.0 + ¤¬ÀßÄꤵ¤ì¤¿¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + + +

    force-response-1.0

    + + +

    ¤³¤ì¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢HTTP/1.0 ¥ê¥¯¥¨¥¹¥È¤òȯ¹Ô¤¹¤ë¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¤Ï + ¾ï¤Ë HTTP/1.0 ¤Ç±þÅú¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤Îµ¡Ç½¤Ï¡¢ + ¸µ¡¹¤Ï AOL ¤Î¥×¥í¥­¥·¤ÎÌäÂê¤Î¤¿¤á¤Ë¼ÂÁõ¤µ¤ì¤Þ¤·¤¿¡£HTTP/1.0 ¥¯¥é¥¤¥¢¥ó¥È¤ÎÃæ¤Ë¤Ï¡¢ + HTTP/1.1 ¤Î±þÅú¤òÊÖ¤µ¤ì¤ë¤ÈÀµ¤·¤¯Æ°ºî¤·¤Ê¤¤¤â¤Î¤¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤³¤Îµ¡Ç½¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢¤½¤Î¤è¤¦¤Ê¥¯¥é¥¤¥¢¥ó¥È¤È¤Î´Ö¤Î¸ß´¹À­ÌäÂê¤ò²ò·è¤Ç¤­¤Þ¤¹¡£

    + + +

    gzip-only-text/html

    + + +

    ¤³¤ì¤¬ 1 ¤ËÀßÄꤵ¤ì¤ë¤È¡¢¤³¤ÎÊÑ¿ô¤Ï text/html + °Ê³°¤Î¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ËÂФ¹¤ë¡¢mod_deflate + Ä󶡤ΠDEFLATE ½ÐÎÏ¥Õ¥£¥ë¥¿¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£ + ¤Þ¤¿¡¢ÀÅŪ¤Ë¡¢´û¤Ë°µ½Ì¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤¿¤¤¾ì¹ç¡¢ + (gzip ¤À¤±¤Ç¤Ê¤¯¡¢"identity" ¤È°Û¤Ê¤ëÁ´¤Æ¤Î¥¨¥ó¥³¡¼¥É¤ËÂФ·¤Æ) + mod_negotiation ¤âÊÑ¿ô¤òɾ²Á¤·¤Þ¤¹¡£

    + + +

    no-gzip

    +

    ¥»¥Ã¥È¤µ¤ì¤ë¤È¡¢mod_deflate ¤Î + DEFLATE ¥Õ¥£¥ë¥¿¤¬¥ª¥Õ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤½¤·¤Æ mod_negotiation + ¤Ï¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿¥ê¥½¡¼¥¹¤òÁ÷¤é¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + + +

    nokeepalive

    + + +

    ¤³¤ì¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢KeepAlive ¤ò»ÈÍѤ·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    prefer-language

    + +

    mod_negotiation ¤ÎµóÆ°¤Ë±Æ¶Á¤òÍ¿¤¨¤Þ¤¹¡£ + (en, ja, x-klingon¤È¤¤¤Ã¤¿) + ¸À¸ì¥¿¥°¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤Î¸À¸ì¤Î variant ¤òÁ÷¿®¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê variant ¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢ + Ä̾ï¤Î¥Í¥´¥·¥¨¡¼¥·¥ç¥ó½èÍý¤¬ + ŬÍѤµ¤ì¤Þ¤¹¡£

    + + + + +

    redirect-carefully

    + + +

    ¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤ÎÁ÷¿®¤ò¥µ¡¼¥Ð¤¬¤è¤êÃí°Õ¿¼¤¯ + ¹Ô¤Ê¤¦¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¤³¤ì¤ÏÄ̾¥ê¥À¥¤¥ì¥¯¥È¤ËºÝ¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤Ë + ÌäÂ꤬¤¢¤ë¤³¤È¤¬Ê¬¤«¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë»È¤ï¤ì¤Þ¤¹¡£¤³¤Îµ¡Ç½¤Ï¸µ¡¹¤Ï + ¥Þ¥¤¥¯¥í¥½¥Õ¥È¤Î¥¦¥§¥Ö¥Õ¥©¥ë¥À¤Î¥½¥Õ¥È¤¬ DAV + ¥á¥½¥Ã¥É¤Ë¤è¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥½¡¼¥¹¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤Î°·¤¤¤Ë + ÌäÂ꤬¤ê¡¢¤½¤ì¤ò²óÈò¤¹¤ë¤¿¤á¤Ë¼ÂÁõ¤µ¤ì¤Þ¤·¤¿¡£

    + + + +

    suppress-error-charset

    + + +

    Apache 2.2 °Ê¹ß¤ÇÍøÍѲÄǽ

    + +

    ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë±þÅú¤È¤·¤Æ¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¿®¤¹¤ëºÝ¡¢ + ¥ì¥¹¥Ý¥ó¥¹¤Ë¤Ï¥ê¥À¥¤¥ì¥¯¥È¤¬¼«Æ°Åª¤Ë¹Ô¤Ê¤¨¤Ê¤¤ (¹Ô¤Ê¤ï¤ì¤Ê¤¤) + ¾ì¹ç¤Ëɽ¼¨¤¹¤ë¥Æ¥­¥¹¥È¤¬´Þ¤Þ¤ì¤Þ¤¹¡£ + Ä̾¤³¤Î¥Æ¥­¥¹¥È¤Ë¹çÃפ·¤¿¥­¥ã¥é¥¯¥¿¥»¥Ã¥È¡¢ISO-8859-1 + ¤Ç¥é¥Ù¥ëÉÕ¤±¤ò¤·¤Þ¤¹¡£

    +

    ¤·¤«¤·¡¢¥ê¥À¥¤¥ì¥¯¥ÈÀ褬Ê̤Îʸ»ú¥»¥Ã¥È¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢ + ¤¢¤ëÌäÂê¤Î¤¢¤ë¥Ö¥é¥¦¥¶¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢ + ¥ê¥À¥¤¥ì¥¯¥ÈÀè¤Î¼ÂºÝ¤Îʸ»ú¥»¥Ã¥È¤ÎÂå¤ï¤ê¤Ë¡¢ + ¥ê¥À¥¤¥ì¥¯¥È¸µ¤Îʸ»ú¥»¥Ã¥È¤ò»È¤Ã¤Æ¤·¤Þ¤¦¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤Î·ë²Ì¡¢Î㤨¤ÐÊѤÊÉÁ²è¤¬¹Ô¤Ê¤ï¤ì¤¿¤ê¤·¤Æ¡¢Æɤá¤Ê¤¯¤Ê¤Ã¤¿¤ê¤·¤Þ¤¹¡£

    +

    ¤³¤Î´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤Ç¡¢¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó¥Æ¥­¥¹¥È¤ËÂФ¹¤ë + ¥­¥ã¥é¥¯¥¿¥»¥Ã¥È¤Î»ØÄê¤ò½üµî¤·¤Þ¤¹¤Î¤Ç¡¢¤½¤ì¤éÌäÂê¤Î¤¢¤ë¥Ö¥é¥¦¥¶¤Ç¤â + ¥ê¥À¥¤¥ì¥¯¥ÈÀè¤Îʸ»ú¥»¥Ã¥È¤òÀµ¤·¤¯»È¤¦¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + + + +
    top
    +
    +

    Îã

    + + +

    ¤ª¤«¤·¤ÊµóÆ°¤ò¤¹¤ë¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¥×¥í¥È¥³¥ë¤ÎÆ°ºî¤òÊѹ¹¤¹¤ë

    + + +

    ¥¯¥é¥¤¥¢¥ó¥È¤Ë´Ø¤¹¤ë´ûÃΤÎÌäÂê¤ËÂн褹¤ë¤¿¤á¤Ë¡¢°Ê²¼¤Î¹Ô¤ò + httpd.conf ¤ËÆþ¤ì¤ë¤³¤È¤ò¿ä¾©¤·¤Æ¤¤¤Þ¤¹¡£

    +
    +#
    +# The following directives modify normal HTTP response behavior.
    +# The first directive disables keepalive for Netscape 2.x and browsers that
    +# spoof it. There are known problems with these browser implementations.
    +# The second directive is for Microsoft Internet Explorer 4.0b2
    +# which has a broken HTTP/1.1 implementation and does not properly
    +# support keepalive when it is used on 301 or 302 (redirect) responses.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# The following directive disables HTTP/1.1 responses to browsers which
    +# are in violation of the HTTP/1.0 spec by not being able to grok a
    +# basic 1.1 response.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + + +

    ²èÁü¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¥¢¥¯¥»¥¹¥í¥°¤Ëµ­Ï¿¤·¤Ê¤¤

    + + +

    ¤³¤ÎÎã¤Ç¤Ï¡¢²èÁü¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤¬¥¢¥¯¥»¥¹¥í¥°¤Ë¸½¤ì¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¤³¤ì¤òÊѹ¹¤¹¤ë¤³¤È¤Ç¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¥í¥°¼ý½¸¤ò¤ä¤á¤¿¤ê¡¢ + ÆÃÄê¤Î¥Û¥¹¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤Î¥í¥°¼ý½¸¤ò¤ä¤á¤¿¤ê¤¹¤ë¤³¤È¤¬´Êñ¤Ë¤Ç¤­¤Þ¤¹¡£ +

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + + +

    ¡Ö²èÁü¤ÎÅðÍѡפòËɤ°

    + + +

    ¤³¤ÎÎã¤Ï¡¢Ê̤Υµ¡¼¥Ð¤Ë¤¤¤ë¿Í¤¬¡¢¤¢¤Ê¤¿¤Î¥µ¡¼¥Ð¤Ë¤¢¤ë²èÁü¤ò + inline ²èÁü¤È¤·¤Æ»ÈÍѤ¹¤ë¤³¤È¤òËɤ®¤Þ¤¹¡£ + ¤³¤ì¤Ï¿ä¾©¤µ¤ì¤Æ¤¤¤ëÀßÄê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¤¢¤ë¸ÂÄꤵ¤ì¤¿¾õ¶·¤Ç¤ÏÍ­¸ú¤Ç¤¹¡£ + ¤³¤³¤Ç¤Ï¡¢¤¹¤Ù¤Æ¤Î²èÁü¤Ï /web/images + ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë¤È²¾Äꤷ¤Þ¤¹¡£

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Allow browsers that do not send Referer info
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    ¤³¤Î¼êË¡¤Ë´Ø¤¹¤ë¾Ü¤·¤¤¾ðÊó¤Ï ApacheToday ¤Î¥Á¥å¡¼¥È¥ê¥¢¥ë¡ÖKeeping Your Images from Adorning Other Sites + ¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/env.html.ko.euc-kr b/trunk/docs/manual/env.html.ko.euc-kr new file mode 100644 index 0000000000..5e53caff7c --- /dev/null +++ b/trunk/docs/manual/env.html.ko.euc-kr @@ -0,0 +1,373 @@ + + + +¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ȯ°æº¯¼ö(environment variable)¶ó´Â + º¯¼ö¿¡ Á¤º¸¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Ù. ÀÌ Á¤º¸¸¦ »ç¿ëÇÏ¿© ·Î±×³ª + Á¢±ÙÁ¦¾î µî ¿©·¯ ÀÛ¾÷À» Á¶ÀýÇÑ´Ù. ¶Ç, ȯ°æº¯¼ö´Â CGI ½ºÅ©¸³Æ®¿Í + °°Àº ¿ÜºÎ ÇÁ·Î±×·¥°ú Åë½ÅÇÏ´Â ¼ö´ÜÀÌ µÈ´Ù. ÀÌ ¹®¼­´Â ȯ°æº¯¼ö¸¦ + ´Ù·ç°í »ç¿ëÇÏ´Â ´Ù¾çÇÑ ¹æ¹ýµéÀ» ¼³¸íÇÑ´Ù.

    + +

    ÀÌ º¯¼öµéÀ» ȯ°æº¯¼ö¶ó°í ºÎ¸£Áö¸¸, ¿î¿µÃ¼Á¦¿¡¼­ + ¸»Çϴ ȯ°æº¯¼ö¿Í ´Ù¸£´Ù. ÀÌ º¯¼ö´Â ¾ÆÆÄÄ¡ ³»ºÎ¿¡ ÀúÀåµÇ°í + »ç¿ëµÈ´Ù. ȯ°æº¯¼ö´Â CGI ½ºÅ©¸³Æ®³ª Server Side Include + ½ºÅ©¸³Æ®·Î ³Ñ°ÜÁú¶§¸¸ ½ÇÁ¦ ¿î¿µÃ¼Á¦ ȯ°æº¯¼ö°¡ µÈ´Ù. ¼­¹ö¸¦ + ½ÇÇàÇÏ´Â ¿î¿µÃ¼Á¦ ȯ°æÀ» ¼öÁ¤ÇÏ°í ½Í´Ù¸é ¿î¿µÃ¼Á¦ ½©¿¡¼­ + ȯ°æÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    +
    + +
    top
    +
    +

    ȯ°æº¯¼ö ¼³Á¤Çϱâ

    + + + +

    ±âº»ÀûÀΠȯ°æ¼³Á¤

    + + +

    ¾ÆÆÄÄ¡¿¡¼­ ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ´Â °¡Àå ±âº»ÀûÀÎ ¹æ¹ýÀº + ¹«Á¶°ÇÀûÀÎ SetEnv Áö½Ã¾î¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. PassEnv Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼­¹ö¸¦ ½ÃÀÛÇÑ ½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Ã ¼öµµ ÀÖ´Ù.

    + + +

    ¿äû¿¡ µû¸¥ Á¶°ÇºÎ ¼³Á¤

    + + +

    ´õ À¯¿¬ÇÏ°Ô, mod_setenvif°¡ Á¦°øÇÏ´Â Áö½Ã¾î´Â ¿äû¸¶´Ù + ¿äûÀÇ Æ¯Â¡¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¾î, ƯÁ¤ + ºê¶ó¿ìÀú·Î (User-Agent) ¿äûÇϰųª ƯÁ¤ Referer (¸ÂÃã¹ýÀÌ + Ʋ¸®Áö ¾Ê¾Ò´Ù) Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ º¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö + ÀÖ´Ù. ½ÉÁö¾î mod_rewrite¿¡ ÀÖ´Â RewriteRuleÀÇ + [E=...] ¿É¼ÇÀ» »ç¿ëÇÏ¿© ´õ À¯¿¬ÇÏ°Ô È¯°æº¯¼ö¸¦ + ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù.

    + + +

    À¯ÀÏÇÑ ½Äº°ÀÚ

    + + +

    ¸¶Áö¸·À¸·Î mod_unique_id´Â °¢ ¿äû¿¡ ´ëÇØ ¾î¶² °æ¿ì¿¡µµ + "¸ðµç" ¿äûÁß¿¡ È®½ÇÈ÷ À¯ÀÏÇÑ(°ãÄ¡Áö¾ÊÀº) °ªÀ¸·Î + UNIQUE_ID ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + + +

    Ç¥ÁØ CGI º¯¼ö

    + + +

    CGI ½ºÅ©¸³Æ®¿Í SSI ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ ¼³Á¤ÇÏ¿´°Å³ª + ½©¿¡¼­ °¡Á®¿Â ȯ°æº¯¼ö ¿Ü¿¡ Ãß°¡·Î CGI ±Ô¾àÀÌ ±ÔÁ¤ÇÑ + ¿äû¿¡ ´ëÇÑ Á¤º¸¸¦ ¾Ë·ÁÁִ ȯ°æº¯¼öµéÀ» ¹Þ´Â´Ù.

    + + +

    ÁÖÀÇÇÒ Á¡

    + + +
      +
    • ȯ°æ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Ç¥ÁØ CGI º¯¼ö¸¦ ¹«½ÃÇϰųª + ¼öÁ¤ÇÒ ¼ö ¾ø´Ù.
    • + +
    • suexec°¡ CGI ½ºÅ©¸³Æ®¸¦ + ½ÇÇàÇÏ´Â °æ¿ì, ½ÃÀÛÇϱâÀü¿¡ CGI ½ºÅ©¸³Æ®ÀÇ È¯°æÀº + ¾ÈÀüÇÑ º¯¼öµé¸¸ °¡Áöµµ·Ï û¼ÒµÈ´Ù. + ¾ÈÀüÇÑ º¯¼ö ¸ñ·ÏÀº ÄÄÆÄÀϽà + suexec.c¿¡ Á¤ÀǵȴÙ.
    • + +
    • Æ÷ÆÃÀ» À§ÇØ È¯°æº¯¼ö À̸§¿¡´Â ¿ÀÁ÷ ¹®ÀÚ, ¼ýÀÚ, + ¹ØÁÙ¹®ÀÚ¸¸ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. ¶Ç, ù¹ø° ¹®ÀÚ·Î + ¼ýÀÚ¸¦ »ç¿ëÇÏÁö¾Ê´Â °ÍÀÌ ÁÁ´Ù. CGI ½ºÅ©¸³Æ®³ª SSI + ÆäÀÌÁö¿¡ ³Ñ¾î°¥¶§ ÀÌ¿ÜÀÇ ¹®ÀÚ´Â ¹ØÁÙ·Î ´ëüµÈ´Ù.
    • +
    + +
    top
    +
    +

    ȯ°æº¯¼ö »ç¿ëÇϱâ

    + + + + +

    CGI ½ºÅ©¸³Æ®

    + + +

    ȯ°æº¯¼öÀÇ ÁÖµÈ ¿ëµµÁß Çϳª´Â CGI ½ºÅ©¸³Æ®¿Í Á¤º¸¸¦ + ±³È¯ÇÏ´Â °ÍÀÌ´Ù. ¾Õ¿¡¼­ ¼³¸íÇßµíÀÌ ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ ¼³Á¤ÇÑ + º¯¼ö¿Ü¿¡ ¿äû¿¡ ´ëÇÑ Ç¥ÁØ Á¤º¸¸¦ °¡Áø º¯¼ö°¡ CGI ½ºÅ©¸³Æ®·Î + ³Ñ¾î°£´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº CGI + ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + + +

    SSI ÆäÀÌÁö

    + + +

    mod_includeÀÇ INCLUDES ÇÊÅÍ°¡ ó¸®ÇÏ´Â + ¼­¹öÆÄ½Ì (SSI) ¹®¼­´Â echo ¿ä¼Ò¸¦ »ç¿ëÇÏ¿© + ȯ°æº¯¼ö¸¦ Ãâ·ÂÇÒ ¼ö ÀÖ°í, ȯ°æº¯¼ö¸¦ »ç¿ëÇÏ¿© ¿äûÀÇ + Ư¡¿¡ µû¶ó È帧Á¦¾î ¿ä¼Ò·Î ÆäÀÌÁöÀÇ ÀϺθ¦ º¯°æÇÒ ¼ö + ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¶Ç SSI ¹®¼­¿¡°Ô À§¿¡¼­ ¼³¸íÇÑ Ç¥ÁØ CGI + ȯ°æº¯¼ö¸¦ Á¦°øÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº SSI ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + + +

    Á¢±ÙÁ¦¾î

    + + +

    allow from env=°ú deny from env= + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ȯ°æº¯¼ö °ª¿¡ µû¶ó ¼­¹ö·ÎÀÇ Á¢±ÙÀ» + Á¶ÀýÇÒ ¼ö ÀÖ´Ù. SetEnvIf¿Í °°ÀÌ »ç¿ëÇϸé + Ŭ¶óÀ̾ðÆ®ÀÇ Æ¯Â¡¿¡ µû¶ó ÀÚÀ¯·Ó°Ô ¼­¹ö·ÎÀÇ Á¢±ÙÀ» Á¦¾îÇÒ + ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ƯÁ¤ ºê¶ó¿ìÀúÀÇ (User-Agent) Á¢±ÙÀ» + °ÅºÎÇÒ ¼ö ÀÖ´Ù.

    + + +

    Á¶°ÇºÎ ·Î±×

    + + +

    LogFormatÀÇ + %e ¿É¼ÇÀ» »ç¿ëÇÏ¿© ȯ°æº¯¼ö¸¦ Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÒ ¼ö ÀÖ´Ù. ¶Ç, CustomLog Áö½Ã¾îÀÇ + Á¶°ÇºÎ Çü½ÄÀ» »ç¿ëÇϸé ȯ°æº¯¼öÀÇ »óȲ¿¡ µû¶ó ¿äûÀ» + ·Î±×ÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÒ ¼ö ÀÖ´Ù. SetEnvIf¿Í °°ÀÌ »ç¿ëÇÏ¿© + ¾î¶² ¿äûÀ» ·Î±×ÇÒÁö ÀÚÀ¯·Ó°Ô °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + ÆÄÀϸíÀÌ gif·Î ³¡³ª´Â ¿äûÀº ·Î±×ÇÏÁö ¾Ê°Å³ª, + ¿ÜºÎ ³×Æ®¿÷¿¡ Àִ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¸¸À» ·Î±×ÇÒ ¼ö ÀÖ´Ù.

    + + +

    Á¶°ÇºÎ ÀÀ´ä Çì´õ

    + + +

    Header + Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÀ´äÀ» º¸³¾¶§ ȯ°æº¯¼öÀÇ À¯¹«¿¡ + µû¶ó ¾î¶² HTTP Çì´õ¸¦ Æ÷ÇÔÇÒÁö °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ƯÁ¤ Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ + ¾î¶² ÀÀ´ä Çì´õ¸¦ º¸³¾ ¼ö ÀÖ´Ù.

    + + + +

    ¿ÜºÎ ÇÊÅÍ ½ÇÇàÇϱâ

    + + +

    mod_ext_filterÀÇ ExtFilterDefine + Áö½Ã¾î·Î ¼³Á¤ÇÑ ¿ÜºÎ ÇÊÅ͸¦ disableenv=¿Í + enableenv= ¿É¼ÇÀ» »ç¿ëÇÏ¿© ȯ°æº¯¼ö¿¡ µû¶ó + ¼±ÅÃÀûÀ¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + + +

    URL ÀçÀÛ¼º(Rewriting)

    + + +

    RewriteCondÀÇ + TestString¿¡ %{ENV:...} Çü½ÄÀ» + »ç¿ëÇϸé mod_rewriteÀÇ ÀçÀÛ¼º ¿£ÁøÀÌ È¯°æº¯¼ö¿¡ µû¶ó + ´Ù¸£°Ô ÇൿÇÑ´Ù. mod_rewrite¿¡¼­ ¾Õ¿¡ ENV:¸¦ + ºÙÀÌÁö¾Ê°í Á¢±ÙÇÏ´Â º¯¼ö´Â ½ÇÁ¦ ȯ°æº¯¼ö°¡ ¾Æ´ÔÀ» ÁÖÀÇÇ϶ó. + ±×µéÀº ´Ù¸¥ ¸ðµâ¿¡¼­ ÀÐÀ» ¼ö ¾ø´Â mod_rewrite¿¡ ÇÑÁ¤µÈ + º¯¼ö´Ù.

    + +
    top
    +
    +

    Ưº°ÇÑ ¸ñÀûÀÇ È¯°æº¯¼ö

    + + +

    Ŭ¶óÀ̾ðÆ®¿Í ¿øÈ°ÇÑ µ¿ÀÛÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â Ưº°ÇÑ + Ŭ¶óÀ̾ðÆ®¿¡ ´ëÇØ ÀÚ½ÅÀÇ ÇൿÀ» ¼öÁ¤ÇÑ´Ù. º¸Åë BrowserMatch¿¡¼­ + ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÏ¿© ÀÌ·± ¹®Á¦¸¦ ÇØ°áÇÑ´Ù. ±×·¯³ª SetEnv¿Í PassEnv·Îµµ °¡´ÉÇÏ´Ù.

    + +

    downgrade-1.0

    + + +

    ¿äûÀÌ ÀÌÈÄ ¹öÀüÀ» »ç¿ëÇÏ´õ¶óµµ HTTP/1.0 ¿äûÀ¸·Î + ó¸®ÇÑ´Ù.

    + + +

    force-gzip

    + +

    DEFLATE ÇÊÅ͸¦ »ç¿ëÇÒ¶§ ÀÌ È¯°æº¯¼ö´Â + ºê¶ó¿ìÀúÀÇ accept-encoding ¼³Á¤À» ¹«½ÃÇÏ°í ¹«Á¶°Ç + ¾ÐÃàµÈ °á°ú¸¦ º¸³½´Ù.

    + +

    force-no-vary

    + + +

    ÀÀ´äÀ» Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»±â Àü¿¡ ÀÀ´ä Çì´õ¿¡¼­ + Vary Çʵ带 »«´Ù. ¾î¶² Ŭ¶óÀ̾ðÆ®´Â ÀÌ + Çʵ带 Á¦´ë·Î Çؼ®ÇÏÁö ¸øÇÑ´Ù. ÀÌ º¯¼ö´Â ÀÌ·± ¹®Á¦¸¦ + ÇØ°áÇÑ´Ù. ¶ÇÇÑ, ÀÌ º¯¼ö´Â + force-response-1.0À» °¡Á¤ÇÑ´Ù.

    + + +

    force-response-1.0

    + + +

    HTTP/1.0 ¿äûÀ» Çϴ Ŭ¶óÀ̾ðÆ®¿¡°Ô HTTP/1.0 ÀÀ´äÀ» + °­Á¦ÇÑ´Ù. ¿ø·¡ AOL ÇÁ·Ï½Ã¿¡ ¹®Á¦°¡ À־ ¸¸µé¾îÁ³´Ù. + ¾î¶² HTTP/1.0 Ŭ¶óÀ̾ðÆ®´Â HTTP/1.1 ÀÀ´äÀ» ¹ÞÀ¸¸é Á¦´ë·Î + µ¿ÀÛÇÏÁö ¾ÊÀ¸¹Ç·Î, ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâÀ§ÇØ »ç¿ëÇÑ´Ù.

    + + +

    gzip-only-text/html

    + + +

    °ªÀÌ "1"À̸é text/htmlÀÌ ¾Æ´Ñ content-type¿¡ + ´ëÇØ mod_deflateÀÇ DEFLATE Ãâ·ÂÇÊÅ͸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù. (gzip »Ó¸¸ ¾Æ´Ï¶ó "identity"°¡ ¾Æ´Ñ ¸ðµç + ÀÎÄÚµùÀÇ) Á¤ÀûÀ¸·Î ¾ÐÃàÇÑ ÆÄÀÏÀÇ °æ¿ì¿¡µµ + mod_negotiationÀº ÀÌ º¯¼ö¸¦ Âü°íÇÑ´Ù.

    + + +

    no-gzip

    + +

    ÀÌ ¿É¼ÇÀ» ¼³Á¤Çϸé mod_deflateÀÇ + DEFLATE ÇÊÅ͸¦ »ç¿ëÇÏÁö ¾Ê°í, + mod_negotiationÀº ÀÎÄÚµùµÈ ÀÚ¿øÀ» + º¸³»Áö ¾Ê´Â´Ù.

    + + + +

    nokeepalive

    + + +

    KeepAlive¸¦ + ¹«½ÃÇÑ´Ù.

    + + + +

    prefer-language

    + +

    ÀÌ º¯¼ö´Â mod_negotiationÀÇ Çൿ¿¡ + ¿µÇâÀ» ¹ÌÄ£´Ù. º¯¼ö°¡ (en, ja, + x-klingon µî) ¾ð¾îű׸¦ ´ã°íÀÖ´Ù¸é, + mod_negotiation´Â ±× ¾ð¾î·Î µÈ º¯ÇüÀ» + º¸³»±æ ½ÃµµÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ Çù»ó °úÁ¤À» ½ÃÀÛÇÑ´Ù.

    + + + +

    redirect-carefully

    + + +

    ¼­¹ö°¡ ´õ Á¶½ÉÈ÷ Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. + º¸Åë ¸®´ÙÀÌ·º¼ÇÀ» ó¸®Çϴµ¥ ¹®Á¦°¡ Àִ Ŭ¶óÀ̾ðÆ®À» + À§ÇØ »ç¿ëÇÑ´Ù. ¿ø·¡ MicrosoftÀÇ WebFolders ¼ÒÇÁÆ®¿þ¾î°¡ + DAV ¸Þ½áµå¸¦ ÅëÇØ µð·ºÅ丮 ÀÚ¿øÀÇ ¸®´ÙÀÌ·º¼ÇÀ» ó¸®Çϴµ¥ + ¹®Á¦°¡ À־ ¸¸µé¾îÁ³´Ù.

    + + + +

    suppress-error-charset

    + + +

    2.0.40 ÀÌÈÄ ¹öÀü¿¡ ÀÖ´Ù

    + +

    ¾ÆÆÄÄ¡°¡ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ´ëÇÑ ÀÀ´äÀ¸·Î ¸®´ÙÀÌ·º¼ÇÀ» + º¸³¾¶§ Ŭ¶óÀ̾ðÆ®°¡ ÀÚµ¿À¸·Î ¸®´ÙÀÌ·º¼ÇÀ» µû¶ó°¡Áö ¸øÇÏ´Â(ȤÀº + ¾Ê´Â) °æ¿ì¿¡ ´ëºñÇÏ¿© ÀÀ´ä¿¡ »ç¿ëÀÚ¿¡°Ô º¸¿©ÁÙ ¹®±¸¸¦ Æ÷ÇÔÇÑ´Ù. + ¾ÆÆÄÄ¡´Â º¸Åë ÀÌ ±ÛÀ» ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ¹®ÀÚÁýÇÕÀÎ ISO-8859-1·Î + Ç¥½ÃÇÑ´Ù.

    +

    ±×·¯³ª ¸®´ÙÀÌ·º¼ÇµÈ ÆäÀÌÁö°¡ ´Ù¸¥ ¹®ÀÚÁýÇÕÀ» »ç¿ëÇÒ °æ¿ì + ¾î¶² ÀÌ»óÇÑ ºê¶ó¿ìÀú ¹öÀüÀº ½ÇÁ¦ ÆäÀÌÁö°¡ ¾Æ´Ï¶ó ¸®´ÙÀÌ·º¼Ç + ÆäÀÌÁöÀÇ ¹®ÀÚÁýÇÕÀ» »ç¿ëÇÏ·Á°í ÇÑ´Ù. ¿¹¸¦ µé¾î, ±×¸®½º¾î°¡ + ÀÌ»óÇÏ°Ô º¸ÀÏ ¼ö ÀÖ´Ù.

    +

    ÀÌ È¯°æº¯¼ö´Â ¾ÆÆÄÄ¡°¡ ¸®´ÙÀÌ·º¼Ç ÆäÀÌÁö¿¡ ¹®ÀÚÁýÇÕÀ» + ¼³Á¤ÇÏÁö¾Êµµ·Ï ÇÏ¿©, ÀÌ·± ºê¶ó¿ìÀú°¡ ½ÇÁ¦ ÆäÀÌÁöÀÇ ¹®ÀÚÁýÇÕÀ» + ¿Ã¹Ù·Î »ç¿ëÇÏ°Ô ¸¸µç´Ù.

    + + + +
    top
    +
    +

    ¿¹Á¦

    + + +

    À߸ø µ¿ÀÛÇϴ Ŭ¶óÀ̾ðÆ®µéÀ» À§ÇØ ÇÁ·ÎÅäÄÝ Çൿ + º¯°æÇϱâ

    + + +

    Ŭ¶óÀ̾ðÆ®µéÀÇ ÀÌ¹Ì ¾Ë·ÁÁø ¹®Á¦¸¦ ÇØ°áÇϱâÀ§ÇØ + httpd.conf¿¡ ´ÙÀ½ ³»¿ëÀ» Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù.

    +
    +#
    +# ´ÙÀ½ Áö½Ã¾îµéÀº ÀϹÝÀûÀÎ HTTP ÀÀ´äÀ» º¯°æÇÑ´Ù.
    +# ù¹ø° Áö½Ã¾î´Â Netscape 2.x¿Í À̸¦ °¡ÀåÇÑ ºê¶ó¿ìÀú¿¡°Ô
    +# keepalive¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌµé ºê¶ó¿ìÀú ±¸Çö¿¡ ¹®Á¦°¡ ÀÖ´Ù.
    +# µÎ¹ø° Áö½Ã¾î´Â HTTP/1.1 ±¸ÇöÀÌ À߸øµÇ¾ú°í 301À̳ª 302
    +# (¸®´ÙÀÌ·º¼Ç) ÀÀ´ä¿¡ »ç¿ëÇÑ keepalive¸¦ Á¦´ë·Î Áö¿øÇÏÁö
    +# ¸øÇÏ´Â Microsoft Internet Explorer 4.0b2¸¦ À§ÇÑ °ÍÀÌ´Ù.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# ´ÙÀ½ Áö½Ã¾î´Â ±âº»ÀûÀÎ HTTP/1.1 ÀÀ´äÀ» ÀÌÇØÇÏÁö ¸øÇÏ¿©
    +# HTTP/1.0 ±Ô¾àÀ» ¾î±â´Â ºê¶ó¿ìÀú¿¡°Ô HTTP/1.1 ÀÀ´äÀ» º¸³»Áö ¾Ê´Â´Ù.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + + +

    Á¢±Ù ·Î±×¿¡ À̹ÌÁö¿¡ ´ëÇÑ ¿äûÀ» ·Î±×ÇÏÁö ¾Ê±â

    + + +

    ÀÌ ¿¹Á¦´Â À̹ÌÁö¿¡ ´ëÇÑ ¿äûÀ» Á¢±Ù ·Î±×¿¡ ±â·ÏÇÏÁö + ¾Ê´Â´Ù. ƯÁ¤ µð·ºÅ丮¿¡ ´ëÇÑ È¤Àº ƯÁ¤ È£½ºÆ®¿¡¼­ ¿Â + ¿äûÀ» ·Î±×ÇÏÁö ¾Êµµ·Ï ½±°Ô ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + + +

    "À̹ÌÁö µµµÏ" ¹æÁö

    + + +

    ÀÌ ¿¹´Â ÇöÀç ¼­¹ö¿ÜÀÇ »ç¿ëÀÚ°¡ ÆäÀÌÁö¿¡ ¼­¹ö¿¡ ÀÖ´Â + À̹ÌÁö¸¦ Æ÷ÇÔÇÏÁö ¸øÇϵµ·Ï ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. ÀÌ + ¼³Á¤À» ±ÇÀåÇÏÁö´Â ¾ÊÀ¸¸ç, Á¦ÇÑµÈ °æ¿ì¿¡¸¸ µ¿ÀÛÇÑ´Ù. + ¿ì¸®´Â ¸ðµç À̹ÌÁö°¡ /web/images µð·ºÅ丮 ¾È¿¡ ÀÖ´Ù°í + °¡Á¤ÇÑ´Ù.

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Referer Á¤º¸¸¦ º¸³»Áö ¾Ê´Â ºê¶ó¿ìÀú¸¦ Çã¿ëÇÑ´Ù
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    ÀÌ ±â¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ApacheToday ÅõÅ丮¾ó " + Keeping Your Images from Adorning Other Sites"¸¦ Âü°íÇ϶ó.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/env.xml b/trunk/docs/manual/env.xml new file mode 100644 index 0000000000..048f5b1cd7 --- /dev/null +++ b/trunk/docs/manual/env.xml @@ -0,0 +1,439 @@ + + + + + + + + + + Environment Variables in Apache + + +

    The Apache HTTP Server provides a mechanism for storing + information in named variables that are called environment + variables. This information can be used to control various + operations such as logging or access control. The variables are + also used as a mechanism to communicate with external programs + such as CGI scripts. This document discusses different ways to + manipulate and use these variables.

    + +

    Although these variables are referred to as environment + variables, they are not the same as the environment + variables controlled by the underlying operating system. + Instead, these variables are stored and manipulated in an + internal Apache structure. They only become actual operating + system environment variables when they are provided to CGI + scripts and Server Side Include scripts. If you wish to + manipulate the operating system environment under which the + server itself runs, you must use the standard environment + manipulation mechanisms provided by your operating system + shell.

    +
    + +
    + Setting Environment Variables + + + mod_env + mod_rewrite + mod_setenvif + mod_unique_id + + + BrowserMatch + BrowserMatchNoCase + PassEnv + RewriteRule + SetEnv + SetEnvIf + SetEnvIfNoCase + UnsetEnv + + + +
    + Basic Environment Manipulation + +

    The most basic way to set an environment variable in Apache + is using the unconditional SetEnv directive. Variables may also be passed from + the environment of the shell which started the server using the + PassEnv directive.

    + +
    +
    + Conditional Per-Request Settings + +

    For additional flexibility, the directives provided by + mod_setenvif allow environment variables to be set on a + per-request basis, conditional on characteristics of particular + requests. For example, a variable could be set only when a + specific browser (User-Agent) is making a request, or only when + a specific Referer [sic] header is found. Even more flexibility + is available through the mod_rewrite's RewriteRule which uses the + [E=...] option to set environment variables.

    + +
    +
    + Unique Identifiers + +

    Finally, mod_unique_id sets the environment variable + UNIQUE_ID for each request to a value which is + guaranteed to be unique across "all" requests under very + specific conditions.

    + +
    +
    + Standard CGI Variables + +

    In addition to all environment variables set within the + Apache configuration and passed from the shell, CGI scripts and + SSI pages are provided with a set of environment variables + containing meta-information about the request as required by + the CGI + specification.

    + +
    +
    + Some Caveats + +
      +
    • It is not possible to override or change the standard CGI + variables using the environment manipulation directives.
    • + +
    • When suexec is used to launch + CGI scripts, the environment will be cleaned down to a set of + safe variables before CGI scripts are launched. The + list of safe variables is defined at compile-time in + suexec.c.
    • + +
    • For portability reasons, the names of environment + variables may contain only letters, numbers, and the + underscore character. In addition, the first character may + not be a number. Characters which do not match this + restriction will be replaced by an underscore when passed to + CGI scripts and SSI pages.
    • +
    +
    +
    +
    + Using Environment Variables + + + + mod_authz_host + mod_cgi + mod_ext_filter + mod_headers + mod_include + mod_log_config + mod_rewrite + + + Allow + CustomLog + Deny + ExtFilterDefine + Header + LogFormat + RewriteCond + RewriteRule + + + +
    + CGI Scripts + +

    One of the primary uses of environment variables is to + communicate information to CGI scripts. As discussed above, the + environment passed to CGI scripts includes standard + meta-information about the request in addition to any variables + set within the Apache configuration. For more details, see the + CGI tutorial.

    + +
    +
    + SSI Pages + +

    Server-parsed (SSI) documents processed by mod_include's + INCLUDES filter can print environment variables + using the echo element, and can use environment + variables in flow control elements to makes parts of a page + conditional on characteristics of a request. Apache also + provides SSI pages with the standard CGI environment variables + as discussed above. For more details, see the SSI tutorial.

    + +
    +
    + Access Control + +

    Access to the server can be controlled based on the value of + environment variables using the allow from env= + and deny from env= directives. In combination with + SetEnvIf, this + allows for flexible control of access to the server based on + characteristics of the client. For example, you can use these + directives to deny access to a particular browser (User-Agent). +

    + +
    +
    + Conditional Logging + +

    Environment variables can be logged in the access log using + the LogFormat + option %e. In addition, the decision on whether + or not to log requests can be made based on the status of + environment variables using the conditional form of the + CustomLog + directive. In combination with SetEnvIf this allows for flexible control of which + requests are logged. For example, you can choose not to log + requests for filenames ending in gif, or you can + choose to only log requests from clients which are outside your + subnet.

    + +
    +
    + Conditional Response Headers + +

    The Header + directive can use the presence or + absence of an environment variable to determine whether or not + a certain HTTP header will be placed in the response to the + client. This allows, for example, a certain response header to + be sent only if a corresponding header is received in the + request from the client.

    + +
    + +
    + External Filter Activation + +

    External filters configured by mod_ext_filter + using the ExtFilterDefine directive can + by activated conditional on an environment variable using the + disableenv= and enableenv= options.

    +
    + +
    + URL Rewriting + +

    The %{ENV:...} form of TestString in + the RewriteCond + allows mod_rewrite's rewrite + engine to make decisions conditional on environment variables. + Note that the variables accessible in mod_rewrite without the + ENV: prefix are not actually environment + variables. Rather, they are variables special to mod_rewrite + which cannot be accessed from other modules.

    +
    +
    + +
    + Special Purpose Environment Variables + +

    Interoperability problems have led to the introduction of + mechanisms to modify the way Apache behaves when talking to + particular clients. To make these mechanisms as flexible as + possible, they are invoked by defining environment variables, + typically with BrowserMatch, though SetEnv and PassEnv could also be used, for example.

    + +
    + downgrade-1.0 + +

    This forces the request to be treated as a HTTP/1.0 request + even if it was in a later dialect.

    + +
    +
    + force-gzip +

    If you have the DEFLATE filter activated, this + environment variable will ignore the accept-encoding setting of + your browser and will send compressed output unconditionally.

    +
    +
    + force-no-vary + +

    This causes any Vary fields to be removed from + the response header before it is sent back to the client. Some + clients don't interpret this field correctly; setting this + variable can work around this problem. Setting this variable + also implies force-response-1.0.

    + +
    +
    + force-response-1.0 + +

    This forces an HTTP/1.0 response to clients making an HTTP/1.0 + request. It was originally + implemented as a result of a problem with AOL's proxies. Some + HTTP/1.0 clients may not behave correctly when given an HTTP/1.1 + response, and this can be used to interoperate with them.

    + +
    + +
    + gzip-only-text/html + +

    When set to a value of "1", this variable disables the DEFLATE + output filter provided by mod_deflate for + content-types other than text/html. If you'd rather + use statically compressed files; mod_negotiation + evaluates the variable as well (not only for gzip, but for all + encodings that differ from "identity").

    +
    + +
    no-gzip + +

    When set, the DEFLATE filter of + mod_deflate will be turned off and + mod_negotiation will refuse to deliver encoded + resources.

    + +
    + +
    + nokeepalive + +

    This disables KeepAlive + when set.

    + +
    + +
    prefer-language + +

    This influences mod_negotiation's behaviour. If + it contains a language tag (such as en, ja + or x-klingon), mod_negotiation tries + to deliver a variant with that language. If there's no such variant, + the normal negotiation process + applies.

    + +
    + +
    + redirect-carefully + +

    This forces the server to be more careful when sending a redirect + to the client. This is typically used when a client has a known + problem handling redirects. This was originally implemented as a + result of a problem with Microsoft's WebFolders software which has + a problem handling redirects on directory resources via DAV + methods.

    + +
    + +
    + suppress-error-charset + +

    Available in versions 2.2 and later

    + +

    When Apache issues a redirect in response to a client request, + the response includes some actual text to be displayed in case + the client can't (or doesn't) automatically follow the redirection. + Apache ordinarily labels this text according to the character set + which it uses, which is ISO-8859-1.

    +

    However, if the redirection is to a page that uses a different + character set, some broken browser versions will try to use the + character set from the redirection text rather than the actual page. + This can result in Greek, for instance, being incorrectly rendered.

    +

    Setting this environment variable causes Apache to omit the character + set for the redirection text, and these broken browsers will then correctly + use that of the destination page.

    + +
    + +
    + +
    + Examples + +
    + Changing protocol behavior with misbehaving clients + +

    We recommend that the following lines be included in + httpd.conf to deal with known client problems.

    +
    +#
    +# The following directives modify normal HTTP response behavior.
    +# The first directive disables keepalive for Netscape 2.x and browsers that
    +# spoof it. There are known problems with these browser implementations.
    +# The second directive is for Microsoft Internet Explorer 4.0b2
    +# which has a broken HTTP/1.1 implementation and does not properly
    +# support keepalive when it is used on 301 or 302 (redirect) responses.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# The following directive disables HTTP/1.1 responses to browsers which
    +# are in violation of the HTTP/1.0 spec by not being able to grok a
    +# basic 1.1 response.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + +
    +
    + Do not log requests for images in the access log + +

    This example keeps requests for images from appearing in the + access log. It can be easily modified to prevent logging of + particular directories, or to prevent logging of requests + coming from particular hosts.

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + +
    +
    + Prevent "Image Theft" + +

    This example shows how to keep people not on your server + from using images on your server as inline-images on their + pages. This is not a recommended configuration, but it can work + in limited circumstances. We assume that all your images are in + a directory called /web/images.

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Allow browsers that do not send Referer info
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    For more information about this technique, see the + ApacheToday tutorial " + Keeping Your Images from Adorning Other Sites".

    +
    +
    +
    diff --git a/trunk/docs/manual/env.xml.ja b/trunk/docs/manual/env.xml.ja new file mode 100644 index 0000000000..8ad838984c --- /dev/null +++ b/trunk/docs/manual/env.xml.ja @@ -0,0 +1,426 @@ + + + + + + + + + + Apache $B$N4D6-JQ?t(B + + +

    Apache HTTP $B%5!<%P$O(B$B4D6-JQ?t(B$B$H8F$P$l$k!"L>A0$N$D$$$?(B + $BJQ?t$K>pJs$r5-21$9$k;EAH$_$rDs6!$7$F$$$^$9!#$3$N>pJs$O%m%0<}=8$d(B + $B%"%/%;%9@)8f$J$I$N$$$m$$$m$JA`:n$r@)8f$9$k$?$a$K;H$&$3$H$,$G$-$^$9!#(B + $B$3$l$i$NJQ?t$O(B CGI $B%9%/%j%W%H$J$I$N30It%W%m%0%i%`$HDL?.$9$k$?$a$K$b(B + $B;H$o$l$^$9!#$3$NJ8=q$O$=$l$i$NJQ?t$NA`:nJ}K!$H;HMQJ}K!$r$$$/$D$+(B + $B>R2p$7$^$9!#(B

    + +

    $B$3$l$i$NJQ?t$O(B$B4D6-JQ?t(B$B$H8F$P$l$F$$$^$9$,!"%*%Z%l!<%F%#%s%0(B + $B%7%9%F%`$K$h$C$F@)8f$5$l$F$$$k4D6-JQ?t$HF1$8$G$O$"$j$^$;$s!#(B + $Bl9g$O!"(B + $B%*%Z%l!<%F%#%s%0%7%9%F%`$N%7%'%k$,Ds6!$7$F$$$kI8=`$N4D6-JQ?t$N(B + $BA`:nJ}K!$r;H$o$J$1$l$P$J$j$^$;$s!#(B

    +
    + +
    + $B4D6-JQ?t$N@_Dj(B + + + mod_env + mod_rewrite + mod_setenvif + mod_unique_id + + + BrowserMatch + BrowserMatchNoCase + PassEnv + RewriteRule + SetEnv + SetEnvIf + SetEnvIfNoCase + UnsetEnv + + + +
    + $B4pK\E*$J4D6-$NA`:n(B + +

    Apache $B$K$*$$$F4D6-JQ?t$r@_Dj$9$k0lHV4pK\E*$JJ}K!$O!"(B + $BL5>r7o$K4D6-JQ?t$r@_Dj$9$k(B SetEnv $B%G%#%l%/%F%#%V$r;HMQ$9$k$3$H$G$9!#(B + PassEnv + $B%G%#%l%/%F%#%V$K$h$j!"(BApache $B$,5/F0$5$l$?%7%'%k$N(B + $B4D6-JQ?t$rEO$9$3$H$b$G$-$^$9!#(B

    + +
    +
    + $B%j%/%(%9%HKh$K>r7o$K4p$E$$$F@_Dj$9$k(B + +

    $B$h$j=@Fp@-$r9b$a$k$?$a$K!"(Bmod_setenvif + $B$GDs6!$5$l$F$$$k%G%#%l%/%F%#%V$r;HMQ$9$k$3$H$G!"%j%/%(%9%H$N(B + $BFC@-$K4p$E$$$F4D6-JQ?t$r@_Dj$9$k$3$H$,$G$-$^$9!#Nc$($P!"FCDj$N%V%i%&%6(B + (User-Agent) $B$N%j%/%(%9%H$dFCDj$N(B Referer [$B0U?^E*$JDV$j$G$9(B] + ($BLuCm(B: $B@5$7$$DV$j$O(B referrer $B$G$9$,!"(BHTTP $B$N;EMM$G$O(B Referer + $B$H$J$C$F$$$^$9(B) $B%X%C%@$,8+$D$+$C$?$H$-$N$_JQ?t$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + mod_rewrite $B$N(B RewriteRule + $B%G%#%l%/%F%#%V$K$*$$$F4D6-JQ?t$r@_Dj$9$k(B [E=...] + $B%*%W%7%g%s$r;HMQ$9$k$3$H$G!"(B + $B$h$j=@Fp$J@_Dj$r9T$J$&$3$H$,$G$-$^$9!#(B

    + +
    +
    + $B0l0U$J<1JL;R(B + +

    mod_unique_id $B$O!"Hs>o$K8B$i$l$?>r7o$N2<$G(B + $B!V$9$Y$F!W$N%j%/%(%9%H$K$D$$$F!"0l0U$G$"$k$3$H$,J]>Z$5$l$F$$$kCM$r4D6-JQ?t(B + UNIQUE_ID $B$K@_Dj$7$^$9!#(B

    + +
    +
    + $BI8=`(B CGI $BJQ?t(B + +

    Apache $B$N@_Dj%U%!%$%k$G@_Dj$5$l$?4D6-JQ?t$H%7%'%k$+$iEO$5$l$k(B + $B4D6-JQ?t$K2C$($F!"(BCGI $B%9%/%j%W%H$H(B SSI $B%Z!<%8$K$O(B CGI $B$N;EMM(B$B$GMW5a$5$l$F$$$k!"(B + $B%j%/%(%9%H$N%a%?>pJs$r;}$C$?4D6-JQ?t$NAH$,Ds6!$5$l$^$9!#(B

    + +
    +
    + $B$$$/$D$+$NCm0U(B + +
      +
    • $B4D6-$rA`:n$9$k%G%#%l%/%F%#%V$r;H$C$FI8=`(B CGI + $BJQ?t$r>e=q$-$7$?$jJQ99$7$?$j$9$k$3$H$O$G$-$^$;$s!#(B
    • + +
    • CGI $B%9%/%j%W%H$r5/F0$9$k$?$a$K(B suexec + $B$,;HMQ$5$l$F$$$k>l9g!"(BCGI $B%9%/%j%W%H$,5/F0$9$k$?$a$K!"4D6-JQ?t$O(B$B0BA4(B$B$J4D6-JQ?t$NAH$K@0M}$5$l$^$9!#(B + $B$3$N0BA4$J4D6-JQ?t$N=89g$O!"%3%s%Q%$%k;~$K(B suexec.c + $B$GDj5A$5$l$^$9!#(B
    • + +
    • $B0\?"@-$N$?$a$K!"4D6-JQ?t$NL>A0$O%"%k%U%!%Y%C%H!"(B + $B?t;z$H%"%s%@!<%9%3%"(B ($BLuCm(B: '_') $B$@$1$+$i@.$j$^$9!#(B + $B$5$i$K!":G=i$NJ8;z$O?t;z$G$"$C$F$O$$$1$^$;$s!#(B + $B$3$N@)8B$K9g$o$J$$J8;z$O(B CGI $B%9%/%j%W%H$H(B SSI + $B%Z!<%8$KEO$5$l$k$H$-$K%"%s%@!<%9%3%"$KCV49$5$l$^$9!#(B
    • +
    +
    +
    +
    + $B4D6-JQ?t$N;HMQ(B + + + + mod_authz_host + mod_cgi + mod_ext_filter + mod_headers + mod_include + mod_log_config + mod_rewrite + + + Allow + CustomLog + Deny + ExtFilterDefine + Header + LogFormat + RewriteCond + RewriteRule + + + +
    + CGI $B%9%/%j%W%H(B + +

    $B4D6-JQ?t$NpJs$rEA$($k$3$H$G$9!#(B + $B>e$G@bL@$5$l$F$$$k$h$&$K!"(BCGI $B%9%/%j%W%H$KEO$5$l$k4D6-JQ?t$O(B Apache + $B$N@_Dj$K$h$j@_Dj$5$l$kJQ?t$K2C$($F!"%j%/%(%9%H$NI8=`$N%a%?>pJs$r4^$s$G$$$^$9!#(B + $B>\:Y$O(B CGI $B%A%e!<%H%j%"%k(B + $B$r;2>H$7$F$/$@$5$$!#(B

    + +
    +
    + SSI $B%Z!<%8(B + +

    mod_include $B$N(B INCLUDES $B%U%#%k%?$G=hM}$5$l$k(B + server-parsed (SSI) $B%I%-%e%a%s%H$G$O!"(Becho + $BMWAG$r;HMQ$9$k$H4D6-JQ?t$,=PNO$5$l$^$9!#(B + $B$^$?!"%Z!<%8$N$"$kItJ,$,%j%/%(%9%H$N@-\:Y$O(B + SSI $B%A%e!<%H%j%"%k(B $B$r;2>H$7$F$/$@$5$$!#(B

    + +
    +
    + $B%"%/%;%9@)8f(B + +

    allow from env= $B%G%#%l%/%F%#%V$H(B deny from env= + $B%G%#%l%/%F%#%V$r;HMQ$7$F!"%5!<%P$X$N%"%/%;%9$r4D6-JQ?t$NCM$G@)8f$9$k$3$H$,$G$-$^$9!#(B + SetEnvIf + $B%G%#%l%/%F%#%V$HAH$_9g$o$;$k$3$H$G!"%/%i%$%"%s%H$NFC@-$K4p$E$$$F(B + $B%5!<%P$X$N%"%/%;%9@)8f$r=@Fp$K9T$J$&$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B + $B$?$H$($P!"$3$l$i$N%G%#%l%/%F%#%V$r;HMQ$7$F!"FCDj$N%V%i%&%6(B (User-Agent) + $B$+$i$N%"%/%;%9$r5qH]$9$k$3$H$,$G$-$^$9!#(B

    + +
    +
    + $B>r7oIU$-%m%05-O?(B + +

    LogFormat + $B%G%#%l%/%F%#%V$N%*%W%7%g%s(B %e + $B$r;HMQ$9$k$3$H$G!"4D6-JQ?t$r%"%/%;%9%m%0$K5-O?$9$k$3$H$,$G$-$^$9!#$5$i$K!"(B + CustomLog + $B%G%#%l%/%F%#%V$N>r7oJ,4t<0$r;HMQ$9$k$3$H$G!"(B + $B4D6-JQ?t$NCM$K$h$C$F%j%/%(%9%H$r%m%0$K5-O?$9$k$+$I$&$+$r7h$a$k$3$H$,$G$-$^$9!#(B + SetEnvIf + $B%G%#%l%/%F%#%V$HAH$_9g$o$;$k$3$H$G!"(B + $B$I$N%j%/%(%9%H$r%m%0$K5-O?$9$k$+$r=@Fp$K@)8f$9$k$3$H$,2DG=$K$J$j$^$9!#$?$H$($P!"(B + gif $B$G=*$o$k%U%!%$%kL>$X$N%j%/%(%9%H$O%m%0$K5-O?$7$J$$!"(B + $B0c$&%5%V%M%C%H$N%/%i%$%"%s%H$+$i$N%j%/%(%9%H$@$1$r%m%0$K5-O?$9$k!"(B + $B$H$$$&A*Br$,2DG=$G$9!#(B

    + +
    +
    + $B>r7oIU$-1~Ez%X%C%@(B + +

    Header + $B%G%#%l%/%F%#%V$O4D6-JQ?t$NB8:_$dIT:_$K$h$C$F%/%i%$%"%s%H$X$N1~Ez$KFCDj$N(B + HTTP $B%X%C%@$rIU$1$k$+$I$&$+$r7h$a$k$3$H$,$G$-$^$9!#(B + $B$3$l$K$h$j!"$?$H$($P!"%/%i%$%"%s%H$+$i$N%j%/%(%9%H(B + $B$K$"$k%X%C%@$,$"$k>l9g$K$N$_FCDj$N1~Ez%X%C%@$rAw$k!"$H$$$&$h$&$J$3$H$,(B + $B$G$-$^$9!#(B

    + +
    + +
    + $B30It%U%#%k%?$NE,MQ(B + +

    ExtFilterDefine + $B%G%#%l%/%F%#%V$r;HMQ$7$F(B + mod_ext_filter $B$G@_Dj$5$l$k30It%U%#%k%?$O!"(B + disableenv= $B$H(B enableenv= + $B%*%W%7%g%s$r;H$C$F!"4D6-JQ?t$K$h$k>r7oIU$-E,MQ$,$G$-$^$9!#(B

    +
    + +
    + URL $B$N=q$-49$((B + +

    RewriteCond + $B%G%#%l%/%F%#%V$G(B$BI>2AJ8;zNs(B$B$H$7$F(B + %{ENV:...} $B<0$r;XDj$9$k$3$H$G!"(Bmod_rewrite + $B$N=q$-49$(%(%s%8%s$,4D6-JQ?t$K4p$$$F>r7oJ,4t$r9T$J$&$3$H$,$G$-$^$9!#(B + mod_rewrite $B$,;HMQ2DG=$JJQ?t$G(B ENV: $B$,A0$K$D$$$F$$$J$$JQ?t$O!"(B + $B$N%b%8%e!<%k$+$i$O;HMQ$G$-$J$$(B mod_rewrite $BMQ$NFCJL$JJQ?t$G$9!#(B +

    +
    +
    + +
    + $BFCJL$JL\E*$N4D6-JQ?t(B + +

    $B8_49@-$NLdBj$r2r7h$9$k$?$a$K!"FCDj$N%/%i%$%"%s%H$HDL?.$7$F$$$k$H$-$O(B + Apache $B$NF0:n$rJQ99$G$-$k5!9=$,F3F~$5$l$^$7$?!#$G$-$k$@$1=@Fp$K$9$k$?$a$K!"(B + $B$3$l$i$N5!9=$O4D6-JQ?t$rDj5A$9$k$3$H$G8F$S=P$5$l$^$9!#IaDL$O!"(B + BrowserMatch + $B%G%#%l%/%F%#%V$r;H$$$^$9$,!"$?$H$($P(B SetEnv $B%G%#%l%/%F%#%V$d(B PassEnv $B%G%#%l%/%F%#%V$b;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + +
    + downgrade-1.0 + +

    $B$3$l$r;XDj$9$k$3$H$G!"%j%/%(%9%H$,(B HTTP/1.0 + $B$h$j?7$7$$%W%m%H%3%k$N>l9g$G$b!"(BHTTP/1.0 $B$H$7$F07$o$l$^$9!#(B

    + +
    +
    + force-gzip +

    DEFLATE $B%U%#%k%?$,;HMQ$9$k$h$&$K@_Dj$5$l$F$$$k$H$-$K!"(B + $B$3$N4D6-JQ?t$O%V%i%&%6$N(B accept-encoding $B$N@_Dj$rL5;k$7$F>o$K(B + $B05=L$5$l$?=PNO$rAw$k$h$&$K$7$^$9!#(B

    +
    +
    + force-no-vary + +

    $B1~Ez%X%C%@$,%/%i%$%"%s%H$KAw$i$l$kA0$K(B Vary + $B%U%#!<%k%I$rforce-response-1.0 + $B$,@_Dj$5$l$?$3$H$K$J$j$^$9!#(B

    + +
    +
    + force-response-1.0 + +

    $B$3$l$,@_Dj$5$l$F$$$k$H!"(BHTTP/1.0 $B%j%/%(%9%H$rH/9T$9$k%/%i%$%"%s%H$KBP$7$F$O(B + $B>o$K(B HTTP/1.0 $B$G1~Ez$9$k$h$&$K$J$j$^$9!#$3$N5!G=$O!"(B + $B85!9$O(B AOL $B$N%W%m%-%7$NLdBj$N$?$a$K +

    + +
    + gzip-only-text/html + +

    $B$3$l$,(B 1 $B$K@_Dj$5$l$k$H!"$3$NJQ?t$O(B text/html + $B0J30$N%3%s%F%s%H%?%$%W$KBP$9$k!"(Bmod_deflate + $BDs6!$N(B DEFLATE $B=PNO%U%#%k%?$rL58z$K$7$^$9!#(B + $B$^$?!"@EE*$K!"4{$K05=L$5$l$?%U%!%$%k$r;HMQ$7$?$$>l9g!"(B + (gzip $B$@$1$G$J$/!"(B"identity" $B$H0[$J$kA4$F$N%(%s%3!<%I$KBP$7$F(B) + mod_negotiation $B$bJQ?t$rI>2A$7$^$9!#(B

    +
    + +
    no-gzip +

    $B%;%C%H$5$l$k$H!"(Bmod_deflate $B$N(B + DEFLATE $B%U%#%k%?$,%*%U$K$J$j$^$9!#(B + $B$=$7$F(B mod_negotiation + $B$O%(%s%3!<%I$5$l$?%j%=!<%9$rAw$i$J$$$h$&$K$7$^$9!#(B

    +
    + +
    + nokeepalive + +

    $B$3$l$,@_Dj$5$l$F$$$k>l9g$O!"(BKeepAlive $B$r;HMQ$7$J$$$h$&$K$7$^$9!#(B

    + +
    prefer-language + +

    mod_negotiation $B$N5sF0$K1F6A$rM?$($^$9!#(B + (en, ja, x-klingon$B$H$$$C$?(B) + $B8@8l%?%0$,3JG<$5$l$F$$$l$P!"$=$N8@8l$N(B variant $B$rAw?.$7$h$&$H$7$^$9!#(B + $B$=$N$h$&$J(B variant $B$,$J$$>l9g$O!"(B + $BDL>o$N(B$B%M%4%7%(!<%7%g%s(B$B=hM}$,(B + $BE,MQ$5$l$^$9!#(B

    + +
    + +
    +
    + redirect-carefully + +

    $B$3$l$O%/%i%$%"%s%H$X$N%j%@%$%l%/%H$NAw?.$r%5!<%P$,$h$jCm0U?<$/(B + $B9T$J$&$h$&$K$7$^$9!#(B + $B$3$l$ODL>o!"%j%@%$%l%/%H$K:]$7$F%/%i%$%"%s%H$K(B + $BLdBj$,$"$k$3$H$,J,$+$C$F$$$k>l9g$K;H$o$l$^$9!#$3$N5!G=$O85!9$O(B + $B%^%$%/%m%=%U%H$N%&%'%V%U%)%k%@$N%=%U%H$,(B DAV + $B%a%=%C%I$K$h$k%G%#%l%/%H%j$N%j%=!<%9$X$N%j%@%$%l%/%H$N07$$$K(B + $BLdBj$,$j!"$=$l$r2sHr$9$k$?$a$K + +

    + +
    + suppress-error-charset + +

    Apache 2.2 $B0J9_$GMxMQ2DG=(B

    + +

    $B%/%i%$%"%s%H$N%j%/%(%9%H$KBP$9$k1~Ez$H$7$F%j%@%$%l%/%H$rAw?.$9$k:]!"(B + $B%l%9%]%s%9$K$O%j%@%$%l%/%H$,<+F0E*$K9T$J$($J$$(B ($B9T$J$o$l$J$$(B) + $B>l9g$KI=<($9$k%F%-%9%H$,4^$^$l$^$9!#(B + $BDL>o!"$3$N%F%-%9%H$K9gCW$7$?%-%c%i%/%?%;%C%H!"(BISO-8859-1 + $B$G%i%Y%kIU$1$r$7$^$9!#(B

    +

    $B$7$+$7!"%j%@%$%l%/%H@h$,JL$NJ8;z%;%C%H$r;H$C$F$$$k>l9g!"(B + $B$"$kLdBj$N$"$k%V%i%&%6$N%P!<%8%g%s$G$O!"(B + $B%j%@%$%l%/%H@h$N +

    $B$3$N4D6-JQ?t$r@_Dj$9$k$3$H$G!"%j%@%$%l%/%7%g%s%F%-%9%H$KBP$9$k(B + $B%-%c%i%/%?%;%C%H$N;XDj$r=|5n$7$^$9$N$G!"$=$l$iLdBj$N$"$k%V%i%&%6$G$b(B + $B%j%@%$%l%/%H@h$NJ8;z%;%C%H$r@5$7$/;H$&$h$&$K$G$-$^$9!#(B

    + +
    + +
    + +
    + $BNc(B + +
    + $B$*$+$7$J5sF0$r$9$k%/%i%$%"%s%H$KBP$7$F%W%m%H%3%k$NF0:n$rJQ99$9$k(B + +

    $B%/%i%$%"%s%H$K4X$9$k4{CN$NLdBj$KBP=h$9$k$?$a$K!"0J2<$N9T$r(B + httpd.conf $B$KF~$l$k$3$H$r?d>)$7$F$$$^$9!#(B

    +
    +#
    +# The following directives modify normal HTTP response behavior.
    +# The first directive disables keepalive for Netscape 2.x and browsers that
    +# spoof it. There are known problems with these browser implementations.
    +# The second directive is for Microsoft Internet Explorer 4.0b2
    +# which has a broken HTTP/1.1 implementation and does not properly
    +# support keepalive when it is used on 301 or 302 (redirect) responses.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# The following directive disables HTTP/1.1 responses to browsers which
    +# are in violation of the HTTP/1.0 spec by not being able to grok a
    +# basic 1.1 response.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + +
    +
    + $B2hA|$X$N%j%/%(%9%H$r%"%/%;%9%m%0$K5-O?$7$J$$(B + +

    $B$3$NNc$G$O!"2hA|$X$N%j%/%(%9%H$,%"%/%;%9%m%0$K8=$l$J$$$h$&$K$7$^$9!#(B + $B$3$l$rJQ99$9$k$3$H$G!"FCDj$N%G%#%l%/%H%j$N%m%0<}=8$r$d$a$?$j!"(B + $BFCDj$N%[%9%H$+$i$N%j%/%(%9%H$N%m%0<}=8$r$d$a$?$j$9$k$3$H$,4JC1$K$G$-$^$9!#(B +

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + +
    +
    + $B!V2hA|$NEpMQ!W$rKI$0(B + +

    $B$3$NNc$O!"JL$N%5!<%P$K$$$k?M$,!"$"$J$?$N%5!<%P$K$"$k2hA|$r(B + inline $B2hA|$H$7$F;HMQ$9$k$3$H$rKI$.$^$9!#(B + $B$3$l$O?d>)$5$l$F$$$k@_Dj$G$O$"$j$^$;$s$,!"$"$k8BDj$5$l$?>u67$G$OM-8z$G$9!#(B + $B$3$3$G$O!"$9$Y$F$N2hA|$O(B /web/images + $B$H$$$&%G%#%l%/%H%j$K$"$k$H2>Dj$7$^$9!#(B

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Allow browsers that do not send Referer info
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    $B$3$N\$7$$>pJs$O(B ApacheToday $B$N%A%e!<%H%j%"%k!V(BKeeping Your Images from Adorning Other Sites + $B!W$r;2>H$7$F$/$@$5$$!#(B

    +
    +
    +
    diff --git a/trunk/docs/manual/env.xml.ko b/trunk/docs/manual/env.xml.ko new file mode 100644 index 0000000000..116a7841ab --- /dev/null +++ b/trunk/docs/manual/env.xml.ko @@ -0,0 +1,410 @@ + + + + + + + + + + ¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ȯ°æº¯¼ö(environment variable)¶ó´Â + º¯¼ö¿¡ Á¤º¸¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Ù. ÀÌ Á¤º¸¸¦ »ç¿ëÇÏ¿© ·Î±×³ª + Á¢±ÙÁ¦¾î µî ¿©·¯ ÀÛ¾÷À» Á¶ÀýÇÑ´Ù. ¶Ç, ȯ°æº¯¼ö´Â CGI ½ºÅ©¸³Æ®¿Í + °°Àº ¿ÜºÎ ÇÁ·Î±×·¥°ú Åë½ÅÇÏ´Â ¼ö´ÜÀÌ µÈ´Ù. ÀÌ ¹®¼­´Â ȯ°æº¯¼ö¸¦ + ´Ù·ç°í »ç¿ëÇÏ´Â ´Ù¾çÇÑ ¹æ¹ýµéÀ» ¼³¸íÇÑ´Ù.

    + +

    ÀÌ º¯¼öµéÀ» ȯ°æº¯¼ö¶ó°í ºÎ¸£Áö¸¸, ¿î¿µÃ¼Á¦¿¡¼­ + ¸»Çϴ ȯ°æº¯¼ö¿Í ´Ù¸£´Ù. ÀÌ º¯¼ö´Â ¾ÆÆÄÄ¡ ³»ºÎ¿¡ ÀúÀåµÇ°í + »ç¿ëµÈ´Ù. ȯ°æº¯¼ö´Â CGI ½ºÅ©¸³Æ®³ª Server Side Include + ½ºÅ©¸³Æ®·Î ³Ñ°ÜÁú¶§¸¸ ½ÇÁ¦ ¿î¿µÃ¼Á¦ ȯ°æº¯¼ö°¡ µÈ´Ù. ¼­¹ö¸¦ + ½ÇÇàÇÏ´Â ¿î¿µÃ¼Á¦ ȯ°æÀ» ¼öÁ¤ÇÏ°í ½Í´Ù¸é ¿î¿µÃ¼Á¦ ½©¿¡¼­ + ȯ°æÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    +
    + +
    + ȯ°æº¯¼ö ¼³Á¤Çϱâ + + + mod_env + mod_rewrite + mod_setenvif + mod_unique_id + + + BrowserMatch + BrowserMatchNoCase + PassEnv + RewriteRule + SetEnv + SetEnvIf + SetEnvIfNoCase + UnsetEnv + + + +
    + ±âº»ÀûÀΠȯ°æ¼³Á¤ + +

    ¾ÆÆÄÄ¡¿¡¼­ ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ´Â °¡Àå ±âº»ÀûÀÎ ¹æ¹ýÀº + ¹«Á¶°ÇÀûÀÎ SetEnv Áö½Ã¾î¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. PassEnv Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼­¹ö¸¦ ½ÃÀÛÇÑ ½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Ã ¼öµµ ÀÖ´Ù.

    + +
    +
    + ¿äû¿¡ µû¸¥ Á¶°ÇºÎ ¼³Á¤ + +

    ´õ À¯¿¬ÇÏ°Ô, mod_setenvif°¡ Á¦°øÇÏ´Â Áö½Ã¾î´Â ¿äû¸¶´Ù + ¿äûÀÇ Æ¯Â¡¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¾î, ƯÁ¤ + ºê¶ó¿ìÀú·Î (User-Agent) ¿äûÇϰųª ƯÁ¤ Referer (¸ÂÃã¹ýÀÌ + Ʋ¸®Áö ¾Ê¾Ò´Ù) Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ º¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö + ÀÖ´Ù. ½ÉÁö¾î mod_rewrite¿¡ ÀÖ´Â RewriteRuleÀÇ + [E=...] ¿É¼ÇÀ» »ç¿ëÇÏ¿© ´õ À¯¿¬ÇÏ°Ô È¯°æº¯¼ö¸¦ + ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù.

    + +
    +
    + À¯ÀÏÇÑ ½Äº°ÀÚ + +

    ¸¶Áö¸·À¸·Î mod_unique_id´Â °¢ ¿äû¿¡ ´ëÇØ ¾î¶² °æ¿ì¿¡µµ + "¸ðµç" ¿äûÁß¿¡ È®½ÇÈ÷ À¯ÀÏÇÑ(°ãÄ¡Áö¾ÊÀº) °ªÀ¸·Î + UNIQUE_ID ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +
    +
    + Ç¥ÁØ CGI º¯¼ö + +

    CGI ½ºÅ©¸³Æ®¿Í SSI ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ ¼³Á¤ÇÏ¿´°Å³ª + ½©¿¡¼­ °¡Á®¿Â ȯ°æº¯¼ö ¿Ü¿¡ Ãß°¡·Î CGI ±Ô¾àÀÌ ±ÔÁ¤ÇÑ + ¿äû¿¡ ´ëÇÑ Á¤º¸¸¦ ¾Ë·ÁÁִ ȯ°æº¯¼öµéÀ» ¹Þ´Â´Ù.

    + +
    +
    + ÁÖÀÇÇÒ Á¡ + +
      +
    • ȯ°æ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Ç¥ÁØ CGI º¯¼ö¸¦ ¹«½ÃÇϰųª + ¼öÁ¤ÇÒ ¼ö ¾ø´Ù.
    • + +
    • suexec°¡ CGI ½ºÅ©¸³Æ®¸¦ + ½ÇÇàÇÏ´Â °æ¿ì, ½ÃÀÛÇϱâÀü¿¡ CGI ½ºÅ©¸³Æ®ÀÇ È¯°æÀº + ¾ÈÀüÇÑ º¯¼öµé¸¸ °¡Áöµµ·Ï û¼ÒµÈ´Ù. + ¾ÈÀüÇÑ º¯¼ö ¸ñ·ÏÀº ÄÄÆÄÀϽà + suexec.c¿¡ Á¤ÀǵȴÙ.
    • + +
    • Æ÷ÆÃÀ» À§ÇØ È¯°æº¯¼ö À̸§¿¡´Â ¿ÀÁ÷ ¹®ÀÚ, ¼ýÀÚ, + ¹ØÁÙ¹®ÀÚ¸¸ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. ¶Ç, ù¹ø° ¹®ÀÚ·Î + ¼ýÀÚ¸¦ »ç¿ëÇÏÁö¾Ê´Â °ÍÀÌ ÁÁ´Ù. CGI ½ºÅ©¸³Æ®³ª SSI + ÆäÀÌÁö¿¡ ³Ñ¾î°¥¶§ ÀÌ¿ÜÀÇ ¹®ÀÚ´Â ¹ØÁÙ·Î ´ëüµÈ´Ù.
    • +
    +
    +
    +
    + ȯ°æº¯¼ö »ç¿ëÇϱâ + + + + mod_authz_host + mod_cgi + mod_ext_filter + mod_headers + mod_include + mod_log_config + mod_rewrite + + + Allow + CustomLog + Deny + ExtFilterDefine + Header + LogFormat + RewriteCond + RewriteRule + + + +
    + CGI ½ºÅ©¸³Æ® + +

    ȯ°æº¯¼öÀÇ ÁÖµÈ ¿ëµµÁß Çϳª´Â CGI ½ºÅ©¸³Æ®¿Í Á¤º¸¸¦ + ±³È¯ÇÏ´Â °ÍÀÌ´Ù. ¾Õ¿¡¼­ ¼³¸íÇßµíÀÌ ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ ¼³Á¤ÇÑ + º¯¼ö¿Ü¿¡ ¿äû¿¡ ´ëÇÑ Ç¥ÁØ Á¤º¸¸¦ °¡Áø º¯¼ö°¡ CGI ½ºÅ©¸³Æ®·Î + ³Ñ¾î°£´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº CGI + ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + +
    +
    + SSI ÆäÀÌÁö + +

    mod_includeÀÇ INCLUDES ÇÊÅÍ°¡ ó¸®ÇÏ´Â + ¼­¹öÆÄ½Ì (SSI) ¹®¼­´Â echo ¿ä¼Ò¸¦ »ç¿ëÇÏ¿© + ȯ°æº¯¼ö¸¦ Ãâ·ÂÇÒ ¼ö ÀÖ°í, ȯ°æº¯¼ö¸¦ »ç¿ëÇÏ¿© ¿äûÀÇ + Ư¡¿¡ µû¶ó È帧Á¦¾î ¿ä¼Ò·Î ÆäÀÌÁöÀÇ ÀϺθ¦ º¯°æÇÒ ¼ö + ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¶Ç SSI ¹®¼­¿¡°Ô À§¿¡¼­ ¼³¸íÇÑ Ç¥ÁØ CGI + ȯ°æº¯¼ö¸¦ Á¦°øÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº SSI ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + +
    +
    + Á¢±ÙÁ¦¾î + +

    allow from env=°ú deny from env= + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ȯ°æº¯¼ö °ª¿¡ µû¶ó ¼­¹ö·ÎÀÇ Á¢±ÙÀ» + Á¶ÀýÇÒ ¼ö ÀÖ´Ù. SetEnvIf¿Í °°ÀÌ »ç¿ëÇϸé + Ŭ¶óÀ̾ðÆ®ÀÇ Æ¯Â¡¿¡ µû¶ó ÀÚÀ¯·Ó°Ô ¼­¹ö·ÎÀÇ Á¢±ÙÀ» Á¦¾îÇÒ + ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ƯÁ¤ ºê¶ó¿ìÀúÀÇ (User-Agent) Á¢±ÙÀ» + °ÅºÎÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    + Á¶°ÇºÎ ·Î±× + +

    LogFormatÀÇ + %e ¿É¼ÇÀ» »ç¿ëÇÏ¿© ȯ°æº¯¼ö¸¦ Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÒ ¼ö ÀÖ´Ù. ¶Ç, CustomLog Áö½Ã¾îÀÇ + Á¶°ÇºÎ Çü½ÄÀ» »ç¿ëÇϸé ȯ°æº¯¼öÀÇ »óȲ¿¡ µû¶ó ¿äûÀ» + ·Î±×ÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÒ ¼ö ÀÖ´Ù. SetEnvIf¿Í °°ÀÌ »ç¿ëÇÏ¿© + ¾î¶² ¿äûÀ» ·Î±×ÇÒÁö ÀÚÀ¯·Ó°Ô °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + ÆÄÀϸíÀÌ gif·Î ³¡³ª´Â ¿äûÀº ·Î±×ÇÏÁö ¾Ê°Å³ª, + ¿ÜºÎ ³×Æ®¿÷¿¡ Àִ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¸¸À» ·Î±×ÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    + Á¶°ÇºÎ ÀÀ´ä Çì´õ + +

    Header + Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÀ´äÀ» º¸³¾¶§ ȯ°æº¯¼öÀÇ À¯¹«¿¡ + µû¶ó ¾î¶² HTTP Çì´õ¸¦ Æ÷ÇÔÇÒÁö °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ƯÁ¤ Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ + ¾î¶² ÀÀ´ä Çì´õ¸¦ º¸³¾ ¼ö ÀÖ´Ù.

    + +
    + +
    + ¿ÜºÎ ÇÊÅÍ ½ÇÇàÇϱâ + +

    mod_ext_filterÀÇ ExtFilterDefine + Áö½Ã¾î·Î ¼³Á¤ÇÑ ¿ÜºÎ ÇÊÅ͸¦ disableenv=¿Í + enableenv= ¿É¼ÇÀ» »ç¿ëÇÏ¿© ȯ°æº¯¼ö¿¡ µû¶ó + ¼±ÅÃÀûÀ¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    + URL ÀçÀÛ¼º(Rewriting) + +

    RewriteCondÀÇ + TestString¿¡ %{ENV:...} Çü½ÄÀ» + »ç¿ëÇϸé mod_rewriteÀÇ ÀçÀÛ¼º ¿£ÁøÀÌ È¯°æº¯¼ö¿¡ µû¶ó + ´Ù¸£°Ô ÇൿÇÑ´Ù. mod_rewrite¿¡¼­ ¾Õ¿¡ ENV:¸¦ + ºÙÀÌÁö¾Ê°í Á¢±ÙÇÏ´Â º¯¼ö´Â ½ÇÁ¦ ȯ°æº¯¼ö°¡ ¾Æ´ÔÀ» ÁÖÀÇÇ϶ó. + ±×µéÀº ´Ù¸¥ ¸ðµâ¿¡¼­ ÀÐÀ» ¼ö ¾ø´Â mod_rewrite¿¡ ÇÑÁ¤µÈ + º¯¼ö´Ù.

    +
    +
    + +
    + Ưº°ÇÑ ¸ñÀûÀÇ È¯°æº¯¼ö + +

    Ŭ¶óÀ̾ðÆ®¿Í ¿øÈ°ÇÑ µ¿ÀÛÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â Ưº°ÇÑ + Ŭ¶óÀ̾ðÆ®¿¡ ´ëÇØ ÀÚ½ÅÀÇ ÇൿÀ» ¼öÁ¤ÇÑ´Ù. º¸Åë BrowserMatch¿¡¼­ + ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÏ¿© ÀÌ·± ¹®Á¦¸¦ ÇØ°áÇÑ´Ù. ±×·¯³ª SetEnv¿Í PassEnv·Îµµ °¡´ÉÇÏ´Ù.

    + +
    + downgrade-1.0 + +

    ¿äûÀÌ ÀÌÈÄ ¹öÀüÀ» »ç¿ëÇÏ´õ¶óµµ HTTP/1.0 ¿äûÀ¸·Î + ó¸®ÇÑ´Ù.

    + +
    +
    + force-gzip +

    DEFLATE ÇÊÅ͸¦ »ç¿ëÇÒ¶§ ÀÌ È¯°æº¯¼ö´Â + ºê¶ó¿ìÀúÀÇ accept-encoding ¼³Á¤À» ¹«½ÃÇÏ°í ¹«Á¶°Ç + ¾ÐÃàµÈ °á°ú¸¦ º¸³½´Ù.

    +
    +
    + force-no-vary + +

    ÀÀ´äÀ» Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»±â Àü¿¡ ÀÀ´ä Çì´õ¿¡¼­ + Vary Çʵ带 »«´Ù. ¾î¶² Ŭ¶óÀ̾ðÆ®´Â ÀÌ + Çʵ带 Á¦´ë·Î Çؼ®ÇÏÁö ¸øÇÑ´Ù. ÀÌ º¯¼ö´Â ÀÌ·± ¹®Á¦¸¦ + ÇØ°áÇÑ´Ù. ¶ÇÇÑ, ÀÌ º¯¼ö´Â + force-response-1.0À» °¡Á¤ÇÑ´Ù.

    + +
    +
    + force-response-1.0 + +

    HTTP/1.0 ¿äûÀ» Çϴ Ŭ¶óÀ̾ðÆ®¿¡°Ô HTTP/1.0 ÀÀ´äÀ» + °­Á¦ÇÑ´Ù. ¿ø·¡ AOL ÇÁ·Ï½Ã¿¡ ¹®Á¦°¡ À־ ¸¸µé¾îÁ³´Ù. + ¾î¶² HTTP/1.0 Ŭ¶óÀ̾ðÆ®´Â HTTP/1.1 ÀÀ´äÀ» ¹ÞÀ¸¸é Á¦´ë·Î + µ¿ÀÛÇÏÁö ¾ÊÀ¸¹Ç·Î, ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâÀ§ÇØ »ç¿ëÇÑ´Ù.

    +
    + +
    + gzip-only-text/html + +

    °ªÀÌ "1"À̸é text/htmlÀÌ ¾Æ´Ñ content-type¿¡ + ´ëÇØ mod_deflateÀÇ DEFLATE Ãâ·ÂÇÊÅ͸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù. (gzip »Ó¸¸ ¾Æ´Ï¶ó "identity"°¡ ¾Æ´Ñ ¸ðµç + ÀÎÄÚµùÀÇ) Á¤ÀûÀ¸·Î ¾ÐÃàÇÑ ÆÄÀÏÀÇ °æ¿ì¿¡µµ + mod_negotiationÀº ÀÌ º¯¼ö¸¦ Âü°íÇÑ´Ù.

    +
    + +
    no-gzip + +

    ÀÌ ¿É¼ÇÀ» ¼³Á¤Çϸé mod_deflateÀÇ + DEFLATE ÇÊÅ͸¦ »ç¿ëÇÏÁö ¾Ê°í, + mod_negotiationÀº ÀÎÄÚµùµÈ ÀÚ¿øÀ» + º¸³»Áö ¾Ê´Â´Ù.

    + +
    + +
    + nokeepalive + +

    KeepAlive¸¦ + ¹«½ÃÇÑ´Ù.

    + +
    + +
    prefer-language + +

    ÀÌ º¯¼ö´Â mod_negotiationÀÇ Çൿ¿¡ + ¿µÇâÀ» ¹ÌÄ£´Ù. º¯¼ö°¡ (en, ja, + x-klingon µî) ¾ð¾îű׸¦ ´ã°íÀÖ´Ù¸é, + mod_negotiation´Â ±× ¾ð¾î·Î µÈ º¯ÇüÀ» + º¸³»±æ ½ÃµµÇÑ´Ù. ±×·± º¯ÇüÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ Çù»ó °úÁ¤À» ½ÃÀÛÇÑ´Ù.

    + +
    + +
    + redirect-carefully + +

    ¼­¹ö°¡ ´õ Á¶½ÉÈ÷ Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. + º¸Åë ¸®´ÙÀÌ·º¼ÇÀ» ó¸®Çϴµ¥ ¹®Á¦°¡ Àִ Ŭ¶óÀ̾ðÆ®À» + À§ÇØ »ç¿ëÇÑ´Ù. ¿ø·¡ MicrosoftÀÇ WebFolders ¼ÒÇÁÆ®¿þ¾î°¡ + DAV ¸Þ½áµå¸¦ ÅëÇØ µð·ºÅ丮 ÀÚ¿øÀÇ ¸®´ÙÀÌ·º¼ÇÀ» ó¸®Çϴµ¥ + ¹®Á¦°¡ À־ ¸¸µé¾îÁ³´Ù.

    + +
    + +
    + suppress-error-charset + +

    2.0.40 ÀÌÈÄ ¹öÀü¿¡ ÀÖ´Ù

    + +

    ¾ÆÆÄÄ¡°¡ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû¿¡ ´ëÇÑ ÀÀ´äÀ¸·Î ¸®´ÙÀÌ·º¼ÇÀ» + º¸³¾¶§ Ŭ¶óÀ̾ðÆ®°¡ ÀÚµ¿À¸·Î ¸®´ÙÀÌ·º¼ÇÀ» µû¶ó°¡Áö ¸øÇÏ´Â(ȤÀº + ¾Ê´Â) °æ¿ì¿¡ ´ëºñÇÏ¿© ÀÀ´ä¿¡ »ç¿ëÀÚ¿¡°Ô º¸¿©ÁÙ ¹®±¸¸¦ Æ÷ÇÔÇÑ´Ù. + ¾ÆÆÄÄ¡´Â º¸Åë ÀÌ ±ÛÀ» ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ¹®ÀÚÁýÇÕÀÎ ISO-8859-1·Î + Ç¥½ÃÇÑ´Ù.

    +

    ±×·¯³ª ¸®´ÙÀÌ·º¼ÇµÈ ÆäÀÌÁö°¡ ´Ù¸¥ ¹®ÀÚÁýÇÕÀ» »ç¿ëÇÒ °æ¿ì + ¾î¶² ÀÌ»óÇÑ ºê¶ó¿ìÀú ¹öÀüÀº ½ÇÁ¦ ÆäÀÌÁö°¡ ¾Æ´Ï¶ó ¸®´ÙÀÌ·º¼Ç + ÆäÀÌÁöÀÇ ¹®ÀÚÁýÇÕÀ» »ç¿ëÇÏ·Á°í ÇÑ´Ù. ¿¹¸¦ µé¾î, ±×¸®½º¾î°¡ + ÀÌ»óÇÏ°Ô º¸ÀÏ ¼ö ÀÖ´Ù.

    +

    ÀÌ È¯°æº¯¼ö´Â ¾ÆÆÄÄ¡°¡ ¸®´ÙÀÌ·º¼Ç ÆäÀÌÁö¿¡ ¹®ÀÚÁýÇÕÀ» + ¼³Á¤ÇÏÁö¾Êµµ·Ï ÇÏ¿©, ÀÌ·± ºê¶ó¿ìÀú°¡ ½ÇÁ¦ ÆäÀÌÁöÀÇ ¹®ÀÚÁýÇÕÀ» + ¿Ã¹Ù·Î »ç¿ëÇÏ°Ô ¸¸µç´Ù.

    + +
    + +
    + +
    + ¿¹Á¦ + +
    + À߸ø µ¿ÀÛÇϴ Ŭ¶óÀ̾ðÆ®µéÀ» À§ÇØ ÇÁ·ÎÅäÄÝ Çൿ + º¯°æÇϱâ + +

    Ŭ¶óÀ̾ðÆ®µéÀÇ ÀÌ¹Ì ¾Ë·ÁÁø ¹®Á¦¸¦ ÇØ°áÇϱâÀ§ÇØ + httpd.conf¿¡ ´ÙÀ½ ³»¿ëÀ» Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù.

    +
    +#
    +# ´ÙÀ½ Áö½Ã¾îµéÀº ÀϹÝÀûÀÎ HTTP ÀÀ´äÀ» º¯°æÇÑ´Ù.
    +# ù¹ø° Áö½Ã¾î´Â Netscape 2.x¿Í À̸¦ °¡ÀåÇÑ ºê¶ó¿ìÀú¿¡°Ô
    +# keepalive¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌµé ºê¶ó¿ìÀú ±¸Çö¿¡ ¹®Á¦°¡ ÀÖ´Ù.
    +# µÎ¹ø° Áö½Ã¾î´Â HTTP/1.1 ±¸ÇöÀÌ À߸øµÇ¾ú°í 301À̳ª 302
    +# (¸®´ÙÀÌ·º¼Ç) ÀÀ´ä¿¡ »ç¿ëÇÑ keepalive¸¦ Á¦´ë·Î Áö¿øÇÏÁö
    +# ¸øÇÏ´Â Microsoft Internet Explorer 4.0b2¸¦ À§ÇÑ °ÍÀÌ´Ù.
    +#
    +BrowserMatch "Mozilla/2" nokeepalive
    +BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    +
    +#
    +# ´ÙÀ½ Áö½Ã¾î´Â ±âº»ÀûÀÎ HTTP/1.1 ÀÀ´äÀ» ÀÌÇØÇÏÁö ¸øÇÏ¿©
    +# HTTP/1.0 ±Ô¾àÀ» ¾î±â´Â ºê¶ó¿ìÀú¿¡°Ô HTTP/1.1 ÀÀ´äÀ» º¸³»Áö ¾Ê´Â´Ù.
    +#
    +BrowserMatch "RealPlayer 4\.0" force-response-1.0
    +BrowserMatch "Java/1\.0" force-response-1.0
    +BrowserMatch "JDK/1\.0" force-response-1.0
    + +
    +
    + Á¢±Ù ·Î±×¿¡ À̹ÌÁö¿¡ ´ëÇÑ ¿äûÀ» ·Î±×ÇÏÁö ¾Ê±â + +

    ÀÌ ¿¹Á¦´Â À̹ÌÁö¿¡ ´ëÇÑ ¿äûÀ» Á¢±Ù ·Î±×¿¡ ±â·ÏÇÏÁö + ¾Ê´Â´Ù. ƯÁ¤ µð·ºÅ丮¿¡ ´ëÇÑ È¤Àº ƯÁ¤ È£½ºÆ®¿¡¼­ ¿Â + ¿äûÀ» ·Î±×ÇÏÁö ¾Êµµ·Ï ½±°Ô ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +SetEnvIf Request_URI \.gif image-request
    +SetEnvIf Request_URI \.jpg image-request
    +SetEnvIf Request_URI \.png image-request
    +CustomLog logs/access_log common env=!image-request
    + +
    +
    + "À̹ÌÁö µµµÏ" ¹æÁö + +

    ÀÌ ¿¹´Â ÇöÀç ¼­¹ö¿ÜÀÇ »ç¿ëÀÚ°¡ ÆäÀÌÁö¿¡ ¼­¹ö¿¡ ÀÖ´Â + À̹ÌÁö¸¦ Æ÷ÇÔÇÏÁö ¸øÇϵµ·Ï ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. ÀÌ + ¼³Á¤À» ±ÇÀåÇÏÁö´Â ¾ÊÀ¸¸ç, Á¦ÇÑµÈ °æ¿ì¿¡¸¸ µ¿ÀÛÇÑ´Ù. + ¿ì¸®´Â ¸ðµç À̹ÌÁö°¡ /web/images µð·ºÅ丮 ¾È¿¡ ÀÖ´Ù°í + °¡Á¤ÇÑ´Ù.

    +
    +SetEnvIf Referer "^http://www.example.com/" local_referal
    +# Referer Á¤º¸¸¦ º¸³»Áö ¾Ê´Â ºê¶ó¿ìÀú¸¦ Çã¿ëÇÑ´Ù
    +SetEnvIf Referer "^$" local_referal
    +<Directory /web/images>
    +   Order Deny,Allow
    +   Deny from all
    +   Allow from env=local_referal
    +</Directory>
    + +

    ÀÌ ±â¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ApacheToday ÅõÅ丮¾ó " + Keeping Your Images from Adorning Other Sites"¸¦ Âü°íÇ϶ó.

    +
    +
    +
    diff --git a/trunk/docs/manual/env.xml.meta b/trunk/docs/manual/env.xml.meta new file mode 100644 index 0000000000..fd4d4a5499 --- /dev/null +++ b/trunk/docs/manual/env.xml.meta @@ -0,0 +1,13 @@ + + + + env + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/faq/all_in_one.html b/trunk/docs/manual/faq/all_in_one.html new file mode 100644 index 0000000000..b1ee596875 --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.html @@ -0,0 +1,11 @@ +URI: all_in_one.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: all_in_one.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: all_in_one.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/faq/all_in_one.html.en b/trunk/docs/manual/faq/all_in_one.html.en new file mode 100644 index 0000000000..92f0bb4f4a --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.html.en @@ -0,0 +1,202 @@ + + + +Frequently Asked Questions - Apache HTTP Server + + + + + +
    <-
    +

    Frequently Asked Questions

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    The latest version of this FAQ is always available from the main Apache + web site, at <http://httpd.apache.org/docs-2.1/faq/>.

    + +

    Since Apache 2.0 is quite new, we don't yet know what the Frequently + Asked Questions will be. While this section fills up, you should also + consult the Apache 1.3 + FAQ to see if your question is answered there.

    +
    + +
    top
    +
    +

    Topics

    +
    Support
    What do I do when I have problems?
    +
    Error Messages
    What does this error message mean?
    +
    top
    +
    +

    Support

    + + +

    "Why can't I ...? Why won't ... work?" What to do in case of + problems

    + + +

    If you are having trouble with your Apache server software, you should + take the following steps:

    + +
    +
    Check the errorlog!
    +
    Apache tries to be helpful when it encounters a problem. In many + cases, it will provide some details by writing one or more messages to the + server error log. Sometimes this is enough for you to diagnose & fix + the problem yourself (such as file permissions or the like). The default + location of the error log is + /usr/local/apache2/logs/error_log, but see the ErrorLog directive in your config files for the + location on your server.
    + +
    Check the FAQ!
    +
    The latest version of the Apache Frequently-Asked Questions list can + always be found at the main Apache web site.
    + +
    Check the Apache bug database
    +
    Most problems that get reported to The Apache Group are recorded in + the bug database. + Please check the existing reports, open + and closed, before adding one. If you find that your + issue has already been reported, please don't add a "me, too" + report. If the original report isn't closed yet, we suggest that you + check it periodically. You might also consider contacting the original + submitter, because there may be an email exchange going on about the + issue that isn't getting recorded in the database.
    + +
    Ask in a user support forum
    +

    Apache has an active community of users who are willing to share + their knowledge. Participating in this community is usually the best and + fastest way to get answers to your questions and problems.

    + +

    Users + mailing list

    + +

    USENET newsgroups:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    If all else fails, report the problem in the bug database
    +

    If you've gone through those steps above that are appropriate and + have obtained no relief, then please do let the httpd developers + know about the problem by logging a bug + report.

    + +

    If your problem involves the server crashing and generating a core + dump, please include a backtrace (if possible). As an example,

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (Substitute the appropriate locations for your ServerRoot + and your httpd and core files. You may have to use + gdb instead of dbx.)

    +
    +
    + + +

    Whom do I contact for support?

    +

    With several million users and fewer than forty volunteer developers, + we cannot provide personal support for Apache. For free support, we + suggest participating in a user forum.

    + +

    Professional, commercial support for Apache is available from + a number of + companies.

    + +
    top
    +
    +

    Error Messages

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    Apache uses the sendfile syscall on platforms + where it is available in order to speed sending of responses. + Unfortunately, on some systems, Apache will detect the presence of + sendfile at compile-time, even when it does not work + properly. This happens most frequently when using network or + other non-standard file-system.

    + +

    Symptoms of this problem include the above message in the error + log and zero-length responses to non-zero-sized files. The + problem generally occurs only for static files, since dynamic + content usually does not make use of sendfile.

    + +

    To fix this problem, simply use the EnableSendfile directive to disable + sendfile for all or part of your server. Also see + the EnableMMAP, which can + help with similar problems.

    + + + +

    AcceptEx Failed

    + +

    If you get error messages related to the AcceptEx syscall + on win32, see the Win32DisableAcceptEx + directive.

    + + + +

    Premature end of script + headers

    + +

    Most problems with CGI scripts result in this message written in the + error log together with an Internal Server Error delivered + to the browser. A guide to helping debug this type of problem is + available in the CGI + tutorial.

    + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/all_in_one.html.ja.euc-jp b/trunk/docs/manual/faq/all_in_one.html.ja.euc-jp new file mode 100644 index 0000000000..e391387b46 --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.html.ja.euc-jp @@ -0,0 +1,206 @@ + + + +¤è¤¯¤¢¤ë¼ÁÌä - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¤è¤¯¤¢¤ë¼ÁÌä

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Apache ¤Î¼ç¥µ¥¤¥È¡¢<http://httpd.apache.org/docs-2.1/faq/> + ¤«¤éºÇ¿·ÈǤΠFAQ ¤ò¾ï¤Ë¼ê¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Apache 2.0 ¤Ï¤Þ¤À¿·¤·¤¤¤Î¤Ç¡¢²¿¤¬¤è¤¯¤¢¤ë¼ÁÌä¤Ê¤Î¤« + ¤Þ¤À¤è¤¯¤ï¤«¤Ã¤Æ¤¤¤Þ¤»¤ó¡£¤³¤Î¥»¥¯¥·¥ç¥ó¤¬Ëä¤Þ¤Ã¤Æ¤¤¤¯¤Þ¤Ç¡¢ + ´û¤Ë¼ÁÌ䤬Åú¤¨¤é¤ì¤Æ¤¤¤ë¤«¤É¤¦¤« Apache 1.3 ¤Î FAQ + ¤â¸«¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    + +
    top
    +
    +

    ¥È¥Ô¥Ã¥¯

    +
    ¥µ¥Ý¡¼¥È
    ²¿¤«ÌäÂ꤬µ¯¤³¤Ã¤¿¤È¤­¤Ë¤É¤¦¤¹¤ë?
    +
    ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
    ¤³¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Î°ÕÌ£¤Ï?
    +
    top
    +
    +

    ¥µ¥Ý¡¼¥È

    + + +

    ¡Ö¤Ê¤ó¤Ç¡Ä? ¤É¤¦¤·¤ÆÆ°ºî¤·¤Ê¤¤¡Ä?¡×ÌäÂ꤬ + µ¯¤­¤¿¤È¤­¤Ë¤É¤¦¤¹¤ë¤«

    + + +

    Apache ¤Î¥µ¡¼¥Ð¥½¥Õ¥È¥¦¥§¥¢¤Ë²¿¤«ÌäÂ꤬µ¯¤³¤Ã¤¿¤È¤­¤Ï¡¢°Ê²¼¤Î + ¼ê½ç¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤:

    + +
    +
    ¥¨¥é¡¼¥í¥°¤òÄ´¤Ù¤ë!
    +
    ÌäÂ꤬ȯÀ¸¤·¤¿¤È¤­¤Ï Apache ¤Ï¤Ê¤ë¤Ù¤¯¼ê½õ¤±¤ò¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + ¿¤¯¤Î¾ì¹ç¡¢Apache ¤Ï¥µ¡¼¥Ð¤Î¥¨¥é¡¼¥í¥°¤Ë¥á¥Ã¥»¡¼¥¸¤ò½ñ¤¯¤³¤È¤Ç¡¢¾ÜºÙ¤Ê + ¾ðÊó¤òÄ󶡤·¤Þ¤¹¡£¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢¤³¤ì¤À¤±¤ÇÌäÂê¤ò¼«Ê¬¼«¿È¤ÇʬÀϤ·¡¢ + ½¤Àµ¤¹¤ë¤¿¤á¤Ë½½Ê¬¤Ê¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹ (¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤Î + ÌäÂê¤Ê¤É)¡£¥¨¥é¡¼¥í¥°¤Î¥Ç¥Õ¥©¥ë¥È¤Î¾ì½ê¤Ï + /usr/local/apache2/logs/error_log ¤Ç¤¹¤¬¡¢¤¢¤Ê¤¿¤Î¥µ¡¼¥Ð + ¤Ç¤Î¾ì½ê¤òÃΤ뤿¤á¤Ë¤ÏÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î ErrorLog ¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
    + +
    FAQ ¤òÄ´¤Ù¤ë!
    +
    Apache ¤Î¤è¤¯¤¢¤ë¼ÁÌä¤ÎºÇ¿·ÈǤϾï¤Ë Apache ¤Î¼ç¥¦¥§¥Ö¥µ¥¤¥È¤Ë + ¤¢¤ê¤Þ¤¹¡£
    + +
    Apache ¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄ´¤Ù¤ë
    +
    Apache ¥°¥ë¡¼¥×¤ËÊó¹ð¤µ¤ì¤ë¤Û¤È¤ó¤É¤ÎÌäÂê¤Ï¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë + µ­Ï¿¤µ¤ì¤Þ¤¹¡£Open ¤â closed ¤â ´Þ¤á¤Æ¡¢ + ´û¸¤Î¥ì¥Ý¡¼¥È¤Ë¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£ + ´û¤ËÌäÂ꤬Êó¹ð¤µ¤ì¤Æ¤¤¤ë¤È¤­¡¢¡Ö»ä¤â¡×¤È¤¤¤¦Êó¹ð¤ÏÄɲ䷤ʤ¤¤Ç + ¤¯¤À¤µ¤¤¡£¸µ¤ÎÊó¹ð¤¬ close ¤µ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢Äê´üŪ¤Ë + ¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄ´¤Ù¤ë¤³¤È¤ò¤ªÁ¦¤á¤·¤Þ¤¹¡£¤Þ¤¿¡¢¸µ¤ÎÄó½Ð¼Ô¤Ë + Ï¢Íí¤ò¼è¤ë¤³¤È¤â¹Íθ¤ËÆþ¤ì¤Æ¤ª¤¯¤È¤è¤¤¤Ç¤·¤ç¤¦¡£¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë + µ­Ï¿¤µ¤ì¤Æ¤¤¤Ê¤¤ÅŻҥ᡼¥ë¤Î¸ò´¹¤¬¹Ô¤Ê¤ï¤ì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    + +
    ¥æ¡¼¥¶¥µ¥Ý¡¼¥È¥Õ¥©¡¼¥é¥à¤Ç¼ÁÌ䤹¤ë
    +

    Apache ¤Ë¤Ï¤è¤í¤³¤ó¤ÇÃ챤ò¶¦Í­¤µ¤»¤Æ¤¯¤ì¤ë³èȯ¤Ê + ¥æ¡¼¥¶¤Î¥³¥ß¥å¥Ë¥Æ¥£¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥³¥ß¥å¥Ë¥Æ¥£¤Ë»²²Ã¤¹¤ë¤³¤È¤¬¡¢ + ÉáÄ̤ϼÁÌä¤äÌäÂê¤ËÂФ¹¤ë²óÅú¤òÆÀ¤ëºÇÁ±¤ÇºÇ®¤Î¼êÃʤǤ¹¡£

    + +

    ¥æ¡¼¥¶ + ¥á¡¼¥ê¥ó¥°¥ê¥¹¥È

    + +

    USENET ¥Ë¥å¡¼¥¹¥°¥ë¡¼¥×:

    + +
    + +
    ¤â¤·¡¢Á´Éô¼ºÇÔ¤·¤¿¾ì¹ç¤Ï¡¢ÌäÂê¤ò¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤
    +

    ¾åµ­¤Î¼êÃʤÎÃæ¤Ç³ºÅö¤¹¤ë¤â¤Î¤ò¤ò¤¹¤Ù¤Æ¼è¤Ã¤Æ¡¢ + ¤½¤ì¤Ç¤âÌäÂê¤Î²ò·èºö¤òÆÀ¤é¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ð¥°¤ÎÊó¹ð¤ò + ¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ÌäÂê¤ò¤¼¤Ò httpd ³«È¯¼Ô¤ËÃΤ餻¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥µ¡¼¥Ð¤Î¥¯¥é¥Ã¥·¥å¤ä¥³¥¢¥À¥ó¥×¤ÎȯÀ¸¤¹¤ëÌäÂê¤Ç¤¢¤ì¤Ð¡¢(²Äǽ¤Ç¤¢¤ì¤Ð) + ¥Ð¥Ã¥¯¥È¥ì¡¼¥¹¤òÊó¹ð¤Ë´Þ¤á¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¡¢

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (ServerRoot ¤È httpd ¤È core ¥Õ¥¡¥¤¥ë + ¤Î°ÌÃÖ¤òŬÀڤʤâ¤Î¤ËÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£dbx ¤ÎÂå¤ï¤ê¤Ë + gdb ¤ò»È¤¦É¬Íפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£)

    +
    +
    + + +

    ï¤Ë¥µ¥Ý¡¼¥È¤òÍê¤á¤Ð¤è¤¤?

    +

    ¿ôÉ´Ëü¤Î¥æ¡¼¥¶¤ËÂФ·¤Æ¡¢40̤Ëþ¤Î¥Ü¥é¥ó¥Æ¥£¥¢³«È¯¼Ô¤·¤«¤¤¤Ê¤¤¤¿¤á¡¢ + Apache ¤Î¸Ä¿ÍŪ¤Ê¥µ¥Ý¡¼¥È¤òÄ󶡤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ÌµÎÁ¤Î + ¥µ¥Ý¡¼¥È¤Ë¤Ï¡¢¥æ¡¼¥¶¤Î¥Õ¥©¡¼¥é¥à¤Ë»²²Ã¤¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    Apache ¤Î¥×¥í¤Î¡¢¾¦ÍÑ¥µ¥Ý¡¼¥È¤â + ¿¤¯¤Î²ñ¼Ò + ¤«¤éÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    (ÌõÃí: ̵¸ú¤Ê°ú¿ô: core_output_filter: ¥Í¥Ã¥È¥ï¡¼¥¯¤Ø¤Î¥Ç¡¼¥¿¤Î + ½ñ¤­¹þ¤ß)

    + +

    Apache ¤Ï±þÅú¤ÎÊÖÁ÷¤ò®¤¯¤¹¤ë¤¿¤á¤Ë¡¢sendfile ¥·¥¹¥Æ¥à + ¥³¡¼¥ë¤¬»ÈÍѲÄǽ¤Ê¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¤Ï¤½¤Î¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò»ÈÍѤ·¤Þ¤¹¡£ + ¤È¤³¤í¤¬¡¢ÅÔ¹ç¤Î°­¤¤¤³¤È¤Ë¡¢sendfile ¤¬Àµ¤·¤¯Æ°ºî¤·¤Ê¤¤¤Ë¤â + ´Ø¤ï¤é¤º¡¢Apache ¤¬¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¸ºß¤ò¸¡ÃΤ·¤Æ¤·¤Þ¤¦¥·¥¹¥Æ¥à¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥Í¥Ã¥È¥ï¡¼¥¯¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ä¾¤ÎÈóɸ½à¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò + »ÈÍѤ·¤Æ¤¤¤ë¤È¤­¤Ë°ìÈ֤褯ȯÀ¸¤·¤Þ¤¹¡£

    + +

    ¤³¤ÎÌäÂê¤Î¾É¾õ¤Ï¡¢¾åµ­¤Î¥á¥Ã¥»¡¼¥¸¤¬¥¨¥é¡¼¥í¥°¤Ë½ñ¤«¤ì¤ë¤³¤È¤È¡¢ + ¥µ¥¤¥º¤¬¥¼¥í¤Ç¤Ê¤¤¥Õ¥¡¥¤¥ë¤Î±þÅú¤¬¥¼¥í¤Ë¤Ê¤ë¤³¤È¤Ç¤¹¡£ + ưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤Ï sendfile ¤òÍøÍѤ·¤Ê¤¤¤¿¤á¡¢ + ¤³¤ÎÌäÂê¤ÏÄ̾ï¤ÏÀÅŪ¤Ê¥Õ¥¡¥¤¥ë¤Ç¤Î¤ßȯÀ¸¤·¤Þ¤¹¡£

    + +

    ¤³¤ÎÌäÂê¤Ï¡¢EnableSendfile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ + ¥µ¡¼¥Ð¤Î¤¹¤Ù¤Æ¡¢¤â¤·¤¯¤Ï°ìÉôʬ¤ËÂФ·¤Æ sendfile ¤ò + ̵¸ú¤Ë¤¹¤ë¤À¤±¤Ç½¤Àµ¤Ç¤­¤Þ¤¹¡£Æ±ÍͤÎÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Î + EnableMMAP ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤â + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + + +

    AcceptEx Failed

    + +

    (ÌõÃí: AcceptEx ¼ºÇÔ)

    + +

    Win32 ¤Ç¤Î AcceptEx ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Ë´Ø·¸¤¹¤ë¥¨¥é¡¼ + ¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤Ã¤¿¤È¤­¤Ï¡¢Win32DisableAcceptEx ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + + +

    Premature end of script + headers

    + +

    (ÌõÃí: ¥¹¥¯¥ê¥×¥È¥Ø¥Ã¥À¤ÎÃæÅÓ½ªÎ»)

    + +

    CGI ¥¹¥¯¥ê¥×¥È¤Î¤Û¤È¤ó¤É¤ÎÌäÂê¤Ï¥¨¥é¡¼¥í¥°¤Ë¤³¤Î¥á¥Ã¥»¡¼¥¸¤¬½ñ¤«¤ì¡¢ + ¥Ö¥é¥¦¥¶¤Ë¤Ï Internal Server Error ¤¬Á÷¤é¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¼ï¤ÎÌäÂê¤Î¥Ç¥Ð¥Ã¥°ÊýË¡¤Ï CGI + ¥Á¥å¡¼¥È¥ê¥¢¥ë ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/all_in_one.html.ko.euc-kr b/trunk/docs/manual/faq/all_in_one.html.ko.euc-kr new file mode 100644 index 0000000000..ef735fd5e1 --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.html.ko.euc-kr @@ -0,0 +1,207 @@ + + + +ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) - Apache HTTP Server + + + + + +
    <-
    +

    ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    FAQ ÃÖ½ÅÆÇÀº ¾ÆÆÄÄ¡ À¥»çÀÌÆ® <http://httpd.apache.org/docs-2.1/faq/>¿¡¼­ º¼ ¼ö + ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÌ ³ª¿ÂÁö ¾ó¸¶ ¾ÈµÇ¼­ ¿ì¸®´Â ¾ÆÁ÷ ÀÚÁÖ + ¹°¾îº¸´Â Áú¹® (FAQ)ÀÌ ¹«¾ùÀÎÁö ¸ð¸¥´Ù. ³»¿ëÀÌ Ã¤¿öÁú + ¶§±îÁö ¿©±â¿¡ ÇØ´äÀÌ ¾ø´Ù¸é ¾ÆÆÄÄ¡ + 1.3 FAQµµ Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    ÁÖÁ¦

    +
    Áö¿ø
    ¹®Á¦°¡ »ý±â¸é ¾î¶»°Ô ÇØ°áÇϳª?
    +
    ¿À·ù¹®
    ÀÌ ¿À·ù¹®ÀÌ ¹«½¼ ¶æÀΰ¡?
    +
    top
    +
    +

    Áö¿ø

    + + +

    "¿Ö ... ¾ÈµÇ³ª? ¿Ö ... µ¿ÀÛÇÏÁö ¾Ê´Â°¡?" ¹®Á¦°¡ »ý±â¸é + ÇÒÀÏ

    + + +

    ¾ÆÆÄÄ¡ ¼­¹ö ¼ÒÇÁÆ®¿þ¾î¿¡ ¹®Á¦°¡ »ý±â¸é ´ÙÀ½°ú °°Àº + ´Ü°è¸¦ µû¸¥´Ù:

    + +
    +
    ¿À·ù ·Î±×(errorlog)¸¦ È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ ¼­¹ö´Â ¹®Á¦°¡ »ý±â¸é µµ¿òÀ» ÁÖ·Á°í ³ë·ÂÇÑ´Ù. + ¸¹Àº °æ¿ì ¼­¹ö ¿À·ù ·Î±×¿¡ ÀÚ¼¼ÇÑ ³»¿ëÀ» ±â·ÏÇÑ´Ù. + À̰͸¸À¸·Îµµ Á÷Á¢ (ÆÄÀϱÇÇÑ µî) ¹®Á¦¸¦ ¹ß°ßÇÏ°í °íÄ¥ ¼ö + ÀÖ´Â °æ¿ì°¡ ¸¹´Ù. ¿À·ù ·Î±×ÀÇ ±âº» À§Ä¡´Â + /usr/local/apache2/logs/error_logÀÌÁö¸¸, + Á¤È®ÇÑ À§Ä¡´Â ¼³Á¤ÆÄÀÏÀÇ ErrorLog Áö½Ã¾î¸¦ Âü°íÇ϶ó.
    + +
    FAQ¸¦ + È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ À¥»çÀÌÆ®¿¡¼­ Ç×»ó ¾ÆÆÄÄ¡ FAQ ÃÖ½ÅÆÇÀ» º¼ ¼ö + ÀÖ´Ù.
    + +
    ¾ÆÆÄÄ¡ ¹ö±× µ¥ÀÌÅͺ£À̽º¸¦ È®ÀÎÇ϶ó
    +
    ¾ÆÆÄÄ¡±×·ì(The Apache Group)¿¡ º¸°íµÈ ´ëºÎºÐÀÇ ¹®Á¦´Â + ¹ö±× + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÈ´Ù. »õ·Î ¹ö±×¸¦ Ãß°¡Çϱâ Àü¿¡, + ÀÌ¹Ì ¾Ë·ÁÁ³°Å³ª(open) ÇØ°áµÈ(closed) ¹ö±×°¡ ÀÖ´ÂÁö È®ÀÎÇϱæ + ¹Ù¶õ´Ù. ÀÌ¹Ì ¹®Á¦°¡ º¸°íµÇ¾ú´Ù¸é "³ªµµ + ÀÌ·± ¹®Á¦°¡ ÀÖ´Ù°í" º¸°íÇÏÁö ¾Ê±æ ¹Ù¶õ´Ù. ¾ÆÁ÷ + ÇØ°áµÇÁö ¾Ê¾Ò´Ù¸é ÁÖ±âÀûÀ¸·Î »óȲÀ» È®ÀÎÇÏ±æ ¹Ù¶õ´Ù. ¶Ç, + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÇÁö ¾Ê°í À̸ÞÀÏ ±³È¯À¸·Î ÁøÇàµÈ »çÇ×ÀÌ + ÀÖÀ» ¼ö ÀÖÀ¸´Ï óÀ½ ¹®Á¦¸¦ º¸°íÇÑ »ç¶÷¿¡°Ô ¿¬¶ôÇغ¼ ¼öµµ + ÀÖ´Ù.
    + +
    »ç¿ëÀÚ Áö¿ø °ø°£¿¡ + ¹®ÀÇÇÑ´Ù
    +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Áö½ÄÀ» °øÀ¯ÇÏ±æ ¿øÇÏ´Â È°¹ßÇÑ »ç¿ëÀÚ + °øµ¿Ã¼µéÀÌ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î ÀÌ·± °øµ¿Ã¼¿¡ Âü¿©ÇÏ´Â °ÍÀÌ + ¹®Á¦ÀÇ ´äÀ» ¾ò´Â °¡Àå ÁÁ°í ºü¸¥ ¹æ¹ýÀÌ´Ù.

    + +

    »ç¿ëÀÚ + ¸ÞÀϸµ¸®½ºÆ®

    + +

    USENET ´º½º±×·ì:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    À§ÀÇ ¹æ¹ýÀÌ ¸ðµÎ ½ÇÆÐÇÏ¸é ¹ö±× µ¥ÀÌÅͺ£À̽º¿¡ ¹®Á¦¸¦ + º¸°íÇÑ´Ù
    +

    À§ÀÇ ´Ü°è¸¦ ¸ðµÎ ½ÃµµÇÏ°íµµ ÇØ°áÃ¥ÀÌ ¾ø´Ù¸é, ¹ö±×¸¦ + º¸°íÇÏ¿© À¥¼­¹ö °³¹ßÀڵ鿡°Ô ¹®Á¦¸¦ ¾Ë¸®±æ + ¹Ù¶õ´Ù.

    + +

    core dump¸¦ ¸¸µé¸ç ¼­¹ö°¡ Á×´Â °æ¿ì¶ó¸é (°¡´ÉÇϸé) + backtrace(¿ªÁÖ; ¹®Á¦°¡ ½ÇÇàÆÄÀÏÀÇ Á¤È®È÷ ¾î¶² ÁöÁ¡¿¡¼­ + ¹ß»ýÇÏ¿´°í, ÇÁ·Î±×·¥ÀÌ ±× ÁöÁ¡±îÁö ¾î¶² °æ·Î·Î ½ÇÇàµÇ¾ú´ÂÁö¸¦ + ¾Ë·ÁÁÖ´Â Á¤º¸)¸¦ Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù. ¿¹¸¦ µé¾î,

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (ServerRoot, httpd, core + ÆÄÀÏÀÇ ½ÇÁ¦ À§Ä¡¸¦ ´ë½Å »ç¿ëÇ϶ó. dbx ´ë½Å + gdb¸¦ »ç¿ëÇØ¾ß ÇÒ ¼öµµ ÀÖ´Ù.)

    +
    +
    + + +

    µµ¿òÀ» ¾òÀ¸·Á¸é ´©±¸¿¡°Ô + ¿¬¶ôÇϳª?

    +

    40¸í °¡·®ÀÇ ÀÚ¹ßÀûÀ¸·Î Âü¿©ÇÑ °³¹ßÀÚ¸¸À¸·Î´Â ¼ö¹é¸¸ÀÇ + »ç¿ëÀÚ¿¡°Ô ¾ÆÆÄÄ¡¿¡ ´ëÇØ ÀÏÀÏÀÌ Áö¿øÇÒ ¼ö ¾ø´Ù. ¹«·á Áö¿øÀ» + ¾òÀ¸·Á¸é »ç¿ëÀÚ + °ø°£¿¡ Âü¿©ÇÏ±æ ±ÇÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Á÷¾÷ÀûÀÎ À¯·á Áö¿øÀº ¿©·¯ + ȸ»ç¿¡¼­ Á¦°øÇÑ´Ù.

    + +
    top
    +
    +

    ¿À·ù¹®

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    Ç÷¡ÆûÀÌ sendfile ½Ã½ºÅÛÈ£ÃâÀ» Áö¿øÇÑ´Ù¸é, + ¾ÆÆÄÄ¡´Â ÀÀ´äÀÇ ¼Óµµ¸¦ ºü¸£°ÔÇϱâÀ§ÇØ ÀÌ ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù. + ºÒÇàÈ÷µµ ¾î¶² ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡´Â ÄÄÆÄÀÏÇÒ¶§ + sendfileÀÌ Á¤»óÀûÀ¸·Î ÀÛµ¿ÇÏÁö ¾Ê´Âµ¥µµ Á¤»óÀûÀ¸·Î + ÀÛµ¿ÇÑ´Ù°í ¿ÀÆÇÇÑ´Ù. ÀÌ ¹®Á¦´Â ³×Æ®¿÷ ÆÄÀϽýºÅÛÀ̳ª ºñÇ¥ÁØ + ÆÄÀϽýºÅÛÀ» »ç¿ëÇÒ¶§ ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    ÀÌ ¹®Á¦ÀÇ Áõ»óÀº ¿À·ù ·Î±×(error log)¿¡ À§ÀÇ ¹®±¸¸¦ + ±â·ÏÇϰųª Å©±â°¡ 0ÀÌ ¾Æ´Ñ ÆÄÀÏ¿¡ ´ëÇØ Å©±â°¡ 0ÀÎ ÀÀ´äÀ» + ÇÏ´Â °æ¿ìÀÌ´Ù. µ¿ÀûÀ¸·Î ³»¿ëÀ» »ý¼ºÇÒ¶§´Â + sendfileÀ» »ç¿ëÇÏÁö ¾Ê±â¶§¹®¿¡ ÀϹÝÀûÀ¸·Î Á¤ÀûÀÎ + ÆÄÀÏÀ» ¿äûÇÒ¶§¸¸ ¹®Á¦°¡ ¹ß»ýÇÑ´Ù.

    + +

    ¹®Á¦¸¦ ÇØ°áÇÏ·Á¸é ¼­¹ö°¡ sendfileÀ» »ç¿ëÇÏÁö + ¾Êµµ·Ï EnableSendfile + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ¶Ç, ÀÌ¿Í À¯»çÇÑ ¹®Á¦¿¡ ´ëÇØ EnableMMAPÀ» Âü°íÇ϶ó.

    + + + +

    AcceptEx Failed

    + +

    win32¿¡¼­ AcceptEx ½Ã½ºÅÛÈ£Ãâ¿¡ ´ëÇÑ ¿À·ù¹®À» + ³ª¿À¸é, Win32DisableAcceptEx + Áö½Ã¾î¸¦ Âü°íÇ϶ó.

    + + + +

    Premature end of script + headers

    + +

    º¸Åë CGI ½ºÅ©¸³Æ®¿¡ ¹®Á¦°¡ ÀÖÀ¸¸é ºê¶ó¿ìÀú¿¡°Ô Internal + Server Error¸¦ º¸³»°í ¿À·ù·Î±×¿¡ ÀÌ ¹®±¸¸¦ ±â·ÏÇÑ´Ù. + ÀÌ·± ¹®Á¦¸¦ µð¹ö±ëÇÒ¶§ CGI ÅõÅ丮¾óÀÌ + µµ¿òÀÌ µÉ ¼ö ÀÖ´Ù.

    + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/all_in_one.xml b/trunk/docs/manual/faq/all_in_one.xml new file mode 100644 index 0000000000..f4c210940d --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.xml @@ -0,0 +1,44 @@ + + +]> + + + + + + +FAQ + +Frequently Asked Questions + + +

    The latest version of this FAQ is always available from the main Apache + web site, at <http://httpd.apache.org/docs-2.1/faq/>.

    + +

    Since Apache 2.0 is quite new, we don't yet know what the Frequently + Asked Questions will be. While this section fills up, you should also + consult the Apache 1.3 + FAQ to see if your question is answered there.

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/all_in_one.xml.ja b/trunk/docs/manual/faq/all_in_one.xml.ja new file mode 100644 index 0000000000..f1458092af --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.xml.ja @@ -0,0 +1,46 @@ + + +]> + + + + + + +FAQ + +$B$h$/$"$k<ALd(B + + +

    Apache $B$Nhttp://httpd.apache.org/docs-2.1/faq/> + $B$+$i:G?7HG$N(B FAQ $B$r>o$K + +

    Apache 2.0 $B$O$^$@?7$7$$$N$G!"2?$,(B$B$h$/$"$k$B$J$N$+(B + $B$^$@$h$/$o$+$C$F$$$^$;$s!#$3$N%;%/%7%g%s$,Kd$^$C$F$$$/$^$G!"(B + $B4{$KApache 1.3 $B$N(B FAQ + $B$b8+$k$h$&$K$7$F$/$@$5$$!#(B

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/all_in_one.xml.ko b/trunk/docs/manual/faq/all_in_one.xml.ko new file mode 100644 index 0000000000..40da0360b1 --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.xml.ko @@ -0,0 +1,46 @@ + + +]> + + + + + + +FAQ + +ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) + + +

    FAQ ÃÖ½ÅÆÇÀº ¾ÆÆÄÄ¡ À¥»çÀÌÆ® <http://httpd.apache.org/docs-2.1/faq/>¿¡¼­ º¼ ¼ö + ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÌ ³ª¿ÂÁö ¾ó¸¶ ¾ÈµÇ¼­ ¿ì¸®´Â ¾ÆÁ÷ ÀÚÁÖ + ¹°¾îº¸´Â Áú¹® (FAQ)ÀÌ ¹«¾ùÀÎÁö ¸ð¸¥´Ù. ³»¿ëÀÌ Ã¤¿öÁú + ¶§±îÁö ¿©±â¿¡ ÇØ´äÀÌ ¾ø´Ù¸é ¾ÆÆÄÄ¡ + 1.3 FAQµµ Âü°íÇ϶ó.

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/all_in_one.xml.meta b/trunk/docs/manual/faq/all_in_one.xml.meta new file mode 100644 index 0000000000..56ed899da8 --- /dev/null +++ b/trunk/docs/manual/faq/all_in_one.xml.meta @@ -0,0 +1,13 @@ + + + + all_in_one + /faq/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/faq/categories.xml b/trunk/docs/manual/faq/categories.xml new file mode 100644 index 0000000000..c4ce5856ee --- /dev/null +++ b/trunk/docs/manual/faq/categories.xml @@ -0,0 +1,23 @@ + + + + + + support.xml + error.xml + diff --git a/trunk/docs/manual/faq/categories.xml.ja b/trunk/docs/manual/faq/categories.xml.ja new file mode 100644 index 0000000000..7cc5d0928a --- /dev/null +++ b/trunk/docs/manual/faq/categories.xml.ja @@ -0,0 +1,23 @@ + + + + + + support.xml.ja + error.xml.ja + diff --git a/trunk/docs/manual/faq/categories.xml.ko b/trunk/docs/manual/faq/categories.xml.ko new file mode 100644 index 0000000000..67e664cf61 --- /dev/null +++ b/trunk/docs/manual/faq/categories.xml.ko @@ -0,0 +1,24 @@ + + + + + + + support.xml.ko + error.xml.ko + diff --git a/trunk/docs/manual/faq/error.html b/trunk/docs/manual/faq/error.html new file mode 100644 index 0000000000..7bbf1a051f --- /dev/null +++ b/trunk/docs/manual/faq/error.html @@ -0,0 +1,11 @@ +URI: error.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: error.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: error.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/faq/error.html.en b/trunk/docs/manual/faq/error.html.en new file mode 100644 index 0000000000..d0dae8ea14 --- /dev/null +++ b/trunk/docs/manual/faq/error.html.en @@ -0,0 +1,85 @@ + + + +Error Messages - Frequently Asked Questions - Apache HTTP Server + + + + + +
    <-
    +

    Error Messages - Frequently Asked Questions

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    Error Messages

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    Apache uses the sendfile syscall on platforms + where it is available in order to speed sending of responses. + Unfortunately, on some systems, Apache will detect the presence of + sendfile at compile-time, even when it does not work + properly. This happens most frequently when using network or + other non-standard file-system.

    + +

    Symptoms of this problem include the above message in the error + log and zero-length responses to non-zero-sized files. The + problem generally occurs only for static files, since dynamic + content usually does not make use of sendfile.

    + +

    To fix this problem, simply use the EnableSendfile directive to disable + sendfile for all or part of your server. Also see + the EnableMMAP, which can + help with similar problems.

    + + + +

    AcceptEx Failed

    + +

    If you get error messages related to the AcceptEx syscall + on win32, see the Win32DisableAcceptEx + directive.

    + + + +

    Premature end of script + headers

    + +

    Most problems with CGI scripts result in this message written in the + error log together with an Internal Server Error delivered + to the browser. A guide to helping debug this type of problem is + available in the CGI + tutorial.

    + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/error.html.ja.euc-jp b/trunk/docs/manual/faq/error.html.ja.euc-jp new file mode 100644 index 0000000000..52d25152ae --- /dev/null +++ b/trunk/docs/manual/faq/error.html.ja.euc-jp @@ -0,0 +1,91 @@ + + + +¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸ ¡½ ¤è¤¯¤¢¤ë¼ÁÌä - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸ ¡½ ¤è¤¯¤¢¤ë¼ÁÌä

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    (ÌõÃí: ̵¸ú¤Ê°ú¿ô: core_output_filter: ¥Í¥Ã¥È¥ï¡¼¥¯¤Ø¤Î¥Ç¡¼¥¿¤Î + ½ñ¤­¹þ¤ß)

    + +

    Apache ¤Ï±þÅú¤ÎÊÖÁ÷¤ò®¤¯¤¹¤ë¤¿¤á¤Ë¡¢sendfile ¥·¥¹¥Æ¥à + ¥³¡¼¥ë¤¬»ÈÍѲÄǽ¤Ê¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¤Ï¤½¤Î¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò»ÈÍѤ·¤Þ¤¹¡£ + ¤È¤³¤í¤¬¡¢ÅÔ¹ç¤Î°­¤¤¤³¤È¤Ë¡¢sendfile ¤¬Àµ¤·¤¯Æ°ºî¤·¤Ê¤¤¤Ë¤â + ´Ø¤ï¤é¤º¡¢Apache ¤¬¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¸ºß¤ò¸¡ÃΤ·¤Æ¤·¤Þ¤¦¥·¥¹¥Æ¥à¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥Í¥Ã¥È¥ï¡¼¥¯¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ä¾¤ÎÈóɸ½à¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò + »ÈÍѤ·¤Æ¤¤¤ë¤È¤­¤Ë°ìÈ֤褯ȯÀ¸¤·¤Þ¤¹¡£

    + +

    ¤³¤ÎÌäÂê¤Î¾É¾õ¤Ï¡¢¾åµ­¤Î¥á¥Ã¥»¡¼¥¸¤¬¥¨¥é¡¼¥í¥°¤Ë½ñ¤«¤ì¤ë¤³¤È¤È¡¢ + ¥µ¥¤¥º¤¬¥¼¥í¤Ç¤Ê¤¤¥Õ¥¡¥¤¥ë¤Î±þÅú¤¬¥¼¥í¤Ë¤Ê¤ë¤³¤È¤Ç¤¹¡£ + ưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤Ï sendfile ¤òÍøÍѤ·¤Ê¤¤¤¿¤á¡¢ + ¤³¤ÎÌäÂê¤ÏÄ̾ï¤ÏÀÅŪ¤Ê¥Õ¥¡¥¤¥ë¤Ç¤Î¤ßȯÀ¸¤·¤Þ¤¹¡£

    + +

    ¤³¤ÎÌäÂê¤Ï¡¢EnableSendfile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ + ¥µ¡¼¥Ð¤Î¤¹¤Ù¤Æ¡¢¤â¤·¤¯¤Ï°ìÉôʬ¤ËÂФ·¤Æ sendfile ¤ò + ̵¸ú¤Ë¤¹¤ë¤À¤±¤Ç½¤Àµ¤Ç¤­¤Þ¤¹¡£Æ±ÍͤÎÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Î + EnableMMAP ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤â + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + + +

    AcceptEx Failed

    + +

    (ÌõÃí: AcceptEx ¼ºÇÔ)

    + +

    Win32 ¤Ç¤Î AcceptEx ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Ë´Ø·¸¤¹¤ë¥¨¥é¡¼ + ¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤Ã¤¿¤È¤­¤Ï¡¢Win32DisableAcceptEx ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + + + +

    Premature end of script + headers

    + +

    (ÌõÃí: ¥¹¥¯¥ê¥×¥È¥Ø¥Ã¥À¤ÎÃæÅÓ½ªÎ»)

    + +

    CGI ¥¹¥¯¥ê¥×¥È¤Î¤Û¤È¤ó¤É¤ÎÌäÂê¤Ï¥¨¥é¡¼¥í¥°¤Ë¤³¤Î¥á¥Ã¥»¡¼¥¸¤¬½ñ¤«¤ì¡¢ + ¥Ö¥é¥¦¥¶¤Ë¤Ï Internal Server Error ¤¬Á÷¤é¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¼ï¤ÎÌäÂê¤Î¥Ç¥Ð¥Ã¥°ÊýË¡¤Ï CGI + ¥Á¥å¡¼¥È¥ê¥¢¥ë ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/error.html.ko.euc-kr b/trunk/docs/manual/faq/error.html.ko.euc-kr new file mode 100644 index 0000000000..302749d204 --- /dev/null +++ b/trunk/docs/manual/faq/error.html.ko.euc-kr @@ -0,0 +1,84 @@ + + + +¿À·ù¹® - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) - Apache HTTP Server + + + + + +
    <-
    +

    ¿À·ù¹® - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    ¿À·ù¹®

    + + +

    Invalid argument: + core_output_filter: writing data to the network

    + +

    Ç÷¡ÆûÀÌ sendfile ½Ã½ºÅÛÈ£ÃâÀ» Áö¿øÇÑ´Ù¸é, + ¾ÆÆÄÄ¡´Â ÀÀ´äÀÇ ¼Óµµ¸¦ ºü¸£°ÔÇϱâÀ§ÇØ ÀÌ ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù. + ºÒÇàÈ÷µµ ¾î¶² ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡´Â ÄÄÆÄÀÏÇÒ¶§ + sendfileÀÌ Á¤»óÀûÀ¸·Î ÀÛµ¿ÇÏÁö ¾Ê´Âµ¥µµ Á¤»óÀûÀ¸·Î + ÀÛµ¿ÇÑ´Ù°í ¿ÀÆÇÇÑ´Ù. ÀÌ ¹®Á¦´Â ³×Æ®¿÷ ÆÄÀϽýºÅÛÀ̳ª ºñÇ¥ÁØ + ÆÄÀϽýºÅÛÀ» »ç¿ëÇÒ¶§ ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    ÀÌ ¹®Á¦ÀÇ Áõ»óÀº ¿À·ù ·Î±×(error log)¿¡ À§ÀÇ ¹®±¸¸¦ + ±â·ÏÇϰųª Å©±â°¡ 0ÀÌ ¾Æ´Ñ ÆÄÀÏ¿¡ ´ëÇØ Å©±â°¡ 0ÀÎ ÀÀ´äÀ» + ÇÏ´Â °æ¿ìÀÌ´Ù. µ¿ÀûÀ¸·Î ³»¿ëÀ» »ý¼ºÇÒ¶§´Â + sendfileÀ» »ç¿ëÇÏÁö ¾Ê±â¶§¹®¿¡ ÀϹÝÀûÀ¸·Î Á¤ÀûÀÎ + ÆÄÀÏÀ» ¿äûÇÒ¶§¸¸ ¹®Á¦°¡ ¹ß»ýÇÑ´Ù.

    + +

    ¹®Á¦¸¦ ÇØ°áÇÏ·Á¸é ¼­¹ö°¡ sendfileÀ» »ç¿ëÇÏÁö + ¾Êµµ·Ï EnableSendfile + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ¶Ç, ÀÌ¿Í À¯»çÇÑ ¹®Á¦¿¡ ´ëÇØ EnableMMAPÀ» Âü°íÇ϶ó.

    + + + +

    AcceptEx Failed

    + +

    win32¿¡¼­ AcceptEx ½Ã½ºÅÛÈ£Ãâ¿¡ ´ëÇÑ ¿À·ù¹®À» + ³ª¿À¸é, Win32DisableAcceptEx + Áö½Ã¾î¸¦ Âü°íÇ϶ó.

    + + + +

    Premature end of script + headers

    + +

    º¸Åë CGI ½ºÅ©¸³Æ®¿¡ ¹®Á¦°¡ ÀÖÀ¸¸é ºê¶ó¿ìÀú¿¡°Ô Internal + Server Error¸¦ º¸³»°í ¿À·ù·Î±×¿¡ ÀÌ ¹®±¸¸¦ ±â·ÏÇÑ´Ù. + ÀÌ·± ¹®Á¦¸¦ µð¹ö±ëÇÒ¶§ CGI ÅõÅ丮¾óÀÌ + µµ¿òÀÌ µÉ ¼ö ÀÖ´Ù.

    + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/error.xml b/trunk/docs/manual/faq/error.xml new file mode 100644 index 0000000000..5eb0a20223 --- /dev/null +++ b/trunk/docs/manual/faq/error.xml @@ -0,0 +1,84 @@ + + + + + + + + +FAQ + +Error Messages - Frequently Asked Questions +What does this error message mean? + + + +
    Error Messages + + +
    Invalid argument: + core_output_filter: writing data to the network + +

    Apache uses the sendfile syscall on platforms + where it is available in order to speed sending of responses. + Unfortunately, on some systems, Apache will detect the presence of + sendfile at compile-time, even when it does not work + properly. This happens most frequently when using network or + other non-standard file-system.

    + +

    Symptoms of this problem include the above message in the error + log and zero-length responses to non-zero-sized files. The + problem generally occurs only for static files, since dynamic + content usually does not make use of sendfile.

    + +

    To fix this problem, simply use the EnableSendfile directive to disable + sendfile for all or part of your server. Also see + the EnableMMAP, which can + help with similar problems.

    + +
    + +
    AcceptEx Failed + +

    If you get error messages related to the AcceptEx syscall + on win32, see the Win32DisableAcceptEx + directive.

    +
    + + +
    Premature end of script + headers + +

    Most problems with CGI scripts result in this message written in the + error log together with an Internal Server Error delivered + to the browser. A guide to helping debug this type of problem is + available in the CGI + tutorial.

    +
    + +
    + +
    + diff --git a/trunk/docs/manual/faq/error.xml.ja b/trunk/docs/manual/faq/error.xml.ja new file mode 100644 index 0000000000..6c781a9e4c --- /dev/null +++ b/trunk/docs/manual/faq/error.xml.ja @@ -0,0 +1,89 @@ + + + + + + + + +FAQ + +$B%(%i!<%a%C%;!<%8(B $B!=(B $B$h$/$"$k<ALd(B +$B$3$N%(%i!<%a%C%;!<%8$N0UL#$O(B? + +
    $B%(%i!<%a%C%;!<%8(B + + +
    Invalid argument: + core_output_filter: writing data to the network + +

    ($BLuCm(B: $BL58z$J0z?t(B: core_output_filter: $B%M%C%H%o!<%/$X$N%G!<%?$N(B + $B=q$-9~$_(B)

    + +

    Apache $B$O1~Ez$NJVAw$rB.$/$9$k$?$a$K!"(Bsendfile $B%7%9%F%`(B + $B%3!<%k$,;HMQ2DG=$J%W%i%C%H%U%)!<%`$G$O$=$N%7%9%F%`%3!<%k$r;HMQ$7$^$9!#(B + $B$H$3$m$,!"ET9g$N0-$$$3$H$K!"(Bsendfile $B$,@5$7$/F0:n$7$J$$$K$b(B + $B4X$o$i$:!"(BApache $B$,%3%s%Q%$%k;~$KB8:_$r8!CN$7$F$7$^$&%7%9%F%`$,$"$j$^$9!#(B + $B$3$l$O!"%M%C%H%o!<%/%U%!%$%k%7%9%F%`$dB>$NHsI8=`$N%U%!%$%k%7%9%F%`$r(B + $B;HMQ$7$F$$$k$H$-$K0lHV$h$/H/@8$7$^$9!#(B

    + +

    $B$3$NLdBj$N>I>u$O!">e5-$N%a%C%;!<%8$,%(%i!<%m%0$K=q$+$l$k$3$H$H!"(B + $B%5%$%:$,%<%m$G$J$$%U%!%$%k$N1~Ez$,%<%m$K$J$k$3$H$G$9!#(B + $BF0E*$J%3%s%F%s%D$O(B sendfile $B$rMxMQ$7$J$$$?$a!"(B + $B$3$NLdBj$ODL>o$O@EE*$J%U%!%$%k$G$N$_H/@8$7$^$9!#(B

    + +

    $B$3$NLdBj$O!"(BEnableSendfile $B%G%#%l%/%F%#%V$r;HMQ$7$F!"(B + $B%5!<%P$N$9$Y$F!"$b$7$/$O0lItJ,$KBP$7$F(B sendfile $B$r(B + $BL58z$K$9$k$@$1$G=$@5$G$-$^$9!#F1MM$NLdBj$r2r7h$9$k$?$a$N(B + EnableMMAP $B%G%#%l%/%F%#%V$b(B + $B;2>H$7$F$/$@$5$$!#(B

    + +
    + +
    AcceptEx Failed + +

    ($BLuCm(B: AcceptEx $B<:GT(B)

    + +

    Win32 $B$G$N(B AcceptEx $B%7%9%F%`%3!<%k$K4X78$9$k%(%i!<(B + $B%a%C%;!<%8$rWin32DisableAcceptEx $B$r;2>H$7$F$/$@$5$$!#(B

    +
    + + +
    Premature end of script + headers + +

    ($BLuCm(B: $B%9%/%j%W%H%X%C%@$NCfES=*N;(B)

    + +

    CGI $B%9%/%j%W%H$N$[$H$s$I$NLdBj$O%(%i!<%m%0$K$3$N%a%C%;!<%8$,=q$+$l!"(B + $B%V%i%&%6$K$O(B Internal Server Error $B$,Aw$i$l$k$3$H$K$J$j$^$9!#(B + $B$3$NCGI + $B%A%e!<%H%j%"%k(B $B$G@bL@$5$l$F$$$^$9!#(B

    +
    + +
    + +
    + diff --git a/trunk/docs/manual/faq/error.xml.ko b/trunk/docs/manual/faq/error.xml.ko new file mode 100644 index 0000000000..0906e84bdf --- /dev/null +++ b/trunk/docs/manual/faq/error.xml.ko @@ -0,0 +1,84 @@ + + + + + + + + +FAQ + +¿À·ù¹® - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) +ÀÌ ¿À·ù¹®ÀÌ ¹«½¼ ¶æÀΰ¡? + + + +
    ¿À·ù¹® + + +
    Invalid argument: + core_output_filter: writing data to the network + +

    Ç÷¡ÆûÀÌ sendfile ½Ã½ºÅÛÈ£ÃâÀ» Áö¿øÇÑ´Ù¸é, + ¾ÆÆÄÄ¡´Â ÀÀ´äÀÇ ¼Óµµ¸¦ ºü¸£°ÔÇϱâÀ§ÇØ ÀÌ ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù. + ºÒÇàÈ÷µµ ¾î¶² ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡´Â ÄÄÆÄÀÏÇÒ¶§ + sendfileÀÌ Á¤»óÀûÀ¸·Î ÀÛµ¿ÇÏÁö ¾Ê´Âµ¥µµ Á¤»óÀûÀ¸·Î + ÀÛµ¿ÇÑ´Ù°í ¿ÀÆÇÇÑ´Ù. ÀÌ ¹®Á¦´Â ³×Æ®¿÷ ÆÄÀϽýºÅÛÀ̳ª ºñÇ¥ÁØ + ÆÄÀϽýºÅÛÀ» »ç¿ëÇÒ¶§ ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    ÀÌ ¹®Á¦ÀÇ Áõ»óÀº ¿À·ù ·Î±×(error log)¿¡ À§ÀÇ ¹®±¸¸¦ + ±â·ÏÇϰųª Å©±â°¡ 0ÀÌ ¾Æ´Ñ ÆÄÀÏ¿¡ ´ëÇØ Å©±â°¡ 0ÀÎ ÀÀ´äÀ» + ÇÏ´Â °æ¿ìÀÌ´Ù. µ¿ÀûÀ¸·Î ³»¿ëÀ» »ý¼ºÇÒ¶§´Â + sendfileÀ» »ç¿ëÇÏÁö ¾Ê±â¶§¹®¿¡ ÀϹÝÀûÀ¸·Î Á¤ÀûÀÎ + ÆÄÀÏÀ» ¿äûÇÒ¶§¸¸ ¹®Á¦°¡ ¹ß»ýÇÑ´Ù.

    + +

    ¹®Á¦¸¦ ÇØ°áÇÏ·Á¸é ¼­¹ö°¡ sendfileÀ» »ç¿ëÇÏÁö + ¾Êµµ·Ï EnableSendfile + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ¶Ç, ÀÌ¿Í À¯»çÇÑ ¹®Á¦¿¡ ´ëÇØ EnableMMAPÀ» Âü°íÇ϶ó.

    + +
    + +
    AcceptEx Failed + +

    win32¿¡¼­ AcceptEx ½Ã½ºÅÛÈ£Ãâ¿¡ ´ëÇÑ ¿À·ù¹®À» + ³ª¿À¸é, Win32DisableAcceptEx + Áö½Ã¾î¸¦ Âü°íÇ϶ó.

    +
    + + +
    Premature end of script + headers + +

    º¸Åë CGI ½ºÅ©¸³Æ®¿¡ ¹®Á¦°¡ ÀÖÀ¸¸é ºê¶ó¿ìÀú¿¡°Ô Internal + Server Error¸¦ º¸³»°í ¿À·ù·Î±×¿¡ ÀÌ ¹®±¸¸¦ ±â·ÏÇÑ´Ù. + ÀÌ·± ¹®Á¦¸¦ µð¹ö±ëÇÒ¶§ CGI ÅõÅ丮¾óÀÌ + µµ¿òÀÌ µÉ ¼ö ÀÖ´Ù.

    +
    + +
    + +
    + diff --git a/trunk/docs/manual/faq/error.xml.meta b/trunk/docs/manual/faq/error.xml.meta new file mode 100644 index 0000000000..d202df6763 --- /dev/null +++ b/trunk/docs/manual/faq/error.xml.meta @@ -0,0 +1,13 @@ + + + + error + /faq/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/faq/index.html b/trunk/docs/manual/faq/index.html new file mode 100644 index 0000000000..9ee330865b --- /dev/null +++ b/trunk/docs/manual/faq/index.html @@ -0,0 +1,11 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/faq/index.html.en b/trunk/docs/manual/faq/index.html.en new file mode 100644 index 0000000000..6a583dae92 --- /dev/null +++ b/trunk/docs/manual/faq/index.html.en @@ -0,0 +1,49 @@ + + + +Frequently Asked Questions - Apache HTTP Server + + + + + +
    <-
    +

    Frequently Asked Questions

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    The latest version of this FAQ is always available from the + main Apache web site, at <http://httpd.apache.org/docs-2.1/faq/>. In addition, you can view + this FAQ all in one page for easy searching + and printing.

    + +

    Since Apache 2.0 is quite new, we don't yet know what the + Frequently Asked Questions will be. While this section fills up, + you should also consult the Apache 1.3 FAQ to see + if your question is answered there.

    +
    +
    top
    +
    +

    Topics

    +
    Support
    What do I do when I have problems?
    +
    Error Messages
    What does this error message mean?
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/index.html.ja.euc-jp b/trunk/docs/manual/faq/index.html.ja.euc-jp new file mode 100644 index 0000000000..bdccf74a78 --- /dev/null +++ b/trunk/docs/manual/faq/index.html.ja.euc-jp @@ -0,0 +1,49 @@ + + + +¤è¤¯¤¢¤ë¼ÁÌä - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¤è¤¯¤¢¤ë¼ÁÌä

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Apache ¤Î¼ç¥µ¥¤¥È¡¢<http://httpd.apache.org/docs-2.1/faq/> + ¤«¤éºÇ¿·ÈǤΠFAQ ¤ò¾ï¤Ë¼ê¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Þ¤¿¡¢´Êñ¤Ê¸¡º÷¤ä°õºþ¤Î¤¿¤á¤Ë¤³¤Î FAQ ¤Î + °ì¥Ú¡¼¥¸ÈǤ⤢¤ê¤Þ¤¹¡£

    + +

    Apache 2.0 ¤Ï¤Þ¤À¿·¤·¤¤¤Î¤Ç¡¢²¿¤¬¤è¤¯¤¢¤ë¼ÁÌä¤Ê¤Î¤« + ¤Þ¤À¤è¤¯¤ï¤«¤Ã¤Æ¤¤¤Þ¤»¤ó¡£¤³¤Î¥»¥¯¥·¥ç¥ó¤¬Ëä¤Þ¤Ã¤Æ¤¤¤¯¤Þ¤Ç¡¢ + ´û¤Ë¼ÁÌ䤬Åú¤¨¤é¤ì¤Æ¤¤¤ë¤«¤É¤¦¤« Apache 1.3 ¤Î FAQ + ¤â¸«¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    top
    +
    +

    ¥È¥Ô¥Ã¥¯

    +
    ¥µ¥Ý¡¼¥È
    ²¿¤«ÌäÂ꤬µ¯¤³¤Ã¤¿¤È¤­¤Ë¤É¤¦¤¹¤ë?
    +
    ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
    ¤³¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Î°ÕÌ£¤Ï?
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/index.html.ko.euc-kr b/trunk/docs/manual/faq/index.html.ko.euc-kr new file mode 100644 index 0000000000..66ed4b2c94 --- /dev/null +++ b/trunk/docs/manual/faq/index.html.ko.euc-kr @@ -0,0 +1,47 @@ + + + +ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) - Apache HTTP Server + + + + + +
    <-
    +

    ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    FAQ ÃÖ½ÅÆÇÀº ¾ÆÆÄÄ¡ À¥»çÀÌÆ® <http://httpd.apache.org/docs-2.1/faq/>¿¡¼­ º¼ ¼ö + ÀÖ´Ù. ¶Ç, °Ë»öÇÏ°í Ãâ·ÂÇϱâ ÆíÇÏ°Ô FAQ¸¦ ÇÑ ÆäÀÌÁö·Î º¼ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÌ ³ª¿ÂÁö ¾ó¸¶ ¾ÈµÇ¼­ ¿ì¸®´Â ¾ÆÁ÷ ÀÚÁÖ + ¹°¾îº¸´Â Áú¹® (FAQ)ÀÌ ¹«¾ùÀÎÁö ¸ð¸¥´Ù. ³»¿ëÀÌ Ã¤¿öÁú + ¶§±îÁö ¿©±â¿¡ ÇØ´äÀÌ ¾ø´Ù¸é ¾ÆÆÄÄ¡ + 1.3 FAQµµ Âü°íÇ϶ó.

    +
    +
    top
    +
    +

    ÁÖÁ¦

    +
    Áö¿ø
    ¹®Á¦°¡ »ý±â¸é ¾î¶»°Ô ÇØ°áÇϳª?
    +
    ¿À·ù¹®
    ÀÌ ¿À·ù¹®ÀÌ ¹«½¼ ¶æÀΰ¡?
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/index.xml b/trunk/docs/manual/faq/index.xml new file mode 100644 index 0000000000..e0fc20a6e6 --- /dev/null +++ b/trunk/docs/manual/faq/index.xml @@ -0,0 +1,47 @@ + + +]> + + + + + + + + +Frequently Asked Questions + + +

    The latest version of this FAQ is always available from the + main Apache web site, at <http://httpd.apache.org/docs-2.1/faq/>. In addition, you can view + this FAQ all in one page for easy searching + and printing.

    + +

    Since Apache 2.0 is quite new, we don't yet know what the + Frequently Asked Questions will be. While this section fills up, + you should also consult the Apache 1.3 FAQ to see + if your question is answered there.

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/index.xml.ja b/trunk/docs/manual/faq/index.xml.ja new file mode 100644 index 0000000000..c270fa6df9 --- /dev/null +++ b/trunk/docs/manual/faq/index.xml.ja @@ -0,0 +1,48 @@ + + +]> + + + + + + + + +$B$h$/$"$k<ALd(B + + +

    Apache $B$Nhttp://httpd.apache.org/docs-2.1/faq/> + $B$+$i:G?7HG$N(B FAQ $B$r>o$K$B0l%Z!<%8HG(B$B$b$"$j$^$9!#(B

    + +

    Apache 2.0 $B$O$^$@?7$7$$$N$G!"2?$,(B$B$h$/$"$k$B$J$N$+(B + $B$^$@$h$/$o$+$C$F$$$^$;$s!#$3$N%;%/%7%g%s$,Kd$^$C$F$$$/$^$G!"(B + $B4{$KApache 1.3 $B$N(B FAQ + $B$b8+$k$h$&$K$7$F$/$@$5$$!#(B

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/index.xml.ko b/trunk/docs/manual/faq/index.xml.ko new file mode 100644 index 0000000000..cdeff3fed4 --- /dev/null +++ b/trunk/docs/manual/faq/index.xml.ko @@ -0,0 +1,47 @@ + + +]> + + + + + + + + +ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) + + +

    FAQ ÃÖ½ÅÆÇÀº ¾ÆÆÄÄ¡ À¥»çÀÌÆ® <http://httpd.apache.org/docs-2.1/faq/>¿¡¼­ º¼ ¼ö + ÀÖ´Ù. ¶Ç, °Ë»öÇÏ°í Ãâ·ÂÇϱâ ÆíÇÏ°Ô FAQ¸¦ ÇÑ ÆäÀÌÁö·Î º¼ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÌ ³ª¿ÂÁö ¾ó¸¶ ¾ÈµÇ¼­ ¿ì¸®´Â ¾ÆÁ÷ ÀÚÁÖ + ¹°¾îº¸´Â Áú¹® (FAQ)ÀÌ ¹«¾ùÀÎÁö ¸ð¸¥´Ù. ³»¿ëÀÌ Ã¤¿öÁú + ¶§±îÁö ¿©±â¿¡ ÇØ´äÀÌ ¾ø´Ù¸é ¾ÆÆÄÄ¡ + 1.3 FAQµµ Âü°íÇ϶ó.

    +
    + +&categories; + +
    + diff --git a/trunk/docs/manual/faq/index.xml.meta b/trunk/docs/manual/faq/index.xml.meta new file mode 100644 index 0000000000..a3a99d706c --- /dev/null +++ b/trunk/docs/manual/faq/index.xml.meta @@ -0,0 +1,13 @@ + + + + index + /faq/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/faq/support.html b/trunk/docs/manual/faq/support.html new file mode 100644 index 0000000000..2af73a38ac --- /dev/null +++ b/trunk/docs/manual/faq/support.html @@ -0,0 +1,11 @@ +URI: support.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: support.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: support.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/faq/support.html.en b/trunk/docs/manual/faq/support.html.en new file mode 100644 index 0000000000..b4ca2df03d --- /dev/null +++ b/trunk/docs/manual/faq/support.html.en @@ -0,0 +1,134 @@ + + + +Support - Frequently Asked Questions - Apache HTTP Server + + + + + +
    <-
    +

    Support - Frequently Asked Questions

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    Support

    + + +

    "Why can't I ...? Why won't ... work?" What to do in case of + problems

    + + +

    If you are having trouble with your Apache server software, you should + take the following steps:

    + +
    +
    Check the errorlog!
    +
    Apache tries to be helpful when it encounters a problem. In many + cases, it will provide some details by writing one or more messages to the + server error log. Sometimes this is enough for you to diagnose & fix + the problem yourself (such as file permissions or the like). The default + location of the error log is + /usr/local/apache2/logs/error_log, but see the ErrorLog directive in your config files for the + location on your server.
    + +
    Check the FAQ!
    +
    The latest version of the Apache Frequently-Asked Questions list can + always be found at the main Apache web site.
    + +
    Check the Apache bug database
    +
    Most problems that get reported to The Apache Group are recorded in + the bug database. + Please check the existing reports, open + and closed, before adding one. If you find that your + issue has already been reported, please don't add a "me, too" + report. If the original report isn't closed yet, we suggest that you + check it periodically. You might also consider contacting the original + submitter, because there may be an email exchange going on about the + issue that isn't getting recorded in the database.
    + +
    Ask in a user support forum
    +

    Apache has an active community of users who are willing to share + their knowledge. Participating in this community is usually the best and + fastest way to get answers to your questions and problems.

    + +

    Users + mailing list

    + +

    USENET newsgroups:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    If all else fails, report the problem in the bug database
    +

    If you've gone through those steps above that are appropriate and + have obtained no relief, then please do let the httpd developers + know about the problem by logging a bug + report.

    + +

    If your problem involves the server crashing and generating a core + dump, please include a backtrace (if possible). As an example,

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (Substitute the appropriate locations for your ServerRoot + and your httpd and core files. You may have to use + gdb instead of dbx.)

    +
    +
    + + +

    Whom do I contact for support?

    +

    With several million users and fewer than forty volunteer developers, + we cannot provide personal support for Apache. For free support, we + suggest participating in a user forum.

    + +

    Professional, commercial support for Apache is available from + a number of + companies.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/support.html.ja.euc-jp b/trunk/docs/manual/faq/support.html.ja.euc-jp new file mode 100644 index 0000000000..47408e91ad --- /dev/null +++ b/trunk/docs/manual/faq/support.html.ja.euc-jp @@ -0,0 +1,132 @@ + + + +¥µ¥Ý¡¼¥È ¡½ ¤è¤¯¤¢¤ë¼ÁÌä - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥µ¥Ý¡¼¥È ¡½ ¤è¤¯¤¢¤ë¼ÁÌä

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    ¥µ¥Ý¡¼¥È

    + + +

    ¡Ö¤Ê¤ó¤Ç¡Ä? ¤É¤¦¤·¤ÆÆ°ºî¤·¤Ê¤¤¡Ä?¡×ÌäÂ꤬ + µ¯¤­¤¿¤È¤­¤Ë¤É¤¦¤¹¤ë¤«

    + + +

    Apache ¤Î¥µ¡¼¥Ð¥½¥Õ¥È¥¦¥§¥¢¤Ë²¿¤«ÌäÂ꤬µ¯¤³¤Ã¤¿¤È¤­¤Ï¡¢°Ê²¼¤Î + ¼ê½ç¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤:

    + +
    +
    ¥¨¥é¡¼¥í¥°¤òÄ´¤Ù¤ë!
    +
    ÌäÂ꤬ȯÀ¸¤·¤¿¤È¤­¤Ï Apache ¤Ï¤Ê¤ë¤Ù¤¯¼ê½õ¤±¤ò¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + ¿¤¯¤Î¾ì¹ç¡¢Apache ¤Ï¥µ¡¼¥Ð¤Î¥¨¥é¡¼¥í¥°¤Ë¥á¥Ã¥»¡¼¥¸¤ò½ñ¤¯¤³¤È¤Ç¡¢¾ÜºÙ¤Ê + ¾ðÊó¤òÄ󶡤·¤Þ¤¹¡£¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢¤³¤ì¤À¤±¤ÇÌäÂê¤ò¼«Ê¬¼«¿È¤ÇʬÀϤ·¡¢ + ½¤Àµ¤¹¤ë¤¿¤á¤Ë½½Ê¬¤Ê¾ðÊó¤òÆÀ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹ (¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤Î + ÌäÂê¤Ê¤É)¡£¥¨¥é¡¼¥í¥°¤Î¥Ç¥Õ¥©¥ë¥È¤Î¾ì½ê¤Ï + /usr/local/apache2/logs/error_log ¤Ç¤¹¤¬¡¢¤¢¤Ê¤¿¤Î¥µ¡¼¥Ð + ¤Ç¤Î¾ì½ê¤òÃΤ뤿¤á¤Ë¤ÏÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î ErrorLog ¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
    + +
    FAQ ¤òÄ´¤Ù¤ë!
    +
    Apache ¤Î¤è¤¯¤¢¤ë¼ÁÌä¤ÎºÇ¿·ÈǤϾï¤Ë Apache ¤Î¼ç¥¦¥§¥Ö¥µ¥¤¥È¤Ë + ¤¢¤ê¤Þ¤¹¡£
    + +
    Apache ¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄ´¤Ù¤ë
    +
    Apache ¥°¥ë¡¼¥×¤ËÊó¹ð¤µ¤ì¤ë¤Û¤È¤ó¤É¤ÎÌäÂê¤Ï¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë + µ­Ï¿¤µ¤ì¤Þ¤¹¡£Open ¤â closed ¤â ´Þ¤á¤Æ¡¢ + ´û¸¤Î¥ì¥Ý¡¼¥È¤Ë¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£ + ´û¤ËÌäÂ꤬Êó¹ð¤µ¤ì¤Æ¤¤¤ë¤È¤­¡¢¡Ö»ä¤â¡×¤È¤¤¤¦Êó¹ð¤ÏÄɲ䷤ʤ¤¤Ç + ¤¯¤À¤µ¤¤¡£¸µ¤ÎÊó¹ð¤¬ close ¤µ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢Äê´üŪ¤Ë + ¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄ´¤Ù¤ë¤³¤È¤ò¤ªÁ¦¤á¤·¤Þ¤¹¡£¤Þ¤¿¡¢¸µ¤ÎÄó½Ð¼Ô¤Ë + Ï¢Íí¤ò¼è¤ë¤³¤È¤â¹Íθ¤ËÆþ¤ì¤Æ¤ª¤¯¤È¤è¤¤¤Ç¤·¤ç¤¦¡£¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë + µ­Ï¿¤µ¤ì¤Æ¤¤¤Ê¤¤ÅŻҥ᡼¥ë¤Î¸ò´¹¤¬¹Ô¤Ê¤ï¤ì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    + +
    ¥æ¡¼¥¶¥µ¥Ý¡¼¥È¥Õ¥©¡¼¥é¥à¤Ç¼ÁÌ䤹¤ë
    +

    Apache ¤Ë¤Ï¤è¤í¤³¤ó¤ÇÃ챤ò¶¦Í­¤µ¤»¤Æ¤¯¤ì¤ë³èȯ¤Ê + ¥æ¡¼¥¶¤Î¥³¥ß¥å¥Ë¥Æ¥£¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥³¥ß¥å¥Ë¥Æ¥£¤Ë»²²Ã¤¹¤ë¤³¤È¤¬¡¢ + ÉáÄ̤ϼÁÌä¤äÌäÂê¤ËÂФ¹¤ë²óÅú¤òÆÀ¤ëºÇÁ±¤ÇºÇ®¤Î¼êÃʤǤ¹¡£

    + +

    ¥æ¡¼¥¶ + ¥á¡¼¥ê¥ó¥°¥ê¥¹¥È

    + +

    USENET ¥Ë¥å¡¼¥¹¥°¥ë¡¼¥×:

    + +
    + +
    ¤â¤·¡¢Á´Éô¼ºÇÔ¤·¤¿¾ì¹ç¤Ï¡¢ÌäÂê¤ò¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤
    +

    ¾åµ­¤Î¼êÃʤÎÃæ¤Ç³ºÅö¤¹¤ë¤â¤Î¤ò¤ò¤¹¤Ù¤Æ¼è¤Ã¤Æ¡¢ + ¤½¤ì¤Ç¤âÌäÂê¤Î²ò·èºö¤òÆÀ¤é¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¥Ð¥°¤ÎÊó¹ð¤ò + ¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ÌäÂê¤ò¤¼¤Ò httpd ³«È¯¼Ô¤ËÃΤ餻¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥µ¡¼¥Ð¤Î¥¯¥é¥Ã¥·¥å¤ä¥³¥¢¥À¥ó¥×¤ÎȯÀ¸¤¹¤ëÌäÂê¤Ç¤¢¤ì¤Ð¡¢(²Äǽ¤Ç¤¢¤ì¤Ð) + ¥Ð¥Ã¥¯¥È¥ì¡¼¥¹¤òÊó¹ð¤Ë´Þ¤á¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¡¢

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (ServerRoot ¤È httpd ¤È core ¥Õ¥¡¥¤¥ë + ¤Î°ÌÃÖ¤òŬÀڤʤâ¤Î¤ËÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£dbx ¤ÎÂå¤ï¤ê¤Ë + gdb ¤ò»È¤¦É¬Íפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£)

    +
    +
    + + +

    ï¤Ë¥µ¥Ý¡¼¥È¤òÍê¤á¤Ð¤è¤¤?

    +

    ¿ôÉ´Ëü¤Î¥æ¡¼¥¶¤ËÂФ·¤Æ¡¢40̤Ëþ¤Î¥Ü¥é¥ó¥Æ¥£¥¢³«È¯¼Ô¤·¤«¤¤¤Ê¤¤¤¿¤á¡¢ + Apache ¤Î¸Ä¿ÍŪ¤Ê¥µ¥Ý¡¼¥È¤òÄ󶡤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ÌµÎÁ¤Î + ¥µ¥Ý¡¼¥È¤Ë¤Ï¡¢¥æ¡¼¥¶¤Î¥Õ¥©¡¼¥é¥à¤Ë»²²Ã¤¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    Apache ¤Î¥×¥í¤Î¡¢¾¦ÍÑ¥µ¥Ý¡¼¥È¤â + ¿¤¯¤Î²ñ¼Ò + ¤«¤éÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/support.html.ko.euc-kr b/trunk/docs/manual/faq/support.html.ko.euc-kr new file mode 100644 index 0000000000..5793fda8dd --- /dev/null +++ b/trunk/docs/manual/faq/support.html.ko.euc-kr @@ -0,0 +1,140 @@ + + + +Áö¿ø - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) - Apache HTTP Server + + + + + +
    <-
    +

    Áö¿ø - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    Áö¿ø

    + + +

    "¿Ö ... ¾ÈµÇ³ª? ¿Ö ... µ¿ÀÛÇÏÁö ¾Ê´Â°¡?" ¹®Á¦°¡ »ý±â¸é + ÇÒÀÏ

    + + +

    ¾ÆÆÄÄ¡ ¼­¹ö ¼ÒÇÁÆ®¿þ¾î¿¡ ¹®Á¦°¡ »ý±â¸é ´ÙÀ½°ú °°Àº + ´Ü°è¸¦ µû¸¥´Ù:

    + +
    +
    ¿À·ù ·Î±×(errorlog)¸¦ È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ ¼­¹ö´Â ¹®Á¦°¡ »ý±â¸é µµ¿òÀ» ÁÖ·Á°í ³ë·ÂÇÑ´Ù. + ¸¹Àº °æ¿ì ¼­¹ö ¿À·ù ·Î±×¿¡ ÀÚ¼¼ÇÑ ³»¿ëÀ» ±â·ÏÇÑ´Ù. + À̰͸¸À¸·Îµµ Á÷Á¢ (ÆÄÀϱÇÇÑ µî) ¹®Á¦¸¦ ¹ß°ßÇÏ°í °íÄ¥ ¼ö + ÀÖ´Â °æ¿ì°¡ ¸¹´Ù. ¿À·ù ·Î±×ÀÇ ±âº» À§Ä¡´Â + /usr/local/apache2/logs/error_logÀÌÁö¸¸, + Á¤È®ÇÑ À§Ä¡´Â ¼³Á¤ÆÄÀÏÀÇ ErrorLog Áö½Ã¾î¸¦ Âü°íÇ϶ó.
    + +
    FAQ¸¦ + È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ À¥»çÀÌÆ®¿¡¼­ Ç×»ó ¾ÆÆÄÄ¡ FAQ ÃÖ½ÅÆÇÀ» º¼ ¼ö + ÀÖ´Ù.
    + +
    ¾ÆÆÄÄ¡ ¹ö±× µ¥ÀÌÅͺ£À̽º¸¦ È®ÀÎÇ϶ó
    +
    ¾ÆÆÄÄ¡±×·ì(The Apache Group)¿¡ º¸°íµÈ ´ëºÎºÐÀÇ ¹®Á¦´Â + ¹ö±× + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÈ´Ù. »õ·Î ¹ö±×¸¦ Ãß°¡Çϱâ Àü¿¡, + ÀÌ¹Ì ¾Ë·ÁÁ³°Å³ª(open) ÇØ°áµÈ(closed) ¹ö±×°¡ ÀÖ´ÂÁö È®ÀÎÇϱæ + ¹Ù¶õ´Ù. ÀÌ¹Ì ¹®Á¦°¡ º¸°íµÇ¾ú´Ù¸é "³ªµµ + ÀÌ·± ¹®Á¦°¡ ÀÖ´Ù°í" º¸°íÇÏÁö ¾Ê±æ ¹Ù¶õ´Ù. ¾ÆÁ÷ + ÇØ°áµÇÁö ¾Ê¾Ò´Ù¸é ÁÖ±âÀûÀ¸·Î »óȲÀ» È®ÀÎÇÏ±æ ¹Ù¶õ´Ù. ¶Ç, + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÇÁö ¾Ê°í À̸ÞÀÏ ±³È¯À¸·Î ÁøÇàµÈ »çÇ×ÀÌ + ÀÖÀ» ¼ö ÀÖÀ¸´Ï óÀ½ ¹®Á¦¸¦ º¸°íÇÑ »ç¶÷¿¡°Ô ¿¬¶ôÇغ¼ ¼öµµ + ÀÖ´Ù.
    + +
    »ç¿ëÀÚ Áö¿ø °ø°£¿¡ + ¹®ÀÇÇÑ´Ù
    +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Áö½ÄÀ» °øÀ¯ÇÏ±æ ¿øÇÏ´Â È°¹ßÇÑ »ç¿ëÀÚ + °øµ¿Ã¼µéÀÌ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î ÀÌ·± °øµ¿Ã¼¿¡ Âü¿©ÇÏ´Â °ÍÀÌ + ¹®Á¦ÀÇ ´äÀ» ¾ò´Â °¡Àå ÁÁ°í ºü¸¥ ¹æ¹ýÀÌ´Ù.

    + +

    »ç¿ëÀÚ + ¸ÞÀϸµ¸®½ºÆ®

    + +

    USENET ´º½º±×·ì:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    À§ÀÇ ¹æ¹ýÀÌ ¸ðµÎ ½ÇÆÐÇÏ¸é ¹ö±× µ¥ÀÌÅͺ£À̽º¿¡ ¹®Á¦¸¦ + º¸°íÇÑ´Ù
    +

    À§ÀÇ ´Ü°è¸¦ ¸ðµÎ ½ÃµµÇÏ°íµµ ÇØ°áÃ¥ÀÌ ¾ø´Ù¸é, ¹ö±×¸¦ + º¸°íÇÏ¿© À¥¼­¹ö °³¹ßÀڵ鿡°Ô ¹®Á¦¸¦ ¾Ë¸®±æ + ¹Ù¶õ´Ù.

    + +

    core dump¸¦ ¸¸µé¸ç ¼­¹ö°¡ Á×´Â °æ¿ì¶ó¸é (°¡´ÉÇϸé) + backtrace(¿ªÁÖ; ¹®Á¦°¡ ½ÇÇàÆÄÀÏÀÇ Á¤È®È÷ ¾î¶² ÁöÁ¡¿¡¼­ + ¹ß»ýÇÏ¿´°í, ÇÁ·Î±×·¥ÀÌ ±× ÁöÁ¡±îÁö ¾î¶² °æ·Î·Î ½ÇÇàµÇ¾ú´ÂÁö¸¦ + ¾Ë·ÁÁÖ´Â Á¤º¸)¸¦ Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù. ¿¹¸¦ µé¾î,

    + +

    + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +

    + +

    (ServerRoot, httpd, core + ÆÄÀÏÀÇ ½ÇÁ¦ À§Ä¡¸¦ ´ë½Å »ç¿ëÇ϶ó. dbx ´ë½Å + gdb¸¦ »ç¿ëÇØ¾ß ÇÒ ¼öµµ ÀÖ´Ù.)

    +
    +
    + + +

    µµ¿òÀ» ¾òÀ¸·Á¸é ´©±¸¿¡°Ô + ¿¬¶ôÇϳª?

    +

    40¸í °¡·®ÀÇ ÀÚ¹ßÀûÀ¸·Î Âü¿©ÇÑ °³¹ßÀÚ¸¸À¸·Î´Â ¼ö¹é¸¸ÀÇ + »ç¿ëÀÚ¿¡°Ô ¾ÆÆÄÄ¡¿¡ ´ëÇØ ÀÏÀÏÀÌ Áö¿øÇÒ ¼ö ¾ø´Ù. ¹«·á Áö¿øÀ» + ¾òÀ¸·Á¸é »ç¿ëÀÚ + °ø°£¿¡ Âü¿©ÇÏ±æ ±ÇÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Á÷¾÷ÀûÀÎ À¯·á Áö¿øÀº ¿©·¯ + ȸ»ç¿¡¼­ Á¦°øÇÑ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/faq/support.xml b/trunk/docs/manual/faq/support.xml new file mode 100644 index 0000000000..42f58f635b --- /dev/null +++ b/trunk/docs/manual/faq/support.xml @@ -0,0 +1,135 @@ + + + + + + + + +FAQ + +Support - Frequently Asked Questions +What do I do when I have problems? + +
    Support + + +
    + "Why can't I ...? Why won't ... work?" What to do in case of + problems + +

    If you are having trouble with your Apache server software, you should + take the following steps:

    + +
    +
    Check the errorlog!
    +
    Apache tries to be helpful when it encounters a problem. In many + cases, it will provide some details by writing one or more messages to the + server error log. Sometimes this is enough for you to diagnose & fix + the problem yourself (such as file permissions or the like). The default + location of the error log is + /usr/local/apache2/logs/error_log, but see the ErrorLog directive in your config files for the + location on your server.
    + +
    Check the FAQ!
    +
    The latest version of the Apache Frequently-Asked Questions list can + always be found at the main Apache web site.
    + +
    Check the Apache bug database
    +
    Most problems that get reported to The Apache Group are recorded in + the bug database. + Please check the existing reports, open + and closed, before adding one. If you find that your + issue has already been reported, please don't add a "me, too" + report. If the original report isn't closed yet, we suggest that you + check it periodically. You might also consider contacting the original + submitter, because there may be an email exchange going on about the + issue that isn't getting recorded in the database.
    + +
    Ask in a user support forum
    +

    Apache has an active community of users who are willing to share + their knowledge. Participating in this community is usually the best and + fastest way to get answers to your questions and problems.

    + +

    Users + mailing list

    + +

    USENET newsgroups:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    If all else fails, report the problem in the bug database
    +

    If you've gone through those steps above that are appropriate and + have obtained no relief, then please do let the httpd developers + know about the problem by logging a bug + report.

    + +

    If your problem involves the server crashing and generating a core + dump, please include a backtrace (if possible). As an example,

    + + + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +
    + +

    (Substitute the appropriate locations for your ServerRoot + and your httpd and core files. You may have to use + gdb instead of dbx.)

    +
    +
    +
    + +
    Whom do I contact for support? +

    With several million users and fewer than forty volunteer developers, + we cannot provide personal support for Apache. For free support, we + suggest participating in a user forum.

    + +

    Professional, commercial support for Apache is available from + a number of + companies.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/faq/support.xml.ja b/trunk/docs/manual/faq/support.xml.ja new file mode 100644 index 0000000000..3b4da96493 --- /dev/null +++ b/trunk/docs/manual/faq/support.xml.ja @@ -0,0 +1,134 @@ + + + + + + + + +FAQ + +$B%5%]!<%H(B $B!=(B $B$h$/$"$k<ALd(B +$B2?$+LdBj$,5/$3$C$?$H$-$K$I$&$9$k(B? + +
    $B%5%]!<%H(B + + +
    + $B!V$J$s$G!D(B? $B$I$&$7$FF0:n$7$J$$!D(B?$B!WLdBj$,(B + $B5/$-$?$H$-$K$I$&$9$k$+(B + +

    Apache $B$N%5!<%P%=%U%H%&%'%"$K2?$+LdBj$,5/$3$C$?$H$-$O!"0J2<$N(B + $B$C$F$/$@$5$$(B:

    + +
    +
    $B%(%i!<%m%0$rD4$Y$k(B!
    +
    $BLdBj$,H/@8$7$?$H$-$O(B Apache $B$O$J$k$Y$/l9g!"(BApache $B$O%5!<%P$N%(%i!<%m%0$K%a%C%;!<%8$r=q$/$3$H$G!">\:Y$J(B + $B>pJs$rDs6!$7$^$9!#>l9g$K$h$C$F$O!"$3$l$@$1$GLdBj$r<+J,<+?H$GJ,@O$7!"(B + $B=$@5$9$k$?$a$K==J,$J>pJs$rF@$k$3$H$,$G$-$^$9(B ($B%U%!%$%k$N%Q!<%_%C%7%g%s$N(B + $BLdBj$J$I(B)$B!#%(%i!<%m%0$N%G%U%)%k%H$N>l=j$O(B + /usr/local/apache2/logs/error_log $B$G$9$,!"$"$J$?$N%5!<%P(B + $B$G$N>l=j$rCN$k$?$a$K$O@_Dj%U%!%$%kCf$N(B ErrorLog $B$r8+$F$/$@$5$$!#(B
    + +
    FAQ $B$rD4$Y$k(B!
    +
    Apache $B$N$h$/$"$ko$K(B Apache $B$N + +
    Apache $B%P%0%G!<%?%Y!<%9$rD4$Y$k(B
    +
    Apache $B%0%k!<%W$KJs9p$5$l$k$[$H$s$I$NLdBj$O(B$B%P%0%G!<%?%Y!<%9(B$B$K(B + $B5-O?$5$l$^$9!#(BOpen $B$b(B closed $B$b(B $B4^$a$F!"(B + $B4{B8$N%l%]!<%H$K$"$k$+$I$&$+$rD4$Y$F(B$B$/$@$5$$(B$B!#(B + $B4{$KLdBj$,Js9p$5$l$F$$$k$H$-!"!V;d$b!W$H$$$&Js9p$ODI2C(B$B$7$J$$$G(B + $B$/$@$5$$(B$B!#85$NJs9p$,(B close $B$5$l$F$$$J$$$H$-$O!"Dj4|E*$K(B + $B%P%0%G!<%?%Y!<%9$rD4$Y$k$3$H$r$*A&$a$7$^$9!#$^$?!"85$NDs=P + +
    $B%f!<%6%5%]!<%H%U%)!<%i%`$G
    +

    Apache $B$K$O$h$m$3$s$GCN<1$r6&M-$5$;$F$/$l$k3hH/$J(B + $B%f!<%6$N%3%_%e%K%F%#$,$"$j$^$9!#$3$N%3%_%e%K%F%#$K;22C$9$k$3$H$,!"(B + $BIaDL$O + +

    $B%f!<%6(B + $B%a!<%j%s%0%j%9%H(B

    + +

    USENET $B%K%e!<%9%0%k!<%W(B:

    + +
    + +
    $B$b$7!"A4It<:GT$7$?>l9g$O!"LdBj$r%P%0%G!<%?%Y!<%9$KJs9p$7$F$/$@$5$$(B
    +

    $B>e5-$Nl9g$O!"(B$B%P%0$NJs9p(B$B$r(B + $B$9$k$3$H$K$h$j!"LdBj$r(B$B$<$R(B httpd $B3+H/ + +

    $B%5!<%P$N%/%i%C%7%e$d%3%"%@%s%W$NH/@8$9$kLdBj$G$"$l$P!"(B($B2DG=$G$"$l$P(B) + $B%P%C%/%H%l!<%9$rJs9p$K4^$a$F$/$@$5$$!#Nc$($P!"(B

    + + + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +
    + +

    (ServerRoot $B$H(B httpd $B$H(B core $B%U%!%$%k(B + $B$N0LCV$rE,@Z$J$b$N$KCV$-49$($F$/$@$5$$!#(Bdbx $B$NBe$o$j$K(B + gdb $B$r;H$&I,MW$,$"$k$+$b$7$l$^$;$s!#(B)

    +
    +
    +
    + +
    $BC/$K%5%]!<%H$rMj$a$P$h$$(B? +

    $B?tI4K|$N%f!<%6$KBP$7$F!"(B40$BL$K~$N%\%i%s%F%#%"3+H/$B%f!<%6$N%U%)!<%i%`(B$B$K;22C$9$k$N$,NI$$$G$7$g$&!#(B

    + +

    Apache $B$N%W%m$N!">&MQ%5%]!<%H$b(B + $BB?$/$N2q + $B$+$iDs6!$5$l$F$$$^$9!#(B

    +
    +
    + +
    + diff --git a/trunk/docs/manual/faq/support.xml.ko b/trunk/docs/manual/faq/support.xml.ko new file mode 100644 index 0000000000..05bdb134f9 --- /dev/null +++ b/trunk/docs/manual/faq/support.xml.ko @@ -0,0 +1,141 @@ + + + + + + + + +FAQ + +Áö¿ø - ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) +¹®Á¦°¡ »ý±â¸é ¾î¶»°Ô ÇØ°áÇϳª? + +
    Áö¿ø + + +
    + "¿Ö ... ¾ÈµÇ³ª? ¿Ö ... µ¿ÀÛÇÏÁö ¾Ê´Â°¡?" ¹®Á¦°¡ »ý±â¸é + ÇÒÀÏ + +

    ¾ÆÆÄÄ¡ ¼­¹ö ¼ÒÇÁÆ®¿þ¾î¿¡ ¹®Á¦°¡ »ý±â¸é ´ÙÀ½°ú °°Àº + ´Ü°è¸¦ µû¸¥´Ù:

    + +
    +
    ¿À·ù ·Î±×(errorlog)¸¦ È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ ¼­¹ö´Â ¹®Á¦°¡ »ý±â¸é µµ¿òÀ» ÁÖ·Á°í ³ë·ÂÇÑ´Ù. + ¸¹Àº °æ¿ì ¼­¹ö ¿À·ù ·Î±×¿¡ ÀÚ¼¼ÇÑ ³»¿ëÀ» ±â·ÏÇÑ´Ù. + À̰͸¸À¸·Îµµ Á÷Á¢ (ÆÄÀϱÇÇÑ µî) ¹®Á¦¸¦ ¹ß°ßÇÏ°í °íÄ¥ ¼ö + ÀÖ´Â °æ¿ì°¡ ¸¹´Ù. ¿À·ù ·Î±×ÀÇ ±âº» À§Ä¡´Â + /usr/local/apache2/logs/error_logÀÌÁö¸¸, + Á¤È®ÇÑ À§Ä¡´Â ¼³Á¤ÆÄÀÏÀÇ ErrorLog Áö½Ã¾î¸¦ Âü°íÇ϶ó.
    + +
    FAQ¸¦ + È®ÀÎÇ϶ó!
    +
    ¾ÆÆÄÄ¡ À¥»çÀÌÆ®¿¡¼­ Ç×»ó ¾ÆÆÄÄ¡ FAQ ÃÖ½ÅÆÇÀ» º¼ ¼ö + ÀÖ´Ù.
    + +
    ¾ÆÆÄÄ¡ ¹ö±× µ¥ÀÌÅͺ£À̽º¸¦ È®ÀÎÇ϶ó
    +
    ¾ÆÆÄÄ¡±×·ì(The Apache Group)¿¡ º¸°íµÈ ´ëºÎºÐÀÇ ¹®Á¦´Â + ¹ö±× + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÈ´Ù. »õ·Î ¹ö±×¸¦ Ãß°¡Çϱâ Àü¿¡, + ÀÌ¹Ì ¾Ë·ÁÁ³°Å³ª(open) ÇØ°áµÈ(closed) ¹ö±×°¡ ÀÖ´ÂÁö È®ÀÎÇϱæ + ¹Ù¶õ´Ù. ÀÌ¹Ì ¹®Á¦°¡ º¸°íµÇ¾ú´Ù¸é "³ªµµ + ÀÌ·± ¹®Á¦°¡ ÀÖ´Ù°í" º¸°íÇÏÁö ¾Ê±æ ¹Ù¶õ´Ù. ¾ÆÁ÷ + ÇØ°áµÇÁö ¾Ê¾Ò´Ù¸é ÁÖ±âÀûÀ¸·Î »óȲÀ» È®ÀÎÇÏ±æ ¹Ù¶õ´Ù. ¶Ç, + µ¥ÀÌÅͺ£À̽º¿¡ ±â·ÏµÇÁö ¾Ê°í À̸ÞÀÏ ±³È¯À¸·Î ÁøÇàµÈ »çÇ×ÀÌ + ÀÖÀ» ¼ö ÀÖÀ¸´Ï óÀ½ ¹®Á¦¸¦ º¸°íÇÑ »ç¶÷¿¡°Ô ¿¬¶ôÇغ¼ ¼öµµ + ÀÖ´Ù.
    + +
    »ç¿ëÀÚ Áö¿ø °ø°£¿¡ + ¹®ÀÇÇÑ´Ù
    +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Áö½ÄÀ» °øÀ¯ÇÏ±æ ¿øÇÏ´Â È°¹ßÇÑ »ç¿ëÀÚ + °øµ¿Ã¼µéÀÌ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î ÀÌ·± °øµ¿Ã¼¿¡ Âü¿©ÇÏ´Â °ÍÀÌ + ¹®Á¦ÀÇ ´äÀ» ¾ò´Â °¡Àå ÁÁ°í ºü¸¥ ¹æ¹ýÀÌ´Ù.

    + +

    »ç¿ëÀÚ + ¸ÞÀϸµ¸®½ºÆ®

    + +

    USENET ´º½º±×·ì:

    + +
      +
    • comp.infosystems.www.servers.unix + [news] + [google] +
    • + +
    • comp.infosystems.www.servers.ms-windows + [news] + [google] +
    • + +
    • comp.infosystems.www.authoring.cgi + [news] + [google] +
    • +
    + +
    À§ÀÇ ¹æ¹ýÀÌ ¸ðµÎ ½ÇÆÐÇÏ¸é ¹ö±× µ¥ÀÌÅͺ£À̽º¿¡ ¹®Á¦¸¦ + º¸°íÇÑ´Ù
    +

    À§ÀÇ ´Ü°è¸¦ ¸ðµÎ ½ÃµµÇÏ°íµµ ÇØ°áÃ¥ÀÌ ¾ø´Ù¸é, ¹ö±×¸¦ + º¸°íÇÏ¿© À¥¼­¹ö °³¹ßÀڵ鿡°Ô ¹®Á¦¸¦ ¾Ë¸®±æ + ¹Ù¶õ´Ù.

    + +

    core dump¸¦ ¸¸µé¸ç ¼­¹ö°¡ Á×´Â °æ¿ì¶ó¸é (°¡´ÉÇϸé) + backtrace¹®Á¦°¡ ½ÇÇàÆÄÀÏÀÇ Á¤È®È÷ ¾î¶² ÁöÁ¡¿¡¼­ + ¹ß»ýÇÏ¿´°í, ÇÁ·Î±×·¥ÀÌ ±× ÁöÁ¡±îÁö ¾î¶² °æ·Î·Î ½ÇÇàµÇ¾ú´ÂÁö¸¦ + ¾Ë·ÁÁÖ´Â Á¤º¸¸¦ Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù. ¿¹¸¦ µé¾î,

    + + + # cd ServerRoot
    + # dbx httpd core
    + (dbx) where +
    + +

    (ServerRoot, httpd, core + ÆÄÀÏÀÇ ½ÇÁ¦ À§Ä¡¸¦ ´ë½Å »ç¿ëÇ϶ó. dbx ´ë½Å + gdb¸¦ »ç¿ëÇØ¾ß ÇÒ ¼öµµ ÀÖ´Ù.)

    +
    +
    +
    + +
    µµ¿òÀ» ¾òÀ¸·Á¸é ´©±¸¿¡°Ô + ¿¬¶ôÇϳª? +

    40¸í °¡·®ÀÇ ÀÚ¹ßÀûÀ¸·Î Âü¿©ÇÑ °³¹ßÀÚ¸¸À¸·Î´Â ¼ö¹é¸¸ÀÇ + »ç¿ëÀÚ¿¡°Ô ¾ÆÆÄÄ¡¿¡ ´ëÇØ ÀÏÀÏÀÌ Áö¿øÇÒ ¼ö ¾ø´Ù. ¹«·á Áö¿øÀ» + ¾òÀ¸·Á¸é »ç¿ëÀÚ + °ø°£¿¡ Âü¿©ÇÏ±æ ±ÇÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡ ´ëÇÑ Á÷¾÷ÀûÀÎ À¯·á Áö¿øÀº ¿©·¯ + ȸ»ç¿¡¼­ Á¦°øÇÑ´Ù.

    +
    +
    + + + diff --git a/trunk/docs/manual/faq/support.xml.meta b/trunk/docs/manual/faq/support.xml.meta new file mode 100644 index 0000000000..bb78422082 --- /dev/null +++ b/trunk/docs/manual/faq/support.xml.meta @@ -0,0 +1,13 @@ + + + + support + /faq/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/filter.html b/trunk/docs/manual/filter.html new file mode 100644 index 0000000000..98b9e5c44a --- /dev/null +++ b/trunk/docs/manual/filter.html @@ -0,0 +1,19 @@ +URI: filter.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: filter.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: filter.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: filter.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: filter.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/filter.html.en b/trunk/docs/manual/filter.html.en new file mode 100644 index 0000000000..b03288823a --- /dev/null +++ b/trunk/docs/manual/filter.html.en @@ -0,0 +1,80 @@ + + + +Filters - Apache HTTP Server + + + + + +
    <-
    +

    Filters

    +
    +

    Available Languages:  en  | + es  | + fr  | + ja  | + ko 

    +
    + +

    This document describes the use of filters in Apache.

    +
    +
    top
    +
    +

    Filters

    + + + +

    A filter is a process that is applied to data that + is sent or received by the server. Data sent by clients to the + server is processed by input filters while data sent + by the server to the client is processed by output + filters. Multiple filters can be applied to the data, and + the order of the filters can be explicitly specified.

    + +

    Filters are used internally by Apache to perform functions such + as chunking and byte-range request handling. In addition, modules + can provide filters that are selectable using run-time + configuration directives. The set of filters that apply to data + can be manipulated with the + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, and + RemoveOutputFilter + directives.

    + +

    The following user-selectable filters are currently provided + with the Apache HTTP Server distribution.

    + +
    +
    INCLUDES
    +
    Server-Side Includes processing by mod_include
    +
    DEFLATE
    +
    Compress output before sending it to the client using + mod_deflate +
    +
    + +

    In addition, the module mod_ext_filter allows + for external programs to be defined as filters.

    +
    +
    +

    Available Languages:  en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/filter.html.es b/trunk/docs/manual/filter.html.es new file mode 100644 index 0000000000..ad0ea8c87b --- /dev/null +++ b/trunk/docs/manual/filter.html.es @@ -0,0 +1,77 @@ + + + +Filtros - Servidor HTTP Apache + + + + + +
    <-
    +

    Filtros

    +
    +

    Idiomas disponibles:  en  | + es  | + fr  | + ja  | + ko 

    +
    + +

    Este documento describe cómo usar filtros en Apache.

    +
    +
    top
    +
    +

    Filtros

    + + + +

    Un filtro es un proceso que se aplica a los datos que + se reciben o se envían por el servidor. Los datos enviados + por los clientes al servidor son procesados por filtros de + entrada mientras que los datos enviados por el servidor se + procesan por los filtros de salida. A los datos se les + pueden aplicar varios filtros, y el orden en que se aplica cada + filtro puede especificarse explícitamente.

    + +

    Los filtros se usan internamente por Apache para llevar a cabo + funciones tales como chunking y servir peticiones de + byte-range. Además, los módulos contienen filtros que se + pueden seleccionar usando directivas de configuración al + iniciar el servidor. El conjunto de filtros que se aplica a los + datos puede manipularse con las directivas SetInputFilter, SetOutputFilter, AddInputFilter, AddOutputFilter, RemoveInputFilter, y RemoveOutputFilter.

    + +

    Actualmente, vienen con la distribución de Apache los + siguientes filtros seleccionables por el usuario.

    + +
    +
    INCLUDES
    +
    Server-Side Includes procesado por + mod_include
    +
    DEFLATE
    +
    Comprime los datos de salida antes de enviarlos al cliente + usando el módulo + mod_deflate +
    +
    + +

    Además, el módulo mod_ext_filter + permite definir programas externos como filtros.

    +
    +
    +

    Idiomas disponibles:  en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/filter.html.fr b/trunk/docs/manual/filter.html.fr new file mode 100644 index 0000000000..77d2e8b8f2 --- /dev/null +++ b/trunk/docs/manual/filter.html.fr @@ -0,0 +1,82 @@ + + + +Filtres - Serveur Apache HTTP + + + + + +
    <-
    +

    Filtres

    +
    +

    Langues Disponibles:  en  | + es  | + fr  | + ja  | + ko 

    +
    + +

    Ce document explique le fonctionnement des filtres avec Apache.

    +
    +
    top
    +
    +

    Filtres

    + + + +

    On appelle filtre un processus qui s'applique aux données reçues + ou envoyées par le serveur. Les filtres en entrée ("input filters") + servent à filtrer les données envoyées par les clients au serveur, tandis + que les filtres en sortie ("output filters") travaillent sur les + données envoyées par le serveur à un client. Il est possible d'appliquer + plusieurs filtres à un flux de données, et l'ordre de ces filtres peux être + spécifiée de façon explicite.

    + +

    Apache utilise des filtres en interne pour par exemple gérer les "grosses" requêtes + (chunked) ou les requêtes partielles (NDT : "byte-range" : requêtes sur seulement une + partie d'un fichier spécifiée par un pointeur de départ, et de fin). + Certains modules permettent en plus d'utiliser des filtres + en utilisant des directives de configuration. Les filtres sont utilisables + au moyen des directives + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter et + RemoveOutputFilter + .

    + +

    Les filtres listés ci-dessous sont fournis dans la distribution d'Apache, et + peuvent être utilisés par tout administrateur.

    + +
    +
    INCLUDES
    +
    Le module mod_include travaille au moyen de + "Server-Side Includes"
    +
    DEFLATE
    +
    Le module mod_deflate compresse les données avant leur envoi au + client (filtre en sortie).
    +
    + +

    En outre, le module mod_ext_filter permet d'utiliser des + programes externes à Apache en tant que filtres.

    +
    +
    +

    Langues Disponibles:  en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/filter.html.ja.euc-jp b/trunk/docs/manual/filter.html.ja.euc-jp new file mode 100644 index 0000000000..bd576e7b3f --- /dev/null +++ b/trunk/docs/manual/filter.html.ja.euc-jp @@ -0,0 +1,80 @@ + + + +¥Õ¥£¥ë¥¿ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Õ¥£¥ë¥¿

    +
    +

    Available Languages:  en  | + es  | + fr  | + ja  | + ko 

    +
    + +

    Apache ¤Ç¤Î¥Õ¥£¥ë¥¿¤Î»È¤¤Êý¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£

    +
    +
    top
    +
    +

    ¥Õ¥£¥ë¥¿

    + + + +

    ¥Õ¥£¥ë¥¿ ¤È¤Ï¡¢¥µ¡¼¥Ð¤¬Á÷¼õ¿®¤·¤¿¥Ç¡¼¥¿¤Ë + ŬÍѤµ¤ì¤ë½èÍý¥×¥í¥»¥¹¤Î¤³¤È¤ò¤¤¤¤¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¤«¤é¥µ¡¼¥Ð¤Ë + Á÷¤é¤ì¤¿¥Ç¡¼¥¿¤Ï ÆþÎÏ¥Õ¥£¥ë¥¿ ¤Ë¤è¤Ã¤Æ¡¢¥µ¡¼¥Ð¤«¤é + ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ë¥Ç¡¼¥¿¤Ï½ÐÎÏ¥Õ¥£¥ë¥¿¤Ë¤è¤Ã¤Æ + ½èÍý¤µ¤ì¤Þ¤¹¡£Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤òŬÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¡¢ + ¤½¤Î½çÈÖ¤ò¸·Ì©¤Ë»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ÆâÉô¤Ç¤Ï¡¢¥Á¥ã¥ó¥¯ (¥Ç¡¼¥¿¤Î¤Ö¤ÄÀÚ¤ê) ¤ò¹Ô¤Ã¤¿¤ê¡¢ + ¥Ð¥¤¥ÈÈϰϤλØÄꤵ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤¿¤ê¤È¤¤¤Ã¤¿µ¡Ç½¤ò + ¹Ô¤¦ºÝ¤Ë¡¢¥Õ¥£¥ë¥¿¤¬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤Ë²Ã¤¨¤Æ¡¢ + ¼Â¹Ô»þ¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÁªÂò¤¬²Äǽ¤Ê¥Õ¥£¥ë¥¿¤ò + ¥â¥¸¥å¡¼¥ë¤¬Ä󶡤Ǥ­¤Þ¤¹¡£ + ¥Ç¡¼¥¿¤ËŬ±þ¤µ¤ì¤ë¥Õ¥£¥ë¥¿¤Î¥»¥Ã¥È¤Ï¡¢ + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, + RemoveOutputFilter + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀ©¸æ¤Ç¤­¤Þ¤¹¡£

    + +

    ¸½¹Ô¤Î Apache HTTP ¥µ¡¼¥Ð¤ÎÇÛÉۤǤϡ¢ + ¼¡¤Î¥æ¡¼¥¶ÁªÂò²Äǽ¤Ê¥Õ¥£¥ë¥¿¤¬Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    +
    INCLUDES
    +
    mod_include ¤Ç Server-Side Include ¤ò¤·¤Þ¤¹¡£
    +
    DEFLATE
    +
    mod_deflate + ¤ò»È¤Ã¤Æ¡¢¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¿®¤¹¤ëÁ°¤Ë½ÐÎϤò°µ½Ì¤·¤Þ¤¹¡£
    +
    + +

    ¤Þ¤¿¡¢mod_ext_filter ¥â¥¸¥å¡¼¥ë¤Ç + ³°Éô¥×¥í¥°¥é¥à¤ò¥Õ¥£¥ë¥¿¤È¤·¤Æ»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/filter.html.ko.euc-kr b/trunk/docs/manual/filter.html.ko.euc-kr new file mode 100644 index 0000000000..bef44c2e92 --- /dev/null +++ b/trunk/docs/manual/filter.html.ko.euc-kr @@ -0,0 +1,78 @@ + + + +ÇÊÅÍ - Apache HTTP Server + + + + + +
    <-
    +

    ÇÊÅÍ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + fr  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡¿¡¼­ ÇÊÅ͸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    +
    top
    +
    +

    ÇÊÅÍ

    + + + +

    ÇÊÅÍ(filter)´Â ¼­¹ö°¡ º¸³»°Å³ª ¹Þ´Â ÀÚ·á¿¡ + Àû¿ëµÇ´Â ÀÛ¾÷ÀÌ´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡°Ô º¸³»´Â ÀÚ·á´Â + ÀÔ·ÂÇÊÅÍ(input filter)°¡ ó¸®ÇÏ°í, ¼­¹ö°¡ + Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â ÀÚ·á´Â Ãâ·ÂÇÊÅÍ(output filter)°¡ + ó¸®ÇÑ´Ù. ÀÚ·á¿¡ ¿©·¯ ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ°í, Á÷Á¢ ÇÊÅÍÀÇ + ¼ø¼­¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â À̾î¹Þ±â(byte-range) ¿äû µîÀ» ó¸®ÇϱâÀ§ÇØ + ³»ºÎÀûÀ¸·Î ÇÊÅ͸¦ »ç¿ëÇÑ´Ù. ¶Ç, ¼³Á¤ Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¼±Åð¡´ÉÇÑ ÇÊÅ͸¦ Á¦°øÇÏ´Â ¸ðµâµµ ÀÖ´Ù. + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, + RemoveOutputFilter + Áö½Ã¾î·Î ÀڷḦ ó¸®ÇÏ´Â ÇÊÅ͸¦ Á¶ÀýÇÑ´Ù.

    + +

    ÇöÀç ¾ÆÆÄÄ¡ À¥¼­¹ö ¹èÆ÷º»Àº »ç¿ëÀÚ°¡ ¼±ÅÃÇÒ ¼ö ÀÖ´Â ´ÙÀ½°ú + °°Àº ÇÊÅ͸¦ Á¦°øÇÑ´Ù.

    + +
    +
    INCLUDES
    +
    mod_include°¡ ó¸®ÇÏ´Â Server-Side Includes
    +
    DEFLATE
    +
    mod_deflate¸¦ »ç¿ëÇÏ¿© Ãâ·ÂÀ» + Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ ¾ÐÃà +
    +
    + +

    ¶Ç, mod_ext_filter ¸ðµâÀ» »ç¿ëÇÏ¿© + ¿ÜºÎ ÇÁ·Î±×·¥À» ÇÊÅÍ·Î »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/filter.xml b/trunk/docs/manual/filter.xml new file mode 100644 index 0000000000..e5de3c0bfb --- /dev/null +++ b/trunk/docs/manual/filter.xml @@ -0,0 +1,86 @@ + + + + + + + + + + Filters + + +

    This document describes the use of filters in Apache.

    +
    + +
    + Filters + + + mod_deflate + mod_ext_filter + mod_include + + + AddInputFilter + AddOutputFilter + RemoveInputFilter + RemoveOutputFilter + ExtFilterDefine + ExtFilterOptions + SetInputFilter + SetOutputFilter + + + +

    A filter is a process that is applied to data that + is sent or received by the server. Data sent by clients to the + server is processed by input filters while data sent + by the server to the client is processed by output + filters. Multiple filters can be applied to the data, and + the order of the filters can be explicitly specified.

    + +

    Filters are used internally by Apache to perform functions such + as chunking and byte-range request handling. In addition, modules + can provide filters that are selectable using run-time + configuration directives. The set of filters that apply to data + can be manipulated with the + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, and + RemoveOutputFilter + directives.

    + +

    The following user-selectable filters are currently provided + with the Apache HTTP Server distribution.

    + +
    +
    INCLUDES
    +
    Server-Side Includes processing by mod_include
    +
    DEFLATE
    +
    Compress output before sending it to the client using + mod_deflate +
    +
    + +

    In addition, the module mod_ext_filter allows + for external programs to be defined as filters.

    +
    +
    diff --git a/trunk/docs/manual/filter.xml.es b/trunk/docs/manual/filter.xml.es new file mode 100644 index 0000000000..f5e2d9d9a7 --- /dev/null +++ b/trunk/docs/manual/filter.xml.es @@ -0,0 +1,90 @@ + + + + + + + + + + Filtros + + +

    Este documento describe cómo usar filtros en Apache.

    +
    + +
    + Filtros + + + mod_deflate + mod_ext_filter + mod_include + + + AddInputFilter + AddOutputFilter + RemoveInputFilter + RemoveOutputFilter + ExtFilterDefine + ExtFilterOptions + SetInputFilter + SetOutputFilter + + + +

    Un filtro es un proceso que se aplica a los datos que + se reciben o se envían por el servidor. Los datos enviados + por los clientes al servidor son procesados por filtros de + entrada mientras que los datos enviados por el servidor se + procesan por los filtros de salida. A los datos se les + pueden aplicar varios filtros, y el orden en que se aplica cada + filtro puede especificarse explícitamente.

    + +

    Los filtros se usan internamente por Apache para llevar a cabo + funciones tales como chunking y servir peticiones de + byte-range. Además, los módulos contienen filtros que se + pueden seleccionar usando directivas de configuración al + iniciar el servidor. El conjunto de filtros que se aplica a los + datos puede manipularse con las directivas SetInputFilter, SetOutputFilter, AddInputFilter, AddOutputFilter, RemoveInputFilter, y RemoveOutputFilter.

    + +

    Actualmente, vienen con la distribución de Apache los + siguientes filtros seleccionables por el usuario.

    + +
    +
    INCLUDES
    +
    Server-Side Includes procesado por + mod_include
    +
    DEFLATE
    +
    Comprime los datos de salida antes de enviarlos al cliente + usando el módulo + mod_deflate +
    +
    + +

    Además, el módulo mod_ext_filter + permite definir programas externos como filtros.

    +
    +
    + diff --git a/trunk/docs/manual/filter.xml.fr b/trunk/docs/manual/filter.xml.fr new file mode 100644 index 0000000000..8eadfde524 --- /dev/null +++ b/trunk/docs/manual/filter.xml.fr @@ -0,0 +1,88 @@ + + + + + + + + + + Filtres + + +

    Ce document explique le fonctionnement des filtres avec Apache.

    +
    + +
    + Filtres + + + mod_deflate + mod_ext_filter + mod_include + + + AddInputFilter + AddOutputFilter + RemoveInputFilter + RemoveOutputFilter + ExtFilterDefine + ExtFilterOptions + SetInputFilter + SetOutputFilter + + + +

    On appelle filtre un processus qui s'applique aux données reçues + ou envoyées par le serveur. Les filtres en entrée ("input filters") + servent à filtrer les données envoyées par les clients au serveur, tandis + que les filtres en sortie ("output filters") travaillent sur les + données envoyées par le serveur à un client. Il est possible d'appliquer + plusieurs filtres à un flux de données, et l'ordre de ces filtres peux être + spécifiée de façon explicite.

    + +

    Apache utilise des filtres en interne pour par exemple gérer les "grosses" requêtes + (chunked) ou les requêtes partielles (NDT : "byte-range" : requêtes sur seulement une + partie d'un fichier spécifiée par un pointeur de départ, et de fin). + Certains modules permettent en plus d'utiliser des filtres + en utilisant des directives de configuration. Les filtres sont utilisables + au moyen des directives + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter et + RemoveOutputFilter + .

    + +

    Les filtres listés ci-dessous sont fournis dans la distribution d'Apache, et + peuvent être utilisés par tout administrateur.

    + +
    +
    INCLUDES
    +
    Le module mod_include travaille au moyen de + "Server-Side Includes"
    +
    DEFLATE
    +
    Le module mod_deflate compresse les données avant leur envoi au + client (filtre en sortie).
    +
    + +

    En outre, le module mod_ext_filter permet d'utiliser des + programes externes à Apache en tant que filtres.

    +
    +
    diff --git a/trunk/docs/manual/filter.xml.ja b/trunk/docs/manual/filter.xml.ja new file mode 100644 index 0000000000..2b45176f0e --- /dev/null +++ b/trunk/docs/manual/filter.xml.ja @@ -0,0 +1,90 @@ + + + + + + + + + + $B%U%#%k%?(B + + +

    Apache $B$G$N%U%#%k%?$N;H$$J}$K$D$$$F5-=R$7$F$$$^$9!#(B

    +
    + +
    + $B%U%#%k%?(B + + + mod_deflate + mod_ext_filter + mod_include + + + AddInputFilter + AddOutputFilter + RemoveInputFilter + RemoveOutputFilter + ExtFilterDefine + ExtFilterOptions + SetInputFilter + SetOutputFilter + + + +

    $B%U%#%k%?(B $B$H$O!"%5!<%P$,Aw$BF~NO%U%#%k%?(B $B$K$h$C$F!"%5!<%P$+$i(B + $B%/%i%$%"%s%H$KAw$i$l$k%G!<%?$O(B$B=PNO%U%#%k%?(B$B$K$h$C$F(B + $B=hM}$5$l$^$9!#J#?t$N%U%#%k%?$rE,MQ$9$k$3$H$,$G$-!"(B + $B$=$N=gHV$r87L)$K;XDj$9$k$3$H$b$G$-$^$9!#(B

    + +

    Apache $BFbIt$G$O!"%A%c%s%/(B ($B%G!<%?$N$V$D@Z$j(B) $B$r9T$C$?$j!"(B + $B%P%$%HHO0O$N;XDj$5$l$?%j%/%(%9%H$r07$C$?$j$H$$$C$?5!G=$r(B + $B9T$&:]$K!"%U%#%k%?$,;H$o$l$F$$$^$9!#$=$l$K2C$($F!"(B + $BSetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, + RemoveOutputFilter + $B%G%#%l%/%F%#%V$G@)8f$G$-$^$9!#(B

    + +

    $B8=9T$N(B Apache HTTP $B%5!<%P$NG[I[$G$O!"(B + $B + +

    +
    INCLUDES
    +
    mod_include $B$G(B Server-Side Include $B$r$7$^$9!#(B
    +
    DEFLATE
    +
    mod_deflate + $B$r;H$C$F!"%/%i%$%"%s%H$KAw?.$9$kA0$K=PNO$r05=L$7$^$9!#(B
    +
    + +

    $B$^$?!"(Bmod_ext_filter $B%b%8%e!<%k$G(B + $B30It%W%m%0%i%`$r%U%#%k%?$H$7$F;XDj$9$k$3$H$,$G$-$^$9!#(B

    +
    + + + + + diff --git a/trunk/docs/manual/filter.xml.ko b/trunk/docs/manual/filter.xml.ko new file mode 100644 index 0000000000..b961236720 --- /dev/null +++ b/trunk/docs/manual/filter.xml.ko @@ -0,0 +1,84 @@ + + + + + + + + + + ÇÊÅÍ + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡¿¡¼­ ÇÊÅ͸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    + ÇÊÅÍ + + + mod_deflate + mod_ext_filter + mod_include + + + AddInputFilter + AddOutputFilter + RemoveInputFilter + RemoveOutputFilter + ExtFilterDefine + ExtFilterOptions + SetInputFilter + SetOutputFilter + + + +

    ÇÊÅÍ(filter)´Â ¼­¹ö°¡ º¸³»°Å³ª ¹Þ´Â ÀÚ·á¿¡ + Àû¿ëµÇ´Â ÀÛ¾÷ÀÌ´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡°Ô º¸³»´Â ÀÚ·á´Â + ÀÔ·ÂÇÊÅÍ(input filter)°¡ ó¸®ÇÏ°í, ¼­¹ö°¡ + Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â ÀÚ·á´Â Ãâ·ÂÇÊÅÍ(output filter)°¡ + ó¸®ÇÑ´Ù. ÀÚ·á¿¡ ¿©·¯ ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ°í, Á÷Á¢ ÇÊÅÍÀÇ + ¼ø¼­¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â À̾î¹Þ±â(byte-range) ¿äû µîÀ» ó¸®ÇϱâÀ§ÇØ + ³»ºÎÀûÀ¸·Î ÇÊÅ͸¦ »ç¿ëÇÑ´Ù. ¶Ç, ¼³Á¤ Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¼±Åð¡´ÉÇÑ ÇÊÅ͸¦ Á¦°øÇÏ´Â ¸ðµâµµ ÀÖ´Ù. + SetInputFilter, + SetOutputFilter, + AddInputFilter, + AddOutputFilter, + RemoveInputFilter, + RemoveOutputFilter + Áö½Ã¾î·Î ÀڷḦ ó¸®ÇÏ´Â ÇÊÅ͸¦ Á¶ÀýÇÑ´Ù.

    + +

    ÇöÀç ¾ÆÆÄÄ¡ À¥¼­¹ö ¹èÆ÷º»Àº »ç¿ëÀÚ°¡ ¼±ÅÃÇÒ ¼ö ÀÖ´Â ´ÙÀ½°ú + °°Àº ÇÊÅ͸¦ Á¦°øÇÑ´Ù.

    + +
    +
    INCLUDES
    +
    mod_include°¡ ó¸®ÇÏ´Â Server-Side Includes
    +
    DEFLATE
    +
    mod_deflate¸¦ »ç¿ëÇÏ¿© Ãâ·ÂÀ» + Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ ¾ÐÃà +
    +
    + +

    ¶Ç, mod_ext_filter ¸ðµâÀ» »ç¿ëÇÏ¿© + ¿ÜºÎ ÇÁ·Î±×·¥À» ÇÊÅÍ·Î »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    +
    +
    diff --git a/trunk/docs/manual/filter.xml.meta b/trunk/docs/manual/filter.xml.meta new file mode 100644 index 0000000000..ac572243f6 --- /dev/null +++ b/trunk/docs/manual/filter.xml.meta @@ -0,0 +1,15 @@ + + + + filter + / + . + + + en + es + fr + ja + ko + + diff --git a/trunk/docs/manual/glossary.html b/trunk/docs/manual/glossary.html new file mode 100644 index 0000000000..1efee97240 --- /dev/null +++ b/trunk/docs/manual/glossary.html @@ -0,0 +1,15 @@ +URI: glossary.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: glossary.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: glossary.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: glossary.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/glossary.html.de b/trunk/docs/manual/glossary.html.de new file mode 100644 index 0000000000..3b8c5a2aab --- /dev/null +++ b/trunk/docs/manual/glossary.html.de @@ -0,0 +1,539 @@ + + + +Glossar - Apache HTTP Server + + + + + +
    <-
    +

    Glossar

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ko 

    +
    + +

    Dieses Glossar erläutert einige gebräuchliche Fachbegriffe im + Zusammenhang mit dem Apache im Speziellen und Web-Diensten im + Allgemeinen. Weitere Informationen zum jeweiligen Begriff erreichen Sie + über die Links.

    +
    +
    top
    +
    +

    Definitionen

    + +
    +
    Algorithmus
    +
    Eine eindeutige Formel oder ein Satz von Regeln zur Lösung eines + Problems in einer endlichen Anzahl von Schritten. Algorithmen zur + Verschlüsselung werden üblicherweise  Chiffre genannt. +
    + +
    APache + eXtension Tool (apxs)
    +
    Ein Perl-Skript zur Kompilierung von Modul-Quelltexten zu Dynamic-Shared-Objects + ( DSOs) und zur Installation dieser zum + Apache-Webserver.
    + Siehe: apxs-Dokumentation +
    + +
    Authentifizierung
    +
    Die positive Identifizierung einer Netzwerkeinheit, wie z.B. + eines Servers, eines Clients oder eines Benutzers.
    + Siehe: Authentisierung, Autorisierung und + Zugriffskontrolle +
    + +
    Certification Authority + [səˈtifiˈkeiʃən + ɔːθɔriti] + (CA)
    +
    (Anm.d.Ü.: die Zertifizierungsstelle) Eine + vertrauenswürdige dritte Partei, deren Zweck es ist, + Zertifikate für Netzwerkeinheiten zu signieren. Andere + Netzwerkeinheiten können die Signatur prüfen, um + sicherzustellen, dass eine CA den Inhaber eines Zertifikats + authentifiziert hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Certificate Signing Request + [səˈtifikit sainiŋ + riˈkwest] (CSR)
    +
    (Anm.d.Ü.: Zertifikats-Signierungsanfrage) Ein unsigniertes +  Zertifikat zur Einreichung bei + einer  Zertifizierungsstelle, welche + es mit dem  privaten Schlüssel + ihres CA-Zertifikats signiert. Durch die Signatur wird ein CSR + zum echten Zertifikat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Chiffre
    +
    Die Chiffre ist ein Algorithmus oder System zur + Datenverschlüsselung. Beispiele sind DES, IDEA, RC4 usw. Im + Englischen spricht man von + Cipher [ˈsaifə]
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Chiffretext
    +
    Das Ergebnis, nachdem ein  Klartext + eine  Chiffre durchlaufen hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Common + Gateway Interface [ˈkɔmən geitwei + ˈintəːfeis] + (CGI)
    +
    Eine einheitliche Definition einer Schnittstelle zwischen einem + Webserver und einem externen Programm, welcher dem externen Programm die + Behandlung von Anfragen ermöglicht. Die Schnittstelle ist + ursprünglich von der NCSA + definiert worden. Es exisitert jedoch auch ein RFC-Projekt.
    + Siehe: Dynamische Inhalte mit CGI +
    + +
    CONNECT + [kənekt]
    +
    Eine  HTTP-Methode zur Weiterleitung + von Rohdaten über HTTP. Sie kann dazu verwendet werden, andere + Protokolle wie zum Beispiel das SSL-Protokoll zu kapseln. +
    + +
    Digitale + Signatur
    +
    Ein chiffrierter Textblock, der die Gültigkeit eines Zertifikats + oder einer anderen Datei bestätigt. Eine  Zertifizierungsstelle erstellt + eine digitale Signatur durch Generierung eines  Hashs aus dem in einem Zertifikat + enthaltenen öffentlichen Schlüssel und + anschließender Codierung des Hashs mit dem privaten + Schlüssel des Zertifikats. Nur der öffentliche + Schlüssel der CA kann die Signatur decodieren. So wird + sichergestellt, dass die CA die Netwerkeinheit, welche das + Zertifikat besitzt, authentifiziert hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Direktive
    +
    Eine Konfigurationsanweisung, die das Verhalten des Apache in einem + oder mehreren Punkten steuert. Direktiven werden in den  Konfigurationsdateien gesetzt.
    + Siehe: Verzeichnis der Direktiven +
    + +
    Dynamic + Shared Object + [daiˈnæmik ʃɛəd + ˈɔbdʒikt] (DSO)
    +
    Separat von der Apache-Binärdatei httpd + kompilierte  Module, die bei Bedarf + geladen werden können.
    + Siehe: Unterstützung für + Dynamic-Shared-Objects +
    + +
    exportbeschränkt
    +
    Verminderte kryptografische Stärke (und Sicherheit), um den + Exportbesimmungen der Vereinigten Staaten (Anm.d.Ü.: konkret: United + States' Export Administration Regulations (EAR)) zu + entsprechen. Exportbeschränkte Verschlüsselungssoftware ist + auf eine kurze Schlüssellänge begrenzt, was zu + Chiffretexten führt, die gewöhnlich mittels + Brute-Force dekodiert werden können.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Filter
    +
    Ein Verfahren, dass auf vom Server empfangene oder zu sendende Daten + angewendet wird. Eingabefilter verarbeiten vom Client an den Server + gesendetet Daten, während Ausgabefilter vom Server an den Client zu + sendende Daten verarbeiten. Der Ausgabefilter INCLUDES + beispielsweise untersucht Dokumente nach  Server-Side-Includes und führt sie aus.
    + Siehe: Filter +
    + +
    Handler + [ˈhændlə]
    +
    Eine Apache-interne Darstellung der Aktion, die beim Aufruf einer + Datei auszuführen ist. Im Allgemeinen besitzen Dateien implizite, + auf dem Dateityp basierende Handler. Gewöhnlich werden alle Dateien + vom Server bedient, einige Dateitypen werden jedoch separat "behandelt" + (Anm.d.Ü.: besitzen einen separaten Handler). Der + cgi-script-Handler beispielsweise kennzeichnet Dateien, die + als  CGI-Programme ausgeführt werden + sollen.
    + Siehe: Verwendung von Apache-Handlern +
    + +
    Hash + [hæʃ]
    +
    Ein mathematischer, unumkehrbarer Einweg-Algorithmus zur Generierung + einer Zeichenfolge fester Länge aus einer anderen Zeichenfolge + beliebiger Länge. Unterschiedliche Zeichenfolgen bei der Eingabe + ergeben üblischerweise unterschiedliche Hashes (abhängig von + der Hash-Funktion). +
    + +
    Header + [hedə]
    +
    Der Teil der  HTTP-Anfrage und -Antwort, + der vor den eigentlichen Daten übermittelt wird und den Inhalt + beschreibende Meta-Informationen enthält. +
    + +
    .htaccess
    +
    Eine  Konfigurationsdatei, + die innerhalb des Web-Verzeichnisbaums abgelegt wird und zu dem + Verzeichnis, in dem sie abgelegt ist, sowie allen Unterverzeichnissen +  Konfigurationsdirektiven + enthält. Trotz ihres Namens kann diese Datei nahezu alle Arten von + Direktiven enthalten, nicht nur Direktiven zur Zugriffskontrolle.
    + Siehe: Konfigurationsdateien +
    + +
    httpd.conf
    +
    Die  Haupt-Konfigurationsdatei ist + /usr/local/apache2/conf/httpd.conf. Dies kann aber zur + Laufzeit oder zur Kompilierungszeit anders konfiguriert werden.
    + Siehe: Konfigurationsdateien +
    + +
    HTTPS
    +
    Das HyperText-Transfer-Protokoll (Secure), der + Standard-Verschlüsselungsmechanismus im World Wide Web. + Tatsächlich handelt es sich hierbei um HTTP über  SSL.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    HyperText-Transfer-Protokoll + (HTTP)
    +
    Das Standard-Übertragungsprotokoll im World Wide Web. Der Apache + implementiert die Protokollversion 1.1, bezeichnet als HTTP/1.1 und + definiert in RFC 2616. +
    + +
    Klartext
    +
    Der unverschlüsselte Text.
    + +
    Konfigurationsanweisung
    +
    Siehe:  Direktive
    + +
    Konfigurationsdatei
    +
    Eine Textdatei mit  Direktiven, + welche die Konfiguration des Apache steuern.
    + Siehe: Konfigurationsdateien +
    + +
    Kontext
    +
    Ein Bereich in den  Konfigurationsdateien, in dem + verschiedene Typen von  Direktiven + erlaubt sind.
    + Siehe: Erklärung der + Fachbegriffe zu Apache-Direktiven +
    + +
    Message-Digest + [ˈmesidʒ]
    +
    Ein Hash einer Nachricht, mit dem sich sicherstellen läßt, + dass der Inhalt der Nachricht während der Übertragung nicht + verändert wurde. (Anm.d.Ü.: ein so genannter Extrakt der + Nachricht)
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Methode
    +
    Im  HTTP-Kontext eine in der + Anfrage(zeile) des Clients angegeben Aktion, die auf eine Ressource + angewendet wird. GET, POST und PUT + sind einige der verfügbaren HTTP-Methoden. +
    + +
    MIME-Typ + [maim tyːp]
    +
    Eine Art und Weise, den Typ des übermittelten Dokuments zu + beschreiben. Sein Name leitet sich davon ab, dass sein Format den + Multipurpose Internet Mail Extensions entlehnt wurde. Er besteht aus + einem Haupttyp und einem Untertyp, getrennt durch einen + Schrägstrich. Einige Beispiele sind text/html, + image/gif und application/octet-stream. + Bei HTTP wird der MIME-Typ mit dem  Header Content-Type + übermittelt.
    + Siehe: mod_mime +
    + +
    Modul
    +
    Ein selbstständiger Teil eines Programms. Ein Großteil der + Funktionalität des Apache ist in Modulen enthalten, die Sie einbinden + oder entfernen können. In die Apache-Binärdatei httpd einkompilierte Module werden statische Module + genannt, während Module, die separat gespeichert sind und optional + zur Laufzeit geladen werden können, dynamische Module oder +  DSOs genannt werden. + Standardmäßig eingebundene Module werden Basismodule + genannt. Für den Apache sind viele Module verfügbar, die nicht + als Bestandteil des  Apache-HTTP-Server-Tarballs ausgeliefert + werden. Diese werden als Drittmodule bezeichnet.
    + Siehe: Modulverzeichnis +
    + +
    Module-Magic-Number + [ˈmɔjuːl mædʒik + ˈnʌmbə] + (MMN)
    +
    Die Module-Magic-Number ist eine Konstante, die im Apache-Quelltext + definiert ist und im Zusammenhang mit der Binärkompatibilität + von Modulen steht. Sie wird geändert, wenn sich interne + Apache-Strukturen, -Funktionen oder andere signifikante Teile der API + derart ändern, dass eine Binärkompatibilität nicht mehr + gewährleistet werden kann. Bei einer MMN-Änderung müssen + alle Module von Drittanbietern zumindest neu kompiliert und zuweilen auch + geringfügig angepaßt werden, um mit der neuen Apache-Version zu + funktionieren. +
    + +
    Öffentlicher + Schlüssel
    +
    Der öffentlich verfügbare Schlüssel in einem  Public-Key-Kryptographie-System, + mit dem für seinen Eigentümer bestimmte Nachrichten + verschlüsselt und Signaturen von seinem Eigentümer + entschlüsselt werden.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    OpenSSL + [ˈəupənɛsɛsˈɛl] +
    +
    Das Open-Source-Toolkit für SSL/TLS
    + Siehe: http://www.openssl.org/ +
    + +
    Passphrase + [paːfreiz]
    +
    Das Wort oder die Phrase, welches private Schlüssel-Dateien + schützt. Sie verhindert die Entschlüsselung durch nicht + authorisierte Benutzer. Normalerweise ist dies einfach der geheimen + (De-)Codierungsschlüssel, der für  Chiffren verwendet wird.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Privater Schlüssel
    +
    Der geheime Schlüssel in einem  Public-Key-Kryptographie-System, + mit dem hereinkommende Nachrichten decodiert und ausgehende signiert + werden.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Proxy
    +
    Ein zwischen dem Client und dem ursprünglichen Server + (Anm.d.Ü.: der Server, den der Client tatsächlich erreichen + möchte) liegender Server. Er nimmt Anfragen von + Clients entgegen, übermittelt diese Anfragen dem + ursprünglichen Server und liefert die Antwort des + ursprünglichen Servers an den Client zurück. Wenn mehrere + Clients den gleichen Inhalt abfragen, dann kann der Proxy diesen Inhalt + aus seinem Zwischenspeicher ausliefern, anstatt ihn jedesmal vom + ursprünglichen Server anzufordern, und dadurch die Antwortzeit + verringern.
    + Siehe: mod_proxy +
    + +
    Public-Key-Kryptographie + [ˈpʌblik kiː + ˈkyptograˈfiː]
    +
    Theorie und Anwendung asymmetrischer Verschlüsselungssysteme, + die einen Schlüssel zur Verschlüsselung und einen anderen zur + Entschlüsselung verwenden. Zwei derart zusammengehörende + Schlüssel bilden Schüsselpaar. Man spricht auch von + "Asymetrischer Kryptographie".
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Regulärer + Ausdruck (Regex)
    +
    Eine Form, ein Muster im Text zu beschreiben - zum Beispiel: "alle + Wörter, die mit dem Buchstaben A beginnen" oder "Jeder Satz mit + zwei Kommata und ohne großes Q". Beim Apache sind reguläre + Ausdrücke hilfreich, da sie auf sehr flexible Art und Weise die + Anwendung bestimmter Eigenschaften auf eine Auswahl von Dateien oder + Ressourcen ermöglichen. - Zum Beispiel können alle .gif- und + .jpg-Dateien eines Verzeichnis "images" mit + "/images/.*(jpg|gif)$" beschrieben werden. Der Apache + verwendet Perl-kompatible reguläre Ausdrücke, wie sie die + PCRE-Bibliothek bereitstellt. +
    + +
    Reverse Proxy + [riːvəːs + ˈprɔksi]
    +
    Ein  Proxy-Server, der dem Client + gegenüber als ursprünglicher Server erscheint. Dies + ist nützlich, um den tatsächlichen Server aus + Sicherheitsgründen oder zur Lastverteilung vor dem Client zu + verstecken. +
    + +
    Secure Sockets + Layer [siˈkjuə ˈsɔkits + ˈleiə] (SSL)
    +
    Ein von der Firma Netscape Communications Corporation entwickeltes + Protokoll zur allgemeinen Authentisierung und Verschlüsselung der + Kommunikation über TCP/IP-Netzwerke. Die meistverbreitete Nutzung + ist HTTPS, d.h. HyperText Transfer Protocol (HTTP) über + SSL.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Server Side + Includes [səːə said + inˈkluːds] (SSI)
    +
    Eine Technik zum Einbetten von weiterverarbeitenden Anweisungen in + HMTL-Dateien.
    + Siehe: Einführung in Server Side + Includes +
    + +
    Session + [ˈseʃən]
    +
    Allgemein der Kontext einer Kommunikation.
    + +
    SSLeay
    +
    Die Bibliothek der Original-SSL/TLS-Implementation von Eric A. + Young
    + +
    Symmetrische Kryptographie
    +
    Die Theorie und Anwendung von Chiffren, die einen einzigen + geheimen Schlüssel sowohl zur Verschlüsswelung als auch zur + Entschlüsselung benutzen.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Tarball + [taːbɔːl]
    +
    Ein Paket von Dateien, die mit dem Hilfsprogramm tar + zusammengefasst wurden. Apache-Distributionen werden in komprimierten + tar-Archiven oder unter Verwendung von pkzip gespeichert. +
    + +
    Transport + Layer Security [trænsˈpɔːt + ˈeiə siˈkjuəriti] + (TLS)
    +
    Das SSL-Nachfolgeprotokoll, das von der Internet Engineering Task + Force (IETF) zur allgemeinen Authentisierung und Verschlüsselung + einer Kommunikation über TCP/IP-Netzwerke entwickelt worden ist. + TLS Version 1 ist nahezu identisch mit SSL Version 3.
    + Siehe: SSL/TLS-Verschlüsseliung +
    + +
    Umgebungsvariable (env-Variable)
    +
    Benannte, von der Betriebssystem-Shell verwaltete Variablen zur + Speicherung von Informationen und zur Kommunikation zwischen Programmen. + Der Apache beinhaltet auch interne Variablen, die ebenfalls + Umgebungsvariablen genannt werden, die aber statt in der + Shell-Umgebung in internen Apache-Strukturen gespeichert sind.
    + Siehe: Umgebungsvariablen im Apache +
    + +
    Uniform + Resource Locator [ˈjuːnifɔːm + riˈsɔːs ləuˈkeitə] + (URL)
    +
    Der Name bzw. die Adresse einer Ressource im Internet. Dies ist der + allgemein gebräuchliche Audruck für die formale Bezeichnung +  Uniform Resource + Identifier. URLs bestehen üblicherweise aus einem + Schema wie http oder https, einem Hostnamen + und einem Pfad. Die URL für diese Seite ist + http://httpd.apache.org/docs-2.1/glossary.html. +
    + +
    Uniform Resource Identifier + [ˈjuːnifɔːm + riˈsɔːs aiˈdentifaiə] + (URI)
    +
    Eine kompakte Zeichenfolge zur Identifizierung einer abstrakten oder + physischen Ressource. Er wird in dem RFC 2396 formell + definiert. Im World Wide Web verwendete URIs werden üblicherweise + als  URLs bezeichnet. +
    + +
    Virtual-Hosting + [vəˈtjuəl + həustiŋ]
    +
    Die Bedienung mehrere Websites mit einer einzigen Apache-Instanz. + IP-basierte virtuelle Hosts unterscheiden zwischen + verschiedenen Websites aufgrund ihrer IP-Adressen, während + namensbasierte virtuelle Hosts nur den Namen des Hosts + verwenden und daher mehrere Angebote unter der gleichen IP-Adresse + hosten können.
    + Siehe: Apache-Dokumentation zu virtuellen + Hosts +
    + +
    Voll-qualifizierter Domainname + (FQDN)
    +
    Der eindeutige Name einer Netzwerkeinheit, bestehend aus einem + Hostnamen und dem Domainnamen, welcher zu einer IP-Adresse + aufgelöst werden kann. Zum Beispiel ist www ein + Hostname, example.com ein Domainname und + www.example.com ein voll-qualifizierter Domainname. +
    + + +
    Website + [websait]
    +
    Im Gegensatz zur Webseite, die einer konkreten URL entspricht, ist mit + Website ein komplettes Angebot unter einem bestimmten Hostnamen (und Port) + gemeint. Dieses kann aus vielen verschiedenen Webseiten bestehen. +
    + +
    X.509
    +
    Ein von der International Telecommunication Union (ITU-T) empfohlenes + Schema für Authentifizierungszertifikate. Es wird für + SSL/TLS-Authentifizierungen verwendet.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Zertifikat
    +
    Ein Datensatz zur  Authentisierung einer + Nertzwerkeinheit wie Server oder Client. Ein Zertifikat + enthält  X.509-Informationen + über seinen Eigentümer (das sogenannte Betreff + (Anm.d.Ü.: engl.: subject)) und die + signierende  Certification + Authority (der sogenannte Aussteller (Anm.d.Ü.: engl.: + issuer)) sowie den  öffentlichen Schlüssel des + Eigentümers und die Signatur der CA. Netzwerkeinheiten + überprüfen diese Signatur mit Hilfe von CA-Zertifikaten.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Zugriffskontrolle
    +
    Die Beschränkung des Zugriffs auf Netzwerkbereiche. Im + Apache-Kontext in der Regel die Zugriffsbeschränkung auf bestimmte + URLs.
    + Siehe: Authentisierung, Autorisierung und + Zugriffskontrolle +
    +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/glossary.html.en b/trunk/docs/manual/glossary.html.en new file mode 100644 index 0000000000..f0b63686a9 --- /dev/null +++ b/trunk/docs/manual/glossary.html.en @@ -0,0 +1,448 @@ + + + +Glossary - Apache HTTP Server + + + + + +
    <-
    +

    Glossary

    +
    +

    Available Languages:  de  | + en  | + es  | + ko 

    +
    + +

    This glossary defines some of the common terminology related to Apache in + particular, and web serving in general. More information on each concept + is provided in the links.

    +
    +
    top
    +
    +

    Definitions

    + +
    +
    Access Control
    +
    The restriction of access to network realms. In an Apache context + usually the restriction of access to certain URLs.
    See: Authentication, Authorization, and Access + Control +
    + +
    Algorithm
    + +
    An unambiguous formula or set of rules for solving a problem in a finite + number of steps. Algorithms for encryption are usually called + Ciphers. +
    + +
    APache + eXtension Tool (apxs)
    +
    A perl script that aids in compiling  module sources into Dynamic Shared Objects + ( DSOs) and helps install them in the + Apache Web server.
    + See: Manual Page: apxs +
    + +
    Authentication
    +
    The positive identification of a network entity such as a server, a + client, or a user.
    + See: Authentication, Authorization, and Access + Control +
    + +
    Certificate
    +
    A data record used for authenticating network entities such + as a server or a client. A certificate contains X.509 information pieces + about its owner (called the subject) and the signing  Certification Authority (called + the issuer), plus the owner's  public + key and the + signature made by the CA. Network entities verify these signatures + using CA certificates.
    + See: SSL/TLS Encryption +
    + +
    Certificate Signing Request + (CSR)
    +
    An unsigned  certificate for + submission to a  Certification + Authority, which signs it with the  Private Key of their CA + Certificate. Once the CSR is signed, it becomes a real + certificate.
    + See: SSL/TLS Encryption +
    + +
    Certification Authority + (CA)
    +
    A trusted third party whose purpose is to sign certificates for network + entities it has authenticated using secure means. Other network entities + can check the signature to verify that a CA has authenticated the bearer + of a certificate.
    + See: SSL/TLS Encryption +
    + +
    Cipher
    +
    An algorithm or system for data encryption. Examples are DES, IDEA, RC4, + etc.
    + See: SSL/TLS Encryption +
    + +
    Ciphertext
    +
    The result after  Plaintext is + passed through a  Cipher.
    See: SSL/TLS Encryption +
    + +
    Common + Gateway Interface (CGI)
    +
    A standard definition for an interface between a web server and an + external program that allows the external program to service requests. + The interface was originally defined by NCSA but there + is also an RFC project.
    + See: Dynamic Content with CGI +
    + +
    Configuration Directive
    +
    See:  Directive
    + +
    Configuration + File
    +
    A text file containing  Directives + that control the configuration of Apache.
    + See: Configuration Files +
    + +
    CONNECT
    +
    An HTTP  method for proxying raw data + channels over HTTP. It can be used to encapsulate other protocols, such as + the SSL protocol. +
    + +
    Context
    +
    An area in the  configuration + files where certain types of  directives are allowed.
    + See: Terms Used to Describe + Apache Directives +
    + +
    Digital + Signature
    +
    An encrypted text block that validates a certificate or other file. A +  Certification Authority + creates a signature by generating a hash of the Public Key + embedded in a Certificate, then encrypting the hash with its own + Private Key. Only the CA's public key can decrypt the signature, + verifying that the CA has authenticated the network entity that owns the + Certificate.
    + See: SSL/TLS Encryption +
    + +
    Directive
    +
    A configuration command that controls one or more aspects of Apache's + behavior. Directives are placed in the  Configuration File
    + See: Directive Index +
    + +
    Dynamic + Shared Object (DSO)
    +
     Modules compiled separately from the + Apache httpd binary that can be loaded on-demand.
    + See: Dynamic Shared Object Support +
    + +
    Environment + Variable (env-variable)
    +
    Named variables managed by the operating system shell and used to store + information and communicate between programs. Apache also contains + internal variables that are referred to as environment variables, but are + stored in internal Apache structures, rather than in the shell + environment.
    + See: Environment Variables in Apache +
    + +
    Export-Crippled
    +
    Diminished in cryptographic strength (and security) in order to comply + with the United States' Export Administration Regulations (EAR). + Export-crippled cryptographic software is limited to a small key size, + resulting in Ciphertext which usually can be decrypted by brute + force.
    + See: SSL/TLS Encryption +
    + +
    Filter
    +
    A process that is applied to data that is sent or received by the + server. Input filters process data sent by the client to the server, + while output filters process documents on the server before they are sent + to the client. For example, the INCLUDES output filter + processes documents for  Server Side + Includes.
    + See: Filters +
    + +
    Fully-Qualified Domain-Name + (FQDN)
    +
    The unique name of a network entity, consisting of a hostname and a + domain name that can resolve to an IP address. For example, + www is a hostname, example.com is a domain name, + and www.example.com is a fully-qualified domain name. +
    + +
    Handler
    +
    An internal Apache representation of the action to be performed when a + file is called. Generally, files have implicit handlers, based on the file + type. Normally, all files are simply served by the server, but certain + file types are "handled" separately. For example, the + cgi-script handler designates files to be processed as +  CGIs.
    + See: Apache's Handler Use +
    + +
    Hash
    +
    A mathematical one-way, irreversable algorithm generating a string with + fixed-length from another string of any length. Different input strings + will usually produce different hashes (depending on the hash function). +
    + +
    Header
    +
    The part of the  HTTP request and + response that is sent before the actual content, and that contains + meta-information describing the content. +
    + +
    .htaccess
    +
    A  configuration file that + is placed inside the web tree and applies configuration  directives to the directory where it is + placed and all sub-directories. Despite its name, this file can hold + almost any type of directive, not just access-control directives.
    + See: Configuration Files +
    + +
    httpd.conf
    +
    The main Apache  configuration + file. The default location is + /usr/local/apache2/conf/httpd.conf, but it may be moved using + run-time or compile-time configuration.
    + See: Configuration Files +
    + +
    HyperText Transfer Protocol + (HTTP)
    +
    The standard transmission protocol used on the World Wide Web. Apache + implements version 1.1 of the protocol, referred to as HTTP/1.1 and + defined by RFC 2616. +
    + +
    HTTPS
    +
    The HyperText Transfer Protocol (Secure), the standard encrypted + communication mechanism on the World Wide Web. This is actually just HTTP + over  SSL.
    + See: SSL/TLS Encryption +
    + +
    Method
    +
    In the context of  HTTP, an action to + perform on a resource, specified on the request line by the client. Some + of the methods available in HTTP are GET, POST, + and PUT. +
    + +
    Message Digest
    +
    A hash of a message, which can be used to verify that the contents of + the message have not been altered in transit.
    + See: SSL/TLS Encryption +
    + +
    MIME-type
    +
    A way to describe the kind of document being transmitted. Its name + comes from that fact that its format is borrowed from the Multipurpose + Internet Mail Extensions. It consists of a major type and a minor type, + separated by a slash. Some examples are text/html, + image/gif, and application/octet-stream. In + HTTP, the MIME-type is transmitted in the Content-Type +  header.
    + See: mod_mime +
    + +
    Module
    +
    An independent part of a program. Much of Apache's functionality is + contained in modules that you can choose to include or exclude. Modules + that are compiled into the Apache httpd binary are + called static modules, while modules that are stored + separately and can be optionally loaded at run-time are called + dynamic modules or  DSOs. + Modules that are included by default + are called base modules. Many modules are available for Apache + that are not distributed as part of the Apache HTTP Server  tarball. These are referred to as + third-party modules.
    + See: Module Index +
    + +
    Module Magic + Number (MMN)
    +
    Module Magic Number is a constant defined in the Apache source code that + is associated with binary compatibility of modules. It is changed when + internal Apache structures, function calls and other significant parts of + API change in such a way that binary compatibility cannot be guaranteed + any more. On MMN change, all third party modules have to be at least + recompiled, sometimes even slightly changed in order to work with the new + version of Apache. +
    + +
    OpenSSL
    +
    The Open Source toolkit for SSL/TLS
    + See http://www.openssl.org/# +
    + +
    Pass Phrase
    +
    The word or phrase that protects private key files. It prevents + unauthorized users from encrypting them. Usually it's just the secret + encryption/decryption key used for  Ciphers.
    + See: SSL/TLS Encryption +
    + +
    Plaintext
    +
    The unencrypted text.
    + +
    Private Key
    +
    The secret key in a  Public Key + Cryptography system, used to decrypt incoming messages and + sign outgoing ones.
    + See: SSL/TLS Encryption +
    + +
    Proxy
    +
    An intermediate server that sits between the client and the origin + server. It accepts requests from clients, transmits those requests + on to the origin server, and then returns the response from the origin + server to the client. If several clients request the same content, the + proxy can deliver that content from its cache, rather than requesting it + from the origin server each time, thereby reducing response time.
    + See: mod_proxy +
    + +
    Public Key
    +
    The publicly available key in a  Public Key Cryptography system, + used to encrypt messages bound for its owner and to decrypt signatures + made by its owner.
    + See: SSL/TLS Encryption +
    + +
    Public Key Cryptography
    +
    The study and application of asymmetric encryption systems, which use + one key for encryption and another for decryption. A corresponding pair of + such keys constitutes a key pair. Also called Asymmetric Cryptography. +
    + See: SSL/TLS Encryption +
    + +
    Regular Expression + (Regex)
    +
    A way of describing a pattern in text - 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 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)$". Apache uses Perl + Compatible Regular Expressions provided by the PCRE library. +
    + +
    Reverse Proxy
    +
    A  proxy server that appears to the client + as if it is an origin server. This is useful to hide the real + origin server from the client for security reasons, or to load balance. +
    + +
    Secure Sockets + Layer (SSL)
    +
    A protocol created by Netscape Communications Corporation for general + communication authentication and encryption over TCP/IP networks. The most + popular usage is HTTPS, i.e. the HyperText Transfer Protocol (HTTP) + over SSL.
    + See: SSL/TLS Encryption +
    + +
    Server Side + Includes (SSI)
    +
    A technique for embedding processing directives inside HTML files.
    + See: Introduction to Server Side Includes +
    + +
    Session
    +
    The context information of a communication in general.
    + +
    SSLeay
    +
    The original SSL/TLS implementation library developed by Eric A. + Young +
    + +
    Symmetric + Cryptography
    +
    The study and application of Ciphers that use a single secret key + for both encryption and decryption operations.
    + See: SSL/TLS Encryption +
    + +
    Tarball
    +
    A package of files gathered together using the tar utility. + Apache distributions are stored in compressed tar archives or using + pkzip. +
    + +
    Transport + Layer Security (TLS)
    +
    The successor protocol to SSL, created by the Internet Engineering Task + Force (IETF) for general communication authentication and encryption over + TCP/IP networks. TLS version 1 and is nearly identical with SSL version + 3.
    + See: SSL/TLS Encryption +
    + +
    Uniform + Resource Locator (URL)
    +
    The name/address of a resource on the Internet. This is the common + informal term for what is formally called a  Uniform Resource Identifier. + URLs are usually made up of a scheme, like http or + https, a hostname, and a path. A URL for this page is + http://httpd.apache.org/docs-2.1/glossary.html. +
    + +
    Uniform Resource Identifier + (URI)
    +
    A compact string of characters for identifying an abstract or physical + resource. It is formally defined by RFC 2396. URIs used on the + world-wide web are commonly referred to as  URLs. +
    + +
    Virtual Hosting
    +
    Serving multiple websites using a single instance of Apache. IP + virtual hosting differentiates between websites based on their IP + address, while name-based virtual hosting uses only the name of the + host and can therefore host many sites on the same IP address.
    + See: Apache Virtual Host documentation +
    + +
    X.509
    +
    An authentication certificate scheme recommended by the International + Telecommunication Union (ITU-T) which is used for SSL/TLS authentication.
    See: SSL/TLS Encryption +
    +
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/glossary.html.es b/trunk/docs/manual/glossary.html.es new file mode 100644 index 0000000000..247126f267 --- /dev/null +++ b/trunk/docs/manual/glossary.html.es @@ -0,0 +1,395 @@ + + + +Glosario - Servidor HTTP Apache + + + + + +
    <-
    +

    Glosario

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Este glosario define la terminología más común +relacionada con Apache en particular y con los servidores web en +general. En los enlaces que hay asociados a cada término se puede +encontrar información más detallada.

    +
    +
    top
    +
    +

    Definiciones

    + +
    +
    Autentificación
    La +identificación positiva de una entidad de red tal como un +servidor, un cliente, o un usuario.
    Consulte: Autentificación, Autorización, y +Control de Acceso
    + +
    Control de Acceso
    La +restricción en el acceso al entorno de una red. En el contexto de +Apache significa normalmente la restricción en el acceso a +ciertas URLs.
    Consulte: Autentificación, Autorización, y +Control de Acceso
    + +
    Algoritmo
    Un proceso definido sin +ambiguedades o un conjunto de reglas para solucionar un problema en un +número finito de pasos. Los algoritmos para encriptar se llaman +normalmente algoritmos de cifrado.
    + +
    Herramienta de extensión de +Apache (apxs)
    Es un script escrito en +Perl que ayuda a compilar el código fuente de algunos módulos para convertirlos en Objetos Dinamicos +Compartidos (DSOs) y ayuda a instalarlos en el +servidor web Apache.
    Consulte: Paginas de Ayuda: apxs
    + +
    Certificado
    + +
    Una información que se almacena para autentificar entidades + de red tales como un servidor o un cliente. Un certificado + contiene piezas de información X.509 sobre su poseedor + (llamado sujeto) y sobre la Autoridad Certificadora + (llamada el expendedor) que lo firma, más la clave publica del propietario y la firma de + la AC. Las entidades de red verifican las firmas usando + certificados de las AC.
    + +Consulte: Encriptado SSL/TLS
    + +
    Autoridad Certificadora (CA)
    Una entidad externa de confianza cuyo fin +es firmar certificados para las entidades de red que ha autentificado +usando medios seguros. Otras entidades de red pueden verificar la +firma para comprobar que una Autoridad Certificadora ha autentificado +al poseedor del certificado.
    Consulte: Encriptado +SSL/TLS
    + +
    Petición de firma de +Certificado (CSR)
    Es la petición a +una Autoridad Certificadora para +que firme un certificado aún sin +firmar. La Autoridad Certificadora firma el Certificado con +la Clave Privada de su certificado de Autoridad Certificadora. Una +vez que el CSR está firmado, se convierte en un auténtico +certificado.
    Consulte: Encriptado +SSL/TLS
    + + +
    Algoritmo de cifrado
    Es un algoritmo +o sistema de encriptado de información. Ejemplos de estos +algoritmos son DES, IDEA, RC4, etc.
    Consulte: Encriptado SSL/TLS
    + +
    Texto cifrado
    El resultado de +haber aplicado a un texto sin cifrar un algoritmo de cifrado.
    Consultar: Encriptado SSL/TLS
    + +
    Common Gateway Interface (CGI)
    Una definición estándar para +un interfaz entre un servidor web y un programa externo que permite +hacer peticiones de servicio a los programas externos. Este interfaz +fue definido originalmente por la NCSA pero +tambien hay un proyecto RFC.
    Consulte: Contenido Dinámico con CGI
    + + +
    Directivas de +configuración
    Consulte: Directivas
    + +
    Fichero de Configuración
    +
    Un fichero de texto que contiene Directivas que controlan la configuración +de Apache.
    Consulte: Ficheros de +Configuración
    + +
    CONNECT
    Un método de HTTP para hacer proxy a canales de +datos sin usar HTTP. Puede usarse para encapsular otros protocolos, +tales como el protocolo SSL.
    + +
    Contexto
    Un área en los ficheros de configuración donde +están permitidos ciertos tipos de directivas.
    Consulte: Terminos usados para describir +las directivas de Apache
    + +
    Firma Digital
    Un bloque de +texto encriptado que verifica la validez de un certificado o de otro +fichero. Una Autoridad +Certificadora crea una firma generando un hash a partir de la +Clave Pública que lleva incorporada en un +Certificado, después encriptando el hash con su propia +Clave Privada. Solo las claves públicas de las CAs +pueden desencriptar la firma, verificando que la CA ha autentificado a +la entidad de red propietaria del Certificado.
    +Consulte: Encriptado SSL/TLS
    + +
    Directiva
    Un comando de +configuración que controla uno o más aspectos del +comportamiento de Apache. Las directivas se ponen en el Fichero de Configuración
    +Consulte: Índice de +Directivas
    + +
    Objetos Dinámicos +Compartidos (DSO)
    Los Módulos compilados de forma separada al +binario httpd de Apache se pueden cargar según se necesiten.
    Consulte: Soporte de Objetos Dinámicos +Compartidos
    + +
    Variable de Entorno (env-variable)
    Variables que +gestionan el shell del sistema operativo y que se usan para guardar +información y para la comunicación entre programas. Apache +también contiene variables internas que son referidas como +variables de entorno, pero que son almacenadas en las estructuras +internas de Apache, en lugar de en el entorno del shell.
    +Consulte: Variables de entorno de Apache
    + +
    Export-Crippled
    +
    Disminución de la fortaleza criptográfica (y seguridad) +para cumplir con las Regulaciones sobre Exportación de la +Administracción de los Estados Unidos (EAR). El software +criptográfico Export-crippled está limitado a una clave de +pequeño tamaño, de tal manera que el texto cifrado +que se consigue con él, puede desencriptarse por fuerza bruta.
    Consulte: Encriptado SSL/TLS
    + +
    Filtro
    Un proceso que se aplica a la +información que es enviada o recibida por el servidor. Los +ficheros de entrada procesan la información enviada por un +cliente al servidor, mientras que los filtros de salida procesan la +información en el servidor antes de enviársela al +cliente. Por ejemplo, el filtro de salida INCLUDES +procesa documentos para Server Side Includes.
    +Consulte: Filtros
    + +
    Nombre de dominio +completamente qualificado (FQDN)
    El +nombre único de una entidad de red, que consiste en un nombre de +host y un nombre de dominio que puede traducirse a una dirección +IP. Por ejemplo, www es un nombre de host, +example.com es un nombre de dominio, y +www.example.com es un nombre de dominio completamente +qualificado.
    + +
    Handler
    Es una representación +interna de Apache de una acción a ser ejecutada cuando se llama a +un fichero. Generalmente, los ficheros tienen un handler +implícito, basado en el tipo de fichero. Normalmente, todos los +ficheros son simplemente servidos por el servidor, pero sobre algunos +tipos de ficheros se ejecutan acciones complementarias. Por ejemplo, +el handler cgi-script designa los ficheros a ser +procesados como CGIs.
    Consulte: Uso de Handlers en Apache
    + +
    Cabecera
    La parte de la +petición y la respuesta HTTP que se +envía antes del contenido propiamente dicho, y que contiene +meta-información describiendo el contenido.
    + +
    .htaccess
    Un fichero de configuración que se +pone dentro de la estructura de directorios del sitio web y aplica directivas de configuración al directorio +en el que está y a sus subdirectorios. A pesar de su nombre, este +fichero puede contener cualquier tipo de directivas, no solo +directivas de control de acceso.
    Consulte: Ficheros de Configuración
    + +
    httpd.conf
    Es el fichero de configuración principal +de Apache. Su ubicación por defecto es +/usr/local/apache2/conf/httpd.conf, pero puede moverse +usando opciones de configuración al compilar o al iniciar +Apache.
    Consulte: Ficheros de +Configuración
    + +
    Protocolo de Tranferencia de +Hipertexto (HTTP)
    Es el protocolo de +transmisión estádar usado en la World Wide Web. Apache +implementa la versión 1.1 de este protocolo, al que se hace +referencia como HTTP/1.1 y definido por el RFC 2616.
    + +
    HTTPS
    Protocolo de transferencia de +Hipertext (Seguro), es el mecanismo de comunicación encriptado +estándar en World Wide Web. En realidad es HTTP sobre SSL.
    Consulte: Encriptado +SSL/TLS
    + +
    Método
    En el contexto de HTTP, es una acción a ejecutar sobre un recurso, +especificado en la líneas de petición por el cliente. +Algunos de los metodos diponibles en HTTP son GET, +POST, y PUT.
    + +
    Message Digest
    Un hash de un +mensaje, el cual pude ser usado para verificar que el contenido del +mensaje no ha sido alterado durante la transmisión.
    +Consulte: Encriptado SSL/TLS
    + +
    MIME-type
    Una manera de describir +el tipo de documento a ser transmitido. Su nombre viene del hecho de +que su formato se toma de las Extensiones del Multipurpose Internet +Mail. Consiste en dos componentes, uno principal y otro secundario, +separados por una barra. Algunos ejemplos son text/html, +image/gif, y application/octet-stream. En +HTTP, el tipo MIME se transmite en la cabecera +del Tipo Contenido.
    Consulte: mod_mime
    + +
    Módulo
    Una parte independiente +de un programa. La mayor parte de la funcionalidad de Apache +está contenida en módulos que pueden incluirse o excluirse. +Los módulos que se compilan con el binario httpd de Apache se +llaman módulos estáticos, mientras que los que se +almacenan de forma separada y pueden ser cargados de forma opcional, +se llaman módulos dinamicos o DSOs. +Los módulos que están incluidos por sefecto de llaman +módulos base. Hay muchos módulos disponibles para +Apache que no se distribuyen con la tarball del +Servidor HTTP Apache . Estos módulos son llamados +módulos de terceros.
    Consulte: Índice de Módulos
    + +
    Número Mágico de +Módulo (MMN)
    El número +mágico de módulo es una constante definida en el código +fuente de Apache que está asociado con la compatibilidad binaria +de los módulos. Ese número cambia cuando cambian las +estructuras internas de Apache, las llamadas a funciones y otras +partes significativas de la interfaz de programación de manera +que la compatibilidad binaria no puede garantizarse sin cambiarlo. Si +cambia el número mágico de módulo, todos los +módulos de terceros tienen que ser al menos recompilados, y +algunas veces, incluso hay que introducir ligeras modificaciones para +que funcionen con la nueva versión de Apache
    + +
    OpenSSL
    +
    El toolkit Open Source para SSL/TLS
    + see http://www.openssl.org/
    + +
    Pass Phrase
    La palabra o frase +que protege los archivos de clave privada. Evita que usuarios no +autorizados los encripten. Normalmente es solo la clave de +encriptado/desencriptado usada por los Algoritmos de +Cifrado.
    Consulte: Encriptado +SSL/TLS
    + +
    Plaintext
    +
    Un texto no encriptado.
    + +
    Clave Privada
    La clave secreta +de un sistema criptográfico de +Clave Pública, usada para desencriptar los mensajes entrantes +y firmar los salientes.
    Consulte: Encriptado +SSL/TLS
    + +
    Proxy
    Un servidor intermedio que se +pone entre el cliente y el servidor de origen. Acepta las +peticiones de los clientes, las transmite al servidor de origen, y +después devuelve la respuesta del servidor de origen al +cliente. Si varios clientes piden el mismo contenido, el proxy sirve +el contenido desde su caché, en lugar de pedirlo cada vez que lo +necesita al servidor de origen, reduciendo con esto el tiempo de +respuesta.
    Consulte: mod_proxy
    + +
    Clave Publica
    La clave disponible +públicamente en un sistema +criptográfico de Clave Pública, usado para encriptar +mensajes destinados a su propietario y para desencriptar firmas hechas +por su propietario.
    Consulte: Encriptado +SSL/TLS
    + +
    Criptográfia de Clave +Pública
    El estudio y aplicación de sistemas de +encriptado asimétricos, que usa una clave para encriptar y otra +para desencriptar. Una clave de cada uno de estos tipos constituye un +par de claves. Tambien se llama Criptografia Asimétrica.
    +Consulte: Encriptado SSL/TLS
    + +
    Expresiones Regulares (Regex)
    Una forma de describir un modelo de +texto - por ejemplo, "todas las palabras que empiezan con la letra "A" +o "todos los números de teléfono que contienen 10 +dígitos" o incluso "Todas las frases entre comas, y que no +contengan ninguna letra Q". Las Expresiones Regulares son utiles en +Apache porque permiten aplicar ciertos atributos a colecciones de +ficheros o recursos de una forma flexible - por ejemplo, todos los +archivos .gif y .jpg que estén en un directorio "imágenes" +podrían ser escritos como "/images/.*(jpg|gif)$". +Apache usa Expresiones Regulares compatibles con Perl gracias a la +librería PCRE.
    + +
    Reverse Proxy
    Es un servidor +proxy que se presenta al cliente como si fuera un +servidor de origen. Es útil para esconder el +auténtico servidor de origen a los clientes por cuestiones de +seguridad, o para equilibrar la carga.
    + +
    Secure Sockets Layer (SSL)
    Un protocolo creado por Netscape +Communications Corporation para la autentificación en +comunicaciones en general y encriptado sobre redes TCP/IP. Su +aplicación más popular es HTTPS, el Protocolo de +Transferencia de Hipertexto (HTTP) sobre SSL.
    Consulte: Encriptado SSL/TLS
    + +
    Server Side Includes (SSI)
    Una tecnica para incluir directivas de +proceso en archivos HTML.
    Consulte: Introducción al Server Side +Includes
    + +
    Sesion
    Información del +contexto de una comunicación en general.
    + +
    SSLeay
    La implementación +original de la librería SSL/TLS desarrollada por Eric +A. Young
    + +
    Criptografía +Simétrica
    El estudio y aplicación de +Algoritmos de Cifrado que usan una solo clave secreta tanto +para encriptar como para desencriptar.
    Consulte: Encriptado SSL/TLS
    + +
    Tarball
    Un grupo de ficheros +puestos en un solo paquete usando la utilidad tar. Las +distribuciones Apache se almacenan en ficheros comprimidos con tar o +con pkzip.
    + +
    Transport Layer Security (TLS)
    Es el sucesor del protocolo SSL, creado +por el Internet Engineering Task Force (IETF) para la +autentificación en comunicaciones en general y encriptado sobre +redes TCP/IP. La versión 1 de TLS es casi idéntica a la +versión 3 de SSL.
    Consulte: Encriptado +SSL/TLS
    + +
    Localizador de Recursos +Uniforme (URL)
    El nombre de un recurso +en Internet. Es la manera informal de decir lo que formalmente se +llama un Identificador de +Recursos Uniforme. Las URLs están compuestas normalmente por +un esquema, tal como http o https, un nombre +de host, y una ruta. Una URL para esta página es +http://httpd.apache.org/docs-2.1/glossary.html.
    + +
    Identificador de Recursos +Uniforme (URI)
    Una cadena de caracteres +compacta para identificar un recurso físico o abstracto. Se +define formalmente en la RFC 2396. Los URIs que +se usan en world-wide web se refieren normalmente como URLs.
    + +
    Hosting Virtual
    Se trata de +servir diferentes sitios web con una sola entidad de Apache. El +hosting virtual de IPs diferencia los sitios web basandose en sus +direcciones IP, mientras que el hosting virtual basado en +nombres usa solo el nombre del host y de esta manera puede alojar +muchos sitios web con la misma dirección IP.
    Consulte: Documentación sobre Hosting Virtual en +Apache
    + +
    X.509
    Un esquema de certificado de +autentificación recomendado por la International +Telecommunication Union (ITU-T) que se usa en la autentificación +SSL/TLS.
    Consulte: Encriptado SSL/TLS
    + +
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/glossary.html.ko.euc-kr b/trunk/docs/manual/glossary.html.ko.euc-kr new file mode 100644 index 0000000000..33be57ee61 --- /dev/null +++ b/trunk/docs/manual/glossary.html.ko.euc-kr @@ -0,0 +1,364 @@ + + + +¿ë¾î - Apache HTTP Server + + + + + +
    <-
    +

    ¿ë¾î

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­´Â À¥ ¼­ºñ½º ÀϹݿ¡ ´ëÇÑ, ƯÈ÷ ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ, ¿ë¾îµéÀ» +Á¤ÀÇÇÑ´Ù. °¢ °³³ä¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â ¸µÅ©¸¦ Âü°íÇ϶ó. +(¿ªÁÖ; ÇöÀç ´Ü¾îÀÇ ¼ø¼­´Â ÇÑ±Û ¼ø¼­°¡ ¾Æ´Ï¶ó, ¿µ¹®ÀÚ +¼ø¼­ÀÔ´Ï´Ù. ¿ë¾î¹ø¿ªÇ¥´Â ¿©±â¸¦ +Âü°íÇÏ±æ ¹Ù¶ø´Ï´Ù.)

    +
    +
    top
    +
    +

    Á¤ÀÇ

    + +
    +
    Á¢±ÙÁ¦¾î (Access Control)
    +
    ³×Æ®¿÷ ¿µ¿ª¿¡ ´ëÇÑ Á¢±ÙÀ» Á¦ÇÑ. ¾ÆÆÄÄ¡¿¡¼­´Â º¸Åë ƯÁ¤ +URLÀÇ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ »ç¿ëÇÑ´Ù.
    Âü°í: ÀÎÁõ, ±ÇÇѺο©, Á¢±ÙÁ¦¾î
    + +
    ¾Ë°í¸®Áò (Algorithm)
    +
    À¯ÇÑÇÑ ´Ü°è¸¦ °ÅÃÄ ¹®Á¦¸¦ Ǫ´Â ¸íÈ®ÇÑ °ø½Ä ȤÀº ±ÔÄ¢µé. +¾Ïȣȭ¸¦ À§ÇÑ ¾Ë°í¸®ÁòÀ» º¸Åë ¾ÏÈ£±â(Ciphers)¶ó°í +ºÎ¸¥´Ù.
    + +
    APache eXtension Tool +(apxs)
    ¸ðµâ +(module) ¼Ò½º¸¦ µ¿Àû°øÀ¯°´Ã¼ (DSO)·Î +ÄÄÆÄÀÏÇÏ°í ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ ¼³Ä¡ÇÏ´Â ÀÛ¾÷À» µ½´Â perl +½ºÅ©¸³Æ®.
    Âü°í: Manpage: +apxs
    + +
    ÀÎÁõ (Authentication)
    +
    ¼­¹ö, Ŭ¶óÀ̾ðÆ®, »ç¿ëÀÚ µî ³×Æ®¿÷ ½Çü¿¡ ´ëÇÑ +È®ÀÎ.
    Âü°í: ÀÎÁõ, ±ÇÇѺο©, +Á¢±ÙÁ¦¾î
    + +
    ÀÎÁõ¼­ (Certificate)
    +
    ¼­¹ö³ª Ŭ¶óÀ̾ðÆ®¿Í °°Àº ³×Æ®¿÷ ½Çü¸¦ ÀÎÁõÇÏ´Â ÀÚ·á. + ÀÎÁõ¼­¿¡´Â ¼ÒÀ¯ÀÚ (subject¶ó°í ÇÔ), ¼­¸í ÀÎÁõ±â°ü (Certificate + Authority) (issuer¶ó°í ÇÔ), ¼ÒÀ¯ÀÚÀÇ °ø°³Å°, CA°¡ ¸¸µç ¼­¸í µî¿¡ ´ëÇÑ + X.509 Á¤º¸°¡ ÀÖ´Ù. ³×Æ®¿÷ ½Çü´Â CA ÀÎÁõ¼­¸¦ »ç¿ëÇÏ¿© + ¼­¸íÀ» °Ë»çÇÑ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÀÎÁõ ¼­¸í ¿äû (Certificate +Signing Request, CSR)
    ÀÎÁõ±â°ü (Certification +Authority)¿¡ Á¦ÃâÇÏ¿© CA ÀÎÁõ¼­ (Certificate)ÀÇ +°³ÀÎÅ° (Private Key)·Î ¼­¸íµÉ ¾ÆÁ÷ +¼­¸íµÇÁö¾ÊÀº ÀÎÁõ¼­. CSRÀÌ ¼­¸íµÇ¸é +½ÇÁ¦ ÀÎÁõ¼­°¡ µÈ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÀÎÁõ±â°ü (Certification +Authority, CA)
    ¾ÈÀüÇÑ ¹æ¹ýÀ¸·Î +³×Æ®¿÷ ½Çü¿¡ ´ëÇÑ ÀÎÁõÀ» ¼­¸íÇÏ´Â ½Å·ÚÇÏ´Â Á¦»ïÀÚ. ´Ù¸¥ ³×Æ®¿÷ +½ÇüµéÀº ¼­¸íÀ¸·Î CA°¡ ÀÎÁõ¼­ ¼ÒÀ¯ÀÚ¸¦ ÀÎÁõÇß´ÂÁö È®ÀÎÇÒ ¼ö +ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¾ÏÈ£±â (Cipher)
    ÀڷḦ +¾ÏȣȭÇÏ´Â ¾Ë°í¸®ÁòÀ̳ª ½Ã½ºÅÛ. ¿¹¸¦ µé¾î, DES, IDEA, RC4 µîÀÌ ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¾ÏÈ£¹® (Ciphertext)
    Æò¹® (Plaintext)À» ¾ÏÈ£±â +(Cipher)·Î ó¸®ÇÑ °á°ú.
    Âü°í: SSL/TLS +¾Ïȣȭ
    + +
    °øÅë °ÔÀÌÆ®¿þÀÌ ÀÎÅÍÆäÀ̽º +(Common Gateway Interface, CGI)
    +
    ¿ÜºÎ ÇÁ·Î±×·¥ÀÌ ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖµµ·Ï ¸¸µç À¥¼­¹ö¿Í ¿ÜºÎ +ÇÁ·Î±×·¥ »çÀÌÀÇ ÀÎÅÍÆäÀ̽º Ç¥ÁØ. ÀÎÅÍÆäÀ̽º´Â ¿ø·¡ NCSA°¡ +Á¤ÀÇÇßÁö¸¸, RFC +ÇÁ·ÎÁ§Æ®À̱⵵ ÇÏ´Ù.
    +Âü°í: CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º
    + + +
    ¼³Á¤ Áö½Ã¾î (Configuration +Directive)
    +
    Âü°í: Áö½Ã¾î
    + +
    ¼³Á¤ÆÄÀÏ (Configuration File)
    +
    ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÏ´Â Áö½Ã¾î (directive)¸¦ +Àû¾îµÐ ÅؽºÆ®ÆÄÀÏ.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    CONNECT
    +
    HTTP¸¦ ÅëÇØ ÀÚ·áÈ帧À» ÇÁ·Ï½ÃÇÏ´Â HTTP ¸Þ½áµå +(method). SSL ÇÁ·ÎÅäÄÝ µî ´Ù¸¥ ÇÁ·ÎÅäÄÝÀ» °¨½Î±âÀ§ÇØ »ç¿ëÇÑ´Ù.
    + +
    »ç¿ëÀå¼Ò (Context)
    ¼³Á¤ÆÄÀÏ (configuration file)¿¡¼­ +ƯÁ¤ Áö½Ã¾î (directive)¸¦ »ç¿ëÇÒ ¼ö +ÀÖ´Â Àå¼Ò.
    Âü°í: ¾ÆÆÄÄ¡ Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ +»ç¿ëÇÑ ¿ë¾îÁ¤ÀÇ
    + +
    ÀüÀÚ¼­¸í (Digital Signature)
    +
    ÀÎÁõ¼­³ª ´Ù¸¥ ÆÄÀÏÀ» °Ë»çÇÏ´Â ¾ÏȣȭµÈ ¹®ÀÚµé. ÀÎÁõ±â°ü (Certification + Authority)Àº ÀÎÁõ¼­ (Certificate)¿¡ Æ÷ÇÔµÈ + °ø°³Å° (Public Key)¸¦ Çؽ¬ÇÑ °á°ú¸¦ ÀÚ½ÅÀÇ + °³ÀÎÅ° (Private Key)·Î ¾ÏȣȭÇÏ¿© ¼­¸íÀ» ¸¸µç´Ù. + ¿ÀÁ÷ CAÀÇ °ø°³Å°¸¸ÀÌ ¼­¸íÀ» Ç® ¼ö Àֱ⶧¹®¿¡, CA°¡ ÀÎÁõ¼­ + (Certificate)¸¦ °¡Áø ³×Æ®¿÷ ½Çü¸¦ ÀÎÁõÇßÀ½À» Áõ¸íÇÒ + ¼ö ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Áö½Ã¾î (Directive)
    ¾ÆÆÄÄ¡ÀÇ +¿©·¯ ±â´ÉÀ» Á¶ÀýÇÏ´Â ¼³Á¤ ¸í·É¾î. Áö½Ã¾î´Â ¼³Á¤ÆÄÀÏ (Configuration File)¿¡¼­ +»ç¿ëÇÑ´Ù.
    Âü°í: Áö½Ã¾î ¸ñ·Ï
    + +
    µ¿Àû°øÀ¯°´Ã¼ (Dynamic Shared +Object) (DSO)
    ¾ÆÆÄÄ¡ httpd +½ÇÇàÆÄÀÏ°ú º°µµ·Î ÄÄÆÄÀÏÇÏ¿© ÇÊ¿äÇÒ¶§ ÀоîµéÀÏ ¼ö ÀÖ´Â ¸ðµâ (Module).
    +Âü°í: µ¿Àû°øÀ¯°´Ã¼ Áö¿ø
    + +
    ȯ°æº¯¼ö (Environment Variable) +(env-variable)
    +
    Á¤º¸¸¦ ÀúÀåÇÏ°í ÇÁ·Î±×·¥°£¿¡ Åë½ÅÀ» À§ÇØ ¿î¿µÃ¼Á¦ ½©ÀÌ °ü¸®ÇÏ´Â +º¯¼ö. ¾ÆÆÄÄ¡¿¡µµ ȯ°æº¯¼ö¶ó´Â ³»ºÎ º¯¼ö°¡ ÀÖÁö¸¸, ½© ȯ°æÀÌ +¾Æ´Ï¶ó ¾ÆÆÄÄ¡ ³»ºÎ¿¡ ÀúÀåµÈ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö
    + +
    ¼öÃâ¿ë (Export-Crippled)
    +
    ¹Ì±¹ ¼öÃâ°ü¸®±ÔÁ¦(Export Administration Regulations, EAR)¸¦ + ÁؼöÇϱâÀ§ÇØ ¾ÏÈ£(¿Í º¸¾È)ÀÇ °­µµ¸¦ ³·Ãã. ¼öÃâ¿ë ¾Ïȣȭ + ¼ÒÇÁÆ®¿þ¾î´Â Å° Å©±â°¡ ÀÛ°Ô Á¦ÇѵǾî, ¾ÏÈ£¹® + (Ciphertext)À» ¹«½ÄÇÑ ¹æ¹ý(brute force)À¸·Î Ç® ¼ö ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ (SSL/TLS Encryption)
    + +
    ÇÊÅÍ (Filter)
    +
    ¼­¹ö°¡ º¸³»°Å³ª ¹Þ´Â ÀڷḦ ó¸®ÇÏ´Â °úÁ¤. ÀÔ·ÂÇÊÅÍ´Â +Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö·Î º¸³»´Â ÀڷḦ ó¸®ÇÏ°í, Ãâ·ÂÇÊÅÍ´Â ¼­¹ö°¡ +Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³¾ ¹®¼­¸¦ ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, +INCLUDES Ãâ·ÂÇÊÅÍ´Â ¹®¼­ÀÇ Server +Side Includes¸¦ ó¸®ÇÑ´Ù.
    +Âü°í: ÇÊÅÍ
    + +
    ¿ÏÀüÇÑ µµ¸ÞÀθí +(Fully-Qualified Domain-Name) (FQDN)
    +
    IP ÁÖ¼Ò¿¡ ´ëÀÀÇÏ´Â, È£½ºÆ®¸í°ú µµ¸ÞÀθíÀ¸·Î ±¸¼ºµÈ ³×Æ®¿÷ +½ÇüÀÇ À¯ÀÏÇÑ À̸§. ¿¹¸¦ µé¾î, www°¡ È£½ºÆ®¸íÀÌ°í +example.comÀÌ µµ¸ÞÀθíÀ϶§, +www.example.comÀº ¿ÏÀüÇÑ µµ¸ÞÀθíÀÌ´Ù.
    + +
    Çڵ鷯 (Handler)
    +
    ÆÄÀÏÀ» ¿äûÇÒ¶§ ¼öÇàÇÏ´Â ÀÛ¾÷¿¡ ´ëÇÑ ¾ÆÆÄÄ¡ ³»ºÎ Ç¥Çö. +ÀϹÝÀûÀ¸·Î ÆÄÀÏÀº ÆÄÀÏ Á¾·ù¿¡ µû¶ó ¾Ï¹¬ÀûÀÎ Çڵ鷯¸¦ °¡Áø´Ù. +º¸Åë ¸ðµç ÆÄÀÏÀº ¼­¹ö°¡ °£´ÜÈ÷ ¼­ºñ½ºÇÏÁö¸¸, ¾î¶² ÆÄÀÏ Á¾·ù´Â +µû·Î "󸮵ȴÙ(handled)". ¿¹¸¦ µé¾î, cgi-script +Çڵ鷯´Â CGI·Î ó¸®ÇÒ ÆÄÀÏÀ» ÁöÁ¤ÇÑ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë
    + +
    Çì´õ (Header)
    +
    HTTP ¿äû°ú ÀÀ´ä¿¡¼­ ½ÇÁ¦ ³»¿ë ÀÌÀü¿¡ +º¸³»´Â ºÎºÐÀ¸·Î ³»¿ëÀ» ¼³¸íÇÏ´Â Á¤º¸°¡ ÀÖ´Ù.
    + +
    .htaccess
    À¥¹®¼­µé ¾È¿¡ ÀÖ´Â +¼³Á¤ÆÄÀÏ (configuration file)·Î, +¼³Á¤ Áö½Ã¾î (directive)¸¦ ÀÚ½ÅÀÌ À§Ä¡ÇÑ +µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ Àû¿ëÇÑ´Ù. À̸§°ú ´Þ¸® ÀÌ +ÆÄÀÏ¿¡¼­´Â ´Ü¼øÇÑ Á¢±ÙÁ¦¾î Áö½Ã¾î¿Ü¿¡ °ÅÀÇ ¸ðµç Á¾·ùÀÇ Áö½Ã¾î¸¦ +»ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    httpd.conf
    +
    ¾ÆÆÄÄ¡ ÁÖ ¼³Á¤ÆÄÀÏ (configuration +file). ±âº»ÀûÀÎ À§Ä¡´Â +/usr/local/apache2/conf/httpd.confÀÌÁö¸¸, ½ÇÇàÇÒ¶§ +ȤÀº ÄÄÆÄÀ϶§ ¼³Á¤À¸·Î º¯°æÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    HyperText Transfer +Protocol (HTTP)
    +
    ¿ùµå¿ÍÀ̵åÀ¥¿¡¼­ »ç¿ëÇϴ ǥÁØ Àü¼Û ÇÁ·ÎÅäÄÝ. ¾ÆÆÄÄ¡´Â +RFC 2616¿¡¼­ +Á¤ÀÇÇÑ HTTP/1.1À̶ó´Â ÇÁ·ÎÅäÄÝÀÇ 1.1 ¹öÀüÀ» ±¸ÇöÇÑ´Ù.
    + +
    HTTPS
    +
    ¿ùµåÈ­À̵åÀ¥ÀÇ Ç¥ÁØ ¾ÏÈ£Åë½Å ¹æ¹ý, HyperText Transfer + Protocol (Secure). »ç½Ç ¹Ø´Ü¿¡ SSLÀ» + »ç¿ëÇÑ HTTPÀÌ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¸Þ½áµå (Method)
    Ŭ¶óÀ̾ðÆ®°¡ +º¸³»´Â HTTP ¿äûÁÙÀÌ +ÀÚ¿ø¿¡ ¼öÇàÇϵµ·Ï Áö½ÃÇÑ Çൿ. HTTP ¸Þ½áµå¿¡´Â GET, +POST, PUT µîÀÌ ÀÖ´Ù.
    + +
    ¸Þ½ÃÁö ¿ä¾à (Message Digest)
    +
    ¸Þ½ÃÁö ³»¿ëÀÌ Àü¼ÛÁß º¯°æµÇÁö ¾Ê¾ÒÀ½À» Áõ¸íÇϱâÀ§ÇÑ + ¸Þ½ÃÁöÀÇ Çؽ¬.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    MIME-type
    Àü¼ÛÇÒ ¹®¼­ÀÇ +Á¾·ù¸¦ ¼³¸íÇÏ´Â ¹æ½Ä. Multipurpose Internet Mail Extensions +Çü½ÄÀ» ºô·Á¿Ô±â¶§¹®¿¡ ÀÌ·¸°Ô À̸§À» Áö¾ú´Ù. ½½·¡½¬¸¦ »çÀÌ¿¡ +µÐ major type°ú minor typeÀ¸·Î ÀÌ·ç¾îÁø´Ù. ¿¹¸¦ µé¸é, +text/html, image/gif, +application/octet-stream µîÀÌ´Ù. MIME-typeÀº HTTPÀÇ +Content-Type Çì´õ (header)·Î +Àü¼ÛÇÑ´Ù.
    Âü°í: mod_mime
    + +
    ¸ðµâ (Module)
    ÇÁ·Î±×·¥ÀÇ µ¶¸³µÈ +ºÎºÐ. ¸¹Àº ¾ÆÆÄÄ¡ ±â´ÉÀº ´ç½ÅÀÌ Æ÷ÇÔ¿©ºÎ¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ´Â ¸ðµâ¿¡ +µé¾îÀÖ´Ù. ¾ÆÆÄÄ¡ httpd ½ÇÇàÆÄÀÏ°ú °°ÀÌ ÄÄÆÄÀÏÇÑ ¸ðµâÀ» Á¤Àû +¸ðµâÀ̶ó°í Çϸç, µû·Î ºÐ¸®µÇ¾î ½ÇÇà½Ã ¼±ÅÃÀûÀ¸·Î ÀоîµéÀÏ +¼ö ÀÖ´Â ¸ðµâÀ» µ¿Àû ¸ðµâ ȤÀº DSO¶ó°í +ÇÑ´Ù. ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏ´Â ¸ðµâÀ» base ¸ðµâÀ̶ó°í ÇÑ´Ù. +¾ÆÆÄÄ¡ À¥¼­¹ö Ÿº¼ (tarball)°ú °°ÀÌ +¹èÆ÷µÇÁö´Â ¾ÊÁö¸¸ ¾ÆÆÄÄ¡¿¡´Â ¸¹Àº ¸ðµâµéÀÌ ÀÖ´Ù. À̵éÀ» +Á¦»ïÀÚ°¡ ¸¸µç(third-party) ¸ðµâÀ̶ó°í ÇÑ´Ù.
    +Âü°í: ¸ðµâ ¸ñ·Ï
    + +
    ¸ðµâ ¸¶¹ý¼ö (Module Magic Number) +(MMN)
    +
    ¸ðµâ ¸¶¹ý¼ö´Â ¾ÆÆÄÄ¡ ¼Ò½ºÄڵ尡 Á¤ÀÇÇÑ »ó¼ö·Î, ¸ðµâÀÇ +ÀÌÁøȣȯ¼º°ú °ü·ÃÀÌ ÀÖ´Ù. ¸ðµâ ¸¶¹ý¼ö´Â ÀÌÁøȣȯ¼ºÀ» ´õ ÀÌ»ó º¸ÀåÇÒ +¼ö ¾øµµ·Ï ¾ÆÆÄÄ¡ ³»ºÎ ±¸Á¶³ª ÇÔ¼ö È£Ãâ, ´Ù¸¥ API ÀϺΰ¡ º¯°æµÈ +°æ¿ì¿¡ ¹Ù²ï´Ù. MMNÀÌ º¯Çϸé Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀº ¸ðµÎ ÃÖ¼ÒÇÑ ´Ù½Ã +ÄÄÆÄÀÏµÇ¾ß ÇÑ´Ù. »õ ¾ÆÆÄÄ¡ ¹öÀü¿¡ ¸Âµµ·Ï Á¶±Ý ¼öÁ¤ÇؾßÇÒ °æ¿ìµµ +ÀÖ´Ù. +
    + +
    OpenSSL
    +
    SSL/TLS¸¦ À§ÇÑ ¿ÀǼҽº µµ±¸
    + Âü°í http://www.openssl.org/
    + +
    Pass Phrase
    +
    °³ÀÎÅ° ÆÄÀÏÀ» º¸È£ÇÏ´Â ¹®±¸. ÀÎÁõÇÏÁö¾ÊÀº »ç¿ëÀÚ°¡ ÀÌ °³ÀÎÅ° +ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¾ÏȣȭÇÏÁö ¸øÇϵµ·Ï ÇÑ´Ù. º¸Åë ¾ÏÈ£±â +(Ciphers)°¡ »ç¿ëÇÏ´Â ºñ¹Ð½º·± ¾ÏÈ£/Çص¶ Å°ÀÌ´Ù.
    Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Æò¹® (Plaintext)
    +
    ¾ÏȣȭÇÏÁö ¾ÊÀº ±Û.
    + +
    °³ÀÎÅ° (Private Key)
    ¹ÞÀº +ÀڷḦ Çص¶ÇÏ°í º¸³»´Â ÀڷḦ ¼­¸íÇϱâÀ§ÇÑ °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography) ½Ã½ºÅÛÀÇ ¾ÏȣŰ.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÇÁ·Ï½Ã (Proxy)
    Ŭ¶óÀ̾ðÆ®¿Í +½ÇÁ¦ ¼­¹ö »çÀÌ¿¡ ÀÖ´Â Áß°£ ¼­¹ö. Ŭ¶óÀ̾ðÆ®¿¡°Ô ¿äûÀ» +¹Þ¾Æ ½ÇÁ¦ ¼­¹ö·Î º¸³»°í, ½ÇÁ¦ ¼­¹ö¿¡°Ô¼­ ¹ÞÀº ÀÀ´äÀ» ´Ù½Ã +Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù. ¿©·¯ Ŭ¶óÀ̾ðÆ®°¡ °°Àº ³»¿ëÀ» ¿äûÇϸé +ÇÁ·Ï½Ã´Â ¸Å¹ø ¼­¹ö¿¡ ¿äûÇÏÁö¾Ê°í ij½¬¿¡ ÀúÀåµÈ ³»¿ëÀ» »ç¿ëÇÏ¿© +ÀÀ´ä½Ã°£À» ÁÙÀÏ ¼ö ÀÖ´Ù.
    +Âü°í: mod_proxy
    + +
    °ø°³Å° (Public Key)
    °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography) ½Ã½ºÅÛ¿¡¼­ Å°ÀÇ ¼ÒÀ¯ÀÚ¿¡°Ô º¸³»´Â ¹®±¸¸¦ ¾ÏȣȭÇϰųª +¼ÒÀ¯ÀÚ°¡ ¸¸µç ¼­¸íÀ» Ç®±âÀ§ÇÑ °ø°³µÈ Å°.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography)
    +
    ¾ÏÈ£¿Í Çص¶¿¡ ¼­·Î ´Ù¸¥ Å°¸¦ »ç¿ëÇÏ´Â ºñ´ëĪ(asymmetric) +¾Ïȣȭ ½Ã½ºÅÛÀÇ ¿¬±¸ ¹× È°¿ë. ¾ÏÈ£¿Í Çص¶¿¡ »ç¿ëÇÏ´Â µÎ°³ÀÇ Å°´Â +Å°½Ö(key pair)À» ÀÌ·é´Ù. ºñ´ëĪ ¾Ïȣȭ¶ó°íµµ ºÎ¸¥´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Á¤±ÔÇ¥Çö½Ä (Regular Expression) (Regex)
    ±ÛÀÇ ÆÐÅÏÀ» ±â¼úÇÏ´Â ¹æ½Ä. +¿¹¸¦ µé¾î, "¹®ÀÚ A·Î ½ÃÀÛÇÏ´Â ¸ðµç ´Ü¾î", "¼ýÀÚ 10°³·ÎµÈ ÀüÈ­¹øÈ£", +½ÉÁö¾î "½°Ç¥°¡ µÎ°³ÀÖ°í ´ë¹®ÀÚ Q°¡ ¾ø´Â ¹®Àå" µîÀ» Ç¥ÇöÇÒ ¼ö ÀÖ´Ù. +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¸é ¸Å¿ì À¯¿¬ÇÏ°Ô ÆÄÀÏÀ̳ª ÀÚ¿ø¿¡ ¾î¶² ¼ºÁúÀ» Àû¿ëÇÒ +¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, "images"¶õ µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â ¸ðµç .gif¿Í +.jpg ÆÄÀÏÀº "/images/.*(jpg|gif)$"·Î ÁöĪÇÒ ¼ö +ÀÖ´Ù. ¾ÆÆÄÄ¡´Â PCRE ¶óÀ̺귯¸®¸¦ +»ç¿ëÇÏ¿© Perlȣȯ Á¤±ÔÇ¥Çö½ÄÀ» Áö¿øÇÑ´Ù.
    + +
    ¿ªÇÁ·Ï½Ã (Reverse Proxy)
    +
    Ŭ¶óÀ̾ðÆ®¿¡°Ô ½ÇÁ¦ ¼­¹öó·³ º¸ÀÌ´Â ÇÁ·Ï½Ã (proxy) ¼­¹ö. º¸¾È»ó ÀÌÀ¯ ȤÀº ºÎÇϸ¦ +ºÐ»êÇϱâÀ§ÇØ Å¬¶óÀ̾ðÆ®¿¡°Ô ½ÇÁ¦ ¼­¹ö¸¦ ¼û±æ¶§ À¯¿ëÇÏ´Ù.
    + +
    Secure Sockets Layer (SSL)
    Netscape Communications»ç°¡ TCP/IP +³×Æ®¿÷ÀÇ ÀϹÝÀûÀÎ Åë½Å ÀÎÁõ°ú ¾Ïȣȭ¸¦ À§ÇØ ¸¸µç ÇÁ·ÎÅäÄÝ. +°¡Àå ÀϹÝÀûÀÎ ¿ëµµ´Â HTTPS (HyperText Transfer Protocol +(HTTP) over SSL)ÀÌ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Server Side Includes (SSI)
    HTML ÆÄÀÏ ¾È¿¡ ó¸®Áö½Ã¾î¸¦ Æ÷ÇÔÇÏ´Â +±â¼ú.
    Âü°í: Server Side Includes ¼Ò°³
    + +
    ¼¼¼Ç (Session)
    +
    ÀϹÝÀûÀ¸·Î Åë½ÅÀÇ »óȲ(context) Á¤º¸.
    + +
    SSLeay
    +
    Eric A. YoungÀÌ °³¹ßÇÑ ¿ø·¡ SSL/TLS ±¸Çö ¶óÀ̺귯¸®
    + +
    ´ëĪÀû ¾ÏÈ£¹ý (Symmetric +Cryptography)
    +
    ¾ÏÈ£¿Í Çص¶ ÀÛ¾÷¿¡ °°Àº ¾Ïȣ۸¦ »ç¿ëÇÏ´Â ¾ÏÈ£±â + (Ciphers)ÀÇ ¿¬±¸ ¹× È°¿ë.
    +Âü°í: SSL/TLS Encryption
    + +
    Ÿº¼ (Tarball)
    +
    tar µµ±¸¸¦ »ç¿ëÇÏ¿© ÆÄÀϵéÀ» ¸ðÀº ¹­À½. ¾ÆÆÄÄ¡´Â +tar ÆÄÀÏÀ» ¾ÐÃàÇϰųª pkzipÀ¸·Î ¾ÐÃàÇÏ¿© ¹èÆ÷µÈ´Ù.
    + +
    Transport Layer Security (TLS)
    +
    ÀÎÅͳݱâ¼ú °ü·Ã ±¹Á¦Ç¥ÁØÈ­±â±¸(Internet Engineering Task +Force, IETF)°¡ TCP/IP ³×Æ®¿÷ÀÇ ÀϹÝÀûÀÎ Åë½Å ÀÎÁõ°ú ¾Ïȣȭ¸¦ +À§ÇØ ¸¸µç SSLÀÇ ÈÄ¼Ó ÇÁ·ÎÅäÄÝ. TLS ¹öÀü 1Àº SSL ¹öÀü 3°ú °ÅÀÇ +À¯»çÇÏ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Uniform Resource Locator +(URL)
    +
    ÀÎÅͳݿ¡ ÀÖ´Â ÀÚ¿øÀÇ À̸§/ÁÖ¼Ò. Á¤½ÄÀ¸·Î´Â Uniform Resource +Identifier¶ó°í ÇÏ´Â °ÍÀÇ ÀÏ»óÀûÀÎ ºñ°ø½Ä ¸íĪÀÌ´Ù. º¸Åë URLÀº +http³ª https°°Àº ½ºÅ´(scheme), È£½ºÆ®¸í, +°æ·Î·Î ±¸¼ºµÈ´Ù. ÀÌ ÆäÀÌÁöÀÇ URLÀº +http://httpd.apache.org/docs-2.1/glossary.htmlÀÌ´Ù.
    + +
    Uniform Resource Identifier +(URI)
    +
    Ãß»óÀûÀÎ ÀÚ¿øÀ̳ª ½ÇÁ¦ ÀÚ¿øÀ» ÁöĪÇϱâÀ§ÇÑ °£°áÇÑ ¹®ÀÚ¿­. +°ø½ÄÀûÀ¸·Î RFC +2396¿¡¼­ Á¤ÀÇÇÑ´Ù. ¿ùµå¿ÍÀ̵åÀ¥¿¡¼­ »ç¿ëÇÏ´Â URI¸¦ º¸Åë +URLÀ̶ó°í ºÎ¸¥´Ù.
    + +
    °¡»óÈ£½ºÆ® (Virtual Hosting)
    +
    ¾ÆÆÄÄ¡ Çϳª·Î ¿©·¯ À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇϱâ. IP °¡»óÈ£½ºÆ®´Â +À¥»çÀÌÆ®¸¶´Ù IP ÁÖ¼Ò°¡ ´Ù¸£´Ù. À̸§±â¹Ý(name-based) +°¡»óÈ£½ºÆ®´Â È£½ºÆ®¸í¸¸À» »ç¿ëÇϹǷΠÇÑ IP ÁÖ¼Ò¿¡¼­ ¿©·¯ +»çÀÌÆ®¸¦ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­
    + +
    X.509
    +
    ±¹Á¦Àü±âÅë½Å¿¬ÇÕ(International Telecommunication Union, +ITU-T)ÀÌ ±ÇÀåÇÏ´Â ÀÎÁõ¼­ ¾ç½Ä. SSL/TLS ÀÎÁõ¿¡¼­ »ç¿ëÇÑ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/glossary.xml b/trunk/docs/manual/glossary.xml new file mode 100644 index 0000000000..dca77df92e --- /dev/null +++ b/trunk/docs/manual/glossary.xml @@ -0,0 +1,465 @@ + + + + + + + + + + Glossary + + +

    This glossary defines some of the common terminology related to Apache in + particular, and web serving in general. More information on each concept + is provided in the links.

    +
    + +
    Definitions + +
    +
    Access Control
    +
    The restriction of access to network realms. In an Apache context + usually the restriction of access to certain URLs.
    See: Authentication, Authorization, and Access + Control +
    + +
    Algorithm
    + +
    An unambiguous formula or set of rules for solving a problem in a finite + number of steps. Algorithms for encryption are usually called + Ciphers. +
    + +
    APache + eXtension Tool (apxs)
    +
    A perl script that aids in compiling module sources into Dynamic Shared Objects + (DSOs) and helps install them in the + Apache Web server.
    + See: Manual Page: apxs +
    + +
    Authentication
    +
    The positive identification of a network entity such as a server, a + client, or a user.
    + See: Authentication, Authorization, and Access + Control +
    + +
    Certificate
    +
    A data record used for authenticating network entities such + as a server or a client. A certificate contains X.509 information pieces + about its owner (called the subject) and the signing Certification Authority (called + the issuer), plus the owner's public + key and the + signature made by the CA. Network entities verify these signatures + using CA certificates.
    + See: SSL/TLS Encryption +
    + +
    Certificate Signing Request + (CSR)
    +
    An unsigned certificate for + submission to a Certification + Authority, which signs it with the Private Key of their CA + Certificate. Once the CSR is signed, it becomes a real + certificate.
    + See: SSL/TLS Encryption +
    + +
    Certification Authority + (CA)
    +
    A trusted third party whose purpose is to sign certificates for network + entities it has authenticated using secure means. Other network entities + can check the signature to verify that a CA has authenticated the bearer + of a certificate.
    + See: SSL/TLS Encryption +
    + +
    Cipher
    +
    An algorithm or system for data encryption. Examples are DES, IDEA, RC4, + etc.
    + See: SSL/TLS Encryption +
    + +
    Ciphertext
    +
    The result after Plaintext is + passed through a Cipher.
    See: SSL/TLS Encryption +
    + +
    Common + Gateway Interface (CGI)
    +
    A standard definition for an interface between a web server and an + external program that allows the external program to service requests. + The interface was originally defined by NCSA but there + is also an RFC project.
    + See: Dynamic Content with CGI +
    + +
    Configuration Directive
    +
    See: Directive
    + +
    Configuration + File
    +
    A text file containing Directives + that control the configuration of Apache.
    + See: Configuration Files +
    + +
    CONNECT
    +
    An HTTP method for proxying raw data + channels over HTTP. It can be used to encapsulate other protocols, such as + the SSL protocol. +
    + +
    Context
    +
    An area in the configuration + files where certain types of directives are allowed.
    + See: Terms Used to Describe + Apache Directives +
    + +
    Digital + Signature
    +
    An encrypted text block that validates a certificate or other file. A + Certification Authority + creates a signature by generating a hash of the Public Key + embedded in a Certificate, then encrypting the hash with its own + Private Key. Only the CA's public key can decrypt the signature, + verifying that the CA has authenticated the network entity that owns the + Certificate.
    + See: SSL/TLS Encryption +
    + +
    Directive
    +
    A configuration command that controls one or more aspects of Apache's + behavior. Directives are placed in the Configuration File
    + See: Directive Index +
    + +
    Dynamic + Shared Object (DSO)
    +
    Modules compiled separately from the + Apache httpd binary that can be loaded on-demand.
    + See: Dynamic Shared Object Support +
    + +
    Environment + Variable (env-variable)
    +
    Named variables managed by the operating system shell and used to store + information and communicate between programs. Apache also contains + internal variables that are referred to as environment variables, but are + stored in internal Apache structures, rather than in the shell + environment.
    + See: Environment Variables in Apache +
    + +
    Export-Crippled
    +
    Diminished in cryptographic strength (and security) in order to comply + with the United States' Export Administration Regulations (EAR). + Export-crippled cryptographic software is limited to a small key size, + resulting in Ciphertext which usually can be decrypted by brute + force.
    + See: SSL/TLS Encryption +
    + +
    Filter
    +
    A process that is applied to data that is sent or received by the + server. Input filters process data sent by the client to the server, + while output filters process documents on the server before they are sent + to the client. For example, the INCLUDES output filter + processes documents for Server Side + Includes.
    + See: Filters +
    + +
    Fully-Qualified Domain-Name + (FQDN)
    +
    The unique name of a network entity, consisting of a hostname and a + domain name that can resolve to an IP address. For example, + www is a hostname, example.com is a domain name, + and www.example.com is a fully-qualified domain name. +
    + +
    Handler
    +
    An internal Apache representation of the action to be performed when a + file is called. Generally, files have implicit handlers, based on the file + type. Normally, all files are simply served by the server, but certain + file types are "handled" separately. For example, the + cgi-script handler designates files to be processed as + CGIs.
    + See: Apache's Handler Use +
    + +
    Hash
    +
    A mathematical one-way, irreversable algorithm generating a string with + fixed-length from another string of any length. Different input strings + will usually produce different hashes (depending on the hash function). +
    + +
    Header
    +
    The part of the HTTP request and + response that is sent before the actual content, and that contains + meta-information describing the content. +
    + +
    .htaccess
    +
    A configuration file that + is placed inside the web tree and applies configuration directives to the directory where it is + placed and all sub-directories. Despite its name, this file can hold + almost any type of directive, not just access-control directives.
    + See: Configuration Files +
    + +
    httpd.conf
    +
    The main Apache configuration + file. The default location is + /usr/local/apache2/conf/httpd.conf, but it may be moved using + run-time or compile-time configuration.
    + See: Configuration Files +
    + +
    HyperText Transfer Protocol + (HTTP)
    +
    The standard transmission protocol used on the World Wide Web. Apache + implements version 1.1 of the protocol, referred to as HTTP/1.1 and + defined by RFC 2616. +
    + +
    HTTPS
    +
    The HyperText Transfer Protocol (Secure), the standard encrypted + communication mechanism on the World Wide Web. This is actually just HTTP + over SSL.
    + See: SSL/TLS Encryption +
    + +
    Method
    +
    In the context of HTTP, an action to + perform on a resource, specified on the request line by the client. Some + of the methods available in HTTP are GET, POST, + and PUT. +
    + +
    Message Digest
    +
    A hash of a message, which can be used to verify that the contents of + the message have not been altered in transit.
    + See: SSL/TLS Encryption +
    + +
    MIME-type
    +
    A way to describe the kind of document being transmitted. Its name + comes from that fact that its format is borrowed from the Multipurpose + Internet Mail Extensions. It consists of a major type and a minor type, + separated by a slash. Some examples are text/html, + image/gif, and application/octet-stream. In + HTTP, the MIME-type is transmitted in the Content-Type + header.
    + See: mod_mime +
    + +
    Module
    +
    An independent part of a program. Much of Apache's functionality is + contained in modules that you can choose to include or exclude. Modules + that are compiled into the Apache httpd binary are + called static modules, while modules that are stored + separately and can be optionally loaded at run-time are called + dynamic modules or DSOs. + Modules that are included by default + are called base modules. Many modules are available for Apache + that are not distributed as part of the Apache HTTP Server tarball. These are referred to as + third-party modules.
    + See: Module Index +
    + +
    Module Magic + Number (MMN)
    +
    Module Magic Number is a constant defined in the Apache source code that + is associated with binary compatibility of modules. It is changed when + internal Apache structures, function calls and other significant parts of + API change in such a way that binary compatibility cannot be guaranteed + any more. On MMN change, all third party modules have to be at least + recompiled, sometimes even slightly changed in order to work with the new + version of Apache. +
    + +
    OpenSSL
    +
    The Open Source toolkit for SSL/TLS
    + See http://www.openssl.org/# +
    + +
    Pass Phrase
    +
    The word or phrase that protects private key files. It prevents + unauthorized users from encrypting them. Usually it's just the secret + encryption/decryption key used for Ciphers.
    + See: SSL/TLS Encryption +
    + +
    Plaintext
    +
    The unencrypted text.
    + +
    Private Key
    +
    The secret key in a Public Key + Cryptography system, used to decrypt incoming messages and + sign outgoing ones.
    + See: SSL/TLS Encryption +
    + +
    Proxy
    +
    An intermediate server that sits between the client and the origin + server. It accepts requests from clients, transmits those requests + on to the origin server, and then returns the response from the origin + server to the client. If several clients request the same content, the + proxy can deliver that content from its cache, rather than requesting it + from the origin server each time, thereby reducing response time.
    + See: mod_proxy +
    + +
    Public Key
    +
    The publicly available key in a Public Key Cryptography system, + used to encrypt messages bound for its owner and to decrypt signatures + made by its owner.
    + See: SSL/TLS Encryption +
    + +
    Public Key Cryptography
    +
    The study and application of asymmetric encryption systems, which use + one key for encryption and another for decryption. A corresponding pair of + such keys constitutes a key pair. Also called Asymmetric Cryptography. +
    + See: SSL/TLS Encryption +
    + +
    Regular Expression + (Regex)
    +
    A way of describing a pattern in text - 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 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)$". Apache uses Perl + Compatible Regular Expressions provided by the PCRE library. +
    + +
    Reverse Proxy
    +
    A proxy server that appears to the client + as if it is an origin server. This is useful to hide the real + origin server from the client for security reasons, or to load balance. +
    + +
    Secure Sockets + Layer (SSL)
    +
    A protocol created by Netscape Communications Corporation for general + communication authentication and encryption over TCP/IP networks. The most + popular usage is HTTPS, i.e. the HyperText Transfer Protocol (HTTP) + over SSL.
    + See: SSL/TLS Encryption +
    + +
    Server Side + Includes (SSI)
    +
    A technique for embedding processing directives inside HTML files.
    + See: Introduction to Server Side Includes +
    + +
    Session
    +
    The context information of a communication in general.
    + +
    SSLeay
    +
    The original SSL/TLS implementation library developed by Eric A. + Young +
    + +
    Symmetric + Cryptography
    +
    The study and application of Ciphers that use a single secret key + for both encryption and decryption operations.
    + See: SSL/TLS Encryption +
    + +
    Tarball
    +
    A package of files gathered together using the tar utility. + Apache distributions are stored in compressed tar archives or using + pkzip. +
    + +
    Transport + Layer Security (TLS)
    +
    The successor protocol to SSL, created by the Internet Engineering Task + Force (IETF) for general communication authentication and encryption over + TCP/IP networks. TLS version 1 and is nearly identical with SSL version + 3.
    + See: SSL/TLS Encryption +
    + +
    Uniform + Resource Locator (URL)
    +
    The name/address of a resource on the Internet. This is the common + informal term for what is formally called a Uniform Resource Identifier. + URLs are usually made up of a scheme, like http or + https, a hostname, and a path. A URL for this page is + http://httpd.apache.org/docs-2.1/glossary.html. +
    + +
    Uniform Resource Identifier + (URI)
    +
    A compact string of characters for identifying an abstract or physical + resource. It is formally defined by RFC 2396. URIs used on the + world-wide web are commonly referred to as URLs. +
    + +
    Virtual Hosting
    +
    Serving multiple websites using a single instance of Apache. IP + virtual hosting differentiates between websites based on their IP + address, while name-based virtual hosting uses only the name of the + host and can therefore host many sites on the same IP address.
    + See: Apache Virtual Host documentation +
    + +
    X.509
    +
    An authentication certificate scheme recommended by the International + Telecommunication Union (ITU-T) which is used for SSL/TLS authentication.
    See: SSL/TLS Encryption +
    +
    +
    +
    diff --git a/trunk/docs/manual/glossary.xml.de b/trunk/docs/manual/glossary.xml.de new file mode 100644 index 0000000000..8afa71d7b0 --- /dev/null +++ b/trunk/docs/manual/glossary.xml.de @@ -0,0 +1,567 @@ + + + + + + + + + + Glossar + + +

    Dieses Glossar erläutert einige gebräuchliche Fachbegriffe im + Zusammenhang mit dem Apache im Speziellen und Web-Diensten im + Allgemeinen. Weitere Informationen zum jeweiligen Begriff erreichen Sie + über die Links.

    +
    + +
    Definitionen + +
    +
    Algorithmus
    +
    Eine eindeutige Formel oder ein Satz von Regeln zur Lösung eines + Problems in einer endlichen Anzahl von Schritten. Algorithmen zur + Verschlüsselung werden üblicherweise Chiffre genannt. +
    + +
    APache + eXtension Tool (apxs)
    +
    Ein Perl-Skript zur Kompilierung von Modul-Quelltexten zu Dynamic-Shared-Objects + (DSOs) und zur Installation dieser zum + Apache-Webserver.
    + Siehe: apxs-Dokumentation +
    + +
    Authentifizierung
    +
    Die positive Identifizierung einer Netzwerkeinheit, wie z.B. + eines Servers, eines Clients oder eines Benutzers.
    + Siehe: Authentisierung, Autorisierung und + Zugriffskontrolle +
    + +
    Certification Authority + səˈtifiˈkeiʃən + ɔːθɔriti + (CA)
    +
    die Zertifizierungsstelle Eine + vertrauenswürdige dritte Partei, deren Zweck es ist, + Zertifikate für Netzwerkeinheiten zu signieren. Andere + Netzwerkeinheiten können die Signatur prüfen, um + sicherzustellen, dass eine CA den Inhaber eines Zertifikats + authentifiziert hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Certificate Signing Request + səˈtifikit sainiŋ + riˈkwest (CSR)
    +
    Zertifikats-Signierungsanfrage Ein unsigniertes + Zertifikat zur Einreichung bei + einer Zertifizierungsstelle, welche + es mit dem privaten Schlüssel + ihres CA-Zertifikats signiert. Durch die Signatur wird ein CSR + zum echten Zertifikat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Chiffre
    +
    Die Chiffre ist ein Algorithmus oder System zur + Datenverschlüsselung. Beispiele sind DES, IDEA, RC4 usw. Im + Englischen spricht man von + Cipher ˈsaifə
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Chiffretext
    +
    Das Ergebnis, nachdem ein Klartext + eine Chiffre durchlaufen hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Common + Gateway Interface ˈkɔmən geitwei + ˈintəːfeis + (CGI)
    +
    Eine einheitliche Definition einer Schnittstelle zwischen einem + Webserver und einem externen Programm, welcher dem externen Programm die + Behandlung von Anfragen ermöglicht. Die Schnittstelle ist + ursprünglich von der NCSA + definiert worden. Es exisitert jedoch auch ein RFC-Projekt.
    + Siehe: Dynamische Inhalte mit CGI +
    + +
    CONNECT + kənekt
    +
    Eine HTTP-Methode zur Weiterleitung + von Rohdaten über HTTP. Sie kann dazu verwendet werden, andere + Protokolle wie zum Beispiel das SSL-Protokoll zu kapseln. +
    + +
    Digitale + Signatur
    +
    Ein chiffrierter Textblock, der die Gültigkeit eines Zertifikats + oder einer anderen Datei bestätigt. Eine Zertifizierungsstelle erstellt + eine digitale Signatur durch Generierung eines Hashs aus dem in einem Zertifikat + enthaltenen öffentlichen Schlüssel und + anschließender Codierung des Hashs mit dem privaten + Schlüssel des Zertifikats. Nur der öffentliche + Schlüssel der CA kann die Signatur decodieren. So wird + sichergestellt, dass die CA die Netwerkeinheit, welche das + Zertifikat besitzt, authentifiziert hat.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Direktive
    +
    Eine Konfigurationsanweisung, die das Verhalten des Apache in einem + oder mehreren Punkten steuert. Direktiven werden in den Konfigurationsdateien gesetzt.
    + Siehe: Verzeichnis der Direktiven +
    + +
    Dynamic + Shared Object + daiˈnæmik ʃɛəd + ˈɔbdʒikt (DSO)
    +
    Separat von der Apache-Binärdatei httpd + kompilierte Module, die bei Bedarf + geladen werden können.
    + Siehe: Unterstützung für + Dynamic-Shared-Objects +
    + +
    exportbeschränkt
    +
    Verminderte kryptografische Stärke (und Sicherheit), um den + Exportbesimmungen der Vereinigten Staaten konkret: United + States' Export Administration Regulations (EAR) zu + entsprechen. Exportbeschränkte Verschlüsselungssoftware ist + auf eine kurze Schlüssellänge begrenzt, was zu + Chiffretexten führt, die gewöhnlich mittels + Brute-Force dekodiert werden können.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Filter
    +
    Ein Verfahren, dass auf vom Server empfangene oder zu sendende Daten + angewendet wird. Eingabefilter verarbeiten vom Client an den Server + gesendetet Daten, während Ausgabefilter vom Server an den Client zu + sendende Daten verarbeiten. Der Ausgabefilter INCLUDES + beispielsweise untersucht Dokumente nach Server-Side-Includes und führt sie aus.
    + Siehe: Filter +
    + +
    Handler + ˈhændlə
    +
    Eine Apache-interne Darstellung der Aktion, die beim Aufruf einer + Datei auszuführen ist. Im Allgemeinen besitzen Dateien implizite, + auf dem Dateityp basierende Handler. Gewöhnlich werden alle Dateien + vom Server bedient, einige Dateitypen werden jedoch separat "behandelt" + besitzen einen separaten Handler. Der + cgi-script-Handler beispielsweise kennzeichnet Dateien, die + als CGI-Programme ausgeführt werden + sollen.
    + Siehe: Verwendung von Apache-Handlern +
    + +
    Hash + hæʃ
    +
    Ein mathematischer, unumkehrbarer Einweg-Algorithmus zur Generierung + einer Zeichenfolge fester Länge aus einer anderen Zeichenfolge + beliebiger Länge. Unterschiedliche Zeichenfolgen bei der Eingabe + ergeben üblischerweise unterschiedliche Hashes (abhängig von + der Hash-Funktion). +
    + +
    Header + hedə
    +
    Der Teil der HTTP-Anfrage und -Antwort, + der vor den eigentlichen Daten übermittelt wird und den Inhalt + beschreibende Meta-Informationen enthält. +
    + +
    .htaccess
    +
    Eine Konfigurationsdatei, + die innerhalb des Web-Verzeichnisbaums abgelegt wird und zu dem + Verzeichnis, in dem sie abgelegt ist, sowie allen Unterverzeichnissen + Konfigurationsdirektiven + enthält. Trotz ihres Namens kann diese Datei nahezu alle Arten von + Direktiven enthalten, nicht nur Direktiven zur Zugriffskontrolle.
    + Siehe: Konfigurationsdateien +
    + +
    httpd.conf
    +
    Die Haupt-Konfigurationsdatei ist + /usr/local/apache2/conf/httpd.conf. Dies kann aber zur + Laufzeit oder zur Kompilierungszeit anders konfiguriert werden.
    + Siehe: Konfigurationsdateien +
    + +
    HTTPS
    +
    Das HyperText-Transfer-Protokoll (Secure), der + Standard-Verschlüsselungsmechanismus im World Wide Web. + Tatsächlich handelt es sich hierbei um HTTP über SSL.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    HyperText-Transfer-Protokoll + (HTTP)
    +
    Das Standard-Übertragungsprotokoll im World Wide Web. Der Apache + implementiert die Protokollversion 1.1, bezeichnet als HTTP/1.1 und + definiert in RFC 2616. +
    + +
    Klartext
    +
    Der unverschlüsselte Text.
    + +
    Konfigurationsanweisung
    +
    Siehe: Direktive
    + +
    Konfigurationsdatei
    +
    Eine Textdatei mit Direktiven, + welche die Konfiguration des Apache steuern.
    + Siehe: Konfigurationsdateien +
    + +
    Kontext
    +
    Ein Bereich in den Konfigurationsdateien, in dem + verschiedene Typen von Direktiven + erlaubt sind.
    + Siehe: Erklärung der + Fachbegriffe zu Apache-Direktiven +
    + +
    Message-Digest + ˈmesidʒ
    +
    Ein Hash einer Nachricht, mit dem sich sicherstellen läßt, + dass der Inhalt der Nachricht während der Übertragung nicht + verändert wurde. ein so genannter Extrakt der + Nachricht
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Methode
    +
    Im HTTP-Kontext eine in der + Anfrage(zeile) des Clients angegeben Aktion, die auf eine Ressource + angewendet wird. GET, POST und PUT + sind einige der verfügbaren HTTP-Methoden. +
    + +
    MIME-Typ + maim tyːp
    +
    Eine Art und Weise, den Typ des übermittelten Dokuments zu + beschreiben. Sein Name leitet sich davon ab, dass sein Format den + Multipurpose Internet Mail Extensions entlehnt wurde. Er besteht aus + einem Haupttyp und einem Untertyp, getrennt durch einen + Schrägstrich. Einige Beispiele sind text/html, + image/gif und application/octet-stream. + Bei HTTP wird der MIME-Typ mit dem Header Content-Type + übermittelt.
    + Siehe: mod_mime +
    + +
    Modul
    +
    Ein selbstständiger Teil eines Programms. Ein Großteil der + Funktionalität des Apache ist in Modulen enthalten, die Sie einbinden + oder entfernen können. In die Apache-Binärdatei httpd + einkompilierte Module werden statische Module + genannt, während Module, die separat gespeichert sind und optional + zur Laufzeit geladen werden können, dynamische Module oder + DSOs genannt werden. + Standardmäßig eingebundene Module werden Basismodule + genannt. Für den Apache sind viele Module verfügbar, die nicht + als Bestandteil des Apache-HTTP-Server-Tarballs ausgeliefert + werden. Diese werden als Drittmodule bezeichnet.
    + Siehe: Modulverzeichnis +
    + +
    Module-Magic-Number + ˈmɔjuːl mædʒik + ˈnʌmbə + (MMN)
    +
    Die Module-Magic-Number ist eine Konstante, die im Apache-Quelltext + definiert ist und im Zusammenhang mit der Binärkompatibilität + von Modulen steht. Sie wird geändert, wenn sich interne + Apache-Strukturen, -Funktionen oder andere signifikante Teile der API + derart ändern, dass eine Binärkompatibilität nicht mehr + gewährleistet werden kann. Bei einer MMN-Änderung müssen + alle Module von Drittanbietern zumindest neu kompiliert und zuweilen auch + geringfügig angepaßt werden, um mit der neuen Apache-Version zu + funktionieren. +
    + +
    Öffentlicher + Schlüssel
    +
    Der öffentlich verfügbare Schlüssel in einem Public-Key-Kryptographie-System, + mit dem für seinen Eigentümer bestimmte Nachrichten + verschlüsselt und Signaturen von seinem Eigentümer + entschlüsselt werden.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    OpenSSL + ˈəupənɛsɛsˈɛl +
    +
    Das Open-Source-Toolkit für SSL/TLS
    + Siehe: http://www.openssl.org/ +
    + +
    Passphrase + paːfreiz
    +
    Das Wort oder die Phrase, welches private Schlüssel-Dateien + schützt. Sie verhindert die Entschlüsselung durch nicht + authorisierte Benutzer. Normalerweise ist dies einfach der geheimen + (De-)Codierungsschlüssel, der für Chiffren verwendet wird.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Privater Schlüssel
    +
    Der geheime Schlüssel in einem Public-Key-Kryptographie-System, + mit dem hereinkommende Nachrichten decodiert und ausgehende signiert + werden.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Proxy
    +
    Ein zwischen dem Client und dem ursprünglichen Server + der Server, den der Client tatsächlich erreichen + möchte liegender Server. Er nimmt Anfragen von + Clients entgegen, übermittelt diese Anfragen dem + ursprünglichen Server und liefert die Antwort des + ursprünglichen Servers an den Client zurück. Wenn mehrere + Clients den gleichen Inhalt abfragen, dann kann der Proxy diesen Inhalt + aus seinem Zwischenspeicher ausliefern, anstatt ihn jedesmal vom + ursprünglichen Server anzufordern, und dadurch die Antwortzeit + verringern.
    + Siehe: mod_proxy +
    + +
    Public-Key-Kryptographie + ˈpʌblik kiː + ˈkyptograˈfiː
    +
    Theorie und Anwendung asymmetrischer Verschlüsselungssysteme, + die einen Schlüssel zur Verschlüsselung und einen anderen zur + Entschlüsselung verwenden. Zwei derart zusammengehörende + Schlüssel bilden Schüsselpaar. Man spricht auch von + "Asymetrischer Kryptographie".
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Regulärer + Ausdruck (Regex)
    +
    Eine Form, ein Muster im Text zu beschreiben - zum Beispiel: "alle + Wörter, die mit dem Buchstaben A beginnen" oder "Jeder Satz mit + zwei Kommata und ohne großes Q". Beim Apache sind reguläre + Ausdrücke hilfreich, da sie auf sehr flexible Art und Weise die + Anwendung bestimmter Eigenschaften auf eine Auswahl von Dateien oder + Ressourcen ermöglichen. - Zum Beispiel können alle .gif- und + .jpg-Dateien eines Verzeichnis "images" mit + "/images/.*(jpg|gif)$" beschrieben werden. Der Apache + verwendet Perl-kompatible reguläre Ausdrücke, wie sie die + PCRE-Bibliothek bereitstellt. +
    + +
    Reverse Proxy + riːvəːs + ˈprɔksi
    +
    Ein Proxy-Server, der dem Client + gegenüber als ursprünglicher Server erscheint. Dies + ist nützlich, um den tatsächlichen Server aus + Sicherheitsgründen oder zur Lastverteilung vor dem Client zu + verstecken. +
    + +
    Secure Sockets + Layer siˈkjuə ˈsɔkits + ˈleiə (SSL)
    +
    Ein von der Firma Netscape Communications Corporation entwickeltes + Protokoll zur allgemeinen Authentisierung und Verschlüsselung der + Kommunikation über TCP/IP-Netzwerke. Die meistverbreitete Nutzung + ist HTTPS, d.h. HyperText Transfer Protocol (HTTP) über + SSL.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Server Side + Includes səːə said + inˈkluːds (SSI)
    +
    Eine Technik zum Einbetten von weiterverarbeitenden Anweisungen in + HMTL-Dateien.
    + Siehe: Einführung in Server Side + Includes +
    + +
    Session + ˈseʃən
    +
    Allgemein der Kontext einer Kommunikation.
    + +
    SSLeay
    +
    Die Bibliothek der Original-SSL/TLS-Implementation von Eric A. + Young
    + +
    Symmetrische Kryptographie
    +
    Die Theorie und Anwendung von Chiffren, die einen einzigen + geheimen Schlüssel sowohl zur Verschlüsswelung als auch zur + Entschlüsselung benutzen.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Tarball + taːbɔːl
    +
    Ein Paket von Dateien, die mit dem Hilfsprogramm tar + zusammengefasst wurden. Apache-Distributionen werden in komprimierten + tar-Archiven oder unter Verwendung von pkzip gespeichert. +
    + +
    Transport + Layer Security trænsˈpɔːt + ˈeiə siˈkjuəriti + (TLS)
    +
    Das SSL-Nachfolgeprotokoll, das von der Internet Engineering Task + Force (IETF) zur allgemeinen Authentisierung und Verschlüsselung + einer Kommunikation über TCP/IP-Netzwerke entwickelt worden ist. + TLS Version 1 ist nahezu identisch mit SSL Version 3.
    + Siehe: SSL/TLS-Verschlüsseliung +
    + +
    Umgebungsvariable (env-Variable)
    +
    Benannte, von der Betriebssystem-Shell verwaltete Variablen zur + Speicherung von Informationen und zur Kommunikation zwischen Programmen. + Der Apache beinhaltet auch interne Variablen, die ebenfalls + Umgebungsvariablen genannt werden, die aber statt in der + Shell-Umgebung in internen Apache-Strukturen gespeichert sind.
    + Siehe: Umgebungsvariablen im Apache +
    + +
    Uniform + Resource Locator ˈjuːnifɔːm + riˈsɔːs ləuˈkeitə + (URL)
    +
    Der Name bzw. die Adresse einer Ressource im Internet. Dies ist der + allgemein gebräuchliche Audruck für die formale Bezeichnung + Uniform Resource + Identifier. URLs bestehen üblicherweise aus einem + Schema wie http oder https, einem Hostnamen + und einem Pfad. Die URL für diese Seite ist + http://httpd.apache.org/docs-2.1/glossary.html. +
    + +
    Uniform Resource Identifier + ˈjuːnifɔːm + riˈsɔːs aiˈdentifaiə + (URI)
    +
    Eine kompakte Zeichenfolge zur Identifizierung einer abstrakten oder + physischen Ressource. Er wird in dem RFC 2396 formell + definiert. Im World Wide Web verwendete URIs werden üblicherweise + als URLs bezeichnet. +
    + +
    Virtual-Hosting + vəˈtjuəl + həustiŋ
    +
    Die Bedienung mehrere Websites mit einer einzigen Apache-Instanz. + IP-basierte virtuelle Hosts unterscheiden zwischen + verschiedenen Websites aufgrund ihrer IP-Adressen, während + namensbasierte virtuelle Hosts nur den Namen des Hosts + verwenden und daher mehrere Angebote unter der gleichen IP-Adresse + hosten können.
    + Siehe: Apache-Dokumentation zu virtuellen + Hosts +
    + +
    Voll-qualifizierter Domainname + (FQDN)
    +
    Der eindeutige Name einer Netzwerkeinheit, bestehend aus einem + Hostnamen und dem Domainnamen, welcher zu einer IP-Adresse + aufgelöst werden kann. Zum Beispiel ist www ein + Hostname, example.com ein Domainname und + www.example.com ein voll-qualifizierter Domainname. +
    + + +
    Website + websait
    +
    Im Gegensatz zur Webseite, die einer konkreten URL entspricht, ist mit + Website ein komplettes Angebot unter einem bestimmten Hostnamen (und Port) + gemeint. Dieses kann aus vielen verschiedenen Webseiten bestehen. +
    + +
    X.509
    +
    Ein von der International Telecommunication Union (ITU-T) empfohlenes + Schema für Authentifizierungszertifikate. Es wird für + SSL/TLS-Authentifizierungen verwendet.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Zertifikat
    +
    Ein Datensatz zur Authentisierung einer + Nertzwerkeinheit wie Server oder Client. Ein Zertifikat + enthält X.509-Informationen + über seinen Eigentümer (das sogenannte Betreff + engl.: subject) und die + signierende Certification + Authority (der sogenannte Aussteller engl.: + issuer) sowie den öffentlichen Schlüssel des + Eigentümers und die Signatur der CA. Netzwerkeinheiten + überprüfen diese Signatur mit Hilfe von CA-Zertifikaten.
    + Siehe: SSL/TLS-Verschlüsselung +
    + +
    Zugriffskontrolle
    +
    Die Beschränkung des Zugriffs auf Netzwerkbereiche. Im + Apache-Kontext in der Regel die Zugriffsbeschränkung auf bestimmte + URLs.
    + Siehe: Authentisierung, Autorisierung und + Zugriffskontrolle +
    +
    +
    +
    + diff --git a/trunk/docs/manual/glossary.xml.es b/trunk/docs/manual/glossary.xml.es new file mode 100644 index 0000000000..85da12100b --- /dev/null +++ b/trunk/docs/manual/glossary.xml.es @@ -0,0 +1,431 @@ + + + + + + + + + + Glosario + + +

    Este glosario define la terminología más común +relacionada con Apache en particular y con los servidores web en +general. En los enlaces que hay asociados a cada término se puede +encontrar información más detallada.

    +
    + +
    Definiciones + +
    +
    Autentificación
    La +identificación positiva de una entidad de red tal como un +servidor, un cliente, o un usuario.
    Consulte: Autentificación, Autorización, y +Control de Acceso
    + +
    Control de Acceso
    La +restricción en el acceso al entorno de una red. En el contexto de +Apache significa normalmente la restricción en el acceso a +ciertas URLs.
    Consulte: Autentificación, Autorización, y +Control de Acceso
    + +
    Algoritmo
    Un proceso definido sin +ambiguedades o un conjunto de reglas para solucionar un problema en un +número finito de pasos. Los algoritmos para encriptar se llaman +normalmente algoritmos de cifrado.
    + +
    Herramienta de extensión de +Apache (apxs)
    Es un script escrito en +Perl que ayuda a compilar el código fuente de algunos módulos para convertirlos en Objetos Dinamicos +Compartidos (DSOs) y ayuda a instalarlos en el +servidor web Apache.
    Consulte: Paginas de Ayuda: apxs
    + +
    Certificado
    + +
    Una información que se almacena para autentificar entidades + de red tales como un servidor o un cliente. Un certificado + contiene piezas de información X.509 sobre su poseedor + (llamado sujeto) y sobre la Autoridad Certificadora + (llamada el expendedor) que lo firma, más la clave publica del propietario y la firma de + la AC. Las entidades de red verifican las firmas usando + certificados de las AC.
    + +Consulte: Encriptado SSL/TLS
    + +
    Autoridad Certificadora (CA)
    Una entidad externa de confianza cuyo fin +es firmar certificados para las entidades de red que ha autentificado +usando medios seguros. Otras entidades de red pueden verificar la +firma para comprobar que una Autoridad Certificadora ha autentificado +al poseedor del certificado.
    Consulte: Encriptado +SSL/TLS
    + +
    Petición de firma de +Certificado (CSR)
    Es la petición a +una Autoridad Certificadora para +que firme un certificado aún sin +firmar. La Autoridad Certificadora firma el Certificado con +la Clave Privada de su certificado de Autoridad Certificadora. Una +vez que el CSR está firmado, se convierte en un auténtico +certificado.
    Consulte: Encriptado +SSL/TLS
    + + +
    Algoritmo de cifrado
    Es un algoritmo +o sistema de encriptado de información. Ejemplos de estos +algoritmos son DES, IDEA, RC4, etc.
    Consulte: Encriptado SSL/TLS
    + +
    Texto cifrado
    El resultado de +haber aplicado a un texto sin cifrar un algoritmo de cifrado.
    Consultar: Encriptado SSL/TLS
    + +
    Common Gateway Interface (CGI)
    Una definición estándar para +un interfaz entre un servidor web y un programa externo que permite +hacer peticiones de servicio a los programas externos. Este interfaz +fue definido originalmente por la NCSA pero +tambien hay un proyecto RFC.
    Consulte: Contenido Dinámico con CGI
    + + +
    Directivas de +configuración
    Consulte: Directivas
    + +
    Fichero de Configuración
    +
    Un fichero de texto que contiene Directivas que controlan la configuración +de Apache.
    Consulte: Ficheros de +Configuración
    + +
    CONNECT
    Un método de HTTP para hacer proxy a canales de +datos sin usar HTTP. Puede usarse para encapsular otros protocolos, +tales como el protocolo SSL.
    + +
    Contexto
    Un área en los ficheros de configuración donde +están permitidos ciertos tipos de directivas.
    Consulte: Terminos usados para describir +las directivas de Apache
    + +
    Firma Digital
    Un bloque de +texto encriptado que verifica la validez de un certificado o de otro +fichero. Una Autoridad +Certificadora crea una firma generando un hash a partir de la +Clave Pública que lleva incorporada en un +Certificado, después encriptando el hash con su propia +Clave Privada. Solo las claves públicas de las CAs +pueden desencriptar la firma, verificando que la CA ha autentificado a +la entidad de red propietaria del Certificado.
    +Consulte: Encriptado SSL/TLS
    + +
    Directiva
    Un comando de +configuración que controla uno o más aspectos del +comportamiento de Apache. Las directivas se ponen en el Fichero de Configuración
    +Consulte: Índice de +Directivas
    + +
    Objetos Dinámicos +Compartidos (DSO)
    Los Módulos compilados de forma separada al +binario httpd de Apache se pueden cargar según se necesiten.
    Consulte: Soporte de Objetos Dinámicos +Compartidos
    + +
    Variable de Entorno (env-variable)
    Variables que +gestionan el shell del sistema operativo y que se usan para guardar +información y para la comunicación entre programas. Apache +también contiene variables internas que son referidas como +variables de entorno, pero que son almacenadas en las estructuras +internas de Apache, en lugar de en el entorno del shell.
    +Consulte: Variables de entorno de Apache
    + +
    Export-Crippled
    +
    Disminución de la fortaleza criptográfica (y seguridad) +para cumplir con las Regulaciones sobre Exportación de la +Administracción de los Estados Unidos (EAR). El software +criptográfico Export-crippled está limitado a una clave de +pequeño tamaño, de tal manera que el texto cifrado +que se consigue con él, puede desencriptarse por fuerza bruta.
    Consulte: Encriptado SSL/TLS
    + +
    Filtro
    Un proceso que se aplica a la +información que es enviada o recibida por el servidor. Los +ficheros de entrada procesan la información enviada por un +cliente al servidor, mientras que los filtros de salida procesan la +información en el servidor antes de enviársela al +cliente. Por ejemplo, el filtro de salida INCLUDES +procesa documentos para Server Side Includes.
    +Consulte: Filtros
    + +
    Nombre de dominio +completamente qualificado (FQDN)
    El +nombre único de una entidad de red, que consiste en un nombre de +host y un nombre de dominio que puede traducirse a una dirección +IP. Por ejemplo, www es un nombre de host, +example.com es un nombre de dominio, y +www.example.com es un nombre de dominio completamente +qualificado.
    + +
    Handler
    Es una representación +interna de Apache de una acción a ser ejecutada cuando se llama a +un fichero. Generalmente, los ficheros tienen un handler +implícito, basado en el tipo de fichero. Normalmente, todos los +ficheros son simplemente servidos por el servidor, pero sobre algunos +tipos de ficheros se ejecutan acciones complementarias. Por ejemplo, +el handler cgi-script designa los ficheros a ser +procesados como CGIs.
    Consulte: Uso de Handlers en Apache
    + +
    Cabecera
    La parte de la +petición y la respuesta HTTP que se +envía antes del contenido propiamente dicho, y que contiene +meta-información describiendo el contenido.
    + +
    .htaccess
    Un fichero de configuración que se +pone dentro de la estructura de directorios del sitio web y aplica directivas de configuración al directorio +en el que está y a sus subdirectorios. A pesar de su nombre, este +fichero puede contener cualquier tipo de directivas, no solo +directivas de control de acceso.
    Consulte: Ficheros de Configuración
    + +
    httpd.conf
    Es el fichero de configuración principal +de Apache. Su ubicación por defecto es +/usr/local/apache2/conf/httpd.conf, pero puede moverse +usando opciones de configuración al compilar o al iniciar +Apache.
    Consulte: Ficheros de +Configuración
    + +
    Protocolo de Tranferencia de +Hipertexto (HTTP)
    Es el protocolo de +transmisión estádar usado en la World Wide Web. Apache +implementa la versión 1.1 de este protocolo, al que se hace +referencia como HTTP/1.1 y definido por el RFC 2616.
    + +
    HTTPS
    Protocolo de transferencia de +Hipertext (Seguro), es el mecanismo de comunicación encriptado +estándar en World Wide Web. En realidad es HTTP sobre SSL.
    Consulte: Encriptado +SSL/TLS
    + +
    Método
    En el contexto de HTTP, es una acción a ejecutar sobre un recurso, +especificado en la líneas de petición por el cliente. +Algunos de los metodos diponibles en HTTP son GET, +POST, y PUT.
    + +
    Message Digest
    Un hash de un +mensaje, el cual pude ser usado para verificar que el contenido del +mensaje no ha sido alterado durante la transmisión.
    +Consulte: Encriptado SSL/TLS
    + +
    MIME-type
    Una manera de describir +el tipo de documento a ser transmitido. Su nombre viene del hecho de +que su formato se toma de las Extensiones del Multipurpose Internet +Mail. Consiste en dos componentes, uno principal y otro secundario, +separados por una barra. Algunos ejemplos son text/html, +image/gif, y application/octet-stream. En +HTTP, el tipo MIME se transmite en la cabecera +del Tipo Contenido.
    Consulte: mod_mime
    + +
    Módulo
    Una parte independiente +de un programa. La mayor parte de la funcionalidad de Apache +está contenida en módulos que pueden incluirse o excluirse. +Los módulos que se compilan con el binario httpd de Apache se +llaman módulos estáticos, mientras que los que se +almacenan de forma separada y pueden ser cargados de forma opcional, +se llaman módulos dinamicos o DSOs. +Los módulos que están incluidos por sefecto de llaman +módulos base. Hay muchos módulos disponibles para +Apache que no se distribuyen con la tarball del +Servidor HTTP Apache . Estos módulos son llamados +módulos de terceros.
    Consulte: Índice de Módulos
    + +
    Número Mágico de +Módulo (MMN)
    El número +mágico de módulo es una constante definida en el código +fuente de Apache que está asociado con la compatibilidad binaria +de los módulos. Ese número cambia cuando cambian las +estructuras internas de Apache, las llamadas a funciones y otras +partes significativas de la interfaz de programación de manera +que la compatibilidad binaria no puede garantizarse sin cambiarlo. Si +cambia el número mágico de módulo, todos los +módulos de terceros tienen que ser al menos recompilados, y +algunas veces, incluso hay que introducir ligeras modificaciones para +que funcionen con la nueva versión de Apache
    + +
    OpenSSL
    +
    El toolkit Open Source para SSL/TLS
    + see http://www.openssl.org/
    + +
    Pass Phrase
    La palabra o frase +que protege los archivos de clave privada. Evita que usuarios no +autorizados los encripten. Normalmente es solo la clave de +encriptado/desencriptado usada por los Algoritmos de +Cifrado.
    Consulte: Encriptado +SSL/TLS
    + +
    Plaintext
    +
    Un texto no encriptado.
    + +
    Clave Privada
    La clave secreta +de un sistema criptográfico de +Clave Pública, usada para desencriptar los mensajes entrantes +y firmar los salientes.
    Consulte: Encriptado +SSL/TLS
    + +
    Proxy
    Un servidor intermedio que se +pone entre el cliente y el servidor de origen. Acepta las +peticiones de los clientes, las transmite al servidor de origen, y +después devuelve la respuesta del servidor de origen al +cliente. Si varios clientes piden el mismo contenido, el proxy sirve +el contenido desde su caché, en lugar de pedirlo cada vez que lo +necesita al servidor de origen, reduciendo con esto el tiempo de +respuesta.
    Consulte: mod_proxy
    + +
    Clave Publica
    La clave disponible +públicamente en un sistema +criptográfico de Clave Pública, usado para encriptar +mensajes destinados a su propietario y para desencriptar firmas hechas +por su propietario.
    Consulte: Encriptado +SSL/TLS
    + +
    Criptográfia de Clave +Pública
    El estudio y aplicación de sistemas de +encriptado asimétricos, que usa una clave para encriptar y otra +para desencriptar. Una clave de cada uno de estos tipos constituye un +par de claves. Tambien se llama Criptografia Asimétrica.
    +Consulte: Encriptado SSL/TLS
    + +
    Expresiones Regulares (Regex)
    Una forma de describir un modelo de +texto - por ejemplo, "todas las palabras que empiezan con la letra "A" +o "todos los números de teléfono que contienen 10 +dígitos" o incluso "Todas las frases entre comas, y que no +contengan ninguna letra Q". Las Expresiones Regulares son utiles en +Apache porque permiten aplicar ciertos atributos a colecciones de +ficheros o recursos de una forma flexible - por ejemplo, todos los +archivos .gif y .jpg que estén en un directorio "imágenes" +podrían ser escritos como "/images/.*(jpg|gif)$". +Apache usa Expresiones Regulares compatibles con Perl gracias a la +librería PCRE.
    + +
    Reverse Proxy
    Es un servidor +proxy que se presenta al cliente como si fuera un +servidor de origen. Es útil para esconder el +auténtico servidor de origen a los clientes por cuestiones de +seguridad, o para equilibrar la carga.
    + +
    Secure Sockets Layer (SSL)
    Un protocolo creado por Netscape +Communications Corporation para la autentificación en +comunicaciones en general y encriptado sobre redes TCP/IP. Su +aplicación más popular es HTTPS, el Protocolo de +Transferencia de Hipertexto (HTTP) sobre SSL.
    Consulte: Encriptado SSL/TLS
    + +
    Server Side Includes (SSI)
    Una tecnica para incluir directivas de +proceso en archivos HTML.
    Consulte: Introducción al Server Side +Includes
    + +
    Sesion
    Información del +contexto de una comunicación en general.
    + +
    SSLeay
    La implementación +original de la librería SSL/TLS desarrollada por Eric +A. Young
    + +
    Criptografía +Simétrica
    El estudio y aplicación de +Algoritmos de Cifrado que usan una solo clave secreta tanto +para encriptar como para desencriptar.
    Consulte: Encriptado SSL/TLS
    + +
    Tarball
    Un grupo de ficheros +puestos en un solo paquete usando la utilidad tar. Las +distribuciones Apache se almacenan en ficheros comprimidos con tar o +con pkzip.
    + +
    Transport Layer Security (TLS)
    Es el sucesor del protocolo SSL, creado +por el Internet Engineering Task Force (IETF) para la +autentificación en comunicaciones en general y encriptado sobre +redes TCP/IP. La versión 1 de TLS es casi idéntica a la +versión 3 de SSL.
    Consulte: Encriptado +SSL/TLS
    + +
    Localizador de Recursos +Uniforme (URL)
    El nombre de un recurso +en Internet. Es la manera informal de decir lo que formalmente se +llama un Identificador de +Recursos Uniforme. Las URLs están compuestas normalmente por +un esquema, tal como http o https, un nombre +de host, y una ruta. Una URL para esta página es +http://httpd.apache.org/docs-2.1/glossary.html.
    + +
    Identificador de Recursos +Uniforme (URI)
    Una cadena de caracteres +compacta para identificar un recurso físico o abstracto. Se +define formalmente en la RFC 2396. Los URIs que +se usan en world-wide web se refieren normalmente como URLs.
    + +
    Hosting Virtual
    Se trata de +servir diferentes sitios web con una sola entidad de Apache. El +hosting virtual de IPs diferencia los sitios web basandose en sus +direcciones IP, mientras que el hosting virtual basado en +nombres usa solo el nombre del host y de esta manera puede alojar +muchos sitios web con la misma dirección IP.
    Consulte: Documentación sobre Hosting Virtual en +Apache
    + +
    X.509
    Un esquema de certificado de +autentificación recomendado por la International +Telecommunication Union (ITU-T) que se usa en la autentificación +SSL/TLS.
    Consulte: Encriptado SSL/TLS
    + +
    +
    +
    + diff --git a/trunk/docs/manual/glossary.xml.ko b/trunk/docs/manual/glossary.xml.ko new file mode 100644 index 0000000000..71620d029c --- /dev/null +++ b/trunk/docs/manual/glossary.xml.ko @@ -0,0 +1,376 @@ + + + + + + + + + + ¿ë¾î + + +

    ÀÌ ¹®¼­´Â À¥ ¼­ºñ½º ÀϹݿ¡ ´ëÇÑ, ƯÈ÷ ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ, ¿ë¾îµéÀ» +Á¤ÀÇÇÑ´Ù. °¢ °³³ä¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â ¸µÅ©¸¦ Âü°íÇ϶ó. +ÇöÀç ´Ü¾îÀÇ ¼ø¼­´Â ÇÑ±Û ¼ø¼­°¡ ¾Æ´Ï¶ó, ¿µ¹®ÀÚ +¼ø¼­ÀÔ´Ï´Ù. ¿ë¾î¹ø¿ªÇ¥´Â ¿©±â¸¦ +Âü°íÇÏ±æ ¹Ù¶ø´Ï´Ù.

    +
    + +
    Á¤ÀÇ + +
    +
    Á¢±ÙÁ¦¾î (Access Control)
    +
    ³×Æ®¿÷ ¿µ¿ª¿¡ ´ëÇÑ Á¢±ÙÀ» Á¦ÇÑ. ¾ÆÆÄÄ¡¿¡¼­´Â º¸Åë ƯÁ¤ +URLÀÇ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ »ç¿ëÇÑ´Ù.
    Âü°í: ÀÎÁõ, ±ÇÇѺο©, Á¢±ÙÁ¦¾î
    + +
    ¾Ë°í¸®Áò (Algorithm)
    +
    À¯ÇÑÇÑ ´Ü°è¸¦ °ÅÃÄ ¹®Á¦¸¦ Ǫ´Â ¸íÈ®ÇÑ °ø½Ä ȤÀº ±ÔÄ¢µé. +¾Ïȣȭ¸¦ À§ÇÑ ¾Ë°í¸®ÁòÀ» º¸Åë ¾ÏÈ£±â(Ciphers)¶ó°í +ºÎ¸¥´Ù.
    + +
    APache eXtension Tool +(apxs)
    ¸ðµâ +(module) ¼Ò½º¸¦ µ¿Àû°øÀ¯°´Ã¼ (DSO)·Î +ÄÄÆÄÀÏÇÏ°í ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ ¼³Ä¡ÇÏ´Â ÀÛ¾÷À» µ½´Â perl +½ºÅ©¸³Æ®.
    Âü°í: Manpage: +apxs
    + +
    ÀÎÁõ (Authentication)
    +
    ¼­¹ö, Ŭ¶óÀ̾ðÆ®, »ç¿ëÀÚ µî ³×Æ®¿÷ ½Çü¿¡ ´ëÇÑ +È®ÀÎ.
    Âü°í: ÀÎÁõ, ±ÇÇѺο©, +Á¢±ÙÁ¦¾î
    + +
    ÀÎÁõ¼­ (Certificate)
    +
    ¼­¹ö³ª Ŭ¶óÀ̾ðÆ®¿Í °°Àº ³×Æ®¿÷ ½Çü¸¦ ÀÎÁõÇÏ´Â ÀÚ·á. + ÀÎÁõ¼­¿¡´Â ¼ÒÀ¯ÀÚ (subject¶ó°í ÇÔ), ¼­¸í ÀÎÁõ±â°ü (Certificate + Authority) (issuer¶ó°í ÇÔ), ¼ÒÀ¯ÀÚÀÇ °ø°³Å°, CA°¡ ¸¸µç ¼­¸í µî¿¡ ´ëÇÑ + X.509 Á¤º¸°¡ ÀÖ´Ù. ³×Æ®¿÷ ½Çü´Â CA ÀÎÁõ¼­¸¦ »ç¿ëÇÏ¿© + ¼­¸íÀ» °Ë»çÇÑ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÀÎÁõ ¼­¸í ¿äû (Certificate +Signing Request, CSR)
    ÀÎÁõ±â°ü (Certification +Authority)¿¡ Á¦ÃâÇÏ¿© CA ÀÎÁõ¼­ (Certificate)ÀÇ +°³ÀÎÅ° (Private Key)·Î ¼­¸íµÉ ¾ÆÁ÷ +¼­¸íµÇÁö¾ÊÀº ÀÎÁõ¼­. CSRÀÌ ¼­¸íµÇ¸é +½ÇÁ¦ ÀÎÁõ¼­°¡ µÈ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÀÎÁõ±â°ü (Certification +Authority, CA)
    ¾ÈÀüÇÑ ¹æ¹ýÀ¸·Î +³×Æ®¿÷ ½Çü¿¡ ´ëÇÑ ÀÎÁõÀ» ¼­¸íÇÏ´Â ½Å·ÚÇÏ´Â Á¦»ïÀÚ. ´Ù¸¥ ³×Æ®¿÷ +½ÇüµéÀº ¼­¸íÀ¸·Î CA°¡ ÀÎÁõ¼­ ¼ÒÀ¯ÀÚ¸¦ ÀÎÁõÇß´ÂÁö È®ÀÎÇÒ ¼ö +ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¾ÏÈ£±â (Cipher)
    ÀڷḦ +¾ÏȣȭÇÏ´Â ¾Ë°í¸®ÁòÀ̳ª ½Ã½ºÅÛ. ¿¹¸¦ µé¾î, DES, IDEA, RC4 µîÀÌ ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¾ÏÈ£¹® (Ciphertext)
    Æò¹® (Plaintext)À» ¾ÏÈ£±â +(Cipher)·Î ó¸®ÇÑ °á°ú.
    Âü°í: SSL/TLS +¾Ïȣȭ
    + +
    °øÅë °ÔÀÌÆ®¿þÀÌ ÀÎÅÍÆäÀ̽º +(Common Gateway Interface, CGI)
    +
    ¿ÜºÎ ÇÁ·Î±×·¥ÀÌ ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖµµ·Ï ¸¸µç À¥¼­¹ö¿Í ¿ÜºÎ +ÇÁ·Î±×·¥ »çÀÌÀÇ ÀÎÅÍÆäÀ̽º Ç¥ÁØ. ÀÎÅÍÆäÀ̽º´Â ¿ø·¡ NCSA°¡ +Á¤ÀÇÇßÁö¸¸, RFC +ÇÁ·ÎÁ§Æ®À̱⵵ ÇÏ´Ù.
    +Âü°í: CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º
    + + +
    ¼³Á¤ Áö½Ã¾î (Configuration +Directive)
    +
    Âü°í: Áö½Ã¾î
    + +
    ¼³Á¤ÆÄÀÏ (Configuration File)
    +
    ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÏ´Â Áö½Ã¾î (directive)¸¦ +Àû¾îµÐ ÅؽºÆ®ÆÄÀÏ.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    CONNECT
    +
    HTTP¸¦ ÅëÇØ ÀÚ·áÈ帧À» ÇÁ·Ï½ÃÇÏ´Â HTTP ¸Þ½áµå +(method). SSL ÇÁ·ÎÅäÄÝ µî ´Ù¸¥ ÇÁ·ÎÅäÄÝÀ» °¨½Î±âÀ§ÇØ »ç¿ëÇÑ´Ù.
    + +
    »ç¿ëÀå¼Ò (Context)
    ¼³Á¤ÆÄÀÏ (configuration file)¿¡¼­ +ƯÁ¤ Áö½Ã¾î (directive)¸¦ »ç¿ëÇÒ ¼ö +ÀÖ´Â Àå¼Ò.
    Âü°í: ¾ÆÆÄÄ¡ Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ +»ç¿ëÇÑ ¿ë¾îÁ¤ÀÇ
    + +
    ÀüÀÚ¼­¸í (Digital Signature)
    +
    ÀÎÁõ¼­³ª ´Ù¸¥ ÆÄÀÏÀ» °Ë»çÇÏ´Â ¾ÏȣȭµÈ ¹®ÀÚµé. ÀÎÁõ±â°ü (Certification + Authority)Àº ÀÎÁõ¼­ (Certificate)¿¡ Æ÷ÇÔµÈ + °ø°³Å° (Public Key)¸¦ Çؽ¬ÇÑ °á°ú¸¦ ÀÚ½ÅÀÇ + °³ÀÎÅ° (Private Key)·Î ¾ÏȣȭÇÏ¿© ¼­¸íÀ» ¸¸µç´Ù. + ¿ÀÁ÷ CAÀÇ °ø°³Å°¸¸ÀÌ ¼­¸íÀ» Ç® ¼ö Àֱ⶧¹®¿¡, CA°¡ ÀÎÁõ¼­ + (Certificate)¸¦ °¡Áø ³×Æ®¿÷ ½Çü¸¦ ÀÎÁõÇßÀ½À» Áõ¸íÇÒ + ¼ö ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Áö½Ã¾î (Directive)
    ¾ÆÆÄÄ¡ÀÇ +¿©·¯ ±â´ÉÀ» Á¶ÀýÇÏ´Â ¼³Á¤ ¸í·É¾î. Áö½Ã¾î´Â ¼³Á¤ÆÄÀÏ (Configuration File)¿¡¼­ +»ç¿ëÇÑ´Ù.
    Âü°í: Áö½Ã¾î ¸ñ·Ï
    + +
    µ¿Àû°øÀ¯°´Ã¼ (Dynamic Shared +Object) (DSO)
    ¾ÆÆÄÄ¡ httpd +½ÇÇàÆÄÀÏ°ú º°µµ·Î ÄÄÆÄÀÏÇÏ¿© ÇÊ¿äÇÒ¶§ ÀоîµéÀÏ ¼ö ÀÖ´Â ¸ðµâ (Module).
    +Âü°í: µ¿Àû°øÀ¯°´Ã¼ Áö¿ø
    + +
    ȯ°æº¯¼ö (Environment Variable) +(env-variable)
    +
    Á¤º¸¸¦ ÀúÀåÇÏ°í ÇÁ·Î±×·¥°£¿¡ Åë½ÅÀ» À§ÇØ ¿î¿µÃ¼Á¦ ½©ÀÌ °ü¸®ÇÏ´Â +º¯¼ö. ¾ÆÆÄÄ¡¿¡µµ ȯ°æº¯¼ö¶ó´Â ³»ºÎ º¯¼ö°¡ ÀÖÁö¸¸, ½© ȯ°æÀÌ +¾Æ´Ï¶ó ¾ÆÆÄÄ¡ ³»ºÎ¿¡ ÀúÀåµÈ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö
    + +
    ¼öÃâ¿ë (Export-Crippled)
    +
    ¹Ì±¹ ¼öÃâ°ü¸®±ÔÁ¦(Export Administration Regulations, EAR)¸¦ + ÁؼöÇϱâÀ§ÇØ ¾ÏÈ£(¿Í º¸¾È)ÀÇ °­µµ¸¦ ³·Ãã. ¼öÃâ¿ë ¾Ïȣȭ + ¼ÒÇÁÆ®¿þ¾î´Â Å° Å©±â°¡ ÀÛ°Ô Á¦ÇѵǾî, ¾ÏÈ£¹® + (Ciphertext)À» ¹«½ÄÇÑ ¹æ¹ý(brute force)À¸·Î Ç® ¼ö ÀÖ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ (SSL/TLS Encryption)
    + +
    ÇÊÅÍ (Filter)
    +
    ¼­¹ö°¡ º¸³»°Å³ª ¹Þ´Â ÀڷḦ ó¸®ÇÏ´Â °úÁ¤. ÀÔ·ÂÇÊÅÍ´Â +Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö·Î º¸³»´Â ÀڷḦ ó¸®ÇÏ°í, Ãâ·ÂÇÊÅÍ´Â ¼­¹ö°¡ +Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³¾ ¹®¼­¸¦ ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, +INCLUDES Ãâ·ÂÇÊÅÍ´Â ¹®¼­ÀÇ Server +Side Includes¸¦ ó¸®ÇÑ´Ù.
    +Âü°í: ÇÊÅÍ
    + +
    ¿ÏÀüÇÑ µµ¸ÞÀθí +(Fully-Qualified Domain-Name) (FQDN)
    +
    IP ÁÖ¼Ò¿¡ ´ëÀÀÇÏ´Â, È£½ºÆ®¸í°ú µµ¸ÞÀθíÀ¸·Î ±¸¼ºµÈ ³×Æ®¿÷ +½ÇüÀÇ À¯ÀÏÇÑ À̸§. ¿¹¸¦ µé¾î, www°¡ È£½ºÆ®¸íÀÌ°í +example.comÀÌ µµ¸ÞÀθíÀ϶§, +www.example.comÀº ¿ÏÀüÇÑ µµ¸ÞÀθíÀÌ´Ù.
    + +
    Çڵ鷯 (Handler)
    +
    ÆÄÀÏÀ» ¿äûÇÒ¶§ ¼öÇàÇÏ´Â ÀÛ¾÷¿¡ ´ëÇÑ ¾ÆÆÄÄ¡ ³»ºÎ Ç¥Çö. +ÀϹÝÀûÀ¸·Î ÆÄÀÏÀº ÆÄÀÏ Á¾·ù¿¡ µû¶ó ¾Ï¹¬ÀûÀÎ Çڵ鷯¸¦ °¡Áø´Ù. +º¸Åë ¸ðµç ÆÄÀÏÀº ¼­¹ö°¡ °£´ÜÈ÷ ¼­ºñ½ºÇÏÁö¸¸, ¾î¶² ÆÄÀÏ Á¾·ù´Â +µû·Î "󸮵ȴÙ(handled)". ¿¹¸¦ µé¾î, cgi-script +Çڵ鷯´Â CGI·Î ó¸®ÇÒ ÆÄÀÏÀ» ÁöÁ¤ÇÑ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë
    + +
    Çì´õ (Header)
    +
    HTTP ¿äû°ú ÀÀ´ä¿¡¼­ ½ÇÁ¦ ³»¿ë ÀÌÀü¿¡ +º¸³»´Â ºÎºÐÀ¸·Î ³»¿ëÀ» ¼³¸íÇÏ´Â Á¤º¸°¡ ÀÖ´Ù.
    + +
    .htaccess
    À¥¹®¼­µé ¾È¿¡ ÀÖ´Â +¼³Á¤ÆÄÀÏ (configuration file)·Î, +¼³Á¤ Áö½Ã¾î (directive)¸¦ ÀÚ½ÅÀÌ À§Ä¡ÇÑ +µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ Àû¿ëÇÑ´Ù. À̸§°ú ´Þ¸® ÀÌ +ÆÄÀÏ¿¡¼­´Â ´Ü¼øÇÑ Á¢±ÙÁ¦¾î Áö½Ã¾î¿Ü¿¡ °ÅÀÇ ¸ðµç Á¾·ùÀÇ Áö½Ã¾î¸¦ +»ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    httpd.conf
    +
    ¾ÆÆÄÄ¡ ÁÖ ¼³Á¤ÆÄÀÏ (configuration +file). ±âº»ÀûÀÎ À§Ä¡´Â +/usr/local/apache2/conf/httpd.confÀÌÁö¸¸, ½ÇÇàÇÒ¶§ +ȤÀº ÄÄÆÄÀ϶§ ¼³Á¤À¸·Î º¯°æÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¼³Á¤ÆÄÀÏ
    + +
    HyperText Transfer +Protocol (HTTP)
    +
    ¿ùµå¿ÍÀ̵åÀ¥¿¡¼­ »ç¿ëÇϴ ǥÁØ Àü¼Û ÇÁ·ÎÅäÄÝ. ¾ÆÆÄÄ¡´Â +RFC 2616¿¡¼­ +Á¤ÀÇÇÑ HTTP/1.1À̶ó´Â ÇÁ·ÎÅäÄÝÀÇ 1.1 ¹öÀüÀ» ±¸ÇöÇÑ´Ù.
    + +
    HTTPS
    +
    ¿ùµåÈ­À̵åÀ¥ÀÇ Ç¥ÁØ ¾ÏÈ£Åë½Å ¹æ¹ý, HyperText Transfer + Protocol (Secure). »ç½Ç ¹Ø´Ü¿¡ SSLÀ» + »ç¿ëÇÑ HTTPÀÌ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ¸Þ½áµå (Method)
    Ŭ¶óÀ̾ðÆ®°¡ +º¸³»´Â HTTP ¿äûÁÙÀÌ +ÀÚ¿ø¿¡ ¼öÇàÇϵµ·Ï Áö½ÃÇÑ Çൿ. HTTP ¸Þ½áµå¿¡´Â GET, +POST, PUT µîÀÌ ÀÖ´Ù.
    + +
    ¸Þ½ÃÁö ¿ä¾à (Message Digest)
    +
    ¸Þ½ÃÁö ³»¿ëÀÌ Àü¼ÛÁß º¯°æµÇÁö ¾Ê¾ÒÀ½À» Áõ¸íÇϱâÀ§ÇÑ + ¸Þ½ÃÁöÀÇ Çؽ¬.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    MIME-type
    Àü¼ÛÇÒ ¹®¼­ÀÇ +Á¾·ù¸¦ ¼³¸íÇÏ´Â ¹æ½Ä. Multipurpose Internet Mail Extensions +Çü½ÄÀ» ºô·Á¿Ô±â¶§¹®¿¡ ÀÌ·¸°Ô À̸§À» Áö¾ú´Ù. ½½·¡½¬¸¦ »çÀÌ¿¡ +µÐ major type°ú minor typeÀ¸·Î ÀÌ·ç¾îÁø´Ù. ¿¹¸¦ µé¸é, +text/html, image/gif, +application/octet-stream µîÀÌ´Ù. MIME-typeÀº HTTPÀÇ +Content-Type Çì´õ (header)·Î +Àü¼ÛÇÑ´Ù.
    Âü°í: mod_mime
    + +
    ¸ðµâ (Module)
    ÇÁ·Î±×·¥ÀÇ µ¶¸³µÈ +ºÎºÐ. ¸¹Àº ¾ÆÆÄÄ¡ ±â´ÉÀº ´ç½ÅÀÌ Æ÷ÇÔ¿©ºÎ¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ´Â ¸ðµâ¿¡ +µé¾îÀÖ´Ù. ¾ÆÆÄÄ¡ httpd ½ÇÇàÆÄÀÏ°ú °°ÀÌ ÄÄÆÄÀÏÇÑ ¸ðµâÀ» Á¤Àû +¸ðµâÀ̶ó°í Çϸç, µû·Î ºÐ¸®µÇ¾î ½ÇÇà½Ã ¼±ÅÃÀûÀ¸·Î ÀоîµéÀÏ +¼ö ÀÖ´Â ¸ðµâÀ» µ¿Àû ¸ðµâ ȤÀº DSO¶ó°í +ÇÑ´Ù. ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏ´Â ¸ðµâÀ» base ¸ðµâÀ̶ó°í ÇÑ´Ù. +¾ÆÆÄÄ¡ À¥¼­¹ö Ÿº¼ (tarball)°ú °°ÀÌ +¹èÆ÷µÇÁö´Â ¾ÊÁö¸¸ ¾ÆÆÄÄ¡¿¡´Â ¸¹Àº ¸ðµâµéÀÌ ÀÖ´Ù. À̵éÀ» +Á¦»ïÀÚ°¡ ¸¸µç(third-party) ¸ðµâÀ̶ó°í ÇÑ´Ù.
    +Âü°í: ¸ðµâ ¸ñ·Ï
    + +
    ¸ðµâ ¸¶¹ý¼ö (Module Magic Number) +(MMN)
    +
    ¸ðµâ ¸¶¹ý¼ö´Â ¾ÆÆÄÄ¡ ¼Ò½ºÄڵ尡 Á¤ÀÇÇÑ »ó¼ö·Î, ¸ðµâÀÇ +ÀÌÁøȣȯ¼º°ú °ü·ÃÀÌ ÀÖ´Ù. ¸ðµâ ¸¶¹ý¼ö´Â ÀÌÁøȣȯ¼ºÀ» ´õ ÀÌ»ó º¸ÀåÇÒ +¼ö ¾øµµ·Ï ¾ÆÆÄÄ¡ ³»ºÎ ±¸Á¶³ª ÇÔ¼ö È£Ãâ, ´Ù¸¥ API ÀϺΰ¡ º¯°æµÈ +°æ¿ì¿¡ ¹Ù²ï´Ù. MMNÀÌ º¯Çϸé Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀº ¸ðµÎ ÃÖ¼ÒÇÑ ´Ù½Ã +ÄÄÆÄÀÏµÇ¾ß ÇÑ´Ù. »õ ¾ÆÆÄÄ¡ ¹öÀü¿¡ ¸Âµµ·Ï Á¶±Ý ¼öÁ¤ÇؾßÇÒ °æ¿ìµµ +ÀÖ´Ù. +
    + +
    OpenSSL
    +
    SSL/TLS¸¦ À§ÇÑ ¿ÀǼҽº µµ±¸
    + Âü°í http://www.openssl.org/
    + +
    Pass Phrase
    +
    °³ÀÎÅ° ÆÄÀÏÀ» º¸È£ÇÏ´Â ¹®±¸. ÀÎÁõÇÏÁö¾ÊÀº »ç¿ëÀÚ°¡ ÀÌ °³ÀÎÅ° +ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¾ÏȣȭÇÏÁö ¸øÇϵµ·Ï ÇÑ´Ù. º¸Åë ¾ÏÈ£±â +(Ciphers)°¡ »ç¿ëÇÏ´Â ºñ¹Ð½º·± ¾ÏÈ£/Çص¶ Å°ÀÌ´Ù.
    Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Æò¹® (Plaintext)
    +
    ¾ÏȣȭÇÏÁö ¾ÊÀº ±Û.
    + +
    °³ÀÎÅ° (Private Key)
    ¹ÞÀº +ÀڷḦ Çص¶ÇÏ°í º¸³»´Â ÀڷḦ ¼­¸íÇϱâÀ§ÇÑ °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography) ½Ã½ºÅÛÀÇ ¾ÏȣŰ.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    ÇÁ·Ï½Ã (Proxy)
    Ŭ¶óÀ̾ðÆ®¿Í +½ÇÁ¦ ¼­¹ö »çÀÌ¿¡ ÀÖ´Â Áß°£ ¼­¹ö. Ŭ¶óÀ̾ðÆ®¿¡°Ô ¿äûÀ» +¹Þ¾Æ ½ÇÁ¦ ¼­¹ö·Î º¸³»°í, ½ÇÁ¦ ¼­¹ö¿¡°Ô¼­ ¹ÞÀº ÀÀ´äÀ» ´Ù½Ã +Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù. ¿©·¯ Ŭ¶óÀ̾ðÆ®°¡ °°Àº ³»¿ëÀ» ¿äûÇϸé +ÇÁ·Ï½Ã´Â ¸Å¹ø ¼­¹ö¿¡ ¿äûÇÏÁö¾Ê°í ij½¬¿¡ ÀúÀåµÈ ³»¿ëÀ» »ç¿ëÇÏ¿© +ÀÀ´ä½Ã°£À» ÁÙÀÏ ¼ö ÀÖ´Ù.
    +Âü°í: mod_proxy
    + +
    °ø°³Å° (Public Key)
    °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography) ½Ã½ºÅÛ¿¡¼­ Å°ÀÇ ¼ÒÀ¯ÀÚ¿¡°Ô º¸³»´Â ¹®±¸¸¦ ¾ÏȣȭÇϰųª +¼ÒÀ¯ÀÚ°¡ ¸¸µç ¼­¸íÀ» Ç®±âÀ§ÇÑ °ø°³µÈ Å°.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    °ø°³Å° ¾Ïȣȭ (Public Key +Cryptography)
    +
    ¾ÏÈ£¿Í Çص¶¿¡ ¼­·Î ´Ù¸¥ Å°¸¦ »ç¿ëÇÏ´Â ºñ´ëĪ(asymmetric) +¾Ïȣȭ ½Ã½ºÅÛÀÇ ¿¬±¸ ¹× È°¿ë. ¾ÏÈ£¿Í Çص¶¿¡ »ç¿ëÇÏ´Â µÎ°³ÀÇ Å°´Â +Å°½Ö(key pair)À» ÀÌ·é´Ù. ºñ´ëĪ ¾Ïȣȭ¶ó°íµµ ºÎ¸¥´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Á¤±ÔÇ¥Çö½Ä (Regular Expression) (Regex)
    ±ÛÀÇ ÆÐÅÏÀ» ±â¼úÇÏ´Â ¹æ½Ä. +¿¹¸¦ µé¾î, "¹®ÀÚ A·Î ½ÃÀÛÇÏ´Â ¸ðµç ´Ü¾î", "¼ýÀÚ 10°³·ÎµÈ ÀüÈ­¹øÈ£", +½ÉÁö¾î "½°Ç¥°¡ µÎ°³ÀÖ°í ´ë¹®ÀÚ Q°¡ ¾ø´Â ¹®Àå" µîÀ» Ç¥ÇöÇÒ ¼ö ÀÖ´Ù. +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¸é ¸Å¿ì À¯¿¬ÇÏ°Ô ÆÄÀÏÀ̳ª ÀÚ¿ø¿¡ ¾î¶² ¼ºÁúÀ» Àû¿ëÇÒ +¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, "images"¶õ µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â ¸ðµç .gif¿Í +.jpg ÆÄÀÏÀº "/images/.*(jpg|gif)$"·Î ÁöĪÇÒ ¼ö +ÀÖ´Ù. ¾ÆÆÄÄ¡´Â PCRE ¶óÀ̺귯¸®¸¦ +»ç¿ëÇÏ¿© Perlȣȯ Á¤±ÔÇ¥Çö½ÄÀ» Áö¿øÇÑ´Ù.
    + +
    ¿ªÇÁ·Ï½Ã (Reverse Proxy)
    +
    Ŭ¶óÀ̾ðÆ®¿¡°Ô ½ÇÁ¦ ¼­¹öó·³ º¸ÀÌ´Â ÇÁ·Ï½Ã (proxy) ¼­¹ö. º¸¾È»ó ÀÌÀ¯ ȤÀº ºÎÇϸ¦ +ºÐ»êÇϱâÀ§ÇØ Å¬¶óÀ̾ðÆ®¿¡°Ô ½ÇÁ¦ ¼­¹ö¸¦ ¼û±æ¶§ À¯¿ëÇÏ´Ù.
    + +
    Secure Sockets Layer (SSL)
    Netscape Communications»ç°¡ TCP/IP +³×Æ®¿÷ÀÇ ÀϹÝÀûÀÎ Åë½Å ÀÎÁõ°ú ¾Ïȣȭ¸¦ À§ÇØ ¸¸µç ÇÁ·ÎÅäÄÝ. +°¡Àå ÀϹÝÀûÀÎ ¿ëµµ´Â HTTPS (HyperText Transfer Protocol +(HTTP) over SSL)ÀÌ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Server Side Includes (SSI)
    HTML ÆÄÀÏ ¾È¿¡ ó¸®Áö½Ã¾î¸¦ Æ÷ÇÔÇÏ´Â +±â¼ú.
    Âü°í: Server Side Includes ¼Ò°³
    + +
    ¼¼¼Ç (Session)
    +
    ÀϹÝÀûÀ¸·Î Åë½ÅÀÇ »óȲ(context) Á¤º¸.
    + +
    SSLeay
    +
    Eric A. YoungÀÌ °³¹ßÇÑ ¿ø·¡ SSL/TLS ±¸Çö ¶óÀ̺귯¸®
    + +
    ´ëĪÀû ¾ÏÈ£¹ý (Symmetric +Cryptography)
    +
    ¾ÏÈ£¿Í Çص¶ ÀÛ¾÷¿¡ °°Àº ¾Ïȣ۸¦ »ç¿ëÇÏ´Â ¾ÏÈ£±â + (Ciphers)ÀÇ ¿¬±¸ ¹× È°¿ë.
    +Âü°í: SSL/TLS Encryption
    + +
    Ÿº¼ (Tarball)
    +
    tar µµ±¸¸¦ »ç¿ëÇÏ¿© ÆÄÀϵéÀ» ¸ðÀº ¹­À½. ¾ÆÆÄÄ¡´Â +tar ÆÄÀÏÀ» ¾ÐÃàÇϰųª pkzipÀ¸·Î ¾ÐÃàÇÏ¿© ¹èÆ÷µÈ´Ù.
    + +
    Transport Layer Security (TLS)
    +
    ÀÎÅͳݱâ¼ú °ü·Ã ±¹Á¦Ç¥ÁØÈ­±â±¸(Internet Engineering Task +Force, IETF)°¡ TCP/IP ³×Æ®¿÷ÀÇ ÀϹÝÀûÀÎ Åë½Å ÀÎÁõ°ú ¾Ïȣȭ¸¦ +À§ÇØ ¸¸µç SSLÀÇ ÈÄ¼Ó ÇÁ·ÎÅäÄÝ. TLS ¹öÀü 1Àº SSL ¹öÀü 3°ú °ÅÀÇ +À¯»çÇÏ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    + +
    Uniform Resource Locator +(URL)
    +
    ÀÎÅͳݿ¡ ÀÖ´Â ÀÚ¿øÀÇ À̸§/ÁÖ¼Ò. Á¤½ÄÀ¸·Î´Â Uniform Resource +Identifier¶ó°í ÇÏ´Â °ÍÀÇ ÀÏ»óÀûÀÎ ºñ°ø½Ä ¸íĪÀÌ´Ù. º¸Åë URLÀº +http³ª https°°Àº ½ºÅ´(scheme), È£½ºÆ®¸í, +°æ·Î·Î ±¸¼ºµÈ´Ù. ÀÌ ÆäÀÌÁöÀÇ URLÀº +http://httpd.apache.org/docs-2.1/glossary.htmlÀÌ´Ù.
    + +
    Uniform Resource Identifier +(URI)
    +
    Ãß»óÀûÀÎ ÀÚ¿øÀ̳ª ½ÇÁ¦ ÀÚ¿øÀ» ÁöĪÇϱâÀ§ÇÑ °£°áÇÑ ¹®ÀÚ¿­. +°ø½ÄÀûÀ¸·Î RFC +2396¿¡¼­ Á¤ÀÇÇÑ´Ù. ¿ùµå¿ÍÀ̵åÀ¥¿¡¼­ »ç¿ëÇÏ´Â URI¸¦ º¸Åë +URLÀ̶ó°í ºÎ¸¥´Ù.
    + +
    °¡»óÈ£½ºÆ® (Virtual Hosting)
    +
    ¾ÆÆÄÄ¡ Çϳª·Î ¿©·¯ À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇϱâ. IP °¡»óÈ£½ºÆ®´Â +À¥»çÀÌÆ®¸¶´Ù IP ÁÖ¼Ò°¡ ´Ù¸£´Ù. À̸§±â¹Ý(name-based) +°¡»óÈ£½ºÆ®´Â È£½ºÆ®¸í¸¸À» »ç¿ëÇϹǷΠÇÑ IP ÁÖ¼Ò¿¡¼­ ¿©·¯ +»çÀÌÆ®¸¦ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.
    +Âü°í: ¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­
    + +
    X.509
    +
    ±¹Á¦Àü±âÅë½Å¿¬ÇÕ(International Telecommunication Union, +ITU-T)ÀÌ ±ÇÀåÇÏ´Â ÀÎÁõ¼­ ¾ç½Ä. SSL/TLS ÀÎÁõ¿¡¼­ »ç¿ëÇÑ´Ù.
    +Âü°í: SSL/TLS ¾Ïȣȭ
    +
    +
    +
    diff --git a/trunk/docs/manual/glossary.xml.meta b/trunk/docs/manual/glossary.xml.meta new file mode 100644 index 0000000000..b0ea4170f5 --- /dev/null +++ b/trunk/docs/manual/glossary.xml.meta @@ -0,0 +1,14 @@ + + + + glossary + / + . + + + de + en + es + ko + + diff --git a/trunk/docs/manual/handler.html b/trunk/docs/manual/handler.html new file mode 100644 index 0000000000..d791187274 --- /dev/null +++ b/trunk/docs/manual/handler.html @@ -0,0 +1,15 @@ +URI: handler.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: handler.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: handler.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: handler.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/handler.html.en b/trunk/docs/manual/handler.html.en new file mode 100644 index 0000000000..b2f347e4e9 --- /dev/null +++ b/trunk/docs/manual/handler.html.en @@ -0,0 +1,153 @@ + + + +Apache's Handler Use - Apache HTTP Server + + + + + +
    <-
    +

    Apache's Handler Use

    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + +

    This document describes the use of Apache's Handlers.

    +
    + +
    top
    +
    +

    What is a Handler

    + + + + +

    A "handler" is an internal Apache representation of the + action to be performed when a file is called. Generally, files + have implicit handlers, based on the file type. Normally, all + files are simply served by the server, but certain file types + are "handled" separately.

    + +

    Apache 1.1 adds the ability to use handlers explicitly. + Based on either filename extensions or on location, handlers + can be specified without relation to file type. This is + advantageous both because it is a more elegant solution, and + because it also allows for both a type and a + handler to be associated with a file. (See also Files with Multiple + Extensions.)

    + +

    Handlers can either be built into the server or included in + a module, or they can be added with the Action directive. The + built-in handlers in the standard distribution are as + follows:

    + +
      +
    • default-handler: Send the file using the + default_handler(), which is the handler used by + default to handle static content. (core)
    • + +
    • send-as-is: Send file with HTTP headers + as is. (mod_asis)
    • + +
    • cgi-script: Treat the file as a CGI + script. (mod_cgi)
    • + +
    • imap-file: Parse as an imagemap rule + file. (mod_imagemap)
    • + +
    • server-info: Get the server's + configuration information. (mod_info)
    • + +
    • server-status: Get the server's status + report. (mod_status)
    • + +
    • type-map: Parse as a type map file for + content negotiation. (mod_negotiation)
    • +
    +
    top
    +
    +

    Examples

    + + +

    Modifying static content using a CGI script

    + + +

    The following directives will cause requests for files with + the html extension to trigger the launch of the + footer.pl CGI script.

    + +

    + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +

    + +

    Then the CGI script is responsible for sending the + originally requested document (pointed to by the + PATH_TRANSLATED environment variable) and making + whatever modifications or additions are desired.

    + + +

    Files with HTTP headers

    + + +

    The following directives will enable the + send-as-is handler, which is used for files which + contain their own HTTP headers. All files in the + /web/htdocs/asis/ directory will be processed by + the send-as-is handler, regardless of their + filename extensions.

    + +

    + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +

    + + +
    top
    +
    +

    Programmer's Note

    + + +

    In order to implement the handler features, an addition has + been made to the Apache API that + you may wish to make use of. Specifically, a new record has + been added to the request_rec structure:

    + +

    + char *handler +

    + +

    If you wish to have your module engage a handler, you need + only to set r->handler to the name of the + handler at any time prior to the invoke_handler + stage of the request. Handlers are implemented as they were + before, albeit using the handler name instead of a content + type. While it is not necessary, the naming convention for + handlers is to use a dash-separated word, with no slashes, so + as to not invade the media type name-space.

    +
    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/handler.html.es b/trunk/docs/manual/handler.html.es new file mode 100644 index 0000000000..23d7e341ae --- /dev/null +++ b/trunk/docs/manual/handler.html.es @@ -0,0 +1,166 @@ + + + +Uso de los Handlers en Apache - Servidor HTTP Apache + + + + + +
    <-
    +

    Uso de los Handlers en Apache

    +
    +

    Idiomas disponibles:  en  | + es  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Este documento describe el uso de los Handlers en Apache.

    +
    + +
    top
    +
    +

    ¿Qué es un Handler?

    + + + + +

    Un "handler" es una representación interna de Apache de + una acción que se va a ejecutar cuando hay una llamada a un + fichero. Generalmente, los ficheros tienen handlers + implícitos, basados en el tipo de fichero de que se + trata. Normalmente, todos los ficheros son simplemente servidos + por el servidor, pero algunos tipos de ficheros se tratan de forma + diferente.

    + +

    Apache 1.1 añade la posibilidad de usar handlers + explicitamente. Basándose en la extension del fichero o en + la ubicación en la que este, se pueden especificar handlers + sin tener en cuenta el tipo de fichero de que se trate. Esto es + una ventaja por dos razones. Primero, es una solución + más elegante. Segundo, porque a un fichero se le pueden + asignar tanto un tipo como un handler. (Consulte + también la sección Ficheros y extensiones + múltiples.)

    + +

    Los Handlers pueden ser tanto ser compilados con el servidor + como incluidos en un módulo, como añadidos con la + directiva Action. Los + handlers compilados con el servidor de la distribución + estándar de Apache son:

    + +
      +
    • default-handler: Envía el fichero + usando el default_handler(), que es el handler + usado por defecto para tratar contenido + estático. (core)
    • + +
    • send-as-is: Envía el fichero con + cabeceras HTTP tal y como es. (mod_asis)
    • + +
    • cgi-script: Trata el fichero como un sript + CGI. (mod_cgi)
    • + +
    • imap-file: Trata el fichero como un mapa de + imágenes. (mod_imap)
    • + +
    • server-info: Extrae la información de + configuración del + servidor. (mod_info)
    • + +
    • server-status: Extrae el informe de estado + del servidor. (mod_status)
    • + +
    • type-map: Trata el fichero como una + correspondencia de tipos para la negociación de contenidos. + (mod_negotiation)
    top
    +
    +

    Ejemplos

    + +

    Modificar contenido estático usando un script + CGI

    + + +

    Las siguientes directivas hacen que cuando haya una + petición de ficheros con la extensión + html se lance el script CGI + footer.pl.

    + +

    + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +

    + +

    En este caso, el script CGI es el responsable de enviar el + documento originalmente solicitado (contenido en la variable de + entorno PATH_TRANSLATED) y de hacer cualquier + modificación o añadido deseado.

    + + +

    Archivos con cabaceras HTTP

    + + +

    Las siguientes directivas activan el handler + send-as-is, que se usa para ficheros que contienen + sus propias cabeceras HTTP. Todos los archivos en el directorio + /web/htdocs/asis/ serán procesados por el + handler send-as-is, sin tener en cuenta su + extension.

    + +

    + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +

    + + +
    top
    +
    +

    Nota para programadores

    + + +

    Para implementar las funcionalidades de los handlers, se ha + hecho un añadido a la API de + Apache que puede que quiera usar. Para ser más + específicos, se ha añadido un nuevo registro a la + estructura request_rec:

    + +

    + char *handler +

    + +

    Si quiere que su módulo llame a un handler , solo tiene + que añadir r->handler al nombre del handler + en cualquier momento antes de la fase invoke_handler + de la petición. Los handlers se implementan siempre como se + hacía antes, aunque usando el nombre del handler en vez de un + tipo de contenido. Aunque no es de obligado cumplimiento, la + convención de nombres para los handlers es que se usen + palabras separadas por guiones, sin barras, de manera que no se + invada el media type name-space.

    +
    +
    +

    Idiomas disponibles:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/handler.html.ja.euc-jp b/trunk/docs/manual/handler.html.ja.euc-jp new file mode 100644 index 0000000000..c14f795bcd --- /dev/null +++ b/trunk/docs/manual/handler.html.ja.euc-jp @@ -0,0 +1,157 @@ + + + +Apache ¤Î¥Ï¥ó¥É¥é¤Î»ÈÍÑ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¤Î¥Ï¥ó¥É¥é¤Î»ÈÍÑ

    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + +

    Apache ¤Î¥Ï¥ó¥É¥é¤Î»ÈÍѤ˴ؤ·¤Æµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥Ï¥ó¥É¥é¤È¤Ï

    + + + + +

    ¡Ö¥Ï¥ó¥É¥é¡×¤È¤Ï¡¢¥Õ¥¡¥¤¥ë¤¬¸Æ¤Ð¤ì¤¿¤È¤­¤Ë¼Â¹Ô¤µ¤ì¤ëÆ°ºî¤Î + Apache ¤Ë¤ª¤±¤ëÆâÉôɽ¸½¤Ç¤¹¡£ + Ä̾¥Õ¥¡¥¤¥ë¤Ï¥Õ¥¡¥¤¥ë·¿¤Ë´ð¤Å¤¤¤¿°ÅÌۤΥϥó¥É¥é¤¬¤¢¤ê¤Þ¤¹¡£ + ÉáÄ̤Ϥ¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤Ïñ¤Ë¥µ¡¼¥Ð¤Ë°·¤ï¤ì¤Þ¤¹¤¬¡¢ + ¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤ÎÃæ¤Ë¤ÏÊ̤ˡ֥ϥó¥É¥ë¡×(ÌõÃí: °·¤¦) + ¤µ¤ì¤ë¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£

    + +

    Apache 1.1 ¤Ç¤Ï¡¢¥Ï¥ó¥É¥é¤òÌÀ¼¨Åª¤Ë»ÈÍѤ¹¤ëµ¡Ç½¤¬Äɲ䵤ì¤Þ¤·¤¿¡£ + ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤äÃÖ¤¤¤Æ¤¤¤ë¾ì½ê¤Ë´ð¤Å¤¤¤Æ¡¢ + ¥Õ¥¡¥¤¥ë·¿¤È´Ø·¸¤Ê¤¯¥Ï¥ó¥É¥é¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï¤è¤êÍ¥²í¤Ê²ò·èË¡¤È¤¤¤¦ÅÀ¤È¡¢¥Õ¥¡¥¤¥ë¤Ë¥¿¥¤¥×¤È¥Ï¥ó¥É¥é¤ÎξÊý¤ò´ØÏ¢ÉÕ¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¤È¤¤¤¦ÅÀ¤ÇÍ¥¤ì¤Æ¤¤¤Þ¤¹¡£ + (Ê£¿ô¤Î³ÈÄ¥»Ò¤Î¤¢¤ë¥Õ¥¡¥¤¥ë¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤)¡£

    + +

    ¥Ï¥ó¥É¥é¤Ï¥µ¡¼¥Ð¤ËÁȤ߹þ¤ó¤À¤ê¡¢¥â¥¸¥å¡¼¥ë¤È¤·¤Æ´Þ¤á¤¿¤ê¡¢ + Action + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤·¤ÆÄɲä·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + °Ê²¼¤Ïɸ½àÇÛÉÛ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¥Ï¥ó¥É¥é¤Ç¤¹¡£ +

    + +
      +
    • default-handler:default_handelr() + ¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¤òÁ÷¤ê¤Þ¤¹¡£ + ÀÅŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤ò°·¤¦¤È¤­¤Ë¥Ç¥Õ¥©¥ë¥È¤Ç»ÈÍѤµ¤ì¤ë¥Ï¥ó¥É¥é¤Ç¤¹¡£ + (core)
    • + +
    • send-as-is: + HTTP ¥Ø¥Ã¥À¤Î¤¢¤ë¥Õ¥¡¥¤¥ë¤ò¤½¤Î¤Þ¤ÞÁ÷¤ê¤Þ¤¹¡£ + (mod_asis)
    • + +
    • cgi-script: ¥Õ¥¡¥¤¥ë¤ò CGI + ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ°·¤¤¤Þ¤¹¡£ + (mod_cgi)
    • + +
    • imap-file: + ¥¤¥á¡¼¥¸¥Þ¥Ã¥×¤Î¥ë¡¼¥ë¥Õ¥¡¥¤¥ë¤È¤·¤Æ²òÀϤ·¤Þ¤¹¡£ + (mod_imagemap)
    • + +
    • server-info: ¥µ¡¼¥Ð¤ÎÀßÄê¾ðÊó¤ò¼èÆÀ¤·¤Þ¤¹¡£ + (mod_info)
    • + +
    • server-status: ¥µ¡¼¥Ð¤Î¾õÂÖÊó¹ð¤ò¼èÆÀ¤·¤Þ¤¹¡£ + (mod_status)
    • + +
    • type-map: + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¤¿¤á¤Î¥¿¥¤¥×¥Þ¥Ã¥×¤È¤·¤Æ²òÀϤ·¤Þ¤¹¡£ + (mod_negotiation)
    • +
    +
    top
    +
    +

    Îã

    + + +

    CGI ¥¹¥¯¥ê¥×¥È¤òÍѤ¤¤ÆÀÅŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤òÊѹ¹¤¹¤ë

    + + +

    °Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ¡¢³ÈÄ¥»Ò¤¬ html + ¤Ç¤¢¤ë¥Õ¥¡¥¤¥ë¤Ï footer.pl + CGI ¥¹¥¯¥ê¥×¥È¤òµ¯Æ°¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +

    + +

    CGI ¥¹¥¯¥ê¥×¥È¤Ï´õ˾¤Î½¤Àµ¤äÄɲäò¹Ô¤Ê¤Ã¤Æ¡¢¸µ¡¹Í׵ᤵ¤ì¤¿Ê¸½ñ + (´Ä¶­ÊÑ¿ô PATH_TRANSLATED + ¤Ç»Ø¤µ¤ì¤Æ¤¤¤Þ¤¹) ¤òÁ÷¤ëÀÕǤ¤¬¤¢¤ê¤Þ¤¹¡£ +

    + + +

    HTTP ¥Ø¥Ã¥À¤Î¤¢¤ë¥Õ¥¡¥¤¥ë

    + + +

    °Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï send-as-is + ¥Ï¥ó¥É¥é¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë»Ø¼¨¤·¤Þ¤¹¡£¤³¤Î¥Ï¥ó¥É¥é¤Ï¼«Ê¬¼«¿È¤Î HTTP + ¥Ø¥Ã¥À¤ò»ý¤Ã¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤³¤Ç¤Ï¡¢³ÈÄ¥»Ò¤Ë´Ø¤ï¤é¤º¡¢ + /web/htdocs/asis ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ëÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤Ï + send-as-is ¥Ï¥ó¥É¥é¤Ë¤è¤Ã¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +

    + + +
    top
    +
    +

    ¥×¥í¥°¥é¥Þ¸þ¤±¤Î¥á¥â

    + + +

    ¥Ï¥ó¥É¥é¤Îµ¡Ç½¤ò¼ÂÁõ¤¹¤ë¤¿¤á¤Ë¡¢ÍøÍѤ¹¤ë¤ÈÊØÍø¤«¤â¤·¤ì¤Ê¤¤¤â¤Î¤¬ + Apache API + ¤ËÄɲ䵤ì¤Þ¤·¤¿¡£¾Ü¤·¤¯¸À¤¦¤È¡¢request_rec + ¹½Â¤ÂΤ˿·¤·¤¤¥ì¥³¡¼¥É¤¬Äɲ䵤줿¤È¤¤¤¦¤³¤È¤Ç¤¹¡£

    + +

    + char *handler +

    + +

    ¤â¤·¥â¥¸¥å¡¼¥ë¤¬¥Ï¥ó¥É¥é¤Ë´Ø¤ï¤ê¤¿¤¤¾ì¹ç¡¢ + ¤ä¤é¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤¬ invoke_handler + ¥¹¥Æ¡¼¥¸¤Ë㤹¤ë°ÊÁ°¤Ë r->handler + ¤òÀßÄꤹ¤ë¤³¤È¤À¤±¤Ç¤¹¡£¥Ï¥ó¥É¥é¤Ï¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ÎÂå¤ï¤ê¤Ë + ¥Ï¥ó¥É¥é̾¤ò»È¤¦¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È°Ê³°¤Ï¡¢°ÊÁ°¤ÈƱ¤¸¤è¤¦¤Ë¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ɬ¤ºÍ׵ᤵ¤ì¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¥á¥Ç¥£¥¢¥¿¥¤¥× + ¤Î̾Á°¶õ´Ö¤ò¿¯¤µ¤Ê¤¤¤è¤¦¤Ë¡¢¥Ï¥ó¥É¥é¤Î̾Á°¤Ë¤Ï¥¹¥é¥Ã¥·¥å¤ò´Þ¤Þ¤Ê¤¤¡¢ + ¥À¥Ã¥·¥å (ÌõÃí: "-") ¤ÇʬΥ¤µ¤ì¤¿Ì¾Á°¤òÉÕ¤±¤ë½¬´·¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/handler.html.ko.euc-kr b/trunk/docs/manual/handler.html.ko.euc-kr new file mode 100644 index 0000000000..e2ca3b3676 --- /dev/null +++ b/trunk/docs/manual/handler.html.ko.euc-kr @@ -0,0 +1,149 @@ + + + +¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    Çڵ鷯°¡ ¹«¾ùÀΰ¡

    + + + + +

    ÆÄÀÏÀ» ¿äûÇÒ¶§ ¾ÆÆÄÄ¡°¡ ³»ºÎÀûÀ¸·Î ¼öÇàÇÒ ÀÛ¾÷À» + "Çڵ鷯(handler)"¶ó°í ÇÑ´Ù. ÀϹÝÀûÀ¸·Î ÆÄÀÏÀº ÆÄÀÏ Á¾·ù¿¡ + µû¶ó ¾Ï¹¬ÀûÀÎ Çڵ鷯¸¦ °¡Áö°í ÀÖ´Ù. ¸ðµç ÆÄÀÏÀº º¸Åë °£´ÜÈ÷ + ¼­¹ö°¡ ¼­ºñ½ºÇÏÁö¸¸, ¾î¶² ÆÄÀÏ Á¾·ù´Â µû·Î "󸮵ȴÙ(handled)".

    + +

    Apache 1.1ºÎÅÍ Çڵ鷯¸¦ ¸í½ÃÀûÀ¸·Î »ç¿ëÇÒ ¼ö ÀÖ°Ô µÇ¾ú´Ù. + ÆÄÀÏ Á¾·ù¿Í °ü°è¾øÀÌ Çڵ鷯¸¦ ÆÄÀÏÀÇ È®ÀåÀÚ³ª À§Ä¡¿¡ µû¶ó + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÀÌ´Â ´õ ÈǸ¢ÇÑ ¹æ¹ýÀÌ°í ÆÄÀÏÀ» Á¾·ù¿Í Çڵ鷯 + µÑ ¸ðµÎ¿Í ¿¬°èÇÒ ¼ö Àֱ⶧¹®¿¡ ÁÁ´Ù. (¿©·¯ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀϵµ + Âü°í)

    + +

    Çڵ鷯´Â ¼­¹ö³ª ¸ðµâ·Î ±¸ÇöÇÏ¿©, Action Áö½Ã¾î·Î Ãß°¡ÇÒ + ¼ö ÀÖ´Ù. Ç¥ÁØ ¹èÆ÷º»¿¡ ÀÖ´Â ±âº» Çڵ鷯´Â ´ÙÀ½°ú °°´Ù:

    + +
      +
    • default-handler: Á¤ÀûÀÎ ³»¿ëÀ» + ó¸®ÇϱâÀ§ÇØ ±âº»ÀûÀ¸·Î »ç¿ëÇÏ´Â Çڵ鷯 + default_handler()¸¦ »ç¿ëÇÏ¿© ÆÄÀÏÀ» º¸³½´Ù. + (core)
    • + +
    • send-as-is: HTTP Çì´õ°¡ ÀÖ´Â ÆÄÀÏÀ» + ±×´ë·Î º¸³½´Ù. (mod_asis)
    • + +
    • cgi-script: ÆÄÀÏÀ» CGI·Î ó¸®ÇÑ´Ù. + (mod_cgi)
    • + +
    • imap-file: imagemap ±ÔÄ¢ ÆÄÀÏ·Î + ó¸®ÇÑ´Ù. (mod_imap)
    • + +
    • server-info: ¼­¹öÀÇ ¼³Á¤ Á¤º¸¸¦ + ¾Ë·ÁÁØ´Ù. (mod_info)
    • + +
    • server-status: ¼­¹öÀÇ »óŸ¦ º¸°íÇÑ´Ù. + (mod_status)
    • + +
    • type-map: ³»¿ëÇù»ó¿¡ »ç¿ëÇÒ + type mapÀ¸·Î ó¸®ÇÑ´Ù. + (mod_negotiation)
    • +
    +
    top
    +
    +

    ¿¹Á¦

    + + +

    CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ¿© Á¤ÀûÀÎ ³»¿ë ¼öÁ¤Çϱâ

    + + +

    ´ÙÀ½ Áö½Ã¾î´Â È®ÀåÀÚ°¡ htmlÀÎ ÆÄÀÏÀ» + ¿äûÇÒ °æ¿ì footer.pl CGI ½ºÅ©¸³Æ®¸¦ ¶ç¿î´Ù.

    + +

    + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +

    + +

    CGI ½ºÅ©¸³Æ®´Â + (PATH_TRANSLATED ȯ°æº¯¼ö°¡ ÁöĪÇÏ´Â) ¿ø·¡ + ¿äûÇÑ ¹®¼­¸¦ ÀûÀýÈ÷ ¼öÁ¤ÇÑ ÈÄ º¸³½´Ù.

    + + +

    HTTP Çì´õ¸¦ Æ÷ÇÔÇÏ´Â ÆÄÀÏ

    + + +

    ´ÙÀ½ Áö½Ã¾î´Â HTTP Çì´õ¸¦ Æ÷ÇÔÇÏ´Â ÆÄÀÏ¿¡ + send-as-is Çڵ鷯¸¦ Áö½ÃÇÑ´Ù. + /web/htdocs/asis/ µð·ºÅ丮 ¾È¿¡ ÀÖ´Â ¸ðµç + ÆÄÀÏÀº È®ÀåÀÚ¿Í °ü°è¾øÀÌ send-as-is Çڵ鷯°¡ + ó¸®ÇÑ´Ù.

    + +

    + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +

    + + +
    top
    +
    +

    ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ Á¤º¸

    + + +

    Çڵ鷯 ±â´ÉÀ» ±¸ÇöÇϱâÀ§ÇØ »ç¿ëÇÔÁ÷ÇÑ + Apache API°¡ Ãß°¡µÇ¾ú´Ù. + ƯÈ÷ request_rec ±¸Á¶Ã¼¿¡ »õ·Î¿î Çʵ尡 + Ãß°¡µÇ¾ú´Ù:

    + +

    + char *handler +

    + +

    ¸ðµâÀÌ Çڵ鷯¸¦ »ç¿ëÇÏ·Á¸é, ¿äûÀÇ + invoke_handler ´Ü°è ÀÌÀü¿¡ + r->handler¿¡ Çڵ鷯 À̸§À» ÁöÁ¤ÇØÁֱ⸸ + ÇÏ¸é µÈ´Ù. Çڵ鷯´Â content type ´ë½Å Çڵ鷯 À̸§À» »ç¿ëÇÑ + °ÍÀ» Á¦¿ÜÇÏ°í´Â Àü°ú °°ÀÌ ±¸ÇöµÇ¾ú´Ù. ²À Áöų ÇÊ¿ä´Â ¾øÁö¸¸ + Çڵ鷯 À̸§¿¡ ½½·¡½¬¸¦ »ç¿ëÇÏÁö ¾Ê°í, ´Ü¾îµé »çÀÌ¿¡ »©±â + ±âÈ£¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÀϹÝÀûÀÌ´Ù. ±×·¡¼­ Çڵ鷯 À̸§ÀÌ + media type°ú °ãÄ¡Áö ¾Ê´Â´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/handler.xml b/trunk/docs/manual/handler.xml new file mode 100644 index 0000000000..d9302af3e4 --- /dev/null +++ b/trunk/docs/manual/handler.xml @@ -0,0 +1,163 @@ + + + + + + + + + + Apache's Handler Use + + +

    This document describes the use of Apache's Handlers.

    +
    + +
    + What is a Handler + + + mod_actions + mod_asis + mod_cgi + mod_imagemap + mod_info + mod_mime + mod_negotiation + mod_status + + + Action + AddHandler + RemoveHandler + SetHandler + + + + +

    A "handler" is an internal Apache representation of the + action to be performed when a file is called. Generally, files + have implicit handlers, based on the file type. Normally, all + files are simply served by the server, but certain file types + are "handled" separately.

    + +

    Apache 1.1 adds the ability to use handlers explicitly. + Based on either filename extensions or on location, handlers + can be specified without relation to file type. This is + advantageous both because it is a more elegant solution, and + because it also allows for both a type and a + handler to be associated with a file. (See also Files with Multiple + Extensions.)

    + +

    Handlers can either be built into the server or included in + a module, or they can be added with the Action directive. The + built-in handlers in the standard distribution are as + follows:

    + +
      +
    • default-handler: Send the file using the + default_handler(), which is the handler used by + default to handle static content. (core)
    • + +
    • send-as-is: Send file with HTTP headers + as is. (mod_asis)
    • + +
    • cgi-script: Treat the file as a CGI + script. (mod_cgi)
    • + +
    • imap-file: Parse as an imagemap rule + file. (mod_imagemap)
    • + +
    • server-info: Get the server's + configuration information. (mod_info)
    • + +
    • server-status: Get the server's status + report. (mod_status)
    • + +
    • type-map: Parse as a type map file for + content negotiation. (mod_negotiation)
    • +
    +
    +
    + Examples + +
    + Modifying static content using a CGI script + +

    The following directives will cause requests for files with + the html extension to trigger the launch of the + footer.pl CGI script.

    + + + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +
    + +

    Then the CGI script is responsible for sending the + originally requested document (pointed to by the + PATH_TRANSLATED environment variable) and making + whatever modifications or additions are desired.

    + +
    +
    + Files with HTTP headers + +

    The following directives will enable the + send-as-is handler, which is used for files which + contain their own HTTP headers. All files in the + /web/htdocs/asis/ directory will be processed by + the send-as-is handler, regardless of their + filename extensions.

    + + + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +
    + +
    +
    +
    + Programmer's Note + +

    In order to implement the handler features, an addition has + been made to the Apache API that + you may wish to make use of. Specifically, a new record has + been added to the request_rec structure:

    + + + char *handler + + +

    If you wish to have your module engage a handler, you need + only to set r->handler to the name of the + handler at any time prior to the invoke_handler + stage of the request. Handlers are implemented as they were + before, albeit using the handler name instead of a content + type. While it is not necessary, the naming convention for + handlers is to use a dash-separated word, with no slashes, so + as to not invade the media type name-space.

    +
    +
    + + + + + diff --git a/trunk/docs/manual/handler.xml.es b/trunk/docs/manual/handler.xml.es new file mode 100644 index 0000000000..e05e0bcc82 --- /dev/null +++ b/trunk/docs/manual/handler.xml.es @@ -0,0 +1,173 @@ + + + + + + + + + + Uso de los Handlers en Apache + + +

    Este documento describe el uso de los Handlers en Apache.

    +
    + +
    + ¿Qué es un Handler? + + + mod_actions + mod_asis + mod_cgi + mod_imap + mod_info + mod_mime + mod_negotiation + mod_status + + + Action + AddHandler + RemoveHandler + SetHandler + + + + +

    Un "handler" es una representación interna de Apache de + una acción que se va a ejecutar cuando hay una llamada a un + fichero. Generalmente, los ficheros tienen handlers + implícitos, basados en el tipo de fichero de que se + trata. Normalmente, todos los ficheros son simplemente servidos + por el servidor, pero algunos tipos de ficheros se tratan de forma + diferente.

    + +

    Apache 1.1 añade la posibilidad de usar handlers + explicitamente. Basándose en la extension del fichero o en + la ubicación en la que este, se pueden especificar handlers + sin tener en cuenta el tipo de fichero de que se trate. Esto es + una ventaja por dos razones. Primero, es una solución + más elegante. Segundo, porque a un fichero se le pueden + asignar tanto un tipo como un handler. (Consulte + también la sección Ficheros y extensiones + múltiples.)

    + +

    Los Handlers pueden ser tanto ser compilados con el servidor + como incluidos en un módulo, como añadidos con la + directiva Action. Los + handlers compilados con el servidor de la distribución + estándar de Apache son:

    + +
      +
    • default-handler: Envía el fichero + usando el default_handler(), que es el handler + usado por defecto para tratar contenido + estático. (core)
    • + +
    • send-as-is: Envía el fichero con + cabeceras HTTP tal y como es. (mod_asis)
    • + +
    • cgi-script: Trata el fichero como un sript + CGI. (mod_cgi)
    • + +
    • imap-file: Trata el fichero como un mapa de + imágenes. (mod_imap)
    • + +
    • server-info: Extrae la información de + configuración del + servidor. (mod_info)
    • + +
    • server-status: Extrae el informe de estado + del servidor. (mod_status)
    • + +
    • type-map: Trata el fichero como una + correspondencia de tipos para la negociación de contenidos. + (mod_negotiation)
    + +
    Ejemplos + +
    + Modificar contenido estático usando un script + CGI + +

    Las siguientes directivas hacen que cuando haya una + petición de ficheros con la extensión + html se lance el script CGI + footer.pl.

    + + + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +
    + +

    En este caso, el script CGI es el responsable de enviar el + documento originalmente solicitado (contenido en la variable de + entorno PATH_TRANSLATED) y de hacer cualquier + modificación o añadido deseado.

    + +
    +
    + Archivos con cabaceras HTTP + +

    Las siguientes directivas activan el handler + send-as-is, que se usa para ficheros que contienen + sus propias cabeceras HTTP. Todos los archivos en el directorio + /web/htdocs/asis/ serán procesados por el + handler send-as-is, sin tener en cuenta su + extension.

    + + + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +
    + +
    +
    +
    + Nota para programadores + +

    Para implementar las funcionalidades de los handlers, se ha + hecho un añadido a la API de + Apache que puede que quiera usar. Para ser más + específicos, se ha añadido un nuevo registro a la + estructura request_rec:

    + + + char *handler + + +

    Si quiere que su módulo llame a un handler , solo tiene + que añadir r->handler al nombre del handler + en cualquier momento antes de la fase invoke_handler + de la petición. Los handlers se implementan siempre como se + hacía antes, aunque usando el nombre del handler en vez de un + tipo de contenido. Aunque no es de obligado cumplimiento, la + convención de nombres para los handlers es que se usen + palabras separadas por guiones, sin barras, de manera que no se + invada el media type name-space.

    +
    +
    + + + + + + diff --git a/trunk/docs/manual/handler.xml.ja b/trunk/docs/manual/handler.xml.ja new file mode 100644 index 0000000000..9bc5a2410e --- /dev/null +++ b/trunk/docs/manual/handler.xml.ja @@ -0,0 +1,162 @@ + + + + + + + + + + Apache $B$N%O%s%I%i$N;HMQ(B + + +

    Apache $B$N%O%s%I%i$N;HMQ$K4X$7$F5-=R$7$F$$$^$9!#(B

    +
    + +
    + $B%O%s%I%i$H$O(B + + + mod_actions + mod_asis + mod_cgi + mod_imagemap + mod_info + mod_mime + mod_negotiation + mod_status + + + Action + AddHandler + RemoveHandler + SetHandler + + + + +

    $B!V%O%s%I%i!W$H$O!"%U%!%$%k$,8F$P$l$?$H$-$Ko!"%U%!%$%k$O%U%!%$%k7?$K4p$E$$$?0EL[$N%O%s%I%i$,$"$j$^$9!#(B + $BIaDL$O$9$Y$F$N%U%!%$%k$OC1$K%5!<%P$K07$o$l$^$9$,!"(B + $B%U%!%$%k%?%$%W$NCf$K$OJL$K!V%O%s%I%k!W(B($BLuCm(B: $B07$&(B) + $B$5$l$k$b$N$b$"$j$^$9!#(B

    + +

    Apache 1.1 $B$G$O!"%O%s%I%i$rL@<(E*$K;HMQ$9$k5!G=$,DI2C$5$l$^$7$?!#(B + $B%U%!%$%k$N3HD%;R$dCV$$$F$$$k>l=j$K4p$E$$$F!"(B + $B%U%!%$%k7?$H4X78$J$/%O%s%I%i$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B$3$l$O$h$jM%2m$J2r7hK!$H$$$&E@$H!"%U%!%$%k$K%?%$%W(B$B$H(B$B%O%s%I%i$NN>J}$r4XO"IU$1$k$3$H$,$G$-$k$H$$$&E@$GM%$l$F$$$^$9!#(B + ($BJ#?t$N3HD%;R$N$"$k%U%!%$%k(B$B$b;2>H$7$F$/$@$5$$(B)$B!#(B

    + +

    $B%O%s%I%i$O%5!<%P$KAH$_9~$s$@$j!"%b%8%e!<%k$H$7$F4^$a$?$j!"(B + Action + $B%G%#%l%/%F%#%V$H$7$FDI2C$7$?$j$9$k$3$H$,$G$-$^$9!#(B + $B0J2<$OI8=`G[I[$KAH$_9~$^$l$F$$$k%O%s%I%i$G$9!#(B +

    + +
      +
    • default-handler:default_handelr() + $B$r;H$C$F%U%!%$%k$rAw$j$^$9!#(B + $B@EE*$J%3%s%F%s%D$r07$&$H$-$K%G%U%)%k%H$G;HMQ$5$l$k%O%s%I%i$G$9!#(B + (core)
    • + +
    • send-as-is: + HTTP $B%X%C%@$N$"$k%U%!%$%k$r$=$N$^$^Aw$j$^$9!#(B + (mod_asis)
    • + +
    • cgi-script: $B%U%!%$%k$r(B CGI + $B%9%/%j%W%H$H$7$F07$$$^$9!#(B + (mod_cgi)
    • + +
    • imap-file: + $B%$%a!<%8%^%C%W$N%k!<%k%U%!%$%k$H$7$F2r@O$7$^$9!#(B + (mod_imagemap)
    • + +
    • server-info: $B%5!<%P$N@_Dj>pJs$rmod_info)
    • + +
    • server-status: $B%5!<%P$N>uBVJs9p$rmod_status)
    • + +
    • type-map: + $B%3%s%F%s%H%M%4%7%(!<%7%g%s$N$?$a$N%?%$%W%^%C%W$H$7$F2r@O$7$^$9!#(B + (mod_negotiation)
    • +
    +
    +
    + $BNc(B + +
    + CGI $B%9%/%j%W%H$rMQ$$$F@EE*$J%3%s%F%s%D$rJQ99$9$k(B + +

    $B0J2<$N%G%#%l%/%F%#%V$K$h$C$F!"3HD%;R$,(B html + $B$G$"$k%U%!%$%k$O(B footer.pl + CGI $B%9%/%j%W%H$r5/F0$9$k$h$&$K$J$j$^$9!#(B

    + + + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +
    + +

    CGI $B%9%/%j%W%H$O4uK>$N=$@5$dDI2C$r9T$J$C$F!"85!9MW5a$5$l$?J8=q(B + ($B4D6-JQ?t(B PATH_TRANSLATED + $B$G;X$5$l$F$$$^$9(B) $B$rAw$k@UG$$,$"$j$^$9!#(B +

    + +
    +
    + HTTP $B%X%C%@$N$"$k%U%!%$%k(B + +

    $B0J2<$N%G%#%l%/%F%#%V$O(B send-as-is + $B%O%s%I%i$r;HMQ$9$k$h$&$K;X<($7$^$9!#$3$N%O%s%I%i$O<+J,<+?H$N(B HTTP + $B%X%C%@$r;}$C$F$$$k%U%!%$%k$K;HMQ$5$l$^$9!#$3$3$G$O!"3HD%;R$K4X$o$i$:!"(B + /web/htdocs/asis $B%G%#%l%/%H%j$K$"$kA4$F$N%U%!%$%k$O(B + send-as-is $B%O%s%I%i$K$h$C$F07$o$l$^$9!#(B

    + + + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +
    + +
    +
    +
    + $B%W%m%0%i%^8~$1$N%a%b(B + +

    $B%O%s%I%i$N5!G=$rApache API + $B$KDI2C$5$l$^$7$?!#>\$7$/8@$&$H!"(Brequest_rec + $B9=B$BN$K?7$7$$%l%3!<%I$,DI2C$5$l$?$H$$$&$3$H$G$9!#(B

    + + + char *handler + + +

    $B$b$7%b%8%e!<%k$,%O%s%I%i$K4X$o$j$?$$>l9g!"(B + $B$d$i$J$1$l$P$J$i$J$$$3$H$O!"%j%/%(%9%H$,(B invoke_handler + $B%9%F!<%8$KC#$9$k0JA0$K(B r->handler + $B$r@_Dj$9$k$3$H$@$1$G$9!#%O%s%I%i$O%3%s%F%s%H%?%$%W$NBe$o$j$K(B + $B%O%s%I%iL>$r;H$&$h$&$K$J$C$F$$$k$3$H0J30$O!"0JA0$HF1$8$h$&$KA06u4V$r?/$5$J$$$h$&$K!"%O%s%I%i$NL>A0$K$O%9%i%C%7%e$r4^$^$J$$!"(B + $B%@%C%7%e(B ($BLuCm(B: "-") $B$GJ,N%$5$l$?L>A0$rIU$1$k=,47$K$J$C$F$$$^$9!#(B

    +
    +
    diff --git a/trunk/docs/manual/handler.xml.ko b/trunk/docs/manual/handler.xml.ko new file mode 100644 index 0000000000..def55f317e --- /dev/null +++ b/trunk/docs/manual/handler.xml.ko @@ -0,0 +1,157 @@ + + + + + + + + + + ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    + Çڵ鷯°¡ ¹«¾ùÀΰ¡ + + + mod_actions + mod_asis + mod_cgi + mod_imap + mod_info + mod_mime + mod_negotiation + mod_status + + + Action + AddHandler + RemoveHandler + SetHandler + + + + +

    ÆÄÀÏÀ» ¿äûÇÒ¶§ ¾ÆÆÄÄ¡°¡ ³»ºÎÀûÀ¸·Î ¼öÇàÇÒ ÀÛ¾÷À» + "Çڵ鷯(handler)"¶ó°í ÇÑ´Ù. ÀϹÝÀûÀ¸·Î ÆÄÀÏÀº ÆÄÀÏ Á¾·ù¿¡ + µû¶ó ¾Ï¹¬ÀûÀÎ Çڵ鷯¸¦ °¡Áö°í ÀÖ´Ù. ¸ðµç ÆÄÀÏÀº º¸Åë °£´ÜÈ÷ + ¼­¹ö°¡ ¼­ºñ½ºÇÏÁö¸¸, ¾î¶² ÆÄÀÏ Á¾·ù´Â µû·Î "󸮵ȴÙ(handled)".

    + +

    Apache 1.1ºÎÅÍ Çڵ鷯¸¦ ¸í½ÃÀûÀ¸·Î »ç¿ëÇÒ ¼ö ÀÖ°Ô µÇ¾ú´Ù. + ÆÄÀÏ Á¾·ù¿Í °ü°è¾øÀÌ Çڵ鷯¸¦ ÆÄÀÏÀÇ È®ÀåÀÚ³ª À§Ä¡¿¡ µû¶ó + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÀÌ´Â ´õ ÈǸ¢ÇÑ ¹æ¹ýÀÌ°í ÆÄÀÏÀ» Á¾·ù¿Í Çڵ鷯 + µÑ ¸ðµÎ¿Í ¿¬°èÇÒ ¼ö Àֱ⶧¹®¿¡ ÁÁ´Ù. (¿©·¯ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀϵµ + Âü°í)

    + +

    Çڵ鷯´Â ¼­¹ö³ª ¸ðµâ·Î ±¸ÇöÇÏ¿©, Action Áö½Ã¾î·Î Ãß°¡ÇÒ + ¼ö ÀÖ´Ù. Ç¥ÁØ ¹èÆ÷º»¿¡ ÀÖ´Â ±âº» Çڵ鷯´Â ´ÙÀ½°ú °°´Ù:

    + +
      +
    • default-handler: Á¤ÀûÀÎ ³»¿ëÀ» + ó¸®ÇϱâÀ§ÇØ ±âº»ÀûÀ¸·Î »ç¿ëÇÏ´Â Çڵ鷯 + default_handler()¸¦ »ç¿ëÇÏ¿© ÆÄÀÏÀ» º¸³½´Ù. + (core)
    • + +
    • send-as-is: HTTP Çì´õ°¡ ÀÖ´Â ÆÄÀÏÀ» + ±×´ë·Î º¸³½´Ù. (mod_asis)
    • + +
    • cgi-script: ÆÄÀÏÀ» CGI·Î ó¸®ÇÑ´Ù. + (mod_cgi)
    • + +
    • imap-file: imagemap ±ÔÄ¢ ÆÄÀÏ·Î + ó¸®ÇÑ´Ù. (mod_imap)
    • + +
    • server-info: ¼­¹öÀÇ ¼³Á¤ Á¤º¸¸¦ + ¾Ë·ÁÁØ´Ù. (mod_info)
    • + +
    • server-status: ¼­¹öÀÇ »óŸ¦ º¸°íÇÑ´Ù. + (mod_status)
    • + +
    • type-map: ³»¿ëÇù»ó¿¡ »ç¿ëÇÒ + type mapÀ¸·Î ó¸®ÇÑ´Ù. + (mod_negotiation)
    • +
    +
    +
    + ¿¹Á¦ + +
    + CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ¿© Á¤ÀûÀÎ ³»¿ë ¼öÁ¤Çϱâ + +

    ´ÙÀ½ Áö½Ã¾î´Â È®ÀåÀÚ°¡ htmlÀÎ ÆÄÀÏÀ» + ¿äûÇÒ °æ¿ì footer.pl CGI ½ºÅ©¸³Æ®¸¦ ¶ç¿î´Ù.

    + + + Action add-footer /cgi-bin/footer.pl
    + AddHandler add-footer .html +
    + +

    CGI ½ºÅ©¸³Æ®´Â + (PATH_TRANSLATED ȯ°æº¯¼ö°¡ ÁöĪÇÏ´Â) ¿ø·¡ + ¿äûÇÑ ¹®¼­¸¦ ÀûÀýÈ÷ ¼öÁ¤ÇÑ ÈÄ º¸³½´Ù.

    + +
    +
    + HTTP Çì´õ¸¦ Æ÷ÇÔÇÏ´Â ÆÄÀÏ + +

    ´ÙÀ½ Áö½Ã¾î´Â HTTP Çì´õ¸¦ Æ÷ÇÔÇÏ´Â ÆÄÀÏ¿¡ + send-as-is Çڵ鷯¸¦ Áö½ÃÇÑ´Ù. + /web/htdocs/asis/ µð·ºÅ丮 ¾È¿¡ ÀÖ´Â ¸ðµç + ÆÄÀÏÀº È®ÀåÀÚ¿Í °ü°è¾øÀÌ send-as-is Çڵ鷯°¡ + ó¸®ÇÑ´Ù.

    + + + <Directory /web/htdocs/asis>
    + SetHandler send-as-is
    + </Directory> +
    + +
    +
    +
    + ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ Á¤º¸ + +

    Çڵ鷯 ±â´ÉÀ» ±¸ÇöÇϱâÀ§ÇØ »ç¿ëÇÔÁ÷ÇÑ + Apache API°¡ Ãß°¡µÇ¾ú´Ù. + ƯÈ÷ request_rec ±¸Á¶Ã¼¿¡ »õ·Î¿î Çʵ尡 + Ãß°¡µÇ¾ú´Ù:

    + + + char *handler + + +

    ¸ðµâÀÌ Çڵ鷯¸¦ »ç¿ëÇÏ·Á¸é, ¿äûÀÇ + invoke_handler ´Ü°è ÀÌÀü¿¡ + r->handler¿¡ Çڵ鷯 À̸§À» ÁöÁ¤ÇØÁֱ⸸ + ÇÏ¸é µÈ´Ù. Çڵ鷯´Â content type ´ë½Å Çڵ鷯 À̸§À» »ç¿ëÇÑ + °ÍÀ» Á¦¿ÜÇÏ°í´Â Àü°ú °°ÀÌ ±¸ÇöµÇ¾ú´Ù. ²À Áöų ÇÊ¿ä´Â ¾øÁö¸¸ + Çڵ鷯 À̸§¿¡ ½½·¡½¬¸¦ »ç¿ëÇÏÁö ¾Ê°í, ´Ü¾îµé »çÀÌ¿¡ »©±â + ±âÈ£¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÀϹÝÀûÀÌ´Ù. ±×·¡¼­ Çڵ鷯 À̸§ÀÌ + media type°ú °ãÄ¡Áö ¾Ê´Â´Ù.

    +
    +
    + + + + + diff --git a/trunk/docs/manual/handler.xml.meta b/trunk/docs/manual/handler.xml.meta new file mode 100644 index 0000000000..6036358d21 --- /dev/null +++ b/trunk/docs/manual/handler.xml.meta @@ -0,0 +1,14 @@ + + + + handler + / + . + + + en + es + ja + ko + + diff --git a/trunk/docs/manual/howto/auth.html b/trunk/docs/manual/howto/auth.html new file mode 100644 index 0000000000..fddd99738b --- /dev/null +++ b/trunk/docs/manual/howto/auth.html @@ -0,0 +1,11 @@ +URI: auth.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: auth.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: auth.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/howto/auth.html.en b/trunk/docs/manual/howto/auth.html.en new file mode 100644 index 0000000000..439fde4e78 --- /dev/null +++ b/trunk/docs/manual/howto/auth.html.en @@ -0,0 +1,352 @@ + + + +Authentication, Authorization and Access Control - Apache HTTP Server + + + + + +
    <-
    +

    Authentication, Authorization and Access Control

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Authentication is any process by which you verify that + someone is who they claim they are. Authorization is any + process by which someone is allowed to be where they want to + go, or to have information that they want to have.

    +
    + +
    top
    +
    top
    +
    +

    Introduction

    +

    If you have information on your web site that is sensitive + or intended for only a small group of people, the techniques in + this article will help you make sure that the people that see + those pages are the people that you wanted to see them.

    + +

    This article covers the "standard" way of protecting parts + of your web site that most of you are going to use.

    +
    top
    +
    +

    The Prerequisites

    +

    The directives discussed in this article will need to go + either in your main server configuration file (typically in a + <Directory> section), or + in per-directory configuration files (.htaccess files).

    + +

    If you plan to use .htaccess files, you will + need to have a server configuration that permits putting + authentication directives in these files. This is done with the + AllowOverride directive, which + specifies which directives, if any, may be put in per-directory + configuration files.

    + +

    Since we're talking here about authentication, you will need + an AllowOverride directive like the + following:

    + +

    + AllowOverride AuthConfig +

    + +

    Or, if you are just going to put the directives directly in + your main server configuration file, you will of course need to + have write permission to that file.

    + +

    And you'll need to know a little bit about the directory + structure of your server, in order to know where some files are + kept. This should not be terribly difficult, and I'll try to + make this clear when we come to that point.

    +
    top
    +
    +

    Getting it working

    +

    Here's the basics of password protecting a directory on your + server.

    + +

    You'll need to create a password file. This file should be + placed somewhere not accessible from the web. This is so that + folks cannot download the password file. For example, if your + documents are served out of /usr/local/apache/htdocs you + might want to put the password file(s) in + /usr/local/apache/passwd.

    + +

    To create the file, use the htpasswd utility that + came with Apache. This will be located in the bin directory + of wherever you installed Apache. To create the file, type:

    + +

    + htpasswd -c /usr/local/apache/passwd/passwords rbowen +

    + +

    htpasswd will ask you for the password, and + then ask you to type it again to confirm it:

    + +

    + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +

    + +

    If htpasswd is not in your path, of course + you'll have to type the full path to the file to get it to run. + On my server, it's located at + /usr/local/apache/bin/htpasswd

    + +

    Next, you'll need to configure the server to request a + password and tell the server which users are allowed access. + You can do this either by editing the httpd.conf + file or using an .htaccess file. For example, if + you wish to protect the directory + /usr/local/apache/htdocs/secret, you can use the + following directives, either placed in the file + /usr/local/apache/htdocs/secret/.htaccess, or + placed in httpd.conf inside a <Directory + /usr/local/apache/apache/htdocs/secret> section.

    + +

    + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +

    + +

    Let's examine each of those directives individually. The AuthType directive selects + that method that is used to authenticate the user. The most + common method is Basic, and this is the method + implemented by mod_auth_basic. It is important to be aware, + however, that Basic authentication sends the password from the client to + the browser unencrypted. This method should therefore not be used for + highly sensitive data. Apache supports one other authentication method: + AuthType Digest. This method is implemented by mod_auth_digest and is much more secure. Only the most recent + versions of clients are known to support Digest authentication.

    + +

    The AuthName directive sets + the Realm to be used in the authentication. The realm serves + two major functions. First, the client often presents this information to + the user as part of the password dialog box. Second, it is used by the + client to determine what password to send for a given authenticated + area.

    + +

    So, for example, once a client has authenticated in the + "Restricted Files" area, it will automatically + retry the same password for any area on the same server that is + marked with the "Restricted Files" Realm. + Therefore, you can prevent a user from being prompted more than + once for a password by letting multiple restricted areas share + the same realm. Of course, for security reasons, the client + will always need to ask again for the password whenever the + hostname of the server changes.

    + +

    The AuthUserFile + directive sets the path to the password file that we just + created with htpasswd. If you have a large number + of users, it can be quite slow to search through a plain text + file to authenticate the user on each request. Apache also has + the ability to store user information in fast database files. + The mod_authn_dbm module provides the AuthDBMUserFile directive. These + files can be created and manipulated with the dbmmanage program. Many + other types of authentication options are available from third + party modules in the Apache Modules + Database.

    + +

    Finally, the Require + directive provides the authorization part of the process by + setting the user that is allowed to access this region of the + server. In the next section, we discuss various ways to use the + Require directive.

    +
    top
    +
    +

    Letting more than one +person in

    +

    The directives above only let one person (specifically + someone with a username of rbowen) into the + directory. In most cases, you'll want to let more than one + person in. This is where the AuthGroupFile comes in.

    + +

    If you want to let more than one person in, you'll need to + create a group file that associates group names with a list of + users in that group. The format of this file is pretty simple, + and you can create it with your favorite editor. The contents + of the file will look like this:

    + +

    + GroupName: rbowen dpitts sungo rshersey +

    + +

    That's just a list of the members of the group in a long + line separated by spaces.

    + +

    To add a user to your already existing password file, + type:

    + +

    + htpasswd /usr/local/apache/passwd/passwords dpitts +

    + +

    You'll get the same response as before, but it will be + appended to the existing file, rather than creating a new file. + (It's the -c that makes it create a new password + file).

    + +

    Now, you need to modify your .htaccess file to + look like the following:

    + +

    + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +

    + +

    Now, anyone that is listed in the group GroupName, + and has an entry in the password file, will be let in, if + they type the correct password.

    + +

    There's another way to let multiple users in that is less + specific. Rather than creating a group file, you can just use + the following directive:

    + +

    + Require valid-user +

    + +

    Using that rather than the Require user rbowen + line will allow anyone in that is listed in the password file, + and who correctly enters their password. You can even emulate + the group behavior here, by just keeping a separate password + file for each group. The advantage of this approach is that + Apache only has to check one file, rather than two. The + disadvantage is that you have to maintain a bunch of password + files, and remember to reference the right one in the + AuthUserFile directive.

    +
    top
    +
    +

    Possible problems

    +

    Because of the way that Basic authentication is specified, + your username and password must be verified every time you + request a document from the server. This is even if you're + reloading the same page, and for every image on the page (if + they come from a protected directory). As you can imagine, this + slows things down a little. The amount that it slows things + down is proportional to the size of the password file, because + it has to open up that file, and go down the list of users + until it gets to your name. And it has to do this every time a + page is loaded.

    + +

    A consequence of this is that there's a practical limit to + how many users you can put in one password file. This limit + will vary depending on the performance of your particular + server machine, but you can expect to see slowdowns once you + get above a few hundred entries, and may wish to consider a + different authentication method at that time.

    +
    top
    +
    +

    What other neat stuff can I +do?

    +

    Authentication by username and password is only part of the + story. Frequently you want to let people in based on something + other than who they are. Something such as where they are + coming from.

    + +

    The Allow and + Deny directives let + you allow and deny access based on the host name, or host + address, of the machine requesting a document. The + Order directive goes + hand-in-hand with these two, and tells Apache in which order to + apply the filters.

    + +

    The usage of these directives is:

    + +

    + Allow from address +

    + +

    where address is an IP address (or a partial IP + address) or a fully qualified domain name (or a partial domain + name); you may provide multiple addresses or domain names, if + desired.

    + +

    For example, if you have someone spamming your message + board, and you want to keep them out, you could do the + following:

    + +

    + Deny from 205.252.46.165 +

    + +

    Visitors coming from that address will not be able to see + the content covered by this directive. If, instead, you have a + machine name, rather than an IP address, you can use that.

    + +

    + Deny from host.example.com +

    + +

    And, if you'd like to block access from an entire domain, + you can specify just part of an address or domain name:

    + +

    + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +

    + +

    Using Order will let you + be sure that you are actually restricting things to the group that you want + to let in, by combining a Deny and an Allow directive:

    + +

    + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +

    + +

    Listing just the Allow + directive would not do what you want, because it will let folks from that + host in, in addition to letting everyone in. What you want is to let + only those folks in.

    +
    top
    +
    +

    More information

    +

    You should also read the documentation for + mod_auth_basic and mod_authz_host which + contain some more information about how this all works.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/auth.html.ja.euc-jp b/trunk/docs/manual/howto/auth.html.ja.euc-jp new file mode 100644 index 0000000000..ada53e4a29 --- /dev/null +++ b/trunk/docs/manual/howto/auth.html.ja.euc-jp @@ -0,0 +1,384 @@ + + + +ǧ¾Ú¡¢¾µÇ§¡¢¥¢¥¯¥»¥¹À©¸æ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ǧ¾Ú¡¢¾µÇ§¡¢¥¢¥¯¥»¥¹À©¸æ

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¡Öǧ¾Ú¡×¤È¤Ï¡¢Ã¯¤«¤¬¼«Ê¬¤Ïï¤Ç¤¢¤ë¤«¤ò¼çÄ¥¤·¤¿¾ì¹ç¤Ë¡¢ + ¤½¤ì¤ò³Îǧ¤¹¤ë¤¿¤á¤ÎÁ´²áÄø¤ò»Ø¤·¤Þ¤¹¡£¡Ö¾µÇ§¡×¤È¤Ï¡¢ + 狼¤¬¹Ô¤­¤¿¤¤¾ì½ê¤Ë¹Ô¤±¤ë¤è¤¦¤Ë¡¢¤¢¤ë¤¤¤ÏÍߤ·¤¤¾ðÊó¤ò + ÆÀ¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤ÎÁ´²áÄø¤ò»Ø¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    top
    +
    +

    ¤Ï¤¸¤á¤Ë

    +

    ¤â¤·µ¡Ì©¤Î¾ðÊó¤ä¡¢¤´¤¯¤´¤¯¾¯¿ô¥°¥ë¡¼¥×¤Î¿Í¸þ¤±¤Î¾ðÊó¤ò + ¥¦¥§¥Ö¥µ¥¤¥È¤ËÃÖ¤¯¤Î¤Ç¤¢¤ì¤Ð¡¢¤³¤Îʸ½ñ¤Ë½ñ¤«¤ì¤Æ¤¤¤ë + ¥Æ¥¯¥Ë¥Ã¥¯¤ò»È¤¦¤³¤È¤Ç¡¢¤½¤Î¥Ú¡¼¥¸¤ò¸«¤Æ¤¤¤ë¿Í¤¿¤Á¤¬ + ˾¤ß¤Î¿Í¤¿¤Á¤Ç¤¢¤ë¤³¤È¤ò³Î¼Â¤Ë¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï¡¢Â¿¤¯¤Î¿Í¤¬ºÎÍѤ¹¤ë¤Ç¤¢¤í¤¦¡¢ + ¥¦¥§¥Ö¥µ¥¤¥È¤Î°ìÉôʬ¤òÊݸ¤ë¡Ö°ìÈÌŪ¤Ê¡× + ÊýË¡¤Ë¤Ä¤¤¤Æ¥«¥Ð¡¼¤·¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ½àÈ÷

    +

    ¤³¤Îʸ½ñ¤Ç¼è¤ê°·¤ï¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥á¥¤¥ó¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë (ÉáÄÌ¤Ï + <Directory> + ¥»¥¯¥·¥ç¥óÃæ) ¤«¡¢¤¢¤ë¤¤¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤ÎÀßÄê¥Õ¥¡¥¤¥ë + (.htaccess ¥Õ¥¡¥¤¥ë) ¤«¤ÇÍѤ¤¤Þ¤¹¡£

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤òÍѤ¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤Ëǧ¾ÚÍѤΥǥ£¥ì¥¯¥Æ¥£¥Ö¤òÃÖ¤±¤ë¤è¤¦¤Ë + ¥µ¡¼¥Ð¤ÎÀßÄê¤ò¤·¤Ê¤¤¤È¤¤¤±¤Ê¤¤¤Ç¤·¤ç¤¦¡£¤³¤ì¤Ï + AllowOverride + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£ + AllowOverride + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥êËè¤ÎÀßÄê¥Õ¥¡¥¤¥ëÃæ¤ËÃÖ¤¯¤³¤È¤Î¤Ç¤­¤ë + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¡¢¤â¤·¤¢¤ì¤Ð¡¢»ØÄꤷ¤Þ¤¹¡£

    + +

    ǧ¾Ú¤Ë¤Ä¤¤¤ÆÏäò¿Ê¤á¤Æ¤¤¤ë¤Î¤Ç¡¢¼¡¤Î¤è¤¦¤Ê + AllowOverride + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬É¬Íפˤʤë¤Ç¤·¤ç¤¦¡£

    + +

    + AllowOverride AuthConfig +

    + +

    ¤½¤¦¤Ç¤Ê¤¯¡¢¥á¥¤¥ó¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë + ľÀÜÃÖ¤¯¤Î¤Ç¤¢¤ì¤Ð¡¢ÅöÁ³¤Ê¤¬¤é¤½¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î½ñ¤­¹þ¤ß + ¸¢¸Â¤ò»ý¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤Ç¤·¤ç¤¦¡£

    + +

    ¤Þ¤¿¡¢¤É¤Î¥Õ¥¡¥¤¥ë¤¬¤É¤³¤ËÊݸ¤µ¤ì¤Æ¤¤¤ë¤«ÃΤ뤿¤á¤Ë¡¢ + ¥µ¡¼¥Ð¤Î¥Ç¥£¥ì¥¯¥È¥ê¹½Â¤¤Ë¤Ä¤¤¤Æ¾¯¤·ÃΤäƤª¤¯ + ɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤ì¤Ï¤½¤ó¤Ê¤ËÆñ¤·¤¯¤Ê¤¤¤Î¤Ç¡¢¤³¤Îʸ½ñÃæ¤Ç + ¥Ç¥£¥ì¥¯¥È¥ê¹½Â¤¤Ë¤Ä¤¤¤ÆÃΤäƤª¤¯É¬Íפ¬¤¢¤ë¾ìÌ̤Ǥϡ¢ + ÌÀ¤é¤«¤Ë¤Ê¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    +
    top
    +
    +

    Æ°ºî¤µ¤»¤ë

    +

    ¤Ç¤Ï¡¢¥µ¡¼¥Ð¾å¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ò¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ë + ´ðËܼê½ç¤ò¼¨¤·¤Þ¤¹¡£

    + +

    ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤òºî¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¡¢¥¦¥§¥Ö¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤ë¾ì½ê¤Ë + ÃÖ¤¯¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£Â¾¤Î¿Í¤¬¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ò + ¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ç¤¹¡£Î㤨¤Ð¡¢ + /usr/local/apache/htdocs ¤Ç¥É¥­¥å¥á¥ó¥È¤ò + Ä󶡤·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤Ï + /usr/local/apache/passwd + ¤Ê¤É¤ËÃÖ¤¤¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    ¥Õ¥¡¥¤¥ë¤òºî¤ë¤¿¤á¤Ë¤Ï¡¢Apache ÉÕ°¤Î htpasswd + ¤ò»È¤¤¤Þ¤¹¡£¤³¤Î¥³¥Þ¥ó¥É¤Ï Apache ¤ò¤É¤³¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤·¤è¤¦¤È¤â¡¢ + ¥¤¥ó¥¹¥È¡¼¥ë¥Ç¥£¥ì¥¯¥È¥ê¤Î bin + ¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤ËÃÖ¤«¤ì¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤òºî¤ë¤Ë¤Ï¡¢¼¡¤Î¤è¤¦¤Ë + ¥¿¥¤¥×¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + htpasswd -c /usr/local/apache/passwd/passwords rbowen +

    + +

    htpasswd ¤Ï¡¢¥Ñ¥¹¥ï¡¼¥É¤òÍ׵ᤷ¡¢¤½¤Î¸å + ³Îǧ¤Î¤¿¤á¤Ë¤â¤¦°ìÅÙÆþÎϤ¹¤ë¤è¤¦¤ËÍ׵ᤷ¤Æ¤­¤Þ¤¹¡£

    + +

    + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +

    + +

    ¤â¤· htpasswd ¤¬¥Ñ¥¹¤ÎÃæ¤ËÆþ¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢ + ¤â¤Á¤í¤ó¡¢¼Â¹Ô¤¹¤ë¤¿¤á¤Ë¥×¥í¥°¥é¥à¤Þ¤Ç¤Î¥Õ¥ë¥Ñ¥¹¤ò + ¥¿¥¤¥×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£»ä¤Î¥µ¡¼¥Ð¤Ç¤¢¤ì¤Ð¡¢ + /usr/local/apache/bin/htpasswd + ¤Ë¥×¥í¥°¥é¥à¤¬ÃÖ¤«¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¼¡¤Ë¡¢¥µ¡¼¥Ð¤¬¥Ñ¥¹¥ï¡¼¥É¤òÍ׵᤹¤ë¤è¤¦¤ËÀßÄꤷ¤Æ¡¢ + ¤É¤Î¥æ¡¼¥¶¤¬¥¢¥¯¥»¥¹¤òµö¤µ¤ì¤Æ¤¤¤ë¤«¤ò¥µ¡¼¥Ð¤ËÃΤ餻¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£ httpd.conf ¤òÊÔ½¸¤¹¤ë¤« + .htaccess ¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ¹¤ë¤«¤Ç + ÀßÄꤷ¤Þ¤¹¡£Î㤨¤Ð¡¢¥Ç¥£¥ì¥¯¥È¥ê + /usr/local/apache/htdocs/secret + ¤òÊݸ¤¿¤¤¾ì¹ç¤Ï¡¢ + /usr/local/apache/htdocs/secret/.htaccess + ¤« httpd.conf Ãæ¤Î <Directory + /usr/local/apache/apache/htdocs/secret> ¥»¥¯¥·¥ç¥ó¤Ë + ÇÛÃÖ¤·¤Æ¡¢¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +

    + +

    ¸Ä¡¹¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ä¤¤¤Æ¸«¤Æ¤ß¤Þ¤·¤ç¤¦¡£ + AuthType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤É¤¦¤¤¤¦Ç§¾ÚÊýË¡¤Ç¥æ¡¼¥¶¤Îǧ¾Ú¤ò¹Ô¤¦¤«¤ò + ÁªÂò¤·¤Þ¤¹¡£ºÇ¤â°ìÈÌŪ¤ÊÊýË¡¤Ï Basic + ¤Ç¡¢¤³¤ì¤Ï mod_auth_basic + ¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤·¤«¤·¤Ê¤¬¤é¡¢ + ¤³¤ì¤Ïµ¤¤òÉÕ¤±¤ë¤Ù¤­½ÅÍפʥݥ¤¥ó¥È¤Ê¤Î¤Ç¤¹¤¬¡¢ + Basic ǧ¾Ú¤Ï¥¯¥é¥¤¥¢¥ó¥È¤«¤é¥Ö¥é¥¦¥¶¤Ø¡¢ + ¥Ñ¥¹¥ï¡¼¥É¤ò°Å¹æ²½¤»¤º¤ËÁ÷¤ê¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ + ¤³¤ÎÊýË¡¤ÏÆä˵¡Ì©À­¤Î¹â¤¤¥Ç¡¼¥¿¤ËÂФ·¤Æ¤ÏÍѤ¤¤ë¤Ù¤­¤Ç¤Ï + ¤¢¤ê¤Þ¤»¤ó¡£ Apache ¤Ç¤Ï¤â¤¦°ì¤ÄÊ̤Îǧ¾ÚÊýË¡: + AuthType Digest ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ÎÊýË¡¤Ï mod_auth_digest + ¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤Æ¡¢¤â¤Ã¤È°ÂÁ´¤Ç¤¹¡£ + ¤´¤¯¤´¤¯ºÇ¶á¤Î¥¯¥é¥¤¥¢¥ó¥È¤·¤« Digest + ǧ¾Ú¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¤è¤¦¤Ç¤¹¡£

    + +

    AuthName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢Ç§¾Ú¤Ë»È¤¦ Realm (ÌõÃí: Îΰè) + ¤òÀßÄꤷ¤Þ¤¹¡£Realm ¤ÏÂ礭¤¯Ê¬¤±¤ÆÆó¤Ä¤Îµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£ + °ì¤ÄÌܤϡ¢¥¯¥é¥¤¥¢¥ó¥È¤¬¥Ñ¥¹¥ï¡¼¥É¥À¥¤¥¢¥í¥°¥Ü¥Ã¥¯¥¹¤Î + °ìÉô¤È¤·¤Æ¥æ¡¼¥¶¤Ë¤³¤Î¾ðÊó¤ò¤è¤¯Ä󼨤¹¤ë¡¢¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£ + Æó¤ÄÌܤˤϡ¢¥¯¥é¥¤¥¢¥ó¥È¤¬Í¿¤¨¤é¤ì¤¿Ç§¾ÚÎΰè¤ËÂФ·¤Æ¤É¤Î¥Ñ¥¹¥ï¡¼¥É¤ò + Á÷¿®¤¹¤ì¤ÐÎɤ¤¤Î¤«¤ò·èÄꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡¢¤È¤¤¤¦µ¡Ç½¤Ç¤¹¡£

    + +

    Î㤨¤Ð¡¢"Restricted Files" ÎΰèÃæ¤Ç + °ìÅÙǧ¾Ú¤µ¤ì¤ì¤Ð¡¢Æ±°ì¥µ¡¼¥Ð¾å¤Ç "Restricted Files" + Realm ¤È¤·¤Æ¥Þ¡¼¥¯¤µ¤ì¤¿¤É¤ó¤ÊÎΰè¤Ç¤â¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï + ¼«Æ°Åª¤ËƱ¤¸¥Ñ¥¹¥ï¡¼¥É¤ò»È¤ª¤¦¤È»î¤ß¤Þ¤¹¡£ + ¤³¤Î¤ª¤«¤²¤Ç¡¢Ê£¿ô¤ÎÀ©¸ÂÎΰè¤ËƱ¤¸ realm ¤ò¶¦Í­¤µ¤»¤Æ¡¢ + ¥æ¡¼¥¶¤¬¥Ñ¥¹¥ï¡¼¥É¤ò²¿ÅÙ¤âÍ׵ᤵ¤ì¤ë»öÂÖ¤ò + Ëɤ°¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤â¤Á¤í¤ó¡¢¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤«¤é¡¢ + ¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¤¬ÊѤï¤ì¤Ð¤¤¤Ä¤Ç¤âɬ¤º¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤ÏºÆ¤Ó¥Ñ¥¹¥ï¡¼¥É¤ò¿Ò¤Í¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    AuthUserFile + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï htpasswd ¤Çºî¤Ã¤¿ + ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤òÀßÄꤷ¤Þ¤¹¡£ + ¥æ¡¼¥¶¿ô¤¬Â¿¤¤¾ì¹ç¤Ï¡¢¥ê¥¯¥¨¥¹¥ÈËè¤Î¥æ¡¼¥¶¤Îǧ¾Ú¤Î¤¿¤á¤Î + ¥×¥ì¡¼¥ó¥Æ¥­¥¹¥È¤Îõº÷¤¬Èó¾ï¤ËÃÙ¤¯¤Ê¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + Apache ¤Ç¤Ï¥æ¡¼¥¶¾ðÊó¤ò¹â®¤Ê¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Ë + Êݴɤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + mod_authn_dbm ¥â¥¸¥å¡¼¥ë¤¬ + AuthDBMUserFile + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤Ï dbmmanage + ¥×¥í¥°¥é¥à¤ÇºîÀ®¤·¤¿¤êÁàºî¤·¤¿¤ê¤Ç¤­¤Þ¤¹¡£ + Apache + ¥â¥¸¥å¡¼¥ë¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Ë¤¢¤ë¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¡¼À½¤Î + ¥â¥¸¥å¡¼¥ë¤Ç¡¢¤½¤Î¾¿¤¯¤Î¥¿¥¤¥×¤Îǧ¾Ú¥ª¥×¥·¥ç¥ó¤¬ + ÍøÍѲÄǽ¤Ç¤¹¡£

    + +

    ºÇ¸å¤Ë¡¢Require + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¡¢¥µ¡¼¥Ð¤Î¤³¤ÎÎΰè¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¥æ¡¼¥¶¤ò + »ØÄꤹ¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¥×¥í¥»¥¹¤Î¾µÇ§Éôʬ¤òÄ󶡤·¤Þ¤¹¡£ + ¼¡¤Î¥»¥¯¥·¥ç¥ó¤Ç¤Ï¡¢Require + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÍÍ¡¹¤ÊÍÑË¡¤Ë¤Ä¤¤¤Æ½Ò¤Ù¤Þ¤¹¡£

    +
    top
    +
    +

    +Ê£¿ô¤Î¿Í¤¬Æþ¤ì¤ë¤è¤¦¤Ë¤¹¤ë

    +

    ¾åµ­¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¤¿¤À°ì¿Í (¶ñÂÎŪ¤Ë¤Ï¥æ¡¼¥¶Ì¾ + rbowen ¤Î狼) ¤¬¥Ç¥£¥ì¥¯¥È¥ê¤Ë + Æþ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£Â¿¤¯¤Î¾ì¹ç¤Ï¡¢Ê£¿ô¤Î¿Í¤¬ + Æþ¤ì¤ë¤è¤¦¤Ë¤·¤¿¤¤¤Ç¤·¤ç¤¦¡£¤³¤³¤Ç + AuthGroupFile + ¤ÎÅоì¤Ç¤¹¡£

    + +

    ¤â¤·Ê£¿ô¤Î¿Í¤¬Æþ¤ì¤ë¤è¤¦¤Ë¤·¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¥°¥ë¡¼¥×¤Ë°¤¹¤ë¥æ¡¼¥¶¤Î°ìÍ÷¤ÎÆþ¤Ã¤Æ¤¤¤ë¡¢¥°¥ë¡¼¥×̾¤Î¤Ä¤¤¤¿ + ¥°¥ë¡¼¥×¥Õ¥¡¥¤¥ë¤òºî¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥Õ¥¡¥¤¥ë¤Î + ½ñ¼°¤Ï¤­¤ï¤á¤Æñ½ã¤Ç¡¢¤ª¹¥¤ß¤Î¥¨¥Ç¥£¥¿¤ÇÀ¸À®¤Ç¤­¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤¹¡£

    + +

    + GroupName: rbowen dpitts sungo rshersey +

    + +

    °ì¹Ô¤Ë¥¹¥Ú¡¼¥¹¶èÀÚ¤ê¤Ç¡¢¥°¥ë¡¼¥×¤Ë½ê°¤¹¤ë¥á¥ó¥Ð¡¼¤Î + °ìÍ÷¤ò¤Ê¤é¤Ù¤ë¤À¤±¤Ç¤¹¡£

    + +

    ´û¤Ë¸ºß¤¹¤ë¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤Ë¥æ¡¼¥¶¤ò²Ã¤¨¤ë¾ì¹ç¤Ï¡¢ + ¼¡¤Î¤è¤¦¤Ë¥¿¥¤¥×¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + htpasswd /usr/local/apache/passwd/passwords dpitts +

    + +

    °ÊÁ°¤ÈƱ¤¸±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¤¬¡¢¿·¤·¤¤¥Õ¥¡¥¤¥ë¤ò + ºî¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢´û¤Ë¤¢¤ë¥Õ¥¡¥¤¥ë¤ËÄɲ䵤ì¤Æ¤¤¤Þ¤¹¡£ + (¿·¤·¤¤¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤òºî¤ë¤Ë¤Ï -c + ¤ò»È¤¤¤Þ¤¹¡£)

    + +

    ¤³¤³¤Ç¼¡¤Î¤è¤¦¤Ë¤·¤Æ .htaccess ¥Õ¥¡¥¤¥ë¤ò + ½¤Àµ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +

    + +

    ¤³¤ì¤Ç¡¢¥°¥ë¡¼¥× GroupName ¤Ë¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤Æ¡¢ + password ¥Õ¥¡¥¤¥ë¤Ë¥¨¥ó¥È¥ê¤¬¤¢¤ë¿Í¤Ï¡¢ + Àµ¤·¤¤¥Ñ¥¹¥ï¡¼¥É¤ò¥¿¥¤¥×¤¹¤ì¤ÐÆþ¤ë¤³¤È¤¬¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ¤â¤Ã¤ÈÆÃÄꤻ¤º¤ËÊ£¿ô¤Î¥æ¡¼¥¶¤¬Æþ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¡¢ + ¤â¤¦°ì¤Ä¤ÎÊýË¡¤¬¤¢¤ê¤Þ¤¹¡£¥°¥ë¡¼¥×¥Õ¥¡¥¤¥ë¤òºî¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¨¤Ð¤Ç¤­¤Þ¤¹¡£

    + +

    + Require valid-user +

    + +

    require user rbowen ¹Ô¤Ç¤Ê¤¯¡¢¾åµ­¤ò»È¤¦¤È¡¢ + ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤Ë¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤ë¿Í¤Ç¤¢¤ì¤Ðï¤Ç¤â + µö²Ä¤µ¤ì¤Þ¤¹¡£ + ñ¤Ë¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ò¥°¥ë¡¼¥×Ëè¤Ëʬ¤±¤Æ¤ª¤¯¤³¤È¤Ç¡¢ + ¥°¥ë¡¼¥×¤Î¤è¤¦¤Ê¿¶¤ëÉñ¤¤¤ò¤µ¤»¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥¢¥×¥í¡¼¥Á¤ÎÍøÅÀ¤Ï¡¢Apache ¤ÏÆó¤Ä¤Ç¤Ï¤Ê¤¯¡¢ + ¤¿¤À°ì¤Ä¤Î¥Õ¥¡¥¤¥ë¤À¤±¤ò¸¡ºº¤¹¤ì¤Ð¤è¤¤¤È¤¤¤¦ÅÀ¤Ç¤¹¡£ + ·çÅÀ¤Ï¡¢¤¿¤¯¤µ¤ó¤Î¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ò´ÉÍý¤·¤Æ¡¢¤½¤ÎÃ椫¤é + AuthUserFile + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÀµ¤·¤¤¥Õ¥¡¥¤¥ë¤ò»²¾È¤µ¤»¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤ÅÀ¤Ç¤¹¡£

    +
    top
    +
    +

    µ¯¤³¤ê¤¨¤ëÌäÂê

    +

    Basic ǧ¾Ú¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤Ë¥É¥­¥å¥á¥ó¥È¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ëÅÙ¤Ë + ¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤ò¸¡ºº¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤ì¤ÏƱ¤¸¥Ú¡¼¥¸¡¢¥Ú¡¼¥¸¤Ë¤¢¤ëÁ´¤Æ¤Î²èÁü¤ò + ¥ê¥í¡¼¥É¤¹¤ë¾ì¹ç¤Ç¤¢¤Ã¤Æ¤â³ºÅö¤·¤Þ¤¹ + (¤â¤·²èÁü¤âÊݸ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÍè¤ë¤Î¤Ç¤¢¤ì¤Ð) ¡£ + ͽÁÛ¤µ¤ì¤ëÄ̤ꡢ¤³¤ì¤ÏÆ°ºî¤ò¿¾¯ÃÙ¤¯¤·¤Þ¤¹¡£ + ÃÙ¤¯¤Ê¤ëÄøÅ٤ϥѥ¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤ÈÈæÎ㤷¤Þ¤¹¤¬¡¢ + ¤³¤ì¤Ï¡¢¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¢¤Ê¤¿¤Î̾Á°¤òȯ¸«¤¹¤ë¤Þ¤Ç + ¥æ¡¼¥¶Ì¾¤Î¥ê¥¹¥È¤òÆɤޤʤ±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤é¤Ç¤¹¡£ + ¤½¤·¤Æ¡¢¥Ú¡¼¥¸¤¬¥í¡¼¥É¤µ¤ì¤ëÅ٤ˤ³¤ì¤ò¹Ô¤ï¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ·ëÏÀ¤È¤·¤Æ¤Ï¡¢°ì¤Ä¤Î¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ËÃÖ¤¯¤³¤È¤Î¤Ç¤­¤ë + ¥æ¡¼¥¶¿ô¤Ë¤Ï¼Â¼ÁŪ¤Ê¸Â³¦¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¸Â³¦¤Ï¥µ¡¼¥Ð¥Þ¥·¥ó¤ÎÀ­Ç½¤Ë°Í¸¤·¤ÆÊѤï¤ê¤Þ¤¹¤¬¡¢ + ¿ôÉ´¤Î¥¨¥ó¥È¥ê¤ò±Û¤¨¤¿¤¢¤¿¤ê¤«¤é®ÅÙÄã²¼¤¬¸«¤é¤ì¤ë¤Èͽ´ü¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤½¤Î»þ¤Ï¾¤Îǧ¾ÚÊýË¡¤ò¹Íθ¤ËÆþ¤ì¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    ¤â¤Ã¤È¹ª¤ß¤ËÀ©¸æ¤Ç¤­¤Ê¤¤ +?

    +

    ¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤Ë¤è¤ëǧ¾Ú¤Ïǧ¾Ú¤Î°ì¤Ä¤ÎÊýË¡¤Ë²á¤®¤Þ¤»¤ó¡£ + ¤·¤Ð¤·¤Ðï¤Ç¤¢¤ë¤«¤È¤¤¤¦¤³¤È¤È¤Ï°ã¤¦²¿¤«¤Ë´ð¤Å¤¤¤Æ¡¢ + Æþ¤ì¤ë¤è¤¦¤Ë¤·¤¿¤¯¤Ê¤ë¤³¤È¤â¤¢¤ë¤Ç¤·¤ç¤¦¡£ + Î㤨¤Ð¤½¤Î¿Í¤¬¤É¤³¤«¤éÍè¤Æ¤¤¤ë¤«¤È¤¤¤Ã¤¿¤³¤È¤Ç¤¹¡£

    + +

    Allow ¤È + Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¡¢¥É¥­¥å¥á¥ó¥È¤òÍ׵ᤷ¤Æ¤­¤¿¥Þ¥·¥ó¤Î + ¥Û¥¹¥È̾¤ä¥Û¥¹¥È¥¢¥É¥ì¥¹¤Ë´ð¤Å¤¤¤Æµö²ÄÉÔµö²Ä¤òÀ©¸æ¤Ç¤­¤Þ¤¹¡£ + Order + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤³¤ÎÆó¤Ä¤ÈÏ¢·È¤·¤ÆÆ°ºî¤·¡¢Apache + ¤Ë¤É¤Î½çÈ֤ǥե£¥ë¥¿¤òŬÍѤ¹¤ë¤«¤òÃΤ餻¤Þ¤¹¡£

    + +

    ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»È¤¤Êý¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + Allow from address +

    + +

    ¤³¤³¤Ç¡¢address ¤Ï IP ¥¢¥É¥ì¥¹ + (¤Þ¤¿¤Ï IP ¥¢¥É¥ì¥¹¤Î°ìÉô)¡¢¤¢¤ë¤¤¤Ï´°Á´½¤¾þ¥É¥á¥¤¥ó̾ + (¤Þ¤¿¤Ï¥É¥á¥¤¥ó̾¤Î°ìÉô) ¤Ç¤¹¡£ + ɬÍפǤ¢¤ì¤ÐÊ£¿ô¤Î¥¢¥É¥ì¥¹¤ä¥É¥á¥¤¥ó̾¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢¤â¤·Ã¯¤«¤¬·Ç¼¨ÈĤò¹¶·â¤·¤Æ¤¤¤Æ¡¢ + ¤½¤Î¿Í¤òÊĤá½Ð¤·¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¼¡¤Î¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + Deny from 205.252.46.165 +

    + +

    ¤³¤Î¥¢¥É¥ì¥¹¤«¤éÍè¤ë¿Í¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÈÏ°ÏÆâ¤Î + ¥³¥ó¥Æ¥ó¥Ä¤ò¸«¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤Þ¤»¤ó¡£¤â¤· IP + ¥¢¥É¥ì¥¹¤ÎÂå¤ï¤ê¤Ë¥Þ¥·¥ó̾¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤ò»È¤¨¤Þ¤¹¡£

    + +

    + Deny from host.example.com +

    + +

    ¥É¥á¥¤¥óÁ´ÂΤ«¤é¤Î¥¢¥¯¥»¥¹¤òËɤ®¤¿¤±¤ì¤Ð¡¢ + ñ¤Ë¥¢¥É¥ì¥¹¤ä¥É¥á¥¤¥ó̾¤Î°ìÉô¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +

    + +

    Order ¤ò»È¤¦¤³¤È¤Ç¡¢ + Deny ¤È + Allow ¤ÎÁȤ߹ç¤ï¤»¤Ç + Æþ¤Ã¤Æ¤âÎɤ¤¥°¥ë¡¼¥×¤¬ËÜÅö¤Ë³Î¼Â¤Ë¸ÂÄê¤Ç¤­¤Æ¤¤¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +

    + +

    Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òñ½ã¤ËÎóµó¤¹¤ë¤Î¤Ç¤Ï˾¤ß¤ÎÆ°ºî¤ò¤·¤Ê¤¤¤Ç¤·¤ç¤¦¡£ + ¤Ê¤¼¤Ê¤é¡¢Á´¤Æ¤Î¿Í¤¬Æþ¤ì¤ë¤È¤¤¤¦¤³¤È¤Ë²Ã¤¨¤Æ¡¢ + »ØÄꤷ¤¿¥Û¥¹¥È¤«¤é¤Î¿Í¤¬Æþ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤«¤é¤Ç¤¹¡£ + ¤ä¤ê¤¿¤¤¤³¤È¤Ï¡¢»ØÄꤷ¤¿¿Í¤¿¤Á¤À¤±¤¬Æþ¤ì¤ë¤è¤¦¤Ë + ¤¹¤ë¤³¤È¤Ç¤¹¡£

    +
    top
    +
    +

    ÄɲþðÊó

    +

    ¤³¤ì¤éÁ´¤Æ¤¬¤É¤Î¤è¤¦¤ËÆ°ºî¤¹¤ë¤«¤Ë¤Ä¤¤¤Æ + ¤â¤Ã¤È¿¤¯¤Î¾ðÊ󤬽ñ¤«¤ì¤Æ¤¤¤ë mod_auth_basic ¤È + mod_authz_host + ¤Îʸ½ñ¤âÆɤà¤È¤è¤¤¤Ç¤·¤ç¤¦¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/auth.html.ko.euc-kr b/trunk/docs/manual/howto/auth.html.ko.euc-kr new file mode 100644 index 0000000000..db3399df9d --- /dev/null +++ b/trunk/docs/manual/howto/auth.html.ko.euc-kr @@ -0,0 +1,323 @@ + + + +ÀÎÁõ(Authentication), ±ÇÇѺο©(Authorization), +Á¢±ÙÁ¦¾î(Access Control) - Apache HTTP Server + + + + + +
    <-
    +

    ÀÎÁõ(Authentication), ±ÇÇѺο©(Authorization), +Á¢±ÙÁ¦¾î(Access Control)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÎÁõ(authentication)Àº ÀÚ½ÅÀÌ ´©±¸¶ó°í ÁÖÀåÇÏ´Â »ç¶÷À» + È®ÀÎÇÏ´Â ÀýÂ÷ÀÌ´Ù. ±ÇÇѺο©(authorization)´Â °¡°í ½ÍÀº °÷À¸·Î + °¡µµ·Ï ȤÀº ¿øÇÏ´Â Á¤º¸¸¦ ¾òµµ·Ï Çã¿ëÇÏ´Â °úÁ¤ÀÌ´Ù.

    +
    + +
    top
    +
    top
    +
    +

    ¼Ò°³

    +

    ´ç½ÅÀÇ À¥»çÀÌÆ®¿¡ ÀÖ´Â Á¤º¸°¡ ¼Ò¼öÀÇ »ç¶÷µé¸¸ÀÇ ºñ¹ÐÀ̰ųª + À̵鸸À» À§ÇÑ Á¤º¸¶ó¸é, ÀÌ ±Û¿¡¼­ ¼³¸íÇÏ´Â ±â¹ýÀ» »ç¿ëÇÏ¿© + ´ç½ÅÀÌ º¸±æ ¿øÇÏ´Â »ç¶÷¸¸ ÆäÀÌÁö¸¦ º¸µµ·Ï ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ±ÛÀº À¥»çÀÌÆ®ÀÇ ÀϺθ¦ º¸È£ÇϱâÀ§ÇØ ¸¹Àº »ç¶÷µéÀÌ + »ç¿ëÇÏ´Â "Ç¥ÁØÀûÀÎ" ¹æ¹ýÀ» ´Ù·é´Ù.

    +
    top
    +
    +

    ±âº» Áö½Ä

    +

    ÀÌ ±Û¿¡¼­ ´Ù·ç´Â Áö½Ã¾î´Â ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏ(ÀϹÝÀûÀ¸·Î + <Directory> + ¼½¼Ç)À̳ª µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ(.htaccess ÆÄÀÏ)¿¡¼­ + »ç¿ëÇÑ´Ù.

    + +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ·Á¸é ÀÌ ÆÄÀÏ¿¡ ÀÖ´Â + ÀÎÁõ Áö½Ã¾î¸¦ Çã¿ëÇϵµ·Ï ¼­¹ö¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. À̸¦ À§ÇØ + µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö¸¦ °áÁ¤ÇÏ´Â + AllowOverride Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¿©±â¼­´Â ÀÎÁõÀ» ´Ù·ç±â ¶§¹®¿¡, ´ÙÀ½°ú °°Àº + AllowOverride Áö½Ã¾î°¡ ÇÊ¿äÇÏ´Ù.

    + +

    + AllowOverride AuthConfig +

    + +

    ȤÀº Áö½Ã¾î¸¦ Á÷Á¢ ¼­¹ö ÁÖ¼³Á¤ÆÄÀÏ¿¡ Àû´Â´Ù¸é, ±× ÆÄÀÏ¿¡ + ¾²±â ±ÇÇÑÀÌ ¹°·Ð ÀÖ¾î¾ß ÇÑ´Ù.

    + +

    ±×¸®°í º¸È£ÇÒ ÆÄÀÏÀÌ ¾îµðÀÖ´ÂÁö ¾Ë±âÀ§ÇØ ¼­¹öÀÇ µð·ºÅ丮 + ±¸Á¶¿¡ ´ëÇØ Á¶±Ý ¾Ë¾Æ¾ßÇÑ´Ù. ÀÌ ÀÏÀº ¾î·ÆÁö¾Ê°í, Àû´çÇÑ + ¶§¿¡ ÀÚ¼¼È÷ ¼³¸íÇÒ °ÍÀÌ´Ù.

    +
    top
    +
    +

    ±âº»ÀûÀÎ ¼³Á¤Çϱâ

    +

    ÀÌÁ¦ ¼­¹öÀÇ µð·ºÅ丮¸¦ ¾ÏÈ£·Î º¸È£ÇÏ´Â ±âº»ÀûÀÎ ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    + +

    ¸ÕÀú ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé¾î¾ß ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¥¿¡¼­ Á¢±ÙÇÒ + ¼ö ¾ø´Â °÷¿¡ ÀÖ¾î¾ß ÇÑ´Ù. ´Ù¸¥»ç¶÷ÀÌ ¾ÏÈ£ÆÄÀÏÀ» ´Ù¿î·ÎµåÇÏÁö + ¸øÇÏ°ÔÇϱâ À§Çؼ­´Ù. ¿¹¸¦ µé¾î, ¹®¼­µéÀÌ + /usr/local/apache/htdocs¿¡ ÀÖ´Ù¸é ¾ÏÈ£ÆÄÀÏ(µé)Àº + /usr/local/apache/passwd¿¡ µÐ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔµÈ htpasswd µµ±¸¸¦ »ç¿ëÇÏ¿© + ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç´Ù. ÀÌ ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ °÷ÀÇ + bin µð·ºÅ丮¿¡ ÀÖ´Ù. ÆÄÀÏÀ» ¸¸µé·Á¸é ´ÙÀ½°ú + °°ÀÌ ÀÔ·ÂÇÑ´Ù.

    + +

    + htpasswd -c /usr/local/apache/passwd/passwords rbowen +

    + +

    htpasswd´Â ¾ÏÈ£¸¦ ¹°¾îº¸°í, È®ÀÎÀ» À§ÇØ + ¾ÏÈ£¸¦ ´Ù½Ã ÀÔ·ÂÇ϶ó°í ¿äûÇÑ´Ù.

    + +

    + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +

    + +

    ¹°·Ð htpasswdÀÌ ½ÇÇàÆÄÀÏ °æ·Î¿¡ ¾ø´Ù¸é + ½ÇÇàÆÄÀÏÀÇ Àüü °æ·Î¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. ³»°¡ »ç¿ëÇÏ´Â ¼­¹ö¿¡¼­´Â + /usr/local/apache/bin/htpasswd¿¡ ½ÇÇàÆÄÀÏÀÌ + ÀÖ´Ù.

    + +

    ´ÙÀ½À¸·Î ¼­¹ö°¡ ¾ÏÈ£¸¦ ¿äûÇϵµ·Ï ¼³Á¤ÇÏ°í, ¼­¹ö¿¡°Ô + ¾î¶² »ç¿ëÀÚÀÇ Á¢±ÙÀ» Çã¿ëÇÒÁö ¾Ë·ÁÁà¾ß ÇÑ´Ù. + httpd.conf¸¦ ÆíÁýÇϰųª .htaccess + ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¾î, + /usr/local/apache/htdocs/secret µð·ºÅ丮¸¦ + º¸È£ÇÏ·Á¸é, ¾Æ·¡ Áö½Ã¾î¸¦ + /usr/local/apache/htdocs/secret/.htaccess ÆÄÀÏÀ̳ª + httpd.confÀÇ <Directory + /usr/local/apache/apache/htdocs/secret> ¼½¼Ç¿¡ Àû¾î¾ß + ÇÑ´Ù.

    + +

    + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +

    + +

    Áö½Ã¾î¸¦ Çϳª¾¿ »ìÆ캸ÀÚ. AuthType Áö½Ã¾î´Â »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ + ¹æ¹ýÀ» ¼±ÅÃÇÑ´Ù. °¡Àå ÀϹÝÀûÀÎ ¹æ¹ýÀº BasicÀ¸·Î, + mod_auth_basicÀÌ ±¸ÇöÇÑ´Ù. ±×·¯³ª Basic + ÀÎÁõÀº ºê¶ó¿ìÀú°¡ ¼­¹ö·Î ¾ÏÈ£¸¦ ¾ÏȣȭÇÏÁö ¾Ê°í º¸³½´Ù. + ±×·¯¹Ç·Î ±â¹Ð ÀڷḦ º¸È£ÇϱâÀ§ÇØ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. + ¾ÆÆÄÄ¡´Â AuthType Digest¶ó´Â ÀÎÁõ ¹æ¹ýµµ Áö¿øÇÑ´Ù. + ÀÌ ¹æ¹ýÀº mod_auth_digest°¡ ±¸ÇöÇϸç, ¸Å¿ì + ¾ÈÀüÇÏ´Ù. °¡Àå Ãֱ٠Ŭ¶óÀ̾ðÆ®µé¸¸ÀÌ Digest ÀÎÁõÀ» Áö¿øÇÑ´Ù°í + ÇÑ´Ù.

    + +

    AuthName Áö½Ã¾î´Â + ÀÎÁõ¿¡ »ç¿ëÇÒ ¿µ¿ª(realm)À» ÁöÁ¤ÇÑ´Ù. ¿µ¿ªÀº + µÎ°¡Áö ¿ªÇÒÀ» ÇÑ´Ù. ù¹ø°´Â Ŭ¶óÀ̾ðÆ®°¡ º¸Åë ÀÌ Á¤º¸¸¦ + ¾ÏÈ£ ´ëȭâ¿¡ º¸¿©ÁØ´Ù. µÎ¹ø°´Â ¿µ¿ª Á¤º¸¸¦ »ç¿ëÇÏ¿© + Ŭ¶óÀ̾ðÆ®°¡ ƯÁ¤ ÀÎÁõ±¸¿ª¿¡ ¾î¶² ¾ÏÈ£¸¦ º¸³¾Áö °áÁ¤ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, ÀÏ´Ü Å¬¶óÀ̾ðÆ®°¡ "Restricted Files" + ¿µ¿ª¿¡ ÀÎÁõÀÌ ¼º°øÇÏ¿´´Ù¸é, Ŭ¶óÀ̾ðÆ®´Â ÀÚµ¿À¸·Î °°Àº ¼­¹ö¿¡¼­ + "Restricted Files" ¿µ¿ªÀ¸·Î Ç¥½ÃµÈ ±¸¿ª¿¡ ´ëÇØ + µ¿ÀÏÇÑ ¾ÏÈ£¸¦ ½ÃµµÇÑ´Ù. ±×·¡¼­ ¿©·¯ Á¦ÇÑ ±¸¿ªÀÌ °°Àº ¿µ¿ªÀ» + °øÀ¯ÇÏ¸é »ç¿ëÀÚ°¡ ¿©·¯¹ø ¾ÏÈ£¸¦ ÀÔ·ÂÇÏÁö ¾Ê¾Æµµ µÈ´Ù. ¹°·Ð + º¸¾È»ó ÀÌÀ¯·Î Ŭ¶óÀ̾ðÆ®´Â ¼­¹öÀÇ È£½ºÆ®¸íÀÌ ´Ù¸£¸é Ç×»ó + »õ·Î ¾ÏÈ£¸¦ ¹°¾îº»´Ù.

    + +

    AuthUserFile + Áö½Ã¾î´Â ¿ì¸®°¡ ¹æ±Ý htpasswd·Î ¸¸µç ¾ÏÈ£ÆÄÀÏÀÇ + °æ·Î¸¦ ¼³Á¤ÇÑ´Ù. »ç¿ëÀÚ°¡ ¸¹´Ù¸é ¿äû¸¶´Ù ¸Å¹ø »ç¿ëÀÚ¸¦ + ÀÎÁõÇϱâÀ§ÇØ ÀÏ¹Ý ¹®¼­ÆÄÀÏÀ» °Ë»öÇϴµ¥ ½Ã°£ÀÌ »ó´çÈ÷ ¸¹ÀÌ + °É¸± ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ºü¸¥ µ¥ÀÌŸº£À̽º ÆÄÀÏ¿¡ »ç¿ëÀÚ Á¤º¸¸¦ + ÀúÀåÇÒ ¼ö ÀÖ´Ù. mod_authn_dbm ¸ðµâÀº AuthDBMUserFile Áö½Ã¾î¸¦ + Á¦°øÇÑ´Ù. dbmmanage + ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé°í ´Ù·é´Ù. ¾ÆÆÄÄ¡ ¸ðµâ + µ¥ÀÌŸº£À̽º¿¡´Â ¿©·¯ ´Ù¸¥ ÀÎÁõ ¹æ½ÄÀ» Á¦°øÇÏ´Â Á¦»ïÀÚ°¡ + ¸¸µç ¸ðµâµéÀÌ ÀÖ´Ù.

    + +

    ¸¶Áö¸·À¸·Î Require + Áö½Ã¾î´Â ¼­¹öÀÇ Æ¯Á¤ ¿µ¿ª¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¸¦ ÁöÁ¤ÇÏ¿© + ±ÇÇѺο©¸¦ ÇÑ´Ù. ´ÙÀ½ ÀýÀº require Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â ´Ù¾çÇÑ ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    top
    +
    +

    ¿©·¯¸íÀ» µé¿©º¸³»±â

    +

    À§ÀÇ Áö½Ã¾î´Â µð·ºÅ丮·Î (»ç¿ëÀÚ¸íÀÌ rbowenÀÎ) + ÇÑ »ç¶÷¸¸À» µé¿©º¸³½´Ù. ´ëºÎºÐÀÇ °æ¿ì ¿©·¯ »ç¶÷À» µé¿©º¸³»°í + ½ÍÀ» °ÍÀÌ´Ù. ÀÌÁ¦ AuthGroupFileÀ» + »ç¿ëÇÒ ¶§´Ù.

    + +

    ¿©·¯ »ç¶÷À» µé¿©º¸³»°í ½Í´Ù¸é ±×·ì¸í°ú ±× ±×·ì¿¡ ¾î¶² + »ç¿ëÀÚµéÀÌ ÀÖ´ÂÁö ¾Ë·ÁÁÖ´Â ±×·ìÆÄÀÏÀÌ ÇÊ¿äÇÏ´Ù. ÀÌ ÆÄÀÏÀÇ + Çü½ÄÀº ¸Å¿ì °£´ÜÇÏ¿©, ¾Æ¹« ÆíÁý±â·Î³ª ¸¸µé ¼ö ÀÖ´Ù. ÆÄÀϳ»¿ëÀº + ´ÙÀ½°ú °°´Ù.

    + +

    + GroupName: rbowen dpitts sungo rshersey +

    + +

    ±×³É °ø¹éÀ¸·Î ±¸ºÐÇÑ ±ä ±×·ì ±¸¼º¿ø ¸ñ·ÏÀÏ »ÓÀÌ´Ù.

    + +

    ±âÁ¸ÀÇ ¾ÏÈ£ÆÄÀÏ¿¡ »ç¿ëÀÚ¸¦ Ãß°¡ÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù

    + +

    + htpasswd /usr/local/apache/passwd/passwords dpitts +

    + +

    Àü°ú °°Áö¸¸, »õ·Î ÆÄÀÏÀ» ¸¸µéÁö ¾Ê°í ±âÁ¸ ÆÄÀÏ¿¡ »ç¿ëÀÚ¸¦ + Ãß°¡ÇÑ´Ù. (-c ¿É¼ÇÀº »õ·Î ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç´Ù).

    + +

    ÀÌÁ¦ .htaccess ÆÄÀÏÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.

    + +

    + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +

    + +

    ±×·¯¸é GroupName ±×·ì¿¡ ¼ÓÇϸç + password ÆÄÀÏ¿¡ Ç׸ñÀÌ ÀÖ´Â »ç¿ëÀÚ°¡ ¿Ã¹Ù¸¥ + ¾ÏÈ£¸¦ ÀÔ·ÂÇϸé Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    + +

    ¿©·¯ ÀÏ¹Ý »ç¿ëÀÚ¸¦ µé¿©º¸³»´Â ´Ù¸¥ ¹æ¹ýÀÌ ÀÖ´Ù. ±×·ìÆÄÀÏÀ» + ¸¸µé ÇÊ¿ä¾øÀÌ ´ÙÀ½ Áö½Ã¾î¸¦ »ç¿ëÇϱ⸸ ÇÏ¸é µÈ´Ù.

    + +

    + Require valid-user +

    + +

    Require user rbowen ´ë½Å ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇϸé + ¾ÏÈ£ÆÄÀÏ¿¡ ÀÖ´Â ´©±¸¶óµµ ¿Ã¹Ù¸¥ ¾ÏÈ£¸¦ ÀÔ·ÂÇϱ⸸ Çϸé Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±×·ìº°·Î ´Ù¸¥ ¾ÏÈ£ÆÄÀÏÀ» »ç¿ëÇÏ¿© ±×·ì°ú ºñ½ÁÇÑ + È¿°ú¸¦ ¾òÀ» ¼öµµ ÀÖ´Ù. ÀÌ °æ¿ì ¾ÆÆÄÄ¡°¡ ÆÄÀÏ µÎ°³(¾ÏÈ£ÆÄÀÏ°ú + ±×·ìÆÄÀÏ)°¡ ¾Æ´Ñ ÆÄÀÏ ÇÑ°³(¾ÏÈ£ÆÄÀÏ)¸¸ °Ë»çÇÏ¸é µÈ´Ù´Â °ÍÀÌ + ÀåÁ¡ÀÌ´Ù. ±×·¯³ª ¿©·¯ ¾ÏÈ£ÆÄÀÏÀ» °ü¸®ÇØ¾ß ÇÏ°í, AuthUserFile Áö½Ã¾î¿¡ + Á¤È®ÇÑ ¾ÏÈ£ÆÄÀÏÀ» ÁöÁ¤ÇØ¾ß ÇÏ´Â °ÍÀº ´ÜÁ¡ÀÌ´Ù.

    +
    top
    +
    +

    ¹ß»ýÇÒ ¼ö ÀÖ´Â ¹®Á¦Á¡

    +

    Basic ÀÎÁõ ¹æ½ÄÀº ¼­¹ö¿¡¼­ ¹®¼­¸¦ ¿äûÇÒ ¶§¸¶´Ù »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ È®ÀÎÇÑ´Ù. ½ÉÁö¾î °°Àº ÆäÀÌÁö¸¦ »õ·Î °íħÇÒ ¶§µµ ÆäÀÌÁö¿Í + (±×¸²ÀÌ ¾ÏÈ£·Î º¸È£ÇÏ´Â µð·ºÅ丮¿¡ ÀÖ´Â °æ¿ì) ÆäÀÌÁö¿¡ ÀÖ´Â + ¸ðµç ±×¸²¿¡ ´ëÇØ ´Ù½Ã È®ÀÎÇÑ´Ù. ÁüÀÛÇϵíÀÌ ¼Óµµ°¡ Á¶±Ý ´À·ÁÁø´Ù. + ¾ÏÈ£ÆÄÀÏÀ» ¿­¾î¼­ »ç¿ëÀÚ¸íÀ» ãÀ» ¶§±îÁö »ç¿ëÀÚ ¸ñ·ÏÀ» »ìÆìºÁ¾ß + Çϱ⶧¹®¿¡ ¾ÏÈ£ÆÄÀÏ Å©±â°¡ Ä¿Áú ¼ö·Ï ´õ ´À·ÁÁø´Ù. ±×¸®°í + ÀÌ ÀÛ¾÷À» ÆäÀÌÁö¸¦ ¿äûÇÒ ¶§¸¶´Ù ÁøÇàÇÑ´Ù.

    + +

    ±×·¡¼­ Çö½ÇÀûÀ¸·Î ÇÑ ¾ÏÈ£ÆÄÀÏ¿¡ ÀúÀåÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¼ö¿¡´Â + ÇÑ°è°¡ ÀÖ´Ù. ÀÌ ÇÑ°è´Â »ç¿ëÇÏ´Â ¼­¹öÀÇ ¼º´É¿¡ µû¶ó ´Ù¸£Áö¸¸, + Ç׸ñÀÌ ¼ö¹é°³°¡ ³Ñ´Â´Ù¸é ´À·ÁÁø´Ù°í »ý°¢ÇÏ°í ´Ù¸¥ ÀÎÁõ ¹æ¹ýÀ» + °í·ÁÇØ¾ß ÇÑ´Ù.

    +
    top
    +
    +

    ´Ù¸¥ ¹æ¹ýµµ °¡´ÉÇÑ°¡?

    +

    »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ »ç¿ëÇÑ ÀÎÁõÀÌ ´Ù°¡ ¾Æ´Ï´Ù. Á¾Á¾ Á¢¼ÓÇÑ + Àå¼Ò¿Í °°Àº ´Ù¸¥ Á¤º¸¸¦ °¡Áö°í »ç¿ëÀÚ¸¦ µé¿©º¸³»°í ½ÍÀ» + ¶§°¡ ÀÖ´Ù.

    + +

    Allow¿Í + Deny Áö½Ã¾î´Â + ¹®¼­¸¦ ¿äûÇÑ ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸í ȤÀº È£½ºÆ® ÁÖ¼Ò¸¦ °¡Áö°í + Á¢±ÙÀ» Çã¿ëÇϰųª °ÅºÎÇÑ´Ù. Order Áö½Ã¾î´Â ÀÌ µÎ + Áö½Ã¾î¿Í °°ÀÌ »ç¿ëÇÏ¿©, ¾ÆÆÄÄ¡¿¡°Ô ¾î¶² ¼ø¼­·Î ±ÔÄ¢À» Àû¿ëÇÒÁö + ¾Ë¸°´Ù.

    + +

    À̵é Áö½Ã¾î »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.

    + +

    + Allow from address +

    + +

    ¿©±â¼­ address´Â IP ÁÖ¼Ò(ȤÀº IP ÁÖ¼Ò ÀϺÎ)³ª + ¿ÏÀüÇÑ µµ¸ÞÀθí(ȤÀº µµ¸ÞÀθí ÀϺÎ)ÀÌ´Ù. ¿øÇÑ´Ù¸é ¿©·¯ ÁÖ¼Ò³ª + µµ¸ÞÀθíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ´©±º°¡°¡ °Ô½ÃÆÇ¿¡ ±¤°í¸¦ ¿Ã¸®°í ÀÖ´Ù¸é ´ÙÀ½°ú + °°ÀÌ Á¢±ÙÀ» ¸·À» ¼ö ÀÖ´Ù.

    + +

    + Deny from 205.252.46.165 +

    + +

    ±× ÁÖ¼Ò¿¡¼­ µé¾î¿À´Â ¹æ¹®ÀÚ´Â ÀÌ Áö½Ã¾î°¡ º¸È£ÇÏ´Â ÆäÀÌÁö¸¦ + º¼ ¼ö ¾ø´Ù. IP ÁÖ¼Ò ´ë½Å ´ÙÀ½°ú °°ÀÌ ÄÄÇ»Å͸íÀ» »ç¿ëÇÒ ¼öµµ + ÀÖ´Ù.

    + +

    + Deny from host.example.com +

    + +

    ¶Ç, Àüü µµ¸ÞÀÎÀÇ Á¢±ÙÀ» ¸·À¸·Á¸é ÁÖ¼Ò³ª µµ¸ÞÀθíÀÇ ÀϺθ¦ + »ç¿ëÇÑ´Ù.

    + +

    + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +

    + +

    Order¸¦ + Deny¿Í Allow Áö½Ã¾î¿Í °°ÀÌ + »ç¿ëÇÏ¿© ½ÇÁ¦·Î ¿øÇÏ´Â ´ë»óÀ» ¸·À» ¼ö ÀÖ´Ù.

    + +

    + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +

    + +

    Allow + Áö½Ã¾î¸¸ »ç¿ëÇϸé, ÇØ´ç È£½ºÆ®ÀÇ »ç¿ëÀÚ¸¦ Çã¿ëÇÏ°í °Å±â¿¡ + Ãß°¡·Î ¸ðµç »ç¶÷À» Çã¿ëÇϹǷΠ¿øÇÏ´Â °á°ú¸¦ ¾òÁö ¸øÇÑ´Ù. + ´ç½ÅÀº ƯÁ¤ »ç¶÷¸¸ Çã¿ëÇÏ±æ ¿øÇÑ´Ù.

    +
    top
    +
    +

    ´õ ¸¹Àº Á¤º¸

    +

    mod_auth_basic°ú + mod_authz_host ¹®¼­¿¡ Á¢±ÙÁ¦¾î°¡ µ¿ÀÛÇÏ´Â + ¹æ¹ý¿¡ ´ëÇÑ ´õ ¸¹Àº Á¤º¸°¡ ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/auth.xml b/trunk/docs/manual/howto/auth.xml new file mode 100644 index 0000000000..45cacae108 --- /dev/null +++ b/trunk/docs/manual/howto/auth.xml @@ -0,0 +1,364 @@ + + + + + + + + +How-To / Tutorials + +Authentication, Authorization and Access Control + + +

    Authentication is any process by which you verify that + someone is who they claim they are. Authorization is any + process by which someone is allowed to be where they want to + go, or to have information that they want to have.

    +
    + + + +
    Introduction +

    If you have information on your web site that is sensitive + or intended for only a small group of people, the techniques in + this article will help you make sure that the people that see + those pages are the people that you wanted to see them.

    + +

    This article covers the "standard" way of protecting parts + of your web site that most of you are going to use.

    +
    + +
    The Prerequisites +

    The directives discussed in this article will need to go + either in your main server configuration file (typically in a + Directory section), or + in per-directory configuration files (.htaccess files).

    + +

    If you plan to use .htaccess files, you will + need to have a server configuration that permits putting + authentication directives in these files. This is done with the + AllowOverride directive, which + specifies which directives, if any, may be put in per-directory + configuration files.

    + +

    Since we're talking here about authentication, you will need + an AllowOverride directive like the + following:

    + + + AllowOverride AuthConfig + + +

    Or, if you are just going to put the directives directly in + your main server configuration file, you will of course need to + have write permission to that file.

    + +

    And you'll need to know a little bit about the directory + structure of your server, in order to know where some files are + kept. This should not be terribly difficult, and I'll try to + make this clear when we come to that point.

    +
    + +
    Getting it working +

    Here's the basics of password protecting a directory on your + server.

    + +

    You'll need to create a password file. This file should be + placed somewhere not accessible from the web. This is so that + folks cannot download the password file. For example, if your + documents are served out of /usr/local/apache/htdocs you + might want to put the password file(s) in + /usr/local/apache/passwd.

    + +

    To create the file, use the htpasswd utility that + came with Apache. This will be located in the bin directory + of wherever you installed Apache. To create the file, type:

    + + + htpasswd -c /usr/local/apache/passwd/passwords rbowen + + +

    htpasswd will ask you for the password, and + then ask you to type it again to confirm it:

    + + + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +
    + +

    If htpasswd is not in your path, of course + you'll have to type the full path to the file to get it to run. + On my server, it's located at + /usr/local/apache/bin/htpasswd

    + +

    Next, you'll need to configure the server to request a + password and tell the server which users are allowed access. + You can do this either by editing the httpd.conf + file or using an .htaccess file. For example, if + you wish to protect the directory + /usr/local/apache/htdocs/secret, you can use the + following directives, either placed in the file + /usr/local/apache/htdocs/secret/.htaccess, or + placed in httpd.conf inside a <Directory + /usr/local/apache/apache/htdocs/secret> section.

    + + + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +
    + +

    Let's examine each of those directives individually. The AuthType directive selects + that method that is used to authenticate the user. The most + common method is Basic, and this is the method + implemented by mod_auth_basic. It is important to be aware, + however, that Basic authentication sends the password from the client to + the browser unencrypted. This method should therefore not be used for + highly sensitive data. Apache supports one other authentication method: + AuthType Digest. This method is implemented by mod_auth_digest and is much more secure. Only the most recent + versions of clients are known to support Digest authentication.

    + +

    The AuthName directive sets + the Realm to be used in the authentication. The realm serves + two major functions. First, the client often presents this information to + the user as part of the password dialog box. Second, it is used by the + client to determine what password to send for a given authenticated + area.

    + +

    So, for example, once a client has authenticated in the + "Restricted Files" area, it will automatically + retry the same password for any area on the same server that is + marked with the "Restricted Files" Realm. + Therefore, you can prevent a user from being prompted more than + once for a password by letting multiple restricted areas share + the same realm. Of course, for security reasons, the client + will always need to ask again for the password whenever the + hostname of the server changes.

    + +

    The AuthUserFile + directive sets the path to the password file that we just + created with htpasswd. If you have a large number + of users, it can be quite slow to search through a plain text + file to authenticate the user on each request. Apache also has + the ability to store user information in fast database files. + The mod_authn_dbm module provides the AuthDBMUserFile directive. These + files can be created and manipulated with the + dbmmanage program. Many + other types of authentication options are available from third + party modules in the Apache Modules + Database.

    + +

    Finally, the Require + directive provides the authorization part of the process by + setting the user that is allowed to access this region of the + server. In the next section, we discuss various ways to use the + Require directive.

    +
    + +
    Letting more than one +person in +

    The directives above only let one person (specifically + someone with a username of rbowen) into the + directory. In most cases, you'll want to let more than one + person in. This is where the AuthGroupFile comes in.

    + +

    If you want to let more than one person in, you'll need to + create a group file that associates group names with a list of + users in that group. The format of this file is pretty simple, + and you can create it with your favorite editor. The contents + of the file will look like this:

    + + + GroupName: rbowen dpitts sungo rshersey + + +

    That's just a list of the members of the group in a long + line separated by spaces.

    + +

    To add a user to your already existing password file, + type:

    + + + htpasswd /usr/local/apache/passwd/passwords dpitts + + +

    You'll get the same response as before, but it will be + appended to the existing file, rather than creating a new file. + (It's the -c that makes it create a new password + file).

    + +

    Now, you need to modify your .htaccess file to + look like the following:

    + + + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +
    + +

    Now, anyone that is listed in the group GroupName, + and has an entry in the password file, will be let in, if + they type the correct password.

    + +

    There's another way to let multiple users in that is less + specific. Rather than creating a group file, you can just use + the following directive:

    + + + Require valid-user + + +

    Using that rather than the Require user rbowen + line will allow anyone in that is listed in the password file, + and who correctly enters their password. You can even emulate + the group behavior here, by just keeping a separate password + file for each group. The advantage of this approach is that + Apache only has to check one file, rather than two. The + disadvantage is that you have to maintain a bunch of password + files, and remember to reference the right one in the + AuthUserFile directive.

    +
    + +
    Possible problems +

    Because of the way that Basic authentication is specified, + your username and password must be verified every time you + request a document from the server. This is even if you're + reloading the same page, and for every image on the page (if + they come from a protected directory). As you can imagine, this + slows things down a little. The amount that it slows things + down is proportional to the size of the password file, because + it has to open up that file, and go down the list of users + until it gets to your name. And it has to do this every time a + page is loaded.

    + +

    A consequence of this is that there's a practical limit to + how many users you can put in one password file. This limit + will vary depending on the performance of your particular + server machine, but you can expect to see slowdowns once you + get above a few hundred entries, and may wish to consider a + different authentication method at that time.

    +
    + +
    What other neat stuff can I +do? +

    Authentication by username and password is only part of the + story. Frequently you want to let people in based on something + other than who they are. Something such as where they are + coming from.

    + +

    The Allow and + Deny directives let + you allow and deny access based on the host name, or host + address, of the machine requesting a document. The + Order directive goes + hand-in-hand with these two, and tells Apache in which order to + apply the filters.

    + +

    The usage of these directives is:

    + + + Allow from address + + +

    where address is an IP address (or a partial IP + address) or a fully qualified domain name (or a partial domain + name); you may provide multiple addresses or domain names, if + desired.

    + +

    For example, if you have someone spamming your message + board, and you want to keep them out, you could do the + following:

    + + + Deny from 205.252.46.165 + + +

    Visitors coming from that address will not be able to see + the content covered by this directive. If, instead, you have a + machine name, rather than an IP address, you can use that.

    + + + Deny from host.example.com + + +

    And, if you'd like to block access from an entire domain, + you can specify just part of an address or domain name:

    + + + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +
    + +

    Using Order will let you + be sure that you are actually restricting things to the group that you want + to let in, by combining a Deny and an Allow directive:

    + + + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +
    + +

    Listing just the Allow + directive would not do what you want, because it will let folks from that + host in, in addition to letting everyone in. What you want is to let + only those folks in.

    +
    + +
    More information +

    You should also read the documentation for + mod_auth_basic and mod_authz_host which + contain some more information about how this all works.

    +
    + +
    + diff --git a/trunk/docs/manual/howto/auth.xml.ja b/trunk/docs/manual/howto/auth.xml.ja new file mode 100644 index 0000000000..504d83d1e8 --- /dev/null +++ b/trunk/docs/manual/howto/auth.xml.ja @@ -0,0 +1,388 @@ + + + + + + + + +How-To / $B%A%e!<%H%j%"%k(B + +$BG'>Z!">5G'!"%"%/%;%9@)8f(B + + +

    $B!VG'>Z!W$H$O!"C/$+$,<+J,$OC/$G$"$k$+$rl9g$K!"(B + $B$=$l$r3NG'$9$k$?$a$NA42aDx$r;X$7$^$9!#!V>5G'!W$H$O!"(B + $BC/$+$,9T$-$?$$>l=j$K9T$1$k$h$&$K!"$"$k$$$OM_$7$$>pJs$r(B + $BF@$k$3$H$,$G$-$k$h$&$K$9$k$?$a$NA42aDx$r;X$7$^$9!#(B

    +
    + + + +
    $B$O$8$a$K(B +

    $B$b$75!L)$N>pJs$d!"$4$/$4$/>/?t%0%k!<%W$N?M8~$1$N>pJs$r(B + $B%&%'%V%5%$%H$KCV$/$N$G$"$l$P!"$3$NJ8=q$K=q$+$l$F$$$k(B + $B%F%/%K%C%/$r;H$&$3$H$G!"$=$N%Z!<%8$r8+$F$$$k?M$?$A$,(B + $BK>$_$N?M$?$A$G$"$k$3$H$r3N + +

    $B$3$NJ8=q$G$O!"B?$/$N?M$,:NMQ$9$k$G$"$m$&!"(B + $B%&%'%V%5%$%H$N0lItJ,$rJ]8n$9$k!V0lHLE*$J!W(B + $BJ}K!$K$D$$$F%+%P!<$7$F$$$^$9!#(B

    +
    + +
    $B=`Hw(B +

    $B$3$NJ8=q$GDirectory + $B%;%/%7%g%sCf(B) $B$+!"$"$k$$$O%G%#%l%/%H%jKh$N@_Dj%U%!%$%k(B + (.htaccess $B%U%!%$%k(B) $B$+$GMQ$$$^$9!#(B

    + +

    .htaccess $B%U%!%$%k$rMQ$$$k$N$G$"$l$P!"(B + $B$3$l$i$N%U%!%$%k$KG'>ZMQ$N%G%#%l%/%F%#%V$rCV$1$k$h$&$K(B + $B%5!<%P$N@_Dj$r$7$J$$$H$$$1$J$$$G$7$g$&!#$3$l$O(B + AllowOverride + $B%G%#%l%/%F%#%V$G2DG=$K$J$j$^$9!#(B + AllowOverride + $B%G%#%l%/%F%#%V$G$O!"%G%#%l%/%H%jKh$N@_Dj%U%!%$%kCf$KCV$/$3$H$N$G$-$k(B + $B%G%#%l%/%F%#%V$r!"$b$7$"$l$P!";XDj$7$^$9!#(B

    + +

    $BG'>Z$K$D$$$FOC$r?J$a$F$$$k$N$G!"AllowOverride + $B%G%#%l%/%F%#%V$,I,MW$K$J$k$G$7$g$&!#(B

    + + + AllowOverride AuthConfig + + +

    $B$=$&$G$J$/!"%a%$%s%5!<%P@_Dj%U%!%$%k$NCf$K(B + $BD>@\CV$/$N$G$"$l$P!"EvA3$J$,$i$=$N%U%!%$%k$X$N=q$-9~$_(B + $B8"8B$r;}$C$F$$$J$1$l$P$J$i$J$$$G$7$g$&!#(B

    + +

    $B$^$?!"$I$N%U%!%$%k$,$I$3$KJ]B8$5$l$F$$$k$+CN$k$?$a$K!"(B + $B%5!<%P$N%G%#%l%/%H%j9=B$$K$D$$$F>/$7CN$C$F$*$/(B + $BI,MW$,$"$k$G$7$g$&!#(B + $B$3$l$O$=$s$J$KFq$7$/$J$$$N$G!"$3$NJ8=qCf$G(B + $B%G%#%l%/%H%j9=B$$K$D$$$FCN$C$F$*$/I,MW$,$"$k>lLL$G$O!"(B + $BL@$i$+$K$J$k$h$&$K$7$^$9!#(B

    +
    + +
    $BF0:n$5$;$k(B +

    $B$G$O!"%5!<%P>e$N$"$k%G%#%l%/%H%j$r%Q%9%o!<%I$GJ]8n$9$k(B + $B4pK\ + +

    $B%Q%9%o!<%I%U%!%$%k$r:n$kI,MW$,$"$j$^$9!#(B + $B$3$N%U%!%$%k$O!"%&%'%V$+$i%"%/%;%9$G$-$k>l=j$K(B + $BCV$/$Y$-$G$O$"$j$^$;$s!#B>$N?M$,%Q%9%o!<%I%U%!%$%k$r(B + $B%@%&%s%m!<%I$G$-$J$$$h$&$K$9$k$?$a$G$9!#Nc$($P!"(B + /usr/local/apache/htdocs $B$G%I%-%e%a%s%H$r(B + $BDs6!$7$F$$$k$N$G$"$l$P!"%Q%9%o!<%I%U%!%$%k$O(B + /usr/local/apache/passwd + $B$J$I$KCV$$$?J}$,NI$$$G$7$g$&!#(B

    + +

    $B%U%!%$%k$r:n$k$?$a$K$O!"(BApache $BIUB0$N(B htpasswd + $B$r;H$$$^$9!#$3$N%3%^%s%I$O(B Apache $B$r$I$3$K%$%s%9%H!<%k$7$h$&$H$b!"(B + $B%$%s%9%H!<%k%G%#%l%/%H%j$N(B bin + $B%G%#%l%/%H%j0J2<$KCV$+$l$^$9!#%U%!%$%k$r:n$k$K$O!" + + + htpasswd -c /usr/local/apache/passwd/passwords rbowen + + +

    htpasswd $B$O!"%Q%9%o!<%I$rMW5a$7!"$=$N8e(B + $B3NG'$N$?$a$K$b$&0lEYF~NO$9$k$h$&$KMW5a$7$F$-$^$9!#(B

    + + + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +
    + +

    $B$b$7(B htpasswd $B$,%Q%9$NCf$KF~$C$F$$$J$$>l9g$O!"(B + $B$b$A$m$s!"/usr/local/apache/bin/htpasswd + $B$K%W%m%0%i%`$,CV$+$l$F$$$^$9!#(B

    + +

    $Bhttpd.conf $B$rJT=8$9$k$+(B + .htaccess $B%U%!%$%k$r;HMQ$9$k$+$G(B + $B@_Dj$7$^$9!#Nc$($P!"%G%#%l%/%H%j(B + /usr/local/apache/htdocs/secret + $B$rJ]8n$7$?$$>l9g$O!"(B + /usr/local/apache/htdocs/secret/.htaccess + $B$+(B httpd.conf $BCf$N(B <Directory + /usr/local/apache/apache/htdocs/secret> $B%;%/%7%g%s$K(B + $BG[CV$7$F!" + + + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +
    + +

    $B8D!9$N%G%#%l%/%F%#%V$K$D$$$F8+$F$_$^$7$g$&!#(B + AuthType + $B%G%#%l%/%F%#%V$O$I$&$$$&G'>ZJ}K!$G%f!<%6$NG'>Z$r9T$&$+$r(B + $BA*Br$7$^$9!#:G$b0lHLE*$JJ}K!$O(B Basic + $B$G!"$3$l$O(B mod_auth_basic + $B$GZ$O%/%i%$%"%s%H$+$i%V%i%&%6$X!"(B + $B%Q%9%o!<%I$r0E9f2=$;$:$KAw$j$^$9!#$G$9$+$i!"(B + $B$3$NJ}K!$OFC$K5!L)@-$N9b$$%G!<%?$KBP$7$F$OMQ$$$k$Y$-$G$O(B + $B$"$j$^$;$s!#(B Apache $B$G$O$b$&0l$DJL$NG'>ZJ}K!(B: + AuthType Digest $B$r%5%]!<%H$7$F$$$^$9!#(B + $B$3$NJ}K!$O(B mod_auth_digest + $B$GZ$r%5%]!<%H$7$F$$$J$$$h$&$G$9!#(B

    + +

    AuthName + $B%G%#%l%/%F%#%V$G$O!"G'>Z$K;H$&(B Realm ($BLuCm(B: $BNN0h(B) + $B$r@_Dj$7$^$9!#(BRealm $B$OBg$-$/J,$1$FFs$D$N5!G=$rDs6!$7$^$9!#(B + $B0l$DL\$O!"%/%i%$%"%s%H$,%Q%9%o!<%I%@%$%"%m%0%\%C%/%9$N(B + $B0lIt$H$7$F%f!<%6$K$3$N>pJs$r$h$/Ds<($9$k!"$H$$$&$b$N$G$9!#(B + $BFs$DL\$K$O!"%/%i%$%"%s%H$,M?$($i$l$?G'>ZNN0h$KBP$7$F$I$N%Q%9%o!<%I$r(B + $BAw?.$9$l$PNI$$$N$+$r7hDj$9$k$?$a$K;H$o$l$k!"$H$$$&5!G=$G$9!#(B

    + +

    $BNc$($P!"(B"Restricted Files" $BNN0hCf$G(B + $B0lEYG'>Z$5$l$l$P!"F10l%5!<%P>e$G(B "Restricted Files" + Realm $B$H$7$F%^!<%/$5$l$?$I$s$JNN0h$G$b!"%/%i%$%"%s%H$O(B + $B<+F0E*$KF1$8%Q%9%o!<%I$r;H$*$&$H;n$_$^$9!#(B + $B$3$N$*$+$2$G!"J#?t$N@)8BNN0h$KF1$8(B realm $B$r6&M-$5$;$F!"(B + $B%f!<%6$,%Q%9%o!<%I$r2?EY$bMW5a$5$l$k;vBV$r(B + $BKI$0$3$H$,$G$-$^$9!#$b$A$m$s!"%;%-%e%j%F%#>e$NM}M3$+$i!"(B + $B%5!<%P$N%[%9%HL>$,JQ$o$l$P$$$D$G$bI,$:!"(B + $B%/%i%$%"%s%H$O:F$S%Q%9%o!<%I$r?R$M$kI,MW$,$"$j$^$9!#(B

    + +

    AuthUserFile + $B%G%#%l%/%F%#%V$O(B htpasswd $B$G:n$C$?(B + $B%Q%9%o!<%I%U%!%$%k$X$N%Q%9$r@_Dj$7$^$9!#(B + $B%f!<%6?t$,B?$$>l9g$O!"%j%/%(%9%HKh$N%f!<%6$NG'>Z$N$?$a$N(B + $B%W%l!<%s%F%-%9%H$NC5:w$,Hs>o$KCY$/$J$k$3$H$,$"$j$^$9!#(B + Apache $B$G$O%f!<%6>pJs$r9bB.$J%G!<%?%Y!<%9%U%!%$%k$K(B + $BJ]4I$9$k$3$H$b$G$-$^$9!#(B + mod_authn_dbm $B%b%8%e!<%k$,(B + AuthDBMUserFile + $B%G%#%l%/%F%#%V$rDs6!$7$^$9!#$3$l$i$N%U%!%$%k$O(B dbmmanage + $B%W%m%0%i%`$G:n@.$7$?$jA`:n$7$?$j$G$-$^$9!#(B + Apache + $B%b%8%e!<%k%G!<%?%Y!<%9(B$BCf$K$"$k%5!<%I%Q!<%F%#!<@=$N(B + $B%b%8%e!<%k$G!"$=$NB>B?$/$N%?%$%W$NG'>Z%*%W%7%g%s$,(B + $BMxMQ2DG=$G$9!#(B

    + +

    $B:G8e$K!"(BRequire + $B%G%#%l%/%F%#%V$,!"%5!<%P$N$3$NNN0h$K%"%/%;%9$G$-$k%f!<%6$r(B + $B;XDj$9$k$3$H$K$h$C$F!"%W%m%;%9$N>5G'ItJ,$rDs6!$7$^$9!#(B + $BRequire + $B%G%#%l%/%F%#%V$NMM!9$JMQK!$K$D$$$F=R$Y$^$9!#(B

    +
    + +
    +$BJ#?t$N?M$,F~$l$k$h$&$K$9$k(B +

    $B>e5-$N%G%#%l%/%F%#%V$O!"$?$@0l?M(B ($B6qBNE*$K$O%f!<%6L>(B + rbowen $B$NC/$+(B) $B$,%G%#%l%/%H%j$K(B + $BF~$l$k$h$&$K$7$^$9!#B?$/$N>l9g$O!"J#?t$N?M$,(B + $BF~$l$k$h$&$K$7$?$$$G$7$g$&!#$3$3$G(B + AuthGroupFile + $B$NEP>l$G$9!#(B

    + +

    $B$b$7J#?t$N?M$,F~$l$k$h$&$K$7$?$$$N$G$"$l$P!"(B + $B%0%k!<%W$KB0$9$k%f!<%6$N0lMw$NF~$C$F$$$k!"%0%k!<%WL>$N$D$$$?(B + $B%0%k!<%W%U%!%$%k$r:n$kI,MW$,$"$j$^$9!#$3$N%U%!%$%k$N(B + $B=q<0$O$-$o$a$FC1=c$G!"$*9%$_$N%(%G%#%?$G@8@.$G$-$^$9!#(B + $B%U%!%$%k$NCf?H$O + + + GroupName: rbowen dpitts sungo rshersey + + +

    $B0l9T$K%9%Z!<%96h@Z$j$G!"%0%k!<%W$K=jB0$9$k%a%s%P!<$N(B + $B0lMw$r$J$i$Y$k$@$1$G$9!#(B

    + +

    $B4{$KB8:_$9$k%Q%9%o!<%I%U%!%$%k$K%f!<%6$r2C$($k>l9g$O!"(B + $B + + + htpasswd /usr/local/apache/passwd/passwords dpitts + + +

    $B0JA0$HF1$81~Ez$,JV$5$l$^$9$,!"?7$7$$%U%!%$%k$r(B + $B:n$k$N$G$O$J$/!"4{$K$"$k%U%!%$%k$KDI2C$5$l$F$$$^$9!#(B + ($B?7$7$$%Q%9%o!<%I%U%!%$%k$r:n$k$K$O(B -c + $B$r;H$$$^$9!#(B)

    + +

    $B$3$3$G.htaccess $B%U%!%$%k$r(B + $B=$@5$9$kI,MW$,$"$j$^$9!#(B

    + + + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +
    + +

    $B$3$l$G!"%0%k!<%W(B GroupName $B$K%j%9%H$5$l$F$$$F!"(B + password $B%U%!%$%k$K%(%s%H%j$,$"$k?M$O!"(B + $B@5$7$$%Q%9%o!<%I$r%?%$%W$9$l$PF~$k$3$H$,$G$-$k$G$7$g$&!#(B

    + +

    $B$b$C$HFCDj$;$:$KJ#?t$N%f!<%6$,F~$l$k$h$&$K$9$k!"(B + $B$b$&0l$D$NJ}K!$,$"$j$^$9!#%0%k!<%W%U%!%$%k$r:n$k$N$G$O$J$/!"(B + $B + + + Require valid-user + + +

    require user rbowen $B9T$G$J$/!">e5-$r;H$&$H!"(B + $B%Q%9%o!<%I%U%!%$%k$K%j%9%H$5$l$F$$$k?M$G$"$l$PC/$G$b(B + $B5v2D$5$l$^$9!#(B + $BC1$K%Q%9%o!<%I%U%!%$%k$r%0%k!<%WKh$KJ,$1$F$*$/$3$H$G!"(B + $B%0%k!<%W$N$h$&$J?6$kIq$$$r$5$;$k$3$H$b$G$-$^$9!#(B + $B$3$N%"%W%m!<%A$NMxE@$O!"(BApache $B$OFs$D$G$O$J$/!"(B + $B$?$@0l$D$N%U%!%$%k$@$1$r8!::$9$l$P$h$$$H$$$&E@$G$9!#(B + $B7gE@$O!"$?$/$5$s$N%Q%9%o!<%I%U%!%$%k$r4IM}$7$F!"$=$NCf$+$i(B + AuthUserFile + $B%G%#%l%/%F%#%V$K@5$7$$%U%!%$%k$r;2>H$5$;$J$1$l$P$J$i$J$$E@$G$9!#(B

    +
    + +
    $B5/$3$j$($kLdBj(B +

    Basic $BG'>Z$,;XDj$5$l$F$$$k>l9g$O!"(B + $B%5!<%P$K%I%-%e%a%s%H$r%j%/%(%9%H$9$kEY$K(B + $B%f!<%6L>$H%Q%9%o!<%I$r8!::$7$J$1$l$P$J$j$^$;$s!#(B + $B$3$l$OF1$8%Z!<%8!"%Z!<%8$K$"$kA4$F$N2hA|$r(B + $B%j%m!<%I$9$k>l9g$G$"$C$F$b3:Ev$7$^$9(B + ($B$b$72hA|$bJ]8n$5$l$?%G%#%l%/%H%j$+$iMh$k$N$G$"$l$P(B) $B!#(B + $BM=A[$5$l$kDL$j!"$3$l$OF0:n$rB?>/CY$/$7$^$9!#(B + $BCY$/$J$kDxEY$O%Q%9%o!<%I%U%!%$%k$NBg$-$5$HHfNc$7$^$9$,!"(B + $B$3$l$O!"%U%!%$%k$r3+$$$F$"$J$?$NL>A0$rH/8+$9$k$^$G(B + $B%f!<%6L>$N%j%9%H$rFI$^$J$1$l$P$J$i$J$$$+$i$G$9!#(B + $B$=$7$F!"%Z!<%8$,%m!<%I$5$l$kEY$K$3$l$r9T$o$J$1$l$P(B + $B$J$j$^$;$s!#(B

    + +

    $B7kO@$H$7$F$O!"0l$D$N%Q%9%o!<%I%U%!%$%k$KCV$/$3$H$N$G$-$k(B + $B%f!<%6?t$K$O$NG'>ZJ}K!$r9MN8$KF~$l$?J}$,NI$$$G$7$g$&!#(B

    +
    + +
    $B$b$C$H9*$_$K@)8f$G$-$J$$(B +? +

    $B%f!<%6L>$H%Q%9%o!<%I$K$h$kG'>Z$OG'>Z$N0l$D$NJ}K!$K2a$.$^$;$s!#(B + $B$7$P$7$PC/$G$"$k$+$H$$$&$3$H$H$O0c$&2?$+$K4p$E$$$F!"(B + $BF~$l$k$h$&$K$7$?$/$J$k$3$H$b$"$k$G$7$g$&!#(B + $BNc$($P$=$N?M$,$I$3$+$iMh$F$$$k$+$H$$$C$?$3$H$G$9!#(B

    + +

    Allow $B$H(B + Deny + $B%G%#%l%/%F%#%V$r;H$C$F!"%I%-%e%a%s%H$rMW5a$7$F$-$?%^%7%s$N(B + $B%[%9%HL>$d%[%9%H%"%I%l%9$K4p$E$$$F5v2DIT5v2D$r@)8f$G$-$^$9!#(B + Order + $B%G%#%l%/%F%#%V$O$3$NFs$D$HO"7H$7$FF0:n$7!"(BApache + $B$K$I$N=gHV$G%U%#%k%?$rE,MQ$9$k$+$rCN$i$;$^$9!#(B

    + +

    $B$3$l$i$N%G%#%l%/%F%#%V$N;H$$J}$O + + + Allow from address + + +

    $B$3$3$G!"(Baddress $B$O(B IP $B%"%I%l%9(B + ($B$^$?$O(B IP $B%"%I%l%9$N0lIt(B)$B!"$"$k$$$O40A4=$>~%I%a%$%sL>(B + ($B$^$?$O%I%a%$%sL>$N0lIt(B) $B$G$9!#(B + $BI,MW$G$"$l$PJ#?t$N%"%I%l%9$d%I%a%$%sL>$r;XDj$G$-$^$9!#(B

    + +

    $BNc$($P!"$b$7C/$+$,7G<(HD$r967b$7$F$$$F!"(B + $B$=$N?M$rJD$a=P$7$?$$$N$G$"$l$P!"(B + $B + + + Deny from 205.252.46.165 + + +

    $B$3$N%"%I%l%9$+$iMh$k?M$O!"$3$N%G%#%l%/%F%#%V$NHO0OFb$N(B + $B%3%s%F%s%D$r8+$k$3$H$,$G$-$J$$$^$;$s!#$b$7(B IP + $B%"%I%l%9$NBe$o$j$K%^%7%sL>$,$"$l$P!"$=$l$r;H$($^$9!#(B

    + + + Deny from host.example.com + + +

    $B%I%a%$%sA4BN$+$i$N%"%/%;%9$rKI$.$?$1$l$P!"(B + $BC1$K%"%I%l%9$d%I%a%$%sL>$N0lIt$r;XDj$9$k$3$H$,$G$-$^$9!#(B

    + + + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +
    + +

    Order $B$r;H$&$3$H$G!"(B + Deny $B$H(B + Allow $B$NAH$_9g$o$;$G(B + $BF~$C$F$bNI$$%0%k!<%W$,K\Ev$K3N + + + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +
    + +

    Allow + $B%G%#%l%/%F%#%V$rC1=c$KNs5s$9$k$N$G$OK>$_$NF0:n$r$7$J$$$G$7$g$&!#(B + $B$J$<$J$i!"A4$F$N?M$,F~$l$k$H$$$&$3$H$K2C$($F!"(B + $B;XDj$7$?%[%9%H$+$i$N?M$,F~$l$k$h$&$K$9$k$+$i$G$9!#(B + $B$d$j$?$$$3$H$O!";XDj$7$??M$?$A(B$B$@$1(B$B$,F~$l$k$h$&$K(B + $B$9$k$3$H$G$9!#(B

    +
    + +
    $BDI2C>pJs(B +

    $B$3$l$iA4$F$,$I$N$h$&$KF0:n$9$k$+$K$D$$$F(B + $B$b$C$HB?$/$N>pJs$,=q$+$l$F$$$k(B mod_auth_basic $B$H(B + mod_authz_host + $B$NJ8=q$bFI$`$H$h$$$G$7$g$&!#(B

    +
    + +
    + diff --git a/trunk/docs/manual/howto/auth.xml.ko b/trunk/docs/manual/howto/auth.xml.ko new file mode 100644 index 0000000000..4a16462456 --- /dev/null +++ b/trunk/docs/manual/howto/auth.xml.ko @@ -0,0 +1,334 @@ + + + + + + + + +How-To / Tutorials + +ÀÎÁõ(Authentication), ±ÇÇѺο©(Authorization), +Á¢±ÙÁ¦¾î(Access Control) + + +

    ÀÎÁõ(authentication)Àº ÀÚ½ÅÀÌ ´©±¸¶ó°í ÁÖÀåÇÏ´Â »ç¶÷À» + È®ÀÎÇÏ´Â ÀýÂ÷ÀÌ´Ù. ±ÇÇѺο©(authorization)´Â °¡°í ½ÍÀº °÷À¸·Î + °¡µµ·Ï ȤÀº ¿øÇÏ´Â Á¤º¸¸¦ ¾òµµ·Ï Çã¿ëÇÏ´Â °úÁ¤ÀÌ´Ù.

    +
    + + + +
    ¼Ò°³ +

    ´ç½ÅÀÇ À¥»çÀÌÆ®¿¡ ÀÖ´Â Á¤º¸°¡ ¼Ò¼öÀÇ »ç¶÷µé¸¸ÀÇ ºñ¹ÐÀ̰ųª + À̵鸸À» À§ÇÑ Á¤º¸¶ó¸é, ÀÌ ±Û¿¡¼­ ¼³¸íÇÏ´Â ±â¹ýÀ» »ç¿ëÇÏ¿© + ´ç½ÅÀÌ º¸±æ ¿øÇÏ´Â »ç¶÷¸¸ ÆäÀÌÁö¸¦ º¸µµ·Ï ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ±ÛÀº À¥»çÀÌÆ®ÀÇ ÀϺθ¦ º¸È£ÇϱâÀ§ÇØ ¸¹Àº »ç¶÷µéÀÌ + »ç¿ëÇÏ´Â "Ç¥ÁØÀûÀÎ" ¹æ¹ýÀ» ´Ù·é´Ù.

    +
    + +
    ±âº» Áö½Ä +

    ÀÌ ±Û¿¡¼­ ´Ù·ç´Â Áö½Ã¾î´Â ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏ(ÀϹÝÀûÀ¸·Î + Directory + ¼½¼Ç)À̳ª µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ(.htaccess ÆÄÀÏ)¿¡¼­ + »ç¿ëÇÑ´Ù.

    + +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ·Á¸é ÀÌ ÆÄÀÏ¿¡ ÀÖ´Â + ÀÎÁõ Áö½Ã¾î¸¦ Çã¿ëÇϵµ·Ï ¼­¹ö¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. À̸¦ À§ÇØ + µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö¸¦ °áÁ¤ÇÏ´Â + AllowOverride Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¿©±â¼­´Â ÀÎÁõÀ» ´Ù·ç±â ¶§¹®¿¡, ´ÙÀ½°ú °°Àº + AllowOverride Áö½Ã¾î°¡ ÇÊ¿äÇÏ´Ù.

    + + + AllowOverride AuthConfig + + +

    ȤÀº Áö½Ã¾î¸¦ Á÷Á¢ ¼­¹ö ÁÖ¼³Á¤ÆÄÀÏ¿¡ Àû´Â´Ù¸é, ±× ÆÄÀÏ¿¡ + ¾²±â ±ÇÇÑÀÌ ¹°·Ð ÀÖ¾î¾ß ÇÑ´Ù.

    + +

    ±×¸®°í º¸È£ÇÒ ÆÄÀÏÀÌ ¾îµðÀÖ´ÂÁö ¾Ë±âÀ§ÇØ ¼­¹öÀÇ µð·ºÅ丮 + ±¸Á¶¿¡ ´ëÇØ Á¶±Ý ¾Ë¾Æ¾ßÇÑ´Ù. ÀÌ ÀÏÀº ¾î·ÆÁö¾Ê°í, Àû´çÇÑ + ¶§¿¡ ÀÚ¼¼È÷ ¼³¸íÇÒ °ÍÀÌ´Ù.

    +
    + +
    ±âº»ÀûÀÎ ¼³Á¤Çϱâ +

    ÀÌÁ¦ ¼­¹öÀÇ µð·ºÅ丮¸¦ ¾ÏÈ£·Î º¸È£ÇÏ´Â ±âº»ÀûÀÎ ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    + +

    ¸ÕÀú ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé¾î¾ß ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¥¿¡¼­ Á¢±ÙÇÒ + ¼ö ¾ø´Â °÷¿¡ ÀÖ¾î¾ß ÇÑ´Ù. ´Ù¸¥»ç¶÷ÀÌ ¾ÏÈ£ÆÄÀÏÀ» ´Ù¿î·ÎµåÇÏÁö + ¸øÇÏ°ÔÇϱâ À§Çؼ­´Ù. ¿¹¸¦ µé¾î, ¹®¼­µéÀÌ + /usr/local/apache/htdocs¿¡ ÀÖ´Ù¸é ¾ÏÈ£ÆÄÀÏ(µé)Àº + /usr/local/apache/passwd¿¡ µÐ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔµÈ htpasswd µµ±¸¸¦ »ç¿ëÇÏ¿© + ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç´Ù. ÀÌ ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ °÷ÀÇ + bin µð·ºÅ丮¿¡ ÀÖ´Ù. ÆÄÀÏÀ» ¸¸µé·Á¸é ´ÙÀ½°ú + °°ÀÌ ÀÔ·ÂÇÑ´Ù.

    + + + htpasswd -c /usr/local/apache/passwd/passwords rbowen + + +

    htpasswd´Â ¾ÏÈ£¸¦ ¹°¾îº¸°í, È®ÀÎÀ» À§ÇØ + ¾ÏÈ£¸¦ ´Ù½Ã ÀÔ·ÂÇ϶ó°í ¿äûÇÑ´Ù.

    + + + # htpasswd -c /usr/local/apache/passwd/passwords rbowen
    + New password: mypassword
    + Re-type new password: mypassword
    + Adding password for user rbowen +
    + +

    ¹°·Ð htpasswdÀÌ ½ÇÇàÆÄÀÏ °æ·Î¿¡ ¾ø´Ù¸é + ½ÇÇàÆÄÀÏÀÇ Àüü °æ·Î¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. ³»°¡ »ç¿ëÇÏ´Â ¼­¹ö¿¡¼­´Â + /usr/local/apache/bin/htpasswd¿¡ ½ÇÇàÆÄÀÏÀÌ + ÀÖ´Ù.

    + +

    ´ÙÀ½À¸·Î ¼­¹ö°¡ ¾ÏÈ£¸¦ ¿äûÇϵµ·Ï ¼³Á¤ÇÏ°í, ¼­¹ö¿¡°Ô + ¾î¶² »ç¿ëÀÚÀÇ Á¢±ÙÀ» Çã¿ëÇÒÁö ¾Ë·ÁÁà¾ß ÇÑ´Ù. + httpd.conf¸¦ ÆíÁýÇϰųª .htaccess + ÆÄÀÏÀ» »ç¿ëÇÏ¿© ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¾î, + /usr/local/apache/htdocs/secret µð·ºÅ丮¸¦ + º¸È£ÇÏ·Á¸é, ¾Æ·¡ Áö½Ã¾î¸¦ + /usr/local/apache/htdocs/secret/.htaccess ÆÄÀÏÀ̳ª + httpd.confÀÇ <Directory + /usr/local/apache/apache/htdocs/secret> ¼½¼Ç¿¡ Àû¾î¾ß + ÇÑ´Ù.

    + + + AuthType Basic
    + AuthName "Restricted Files"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + Require user rbowen +
    + +

    Áö½Ã¾î¸¦ Çϳª¾¿ »ìÆ캸ÀÚ. AuthType Áö½Ã¾î´Â »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ + ¹æ¹ýÀ» ¼±ÅÃÇÑ´Ù. °¡Àå ÀϹÝÀûÀÎ ¹æ¹ýÀº BasicÀ¸·Î, + mod_auth_basicÀÌ ±¸ÇöÇÑ´Ù. ±×·¯³ª Basic + ÀÎÁõÀº ºê¶ó¿ìÀú°¡ ¼­¹ö·Î ¾ÏÈ£¸¦ ¾ÏȣȭÇÏÁö ¾Ê°í º¸³½´Ù. + ±×·¯¹Ç·Î ±â¹Ð ÀڷḦ º¸È£ÇϱâÀ§ÇØ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. + ¾ÆÆÄÄ¡´Â AuthType Digest¶ó´Â ÀÎÁõ ¹æ¹ýµµ Áö¿øÇÑ´Ù. + ÀÌ ¹æ¹ýÀº mod_auth_digest°¡ ±¸ÇöÇϸç, ¸Å¿ì + ¾ÈÀüÇÏ´Ù. °¡Àå Ãֱ٠Ŭ¶óÀ̾ðÆ®µé¸¸ÀÌ Digest ÀÎÁõÀ» Áö¿øÇÑ´Ù°í + ÇÑ´Ù.

    + +

    AuthName Áö½Ã¾î´Â + ÀÎÁõ¿¡ »ç¿ëÇÒ ¿µ¿ª(realm)À» ÁöÁ¤ÇÑ´Ù. ¿µ¿ªÀº + µÎ°¡Áö ¿ªÇÒÀ» ÇÑ´Ù. ù¹ø°´Â Ŭ¶óÀ̾ðÆ®°¡ º¸Åë ÀÌ Á¤º¸¸¦ + ¾ÏÈ£ ´ëȭâ¿¡ º¸¿©ÁØ´Ù. µÎ¹ø°´Â ¿µ¿ª Á¤º¸¸¦ »ç¿ëÇÏ¿© + Ŭ¶óÀ̾ðÆ®°¡ ƯÁ¤ ÀÎÁõ±¸¿ª¿¡ ¾î¶² ¾ÏÈ£¸¦ º¸³¾Áö °áÁ¤ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, ÀÏ´Ü Å¬¶óÀ̾ðÆ®°¡ "Restricted Files" + ¿µ¿ª¿¡ ÀÎÁõÀÌ ¼º°øÇÏ¿´´Ù¸é, Ŭ¶óÀ̾ðÆ®´Â ÀÚµ¿À¸·Î °°Àº ¼­¹ö¿¡¼­ + "Restricted Files" ¿µ¿ªÀ¸·Î Ç¥½ÃµÈ ±¸¿ª¿¡ ´ëÇØ + µ¿ÀÏÇÑ ¾ÏÈ£¸¦ ½ÃµµÇÑ´Ù. ±×·¡¼­ ¿©·¯ Á¦ÇÑ ±¸¿ªÀÌ °°Àº ¿µ¿ªÀ» + °øÀ¯ÇÏ¸é »ç¿ëÀÚ°¡ ¿©·¯¹ø ¾ÏÈ£¸¦ ÀÔ·ÂÇÏÁö ¾Ê¾Æµµ µÈ´Ù. ¹°·Ð + º¸¾È»ó ÀÌÀ¯·Î Ŭ¶óÀ̾ðÆ®´Â ¼­¹öÀÇ È£½ºÆ®¸íÀÌ ´Ù¸£¸é Ç×»ó + »õ·Î ¾ÏÈ£¸¦ ¹°¾îº»´Ù.

    + +

    AuthUserFile + Áö½Ã¾î´Â ¿ì¸®°¡ ¹æ±Ý htpasswd·Î ¸¸µç ¾ÏÈ£ÆÄÀÏÀÇ + °æ·Î¸¦ ¼³Á¤ÇÑ´Ù. »ç¿ëÀÚ°¡ ¸¹´Ù¸é ¿äû¸¶´Ù ¸Å¹ø »ç¿ëÀÚ¸¦ + ÀÎÁõÇϱâÀ§ÇØ ÀÏ¹Ý ¹®¼­ÆÄÀÏÀ» °Ë»öÇϴµ¥ ½Ã°£ÀÌ »ó´çÈ÷ ¸¹ÀÌ + °É¸± ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ºü¸¥ µ¥ÀÌŸº£À̽º ÆÄÀÏ¿¡ »ç¿ëÀÚ Á¤º¸¸¦ + ÀúÀåÇÒ ¼ö ÀÖ´Ù. mod_authn_dbm ¸ðµâÀº AuthDBMUserFile Áö½Ã¾î¸¦ + Á¦°øÇÑ´Ù. dbmmanage + ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé°í ´Ù·é´Ù. ¾ÆÆÄÄ¡ ¸ðµâ + µ¥ÀÌŸº£À̽º¿¡´Â ¿©·¯ ´Ù¸¥ ÀÎÁõ ¹æ½ÄÀ» Á¦°øÇÏ´Â Á¦»ïÀÚ°¡ + ¸¸µç ¸ðµâµéÀÌ ÀÖ´Ù.

    + +

    ¸¶Áö¸·À¸·Î Require + Áö½Ã¾î´Â ¼­¹öÀÇ Æ¯Á¤ ¿µ¿ª¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¸¦ ÁöÁ¤ÇÏ¿© + ±ÇÇѺο©¸¦ ÇÑ´Ù. ´ÙÀ½ ÀýÀº require Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â ´Ù¾çÇÑ ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    ¿©·¯¸íÀ» µé¿©º¸³»±â +

    À§ÀÇ Áö½Ã¾î´Â µð·ºÅ丮·Î (»ç¿ëÀÚ¸íÀÌ rbowenÀÎ) + ÇÑ »ç¶÷¸¸À» µé¿©º¸³½´Ù. ´ëºÎºÐÀÇ °æ¿ì ¿©·¯ »ç¶÷À» µé¿©º¸³»°í + ½ÍÀ» °ÍÀÌ´Ù. ÀÌÁ¦ AuthGroupFileÀ» + »ç¿ëÇÒ ¶§´Ù.

    + +

    ¿©·¯ »ç¶÷À» µé¿©º¸³»°í ½Í´Ù¸é ±×·ì¸í°ú ±× ±×·ì¿¡ ¾î¶² + »ç¿ëÀÚµéÀÌ ÀÖ´ÂÁö ¾Ë·ÁÁÖ´Â ±×·ìÆÄÀÏÀÌ ÇÊ¿äÇÏ´Ù. ÀÌ ÆÄÀÏÀÇ + Çü½ÄÀº ¸Å¿ì °£´ÜÇÏ¿©, ¾Æ¹« ÆíÁý±â·Î³ª ¸¸µé ¼ö ÀÖ´Ù. ÆÄÀϳ»¿ëÀº + ´ÙÀ½°ú °°´Ù.

    + + + GroupName: rbowen dpitts sungo rshersey + + +

    ±×³É °ø¹éÀ¸·Î ±¸ºÐÇÑ ±ä ±×·ì ±¸¼º¿ø ¸ñ·ÏÀÏ »ÓÀÌ´Ù.

    + +

    ±âÁ¸ÀÇ ¾ÏÈ£ÆÄÀÏ¿¡ »ç¿ëÀÚ¸¦ Ãß°¡ÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù

    + + + htpasswd /usr/local/apache/passwd/passwords dpitts + + +

    Àü°ú °°Áö¸¸, »õ·Î ÆÄÀÏÀ» ¸¸µéÁö ¾Ê°í ±âÁ¸ ÆÄÀÏ¿¡ »ç¿ëÀÚ¸¦ + Ãß°¡ÇÑ´Ù. (-c ¿É¼ÇÀº »õ·Î ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç´Ù).

    + +

    ÀÌÁ¦ .htaccess ÆÄÀÏÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.

    + + + AuthType Basic
    + AuthName "By Invitation Only"
    + AuthUserFile /usr/local/apache/passwd/passwords
    + AuthGroupFile /usr/local/apache/passwd/groups
    + Require group GroupName +
    + +

    ±×·¯¸é GroupName ±×·ì¿¡ ¼ÓÇϸç + password ÆÄÀÏ¿¡ Ç׸ñÀÌ ÀÖ´Â »ç¿ëÀÚ°¡ ¿Ã¹Ù¸¥ + ¾ÏÈ£¸¦ ÀÔ·ÂÇϸé Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    + +

    ¿©·¯ ÀÏ¹Ý »ç¿ëÀÚ¸¦ µé¿©º¸³»´Â ´Ù¸¥ ¹æ¹ýÀÌ ÀÖ´Ù. ±×·ìÆÄÀÏÀ» + ¸¸µé ÇÊ¿ä¾øÀÌ ´ÙÀ½ Áö½Ã¾î¸¦ »ç¿ëÇϱ⸸ ÇÏ¸é µÈ´Ù.

    + + + Require valid-user + + +

    Require user rbowen ´ë½Å ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇϸé + ¾ÏÈ£ÆÄÀÏ¿¡ ÀÖ´Â ´©±¸¶óµµ ¿Ã¹Ù¸¥ ¾ÏÈ£¸¦ ÀÔ·ÂÇϱ⸸ Çϸé Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±×·ìº°·Î ´Ù¸¥ ¾ÏÈ£ÆÄÀÏÀ» »ç¿ëÇÏ¿© ±×·ì°ú ºñ½ÁÇÑ + È¿°ú¸¦ ¾òÀ» ¼öµµ ÀÖ´Ù. ÀÌ °æ¿ì ¾ÆÆÄÄ¡°¡ ÆÄÀÏ µÎ°³(¾ÏÈ£ÆÄÀÏ°ú + ±×·ìÆÄÀÏ)°¡ ¾Æ´Ñ ÆÄÀÏ ÇÑ°³(¾ÏÈ£ÆÄÀÏ)¸¸ °Ë»çÇÏ¸é µÈ´Ù´Â °ÍÀÌ + ÀåÁ¡ÀÌ´Ù. ±×·¯³ª ¿©·¯ ¾ÏÈ£ÆÄÀÏÀ» °ü¸®ÇØ¾ß ÇÏ°í, AuthUserFile Áö½Ã¾î¿¡ + Á¤È®ÇÑ ¾ÏÈ£ÆÄÀÏÀ» ÁöÁ¤ÇØ¾ß ÇÏ´Â °ÍÀº ´ÜÁ¡ÀÌ´Ù.

    +
    + +
    ¹ß»ýÇÒ ¼ö ÀÖ´Â ¹®Á¦Á¡ +

    Basic ÀÎÁõ ¹æ½ÄÀº ¼­¹ö¿¡¼­ ¹®¼­¸¦ ¿äûÇÒ ¶§¸¶´Ù »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ È®ÀÎÇÑ´Ù. ½ÉÁö¾î °°Àº ÆäÀÌÁö¸¦ »õ·Î °íħÇÒ ¶§µµ ÆäÀÌÁö¿Í + (±×¸²ÀÌ ¾ÏÈ£·Î º¸È£ÇÏ´Â µð·ºÅ丮¿¡ ÀÖ´Â °æ¿ì) ÆäÀÌÁö¿¡ ÀÖ´Â + ¸ðµç ±×¸²¿¡ ´ëÇØ ´Ù½Ã È®ÀÎÇÑ´Ù. ÁüÀÛÇϵíÀÌ ¼Óµµ°¡ Á¶±Ý ´À·ÁÁø´Ù. + ¾ÏÈ£ÆÄÀÏÀ» ¿­¾î¼­ »ç¿ëÀÚ¸íÀ» ãÀ» ¶§±îÁö »ç¿ëÀÚ ¸ñ·ÏÀ» »ìÆìºÁ¾ß + Çϱ⶧¹®¿¡ ¾ÏÈ£ÆÄÀÏ Å©±â°¡ Ä¿Áú ¼ö·Ï ´õ ´À·ÁÁø´Ù. ±×¸®°í + ÀÌ ÀÛ¾÷À» ÆäÀÌÁö¸¦ ¿äûÇÒ ¶§¸¶´Ù ÁøÇàÇÑ´Ù.

    + +

    ±×·¡¼­ Çö½ÇÀûÀ¸·Î ÇÑ ¾ÏÈ£ÆÄÀÏ¿¡ ÀúÀåÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¼ö¿¡´Â + ÇÑ°è°¡ ÀÖ´Ù. ÀÌ ÇÑ°è´Â »ç¿ëÇÏ´Â ¼­¹öÀÇ ¼º´É¿¡ µû¶ó ´Ù¸£Áö¸¸, + Ç׸ñÀÌ ¼ö¹é°³°¡ ³Ñ´Â´Ù¸é ´À·ÁÁø´Ù°í »ý°¢ÇÏ°í ´Ù¸¥ ÀÎÁõ ¹æ¹ýÀ» + °í·ÁÇØ¾ß ÇÑ´Ù.

    +
    + +
    ´Ù¸¥ ¹æ¹ýµµ °¡´ÉÇÑ°¡? +

    »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ »ç¿ëÇÑ ÀÎÁõÀÌ ´Ù°¡ ¾Æ´Ï´Ù. Á¾Á¾ Á¢¼ÓÇÑ + Àå¼Ò¿Í °°Àº ´Ù¸¥ Á¤º¸¸¦ °¡Áö°í »ç¿ëÀÚ¸¦ µé¿©º¸³»°í ½ÍÀ» + ¶§°¡ ÀÖ´Ù.

    + +

    Allow¿Í + Deny Áö½Ã¾î´Â + ¹®¼­¸¦ ¿äûÇÑ ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸í ȤÀº È£½ºÆ® ÁÖ¼Ò¸¦ °¡Áö°í + Á¢±ÙÀ» Çã¿ëÇϰųª °ÅºÎÇÑ´Ù. Order Áö½Ã¾î´Â ÀÌ µÎ + Áö½Ã¾î¿Í °°ÀÌ »ç¿ëÇÏ¿©, ¾ÆÆÄÄ¡¿¡°Ô ¾î¶² ¼ø¼­·Î ±ÔÄ¢À» Àû¿ëÇÒÁö + ¾Ë¸°´Ù.

    + +

    À̵é Áö½Ã¾î »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.

    + + + Allow from address + + +

    ¿©±â¼­ address´Â IP ÁÖ¼Ò(ȤÀº IP ÁÖ¼Ò ÀϺÎ)³ª + ¿ÏÀüÇÑ µµ¸ÞÀθí(ȤÀº µµ¸ÞÀθí ÀϺÎ)ÀÌ´Ù. ¿øÇÑ´Ù¸é ¿©·¯ ÁÖ¼Ò³ª + µµ¸ÞÀθíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ´©±º°¡°¡ °Ô½ÃÆÇ¿¡ ±¤°í¸¦ ¿Ã¸®°í ÀÖ´Ù¸é ´ÙÀ½°ú + °°ÀÌ Á¢±ÙÀ» ¸·À» ¼ö ÀÖ´Ù.

    + + + Deny from 205.252.46.165 + + +

    ±× ÁÖ¼Ò¿¡¼­ µé¾î¿À´Â ¹æ¹®ÀÚ´Â ÀÌ Áö½Ã¾î°¡ º¸È£ÇÏ´Â ÆäÀÌÁö¸¦ + º¼ ¼ö ¾ø´Ù. IP ÁÖ¼Ò ´ë½Å ´ÙÀ½°ú °°ÀÌ ÄÄÇ»Å͸íÀ» »ç¿ëÇÒ ¼öµµ + ÀÖ´Ù.

    + + + Deny from host.example.com + + +

    ¶Ç, Àüü µµ¸ÞÀÎÀÇ Á¢±ÙÀ» ¸·À¸·Á¸é ÁÖ¼Ò³ª µµ¸ÞÀθíÀÇ ÀϺθ¦ + »ç¿ëÇÑ´Ù.

    + + + Deny from 192.101.205
    + Deny from cyberthugs.com moreidiots.com
    + Deny from ke +
    + +

    Order¸¦ + Deny¿Í Allow Áö½Ã¾î¿Í °°ÀÌ + »ç¿ëÇÏ¿© ½ÇÁ¦·Î ¿øÇÏ´Â ´ë»óÀ» ¸·À» ¼ö ÀÖ´Ù.

    + + + Order deny,allow
    + Deny from all
    + Allow from dev.example.com +
    + +

    Allow + Áö½Ã¾î¸¸ »ç¿ëÇϸé, ÇØ´ç È£½ºÆ®ÀÇ »ç¿ëÀÚ¸¦ Çã¿ëÇÏ°í °Å±â¿¡ + Ãß°¡·Î ¸ðµç »ç¶÷À» Çã¿ëÇϹǷΠ¿øÇÏ´Â °á°ú¸¦ ¾òÁö ¸øÇÑ´Ù. + ´ç½ÅÀº ƯÁ¤ »ç¶÷¸¸ Çã¿ëÇÏ±æ ¿øÇÑ´Ù.

    +
    + +
    ´õ ¸¹Àº Á¤º¸ +

    mod_auth_basic°ú + mod_authz_host ¹®¼­¿¡ Á¢±ÙÁ¦¾î°¡ µ¿ÀÛÇÏ´Â + ¹æ¹ý¿¡ ´ëÇÑ ´õ ¸¹Àº Á¤º¸°¡ ÀÖ´Ù.

    +
    + +
    + diff --git a/trunk/docs/manual/howto/auth.xml.meta b/trunk/docs/manual/howto/auth.xml.meta new file mode 100644 index 0000000000..7a87763842 --- /dev/null +++ b/trunk/docs/manual/howto/auth.xml.meta @@ -0,0 +1,13 @@ + + + + auth + /howto/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/howto/cgi.html b/trunk/docs/manual/howto/cgi.html new file mode 100644 index 0000000000..8d3dbcba19 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.html @@ -0,0 +1,11 @@ +URI: cgi.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: cgi.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: cgi.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/howto/cgi.html.en b/trunk/docs/manual/howto/cgi.html.en new file mode 100644 index 0000000000..fdc7c2aa09 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.html.en @@ -0,0 +1,555 @@ + + + +Apache Tutorial: Dynamic Content with CGI - Apache HTTP Server + + + + + +
    <-
    +

    Apache Tutorial: Dynamic Content with CGI

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    + +
    top
    +
    +

    Introduction

    + + + + +

    The CGI (Common Gateway Interface) defines a way for a web + server to interact with external content-generating programs, + which are often referred to as CGI programs or CGI scripts. It + is the simplest, and most common, way to put dynamic content on + your web site. This document will be an introduction to setting + up CGI on your Apache web server, and getting started writing + CGI programs.

    +
    top
    +
    +

    Configuring Apache to permit CGI

    + + +

    In order to get your CGI programs to work properly, you'll + need to have Apache configured to permit CGI execution. There + are several ways to do this.

    + +

    ScriptAlias

    + + +

    The + ScriptAlias + + directive tells Apache that a particular directory is set + aside for CGI programs. Apache will assume that every file in + this directory is a CGI program, and will attempt to execute + it, when that particular resource is requested by a + client.

    + +

    The ScriptAlias + directive looks like:

    + +

    + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ +

    + +

    The example shown is from your default httpd.conf + configuration file, if you installed Apache in the default + location. The ScriptAlias + directive is much like the Alias directive, which defines a URL prefix that + is to mapped to a particular directory. Alias + and ScriptAlias are usually used for + directories that are outside of the DocumentRoot directory. The difference between + Alias and ScriptAlias + is that ScriptAlias has the added meaning + that everything under that URL prefix will be considered a CGI + program. So, the example above tells Apache that any request for a + resource beginning with /cgi-bin/ should be served from + the directory /usr/local/apache2/cgi-bin/, and should be + treated as a CGI program.

    + +

    For example, if the URL + http://www.example.com/cgi-bin/test.pl + is requested, Apache will attempt to execute the file + /usr/local/apache2/cgi-bin/test.pl + and return the output. Of course, the file will have to + exist, and be executable, and return output in a particular + way, or Apache will return an error message.

    + + +

    CGI outside of ScriptAlias directories

    + + +

    CGI programs are often restricted to ScriptAlias'ed directories for security reasons. + In this way, administrators can tightly control who is allowed to + use CGI programs. However, if the proper security precautions are + taken, there is no reason why CGI programs cannot be run from + arbitrary directories. For example, you may wish to let users + have web content in their home directories with the + UserDir directive. + If they want to have their own CGI programs, but don't have access to + the main cgi-bin directory, they will need to be able to + run CGI programs elsewhere.

    + +

    There are two steps to allowing CGI execution in an arbitrary + directory. First, the cgi-script handler must be + activated using the AddHandler or SetHandler directive. Second, + ExecCGI must be specified in the Options directive.

    + + +

    Explicitly using Options to permit CGI execution

    + + +

    You could explicitly use the Options directive, inside your main server configuration + file, to specify that CGI execution was permitted in a particular + directory:

    + +

    + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +

    + +

    The above directive tells Apache to permit the execution + of CGI files. You will also need to tell the server what + files are CGI files. The following AddHandler directive tells the server to treat all + files with the cgi or pl extension as CGI + programs:

    + +

    + AddHandler cgi-script .cgi .pl +

    + + +

    .htaccess files

    + + +

    The .htaccess tutorial + shows how to activate CGI programs if you do not have + access to httpd.conf.

    + + +

    User Directories

    + + +

    To allow CGI program execution for any file ending in + .cgi in users' directories, you can use the + following configuration.

    + +

    + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +

    + +

    If you wish designate a cgi-bin subdirectory of + a user's directory where everything will be treated as a CGI + program, you can use the following.

    + +

    + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +

    + + + +
    top
    +
    +

    Writing a CGI program

    + + +

    There are two main differences between ``regular'' + programming, and CGI programming.

    + +

    First, all output from your CGI program must be preceded by + a MIME-type header. This is HTTP header that tells the client + what sort of content it is receiving. Most of the time, this + will look like:

    + +

    + Content-type: text/html +

    + +

    Secondly, your output needs to be in HTML, or some other + format that a browser will be able to display. Most of the + time, this will be HTML, but occasionally you might write a CGI + program that outputs a gif image, or other non-HTML + content.

    + +

    Apart from those two things, writing a CGI program will look + a lot like any other program that you might write.

    + +

    Your first CGI program

    + + +

    The following is an example CGI program that prints one + line to your browser. Type in the following, save it to a + file called first.pl, and put it in your + cgi-bin directory.

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +

    + +

    Even if you are not familiar with Perl, you should be able + to see what is happening here. The first line tells Apache + (or whatever shell you happen to be running under) that this + program can be executed by feeding the file to the + interpreter found at the location /usr/bin/perl. + The second line prints the content-type declaration we + talked about, followed by two carriage-return newline pairs. + This puts a blank line after the header, to indicate the end + of the HTTP headers, and the beginning of the body. The third + line prints the string "Hello, World.". And that's the end + of it.

    + +

    If you open your favorite browser and tell it to get the + address

    + +

    + http://www.example.com/cgi-bin/first.pl +

    + +

    or wherever you put your file, you will see the one line + Hello, World. appear in your browser window. + It's not very exciting, but once you get that working, you'll + have a good chance of getting just about anything working.

    + +
    top
    +
    +

    But it's still not working!

    + + +

    There are four basic things that you may see in your browser + when you try to access your CGI program from the web:

    + +
    +
    The output of your CGI program
    +
    Great! That means everything worked fine. If the output is correct, + but the browser is not processing it correctly, make sure you have the + correct Content-Type set in your CGI program.
    + +
    The source code of your CGI program or a "POST Method Not + Allowed" message
    +
    That means that you have not properly configured Apache + to process your CGI program. Reread the section on + configuring + Apache and try to find what you missed.
    + +
    A message starting with "Forbidden"
    +
    That means that there is a permissions problem. Check the + Apache error log and the section below on + file permissions.
    + +
    A message saying "Internal Server Error"
    +
    If you check the + Apache error log, you will probably + find that it says "Premature end of + script headers", possibly along with an error message + generated by your CGI program. In this case, you will want to + check each of the below sections to see what might be + preventing your CGI program from emitting the proper HTTP + headers.
    +
    + +

    File permissions

    + + +

    Remember that the server does not run as you. That is, + when the server starts up, it is running with the permissions + of an unprivileged user - usually nobody, or + www - and so it will need extra permissions to + execute files that are owned by you. Usually, the way to give + a file sufficient permissions to be executed by nobody + is to give everyone execute permission on the file:

    + +

    + chmod a+x first.pl +

    + +

    Also, if your program reads from, or writes to, any other + files, those files will need to have the correct permissions + to permit this.

    + + + +

    Path information and environment

    + + +

    When you run a program from your command line, you have + certain information that is passed to the shell without you + thinking about it. For example, you have a PATH, + which tells the shell where it can look for files that you + reference.

    + +

    When a program runs through the web server as a CGI program, + it may not have the same PATH. Any programs that you + invoke in your CGI program (like sendmail, for + example) will need to be specified by a full path, so that the + shell can find them when it attempts to execute your CGI + program.

    + +

    A common manifestation of this is the path to the script + interpreter (often perl) indicated in the first + line of your CGI program, which will look something like:

    + +

    + #!/usr/bin/perl +

    + +

    Make sure that this is in fact the path to the + interpreter.

    + +

    In addition, if your CGI program depends on other environment variables, you will need to + assure that those variables are passed by Apache.

    + + + +

    Program errors

    + + +

    Most of the time when a CGI program fails, it's because of + a problem with the program itself. This is particularly true + once you get the hang of this CGI stuff, and no longer make + the above two mistakes. The first thing to do is to make + sure that your program runs from the command line before + testing it via the web server. For example, try:

    + +

    + cd /usr/local/apache2/cgi-bin
    + ./first.pl +

    + +

    (Do not call the perl interpreter. The shell + and Apache should find the interpreter using the path information on the first line of + the script.)

    + +

    The first thing you see written by your program should be + a set of HTTP headers, including the Content-Type, + followed by a blank line. If you see anything else, Apache will + return the Premature end of script headers error if + you try to run it through the server. See Writing a CGI program above for more + details.

    + + +

    Error logs

    + + +

    The error logs are your friend. Anything that goes wrong + generates message in the error log. You should always look + there first. If the place where you are hosting your web site + does not permit you access to the error log, you should + probably host your site somewhere else. Learn to read the + error logs, and you'll find that almost all of your problems + are quickly identified, and quickly solved.

    + + +

    Suexec

    + + +

    The suexec support program + allows CGI programs to be run under different user permissions, + depending on which virtual host or user home directory they are + located in. Suexec has very strict permission checking, and any + failure in that checking will result in your CGI programs + failing with Premature end of script headers.

    + +

    To check if you are using suexec, run apachectl + -V and check for the location of SUEXEC_BIN. + If Apache finds an suexec binary there on startup, + suexec will be activated.

    + +

    Unless you fully understand suexec, you should not be using it. + To disable suexec, simply remove (or rename) the suexec + binary pointed to by SUEXEC_BIN and then restart the + server. If, after reading about suexec, + you still wish to use it, then run suexec -V to find + the location of the suexec log file, and use that log file to + find what policy you are violating.

    + +
    top
    +
    +

    What's going on behind the scenes?

    + + +

    As you become more advanced in CGI programming, it will + become useful to understand more about what's happening behind + the scenes. Specifically, how the browser and server + communicate with one another. Because although it's all very + well to write a program that prints "Hello, World.", it's not + particularly useful.

    + +

    Environment variables

    + + +

    Environment variables are values that float around you as + you use your computer. They are useful things like your path + (where the computer searches for the actual file + implementing a command when you type it), your username, your + terminal type, and so on. For a full list of your normal, + every day environment variables, type + env at a command prompt.

    + +

    During the CGI transaction, the server and the browser + also set environment variables, so that they can communicate + with one another. These are things like the browser type + (Netscape, IE, Lynx), the server type (Apache, IIS, WebSite), + the name of the CGI program that is being run, and so on.

    + +

    These variables are available to the CGI programmer, and + are half of the story of the client-server communication. The + complete list of required variables is at + http://hoohoo.ncsa.uiuc.edu/cgi/env.html.

    + +

    This simple Perl CGI program will display all of the + environment variables that are being passed around. Two + similar programs are included in the + cgi-bin + + directory of the Apache distribution. Note that some + variables are required, while others are optional, so you may + see some variables listed that were not in the official list. + In addition, Apache provides many different ways for you to + add your own environment variables + to the basic ones provided by default.

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +

    + + +

    STDIN and STDOUT

    + + +

    Other communication between the server and the client + happens over standard input (STDIN) and standard + output (STDOUT). In normal everyday context, + STDIN means the keyboard, or a file that a + program is given to act on, and STDOUT + usually means the console or screen.

    + +

    When you POST a web form to a CGI program, + the data in that form is bundled up into a special format + and gets delivered to your CGI program over STDIN. + The program then can process that data as though it was + coming in from the keyboard, or from a file

    + +

    The "special format" is very simple. A field name and + its value are joined together with an equals (=) sign, and + pairs of values are joined together with an ampersand + (&). Inconvenient characters like spaces, ampersands, and + equals signs, are converted into their hex equivalent so that + they don't gum up the works. The whole data string might look + something like:

    + +

    + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey +

    + +

    You'll sometimes also see this type of string appended to + a URL. When that is done, the server puts that string + into the environment variable called + QUERY_STRING. That's called a GET + request. Your HTML form specifies whether a GET + or a POST is used to deliver the data, by setting the + METHOD attribute in the FORM tag.

    + +

    Your program is then responsible for splitting that string + up into useful information. Fortunately, there are libraries + and modules available to help you process this data, as well + as handle other of the aspects of your CGI program.

    + +
    top
    +
    +

    CGI modules/libraries

    + + +

    When you write CGI programs, you should consider using a + code library, or module, to do most of the grunt work for you. + This leads to fewer errors, and faster development.

    + +

    If you're writing CGI programs in Perl, modules are + available on CPAN. The most + popular module for this purpose is CGI.pm. You might + also consider CGI::Lite, which implements a minimal + set of functionality, which is all you need in most programs.

    + +

    If you're writing CGI programs in C, there are a variety of + options. One of these is the CGIC library, from + http://www.boutell.com/cgic/.

    +
    top
    +
    +

    For more information

    + + +

    There are a large number of CGI resources on the web. You + can discuss CGI problems with other users on the Usenet group + comp.infosystems.www.authoring.cgi. And the -servers mailing + list from the HTML Writers Guild is a great source of answers + to your questions. You can find out more at + http://www.hwg.org/lists/hwg-servers/.

    + +

    And, of course, you should probably read the CGI + specification, which has all the details on the operation of + CGI programs. You can find the original version at the + NCSA and there is an updated draft at the + Common Gateway + Interface RFC project.

    + +

    When you post a question about a CGI problem that you're + having, whether to a mailing list, or to a newsgroup, make sure + you provide enough information about what happened, what you + expected to happen, and how what actually happened was + different, what server you're running, what language your CGI + program was in, and, if possible, the offending code. This will + make finding your problem much simpler.

    + +

    Note that questions about CGI problems should never + be posted to the Apache bug database unless you are sure you + have found a problem in the Apache source code.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/cgi.html.ja.euc-jp b/trunk/docs/manual/howto/cgi.html.ja.euc-jp new file mode 100644 index 0000000000..71132e2ef4 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.html.ja.euc-jp @@ -0,0 +1,544 @@ + + + +Apache Tutorial: CGI ¤Ë¤è¤ëưŪ¥³¥ó¥Æ¥ó¥Ä - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache Tutorial: CGI ¤Ë¤è¤ëưŪ¥³¥ó¥Æ¥ó¥Ä

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    + +
    top
    +
    +

    ¤Ï¤¸¤á¤Ë

    + + + + +

    CGI (Common Gateway Interface) ¤Ï¡¢¥¦¥§¥Ö¥µ¡¼¥Ð¤¬ + ¥³¥ó¥Æ¥ó¥ÄÀ¸À®¤ò¤¹¤ë³°Éô¥×¥í¥°¥é¥à¤È¶¨Ä´¤·¤ÆÆ°ºî¤¹¤ë¤¿¤á¤ÎÊýË¡¤ò + ÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£¤½¤Î¥×¥í¥°¥é¥à¤Ï¤·¤Ð¤·¤Ð CGI ¥×¥í¥°¥é¥à¤ä + CGI ¥¹¥¯¥ê¥×¥È¤È¸Æ¤Ð¤ì¤Þ¤¹¡£CGI ¤Ï¡¢¥¦¥§¥Ö¥µ¥¤¥È¤ËưŪ¤Ê + ¥³¥ó¥Æ¥ó¥Ä¤òÃÖ¤¯¤¿¤á¤ÎºÇ¤â´Êñ¤Ç°ìÈÌŪ¤ÊÊýË¡¤Ç¤¹¡£¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ï¡¢ + Apache ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ç CGI ¤òÀßÄꤷ¡¢ + CGI ¥×¥í¥°¥é¥à¤ò½ñ¤­»Ï¤á¤ë¤¿¤á¤ÎÆþÌç½ñ¤È¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    CGI ¤òµö²Ä¤¹¤ë¤è¤¦¤Ë Apache ¤òÀßÄꤹ¤ë

    + + +

    CGI ¥×¥í¥°¥é¥à¤òÀµ¤·¤¯Æ°ºî¤µ¤»¤ë¤Ë¤Ï¡¢CGI ¤òµö²Ä¤¹¤ë¤è¤¦¤Ë + Apache ¤ÎÀßÄê¤ò¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤ò¹Ô¤Ê¤¦¤¿¤á¤ÎÊýË¡¤¬¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡£

    + +

    ScriptAlias

    + + +

    ScriptAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ + CGI ¥×¥í¥°¥é¥àÍѤÎÆÃÊ̤ÊÊ̥ǥ£¥ì¥¯¥È¥ê¤ò Apache ¤ËÀßÄꤷ¤Þ¤¹¡£ + Apache ¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥È¥êÃæ¤ÎÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò CGI + ¥×¥í¥°¥é¥à¤Ç¤¢¤ë¤È²¾Äꤷ¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¤³¤ÎÆÃÊ̤ʥ꥽¡¼¥¹¤¬¥¯¥é¥¤¥¢¥ó¥È¤«¤éÍ׵ᤵ¤ì¤ë¤È¡¢ + ¤½¤Î¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤ò»î¤ß¤Þ¤¹¡£

    + +

    ScriptAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï°Ê²¼¤Î¤è¤¦¤Ë»ÈÍѤ·¤Þ¤¹:

    + +

    + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ +

    + +

    ¥Ç¥Õ¥©¥ë¥È°ÌÃÖ¤Ë Apache ¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤¿¤Ê¤é¤Ð¡¢ + ¤³¤ÎÎã¤Ï¥Ç¥Õ¥©¥ë¥È¾õÂ֤Πhttpd.conf + ÀßÄê¥Õ¥¡¥¤¥ë¤Ë´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ + ScriptAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢URL ¤ÎÁ°¤ËÉղ乤ë¥Ç¥£¥ì¥¯¥È¥ê¤òÄêµÁ¤¹¤ë + Alias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤«¤Ê¤ê»÷¤Æ¤¤¤Þ¤¹¡£ + Alias ¤È ScriptAlias + ¤ÏÄ̾DocumentRoot + ¥Ç¥£¥ì¥¯¥È¥ê³°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£ + Alias ¤È ScriptAlias + ¤È¤Îº¹¤Ï¡¢ScriptAlias ¤¬ÀÜƬ¼­¤Ç»Ï¤Þ¤ë¤¹¤Ù¤Æ¤Î + URL ¤Ï CGI ¥×¥í¥°¥é¥à¤È¤ß¤Ê¤µ¤ì¤ë¤È¤¤¤¦ÄɲäΰÕÌ£¤ò´Þ¤ó¤Ç¤¤¤ë¤³¤È¤Ç¤¹¡£ + ½¾¤Ã¤Æ¡¢¾åµ­¤ÎÎã¤Ç¤Ï¡¢/cgi-bin/ + ¤Ç»Ï¤Þ¤ë¥ê¥½¡¼¥¹¤Ø¤Î¤¢¤é¤æ¤ë¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¡¢¥Ç¥£¥ì¥¯¥È¥ê + /usr/local/apache2/cgi-bin/ ¤«¤éÄ󶡤·¡¢¤½¤ì¤é¤ò + CGI ¥×¥í¥°¥é¥à¤È¤·¤Æ°·¤¦¤è¤¦ Apache ¤Ë¼¨¤·¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢URL http://dev.rcbowen.com/cgi-bin/test.pl + ¤¬Í׵ᤵ¤ì¤¿¾ì¹ç¡¢Apache ¤Ï ¥Õ¥¡¥¤¥ë + /usr/local/apache2/cgi-bin/test.pl + ¤ò¼Â¹Ô¤·¡¢¤½¤Î½ÐÎϤòÊÖ¤¹¤³¤È¤ò»î¤ß¤Þ¤¹¡£ + ¤â¤Á¤í¤ó¡¢¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¡¢¼Â¹Ô²Äǽ¤Ç¤¢¤ê¡¢·è¤á¤é¤ì¤¿ÊýË¡¤Ç½ÐÎϤòÊÖ¤·¤Þ¤¹¡£ + ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢Apache ¤Ï¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤òÊÖ¤·¤Þ¤¹¡£

    + + +

    ScriptAlias ¥Ç¥£¥ì¥¯¥È¥ê³°¤Î CGI

    + + +

    CGI ¥×¥í¥°¥é¥à¤Ï¡¢¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤«¤é + ScriptAlias + ¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤ËÀ©¸Â¤µ¤ì¤ë¤³¤È¤¬¤·¤Ð¤·¤Ð¤¢¤ê¤Þ¤¹¡£¤³¤ÎÊýË¡¤Ë¤è¤ê¡¢ + CGI ¥×¥í¥°¥é¥à¤ò»ÈÍѤǤ­¤ë¥æ¡¼¥¶¤ò´ÉÍý¼Ô¤¬¸·¤·¤¯À©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢Å¬Àڤʥ»¥­¥å¥ê¥Æ¥£»öÁ°Âкö¤¬¤È¤é¤ì¤ë¤Ê¤é¤Ð¡¢CGI + ¥×¥í¥°¥é¥à¤òǤ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¼Â¹Ô¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¤¹¤ëÍýͳ¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢¥æ¡¼¥¶¤Ë UserDir + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÈà¤é¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥êÇÛ²¼¤Ë¥¦¥§¥Ö¥³¥ó¥Æ¥ó¥Ä¤ò»ý¤¿¤»¤¿¤¤¤È¤·¤Þ¤¹¡£ + ¤â¤·¡¢Èà¤é¤¬ CGI ¥×¥í¥°¥é¥à¤ò»ý¤Ä¤³¤È¤ò˾¤ó¤Ç¤¤¤Æ¤â¡¢¥á¥¤¥ó¤Î + cgi-bin ¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤¬¤Ç¤­¤Ê¤¤¾ì¹ç¡¢ + CGI ¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¾¤Î¾ì½ê¤¬É¬Íפˤʤê¤Þ¤¹¡£

    + +

    Ǥ°Õ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç CGI ¤Î¼Â¹Ô¤òµö²Ä¤¹¤ë¤Ë¤ÏÆóÃʳ¬¤ÎÀßÄ꤬ɬÍפǤ¹¡£ + ¤Þ¤º¡¢AddHandler ¤ä SetHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ + cgi-script ¥Ï¥ó¥É¥é¤¬²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¼¡¤Ë¡¢Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + ExecCGI ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + + +

    CGI ¤Î¼Â¹Ô¤ò²Äǽ¤Ë¤¹¤ë¤¿¤á¤Ë Options ¤òÌÀ¼¨Åª¤Ë»ÈÍѤ¹¤ë

    + + +

    ¥µ¡¼¥Ð¤Î¥á¥¤¥ó¤ÎÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ç Options + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÌÀ¼¨Åª¤Ë»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥êÇÛ²¼¤Ç + CGI ¤Î¼Â¹Ô¤òµö²Ä¤¹¤ë¤è¤¦¤Ë»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +

    + +

    ¾åµ­¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢CGI ¥Õ¥¡¥¤¥ë¤Î¼Â¹Ô¤ò²Äǽ¤Ë¤¹¤ë¤è¤¦ + Apache ¤ËÅÁ¤¨¤Þ¤¹¡£¤Þ¤¿¡¢¤É¤Î¥Õ¥¡¥¤¥ë¤¬ CGI ¥Õ¥¡¥¤¥ë¤«¤ò + ¥µ¡¼¥Ð¤ËÅÁ¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¼¡¤Î + AddHandler + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÎã¤Ç¤Ï¡¢cgi ¤Þ¤¿¤Ï pl + ¤ò³ÈÄ¥»Ò¤Ë»ý¤Ä¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò CGI + ¥×¥í¥°¥é¥à¤È¤·¤Æ¤ß¤Ê¤¹¤³¤È¤ò¥µ¡¼¥Ð¤ËÅÁ¤¨¤Þ¤¹:

    + +

    + AddHandler cgi-script .cgi .pl +

    + + +

    .htaccess files

    + + +

    .htaccess ¥Á¥å¡¼¥È¥ê¥¢¥ë + ¤Ï httpd.conf ¤òÊѹ¹¤Ç¤­¤Ê¤¤¾ì¹ç¤Ë¤É¤¦¤ä¤Ã¤Æ CGI ¥×¥í¥°¥é¥à¤ò + »È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤«¤òÀâÌÀ¤·¤Æ¤¤¤Þ¤¹¡£

    + + +

    User ¥Ç¥£¥ì¥¯¥È¥ê

    + + +

    .cgi ¤Ç½ª¤ï¤ë¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ CGI ¥×¥í¥°¥é¥à¤Î + ¼Â¹Ô¤òµö²Ä¤¹¤ë¤Ë¤Ï¡¢°Ê²¼¤ÎÀßÄê¤ò»ÈÍѤǤ­¤Þ¤¹¡£

    + +

    + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +

    + +

    ¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê¤Î cgi-bin ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î + ¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò CGI ¥×¥í¥°¥é¥à¤È¤·¤Æ»ØÄꤷ¤¿¤¤¾ì¹ç¤Ë¤Ï + °Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤ò»È¤¤¤Þ¤¹¡£

    + +

    + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +

    + + +
    top
    +
    +

    CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¯

    + + +

    ¡ÖÄ̾ï¤Î¡×¥×¥í¥°¥é¥ß¥ó¥°¤È CGI + ¥×¥í¥°¥é¥ß¥ó¥°¤Î´Ö¤Ë¤Ï¼ç¤ËÆó¤Ä¤Î°ã¤¤¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    °ì¤Ä¤Ï¡¢CGI ¥×¥í¥°¥é¥à¤Î¤¹¤Ù¤Æ¤Î½ÐÎÏ¤Ë¤Ï MIME-type + ¥Ø¥Ã¥À¤òÉÕ¤±¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤ì¤Ï¤É¤Î¤è¤¦¤Ê¼ïÎà¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¼õ¤±¼è¤Ã¤Æ¤¤¤ë¤«¤ò¥¯¥é¥¤¥¢¥ó¥È¤Ë¼¨¤¹ + HTTP ¥Ø¥Ã¥À¤Ç¤¹¡£¤Û¤È¤ó¤É¤Î¾ì¹ç¤Ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë½ÐÎϤ·¤Þ¤¹:

    + +

    + Content-type: text/html +

    + +

    ¤â¤¦°ì¤Ä¤Ï¡¢½ÐÎϤò HTML + ¤«¡¢¥Ö¥é¥¦¥¶¤¬É½¼¨¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë²¿¤«Â¾¤Î·Á¼°¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ÂçÄñ¤Î¾ì¹ç¤Ï HTML ¤Ç¤·¤ç¤¦¤¬¡¢GIF ¥¤¥á¡¼¥¸¤ä¾¤ÎÈó HTML + ¥³¥ó¥Æ¥ó¥Ä¤ò½ÐÎϤ¹¤ë CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¯¤³¤È¤â¤¢¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ¤³¤ì¤éÆóÅÀ°Ê³°¤Ç¤Ï¡¢CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¯¤³¤È¤Ï¡¢ + ¤¢¤Ê¤¿¤¬½ñ¤¤¤Æ¤¤¤ë¾¤Î¥×¥í¥°¥é¥à¤È¤è¤¯»÷¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ºÇ½é¤Î CGI ¥×¥í¥°¥é¥à

    + + +

    ¼¡¤Ë¼¨¤¹¤Î¤Ï¡¢¥Ö¥é¥¦¥¶¤Ë 1 ¹Ô°õ»ú¤¹¤ë CGI + ¥×¥í¥°¥é¥à¤ÎÎã¤Ç¤¹¡£°Ê²¼¤òÆþÎϤ·¡¢first.pl + ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¡¢¤½¤ì¤ò cgi-bin + ¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤¤¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +

    + +

    Perl ¤ËÀºÄ̤·¤Æ¤¤¤Ê¤¯¤Æ¤â¡¢ + ²¿¤¬µ¯¤³¤ë¤«¤òÍý²ò¤¹¤ë¤³¤È¤Ï¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£1 ¹ÔÌܤϡ¢ + /usr/bin/perl ¤Ç¸«¤Ä¤±¤é¤ì¤ë¥¤¥ó¥¿¥×¥ê¥¿¤Ë + ¤³¤Î¥Õ¥¡¥¤¥ë¤ò¶¡µë¤¹¤ë¤³¤È¤Ç¤³¤Î¥×¥í¥°¥é¥à¤¬¼Â¹Ô¤µ¤ì¤ë¤³¤È¤ò + Apache ¤Ë (¥·¥§¥ë¾å¤Ç¼Â¹Ô¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤Ê¤é¤Ð¡¢¤½¤Î¥·¥§¥ë¤Ë ) + ¼¨¤·¤Þ¤¹¡£2 ¹ÔÌܤϡ¢Á°½Ò¤·¤¿¤È¤ª¤ê content-type ¤ÎÄêµÁ¤ò°õ»ú¤·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤ÏÉüµ¢²þ¹Ô¤ÎÆó¤Ä¤ÎÁȤò¸å¤ËÉղä·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥Ø¥Ã¥À¤Î½ª¤ê¤Ë¶õ¹Ô¤¬ÃÖ¤«¤ì¡¢HTTP + ¥Ø¥Ã¥À¤Î½ª¤ê¤È¥Ü¥Ç¥£¤Î»Ï¤Þ¤ê¤ò¼¨¤·¤Þ¤¹¡£3 ¹ÔÌܤϡ¢"Hello, World." + ¤È¤¤¤¦Ê¸»úÎó¤ò°õ»ú¤·¡¢¤³¤ì¤Ç½ª¤ê¤È¤Ê¤ê¤Þ¤¹¡£

    + +

    ¹¥¤ß¤Î¥Ö¥é¥¦¥¶¤ò³«¤­¡¢¥¢¥É¥ì¥¹

    + +

    + http://www.example.com/cgi-bin/first.pl +

    + +

    ¤¢¤ë¤¤¤Ï¥Õ¥¡¥¤¥ë¤òÃÖ¤¤¤¿¥í¥±¡¼¥·¥ç¥ó¤ò»ØÄꤹ¤ë¤È¡¢ + Hello, World. + ¤È¤¤¤¦ 1 ¹Ô¤¬¥Ö¥é¥¦¥¶¥¦¥£¥ó¥É¤Ë¸½¤ì¤ë¤Ç¤·¤ç¤¦¡£ + ¤½¤ì¤Ï¤¢¤Þ¤ê¥¨¥­¥µ¥¤¥Æ¥£¥ó¥°¤Ê¤³¤È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢¤³¤ì¤¬¤¦¤Þ¤¯Æ°¤±¤Ð¡¢ + ¾¤Î¤É¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤âÆ°¤«¤¹¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    top
    +
    +

    ¤·¤«¤·¡¢¤Þ¤ÀÆ°¤«¤Ê¤¤ !

    + + +

    ¥¦¥§¥Ö¤«¤é CGI ¥×¥í¥°¥é¥à¤Ø¤Î¥¢¥¯¥»¥¹¤ò¹Ô¤Ê¤Ã¤¿¤È¤­¡¢ + ¥Ö¥é¥¦¥¶¤Ç¸«¤ë²ÄǽÀ­¤¬¤¢¤ë»Í¤Ä¤Î´ðËÜŪ¤Ê¤³¤È¤¬¤¢¤ê¤Þ¤¹:

    + +
    +
    CGI ¥×¥í¥°¥é¥à¤Î½ÐÎÏ
    +
    ÁÇÀ²¤é¤·¤¤ ! ¤½¤ì¤Ï¤¹¤Ù¤Æ¤¬¤¦¤Þ¤¯Æ°¤¤¤¿¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + ½ÐÎϤ¬Àµ¾ï¤À¤±¤ì¤É¤â¡¢¥Ö¥é¥¦¥¶¤¬Àµ¾ï¤Ë½èÍý¤·¤Æ¤¯¤ì¤Ê¤¤¾ì¹ç¤Ï¡¢ + Àµ¤·¤¤ Content-Type ¤ò CGI ¥×¥í¥°¥é¥àÆâ¤Ç + ¥»¥Ã¥È¤·¤¿¤«¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
    + +
    CGI ¥×¥í¥°¥é¥à¤Î¥½¡¼¥¹¥³¡¼¥É¡¢¤Þ¤¿¤Ï "POST Method Not Allowed" + ¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸
    +
    ¤³¤ì¤Ï¡¢CGI ¥×¥í¥°¥é¥à¤ò½èÍý¤Ç¤­¤ë¤è¤¦ Apache + ¤òŬÀÚ¤ËÀßÄꤷ¤Æ¤¤¤Ê¤«¤Ã¤¿¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£¡ÖCGI ¤òµö²Ä¤¹¤ë¤è¤¦¤Ë + Apache ¤òÀßÄꤹ¤ë¡×¤Î¾Ï¤òÆɤßľ¤·¡¢ + ¤¢¤Ê¤¿¤¬²¿¤ò´Ö°ã¤¨¤¿¤«¤òõ¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£ +
    + +
    ¥á¥Ã¥»¡¼¥¸¤¬ "Forbidden" ¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤ë
    +
    ¤³¤ì¤Ï¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ÎÌäÂê¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + Apache ¤Î¥¨¥é¡¼¥í¥°¤È¡¢¸å½Ò¤Î¡Ö¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¡× + ¤Î¾Ï¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    + +
    "Internal Server Error" ¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸
    +
    Apache + ¤Î¥¨¥é¡¼¥í¥°¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤È¡¢"Premature end of script headers" + ¤È¤¤¤¦¥í¥°¤¬µ­Ï¿¤µ¤ì¤Æ¤¤¤ë¤È»×¤¤¤Þ¤¹¡£¤½¤·¤Æ¡¢¤ª¤½¤é¤¯ CGI + ¥×¥í¥°¥é¥à¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤¿¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤âµ­Ï¿¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¾ì¹ç¡¢CGI ¥×¥í¥°¥é¥à¤¬Å¬ÀÚ¤Ê + HTTP ¥Ø¥Ã¥À¤ò½ÐÎϤǤ­¤Ê¤¤¸¶°ø¤òÃΤ뤿¤á¤Ë¡¢ + °Ê²¼¤Î³Æ¾Ï¤Ç¥Á¥§¥Ã¥¯¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
    +
    + +

    ¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó

    + + +

    ¥µ¡¼¥Ð¤Ï¤¢¤Ê¤¿¤Î¸¢¸Â¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ò˺¤ì¤Ê¤¤¤è¤¦¤Ë¡£ + ¤Ä¤Þ¤ê¡¢µ¯Æ°¤¹¤ë¤È¤­¡¢¥µ¡¼¥Ð¤ÏÆø¢¤ò¤â¤¿¤Ê¤¤¥æ¡¼¥¶ - Ä̾ï nobody + ¤ä www ¤Î¸¢¸Â¤Ç¼Â¹Ô¤µ¤ì¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢¤¢¤Ê¤¿¤¬½êÍ­¤¹¤ë + ¥Õ¥¡¥¤¥ë¤ò¼Â¹Ô¤¹¤ë¤Ë¤ÏÊ̤Υѡ¼¥ß¥Ã¥·¥ç¥ó¤¬É¬ÍפȤʤê¤Þ¤¹¡£ + Ä̾nobody ¤¬¼Â¹Ô¤¹¤ë¤Î¤Ë½½Ê¬¤Ê¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÍ¿¤¨¤ëÊýË¡¤Ï¡¢ + ¥Õ¥¡¥¤¥ë¤Ëï¤Ç¤â¼Â¹Ô²Äǽ¤È¤¹¤ë¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÍ¿¤¨¤ë¤³¤È¤Ç¤¹:

    + +

    + chmod a+x first.pl +

    + +

    ¤Þ¤¿¡¢¤â¤·¤¢¤Ê¤¿¤Î¥×¥í¥°¥é¥à¤¬Â¾¤Î¥Õ¥¡¥¤¥ë¤òÆɤ߽ñ¤­¤¹¤ë¤Ê¤é¤Ð¡¢ + ¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤Ï¡¢¤³¤ì¤¬²Äǽ¤È¤Ê¤ëÀµ¤·¤¤¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó + ¤ò»ý¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + + + +

    ¥Ñ¥¹¾ðÊó¤È´Ä¶­

    + + +

    ¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ë¤È¤­¡¢ + °Õ¼±¤·¤Ê¤¯¤Æ¤â¥·¥§¥ë¤ËÅϤµ¤ì¤ë¾ðÊ󤬤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢»²¾È¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¤¿¤á¤Ë¤É¤³¤ò¸¡º÷¤·¤¿¤é¤è¤¤¤«¤ò + ¥·¥§¥ë¤ËÅÁ¤¨¤ë PATH ¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥×¥í¥°¥é¥à¤¬ CGI ¥×¥í¥°¥é¥à¤È¤·¤Æ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¤è¤Ã¤Æ¼Â¹Ô¤µ¤ì¤ë¤È¤­¡¢ + ¤½¤ì¤ÏƱ¤¸ PATH ¤Ç¤Ï¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + CGI ¥×¥í¥°¥é¥àÆâ¤Ç¸Æ¤Ó½Ð¤¹¤¢¤é¤æ¤ë¥×¥í¥°¥é¥à + (Î㤨¤Ð¡¢sendmail ¤Î¤è¤¦¤Ê¤â¤Î) ¤Ï¡¢ + ¥Õ¥ë¥Ñ¥¹¤Ç»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£¤½¤ì¤Ë¤è¤ê¡¢CGI + ¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤·¤è¤¦¤È¤·¤¿¤È¤­¡¢ + ¥·¥§¥ë¤Ï¤½¤Î¤è¤¦¤Ê¥×¥í¥°¥é¥à¤ò¸«¤Ä¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ƱÍͤʤ³¤È¤Ï¡¢¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¿¥×¥ê¥¿ (¤·¤Ð¤·¤Ð perl) + ¤Ø¤Î¥Ñ¥¹¤Ç¡¢CGI ¥×¥í¥°¥é¥à¤Î 1 ¹ÔÌܤ˼¡¤Î¤è¤¦¤Ë¼¨¤µ¤ì¤Þ¤¹:

    + +

    + #!/usr/bin/perl +

    + +

    ¤³¤ì¤¬¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ø¤Î¼ÂºÝ¤Î¥Ñ¥¹¤Ç¤¢¤ë¤³¤È¤ò³Î¼Â¤Ë¤·¤Æ¤ª¤­¤Þ¤¹¡£

    + + +

    ¥×¥í¥°¥é¥à¥¨¥é¡¼

    + + +

    CGI + ¥×¥í¥°¥é¥à¤¬¼ºÇÔ¤¹¤ë¤Î¤ÏÂçÄñ¡¢¥×¥í¥°¥é¥à¼«¿È¤ËÌäÂ꤬¤¢¤ë¾ì¹ç¤Ç¤¹¡£ + °ìÅÙ CGI ¤Î»È¤¤Êý¤òÍý²ò¤·¡¢Á°½Ò¤ÎÆó¤Ä¤Î¸í¤ê¤òÈȤ·¤Æ¤¤¤Ê¤¤¤Ê¤é¤Ð¡¢ + ¤Þ¤º´Ö°ã¤¤¤Ê¤¯¤½¤¦¤Ç¤·¤ç¤¦¡£¥Ö¥é¥¦¥¶¤ò»È¤Ã¤Æ¥Æ¥¹¥È¤¹¤ëÁ°¤Ë + ¤Þ¤º³Îǧ¤¹¤ë¤³¤È¤Ï¡¢¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¥×¥í¥°¥é¥à¤¬¼Â¹Ô¤Ç¤­¤ë¤³¤È¤Ç¤¹¡£ + Î㤨¤Ð¡¢°Ê²¼¤ò¼Â¹Ô¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤:

    + +

    + cd /usr/local/apache2/cgi-bin
    + ./first.pl +

    + +

    (perl ¥¤¥ó¥¿¥×¥ê¥¿¤Ï¸Æ¤Ð¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¥·¥§¥ë¤È Apache ¤¬¥¹¥¯¥ê¥×¥È¤ÎºÇ½é¤Î¹Ô¤Î ¥Ñ¥¹¾ðÊó ¤ò»È¤Ã¤Æ¸«¤Ä¤±¤Þ¤¹¡£)

    + +

    ºÇ½é¤Ë¥×¥í¥°¥é¥à¤«¤é½ÐÎϤµ¤ì¤ë¤Î¤Ï Content-Type ¤ò´Þ¤ß¡¢ + ¸å¤Ë¶õ¹Ô¤Î³¤¯ HTTP ¥Ø¥Ã¥À¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£Â¾¤Î¤â¤Î¤¬½ÐÎϤµ¤ì¤Æ¤¤¤ë + ¾ì¹ç¤Ï¡¢Apache ¤Ï¤³¤Î¥×¥í¥°¥é¥à¤ò¥µ¡¼¥Ð·Ðͳ¤Ç¼Â¹Ô¤·¤è¤¦¤È¤·¤¿¤È¤­¤Ë¤Ï + Premature end of script headers ¥¨¥é¡¼¤ò½ÐÎϤ·¤Þ¤¹¡£¾ÜºÙ¤Ï + ¾åµ­¤Î CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¯ ¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£

    + + +

    ¥¨¥é¡¼¥í¥°

    + + +

    ¥¨¥é¡¼¥í¥°¤Ïͧã¤Ç¤¹¡£ + Á´¤Æ¤Î¤¦¤Þ¤¯¤¤¤«¤Ê¤¤¤³¤È¤Ï¡¢¥¨¥é¡¼¥í¥°¤Ë¥á¥Ã¥»¡¼¥¸¤òÀ¸À®¤·¤Þ¤¹¡£ + ɬ¤º¤½¤ì¤òºÇ½é¤Ë¸«¤ë¤Ù¤­¤Ç¤¹¡£ + ¤â¤·¡¢¤¢¤Ê¤¿¤¬¥¦¥§¥Ö¥µ¥¤¥È¤ò¼çºÅ¤·¤Æ¤¤¤ë¾ì½ê¤¬ + ¥¨¥é¡¼¥í¥°¤Î»²¾È¤òµö¤·¤Æ¤¤¤Ê¤¤¤Ê¤é¤Ð¡¢¤­¤Ã¤È¾¤Î¥µ¥¤¥È¤Ç¼çºÅ¤¹¤ë¤Ù¤­¤Ç¤¹¡£ + ¥¨¥é¡¼¥í¥°¤ÎÆɤßÊý¤ò³Ø¤Ö¤³¤È¤Ç¡¢¤Û¤È¤ó¤ÉÁ´¤Æ¤ÎÌäÂ꤬¿×®¤Ë³Îǧ¤µ¤ì¡¢ + ¿×®¤Ë²ò·è¤µ¤ì¤ë¤È¤¤¤¦¤³¤È¤¬Ê¬¤«¤ë¤Ç¤·¤ç¤¦¡£

    + + +

    Suexec

    + + +

    suexec ¥µ¥Ý¡¼¥È¥×¥í¥°¥é¥à¤Ï + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ä¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î¾ì½ê¤Ë°Í¤Ã¤Æ + CGI ¥×¥í¥°¥é¥à¤ò°ã¤¦¥æ¡¼¥¶¸¢¸Â¤Î²¼¤ÇÁö¤é¤»¤ë¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£ + Suexec ¤Î¸¢¸Â¤Î¥Á¥§¥Ã¥¯¤ÏÈó¾ï¤Ë¸·¤·¤¯¡¢¤½¤ì¤òËþ¤¿¤µ¤Ê¤¤¾ì¹ç¤Ï + CGI ¥×¥í¥°¥é¥à¤¬ Premature end of script headers ¥¨¥é¡¼¤Ç + ¼Â¹Ô¤µ¤ì¤Þ¤»¤ó¡£

    + +

    suexec ¤ò»È¤Ã¤Æ¤¤¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤¿¤á¤Ë¤Ï apachectl + -V ¤ò¼Â¹Ô¤·¤Æ¡¢SUEXEC_BIN ¤Î¾ì½ê¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£ + Apache ¤¬¤½¤³¤Ë suexec ¤Î¥Ð¥¤¥Ê¥ê¤òȯ¸«¤·¤¿¾ì¹ç¤Ï¡¢suexec ¤¬ + »ÈÍѤµ¤ì¤Þ¤¹¡£

    + +

    suexec ¤ò´°Á´¤ËÍý²ò¤·¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢»È¤¦¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + suexec ¤ò̵¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢SUEXEC_BIN ¤«¤é»Ø¤µ¤ì¤Æ¤¤¤ë + suexec ¥Ð¥¤¥Ê¥ê¤òºï½ü (¤«Ì¾Á°¤òÊѹ¹) ¤¹¤ë¤À¤±¤Ç¤¹¡£ + suexec ¤òÆɤó¤À¸å¤Ç¡¢¤Þ¤À¤½¤ì¤ò + »È¤¤¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢suexec -V ¤ò¼Â¹Ô¤·¤Æ suexec ¤Î + ¥í¥°¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤òÄ´¤Ù¡¢¤½¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¥Ý¥ê¥·¡¼°ãÈ¿¤ò + ¸«¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    ΢¤Ç²¿¤¬µ¯¤³¤Ã¤Æ¤¤¤ë¤Î¤«?

    + + +

    CGI ¥×¥í¥°¥é¥ß¥ó¥°¤Ë½¬½Ï¤¹¤ë¤È¡¢ + ΢¤Çµ¯¤³¤Ã¤Æ¤¤¤ë¤³¤È¤Ë¤Ä¤¤¤Æ¹¹¤ËÍý²ò¤¹¤ë¤³¤ÈÌò¤ËΩ¤Á¤Þ¤¹¡£ + ¥Ö¥é¥¦¥¶¤È¥µ¡¼¥Ð¤¬¤É¤Î¤è¤¦¤ËÁê¸ßÄÌ¿®¤¹¤ë¤«¤Ë¤Ä¤¤¤Æ¤ÏÆäˤ½¤¦¤Ç¤¹¡£ + ¤Ê¤¼¤Ê¤é¡¢"Hello, World." + ¤ò°õ»ú¤¹¤ë¥×¥í¥°¥é¥à¤ò½ñ¤¯¤³¤È¤Ï¤ª¤ª¤¤¤Ë·ë¹½¤Ç¤¹¤¬¡¢ + ¤½¤ì¤ÏÆäËÍ­±×¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    ´Ä¶­ÊÑ¿ô

    + + +

    ´Ä¶­ÊÑ¿ô¤Ï¡¢ + ¤¢¤Ê¤¿¤¬¥³¥ó¥Ô¥å¡¼¥¿¤ò»È¤¦¤È¤­¤ËÊÕ¤ê¤Ë¸ºß¤·¤Æ¤¤¤ëÃͤǤ¹¡£ + ¤½¤ì¤é¤Ï¡¢¥Ñ¥¹ + (¥³¥Þ¥ó¥É¤ò¥¿¥¤¥×¤·¤¿¤È¤­¤Ë¼Â¹Ô¤¹¤ë¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë¤òõ¤·½Ð¤¹¤È¤³¤í)¡¢ + ¥æ¡¼¥¶Ì¾¡¢Ã¼Ëö·¿¤Ê¤É¤Î¤è¤¦¤ÊÊØÍø¤Ê¤â¤Î¤Ç¤¹¡£ + Ä̾ÉáÃÊ»ÈÍѤ·¤Æ¤¤¤ë´Ä¶­ÊÑ¿ô¤Î´°Á´¤Ê¥ê¥¹¥È¤òÄ´¤Ù¤ë¤Ë¤Ï¡¢ + ¥³¥Þ¥ó¥É¥×¥í¥ó¥×¥È¤Ç env ¤òÆþÎϤ·¤Þ¤¹¡£

    + +

    CGI ¤Î½èÍýÃæ¡¢¥µ¡¼¥Ð¤È¥Ö¥é¥¦¥¶¤â´Ä¶­ÊÑ¿ô¤òÀßÄꤷ¡¢ + ¤½¤ì¤Ë¤è¤êÁê¸ß¤ËÄÌ¿®¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤½¤Î´Ä¶­ÊÑ¿ô¤Ï¡¢¥Ö¥é¥¦¥¶¥¿¥¤¥× (Netscape, IE, Lynx)¡¢¥µ¡¼¥Ð¥¿¥¤¥× + (Apache, IIS, WebSite)¡¢¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë CGI + ¥×¥í¥°¥é¥à¤Î̾Á°¤Ê¤É¤Ç¤¹¡£

    + +

    ¤³¤ì¤é¤ÎÊÑ¿ô¤Ï CGI ¥×¥í¥°¥é¥Þ¤¬»ÈÍѤǤ­¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¤½¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð¤ÎÄÌ¿®¤ÎÏäÎȾʬ¤Ç¤¹¡£ + ɬÍפÊÊÑ¿ô¤Î´°Á´¤Ê¥ê¥¹¥È¤Ï http://hoohoo.ncsa.uiuc.edu/cgi/env.html ¤Ë¤¢¤ê¤Þ¤¹¡£

    + +

    °Ê²¼¤Îñ½ã¤Ê Perl CGI + ¥×¥í¥°¥é¥à¤Ï¡¢ÅϤµ¤ì¤ëÁ´¤Æ¤Î´Ä¶­ÊÑ¿ô¤òɽ¼¨¤·¤Þ¤¹¡£Æ±ÍÍ¤Î¥×¥í¥°¥é¥à¤Ï¡¢ + Apache ¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥ó¤Î cgi-bin + ¥Ç¥£¥ì¥¯¥È¥ê¤ËÆó¤Ä´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤¤¤¯¤Ä¤«¤ÎÊÑ¿ô¤¬É¬¿Ü¤Ç¤¢¤ê¡¢¤¤¤¯¤Ä¤«¤ÏǤ°Õ¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤·¤Æ¡¢¸ø¼°¤Î¥ê¥¹¥È¤Ë¤Ï¤Ê¤¤¤¤¤¯¤Ä¤«¤ÎÊÑ¿ô¤¬É½¼¨¤µ¤ì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤µ¤é¤Ë¡¢Apache ¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë´ðËÜŪ¤Ê¤â¤Î¤Ë + ¤¢¤Ê¤¿¼«¿È¤Î´Ä¶­ÊÑ¿ô¤ò²Ã¤¨¤ë¤¿¤á¤Î¡¢ + ¿¤¯¤Î°Û¤Ê¤ëÊýË¡¤òÍÑ°Õ¤·¤Æ¤·¤Þ¤¹¡£

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +

    + + +

    STDIN ¤È STDOUT

    + + +

    ¥µ¡¼¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È´Ö¤Î¤â¤¦°ì¤Ä¤ÎÄÌ¿®¤Ï¡¢É¸½àÆþÎÏ + (STDIN)¤Èɸ½à½ÐÎÏ (STDOUT) + ¤òÄ̤¸¤Æ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£Ä̾ï¤Îʸ̮¤Ë¤ª¤¤¤Æ¡¢STDIN + ¤Ï¥­¡¼¥Ü¡¼¥É¤ä¥×¥í¥°¥é¥à¤¬Æ°ºî¤¹¤ë¤¿¤á¤ËÍ¿¤¨¤é¤ì¤ë¥Õ¥¡¥¤¥ë¤ò°ÕÌ£¤·¡¢ + STDOUT ¤ÏÄ̾拾¥ó¥½¡¼¥ë¤Þ¤¿¤Ï¥¹¥¯¥ê¡¼¥ó¤ò°ÕÌ£¤·¤Þ¤¹¡£

    + +

    ¥¦¥§¥Ö¥Õ¥©¡¼¥à¤«¤é CGI ¥×¥í¥°¥é¥à¤ØPOST + ¤·¤¿¤È¤­¡¢¥Õ¥©¡¼¥à¤Î¥Ç¡¼¥¿¤ÏÆÃÊ̤ʥե©¡¼¥Þ¥Ã¥È¤Ç«¤Í¤é¤ì¡¢ + STDIN ¤òÄ̤·¤Æ¡¢CGI ¥×¥í¥°¥é¥à¤Ë°ú¤­ÅϤµ¤ì¤Þ¤¹¡£ + ¥×¥í¥°¥é¥à¤Ï¥Ç¡¼¥¿¤¬¥­¡¼¥Ü¡¼¥É + ¤â¤·¤¯¤Ï¥Õ¥¡¥¤¥ë¤«¤éÍè¤Æ¤¤¤¿¤«¤Î¤è¤¦¤Ë½èÍý¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¡ÖÆÃÊ̤ʥե©¡¼¥Þ¥Ã¥È¡×¤Ï¤È¤Æ¤âñ½ã¤Ç¤¹¡£¥Õ¥£¡¼¥ë¥É̾¤ÈÃͤϥ¤¥³¡¼¥ë + (=) ¤Ç·ë¤Ð¤ì¤Þ¤¹¡£¤½¤·¤ÆÃͤÎÁȤϥ¢¥ó¥Ñ¥µ¥ó¥É (&) ¤Ç·ë¤Ð¤ì¤Þ¤¹¡£ + ¥¹¥Ú¡¼¥¹¡¢¥¢¥ó¥Ñ¥µ¥ó¥É¡¢¥¤¥³¡¼¥ë¤Î¤è¤¦¤ÊÌÌÅݤÊʸ»ú¤Ï¡¢ + ¤½¤ì¤é¤¬Æ°ºî¤òÂÌÌܤˤ·¤Ê¤¤¤è¤¦¤Ë¤½¤Îʸ»ú¤ËÁêÅö¤¹¤ë 16 ¿Ê¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£ + Á´¥Ç¡¼¥¿Ê¸»úÎó¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹: +

    + +

    + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey +

    + +

    »þ¡¹¡¢¤³¤Î¤è¤¦¤Êʸ»úÎó¤¬ URL + ¤ËÉղ䵤ì¤ë¤Î¤ò¸«¤ë¤Ç¤·¤ç¤¦¡£¤½¤Î¾ì¹ç¡¢¥µ¡¼¥Ð¤Ï + QUERY_STRING ¤È¤¤¤¦´Ä¶­ÊÑ¿ô¤Ë¤½¤Îʸ»úÎó¤òÆþ¤ì¤Þ¤¹¡£¤½¤ì¤Ï + GET ¥ê¥¯¥¨¥¹¥È¤È¸Æ¤Ð¤ì¤Þ¤¹¡£ + HTML ¥Õ¥©¡¼¥à¤Ç¤Ï¡¢¥Ç¡¼¥¿¤òÅϤ¹¤¿¤á¤Ë GET ¤È + POST ¤Î¤É¤Á¤é¤ò»ÈÍѤ¹¤ë¤«¤ò¡¢FORM ¥¿¥°¤Î + METHOD °À­¤ÎÀßÄê¤Ç»ØÄꤷ¤Þ¤¹¡£

    + +

    CGI ¥×¥í¥°¥é¥à¤Ï¡¢¤½¤Îʸ»úÎó¤òÌò¤ËΩ¤Ä¾ðÊó¤Ëʬ³ä¤¹¤ëÀÕǤ¤¬¤¢¤ê¤Þ¤¹¡£ + ¹¬¤¤¤Ë¤â¡¢¤½¤Î¥Ç¡¼¥¿½èÍý¤ò½õ¤±¤ë¥é¥¤¥Ö¥é¥ê¤ä¥â¥¸¥å¡¼¥ë¤¬Â¸ºß¤·¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï¡¢CGI ¥×¥í¥°¥é¥à¤Î¾¤ÎÌ̤ǤâƱÍͤËÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +
    top
    +
    +

    CGI ¥â¥¸¥å¡¼¥ë/¥é¥¤¥Ö¥é¥ê

    + + +

    CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¯¤È¤­¡¢ÌÌÅݤʻŻö¤ÎÂçÉôʬ¤ò¤·¤Æ¤¯¤ì¤ë + ¥³¡¼¥É¥é¥¤¥Ö¥é¥ê¤Þ¤¿¤Ï¥â¥¸¥å¡¼¥ë¤ò»È¤¦¤³¤È¤ò¸¡Æ¤¤¹¤Ù¤­¤Ç¤¹¡£ + ¤³¤ì¤Ï¥¨¥é¡¼¤ò¸º¤é¤·¡¢Áᤤ³«È¯¤Ë¤Ä¤Ê¤¬¤ê¤Þ¤¹¡£

    + +

    Perl ¤Ç CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¤¤Æ¤¤¤ë¤Ê¤é¡¢¥â¥¸¥å¡¼¥ë¤Ï CPAN ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ÎÌÜŪ¤Î¤¿¤á¤ÎºÇ¤âÉáµÚ¤·¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤Ï CGI.pm ¤Ç¤¹¡£ + CGI::Lite ¤â¸¡Æ¤¤·¤Þ¤·¤ç¤¦¡£¤³¤ì¤Ï¡¢¤Û¤È¤ó¤É¤Î¥×¥í¥°¥é¥à + ¤Ë¤ª¤¤¤ÆɬÍפȤ¹¤ë¤¹¤Ù¤Æ¤Îµ¡Ç½¤ÎºÇ¾®¥»¥Ã¥È¤Î¼ÂÁõ¤Ç¤¹¡£

    + +

    C ¤Ç CGI ¥×¥í¥°¥é¥à¤ò½ñ¤¤¤Æ¤¤¤ë¤Ê¤é¡¢¤¤¤í¤¤¤í¤Ê + ¥ª¥×¥·¥ç¥ó¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤ÎÆâ¤Î°ì¤Ä¤Ï http://www.boutell.com/cgic/ + ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë CGIC ¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£

    +
    top
    +
    +

    ¹¹¤Ê¤ë¾ðÊó

    + + +

    CGI ¤Ë´Ø¤¹¤ë¾ðÊó¤Ï¥¦¥§¥Ö¤Ç¿ô¿¤¯Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£CGI + ¤ÎÌäÂê¤Ë¤Ä¤¤¤Æ¤Ï Usenet ¤Î comp.infosystems.www.authoring.cgi ¤Ç¡¢ + ¾¤Î¥æ¡¼¥¶¤ÈÏÀµÄ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£HTML Writers Guide ¤Î + -servers ¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤Ï¡¢¤¢¤Ê¤¿¤Î¼ÁÌä¤Ë²óÅú¤·¤Æ¤¯¤ì¤ë°ÎÂç¤Ê¥ê¥½¡¼¥¹¤Ç¤¹¡£ + http://www.hwg.org/lists/hwg-servers/ + ¤Ç¹¹¤Ë¿¤¯¤òõ¤·½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤½¤·¤Æ¤â¤Á¤í¤ó¡¢¤ª¤½¤é¤¯ CGI + ¥×¥í¥°¥é¥à¤ÎÆ°ºî¤Ë´Ø¤¹¤ë¾ÜºÙ¤ÎÁ´¤Æ¤¬µ­½Ò¤µ¤ì¤Æ¤¤¤ë + CGI ¤Î»ÅÍͤòÆɤà¤Ù¤­¤Ç¤¹¡£¥ª¥ê¥¸¥Ê¥ë¥Ð¡¼¥¸¥ç¥ó¤ò + NCSA + ¤Ç¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤µ¤ì¤¿¥É¥é¥Õ¥È¤ò + Common Gateway Interface RFC + ¥×¥í¥¸¥§¥¯¥È¤Ç»²¾È¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    CGI ¤ÎÌäÂê¤Ë¤Ä¤¤¤Æ¡¢²Ã¤ï¤Ã¤Æ¤¤¤ë¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤Þ¤¿¤Ï¥Ë¥å¡¼¥¹ + ¥°¥ë¡¼¥×¤Ë¼ÁÌä¤òÁ÷¤ë¤È¤­¡¢µ¯¤³¤Ã¤¿¤â¤Î¡¢µ¯¤³¤Ã¤Æ¤Û¤·¤¤¤³¤È¡¢ + ¼ÂºÝ¤Ëµ¯¤³¤Ã¤¿¤³¤È¤¬¤É¤¦°ã¤¦¤«¡¢»ÈÍѤ·¤Æ¤¤¤ë¥µ¡¼¥Ð¡¢ + CGI ¥×¥í¥°¥é¥à¤òµ­½Ò¤·¤Æ¤¤¤ë¸À¸ì¤Ë´Ø¤¹¤ë½½Ê¬¤Ê¾ðÊó¤È¡¢ + ²Äǽ¤Ç¤¢¤ì¤ÐÌäÂê¤Î¥³¡¼¥É¤òÄ󶡤¹¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤¦¤¹¤ë¤³¤È¤Ç¡¢ÌäÂ꤬¤è¤ê´Öñ¤Ë¸«¤Ä¤«¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Apache ¤Î¥½¡¼¥¹¥³¡¼¥É¤Ë¤ª¤¤¤ÆÌäÂê¤òȯ¸«¤·¤¿¤³¤È¤ò³Î¿®¤·¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢ + CGI ¤ÎÌäÂê¤Ë´Ø¤¹¤ë¼ÁÌä¤ò Apache + ¥Ð¥°¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÁ÷¤ë¤Ù¤­¤Ç¤Ê¤¤ + ¤³¤È¤ËÃíÌܤ·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/cgi.html.ko.euc-kr b/trunk/docs/manual/howto/cgi.html.ko.euc-kr new file mode 100644 index 0000000000..92513c40db --- /dev/null +++ b/trunk/docs/manual/howto/cgi.html.ko.euc-kr @@ -0,0 +1,503 @@ + + + +¾ÆÆÄÄ¡ ÅõÅ丮¾ó: CGI¸¦ »ç¿ëÇÑ µ¿Àû ÆäÀÌÁö »ý¼º - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ ÅõÅ丮¾ó: CGI¸¦ »ç¿ëÇÑ µ¿Àû ÆäÀÌÁö »ý¼º

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    +
    + +
    top
    +
    +

    ¼Ò°³

    + + + + +

    CGI (Common Gateway Interface)´Â À¥¼­¹ö°¡ º¸Åë CGI ÇÁ·Î±×·¥ + ȤÀº CGI ½ºÅ©¸³Æ®¶ó°í ºÎ¸£´Â, (À¥ÆäÀÌÁö ³»¿ëÀ» ¸¸µå´Â) ¿ÜºÎ + ÇÁ·Î±×·¥°ú Åë½ÅÇÏ´Â ¹æ¹ýÀ» Á¤ÀÇÇÑ´Ù. À¥»çÀÌÆ®¿¡¼­ µ¿ÀûÀÎ + ÆäÀÌÁö¸¦ ¸¸µå´Â °¡Àå ÈçÇÏ°í °£´ÜÇÑ ¹æ¹ýÀÌ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ + À¥¼­¹ö¿¡ CGI¸¦ ±¸¼ºÇÏ´Â ¹æ¹ýÀ» ¼Ò°³ÇÏ°í, CGI ÇÁ·Î±×·¥À» + ÀÛ¼ºÇغ»´Ù.

    +
    top
    +
    +

    CGI¸¦ Çã¿ëÇϵµ·Ï ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ

    + + +

    CGI ÇÁ·Î±×·¥ÀÌ ¿Ã¹Ù·Î µ¿ÀÛÇÏ·Á¸é CGI ½ÇÇàÀÌ °¡´ÉÇϵµ·Ï + ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. ¼³Á¤ÇÏ´Â ¹æ¹ýÀº ¿©·¯°¡Áö´Ù.

    + +

    ScriptAlias

    + + +

    ScriptAlias + Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â ƯÁ¤ µð·ºÅ丮¸¦ CGI ÇÁ·Î±×·¥¿ëÀ¸·Î + µÐ´Ù. ¾ÆÆÄÄ¡´Â ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀÌ CGI + ÇÁ·Î±×·¥À̶ó°í °¡Á¤ÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ ÀÚ¿øÀ» ¿äûÇϸé ÀÚ¿øÀ» + ½ÇÇàÇÏ·Á°í ½ÃµµÇÑ´Ù.

    + +

    ScriptAlias + Áö½Ã¾î´Â ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ +

    + +

    À§ ¿¹Á¦´Â ¾ÆÆÄÄ¡¸¦ ±âº» Àå¼Ò¿¡ ¼³Ä¡ÇÑ °æ¿ì + httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â ³»¿ëÀÌ´Ù. ScriptAlias Áö½Ã¾î´Â Alias Áö½Ã¾î¿Í °°ÀÌ URL + ¾ÕºÎºÐÀ» ƯÁ¤ µð·ºÅ丮·Î ´ëÀÀÇÑ´Ù. + Alias¿Í + ScriptAlias´Â º¸Åë DocumentRoot µð·ºÅ丮 ¹Û¿¡ ÀÖ´Â + µð·ºÅ丮¿¡ »ç¿ëÇÑ´Ù. Alias¿Í + ScriptAliasÀÇ Â÷ÀÌÁ¡Àº + ScriptAlias°¡ Ãß°¡·Î URL ¾ÕºÎºÐÀ¸·Î + ½ÃÀÛÇÏ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î Ãë±ÞÇÏ´Â Á¡ÀÌ´Ù. + ±×·¡¼­ À§ÀÇ ¼³Á¤Àº ¾ÆÆÄÄ¡¿¡°Ô /cgi-bin/À¸·Î + ½ÃÀÛÇÏ´Â ÀÚ¿øÀ» ¿äûÇϸé + /usr/local/apache2/cgi-bin/ µð·ºÅ丮¿¡¼­ + ã¾Æ¼­ CGI ÇÁ·Î±×·¥À¸·Î ó¸®Ç϶ó°í ¾Ë¸°´Ù.

    + +

    ¿¹¸¦ µé¾î, URL + http://www.example.com/cgi-bin/test.plÀ» + ¿äûÇÏ¸é ¾ÆÆÄÄ¡´Â + /usr/local/apache2/cgi-bin/test.pl ÆÄÀÏÀ» + ½ÇÇàÇÏ¿© °á°ú¸¦ ¹ÝȯÇÑ´Ù. ¹°·Ð ÆÄÀÏÀÌ Á¸ÀçÇÏ°í ½ÇÇà°¡´ÉÇϸç + ¾î¶² ¹æ¹ýÀ¸·Îµç Ãâ·ÂÀ» ÇØ¾ß ÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ¾ÆÆÄÄ¡´Â + ¿À·ù¹®À» º¸³½´Ù.

    + + +

    ScriptAlias µð·ºÅ丮 ¹Û¿¡ ÀÖ´Â CGI

    + + +

    º¸Åë º¸¾È»ó ÀÌÀ¯¶§¹®¿¡ CGI ÇÁ·Î±×·¥Àº ScriptAliasÇÑ µð·ºÅ丮¿¡ + ÇÑÁ¤ÇÑ´Ù. ±×·¡¼­ °ü¸®ÀÚ´Â ´©°¡ CGI ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö + ÀÖ´ÂÁö ¾ö°ÝÈ÷ °¨µ¶ÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Àû´çÇÑ º¸¾ÈÁ¶Ä¡¸¦ + ÃëÇß´Ù¸é ¾Æ¹« µð·ºÅ丮¿¡¼­³ª CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö ¾ÊÀ» + ÀÌÀ¯°¡ ¾ø´Ù. ¿¹¸¦ µé¾î, UserDir Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ È¨µð·ºÅ丮¿¡ À¥ÆäÀÌÁö¸¦ °¡Áö´Â °æ¿ì¸¦ + °¡Á¤ÇÏÀÚ. »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ CGI ÇÁ·Î±×·¥À» »ç¿ëÇÏ°í ½ÍÀºµ¥ + cgi-bin µð·ºÅ丮¿¡ Á¢±Ù±ÇÇÑÀÌ ¾ø´Ù¸é, ´Ù¸¥ + °÷¿¡¼­¶óµµ CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏ°í ½ÍÀ» °ÍÀÌ´Ù.

    + +

    ¾Æ¹« µð·ºÅ丮¿¡¼­³ª CGI ½ÇÇàÀ» Çã¿ëÇÏ·Á¸é µÎ °úÁ¤ÀÌ + ÇÊ¿äÇÏ´Ù. ¸ÕÀú, AddHandler³ª SetHandler Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + cgi-script Çڵ鷯¸¦ ÀÛµ¿ÇØ¾ß ÇÑ´Ù. µÎ¹ø°·Î, + Options Áö½Ã¾î¿¡ + ExecCGI¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + + +

    Options¸¦ »ç¿ëÇÏ¿© ¸í½ÃÀûÀ¸·Î CGI ½ÇÇàÀ» Çã¿ëÇϱâ

    + + +

    ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏ¿¡ Á÷Á¢ Options Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ƯÁ¤ + µð·ºÅ丮¿¡¼­ CGI ½ÇÇàÀ» Çã¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +

    + +

    À§ Áö½Ã¾î·Î ¾ÆÆÄÄ¡´Â CGI ÆÄÀÏÀÇ ½ÇÇàÀ» Çã¿ëÇÑ´Ù. ¾î¶² + ÆÄÀÏÀÌ CGI ÆÄÀÏÀÎÁöµµ ¼­¹ö¿¡°Ô ¾Ë·Á¾ß ÇÑ´Ù. ´ÙÀ½ AddHandler Áö½Ã¾î´Â ¼­¹ö¿¡°Ô + È®ÀåÀÚ°¡ cgi³ª plÀÎ ÆÄÀÏÀº ¸ðµÎ + CGI ÇÁ·Î±×·¥À̶ó°í ¾Ë¸°´Ù.

    + +

    + AddHandler cgi-script .cgi .pl +

    + + +

    .htaccess ÆÄÀÏ

    + + +

    .htaccess ÅõÅ丮¾óÀº + httpd.conf¿¡ Á¢±Ù±ÇÇÑÀÌ ¾ø´Â °æ¿ì¿¡ CGI ÇÁ·Î±×·¥À» + »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀ» ¾Ë·ÁÁØ´Ù.

    + + +

    »ç¿ëÀÚ µð·ºÅ丮

    + + +

    ¾Æ·¡ ¼³Á¤À» »ç¿ëÇÏ¸é »ç¿ëÀÚ µð·ºÅ丮¿¡¼­ .cgi·Î + ³¡³ª´Â ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÑ´Ù.

    + +

    + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +

    + +

    ´ÙÀ½À» »ç¿ëÇÏ¸é »ç¿ëÀÚ µð·ºÅ丮ÀÇ cgi-bin + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î ÀνÄÇÑ´Ù.

    + +

    + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +

    + + + +
    top
    +
    +

    CGI ÇÁ·Î±×·¥ ÀÛ¼ºÇϱâ

    + + +

    ``ÀϹÝÀûÀÎ'' ÇÁ·Î±×·¡¹Ö°ú CGI ÇÁ·Î±×·¡¹Ö »çÀÌ¿¡´Â µÎ°¡Áö + ÁÖµÈ Â÷ÀÌÁ¡ÀÌ ÀÖ´Ù.

    + +

    ù¹ø° Â÷ÀÌ´Â CGI ÇÁ·Î±×·¥Àº ´Ù¸¥ Ãâ·ÂÀ» ÇϱâÀü¿¡ ¸ÕÀú + MIME-type Çì´õ¸¦ Ãâ·ÂÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. HTTP Çì´õ´Â + Ŭ¶óÀ̾ðÆ®¿¡°Ô Ŭ¶óÀ̾ðÆ®°¡ ¾î¶² ³»¿ëÀ» ¹Þ°ÔµÉÁö ¹Ì¸® ¾Ë¸°´Ù. + º¸Åë ´ÙÀ½°ú °°´Ù.

    + +

    + Content-type: text/html +

    + +

    µÎ¹ø° Â÷ÀÌ´Â HTML ȤÀº ºê¶ó¿ìÀú°¡ º¸¿©ÁÙ ¼ö ÀÖ´Â Çü½ÄÀ¸·Î + Ãâ·ÂÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. ´ëºÎºÐÀÇ °æ¿ì HTMLÀ» Ãâ·ÂÇÏÁö¸¸, + ¶§¶§·Î gif ±×¸²°ú °°ÀÌ HTMLÀÌ ¾Æ´Ñ ³»¿ëÀ» Ãâ·ÂÇÏ´Â CGI + ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â °æ¿ìµµ ÀÖ´Ù.

    + +

    µÎ°¡Áö¸¦ Á¦¿ÜÇÏ°í´Â CGI ÇÁ·Î±×·¥ ÀÛ¼ºÀº ÀÌ¹Ì ¸¸µé¾î º¸¾ÒÀ» + ´Ù¸¥ ÇÁ·Î±×·¥µé°ú ¸Å¿ì ºñ½ÁÇÏ´Ù.

    + +

    óÀ½À¸·Î ¸¸µç CGI ÇÁ·Î±×·¥

    + + +

    ´ÙÀ½Àº ºê¶ó¿ìÀú¿¡ ÇÑ ÁÙÀ» Âï´Â CGI ÇÁ·Î±×·¥ ¿¹Á¦´Ù. + ±×´ë·Î first.plÀ̶ó´Â ÆÄÀÏ¿¡ ÀúÀåÇÏ°í, + cgi-bin µð·ºÅ丮¿¡ º¹»çÇÑ´Ù.

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +

    + +

    Perl¿¡ Àͼ÷ÇÏÁö ¾Ê´õ¶óµµ ¹«½¼ ÀÏÀÌ ÀϾ´ÂÁö ¾Ë ¼ö + ÀÖ´Ù. ù¹ø° ÁÙÀº ¾ÆÆÄÄ¡(ȤÀº »ç¿ëÇÏ´Â ½©)¿¡°Ô + /usr/bin/perl À§Ä¡¿¡ ÀÖ´Â ÀÎÅÍÇÁ¸®ÅÍÀ» »ç¿ëÇÏ¿© + ÀÌ ÇÁ·Î±×·¥ ÆÄÀÏÀ» ½ÇÇàÇ϶ó°í ¾Ë¸°´Ù. µÎ¹ø° ÁÙÀº ¹æ±Ý + ¸»ÇÑ content-type ¼±¾ðÀ» Ãâ·ÂÇÏ°í carriage-return ÁٹٲÞÀ» + µÎ¹ø Ãâ·ÂÇÑ´Ù. ±×·¯¸é Çì´õ µÚ¿¡ HTTP Çì´õÀÇ ³¡À» ¶æÇÏ´Â + ºóÁÙÀÌ »ý±â°í, º»¹®ÀÌ ½ÃÀÛÇÑ´Ù. ¼¼¹ø° ÁÙÀº "Hello, World." + ¹®ÀÚ¿­À» Ãâ·ÂÇÑ´Ù. ÀÌ°ÍÀ¸·Î ³¡ÀÌ´Ù.

    + +

    ºê¶ó¿ìÀú¸¦ ½ÇÇàÇÏ°í ÁÖ¼Ò¸¦ ÀÔ·ÂÇÑ´Ù

    + +

    + http://www.example.com/cgi-bin/first.pl +

    + +

    ÆÄÀÏ Àå¼Ò¸¦ ÀÔ·ÂÇϸé, ºê¶ó¿ìÀúâ¿¡ Hello, World. + ÇÑ ÁÙÀÌ º¸ÀδÙ. ÈïºÐµÇÁö´Â ¾ÊÁö¸¸, Çѹø µ¿ÀÛÇÏ´Â °ÍÀ» + º¸¾ÒÀ¸´Ï ÀÌÁ¦ ´Ù¸¥ °ÍÀ» ½ÃµµÇØ º¼ ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    ±×·¯³ª ¾ÆÁ÷ µ¿ÀÛÇÏÁö ¾Ê¾Æ¿ä!

    + + +

    À¥¿¡¼­ CGI ÇÁ·Î±×·¥¿¡ Á¢±ÙÇÒ¶§ ºê¶ó¿ìÀú¿¡ ³ª¿Ã ¼ö ÀÖ´Â + ³»¿ëÀº ±âº»ÀûÀ¸·Î ³×°¡Áö´Ù.

    + +
    +
    CGI ÇÁ·Î±×·¥ÀÇ Ãâ·Â
    +
    ÁÁ´Ù! ¸ðµç °ÍÀÌ Àß µ¿ÀÛÇÑ´Ù´Â ¶æÀÌ´Ù. Ãâ·ÂÀº Á¤È®ÇÏÁö¸¸ + ºê¶ó¿ìÀú°¡ ¿Ã¹Ù·Î ó¸®ÇÏÁö ¸øÇÑ´Ù¸é, CGI ÇÁ·Î±×·¥¿¡¼­ + ¿Ã¹Ù¸¥ Content-TypeÀ» ¼³Á¤ÇÏ¿´´ÂÁö È®ÀÎÇÑ´Ù.
    + +
    CGI ÇÁ·Î±×·¥ ¼Ò½ºÄÚµå ȤÀº "POST Method Not Allowed" + ¹®±¸
    +
    CGI ÇÁ·Î±×·¥À» ½ÇÇàÇϵµ·Ï ¾ÆÆÄÄ¡¸¦ ÀûÀýÈ÷ ¼³Á¤ÇÏÁö + ¾Ê¾Ò´Ù´Â ¶æÀÌ´Ù. ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ + ÀýÀ» ´Ù½Ã ÀÐ°í »©¸ÔÀº ºÎºÐÀÌ ÀÖ´ÂÁö ã¾ÆºÁ¶ó.
    + +
    "Forbidden"À¸·Î ½ÃÀÛÇÏ´Â ¹®±¸
    +
    ±ÇÇÑ ¹®Á¦°¡ ÀÖ´Ù´Â ¶æÀÌ´Ù. ¾ÆÆÄÄ¡ + ¿À·ù ·Î±×¿Í ¾Æ·¡ ÆÄÀϱÇÇÑ + ÀýÀ» È®ÀÎÇ϶ó.
    + +
    "Internal Server Error"¶ó´Â ¹®±¸
    +
    ¾ÆÆÄÄ¡ ¿À·ù ·Î±×¸¦ º¸¸é ¾Æ¸¶µµ + CGI ÇÁ·Î±×·¥ÀÌ Ãâ·ÂÇÑ ¿À·ù¹®°ú ÇÔ²² "Premature end of + script headers"°¡ º¸ÀÏ °ÍÀÌ´Ù. ÀÌ °æ¿ì ¾Æ·¡ ³»¿ëµéÀ» Çϳª¾¿ + È®ÀÎÇÏ¿© ¾î¶² ÀÌÀ¯·Î CGI ÇÁ·Î±×·¥ÀÌ ÀûÀýÇÑ HTTP Çì´õ¸¦ + Ãâ·ÂÇÏÁö ¸øÇß´ÂÁö ¾Ë¾Æº»´Ù.
    +
    + +

    ÆÄÀϱÇÇÑ

    + + +

    ¼­¹ö´Â ´ç½Å°ú µ¿ÀÏÇÑ °èÁ¤À¸·Î µ¿ÀÛÇÏÁö ¾ÊÀ½À» ¸í½ÉÇ϶ó. + Áï, ¼­¹ö°¡ ½ÃÀÛÇÏ¸é ¼­¹ö´Â ºñƯ±Ç »ç¿ëÀÚ ±ÇÇÑ(º¸Åë + nobody³ª www)À¸·Î µ¿ÀÛÇÑ´Ù. + ±×·¡¼­ ´ç½ÅÀÌ ¼ÒÀ¯ÇÑ ÆÄÀÏÀ» ½ÇÇàÇÏ·Á¸é ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù. + ÆÄÀÏ¿¡ nobody°¡ ½ÇÇàÇϱ⿡ ÃæºÐÇÑ ±ÇÇÑÀ» + ÁÖ±âÀ§ÇØ º¸Åë ¸ðµÎ¿¡°Ô ÆÄÀÏÀÇ ½ÇÇà ±ÇÇÑÀ» ÁØ´Ù.

    + +

    + chmod a+x first.pl +

    + +

    ¶Ç, ÇÁ·Î±×·¥ÀÌ ´Ù¸¥ ÆÄÀÏÀ» Àаųª ¾´´Ù¸é ÀÌ ÆÄÀÏ¿¡µµ + ÀûÀýÇÑ ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù.

    + + + +

    °æ·Î Á¤º¸¿Í ȯ°æ

    + + +

    ¸í·ÉÇà¿¡¼­ ÇÁ·Î±×·¥À» ½ÇÇàÇϸé ÀÚµ¿À¸·Î ¾î¶² Á¤º¸°¡ + ½©·Î Àü´ÞµÈ´Ù. ¿¹¸¦ µé¾î, PATH´Â ½©¿¡°Ô ´ç½ÅÀÌ + ¸»ÇÑ ÆÄÀÏÀ» ãÀ» Àå¼Ò¸¦ ¾Ë·ÁÁØ´Ù.

    + +

    À¥¼­¹ö°¡ ÇÁ·Î±×·¥À» CGI ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÒ¶§´Â + PATH°¡ ´Ù¸¦ ¼ö ÀÖ´Ù. (¿¹¸¦ µé¾î, + sendmail °°ÀÌ) CGI ÇÁ·Î±×·¥ ¾È¿¡¼­ ½ÇÇàÇÏ´Â + ¸í·É¾î´Â ¿ÏÀüÇÑ °æ·Î·Î ¸í½ÃÇØ¾ß ½©ÀÌ ¸í·É¾î¸¦ ãÀ» ¼ö + ÀÖ´Ù.

    + +

    °æ·Î ¹®Á¦´Â ´ÙÀ½°ú °°ÀÌ CGI ÇÁ·Î±×·¥ ù¹ø° ÁÙ¿¡ ³ª¿À´Â + ½ºÅ©¸³Æ® ÀÎÅÍÇÁ¸®ÅÍ (º¸Åë perl) °æ·Î¿¡¼­ + ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    + #!/usr/bin/perl +

    + +

    ½ÇÁ¦·Î ÀÎÅÍÇÁ¸®ÅÍÀÇ °æ·ÎÀÎÁö È®ÀÎÇÑ´Ù.

    + +

    ¶Ç, CGI ÇÁ·Î±×·¥ÀÌ ´Ù¸¥ ȯ°æº¯¼ö¸¦ + »ç¿ëÇÑ´Ù¸é ¾ÆÆÄÄ¡°¡ ÀÌ º¯¼öµéÀ» ÇÁ·Î±×·¥¿¡°Ô Àü´ÞÇØ¾ß + ÇÑ´Ù.

    + + + +

    ÇÁ·Î±×·¥ ¿À·ù

    + + +

    CGI ÇÁ·Î±×·¥ÀÌ ½ÇÆÐÇÏ´Â °æ¿ì ´ëºÎºÐ ÇÁ·Î±×·¥ ÀÚü + ¹®Á¦¶§¹®ÀÌ´Ù. ƯÈ÷ À§ÀÇ µÎ°¡Áö ½Ç¼ö¸¦ ÇÏÁö ¾Ê¾Ò°í ÀÌ ±ÛÀ» + °è¼Ó º¸°í ÀÖ´Ù¸é ´õ´õ¿í ±×·¸´Ù. ¸ÕÀú À¥¼­¹ö¿¡¼­ ½ÇÇàÇϱâ + Àü¿¡ ¸í·ÉÇà¿¡¼­ ÇÁ·Î±×·¥À» ½ÇÇàÇغ»´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°ÀÌ ½ÇÇàÇÑ´Ù.

    + +

    + cd /usr/local/apache2/cgi-bin
    + ./first.pl +

    + +

    (perl ÀÎÅÍÇÁ¸®Å͸¦ ½ÇÇàÇÏÁö ¸¶¶ó. ½©°ú + ¾ÆÆÄÄ¡´Â ½ºÅ©¸³Æ® ù¹ø° ÁÙ¿¡ ÀÖ´Â °æ·Î Á¤º¸¸¦ »ç¿ëÇÏ¿© ÀÎÅÍÇÁ¸®Å͸¦ + ã¾Æ¾ß ÇÑ´Ù.)

    + +

    ÇÁ·Î±×·¥Àº Á¦ÀÏ ¸ÕÀú Content-TypeÀ» Æ÷ÇÔÇÑ + HTTP Çì´õµéÀ» Ãâ·ÂÇÏ°í ºó ÁÙÀ» Ãâ·ÂÇØ¾ß ÇÑ´Ù. ´Ù¸¥ °ÍÀ» + Ãâ·ÂÇÑ´Ù¸é À¥¼­¹ö¿¡¼­ ½ÇÇàÇÒ °æ¿ì ¾ÆÆÄÄ¡´Â Premature + end of script headers¸¦ ¹ÝȯÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº + À§ÀÇ CGI ÇÁ·Î±×·¥ ÀÛ¼ºÇϱ⸦ Âü°íÇ϶ó.

    + + +

    ¿À·ù ·Î±×

    + + +

    ¿À·ù ·Î±×´Â ´ç½Å ÆíÀÌ´Ù. ¹«¾ð°¡ À߸øµÇ¸é ¿À·ù ·Î±×¿¡ + ¹®±¸°¡ »ý±ä´Ù. ¿À·ù ·Î±×¸¦ Á¦ÀÏ ¸ÕÀú »ìÆìºÁ¾ß ÇÑ´Ù. À¥»çÀÌÆ®¸¦ + È£½ºÆÃÇÏ´Â °÷¿¡¼­ ¿À·ù ·Î±×¸¦ º¸Áö ¸øÇÏ°Ô ÇÑ´Ù¸é, ¾Æ¸¶µµ + ´Ù¸¥ ¾÷ü¸¦ ¾Ë¾ÆºÁ¾ß ÇÑ´Ù. ¿À·ù ·Î±×¸¦ º¸´Â ¹æ¹ýÀ» ÀÍÈ÷¸é, + ´ëºÎºÐÀÇ ¹®Á¦¸¦ »¡¸® ÆľÇÇÏ¿© ÇØ°áÇÒ ¼ö ÀÖ´Ù.

    + + +

    Suexec

    + + +

    suexec Áö¿ø ÇÁ·Î±×·¥À» + »ç¿ëÇÏ¸é ¾î¶² °¡»óÈ£½ºÆ® ȤÀº ¾î¶² »ç¿ëÀÚ µð·ºÅ丮¿¡ ÀÖ´ÂÁö¿¡ + µû¶ó CGI ÇÁ·Î±×·¥À» ´Ù¸¥ »ç¿ëÀÚ ±ÇÇÑÀ¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + Suexec´Â ¸Å¿ì ¾ö°ÝÇÏ°Ô ±ÇÇÑÀ» °Ë»çÇϸç, °Ë»ç¸¦ Çϳª¶óµµ + Åë°úÇÏÁö ¸øÇϸé CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö ¾Ê°í Premature + end of script headers¸¦ ¹ÝȯÇÑ´Ù.

    + +

    suexec¸¦ »ç¿ëÇÏ°í ÀÖ´ÂÁö ¾Ë·Á¸é apachectl -V¸¦ + ½ÇÇàÇÏ¿© SUEXEC_BIN À§Ä¡¸¦ È®ÀÎÇÑ´Ù. ¾ÆÆÄÄ¡°¡ + ½ÃÀÛÇÒ¶§ ±× Àå¼Ò¿¡¼­ suexec ½ÇÇàÆÄÀÏÀ» ¹ß°ßÇϸé, suexec¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    suexec¸¦ ¿ÏÀüÈ÷ ÀÌÇØÇÏÁö ¸øÇß´Ù¸é »ç¿ëÇؼ­´Â ¾ÈµÈ´Ù. + suexec¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸·Á¸é SUEXEC_BIN À§Ä¡¿¡ + ÀÖ´Â suexec ½ÇÇàÆÄÀÏÀ» Áö¿ì°í (ȤÀº ÆÄÀϸíÀ» + ¹Ù²Ù°í) ¼­¹ö¸¦ Àç½ÃÀÛÇÏ¸é µÈ´Ù. suexec¿¡ ´ëÇØ ÀÐÀº ´ÙÀ½ ±×·¡µµ + »ç¿ëÇÏ°í ½Í´Ù¸é, suexec -V¸¦ ½ÇÇàÇÏ¿© suexec + ·Î±×ÆÄÀÏ À§Ä¡¸¦ ¾Ë¾Æ³»°í ·Î±×ÆÄÀÏ¿¡¼­ ´ç½ÅÀÌ ¾î¶² ±ÔÄ¢À» + ¾î±â°í ÀÖ´ÂÁö ã´Â´Ù.

    + +
    top
    +
    +

    µÚ¿¡¼­´Â ¹«½¼ ÀÏÀÌ ¹ú¾îÁö´Â°¡?

    + + +

    CGI ÇÁ·Î±×·¡¹Ö¿¡ Àͼ÷ÇØÁú¼ö·Ï µÚ¿¡¼­ ¹ú¾îÁö´Â ÀÏÀ» ÀÌÇØÇϸé + µµ¿òÀÌ µÈ´Ù. ±¸Ã¼ÀûÀ¸·Î ºê¶ó¿ìÀú¿Í ¼­¹ö°¡ ¼­·Î Åë½ÅÇÏ´Â + ¹æ¹ýÀ» ¸»ÇÏ´Â °ÍÀÌ´Ù. ¸ô¶óµµ "Hello, World."¸¦ Ãâ·ÂÇÏ´Â + ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¼ö ÀÖÁö¸¸ ÀÌ·± ÇÁ·Î±×·¥Àº º°·Î ¾µ¸ð°¡ + ¾ø±â¶§¹®ÀÌ´Ù.

    + +

    ȯ°æº¯¼ö

    + + +

    ȯ°æº¯¼ö´Â ´ç½ÅÀÌ ÄÄÇ»Å͸¦ »ç¿ëÇÏ´Â µ¿¾È ´ç½Å ÁÖÀ§¸¦ + ¶°´Ù´Ï´Â °ªÀÌ´Ù. ȯ°æº¯¼ö´Â path (ÄÄÇ»ÅÍ°¡ ´ç½ÅÀÌ ÀÔ·ÂÇÑ + ¸í·É¾î¿¡ ÇØ´çÇÏ´Â ½ÇÁ¦ ÆÄÀÏÀ» ã´Â Àå¼Ò), »ç¿ëÀÚ¸í, Å͹̳Π+ Á¾·ù¿Í °°ÀÌ À¯¿ëÇÑ Á¤º¸´Ù. ÀϹÝÀûÀΠȯ°æº¯¼ö¸¦ ¸ðµÎ º¸·Á¸é + ¸í·ÉÇà ÇÁ·ÒÇÁÆ®¿¡¼­ env¸¦ ÀÔ·ÂÇÑ´Ù.

    + +

    CGI¸¦ ½ÇÇàÇÒ¶§µµ ¼­¹ö¿Í ºê¶ó¿ìÀú´Â °¢ÀÚÀÇ È¯°æº¯¼ö¸¦ + ¼­·Î ±³È¯ÇÑ´Ù. ÀÌ Á¤º¸¿¡´Â ºê¶ó¿ìÀú Á¾·ù (Netscape, IE, + Lynx), ¼­¹ö Á¾·ù (¾ÆÆÄÄ¡, IIS, WebSite), ½ÇÇàÇÏ´Â CGI + ÇÁ·Î±×·¥¸í µîÀÌ ÀÖ´Ù.

    + +

    CGI ÇÁ·Î±×·¡¸Ó´Â ÀÌ·± º¯¼öµéÀ» »ç¿ëÇÒ ¼ö ÀÖ°í, + ȯ°æº¯¼ö´Â Ŭ¶óÀ̾ðÆ®-¼­¹ö Åë½Å¿¡´Â ÀϺκÐÀ» Â÷ÁöÇÑ´Ù. + Àüü Çʼö º¯¼ö ¸ñ·ÏÀº http://hoohoo.ncsa.uiuc.edu/cgi/env.html¿¡ ÀÖ´Ù.

    + +

    ¾Æ·¡ °£´ÜÇÑ Perl CGI ÇÁ·Î±×·¥Àº Àڽſ¡°Ô Àü´ÞµÈ ¸ðµç + ȯ°æº¯¼ö¸¦ º¸¿©ÁØ´Ù. ¾ÆÆÄÄ¡ ¹èÆ÷º»ÀÇ cgi-bin + µð·ºÅ丮¿¡ ÀÌ¿Í ºñ½ÁÇÑ ÇÁ·Î±×·¥ÀÌ µÎ°³ ÀÖ´Ù. ¸î¸î º¯¼ö´Â + ÇʼöÀÌ°í ³ª¸ÓÁö´Â ¼±ÅÃÀûÀÌ´Ù. ±×·¡¼­ °ø½Ä ¸ñ·Ï¿¡ ¾ø´Â + º¯¼öµµ º¸ÀδÙ. ¶Ç, ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î Á¦°øÇϴ ȯ°æº¯¼ö + ¿Ü¿¡ ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î Á÷Á¢ ȯ°æº¯¼ö¸¦ + Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +

    + + +

    STDIN°ú STDOUT

    + + +

    ¶Ç, ¼­¹ö¿Í Ŭ¶óÀ̾ðÆ®´Â Ç¥ÁØÀÔ·Â(STDIN)°ú + Ç¥ÁØÃâ·Â(STDOUT)À¸·Î Åë½ÅÇÑ´Ù. ÀÏ»óÀûÀÎ °æ¿ì + STDINÀº Å°º¸µå³ª ÇÁ·Î±×·¥ÀÌ Ã³¸®ÇÏ´Â ÆÄÀÏÀ» + ³ªÅ¸³»°í, STDOUTÀº º¸Åë ÄܼÖÀ̳ª È­¸éÀ» ¶æÇÑ´Ù.

    + +

    CGI ÇÁ·Î±×·¥¿¡°Ô À¥ ¾ç½Ä(form)À» POSTÇϸé + ¾ç½Ä¿¡ ÀÔ·ÂÇÑ ÀڷḦ Ưº°ÇÑ Çü½ÄÀ¸·Î ¹­¾î¼­ CGI ÇÁ·Î±×·¥ÀÇ + STDINÀ¸·Î Àü´ÞÇÑ´Ù. ±×·¯¸é ÇÁ·Î±×·¥Àº Å°º¸µå³ª + ÆÄÀÏ¿¡¼­ ¾òÀº ÀڷḦ ó¸®ÇϵíÀÌ ÀڷḦ ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    "Ưº°ÇÑ Çü½Ä"Àº ¸Å¿ì °£´ÜÇÏ´Ù. Ç׸ñ À̸§°ú °ªÀ» µîÈ£(=)·Î + ¿¬°áÇÏ°í, Ç׸ñ À̸§°ú °ªÀÇ ½ÖµéÀ» ¼­·Î ¾ØÆÛ»÷µå(&)·Î + ¿¬°áÇÑ´Ù. °ø¹é, ¾ÚÆÛ»÷µå, µîÈ£ °°Àº ºÎÀÚ¿¬½º·¯¿î ¹®ÀÚ´Â + È¥µ¿ÇÏÁö ¾Êµµ·Ï 16Áø¼ö·Î º¯È¯ÇÑ´Ù. ¿ÏÀüÇÑ ÀÚ·á ¹®ÀÚ¿­Àº + ´ÙÀ½°ú °°ÀÌ »ý°å´Ù.

    + +

    + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey +

    + +

    Á¾Á¾ URL µÚ¿¡¼­ ÀÌ·± ¹®ÀÚ¿­À» º¸°Ô µÈ´Ù. ÀÌ °æ¿ì ¼­¹ö´Â + ¹®ÀÚ¿­À» QUERY_STRINGÀ̶ó´Â ȯ°æº¯¼ö¿¡ ÀúÀåÇÑ´Ù. + À̸¦ GET ¿äûÀ̶ó°í ÇÑ´Ù. FORM + ű×ÀÇ METHOD ¼Ó¼ºÀ» ÁöÁ¤ÇÏ¿© HTML ¾ç½Ä(form)ÀÌ + ÀڷḦ GETÇÒÁö POSTÇÒÁö °áÁ¤ÇÑ´Ù.

    + +

    ÀÌÁ¦ ÇÁ·Î±×·¥Àº ÀÌ·± ¹®ÀÚ¿­À» À¯¿ëÇÑ Á¤º¸·Î ÂÉ°³¾ß + ÇÑ´Ù. ´ÙÇàÈ÷µµ ÀÌ·± ÀÚ·á 󸮸¦ µ½°í CGI ÇÁ·Î±×·¥ÀÇ ´Ù¸¥ + ¿©·¯ ¸éÀ» »ìÇÇ´Â ¶óÀ̺귯¸®¿Í ¸ðµâµéÀÌ ÀÖ´Ù.

    + +
    top
    +
    +

    CGI ¸ðµâ/¶óÀ̺귯¸®

    + + +

    CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ¶§ Áö·çÇÑ ÀÛ¾÷À» ´ë½ÅÇØÁÖ´Â ÄÚµå + ¶óÀ̺귯¸® ȤÀº ¸ðµâÀ» »ç¿ëÇÒÁö °í·ÁÇغÁ¾ß ÇÑ´Ù. ÀÌ·± °ÍÀ» + »ç¿ëÇÏ¸é ¹ö±×°¡ ÁÙ°í ´õ »¡¸® ÇÁ·Î±×·¥À» °³¹ßÇÒ ¼ö ÀÖ´Ù.

    + +

    Perl·Î CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ´Ù¸é CPAN¿¡¼­ °ü·Ã ¸ðµâµéÀ» ãÀ» + ¼ö ÀÖ´Ù. CGI °³¹ß¿¡ °¡Àå ³Î¸® »ç¿ëµÇ´Â ¸ðµâÀº + CGI.pmÀÌ´Ù. ´ëºÎºÐÀÇ ÇÁ·Î±×·¥¿¡ ÃæºÐÇÑ ÃÖ¼Ò + ±â´ÉÀ» ±¸ÇöÇÑ CGI::Liteµµ °í·ÁÇØ º¼ ¼ö ÀÖ´Ù.

    + +

    C·Î CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ´Ù¸é ¼±ÅÃÀÇ ¿©Áö°¡ ¸¹´Ù. ÀÌÁß + Çϳª°¡ http://www.boutell.com/cgic/¿¡ + ÀÖ´Â CGIC ¶óÀ̺귯¸®´Ù.

    +
    top
    +
    +

    ´õ ¸¹Àº Á¤º¸...

    + + +

    À¥¿¡ ¸Å¿ì ¸¹Àº CGI Á¤º¸°¡ ÀÖ´Ù. ´º½º±×·ì comp.infosystems.www.authoring.cgi¿¡¼­ ¿©·¯ »ç¶÷µé°ú + CGI ¹®Á¦¸¦ ³íÀÇÇÒ ¼ö ÀÖ´Ù. HTML Writers GuildÀÇ -servers + ¸ÞÀϸµ¸®½ºÆ®´Â Áú¹®¿¡ ´ëÇÑ ´äÀ» ã±â¿¡ ÈǸ¢ÇÑ Àå¼Ò´Ù. http://www.hwg.org/lists/hwg-servers/¿¡¼­ ´õ ¸¹Àº °ÍÀ» + ¾Ë ¼ö ÀÖ´Ù.

    + +

    ±×¸®°í ¹°·Ð CGI ÇÁ·Î±×·¥ µ¿ÀÛ¿¡ ´ëÇÑ ¸ðµç ³»¿ëÀ» ¼³¸íÇÑ + CGI ±Ô¾àÀ» Àоî¾ß ÇÒÁöµµ ¸ð¸¥´Ù. NCSA¿¡ + ¿øº» ¹®¼­°¡ ÀÖ°í, ¼öÁ¤ÇÑ ÃʾÈÀº Common Gateway Interface + RFC ÇÁ·ÎÁ§Æ®¿¡ ÀÖ´Ù.

    + +

    ¸ÞÀϸµ¸®½ºÆ®³ª ´º½º±×·ì¿¡ ÇöÀç °Ý°í ÀÖ´Â CGI ¹®Á¦¿¡ ´ëÇØ + Áú¹®ÇÒ¶§´Â ¹ß»ýÇÑ Çö»ó°ú ¿ø·¡ ±â´ëÇÑ °á°ú, ½ÇÁ¦·Î ¹ß»ýÇÑ + Çö»óÀÌ ¾î¶»°Ô ´Ù¸¥Áö, »ç¿ëÇÏ´Â ¼­¹ö, CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ + ¾ð¾î, °¡´ÉÇϸé ÇØ´ç Äڵ带 ÀÚ¼¼È÷ Àû¾î¶ó. ±×·¯¸é ÇØ°áÃ¥À» + ã±â ½¬¿öÁø´Ù.

    + +

    ¾ÆÆÄÄ¡ ¼Ò½ºÄڵ尡 À߸øµÇ¾ú´Ù°í È®½ÅÇÏÁö ¾Ê´Â ÇÑ CGI Áú¹®À» + ¾ÆÆÄÄ¡ ¹ö±× µ¥ÀÌÅͺ£À̽º¿¡ ¿Ã¸®¸é Àý´ë·Î + ¾ÈµÈ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/cgi.xml b/trunk/docs/manual/howto/cgi.xml new file mode 100644 index 0000000000..b80c9e784e --- /dev/null +++ b/trunk/docs/manual/howto/cgi.xml @@ -0,0 +1,568 @@ + + + + + + + + + How-To / Tutorials + + Apache Tutorial: Dynamic Content with CGI + +
    + Introduction + + + + mod_alias + mod_cgi + + + + AddHandler + Options + ScriptAlias + + + +

    The CGI (Common Gateway Interface) defines a way for a web + server to interact with external content-generating programs, + which are often referred to as CGI programs or CGI scripts. It + is the simplest, and most common, way to put dynamic content on + your web site. This document will be an introduction to setting + up CGI on your Apache web server, and getting started writing + CGI programs.

    +
    + +
    + Configuring Apache to permit CGI + +

    In order to get your CGI programs to work properly, you'll + need to have Apache configured to permit CGI execution. There + are several ways to do this.

    + +
    + ScriptAlias + +

    The + ScriptAlias + + directive tells Apache that a particular directory is set + aside for CGI programs. Apache will assume that every file in + this directory is a CGI program, and will attempt to execute + it, when that particular resource is requested by a + client.

    + +

    The ScriptAlias + directive looks like:

    + + + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ + + +

    The example shown is from your default httpd.conf + configuration file, if you installed Apache in the default + location. The ScriptAlias + directive is much like the Alias directive, which defines a URL prefix that + is to mapped to a particular directory. Alias + and ScriptAlias are usually used for + directories that are outside of the DocumentRoot directory. The difference between + Alias and ScriptAlias + is that ScriptAlias has the added meaning + that everything under that URL prefix will be considered a CGI + program. So, the example above tells Apache that any request for a + resource beginning with /cgi-bin/ should be served from + the directory /usr/local/apache2/cgi-bin/, and should be + treated as a CGI program.

    + +

    For example, if the URL + http://www.example.com/cgi-bin/test.pl + is requested, Apache will attempt to execute the file + /usr/local/apache2/cgi-bin/test.pl + and return the output. Of course, the file will have to + exist, and be executable, and return output in a particular + way, or Apache will return an error message.

    +
    + +
    + CGI outside of ScriptAlias directories + +

    CGI programs are often restricted to ScriptAlias'ed directories for security reasons. + In this way, administrators can tightly control who is allowed to + use CGI programs. However, if the proper security precautions are + taken, there is no reason why CGI programs cannot be run from + arbitrary directories. For example, you may wish to let users + have web content in their home directories with the + UserDir directive. + If they want to have their own CGI programs, but don't have access to + the main cgi-bin directory, they will need to be able to + run CGI programs elsewhere.

    + +

    There are two steps to allowing CGI execution in an arbitrary + directory. First, the cgi-script handler must be + activated using the AddHandler or SetHandler directive. Second, + ExecCGI must be specified in the Options directive.

    +
    + +
    + Explicitly using Options to permit CGI execution + +

    You could explicitly use the Options directive, inside your main server configuration + file, to specify that CGI execution was permitted in a particular + directory:

    + + + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +
    + +

    The above directive tells Apache to permit the execution + of CGI files. You will also need to tell the server what + files are CGI files. The following AddHandler directive tells the server to treat all + files with the cgi or pl extension as CGI + programs:

    + + + AddHandler cgi-script .cgi .pl + +
    + +
    + .htaccess files + +

    The .htaccess tutorial + shows how to activate CGI programs if you do not have + access to httpd.conf.

    +
    + +
    + User Directories + +

    To allow CGI program execution for any file ending in + .cgi in users' directories, you can use the + following configuration.

    + + + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +
    + +

    If you wish designate a cgi-bin subdirectory of + a user's directory where everything will be treated as a CGI + program, you can use the following.

    + + + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +
    + +
    + +
    + +
    + Writing a CGI program + +

    There are two main differences between ``regular'' + programming, and CGI programming.

    + +

    First, all output from your CGI program must be preceded by + a MIME-type header. This is HTTP header that tells the client + what sort of content it is receiving. Most of the time, this + will look like:

    + + + Content-type: text/html + + +

    Secondly, your output needs to be in HTML, or some other + format that a browser will be able to display. Most of the + time, this will be HTML, but occasionally you might write a CGI + program that outputs a gif image, or other non-HTML + content.

    + +

    Apart from those two things, writing a CGI program will look + a lot like any other program that you might write.

    + +
    + Your first CGI program + +

    The following is an example CGI program that prints one + line to your browser. Type in the following, save it to a + file called first.pl, and put it in your + cgi-bin directory.

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +
    + +

    Even if you are not familiar with Perl, you should be able + to see what is happening here. The first line tells Apache + (or whatever shell you happen to be running under) that this + program can be executed by feeding the file to the + interpreter found at the location /usr/bin/perl. + The second line prints the content-type declaration we + talked about, followed by two carriage-return newline pairs. + This puts a blank line after the header, to indicate the end + of the HTTP headers, and the beginning of the body. The third + line prints the string "Hello, World.". And that's the end + of it.

    + +

    If you open your favorite browser and tell it to get the + address

    + + + http://www.example.com/cgi-bin/first.pl + + +

    or wherever you put your file, you will see the one line + Hello, World. appear in your browser window. + It's not very exciting, but once you get that working, you'll + have a good chance of getting just about anything working.

    +
    +
    + +
    + But it's still not working! + +

    There are four basic things that you may see in your browser + when you try to access your CGI program from the web:

    + +
    +
    The output of your CGI program
    +
    Great! That means everything worked fine. If the output is correct, + but the browser is not processing it correctly, make sure you have the + correct Content-Type set in your CGI program.
    + +
    The source code of your CGI program or a "POST Method Not + Allowed" message
    +
    That means that you have not properly configured Apache + to process your CGI program. Reread the section on + configuring + Apache and try to find what you missed.
    + +
    A message starting with "Forbidden"
    +
    That means that there is a permissions problem. Check the + Apache error log and the section below on + file permissions.
    + +
    A message saying "Internal Server Error"
    +
    If you check the + Apache error log, you will probably + find that it says "Premature end of + script headers", possibly along with an error message + generated by your CGI program. In this case, you will want to + check each of the below sections to see what might be + preventing your CGI program from emitting the proper HTTP + headers.
    +
    + +
    + File permissions + +

    Remember that the server does not run as you. That is, + when the server starts up, it is running with the permissions + of an unprivileged user - usually nobody, or + www - and so it will need extra permissions to + execute files that are owned by you. Usually, the way to give + a file sufficient permissions to be executed by nobody + is to give everyone execute permission on the file:

    + + + chmod a+x first.pl + + +

    Also, if your program reads from, or writes to, any other + files, those files will need to have the correct permissions + to permit this.

    + +
    + +
    + Path information and environment + +

    When you run a program from your command line, you have + certain information that is passed to the shell without you + thinking about it. For example, you have a PATH, + which tells the shell where it can look for files that you + reference.

    + +

    When a program runs through the web server as a CGI program, + it may not have the same PATH. Any programs that you + invoke in your CGI program (like sendmail, for + example) will need to be specified by a full path, so that the + shell can find them when it attempts to execute your CGI + program.

    + +

    A common manifestation of this is the path to the script + interpreter (often perl) indicated in the first + line of your CGI program, which will look something like:

    + + + #!/usr/bin/perl + + +

    Make sure that this is in fact the path to the + interpreter.

    + +

    In addition, if your CGI program depends on other environment variables, you will need to + assure that those variables are passed by Apache.

    + +
    + +
    + Program errors + +

    Most of the time when a CGI program fails, it's because of + a problem with the program itself. This is particularly true + once you get the hang of this CGI stuff, and no longer make + the above two mistakes. The first thing to do is to make + sure that your program runs from the command line before + testing it via the web server. For example, try:

    + + + cd /usr/local/apache2/cgi-bin
    + ./first.pl +
    + +

    (Do not call the perl interpreter. The shell + and Apache should find the interpreter using the path information on the first line of + the script.)

    + +

    The first thing you see written by your program should be + a set of HTTP headers, including the Content-Type, + followed by a blank line. If you see anything else, Apache will + return the Premature end of script headers error if + you try to run it through the server. See Writing a CGI program above for more + details.

    +
    + +
    + Error logs + +

    The error logs are your friend. Anything that goes wrong + generates message in the error log. You should always look + there first. If the place where you are hosting your web site + does not permit you access to the error log, you should + probably host your site somewhere else. Learn to read the + error logs, and you'll find that almost all of your problems + are quickly identified, and quickly solved.

    +
    + +
    + Suexec + +

    The suexec support program + allows CGI programs to be run under different user permissions, + depending on which virtual host or user home directory they are + located in. Suexec has very strict permission checking, and any + failure in that checking will result in your CGI programs + failing with Premature end of script headers.

    + +

    To check if you are using suexec, run apachectl + -V and check for the location of SUEXEC_BIN. + If Apache finds an suexec binary there on startup, + suexec will be activated.

    + +

    Unless you fully understand suexec, you should not be using it. + To disable suexec, simply remove (or rename) the suexec + binary pointed to by SUEXEC_BIN and then restart the + server. If, after reading about suexec, + you still wish to use it, then run suexec -V to find + the location of the suexec log file, and use that log file to + find what policy you are violating.

    +
    +
    + +
    + What's going on behind the scenes? + +

    As you become more advanced in CGI programming, it will + become useful to understand more about what's happening behind + the scenes. Specifically, how the browser and server + communicate with one another. Because although it's all very + well to write a program that prints "Hello, World.", it's not + particularly useful.

    + +
    + Environment variables + +

    Environment variables are values that float around you as + you use your computer. They are useful things like your path + (where the computer searches for the actual file + implementing a command when you type it), your username, your + terminal type, and so on. For a full list of your normal, + every day environment variables, type + env at a command prompt.

    + +

    During the CGI transaction, the server and the browser + also set environment variables, so that they can communicate + with one another. These are things like the browser type + (Netscape, IE, Lynx), the server type (Apache, IIS, WebSite), + the name of the CGI program that is being run, and so on.

    + +

    These variables are available to the CGI programmer, and + are half of the story of the client-server communication. The + complete list of required variables is at + http://hoohoo.ncsa.uiuc.edu/cgi/env.html.

    + +

    This simple Perl CGI program will display all of the + environment variables that are being passed around. Two + similar programs are included in the + cgi-bin + + directory of the Apache distribution. Note that some + variables are required, while others are optional, so you may + see some variables listed that were not in the official list. + In addition, Apache provides many different ways for you to + add your own environment variables + to the basic ones provided by default.

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +
    +
    + +
    + STDIN and STDOUT + +

    Other communication between the server and the client + happens over standard input (STDIN) and standard + output (STDOUT). In normal everyday context, + STDIN means the keyboard, or a file that a + program is given to act on, and STDOUT + usually means the console or screen.

    + +

    When you POST a web form to a CGI program, + the data in that form is bundled up into a special format + and gets delivered to your CGI program over STDIN. + The program then can process that data as though it was + coming in from the keyboard, or from a file

    + +

    The "special format" is very simple. A field name and + its value are joined together with an equals (=) sign, and + pairs of values are joined together with an ampersand + (&). Inconvenient characters like spaces, ampersands, and + equals signs, are converted into their hex equivalent so that + they don't gum up the works. The whole data string might look + something like:

    + + + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey + + +

    You'll sometimes also see this type of string appended to + a URL. When that is done, the server puts that string + into the environment variable called + QUERY_STRING. That's called a GET + request. Your HTML form specifies whether a GET + or a POST is used to deliver the data, by setting the + METHOD attribute in the FORM tag.

    + +

    Your program is then responsible for splitting that string + up into useful information. Fortunately, there are libraries + and modules available to help you process this data, as well + as handle other of the aspects of your CGI program.

    +
    +
    + +
    + CGI modules/libraries + +

    When you write CGI programs, you should consider using a + code library, or module, to do most of the grunt work for you. + This leads to fewer errors, and faster development.

    + +

    If you're writing CGI programs in Perl, modules are + available on CPAN. The most + popular module for this purpose is CGI.pm. You might + also consider CGI::Lite, which implements a minimal + set of functionality, which is all you need in most programs.

    + +

    If you're writing CGI programs in C, there are a variety of + options. One of these is the CGIC library, from + http://www.boutell.com/cgic/.

    +
    + +
    + For more information + +

    There are a large number of CGI resources on the web. You + can discuss CGI problems with other users on the Usenet group + comp.infosystems.www.authoring.cgi. And the -servers mailing + list from the HTML Writers Guild is a great source of answers + to your questions. You can find out more at + http://www.hwg.org/lists/hwg-servers/.

    + +

    And, of course, you should probably read the CGI + specification, which has all the details on the operation of + CGI programs. You can find the original version at the + NCSA and there is an updated draft at the + Common Gateway + Interface RFC project.

    + +

    When you post a question about a CGI problem that you're + having, whether to a mailing list, or to a newsgroup, make sure + you provide enough information about what happened, what you + expected to happen, and how what actually happened was + different, what server you're running, what language your CGI + program was in, and, if possible, the offending code. This will + make finding your problem much simpler.

    + +

    Note that questions about CGI problems should never + be posted to the Apache bug database unless you are sure you + have found a problem in the Apache source code.

    +
    +
    + diff --git a/trunk/docs/manual/howto/cgi.xml.ja b/trunk/docs/manual/howto/cgi.xml.ja new file mode 100644 index 0000000000..aa1a406137 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.xml.ja @@ -0,0 +1,553 @@ + + + + + + + + + How-To / $B%A%e!<%H%j%"%k(B + + Apache Tutorial: CGI $B$K$h$kF0E*%3%s%F%s%D(B + +
    + $B$O$8$a$K(B + + + + mod_alias + mod_cgi + + + + AddHandler + Options + ScriptAlias + + + +

    CGI (Common Gateway Interface) $B$O!"%&%'%V%5!<%P$,(B + $B%3%s%F%s%D@8@.$r$9$k30It%W%m%0%i%`$H6(D4$7$FF0:n$9$k$?$a$NJ}K!$r(B + $BDj5A$7$F$$$^$9!#$=$N%W%m%0%i%`$O$7$P$7$P(B CGI $B%W%m%0%i%`$d(B + CGI $B%9%/%j%W%H$H8F$P$l$^$9!#(BCGI $B$O!"%&%'%V%5%$%H$KF0E*$J(B + $B%3%s%F%s%D$rCV$/$?$a$N:G$b4JC1$G0lHLE*$JJ}K!$G$9!#$3$N%I%-%e%a%s%H$O!"(B + Apache $B%&%'%V%5!<%P$G(B CGI $B$r@_Dj$7!"(B + CGI $B%W%m%0%i%`$r=q$-;O$a$k$?$a$NF~Lg=q$H$J$k$G$7$g$&!#(B

    +
    + +
    + CGI $B$r5v2D$9$k$h$&$K(B Apache $B$r@_Dj$9$k(B + +

    CGI $B%W%m%0%i%`$r@5$7$/F0:n$5$;$k$K$O!"(BCGI $B$r5v2D$9$k$h$&$K(B + Apache $B$N@_Dj$r9T$&I,MW$,$"$j$^$9!#(B + $B$3$l$r9T$J$&$?$a$NJ}K!$,$$$/$D$+$"$j$^$9!#(B

    + +
    + ScriptAlias + +

    ScriptAlias + $B%G%#%l%/%F%#%V$r;HMQ$7$F!"(B + CGI $B%W%m%0%i%`MQ$NFCJL$JJL%G%#%l%/%H%j$r(B Apache $B$K@_Dj$7$^$9!#(B + Apache $B$O!"$3$N%G%#%l%/%H%jCf$NA4$F$N%U%!%$%k$r(B CGI + $B%W%m%0%i%`$G$"$k$H2>Dj$7$^$9!#(B + $B$=$7$F!"$3$NFCJL$J%j%=!<%9$,%/%i%$%"%s%H$+$iMW5a$5$l$k$H!"(B + $B$=$N%W%m%0%i%`$N + +

    ScriptAlias + $B%G%#%l%/%F%#%V$O0J2<$N$h$&$K;HMQ$7$^$9(B:

    + + + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ + + +

    $B%G%U%)%k%H0LCV$K(B Apache $B$r%$%s%9%H!<%k$7$?$J$i$P!"(B + $B$3$NNc$O%G%U%)%k%H>uBV$N(B httpd.conf + $B@_Dj%U%!%$%k$K4^$^$l$F$$$^$9!#(B + ScriptAlias + $B%G%#%l%/%F%#%V$O!"(BURL $B$NA0$KIU2C$9$k%G%#%l%/%H%j$rDj5A$9$k(B + Alias + $B%G%#%l%/%F%#%V$H$+$J$j;w$F$$$^$9!#(B + Alias $B$H(B ScriptAlias + $B$ODL>o!"(BDocumentRoot + $B%G%#%l%/%H%j30$N%G%#%l%/%H%j$N$?$a$K;HMQ$5$l$^$9!#(B + Alias $B$H(B ScriptAlias + $B$H$N:9$O!"(BScriptAlias $B$,@\F,<-$G;O$^$k$9$Y$F$N(B + URL $B$O(B CGI $B%W%m%0%i%`$H$_$J$5$l$k$H$$$&DI2C$N0UL#$r4^$s$G$$$k$3$H$G$9!#(B + $B=>$C$F!">e5-$NNc$G$O!"(B/cgi-bin/ + $B$G;O$^$k%j%=!<%9$X$N$"$i$f$k%j%/%(%9%H$KBP$7$F!"%G%#%l%/%H%j(B + /usr/local/apache2/cgi-bin/ $B$+$iDs6!$7!"$=$l$i$r(B + CGI $B%W%m%0%i%`$H$7$F07$&$h$&(B Apache $B$K<($7$^$9!#(B

    + +

    $BNc$($P!"(BURL http://dev.rcbowen.com/cgi-bin/test.pl + $B$,MW5a$5$l$?>l9g!"(BApache $B$O(B $B%U%!%$%k(B + /usr/local/apache2/cgi-bin/test.pl + $B$r +

    + +
    + ScriptAlias $B%G%#%l%/%H%j30$N(B CGI + +

    CGI $B%W%m%0%i%`$O!"%;%-%e%j%F%#>e$NM}M3$+$i(B + ScriptAlias + $B$5$l$?%G%#%l%/%H%j$K@)8B$5$l$k$3$H$,$7$P$7$P$"$j$^$9!#$3$NJ}K!$K$h$j!"(B + CGI $B%W%m%0%i%`$r;HMQ$G$-$k%f!<%6$r4IM}UserDir + $B%G%#%l%/%F%#%V$GH`$i$N%[!<%`%G%#%l%/%H%jG[2<$K%&%'%V%3%s%F%s%D$r;}$?$;$?$$$H$7$^$9!#(B + $B$b$7!"H`$i$,(B CGI $B%W%m%0%i%`$r;}$D$3$H$rK>$s$G$$$F$b!"%a%$%s$N(B + cgi-bin $B%G%#%l%/%H%j$X$N%"%/%;%9$,$G$-$J$$>l9g!"(B + CGI $B%W%m%0%i%`$r$N>l=j$,I,MW$K$J$j$^$9!#(B

    + +

    $BG$0U$N%G%#%l%/%H%j$G(B CGI $B$NAddHandler $B$d(B SetHandler $B%G%#%l%/%F%#%V$K$h$C$F(B + cgi-script $B%O%s%I%i$,2DG=$K$J$C$F$$$kI,MW$,$"$j$^$9!#(B + $BOptions $B%G%#%l%/%F%#%V$G(B + ExecCGI $B$,;XDj$5$l$F$$$J$1$l$P$J$j$^$;$s!#(B

    +
    + +
    + CGI $B$N<B9T$r2DG=$K$9$k$?$a$K(B Options $B$rL@<(E*$K;HMQ$9$k(B + +

    $B%5!<%P$N%a%$%s$N@_Dj%U%!%$%kCf$G(B Options + $B%G%#%l%/%F%#%V$rL@<(E*$K;HMQ$9$k$3$H$G!"FCDj$N%G%#%l%/%H%jG[2<$G(B + CGI $B$N + + + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +
    + +

    $B>e5-%G%#%l%/%F%#%V$O!"(BCGI $B%U%!%$%k$NAddHandler + $B%G%#%l%/%F%#%V$NNc$G$O!"(Bcgi $B$^$?$O(B pl + $B$r3HD%;R$K;}$D$9$Y$F$N%U%!%$%k$r(B CGI + $B%W%m%0%i%`$H$7$F$_$J$9$3$H$r%5!<%P$KEA$($^$9(B:

    + + + AddHandler cgi-script .cgi .pl + +
    + +
    + .htaccess files + +

    .htaccess $B%A%e!<%H%j%"%k(B + $B$O(B httpd.conf $B$rJQ99$G$-$J$$>l9g$K$I$&$d$C$F(B CGI $B%W%m%0%i%`$r(B + $B;H$($k$h$&$K$9$k$+$r@bL@$7$F$$$^$9!#(B

    +
    + +
    + User $B%G%#%l%/%H%j(B + +

    .cgi $B$G=*$o$k$9$Y$F$N%U%!%$%k$KBP$7$F(B CGI $B%W%m%0%i%`$N(B + $B + + + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +
    + +

    $B%f!<%6%G%#%l%/%H%j$N(B cgi-bin $B%5%V%G%#%l%/%H%j$N(B + $B$9$Y$F$N%U%!%$%k$r(B CGI $B%W%m%0%i%`$H$7$F;XDj$7$?$$>l9g$K$O(B + $B0J2<$N$h$&$J$b$N$r;H$$$^$9!#(B

    + + + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +
    + +
    +
    + +
    + CGI $B%W%m%0%i%`$r=q$/(B + +

    $B!VDL>o$N!W%W%m%0%i%_%s%0$H(B CGI + $B%W%m%0%i%_%s%0$N4V$K$O + +

    $B0l$D$O!"(BCGI $B%W%m%0%i%`$N$9$Y$F$N=PNO$K$O(B MIME-type + $B%X%C%@$rIU$1$J$1$l$P$J$j$^$;$s!#(B + $B$3$l$O$I$N$h$&$Jl9g$G$O!" + + + Content-type: text/html + + +

    $B$b$&0l$D$O!"=PNO$r(B HTML + $B$+!"%V%i%&%6$,I=<($9$k$3$H$,$G$-$k2?$+B>$N7A<0$K$9$kI,MW$,$"$j$^$9!#(B + $BBgDq$N>l9g$O(B HTML $B$G$7$g$&$,!"(BGIF $B%$%a!<%8$dB>$NHs(B HTML + $B%3%s%F%s%D$r=PNO$9$k(B CGI $B%W%m%0%i%`$r=q$/$3$H$b$"$k$G$7$g$&!#(B

    + +

    $B$3$l$iFsE@0J30$G$O!"(BCGI $B%W%m%0%i%`$r=q$/$3$H$O!"(B + $B$"$J$?$,=q$$$F$$$kB>$N%W%m%0%i%`$H$h$/;w$F$$$k$G$7$g$&!#(B

    + +
    + $B:G=i$N(B CGI $B%W%m%0%i%`(B + +

    $Bfirst.pl + $B$H$$$&%U%!%$%k$KJ]B8$7!"$=$l$r(B cgi-bin + $B%G%#%l%/%H%j$KCV$$$F$/$@$5$$!#(B

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +
    + +

    Perl $B$K@:DL$7$F$$$J$/$F$b!"(B + $B2?$,5/$3$k$+$rM}2r$9$k$3$H$O$G$-$k$G$7$g$&!#(B1 $B9TL\$O!"(B + /usr/bin/perl $B$G8+$D$1$i$l$k%$%s%?%W%j%?$K(B + $B$3$N%U%!%$%k$r6!5k$9$k$3$H$G$3$N%W%m%0%i%`$,e$G + +

    $B9%$_$N%V%i%&%6$r3+$-!"%"%I%l%9(B

    + + + http://www.example.com/cgi-bin/first.pl + + +

    $B$"$k$$$O%U%!%$%k$rCV$$$?%m%1!<%7%g%s$r;XDj$9$k$H!"(B + Hello, World. + $B$H$$$&(B 1 $B9T$,%V%i%&%6%&%#%s%I$K8=$l$k$G$7$g$&!#(B + $B$=$l$O$"$^$j%(%-%5%$%F%#%s%0$J$3$H$G$O$"$j$^$;$s!#(B + $B$7$+$7!"$3$l$,$&$^$/F0$1$P!"(B + $BB>$N$I$N$h$&$J$b$N$G$bF0$+$9$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B

    +
    +
    + +
    + $B$7$+$7!"$^$@F0$+$J$$(B ! + +

    $B%&%'%V$+$i(B CGI $B%W%m%0%i%`$X$N%"%/%;%9$r9T$J$C$?$H$-!"(B + $B%V%i%&%6$G8+$k2DG=@-$,$"$k;M$D$N4pK\E*$J$3$H$,$"$j$^$9(B:

    + +
    +
    CGI $B%W%m%0%i%`$N=PNO(B
    +
    $BAG@2$i$7$$(B ! $B$=$l$O$9$Y$F$,$&$^$/F0$$$?$3$H$r0UL#$7$^$9!#(B + $B=PNO$,@5>o$@$1$l$I$b!"%V%i%&%6$,@5>o$K=hM}$7$F$/$l$J$$>l9g$O!"(B + $B@5$7$$(B Content-Type $B$r(B CGI $B%W%m%0%i%`Fb$G(B + $B%;%C%H$7$?$+$r3NG'$7$F$/$@$5$$!#(B
    + +
    CGI $B%W%m%0%i%`$N%=!<%9%3!<%I!"$^$?$O(B "POST Method Not Allowed" + $B$H$$$&%a%C%;!<%8(B
    +
    $B$3$l$O!"(BCGI $B%W%m%0%i%`$r=hM}$G$-$k$h$&(B Apache + $B$rE,@Z$K@_Dj$7$F$$$J$+$C$?$3$H$r0UL#$7$^$9!#(B$B!V(BCGI $B$r5v2D$9$k$h$&$K(B + Apache $B$r@_Dj$9$k!W(B$B$N>O$rFI$_D>$7!"(B + $B$"$J$?$,2?$r4V0c$($?$+$rC5$7$F$_$F$/$@$5$$!#(B +
    + +
    $B%a%C%;!<%8$,(B "Forbidden" $B$G;O$^$C$F$$$k(B
    +
    $B$3$l$O%Q!<%_%C%7%g%s$NLdBj$H$$$&$3$H$r0UL#$7$^$9!#(B + Apache $B$N%(%i!<%m%0(B$B$H!"8e=R$N(B$B!V%U%!%$%k$N%Q!<%_%C%7%g%s!W(B + $B$N>O$r%A%'%C%/$7$F$/$@$5$$!#(B +
    + +
    "Internal Server Error" $B$H$$$&%a%C%;!<%8(B
    +
    Apache + $B$N%(%i!<%m%0(B$B$r%A%'%C%/$9$k$H!"(B"Premature end of script headers" + $B$H$$$&%m%0$,5-O?$5$l$F$$$k$H;W$$$^$9!#$=$7$F!"$*$=$i$/(B CGI + $B%W%m%0%i%`$K$h$C$F@8@.$5$l$?%(%i!<%a%C%;!<%8$b5-O?$5$l$F$$$k$G$7$g$&!#(B + $B$3$N>l9g!"(BCGI $B%W%m%0%i%`$,E,@Z$J(B + HTTP $B%X%C%@$r=PNO$G$-$J$$860x$rCN$k$?$a$K!"(B + $B0J2<$N3F>O$G%A%'%C%/$7$F$_$F$/$@$5$$!#(B
    +
    + +
    + $B%U%!%$%k$N%Q!<%_%C%7%g%s(B + +

    $B%5!<%P$O$"$J$?$N8"8B$Go(B nobody + $B$d(B www $B$N8"8B$Go!"(Bnobody $B$, + + + chmod a+x first.pl + + +

    $B$^$?!"$b$7$"$J$?$N%W%m%0%i%`$,B>$N%U%!%$%k$rFI$_=q$-$9$k$J$i$P!"(B + $B$=$l$i$N%U%!%$%k$O!"$3$l$,2DG=$H$J$k@5$7$$%Q!<%_%C%7%g%s(B + $B$r;}$C$F$$$kI,MW$,$"$j$^$9!#(B

    + +
    + +
    + $B%Q%9>pJs$H4D6-(B + +

    $B%3%^%s%I%i%$%s$+$i%W%m%0%i%`$rpJs$,$"$j$^$9!#(B + $BNc$($P!";2>H$9$k%U%!%$%k$N$?$a$K$I$3$r8!:w$7$?$i$h$$$+$r(B + $B%7%'%k$KEA$($k(B PATH $B$,$"$j$^$9!#(B

    + +

    $B%W%m%0%i%`$,(B CGI $B%W%m%0%i%`$H$7$F%&%'%V%5!<%P$K$h$C$FPATH $B$G$O$J$$$+$b$7$l$^$;$s!#(B + CGI $B%W%m%0%i%`Fb$G8F$S=P$9$"$i$f$k%W%m%0%i%`(B + ($BNc$($P!"(Bsendmail $B$N$h$&$J$b$N(B) $B$O!"(B + $B%U%k%Q%9$G;XDj$9$kI,MW$,$"$k$G$7$g$&!#$=$l$K$h$j!"(BCGI + $B%W%m%0%i%`$r + +

    $BF1MM$J$3$H$O!"%9%/%j%W%H$N%$%s%?%W%j%?(B ($B$7$P$7$P(B perl) + $B$X$N%Q%9$G!"(BCGI $B%W%m%0%i%`$N(B 1 $B9TL\$K + + + #!/usr/bin/perl + + +

    $B$3$l$,%$%s%?!<%W%j%?$X$N +

    + +
    + $B%W%m%0%i%`%(%i!<(B + +

    CGI + $B%W%m%0%i%`$,<:GT$9$k$N$OBgDq!"%W%m%0%i%`<+?H$KLdBj$,$"$k>l9g$G$9!#(B + $B0lEY(B CGI $B$N;H$$J}$rM}2r$7!"A0=R$NFs$D$N8m$j$rHH$7$F$$$J$$$J$i$P!"(B + $B$^$:4V0c$$$J$/$=$&$G$7$g$&!#%V%i%&%6$r;H$C$F%F%9%H$9$kA0$K(B + $B$^$:3NG'$9$k$3$H$O!"%3%^%s%I%i%$%s$+$i%W%m%0%i%`$, + + + cd /usr/local/apache2/cgi-bin
    + ./first.pl +
    + +

    (perl $B%$%s%?%W%j%?$O8F$P$J$$$G$/$@$5$$!#(B + $B%7%'%k$H(B Apache $B$,%9%/%j%W%H$N:G=i$N9T$N(B $B%Q%9>pJs(B $B$r;H$C$F8+$D$1$^$9!#(B)

    + +

    $B:G=i$K%W%m%0%i%`$+$i=PNO$5$l$k$N$O(B Content-Type $B$r4^$_!"(B + $B8e$K6u9T$NB3$/(B HTTP $B%X%C%@$G$J$1$l$P$J$j$^$;$s!#B>$N$b$N$,=PNO$5$l$F$$$k(B + $B>l9g$O!"(BApache $B$O$3$N%W%m%0%i%`$r%5!<%P7PM3$GPremature end of script headers $B%(%i!<$r=PNO$7$^$9!#>\:Y$O(B + $B>e5-$N(B CGI $B%W%m%0%i%`$r=q$/(B $B$rFI$s$G$/$@$5$$!#(B

    +
    + +
    + $B%(%i!<%m%0(B + +

    $B%(%i!<%m%0$OM'C#$G$9!#(B + $BA4$F$N$&$^$/$$$+$J$$$3$H$O!"%(%i!<%m%0$K%a%C%;!<%8$r@8@.$7$^$9!#(B + $BI,$:$=$l$r:G=i$K8+$k$Y$-$G$9!#(B + $B$b$7!"$"$J$?$,%&%'%V%5%$%H$rl=j$,(B + $B%(%i!<%m%0$N;2>H$r5v$7$F$$$J$$$J$i$P!"$-$C$HB>$N%5%$%H$G +

    + +
    + Suexec + +

    suexec $B%5%]!<%H%W%m%0%i%`$O(B + $B%P!<%A%c%k%[%9%H$d%f!<%6$N%[!<%`%G%#%l%/%H%j$N>l=j$K0M$C$F(B + CGI $B%W%m%0%i%`$r0c$&%f!<%68"8B$N2<$GAv$i$;$k$3$H$r2DG=$K$7$^$9!#(B + Suexec $B$N8"8B$N%A%'%C%/$OHs>o$K87$7$/!"$=$l$rK~$?$5$J$$>l9g$O(B + CGI $B%W%m%0%i%`$,(B Premature end of script headers $B%(%i!<$G(B + $B + +

    suexec $B$r;H$C$F$$$k$+$I$&$+$rD4$Y$?$a$K$O(B apachectl + -V $B$rSUEXEC_BIN $B$N>l=j$rD4$Y$F$/$@$5$$!#(B + Apache $B$,$=$3$K(B suexec $B$N%P%$%J%j$rH/8+$7$?>l9g$O!"(Bsuexec $B$,(B + $B;HMQ$5$l$^$9!#(B

    + +

    suexec $B$r40A4$KM}2r$7$F$$$J$$8B$j!";H$&$Y$-$G$O$"$j$^$;$s!#(B + suexec $B$rL58z$K$9$k$K$O!"(BSUEXEC_BIN $B$+$i;X$5$l$F$$$k(B + suexec $B%P%$%J%j$r:o=|(B ($B$+L>A0$rJQ99(B) $B$9$k$@$1$G$9!#(B + suexec $B$rFI$s$@8e$G!"$^$@$=$l$r(B + $B;H$$$?$$$N$G$"$l$P!"(Bsuexec -V $B$r +

    +
    + +
    + $BN"$G2?$,5/$3$C$F$$$k$N$+(B? + +

    CGI $B%W%m%0%i%_%s%0$K=,=O$9$k$H!"(B + $BN"$G5/$3$C$F$$$k$3$H$K$D$$$F99$KM}2r$9$k$3$HLr$KN)$A$^$9!#(B + $B%V%i%&%6$H%5!<%P$,$I$N$h$&$KAj8_DL?.$9$k$+$K$D$$$F$OFC$K$=$&$G$9!#(B + $B$J$<$J$i!"(B"Hello, World." + $B$r0u;z$9$k%W%m%0%i%`$r=q$/$3$H$O$*$*$$$K7k9=$G$9$,!"(B + $B$=$l$OFC$KM-1W$G$O$"$j$^$;$s!#(B

    + +
    + $B4D6-JQ?t(B + +

    $B4D6-JQ?t$O!"(B + $B$"$J$?$,%3%s%T%e!<%?$r;H$&$H$-$KJU$j$KB8:_$7$F$$$kCM$G$9!#(B + $B$=$l$i$O!"%Q%9(B + ($B%3%^%s%I$r%?%$%W$7$?$H$-$K!"Co!"IaCJ;HMQ$7$F$$$k4D6-JQ?t$N40A4$J%j%9%H$rD4$Y$k$K$O!"(B + $B%3%^%s%I%W%m%s%W%H$G(B env $B$rF~NO$7$^$9!#(B

    + +

    CGI $B$N=hM}Cf!"%5!<%P$H%V%i%&%6$b4D6-JQ?t$r@_Dj$7!"(B + $B$=$l$K$h$jAj8_$KDL?.$9$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B + $B$=$N4D6-JQ?t$O!"%V%i%&%6%?%$%W(B (Netscape, IE, Lynx)$B!"%5!<%P%?%$%W(B + (Apache, IIS, WebSite)$B!"A0$J$I$G$9!#(B

    + +

    $B$3$l$i$NJQ?t$O(B CGI $B%W%m%0%i%^$,;HMQ$G$-$^$9!#(B + $B$=$7$F!"$=$l$O%/%i%$%"%s%H$H%5!<%P$NDL?.$NOC$NH>J,$G$9!#(B + $BI,MW$JJQ?t$N40A4$J%j%9%H$O(B http://hoohoo.ncsa.uiuc.edu/cgi/env.html $B$K$"$j$^$9!#(B

    + +

    $B0J2<$NC1=c$J(B Perl CGI + $B%W%m%0%i%`$O!"EO$5$l$kA4$F$N4D6-JQ?t$rI=<($7$^$9!#F1MM$N%W%m%0%i%`$O!"(B + Apache $B%G%#%9%H%j%S%e!<%7%g%s$N(B cgi-bin + $B%G%#%l%/%H%j$KFs$D4^$^$l$F$$$^$9!#(B + $B$$$/$D$+$NJQ?t$,I,?\$G$"$j!"$$$/$D$+$OG$0U$G$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$=$7$F!"8x<0$N%j%9%H$K$O$J$$$$$/$D$+$NJQ?t$,I=<($5$l$F$$$k$+$b$7$l$^$;$s!#(B + $B$5$i$K!"(BApache $B$O%G%U%)%k%H$GMQ0U$5$l$F$$$k4pK\E*$J$b$N$K(B + $B$"$J$?<+?H$N4D6-JQ?t$r2C$($k(B$B$?$a$N!"(B + $BB?$/$N0[$J$kJ}K!$rMQ0U$7$F$7$^$9!#(B

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +
    +
    + +
    + STDIN $B$H(B STDOUT + +

    $B%5!<%P$H%/%i%$%"%s%H4V$N$b$&0l$D$NDL?.$O!"I8=`F~NO(B + (STDIN)$B$HI8=`=PNO(B (STDOUT) + $B$rDL$8$F9T$J$o$l$^$9!#DL>o$NJ8L.$K$*$$$F!"(BSTDIN + $B$O%-!<%\!<%I$d%W%m%0%i%`$,F0:n$9$k$?$a$KM?$($i$l$k%U%!%$%k$r0UL#$7!"(B + STDOUT $B$ODL>o%3%s%=!<%k$^$?$O%9%/%j!<%s$r0UL#$7$^$9!#(B

    + +

    $B%&%'%V%U%)!<%`$+$i(B CGI $B%W%m%0%i%`$X(BPOST + $B$7$?$H$-!"%U%)!<%`$N%G!<%?$OFCJL$J%U%)!<%^%C%H$GB+$M$i$l!"(B + STDIN $B$rDL$7$F!"(BCGI $B%W%m%0%i%`$K0z$-EO$5$l$^$9!#(B + $B%W%m%0%i%`$O%G!<%?$,%-!<%\!<%I(B + $B$b$7$/$O%U%!%$%k$+$iMh$F$$$?$+$N$h$&$K=hM}$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B!VFCJL$J%U%)!<%^%C%H!W$O$H$F$bC1=c$G$9!#%U%#!<%k%IL>$HCM$O%$%3!<%k(B + (=) $B$G7k$P$l$^$9!#$=$7$FCM$NAH$O%"%s%Q%5%s%I(B (&) $B$G7k$P$l$^$9!#(B + $B%9%Z!<%9!"%"%s%Q%5%s%I!"%$%3!<%k$N$h$&$JLLE]$JJ8;z$O!"(B + $B$=$l$i$,F0:n$rBLL\$K$7$J$$$h$&$K$=$NJ8;z$KAjEv$9$k(B 16 $B?J$KJQ49$5$l$^$9!#(B + $BA4%G!<%?J8;zNs$O!"0J2<$N$h$&$K$J$j$^$9(B: +

    + + + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey + + +

    $B;~!9!"$3$N$h$&$JJ8;zNs$,(B URL + $B$KIU2C$5$l$k$N$r8+$k$G$7$g$&!#$=$N>l9g!"%5!<%P$O(B + QUERY_STRING $B$H$$$&4D6-JQ?t$K$=$NJ8;zNs$rF~$l$^$9!#$=$l$O(B + GET $B%j%/%(%9%H$H8F$P$l$^$9!#(B + HTML $B%U%)!<%`$G$O!"%G!<%?$rEO$9$?$a$K(B GET $B$H(B + POST $B$N$I$A$i$r;HMQ$9$k$+$r!"(BFORM $B%?%0$N(B + METHOD $BB0@-$N@_Dj$G;XDj$7$^$9!#(B

    + +

    CGI $B%W%m%0%i%`$O!"$=$NJ8;zNs$rLr$KN)$D>pJs$KJ,3d$9$k@UG$$,$"$j$^$9!#(B + $B9,$$$K$b!"$=$N%G!<%?=hM}$r=u$1$k%i%$%V%i%j$d%b%8%e!<%k$,B8:_$7$^$9!#(B + $B$3$l$i$O!"(BCGI $B%W%m%0%i%`$NB>$NLL$G$bF1MM$KLr$KN)$A$^$9!#(B

    +
    +
    + +
    + CGI $B%b%8%e!<%k(B/$B%i%$%V%i%j(B + +

    CGI $B%W%m%0%i%`$r=q$/$H$-!"LLE]$J;E;v$NBgItJ,$r$7$F$/$l$k(B + $B%3!<%I%i%$%V%i%j$^$?$O%b%8%e!<%k$r;H$&$3$H$r8!F$$9$Y$-$G$9!#(B + $B$3$l$O%(%i!<$r8:$i$7!"Aa$$3+H/$K$D$J$,$j$^$9!#(B

    + +

    Perl $B$G(B CGI $B%W%m%0%i%`$r=q$$$F$$$k$J$i!"%b%8%e!<%k$O(B CPAN $B$GDs6!$5$l$F$$$^$9!#(B + $B$3$NL\E*$N$?$a$N:G$bIa5Z$7$F$$$k%b%8%e!<%k$O(B CGI.pm $B$G$9!#(B + CGI::Lite $B$b8!F$$7$^$7$g$&!#$3$l$O!"$[$H$s$I$N%W%m%0%i%`(B + $B$K$*$$$FI,MW$H$9$k$9$Y$F$N5!G=$N:G>.%;%C%H$N + +

    C $B$G(B CGI $B%W%m%0%i%`$r=q$$$F$$$k$J$i!"$$$m$$$m$J(B + $B%*%W%7%g%s$,$"$j$^$9!#$3$l$i$NFb$N0l$D$O(B http://www.boutell.com/cgic/ + $B$GDs6!$5$l$F$$$k(B CGIC $B%i%$%V%i%j$G$9!#(B

    +
    + +
    + $B99$J$k>pJs(B + +

    CGI $B$K4X$9$k>pJs$O%&%'%V$G?tB?$/Ds6!$5$l$F$$$^$9!#(BCGI + $B$NLdBj$K$D$$$F$O(B Usenet $B$N(B comp.infosystems.www.authoring.cgi $B$G!"(B + $BB>$N%f!<%6$HO@5D$9$k$3$H$,$G$-$^$9!#(BHTML Writers Guide $B$N(B + -servers $B%a!<%j%s%0%j%9%H$O!"$"$J$?$Nhttp://www.hwg.org/lists/hwg-servers/ + $B$G99$KB?$/$rC5$7=P$9$3$H$,$G$-$^$9!#(B

    + +

    $B$=$7$F$b$A$m$s!"$*$=$i$/(B CGI + $B%W%m%0%i%`$NF0:n$K4X$9$k>\:Y$NA4$F$,5-=R$5$l$F$$$k(B + CGI $B$N;EMM$rFI$`$Y$-$G$9!#%*%j%8%J%k%P!<%8%g%s$r(B + NCSA + $B$G!"%"%C%W%G!<%H$5$l$?%I%i%U%H$r(B + Common Gateway Interface RFC + $B%W%m%8%'%/%H(B$B$G;2>H$9$k$3$H$,$G$-$^$9!#(B

    + +

    CGI $B$NLdBj$K$D$$$F!"2C$o$C$F$$$k%a!<%j%s%0%j%9%H$^$?$O%K%e!<%9(B + $B%0%k!<%W$KpJs$H!"(B + $B2DG=$G$"$l$PLdBj$N%3!<%I$rDs6!$9$k$h$&$K$7$F$/$@$5$$!#(B + $B$=$&$9$k$3$H$G!"LdBj$,$h$j4VC1$K8+$D$+$k$h$&$K$J$j$^$9!#(B

    + +

    Apache $B$N%=!<%9%3!<%I$K$*$$$FLdBj$rH/8+$7$?$3$H$r3N?.$7$F$$$J$$8B$j!"(B + CGI $B$NLdBj$K4X$9$k$BAw$k$Y$-$G$J$$(B + $B$3$H$KCmL\$7$F$/$@$5$$!#(B

    +
    +
    + diff --git a/trunk/docs/manual/howto/cgi.xml.ko b/trunk/docs/manual/howto/cgi.xml.ko new file mode 100644 index 0000000000..db7bc18622 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.xml.ko @@ -0,0 +1,519 @@ + + + + + + + + + How-To / Tutorials + + ¾ÆÆÄÄ¡ ÅõÅ丮¾ó: CGI¸¦ »ç¿ëÇÑ µ¿Àû ÆäÀÌÁö »ý¼º + +
    + ¼Ò°³ + + + + mod_alias + mod_cgi + + + + AddHandler + Options + ScriptAlias + + + +

    CGI (Common Gateway Interface)´Â À¥¼­¹ö°¡ º¸Åë CGI ÇÁ·Î±×·¥ + ȤÀº CGI ½ºÅ©¸³Æ®¶ó°í ºÎ¸£´Â, (À¥ÆäÀÌÁö ³»¿ëÀ» ¸¸µå´Â) ¿ÜºÎ + ÇÁ·Î±×·¥°ú Åë½ÅÇÏ´Â ¹æ¹ýÀ» Á¤ÀÇÇÑ´Ù. À¥»çÀÌÆ®¿¡¼­ µ¿ÀûÀÎ + ÆäÀÌÁö¸¦ ¸¸µå´Â °¡Àå ÈçÇÏ°í °£´ÜÇÑ ¹æ¹ýÀÌ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ + À¥¼­¹ö¿¡ CGI¸¦ ±¸¼ºÇÏ´Â ¹æ¹ýÀ» ¼Ò°³ÇÏ°í, CGI ÇÁ·Î±×·¥À» + ÀÛ¼ºÇغ»´Ù.

    +
    + +
    + CGI¸¦ Çã¿ëÇϵµ·Ï ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ + +

    CGI ÇÁ·Î±×·¥ÀÌ ¿Ã¹Ù·Î µ¿ÀÛÇÏ·Á¸é CGI ½ÇÇàÀÌ °¡´ÉÇϵµ·Ï + ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. ¼³Á¤ÇÏ´Â ¹æ¹ýÀº ¿©·¯°¡Áö´Ù.

    + +
    + ScriptAlias + +

    ScriptAlias + Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â ƯÁ¤ µð·ºÅ丮¸¦ CGI ÇÁ·Î±×·¥¿ëÀ¸·Î + µÐ´Ù. ¾ÆÆÄÄ¡´Â ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀÌ CGI + ÇÁ·Î±×·¥À̶ó°í °¡Á¤ÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ ÀÚ¿øÀ» ¿äûÇϸé ÀÚ¿øÀ» + ½ÇÇàÇÏ·Á°í ½ÃµµÇÑ´Ù.

    + +

    ScriptAlias + Áö½Ã¾î´Â ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + + + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/ + + +

    À§ ¿¹Á¦´Â ¾ÆÆÄÄ¡¸¦ ±âº» Àå¼Ò¿¡ ¼³Ä¡ÇÑ °æ¿ì + httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â ³»¿ëÀÌ´Ù. ScriptAlias Áö½Ã¾î´Â Alias Áö½Ã¾î¿Í °°ÀÌ URL + ¾ÕºÎºÐÀ» ƯÁ¤ µð·ºÅ丮·Î ´ëÀÀÇÑ´Ù. + Alias¿Í + ScriptAlias´Â º¸Åë DocumentRoot µð·ºÅ丮 ¹Û¿¡ ÀÖ´Â + µð·ºÅ丮¿¡ »ç¿ëÇÑ´Ù. Alias¿Í + ScriptAliasÀÇ Â÷ÀÌÁ¡Àº + ScriptAlias°¡ Ãß°¡·Î URL ¾ÕºÎºÐÀ¸·Î + ½ÃÀÛÇÏ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î Ãë±ÞÇÏ´Â Á¡ÀÌ´Ù. + ±×·¡¼­ À§ÀÇ ¼³Á¤Àº ¾ÆÆÄÄ¡¿¡°Ô /cgi-bin/À¸·Î + ½ÃÀÛÇÏ´Â ÀÚ¿øÀ» ¿äûÇϸé + /usr/local/apache2/cgi-bin/ µð·ºÅ丮¿¡¼­ + ã¾Æ¼­ CGI ÇÁ·Î±×·¥À¸·Î ó¸®Ç϶ó°í ¾Ë¸°´Ù.

    + +

    ¿¹¸¦ µé¾î, URL + http://www.example.com/cgi-bin/test.plÀ» + ¿äûÇÏ¸é ¾ÆÆÄÄ¡´Â + /usr/local/apache2/cgi-bin/test.pl ÆÄÀÏÀ» + ½ÇÇàÇÏ¿© °á°ú¸¦ ¹ÝȯÇÑ´Ù. ¹°·Ð ÆÄÀÏÀÌ Á¸ÀçÇÏ°í ½ÇÇà°¡´ÉÇϸç + ¾î¶² ¹æ¹ýÀ¸·Îµç Ãâ·ÂÀ» ÇØ¾ß ÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ¾ÆÆÄÄ¡´Â + ¿À·ù¹®À» º¸³½´Ù.

    +
    + +
    + ScriptAlias µð·ºÅ丮 ¹Û¿¡ ÀÖ´Â CGI + +

    º¸Åë º¸¾È»ó ÀÌÀ¯¶§¹®¿¡ CGI ÇÁ·Î±×·¥Àº ScriptAliasÇÑ µð·ºÅ丮¿¡ + ÇÑÁ¤ÇÑ´Ù. ±×·¡¼­ °ü¸®ÀÚ´Â ´©°¡ CGI ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö + ÀÖ´ÂÁö ¾ö°ÝÈ÷ °¨µ¶ÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Àû´çÇÑ º¸¾ÈÁ¶Ä¡¸¦ + ÃëÇß´Ù¸é ¾Æ¹« µð·ºÅ丮¿¡¼­³ª CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö ¾ÊÀ» + ÀÌÀ¯°¡ ¾ø´Ù. ¿¹¸¦ µé¾î, UserDir Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ È¨µð·ºÅ丮¿¡ À¥ÆäÀÌÁö¸¦ °¡Áö´Â °æ¿ì¸¦ + °¡Á¤ÇÏÀÚ. »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ CGI ÇÁ·Î±×·¥À» »ç¿ëÇÏ°í ½ÍÀºµ¥ + cgi-bin µð·ºÅ丮¿¡ Á¢±Ù±ÇÇÑÀÌ ¾ø´Ù¸é, ´Ù¸¥ + °÷¿¡¼­¶óµµ CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏ°í ½ÍÀ» °ÍÀÌ´Ù.

    + +

    ¾Æ¹« µð·ºÅ丮¿¡¼­³ª CGI ½ÇÇàÀ» Çã¿ëÇÏ·Á¸é µÎ °úÁ¤ÀÌ + ÇÊ¿äÇÏ´Ù. ¸ÕÀú, AddHandler³ª SetHandler Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + cgi-script Çڵ鷯¸¦ ÀÛµ¿ÇØ¾ß ÇÑ´Ù. µÎ¹ø°·Î, + Options Áö½Ã¾î¿¡ + ExecCGI¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    +
    + +
    + Options¸¦ »ç¿ëÇÏ¿© ¸í½ÃÀûÀ¸·Î CGI ½ÇÇàÀ» Çã¿ëÇϱâ + +

    ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏ¿¡ Á÷Á¢ Options Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ƯÁ¤ + µð·ºÅ丮¿¡¼­ CGI ½ÇÇàÀ» Çã¿ëÇÒ ¼ö ÀÖ´Ù.

    + + + <Directory /usr/local/apache2/htdocs/somedir>
    + + Options +ExecCGI
    +
    + </Directory> +
    + +

    À§ Áö½Ã¾î·Î ¾ÆÆÄÄ¡´Â CGI ÆÄÀÏÀÇ ½ÇÇàÀ» Çã¿ëÇÑ´Ù. ¾î¶² + ÆÄÀÏÀÌ CGI ÆÄÀÏÀÎÁöµµ ¼­¹ö¿¡°Ô ¾Ë·Á¾ß ÇÑ´Ù. ´ÙÀ½ AddHandler Áö½Ã¾î´Â ¼­¹ö¿¡°Ô + È®ÀåÀÚ°¡ cgi³ª plÀÎ ÆÄÀÏÀº ¸ðµÎ + CGI ÇÁ·Î±×·¥À̶ó°í ¾Ë¸°´Ù.

    + + + AddHandler cgi-script .cgi .pl + +
    + +
    + .htaccess ÆÄÀÏ + +

    .htaccess ÅõÅ丮¾óÀº + httpd.conf¿¡ Á¢±Ù±ÇÇÑÀÌ ¾ø´Â °æ¿ì¿¡ CGI ÇÁ·Î±×·¥À» + »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ¹ýÀ» ¾Ë·ÁÁØ´Ù.

    +
    + +
    + »ç¿ëÀÚ µð·ºÅ丮 + +

    ¾Æ·¡ ¼³Á¤À» »ç¿ëÇÏ¸é »ç¿ëÀÚ µð·ºÅ丮¿¡¼­ .cgi·Î + ³¡³ª´Â ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÑ´Ù.

    + + + <Directory /home/*/public_html>
    + + Options +ExecCGI
    + AddHandler cgi-script .cgi
    +
    + </Directory> +
    + +

    ´ÙÀ½À» »ç¿ëÇÏ¸é »ç¿ëÀÚ µð·ºÅ丮ÀÇ cgi-bin + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î ÀνÄÇÑ´Ù.

    + + + <Directory /home/*/public_html/cgi-bin>
    + + Options ExecCGI
    + SetHandler cgi-script
    +
    + </Directory> +
    + +
    + +
    + +
    + CGI ÇÁ·Î±×·¥ ÀÛ¼ºÇϱâ + +

    ``ÀϹÝÀûÀÎ'' ÇÁ·Î±×·¡¹Ö°ú CGI ÇÁ·Î±×·¡¹Ö »çÀÌ¿¡´Â µÎ°¡Áö + ÁÖµÈ Â÷ÀÌÁ¡ÀÌ ÀÖ´Ù.

    + +

    ù¹ø° Â÷ÀÌ´Â CGI ÇÁ·Î±×·¥Àº ´Ù¸¥ Ãâ·ÂÀ» ÇϱâÀü¿¡ ¸ÕÀú + MIME-type Çì´õ¸¦ Ãâ·ÂÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. HTTP Çì´õ´Â + Ŭ¶óÀ̾ðÆ®¿¡°Ô Ŭ¶óÀ̾ðÆ®°¡ ¾î¶² ³»¿ëÀ» ¹Þ°ÔµÉÁö ¹Ì¸® ¾Ë¸°´Ù. + º¸Åë ´ÙÀ½°ú °°´Ù.

    + + + Content-type: text/html + + +

    µÎ¹ø° Â÷ÀÌ´Â HTML ȤÀº ºê¶ó¿ìÀú°¡ º¸¿©ÁÙ ¼ö ÀÖ´Â Çü½ÄÀ¸·Î + Ãâ·ÂÇØ¾ß ÇÑ´Ù´Â Á¡ÀÌ´Ù. ´ëºÎºÐÀÇ °æ¿ì HTMLÀ» Ãâ·ÂÇÏÁö¸¸, + ¶§¶§·Î gif ±×¸²°ú °°ÀÌ HTMLÀÌ ¾Æ´Ñ ³»¿ëÀ» Ãâ·ÂÇÏ´Â CGI + ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ´Â °æ¿ìµµ ÀÖ´Ù.

    + +

    µÎ°¡Áö¸¦ Á¦¿ÜÇÏ°í´Â CGI ÇÁ·Î±×·¥ ÀÛ¼ºÀº ÀÌ¹Ì ¸¸µé¾î º¸¾ÒÀ» + ´Ù¸¥ ÇÁ·Î±×·¥µé°ú ¸Å¿ì ºñ½ÁÇÏ´Ù.

    + +
    + óÀ½À¸·Î ¸¸µç CGI ÇÁ·Î±×·¥ + +

    ´ÙÀ½Àº ºê¶ó¿ìÀú¿¡ ÇÑ ÁÙÀ» Âï´Â CGI ÇÁ·Î±×·¥ ¿¹Á¦´Ù. + ±×´ë·Î first.plÀ̶ó´Â ÆÄÀÏ¿¡ ÀúÀåÇÏ°í, + cgi-bin µð·ºÅ丮¿¡ º¹»çÇÑ´Ù.

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + print "Hello, World."; +
    + +

    Perl¿¡ Àͼ÷ÇÏÁö ¾Ê´õ¶óµµ ¹«½¼ ÀÏÀÌ ÀϾ´ÂÁö ¾Ë ¼ö + ÀÖ´Ù. ù¹ø° ÁÙÀº ¾ÆÆÄÄ¡(ȤÀº »ç¿ëÇÏ´Â ½©)¿¡°Ô + /usr/bin/perl À§Ä¡¿¡ ÀÖ´Â ÀÎÅÍÇÁ¸®ÅÍÀ» »ç¿ëÇÏ¿© + ÀÌ ÇÁ·Î±×·¥ ÆÄÀÏÀ» ½ÇÇàÇ϶ó°í ¾Ë¸°´Ù. µÎ¹ø° ÁÙÀº ¹æ±Ý + ¸»ÇÑ content-type ¼±¾ðÀ» Ãâ·ÂÇÏ°í carriage-return ÁٹٲÞÀ» + µÎ¹ø Ãâ·ÂÇÑ´Ù. ±×·¯¸é Çì´õ µÚ¿¡ HTTP Çì´õÀÇ ³¡À» ¶æÇÏ´Â + ºóÁÙÀÌ »ý±â°í, º»¹®ÀÌ ½ÃÀÛÇÑ´Ù. ¼¼¹ø° ÁÙÀº "Hello, World." + ¹®ÀÚ¿­À» Ãâ·ÂÇÑ´Ù. ÀÌ°ÍÀ¸·Î ³¡ÀÌ´Ù.

    + +

    ºê¶ó¿ìÀú¸¦ ½ÇÇàÇÏ°í ÁÖ¼Ò¸¦ ÀÔ·ÂÇÑ´Ù

    + + + http://www.example.com/cgi-bin/first.pl + + +

    ÆÄÀÏ Àå¼Ò¸¦ ÀÔ·ÂÇϸé, ºê¶ó¿ìÀúâ¿¡ Hello, World. + ÇÑ ÁÙÀÌ º¸ÀδÙ. ÈïºÐµÇÁö´Â ¾ÊÁö¸¸, Çѹø µ¿ÀÛÇÏ´Â °ÍÀ» + º¸¾ÒÀ¸´Ï ÀÌÁ¦ ´Ù¸¥ °ÍÀ» ½ÃµµÇØ º¼ ¼ö ÀÖ´Ù.

    +
    +
    + +
    + ±×·¯³ª ¾ÆÁ÷ µ¿ÀÛÇÏÁö ¾Ê¾Æ¿ä! + +

    À¥¿¡¼­ CGI ÇÁ·Î±×·¥¿¡ Á¢±ÙÇÒ¶§ ºê¶ó¿ìÀú¿¡ ³ª¿Ã ¼ö ÀÖ´Â + ³»¿ëÀº ±âº»ÀûÀ¸·Î ³×°¡Áö´Ù.

    + +
    +
    CGI ÇÁ·Î±×·¥ÀÇ Ãâ·Â
    +
    ÁÁ´Ù! ¸ðµç °ÍÀÌ Àß µ¿ÀÛÇÑ´Ù´Â ¶æÀÌ´Ù. Ãâ·ÂÀº Á¤È®ÇÏÁö¸¸ + ºê¶ó¿ìÀú°¡ ¿Ã¹Ù·Î ó¸®ÇÏÁö ¸øÇÑ´Ù¸é, CGI ÇÁ·Î±×·¥¿¡¼­ + ¿Ã¹Ù¸¥ Content-TypeÀ» ¼³Á¤ÇÏ¿´´ÂÁö È®ÀÎÇÑ´Ù.
    + +
    CGI ÇÁ·Î±×·¥ ¼Ò½ºÄÚµå ȤÀº "POST Method Not Allowed" + ¹®±¸
    +
    CGI ÇÁ·Î±×·¥À» ½ÇÇàÇϵµ·Ï ¾ÆÆÄÄ¡¸¦ ÀûÀýÈ÷ ¼³Á¤ÇÏÁö + ¾Ê¾Ò´Ù´Â ¶æÀÌ´Ù. ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ + ÀýÀ» ´Ù½Ã ÀÐ°í »©¸ÔÀº ºÎºÐÀÌ ÀÖ´ÂÁö ã¾ÆºÁ¶ó.
    + +
    "Forbidden"À¸·Î ½ÃÀÛÇÏ´Â ¹®±¸
    +
    ±ÇÇÑ ¹®Á¦°¡ ÀÖ´Ù´Â ¶æÀÌ´Ù. ¾ÆÆÄÄ¡ + ¿À·ù ·Î±×¿Í ¾Æ·¡ ÆÄÀϱÇÇÑ + ÀýÀ» È®ÀÎÇ϶ó.
    + +
    "Internal Server Error"¶ó´Â ¹®±¸
    +
    ¾ÆÆÄÄ¡ ¿À·ù ·Î±×¸¦ º¸¸é ¾Æ¸¶µµ + CGI ÇÁ·Î±×·¥ÀÌ Ãâ·ÂÇÑ ¿À·ù¹®°ú ÇÔ²² "Premature end of + script headers"°¡ º¸ÀÏ °ÍÀÌ´Ù. ÀÌ °æ¿ì ¾Æ·¡ ³»¿ëµéÀ» Çϳª¾¿ + È®ÀÎÇÏ¿© ¾î¶² ÀÌÀ¯·Î CGI ÇÁ·Î±×·¥ÀÌ ÀûÀýÇÑ HTTP Çì´õ¸¦ + Ãâ·ÂÇÏÁö ¸øÇß´ÂÁö ¾Ë¾Æº»´Ù.
    +
    + +
    + ÆÄÀϱÇÇÑ + +

    ¼­¹ö´Â ´ç½Å°ú µ¿ÀÏÇÑ °èÁ¤À¸·Î µ¿ÀÛÇÏÁö ¾ÊÀ½À» ¸í½ÉÇ϶ó. + Áï, ¼­¹ö°¡ ½ÃÀÛÇÏ¸é ¼­¹ö´Â ºñƯ±Ç »ç¿ëÀÚ ±ÇÇÑ(º¸Åë + nobody³ª www)À¸·Î µ¿ÀÛÇÑ´Ù. + ±×·¡¼­ ´ç½ÅÀÌ ¼ÒÀ¯ÇÑ ÆÄÀÏÀ» ½ÇÇàÇÏ·Á¸é ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù. + ÆÄÀÏ¿¡ nobody°¡ ½ÇÇàÇϱ⿡ ÃæºÐÇÑ ±ÇÇÑÀ» + ÁÖ±âÀ§ÇØ º¸Åë ¸ðµÎ¿¡°Ô ÆÄÀÏÀÇ ½ÇÇà ±ÇÇÑÀ» ÁØ´Ù.

    + + + chmod a+x first.pl + + +

    ¶Ç, ÇÁ·Î±×·¥ÀÌ ´Ù¸¥ ÆÄÀÏÀ» Àаųª ¾´´Ù¸é ÀÌ ÆÄÀÏ¿¡µµ + ÀûÀýÇÑ ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù.

    + +
    + +
    + °æ·Î Á¤º¸¿Í ȯ°æ + +

    ¸í·ÉÇà¿¡¼­ ÇÁ·Î±×·¥À» ½ÇÇàÇϸé ÀÚµ¿À¸·Î ¾î¶² Á¤º¸°¡ + ½©·Î Àü´ÞµÈ´Ù. ¿¹¸¦ µé¾î, PATH´Â ½©¿¡°Ô ´ç½ÅÀÌ + ¸»ÇÑ ÆÄÀÏÀ» ãÀ» Àå¼Ò¸¦ ¾Ë·ÁÁØ´Ù.

    + +

    À¥¼­¹ö°¡ ÇÁ·Î±×·¥À» CGI ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÒ¶§´Â + PATH°¡ ´Ù¸¦ ¼ö ÀÖ´Ù. (¿¹¸¦ µé¾î, + sendmail °°ÀÌ) CGI ÇÁ·Î±×·¥ ¾È¿¡¼­ ½ÇÇàÇÏ´Â + ¸í·É¾î´Â ¿ÏÀüÇÑ °æ·Î·Î ¸í½ÃÇØ¾ß ½©ÀÌ ¸í·É¾î¸¦ ãÀ» ¼ö + ÀÖ´Ù.

    + +

    °æ·Î ¹®Á¦´Â ´ÙÀ½°ú °°ÀÌ CGI ÇÁ·Î±×·¥ ù¹ø° ÁÙ¿¡ ³ª¿À´Â + ½ºÅ©¸³Æ® ÀÎÅÍÇÁ¸®ÅÍ (º¸Åë perl) °æ·Î¿¡¼­ + ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + + + #!/usr/bin/perl + + +

    ½ÇÁ¦·Î ÀÎÅÍÇÁ¸®ÅÍÀÇ °æ·ÎÀÎÁö È®ÀÎÇÑ´Ù.

    + +

    ¶Ç, CGI ÇÁ·Î±×·¥ÀÌ ´Ù¸¥ ȯ°æº¯¼ö¸¦ + »ç¿ëÇÑ´Ù¸é ¾ÆÆÄÄ¡°¡ ÀÌ º¯¼öµéÀ» ÇÁ·Î±×·¥¿¡°Ô Àü´ÞÇØ¾ß + ÇÑ´Ù.

    + +
    + +
    + ÇÁ·Î±×·¥ ¿À·ù + +

    CGI ÇÁ·Î±×·¥ÀÌ ½ÇÆÐÇÏ´Â °æ¿ì ´ëºÎºÐ ÇÁ·Î±×·¥ ÀÚü + ¹®Á¦¶§¹®ÀÌ´Ù. ƯÈ÷ À§ÀÇ µÎ°¡Áö ½Ç¼ö¸¦ ÇÏÁö ¾Ê¾Ò°í ÀÌ ±ÛÀ» + °è¼Ó º¸°í ÀÖ´Ù¸é ´õ´õ¿í ±×·¸´Ù. ¸ÕÀú À¥¼­¹ö¿¡¼­ ½ÇÇàÇϱâ + Àü¿¡ ¸í·ÉÇà¿¡¼­ ÇÁ·Î±×·¥À» ½ÇÇàÇغ»´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°ÀÌ ½ÇÇàÇÑ´Ù.

    + + + cd /usr/local/apache2/cgi-bin
    + ./first.pl +
    + +

    (perl ÀÎÅÍÇÁ¸®Å͸¦ ½ÇÇàÇÏÁö ¸¶¶ó. ½©°ú + ¾ÆÆÄÄ¡´Â ½ºÅ©¸³Æ® ù¹ø° ÁÙ¿¡ ÀÖ´Â °æ·Î Á¤º¸¸¦ »ç¿ëÇÏ¿© ÀÎÅÍÇÁ¸®Å͸¦ + ã¾Æ¾ß ÇÑ´Ù.)

    + +

    ÇÁ·Î±×·¥Àº Á¦ÀÏ ¸ÕÀú Content-TypeÀ» Æ÷ÇÔÇÑ + HTTP Çì´õµéÀ» Ãâ·ÂÇÏ°í ºó ÁÙÀ» Ãâ·ÂÇØ¾ß ÇÑ´Ù. ´Ù¸¥ °ÍÀ» + Ãâ·ÂÇÑ´Ù¸é À¥¼­¹ö¿¡¼­ ½ÇÇàÇÒ °æ¿ì ¾ÆÆÄÄ¡´Â Premature + end of script headers¸¦ ¹ÝȯÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº + À§ÀÇ CGI ÇÁ·Î±×·¥ ÀÛ¼ºÇϱ⸦ Âü°íÇ϶ó.

    +
    + +
    + ¿À·ù ·Î±× + +

    ¿À·ù ·Î±×´Â ´ç½Å ÆíÀÌ´Ù. ¹«¾ð°¡ À߸øµÇ¸é ¿À·ù ·Î±×¿¡ + ¹®±¸°¡ »ý±ä´Ù. ¿À·ù ·Î±×¸¦ Á¦ÀÏ ¸ÕÀú »ìÆìºÁ¾ß ÇÑ´Ù. À¥»çÀÌÆ®¸¦ + È£½ºÆÃÇÏ´Â °÷¿¡¼­ ¿À·ù ·Î±×¸¦ º¸Áö ¸øÇÏ°Ô ÇÑ´Ù¸é, ¾Æ¸¶µµ + ´Ù¸¥ ¾÷ü¸¦ ¾Ë¾ÆºÁ¾ß ÇÑ´Ù. ¿À·ù ·Î±×¸¦ º¸´Â ¹æ¹ýÀ» ÀÍÈ÷¸é, + ´ëºÎºÐÀÇ ¹®Á¦¸¦ »¡¸® ÆľÇÇÏ¿© ÇØ°áÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    + Suexec + +

    suexec Áö¿ø ÇÁ·Î±×·¥À» + »ç¿ëÇÏ¸é ¾î¶² °¡»óÈ£½ºÆ® ȤÀº ¾î¶² »ç¿ëÀÚ µð·ºÅ丮¿¡ ÀÖ´ÂÁö¿¡ + µû¶ó CGI ÇÁ·Î±×·¥À» ´Ù¸¥ »ç¿ëÀÚ ±ÇÇÑÀ¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + Suexec´Â ¸Å¿ì ¾ö°ÝÇÏ°Ô ±ÇÇÑÀ» °Ë»çÇϸç, °Ë»ç¸¦ Çϳª¶óµµ + Åë°úÇÏÁö ¸øÇϸé CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö ¾Ê°í Premature + end of script headers¸¦ ¹ÝȯÇÑ´Ù.

    + +

    suexec¸¦ »ç¿ëÇÏ°í ÀÖ´ÂÁö ¾Ë·Á¸é apachectl -V¸¦ + ½ÇÇàÇÏ¿© SUEXEC_BIN À§Ä¡¸¦ È®ÀÎÇÑ´Ù. ¾ÆÆÄÄ¡°¡ + ½ÃÀÛÇÒ¶§ ±× Àå¼Ò¿¡¼­ suexec ½ÇÇàÆÄÀÏÀ» ¹ß°ßÇϸé, suexec¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    suexec¸¦ ¿ÏÀüÈ÷ ÀÌÇØÇÏÁö ¸øÇß´Ù¸é »ç¿ëÇؼ­´Â ¾ÈµÈ´Ù. + suexec¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸·Á¸é SUEXEC_BIN À§Ä¡¿¡ + ÀÖ´Â suexec ½ÇÇàÆÄÀÏÀ» Áö¿ì°í (ȤÀº ÆÄÀϸíÀ» + ¹Ù²Ù°í) ¼­¹ö¸¦ Àç½ÃÀÛÇÏ¸é µÈ´Ù. suexec¿¡ ´ëÇØ ÀÐÀº ´ÙÀ½ ±×·¡µµ + »ç¿ëÇÏ°í ½Í´Ù¸é, suexec -V¸¦ ½ÇÇàÇÏ¿© suexec + ·Î±×ÆÄÀÏ À§Ä¡¸¦ ¾Ë¾Æ³»°í ·Î±×ÆÄÀÏ¿¡¼­ ´ç½ÅÀÌ ¾î¶² ±ÔÄ¢À» + ¾î±â°í ÀÖ´ÂÁö ã´Â´Ù.

    +
    +
    + +
    + µÚ¿¡¼­´Â ¹«½¼ ÀÏÀÌ ¹ú¾îÁö´Â°¡? + +

    CGI ÇÁ·Î±×·¡¹Ö¿¡ Àͼ÷ÇØÁú¼ö·Ï µÚ¿¡¼­ ¹ú¾îÁö´Â ÀÏÀ» ÀÌÇØÇϸé + µµ¿òÀÌ µÈ´Ù. ±¸Ã¼ÀûÀ¸·Î ºê¶ó¿ìÀú¿Í ¼­¹ö°¡ ¼­·Î Åë½ÅÇÏ´Â + ¹æ¹ýÀ» ¸»ÇÏ´Â °ÍÀÌ´Ù. ¸ô¶óµµ "Hello, World."¸¦ Ãâ·ÂÇÏ´Â + ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ ¼ö ÀÖÁö¸¸ ÀÌ·± ÇÁ·Î±×·¥Àº º°·Î ¾µ¸ð°¡ + ¾ø±â¶§¹®ÀÌ´Ù.

    + +
    + ȯ°æº¯¼ö + +

    ȯ°æº¯¼ö´Â ´ç½ÅÀÌ ÄÄÇ»Å͸¦ »ç¿ëÇÏ´Â µ¿¾È ´ç½Å ÁÖÀ§¸¦ + ¶°´Ù´Ï´Â °ªÀÌ´Ù. ȯ°æº¯¼ö´Â path (ÄÄÇ»ÅÍ°¡ ´ç½ÅÀÌ ÀÔ·ÂÇÑ + ¸í·É¾î¿¡ ÇØ´çÇÏ´Â ½ÇÁ¦ ÆÄÀÏÀ» ã´Â Àå¼Ò), »ç¿ëÀÚ¸í, Å͹̳Π+ Á¾·ù¿Í °°ÀÌ À¯¿ëÇÑ Á¤º¸´Ù. ÀϹÝÀûÀΠȯ°æº¯¼ö¸¦ ¸ðµÎ º¸·Á¸é + ¸í·ÉÇà ÇÁ·ÒÇÁÆ®¿¡¼­ env¸¦ ÀÔ·ÂÇÑ´Ù.

    + +

    CGI¸¦ ½ÇÇàÇÒ¶§µµ ¼­¹ö¿Í ºê¶ó¿ìÀú´Â °¢ÀÚÀÇ È¯°æº¯¼ö¸¦ + ¼­·Î ±³È¯ÇÑ´Ù. ÀÌ Á¤º¸¿¡´Â ºê¶ó¿ìÀú Á¾·ù (Netscape, IE, + Lynx), ¼­¹ö Á¾·ù (¾ÆÆÄÄ¡, IIS, WebSite), ½ÇÇàÇÏ´Â CGI + ÇÁ·Î±×·¥¸í µîÀÌ ÀÖ´Ù.

    + +

    CGI ÇÁ·Î±×·¡¸Ó´Â ÀÌ·± º¯¼öµéÀ» »ç¿ëÇÒ ¼ö ÀÖ°í, + ȯ°æº¯¼ö´Â Ŭ¶óÀ̾ðÆ®-¼­¹ö Åë½Å¿¡´Â ÀϺκÐÀ» Â÷ÁöÇÑ´Ù. + Àüü Çʼö º¯¼ö ¸ñ·ÏÀº http://hoohoo.ncsa.uiuc.edu/cgi/env.html¿¡ ÀÖ´Ù.

    + +

    ¾Æ·¡ °£´ÜÇÑ Perl CGI ÇÁ·Î±×·¥Àº Àڽſ¡°Ô Àü´ÞµÈ ¸ðµç + ȯ°æº¯¼ö¸¦ º¸¿©ÁØ´Ù. ¾ÆÆÄÄ¡ ¹èÆ÷º»ÀÇ cgi-bin + µð·ºÅ丮¿¡ ÀÌ¿Í ºñ½ÁÇÑ ÇÁ·Î±×·¥ÀÌ µÎ°³ ÀÖ´Ù. ¸î¸î º¯¼ö´Â + ÇʼöÀÌ°í ³ª¸ÓÁö´Â ¼±ÅÃÀûÀÌ´Ù. ±×·¡¼­ °ø½Ä ¸ñ·Ï¿¡ ¾ø´Â + º¯¼öµµ º¸ÀδÙ. ¶Ç, ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î Á¦°øÇϴ ȯ°æº¯¼ö + ¿Ü¿¡ ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î Á÷Á¢ ȯ°æº¯¼ö¸¦ + Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + + + #!/usr/bin/perl
    + print "Content-type: text/html\n\n";
    + foreach $key (keys %ENV) {
    + + print "$key --> $ENV{$key}<br>";
    +
    + } +
    +
    + +
    + STDIN°ú STDOUT + +

    ¶Ç, ¼­¹ö¿Í Ŭ¶óÀ̾ðÆ®´Â Ç¥ÁØÀÔ·Â(STDIN)°ú + Ç¥ÁØÃâ·Â(STDOUT)À¸·Î Åë½ÅÇÑ´Ù. ÀÏ»óÀûÀÎ °æ¿ì + STDINÀº Å°º¸µå³ª ÇÁ·Î±×·¥ÀÌ Ã³¸®ÇÏ´Â ÆÄÀÏÀ» + ³ªÅ¸³»°í, STDOUTÀº º¸Åë ÄܼÖÀ̳ª È­¸éÀ» ¶æÇÑ´Ù.

    + +

    CGI ÇÁ·Î±×·¥¿¡°Ô À¥ ¾ç½Ä(form)À» POSTÇϸé + ¾ç½Ä¿¡ ÀÔ·ÂÇÑ ÀڷḦ Ưº°ÇÑ Çü½ÄÀ¸·Î ¹­¾î¼­ CGI ÇÁ·Î±×·¥ÀÇ + STDINÀ¸·Î Àü´ÞÇÑ´Ù. ±×·¯¸é ÇÁ·Î±×·¥Àº Å°º¸µå³ª + ÆÄÀÏ¿¡¼­ ¾òÀº ÀڷḦ ó¸®ÇϵíÀÌ ÀڷḦ ó¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    "Ưº°ÇÑ Çü½Ä"Àº ¸Å¿ì °£´ÜÇÏ´Ù. Ç׸ñ À̸§°ú °ªÀ» µîÈ£(=)·Î + ¿¬°áÇÏ°í, Ç׸ñ À̸§°ú °ªÀÇ ½ÖµéÀ» ¼­·Î ¾ØÆÛ»÷µå(&)·Î + ¿¬°áÇÑ´Ù. °ø¹é, ¾ÚÆÛ»÷µå, µîÈ£ °°Àº ºÎÀÚ¿¬½º·¯¿î ¹®ÀÚ´Â + È¥µ¿ÇÏÁö ¾Êµµ·Ï 16Áø¼ö·Î º¯È¯ÇÑ´Ù. ¿ÏÀüÇÑ ÀÚ·á ¹®ÀÚ¿­Àº + ´ÙÀ½°ú °°ÀÌ »ý°å´Ù.

    + + + name=Rich%20Bowen&city=Lexington&state=KY&sidekick=Squirrel%20Monkey + + +

    Á¾Á¾ URL µÚ¿¡¼­ ÀÌ·± ¹®ÀÚ¿­À» º¸°Ô µÈ´Ù. ÀÌ °æ¿ì ¼­¹ö´Â + ¹®ÀÚ¿­À» QUERY_STRINGÀ̶ó´Â ȯ°æº¯¼ö¿¡ ÀúÀåÇÑ´Ù. + À̸¦ GET ¿äûÀ̶ó°í ÇÑ´Ù. FORM + ű×ÀÇ METHOD ¼Ó¼ºÀ» ÁöÁ¤ÇÏ¿© HTML ¾ç½Ä(form)ÀÌ + ÀڷḦ GETÇÒÁö POSTÇÒÁö °áÁ¤ÇÑ´Ù.

    + +

    ÀÌÁ¦ ÇÁ·Î±×·¥Àº ÀÌ·± ¹®ÀÚ¿­À» À¯¿ëÇÑ Á¤º¸·Î ÂÉ°³¾ß + ÇÑ´Ù. ´ÙÇàÈ÷µµ ÀÌ·± ÀÚ·á 󸮸¦ µ½°í CGI ÇÁ·Î±×·¥ÀÇ ´Ù¸¥ + ¿©·¯ ¸éÀ» »ìÇÇ´Â ¶óÀ̺귯¸®¿Í ¸ðµâµéÀÌ ÀÖ´Ù.

    +
    +
    + +
    + CGI ¸ðµâ/¶óÀ̺귯¸® + +

    CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÒ¶§ Áö·çÇÑ ÀÛ¾÷À» ´ë½ÅÇØÁÖ´Â ÄÚµå + ¶óÀ̺귯¸® ȤÀº ¸ðµâÀ» »ç¿ëÇÒÁö °í·ÁÇغÁ¾ß ÇÑ´Ù. ÀÌ·± °ÍÀ» + »ç¿ëÇÏ¸é ¹ö±×°¡ ÁÙ°í ´õ »¡¸® ÇÁ·Î±×·¥À» °³¹ßÇÒ ¼ö ÀÖ´Ù.

    + +

    Perl·Î CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ´Ù¸é CPAN¿¡¼­ °ü·Ã ¸ðµâµéÀ» ãÀ» + ¼ö ÀÖ´Ù. CGI °³¹ß¿¡ °¡Àå ³Î¸® »ç¿ëµÇ´Â ¸ðµâÀº + CGI.pmÀÌ´Ù. ´ëºÎºÐÀÇ ÇÁ·Î±×·¥¿¡ ÃæºÐÇÑ ÃÖ¼Ò + ±â´ÉÀ» ±¸ÇöÇÑ CGI::Liteµµ °í·ÁÇØ º¼ ¼ö ÀÖ´Ù.

    + +

    C·Î CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ´Ù¸é ¼±ÅÃÀÇ ¿©Áö°¡ ¸¹´Ù. ÀÌÁß + Çϳª°¡ http://www.boutell.com/cgic/¿¡ + ÀÖ´Â CGIC ¶óÀ̺귯¸®´Ù.

    +
    + +
    + ´õ ¸¹Àº Á¤º¸... + +

    À¥¿¡ ¸Å¿ì ¸¹Àº CGI Á¤º¸°¡ ÀÖ´Ù. ´º½º±×·ì comp.infosystems.www.authoring.cgi¿¡¼­ ¿©·¯ »ç¶÷µé°ú + CGI ¹®Á¦¸¦ ³íÀÇÇÒ ¼ö ÀÖ´Ù. HTML Writers GuildÀÇ -servers + ¸ÞÀϸµ¸®½ºÆ®´Â Áú¹®¿¡ ´ëÇÑ ´äÀ» ã±â¿¡ ÈǸ¢ÇÑ Àå¼Ò´Ù. http://www.hwg.org/lists/hwg-servers/¿¡¼­ ´õ ¸¹Àº °ÍÀ» + ¾Ë ¼ö ÀÖ´Ù.

    + +

    ±×¸®°í ¹°·Ð CGI ÇÁ·Î±×·¥ µ¿ÀÛ¿¡ ´ëÇÑ ¸ðµç ³»¿ëÀ» ¼³¸íÇÑ + CGI ±Ô¾àÀ» Àоî¾ß ÇÒÁöµµ ¸ð¸¥´Ù. NCSA¿¡ + ¿øº» ¹®¼­°¡ ÀÖ°í, ¼öÁ¤ÇÑ ÃʾÈÀº Common Gateway Interface + RFC ÇÁ·ÎÁ§Æ®¿¡ ÀÖ´Ù.

    + +

    ¸ÞÀϸµ¸®½ºÆ®³ª ´º½º±×·ì¿¡ ÇöÀç °Ý°í ÀÖ´Â CGI ¹®Á¦¿¡ ´ëÇØ + Áú¹®ÇÒ¶§´Â ¹ß»ýÇÑ Çö»ó°ú ¿ø·¡ ±â´ëÇÑ °á°ú, ½ÇÁ¦·Î ¹ß»ýÇÑ + Çö»óÀÌ ¾î¶»°Ô ´Ù¸¥Áö, »ç¿ëÇÏ´Â ¼­¹ö, CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇÑ + ¾ð¾î, °¡´ÉÇϸé ÇØ´ç Äڵ带 ÀÚ¼¼È÷ Àû¾î¶ó. ±×·¯¸é ÇØ°áÃ¥À» + ã±â ½¬¿öÁø´Ù.

    + +

    ¾ÆÆÄÄ¡ ¼Ò½ºÄڵ尡 À߸øµÇ¾ú´Ù°í È®½ÅÇÏÁö ¾Ê´Â ÇÑ CGI Áú¹®À» + ¾ÆÆÄÄ¡ ¹ö±× µ¥ÀÌÅͺ£À̽º¿¡ ¿Ã¸®¸é Àý´ë·Î + ¾ÈµÈ´Ù.

    +
    +
    + diff --git a/trunk/docs/manual/howto/cgi.xml.meta b/trunk/docs/manual/howto/cgi.xml.meta new file mode 100644 index 0000000000..9e8940a909 --- /dev/null +++ b/trunk/docs/manual/howto/cgi.xml.meta @@ -0,0 +1,13 @@ + + + + cgi + /howto/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/howto/htaccess.html b/trunk/docs/manual/howto/htaccess.html new file mode 100644 index 0000000000..9c6579d86f --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.html @@ -0,0 +1,15 @@ +URI: htaccess.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: htaccess.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: htaccess.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR + +URI: htaccess.html.pt-br +Content-Language: pt-br +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/howto/htaccess.html.en b/trunk/docs/manual/howto/htaccess.html.en new file mode 100644 index 0000000000..2633309321 --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.html.en @@ -0,0 +1,385 @@ + + + +Apache Tutorial: .htaccess files - Apache HTTP Server + + + + + +
    <-
    +

    Apache Tutorial: .htaccess files

    +
    +

    Available Languages:  en  | + ja  | + ko  | + pt-br 

    +
    + +

    .htaccess files provide a way to make configuration +changes on a per-directory basis.

    +
    + +
    top
    +
    top
    +
    +

    What they are/How to use them

    + + +

    .htaccess files (or "distributed configuration files") + provide a way to make configuration changes on a per-directory basis. A + file, containing one or more configuration directives, is placed in a + particular document directory, and the directives apply to that + directory, and all subdirectories thereof.

    + +

    Note:

    +

    If you want to call your .htaccess file something + else, you can change the name of the file using the AccessFileName directive. For example, + if you would rather call the file .config then you + can put the following in your server configuration file:

    + +

    + AccessFileName .config +

    +
    + +

    In general, .htaccess files use the same syntax as + the main configuration + files. What you can put in these files is determined by the + AllowOverride directive. This + directive specifies, in categories, what directives will be + honored if they are found in a .htaccess file. If a + directive is permitted in a .htaccess file, the + documentation for that directive will contain an Override section, + specifying what value must be in AllowOverride in order for that + directive to be permitted.

    + +

    For example, if you look at the documentation for the AddDefaultCharset + directive, you will find that it is permitted in .htaccess + files. (See the Context line in the directive summary.) The Override line reads + FileInfo. Thus, you must have at least + AllowOverride FileInfo in order for this directive to be + honored in .htaccess files.

    + +

    Example:

    + + + + + + + + + +
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    + +

    If you are unsure whether a particular directive is permitted in a + .htaccess file, look at the documentation for that + directive, and check the Context line for ".htaccess".

    +
    top
    +
    +

    When (not) to use .htaccess files

    + +

    In general, you should never use .htaccess files unless + you don't have access to the main server configuration file. There is, + for example, a prevailing misconception that user authentication should + always be done in .htaccess files. This is simply not the + case. You can put user authentication configurations in the main server + configuration, and this is, in fact, the preferred way to do + things.

    + +

    .htaccess files should be used in a case where the + content providers need to make configuration changes to the server on a + per-directory basis, but do not have root access on the server system. + In the event that the server administrator is not willing to make + frequent configuration changes, it might be desirable to permit + individual users to make these changes in .htaccess files + for themselves. This is particularly true, for example, in cases where + ISPs are hosting multiple user sites on a single machine, and want + their users to be able to alter their configuration.

    + +

    However, in general, use of .htaccess files should be + avoided when possible. Any configuration that you would consider + putting in a .htaccess file, can just as effectively be + made in a <Directory> section in your main server + configuration file.

    + +

    There are two main reasons to avoid the use of + .htaccess files.

    + +

    The first of these is performance. When AllowOverride + is set to allow the use of .htaccess files, Apache will + look in every directory for .htaccess files. Thus, + permitting .htaccess files causes a performance hit, + whether or not you actually even use them! Also, the + .htaccess file is loaded every time a document is + requested.

    + +

    Further note that Apache must look for .htaccess files + in all higher-level directories, in order to have a full complement of + directives that it must apply. (See section on how + directives are applied.) Thus, if a file is requested out of a + directory /www/htdocs/example, Apache must look for the + following files:

    + +

    + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +

    + +

    And so, for each file access out of that directory, there are 4 + additional file-system accesses, even if none of those files are + present. (Note that this would only be the case if + .htaccess files were enabled for /, which + is not usually the case.)

    + +

    The second consideration is one of security. You are permitting + users to modify server configuration, which may result in changes over + which you have no control. Carefully consider whether you want to give + your users this privilege. Note also that giving users less + privileges than they need will lead to additional technical support + requests. Make sure you clearly tell your users what level of + privileges you have given them. Specifying exactly what you have set + AllowOverride to, and pointing them + to the relevant documentation, will save yourself a lot of confusion + later.

    + +

    Note that it is completely equivalent to put a .htaccess + file in a directory /www/htdocs/example containing a + directive, and to put that same directive in a Directory section + <Directory /www/htdocs/example> in your main server + configuration:

    + +

    .htaccess file in /www/htdocs/example:

    + +

    Contents of .htaccess file in + /www/htdocs/example

    + AddType text/example .exm +

    + +

    Section from your httpd.conf + file

    + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +

    + +

    However, putting this configuration in your server configuration + file will result in less of a performance hit, as the configuration is + loaded once when Apache starts, rather than every time a file is + requested.

    + +

    The use of .htaccess files can be disabled completely + by setting the AllowOverride + directive to none:

    + +

    + AllowOverride None +

    +
    top
    +
    +

    How directives are applied

    + +

    The configuration directives found in a .htaccess file + are applied to the directory in which the .htaccess file + is found, and to all subdirectories thereof. However, it is important + to also remember that there may have been .htaccess files + in directories higher up. Directives are applied in the order that they + are found. Therefore, a .htaccess file in a particular + directory may override directives found in .htaccess files + found higher up in the directory tree. And those, in turn, may have + overridden directives found yet higher up, or in the main server + configuration file itself.

    + +

    Example:

    + +

    In the directory /www/htdocs/example1 we have a + .htaccess file containing the following:

    + +

    + Options +ExecCGI +

    + +

    (Note: you must have "AllowOverride Options" in effect + to permit the use of the "Options" directive in + .htaccess files.)

    + +

    In the directory /www/htdocs/example1/example2 we have + a .htaccess file containing:

    + +

    + Options Includes +

    + +

    Because of this second .htaccess file, in the directory + /www/htdocs/example1/example2, CGI execution is not + permitted, as only Options Includes is in effect, which + completely overrides any earlier setting that may have been in + place.

    + +

    Merging of .htaccess with the main + configuration files

    + +

    As discussed in the documentation on Configuration Sections, + .htaccess files can override the <Directory> sections for + the corresponding directory, but will be overriden by other types + of configuration sections from the main configuration files. This + fact can be used to enforce certain configurations, even in the + presence of a liberal AllowOverride setting. For example, to + prevent script execution while allowing anything else to be set in + .htaccess you can use:

    + +

    +<Directory />
    + +Allowoverride All
    +
    +</Directory>
    +
    +<Location />
    + +Options +IncludesNoExec -ExecCGI
    +
    +</Location> +

    + + +
    top
    +
    +

    Authentication example

    + +

    If you jumped directly to this part of the document to find out how + to do authentication, it is important to note one thing. There is a + common misconception that you are required to use + .htaccess files in order to implement password + authentication. This is not the case. Putting authentication directives + in a <Directory> + section, in your main server configuration file, is the preferred way + to implement this, and .htaccess files should be used only + if you don't have access to the main server configuration file. See above for a discussion of when you should and should + not use .htaccess files.

    + +

    Having said that, if you still think you need to use a + .htaccess file, you may find that a configuration such as + what follows may work for you.

    + +

    .htaccess file contents:

    + +

    + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +

    + +

    Note that AllowOverride AuthConfig must be in effect + for these directives to have any effect.

    + +

    Please see the authentication tutorial for a + more complete discussion of authentication and authorization.

    +
    top
    +
    +

    Server Side Includes example

    + +

    Another common use of .htaccess files is to enable + Server Side Includes for a particular directory. This may be done with + the following configuration directives, placed in a + .htaccess file in the desired directory:

    + +

    + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +

    + +

    Note that AllowOverride Options and AllowOverride + FileInfo must both be in effect for these directives to have any + effect.

    + +

    Please see the SSI tutorial for a more + complete discussion of server-side includes.

    +
    top
    +
    +

    CGI example

    + +

    Finally, you may wish to use a .htaccess file to permit + the execution of CGI programs in a particular directory. This may be + implemented with the following configuration:

    + +

    + Options +ExecCGI
    + AddHandler cgi-script cgi pl +

    + +

    Alternately, if you wish to have all files in the given directory be + considered to be CGI programs, this may be done with the following + configuration:

    + +

    + Options +ExecCGI
    + SetHandler cgi-script +

    + +

    Note that AllowOverride Options and AllowOverride + FileInfo must both be in effect for these directives to have any + effect.

    + +

    Please see the CGI tutorial for a more + complete discussion of CGI programming and configuration.

    + +
    top
    +
    +

    Troubleshooting

    + +

    When you put configuration directives in a .htaccess + file, and you don't get the desired effect, there are a number of + things that may be going wrong.

    + +

    Most commonly, the problem is that AllowOverride is not + set such that your configuration directives are being honored. Make + sure that you don't have a AllowOverride None in effect + for the file scope in question. A good test for this is to put garbage + in your .htaccess file and reload. If a server error is + not generated, then you almost certainly have AllowOverride + None in effect.

    + +

    If, on the other hand, you are getting server errors when trying to + access documents, check your Apache error log. It will likely tell you + that the directive used in your .htaccess file is not + permitted. Alternately, it may tell you that you had a syntax error, + which you will then need to fix.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/htaccess.html.ja.euc-jp b/trunk/docs/manual/howto/htaccess.html.ja.euc-jp new file mode 100644 index 0000000000..56cb3cd404 --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.html.ja.euc-jp @@ -0,0 +1,383 @@ + + + +Apache ¥Á¥å¡¼¥È¥ê¥¢¥ë: .htaccess ¥Õ¥¡¥¤¥ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¥Á¥å¡¼¥È¥ê¥¢¥ë: .htaccess ¥Õ¥¡¥¤¥ë

    +
    +

    Available Languages:  en  | + ja  | + ko  | + pt-br 

    +
    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤ËÀßÄê¤òÊѹ¹¤¹¤ëÊýË¡¤ò +Ä󶡤·¤Þ¤¹¡£

    +
    + +
    top
    +
    top
    +
    +

    .htaccess ¥Õ¥¡¥¤¥ë¤È¤Ï²¿¤«/¤½¤Î»È¤¤Êý

    + + +

    .htaccess ¥Õ¥¡¥¤¥ë (¡Öʬ»¶ÀßÄê¥Õ¥¡¥¤¥ë¡×) ¤Ï + ¥Ç¥£¥ì¥¯¥È¥êËè¤ËÀßÄê¤òÊѹ¹¤¹¤ëÊýË¡¤òÄ󶡤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ½ñ¤«¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤¯¤³¤È¤Ç¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤Î + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤¹¤Ù¤Æ¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬÍѤµ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Ãí:

    +

    .htaccess ¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + AccessFileName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤Ã¤ÆÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ò .config + ¤È¤¤¤¦Ì¾Á°¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢°Ê²¼¤ÎÀßÄê¤ò¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤ËÆþ¤ì¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹:

    + +

    + AccessFileName .config +

    +
    + +

    °ìÈ̤ˡ¢.htaccess ¥Õ¥¡¥¤¥ë¤Î¹½Ê¸¤Ï + ¼çÀßÄê¥Õ¥¡¥¤¥ë + ¤ÈƱ¤¸¤Ç¤¹¡£¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤Î¤Ç¤­¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï AllowOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê·è¤Þ¤ê¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢.htaccess ¥Õ¥¡¥¤¥ë¤Ë + ½ñ¤«¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ç¡¢¡¢ + ¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Å¬ÍѤµ¤ì¤ë¤«¤ò¥«¥Æ¥´¥ê¡¼Ã±°Ì¤Ç»ØÄꤷ¤Þ¤¹¡£ + .htaccess ¤Ë½ñ¤¯¤³¤È¤Î¤Ç¤­¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤¢¤ì¤Ð¡¢ + ÀâÌÀʸ½ñ¤Ë¤Ï¡Ö¾å½ñ¤­¡×¤È¤¤¤¦¹àÌܤ¬¤¢¤ê¡¢.htaccess ¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë + ¤Ê¤ë¤¿¤á¤Î AllowOverride ¤ÎÃͤ¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢AddDefaultCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀâÌÀ¤ò + ¸«¤ë¤È¡¢.htaccess ¥Õ¥¡¥¤¥ë¤Ç¤Î»ÈÍѤ¬µö²Ä¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬ + ¤ï¤«¤ê¤Þ¤¹¡£ (¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î³µÍפνê¤Ë¤¢¤ë¡Ö¥³¥ó¥Æ¥­¥¹¥È¡×¤È½ñ¤«¤ì¤Æ¤¤¤ë + ¹Ô¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£) ¾å½ñ¤­¤È½ñ¤«¤ì¤Æ¤¤¤ë¹Ô¤Ë¤Ï + FileInfo ¤È¤¢¤ê¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢.htaccess Ãæ¤Î + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤Ë¤Ï¡¢¾¯¤Ê¤¯¤È¤â + AllowOverride FileInfo ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Îã:

    + + + + + + + + + +
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë,¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È,¥Ç¥£¥ì¥¯¥È¥ê,.htaccess
    ¾å½ñ¤­:FileInfo
    + +

    ¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò .htaccess ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¤« + ¤É¤¦¤«¤ï¤«¤é¤Ê¤¤¤È¤­¤Ï¡¢¤½¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀâÌÀ¤òõ¤·¤Æ¡¢".htaccess" + ¤Î¤¿¤á¤Î¡Ö¥³¥ó¥Æ¥­¥¹¥È¡×¤Î¹Ô¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¤¤¤Ä .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤¦(»È¤ï¤Ê¤¤)¤«¡£

    + +

    °ìÈÌŪ¤Ë¡¢¥µ¡¼¥Ð¤Î¼çÀßÄê¥Õ¥¡¥¤¥ë¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¾ì¹ç¤ò½ü¤¤¤Æ¡¢ + .htaccess ¥Õ¥¡¥¤¥ë¤Î»ÈÍѤ϶ËÎÏÈò¤±¤Æ¤¯¤À¤µ¤¤¡£ + À¤¤ÎÃæ¤Ë¤Ï¡¢Î㤨¤Ð¡¢¥æ¡¼¥¶Ç§¾Ú¤Ï¾ï¤Ë .htaccess ¥Õ¥¡¥¤¥ë¤Ç + ¹Ô¤Ê¤ï¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¢¤È¤¤¤¦¸í²ò¤¬¹­¤Þ¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¢¤Þ¤Ã¤¿¤¯¤½¤ó¤Ê¤³¤È¤Ï + ¤¢¤ê¤Þ¤»¤ó¡£¥æ¡¼¥¶Ç§¾Ú¤ÎÀßÄê¤Ï¥µ¡¼¥Ð¼çÀßÄê¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¡¢ + ¼ÂºÝ¡¢¤½¤ÎÊý¤¬¤è¤êÎɤ¤ÀßÄêÊýË¡¤Ç¤¹¡£

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤Ï¥³¥ó¥Æ¥ó¥ÄÄ󶡼Ԥ¬¥Ç¥£¥ì¥¯¥È¥êËè¤Î + ÀßÄê¤ò¹Ô¤Ê¤¤¤¿¤¤¤±¤ì¤É¡¢¥µ¡¼¥Ð¥·¥¹¥Æ¥à¤Î root ¥¢¥¯¥»¥¹¸¢¸Â¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤ + ¤È¤¤¤¦¾ì¹ç¤Ë¤Î¤ß»È¤¦¤Ù¤­¤â¤Î¤Ç¤¹¡£¥µ¡¼¥Ð´ÉÍý¼Ô¤¬ÉÑÈˤËÀßÄêÊѹ¹¤ò¹Ô¤Ê¤¤¤¿¤¯¤Ï + ¤Ê¤¤¡¢¤È¤¤¤¦¤È¤­¤Ë¤Ï¸Ä¡¹¤Î¥æ¡¼¥¶¤¬ .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ + ¼«Ê¬¤ÇÀßÄê¤ÎÊѹ¹¤ò¹Ô¤Ê¤¦¤³¤È¤òµö²Ä¤·¤¿Êý¤¬Îɤ¤¤È¤­¤â¤¢¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤ì¤ÏÆäˡ¢ISP ¤¬Ê£¿ô¤Î¥æ¡¼¥¶¤Î¥µ¥¤¥È¤ò°ì¤Ä¤Î¥Þ¥·¥ó¤Ç¥Û¥¹¥È¤·¤Æ¤¤¤Æ¡¢ + ³Æ¥æ¡¼¥¶¤¬ÀßÄê¤ÎÊѹ¹¤ò¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿¤¤¤è¤¦¤Ê¤È¤­¤Ë¤¢¤Æ¤Ï¤Þ¤ê¤Þ¤¹¡£

    + +

    ¤·¤«¤·¡¢ÉáÄ̤ϲÄǽ¤Ç¤¢¤ì¤Ð .htaccess ¥Õ¥¡¥¤¥ë¤Î»ÈÍÑ¤Ï + Èò¤±¤Æ¤¯¤À¤µ¤¤¡£.htaccess ¥Õ¥¡¥¤¥ë¤Ë½ñ¤³¤¦¤È¹Í¤¨¤ë¤è¤¦¤Ê + ¤¹¤Ù¤Æ¤ÎÀßÄê¤Ï¡¢¥µ¡¼¥Ð¤Î¼çÀßÄê¥Õ¥¡¥¤¥ë¤Î <Directory> ¥»¥¯¥·¥ç¥ó¤ÇƱ¤¸¤è¤¦¤Ë¹Ô¤Ê¤¦¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤Î»ÈÍѤòÈò¤±¤ëÍýͳ¤Ï¼ç¤ËÆó¤Ä¤¢¤ê¤Þ¤¹¡£

    + +

    °ì¤ÄÌܤϥµ¡¼¥Ð¤ÎÀ­Ç½¤ÎÌäÂê¤Ç¤¹¡£AllowOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + .htaccess ¥Õ¥¡¥¤¥ë¤ÎÀßÄê¤òµö²Ä¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢Apache ¤Ï + ³Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ç .htaccess ¥Õ¥¡¥¤¥ë¤òõ¤·¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢.htaccess ¥Õ¥¡¥¤¥ë¤òµö²Ä¤¹¤ë¤È¡¢¼ÂºÝ¤Ë»ÈÍѤ·¤Æ¤¤¤ë¤« + ¤É¤¦¤«¤Ë´Ø¤ï¤é¤º¡¢À­Ç½¤ÎÄã²¼¤ò¾·¤¯¤³¤È¤Ë¤Ê¤ê¤Þ¤¹! ¤Þ¤¿¡¢.htaccess + ¥Õ¥¡¥¤¥ë¤Ïʸ½ñ¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤ëÅÙ¤ËÆɤ߹þ¤Þ¤ì¤Þ¤¹¡£

    + +

    ¤µ¤é¤Ë¡¢Apache ¤ÏŬÍѤ¹¤Ù¤­¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½¸¤á¤ë¤¿¤á¤Ë¡¢¤¹¤Ù¤Æ¤Î + ¾å°Ì¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î .htaccess ¥Õ¥¡¥¤¥ë¤òõ¤¹É¬Íפ¬¤¢¤ë¤³¤È¤Ë¤â + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£(¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Å¬ÍѤµ¤ì¤ëÊýË¡¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£)¤Ç¤¹¤«¤é¡¢/www/htdocs/example ¤Ë¤¢¤ë + ¥Õ¥¡¥¤¥ë¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¤È¤­¤Ï¡¢Apache ¤Ï°Ê²¼¤Î¥Õ¥¡¥¤¥ë¤òÄ´¤Ù¤Þ¤¹¡£

    + +

    + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +

    + +

    ¤Ç¤¹¤«¤é¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤½¤ì¤¾¤ì¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î¥¢¥¯¥»¥¹¤ËÂФ·¤Æ¡¢ + ¾å¤ÎÎã¤Î¥Õ¥¡¥¤¥ë¤¬¤Þ¤Ã¤¿¤¯Â¸ºß¤·¤Ê¤¤¤È¤­¤Ç¤â¡¢ÄɲäΥե¡¥¤¥ë¥·¥¹¥Æ¥à¤Î + ¥¢¥¯¥»¥¹¤¬¹Ô¤Ê¤ï¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£(¤³¤ì¤Ï¡¢.htaccess ¤¬ + / ¤ËÂФ·¤ÆÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¤Î¾ì¹ç¤Ç¡¢ÉáÄ̤Ϥ½¤¦¤Ê¤Ã¤Æ + ¤¤¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£)

    + +

    Æó¤ÄÌܤϥ»¥­¥å¥ê¥Æ¥£¤Ç¤¹¡£¥æ¡¼¥¶¤Ë¥µ¡¼¥Ð¤ÎÀßÄê¤òÊѹ¹¤¹¤ë¤³¤È¤ò + µö²Ä¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¤Î¤Ç¡¢¤¢¤Ê¤¿¼«¿È¤¬´ÉÍý¤Ç¤­¤Ê¤¤Êѹ¹¤ò¤µ¤ì¤ë + ¶²¤ì¤¬¤¢¤ê¤Þ¤¹¡£¥æ¡¼¥¶¤Ë¤³¤ÎÆø¢¤òÍ¿¤¨¤ë¤Î¤¬Îɤ¤¤Î¤«¤É¤¦¤«¡¢½½Ê¬ + ¸¡Æ¤¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢¥æ¡¼¥¶¤ËÍ¿¤¨¤ë¸¢¸Â¤¬É¬Íפʤâ¤Î¤è¤ê¤â¾¯¤Ê¤¹¤®¤ë¤È¡¢ + ;ʬ¤Êµ»½Ñ¥µ¥Ý¡¼¥ÈÊó¹ð¤ò¼õ¤±¼è¤ë¤è¤¦¤Ë¤Ê¤ë²ÄǽÀ­¤¬¹â¤¤¤³¤È¤Ë¤â + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£³Î¼Â¤Ë¡¢¥æ¡¼¥¶¤Ë¤É¤ÎÄøÅ٤θ¢¸Â¤òÍ¿¤¨¤¿¤«ÌÀ³Î¤Ë¹ð¤²¤ë¤è¤¦¤Ë + ¤·¤Æ¤¯¤À¤µ¤¤¡£AllowOverride ¤Ë + ²¿¤òÀßÄꤷ¤¿¤«¤È¤¤¤¦¤³¤È¤È¡¢´ØÏ¢¤¹¤ëʸ½ñ¤ò¼¨¤¹¤³¤È¤Ç¡¢ + ¸å¡¹¤Îº®Íð¤ò¤°¤Ã¤È¸º¤é¤¹¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +

    ¤È¤³¤í¤Ç¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î½ñ¤«¤ì¤¿ .htaccess ¤ò + /www/htdocs/example ¤ËÃÖ¤¯¤³¤È¤È¡¢Æ±¤¸¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ¼ç¥µ¡¼¥ÐÀßÄê¤Î Directory ¥»¥¯¥·¥ç¥ó + <Directory /www/htdocs/example> ¤Ë½ñ¤¯¤³¤È¤Ï + ´°Á´¤ËÅù²Á¤Ç¤¹:

    + +

    /www/htdocs/example ¤Î .htaccess ¥Õ¥¡¥¤¥ë:

    + +

    /www/htdocs/example ¤Î .htaccess ¥Õ¥¡¥¤¥ë¤Î + ÆâÍÆ

    + AddType text/example .exm +

    + +

    httpd.conf ¤Î¥»¥¯¥·¥ç¥ó + file

    + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +

    + +

    ¤·¤«¤·¡¢¤³¤ÎÀßÄê¤Ï¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤Ë½ñ¤¤¤¿Êý¤¬¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Î + Äã²¼¤¬¾¯¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤ëÅÙ¤Ë + Æɤ߹þ¤Þ¤ì¤ëÂå¤ï¤ê¤Ë¡¢Apache ¤Îµ¯Æ°»þ¤Ë 1 ²ó¤À¤±Æɤ߹þ¤á¤Ð + ¤è¤¯¤Ê¤ë¤«¤é¤Ç¤¹¡£

    + +

    AllowOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + Ãͤò none ¤ËÀßÄꤹ¤ë¤³¤È¤Ç .htaccess ¥Õ¥¡¥¤¥ë + ¤Î»ÈÍѤò´°Á´¤Ë̵¸ú¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + AllowOverride None +

    +
    top
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍѤΤµ¤ìÊý

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï .htaccess + ¥Õ¥¡¥¤¥ë¤Î¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤È¡¢¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤¹¤Ù¤Æ¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + ¤·¤«¤·¡¢¾å¤Î³¬ÁؤΥǥ£¥ì¥¯¥È¥ê¤Ë¤â .htaccess ¥Õ¥¡¥¤¥ë¤¬ + ¸ºß¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¤³¤È¤ò³Ð¤¨¤Æ¤ª¤¯¤³¤È¤ÏÂçÀڤǤ¹¡£¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¸½¤ì¤ë + ½çÈÖ¤ËŬÍѤµ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î .htaccess ¤Ï + ¥Ç¥£¥ì¥¯¥È¥ê¥Ä¥ê¡¼¤Î¤è¤ê¾å¤Î³¬ÁؤΠ.htaccess ¥Õ¥¡¥¤¥ë¤Î + ÀßÄê¤ò¾å½ñ¤­¤¹¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤½¤·¤Æ¡¢¤½¤Î .htaccess ¤â + ¤è¤ê¾å¤Î³¬Áؤǽñ¤«¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¾å½ñ¤­¤·¤¿¤ê¡¢¼ç¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë + ¤½¤Î¤â¤Î¤ÎÀßÄê¤ò¾å½ñ¤­¤·¤¿¤ê¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    Îã:

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê /www/htdocs/example1 ¤Ë°Ê²¼¤ÎÆâÍƤΠ+ .htaccess ¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤¹:

    + +

    + Options +ExecCGI +

    + +

    (Ãí: .htaccess + ¥Õ¥¡¥¤¥ë¤Ç "Options" ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤Ë¤Ï¡¢ + "AllowOverride Options" ¤òÍ­¸ú¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£)

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê /www/htdocs/example1/example2 ¤Ë¤Ï + °Ê²¼¤Î¤è¤¦¤Ê .htaccess ¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤¹:

    + +

    + Options Includes +

    + +

    Æó¤Ä¤á¤Î .htaccess ¤Ë¤è¤ê¡¢¥Ç¥£¥ì¥¯¥È¥ê + /www/htdocs/example1/example2 ¤Ç¤Ï CGI ¤Î¼Â¹Ô¤Ï + µö²Ä¤µ¤ì¤Þ¤»¤ó¡£¤³¤ì¤Ï¡¢Options Includes ¤Î¤ß¤¬ + ¸úÎϤò»ý¤Á¡¢¤½¤ì¤¬¤¹¤Ù¤Æ¤Î°ÊÁ°¤ÎÀßÄê¤ò¾å½ñ¤­¤¹¤ë¤«¤é¤Ç¤¹¡£

    + +

    ¥á¥¤¥óÀßÄê¥Õ¥¡¥¤¥ë¤ËÂФ¹¤ë + .htaccess ¤Î¥Þ¡¼¥¸

    + +

    As discussed in the documentation on Configuration Sections, + .htaccess files can override the <Directory> sections for + the corresponding directory, but will be overriden by other types + of configuration sections from the main configuration files. This + fact can be used to enforce certain configurations, even in the + presence of a liberal AllowOverride setting. For example, to + prevent script execution while allowing anything else to be set in + .htaccess you can use:

    +

    ¥»¥¯¥·¥ç¥ó¤ÎÀßÄê + ¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢.htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ + <Directory> + ¥»¥¯¥·¥ç¥ó¤ÎÀßÄê¤ò¥Ç¥£¥ì¥¯¥È¥êËè¤Ë¾å½ñ¤­¤Ç¤­¤Þ¤¹¤¬¡¢ + ¥á¥¤¥óÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ë¤¢¤ë¡¢Â¾¤Î¼ïÎà¤ÎÀßÄꥻ¥¯¥·¥ç¥ó¤Ë¤è¤Ã¤Æ + ¤µ¤é¤Ë¾å½ñ¤­¤µ¤ì¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£ + ¤³¤ÎÆÃħ¤ò»È¤Ã¤Æ¡¢ + AllowOverride + ¤Ç¼«Í³Å٤ι⤤ÀßÄ꤬¤¢¤Ã¤¿¤È¤·¤Æ¤â¡¢¤¢¤ëÆÃÄê¤ÎÀßÄ꤬³Î¼Â¤Ë + È¿±Ç¤µ¤ì¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤Ï + ÉÔµö²Ä¤Ë¡¢¤«¤Ä¡¢.htaccess ¤Ç¤½¤Î¾¤Î¹àÌÜ¤Ï + ÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¡¢¤È¤¤¤¦¾ì¹ç¤Ï¼¡¤Î¤è¤¦¤Ë¤Ç¤­¤Þ¤¹ :

    + +

    +<Directory />
    + +Allowoverride All
    +
    +</Directory>
    +
    +<Location />
    + +Options +IncludesNoExec -ExecCGI
    +
    +</Location> +

    + + +
    top
    +
    +

    ǧ¾Ú¤ÎÎã

    + +

    ¤â¤·Ç§¾Ú¤ÎÊýË¡¤òÃΤ뤿¤á¤Ë¤³¤ÎÉôʬ¤ËľÀÜÍ褿¤Î¤Ç¤¢¤ì¤Ð¡¢¼¡¤Î¤³¤È¤ò + ÃΤäƤª¤¯¤³¤È¤¬½ÅÍפǤ¹¡£¤è¤¯¤¢¤ë¸í²ò¤Ë¡¢¥Ñ¥¹¥ï¡¼¥Éǧ¾Ú¤ò¹Ô¤Ê¤¦¤¿¤á¤Ë¤Ï + .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤¦É¬Íפ¬¤¢¤ë¡¢¤È¤¤¤¦¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤ÏÀµ¤·¤¯¤¢¤ê¤Þ¤»¤ó¡£¼ç¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤Î <Directory> ¥»¥¯¥·¥ç¥ó¤Ë + ǧ¾ÚÍѤΥǥ£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯Êý¤¬¿ä¾©¤µ¤ì¤ëÊýË¡¤Ç¡¢.htaccess + ¥Õ¥¡¥¤¥ë¤Ï¼ç¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤òÊѹ¹¤Ç¤­¤Ê¤¤¤È¤­¤Ë¤Î¤ß»ÈÍѤ¹¤Ù¤­¤Ç¤¹¡£ + ¤¤¤Ä .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤¦¤Ù¤­¤Ç¡¢¤¤¤Ä»È¤¦¤Ù¤­¤Ç¤Ï¤Ê¤¤¤«¤Ë + ¤Ä¤¤¤Æ¤Ï ¾å¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    °Ê¾å¤Î¤³¤È¤ò¤Õ¤Þ¤¨¤¿¾å¤Ç¡¢¤â¤· .htaccess ¤Î»ÈÍѤ¬ + ¤Þ¤ÀɬÍפÀ¤È»×¤¦¾ì¹ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ê¤â¤Î¤¬Ë¾¤ß¤Î¤³¤È¤ò¤·¤Æ¤¯¤ì¤ë¤«¤â + ¤·¤ì¤Þ¤»¤ó¡£

    + +

    .htaccess ¥Õ¥¡¥¤¥ë¤ÎÆâÍÆ:

    + +

    + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +

    + +

    ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤Ë¤Ï¡¢ + AllowOverride AuthConfig ¤¬Í­¸ú¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ǧ¾Ú¤È¾µÇ§¤Ë¤Ä¤¤¤Æ¤Ï ǧ¾Ú¥Á¥å¡¼¥È¥ê¥¢¥ë¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    SSI ¤ÎÎã

    + +

    ¤â¤¦°ì¤Ä¤Î .htaccess ¥Õ¥¡¥¤¥ë¤Î¤è¤¯¤¢¤ëÍøÍÑË¡¤Ï + ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç SSI ¤òÍ­¸ú¤Ë¤¹¤ë¤³¤È¤Ç¤¹¡£¤³¤ì¤Ï¡¢Ë¾¤ß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î + .htaccess ¥Õ¥¡¥¤¥ë¤Ë°Ê²¼¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤Ç + ãÀ®¤Ç¤­¤Þ¤¹:

    + +

    + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +

    + +

    ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤Ë¤Ï¡¢ + AllowOverride Options ¤È AllowOverride + FileInfo ¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¤è¤ê¤Þ¤È¤Þ¤Ã¤¿ SSI ¤ÎÀâÌÀ¤Ï SSI ¥Á¥å¡¼¥È¥ê¥¢¥ë¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    CGI ¤ÎÎã

    + +

    ºÇ¸å¤Ë¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç CGI ¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤òµö²Ä¤·¤¿¤¤¤³¤È¤¬ + ¤¢¤ë¤Ç¤·¤ç¤¦¡£¤³¤ì¤Ï°Ê²¼¤ÎÀßÄê¤Ç¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + Options +ExecCGI
    + AddHandler cgi-script cgi pl +

    + +

    ¤â¤·¤¯¤Ï¡¢¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤¬ CGI ¥×¥í¥°¥é¥à¤È + ¤ß¤Ê¤µ¤ì¤ë¤è¤¦¤Ë¤·¤¿¤¤¤Ê¤é¡¢°Ê²¼¤ÎÀßÄê¤Ç¼Â¸½¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + Options +ExecCGI
    + SetHandler cgi-script +

    + +

    ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤Ë¤Ï¡¢ + AllowOverride Options ¤È AllowOverride + FileInfo ¤¬Í­¸ú¤Ç¤¢¤ëɬÍפ¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    CGI ¥×¥í¥°¥é¥à¤ÈÀßÄê¤Î¤è¤ê¤Þ¤È¤Þ¤Ã¤¿ÀâÌÀ¤Ï CGI ¥Á¥å¡¼¥È¥ê¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    ÌäÂê²ò·è

    + +

    ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò .htaccess ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¤¤¿¤±¤ì¤É¤â¡¢ + ´üÂÔ¤·¤¿¸ú²Ì¤¬ÆÀ¤é¤ì¤Ê¤¤¤È¤­¤Ë¤Ï¡¢¤¤¤¯¤Ä¤«¤Î¸¶°ø¤¬¹Í¤¨¤é¤ì¤Þ¤¹¡£

    + +

    °ìÈ֤褯¤¢¤ë¤³¤È¤Ï¡¢ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¹Í褵¤ì¤ë¤è¤¦¤Ë¤Ï + AllowOverride ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤ + ¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£³ºÅö¤Î¥Õ¥¡¥¤¥ë¤Î¥¹¥³¡¼¥×¤Ë AllowOverride None + ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤òÄ´¤Ù¤ë¤¿¤á¤ÎÎɤ¤ÊýË¡¤Ï¡¢ + .htaccess ¥Õ¥¡¥¤¥ë¤Ë¤´¤ß¤ò½ñ¤¤¤Æ¡¢¥ê¥í¡¼¥É¤¹¤ë¤³¤È¤Ç¤¹¡£ + ¥µ¡¼¥Ð¤Î¥¨¥é¡¼¤¬À¸À®¤µ¤ì¤Ê¤¤¤È¤­¤Ï¡¢¤Û¤Ü³Î¼Â¤Ë AllowOverride + None ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾õÂ֤ˤʤäƤ¤¤Þ¤¹¡£

    + +

    ¤½¤¦¤Ç¤Ï¤Ê¤¯¡¢Ê¸½ñ¤ò¥¢¥¯¥»¥¹¤·¤è¤¦¤È¤·¤¿¤È¤­¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Æ¤¤¤ë + ¤È¤­¤Ï¡¢Apache ¤Î¥¨¥é¡¼¥í¥°¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£.htaccess ¥Õ¥¡¥¤¥ë¤Ç + »ÈÍѤµ¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¡¢¤È¤¤¤¦¤³¤È¤òÃΤ餻¤Æ¤¤¤ë + ²ÄǽÀ­¤¬¹â¤¤¤Ç¤¹¡£¤Þ¤¿¤Ï¡¢¹½Ê¸¤Î´Ö°ã¤¤¤¬¤¢¤ë¤³¤È¤ò½Ò¤Ù¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¾ì¹ç¤Ë¤Ï¤Þ¤º¤½¤ì¤ò½¤Àµ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/htaccess.html.ko.euc-kr b/trunk/docs/manual/howto/htaccess.html.ko.euc-kr new file mode 100644 index 0000000000..e7e3f1835e --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.html.ko.euc-kr @@ -0,0 +1,333 @@ + + + +¾ÆÆÄÄ¡ ÅõÅ丮¾ó: .htaccess ÆÄÀÏ - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ ÅõÅ丮¾ó: .htaccess ÆÄÀÏ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko  | + pt-br 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© µð·ºÅ丮º°·Î ¼³Á¤À» +º¯°æÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    top
    +
    +

    ¹«¾ùÀ̸ç/¾î¶»°Ô »ç¿ëÇϴ°¡

    + + +

    .htaccess ÆÄÀÏ(ȤÀº "ºÐ»ê ¼³Á¤ÆÄÀÏ")À» + »ç¿ëÇÏ¸é µð·ºÅ丮º°·Î ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖ´Ù. ¿©·¯ ¼³Á¤ Áö½Ã¾î°¡ + ÀÖ´Â ÆÄÀÏÀ» ƯÁ¤ ¹®¼­ µð·ºÅ丮¿¡ µÎ¸é, ±× µð·ºÅ丮¿Í ¸ðµç + ÇÏÀ§µð·ºÅ丮¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù.

    + +

    ÁÖÀÇ:

    +

    .htaccess ÆÄÀϸíÀ» ´Ù¸£°Ô »ç¿ëÇÏ°í ½Í´Ù¸é, + AccessFileName Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© º¯°æÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, .config + ÆÄÀϸíÀ» »ç¿ëÇÏ·Á¸é ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    + +

    + AccessFileName .config +

    +
    + +

    ÀϹÝÀûÀ¸·Î .htaccess ÆÄÀÏÀº ÁÖ¼³Á¤ÆÄÀÏ°ú ¹®¹ýÀÌ + °°´Ù. AllowOverride + Áö½Ã¾î°¡ ÀÌ ÆÄÀÏ¿¡ ³ª¿Ã ¼ö ÀÖ´Â ³»¿ëÀ» °áÁ¤ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + .htaccess ÆÄÀÏ¿¡¼­ Çã¿ëÇÏ´Â Áö½Ã¾î ºÐ·ù¸¦ ÁöÁ¤ÇÑ´Ù. + Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù¸é, + ÇØ´ç Áö½Ã¾î ¹®¼­ÀÇ Override Ç׸ñÀº Áö½Ã¾î¸¦ Çã¿ëÇϱâÀ§ÇØ + AllowOverride¿¡ »ç¿ëÇÒ + °ªÀ» ¾Ë·ÁÁØ´Ù.

    + +

    ¿¹¸¦ µé¾î, AddDefaultCharset + Áö½Ã¾î ¹®¼­¸¦ º¸¸é ÀÌ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. (Áö½Ã¾î ¿ä¾à¿¡¼­ »ç¿ëÀå¼Ò Ç׸ñÀ» º¸¶ó.) + Override + ÁÙ¿¡ FileInfo°¡ ÀÖ´Ù. ±×·¡¼­ ÀÌ Áö½Ã¾î¸¦ + .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇϱâÀ§Çؼ­´Â ÃÖ¼ÒÇÑ + AllowOverride FileInfo°¡ ÇÊ¿äÇÏ´Ù.

    + +

    ¿¹Á¦:

    + + + + + + + + + +
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override:FileInfo
    + +

    ƯÁ¤ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ + ¼ö ÀÖ´ÂÁö ±Ã±ÝÇϸé Áö½Ã¾î ¹®¼­ÀÇ »ç¿ëÀå¼Ò Ç׸ñ¿¡ ".htaccess"°¡ + ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.

    +
    top
    +
    +

    ¾ðÁ¦ .htaccess ÆÄÀÏÀ» »ç¿ëÇϳª + (ȤÀº »ç¿ëÇÏÁö ¾Ê³ª)

    + +

    ÀϹÝÀûÀ¸·Î ÁÖ¼­¹öÆÄÀÏ¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ¾Æ´Ï¶ó¸é + .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ¿¹¸¦ µé¾î, + »ç¿ëÀÚ ÀÎÁõÀÌ Ç×»ó .htaccess ÆÄÀÏ¿¡ ÀÖ¾î¾ß + ÇÑ´Ù´Â °ÍÀº À߸ø ¾Ë·ÁÁø ¿ÀÇØ´Ù. ÀÌ´Â »ç½ÇÀÌ ¾Æ´Ï´Ù. ÁÖ¼­¹ö¼³Á¤¿¡ + »ç¿ëÀÚ ÀÎÁõ ¼³Á¤À» ÀûÀ» ¼ö ÀÖ°í, »ç½Ç ÀÌ·¯±æ ±ÇÇÑ´Ù.

    + +

    .htaccess ÆÄÀÏÀº ÄÁÅÙÃ÷ Á¦°øÀÚ°¡ µð·ºÅ丮º°·Î + ¼­¹ö ¼³Á¤À» ´Ù¸£°ÔÇÏ°í ½ÍÁö¸¸ ¼­¹ö ½Ã½ºÅÛ¿¡ root ±ÇÇÑÀÌ + ¾ø´Â °æ¿ì¿¡ »ç¿ëÇÑ´Ù. ¼­¹ö °ü¸®ÀÚ°¡ ¼³Á¤À» ÀÚÁÖ º¯°æÇÏ°í + ½ÍÁö ¾ÊÀº °æ¿ì ÀÏ¹Ý »ç¿ëÀÚ°¡ Á÷Á¢ .htaccess + ÆÄÀÏÀ» ¼öÁ¤Çϵµ·Ï Çã¿ëÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. ¿¹¸¦ µé¾î, ÇÑ + ÄÄÇ»ÅÍ¿¡ ¿©·¯ »ç¿ëÀÚ »çÀÌÆ®¸¦ ¼­ºñ½ºÇÏ´Â ISP¿¡¼­ »ç¿ëÀÚ°¡ + ÀÚ½ÅÀÇ ¼³Á¤À» º¯°æÇÏ°í ½ÍÀº °æ¿ì°¡ ±×·¯ÇÏ´Ù.

    + +

    ±×·¯³ª ÀϹÝÀûÀ¸·Î .htaccess ÆÄÀÏÀº °¡±ÞÀû + ÇÇÇØ¾ß ÇÑ´Ù. .htaccess ÆÄÀÏ¿¡¼­ Çã¿ëÇÏ´Â Áö½Ã¾î´Â + ÁÖ¼³Á¤ÆÄÀÏÀÇ <Directory> ¼½¼Ç°ú °°Àº È¿°ú°¡ + ÀÖ´Ù.

    + +

    ´ÙÀ½ µÎ°¡Áö Å« ÀÌÀ¯¶§¹®¿¡ .htaccess ÆÄÀÏ + »ç¿ëÀ» ÇÇÇØ¾ß ÇÑ´Ù.

    + +

    ù¹ø°´Â ¼º´ÉÀÌ´Ù. AllowOverride°¡ .htaccess + ÆÄÀÏÀ» »ç¿ëÇϵµ·Ï Çã¿ëÇϸé, ¾ÆÆÄÄ¡´Â µð·ºÅ丮¸¶´Ù + .htaccess ÆÄÀÏÀ» ã´Â´Ù. ±×·¡¼­ + .htaccess ÆÄÀÏÀ» Çã¿ëÇÏ¸é ½ÇÁ¦·Î ÆÄÀÏÀ» »ç¿ëÇÏÁö + ¾Ê´Â °æ¿ì¿¡µµ ¼º´ÉÀÌ ¶³¾îÁø´Ù! ¶Ç, .htaccess + ÆÄÀÏÀº ¹®¼­¸¦ ¿äûÇÒ¶§¸¶´Ù ÀоîµéÀδÙ.

    + +

    °Ô´Ù°¡ Àû¿ëÇØ¾ß ÇÏ´Â Àüü Áö½Ã¾î¸¦ ¸ðÀ¸±âÀ§ÇØ ¾ÆÆÄÄ¡´Â + ¸ðµç »óÀ§ µð·ºÅ丮¿¡¼­ .htaccess ÆÄÀÏÀ» ã´Â´Ù. + (¾î¶»°Ô Áö½Ã¾î¸¦ Àû¿ëÇϳª ÀýÀ» Âü°í.) + ±×·¡¼­ /www/htdocs/example µð·ºÅ丮¿¡ ÀÖ´Â + ÆÄÀÏÀ» ¿äûÇϸé, ¾ÆÆÄÄ¡´Â ´ÙÀ½ ÆÄÀϵéÀ» ã¾Æ¾ß ÇÑ´Ù.

    + +

    + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +

    + +

    ±×·¡¼­ ±× µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏÀ» Á¢±ÙÇÒ ¶§¸¶´Ù ¼³Á¤ÆÄÀÏÀÌ + ÀüÇô ¾ø¾îµµ ÆÄÀϽýºÅÛÀ» 4¹ø ´õ Á¢±ÙÇØ¾ß ÇÑ´Ù. + (/¿¡¼­µµ .htaccess ÆÄÀÏÀ» Çã¿ëÇÑ + °æ¿ì¸¦ ¸»ÇÑ´Ù. º¸ÅëÀº Çã¿ëÇÏÁö ¾Ê´Â´Ù.)

    + +

    µÎ¹ø° ÀÌÀ¯´Â º¸¾ÈÀÌ´Ù. »ç¿ëÀÚ¿¡°Ô ¼­¹ö¼³Á¤ º¯°æ ±ÇÇÑÀ» + ÁÖ¸é ´ç½ÅÀÌ °¨´çÇÒ ¼ö ¾ø´Â º¯È­°¡ ÀϾ ¼ö ÀÖ´Ù. »ç¿ëÀÚ¿¡°Ô + ÀÌ·± ±ÇÇÑÀ» ÁÙÁö °õ°õÀÌ »ý°¢Ç϶ó. ¶Ç, »ç¿ëÀÚ°¡ ¿øÇÏ´Â °Íº¸´Ù + ÀûÀº ±ÇÇÑÀ» ÁÖ¸é ±â¼úÁö¿ø¿äûÀÌ µé¾î¿Â´Ù. »ç¿ëÀÚ¿¡°Ô °¡´ÉÇÑ + ±ÇÇÑ ¼öÁØÀ» ¸íÈ®È÷ ¾Ë·Á¶ó. »ç¿ëÀÚ¿¡°Ô AllowOverride¸¦ ¾î¶»°Ô ¼³Á¤ÇÏ¿´´ÂÁö + Á¤È®È÷ ¾Ë¸®°í °ü·Ã ¹®¼­¸¦ Á¦°øÇÏ¸é ¾ÕÀ¸·Î È¥¶õÀ» ÇÇÇÒ ¼ö + ÀÖ´Ù.

    + +

    Áö½Ã¾î¸¦ /www/htdocs/example µð·ºÅ丮ÀÇ + .htaccess ÆÄÀÏÀ» µÎ´Â °Í°ú ÁÖ¼­¹ö¼³Á¤ÀÇ + <Directory /www/htdocs/example> Directory + ¼³Á¤¿¡ µÎ´Â °ÍÀº ¿ÏÀüÈ÷ °°´Ù.

    + +

    /www/htdocs/example¿¡ ÀÖ´Â + .htaccess ¼½¼Ç:

    + +

    /www/htdocs/example¿¡ ÀÖ´Â + .htaccess ÆÄÀÏ ³»¿ë

    + AddType text/example .exm +

    + +

    httpd.conf ÆÄÀÏ¿¡ ÀÖ´Â ¼½¼Ç

    + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +

    + +

    ±×·¯³ª ÆÄÀÏÀ» ¿äûÇÒ ¶§¸¶´Ù ¼³Á¤À» ÀÐÁö¾Ê°í ¾ÆÆÄÄ¡°¡ + ½ÃÀÛÇÒ¶§ Çѹø¸¸ ¼³Á¤À» Àб⶧¹®¿¡ °°Àº ¼³Á¤À» ¼­¹ö¼³Á¤ÆÄÀÏ¿¡ + »ç¿ëÇÏ¸é ¼º´ÉÀÌ ´õ ºü¸£´Ù.

    + +

    AllowOverride Áö½Ã¾î¸¦ + noneÀ¸·Î ¼³Á¤Çϸé .htaccess ÆÄÀÏÀ» + ¿ÏÀüÈ÷ »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    + AllowOverride None +

    +
    top
    +
    +

    ¾î¶»°Ô Áö½Ã¾î¸¦ Àû¿ëÇϳª

    + +

    .htaccess ÆÄÀÏÀ» ¹ß°ßÇÑ µð·ºÅ丮¿Í ±× µð·ºÅ丮ÀÇ + ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ .htaccess ÆÄÀÏ¿¡ ÀÖ´Â ¼³Á¤ + Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ±×·¡¼­ »óÀ§µð·ºÅ丮ÀÇ .htaccess + ÆÄÀÏÀ» ÁÖÀÇÇØ¾ß ÇÑ´Ù. ¹ß°ßÇÑ ¼ø¼­·Î Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ƯÁ¤ + µð·ºÅ丮¿¡ ÀÖ´Â .htaccess ÆÄÀÏÀº »óÀ§µð·ºÅ丮¿¡ + ÀÖ´Â .htaccess ÆÄÀÏÀÇ Áö½Ã¾î¸¦ ¹«È¿·Î ¸¸µé + ¼ö ÀÖ°í, »óÀ§µð·ºÅ丮¿¡ ÀÖ´Â Áö½Ã¾î´Â ´õ »óÀ§µð·ºÅ丮 ȤÀº + ÁÖ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ ¹«È¿·Î ¸¸µé ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦:

    + +

    /www/htdocs/example1 µð·ºÅ丮¿¡ ´ÙÀ½°ú °°Àº + .htaccess ÆÄÀÏÀÌ ÀÖ´Ù.

    + +

    + Options +ExecCGI +

    + +

    (ÁÖÀÇ: .htaccess ÆÄÀÏ¿¡ "Options" Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á¸é + "AllowOverride Options"°¡ ÇÊ¿äÇÏ´Ù.)

    + +

    /www/htdocs/example1/example2 µð·ºÅ丮¿¡´Â + ´ÙÀ½°ú °°Àº .htaccess ÆÄÀÏÀÌ ÀÖ´Ù.

    + +

    + Options Includes +

    + +

    ÀÌ µÎ¹ø° .htaccess ÆÄÀÏÀÇ + Options Includes°¡ ÀÌÀü ¼³Á¤À» ¿ÏÀüÈ÷ ¹«È¿·Î + ¸¸µé±â¶§¹®¿¡ /www/htdocs/example1/example2 + µð·ºÅ丮´Â CGI ½ÇÇàÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù.

    +
    top
    +
    +

    ÀÎÁõ ¿¹Á¦

    + +

    ÀÎÁõ ¹æ¹ýÀ» ¾Ë±âÀ§ÇØ ¹Ù·Î ÀÌ°÷ºÎÅÍ Àд´ٸé ÁÖÀÇÇÒ °ÍÀÌ + ÀÖ´Ù. ¾ÏÈ£ ÀÎÁõÀ» ÇÏ·Á¸é .htaccess ÆÄÀÏÀÌ + ÇÊ¿äÇÏ´Ù´Â ¿ÀÇØ°¡ ³Î¸® ÆÛÁ®ÀÖ´Ù. ÀÌ´Â »ç½ÇÀÌ ¾Æ´Ï´Ù. + ÁÖ¼³Á¤ÆÄÀÏÀÇ <Directory> ¼½¼Ç¿¡ ÀÎÁõ Áö½Ã¾î¸¦ + µÎ´Â °ÍÀÌ ´õ ±ÇÀåÇÏ´Â ¹æ¹ýÀÌ°í, ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÒ + ¼ö ¾ø´Â °æ¿ì¿¡¸¸ .htaccess ÆÄÀÏÀ» »ç¿ëÇØ¾ß + ÇÑ´Ù. ¾ðÁ¦ .htaccess ÆÄÀÏÀ» »ç¿ëÇØ¾ß ÇÏ´ÂÁö¿Í + »ç¿ëÇÏÁö ¸»¾Æ¾ß ÇÏ´ÂÁö´Â À§¿¡¼­ + ¼³¸íÇÏ¿´´Ù.

    + +

    ¾Õ¿¡¼­ ¸»ÇßÁö¸¸ ¾ÆÁ÷µµ .htaccess ÆÄÀÏÀÌ + ÇÊ¿äÇÏ´Ù°í »ý°¢µÇ¸é ¾Æ·¡ ¼³Á¤ÀÌ µµ¿òÀÌ µÉ °ÍÀÌ´Ù.

    + +

    .htaccess ÆÄÀÏ ³»¿ë.

    + +

    + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +

    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇϱâÀ§Çؼ­´Â + AllowOverride AuthConfig Áö½Ã¾î°¡ ÇÊ¿äÇÔÀ» + ¸í½ÉÇ϶ó.

    + +

    ÀÎÁõ°ú ±ÇÇѺο©¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ÀÎÁõ + ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    +
    top
    +
    +

    Server Side Includes ¿¹Á¦

    + +

    ¶Ç´Ù¸¥ ÀϹÝÀûÀÎ .htaccess ÆÄÀÏÀÇ ¿ëµµ´Â + ƯÁ¤ µð·ºÅ丮¿¡¼­ Server Side Includes¸¦ °¡´ÉÇÏ°Ô ¸¸µå´Â + °ÍÀÌ´Ù. ¿øÇÏ´Â µð·ºÅ丮ÀÇ .htaccess ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°Àº ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é µÈ´Ù.

    + +

    + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +

    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇÏ·Á¸é AllowOverride Options¿Í + AllowOverride FileInfo°¡ ¸ðµÎ ÇÊ¿äÇÔÀ» ¸í½ÉÇ϶ó.

    + +

    server-side includes¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº SSI ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    +
    top
    +
    +

    CGI ¿¹Á¦

    + +

    ¸¶Áö¸·À¸·Î .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© ƯÁ¤ + µð·ºÅ丮¿¡¼­ CGI ÇÁ·Î±×·¥ ½ÇÇàÀ» Çã¿ëÇÏ°í ½Í´Ù¸é, ´ÙÀ½°ú + °°Àº ¼³Á¤À» »ç¿ëÇÑ´Ù.

    + +

    + Options +ExecCGI
    + AddHandler cgi-script cgi pl +

    + +

    ȤÀº ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î + ó¸®ÇÏ°í ½Í´Ù¸é ´ÙÀ½°ú °°Àº ¼³Á¤µµ °¡´ÉÇÏ´Ù.

    + +

    + Options +ExecCGI
    + SetHandler cgi-script +

    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇÏ·Á¸é AllowOverride Options¿Í + AllowOverride FileInfo°¡ ¸ðµÎ ÇÊ¿äÇÔÀ» ¸í½ÉÇ϶ó.

    + +

    CGI ÇÁ·Î±×·¡¹Ö°ú ¼³Á¤¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº CGI ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    + +
    top
    +
    +

    ¹®Á¦ÇØ°á

    + +

    .htaccess ÆÄÀÏ¿¡ µÐ ¼³Á¤ Áö½Ã¾î°¡ ¿øÇÏ´Â + ±â´ÉÀ» ÇÏÁö ¾Ê´Â °æ¿ì ¿©·¯°¡Áö ÀÌÀ¯°¡ ÀÖÀ» ¼ö ÀÖ´Ù.

    + +

    °¡Àå ÀϹÝÀûÀÎ ¹®Á¦´Â ¼³Á¤ Áö½Ã¾î¸¦ °¡´ÉÇÏ°Ô ¸¸µå´Â AllowOverride¸¦ ¼³Á¤ÇÏÁö ¾ÊÀº + °æ¿ì´Ù. ¹®Á¦°¡ µÇ´Â ÆÄÀÏ ¿µ¿ª¿¡ AllowOverride NoneÀÌ + ¾ø´ÂÁö È®ÀÎÇÑ´Ù. .htaccess ÆÄÀÏÀ» ¾Æ¹«·¸°Ô³ª + ÀûÀº ´ÙÀ½ ÆäÀÌÁö¸¦ ´Ù½Ã Á¢±ÙÇÏ¿© ½±°Ô °Ë»çÇغ¼ ¼ö ÀÖ´Ù. + ¼­¹ö ¿À·ù°¡ ³ª¿ÀÁö ¾ÊÀ¸¸é °ÅÀÇ È®½ÇÈ÷ + AllowOverride NoneÀ» »ç¿ëÇÑ °æ¿ì´Ù.

    + +

    ¹Ý´ë·Î ¹®¼­¿¡ Á¢±ÙÇÒ¶§ ¼­¹ö ¿À·ù°¡ ¹ß»ýÇÏ¸é ¾ÆÆÄÄ¡ ¿À·ù·Î±×¸¦ + »ìÆìºÁ¶ó. ¾Æ¸¶µµ .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ + Çã¿ëÇÏÁö ¾Ê´Â´Ù°í ÇÒ °ÍÀÌ´Ù. ¾Æ´Ï°í ¹®¹ý ¿À·ù°¡ ÀÖ´Ù¸é ¿À·ù¸¦ + °íÄ£´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/htaccess.html.pt-br b/trunk/docs/manual/howto/htaccess.html.pt-br new file mode 100644 index 0000000000..cda6c72a20 --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.html.pt-br @@ -0,0 +1,375 @@ + + + +Tutorial do Apache: arquivos .htaccess - Servidor HTTP Apache + + + + + +
    <-
    +

    Tutorial do Apache: arquivos .htaccess

    +
    +

    Línguas Disponíveis:  en  | + ja  | + ko  | + pt-br 

    +
    + +

    Arquivos .htaccess oferecem um meio de fazer mudanças + nas configurações por-diretório.

    +
    + +
    top
    +
    top
    +
    +

    O que eles são/Como usá-los

    + + +

    Os arquivos .htaccess (ou "arquivos de + configuração distribuída") oferecem um meio de fazer mudanças nas + configurações por-diretório. Um arquivo, contendo uma ou mais + diretrizes de configurações, é colocado em um diretório + em particular, e as diretrizes se aplicam para aquele diretório e todos + os seu subdiretórios subseqüentes.

    + +

    Nota:

    +

    Se você quiser renomear o seu arquivo .htaccess + para outro nome, você deve usar a diretriz AccessFileName. Por exemplo, se você + prefere que o arquivo se chame .config, então você + pode adicionar a seguinte linha ao seu arquivo de configuração + do servidor:

    + +

    + AccessFileName .config +

    +
    + +

    No geral, arquivos .htaccess usam a mesma sintaxe + que os arquivos de + configuração principal. O que você pode colocar nesses + arquivos é determinado pele diretriz AllowOverride. Essa diretriz especifica, + em categorias, quais diretrizes serão aceitas caso sejam + encontradas em um arquivo .htaccess. Se uma diretriz + for permitida em um arquivo .htaccess, a documentação + para essa diretriz irá conter uma seção Override, + especificando que valor precisa estar em AllowOverride para que esta diretriz + seja permitida.

    + +

    Por exemplo, se você procurar na documentação pela diretriz + AddDefaultCharset, você + achará que ela é permitida nos arquivos .htaccess. + (Veja a linha Contexto no sumário das diretivas.) A + linha Override lê + FileInfo. Então, você deve ao menos ter + AllowOverride FileInfo para que essa diretriz seja + aceita nos arquivos .htaccess.

    + +

    Exemplo:

    + + + + + + + + + +
    Contexto:configuração do servidor, hospedeiros virtuais, diretório, .htaccess
    Override:FileInfo
    + +

    Se você estiver incerto se uma diretriz em particular é + aceita em um arquivo .htaccess, procure na + documentação por essa diretriz, e verifique a linha de + Contexto por ".htaccess".

    top
    +
    +

    Quando (não) usar arquivos .htaccess

    + +

    No geral, você nunca deve usar arquivos .htaccess + a não ser que você não tenha acesso ao arquivo de configuração + principal do servidor. Existe, por exemplo, um erro de concepção + que dita que a autenticação de usuários sempre deve + ser feita usando os arquivos .htaccess. Esse + simplesmente não é o caso. Você pode usar as configurações de + autenticação de usuário no arquivo de configuração principal do + servidor, e isso é, de fato, a maneira mais adequada de se fazer + as coisas.

    + +

    Arquivos .htaccess devem ser usados em casos onde + os provedores de conteúdo do site precisem fazer mudanças na + configuração do servidor por-diretório, mas não tem + acesso root ao sistema do servidor. Caso o administrador do + servidor não esteja disposto a fazer mudanças freqüentes nas + configurações do servidor, é desejável permitir que os + usuários possam fazer essas mudanças através de arquivos + .htaccess eles mesmos. Isso é particularmente + verdade, por exemplo, em casos onde provedores estão fornecendo + múltiplos sites para usuários em apenas uma máquina, e querem que + seus usuários possam alterar suas configurações.

    + +

    No entanto, de modo geral, o uso de arquivos .htaccess + deve ser evitado quando possível. Quaisquer configurações + que você considerar acrescentar em um arquivo .htaccess, podem + ser efetivamente colocadas em uma seção <Directory> no arquivo principal de + configuração de seu servidor.

    + +

    Existem duas razões principais para evitar o uso de arquivos + .htaccess.

    + +

    A primeira delas é a performance. Quando AllowOverride é configurado para + permitir o uso de arquivos .htaccess, o Apache procura + em todos diretórios por arquivos .htaccess. + Logo, permitir arquivos .htaccess causa um impacto na + performance, mesmo sem você usá-los de fato! Além disso, + o arquivo .htaccess é carregado toda vez que um documento + é requerido.

    + +

    Além disso, note que o Apache precisa procurar pelos arquivos + .htaccess em todos os diretórios superiores, para ter + o complemento total de todas as diretivas que devem ser + aplicadas. (Veja a seção como as diretrizes são + aplicadas.) Então, se um arquivo de um diretório + /www/htdocs/example é requerido, o Apache precisa + procurar pelos seguintes arquivos:

    + +

    + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +

    + +

    Assim, para cada acesso de arquivo fora desse diretório, + existem 4 acessos ao sistema de arquivos adicionais, mesmo + que nenhum desses arquivos estejam presentes. (Note que esse + só será o caso se os arquivos .htaccess + estiverem habilitados para /, o que + normalmente não é o verdade.)

    + +

    A segunda consideração é relativa à segurança. + Você está permitindo que os usuários modifiquem as + configurações do servidor, o que pode resultar em mudanças + que podem fugir ao seu controle. Considere com cuidado se você quer + ou não dar aos seus usuários esses privilégios. Note também + que dar aos usuários menos privilégios que eles precisam, acarreta em + pedidos de suporte técnico adicionais. Tenha certeza que você comunicou + aos usuários que nível de privilégios você os deu. + Especificar exatamente o que você configurou na diretriz AllowOverride, e direcioná-los para a + documentação relevante, irá poupá-lo de muita confusão + depois.

    + +

    Perceba que é exatamente equivalente colocar o arquivo + .htaccess em um diretório + /www/htdocs/example contendo uma diretriz, e + adicionar a mesma diretriz em uma seção Directory + <Directory /www/htdocs/example> na configuração + principal do seu servidor:

    + +

    Arquivo .htaccess em /www/htdocs/example:

    + +

    Conteúdo de um arquivo .htaccess em + /www/htdocs/example

    + AddType text/example .exm +

    + +

    Seção do seu arquivo httpd.conf

    + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +

    + +

    No entanto, adicionando isso ao seu arquivo de configuração do + servidor resultará em uma menor perda de performance, na medida que + a configuração é carregada no momento da inicialização do + servidor, ao invés de toda que que um arquivo é requerido.

    + +

    O uso de arquivos .htaccess pode ser totalmente + desabilitado, ajustando a diretriz AllowOverride para none:

    + +

    + AllowOverride None +

    +
    top
    +
    +

    Como as diretrizes são aplicadas

    + +

    As diretrizes de configuração que se encontram em um arquivo + .htaccess são aplicadas para o diretório no qual o + arquivo .htaccess se encontra, e para todos os + subdiretórios ali presentes. Mas, é importante lembrar também que + podem existir arquivos .htaccess no diretórios + superiores. As diretrizes são aplicadas na ordem que são + achadas. Logo, um arquivo .htaccess em um diretório + em particular, pode sobrescrever as diretrizes encontradas em um + diretório acima deste em sua respectiva árvore. Estes, por sua vez, + podem ter suas diretrizes sobrescritas por diretrizes ainda mais + acima, ou no próprio arquivo de configuração principal do + servidor.

    + +

    Exemplo:

    + +

    No diretório /www/htdocs/example1 nós temos + um arquivo .htaccess contendo o seguinte:

    + +

    + Options +ExecCGI +

    + +

    (Nota: você deve ter "AllowOverride Options" para + permitir o uso da diretriz "Options" nos arquivos + .htaccess .)

    + +

    No diretório /www/htdocs/example1/example2 nós temos + um arquivo .htaccess contendo:

    + +

    + Options Includes +

    + +

    Devido a esse segundo arquivo .htaccess, no + diretório /www/htdocs/example1/example2, a execução + de scripts CGI não é permitida, pois somente Options + Includes está em efeito, o que sobrescreve completamente + quaisquer outros ajustes previamente configurados.

    +
    top
    +
    +

    Exemplo de Autenticação

    + +

    Se você veio diretamente à esta parte do documento para + aprender como fazer autenticação, é importante notar uma + coisa. Existe uma concepção errada, mas muito comum, de que é + necessário o uso de arquivos .htaccess para implementar + a autenticação por senha. Este não é o caso. Colocar + diretrizes de senha em uma seção <Directory>, no seu arquivo principal de + configuração do servidor, é a melhor maneira de se implementar + isto, e os arquivos .htaccess devem ser usados apenas + se você não tem acesso ao arquivo principal de configuração do + servidor. Veja acima a discussão sobre quando + você deve e quando não deve usar os arquivos + .htaccess.

    + +

    Dito isso, se você ainda acredita que precisa usar um arquivo + .htaccess, a configuração a seguir provavelmente + funcionará para você.

    + +

    Conteúdo de um arquivo .htaccess:

    + +

    + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +

    + +

    Note que AllowOverride AuthConfig precisa estar + habilitado para que estas diretrizes tenham efeito.

    + +

    Por favor veja o tutorial de + autenticação para uma discussão mais completa sobre + autenticação e autorização.

    +
    top
    +
    +

    Exemplo de Server Side Includes

    + +

    Outro uso comum de arquivos .htaccess é ativar o + Server Side Includes para um diretório em particular. Isto pode + ser feito com as seguintes diretrizes de configuração, colocadas em + um arquivo .htaccess no diretório desejado:

    + +

    + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +

    + +

    Note que ambos AllowOverride Options e + AllowOverride FileInfo precisam estar habilitados + para essas diretrizes terem efeito.

    + +

    Por favor veja o tutorial de SSI para + uma discussão mais completa sobre server-side includes.

    +
    top
    +
    +

    Exemplo de CGI

    + +

    Finalmente, você pode querer que um arquivo + .htaccess permita a execução de programas CGI em um + diretório em particular. Isto pode ser implementado com as + seguintes configurações:

    + +

    + Options +ExecCGI
    + AddHandler cgi-script cgi pl +

    + +

    Alternativamente, se você desejar que todos os arquivos de um + dado diretório, sejam considerados programas CGI, isso pode ser + feito com a seguinte configuração:

    + +

    + Options +ExecCGI
    + SetHandler cgi-script +

    + +

    Note que ambos AllowOverride Options e + AllowOverride FileInfo precisam estar habilitados + para que essas diretrizes tenham quaisquer efeito.

    + +

    Por favor veja o tutorial de CGI + tutorial para uma discussão mais completa sobre programação + e configuração CGI.

    +
    top
    +
    +

    Resolvendo Problemas

    + +

    Quando você adiciona diretrizes de configuração em um arquivo + .htaccess, e não obtém o efeito desejado, existe uma + série de pontos que podem estar errados.

    + +

    Mais comumente, o problema é que a diretriz AllowOverride não está habilitada + corretamente para que as suas diretrizes de configurações sejam + honradas. Verifique se você não possui AllowOverride + None ajustado para o escopo do arquivo em questão. Um bom + meio de testar isso é colocar "lixo" em seu arquivo + .htaccess e recarregá-lo. Se não for gerado nenhum + erro do servidor, certamente você tem AllowOverride + None habilitado.

    + +

    Se, por outro lado, você está obtendo erros do servidor ao + tentar acessar documentos, verifique o registro de erros do + Apache. Ele provavelmente irá indicar que a diretriz usada em + seu arquivo .htaccess não é permitida. + Alternativamente, ele pode acusar erros de sintaxe que você terá + que corrigir.

    + +
    +
    +

    Línguas Disponíveis:  en  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/htaccess.xml b/trunk/docs/manual/howto/htaccess.xml new file mode 100644 index 0000000000..6978a65cfd --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.xml @@ -0,0 +1,409 @@ + + + + + + + + +How-To / Tutorials + +Apache Tutorial: .htaccess files + + +

    .htaccess files provide a way to make configuration +changes on a per-directory basis.

    +
    + + + +
    +What they are/How to use them + +

    .htaccess files (or "distributed configuration files") + provide a way to make configuration changes on a per-directory basis. A + file, containing one or more configuration directives, is placed in a + particular document directory, and the directives apply to that + directory, and all subdirectories thereof.

    + + Note: +

    If you want to call your .htaccess file something + else, you can change the name of the file using the AccessFileName directive. For example, + if you would rather call the file .config then you + can put the following in your server configuration file:

    + + + AccessFileName .config + +
    + +

    In general, .htaccess files use the same syntax as + the main configuration + files. What you can put in these files is determined by the + AllowOverride directive. This + directive specifies, in categories, what directives will be + honored if they are found in a .htaccess file. If a + directive is permitted in a .htaccess file, the + documentation for that directive will contain an Override section, + specifying what value must be in AllowOverride in order for that + directive to be permitted.

    + +

    For example, if you look at the documentation for the AddDefaultCharset + directive, you will find that it is permitted in .htaccess + files. (See the Context line in the directive summary.) The Override line reads + FileInfo. Thus, you must have at least + AllowOverride FileInfo in order for this directive to be + honored in .htaccess files.

    + + Example: + + + + + + + + + + +
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    +
    + +

    If you are unsure whether a particular directive is permitted in a + .htaccess file, look at the documentation for that + directive, and check the Context line for ".htaccess".

    +
    + +
    When (not) to use .htaccess files + +

    In general, you should never use .htaccess files unless + you don't have access to the main server configuration file. There is, + for example, a prevailing misconception that user authentication should + always be done in .htaccess files. This is simply not the + case. You can put user authentication configurations in the main server + configuration, and this is, in fact, the preferred way to do + things.

    + +

    .htaccess files should be used in a case where the + content providers need to make configuration changes to the server on a + per-directory basis, but do not have root access on the server system. + In the event that the server administrator is not willing to make + frequent configuration changes, it might be desirable to permit + individual users to make these changes in .htaccess files + for themselves. This is particularly true, for example, in cases where + ISPs are hosting multiple user sites on a single machine, and want + their users to be able to alter their configuration.

    + +

    However, in general, use of .htaccess files should be + avoided when possible. Any configuration that you would consider + putting in a .htaccess file, can just as effectively be + made in a Directory section in your main server + configuration file.

    + +

    There are two main reasons to avoid the use of + .htaccess files.

    + +

    The first of these is performance. When AllowOverride + is set to allow the use of .htaccess files, Apache will + look in every directory for .htaccess files. Thus, + permitting .htaccess files causes a performance hit, + whether or not you actually even use them! Also, the + .htaccess file is loaded every time a document is + requested.

    + +

    Further note that Apache must look for .htaccess files + in all higher-level directories, in order to have a full complement of + directives that it must apply. (See section on how + directives are applied.) Thus, if a file is requested out of a + directory /www/htdocs/example, Apache must look for the + following files:

    + + + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +
    + +

    And so, for each file access out of that directory, there are 4 + additional file-system accesses, even if none of those files are + present. (Note that this would only be the case if + .htaccess files were enabled for /, which + is not usually the case.)

    + +

    The second consideration is one of security. You are permitting + users to modify server configuration, which may result in changes over + which you have no control. Carefully consider whether you want to give + your users this privilege. Note also that giving users less + privileges than they need will lead to additional technical support + requests. Make sure you clearly tell your users what level of + privileges you have given them. Specifying exactly what you have set + AllowOverride to, and pointing them + to the relevant documentation, will save yourself a lot of confusion + later.

    + +

    Note that it is completely equivalent to put a .htaccess + file in a directory /www/htdocs/example containing a + directive, and to put that same directive in a Directory section + <Directory /www/htdocs/example> in your main server + configuration:

    + +

    .htaccess file in /www/htdocs/example:

    + + Contents of .htaccess file in + <code>/www/htdocs/example</code> + AddType text/example .exm + + + Section from your <code>httpd.conf</code> + file + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +
    + +

    However, putting this configuration in your server configuration + file will result in less of a performance hit, as the configuration is + loaded once when Apache starts, rather than every time a file is + requested.

    + +

    The use of .htaccess files can be disabled completely + by setting the AllowOverride + directive to none:

    + + + AllowOverride None + +
    + +
    How directives are applied + +

    The configuration directives found in a .htaccess file + are applied to the directory in which the .htaccess file + is found, and to all subdirectories thereof. However, it is important + to also remember that there may have been .htaccess files + in directories higher up. Directives are applied in the order that they + are found. Therefore, a .htaccess file in a particular + directory may override directives found in .htaccess files + found higher up in the directory tree. And those, in turn, may have + overridden directives found yet higher up, or in the main server + configuration file itself.

    + +

    Example:

    + +

    In the directory /www/htdocs/example1 we have a + .htaccess file containing the following:

    + + + Options +ExecCGI + + +

    (Note: you must have "AllowOverride Options" in effect + to permit the use of the "Options" directive in + .htaccess files.)

    + +

    In the directory /www/htdocs/example1/example2 we have + a .htaccess file containing:

    + + + Options Includes + + +

    Because of this second .htaccess file, in the directory + /www/htdocs/example1/example2, CGI execution is not + permitted, as only Options Includes is in effect, which + completely overrides any earlier setting that may have been in + place.

    + +
    Merging of .htaccess with the main + configuration files + +

    As discussed in the documentation on Configuration Sections, + .htaccess files can override the Directory sections for + the corresponding directory, but will be overriden by other types + of configuration sections from the main configuration files. This + fact can be used to enforce certain configurations, even in the + presence of a liberal AllowOverride setting. For example, to + prevent script execution while allowing anything else to be set in + .htaccess you can use:

    + + +<Directory />
    + +Allowoverride All
    +
    +</Directory>
    +
    +<Location />
    + +Options +IncludesNoExec -ExecCGI
    +
    +</Location> +
    +
    + +
    + +
    Authentication example + +

    If you jumped directly to this part of the document to find out how + to do authentication, it is important to note one thing. There is a + common misconception that you are required to use + .htaccess files in order to implement password + authentication. This is not the case. Putting authentication directives + in a Directory + section, in your main server configuration file, is the preferred way + to implement this, and .htaccess files should be used only + if you don't have access to the main server configuration file. See above for a discussion of when you should and should + not use .htaccess files.

    + +

    Having said that, if you still think you need to use a + .htaccess file, you may find that a configuration such as + what follows may work for you.

    + +

    .htaccess file contents:

    + + + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +
    + +

    Note that AllowOverride AuthConfig must be in effect + for these directives to have any effect.

    + +

    Please see the authentication tutorial for a + more complete discussion of authentication and authorization.

    +
    + +
    Server Side Includes example + +

    Another common use of .htaccess files is to enable + Server Side Includes for a particular directory. This may be done with + the following configuration directives, placed in a + .htaccess file in the desired directory:

    + + + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +
    + +

    Note that AllowOverride Options and AllowOverride + FileInfo must both be in effect for these directives to have any + effect.

    + +

    Please see the SSI tutorial for a more + complete discussion of server-side includes.

    +
    + +
    CGI example + +

    Finally, you may wish to use a .htaccess file to permit + the execution of CGI programs in a particular directory. This may be + implemented with the following configuration:

    + + + Options +ExecCGI
    + AddHandler cgi-script cgi pl +
    + +

    Alternately, if you wish to have all files in the given directory be + considered to be CGI programs, this may be done with the following + configuration:

    + + + Options +ExecCGI
    + SetHandler cgi-script +
    + +

    Note that AllowOverride Options and AllowOverride + FileInfo must both be in effect for these directives to have any + effect.

    + +

    Please see the CGI tutorial for a more + complete discussion of CGI programming and configuration.

    + +
    + +
    Troubleshooting + +

    When you put configuration directives in a .htaccess + file, and you don't get the desired effect, there are a number of + things that may be going wrong.

    + +

    Most commonly, the problem is that AllowOverride is not + set such that your configuration directives are being honored. Make + sure that you don't have a AllowOverride None in effect + for the file scope in question. A good test for this is to put garbage + in your .htaccess file and reload. If a server error is + not generated, then you almost certainly have AllowOverride + None in effect.

    + +

    If, on the other hand, you are getting server errors when trying to + access documents, check your Apache error log. It will likely tell you + that the directive used in your .htaccess file is not + permitted. Alternately, it may tell you that you had a syntax error, + which you will then need to fix.

    + +
    + +
    diff --git a/trunk/docs/manual/howto/htaccess.xml.ja b/trunk/docs/manual/howto/htaccess.xml.ja new file mode 100644 index 0000000000..0c29239f3b --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.xml.ja @@ -0,0 +1,408 @@ + + + + + + + + +How-To / $B%A%e!<%H%j%"%k(B + +Apache $B%A%e!<%H%j%"%k(B: .htaccess $B%U%!%$%k(B + + +

    .htaccess $B%U%!%$%k$O%G%#%l%/%H%jKh$K@_Dj$rJQ99$9$kJ}K!$r(B +$BDs6!$7$^$9!#(B

    +
    + + + +
    +.htaccess $B%U%!%$%k$H$O2?$+(B/$B$=$N;H$$J}(B + +

    .htaccess $B%U%!%$%k(B ($B!VJ,;6@_Dj%U%!%$%k!W(B) $B$O(B + $B%G%#%l%/%H%jKh$K@_Dj$rJQ99$9$kJ}K!$rDs6!$7$^$9!#%G%#%l%/%F%#%V$N(B + $B=q$+$l$?%U%!%$%k$r%G%#%l%/%H%j$KCV$/$3$H$G!"$=$N%G%#%l%/%H%j$H$=$N(B + $B%5%V%G%#%l%/%H%j$9$Y$F$K%G%#%l%/%F%#%V$rE,MQ$5$;$k$3$H$,$G$-$^$9!#(B

    + + $BCm(B: +

    .htaccess $B%U%!%$%k$rJL$NL>A0$K$7$?$$>l9g$O!"(B + AccessFileName $B%G%#%l%/%F%#%V$r(B + $B;H$C$FJQ99$9$k$3$H$,$G$-$^$9!#Nc$($P!"$=$N%U%!%$%k$r(B .config + $B$H$$$&L>A0$K$7$?$$>l9g$O!"0J2<$N@_Dj$r%5!<%P@_Dj%U%!%$%k$KF~$l$k$3$H$,(B + $B$G$-$^$9(B:

    + + + AccessFileName .config + +
    + +

    $B0lHL$K!"(B.htaccess $B%U%!%$%k$N9=J8$O(B + $B + $B$HF1$8$G$9!#$3$l$i$N%U%!%$%k$K=q$/$3$H$N$G$-$k%G%#%l%/%F%#%V$O(B AllowOverride $B%G%#%l%/%F%#%V$K$h$j7h$^$j$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$O!"(B.htaccess $B%U%!%$%k$K(B + $B=q$+$l$?%G%#%l%/%F%#%V$NCf$G!"!"(B + $B$I$N%G%#%l%/%F%#%V$,E,MQ$5$l$k$+$r%+%F%4%j!.htaccess $B$K=q$/$3$H$N$G$-$k%G%#%l%/%F%#%V$G$"$l$P!"(B + $B@bL@J8=q$K$O!V>e=q$-!W$H$$$&9`L\$,$"$j!"(B.htaccess $B$K=q$/$3$H$,$G$-$k$h$&$K(B + $B$J$k$?$a$N(B AllowOverride $B$NCM$,;XDj$5$l$F$$$^$9!#(B

    + +

    $BNc$($P!"(BAddDefaultCharset $B%G%#%l%/%F%#%V$N@bL@$r(B + $B8+$k$H!"(B.htaccess $B%U%!%$%k$G$N;HMQ$,5v2D$5$l$F$$$k$3$H$,(B + $B$o$+$j$^$9!#(B ($B%G%#%l%/%F%#%V$N35MW$N=j$K$"$k!V%3%s%F%-%9%H!W$H=q$+$l$F$$$k(B + $B9T$r8+$F$/$@$5$$!#(B) $B>e=q$-(B$B$H=q$+$l$F$$$k9T$K$O(B + FileInfo $B$H$"$j$^$9!#$G$9$+$i!"(B.htaccess $BCf$N(B + $B$3$N%G%#%l%/%F%#%V$,M-8z$K$J$k$?$a$K$O!">/$J$/$H$b(B + AllowOverride FileInfo $B$,@_Dj$5$l$F$$$kI,MW$,$"$j$^$9!#(B

    + + $BNc(B: + + + + + + + + + + +
    $B%3%s%F%-%9%H(B:$B%5!<%P@_Dj%U%!%$%k(B,$B%P!<%A%c%k%[%9%H(B,$B%G%#%l%/%H%j(B,.htaccess
    $B>e=q$-(B:FileInfo
    +
    + +

    $B$"$k%G%#%l%/%F%#%V$r(B .htaccess $B%U%!%$%k$K=q$/$3$H$,$G$-$k$+(B + $B$I$&$+$o$+$i$J$$$H$-$O!"$=$N%G%#%l%/%F%#%V$N@bL@$rC5$7$F!"(B".htaccess" + $B$N$?$a$N!V%3%s%F%-%9%H!W$N9T$rD4$Y$F$/$@$5$$!#(B

    +
    + +
    $B$$$D(B .htaccess $B%U%!%$%k$r;H$&(B($B;H$o$J$$(B)$B$+!#(B + +

    $B0lHLE*$K!"%5!<%P$Nl9g$r=|$$$F!"(B + .htaccess $B%U%!%$%k$N;HMQ$O6KNOHr$1$F$/$@$5$$!#(B + $B@$$NCf$K$O!"Nc$($P!"%f!<%6G'>Z$O>o$K(B .htaccess $B%U%!%$%k$G(B + $B9T$J$o$J$1$l$P$J$i$J$$!"$H$$$&8m2r$,9-$^$C$F$$$^$9$,!"$^$C$?$/$=$s$J$3$H$O(B + $B$"$j$^$;$s!#%f!<%6G'>Z$N@_Dj$O%5!<%P + +

    .htaccess $B%U%!%$%k$O%3%s%F%s%DDs6!l9g$K$N$_;H$&$Y$-$b$N$G$9!#%5!<%P4IM}.htaccess $B%U%!%$%k$r;H$C$F(B + $B<+J,$G@_Dj$NJQ99$r9T$J$&$3$H$r5v2D$7$?J}$,NI$$$H$-$b$"$k$G$7$g$&!#(B + $B$3$l$OFC$K!"(BISP $B$,J#?t$N%f!<%6$N%5%$%H$r0l$D$N%^%7%s$G%[%9%H$7$F$$$F!"(B + $B3F%f!<%6$,@_Dj$NJQ99$r$G$-$k$h$&$K$7$?$$$h$&$J$H$-$K$"$F$O$^$j$^$9!#(B

    + +

    $B$7$+$7!"IaDL$O2DG=$G$"$l$P(B .htaccess $B%U%!%$%k$N;HMQ$O(B + $BHr$1$F$/$@$5$$!#(B.htaccess $B%U%!%$%k$K=q$3$&$H9M$($k$h$&$J(B + $B$9$Y$F$N@_Dj$O!"%5!<%P$NDirectory $B%;%/%7%g%s$GF1$8$h$&$K9T$J$&$3$H$,(B + $B$G$-$^$9!#(B

    + +

    .htaccess $B%U%!%$%k$N;HMQ$rHr$1$kM}M3$O + +

    $B0l$DL\$O%5!<%P$N@-G=$NLdBj$G$9!#(BAllowOverride $B%G%#%l%/%F%#%V$,(B + .htaccess $B%U%!%$%k$N@_Dj$r5v2D$7$F$$$k>l9g$O!"(BApache $B$O(B + $B3F%G%#%l%/%H%j$G(B .htaccess $B%U%!%$%k$rC5$7$^$9!#(B + $B$G$9$+$i!"(B.htaccess $B%U%!%$%k$r5v2D$9$k$H!"7$/$3$H$K$J$j$^$9(B! $B$^$?!"(B.htaccess + $B%U%!%$%k$OJ8=q$,%j%/%(%9%H$5$l$kEY$KFI$_9~$^$l$^$9!#(B

    + +

    $B$5$i$K!"(BApache $B$OE,MQ$9$Y$-%G%#%l%/%F%#%V$r=8$a$k$?$a$K!"$9$Y$F$N(B + $B>e0L$N%G%#%l%/%H%j$N(B .htaccess $B%U%!%$%k$rC5$9I,MW$,$"$k$3$H$K$b(B + $BCm0U$7$F$/$@$5$$!#(B($B%G%#%l%/%F%#%V$,E,MQ$5$l$kJ}K!(B$B$r(B + $B;2>H$7$F$/$@$5$$!#(B)$B$G$9$+$i!"(B/www/htdocs/example $B$K$"$k(B + $B%U%!%$%k$,%j%/%(%9%H$5$l$?$H$-$O!"(BApache $B$O0J2<$N%U%!%$%k$rD4$Y$^$9!#(B

    + + + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +
    + +

    $B$G$9$+$i!"$=$N%G%#%l%/%H%j$N$=$l$>$l$N%U%!%$%k$X$N%"%/%;%9$KBP$7$F!"(B + $B>e$NNc$N%U%!%$%k$,$^$C$?$/B8:_$7$J$$$H$-$G$b!"DI2C$N%U%!%$%k%7%9%F%`$N(B + $B%"%/%;%9$,9T$J$o$l$k$3$H$K$J$j$^$9!#(B($B$3$l$O!"(B.htaccess $B$,(B + / $B$KBP$7$FM-8z$K$J$C$F$$$k$H$-$N>l9g$G!"IaDL$O$=$&$J$C$F(B + $B$$$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B)

    + +

    $BFs$DL\$O%;%-%e%j%F%#$G$9!#%f!<%6$K%5!<%P$N@_Dj$rJQ99$9$k$3$H$r(B + $B5v2D$9$k$3$H$K$J$j$^$9$N$G!"$"$J$?<+?H$,4IM}$G$-$J$$JQ99$r$5$l$k(B + $B62$l$,$"$j$^$9!#%f!<%6$K$3$NFC8"$rM?$($k$N$,NI$$$N$+$I$&$+!"==J,(B + $B8!F$$7$F$/$@$5$$!#$^$?!"%f!<%6$KM?$($k8"8B$,I,MW$J$b$N$h$j$b>/$J$9$.$k$H!"(B + $BM>J,$J5;=Q%5%]!<%HJs9p$rAllowOverride $B$K(B + $B2?$r@_Dj$7$?$+$H$$$&$3$H$H!"4XO"$9$kJ8=q$r<($9$3$H$G!"(B + $B8e!9$N:.Mp$r$0$C$H8:$i$9$3$H$,(B + $B$G$-$^$9!#(B

    + +

    $B$H$3$m$G!"%G%#%l%/%F%#%V$N=q$+$l$?(B .htaccess $B$r(B + /www/htdocs/example $B$KCV$/$3$H$H!"F1$8%G%#%l%/%F%#%V$r(B + $B<Directory /www/htdocs/example> $B$K=q$/$3$H$O(B + $B40A4$KEy2A$G$9(B:

    + +

    /www/htdocs/example $B$N(B .htaccess $B%U%!%$%k(B:

    + + <code>/www/htdocs/example</code> $B$N(B .htaccess $B%U%!%$%k$N(B + $BFbMF(B + AddType text/example .exm + + + <code>httpd.conf $B$N%;%/%7%g%s(B</code> + file + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +
    + +

    $B$7$+$7!"$3$N@_Dj$O%5!<%P@_Dj%U%!%$%k$K=q$$$?J}$,%Q%U%)!<%^%s%9$N(B + $BDc2<$,>/$J$/$J$j$^$9!#%U%!%$%k$,%j%/%(%9%H$5$l$kEY$K(B + $BFI$_9~$^$l$kBe$o$j$K!"(BApache $B$N5/F0;~$K(B 1 $B2s$@$1FI$_9~$a$P(B + $B$h$/$J$k$+$i$G$9!#(B

    + +

    AllowOverride $B%G%#%l%/%F%#%V$N(B + $BCM$r(B none $B$K@_Dj$9$k$3$H$G(B .htaccess $B%U%!%$%k(B + $B$N;HMQ$r40A4$KL58z$K$9$k$3$H$,$G$-$^$9!#(B

    + + + AllowOverride None + +
    + +
    $B%G%#%l%/%F%#%V$NE,MQ$N$5$lJ}(B + +

    .htaccess $B%U%!%$%k$N@_Dj%G%#%l%/%F%#%V$O(B .htaccess + $B%U%!%$%k$NB8:_$9$k%G%#%l%/%H%j$H!"$=$N%5%V%G%#%l%/%H%j$9$Y$F$KE,MQ$5$l$^$9!#(B + $B$7$+$7!">e$N3,AX$N%G%#%l%/%H%j$K$b(B .htaccess $B%U%!%$%k$,(B + $BB8:_$9$k$+$b$7$l$J$$$3$H$r3P$($F$*$/$3$H$OBg@Z$G$9!#%G%#%l%/%F%#%V$O8=$l$k(B + $B=gHV$KE,MQ$5$l$^$9!#$G$9$+$i!"$"$k%G%#%l%/%H%j$N(B .htaccess $B$O(B + $B%G%#%l%/%H%j%D%j!<$N$h$j>e$N3,AX$N(B .htaccess $B%U%!%$%k$N(B + $B@_Dj$r>e=q$-$9$k$+$b$7$l$^$;$s!#$=$7$F!"$=$N(B .htaccess $B$b(B + $B$h$j>e$N3,AX$G=q$+$l$?%G%#%l%/%F%#%V$r>e=q$-$7$?$j!"e=q$-$7$?$j$7$F$$$k$+$b$7$l$^$;$s!#(B

    + +

    $BNc(B:

    + +

    $B%G%#%l%/%H%j(B /www/htdocs/example1 $B$K0J2<$NFbMF$N(B + .htaccess $B%U%!%$%k$,$"$j$^$9(B:

    + + + Options +ExecCGI + + +

    ($BCm(B: .htaccess + $B%U%!%$%k$G(B "Options" $B%G%#%l%/%F%#%V$,M-8z$K$J$k$?$a$K$O!"(B + "AllowOverride Options" $B$rM-8z$K$9$kI,MW$,$"$j$^$9!#(B)

    + +

    $B%G%#%l%/%H%j(B /www/htdocs/example1/example2 $B$K$O(B + $B0J2<$N$h$&$J(B .htaccess $B%U%!%$%k$,$"$j$^$9(B:

    + + + Options Includes + + +

    $BFs$D$a$N(B .htaccess $B$K$h$j!"%G%#%l%/%H%j(B + /www/htdocs/example1/example2 $B$G$O(B CGI $B$NOptions Includes $B$N$_$,(B + $B8zNO$r;}$A!"$=$l$,$9$Y$F$N0JA0$N@_Dj$r>e=q$-$9$k$+$i$G$9!#(B

    + +
    $B%a%$%s@_Dj%U%!%$%k$KBP$9$k(B + .htaccess $B$N%^!<%8(B + +

    As discussed in the documentation on Configuration Sections, + .htaccess files can override the Directory sections for + the corresponding directory, but will be overriden by other types + of configuration sections from the main configuration files. This + fact can be used to enforce certain configurations, even in the + presence of a liberal AllowOverride setting. For example, to + prevent script execution while allowing anything else to be set in + .htaccess you can use:

    +

    $B%;%/%7%g%s$N@_Dj(B + $B$K5-:\$5$l$F$$$k$h$&$K!"(B.htaccess $B%U%!%$%k$r;H$C$F(B + Directory + $B%;%/%7%g%s$N@_Dj$r%G%#%l%/%H%jKh$K>e=q$-$G$-$^$9$,!"(B + $B%a%$%s@_Dj%U%!%$%kCf$K$"$k!"B>$Ne=q$-$5$l$k$3$H$b$"$j$^$9!#(B + $B$3$NFCD'$r;H$C$F!"(B + AllowOverride + $B$G<+M3EY$N9b$$@_Dj$,$"$C$?$H$7$F$b!"$"$kFCDj$N@_Dj$,3N.htaccess $B$G$=$NB>$N9`L\$O(B + $B@_Dj$G$-$k$h$&$K!"$H$$$&>l9g$O + + +<Directory />
    + +Allowoverride All
    +
    +</Directory>
    +
    +<Location />
    + +Options +IncludesNoExec -ExecCGI
    +
    +</Location> +
    +

    + +
    + +
    $BG'>Z$NNc(B + +

    $B$b$7G'>Z$NJ}K!$rCN$k$?$a$K$3$NItJ,$KD>@\Mh$?$N$G$"$l$P!"Z$r9T$J$&$?$a$K$O(B + .htaccess $B%U%!%$%k$r;H$&I,MW$,$"$k!"$H$$$&$b$N$,$"$j$^$9!#(B + $B$3$l$O@5$7$/$"$j$^$;$s!#Directory $B%;%/%7%g%s$K(B + $BG'>ZMQ$N%G%#%l%/%F%#%V$r=q$/J}$,?d>)$5$l$kJ}K!$G!"(B.htaccess + $B%U%!%$%k$O.htaccess $B%U%!%$%k$r;H$&$Y$-$G!"$$$D;H$&$Y$-$G$O$J$$$+$K(B + $B$D$$$F$O(B $B>e(B$B$r;2>H$7$F$/$@$5$$!#(B

    + +

    $B0J>e$N$3$H$r$U$^$($?>e$G!"$b$7(B .htaccess $B$N;HMQ$,(B + $B$^$@I,MW$@$H;W$&>l9g$O!"$_$N$3$H$r$7$F$/$l$k$+$b(B + $B$7$l$^$;$s!#(B

    + +

    .htaccess $B%U%!%$%k$NFbMF(B:

    + + + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +
    + +

    $B$3$l$i$N%G%#%l%/%F%#%V$,M-8z$K$J$k$?$a$K$O!"(B + AllowOverride AuthConfig $B$,M-8z$G$J$/$F$O$J$i$J$$$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B

    + +

    $BG'>Z$H>5G'$K$D$$$F$O(B $BG'>Z%A%e!<%H%j%"%k(B$B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    +
    + +
    SSI $B$NNc(B + +

    $B$b$&0l$D$N(B .htaccess $B%U%!%$%k$N$h$/$"$kMxMQK!$O(B + $BFCDj$N%G%#%l%/%H%j$G(B SSI $B$rM-8z$K$9$k$3$H$G$9!#$3$l$O!"K>$_$N%G%#%l%/%H%j$N(B + .htaccess $B%U%!%$%k$K0J2<$N@_Dj%G%#%l%/%F%#%V$r=q$/$3$H$G(B + $BC#@.$G$-$^$9(B:

    + + + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +
    + +

    $B$3$l$i$N%G%#%l%/%F%#%V$,M-8z$K$J$k$?$a$K$O!"(B + AllowOverride Options $B$H(B AllowOverride + FileInfo $B$,M-8z$K$J$C$F$$$kI,MW$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    + +

    $B$h$j$^$H$^$C$?(B SSI $B$N@bL@$O(B SSI $B%A%e!<%H%j%"%k(B$B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    +
    + +
    CGI $B$NNc(B + +

    $B:G8e$K!"FCDj$N%G%#%l%/%H%j$G(B CGI $B%W%m%0%i%`$N + + + Options +ExecCGI
    + AddHandler cgi-script cgi pl +
    + +

    $B$b$7$/$O!"$"$k%G%#%l%/%H%j$N$9$Y$F$N%U%!%$%k$,(B CGI $B%W%m%0%i%`$H(B + $B$_$J$5$l$k$h$&$K$7$?$$$J$i!"0J2<$N@_Dj$G + + + Options +ExecCGI
    + SetHandler cgi-script +
    + +

    $B$3$l$i$N%G%#%l%/%F%#%V$,M-8z$K$J$k$?$a$K$O!"(B + AllowOverride Options $B$H(B AllowOverride + FileInfo $B$,M-8z$G$"$kI,MW$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    + +

    CGI $B%W%m%0%i%`$H@_Dj$N$h$j$^$H$^$C$?@bL@$O(B CGI $B%A%e!<%H%j%"%k(B$B$r;2>H$7$F$/$@$5$$!#(B

    + +
    + +
    $BLdBj2r7h(B + +

    $B@_Dj%G%#%l%/%F%#%V$r(B .htaccess $B%U%!%$%k$K=q$$$?$1$l$I$b!"(B + $B4|BT$7$?8z2L$,F@$i$l$J$$$H$-$K$O!"$$$/$D$+$N860x$,9M$($i$l$^$9!#(B

    + +

    $B0lHV$h$/$"$k$3$H$O!"@_Dj%G%#%l%/%F%#%V$,9MN8$5$l$k$h$&$K$O(B + AllowOverride $B$,@_Dj$5$l$F$$$J$$(B + $B$H$$$&$b$N$G$9!#3:Ev$N%U%!%$%k$N%9%3!<%W$K(B AllowOverride None + $B$,@_Dj$5$l$F$$$J$$$3$H$r3NG'$7$F$/$@$5$$!#$3$l$rD4$Y$k$?$a$NNI$$J}K!$O!"(B + .htaccess $B%U%!%$%k$K$4$_$r=q$$$F!"%j%m!<%I$9$k$3$H$G$9!#(B + $B%5!<%P$N%(%i!<$,@8@.$5$l$J$$$H$-$O!"$[$\3NAllowOverride + None $B$,@_Dj$5$l$F$$$k>uBV$K$J$C$F$$$^$9!#(B

    + +

    $B$=$&$G$O$J$/!"J8=q$r%"%/%;%9$7$h$&$H$7$?$H$-$K%(%i!<$,H/@8$7$F$$$k(B + $B$H$-$O!"(BApache $B$N%(%i!<%m%0$rD4$Y$F$/$@$5$$!#(B.htaccess $B%U%!%$%k$G(B + $B;HMQ$5$l$?%G%#%l%/%F%#%V$,5v2D$5$l$F$$$J$$!"$H$$$&$3$H$rCN$i$;$F$$$k(B + $B2DG=@-$,9b$$$G$9!#$^$?$O!"9=J8$N4V0c$$$,$"$k$3$H$r=R$Y$F$$$k$+$b$7$l$^$;$s!#(B + $B$=$N>l9g$K$O$^$:$=$l$r=$@5$9$kI,MW$,$"$j$^$9!#(B

    + +
    + +
    diff --git a/trunk/docs/manual/howto/htaccess.xml.ko b/trunk/docs/manual/howto/htaccess.xml.ko new file mode 100644 index 0000000000..9b2f9117bf --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.xml.ko @@ -0,0 +1,351 @@ + + + + + + + + +How-To / Tutorials + +¾ÆÆÄÄ¡ ÅõÅ丮¾ó: .htaccess ÆÄÀÏ + + +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© µð·ºÅ丮º°·Î ¼³Á¤À» +º¯°æÇÒ ¼ö ÀÖ´Ù.

    +
    + + + +
    +¹«¾ùÀ̸ç/¾î¶»°Ô »ç¿ëÇϴ°¡ + +

    .htaccess ÆÄÀÏ(ȤÀº "ºÐ»ê ¼³Á¤ÆÄÀÏ")À» + »ç¿ëÇÏ¸é µð·ºÅ丮º°·Î ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖ´Ù. ¿©·¯ ¼³Á¤ Áö½Ã¾î°¡ + ÀÖ´Â ÆÄÀÏÀ» ƯÁ¤ ¹®¼­ µð·ºÅ丮¿¡ µÎ¸é, ±× µð·ºÅ丮¿Í ¸ðµç + ÇÏÀ§µð·ºÅ丮¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù.

    + + ÁÖÀÇ: +

    .htaccess ÆÄÀϸíÀ» ´Ù¸£°Ô »ç¿ëÇÏ°í ½Í´Ù¸é, + AccessFileName Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© º¯°æÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, .config + ÆÄÀϸíÀ» »ç¿ëÇÏ·Á¸é ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    + + + AccessFileName .config + +
    + +

    ÀϹÝÀûÀ¸·Î .htaccess ÆÄÀÏÀº ÁÖ¼³Á¤ÆÄÀÏ°ú ¹®¹ýÀÌ + °°´Ù. AllowOverride + Áö½Ã¾î°¡ ÀÌ ÆÄÀÏ¿¡ ³ª¿Ã ¼ö ÀÖ´Â ³»¿ëÀ» °áÁ¤ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + .htaccess ÆÄÀÏ¿¡¼­ Çã¿ëÇÏ´Â Áö½Ã¾î ºÐ·ù¸¦ ÁöÁ¤ÇÑ´Ù. + Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù¸é, + ÇØ´ç Áö½Ã¾î ¹®¼­ÀÇ Override Ç׸ñÀº Áö½Ã¾î¸¦ Çã¿ëÇϱâÀ§ÇØ + AllowOverride¿¡ »ç¿ëÇÒ + °ªÀ» ¾Ë·ÁÁØ´Ù.

    + +

    ¿¹¸¦ µé¾î, AddDefaultCharset + Áö½Ã¾î ¹®¼­¸¦ º¸¸é ÀÌ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. (Áö½Ã¾î ¿ä¾à¿¡¼­ »ç¿ëÀå¼Ò Ç׸ñÀ» º¸¶ó.) + Override + ÁÙ¿¡ FileInfo°¡ ÀÖ´Ù. ±×·¡¼­ ÀÌ Áö½Ã¾î¸¦ + .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇϱâÀ§Çؼ­´Â ÃÖ¼ÒÇÑ + AllowOverride FileInfo°¡ ÇÊ¿äÇÏ´Ù.

    + + ¿¹Á¦: + + + + + + + + + + +
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override:FileInfo
    +
    + +

    ƯÁ¤ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ + ¼ö ÀÖ´ÂÁö ±Ã±ÝÇϸé Áö½Ã¾î ¹®¼­ÀÇ »ç¿ëÀå¼Ò Ç׸ñ¿¡ ".htaccess"°¡ + ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.

    +
    + +
    ¾ðÁ¦ .htaccess ÆÄÀÏÀ» »ç¿ëÇϳª + (ȤÀº »ç¿ëÇÏÁö ¾Ê³ª) + +

    ÀϹÝÀûÀ¸·Î ÁÖ¼­¹öÆÄÀÏ¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ¾Æ´Ï¶ó¸é + .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ¿¹¸¦ µé¾î, + »ç¿ëÀÚ ÀÎÁõÀÌ Ç×»ó .htaccess ÆÄÀÏ¿¡ ÀÖ¾î¾ß + ÇÑ´Ù´Â °ÍÀº À߸ø ¾Ë·ÁÁø ¿ÀÇØ´Ù. ÀÌ´Â »ç½ÇÀÌ ¾Æ´Ï´Ù. ÁÖ¼­¹ö¼³Á¤¿¡ + »ç¿ëÀÚ ÀÎÁõ ¼³Á¤À» ÀûÀ» ¼ö ÀÖ°í, »ç½Ç ÀÌ·¯±æ ±ÇÇÑ´Ù.

    + +

    .htaccess ÆÄÀÏÀº ÄÁÅÙÃ÷ Á¦°øÀÚ°¡ µð·ºÅ丮º°·Î + ¼­¹ö ¼³Á¤À» ´Ù¸£°ÔÇÏ°í ½ÍÁö¸¸ ¼­¹ö ½Ã½ºÅÛ¿¡ root ±ÇÇÑÀÌ + ¾ø´Â °æ¿ì¿¡ »ç¿ëÇÑ´Ù. ¼­¹ö °ü¸®ÀÚ°¡ ¼³Á¤À» ÀÚÁÖ º¯°æÇÏ°í + ½ÍÁö ¾ÊÀº °æ¿ì ÀÏ¹Ý »ç¿ëÀÚ°¡ Á÷Á¢ .htaccess + ÆÄÀÏÀ» ¼öÁ¤Çϵµ·Ï Çã¿ëÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. ¿¹¸¦ µé¾î, ÇÑ + ÄÄÇ»ÅÍ¿¡ ¿©·¯ »ç¿ëÀÚ »çÀÌÆ®¸¦ ¼­ºñ½ºÇÏ´Â ISP¿¡¼­ »ç¿ëÀÚ°¡ + ÀÚ½ÅÀÇ ¼³Á¤À» º¯°æÇÏ°í ½ÍÀº °æ¿ì°¡ ±×·¯ÇÏ´Ù.

    + +

    ±×·¯³ª ÀϹÝÀûÀ¸·Î .htaccess ÆÄÀÏÀº °¡±ÞÀû + ÇÇÇØ¾ß ÇÑ´Ù. .htaccess ÆÄÀÏ¿¡¼­ Çã¿ëÇÏ´Â Áö½Ã¾î´Â + ÁÖ¼³Á¤ÆÄÀÏÀÇ Directory ¼½¼Ç°ú °°Àº È¿°ú°¡ + ÀÖ´Ù.

    + +

    ´ÙÀ½ µÎ°¡Áö Å« ÀÌÀ¯¶§¹®¿¡ .htaccess ÆÄÀÏ + »ç¿ëÀ» ÇÇÇØ¾ß ÇÑ´Ù.

    + +

    ù¹ø°´Â ¼º´ÉÀÌ´Ù. AllowOverride°¡ .htaccess + ÆÄÀÏÀ» »ç¿ëÇϵµ·Ï Çã¿ëÇϸé, ¾ÆÆÄÄ¡´Â µð·ºÅ丮¸¶´Ù + .htaccess ÆÄÀÏÀ» ã´Â´Ù. ±×·¡¼­ + .htaccess ÆÄÀÏÀ» Çã¿ëÇÏ¸é ½ÇÁ¦·Î ÆÄÀÏÀ» »ç¿ëÇÏÁö + ¾Ê´Â °æ¿ì¿¡µµ ¼º´ÉÀÌ ¶³¾îÁø´Ù! ¶Ç, .htaccess + ÆÄÀÏÀº ¹®¼­¸¦ ¿äûÇÒ¶§¸¶´Ù ÀоîµéÀδÙ.

    + +

    °Ô´Ù°¡ Àû¿ëÇØ¾ß ÇÏ´Â Àüü Áö½Ã¾î¸¦ ¸ðÀ¸±âÀ§ÇØ ¾ÆÆÄÄ¡´Â + ¸ðµç »óÀ§ µð·ºÅ丮¿¡¼­ .htaccess ÆÄÀÏÀ» ã´Â´Ù. + (¾î¶»°Ô Áö½Ã¾î¸¦ Àû¿ëÇϳª ÀýÀ» Âü°í.) + ±×·¡¼­ /www/htdocs/example µð·ºÅ丮¿¡ ÀÖ´Â + ÆÄÀÏÀ» ¿äûÇϸé, ¾ÆÆÄÄ¡´Â ´ÙÀ½ ÆÄÀϵéÀ» ã¾Æ¾ß ÇÑ´Ù.

    + + + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +
    + +

    ±×·¡¼­ ±× µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏÀ» Á¢±ÙÇÒ ¶§¸¶´Ù ¼³Á¤ÆÄÀÏÀÌ + ÀüÇô ¾ø¾îµµ ÆÄÀϽýºÅÛÀ» 4¹ø ´õ Á¢±ÙÇØ¾ß ÇÑ´Ù. + (/¿¡¼­µµ .htaccess ÆÄÀÏÀ» Çã¿ëÇÑ + °æ¿ì¸¦ ¸»ÇÑ´Ù. º¸ÅëÀº Çã¿ëÇÏÁö ¾Ê´Â´Ù.)

    + +

    µÎ¹ø° ÀÌÀ¯´Â º¸¾ÈÀÌ´Ù. »ç¿ëÀÚ¿¡°Ô ¼­¹ö¼³Á¤ º¯°æ ±ÇÇÑÀ» + ÁÖ¸é ´ç½ÅÀÌ °¨´çÇÒ ¼ö ¾ø´Â º¯È­°¡ ÀϾ ¼ö ÀÖ´Ù. »ç¿ëÀÚ¿¡°Ô + ÀÌ·± ±ÇÇÑÀ» ÁÙÁö °õ°õÀÌ »ý°¢Ç϶ó. ¶Ç, »ç¿ëÀÚ°¡ ¿øÇÏ´Â °Íº¸´Ù + ÀûÀº ±ÇÇÑÀ» ÁÖ¸é ±â¼úÁö¿ø¿äûÀÌ µé¾î¿Â´Ù. »ç¿ëÀÚ¿¡°Ô °¡´ÉÇÑ + ±ÇÇÑ ¼öÁØÀ» ¸íÈ®È÷ ¾Ë·Á¶ó. »ç¿ëÀÚ¿¡°Ô AllowOverride¸¦ ¾î¶»°Ô ¼³Á¤ÇÏ¿´´ÂÁö + Á¤È®È÷ ¾Ë¸®°í °ü·Ã ¹®¼­¸¦ Á¦°øÇÏ¸é ¾ÕÀ¸·Î È¥¶õÀ» ÇÇÇÒ ¼ö + ÀÖ´Ù.

    + +

    Áö½Ã¾î¸¦ /www/htdocs/example µð·ºÅ丮ÀÇ + .htaccess ÆÄÀÏÀ» µÎ´Â °Í°ú ÁÖ¼­¹ö¼³Á¤ÀÇ + <Directory /www/htdocs/example> Directory + ¼³Á¤¿¡ µÎ´Â °ÍÀº ¿ÏÀüÈ÷ °°´Ù.

    + +

    /www/htdocs/example¿¡ ÀÖ´Â + .htaccess ¼½¼Ç:

    + + <code>/www/htdocs/example</code>¿¡ ÀÖ´Â + .htaccess ÆÄÀÏ ³»¿ë + AddType text/example .exm + + + <code>httpd.conf</code> ÆÄÀÏ¿¡ ÀÖ´Â ¼½¼Ç + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +
    + +

    ±×·¯³ª ÆÄÀÏÀ» ¿äûÇÒ ¶§¸¶´Ù ¼³Á¤À» ÀÐÁö¾Ê°í ¾ÆÆÄÄ¡°¡ + ½ÃÀÛÇÒ¶§ Çѹø¸¸ ¼³Á¤À» Àб⶧¹®¿¡ °°Àº ¼³Á¤À» ¼­¹ö¼³Á¤ÆÄÀÏ¿¡ + »ç¿ëÇÏ¸é ¼º´ÉÀÌ ´õ ºü¸£´Ù.

    + +

    AllowOverride Áö½Ã¾î¸¦ + noneÀ¸·Î ¼³Á¤Çϸé .htaccess ÆÄÀÏÀ» + ¿ÏÀüÈ÷ »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + + + AllowOverride None + +
    + +
    ¾î¶»°Ô Áö½Ã¾î¸¦ Àû¿ëÇϳª + +

    .htaccess ÆÄÀÏÀ» ¹ß°ßÇÑ µð·ºÅ丮¿Í ±× µð·ºÅ丮ÀÇ + ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ .htaccess ÆÄÀÏ¿¡ ÀÖ´Â ¼³Á¤ + Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ±×·¡¼­ »óÀ§µð·ºÅ丮ÀÇ .htaccess + ÆÄÀÏÀ» ÁÖÀÇÇØ¾ß ÇÑ´Ù. ¹ß°ßÇÑ ¼ø¼­·Î Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ƯÁ¤ + µð·ºÅ丮¿¡ ÀÖ´Â .htaccess ÆÄÀÏÀº »óÀ§µð·ºÅ丮¿¡ + ÀÖ´Â .htaccess ÆÄÀÏÀÇ Áö½Ã¾î¸¦ ¹«È¿·Î ¸¸µé + ¼ö ÀÖ°í, »óÀ§µð·ºÅ丮¿¡ ÀÖ´Â Áö½Ã¾î´Â ´õ »óÀ§µð·ºÅ丮 ȤÀº + ÁÖ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ ¹«È¿·Î ¸¸µé ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦:

    + +

    /www/htdocs/example1 µð·ºÅ丮¿¡ ´ÙÀ½°ú °°Àº + .htaccess ÆÄÀÏÀÌ ÀÖ´Ù.

    + + + Options +ExecCGI + + +

    (ÁÖÀÇ: .htaccess ÆÄÀÏ¿¡ "Options" Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á¸é + "AllowOverride Options"°¡ ÇÊ¿äÇÏ´Ù.)

    + +

    /www/htdocs/example1/example2 µð·ºÅ丮¿¡´Â + ´ÙÀ½°ú °°Àº .htaccess ÆÄÀÏÀÌ ÀÖ´Ù.

    + + + Options Includes + + +

    ÀÌ µÎ¹ø° .htaccess ÆÄÀÏÀÇ + Options Includes°¡ ÀÌÀü ¼³Á¤À» ¿ÏÀüÈ÷ ¹«È¿·Î + ¸¸µé±â¶§¹®¿¡ /www/htdocs/example1/example2 + µð·ºÅ丮´Â CGI ½ÇÇàÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù.

    +
    + +
    ÀÎÁõ ¿¹Á¦ + +

    ÀÎÁõ ¹æ¹ýÀ» ¾Ë±âÀ§ÇØ ¹Ù·Î ÀÌ°÷ºÎÅÍ Àд´ٸé ÁÖÀÇÇÒ °ÍÀÌ + ÀÖ´Ù. ¾ÏÈ£ ÀÎÁõÀ» ÇÏ·Á¸é .htaccess ÆÄÀÏÀÌ + ÇÊ¿äÇÏ´Ù´Â ¿ÀÇØ°¡ ³Î¸® ÆÛÁ®ÀÖ´Ù. ÀÌ´Â »ç½ÇÀÌ ¾Æ´Ï´Ù. + ÁÖ¼³Á¤ÆÄÀÏÀÇ Directory ¼½¼Ç¿¡ ÀÎÁõ Áö½Ã¾î¸¦ + µÎ´Â °ÍÀÌ ´õ ±ÇÀåÇÏ´Â ¹æ¹ýÀÌ°í, ¼­¹öÀÇ ÁÖ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÒ + ¼ö ¾ø´Â °æ¿ì¿¡¸¸ .htaccess ÆÄÀÏÀ» »ç¿ëÇØ¾ß + ÇÑ´Ù. ¾ðÁ¦ .htaccess ÆÄÀÏÀ» »ç¿ëÇØ¾ß ÇÏ´ÂÁö¿Í + »ç¿ëÇÏÁö ¸»¾Æ¾ß ÇÏ´ÂÁö´Â À§¿¡¼­ + ¼³¸íÇÏ¿´´Ù.

    + +

    ¾Õ¿¡¼­ ¸»ÇßÁö¸¸ ¾ÆÁ÷µµ .htaccess ÆÄÀÏÀÌ + ÇÊ¿äÇÏ´Ù°í »ý°¢µÇ¸é ¾Æ·¡ ¼³Á¤ÀÌ µµ¿òÀÌ µÉ °ÍÀÌ´Ù.

    + +

    .htaccess ÆÄÀÏ ³»¿ë.

    + + + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +
    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇϱâÀ§Çؼ­´Â + AllowOverride AuthConfig Áö½Ã¾î°¡ ÇÊ¿äÇÔÀ» + ¸í½ÉÇ϶ó.

    + +

    ÀÎÁõ°ú ±ÇÇѺο©¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ÀÎÁõ + ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    +
    + +
    Server Side Includes ¿¹Á¦ + +

    ¶Ç´Ù¸¥ ÀϹÝÀûÀÎ .htaccess ÆÄÀÏÀÇ ¿ëµµ´Â + ƯÁ¤ µð·ºÅ丮¿¡¼­ Server Side Includes¸¦ °¡´ÉÇÏ°Ô ¸¸µå´Â + °ÍÀÌ´Ù. ¿øÇÏ´Â µð·ºÅ丮ÀÇ .htaccess ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°Àº ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é µÈ´Ù.

    + + + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +
    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇÏ·Á¸é AllowOverride Options¿Í + AllowOverride FileInfo°¡ ¸ðµÎ ÇÊ¿äÇÔÀ» ¸í½ÉÇ϶ó.

    + +

    server-side includes¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº SSI ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    +
    + +
    CGI ¿¹Á¦ + +

    ¸¶Áö¸·À¸·Î .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© ƯÁ¤ + µð·ºÅ丮¿¡¼­ CGI ÇÁ·Î±×·¥ ½ÇÇàÀ» Çã¿ëÇÏ°í ½Í´Ù¸é, ´ÙÀ½°ú + °°Àº ¼³Á¤À» »ç¿ëÇÑ´Ù.

    + + + Options +ExecCGI
    + AddHandler cgi-script cgi pl +
    + +

    ȤÀº ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏÀ» CGI ÇÁ·Î±×·¥À¸·Î + ó¸®ÇÏ°í ½Í´Ù¸é ´ÙÀ½°ú °°Àº ¼³Á¤µµ °¡´ÉÇÏ´Ù.

    + + + Options +ExecCGI
    + SetHandler cgi-script +
    + +

    ÀÌ Áö½Ã¾î°¡ µ¿ÀÛÇÏ·Á¸é AllowOverride Options¿Í + AllowOverride FileInfo°¡ ¸ðµÎ ÇÊ¿äÇÔÀ» ¸í½ÉÇ϶ó.

    + +

    CGI ÇÁ·Î±×·¡¹Ö°ú ¼³Á¤¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº CGI ÅõÅ丮¾óÀ» º¸±æ ¹Ù¶õ´Ù.

    + +
    + +
    ¹®Á¦ÇØ°á + +

    .htaccess ÆÄÀÏ¿¡ µÐ ¼³Á¤ Áö½Ã¾î°¡ ¿øÇÏ´Â + ±â´ÉÀ» ÇÏÁö ¾Ê´Â °æ¿ì ¿©·¯°¡Áö ÀÌÀ¯°¡ ÀÖÀ» ¼ö ÀÖ´Ù.

    + +

    °¡Àå ÀϹÝÀûÀÎ ¹®Á¦´Â ¼³Á¤ Áö½Ã¾î¸¦ °¡´ÉÇÏ°Ô ¸¸µå´Â AllowOverride¸¦ ¼³Á¤ÇÏÁö ¾ÊÀº + °æ¿ì´Ù. ¹®Á¦°¡ µÇ´Â ÆÄÀÏ ¿µ¿ª¿¡ AllowOverride NoneÀÌ + ¾ø´ÂÁö È®ÀÎÇÑ´Ù. .htaccess ÆÄÀÏÀ» ¾Æ¹«·¸°Ô³ª + ÀûÀº ´ÙÀ½ ÆäÀÌÁö¸¦ ´Ù½Ã Á¢±ÙÇÏ¿© ½±°Ô °Ë»çÇغ¼ ¼ö ÀÖ´Ù. + ¼­¹ö ¿À·ù°¡ ³ª¿ÀÁö ¾ÊÀ¸¸é °ÅÀÇ È®½ÇÈ÷ + AllowOverride NoneÀ» »ç¿ëÇÑ °æ¿ì´Ù.

    + +

    ¹Ý´ë·Î ¹®¼­¿¡ Á¢±ÙÇÒ¶§ ¼­¹ö ¿À·ù°¡ ¹ß»ýÇÏ¸é ¾ÆÆÄÄ¡ ¿À·ù·Î±×¸¦ + »ìÆìºÁ¶ó. ¾Æ¸¶µµ .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ + Çã¿ëÇÏÁö ¾Ê´Â´Ù°í ÇÒ °ÍÀÌ´Ù. ¾Æ´Ï°í ¹®¹ý ¿À·ù°¡ ÀÖ´Ù¸é ¿À·ù¸¦ + °íÄ£´Ù.

    + +
    + +
    diff --git a/trunk/docs/manual/howto/htaccess.xml.meta b/trunk/docs/manual/howto/htaccess.xml.meta new file mode 100644 index 0000000000..b04522ef4f --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.xml.meta @@ -0,0 +1,14 @@ + + + + htaccess + /howto/ + .. + + + en + ja + ko + pt-br + + diff --git a/trunk/docs/manual/howto/htaccess.xml.pt-br b/trunk/docs/manual/howto/htaccess.xml.pt-br new file mode 100644 index 0000000000..df2951851d --- /dev/null +++ b/trunk/docs/manual/howto/htaccess.xml.pt-br @@ -0,0 +1,397 @@ + + + + + + + + +How-To / Tutoriais + +Tutorial do Apache: arquivos .htaccess + + +

    Arquivos .htaccess oferecem um meio de fazer mudanças + nas configurações por-diretório.

    +
    + + + +
    +O que eles são/Como usá-los + +

    Os arquivos .htaccess (ou "arquivos de + configuração distribuída") oferecem um meio de fazer mudanças nas + configurações por-diretório. Um arquivo, contendo uma ou mais + diretrizes de configurações, é colocado em um diretório + em particular, e as diretrizes se aplicam para aquele diretório e todos + os seu subdiretórios subseqüentes.

    + + Nota: +

    Se você quiser renomear o seu arquivo .htaccess + para outro nome, você deve usar a diretriz AccessFileName. Por exemplo, se você + prefere que o arquivo se chame .config, então você + pode adicionar a seguinte linha ao seu arquivo de configuração + do servidor:

    + + + AccessFileName .config + +
    + +

    No geral, arquivos .htaccess usam a mesma sintaxe + que os arquivos de + configuração principal. O que você pode colocar nesses + arquivos é determinado pele diretriz AllowOverride. Essa diretriz especifica, + em categorias, quais diretrizes serão aceitas caso sejam + encontradas em um arquivo .htaccess. Se uma diretriz + for permitida em um arquivo .htaccess, a documentação + para essa diretriz irá conter uma seção Override, + especificando que valor precisa estar em AllowOverride para que esta diretriz + seja permitida.

    + +

    Por exemplo, se você procurar na documentação pela diretriz + AddDefaultCharset, você + achará que ela é permitida nos arquivos .htaccess. + (Veja a linha Contexto no sumário das diretivas.) A + linha Override lê + FileInfo. Então, você deve ao menos ter + AllowOverride FileInfo para que essa diretriz seja + aceita nos arquivos .htaccess.

    + + Exemplo: + + + + + + + + + + +
    Contexto:configuração do servidor, hospedeiros virtuais, diretório, .htaccess
    Override:FileInfo
    +
    + +

    Se você estiver incerto se uma diretriz em particular é + aceita em um arquivo .htaccess, procure na + documentação por essa diretriz, e verifique a linha de + Contexto por ".htaccess".

    + +
    Quando (não) usar arquivos .htaccess + +

    No geral, você nunca deve usar arquivos .htaccess + a não ser que você não tenha acesso ao arquivo de configuração + principal do servidor. Existe, por exemplo, um erro de concepção + que dita que a autenticação de usuários sempre deve + ser feita usando os arquivos .htaccess. Esse + simplesmente não é o caso. Você pode usar as configurações de + autenticação de usuário no arquivo de configuração principal do + servidor, e isso é, de fato, a maneira mais adequada de se fazer + as coisas.

    + +

    Arquivos .htaccess devem ser usados em casos onde + os provedores de conteúdo do site precisem fazer mudanças na + configuração do servidor por-diretório, mas não tem + acesso root ao sistema do servidor. Caso o administrador do + servidor não esteja disposto a fazer mudanças freqüentes nas + configurações do servidor, é desejável permitir que os + usuários possam fazer essas mudanças através de arquivos + .htaccess eles mesmos. Isso é particularmente + verdade, por exemplo, em casos onde provedores estão fornecendo + múltiplos sites para usuários em apenas uma máquina, e querem que + seus usuários possam alterar suas configurações.

    + +

    No entanto, de modo geral, o uso de arquivos .htaccess + deve ser evitado quando possível. Quaisquer configurações + que você considerar acrescentar em um arquivo .htaccess, podem + ser efetivamente colocadas em uma seção Directory no arquivo principal de + configuração de seu servidor.

    + +

    Existem duas razões principais para evitar o uso de arquivos + .htaccess.

    + +

    A primeira delas é a performance. Quando AllowOverride é configurado para + permitir o uso de arquivos .htaccess, o Apache procura + em todos diretórios por arquivos .htaccess. + Logo, permitir arquivos .htaccess causa um impacto na + performance, mesmo sem você usá-los de fato! Além disso, + o arquivo .htaccess é carregado toda vez que um documento + é requerido.

    + +

    Além disso, note que o Apache precisa procurar pelos arquivos + .htaccess em todos os diretórios superiores, para ter + o complemento total de todas as diretivas que devem ser + aplicadas. (Veja a seção como as diretrizes são + aplicadas.) Então, se um arquivo de um diretório + /www/htdocs/example é requerido, o Apache precisa + procurar pelos seguintes arquivos:

    + + + /.htaccess
    + /www/.htaccess
    + /www/htdocs/.htaccess
    + /www/htdocs/example/.htaccess +
    + +

    Assim, para cada acesso de arquivo fora desse diretório, + existem 4 acessos ao sistema de arquivos adicionais, mesmo + que nenhum desses arquivos estejam presentes. (Note que esse + só será o caso se os arquivos .htaccess + estiverem habilitados para /, o que + normalmente não é o verdade.)

    + +

    A segunda consideração é relativa à segurança. + Você está permitindo que os usuários modifiquem as + configurações do servidor, o que pode resultar em mudanças + que podem fugir ao seu controle. Considere com cuidado se você quer + ou não dar aos seus usuários esses privilégios. Note também + que dar aos usuários menos privilégios que eles precisam, acarreta em + pedidos de suporte técnico adicionais. Tenha certeza que você comunicou + aos usuários que nível de privilégios você os deu. + Especificar exatamente o que você configurou na diretriz AllowOverride, e direcioná-los para a + documentação relevante, irá poupá-lo de muita confusão + depois.

    + +

    Perceba que é exatamente equivalente colocar o arquivo + .htaccess em um diretório + /www/htdocs/example contendo uma diretriz, e + adicionar a mesma diretriz em uma seção Directory + <Directory /www/htdocs/example> na configuração + principal do seu servidor:

    + +

    Arquivo .htaccess em /www/htdocs/example:

    + + Conteúdo de um arquivo .htaccess em + <code>/www/htdocs/example</code> + AddType text/example .exm + + + Seção do seu arquivo <code>httpd.conf</code> + <Directory /www/htdocs/example>
    + + AddType text/example .exm
    +
    + </Directory> +
    + +

    No entanto, adicionando isso ao seu arquivo de configuração do + servidor resultará em uma menor perda de performance, na medida que + a configuração é carregada no momento da inicialização do + servidor, ao invés de toda que que um arquivo é requerido.

    + +

    O uso de arquivos .htaccess pode ser totalmente + desabilitado, ajustando a diretriz AllowOverride para none:

    + + + AllowOverride None + +
    + +
    Como as diretrizes são aplicadas + +

    As diretrizes de configuração que se encontram em um arquivo + .htaccess são aplicadas para o diretório no qual o + arquivo .htaccess se encontra, e para todos os + subdiretórios ali presentes. Mas, é importante lembrar também que + podem existir arquivos .htaccess no diretórios + superiores. As diretrizes são aplicadas na ordem que são + achadas. Logo, um arquivo .htaccess em um diretório + em particular, pode sobrescrever as diretrizes encontradas em um + diretório acima deste em sua respectiva árvore. Estes, por sua vez, + podem ter suas diretrizes sobrescritas por diretrizes ainda mais + acima, ou no próprio arquivo de configuração principal do + servidor.

    + +

    Exemplo:

    + +

    No diretório /www/htdocs/example1 nós temos + um arquivo .htaccess contendo o seguinte:

    + + + Options +ExecCGI + + +

    (Nota: você deve ter "AllowOverride Options" para + permitir o uso da diretriz "Options" nos arquivos + .htaccess .)

    + +

    No diretório /www/htdocs/example1/example2 nós temos + um arquivo .htaccess contendo:

    + + + Options Includes + + +

    Devido a esse segundo arquivo .htaccess, no + diretório /www/htdocs/example1/example2, a execução + de scripts CGI não é permitida, pois somente Options + Includes está em efeito, o que sobrescreve completamente + quaisquer outros ajustes previamente configurados.

    +
    + +
    Exemplo de Autenticação + +

    Se você veio diretamente à esta parte do documento para + aprender como fazer autenticação, é importante notar uma + coisa. Existe uma concepção errada, mas muito comum, de que é + necessário o uso de arquivos .htaccess para implementar + a autenticação por senha. Este não é o caso. Colocar + diretrizes de senha em uma seção Directory, no seu arquivo principal de + configuração do servidor, é a melhor maneira de se implementar + isto, e os arquivos .htaccess devem ser usados apenas + se você não tem acesso ao arquivo principal de configuração do + servidor. Veja acima a discussão sobre quando + você deve e quando não deve usar os arquivos + .htaccess.

    + +

    Dito isso, se você ainda acredita que precisa usar um arquivo + .htaccess, a configuração a seguir provavelmente + funcionará para você.

    + +

    Conteúdo de um arquivo .htaccess:

    + + + AuthType Basic
    + AuthName "Password Required"
    + AuthUserFile /www/passwords/password.file
    + AuthGroupFile /www/passwords/group.file
    + Require Group admins +
    + +

    Note que AllowOverride AuthConfig precisa estar + habilitado para que estas diretrizes tenham efeito.

    + +

    Por favor veja o tutorial de + autenticação para uma discussão mais completa sobre + autenticação e autorização.

    +
    + +
    Exemplo de Server Side Includes + +

    Outro uso comum de arquivos .htaccess é ativar o + Server Side Includes para um diretório em particular. Isto pode + ser feito com as seguintes diretrizes de configuração, colocadas em + um arquivo .htaccess no diretório desejado:

    + + + Options +Includes
    + AddType text/html shtml
    + AddHandler server-parsed shtml +
    + +

    Note que ambos AllowOverride Options e + AllowOverride FileInfo precisam estar habilitados + para essas diretrizes terem efeito.

    + +

    Por favor veja o tutorial de SSI para + uma discussão mais completa sobre server-side includes.

    +
    + +
    Exemplo de CGI + +

    Finalmente, você pode querer que um arquivo + .htaccess permita a execução de programas CGI em um + diretório em particular. Isto pode ser implementado com as + seguintes configurações:

    + + + Options +ExecCGI
    + AddHandler cgi-script cgi pl +
    + +

    Alternativamente, se você desejar que todos os arquivos de um + dado diretório, sejam considerados programas CGI, isso pode ser + feito com a seguinte configuração:

    + + + Options +ExecCGI
    + SetHandler cgi-script +
    + +

    Note que ambos AllowOverride Options e + AllowOverride FileInfo precisam estar habilitados + para que essas diretrizes tenham quaisquer efeito.

    + +

    Por favor veja o tutorial de CGI + tutorial para uma discussão mais completa sobre programação + e configuração CGI.

    +
    + +
    Resolvendo Problemas + +

    Quando você adiciona diretrizes de configuração em um arquivo + .htaccess, e não obtém o efeito desejado, existe uma + série de pontos que podem estar errados.

    + +

    Mais comumente, o problema é que a diretriz AllowOverride não está habilitada + corretamente para que as suas diretrizes de configurações sejam + honradas. Verifique se você não possui AllowOverride + None ajustado para o escopo do arquivo em questão. Um bom + meio de testar isso é colocar "lixo" em seu arquivo + .htaccess e recarregá-lo. Se não for gerado nenhum + erro do servidor, certamente você tem AllowOverride + None habilitado.

    + +

    Se, por outro lado, você está obtendo erros do servidor ao + tentar acessar documentos, verifique o registro de erros do + Apache. Ele provavelmente irá indicar que a diretriz usada em + seu arquivo .htaccess não é permitida. + Alternativamente, ele pode acusar erros de sintaxe que você terá + que corrigir.

    + +
    + +
    diff --git a/trunk/docs/manual/howto/index.html b/trunk/docs/manual/howto/index.html new file mode 100644 index 0000000000..9ee330865b --- /dev/null +++ b/trunk/docs/manual/howto/index.html @@ -0,0 +1,11 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/howto/index.html.en b/trunk/docs/manual/howto/index.html.en new file mode 100644 index 0000000000..55d6b9b1ab --- /dev/null +++ b/trunk/docs/manual/howto/index.html.en @@ -0,0 +1,105 @@ + + + +How-To / Tutorials - Apache HTTP Server + + + + + +
    <-
    +

    How-To / Tutorials

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    How-To / Tutorials

    + + + +
    +
    Authentication
    +
    +

    Authentication is any process by which you verify that + someone is who they claim they are. Authorization is any + process by which someone is allowed to be where they want to + go, or to have information that they want to have.

    + +

    See: Authentication, Authorization, and Access Control

    +
    +
    + +
    +
    Dynamic Content with CGI
    +
    +

    The CGI (Common Gateway Interface) defines a way for a web + server to interact with external content-generating programs, + which are often referred to as CGI programs or CGI scripts. It + is the simplest, and most common, way to put dynamic content on + your web site. This document will be an introduction to setting + up CGI on your Apache web server, and getting started writing + CGI programs.

    + +

    See: CGI: Dynamic Content

    +
    +
    + +
    +
    .htaccess files
    +
    +

    .htaccess files provide a way to make configuration + changes on a per-directory basis. A file, containing one or more + configuration directives, is placed in a particular document directory, + and the directives apply to that directory, and all subdirectories thereof.

    + +

    See: .htaccess files

    +
    +
    + +
    +
    Introduction to Server Side Includes
    +
    +

    SSI (Server Side Includes) are directives that are placed in + HTML pages, and evaluated on the server while the pages are + being served. They let you add dynamically generated content to + an existing HTML page, without having to serve the entire page + via a CGI program, or other dynamic technology.

    + +

    See: Server Side Includes (SSI)

    +
    +
    + +
    +
    Per-user web directories
    +
    +

    On systems with multiple users, each user can be permitted to have a + web site in their home directory using the UserDir directive. Visitors + to a URL http://example.com/~username/ will get content + out of the home directory of the user "username", out of + the subdirectory specified by the UserDir directive.

    + +

    See: User web directories (public_html)

    +
    +
    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/index.html.ja.euc-jp b/trunk/docs/manual/howto/index.html.ja.euc-jp new file mode 100644 index 0000000000..35831a7560 --- /dev/null +++ b/trunk/docs/manual/howto/index.html.ja.euc-jp @@ -0,0 +1,102 @@ + + + +How-To / ¥Á¥å¡¼¥È¥ê¥¢¥ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    How-To / ¥Á¥å¡¼¥È¥ê¥¢¥ë

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    How-To / ¥Á¥å¡¼¥È¥ê¥¢¥ë

    + + + +
    +
    ǧ¾Ú
    +
    +

    ǧ¾Ú¤È¤Ï¡¢Ã¯¤«¤¬¼«Ê¬¤Ïï¤Ç¤¢¤ë¤«¤ò̾¾è¤Ã¤Æ¤¤¤ë¤â¤Î¤ò¸¡¾Ú¤¹¤ë + ½èÍý¤Î¤³¤È¤Ç¤¹¡£¾µÇ§¤È¤Ï¡¢Ã¯¤«¤¬Ë¾¤ß¤Î¾ì½ê¤Ëé¤êÃ失¤¿¤ê¡¢ + ˾¤ß¤Î¾ðÊó¤ò¼ê¤ËÆþ¤ì¤¿¤ê¤¹¤ë¤³¤È¤òµö²Ä¤¹¤ë½èÍý¤Î¤³¤È¤Ç¤¹¡£

    + +

    »²¾È: ǧ¾Ú¡¢¾µÇ§¡¢¥¢¥¯¥»¥¹À©¸æ

    +
    +
    + +
    +
    CGI ¤Ë¤è¤ëưŪ¥³¥ó¥Æ¥ó¥Ä
    +
    +

    CGI (Common Gateway Interface) ¤Ï¥¦¥§¥Ö¥µ¡¼¥Ð¤¬³°Éô¤Î¥³¥ó¥Æ¥ó¥Ä + À¸À®¥×¥í¥°¥é¥à¤È¤É¤Î¤è¤¦¤ËÁê¸ßÆ°ºî¤ò¤¹¤ë¤«¤òÄêµÁ¤·¤Þ¤¹¡£ + ¤½¤Î³°Éô¥×¥í¥°¥é¥à¤ÏÄ̾ï CGI ¥×¥í¥°¥é¥à¤ä CGI ¥¹¥¯¥ê¥×¥È¤È¸Æ¤Ð¤ì¤Þ¤¹¡£ + CGI ¤Ï¥¦¥§¥Ö¥µ¥¤¥È¤ËưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤òÄɲ乤뤿¤á¤Î¡¢ + °ìÈÖñ½ã¤Ç¤è¤¯»È¤ï¤ì¤Æ¤¤¤ëÊýË¡¤Ç¤¹¡£¤³¤Îʸ½ñ¤Ï Apache ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë + CGI ¤òÀßÄꤷ¡¢CGI ¥×¥í¥°¥é¥à¤ò½ñ¤­»Ï¤á¤ë¤¿¤á¤Î¥¤¥ó¥È¥í¥À¥¯¥·¥ç¥ó¤Ç¤¹¡£

    + +

    »²¾È: CGI: ưŪ¥³¥ó¥Æ¥ó¥Ä

    +
    +
    + +
    +
    .htaccess ¥Õ¥¡¥¤¥ë
    +
    +

    .htaccess ¥Õ¥¡¥¤¥ë¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤ËÀßÄê¤òÊѹ¹¤¹¤ë¤¿¤á¤Î + ÊýË¡¤òÄ󶡤·¤Þ¤¹¡£ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬½ñ¤«¤ì¤¿¥Õ¥¡¥¤¥ë¤¬¡¢¤¢¤ë¥É¥­¥å¥á¥ó¥È + ¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤«¤ì¤ë¤È¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È + ¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËŬÍѤµ¤ì¤Þ¤¹¡£

    + +

    »²¾È: .htaccess ¥Õ¥¡¥¤¥ë

    +
    +
    + +
    +
    Server Side Includes ¥¤¥ó¥È¥í¥À¥¯¥·¥ç¥ó
    +
    +

    SSI (Server Side Includes) ¤Ï HTML ¥Ú¡¼¥¸Ãæ¤Ë½ñ¤«¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ + ¥Ú¡¼¥¸¤¬Á÷¤é¤ì¤ë»þ¤Ë¥µ¡¼¥Ð¤Ë¤è¤êɾ²Á¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥Ú¡¼¥¸Á´ÂΤò + CGI ¥×¥í¥°¥é¥à¤ÇÀ¸À®¤·¤¿¤ê¡¢Â¾¤ÎưŪ¤Êµ»½Ñ¤ò»È¤¦¤³¤È¤Ê¤¯¡¢´û¸¤Î HTML + ¥Ú¡¼¥¸¤ËưŪ¤ËÀ¸À®¤µ¤ì¤¿ÆâÍƤòÉղ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    »²¾È: Server Side Includes (SSI)

    +
    +
    + +
    +
    ¥æ¡¼¥¶Ëè¤Î¥¦¥§¥Ö¥Ç¥£¥ì¥¯¥È¥ê
    +
    +

    Ê£¿ô¥æ¡¼¥¶¤Î¸ºß¤¹¤ë¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¤½¤ì¤¾¤ì¤Î¥æ¡¼¥¶¤Ï UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤³¤È¤Ë¤è¤Ã¤Æ + ¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¾å¤Ë¥¦¥§¥Ö¥µ¥¤¥È¤òºîÀ®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + URL http://example.com/~username/ ¤òˬ¤ì¤¿¿Í¤Ï + ¥æ¡¼¥¶ "username" ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î¡¢UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿ + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¥³¥ó¥Æ¥ó¥Ä¤òÆÀ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    »²¾È: ¥æ¡¼¥¶¥¦¥§¥Ö¥Ç¥£¥ì¥¯¥È¥ê (public_html)

    +
    +
    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/index.html.ko.euc-kr b/trunk/docs/manual/howto/index.html.ko.euc-kr new file mode 100644 index 0000000000..5630623356 --- /dev/null +++ b/trunk/docs/manual/howto/index.html.ko.euc-kr @@ -0,0 +1,107 @@ + + + +How-To / ÅõÅ丮¾ó - Apache HTTP Server + + + + + +
    <-
    +

    How-To / ÅõÅ丮¾ó

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    +
    top
    +
    +

    How-To / ÅõÅ丮¾ó

    + + + +
    +
    ÀÎÁõ
    +
    +

    ÀÎÁõ(authentication)Àº ÀÚ½ÅÀÌ ´©±¸¶ó°í ÁÖÀåÇÏ´Â »ç¶÷À» + È®ÀÎÇÏ´Â ÀýÂ÷ÀÌ´Ù. ±ÇÇѺο©(authorization)´Â °¡°í ½ÍÀº + °÷À¸·Î °¡µµ·Ï ȤÀº ¿øÇÏ´Â Á¤º¸¸¦ ¾òµµ·Ï Çã¿ëÇÏ´Â °úÁ¤ÀÌ´Ù.

    + +

    Âü°í: ÀÎÁõ, ±ÇÇѺο©, Á¢±ÙÁ¦¾î

    +
    +
    + +
    +
    CGI¸¦ »ç¿ëÇÑ µ¿Àû ÆäÀÌÁö »ý¼º
    +
    +

    CGI (Common Gateway Interface)´Â À¥¼­¹ö°¡ º¸Åë CGI + ÇÁ·Î±×·¥ ȤÀº CGI ½ºÅ©¸³Æ®ÇÏ°í ºÎ¸£´Â, (À¥ÆäÀÌÁö ³»¿ëÀ» + ¸¸µå´Â) ¿ÜºÎ ÇÁ·Î±×·¥°ú »óÈ£ÀÛ¿ëÇÏ´Â ¹æ¹ýÀ» Á¤ÀÇÇÑ´Ù. + À¥»çÀÌÆ®¿¡¼­ µ¿ÀûÀÎ ÆäÀÌÁö¸¦ ¸¸µå´Â °¡Àå ÈçÇÏ°í °£´ÜÇÑ + ¹æ¹ýÀÌ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ CGI¸¦ ±¸¼ºÇÏ´Â ¹æ¹ýÀ» + ¼Ò°³ÇÏ°í, CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇغ»´Ù.

    + +

    Âü°í: CGI: µ¿Àû ÆäÀÌÁö »ý¼º

    +
    +
    + +
    +
    .htaccess ÆÄÀÏ
    +
    +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© µð·ºÅ丮º°·Î + ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖ´Ù. ¿©·¯ ¼³Á¤ Áö½Ã¾î°¡ ÀÖ´Â ÆÄÀÏÀ» + ƯÁ¤ ¹®¼­ µð·ºÅ丮¿¡ µÎ¸é, ±× µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ + Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù.

    + +

    Âü°í: .htaccess + ÆÄÀÏ

    +
    +
    + +
    +
    Server Side Includes ¼Ò°³
    +
    +

    SSI (Server Side Includes)´Â HTML ÆäÀÌÁö¿¡ »ç¿ëÇÏ´Â + Áö½Ã¾î·Î, ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ¶§ ¼­¹ö°¡ ó¸®ÇÑ´Ù. SSI¸¦ + »ç¿ëÇϸé CGI ÇÁ·Î±×·¥À̳ª ´Ù¸¥ µ¿ÀûÀÎ ±â¼ú·Î ÆäÀÌÁö + Àüü¸¦ ¸¸µé¾î¼­ ¼­ºñ½ºÇÏÁö ¾Ê°íµµ HTML ÆäÀÌÁö¿¡ µ¿ÀûÀ¸·Î + »ý¼ºÇÑ ³»¿ëÀ» Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    Âü°í: Server Side Includes (SSI)

    +
    +
    + +
    +
    »ç¿ëÀÚº° À¥µð·ºÅ丮
    +
    +

    ¿©·¯ »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼­ UserDir Áö½Ã¾î¸¦ »ç¿ëÇϸé + °¢ »ç¿ëÀÚ´Â ÀÚ½ÅÀÇ È¨µð·ºÅ丮 ¾È¿¡ À¥»çÀÌÆ®¸¦ ¸¸µé ¼ö + ÀÖ´Ù. URL http://example.com/~username/¿¡ + Á¢±ÙÇÏ¸é »ç¿ëÀÚ "username"ÀÇ È¨µð·ºÅ丮¿¡¼­ + UserDir + Áö½Ã¾î·Î ÁöÁ¤ÇÑ ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆäÀÌÁö¸¦ °¡Á®¿À°Ô + µÈ´Ù.

    + +

    Âü°í: »ç¿ëÀÚ À¥µð·ºÅ丮 + (public_html)

    +
    +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/index.xml b/trunk/docs/manual/howto/index.xml new file mode 100644 index 0000000000..c81e72a1e6 --- /dev/null +++ b/trunk/docs/manual/howto/index.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + How-To / Tutorials + +
    + + How-To / Tutorials + +
    +
    Authentication
    +
    +

    Authentication is any process by which you verify that + someone is who they claim they are. Authorization is any + process by which someone is allowed to be where they want to + go, or to have information that they want to have.

    + +

    See: Authentication, Authorization, and Access Control

    +
    +
    + +
    +
    Dynamic Content with CGI
    +
    +

    The CGI (Common Gateway Interface) defines a way for a web + server to interact with external content-generating programs, + which are often referred to as CGI programs or CGI scripts. It + is the simplest, and most common, way to put dynamic content on + your web site. This document will be an introduction to setting + up CGI on your Apache web server, and getting started writing + CGI programs.

    + +

    See: CGI: Dynamic Content

    +
    +
    + +
    +
    .htaccess files
    +
    +

    .htaccess files provide a way to make configuration + changes on a per-directory basis. A file, containing one or more + configuration directives, is placed in a particular document directory, + and the directives apply to that directory, and all subdirectories thereof.

    + +

    See: .htaccess files

    +
    +
    + +
    +
    Introduction to Server Side Includes
    +
    +

    SSI (Server Side Includes) are directives that are placed in + HTML pages, and evaluated on the server while the pages are + being served. They let you add dynamically generated content to + an existing HTML page, without having to serve the entire page + via a CGI program, or other dynamic technology.

    + +

    See: Server Side Includes (SSI)

    +
    +
    + +
    +
    Per-user web directories
    +
    +

    On systems with multiple users, each user can be permitted to have a + web site in their home directory using the UserDir directive. Visitors + to a URL http://example.com/~username/ will get content + out of the home directory of the user "username", out of + the subdirectory specified by the UserDir directive.

    + +

    See: User web directories (public_html)

    +
    +
    + +
    + +
    + + diff --git a/trunk/docs/manual/howto/index.xml.ja b/trunk/docs/manual/howto/index.xml.ja new file mode 100644 index 0000000000..8b2343d5dd --- /dev/null +++ b/trunk/docs/manual/howto/index.xml.ja @@ -0,0 +1,101 @@ + + + + + + + + + + + How-To / $B%A%e!<%H%j%"%k(B + +
    + + How-To / $B%A%e!<%H%j%"%k(B + +
    +
    $BG'>Z(B
    +
    +

    $BG'>Z$H$O!"C/$+$,<+J,$OC/$G$"$k$+$rL>>h$C$F$$$k$b$N$r8!>Z$9$k(B + $B=hM}$N$3$H$G$9!#>5G'$H$O!"C/$+$,K>$_$N>l=j$KC)$jCe$1$?$j!"(B + $BK>$_$N>pJs$r + +

    $B;2>H(B: $BG'>Z!">5G'!"%"%/%;%9@)8f(B

    +
    +
    + +
    +
    CGI $B$K$h$kF0E*%3%s%F%s%D(B
    +
    +

    CGI (Common Gateway Interface) $B$O%&%'%V%5!<%P$,30It$N%3%s%F%s%D(B + $B@8@.%W%m%0%i%`$H$I$N$h$&$KAj8_F0:n$r$9$k$+$rDj5A$7$^$9!#(B + $B$=$N30It%W%m%0%i%`$ODL>o(B CGI $B%W%m%0%i%`$d(B CGI $B%9%/%j%W%H$H8F$P$l$^$9!#(B + CGI $B$O%&%'%V%5%$%H$KF0E*$J%3%s%F%s%D$rDI2C$9$k$?$a$N!"(B + $B0lHVC1=c$G$h$/;H$o$l$F$$$kJ}K!$G$9!#$3$NJ8=q$O(B Apache $B%&%'%V%5!<%P$K(B + CGI $B$r@_Dj$7!"(BCGI $B%W%m%0%i%`$r=q$-;O$a$k$?$a$N%$%s%H%m%@%/%7%g%s$G$9!#(B

    + +

    $B;2>H(B: CGI: $BF0E*%3%s%F%s%D(B

    +
    +
    + +
    +
    .htaccess $B%U%!%$%k(B
    +
    +

    .htaccess $B%U%!%$%k$O%G%#%l%/%H%jKh$K@_Dj$rJQ99$9$k$?$a$N(B + $BJ}K!$rDs6!$7$^$9!#@_Dj%G%#%l%/%F%#%V$,=q$+$l$?%U%!%$%k$,!"$"$k%I%-%e%a%s%H(B + $B%G%#%l%/%H%j$KCV$+$l$k$H!"%G%#%l%/%F%#%V$O$=$N%G%#%l%/%H%j$H(B + $B$9$Y$F$N%5%V%G%#%l%/%H%j$KE,MQ$5$l$^$9!#(B

    + +

    $B;2>H(B: .htaccess $B%U%!%$%k(B

    +
    +
    + +
    +
    Server Side Includes $B%$%s%H%m%@%/%7%g%s(B
    +
    +

    SSI (Server Side Includes) $B$O(B HTML $B%Z!<%8Cf$K=q$+$l$k%G%#%l%/%F%#%V$G!"(B + $B%Z!<%8$,Aw$i$l$k;~$K%5!<%P$K$h$jI>2A$5$l$^$9!#$3$l$K$h$j!"%Z!<%8A4BN$r(B + CGI $B%W%m%0%i%`$G@8@.$7$?$j!"B>$NF0E*$J5;=Q$r;H$&$3$H$J$/!"4{B8$N(B HTML + $B%Z!<%8$KF0E*$K@8@.$5$l$?FbMF$rIU2C$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B;2>H(B: Server Side Includes (SSI)

    +
    +
    + +
    +
    $B%f!<%6Kh$N%&%'%V%G%#%l%/%H%j(B
    +
    +

    $BJ#?t%f!<%6$NB8:_$9$k%7%9%F%`$G$O!"$=$l$>$l$N%f!<%6$O(B UserDir $B%G%#%l%/%F%#%V$r;H$&$3$H$K$h$C$F(B + $B%[!<%`%G%#%l%/%H%j>e$K%&%'%V%5%$%H$r:n@.$9$k$3$H$,$G$-$^$9!#(B + URL http://example.com/~username/ $B$rK,$l$??M$O(B + $B%f!<%6(B "username" $B$N%[!<%`%G%#%l%/%H%j$N!"(BUserDir $B%G%#%l%/%F%#%V$G;XDj$5$l$?(B + $B%5%V%G%#%l%/%H%j$+$i%3%s%F%s%D$rF@$k$3$H$K$J$j$^$9!#(B

    + +

    $B;2>H(B: $B%f!<%6%&%'%V%G%#%l%/%H%j(B (public_html)

    +
    +
    + +
    + +
    + + diff --git a/trunk/docs/manual/howto/index.xml.ko b/trunk/docs/manual/howto/index.xml.ko new file mode 100644 index 0000000000..637f2e2a2d --- /dev/null +++ b/trunk/docs/manual/howto/index.xml.ko @@ -0,0 +1,104 @@ + + + + + + + + + + + How-To / ÅõÅ丮¾ó + +
    + + How-To / ÅõÅ丮¾ó + +
    +
    ÀÎÁõ
    +
    +

    ÀÎÁõ(authentication)Àº ÀÚ½ÅÀÌ ´©±¸¶ó°í ÁÖÀåÇÏ´Â »ç¶÷À» + È®ÀÎÇÏ´Â ÀýÂ÷ÀÌ´Ù. ±ÇÇѺο©(authorization)´Â °¡°í ½ÍÀº + °÷À¸·Î °¡µµ·Ï ȤÀº ¿øÇÏ´Â Á¤º¸¸¦ ¾òµµ·Ï Çã¿ëÇÏ´Â °úÁ¤ÀÌ´Ù.

    + +

    Âü°í: ÀÎÁõ, ±ÇÇѺο©, Á¢±ÙÁ¦¾î

    +
    +
    + +
    +
    CGI¸¦ »ç¿ëÇÑ µ¿Àû ÆäÀÌÁö »ý¼º
    +
    +

    CGI (Common Gateway Interface)´Â À¥¼­¹ö°¡ º¸Åë CGI + ÇÁ·Î±×·¥ ȤÀº CGI ½ºÅ©¸³Æ®ÇÏ°í ºÎ¸£´Â, (À¥ÆäÀÌÁö ³»¿ëÀ» + ¸¸µå´Â) ¿ÜºÎ ÇÁ·Î±×·¥°ú »óÈ£ÀÛ¿ëÇÏ´Â ¹æ¹ýÀ» Á¤ÀÇÇÑ´Ù. + À¥»çÀÌÆ®¿¡¼­ µ¿ÀûÀÎ ÆäÀÌÁö¸¦ ¸¸µå´Â °¡Àå ÈçÇÏ°í °£´ÜÇÑ + ¹æ¹ýÀÌ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ CGI¸¦ ±¸¼ºÇÏ´Â ¹æ¹ýÀ» + ¼Ò°³ÇÏ°í, CGI ÇÁ·Î±×·¥À» ÀÛ¼ºÇغ»´Ù.

    + +

    Âü°í: CGI: µ¿Àû ÆäÀÌÁö »ý¼º

    +
    +
    + +
    +
    .htaccess ÆÄÀÏ
    +
    +

    .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© µð·ºÅ丮º°·Î + ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖ´Ù. ¿©·¯ ¼³Á¤ Áö½Ã¾î°¡ ÀÖ´Â ÆÄÀÏÀ» + ƯÁ¤ ¹®¼­ µð·ºÅ丮¿¡ µÎ¸é, ±× µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§µð·ºÅ丮¿¡ + Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù.

    + +

    Âü°í: .htaccess + ÆÄÀÏ

    +
    +
    + +
    +
    Server Side Includes ¼Ò°³
    +
    +

    SSI (Server Side Includes)´Â HTML ÆäÀÌÁö¿¡ »ç¿ëÇÏ´Â + Áö½Ã¾î·Î, ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ¶§ ¼­¹ö°¡ ó¸®ÇÑ´Ù. SSI¸¦ + »ç¿ëÇϸé CGI ÇÁ·Î±×·¥À̳ª ´Ù¸¥ µ¿ÀûÀÎ ±â¼ú·Î ÆäÀÌÁö + Àüü¸¦ ¸¸µé¾î¼­ ¼­ºñ½ºÇÏÁö ¾Ê°íµµ HTML ÆäÀÌÁö¿¡ µ¿ÀûÀ¸·Î + »ý¼ºÇÑ ³»¿ëÀ» Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    Âü°í: Server Side Includes (SSI)

    +
    +
    + +
    +
    »ç¿ëÀÚº° À¥µð·ºÅ丮
    +
    +

    ¿©·¯ »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼­ UserDir Áö½Ã¾î¸¦ »ç¿ëÇϸé + °¢ »ç¿ëÀÚ´Â ÀÚ½ÅÀÇ È¨µð·ºÅ丮 ¾È¿¡ À¥»çÀÌÆ®¸¦ ¸¸µé ¼ö + ÀÖ´Ù. URL http://example.com/~username/¿¡ + Á¢±ÙÇÏ¸é »ç¿ëÀÚ "username"ÀÇ È¨µð·ºÅ丮¿¡¼­ + UserDir + Áö½Ã¾î·Î ÁöÁ¤ÇÑ ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆäÀÌÁö¸¦ °¡Á®¿À°Ô + µÈ´Ù.

    + +

    Âü°í: »ç¿ëÀÚ À¥µð·ºÅ丮 + (public_html)

    +
    +
    + +
    + +
    + + diff --git a/trunk/docs/manual/howto/index.xml.meta b/trunk/docs/manual/howto/index.xml.meta new file mode 100644 index 0000000000..c91f4a8999 --- /dev/null +++ b/trunk/docs/manual/howto/index.xml.meta @@ -0,0 +1,13 @@ + + + + index + /howto/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/howto/public_html.html b/trunk/docs/manual/howto/public_html.html new file mode 100644 index 0000000000..690c35b259 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.html @@ -0,0 +1,11 @@ +URI: public_html.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: public_html.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: public_html.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/howto/public_html.html.en b/trunk/docs/manual/howto/public_html.html.en new file mode 100644 index 0000000000..0af608c345 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.html.en @@ -0,0 +1,161 @@ + + + +Per-user web directories - Apache HTTP Server + + + + + +
    <-
    +

    Per-user web directories

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    On systems with multiple users, each user can be permitted to have a + web site in their home directory using the UserDir directive. Visitors + to a URL http://example.com/~username/ will get content + out of the home directory of the user "username", out of + the subdirectory specified by the UserDir directive.

    + +
    + +
    top
    +
    top
    +
    +

    Setting the file path with UserDir

    + + +

    The UserDir + directive specifies a directory out of which per-user + content is loaded. This directive may take several different forms.

    + +

    If a path is given which does not start with a leading slash, it is + assumed to be a directory path relative to the home directory of the + specified user. Given this configuration:

    + +

    + UserDir public_html +

    + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path + /home/rbowen/public_html/file.html

    + +

    If a path is given starting with a slash, a directory path will be + constructed using that path, plus the username specified. Given this + configuration:

    + +

    + UserDir /var/html +

    + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path /var/html/rbowen/file.html

    + +

    If a path is provided which contains an asterisk (*), a path is used + in which the asterisk is replaced with the username. Given this + configuration:

    + +

    + UserDir /var/www/*/docs +

    + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path + /var/www/rbowen/docs/file.html

    + +
    top
    +
    +

    Restricting what users are permitted to use this + feature

    + + +

    Using the syntax shown in the UserDir documentation, you can restrict + what users are permitted to use this functionality:

    + +

    + UserDir enabled
    + UserDir disabled root jro fish +

    + +

    The configuration above will enable the feature for all users + except for those listed in the disabled statement. + You can, likewise, disable the feature for all but a few users by + using a configuration like the following:

    + +

    + UserDir disabled
    + UserDir enabled rbowen krietz +

    + +

    See UserDir + documentation for additional examples.

    + +
    top
    +
    +

    Enabling a cgi directory for each user

    + + +

    In order to give each user their own cgi-bin directory, you can use + a <Directory> + directive to make a particular subdirectory of a user's home directory + cgi-enabled.

    + +

    + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +

    + +

    Then, presuming that UserDir is set to + public_html, a cgi program example.cgi + could be loaded from that directory as:

    + +

    + http://example.com/~rbowen/cgi-bin/example.cgi +

    + +
    top
    +
    +

    Allowing users to alter configuration

    + + +

    If you want to allows users to modify the server configuration in + their web space, they will need to use .htaccess files to + make these changed. Ensure that you have set AllowOverride to a + value sufficient for the directives that you want to permit the users + to modify. See the .htaccess tutorial for + additional details on how this works.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/public_html.html.ja.euc-jp b/trunk/docs/manual/howto/public_html.html.ja.euc-jp new file mode 100644 index 0000000000..71b4f58aa9 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.html.ja.euc-jp @@ -0,0 +1,155 @@ + + + +¥æ¡¼¥¶Ëè¤Î¥¦¥§¥Ö¥Ç¥£¥ì¥¯¥È¥ê - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥æ¡¼¥¶Ëè¤Î¥¦¥§¥Ö¥Ç¥£¥ì¥¯¥È¥ê

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Ê£¿ô¤Î¥æ¡¼¥¶¤Î¤¤¤ë¥·¥¹¥Æ¥à¤Ç¤Ï¡¢UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ + ³Æ¥æ¡¼¥¶¤¬¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥¦¥§¥Ö¥µ¥¤¥È¤ò¹½ÃۤǤ­¤ë¤è¤¦¤ËÀßÄꤹ¤ë¤³¤È¤¬ + ²Äǽ¤Ç¤¹¡£URL http://example.com/~username/ ¤òˬ¤ì¤¿¿Í¤Ï + "username" ¤È¤¤¤¦¥æ¡¼¥¶¤Î UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿ + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¥³¥ó¥Æ¥ó¥Ä¤òÆÀ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥æ¡¼¥¶Ëè¤Î¥¦¥§¥Ö¥Ç¥£¥ì¥¯¥È¥ê

    + + +
    top
    +
    +

    UserDir ¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÀßÄꤹ¤ë

    + + +

    UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥æ¡¼¥¶Ëè¤Î¥³¥ó¥Æ¥ó¥Ä¤¬Æɤ߹þ¤Þ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¤¤í¤¤¤í°ã¤Ã¤¿·Á¼°¤ò¼è¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤é¤Ê¤¤¥Ñ¥¹¤¬Í¿¤¨¤é¤ì¤¿¤È¤­¤Ï¡¢¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê + ¤«¤é¤ÎÁêÂХѥ¹¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£¼¡¤ÎÀßÄ꤬¤¢¤Ã¤¿¤È¤­¤Ë:

    + +

    + UserDir public_html +

    + +

    URL http://example.com/~rbowen/file.html ¤Ï + ¥Ñ¥¹ /home/rbowen/public_html/file.html ¤Ø + ÊÑ´¹¤µ¤ì¤Þ¤¹¡£

    + +

    ¥Ñ¥¹¤¬¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤ë¤È¤­¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê¥Ñ¥¹¤Ï¤½¤Î¥Ñ¥¹¤Ë + ¥æ¡¼¥¶Ì¾¤ò²Ã¤¨¤¿¤â¤Î¤«¤é¤Ê¤ê¤Þ¤¹¡£¼¡¤ÎÀßÄê¤Î¤È¤­:

    + +

    + UserDir /var/html +

    + +

    URL http://example.com/~rbowen/file.html ¤Ï + ¥Ñ¥¹ /var/html/rbowen/file.html ¤ØÊÑ´¹¤µ¤ì¤Þ¤¹¡£

    + +

    ¥¢¥¹¥¿¥ê¥¹¥¯ (*) ¤ò´Þ¤à¥Ñ¥¹¤¬»ØÄꤵ¤ì¤¿¤È¤­¤Ï¡¢¥¢¥¹¥¿¥ê¥¹¥¯¤ò + ¥æ¡¼¥¶Ì¾¤ÇÃÖ´¹¤·¤¿¤â¤Î¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¤è¤¦¤ÊÀßÄê¤À¤È:

    + +

    + UserDir /var/www/*/docs +

    + +

    URL http://example.com/~rbowen/file.html ¤Ï + ¥Ñ¥¹ /var/www/rbowen/docs/file.html ¤ØÊÑ´¹¤µ¤ì¤Þ¤¹¡£

    + +
    top
    +
    +

    ¤³¤Îµ¡Ç½¤ò»ÈÍѤǤ­¤ë¥æ¡¼¥¶¤òÀ©¸Â¤¹¤ë

    + + +

    UserDir ¤Î¥É¥­¥å¥á¥ó¥È¤Ë¼¨¤µ¤ì¤Æ¤¤¤ë¹½Ê¸¤ò»È¤¦¤³¤È¤Ç¡¢ + ¤É¤Î¥æ¡¼¥¶¤¬¤³¤Îµ¡Ç½¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤ë¤«¤òÀ©¸Â¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + UserDir enabled
    + UserDir disabled root jro fish +

    + +

    ¾å¤ÎÀßÄê¤Ï dissabled ʸ¤Î¥æ¡¼¥¶°Ê³°¤Î¤¹¤Ù¤Æ¤Î¥æ¡¼¥¶¤Ë + ÂФ·¤Æ UserDir ¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£Æ±Íͤˤ·¤Æ¡¢°Ê²¼¤Î¤è¤¦¤Ë + ¿ô̾¤Î¥æ¡¼¥¶°Ê³°¤ËÂФ·¤Æ¤³¤Îµ¡Ç½¤ò̵¸ú¤Ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹:

    + +

    + UserDir disabled
    + UserDir enabled rbowen krietz +

    + +

    ¾¤ÎÎã¤Ï UserDir + ¤ÎÀâÌÀ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    ¥æ¡¼¥¶Ëè¤Î CGI ¥Ç¥£¥ì¥¯¥È¥ê

    + + +

    ¤½¤ì¤¾¤ì¤Î¥æ¡¼¥¶¤ËÀìÍѤΠcgi-bin ¥Ç¥£¥ì¥¯¥È¥ê¤òÍ¿¤¨¤ë¤¿¤á¤Ë¡¢ + <Directory> + ¤ò»È¤Ã¤Æ¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î»ØÄꤵ¤ì¤¿Îΰè¤ËÂФ·¤Æ CGI ¤òÍ­¸ú¤Ë + ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +

    + +

    ¤½¤·¤Æ¡¢UserDir ¤¬ + public_html ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È²¾Äꤹ¤ë¤È¡¢ + ¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î CGI ¥×¥í¥°¥é¥à example.cgi + ¤Ï°Ê²¼¤ÎÍͤ˸ƤӽФµ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + http://example.com/~rbowen/cgi-bin/example.cgi +

    + +
    top
    +
    +

    ¥æ¡¼¥¶¤Ë¤è¤ëÀßÄêÊѹ¹¤òµö²Ä

    + + +

    ¥æ¡¼¥¶¤ËÈà¤é¤Î¥¦¥§¥Ö¶õ´Ö¤Ç¤Î¥µ¡¼¥Ð¤ÎÀßÄê¤ÎÊѹ¹¤òµö²Ä¤¹¤ë¾ì¹ç¡¢ + ¥æ¡¼¥¶¤Ï .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤ÆÀßÄê¤òÊѹ¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + AllowOverride ¤ÎÃͤò + ¥æ¡¼¥¶¤¬Êѹ¹¤¹¤ë¤³¤È¤òµö²Ä¤·¤¿¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÂФ·¤Æ½½Ê¬¤Ê¤â¤Î¤Ë + ÀßÄꤷ¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Îµ¡Ç½¤¬¤É¤Î¤è¤¦¤Ë¤·¤ÆÆ°ºî¤·¤Æ¤¤¤ë¤« + ¤Î¾ÜºÙ¤Ï .htaccess ¥Á¥å¡¼¥È¥ê¥¢¥ë ¤òÆɤó¤Ç + ¤¯¤À¤µ¤¤¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/public_html.html.ko.euc-kr b/trunk/docs/manual/howto/public_html.html.ko.euc-kr new file mode 100644 index 0000000000..1d0b895552 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.html.ko.euc-kr @@ -0,0 +1,156 @@ + + + +»ç¿ëÀÚº° À¥µð·ºÅ丮 - Apache HTTP Server + + + + + +
    <-
    +

    »ç¿ëÀÚº° À¥µð·ºÅ丮

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    ¿©·¯ »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼­ UserDir Áö½Ã¾î¸¦ »ç¿ëÇϸé + °¢ »ç¿ëÀÚ´Â ÀÚ½ÅÀÇ È¨µð·ºÅ丮 ¾È¿¡ À¥»çÀÌÆ®¸¦ ¸¸µé ¼ö ÀÖ´Ù. + URL http://example.com/~username/¿¡ Á¢±ÙÇϸé + »ç¿ëÀÚ "username"ÀÇ È¨µð·ºÅ丮¿¡¼­ UserDir Áö½Ã¾î·Î ÁöÁ¤ÇÑ + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆäÀÌÁö¸¦ °¡Á®¿À°Ô µÈ´Ù.

    + +
    + +
    top
    +
    +

    »ç¿ëÀÚº° À¥µð·ºÅ丮

    + + +
    top
    +
    +

    UserDir·Î ÆÄÀÏ°æ·Î ÁöÁ¤Çϱâ

    + + +

    UserDir + Áö½Ã¾î´Â »ç¿ëÀÚº° ÆäÀÌÁö¸¦ °¡Á®¿Ã µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ + Áö½Ã¾îÀÇ »ç¿ë¹ýÀº ¿©·¯°¡Áö´Ù.

    + +

    ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾Ê´Â °æ·Î¸¦ ÁöÁ¤ÇÏ¸é °¢ »ç¿ëÀÚÀÇ + Ȩµð·ºÅ丮¿¡ »ó´ëÀûÀÎ µð·ºÅ丮 °æ·Î·Î ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¾Æ·¡ ¼³Á¤ÀÇ °æ¿ì:

    + +

    + UserDir public_html +

    + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /home/rbowen/public_html/file.htmlÀ» + ¶æÇÑ´Ù.

    + +

    ½½·¡½¬·Î ½ÃÀÛÇÏ´Â °æ·Î¸¦ ÁöÁ¤Çϸé ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ + »ç¿ëÀÚ¸íÀ» ´õÇÑ µð·ºÅ丮 °æ·Î¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾Æ·¡ + ¼³Á¤ÀÇ °æ¿ì:

    + +

    + UserDir /var/html +

    + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /var/html/rbowen/file.htmlÀ» ¶æÇÑ´Ù.

    + +

    º°Ç¥ (*)¸¦ Æ÷ÇÔÇÑ °æ·Î¸¦ ÁöÁ¤ÇÏ¸é º°Ç¥¸¦ »ç¿ëÀÚ¸íÀ¸·Î + ´ëüÇÑ °æ·Î¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾Æ·¡ ¼³Á¤ÀÇ °æ¿ì:

    + +

    + UserDir /var/www/*/docs +

    + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /var/www/rbowen/docs/file.htmlÀ» + ¶æÇÑ´Ù.

    + +
    top
    +
    +

    ±â´ÉÀ» ÀÌ¿ëÇÒ »ç¿ëÀÚ Á¦ÇÑÇϱâ

    + + +

    UserDir ¹®¼­¿¡ ÀÖ´Â ¹®¹ýÀ» »ç¿ëÇÏ¿© »ç¿ëÀÚº° À¥µð·ºÅ丮 + ±â´ÉÀ» ÀÌ¿ëÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¸¦ Á¦ÇÑÇÒ ¼ö ÀÖ´Ù:

    + +

    + UserDir enabled
    + UserDir disabled root jro fish +

    + +

    À§ ¼³Á¤Àº disabled ¹®Àå¿¡ ¿­°ÅÇÑ »ç¶÷À» + Á¦¿ÜÇÏ°í ¸ðµç »ç¿ëÀÚ¿¡°Ô À¥µð·ºÅ丮 ±â´ÉÀ» Çã¶ôÇÑ´Ù. ¶Ç, + ´ÙÀ½°ú °°ÀÌ ¸î¸î »ç¿ëÀÚ¸¦ Á¦¿ÜÇÏ°í ±â´ÉÀ» Çã¶ôÇÏÁö ¾ÊÀ» + ¼öµµ ÀÖ´Ù:

    + +

    + UserDir disabled
    + UserDir enabled rbowen krietz +

    + +

    UserDir + ¹®¼­¿¡ ÀÖ´Â ´Ù¸¥ ¿¹µéµµ Âü°íÇ϶ó.

    + +
    top
    +
    +

    °¢ »ç¿ëÀÚº° cgi µð·ºÅ丮 ÁöÁ¤Çϱâ

    + + +

    »ç¿ëÀÚ¸¶´Ù cgi-bin µð·ºÅ丮¸¦ ºÎ¿©ÇÏ·Á¸é <Directory> Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© »ç¿ëÀÚ È¨µð·ºÅ丮ÀÇ Æ¯Á¤ ÇÏÀ§µð·ºÅ丮¸¦ cgi °¡´ÉÇÏ°Ô + ¸¸µç´Ù.

    + +

    + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +

    + +

    UserDirÀÌ public_htmlÀ̶ó°í + °¡Á¤Çϸé, ´ÙÀ½°ú °°ÀÌ ±× ¾È¿¡ ÀÖ´Â cgi ÇÁ·Î±×·¥ + example.cgi¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + +

    + http://example.com/~rbowen/cgi-bin/example.cgi +

    + +
    top
    +
    +

    »ç¿ëÀÚ°¡ ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖµµ·Ï ¸¸µé±â

    + + +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ À¥°ø°£¿¡ ´ëÇÑ À¥¼­¹ö ¼³Á¤À» ¼öÁ¤ÇÏ·Á¸é, + .htaccess ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. AllowOverride¸¦ »ç¿ëÀÚ°¡ ¼öÁ¤ÇÒ + ¼ö ÀÖ´Â Áö½Ã¾î¿¡ ÀûÇÕÇÑ °ªÀ¸·Î ¼³Á¤Ç϶ó. ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö¿¡ + ´ëÇÑ ÀÚ¼¼ÇÑ Á´º¸´Â .htaccess + ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/public_html.xml b/trunk/docs/manual/howto/public_html.xml new file mode 100644 index 0000000000..18be56808b --- /dev/null +++ b/trunk/docs/manual/howto/public_html.xml @@ -0,0 +1,164 @@ + + + + + + + + +How-To / Tutorials + + Per-user web directories + + +

    On systems with multiple users, each user can be permitted to have a + web site in their home directory using the UserDir directive. Visitors + to a URL http://example.com/~username/ will get content + out of the home directory of the user "username", out of + the subdirectory specified by the UserDir directive.

    + +
    + +Mapping URLs to the Filesystem + + + +
    + Setting the file path with UserDir + +

    The UserDir + directive specifies a directory out of which per-user + content is loaded. This directive may take several different forms.

    + +

    If a path is given which does not start with a leading slash, it is + assumed to be a directory path relative to the home directory of the + specified user. Given this configuration:

    + + + UserDir public_html + + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path + /home/rbowen/public_html/file.html

    + +

    If a path is given starting with a slash, a directory path will be + constructed using that path, plus the username specified. Given this + configuration:

    + + + UserDir /var/html + + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path /var/html/rbowen/file.html

    + +

    If a path is provided which contains an asterisk (*), a path is used + in which the asterisk is replaced with the username. Given this + configuration:

    + + + UserDir /var/www/*/docs + + +

    the URL http://example.com/~rbowen/file.html will be + translated to the file path + /var/www/rbowen/docs/file.html

    + +
    + +
    + Restricting what users are permitted to use this + feature + +

    Using the syntax shown in the UserDir documentation, you can restrict + what users are permitted to use this functionality:

    + + + UserDir enabled
    + UserDir disabled root jro fish +
    + +

    The configuration above will enable the feature for all users + except for those listed in the disabled statement. + You can, likewise, disable the feature for all but a few users by + using a configuration like the following:

    + + + UserDir disabled
    + UserDir enabled rbowen krietz +
    + +

    See UserDir + documentation for additional examples.

    + +
    + +
    + Enabling a cgi directory for each user + +

    In order to give each user their own cgi-bin directory, you can use + a Directory + directive to make a particular subdirectory of a user's home directory + cgi-enabled.

    + + + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +
    + +

    Then, presuming that UserDir is set to + public_html, a cgi program example.cgi + could be loaded from that directory as:

    + + + http://example.com/~rbowen/cgi-bin/example.cgi + + +
    + +
    + Allowing users to alter configuration + +

    If you want to allows users to modify the server configuration in + their web space, they will need to use .htaccess files to + make these changed. Ensure that you have set AllowOverride to a + value sufficient for the directives that you want to permit the users + to modify. See the .htaccess tutorial for + additional details on how this works.

    + +
    + +
    diff --git a/trunk/docs/manual/howto/public_html.xml.ja b/trunk/docs/manual/howto/public_html.xml.ja new file mode 100644 index 0000000000..3cc893f2dc --- /dev/null +++ b/trunk/docs/manual/howto/public_html.xml.ja @@ -0,0 +1,158 @@ + + + + + + + + +How-To / $B%A%e!<%H%j%"%k(B + + $B%f!<%6Kh$N%&%'%V%G%#%l%/%H%j(B + + +

    $BJ#?t$N%f!<%6$N$$$k%7%9%F%`$G$O!"(BUserDir $B%G%#%l%/%F%#%V$r;H$C$F(B + $B3F%f!<%6$,%[!<%`%G%#%l%/%H%j$K%&%'%V%5%$%H$r9=C[$G$-$k$h$&$K@_Dj$9$k$3$H$,(B + $B2DG=$G$9!#(BURL http://example.com/~username/ $B$rK,$l$??M$O(B + "username" $B$H$$$&%f!<%6$N(B UserDir $B%G%#%l%/%F%#%V$G;XDj$5$l$?(B + $B%5%V%G%#%l%/%H%j$+$i%3%s%F%s%D$rF@$k$3$H$K$J$j$^$9!#(B

    +
    + +URL $B$+$i%U%!%$%k%7%9%F%`$X$N%^%C%T%s%0(B + + + +
    + UserDir $B$r;H$C$F%U%!%$%k$N%Q%9$r@_Dj$9$k(B + +

    UserDir $B%G%#%l%/%F%#%V$O(B + $B%f!<%6Kh$N%3%s%F%s%D$,FI$_9~$^$l$k%G%#%l%/%H%j$r;XDj$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$O$$$m$$$m0c$C$?7A<0$r + +

    $B%9%i%C%7%e$G;O$^$i$J$$%Q%9$,M?$($i$l$?$H$-$O!"%f!<%6$N%[!<%`%G%#%l%/%H%j(B + $B$+$i$NAjBP%Q%9$H$_$J$5$l$^$9!# + + + UserDir public_html + + +

    URL http://example.com/~rbowen/file.html $B$O(B + $B%Q%9(B /home/rbowen/public_html/file.html $B$X(B + $BJQ49$5$l$^$9!#(B

    + +

    $B%Q%9$,%9%i%C%7%e$G;O$^$k$H$-$O!"%G%#%l%/%H%j%Q%9$O$=$N%Q%9$K(B + $B%f!<%6L>$r2C$($?$b$N$+$i$J$j$^$9!# + + + UserDir /var/html + + +

    URL http://example.com/~rbowen/file.html $B$O(B + $B%Q%9(B /var/html/rbowen/file.html $B$XJQ49$5$l$^$9!#(B

    + +

    $B%"%9%?%j%9%/(B (*) $B$r4^$`%Q%9$,;XDj$5$l$?$H$-$O!"%"%9%?%j%9%/$r(B + $B%f!<%6L>$GCV49$7$?$b$N$,;HMQ$5$l$^$9!#$3$N$h$&$J@_Dj$@$H(B:

    + + + UserDir /var/www/*/docs + + +

    URL http://example.com/~rbowen/file.html $B$O(B + $B%Q%9(B /var/www/rbowen/docs/file.html $B$XJQ49$5$l$^$9!#(B

    + +
    + +
    + $B$3$N5!G=$r;HMQ$G$-$k%f!<%6$r@)8B$9$k(B + +

    UserDir $B$N%I%-%e%a%s%H$K<($5$l$F$$$k9=J8$r;H$&$3$H$G!"(B + $B$I$N%f!<%6$,$3$N5!G=$r;H$&$3$H$,$G$-$k$+$r@)8B$9$k$3$H$,$G$-$^$9(B:

    + + + UserDir enabled
    + UserDir disabled root jro fish +
    + +

    $B>e$N@_Dj$O(B dissabled $BJ8$N%f!<%60J30$N$9$Y$F$N%f!<%6$K(B + $BBP$7$F(B UserDir $B$N5!G=$rM-8z$K$7$^$9!#F1MM$K$7$F!"0J2<$N$h$&$K(B + $B?tL>$N%f!<%60J30$KBP$7$F$3$N5!G=$rL58z$K$9$k$3$H$b$G$-$^$9(B:

    + + + UserDir disabled
    + UserDir enabled rbowen krietz +
    + +

    $BB>$NNc$O(B UserDir + $B$N@bL@$r;2>H$7$F$/$@$5$$!#(B

    + +
    + +
    + $B%f!<%6Kh$N(B CGI $B%G%#%l%/%H%j(B + +

    $B$=$l$>$l$N%f!<%6$K@lMQ$N(B cgi-bin $B%G%#%l%/%H%j$rM?$($k$?$a$K!"(B + Directory + $B$r;H$C$F%f!<%6$N%[!<%`%G%#%l%/%H%j$N;XDj$5$l$?NN0h$KBP$7$F(B CGI $B$rM-8z$K(B + $B$9$k$3$H$,$G$-$^$9!#(B

    + + + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +
    + +

    $B$=$7$F!"(BUserDir $B$,(B + public_html $B$K@_Dj$5$l$F$$$k$H2>Dj$9$k$H!"(B + $B$=$N%G%#%l%/%H%j$N(B CGI $B%W%m%0%i%`(B example.cgi + $B$O0J2<$NMM$K8F$S=P$5$l$k$3$H$,$G$-$^$9(B:

    + + + http://example.com/~rbowen/cgi-bin/example.cgi + + +
    + +
    + $B%f!<%6$K$h$k@_DjJQ99$r5v2D(B + +

    $B%f!<%6$KH`$i$N%&%'%V6u4V$G$N%5!<%P$N@_Dj$NJQ99$r5v2D$9$k>l9g!"(B + $B%f!<%6$O(B .htaccess $B%U%!%$%k$r;H$C$F@_Dj$rJQ99$9$kI,MW$,$"$j$^$9!#(B + AllowOverride $B$NCM$r(B + $B%f!<%6$,JQ99$9$k$3$H$r5v2D$7$?$$%G%#%l%/%F%#%V$KBP$7$F==J,$J$b$N$K(B + $B@_Dj$7$F$$$k$3$H$r3NG'$7$F$/$@$5$$!#$3$N5!G=$,$I$N$h$&$K$7$FF0:n$7$F$$$k$+(B + $B$N>\:Y$O(B .htaccess $B%A%e!<%H%j%"%k(B $B$rFI$s$G(B + $B$/$@$5$$!#(B

    + +
    + +
    diff --git a/trunk/docs/manual/howto/public_html.xml.ko b/trunk/docs/manual/howto/public_html.xml.ko new file mode 100644 index 0000000000..f0683f3f92 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.xml.ko @@ -0,0 +1,161 @@ + + + + + + + + +How-To / Tutorials + + »ç¿ëÀÚº° À¥µð·ºÅ丮 + + +

    ¿©·¯ »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼­ UserDir Áö½Ã¾î¸¦ »ç¿ëÇϸé + °¢ »ç¿ëÀÚ´Â ÀÚ½ÅÀÇ È¨µð·ºÅ丮 ¾È¿¡ À¥»çÀÌÆ®¸¦ ¸¸µé ¼ö ÀÖ´Ù. + URL http://example.com/~username/¿¡ Á¢±ÙÇϸé + »ç¿ëÀÚ "username"ÀÇ È¨µð·ºÅ丮¿¡¼­ UserDir Áö½Ã¾î·Î ÁöÁ¤ÇÑ + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆäÀÌÁö¸¦ °¡Á®¿À°Ô µÈ´Ù.

    + +
    + +URLÀ» ÆÄÀϽýºÅÛ¿¡ ´ëÀÀ + + + +
    + UserDir·Î ÆÄÀÏ°æ·Î ÁöÁ¤Çϱâ + +

    UserDir + Áö½Ã¾î´Â »ç¿ëÀÚº° ÆäÀÌÁö¸¦ °¡Á®¿Ã µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ + Áö½Ã¾îÀÇ »ç¿ë¹ýÀº ¿©·¯°¡Áö´Ù.

    + +

    ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾Ê´Â °æ·Î¸¦ ÁöÁ¤ÇÏ¸é °¢ »ç¿ëÀÚÀÇ + Ȩµð·ºÅ丮¿¡ »ó´ëÀûÀÎ µð·ºÅ丮 °æ·Î·Î ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¾Æ·¡ ¼³Á¤ÀÇ °æ¿ì:

    + + + UserDir public_html + + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /home/rbowen/public_html/file.htmlÀ» + ¶æÇÑ´Ù.

    + +

    ½½·¡½¬·Î ½ÃÀÛÇÏ´Â °æ·Î¸¦ ÁöÁ¤Çϸé ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ + »ç¿ëÀÚ¸íÀ» ´õÇÑ µð·ºÅ丮 °æ·Î¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾Æ·¡ + ¼³Á¤ÀÇ °æ¿ì:

    + + + UserDir /var/html + + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /var/html/rbowen/file.htmlÀ» ¶æÇÑ´Ù.

    + +

    º°Ç¥ (*)¸¦ Æ÷ÇÔÇÑ °æ·Î¸¦ ÁöÁ¤ÇÏ¸é º°Ç¥¸¦ »ç¿ëÀÚ¸íÀ¸·Î + ´ëüÇÑ °æ·Î¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾Æ·¡ ¼³Á¤ÀÇ °æ¿ì:

    + + + UserDir /var/www/*/docs + + +

    URL http://example.com/~rbowen/file.htmlÀº + ÆÄÀÏ °æ·Î /var/www/rbowen/docs/file.htmlÀ» + ¶æÇÑ´Ù.

    + +
    + +
    + ±â´ÉÀ» ÀÌ¿ëÇÒ »ç¿ëÀÚ Á¦ÇÑÇϱâ + +

    UserDir ¹®¼­¿¡ ÀÖ´Â ¹®¹ýÀ» »ç¿ëÇÏ¿© »ç¿ëÀÚº° À¥µð·ºÅ丮 + ±â´ÉÀ» ÀÌ¿ëÇÒ ¼ö ÀÖ´Â »ç¿ëÀÚ¸¦ Á¦ÇÑÇÒ ¼ö ÀÖ´Ù:

    + + + UserDir enabled
    + UserDir disabled root jro fish +
    + +

    À§ ¼³Á¤Àº disabled ¹®Àå¿¡ ¿­°ÅÇÑ »ç¶÷À» + Á¦¿ÜÇÏ°í ¸ðµç »ç¿ëÀÚ¿¡°Ô À¥µð·ºÅ丮 ±â´ÉÀ» Çã¶ôÇÑ´Ù. ¶Ç, + ´ÙÀ½°ú °°ÀÌ ¸î¸î »ç¿ëÀÚ¸¦ Á¦¿ÜÇÏ°í ±â´ÉÀ» Çã¶ôÇÏÁö ¾ÊÀ» + ¼öµµ ÀÖ´Ù:

    + + + UserDir disabled
    + UserDir enabled rbowen krietz +
    + +

    UserDir + ¹®¼­¿¡ ÀÖ´Â ´Ù¸¥ ¿¹µéµµ Âü°íÇ϶ó.

    + +
    + +
    + °¢ »ç¿ëÀÚº° cgi µð·ºÅ丮 ÁöÁ¤Çϱâ + +

    »ç¿ëÀÚ¸¶´Ù cgi-bin µð·ºÅ丮¸¦ ºÎ¿©ÇÏ·Á¸é Directory Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© »ç¿ëÀÚ È¨µð·ºÅ丮ÀÇ Æ¯Á¤ ÇÏÀ§µð·ºÅ丮¸¦ cgi °¡´ÉÇÏ°Ô + ¸¸µç´Ù.

    + + + <Directory /home/*/public_html/cgi-bin/>
    + Options ExecCGI
    + SetHandler cgi-script
    + </Directory> +
    + +

    UserDirÀÌ public_htmlÀ̶ó°í + °¡Á¤Çϸé, ´ÙÀ½°ú °°ÀÌ ±× ¾È¿¡ ÀÖ´Â cgi ÇÁ·Î±×·¥ + example.cgi¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + + + http://example.com/~rbowen/cgi-bin/example.cgi + + +
    + +
    + »ç¿ëÀÚ°¡ ¼³Á¤À» º¯°æÇÒ ¼ö ÀÖµµ·Ï ¸¸µé±â + +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ À¥°ø°£¿¡ ´ëÇÑ À¥¼­¹ö ¼³Á¤À» ¼öÁ¤ÇÏ·Á¸é, + .htaccess ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. AllowOverride¸¦ »ç¿ëÀÚ°¡ ¼öÁ¤ÇÒ + ¼ö ÀÖ´Â Áö½Ã¾î¿¡ ÀûÇÕÇÑ °ªÀ¸·Î ¼³Á¤Ç϶ó. ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö¿¡ + ´ëÇÑ ÀÚ¼¼ÇÑ Á´º¸´Â .htaccess + ÅõÅ丮¾óÀ» Âü°íÇ϶ó.

    + +
    + +
    diff --git a/trunk/docs/manual/howto/public_html.xml.meta b/trunk/docs/manual/howto/public_html.xml.meta new file mode 100644 index 0000000000..96559002a1 --- /dev/null +++ b/trunk/docs/manual/howto/public_html.xml.meta @@ -0,0 +1,13 @@ + + + + public_html + /howto/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/howto/ssi.html b/trunk/docs/manual/howto/ssi.html new file mode 100644 index 0000000000..6142aec8e8 --- /dev/null +++ b/trunk/docs/manual/howto/ssi.html @@ -0,0 +1,11 @@ +URI: ssi.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: ssi.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: ssi.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/howto/ssi.html.en b/trunk/docs/manual/howto/ssi.html.en new file mode 100644 index 0000000000..b6f21eae7a --- /dev/null +++ b/trunk/docs/manual/howto/ssi.html.en @@ -0,0 +1,486 @@ + + + +Apache Tutorial: Introduction to Server Side Includes - Apache HTTP Server + + + + + +
    <-
    +

    Apache Tutorial: Introduction to Server Side Includes

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    Server-side includes provide a means to add dynamic content to +existing HTML documents.

    +
    + +
    top
    +
    +

    Introduction

    + + +

    This article deals with Server Side Includes, usually called + simply SSI. In this article, I'll talk about configuring your + server to permit SSI, and introduce some basic SSI techniques + for adding dynamic content to your existing HTML pages.

    + +

    In the latter part of the article, we'll talk about some of + the somewhat more advanced things that can be done with SSI, + such as conditional statements in your SSI directives.

    + +
    top
    +
    +

    What are SSI?

    + +

    SSI (Server Side Includes) are directives that are placed in + HTML pages, and evaluated on the server while the pages are + being served. They let you add dynamically generated content to + an existing HTML page, without having to serve the entire page + via a CGI program, or other dynamic technology.

    + +

    The decision of when to use SSI, and when to have your page + entirely generated by some program, is usually a matter of how + much of the page is static, and how much needs to be + recalculated every time the page is served. SSI is a great way + to add small pieces of information, such as the current time. + But if a majority of your page is being generated at the time + that it is served, you need to look for some other + solution.

    +
    top
    +
    +

    Configuring your server to permit SSI

    + + +

    To permit SSI on your server, you must have the following + directive either in your httpd.conf file, or in a + .htaccess file:

    +

    + Options +Includes +

    + +

    This tells Apache that you want to permit files to be parsed + for SSI directives. Note that most configurations contain + multiple Options directives + that can override each other. You will probably need to apply the + Options to the specific directory where you want SSI + enabled in order to assure that it gets evaluated last.

    + +

    Not just any file is parsed for SSI directives. You have to + tell Apache which files should be parsed. There are two ways to + do this. You can tell Apache to parse any file with a + particular file extension, such as .shtml, with + the following directives:

    +

    + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +

    + +

    One disadvantage to this approach is that if you wanted to + add SSI directives to an existing page, you would have to + change the name of that page, and all links to that page, in + order to give it a .shtml extension, so that those + directives would be executed.

    + +

    The other method is to use the XBitHack directive:

    +

    + XBitHack on +

    + +

    XBitHack + tells Apache to parse files for SSI + directives if they have the execute bit set. So, to add SSI + directives to an existing page, rather than having to change + the file name, you would just need to make the file executable + using chmod.

    +

    + chmod +x pagename.html +

    + +

    A brief comment about what not to do. You'll occasionally + see people recommending that you just tell Apache to parse all + .html files for SSI, so that you don't have to + mess with .shtml file names. These folks have + perhaps not heard about XBitHack. The thing to + keep in mind is that, by doing this, you're requiring that + Apache read through every single file that it sends out to + clients, even if they don't contain any SSI directives. This + can slow things down quite a bit, and is not a good idea.

    + +

    Of course, on Windows, there is no such thing as an execute + bit to set, so that limits your options a little.

    + +

    In its default configuration, Apache does not send the last + modified date or content length HTTP headers on SSI pages, + because these values are difficult to calculate for dynamic + content. This can prevent your document from being cached, and + result in slower perceived client performance. There are two + ways to solve this:

    + +
      +
    1. Use the XBitHack Full configuration. This + tells Apache to determine the last modified date by looking + only at the date of the originally requested file, ignoring + the modification date of any included files.
    2. + +
    3. Use the directives provided by + mod_expires to set an explicit expiration + time on your files, thereby letting browsers and proxies + know that it is acceptable to cache them.
    4. +
    +
    top
    +
    +

    Basic SSI directives

    + +

    SSI directives have the following syntax:

    +

    + <!--#element attribute=value attribute=value ... --> +

    + +

    It is formatted like an HTML comment, so if you don't have + SSI correctly enabled, the browser will ignore it, but it will + still be visible in the HTML source. If you have SSI correctly + configured, the directive will be replaced with its + results.

    + +

    The element can be one of a number of things, and we'll talk + some more about most of these in the next installment of this + series. For now, here are some examples of what you can do with + SSI

    + +

    Today's date

    + +

    + <!--#echo var="DATE_LOCAL" --> +

    + +

    The echo element just spits out the value of a + variable. There are a number of standard variables, which + include the whole set of environment variables that are + available to CGI programs. Also, you can define your own + variables with the set element.

    + +

    If you don't like the format in which the date gets printed, + you can use the config element, with a + timefmt attribute, to modify that formatting.

    + +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +

    + + +

    Modification date of the file

    + +

    + This document last modified <!--#flastmod file="index.html" --> +

    + +

    This element is also subject to timefmt format + configurations.

    + + +

    Including the results of a CGI program

    + +

    This is one of the more common uses of SSI - to output the + results of a CGI program, such as everybody's favorite, a ``hit + counter.''

    + +

    + <!--#include virtual="/cgi-bin/counter.pl" --> +

    + + +
    top
    +
    +

    Additional examples

    + + +

    Following are some specific examples of things you can do in + your HTML documents with SSI.

    + +

    When was this document +modified?

    + +

    Earlier, we mentioned that you could use SSI to inform the + user when the document was most recently modified. However, the + actual method for doing that was left somewhat in question. The + following code, placed in your HTML document, will put such a + time stamp on your page. Of course, you will have to have SSI + correctly enabled, as discussed above.

    +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + This file last modified <!--#flastmod file="ssi.shtml" --> +

    + +

    Of course, you will need to replace the + ssi.shtml with the actual name of the file that + you're referring to. This can be inconvenient if you're just + looking for a generic piece of code that you can paste into any + file, so you probably want to use the + LAST_MODIFIED variable instead:

    +

    + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +

    + +

    For more details on the timefmt format, go to + your favorite search site and look for strftime. The + syntax is the same.

    + + +

    Including a standard footer

    + + +

    If you are managing any site that is more than a few pages, + you may find that making changes to all those pages can be a + real pain, particularly if you are trying to maintain some kind + of standard look across all those pages.

    + +

    Using an include file for a header and/or a footer can + reduce the burden of these updates. You just have to make one + footer file, and then include it into each page with the + include SSI command. The include + element can determine what file to include with either the + file attribute, or the virtual + attribute. The file attribute is a file path, + relative to the current directory. That means that it + cannot be an absolute file path (starting with /), nor can it + contain ../ as part of that path. The virtual + attribute is probably more useful, and should specify a URL + relative to the document being served. It can start with a /, + but must be on the same server as the file being served.

    +

    + <!--#include virtual="/footer.html" --> +

    + +

    I'll frequently combine the last two things, putting a + LAST_MODIFIED directive inside a footer file to be + included. SSI directives can be contained in the included file, + and includes can be nested - that is, the included file can + include another file, and so on.

    + + +
    top
    +
    +

    What else can I config?

    + + +

    In addition to being able to config the time + format, you can also config two other things.

    + +

    Usually, when something goes wrong with your SSI directive, + you get the message

    +

    + [an error occurred while processing this directive] +

    + +

    If you want to change that message to something else, you + can do so with the errmsg attribute to the + config element:

    +

    + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> +

    + +

    Hopefully, end users will never see this message, because + you will have resolved all the problems with your SSI + directives before your site goes live. (Right?)

    + +

    And you can config the format in which file + sizes are returned with the sizefmt attribute. You + can specify bytes for a full count in bytes, or + abbrev for an abbreviated number in Kb or Mb, as + appropriate.

    +
    top
    +
    +

    Executing commands

    + + +

    I expect that I'll have an article some time in the coming + months about using SSI with small CGI programs. For now, here's + something else that you can do with the exec + element. You can actually have SSI execute a command using the + shell (/bin/sh, to be precise - or the DOS shell, + if you're on Win32). The following, for example, will give you + a directory listing.

    +

    + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +

    + +

    or, on Windows

    +

    + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +

    + +

    You might notice some strange formatting with this directive + on Windows, because the output from dir contains + the string ``<dir>'' in it, which confuses + browsers.

    + +

    Note that this feature is exceedingly dangerous, as it will + execute whatever code happens to be embedded in the + exec tag. If you have any situation where users + can edit content on your web pages, such as with a + ``guestbook'', for example, make sure that you have this + feature disabled. You can allow SSI, but not the + exec feature, with the IncludesNOEXEC + argument to the Options directive.

    +
    top
    +
    +

    Advanced SSI techniques

    + + +

    In addition to spitting out content, Apache SSI gives you + the option of setting variables, and using those variables in + comparisons and conditionals.

    + +

    Caveat

    + +

    Most of the features discussed in this article are only + available to you if you are running Apache 1.2 or later. Of + course, if you are not running Apache 1.2 or later, you need to + upgrade immediately, if not sooner. Go on. Do it now. We'll + wait.

    + + +

    Setting variables

    + +

    Using the set directive, you can set variables + for later use. We'll need this later in the discussion, so + we'll talk about it here. The syntax of this is as follows:

    +

    + <!--#set var="name" value="Rich" --> +

    + +

    In addition to merely setting values literally like that, you + can use any other variable, including environment variables or the variables + discussed above (like LAST_MODIFIED, for example) to + give values to your variables. You will specify that something is + a variable, rather than a literal string, by using the dollar sign + ($) before the name of the variable.

    + +

    <!--#set var="modified" value="$LAST_MODIFIED" --> +

    + +

    To put a literal dollar sign into the value of your + variable, you need to escape the dollar sign with a + backslash.

    +

    + <!--#set var="cost" value="\$100" --> +

    + +

    Finally, if you want to put a variable in the midst of a + longer string, and there's a chance that the name of the + variable will run up against some other characters, and thus be + confused with those characters, you can place the name of the + variable in braces, to remove this confusion. (It's hard to + come up with a really good example of this, but hopefully + you'll get the point.)

    +

    + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> +

    + + +

    Conditional expressions

    + + +

    Now that we have variables, and are able to set and compare + their values, we can use them to express conditionals. This + lets SSI be a tiny programming language of sorts. + mod_include provides an if, + elif, else, endif + structure for building conditional statements. This allows you + to effectively generate multiple logical pages out of one + actual page.

    + +

    The structure of this conditional construct is:

    +

    + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +

    + +

    A test_condition can be any sort of logical + comparison - either comparing values to one another, or testing + the ``truth'' of a particular value. (A given string is true if + it is nonempty.) For a full list of the comparison operators + available to you, see the mod_include + documentation. Here are some examples of how one might use this + construct.

    + +

    In your configuration file, you could put the following + line:

    +

    + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +

    + +

    This will set environment variables ``Mac'' and + ``InternetExplorer'' to true, if the client is running Internet + Explorer on a Macintosh.

    + +

    Then, in your SSI-enabled document, you might do the + following:

    +

    + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + Apologetic text goes here
    + <!--#else -->
    + Cool JavaScript code goes here
    + <!--#endif --> +

    + +

    Not that I have anything against IE on Macs - I just + struggled for a few hours last week trying to get some + JavaScript working on IE on a Mac, when it was working + everywhere else. The above was the interim workaround.

    + +

    Any other variable (either ones that you define, or normal + environment variables) can be used in conditional statements. + With Apache's ability to set environment variables with the + SetEnvIf directives, and other related directives, + this functionality can let you do some pretty involved dynamic + stuff without ever resorting to CGI.

    + +
    top
    +
    +

    Conclusion

    + +

    SSI is certainly not a replacement for CGI, or other + technologies used for generating dynamic web pages. But it is a + great way to add small amounts of dynamic content to pages, + without doing a lot of extra work.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/ssi.html.ja.euc-jp b/trunk/docs/manual/howto/ssi.html.ja.euc-jp new file mode 100644 index 0000000000..88f2f6a63e --- /dev/null +++ b/trunk/docs/manual/howto/ssi.html.ja.euc-jp @@ -0,0 +1,481 @@ + + + +Apache ¥Á¥å¡¼¥È¥ê¥¢¥ë: Server Side Includes ÆþÌç - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¥Á¥å¡¼¥È¥ê¥¢¥ë: Server Side Includes ÆþÌç

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¥µ¡¼¥Ð¥µ¥¤¥É¥¤¥ó¥¯¥ë¡¼¥É¤Ë¤è¤Ã¤Æ¡¢´û¸¤Î HTML +¥É¥­¥å¥á¥ó¥È¤ËưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¤Ï¤¸¤á¤Ë

    + + +

    ¤³¤Îµ­»ö¤Ï¡¢Ä̾ï¤Ïñ¤Ë SSI ¤È¸Æ¤Ð¤ì¤ë Server Side Includes + ¤ò°·¤¤¤Þ¤¹¡£¤³¤Îµ­»ö¤Ë¤ª¤¤¤Æ¤Ï¡¢¥µ¡¼¥Ð¤Ç¤Î SSI ¤òµö²Ä¤¹¤ë¤¿¤á¤ÎÀßÄê¤È¡¢ + ¸½ºß¤Î HTML ¥Ú¡¼¥¸¤ËưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤ò²Ã¤¨¤ë¤¿¤á¤Î¤¤¤¯¤Ä¤«¤Î´ðËÜŪ¤Ê + SSI µ»½Ñ¤ò¾Ò²ð¤·¤Þ¤¹¡£

    + +

    µ­»ö¤Î¸åȾ¤Ç¤Ï¡¢SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç SSI + ¤È¶¦¤Ë¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¾ò·ïʸ¤Î¤è¤¦¤Ê + ´öʬ¹âÅ٤ʻöÊÁ¤Ë¤Ä¤¤¤Æ½Ò¤Ù¤Æ¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    SSI ¤È¤Ï ?

    + +

    SSI (Server Side Includes) ¤Ï¡¢HTML + ¥Ú¡¼¥¸Ãæ¤ËÇÛÃÖ¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤¢¤ê¡¢ + ¥µ¡¼¥Ð¤Ç¥Ú¡¼¥¸¤òÄ󶡤¹¤ë»þ¤Ëɾ²Á¤µ¤ì¤Þ¤¹¡£SSI ¤Ï¡¢CGI + ¥×¥í¥°¥é¥à¤ä¤½¤Î¾¤ÎưŪ¤Êµ»½Ñ¤ÇÁ´¤Æ¤Î¥Ú¡¼¥¸¤òÄ󶡤»¤º¤Ë¡¢ + ưŪ¤ËÀ¸À®¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥Ä¤ò¸½ºß¤Î HTML ¥Ú¡¼¥¸¤Ë²Ã¤¨¤Þ¤¹¡£

    + +

    ¤É¤¦¤¤¤¦¾ì¹ç¤Ë SSI ¤ò»È¤¤¡¢¤É¤¦¤¤¤¦¾ì¹ç¤Ë¥×¥í¥°¥é¥à¤Ç + ¥Ú¡¼¥¸¤ò´°Á´¤ËÀ¸À®¤¹¤ë¤«¤Ï¡¢¥Ú¡¼¥¸¤Î¤¦¤Á¤É¤ÎÄøÅÙ¤¬ÀÅŪ¤Ç¤¢¤ê¡¢ + ¥Ú¡¼¥¸¤¬Ä󶡤µ¤ì¤ë¤¿¤Ó¤ËºÆ·×»»¤¹¤ëɬÍפ¬¤É¤ÎÄøÅÙ¤¢¤ë¤«¤ÇÄ̾ï¤Ï·èÄꤷ¤Þ¤¹¡£ + SSI ¤Ï¸½ºß»þ¹ï¤Î¤è¤¦¤Ê¾®¤µ¤¤¾ðÊó¤ò²Ã¤¨¤ë¤Ë¤Ï¤¦¤Ã¤Æ¤Ä¤±¤ÎÊýË¡¤Ç¤¹¡£ + ¤·¤«¤·¡¢¤½¤Î¥Ú¡¼¥¸¤Î¤Û¤È¤ó¤É¤ÎÉôʬ¤¬Ä󶡻þ¤ËÀ¸À®¤µ¤ì¤ë¾ì¹ç¤Ï¡¢ + ¾¤ÎÊýË¡¤òõ¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    SSI ¤òµö²Ä¤¹¤ë¤¿¤á¤Î¥µ¡¼¥Ð¤ÎÀßÄê

    + + +

    ¥µ¡¼¥Ð¤Ç SSI ¤òµö²Ä¤¹¤ë¤Ë¤Ï¡¢httpd.conf + ¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï .htaccess + ¥Õ¥¡¥¤¥ë¤Ë¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹:

    +

    + Options +Includes +

    + +

    ¤³¤Î»ØÄê¤Ï¡¢¥Õ¥¡¥¤¥ë¤ò SSI + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç²òÀϤµ¤»¤ë¤³¤È¤òµö²Ä¤¹¤ë¤È¤¤¤¦¤³¤È¤ò Apache + ¤ËÅÁ¤¨¤Þ¤¹¡£¤Û¤È¤ó¤É¤ÎÀßÄê¤Ç¤Ï¤ª¸ß¤¤¤ò¾å½ñ¤­¤Ç¤­¤ë¡¢Ê£¿ô¤Î + Options ¤¬¤¢¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤ª¤½¤é¤¯¡¢ÀßÄ꤬ºÇ¸å¤Ëɾ²Á¤µ¤ì¤ë¤³¤È¤ò + Êݾڤµ¤ì¤ë¤¿¤á¤Ë¡¢SSI ¤ò»ÈÍѤ·¤¿¤¤¥Ç¥£¥ì¥¯¥È¥ê¤Ë Options + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬÍѤ¹¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£

    + +

    Á´¤Æ¤Î¥Õ¥¡¥¤¥ë¤¬ SSI + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç²òÀϤµ¤ì¤ë¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤É¤Î¥Õ¥¡¥¤¥ë¤¬²òÀϤµ¤ì¤ë¤«¤ò Apache ¤ËÅÁ¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤ò¹Ô¤Ê¤¦¤Ë¤ÏÆó¤ÄÊýË¡¤¬¤¢¤ê¤Þ¤¹¡£ + ¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤³¤È¤Ç¡¢Î㤨¤Ð .shtml + ¤Î¤è¤¦¤ÊÆÃÊ̤ʥե¡¥¤¥ë³ÈÄ¥»Ò¤ò»ý¤Ä¥Õ¥¡¥¤¥ë¤ò²òÀϤ¹¤ë¤è¤¦ + Apache ¤ËÅÁ¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    +

    + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +

    + +

    ¤³¤ÎÊýË¡¤Î·çÅÀ¤Ï¡¢¤â¤·¸½ºß¤Î¥Ú¡¼¥¸¤Ë SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò²Ã¤¨¤¿¤¤¾ì¹ç¡¢ + ¤½¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¼Â¹Ô¤µ¤ì¤ë¤è¤¦¤Ë + .shtml ³ÈÄ¥»Ò¤Ë¤¹¤ë¤¿¤á¡¢¤½¤Î¥Ú¡¼¥¸¤Î̾Á°¤È¡¢ + ¤½¤Î¥Ú¡¼¥¸¤Ø¤ÎÁ´¤Æ¤Î¥ê¥ó¥¯¤òÊѹ¹¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤Ç¤¹¡£

    + +

    ¤â¤¦°ì¤Ä¤ÎÊýË¡¤Ï¡¢XBitHack + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¤¹:

    +

    + XBitHack on +

    + +

    XBitHack + ¤Ï¡¢¥Õ¥¡¥¤¥ë¤Î¼Â¹Ô¥Ó¥Ã¥È¤¬Î©¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢ + SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê²òÀϤ¹¤ë¤³¤È¤ò Apache ¤ËÅÁ¤¨¤Þ¤¹¡£ + ½¾¤Ã¤Æ¡¢SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¸½ºß¤Î¥Ú¡¼¥¸¤Ë²Ã¤¨¤ë¤¿¤á¤Ë¤Ï¡¢ + ¥Õ¥¡¥¤¥ë̾¤òÊѹ¹¤·¤Ê¤¯¤Æ¤â¤è¤¯¡¢Ã±¤Ë chmod + ¤ò»ÈÍѤ·¤Æ¥Õ¥¡¥¤¥ë¤ò¼Â¹Ô²Äǽ¤Ë¤¹¤ë¤À¤±¤ÇºÑ¤ß¤Þ¤¹¡£

    +

    + chmod +x pagename.html +

    + +

    ¹Ô¤Ê¤¦¤Ù¤­¤Ç¤Ï¤Ê¤¤¤³¤È¤Ë´Ø¤¹¤ëû¤¤¥³¥á¥ó¥È¡£»þ¡¹Ã¯¤«¤¬¡¢Á´¤Æ¤Î + .html ¥Õ¥¡¥¤¥ë¤ò SSI ¤Ç²òÀϤ¹¤ë¤è¤¦ Apache ¤ËÅÁ¤¨¤ì¤Ð¡¢ + ¤ï¤¶¤ï¤¶ .shtml ¤È¤¤¤¦¥Õ¥¡¥¤¥ë̾¤Ë¤¹¤ëɬÍפ¬¤Ê¤¤¤È¤¤¤Ã¤Æ + Á¦¤á¤ë¤Î¤ò¸«¤ë¤³¤È¤Ç¤·¤ç¤¦¡£¤³¤¦¤¤¤¦¿Í¤¿¤Á¤Ï¡¢¤ª¤½¤é¤¯ + XBitHack + ¤Ë¤Ä¤¤¤Æʹ¤¤¤¿¤³¤È¤¬¤Ê¤¤¤Î¤Ç¤·¤ç¤¦¡£ + ¤³¤ÎÊýË¡¤Ë¤Ä¤¤¤ÆÃí°Õ¤¹¤ë¤³¤È¤Ï¡¢¤¿¤È¤¨ SSI + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÁ´¤¯´Þ¤Þ¤Ê¤¤¾ì¹ç¤Ç¤â¡¢Apache ¤¬¥¯¥é¥¤¥¢¥ó¥È¤Ë + Á÷¤ëÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤òºÇ¸å¤Þ¤ÇÆɤ߹þ¤Þ¤»¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ÎÊýË¡¤Ï¤«¤Ê¤ê½èÍý¤òÃÙ¤¯¤¹¤ë¤â¤Î¤Ç¤¢¤ê¡¢Îɤ¯¤Ê¤¤¥¢¥¤¥Ç¥¢¤Ç¤¹¡£

    + +

    ¤â¤Á¤í¤ó¡¢Windows ¤Ç¤Ï¤½¤Î¤è¤¦¤Ê¼Â¹Ô¥Ó¥Ã¥È¤ò¥»¥Ã¥È + ¤¹¤ë¤è¤¦¤Ê¤â¤Î¤Ï¤¢¤ê¤Þ¤»¤ó¤Î¤Ç¥ª¥×¥·¥ç¥ó¤¬¾¯¤·À©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤Ç¤Ï¡¢Apache ¤Ï SSI ¥Ú¡¼¥¸¤Ë¤Ä¤¤¤ÆºÇ½ªÊѹ¹»þ¹ï¤ä + ¥³¥ó¥Æ¥ó¥Ä¤ÎŤµ¤ò HTTP ¥Ø¥Ã¥À¤ËÁ÷¤ê¤Þ¤»¤ó¡£ + ưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤Ç¤¢¤ë¤¿¤á¡¢¤½¤ì¤é¤ÎÃͤò·×»»¤¹¤ë¤Î¤¬Æñ¤·¤¤¤«¤é¤Ç¤¹¡£ + ¤³¤Î¤¿¤á¥É¥­¥å¥á¥ó¥È¤¬¥­¥ã¥Ã¥·¥å¤µ¤ì¤Ê¤¯¤Ê¤ê¡¢ + ·ë²Ì¤È¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤ÎÀ­Ç½¤¬ÃÙ¤¯¤Ê¤Ã¤¿¤è¤¦¤Ë´¶¤¸¤µ¤»¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤ò²ò·è¤¹¤ëÊýË¡¤¬Æó¤Ä¤¢¤ê¤Þ¤¹:

    + +
      +
    1. XBitHack Full ÀßÄê¤ò»ÈÍѤ¹¤ë¡£ + ¤³¤ÎÀßÄê¤Ë¤è¤ê¡¢¤â¤È¤â¤ÈÍ׵ᤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î»þ¹ï¤ò»²¾È¤·¡¢ + Æɤ߹þ¤Þ¤ì¤ë¥Õ¥¡¥¤¥ë¤ÎÊѹ¹»þ¹ï¤ò̵»ë¤·¤ÆºÇ½ªÊѹ¹»þ¹ï¤ò·èÄꤹ¤ë¤è¤¦ + Apache ¤ËÅÁ¤¨¤Þ¤¹¡£
    2. + +
    3. mod_expires + ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ + ¥Õ¥¡¥¤¥ë¤¬Ìµ¸ú¤Ë¤Ê¤ë»þ¹ï¤òÌÀ¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢ + ¥Ö¥é¥¦¥¶¤È¥×¥í¥­¥·¤Ë¥­¥ã¥Ã¥·¥å¤¬Í­¸ú¤Ç¤¢¤ë¤³¤È¤òÄÌÃΤ·¤Þ¤¹¡£
    4. +
    +
    top
    +
    +

    ´ðËÜŪ¤Ê SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï°Ê²¼¤Îʸˡ¤Çµ­½Ò¤·¤Þ¤¹:

    +

    + <!--#element attribute=value attribute=value ... --> +

    + +

    HTML ¤Î¥³¥á¥ó¥È¤Î¤è¤¦¤Ê½ñ¼°¤ò¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¤â¤· SSI + ¤òÀµ¤·¤¯Æ°ºî²Äǽ¤Ë¤·¤Ê¤±¤ì¤Ð¡¢¥Ö¥é¥¦¥¶¤Ï¤½¤ì¤ò̵»ë¤¹¤ë¤Ç¤·¤ç¤¦¡£ + ¤·¤«¤·¡¢HTML ¥½¡¼¥¹Ãæ¤Ç¤Ï¸«¤¨¤Þ¤¹¡£¤â¤· SSI ¤òÀµ¤·¤¯ÀßÄꤷ¤¿¤Ê¤é¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤Î·ë²Ì¤ÈÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£

    + +

    element ¤Ï¤¿¤¯¤µ¤ó¤¢¤ë¤â¤Î¤«¤é°ì¤Ä»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + »ØÄê¤Ç¤­¤ë¤â¤Î¤ÎÂç¿¿ô¤Ë¤Ä¤¤¤Æ¤Ï¡¢¼¡²ó¤â¤¦¾¯¤·¾Ü¤·¤¯ÀâÌÀ¤·¤Þ¤¹¡£ + ¤³¤³¤Ç¤Ï¡¢SSI ¤Ç¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤ëÎã¤ò¤¤¤¯¤Ä¤«¼¨¤·¤Þ¤¹¡£

    + +

    º£Æü¤ÎÆüÉÕ

    + +

    + <!--#echo var="DATE_LOCAL" --> +

    + +

    echo Í×ÁǤÏñ¤ËÊÑ¿ô¤ÎÃͤò½ÐÎϤ·¤Þ¤¹¡£ + CGI ¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê´Ä¶­ÊÑ¿ô¤ÎÁ´¤Æ¤Î + ¥»¥Ã¥È¤ò´Þ¤à¿¤¯¤Îɸ½àÊÑ¿ô¤¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢set + Í×ÁǤòÍѤ¤¤ë¤³¤È¤Ç¡¢Æȼ«¤ÎÊÑ¿ô¤òÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    + +

    ½ÐÎϤµ¤ì¤ëÆüÉդνñ¼°¤¬¹¥¤­¤Ç¤Ï¤Ê¤¤¾ì¹ç¡¢¤½¤Î½ñ¼°¤ò½¤Àµ¤¹¤ë¤¿¤á¤Ë¡¢ + config Í×ÁÇ¤Ë timefmt + °À­¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +

    + + +

    ¥Õ¥¡¥¤¥ë¤ÎÊѹ¹Æü

    + +

    + This document last modified <!--#flastmod file="index.html" --> +

    + +

    ¤³¤ÎÍ×ÁǤâ timefmt + ¥Õ¥©¡¼¥Þ¥Ã¥È¤ÎÀßÄê¤Ë½¾¤¤¤Þ¤¹¡£

    + + +

    CGI ¥×¥í¥°¥é¥à¤Î·ë²Ì¤ò¼è¤ê¹þ¤à

    + +

    ¤³¤ì¤Ï¡¢Á´¤Æ¤Î¿Í¤Î¤ªµ¤¤ËÆþ¤ê¤Ç¤¢¤ë ``¥Ò¥Ã¥È¥«¥¦¥ó¥¿'' ¤Î¤è¤¦¤Ê + CGI ¥×¥í¥°¥é¥à¤Î·ë²Ì¤ò½ÐÎϤ¹¤ë SSI + ¤Î¤è¤ê°ìÈÌŪ¤Ê»ÈÍѤΤ¦¤Á¤Î°ì¤Ä¤Ç¤¹¡£

    + +

    + <!--#include virtual="/cgi-bin/counter.pl" --> +

    + + +
    top
    +
    +

    ÄɲäÎÎã

    + + +

    °Ê²¼¤Ï¡¢SSI ¤ò»ÈÍѤ·¤Æ HTML + ¥É¥­¥å¥á¥ó¥È¤Ë¤ª¤¤¤Æ¤Ç¤­¤ë¤³¤È¤Î¤¤¤¯¤Ä¤«¤ÎÆÃÊ̤ÊÎã¤Ç¤¹¡£

    + +

    ¤¤¤Ä¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ï½¤Àµ¤µ¤ì¤¿¤Î¤« +?

    + +

    Àè¤Ë¡¢¥É¥­¥å¥á¥ó¥È¤¬ºÇ¸å¤ËÊѹ¹¤µ¤ì¤¿¤Î¤Ï¤¤¤Ä¤«¤ò + ¥æ¡¼¥¶¤ËÄÌÃΤ¹¤ë¤¿¤á¤Ë SSI ¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤³¤È¤ò½Ò¤Ù¤Þ¤·¤¿¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢¼ÂºÝ¤ÎÊýË¡¤Ï¡¢¤¤¤¯¤Ö¤óÌäÂê¤Î¤Þ¤Þ¤Ë¤·¤Æ¤ª¤­¤Þ¤·¤¿¡£ + HTML ¥É¥­¥å¥á¥ó¥È¤ËÇÛÃÖ¤µ¤ì¤¿¼¡¤Î¥³¡¼¥É¤Ï¡¢¥Ú¡¼¥¸¤Ë¤½¤Î¤è¤¦¤Ê + ¥¿¥¤¥à¥¹¥¿¥ó¥×¤òÆþ¤ì¤ë¤Ç¤·¤ç¤¦¡£¤â¤Á¤í¤ó¡¢¾å½Ò¤Î¤è¤¦¤Ë¡¢ + SSI ¤òÀµ¤·¤¯Æ°ºî²Äǽ¤Ë¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + This file last modified <!--#flastmod file="ssi.shtml" --> +

    + +

    ¤â¤Á¤í¤ó¡¢ssi.shtml + ¤ÎÉôʬ¤ò¼ÂºÝ¤ÎÅö³º¥Õ¥¡¥¤¥ë̾¤ÈÃÖ¤­´¹¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤â¤·¡¢¤¢¤é¤æ¤ë¥Õ¥¡¥¤¥ë¤ËÄ¥¤ë¤³¤È¤¬¤Ç¤­¤ë°ìÈÌŪ¤Ê¥³¡¼¥É¤òõ¤·¤Æ¤¤¤ë¤Ê¤é¡¢ + ¤³¤ì¤ÏÉÔÊؤǤ¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤ª¤½¤é¤¯¤½¤Î¾ì¹ç¤Ï¡¢ + ¤½¤¦¤¹¤ëÂå¤ï¤ê¤ËÊÑ¿ô LAST_MODIFIED + ¤ò»ÈÍѤ·¤¿¤¤¤È¹Í¤¨¤ë¤Ç¤·¤ç¤¦:

    +

    + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +

    + +

    timefmt + ½ñ¼°¤Ë¤Ä¤¤¤Æ¤Î¤è¤ê¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢¤ª¹¥¤ß¤Î¸¡º÷¥µ¥¤¥È¤Ë¹Ô¤­¡¢ + strftime ¤Ç¸¡º÷¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£Ê¸Ë¡¤ÏƱ¤¸¤Ç¤¹¡£

    + + +

    ɸ½à¤Î¥Õ¥Ã¥¿¤òÁÞÆþ¤¹¤ë

    + + +

    ¤â¤·¿ô¥Ú¡¼¥¸¤òĶ¤¨¤ë¥Ú¡¼¥¸¤ò»ý¤Ä¥µ¥¤¥È¤ò´ÉÍý¤·¤Æ¤¤¤ë¤Ê¤é¤Ð¡¢ + Á´¥Ú¡¼¥¸¤ËÂФ·¤ÆÊѹà¤ò¹Ô¤Ê¤¦¤³¤È¤¬ËÜÅö¤Ë¶ìÄˤȤʤêÆÀ¤ë¤³¤È¤¬ + ʬ¤«¤ë¤Ç¤·¤ç¤¦¡£Á´¤Æ¤Î¥Ú¡¼¥¸¤ËÅϤäƤ¢¤ë¼ï¤Îɸ½àŪ¤Ê³°´Ñ¤ò + °Ý»ý¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤Ê¤é¤ÐÆäˤ½¤¦¤Ç¤·¤ç¤¦¡£

    + +

    ¥Ø¥Ã¥À¤ä¥Õ¥Ã¥¿ÍѤÎÁÞÆþÍÑ¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + ¤³¤Î¤è¤¦¤Ê¹¹¿·¤Ë¤«¤«¤ëÉéô¤ò¸º¤é¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + °ì¤Ä¤Î¥Õ¥Ã¥¿¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¡¢¤½¤ì¤ò include + SSI ¥³¥Þ¥ó¥É¤Ç³Æ¥Ú¡¼¥¸¤ËÆþ¤ì¤ë¤À¤±¤ÇºÑ¤ß¤Þ¤¹¡£include + Í×ÁǤϡ¢file °À­¤Þ¤¿¤Ï virtual + °À­¤Î¤¤¤º¤ì¤«¤ò»ÈÍѤ·¤Æ¤É¤Î¥Õ¥¡¥¤¥ë¤òÁÞÆþ¤¹¤ë¤«¤ò·è¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + file °À­¤Ï¡¢¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂХѥ¹¤Ç¼¨¤µ¤ì¤¿ + ¥Õ¥¡¥¤¥ë¥Ñ¥¹¤Ç¤¹¡£ + ¤½¤ì¤Ï / ¤Ç»Ï¤Þ¤ëÀäÂÐ¥Õ¥¡¥¤¥ë¥Ñ¥¹¤Ë¤Ï¤Ç¤­¤º¡¢¤Þ¤¿¡¢¤½¤Î¥Ñ¥¹¤Î°ìÉô¤Ë ../ + ¤ò´Þ¤à¤³¤È¤¬¤Ç¤­¤Ê¤¤¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£virtual + °À­¤Ï¡¢¤ª¤½¤é¤¯¤è¤êÊØÍø¤À¤È»×¤¤¤Þ¤¹¤¬¡¢Ä󶡤¹¤ë¥É¥­¥å¥á¥ó¥È¤«¤é¤ÎÁêÂÐ + URL ¤Ç»ØÄꤹ¤Ù¤­¤Ç¤¹¡£¤½¤ì¤Ï / ¤Ç»Ï¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ + Ä󶡤¹¤ë¥Õ¥¡¥¤¥ë¤ÈƱ¤¸¥µ¡¼¥Ð¾å¤Ë¸ºß¤·¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£

    +

    + <!--#include virtual="/footer.html" --> +

    + +

    »ä¤ÏºÇ¸å¤ÎÆó¤Ä¤òÁȤ߹ç¤ï¤»¤Æ¡¢LAST_MODIFIED + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Õ¥Ã¥¿¥Õ¥¡¥¤¥ë¤ÎÃæ¤ËÃÖ¤¯¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£ + SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ÁÞÆþÍѤΥե¡¥¤¥ë¤Ë´Þ¤Þ¤»¤¿¤ê¡¢ + ÁÞÆþ¥Õ¥¡¥¤¥ë¤Î¥Í¥¹¥È¤ò¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¹¤Ê¤ï¤Á¡¢ + ÁÞÆþÍѤΥե¡¥¤¥ë¤Ï¾¤Î¥Õ¥¡¥¤¥ë¤òºÆµ¢Åª¤ËÁÞÆþ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +
    top
    +
    +

    ¾¤Ë²¿¤¬ÀßÄê¤Ç¤­¤ë¤Î¤« ?

    + + +

    »þ¹ï½ñ¼°¤ò config ¤ÇÀßÄê¤Ç¤­¤ë¤³¤È¤Ë²Ã¤¨¤Æ¡¢ + ¹¹¤ËÆó¤Ä config ¤ÇÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Ä̾SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç²¿¤«¤¬¤¦¤Þ¤¯¤¤¤«¤Ê¤¤¤È¤­¤Ï¡¢ + ¼¡¤Î¥á¥Ã¥»¡¼¥¸¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£

    +

    + [an error occurred while processing this directive] +

    + +

    ¤³¤Î¥á¥Ã¥»¡¼¥¸¤ò¾¤Î¤â¤Î¤Ë¤·¤¿¤¤¾ì¹ç¡¢config + Í×ÁǤΠerrmsg °À­¤ÇÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    +

    + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> +

    + +

    ¤ª¤½¤é¤¯¡¢¥¨¥ó¥É¥æ¡¼¥¶¤Ï¤³¤Î¥á¥Ã¥»¡¼¥¸¤ò·è¤·¤Æ¸«¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤Ê¤¼¤Ê¤é¡¢¤½¤Î¥µ¥¤¥È¤¬À¸¤­¤¿¾õÂ֤ˤʤëÁ°¤Ë SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë´Ø¤¹¤ë + Á´¤Æ¤ÎÌäÂê¤ò²ò·è¤·¤Æ¤¤¤ë¤Ï¤º¤À¤«¤é¤Ç¤¹¡£(¤½¤¦¤Ç¤¹¤è¤Í?)

    + +

    ¤½¤·¤Æ¡¢config ¤Ë¤ª¤¤¤Æ sizefmt + °À­¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + ÊÖ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤Î½ñ¼°¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥Ð¥¤¥È¿ô¤Ë¤Ï bytes ¤ò¡¢Å¬Åö¤Ë Kb ¤ä Mb + ¤Ëû½Ì¤µ¤»¤ë¤Ë¤Ï abbrev ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ¥³¥Þ¥ó¥É¤Î¼Â¹Ô

    + + +

    º£¸å¿ô¥ö·î¤Î¤¦¤Á¤Ë¡¢¾®¤µ¤Ê CGI ¥×¥í¥°¥é¥à¤È SSI + ¤ò»ÈÍѤ¹¤ëµ­»ö¤ò½Ð¤·¤¿¤¤¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£¤³¤³¤Ç¤Ï¤½¤ì¤È¤ÏÊ̤ˡ¢ + exec Í×ÁǤˤè¤Ã¤Æ¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + SSI ¤Ë¥·¥§¥ë (Àµ³Î¤Ë¤Ï /bin/sh¡£Win32 ¤Ê¤é¤Ð DOS ¥·¥§¥ë) + ¤ò»ÈÍѤ·¤Æ¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ²¼µ­¤ÎÎã¤Ç¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê¥ê¥¹¥È½ÐÎϤò¹Ô¤Ê¤¤¤Þ¤¹¡£

    +

    + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +

    + +

    Windows ¾å¤Ç¤Ï¡¢

    +

    + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +

    + +

    Windows ¾å¤Ç¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ¤¤¤¯¤Ä¤«¤Î´ñ̯¤Ê + ½ñ¼°¤Ëµ¤¤Å¤¯¤Ç¤·¤ç¤¦¡£¤Ê¤¼¤Ê¤é dir ¤Î½ÐÎϤ¬Ê¸»úÎó + ``<dir>'' ¤ò´Þ¤ß¡¢¥Ö¥é¥¦¥¶¤òº®Í𤵤»¤ë¤«¤é¤Ç¤¹¡£

    + +

    ¤³¤Îµ¡Ç½¤ÏÈó¾ï¤Ë´í¸±¤Ç¤¢¤ê¡¢¤É¤ó¤Ê¥³¡¼¥É¤Ç¤â exec + ¥¿¥°¤ËËä¤á¹þ¤Þ¤ì¤Æ¤·¤Þ¤¨¤Ð¼Â¹Ô¤¹¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð + `` ¥²¥¹¥È¥Ö¥Ã¥¯ '' ¤Î¤è¤¦¤Ë¡¢¤â¤·¡¢ + ¥æ¡¼¥¶¤¬¥Ú¡¼¥¸¤ÎÆâÍƤòÊÔ½¸¤Ç¤­¤ë¾õ¶·¤Ë¤¢¤ë¤Ê¤é¤Ð¡¢ + ¤³¤Îµ¡Ç½¤ò³Î¼Â¤ËÍÞÀ©¤·¤Æ¤¯¤À¤µ¤¤¡£Options + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î IncludesNOEXEC °ú¿ô¤ò»ØÄꤹ¤ë¤³¤È¤Ç¡¢ + SSI ¤Ïµö²Ä¤¹¤ë¤±¤ì¤É exec + µ¡Ç½¤Ïµö²Ä¤·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ¹âÅÙ¤Ê SSI ¥Æ¥¯¥Ë¥Ã¥¯

    + + +

    ¥³¥ó¥Æ¥ó¥Ä¤ò½ÐÎϤ¹¤ë¤³¤È¤Ë²Ã¤¨¡¢Apache SSI ¤ÏÊÑ¿ô¤òÀßÄꤷ¡¢ + ¤½¤·¤ÆÈæ³Ó¤È¾ò·ïʬ´ô¤Ë¤½¤ÎÊÑ¿ô¤ò»ÈÍѤǤ­¤ëµ¡Ç½¤òÄ󶡤·¤Æ¤¤¤Þ¤¹¡£ +

    + +

    ·Ù¹ð

    + +

    ¤³¤Îµ­»ö¤Ç½Ò¤Ù¤¿ÂçÉôʬ¤Îµ¡Ç½¤Ï¡¢Apache 1.2 + °Ê¹ß¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Î¤ßÍøÍѲÄǽ¤Ç¤¹¡£¤â¤Á¤í¤ó¡¢¤â¤· Apache 1.2 + °Ê¹ß¤ò»ÈÍѤ·¤Æ¤Ê¤¤¾ì¹ç¡¢Ä¾¤Á¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤µ¤¡¡¢º£¤½¤ì¤ò¹Ô¤Ê¤¤¤Ê¤µ¤¤¡£¤½¤ì¤Þ¤ÇÂԤäƤ¤¤Þ¤¹¡£

    + + +

    ÊÑ¿ô¤òÀßÄꤹ¤ë

    + +

    set ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ + ¸å¤Ç»ÈÍѤ¹¤ë¤¿¤á¤ËÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï¸å¤ÎÀâÌÀ¤ÇɬÍפˤʤë¤Î¤Ç¡¢¤³¤³¤Ç¤½¤ì¤Ë¤Ä¤¤¤Æ½Ò¤Ù¤Æ¤¤¤Þ¤¹¡£ + ʸˡ¤Ï°Ê²¼¤Î¤È¤ª¤ê¤Ç¤¹:

    +

    + <!--#set var="name" value="Rich" --> +

    + +

    ¤³¤Î¤è¤¦¤Ëñ½ã¤Ëʸ»ú¤É¤ª¤ê¤ËÀßÄꤹ¤ë¤³¤È¤Ë²Ã¤¨¡¢ + ´Ä¶­ÊÑ¿ô¤ä¾åµ­¤ÎÊÑ¿ô + (Î㤨¤Ð LAST_MODIFIED ¤Î¤è¤¦¤Ê) + ¤ò´Þ¤à¾¤Î¤¢¤é¤æ¤ëÊÑ¿ô¤òÃͤòÀßÄꤹ¤ë¤Î¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ÊÑ¿ô̾¤ÎÁ°¤Ë¥É¥ëµ­¹æ ($) ¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + ¤½¤ì¤¬¥ê¥Æ¥é¥ëʸ»úÎó¤Ç¤Ï¤Ê¤¯¤ÆÊÑ¿ô¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£

    +

    + <!--#set var="modified" value="$LAST_MODIFIED" --> +

    + +

    ¥É¥ëµ­¹æ ($) ¤òʸ»ú¤È¤·¤ÆÊÑ¿ô¤ÎÃͤËÆþ¤ì¤ë¤Ë¤Ï¡¢ + ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ë¤è¤Ã¤Æ¥É¥ëµ­¹æ¤ò¥¨¥¹¥±¡¼¥×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    +

    + <!--#set var="cost" value="\$100" --> +

    + +

    ºÇ¸å¤Ë¤Ê¤ê¤Þ¤¹¤¬¡¢Ä¹¤¤Ê¸»úÎó¤ÎÃæ¤ËÊÑ¿ô¤òÃÖ¤­¤¿¤¤¾ì¹ç¤Ç¡¢ + ÊÑ¿ô̾¤¬Â¾¤Îʸ»ú¤È¤Ö¤Ä¤«¤ë²ÄǽÀ­¤¬¤¢¤ê¡¢ + ¤½¤ì¤é¤Îʸ»ú¤Ë¤Ä¤¤¤Æº®Í𤷤Ƥ·¤Þ¤¦¾ì¹ç¡¢¤³¤Îº®Íð¤ò¼è¤ê½ü¤¯¤¿¤á¡¢ + ÊÑ¿ô̾¤òÃæ³ç¸Ì¤Ç°Ï¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹ + (¤³¤ì¤Ë¤Ä¤¤¤Æ¤ÎÎɤ¤Îã¤ò¼¨¤¹¤Î¤ÏÆñ¤·¤¤¤Î¤Ç¤¹¤¬¡¢ + ¤ª¤½¤é¤¯Ê¬¤«¤Ã¤Æ¤¤¤¿¤À¤±¤ë¤Ç¤·¤ç¤¦)¡£ +

    +

    + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> +

    + + +

    ¾ò·ï¼°

    + + +

    ¤µ¤Æ¡¢ÊÑ¿ô¤ò»ý¤Ã¤Æ¤¤¤Æ¡¢ + ¤½¤ì¤é¤ÎÃͤòÀßÄꤷ¤ÆÈæ³Ó¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤Î¤Ç¤¹¤«¤é¡¢ + ¾ò·ï¤òɽ¤¹¤¿¤á¤Ë¤½¤ì¤é¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê + SSI ¤Ï¤¢¤ë¼ï¤Î¾®¤µ¤Ê¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + mod_include ¤Ï¾ò·ï¤òɽ¸½¤¹¤ë¤¿¤á¤Ë if, + elif, else, endif + ¹½Â¤¤òÄ󶡤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ë¤è¤Ã¤Æ¡¢ + °ì¤Ä¤Î¼ÂºÝ¤Î¥Ú¡¼¥¸¤«¤éÊ£¿ô¤ÎÏÀÍý¥Ú¡¼¥¸¤ò¸ú²ÌŪ¤ËÀ¸À®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¾ò·ï¹½Â¤¤Ï°Ê²¼¤Î¤È¤ª¤ê¤Ç¤¹:

    +

    + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +

    + +

    test_condition + ¤Ï¤¢¤é¤æ¤ë¼ïÎà¤ÎÏÀÍýŪÈæ³Ó¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ÃͤòÈæ³Ó¤·¤¿¤ê¡¢¤½¤ÎÃͤ¬ ``¿¿'' ¤«¤É¤¦¤«¤òɾ²Á¤·¤Þ¤¹ + (¶õ¤Ç¤Ê¤¤¤Ê¤éÍ¿¤¨¤é¤ì¤¿Ê¸»úÎó¤Ï¿¿¤Ç¤¹)¡£ + ÍøÍѲÄǽ¤ÊÈæ³Ó±é»»»Ò¤ÎÁ´¤Æ¤Î¥ê¥¹¥È¤Ë¤Ä¤¤¤Æ¤Ï¡¢ + mod_include ¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤³¤Ç¤Ï¡¢¤³¤Î¹½Â¤¤ò¤É¤¦»ÈÍѤ¹¤ë¤«¤ÎÎã¤ò¤¤¤¯¤Ä¤«¼¨¤·¤Þ¤¹¡£

    + +

    ÀßÄê¥Õ¥¡¥¤¥ë¤Ç¼¡¤Î¹Ô¤òµ­½Ò¤·¤Þ¤¹:

    +

    + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +

    + +

    ¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤¬ Macintosh + ¾å¤Ç¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥¨¥¯¥¹¥×¥í¡¼¥é¤¬Æ°¤¤¤Æ¤¤¤ë¾ì¹ç¡¢´Ä¶­ÊÑ¿ô + ``Mac'' ¤È ``InternetExplorer'' ¤ò¿¿¤ÈÀßÄꤷ¤Þ¤¹¡£

    + +

    ¼¡¤Ë¡¢SSI ¤¬²Äǽ¤Ë¤Ê¤Ã¤¿¥É¥­¥å¥á¥ó¥È¤Ç°Ê²¼¤ò¹Ô¤Ê¤¤¤Þ¤¹: +

    +

    + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + Apologetic text goes here
    + <!--#else -->
    + Cool JavaScript code goes here
    + <!--#endif --> +

    + +

    Mac ¾å¤Î IE ¤ËÂФ·¤Æ²¿¤«»×¤¦¤È¤³¤í¤¬¤¢¤ë¤ï¤±¤Ç¤¢¤ê¤Þ¤»¤ó¡£ + ¾¤Ç¤Ï¼Â¹Ô¤Ç¤­¤Æ¤¤¤ë¤¤¤¯¤Ä¤«¤Î JavaScript ¤ò Mac ¾å¤Î IE + ¤Ç¼Â¹Ô¤µ¤»¤ë¤Î¤Ë¡¢Àè½µ¿ô»þ´Ö¶ìÏ«¤·¤¿¤È¤¤¤¦¤À¤±¤Î¤³¤È¤Ç¤¹¡£ + ¾å¤ÎÎã¤Ï¤½¤Î»ÃÄêŪ¤ÊÂнèÊýË¡¤Ç¤¹¡£

    + +

    ¾¤Î¤É¤ó¤ÊÊÑ¿ô (¤¢¤Ê¤¿¤¬ÄêµÁ¤¹¤ë¤â¤Î¡¢ + ¤Þ¤¿¤ÏÉáÄ̤δĶ­ÊÑ¿ô¤Î¤¤¤º¤ì¤«) ¤â¡¢¾ò·ïʸ¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Apache ¤Ï SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä¾¤Î´ØÏ¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤Ë¤è¤ê¡¢CGI + ¤ËÍê¤ë¤³¤È¤Ê¤¯¤«¤Ê¤êÊ£»¨¤ÊưŪ¤Ê¤³¤È¤ò¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
    top
    +
    +

    ½ª¤ï¤ê¤Ë

    + +

    SSI ¤Ï³Î¤«¤Ë CGI + ¤äưŪ¤Ê¥¦¥§¥Ö¥Ú¡¼¥¸¤òÀ¸À®¤¹¤ë¾¤Îµ»½Ñ¤ËÂå¤ï¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢¤¿¤¯¤µ¤ó¤Î;ʬ¤Êºî¶È¤ò¤»¤º¤Ë¡¢ + ¾¯Î̤ÎưŪ¤Ê¥³¥ó¥Æ¥ó¥Ä¤ò²Ã¤¨¤ë¤Ë¤Ï¤¹¤°¤ì¤¿ÊýË¡¤Ç¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/ssi.html.ko.euc-kr b/trunk/docs/manual/howto/ssi.html.ko.euc-kr new file mode 100644 index 0000000000..a1e97e6fb9 --- /dev/null +++ b/trunk/docs/manual/howto/ssi.html.ko.euc-kr @@ -0,0 +1,426 @@ + + + +¾ÆÆÄÄ¡ ÅõÅ丮¾ó: Server Side Includes ¼Ò°³ - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ ÅõÅ丮¾ó: Server Side Includes ¼Ò°³

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    Server-side includes¸¦ »ç¿ëÇÏ¿© HTML ¹®¼­¿¡ µ¿ÀûÀÎ ³»¿ëÀ» +Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    ¼Ò°³

    + + +

    ÀÌ ±ÛÀº º¸Åë SSI¶ó°í ºÎ¸£´Â Server Side Includes¸¦ ¼³¸íÇÑ´Ù. + SSI°¡ °¡´ÉÇϵµ·Ï ¼­¹ö¸¦ ¼³Á¤ÇÏ´Â ¹æ¹ý°ú HTML ÆäÀÌÁö¿¡ µ¿ÀûÀÎ + ³»¿ëÀ» Ãß°¡ÇÏ´Â ±âº»ÀûÀÎ SSI »ç¿ë¹ýÀ» ¼Ò°³ÇÑ´Ù.

    + +

    ÀÌ ±ÛÀÇ µÞºÎºÐÀº SSI Áö½Ã¾î Á¶°Ç¹®°ú °°Àº °í±Þ±â¹ýÀ» + ¼³¸íÇÑ´Ù.

    + +
    top
    +
    +

    SSI°¡ ¹«¾ùÀΰ¡?

    + +

    SSI (Server Side Includes)´Â HTML ÆäÀÌÁö¿¡ »ç¿ëÇÏ´Â Áö½Ã¾î·Î, + ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ¶§ ¼­¹ö°¡ ó¸®ÇÑ´Ù. SSI¸¦ »ç¿ëÇϸé CGI + ÇÁ·Î±×·¥À̳ª ´Ù¸¥ µ¿ÀûÀÎ ±â¼ú·Î ÆäÀÌÁö Àüü¸¦ ¸¸µé¾î¼­ + ¼­ºñ½ºÇÏÁö ¾Ê°íµµ HTML ÆäÀÌÁö¿¡ µ¿ÀûÀ¸·Î »ý¼ºÇÑ ³»¿ëÀ» Ãß°¡ÇÒ + ¼ö ÀÖ´Ù.

    + +

    SSI¸¦ »ç¿ëÇÒÁö ¾Æ´Ï¸é ÇÁ·Î±×·¥À¸·Î ÆäÀÌÁö Àüü¸¦ »ý¼ºÇÒÁö + °áÁ¤Àº ÆäÀÌÁö¿¡¼­ Á¤ÀûÀÎ ºÎºÐÀÌ ¸¹ÀºÁö¿Í ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ + ¶§¸¶´Ù ¾î´ÀÁ¤µµ¸¦ ´Ù½Ã °è»êÇؾßÇÒÁö¿¡ ´Þ·È´Ù. SSI´Â ÇöÀç + ½Ã°£°ú °°ÀÌ ÀûÀº Á¤º¸¸¦ Ãß°¡Çϴµ¥ ÁÁ´Ù. ±×·¯³ª ÆäÀÌÁö¸¦ + ¼­ºñ½ºÇÒ¶§ ÆäÀÌÁöÀÇ ´ëºÎºÐÀ» »ý¼ºÇØ¾ß ÇÑ´Ù¸é ´Ù¸¥ ¹æ¹ýÀ» + ã¾ÆºÁ¾ß ÇÑ´Ù.

    +
    top
    +
    +

    SSI°¡ °¡´ÉÇϵµ·Ï ¼­¹ö ¼³Á¤Çϱâ

    + + +

    ¼­¹ö°¡ SSI¸¦ ó¸®ÇÏ·Á¸é httpd.conf ÆÄÀÏÀ̳ª + .htaccess ÆÄÀÏ¿¡¼­ ´ÙÀ½ Áö½Ã¾î¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.

    +

    + Options +Includes +

    + +

    ±×·¯¸é ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ¼³Á¤¿¡´Â + º¸Åë ¿©·¯ Options Áö½Ã¾î°¡ + ÀÖ°í, ÀÌ Áö½Ã¾îµéÀº ¼­·Î µ¤¾î½á¼­ ¹«È¿·Î ¸¸µé´Ù. ±×·¡¼­ + Áö½Ã¾î¸¦ ¸Ç¸¶Áö¸·¿¡ ó¸®ÇϱâÀ§ÇØ º¸Åë SSI¸¦ ¿øÇϴ ƯÁ¤ + µð·ºÅ丮¿¡¼­ Options¸¦ »ç¿ëÇÑ´Ù.

    + +

    ¸ðµç ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¾ÆÆÄÄ¡¿¡°Ô + ¾î¶² ÆÄÀÏÀ» ó¸®ÇÒÁö ¾Ë·ÁÁà¾ß ÇÑ´Ù. µÎ°¡Áö ¹æ¹ýÀÌ ÀÖ´Ù. + Çϳª´Â ´ÙÀ½°ú °°Àº Áö½Ã¾î·Î .shtml°ú °°Àº ƯÁ¤ + ÆÄÀÏ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏÀ» ó¸®ÇÏ´Â ¹æ¹ýÀÌ´Ù.

    +

    + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +

    + +

    ÀÌ ¹æ¹ýÀÇ ´ÜÁ¡Àº ÀÌ¹Ì ÀÖ´Â ÆäÀÌÁö¿¡ SSI Áö½Ã¾î¸¦ Ãß°¡ÇÏ´Â + °æ¿ì SSI Áö½Ã¾î¸¦ ó¸®ÇϱâÀ§ÇØ .shtml È®ÀåÀÚ¸¦ + ºÎ¿©Çϱ⶧¹®¿¡ ÆÄÀϸí°ú ÀÌ ÆäÀÌÁöÀÇ ¸ðµç ¸µÅ©¸¦ º¯°æÇØ¾ß + ÇÏ´Â Á¡ÀÌ´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº XBitHack + Áö½Ã¾î¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù.

    +

    + XBitHack on +

    + +

    XBitHack´Â + ½ÇÇà±ÇÇÑÀÌ ÀÖ´Â ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ ÀÌ¹Ì + ÀÖ´Â ÆäÀÌÁö¿¡ SSI Áö½Ã¾î¸¦ Ãß°¡ÇÑ´Ù¸é ÆÄÀϸíÀ» º¯°æÇÏÁö + ¾Ê°í chmod·Î ÆÄÀÏ¿¡ ½ÇÇà±ÇÇÑÀ» ÁÖ¸é µÈ´Ù.

    +

    + chmod +x pagename.html +

    + +

    ÇÏÁö ¸»¾Æ¾ß ÇÒ °Í Çϳª. °¡²û .shtml ÆÄÀÏ¸í¿¡ + °ñÄ¡¸¦ ¾ÎÁö¸»°í ¸ðµç .html ÆÄÀÏÀ» SSI ó¸®Ç϶ó°í + Ãæ°íÇÏ´Â »ç¶÷ÀÌ ÀÖ´Ù. ÀÌ »ç¶÷µéÀº ¾Æ¸¶µµ XBitHack¿¡ ´ëÇØ ¸ð¸£´Â + °Í °°´Ù. ¸í½ÉÇÒ Á¡Àº ÀÌ·¸°Ô ÇÏ¸é ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡ SSI Áö½Ã¾î°¡ + ¾ø´õ¶óµµ Ŭ¶óÀ̾ðÆ®·Î º¸³»´Â ¸ðµç ÆÄÀÏÀ» »ìÆìºÁ¾ß ÇÑ´Ù´Â + °ÍÀÌ´Ù. ¼º´ÉÀÌ ¸Å¿ì ´À·ÁÁú ¼ö ÀÖÀ¸¸ç, ÁÁÀº »ý°¢ÀÌ ¾Æ´Ï´Ù.

    + +

    ¹°·Ð À©µµ¿ìÁî¿¡¼­´Â ½ÇÇà±ÇÇÑÀ̶õ °ÍÀÌ ¾ø±â¶§¹®¿¡ ÈÄÀÚ¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    ³»¿ëÀÌ µ¿ÀûÀÌ¿©¼­ °è»êÇϱ⠾î·Æ±â¶§¹®¿¡ ¾ÆÆÄÄ¡ ±âº» ¼³Á¤Àº + SSI ÆäÀÌÁöÀÇ ÃÖ±Ù¼öÁ¤ÀÏ°ú content length HTTP Çì´õ¸¦ º¸³»Áö + ¾Ê´Â´Ù. ±×·¡¼­ ¹®¼­¸¦ ij½¬ÇÏÁö ¸øÇÏ°í Ŭ¶óÀ̾ðÆ®°¡ ´À³¢´Â + ¼º´ÉÀÌ ¶³¾îÁø´Ù. µÎ°¡Áö ÇØ°á¹æ¹ýÀÌ ÀÖ´Ù.

    + +
      +
    1. XBitHack Full ¼³Á¤Àº »ç¿ëÇÑ´Ù. ±×·¯¸é + ¾ÆÆÄÄ¡´Â Æ÷ÇÔÇÏ´Â(include) ÆÄÀϵéÀÇ ¼öÁ¤ÀÏÀº ¹«½ÃÇÑü + ¿ø·¡ ¿äûÇÑ ÆÄÀÏÀÇ ³¯Â¥¸¸ º¸°í ÃÖ±Ù¼öÁ¤ÀÏÀ» ¾Ë¾Æ³½´Ù.
    2. + +
    3. mod_expires¿¡ ÀÖ´Â Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ÆÄÀÏ¿¡ Á÷Á¢ ¸¸±âÀÏÀ» ¼³Á¤ÇÏ¸é ºê¶ó¿ìÀú¿Í ÇÁ·Ï½Ã°¡ ¹®¼­¸¦ + ij½¬ÇÒ ¼ö ÀÖ´Ù.
    4. +
    +
    top
    +
    +

    ±âº» SSI Áö½Ã¾î

    + +

    SSI Áö½Ã¾îÀÇ »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.

    +

    + <!--#element attribute=value attribute=value ... --> +

    + +

    HTML ÁÖ¼®°°ÀÌ »ý°å±â¶§¹®¿¡ SSI ±â´ÉÀ» °¡µ¿ÇÏÁö ¾Ê¾Æµµ + HTML ¼Ò½º¿¡´Â ³ª¿ÀÁö¸¸ ºê¶ó¿ìÀú´Â ¹«½ÃÇÑ´Ù. SSI¸¦ ¿Ã¹Ù·Î + ¼³Á¤Çϸé Áö½Ã¾î¸¦ °á°ú°ªÀ¸·Î ¹Ù²Û´Ù.

    + +

    element´Â ´ÙÀ½Áß Çϳª´Ù. ´ÙÀ½ ȸ¿¡ ´õ ÀÚ¼¼È÷ ¼³¸íÇÒ °ÍÀÌ´Ù. + Áö±ÝÀº SSI·Î ÇÒ ¼ö ÀÖ´Â ¸î°¡Áö ¿¹¸¦ º¸ÀδÙ

    + +

    ¿À´Ã ³¯Â¥

    + +

    + <!--#echo var="DATE_LOCAL" --> +

    + +

    echo element´Â º¯¼ö°ªÀ» ±×´ë·Î Ãâ·ÂÇÑ´Ù. + CGI ÇÁ·Î±×·¥¿¡ Á¦°øÇϴ ȯ°æº¯¼öµé ¿Ü¿¡µµ ¿©·¯ Ç¥ÁØ º¯¼ö°¡ + ÀÖ´Ù. ¶Ç, set element¸¦ »ç¿ëÇÏ¿© Á÷Á¢ º¯¼ö¸¦ + Á¤ÀÇÇÒ ¼öµµ ÀÖ´Ù.

    + +

    ³¯Â¥ Ãâ·Â Çü½ÄÀÌ ¸¶À½¿¡ µéÁö ¾Ê´Â´Ù¸é, ´ÙÀ½°ú °°ÀÌ + config elementÀÇ timefmt attribute¸¦ + »ç¿ëÇÑ´Ù.

    + +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +

    + + +

    ÆÄÀÏÀÇ ¼öÁ¤ÀÏ

    + +

    + ÀÌ ¹®¼­´Â <!--#flastmod file="index.html" -->¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú´Ù +

    + +

    ÀÌ elementµµ timefmt Çü½Ä ¼³Á¤¿¡ ´Þ·È´Ù.

    + + +

    CGI ÇÁ·Î±×·¥ °á°ú¸¦ Æ÷ÇÔÇϱâ

    + +

    ÀϹÝÀûÀÎ SSI »ç¿ë¹ýÁß Çϳª·Î, ¸¹ÀÌµé ¾Ö¿ëÇÏ´Â ``¹æ¹®¼ö + Ä«¿îÅÍ'' °°Àº CGI ÇÁ·Î±×·¥ °á°ú¸¦ Ãâ·ÂÇÑ´Ù.

    + +

    + <!--#include virtual="/cgi-bin/counter.pl" --> +

    + + +
    top
    +
    +

    Ãß°¡ ¿¹Á¦

    + + +

    ´ÙÀ½Àº HTML ¹®¼­¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¸î°¡Áö SSI ¿¹Á¦´Ù.

    + +

    ÀÌ ¹®¼­°¡ ¾ðÁ¦ ¸¶Áö¸·À¸·Î +¼öÁ¤µÇ¾ú³ª?

    + +

    ¾Õ¿¡¼­ SSI¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ¿¡°Ô ¹®¼­ÀÇ ÃÖ±Ù¼öÁ¤ÀÏÀ» + ¾Ë¸± ¼ö ÀÖ´Ù°í ¸»Çß´Ù. ±×·¯³ª ½ÇÁ¦ ¹æ¹ýÀº ¾Ë·ÁÁÖÁö ¾Ê¾Ò´Ù. + ´ÙÀ½ Äڵ带 HTML ¹®¼­¿¡ »ç¿ëÇϸé ÆäÀÌÁö¿¡ ½Ã°£ ±â·ÏÀ» ³²±ä´Ù. + ¹°·Ð À§¿¡¼­ ¼³¸íÇÑ´ë·Î SSI°¡ ¿Ã¹Ù·Î ÀÛµ¿ÇØ¾ß ÇÑ´Ù.

    +

    + <!--#config timefmt="%A %B %d, %Y" -->
    + ÀÌ ¹®¼­´Â <!--#flastmod file="ssi.shtml" -->¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú´Ù; +

    + +

    ¹°·Ð ssi.shtml´ë½Å ¿øÇÏ´Â ½ÇÁ¦ ÆÄÀϸíÀ» + »ç¿ëÇÑ´Ù. ¾Æ¹« ÆäÀÌÁö¿¡¶óµµ ºÙ¿©³ÖÀ» ¼ö ÀÖ´Â ¹ü¿ëÄڵ带 + ¿øÇÑ´Ù¸é, ÆÄÀÏ¸í ´ë½Å LAST_MODIFIED º¯¼ö¸¦ + »ç¿ëÇÑ´Ù.

    +

    + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +

    + +

    timefmt Çü½Ä¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â °Ë»ö¿£Áø¿¡¼­ + strftimeÀ» ã¾ÆºÁ¶ó. ¹®¹ýÀº °°´Ù.

    + + +

    Ç¥ÁØ ÆäÀÌÁö ÇÏ´ÜÀ» Æ÷ÇÔÇϱâ

    + + +

    ¿©·¯ ÆäÀÌÁö°¡ ÀÖ´Â »çÀÌÆ®¸¦ °ü¸®ÇÑ´Ù¸é ÆäÀÌÁö Àüü¸¦ + ¼öÁ¤ÇÏ´Â °ÍÀº, ƯÈ÷ ÆäÀÌÁöµéÀÌ Ç¥ÁØ ¿Ü°üÀ» °¡Áöµµ·Ï ¼öÁ¤ÇÏ´Â + °ÍÀº Á¤¸»·Î ±«·Ó´Ù.

    + +

    ÆäÀÌÁö »ó´Ü(header)°ú ÇÏ´Ü(footer)À» ÆÄÀÏ·Î Æ÷ÇÔÇÏ¿© + ÀÌ·± ¼öÁ¤ÀÇ ºÎ´ãÀ» ´ú ¼ö ÀÖ´Ù. ¸ðµç ÆäÀÌÁö¿¡¼­ + include SSI ¸í·É¾î¸¦ »ç¿ëÇÏ¿© ÆäÀÌÁö ÇÏ´Ü ÆÄÀÏ + Çϳª¸¦ Æ÷ÇÔÇÏ¸é µÈ´Ù. include elementÀÇ + file attribute³ª virtual attribute·Î + Æ÷ÇÔÇÒ ÆÄÀÏÀ» ÁöÁ¤ÇÑ´Ù. file attribute´Â ÇöÀç + µð·ºÅ丮¿¡ »ó´ëÀûÀÎ ÆÄÀÏ°æ·Î´Ù. Áï, (/·Î ½ÃÀÛÇÏ´Â) + Àý´ëÆÄÀÏ°æ·Î³ª °æ·Î ¾È¿¡ ../¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù. ¾Æ¸¶µµ ¼­ºñ½ºÇÏ´Â + ¹®¼­ÀÇ »ó´ë URLÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Â virtual attribute°¡ + ´õ À¯¿ëÇÒ °ÍÀÌ´Ù. °æ·Î¸¦ /·Î ½ÃÀÛÇÒ ¼ö ÀÖÁö¸¸, Æ÷ÇÔÇÏ·Á´Â + ÆÄÀÏÀÌ ¼­ºñ½ºÇÏ´Â ÆÄÀÏ°ú °°Àº ¼­¹ö¿¡ ÀÖ¾î¾ß ÇÑ´Ù.

    +

    + <!--#include virtual="/footer.html" --> +

    + +

    ³ª´Â º¸Åë ÀÌ µÎ°¡Áö¸¦ ÇÕÃļ­ Æ÷ÇÔÇÒ ÆäÀÌÁö ÇÏ´Ü ÆÄÀÏ¿¡ + LAST_MODIFIED Áö½Ã¾î¸¦ ³Ö´Â´Ù. Æ÷ÇÔÇÏ·Á´Â ÆÄÀÏ¿¡µµ + SSI Áö½Ã¾î°¡ ³ª¿Ã ¼ö ÀÖÀ¸¸ç, ÀÌ·¸°Ô Æ÷ÇÔÇÑ ÆÄÀÏÀÌ ´Ù¸¥ ÆÄÀÏÀ» + Æ÷ÇÔÇÏ´Â ½ÄÀ¸·Î ¿©·¯¹ø °è¼Ó Æ÷ÇÔÇÒ ¼öµµ ÀÖ´Ù.

    + + +
    top
    +
    +

    ÀÌ¿Ü¿¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Â °ÍÀº?

    + + +

    ½Ã°£ Çü½Ä config(¼³Á¤) ¿Ü¿¡ µÎ°¡Áö¸¦ ´õ + config(¼³Á¤)ÇÒ ¼ö ÀÖ´Ù.

    + +

    º¸Åë SSI Áö½Ã¾î°¡ À߸øµÇ¸é ´ÙÀ½°ú °°Àº ¹®±¸°¡ ³ª¿Â´Ù

    +

    + [an error occurred while processing this directive] +

    + +

    ÀÌ ¹®±¸¸¦ º¯°æÇÏ°í ½Í´Ù¸é config elementÀÇ + errmsg attribute¸¦ »ç¿ëÇÏ¿© º¯°æÇÑ´Ù.

    +

    + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> +

    + +

    »çÀÌÆ®¸¦ ¼­ºñ½ºÇϱâ Àü¿¡ ¸ðµç SSI Áö½Ã¾î ¹®Á¦¸¦ ÇØ°áÇÏ¿© + »ç¿ëÀÚ°¡ ÀÌ·± ¹®±¸¸¦ º¸Áö ¾Ê±æ ¹Ù¶õ´Ù. (±×·¸Áö?)

    + +

    ±×¸®°í sizefmt attribute°¡ ¹ÝȯÇÏ´Â ÆÄÀÏÅ©±â + Çü½ÄÀ» config(¼³Á¤)ÇÒ ¼ö ÀÖ´Ù. ¹ÙÀÌÆ®·Î Å©±â¸¦ + º¸¿©ÁÖ·Á¸é bytes, ÀûÀýÈ÷ Kb³ª Mb·Î Å©±â¸¦ + º¸¿©ÁÖ·Á¸é abbrev¸¦ »ç¿ëÇÑ´Ù.

    +
    top
    +
    +

    ¸í·É¾î ½ÇÇàÇϱâ

    + + +

    ³ª´Â ´ÙÀ½ ´Þ¿¡ ÀÛÀº CGI ÇÁ·Î±×·¥°ú SSI¸¦ °°ÀÌ »ç¿ëÇÏ´Â + ±ÛÀ» ¾µ ¿¹Á¤ÀÌ´Ù. Áö±ÝÀº exec element·Î ÇÒ + ¼ö ÀÖ´Â ´Ù¸¥ °ÍµéÀ» ¼³¸íÇÒ °ÍÀÌ´Ù. SSI´Â ½ÇÁ¦ ½©À» (Á¤È®È÷´Â + /bin/sh³ª Win32¸¦ »ç¿ëÇÑ´Ù¸é DOS ½©) »ç¿ëÇÏ¿© + ¸í·É¾î¸¦ ½ÇÇàÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½Àº µð·ºÅ丮 ¸ñ·ÏÀ» º¸¿©ÁØ´Ù.

    +

    + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +

    + +

    or, on Windows

    +

    + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +

    + +

    dir Ãâ·Â¿¡ ºê¶ó¿ìÀú°¡ È¥µ¿ÇÒ + ``<dir>'' ¹®ÀÚ¿­ÀÌ Æ÷ÇÔµÇÀֱ⶧¹®¿¡, + À©µµ¿ìÁî¿¡¼­ ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é °á°ú°¡ Á¶±Ý ÀÌ»óÇÒ °ÍÀÌ´Ù.

    + +

    ÀÌ ±â´ÉÀº exec ű׿¡ »ç¿ëÇÑ ¾î¶² ¸í·É¾î¶óµµ + ½ÇÇàÇÒ ¼ö Àֱ⶧¹®¿¡ ¸Å¿ì À§ÇèÇÏ´Ù. ``¹æ¸í·Ï''°ú °°ÀÌ »ç¿ëÀÚ°¡ + À¥ÆäÀÌÁö ³»¿ëÀ» ¼öÁ¤ÇÒ ¼ö Àִ ȯ°æÀ̶ó¸é, ÀÌ ±â´ÉÀ» Àý´ë·Î + »ç¿ëÇؼ± ¾ÈµÈ´Ù. Options Áö½Ã¾î¿¡ + IncludesNOEXEC ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÏ¿© SSI¸¦ Çã¿ëÇÏÁö¸¸ + exec ±â´ÉÀ» ¸·À» ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    °í±Þ SSI ±â¹ý

    + + +

    ³»¿ëÀ» Ãâ·ÂÇÏ´Â ±â´É ¿Ü¿¡ ¾ÆÆÄÄ¡ SSI´Â º¯¼ö ¼³Á¤ÀÌ °¡´ÉÇÏ°í, + ºñ±³¹®°ú Á¶°Ç¹®¿¡ ÀÌ º¯¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    °æ°í

    + +

    ÀÌ ±Û¿¡¼­ ¼³¸íÇÏ´Â ´ëºÎºÐÀÇ ±â´ÉÀº ¾ÆÆÄÄ¡ 1.2 ÀÌÈĺÎÅÍ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¹°·Ð, ¾ÆÆÄÄ¡ 1.2 ÀÌ»óÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é + ¾Æ¸¶µµ »¡¸® ¾÷±×·¹À̵åÇØ¾ß ÇÑ´Ù. Çضó. Áö±Ý Çضó. ±â´Ù¸± + °ÍÀÌ´Ù.

    + + +

    º¯¼ö ¼³Á¤

    + +

    set Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ³ªÁß¿¡ »ç¿ëÇÒ º¯¼ö¸¦ + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¾ÕÀ¸·Î º¯¼ö°¡ ÇÊ¿äÇϱ⶧¹®¿¡ ¸ÕÀú ¼³¸íÇÑ´Ù. + ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.

    +

    + <!--#set var="name" value="Rich" --> +

    + +

    ´ÙÀ½°ú °°ÀÌ °ªÀ» ¹®ÀÚ±×´ë·Î ¼³Á¤ÇÏÁö ¾Ê°í ȯ°æº¯¼ö³ª À§¿¡¼­ ¼³¸íÇÑ º¯¼ö(¿¹¸¦ + µé¾î, LAST_MODIFIED)¿Í °°ÀÌ ´Ù¸¥ º¯¼ö¸¦ »ç¿ëÇÏ¿© + º¯¼ö°ªÀ» ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù. À̶§ º¯¼ö¸í ¾Õ¿¡ ´Þ·¯ Ç¥½Ã($)¸¦ + ºÙ¿©¼­ ¹®ÀÚ¿­ÀÌ ¾Æ´Ñ º¯¼öÀÓÀ» Ç¥½ÃÇÑ´Ù.

    + +

    <!--#set var="modified" value="$LAST_MODIFIED" --> +

    + +

    º¯¼ö°ª¿¡ ´Þ·¯ ¹®ÀÚ¸¦ ±×´ë·Î ÀÔ·ÂÇÏ·Á¸é ´Þ·¯ Ç¥½Ã ¾Õ¿¡ + ¹é½½·¡½¬¸¦ »ç¿ëÇÑ´Ù.

    +

    + <!--#set var="cost" value="\$100" --> +

    + +

    ¸¶Áö¸·À¸·Î ±ä ¹®ÀÚ¿­ Áß°£¿¡ º¯¼ö¸¦ »ç¿ëÇϴµ¥ µÚ¿¡ ÀÖ´Â + ¹®ÀÚµµ º¯¼ö¸íÀ¸·Î ¿ÀÀÎÇÏ¿© È¥µ¿µÇ´Â °æ¿ì, º¯¼ö¸íÀ» ´ë°ýÈ£·Î + ¹­¾î¼­ È®½ÇÈ÷ ÇÑ´Ù. (ÁÁÀº ¿¹¸¦ ã±â ÈûµéÁö¸¸, ¹«½¼ ¸»ÀÎÁö + ÀÌÇØÇÏ±æ ¹Ù¶õ´Ù.)

    +

    + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> +

    + + +

    Á¶°Ç Ç¥Çö½Ä

    + + +

    º¯¼ö¸¦ ¼³Á¤ÇÏ°í ºñ±³ÇÒ ¼ö ÀÖÀ¸´Ï Á¶°Ç¹®ÀÌ °¡´ÉÇÏ´Ù. ÀÌÁ¦ + SSI°¡ ÀÏÁ¾ÀÇ °£´ÜÇÑ ÇÁ·Î±×·¡¹Ö¾ð¾î°¡ µÈ´Ù. + mod_include´Â Á¶°Ç¹®À» ¸¸µå´Â if, + elif, else, endif + ±¸Á¶¸¦ Á¦°øÇÑ´Ù. ½ÇÁ¦ ÇÑ ÆäÀÌÁö·Î ¿©·¯ ³í¸®ÀûÀÎ ÆäÀÌÁö¸¦ + ¸¸µé ¼ö ÀÖ´Ù.

    + +

    Á¶°Ç¹® ±¸Á¶´Â ´ÙÀ½°ú °°´Ù.

    +

    + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +

    + +

    test_condition¿¡´Â ¾î¶² ³í¸®ºñ±³¶óµµ »ç¿ëÇÒ + ¼ö ÀÖ´Ù. °ªÀ» ´Ù¸¥ °ª°ú ºñ±³Çϰųª, ƯÁ¤ °ªÀÌ ``Âü''ÀÎÁö + °Ë»çÇÑ´Ù. (¹®ÀÚ¿­ÀÌ ºñ¾îÀÖÁö ¾ÊÀ¸¸é ÂüÀÌ´Ù.) »ç¿ë°¡´ÉÇÑ + ºñ±³ ¿¬»êÀÚ¸¦ ¸ðµÎ º¸·Á¸é, mod_include + ¹®¼­¸¦ Âü°íÇ϶ó. ´ÙÀ½Àº Á¶°Ç¹®À» »ç¿ëÇÑ ¸î°¡Áö ¿¹Á¦´Ù.

    + +

    ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½ ÁÙÀ» Ãß°¡ÇÑ´Ù.

    +

    + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +

    + +

    Ŭ¶óÀ̾ðÆ®°¡ ¸ÆŲÅä½Ã¿¡¼­ ½ÇÇàÇÏ´Â Internet Explorer¶ó¸é + ȯ°æº¯¼ö ``Mac''°ú ``InternetExplorer'' ¸ðµÎ ÂüÀ¸·Î ¼³Á¤ÇÑ´Ù.

    + +

    ±×¸®°í SSI ¹®¼­¿¡ ´ÙÀ½°ú °°ÀÌ Àû´Â´Ù.

    +

    + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + ¿©±â¿¡ »ç°ú¹®°¡ ³ª¿Â´Ù
    + <!--#else -->
    + ¿©±â¿¡ ¸ÚÁø JavaScript Äڵ尡 ³ª¿Â´Ù
    + <!--#endif --> +

    + +

    ³»°¡ ¸ÅŲÅä½Ã IE¿¡ ¹Ý°¨ÀÌ ÀÖ´Â °ÍÀº ¾Æ´Ï´Ù. ³ª´Â ´ÜÁö + Àú¹øÁÖ¿¡ ´Ù¸¥ °÷¿¡¼­´Â ¹®Á¦°¡ ¾ø´Â JavaScript Äڵ尡 ¸ÅŲÅä½Ã + IE¿¡¼­´Â µ¿ÀÛÇÏÁö ¾Ê¾Æ¼­ ¸î½Ã°£À» °í»ýÇß´Ù. À§´Â Àӽà + ÇØ°áÃ¥ÀÌ´Ù.

    + +

    (Á÷Á¢ Á¤ÀÇÇÏ¿´°Ç ÀÏ¹Ý È¯°æº¯¼öÀÌ°Ç) ¾î¶² º¯¼ö¶óµµ Á¶°Ç¹®¿¡ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¾Æ¶óÄ¡´Â SetEnvIf³ª ´Ù¸¥ °ü·Ã + Áö½Ã¾î·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö Àֱ⶧¹®¿¡ CGI ¾øÀ̵µ ¸ÚÁö°Ô + µ¿ÀûÀÎ ³»¿ëÀ» ¸¸µé ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    °á·Ð

    + +

    SSI´Â È®½ÇÈ÷ CGI³ª µ¿ÀûÀÎ À¥ÆäÀÌÁö¸¦ »ý¼ºÇÏ´Â ´Ù¸¥ ±â¼úÀ» + ´ëüÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ¸¹Àº Ãß°¡ ÀÛ¾÷¾øÀÌ ÆäÀÌÁö¿¡ µ¿ÀûÀÎ + ³»¿ëÀ» Á¶±Ý Ãß°¡Çϱ⿡´Â ÈǸ¢ÇÑ ¹æ¹ýÀÌ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/howto/ssi.xml b/trunk/docs/manual/howto/ssi.xml new file mode 100644 index 0000000000..4c15196812 --- /dev/null +++ b/trunk/docs/manual/howto/ssi.xml @@ -0,0 +1,489 @@ + + + + + + + + +How-To / Tutorials + +Apache Tutorial: Introduction to Server Side Includes + + +

    Server-side includes provide a means to add dynamic content to +existing HTML documents.

    +
    + + + +
    What are SSI? + +

    SSI (Server Side Includes) are directives that are placed in + HTML pages, and evaluated on the server while the pages are + being served. They let you add dynamically generated content to + an existing HTML page, without having to serve the entire page + via a CGI program, or other dynamic technology.

    + +

    The decision of when to use SSI, and when to have your page + entirely generated by some program, is usually a matter of how + much of the page is static, and how much needs to be + recalculated every time the page is served. SSI is a great way + to add small pieces of information, such as the current time. + But if a majority of your page is being generated at the time + that it is served, you need to look for some other + solution.

    +
    + +
    +Configuring your server to permit SSI + +

    To permit SSI on your server, you must have the following + directive either in your httpd.conf file, or in a + .htaccess file:

    + + Options +Includes + + +

    This tells Apache that you want to permit files to be parsed + for SSI directives. Note that most configurations contain + multiple Options directives + that can override each other. You will probably need to apply the + Options to the specific directory where you want SSI + enabled in order to assure that it gets evaluated last.

    + +

    Not just any file is parsed for SSI directives. You have to + tell Apache which files should be parsed. There are two ways to + do this. You can tell Apache to parse any file with a + particular file extension, such as .shtml, with + the following directives:

    + + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +
    + +

    One disadvantage to this approach is that if you wanted to + add SSI directives to an existing page, you would have to + change the name of that page, and all links to that page, in + order to give it a .shtml extension, so that those + directives would be executed.

    + +

    The other method is to use the XBitHack directive:

    + + XBitHack on + + +

    XBitHack + tells Apache to parse files for SSI + directives if they have the execute bit set. So, to add SSI + directives to an existing page, rather than having to change + the file name, you would just need to make the file executable + using chmod.

    + + chmod +x pagename.html + + +

    A brief comment about what not to do. You'll occasionally + see people recommending that you just tell Apache to parse all + .html files for SSI, so that you don't have to + mess with .shtml file names. These folks have + perhaps not heard about XBitHack. The thing to + keep in mind is that, by doing this, you're requiring that + Apache read through every single file that it sends out to + clients, even if they don't contain any SSI directives. This + can slow things down quite a bit, and is not a good idea.

    + +

    Of course, on Windows, there is no such thing as an execute + bit to set, so that limits your options a little.

    + +

    In its default configuration, Apache does not send the last + modified date or content length HTTP headers on SSI pages, + because these values are difficult to calculate for dynamic + content. This can prevent your document from being cached, and + result in slower perceived client performance. There are two + ways to solve this:

    + +
      +
    1. Use the XBitHack Full configuration. This + tells Apache to determine the last modified date by looking + only at the date of the originally requested file, ignoring + the modification date of any included files.
    2. + +
    3. Use the directives provided by + mod_expires to set an explicit expiration + time on your files, thereby letting browsers and proxies + know that it is acceptable to cache them.
    4. +
    +
    + +
    Basic SSI directives + +

    SSI directives have the following syntax:

    + + <!--#element attribute=value attribute=value ... --> + + +

    It is formatted like an HTML comment, so if you don't have + SSI correctly enabled, the browser will ignore it, but it will + still be visible in the HTML source. If you have SSI correctly + configured, the directive will be replaced with its + results.

    + +

    The element can be one of a number of things, and we'll talk + some more about most of these in the next installment of this + series. For now, here are some examples of what you can do with + SSI

    + +
    Today's date + + + <!--#echo var="DATE_LOCAL" --> + + +

    The echo element just spits out the value of a + variable. There are a number of standard variables, which + include the whole set of environment variables that are + available to CGI programs. Also, you can define your own + variables with the set element.

    + +

    If you don't like the format in which the date gets printed, + you can use the config element, with a + timefmt attribute, to modify that formatting.

    + + + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +
    +
    + +
    Modification date of the file + + + This document last modified <!--#flastmod file="index.html" --> + + +

    This element is also subject to timefmt format + configurations.

    +
    + +
    Including the results of a CGI program + +

    This is one of the more common uses of SSI - to output the + results of a CGI program, such as everybody's favorite, a ``hit + counter.''

    + + + <!--#include virtual="/cgi-bin/counter.pl" --> + + +
    +
    + +
    +Additional examples + +

    Following are some specific examples of things you can do in + your HTML documents with SSI.

    + +
    When was this document +modified? + +

    Earlier, we mentioned that you could use SSI to inform the + user when the document was most recently modified. However, the + actual method for doing that was left somewhat in question. The + following code, placed in your HTML document, will put such a + time stamp on your page. Of course, you will have to have SSI + correctly enabled, as discussed above.

    + + <!--#config timefmt="%A %B %d, %Y" -->
    + This file last modified <!--#flastmod file="ssi.shtml" --> +
    + +

    Of course, you will need to replace the + ssi.shtml with the actual name of the file that + you're referring to. This can be inconvenient if you're just + looking for a generic piece of code that you can paste into any + file, so you probably want to use the + LAST_MODIFIED variable instead:

    + + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +
    + +

    For more details on the timefmt format, go to + your favorite search site and look for strftime. The + syntax is the same.

    +
    + + + +
    + +
    +What else can I config? + +

    In addition to being able to config the time + format, you can also config two other things.

    + +

    Usually, when something goes wrong with your SSI directive, + you get the message

    + + [an error occurred while processing this directive] + + +

    If you want to change that message to something else, you + can do so with the errmsg attribute to the + config element:

    + + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> + + +

    Hopefully, end users will never see this message, because + you will have resolved all the problems with your SSI + directives before your site goes live. (Right?)

    + +

    And you can config the format in which file + sizes are returned with the sizefmt attribute. You + can specify bytes for a full count in bytes, or + abbrev for an abbreviated number in Kb or Mb, as + appropriate.

    +
    + +
    + Executing commands + +

    I expect that I'll have an article some time in the coming + months about using SSI with small CGI programs. For now, here's + something else that you can do with the exec + element. You can actually have SSI execute a command using the + shell (/bin/sh, to be precise - or the DOS shell, + if you're on Win32). The following, for example, will give you + a directory listing.

    + + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +
    + +

    or, on Windows

    + + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +
    + +

    You might notice some strange formatting with this directive + on Windows, because the output from dir contains + the string ``<dir>'' in it, which confuses + browsers.

    + +

    Note that this feature is exceedingly dangerous, as it will + execute whatever code happens to be embedded in the + exec tag. If you have any situation where users + can edit content on your web pages, such as with a + ``guestbook'', for example, make sure that you have this + feature disabled. You can allow SSI, but not the + exec feature, with the IncludesNOEXEC + argument to the Options directive.

    +
    + +
    +Advanced SSI techniques + +

    In addition to spitting out content, Apache SSI gives you + the option of setting variables, and using those variables in + comparisons and conditionals.

    + +
    Caveat + +

    Most of the features discussed in this article are only + available to you if you are running Apache 1.2 or later. Of + course, if you are not running Apache 1.2 or later, you need to + upgrade immediately, if not sooner. Go on. Do it now. We'll + wait.

    +
    + +
    Setting variables + +

    Using the set directive, you can set variables + for later use. We'll need this later in the discussion, so + we'll talk about it here. The syntax of this is as follows:

    + + <!--#set var="name" value="Rich" --> + + +

    In addition to merely setting values literally like that, you + can use any other variable, including environment variables or the variables + discussed above (like LAST_MODIFIED, for example) to + give values to your variables. You will specify that something is + a variable, rather than a literal string, by using the dollar sign + ($) before the name of the variable.

    + + <!--#set var="modified" value="$LAST_MODIFIED" --> + + +

    To put a literal dollar sign into the value of your + variable, you need to escape the dollar sign with a + backslash.

    + + <!--#set var="cost" value="\$100" --> + + +

    Finally, if you want to put a variable in the midst of a + longer string, and there's a chance that the name of the + variable will run up against some other characters, and thus be + confused with those characters, you can place the name of the + variable in braces, to remove this confusion. (It's hard to + come up with a really good example of this, but hopefully + you'll get the point.)

    + + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> + +
    + +
    +Conditional expressions + +

    Now that we have variables, and are able to set and compare + their values, we can use them to express conditionals. This + lets SSI be a tiny programming language of sorts. + mod_include provides an if, + elif, else, endif + structure for building conditional statements. This allows you + to effectively generate multiple logical pages out of one + actual page.

    + +

    The structure of this conditional construct is:

    + + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +
    + +

    A test_condition can be any sort of logical + comparison - either comparing values to one another, or testing + the ``truth'' of a particular value. (A given string is true if + it is nonempty.) For a full list of the comparison operators + available to you, see the mod_include + documentation. Here are some examples of how one might use this + construct.

    + +

    In your configuration file, you could put the following + line:

    + + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +
    + +

    This will set environment variables ``Mac'' and + ``InternetExplorer'' to true, if the client is running Internet + Explorer on a Macintosh.

    + +

    Then, in your SSI-enabled document, you might do the + following:

    + + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + Apologetic text goes here
    + <!--#else -->
    + Cool JavaScript code goes here
    + <!--#endif --> +
    + +

    Not that I have anything against IE on Macs - I just + struggled for a few hours last week trying to get some + JavaScript working on IE on a Mac, when it was working + everywhere else. The above was the interim workaround.

    + +

    Any other variable (either ones that you define, or normal + environment variables) can be used in conditional statements. + With Apache's ability to set environment variables with the + SetEnvIf directives, and other related directives, + this functionality can let you do some pretty involved dynamic + stuff without ever resorting to CGI.

    +
    +
    + +
    Conclusion + +

    SSI is certainly not a replacement for CGI, or other + technologies used for generating dynamic web pages. But it is a + great way to add small amounts of dynamic content to pages, + without doing a lot of extra work.

    +
    + +
    diff --git a/trunk/docs/manual/howto/ssi.xml.ja b/trunk/docs/manual/howto/ssi.xml.ja new file mode 100644 index 0000000000..9b19a6852f --- /dev/null +++ b/trunk/docs/manual/howto/ssi.xml.ja @@ -0,0 +1,481 @@ + + + + + + + + +How-To / $B%A%e!<%H%j%"%k(B + +Apache $B%A%e!<%H%j%"%k(B: Server Side Includes $BF~Lg(B + + +

    $B%5!<%P%5%$%I%$%s%/%k!<%I$K$h$C$F!"4{B8$N(B HTML +$B%I%-%e%a%s%H$KF0E*$J%3%s%F%s%D$rDI2C$9$k$3$H$,$G$-$^$9!#(B

    +
    + + + +
    SSI $B$H$O(B ? + +

    SSI (Server Side Includes) $B$O!"(BHTML + $B%Z!<%8Cf$KG[CV$5$l$k%G%#%l%/%F%#%V$G$"$j!"(B + $B%5!<%P$G%Z!<%8$rDs6!$9$k;~$KI>2A$5$l$^$9!#(BSSI $B$O!"(BCGI + $B%W%m%0%i%`$d$=$NB>$NF0E*$J5;=Q$GA4$F$N%Z!<%8$rDs6!$;$:$K!"(B + $BF0E*$K@8@.$5$l$?%3%s%F%s%D$r8=:_$N(B HTML $B%Z!<%8$K2C$($^$9!#(B

    + +

    $B$I$&$$$&>l9g$K(B SSI $B$r;H$$!"$I$&$$$&>l9g$K%W%m%0%i%`$G(B + $B%Z!<%8$r40A4$K@8@.$9$k$+$O!"%Z!<%8$N$&$A$I$NDxEY$,@EE*$G$"$j!"(B + $B%Z!<%8$,Ds6!$5$l$k$?$S$K:F7W;;$9$kI,MW$,$I$NDxEY$"$k$+$GDL>o$O7hDj$7$^$9!#(B + SSI $B$O8=:_;~9o$N$h$&$J>.$5$$>pJs$r2C$($k$K$O$&$C$F$D$1$NJ}K!$G$9!#(B + $B$7$+$7!"$=$N%Z!<%8$N$[$H$s$I$NItJ,$,Ds6!;~$K@8@.$5$l$k>l9g$O!"(B + $BB>$NJ}K!$rC5$9I,MW$,$"$j$^$9!#(B

    +
    + +
    +SSI $B$r5v2D$9$k$?$a$N%5!<%P$N@_Dj(B + +

    $B%5!<%P$G(B SSI $B$r5v2D$9$k$K$O!"(Bhttpd.conf + $B%U%!%$%k$^$?$O(B .htaccess + $B%U%!%$%k$K + + Options +Includes + + +

    $B$3$N;XDj$O!"%U%!%$%k$r(B SSI + $B%G%#%l%/%F%#%V$G2r@O$5$;$k$3$H$r5v2D$9$k$H$$$&$3$H$r(B Apache + $B$KEA$($^$9!#$[$H$s$I$N@_Dj$G$O$*8_$$$r>e=q$-$G$-$k!"J#?t$N(B + Options $B$,$"$k$3$H$K(B + $BCm0U$7$F$/$@$5$$!#$*$=$i$/!"@_Dj$,:G8e$KI>2A$5$l$k$3$H$r(B + $BJ]>Z$5$l$k$?$a$K!"(BSSI $B$r;HMQ$7$?$$%G%#%l%/%H%j$K(B Options + $B%G%#%l%/%F%#%V$rE,MQ$9$kI,MW$,$"$k$G$7$g$&!#(B

    + +

    $BA4$F$N%U%!%$%k$,(B SSI + $B%G%#%l%/%F%#%V$G2r@O$5$l$k$H$$$&$o$1$G$O$"$j$^$;$s!#(B + $B$I$N%U%!%$%k$,2r@O$5$l$k$+$r(B Apache $B$KEA$($kI,MW$,$"$j$^$9!#(B + $B$3$l$r9T$J$&$K$OFs$DJ}K!$,$"$j$^$9!#(B + $B.shtml + $B$N$h$&$JFCJL$J%U%!%$%k3HD%;R$r;}$D%U%!%$%k$r2r@O$9$k$h$&(B + Apache $B$KEA$($k$3$H$,$G$-$^$9(B:

    + + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +
    + +

    $B$3$NJ}K!$N7gE@$O!"$b$78=:_$N%Z!<%8$K(B SSI $B%G%#%l%/%F%#%V$r2C$($?$$>l9g!"(B + $B$=$l$i$N%G%#%l%/%F%#%V$,.shtml $B3HD%;R$K$9$k$?$a!"$=$N%Z!<%8$NL>A0$H!"(B + $B$=$N%Z!<%8$X$NA4$F$N%j%s%/$rJQ99$7$J$1$l$P$J$i$J$$$3$H$G$9!#(B

    + +

    $B$b$&0l$D$NJ}K!$O!"(BXBitHack + $B%G%#%l%/%F%#%V$r;HMQ$9$k$3$H$G$9(B:

    + + XBitHack on + + +

    XBitHack + $B$O!"%U%!%$%k$Nl9g!"(B + SSI $B%G%#%l%/%F%#%V$K$h$j2r@O$9$k$3$H$r(B Apache $B$KEA$($^$9!#(B + $B=>$C$F!"(BSSI $B%G%#%l%/%F%#%V$r8=:_$N%Z!<%8$K2C$($k$?$a$K$O!"(B + $B%U%!%$%kL>$rJQ99$7$J$/$F$b$h$/!"C1$K(B chmod + $B$r;HMQ$7$F%U%!%$%k$r + + chmod +x pagename.html + + +

    $B9T$J$&$Y$-$G$O$J$$$3$H$K4X$9$kC;$$%3%a%s%H!#;~!9C/$+$,!"A4$F$N(B + .html $B%U%!%$%k$r(B SSI $B$G2r@O$9$k$h$&(B Apache $B$KEA$($l$P!"(B + $B$o$6$o$6(B .shtml $B$H$$$&%U%!%$%kL>$K$9$kI,MW$,$J$$$H$$$C$F(B + $BA&$a$k$N$r8+$k$3$H$G$7$g$&!#$3$&$$$&?M$?$A$O!"$*$=$i$/(B + XBitHack + $B$K$D$$$FJ9$$$?$3$H$,$J$$$N$G$7$g$&!#(B + $B$3$NJ}K!$K$D$$$FCm0U$9$k$3$H$O!"$?$H$((B SSI + $B%G%#%l%/%F%#%V$rA4$/4^$^$J$$>l9g$G$b!"(BApache $B$,%/%i%$%"%s%H$K(B + $BAw$kA4$F$N%U%!%$%k$r:G8e$^$GFI$_9~$^$;$k$3$H$K$J$j$^$9!#(B + $B$3$NJ}K!$O$+$J$j=hM}$rCY$/$9$k$b$N$G$"$j!"NI$/$J$$%"%$%G%"$G$9!#(B

    + +

    $B$b$A$m$s!"(BWindows $B$G$O$=$N$h$&$J/$7@)8B$5$l$F$$$^$9!#(B

    + +

    $B%G%U%)%k%H$N@_Dj$G$O!"(BApache $B$O(B SSI $B%Z!<%8$K$D$$$F:G=*JQ99;~9o$d(B + $B%3%s%F%s%D$ND9$5$r(B HTTP $B%X%C%@$KAw$j$^$;$s!#(B + $BF0E*$J%3%s%F%s%D$G$"$k$?$a!"$=$l$i$NCM$r7W;;$9$k$N$,Fq$7$$$+$i$G$9!#(B + $B$3$N$?$a%I%-%e%a%s%H$,%-%c%C%7%e$5$l$J$/$J$j!"(B + $B7k2L$H$7$F%/%i%$%"%s%H$N@-G=$,CY$/$J$C$?$h$&$K46$8$5$;$k$3$H$K$J$j$^$9!#(B + $B$3$l$r2r7h$9$kJ}K!$,Fs$D$"$j$^$9(B:

    + +
      +
    1. XBitHack Full $B@_Dj$r;HMQ$9$k!#(B + $B$3$N@_Dj$K$h$j!"$b$H$b$HMW5a$5$l$?%U%!%$%k$N;~9o$r;2>H$7!"(B + $BFI$_9~$^$l$k%U%!%$%k$NJQ99;~9o$rL5;k$7$F:G=*JQ99;~9o$r7hDj$9$k$h$&(B + Apache $B$KEA$($^$9!#(B
    2. + +
    3. mod_expires + $B$GDs6!$5$l$F$$$k%G%#%l%/%F%#%V$r;HMQ$7$F!"(B + $B%U%!%$%k$,L58z$K$J$k;~9o$rL@<($7$^$9!#$3$l$K$h$j!"(B + $B%V%i%&%6$H%W%m%-%7$K%-%c%C%7%e$,M-8z$G$"$k$3$H$rDLCN$7$^$9!#(B
    4. +
    +
    + +
    $B4pK\E*$J(B SSI $B%G%#%l%/%F%#%V(B + +

    SSI $B%G%#%l%/%F%#%V$O0J2<$NJ8K!$G5-=R$7$^$9(B:

    + + <!--#element attribute=value attribute=value ... --> + + +

    HTML $B$N%3%a%s%H$N$h$&$J=q<0$r$7$F$$$k$N$G!"$b$7(B SSI + $B$r@5$7$/F0:n2DG=$K$7$J$1$l$P!"%V%i%&%6$O$=$l$rL5;k$9$k$G$7$g$&!#(B + $B$7$+$7!"(BHTML $B%=!<%9Cf$G$O8+$($^$9!#$b$7(B SSI $B$r@5$7$/@_Dj$7$?$J$i!"(B + $B%G%#%l%/%F%#%V$O$=$N7k2L$HCV$-49$($i$l$^$9!#(B

    + +

    element $B$O$?$/$5$s$"$k$b$N$+$i0l$D;XDj$9$k$3$H$,$G$-$^$9!#(B + $B;XDj$G$-$k$b$N$NBgB??t$K$D$$$F$O!"/$7>\$7$/@bL@$7$^$9!#(B + $B$3$3$G$O!"(BSSI $B$G9T$J$&$3$H$,$G$-$kNc$r$$$/$D$+<($7$^$9!#(B

    + +
    $B:#F|$NF|IU(B + + + <!--#echo var="DATE_LOCAL" --> + + +

    echo $BMWAG$OC1$KJQ?t$NCM$r=PNO$7$^$9!#(B + CGI $B%W%m%0%i%`$KMxMQ2DG=$J4D6-JQ?t$NA4$F$N(B + $B%;%C%H$r4^$`B?$/$NI8=`JQ?t$,$"$j$^$9!#$^$?!"(Bset + $BMWAG$rMQ$$$k$3$H$G!"FH<+$NJQ?t$rDj5A$9$k$3$H$,$G$-$^$9!#(B +

    + +

    $B=PNO$5$l$kF|IU$N=q<0$,9%$-$G$O$J$$>l9g!"$=$N=q<0$r=$@5$9$k$?$a$K!"(B + config $BMWAG$K(B timefmt + $BB0@-$r;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + + + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +
    +
    + +
    $B%U%!%$%k$NJQ99F|(B + + + This document last modified <!--#flastmod file="index.html" --> + + +

    $B$3$NMWAG$b(B timefmt + $B%U%)!<%^%C%H$N@_Dj$K=>$$$^$9!#(B

    +
    + +
    CGI $B%W%m%0%i%`$N7k2L$r<h$j9~$`(B + +

    $B$3$l$O!"A4$F$N?M$N$*5$$KF~$j$G$"$k(B ``$B%R%C%H%+%&%s%?(B'' $B$N$h$&$J(B + CGI $B%W%m%0%i%`$N7k2L$r=PNO$9$k(B SSI + $B$N$h$j0lHLE*$J;HMQ$N$&$A$N0l$D$G$9!#(B

    + + + <!--#include virtual="/cgi-bin/counter.pl" --> + + +
    +
    + +
    +$BDI2C$NNc(B + +

    $B0J2<$O!"(BSSI $B$r;HMQ$7$F(B HTML + $B%I%-%e%a%s%H$K$*$$$F$G$-$k$3$H$N$$$/$D$+$NFCJL$JNc$G$9!#(B

    + +
    $B$$$D$3$N%I%-%e%a%s%H$O=$@5$5$l$?$N$+(B +? + +

    $B@h$K!"%I%-%e%a%s%H$,:G8e$KJQ99$5$l$?$N$O$$$D$+$r(B + $B%f!<%6$KDLCN$9$k$?$a$K(B SSI $B$r;HMQ$9$k$3$H$,$G$-$k$3$H$r=R$Y$^$7$?!#(B + $B$7$+$7$J$,$i!"e=R$N$h$&$K!"(B + SSI $B$r@5$7$/F0:n2DG=$K$7$F$*$/I,MW$,$"$j$^$9!#(B

    + + <!--#config timefmt="%A %B %d, %Y" -->
    + This file last modified <!--#flastmod file="ssi.shtml" --> +
    + +

    $B$b$A$m$s!"(Bssi.shtml + $B$NItJ,$r$HCV$-49$($kI,MW$,$"$j$^$9!#(B + $B$b$7!"$"$i$f$k%U%!%$%k$KD%$k$3$H$,$G$-$k0lHLE*$J%3!<%I$rC5$7$F$$$k$J$i!"(B + $B$3$l$OITJX$G$"$k$+$b$7$l$^$;$s!#$*$=$i$/$=$N>l9g$O!"(B + $B$=$&$9$kBe$o$j$KJQ?t(B LAST_MODIFIED + $B$r;HMQ$7$?$$$H9M$($k$G$7$g$&(B:

    + + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +
    + +

    timefmt + $B=q<0$K$D$$$F$N$h$j>\:Y$K$D$$$F$O!"$*9%$_$N8!:w%5%$%H$K9T$-!"(B + strftime $B$G8!:w$7$F$_$F$/$@$5$$!#J8K!$OF1$8$G$9!#(B

    +
    + + + +
    + +
    +$BB>$K2?$,@_Dj$G$-$k$N$+(B ? + +

    $B;~9o=q<0$r(B config $B$G@_Dj$G$-$k$3$H$K2C$($F!"(B + $B99$KFs$D(B config $B$G@_Dj$9$k$3$H$,$G$-$^$9!#(B

    + +

    $BDL>o!"(BSSI $B%G%#%l%/%F%#%V$G2?$+$,$&$^$/$$$+$J$$$H$-$O!"(B + $B + + [an error occurred while processing this directive] + + +

    $B$3$N%a%C%;!<%8$rB>$N$b$N$K$7$?$$>l9g!"(Bconfig + $BMWAG$N(B errmsg $BB0@-$GJQ99$9$k$3$H$,$G$-$^$9(B:

    + + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> + + +

    $B$*$=$i$/!"%(%s%I%f!<%6$O$3$N%a%C%;!<%8$r7h$7$F8+$k$3$H$O$"$j$^$;$s!#(B + $B$J$<$J$i!"$=$N%5%$%H$,@8$-$?>uBV$K$J$kA0$K(B SSI $B%G%#%l%/%F%#%V$K4X$9$k(B + $BA4$F$NLdBj$r2r7h$7$F$$$k$O$:$@$+$i$G$9!#(B($B$=$&$G$9$h$M(B?)

    + +

    $B$=$7$F!"(Bconfig $B$K$*$$$F(B sizefmt + $BB0@-$r;HMQ$9$k$3$H$G!"(B + $BJV$5$l$k%U%!%$%k%5%$%:$N=q<0$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + $B%P%$%H?t$K$O(B bytes $B$r!"E,Ev$K(B Kb $B$d(B Mb + $B$KC;=L$5$;$k$K$O(B abbrev $B$r;XDj$9$k$3$H$,$G$-$^$9!#(B

    +
    + +
    + $B%3%^%s%I$N<B9T(B + +

    $B:#8e?t%v7n$N$&$A$K!">.$5$J(B CGI $B%W%m%0%i%`$H(B SSI + $B$r;HMQ$9$k5-;v$r=P$7$?$$$H9M$($F$$$^$9!#$3$3$G$O$=$l$H$OJL$K!"(B + exec $BMWAG$K$h$C$F9T$J$&$3$H$,$G$-$k$3$H$r<($7$^$9!#(B + SSI $B$K%7%'%k(B ($B@53N$K$O(B /bin/sh$B!#(BWin32 $B$J$i$P(B DOS $B%7%'%k(B) + $B$r;HMQ$7$F%3%^%s%I$r + + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +
    + +

    Windows $B>e$G$O!"(B

    + + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +
    + +

    Windows $B>e$G$O!"$3$N%G%#%l%/%F%#%V$K$h$C$F$$$/$D$+$N4qL/$J(B + $B=q<0$K5$$E$/$G$7$g$&!#$J$<$J$i(B dir $B$N=PNO$,J8;zNs(B + ``<dir>'' $B$r4^$_!"%V%i%&%6$r:.Mp$5$;$k$+$i$G$9!#(B

    + +

    $B$3$N5!G=$OHs>o$K4m81$G$"$j!"$I$s$J%3!<%I$G$b(B exec + $B%?%0$KKd$a9~$^$l$F$7$^$($Pu67$K$"$k$J$i$P!"(B + $B$3$N5!G=$r3NOptions + $B%G%#%l%/%F%#%V$N(B IncludesNOEXEC $B0z?t$r;XDj$9$k$3$H$G!"(B + SSI $B$O5v2D$9$k$1$l$I(B exec + $B5!G=$O5v2D$7$J$$$h$&$K$9$k$3$H$,$G$-$^$9!#(B

    +
    + +
    +$B9bEY$J(B SSI $B%F%/%K%C%/(B + +

    $B%3%s%F%s%D$r=PNO$9$k$3$H$K2C$(!"(BApache SSI $B$OJQ?t$r@_Dj$7!"(B + $B$=$7$FHf3S$H>r7oJ,4t$K$=$NJQ?t$r;HMQ$G$-$k5!G=$rDs6!$7$F$$$^$9!#(B +

    + +
    $B7Y9p(B + +

    $B$3$N5-;v$G=R$Y$?BgItJ,$N5!G=$O!"(BApache 1.2 + $B0J9_$r;HMQ$7$F$$$k>l9g$N$_MxMQ2DG=$G$9!#$b$A$m$s!"$b$7(B Apache 1.2 + $B0J9_$r;HMQ$7$F$J$$>l9g!"D>$A$K%"%C%W%0%l!<%I$9$kI,MW$,$"$j$^$9!#(B + $B$5$!!":#$=$l$r9T$J$$$J$5$$!#$=$l$^$GBT$C$F$$$^$9!#(B

    +
    + +
    $BJQ?t$r@_Dj$9$k(B + +

    set $B%G%#%l%/%F%#%V$r;HMQ$7$F!"(B + $B8e$G;HMQ$9$k$?$a$KJQ?t$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + $B$3$l$O8e$N@bL@$GI,MW$K$J$k$N$G!"$3$3$G$=$l$K$D$$$F=R$Y$F$$$^$9!#(B + $BJ8K!$O0J2<$N$H$*$j$G$9(B:

    + + <!--#set var="name" value="Rich" --> + + +

    $B$3$N$h$&$KC1=c$KJ8;z$I$*$j$K@_Dj$9$k$3$H$K2C$(!"(B + $B4D6-JQ?t(B$B$d>e5-$NJQ?t(B + ($BNc$($P(B LAST_MODIFIED $B$N$h$&$J(B) + $B$r4^$`B>$N$"$i$f$kJQ?t$rCM$r@_Dj$9$k$N$K;HMQ$9$k$3$H$,$G$-$^$9!#(B + $BJQ?tL>$NA0$K%I%k5-9f(B ($) $B$r;HMQ$9$k$3$H$G!"(B + $B$=$l$,%j%F%i%kJ8;zNs$G$O$J$/$FJQ?t$G$"$k$3$H$r<($7$^$9!#(B

    + + <!--#set var="modified" value="$LAST_MODIFIED" --> + + +

    $B%I%k5-9f(B ($) $B$rJ8;z$H$7$FJQ?t$NCM$KF~$l$k$K$O!"(B + $B%P%C%/%9%i%C%7%e$K$h$C$F%I%k5-9f$r%(%9%1!<%W$9$kI,MW$,$"$j$^$9!#(B

    + + <!--#set var="cost" value="\$100" --> + + +

    $B:G8e$K$J$j$^$9$,!"D9$$J8;zNs$NCf$KJQ?t$rCV$-$?$$>l9g$G!"(B + $BJQ?tL>$,B>$NJ8;z$H$V$D$+$k2DG=@-$,$"$j!"(B + $B$=$l$i$NJ8;z$K$D$$$F:.Mp$7$F$7$^$&>l9g!"$3$N:.Mp$r$rCf3g8L$G0O$`$3$H$,$G$-$^$9(B + ($B$3$l$K$D$$$F$NNI$$Nc$r<($9$N$OFq$7$$$N$G$9$,!"(B + $B$*$=$i$/J,$+$C$F$$$?$@$1$k$G$7$g$&(B)$B!#(B +

    + + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> + +
    + +
    +$B>r7o<0(B + +

    $B$5$F!"JQ?t$r;}$C$F$$$F!"(B + $B$=$l$i$NCM$r@_Dj$7$FHf3S$9$k$3$H$,$G$-$k$N$G$9$+$i!"(B + $B>r7o$rI=$9$?$a$K$=$l$i$r;HMQ$9$k$3$H$,$G$-$^$9!#$3$l$K$h$j(B + SSI $B$O$"$k.$5$J%W%m%0%i%_%s%08@8l$K$J$C$F$$$^$9!#(B + mod_include $B$O>r7o$rI=8=$9$k$?$a$K(B if, + elif, else, endif + $B9=B$$rDs6!$7$F$$$^$9!#$3$l$K$h$C$F!"(B + $B0l$D$N + +

    $B>r7o9=B$$O0J2<$N$H$*$j$G$9(B:

    + + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +
    + +

    test_condition + $B$O$"$i$f$k2A$7$^$9(B + ($B6u$G$J$$$J$iM?$($i$l$?J8;zNs$O??$G$9(B)$B!#(B + $BMxMQ2DG=$JHf3S1i;;;R$NA4$F$N%j%9%H$K$D$$$F$O!"(B + mod_include $B%I%-%e%a%s%F!<%7%g%s$r;2>H$7$F$/$@$5$$!#(B + $B$3$3$G$O!"$3$N9=B$$r$I$&;HMQ$9$k$+$NNc$r$$$/$D$+<($7$^$9!#(B

    + +

    $B@_Dj%U%!%$%k$G + + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +
    + +

    $B$3$l$O%/%i%$%"%s%H$,(B Macintosh + $B>e$G%$%s%?!<%M%C%H%(%/%9%W%m!<%i$,F0$$$F$$$k>l9g!"4D6-JQ?t(B + ``Mac'' $B$H(B ``InternetExplorer'' $B$r??$H@_Dj$7$^$9!#(B

    + +

    $B + + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + Apologetic text goes here
    + <!--#else -->
    + Cool JavaScript code goes here
    + <!--#endif --> +
    + +

    Mac $B>e$N(B IE $B$KBP$7$F2?$+;W$&$H$3$m$,$"$k$o$1$G$"$j$^$;$s!#(B + $BB>$G$Oe$N(B IE + $B$Ge$NNc$O$=$N;CDjE*$JBP=hJ}K!$G$9!#(B

    + +

    $BB>$N$I$s$JJQ?t(B ($B$"$J$?$,Dj5A$9$k$b$N!"(B + $B$^$?$OIaDL$N4D6-JQ?t$N$$$:$l$+(B) $B$b!">r7oJ8$K;HMQ$9$k$3$H$,$G$-$^$9!#(B + Apache $B$O(B SetEnvIf $B%G%#%l%/%F%#%V$dB>$N4XO"(B + $B%G%#%l%/%F%#%V$r;HMQ$7$F4D6-JQ?t$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + $B$3$N5!G=$K$h$j!"(BCGI + $B$KMj$k$3$H$J$/$+$J$jJ#;($JF0E*$J$3$H$r$5$;$k$3$H$,$G$-$^$9!#(B

    +
    +
    + +
    $B=*$o$j$K(B + +

    SSI $B$O3N$+$K(B CGI + $B$dF0E*$J%&%'%V%Z!<%8$r@8@.$9$kB>$N5;=Q$KBe$o$k$b$N$G$O$"$j$^$;$s!#(B + $B$7$+$7!"$?$/$5$s$NM>J,$J:n6H$r$;$:$K!"(B + $B>/NL$NF0E*$J%3%s%F%s%D$r2C$($k$K$O$9$0$l$?J}K!$G$9!#(B

    +
    + +
    diff --git a/trunk/docs/manual/howto/ssi.xml.ko b/trunk/docs/manual/howto/ssi.xml.ko new file mode 100644 index 0000000000..a7e2ee81f0 --- /dev/null +++ b/trunk/docs/manual/howto/ssi.xml.ko @@ -0,0 +1,428 @@ + + + + + + + + +How-To / Tutorials + +¾ÆÆÄÄ¡ ÅõÅ丮¾ó: Server Side Includes ¼Ò°³ + + +

    Server-side includes¸¦ »ç¿ëÇÏ¿© HTML ¹®¼­¿¡ µ¿ÀûÀÎ ³»¿ëÀ» +Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    +
    + + + +
    SSI°¡ ¹«¾ùÀΰ¡? + +

    SSI (Server Side Includes)´Â HTML ÆäÀÌÁö¿¡ »ç¿ëÇÏ´Â Áö½Ã¾î·Î, + ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ¶§ ¼­¹ö°¡ ó¸®ÇÑ´Ù. SSI¸¦ »ç¿ëÇϸé CGI + ÇÁ·Î±×·¥À̳ª ´Ù¸¥ µ¿ÀûÀÎ ±â¼ú·Î ÆäÀÌÁö Àüü¸¦ ¸¸µé¾î¼­ + ¼­ºñ½ºÇÏÁö ¾Ê°íµµ HTML ÆäÀÌÁö¿¡ µ¿ÀûÀ¸·Î »ý¼ºÇÑ ³»¿ëÀ» Ãß°¡ÇÒ + ¼ö ÀÖ´Ù.

    + +

    SSI¸¦ »ç¿ëÇÒÁö ¾Æ´Ï¸é ÇÁ·Î±×·¥À¸·Î ÆäÀÌÁö Àüü¸¦ »ý¼ºÇÒÁö + °áÁ¤Àº ÆäÀÌÁö¿¡¼­ Á¤ÀûÀÎ ºÎºÐÀÌ ¸¹ÀºÁö¿Í ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÒ + ¶§¸¶´Ù ¾î´ÀÁ¤µµ¸¦ ´Ù½Ã °è»êÇؾßÇÒÁö¿¡ ´Þ·È´Ù. SSI´Â ÇöÀç + ½Ã°£°ú °°ÀÌ ÀûÀº Á¤º¸¸¦ Ãß°¡Çϴµ¥ ÁÁ´Ù. ±×·¯³ª ÆäÀÌÁö¸¦ + ¼­ºñ½ºÇÒ¶§ ÆäÀÌÁöÀÇ ´ëºÎºÐÀ» »ý¼ºÇØ¾ß ÇÑ´Ù¸é ´Ù¸¥ ¹æ¹ýÀ» + ã¾ÆºÁ¾ß ÇÑ´Ù.

    +
    + +
    +SSI°¡ °¡´ÉÇϵµ·Ï ¼­¹ö ¼³Á¤Çϱâ + +

    ¼­¹ö°¡ SSI¸¦ ó¸®ÇÏ·Á¸é httpd.conf ÆÄÀÏÀ̳ª + .htaccess ÆÄÀÏ¿¡¼­ ´ÙÀ½ Áö½Ã¾î¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + + Options +Includes + + +

    ±×·¯¸é ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ¼³Á¤¿¡´Â + º¸Åë ¿©·¯ Options Áö½Ã¾î°¡ + ÀÖ°í, ÀÌ Áö½Ã¾îµéÀº ¼­·Î µ¤¾î½á¼­ ¹«È¿·Î ¸¸µé´Ù. ±×·¡¼­ + Áö½Ã¾î¸¦ ¸Ç¸¶Áö¸·¿¡ ó¸®ÇϱâÀ§ÇØ º¸Åë SSI¸¦ ¿øÇϴ ƯÁ¤ + µð·ºÅ丮¿¡¼­ Options¸¦ »ç¿ëÇÑ´Ù.

    + +

    ¸ðµç ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¾ÆÆÄÄ¡¿¡°Ô + ¾î¶² ÆÄÀÏÀ» ó¸®ÇÒÁö ¾Ë·ÁÁà¾ß ÇÑ´Ù. µÎ°¡Áö ¹æ¹ýÀÌ ÀÖ´Ù. + Çϳª´Â ´ÙÀ½°ú °°Àº Áö½Ã¾î·Î .shtml°ú °°Àº ƯÁ¤ + ÆÄÀÏ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏÀ» ó¸®ÇÏ´Â ¹æ¹ýÀÌ´Ù.

    + + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +
    + +

    ÀÌ ¹æ¹ýÀÇ ´ÜÁ¡Àº ÀÌ¹Ì ÀÖ´Â ÆäÀÌÁö¿¡ SSI Áö½Ã¾î¸¦ Ãß°¡ÇÏ´Â + °æ¿ì SSI Áö½Ã¾î¸¦ ó¸®ÇϱâÀ§ÇØ .shtml È®ÀåÀÚ¸¦ + ºÎ¿©Çϱ⶧¹®¿¡ ÆÄÀϸí°ú ÀÌ ÆäÀÌÁöÀÇ ¸ðµç ¸µÅ©¸¦ º¯°æÇØ¾ß + ÇÏ´Â Á¡ÀÌ´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº XBitHack + Áö½Ã¾î¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù.

    + + XBitHack on + + +

    XBitHack´Â + ½ÇÇà±ÇÇÑÀÌ ÀÖ´Â ÆÄÀÏ¿¡¼­ SSI Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ ÀÌ¹Ì + ÀÖ´Â ÆäÀÌÁö¿¡ SSI Áö½Ã¾î¸¦ Ãß°¡ÇÑ´Ù¸é ÆÄÀϸíÀ» º¯°æÇÏÁö + ¾Ê°í chmod·Î ÆÄÀÏ¿¡ ½ÇÇà±ÇÇÑÀ» ÁÖ¸é µÈ´Ù.

    + + chmod +x pagename.html + + +

    ÇÏÁö ¸»¾Æ¾ß ÇÒ °Í Çϳª. °¡²û .shtml ÆÄÀÏ¸í¿¡ + °ñÄ¡¸¦ ¾ÎÁö¸»°í ¸ðµç .html ÆÄÀÏÀ» SSI ó¸®Ç϶ó°í + Ãæ°íÇÏ´Â »ç¶÷ÀÌ ÀÖ´Ù. ÀÌ »ç¶÷µéÀº ¾Æ¸¶µµ XBitHack¿¡ ´ëÇØ ¸ð¸£´Â + °Í °°´Ù. ¸í½ÉÇÒ Á¡Àº ÀÌ·¸°Ô ÇÏ¸é ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡ SSI Áö½Ã¾î°¡ + ¾ø´õ¶óµµ Ŭ¶óÀ̾ðÆ®·Î º¸³»´Â ¸ðµç ÆÄÀÏÀ» »ìÆìºÁ¾ß ÇÑ´Ù´Â + °ÍÀÌ´Ù. ¼º´ÉÀÌ ¸Å¿ì ´À·ÁÁú ¼ö ÀÖÀ¸¸ç, ÁÁÀº »ý°¢ÀÌ ¾Æ´Ï´Ù.

    + +

    ¹°·Ð À©µµ¿ìÁî¿¡¼­´Â ½ÇÇà±ÇÇÑÀ̶õ °ÍÀÌ ¾ø±â¶§¹®¿¡ ÈÄÀÚ¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    ³»¿ëÀÌ µ¿ÀûÀÌ¿©¼­ °è»êÇϱ⠾î·Æ±â¶§¹®¿¡ ¾ÆÆÄÄ¡ ±âº» ¼³Á¤Àº + SSI ÆäÀÌÁöÀÇ ÃÖ±Ù¼öÁ¤ÀÏ°ú content length HTTP Çì´õ¸¦ º¸³»Áö + ¾Ê´Â´Ù. ±×·¡¼­ ¹®¼­¸¦ ij½¬ÇÏÁö ¸øÇÏ°í Ŭ¶óÀ̾ðÆ®°¡ ´À³¢´Â + ¼º´ÉÀÌ ¶³¾îÁø´Ù. µÎ°¡Áö ÇØ°á¹æ¹ýÀÌ ÀÖ´Ù.

    + +
      +
    1. XBitHack Full ¼³Á¤Àº »ç¿ëÇÑ´Ù. ±×·¯¸é + ¾ÆÆÄÄ¡´Â Æ÷ÇÔÇÏ´Â(include) ÆÄÀϵéÀÇ ¼öÁ¤ÀÏÀº ¹«½ÃÇÑü + ¿ø·¡ ¿äûÇÑ ÆÄÀÏÀÇ ³¯Â¥¸¸ º¸°í ÃÖ±Ù¼öÁ¤ÀÏÀ» ¾Ë¾Æ³½´Ù.
    2. + +
    3. mod_expires¿¡ ÀÖ´Â Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ÆÄÀÏ¿¡ Á÷Á¢ ¸¸±âÀÏÀ» ¼³Á¤ÇÏ¸é ºê¶ó¿ìÀú¿Í ÇÁ·Ï½Ã°¡ ¹®¼­¸¦ + ij½¬ÇÒ ¼ö ÀÖ´Ù.
    4. +
    +
    + +
    ±âº» SSI Áö½Ã¾î + +

    SSI Áö½Ã¾îÀÇ »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.

    + + <!--#element attribute=value attribute=value ... --> + + +

    HTML ÁÖ¼®°°ÀÌ »ý°å±â¶§¹®¿¡ SSI ±â´ÉÀ» °¡µ¿ÇÏÁö ¾Ê¾Æµµ + HTML ¼Ò½º¿¡´Â ³ª¿ÀÁö¸¸ ºê¶ó¿ìÀú´Â ¹«½ÃÇÑ´Ù. SSI¸¦ ¿Ã¹Ù·Î + ¼³Á¤Çϸé Áö½Ã¾î¸¦ °á°ú°ªÀ¸·Î ¹Ù²Û´Ù.

    + +

    element´Â ´ÙÀ½Áß Çϳª´Ù. ´ÙÀ½ ȸ¿¡ ´õ ÀÚ¼¼È÷ ¼³¸íÇÒ °ÍÀÌ´Ù. + Áö±ÝÀº SSI·Î ÇÒ ¼ö ÀÖ´Â ¸î°¡Áö ¿¹¸¦ º¸ÀδÙ

    + +
    ¿À´Ã ³¯Â¥ + + + <!--#echo var="DATE_LOCAL" --> + + +

    echo element´Â º¯¼ö°ªÀ» ±×´ë·Î Ãâ·ÂÇÑ´Ù. + CGI ÇÁ·Î±×·¥¿¡ Á¦°øÇϴ ȯ°æº¯¼öµé ¿Ü¿¡µµ ¿©·¯ Ç¥ÁØ º¯¼ö°¡ + ÀÖ´Ù. ¶Ç, set element¸¦ »ç¿ëÇÏ¿© Á÷Á¢ º¯¼ö¸¦ + Á¤ÀÇÇÒ ¼öµµ ÀÖ´Ù.

    + +

    ³¯Â¥ Ãâ·Â Çü½ÄÀÌ ¸¶À½¿¡ µéÁö ¾Ê´Â´Ù¸é, ´ÙÀ½°ú °°ÀÌ + config elementÀÇ timefmt attribute¸¦ + »ç¿ëÇÑ´Ù.

    + + + <!--#config timefmt="%A %B %d, %Y" -->
    + Today is <!--#echo var="DATE_LOCAL" --> +
    +
    + +
    ÆÄÀÏÀÇ ¼öÁ¤ÀÏ + + + ÀÌ ¹®¼­´Â <!--#flastmod file="index.html" -->¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú´Ù + + +

    ÀÌ elementµµ timefmt Çü½Ä ¼³Á¤¿¡ ´Þ·È´Ù.

    +
    + +
    CGI ÇÁ·Î±×·¥ °á°ú¸¦ Æ÷ÇÔÇϱâ + +

    ÀϹÝÀûÀÎ SSI »ç¿ë¹ýÁß Çϳª·Î, ¸¹ÀÌµé ¾Ö¿ëÇÏ´Â ``¹æ¹®¼ö + Ä«¿îÅÍ'' °°Àº CGI ÇÁ·Î±×·¥ °á°ú¸¦ Ãâ·ÂÇÑ´Ù.

    + + + <!--#include virtual="/cgi-bin/counter.pl" --> + + +
    +
    + +
    +Ãß°¡ ¿¹Á¦ + +

    ´ÙÀ½Àº HTML ¹®¼­¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¸î°¡Áö SSI ¿¹Á¦´Ù.

    + +
    ÀÌ ¹®¼­°¡ ¾ðÁ¦ ¸¶Áö¸·À¸·Î +¼öÁ¤µÇ¾ú³ª? + +

    ¾Õ¿¡¼­ SSI¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ¿¡°Ô ¹®¼­ÀÇ ÃÖ±Ù¼öÁ¤ÀÏÀ» + ¾Ë¸± ¼ö ÀÖ´Ù°í ¸»Çß´Ù. ±×·¯³ª ½ÇÁ¦ ¹æ¹ýÀº ¾Ë·ÁÁÖÁö ¾Ê¾Ò´Ù. + ´ÙÀ½ Äڵ带 HTML ¹®¼­¿¡ »ç¿ëÇϸé ÆäÀÌÁö¿¡ ½Ã°£ ±â·ÏÀ» ³²±ä´Ù. + ¹°·Ð À§¿¡¼­ ¼³¸íÇÑ´ë·Î SSI°¡ ¿Ã¹Ù·Î ÀÛµ¿ÇØ¾ß ÇÑ´Ù.

    + + <!--#config timefmt="%A %B %d, %Y" -->
    + ÀÌ ¹®¼­´Â <!--#flastmod file="ssi.shtml" -->¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú´Ù; +
    + +

    ¹°·Ð ssi.shtml´ë½Å ¿øÇÏ´Â ½ÇÁ¦ ÆÄÀϸíÀ» + »ç¿ëÇÑ´Ù. ¾Æ¹« ÆäÀÌÁö¿¡¶óµµ ºÙ¿©³ÖÀ» ¼ö ÀÖ´Â ¹ü¿ëÄڵ带 + ¿øÇÑ´Ù¸é, ÆÄÀÏ¸í ´ë½Å LAST_MODIFIED º¯¼ö¸¦ + »ç¿ëÇÑ´Ù.

    + + <!--#config timefmt="%D" -->
    + This file last modified <!--#echo var="LAST_MODIFIED" --> +
    + +

    timefmt Çü½Ä¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸´Â °Ë»ö¿£Áø¿¡¼­ + strftimeÀ» ã¾ÆºÁ¶ó. ¹®¹ýÀº °°´Ù.

    +
    + + + +
    + +
    +ÀÌ¿Ü¿¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Â °ÍÀº? + +

    ½Ã°£ Çü½Ä config(¼³Á¤) ¿Ü¿¡ µÎ°¡Áö¸¦ ´õ + config(¼³Á¤)ÇÒ ¼ö ÀÖ´Ù.

    + +

    º¸Åë SSI Áö½Ã¾î°¡ À߸øµÇ¸é ´ÙÀ½°ú °°Àº ¹®±¸°¡ ³ª¿Â´Ù

    + + [an error occurred while processing this directive] + + +

    ÀÌ ¹®±¸¸¦ º¯°æÇÏ°í ½Í´Ù¸é config elementÀÇ + errmsg attribute¸¦ »ç¿ëÇÏ¿© º¯°æÇÑ´Ù.

    + + <!--#config errmsg="[It appears that you don't know how to use SSI]" --> + + +

    »çÀÌÆ®¸¦ ¼­ºñ½ºÇϱâ Àü¿¡ ¸ðµç SSI Áö½Ã¾î ¹®Á¦¸¦ ÇØ°áÇÏ¿© + »ç¿ëÀÚ°¡ ÀÌ·± ¹®±¸¸¦ º¸Áö ¾Ê±æ ¹Ù¶õ´Ù. (±×·¸Áö?)

    + +

    ±×¸®°í sizefmt attribute°¡ ¹ÝȯÇÏ´Â ÆÄÀÏÅ©±â + Çü½ÄÀ» config(¼³Á¤)ÇÒ ¼ö ÀÖ´Ù. ¹ÙÀÌÆ®·Î Å©±â¸¦ + º¸¿©ÁÖ·Á¸é bytes, ÀûÀýÈ÷ Kb³ª Mb·Î Å©±â¸¦ + º¸¿©ÁÖ·Á¸é abbrev¸¦ »ç¿ëÇÑ´Ù.

    +
    + +
    + ¸í·É¾î ½ÇÇàÇϱâ + +

    ³ª´Â ´ÙÀ½ ´Þ¿¡ ÀÛÀº CGI ÇÁ·Î±×·¥°ú SSI¸¦ °°ÀÌ »ç¿ëÇÏ´Â + ±ÛÀ» ¾µ ¿¹Á¤ÀÌ´Ù. Áö±ÝÀº exec element·Î ÇÒ + ¼ö ÀÖ´Â ´Ù¸¥ °ÍµéÀ» ¼³¸íÇÒ °ÍÀÌ´Ù. SSI´Â ½ÇÁ¦ ½©À» (Á¤È®È÷´Â + /bin/sh³ª Win32¸¦ »ç¿ëÇÑ´Ù¸é DOS ½©) »ç¿ëÇÏ¿© + ¸í·É¾î¸¦ ½ÇÇàÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½Àº µð·ºÅ丮 ¸ñ·ÏÀ» º¸¿©ÁØ´Ù.

    + + <pre>
    + <!--#exec cmd="ls" -->
    + </pre> +
    + +

    or, on Windows

    + + <pre>
    + <!--#exec cmd="dir" -->
    + </pre> +
    + +

    dir Ãâ·Â¿¡ ºê¶ó¿ìÀú°¡ È¥µ¿ÇÒ + ``<dir>'' ¹®ÀÚ¿­ÀÌ Æ÷ÇÔµÇÀֱ⶧¹®¿¡, + À©µµ¿ìÁî¿¡¼­ ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é °á°ú°¡ Á¶±Ý ÀÌ»óÇÒ °ÍÀÌ´Ù.

    + +

    ÀÌ ±â´ÉÀº exec ű׿¡ »ç¿ëÇÑ ¾î¶² ¸í·É¾î¶óµµ + ½ÇÇàÇÒ ¼ö Àֱ⶧¹®¿¡ ¸Å¿ì À§ÇèÇÏ´Ù. ``¹æ¸í·Ï''°ú °°ÀÌ »ç¿ëÀÚ°¡ + À¥ÆäÀÌÁö ³»¿ëÀ» ¼öÁ¤ÇÒ ¼ö Àִ ȯ°æÀ̶ó¸é, ÀÌ ±â´ÉÀ» Àý´ë·Î + »ç¿ëÇؼ± ¾ÈµÈ´Ù. Options Áö½Ã¾î¿¡ + IncludesNOEXEC ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÏ¿© SSI¸¦ Çã¿ëÇÏÁö¸¸ + exec ±â´ÉÀ» ¸·À» ¼ö ÀÖ´Ù.

    +
    + +
    +°í±Þ SSI ±â¹ý + +

    ³»¿ëÀ» Ãâ·ÂÇÏ´Â ±â´É ¿Ü¿¡ ¾ÆÆÄÄ¡ SSI´Â º¯¼ö ¼³Á¤ÀÌ °¡´ÉÇÏ°í, + ºñ±³¹®°ú Á¶°Ç¹®¿¡ ÀÌ º¯¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    °æ°í + +

    ÀÌ ±Û¿¡¼­ ¼³¸íÇÏ´Â ´ëºÎºÐÀÇ ±â´ÉÀº ¾ÆÆÄÄ¡ 1.2 ÀÌÈĺÎÅÍ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¹°·Ð, ¾ÆÆÄÄ¡ 1.2 ÀÌ»óÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é + ¾Æ¸¶µµ »¡¸® ¾÷±×·¹À̵åÇØ¾ß ÇÑ´Ù. Çضó. Áö±Ý Çضó. ±â´Ù¸± + °ÍÀÌ´Ù.

    +
    + +
    º¯¼ö ¼³Á¤ + +

    set Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ³ªÁß¿¡ »ç¿ëÇÒ º¯¼ö¸¦ + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¾ÕÀ¸·Î º¯¼ö°¡ ÇÊ¿äÇϱ⶧¹®¿¡ ¸ÕÀú ¼³¸íÇÑ´Ù. + ¹®¹ýÀº ´ÙÀ½°ú °°´Ù.

    + + <!--#set var="name" value="Rich" --> + + +

    ´ÙÀ½°ú °°ÀÌ °ªÀ» ¹®ÀÚ±×´ë·Î ¼³Á¤ÇÏÁö ¾Ê°í ȯ°æº¯¼ö³ª À§¿¡¼­ ¼³¸íÇÑ º¯¼ö(¿¹¸¦ + µé¾î, LAST_MODIFIED)¿Í °°ÀÌ ´Ù¸¥ º¯¼ö¸¦ »ç¿ëÇÏ¿© + º¯¼ö°ªÀ» ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù. À̶§ º¯¼ö¸í ¾Õ¿¡ ´Þ·¯ Ç¥½Ã($)¸¦ + ºÙ¿©¼­ ¹®ÀÚ¿­ÀÌ ¾Æ´Ñ º¯¼öÀÓÀ» Ç¥½ÃÇÑ´Ù.

    + + <!--#set var="modified" value="$LAST_MODIFIED" --> + + +

    º¯¼ö°ª¿¡ ´Þ·¯ ¹®ÀÚ¸¦ ±×´ë·Î ÀÔ·ÂÇÏ·Á¸é ´Þ·¯ Ç¥½Ã ¾Õ¿¡ + ¹é½½·¡½¬¸¦ »ç¿ëÇÑ´Ù.

    + + <!--#set var="cost" value="\$100" --> + + +

    ¸¶Áö¸·À¸·Î ±ä ¹®ÀÚ¿­ Áß°£¿¡ º¯¼ö¸¦ »ç¿ëÇϴµ¥ µÚ¿¡ ÀÖ´Â + ¹®ÀÚµµ º¯¼ö¸íÀ¸·Î ¿ÀÀÎÇÏ¿© È¥µ¿µÇ´Â °æ¿ì, º¯¼ö¸íÀ» ´ë°ýÈ£·Î + ¹­¾î¼­ È®½ÇÈ÷ ÇÑ´Ù. (ÁÁÀº ¿¹¸¦ ã±â ÈûµéÁö¸¸, ¹«½¼ ¸»ÀÎÁö + ÀÌÇØÇÏ±æ ¹Ù¶õ´Ù.)

    + + <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> + +
    + +
    +Á¶°Ç Ç¥Çö½Ä + +

    º¯¼ö¸¦ ¼³Á¤ÇÏ°í ºñ±³ÇÒ ¼ö ÀÖÀ¸´Ï Á¶°Ç¹®ÀÌ °¡´ÉÇÏ´Ù. ÀÌÁ¦ + SSI°¡ ÀÏÁ¾ÀÇ °£´ÜÇÑ ÇÁ·Î±×·¡¹Ö¾ð¾î°¡ µÈ´Ù. + mod_include´Â Á¶°Ç¹®À» ¸¸µå´Â if, + elif, else, endif + ±¸Á¶¸¦ Á¦°øÇÑ´Ù. ½ÇÁ¦ ÇÑ ÆäÀÌÁö·Î ¿©·¯ ³í¸®ÀûÀÎ ÆäÀÌÁö¸¦ + ¸¸µé ¼ö ÀÖ´Ù.

    + +

    Á¶°Ç¹® ±¸Á¶´Â ´ÙÀ½°ú °°´Ù.

    + + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +
    + +

    test_condition¿¡´Â ¾î¶² ³í¸®ºñ±³¶óµµ »ç¿ëÇÒ + ¼ö ÀÖ´Ù. °ªÀ» ´Ù¸¥ °ª°ú ºñ±³Çϰųª, ƯÁ¤ °ªÀÌ ``Âü''ÀÎÁö + °Ë»çÇÑ´Ù. (¹®ÀÚ¿­ÀÌ ºñ¾îÀÖÁö ¾ÊÀ¸¸é ÂüÀÌ´Ù.) »ç¿ë°¡´ÉÇÑ + ºñ±³ ¿¬»êÀÚ¸¦ ¸ðµÎ º¸·Á¸é, mod_include + ¹®¼­¸¦ Âü°íÇ϶ó. ´ÙÀ½Àº Á¶°Ç¹®À» »ç¿ëÇÑ ¸î°¡Áö ¿¹Á¦´Ù.

    + +

    ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½ ÁÙÀ» Ãß°¡ÇÑ´Ù.

    + + BrowserMatchNoCase macintosh Mac
    + BrowserMatchNoCase MSIE InternetExplorer +
    + +

    Ŭ¶óÀ̾ðÆ®°¡ ¸ÆŲÅä½Ã¿¡¼­ ½ÇÇàÇÏ´Â Internet Explorer¶ó¸é + ȯ°æº¯¼ö ``Mac''°ú ``InternetExplorer'' ¸ðµÎ ÂüÀ¸·Î ¼³Á¤ÇÑ´Ù.

    + +

    ±×¸®°í SSI ¹®¼­¿¡ ´ÙÀ½°ú °°ÀÌ Àû´Â´Ù.

    + + <!--#if expr="${Mac} && ${InternetExplorer}" -->
    + ¿©±â¿¡ »ç°ú¹®°¡ ³ª¿Â´Ù
    + <!--#else -->
    + ¿©±â¿¡ ¸ÚÁø JavaScript Äڵ尡 ³ª¿Â´Ù
    + <!--#endif --> +
    + +

    ³»°¡ ¸ÅŲÅä½Ã IE¿¡ ¹Ý°¨ÀÌ ÀÖ´Â °ÍÀº ¾Æ´Ï´Ù. ³ª´Â ´ÜÁö + Àú¹øÁÖ¿¡ ´Ù¸¥ °÷¿¡¼­´Â ¹®Á¦°¡ ¾ø´Â JavaScript Äڵ尡 ¸ÅŲÅä½Ã + IE¿¡¼­´Â µ¿ÀÛÇÏÁö ¾Ê¾Æ¼­ ¸î½Ã°£À» °í»ýÇß´Ù. À§´Â Àӽà + ÇØ°áÃ¥ÀÌ´Ù.

    + +

    (Á÷Á¢ Á¤ÀÇÇÏ¿´°Ç ÀÏ¹Ý È¯°æº¯¼öÀÌ°Ç) ¾î¶² º¯¼ö¶óµµ Á¶°Ç¹®¿¡ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¾Æ¶óÄ¡´Â SetEnvIf³ª ´Ù¸¥ °ü·Ã + Áö½Ã¾î·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö Àֱ⶧¹®¿¡ CGI ¾øÀ̵µ ¸ÚÁö°Ô + µ¿ÀûÀÎ ³»¿ëÀ» ¸¸µé ¼ö ÀÖ´Ù.

    +
    +
    + +
    °á·Ð + +

    SSI´Â È®½ÇÈ÷ CGI³ª µ¿ÀûÀÎ À¥ÆäÀÌÁö¸¦ »ý¼ºÇÏ´Â ´Ù¸¥ ±â¼úÀ» + ´ëüÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ¸¹Àº Ãß°¡ ÀÛ¾÷¾øÀÌ ÆäÀÌÁö¿¡ µ¿ÀûÀÎ + ³»¿ëÀ» Á¶±Ý Ãß°¡Çϱ⿡´Â ÈǸ¢ÇÑ ¹æ¹ýÀÌ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/howto/ssi.xml.meta b/trunk/docs/manual/howto/ssi.xml.meta new file mode 100644 index 0000000000..0427d2dcd3 --- /dev/null +++ b/trunk/docs/manual/howto/ssi.xml.meta @@ -0,0 +1,13 @@ + + + + ssi + /howto/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/images/apache_header.gif b/trunk/docs/manual/images/apache_header.gif new file mode 100644 index 0000000000000000000000000000000000000000..260e421bf4ad3f012db1746809cf4d2fdd5d8cc6 GIT binary patch literal 4084 zcmW+(X*ksT`~G~tvzTFw!C-8eLAF#gwy`%xA*GN`k~EB%kfyThbiS5^C|hM24A~MH zYuX28$zGAD&X82M6yV1I-oQ8!(89ezI2XreGf2SO9k?d~_izyI?d{FwauX91 zt8pNU0qz6FA`VDNKnf_m#z0B~QX7!UB{g!v{X{Uy22w5%0JapcCqcLrgbT7L(o`UA z2cJiP^vy2~1>T_G*PSN!v`Wv|pDypiovgZng>=KCV5JYzD*qsVMM#JOYzW#wHJ5|Z#CY;Vw0!3d3 zFKeQQ+dhJ=yr1Nu0(FCjgUc)LKYR>#P*8wg>g!Qt)HJoU)bW~{a$DlY#QlA!l+*-< zyV8)Bb}UKHUEp@o4RcU-gD2IqaRU~uXHT#fBPn=gb$7lsgL5R~(4SUcpKNbPuRBG= z?0+@TT01Irt(?P9smZBci72J?dEu=1!S8bJLY5b|3s06a+ils_->r4zc2=;N;fI;g zR^GFE%aj2CsciD;-w(X!AId=%9|rl7`R9;f*mG+yjwn^b#&msbt%0ooTe;?9I5Cay z1`Ey26LW+;=|nZ65#6M*2a(%*fY{H0!|`1ya`XMoTx_=cr#xz9Xg!@{* zyzSo4Bb5n@D_VP9B>F4JdpM$z(4qW(>wyo|`A;($9P!6+!g5&4FBLfiGuzc^s z2hAQh96?O|n1aR1EVV1RZ*(}y_7Od{nnB>OS5QGX2*BlhgRr&BJ2M_+3GSF9K!ZqNpA`JWtY5|o*@!D(HXL0X|4#W=Q2KaXy?f$k+9_Z8xosV4RjyxW;SMC zE_EpVSXE^KEUzu&Sr(JH^LCpFixsM0@&WOm6qSImy+`S+B!h&#dzW>?hPk5YKdsfQJs%8X)`k;;rpGZKdD7T3P?zo5CpLwa;^ z9moP3AW79*y2oPH%pBwmW!(2TAOOW zo%P@hP4#~nP@AlmeV(frz6kC3!hf@HFX}2P>Uem0>-Yd6N(t+`gKksU1=Ed^p8amf zu_zG}Vyu|cwqP`Xj~PT>xldZZ(S`7}--V!9Cl@?wEy+(v5t>JAehkTREZ!RTstKVqm zq}-5i?KGZxqTa$43XpUh8xY3YTBcS3c(xrYS~p}6i$!8^&NMeEg;64Dxd8gur-bz|p*JMZ2q>LI5}~AxslCG zxe}KioYGgb9C2lc!x6om)F=`gdwvnikXHNdPRF><30X2(@er1PfX^oCM^?YoT^Dem zL2u>v>^0wFFCJ`rVdewTWh5nV(}{%lrtbSzx_`E3xY-xJCE6EVR~i$#VmhUJFqq($ z&KRKvrSARl#qdg-99<026MTJyelQ9RX7*V=iy6bZ@O$w)#~W8Z+jH#OwN^6x%qOzi9x+?c;T(H7d4cx|%eE)~FdXjWG?Ci#KqHGLx8?*VQ z{qYrYZWIfZ5Vm3!+Ec6TY#P+ndHJ*qX(wEjlmsX{Acv9Gvi}Y(I{y4ViV)j`GWSCv zlKMk=9+2}JOD5ZkAtx)uaH8!FF7D}VTv>y_pVK&OYkgNSfD1{n0BpU$54kp6o;Em? z^7{lSM0+7OkkjKwrvF`}{|1qX`C3U_${Z6DJ4EL_J_Kq0oa)=+hdTQTR<)2o7b3f4 zHwbyIsK^#ZI#MvO)b0IdPqyVk%ewpP4mc_*gmN|~r+-oVKLZwxLz$rA(ys6+w=k0? z6=fN}76q(7OXJ{*_|R(Bhh)ul32tv^x7tOnuB+YC%*byjmUv0Ej`MOjMr^wrY`3MP zp!a3=DKt#&KI;^1uUOxfW}Y5`9d>~ihpAkdR)qUf6fpj%y0K5cMrvPu>*Rgb1s~7Q zWb^eUx4n0sULE;cTa$`mm#xW~l)>=s`xsq1g7XzglU4e4$3JHI8CmPK`{zr} zwoa6mMAdDVJ!V+dX~JpsgJ*steP6JXejmH^PnNudPl_9Y5`+H9Pcs)Z z8Qu)Tf>%DxZY5gaQ=7G~SYE75+aTP$Z}pR6U}3fK^b0D?>-{6ym#uQ^(}TK>8VCu6 z;W*f+OQTE17PYEiyOGo~VOc|ycQO23O7=}sjZ5+f-9$u`(IfzKfIJC!%0v^zJb~JA z=Si4~m^Z4aw0fy9)HMG#JTbq|Sf?X6=DE+-U!fa7A_J&t+@b2Ul1Ctn=cU4(yF4mV ziI2&0Vx*KNKja*m_7oyq`<+sF&ad;FKP4jFIi4tjshntIAsAoa4c7qji-^4kq8V46 zXfgiZl3`QD({!fhLA0ikr;o_VHo4h%Jj&miN?B_;ZNP_+W(AK5HAl4rYo2EwVMqbp z;Q`7ZJxBxaHz$~B5iP~Yv0_G7Huk9&o|M||M<-(Fhx5>k?O*8 z>ixQDn;MCb4%X3BKQnj;rGcUX;W$H^bM8+{u98hId8cYl+7SgLzIF*vg`n~@ti(}q z@r8F+rB|G!^giA`nXi!-jBw0UjKT>9`9P$k6P;9BBx#u5`RU? z`=0M$tc8)l7!lYJ4Y~of8|*lR2e~Z(#Zgh09IAz=P!81l2ncV1GMUs)A9!n;e@4bG zHBb1GdXauSIJ^<4@r%;a?I00@_7_cXn?WNLSK1VNGLw$Q7uRK65x5vO`GC%A-rCQt z%&9KHHOJ=}=AUFNP8fNG+o&Vs4zKkLy04$m;$IE^RfAR)2#6hO6>@QcDXX+jUA5s|hB z0O0z`XYvJ_A_41}U{t-dn^Af?mxoOdW?04hPL&d-g=M~nt5wUSHwO%7^=Xy2HVab2 zbj*P0%5Q*`*wVTAuMC)_yfw3v-Crd5=k{h0Muu(G(e*IV_L_x8?z8GWv+598*6>|M znWM&0u1Y|6SA|vwSP+K9SXAhkRZ4uXm_90h9J*U$Ovh(h2Qn$0FfP^=RUZl~w)|1e zSvfOtik&~Zr*d9@-XTBts!@KW&ofGc zC^e~mbr+d6t@(Ac@%lRKvJ?6xIY0FBifyNj_SHtig~iv;VKkLQRbsrwL5S)RFIZRC zh*>^Rms!6)TTAyVJ^xpI)18bo+Z%1R5iR+3t*v#lHYn+dC)Z|a+`~R+SD6j?%EJ7U zwP%7Vf70u_b1I(<2u7AGecemj{Te6l@MG9a156l(1YY|AI@&JZtKy+7H)J7F$OMbm zZ(jQiJoDMtCoA}`P1E=5(9Z#6(-XtZvZc>V)HL^5g27xWRYc@BViQG)Y3w_CH*WsD z=Ts2!SVF~?n1HXTs4w5+f7Wi+!wS}{1l`L@|NYS*Rc~DXQHz9?CQnDJoEMqSv@pMM z6tG;!Fyb6Gp~Zv%36D>I3xW{;sYeY!(&`v~b^ETiAJbaHNp|q+A=kDmXhhLdv)%iB z^_D~Jza_T&mbClbZTFvP5BS;6(d-Da>j*y7p%{|b!7J$qyW0^l(-C>0*a-l;{{yo0 B(}n;5 literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/custom_errordocs.png b/trunk/docs/manual/images/custom_errordocs.png new file mode 100644 index 0000000000000000000000000000000000000000..f2b94907cebebb7a518f2445a128ea9f44ab2e2e GIT binary patch literal 22907 zcmeEtg($KbGXmv-1oglCdN9Hs0Dw|Y_pTWL073%*z!_2^ zLJoY5g@tef2Ak<<0MJt$yMzSTL)}On0BCs%{c|5eNb|Vpni&BAQGx(KToM5Ai;xw! z0|10d004VV0DwXP0Kkka?lDyY0Ehr4h89|c3fI@y!^6XYfq@AL38A5(rl!9WqNA^` z0e}R+lP6Ck+}sKa3-|Z;tE;OM000R>+HJb9@S2B*htRYT;FdthO-N8LtOm#^UAsvT z+FiR%UtdoH0LO&tgkM6Ne;2|Ha839SQW9v&Xlqmf7G+j6iAY2Nkr>6ne(-POyZh&bwiD?2jx58<+>1ns? z=|aGCp~Q6IKe&Y2(}mZBs?*aFgfc>c&~AGAdioz$!ksW&0&=%&K;bn(9{&NomT8*0Lw+ayXqDZ4u{cD7xuAGF*V8CzC^blp4)~o+K~G-Ga}OaACW8Me85x%_?o!t zL3{l9VSX=@TCc9Jamv##q<`b4Ku{!e!6p&Txx}OYYU|yL7t(#1Ap&F}TA;pFZB>LG zXeA3bO@l^6wwv8qK!C{5`%mJG=T!$g%qKgJk}Wa*)iAx%O}aP_*};xYznt`K{w#bU z4rxF)&cYk@X}YNBry?un@1JeenxWzS=?7gFnK_41x;*XLR}J}B6iCYR^H)HgHss+C zvL;m$C#d~xIlT1M`rF=2I@m_(tVDQzTIBKSM?F<@s_WSeQ)?VgmyHjjyUR?NtL(}=ub8>$S4TG4_!kJ z^xM-TuDYMYfJRxbkN?E}#2-nrBx@3Vpt0f<6Agk4%6at&#Gg`L|7_lSy;w?o zJ!h+_3sGjC**7Ge9}aM5r!91c$s4NvkaaehXZ^|0`5&&shgfoS{aDVBtZr;$X)t?k zX0i_i`y4?SM+(K&qEM=cR@r^{tnNdPL*!sZGtDHBSGqoR+D|ZS{y^VrzA~0w6k`>s zJ=CEeUKO9$=HfP6X+Fyk&3Y=q-?Ebr^c|YbboEh*d7E zB?!4W!f&eCc_&la#9+ApOTIpl&0origK;Izm9o|u3shx@KEDZgp)d@NtCODp+f4 zZz7sLKG@Z#^XvwT*uRXF>C>b0tO6hLV>(+AW@Y38gvB2>dxMN06IR<|W=d~QPprTn z4_=^>wG#H0v=3baqSwW8pEfXLzgL z$Xb)xN3Yf3=D!-6zGw{X1ejM1VS^?TEutL-&cF-8WGiPsf`=@vP4gn$_P(-lyR+VM zx-UVo`PXx|yxa733L~q&@pDl(&dLm}S^JPH))ahh_8-fHBT>z^TMww=eu4?P)Cw;V z(cF$RJy97FCQEDVAyLIUlXMuS*h5;uFY7Ktx}gDgPm!auS;jX`P3;zKeH{5o;9vYF zkRnAwJwBa}g0FfT8f5jD#}!EycB90kom!0XTrYTZppzOQ`eg|^;(;q>TLjB3qg|=T9rDELIRJW?YnP(FaQe+>N)njC+qx6Ri@?|-8&*V#%yPl&sLhTMV zsO9PhtE`%e`@po8?!l7ni91)^S5deDc^Vl-DX1c*Ytrqc8Y8= zLzayrkJ2+w30OzHr$O% z?$<>ck$QE2>9CzWk!EYvdOR&YLprGh<+oJ!T3^cuX~eRV1qNYO_2AFdumXUmR%g;P zXOkCo5yl`U^n2Ln$R^DdP2oKSy;9w9BP8M`IHVp8wC_4y`mBpQw4g`3-~U05K4|#( zeTqu{tv(WAM5tgTiCkIKUhpSFzw}<57dc3Mz|HHdnghQ)UvoGujHj@7qgT@whCrQY zcSE$uBq(y}LJcAxay$3`g4u!jbl|}4Vlhi*tRePa-?T?2tmF%H8z?({u8;46fz6OeG z5@V~to+{>F!9Py?w4b~%e8=XO@3ZT$|EJu+?G@egpp%IYq!qjUN4tN-VDGNdPu??b zI%wExefs4B&&a>9w|VrIIPw#}c=D|+V*f`!bhp%9MojdeLjVQUKPQPQc*cT@M3r(` zD11bC75Zs5@H?fJ7Wts7Q@1H?`U1OKI&u{*GP{zTpQ6_cfKvjkoZ^$~!WGLaRrL zoSLfv#Q8TU5P9rvb@3f5&i0#LnxPAygRQ|lb}H&2e}BFthr5FP4VPI=qioq}D4kZo zR$4KA8OXi|x5v;X@5tRs>Cojp3S@P?JH+-}^^swW5(UxeQ8gbf;xt47#btd$noPW= zyT993DXRx%2fClt4LFBv%wONa=*NB~7aV`5B9#33U`DXVXOYDZ=X{s-h*w{oY;osD zH~<}fyGwO(s@bPqN^J;6mupU(qh|x5egMsHKpep0m=rG1wT z&p;U9ZC60TP2L!@@#cqGNKr2$F|yF#B1gtU7m0_|aIhJ)S3juHCpi|*1?r)>>@`&; zRbFo%=zpbLTM|+nBvETB0xVFcIsQ&V$R|r--Ai>@o0qG)zkHjHBD43Bm>|7K7ha{$ zP&0Z9*t8v%!p|^w0PVkLNT=0U7!NSN6Ar09mi++|zP~WEEhIs9xw8HJ=e+iED4ZoS=f!p@f5 zkFCdsX>HUMOY8Ft@S@&oHvaf4hkyyjt6h(FxaA=fk46OsLq~DHy0Yt#D;QaEvGBFR z2mEBn+%LlX8U0J$(TvIVa>@D()}T`B#JQtTB@ zOkUZO6fMu(>g?C~dj16o`ilDKD1L{=ZL&Png?TnA|8wvgSwDfAgF8YI_F0IEL1AFU z@bu%tAr9WwOj4=f7YcN=cyC|Q4G@pZxNzvMHr5@`0;V5p9Q~d9cGl|LDAonK*3;F^ z4qc#gzlnL>ib{qJ+)IPQS6Z2Pt-x-I9e; zX+cL3?O(!X&J-;&wHiA6W z-l}^v@^bplU~a1I9G*>Vnz&cW`E=9=)Cse~xYJfWC`u%1CUXuZd~UQY>zNrH``-A^gxJOusokSZ4jqkj0uuq>S+# zdnMWm_4PkAbb-&3aah&hWDjO3l~@_wkc>E2tW)aU!JMi$6p6&%ZP7fJdM9^0xH(3I zRPP?WAWLUeLTI%wCzUS_$q3^M5ha|si=*#Uf2_SN@tfnuGRF53lf0 zH^BQ0k0@<+Kv{@eme#}~_ND1eDJ{6FHW?+8nrl5{3BIrX7HG)ygbv>bFe-c<+1P;gr;qwtB2tWmr
  • tGsqDN#!CkT80X|R)*9VGR&6VD~k=r6fdp)w}R3p=IECjld zQ?lIW8nOVOba)%OvDt2)xh>;3_)74x$%XCBebz0--E}>k+|r}n=Ftzw)~n& zV7Inm)m{`_R z1)@`N?3&iL`zT2UWhSh6B&B2*JxvgC1W9@+PO{Hudsk$5tA6Q3}bdru?;H-#WB|s zAumYANJ!e-`|{gA`FF)^>#IW0&Lf~ja`^`*`n3>@loP$Z;(zUM^WAKuls3M@ynT#{ zvD!O8eD2@1Yw&`9S2T$Mp;ZZjwF_WBOI9p}oM~mlDkoZtb) z;A^w&CM6L1o5UymPAg{fqVdI-vxG0*L~`)10)gA8&Bff06g=K!n0jm{4ca(l>D*tn z?xD*u`<-uxtxWH}dZLMizX%sh3zFc|ieHKsOf+X&p`^NqK>+(JCEvk@yjPz@F ztP2w-_t5oS6HyK8E-#WGnoKBkBfIwtZ8K|ykLMfpF%XcoLL~!ln>yyBfiMLp<89$A z^MpL2w(1~tH=IJ`g@OG+A#jgxRD>r52=aaKY5ro56;rs{Ux3KCGW-yyru8-=?5Xz< z&pHMpJ7LS`Y2n4pH9o|cW!KINO|?#d2e9!pcQT{*uI~&g?lns-Uwj(MIHY%g$3?_bA+uljMf#0hB5zhaGG+mmn z*N|VRJk{ptLDPcu7tQJk1{_n8Duiq_Cp1u0)@5Q7IoUA&^$P6F6L-plSxk79hoBsm zUEZ>pD=MC#9l}QszJE)o!`=H$ln-f0s+Gm-c$Ocwje|thg6jp?$@Jx*SkmR1K1R$cw z*W|gYL3?uH;KgL`maz?nqp%aJLspveAX!hN^_#(57~2A^7L+*^R1@Bc8g3)+}+OYJ*YF4;AD@ww!52&RXui_|?&->t#|H&3xL@pkD(*kQTdV-V&H2U9f^ zZll0-w(+r2+agk(QUa?mr4pm~5-J^m%iX|4Njnw&>URPz3R-@FHj3Z{v7XUeDX3pp z)WqVWNZGrZ0T*onz6R9ofqZqf+d>BHy!0*Gj|Mb0BfXXucoML>lWd7%! z!&`uzNA0|x8}704#M+*%iiCe)FnbyqKwhszDffp|_MW3XOU?bB4%cysKc227PKpwe3{`qw$bf+T|;@fXHdytMIE1K?KWAM4r zY=uvOF5L|(VJ*^aWcRXYff)^jy%tS5^gwMm-t@J!?Km1tUAp;K^ZL@a*rmBLlzeCC>nGEVifx?kKC^h6j}gU*kE#j zEOk*@I&}$?j7@Kgzmo|w@|WDoKVGVlh{R_uQ9FrWJcKh~3GaUWuvNFEC_nDYrcQ0N z#I}Wb&QZN$m)$W_MPy(N!}jyIQcIS+&sLLK&8B%k1@j6hp&vTG^v@VDO|>y=1oDKX z%R&{Ssv}1m23M}GB_b5l+)ZEV1rxiA689_rr8wq$46H<6I3^rIrr} z-9I99pA}cmNXitG8drSJRPmM>iFQRB?N#O)_x0?wjfj0;+q)yoXn|(CkoP(rPmpX% z{OVv6EAD4;36a#jY2&dP$0s`5H6HiI*5|&>UUK{$8|ujLmt@P2&__~{xi*0Mp62>} z^P-B=d-dcV00mh7)>Z>pY&)H6JN@Y;VvpTna-sTEU7KlukE;t!OOKm#KDAo?IqmdE zAZwpB=-^J4$XA9qXp-WSWFL2*`!_#3%ZQ!k;5q0dh(td)aQ~X_zDvTVwv}JAUE^3% zA*E)mtn*HLSk`Ib$v@1U|1bk0R30`5SR|D7v`iU~tqv%0#)>7PByWMzKJvLP2g>}z zP!ag32E3gGz=dAp7pCTZZNK7Fr8(I8#Mm4e6%`||kN`CVKh?Q8T%(3Q)ocWShux-+*AAhGdq>5O;-`9OZIP;sNJ9e1i~D zl*0uWCYbnl1A2eTFzNTS>3z;u95GQ5?W#&jN(xFGRD)>959d$+gieQC;s+KCD6C%B z=v}X`4nMtlwZ1AB(I{-{pw1d+6W>-bd+8eSq>X4jyW*SViQl9b=;Ap2cgNBIeWy`o z?nLVfJBJeB1INRMC&)8$`R}Kt)Y1rfyDY{jKw1b`P^5HjZRZ^9pnXDK-4J!KH=91@ zUB#qJS9>F#D9-2j62N+acTVueNe(eKao7Xv)#^P?u94SB83i_~2Tt!m$#Pb#%{K?e z9Tr_#YiF&6cEXNXm~V!Ou)Zudj$^M=sH zU^Rp?+bcfnCUjHNK>TfZMRX_1-Q)iKT1bSlYQ?7YbeOrV$NTvUbBQA+qfrZ_1o_ zZw7s0e;NR&zWuI|bP+X7_ZA=li=!7r+k8X(Z^7j+wUer9WJLrngBK z1JJ;>xP|az*EOForZ9~t*c9|}>hM@9ZlZ>}f>ti3Rsc<+ce9j!&1+edqe1Wba{N#x zusMVx1!3Pr_|4!eRj}b z^Y3{tK0Aky@*fKARfeBj9&EAgUaVYlf_{wRUj?cj1bmmyu>Tv3B%S~?;y_`_cN89y z3lHvII*zUHvxX2fUxhNuj)|UN-})QryZA{KhDB5nx1jhiiQ%7byvH*(>?0R&A(*FTObg3flkb47I)~4 zhy+4A>S~)pj`OPE&DgI;aDKS8dYXwcx8vG1%F~U9&_eb zhwM96qWuJk@nq$Z{`hmZx$C&u*5#&eP{u5oNqcA3@-Uak#L*8&W3m1Sq0i}CFrB84 zKW6}+op`JR2h{@7Fq~})Ca(~YZ{oV0vRU$oI%V6ftm>S)M1dv{u6{6b^_5a=HNgFmr(s$8k_r;*DC7F ze^-v*hFL3iB_E_O!2lMA=+eQGVI+zRn=Xi(P;;J_mY%Xi|Rq#d{3M0phF{gLGDKRq?@`W-bq6O5=W=KD@v5#>DQuA zx(928O+w?$Bzi!<=P!Rb;;C~Mq7LdKss^o`7vx+jmE9g_5!J=lf*OctlKG)LOM(sW zUE?o4(v$uCRh>G3f zA81hMG(g*Idruj|dTF+6u37oBE0Z^ znjYPj_SoNQ54$Ao?~N_=<|9cbU_If7FL@#YoYx3ALm=Fuu$y9DqjRgDNi)3iO7+tq z2?EiBmv4t4N#KvDZ)+#JvnN6gyh%S!=%EV~Sivq9QB5tMjBkKI(&3=5R%|Z20@=j! zm%p?Et`~N!*;$zqVg?Ige@mKQK&`0o6T>@Yd9#Q}B8r|JLxO!j8EnG5!%3qHX_j9q zZ^`>pvC949w`89Rz$CJU&eW00bAS^xY-68_6{$jZnTmc#whF{ z;J9d{=E3Y9O(*=lRYQ=JnTYP0uqwj0&|<3>oMxY_7iwl818ZGNBql3=%m)CKxWvgAP+Z)u^lb*VC}NG^5JxP1A1t+$X;)Q>&bO6Bn- z-pYyucL>W8zD1O_SiyD4!Rrk9usTBB;f)=2nvoon@{7{XrF!L`HKq3D>pp|!{m><3 zw08pbGNm;z&U;cCOlr&J^#-4@O~-=9f6vWq7_WB{%0!jH$KTQINog z_%E*Yi=ISW`K2`A9z+)gkNW7pg-6_o+o|_vcj9YknEMzi=KQwsq=CtQT7%?Rt>w29 ztJ)9S*&d(hE*37d($*P5sjZ>h8Yj}Vag=_0y~iSeeR>WIV=@)u{3-TwppYCq`r{RQ zSTdPil5hZbTqqG=;Ykm1@5lRa6^@dZRI^&cVqxkdh=`rNTTXD)>vUth9^6K@Wj}qe zpuxJ&0P#itL7N2$Qb9y?wvdK@b8+$Ti_5}v&wfE;%P=2{=ll#}A3NI2Q17eXq|r7} z(eU1TX9Nuc+k{mRFO!D2Fv)SH!K4uHyZf zm#80*+Jcr4v9;6ap1|J#WtTD+c=2q)KFjJPZ=cMrLdJ(4n$!ks0EIA&$m$`K6x;I? zq$cvDR+l*yrKE{`_} za8}1hq6S-(0JOw==Q-TqH<&Bj1mddoad?>TJ>rYju8THmacHD8dHkHfo@ z1~>accsQ8~^71`S`~Ch5b3&#++=|<`SAm2jGg_-PMTAMpi}x$U>eS;x&rRO;gwS)_ zc=h>6H}=%m*#kI--tE$S_eBZCxs$oNlr56t>5JIplX&tY@D7u8D?uU7{^L{bg(1o2gOkE(EvVC`HwDQijBU9HjfjD3x*VW!6E?QIRlPA|(HNshK$hv62TO3aVQb@t?{i2AbGEMLKlAPb$ z{FVHGe2l4^Pr4s$dBMtp2#kb2hfU#1Ua1gcVI^-E-=g1$zWyVM(H6qLU@eXM8aaAG z!l|%kncsEGnrtvTz=;8ZPG0O)(4hPZLDK*#6Uh}Tb4AxtYvy=7D!c_rn5&PZzTYe_ z<_*pQv=Srb3u%6UzhYi>mG7PB+5J^`5hn#G+h|7!=e?8vU{RrXl@No{DR*--q?g-yc64`Pu@9O zzttcIComcUPp+H8LxL0%EQzw{DBk?Hr!-LGx9WGhwj&-2#xVx!4D+dppl!910c3es z-4e6UCokApO#3Ptmm=InsHgECWlz7EvwBnRx=z`ABCMYRlo4G1%=K|9y|f9?u@;JB zXYm_!qjI2Mhy5C10o1H!Ei)Co(>Me^eWXdP+5RGH%&C+HN z8Qx(I;>^V<+UJwUX+^9xF!lFh*($JWM4f%B=?WkyUbcGbQp8eCk|HjRe%m=)yT9IkDr3ibrm)2%OY# zNYUvJ8@0r0tl?4<#joVrsjhlbVQ`yFcCcv zQW}{T0edqS8YRZDkEP1m)IUf5|W(i__f4H0wh`UBY2#ji4xA`^5(VQSNPI#g1^ECPPjtggQ+}+ zM>{gr+bwy<^b&0Mj4noUl8dNQbsUFOnD4_i1W>)VZ{PcI4_M2GJWSUHzW1wG+xwIo z2*tTomA;!+Yd=s;KwZ;<$8KM)4wT89piU;flr6HQnZc!*vS)4D8Ue3|g9k zY_gIz{p_(~)mBTTkOcwpAT33vYy2DNKT4H+y_YG`}-iB==V!vlJt?_nz z`m?HQngFiqXUL0Y!P+GT=Zxn=lj8Ak{6NBNs-TFO!hHyo&2&s>EGm!5Rho62YW`}> zLqdT_qP&04uj6>CsU)E$Tw;vs6gPR})JF#UF+79TE?B!F6&8Df%+x|9?zh*rB{EeJry;MFgcwzfAI6)Fck`b- zuQ99h*^acH)n2KGK{c$uDku&5iG7%__yvgF7Izv2+8^w^T<|-tIAT-%P`}T_*E5l) zq!k+Ki|XAkd$ZI22bRScJs<0LtH)$MQ_P9n+5pt_+G8eufM|Ru*~h}I>h0v^0a%G_ zt7&cL@uysmA^%n7A|)N{5EeCewYElkrII2bri+$t@u~2a%#nk5E>$fD(mx%xzCXkK z_H{~D^sQu=bU;tu&3KQS$o3gl;o>ygPM0;_yk`wwp=koEpShplzDVHcXRfH2>8Oqd zdYpunNrnNe$Y)-W^{@u5pAMqfj;s&y)t{YRbAdu85PL1MlS{^n+tdr2vgQ+S^qkIq z&dsvoXpBdA`FW{yD)>IBl1fC!r7|Sk2NVQclTuHC+Z6e(#!RNuNXJ4Mix#`TzJze{8PNBj%RJ}OuNn1A1kNH!hsrLQS zKzo3o zprA02A|6=>v}N2$cE?<5wo5gub+P!zZB~;NQ>u~Xq}YP*m05W3nS6^&qS3OX3o@sI z#iv=pzY5T72>mS{rp^*F*%T^1rSccmPJQ~6r6IN1B}?3PSwANEgft;hGfoEd>x49J zf>^YbVf?*FitwCIgA~%hU-GP?GCk0o&1!|X;pVHSIyH{vX!1mn&!Y)x%0!<_fbPJQ zxOvT!$T~GGo#Bn%m%S7v>oeR#9FO~Nm?t#ImTHNTn#l#7{zbR5EIyq!sL`0LYhKU=0K0=JwOTQqe&Fz9^bHG6H65FV zVL>;Zc>fqO0Cwn-JO&v)PeaD&lx~Nf579DjMRMPEm3F^R2fcuo!p|Q+3K*$j@&Yw5 zrv=6_CN!e<8$B_EbJn-pdwbOqk;Ewt!Pd(OZ$SXG)0BoAew~k4Ea5^Z5caZSa=l?c ze7t^V1R(?Hu&?{X_`y>3N*G1r?)uMO9NKbQbJ78bRe@|??6Ul6ry9hkYs2vH8FFMb z0H-iCjccr_of^_$YIkiph5|(V^2-jB+lkb7az%+^`f#!|z9ROSH(-PlKbNwu@bg+trZ+^hv%4|WRD#+b0l!NJzJ{?LU7cng zR9IqR^^JC#{S^>I+RQy5}0CTy&jdK ztE9#b129o>DS+9TmPnkM7-#n9?>IB}b_@cW`3i&quCLCGy|D2G#07}aTczo+WpL-7 z_%xIIKk@`gX}Kt-7=Hr!C1fVJ1Hn|p=^$L1eP2F#rayZHVT0n^K~C_3w;KH16D496 z0N3AgW~lcl<3Z2>-TZ5U(+vXX-g5_q$ndat{Y<-beU$09Y6(p}P*6~1S5?;1WHN#l zm)k}~XiWf|m;pf{%Gy8jo!S$WC3NI#qbQnoNTH#Yx3}x(Y|4lB7({~oWb6qv)N
    Q7q3uL%@*et-w6#r9IAqf<<_ILeM_A9+rC&dG5?YNm5 zWsZWfMBqr3G4z(MWvEtB+;STuCH(t=uyLyAB;ZceXyfMw^0ePm%g^8w7ghplbKugZ zl4ouJW^yhSh7AouzQvKPpC;WRWLsm7ghJ~@Nk`IJ}0BN#%&6pdSM`45v_ zZtz4eEm?0A(0X(QeABbs`^~b>KK3ClBygTIj2Uki4Cn;6uqIgGheDg5USFS{037i&6qrDTA?nmp1`eF@ z;pyxkk~@F{F=I_(n6UkI5)^RG7n^Wp??Xa(Rh0k6ZC z!Kw8o@T0Xuo3%Y@nZv|KHkEe;9XNgUNzE?|^|pXhha<_FOhEL@}6gG=tEGP->3(l0HfP6B;68hiHC zF>UOGs~<1$icIv(W*Ae-VZ>tcm4~wjy!mniC%!cRonZCUYgbFKpnuf*wYA&vb^Cx& zRp@+3$6Akv(e?dvK9*1x*Z=1jq(tfCcpQiqoXy$j!Zw+4sc} ziO|EuPnUx(yHSjzJw|-=u>7%!`wfHSxx*aQ>-8$2DB1c7nqfsiw z$4F|(kwPxoIS3alK$hVe*+qfwC;tv?H-Z1LX*Lkyd+s~mX8q&K?ZsYHo&_UTVTJK$ zhqLFV%z`gAvUhXY@Wxh_`|Ew6nqPQfh5A^-U>mI`kW1}|OzJBBjqtVHT~$?<@9`K(`ueDe;d#jJ3&2_t}i5PU^xg7*^W08CG(M zghG0syuCeH!RI28FYe(cLpB@l7bN_^&a&o5fkxfgL|=xGS(!EmQ}>(ih?aI?yzR7T ziWdDcQ0WcW#Up^LRPCd!)6RHZ5!-lh;bWhqtp>fg4x@Xq=j#4FHx#MgcZYO}BrN!X z)PrmUH{Qv&@JM&7YdmAPh$j_ptP1W%vy2or7&k~Y^K`L1LGFLl<4)>1&0~+*+7s<6 zSb5WE>Q)-l@yXgowM1Is9Zl#XQ+M<#-P^^whWf?%#>i1d@wRu)mb$|*ijEOEmv-Ao z8Cnc%)3+S`R+q2vpLM`ZMrXpM2VB3H%So9=83sHkT)L@OngVuSBphCAZ_F@+Jfll< z`nUf+qs)4b=8KpA=f^eGsTMjI;+KG+W7fk6r&NibHAy~tPHfosECzD^^aJl>n3a6l zzwo7GGw0h58OLwusxe@t{DGJT27XndZ~DrkuS`LvJ+P*KUSIc|!1Rv=;Bpb7jY-Ju zf%C{?=zG|1TiZdBU&D@2*+sTm(#k(ej4C0}@wMf_gb%UnAg2(zvS-2?*5YHg9IEw} zaSUzLGiq(BUhOTa38FpF-=>qqoQw^jq?Ztd5mkC)fF-rKco-0`R zQ;<8T`sMAOuFzlTm(MG!nCv&oCFX=>-l~+@jlzdt=(PGgW@g@==Uu#iII(|qY=}xo z5%y$Wxnzjh4FAF;P()dDFH8`S^jBeG&*gjCZ=M&2c3Kx9*tg%vrY)9IZUh&-v25`X z?P3{We#dr%s16D|6Qi)~Z442%hgjLBXiSu7{YqAQCtyJV7q2`)%y_&rs|`&vPeq_U zJJST!!m_;}tLn#5%3<7V;Tv-#hm$M*(T|Qe02r#d%8lpqB%0ZBccfTY*7w*G>x|L| zkGp503^3DPEK}_9J$%R#Qn1gb%lK(9{o;_dExt3p8q(WluY*{6M9$(DAi-*0>vM-QJ*r&YQ~tU%hj6}rTx zUZo4!uKvt0bt@mRDG3^%J}R zX|X)89TQFId|4(yT|y(7!e;PEHm9 zbkkZL&el5ME(ndU`zT$A;QQ>HWvyIt?jryB8P8|1aP$J8?0KC!IK1S@5W02pmA#7v zZS0mCpH+eKy$_6O0ujSc)>%O0VwzUJf+UXYmL}RN7J0h_;)4Z4|R-hjiklwER9B`%5x? zCKvjtOGa>HK1RO2c;Wx5zBjAm;E9+2_e^JPdxH>{NqDlIHLIfu{70Y((bHNW%m3U}RaItpzWy`6 z>3Vu45|kUk`~6tX;%4ss4gs3`tS3D_LGtZOPM)!cgrX;QkH0U-sOo$UOp72|Fj^?y&{+|^p~T-9JTAu?U|2=;hQ(?=OyRs z?n|qdqm&I(kKv9!HyyZly@esKa4G*Lz@ArYF$8f;0uLiageFOK76s{ zKJ4Bzqol>^M%L0f+0!f|6;JxuYCGbHqK8>Nz$?~bD@LTSy}^mfa{qh~X6d|sqUca- zLbBBmBX`OImi4-6zY^I@)o6JWM`u6(Ht90LX^hHWr_T4nIVqdkM?A@WFGt+Og$>=wa9N8Y9NV zk+Yv??}gA0oRi;;&^%Uj-@JRPu=*h2MabhH;G4^8ab@&+-}Jbn=5CF^(MEmC#9;;a zWpR3A<;)GP%Udg!Po>b!SaSOej;*?Vk!m|pRDxcwCfMI{$my@%Nrc;hWIfnMEONa* z!#r1l4yVQY3<5c;i^TjoTMGG5muzJC-n_Y}vSS{Tn;_3m98Y`knX2h5FaBU)<{k)n zw8xs66mdOOx_r}l2$RDvNHoqc{b-DI=0Pjjp2x-}%EJxzrpM}AW??`gUE^)-@XXMR zG8+?t%Nw~%h18t_5Hv6+{YvNO`NQLbOS_UQ4&Lw+e-LABe$w zigdxrP5u!xauC%ZpbZ2TD zfV=2kin!kjq)4}2ns=Ruf`3Hl#aj02x04;L47EYm3|(H)z~4$aoG^4#OApE3?R4FL z#6$G3%zO}agJMFta>+2BVg0@Sjrp8GSq2OYA;@QJd*f)`VrZVI5F5L8S6~kB!)XZ_ zhK;?HDsZuj2VZQw+iXKKSuO`T-)c|;z{MTEY*~2B1z5JnPxFt!H_v?4y$S!y^Be8K zR6QHcUnK>gJ*CbxKiP`5hlt+s#1Di=bdj7NWsz=L3nf}qJe7X6qUl|$r54HFwJhQNpvxh8K$~+E2dEzMxwG%->5PD~cNY+WaWx0Iv zZ#mB`XNm`ThEZ}3tfUN90%mOdb!J7g(2%69{?|Bi6Is_5Z5oOCzT7#)%LMORybbQ( zv$HhOlZ`43f7UF%D&0zV6KeMRD4HTelN(>Cb@MQc<+%?d9j$+L95JZQ=1%C+Q)t^6ySEDVjTwz#WZ6pNdxsRlE>H1{{()XkQo> zl~c;U%vqMg98(Z~?8UF5jPXGd#KdqVF52JU$GaRlHy?gWz2EU7*}d|U{xXgqb`r+H zK8ofH&log&7Xn-PU29txmrc`CY}>9AXX-<&aKtoB`!k3wJkNgdap*o=Z+4jvM~X$g z^Nkk*JXuUasm6DaR8DifdoT0$>H2)a=Jty9lNc4;kE=`phi4`}V3z+BYF=`B&b?fM zQv65oo;&@Dc|@1y@{iy>GJ4)BoUaD{=M*PX^LzHcCqJ(Sizol-Upj4D{&?O0bnXXt zAN!pDGC#6#9HOH5v1h$jgfNbNV*4gK0)rt?LWc;?NWcAmfq=7TukEkCYW*)Hh?{h! z_I`tu$stn(`-M@}K|A=l)XeUdUDpu2#fP$sWnZwz;>)H1Pa(pT-8$yf?1>)8ilEf> zQyO%;SoB);K+rrj3hZkF*+ZI|pXm{}9@{Y!-y>-~rxv=jHmo+Gz}M7#PY-0u-c_;U z%pWO8CSn1i>>1^OGwc$WZ6Mj@O`dc_1tC`8%khXt3vZoq|Htb&z1Mp4_Kie}k#(&buOuHlS{xSILKM{IrFA3$|5uh3T z=Wi;OGM;76{-5A7^%MnUYW^qZ0&|>DR5o4OKSNf9URl@e#?I*ri+^&Ob?{}(GrZR? zfy>TTl8?ysxUYOL#2uaRY^Y)AX*?|A4l!?Aa?$l6AP2;$_;@=1H^}L_Cuc}TV zKEyRtcK*s4&JNRl_uoyp;8MMXCijCkUa_dxk4bPd@y)!-{CAxAuDNirMh;(7m{XKa z-R#fDF3moOk%KmHkSMrfQ-{XZ8_`9hhIbN*b#RzrR)68jDRA}G3X(?RrapjXFRl*SV2~svEOE_4D zzMVFvK`QHC{6~uctOj}h{;UX%onR7Ofs`4EIvPxEKqSh8P zo6O@IS5Vtwr`C^`eifc9G=SMc zGG=`TnO-ir-BTyWK3qGzz`G;qUCEK0fCJ*IH``+aFVFAiPFKc0{QL^PzYzfl#4%6? z{5qM3yiN+BuvcH-mOlxY&9x~yuUM3w5Y=9|EBDiPob$*33FH+U>frdZN&oF1@4?U8 zw>LMAYJUw(IRJWvKez@H_=C5Tch`sj~FnfiV1$I4#KY$#*?j!5~h42;uJQ)xW z@w?;RF<|%@XSXrD!j%HUAH+}Rku`Jiu@YSH$}-Ao9aRu1$e; z+Im;FW?+@wVoV0ep#Zu^kDfew^W^oD*KgjCS^$axGAnAN0@n%AEa33~L3#1~_k;cc za4vTI`-2OBEqn{m^>9T+g0zA}u8rZfid|RVEd~M#Q25CwkDkEw-J3^m-hf_keD5CI z|Kr<#xVeN^FpV6LLWNvU|&CZbNm`KS+EzJ z{psf7DlpGZp4(PHt5)%aW3Y5JCV>ccU1hfzFi@g_)}u$CFk+Eok3TsE$bN?$`v@!s zpvLxS{B?8l_U)hQDWYioYOJkNLY3^g;%+e}ljjqlMg*oqEMOL{N1p&>L61eq!gcSD zf4oOl12h^$PtE@HAaQG>4_PF;uC7}QP+t2Jz~gtXzXLVk5zwn#gjrM!zC+03`0EYe zwFm0KAMgF?`@z-ZveAY}iN#1DPInbsR=tieCi^yo0l31P7HFz4$U?;xFl!(SEDJmf z-#mKs`nxx99lu6}_AS}ErV9k%{;RNpXnV+9KLx1&>EHkQ?|;n*W%7p~#kR&4wtGKn zl*xbn`Op9L(guGClN@jL&bxO%(69c%TbeBH@D<6fEAAF!G5{1{pa15&CvX1kJAkYs zS<+^~WPnx!_=3syHOwdg-`;!er)={WplJUS-2bTnuTKnK{~Mo&H*W$2UkXSqWPjvT zFAWHz0XkumEdvPH)nr#}+{w*nhzh_fTtK2vP&4q5 z6*CuGx*mP^9e(`;XqG7UAAa|`h-Mk%p9FYixc>C@Pk+7q75&GLo`D&x8N5Os_x||f zAK>RN7x43!|H4eUB@nLn0=WK&09LsEfIz)?dGYcE|9x}u@`nyHD;B*DyRP&Yck=f5 zEm{B&vE1u3nLfg0Ean2T1uFs$#QyEOC%++c*PFM;H`lbxz+V%j!PcpCt)XMexH#av|-``wWz%p9&3|WuV}a(C4TKygLWw6|SzU0bHl5p_VEGYvLATaC3}< zsC#GtAjJT6RK5UM|3)LRUmP3z0f6}X<14@_{CbAH6twpH|AYMMbkRcHmD%?v%;PKn zR@BpeKMPlj-05(A=QY=x?^hkJYw8wb@);l&2mUkz3)(4-z*MIty_PHpFpB^R?C~R7 zl1cT3ukU zUNbb4$zbqyK+O;91_(5-pRlkG6DfZF=snyz;o#=Mvp)_01X%6;@!9L&-UExP;Iv0R%WN*9N)zg9I6$Zp&c`0gG6NV~e{``qp za>A9=SW3XckTbBnn}vnpHI7|x#Vv+Ae9Rpu${27W_h+7F&MDJV%Jh`R?0KZ_6f;fA zwE-hRQ0Q7*^Ho~&8JmMlT@!I@o1@S2kaLFyx{@;N?SXv`2=tZ5kYpa5pXm-ulYG6D zIHo@uP@(8CpFyyc-B&D+UcMubjXf>S9#yy)#73~|ZMnrTlD4g&XmH0n>N$PdfYRs+ zVSh#>qm7u+w;?ATG^vXr#3>=9%{j3CXLKt(z(aTCD(DMSTsa)ub9#y`CrU-D3Q-?Sp>>sj)Hkf5myrsB^AM5T8eD_j1S{qi zqksiwC5Bn!Ex27X$?GGq++3T_t%_aEw(S+#xZMqmHP_lJQ{P&;>uT)xX$}P`rDaQ? zie1;lEyl9Np7NVb0(IDRrQKr8CcYGFxe|z4;<6@gF_tU&l-mpvh*bvG#4W}Q5=>E+ zD1oF5EK%4gt9d0*#jf#gF?6+qo4+n88e7%vm$Wp(o2t!p^z_p%sv8;OZw~Bi&*IaMh`GnSys64$pY=L#$%)LX;>>BG9!@yN5r>c_nUkX)ub(mt!HH;P95h;h@WCm7%81U-T@8BD- zrpqRacF*ZS5Wz(e^Qz8WQF51&EM?J!Iz|lqMCteLeehhE)h`OiKrSkcTtZ%bkY~%w zT2{4a)|8%U3iEV1VGA!T7pIb2Ib7M(J2PvXTMV~q&dE(_P4Hs??Mar!AaWAQ(_0qS z%8`NCyqLX^H5Uf}lfKQyw~B(^;Wfxt3+M>OH&k57gN)>%%s<<%*x|G6%VZHPPpWdI z$k{)?1@h!lXY$R+PeYj2kq9Ppi}ht=b_!f&{uLk_=@!GmRmb_hj_#>;>-@YafWPyd zwTUHxobZEAJ#4-}toiJuUBYY}%lV#M1vRO3qSv6XB4yrja+HG^Cd;Y049 zOe3*O+CC|I9s>2pf{~wl{o2A?J1xgA%LXfY&n{C2m|TfnVH+&*E1u;G|M4IG&z{b! z)aZsZ1#mUh*UCD$h5|JJQ(o{Sl4AvfXs1_sn$m9_dl)`Sj#+iK{!jUHqC(We6>AfoKRc}rZ1D&{_(|!(dU~JV zwbMt}0-LT+2Yse40`icQ7!NL^X(i87A}7UhIXET(~aW&)7`3fr}m2JDo09EW-%PmF-v#G@<7?lA#b3X?ErD?fRm{e?n zuFNIh`*IdMHYFuv3st`UYd)-R0LPK+8s`=R$u+V})8IM_S}QXyL!-iV3R;1F>DkKH zZ3gMo0z{B_H(}@N60K zrhP_C-oen`;fujY&yDH=9N+Z-tO?jB$rRQ^%IX4cNrFzZ%OZg^;+g@d9L2y@b{Xnk zExSBhreUY&;_xPFrZl>H5uVKwXvmr&VhbTJu(tfE6z)i`=u1n0`i$VKFuXFVf9j;V zVGm%G7Ja@Bu3&2+(JMeU0lj(D}+X7rZpA;eQ#(rSc)HvvUtGd7e&t0Vrv}lR~8B$ldqixMb@YkjvEw^)so z^?FD^CSlpzK5)0&U>IKpq2I+i+)VdlUZcz`xlqz!+VnDfBirO$Jkxft`&$6me%e z>8`W4Mz>=syKd7VR@-)5(cj+c!`;oToxN-w`+wiR*Z+I?g_q4KU`E6v#xR}T9sHEJ zFjGM5-JZWc4X*u--Y<7{6I{EExj9O2lmSAM?P0e7u-jW3@9*WvRj1kziT!f85GT& zc#z3n+1`k8nZ?+{kFJf3MoWwvMCV)r3)f6}16)Pd`YG{@UDDv=X;&P1jwwCBNNY zCb)JSaPt+vOc~hR-ez{)+unMAFRQ&Gy8 zUAOzY{~NDgCU%{#xw{^Fnq>e?MjLxOn`q1;!0o!qitY+FP<0~Tg7ngqcZUR`-xq<4!HTsKgBYzxwWwe#@DUwy`5d?>o+}GH^`2)0SMhw zxZ-C0Vq9=BpuSHincDZF>6URb0Q2^|^v$<)}DiR?S z%LTwSqkGj?NdqV_w{ilT?{5iOs|;D7yE3~bWniVzSXsGpWuU*Y_dc-e-rf$H1~!c< zpoyAc)=q#{7+>jCid9JDeZU}&vOKe5%7vBzCIJ7E(b zIwXMruB~GJRG1`z!j0MLJ-b6sSt{!KN+7{?ecQf+HBWHuV56;XkrA#xOIMOWMn+a07*qoM6N<$f(s^ua{vGU literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/down.gif b/trunk/docs/manual/images/down.gif new file mode 100644 index 0000000000000000000000000000000000000000..2194532b45efe0a14e3683762ff12fd10037109a GIT binary patch literal 56 zcmZ?wbhEHb)1XR-S9KOj6Gk zv(uF?DA~qy)uqsq?SBu?ZfF0LSxo!ltk!;7(v2^M`Y@jj)s>+aX)7CtJXpN@_u>m5 z^6Q(<(`Ut<|5q3t@_x~ge#?Xw=j8oxE*N!X0zt6dH?Na%a#iS#N zIAsQ@2yB>iMCD06QF?h^cc7uFX{Q>vdCQyb&RrKzZe8u-UP=OmJHp+!58k;4g7DCBEx@Bom$$USb??3VV<@@~j{PLXhob#OXI*+fv4|Q$q65s=T7XT~3 z;T53mC-8Fx$oLIxTmhUe1IrJAmEXX_6<}fo&|N{JCjt3kV3`a2ZiG22Iv^XB@!J8E zPXm_@Dlq@!!!VQXi-(7p7%~DIeOQ*aEq>Leh;^=t3&?KJ?OF6`BN1 zvMf>eF!&+RYQk z)jZ8beYpf4KXKw?*NMOW`s>w;frs}b;wx?MtG2(9y;**Le*gaczo-8FeKEYJr{~L? zA)$buV(oCKqT*LQ=|f`d{DYVWSq_iNBA#8PJ+E4cHcIOBIhwXB?9Qc3zUo>F!0|f$r03iQ2{J)!^DaZi?tM4Zk^$Hc# z*F+D98>9zt#sMd(A*E_%+73Hj4YZ%VcLd32{vgr?tMo~X!X?T?{}G(qE!;=Cmp|Sl z@+b~pjRe-%;_?ei?MW3+%#-)fJ{ z$BIVfi$yyR6V`SM5Pl==@26TL9buIy{%jYPd_K=Q0>Eful&7DkHPB&`MC-e{3)_8o+v}tz5N$l!8 z*{c$M9+Oe53xxD>HGH^|gJd?524yp~itt;!_$bXS*|A=DW-I8u%O?=;le^)<6P-Pc z^*%hM<|1!MAyAO;629=`g(kG7OG1y~JeZT<#Z#tIEP49fW+nW{+_rS((?nFEDqv?+ zL^ywbyx26JBfy%L_`MbJIk;CRtrgluAm&cj7^umW0C0z?WD0J(_N;ja+zQl2xbLME z>7ofC+EwU76bPZGQhL#1mVAzJNgYL(!f?0qS!Mj(0a`tzkLQ=~4*F@Pl*M4jVy$s4 zpy;t?U2o=J0_{eOz}|QI`d_iKUM${=+mfM4*#p4jt3y0c^Jq#NnAclum8#FJu;i_3 zMI@1Mm)N$)#9~NC!TqRLOt?{n)@xM<(Sr(=w(bB>S;Lo{a!FlE5vu5?xRKDrOFNRf z{uNkxs`yffo;TjxbLxbDdW+7dJtt^En)=5gR62}Arhtw6 z(DSGuxt?eDa*RltYOm@Y-UKGC-Af|?C)8=8-2PW1ULk<8R zY3Bj%a6Ay>p~!MQag?{b$kRAFr3@Ph@f~6<`WKPn@+D|hr3++cql#GJ3RPZC7?@A; zI2NOWRkze?wM{^qvy)*eeI@~v-+>8u&Pe(|65q}85@bpRPtA?Ujo4Y!)Kuk=k}hux zm56W9j zk^0n!@U}VItIBQGHUmkK5{7`V7q?T99X-M1LBsOOG~}Yg5eadwzO#N3y7CK9O=?lY z%hEAkSFPqhDbgz{k2VQ_*NUM|5WSUi^T}l!^ql9|y#xmbEjBpN_OM+qMs~|eqKr-F z!ry~((bQ3PHk~Vc?AVJK32kui+JIblNwWIFAVaML<-jpAPs0^z zOPK2A#O?ev3yQ#nTyMqhRg9Tq1cWx$bR1elTO~0PC#Chux?F_~)Bc1K4r=v>CM6Xe z2BB%_qC6g49lrr5db|3k0oXcONTsV8h;~#HtH|pSyHT&0-7=~j*MW#uy z#|1PAbQR&AZIs_*8wbl$?U6S8FlJ8JWqe1&})PQiG%Zi+80BlvJ+m@N%8Xn=@ zmgHeK-=w-&_tL0mV&qz+buCa< zdjhS)D_6lWFj;#@s$hVx@Plx5#awj&=5NI$h3f$&7J|jte$0t6jw0ouEf62HwGpvO z)%_Wax|W=nvGDffH>{_U4rc8>MZEP1A!ri6QIVA=xY$(T8)iLj=0g--F?T5b(u+Y+ zMZC)XO{w}zB9p_>Ky?~Z+-diNyIn`pF*|rg+Y4~Mb@T5gvaHeN+U&FVqdKP-Ci&4m zvtvZHk?X1V8`4}vNocv~EU}zZxQ5uEz-D{m%eZIB1JO#(E{nIYf@G_5KH7bB@C3c$ z^)-La{e|&(^Y#%!R+K-+pw)h4)7#kpNndDeZl5CSo zjuRTRhi4{dhaX`jg+TN*q+Y-g=#=1^jD|)@@4_KXF;Hy80WIjCdi6Br=xd<+y7taL ze)$1?on4%=GpQR;=T-m3G|ipr>v(Gsk;d1Wzw5nNF7cS3$!r(8)$-JGnObp;*#4KN zRg>r$G9(N=B06eb4zTf()GPh8ekI~F+VGsQpb*4H4c%CkDa)8-HH^NmIdh@m5q}_I z1*egd>Q(< zjsM=W5q#Tm(`94)2$aj%-w%>>pbgKnNUQCcoh}x|kPV&-8NA=6Q@3x8dZ3LI!V|Q% zRavg|f-MA~u`}w+6v1jpCs7C?QfFyGbZ!y2zldd7jea%G_hsWM<8UJ~4do zEQrDM`GT=9Trf8pHtM)4q)%CUhdCx^nawVc)-IBczGc2wv*eJ-t`pv~8hbnC4UWNn z)R0cib5l;|+e5;KU9ZFuu*T3hJ>qwN1h2-fpoW!iY!#=?EL5-*whpJD8tX#m#Fg(SkdpT}VeC*GF1MZp=OQ^1ZsH@!I6CnUyto@LcvMyJ4^ zOIW#`E)L#>wsB$N_ON&c5o9``mlADu3VO0^A5E91$AaSd@~2CHJ+tDqZ)qYO+7efq zSVV2japLf|HH;G$L#nj6aAywv;!aS0*ZKOQD}@e6v?GpkanMBXVYhon^3<(L3B{cY zE^$=5%L~x-NSN}H?XO<{OJTtAr;!`s$dpVlDy}qv4@D%G+KDTZ=vACbxXHWJhGsZp z#C?CwB(am9sBRea#USvGb6-u7p%`|S!G;x-+nxpvG**_h+U=gk{$!YJYE_`lcHo9I zIBY35<{PYqta#7_^>BD{APHM@b&9~63{Sg3*b=+df(Ge?0kspZW_k7A-Y*H1_+;{z$H32Gj32uFEIatE;< zks?Gb)5Cj6`-%DKm1JBJab3FD&ykz`Q5rAbVx+P80984CHR_qUrEqStSL3$4d+y>_pVTnhjF~8*9kkvD%>*t9NyvKi1v!E?{C27T?gd|SL*^RO@=dMVGDGUM z0R17|o^3gwLt%3RURulWi&XMEIt=*h9jAdc`i0B;`#s9$D0%VAW7};4? zFe8rwTxsod)lR!K1DZb+7TgV{ZzgxYCyHzHX*4663>>b~#~`F%FSI2N5KHD8#Y55n zB$9*n5u;eL%QnC8wRAsE8oDS{$48VrEo^)pN?_d6Ir22M5l#bfIr{k*KY5j(!&oMr z->1SO+n+Z#RP(iPv)BVDaGO?pP>_$ss1JA3y_rb#uXI@Rx~kEI|DY^ae1l8DgaPm* zzv2`*&!+0t|7?f8ZM!&~?U#)e zK!t|e!c`ApA|W`W^jrF-A;j^zN9|@DEfgImgGckTCki23TBmL1O?SBj9>6raQlQ{> z1lFGBpH(PUgg3RbB!lI^9R_~hN$Y%SLgm$=LuAG* z5fU|o_LgL&;LsY*XNLbg$00%!QR}V?-5L+xw%o1z@Oe{k)A9FV?T?BRH|qqTh7lMSfgQFaVl6ATN|-AUp_YZG1aey3x=IA2(ZAe`?g@Ykj9cEM zxK-&KE}f{vevkC$Qg^+BY-nZ$yHHwxwwq42yGirYqA#ag7-g~d>xhgn3Btn7UCS7o z_!rV#ftjtqv56|h;yi$DO#jUp7 z=e+k<``Rl}zxj7Po-%oNZB}t}MxDvpF97>Ry`Cq~W%GNcZe7b84!(X1mNISyd1o#U z+9ZvdIb@->zAf*2Z)i1l)I_YK#zpU=;aEd~BO%B(W^$sqQS_4+|HS|6gh|${sq7?B z#!j0i4H-VPx;=l_nwGSxD*yZJo}hgF{elBsa`$}hRp|ty=T^MU(cwRivW9lK>=Q0V zUTAmH5}O3k;Imn{RoR?QorCR3@U5MM8R@#y4tFO4AK!Z0vQ5xlV0QWTi@Sh|&mS*} zx4gg7=C~_K<7rNb^eUV5W?Q}~&4)a4F!xD5M-cWY)HYzEz#z#rA$F~}2x_&A4)(yM ze~ovk=rnNZyLh3+Vvaudw9N(w+QgBk`!4b{El1JjJ)^@JgVN*?qu7>Bnb|L2u%0e0 z_fQcdhQuBt`r|;!3*1!se%FDCI#kVKl-1wVz;mvlcxXKl;_Z%b=D5(gE_U7^sY3I^ z<{ZNT|CV>U|M=cLTSz8z{~TobbY1#WQ{G2T9=SUH+`PR-n0xC$@56%&cXlxV2Rq>l z{h^Xx5*!g~yJ6GdSRJI-d^~*$)rHiN2+&2fvVt6!C2H}SepVX;q|N~ghtgEu%GP%> zG~S!pjP6RgZT_uA-`-v5&vhAacS6j?ii}vXGK73R~a<6%r z5kxBEcNov1)={A>wF3;$b6gnBKPY7Gf!Pd+Yyc??O z`ppb{zQD6doQ=$5aV0GN*P?j&(i*2Q_Vzr|)Ma7hYwbU#g_)-;{QC7~>WI9P#1H?5 z>f=Iodqn!GUkPxq9l6}T>4#x@<$rL%HL=~W1>bDPF=gJT`W1|HH#?8_A`}j6%RQmR zKBjn@)i!!$Wi;Y`flIgQLDWNQ4+Wby40~^5o8@xy^2f(r_^>iIPgzug&U>-jgRIbK zuQ^w7+=N(Pb?A5v>dcqOvv+Ov);h`ioH)A;6MqE7J)P(_1=FjWuJ3fA%%K?DS<-H> zWTvcxeXtyFuP1dYNt(Q&Dkew!#x)}+p5SjI$9!Evr0H=lbU&Dos;D&D)u9zm`{;> zG#+xX%f45GW-I__Wc4z}w*&APv3&X!JDfL1^eI;o zP+Gf&mio%@R(^iy%wBKhTI+)XcIC*FqQRD)g|3RLrRwHunbQL&g_u>?M1SGXa(%JM rDqWQCsLbQV=L}hI(JJ$mU+L0`GCT5tuCDpA$^PbzEy3zzq$&#sES!!2LLYK?CC$U>gI_VZh)W;2{CH zcL&hLASmV$mJyB{S`h1DAE=7O)BdM}(!Ibm5HN%UK=A_T(hH}M59mG_5XJg6(|`-do;=*& z%}9-OaWD-CwA}=4D<~)!;fQp%f6>v_I6FJr!6p37gu}wZQdgaBX=%yB^TOTT?HbM; zpWt;rT7tRUj*p8h$xP17OrL#^b5(_vlbd_onmaW$wYo4mKGIuXSG$)2-`L!^->V1; z3PSImpeqe}dU~!lro%!*oL&gVCneowKRL9sx)`$<^AwznF`WA*JD+lyX=`iglVatY z!l~;=F5`+TVy_5~0*g8bn}(n<5A-T;C81$}ApGIs;oqeG-~R7AaFoR_^sg$uyQ;Al z0FVs+FR;?NN$3H9icL*XPS3|;&Ge%s-9fWnFK*f-bNm=v>^I@q=M5ZN;ArTo=C8Pq z{NpxksjCu#XWi(oyB*#j{c`@9itH>k_{7zj1@o}zms;_6hk13gbC@dg$=~cOhp5ss zR7UqfMKgvoXsw6woV`N^xV?7^dCEcBq-?i9J?1@b@6Aj z{%={JpKjOs>T5?tW21=nKnvkLA`Ft4J84MhpV(s2>2t2PDYH~JUpZGZi$u*1lvKq{ z$$ZJr&-YC*!rgd&{ zhY#S89>2Tmlc~1VqyYqNYn|SCK_MZL{yzMu$8NNuz$9YIy!H1&iwWaT&4;_| z;5X}ua({f7wGGZliHM8{=+^ay`1!~bU5y<=4jsF6TnrL<5f)1uSdPl>$?afpUD$YugIrqrf$?uY>uf`#CCmsD<%h_IPTW@w^?o%C$)|^%M0ZtHb*#9a zom%7`pB7-B`_=e;L;r4lS2~Nn|7@|$*R;l-S+Z(wdym-e>eA+r=<0O};3?N#4WCF6 zo-B)RmA%#r3VKLu**G40xLfGEz3v-d*4d7~YEC!r`sN{YB^`ulFX;^mcMIDg{wx~x zx^-+UFq%H=DfzD^eyJr^8~;goW1pC9mIob?;N11t_3!az*Q$_=rVqNXyTj=~q1Fwl z&8Y&ZyIrQX7*+pX9WHDcX%ZZ&82X}F2WWG7hX?Yeu7(Z_5nS)?D>NL)E-!9I3n!8(GRrc)=bsf&+EiV`Pc&GLVdMjJK7Lw&- zGuDMJt(G~*CRXQI=@sjyuI>){4~9!u-wxxQDmwaZr=rhStoLOjJq&zyK#PgZvWQ$nK=2H^c0t!-NR*F zJiQ3{dzh;4@PVhj!d%7KU1jA$qd50tc5=d^~+;k;y92 zJBHZgBb|-G(NWc_Cx?QsPrh88{6!+uk?bO)=+`OY8SIJXiL_(#VqK+nbH-g78e)Qx zp|*7l_Qa8K7%;_q-F3c3rIqtyCcVVC+hU6D*m^0(Mb!1_OkZxzKqhkj2ZJXPQfJZC z|Mn4q)w1Qt_zYKS(4@ zVC;`w=jf31R1YfrB>HvL)smKd{!%nQN52*2 zz9wH`G#J1+NmmB`lxZ|e+lbe;@m(8!-rgs~kpQZlqig&_Wp+nx1uuE3vzgF6UV3}Z z^r3J{@9h)$v=b7Vwig^9%0Ql^*LQ|9io#e+nxgTUohHE^FUKW<@+*dG9e03X$iLFOt2Kk8A;jFdW zCNTdX|Bj}m$`eMzqmhNe=K(K<3lFSGsLfG|`P_#v$W7Q^0qHeEJ~+##SG8)=Y7%l@ z!(yt0UJ}MXTw7i`>In^Y?ORfkmdBRV@`g%Z4lI^b1Xf9`Ym6Ns(aI;A?`oROWdh74 z!~+6f{HepbN5s-haZy#vh?!MzX0=q0joBXK4)qQ+Xid{_(29#6;iP?&C^4n&$Pn^A zh2b2hejpCC1QY+d&qpY=P-*f=x1yweBsC`K0M#If9nHujCbat^231k}5My{KzNuUr~mu#X}ufhJH>R&6nz z9>XZbzR=1ELT7{)t3CsbJ1^|d6LEmubk%c<_-)h*wdxDh{_JzGG*+SwTebLVNl3T- zU7C$HimZma91E~_C+833N-&;PZEKYVN2cs63k>-mSca2Zm?X#3XYvLs8yAy3l*+ig zu||>jHPvbMGs7LWtuKj&OHDgi6F(U_SjA4iPt$a=8Jw!@j$7U?$$fE$x1^qa zGkoraI?*NzuIs6G?XvhXpF64COr|Rv7@=?+Fv>(H>vJxI?64LchsyH}dJ`U+@G*D?W96}woNk_^i z(CF*$JWqpLa_>a>Tnvxc@1lNo8`OSn*?)U)%7y>xhA0+votP_vS17xh z`!XBv-WOdTW3sWavHU=Ad7EgIxueUo6zWN=UK{dGxH#Cjx?{nHJDQxkZR}A_s)1c1 zv!DU5HAgOWR%8DN6h1J}ovdTy#_3SnP*nu`vCk1pr_TVI6dd)sRf}!{3u=^e>+XLg z^P!iDQ&2x~zllVT+cDDpcpx^+e%JYlnp|e7LBmneGL1I%zk&9S{6Cp;%w7UX)#3=7 z{-zMDH0d%3j%@r-->um8 zTXUp3Z<#eOi`u_)H2HaxF0DDih|_3Gf3$QmXv*uB=QRwqK+;Y09$#(oII+EX{n}=L z{|f!^-yTV+*4M%hebtzfR_ddLG{w~&;rdIbj(#+Iy%uW(VO*-VnCg%ECpGioUdn|+ zTMddvX$7p8;6UdslWDsG+HSG0&(RF|Id!hQCcuO<0iArZf^nEy6b{# z+U?)`R;lfcahA`gGu|x53CCBd#QBbwmC{-y!*WC$f{XYuwy_@(AaTBQO(q5K=YQAQ z%iR-=Tle>TC7Z*2!_yb;d*C%_PQDXCGnSxEg=Yj|-m2K?wVTY&d&12jYg<=W(pV7d z6Ud`#OI}xz)tAK*-ZyEdb70V$a`&T&{Yx97zXVr@E_A}fj*M1xu_!4+RQj*CL>H@Y zC8-kF(D|E97?`*9cU5*iA^KCSh-Jtapd5jX ze_Kjy3mq|h6etE4o){G822mDIq>kgG*QjBI{gRJ%&A!08bB4tSqBfYqQk9J7>ccFa z8Q<%nvJ9K!MLD*yf7-vMUlP@iHmf1R#U3)<#EkxUVfGvnRyqGe&=FEEgqNXjocP^a zW|BOGF+U`S_j%N`X@phP+zS$-feb6q*?&^xs%)~2XJKuB(5<@{N;EVS)%FKJwTVQu z7S%UpM1~&N79-nJjP#V?I&Z0s2b^f%DHLpw=E-1ZOtO^l#fq}2(KF2+`eG|c!6L&I zNQdPFQ2a`&`d+z*Pw#sM)$S07G>jVM3^n|kCEd!Yf_w9I@uFk^DA zwAc!aQ#O%42h@kZH@dxzSou2Xe-+XeF;L42Wu*7|eBPZF7WL7gZ_pi&SHJ7Qayfq+L`wYePox+=Q{XRt+6Jn_pa(5knzqug(UbFlPNC;-$X?Crn$lRz5C<_a!EJyVO_gg&(Q>H8r@t za|_~q_gWaY;mg|)o|fQJ3cryGnn08)mJoaWD)k^!#E}>XjnGsTe{5>e%;Qyt-4c-B z7Y8>&hC)H@g0$XV5&hmnvh#>#S_BISMIGw%ngv^-F>Q>}#}%P-IwOC0{TWU2SM2=w zN;m4n!J1J+6ZEIcU*lPjGm5^|pE{n{hfq$Gz6_UhonZ0`vwWTkHPd=2_Ex-% zKKwDhmEyQ8c9FBL(Qr}m(l@fvO(?dn0l5e48DNu6>|I0@!n?yLHMS>HctR-DjbHoj z(}rnI*^coRpIGoP1M`tAQ4q#RLw+5*3D5ka?Y^;P+{Aueb@Fbw>|9 z7(Dgc%AUp#mm2>*jdE0t`4qp5^HiS9J2EnUnUPCjb3=3QO`-k*&5=B9)R#3=PtDjW zL=X?>HS2wfA%UUr9i|tJJ>$+_q;wk1R*E^8{F!t`#qY=OGG0$tqG{7l!Adn_U65KNluH3 z7o&0c1pBj(#i3Rl`^Ln<5cMankc@Bk7D_mKZI3aPxrHwFnUAK9`l;0#{kLJ%xNko_ z_4TPqtR`13=4G@a7J`M8W`WI7;DyIXrr~X$A(fzly*5f)FpXLFcVyKd zu-*^YbSQVab%BS8+%pQXY0b7f)g8*EITahN(I+rCeZb&bN8$4;(w*h)`=^o;(Bqg* zRmvm}NynTaHG*L4i0L=XsF#H8!9cPI4?~82%hiu*HZ>X!gS*?a+s1_tf%vR#O@EHJt`s1c zl1GfP+M{U`O&X=tQn{e?u@E7TLHW@Ptfp{J@6C%lmVG+jU`Y`SM<%IM`!3lZ)BgRj zjxxEoqPyz5$t${kcNxmfI3)_~5bwIU0o1;x%9A1<2|L(hi*uh#vtg7(kHT|0=BkMO2~~XDrA>KsD1U{WL!4v0oH9;(nf<#^{!nFPC=OV{yOGy{$ z&EB4}qSEn+!T?ohMX^;>sHZa5INW0^y6x%xP~5Tj>C8x@vw4wOqBGz1rRipl1)YW! zlq}FI{i9LeuL(a&&s{jjOB*w;DJ(0UhO1W^qt7pVsbK=Dg~|Xzo(%exaYcJvK-c;g z-X<sz~kH5!fhVdwp$r~AX{EEXLJ%>y+^wIR} zvBj^Hdpy0lfg#J?v6p?p5kQ$7X!yLn^z(&8qtOFaWlly8l(!ZtNE`$5=_Q;B2d>R( zX}cBAmQ_5CI*0 zvJL{*KE8h8`&Z8i!Ng*Fe;9EhymP;vzu~?(3fyS&NAijLOE|Zb&#JGKaJGJ{r=EF2 zCPtjIJ06u0daEMWYXn}q5fN7B+Kc(`{Zp0zwTD_WTsr0H`=`f;-XaITLAcMZgtIQf zoA`c)l|@`6x5(*-#mvv2Z(Z2aG5h+!8ca&HIlh>Pnoj&)DS%=Ts6M$}$8xRfVJUP^ t@jPMb1S&4cMGnz4Unov~gt8SsK+N`@9U+=c%KrCxtEQx-SSt?={U2iyiUj}w literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/home.gif b/trunk/docs/manual/images/home.gif new file mode 100644 index 0000000000000000000000000000000000000000..11299c1cb7ef6aed8ee4b159d733668de8662f22 GIT binary patch literal 1465 zcmW+#YfO^|6g_P}`hb?UfCU7!Ag=*RMW7WJEwIjlKme;k1}ab&2*DvZXLNHgz%i{n z3mR9Y7$rv8M5m%)l>+jRM?iElgAB@Rn)yW3VbpIQyFYGjZf@>9=j7ZC(Vxqt=^BXf zHG1$6}$N0HhEs1{h#YOn?T0#13OAoUz{88vFO7xf%Wan41F$ zvoRaJcqhiP)8UXvpx2|Nh3elp3tt)yQYqY^Tv(twRYGu5QmA5745xS7sN%vC{1a{s z7U)dSd_*{cTCosH56Iys5@GFHjE+L-f=rMsSmeS?r&Ew%e{enws>#Z~@)j zumIC+#{2h}RD+u0!rk4PIpKyfk1GCY3{@(^k);q8h6kaEb>Y6L*u-j1;`ym>=OC^CNoG6R#aAIEolu&@SI z9v=Ac0S6cyBTka2p5bF0qQfx|3Q>mmvzd7On8E;ZIamZp0a$d3K3w4Ja8uv?CFWrRB8irk+8diujrupK}iE_ zY@kvhGZRJ}+=V#;%wyR63m&$$;pIylg_y*4CvaEMkpMQILV`&FXyJUUgqK*1&`|8& z4XqX(9n`I0u?U_}PU8DO0!mMa1r!Co4}v79^72Aj8b}g!8YPH*Ff8;iKSh|WEf&(C z(cr`h*z&0TZGP~y0-Xco!zw2SazD(^L+%c_8{QP_{DWRay zqPC5P#YK=6AWJE`zSS(Lp2g!qr^CgI6n&x)1_HGAQ2eI7g!#{eSo^<)vRxus?#vc2+eTOvP+lpVZ!Fb7Xp_TZ}$yX4uG^@QEFF zco~b74x4EGT=SW}8s3B1FGN3@i@v=QY0yXi))o{zZvQb?bb3v{QCcKkn~PbjM$u?x|e0@l@=M028tTa{kh%sHFXdxbw5B@+uRf zLbgScD_L2eJ`owZ!g&4K)ATZpTy*VOfl1RSOX@8c7WAxXt?}J{%h}pGk+o6ia{QUz z;^6y7nz0oz_8e)L;bSmo>+=n!&C`_5K9cINoz>#L+btv3(IVtA4pZXeP z!q8hnq9bs->OPIf>C3PZn3}Kuk?}wmQR!vN-Fw$7z)jpE3HFC5=U#FK7LE*K1o zO^7<`VCbX0(zD%WI->b{S@oSgbeEk)Nfv8ob&B(6+z{}>FmH*;fy6SGG!wlpY{R&? zn0xbPdusfD_sLtamKk^=)G&cCj?2j;s*`)?b& z3j5o;9{pY@vT_cz6siQD5uWQ6`Y7wC>hU2@#@F|Lu;Oss%J__+(+aVruBm;cH#rjB L;Md}uqCn_>{mJyz literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/index.gif b/trunk/docs/manual/images/index.gif new file mode 100644 index 0000000000000000000000000000000000000000..741c8939d77d2423d67beaaef8fe78aed13a94bb GIT binary patch literal 1540 zcma)5X;V`N6g^2EAqfEj3FHAmLln@6kxfB?HbDhZNdqfbC>Xlu)u%~i4fxr zzJ!Ylva@mP7Gz+zw_{`kMmA>_j_13=(h?F02v~kb=lD2<&y`h?98{sgmB3Y7|P-oTat3#t{+%}_+4$c(KApcmUwEFv-z zQkXL`K&NAD41LL%jpJryk+4|17MCw$Vge?%6%BNmEzZkPk^&wNT69%Zpr?mYaBGFx z2vR77uP>64s45aIBGWK5aSpx$Fc>H=$Fpa6{~i-r;BesXj$ONOAr>|uii*(O3=V;B zkzlgJbM#NBV6>%t*;#=sg?S1Xr!ZkcwKbR;r2Po9pC4}Apa6m=PeAfOa$!ON1AG$j zh6_Pp>QtnrqP`vf&K< z549Tm_oKBHeSMS{HZ?gXC;0n=57HGjc5obzg$HCZNX#%0V4HA7EJjceR;|MJ?a*pr zGEpUL#Eu9-{A4CRBah34rzb)~ariJ2p*5Q+h3BJaS2<8dY$GCY-~e<`mz1EY3jO^k zo)4KA%dtsDf&-efGxow99Ss==$;og-*v*@e5pX8JWMan->TKjp;NwTQ2~o8HCKZGb zSX)z@m74b=E)Fd%P{QvCHZy>6NCiy9$taeK5V8SezeUz8IGcF?-Sq!XUSE)3enHNf z1dSzHqB~u$VezHw^t#eUP4gzxutT0fms>j#+^N5MwsCda9aW;A_roSDIF{W-%W4<< zDe9IJ^V^)Fg%gf#8e7NfD){dmk4$i9+ z3Wpe@J|?#JZ;wr)%O>B3Wy1S4sR1nw$0VqiSa>Ith1sm_{3G2ep^>%Z_c_s9RVi!S zmW3Od3te~hF8^LNW7peLq~NGjR8P){yYT3AUrX8U684qS#d-3=r}mfb77*g~{xdST zq0#5G-!BvwPHC{gXqFHg@^6gU`rXBJ9o@8Pk$e;;{PdNFnVP8OfEo>nO1 z7mXPa z8}g=~3>^KF=R+TS?B~`#ta05FyyLE~Qmb1L%RCyJIDg4-`hx}DK{Q5a-=1j&PDfGN zb=%1CzwbBKK5gk7a(b1((%M*>HcMj|M(wyqZj|MUAev?HAi+p?Ve5Gc-)*d>$N*LF OiPzOh=dG1;1pN#BQV7)m literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/left.gif b/trunk/docs/manual/images/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..2be39310bd7cd10303d3d13480de0662c0aa43d7 GIT binary patch literal 60 zcmZ?wbhEHb1}5R2{>%mJcjSDEc1fjjSMA^1 J;Kj&b4FJr158VI& literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_filter_new.gif b/trunk/docs/manual/images/mod_filter_new.gif new file mode 100644 index 0000000000000000000000000000000000000000..15660785cda020b5044d0ebc6b0ed01b1b54e4a3 GIT binary patch literal 2392 zcmV-e38(f)Nk%v~VW$C00e}Di|Ns90001li0001|0ZRb@0{(=LsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZahs2`sh)gP%%%<}RjY_A~s`ZM^YPa03 z_X`e-$K-YS={|^`_I7nD%c!-#&xX9S(_y`#(Ir$M_ zc^Qy_nR#%zU`ZLu#i^MoMDE8?(9zQ45d@YKqy}>xrs+dn}Wx z{J8)F`A$!c+Kz8BE)Rb{ zFRegbzkCEW_#(zESSN+W5Dr7Q?^nTz6f0W1h%uwa{*4?vdi)47q{xvZOPV~1GNsCu zPu8(~S;8gEnUy5cyh*|#&Yd-7^8C4rA<&@~j1fHw3#rnjOq)7=3U!9hs6VGt-D&lz z)~#H-di|O)E7+7`$DS-}Hm%yVY}>kBgZ6F5xNsUu*Et7dxzHzy4lgu?ZYgXb}>Sr~fli4Z#5;Y9fej!(3-O@D`*rS8c zW^uc=kApgEnlq^TOs;w>=;mH>yyS3zEsUR*&72%3heo;e4o0ea!+_7%^0p~)I<|fE zep$~>JUE!;|NL1WXwP4_cc;dwU(fwqet78q>pcSupDeuK(DAHo_-<*WK?6tHFs8n={GWjwTIxWN|%ifFX)cB8khC6jYhxl}_4V;{;sd zs2rA!X&ImsP$sgbDnx`SpA>B#GA9UiZVAerw6v69pML(?fu4b?Nu~;d7G8hnt8i6w{ z#`z+Q5N$`Qq_ehK>wwN&!=a36PPqPQ6r=v(DzYl#3SocH{^qNuBsDu?bkH*C;+C3DoVJpyZtKJXv>YNJMDYh z`d6XC*#i4(5*%t0{;t@qhx1z8t;bH!b@aMITWYY=wn7Z9u9?V4 z-PE*>+jP`aQ_SjuVuyWWvaPKwuRYp5 zf90`@F*|Kl0o6UL=r2`@g@@ z1@C@tVjt8Dh$jLz34Nu@T4ogJ93H_>VhFU$=X`{}1h(mT0Aw4kjuXM4D9{@D>tNo1 z#;cm84sPIbTfkDdF7>5teqHilt^~9=>CjALiIY!wh$BN2RZt^4>qie~H!~EbEOkM& z-twN9Ao}5Mhe%Xe{x>R@jS=3*3Pp@rd6KrnDb6bn&SOUx!Kg7b8u5sM107tTGqQh0 zuXb8Pd$T<7?%$<1KOlUogJCnn*Ek#dTYY{;~TKC{QYfS%7&mODt}3MfGS z9dM9;#GE_+6iUo`9Xm|45>p&+0Zn_)Pbn$6+i8{(225cjABHT+CF6`evm7GD>bR-it5vdesEu< zu;Cb0NXJkK=#EQ0>PG=uFpR2Gf1^Vg-F~>R7GWo=2s>j?O*qY;(vfL8^qUn=H`SE( z?1W@Z=RJ`|GMTw3V}jkQSOxmmHvY_WgAF4VGdfUZ%`=$TTP)(#m{+K-lp~z`Dh+B{ zS=#wbv?hfW0_aaU=&_9)k`IXvxffy&wF-q4E}tK4r*o7juOu5Cx`Y0qTRT$S3U zrT&aAT`gPJ3))A$4}W_in8 z?y{E)VdXD}Rm`LzvzgC~<}{Nb%xZpKo6W%HH_Lg>bY60t>x?}-W8uzkUX-5WdH!5j z(DTnex|}KuO=wz7@RuGMxEK{IxiZ~mcDfI9KC6sW%|pbrWl_; zQ))iRIn{nSbzWS3RWHMukzAfNWUp*%+DiE@^9`A&JxpcA^xCMWwUexKTVoR7F08g^iQMcJl{c>|^x#nGq zxtXP+)gGGVdAkRP=jC^~zm4v6Bin}!+iQMb6kL)u@7QjL_g5Sq>tMG5;tzkLnJIqL zDMK9NX`!~7IIb3tBM0P=xwFWFeRA8R9M>y9aLbwf^3KFu)-!KT&Bzy5KZ)?Vp~juPP$Z>=k%yced<)Ny4A0a^{i`s>s;@;*S`+-u#0`{ KWUoL00028IDacU( literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_filter_old.gif b/trunk/docs/manual/images/mod_filter_old.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9a9ede2806ba0f3c9f9a04a94f10fb1d926a4a5 GIT binary patch literal 1230 zcmV;<1Tp(ZNk%v~VW0pu0e}Di|Ns90001li0001>05$;t0{(=LsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpTWhk*>Sco;5(KpoPUcp9W4YExsaWD#3W z_o`JKAzy%186_soXto**fs!`+)>Biw`Mj+$QO4wMaQ_5Hdgqzh?qF3 z=m;oiD7G0%c`<0IDJe?o*?Ia@_KE7oMD~`~=BgJP>c*O@yUW|_`wJW_JWO0{e2ko| zyv%&H+T8OD?esbgHfs%pogE#^-M#(2BQ0KTevY0Vq|QUm&f@+qKTlu39B)s8pI^oA z{|_)At9=4D5G+^;p~8g>8}@T(;vmEb5+_=`h;d%U{*0VBe%R=I}`a=nbJVh}JL)18GMUN?kNHb>bjolqyve*hY2B zcPZ3CdnOo;h`0e@IbtD^Ei9KzVpK)WNKUv5?PkHA^nS+hxP<5>-Yh5K>H1)5eO-Oc zKHT@JZrfCuWk(zE%45?Ayn5Uy6Nl`1I=soL>(=J^l9n`}=3dA0OBaNML~h8Wfy!ycO46ZVMvU zAY{^omLP5q0ym*92YL}9bRJ4}*K1XJDa*-t=FhiprBF zI*p$5=%SKN8cd|+SSk*tly1uDoAqhR4XB-tO6oYDo?2=;hpx&hiE{24D4lnH0_UI< z&U##yvEm7=%t+ZpVu5Tbjly%taW(VPt{7;(QKkDPI()>0xW9j&fxpiHR3mvX8y z&)h=H(AeAz&NT1LvvM!Hr*qFj4_zw9TBYCWNqKR#A!ep>i{=JdPPZ{Ak;~xHk4Tk^fKo3)sJ+ s1aNNuW6A)%azN!Iuo$I_O4jT#H7rzZA}v#z1uuxf3~F$LoGJhSI|SltGXMYp literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_rewrite_fig1.gif b/trunk/docs/manual/images/mod_rewrite_fig1.gif new file mode 100644 index 0000000000000000000000000000000000000000..664ac1e7bb7a186d2c6157878cdadd5bfb7d3466 GIT binary patch literal 3525 zcmV;$4Lb5iNk%v~VXOgx0igf@000000I&Z50RR90EC2ui0IUIl0RRI2oR6u??GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4KDwoWr^9hYgr_`$T zip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k&V$j?e4&{J#GW7$`VMSZH{Nn5ekO*y#8O z87VnQS!sERnW?$S+3EQS8ma{VAZi*%daBx%y6XB08!J0YTWfoZJJ_1b`?T8&tn?d9 zTx@)doUFXe+}t>uEKSD7VUw$V!fPAKs7Md zyD+KN9Q=3h;kSZ|nq;i_tyjVj)go#8aj#*#l1DDS3)(Z@%69kyPTY9&V!4&)rtBFx zuj2)w`FT#Zid9C@pqy*6bX(4r!i z`&oEWA8EOQzK;7h-_)wNdu5K?Iehubp{JLgo4RDqgZ`)Y*B;$$)*%+$dHscE#A{gb zR-kbH1*IQZjHxyr2lYAeQhMI0XB~uIWhh>7=EXn_fCXlz9*RV4IG20X@n;)YEyjqV zZzf#W#9BIHb|Q;WnUx=P*|kMtQ@s&q*LfQbkywavf%hMh?0vUnUk~7jP?lP5$z_*b zehFrnVvb2>nP#3T29{_Bqvo2uwCQFpaK?GdoOIS==bf|Usb?&FW&>ZKf(}Y(p@H_f zM*u!3is&7TF4|}vkNz-eq;FK(1E!X;q3H^pF7W53V|Z$>}`s%Bqu>#xc1iDTV{;D&&R{HCsu*yp8vByf1Y%|O9+Ux z-3#mecOiw7a5$cc3$nP<;RJq2<6evY1GyoR!%g|+e`u}&=de^Bx#tvsE~n^zl#IIR zpR0~*Af&ghHS4gSF8l0!yl#8wxx0e|zaD&_XPZ1tY z8sBI|GGg#PLSdr?;8?|v9qvbAnbL=N1Qhdf)ZUCxu8f|=>UjiK^T)Xn(x5qHnABbZJemex0KS7O!VPvHiOI4 zbn-}bfu$R3X+v_v206$;FM3iA0kfKH24|KF;HD2d zbRTN!D4cp3&Ii01OhUGDkjTWQh(1H1vfzgU==9q&4^*N+R+E+Z5vDd*iNt1}U>K-G z&pMFgA1Ap;K(B0NDE{eqOAToel@Xoi2I_gEdqydR`rKkX56Xbri1afU4FN$zN+EY@ z@jpEpr3d^;AbtrDV3 z8zUqoPBzGn7d>jJ2p9ykQema15Nyx@3k1VTK|6)@D+(rP1jQ<4rlFAR*%12!%R-@` zrqJvLAX@~_o=LR-!mJNSTPD-g7gL!zm2Ld9`Fd@01J4)Jd^-|4~*ahD_FpK zeC~oD3}HALIKmXJu!YgsV1Wo0zSMGWW%)}=5SMNs8x}F(JPe8wvkS$aP_Z)f`wAE1 zi^ZOhG0|w;2^${+#;(w@F?hTRA2$uhoDeeDh`b3Sr;WrW=5Qo{tO_Lq1Imq^@QRsi z3tW zla!qSrQ;asOrmg^adiU8P@2#pim{RgHdy&pneohVSpnZih{MM+D4kU zC~y|7O4MBX5~l_oW-smO?RJ@lk_OlKKV>uW6Rk7dx3zRr7OtcT<>%jfRx?lveoX$x z=KQBFdZe_y=I0URQ%D|_d92BZYX8EYstA5?*kuPLdhNN{4a+L37O=#vv&?H`#b)ux_e3j_lTMFt< z^_KH9>jUok*W=*KvL^!VYmc(nJUY4n><{pn|a8_Mtg$NqLd{;{RM z{N`_e3BW)9*f&SBU#$xJw>Fs)fcWPqKwyAMAb^pBGN!PAmeYXhLOF;NEuWQuNAQ4# z<2PoLH=vM#zXJiX5-Y+YEX+oNv~nR12PzWyI3ZXzD0nVp(<>ubfmgzUdgFpWGlF&_ zgC`h+sB(cu@PUH>gy7|aNkcY2$bl;u3PZ>^IruX#h=ep)D{q5bH~0;>6@*3Lgsw9< zOVfo2xP@_`g^1>Cd^0@jMl%9uf-2aCkoJZwvuWnShC1kmb_j=fh$Cf)Gyms@e+Y;s zBLiwkhi9mVokEClh=_Bjh%2**b+~SPScrj0iIo_L6S!J;!-JUP{)l0?J7e=UR%jt$ zn1}r50H7!}qWD?$w_{^ydmZ>JG02Ho=!#!xHFsl#jzfzM2#e^lgq`y^wHSdG&@o7J zhocjWyf}>B;E7ToiOeXBLGX;-(2P+aThZt{*Jz5RvW(l9UkK=pDv(^&_&=7|FyV-f z>8OscK#uF^9Pao9?Ff%BGml*$kM#&%_?QLvh>!fJkN*ge0V$9JNst9;kOygg{y2|$ za*P}W01t_J(ROnXnG_F69uygoS#W6?NrswMhZ1R#i}qO zhk~eW$~I857HZtlcxS*^AZ0@>`960DFwZ8FN0e+N$&o|;bdy2F1t>X`KzVFBDF@%i zX%N{*ocC3Kgpw3#ZVA^?Md=dlc9Ix*l~QSyLbW1Fxp-n3Z&In2V(D>M`4v{_lBIZ1 zZs|}?(jEXsC1@FQwqcepqD#`c!5cEh}o9Zv_B#TP1bahF$H$4 zL70&#cwos;;c-kSS5Ad#m|qEXgoSaU$(J5Sl51d^pmv!vQkgfUP8F`AC znin~4JV#Zl*_wQ}8h*zLE7h0!)_5NUk~TF=BJ^@|_f$%Gl;pv75wce`Wu4R+QyF&$ z&{=w;2~Kato!$v`MFM!8$#_o17KP`UHNsCEr+BO8iFncJ253p2huKnMr9p4WmV}8< zdP$yhX`5B4cR{%WnrV8Y*K~Ht9$^Wa26>6auilG?+ni*OG#mS)} zv7sL-q9aP8CHg%cYNDH&qEHp0E9#;z3ZpSvCMYVSEkL6+8k#t&qdUr@Jvt^g>Z3*( zq!TfuMQWr+`U*gbq-nLJa@C?unwwB6rBh0!RcfVIilteqrCZ9SUFxOoR{#JzTehj$ literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_rewrite_fig1.png b/trunk/docs/manual/images/mod_rewrite_fig1.png new file mode 100644 index 0000000000000000000000000000000000000000..f914f681ad73b7beaa007a8a336dda10d6b8de1c GIT binary patch literal 5597 zcmeI0c{tQv|Hr>$Nr=i#L?}XxrD$w1DkRy)V9XHBWEpGrEMdmJ6*n3CzGazV5K3u= zK~d^X8EeWi$yT-@OU+NuecyjR&-MKEyPoU!d(L&8bKd8C&-e5FoO7K&zOQ!@%-o2N zN0bKu06ycZ25wIbEO z0$&cZMBy1%K}MxzO~A`^w$#gpE}$%F&J%IT{cMUxJeoX01WshCps%2U0x$W5{HHV4 z*8gSz4|^2OYd~wz&!oC_fsGD#!?##F+RwC-y_{lNOhHutOac6#p=-Terp`YS)I}>1 zhUuE<(S^tF^OT5{rCpk6t$q;o&pd`&n|uRrBukL9`aL~QkiD4KJqC`^2Vs~KOM(5c7+FT)lDW_A*`^r(-G*@d%?;!PhWXELg2$p>@mig^&i-hk_ z56ra&+m3$Pgn3WXlHy}!WvuHx4eL8*@yI9L3a0bSJla^ucmsJ-geu(CuAb_gUPY#7 z*)>`mybua;n0&RP(9txk$UI-GLQjGwEHABJ+RY2c>4fTtL9MFPH7Ncgjfa~zIu9v2yT)P%A8{$9C^)VqlrqR6z)+^3bx~wQ za&Ip!-#FHA4K}^COx&{ceNyt8Dled+Ca(>bx|~rd5x^RZ(G{XJB%cFP4E|W&S>muo zb_PsX1-b+kTD}(ukzh)>6qyv+1rolbVnotUeb>YL0AG!e(B(M>HM#+H*u#e>7E_ zGwiU)qEr;4iVZ)M`9+r~4?lA(Fo`zfhC;SE zpB8lHW!~}Mu~=s#7R&xI#d?Ba5Z-Hg2YuO;*2f7GanE*3f|14SdldH0)o<%ExB^OD zcw{yd@N_ac!)!S$_*p2YkTqL#x;>k=Q!knPl917r7{{^%iVIu-KBBcmgZ;ivd5%Y&m*}MG;pY zKtt{-EDE%Y;MRgE3(wn(aB_R$I%o&*Vje~%YN+~;4e`6SkQMlBPrr5=e#%tDd}%A~ z`%MnlAsT&rTNc^9be!m94YWEsgAY?g5rC@G4=0U?Y&vmp|Y&HC7$qC!0})bUG#@fFJOWf)eItwOUjI-W6a$6Iz9gA zXPa@ENDS5)uyfG!v@ej8(LW_A@TL;8mHHm+zIV_1{%k~n*pSGAE;zI$!XYi}%S}@w zC@0u6v2xEWxg-5k8d?Tgys>xWl6BK$q<40eqf|dCCGduBkUaR6AD#IbhW%D)+n|I9?Y{s6q){8RSgMM}2 zF<#DMFAHrcXuK68CGtSU#+H9EOaiU7{zi+qoA@p;F+4Wwv{sTKp^#aV5;LBOi0c_h z9gn+~idKP^zV#m}oUd4XNWQk-KOIo`y|UG}M$v{-a99mVn1zQ51Qdd0YlcF+?uptq zZ+lTX@&z%7tsJjR^}YZ}XeSJigT4 zMqb!@Gx#+=;&43iflcJ_k0VP`V==srb1&sh-IES{mrpy;!`%*y7`2HKBM z!>@6tw^U$TN(b8>mDY597IjXrjFPA)WJlRcTpawP~w6!RJVNeY?MKOxd?3{85Gz z?i2^&>;!3cbY}A>s=)E+G1C3;IHJ|?c6RmqM^4*mH*=$GkY7-G*C2Gc7n#&)4l64` z;?CnW=)y>d>Y6~5Ag&qpoH_K9L-q0V#PgW3r28k&M9et6tr(P;bZ|O>I43uApmZEk zY0jTAvMQSKBr51kE=Sk;L1X^}5v3B%2!vgWVZmksV{o#1EodAYlUssbPG{ zw@?0OyzpYU)5G!F^zDoG#A1n6Z?bas{V?T~?)P)%RaYX96XiP}$XZy2Xl_42oAv8z z{V1KCp#diDT*#TE_j=7Wo7jurZNty2w&_XC9H%riDUff;i>5$5zNTQrZAJMc=O`AJ z-m2}f>CQYj9H~ZRzjC^pZ-qz%Rt5#~y#pW0dVP+#plD+n8;>ru{XSqXg&uVtk_IP@ zU}tz;1nWB#0|QYED~avx(n}v5P;*5+x@j28-|l`d+o&eqbJqlKF75T0{Fv?+g()Wl z;eLDv&8%AiCZ5$8n|g6QmED}UNaVKEETJo$M=}yA@-frD|zCmqb{jIOW*#PtmQKZub7~SLaY5NK$#J27G zMHiBBxy;RdF!F|f5*tG&SXUGI8(kC3lXbNs)OSX=Kd$Jn2Jiukj}hzAazjN0P)Sw+ zCzb%&O2NHG=|1t9y$&6DErB!g3a?t`=_Q5M5!Xq>jn5xl^~s$-LbtCNm*he(4~LIP zqxnqQaAnQGXE%8_WYh3WS1wB@ZWQI+3^vD0Vrj%~lehZ!2WEVEcmnwA4JGmgdpmxbX_yl!7kklVzltL(ZhP+HocR!Jn^k-2Ge?WgA3(~4Ab@0p8$yWq=+ z7d>?b)$9kB#o0_>NUFfrPeKLj9txs{)H*k+MJ{Gqd`Ur6xKOqi4+&kE<4!2v;rrOf zRdaF0R5ZBqln_p%fF~9XwuX<;MAE~1xT~ssSr&s07MAYkv_csg2E%R5lSZA((c0|n zN%^QQBhZZO&0{9tz8=*`thTFOV}*n%)q{aGR3QZy_nB@n|L=C;z+7O_ns0#cn`= Vdo9@>EB$4r85^1#)L%wN{||688W8{h literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_rewrite_fig2.gif b/trunk/docs/manual/images/mod_rewrite_fig2.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ea8cb65a3f9f1682c6b52d3911f52d2434ad38f GIT binary patch literal 2553 zcmV*@J5W=b#yB~Kp0=~-bve892N4)}p(pW%2p5sZht~LD zI1%}hx8|otxH2g-xLK0vxppC@5V~NentIoI(rJ0{2OE+}BP-$wx*=Bz983yn zON(iU%aN>EEQsprz_yI0Q)?}KoO*nQ-CZ_4KxX`yc3=u2d>*X_(0`guqzqd@*%#-LfeXh5BVQWpLp z)QG8|NtFn{$$Q4mA4HAe4t}G#aHU6(6t}s=hq0PVmJMrKq`A|k!e|9O8l4z&!W#`S zjZ$>#(5cRsJn6|i1(K`QjsTk`MM>77$!02Ard6pHsnu+78$i8lc7VuF^ky0)tFtHF zr(QWty35d@Uzmf7Y8_lL2S2v}^FhUV^=(jScxmn>5x6qvpoM!Pb&QqLVZdksM=H$I z>f6||`_!fUG4I*j11X7%v6>pY2xh3(3xa*;o zNYwSdUv1ZB&wdX*)_krZ4vewXW?IWbBeN8I)p6nPzS&B?4Ba$!41htm$T)Y{DsLok!AXXP!Iasb`-s^66)wB?2mFp%M~m zXrkQ3=fOx@uY&%$*{vTrQ0I{>pr{8vB)Ijjp5X8oW+QCNZyu6c=x)f=Sie!59OmW78?Uq0#Q z-A_M>*2j0|B3IR1{j3WUtyZmwDmAPb*OzWZ(KlCd!!olPXD?x<)MZ`WCSOCy2xXtD zBJXyVst}vinMV{8xGT+dtvA`ugw^Np$GNUjU414?N3v`l^XJ|U-Mw}&ZPjtd6m(DJ z6=fj;N4r>Zw<*{1t;9aJ(R|1-mS1mQ3*BsPl^rbC)KrgcT-_5(HI>#v|5g>Q3aoBpX0Y3fE=(`y56f!k?an7cM1Y2Z z>89<%9O0m%5>UCP<%ld{q4w}rZ#fjfi|+vUI%bW2f9l`Je*0g%Phpa(w)!Vrq^ zK;-L{1y9HXM4@nnK~NzJU&sR&!f=MpVu1{4I70`L;D$JSp$#5&cs{ zYT@jNOnhJx6M&^AO3?#^;?n*Uuh<3#lnIMmM8^c;)kQ!3a6w;0P#6_8#t_^LgJ*0~ z8bMIOHp($7bF3p3?TE(>#4(Rt+#?@BK)p8k@sBNFBX(pkNJ5^-eBJ6mA{CheLyiju zkA&n2BzXe>G;%|hOadk^RLM@dsDz>{!Y2<^N+X=|L7_|~AW7-UAgr=&FKA^fYs5%I z`f7x{?4>V%3Cv(F(FvN=r3r6Y#~>n;iOO825u52uAwn~nIGiRmXK2l9zA&5GEP^J# zSxjy@;+s@?7XnT-%uMkmW9qbo!NR!*cxJ^gHB45ja8-zDopYBYWED8c87Y7YLT~j< z!9TkN&v44KJU)w6L;elAvYZ*|nCAo|*E}W(wrLbBv>95q?)j~FcCxUUeXSS_qn!ztLk!=+AD_Zz6^so0i)aBZQiC`j+k z*P9!?-z)_r-R~*Ey)V3Rf27Mu^G49eU|?}Kw+G83*MP`hFtU<|l;kJNfXQBPvXr$L z_+~zF2`O9&Z^NR0`=RE7#d1Vx) zpa1;+r88#{$%0-X#R_fcFCrR+hhDS=8|`QXLORm?n>3~6XX#6$FVmXV9;Z87n?$UQ1dKj$WxKWt%&lC&*2KeJ zg|Jc^3%8wSJbJ~>Es5hsvVku&bMOtThffzVrY3bjZp9qQL0cRG3m7&S2lxLF`)k|Z zf?Q-y{q1!w@@ujE{JG!dHe$z|&Vcqbv=aBY>W)J$AvZ9!qFH%?Ma*N^PF&p0-WiVv zzMQNZfxTa!4%O>=-_E_8*b=)>dpCpizhqA8omJk;HIvg6=s4YH_3mYv&UCJ#46a;f zD6N=H-t{KN>tGW*NzbkI=0cs4Ge);y`zlrYMtkMWtfc2gZs#07qC6*Y8&p!K)?pjTI?meG(PwMLdKh&2SzNe>a{NyWt`OI&=^Pdm> P=u3b4)UW=R3jhE+CPVN4 literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/mod_rewrite_fig2.png b/trunk/docs/manual/images/mod_rewrite_fig2.png new file mode 100644 index 0000000000000000000000000000000000000000..90dbf544d053bfc9296d1798856ce72fe70ec9f7 GIT binary patch literal 4144 zcmeHKc{J4h8vn^sWbBHNB?;NGWf{gW(-?(jEU7RFWvNiIjAbmz5>4LpdJ`#Ri%Fp( zYnEY%8GECWkQvN7mWj+XGuJ)mzW>~F@40{6Kkt3cd7jVne9m*e=X^isd(QWHGEci8 zKw<~P0000X9bsqy5J=d`>-PxmM6@wjb_WD*pb_=}VMv+2QwUv#Izs{AC4TQOKjEEP z&EFC23;YmrW}-F$hH<;Vfj%1HGU4_ zOU4)V_!rtN2OQuqXU@b75|C`opASbLGSZtC9kI`o)y@%j*SP)aLRuIx{6Q;F+#pc? zr6C~Wz1DXU>dvx|;he>p`J@?r{ZyVMZ^*dE>;Ya{loDoQmw8+dnqnO^A?2S3Grymx z(d+0b2-TyUDFU<17;Bf|lq^m}b`dyLO2Ojo&AhXY(EST%+wG(-EeI%%yj}RAoqAo2 zKaf0YmO3EBCGU@YkleOMO-4@T_spMk8hCl6Gb=&4kgS?XR)dC0N>*Bxfaie&==#+oua|Zq58_+C z1tHTE@@<`D)4TUzfwe*ORq?l$-QYEuJ#)m)%&Uu%B|f?Fm_6nPUx4`IOT1GoH9Kf(+tZD&`GwCMS@D4N;Lehk3tLuO*v$F zk@vaKZt#(_uOi0`!KQ*L7BTmfJf8kpFxq_evZh%=jxAoi1f6!Tt6P);vbbZr(S^J` zw8uu(5|eC+A8gu9JChGazI1Y(^PCP^pg*uvs?%+Oy_GE*gUR$if$Nu+Hf_~uK>Q(K2U4b~n-EZiH-_mQ!RgQkt1H1nbL2xW6gtAyww`W1Ob*saji8`^rU`->C zs%juimdko%tz<0ehG!yZ1?6{A9U;c_T>R9vERZ*BTsfZ-DpnKo+0sZ*(79+^`B7|R z`}d@f-gC@1EcSGQbJ3^N#CZdzev4}kuhk^MN7WWTF}pUz+TJz)wXUMSmd=D8SUtxQ ztQ&c>j~iJgkP3$YM_Yp_u80FhUjIzf&1hSyxcCoz!!=}=w;=sG=dcK5TjxB52}iM_ zUGA4)SkW?5^mh$^Ax@Fql5+K6?#nAllgbLM1!kZ~;&x2F{K0yJR*2t)KHi|Y!KJK+ zISu9$8-;`c1s9Tx+Kmn@JhL2f32+O;GAHzG!HV4ziJfs82YrvocvZ`Yy?>&5_SV4F ziuLW?S)O?;*0ea8B&D>R6nCX}xk#fKB9A}!Y_3sp@5RivC0O+;nSTs2g_?V%S)Old zsY%m0?FuFZKT53c3$dE@p&K8S?7P>}ck~4_#i8Lzw({C0*<6xjfD!bNKP3$AYl1I>%3lSJ|d~Ks;maCulUZEN>ew^ClOuEY4062q={-KU6xV(&)V`Ldf#bu)T7=V zws3#@Q&9o4$0mUc$aR=k#V&6#7H|Fli3=rT-QOsn`D0x+Y|rN^cLfDn@v_k|$CKa4 zl_azYNPintHjRi>za}xWwwyN*G}*^(`7>+n`%+ziTKnj;Nv3P@q|diHbolSe`q9n3 z1tMZIpUVAWuf$8fx-$D&#Sj6x(ec#j5q&Cj`5dbiHS^4eGV`$iAFtE;3}>C55q651 z;5)g$YseGcPGf4;jYbnTOAl3%Ob+eidFf{HFmb$E_N3la`!`$A8XUa0is#{DTg}D5 zzsq*+U84{giZ87}41Fi8E_1 z`O7P!1pAFplWC5F6GTf z+(hWQ=)K--D5N3xc%Z*-apor7ZMUdMbVK28VG7TpHrr#+MBqe4sNSS@17l} zQl6#$h_J_HyOMy|uiQ$>#nqeufe<@$UCqh2NH#dp-0p;8i~Yz-r)!);sqQmX-h75X z*;d+a7A+FAVtp-jXKDOv8kOY&oknAh`)4R>v}rpi4f z8OE+4613j+ZJ~hmkeUeNWFxfY)qu6KT26SBm!mJEJ(!tFoABko=Q`Q%}+o zKBLEPV-M|;R~VjREpN`?)X44Kk4HFrxI=M__8D(o40>~8=zcT5rSy5)Cs0#CSWw=( za&;>pHF2!_EN9aPQNEygezK(4v=ZZAPGg?(_z&aKUt?7384hGob#<|bA%*#F`7(G3 zvbN2uh&*0X^fPZR5CX?3`q&doih+oaFbd{GKKUi>h@H1Nij_|}9I3|^mCARP;|4~G zs@zH3)g37NU$;MnfD>)4Xpdoy*cesM#u8>RPBLe8WvlrJZrJ@$%;C+`HRP!n-!0P= zUI6Fx^FWh*V@F;6Y)ZodpUf~W)Cfo2?5k1~;ihq8sf8^vijXMflT-@Tp?#o3x;ks} z^p^#iO)>&t|$KgSqkBQJP8StyhNz(|j&c||l zb1{qN>sxP=p1xSe{me^WR2Q;Pcxn4lHlrqdszFI?#lv2yu`c7DLX#3Bop z#yUlKviLw3)jMrvD)k);sBNKy)xea{O0=_(6gmAM>38u$Kjn*iLuc*^FFv5=!kSRI zeK6urnwUI(;Z_^9KqR6vxWZ9N3l-}C$x@j_ltR8eGU%)0xv{wdimw1H`B!29!$@4@}?q+7tGt=&he@H(~y80u4+xa z{!=l-ordxJ@h_>S(*5&W2>((1)(q7@c7Z=p`C!A7b0$+4a`%%>@~dwgWA@pp-&W$K zxtbRrUTRBA)T#%chePmzpU@P%$-pv-wc*vPFVD58Z#npHXuhC`+-him-RAkf?`KH3 K3yffYA?0tGe50TM literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/pixel.gif b/trunk/docs/manual/images/pixel.gif new file mode 100644 index 0000000000000000000000000000000000000000..c0801475d2729dddd97b223bfc8af320516926e2 GIT binary patch literal 61 zcmZ?wbhEHbWMp7uXkcLY4+e_=_T^H%m4rY|NsC0|NsC0|NsC0|NsC0|NsC0 z|NsC0|NsC0|NsC0|NsC0A^sLeNk$-3ZDDeBQ(<;xav)Y^axpG3VE`-u0001|0Y?D< z1pW}nNvpj$>&?6WU?`4cX`X1Ru59bRa4gSsZQppV?|kq7z@TtQEE41e zjE#+3ns803VfLYeS)}&A|{FvlVLQqaaBis{vRiH z3Mt^9422DC1w{CZ7SP_88<$hi|_`(745d|8#W_d&!54z?d}*>&BkZiVj)RSrD#o&~5#dTYMI@-xsTzpofCzO80#$ce^ z`Ki`ge71&Xlo6^I5s+?1%H}-rzzLL4m;TgKrjC{bsidGP2S}y*af+#_AfbBdk7|bM zYI}pMW2vgN)@tj8YC@vxuDtfz>#Vm1E3B#{vasf>$j&5)tfl@A>+G|a7Q4c+$yV#j zs0jfZ<+jYI2yK_$Om|bapIU3KIVeec!KUDH!|u1;-YCkuytR7ny)vn50gcvmc9)#m zE$W|y{26N3lz)}^Z=%%sYg1T<)`eT3fzdl}x%g%*jlLD+^qIq9!gd{xTFUDkZ3yG0 zvW+rgH=DQ+k2%`MHs0kA#v13`3&#|gNal_+GAgslI)>abkKujyB8vlVSEz*=;jHu2 zxbQrI&r3r%=tu%L*l4>?ujsX$4DVRs$j$*B_A*uvL-pG`&swyZ;&yuU-Gd2@w3cXI z>9W{*%g8d9CbQBu3Dm+p_2C}RJanOGulA*wgg0I1$p1}m2{@E=hrG5jhi9Ys=x;Xb zr{r1wY4BWiMy%e#lb6hU}!A20L4I)BfkQ#l1(e34?${rTvJBX#(RDS0GQ@4zn^a`S9RX^`fp zumAq_{tof2@+z4g4JkOyg-M9b z>y57_Ny$oD(rP9ej~EZ7NY>=#IT2c0=ahyhtfYvLHd|mHIq=6o1X7SbY~$G;Ik>`2 zPL!J~&n>;QybiANGAaq)E6>G78oBY9rmPv%NY+VO5=fJ~sazo$_{$O@ahUijrgL_O zyJT|HjG6?~7{SQMfVGTl;G`x9v3V~xW(tx-T>4U2$@Hev@}q6^}suxi%2EM^s}*_NDed>S-LwM0AG!j_h@!IYmAkz%CxL2V=6)a!aV$y9;{GYY zy(w;qh+9nKM|C*Hp|a;EPh_`KWmrr>WKEB+qzdDT4#z6RFpup9&$_V z*l7)(+JRT5;x&xkjDHBahZ8H}n~kk}aZ6vRI8h$

    G70UfepnLnK7GqkyfEl8jF#h138rC+(t`QkOM&q6*K@Qc02aDkkFv%fOpfH=x- zlKO5@Cgt;qt!$^oh&$y3$JYHA)igfz z7e}%-f3b&r3#f4`rfMi-GomLNoJ28m!Zl*^Ct5@$ghGNXf+&G@dik(@`qf??=z;my z4|11v$3TO?bc3Rzc2CBG$#Z-_=vYNZgj#2WN7xX8r-T#bgVxl9f+d7d2vAZ;P*hlj zNqB`Dm4ywph2dj`UKmec7+_);K@V|%Y}kfwcvj;ULEsm7O!Qn(v|n@hYzGEln#DsI zS8#sVL?5+>d)SBUgK>eFLbO+Vgvf^xBzq(0KE*RX0ta?JM?Fa*bwzQ8jYtNsRX>ms zBLDJHK@(J7Lx)1av2uX7F`ej$n+R252a9DVi_S$tqBvZ62y?BNU)?1_!KH|TxLvjA zi_L|KNVtpZWr%hsK6aNJdG~WSWQlrrjK~OHeVA17<%|+!TbUR|kSA19<#M&9hSjKE zC$@+<#);+F1wEIGX_z1DNL>`>eec)~@%UYDn2!o}kJB}e=~j=G!H@m8bm$mk>L`#` zaE<_ZEeN?=1=)cI*^pH5kP8@*5-9}~>1-Bxku9~5ILMKt<&nYzl9?rvL`RZ|m65r& zktk_mCYf+8nUXJg4KaxZYvoorX$er*eLPuNJ_(CJd2T-`ltGD9Q`M72$y9cQR{wZ) zS4(-5P05r``BrsRl}>4uQi+vNIh8rdl~K8sSh-j;>0LGHS1S2wELoODaF&XemTLJ| zW66qdc~fjDXKp!{K~R@dHxNPTPk1R)Y*~p1hl$D+T7MZ+XZdx5iE)dGEFh(ikQtdG z#e^ebgOO+?C1-iw=$K?!hG(>auyS)~XFz|)cdLjWPw1KYw2_IqTuf(*lxH9A7=&G@ znhC|4#pQJ;ghR$?n#q!ywn;>|nVZX)U9mV`rI};EVrx>iJZ={bLKb&?M0&oHXp;3u zjt7pk6?x}2dCF;f2e@Qwmpz7qc!{S!ZbzAMiDKwLXJ)2l(S(98=tZN)g8vh;W?KV0 ztTq-V2r_A=pA-Wcai^YR>3zktWGRz7ye53`SvLi^GBWd^tJXDiWJhMBenZv@1Ui$k zvUy&1p-LlY#CIdewoAV!q7Mi;7O0}Ll%6vsnJ_v@5tVA>7os!@Xnqrannr6MV{4p5 zPR=w&tRrfj2AXjxU`^qk%Qm9N79%P;fF{~V)(2!cvZ6#rY}$rsad@Pz=@d%(Xe~N? z(6=At_ia5oq59XLd&Z<$TAf?UrFIC9&^CUn6M7c$G+lG2`Nn7a=7Ly4Z*_W~0J=Nr zw4^$*p>P@uof({lw@`?hsO?#sj2aZ(^QegmoRg|bmI|ksnyLFUod1y8S&Qna+ykmt zH(7;Al<2aZ7H3;3mV=~aQdT}DhB$$bLnn_<^7kQ93TdeAYRrGl-NT>!gCos5!wrQ$=NSLG9bjUf4 z!w4e6l|$SbYPx5EndUU)s+#7iba;5Ju=!rHX?62xoV-bnuo^p~#G?Jztj-#&Ay z829R#`C1Q+$BmD-ok!`Nib!GFIjq!(v3{0k%><&92C_vevj0HnUI$7rAXsmE;;pQM zw5d?DXql`+TeVbMsSKNrw8yLAxwWvTw4quxqbjyV*tHyra%YRSv|_bKYM^cFwvMW{ zFWI4UOShcDnlak9yOOth8!gXTk9gZ)etWoxdkBO3j&ggLD^-_`#h!QRxI6&4NH)2Y z%THxnI+>dXmYa^9s|TNJkfH0jn;Vd&dk3SNVwjt{G_blL*1E2H5~pjnvr7lCYhki` zyIFaazMGXhIh02ERH{0>NLjp0b-czayh^E+RQbDL3BAwTyVM)K)jPe`o4we(yKnQ33kUCeSpV!Bzn5UXDq+8FFu#FSzxsKQRyap~Mb|VY4$eO{rHo-QjuM-P&A<~U2 zYhTdCz>~ESwWV?j$H5Bh!SGd@CtRGq6?CeYiVS>Pe#d|;Yz7rfc2CEyMB>BK7{t5j zR2B=9JIuo_%w5aqhZcOCPPcc0*}ycJ#AUF+(wKKoe0OM^hQG?1=&VUeZc( zn(41m6p14zjsW{x4_w7#EC!#Oh_os^7dFRWP{+rLs}AghY^%p%FuJq3U(v&!33pV2 zJjkb8xQpxsi5tm@@W@}lzx3qDl)MF&%ubD)$^V+%$bsz1TCmBpC(56Eofw3yhzwuE zWXhv_J$;N?etci9oRF~W!m|9EwTuOjJ3s`yji_jO^XtE++{>3pz@w;hHr&d)Yz4h6 zjkrjdRTs;P*347z%n?hPOq{ERY0VRP%joLGIc&!p6w1RO$>=P}i(AGXDqa?)AfqgMYh-g zsbl{Vos#X+4K zw!Dqd6m`$#w#v$qoUD8hg}jNjP2AeI&XrhNQ>?*7EGfec-D7K=4STD9OvR@O-gz9* z+C416oy*WTi9QL6vWIz^C|}!^!v8)SuV|gvBW<2et=;FX!7*&ZFznsSjG4)Nhaeor zEc-lJrnMNo;QGC|#+r)TTtR?nvcW6GMl9ZBS>NxeMXWa{WEO(J?cmw0%mXfr;p|*d z48iXm-nyvaW<%7L^Elz=w)<^x0Hnnu&c!86;;-3vBy^GutssC(*^Go|kxjQXzFcPP z&TLHJu6o=$E8oFOL2!)Ra_QnF_&MyS*68GKXq)8uLd`0U#~U2vL^`H*eXtZAxHW6# z)5GEuhs(5y<&Hz-W;$(S{i~)*kAmgqO3u!D*s_iGt*#BE3VKQpoprdWfWrOUE|Y?>7l+2U>>)ie(F-4*Vv6M55C-0 zv$~Ht>9+oco=xT$ZrvD+-QN7ozj>~+oL;|`{=r!6S)4T*Ev^ z>(2h{$6kyyEX{jq?brSU&A|3LflQ2qk5xop zRscN*aA;Ov4^%#N_DbLKCZUs5RrW)F^`hJMP>=R-?+TN^RRX{d0YFY#!LSs|&Bxz5 zF(XU!L{oJ=MKIJR7vxy`#&dn=d;eE;G9#IVcmXDrKv+eH6h4tlYSnthW`o9B*IV>T zwd3Bi8H+`^WOm#AZmYxS=@BD_=ZAK%c{=~o6C5NgbfWRN`_NdtSVU|zG*mQeLJcvdKS1iHW~2rH)TU8iIgGc>3%C_k|#8;ih- z5Oz6em}!M(aXt=E`}|gpl=+vG9>ZJvF^+Ej$Cmo>u<5Xbd&$t3AnRIo$atENYrQDv z?d0h&{U_@818$u01t_>1ysk<+&BdsK_00#9AWg5-+Y4eZr-V>esU9EhJf+7g*FTW8 zwz{^I_vHdV5z92J9odrf_DwQ+z+EXKhc=c`aWc^4!ERXgUm|` zG+hF0Oshm&meGH{T;myKjH0XdnAe`^*5?PkuPV)`$?)+Am*aR7S<~uMotQbnzWYVn zpxG;cYSF`NYvi-Ba?In_SNeX3Yqs*Uw9WG$=E%2U@6f5B*)Nok)RM8dK&NoxFU#Cf zNYhD|woYj6tvpB@H#nF3tB(`e(ifn)>Q2S(R#0i1sKOQO z=*|&Mc(FMyW3e)oAw=jimkH5i5AxP~Z(h3hJ93c{Xc1asW$|9sTdh6D;$4}-N)zD$ zCZt4OmgGiKT+_w&Bh%S5mkud$HWpsLz&oHS>4v|2szG;SYPNH11wn<&C^LskX0Ia) zyh8Yva2bv6vH^;G&H98m#u(?nEf;CDt`J^wWugCT)zXlTGrePTW711A!iz7{r|XaY z@Jx3Vi~b_#>y8`j*D=z`AcGWue~lmMZRjm4 z_^|MPM^}UQ6%en_C9pinGSuU1B!-H}@br*Hv6xCBCgCpp9WYtN=md^7xM@om%KYZu zvx7Yo0~l&9g;L;`SQtz|#rzM_S=*{>!)k`{c8i8~(NWE&&tD$b+DET{>nFGuh_Y>KS`@vS6W`Gn9cgoXuGybqbN!(TY2cY*M~QVW$ZF?sR%nhPBkxN zR;6DjLf*6_8#jfHTVGJeuwl#D*v~k1QVk>m&f}ciH_qQ-r>UnHgieGFvmVs}&q8J` zC|*5Tfxt+oh4HT{nR*BM8F!QlNt}m@XbSU)qgDHQk4;f)XA%OP_b%_lB!$mrYl$h_p1fZCD!$5itg}*| zW}`$MUH1juHz10c?g3(^Db6m8QQ^Kec47#d)aaU?y`F8dSr_o-s^pzd1w_$m7zUou9_PM zdVl*}<0|WjmE`l2mQTM-x7sp7(^?aps+LuP`GqMSKqQ-3kdwM7iga=qwjxPg>%B0{ z*~jFFvB2%D)a>zATd{@tvoPZeotVIDg3 zyK6g7-gX}?x_pM@?-9!9Mt@`<3PQ$N9R1!3!8|u*3eKX#s1Hz@ZF@COd70FR>4(~< z*+J75YKqqIH{@&;regXAvxUtGtaKugOLv3jx6+vK2b4iBv13O!hzC2n4wUnt8W^)` zoCnD>wW2FGX7=Y-<_~nf2ekmxGAlBelexR=>vJFR5T z49p7HA8M8Jem3sH$iYfpW@X{^Jl~cG;F2szk9(N){;pGZ0lseRi9utY2<3Nw#p(^@ zzk!#1yMtD3^RR$}L=4HXB5K~t9l8hYVJOlYW$m)vz2C|#yTuU#cZRk6iL)r@4hH7H z2^!yeYp_srZ6ld|sy0iD47$%rg9MY+8j-YZNuANOB2zB8XH3#IQKN+;F-}@Vbg&eM z^-`3Y1C6-CdI)D!ni6{#muF`)Uy(+T=W`Y`AGDJ7VEH;SuTgS}Xlu=v7i?h~roa{M zR~7xpypJ{i-KlDRAA~#o<+l@h)lVEuIULYm>v>!NE8)!NApS3(0^TXfmV;pJeSD%Z8zMMfOkO+UN7kqk@)^L zQx-FTQK*^jckd*V94*S~ef%g3!uV7ac1;Oo9C(&Cgfx_;5JWrfoBFe^Lz50a>ChLt zPMa6G5h6B*(dp_Xm21>6{U?o|jsia3I zW6Zc<9aftM(?cheZi-J%;xfovS9ewt?&0B?!g+`Ks0I7?-6woZ^+q%9CFF-fXYZwr zJw1LPLia|P8e|V>jY7lz7Uo+JP{7-{im%Q3Xbl}=1jsA&LsG7!h~gEuitpkc=3n^E zDV;tMSz$y8MGGRHzgl^C#`W&E+`W+)vI%E$n-`ffx?keyhBK#aUYHW$E&4avFb zoz!*PNC|Z(|5<%(?IXpF%w>*4;b*I)F|nfIRMwcx>$t(tsTnuSX&j}%W*d>`cH0Hj zBKuQRqx`Y;9FKNt2eOE2Fu)&?xCnw412s|Z34;7b0;9xIBGO$p2SnFxU3Vk$u9fLx z1)D!9Ab;Evk)^;WDnU6&jKl0uN~hi(WPY;p6=M*TQVGiDHsT^%X$UTV8XNf9m^v=9 zcnFJ+9b+-mL$Od?tLGpm$%-XD5I~SN0SjM02EQ3JU)s8is->harC}+c@7gAKbweV^ znBi_sM0U^g5RX`Z@M_s#h7hcD(WS5TM=pDMOdZmj9wYJ)IoT6Z4fE>Al7x1p(iL_w zKT^n~n(>d}+nQz3aS%haB!NmP963mZ8pdM0-QRX-Bl7ROaYTLi8%UJ-XpY7RRgKfk zT2>Np(0yZ3+78D{Qiyd2@4hLGP?U{wJ3*SU;-$V*T09#DK6%TaGwIb{>7Y}!HYp3m z-?=;HvcdVcqUvN-s)d$=6PDA!6T)Fwl*m^lL`WA+jusUA&NsNF>4ZZ{u@ZFx3d9_<1#726LQ3nu8RF`BNJc4u z;Iyon96i*GGeB@wU46$=;W%M})#BSp->*w$w4ZWdln~m9U}LU`un|7DYDb#>AMX$Y z%(mLnE`}wpCUKzoN$*e}c8CZ_Mj=7I2UDRbMne>IInqU#lzYpaOpDBE!@OGMg9vT! zT1Z}I3J@WE$7k7xBjX_(s5G*$=gM}AW?QU2bHEJgu)LrJ6iO=}(usFYI~;gcMKtC9 zgTvc!`{|ByujIK5HjVF6D3A(p55oVm#1`6lB)gNTQ`_1)>=*v|t0#lt3sB73Pfb77 za!D9xX4>-DW88U2i`D9ptRi~!=8o>^M?jxlK8_yekEeOk9+CF2K^JNNqq8K8N#QKKy+P|E6(hBc^ai`;Cu>fm$i!2Kv<+sLYr z`reA>+fBPxO?AeEPvkgWfjj1$`R2NVFQ!x%ro&=5qfFpm+WT}IGu!*bs7Tc}AHAyp zs#1yo@{J*PiNT@EvIK+R_qPL@Dh@dD{ZDtz77Ul-O{45I>eJ!EUeHHe!<&bq2;Vq& zk^_RCr*VG3d6<{3fBTQM$q07nxH|4AE^F^pni(Te1k!&b%KYcmQ$v4*`}e6Z)*om| zq3SW;#2B(4A3`6}b`G>Svli4{9{p^P$}qMBTG~L4r3k}*b`zJ@sK$7U{=`{grL)1r zuXyK05pJYMl74!YV;Mux*zuW54x3pt2e?ew2V-$h>eXg!P-rne+~gLvf_dQyE?Ggq z0+v=*;nuo^b8*s^8>tXf7c)H72(5uKHfA=(LWqJ4iM8b2N>U~zry5gEcUGe&k+?q& zis)E+dN-)3gcXh5O|%s&to5kK*^h0%E(K^_`b%`wy5}~|Ujjj<=BTAJvdD*$TC>S5 z&1QSp>d@t%XYHHT_yB}4K#Knso~Wm^$VqyHd4^6guG&&M!E4crqmncG-UjC26M)K) zpSQxc0xWC-XDNEb=~Y&AnizeU|8z~+jea!y9wxQ_yMulubJM?_2Mq+X^1o-L!mTx@ zESYX-ocR-fj#{`@Hc3lc7$r*d#8BPfkCeMY)vdW2s>@wFNO*t|6MYS&^ zI)&@vyCrX5_y|?L{E7a>eAYt@{M2-6`mH4}>Ldhy@z*mVYOj)U|GJ5Fd1`d&@H(qT z@(m<{ycKDRTa$-BBy5=N-zSYkWDQ_aV#Atja7Ujy?gr*S?3m`er-7J6vdG%6SbWKH zg5|HSd$#ZTYC5_w1z&zUlRR7@Zz#RmE=j8Ol5Bf1Uy6yK8Bn|xVSp3x$+ z1Mndqxo^MtjoJn>zWCkr8=T)dLpEs)CJQ!fu12WOkkd6OJULZO;HFEYr|2+&7vzUi z9U`?1e?c4tj~jC>Ut5M)x>+xEFHG0Fr8nBGY8yAbG#_E|!1tSjZTs+;vmrT@A9-;7PteQEv$45<*hD_ra^aWJhv zFr}632aytmWGS5|QCO)(V?8edR|U4?s z`Q{meb-U`kJ}4bTQ}zW%HR!T|pELA7u5Q1|6`@z0}&^~)Xf{!N; z!P6GmAevql!NHscNtqK1x!i=kclq}%#Q>dqdhDp0oVd7Od|o&V^(&C7_HtIF0wpns z+YbO{gW-ZRPqvilJ*D#oTR^Svu+rfMqDFKL!*;o6x z!{R6_Y`o!Ka7FDp6j4Ub|L(y9>9guZzXgIRwZfHhcp+S=)!w&><{lntn3WP#RIltmexJw<3OsOyuCB-k7tJ^ z2oFEJ&?t?h!w7V24g4ueSfiA)k?$hw)mIrS_^kmM*FeU}Kguh-e1<4NIFPvIAA%81 z9>p$aT3H2+94}uG6E|sQY0j4^jMvYWdgh6Hgd=q4y^Sh(d-eV_FJlYUI5BOU4rfB& zdekllQ)*AiLs*cY5G&cB;cH1Jr-cAB`=zUk7WkuV-3RaU1IIfGno3l#;Cm8hVvQuz zd9}tZpBmf%z@cjZxU*@dk`~I|qX_1ao?d??yO_3DF3MO`O8N@zqAnCau%zKXX2f(! z8kp>}$+C5FK~D*!9^YTFD4y}LJ}#5oJfQSna>mpO!Q6OO zipk*NvG)-W+ccQlxMD`;g-}Ww4agO#R-r#?bNnZBpOSU!D3-j+eR(35u4d4rPksC7 zxeMsZ*Bf0Sm@1?)$})ioPa@%m6n8$5wR(ntDa%BbdqxY@tsm>OY&;4r{K;YuUDr%die zq#o0j!fJO&yb>0@Ji+6kjs1D+cxzz~(TdZGjxP+lxd~$u8afJS=RcWu6OWZ40~`tP zsMe0??Z72hbO-n06?e{q${p{Jx-jKStlB{=kdt@j`BU_8GHLbmI~!BpZHY5K6EklO z4Y`IwB(jg%cK22^`Px=x53`L&ob{j!g2{C!%22h)<|U}zj7MQ|`RT=_Cn_>dXFg|0 z2o`~oqz-cE!Fq_m9L8>=1}A#)+|NeZ;4kwwwcS_V?(}kBzkPpF$Y*c=K=S*EXN$M^ zqAyOyY!9v*epY@5Iq87nV==Q}_&!dMH+I!Sk*|_g7=M&m2^sKF9a=ZF24YqqdQjlU z7LcbDB3pPN`o(L=F(P@`Z(L(692hu0=q=CbMDKu`>J(*>?|MUp($)+9B%)+klG>1z zE(~*nM5uC|toyyal@RniS-IteMCHu%E8rF_v0CMg$sTQk@#L~0s`nzSE?OUT0r~zq zqI3Z(inuVliRry2K8+F03D<`TqXk%gw>~A{C->fSMg2GP_y6m3-baJjR(%~Ewf+9r z1b%DXlxr~c@nM5GwG5|8rF7S?HQLo+{@Elt0^U7(bmf+^@{c9z6?a->96suxD(ZBAc(fMtKd&favO0VzuXszB$1d&qp6mW+&!eXW)2vo^i2W~l3zn<^ literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/ssl_intro_fig2.gif b/trunk/docs/manual/images/ssl_intro_fig2.gif new file mode 100644 index 0000000000000000000000000000000000000000..26b295a67b0a5fe44bc4dcd9f06cba8e281eed6b GIT binary patch literal 2700 zcmV;73Ul>GNk%w1VXOh!0J8u9%*@Qp%>V!Y|CyQ000030|NsC0|NsC0|NsC0|NsC0 z|NsC0|NsC0|NsC0|NsC0A^sLeNk$-3ZDDeBQ(<;xav)Y^axpG3VE`-u000220oecm z1pZLSNvpj$>&?6WU?`4cX`X1Ru59bRa4gSsZQppV?|kq7z@TtQEE41e z0fCHXqH#@ZRK0 z^IYuhk@xtR`_}RQ&gvx*s72o}GlR|uGRTNwzeElnDg#I{7r`SJu|!OGOjV$b{=+2F z0x7al#gn5l7Ex)1NhO^dVb4#P}*`t2JO&B(wX;~v7hu-Y|`ew_Zc)i(l>x3F|E$yE7`<=>88v)H}2XHk7M54yt3|wzE29T zvE2yqb1$V=zD+weY>v$Nj^8W(uWG5gHM<{{y<+zn_lbPpmYlU<=<)^rh#NKcz(inO z@~!7teH7&vgM&ishYf1hNmibMW1UxFU(d~ETY?EfS7CMYO~xQV5WbKi5HNYz5N-cW z;>v4&IR+G6LY;@2hKsp4V{5MUcwC0paX45&oGgRJR%euA#&08_fx$&ht=JWe47IqK zBoZFA*I8&GnNyOTywgo@yOdB5l_Xf{gO;2HiI-*weKaS0arOtMdNG1|WHV-xDQGEU ze!~?sW&k3<851O$s0ePdrHqXv(iz}#=yj-^pImZ^i9AadD(Y6F0;(njyqKbDql>ay zTGP!ayTcnI#RXijTDNQkFK&z!Y_I5 zaJlWMHU%2msp7VptirCg83Lonu50e2I>0%vfb!;salLuQm~XE#RvYq{)&ksVJ_84< z^2*;ngK(qkE{w{f5~KSt#em=pbImw(nap&0*=gOK8!p;teR)8cH`~y^O23%Tq|FuCbcqNW>Gad2n;dP8x9=V`%B!;;x9cPe-n;Dlj4W5b zn*&w6@rEPcc#gLU4@d{^P^u*?DvcQX(~ghYuo$a7rvMX&>{p3gJ&+Zq4pKcfYEE}Zcc;#;2 zjHDzdIgCeA@{*X$q##-1MooJ1lb~#zB|}NdQkoJxqdcW5SIJ6Qq_UN;jHN6W^2%A- z@|L0GBrbQ!%TMaEm%t1rB!4N)Vj6RkwLGRWm+2{DGV__xJc~1wLf;WF7I6A! z3 zq-i^8K@I8wgyxc-yc?)QA!D@K)GeSTRH;a3ioKOKBA?&<*YKj#&iM2*Gdnd}J8zn{ z@mNfzK?N!}JIc_Sf=s7L^$}A$guu`VRG(6<<~}EyJbwBUt4M`hRzuoT5gk>dVWs9+ z7h2Y|I<>7`RZu`_+E%RQ6sq3bC`b9U)HHnbM1=N|KSC_p0vlJKTGp6? zy{u-Lnc2;HwwRs$tY~=|+R>VJmZd$dYFU}u)w;Hnt$nR*JsI2C+Ln^Fy{&E=ncLm^ z){wpZt#I2|+2I;@iN!sxau0d`(B(Q;k->egboZ3p=~}lc(Y>yAACleedbc>${jPW& zdC)(a_q^y$uX@+Z-u43Wpa6)keCJEw`r7xt_|30=_sie@`uD#84zPd+OyB|=_`nEG zu!0vnUrsXk!4QtHgeOel3S0QX7_P8`GtA)*d-%g34zY+w%-;=@_{1nqv5HsB;t!j+ z#W0SsjAu;a7QeX0IL@(-cg$k}-?+y>4ziGk%;Fyt`N&94vXU8WQKkp)SJFFpjD0EH0b)(x&AedXWeUI z3mMkN4l%KLZR=zM8@|r2@v24bXl=lhiTpDT5B8I!Tz?mwVmy8n|sjZKDWB{ zobGkId(Q2Cx4hLH?|IvM%=NyvzPX(5efzu0{r z^{ofJ>t3HZ*u(zvv6Fq}W>baF88@#yzX|NINtYNZ8YS4@A|Gb zv*8Z-dkdb`Z7;mN5ASWVD}LULAGO^dFYms0d+wBfcjWUP>ZwP4^MCg|)ImRa(Kns+ zm^VG=!=Cxo`@8k754`GQUv=2i9`dul{pfSAd#2mI_v`*W@Xsy$;g7rc#{V|*lYi~y zGvC?Hf4;G!Fa2LrzxubnKK5O${q2{!``*tq_`~n$@spp>HSf9l*U$d;yZ`+VgO&W} zPyhPc|Nbuc&%gfn&;S1W|Nj6OfC4yx1XzFucz_6)fC{*P4A_7U_<#@?ff6`@6j*^j G002AZ8?&qc literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/ssl_intro_fig2.png b/trunk/docs/manual/images/ssl_intro_fig2.png new file mode 100644 index 0000000000000000000000000000000000000000..c540f48a59222026dabf9ee1e3653ef87c62941a GIT binary patch literal 3190 zcmeHJcTm&W7XA@B7>c;`C?H0KNKraLim-qYq!Sj<#6my>L8KQkM39b@P$Ymr9>o|! zm(TDD>C&?-g#%+~VF&<~$^1KLPL?in)y&2M z079Su5QzhTZPr!f3;_760Kgmy0CchdK+GqXY7GYfcEIX_ok{mT_E^Zy?q)gfOMeNL z&p-Hwf&Uu@qJm3eS;_GFm^t|YfWXWB#g?HcAO!$C{pQAoc0rdG2=VwL86jhg+v?s} zld$_I4r`7$yC1oo{Iw8ByjdGhtJI%o|hqs(C20EB>M}A zqSv#$wJ;ea=jl$)Jx-&P+cLmYu47L3bg^Y88L7LSrA(PpC_kckbN6wWM?`remUf$LMe8CT7I>30yxuVcaj;H%Qpgvp=}P5~V2O)fU_53wZA0j7GyQFr@R$qL_sK}$tuEb;O zh|?Vn&%o3X$AkKLCD;!TiutcoBafOiK#W%!?q7;C6`2pVVt?axkacNHDm@dk7$sM6 zZBB-P88~G^?-sr{RKWg>0|q(%(rL;`W3Hq+Oa7q%W!O2X-WV`ECd4_Q>#xX7do792wkhzYf$tl=uG7sNb4yvw}y@WwM_|p-YR8^ zv`eREWf5P+Mw5pcY{^vK*YCdAKBok&OQ`S`D0v!iCUB!(onbb-lvXc_6Z4zzCUjRg zOP&Ou<$9v7D&l~g&|+IzCtNbMU<4ou;OrLy1eQ5*k&8y0zyF zaxFYg%w6!6XiCrG^*jyJh6F-YMHmN=@9maUN8uYC9dn(}-3^lE-(Q7X%#&(*J#=a? zYBP}7<{7uqn@v|ZqQ0U3Ff{QD!GEHg3+?6aai6P%0)G7i^}KZH>;duPYUP4u$usD; z3+OUIrIoruP@hX9R|3^bYXS=jm^ez}p95dQQMmXcFn&0H)8;nXK?bUA>1GmTu~ak2 zsa+DbN$3$~K-RgG5y&Xc)@to`YSE|h>%5+n@jwkzWZ-~Q6ATR&-JwtM%qN9JWga87 zVaJA~(WBP4maA~;$YtF}M@hP@Aoza=@qA&EA7#~=2Vc=Qxq9}P@7(*$3Z(}1kofRT zcgy693%Lr*-33H6=jCnv2lp?l{bsS5!_A!Kc8q z#@-x4V_z8*@A@Gm)p?llWY~Dh)C=5yG8@E*{z^@SD{vejs2f3@kcL*Wq{YU^U($HR zt=}x?;|X80yKaR?V83ez>?M-PJ{}kXuef)DW<94(W0Kh0@H>pbQE2su1oD$TG%;f$ zsKBlG&AlO_xQcfrP5Kb++oW9KkB*q}@TQFWUzw%{5*F(Xd_NoCBTmCs_#3@h*M%O5JJ5)ega6F0Uo#HFn$C z2Q|thEo%NZb$-E*5_sJcm&6Sa9?tDIgaHp2n(dt&>`yZL-+1Ad60OK-Ac1rvyoKJt zEQnQLjZXDI6?D&FtH(TUQ2zZ$8&2JE?_WJ&kPAq^^;^R_ zX!XDIV7Y}dU@xoL(2gH6)rcWR&|H;9Yo==-!3tfK)XXqFguCRM1h3_|8)^6P5-ViTq^UFh9&w#hr{Up80*VEXln6^3b;y3c0j$^E9qjOQse6U&F!QOS$h4aONhK J#$+QD_IK+YzNk%w1VW$B@0kZ%A|NsBY%*@Qp|CyQ0nVDv0W|;s00RR90|NsC0|NsC0 z|NsC0|NsC0|NsC0|NsC0A^sLeNk$-3ZDDeBQ(<;xav)Y^axpG3VE`-u0001|0Yd=* z1pW}nNvpj$>&?6WU?`4cX`X1Ru59bRa4gSsZQppV?|kq7z@TtQEE41e zjE#q#u}}sHv)}tf-?aXC-D5vzMm>q*~G?}#ogQEqAau3An2yo)6wkCSK{Q_ z@`B%o_4CK??Euy1?)(K5=0pQ}@T%mf-HDr3iv{u)6J z3mKrI#ZMDMFr093RLg`bsj;Nwkf6<%6>8F&Y11FiCMHjI0{5|`sG~+pdQ7?tqtc@! zh4Mzb1plb}*Jadetgm|HYR<1S^Iwii_oION< z3i>!!gUmvk6+P2zdC|FmUSD6RDf_84)FChRL;3r0?(eV4F6-HR`aRhGryo7m4d_aI z{_zK3d3VGX^Wu{r?lcS|GrkZe;$fk}e#c3yzDPlP1oqR61=U}q*Dd>t; zBKhZ_h<0(Pkte*F=%YY6`sSjLRtl6kuvn@o7L;n>=y02c8tIfSd@8CBnGxYmp@7C0 zgQ+y0Dg~^K(ix2jw06)bUa!hZMXrIev{Rdx=m0FSFzo6p57++CR333Y`9z*V!s;e$ zv<>~knY6cZTb7>3BHQb-PLR0JwZhFfY_u|A%kGia_6F0i?P8mqvUSoBF1eYu+G@Am z+KcYM>v9!uz%CJtaJ*dJuy3sVQpD(a1y@{fL;xQQuf+m)obbiwS@W>Ju11X7#2ype zvAY&8OsvZ()64O_%;tcv$)%zk*t|2V{Bdp?_bl_!F!OVBur}j7M6;fGB{Xj>JNxa_ zL9;s^$J8Dg{Kl=F5O33+W!{)B zt@oyO>q=4Jf6GaD!>Sf8DBsBLo)#yX;d0oO`OScJkNn#<%w8 zufFL5rd8#B`^brf$}zqEN#%b7EQtUI7^L%+Dnaf;kY_-Ztz@affQ&#Ob`TL2PUHrF z$$(HZDEL4iK}>GA%FRGTMm$_y5E&Xo2|f-q8W6Ukfh&Zc2}#JpWvK9kS~JHB1L!GN z%us|Zu^}sPNTcH=&xzpyo>;y^MTuCEVpv=rY5sr*kS-d^6V}PdFAC&A?Vw~XVeDWT zYY4`rh;buG1k)6QvzKjkaffzHmw4(ptt|qlG{wQiP#!ax$H+!4W*p>G8e>S5EYO2R zDI{&y*p4T1CqZ@G)_Jzb$8DkIi({<7|I_`5Iuq9p(r~^ z!d}jin}*pH23sRd?5Hx9tPCM7T}jSkPO~4pyd*fg^UDbe^Pauj&Nug{%Tlh=m~3fg zCSs_Gb_VpFv{2?E1L{g)^yiZbS=B?v{xi{C_60l@jVN(23Nhz-(~B+~iW|vDMno2| znA6FRIiKl4H_mdU%xkDV2uh(3ni7WElj%HY`XHM^Q>PrvX#y2^QU=0OEo!`BPW8vs z|1`C!_8^D3D`NIq2Em?%uv+M=VOd5!xGwf&bLHz}HHX;rP1bRh z+Gn{JYPiZQdMEoj#r7+(kFBqKyLwsuo|nIumDqoS7vSXVm%s&1 z+<y#F%+3X%LHgrqOgn)OTvqZ?^JB-)JU^^Sq>-zjIG) zAo|#|wsoHqtm|Nd^C}^WwjPJ=>{;3R)7TDmwmbc4Fyq=z&Bo`nH_2<*O4OVC9JjSW z-Dzak+TEgNHdoZ0&m6uNYPjs?tBY;BWW)R4c>XrH_g!z^VDpLv*Nb`y?n&DL{N4WE zw7>_xYKn4`FskNg7CRHwU&qthX70AON6zg~dwa{Zd~>@^9&w0&dE#Z8w2Hdya%HzX z&oKX*%zu~VoumIe*C_k>l7%buxEieJLnk`Y!^+&Hr`2dqFDule&ebYW9jjKq`ukFn zbFJGbOkU5aSi@dCNt3rhS)f*U*S#H@PUsy~8%HviZ7xciZZ{cAjc+ z-!%j;@Kh^h(9Qem;5>LIr>9*28?SEvjvFmEp1~8_EyJXiUB%MzLyO*4chl^iQf(dc%34BSK5xx^*K8Y_tN4etF$Bi$qL zk}VwtP`#SEf@&bnPFy>*Upj}k=xF`6N!tAIM}L>p z-|KH$E=>OL&%gY!ME^XtKj!6^fBGkHr$$8nlghlSSdDm zgKu_%ItVE_*n@w@gFuKVKRAS>CWJ=lXh@iZa3Xk%2YO7{fO9v3P#A?(RfQ4(f>ww( zSQt@SxP?H#c!9TpV0b#>7nPf1DUoaWf}qD2t;( ziL1znX@-9Sn04WEQNC3f!bAe=HhD{M^FA&7-R@x z{*aB1n2rQcB_7Cqeiw^7)JGMSa0-`Ah(&XGhKnV)kD2(0*3gcx7<9f^LBKSR>gI*@ zSBHZ^jOoaVY}SDQ8IZ>{knxyJtwxXf1b5TbWg>@;qR15yIe-)CjReV0Dzqx&2#wTe zEY_%wx%iSVmo0ZNlD@+`*d&i$kx{Y6aX3PSSq6zDc7SGbVG-79L(+#aW=VKLl>eOw zS(nq4wsVI+36)fNgL_z&PKlK}sFgm*m0jtTiE@=-83bZEmKJ7~M~Ie6sFrETmf+@= zKnIs`QkHT_d38x9ba|Jkr@|7{1C*W#cr1f42Qz#zb1Zqeg0~l%j3s%z#hRu0 znWe`w!zG)UNtv}Nn7!o}GozZuwK=WXn@eb%JW`y<>08UWl+Ed!&pDLQDV@`qoYmQU z*J+*EDSq3@o!wa@%K4p9wUXk=g@9R}q;Q_-sfOgao?+O9?kRWS>7L~npZ_j4pY&;; zGpC>BB9;CbBF1R|1TX*tTA&1apazjpbi?L5IUg}TA>e$p8-a54!NP& z*pMB{q5fE#8v3Cm>X9Ytq3DRA#?oTnI6kLnPbM;=COV@iTB9IZqbk}p_H=L%btu4S zJQNzF7CNLtTBJmJq(*w61CXPr2vIv~O&Zxl^kY0UdZSi)qBqK9xZka@V zASk0Yilt^+r6;PTGRCF$_i^?zN?asQy0CI+TBl`dr;VtlIAD}M2|?0^lNt4Z)H9$1 zP^e03pof~MNs6S5x~Psiq#SBj@+dZ+0asd6@^lQ4=$pCpeE z_a5MGsEA6a(;BVRYOT?_pow~|+Ip?rTCLrRtxFo9{K$~z`m4Rlsla+C zGaKR`UeJ-b1}!oIvf z#J|SHL%Op!%1X;i%uJ7`o-t3bEw50}GOkgvQ!<)K%~sb}*w~TMo?4yTpIj(gUEWSF6_>}>6A?r!gI@Nn^Q@^bTY^mO%g_ICGo_;~qw a`g;3&{Cxd={(k>|fB`c^000000028vI}uy} literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/ssl_intro_fig3.png b/trunk/docs/manual/images/ssl_intro_fig3.png new file mode 100644 index 0000000000000000000000000000000000000000..d71a1cba98daeb8cd650162669671610b2240ceb GIT binary patch literal 5487 zcmeHLXHe7MwhaOzC`AH@AfQqb5KxpFKtMW5D4_@lNGH@#La)+;z*Rbgo|uHHNCyEa zB2^&LC4lrM2Ba4s{{3|4&inAbzPWqm%>JEqX0LPBI(z2K{Ni+>>hyFRbN~Q=UQj~tRssOtC0#zTqCTJBw9(Ml1^@yC z0D!Pa0O05x3R?jHkoN$9wdVi;Bm)4rhCnyy$pHYA0Np1Bs=t5#?)wwJGc)@#Gwto| zGtW!T!T&AJSN|LTb>RPv1Hh|%z;iLQ2n`c20Dz(6&!9-X!@vmuTRAu?s0-9a2-&RkkWvhR|5ewl!-CeKz61kxOPv^%J%WLj)K`{-#} zO6V@cPsF`{6e}$Klkdio%|?4ye6R9Jk-x=WR+$x}Gvfq3oB1e5&ZlI*_DLEM&_w|Y z;~|;MvWmHD?@X-O&?@te`MkUwPF2wZj8O)kJ@ef2(igkz*w>?XX`GxSrUd5&pFgc1 zT&Lsnq*sxk1T9Ri`Fzuo~>CLCauUB?7k=&>=P)T4_AhuA94 z0W-_|-MfZw=hLC@;L)XgcDl~nU6ivMN0?+?6P;b5S{=bUu4aVhpt*RGJ zo|4BzbH!2d`NQJwu0{wLE7JHr_U>3CS18WI{mGqczwX2IZfUN;}3!l3lV=cng)6Md6YFHU(3Hx=@B$is80+}p@E zC*3}b1a-xn-VhEMZvEQi2D(JA8{GO*5e+Y2mPpBC-1rPH#XHAB*97!C7YuKT$>I^+ zy1h~F>d|G6IMJY9Mt3>w*IGzc zw0(1*Dv7lV?qbE)0sIup}(*2&As&Raiv(37!VIx zOQFZtuNcK%P!QK%u*=J3o679gWk)7a*ggEIsxGYmI8@B zLw>pYLW`y0ro=seDj~)_|0EvDN@6-4grQEC3&kut8Yt-O8I`d{b68OKTHg**Qd2&> zmXPq0u{&TVRbD8&<*L#U?wOU*h5<2u5mCX~Y{w&Ev)e*eC^S2^XPEa0pEvbN8iz{G% zvnC{?Xy1|k5{Iw)eqwo1yv1hdzTPyi&;CG3jI2`(ck1dD!?D5R{h8`xB?xcgG88M@ z$avd3J^PXt7n16WJ9I7UwnkpagHyH!hB05?PgF#Qmw;5O<|eak)2%Sv^eTmCHTR84 z%IChvKP4%9JMF;cy6Bbe&+f@DV+J78A;?|Qx9u3GuX8(?=KSFKNOP_WS(I59 z;JcX2#N*4JZj_zWfqR(Gr^id6u01mpPpD!yo#e>J=)L?~Ct~ppEMbf{nRaO;E^ct} z7bB?Q%%Ln4;_X?nF}$-eBGh3@1qywW`PH|6QtaH{0rv@IMY0w?3ceJ`cA7!UEOpjj zDUWzB9RWiBs!!(CpNRm{?>@7X^e|`G-ahCRS<$VC1Hpg2bzGP9{z~qUyv&g2IT`OO z`H>Gg!F`P!(7$?ru$QGrKBrT;S0o7_{9|ET<)8Sh_yWuEWpxV_C)F z^MT65lCj6@2X86{XAg2}JI5$NH8suKwZi3hQXk6CzaUs48+w%u`vrvq)%UcFB#=~P zMP1InENBeGa$l@W$=V(ASr6U^3rY{Ue|<2OI+M(0Y*v`;_&x@CD>#fLjW@A`VBwg* zXkY^~+QB-obnO1AEmMyf(x35nwp%?D3RvbQiWUO{VI0 zShidA#$6*VQWi%6b*^Gsu4DtDWR`JNxe-L+x6H>uQBAl6EE_bQyJJlVmbwgL2;%ZH zBms9C}X(zEleGQf~3a8K-`@loseC5N?hhM z4$F5e@VxkeJBIeAP?uL5yIsJF?9$6Y3hsO*pz&2{RXKR2!*-X9e5WQXK^lh-gKUj- zn%0x zbJpB~LdiD?REpWEQ}3_BLPX{34Jwdbe_5(~u$#39mv^r_2`5}QKc-HJuTA5u=r9~3 z(oWP+IyB`Xkfpu{DAB@!`Kw2JZC#cigPpoQM!VUhA^wjtoxA?9 zUIX~I#zIwL=v+05@~!irWJ--ir`{ivSZSV*<-3AiKcI^K$iKrd>q`IfA14AiqYD-O zdccbGH>3P(8Y#M9CF$=WRn1AGt^fG@q1Fm~^jDFEUV5#>Tc)rdC^d$WHf>DkQjIW` zqSvFT2iI6XP~M?1YLs>;`_|#_=+dnPxCdHj5c-7T$W*_q6Yr z`P8lmC88aZl!UTg6(OK6r!80No!;#7{?<%rie)m_$JQR79SwVb615M*lKSOUqMIlb zE)jKhsctE9a8sR2J9OzgmF%!G`TA3b3FWq{Cb#ld9^8)Sc0y0v6SiGmr?BRVRBS#IsK&p`TVXlKvWE)lhVf z)f#&K@YY5cW#pyR$60<^B6Kg|ocnJ|n9`&v8y}tUS>>pW+mgNc=Q(8vUo@mawvk^a zws#hh0Uz)ZG5yz~zQlhWYh*r@27hp5tn!93#**IlvZ!(E(r-_XcFIf(Ajc9_So{@{ zg7B#cnTfUdO3{eVlyq1jQleLzvy+tvP?=kojak{nZAcm%i@&IbP7cRk6!5*eKw+0J z)`szVgm-ke;Zfw)-OH-oxYf0a44rYgK3){O!WgW`!$1a#0(V2r=~k$}*2sCbJ-a_|0eg3 zb!_k|d}o5ku#Ic&(lTavv*A@N?z3Qr-lgJA6d;T1=meujsOhIiE7qEhB)XLE`67nD zxO&0kZ)hh1`?b-h!v@$%k8<0Lip1IV-FB+0T@I4haF7?cLfz>y4ZpP84h9*Xj1XGj zw88IfbcZ&FZ(^GC$mVwJ!t#uFMjM*bogNctnXARg4psPl)=#shiaz)>(|~|r>Zpl9 z`DuIV zxgFxy@EvhDGNLl81$oI2W-O-QDyB`1(lH}i0uM~|?eo0IKbdjzZwQKWQH>MU5MXM( z|GvFtknb`bIwvq=3*9lU9`3~vk>}+JwE^FYPUqGcfM22h^mBN=TPC5PmE9shP6j8& z!ruNk3A8L8eZj_Wl`Iaxy>E0p`H|)O(F?lu-D9nPf=8U@NO}3D)_(me`si0s}|~CaV3^b;i1Zxx#s#&h6-D#Ws!&Mh9-+FUhY5&(9#vUjc@`oMbL^5A9ipary!)EOO z?>hcKA?Kl{wJ4OJqLHNc@>y<9Uit70&zpbAgV+91^Lot~G^JoT z*oCNx0dswVKuztJqrG%Ll&%lRgd=l$ z(A@>@*4{!BB{VRY!pf9U;~dws@CyA_*aUlBPO=w=a=2L2FTejomn@(^={~=5S3Va_ zWT$&MhwVzHz%?w_6f@yDu3xe9Nk%rLnWdZcmE-#l*1Sb(MQh()@7gemDDSmiT<1c~ zIW%lYp0dq=t-+ER=DJ1XtGF=R)9=+*o$kFxXDzcaUX>J`WR+1$hC=4s+HQg{@ZWlV z9D*W{Pq}+Q=EEF26I$h_o`Hr_?ml;C^&;PQxO)FGPF-xMEd5;;c=5ycUoe-S8;Ia7 z0+WZxMcvkUI6%XoJ!x*$H}Jg4FNQAvr-c9Tff7;NIN%aSp}kh<#X+?(0qKgU`z_%H z!HMb0;>4tfuvrn($DM9RkRLX!zEB$k$NmsGVkO>__(eTG#igbwRPJt#-TQXSN%Hbm z9_Vc6Qkfhn#4-3Yir;(08EP@^4ILopQ@9QIpYF(pR;J&n?#Wx^b~8n^&uhj)v%08h zi9L~30IiEXA<24g4*YEcP`w%w+{bFudyj|35tVdzlW@v%{Dd9!@UTRqD*ssZ*h@tj zoGEl&-nO?)YcBrUr^hW>RL3#NAs)WZTpd$7W%(gXA6R$_6Z6gBhi8>v<1>*Buh!2F zPpVFigDfAaZCds}G)-s|)U4@_zM*5lDOwg=q&IoI=wFetzjAu%`2#_$M7v#?<5ito z>C-vKq#HWf)o+RxOrS~qI(@xaQzbHSU+NE=x*mseugkxW5(stlDLjPd6#Ml+284XdfxwR3{E!K+MHjJou}n54(F=iy`my&{T!0ls|g@;(q|w$v8Ry literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/images/sub.gif b/trunk/docs/manual/images/sub.gif new file mode 100644 index 0000000000000000000000000000000000000000..93061c5ad7f011307c4188fbc5d134db19fbc8c0 GIT binary patch literal 6083 zcmaKNc~BGC_xAdZs(b)vW+xP(Py6C*@L zL<}GZDo$WT5k&(CqM{Qwz;y!Z;7)MG`HYh<)bIaaSJ$mu{q8&WoO9o+4h;|S79@R! z{J}RPFdB^*hQ-9hBqt|lW@f5Xs=B(m-rimW01N;Q0DJ%h0EhvI2Ot@MGypOI7)5{) z0dBs~z0wh%oa+5J*>tsZ}wSu(NnA8{$BjzT@^96j2&qa&_AU9Ji7GY`0$k=UASb)7PdXQX7zC&=(8>a1lhm-u{$P{?R0!ZqQWJsE zNm7$LVy5yY3~)IhCV7hfWQ{m&%7d6RFqSz*d{TXUJgDOWaSTwg0C&;`)zq%k%Bj`c zbyMK1rYS#C)27M92On^aV1Nra zO;ZK8$3TY>^ooIi16anXyfp?0DnaT1m>dGX6=cQ(ff3Y+05=tgjG!_TOwNSW3(`hG z?${K9$~YBsV*qymq;fFU*i^4fG2j?MS|t!=0=^NX8bPuV#IpeMZOT<_Ux;B?M~%Trt2>0ZRoql~YTTYy~j@iw9UPU_G0H<%$3@HkEM102u(29VeMj zzL;@pl>fhH^6+!M;~@Zyz;&u_>P`re$xA_=8KzNp<{;BtR`hAAyZ2yr;>xh*nw}!o zoRlYh&9#A$bztGl@RsA(%ba6Rt`OW+0H-Lkz6l7|Tf}tpRO#hO*}25eFRrKU`Ec0t zm;NmY5jPe-YJrVJge_GUX2Fnfy1l%vYT55gmls+^oICyS4_Qyl{**d2+irneD~zsz zE>*ug-PoPiRMA?0r+gCk)O5EMEt11#1o1(a*dnilm|U4e?Z4@3-?n?iTju=Lm$rYu z`|{N5doZyf(ao#r?Vu+4X307Q7&LSC@AJ+MbT4MuScH|IU!O2fK3Wx=w&mTyx$B2Y z94UW?Z)jZn=g#pO=G!HWQPu9@#*IN-m0fr~<41Ec>Cc(Io1ba8c8*c~%;g_vG{+w}i0l%c2xq!;8Q2?GMUE z3Y_a3Mhacey&5Uv^*TQCHtR+x?yUw}D(^~Me({_;kvX@#|CHX_D;Qg>gb*904o1_q9U$yg=efLT zIDRnYO=Cm7Pc60piO#`-tc`c<7{21@t7g#?tld=M2UzCT_AX|ae@9rm(BrN&Im+iE z)*ZpuKIx+HFW7e%d)`}ZcY991=Z%H#R~coI?texmM+q9S}PW$NdaKzfY0E zEV)^bu#;dOrvrpTTciP3$WkFpv^cHFCMPzl-*jW4uH#o3%hrzfIMy`x_Wr#6CDCeg zZa=9Y7yogOU5V?ez8kKV@b#NV<7^)~s6Nk&;MQM?DRNs01r{aso)*eS2!gl;*AzyfdnUpv9ih10gIc&+G(DB2VkPjc42_z!|CpYyvCdNqTXI(hDjNil!_!6V zSaSsv6)IfL?gp^z=BJRbF0;~?E;uzjUZKR>G-z=*lmV2b!ffhiy!8ujl1FZIQT!#C zS*{_t8WTGUqn^}Ef0|Wn8^Wm?w-=cd@s``X%FCe2?~fipMrCeE!Krmkjn%Pwhm zdo;=-FH^2s{m07>>U-^1Jb`x(<8YSf7Ku(^y|b0g#WFvf&kZ!xcYwc-Bv;@aB#H6* z-o6l@kNXo3cQFo1vz_{HkS}C+nQU>$wewDz_9gC7!B6{U`hv1seBG z>#3%m5?-6zXIfHMmt$4ENg)cnuov-@La*A0^UfvhB}k-}f2oP{9#xlY^0Z}M1a$>9 z!PP&VZZN-KzTo^KvZv6-hr{H%fL`oU5@oK=Sr@ z?0@LS{rV4S)K%Wyy}i=Blku&laXl$Bg-iGNgAvcAsyaKzJ2gr1d#0Td#?HFizSOg+ zYer9c0zWdvqK3K7Ql|*zN%i(wtX~n4|AQ zr^V-5qHdjDGw0+{N_CVGVj zph8{N`1M-v!HI}X%Fd>*v|7_}zumLK?i4IjcA?RY?-!rpc^|^77eLS%vO5ZKs8A%;jJKbqiS8rU$=wGe{G`e0jJr%Q2-JddgP13|&AW1WYID zp3~k;{HbuShCF2i<|{l7muW$G)~UBhRKOH0)T^esIKi83J?a%Y?$opln`IJ2&lxgCUAQ5LIgla!NcK$!epjuI{yZVFG?j(U z)nutwzZ;3`)qA_eRToC_vUhDV;B4J%_k^p={kQ76*9<6$yo_q<>b`w59`W+{uiArC z;>w(;0VJ2N0onPApif{4$J)67H!9@0}366FzqTJ zyQpscGULzm&}R*yF|1OvbjCI(B#T@=)@fR!#XI{YG1tc7Ec(R+sNc?PMuQ=D)+$qqv~7f0?O#*9_RjjB2cJ&Ax45yk zrF!q$O|_P9FcRlwK-T?-5d@yX)kxW-oA`Ld`0w$In~a%DP26N0sB91}k$=Y9kh4C< zc#D4QR-%#p(aaWgWV4oXj<>zlKiN^Ovj=cKmKw+&gWWW- z&U&6J8~18!ZdiG4qpiIlJA6S4K9-Fau-$ri)XQ?Z!w?-GOn=KZG010M*16r2(}pqb z6Lwe+$K<&N3`*%Aomc9%zgg_->Qnf^lWtY^>khkgZR&@4Sf)Zintci>7_WCjG)nSVBm*YEG_)uZ-)mOOE#fwVXiu;l9HA10f z4)Jb2Q7+lLg6XkVZ&S`fE_EaO414txNUec5!EiWQI9;KO31Pq8-(e?afOsC}LW8l=>{-{Gjv}M(3HAc@#+Oy1?A);D1J$Euw}T z**HhJ-;X5Nho=f!t_o?y36(1Bf-3T%D$3k$){Fx&f&-)^uuOO$?(l*5ZDuR90ZSy_ zHX=}X6?2a^nP@#AJA4pF6g36_7Yw$=U`!8RX@<_X!Y)G0Y8BIJ71;R@!x>g4@(-pg zFVDN+httjT)#G95>e=#XZajFF7P|U{ZYuS8s->++r%`w&A9!^5PCzTPt~HwA6pFcz zbMHDx_dKjPvwU767dM}WpRcp@Wgk{u|B0c4whq&u80drZXm`}K42Ewb=6l&dX_Y3& z={P5&!3_!a^EQj5@rr?MM`ioV-K8=s-io=$Wp-?MuJQh~F%9jZl6F_l*#5$QKx1{* zfYxs!S4hc)(tvU{c_J7z>85-9z4AX(@F4Ff?4!0%0wHX?SOKiD#EO{2j+eWKCG_na z+8scBAzyz_U1d6C)xayMk&>GX_RojOo%gJF8i<*S8aUb(h}G`@)R=b$z?#@u82rP- z#|&fWwMRavf8EApUDG9*dT*-LQ+D66IxQ)gxcA#m%x@D$g6^+c2SQfq2rIuGyF;vv zZ?7Yp&foVO@{>;EVzB->>@0+5N+CL%KE$Iv(1u!sP<`S=dFWZds)!?c=3H+L6F7kRd z2GP~@XL;-I%W3BA)JEV8^3ffu$ow?&0RvK``z=Sf*1#dH#Yl#6qFXO*wD8smQUK z@rHU)PJgw$TB`{9U5_^Lg6cKw5;^kA!BsniNQWay&LjOXJ>=YUBI%oh;|OsbmhqdO zR3;;BRUoAjvYbSDkVm-r<-kp*$Z|Ddu%gNKZTzlqLWlzI!NytZ;haOzRVI`!^Z8p& zlQ=@7##XvsO6$^YXqVC)kmJ2-3f6}fZ9q?G(c^41@`%Xdx}KAA zr&UM>K+MjPjGssfEmEK(Z#F|uu+atsdUEoZY@{eubOR5f@h~C=@X<%pEH53HBZGzW zEwEpo%V~@Z>iaax_SMvG1$7W(SvvZ*saZuy=ztUb zOAKV8#_w~v#PGA+br{cPdokE_3LEFlu43v}_l?i4FQaw6PHT~%$AzcLwe2I(zG}Al z|HOz&xyH~*Oammhb3`ddg0~W-Y>V1)LW+)%peDN35Lf6)>4pV)N@SGd#C*IZ?Y@2U z#mMvW?ekUWj$HafDSbpu|DfM(A~azF*bU&^c%8Cw)%r`t(SQ(GvulGZ-o-!-IB#`Y zkFvd}c>!mub!4pqZL_n^mtVeul6D$}q|WvwZePt4w8VtFo5yF_t&+t{VNMSjZwJooa(gb`*W1dPA7h+(r#*~*UjjIqj?lw*hdT^mciA9 zu%iOU$NK3%bjP!2MeD;w61@LMI}ZuI{2MO9fRjk@!AhI}D~^|#Fdo{jkzX#FDZNT`!)9vQ8%mdy z+OMQOQo7!s#~tycC&cL(de4*_vpE{wd>#%<7+6Ddi7?%7!Bu zc(HUF@`!vAkJc*D!f`ZXVQ4d;v?!2If;9)QK11>LR%KU0-Uif}Q!A(Ve4_N)bIQ~d zvD<@t&D6o{h1X%)%j_KkhMqV2KOO?Q!XfH0n_;E_QDx9b88j1vU3lrv>Nu`W_si4A zmw(tU2fM`vd@vjDD8WZ7aY~Z?(L*?q-cF*%d)wk_HA5#1k(-^U7u2EG^wdEkM!gnF z(elunDzr`M{FFvpoKC%$MY(6Dc)F2xxod+~eW`R6{e?EK2Qqo(X<|_Ntoe7g|M=`R z{{k~PR1Pm9mTTeV0KZ`-!PoX$tQ_xO+W*fWQlFlsHBfEy zX;0+zY|E&ZYTBO?>Q&oE@7y}Rb<7t>5WNOKs{^GrE3 zT>_i3eX>L0S-PC3J%FrBuvQYBdAZDIFBARwUOa-AayV825WfevBqq-^v|(l0GtIsg z>_-oHv@#F+Uvk=eHhok$`;!ntHMDY~iHTx&V-xLp?fl0^$>h&(6k|gyJ@iEnu{4l{ zPPuaD>+-7Q$~OKc1u0!xaA=5BBo*uXkkx-9$9SbxTBJhvrdn#-E~K>FwrW$9*sr2p zmw2{Y(^hWZ0lj}K8V3JPc(%paQk7m_Ny?6ixDNi2K*KxTfA7je@rM)Nm#{Ks#+vN1 z@Yu*BIhZY#teE3qX8kdI>D*fMv@Y zb}8NBaz1Xr-w^q|c>fT;KB-;RK(cGu>-@=p%_diS$751v8lbU**D`B2|{gCwI~ z=GlHh?7purT9gLavtjO)kLsLvdt2Z2e|V=;yW{aIKZW*P-e3O7GO)nU#zP^$yE5A2 ziT6_Xjp*Bk@jq@`otPN!;Vt{Y|7b576LCxg-1}1@?{*|ZMcpr6{T&!M~w`VaE GgEauCMi2b} literal 0 HcmV?d00001 diff --git a/trunk/docs/manual/index.html b/trunk/docs/manual/index.html new file mode 100644 index 0000000000..90fa64a511 --- /dev/null +++ b/trunk/docs/manual/index.html @@ -0,0 +1,27 @@ +URI: index.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR + +URI: index.html.pt-br +Content-Language: pt-br +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/index.html.de b/trunk/docs/manual/index.html.de new file mode 100644 index 0000000000..57d8f39526 --- /dev/null +++ b/trunk/docs/manual/index.html.de @@ -0,0 +1,101 @@ + + + +Dokumentation zum Apache HTTP Server Version 2.1 - Apache HTTP Server + + + + + +

    +
    <-
    + + +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.en b/trunk/docs/manual/index.html.en new file mode 100644 index 0000000000..6d1f2dde15 --- /dev/null +++ b/trunk/docs/manual/index.html.en @@ -0,0 +1,100 @@ + + + +Apache HTTP Server Version 2.1 Documentation - Apache HTTP Server + + + + + + +
    <-
    + + +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.es b/trunk/docs/manual/index.html.es new file mode 100644 index 0000000000..047ce7bb6a --- /dev/null +++ b/trunk/docs/manual/index.html.es @@ -0,0 +1,108 @@ + + + +Versión 2.1 de la documentación del Servidor de HTTP Apache - Servidor HTTP Apache + + + + + + +
    <-
    + +

    Versión 2.1 de la documentación del Servidor de HTTP Apache

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    +

    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.fr b/trunk/docs/manual/index.html.fr new file mode 100644 index 0000000000..0bf38a4b8f --- /dev/null +++ b/trunk/docs/manual/index.html.fr @@ -0,0 +1,101 @@ + + + +Documentation du Serveur HTTP Apache Version 2.1 - Serveur Apache HTTP + + + + + + +
    <-
    + + +
    +

    Langues Disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.ja.euc-jp b/trunk/docs/manual/index.html.ja.euc-jp new file mode 100644 index 0000000000..29bb02df25 --- /dev/null +++ b/trunk/docs/manual/index.html.ja.euc-jp @@ -0,0 +1,100 @@ + + + +Apache HTTP ¥µ¡¼¥Ð ¥Ð¡¼¥¸¥ç¥ó 2.1 ¥É¥­¥å¥á¥ó¥È - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +

    Apache HTTP ¥µ¡¼¥Ð ¥Ð¡¼¥¸¥ç¥ó 2.1 ¥É¥­¥å¥á¥ó¥È

    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    +

    +
    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.ko.euc-kr b/trunk/docs/manual/index.html.ko.euc-kr new file mode 100644 index 0000000000..a472e0c3ae --- /dev/null +++ b/trunk/docs/manual/index.html.ko.euc-kr @@ -0,0 +1,101 @@ + + + +Apache HTTP Server Version 2.1 ¹®¼­ - Apache HTTP Server + + + + + + +
    <-
    + +

    Apache HTTP Server Version 2.1 ¹®¼­

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    +

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.html.pt-br b/trunk/docs/manual/index.html.pt-br new file mode 100644 index 0000000000..1a103ffbbb --- /dev/null +++ b/trunk/docs/manual/index.html.pt-br @@ -0,0 +1,100 @@ + + + +Documentação do Servidor HTTP Apache Versão 2.1 - Servidor HTTP Apache + + + + + + +
    <-
    + + +
    +

    Línguas Disponíveis:  de  | + en  | + es  | + fr  | + ja  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/index.xml b/trunk/docs/manual/index.xml new file mode 100644 index 0000000000..941f439ab6 --- /dev/null +++ b/trunk/docs/manual/index.xml @@ -0,0 +1,91 @@ + + + + + + + + + + +Apache HTTP Server Version 2.1 Documentation + +Release Notes + New features with Apache 2.1/2.2 + New features with Apache 2.0 + Upgrading to 2.2 from 2.0 + Apache License + + +Reference Manual + Compiling and Installing + Starting + Stopping or Restarting + Run-time Configuration Directives + Directive Quick-Reference + Modules + Multi-Processing Modules (MPMs) + Filters + Handlers + Server and Supporting Programs + Glossary + + +Users' Guide + Binding + Configuration Files + Configuration Sections + Content Negotiation + Dynamic Shared Objects (DSO) + Environment Variables + Log Files + Mapping URLs to the Filesystem + Performance Tuning + Security Tips + Server-Wide Configuration + SSL/TLS Encryption + Suexec Execution for CGI + URL Rewriting Guide + Virtual Hosts + + +How-To / Tutorials + Authentication, Authorization, and Access + Control + CGI: Dynamic Content + .htaccess files + Server Side Includes (SSI) + Per-user Web Directories + (public_html) + + +Platform Specific Notes + Microsoft Windows + Novell NetWare + EBCDIC Port + + +Other Topics + Frequently Asked Questions + Sitemap + Documentation for Developers + Other Notes + + + + diff --git a/trunk/docs/manual/index.xml.de b/trunk/docs/manual/index.xml.de new file mode 100644 index 0000000000..bc73e8e765 --- /dev/null +++ b/trunk/docs/manual/index.xml.de @@ -0,0 +1,92 @@ + + + + + + + + + + +Dokumentation zum Apache HTTP Server Version 2.1 + +Hinweise zur Version + Neue Funktionen in Version 2.1/2.2 + Neue Funktionen in Version 2.0 + Upgrade auf Version 2.2 + Apache-Lizenz + + +Bedienungsanleitung + Kompilieren und Installieren + Starten + Stoppen und Neustarten + Konfigurationsanweisungen + Kurzreferenz der Direktiven + Module + Multi-Processing-Module (MPMs) + Filter + Handler + Server und Hilfsprogramme + Glossar + + +Benutzerhandbuch + Bindung + Konfigurationsdateien + Konfigurationsabschnitte + Content Negotiation + Dynamic Shared Objects (DSO) + Umgebungsvariablen + Log-Dateien + URLs auf das Dateisystem abbilden + Performance-Hinweise + Tipps zur Sicherheit + Serverweite Konfiguration + SSL/TLS-Verschlüsselung + Suexec für CGI + Einführung in die + URL-Manipulation + Virtual-Hosts + + +Praxis / Anleitungen + Authentisierung, Autorisierung und + Zugriffskontrolle + CGI: Dynamische Inhalte + .htaccess-Dateien + Server Side Includes (SSI) + Web-Verzeichnisse für Benutzer + (public_html) + + +Plattform-spezifische Anmerkungen + Microsoft Windows + Novell NetWare + EBCDIC-Portierung + + +Weitere Themen + Häufig gestellte Fragen (FAQ) + Seitenindex + Dokumentation für Entwickler + Sonstiges + + + + diff --git a/trunk/docs/manual/index.xml.es b/trunk/docs/manual/index.xml.es new file mode 100644 index 0000000000..3422b44747 --- /dev/null +++ b/trunk/docs/manual/index.xml.es @@ -0,0 +1,96 @@ + + + + + + + + + + +Versión 2.1 de la documentación del Servidor de HTTP Apache + +Notas de la Versión + Nuevas funcionalidades en + Apache 2.0 + Actualizarse a la versión 2.0 desde la 1.3 + Licencia Apache + + +Manual de Referencia + Compilación e Instalación + Iniciar Apache + Parar y reiniciar Apache + Directivas para configurar la +ejecución + Guía rápida de + Referencia de Directivas + Módulos + Módulos de MultiProcesamiento (MPMs) + Filtros + Handlers + El Servidor Apache y Programas de Soporte + Glosario + + +Guía del Usuario + Puertos de escucha + Ficheros de Configuración + Secciones de Configuración + Negociación de Contenidos + Objetos Dinámicos Compartidos (DSO) + Variables de Entorno + Archivos Log + Mapear URLs a ubicaciones de un + sistema de ficheros + Ajustes para conseguir un mejor rendimiento + Consejos de Seguridad + Configuración Básica de Apache + Encriptado SSL/TLS + Ejecución de Suexec para CGIs + Documentación adicional + sobre mod_rewrite + Hosting Virtual + + +How-To / Tutoriales + Autentificación, + Autorización, y Control de Acceso + CGI: Contenido Dinámico + Archivos .htaccess + Server Side Includes (SSI) + Directorios web para cada + usuario (public_html) + + +Notas específicas sobre plataformas + Microsoft Windows + Novell NetWare + EBCDIC Port + + +Documentación adicional + Preguntas Más Frecuentes + Mapa de este sitio web + Documentación para desarrolladores + Otros documentos + + + + + diff --git a/trunk/docs/manual/index.xml.fr b/trunk/docs/manual/index.xml.fr new file mode 100644 index 0000000000..9335be5f77 --- /dev/null +++ b/trunk/docs/manual/index.xml.fr @@ -0,0 +1,90 @@ + + + + + + + + + + +Documentation du Serveur HTTP Apache Version 2.1 + +Notes sur cette version + Nouvelles Fonctionnalités de la version 2.0 + Migrer à 2.0 depuis la version 1.3 + Licence Apache + + +Manuel de Référence + Compilation et Installation + Démarrage + Arrêt ou Redémarrage + Directives de Configuration à l'exécution + Résumé des Directives + Modules + Modules Multi-Processus (MPMs) + Filtres + Handlers + Serveur et Autres Programmes + Glossaire + + +Guide de l'Utilisateur + Liaison + Fichiers de Configuration + Configuration de Sections + Négociation de Contenu + Dynamic Shared Objects (DSO) + Variables d'Environnement + Fichiers Journaux + Correspondances entre URLS et Système de Fichiers + Réglage de la Performance + Conseils sur la Sécurité + Configuration à l'échelle du Serveur + Chiffrement SSL/TLS + Execution Suexec des CGIs + Guide de réécriture d'URLs + Serveurs Virtuels + + +Marche-à-Suivre / Tutoriels + Authentification, Autorisation, et Contrôles + d'accès + CGI: Contenu Dynamique + Fichiers .htaccess + Server Side Includes (SSI) + Répertoires Web par Utilisateur + (public_html) + + +Notes Spécifiques aux Différentes Plate-formes + Microsoft Windows + Novell NetWare + Port EBCDIC + + +Autres Sujets + Foire Aux Questions + Plan du Site + Documentation du Developpeur + Autres Notes + + + + diff --git a/trunk/docs/manual/index.xml.ja b/trunk/docs/manual/index.xml.ja new file mode 100644 index 0000000000..0f592fc735 --- /dev/null +++ b/trunk/docs/manual/index.xml.ja @@ -0,0 +1,91 @@ + + + + + + + + + + +Apache HTTP $B%5!<%P(B $B%P!<%8%g%s(B 2.1 $B%I%-%e%a%s%H(B + +$B%j%j!<%9%N!<%H(B + Apache 2.1/2.2 $B$N?75!G=(B + Apache 2.0 $B$N?75!G=(B + 2.0 $B$+$i(B 2.2 $B$X$N%"%C%W%0%l!<%I(B + Apache $B%i%$%;%s%9(B + + +$B%j%U%!%l%s%9%^%K%e%"%k(B + $B%3%s%Q%$%k$H%$%s%9%H!<%k(B + $B5/F0(B + $B=*N;$H:F5/F0(B + $B + $B%G%#%l%/%F%#%V(B $B%/%$%C%/%j%U%!%l%s%9(B + $B%b%8%e!<%k(B + $B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) + $B%U%#%k%?(B + $B%O%s%I%i(B + $B%5!<%P$H%5%]!<%H%W%m%0%i%`(B + $BMQ8l=8(B + + +$B%f!<%6$N<j0z(B + $B%"%I%l%9$H%]!<%H$N%P%$%s%I(B + $B@_Dj%U%!%$%k(B + $B%;%/%7%g%s$N@_Dj(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $BF0E*6&M-%*%V%8%'%/%H(B (DSO) + $B4D6-JQ?t(B + $B%m%0%U%!%$%k(B + URL $B$r%U%!%$%k%7%9%F%`$K%^%C%W$9$k(B + $B@-G=$K4X$9$kD4@0(B + $B%;%-%e%j%F%#>pJs(B + $B%5!<%PA4BN$N@_Dj(B + SSL/TLS $B$K$h$k0E9f2=(B + CGI $B$N(B Suexec $B + URL Rewriting $B$N + $B%P!<%A%c%k%[%9%H(B + + +How-To / $B%A%e!<%H%j%"%k(B + $BG'>Z!">5G'!"%"%/%;%9@)8f(B + + CGI: $BF0E*%3%s%F%s%D(B + .htaccess $B%U%!%$%k(B + Server Side Includes (SSI) + $B%f!<%6@lMQ%G%#%l%/%H%j(B + (public_html) + + +$B%W%i%C%H%U%)!<%`8GM-$N>pJs(B + Microsoft Windows + Novell NetWare + EBCDIC $BHG(B + + +$B$=$NB>(B + $B$h$/$"$k + $B%5%$%H%^%C%W(B + $B3+H/ + $B$=$NB>(B + + + + diff --git a/trunk/docs/manual/index.xml.ko b/trunk/docs/manual/index.xml.ko new file mode 100644 index 0000000000..a265063947 --- /dev/null +++ b/trunk/docs/manual/index.xml.ko @@ -0,0 +1,90 @@ + + + + + + + + + + +Apache HTTP Server Version 2.1 ¹®¼­ + +¹ßÇ¥¹® + ¹öÀü 2.0ÀÇ »õ·Î¿î ±â´É + 1.3¿¡¼­ 2.0 ¹öÀüÀ¸·Î ¾÷±×·¹À̵å + ¾ÆÆÄÄ¡ ¶óÀ̼±½º + + +ÂüÁ¶ ¼³¸í¼­ + ÄÄÆÄÀÏ°ú ¼³Ä¡ + ½ÃÀÛ + Áß´Ü°ú Àç½ÃÀÛ + ¼³Á¤ Áö½Ã¾î + Áö½Ã¾î ºü¸¥ÂüÁ¶ + ¸ðµâ + ´ÙÁß󸮸ðµâ (MPM) + ÇÊÅÍ + Çڵ鷯 + ¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ + ¿ë¾î + + +»ç¿ëÀÚ Áöħ¼­ + ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ + ¼³Á¤ÆÄÀÏ + ¼½¼Ç ¼³Á¤ + ³»¿ëÇù»ó (content negotiation) + µ¿Àû°øÀ¯°´Ã¼ (DSO) + ȯ°æº¯¼ö + ·Î±×ÆÄÀÏ + URLÀ» ÆÄÀϽýºÅÛ¿¡ ´ëÀÀ + ¼º´ÉÇâ»ó + º¸¾È ÆÁ + ¼­¹ö Àü¿ª ¼³Á¤ + SSL/TLS ¾Ïȣȭ + CGIÀÇ Suexec ½ÇÇà + URL ÀçÀÛ¼º(rewriting) Áöħ¼­ + °¡»óÈ£½ºÆ® + + +How-To / ÅõÅ丮¾ó + ÀÎÁõ, ±ÇÇѺο©, + Á¢±ÙÁ¦¾î + CGI: µ¿Àû ÆäÀÌÁö »ý¼º + .htaccess ÆÄÀÏ + Server Side Includes (SSI) + »ç¿ëÀÚº° À¥µð·ºÅ丮 + (public_html) + + +Ç÷¡Æûº° ¼³¸í + Microsoft Windows + Novell NetWare + EBCDIC Æ÷Æà + + +´Ù¸¥ ÁÖÁ¦ + ÀÚÁÖ ¹°¾îº¸´Â Áú¹® (FAQ) + »çÀÌÆ®¸Ê + °³¹ßÀÚ¸¦ À§ÇÑ ¹®¼­ + ±âŸ + + + + diff --git a/trunk/docs/manual/index.xml.meta b/trunk/docs/manual/index.xml.meta new file mode 100644 index 0000000000..1473c4514d --- /dev/null +++ b/trunk/docs/manual/index.xml.meta @@ -0,0 +1,17 @@ + + + + index + / + . + + + de + en + es + fr + ja + ko + pt-br + + diff --git a/trunk/docs/manual/index.xml.pt-br b/trunk/docs/manual/index.xml.pt-br new file mode 100644 index 0000000000..a174ddf758 --- /dev/null +++ b/trunk/docs/manual/index.xml.pt-br @@ -0,0 +1,89 @@ + + + + + + + + + + +Documentação do Servidor HTTP Apache Versão 2.1 + +Notas da Versão + Novas funcionalidades no Apache 2.1/2.2 + Novas funcionalidades no Apache 2.0 + Atualizando da versão 1.3 para 2.0 + Licença Apache + + +Manual de Referência + Compilando e Instalando + Iniciando + Parando ou Reiniciando + Diretrizes de Configuração para execução + Referência Rápida de Diretrizes + Módulos + Módulos Multi-Processamento (MPMs) + Filtros + Manipuladores + Servidor e Programas Suportados + Glossário + + +Guia do Usuário + Direcionamento + Arquivos de Configuração + Seções de Configuração + Negociação de Conteúdo + Objetos Dinâmicos Compartilhados (DSO) + Variáveis de Ambiente + Arquivos de Registro + Mapeando URLs para o Sistema de Arquivos + Ajustes de Performance + Dicas de Segurança + Configurações do Servidor + Codificação SSL/TLS + Execução Suexec para CGI + Guia para Reescrever URL + Hospedeiros Virtuais + + +How-To / Tutoriais + Autenticação, Autorização, e Controle de Acesso + CGI: Conteúdo Dinâmico + Arquivos .htaccess + Server Side Includes (SSI) + Diretórios Web por usuário (public_html) + + +Notas Específicas sobre Platformas + Microsoft Windows + Novell NetWare + EBCDIC Port + + +Outros Tópicos + Perguntas Mais Frequentes + Mapa do Site + Documentação para Desenvolvedores + Outras Notas + + + + diff --git a/trunk/docs/manual/install.html b/trunk/docs/manual/install.html new file mode 100644 index 0000000000..53619faf71 --- /dev/null +++ b/trunk/docs/manual/install.html @@ -0,0 +1,23 @@ +URI: install.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: install.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: install.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: install.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: install.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: install.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/install.html.de b/trunk/docs/manual/install.html.de new file mode 100644 index 0000000000..5afab9a423 --- /dev/null +++ b/trunk/docs/manual/install.html.de @@ -0,0 +1,407 @@ + + + +Kompilieren und Installieren - Apache HTTP Server + + + + + +
    <-
    +

    Kompilieren und Installieren

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    +
    Diese Übersetzung ist möglicherweise + nicht mehr aktuell. Bitte prüfen Sie die englische Version auf + die neuesten Änderungen.
    + +

    Dieses Dokument umfaßt nur die Kompilierung und Installation des + Apache auf Unix und Unix-ähnlichen Systemen. Für die + Kompilierung und Installation unter Windows lesen Sie bitte Den Apache unter Microsoft Windows + betreiben. Für andere Plattformen lesen Sie bitte die + Dokumentation Plattformen.

    + +

    Die Konfigurations- und Installationsumgebung des Apache 2.0 hat sich + seit dem Apache 1.3 komplett verändert. Der Apache 1.3 benutzt einen + speziellen Satz von Skripten, um eine einfache Installation zu + ermöglichen. Der Apache 2.0 dagegen verwendet nun + libtool und autoconf, um eine Umgebung zu + schaffen, die der vieler anderer Open Source Projekte ähnlich + sieht.

    + +

    Wenn Sie von einer Unterversion auf die nächste aktualisieren (z.B. + von 2.0.50 auf 2.0.51), springen Sie bitte zum Abschnitt Upgrade.

    +
    + +
    top
    +
    +

    Überblick für die Ungeduldigen

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Download$ lynx http://httpd.apache.org/download.cgi +
    Auspacken$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Konfigurieren$ ./configure --prefix=PREFIX +
    Kompilieren$ make
    Installieren$ make install
    Anpassen$ vi PREFIX/conf/httpd.conf
    Testen$ PREFIX/bin/apachectl start +
    + +

    NN muss durch die Nummer der Unterversion ersetzt werden, + und PREFIX durch den Verzeichnispfad, + in dem der Server installiert werden soll. Wenn PREFIX nicht + angegeben ist, wird die Voreinstellung /usr/local/apache2 + verwendet.

    + +

    Beginnend mit den Anforderungen + für die Kompilierung und Installation des Apache HTTPD ist + weiter unten jeder Abschnitt des Kompilierungs- und + Installationsvorganges genauer beschrieben.

    +
    top
    +
    +

    Anforderungen

    + +

    Folgende Anforderungen gelten für die Erstellung des + Apache:

    + +
    +
    Plattenplatz
    +
    Stellen Sie sicher, dass Sie kurzzeitig wenigstens 50 MB freien + Festplattenplatz zur Verfügung haben. Nach der Installation + belegt der Apache ungefähr 10 MB Plattenplatz. Der + tatsächliche Platzbedarf variiert in Abhängigkeit von den + gewählten Konfigurationseinstellungen und + Modulen von Drittanbietern.
    + +
    ANSI-C-Compiler und Generierungswerkzeuge
    +
    Stellen Sie sicher, dass Sie einen ANSI-C Compiler installiert + haben. Der GNU C + Compiler (GCC) der Free Software + Foundation (FSF) ist empfehlenswert (Version 2.7.2 ist gut). Wenn + Sie den GCC nicht besitzen, stellen Sie zumindest sicher, dass der + Compiler Ihres Anbieters ANSI-kompatibel ist. Außerdem muss Ihr + PATH wesentliche Generierungswerkzeuge wie + make enthalten.
    + +
    Zeitgenauigkeit bewahren
    +
    Elemente des HTTP-Protokolls werden in Form einer Tageszeit + ausgedrückt. Darum sollten Sie jetzt prüfen, ob Ihr System + die Fähigkeit zur Zeitsynchronisation besitzt, und diese + gegebenenfalls installieren. Üblicherweise werden hierfür + die Programme ntpdate oder xntpd verwendet, + die auf dem Network Time Protocol (NTP) basieren. Nähere + Informationen über NTP Software und öffentliche Zeitserver + finden Sie in der Usenet Newsgroup comp.protocols.time.ntp + und auf der NTP + Homepage.
    + +
    Perl 5 + [OPTIONAL]
    +
    Für einige Hilfsskripte wie apxs + oder dbmmanage (die in Perl + geschrieben sind) wird der Perl 5 Interpreter benötigt (die + Versionen ab 5.003 sind ausreichend). Wenn kein derartiger Interpreter + vom configure-Skript gefunden werden kann, macht das + jedoch nichts. Selbstverständlich können Sie den Apache 2.0 + auch so generieren und installieren. Lediglich diese Pflegeskripte + können dann nicht verwendet werden. Wenn Sie mehrere Perl + Interpreter installiert haben (vielleicht Perl 4 durch Ihren + Händler und Perl 5 durch Sie selbst), dann ist die Verwendung der + --with-perl Option (siehe unten) empfehlenswert, um + sicherzustellen, dass der richtige Interpreter von + configure ausgewählt wird.
    +
    +
    top
    +
    +

    Download

    + +

    Der Apache kann von der Apache HTTP Server + Downloadseite heruntergeladen werden, auf der verschiedene Spiegelserver + angegeben sind. Für die meisten Benutzer des Apache ist es auf + Unix-ähnlichen Systemen am Besten, die Quellcodeversion herunterzuladen + und zu kompilieren. Der Erstellungsprozess (weiter unten beschrieben) ist + einfach und erlaubt es Ihnen, den Server Ihren Bedürfnissen anzupassen. + Dazu kommt, dass Binärdistributionen gegenüber der aktuellen + Quellcodeversion oft veraltet sind. Wenn Sie tatsächlich ein + Binärpaket herunterladen, folgen Sie bitte den Anweisungen in der Datei + INSTALL.bindist, die der Distribution beiliegt.

    + +

    Es ist wichtig, dass Sie nach dem Herunterladen überprüfen, + dass es sich um einer vollständige und unveränderte Version des + Apache HTTP Servers handelt. Das können Sie erreichen, indem Sie das + heruntergeladene Paket gegen die PGP-Signatur prüfen. Einzelheiten dazu + erfahren Sie auf der Download-Seite. Es + ist auch ein erweitertes Beispiel verfügbar, dass die Anwendung von PGP + beschreibt.

    + +
    top
    +
    +

    Auspacken

    + +

    Das Auspacken des Quellcodes aus dem Apache HTTPD Tarball besteht + aus einem simplen Dekomprimieren und danach "Ent-tarren":

    + +

    + $ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar +

    + +

    Dies erstellt unterhalb des aktuellen Verzeichnisses ein neues + Verzeichnis, das den Quellcode für die Distribution enthält. + Sie sollten mit cd in dieses Verzeichnis wechseln, + bevor Sie mit der Kompilierung des Servers weitermachen.

    + +
    top
    +
    +

    Den Codebaum konfigurieren

    + +

    Der nächste Schritt ist die Konfiguration des + Apache-Codebaumes für Ihre spezielle Plattform und Ihre + persönlichen Bedürfnisse. Dies wird mit dem Skript + configure durchgeführt, das im Wurzelverzeichnis + der Distribution enthalten ist. (Entwickler, welche die CVS Version + des Apache-Codebaumes herunterladen, müssen autoconf + und libtool installiert haben und müssen + buildconf ausführen, bevor sie mit den + nächsten Schritten fortfahren können. Dies wird bei + offiziellen Releases nicht notwendig sein.)

    + +

    Um den Codebaum mit den Standardeinstellungen zu konfigurieren, + geben Sie einfach ./configure ein. Zur Änderung + dieser Voreinstellungen akzeptiert configure eine + Reihe von Variablen und Kommandozeilenoptionen.

    + +

    Die wichtigste Option ist --prefix, der Ablageort, an dem + der Apache später installiert wird, da er für diesen Ort + konfiguriert werden muss, um korrekt zu arbeiten. Eine feinere Einstellung + der Dateiablagen ist mit weiteren configure-Optionen + möglich.

    + +

    Weiterhin können Sie zu diesem Zeitpunkt festlegen, welche Funktionalität Sie + in den Apache aufnehmen möchten, indem Sie Module + aktivieren oder deaktivieren. Der Apache bindet standardmäßig + einen Satz von Basismodulen ein. + Andere Module werden mit Hilfe der Option + --enable-module aktiviert, wobei module + den Namen des Moduls ohne das Präfix mod_ darstellt. + Ausserdem sind alle Unterstriche durch Bindestriche zu ersetzen. Sie + können sich auch entscheiden, Module als "Shared + Objects (DSOs)" zu kompilieren, welche zur Laufzeit ge- und entladen + werden können. Dazu verwenden Sie die Option + --enable-module=shared. Entsprechend können Sie + Basismodule mit der Option --disable-module + deaktivieren. Lassen Sie Vorsicht walten. wenn Sie diese Optionen verwenden, + da configure Sie nicht warnen kann, wenn die von Ihnen + angegebenen Module nicht existieren; die Option wird dann einfach + ignoriert.

    + +

    Zusätzlich ist es zuweilen notwendig, das + configure-Skript mit Extrainformationen zum Ablageort + Ihres Compilers, Ihrer Bibliotheken oder Header-Dateien zu versorgen. Das + tun Sie, indem Sie entweder Umgebungsvariablen oder Kommandozeilenoptionen + an configure übergeben. Für mehr Informationen + lesen Sie bitte die Hilfeseite zu configure.

    + +

    Um einen kurzen Eindruck zu gewinnen, welche Möglichkeiten Sie + haben, folgt hier ein typisches Beispiel, das den Apache mit einem + speziellen Compiler und Compilerflags für das + Installationsverzeichnis /sk/pkg/apache kompiliert, sowie + die beiden zusätzlichen Module mod_rewrite und + mod_speling für späteres Laden durch den + DSO-Mechanismus:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    Wenn configure startet, benötigt es mehrere + Minuten, um die Verfügbarkeit von Features auf Ihrem System zu + prüfen und ein Makefile zu generieren, das später zur + Kompilierung des Servers verwendet wird.

    + +

    Einzelheiten zu den vielen verschiedenen configure-Optionen finden Sie auf der Hilfeseite zu + configure.

    + +
    top
    +
    +

    Erstellen

    + +

    Nun können Sie die verschiedenen Teile, die das Apache-Paket + bilden, einfach durch Ausführen des folgenden Befehls erstellen:

    + +

    $ make

    + +

    Seien Sie hierbei bitte geduldig, denn eine Basiskonfiguration + benötigt ungefähr 3 Minuten auf einem Pentium III/Linux 2.2. + System. Dies kann aber abhängig von Ihrer Hardware und der Anzahl + der Module, die Sie aktiviert haben, sehr stark variieren.

    +
    top
    +
    +

    Installieren

    + +

    Nun endlich installieren Sie das Package unter dem konfigurierten + Installations-PREFIX (siehe oben: Option --prefix + durch Aufrufen von:

    + +

    $ make install

    + +

    Wenn Sie upgraden, wird die Installation Ihre Konfigurationsdateien + oder Dokumente nicht überschrieben.

    +
    top
    +
    +

    Anpassen

    + +

    Als nächstes können Sie Ihren Apache HTTP Server anpassen, + indem Sie die Konfigurationsdateien + unterhalb von PREFIX/conf/ editieren.

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    Werfen Sie auch einen Blick in das Apache-Handbuch unter docs/manual/. Die aktuellste Version dieses Handbuchs + sowie eine komplette Referenz der verfügbaren Konfigurationsanweisungen finden + Sie unter http://httpd.apache.org/docs-2.1/.

    +
    top
    +
    +

    Testen

    + +

    Sie können nun Ihren Apache HTTP Server starten, indem Sie einfach

    + +

    $ PREFIX/bin/apachectl start

    + +

    ausführen.

    + +

    Danach sollten Sie Ihr erstes Dokument unter dem URL + http://localhost/ anfordern können. Die Webseite, + die Sie sehen, ist im DocumentRoot + abgelegt, welches üblicherweise PREFIX/htdocs/ + ist. Den Server stoppen Sie wieder durch + Ausführen von:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    Upgrade

    + +

    Der erste Schritt beim Aktualisieren besteht darin, die + Versionsankündigung sowie die CHANGES-Datei in der + Quelltextdistribution zu lesen, um Änderungen zu finden, die Ihr + System möglicherweise betreffen. Wenn Sie einen größeren + Versionssprung durchführen (z.B. vom 1.3 auf 2.0 oder von 2.0 auf + 2.2), wird es wahrscheinlich auch größere Unterschiede in der + Kompilier- und Laufzeitkonfiguration geben, die manuelle Nacharbeiten + erfordern. Außerdem müssen alle Module aktualisiert + werden, um den Änderungen der Modul-API gerecht zu werden.

    + +

    Die Aktualisierung einer Unterversion auf eine andere (z.B. von 2.0.55 + auf 2.0.57) ist einfacher. make install überschreibt + keine der bereits existierenden Dokumente, Log- und Konfigurationsdateien. + Ausserdem bemühen sich die Entwickler, inkompatible Änderungen + der configure-Optionen, der Laufzeitkonfiguration sowie + der Modul-API zu vermeiden. In den meisten Fällen sollten Sie in der + Lage sein, den gleichen configure-Befehl, die gleiche + Konfiguration und die gleichen Module wieder zu verwenden. (Das gilt erst + seit Version 2.0.41 -- frühere Versionen enthielten noch inkompatible + Änderungen).

    + +

    Wenn Sie den Quellcode von Ihrer letzten Installation aufgehoben haben, + ist ein Upgrade sogar noch einfacher. Die Datei config.nice im + Wurzelverzeichnis des alten Quelltextbaums enthält den genauen + configure-Befehl, der verwendet wurde, um den Quellcode + zu konfigurieren. Um jetzt von einer Version auf die nächste zu + aktualisieren, kopieren Sie einfach die config.nice in das + Verzeichnis der neuen Version, passen sie bei Bedarf an, und + führen Sie sie aus:

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    Sie sollten jede neue Version immer in Ihrer Umgebung + testen, bevor Sie sie produktiv schalten. Beispielsweise können Sie + die neue Version neben der alten installieren, indem Sie ein anderes + --prefix und einen anderen Port wählen (durch Anpassen der + Listen-Direktive). So + können Sie auf eventuelle Inkompatibilitäten testen, bevor Sie + endgültig die neue Version verwenden.
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.html.en b/trunk/docs/manual/install.html.en new file mode 100644 index 0000000000..5842b4b84a --- /dev/null +++ b/trunk/docs/manual/install.html.en @@ -0,0 +1,383 @@ + + + +Compiling and Installing - Apache HTTP Server + + + + + +
    <-
    +

    Compiling and Installing

    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + + +

    This document covers compilation and installation of Apache + on Unix and Unix-like systems only. For compiling and + installation on Windows, see Using Apache with Microsoft + Windows. For other platforms, see the platform documentation.

    + +

    Apache 2.0's configuration and installation environment has + changed completely from Apache 1.3. Apache 1.3 used a custom + set of scripts to achieve easy installation. Apache 2.0 now + uses libtool and autoconf + to create an environment that looks like many other Open Source + projects.

    + +

    If you are upgrading from one minor version to the next (for + example, 2.0.50 to 2.0.51), please skip down to the upgrading section.

    + +
    + +
    top
    +
    +

    Overview for the + impatient

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Download$ lynx http://httpd.apache.org/download.cgi +
    Extract$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Configure$ ./configure --prefix=PREFIX +
    Compile$ make
    Install$ make install
    Customize$ vi PREFIX/conf/httpd.conf
    Test$ PREFIX/bin/apachectl start +
    + +

    NN must be replaced with the current minor version + number, and PREFIX must be replaced with the + filesystem path under which the server should be installed. If + PREFIX is not specified, it defaults to + /usr/local/apache2.

    + +

    Each section of the compilation and installation process is + described in more detail below, beginning with the requirements + for compiling and installing Apache HTTPD.

    +
    top
    +
    +

    Requirements

    + +

    The following requirements exist for building Apache:

    + +
    +
    Disk Space
    +
    Make sure you have at least 50 MB of temporary free disk + space available. After installation Apache occupies + approximately 10 MB of disk space. The actual disk space + requirements will vary considerably based on your chosen + configuration options and any third-party modules.
    + +
    ANSI-C Compiler and Build System
    +
    Make sure you have an ANSI-C compiler installed. The GNU C + compiler (GCC) from the Free Software Foundation (FSF) + is recommended (version 2.7.2 is fine). If you don't have GCC + then at least make sure your vendor's compiler is ANSI + compliant. In addition, your PATH must contain + basic build tools such as make.
    + +
    Accurate time keeping
    +
    Elements of the HTTP protocol are expressed as the time of + day. So, it's time to investigate setting some time + synchronization facility on your system. Usually the + ntpdate or xntpd programs are used for + this purpose which are based on the Network Time Protocol (NTP). + See the Usenet newsgroup comp.protocols.time.ntp + and the NTP + homepage for more details about NTP software and public + time servers.
    + +
    Perl 5 + [OPTIONAL]
    +
    For some of the support scripts like apxs or dbmmanage (which are + written in Perl) the Perl 5 interpreter is required (versions + 5.003 or newer are sufficient). If no such interpreter is found by + the configure script there is no harm. Of course, you + still can build and install Apache 2.0. Only those support scripts + cannot be used. If you have multiple Perl interpreters + installed (perhaps a Perl 4 from the vendor and a Perl 5 from + your own), then it is recommended to use the --with-perl + option (see below) to make sure the correct one is selected + by configure.
    +
    +
    top
    +
    +

    Download

    + +

    Apache can be downloaded from the Apache HTTP Server + download site which lists several mirrors. Most users of + Apache on unix-like systems will be better off downloading and + compiling a source version. The build process (described below) is + easy, and it allows you to customize your server to suit your needs. + In addition, binary releases are often not up to date with the latest + source releases. If you do download a binary, follow the instructions + in the INSTALL.bindist file inside the distribution.

    + +

    After downloading, it is important to verify that you have a + complete and unmodified version of the Apache HTTP Server. This + can be accomplished by testing the downloaded tarball against the + PGP signature. Details on how to do this are available on the download + page and an extended example is available describing the use of + PGP.

    + +
    top
    +
    +

    Extract

    + +

    Extracting the source from the Apache HTTPD tarball is a + simple matter of uncompressing, and then untarring:

    + +

    +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +

    + +

    This will create a new directory under the current directory + containing the source code for the distribution. You should + cd into that directory before proceeding with + compiling the server.

    +
    top
    +
    +

    Configuring the source tree

    + +

    The next step is to configure the Apache source tree for your + particular platform and personal requirements. This is done using + the script configure included in + the root directory of the distribution. (Developers downloading + the CVS version of the Apache source tree will need to have + autoconf and libtool installed and will + need to run buildconf before proceeding with the next + steps. This is not necessary for official releases.)

    + +

    To configure the source tree using all the default options, + simply type ./configure. To change the default + options, configure accepts a variety of variables + and command line options.

    + +

    The most important option is the location --prefix + where Apache is to be installed later, because Apache has to be + configured for this location to work correctly. More fine-tuned + control of the location of files is possible with additional configure + options.

    + +

    Also at this point, you can specify which features you + want included in Apache by enabling and disabling modules. Apache comes with a Base set of modules included by + default. Other modules are enabled using the + --enable-module option, where + module is the name of the module with the + mod_ string removed and with any underscore converted + to a dash. You can also choose to compile modules as shared objects (DSOs) -- which can be loaded + or unloaded at runtime -- by using the option + --enable-module=shared. Similarly, you can + disable Base modules with the + --disable-module option. Be careful when + using these options, since configure cannot warn you + if the module you specify does not exist; it will simply ignore the + option.

    + +

    In addition, it is sometimes necessary to provide the + configure script with extra information about the + location of your compiler, libraries, or header files. This is + done by passing either environment variables or command line + options to configure. For more information, see the + configure manual page.

    + +

    For a short impression of what possibilities you have, here + is a typical example which compiles Apache for the installation + tree /sw/pkg/apache with a particular compiler and flags + plus the two additional modules mod_rewrite and + mod_speling for + later loading through the DSO mechanism:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    When configure is run it will take several minutes to + test for the availability of features on your system and build + Makefiles which will later be used to compile the server.

    + +

    Details on all the different configure options are + available on the configure manual page.

    +
    top
    +
    +

    Build

    + +

    Now you can build the various parts which form the Apache + package by simply running the command:

    + +

    $ make

    + +

    Please be patient here, since a base configuration takes + approximately 3 minutes to compile under a Pentium III/Linux + 2.2 system, but this will vary widely depending on your + hardware and the number of modules which you have enabled.

    +
    top
    +
    +

    Install

    + +

    Now it's time to install the package under the configured + installation PREFIX (see --prefix option + above) by running:

    + +

    $ make install

    + +

    If you are upgrading, the installation will not overwrite + your configuration files or documents.

    +
    top
    +
    +

    Customize

    + +

    Next, you can customize your Apache HTTP server by editing + the configuration files under + PREFIX/conf/.

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    Have a look at the Apache manual under docs/manual/ or consult http://httpd.apache.org/docs-2.1/ for the most recent version of + this manual and a complete reference of available configuration directives.

    +
    top
    +
    +

    Test

    + +

    Now you can start your Apache + HTTP server by immediately running:

    + +

    $ PREFIX/bin/apachectl start

    + +

    and then you should be able to request your first document + via URL http://localhost/. The web page you see is located + under the DocumentRoot + which will usually be PREFIX/htdocs/. + Then stop the server again by + running:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    Upgrading

    + +

    The first step in upgrading is to read the release announcement + and the file CHANGES in the source distribution to + find any changes that may affect your site. When changing between + major releases (for example, from 1.3 to 2.0 or from 2.0 to 2.2), + there will likely be major differences in the compile-time and + run-time configuration that will require manual adjustments. All + modules will also need to be upgraded to accomodate changes in the + module API.

    + +

    Upgrading from one minor version to the next (for example, from + 2.0.55 to 2.0.57) is easier. The make install + process will not overwrite any of your existing documents, log + files, or configuration files. In addition, the developers make + every effort to avoid incompatible changes in the + configure options, run-time configuration, or the + module API between minor versions. In most cases you should be able to + use an identical configure command line, an identical + configuration file, and all of your modules should continue to + work. (This is only valid for versions after 2.0.41; earlier + versions have incompatible changes.)

    + +

    To upgrade across minor versions, start by finding the file + config.nice in the build directory of + your installed server or at the root of the source tree for your + old install. This will contain the exact + configure command line that you used to + configure the source tree. Then to upgrade from one version to + the next, you need only copy the config.nice file to + the source tree of the new version, edit it to make any desired + changes, and then run:

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    You should always test any new version in your + environment before putting it into production. For example, you + can install and run the new version along side the old one by + using a different --prefix and a + different port (by adjusting the Listen directive) to test for any + incompatibilities before doing the final upgrade.
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.html.es b/trunk/docs/manual/install.html.es new file mode 100644 index 0000000000..47a7367bc4 --- /dev/null +++ b/trunk/docs/manual/install.html.es @@ -0,0 +1,438 @@ + + + +Compilación e Instalación - Servidor HTTP Apache + + + + + +
    <-
    +

    Compilación e Instalación

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + + +

    Este documento explica cómo compilar e instalar Apache en + sistemas Unix y tipo Unix. Para obtener información sobre + cómo compilar e instalar en Windows, consulte la sección + Usar Apache en Microsoft + Windows. Para otras plataformas, consulte la + documentación sobre plataformas.

    + +

    El entorno de configuración e instalación de Apache + 2.0 ha cambiado completamente respecto al de Apache 1.3. Apache + 1.3 usaba un conjunto de scripts a medida para conseguir una + instalación fácil. Apache 2.0 usa libtool y + autoconf para crear un entorno más parecido al + de muchos otros proyectos Open Source.

    + +

    Si lo que quiere hacer es actualizar su servidor Apache desde + una versión menor (por ejemplo, desde la 2.0.50 a la 2.0.51), + pase directamente a la sección de actualización.

    + +
    + +
    top
    +
    +

    Visión general del proceso para + impacientes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Descargar$ lynx http://httpd.apache.org/download.cgi +
    Descomprimir$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Ejecutar el script configure$ ./configure --prefix=PREFIX +
    Compilar$ make
    Instalar$ make install
    Personalizar$ vi PREFIX/conf/httpd.conf
    Comprobar que la instalación + funciona$ PREFIX/bin/apachectl start +
    + +

    NN hay que reemplazarlo por el número de la + versión menor, y PREFIX hay que reemplazarlo por la + ruta en la que se va a instalar Apache. Si no especifica + ningún valor en PREFIX, el valor por defecto que se + toma es /usr/local/apache2.

    + +

    Cada parte del proceso de configuración e instalación + se describe detalladamente más abajo, empezando por los + requisitos para compilar e instalar Apache.

    +
    top
    +
    +

    Requisitos

    + +

    Estos son los requisitos necesarios para compilar Apache:

    + +
    +
    Espacio en disco
    Compruebe que tiene disponibles al + menos 50 MB de espacio libre en disco. Después de la + instalación, Apache ocupa aproximadamente 10 MB. No + obstante, la necesidad real de espacio en disco varía + considerablemente en función de las opciones de + configuración que elija y de los módulos externos que + use.
    + +
    Compilador ANSI-C y Build System
    Compruebe que + tiene instalado un compilador de ANSI-C. Se recomienda el Compilador GNU C + (GCC) de la Free Software + Foundation (FSF) (con la versión 2.7.2 es + suficiente). Si no tiene instaldo el GCC, entonces compruebe que + el compilador que va a utilizar cumple con los estándares + ANSI. Además, su PATH debe contener la + ubicación donde de encuentran las herramientas básicas + para compilar tales como make.
    + +
    Ajuste exacto del reloj del sistema
    Los elementos + del protocolo HTTP están expresados según la hora del + dia. Por eso, si quiere puede investigar como instalar alguna + utilidad para sincronizar la hora de su sistema. Para esto, + normalmente, se usan los programas ntpdate o + xntpd, que están basados en el protocolo + Network Time Protocol (NTP). Consulte el grupo de noticias comp.protocols.time.ntp + y el sitio web de NTP + para obtener más información sobre NTP y los + servidores públicos de tiempo.
    + +
    Perl 5 [OPCIONAL]
    +
    Para algunos de los scripts de soporte como apxs o dbmmanage (que están + escritos en Perl) es necesario el intérprete de Perl 5 (las + versiones 5.003 o posteriores son suficientes). Si el script + `configure' no encuentra ese intérprete + tampoco pasa nada. Aún puede compilar e instalar Apache + 2.0. Lo único que ocurrirá es que esos scripts de + soporte no podrán ser usados. Si usted tiene varios + interpretes de Perl instalados (quizás Perl 4 porque estaba + ya incluido en su distribución de Linux y Perl 5 porque lo + ha instalado usted), entonces se recomienda usar la opción + --with-perl para asegurarse de que + ./configure usa el intérprete correcto.
    +
    +
    top
    +
    +

    Descargar

    + +

    Puede descargar Apache desde la sección de + descargas del sitio web de Apache el cual tiene varios + mirrors. Para la mayoría de los usuarios de Apache que tienen + sistemas tipo Unix, se recomienda que se descarguen y compilen el + código fuente. El proceso de compilación (descrito + más abajo) es fácil, y permite adaptar el servidor + Apache a sus necesidades. Además, las versiones de + disponibles en archivos binarios no están siempre actulizadas + con las últimas modificaciones en el codigo fuente. Si se + descarga un binario, siga las instrucciones contenidas en el + archivo INSTALL.bindist incluido en la + distribución

    + +

    Después de la descarga, es importante que verifique que el + archivo descargado del servidor HTTP Apache está completo y + sin modificaciones. Esto puede hacerlo comparando el archivo + descargado (.tgz) con su firma PGP. Instrucciones detalladas de + cómo hacer esto están disponibles en la + sección de descargas junto con un ejemplo de cómo usar + PGP.

    + +
    top
    +
    +

    Descomprimir

    + +

    Extraer el código fuente del archivo .tgz que acabada de + descargar es muy fácil. Ejecute los siguientes comandos:

    + +

    + $ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar +

    + +

    Estos comandos crearán un nuevo directorio dentro del + directorio en el que se encuentra y que contendrá el + código fuente de la distribución. Debe cambiarse a ese + directorio con cd para proceder a compilar el + servidor Apache.

    + +
    top
    +
    +

    Configuración de la estructura de +directorios

    + +

    El siguiente paso es configurar la estructura de directorios + para su plataforma y sus necesidades personales. Esto se hace + usando el script configure incluido en el directorio + raiz de la distribución que acaba de descargar. (Los + desarrolladores que se descarguen la versión del CVS de la + estructura de directorios necesitarán tener instalados + autoconf y libtool, y necesitarán + ejecutar buildconf antes de continuar con los + siguientes pasos. Esto no es preciso para las versiones + oficiales.)

    + +

    Para configurar la estructura de directorios a partir del + código fuente usando las opciones por defecto, solo tiene que + ejecutar ./configure. Para cambiar las opciones por + defecto, configure acepta una serie de variables y + opciones por la línea de comandos.

    + +

    La opción más importante es --prefix que + es el directorio en el que Apache va a ser instalado después, + porque Apache tiene que ser configurado para el directorio que se + especifique para que funcione correctamente. Es posible lograr un + mayor control del lugar donde se van a instalar los ficheros de + Apache con otras opciones de + configuración.

    + +

    En este momento, puede especificar que características + o funcionalidades quiere incluir en Apache activando o + desactivando módulos. Apache viene con + una selección + básica de módulos incluidos por defecto. Se pueden + activar otros módulos usando la opción + --enable-module, donde module + es el nombre del módulo sin el mod_ y + convirtiendo los guiones bajos que tenga en guiones normales. + También puede optar por compilar módulos como objetos dinámicos compartidos (DSOs) -- + que pueden ser activados o desactivados al ejecutar -- usando la + opción --enable-module=shared. De + igual manera, puede desactivar alguno de los módulos que + vienen por defecto en la selección basica con la opción + --disable-module. Tenga cuidado cuando + use estas opciones, porque configure no le + avisará si el módulo que especifica no existe; + simplemente ignorará esa opción.

    + +

    Además, a veces es necesario pasarle al script + configure información adicional sobre donde esta + su compilador, librerias o ficheros de cabecera. Esto se puede + hacer, tanto pasando variables de entorno, como pasandole opciones + a configure a través de la línea de + comandos. Para más información, consulte el Manual del script + configure.

    + +

    Para que se haga una idea sobre las posibilidades que tiene, + aquí tiene un ejemplo típico que configura Apache para + la ruta /sw/pkg/apache con un compilador y unos flags + determinados, y además, con dos módulos adicionales + mod_rewrite y mod_speling para + cargarlos después a través del mecanismo DSO:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    Cuando se ejecuta configure se comprueban que + características o funcionalidades están disponibles en + su sistema y se crean los Makefiles que serán usados luego + para compilar el servidor. Esto tardará algunos minutos.

    + +

    La información sobre todas las opciones de + configure está disponible en el Manual del script + configure.

    + +
    top
    +
    +

    Compilar

    + +

    Ahora puede compilar las diferentes partes que forman Apache + simplemente ejecutando el siguiente comando:

    + +

    $ make

    + +

    Por favor, tanga un poco de paciencia ahora, porque una + configuración básica tarda aproximadamente 3 minutos en + compilar en un Pentium III con un sistema Linux 2.2, pero este + tiempo puede variar considerablemente en función de su + hardware y del número de módulos que haya + seleccionado.

    +
    top
    +
    +

    Instalar

    + +

    Ahora es el momento de instalar el paquete en el diretorio + elegido en PREFIX (consulte la opción + --prefix más arriba) ejecutando:

    + +

    $ make install

    + +

    Si usted está solo actualizando una instalación + anterior, la nueva instalación no sobreescribirá sus + ficheros de configuración ni otros documentos.

    +
    top
    +
    +

    Personalizar

    + +

    El paso siguiente, es personalizar su servidor Apache editando + los ficheros de configuración + que están en PREFIX/conf/.

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    échele un vistazo al Manual de Apache que está en docs/manual/ o consulte en http://httpd.apache.org/docs-2.1/ la versión más + reciente de este manual y la Guia de Referencia de todas las directivas de configuración + disponibles.

    +
    top
    +
    +

    Comprobar que la instalación +funciona

    + +

    Ahora puede iniciar su servidor + Apache cuando quiera ejecutando:

    + +

    $ PREFIX/bin/apachectl start

    + +

    y entonces debe poder acceder al documento que tenga + especificado por defecto usando el siguiente URL: + http://localhost/. El documento que verá + estará en DocumentRoot y + casi siempre estará en PREFIX/htdocs/. + Si quiere parar el servidor, puede + hacerlo ejecutando:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    Actualizar una instalación +prrevia

    + +

    El primer paso para actualizar una instalación anterior es + leer las especificaciones de la versión y el fichero + CHANGES en la distribución de código fuente + que ha descargado para encontrar los cambios que puedan afectar a + su instalación actual. Cuando el cambio sea entre versiones + mayores (por ejemplo, de la 1.3 a la 2.0 o de la 2.0 a la 2.2), + entonces es más probable que haya diferencias importantes en + la compilación y en la ejecución que necesitarán + ajustes manuales. Todos los módulos necesitarán + también ser actualizados para adaptarse a los cambios en el + interfaz de programación (API) de módulos.

    + +

    La actualización cuando el cambio es entre versiones + menores (por ejemplo, de la 2.0.55 a la 2.0.57) es más + fácil. El proceso make install no + sobreescribirá ninguno de los documentos existentes, archivos + log, o archivos de configuración. Además, los + desarrolladores hacen todos los esfuerzos posibles para evitar + cambios que generen incompatibilidades en las opciones de + configure, en la configuración de la + ejecución o en la interfaz de programación de + módulos. En la mayor parte de los casos debe poder usar un + comando configure idéntico, un fichero de + configuracién idéntico, y todos sus módulos deben + seguir funcionando. (Esto es válido solo para versiones + posteriores a la 2.0.41; las versiones anteriores contienen + cambios incompatibles.)

    + +

    Si va a conservar la estructura de directorios de su anterior + instalación, la actualización es más fácil + incluso. El fichero config.nice que está en el + directorio raiz de la estructura de directorios antigua contiene + exactamente el comando configure que usted usó + para configurar la estructura de directorios de Apache. Entonces, + para actualizar su instalación de una versóon a la + siguinete, solo tiene que copiar el archivo + config.nice a la estructura de directorios del + código fuente de la nueva versión, editarlo, hacer + cualquier cambio que desee, y ejecutarlo :

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    Tenga en cuenta que antes de poner una nueva + versión de Apache en producción, debe siempre probarla + antes en su entorno. Por ejemplo, puede instalar y ejecutar la + nueva versión junto con la antigua usando un + --prefix diferente y un puerto diferente (modificando + la directiva Listen) + para comprobar que no existe ninguna incompatibilidad antes de + hacer la actualización definitiva.
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.html.fr b/trunk/docs/manual/install.html.fr new file mode 100644 index 0000000000..4d92f8f237 --- /dev/null +++ b/trunk/docs/manual/install.html.fr @@ -0,0 +1,429 @@ + + + +Compilation et Installation - Serveur Apache HTTP + + + + + +
    <-
    +

    Compilation et Installation

    +
    +

    Langues Disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    +
    Cette traduction peut être périmée. Verifiez la version + Anglaise pour les changements récents.
    + + +

    Ce document couvre la compilation et l'installation d'Apache sur les + systèmes Unix et clones d'Unix. Pour la compilation et l'installation sous + Windows, voir Utiliser Apache sous Windows + . Pour les autres plates-formes, voir la documentation des plates-formes.

    + +

    L'environnement de configuration et d'installation d'Apache 2.0 a été + complétement revu par rapport à celui d'Apache 1.3. Apache 1.3 utilisait un + ensemble de scripts pour permettre une installation facile. Apache 2.0 + utilise à présent libtool et autoconf afin de + créer un environnement le plus proche possible d'autres projets + Logiciel Libre.

    + +

    Si vous faite une mise à niveau d'une version mineure à la suivante (par + exemple, de 2.0.50 à 2.0.51), veuillez s'il vous plaît passer directement à + la section Mise à niveau.

    + +
    + +
    top
    +
    +

    Survol Rapide pour les + impatients

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Télécharger$ lynx http://httpd.apache.org/download.cgi +
    Extraire$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Configurer$ ./configure --prefix=PREFIX +
    Compiler$ make
    Installer$ make install
    Personnaliser$ vi PREFIX/conf/httpd.conf
    Tester$ PREFIX/bin/apachectl start +
    + +

    NN doit être remplacé par le numéro de version mineure actuel, et + PREFIX par le chemin où le serveur doit être installé. Si + PREFIX n'est pas spécifié, l'installation se fait dans + /usr/local/apache2.

    + +

    Chacune des sections du processus de compilation et d'installation est + décrite ci-après, en commençant par les pré-requis à la compilation et à + l'installation d'Apache HTTPD.

    +
    top
    +
    +

    Pré-requis

    + +

    Les pré-requis suivants sont nécessaire pour l'installation d'Apache:

    + +
    +
    Espace Disque
    +
    Au moins 50 Mo d'espace disque temporaire sont nécessaires. Après + installation, Apache occupe environ 10 Mo sur le disque. L'espace disque + occupé par une installation complète dépend beaucoup de la configuration + du serveur, ainsi que de la présence éventuelle de modules tiers.
    + +
    Compilateur C ANSI et Build
    +
    Un compilateur C ANSI doit être utilisé. Le compilateur C GNU + (GCC) de la Free Software Foundation + (FSF) est recommandé (la version 2.7.2 convient). En cas + d'absence de GCC, vérifiez que le compilateur fourni avec l'architecture + utilisée est conforme aux normes ANSI. De plus, les outils de constructions + de base, tel make, doivent être présents dans votre + PATH.
    + +
    S'assurer que la machine est et reste à l'heure
    +
    Certains éléments du protocole HTTP sont exprimés en tant qu'heure de + la journée. Aussi est-il important de s'assurer que le système où Apache + doit tourner dispose de mécanismes de synchronisation temporelle. En + général, les programmes ntpdate ou xntpd sont + utilisés; ces programmes implémentent le Network Time Protocol (NTP). + Voir le groupe Usenet comp.protocols.time.ntp et la page NTP pour plus de détails + sur les logiciels NTP et les serveurs de temps publics.
    + +
    Perl 5 + [FACULTATIF]
    +
    Certains des scripts fournis avec Apache, tel apxs ou dbmmanage (qui sont écrits en + Perl) nécessitent l'interpréteur Perl 5 (version 5.003 ou supérieure). + Au cas où le script configure ne trouve pas d'interpréteur + Perl, la compilation sera quand même réalisée sans souci. Seuls ces + scripts ne seront pas utilisables. Si plusieurs interpréteurs Perl sont + installés (par exemple, Perl 4 fourni avec l'OS, et Perl 5 installé par + l'administrateur), il est conseillé de passer l'option + --with-perl afin de garantir que le bon interpréteur est + utilisé par ./configure.
    +
    +
    top
    +
    +

    Télécharger

    + +

    Apache est téléchargeable depuis le site de téléchargement + d'Apache qui fournit la liste de plusieurs miroirs. Là sont disponibles + les dernières versions. La plupart des + utilisateurs d'Apache sur des systèmes de type Unix devraient + probablement télécharger et compiler une version à partir du code source. + Le processus de construction (décrit ci-dessous) est facile et + vous permet d'adapter votre serveur pour convenir à vos besoins. + En outre, les versions binaires ne sont souvent pas à jour avec + les dernières versions du code source. Si vous téléchargez une + version binaire, suivez les instructions dans le dossier + INSTALL.bindist à l'intérieur de la distribution.

    + +

    Après le téléchargement, il est important de vérifier que les sources + téléchargées sont bien complètes et non modifiées, et ce surtout si un + miroir a été utilisé pour le téléchargement. Ceci peut être fait en + testant l'archive tar téléchargée avec la signature PGP. Cette procédure + s'effectue en 2 étapes. D'abord, il faut récupérer le fichier KEYS du site + de distribution d'Apache. (Pour vérifier que ce fichier KEYS + n'a pas été modifié, une bonne idée peut être d'utiliser un fichier d'une + distribution précédente d'Apache ou d'importer les clés d'un serveur de + clés public.) Les clés peuvent être importées dans le keyring de + l'utilisateur au moyen d'une des commandes (selon la version de PGP):

    + +

    $ pgp < KEYS

    + +

    ou

    + +

    $ gpg --import KEYS

    + +

    La prochaine étape est de tester l'archive tar au moyen de la signature + PGP, qui devrait toujours être disponible sur le site principal d'Apache. + Un lien vers cette signature est placé derrière le lien de téléchargement + correspondant ou peut être trouvé dans le répertoire correspondant sur le site de distribution + d'Apache. Le nom de ce fichier est le même que celui de l'archive + source, avec en plus l'extension .asc. La distribution + téléchargée peut alors être vérifiée au moyen de la commande (à nouveau, + selon la version de PGP):

    + +

    $ pgp httpd-2_1_NN.tar.gz.asc

    + +

    ou

    + +

    $ gpg --verify httpd-2_1_NN.tar.gz.asc

    + +

    Un message comme celui-ci devrait s'afficher

    + +

    Good signature from user "Martin Kraemer + <martin@apache.org>".

    + +

    Selon les relations de confiances contenues dans le keyring de + l'utilisateur, un message peut s'afficher, spécifiant que la relation entre + la clé et le signataire ne peut être vérifiée. Ceci n'est pas un problème si + vous ne mettez pas en doute l'authenticité du fichier KEYS.

    +
    top
    +
    +

    Extraire

    + +

    Extraire les sources à partir de l'archive tar est une simple affaire de + décompression et d'extraction tar:

    + +

    +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +

    + +

    Un nouveau répertoire est créé dans le répertoire courant, il contient le + code source de la distribution. Il faut aller dans ce répertoire au moyen + de la commande cd avant de commencer la compilation du + serveur.

    +
    top
    +
    +

    Configurer l'arborescence source

    + +

    L'étape suivante est la configuration de l'arborescence source d'Apache, + pour votre plate-forme et selon les nécessités du site. Cette configuration est + réalisée au moyen du script configure fourni dans le + répertoire racine de la distribution. (Les développeurs qui téléchargent + Apache via CVS devront utiliser les outils autoconf et + libtool avant de passer à la suite. Ceci n'est pas nécessaire + pour les versions officielles.)

    + +

    Pour configurer l'arborescence source en utilisant les options par + défaut, tapez ./configure. Pour modifier les valeurs des + options par défaut, configure accepte un grand nombre de + variables et d'options de ligne de commande.

    + +

    La plus importante de ces options est le chemin du répertoire où + Apache sera installé, + car Apache doit être configuré pour que cet emplacement fonctionne + correctement. Plusieurs autres options sont disponibles pour + le contrôle fin de l'emplacement des fichiers résultants avec options de + configuration.

    + +

    En outre, à ce moment, vous pouvez indiquer quels fonctionnalités + vous voulez inclure dans Apache en ajoutant et/ou en retranchant + des modules. Apache vient avec un ensemble + de modules de Base + inclus par défaut. D'autres modules peuvent être ajoutés en utilisant + l'option --enable-module, où + module est le nom du module avec la chaîne + mod_ coupée et avec les caractères de soulignement + convertis en tirets. Vous pouvez également choisir de compiler + des modules en tant qu'objets partagés (DSOs), + qui peuvent être chargés ou déchargé à l'exécution -- en employant + l'option --enable-module=shared. + De même, vous pouvez retrancher les modules de Base avec l'option + --disable-module. Prenez garde lorsque + vous employez ces options, puisque configure ne peut + vous informer si le module cible n'existe pas; configure + ignorera simplement l'option.

    + +

    Il est parfois nécessaire de fournir des + informations supplémentaires au script + configure sur l'emplacement de vos + compilateur, bibliothèques ou dossiers d'en-tête. Ceci se fait en + passant les variables d'environnement ou des options incluses sur la ligne + de commande à configure. Pour plus d'information + sur ce sujet, consultez la page de documentation + configurer.

    + +

    L'exemple suivant compile Apache pour être installé + dans /sw/pkg/apache avec un + compilateur et des options de compilation particulières, ainsi que les deux + modules mod_rewrite et mod_speling, qui + pourront être chargés plus tard au moyen des mécanismes DSO:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    Une fois lancé, configure peut prendre quelques minutes + pour tester les possibilités du système et produire les fichiers + Makefile qui seront utilisés pour construire le serveur.

    + +

    Les détails de toutes les options configure sont + disponibles sur la page de documentation configurer.

    +
    top
    +
    +

    Compiler

    + +

    Les différents composants d'Apache sont à présent prêts à + être compilés, en tapant simplement la commande:

    + +

    $ make

    + +

    Un peu de patience est requise, une configuration standard met environ 3 + minutes à compiler sur un Pentium III sous Linux 2.2. Ce temps peut + varier largement suivant le matériel utilisé et les modules + selectionnés.

    +
    top
    +
    +

    Installer

    + +

    Il est temps d'installer le 'package' dans le répertoire d'installation + PREFIX configuré auparavant (voir l'option --prefix + ci-dessus) en tapant:

    + +

    $ make install

    + +

    En cas de mise à jour, l'installation n'écrasera ni les fichiers de + configuration du serveur, ni ses documents.

    +
    top
    +
    +

    Personnaliser la Configuration

    + +

    Il reste à présent à configurer le serveur HTTP Apache, en éditant les + fichiers de configuration placés dans + PREFIX/conf/.

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    A consulter : le manuel d'Apache dans + docs/manual/ ou bien http://httpd.apache.org/docs-2.1/ pour la dernière version de ce + manuel, ainsi qu'une référence complète de toutes les + directives de configuration.

    +
    top
    +
    +

    Tester

    + +

    Une fois configuré, le serveur HTTP Apache peut être + démarré en tapant:

    + +

    $ PREFIX/bin/apachectl start

    + +

    Vous devriez alors pouvoir tester l'URL http://localhost/. + La page affichée se trouve dans le répertoire + DocumentRoot, habituellement configuré + en tant que PREFIX/htdocs/. + Le serveur peut être arrêté en tapant:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    Mise à niveau

    + +

    La première étape pour une mise à niveau est de lire + l'annonce de la nouvelle version et le fichier CHANGES + dans la distribution afin de trouver tous les changements qui + peuvent affecter votre site. Si la mise à jour est effectuée + entre deux versions principales (par exemple, de 1.3 à 2.0 ou + de 2.0 à 2.2), attendez-vous à des différences majeures + au moment de la compilation et de l'exécution, exigeant probablement + des ajustements manuels. Tous les modules devront également + être mis à niveau pour tenir compte des changements de l'API.

    + +

    La mise à niveau d'une version mineure à une plus récente + (par exemple, de 2.0.55 à 2.0.57) est plus facile. Le processus + make install n'écrasera aucun de vos documents, + fichiers journaux, ou fichiers de configuration existants. + En outre, les développeurs font tous les efforts possibles + pour éviter les changements incompatibles des options + configure, de la configuration d'exécution, + ou de l'API entre les versions mineures. Dans la plupart + des cas vous devriez pouvoir employer une ligne de commande + configure et un fichier de configuration + identiques. De plus, tous vos modules devraient continuer à fonctionner. + (Ceci ne vaut que pour les versions postérieures à 2.0.41; + les versions antérieures ont des changements incompatibles.)

    + +

    Si vous avez gardé l'arborescence source de votre dernière + installation, la mise à niveau est encore plus facile. + Le dossier config.nice dans la racine de l'ancienne + arborescence contient la ligne de commande configure + exacte que vous avez utilisée pour configurer l'arborescence des + sources. Pour faire la mise à niveau d'une version à la suivante, + vous devez copier le dossier config.nice dans + l'arborescence des sources de la nouvelle version, l'éditer + pour faire les changements désirés, puis exécuter:

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    Vous devriez toujours essayer une + nouvelle version dans un environnement de test avant de la + mettre dans un environnement de production. Par exemple, vous pouvez + installer et exécuter la nouvelle version côte à côte avec l'ancienne + en employant un --prefix et un port différents + (ce qui est possible en ajustant la directive Listen) + dans le but de tester toutes les incompatibilités possibles avant de + faire la mise à niveau finale.
    +
    +
    +

    Langues Disponibles:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.html.ja.euc-jp b/trunk/docs/manual/install.html.ja.euc-jp new file mode 100644 index 0000000000..af78f7f72a --- /dev/null +++ b/trunk/docs/manual/install.html.ja.euc-jp @@ -0,0 +1,395 @@ + + + +¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë

    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    +
    This translation may be out of date. Check the + English version for recent changes.
    + + +

    ¤³¤Îʸ½ñ¤Ç°·¤¦ÈϰϤϡ¢Unix ¤ä Unix ¤ËÎà»÷¤·¤¿¥·¥¹¥Æ¥à¤Ç¤Î + Apache ¤Î¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤¹¡£ Windows ¤Ë¤ª¤±¤ë + ¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë¤Ë´Ø¤·¤Æ¤Ï¡ÖMicrosoft + Windows ¤Ç Apache ¤ò»È¤¦¡×¤ò¤´Í÷²¼¤µ¤¤¡£ + ¤½¤Î¾¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ë´Ø¤·¤Æ¤Ï¡Ö¥×¥é¥Ã¥È¥Û¡¼¥à¡×¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    Apache 2.0 ¤ÎÀßÄê¤È¥¤¥ó¥¹¥È¡¼¥ë¤Î´Ä¶­¤Ï¡¢Apache 1.3 ¤È¤Ï + ´°Á´¤Ë°Û¤Ê¤ë¤â¤Î¤Ë¤Ê¤ê¤Þ¤·¤¿¡£´Êñ¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤ë¤è¤¦¤Ë¡¢ + Apache 1.3 ¤Ç¤ÏÆÃÀ½¥¹¥¯¥ê¥×¥È¤ò»È¤Ã¤Æ¤¤¤Þ¤·¤¿¡£ + Apache 2.0 ¤Ç¤Ï¾¤Î Open Source ¥×¥í¥¸¥§¥¯¥È¤ÈƱÍͤδĶ­¤Ë + ¤¹¤ë¤¿¤á¤Ë libtool ¤È autoconf + ¤ò»È¤¦¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥Þ¥¤¥Ê¡¼¥Ð¡¼¥¸¥ç¥ó¤«¤é¤½¤Î¼¡¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ë + (2.0.50 ¤«¤é 2.0.51 ¤ØÅù) ¾ì¹ç¤Ï¡¢¤Þ¤º + ¥¢¥Ã¥×¥°¥ì¡¼¥É¤ò¤´Í÷²¼¤µ¤¤¡£

    + +
    + +
    top
    +
    +

    ³µÍ× (¤»¤Ã¤«¤Á¤Ê¿Í¸þ¤±)

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥À¥¦¥ó¥í¡¼¥É$ lynx http://httpd.apache.org/download.cgi +
    Ÿ³«$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    ÀßÄê$ ./configure --prefix=PREFIX +
    ¥³¥ó¥Ñ¥¤¥ë$ make
    ¥¤¥ó¥¹¥È¡¼¥ë$ make install
    ¥«¥¹¥¿¥Þ¥¤¥º$ vi PREFIX/conf/httpd.conf
    ¥Æ¥¹¥È$ PREFIX/bin/apachectl start +
    + +

    NN ¤ÏºÇ¿·¤Î¥Þ¥¤¥Ê¡¼¥Ð¡¼¥¸¥ç¥ó¥Ê¥ó¥Ð¡¼¤Ë¡¢ + PREFIX ¤Ï¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¥µ¡¼¥Ð¤Ç¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ñ¥¹¤Ë¡¢ + ÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£PREFIX ¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Î /usr/local/apache2 ¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Apache HTTPD ¤Î¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë¤ËɬÍפʤâ¤Î¤ò¤Ï¤¸¤á¤È¤·¤Æ¡¢ + ÊÔ½¸¤È¥¤¥ó¥¹¥È¡¼¥ë¥×¥í¥»¥¹¤Ç¤Î¤½¤ì¤¾¤ì¤Î¹à¤Ï + ¼¡¤Ë¾Ü¤·¤¯µ­½Ò¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ɬÍפʤâ¤Î

    + +

    Apache ¤Î¥Ó¥ë¥É¤Ë¤Ï¼¡¤Î¤â¤Î¤¬É¬ÍפǤ¹:

    + +
    +
    ¥Ç¥£¥¹¥¯¥¹¥Ú¡¼¥¹
    +
    ¥Ç¥£¥¹¥¯¤Ë¾¯¤Ê¤¯¤È¤â 50 MB ¤Î°ì»þŪ¤Ê¶õ¤­ÍÆÎ̤¬¤¢¤ë¤è¤¦¤Ë + µ¤¤òÉÕ¤±¤Æ¤¯¤À¤µ¤¤¡£¥¤¥ó¥¹¥È¡¼¥ë¸å¤Ï Apache ¤Ï 10 MB ÄøÅ٤Π+ ¥Ç¥£¥¹¥¯¥¹¥Ú¡¼¥¹¤òÀê¤á¤Þ¤¹¡£¼ÂºÝ¤ËɬÍפˤʤë¥Ç¥£¥¹¥¯¥¹¥Ú¡¼¥¹¤Ï¡¢ + ÀßÄꥪ¥×¥·¥ç¥ó¤ä¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¡¼À½¥â¥¸¥å¡¼¥ë¤ò¤É¤¦ÁªÂò¤¹¤ë¤«¤Ë¤è¤Ã¤Æ + Â礭¤¯ÊѤï¤ë¤Ç¤·¤ç¤¦¡£
    + +
    ANSI-C ¥³¥ó¥Ñ¥¤¥é¤È¥Ó¥ë¥É¥·¥¹¥Æ¥à
    +
    ANSI-C ¥³¥ó¥Ñ¥¤¥é¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ¤ª¤¤¤Æ²¼¤µ¤¤¡£¤ªÁ¦¤á¤Ï Free Software Foundation (FSF) + ¤Ë¤è¤ë GNU C + compiler (GCC) ¤Ç¤¹ (¥Ð¡¼¥¸¥ç¥ó 2.7.2 ¤ÇÂç¾æÉפǤ¹)¡£GCC ¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢ + ¾¯¤Ê¤¯¤È¤âÄ󶡤µ¤ì¤Æ¤¤¤ë¥³¥ó¥Ñ¥¤¥é¤¬ ANSI ½àµò¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤ª¤¤¤Æ²¼¤µ¤¤¡£ + ¤½¤ì¤«¤é¡¢ÊÑ¿ô PATH ¤Ë¤Ï make + ¤È¤¤¤Ã¤¿´ðËÜŪ¤Ê¥Ó¥ë¥É¥Ä¡¼¥ë¤¬´Þ¤Þ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
    + +
    »þ¹ï¤òÀµ³Î¤Ë¤¹¤ë
    +
    HTTP ¥×¥í¥È¥³¥ë¤ÎÍ×ÁǤÏÆü»þ¤Î»þ¹ï¤Çɽ¸½¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ + Àµ³Î¤Ê»þ¹ï¤Ë¥·¥ó¥¯¥í¤µ¤»¤ëµ¡Ç½¤ò¥·¥¹¥Æ¥à¤ËÀßÄꤹ¤ë¤³¤È¤ò¶ãÌ£¤·¤Æ¤ß¤Æ²¼¤µ¤¤¡£ + Network Time Protocol (NTP) ¤ò¥Ù¡¼¥¹¤È¤·¤¿ ntpdate ¤ä xntpd ¥×¥í¥°¥é¥à¤¬ + ¤³¤ÎÌÜŪ¤Ë¤è¤¯ÍѤ¤¤é¤ì¤Þ¤¹¡£NTP ¥½¥Õ¥È¥¦¥§¥¢¤ä¸ø³« NTP + ¥µ¡¼¥Ð¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï¡¢Usenet ¥Ë¥å¡¼¥¹¥°¥ë¡¼¥× comp.protocols.time.ntp ¤ä NTP ¥Û¡¼¥à¥Ú¡¼¥¸ ¤ò¤´Í÷²¼¤µ¤¤¡£
    + +
    Perl 5 + [¥ª¥×¥·¥ç¥ó]
    +
    Ä󶡤µ¤ì¤Æ¤¤¤ë¥¹¥¯¥ê¥×¥È´ö¤Ä¤«¡¢Î㤨¤Ð apxs ¤ä + dbmmanage ¤Ï + Perl ¤Ç½ñ¤«¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢Perl + 5 ¥¤¥ó¥¿¥×¥ê¥¿¤¬É¬Íפˤʤê¤Þ¤¹ (5.003 °Ê¹ß)¡£ + configure ¥¹¥¯¥ê¥×¥È¤Ç¤³¤Î¤è¤¦¤Ê¥¤¥ó¥¿¥×¥ê¥¿¤¬¸«¤Ä¤«¤é¤Ê¤¯¤Æ¤â¡¢ + Ê̤ËÉÔ¶ñ¹ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤â¤Á¤í¤ó¡¢Apache + 2.0 ¤Î¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë¤Ï¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¥µ¥Ý¡¼¥È¥¹¥¯¥ê¥×¥È¤¬»È¤¨¤Ê¤¯¤Ê¤ë¤À¤±¤Ç¤¹¡£ + Perl ¥¤¥ó¥¿¥×¥ê¥¿¤òÊ£¿ô¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ¤¤¤ë¾ì¹ç (¥Ù¥ó¥À¡¼¤Î Perl + 4 ¤È¼«Ê¬¤ÇÆþ¤ì¤¿ Perl 5 ¤¬¤¢¤ë¾ì¹ç¤Ê¤É) ¤Ï¡¢ + --with-perl ¥ª¥×¥·¥ç¥ó (²¼µ­»²¾È) ¤ò»È¤Ã¤Æ configure + ¤¬Å¬Àڤʤâ¤Î¤ò³Î¼Â¤ËÁª¤Ö¤è¤¦¤Ë¤¹¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡£
    +
    +
    top
    +
    +

    ¥À¥¦¥ó¥í¡¼¥É

    + +

    Apache ¤Ï Apache HTTP + ¥µ¡¼¥Ð¥À¥¦¥ó¥í¡¼¥É¥µ¥¤¥È¤«¤é¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Þ¤¹¤·¡¢ + Ʊ¤¸¾ì½ê¤Ë´ö¤Ä¤«¤Î¥ß¥é¡¼¥µ¥¤¥È¤â¥ê¥¹¥È¤·¤Æ¤¤¤Þ¤¹¡£ + UNIX ¤ËÎà»÷¤¹¤ë¥·¥¹¥Æ¥à¤Ç Apache ¤ò»È¤¦¥æ¡¼¥¶¤Ï¡¢¥½¡¼¥¹¤ò + ¥À¥¦¥ó¥í¡¼¥É¤·¤Æ¥Ó¥ë¥É¤·¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ + ¥Ó¥ë¥É¤Î¼ê½ç¡Ê²¼µ­¡Ë¤Ï´Êñ¤Ç¤¹¤·¡¢¤½¤Î¤ª¤«¤²¤Ç¥Ë¡¼¥º¤Ë + ¸«¹ç¤Ã¤¿¥«¥¹¥¿¥Þ¥¤¥º¤ò´Êñ¤Ë¤Ç¤­¤Þ¤¹¡£ + ¤µ¤é¤Ë¡¢¥Ð¥¤¥Ê¥ê¤Î¥ê¥ê¡¼¥¹¤Ï¥½¡¼¥¹¥ê¥ê¡¼¥¹¤è¤ê¤â + ÃÙ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£ + ¤½¤ì¤Ç¤â¥Ð¥¤¥Ê¥ê¤ò¥À¥¦¥ó¥í¡¼¥É¤·¤¿¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥ó¤ÎÃæ¤Ë¤¢¤ë INSSTALL.bindist + ¥Õ¥¡¥¤¥ë¤ÎÀâÌÀ¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥À¥¦¥ó¥í¡¼¥É¸å¡¢¥À¥¦¥ó¥í¡¼¥É¤·¤¿¤â¤Î¤¬ Apache HTTP + ¥µ¡¼¥Ð¤Î´°Á´¤Ç²þã⤵¤ì¤Æ¤¤¤Ê¤¤¥Ð¡¼¥¸¥ç¥ó¤Ç¤¢¤ë¤³¤È¤ò + ¸¡¾Ú¤¹¤ë¤³¤È¤¬½ÅÍפǤ¹¡£¤³¤ì¤Ï¥À¥¦¥ó¥í¡¼¥É¤·¤¿ tarball ¤Î PGP ½ð̾¤ò + ¥Æ¥¹¥È¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¸¡¾Ú¤·¤Þ¤¹¡£ + ¤³¤Î¼ê½ç¤Î¾ÜºÙ¤Ï ¥À¥¦¥ó¥í¡¼¥É + ¥Ú¡¼¥¸ ¤Ë¤¢¤ê¡¢¤µ¤é¤Ë¾Ü¤·¤¤Îã¤Ï PGP ¤Î»ÈÍÑ + ¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    Ÿ³«

    + +

    Apache HTTPD ¤Î tarball + ¤«¤é¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤òŸ³«¤·¤Æ¼è¤ê½Ð¤¹¤È¤Ï¡¢ + ñ¤Ê¤ë°µ½Ì¤Î²ò½ü¤È tar ¤ÎŸ³«¤Ç¤¹:

    + +

    +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +

    + +

    ÇÛÉÛÍѤΥ½¡¼¥¹¥³¡¼¥É¤¬¤¢¤ë¸½ºß¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¡¢ + ¿·¤·¤¤¥Ç¥£¥ì¥¯¥È¥ê¤¬ºî¤é¤ì¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ëÃʳ¬¤Ë¿Ê¤àÁ°¤Ë¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë + cd ¤Ç°ÜÆ°¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥½¡¼¥¹¥Ä¥ê¡¼¤òÀßÄꤹ¤ë

    + +

    ¼¡¤Î¥¹¥Æ¥Ã¥×¤Ï¡¢¤¢¤Ê¤¿¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤È + ¸Ä¿ÍŪ¤ÊÍ×µá¤Ë¹ç¤¦¤è¤¦¤Ë Apache + ¥½¡¼¥¹¥Ä¥ê¡¼¤òÀßÄꤹ¤ë¤³¤È¤Ç¤¹¡£ + ¤³¤ì¤ÏÇÛÉۥǥ£¥ì¥¯¥È¥ê¤Î¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë¡¢ + configure + ¥¹¥¯¥ê¥×¥È¤Ç¹Ô¤Ê¤¤¤Þ¤¹¡£ + (Apache ¥½¡¼¥¹¥Ä¥ê¡¼¤Î CVS + ÈǤò¥À¥¦¥ó¥í¡¼¥É¤·¤¿³«È¯¼Ô¤Ï¡¢¼¡¤Î¥¹¥Æ¥Ã¥×¤Ë¿Ê¤àÁ°¤Ë + autoconf ¤Èlibtool + ¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ buildconf + ¤ò¼Â¹Ô¤¹¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£ + ¸ø¼°¥ê¥ê¡¼¥¹¤Ç¤Ï¤³¤Îºî¶È¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£)

    + +

    ¥Ç¥Õ¥©¥ë¥È¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¥½¡¼¥¹¥Ä¥ê¡¼¤òÁ´¤ÆÀßÄꤹ¤ë + ¤Î¤Ç¤¢¤ì¤Ð¡¢Ã±½ã¤Ë ./configure ¤È¥¿¥¤¥×¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¥Ç¥Õ¥©¥ë¥È¥ª¥×¥·¥ç¥ó¤òÊѹ¹¤Ç¤­¤ë¤è¤¦¤Ë¡¢configure + ¤Ë¤ÏÍÍ¡¹¤ÊÊÑ¿ô¤ä¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤¬ÍÑ°Õ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ºÇ¤â½ÅÍפʥª¥×¥·¥ç¥ó¤Ï¡¢Apache ¤¬¤³¤Î¸å¤Ç¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤ë°ÌÃÖ + --prefix ¤Ç¤¹¡£Apache ¤Ï¡¢¤³¤Î¥¤¥ó¥¹¥È¡¼¥ë°ÌÃÖ¤Ë + ¤ª¤¤¤ÆÀµ¾ï¤ËÆ°ºî¤¹¤ë¤è¤¦¤ËÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤é¤Ç¤¹¡£ + ¤µ¤é¤Ë¾ÜºÙ¤Ê¥Õ¥¡¥¤¥ë°ÌÃÖ¤ÎÀ©¸æ¤ÏÄɲäΠÀßÄꥪ¥×¥·¥ç¥ó + ¤Ç¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î»þÅÀ¤Ç¡¢¥â¥¸¥å¡¼¥ë ¤òÍ­¸ú¤Ë¤·¤¿¤ê + ̵¸ú¤Ë¤·¤¿¤ê¤¹¤ë¤³¤È¤Ç Apache ËÜÂΤ˴ޤޤì¤ë µ¡Ç½ + ¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£Apache ËÜÂΤˤϥǥե©¥ë¥È¤Ç¡¢¥â¥¸¥å¡¼¥ë¤Î Base ¥»¥Ã¥È¤¬ + ´Þ¤Þ¤ì¤Þ¤¹¡£¤½¤Î¾¤Î¥â¥¸¥å¡¼¥ë¤Ï + --enable-module ¥ª¥×¥·¥ç¥ó¤Ç + Í­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤³¤Ç module ¤Ï¥â¥¸¥å¡¼¥ë¤Î̾Á°¤Ç¡¢ + ¤Ä¤Þ¤ê¤½¤ì¤Ï¥â¥¸¥å¡¼¥ë¤Î̾Á°¤«¤é mod_ ʸ»úÎó¤ò¼è¤ê½ü¤¤¤¿¸å¤Ë + ¥¢¥ó¥À¡¼¥¹¥³¥¢¤ò¥À¥Ã¥·¥å¤ÇÃÖ´¹¤·¤¿Ê¸»úÎó¤Ç¤¹¡£ + ¤³¤ì¤È¤ÏÊ̤ÎÊýË¡¤Ç --enable-module=shared + ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¡¢¥â¥¸¥å¡¼¥ë¤ò + ¥·¥§¥¢¡¼¥É¥ª¥Ö¥¸¥§¥¯¥È (DSO) -- ¼Â¹Ô»þ¤Ë¥í¡¼¥É¤·¤¿¤ê + ¥¢¥ó¥í¡¼¥É¤·¤¿¤ê¤Ç¤­¤ë·Á¼° -- ¤È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ƱÍͤˡ¢--disable-module ¥ª¥×¥·¥ç¥ó¤Ç + Base ¥â¥¸¥å¡¼¥ë¤ò̵¸ú²½¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¡¢¤â¤·»ØÄꤷ¤¿¥â¥¸¥å¡¼¥ë¤¬Â¸ºß¤·¤Ê¤¯¤Æ¤â + configure ¤Ï·Ù¹ð¤ò¾å¤²¤ë¤³¤È¤Ê¤¯¡¢Ã±½ã¤Ë¥ª¥×¥·¥ç¥ó¤ò + ̵»ë¤¹¤ë¤³¤È¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¾åµ­¤Ë²Ã¤¨¤Æ¡¢configure ¥¹¥¯¥ê¥×¥È¤Ë¡¢ + ¥³¥ó¥Ñ¥¤¥é¡¢¥é¥¤¥Ö¥é¥ê¡¢¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤òÄɲþðÊó¤È¤·¤ÆÅϤ¹ + ɬÍפ¬¤¢¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¢´Ä¶­ÊÑ¿ô¤¢¤ë¤¤¤Ï + ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤Ç configure ¤ËÅϤ·¤Þ¤¹¡£ + ¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï configure ¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸ + ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£

    + +

    ¤Á¤ç¤Ã¤È¤É¤ó¤Ê¤³¤È¤¬¤Ç¤­¤ë¤«¤ò¸«¤»¤Þ¤·¤ç¤¦¡£ + ¤³¤³¤Çŵ·¿Åª¤ÊÎã¤È¤·¤Æ¡¢/sw/pkg/apache + ¤È¤¤¤¦¥¤¥ó¥¹¥È¡¼¥ë¥Ä¥ê¡¼¤Ç¥³¥ó¥Ñ¥¤¥é¤È¥Õ¥é¥°¤ò»ØÄꤷ¤Æ¡¢ + ¤µ¤é¤ËÆó¤Ä¤ÎÄɲå⥸¥å¡¼¥ë mod_rewrite ¤È + mod_speling ¤ò¸å¤Ç DSO + ¥á¥«¥Ë¥º¥à¤Ç¥í¡¼¥É¤¹¤ë¤è¤¦¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤ß¤Þ¤¹:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    configure ¤ò¼Â¹Ô¤·¤¿¤é¡¢¥·¥¹¥Æ¥à¤Îµ¡Ç½¤ò + ¥Æ¥¹¥È¤·¤¿¤ê¡¢¸å¤Ç¥µ¡¼¥Ð¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤¿¤á¤ËɬÍ×¤Ê Makefile + ¤òÀ¸À®¤·¤¿¤ê¤¹¤ë¤Î¤Ë¿ôʬ´Ö¤«¤«¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ¸Ä¡¹¤Î configure ¥ª¥×¥·¥ç¥ó¤Î¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï + configure ¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸ + ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥Ó¥ë¥É

    + +

    ¤³¤ì¤Ç Apache ¤ÎÍÍ¡¹¤Ê¥Ñ¡¼¥Ä¤ò¥Ó¥ë¥É¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¼¡¤Î¥³¥Þ¥ó¥É¤òñ½ã¤Ë¼Â¹Ô¤¹¤ë¤À¤±¤Ç¤¹:

    + +

    $ make

    + +

    ´ðËÜŪ¤ÊÀßÄê¤ò¤¹¤ë¤Î¤Ë¡¢Pentium III/Linux 2.2 + ¤Î¥·¥¹¥Æ¥à¤Ç¤ª¤ª¤è¤½ 3 ʬÄøÅÙ¤«¤«¤ê¤Þ¤¹¤¬¡¢ + ¤¢¤é¤«¤¸¤á¤´Î»¾µ²¼¤µ¤¤¡£ + ¤Þ¤¿¡¢»þ´Ö¤Ï¥Ï¡¼¥É¥¦¥§¥¢¤äÍ­¸ú¤Ë¤·¤¿¥â¥¸¥å¡¼¥ë¤Î¿ô¤Ë + Â礭¤¯°Í¸¤¹¤ë¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    ¥¤¥ó¥¹¥È¡¼¥ë

    + +

    ¤µ¤Æ¡¢ÀßÄꤷ¤¿¥¤¥ó¥¹¥È¡¼¥ë PREFIX + (Á°½Ò¤Î --prefix ¥ª¥×¥·¥ç¥ó¤ò»²¾È) + °Ê²¼¤Ë¥Ñ¥Ã¥±¡¼¥¸¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ëÃʳ¬¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤:

    + +

    $ make install

    + +

    ¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ë¾ì¹ç¤Ï¡¢¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤ÏÀßÄê¥Õ¥¡¥¤¥ë¤ä + ¥É¥­¥å¥á¥ó¥È¥Õ¥¡¥¤¥ë¤Î¾å½ñ¤­¤Ï¹Ô¤¤¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ¥«¥¹¥¿¥Þ¥¤¥º

    + +

    ¼¡¤Ë PREFIX/conf/ °Ê²¼¤Ë¤¢¤ë ÀßÄê¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ¡¢ + Apache HTTP ¥µ¡¼¥Ð¤ò¥«¥¹¥¿¥Þ¥¤¥º¤·¤Þ¤¹¡£

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    docs/manual/ ¤Î Apache ¥Þ¥Ë¥å¥¢¥ë¤ò¤¶¤Ã¤È¸«¤Æ¤¯¤À¤µ¤¤¡£ + ¤Þ¤¿¤Ï¡¢http://httpd.apache.org/docs-2.1/ + ¤Ë¤¢¤ë¥Þ¥Ë¥å¥¢¥ëºÇ¿·ÈÇ¡¢ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÅö¤¿¤Ã¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥Æ¥¹¥È

    + +

    ¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Æ Apache HTTP ¥µ¡¼¥Ð¤ò³«»Ï¤Ç¤­¤Þ¤¹:

    + +

    $ PREFIX/bin/apachectl start

    + +

    URL http://localhost/ ¤òÄ̤·¤ÆºÇ½é¤Î¥É¥­¥å¥á¥ó¥È¤ËÂФ¹¤ë + ¥ê¥¯¥¨¥¹¥È¤òȯ¹Ô¤¹¤ë»ö¤¬¤Ç¤­¤ë¤Ï¤º¤Ç¤¹¡£¤³¤ì¤Ç¸«¤¨¤ë + ¥¦¥§¥Ö¥Ú¡¼¥¸¤Ï DocumentRoot + °Ê²¼¤ËÃÖ¤«¤ì¤¿¤â¤Î¤Ç¡¢Ä̾ï¤Ï + PREFIX/htdocs/ ¤Ç¤·¤ç¤¦¡£ + ¥µ¡¼¥Ð¤òºÆ¤ÓÄä»ß¤¹¤ë¤Ë¤Ï¡¢ + ¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤¹:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    ¥¢¥Ã¥×¥°¥ì¡¼¥É

    + +

    ¥¢¥Ã¥×¥°¥ì¡¼¥É¤Ç¤Þ¤º¹Ô¤Ê¤¦¤Ù¤­¤³¤È¤Ï¡¢¥ê¥ê¡¼¥¹¥¢¥Ê¥¦¥ó¥¹¤È + ¥½¡¼¥¹¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥ó¤ËÆþ¤Ã¤Æ¤¤¤ë CHANGES ¤òÆɤó¤Ç¡¢ + ¼«¿È¤Î¥µ¥¤¥È¤ËÂФ·¤Æ±Æ¶Á¤òµÚ¤Ü¤¹Êѹ¹ÅÀ¤òõ¤¹¤³¤È¤Ç¤¹¡£ + ¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹´Ö¤ÎÊѹ¹¤ò¤¹¤ë¾ì¹ç (Î㤨¤Ð 1.3 ¤«¤é 2.0 ¤Ø¡¢2.0 ¤«¤é 2.2 ¤Ø) + ¤Ï¡¢¥³¥ó¥Ñ¥¤¥ë»þ¤ä¼Â¹Ô»þ¤ÎÀßÄê¤ËÂ礭¤Êº¹°Û¤¬¤¢¤ë¤Ç¤·¤ç¤¦¤«¤é¡¢ + ¼êÆ°¤ÎÄ´À°¤¬É¬Íפˤʤë¤Ç¤·¤ç¤¦¡£¥â¥¸¥å¡¼¥ë¤âÁ´¤Æ¡¢API + ¤ÎÊѹ¹¤Ë¹ç¤ï¤»¤ë¤¿¤á¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¬É¬Íפˤʤë¤Ç¤·¤ç¤¦¡£

    + +

    ¥Þ¥¤¥Ê¡¼¥Ð¡¼¥¸¥ç¥ó¤«¤é¼¡¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ë¾ì¹ç + (Î㤨¤Ð 2.0.55 ¤«¤é 2.0.57 ¤Ø) ¤Ï¡¢¤â¤Ã¤È´Êñ¤Ç¤¹¡£ + make install ¤ò¼Â¹Ô¤·¤Æ¤âº£¤¢¤ë¥É¥­¥å¥á¥ó¥È¡¢ + ¥í¥°¥Õ¥¡¥¤¥ë¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤Ï¾å½ñ¤­¤µ¤ì¤Þ¤»¤ó¡£ + ¤µ¤é¤Ë¡¢¥Þ¥¤¥Ê¡¼¥Ð¡¼¥¸¥ç¥ó´Ö¤Ç¤Ï configure ¥ª¥×¥·¥ç¥ó¡¢ + ¼Â¹Ô»þ¤ÎÀßÄê¡¢¥â¥¸¥å¡¼¥ë API ¤ËÉÔÀ°¹ç¤¬µ¯¤³¤é¤Ê¤¤¤è¤¦¤Ë¡¢ + ³«È¯¼Ô¤ÏºÇÂç¸Â¤ÎÅØÎϤò¤·¤Æ¤¤¤Þ¤¹¡£ + ÂçÄñ¤Î¾ì¹ç¡¢Æ±°ì¤Î configure ¥³¥Þ¥ó¥É¥é¥¤¥ó¡¢ + Ʊ°ì¤ÎÀßÄê¥Õ¥¡¥¤¥ë¡¢¥â¥¸¥å¡¼¥ëÁ´¤Æ¤¬Àµ¾ï¤ËÆ°ºî¤¹¤ë¤Ï¤º¤Ç¤¹¡£ + (2.0.41 °Ê¹ß¤Ç¤Ï¤½¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤½¤ì°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¤Ï + ÉÔÀ°¹ç¤¬Â¸ºß¤·¤Þ¤¹¡£)

    + +

    Á°²ó¤Î¥¤¥ó¥¹¥È¡¼¥ë»þ¤Î¥½¡¼¥¹¥Ä¥ê¡¼¤¬»Ä¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¥¢¥Ã¥×¥°¥ì¡¼¥É¤Ï¤µ¤é¤Ë´Êñ¤Ç¤¹¡£¸Å¤¤¥½¡¼¥¹¥Ä¥ê¡¼¤Î¥ë¡¼¥È¤Ë¸ºß¤¹¤ë + config.nice ¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢Á°²ó¥½¡¼¥¹¥Ä¥ê¡¼¤òÀßÄꤷ¤¿»þ¤Î + configure ¥³¥Þ¥ó¥É¥é¥¤¥ó¤¬Æþ¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¼¡¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ë¾ì¹ç¤Ï¡¢config.nice + ¥Õ¥¡¥¤¥ë¤ò¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î¥½¡¼¥¹¥Ä¥ê¡¼¤Ë¥³¥Ô¡¼¤·¡¢ + ¤½¤ì¤òÊÔ½¸¤·É¬ÍפÊÊѹ¹¤ò¹Ô¤Ê¤Ã¤Æ¡¢¼¡¤Î¤è¤¦¤Ë¼Â¹Ô¤·¤Þ¤¹¡£

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    ¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï¡¢ + ¼ÂºÝ¤Ë±¿ÍѤò»Ï¤á¤ëÁ°¤Ë¡¢É¬¤º¼«Ê¬ÍѤδĶ­¤Ç¥Æ¥¹¥È¤¹¤Ù¤­¤Ç¤¹¡£ + ºÇ½ªÅª¤Ë¥¢¥Ã¥×¥°¥ì¡¼¥É¤¹¤ëÁ°¤Ë¡¢Èó¸ß´¹À­¤¬¤Ê¤¤¤«¤ò¥Æ¥¹¥È¤¹¤ë¤¿¤á¤Ë¡¢ + Î㤨¤Ð¡¢°Û¤Ê¤ë --prefix ¤È°Û¤Ê¤ë¥Ý¡¼¥È (Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹) + ¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢¸Å¤¤¥Ð¡¼¥¸¥ç¥ó¤Ë±Æ¶Á¤òÍ¿¤¨¤º¤Ë¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤ò + ¥¤¥ó¥¹¥È¡¼¥ë¤·¡¢¼Â¹Ô¤Ç¤­¤Þ¤¹¡£
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.html.ko.euc-kr b/trunk/docs/manual/install.html.ko.euc-kr new file mode 100644 index 0000000000..f3775ce19f --- /dev/null +++ b/trunk/docs/manual/install.html.ko.euc-kr @@ -0,0 +1,360 @@ + + + +ÄÄÆÄÀÏ°ú ¼³Ä¡ - Apache HTTP Server + + + + + +
    <-
    +

    ÄÄÆÄÀÏ°ú ¼³Ä¡

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ÀÌ ¹®¼­´Â À¯´Ð½º¿Í À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ°í + ¼³Ä¡ÇÏ´Â °Í¸¸À» ´Ù·é´Ù. À©µµ¿ìÁî¿¡¼­ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â ¹æ¹ýÀº + ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® À©µµ¿ìÁî¿¡¼­ + ¾ÆÆÄÄ¡ »ç¿ëÀ» Âü°íÇ϶ó. ´Ù¸¥ Ç÷¡Æû¿¡ ´ëÇؼ­´Â Ç÷¡Æû ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÇ ±¸¼º°ú ¼³Ä¡ ȯ°æÀº 1.3°ú ¸Å¿ì ´Ù¸£´Ù. + ¾ÆÆÄÄ¡ 1.3Àº ½¬¿î ¼³Ä¡¸¦ À§ÇØ ÀÚü ½ºÅ©¸³Æ®¸¦ »ç¿ëÇß´Ù. + ¾ÆÆÄÄ¡ 2.0Àº ÀÌÁ¦ ´Ù¸¥ ¿©·¯ ¿ÀǼҽº ÇÁ·ÎÁ§Æ®¿Í ºñ½ÁÇÑ È¯°æÀ» + ¸¸µé±âÀ§ÇØ libtool°ú autoconf¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¸¸¾à ÀÛÀº ¹öÀüÀ» ÇÑ´Ü°è ¾÷±×·¹À̵åÇÑ´Ù¸é (¿¹¸¦ µé¾î, + 2.0.50¿¡¼­ 2.0.51), ¾÷±×·¹À̵å + ÀåÀ¸·Î ¹Ù·Î °¡±æ ¹Ù¶õ´Ù.

    + +
    + +
    top
    +
    +

    ¼º¹Ì ±ÞÇÑ »ç¶÷À» À§ÇÑ °³¿ä

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ´Ù¿î·Îµå$ lynx http://httpd.apache.org/download.cgi +
    ¾ÐÃà Ç®±â$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    ±¸¼º$ ./configure --prefix=PREFIX +
    ÄÄÆÄÀÏ$ make
    ¼³Ä¡$ make install
    ¼³Á¤$ vi PREFIX/conf/httpd.conf
    °Ë»ç$ PREFIX/bin/apachectl start +
    + +

    NNÀº ÇöÀç ÀÛÀº ¹öÀü ¼ýÀÚ·Î, PREFIX´Â + ¼­¹ö°¡ ¼³Ä¡µÉ ÆÄÀϽýºÅÛ °æ·Î·Î ´ëüÇØ¾ß ÇÑ´Ù. PREFIX¸¦ + ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ±âº»°ªÀ¸·Î /usr/local/apache2¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¾Æ·¡´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇϱâÀ§ÇÑ ¿ä±¸»çÇ׺ÎÅÍ + ÄÄÆÄÀÏ°ú ¼³Ä¡ °úÁ¤À» °¢°¢ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.

    +
    top
    +
    +

    ¿ä±¸»çÇ×

    + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâÀ§ÇØ ´ÙÀ½°ú °°Àº °ÍµéÀÌ ÇÊ¿äÇÏ´Ù:

    + +
    +
    µð½ºÅ© °ø°£
    +
    µð½ºÅ© ¿©À¯°ø°£ÀÌ ÃÖ¼Ò 50 MB ÀÌ»óÀÎÁö È®ÀÎÇ϶ó. + ¼³Ä¡ÈÄ ¾ÆÆÄÄ¡´Â ¾à 10 MBÀÇ µð½ºÅ© °ø°£À» Â÷ÁöÇÑ´Ù. + ½ÇÁ¦ ÇÊ¿äÇÑ µð½ºÅ© °ø°£Àº ¼±ÅÃÇÑ ±¸¼º ¿É¼Ç°ú Ãß°¡ ¸ðµâ¿¡ + µû¶ó »ó´çÈ÷ Â÷ÀÌ°¡ ³­´Ù.
    + +
    ANSI-C ÄÄÆÄÀÏ·¯¿Í ÄÄÆÄÀÏ ½Ã½ºÅÛ
    +
    ANSI-C ÄÄÆÄÀÏ·¯°¡ ¼³Ä¡µÇÀÖ´ÂÁö È®ÀÎÇ϶ó. Free Software Foundation (FSF)ÀÇ + GNU C + compiler (GCC)¸¦ ÃßõÇÑ´Ù. (¹öÀü 2.7.2¸é µÈ´Ù.) GCC°¡ + ¾ø´Ù¸é ÃÖ¼ÒÇÑ »ç¿ëÇÏ´Â ÄÄÆÄÀÏ·¯°¡ ANSI ȣȯÀÎÁö È®ÀÎÇ϶ó. + Ãß°¡·Î PATH ȯ°æº¯¼ö´Â make¿Í + °°Àº ±âº»ÀûÀÎ ÄÄÆÄÀÏ µµ±¸¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù.
    + +
    Á¤È®ÇÑ ½Ã°£
    +
    HTTP ÇÁ·ÎÅäÄÝ¿¡´Â ÇÏ·çÁß ½Ã°£À» Ç¥ÇöÇÏ´Â ºÎºÐÀÌ ÀÖ´Ù. ±×·¡¼­ + ÀÌÁ¦ ½Ã½ºÅÛÀÇ ½Ã°£ µ¿±âÈ­ ±â´ÉÀ» »ìÆ캼 ½Ã°£ÀÌ´Ù. º¸Åë + À̸¦ À§ÇØ Network Time Protocol (NTP)¿¡ ±â¹ÝÇÑ + ntpdate³ª xntpd¸¦ »ç¿ëÇÑ´Ù. + NTP ¼ÒÇÁÆ®¿þ¾î¿Í °ø°³ ½Ã°£ ¼­¹ö¿¡ ´ëÇÑ Á¤º¸´Â ´º½º±×·ì + comp.protocols.time.ntp¿Í + NTP ȨÆäÀÌÁö¸¦ + Âü°íÇ϶ó.
    + +
    Perl 5 + [¼±ÅûçÇ×]
    +
    (Perl·Î ¾²¿©Áø) apxs³ª + dbmmanage¿Í °°Àº + Áö¿ø ½ºÅ©¸³Æ®¸¦ À§ÇØ Perl 5 ÀÎÅÍÇÁ¸®ÅÍ°¡ ÇÊ¿äÇÏ´Ù. (¹öÀü + 5.003 ÀÌ»óÀÌ¸é µÈ´Ù.) `configure' ½ºÅ©¸³Æ®°¡ + ÀÌ ÀÎÅÍÇÁ¸®Å͸¦ ãÁö ¸øÇصµ ¹®Á¦¾øÀÌ ¾ÆÆÄÄ¡ 2.0À» + ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ´Ù¸¸ Áö¿ø ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏÁö + ¸øÇÒ »ÓÀÌ´Ù. ¿©·¯ Perl ÀÎÅÍÇÁ¸®ÅÍ°¡ ¼³Ä¡µÇÀÖ´Ù¸é (¾Æ¸¶µµ + »ì¶§ Æ÷ÇÔµÈ Perl 4¿Í Á÷Á¢ ÄÄÆÄÀÏÇÑ Perl 5) + ./configure°¡ ¿Ã¹Ù¸¥ °ÍÀ» ã±âÀ§ÇØ + --with-perl ¿É¼ÇÀ» (¾Æ·¡ Âü°í) »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.
    +
    +
    top
    +
    +

    ´Ù¿î·Îµå

    + +

    ¾ÆÆÄÄ¡´Â ¿©·¯ ¹Ì·¯ ¸ñ·ÏÀÌ ÀÖ´Â ¾ÆÆÄÄ¡ À¥¼­¹ö + ´Ù¿î·Îµå »çÀÌÆ®¿¡¼­ ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º·ù ½Ã½ºÅÛÀ» + »ç¿ëÇÑ´Ù¸é ¼Ò½ºÄڵ带 ´Ù¿î¹Þ¾Æ¼­ ÄÄÆÄÀÏÇÏ´Â ÆíÀÌ ³´´Ù. ½±°Ô + (¾Æ·¡¿¡¼­ ¼³¸í) ÄÄÆÄÀÏÇÒ ¼ö ÀÖ°í, ÀÚ½ÅÀÇ ¿ëµµ¿¡ ¾Ë¸Â°Ô ¼­¹ö¸¦ + ¸ÂÃâ ¼ö ÀÖ´Ù. ¶Ç, ÃֽŠ¹öÀü ¹ÙÀ̳ʸ® ¹èÆ÷º»ÀÌ ¾ø´Â °æ¿ìµµ + ¸¹´Ù. ¹ÙÀ̳ʸ®¸¦ ´Ù¿î¹Þ´Â´Ù¸é ¹èÆ÷º»¿¡ ÀÖ´Â + INSTALL.bindist ÆÄÀÏÀÇ Áö½Ã¸¦ µû¸£¶ó.

    + +

    ´Ù¿î·ÎµåÈÄ ´Ù¿î¹ÞÀº ÆÄÀÏÀÌ ¿ÏÀüÇÏ°í + º¯°æµÇÁö¾ÊÀº ¾ÆÆÄÄ¡ À¥¼­¹öÀÓÀ» È®ÀÎÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù. + PGP ¼­¸íÀ» °¡Áö°í ´Ù¿î·ÎµåÇÑ Å¸º¼(tarball)À» °Ë»çÇÏ¿© È®ÀÎÇÑ´Ù. + ÀÚ¼¼ÇÑ ¹æ¹ýÀº ´Ù¿î·Îµå + ÆäÀÌÁö¿¡ ÀÖ°í, PGP + »ç¿ë¹ýÀ» ¼³¸íÇÏ´Â »ó¼¼ÇÑ ¿¹µµ ÀÖ´Ù.

    + +
    top
    +
    +

    ¾ÐÃà Ç®±â

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö Ÿº¼¿¡¼­ ¼Ò½º¸¦ Ǫ´Â ÀÛ¾÷Àº ´Ü¼øÈ÷ ¾ÐÃà°ú + tar¸¦ Ǫ´Â °ÍÀÌ´Ù:

    + +

    +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +

    + +

    ±×·¯¸é ÇöÀç µð·ºÅ丮 ¾Æ·¡¿¡ ¹èÆ÷º»ÀÇ ¼Ò½ºÄڵ带 ´ãÀº + »õ·Î¿î µð·ºÅ丮°¡ »ý±ä´Ù. ¼­¹ö¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ±× + µð·ºÅ丮·Î cdÇØ¾ß ÇÑ´Ù.

    +
    top
    +
    +

    ¼Ò½º Æ®¸® ±¸¼ºÇϱâ

    + +

    ´ÙÀ½ °úÁ¤Àº ƯÁ¤ Ç÷¡Æû°ú °³ÀÎÀûÀÎ ÇÊ¿ä¿¡ µû¶ó ¾ÆÆÄÄ¡ + ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÏ´Â ÀÏÀÌ´Ù. À̸¦ À§ÇØ ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ µð·ºÅ丮¿¡ + ÀÖ´Â configure + ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ´Ù. (¾ÆÆÄÄ¡ + ¼Ò½º Æ®¸®ÀÇ CVS ¹öÀüÀ» ´Ù¿î·ÎµåÇÑ °³¹ßÀÚ´Â ÀÌ¹Ì + autoconf¿Í libtool°¡ ¼³Ä¡µÇÀÖ°í, + ´ÙÀ½ °úÁ¤À¸·Î ³Ñ¾î°¡±â Àü¿¡ buildconf¸¦ ½ÇÇàÇØ¾ß + ÇÑ´Ù. ÀÌ´Â Á¤½Ä ¹öÀü¿¡¼­´Â ÇÊ¿ä¾ø´Ù.)

    + +

    ¸ðµÎ ±âº» ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÏ·Á¸é °£´ÜÈ÷ + ./configure¸¦ ÀÔ·ÂÇϸéµÈ´Ù. ±âº» ¿É¼ÇÀ» ¼öÁ¤ÇÏ·Á¸é + ./configure¿¡ ¿©·¯ º¯¼ö¿Í ¸í·ÉÇà ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.

    + +

    °¡Àå Áß¿äÇÑ ¿É¼ÇÀº ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î ÀÛµ¿ÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ + ±¸¼ºÇÏ°í ¼³Ä¡ÇÒ Àå¼ÒÀÎ --prefix´Ù. ´Ù¸¥ configure + ¿É¼ÇµéÀ» »ç¿ëÇÏ¿© ÆÄÀÏÀÇ À§Ä¡¸¦ ´õ ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼öµµ + ÀÖ´Ù.

    + +

    ¸ðµâÀ» Æ÷ÇÔÇϰųª »©¼­ ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» + ¼±ÅÃÇÑ´Ù. Base + »óÅÂÀÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î ¾ÆÆÄÄ¡¿¡ Æ÷ÇԵȴÙ. ´Ù¸¥ »óÅÂÀÇ + ¸ðµâÀº --enable-module ¿É¼ÇÀ» »ç¿ëÇÏ¿© + Æ÷ÇÔÇÑ´Ù. ¿©±â¼­ moduleÀº ¸ðµâ À̸§¿¡¼­ + mod_¸¦ »©°í ¹ØÁÙÀ» »©±â±âÈ£·Î º¯°æÇÑ °á°ú´Ù. + --enable-module=shared ¿É¼ÇÀ» »ç¿ëÇϸé + ¸ðµâÀ» ½ÇÇàÁß¿¡ Æ÷ÇÔÇϰųª »¬ ¼ö ÀÖ´Â °øÀ¯°´Ã¼(shared object, DSO)·Î ÄÄÆÄÀÏÇÑ´Ù. + ¶Ç, --disable-module ¿É¼ÇÀ» »ç¿ëÇÏ¿© + Base ¸ðµâÀ» »¬ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ ¸ðµâÀÌ ¾ø¾îµµ + configure°¡ °æ°íÇÏÁö¾Ê°í ±×³É ¹«½ÃÇϱ⶧¹®¿¡ + ¸ðµâ À̸§À» Á¤È®È÷ ÀÔ·ÂÇ϶ó.

    + +

    °¡²û configure ½ºÅ©¸³Æ®¿¡°Ô ÄÄÆÄÀÏ·¯, + ¶óÀ̺귯¸®, Çì´õÆÄÀÏ µîÀÇ À§Ä¡¸¦ ¾Ë·ÁÁà¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. + ÀÌ Á¤º¸´Â ȯ°æº¯¼ö³ª configureÀÇ ¸í·ÉÇà ¿É¼ÇÀ» + »ç¿ëÇÏ¿© Àü´ÞÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº configure manpage¸¦ + Âü°íÇ϶ó.

    + +

    ¿©·¯ºÐÀÌ ¼±ÅÃÇÒ ¼ö ÀÖ´Â °¡´É¼ºÀ» º¸¿©ÁÖ±âÀ§ÇØ ´ÙÀ½Àº + ƯÁ¤ ÄÄÆÄÀÏ·¯¿Í Ç÷¡±×¸¦ »ç¿ëÇÏ°í ³ªÁß¿¡ DSO·Î ÀоîµéÀÏ + µÎ ¸ðµâ mod_rewrite¿Í + mod_spelingÀ» Ãß°¡ÇÏ¿© + /sw/pkg/apache¿¡ ¼³Ä¡ÇÒ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ´Â + ÀüÇüÀûÀÎ ¿¹ÀÌ´Ù:

    + +

    + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +

    + +

    configure¸¦ ½ÇÇàÇÏ¸é ¸îºÐ°£ ½Ã½ºÅÛÀÇ ±â´ÉÀ» + °Ë»çÇÏ¿© ³ªÁß¿¡ ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇÒ MakefileµéÀ» + ¸¸µç´Ù.

    + +

    configure ¿É¼Çµé¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº configure manpage¿¡ ÀÖ´Ù.

    +
    top
    +
    +

    ÄÄÆÄÀÏ

    + +

    ÀÌÁ¦ ´ÙÀ½ ¸í·É¾î Çϳª·Î ¾ÆÆÄÄ¡ÀÇ ¿©·¯ ºÎºÐÀ» ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù:

    + +

    $ make

    + +

    ¿©±â¼­ Á» ±â´Ù·Á¶ó. ÆæƼ¾ö III/¸®´ª½º 2.2 ½Ã½ºÅÛ¿¡¼­ + ±âº» ±¸¼ºÀ» ÄÄÆÄÀÏÇϴµ¥ ¾à 3ºÐ Á¤µµ °É¸°´Ù. ÀÌ ½Ã°£Àº + Çϵå¿þ¾î¿Í Æ÷ÇÔÇÑ ¸ðµâ¼ö¿¡ µû¶ó Å©°Ô º¯ÇÑ´Ù.

    +
    top
    +
    +

    ¼³Ä¡

    + +

    ÀÌÁ¦ ´ÙÀ½ ¸í·É¾î·Î ÆÐÅ°Áö¸¦ (À§ÀÇ --prefix + ¿É¼Ç Âü°í) ÁöÁ¤ÇÑ ¼³Ä¡ À§Ä¡ PREFIX¿¡ ¼³Ä¡ÇÑ´Ù:

    + +

    $ make install

    + +

    ¾÷±×·¹À̵åÇÑ´Ù¸é ÀÌ ¼³Ä¡ °úÁ¤ÀÌ ±âÁ¸ ¼³Á¤ÆÄÀÏÀ̳ª ¹®¼­¸¦ + µ¤¾î¾²Áö ¾Ê´Â´Ù.

    +
    top
    +
    +

    ¼³Á¤

    + +

    ´ÙÀ½À¸·Î PREFIX/conf/¿¡ ÀÖ´Â + ¼³Á¤ÆÄÀÏÀ» ÆíÁýÇÏ¿© ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    $ vi PREFIX/conf/httpd.conf

    + +

    »ç¿ë°¡´ÉÇÑ ¼³Á¤ Áö½Ã¾î¿¡ + ´ëÇÑ ¿ÏÀüÇÑ ¼³¸í°ú ÀÌ ¹®¼­ÀÇ °¡Àå ÃÖ±Ù ÆÇÀº docs/manual/À̳ª http://httpd.apache.org/docs-2.1/¿¡ ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ + Âü°íÇ϶ó.

    +
    top
    +
    +

    °Ë»ç

    + +

    ÀÌÁ¦ ´ÙÀ½°ú °°ÀÌ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ½ÃÀÛÇÒ ¼ö ÀÖ´Ù:

    + +

    $ PREFIX/bin/apachectl start

    + +

    ±×¸®°í URL http://localhost/·Î ù ¹®¼­¸¦ + ¿äûÇÑ´Ù. º¸°ÔµÉ À¥ÆäÀÌÁö´Â ¾Æ¸¶µµ + PREFIX/htdocs/ÀÏ DocumentRoot ¾Æ·¡¿¡ ÀÖ´Ù. ±×¸®°í + ´ÙÀ½ ¸í·É¾î·Î ´Ù½Ã ¼­¹ö¸¦ Áß´ÜÇÑ´Ù:

    + +

    $ PREFIX/bin/apachectl stop

    +
    top
    +
    +

    ¾÷±×·¹À̵å

    + +

    ¾÷±×·¹À̵åÇÑ´Ù¸é ¸ÕÀú »çÀÌÆ®¿¡ ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Â º¯È­°¡ + ÀÖ´ÂÁö ¾Ë¾Æº¸±âÀ§ÇØ ¹ßÇ¥¹®°ú ¼Ò½º ¹èÆ÷º»ÀÇ CHANGES + ÆÄÀÏÀ» Àд´Ù. (¿¹¸¦ µé¾î, 1.3¿¡¼­ 2.0À̳ª 2.0¿¡¼­ 2.2¿Í + °°Àº) Å« ¹öÀüÀÌ º¯ÇÑ °æ¿ì ÄÄÆÄÀÏ ¿É¼Ç°ú ¼³Á¤À» Á÷Á¢ ¼öÁ¤ÇؾßÇÒ + Á¤µµÀÇ Å« º¯È­°¡ ÀÖÀ» °ÍÀÌ´Ù. ¸ðµç ¸ðµâµµ ¸ðµâ APIÀÇ º¯È­¿¡ + ¾Ë¸Â°Ô ¾÷±×·¹À̵åÇØ¾ß ÇÑ´Ù.

    + +

    ÀÛÀº ¹öÀüÀ» ÇÑ´Ü°è ¾÷±×·¹À̵åÇÏ´Â °ÍÀº (¿¹¸¦ µé¾î, + 2.0.55¿¡¼­ 2.0.57) ½±´Ù. make install ÀÛ¾÷Àº + ±âÁ¸ÀÇ ¹®¼­, ·Î±×ÆÄÀÏ, ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö ¾Ê´Â´Ù. ¶Ç, + °³¹ßÀÚ´Â ÀÛÀº ¹öÀü°£¿¡ configure ¿É¼Ç, ¼³Á¤, + ¸ðµâ APIÀÇ È£È¯¼º¾ø´Â º¯È­¸¦ ÃÖ´ëÇÑ ¸·´Â´Ù. ´ëºÎºÐÀÇ °æ¿ì + µ¿ÀÏÇÑ configure ¸í·ÉÇà, µ¿ÀÏÇÑ ¼³Á¤ÆÄÀÏÀ» + »ç¿ëÇÒ ¼ö ÀÖ°í, ¸ðµâµéµµ ¸ðµÎ °è¼Ó µ¿ÀÛÇÒ °ÍÀÌ´Ù. (ÀÌ ¸»Àº + 2.0.41ÀÌÈÄ ¹öÀü¿¡¸¸ ÇØ´çÇÑ´Ù. ÀÌÀü ¹öÀüµé¿¡´Â ȣȯ¼º¾ø´Â + º¯È­°¡ ÀÖ´Ù.)

    + +

    ÀÌÀü¿¡ ¼³Ä¡Çß´ø ¼Ò½º¸¦ °¡Áö°í ÀÖ´Ù¸é, ¾÷±×·¹À̵尡 ´õ + ½¬¿öÁø´Ù. ÀÌÀü ¼Ò½º ÃÖ»óÀ§¿¡ ÀÖ´Â config.nice + ÆÄÀÏ¿¡´Â ¼Ò½º¸¦ ±¸¼ºÇÒ ¶§ »ç¿ëÇß´ø configure + ¸í·ÉÇà ¿É¼ÇÀÌ ±×´ë·Î ÀÖ´Ù. ±×·¡¼­ ´ÙÀ½ ¹öÀüÀ¸·Î ¾÷±×·¹À̵åÇÑ´Ù¸é + »õ·Î¿î ¹öÀü ¼Ò½º·Î config.nice ÆÄÀÏÀ» º¹»çÇÏ°í, + ¿øÇÑ´Ù¸é Á¶±Ý ¼öÁ¤À» ÇÑ ÈÄ, ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù:

    + +

    + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +

    + +
    »õ·Î¿î ¹öÀüÀ» »ç¿ëÇϱâ Àü¿¡ Ç×»ó °Ë»çÇغÁ¾ß + ÇÑ´Ù. ¿¹¸¦ µé¾î, ¾÷±×·¹À̵带 ¸¶Ä¡±â Àü¿¡ ȣȯ¼º ¹®Á¦°¡ + ÀÖ´ÂÁö ¾Ë¾Æº¸±âÀ§ÇØ ´Ù¸¥ --prefix¿Í (Listen Áö½Ã¾î·Î) ´Ù¸¥ Æ÷Æ®¸¦ + »ç¿ëÇÏ¿© »õ·Î¿î ¹öÀüÀ» ¼³Ä¡ÇÑÈÄ ÀÌÀü ¹öÀü°ú °°ÀÌ ½ÇÇàÇغ¼ + ¼ö ÀÖ´Ù.
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + fr  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/install.xml b/trunk/docs/manual/install.xml new file mode 100644 index 0000000000..6541d29386 --- /dev/null +++ b/trunk/docs/manual/install.xml @@ -0,0 +1,382 @@ + + + + + + + + + + Compiling and Installing + + + +

    This document covers compilation and installation of Apache + on Unix and Unix-like systems only. For compiling and + installation on Windows, see Using Apache with Microsoft + Windows. For other platforms, see the platform documentation.

    + +

    Apache 2.0's configuration and installation environment has + changed completely from Apache 1.3. Apache 1.3 used a custom + set of scripts to achieve easy installation. Apache 2.0 now + uses libtool and autoconf + to create an environment that looks like many other Open Source + projects.

    + +

    If you are upgrading from one minor version to the next (for + example, 2.0.50 to 2.0.51), please skip down to the upgrading section.

    + +
    + +Configure the source tree +Starting Apache +Stopping and Restarting + +
    Overview for the + impatient + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Download$ lynx http://httpd.apache.org/download.cgi +
    Extract$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Configure$ ./configure --prefix=PREFIX +
    Compile$ make
    Install$ make install
    Customize$ vi PREFIX/conf/httpd.conf
    Test$ PREFIX/bin/apachectl start +
    + +

    NN must be replaced with the current minor version + number, and PREFIX must be replaced with the + filesystem path under which the server should be installed. If + PREFIX is not specified, it defaults to + /usr/local/apache2.

    + +

    Each section of the compilation and installation process is + described in more detail below, beginning with the requirements + for compiling and installing Apache HTTPD.

    +
    + +
    Requirements + +

    The following requirements exist for building Apache:

    + +
    +
    Disk Space
    +
    Make sure you have at least 50 MB of temporary free disk + space available. After installation Apache occupies + approximately 10 MB of disk space. The actual disk space + requirements will vary considerably based on your chosen + configuration options and any third-party modules.
    + +
    ANSI-C Compiler and Build System
    +
    Make sure you have an ANSI-C compiler installed. The GNU C + compiler (GCC) from the Free Software Foundation (FSF) + is recommended (version 2.7.2 is fine). If you don't have GCC + then at least make sure your vendor's compiler is ANSI + compliant. In addition, your PATH must contain + basic build tools such as make.
    + +
    Accurate time keeping
    +
    Elements of the HTTP protocol are expressed as the time of + day. So, it's time to investigate setting some time + synchronization facility on your system. Usually the + ntpdate or xntpd programs are used for + this purpose which are based on the Network Time Protocol (NTP). + See the Usenet newsgroup comp.protocols.time.ntp + and the NTP + homepage for more details about NTP software and public + time servers.
    + +
    Perl 5 + [OPTIONAL]
    +
    For some of the support scripts like + apxs or dbmmanage (which are + written in Perl) the Perl 5 interpreter is required (versions + 5.003 or newer are sufficient). If no such interpreter is found by + the configure script there is no harm. Of course, you + still can build and install Apache 2.0. Only those support scripts + cannot be used. If you have multiple Perl interpreters + installed (perhaps a Perl 4 from the vendor and a Perl 5 from + your own), then it is recommended to use the --with-perl + option (see below) to make sure the correct one is selected + by configure.
    +
    +
    + +
    Download + +

    Apache can be downloaded from the Apache HTTP Server + download site which lists several mirrors. Most users of + Apache on unix-like systems will be better off downloading and + compiling a source version. The build process (described below) is + easy, and it allows you to customize your server to suit your needs. + In addition, binary releases are often not up to date with the latest + source releases. If you do download a binary, follow the instructions + in the INSTALL.bindist file inside the distribution.

    + +

    After downloading, it is important to verify that you have a + complete and unmodified version of the Apache HTTP Server. This + can be accomplished by testing the downloaded tarball against the + PGP signature. Details on how to do this are available on the download + page and an extended example is available describing the use of + PGP.

    + +
    + +
    Extract + +

    Extracting the source from the Apache HTTPD tarball is a + simple matter of uncompressing, and then untarring:

    + + +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +
    + +

    This will create a new directory under the current directory + containing the source code for the distribution. You should + cd into that directory before proceeding with + compiling the server.

    +
    + +
    Configuring the source tree + +

    The next step is to configure the Apache source tree for your + particular platform and personal requirements. This is done using + the script configure included in + the root directory of the distribution. (Developers downloading + the CVS version of the Apache source tree will need to have + autoconf and libtool installed and will + need to run buildconf before proceeding with the next + steps. This is not necessary for official releases.)

    + +

    To configure the source tree using all the default options, + simply type ./configure. To change the default + options, configure accepts a variety of variables + and command line options.

    + +

    The most important option is the location --prefix + where Apache is to be installed later, because Apache has to be + configured for this location to work correctly. More fine-tuned + control of the location of files is possible with additional configure + options.

    + +

    Also at this point, you can specify which features you + want included in Apache by enabling and disabling modules. Apache comes with a Base set of modules included by + default. Other modules are enabled using the + --enable-module option, where + module is the name of the module with the + mod_ string removed and with any underscore converted + to a dash. You can also choose to compile modules as shared objects (DSOs) -- which can be loaded + or unloaded at runtime -- by using the option + --enable-module=shared. Similarly, you can + disable Base modules with the + --disable-module option. Be careful when + using these options, since configure cannot warn you + if the module you specify does not exist; it will simply ignore the + option.

    + +

    In addition, it is sometimes necessary to provide the + configure script with extra information about the + location of your compiler, libraries, or header files. This is + done by passing either environment variables or command line + options to configure. For more information, see the + configure manual page.

    + +

    For a short impression of what possibilities you have, here + is a typical example which compiles Apache for the installation + tree /sw/pkg/apache with a particular compiler and flags + plus the two additional modules mod_rewrite and + mod_speling for + later loading through the DSO mechanism:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    When configure is run it will take several minutes to + test for the availability of features on your system and build + Makefiles which will later be used to compile the server.

    + +

    Details on all the different configure options are + available on the configure manual page.

    +
    + +
    Build + +

    Now you can build the various parts which form the Apache + package by simply running the command:

    + +$ make + +

    Please be patient here, since a base configuration takes + approximately 3 minutes to compile under a Pentium III/Linux + 2.2 system, but this will vary widely depending on your + hardware and the number of modules which you have enabled.

    +
    + +
    Install + +

    Now it's time to install the package under the configured + installation PREFIX (see --prefix option + above) by running:

    + +$ make install + +

    If you are upgrading, the installation will not overwrite + your configuration files or documents.

    +
    + +
    Customize + +

    Next, you can customize your Apache HTTP server by editing + the configuration files under + PREFIX/conf/.

    + +$ vi PREFIX/conf/httpd.conf + +

    Have a look at the Apache manual under docs/manual/ or consult http://httpd.apache.org/docs-2.1/ for the most recent version of + this manual and a complete reference of available configuration directives.

    +
    + +
    Test + +

    Now you can start your Apache + HTTP server by immediately running:

    + +$ PREFIX/bin/apachectl start + +

    and then you should be able to request your first document + via URL http://localhost/. The web page you see is located + under the DocumentRoot + which will usually be PREFIX/htdocs/. + Then stop the server again by + running:

    + +$ PREFIX/bin/apachectl stop +
    +
    Upgrading + +

    The first step in upgrading is to read the release announcement + and the file CHANGES in the source distribution to + find any changes that may affect your site. When changing between + major releases (for example, from 1.3 to 2.0 or from 2.0 to 2.2), + there will likely be major differences in the compile-time and + run-time configuration that will require manual adjustments. All + modules will also need to be upgraded to accomodate changes in the + module API.

    + +

    Upgrading from one minor version to the next (for example, from + 2.0.55 to 2.0.57) is easier. The make install + process will not overwrite any of your existing documents, log + files, or configuration files. In addition, the developers make + every effort to avoid incompatible changes in the + configure options, run-time configuration, or the + module API between minor versions. In most cases you should be able to + use an identical configure command line, an identical + configuration file, and all of your modules should continue to + work. (This is only valid for versions after 2.0.41; earlier + versions have incompatible changes.)

    + +

    To upgrade across minor versions, start by finding the file + config.nice in the build directory of + your installed server or at the root of the source tree for your + old install. This will contain the exact + configure command line that you used to + configure the source tree. Then to upgrade from one version to + the next, you need only copy the config.nice file to + the source tree of the new version, edit it to make any desired + changes, and then run:

    + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + You should always test any new version in your + environment before putting it into production. For example, you + can install and run the new version along side the old one by + using a different --prefix and a + different port (by adjusting the Listen directive) to test for any + incompatibilities before doing the final upgrade. +
    +
    diff --git a/trunk/docs/manual/install.xml.de b/trunk/docs/manual/install.xml.de new file mode 100644 index 0000000000..03214ecc80 --- /dev/null +++ b/trunk/docs/manual/install.xml.de @@ -0,0 +1,399 @@ + + + + + + + + + + Kompilieren und Installieren + + +

    Dieses Dokument umfaßt nur die Kompilierung und Installation des + Apache auf Unix und Unix-ähnlichen Systemen. Für die + Kompilierung und Installation unter Windows lesen Sie bitte Den Apache unter Microsoft Windows + betreiben. Für andere Plattformen lesen Sie bitte die + Dokumentation Plattformen.

    + +

    Die Konfigurations- und Installationsumgebung des Apache 2.0 hat sich + seit dem Apache 1.3 komplett verändert. Der Apache 1.3 benutzt einen + speziellen Satz von Skripten, um eine einfache Installation zu + ermöglichen. Der Apache 2.0 dagegen verwendet nun + libtool und autoconf, um eine Umgebung zu + schaffen, die der vieler anderer Open Source Projekte ähnlich + sieht.

    + +

    Wenn Sie von einer Unterversion auf die nächste aktualisieren (z.B. + von 2.0.50 auf 2.0.51), springen Sie bitte zum Abschnitt Upgrade.

    +
    + +Den Quellcode konfigurieren +Apache starten +Beenden und Neustarten + +
    Überblick für die Ungeduldigen + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Download$ lynx http://httpd.apache.org/download.cgi +
    Auspacken$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Konfigurieren$ ./configure --prefix=PREFIX +
    Kompilieren$ make
    Installieren$ make install
    Anpassen$ vi PREFIX/conf/httpd.conf
    Testen$ PREFIX/bin/apachectl start +
    + +

    NN muss durch die Nummer der Unterversion ersetzt werden, + und PREFIX durch den Verzeichnispfad, + in dem der Server installiert werden soll. Wenn PREFIX nicht + angegeben ist, wird die Voreinstellung /usr/local/apache2 + verwendet.

    + +

    Beginnend mit den Anforderungen + für die Kompilierung und Installation des Apache HTTPD ist + weiter unten jeder Abschnitt des Kompilierungs- und + Installationsvorganges genauer beschrieben.

    +
    + +
    Anforderungen + +

    Folgende Anforderungen gelten für die Erstellung des + Apache:

    + +
    +
    Plattenplatz
    +
    Stellen Sie sicher, dass Sie kurzzeitig wenigstens 50 MB freien + Festplattenplatz zur Verfügung haben. Nach der Installation + belegt der Apache ungefähr 10 MB Plattenplatz. Der + tatsächliche Platzbedarf variiert in Abhängigkeit von den + gewählten Konfigurationseinstellungen und + Modulen von Drittanbietern.
    + +
    ANSI-C-Compiler und Generierungswerkzeuge
    +
    Stellen Sie sicher, dass Sie einen ANSI-C Compiler installiert + haben. Der GNU C + Compiler (GCC) der Free Software + Foundation (FSF) ist empfehlenswert (Version 2.7.2 ist gut). Wenn + Sie den GCC nicht besitzen, stellen Sie zumindest sicher, dass der + Compiler Ihres Anbieters ANSI-kompatibel ist. Außerdem muss Ihr + PATH wesentliche Generierungswerkzeuge wie + make enthalten.
    + +
    Zeitgenauigkeit bewahren
    +
    Elemente des HTTP-Protokolls werden in Form einer Tageszeit + ausgedrückt. Darum sollten Sie jetzt prüfen, ob Ihr System + die Fähigkeit zur Zeitsynchronisation besitzt, und diese + gegebenenfalls installieren. Üblicherweise werden hierfür + die Programme ntpdate oder xntpd verwendet, + die auf dem Network Time Protocol (NTP) basieren. Nähere + Informationen über NTP Software und öffentliche Zeitserver + finden Sie in der Usenet Newsgroup comp.protocols.time.ntp + und auf der NTP + Homepage.
    + +
    Perl 5 + [OPTIONAL]
    +
    Für einige Hilfsskripte wie apxs + oder dbmmanage (die in Perl + geschrieben sind) wird der Perl 5 Interpreter benötigt (die + Versionen ab 5.003 sind ausreichend). Wenn kein derartiger Interpreter + vom configure-Skript gefunden werden kann, macht das + jedoch nichts. Selbstverständlich können Sie den Apache 2.0 + auch so generieren und installieren. Lediglich diese Pflegeskripte + können dann nicht verwendet werden. Wenn Sie mehrere Perl + Interpreter installiert haben (vielleicht Perl 4 durch Ihren + Händler und Perl 5 durch Sie selbst), dann ist die Verwendung der + --with-perl Option (siehe unten) empfehlenswert, um + sicherzustellen, dass der richtige Interpreter von + configure ausgewählt wird.
    +
    +
    + +
    Download + +

    Der Apache kann von der Apache HTTP Server + Downloadseite heruntergeladen werden, auf der verschiedene Spiegelserver + angegeben sind. Für die meisten Benutzer des Apache ist es auf + Unix-ähnlichen Systemen am Besten, die Quellcodeversion herunterzuladen + und zu kompilieren. Der Erstellungsprozess (weiter unten beschrieben) ist + einfach und erlaubt es Ihnen, den Server Ihren Bedürfnissen anzupassen. + Dazu kommt, dass Binärdistributionen gegenüber der aktuellen + Quellcodeversion oft veraltet sind. Wenn Sie tatsächlich ein + Binärpaket herunterladen, folgen Sie bitte den Anweisungen in der Datei + INSTALL.bindist, die der Distribution beiliegt.

    + +

    Es ist wichtig, dass Sie nach dem Herunterladen überprüfen, + dass es sich um einer vollständige und unveränderte Version des + Apache HTTP Servers handelt. Das können Sie erreichen, indem Sie das + heruntergeladene Paket gegen die PGP-Signatur prüfen. Einzelheiten dazu + erfahren Sie auf der Download-Seite. Es + ist auch ein erweitertes Beispiel verfügbar, dass die Anwendung von PGP + beschreibt.

    + +
    + +
    Auspacken + +

    Das Auspacken des Quellcodes aus dem Apache HTTPD Tarball besteht + aus einem simplen Dekomprimieren und danach "Ent-tarren":

    + + + $ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar +
    + +

    Dies erstellt unterhalb des aktuellen Verzeichnisses ein neues + Verzeichnis, das den Quellcode für die Distribution enthält. + Sie sollten mit cd in dieses Verzeichnis wechseln, + bevor Sie mit der Kompilierung des Servers weitermachen.

    + +
    + +
    Den Codebaum konfigurieren + +

    Der nächste Schritt ist die Konfiguration des + Apache-Codebaumes für Ihre spezielle Plattform und Ihre + persönlichen Bedürfnisse. Dies wird mit dem Skript + configure durchgeführt, das im Wurzelverzeichnis + der Distribution enthalten ist. (Entwickler, welche die CVS Version + des Apache-Codebaumes herunterladen, müssen autoconf + und libtool installiert haben und müssen + buildconf ausführen, bevor sie mit den + nächsten Schritten fortfahren können. Dies wird bei + offiziellen Releases nicht notwendig sein.)

    + +

    Um den Codebaum mit den Standardeinstellungen zu konfigurieren, + geben Sie einfach ./configure ein. Zur Änderung + dieser Voreinstellungen akzeptiert configure eine + Reihe von Variablen und Kommandozeilenoptionen.

    + +

    Die wichtigste Option ist --prefix, der Ablageort, an dem + der Apache später installiert wird, da er für diesen Ort + konfiguriert werden muss, um korrekt zu arbeiten. Eine feinere Einstellung + der Dateiablagen ist mit weiteren configure-Optionen + möglich.

    + +

    Weiterhin können Sie zu diesem Zeitpunkt festlegen, welche Funktionalität Sie + in den Apache aufnehmen möchten, indem Sie Module + aktivieren oder deaktivieren. Der Apache bindet standardmäßig + einen Satz von Basismodulen ein. + Andere Module werden mit Hilfe der Option + --enable-module aktiviert, wobei module + den Namen des Moduls ohne das Präfix mod_ darstellt. + Ausserdem sind alle Unterstriche durch Bindestriche zu ersetzen. Sie + können sich auch entscheiden, Module als "Shared + Objects (DSOs)" zu kompilieren, welche zur Laufzeit ge- und entladen + werden können. Dazu verwenden Sie die Option + --enable-module=shared. Entsprechend können Sie + Basismodule mit der Option --disable-module + deaktivieren. Lassen Sie Vorsicht walten. wenn Sie diese Optionen verwenden, + da configure Sie nicht warnen kann, wenn die von Ihnen + angegebenen Module nicht existieren; die Option wird dann einfach + ignoriert.

    + +

    Zusätzlich ist es zuweilen notwendig, das + configure-Skript mit Extrainformationen zum Ablageort + Ihres Compilers, Ihrer Bibliotheken oder Header-Dateien zu versorgen. Das + tun Sie, indem Sie entweder Umgebungsvariablen oder Kommandozeilenoptionen + an configure übergeben. Für mehr Informationen + lesen Sie bitte die Hilfeseite zu configure.

    + +

    Um einen kurzen Eindruck zu gewinnen, welche Möglichkeiten Sie + haben, folgt hier ein typisches Beispiel, das den Apache mit einem + speziellen Compiler und Compilerflags für das + Installationsverzeichnis /sk/pkg/apache kompiliert, sowie + die beiden zusätzlichen Module mod_rewrite und + mod_speling für späteres Laden durch den + DSO-Mechanismus:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    Wenn configure startet, benötigt es mehrere + Minuten, um die Verfügbarkeit von Features auf Ihrem System zu + prüfen und ein Makefile zu generieren, das später zur + Kompilierung des Servers verwendet wird.

    + +

    Einzelheiten zu den vielen verschiedenen configure + -Optionen finden Sie auf der Hilfeseite zu + configure.

    + +
    + +
    Erstellen + +

    Nun können Sie die verschiedenen Teile, die das Apache-Paket + bilden, einfach durch Ausführen des folgenden Befehls erstellen:

    + + $ make + +

    Seien Sie hierbei bitte geduldig, denn eine Basiskonfiguration + benötigt ungefähr 3 Minuten auf einem Pentium III/Linux 2.2. + System. Dies kann aber abhängig von Ihrer Hardware und der Anzahl + der Module, die Sie aktiviert haben, sehr stark variieren.

    +
    + +
    Installieren + +

    Nun endlich installieren Sie das Package unter dem konfigurierten + Installations-PREFIX (siehe oben: Option --prefix + durch Aufrufen von:

    + + $ make install + +

    Wenn Sie upgraden, wird die Installation Ihre Konfigurationsdateien + oder Dokumente nicht überschrieben.

    +
    + +
    Anpassen + +

    Als nächstes können Sie Ihren Apache HTTP Server anpassen, + indem Sie die Konfigurationsdateien + unterhalb von PREFIX/conf/ editieren.

    + + $ vi PREFIX/conf/httpd.conf + +

    Werfen Sie auch einen Blick in das Apache-Handbuch unter docs/manual/. Die aktuellste Version dieses Handbuchs + sowie eine komplette Referenz der verfügbaren Konfigurationsanweisungen finden + Sie unter http://httpd.apache.org/docs-2.1/.

    +
    + +
    Testen + +

    Sie können nun Ihren Apache HTTP Server starten, indem Sie einfach

    + + $ PREFIX/bin/apachectl start + +

    ausführen.

    + +

    Danach sollten Sie Ihr erstes Dokument unter dem URL + http://localhost/ anfordern können. Die Webseite, + die Sie sehen, ist im DocumentRoot + abgelegt, welches üblicherweise PREFIX/htdocs/ + ist. Den Server stoppen Sie wieder durch + Ausführen von:

    + + $ PREFIX/bin/apachectl stop +
    + +
    Upgrade + +

    Der erste Schritt beim Aktualisieren besteht darin, die + Versionsankündigung sowie die CHANGES-Datei in der + Quelltextdistribution zu lesen, um Änderungen zu finden, die Ihr + System möglicherweise betreffen. Wenn Sie einen größeren + Versionssprung durchführen (z.B. vom 1.3 auf 2.0 oder von 2.0 auf + 2.2), wird es wahrscheinlich auch größere Unterschiede in der + Kompilier- und Laufzeitkonfiguration geben, die manuelle Nacharbeiten + erfordern. Außerdem müssen alle Module aktualisiert + werden, um den Änderungen der Modul-API gerecht zu werden.

    + +

    Die Aktualisierung einer Unterversion auf eine andere (z.B. von 2.0.55 + auf 2.0.57) ist einfacher. make install überschreibt + keine der bereits existierenden Dokumente, Log- und Konfigurationsdateien. + Ausserdem bemühen sich die Entwickler, inkompatible Änderungen + der configure-Optionen, der Laufzeitkonfiguration sowie + der Modul-API zu vermeiden. In den meisten Fällen sollten Sie in der + Lage sein, den gleichen configure-Befehl, die gleiche + Konfiguration und die gleichen Module wieder zu verwenden. (Das gilt erst + seit Version 2.0.41 -- frühere Versionen enthielten noch inkompatible + Änderungen).

    + +

    Wenn Sie den Quellcode von Ihrer letzten Installation aufgehoben haben, + ist ein Upgrade sogar noch einfacher. Die Datei config.nice im + Wurzelverzeichnis des alten Quelltextbaums enthält den genauen + configure-Befehl, der verwendet wurde, um den Quellcode + zu konfigurieren. Um jetzt von einer Version auf die nächste zu + aktualisieren, kopieren Sie einfach die config.nice in das + Verzeichnis der neuen Version, passen sie bei Bedarf an, und + führen Sie sie aus:

    + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + Sie sollten jede neue Version immer in Ihrer Umgebung + testen, bevor Sie sie produktiv schalten. Beispielsweise können Sie + die neue Version neben der alten installieren, indem Sie ein anderes + --prefix und einen anderen Port wählen (durch Anpassen der + Listen-Direktive). So + können Sie auf eventuelle Inkompatibilitäten testen, bevor Sie + endgültig die neue Version verwenden. +
    + +
    diff --git a/trunk/docs/manual/install.xml.es b/trunk/docs/manual/install.xml.es new file mode 100644 index 0000000000..096fda8919 --- /dev/null +++ b/trunk/docs/manual/install.xml.es @@ -0,0 +1,429 @@ + + + + + + + + + + Compilación e Instalación + + + +

    Este documento explica cómo compilar e instalar Apache en + sistemas Unix y tipo Unix. Para obtener información sobre + cómo compilar e instalar en Windows, consulte la sección + Usar Apache en Microsoft + Windows. Para otras plataformas, consulte la + documentación sobre plataformas.

    + +

    El entorno de configuración e instalación de Apache + 2.0 ha cambiado completamente respecto al de Apache 1.3. Apache + 1.3 usaba un conjunto de scripts a medida para conseguir una + instalación fácil. Apache 2.0 usa libtool y + autoconf para crear un entorno más parecido al + de muchos otros proyectos Open Source.

    + +

    Si lo que quiere hacer es actualizar su servidor Apache desde + una versión menor (por ejemplo, desde la 2.0.50 a la 2.0.51), + pase directamente a la sección de actualización.

    + +
    + +Configuración de la +estructura de directorios Iniciar Apache Parar y reiniciar Apache + +
    Visión general del proceso para + impacientes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Descargar$ lynx http://httpd.apache.org/download.cgi +
    Descomprimir$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Ejecutar el script configure$ ./configure --prefix=PREFIX +
    Compilar$ make
    Instalar$ make install
    Personalizar$ vi PREFIX/conf/httpd.conf
    Comprobar que la instalación + funciona$ PREFIX/bin/apachectl start +
    + +

    NN hay que reemplazarlo por el número de la + versión menor, y PREFIX hay que reemplazarlo por la + ruta en la que se va a instalar Apache. Si no especifica + ningún valor en PREFIX, el valor por defecto que se + toma es /usr/local/apache2.

    + +

    Cada parte del proceso de configuración e instalación + se describe detalladamente más abajo, empezando por los + requisitos para compilar e instalar Apache.

    +
    + +
    Requisitos + +

    Estos son los requisitos necesarios para compilar Apache:

    + +
    +
    Espacio en disco
    Compruebe que tiene disponibles al + menos 50 MB de espacio libre en disco. Después de la + instalación, Apache ocupa aproximadamente 10 MB. No + obstante, la necesidad real de espacio en disco varía + considerablemente en función de las opciones de + configuración que elija y de los módulos externos que + use.
    + +
    Compilador ANSI-C y Build System
    Compruebe que + tiene instalado un compilador de ANSI-C. Se recomienda el Compilador GNU C + (GCC) de la Free Software + Foundation (FSF) (con la versión 2.7.2 es + suficiente). Si no tiene instaldo el GCC, entonces compruebe que + el compilador que va a utilizar cumple con los estándares + ANSI. Además, su PATH debe contener la + ubicación donde de encuentran las herramientas básicas + para compilar tales como make.
    + +
    Ajuste exacto del reloj del sistema
    Los elementos + del protocolo HTTP están expresados según la hora del + dia. Por eso, si quiere puede investigar como instalar alguna + utilidad para sincronizar la hora de su sistema. Para esto, + normalmente, se usan los programas ntpdate o + xntpd, que están basados en el protocolo + Network Time Protocol (NTP). Consulte el grupo de noticias comp.protocols.time.ntp + y el sitio web de NTP + para obtener más información sobre NTP y los + servidores públicos de tiempo.
    + +
    Perl 5 [OPCIONAL]
    +
    Para algunos de los scripts de soporte como apxs o dbmmanage (que están + escritos en Perl) es necesario el intérprete de Perl 5 (las + versiones 5.003 o posteriores son suficientes). Si el script + `configure' no encuentra ese intérprete + tampoco pasa nada. Aún puede compilar e instalar Apache + 2.0. Lo único que ocurrirá es que esos scripts de + soporte no podrán ser usados. Si usted tiene varios + interpretes de Perl instalados (quizás Perl 4 porque estaba + ya incluido en su distribución de Linux y Perl 5 porque lo + ha instalado usted), entonces se recomienda usar la opción + --with-perl para asegurarse de que + ./configure usa el intérprete correcto.
    +
    +
    + +
    Descargar + +

    Puede descargar Apache desde la sección de + descargas del sitio web de Apache el cual tiene varios + mirrors. Para la mayoría de los usuarios de Apache que tienen + sistemas tipo Unix, se recomienda que se descarguen y compilen el + código fuente. El proceso de compilación (descrito + más abajo) es fácil, y permite adaptar el servidor + Apache a sus necesidades. Además, las versiones de + disponibles en archivos binarios no están siempre actulizadas + con las últimas modificaciones en el codigo fuente. Si se + descarga un binario, siga las instrucciones contenidas en el + archivo INSTALL.bindist incluido en la + distribución

    + +

    Después de la descarga, es importante que verifique que el + archivo descargado del servidor HTTP Apache está completo y + sin modificaciones. Esto puede hacerlo comparando el archivo + descargado (.tgz) con su firma PGP. Instrucciones detalladas de + cómo hacer esto están disponibles en la + sección de descargas junto con un ejemplo de cómo usar + PGP.

    + +
    + +
    Descomprimir + +

    Extraer el código fuente del archivo .tgz que acabada de + descargar es muy fácil. Ejecute los siguientes comandos:

    + + + $ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar +
    + +

    Estos comandos crearán un nuevo directorio dentro del + directorio en el que se encuentra y que contendrá el + código fuente de la distribución. Debe cambiarse a ese + directorio con cd para proceder a compilar el + servidor Apache.

    + +
    + +
    Configuración de la estructura de +directorios + +

    El siguiente paso es configurar la estructura de directorios + para su plataforma y sus necesidades personales. Esto se hace + usando el script configure incluido en el directorio + raiz de la distribución que acaba de descargar. (Los + desarrolladores que se descarguen la versión del CVS de la + estructura de directorios necesitarán tener instalados + autoconf y libtool, y necesitarán + ejecutar buildconf antes de continuar con los + siguientes pasos. Esto no es preciso para las versiones + oficiales.)

    + +

    Para configurar la estructura de directorios a partir del + código fuente usando las opciones por defecto, solo tiene que + ejecutar ./configure. Para cambiar las opciones por + defecto, configure acepta una serie de variables y + opciones por la línea de comandos.

    + +

    La opción más importante es --prefix que + es el directorio en el que Apache va a ser instalado después, + porque Apache tiene que ser configurado para el directorio que se + especifique para que funcione correctamente. Es posible lograr un + mayor control del lugar donde se van a instalar los ficheros de + Apache con otras opciones de + configuración.

    + +

    En este momento, puede especificar que características + o funcionalidades quiere incluir en Apache activando o + desactivando módulos. Apache viene con + una selección + básica de módulos incluidos por defecto. Se pueden + activar otros módulos usando la opción + --enable-module, donde module + es el nombre del módulo sin el mod_ y + convirtiendo los guiones bajos que tenga en guiones normales. + También puede optar por compilar módulos como objetos dinámicos compartidos (DSOs) -- + que pueden ser activados o desactivados al ejecutar -- usando la + opción --enable-module=shared. De + igual manera, puede desactivar alguno de los módulos que + vienen por defecto en la selección basica con la opción + --disable-module. Tenga cuidado cuando + use estas opciones, porque configure no le + avisará si el módulo que especifica no existe; + simplemente ignorará esa opción.

    + +

    Además, a veces es necesario pasarle al script + configure información adicional sobre donde esta + su compilador, librerias o ficheros de cabecera. Esto se puede + hacer, tanto pasando variables de entorno, como pasandole opciones + a configure a través de la línea de + comandos. Para más información, consulte el Manual del script + configure.

    + +

    Para que se haga una idea sobre las posibilidades que tiene, + aquí tiene un ejemplo típico que configura Apache para + la ruta /sw/pkg/apache con un compilador y unos flags + determinados, y además, con dos módulos adicionales + mod_rewrite y mod_speling para + cargarlos después a través del mecanismo DSO:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    Cuando se ejecuta configure se comprueban que + características o funcionalidades están disponibles en + su sistema y se crean los Makefiles que serán usados luego + para compilar el servidor. Esto tardará algunos minutos.

    + +

    La información sobre todas las opciones de + configure está disponible en el Manual del script + configure.

    + +
    + +
    Compilar + +

    Ahora puede compilar las diferentes partes que forman Apache + simplemente ejecutando el siguiente comando:

    + +$ make + +

    Por favor, tanga un poco de paciencia ahora, porque una + configuración básica tarda aproximadamente 3 minutos en + compilar en un Pentium III con un sistema Linux 2.2, pero este + tiempo puede variar considerablemente en función de su + hardware y del número de módulos que haya + seleccionado.

    +
    + +
    Instalar + +

    Ahora es el momento de instalar el paquete en el diretorio + elegido en PREFIX (consulte la opción + --prefix más arriba) ejecutando:

    + +$ make install + +

    Si usted está solo actualizando una instalación + anterior, la nueva instalación no sobreescribirá sus + ficheros de configuración ni otros documentos.

    +
    + +
    Personalizar + +

    El paso siguiente, es personalizar su servidor Apache editando + los ficheros de configuración + que están en PREFIX/conf/.

    + +$ vi PREFIX/conf/httpd.conf + +

    échele un vistazo al Manual de Apache que está en docs/manual/ o consulte en http://httpd.apache.org/docs-2.1/ la versión más + reciente de este manual y la Guia de Referencia de todas las directivas de configuración + disponibles.

    +
    + +
    Comprobar que la instalación +funciona + +

    Ahora puede iniciar su servidor + Apache cuando quiera ejecutando:

    + +$ PREFIX/bin/apachectl start + +

    y entonces debe poder acceder al documento que tenga + especificado por defecto usando el siguiente URL: + http://localhost/. El documento que verá + estará en DocumentRoot y + casi siempre estará en PREFIX/htdocs/. + Si quiere parar el servidor, puede + hacerlo ejecutando:

    + +$ PREFIX/bin/apachectl stop +
    +
    Actualizar una instalación +prrevia + +

    El primer paso para actualizar una instalación anterior es + leer las especificaciones de la versión y el fichero + CHANGES en la distribución de código fuente + que ha descargado para encontrar los cambios que puedan afectar a + su instalación actual. Cuando el cambio sea entre versiones + mayores (por ejemplo, de la 1.3 a la 2.0 o de la 2.0 a la 2.2), + entonces es más probable que haya diferencias importantes en + la compilación y en la ejecución que necesitarán + ajustes manuales. Todos los módulos necesitarán + también ser actualizados para adaptarse a los cambios en el + interfaz de programación (API) de módulos.

    + +

    La actualización cuando el cambio es entre versiones + menores (por ejemplo, de la 2.0.55 a la 2.0.57) es más + fácil. El proceso make install no + sobreescribirá ninguno de los documentos existentes, archivos + log, o archivos de configuración. Además, los + desarrolladores hacen todos los esfuerzos posibles para evitar + cambios que generen incompatibilidades en las opciones de + configure, en la configuración de la + ejecución o en la interfaz de programación de + módulos. En la mayor parte de los casos debe poder usar un + comando configure idéntico, un fichero de + configuracién idéntico, y todos sus módulos deben + seguir funcionando. (Esto es válido solo para versiones + posteriores a la 2.0.41; las versiones anteriores contienen + cambios incompatibles.)

    + +

    Si va a conservar la estructura de directorios de su anterior + instalación, la actualización es más fácil + incluso. El fichero config.nice que está en el + directorio raiz de la estructura de directorios antigua contiene + exactamente el comando configure que usted usó + para configurar la estructura de directorios de Apache. Entonces, + para actualizar su instalación de una versóon a la + siguinete, solo tiene que copiar el archivo + config.nice a la estructura de directorios del + código fuente de la nueva versión, editarlo, hacer + cualquier cambio que desee, y ejecutarlo :

    + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + Tenga en cuenta que antes de poner una nueva + versión de Apache en producción, debe siempre probarla + antes en su entorno. Por ejemplo, puede instalar y ejecutar la + nueva versión junto con la antigua usando un + --prefix diferente y un puerto diferente (modificando + la directiva Listen) + para comprobar que no existe ninguna incompatibilidad antes de + hacer la actualización definitiva. +
    +
    + diff --git a/trunk/docs/manual/install.xml.fr b/trunk/docs/manual/install.xml.fr new file mode 100644 index 0000000000..7a415c9dde --- /dev/null +++ b/trunk/docs/manual/install.xml.fr @@ -0,0 +1,421 @@ + + + + + + + + + + Compilation et Installation + + + +

    Ce document couvre la compilation et l'installation d'Apache sur les + systèmes Unix et clones d'Unix. Pour la compilation et l'installation sous + Windows, voir Utiliser Apache sous Windows + . Pour les autres plates-formes, voir la documentation des plates-formes.

    + +

    L'environnement de configuration et d'installation d'Apache 2.0 a été + complétement revu par rapport à celui d'Apache 1.3. Apache 1.3 utilisait un + ensemble de scripts pour permettre une installation facile. Apache 2.0 + utilise à présent libtool et autoconf afin de + créer un environnement le plus proche possible d'autres projets + Logiciel Libre.

    + +

    Si vous faite une mise à niveau d'une version mineure à la suivante (par + exemple, de 2.0.50 à 2.0.51), veuillez s'il vous plaît passer directement à + la section Mise à niveau.

    + +
    + +Configurer l'arborescence source +Démarrage d'Apache +Arrêt et Redémarrage + +
    Survol Rapide pour les + impatients + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Télécharger$ lynx http://httpd.apache.org/download.cgi +
    Extraire$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    Configurer$ ./configure --prefix=PREFIX +
    Compiler$ make
    Installer$ make install
    Personnaliser$ vi PREFIX/conf/httpd.conf
    Tester$ PREFIX/bin/apachectl start +
    + +

    NN doit être remplacé par le numéro de version mineure actuel, et + PREFIX par le chemin où le serveur doit être installé. Si + PREFIX n'est pas spécifié, l'installation se fait dans + /usr/local/apache2.

    + +

    Chacune des sections du processus de compilation et d'installation est + décrite ci-après, en commençant par les pré-requis à la compilation et à + l'installation d'Apache HTTPD.

    +
    + +
    Pré-requis + +

    Les pré-requis suivants sont nécessaire pour l'installation d'Apache:

    + +
    +
    Espace Disque
    +
    Au moins 50 Mo d'espace disque temporaire sont nécessaires. Après + installation, Apache occupe environ 10 Mo sur le disque. L'espace disque + occupé par une installation complète dépend beaucoup de la configuration + du serveur, ainsi que de la présence éventuelle de modules tiers.
    + +
    Compilateur C ANSI et Build
    +
    Un compilateur C ANSI doit être utilisé. Le compilateur C GNU + (GCC) de la Free Software Foundation + (FSF) est recommandé (la version 2.7.2 convient). En cas + d'absence de GCC, vérifiez que le compilateur fourni avec l'architecture + utilisée est conforme aux normes ANSI. De plus, les outils de constructions + de base, tel make, doivent être présents dans votre + PATH.
    + +
    S'assurer que la machine est et reste à l'heure
    +
    Certains éléments du protocole HTTP sont exprimés en tant qu'heure de + la journée. Aussi est-il important de s'assurer que le système où Apache + doit tourner dispose de mécanismes de synchronisation temporelle. En + général, les programmes ntpdate ou xntpd sont + utilisés; ces programmes implémentent le Network Time Protocol (NTP). + Voir le groupe Usenet comp.protocols.time.ntp et la page NTP pour plus de détails + sur les logiciels NTP et les serveurs de temps publics.
    + +
    Perl 5 + [FACULTATIF]
    +
    Certains des scripts fournis avec Apache, tel apxs ou dbmmanage (qui sont écrits en + Perl) nécessitent l'interpréteur Perl 5 (version 5.003 ou supérieure). + Au cas où le script configure ne trouve pas d'interpréteur + Perl, la compilation sera quand même réalisée sans souci. Seuls ces + scripts ne seront pas utilisables. Si plusieurs interpréteurs Perl sont + installés (par exemple, Perl 4 fourni avec l'OS, et Perl 5 installé par + l'administrateur), il est conseillé de passer l'option + --with-perl afin de garantir que le bon interpréteur est + utilisé par ./configure.
    +
    +
    + +
    Télécharger + +

    Apache est téléchargeable depuis le site de téléchargement + d'Apache qui fournit la liste de plusieurs miroirs. Là sont disponibles + les dernières versions. La plupart des + utilisateurs d'Apache sur des systèmes de type Unix devraient + probablement télécharger et compiler une version à partir du code source. + Le processus de construction (décrit ci-dessous) est facile et + vous permet d'adapter votre serveur pour convenir à vos besoins. + En outre, les versions binaires ne sont souvent pas à jour avec + les dernières versions du code source. Si vous téléchargez une + version binaire, suivez les instructions dans le dossier + INSTALL.bindist à l'intérieur de la distribution.

    + +

    Après le téléchargement, il est important de vérifier que les sources + téléchargées sont bien complètes et non modifiées, et ce surtout si un + miroir a été utilisé pour le téléchargement. Ceci peut être fait en + testant l'archive tar téléchargée avec la signature PGP. Cette procédure + s'effectue en 2 étapes. D'abord, il faut récupérer le fichier KEYS du site + de distribution d'Apache. (Pour vérifier que ce fichier KEYS + n'a pas été modifié, une bonne idée peut être d'utiliser un fichier d'une + distribution précédente d'Apache ou d'importer les clés d'un serveur de + clés public.) Les clés peuvent être importées dans le keyring de + l'utilisateur au moyen d'une des commandes (selon la version de PGP):

    + +$ pgp < KEYS + +

    ou

    + +$ gpg --import KEYS + +

    La prochaine étape est de tester l'archive tar au moyen de la signature + PGP, qui devrait toujours être disponible sur le site principal d'Apache. + Un lien vers cette signature est placé derrière le lien de téléchargement + correspondant ou peut être trouvé dans le répertoire correspondant sur le site de distribution + d'Apache. Le nom de ce fichier est le même que celui de l'archive + source, avec en plus l'extension .asc. La distribution + téléchargée peut alors être vérifiée au moyen de la commande (à nouveau, + selon la version de PGP):

    + +$ pgp httpd-2_1_NN.tar.gz.asc + +

    ou

    + +$ gpg --verify httpd-2_1_NN.tar.gz.asc + +

    Un message comme celui-ci devrait s'afficher

    + +Good signature from user "Martin Kraemer + <martin@apache.org>". + +

    Selon les relations de confiances contenues dans le keyring de + l'utilisateur, un message peut s'afficher, spécifiant que la relation entre + la clé et le signataire ne peut être vérifiée. Ceci n'est pas un problème si + vous ne mettez pas en doute l'authenticité du fichier KEYS.

    +
    + +
    Extraire + +

    Extraire les sources à partir de l'archive tar est une simple affaire de + décompression et d'extraction tar:

    + + +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +
    + +

    Un nouveau répertoire est créé dans le répertoire courant, il contient le + code source de la distribution. Il faut aller dans ce répertoire au moyen + de la commande cd avant de commencer la compilation du + serveur.

    +
    + +
    Configurer l'arborescence source + +

    L'étape suivante est la configuration de l'arborescence source d'Apache, + pour votre plate-forme et selon les nécessités du site. Cette configuration est + réalisée au moyen du script configure fourni dans le + répertoire racine de la distribution. (Les développeurs qui téléchargent + Apache via CVS devront utiliser les outils autoconf et + libtool avant de passer à la suite. Ceci n'est pas nécessaire + pour les versions officielles.)

    + +

    Pour configurer l'arborescence source en utilisant les options par + défaut, tapez ./configure. Pour modifier les valeurs des + options par défaut, configure accepte un grand nombre de + variables et d'options de ligne de commande.

    + +

    La plus importante de ces options est le chemin du répertoire où + Apache sera installé, + car Apache doit être configuré pour que cet emplacement fonctionne + correctement. Plusieurs autres options sont disponibles pour + le contrôle fin de l'emplacement des fichiers résultants avec options de + configuration.

    + +

    En outre, à ce moment, vous pouvez indiquer quels fonctionnalités + vous voulez inclure dans Apache en ajoutant et/ou en retranchant + des modules. Apache vient avec un ensemble + de modules de Base + inclus par défaut. D'autres modules peuvent être ajoutés en utilisant + l'option --enable-module, où + module est le nom du module avec la chaîne + mod_ coupée et avec les caractères de soulignement + convertis en tirets. Vous pouvez également choisir de compiler + des modules en tant qu'objets partagés (DSOs), + qui peuvent être chargés ou déchargé à l'exécution -- en employant + l'option --enable-module=shared. + De même, vous pouvez retrancher les modules de Base avec l'option + --disable-module. Prenez garde lorsque + vous employez ces options, puisque configure ne peut + vous informer si le module cible n'existe pas; configure + ignorera simplement l'option.

    + +

    Il est parfois nécessaire de fournir des + informations supplémentaires au script + configure sur l'emplacement de vos + compilateur, bibliothèques ou dossiers d'en-tête. Ceci se fait en + passant les variables d'environnement ou des options incluses sur la ligne + de commande à configure. Pour plus d'information + sur ce sujet, consultez la page de documentation + configurer.

    + +

    L'exemple suivant compile Apache pour être installé + dans /sw/pkg/apache avec un + compilateur et des options de compilation particulières, ainsi que les deux + modules mod_rewrite et mod_speling, qui + pourront être chargés plus tard au moyen des mécanismes DSO:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    Une fois lancé, configure peut prendre quelques minutes + pour tester les possibilités du système et produire les fichiers + Makefile qui seront utilisés pour construire le serveur.

    + +

    Les détails de toutes les options configure sont + disponibles sur la page de documentation configurer.

    +
    + +
    Compiler + +

    Les différents composants d'Apache sont à présent prêts à + être compilés, en tapant simplement la commande:

    + +$ make + +

    Un peu de patience est requise, une configuration standard met environ 3 + minutes à compiler sur un Pentium III sous Linux 2.2. Ce temps peut + varier largement suivant le matériel utilisé et les modules + selectionnés.

    +
    + +
    Installer + +

    Il est temps d'installer le 'package' dans le répertoire d'installation + PREFIX configuré auparavant (voir l'option --prefix + ci-dessus) en tapant:

    + +$ make install + +

    En cas de mise à jour, l'installation n'écrasera ni les fichiers de + configuration du serveur, ni ses documents.

    +
    + +
    Personnaliser la Configuration + +

    Il reste à présent à configurer le serveur HTTP Apache, en éditant les + fichiers de configuration placés dans + PREFIX/conf/.

    + +$ vi PREFIX/conf/httpd.conf + +

    A consulter : le manuel d'Apache dans + docs/manual/ ou bien http://httpd.apache.org/docs-2.1/ pour la dernière version de ce + manuel, ainsi qu'une référence complète de toutes les + directives de configuration.

    +
    + +
    Tester + +

    Une fois configuré, le serveur HTTP Apache peut être + démarré en tapant:

    + +$ PREFIX/bin/apachectl start + +

    Vous devriez alors pouvoir tester l'URL http://localhost/. + La page affichée se trouve dans le répertoire + DocumentRoot, habituellement configuré + en tant que PREFIX/htdocs/. + Le serveur peut être arrêté en tapant:

    + +$ PREFIX/bin/apachectl stop +
    + +
    Mise à niveau + +

    La première étape pour une mise à niveau est de lire + l'annonce de la nouvelle version et le fichier CHANGES + dans la distribution afin de trouver tous les changements qui + peuvent affecter votre site. Si la mise à jour est effectuée + entre deux versions principales (par exemple, de 1.3 à 2.0 ou + de 2.0 à 2.2), attendez-vous à des différences majeures + au moment de la compilation et de l'exécution, exigeant probablement + des ajustements manuels. Tous les modules devront également + être mis à niveau pour tenir compte des changements de l'API.

    + +

    La mise à niveau d'une version mineure à une plus récente + (par exemple, de 2.0.55 à 2.0.57) est plus facile. Le processus + make install n'écrasera aucun de vos documents, + fichiers journaux, ou fichiers de configuration existants. + En outre, les développeurs font tous les efforts possibles + pour éviter les changements incompatibles des options + configure, de la configuration d'exécution, + ou de l'API entre les versions mineures. Dans la plupart + des cas vous devriez pouvoir employer une ligne de commande + configure et un fichier de configuration + identiques. De plus, tous vos modules devraient continuer à fonctionner. + (Ceci ne vaut que pour les versions postérieures à 2.0.41; + les versions antérieures ont des changements incompatibles.)

    + +

    Si vous avez gardé l'arborescence source de votre dernière + installation, la mise à niveau est encore plus facile. + Le dossier config.nice dans la racine de l'ancienne + arborescence contient la ligne de commande configure + exacte que vous avez utilisée pour configurer l'arborescence des + sources. Pour faire la mise à niveau d'une version à la suivante, + vous devez copier le dossier config.nice dans + l'arborescence des sources de la nouvelle version, l'éditer + pour faire les changements désirés, puis exécuter:

    + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + Vous devriez toujours essayer une + nouvelle version dans un environnement de test avant de la + mettre dans un environnement de production. Par exemple, vous pouvez + installer et exécuter la nouvelle version côte à côte avec l'ancienne + en employant un --prefix et un port différents + (ce qui est possible en ajustant la directive Listen) + dans le but de tester toutes les incompatibilités possibles avant de + faire la mise à niveau finale. +
    +
    diff --git a/trunk/docs/manual/install.xml.ja b/trunk/docs/manual/install.xml.ja new file mode 100644 index 0000000000..da45c10feb --- /dev/null +++ b/trunk/docs/manual/install.xml.ja @@ -0,0 +1,389 @@ + + + + + + + + + + $B%3%s%Q%$%k$H%$%s%9%H!<%k(B + + + +

    $B$3$NJ8=q$G07$&HO0O$O!"(BUnix $B$d(B Unix $B$KN`;w$7$?%7%9%F%`$G$N(B + Apache $B$N%3%s%Q%$%k$H%$%s%9%H!<%k$G$9!#(B Windows $B$K$*$1$k(B + $B%3%s%Q%$%k$H%$%s%9%H!<%k$K4X$7$F$O!V(BMicrosoft + Windows $B$G(B Apache $B$r;H$&(B$B!W$r$4Mw2<$5$$!#(B + $B$=$NB>$N%W%i%C%H%[!<%`$K4X$7$F$O!V(B$B%W%i%C%H%[!<%`(B$B!W$r$4Mw2<$5$$!#(B

    + +

    Apache 2.0 $B$N@_Dj$H%$%s%9%H!<%k$N4D6-$O!"(BApache 1.3 $B$H$O(B + $B40A4$K0[$J$k$b$N$K$J$j$^$7$?!#4JC1$K%$%s%9%H!<%k$G$-$k$h$&$K!"(B + Apache 1.3 $B$G$OFC@=%9%/%j%W%H$r;H$C$F$$$^$7$?!#(B + Apache 2.0 $B$G$OB>$N(B Open Source $B%W%m%8%'%/%H$HF1MM$N4D6-$K(B + $B$9$k$?$a$K(B libtool $B$H(B autoconf + $B$r;H$&$h$&$K$J$C$F$$$^$9!#(B

    + +

    $B%^%$%J!<%P!<%8%g%s$+$i$=$Nl9g$O!"$^$:(B + $B%"%C%W%0%l!<%I(B$B$r$4Mw2<$5$$!#(B

    + +
    + +$B%=!<%9%D%j!<$N@_Dj(B +Apache$B$N5/F0(B +Apache$B$NDd;_$H:F5/F0(B + +
    $B35MW(B ($B$;$C$+$A$J?M8~$1(B) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%@%&%s%m!<%I(B$ lynx http://httpd.apache.org/download.cgi +
    $BE83+(B$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    $B@_Dj(B$ ./configure --prefix=PREFIX +
    $B%3%s%Q%$%k(B$ make
    $B%$%s%9%H!<%k(B$ make install
    $B%+%9%?%^%$%:(B$ vi PREFIX/conf/httpd.conf
    $B%F%9%H(B$ PREFIX/bin/apachectl start +
    + +

    NN $B$O:G?7$N%^%$%J!<%P!<%8%g%s%J%s%P!<$K!"(B + PREFIX $B$O%$%s%9%H!<%k$9$k%5!<%P$G$N%U%!%$%k%7%9%F%`$N%Q%9$K!"(B + $BCV$-49$($F$/$@$5$$!#(BPREFIX $B$r;XDj$7$J$+$C$?>l9g$O!"(B + $B%G%U%)%k%H$N(B /usr/local/apache2 $B$K$J$j$^$9!#(B

    + +

    Apache HTTPD $B$N%3%s%Q%$%k$H%$%s%9%H!<%k$KI,MW$J$b$N$r$O$8$a$H$7$F!"(B + $BJT=8$H%$%s%9%H!<%k%W%m%;%9$G$N$=$l$>$l$N9`$O(B + $B\$7$/5-=R$5$l$F$$$^$9!#(B

    +
    + +
    $BI,MW$J$b$N(B + +

    Apache $B$N%S%k%I$K$O + +

    +
    $B%G%#%9%/%9%Z!<%9(B
    +
    $B%G%#%9%/$K>/$J$/$H$b(B 50 MB $B$N0l;~E*$J6u$-MFNL$,$"$k$h$&$K(B + $B5$$rIU$1$F$/$@$5$$!#%$%s%9%H!<%k8e$O(B Apache $B$O(B 10 MB $BDxEY$N(B + $B%G%#%9%/%9%Z!<%9$r@j$a$^$9!# + +
    ANSI-C $B%3%s%Q%$%i$H%S%k%I%7%9%F%`(B
    +
    ANSI-C $B%3%s%Q%$%i$r%$%s%9%H!<%k$7$F$*$$$F2<$5$$!#$*A&$a$O(B Free Software Foundation (FSF) + $B$K$h$k(B GNU C + compiler (GCC) $B$G$9(B ($B%P!<%8%g%s(B 2.7.2 $B$GBg>fIW$G$9(B)$B!#(BGCC $B$,$J$$>l9g$O!"(B + $B>/$J$/$H$bDs6!$5$l$F$$$k%3%s%Q%$%i$,(B ANSI $B=`5r$G$"$k$3$H$r3NG'$7$F$*$$$F2<$5$$!#(B + $B$=$l$+$i!"JQ?t(B PATH $B$K$O(B make + $B$H$$$C$?4pK\E*$J%S%k%I%D!<%k$,4^$^$l$F$$$kI,MW$,$"$j$^$9!#(B
    + +
    $B;~9o$r@53N$K$9$k(B
    +
    HTTP $B%W%m%H%3%k$NMWAG$OF|;~$N;~9o$GI=8=$5$l$F$$$^$9!#$G$9$+$i!"(B + $B@53N$J;~9o$K%7%s%/%m$5$;$k5!G=$r%7%9%F%`$K@_Dj$9$k$3$H$r6cL#$7$F$_$F2<$5$$!#(B + Network Time Protocol (NTP) $B$r%Y!<%9$H$7$?(B ntpdate $B$d(B xntpd $B%W%m%0%i%`$,(B + $B$3$NL\E*$K$h$/MQ$$$i$l$^$9!#(BNTP $B%=%U%H%&%'%"$d8x3+(B NTP + $B%5!<%P$K4X$9$k>\:Y$O!"(BUsenet $B%K%e!<%9%0%k!<%W(B comp.protocols.time.ntp $B$d(B NTP $B%[!<%`%Z!<%8(B $B$r$4Mw2<$5$$!#(B
    + +
    Perl 5 + [$B%*%W%7%g%s(B]
    +
    $BDs6!$5$l$F$$$k%9%/%j%W%H4v$D$+!"Nc$($P(B apxs $B$d(B + dbmmanage $B$O(B + Perl $B$G=q$+$l$F$$$k$N$G!"(BPerl + 5 $B%$%s%?%W%j%?$,I,MW$K$J$j$^$9(B (5.003 $B0J9_(B)$B!#(B + configure $B%9%/%j%W%H$G$3$N$h$&$J%$%s%?%W%j%?$,8+$D$+$i$J$/$F$b!"(B + $BJL$KIT6q9g$O$"$j$^$;$s!#$b$A$m$s!"(BApache + 2.0 $B$N%3%s%Q%$%k$H%$%s%9%H!<%k$O$G$-$^$9!#(B + $B$3$l$i$N%5%]!<%H%9%/%j%W%H$,;H$($J$/$J$k$@$1$G$9!#(B + Perl $B%$%s%?%W%j%?$rJ#?t%$%s%9%H!<%k$7$F$$$k>l9g(B ($B%Y%s%@!<$N(B Perl + 4 $B$H<+J,$GF~$l$?(B Perl 5 $B$,$"$k>l9g$J$I(B) $B$O!"(B + --with-perl $B%*%W%7%g%s(B ($B2<5-;2>H(B) $B$r;H$C$F(B configure + $B$,E,@Z$J$b$N$r3N +
    +
    + +
    $B%@%&%s%m!<%I(B + +

    Apache $B$O(B Apache HTTP + $B%5!<%P%@%&%s%m!<%I%5%$%H(B$B$+$i%@%&%s%m!<%I$G$-$^$9$7!"(B + $BF1$8>l=j$K4v$D$+$N%_%i!<%5%$%H$b%j%9%H$7$F$$$^$9!#(B + UNIX $B$KN`;w$9$k%7%9%F%`$G(B Apache $B$r;H$&%f!<%6$O!"%=!<%9$r(B + $B%@%&%s%m!<%I$7$F%S%k%I$7$?$[$&$,NI$$$G$7$g$&!#(B + $B%S%k%I$NINSSTALL.bindist + $B%U%!%$%k$N@bL@$K=>$C$F$/$@$5$$!#(B

    + +

    $B%@%&%s%m!<%I8e!"%@%&%s%m!<%I$7$?$b$N$,(B Apache HTTP + $B%5!<%P$N40A4$G2~cb$5$l$F$$$J$$%P!<%8%g%s$G$"$k$3$H$r(B + $B8!>Z$9$k$3$H$,=EMW$G$9!#$3$l$O%@%&%s%m!<%I$7$?(B tarball $B$N(B PGP $B=pL>$r(B + $B%F%9%H$9$k$3$H$K$h$C$F8!>Z$7$^$9!#(B + $B$3$N\:Y$O(B $B%@%&%s%m!<%I(B + $B%Z!<%8(B $B$K$"$j!"$5$i$K>\$7$$Nc$O(B PGP $B$N;HMQ(B + $B$K5-:\$5$l$F$$$^$9!#(B

    + +
    + +
    $BE83+(B + +

    Apache HTTPD $B$N(B tarball + $B$+$i%=!<%9%U%!%$%k$rE83+$7$F + + +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +
    + +

    $BG[I[MQ$N%=!<%9%3!<%I$,$"$k8=:_$$$k%G%#%l%/%H%j$N2<$K!"(B + $B?7$7$$%G%#%l%/%H%j$,:n$i$l$^$9!#(B + $B%5!<%P$r%3%s%Q%$%k$9$kCJ3,$K?J$`A0$K!"$=$N%G%#%l%/%H%j$K(B + cd $B$G0\F0$7$F$/$@$5$$!#(B

    +
    + +
    $B%=!<%9%D%j!<$r@_Dj$9$k(B + +

    $Bconfigure + $B%9%/%j%W%H$G9T$J$$$^$9!#(B + (Apache $B%=!<%9%D%j!<$N(B CVS + $BHG$r%@%&%s%m!<%I$7$?3+H/autoconf $B$H(Blibtool + $B$r%$%s%9%H!<%k$7$F(B buildconf + $B$r + +

    $B%G%U%)%k%H%*%W%7%g%s$r;H$C$F%=!<%9%D%j!<$rA4$F@_Dj$9$k(B + $B$N$G$"$l$P!"C1=c$K(B ./configure $B$H%?%$%W$7$F$/$@$5$$!#(B + $B%G%U%)%k%H%*%W%7%g%s$rJQ99$G$-$k$h$&$K!"(Bconfigure + $B$K$OMM!9$JJQ?t$d%3%^%s%I%i%$%s%*%W%7%g%s$,MQ0U$5$l$F$$$^$9!#(B

    + +

    $B:G$b=EMW$J%*%W%7%g%s$O!"(BApache $B$,$3$N8e$G%$%s%9%H!<%k$5$l$k0LCV(B + --prefix $B$G$9!#(BApache $B$O!"$3$N%$%s%9%H!<%k0LCV$K(B + $B$*$$$F@5>o$KF0:n$9$k$h$&$K@_Dj$7$J$1$l$P$J$i$J$$$+$i$G$9!#(B + $B$5$i$K>\:Y$J%U%!%$%k0LCV$N@)8f$ODI2C$N(B $B@_Dj%*%W%7%g%s(B + $B$G$G$-$^$9!#(B

    + +

    $B$3$N;~E@$G!"(B$B%b%8%e!<%k(B $B$rM-8z$K$7$?$j(B + $BL58z$K$7$?$j$9$k$3$H$G(B Apache $BK\BN$K4^$^$l$k(B $B5!G=(B + $B$r;XDj$G$-$^$9!#(BApache $BK\BN$K$O%G%U%)%k%H$G!"%b%8%e!<%k$N(B Base $B%;%C%H$,(B + $B4^$^$l$^$9!#$=$NB>$N%b%8%e!<%k$O(B + --enable-module $B%*%W%7%g%s$G(B + $BM-8z$K$J$j$^$9!#$3$3$G(B module $B$O%b%8%e!<%k$NL>A0$G!"(B + $B$D$^$j$=$l$O%b%8%e!<%k$NL>A0$+$i(B mod_ $BJ8;zNs$r--enable-module=shared + $B%*%W%7%g%s$r;H$C$F!"%b%8%e!<%k$r(B + $B%7%'%"!<%I%*%V%8%'%/%H(B (DSO) -- $B--disable-module $B%*%W%7%g%s$G(B + Base $B%b%8%e!<%k$rL58z2=$9$k$3$H$b$G$-$^$9!#(B + $B$3$l$i$N%*%W%7%g%s$r;H$C$F$$$k$H$-$K!"$b$7;XDj$7$?%b%8%e!<%k$,B8:_$7$J$/$F$b(B + configure $B$O7Y9p$r>e$2$k$3$H$J$/!"C1=c$K%*%W%7%g%s$r(B + $BL5;k$9$k$3$H$K5$$r$D$1$F$/$@$5$$!#(B

    + +

    $B>e5-$K2C$($F!"(Bconfigure $B%9%/%j%W%H$K!"(B + $B%3%s%Q%$%i!"%i%$%V%i%j!"%X%C%@%U%!%$%k$N0LCV$rDI2C>pJs$H$7$FEO$9(B + $BI,MW$,$"$k>l9g$,$"$j$^$9!#$3$N$h$&$J>l9g$K$O!"4D6-JQ?t$"$k$$$O(B + $B%3%^%s%I%i%$%s%*%W%7%g%s$G(B configure $B$KEO$7$^$9!#(B + $B>\:Y$K4X$7$F$O(B configure $B%^%K%e%"%k%Z!<%8(B + $B$r$4Mw$/$@$5$$!#(B

    + +

    $B$A$g$C$H$I$s$J$3$H$,$G$-$k$+$r8+$;$^$7$g$&!#(B + $B$3$3$GE57?E*$JNc$H$7$F!"(B/sw/pkg/apache + $B$H$$$&%$%s%9%H!<%k%D%j!<$G%3%s%Q%$%i$H%U%i%0$r;XDj$7$F!"(B + $B$5$i$KFs$D$NDI2C%b%8%e!<%k(B mod_rewrite $B$H(B + mod_speling $B$r8e$G(B DSO + $B%a%+%K%:%`$G%m!<%I$9$k$h$&$K%3%s%Q%$%k$7$F$_$^$9(B:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    configure $B$r + +

    $B8D!9$N(B configure $B%*%W%7%g%s$N>\:Y$K4X$7$F$O(B + configure $B%^%K%e%"%k%Z!<%8(B + $B$r$4Mw$/$@$5$$!#(B

    +
    + +
    $B%S%k%I(B + +

    $B$3$l$G(B Apache $B$NMM!9$J%Q!<%D$r%S%k%I$9$k$3$H$,$G$-$^$9!#(B + $B + +$ make + +

    $B4pK\E*$J@_Dj$r$9$k$N$K!"(BPentium III/Linux 2.2 + $B$N%7%9%F%`$G$*$*$h$=(B 3 $BJ,DxEY$+$+$j$^$9$,!"(B + $B$"$i$+$8$a$4N;>52<$5$$!#(B + $B$^$?!";~4V$O%O!<%I%&%'%"$dM-8z$K$7$?%b%8%e!<%k$N?t$K(B + $BBg$-$/0MB8$9$k$G$7$g$&!#(B

    +
    + +
    $B%$%s%9%H!<%k(B + +

    $B$5$F!"@_Dj$7$?%$%s%9%H!<%k(B PREFIX + ($BA0=R$N(B --prefix $B%*%W%7%g%s$r;2>H(B) + $B0J2<$K%Q%C%1!<%8$r%$%s%9%H!<%k$9$kCJ3,$K$J$j$^$7$?!#(B + $B + +$ make install + +

    $B%"%C%W%0%l!<%I$9$k>l9g$O!"%$%s%9%H!<%k$G$O@_Dj%U%!%$%k$d(B + $B%I%-%e%a%s%H%U%!%$%k$N>e=q$-$O9T$$$^$;$s!#(B

    +
    + +
    $B%+%9%?%^%$%:(B + +

    $BPREFIX/conf/ $B0J2<$K$"$k(B $B@_Dj%U%!%$%k(B$B$rJT=8$7$F!"(B + Apache HTTP $B%5!<%P$r%+%9%?%^%$%:$7$^$9!#(B

    + +$ vi PREFIX/conf/httpd.conf + +

    docs/manual/ $B$N(B Apache $B%^%K%e%"%k$r$6$C$H8+$F$/$@$5$$!#(B + $B$^$?$O!"(Bhttp://httpd.apache.org/docs-2.1/ + $B$K$"$k%^%K%e%"%k:G?7HG!"(B$B@_Dj%G%#%l%/%F%#%V(B$B$KEv$?$C$F$_$F$/$@$5$$!#(B

    +
    + +
    $B%F%9%H(B + +

    $B$B3+;O(B$B$G$-$^$9(B:

    + +$ PREFIX/bin/apachectl start + +

    URL http://localhost/ $B$rDL$7$F:G=i$N%I%-%e%a%s%H$KBP$9$k(B + $B%j%/%(%9%H$rH/9T$9$k;v$,$G$-$k$O$:$G$9!#$3$l$G8+$($k(B + $B%&%'%V%Z!<%8$O(B DocumentRoot + $B0J2<$KCV$+$l$?$b$N$G!"DL>o$O(B + PREFIX/htdocs/ $B$G$7$g$&!#(B + $B%5!<%P$r:F$S(B$BDd;_(B$B$9$k$K$O!"(B + $B + +$ PREFIX/bin/apachectl stop +

    +
    $B%"%C%W%0%l!<%I(B + +

    $B%"%C%W%0%l!<%I$G$^$:9T$J$&$Y$-$3$H$O!"%j%j!<%9%"%J%&%s%9$H(B + $B%=!<%9%G%#%9%H%j%S%e!<%7%g%s$KF~$C$F$$$k(B CHANGES $B$rFI$s$G!"(B + $B<+?H$N%5%$%H$KBP$7$F1F6A$r5Z$\$9JQ99E@$rC5$9$3$H$G$9!#(B + $B%a%8%c!<%j%j!<%94V$NJQ99$r$9$k>l9g(B ($BNc$($P(B 1.3 $B$+$i(B 2.0 $B$X!"(B2.0 $B$+$i(B 2.2 $B$X(B) + $B$O!"%3%s%Q%$%k;~$d + +

    $B%^%$%J!<%P!<%8%g%s$+$il9g(B + ($BNc$($P(B 2.0.55 $B$+$i(B 2.0.57 $B$X(B) $B$O!"$b$C$H4JC1$G$9!#(B + make install $B$re=q$-$5$l$^$;$s!#(B + $B$5$i$K!"%^%$%J!<%P!<%8%g%s4V$G$O(B configure $B%*%W%7%g%s!"(B + $Bl9g!"F10l$N(B configure $B%3%^%s%I%i%$%s!"(B + $BF10l$N@_Dj%U%!%$%k!"%b%8%e!<%kA4$F$,@5>o$KF0:n$9$k$O$:$G$9!#(B + (2.0.41 $B0J9_$G$O$=$N$h$&$K$J$C$F$$$^$9!#$=$l0JA0$N%P!<%8%g%s$K$O(B + $BIT@09g$,B8:_$7$^$9!#(B)

    + +

    $BA02s$N%$%s%9%H!<%k;~$N%=!<%9%D%j!<$,;D$5$l$F$$$k$N$G$"$l$P!"(B + $B%"%C%W%0%l!<%I$O$5$i$K4JC1$G$9!#8E$$%=!<%9%D%j!<$N%k!<%H$KB8:_$9$k(B + config.nice $B%U%!%$%k$K$O!"A02s%=!<%9%D%j!<$r@_Dj$7$?;~$N(B + configure $B%3%^%s%I%i%$%s$,F~$C$F$$$^$9!#(B + $Bl9g$O!"(Bconfig.nice + $B%U%!%$%k$r?7$7$$%P!<%8%g%s$N%=!<%9%D%j!<$K%3%T!<$7!"(B + $B$=$l$rJT=8$7I,MW$JJQ99$r9T$J$C$F!" + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + $B?7$7$$%P!<%8%g%s$r;HMQ$9$k>l9g$O!"(B + $B--prefix $B$H0[$J$k%]!<%H(B (Listen $B%G%#%l%/%F%#%V$G@_Dj$7$^$9(B) + $B$r;HMQ$9$k$3$H$G!"8E$$%P!<%8%g%s$K1F6A$rM?$($:$K?7$7$$%P!<%8%g%s$r(B + $B%$%s%9%H!<%k$7!" +

    +
    diff --git a/trunk/docs/manual/install.xml.ko b/trunk/docs/manual/install.xml.ko new file mode 100644 index 0000000000..219a80a337 --- /dev/null +++ b/trunk/docs/manual/install.xml.ko @@ -0,0 +1,353 @@ + + + + + + + + + + ÄÄÆÄÀÏ°ú ¼³Ä¡ + + + +

    ÀÌ ¹®¼­´Â À¯´Ð½º¿Í À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ°í + ¼³Ä¡ÇÏ´Â °Í¸¸À» ´Ù·é´Ù. À©µµ¿ìÁî¿¡¼­ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â ¹æ¹ýÀº + ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® À©µµ¿ìÁî¿¡¼­ + ¾ÆÆÄÄ¡ »ç¿ëÀ» Âü°íÇ϶ó. ´Ù¸¥ Ç÷¡Æû¿¡ ´ëÇؼ­´Â Ç÷¡Æû ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ 2.0ÀÇ ±¸¼º°ú ¼³Ä¡ ȯ°æÀº 1.3°ú ¸Å¿ì ´Ù¸£´Ù. + ¾ÆÆÄÄ¡ 1.3Àº ½¬¿î ¼³Ä¡¸¦ À§ÇØ ÀÚü ½ºÅ©¸³Æ®¸¦ »ç¿ëÇß´Ù. + ¾ÆÆÄÄ¡ 2.0Àº ÀÌÁ¦ ´Ù¸¥ ¿©·¯ ¿ÀǼҽº ÇÁ·ÎÁ§Æ®¿Í ºñ½ÁÇÑ È¯°æÀ» + ¸¸µé±âÀ§ÇØ libtool°ú autoconf¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¸¸¾à ÀÛÀº ¹öÀüÀ» ÇÑ´Ü°è ¾÷±×·¹À̵åÇÑ´Ù¸é (¿¹¸¦ µé¾î, + 2.0.50¿¡¼­ 2.0.51), ¾÷±×·¹À̵å + ÀåÀ¸·Î ¹Ù·Î °¡±æ ¹Ù¶õ´Ù.

    + +
    + +¼Ò½º Æ®¸® ±¸¼º +¾ÆÆÄÄ¡ ½ÃÀÛ +¾ÆÆÄÄ¡ Áß´Ü°ú Àç½ÃÀÛ + +
    ¼º¹Ì ±ÞÇÑ »ç¶÷À» À§ÇÑ °³¿ä + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ´Ù¿î·Îµå$ lynx http://httpd.apache.org/download.cgi +
    ¾ÐÃà Ç®±â$ gzip -d httpd-2_1_NN.tar.gz
    + $ tar xvf httpd-2_1_NN.tar
    ±¸¼º$ ./configure --prefix=PREFIX +
    ÄÄÆÄÀÏ$ make
    ¼³Ä¡$ make install
    ¼³Á¤$ vi PREFIX/conf/httpd.conf
    °Ë»ç$ PREFIX/bin/apachectl start +
    + +

    NNÀº ÇöÀç ÀÛÀº ¹öÀü ¼ýÀÚ·Î, PREFIX´Â + ¼­¹ö°¡ ¼³Ä¡µÉ ÆÄÀϽýºÅÛ °æ·Î·Î ´ëüÇØ¾ß ÇÑ´Ù. PREFIX¸¦ + ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ±âº»°ªÀ¸·Î /usr/local/apache2¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ¾Æ·¡´Â ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇϱâÀ§ÇÑ ¿ä±¸»çÇ׺ÎÅÍ + ÄÄÆÄÀÏ°ú ¼³Ä¡ °úÁ¤À» °¢°¢ ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.

    +
    + +
    ¿ä±¸»çÇ× + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâÀ§ÇØ ´ÙÀ½°ú °°Àº °ÍµéÀÌ ÇÊ¿äÇÏ´Ù:

    + +
    +
    µð½ºÅ© °ø°£
    +
    µð½ºÅ© ¿©À¯°ø°£ÀÌ ÃÖ¼Ò 50 MB ÀÌ»óÀÎÁö È®ÀÎÇ϶ó. + ¼³Ä¡ÈÄ ¾ÆÆÄÄ¡´Â ¾à 10 MBÀÇ µð½ºÅ© °ø°£À» Â÷ÁöÇÑ´Ù. + ½ÇÁ¦ ÇÊ¿äÇÑ µð½ºÅ© °ø°£Àº ¼±ÅÃÇÑ ±¸¼º ¿É¼Ç°ú Ãß°¡ ¸ðµâ¿¡ + µû¶ó »ó´çÈ÷ Â÷ÀÌ°¡ ³­´Ù.
    + +
    ANSI-C ÄÄÆÄÀÏ·¯¿Í ÄÄÆÄÀÏ ½Ã½ºÅÛ
    +
    ANSI-C ÄÄÆÄÀÏ·¯°¡ ¼³Ä¡µÇÀÖ´ÂÁö È®ÀÎÇ϶ó. Free Software Foundation (FSF)ÀÇ + GNU C + compiler (GCC)¸¦ ÃßõÇÑ´Ù. (¹öÀü 2.7.2¸é µÈ´Ù.) GCC°¡ + ¾ø´Ù¸é ÃÖ¼ÒÇÑ »ç¿ëÇÏ´Â ÄÄÆÄÀÏ·¯°¡ ANSI ȣȯÀÎÁö È®ÀÎÇ϶ó. + Ãß°¡·Î PATH ȯ°æº¯¼ö´Â make¿Í + °°Àº ±âº»ÀûÀÎ ÄÄÆÄÀÏ µµ±¸¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù.
    + +
    Á¤È®ÇÑ ½Ã°£
    +
    HTTP ÇÁ·ÎÅäÄÝ¿¡´Â ÇÏ·çÁß ½Ã°£À» Ç¥ÇöÇÏ´Â ºÎºÐÀÌ ÀÖ´Ù. ±×·¡¼­ + ÀÌÁ¦ ½Ã½ºÅÛÀÇ ½Ã°£ µ¿±âÈ­ ±â´ÉÀ» »ìÆ캼 ½Ã°£ÀÌ´Ù. º¸Åë + À̸¦ À§ÇØ Network Time Protocol (NTP)¿¡ ±â¹ÝÇÑ + ntpdate³ª xntpd¸¦ »ç¿ëÇÑ´Ù. + NTP ¼ÒÇÁÆ®¿þ¾î¿Í °ø°³ ½Ã°£ ¼­¹ö¿¡ ´ëÇÑ Á¤º¸´Â ´º½º±×·ì + comp.protocols.time.ntp¿Í + NTP ȨÆäÀÌÁö¸¦ + Âü°íÇ϶ó.
    + +
    Perl 5 + [¼±ÅûçÇ×]
    +
    (Perl·Î ¾²¿©Áø) apxs³ª + dbmmanage¿Í °°Àº + Áö¿ø ½ºÅ©¸³Æ®¸¦ À§ÇØ Perl 5 ÀÎÅÍÇÁ¸®ÅÍ°¡ ÇÊ¿äÇÏ´Ù. (¹öÀü + 5.003 ÀÌ»óÀÌ¸é µÈ´Ù.) `configure' ½ºÅ©¸³Æ®°¡ + ÀÌ ÀÎÅÍÇÁ¸®Å͸¦ ãÁö ¸øÇصµ ¹®Á¦¾øÀÌ ¾ÆÆÄÄ¡ 2.0À» + ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ´Ù¸¸ Áö¿ø ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏÁö + ¸øÇÒ »ÓÀÌ´Ù. ¿©·¯ Perl ÀÎÅÍÇÁ¸®ÅÍ°¡ ¼³Ä¡µÇÀÖ´Ù¸é (¾Æ¸¶µµ + »ì¶§ Æ÷ÇÔµÈ Perl 4¿Í Á÷Á¢ ÄÄÆÄÀÏÇÑ Perl 5) + ./configure°¡ ¿Ã¹Ù¸¥ °ÍÀ» ã±âÀ§ÇØ + --with-perl ¿É¼ÇÀ» (¾Æ·¡ Âü°í) »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.
    +
    +
    + +
    ´Ù¿î·Îµå + +

    ¾ÆÆÄÄ¡´Â ¿©·¯ ¹Ì·¯ ¸ñ·ÏÀÌ ÀÖ´Â ¾ÆÆÄÄ¡ À¥¼­¹ö + ´Ù¿î·Îµå »çÀÌÆ®¿¡¼­ ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º·ù ½Ã½ºÅÛÀ» + »ç¿ëÇÑ´Ù¸é ¼Ò½ºÄڵ带 ´Ù¿î¹Þ¾Æ¼­ ÄÄÆÄÀÏÇÏ´Â ÆíÀÌ ³´´Ù. ½±°Ô + (¾Æ·¡¿¡¼­ ¼³¸í) ÄÄÆÄÀÏÇÒ ¼ö ÀÖ°í, ÀÚ½ÅÀÇ ¿ëµµ¿¡ ¾Ë¸Â°Ô ¼­¹ö¸¦ + ¸ÂÃâ ¼ö ÀÖ´Ù. ¶Ç, ÃֽŠ¹öÀü ¹ÙÀ̳ʸ® ¹èÆ÷º»ÀÌ ¾ø´Â °æ¿ìµµ + ¸¹´Ù. ¹ÙÀ̳ʸ®¸¦ ´Ù¿î¹Þ´Â´Ù¸é ¹èÆ÷º»¿¡ ÀÖ´Â + INSTALL.bindist ÆÄÀÏÀÇ Áö½Ã¸¦ µû¸£¶ó.

    + +

    ´Ù¿î·ÎµåÈÄ ´Ù¿î¹ÞÀº ÆÄÀÏÀÌ ¿ÏÀüÇÏ°í + º¯°æµÇÁö¾ÊÀº ¾ÆÆÄÄ¡ À¥¼­¹öÀÓÀ» È®ÀÎÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù. + PGP ¼­¸íÀ» °¡Áö°í ´Ù¿î·ÎµåÇÑ Å¸º¼(tarball)À» °Ë»çÇÏ¿© È®ÀÎÇÑ´Ù. + ÀÚ¼¼ÇÑ ¹æ¹ýÀº ´Ù¿î·Îµå + ÆäÀÌÁö¿¡ ÀÖ°í, PGP + »ç¿ë¹ýÀ» ¼³¸íÇÏ´Â »ó¼¼ÇÑ ¿¹µµ ÀÖ´Ù.

    + +
    + +
    ¾ÐÃà Ç®±â + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö Ÿº¼¿¡¼­ ¼Ò½º¸¦ Ǫ´Â ÀÛ¾÷Àº ´Ü¼øÈ÷ ¾ÐÃà°ú + tar¸¦ Ǫ´Â °ÍÀÌ´Ù:

    + + +$ gzip -d httpd-2_1_NN.tar.gz
    +$ tar xvf httpd-2_1_NN.tar +
    + +

    ±×·¯¸é ÇöÀç µð·ºÅ丮 ¾Æ·¡¿¡ ¹èÆ÷º»ÀÇ ¼Ò½ºÄڵ带 ´ãÀº + »õ·Î¿î µð·ºÅ丮°¡ »ý±ä´Ù. ¼­¹ö¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ±× + µð·ºÅ丮·Î cdÇØ¾ß ÇÑ´Ù.

    +
    + +
    ¼Ò½º Æ®¸® ±¸¼ºÇϱâ + +

    ´ÙÀ½ °úÁ¤Àº ƯÁ¤ Ç÷¡Æû°ú °³ÀÎÀûÀÎ ÇÊ¿ä¿¡ µû¶ó ¾ÆÆÄÄ¡ + ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÏ´Â ÀÏÀÌ´Ù. À̸¦ À§ÇØ ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ µð·ºÅ丮¿¡ + ÀÖ´Â configure + ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ´Ù. (¾ÆÆÄÄ¡ + ¼Ò½º Æ®¸®ÀÇ CVS ¹öÀüÀ» ´Ù¿î·ÎµåÇÑ °³¹ßÀÚ´Â ÀÌ¹Ì + autoconf¿Í libtool°¡ ¼³Ä¡µÇÀÖ°í, + ´ÙÀ½ °úÁ¤À¸·Î ³Ñ¾î°¡±â Àü¿¡ buildconf¸¦ ½ÇÇàÇØ¾ß + ÇÑ´Ù. ÀÌ´Â Á¤½Ä ¹öÀü¿¡¼­´Â ÇÊ¿ä¾ø´Ù.)

    + +

    ¸ðµÎ ±âº» ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÏ·Á¸é °£´ÜÈ÷ + ./configure¸¦ ÀÔ·ÂÇϸéµÈ´Ù. ±âº» ¿É¼ÇÀ» ¼öÁ¤ÇÏ·Á¸é + ./configure¿¡ ¿©·¯ º¯¼ö¿Í ¸í·ÉÇà ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.

    + +

    °¡Àå Áß¿äÇÑ ¿É¼ÇÀº ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î ÀÛµ¿ÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ + ±¸¼ºÇÏ°í ¼³Ä¡ÇÒ Àå¼ÒÀÎ --prefix´Ù. ´Ù¸¥ configure + ¿É¼ÇµéÀ» »ç¿ëÇÏ¿© ÆÄÀÏÀÇ À§Ä¡¸¦ ´õ ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼öµµ + ÀÖ´Ù.

    + +

    ¸ðµâÀ» Æ÷ÇÔÇϰųª »©¼­ ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» + ¼±ÅÃÇÑ´Ù. Base + »óÅÂÀÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î ¾ÆÆÄÄ¡¿¡ Æ÷ÇԵȴÙ. ´Ù¸¥ »óÅÂÀÇ + ¸ðµâÀº --enable-module ¿É¼ÇÀ» »ç¿ëÇÏ¿© + Æ÷ÇÔÇÑ´Ù. ¿©±â¼­ moduleÀº ¸ðµâ À̸§¿¡¼­ + mod_¸¦ »©°í ¹ØÁÙÀ» »©±â±âÈ£·Î º¯°æÇÑ °á°ú´Ù. + --enable-module=shared ¿É¼ÇÀ» »ç¿ëÇϸé + ¸ðµâÀ» ½ÇÇàÁß¿¡ Æ÷ÇÔÇϰųª »¬ ¼ö ÀÖ´Â °øÀ¯°´Ã¼(shared object, DSO)·Î ÄÄÆÄÀÏÇÑ´Ù. + ¶Ç, --disable-module ¿É¼ÇÀ» »ç¿ëÇÏ¿© + Base ¸ðµâÀ» »¬ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ ¸ðµâÀÌ ¾ø¾îµµ + configure°¡ °æ°íÇÏÁö¾Ê°í ±×³É ¹«½ÃÇϱ⶧¹®¿¡ + ¸ðµâ À̸§À» Á¤È®È÷ ÀÔ·ÂÇ϶ó.

    + +

    °¡²û configure ½ºÅ©¸³Æ®¿¡°Ô ÄÄÆÄÀÏ·¯, + ¶óÀ̺귯¸®, Çì´õÆÄÀÏ µîÀÇ À§Ä¡¸¦ ¾Ë·ÁÁà¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. + ÀÌ Á¤º¸´Â ȯ°æº¯¼ö³ª configureÀÇ ¸í·ÉÇà ¿É¼ÇÀ» + »ç¿ëÇÏ¿© Àü´ÞÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº configure manpage¸¦ + Âü°íÇ϶ó.

    + +

    ¿©·¯ºÐÀÌ ¼±ÅÃÇÒ ¼ö ÀÖ´Â °¡´É¼ºÀ» º¸¿©ÁÖ±âÀ§ÇØ ´ÙÀ½Àº + ƯÁ¤ ÄÄÆÄÀÏ·¯¿Í Ç÷¡±×¸¦ »ç¿ëÇÏ°í ³ªÁß¿¡ DSO·Î ÀоîµéÀÏ + µÎ ¸ðµâ mod_rewrite¿Í + mod_spelingÀ» Ãß°¡ÇÏ¿© + /sw/pkg/apache¿¡ ¼³Ä¡ÇÒ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ´Â + ÀüÇüÀûÀÎ ¿¹ÀÌ´Ù:

    + + + $ CC="pgcc" CFLAGS="-O2" \
    + ./configure --prefix=/sw/pkg/apache \
    + --enable-rewrite=shared \
    + --enable-speling=shared +
    + +

    configure¸¦ ½ÇÇàÇÏ¸é ¸îºÐ°£ ½Ã½ºÅÛÀÇ ±â´ÉÀ» + °Ë»çÇÏ¿© ³ªÁß¿¡ ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇÒ MakefileµéÀ» + ¸¸µç´Ù.

    + +

    configure ¿É¼Çµé¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº configure manpage¿¡ ÀÖ´Ù.

    +
    + +
    ÄÄÆÄÀÏ + +

    ÀÌÁ¦ ´ÙÀ½ ¸í·É¾î Çϳª·Î ¾ÆÆÄÄ¡ÀÇ ¿©·¯ ºÎºÐÀ» ÄÄÆÄÀÏÇÒ + ¼ö ÀÖ´Ù:

    + +$ make + +

    ¿©±â¼­ Á» ±â´Ù·Á¶ó. ÆæƼ¾ö III/¸®´ª½º 2.2 ½Ã½ºÅÛ¿¡¼­ + ±âº» ±¸¼ºÀ» ÄÄÆÄÀÏÇϴµ¥ ¾à 3ºÐ Á¤µµ °É¸°´Ù. ÀÌ ½Ã°£Àº + Çϵå¿þ¾î¿Í Æ÷ÇÔÇÑ ¸ðµâ¼ö¿¡ µû¶ó Å©°Ô º¯ÇÑ´Ù.

    +
    + +
    ¼³Ä¡ + +

    ÀÌÁ¦ ´ÙÀ½ ¸í·É¾î·Î ÆÐÅ°Áö¸¦ (À§ÀÇ --prefix + ¿É¼Ç Âü°í) ÁöÁ¤ÇÑ ¼³Ä¡ À§Ä¡ PREFIX¿¡ ¼³Ä¡ÇÑ´Ù:

    + +$ make install + +

    ¾÷±×·¹À̵åÇÑ´Ù¸é ÀÌ ¼³Ä¡ °úÁ¤ÀÌ ±âÁ¸ ¼³Á¤ÆÄÀÏÀ̳ª ¹®¼­¸¦ + µ¤¾î¾²Áö ¾Ê´Â´Ù.

    +
    + +
    ¼³Á¤ + +

    ´ÙÀ½À¸·Î PREFIX/conf/¿¡ ÀÖ´Â + ¼³Á¤ÆÄÀÏÀ» ÆíÁýÇÏ¿© ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +$ vi PREFIX/conf/httpd.conf + +

    »ç¿ë°¡´ÉÇÑ ¼³Á¤ Áö½Ã¾î¿¡ + ´ëÇÑ ¿ÏÀüÇÑ ¼³¸í°ú ÀÌ ¹®¼­ÀÇ °¡Àå ÃÖ±Ù ÆÇÀº docs/manual/À̳ª http://httpd.apache.org/docs-2.1/¿¡ ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ + Âü°íÇ϶ó.

    +
    + +
    °Ë»ç + +

    ÀÌÁ¦ ´ÙÀ½°ú °°ÀÌ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ½ÃÀÛÇÒ ¼ö ÀÖ´Ù:

    + +$ PREFIX/bin/apachectl start + +

    ±×¸®°í URL http://localhost/·Î ù ¹®¼­¸¦ + ¿äûÇÑ´Ù. º¸°ÔµÉ À¥ÆäÀÌÁö´Â ¾Æ¸¶µµ + PREFIX/htdocs/ÀÏ DocumentRoot ¾Æ·¡¿¡ ÀÖ´Ù. ±×¸®°í + ´ÙÀ½ ¸í·É¾î·Î ´Ù½Ã ¼­¹ö¸¦ Áß´ÜÇÑ´Ù:

    + +$ PREFIX/bin/apachectl stop +
    +
    ¾÷±×·¹À̵å + +

    ¾÷±×·¹À̵åÇÑ´Ù¸é ¸ÕÀú »çÀÌÆ®¿¡ ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Â º¯È­°¡ + ÀÖ´ÂÁö ¾Ë¾Æº¸±âÀ§ÇØ ¹ßÇ¥¹®°ú ¼Ò½º ¹èÆ÷º»ÀÇ CHANGES + ÆÄÀÏÀ» Àд´Ù. (¿¹¸¦ µé¾î, 1.3¿¡¼­ 2.0À̳ª 2.0¿¡¼­ 2.2¿Í + °°Àº) Å« ¹öÀüÀÌ º¯ÇÑ °æ¿ì ÄÄÆÄÀÏ ¿É¼Ç°ú ¼³Á¤À» Á÷Á¢ ¼öÁ¤ÇؾßÇÒ + Á¤µµÀÇ Å« º¯È­°¡ ÀÖÀ» °ÍÀÌ´Ù. ¸ðµç ¸ðµâµµ ¸ðµâ APIÀÇ º¯È­¿¡ + ¾Ë¸Â°Ô ¾÷±×·¹À̵åÇØ¾ß ÇÑ´Ù.

    + +

    ÀÛÀº ¹öÀüÀ» ÇÑ´Ü°è ¾÷±×·¹À̵åÇÏ´Â °ÍÀº (¿¹¸¦ µé¾î, + 2.0.55¿¡¼­ 2.0.57) ½±´Ù. make install ÀÛ¾÷Àº + ±âÁ¸ÀÇ ¹®¼­, ·Î±×ÆÄÀÏ, ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö ¾Ê´Â´Ù. ¶Ç, + °³¹ßÀÚ´Â ÀÛÀº ¹öÀü°£¿¡ configure ¿É¼Ç, ¼³Á¤, + ¸ðµâ APIÀÇ È£È¯¼º¾ø´Â º¯È­¸¦ ÃÖ´ëÇÑ ¸·´Â´Ù. ´ëºÎºÐÀÇ °æ¿ì + µ¿ÀÏÇÑ configure ¸í·ÉÇà, µ¿ÀÏÇÑ ¼³Á¤ÆÄÀÏÀ» + »ç¿ëÇÒ ¼ö ÀÖ°í, ¸ðµâµéµµ ¸ðµÎ °è¼Ó µ¿ÀÛÇÒ °ÍÀÌ´Ù. (ÀÌ ¸»Àº + 2.0.41ÀÌÈÄ ¹öÀü¿¡¸¸ ÇØ´çÇÑ´Ù. ÀÌÀü ¹öÀüµé¿¡´Â ȣȯ¼º¾ø´Â + º¯È­°¡ ÀÖ´Ù.)

    + +

    ÀÌÀü¿¡ ¼³Ä¡Çß´ø ¼Ò½º¸¦ °¡Áö°í ÀÖ´Ù¸é, ¾÷±×·¹À̵尡 ´õ + ½¬¿öÁø´Ù. ÀÌÀü ¼Ò½º ÃÖ»óÀ§¿¡ ÀÖ´Â config.nice + ÆÄÀÏ¿¡´Â ¼Ò½º¸¦ ±¸¼ºÇÒ ¶§ »ç¿ëÇß´ø configure + ¸í·ÉÇà ¿É¼ÇÀÌ ±×´ë·Î ÀÖ´Ù. ±×·¡¼­ ´ÙÀ½ ¹öÀüÀ¸·Î ¾÷±×·¹À̵åÇÑ´Ù¸é + »õ·Î¿î ¹öÀü ¼Ò½º·Î config.nice ÆÄÀÏÀ» º¹»çÇÏ°í, + ¿øÇÑ´Ù¸é Á¶±Ý ¼öÁ¤À» ÇÑ ÈÄ, ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù:

    + + + $ ./config.nice
    + $ make
    + $ make install
    + $ PREFIX/bin/apachectl stop
    + $ PREFIX/bin/apachectl start
    +
    + + »õ·Î¿î ¹öÀüÀ» »ç¿ëÇϱâ Àü¿¡ Ç×»ó °Ë»çÇغÁ¾ß + ÇÑ´Ù. ¿¹¸¦ µé¾î, ¾÷±×·¹À̵带 ¸¶Ä¡±â Àü¿¡ ȣȯ¼º ¹®Á¦°¡ + ÀÖ´ÂÁö ¾Ë¾Æº¸±âÀ§ÇØ ´Ù¸¥ --prefix¿Í (Listen Áö½Ã¾î·Î) ´Ù¸¥ Æ÷Æ®¸¦ + »ç¿ëÇÏ¿© »õ·Î¿î ¹öÀüÀ» ¼³Ä¡ÇÑÈÄ ÀÌÀü ¹öÀü°ú °°ÀÌ ½ÇÇàÇغ¼ + ¼ö ÀÖ´Ù. +
    +
    diff --git a/trunk/docs/manual/install.xml.meta b/trunk/docs/manual/install.xml.meta new file mode 100644 index 0000000000..06f4946208 --- /dev/null +++ b/trunk/docs/manual/install.xml.meta @@ -0,0 +1,16 @@ + + + + install + / + . + + + de + en + es + fr + ja + ko + + diff --git a/trunk/docs/manual/invoking.html b/trunk/docs/manual/invoking.html new file mode 100644 index 0000000000..eb9ed56683 --- /dev/null +++ b/trunk/docs/manual/invoking.html @@ -0,0 +1,19 @@ +URI: invoking.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: invoking.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: invoking.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: invoking.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: invoking.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/invoking.html.de b/trunk/docs/manual/invoking.html.de new file mode 100644 index 0000000000..ba05dd06d1 --- /dev/null +++ b/trunk/docs/manual/invoking.html.de @@ -0,0 +1,154 @@ + + + +Apache starten - Apache HTTP Server + + + + + +
    <-
    +

    Apache starten

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Unter Windows läuft der Apache üblicherweise als Dienst + (Windows NT, 2000 und XP) oder als Konsolenanwendung (Windows 9x und + ME). Für Einzelheiten lesen Sie bitte Apache als Dienst betreiben + und Apache als Konsolenanwendung betreiben.

    + +

    Unter Unix wird das httpd-Programm als Daemon + ausgeführt, der im Hintergrund fortlaufend aktiv ist, um + Anfragen zu bearbeiten. Dieses Dokument beschreibt, wie + httpd aufgerufen wird.

    +
    + +
    top
    +
    +

    Wie der Apache startet

    + +

    Wenn die in der Konfigurationsdatei angegebene Listen-Anweisung auf die Voreinstellung + von 80 gesetzt ist (oder einen anderen Port unterhalb von 1024), dann + müssen Sie root-Berechtigung besitzen, um den Apache starten + zu können. Nur dann kann er sich an diesen privilegierten + Port binden. Sobald der Server gestartet ist und einige vorbereitende + Aktionen wie das Öffnen seiner Log-Dateien ausgeführt hat, + startet er mehrere Kind-Prozesse, welche die Arbeit erledigen: + das Lauschen auf und Beantworten von Anfragen von Clients. Der + Haupt-httpd-Prozess läuft unter dem Benutzer root + weiter, die Kind-Prozesse jedoch werden unter weniger privilegierten + Benutzerkennungen ausgeführt. Dies wird von dem ausgewählten + Multi-Processing-Modul gesteuert.

    + +

    Die Verwendung des Steuerskripts apachectl ist die + empfohlene Methode, das httpd-Programm zu starten. + Dieses Skript setzt verschiedene Umgebungsvariablen, die für die + korrekte Funktion von httpd unter einigen + Betriebssystemen notwendig sind, und startet dann das + httpd-Programm. apachectl + reicht alle Kommandozeilenargumente durch, so dass alle + httpd-Optionen auch mit apachectl + verwendet werden können. Um den korrekten Ablageort des + httpd-Programms sowie einige Kommandozeilenargumente + anzugeben, die Sie immer verwenden möchten, können + Sie auch das Skript apachectl direkt editieren und die + Variable HTTPD am Anfang ändern.

    + +

    Das Erste was httpd macht, wenn es startet, ist das + Suchen und Einlesen der Konfigurationsdatei httpd.conf. + Der Ablageort dieser Datei wird zur Kompilierungszeit festgelegt. Es ist + aber möglich, den Ablageort zur Laufzeit anzugeben, indem die + Kommandozeilenoption -f wie folgt verwendet wird:

    + +

    /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf

    + +

    Wenn während des Starts alles gutgeht, trennt sich der Server + vom Terminal ab und die Eingabeaufforderung erscheint gleich darauf + wieder. Dies zeigt an, dass der Server hochgefahren ist und läuft. + Sie können nun Ihren Browser benutzen, um Verbindung zum Server + aufzunehmen und sich die Testseite im DocumentRoot-Verzeichnis anzusehen wie auch + die lokale Kopie der Dokumentation, die von dieser Seite aus verlinkt + ist.

    +
    top
    +
    +

    Fehler während des Hochfahrens

    + +

    Wenn der Apache während des Hochfahrens einen schweren Fehler + feststellt, schreibt er entweder eine Nachricht, die das Problem + näher schildert, auf die Konsole oder ins ErrorLog, bevor er sich selbst beendet. + Eine der häufigsten Fehlermeldungen ist "Unable + to bind to Port ..." (Anm.d.Ü.: "Kann nicht an Port ... + binden"). Diese Meldung wird üblicherweise verursacht:

    + +
      +
    • entweder durch den Versuch, den Server an einem privilegierten + Port zu starten, während man nicht als Benutzer root angemeldet + ist,
    • + +
    • oder durch den Versuch, den Server zu starten, wenn bereits eine + andere Instanz des Apache oder ein anderer Webserver an den gleichen + Port gebunden ist.
    • +
    + +

    Für weitere Anleitungen zur Fehlerbehebung lesen Sie bitte die + Apache-FAQ.

    +
    top
    +
    +

    Beim Bootvorgang starten

    + +

    Wenn Sie möchten, dass Ihr Server direkt nach einem + System-Neustart weiterläuft, sollten Sie einen Aufruf von + apachectl zu den Startdateien Ihres Systems + hinzufügen (üblicherweise rc.local oder + eine Datei in einem rc.N-Verzeichnis). Dies startet + den Apache als root. Stellen Sie zuvor jedoch sicher, dass Ihr + Server hinsichtlich Sicherheit und Zugriffsbeschränkungen + richtig konfiguriert ist.

    + +

    Das apachectl-Skript ist dafür ausgelegt, wie + ein Standard-SysV-init-Skript zu arbeiten. Es akzeptiert die Argumente + start, restart und stop + und übersetzt sie in die entsprechenden Signale für + httpd. Daher können Sie oftmals + einfach apachectl in das entsprechende init-Verzeichnis + linken. Überprüfen Sie bitte auf jeden Fall die genauen + Anforderungen Ihres Systems.

    +
    top
    +
    +

    Weitere Informationen

    + +

    Weitere Informationen über Kommandozeilenoptionen von httpd und apachectl sowie anderen + Hilfsprogrammen, die dem Server beigefügt sind, sind auf der + Seite Server und Hilfsprogramme + verfügbar. Es existiert außerdem eine Dokumentation + aller in der Apache-Distribution enthaltenen Module und der von ihnen bereitgestellten + Direktiven.

    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/invoking.html.en b/trunk/docs/manual/invoking.html.en new file mode 100644 index 0000000000..1a4cbc21a6 --- /dev/null +++ b/trunk/docs/manual/invoking.html.en @@ -0,0 +1,149 @@ + + + +Starting Apache - Apache HTTP Server + + + + + +
    <-
    +

    Starting Apache

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    On Windows, Apache is normally run as a service on Windows + NT, 2000 and XP, or as a console application on Windows 9x and + ME. For details, see Running Apache as a Service + and Running Apache as a + Console Application.

    + +

    On Unix, the httpd program + is run as a daemon that executes continuously in the + background to handle requests. This document describes how + to invoke httpd.

    +
    + +
    top
    +
    +

    How Apache Starts

    + +

    If the Listen + specified in the configuration file is default of 80 (or any other + port below 1024), then it is necessary to have root privileges in + order to start apache, so that it can bind to this privileged + port. Once the server has started and performed a few preliminary + activities such as opening its log files, it will launch several + child processes which do the work of listening for and + answering requests from clients. The main httpd + process continues to run as the root user, but the child processes + run as a less privileged user. This is controlled by the selected + Multi-Processing Module.

    + +

    The recommended method of invoking the httpd + executable is to use the apachectl control script. This + script sets certain environment variables that are necessary for + httpd to function correctly under some operating + systems, and then invokes the httpd binary. + apachectl will pass through any command line + arguments, so any httpd options may also be used with + apachectl. You may also directly edit the + apachectl script by changing the HTTPD + variable near the top to specify the correct location of the + httpd binary and any command-line arguments that you + wish to be always present.

    + +

    The first thing that httpd does when it is + invoked is to locate and read the configuration file + httpd.conf. The location of this file is set at + compile-time, but it is possible to specify its location at run + time using the -f command-line option as in

    + +

    /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf

    + +

    If all goes well during startup, the server will detach from + the terminal and the command prompt will return almost + immediately. This indicates that the server is up and running. + You can then use your browser to connect to the server and view + the test page in the DocumentRoot directory + and the local copy of the documentation linked from that + page.

    +
    top
    +
    +

    Errors During Start-up

    + +

    If Apache suffers a fatal problem during startup, it will + write a message describing the problem either to the console or + to the ErrorLog before + exiting. One of the most common error messages is "Unable + to bind to Port ...". This message is usually caused by + either:

    + +
      +
    • Trying to start the server on a privileged port when not + logged in as the root user; or
    • + +
    • Trying to start the server when there is another instance + of Apache or some other web server already bound to the same + Port.
    • +
    + +

    For further trouble-shooting instructions, consult the + Apache FAQ.

    +
    top
    +
    +

    Starting at Boot-Time

    + +

    If you want your server to continue running after a system + reboot, you should add a call to apachectl to your + system startup files (typically rc.local or a file in + an rc.N directory). This will start Apache as + root. Before doing this ensure that your server is properly + configured for security and access restrictions.

    + +

    The apachectl script is designed to act like a + standard SysV init script; it can take the arguments + start, restart, and stop + and translate them into the appropriate signals to + httpd. So you can often simply link + apachectl into the appropriate init directory. But be + sure to check the exact requirements of your system.

    +
    top
    +
    +

    Additional Information

    + +

    Additional information about the command-line options of httpd and apachectl as well as other support + programs included with the server is available on the + Server and Supporting Programs page. + There is also documentation on all the modules included with the Apache distribution + and the directives that they + provide.

    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/invoking.html.es b/trunk/docs/manual/invoking.html.es new file mode 100644 index 0000000000..448e854073 --- /dev/null +++ b/trunk/docs/manual/invoking.html.es @@ -0,0 +1,166 @@ + + + +iniciar Apache - Servidor HTTP Apache + + + + + +
    <-
    +

    iniciar Apache

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    En Windows, Apache se ejecuta normalmente como un servicio en + Windows NT, 2000 and XP, y como una aplicacion de consola en + Windows 9x y ME. Para obtener más información, consulte + Ejecutar Apache como un + servicio y Ejecutar + Apache como una aplicación de consola.

    + +

    En Unix, el programa httpd se + ejecuta como un demonio (daemon) de forma silenciosa y atiende las + peticiones que le lleguen. Este documento describe cómo + invocar el programa httpd.

    +
    + +
    top
    +
    +

    Cómo iniciar Apache

    + +

    Si el puerto especificado en la directiva Listen del fichero de + configuración es el que viene por defecto, es decir, el + puerto 80 (o cualquier otro puerto por debajo del 1024), entonces + es necesario tener privilegios de usuario root (superusuario) para + iniciar Apache, de modo que pueda establecerse una conexión a + través de esos puertos privilegiados. Una vez que el servidor + Apache se ha iniciado y ha completado algunas tareas preliminares, + tales como abrir sus ficheros log, lanzará varios procesos, + procesos hijo, que hacen el trabajo de escuchar y atender + las peticiones de los clientes. El proceso principal, + httpd continúa ejecutandose como root, pero los + procesos hijo se ejecutan con menores privilegios de usuario. + Esto lo controla el Módulo de + MultiProcesamiento (MPM) seleccionado.

    + +

    La forma recomendada para invocar el ejecutable + httpd es usando el script de control apachectl. Este script fija + determinadas variables de entorno que son necesarias para que + httpd funcione correctamente en el sistema operativo, + y después invoca el binario httpd. + apachectl pasa a httpd cualquier argumento que se le + pase a través de la línea de comandos, de forma que + cualquier opción de httpd puede ser usada + también con apachectl. Puede editar + directamente el script apachectl y cambiar la + variable HTTPD variable que está al principio y + que especifica la ubicación exacta en la que está el + binario httpd y cualquier argumento de línea de + comandos que quiera que esté siempre presente.

    + +

    La primera cosa que hace httpd cuando es invocado + es localizar y leer el fichero de + configuración httpd.conf. El lugar en el que + está ese fichero se determina al compilar, pero también + es posible especificar la ubicación en la que se encuentra al + iniciar el servidor Apache usando la opción de línea de + comandos -f

    + +

    /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf

    + +

    Si todo va bien durante el arranque, la sesión de terminal + se suspenderá un momento y volverá a estar activa casi + inmediatamente. Esto quiere decir que el servidor está activo + y funcionando. Puede usar su navegador para conectarse al + servidor y ver la pagina de prueba que hay en el directorio + DocumentRoot y la copia local + de esta documentación a la que se puede acceder desde esa + página.

    +
    top
    +
    +

    Errores Durante el Arranque

    + +

    Si Apache encuentra una error irrecuperable durante el + arranque, escribirá un mensaje describiendo el problema en la + consola o en el archivo ErrorLog antes de abortar la + ejecución. Uno de los mensajes de error más comunes es + "Unable to bind to Port ...". Cuando se recibe este + mensaje es normalmente por alguna de las siguientes razones:

    + +
      +
    • Está intentando iniciar el servidor Apache en un puerto + privilegiado (del 0 al 1024) sin haber hecho login como usuario + root; ó
    • + +
    • Está intentando iniciar el servidor Apache mientras + está ya ejecutando Apache o algún otro servidor web en + el mismo puerto.
    • +
    + +

    Puede encontrar más información sobre cómo + solucionar problemas, en la sección de Preguntas Frecuentes de Apache.

    +
    top
    +
    +

    Iniciar Apache al Iniciar el Sistema

    + +

    Si quiere que el servidor Apache continú su ejecución + después de reiniciar el sistema, debe añadir una llamada + a apachectl en sus archivos de arranque (normalmente + rc.local o un fichero en ese directorio del tipo + rc.N). Esto iniciará Apache como usuario + root. Antes de hacer esto, asegúrese de que la + configuración de seguridad y las restricciones de acceso de + su servidor Apache están correctamente configuradas.

    + +

    El script apachectl está diseñado para + actuar como un script estandar de tipo SysV init; puede tomar los + argumentos start, restart, y + stop y traducirlos en las señales apropiadas + para httpd. De esta manera, casi siempre puede + simplemente enlazar apachectl con el directorio init + adecuado. Pero asegúrese de comprobar los requisitos exactos + de su sistema.

    +
    top
    +
    +

    Información Adicional

    + +

    En la sección El Servidor y Programas + de Soporte puede encontrar más información sobre + las opciones de línea de comandos que puede pasar a httpd y apachectl asi como sobre otros + programas de soporte incluidos con el servidor Apache. + También hay documentación sobre todos los módulos incluidos con la distribucion de + Apache y sus correspondientes directivas asociadas.

    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/invoking.html.ja.euc-jp b/trunk/docs/manual/invoking.html.ja.euc-jp new file mode 100644 index 0000000000..0aa8be412d --- /dev/null +++ b/trunk/docs/manual/invoking.html.ja.euc-jp @@ -0,0 +1,159 @@ + + + +Apache ¤Îµ¯Æ° - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¤Îµ¯Æ°

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Windows ¾å¤Ç¤Ï¡¢Apache ¤ÏÄ̾ï¤Ï + Windows NT, 2000, XP ¤Ç¤Ï¥µ¡¼¥Ó¥¹¤È¤·¤Æ¡¢Windows 9x, ME + ¤Ç¤Ï¥³¥ó¥½¡¼¥ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ + ¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï¡¢¡Ö + ¥µ¡¼¥Ó¥¹¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡×¤È¡Ö + ¥³¥ó¥½¡¼¥ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡×¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    Unix¤Ç¤Ï¡¢httpd + ¥×¥í¥°¥é¥à¤¬¡¢¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Ç¾ï¤Ë¥ê¥¯¥¨¥¹¥È½èÍý¤ò¹Ô¤¦ + ¥Ç¡¼¥â¥ó¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤Îʸ½ñ¤Ç¤Ï¤É¤Î¤è¤¦¤Ë + httpd ¤òµ¯Æ°¤¹¤ë¤«¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    Apache ¤Îµ¯Æ°ÊýË¡

    + +

    ¤â¤·¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë + Listen + ¤¬¥Ç¥Õ¥©¥ë¥È¤Î 80 (¤â¤·¤¯¤Ï 1024 °Ê²¼¤Î¾¤Î¥Ý¡¼¥È) + ¤Ç¤¢¤ë¾ì¹ç¤Ï¡¢Apache ¤òµ¯Æ°¤¹¤ë¤¿¤á¤Ë¤Ï root + ¸¢¸Â¤¬É¬Íפˤʤê¤Þ¤¹¤¬¡¢ + ¤³¤ì¤Ï¤³¤ÎÆø¢¥Ý¡¼¥È¤Ë¥Ð¥¤¥ó¥É¤¹¤ë¤¿¤á¤Ç¤¹¡£ + µ¯Æ°¤·¤Æ¡¢°ìÅÙ¥í¥°¥Õ¥¡¥¤¥ë¤ò³«¤¯¤È¤¤¤Ã¤¿½àÈ÷¤Î¤¿¤á¤Î + Æ°ºî¤ò´ö¤Ä¤«¼Â¹Ô¤·¤¿¸å¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë + listen ¤È±þÅú¤ò¼ÂºÝ¤Ë¹Ô¤¦»Ò¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Þ¤¹¡£ + ¥á¥¤¥ó¤Î httpd ¥×¥í¥»¥¹¤Ï root ¸¢¸Â¤ÇÁö¤ê³¤±¤Þ¤¹¤¬¡¢ + »Ò¥×¥í¥»¥¹¤Ï¤â¤Ã¤ÈÄ㤤¸¢¸Â¤ÇÁö¤ê¤Þ¤¹¡£ + ¤³¤ì¤ÏÁªÂò¤·¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë¤ÇÀ©¸æ¤µ¤ì¤Þ¤¹¡£

    + +

    ¿ä¾©¤Î httpd ¼Â¹Ô¥×¥í¥°¥é¥à¤Îµ¯Æ°ÊýË¡¤Ï¡¢ + apachectl + À©¸æ¥¹¥¯¥ê¥×¥È¤ò»ÈÍѤ¹¤ëÊýË¡¤Ç¤¹¡£¤³¤Î¥¹¥¯¥ê¥×¥È¤Ï¡¢httpd + ¤¬¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¾å¤ÇÀµ¾ï¤ËÆ°ºî¤¹¤ë¤è¤¦¤ËɬÍפʴĶ­ÊÑ¿ô¤ò + ŬÀÚ¤ËÀßÄꤷ¤Æ¡¢httpd ¥Ð¥¤¥Ê¥ê¤òµ¯Æ°¤·¤Þ¤¹¡£ + apachectl ¤Ï¤É¤ó¤Ê¥³¥Þ¥ó¥É¥é¥¤¥ó°ú¿ô¤âÄ̲ᤵ¤»¤Þ¤¹¤Î¤Ç¡¢ + httpd ¤Î¤É¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤â + apchectl ¤Î¥ª¥×¥·¥ç¥ó¤È¤·¤Æ»ÈÍѤǤ­¤Þ¤¹¡£ + ¤Þ¤¿¡¢apchectl ¥¹¥¯¥ê¥×¥È¤òľÀÜÊÔ½¸¤·¡¢ + ¥¹¥¯¥ê¥×¥ÈÀèƬÉÕ¶á¤Î HTTPD ÊÑ¿ô¤òÊѹ¹¤¹¤ë¤³¤È¤Ç¡¢ + httpd ¥Ð¥¤¥Ê¥ê¤ÎÀµ¤·¤¤°ÌÃÖ¤ò»ØÄꤷ¤¿¤ê¡¢¾ï¤Ë + Éղ䵤»¤ë¥³¥Þ¥ó¥É¥é¥¤¥ó°ú¿ô¤ò»ØÄꤷ¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    httpd ¤¬µ¯Æ°¤µ¤ì¤Æ¤Þ¤ººÇ½é¤Ë¤¹¤ë¤³¤È¤Ï¡¢ + ÀßÄê¥Õ¥¡¥¤¥ë + httpd.conf ¤Î°ÌÃÖ¤òÆÃÄꤷ¤ÆÆɤ߹þ¤à¤³¤È¤Ç¤¹¡£ + ¤³¤Î¥Õ¥¡¥¤¥ë¤Î°ÌÃ֤ϥ³¥ó¥Ñ¥¤¥ë»þ¤ËÀßÄꤵ¤ì¤Þ¤¹¤¬¡¢¼Â¹Ô»þ¤Ë + -f ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ + °ÌÃÖ¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¼¡¤Î¤è¤¦¤Ë¤Ç¤¹¡£

    + +

    /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf

    + +

    ¥¹¥¿¡¼¥È¥¢¥Ã¥×¤¬Ëü»ö¾å¼ê¤¯¤¤¤Ã¤¿¤é¡¢¥µ¡¼¥Ð¤Ï¥¿¡¼¥ß¥Ê¥ë¤«¤é + ÀÚ¤êÎ¥¤µ¤ì¤Æ¡¢¥³¥Þ¥ó¥É¥×¥í¥ó¥×¥È¤¬Â¨ºÂ¤ËÌá¤Ã¤Æ¤¯¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤ì¤Ï¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤Æ¤¤¤ë¾õÂÖ¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£ + ¤½¤Î¸å¤Ï¥Ö¥é¥¦¥¶¤Ç¥µ¡¼¥Ð¤ËÀܳ¤·¤Æ¡¢ + DocumentRoot + ¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Æ¥¹¥È¥Ú¡¼¥¸¤ä¤½¤³¤«¤é¥ê¥ó¥¯¤µ¤ì¤Æ¤¤¤ë + ¥í¡¼¥«¥ë¤Î¥É¥­¥å¥á¥ó¥È¤ò¸«¤ë¤³¤È¤¬¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    µ¯Æ°»þ¤Î¥¨¥é¡¼

    + +

    Apache ¤Ï¡¢µ¯Æ°»þ¤ËÃ×̿Ū¤ÊÌäÂê¤ËÁø¶ø¤¹¤ë¤È¡¢ + ½ªÎ»¤¹¤ëÁ°¤Ë¡¢¥³¥ó¥½¡¼¥ë¤« + ErrorLog + ¤Î¤É¤Á¤é¤«¤ËÌäÂê¤òµ­½Ò¤·¤¿¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ·¤Þ¤¹¡£ + ºÇ¤â¤è¤¯¤¢¤ë¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ï + ¡ÖUnable to bind to Port ...¡× + ¤Ç¤¹¡£¤³¤Î¥á¥Ã¥»¡¼¥¸¤ÏÉáÄ̤ϼ¡¤Î¤É¤Á¤é¤«¤¬¸¶°ø¤Ç¤¹¡£

    + +
      +
    • root ¤Ç¥í¥°¥¤¥ó¤·¤Æ¤¤¤Ê¤¤»þ¤Ë¡¢ + Æø¢¥Ý¡¼¥È¤Ç¥µ¡¼¥Ð¤òµ¯Æ°¤·¤è¤¦¤È¤·¤¿¡£
    • + +
    • Ʊ¤¸¥Ý¡¼¥È¤Ë´û¤Ë¥Ð¥¤¥ó¥É¤µ¤ì¤Æ¤¤¤ë Apache + ¤¬¤â¤¦°ì¤Ä¤¢¤ë¤È¤­¤ä¾¤Î¥¦¥§¥Ö¥µ¡¼¥Ð¤¬Â¸ºß¤·¤Æ¤¤¤ë»þ¤Ë¡¢ + ¥µ¡¼¥Ð¤ò³«»Ï¤·¤è¤¦¤È¤·¤¿¡£
    • +
    + +

    ¤è¤ê¿¤¯¤ÎÌäÂê²ò·è¤ÎÊýºö¤ÎÀâÌÀ¤Ï¡¢ + Apache FAQ ¤ò¤´Í÷²¼¤µ¤¤¡£

    +
    top
    +
    +

    ¥Ö¡¼¥È»þ¤Îµ¯Æ°

    + +

    ¥·¥¹¥Æ¥à¤¬¥ê¥Ö¡¼¥È¤·¤¿¸å¤Ç¤â + ¥µ¡¼¥Ð¤¬¼Â¹Ô¤µ¤ì³¤±¤ë¤è¤¦¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + apachectl + ¤ò¸Æ¤Ó½Ð¤¹¤â¤Î¤ò¥·¥¹¥Æ¥à¥¹¥¿¡¼¥È¥¢¥Ã¥×¥Õ¥¡¥¤¥ë + (Ä̾ï rc.local ¤ä rc.N + Æâ¤Î¥Õ¥¡¥¤¥ë) ¤ËÄɲ䷤ʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤ÎÊýË¡¤Ç¤Ï Apache ¤ò root ¸¢¸Â¤Çµ¯Æ°¤·¤Þ¤¹¡£ + ¤³¤ì¤ò¤¹¤ëÁ°¤Ë¡¢¥»¥­¥å¥ê¥Æ¥£¤ä¥¢¥¯¥»¥¹À©¸Â¤¬ + ŬÀÚ¤ËÀßÄꤵ¤ì¤Æ¤¤¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    apachectl ¥¹¥¯¥ê¥×¥È¤ÏÄ̾ï¤Ï¡¢É¸½àŪ¤Ê SysV init + ¥¹¥¯¥ê¥×¥È¤È¤·¤ÆÆ°ºî¤¹¤ë¤è¤¦¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ + start, restart, stop + ¤È¤¤¤Ã¤¿°ú¿ô¤ò¤È¤Ã¤Æ¡¢httpd + ¤Ø¤ÎŬÀڤʥ·¥°¥Ê¥ë¤ËÊÑ´¹¤·¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢Ä̾ï¤Ïñ¤ËŬÀÚ¤Ê init ¥Ç¥£¥ì¥¯¥È¥êÆ⤫¤é + apachectl ¤Ø¥ê¥ó¥¯¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤·¤«¤·¡¢ + Ç°¤Î¤¿¤á¥·¥¹¥Æ¥à¤ÎÍ×µá¤Ë¹çÃפ·¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ÄɲþðÊó

    + +

    httpd ¤ä + apachectl¡¢¥µ¡¼¥Ð¤Ë´Þ¤Þ¤ì¤Æ¤¤¤¿¤½¤Î¾Êä½õ¥×¥í¥°¥é¥à¤Î¡¢ + ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤Ë´Ø¤¹¤ëÄɲþðÊó¤Ï¡¢ + ¥µ¡¼¥Ð¤ÈÊä½õ¥×¥í¥°¥é¥à¥Ú¡¼¥¸¤Ë + µ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + Apache ÇÛÉۤ˴ޤޤì¤Æ¤¤¤ëÁ´¥â¥¸¥å¡¼¥ë¡¢ + ¤½¤ì¤Ë¤è¤Ã¤ÆÄ󶡤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤Î¥É¥­¥å¥á¥ó¥È¤â¤¢¤ê¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/invoking.html.ko.euc-kr b/trunk/docs/manual/invoking.html.ko.euc-kr new file mode 100644 index 0000000000..fccb3d3382 --- /dev/null +++ b/trunk/docs/manual/invoking.html.ko.euc-kr @@ -0,0 +1,138 @@ + + + +¾ÆÆÄÄ¡ ½ÃÀÛ - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ ½ÃÀÛ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    º¸Åë ¾ÆÆÄÄ¡´Â Windows NT, 2000, XP¿¡¼­´Â ¼­ºñ½º·Î, + Windows 95°ú ME¿¡¼­´Â ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàµÈ´Ù. ÀÚ¼¼ÇÑ + ³»¿ëÀº ¼­ºñ½º·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϱâ¿Í ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϱâ.

    + +

    À¯´Ð½º¿¡¼­ httpd + ÇÁ·Î±×·¥Àº ¹é±×¶ó¿îµå¿¡¼­ °è¼Ó ¿äûÀ» ó¸®ÇÏ´Â µ¥¸óÀ¸·Î + ½ÇÇàµÈ´Ù. ÀÌ ¹®¼­´Â httpd¸¦ ½ÃÀÛÇÏ´Â ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¾î¶»°Ô ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇϳª

    + +

    ¼³Á¤ÆÄÀÏ¿¡¼­ ListenÀÌ ±âº»°ªÀÎ 80(ȤÀº + 1024ÀÌÇÏÀÇ ´Ù¸¥ Æ÷Æ®)À̶ó¸é ÀÌ Æ¯±Ç Æ÷Æ®¿¡ ¿¬°áÇϱâÀ§ÇØ + root ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù. ¼­¹ö´Â ½ÃÀÛÇÏ¿© ·Î±×ÆÄÀÏÀ» ¿©´Â µîÀÇ + ¸î¸î ±âÃÊÀûÀÎ ÀÛ¾÷À» ¸¶Ä£ÈÄ, Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ±â´Ù¸®°í + ÀÀ´äÇÏ´Â ÀÚ½Ä(child) ÇÁ·Î¼¼½º¸¦ ¿©·¯°³ ¶ç¿î´Ù. + ÁÖ httpd ÇÁ·Î¼¼½º´Â °è¼Ó root »ç¿ëÀÚ·Î ½ÇÇàµÇÁö¸¸, + ÀÚ½Ä ÇÁ·Î¼¼½ºµéÀº ´õ ±ÇÇÑÀÌ ÀÛÀº »ç¿ëÀÚ·Î ½ÇÇàµÈ´Ù. ÀÌ´Â + ¼±ÅÃÇÑ ´ÙÁßó¸® ¸ðµâ·Î Á¶Á¤ÇÑ´Ù.

    + +

    apachectl + ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ¿© httpd ½ÇÇàÆÄÀÏÀ» ½ÃÀÛÇϱæ + ±ÇÀåÇÑ´Ù. ÀÌ ½ºÅ©¸³Æ®´Â httpd°¡ ¸î¸î + ¿î¿µÃ¼Á¦¿¡¼­ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ È¯°æº¯¼öµéÀ» + ¼³Á¤ÇÏ°í httpd ½ÇÇàÆÄÀÏÀ» ½ÃÀÛÇÑ´Ù. + apachectlÀº ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ ±×´ë·Î ³Ñ±â±â¶§¹®¿¡, + httpdÀÇ ¾î¶² ¿É¼ÇÀÌ¶óµµ apachectl¿¡ + »ç¿ë°¡´ÉÇÏ´Ù. ¶Ç, apachectl ½ºÅ©¸³Æ®ÀÇ ¾ÕºÎºÐ¿¡ + ³ª¿À´Â HTTPD º¯¼ö¸¦ httpd ½ÇÇàÆÄÀÏÀÌ + ÀÖ´Â À§Ä¡¿Í Ç×»ó »ç¿ëÇÒ ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®·Î Á÷Á¢ + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    httpd¸¦ ½ÇÇàÇÏ¸é ¸ÕÀú ¼³Á¤ÆÄÀÏ httpd.conf¸¦ + ã¾Æ¼­ Àд´Ù. ÀÌ ÆÄÀÏÀÇ À§Ä¡´Â ÄÄÆÄÀÏ Áß¿¡ ÁöÁ¤Çϳª, ½ÇÇà½Ã + ´ÙÀ½°ú °°ÀÌ -f ¸í·ÉÇà ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù.

    + +

    /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf

    + +

    ½ÃÀÛÇÏ´Â °úÁ¤¿¡¼­ ¹®Á¦°¡ ¾ø´Ù¸é, ¼­¹ö´Â Å͹̳ο¡¼­ + ¶³¾îÁö°í ¸í·É ÇÁ·ÒÇÁÆ®°¡ °ÅÀÇ Áï½Ã ³ª¿À°ÔµÈ´Ù. ÀÌ´Â ¼­¹ö°¡ + ½ÇÇàµÊÀ» ÀǹÌÇÑ´Ù. ºê¶ó¿ìÀú·Î ¼­¹ö¿¡ ¿¬°áÇÏ¿© DocumentRoot µð·ºÅ丮¿¡ ÀÖ´Â + Å×½ºÆ® ÆäÀÌÁö¿Í ±× ÆäÀÌÁö¿¡ ¸µÅ©µÈ (·ÎÄÃÄ«ÇÇ) ¼³¸í¼­¸¦ º¼ + ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ½ÃÀÛÁß ¿À·ù

    + +

    ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇÏ´Â °úÁ¤Áß¿¡ ½É°¢ÇÑ ¹®Á¦°¡ ¹ß»ýÇϸé, + Á¾·áÇϱâ Àü¿¡ ¹®Á¦¸¦ ¾Ë¸®´Â ¹®±¸¸¦ ÄܼÖÀ̳ª ErrorLog¿¡ ¾´´Ù. °¡Àå ÈçÇÑ ¿À·ù¹® Áß + Çϳª´Â "Unable to bind to Port ..."ÀÌ´Ù. + ÀÌ ¸Þ¼¼Áö´Â º¸Åë ´ÙÀ½ µÎ °æ¿ì¿¡ ¹ß»ýÇÑ´Ù:

    + +
      +
    • root »ç¿ëÀÚ·Î ·Î±×ÀÎÇÏÁö ¾Ê°í Ư±Ç Æ÷Æ®¿¡ ¼­¹ö¸¦ + ½ÃÀÛÇÏ·Á ÇÑ °æ¿ì. ȤÀº
    • + +
    • ÀÌ¹Ì ¾ÆÆÄÄ¡³ª ´Ù¸¥ À¥¼­¹ö°¡ »ç¿ëÁßÀÎ Æ÷Æ®¿¡ + ¼­¹ö¸¦ ½ÃÀÛÇÏ·Á ÇÑ °æ¿ì.
    • +
    + +

    ±âŸ ¹®Á¦ÇØ°á ¹æ¹ýÀº ¾ÆÆÄÄ¡ FAQ¸¦ + Âü°íÇ϶ó.

    +
    top
    +
    +

    ºÎÆÃÇÒ¶§ ½ÃÀÛÇϱâ

    + +

    ½Ã½ºÅÛÀÌ Àç½ÃÀÛÇÑ ÈÄ¿¡µµ ¼­¹ö°¡ °è¼Ó ½ÇÇàµÇ±æ ¹Ù¶õ´Ù¸é, + ½Ã½ºÅÛ ½ÃÀÛÆÄÀÏ(º¸Åë rc.localÀ̳ª rc.N + µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏ)¿¡ apachectlÀ» Ãß°¡ÇØ¾ß + ÇÑ´Ù. ÀÌ °æ¿ì ¾ÆÆÄÄ¡´Â root·Î ½ÃÀ۵ȴÙ. ÀÌÀü¿¡ ¼­¹öÀÇ º¸¾ÈÀ̳ª + Á¢±Ù Á¦ÇÑ(ÆÄÀϱÇÇÑ)ÀÌ ¿Ã¹Ù·Î ¼³Á¤µÇ¾ú´ÂÁö È®ÀÎÇ϶ó.

    + +

    apachectlÀº Ç¥ÁØ SysV init ½ºÅ©¸³Æ®¿Í ºñ½ÁÇÏ°Ô + µ¿ÀÛÇϵµ·Ï ¸¸µé¾îÁ³´Ù. ½ºÅ©¸³Æ®´Â ¾Æ±Ô¸ÕÆ®·Î start, + restart, stopÀ» ¹ÞÀ¸¸é °¢°¢ ÀûÀýÇÑ + ½Ã±×³ÎÀ» httpd¿¡ º¸³½´Ù. ±×·¡¼­ º¸ÅëÀº + apachectlÀ» ÀûÀýÇÑ init µð·ºÅ丮·Î ¸µÅ©¸¦ °É¸éµÈ´Ù. + ±×·¯³ª »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ Á¤È®ÇÑ ¿ä±¸»çÇ×À» È®ÀÎÇ϶ó.

    +
    top
    +
    +

    Ãß°¡ Á¤º¸

    + +

    httpd¿Í apachectl, ±âŸ ¼­¹ö¿¡ + Æ÷ÇÔµÈ Áö¿ø ÇÁ·Î±×·¥µéÀÇ ¸í·ÉÇà ¿É¼ÇÀº + ¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ ÆäÀÌÁö¸¦ + Âü°íÇ϶ó. ¶Ç ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡´Â ¸ðµç ¸ðµâ°ú + ±×µéÀÌ Á¦°øÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¹®¼­°¡ ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/invoking.xml b/trunk/docs/manual/invoking.xml new file mode 100644 index 0000000000..7fe03a19a6 --- /dev/null +++ b/trunk/docs/manual/invoking.xml @@ -0,0 +1,144 @@ + + + + + + + + + + Starting Apache + + +

    On Windows, Apache is normally run as a service on Windows + NT, 2000 and XP, or as a console application on Windows 9x and + ME. For details, see Running Apache as a Service + and Running Apache as a + Console Application.

    + +

    On Unix, the httpd program + is run as a daemon that executes continuously in the + background to handle requests. This document describes how + to invoke httpd.

    +
    + +Stopping and Restarting +httpd +apachectl + +
    How Apache Starts + +

    If the Listen + specified in the configuration file is default of 80 (or any other + port below 1024), then it is necessary to have root privileges in + order to start apache, so that it can bind to this privileged + port. Once the server has started and performed a few preliminary + activities such as opening its log files, it will launch several + child processes which do the work of listening for and + answering requests from clients. The main httpd + process continues to run as the root user, but the child processes + run as a less privileged user. This is controlled by the selected + Multi-Processing Module.

    + +

    The recommended method of invoking the httpd + executable is to use the apachectl control script. This + script sets certain environment variables that are necessary for + httpd to function correctly under some operating + systems, and then invokes the httpd binary. + apachectl will pass through any command line + arguments, so any httpd options may also be used with + apachectl. You may also directly edit the + apachectl script by changing the HTTPD + variable near the top to specify the correct location of the + httpd binary and any command-line arguments that you + wish to be always present.

    + +

    The first thing that httpd does when it is + invoked is to locate and read the configuration file + httpd.conf. The location of this file is set at + compile-time, but it is possible to specify its location at run + time using the -f command-line option as in

    + +/usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf + +

    If all goes well during startup, the server will detach from + the terminal and the command prompt will return almost + immediately. This indicates that the server is up and running. + You can then use your browser to connect to the server and view + the test page in the DocumentRoot directory + and the local copy of the documentation linked from that + page.

    +
    + +
    Errors During Start-up + +

    If Apache suffers a fatal problem during startup, it will + write a message describing the problem either to the console or + to the ErrorLog before + exiting. One of the most common error messages is "Unable + to bind to Port ...". This message is usually caused by + either:

    + +
      +
    • Trying to start the server on a privileged port when not + logged in as the root user; or
    • + +
    • Trying to start the server when there is another instance + of Apache or some other web server already bound to the same + Port.
    • +
    + +

    For further trouble-shooting instructions, consult the + Apache FAQ.

    +
    + +
    Starting at Boot-Time + +

    If you want your server to continue running after a system + reboot, you should add a call to apachectl to your + system startup files (typically rc.local or a file in + an rc.N directory). This will start Apache as + root. Before doing this ensure that your server is properly + configured for security and access restrictions.

    + +

    The apachectl script is designed to act like a + standard SysV init script; it can take the arguments + start, restart, and stop + and translate them into the appropriate signals to + httpd. So you can often simply link + apachectl into the appropriate init directory. But be + sure to check the exact requirements of your system.

    +
    + +
    Additional Information + +

    Additional information about the command-line options of + httpd and apachectl as well as other support + programs included with the server is available on the + Server and Supporting Programs page. + There is also documentation on all the modules included with the Apache distribution + and the directives that they + provide.

    +
    + +
    diff --git a/trunk/docs/manual/invoking.xml.de b/trunk/docs/manual/invoking.xml.de new file mode 100644 index 0000000000..410c41714e --- /dev/null +++ b/trunk/docs/manual/invoking.xml.de @@ -0,0 +1,152 @@ + + + + + + + + + + Apache starten + + +

    Unter Windows läuft der Apache üblicherweise als Dienst + (Windows NT, 2000 und XP) oder als Konsolenanwendung (Windows 9x und + ME). Für Einzelheiten lesen Sie bitte Apache als Dienst betreiben + und Apache als Konsolenanwendung betreiben.

    + +

    Unter Unix wird das httpd-Programm als Daemon + ausgeführt, der im Hintergrund fortlaufend aktiv ist, um + Anfragen zu bearbeiten. Dieses Dokument beschreibt, wie + httpd aufgerufen wird.

    +
    + +Beenden und Neustarten +httpd +apachectl + +
    Wie der Apache startet + +

    Wenn die in der Konfigurationsdatei angegebene Listen-Anweisung auf die Voreinstellung + von 80 gesetzt ist (oder einen anderen Port unterhalb von 1024), dann + müssen Sie root-Berechtigung besitzen, um den Apache starten + zu können. Nur dann kann er sich an diesen privilegierten + Port binden. Sobald der Server gestartet ist und einige vorbereitende + Aktionen wie das Öffnen seiner Log-Dateien ausgeführt hat, + startet er mehrere Kind-Prozesse, welche die Arbeit erledigen: + das Lauschen auf und Beantworten von Anfragen von Clients. Der + Haupt-httpd-Prozess läuft unter dem Benutzer root + weiter, die Kind-Prozesse jedoch werden unter weniger privilegierten + Benutzerkennungen ausgeführt. Dies wird von dem ausgewählten + Multi-Processing-Modul gesteuert.

    + +

    Die Verwendung des Steuerskripts apachectl ist die + empfohlene Methode, das httpd-Programm zu starten. + Dieses Skript setzt verschiedene Umgebungsvariablen, die für die + korrekte Funktion von httpd unter einigen + Betriebssystemen notwendig sind, und startet dann das + httpd-Programm. apachectl + reicht alle Kommandozeilenargumente durch, so dass alle + httpd-Optionen auch mit apachectl + verwendet werden können. Um den korrekten Ablageort des + httpd-Programms sowie einige Kommandozeilenargumente + anzugeben, die Sie immer verwenden möchten, können + Sie auch das Skript apachectl direkt editieren und die + Variable HTTPD am Anfang ändern.

    + +

    Das Erste was httpd macht, wenn es startet, ist das + Suchen und Einlesen der Konfigurationsdatei httpd.conf. + Der Ablageort dieser Datei wird zur Kompilierungszeit festgelegt. Es ist + aber möglich, den Ablageort zur Laufzeit anzugeben, indem die + Kommandozeilenoption -f wie folgt verwendet wird:

    + + /usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf + +

    Wenn während des Starts alles gutgeht, trennt sich der Server + vom Terminal ab und die Eingabeaufforderung erscheint gleich darauf + wieder. Dies zeigt an, dass der Server hochgefahren ist und läuft. + Sie können nun Ihren Browser benutzen, um Verbindung zum Server + aufzunehmen und sich die Testseite im DocumentRoot-Verzeichnis anzusehen wie auch + die lokale Kopie der Dokumentation, die von dieser Seite aus verlinkt + ist.

    +
    + +
    Fehler während des Hochfahrens + +

    Wenn der Apache während des Hochfahrens einen schweren Fehler + feststellt, schreibt er entweder eine Nachricht, die das Problem + näher schildert, auf die Konsole oder ins ErrorLog, bevor er sich selbst beendet. + Eine der häufigsten Fehlermeldungen ist "Unable + to bind to Port ..." "Kann nicht an Port ... + binden". Diese Meldung wird üblicherweise verursacht:

    + +
      +
    • entweder durch den Versuch, den Server an einem privilegierten + Port zu starten, während man nicht als Benutzer root angemeldet + ist,
    • + +
    • oder durch den Versuch, den Server zu starten, wenn bereits eine + andere Instanz des Apache oder ein anderer Webserver an den gleichen + Port gebunden ist.
    • +
    + +

    Für weitere Anleitungen zur Fehlerbehebung lesen Sie bitte die + Apache-FAQ.

    +
    + +
    Beim Bootvorgang starten + +

    Wenn Sie möchten, dass Ihr Server direkt nach einem + System-Neustart weiterläuft, sollten Sie einen Aufruf von + apachectl zu den Startdateien Ihres Systems + hinzufügen (üblicherweise rc.local oder + eine Datei in einem rc.N-Verzeichnis). Dies startet + den Apache als root. Stellen Sie zuvor jedoch sicher, dass Ihr + Server hinsichtlich Sicherheit und Zugriffsbeschränkungen + richtig konfiguriert ist.

    + +

    Das apachectl-Skript ist dafür ausgelegt, wie + ein Standard-SysV-init-Skript zu arbeiten. Es akzeptiert die Argumente + start, restart und stop + und übersetzt sie in die entsprechenden Signale für + httpd. Daher können Sie oftmals + einfach apachectl in das entsprechende init-Verzeichnis + linken. Überprüfen Sie bitte auf jeden Fall die genauen + Anforderungen Ihres Systems.

    +
    + +
    Weitere Informationen + +

    Weitere Informationen über Kommandozeilenoptionen von + httpd und apachectl sowie anderen + Hilfsprogrammen, die dem Server beigefügt sind, sind auf der + Seite Server und Hilfsprogramme + verfügbar. Es existiert außerdem eine Dokumentation + aller in der Apache-Distribution enthaltenen Module und der von ihnen bereitgestellten + Direktiven.

    +
    + +
    diff --git a/trunk/docs/manual/invoking.xml.es b/trunk/docs/manual/invoking.xml.es new file mode 100644 index 0000000000..9818ec5a39 --- /dev/null +++ b/trunk/docs/manual/invoking.xml.es @@ -0,0 +1,161 @@ + + + + + + + + + + iniciar Apache + + +

    En Windows, Apache se ejecuta normalmente como un servicio en + Windows NT, 2000 and XP, y como una aplicacion de consola en + Windows 9x y ME. Para obtener más información, consulte + Ejecutar Apache como un + servicio y Ejecutar + Apache como una aplicación de consola.

    + +

    En Unix, el programa httpd se + ejecuta como un demonio (daemon) de forma silenciosa y atiende las + peticiones que le lleguen. Este documento describe cómo + invocar el programa httpd.

    +
    + +Parar y reiniciar Apache +httpd +apachectl + +
    Cómo iniciar Apache + +

    Si el puerto especificado en la directiva Listen del fichero de + configuración es el que viene por defecto, es decir, el + puerto 80 (o cualquier otro puerto por debajo del 1024), entonces + es necesario tener privilegios de usuario root (superusuario) para + iniciar Apache, de modo que pueda establecerse una conexión a + través de esos puertos privilegiados. Una vez que el servidor + Apache se ha iniciado y ha completado algunas tareas preliminares, + tales como abrir sus ficheros log, lanzará varios procesos, + procesos hijo, que hacen el trabajo de escuchar y atender + las peticiones de los clientes. El proceso principal, + httpd continúa ejecutandose como root, pero los + procesos hijo se ejecutan con menores privilegios de usuario. + Esto lo controla el Módulo de + MultiProcesamiento (MPM) seleccionado.

    + +

    La forma recomendada para invocar el ejecutable + httpd es usando el script de control apachectl. Este script fija + determinadas variables de entorno que son necesarias para que + httpd funcione correctamente en el sistema operativo, + y después invoca el binario httpd. + apachectl pasa a httpd cualquier argumento que se le + pase a través de la línea de comandos, de forma que + cualquier opción de httpd puede ser usada + también con apachectl. Puede editar + directamente el script apachectl y cambiar la + variable HTTPD variable que está al principio y + que especifica la ubicación exacta en la que está el + binario httpd y cualquier argumento de línea de + comandos que quiera que esté siempre presente.

    + +

    La primera cosa que hace httpd cuando es invocado + es localizar y leer el fichero de + configuración httpd.conf. El lugar en el que + está ese fichero se determina al compilar, pero también + es posible especificar la ubicación en la que se encuentra al + iniciar el servidor Apache usando la opción de línea de + comandos -f

    + +/usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf + +

    Si todo va bien durante el arranque, la sesión de terminal + se suspenderá un momento y volverá a estar activa casi + inmediatamente. Esto quiere decir que el servidor está activo + y funcionando. Puede usar su navegador para conectarse al + servidor y ver la pagina de prueba que hay en el directorio + DocumentRoot y la copia local + de esta documentación a la que se puede acceder desde esa + página.

    +
    + +
    Errores Durante el Arranque + +

    Si Apache encuentra una error irrecuperable durante el + arranque, escribirá un mensaje describiendo el problema en la + consola o en el archivo ErrorLog antes de abortar la + ejecución. Uno de los mensajes de error más comunes es + "Unable to bind to Port ...". Cuando se recibe este + mensaje es normalmente por alguna de las siguientes razones:

    + +
      +
    • Está intentando iniciar el servidor Apache en un puerto + privilegiado (del 0 al 1024) sin haber hecho login como usuario + root; ó
    • + +
    • Está intentando iniciar el servidor Apache mientras + está ya ejecutando Apache o algún otro servidor web en + el mismo puerto.
    • +
    + +

    Puede encontrar más información sobre cómo + solucionar problemas, en la sección de Preguntas Frecuentes de Apache.

    +
    + +
    Iniciar Apache al Iniciar el Sistema + +

    Si quiere que el servidor Apache continú su ejecución + después de reiniciar el sistema, debe añadir una llamada + a apachectl en sus archivos de arranque (normalmente + rc.local o un fichero en ese directorio del tipo + rc.N). Esto iniciará Apache como usuario + root. Antes de hacer esto, asegúrese de que la + configuración de seguridad y las restricciones de acceso de + su servidor Apache están correctamente configuradas.

    + +

    El script apachectl está diseñado para + actuar como un script estandar de tipo SysV init; puede tomar los + argumentos start, restart, y + stop y traducirlos en las señales apropiadas + para httpd. De esta manera, casi siempre puede + simplemente enlazar apachectl con el directorio init + adecuado. Pero asegúrese de comprobar los requisitos exactos + de su sistema.

    +
    + +
    Información Adicional + +

    En la sección El Servidor y Programas + de Soporte puede encontrar más información sobre + las opciones de línea de comandos que puede pasar a httpd y apachectl asi como sobre otros + programas de soporte incluidos con el servidor Apache. + También hay documentación sobre todos los módulos incluidos con la distribucion de + Apache y sus correspondientes directivas asociadas.

    +
    + +
    + diff --git a/trunk/docs/manual/invoking.xml.ja b/trunk/docs/manual/invoking.xml.ja new file mode 100644 index 0000000000..273d5a1c45 --- /dev/null +++ b/trunk/docs/manual/invoking.xml.ja @@ -0,0 +1,151 @@ + + + + + + + + + + Apache $B$N5/F0(B + + +

    Windows $B>e$G$O!"(BApache $B$ODL>o$O(B + Windows NT, 2000, XP $B$G$O%5!<%S%9$H$7$F!"(BWindows 9x, ME + $B$G$O%3%s%=!<%k%"%W%j%1!<%7%g%s$H$7$F\:Y$K4X$7$F$O!"!V(B + $B%5!<%S%9$H$7$F$B!W$H!V(B + $B%3%s%=!<%k%"%W%j%1!<%7%g%s$H$7$F$B!W$r$4Mw2<$5$$!#(B

    + +

    Unix$B$G$O!"(Bhttpd + $B%W%m%0%i%`$,!"%P%C%/%0%i%&%s%I$G>o$K%j%/%(%9%H=hM}$r9T$&(B + $B%G!<%b%s$H$7$Fhttpd $B$r5/F0$9$k$+$K$D$$$F5-=R$7$F$$$^$9!#(B

    +
    + +$BDd;_$H:F5/F0(B +httpd +apachectl + +
    Apache $B$N5/F0J}K!(B + +

    $B$b$7!"@_Dj%U%!%$%kCf$G;XDj$5$l$F$$$k(B + Listen + $B$,%G%U%)%k%H$N(B 80 ($B$b$7$/$O(B 1024 $B0J2<$NB>$N%]!<%H(B) + $B$G$"$k>l9g$O!"(BApache $B$r5/F0$9$k$?$a$K$O(B root + $B8"8B$,I,MW$K$J$j$^$9$,!"(B + $B$3$l$O$3$NFC8"%]!<%H$K%P%$%s%I$9$k$?$a$G$9!#(B + $B5/F0$7$F!"0lEY%m%0%U%!%$%k$r3+$/$H$$$C$?=`Hw$N$?$a$N(B + $BF0:n$r4v$D$+$B;R(B$B%W%m%;%9$r5/F0$7$^$9!#(B + $B%a%$%s$N(B httpd $B%W%m%;%9$O(B root $B8"8B$GAv$jB3$1$^$9$,!"(B + $B;R%W%m%;%9$O$b$C$HDc$$8"8B$GAv$j$^$9!#(B + $B$3$l$OA*Br$7$?(B$B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B$B$G@)8f$5$l$^$9!#(B

    + +

    $B?d>)$N(B httpd $Bapachectl + $B@)8f%9%/%j%W%H$r;HMQ$9$kJ}K!$G$9!#$3$N%9%/%j%W%H$O!"(Bhttpd + $B$,%*%Z%l!<%F%#%s%0%7%9%F%`>e$G@5>o$KF0:n$9$k$h$&$KI,MW$J4D6-JQ?t$r(B + $BE,@Z$K@_Dj$7$F!"(Bhttpd $B%P%$%J%j$r5/F0$7$^$9!#(B + apachectl $B$O$I$s$J%3%^%s%I%i%$%s0z?t$bDL2a$5$;$^$9$N$G!"(B + httpd $B$N$I$N%3%^%s%I%i%$%s%*%W%7%g%s$b(B + apchectl $B$N%*%W%7%g%s$H$7$F;HMQ$G$-$^$9!#(B + $B$^$?!"(Bapchectl $B%9%/%j%W%H$rD>@\JT=8$7!"(B + $B%9%/%j%W%H@hF,IU6a$N(B HTTPD $BJQ?t$rJQ99$9$k$3$H$G!"(B + httpd $B%P%$%J%j$N@5$7$$0LCV$r;XDj$7$?$j!"(B$B>o$K(B + $BIU2C$5$;$k%3%^%s%I%i%$%s0z?t$r;XDj$7$?$j$9$k$3$H$,$G$-$^$9!#(B

    + +

    httpd $B$,5/F0$5$l$F$^$::G=i$K$9$k$3$H$O!"(B + $B@_Dj%U%!%$%k(B + httpd.conf $B$N0LCV$rFCDj$7$FFI$_9~$`$3$H$G$9!#(B + $B$3$N%U%!%$%k$N0LCV$O%3%s%Q%$%k;~$K@_Dj$5$l$^$9$,!"-f $B%3%^%s%I%i%$%s%*%W%7%g%s$r;H$C$F(B + $B0LCV$r;XDj$9$k$3$H$b$G$-$^$9!#Nc$($P + +/usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf + +

    $B%9%?!<%H%"%C%W$,K|;v>euBV$r<($7$F$$$^$9!#(B + $B$=$N8e$O%V%i%&%6$G%5!<%P$K@\B3$7$F!"(B + DocumentRoot + $B%G%#%l%/%H%j$N%F%9%H%Z!<%8$d$=$3$+$i%j%s%/$5$l$F$$$k(B + $B%m!<%+%k$N%I%-%e%a%s%H$r8+$k$3$H$,$G$-$k$G$7$g$&!#(B

    +
    + +
    $B5/F0;~$N%(%i!<(B + +

    Apache $B$O!"5/F0;~$KCWL?E*$JLdBj$KAx6x$9$k$H!"(B + $B=*N;$9$kA0$K!"%3%s%=!<%k$+(B + ErrorLog + $B$N$I$A$i$+$KLdBj$r5-=R$7$?%a%C%;!<%8$r=PNO$7$^$9!#(B + $B:G$b$h$/$"$k%(%i!<%a%C%;!<%8$O(B + $B!V(BUnable to bind to Port ...$B!W(B + $B$G$9!#$3$N%a%C%;!<%8$OIaDL$O + +

      +
    • root $B$G%m%0%$%s$7$F$$$J$$;~$K!"(B + $BFC8"%]!<%H$G%5!<%P$r5/F0$7$h$&$H$7$?!#(B
    • + +
    • $BF1$8%]!<%H$K4{$K%P%$%s%I$5$l$F$$$k(B Apache + $B$,$b$&0l$D$"$k$H$-$dB>$N%&%'%V%5!<%P$,B8:_$7$F$$$k;~$K!"(B + $B%5!<%P$r3+;O$7$h$&$H$7$?!#(B
    • +
    + +

    $B$h$jB?$/$NLdBj2r7h$NJ}:v$N@bL@$O!"(B + Apache FAQ $B$r$4Mw2<$5$$!#(B

    +
    + +
    $B%V!<%H;~$N5/F0(B + +

    $B%7%9%F%`$,%j%V!<%H$7$?8e$G$b(B + $B%5!<%P$,l9g$O!"(B + apachectl + $B$r8F$S=P$9$b$N$r%7%9%F%`%9%?!<%H%"%C%W%U%!%$%k(B + ($BDL>o(B rc.local $B$d(B rc.N + $BFb$N%U%!%$%k(B) $B$KDI2C$7$J$1$l$P$J$j$^$;$s!#(B + $B$3$NJ}K!$G$O(B Apache $B$r(B root $B8"8B$G5/F0$7$^$9!#(B + $B$3$l$r$9$kA0$K!"%;%-%e%j%F%#$d%"%/%;%9@)8B$,(B + $BE,@Z$K@_Dj$5$l$F$$$F$$$k$3$H$r3NG'$7$F$/$@$5$$!#(B

    + +

    apachectl $B%9%/%j%W%H$ODL>o$O!"I8=`E*$J(B SysV init + $B%9%/%j%W%H$H$7$FF0:n$9$k$h$&$K@_7W$5$l$F$$$^$9!#(B + start, restart, stop + $B$H$$$C$?0z?t$r$H$C$F!"(Bhttpd + $B$X$NE,@Z$J%7%0%J%k$KJQ49$7$^$9!#(B + $B$G$9$+$i!"DL>o$OC1$KE,@Z$J(B init $B%G%#%l%/%H%jFb$+$i(B + apachectl $B$X%j%s%/$9$k$3$H$,$G$-$^$9!#$7$+$7!"(B + $BG0$N$?$a%7%9%F%`$NMW5a$K9gCW$7$F$$$k$3$H$r3NG'$7$F$/$@$5$$!#(B

    +
    + +
    $BDI2C>pJs(B + +

    httpd $B$d(B + apachectl$B!"%5!<%P$K4^$^$l$F$$$?$=$NB>Jd=u%W%m%0%i%`$N!"(B + $B%3%^%s%I%i%$%s%*%W%7%g%s$K4X$9$kDI2C>pJs$O!"(B + $B%5!<%P$HJd=u%W%m%0%i%`(B$B%Z!<%8$K(B + $B5-:\$5$l$F$$$^$9!#(B + Apache $BG[I[$K4^$^$l$F$$$kA4(B$B%b%8%e!<%k(B$B!"(B + $B$=$l$K$h$C$FDs6!$5$l$k(B$B%G%#%l%/%F%#%V(B + $B$N%I%-%e%a%s%H$b$"$j$^$9!#(B

    +
    + + diff --git a/trunk/docs/manual/invoking.xml.ko b/trunk/docs/manual/invoking.xml.ko new file mode 100644 index 0000000000..4258ce6278 --- /dev/null +++ b/trunk/docs/manual/invoking.xml.ko @@ -0,0 +1,132 @@ + + + + + + + + + + ¾ÆÆÄÄ¡ ½ÃÀÛ + + +

    º¸Åë ¾ÆÆÄÄ¡´Â Windows NT, 2000, XP¿¡¼­´Â ¼­ºñ½º·Î, + Windows 95°ú ME¿¡¼­´Â ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàµÈ´Ù. ÀÚ¼¼ÇÑ + ³»¿ëÀº ¼­ºñ½º·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϱâ¿Í ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϱâ.

    + +

    À¯´Ð½º¿¡¼­ httpd + ÇÁ·Î±×·¥Àº ¹é±×¶ó¿îµå¿¡¼­ °è¼Ó ¿äûÀ» ó¸®ÇÏ´Â µ¥¸óÀ¸·Î + ½ÇÇàµÈ´Ù. ÀÌ ¹®¼­´Â httpd¸¦ ½ÃÀÛÇÏ´Â ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    +
    + +¾ÆÆÄÄ¡ Áß´Ü°ú Àç½ÃÀÛ +httpd +apachectl + +
    ¾î¶»°Ô ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇϳª + +

    ¼³Á¤ÆÄÀÏ¿¡¼­ ListenÀÌ ±âº»°ªÀÎ 80(ȤÀº + 1024ÀÌÇÏÀÇ ´Ù¸¥ Æ÷Æ®)À̶ó¸é ÀÌ Æ¯±Ç Æ÷Æ®¿¡ ¿¬°áÇϱâÀ§ÇØ + root ±ÇÇÑÀÌ ÇÊ¿äÇÏ´Ù. ¼­¹ö´Â ½ÃÀÛÇÏ¿© ·Î±×ÆÄÀÏÀ» ¿©´Â µîÀÇ + ¸î¸î ±âÃÊÀûÀÎ ÀÛ¾÷À» ¸¶Ä£ÈÄ, Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ±â´Ù¸®°í + ÀÀ´äÇÏ´Â ÀÚ½Ä(child) ÇÁ·Î¼¼½º¸¦ ¿©·¯°³ ¶ç¿î´Ù. + ÁÖ httpd ÇÁ·Î¼¼½º´Â °è¼Ó root »ç¿ëÀÚ·Î ½ÇÇàµÇÁö¸¸, + ÀÚ½Ä ÇÁ·Î¼¼½ºµéÀº ´õ ±ÇÇÑÀÌ ÀÛÀº »ç¿ëÀÚ·Î ½ÇÇàµÈ´Ù. ÀÌ´Â + ¼±ÅÃÇÑ ´ÙÁßó¸® ¸ðµâ·Î Á¶Á¤ÇÑ´Ù.

    + +

    apachectl + ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ¿© httpd ½ÇÇàÆÄÀÏÀ» ½ÃÀÛÇϱæ + ±ÇÀåÇÑ´Ù. ÀÌ ½ºÅ©¸³Æ®´Â httpd°¡ ¸î¸î + ¿î¿µÃ¼Á¦¿¡¼­ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ È¯°æº¯¼öµéÀ» + ¼³Á¤ÇÏ°í httpd ½ÇÇàÆÄÀÏÀ» ½ÃÀÛÇÑ´Ù. + apachectlÀº ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ ±×´ë·Î ³Ñ±â±â¶§¹®¿¡, + httpdÀÇ ¾î¶² ¿É¼ÇÀÌ¶óµµ apachectl¿¡ + »ç¿ë°¡´ÉÇÏ´Ù. ¶Ç, apachectl ½ºÅ©¸³Æ®ÀÇ ¾ÕºÎºÐ¿¡ + ³ª¿À´Â HTTPD º¯¼ö¸¦ httpd ½ÇÇàÆÄÀÏÀÌ + ÀÖ´Â À§Ä¡¿Í Ç×»ó »ç¿ëÇÒ ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®·Î Á÷Á¢ + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    httpd¸¦ ½ÇÇàÇÏ¸é ¸ÕÀú ¼³Á¤ÆÄÀÏ httpd.conf¸¦ + ã¾Æ¼­ Àд´Ù. ÀÌ ÆÄÀÏÀÇ À§Ä¡´Â ÄÄÆÄÀÏ Áß¿¡ ÁöÁ¤Çϳª, ½ÇÇà½Ã + ´ÙÀ½°ú °°ÀÌ -f ¸í·ÉÇà ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù.

    + +/usr/local/apache2/bin/apachectl -f + /usr/local/apache2/conf/httpd.conf + +

    ½ÃÀÛÇÏ´Â °úÁ¤¿¡¼­ ¹®Á¦°¡ ¾ø´Ù¸é, ¼­¹ö´Â Å͹̳ο¡¼­ + ¶³¾îÁö°í ¸í·É ÇÁ·ÒÇÁÆ®°¡ °ÅÀÇ Áï½Ã ³ª¿À°ÔµÈ´Ù. ÀÌ´Â ¼­¹ö°¡ + ½ÇÇàµÊÀ» ÀǹÌÇÑ´Ù. ºê¶ó¿ìÀú·Î ¼­¹ö¿¡ ¿¬°áÇÏ¿© DocumentRoot µð·ºÅ丮¿¡ ÀÖ´Â + Å×½ºÆ® ÆäÀÌÁö¿Í ±× ÆäÀÌÁö¿¡ ¸µÅ©µÈ (·ÎÄÃÄ«ÇÇ) ¼³¸í¼­¸¦ º¼ + ¼ö ÀÖ´Ù.

    +
    + +
    ½ÃÀÛÁß ¿À·ù + +

    ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇÏ´Â °úÁ¤Áß¿¡ ½É°¢ÇÑ ¹®Á¦°¡ ¹ß»ýÇϸé, + Á¾·áÇϱâ Àü¿¡ ¹®Á¦¸¦ ¾Ë¸®´Â ¹®±¸¸¦ ÄܼÖÀ̳ª ErrorLog¿¡ ¾´´Ù. °¡Àå ÈçÇÑ ¿À·ù¹® Áß + Çϳª´Â "Unable to bind to Port ..."ÀÌ´Ù. + ÀÌ ¸Þ¼¼Áö´Â º¸Åë ´ÙÀ½ µÎ °æ¿ì¿¡ ¹ß»ýÇÑ´Ù:

    + +
      +
    • root »ç¿ëÀÚ·Î ·Î±×ÀÎÇÏÁö ¾Ê°í Ư±Ç Æ÷Æ®¿¡ ¼­¹ö¸¦ + ½ÃÀÛÇÏ·Á ÇÑ °æ¿ì. ȤÀº
    • + +
    • ÀÌ¹Ì ¾ÆÆÄÄ¡³ª ´Ù¸¥ À¥¼­¹ö°¡ »ç¿ëÁßÀÎ Æ÷Æ®¿¡ + ¼­¹ö¸¦ ½ÃÀÛÇÏ·Á ÇÑ °æ¿ì.
    • +
    + +

    ±âŸ ¹®Á¦ÇØ°á ¹æ¹ýÀº ¾ÆÆÄÄ¡ FAQ¸¦ + Âü°íÇ϶ó.

    +
    + +
    ºÎÆÃÇÒ¶§ ½ÃÀÛÇϱâ + +

    ½Ã½ºÅÛÀÌ Àç½ÃÀÛÇÑ ÈÄ¿¡µµ ¼­¹ö°¡ °è¼Ó ½ÇÇàµÇ±æ ¹Ù¶õ´Ù¸é, + ½Ã½ºÅÛ ½ÃÀÛÆÄÀÏ(º¸Åë rc.localÀ̳ª rc.N + µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏ)¿¡ apachectlÀ» Ãß°¡ÇØ¾ß + ÇÑ´Ù. ÀÌ °æ¿ì ¾ÆÆÄÄ¡´Â root·Î ½ÃÀ۵ȴÙ. ÀÌÀü¿¡ ¼­¹öÀÇ º¸¾ÈÀ̳ª + Á¢±Ù Á¦ÇÑ(ÆÄÀϱÇÇÑ)ÀÌ ¿Ã¹Ù·Î ¼³Á¤µÇ¾ú´ÂÁö È®ÀÎÇ϶ó.

    + +

    apachectlÀº Ç¥ÁØ SysV init ½ºÅ©¸³Æ®¿Í ºñ½ÁÇÏ°Ô + µ¿ÀÛÇϵµ·Ï ¸¸µé¾îÁ³´Ù. ½ºÅ©¸³Æ®´Â ¾Æ±Ô¸ÕÆ®·Î start, + restart, stopÀ» ¹ÞÀ¸¸é °¢°¢ ÀûÀýÇÑ + ½Ã±×³ÎÀ» httpd¿¡ º¸³½´Ù. ±×·¡¼­ º¸ÅëÀº + apachectlÀ» ÀûÀýÇÑ init µð·ºÅ丮·Î ¸µÅ©¸¦ °É¸éµÈ´Ù. + ±×·¯³ª »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ Á¤È®ÇÑ ¿ä±¸»çÇ×À» È®ÀÎÇ϶ó.

    +
    + +
    Ãß°¡ Á¤º¸ + +

    httpd¿Í apachectl, ±âŸ ¼­¹ö¿¡ + Æ÷ÇÔµÈ Áö¿ø ÇÁ·Î±×·¥µéÀÇ ¸í·ÉÇà ¿É¼ÇÀº + ¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ ÆäÀÌÁö¸¦ + Âü°íÇ϶ó. ¶Ç ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡´Â ¸ðµç ¸ðµâ°ú + ±×µéÀÌ Á¦°øÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¹®¼­°¡ ÀÖ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/invoking.xml.meta b/trunk/docs/manual/invoking.xml.meta new file mode 100644 index 0000000000..5e379f5493 --- /dev/null +++ b/trunk/docs/manual/invoking.xml.meta @@ -0,0 +1,15 @@ + + + + invoking + / + . + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/license.html b/trunk/docs/manual/license.html new file mode 100644 index 0000000000..11472e452b --- /dev/null +++ b/trunk/docs/manual/license.html @@ -0,0 +1,3 @@ +URI: license.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/license.html.en b/trunk/docs/manual/license.html.en new file mode 100644 index 0000000000..94e17923f2 --- /dev/null +++ b/trunk/docs/manual/license.html.en @@ -0,0 +1,238 @@ + + + +The Apache License, Version 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    The Apache License, Version 2.0

    +
    +

    Available Languages:  en 

    +
    + +

    Apache License
    + Version 2.0, January 2004
    + http://www.apache.org/licenses/

    + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

    + +
      +
    1. Definitions
      + +

      "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document.

      + +

      "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License.

      + +

      "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity.

      + +

      "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License.

      + +

      "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files.

      + +

      "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types.

      + +

      "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below).

      + +

      "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof.

      + +

      "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution."

      + +

      "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work.

    2. + +
    3. Grant of Copyright License. Subject to the terms + and conditions of this License, each Contributor hereby grants to You + a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form.
    4. + +
    5. Grant of Patent License. Subject to the terms + and conditions of this License, each Contributor hereby grants to You a + perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed.
    6. + +
    7. Redistribution. You may reproduce and distribute + copies of the Work or Derivative Works thereof in any medium, with or + without modifications, and in Source or Object form, provided that You + meet the following conditions: + +
        +
      1. You must give any other recipients of the Work or + Derivative Works a copy of this License; and
      2. + +
      3. You must cause any modified files to carry prominent notices + stating that You changed the files; and
      4. + +
      5. You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and
      6. + +
      7. If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License.
      8. +
      + +

      You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License.

    8. + +
    9. Submission of Contributions. Unless You explicitly + state otherwise, any Contribution intentionally submitted for inclusion + in the Work by You to the Licensor shall be under the terms and + conditions of this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions.
    10. + +
    11. Trademarks. This License does not grant permission + to use the trade names, trademarks, service marks, or product names of + the Licensor, except as required for reasonable and customary use in + describing the origin of the Work and reproducing the content of the + NOTICE file.
    12. + +
    13. Disclaimer of Warranty. Unless required by + applicable law or agreed to in writing, Licensor provides the Work (and + each Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License.
    14. + +
    15. Limitation of Liability. In no event and under no + legal theory, whether in tort (including negligence), contract, or + otherwise, unless required by applicable law (such as deliberate and + grossly negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages.
    16. + +
    17. Accepting Warranty or Additional Liability. While + redistributing the Work or Derivative Works thereof, You may choose to + offer, and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability.
    18. +
    + +

    END OF TERMS AND CONDITIONS

    + +

    APPENDIX: How to apply the Apache License to your + work.

    + +

    To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives.

    + +
    Copyright [yyyy] [name of copyright owner]
    +
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +    http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/license.xml b/trunk/docs/manual/license.xml new file mode 100644 index 0000000000..95bfbac643 --- /dev/null +++ b/trunk/docs/manual/license.xml @@ -0,0 +1,240 @@ + + + + + + + + + +The Apache License, Version 2.0 + + +

    Apache License
    + Version 2.0, January 2004
    + http://www.apache.org/licenses/

    + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

    + +
      +
    1. Definitions
      + +

      "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document.

      + +

      "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License.

      + +

      "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity.

      + +

      "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License.

      + +

      "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files.

      + +

      "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types.

      + +

      "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below).

      + +

      "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof.

      + +

      "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution."

      + +

      "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work.

    2. + +
    3. Grant of Copyright License. Subject to the terms + and conditions of this License, each Contributor hereby grants to You + a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form.
    4. + +
    5. Grant of Patent License. Subject to the terms + and conditions of this License, each Contributor hereby grants to You a + perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed.
    6. + +
    7. Redistribution. You may reproduce and distribute + copies of the Work or Derivative Works thereof in any medium, with or + without modifications, and in Source or Object form, provided that You + meet the following conditions: + +
        +
      1. You must give any other recipients of the Work or + Derivative Works a copy of this License; and
      2. + +
      3. You must cause any modified files to carry prominent notices + stating that You changed the files; and
      4. + +
      5. You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and
      6. + +
      7. If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License.
      8. +
      + +

      You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License.

    8. + +
    9. Submission of Contributions. Unless You explicitly + state otherwise, any Contribution intentionally submitted for inclusion + in the Work by You to the Licensor shall be under the terms and + conditions of this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions.
    10. + +
    11. Trademarks. This License does not grant permission + to use the trade names, trademarks, service marks, or product names of + the Licensor, except as required for reasonable and customary use in + describing the origin of the Work and reproducing the content of the + NOTICE file.
    12. + +
    13. Disclaimer of Warranty. Unless required by + applicable law or agreed to in writing, Licensor provides the Work (and + each Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License.
    14. + +
    15. Limitation of Liability. In no event and under no + legal theory, whether in tort (including negligence), contract, or + otherwise, unless required by applicable law (such as deliberate and + grossly negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages.
    16. + +
    17. Accepting Warranty or Additional Liability. While + redistributing the Work or Derivative Works thereof, You may choose to + offer, and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability.
    18. +
    + +

    END OF TERMS AND CONDITIONS

    + +

    APPENDIX: How to apply the Apache License to your + work.

    + +

    To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives.

    + + +
    Copyright [yyyy] [name of copyright owner]
    +
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +    http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +
    +
    +
    + diff --git a/trunk/docs/manual/license.xml.meta b/trunk/docs/manual/license.xml.meta new file mode 100644 index 0000000000..326f784edb --- /dev/null +++ b/trunk/docs/manual/license.xml.meta @@ -0,0 +1,11 @@ + + + + license + / + . + + + en + + diff --git a/trunk/docs/manual/logs.html b/trunk/docs/manual/logs.html new file mode 100644 index 0000000000..0ab020d445 --- /dev/null +++ b/trunk/docs/manual/logs.html @@ -0,0 +1,11 @@ +URI: logs.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: logs.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: logs.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/logs.html.en b/trunk/docs/manual/logs.html.en new file mode 100644 index 0000000000..acfaee16c4 --- /dev/null +++ b/trunk/docs/manual/logs.html.en @@ -0,0 +1,583 @@ + + + +Log Files - Apache HTTP Server + + + + + +
    <-
    +

    Log Files

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    In order to effectively manage a web server, it is necessary + to get feedback about the activity and performance of the + server as well as any problems that may be occurring. The Apache + HTTP Server provides very comprehensive and flexible logging + capabilities. This document describes how to configure its + logging capabilities, and how to understand what the logs + contain.

    +
    + +
    top
    +
    +

    Security Warning

    + + +

    Anyone who can write to the directory where Apache is + writing a log file can almost certainly gain access to the uid + that the server is started as, which is normally root. Do + NOT give people write access to the directory the logs + are stored in without being aware of the consequences; see the + security tips document + for details.

    + +

    In addition, log files may contain information supplied + directly by the client, without escaping. Therefore, it is + possible for malicious clients to insert control-characters in + the log files, so care must be taken in dealing with raw + logs.

    +
    top
    +
    +

    Error Log

    + + + + +

    The server error log, whose name and location is set by the + ErrorLog directive, is the + most important log file. This is the place where Apache httpd + will send diagnostic information and record any errors that it + encounters in processing requests. It is the first place to + look when a problem occurs with starting the server or with the + operation of the server, since it will often contain details of + what went wrong and how to fix it.

    + +

    The error log is usually written to a file (typically + error_log on unix systems and + error.log on Windows and OS/2). On unix systems it + is also possible to have the server send errors to + syslog or pipe them to a + program.

    + +

    The format of the error log is relatively free-form and + descriptive. But there is certain information that is contained + in most error log entries. For example, here is a typical + message.

    + +

    + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test +

    + +

    The first item in the log entry is the date and time of the + message. The second entry lists the severity of the error being + reported. The LogLevel + directive is used to control the types of errors that are sent + to the error log by restricting the severity level. The third + entry gives the IP address of the client that generated the + error. Beyond that is the message itself, which in this case + indicates that the server has been configured to deny the + client access. The server reports the file-system path (as + opposed to the web path) of the requested document.

    + +

    A very wide variety of different messages can appear in the + error log. Most look similar to the example above. The error + log will also contain debugging output from CGI scripts. Any + information written to stderr by a CGI script will + be copied directly to the error log.

    + +

    It is not possible to customize the error log by adding or + removing information. However, error log entries dealing with + particular requests have corresponding entries in the access log. For example, the above example + entry corresponds to an access log entry with status code 403. + Since it is possible to customize the access log, you can + obtain more information about error conditions using that log + file.

    + +

    During testing, it is often useful to continuously monitor + the error log for any problems. On unix systems, you can + accomplish this using:

    + +

    + tail -f error_log +

    +
    top
    +
    +

    Access Log

    + + + + +

    The server access log records all requests processed by the + server. The location and content of the access log are + controlled by the CustomLog + directive. The LogFormat + directive can be used to simplify the selection of + the contents of the logs. This section describes how to configure the server + to record information in the access log.

    + +

    Of course, storing the information in the access log is only + the start of log management. The next step is to analyze this + information to produce useful statistics. Log analysis in + general is beyond the scope of this document, and not really + part of the job of the web server itself. For more information + about this topic, and for applications which perform log + analysis, check the + Open Directory or + Yahoo.

    + +

    Various versions of Apache httpd have used other modules and + directives to control access logging, including + mod_log_referer, mod_log_agent, and the + TransferLog directive. The CustomLog directive now subsumes + the functionality of all the older directives.

    + +

    The format of the access log is highly configurable. The format + is specified using a format string that looks much like a C-style + printf(1) format string. Some examples are presented in the next + sections. For a complete list of the possible contents of the + format string, see the mod_log_config format strings.

    + +

    Common Log Format

    + + +

    A typical configuration for the access log might look as + follows.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +

    + +

    This defines the nickname common and + associates it with a particular log format string. The format + string consists of percent directives, each of which tell the + server to log a particular piece of information. Literal + characters may also be placed in the format string and will be + copied directly into the log output. The quote character + (") must be escaped by placing a back-slash before + it to prevent it from being interpreted as the end of the + format string. The format string may also contain the special + control characters "\n" for new-line and + "\t" for tab.

    + +

    The CustomLog + directive sets up a new log file using the defined + nickname. The filename for the access log is relative to + the ServerRoot unless it + begins with a slash.

    + +

    The above configuration will write log entries in a format + known as the Common Log Format (CLF). This standard format can + be produced by many different web servers and read by many log + analysis programs. The log file entries produced in CLF will + look something like this:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 +

    + +

    Each part of this log entry is described below.

    + +
    +
    127.0.0.1 (%h)
    + +
    This is the IP address of the client (remote host) which + made the request to the server. If HostnameLookups is + set to On, then the server will try to determine + the hostname and log it in place of the IP address. However, + this configuration is not recommended since it can + significantly slow the server. Instead, it is best to use a + log post-processor such as logresolve to determine + the hostnames. The IP address reported here is not + necessarily the address of the machine at which the user is + sitting. If a proxy server exists between the user and the + server, this address will be the address of the proxy, rather + than the originating machine.
    + +
    - (%l)
    + +
    The "hyphen" in the output indicates that the requested + piece of information is not available. In this case, the + information that is not available is the RFC 1413 identity of + the client determined by identd on the clients + machine. This information is highly unreliable and should + almost never be used except on tightly controlled internal + networks. Apache httpd will not even attempt to determine + this information unless IdentityCheck is set + to On.
    + +
    frank (%u)
    + +
    This is the userid of the person requesting the document + as determined by HTTP authentication. The same value is + typically provided to CGI scripts in the + REMOTE_USER environment variable. If the status + code for the request (see below) is 401, then this value + should not be trusted because the user is not yet + authenticated. If the document is not password protected, + this entry will be "-" just like the previous + one.
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + The time that the request was received. + The format is: + +

    + [day/month/year:hour:minute:second zone]
    + day = 2*digit
    + month = 3*letter
    + year = 4*digit
    + hour = 2*digit
    + minute = 2*digit
    + second = 2*digit
    + zone = (`+' | `-') 4*digit
    +

    + It is possible to have the time displayed in another format + by specifying %{format}t in the log format + string, where format is as in + strftime(3) from the C standard library. +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    The request line from the client is given in double + quotes. The request line contains a great deal of useful + information. First, the method used by the client is + GET. Second, the client requested the resource + /apache_pb.gif, and third, the client used the + protocol HTTP/1.0. It is also possible to log + one or more parts of the request line independently. For + example, the format string "%m %U%q %H" will log + the method, path, query-string, and protocol, resulting in + exactly the same output as "%r".
    + +
    200 (%>s)
    + +
    This is the status code that the server sends back to the + client. This information is very valuable, because it reveals + whether the request resulted in a successful response (codes + beginning in 2), a redirection (codes beginning in 3), an + error caused by the client (codes beginning in 4), or an + error in the server (codes beginning in 5). The full list of + possible status codes can be found in the HTTP + specification (RFC2616 section 10).
    + +
    2326 (%b)
    + +
    The last entry indicates the size of the object returned + to the client, not including the response headers. If no + content was returned to the client, this value will be + "-". To log "0" for no content, use + %B instead.
    +
    + + +

    Combined Log Format

    + + +

    Another commonly used format string is called the Combined + Log Format. It can be used as follows.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +

    + +

    This format is exactly the same as the Common Log Format, + with the addition of two more fields. Each of the additional + fields uses the percent-directive + %{header}i, where header can be + any HTTP request header. The access log under this format will + look like:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" +

    + +

    The additional fields are:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    The "Referer" (sic) HTTP request header. This gives the + site that the client reports having been referred from. (This + should be the page that links to or includes + /apache_pb.gif).
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    The User-Agent HTTP request header. This is the + identifying information that the client browser reports about + itself.
    +
    + + +

    Multiple Access Logs

    + + +

    Multiple access logs can be created simply by specifying + multiple CustomLog + directives in the configuration + file. For example, the following directives will create three + access logs. The first contains the basic CLF information, + while the second and third contain referer and browser + information. The last two CustomLog lines show how + to mimic the effects of the ReferLog and AgentLog directives.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +

    + +

    This example also shows that it is not necessary to define a + nickname with the LogFormat directive. Instead, + the log format can be specified directly in the CustomLog directive.

    + + +

    Conditional Logs

    + + +

    There are times when it is convenient to exclude certain + entries from the access logs based on characteristics of the + client request. This is easily accomplished with the help of environment variables. First, an + environment variable must be set to indicate that the request + meets certain conditions. This is usually accomplished with + SetEnvIf. Then the + env= clause of the CustomLog directive is used to + include or exclude requests where the environment variable is + set. Some examples:

    + +

    + # Mark requests from the loop-back interface
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # Mark requests for the robots.txt file
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # Log what remains
    + CustomLog logs/access_log common env=!dontlog +

    + +

    As another example, consider logging requests from + english-speakers to one log file, and non-english speakers to a + different log file.

    + +

    + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +

    + +

    Although we have just shown that conditional logging is very + powerful and flexibly, it is not the only way to control the + contents of the logs. Log files are more useful when they + contain a complete record of server activity. It is often + easier to simply post-process the log files to remove requests + that you do not want to consider.

    + +
    top
    +
    +

    Log Rotation

    + + +

    On even a moderately busy server, the quantity of + information stored in the log files is very large. The access + log file typically grows 1 MB or more per 10,000 requests. It + will consequently be necessary to periodically rotate the log + files by moving or deleting the existing logs. This cannot be + done while the server is running, because Apache will continue + writing to the old log file as long as it holds the file open. + Instead, the server must be restarted after the log files are + moved or deleted so that it will open new log files.

    + +

    By using a graceful restart, the server can be + instructed to open new log files without losing any existing or + pending connections from clients. However, in order to + accomplish this, the server must continue to write to the old + log files while it finishes serving old requests. It is + therefore necessary to wait for some time after the restart + before doing any processing on the log files. A typical + scenario that simply rotates the logs and compresses the old + logs to save space is:

    + +

    + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +

    + +

    Another way to perform log rotation is using piped logs as discussed in the next + section.

    +
    top
    +
    +

    Piped Logs

    + + +

    Apache httpd is capable of writing error and access log + files through a pipe to another process, rather than directly + to a file. This capability dramatically increases the + flexibility of logging, without adding code to the main server. + In order to write logs to a pipe, simply replace the filename + with the pipe character "|", followed by the name + of the executable which should accept log entries on its + standard input. Apache will start the piped-log process when + the server starts, and will restart it if it crashes while the + server is running. (This last feature is why we can refer to + this technique as "reliable piped logging".)

    + +

    Piped log processes are spawned by the parent Apache httpd + process, and inherit the userid of that process. This means + that piped log programs usually run as root. It is therefore + very important to keep the programs simple and secure.

    + +

    One important use of piped logs is to allow log rotation + without having to restart the server. The Apache HTTP Server + includes a simple program called rotatelogs + for this purpose. For example, to rotate the logs every 24 hours, you + can use:

    + +

    + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common +

    + +

    Notice that quotes are used to enclose the entire command + that will be called for the pipe. Although these examples are + for the access log, the same technique can be used for the + error log.

    + +

    A similar but much more flexible log rotation program + called cronolog + is available at an external site.

    + +

    As with conditional logging, piped logs are a very powerful + tool, but they should not be used where a simpler solution like + off-line post-processing is available.

    +
    top
    +
    +

    Virtual Hosts

    + + +

    When running a server with many virtual + hosts, there are several options for dealing with log + files. First, it is possible to use logs exactly as in a + single-host server. Simply by placing the logging directives + outside the <VirtualHost> sections in the + main server context, it is possible to log all requests in the + same access log and error log. This technique does not allow + for easy collection of statistics on individual virtual + hosts.

    + +

    If CustomLog + or ErrorLog + directives are placed inside a + <VirtualHost> + section, all requests or errors for that virtual host will be + logged only to the specified file. Any virtual host which does + not have logging directives will still have its requests sent + to the main server logs. This technique is very useful for a + small number of virtual hosts, but if the number of hosts is + very large, it can be complicated to manage. In addition, it + can often create problems with insufficient file + descriptors.

    + +

    For the access log, there is a very good compromise. By + adding information on the virtual host to the log format + string, it is possible to log all hosts to the same log, and + later split the log into individual files. For example, + consider the following directives.

    + +

    + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +

    + +

    The %v is used to log the name of the virtual + host that is serving the request. Then a program like split-logfile can be used to + post-process the access log in order to split it into one file + per virtual host.

    +
    top
    +
    +

    Other Log Files

    + + + + +

    PID File

    + + +

    On startup, Apache httpd saves the process id of the parent + httpd process to the file logs/httpd.pid. This + filename can be changed with the PidFile directive. The + process-id is for use by the administrator in restarting and + terminating the daemon by sending signals to the parent + process; on Windows, use the -k command line option instead. + For more information see the Stopping + and Restarting page.

    + + +

    Script Log

    + + +

    In order to aid in debugging, the + ScriptLog directive + allows you to record the input to and output from CGI scripts. + This should only be used in testing - not for live servers. + More information is available in the mod_cgi documentation.

    + + +

    Rewrite Log

    + + +

    When using the powerful and complex features of mod_rewrite, it is almost + always necessary to use the RewriteLog to help + in debugging. This log file produces a detailed analysis of how + the rewriting engine transforms requests. The level of detail + is controlled by the RewriteLogLevel directive.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/logs.html.ja.euc-jp b/trunk/docs/manual/logs.html.ja.euc-jp new file mode 100644 index 0000000000..827661498b --- /dev/null +++ b/trunk/docs/manual/logs.html.ja.euc-jp @@ -0,0 +1,551 @@ + + + +¥í¥°¥Õ¥¡¥¤¥ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥í¥°¥Õ¥¡¥¤¥ë

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¸ú²ÌŪ¤Ë´ÉÍý¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¥µ¡¼¥Ð¤Î³èÆ°¤ä¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¡¢ + º£È¯À¸¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Ê¤¤ÌäÂê¤Ë´Ø¤¹¤ë¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¤òÆÀ¤ë¤³¤È¤¬É¬ÍפǤ¹¡£ + Apache HTTP ¥µ¡¼¥Ð¤Ë¤ÏÈó¾ï¤ËÊñ³çŪ¤Ç½ÀÆð¤Ê¥í¥®¥ó¥°µ¡Ç½¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Îʸ½ñ¤Ï¥í¥®¥ó¥°µ¡Ç½¤ÎÀßÄê¤Î»ÅÊý¤È¡¢¥í¥°¤Ë²¿¤¬½ñ¤«¤ì¤Æ¤¤¤ë¤«¤ò + Íý²ò¤¹¤ë¤¿¤á¤ÎÊýË¡¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    + ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë·Ù¹ð

    + +

    Apache ¤¬¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¤¤¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë½ñ¤­¹þ¤á¤ë¿Í¤Ï¡¢ + ¤Û¤Ü³Î¼Â¤Ë¥µ¡¼¥Ð¤¬µ¯Æ°¤µ¤ì¤¿ uid ¤Ø¤Î¥¢¥¯¥»¥¹¤ò¼ê¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¤½¤ì¤ÏÄ̾ï¤Ï root ¥æ¡¼¥¶¤Ç¤¹¡£ + ¤Á¤ã¤ó¤È·ë²Ì¤ò¹Í¤¨¤ë¤³¤È¤Ê¤¯¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î + ½ñ¤­¹þ¤ß¸¢¸Â¤òÍ¿¤¨¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£¾Ü¤·¤¯¤Ï + ¥»¥­¥å¥ê¥Æ¥£¤Î¤³¤Ä¤Îʸ½ñ¤ò + Æɤó¤Ç¤¯¤À¤µ¤¤¡£

    + +

    ²Ã¤¨¤Æ¡¢¥í¥°¥Õ¥¡¥¤¥ë¤Ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¾ðÊ󤬤½¤Î¤Þ¤Þ¡¢ + ¥¨¥¹¥±¡¼¥×¤µ¤ì¤ë¤³¤È¤Ê¤¯½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢°­°Õ¤Î¤¢¤ë + ¥¯¥é¥¤¥¢¥ó¥È¤¬¥í¥°¥Õ¥¡¥¤¥ë¤ËÀ©¸æʸ»ú¤òÁÞÆþ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + À¸¤Î¥í¥°¤ò°·¤¦¤È¤­¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥¨¥é¡¼¥í¥°

    + + + +

    ErrorLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê + ̾Á°¤È¾ì½ê¤¬·è¤Þ¤ë¥µ¡¼¥Ð¤Î¥¨¥é¡¼¥í¥°¤Ï¡¢°ìÈÖ½ÅÍ×¤Ê¥í¥°¥Õ¥¡¥¤¥ë¤Ç¤¹¡£ + Apache ¤Î¿ÇÃǾðÊó¤Ï¤³¤³¤ËÁ÷¤é¤ì¡¢¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤·¤Æ¤¤¤ë¤È¤­¤Ë + ȯÀ¸¤·¤¿¥¨¥é¡¼¤Ï¤¹¤Ù¤Æ¤³¤³¤Ëµ­Ï¿¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿¤È¤­¤ä¡¢ + ¥µ¡¼¥Ð¤ÎÆ°ºî¤ËÌäÂ꤬µ¯¤³¤Ã¤¿¤È¤­¤Ï¡¢°ìÈֺǽé¤ËÄ´¤Ù¤ë¤Ù¤­ + ¤È¤³¤í¤Ç¤¹¡£´Ö°ã¤¤¤Î¾ÜºÙ¤ä½¤ÀµÊýË¡¤¬¤½¤³¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¤³¤È¤¬ + ¤è¤¯¤¢¤ê¤Þ¤¹¡£

    + +

    ¥¨¥é¡¼¥í¥°¤ÏÉáÄ̤ϥե¡¥¤¥ë¤Ë½ñ¤«¤ì¤Þ¤¹ (Ä̾ï unix ¥·¥¹¥Æ¥à¤Ç¤Ï + error_log¡¢Windows ¤È OS/2 ¤Ç¤Ï error.log)¡£ + Unix ¥·¥¹¥Æ¥à¤Ç¤Ï¥¨¥é¡¼¤ò syslog ¤ä + ¥Ñ¥¤¥×¤Ç¥×¥í¥°¥é¥à¤ËÁ÷¤ë ¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥¨¥é¡¼¥í¥°¤Î½ñ¼°¤ÏÈæ³ÓŪ¼«Í³Å٤ι⤤¤â¤Î¤Ç¡¢ÀâÌÀŪ¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤¿¤À¤·¡¢¤¤¤¯¤Ä¤«¤Î¾ðÊó¤Ï¤Û¤È¤ó¤É¤Î¥¨¥é¡¼¥í¥°¤Î¥¨¥ó¥È¥ê¤Ë¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢ÂåɽŪ¤Ê¤â¤Î¤Ë¼¡¤Î¤è¤¦¤Ê¥á¥Ã¥»¡¼¥¸¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test +

    + +

    ¥í¥°¥¨¥ó¥È¥ê¤ÎºÇ½é¤Î¹àÌܤϥá¥Ã¥»¡¼¥¸¤ÎÆüÉդȻþ¹ï¤Ç¤¹¡£ + Æó¤Ä¤á¤Î¹àÌܤÏÊó¹ð¤µ¤ì¤Æ¤¤¤ë¥¨¥é¡¼¤Î½ÅÍ×Å٤Ǥ¹¡£ + LogLevel ¤Ç½ÅÍ×Å٤Υì¥Ù¥ë¤ò + À©¸Â¤¹¤ë¤³¤È¤Ë¤è¤ê¥¨¥é¡¼¥í¥°¤ËÁ÷¤é¤ì¤ë¥¨¥é¡¼¤Î¼ïÎà¤òÀ©¸æ¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£»°¤ÄÌܤιàÌܤϥ¨¥é¡¼¤òȯÀ¸¤µ¤»¤¿¥¯¥é¥¤¥¢¥ó¥È¤Î IP ¥¢¥É¥ì¥¹ + ¤Ç¤¹¡£»Ä¤ê¤Ï¥á¥Ã¥»¡¼¥¸¤Ç¡¢¤³¤Î¾ì¹ç¤Ï¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤Î¥¢¥¯¥»¥¹¤ò + µñÈݤ¹¤ë¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¡¢¤È¤¤¤¦¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿Ê¸½ñ¤Î (¥¦¥§¥Ö¤Î¥Ñ¥¹¤Ç¤Ï¤Ê¤¯) ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î + ¥Ñ¥¹¤òÊó¹ð¤·¤Þ¤¹¡£

    + +

    Èó¾ï¤Ë¹­ÈϰϤΥá¥Ã¥»¡¼¥¸¤¬¥¨¥é¡¼¥í¥°¤Ë¸½¤ì¤Þ¤¹¡£¤¿¤¤¤Æ¤¤¤Î¤â¤Î¤Ï + ¾å¤ÎÎã¤Î¤è¤¦¤Ê´¶¤¸¤Ç¤¹¡£¥¨¥é¡¼¥í¥°¤Ë¤Ï CGI ¥¹¥¯¥ê¥×¥È¤Î¥Ç¥Ð¥Ã¥° + ½ÐÎϤâ½ñ¤«¤ì¤Þ¤¹¡£CGI ¥¹¥¯¥ê¥×¥È¤¬ stderr ¤Ë½ñ¤¤¤¿ + ¤¹¤Ù¤Æ¤Î¾ðÊó¤ÏľÀÜ¥¨¥é¡¼¥í¥°¤Ë¥³¥Ô¡¼¤µ¤ì¤Þ¤¹¡£

    + +

    ¾ðÊó¤òÄɲä·¤¿¤êºï½ü¤·¤¿¤ê¤·¤Æ¥¨¥é¡¼¥í¥°¤ò¥«¥¹¥¿¥Þ¥¤¥º¤¹¤ë¤³¤È¤Ï + ¤Ç¤­¤Þ¤»¤ó¡£¤·¤«¤·¡¢¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë¥¨¥é¡¼¥í¥°¤Î¥¨¥ó¥È¥ê¤Ï¡¢ + Âбþ¤¹¤ë¥¨¥ó¥È¥ê¤¬¥¢¥¯¥»¥¹¥í¥°¤Ë¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢¾å¤ÎÎã¤Î¥¨¥ó¥È¥ê¤Ï¥¢¥¯¥»¥¹¥í¥°¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É 403 ¤Î + ¥¨¥ó¥È¥ê¤ËÂбþ¤·¤Þ¤¹¡£¥¢¥¯¥»¥¹¥í¥°¤Ï¥«¥¹¥¿¥Þ¥¤¥º²Äǽ¤Ç¤¹¤Î¤Ç¡¢ + ¤½¤Á¤é¤ò»È¤¦¤³¤È¤Ë¤è¤ê¥¨¥é¡¼¤Î¾õ¶·¤Ë´Ø¤¹¤ë¾ðÊó¤ò¤è¤ê¿¤¯ + ¼ê¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥Æ¥¹¥È¤ÎºÇÃæ¤Ï¡¢ÌäÂ꤬ȯÀ¸¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò¸«¤ë¤¿¤á¤Ë¡¢ + ¾ï¤Ë¥¨¥é¡¼¥í¥°¤ò´Æ»ë¤¹¤ë¤Î¤¬Ìò¤ËΩ¤Ä¾ì¹ç¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£ + Unix ¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¼¡¤Î¤â¤Î¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + tail -f error_log +

    +
    top
    +
    +

    ¥¢¥¯¥»¥¹¥í¥°

    + + + + +

    ¥µ¡¼¥Ð¥¢¥¯¥»¥¹¥í¥°¤Ï¥µ¡¼¥Ð¤¬½èÍý¤ò¤·¤¿¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ò + µ­Ï¿¤·¤Þ¤¹¡£¥¢¥¯¥»¥¹¥í¥°¤Î¾ì½ê¤ÈÆâÍÆ¤Ï CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê·è¤Þ¤ê¤Þ¤¹¡£¥í¥°¤ÎÆâÍƤÎÁªÂò¤ò´Ê·é¤Ë¤¹¤ë¤¿¤á¤Ë + LogFormat + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Î¥»¥¯¥·¥ç¥ó¤Ï¥¢¥¯¥»¥¹¥í¥°¤Ë + ¾ðÊó¤òµ­Ï¿¤¹¤ë¤¿¤á¤Î¥µ¡¼¥Ð¤ÎÀßÄêÊýË¡¤òÀâÌÀ¤·¤Þ¤¹¡£

    + +

    ¤â¤Á¤í¤ó¡¢¥¢¥¯¥»¥¹¥í¥°¤Ë¾ðÊó¤òÃßÀѤ¹¤ë¤³¤È¤Ï¥í¥°´ÉÍý¤Î + »Ï¤Þ¤ê¤Ë²á¤®¤Þ¤»¤ó¡£¼¡¤ÎÃʳ¬¤ÏÍ­ÍѤÊÅý·×¤ò¼è¤ë¤¿¤á¤Ë¤³¤Î¾ðÊó¤ò + ²òÀϤ¹¤ë¤³¤È¤Ç¤¹¡£°ìÈÌŪ¤Ê¥í¥°²òÀϤϤ³¤Îʸ½ñ¤ÎÈϰϳ°¤Ç¡¢ + ¥¦¥§¥Ö¥µ¡¼¥Ð¼«¿È¤Î»Å»ö¤È¤¤¤¦¤ï¤±¤Ç¤â¤¢¤ê¤Þ¤»¤ó¡£¤³¤ÎÏä䡢 + ¥í¥°²òÀϤò¹Ô¤Ê¤¦¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¾ðÊó¤òÆÀ¤ë¤Ë¤Ï¡¢ + Open Directory ¤ä + Yahoo ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¤¤¤í¤ó¤Ê¥Ð¡¼¥¸¥ç¥ó¤Î Apache httpd ¤¬ mod_log_config, + mod_log_agent, TransferLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤¤¤Ã¤¿¡¢ + ¾¤Î¥â¥¸¥å¡¼¥ë¤ä¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¥¢¥¯¥»¥¹¤Î¥í¥®¥ó¥°¤ò + À©¸æ¤·¤Æ¤­¤Þ¤·¤¿¡£º£¤Ç¤Ï¡¢CustomLog ¤¬¤¹¤Ù¤Æ¤Î¸Å¤¤ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Îµ¡Ç½¤ò´Þ¤à¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥¢¥¯¥»¥¹¥í¥°¤Î½ñ¼°¤ÏÈó¾ï¤Ë½ÀÆð¤ÊÀßÄ꤬²Äǽ¤Ç¤¹¡£ + ½ñ¼°¤Ï C ¤Î printf(1) ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ËÈó¾ï¤Ë»÷¤¿ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó + ¤Ë¤è¤ê»ØÄꤵ¤ì¤Þ¤¹¡£¤¤¤¯¤Ä¤«¼¡¤ÎÀá¤ÇÎã¤ò¼¨¤·¤Þ¤¹¡£ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë»ÈÍѤǤ­¤ëÆâÍƤΰìÍ÷¤Ï mod_log_config ¤Îʸ½ñ + ¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Common Log Format

    + + +

    ¥¢¥¯¥»¥¹¥í¥°¤Î¤è¤¯¤¢¤ëÀßÄê¤Ë°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +

    + +

    ¤³¤ì¤Ï¡¢¥Ë¥Ã¥¯¥Í¡¼¥à common ¤òÄêµÁ¤·¡¢ + ¥í¥°¤Î¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Î°ì¤Ä¤È´ØÏ¢ÉÕ¤±¤Þ¤¹¡£¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ï + ¥Ñ¡¼¥»¥ó¥È¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤«¤é¤Ê¤ê¡¢¤½¤ì¤¾¤ì¤Î¥Ñ¡¼¥»¥ó¥È¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥µ¡¼¥Ð¤Ë¤É¤Î¾ðÊó¤ò¥í¥®¥ó¥°¤¹¤ë¤«¤ò»Ø¼¨¤·¤Þ¤¹¡£¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë + ʸ»ú¤ò¤½¤Î¤Þ¤ÞÆþ¤ì¤ë¤³¤È¤â¤Ç¤­¡¢¤½¤ì¤é¤Ï¥í¥°¤Î½ÐÎϤËľÀÜ¥³¥Ô¡¼¤µ¤ì¤Þ¤¹¡£ + ¤½¤³¤Ë°úÍÑʸ»ú (") ¤ò½ñ¤¯¤È¤­¤Ï¡¢ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ÎºÇ¸å¤È¤·¤Æ²ò¼á + ¤µ¤ì¤ë¤³¤È¤òËɤ°¤¿¤á¤Ë¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ç¥¨¥¹¥±¡¼¥×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë¤Ï²þ¹ÔÍѤΠ"\n"¡¢¥¿¥ÖÍѤΠ+ "\t" ¤È¤¤¤¦ÆÃÊ̤ÊÀ©¸æʸ»ú¤â´Þ¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ´û¤ËÄêµÁ¤µ¤ì¤¿ + ¥Ë¥Ã¥¯¥Í¡¼¥à ¤ò»È¤Ã¤Æ¿·¤·¤¤¥í¥°¥Õ¥¡¥¤¥ë¤òÀßÄꤷ¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹¥í¥°¤Î¥Õ¥¡¥¤¥ë̾¤Ï¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤é¤Ê¤¤¸Â¤ê¡¢ + ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ + °·¤ï¤ì¤Þ¤¹¡£

    + +

    ¾å¤ÎÀßÄê¤Ï Common Log Format (CLF) ¤È¸Æ¤Ð¤ì¤ë·Á¼°¤Ç + ¥í¥°¥¨¥ó¥È¥ê¤ò½ñ¤­¤Þ¤¹¡£¤³¤Îɸ½à¤Î·Á¼°¤Ï°Û¤Ê¤ë¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¿¤¯¤¬ + À¸À®¤¹¤ë¤³¤È¤¬¤Ç¤­¡¢Â¿¤¯¤Î¥í¥°²òÀÏ¥×¥í¥°¥é¥à¤¬Æɤߤ³¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + CLF ¤Ë¤è¤êÀ¸À®¤µ¤ì¤¿¥í¥°¥Õ¥¡¥¤¥ë¤Î¥¨¥ó¥È¥ê¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 +

    + +

    ¤³¤Î¥í¥°¥¨¥ó¥È¥ê¤Î¤½¤ì¤¾¤ì¤ÎÉôʬ¤Î°ÕÌ£¤Ï°Ê²¼¤ÇÀâÌÀ¤·¤Þ¤¹¡£

    + +
    +
    127.0.0.1 (%h)
    + +
    ¤³¤ì¤Ï¥µ¡¼¥Ð¤Ø¥ê¥¯¥¨¥¹¥È¤ò¤·¤¿¥¯¥é¥¤¥¢¥ó¥È (¥ê¥â¡¼¥È¥Û¥¹¥È) + ¤Î IP ¥¢¥É¥ì¥¹¤Ç¤¹¡£HostnameLookups ¤¬ + On ¤Î¾ì¹ç¤Ï¡¢¥µ¡¼¥Ð¤Ï¥Û¥¹¥È̾¤òÄ´¤Ù¤Æ¡¢ + IP ¥¢¥É¥ì¥¹¤¬½ñ¤«¤ì¤Æ¤¤¤ë¤È¤³¤í¤Ëµ­Ï¿¤·¤Þ¤¹¡£¤·¤«¤·¡¢¤³¤ÎÀßÄê¤Ï + ¥µ¡¼¥Ð¤ò¤«¤Ê¤êÃÙ¤¯¤¹¤ë¤Î¤Ç¡¢¤¢¤Þ¤ê¤ª´«¤á¤Ç¤­¤Þ¤»¤ó¡£ + ¤½¤¦¤Ç¤Ï¤Ê¤¯¡¢logresolve ¤Î + ¤è¤¦¤Ê¥í¥°¤Î¸å½èÍý¤ò¹Ô¤Ê¤¦¥×¥í¥°¥é¥à¤Ç¥Û¥¹¥È̾¤òÄ´¤Ù¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ + ¤³¤³¤ËÊó¹ð¤µ¤ì¤ë IP ¥¢¥É¥ì¥¹¤Ïɬ¤º¤·¤â¥æ¡¼¥¶¤¬»È¤Ã¤Æ¤¤¤ë¥Þ¥·¥ó¤Î + ¤â¤Î¤Ç¤¢¤ë¤È¤Ï¸Â¤ê¤Þ¤»¤ó¡£¥æ¡¼¥¶¤È¥µ¡¼¥Ð¤Î´Ö¤Ë¥×¥í¥­¥·¥µ¡¼¥Ð¤¬ + ¤¢¤ì¤Ð¡¢¤³¤Î¥¢¥É¥ì¥¹¤Ï¸µ¤Î¥Þ¥·¥ó¤Î¤â¤Î¤Ç¤Ï¤Ê¤¯¡¢¥×¥í¥­¥·¤Î + ¥¢¥É¥ì¥¹¤Ë¤Ê¤ê¤Þ¤¹¡£
    + +
    - (%l)
    + +
    ½ÐÎÏÃæ¤Î¡Ö¥Ï¥¤¥Õ¥ó¡×¤ÏÍ׵ᤵ¤ì¤¿¾ðÊ󤬼ê¤ËÆþ¤é¤Ê¤«¤Ã¤¿¤È¤¤¤¦¤³¤È¤ò + °ÕÌ£¤·¤Þ¤¹¡£¤³¤Î¾ì¹ç¡¢¼èÆÀ¤Ç¤­¤Ê¤«¤Ã¤¿¾ðÊó¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î¥Þ¥·¥ó¤Î + identd ¤Ë¤è¤ê·è¤Þ¤ë RFC 1413 ¤Î¥¯¥é¥¤¥¢¥ó¥È¤Î + ¥¢¥¤¥Ç¥ó¥Æ¥£¥Æ¥£¤Ç¤¹¡£¤³¤Î¾ðÊó¤Ï¤¢¤Þ¤ê¿®ÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤º¡¢ + ¤·¤Ã¤«¤ê¤È´ÉÍý¤µ¤ì¤¿ÆâÉô¥Í¥Ã¥È¥ï¡¼¥¯¤ò½ü¤¤¤Æ¤Ï»È¤¦¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + Apache ¤Ï IdentityCheck ¤¬ + On ¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢¤³¤Î¾ðÊó¤òÆÀ¤è¤¦¤È¤¹¤é¤·¤Þ¤»¤ó¡£
    + +
    frank (%u)
    + +
    ¤³¤ì¤Ï HTTP ǧ¾Ú¤Ë¤è¤ë¡¢¥É¥­¥å¥á¥ó¥È¤ò¥ê¥¯¥¨¥¹¥È¤·¤¿¿Í¤Î + ¥æ¡¼¥¶ ID ¤Ç¤¹¡£CGI ¥¹¥¯¥ê¥×¥È¤Ë¤ÏÄ̾ïƱ¤¸Ãͤ¬ REMOTE_USER + ´Ä¶­ÊÑ¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤Þ¤¹¡£¥ê¥¯¥¨¥¹¥È¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É + (°Ê²¼¤ò»²¾È) ¤¬ 401 ¤Ç¤¢¤Ã¤¿¾ì¹ç¤Ï¡¢¥æ¡¼¥¶¤Ïǧ¾Ú¤Ë¼ºÇÔ¤·¤Æ¤¤¤ë¤Î¤Ç¡¢ + ¤³¤ÎÃͤϿ®ÍѤǤ­¤Þ¤»¤ó¡£¥É¥­¥å¥á¥ó¥È¤¬¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ì¤Æ¤¤¤Ê¤¤ + ¾ì¹ç¤Ï¡¢¤³¤Î¥¨¥ó¥È¥ê¤ÏÁ°¤Î¤â¤Î¤ÈƱ¤¸¤è¤¦¤Ë "-" ¤Ë + ¤Ê¤ê¤Þ¤¹¡£
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + ¥µ¡¼¥Ð¤¬¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤Ã¤¿»þ¹ï¤Ç¤¹¡£½ñ¼°¤Ï: + +

    + [day/month/year:hour:minute:second zone]
    + day = 2*digit
    + month = 3*letter
    + year = 4*digit
    + hour = 2*digit
    + minute = 2*digit
    + second = 2*digit
    + zone = (`+' | `-') 4*digit
    +

    + ¥í¥°¤Î¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë %{format}t ¤ò + »ØÄꤹ¤ë¤³¤È¤Ç¡¢Ê̤ηÁ¼°¤Ç»þ¹ï¤òɽ¼¨¤µ¤»¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¤È¤­¡¢format ¤Ï C ¤Îɸ½à¥é¥¤¥Ö¥é¥ê¤Î + strftime(3) ¤Î·Á¼°¤Ë¤Ê¤ê¤Þ¤¹¡£ +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤¬Æó½Å°úÍÑÉä¤ÎÃæ¤Ë¼¨¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤Ë¤Ï¿¤¯¤ÎÍ­ÍѤʾðÊ󤬤¢¤ê¤Þ¤¹¡£¤Þ¤º¡¢¤³¤Î¾ì¹ç¥¯¥é¥¤¥¢¥ó¥È¤¬ + »È¤Ã¤¿¥á¥½¥Ã¥É¤Ï GET ¤Ç¤¹¡£¼¡¤Ë¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï + ¥ê¥½¡¼¥¹ /apache_pb.gif ¤òÍ׵ᤷ¤Þ¤·¤¿¡£¤½¤·¤Æ¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤Ï¥×¥í¥È¥³¥ë HTTP/1.0 ¤ò»ÈÍѤ·¤Þ¤·¤¿¡£ + ¥ê¥¯¥¨¥¹¥È¤Î³ÆÉôʬ¤òÆÈΩ¤Ë¥í¥°¼ý½¸¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó "%m %U%q %H" ¤Ï + ¥á¥½¥Ã¥É¡¢¥Ñ¥¹¡¢¥¯¥¨¥êʸ»úÎó¡¢¥×¥í¥È¥³¥ë¤ò¥í¥°¼ý½¸¤·¡¢ + ·ë¶É "%r" ¤È¤Þ¤Ã¤¿¤¯Æ±¤¸½ÐÎϤˤʤê¤Þ¤¹¡£
    + +
    200 (%>s)
    + +
    ¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤êÊÖ¤¹¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤Ç¤¹¡£ + ¤³¤Î¾ðÊó¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤¬À®¸ù±þÅú (2 ¤Ç»Ï¤Þ¤ë¥³¡¼¥É) ¤Ç¤¢¤Ã¤¿¤«¡¢ + ¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó (3 ¤Ç»Ï¤Þ¤ë¥³¡¼¥É) ¤Ç¤¢¤Ã¤¿¤«¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ë¤è¤ë + ¥¨¥é¡¼ (4 ¤Ç»Ï¤Þ¤ë¥³¡¼¥É) ¤Ç¤¢¤Ã¤¿¤«¡¢¥µ¡¼¥Ð¤Î¥¨¥é¡¼ (5 ¤Ç»Ï¤Þ¤ë¥³¡¼¥É) + ¤Ç¤¢¤Ã¤¿¤«¡¢¤ò¸½¤¹¤Î¤Ç¡¢Èó¾ï¤ËÂçÀڤǤ¹¡£¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤Î + ´°Á´¤Ê¥ê¥¹¥È¤Ï HTTP + µ¬³Ê (RFC2616 Âè 10 Àá) ¤Ë¤¢¤ê¤Þ¤¹¡£
    + +
    2326 (%b)
    + +
    ¤³¤ÎºÇ¸å¤Î¥¨¥ó¥È¥ê¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¿®¤µ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Î¡¢ + ±þÅú¥Ø¥Ã¥À¤ò½ü¤¤¤¿¥µ¥¤¥º¤ò¸½¤·¤Þ¤¹¡£¥³¥ó¥Æ¥ó¥È¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤Ê¤«¤Ã¤¿ + ¾ì¹ç¤Ï¡¢¤³¤ÎÃÍ¤Ï "-" ¤Ë¤Ê¤ê¤Þ¤¹¡£¥³¥ó¥Æ¥ó¥È¤¬Ìµ¤¤¾ì¹ç¤Ë + "0" ¤ò¥í¥°¼ý½¸¤¹¤ë¤Ë¤Ï¡¢%b ¤Ç¤Ï¤Ê¤¯ + %B ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£
    + +
    + + +

    Combined Log Format

    + + +

    ¤â¤¦°ì¤Ä¤Î¤è¤¯»È¤ï¤ì¤ë½ñ¼°¤Ï Combined Log Format ¤È¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¡£ + °Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +

    + +

    ¤³¤Î½ñ¼°¤ÎºÇ½é¤ÎÊý¤Ï Common Log Format ¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤Ç¡¢ºÇ¸å¤Ë + Æó¤ÄÄɲäΥ¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤¹¡£ÄɲäΥ¨¥ó¥È¥ê¤Ï¥Ñ¡¼¥»¥ó¥È¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + %{header}i ¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤³¤Ç + header ¤Ï HTTP ¤Î¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Î¤É¤ì¤«¤Ç¤¹¡£¤³¤Î½ñ¼°¤Ë¤è¤ë + ¥¢¥¯¥»¥¹¥í¥°¤Ï°Ê²¼¤Î¤è¤¦¤Ê´¶¤¸¤Ë¤Ê¤ê¤Þ¤¹:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" +

    + +

    ÄɲäΥ¨¥ó¥È¥ê¤Ï:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    "Referer" (°Õ¿ÞŪ¤ÊÄÖ¤ê´Ö°ã¤¤) HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ç¤¹¡£ + ¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤¬Êó¹ð¤·¤Æ¤¯¤ë»²¾È¸µ¤Î¥µ¥¤¥È¤òɽ¤·¤Þ¤¹¡£ + (¤³¤Î¾ì¹ç¤Ï¡¢/apache_pb.gif ¤Ë¥ê¥ó¥¯¤·¤Æ¤¤¤ë¤«¡¢ + ¤½¤ì¤ò´Þ¤ó¤Ç¤¤¤ë¥Ú¡¼¥¸¤Ç¤¹)¡£
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    User-Agent HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ç¤¹¡£¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î¥Ö¥é¥¦¥¶¤¬ + ¼«Ê¬¼«¿È¤Î¤³¤È¤òÊó¹ð¤·¤Æ¤¯¤ë¾ðÊó¤Ç¤¹¡£
    +
    + + +

    Ê£¿ô¤Î¥¢¥¯¥»¥¹¥í¥°

    + + +

    Ê£¿ô¤Î¥¢¥¯¥»¥¹¥í¥°¤Ïñ¤ËÀßÄê¥Õ¥¡¥¤¥ë¤ËÊ£¿ô¤Î CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤ÇºîÀ®¤µ¤ì¤Þ¤¹¡£Î㤨¤Ð¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + »°¤Ä¤Î¥¢¥¯¥»¥¹¥í¥°¤òºî¤ê¤Þ¤¹¡£ºÇ½é¤Î¤â¤Î¤Ï´ðËÜŪ¤Ê CLF ¤Î¾ðÊó¤Ç¡¢ + Æó¤ÄÌܤȻ°¤ÄÌÜ¤Ï referer ¤È¥Ö¥é¥¦¥¶¤Î¾ðÊó¤Ç¤¹¡£ºÇ¸åÆó¤Ä¤Î + CustomLog ¤Ï + ReferLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + AgentLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸ú²Ì¤ò¤Þ¤Í¤ëÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +

    + +

    ¤³¤ÎÎã¤Ï LogFormat ¤Ç + ¥Ë¥Ã¥¯¥Í¡¼¥à¤òÄêµÁ¤¹¤ëɬÍפ¬¤Ê¤¤¡¢ + ¤È¤¤¤¦¤³¤È¤â¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥Ë¥Ã¥¯¥Í¡¼¥à¤ÎÂå¤ï¤ê¤Ë¡¢ + CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë + ľÀÜ¥í¥°¤Î½ñ¼°¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +

    ¾ò·ïÉÕ¤­¥í¥°

    + + +

    ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤Ë´ð¤Å¤¤¤Æ¥¢¥¯¥»¥¹¥í¥°¤Ë¥¨¥ó¥È¥ê¤Î + °ìÉô¤ò¥í¥®¥ó¥°¤·¤Ê¤¤Êý¤¬ÊØÍø¤Ê¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ï ´Ä¶­ÊÑ¿ô ¤ÎÊä½õ¤Ë¤è¤ê´Êñ¤Ë¼Â¸½¤Ç¤­¤Þ¤¹¡£¤Þ¤º¡¢ + ¥ê¥¯¥¨¥¹¥È¤¬²¿¤é¤«¤Î¾ò·ï¤Ë¹ç¤¦¤È¤¤¤¦¤³¤È¤ò¸½¤¹¤¿¤á¤Ë´Ä¶­ÊÑ¿ô¤¬ + ÀßÄꤵ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤ÏÄ̾ï¤Ï SetEnvIf ¤Ë¤è¤ê + ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£¤½¤·¤Æ¡¢CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + env= Àá¤ò»È¤Ã¤Æ´Ä¶­ÊÑ¿ô¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¤ò + ´Þ¤á¤¿¤êÇÓ½ü¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¤¤¯¤Ä¤«Îã¤òµó¤²¤Þ¤¹:

    + +

    + # Mark requests from the loop-back interface
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # Mark requests for the robots.txt file
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # Log what remains
    + CustomLog logs/access_log common env=!dontlog +

    + +

    ¾¤ÎÎã¤È¤·¤Æ¡¢±Ñ¸ì¤òÏ乿ͤ«¤é¤Î¥ê¥¯¥¨¥¹¥È¤È¤½¤ì°Ê³°¤Î¿Í¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ò + ʬ¤±¤¿¤¤¡¢¤È¤¤¤¦¾ì¹ç¤ò¹Í¤¨¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +

    + +

    ¤³¤³¤Þ¤Ç¤Ç¤Ï¾ò·ïÉÕ¤­¥í¥®¥ó¥°¤¬Èó¾ï¤Ë¶¯ÎϤǽÀÆð¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Æ¤­¤Þ¤·¤¿¤¬¡¢ + ¤½¤ì¤¬¥í¥°¤ÎÆâÍƤòÀ©¸æ¤¹¤ëÍ£°ì¤ÎÊýË¡¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¥í¥°¥Õ¥¡¥¤¥ë¤Ï + ¥µ¡¼¥Ð¤Î³èÆ°¤Î´°Á´¤Êµ­Ï¿¤Ç¤¢¤ëÊý¤¬¤è¤êÌò¤ËΩ¤Á¤Þ¤¹¡£Ã±½ã¤Ë¥í¥°¥Õ¥¡¥¤¥ë¤ò + ¸å½èÍý¤·¤Æ¡¢¹Íθ¤·¤¿¤¯¤Ê¤¤¥í¥°¤òºï½ü¤¹¤ëÊý¤¬´Êñ¤Ç¤¢¤ë¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥í¥°¤Î¸òÂØ

    + + +

    ÉáÄ̤ÎÉé²Ù¤Î¥µ¡¼¥Ð¤Ç¤µ¤¨¡¢¥í¥°¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤ë¾ðÊó¤ÎÎÌ¤Ï + ËÄÂç¤Ë¤Ê¤ê¤Þ¤¹¡£¥¢¥¯¥»¥¹¥í¥°¤Î¥Õ¥¡¥¤¥ë¤ÏÉáÄÌ 10,000 ¥ê¥¯¥¨¥¹¥ÈËè¤Ë + 1 MB °Ê¾åÁý¤¨¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢´û¸¤Î¥í¥°¤ò°ÜÆ°¤·¤¿¤ê¡¢ºï½ü¤·¤¿¤ê¤·¤Æ¡¢ + Äê´üŪ¤Ë¥í¥°¤ò¸òÂؤµ¤»¤ë¤³¤È¤¬É¬Íפˤʤê¤Þ¤¹¡£¤³¤ì¤Ï¥µ¡¼¥Ð¤Î¼Â¹ÔÃæ¤Ë¤Ï + ¹Ô¤Ê¤¨¤Þ¤»¤ó¡£¤È¤¤¤¦¤Î¤Ï¡¢Apache ¤Ï¥Õ¥¡¥¤¥ë¤¬ open ¤µ¤ì¤Æ¤¤¤ë´Ö¤Ï + ¤º¤Ã¤È¸Å¤¤¥í¥°¥Õ¥¡¥¤¥ë¤Ë½ñ¤­Â³¤±¤ë¤«¤é¤Ç¤¹¡£ + ¿·¤·¤¤¥í¥°¥Õ¥¡¥¤¥ë¤ò open ¤Ç¤­¤ë¤è¤¦¤Ë¡¢¥í¥°¥Õ¥¡¥¤¥ë¤¬°ÜÆ°¤µ¤ì¤¿¤ê + ºï½ü¤µ¤ì¤¿¸å¤Ë¡¢¥µ¡¼¥Ð¤òºÆµ¯Æ°¤¹¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Í¥²í¤Ê ºÆµ¯Æ°¤ò¹Ô¤Ê¤¦¤³¤È¤Ç¡¢¥µ¡¼¥Ð¤Ï´û¸¤Î¥³¥Í¥¯¥·¥ç¥ó¤ä + ½èÍýÂÔ¤Á¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¼º¤¦¤³¤È¤Ê¤¯¿·¤·¤¤¥í¥°¥Õ¥¡¥¤¥ë¤ò open ¤µ¤»¤ë + ¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤·¤«¤·¡¢¤³¤ì¤ò¼Â¸½¤¹¤ë¤¿¤á¤Ë¡¢¥µ¡¼¥Ð¤Ï¸Å¤¤¥ê¥¯¥¨¥¹¥È¤ò + °·¤Ã¤Æ¤¤¤ë´Ö¤Ï¸Å¤¤¥í¥°¥Õ¥¡¥¤¥ë¤Ë½ñ¤­Â³¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢ºÆµ¯Æ°¤Î¸å¤Ç¤Ï¥í¥°¥Õ¥¡¥¤¥ë¤Î½èÍý¤ò»Ï¤á¤ëÁ°¤Ë¡¢¤·¤Ð¤é¤¯ÂÔ¤¿¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£Ã±¤Ë¥í¥°¤ò¸òÂؤµ¤»¤Æ¡¢¥Ç¥£¥¹¥¯¤ÎÀáÌó¤Î¤¿¤á¤Ë¸Å¤¤¥í¥°¤ò + °µ½Ì¤¹¤ëÉáÄ̤Υ·¥Ê¥ê¥ª¤Ï:

    + +

    + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +

    + +

    ¥í¥°¤Î¸òÂؤò¤¹¤ë¤â¤¦°ì¤Ä¤ÎÊýË¡¤Ï¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°¤ò»È¤¦¤â¤Î¤Ç¡¢¼¡¤ÎÀá¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°

    + + +

    Apache httpd ¤Ï¥¨¥é¡¼¥í¥°¤È¥¢¥¯¥»¥¹¥í¥°¤ò¥Õ¥¡¥¤¥ë¤ËľÀܽñ¤¯Âå¤ï¤ê¤Ë¡¢ + ¥Ñ¥¤¥×¤òÄ̤·¤ÆÊÌ¤Î¥×¥í¥°¥é¥à¤Ë½ñ¤­½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤Ë¤è¤ê¡¢¼ç¥µ¡¼¥Ð¤Ë¥³¡¼¥É¤òÄɲ乤뤳¤È¤Ê¤¯ + ¥í¥®¥ó¥°¤Î½ÀÆðÀ­¤¬Èó¾ï¤Ë¹â¤Þ¤Ã¤Æ¤¤¤Þ¤¹¡£¥Ñ¥¤¥×¤Ë¥í¥°¤ò½ñ¤¯¤¿¤á¤Ë¤Ï¡¢ + ñ¤Ë¥Õ¥¡¥¤¥ë̾¤ò¥Ñ¥¤¥×ʸ»ú "|" ¤ËÃÖ¤­´¹¤¨¡¢¤½¤Î³¤­¤Ë + ɸ½àÆþÎϤ«¤é¥í¥°¤Î¥¨¥ó¥È¥ê¤ò¼õ¤±¤È¤ë¼Â¹Ô¥×¥í¥°¥é¥à¤Î̾Á°¤ò½ñ¤¯¤À¤±¤Ç¤¹¡£ + Apache ¤Ï¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°ÍÑ¤Î¥×¥í¥»¥¹¤ò¥µ¡¼¥Ð¤Îµ¯Æ°»þ¤Ë¼Â¹Ô¤·¡¢ + ¥µ¡¼¥Ð¤Î¼Â¹ÔÃæ¤Ë¤½¤Î¥×¥í¥°¥é¥à¤¬¥¯¥é¥Ã¥·¥å¤·¤¿¤È¤­¤Ï¤½¤ì¤òºÆ¤Ó + ¼Â¹Ô¤·¤Þ¤¹¡£(¤³¤ÎºÇ¸å¤Îµ¡Ç½¤¬¤³¤Îµ»½Ñ¤¬¡Ö¿®ÍêÀ­¤Î¤¢¤ë¥Ñ¥¤¥×·Ðͳ¤Î¥í¥®¥ó¥°¡× + ¤È¸Æ¤Ð¤ì¤Æ¤¤¤ëÍýͳ¤Ç¤¹¡£)

    + +

    ¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°ÍÑ¤Î¥×¥í¥»¥¹¤Ï Apache httpd ¤Î¿Æ¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¡¢ + ¤½¤Î¥×¥í¥»¥¹¤Î¥æ¡¼¥¶ ID ¤ò·Ñ¾µ¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤³¤ì¤Ï¡¢¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°ÍѤΠ+ ¥×¥í¥°¥é¥à¤ÏÉáÄÌ root ¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¥×¥í¥°¥é¥à¤ò´Êñ¤Ç°ÂÁ´¤ËÊݤĤ³¤È¤¬Èó¾ï¤Ë½ÅÍפǤ¹¡£

    + +

    ¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°¤Î½ÅÍפÊÍøÍÑË¡¤Ï¡¢¥µ¡¼¥Ð¤ÎºÆµ¯Æ°¤Ê¤·¤Ç¥í¥°¤Î¸òÂؤò + ¤¹¤ë¤³¤È¤Ç¤¹¡£Apache HTTP ¥µ¡¼¥Ð¤Ë¤Ï¤³¤Î¤¿¤á¤Î rotatelogs ¤È¸Æ¤Ð¤ì¤ë´Êñ¤Ê + ¥×¥í¥°¥é¥à¤¬ÉÕ°¤·¤Æ¤¤¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢24 »þ´ÖËè¤Ë¥í¥°¤ò¸òÂؤµ¤»¤ë¤Ë¤Ï¡¢ + °Ê²¼¤Î¤â¤Î¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common +

    + +

    ¥Ñ¥¤¥×¤ÎÀè¤Ç¸Æ¤Ð¤ì¤ë¥³¥Þ¥ó¥ÉÁ´ÂΤ¬°úÍÑÉä¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤³¤È¤ËÃíÌܤ·¤Æ + ¤¯¤À¤µ¤¤¡£¤³¤ÎÎã¤Ï¥¢¥¯¥»¥¹¥í¥°¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¢¥¨¥é¡¼¥í¥°¤Ë¤âƱ¤¸µ»½Ñ¤ò + »È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    »÷¤Æ¤¤¤ë¤±¤ì¤É¡¢¤è¤ê¤º¤Ã¤È½ÀÆð¤Ê + cronolog ¤È¤¤¤¦¥í¥°¸òÂØÍѤΠ+ ¥×¥í¥°¥é¥à¤¬³°Éô¤Î¥µ¥¤¥È¤Ë¤¢¤ê¤Þ¤¹¡£

    + +

    ¾ò·ïÉÕ¤­¥í¥®¥ó¥°¤ÈƱÍÍ¡¢¥Ñ¥¤¥×·Ðͳ¤Î¥í¥°¤ÏÈó¾ï¤Ë¶¯ÎÏ¤Ê + Æ»¶ñ¤Ç¤¹¤¬¡¢¥ª¥Õ¥é¥¤¥ó¤Î¸å½èÍý¤Î¤è¤¦¤Ê¡¢¤è¤ê´Êñ¤Ê²ò·èÊýË¡¤¬¤¢¤ë¤È¤­¤Ï + »È¤ï¤Ê¤¤Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + + +

    ¿¤¯¤Î ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È ¤Î¤¢¤ë¥µ¡¼¥Ð¤ò¼Â¹Ô¤·¤Æ¤¤¤ë + ¤È¤­¤Ï¡¢¥í¥°¥Õ¥¡¥¤¥ë¤Î°·¤¤Êý¤Ë¤¤¤¯¤Ä¤«¤ÎÊýË¡¤¬¤¢¤ê¤Þ¤¹¡£ + ¤Þ¤º¡¢Ã±ÆȤΥۥ¹¥È¤Î¤ß¤Î¥µ¡¼¥Ð¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤è¤¦¤Ë¥í¥°¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥í¥®¥ó¥°¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¼ç¥µ¡¼¥Ð¤Î¥³¥ó¥Æ¥­¥¹¥È¤Î + <VirtualHost> ¥»¥¯¥·¥ç¥ó¤Î³°¤ËÃÖ¤¯¤³¤È¤Ç¡¢ + ¤¹¤Ù¤Æ¤Î¥í¥°¤òƱ¤¸¥¢¥¯¥»¥¹¥í¥°¤È¥¨¥é¡¼¥í¥°¤Ë¥í¥°¼ý½¸¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¼êË¡¤Ç¤Ï¸Ä¡¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÅý·×¤ò´Êñ¤Ë¤È¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£

    + +

    >CustomLog ¤ä + ErrorLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + <VirtualHost> ¤ÎÃæ¤Ë + ÃÖ¤«¤ì¤¿¾ì¹ç¤Ï¡¢¤½¤Î¥Ð¡¼¥Á¥ã¥ë + ¥Û¥¹¥È¤Ø¤Î¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ä¥¨¥é¡¼¤¬¤½¤³¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¤Î¤ß + ¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£¥í¥®¥ó¥°¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤Ê¤¤¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï + °ÍÁ³¤È¤·¤Æ¥ê¥¯¥¨¥¹¥È¤¬¼ç¥µ¡¼¥Ð¤Î¥í¥°¤ËÁ÷¤é¤ì¤Þ¤¹¡£¤³¤Î¼êË¡¤Ï¾¯¤Ê¤¤ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤Æ¤ÏÈó¾ï¤ËÍ­ÍѤǤ¹¤¬¡¢¥Û¥¹¥È¤Î¿ô¤¬Èó¾ï¤Ë¿¤¯¤Ê¤ë¤È + ´ÉÍý¤¬ÂçÊѤˤʤê¤Þ¤¹¡£¤µ¤é¤Ë¡¢¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¸Â³¦¤ÎÌäÂê¤òµ¯¤³¤¹¤³¤È¤¬ + ¤¢¤ê¤Þ¤¹¡£

    + +

    ¥¢¥¯¥»¥¹¥í¥°¤Ë¤Ï¡¢Èó¾ï¤ËÎɤ¤ÂŶ¨°Æ¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î + ¾ðÊó¤ò¥í¥°¤Î¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë²Ã¤¨¤ë¤³¤È¤Ç¡¢¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤òƱ¤¸¥í¥°¤Ë¥í¥°¼ý½¸¤·¤Æ¡¢¸å¤Ç¥í¥°¤ò¸Ä¡¹¤Î¥Õ¥¡¥¤¥ë¤Ëʬ³ä¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +

    + +

    %v ¤¬¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î̾Á°¤ò + ¥í¥°¼ý½¸¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£¤½¤·¤Æ¡¢split-logfile ¤Î¤è¤¦¤Ê¥×¥í¥°¥é¥à¤ò + »È¤Ã¤Æ¥¢¥¯¥»¥¹¥í¥°¤ò¸å½èÍý¤¹¤ë¤³¤È¤Ç¡¢ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Î¥Õ¥¡¥¤¥ë¤Ë¥í¥°¤òʬ³ä¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    »ÄÇ°¤Ê¤¬¤é¡¢¥¨¥é¡¼¥í¥°¤Ë¤ÏƱÍͤμêË¡¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é¡¢ + ¤¹¤Ù¤Æ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òƱ¤¸¥¨¥é¡¼¥í¥°¤ÎÃæ¤Ëº®¤¼¤ë¤«¡¢ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Ë¥¨¥é¡¼¥í¥°¤ò»È¤¦¤«¤òÁª¤Ð¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ¾¤Î¥í¥°¥Õ¥¡¥¤¥ë

    + + + + +

    PID ¥Õ¥¡¥¤¥ë

    + + +

    µ¯Æ°»þ¤Ë¡¢Apache ¤Ï¿Æ httpd ¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹ ID ¤ò + logs/httpd.pid ¤ËÊݸ¤·¤Þ¤¹¡£¤³¤Î + ¥Õ¥¡¥¤¥ë̾¤Ï PidFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ + Êѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥×¥í¥»¥¹ ID ¤Ï´ÉÍý¼Ô¤¬¿Æ¥×¥í¥»¥¹¤Ë + ¥·¥°¥Ê¥ë¤òÁ÷¤ë¤³¤È¤Ç¥Ç¡¼¥â¥ó¤òºÆµ¯Æ°¤·¤¿¤ê½ªÎ»¤µ¤»¤¿¤ê¤¹¤ë¤È¤­¤Ë + »ÈÍѤ·¤Þ¤¹¡£Windows ¤Ç¤Ï¡¢Âå¤ï¤ê¤Ë -k ¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ò + »È¤Ã¤Æ¤¯¤À¤µ¤¤¡£¾Ü¤·¤¤¾ðÊó¤Ï ½ªÎ»¤È + ºÆµ¯Æ° ¤Î¥Ú¡¼¥¸¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£

    + + +

    ¥¹¥¯¥ê¥×¥È¥í¥°

    + + +

    ¥Ç¥Ð¥Ã¥°¤ÎÊä½õ¤Î¤¿¤á¤Ë¡¢ScriptLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + CGI ¥¹¥¯¥ê¥×¥È¤ÎÆþÎϤȽÐÎϤòµ­Ï¿¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï¥Æ¥¹¥ÈÍѤˤΤ߻ÈÍѤ·¤Æ¡¢Ä̾ï¤Î¥µ¡¼¥Ð¤Ç¤Ï»ÈÍѤ·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¾Ü¤·¤¤¾ðÊó¤Ï mod_cgi ¤Îʸ½ñ ¤Ë¤¢¤ê¤Þ¤¹¡£

    + + +

    ¥ê¥é¥¤¥È¥í¥°

    + + +

    mod_rewrite ¤Î¶¯ÎÏ¤Ç + Ê£»¨¤Êµ¡Ç½¤ò + »È¤Ã¤Æ¤¤¤ë¤È¤­¤Ï¡¢¤Û¤Ü¤¤¤Ä¤â¥Ç¥Ð¥Ã¥°¤ò´Êñ¤Ë¤¹¤ë¤¿¤á¤Ë + RewriteLog ¤Î»ÈÍѤ¬ + ɬÍפǤ·¤ç¤¦¡£¤³¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Ë¤Ï¥ê¥é¥¤¥È¥¨¥ó¥¸¥ó¤¬¥ê¥¯¥¨¥¹¥È¤ò + ½ñ¤­´¹¤¨¤ëÊýË¡¤Î¾ÜºÙ¤Ê²òÀϤ¬½ÐÎϤµ¤ì¤Þ¤¹¡£¾Ü¤·¤µ¤ÎÅÙ¹ç¤Ï RewriteLogLevel + ¤ÇÀ©¸æ¤Ç¤­¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/logs.html.ko.euc-kr b/trunk/docs/manual/logs.html.ko.euc-kr new file mode 100644 index 0000000000..1080bbfc03 --- /dev/null +++ b/trunk/docs/manual/logs.html.ko.euc-kr @@ -0,0 +1,521 @@ + + + +·Î±×ÆÄÀÏ - Apache HTTP Server + + + + + +
    <-
    +

    ·Î±×ÆÄÀÏ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    È¿À²ÀûÀ¸·Î À¥¼­¹ö¸¦ °ü¸®ÇÏ·Á¸é ¹ß»ýÇÏ´Â ¹®Á¦¿Í ÇÔ²² ¼­¹öÀÇ + È°µ¿°ú ¼º´É¿¡ ´ëÇØ ¾Ë¾Æ¾ß ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¸Å¿ì Á¾ÇÕÀûÀÌ°í + À¯¿¬ÇÑ ·Î±× ±â´ÉÀ» Á¦°øÇÑ´Ù. ÀÌ ¹®¼­´Â ·Î±× ±â´ÉÀ» ¼³Á¤ÇÏ´Â + ¹æ¹ý°ú ·Î±×¿¡ µé¾î°¥ ³»¿ëÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    º¸¾È °æ°í

    + + +

    ´©±º°¡¿¡°Ô ¾ÆÆÄÄ¡ÀÇ ·Î±×ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ + ÀÖ´Ù¸é (º¸Åë root) ¼­¹ö¸¦ ½ÇÇàÇÏ´Â uid¸¦ °ÅÀÇ È®½ÇÈ÷ ¾òÀ» + ¼ö ÀÖ´Ù. À̸¦ °í·ÁÇÏÁö¾Ê°í ·Î±×°¡ ÀúÀåµÈ µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀ» + ÁÖÁö ¸¶¶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº º¸¾È ÆÁ ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¶Ç, Ŭ¶óÀ̾ðÆ®°¡ Á¦°øÇÑ Á¤º¸´Â ·Î±×ÆÄÀÏ¿¡ °ÅÀÇ ±×´ë·Î + ±â·ÏµÈ´Ù. ±×·¡¼­ ¾ÇÀÇ°¡ Àִ Ŭ¶óÀ̾ðÆ®°¡ ·Î±×ÆÄÀÏ¿¡ Á¦¾î¹®ÀÚ¸¦ + ³ÖÀ» ¼ö ÀÖÀ¸¹Ç·Î, ·Î±×¸¦ ´Ù·ê¶§´Â ÁÖÀÇÇØ¾ß ÇÑ´Ù.

    +
    top
    +
    +

    ¿À·ù ·Î±× (Error Log)

    + + + + +

    ErrorLog Áö½Ã¾î´Â + °¡Àå Áß¿äÇÑ ·Î±×ÆÄÀÏÀÎ ¼­¹ö ¿À·ù ·Î±×ÀÇ À̸§°ú À§Ä¡¸¦ ÁöÁ¤ÇÑ´Ù. + ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ ÆÄÀÏ¿¡ Áø´ÜÁ¤º¸¿Í ¿äûÀ» ó¸®ÇÏ´Â µµÁß + ¹ß»ýÇÑ ¿À·ù¸¦ ±â·ÏÇÑ´Ù. ¼­¹ö°¡ ½ÃÀÛÇϰųª µ¿ÀÛÇϴµ¥ ¹®Á¦°¡ + ÀÖ´Ù¸é ¹«¾ùÀÌ À߸øµÇ¾ú°í ¶§¶§·Î ¾î¶»°Ô °íÄ¡´ÂÁö¸¦ ¾Ë·ÁÁÖ´Â + ÀÌ°÷À» °¡Àå ¸ÕÀú »ìÆìºÁ¾ß ÇÑ´Ù.

    + +

    ¿À·ù ·Î±×´Â º¸Åë (ÀüÇüÀûÀ¸·Î À¯´Ð½º ½Ã½ºÅÛ¿¡¼­´Â + error_log, À©µµ¿ìÁî¿Í OS/2¿¡¼­´Â + error.log) ÆÄÀÏ¿¡ ±â·ÏµÈ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ + ¼­¹ö´Â ¿À·ù¸¦ syslog³ª ÆÄÀÌÇÁ¸¦ + »ç¿ëÇÏ¿© ´Ù¸¥ ÇÁ·Î±×·¥À¸·Î º¸³¾ ¼öµµ ÀÖ´Ù.

    + +

    ¿À·ù ·Î±×ÀÇ Çü½ÄÀº »ó´ëÀûÀ¸·Î ÀÚÀ¯·Ó°í ÀÚ¼¼ÇÏ´Ù. ±×·¯³ª + ´ëºÎºÐÀÇ ¿À·ù ·Î±× Ç׸ñ¿¡ °øÅëÀûÀ¸·Î ³ª¿À´Â Á¤º¸°¡ ÀÖ´Ù. + ¿¹¸¦ µé¾î, Ç׸ñÀº º¸Åë ´ÙÀ½°ú °°´Ù.

    + +

    + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test +

    + +

    ·Î±× Ç׸ñ¿¡¼­ ù¹ø° Ç׸ñÀº ³¯Â¥¿Í ½Ã°£ÀÌ´Ù. µÎ¹ø° + Ç׸ñÀº º¸°íÇÏ´Â ¿À·ùÀÇ ½É°¢¼ºÀ» ³ªÅ¸³½´Ù. LogLevel Áö½Ã¾î·Î ¿À·ù ·Î±×¿¡ + ±â·ÏµÇ´Â ¿À·ùÀÇ ½É°¢¼ºÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. ¼¼¹ø° Ç׸ñÀº + ¿À·ù¸¦ ¹ß»ýÇÑ Å¬¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼ÒÀÌ´Ù. ÀÌ ´ÙÀ½ºÎÅÍ ¿À·ù¹®ÀÌ + ³ª¿À¸ç, ÀÌ °æ¿ì ¼­¹ö°¡ Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» °ÅºÎÇϵµ·Ï + ¼³Á¤µÇ¾ú´Ù°í ³ª¿ÍÀÖ´Ù. ¿äûÇÑ ¹®¼­ÀÇ (À¥ °æ·Î°¡ ¾Æ´Ñ) + ÆÄÀϽýºÅÛ °æ·Îµµ º¸ÀδÙ.

    + +

    ¿À·ù ·Î±×¿¡´Â ¸Å¿ì ´Ù¾çÇÑ Á¾·ùÀÇ ¹®±¸°¡ ³ª¿Ã ¼ö ÀÖ´Ù. + ´ëºÎºÐÀº À§¿Í ºñ½ÁÇÏ´Ù. CGI ½ºÅ©¸³Æ®ÀÇ µð¹ö±ë Ãâ·Âµµ ¿À·ù + ·Î±×¿¡ ±â·ÏµÈ´Ù. CGI ½ºÅ©¸³Æ®°¡ stderr¿¡ ¾´ + Á¤º¸´Â ±×´ë·Î ¿À·ù ·Î±×·Î º¹»çµÈ´Ù.

    + +

    ¿À·ù ·Î±×¿¡ Á¤º¸¸¦ Ãß°¡ÇÏ°¡³ª »ý·«ÇÒ ¼ö ¾ø´Ù. ±×·¯³ª + ¿äû¿¡ ´ëÇÑ ¿À·ù ·Î±×ÀÇ °æ¿ì Á¢±Ù + ·Î±×¿¡µµ ´ëÀÀÇÏ´Â Ç׸ñÀÌ »ý±ä´Ù. ¿¹¸¦ µé¾î, À§ÀÇ °æ¿ì + »óÅÂÄڵ尡 403ÀÎ Á¢±Ù ·Î±× Ç׸ñÀÌ »ý±ä´Ù. Á¢±Ù ·Î±×´Â + »ç¿ëÀÚÁ¤ÀÇÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÀÌ ÆÄÀÏÀ» Âü°íÇÏ¿© ¿À·ù »óȲ¿¡ + ´ëÇÑ Ãß°¡Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

    + +

    °Ë»çÇÒ¶§ ¾î¶² ¹®Á¦°¡ »ý±â´ÂÁö ¿À·ù ·Î±×¸¦ °è¼Ó »ìÆ캸´Â + °ÍÀÌ ÁÁ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ´ÙÀ½°ú °°ÀÌ ÇÑ´Ù:

    + +

    + tail -f error_log +

    +
    top
    +
    +

    Á¢±Ù ·Î±× (Access Log)

    + + + + +

    ¼­¹ö Á¢±Ù ·Î±×´Â ¼­¹ö°¡ ó¸®ÇÏ´Â ¸ðµç ¿äûÀ» ±â·ÏÇÑ´Ù. + CustomLog + Áö½Ã¾î´Â Á¢±Ù ·Î±×ÀÇ À§Ä¡¿Í ³»¿ëÀ» ÁöÁ¤ÇÑ´Ù. LogFormat Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ·Î±×¿¡ Æ÷ÇÔÇÒ ³»¿ëÀ» ½±°Ô ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. ÀÌ ÀýÀº + ¼­¹ö°¡ Á¢±Ù ·Î±×¿¡ ¾µ ³»¿ëÀ» ¼³Á¤ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹°·Ð Á¢±Ù ·Î±×¿¡ Á¤º¸¸¦ ±â·ÏÇÏ´Â °ÍÀº ·Î±× °ü¸®ÀÇ ½ÃÀÛÀÏ + »ÓÀÌ´Ù. ´ÙÀ½ ´Ü°è´Â ÀÌ Á¤º¸¸¦ ºÐ¼®ÇÏ¿© À¯¿ëÇÑ Åë°è¸¦ ¸¸µå´Â + °ÍÀÌ´Ù. ÀÌ ¹®¼­´Â ÀϹÝÀûÀÎ ·Î±× ºÐ¼®¿¡ ´ëÇؼ­ ´Ù·çÁö ¾ÊÀ¸¸ç, + ·Î±× ºÐ¼®Àº ½ÇÁ¦ À¥¼­¹ö°¡ ÇÒ ÀÏÀÌ ¾Æ´Ï´Ù. ·Î±× ºÐ¼®¿¡ ´ëÇÑ + Á¤º¸¿Í ·Î±×¸¦ ºÐ¼®ÇÏ´Â ¼ÒÇÁÆ®¿þ¾î¿¡ ´ëÇؼ­´Â Open Directory³ª + Yahoo¸¦ + Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌÀüºÎÅÍ mod_log_referer, mod_log_agent, + CustomLog + °°Àº ¸ðµâ°ú Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Á¢±Ù ·Î±×¸¦ ´Ù·ç¾ú´Ù. Áö±ÝÀº + CustomLog + Áö½Ã¾î°¡ ¿À·¡µÈ Áö½Ã¾îµéÀÇ ¸ðµç ±â´ÉÀ» À̾î¹Þ¾Ò´Ù.

    + +

    Á¢±Ù ·Î±×ÀÇ Çü½ÄÀº ¸Å¿ì »ç¿ëÀÚÁ¤ÀÇ °¡´ÉÇÏ´Ù. Çü½ÄÀº CÀÇ + printf(1) Çü½Ä¹®ÀÚ¿­°ú ¸Å¿ì À¯»çÇÑ Çü½Ä¹®ÀÚ¿­À» »ç¿ëÇÏ¿© + ÁöÁ¤ÇÑ´Ù. ´ÙÀ½ Àý¿¡ ¿¹¸¦ µé¾ú´Ù. Çü½Ä¹®ÀÚ¿­¿¡ »ç¿ë°¡´ÉÇÑ + ¸ðµç ³»¿ëÀ» ¾Ë·Á¸é mod_log_config Çü½Ä¹®ÀÚ¿­À» + Âü°íÇ϶ó.

    + +

    Common ·Î±× Çü½Ä

    + + +

    Á¢±Ù ·Î±×ÀÇ ÀüÇüÀûÀÎ ¼³Á¤Àº ´ÙÀ½°ú °°´Ù.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +

    + +

    ±×·¯¸é ÁöÁ¤ÇÑ ·Î±× Çü½Ä¹®ÀÚ¿­À» º°¸í + commonÀ¸·Î Á¤ÀÇÇÑ´Ù. Çü½Ä¹®ÀÚ¿­Àº ÆÛ¼¾Æ® + Áö½Ã¾îµé·Î ±¸¼ºµÇ¸ç, °¢°¢Àº ¾î¶² Á¤º¸¸¦ ±â·ÏÇÒÁö ¾Ë¸°´Ù. + Çü½Ä¹®ÀÚ¿­¿¡ ÀÏ¹Ý ¹®ÀÚ¸¦ ÀûÀ¸¸é ±×´ë·Î ·Î±×¿¡ Ãâ·ÂµÈ´Ù. + µû¿ÈÇ¥ ¹®ÀÚ(")¸¦ Ãâ·ÂÇÏ°í ½Í´Ù¸é ¹é½½·¡½¬¸¦ + ¾Õ¿¡ ºÙ¿©¼­ Çü½Ä¹®ÀÚ¿­ÀÇ ³¡ÀÌ ¾Æ´ÔÀ» Ç¥½ÃÇÑ´Ù. Çü½Ä¹®ÀÚ¿­¿¡ + ÁÙ¹Ù²Þ "\n", ÅÇ "\t"¿Í °°Àº + Ư¼ö Á¶Àý¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    CustomLog + Áö½Ã¾î´Â Á¤ÀÇÇÑ º°¸íÀ» »ç¿ëÇÏ´Â »õ·Î¿î ·Î±×ÆÄÀÏÀ» + ¸¸µç´Ù. Á¢±Ù ·Î±×ÀÇ ÆÄÀϸíÀÌ ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾ÊÀ¸¸é + ServerRootÀÇ »ó´ë°æ·ÎÀÌ´Ù.

    + +

    ¾ÕÀÇ ¼³Á¤Àº °øÅë·Î±×Çü½Ä(Common Log Format, CLF)À̶ó´Â + Çü½ÄÀ¸·Î ·Î±× Ç׸ñÀ» ±â·ÏÇÑ´Ù. ¿©·¯ ´Ù¸¥ À¥¼­¹öµéµµ ÀÌ·± + Ç¥ÁØ Çü½ÄÀ¸·Î ·Î±×¸¦ ¸¸µé¸ç, ¿©·¯ ·Î±× ºÐ¼® ÇÁ·Î±×·¥¿¡¼­ + ÀÐÀ» ¼ö ÀÖ´Ù. CLF·Î ¸¸µç ·Î±×ÆÄÀÏ Ç׸ñÀº ´ÙÀ½°ú °°´Ù:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 +

    + +

    ÀÌÁ¦ ·Î±× Ç׸ñÀÇ °¢ ºÎºÐÀ» ¼³¸íÇÑ´Ù.

    + +
    +
    127.0.0.1 (%h)
    + +
    ¼­¹ö¿¡ ¿äûÀ» ÇÑ Å¬¶óÀ̾ðÆ®(¿ø°Ý È£½ºÆ®)ÀÇ IP + ÁÖ¼ÒÀÌ´Ù. HostnameLookups°¡ + OnÀ̶ó¸é È£½ºÆ®¸íÀ» ã¾Æ¼­ IP ÁÖ¼Ò ÀÚ¸®¿¡ + ´ë½Å ¾´´Ù. ±×·¯³ª ÀÌ ¼³Á¤Àº ¼­¹ö¸¦ ¸Å¿ì ´À¸®°Ô ÇÒ ¼ö + ÀÖÀ¸¹Ç·Î ÃßõÇÏÁö ¾Ê´Â´Ù. È£½ºÆ®¸íÀ» ¾Ë·Á¸é ´ë½Å ³ªÁß¿¡ + logresolve¿Í + °°Àº ·Î±×¸¦ ó¸®ÇÏ´Â ÇÁ·Î±×·¥À» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. + ¿©±â¿¡ ³ª¿Â IP ÁÖ¼Ò´Â »ç¿ëÀÚ°¡ »ç¿ëÇÏ´Â ÄÄÇ»ÅÍ ÁÖ¼Ò°¡ + ¾Æ´Ò ¼ö ÀÖ´Ù. ÇÁ·Ï½Ã ¼­¹ö°¡ »ç¿ëÀÚ¿Í ¼­¹ö»çÀÌ¿¡ Á¸ÀçÇÑ´Ù¸é, + ¿ø·¡ ÄÄÇ»ÅÍ ÁÖ¼Ò°¡ ¾Æ´Ï¶ó ÇÁ·Ï½ÃÀÇ ÁÖ¼Ò°¡ ±â·ÏµÉ °ÍÀÌ´Ù.
    + +
    - (%l)
    + +
    Ãâ·Â¿¡¼­ "»©±â±âÈ£"´Â ¿äûÇÑ Á¤º¸°¡ ¾øÀ½À» ³ªÅ¸³½´Ù. + ÀÌ °æ¿ì ¿©±â¿¡ ³ª¿Ã Á¤º¸´Â Ŭ¶óÀ̾ðÆ® ÄÄÇ»ÅÍÀÇ + identd°¡ Á¦°øÇÒ Å¬¶óÀ̾ðÆ®ÀÇ RFC 1413 + ½Å¿øÀÌ´Ù. ÀÌ Á¤º¸´Â ¸Å¿ì ¹ÏÀ» ¼ö ¾ø±â¶§¹®¿¡, ±ä¹ÐÈ÷ + °ü¸®µÇ´Â ³»ºÎ ³×Æ®¿÷ÀÌ ¾Æ´Ï¶ó¸é Àý´ë·Î ÀÌ Á¤º¸¸¦ »ç¿ëÇϸé + ¾ÈµÈ´Ù. IdentityCheck°¡ + OnÀÌ ¾Æ´Ï¶ó¸é ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ Á¤º¸¸¦ + ¾Ë¾Æº¸·Á°í ½ÃµµÇÏÁöµµ ¾Ê´Â´Ù.
    + +
    frank (%u)
    + +
    ÀÌ´Â HTTP ÀÎÁõÀ¸·Î ¾Ë¾Æ³½ ¹®¼­¸¦ ¿äûÇÑ »ç¿ëÀÚÀÇ + useridÀÌ´Ù. º¸Åë ÀÌ °ªÀº CGI ½ºÅ©¸³Æ®¿¡°Ô + REMOTE_USER ȯ°æº¯¼ö·Î ³Ñ°ÜÁø´Ù. ¿äûÀÇ + »óÅÂÄڵ尡 401À̶ó¸é (¾Æ·¡ Âü°í) »ç¿ëÀÚ°¡ ¾ÆÁ÷ ÀÎÁõÀ» + °ÅÄ¡Áö ¾Ê¾ÒÀ¸¹Ç·Î ÀÌ °ªÀ» ¹ÏÀ¸¸é ¾ÈµÈ´Ù. ¹®¼­¸¦ ¾ÏÈ£·Î + º¸È£ÇÏÁö ¾Ê´Â´Ù¸é ÀÌ Ç׸ñÀº ÀÌÀü Ç׸ñ°ú °°ÀÌ + "-"ÀÌ´Ù.
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + ¼­¹ö°¡ ¿äû󸮸¦ ¸¶Ä£ ½Ã°£. + Çü½ÄÀº: + +

    + [day/month/year:hour:minute:second zone]
    + day = ¼ýÀÚ 2°³
    + month = ¼ýÀÚ 3°³
    + year = ¼ýÀÚ 4°³
    + hour = ¼ýÀÚ 2°³
    + minute = ¼ýÀÚ 2°³
    + second = ¼ýÀÚ 2°³
    + zone = (`+' | `-') ¼ýÀÚ 4°³
    +

    + ·Î±× Çü½Ä¹®ÀÚ¿­¿¡ %{format}t¸¦ »ç¿ëÇÏ¿© + ´Ù¸¥ Çü½ÄÀ¸·Î ½Ã°£À» Ãâ·ÂÇÒ ¼ö ÀÖ´Ù. formatÀº + C Ç¥ÁØ ¶óÀ̺귯¸®ÀÇ strftime(3)°ú °°´Ù. +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÁÙÀÌ ½Öµû¿ÈÇ¥·Î ¹­¿©ÀÖ´Ù. ¿äûÁÙÀº + ¸Å¿ì À¯¿ëÇÑ Á¤º¸¸¦ ´ã°í ÀÖ´Ù. ù°, Ŭ¶óÀ̾ðÆ®°¡ »ç¿ëÇÑ + ¸Þ½áµå´Â GETÀÌ´Ù. µÑ°, Ŭ¶óÀ̾ðÆ®´Â ÀÚ¿ø + /apache_pb.gif¸¦ ¿äûÇÑ´Ù. ¼¼¹ø°, Ŭ¶óÀ̾ðÆ®´Â + HTTP/1.0 ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÑ´Ù. ¿äûÁÙÀÇ + ¿©·¯ ºÎºÐÀ» µû·Î ·Î±×ÇÒ ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, Çü½Ä¹®ÀÚ¿­ + "%m %U%q %H"Àº "%r"°ú ¶È°°ÀÌ + ¸Þ½áµå, °æ·Î, ÁúÀǹ®ÀÚ¿­, ÇÁ·ÎÅäÄÝÀ» ·Î±×ÇÑ´Ù.
    + +
    200 (%>s)
    + +
    ÀÌ´Â ¼­¹ö°¡ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â »óÅÂÄÚµåÀÌ´Ù. ÀÌ + Á¤º¸´Â (2·Î ½ÃÀÛÇÏ´Â ÄÚµå) ¿äûÀÌ ¼º°øÇÏ¿´´ÂÁö, (4·Î + ½ÃÀÛÇÏ´Â ÄÚµå) Ŭ¶óÀ̾ðÆ®¿¡ ¿À·ù°¡ ÀÖ´ÂÁö, (5·Î ½ÃÀÛÇÏ´Â + ÄÚµå) ¼­¹ö¿¡ ¿À·ù°¡ ÀÖ´ÂÁö ¾Ë·ÁÁֹǷΠ¸Å¿ì Áß¿äÇÏ´Ù. + »óÅÂÄÚµåÀÇ Àüü ¸ñ·ÏÀº HTTP + ±Ô¾à (RFC2616 section 10)¿¡¼­ ãÀ» ¼ö ÀÖ´Ù.
    + +
    2326 (%b)
    + +
    ¸¶Áö¸· Ç׸ñÀº ÀÀ´ä Çì´õ¸¦ Á¦¿ÜÇÏ°í Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³»´Â ³»¿ëÀÇ Å©±â¸¦ ³ªÅ¸³½´Ù. Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â + ³»¿ëÀÌ ¾ø´Ù¸é ÀÌ °ªÀº "-"ÀÌ´Ù. ³»¿ëÀÌ + ¾ø´Â °æ¿ì "0"À» ·Î±×ÇÏ·Á¸é ´ë½Å + %B¸¦ »ç¿ëÇÑ´Ù.
    +
    + + +

    Combined ·Î±× Çü½Ä

    + + +

    ÀÚÁÖ »ç¿ëµÇ´Â ´Ù¸¥ Çü½Ä¹®ÀÚ¿­Àº °áÇյȷα×Çü½Ä(Combined + Log Format)ÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +

    + +

    ÀÌ Çü½ÄÀº µÎ Ç׸ñÀ» ´õ Ãß°¡ÇÑ °ÍÀ» Á¦¿ÜÇÏ°í´Â Common + ·Î±× Çü½Ä°ú ¿ÏÀüÈ÷ °°´Ù. Ãß°¡µÈ Ç׸ñµéÀº ÆÛ¼¾Æ® Áö½Ã¾î + %{header}i¸¦ »ç¿ëÇÑ´Ù. ¿©±â¼­ + header ÀÚ¸®¿¡ HTTP ¿äû Çì´õ À̸§ÀÌ ³ª¿Ã ¼ö + ÀÖ´Ù. ÀÌ Çü½ÄÀÇ Á¢±Ù ·Î±×´Â ´ÙÀ½°ú °°´Ù:

    + +

    + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" +

    + +

    Ãß°¡µÈ Ç׸ñÀº:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    "Referer" (¸ÂÃã¹ý Ʋ¸®Áö¾Ê¾ÒÀ½) HTTP ¿äû Çì´õ. + Ŭ¶óÀ̾ðÆ®°¡ ÂüÁ¶Çß´Ù°í ¼­¹ö¿¡°Ô ¾Ë¸° »çÀÌÆ®ÀÌ´Ù. + (Áï, /apache_pb.gif¸¦ ¸µÅ©ÇÏ¿´°Å³ª Æ÷ÇÔÇÑ + »çÀÌÆ®ÀÌ´Ù.)
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    User-Agent HTTP ¿äû Çì´õ. Ŭ¶óÀ̾ðÆ® ºê¶ó¿ìÀú°¡ + Àڽſ¡ ´ëÇØ ¾Ë¸®´Â ½Äº°Á¤º¸ÀÌ´Ù.
    +
    + + +

    ¿©·¯ Á¢±Ù ·Î±×

    + + +

    ¼³Á¤ÆÄÀÏ¿¡ ¿©·¯ CustomLog Áö½Ã¾î¸¦ + »ç¿ëÇϸé Á¢±Ù ·Î±×°¡ ¿©·¯°³ ¸¸µé¾îÁø´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ + ¼³Á¤Àº ¼¼°¡Áö Á¢±Ù ·Î±×¸¦ ¸¸µç´Ù. ù¹ø°´Â ±âº» CLF Á¤º¸¸¦ + ±â·ÏÇÏ°í, µÎ¹ø°¿Í ¼¼¹ø°´Â referer¿Í ºê¶ó¿ìÀú Á¤º¸¸¦ + ±â·ÏÇÑ´Ù. ¸¶Áö¸· µÎ CustomLog ÁÙÀº ¾î¶»°Ô + ÀÌÀü ReferLog¿Í AgentLog Áö½Ã¾îÀÇ + ±â´ÉÀ» Èä³»³¾ ¼ö ÀÖ´ÂÁö º¸¿©ÁØ´Ù.

    + +

    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +

    + +

    ¶Ç, ÀÌ ¿¹´Â LogFormatÀ¸·Î ¹Ýµå½Ã + º°¸íÀ» Á¤ÀÇÇÒ ÇÊ¿ä´Â ¾øÀ½À» º¸¿©ÁØ´Ù. ´ë½Å CustomLog Áö½Ã¾î¿¡ + Á÷Á¢ ·Î±× Çü½ÄÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + + +

    Á¶°ÇºÎ ·Î±×

    + + +

    Ŭ¶óÀ̾ðÆ® ¿äûÀÇ ¼º°Ý¿¡ µû¶ó ÇØ´ç Ç׸ñÀ» Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÏÁö¾Ê°í ½ÍÀ» ¶§°¡ ÀÖ´Ù. ȯ°æº¯¼ö¸¦ + »ç¿ëÇÏ¸é ½±°Ô ÇØ°áµÈ´Ù. ¸ÕÀú, Ŭ¶óÀ̾ðÆ®°¡ ƯÁ¤ Á¶°ÇÀ» + ¸¸Á·Çϸé ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ ÀÛ¾÷¿¡´Â º¸Åë SetEnvIf¸¦ »ç¿ëÇÑ´Ù. + ±×¸®°í CustomLog + Áö½Ã¾î¿¡ env=À» »ç¿ëÇÏ¿© ȯ°æº¯¼ö À¯¹«¿¡ + µû¶ó ¿äûÀ» Áý¾î³Ö°Å³ª »«´Ù. ¿¹¸¦ µé¸é:

    + +

    + # loop-back ÀÎÅÍÆäÀ̽º¿¡¼­ ¿äûÀ» Ç¥½ÃÇÑ´Ù
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # robots.txt ÆÄÀÏ¿¡ ´ëÇÑ ¿äûÀ» Ç¥½ÃÇÑ´Ù
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # ³ª¸ÓÁö¸¦ ·Î±×¿¡ ³²±ä´Ù
    + CustomLog logs/access_log common env=!dontlog +

    + +

    ´Ù¸¥ ¿¹·Î ¿µ¾î±Ç »ç¿ëÀÚÀÇ ¿äû¸¸À» ÇÑ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ°í, + ºñ¿µ¾î±Ç »ç¿ëÀÚÀÇ ¿äûÀº ´Ù¸¥ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ´Â °æ¿ì¸¦ + »ý°¢Çغ¸ÀÚ.

    + +

    + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +

    + +

    Á¶°ÇºÎ ·Î±×´Â ¸Å¿ì °­·ÂÇÏ°í À¯¿¬ÇÏÁö¸¸, ÀÌ°ÍÀÌ ·Î±× + ³»¿ëÀ» Á¶ÀýÇÏ´Â À¯ÀÏÇÑ ¹æ¹ýÀº ¾Æ´Ï´Ù. ·Î±×ÆÄÀÏÀº ¼­¹öÀÇ + ¸ðµç ÇൿÀ» ±â·ÏÇÒ¶§ ´õ À¯¿ëÇÏ´Ù. ³ªÁß¿¡ ¿øÇÏÁö¾Ê´Â ¿äûÀ» + Á¦¿ÜÇÏ°í ·Î±×ÆÄÀÏÀ» ºÐ¼®ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    + +
    top
    +
    +

    ·Î±× ¼øȯ (Log Rotation)

    + + +

    Á¶±Ý ¹Ù»Û ¼­¹öÁ¶Â÷µµ ·Î±×ÆÄÀÏ¿¡ ÀúÀåµÇ´Â Á¤º¸·®Àº ¸Å¿ì + ¸¹´Ù. Á¢¼Ó ·Î±×´Â º¸Åë ¸¸¹ø ¿äû´ç 1MB ÀÌ»ó Áõ°¡ÇÑ´Ù. °á°úÀûÀ¸·Î + ±âÁ¸ÀÇ ·Î±×¸¦ ¿Å±â°Å³ª Áö¿ì´Â ¹æ¹ýÀ¸·Î ·Î±×¸¦ ÁÖ±âÀûÀ¸·Î + ¼øÈ°ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ÆÄÀÏÀ» ¿­°íÀÖ´Â µ¿¾È¿¡´Â °è¼Ó + ÀÌÀü ·Î±×ÆÄÀÏ¿¡ ¾²±â¶§¹®¿¡ ¼­¹ö°¡ ½ÇÇàÁßÀ϶§ ·Î±×¸¦ ¼øȯÇÒ + ¼ö ¾ø´Ù. ´ë½Å ·Î±×ÆÄÀÏÀ» ¿Å±â°Å³ª Áö¿îÈÄ ¼­¹ö¸¦ Àç½ÃÀÛÇÏ¿©, ·Î±×ÆÄÀÏÀ» »õ·Î ¿­¾î¾ß + ÇÑ´Ù.

    + +

    Á¡ÀÝÀº Àç½ÃÀÛÀ» »ç¿ëÇÏ¸é ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®¿Í + ±âÁ¸ÀÇ È¤Àº ´ë±âµÈ ¿¬°áÀ» ÀÒÁö¾Ê°í »õ ·Î±×ÆÄÀÏÀ» ¿­ ¼ö ÀÖ´Ù. + ±×·¯³ª À̸¦ À§ÇØ ¼­¹ö´Â ¿À·¡µÈ ¿äûÀÇ ¼­ºñ½º¸¦ ³¡³»´Â µ¿¾È + ÀÌÀü ·Î±×ÆÄÀÏÀ» °è¼Ó »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯¹Ç·Î Àç½ÃÀÛÇÑÈÄ + ·Î±×ÆÄÀÏÀ» ó¸®Çϱâ Àü¿¡ ¾ó¸¶°£ ±â´Ù¸± ÇÊ¿ä°¡ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î + ´ÙÀ½°ú °°ÀÌ ·Î±×¸¦ ¼øȯÇÏ°í, µð½ºÅ©°ø°£À» Àý¾àÇϱâÀ§ÇØ ÀÌÀü + ·Î±×¸¦ ¾ÐÃàÇÑ´Ù:

    + +

    + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +

    + +

    ·Î±×¸¦ ¼øȯÇÏ´Â ´Ù¸¥ ¹æ¹ýÀº ´ÙÀ½ Àý¿¡¼­ ¼³¸íÇÒ ÆÄÀÌÇÁ ·Î±×¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù.

    +
    top
    +
    +

    ·Î±×¸¦ ÆÄÀÌÇÁ·Î º¸³»±â

    + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¿À·ù ·Î±×¿Í Á¢±Ù ·Î±×¸¦ ÆÄÀÏ¿¡ Á÷Á¢ + ¾²Áö¾Ê°í ÆÄÀÌÇÁ¸¦ ÅëÇØ ´Ù¸¥ ÇÁ·Î¼¼½º·Î º¸³¾ ¼ö ÀÖ´Ù. ÀÌ + ±â´ÉÀ» »ç¿ëÇÏ¸é ¼­¹ö¿¡ Äڵ带 Ãß°¡ÇÏÁö¾Ê°íµµ ¸Å¿ì À¯¿¬ÇÏ°Ô + ·Î±×¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. ·Î±×¸¦ ÆÄÀÌÇÁ¿¡ ¾²±âÀ§ÇØ ÆÄÀϸí + ÀÚ¸®¿¡ ÆÄÀÌÇÁ¹®ÀÚ "|"¿Í µÚ¿¡ Ç¥ÁØÀÔ·ÂÀ¸·Î + ·Î±× Ç׸ñÀ» ÀÐÀ» ½ÇÇàÆÄÀϸíÀ» ÀûÀ¸¸é µÈ´Ù. ¾ÆÆÄÄ¡´Â ¼­¹ö°¡ + ½ÃÀÛÇÒ¶§ ÆÄÀÌÇÁ·Î ¿¬°áÇÒ ·Î±× ÇÁ·Î¼¼½º¸¦ ½ÃÀÛÇÏ°í, ¼­¹ö°¡ + ½ÇÇàµÇ´Â µ¿¾È ÇÁ·Î¼¼½º°¡ Á×À¸¸é ´Ù½Ã ½ÃÀÛÇÑ´Ù. (ÀÌ ¸¶Áö¸· + ±â´É¶§¹®¿¡ ¿ì¸®´Â ÀÌ ¹æ¹ýÀ» "¹ÏÀ» ¼ö ÀÖ´Â ÆÄÀÌÇÁ ·Î±×"¶ó°í + ºÎ¸¥´Ù.)

    + +

    ÆÄÀÌÇÁ·Î ¿¬°áµÈ ·Î±× ÇÁ·Î¼¼½º´Â ºÎ¸ð ¾ÆÆÄÄ¡ httpd ÇÁ·Î¼¼½º°¡ + ¶ç¿ì°í, ÇÁ·Î¼¼½ºÀÇ useridµµ °°´Ù. Áï, ÆÄÀÌÇÁ·Î ¿¬°áµÈ ·Î±× + ÇÁ·Î±×·¥Àº º¸Åë root·Î ½ÇÇàµÈ´Ù. ±×·¯¹Ç·Î ÇÁ·Î±×·¥À» °£´ÜÇÏ°í + ¾ÈÀüÇÏ°Ô ¸¸µå´Â °ÍÀÌ ¸Å¿ì Áß¿äÇÏ´Ù.

    + +

    ÆÄÀÌÇÁ·Î ºÎ¸£´Â Àüü ¸í·É¾î¸¦ µû¿ÈÇ¥·Î ¹­À½À» ¸í½ÉÇ϶ó. + ÀÌ ¿¹´Â Á¢±Ù ·Î±×¿¡ ´ëÇÑ °ÍÀÌÁö¸¸, ¿À·ù ·Î±×µµ ¸¶Âù°¡Áö´Ù.

    + +

    ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö¾Ê°í ·Î±×¸¦ ¼øȯÇÒ ¼ö ÀÖ´Â °ÍÀÌ ÆÄÀÌÇÁ + ·Î±×¸¦ »ç¿ëÇÏ´Â Áß¿äÇÑ ÀÌÀ¯´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â À̸¦ À§ÇØ + rotatelogs¶ó´Â °£´ÜÇÑ + ÇÁ·Î±×·¥À» Æ÷ÇÔÇÑ´Ù. ¿¹¸¦ µé¾î 24½Ã°£¸¶´Ù ·Î±×¸¦ ¼øȯÇÑ´Ù¸é:

    + +

    + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common +

    + +

    ´Ù¸¥ »çÀÌÆ®¿¡ cronolog¶ó´Â ºñ½ÁÇÏÁö¸¸ + ÈξÀ ´õ À¯¿¬ÇÑ ·Î±× ¼øȯ ÇÁ·Î±×·¥ÀÌ ÀÖ´Ù.

    + +

    Á¶°ÇºÎ ·Î±×¿Í °°ÀÌ ÆÄÀÌÇÁ ·Î±×´Â ¸Å¿ì °­·ÂÇÑ µµ±¸Áö¸¸, + ³ªÁß¿¡ ó¸®ÇÏ´Â µîÀÇ ´õ °£´ÜÇÑ ¹æ¹ýÀÌ °¡´ÉÇÑ °æ¿ì »ç¿ëÇؼ­´Â + ¾ÈµÈ´Ù.

    +
    top
    +
    +

    °¡»óÈ£½ºÆ®

    + + +

    ¸¹Àº °¡»óÈ£½ºÆ®°¡ ÀÖ´Â ¼­¹ö¸¦ + ¿î¿µÇÒ¶§ ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î ·Î±×ÆÄÀÏÀ» ´Ù·ê ¼ö ÀÖ´Ù. ¸ÕÀú, + È£½ºÆ®°¡ ÇÑ°³ÀÎ ¼­¹ö¿Í °°ÀÌ ·Î±×¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. <VirtualHost> ¼½¼ÇÀÌ + ¾Æ´Ñ ÁÖ¼­¹ö ¼³Á¤¿¡ ·Î±× Áö½Ã¾î¸¦ µÎ¸é ¸ðµç ¿äûÀÌ °°Àº Á¢±Ù + ·Î±×¿Í ¿À·ù ·Î±×·Î ±â·ÏµÈ´Ù. ÀÌ ¹æ¹ýÀº °¡»óÈ£½ºÆ®º°·Î ½±°Ô + Åë°è󸮸¦ ÇÒ ¼ö ¾ø´Ù.

    + +

    <VirtualHost> + ¼½¼Ç ¾È¿¡ CustomLog³ª + ErrorLog Áö½Ã¾î¸¦ + »ç¿ëÇϸé ÇØ´ç °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ ¿äû°ú ¿À·ù¸¸ÀÌ ÁöÁ¤µÈ + ÆÄÀÏ¿¡ ±â·ÏµÈ´Ù. ·Î±× Áö½Ã¾î°¡ ¾ø´Â ´Ù¸¥ °¡»óÈ£½ºÆ®´Â °è¼Ó + ÁÖ¼­¹ö ·Î±×¿¡ ·Î±×¸¦ ±â·ÏÇÑ´Ù. ÀÌ ¹æ¹ýÀº °¡»óÈ£½ºÆ® °³¼ö°¡ + ÀûÀ» °æ¿ì ¸Å¿ì À¯¿ëÇÏÁö¸¸, È£½ºÆ® ¼ö°¡ ¸¹´Ù¸é °ü¸®Çϱâ + Èûµé¾îÁø´Ù. ¶Ç, ÆÄÀϱâ¼úÀÚ°¡ + ºÎÁ·ÇÑ ¹®Á¦°¡ ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    Á¢±Ù ·Î±×ÀÇ °æ¿ì ¸Å¿ì ÁÁÀº ÇØ°áÃ¥ÀÌ ÀÖ´Ù. ·Î±× Çü½Ä¹®ÀÚ¿­¿¡ + °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ Á¤º¸¸¦ Ãß°¡ÇÏ¸é ¸ðµç È£½ºÆ®°¡ °°Àº ·Î±×¸¦ + »ç¿ëÇÏ°í, ³ªÁß¿¡ ·Î±×¸¦ °¡»óÈ£½ºÆ®º°·Î ³ª´­ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ´ÙÀ½ Áö½Ã¾î¸¦ ºÁ¶ó.

    + +

    + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +

    + +

    %v´Â ¿äûÀ» ¼­ºñ½ºÇÏ´Â °¡»óÈ£½ºÆ® À̸§À» + ±â·ÏÇÑ´Ù. ³ªÁß¿¡ split-logfile + °°Àº ÇÁ·Î±×·¥À¸·Î Á¢±Ù ·Î±×¸¦ °¡»óÈ£½ºº°·Î ³ª´­ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ´Ù¸¥ ·Î±×ÆÄÀÏ

    + + + + +

    PID ÆÄÀÏ

    + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ½ÃÀÛÇÒ¶§ logs/httpd.pid + ÆÄÀÏ¿¡ ºÎ¸ð httpd ÇÁ·Î¼¼½ºÀÇ process id¸¦ ÀúÀåÇÑ´Ù. ÀÌ + ÆÄÀϸíÀº PidFile + Áö½Ã¾î·Î º¯°æÇÒ ¼ö ÀÖ´Ù. process-id´Â °ü¸®ÀÚ°¡ ºÎ¸ð ÇÁ·Î¼¼½º¿¡ + ½Ã±×³ÎÀ» º¸³» ¼­¹ö¸¦ Àç½ÃÀÛÇϰųª Á×À϶§ »ç¿ëÇÑ´Ù. + À©µµ¿ìÁî¿¡¼­´Â ´ë½Å -k ¸í·ÉÇà¿É¼ÇÀ» »ç¿ëÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ + Á¤º¸´Â Áß´Ü°ú Àç½ÃÀÛ ÆäÀÌÁö¸¦ + Âü°íÇ϶ó.

    + + +

    ½ºÅ©¸³Æ® ·Î±×

    + + +

    µð¹ö±ëÀ» µ½±âÀ§ÇØ ScriptLog Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + CGI ½ºÅ©¸³Æ®ÀÇ ÀԷ°ú Ãâ·ÂÀ» ±â·ÏÇÒ ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾î´Â + ¿ÀÁ÷ Å×½ºÆ®¿ëÀ¸·Î¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù. ½ÇÁ¦ »ç¿ëÇÏ´Â ¼­¹ö¿¡¼­ + »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â mod_cgi ¹®¼­¸¦ Âü°íÇ϶ó.

    + + +

    ÀçÀÛ¼º ·Î±×

    + + +

    mod_rewriteÀÇ °­·ÂÇÏ°í + º¹ÀâÇÑ ±â´ÉÀ» »ç¿ëÇÑ´Ù¸é µð¹ö±ëÀ» À§ÇØ °ÅÀÇ Ç×»ó RewriteLog¸¦ »ç¿ëÇÒ ÇÊ¿ä°¡ + ÀÖ´Ù. ÀÌ ·Î±×ÆÄÀÏÀº ÀçÀÛ¼º ¿£ÁøÀÌ ¾î¶»°Ô ¿äûÀ» º¯È¯ÇÏ´ÂÁö¿¡ + ´ëÇØ ÀÚ¼¼È÷ ¾Ë·ÁÁØ´Ù. ÀÚ¼¼ÇÑ Á¤µµ´Â RewriteLogLevel Áö½Ã¾î·Î + Á¶ÀýÇÑ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/logs.xml b/trunk/docs/manual/logs.xml new file mode 100644 index 0000000000..4592364269 --- /dev/null +++ b/trunk/docs/manual/logs.xml @@ -0,0 +1,625 @@ + + + + + + + + + + Log Files + + +

    In order to effectively manage a web server, it is necessary + to get feedback about the activity and performance of the + server as well as any problems that may be occurring. The Apache + HTTP Server provides very comprehensive and flexible logging + capabilities. This document describes how to configure its + logging capabilities, and how to understand what the logs + contain.

    +
    + +
    + Security Warning + +

    Anyone who can write to the directory where Apache is + writing a log file can almost certainly gain access to the uid + that the server is started as, which is normally root. Do + NOT give people write access to the directory the logs + are stored in without being aware of the consequences; see the + security tips document + for details.

    + +

    In addition, log files may contain information supplied + directly by the client, without escaping. Therefore, it is + possible for malicious clients to insert control-characters in + the log files, so care must be taken in dealing with raw + logs.

    +
    + +
    + Error Log + + + + ErrorLog + LogLevel + + + +

    The server error log, whose name and location is set by the + ErrorLog directive, is the + most important log file. This is the place where Apache httpd + will send diagnostic information and record any errors that it + encounters in processing requests. It is the first place to + look when a problem occurs with starting the server or with the + operation of the server, since it will often contain details of + what went wrong and how to fix it.

    + +

    The error log is usually written to a file (typically + error_log on unix systems and + error.log on Windows and OS/2). On unix systems it + is also possible to have the server send errors to + syslog or pipe them to a + program.

    + +

    The format of the error log is relatively free-form and + descriptive. But there is certain information that is contained + in most error log entries. For example, here is a typical + message.

    + + + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test + + +

    The first item in the log entry is the date and time of the + message. The second entry lists the severity of the error being + reported. The LogLevel + directive is used to control the types of errors that are sent + to the error log by restricting the severity level. The third + entry gives the IP address of the client that generated the + error. Beyond that is the message itself, which in this case + indicates that the server has been configured to deny the + client access. The server reports the file-system path (as + opposed to the web path) of the requested document.

    + +

    A very wide variety of different messages can appear in the + error log. Most look similar to the example above. The error + log will also contain debugging output from CGI scripts. Any + information written to stderr by a CGI script will + be copied directly to the error log.

    + +

    It is not possible to customize the error log by adding or + removing information. However, error log entries dealing with + particular requests have corresponding entries in the access log. For example, the above example + entry corresponds to an access log entry with status code 403. + Since it is possible to customize the access log, you can + obtain more information about error conditions using that log + file.

    + +

    During testing, it is often useful to continuously monitor + the error log for any problems. On unix systems, you can + accomplish this using:

    + + + tail -f error_log + +
    + +
    + Access Log + + + + mod_log_config + mod_setenvif + + + CustomLog + LogFormat + SetEnvIf + + + +

    The server access log records all requests processed by the + server. The location and content of the access log are + controlled by the CustomLog + directive. The LogFormat + directive can be used to simplify the selection of + the contents of the logs. This section describes how to configure the server + to record information in the access log.

    + +

    Of course, storing the information in the access log is only + the start of log management. The next step is to analyze this + information to produce useful statistics. Log analysis in + general is beyond the scope of this document, and not really + part of the job of the web server itself. For more information + about this topic, and for applications which perform log + analysis, check the + Open Directory or + Yahoo.

    + +

    Various versions of Apache httpd have used other modules and + directives to control access logging, including + mod_log_referer, mod_log_agent, and the + TransferLog directive. The CustomLog directive now subsumes + the functionality of all the older directives.

    + +

    The format of the access log is highly configurable. The format + is specified using a format string that looks much like a C-style + printf(1) format string. Some examples are presented in the next + sections. For a complete list of the possible contents of the + format string, see the mod_log_config format strings.

    + +
    + Common Log Format + +

    A typical configuration for the access log might look as + follows.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +
    + +

    This defines the nickname common and + associates it with a particular log format string. The format + string consists of percent directives, each of which tell the + server to log a particular piece of information. Literal + characters may also be placed in the format string and will be + copied directly into the log output. The quote character + (") must be escaped by placing a back-slash before + it to prevent it from being interpreted as the end of the + format string. The format string may also contain the special + control characters "\n" for new-line and + "\t" for tab.

    + +

    The CustomLog + directive sets up a new log file using the defined + nickname. The filename for the access log is relative to + the ServerRoot unless it + begins with a slash.

    + +

    The above configuration will write log entries in a format + known as the Common Log Format (CLF). This standard format can + be produced by many different web servers and read by many log + analysis programs. The log file entries produced in CLF will + look something like this:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + + +

    Each part of this log entry is described below.

    + +
    +
    127.0.0.1 (%h)
    + +
    This is the IP address of the client (remote host) which + made the request to the server. If HostnameLookups is + set to On, then the server will try to determine + the hostname and log it in place of the IP address. However, + this configuration is not recommended since it can + significantly slow the server. Instead, it is best to use a + log post-processor such as logresolve to determine + the hostnames. The IP address reported here is not + necessarily the address of the machine at which the user is + sitting. If a proxy server exists between the user and the + server, this address will be the address of the proxy, rather + than the originating machine.
    + +
    - (%l)
    + +
    The "hyphen" in the output indicates that the requested + piece of information is not available. In this case, the + information that is not available is the RFC 1413 identity of + the client determined by identd on the clients + machine. This information is highly unreliable and should + almost never be used except on tightly controlled internal + networks. Apache httpd will not even attempt to determine + this information unless IdentityCheck is set + to On.
    + +
    frank (%u)
    + +
    This is the userid of the person requesting the document + as determined by HTTP authentication. The same value is + typically provided to CGI scripts in the + REMOTE_USER environment variable. If the status + code for the request (see below) is 401, then this value + should not be trusted because the user is not yet + authenticated. If the document is not password protected, + this entry will be "-" just like the previous + one.
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + The time that the request was received. + The format is: + +

    + [day/month/year:hour:minute:second zone]
    + day = 2*digit
    + month = 3*letter
    + year = 4*digit
    + hour = 2*digit
    + minute = 2*digit
    + second = 2*digit
    + zone = (`+' | `-') 4*digit
    +

    + It is possible to have the time displayed in another format + by specifying %{format}t in the log format + string, where format is as in + strftime(3) from the C standard library. +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    The request line from the client is given in double + quotes. The request line contains a great deal of useful + information. First, the method used by the client is + GET. Second, the client requested the resource + /apache_pb.gif, and third, the client used the + protocol HTTP/1.0. It is also possible to log + one or more parts of the request line independently. For + example, the format string "%m %U%q %H" will log + the method, path, query-string, and protocol, resulting in + exactly the same output as "%r".
    + +
    200 (%>s)
    + +
    This is the status code that the server sends back to the + client. This information is very valuable, because it reveals + whether the request resulted in a successful response (codes + beginning in 2), a redirection (codes beginning in 3), an + error caused by the client (codes beginning in 4), or an + error in the server (codes beginning in 5). The full list of + possible status codes can be found in the HTTP + specification (RFC2616 section 10).
    + +
    2326 (%b)
    + +
    The last entry indicates the size of the object returned + to the client, not including the response headers. If no + content was returned to the client, this value will be + "-". To log "0" for no content, use + %B instead.
    +
    +
    + +
    + Combined Log Format + +

    Another commonly used format string is called the Combined + Log Format. It can be used as follows.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +
    + +

    This format is exactly the same as the Common Log Format, + with the addition of two more fields. Each of the additional + fields uses the percent-directive + %{header}i, where header can be + any HTTP request header. The access log under this format will + look like:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" + + +

    The additional fields are:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    The "Referer" (sic) HTTP request header. This gives the + site that the client reports having been referred from. (This + should be the page that links to or includes + /apache_pb.gif).
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    The User-Agent HTTP request header. This is the + identifying information that the client browser reports about + itself.
    +
    +
    + +
    + Multiple Access Logs + +

    Multiple access logs can be created simply by specifying + multiple CustomLog + directives in the configuration + file. For example, the following directives will create three + access logs. The first contains the basic CLF information, + while the second and third contain referer and browser + information. The last two CustomLog lines show how + to mimic the effects of the ReferLog and AgentLog directives.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +
    + +

    This example also shows that it is not necessary to define a + nickname with the LogFormat directive. Instead, + the log format can be specified directly in the CustomLog directive.

    +
    + +
    + Conditional Logs + +

    There are times when it is convenient to exclude certain + entries from the access logs based on characteristics of the + client request. This is easily accomplished with the help of environment variables. First, an + environment variable must be set to indicate that the request + meets certain conditions. This is usually accomplished with + SetEnvIf. Then the + env= clause of the CustomLog directive is used to + include or exclude requests where the environment variable is + set. Some examples:

    + + + # Mark requests from the loop-back interface
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # Mark requests for the robots.txt file
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # Log what remains
    + CustomLog logs/access_log common env=!dontlog +
    + +

    As another example, consider logging requests from + english-speakers to one log file, and non-english speakers to a + different log file.

    + + + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +
    + +

    Although we have just shown that conditional logging is very + powerful and flexibly, it is not the only way to control the + contents of the logs. Log files are more useful when they + contain a complete record of server activity. It is often + easier to simply post-process the log files to remove requests + that you do not want to consider.

    +
    +
    + +
    + Log Rotation + +

    On even a moderately busy server, the quantity of + information stored in the log files is very large. The access + log file typically grows 1 MB or more per 10,000 requests. It + will consequently be necessary to periodically rotate the log + files by moving or deleting the existing logs. This cannot be + done while the server is running, because Apache will continue + writing to the old log file as long as it holds the file open. + Instead, the server must be restarted after the log files are + moved or deleted so that it will open new log files.

    + +

    By using a graceful restart, the server can be + instructed to open new log files without losing any existing or + pending connections from clients. However, in order to + accomplish this, the server must continue to write to the old + log files while it finishes serving old requests. It is + therefore necessary to wait for some time after the restart + before doing any processing on the log files. A typical + scenario that simply rotates the logs and compresses the old + logs to save space is:

    + + + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +
    + +

    Another way to perform log rotation is using piped logs as discussed in the next + section.

    +
    + +
    + Piped Logs + +

    Apache httpd is capable of writing error and access log + files through a pipe to another process, rather than directly + to a file. This capability dramatically increases the + flexibility of logging, without adding code to the main server. + In order to write logs to a pipe, simply replace the filename + with the pipe character "|", followed by the name + of the executable which should accept log entries on its + standard input. Apache will start the piped-log process when + the server starts, and will restart it if it crashes while the + server is running. (This last feature is why we can refer to + this technique as "reliable piped logging".)

    + +

    Piped log processes are spawned by the parent Apache httpd + process, and inherit the userid of that process. This means + that piped log programs usually run as root. It is therefore + very important to keep the programs simple and secure.

    + +

    One important use of piped logs is to allow log rotation + without having to restart the server. The Apache HTTP Server + includes a simple program called rotatelogs + for this purpose. For example, to rotate the logs every 24 hours, you + can use:

    + + + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common + + +

    Notice that quotes are used to enclose the entire command + that will be called for the pipe. Although these examples are + for the access log, the same technique can be used for the + error log.

    + +

    A similar but much more flexible log rotation program + called cronolog + is available at an external site.

    + +

    As with conditional logging, piped logs are a very powerful + tool, but they should not be used where a simpler solution like + off-line post-processing is available.

    +
    + +
    + Virtual Hosts + +

    When running a server with many virtual + hosts, there are several options for dealing with log + files. First, it is possible to use logs exactly as in a + single-host server. Simply by placing the logging directives + outside the VirtualHost sections in the + main server context, it is possible to log all requests in the + same access log and error log. This technique does not allow + for easy collection of statistics on individual virtual + hosts.

    + +

    If CustomLog + or ErrorLog + directives are placed inside a + VirtualHost + section, all requests or errors for that virtual host will be + logged only to the specified file. Any virtual host which does + not have logging directives will still have its requests sent + to the main server logs. This technique is very useful for a + small number of virtual hosts, but if the number of hosts is + very large, it can be complicated to manage. In addition, it + can often create problems with insufficient file + descriptors.

    + +

    For the access log, there is a very good compromise. By + adding information on the virtual host to the log format + string, it is possible to log all hosts to the same log, and + later split the log into individual files. For example, + consider the following directives.

    + + + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +
    + +

    The %v is used to log the name of the virtual + host that is serving the request. Then a program like split-logfile can be used to + post-process the access log in order to split it into one file + per virtual host.

    +
    + +
    + Other Log Files + + + + mod_cgi + mod_rewrite + + + PidFile + RewriteLog + RewriteLogLevel + ScriptLog + ScriptLogBuffer + ScriptLogLength + + + +
    + PID File + +

    On startup, Apache httpd saves the process id of the parent + httpd process to the file logs/httpd.pid. This + filename can be changed with the PidFile directive. The + process-id is for use by the administrator in restarting and + terminating the daemon by sending signals to the parent + process; on Windows, use the -k command line option instead. + For more information see the Stopping + and Restarting page.

    +
    + +
    + Script Log + +

    In order to aid in debugging, the + ScriptLog directive + allows you to record the input to and output from CGI scripts. + This should only be used in testing - not for live servers. + More information is available in the mod_cgi documentation.

    +
    + +
    + Rewrite Log + +

    When using the powerful and complex features of mod_rewrite, it is almost + always necessary to use the RewriteLog to help + in debugging. This log file produces a detailed analysis of how + the rewriting engine transforms requests. The level of detail + is controlled by the RewriteLogLevel directive.

    +
    +
    +
    + + + + diff --git a/trunk/docs/manual/logs.xml.ja b/trunk/docs/manual/logs.xml.ja new file mode 100644 index 0000000000..ccf6cda4f9 --- /dev/null +++ b/trunk/docs/manual/logs.xml.ja @@ -0,0 +1,585 @@ + + + + + + + + + + $B%m%0%U%!%$%k(B + + +

    $B%&%'%V%5!<%P$r8z2LE*$K4IM}$9$k$?$a$K$O!"%5!<%P$N3hF0$d%Q%U%)!<%^%s%9!"(B + $B:#H/@8$7$F$$$k$+$b$7$l$J$$LdBj$K4X$9$k%U%#!<%I%P%C%/$rF@$k$3$H$,I,MW$G$9!#(B + Apache HTTP $B%5!<%P$K$OHs>o$KJq3gE*$G=@Fp$J%m%.%s%05!G=$,$"$j$^$9!#(B + $B$3$NJ8=q$O%m%.%s%05!G=$N@_Dj$N;EJ}$H!"%m%0$K2?$,=q$+$l$F$$$k$+$r(B + $BM}2r$9$k$?$a$NJ}K!$r@bL@$7$^$9!#(B

    +
    + +
    + $B%;%-%e%j%F%#$K4X$9$k7Y9p(B + +

    Apache $B$,%m%0%U%!%$%k$r=q$$$F$$$k%G%#%l%/%H%j$K=q$-9~$a$k?M$O!"(B + $B$[$\3No$O(B root $B%f!<%6$G$9!#(B + $B$A$c$s$H7k2L$r9M$($k$3$H$J$/!"$=$N%G%#%l%/%H%j$X$N(B + $B=q$-9~$_8"8B$rM?$((B$B$J$$(B$B$G$/$@$5$$!#>\$7$/$O(B + $B%;%-%e%j%F%#$N$3$D(B$B$NJ8=q$r(B + $BFI$s$G$/$@$5$$!#(B

    + +

    $B2C$($F!"%m%0%U%!%$%k$K$O%/%i%$%"%s%H$+$i$N>pJs$,$=$N$^$^!"(B + $B%(%9%1!<%W$5$l$k$3$H$J$/=q$+$l$F$$$^$9!#$G$9$+$i!"0-0U$N$"$k(B + $B%/%i%$%"%s%H$,%m%0%U%!%$%k$K@)8fJ8;z$rA^F~$9$k$3$H$,$G$-$^$9!#(B + $B@8$N%m%0$r07$&$H$-$OCm0U$7$F$/$@$5$$!#(B

    +
    + +
    + $B%(%i!<%m%0(B + + + ErrorLog + LogLevel + + + +

    ErrorLog $B%G%#%l%/%F%#%V$K$h$j(B + $BL>A0$H>l=j$,7h$^$k%5!<%P$N%(%i!<%m%0$O!"0lHV=EMW$J%m%0%U%!%$%k$G$9!#(B + Apache $B$N?GCG>pJs$O$3$3$KAw$i$l!"%j%/%(%9%H$r=hM}$7$F$$$k$H$-$K(B + $BH/@8$7$?%(%i!<$O$9$Y$F$3$3$K5-O?$5$l$^$9!#%5!<%P$r5/F0$7$?$H$-$d!"(B + $B%5!<%P$NF0:n$KLdBj$,5/$3$C$?$H$-$O!"0lHV:G=i$KD4$Y$k$Y$-(B + $B$H$3$m$G$9!#4V0c$$$N>\:Y$d=$@5J}K!$,$=$3$K=q$+$l$F$$$k$3$H$,(B + $B$h$/$"$j$^$9!#(B

    + +

    $B%(%i!<%m%0$OIaDL$O%U%!%$%k$K=q$+$l$^$9(B ($BDL>o(B unix $B%7%9%F%`$G$O(B + error_log$B!"(BWindows $B$H(B OS/2 $B$G$O(B error.log)$B!#(B + Unix $B%7%9%F%`$G$O%(%i!<$r(B syslog $B$d(B + $B%Q%$%W$G%W%m%0%i%`$KAw$k(B $B$3$H$,$G$-$^$9!#(B

    + +

    $B%(%i!<%m%0$N=q<0$OHf3SE*<+M3EY$N9b$$$b$N$G!"@bL@E*$K=q$+$l$F$$$^$9!#(B + $B$?$@$7!"$$$/$D$+$N>pJs$O$[$H$s$I$N%(%i!<%m%0$N%(%s%H%j$K$"$j$^$9!#(B + $BNc$($P!"BeI=E*$J$b$N$K + + + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test + + +

    $B%m%0%(%s%H%j$N:G=i$N9`L\$O%a%C%;!<%8$NF|IU$H;~9o$G$9!#(B + $BFs$D$a$N9`L\$OJs9p$5$l$F$$$k%(%i!<$N=EMWEY$G$9!#(B + LogLevel $B$G=EMWEY$N%l%Y%k$r(B + $B@)8B$9$k$3$H$K$h$j%(%i!<%m%0$KAw$i$l$k%(%i!<$Nl9g$O%5!<%P$,%/%i%$%"%s%H$N%"%/%;%9$r(B + $B5qH]$9$k$h$&$K@_Dj$5$l$F$$$k!"$H$$$&$3$H$r<($7$F$$$^$9!#(B + $B%5!<%P$O%j%/%(%9%H$5$l$?J8=q$N(B ($B%&%'%V$N%Q%9$G$O$J$/(B) $B%U%!%$%k%7%9%F%`$N(B + $B%Q%9$rJs9p$7$^$9!#(B

    + +

    $BHs>o$K9-HO0O$N%a%C%;!<%8$,%(%i!<%m%0$K8=$l$^$9!#$?$$$F$$$N$b$N$O(B + $B>e$NNc$N$h$&$J46$8$G$9!#%(%i!<%m%0$K$O(B CGI $B%9%/%j%W%H$N%G%P%C%0(B + $B=PNO$b=q$+$l$^$9!#(BCGI $B%9%/%j%W%H$,(B stderr $B$K=q$$$?(B + $B$9$Y$F$N>pJs$OD>@\%(%i!<%m%0$K%3%T!<$5$l$^$9!#(B

    + +

    $B>pJs$rDI2C$7$?$j:o=|$7$?$j$7$F%(%i!<%m%0$r%+%9%?%^%$%:$9$k$3$H$O(B + $B$G$-$^$;$s!#$7$+$7!"%j%/%(%9%H$KBP$9$k%(%i!<%m%0$N%(%s%H%j$O!"(B + $BBP1~$9$k%(%s%H%j$,(B$B%"%/%;%9%m%0(B$B$K$"$j$^$9!#(B + $BNc$($P!">e$NNc$N%(%s%H%j$O%"%/%;%9%m%0$N%9%F!<%?%9%3!<%I(B 403 $B$N(B + $B%(%s%H%j$KBP1~$7$^$9!#%"%/%;%9%m%0$O%+%9%?%^%$%:2DG=$G$9$N$G!"(B + $B$=$A$i$r;H$&$3$H$K$h$j%(%i!<$N>u67$K4X$9$k>pJs$r$h$jB?$/(B + $B + +

    $B%F%9%H$N:GCf$O!"LdBj$,H/@8$7$F$$$k$+$I$&$+$r8+$k$?$a$K!"(B + $B>o$K%(%i!<%m%0$r4F;k$9$k$N$,Lr$KN)$D>l9g$,$h$/$"$j$^$9!#(B + Unix $B%7%9%F%`$G$O!" + + + tail -f error_log + +

    + +
    + $B%"%/%;%9%m%0(B + + + + mod_log_config + mod_setenvif + + + CustomLog + LogFormat + SetEnvIf + + + +

    $B%5!<%P%"%/%;%9%m%0$O%5!<%P$,=hM}$r$7$?$9$Y$F$N%j%/%(%9%H$r(B + $B5-O?$7$^$9!#%"%/%;%9%m%0$N>l=j$HFbMF$O(B CustomLog + $B%G%#%l%/%F%#%V$K$h$j7h$^$j$^$9!#%m%0$NFbMF$NA*Br$r4J7i$K$9$k$?$a$K(B + LogFormat + $B%G%#%l%/%F%#%V$r;HMQ$9$k$3$H$,$G$-$^$9!#$3$N%;%/%7%g%s$O%"%/%;%9%m%0$K(B + $B>pJs$r5-O?$9$k$?$a$N%5!<%P$N@_DjJ}K!$r@bL@$7$^$9!#(B

    + +

    $B$b$A$m$s!"%"%/%;%9%m%0$K>pJs$rC_@Q$9$k$3$H$O%m%04IM}$N(B + $B;O$^$j$K2a$.$^$;$s!#pJs$r(B + $B2r@O$9$k$3$H$G$9!#0lHLE*$J%m%02r@O$O$3$NJ8=q$NHO0O30$G!"(B + $B%&%'%V%5!<%P<+?H$N;E;v$H$$$&$o$1$G$b$"$j$^$;$s!#$3$NOC$d!"(B + $B%m%02r@O$r9T$J$&%"%W%j%1!<%7%g%s$N>pJs$rF@$k$K$O!"(B + Open Directory $B$d(B + Yahoo $B$rD4$Y$F$/$@$5$$!#(B

    + +

    $B$$$m$s$J%P!<%8%g%s$N(B Apache httpd $B$,(B mod_log_config, + mod_log_agent, TransferLog $B%G%#%l%/%F%#%V$H$$$C$?!"(B + $BB>$N%b%8%e!<%k$d%G%#%l%/%F%#%V$r;H$C$F%"%/%;%9$N%m%.%s%0$r(B + $B@)8f$7$F$-$^$7$?!#:#$G$O!"(BCustomLog $B$,$9$Y$F$N8E$$(B + $B%G%#%l%/%F%#%V$N5!G=$r4^$`$h$&$K$J$C$F$$$^$9!#(B

    + +

    $B%"%/%;%9%m%0$N=q<0$OHs>o$K=@Fp$J@_Dj$,2DG=$G$9!#(B + $B=q<0$O(B C $B$N(B printf(1) $B%U%)!<%^%C%HJ8;zNs$KHs>o$K;w$?(B + $B%U%)!<%^%C%HJ8;zNs(B + $B$K$h$j;XDj$5$l$^$9!#$$$/$D$+mod_log_config $B$NJ8=q(B + $B$r8+$F$/$@$5$$!#(B

    + +
    + Common Log Format + +

    $B%"%/%;%9%m%0$N$h$/$"$k@_Dj$K0J2<$N$b$N$,$"$j$^$9!#(B

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +
    + +

    $B$3$l$O!"(B$B%K%C%/%M!<%`(B common $B$rDj5A$7!"(B + $B%m%0$N%U%)!<%^%C%HJ8;zNs$N0l$D$H4XO"IU$1$^$9!#%U%)!<%^%C%HJ8;zNs$O(B + $B%Q!<%;%s%H%G%#%l%/%F%#%V$+$i$J$j!"$=$l$>$l$N%Q!<%;%s%H%G%#%l%/%F%#%V$O(B + $B%5!<%P$K$I$N>pJs$r%m%.%s%0$9$k$+$r;X<($7$^$9!#%U%)!<%^%C%HJ8;zNs$K(B + $BJ8;z$r$=$N$^$^F~$l$k$3$H$b$G$-!"$=$l$i$O%m%0$N=PNO$KD>@\%3%T!<$5$l$^$9!#(B + $B$=$3$K0zMQJ8;z(B (") $B$r=q$/$H$-$O!"(B + $B%U%)!<%^%C%HJ8;zNs$N:G8e$H$7$F2r\n"$B!"%?%VMQ$N(B + "\t" $B$H$$$&FCJL$J@)8fJ8;z$b4^$a$k$3$H$,$G$-$^$9!#(B

    + +

    CustomLog $B%G%#%l%/%F%#%V$O(B + $B4{$KDj5A$5$l$?(B + $B%K%C%/%M!<%`(B $B$r;H$C$F?7$7$$%m%0%U%!%$%k$r@_Dj$7$^$9!#(B + $B%"%/%;%9%m%0$N%U%!%$%kL>$O%9%i%C%7%e$G;O$^$i$J$$8B$j!"(B + ServerRoot $B$+$i$NAjBP%Q%9$H$7$F(B + $B07$o$l$^$9!#(B

    + +

    $B>e$N@_Dj$O(B Common Log Format (CLF) $B$H8F$P$l$k7A<0$G(B + $B%m%0%(%s%H%j$r=q$-$^$9!#$3$NI8=`$N7A<0$O0[$J$k%&%'%V%5!<%P$NB?$/$,(B + $B@8@.$9$k$3$H$,$G$-!"B?$/$N%m%02r@O%W%m%0%i%`$,FI$_$3$`$3$H$,$G$-$^$9!#(B + CLF $B$K$h$j@8@.$5$l$?%m%0%U%!%$%k$N%(%s%H%j$O0J2<$N$h$&$K$J$j$^$9(B:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + + +

    $B$3$N%m%0%(%s%H%j$N$=$l$>$l$NItJ,$N0UL#$O0J2<$G@bL@$7$^$9!#(B

    + +
    +
    127.0.0.1 (%h)
    + +
    $B$3$l$O%5!<%P$X%j%/%(%9%H$r$7$?%/%i%$%"%s%H(B ($B%j%b!<%H%[%9%H(B) + $B$N(B IP $B%"%I%l%9$G$9!#(BHostnameLookups $B$,(B + On $B$N>l9g$O!"%5!<%P$O%[%9%HL>$rD4$Y$F!"(B + IP $B%"%I%l%9$,=q$+$l$F$$$k$H$3$m$K5-O?$7$^$9!#$7$+$7!"$3$N@_Dj$O(B + $B%5!<%P$r$+$J$jCY$/$9$k$N$G!"$"$^$j$*4+$a$G$-$^$;$s!#(B + $B$=$&$G$O$J$/!"(Blogresolve $B$N(B + $B$h$&$J%m%0$N8e=hM}$r9T$J$&%W%m%0%i%`$G%[%9%HL>$rD4$Y$k$N$,NI$$$G$7$g$&!#(B + $B$3$3$KJs9p$5$l$k(B IP $B%"%I%l%9$OI,$:$7$b%f!<%6$,;H$C$F$$$k%^%7%s$N(B + $B$b$N$G$"$k$H$O8B$j$^$;$s!#%f!<%6$H%5!<%P$N4V$K%W%m%-%7%5!<%P$,(B + $B$"$l$P!"$3$N%"%I%l%9$O85$N%^%7%s$N$b$N$G$O$J$/!"%W%m%-%7$N(B + $B%"%I%l%9$K$J$j$^$9!#(B
    + +
    - (%l)
    + +
    $B=PNOCf$N!V%O%$%U%s!W$OMW5a$5$l$?>pJs$,l9g!"pJs$O%/%i%$%"%s%H$N%^%7%s$N(B + identd $B$K$h$j7h$^$k(B RFC 1413 $B$N%/%i%$%"%s%H$N(B + $B%"%$%G%s%F%#%F%#$G$9!#$3$N>pJs$O$"$^$j?.MQ$9$k$3$H$,$G$-$:!"(B + $B$7$C$+$j$H4IM}$5$l$?FbIt%M%C%H%o!<%/$r=|$$$F$O;H$&$Y$-$G$O$"$j$^$;$s!#(B + Apache $B$O(B IdentityCheck $B$,(B + On $B$K$J$C$F$$$J$$8B$j!"$3$N>pJs$rF@$h$&$H$9$i$7$^$;$s!#(B
    + +
    frank (%u)
    + +
    $B$3$l$O(B HTTP $BG'>Z$K$h$k!"%I%-%e%a%s%H$r%j%/%(%9%H$7$??M$N(B + $B%f!<%6(B ID $B$G$9!#(BCGI $B%9%/%j%W%H$K$ODL>oF1$8CM$,(B REMOTE_USER + $B4D6-JQ?t$H$7$FM?$($i$l$^$9!#%j%/%(%9%H$N%9%F!<%?%9%3!<%I(B + ($B0J2<$r;2>H(B) $B$,(B 401 $B$G$"$C$?>l9g$O!"%f!<%6$OG'>Z$K<:GT$7$F$$$k$N$G!"(B + $B$3$NCM$O?.MQ$G$-$^$;$s!#%I%-%e%a%s%H$,%Q%9%o!<%I$GJ]8n$5$l$F$$$J$$(B + $B>l9g$O!"$3$N%(%s%H%j$OA0$N$b$N$HF1$8$h$&$K(B "-" $B$K(B + $B$J$j$^$9!#(B
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + $B%5!<%P$,%j%/%(%9%H$r + [day/month/year:hour:minute:second zone]
    + day = 2*digit
    + month = 3*letter
    + year = 4*digit
    + hour = 2*digit
    + minute = 2*digit
    + second = 2*digit
    + zone = (`+' | `-') 4*digit
    +

    + $B%m%0$N%U%)!<%^%C%HJ8;zNs$K(B %{format}t $B$r(B + $B;XDj$9$k$3$H$G!"JL$N7A<0$G;~9o$rI=<($5$;$k$3$H$b$G$-$^$9!#(B + $B$3$N$H$-!"(Bformat $B$O(B C $B$NI8=`%i%$%V%i%j$N(B + strftime(3) $B$N7A<0$K$J$j$^$9!#(B +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    $B%/%i%$%"%s%H$+$i$N%j%/%(%9%H$,Fs=E0zMQId$NCf$K<($5$l$F$$$^$9!#(B + $B%j%/%(%9%H$K$OB?$/$NM-MQ$J>pJs$,$"$j$^$9!#$^$:!"$3$N>l9g%/%i%$%"%s%H$,(B + $B;H$C$?%a%=%C%I$O(B GET $B$G$9!#/apache_pb.gif $B$rMW5a$7$^$7$?!#$=$7$F!"(B + $B%/%i%$%"%s%H$O%W%m%H%3%k(B HTTP/1.0 $B$r;HMQ$7$^$7$?!#(B + $B%j%/%(%9%H$N3FItJ,$rFHN)$K%m%0<}=8$9$k$3$H$b$G$-$^$9!#Nc$($P!"(B + $B%U%)!<%^%C%HJ8;zNs(B "%m %U%q %H" $B$O(B + $B%a%=%C%I!"%Q%9!"%/%(%jJ8;zNs!"%W%m%H%3%k$r%m%0<}=8$7!"(B + $B7k6I(B "%r" $B$H$^$C$?$/F1$8=PNO$K$J$j$^$9!#(B
    + +
    200 (%>s)
    + +
    $B%5!<%P$,%/%i%$%"%s%H$KAw$jJV$9%9%F!<%?%9%3!<%I$G$9!#(B + $B$3$N>pJs$O!"%j%/%(%9%H$,@.8y1~Ez(B (2 $B$G;O$^$k%3!<%I(B) $B$G$"$C$?$+!"(B + $B%j%@%$%l%/%7%g%s(B (3 $B$G;O$^$k%3!<%I(B) $B$G$"$C$?$+!"%/%i%$%"%s%H$K$h$k(B + $B%(%i!<(B (4 $B$G;O$^$k%3!<%I(B) $B$G$"$C$?$+!"%5!<%P$N%(%i!<(B (5 $B$G;O$^$k%3!<%I(B) + $B$G$"$C$?$+!"$r8=$9$N$G!"Hs>o$KBg@Z$G$9!#%9%F!<%?%9%3!<%I$N(B + $B40A4$J%j%9%H$O(B HTTP + $B5,3J(B (RFC2616 $BBh(B 10 $B@a(B) $B$K$"$j$^$9!#(B
    + +
    2326 (%b)
    + +
    $B$3$N:G8e$N%(%s%H%j$O%/%i%$%"%s%H$KAw?.$5$l$?%*%V%8%'%/%H$N!"(B + $B1~Ez%X%C%@$r=|$$$?%5%$%:$r8=$7$^$9!#%3%s%F%s%H$,%/%i%$%"%s%H$KAw$i$l$J$+$C$?(B + $B>l9g$O!"$3$NCM$O(B "-" $B$K$J$j$^$9!#%3%s%F%s%H$,L5$$>l9g$K(B + "0" $B$r%m%0<}=8$9$k$K$O!"(B%b $B$G$O$J$/(B + %B $B$r;H$C$F$/$@$5$$!#(B
    + +
    +
    + +
    + Combined Log Format + +

    $B$b$&0l$D$N$h$/;H$o$l$k=q<0$O(B Combined Log Format $B$H8F$P$l$F$$$^$9!#(B + $B0J2<$N$h$&$K$7$F;H$&$3$H$,$G$-$^$9!#(B

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +
    + +

    $B$3$N=q<0$N:G=i$NJ}$O(B Common Log Format $B$H$^$C$?$/F1$8$G!":G8e$K(B + $BFs$DDI2C$N%(%s%H%j$,$"$j$^$9!#DI2C$N%(%s%H%j$O%Q!<%;%s%H%G%#%l%/%F%#%V(B + %{header}i $B$r;H$C$F$$$^$9!#$3$3$G(B + header $B$O(B HTTP $B$N%j%/%(%9%H%X%C%@$N$I$l$+$G$9!#$3$N=q<0$K$h$k(B + $B%"%/%;%9%m%0$O0J2<$N$h$&$J46$8$K$J$j$^$9(B:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" + + +

    $BDI2C$N%(%s%H%j$O(B:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    "Referer" ($B0U?^E*$JDV$j4V0c$$(B) HTTP $B%j%/%(%9%H%X%C%@$G$9!#(B + $B$3$l$O%/%i%$%"%s%H$,Js9p$7$F$/$k;2>H85$N%5%$%H$rI=$7$^$9!#(B + ($B$3$N>l9g$O!"(B/apache_pb.gif $B$K%j%s%/$7$F$$$k$+!"(B + $B$=$l$r4^$s$G$$$k%Z!<%8$G$9(B)$B!#(B
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    User-Agent HTTP $B%j%/%(%9%H%X%C%@$G$9!#$3$l$O%/%i%$%"%s%H$N%V%i%&%6$,(B + $B<+J,<+?H$N$3$H$rJs9p$7$F$/$k>pJs$G$9!#(B
    +
    +
    + +
    + $BJ#?t$N%"%/%;%9%m%0(B + +

    $BJ#?t$N%"%/%;%9%m%0$OC1$K@_Dj%U%!%$%k$KJ#?t$N(B CustomLog + $B%G%#%l%/%F%#%V$r=q$/$3$H$G:n@.$5$l$^$9!#Nc$($P!"0J2<$N%G%#%l%/%F%#%V$O(B + $B;0$D$N%"%/%;%9%m%0$r:n$j$^$9!#:G=i$N$b$N$O4pK\E*$J(B CLF $B$N>pJs$G!"(B + $BFs$DL\$H;0$DL\$O(B referer $B$H%V%i%&%6$N>pJs$G$9!#:G8eFs$D$N(B + CustomLog $B$O(B + ReferLog $B%G%#%l%/%F%#%V$H(B + AgentLog $B%G%#%l%/%F%#%V$N8z2L$r$^$M$kJ}K!$r<($7$F$$$^$9!#(B

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +
    + +

    $B$3$NNc$O(B LogFormat $B$G(B + $B%K%C%/%M!<%`$rDj5A$9$kI,MW$,$J$$!"(B + $B$H$$$&$3$H$b<($7$F$$$^$9!#%K%C%/%M!<%`$NBe$o$j$K!"(B + CustomLog $B%G%#%l%/%F%#%V$K(B + $BD>@\%m%0$N=q<0$r;XDj$9$k$3$H$,$G$-$^$9!#(B

    +
    + +
    + $B>r7oIU$-%m%0(B + +

    $B%/%i%$%"%s%H$N%j%/%(%9%H$NFCD'$K4p$E$$$F%"%/%;%9%m%0$K%(%s%H%j$N(B + $B0lIt$r%m%.%s%0$7$J$$J}$,JXMx$J$3$H$,$"$j$^$9!#$3$l$O(B $B4D6-JQ?t(B $B$NJd=u$K$h$j4JC1$Kr7o$K9g$&$H$$$&$3$H$r8=$9$?$a$K4D6-JQ?t$,(B + $B@_Dj$5$l$kI,MW$,$"$j$^$9!#$3$l$ODL>o$O(B SetEnvIf $B$K$h$j(B + $B9T$J$o$l$^$9!#$=$7$F!"(BCustomLog $B%G%#%l%/%F%#%V$N(B + env= $B@a$r;H$C$F4D6-JQ?t$,@_Dj$5$l$F$$$k%j%/%(%9%H$r(B + $B4^$a$?$jGS=|$7$?$j$9$k$3$H$,$G$-$^$9!#$$$/$D$+Nc$r5s$2$^$9(B:

    + + + # Mark requests from the loop-back interface
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # Mark requests for the robots.txt file
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # Log what remains
    + CustomLog logs/access_log common env=!dontlog +
    + +

    $BB>$NNc$H$7$F!"1Q8l$rOC$9?M$+$i$N%j%/%(%9%H$H$=$l0J30$N?M$+$i$N%j%/%(%9%H$r(B + $BJ,$1$?$$!"$H$$$&>l9g$r9M$($F$_$F$/$@$5$$!#(B

    + + + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +
    + +

    $B$3$3$^$G$G$O>r7oIU$-%m%.%s%0$,Hs>o$K6/NO$G=@Fp$G$"$k$3$H$r<($7$F$-$^$7$?$,!"(B + $B$=$l$,%m%0$NFbMF$r@)8f$9$kM#0l$NJ}K!$H$$$&$o$1$G$O$"$j$^$;$s!#%m%0%U%!%$%k$O(B + $B%5!<%P$N3hF0$N40A4$J5-O?$G$"$kJ}$,$h$jLr$KN)$A$^$9!#C1=c$K%m%0%U%!%$%k$r(B + $B8e=hM}$7$F!"9MN8$7$?$/$J$$%m%0$r:o=|$9$kJ}$,4JC1$G$"$k$3$H$,$h$/$"$j$^$9!#(B

    +
    +
    + +
    + $B%m%0$N8rBX(B + +

    $BIaDL$NIi2Y$N%5!<%P$G$5$(!"%m%0%U%!%$%k$KJ]B8$5$l$k>pJs$NNL$O(B + $BKDBg$K$J$j$^$9!#%"%/%;%9%m%0$N%U%!%$%k$OIaDL(B 10,000 $B%j%/%(%9%HKh$K(B + 1 MB $B0J>eA}$($^$9!#$G$9$+$i!"4{B8$N%m%0$r0\F0$7$?$j!":o=|$7$?$j$7$F!"(B + $BDj4|E*$K%m%0$r8rBX$5$;$k$3$H$,I,MW$K$J$j$^$9!#$3$l$O%5!<%P$N$B:F5/F0(B$B$9$k(B + $BI,MW$,$"$j$^$9!#(B

    + +

    $BM%2m$J(B $B:F5/F0$r9T$J$&$3$H$G!"%5!<%P$O4{B8$N%3%M%/%7%g%s$d(B + $B=hM}BT$A$N%3%M%/%7%g%s$r<:$&$3$H$J$/?7$7$$%m%0%U%!%$%k$r(B open $B$5$;$k(B + $B$3$H$,$G$-$^$9!#$7$+$7!"$3$l$r + + + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +
    + +

    $B%m%0$N8rBX$r$9$k$b$&0l$D$NJ}K!$O(B$B%Q%$%W7PM3$N%m%0(B$B$r;H$&$b$N$G!" +

    + +
    + $B%Q%$%W7PM3$N%m%0(B + +

    Apache httpd $B$O%(%i!<%m%0$H%"%/%;%9%m%0$r%U%!%$%k$KD>@\=q$/Be$o$j$K!"(B + $B%Q%$%W$rDL$7$FJL$N%W%m%0%i%`$K=q$-=P$9$3$H$,$G$-$^$9!#(B + $B$3$N5!G=$K$h$j!"o$K9b$^$C$F$$$^$9!#%Q%$%W$K%m%0$r=q$/$?$a$K$O!"(B + $BC1$K%U%!%$%kL>$r%Q%$%WJ8;z(B "|" $B$KCV$-49$(!"$=$NB3$-$K(B + $BI8=`F~NO$+$i%m%0$N%(%s%H%j$rA0$r=q$/$@$1$G$9!#(B + Apache $B$O%Q%$%W7PM3$N%m%0MQ$N%W%m%;%9$r%5!<%P$N5/F0;~$K + +

    $B%Q%$%W7PM3$N%m%0MQ$N%W%m%;%9$O(B Apache httpd $B$N?F%W%m%;%9$+$i5/F0$5$l!"(B + $B$=$N%W%m%;%9$N%f!<%6(B ID $B$r7Q>5$7$^$9!#$3$l$O!"$3$l$O!"%Q%$%W7PM3$N%m%0MQ$N(B + $B%W%m%0%i%`$OIaDL(B root $B$H$7$Fo$K=EMW$G$9!#(B

    + +

    $B%Q%$%W7PM3$N%m%0$N=EMW$JMxMQK!$O!"%5!<%P$N:F5/F0$J$7$G%m%0$N8rBX$r(B + $B$9$k$3$H$G$9!#(BApache HTTP $B%5!<%P$K$O$3$N$?$a$N(B rotatelogs $B$H8F$P$l$k4JC1$J(B + $B%W%m%0%i%`$,IUB0$7$F$$$^$9!#$?$H$($P!"(B24 $B;~4VKh$K%m%0$r8rBX$5$;$k$K$O!"(B + $B0J2<$N$b$N$r;H$&$3$H$,$G$-$^$9(B:

    + + + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common + + +

    $B%Q%$%W$N@h$G8F$P$l$k%3%^%s%IA4BN$,0zMQId$G0O$^$l$F$$$k$3$H$KCmL\$7$F(B + $B$/$@$5$$!#$3$NNc$O%"%/%;%9%m%0$r;H$C$F$$$^$9$,!"%(%i!<%m%0$K$bF1$85;=Q$r(B + $B;H$&$3$H$,$G$-$^$9!#(B

    + +

    $B;w$F$$$k$1$l$I!"$h$j$:$C$H=@Fp$J(B + cronolog $B$H$$$&%m%08rBXMQ$N(B + $B%W%m%0%i%`$,30It$N%5%$%H$K$"$j$^$9!#(B

    + +

    $B>r7oIU$-%m%.%s%0$HF1MM!"%Q%$%W7PM3$N%m%0$OHs>o$K6/NO$J(B + $BF;6q$G$9$,!"%*%U%i%$%s$N8e=hM}$N$h$&$J!"$h$j4JC1$J2r7hJ}K!$,$"$k$H$-$O(B + $B;H$o$J$$J}$,NI$$$G$7$g$&!#(B

    +
    + +
    + $B%P!<%A%c%k%[%9%H(B + +

    $BB?$/$N(B $B%P!<%A%c%k%[%9%H(B $B$N$"$k%5!<%P$rVirtualHost $B%;%/%7%g%s$N30$KCV$/$3$H$G!"(B + $B$9$Y$F$N%m%0$rF1$8%"%/%;%9%m%0$H%(%i!<%m%0$K%m%0<}=8$9$k$3$H$,$G$-$^$9!#(B + $B$3$N + +

    >CustomLog $B$d(B + ErrorLog $B%G%#%l%/%F%#%V$,(B + VirtualHost $B$NCf$K(B + $BCV$+$l$?>l9g$O!"$=$N%P!<%A%c%k(B + $B%[%9%H$X$N$9$Y$F$N%j%/%(%9%H$d%(%i!<$,$=$3$G;XDj$5$l$?%U%!%$%k$K$N$_(B + $B%m%0<}=8$5$l$^$9!#%m%.%s%0%G%#%l%/%F%#%V$N$J$$%P!<%A%c%k%[%9%H$O(B + $B0MA3$H$7$F%j%/%(%9%H$,/$J$$(B + $B%P!<%A%c%k%[%9%H$KBP$7$F$OHs>o$KM-MQ$G$9$,!"%[%9%H$N?t$,Hs>o$KB?$/$J$k$H(B + $B4IM}$,BgJQ$K$J$j$^$9!#$5$i$K!"(B$B%U%!%$%k5-=R;R$N8B3&(B$B$NLdBj$r5/$3$9$3$H$,(B + $B$"$j$^$9!#(B

    + +

    $B%"%/%;%9%m%0$K$O!"Hs>o$KNI$$BE6(0F$,$"$j$^$9!#%P!<%A%c%k%[%9%H$N(B + $B>pJs$r%m%0$N%U%)!<%^%C%HJ8;zNs$K2C$($k$3$H$G!"$9$Y$F$N%[%9%H$X$N(B + $B%j%/%(%9%H$rF1$8%m%0$K%m%0<}=8$7$F!"8e$G%m%0$r8D!9$N%U%!%$%k$KJ,3d$9$k$3$H$,(B + $B$G$-$^$9!#$?$H$($P!"0J2<$N%G%#%l%/%F%#%V$r8+$F$/$@$5$$!#(B

    + + + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +
    + +

    %v $B$,%j%/%(%9%H$r07$C$F$$$k%P!<%A%c%k%[%9%H$NL>A0$r(B + $B%m%0<}=8$9$k$?$a$K;H$o$l$F$$$^$9!#$=$7$F!"(Bsplit-logfile $B$N$h$&$J%W%m%0%i%`$r(B + $B;H$C$F%"%/%;%9%m%0$r8e=hM}$9$k$3$H$G!"(B + $B%P!<%A%c%k%[%9%HKh$N%U%!%$%k$K%m%0$rJ,3d$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B;DG0$J$,$i!"%(%i!<%m%0$K$OF1MM$N +

    + +
    + $BB>$N%m%0%U%!%$%k(B + + + + mod_cgi + mod_rewrite + + + PidFile + RewriteLog + RewriteLogLevel + ScriptLog + ScriptLogBuffer + ScriptLogLength + + + +
    + PID $B%U%!%$%k(B + +

    $B5/F0;~$K!"(BApache $B$O?F(B httpd $B%W%m%;%9$N%W%m%;%9(B ID $B$r(B + logs/httpd.pid $B$KJ]B8$7$^$9!#$3$N(B + $B%U%!%$%kL>$O(B PidFile $B%G%#%l%/%F%#%V$r;H$C$F(B + $BJQ99$9$k$3$H$,$G$-$^$9!#%W%m%;%9(B ID $B$O4IM}\$7$$>pJs$O(B $B=*N;$H(B + $B:F5/F0(B $B$N%Z!<%8$r8+$F$/$@$5$$!#(B

    +
    + +
    + $B%9%/%j%W%H%m%0(B + +

    $B%G%P%C%0$NJd=u$N$?$a$K!"(BScriptLog $B%G%#%l%/%F%#%V$O(B + CGI $B%9%/%j%W%H$NF~NO$H=PNO$r5-O?$9$k$h$&$K$G$-$^$9!#(B + $B$3$l$O%F%9%HMQ$K$N$_;HMQ$7$F!"DL>o$N%5!<%P$G$O;HMQ$7$J$$$G$/$@$5$$!#(B + $B>\$7$$>pJs$O(B mod_cgi $B$NJ8=q(B $B$K$"$j$^$9!#(B

    +
    + +
    + $B%j%i%$%H%m%0(B + +

    mod_rewrite $B$N6/NO$G(B + $BJ#;($J5!G=$r(B + $B;H$C$F$$$k$H$-$O!"$[$\$$$D$b%G%P%C%0$r4JC1$K$9$k$?$a$K(B + RewriteLog $B$N;HMQ$,(B + $BI,MW$G$7$g$&!#$3$N%m%0%U%!%$%k$K$O%j%i%$%H%(%s%8%s$,%j%/%(%9%H$r(B + $B=q$-49$($kJ}K!$N>\:Y$J2r@O$,=PNO$5$l$^$9!#>\$7$5$NEY9g$O(B RewriteLogLevel + $B$G@)8f$G$-$^$9!#(B

    +
    +
    +
    diff --git a/trunk/docs/manual/logs.xml.ko b/trunk/docs/manual/logs.xml.ko new file mode 100644 index 0000000000..77eef925cd --- /dev/null +++ b/trunk/docs/manual/logs.xml.ko @@ -0,0 +1,557 @@ + + + + + + + + + + ·Î±×ÆÄÀÏ + + +

    È¿À²ÀûÀ¸·Î À¥¼­¹ö¸¦ °ü¸®ÇÏ·Á¸é ¹ß»ýÇÏ´Â ¹®Á¦¿Í ÇÔ²² ¼­¹öÀÇ + È°µ¿°ú ¼º´É¿¡ ´ëÇØ ¾Ë¾Æ¾ß ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¸Å¿ì Á¾ÇÕÀûÀÌ°í + À¯¿¬ÇÑ ·Î±× ±â´ÉÀ» Á¦°øÇÑ´Ù. ÀÌ ¹®¼­´Â ·Î±× ±â´ÉÀ» ¼³Á¤ÇÏ´Â + ¹æ¹ý°ú ·Î±×¿¡ µé¾î°¥ ³»¿ëÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    + º¸¾È °æ°í + +

    ´©±º°¡¿¡°Ô ¾ÆÆÄÄ¡ÀÇ ·Î±×ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ + ÀÖ´Ù¸é (º¸Åë root) ¼­¹ö¸¦ ½ÇÇàÇÏ´Â uid¸¦ °ÅÀÇ È®½ÇÈ÷ ¾òÀ» + ¼ö ÀÖ´Ù. À̸¦ °í·ÁÇÏÁö¾Ê°í ·Î±×°¡ ÀúÀåµÈ µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀ» + ÁÖÁö ¸¶¶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº º¸¾È ÆÁ ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¶Ç, Ŭ¶óÀ̾ðÆ®°¡ Á¦°øÇÑ Á¤º¸´Â ·Î±×ÆÄÀÏ¿¡ °ÅÀÇ ±×´ë·Î + ±â·ÏµÈ´Ù. ±×·¡¼­ ¾ÇÀÇ°¡ Àִ Ŭ¶óÀ̾ðÆ®°¡ ·Î±×ÆÄÀÏ¿¡ Á¦¾î¹®ÀÚ¸¦ + ³ÖÀ» ¼ö ÀÖÀ¸¹Ç·Î, ·Î±×¸¦ ´Ù·ê¶§´Â ÁÖÀÇÇØ¾ß ÇÑ´Ù.

    +
    + +
    + ¿À·ù ·Î±× (Error Log) + + + + ErrorLog + LogLevel + + + +

    ErrorLog Áö½Ã¾î´Â + °¡Àå Áß¿äÇÑ ·Î±×ÆÄÀÏÀÎ ¼­¹ö ¿À·ù ·Î±×ÀÇ À̸§°ú À§Ä¡¸¦ ÁöÁ¤ÇÑ´Ù. + ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ ÆÄÀÏ¿¡ Áø´ÜÁ¤º¸¿Í ¿äûÀ» ó¸®ÇÏ´Â µµÁß + ¹ß»ýÇÑ ¿À·ù¸¦ ±â·ÏÇÑ´Ù. ¼­¹ö°¡ ½ÃÀÛÇϰųª µ¿ÀÛÇϴµ¥ ¹®Á¦°¡ + ÀÖ´Ù¸é ¹«¾ùÀÌ À߸øµÇ¾ú°í ¶§¶§·Î ¾î¶»°Ô °íÄ¡´ÂÁö¸¦ ¾Ë·ÁÁÖ´Â + ÀÌ°÷À» °¡Àå ¸ÕÀú »ìÆìºÁ¾ß ÇÑ´Ù.

    + +

    ¿À·ù ·Î±×´Â º¸Åë (ÀüÇüÀûÀ¸·Î À¯´Ð½º ½Ã½ºÅÛ¿¡¼­´Â + error_log, À©µµ¿ìÁî¿Í OS/2¿¡¼­´Â + error.log) ÆÄÀÏ¿¡ ±â·ÏµÈ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ + ¼­¹ö´Â ¿À·ù¸¦ syslog³ª ÆÄÀÌÇÁ¸¦ + »ç¿ëÇÏ¿© ´Ù¸¥ ÇÁ·Î±×·¥À¸·Î º¸³¾ ¼öµµ ÀÖ´Ù.

    + +

    ¿À·ù ·Î±×ÀÇ Çü½ÄÀº »ó´ëÀûÀ¸·Î ÀÚÀ¯·Ó°í ÀÚ¼¼ÇÏ´Ù. ±×·¯³ª + ´ëºÎºÐÀÇ ¿À·ù ·Î±× Ç׸ñ¿¡ °øÅëÀûÀ¸·Î ³ª¿À´Â Á¤º¸°¡ ÀÖ´Ù. + ¿¹¸¦ µé¾î, Ç׸ñÀº º¸Åë ´ÙÀ½°ú °°´Ù.

    + + + [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] + client denied by server configuration: + /export/home/live/ap/htdocs/test + + +

    ·Î±× Ç׸ñ¿¡¼­ ù¹ø° Ç׸ñÀº ³¯Â¥¿Í ½Ã°£ÀÌ´Ù. µÎ¹ø° + Ç׸ñÀº º¸°íÇÏ´Â ¿À·ùÀÇ ½É°¢¼ºÀ» ³ªÅ¸³½´Ù. LogLevel Áö½Ã¾î·Î ¿À·ù ·Î±×¿¡ + ±â·ÏµÇ´Â ¿À·ùÀÇ ½É°¢¼ºÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. ¼¼¹ø° Ç׸ñÀº + ¿À·ù¸¦ ¹ß»ýÇÑ Å¬¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼ÒÀÌ´Ù. ÀÌ ´ÙÀ½ºÎÅÍ ¿À·ù¹®ÀÌ + ³ª¿À¸ç, ÀÌ °æ¿ì ¼­¹ö°¡ Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» °ÅºÎÇϵµ·Ï + ¼³Á¤µÇ¾ú´Ù°í ³ª¿ÍÀÖ´Ù. ¿äûÇÑ ¹®¼­ÀÇ (À¥ °æ·Î°¡ ¾Æ´Ñ) + ÆÄÀϽýºÅÛ °æ·Îµµ º¸ÀδÙ.

    + +

    ¿À·ù ·Î±×¿¡´Â ¸Å¿ì ´Ù¾çÇÑ Á¾·ùÀÇ ¹®±¸°¡ ³ª¿Ã ¼ö ÀÖ´Ù. + ´ëºÎºÐÀº À§¿Í ºñ½ÁÇÏ´Ù. CGI ½ºÅ©¸³Æ®ÀÇ µð¹ö±ë Ãâ·Âµµ ¿À·ù + ·Î±×¿¡ ±â·ÏµÈ´Ù. CGI ½ºÅ©¸³Æ®°¡ stderr¿¡ ¾´ + Á¤º¸´Â ±×´ë·Î ¿À·ù ·Î±×·Î º¹»çµÈ´Ù.

    + +

    ¿À·ù ·Î±×¿¡ Á¤º¸¸¦ Ãß°¡ÇÏ°¡³ª »ý·«ÇÒ ¼ö ¾ø´Ù. ±×·¯³ª + ¿äû¿¡ ´ëÇÑ ¿À·ù ·Î±×ÀÇ °æ¿ì Á¢±Ù + ·Î±×¿¡µµ ´ëÀÀÇÏ´Â Ç׸ñÀÌ »ý±ä´Ù. ¿¹¸¦ µé¾î, À§ÀÇ °æ¿ì + »óÅÂÄڵ尡 403ÀÎ Á¢±Ù ·Î±× Ç׸ñÀÌ »ý±ä´Ù. Á¢±Ù ·Î±×´Â + »ç¿ëÀÚÁ¤ÀÇÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÀÌ ÆÄÀÏÀ» Âü°íÇÏ¿© ¿À·ù »óȲ¿¡ + ´ëÇÑ Ãß°¡Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

    + +

    °Ë»çÇÒ¶§ ¾î¶² ¹®Á¦°¡ »ý±â´ÂÁö ¿À·ù ·Î±×¸¦ °è¼Ó »ìÆ캸´Â + °ÍÀÌ ÁÁ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ´ÙÀ½°ú °°ÀÌ ÇÑ´Ù:

    + + + tail -f error_log + +
    + +
    + Á¢±Ù ·Î±× (Access Log) + + + + mod_log_config + mod_setenvif + + + CustomLog + LogFormat + SetEnvIf + + + +

    ¼­¹ö Á¢±Ù ·Î±×´Â ¼­¹ö°¡ ó¸®ÇÏ´Â ¸ðµç ¿äûÀ» ±â·ÏÇÑ´Ù. + CustomLog + Áö½Ã¾î´Â Á¢±Ù ·Î±×ÀÇ À§Ä¡¿Í ³»¿ëÀ» ÁöÁ¤ÇÑ´Ù. LogFormat Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ·Î±×¿¡ Æ÷ÇÔÇÒ ³»¿ëÀ» ½±°Ô ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. ÀÌ ÀýÀº + ¼­¹ö°¡ Á¢±Ù ·Î±×¿¡ ¾µ ³»¿ëÀ» ¼³Á¤ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹°·Ð Á¢±Ù ·Î±×¿¡ Á¤º¸¸¦ ±â·ÏÇÏ´Â °ÍÀº ·Î±× °ü¸®ÀÇ ½ÃÀÛÀÏ + »ÓÀÌ´Ù. ´ÙÀ½ ´Ü°è´Â ÀÌ Á¤º¸¸¦ ºÐ¼®ÇÏ¿© À¯¿ëÇÑ Åë°è¸¦ ¸¸µå´Â + °ÍÀÌ´Ù. ÀÌ ¹®¼­´Â ÀϹÝÀûÀÎ ·Î±× ºÐ¼®¿¡ ´ëÇؼ­ ´Ù·çÁö ¾ÊÀ¸¸ç, + ·Î±× ºÐ¼®Àº ½ÇÁ¦ À¥¼­¹ö°¡ ÇÒ ÀÏÀÌ ¾Æ´Ï´Ù. ·Î±× ºÐ¼®¿¡ ´ëÇÑ + Á¤º¸¿Í ·Î±×¸¦ ºÐ¼®ÇÏ´Â ¼ÒÇÁÆ®¿þ¾î¿¡ ´ëÇؼ­´Â Open Directory³ª + Yahoo¸¦ + Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌÀüºÎÅÍ mod_log_referer, mod_log_agent, + CustomLog + °°Àº ¸ðµâ°ú Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Á¢±Ù ·Î±×¸¦ ´Ù·ç¾ú´Ù. Áö±ÝÀº + CustomLog + Áö½Ã¾î°¡ ¿À·¡µÈ Áö½Ã¾îµéÀÇ ¸ðµç ±â´ÉÀ» À̾î¹Þ¾Ò´Ù.

    + +

    Á¢±Ù ·Î±×ÀÇ Çü½ÄÀº ¸Å¿ì »ç¿ëÀÚÁ¤ÀÇ °¡´ÉÇÏ´Ù. Çü½ÄÀº CÀÇ + printf(1) Çü½Ä¹®ÀÚ¿­°ú ¸Å¿ì À¯»çÇÑ Çü½Ä¹®ÀÚ¿­À» »ç¿ëÇÏ¿© + ÁöÁ¤ÇÑ´Ù. ´ÙÀ½ Àý¿¡ ¿¹¸¦ µé¾ú´Ù. Çü½Ä¹®ÀÚ¿­¿¡ »ç¿ë°¡´ÉÇÑ + ¸ðµç ³»¿ëÀ» ¾Ë·Á¸é mod_log_config Çü½Ä¹®ÀÚ¿­À» + Âü°íÇ϶ó.

    + +
    + Common ·Î±× Çü½Ä + +

    Á¢±Ù ·Î±×ÀÇ ÀüÇüÀûÀÎ ¼³Á¤Àº ´ÙÀ½°ú °°´Ù.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common +
    + +

    ±×·¯¸é ÁöÁ¤ÇÑ ·Î±× Çü½Ä¹®ÀÚ¿­À» º°¸í + commonÀ¸·Î Á¤ÀÇÇÑ´Ù. Çü½Ä¹®ÀÚ¿­Àº ÆÛ¼¾Æ® + Áö½Ã¾îµé·Î ±¸¼ºµÇ¸ç, °¢°¢Àº ¾î¶² Á¤º¸¸¦ ±â·ÏÇÒÁö ¾Ë¸°´Ù. + Çü½Ä¹®ÀÚ¿­¿¡ ÀÏ¹Ý ¹®ÀÚ¸¦ ÀûÀ¸¸é ±×´ë·Î ·Î±×¿¡ Ãâ·ÂµÈ´Ù. + µû¿ÈÇ¥ ¹®ÀÚ(")¸¦ Ãâ·ÂÇÏ°í ½Í´Ù¸é ¹é½½·¡½¬¸¦ + ¾Õ¿¡ ºÙ¿©¼­ Çü½Ä¹®ÀÚ¿­ÀÇ ³¡ÀÌ ¾Æ´ÔÀ» Ç¥½ÃÇÑ´Ù. Çü½Ä¹®ÀÚ¿­¿¡ + ÁÙ¹Ù²Þ "\n", ÅÇ "\t"¿Í °°Àº + Ư¼ö Á¶Àý¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    CustomLog + Áö½Ã¾î´Â Á¤ÀÇÇÑ º°¸íÀ» »ç¿ëÇÏ´Â »õ·Î¿î ·Î±×ÆÄÀÏÀ» + ¸¸µç´Ù. Á¢±Ù ·Î±×ÀÇ ÆÄÀϸíÀÌ ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾ÊÀ¸¸é + ServerRootÀÇ »ó´ë°æ·ÎÀÌ´Ù.

    + +

    ¾ÕÀÇ ¼³Á¤Àº °øÅë·Î±×Çü½Ä(Common Log Format, CLF)À̶ó´Â + Çü½ÄÀ¸·Î ·Î±× Ç׸ñÀ» ±â·ÏÇÑ´Ù. ¿©·¯ ´Ù¸¥ À¥¼­¹öµéµµ ÀÌ·± + Ç¥ÁØ Çü½ÄÀ¸·Î ·Î±×¸¦ ¸¸µé¸ç, ¿©·¯ ·Î±× ºÐ¼® ÇÁ·Î±×·¥¿¡¼­ + ÀÐÀ» ¼ö ÀÖ´Ù. CLF·Î ¸¸µç ·Î±×ÆÄÀÏ Ç׸ñÀº ´ÙÀ½°ú °°´Ù:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + + +

    ÀÌÁ¦ ·Î±× Ç׸ñÀÇ °¢ ºÎºÐÀ» ¼³¸íÇÑ´Ù.

    + +
    +
    127.0.0.1 (%h)
    + +
    ¼­¹ö¿¡ ¿äûÀ» ÇÑ Å¬¶óÀ̾ðÆ®(¿ø°Ý È£½ºÆ®)ÀÇ IP + ÁÖ¼ÒÀÌ´Ù. HostnameLookups°¡ + OnÀ̶ó¸é È£½ºÆ®¸íÀ» ã¾Æ¼­ IP ÁÖ¼Ò ÀÚ¸®¿¡ + ´ë½Å ¾´´Ù. ±×·¯³ª ÀÌ ¼³Á¤Àº ¼­¹ö¸¦ ¸Å¿ì ´À¸®°Ô ÇÒ ¼ö + ÀÖÀ¸¹Ç·Î ÃßõÇÏÁö ¾Ê´Â´Ù. È£½ºÆ®¸íÀ» ¾Ë·Á¸é ´ë½Å ³ªÁß¿¡ + logresolve¿Í + °°Àº ·Î±×¸¦ ó¸®ÇÏ´Â ÇÁ·Î±×·¥À» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. + ¿©±â¿¡ ³ª¿Â IP ÁÖ¼Ò´Â »ç¿ëÀÚ°¡ »ç¿ëÇÏ´Â ÄÄÇ»ÅÍ ÁÖ¼Ò°¡ + ¾Æ´Ò ¼ö ÀÖ´Ù. ÇÁ·Ï½Ã ¼­¹ö°¡ »ç¿ëÀÚ¿Í ¼­¹ö»çÀÌ¿¡ Á¸ÀçÇÑ´Ù¸é, + ¿ø·¡ ÄÄÇ»ÅÍ ÁÖ¼Ò°¡ ¾Æ´Ï¶ó ÇÁ·Ï½ÃÀÇ ÁÖ¼Ò°¡ ±â·ÏµÉ °ÍÀÌ´Ù.
    + +
    - (%l)
    + +
    Ãâ·Â¿¡¼­ "»©±â±âÈ£"´Â ¿äûÇÑ Á¤º¸°¡ ¾øÀ½À» ³ªÅ¸³½´Ù. + ÀÌ °æ¿ì ¿©±â¿¡ ³ª¿Ã Á¤º¸´Â Ŭ¶óÀ̾ðÆ® ÄÄÇ»ÅÍÀÇ + identd°¡ Á¦°øÇÒ Å¬¶óÀ̾ðÆ®ÀÇ RFC 1413 + ½Å¿øÀÌ´Ù. ÀÌ Á¤º¸´Â ¸Å¿ì ¹ÏÀ» ¼ö ¾ø±â¶§¹®¿¡, ±ä¹ÐÈ÷ + °ü¸®µÇ´Â ³»ºÎ ³×Æ®¿÷ÀÌ ¾Æ´Ï¶ó¸é Àý´ë·Î ÀÌ Á¤º¸¸¦ »ç¿ëÇϸé + ¾ÈµÈ´Ù. IdentityCheck°¡ + OnÀÌ ¾Æ´Ï¶ó¸é ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ Á¤º¸¸¦ + ¾Ë¾Æº¸·Á°í ½ÃµµÇÏÁöµµ ¾Ê´Â´Ù.
    + +
    frank (%u)
    + +
    ÀÌ´Â HTTP ÀÎÁõÀ¸·Î ¾Ë¾Æ³½ ¹®¼­¸¦ ¿äûÇÑ »ç¿ëÀÚÀÇ + useridÀÌ´Ù. º¸Åë ÀÌ °ªÀº CGI ½ºÅ©¸³Æ®¿¡°Ô + REMOTE_USER ȯ°æº¯¼ö·Î ³Ñ°ÜÁø´Ù. ¿äûÀÇ + »óÅÂÄڵ尡 401À̶ó¸é (¾Æ·¡ Âü°í) »ç¿ëÀÚ°¡ ¾ÆÁ÷ ÀÎÁõÀ» + °ÅÄ¡Áö ¾Ê¾ÒÀ¸¹Ç·Î ÀÌ °ªÀ» ¹ÏÀ¸¸é ¾ÈµÈ´Ù. ¹®¼­¸¦ ¾ÏÈ£·Î + º¸È£ÇÏÁö ¾Ê´Â´Ù¸é ÀÌ Ç׸ñÀº ÀÌÀü Ç׸ñ°ú °°ÀÌ + "-"ÀÌ´Ù.
    + +
    [10/Oct/2000:13:55:36 -0700] + (%t)
    + +
    + ¼­¹ö°¡ ¿äû󸮸¦ ¸¶Ä£ ½Ã°£. + Çü½ÄÀº: + +

    + [day/month/year:hour:minute:second zone]
    + day = ¼ýÀÚ 2°³
    + month = ¼ýÀÚ 3°³
    + year = ¼ýÀÚ 4°³
    + hour = ¼ýÀÚ 2°³
    + minute = ¼ýÀÚ 2°³
    + second = ¼ýÀÚ 2°³
    + zone = (`+' | `-') ¼ýÀÚ 4°³
    +

    + ·Î±× Çü½Ä¹®ÀÚ¿­¿¡ %{format}t¸¦ »ç¿ëÇÏ¿© + ´Ù¸¥ Çü½ÄÀ¸·Î ½Ã°£À» Ãâ·ÂÇÒ ¼ö ÀÖ´Ù. formatÀº + C Ç¥ÁØ ¶óÀ̺귯¸®ÀÇ strftime(3)°ú °°´Ù. +
    + +
    "GET /apache_pb.gif HTTP/1.0" + (\"%r\")
    + +
    Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÁÙÀÌ ½Öµû¿ÈÇ¥·Î ¹­¿©ÀÖ´Ù. ¿äûÁÙÀº + ¸Å¿ì À¯¿ëÇÑ Á¤º¸¸¦ ´ã°í ÀÖ´Ù. ù°, Ŭ¶óÀ̾ðÆ®°¡ »ç¿ëÇÑ + ¸Þ½áµå´Â GETÀÌ´Ù. µÑ°, Ŭ¶óÀ̾ðÆ®´Â ÀÚ¿ø + /apache_pb.gif¸¦ ¿äûÇÑ´Ù. ¼¼¹ø°, Ŭ¶óÀ̾ðÆ®´Â + HTTP/1.0 ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÑ´Ù. ¿äûÁÙÀÇ + ¿©·¯ ºÎºÐÀ» µû·Î ·Î±×ÇÒ ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, Çü½Ä¹®ÀÚ¿­ + "%m %U%q %H"Àº "%r"°ú ¶È°°ÀÌ + ¸Þ½áµå, °æ·Î, ÁúÀǹ®ÀÚ¿­, ÇÁ·ÎÅäÄÝÀ» ·Î±×ÇÑ´Ù.
    + +
    200 (%>s)
    + +
    ÀÌ´Â ¼­¹ö°¡ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â »óÅÂÄÚµåÀÌ´Ù. ÀÌ + Á¤º¸´Â (2·Î ½ÃÀÛÇÏ´Â ÄÚµå) ¿äûÀÌ ¼º°øÇÏ¿´´ÂÁö, (4·Î + ½ÃÀÛÇÏ´Â ÄÚµå) Ŭ¶óÀ̾ðÆ®¿¡ ¿À·ù°¡ ÀÖ´ÂÁö, (5·Î ½ÃÀÛÇÏ´Â + ÄÚµå) ¼­¹ö¿¡ ¿À·ù°¡ ÀÖ´ÂÁö ¾Ë·ÁÁֹǷΠ¸Å¿ì Áß¿äÇÏ´Ù. + »óÅÂÄÚµåÀÇ Àüü ¸ñ·ÏÀº HTTP + ±Ô¾à (RFC2616 section 10)¿¡¼­ ãÀ» ¼ö ÀÖ´Ù.
    + +
    2326 (%b)
    + +
    ¸¶Áö¸· Ç׸ñÀº ÀÀ´ä Çì´õ¸¦ Á¦¿ÜÇÏ°í Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³»´Â ³»¿ëÀÇ Å©±â¸¦ ³ªÅ¸³½´Ù. Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â + ³»¿ëÀÌ ¾ø´Ù¸é ÀÌ °ªÀº "-"ÀÌ´Ù. ³»¿ëÀÌ + ¾ø´Â °æ¿ì "0"À» ·Î±×ÇÏ·Á¸é ´ë½Å + %B¸¦ »ç¿ëÇÑ´Ù.
    +
    +
    + +
    + Combined ·Î±× Çü½Ä + +

    ÀÚÁÖ »ç¿ëµÇ´Â ´Ù¸¥ Çü½Ä¹®ÀÚ¿­Àº °áÇյȷα×Çü½Ä(Combined + Log Format)ÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\"" combined
    + CustomLog log/access_log combined +
    + +

    ÀÌ Çü½ÄÀº µÎ Ç׸ñÀ» ´õ Ãß°¡ÇÑ °ÍÀ» Á¦¿ÜÇÏ°í´Â Common + ·Î±× Çü½Ä°ú ¿ÏÀüÈ÷ °°´Ù. Ãß°¡µÈ Ç׸ñµéÀº ÆÛ¼¾Æ® Áö½Ã¾î + %{header}i¸¦ »ç¿ëÇÑ´Ù. ¿©±â¼­ + header ÀÚ¸®¿¡ HTTP ¿äû Çì´õ À̸§ÀÌ ³ª¿Ã ¼ö + ÀÖ´Ù. ÀÌ Çü½ÄÀÇ Á¢±Ù ·Î±×´Â ´ÙÀ½°ú °°´Ù:

    + + + 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET + /apache_pb.gif HTTP/1.0" 200 2326 + "http://www.example.com/start.html" "Mozilla/4.08 [en] + (Win98; I ;Nav)" + + +

    Ãß°¡µÈ Ç׸ñÀº:

    + +
    +
    "http://www.example.com/start.html" + (\"%{Referer}i\")
    + +
    "Referer" (¸ÂÃã¹ý Ʋ¸®Áö¾Ê¾ÒÀ½) HTTP ¿äû Çì´õ. + Ŭ¶óÀ̾ðÆ®°¡ ÂüÁ¶Çß´Ù°í ¼­¹ö¿¡°Ô ¾Ë¸° »çÀÌÆ®ÀÌ´Ù. + (Áï, /apache_pb.gif¸¦ ¸µÅ©ÇÏ¿´°Å³ª Æ÷ÇÔÇÑ + »çÀÌÆ®ÀÌ´Ù.)
    + +
    "Mozilla/4.08 [en] (Win98; I ;Nav)" + (\"%{User-agent}i\")
    + +
    User-Agent HTTP ¿äû Çì´õ. Ŭ¶óÀ̾ðÆ® ºê¶ó¿ìÀú°¡ + Àڽſ¡ ´ëÇØ ¾Ë¸®´Â ½Äº°Á¤º¸ÀÌ´Ù.
    +
    +
    + +
    + ¿©·¯ Á¢±Ù ·Î±× + +

    ¼³Á¤ÆÄÀÏ¿¡ ¿©·¯ CustomLog Áö½Ã¾î¸¦ + »ç¿ëÇϸé Á¢±Ù ·Î±×°¡ ¿©·¯°³ ¸¸µé¾îÁø´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ + ¼³Á¤Àº ¼¼°¡Áö Á¢±Ù ·Î±×¸¦ ¸¸µç´Ù. ù¹ø°´Â ±âº» CLF Á¤º¸¸¦ + ±â·ÏÇÏ°í, µÎ¹ø°¿Í ¼¼¹ø°´Â referer¿Í ºê¶ó¿ìÀú Á¤º¸¸¦ + ±â·ÏÇÑ´Ù. ¸¶Áö¸· µÎ CustomLog ÁÙÀº ¾î¶»°Ô + ÀÌÀü ReferLog¿Í AgentLog Áö½Ã¾îÀÇ + ±â´ÉÀ» Èä³»³¾ ¼ö ÀÖ´ÂÁö º¸¿©ÁØ´Ù.

    + + + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    + CustomLog logs/referer_log "%{Referer}i -> %U"
    + CustomLog logs/agent_log "%{User-agent}i" +
    + +

    ¶Ç, ÀÌ ¿¹´Â LogFormatÀ¸·Î ¹Ýµå½Ã + º°¸íÀ» Á¤ÀÇÇÒ ÇÊ¿ä´Â ¾øÀ½À» º¸¿©ÁØ´Ù. ´ë½Å CustomLog Áö½Ã¾î¿¡ + Á÷Á¢ ·Î±× Çü½ÄÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    + Á¶°ÇºÎ ·Î±× + +

    Ŭ¶óÀ̾ðÆ® ¿äûÀÇ ¼º°Ý¿¡ µû¶ó ÇØ´ç Ç׸ñÀ» Á¢±Ù ·Î±×¿¡ + ±â·ÏÇÏÁö¾Ê°í ½ÍÀ» ¶§°¡ ÀÖ´Ù. ȯ°æº¯¼ö¸¦ + »ç¿ëÇÏ¸é ½±°Ô ÇØ°áµÈ´Ù. ¸ÕÀú, Ŭ¶óÀ̾ðÆ®°¡ ƯÁ¤ Á¶°ÇÀ» + ¸¸Á·Çϸé ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ ÀÛ¾÷¿¡´Â º¸Åë SetEnvIf¸¦ »ç¿ëÇÑ´Ù. + ±×¸®°í CustomLog + Áö½Ã¾î¿¡ env=À» »ç¿ëÇÏ¿© ȯ°æº¯¼ö À¯¹«¿¡ + µû¶ó ¿äûÀ» Áý¾î³Ö°Å³ª »«´Ù. ¿¹¸¦ µé¸é:

    + + + # loop-back ÀÎÅÍÆäÀ̽º¿¡¼­ ¿äûÀ» Ç¥½ÃÇÑ´Ù
    + SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
    + # robots.txt ÆÄÀÏ¿¡ ´ëÇÑ ¿äûÀ» Ç¥½ÃÇÑ´Ù
    + SetEnvIf Request_URI "^/robots\.txt$" dontlog
    + # ³ª¸ÓÁö¸¦ ·Î±×¿¡ ³²±ä´Ù
    + CustomLog logs/access_log common env=!dontlog +
    + +

    ´Ù¸¥ ¿¹·Î ¿µ¾î±Ç »ç¿ëÀÚÀÇ ¿äû¸¸À» ÇÑ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ°í, + ºñ¿µ¾î±Ç »ç¿ëÀÚÀÇ ¿äûÀº ´Ù¸¥ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ´Â °æ¿ì¸¦ + »ý°¢Çغ¸ÀÚ.

    + + + SetEnvIf Accept-Language "en" english
    + CustomLog logs/english_log common env=english
    + CustomLog logs/non_english_log common env=!english +
    + +

    Á¶°ÇºÎ ·Î±×´Â ¸Å¿ì °­·ÂÇÏ°í À¯¿¬ÇÏÁö¸¸, ÀÌ°ÍÀÌ ·Î±× + ³»¿ëÀ» Á¶ÀýÇÏ´Â À¯ÀÏÇÑ ¹æ¹ýÀº ¾Æ´Ï´Ù. ·Î±×ÆÄÀÏÀº ¼­¹öÀÇ + ¸ðµç ÇൿÀ» ±â·ÏÇÒ¶§ ´õ À¯¿ëÇÏ´Ù. ³ªÁß¿¡ ¿øÇÏÁö¾Ê´Â ¿äûÀ» + Á¦¿ÜÇÏ°í ·Î±×ÆÄÀÏÀ» ºÐ¼®ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    +
    +
    + +
    + ·Î±× ¼øȯ (Log Rotation) + +

    Á¶±Ý ¹Ù»Û ¼­¹öÁ¶Â÷µµ ·Î±×ÆÄÀÏ¿¡ ÀúÀåµÇ´Â Á¤º¸·®Àº ¸Å¿ì + ¸¹´Ù. Á¢¼Ó ·Î±×´Â º¸Åë ¸¸¹ø ¿äû´ç 1MB ÀÌ»ó Áõ°¡ÇÑ´Ù. °á°úÀûÀ¸·Î + ±âÁ¸ÀÇ ·Î±×¸¦ ¿Å±â°Å³ª Áö¿ì´Â ¹æ¹ýÀ¸·Î ·Î±×¸¦ ÁÖ±âÀûÀ¸·Î + ¼øÈ°ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ÆÄÀÏÀ» ¿­°íÀÖ´Â µ¿¾È¿¡´Â °è¼Ó + ÀÌÀü ·Î±×ÆÄÀÏ¿¡ ¾²±â¶§¹®¿¡ ¼­¹ö°¡ ½ÇÇàÁßÀ϶§ ·Î±×¸¦ ¼øȯÇÒ + ¼ö ¾ø´Ù. ´ë½Å ·Î±×ÆÄÀÏÀ» ¿Å±â°Å³ª Áö¿îÈÄ ¼­¹ö¸¦ Àç½ÃÀÛÇÏ¿©, ·Î±×ÆÄÀÏÀ» »õ·Î ¿­¾î¾ß + ÇÑ´Ù.

    + +

    Á¡ÀÝÀº Àç½ÃÀÛÀ» »ç¿ëÇÏ¸é ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®¿Í + ±âÁ¸ÀÇ È¤Àº ´ë±âµÈ ¿¬°áÀ» ÀÒÁö¾Ê°í »õ ·Î±×ÆÄÀÏÀ» ¿­ ¼ö ÀÖ´Ù. + ±×·¯³ª À̸¦ À§ÇØ ¼­¹ö´Â ¿À·¡µÈ ¿äûÀÇ ¼­ºñ½º¸¦ ³¡³»´Â µ¿¾È + ÀÌÀü ·Î±×ÆÄÀÏÀ» °è¼Ó »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯¹Ç·Î Àç½ÃÀÛÇÑÈÄ + ·Î±×ÆÄÀÏÀ» ó¸®Çϱâ Àü¿¡ ¾ó¸¶°£ ±â´Ù¸± ÇÊ¿ä°¡ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î + ´ÙÀ½°ú °°ÀÌ ·Î±×¸¦ ¼øȯÇÏ°í, µð½ºÅ©°ø°£À» Àý¾àÇϱâÀ§ÇØ ÀÌÀü + ·Î±×¸¦ ¾ÐÃàÇÑ´Ù:

    + + + mv access_log access_log.old
    + mv error_log error_log.old
    + apachectl graceful
    + sleep 600
    + gzip access_log.old error_log.old +
    + +

    ·Î±×¸¦ ¼øȯÇÏ´Â ´Ù¸¥ ¹æ¹ýÀº ´ÙÀ½ Àý¿¡¼­ ¼³¸íÇÒ ÆÄÀÌÇÁ ·Î±×¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù.

    +
    + +
    + ·Î±×¸¦ ÆÄÀÌÇÁ·Î º¸³»±â + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¿À·ù ·Î±×¿Í Á¢±Ù ·Î±×¸¦ ÆÄÀÏ¿¡ Á÷Á¢ + ¾²Áö¾Ê°í ÆÄÀÌÇÁ¸¦ ÅëÇØ ´Ù¸¥ ÇÁ·Î¼¼½º·Î º¸³¾ ¼ö ÀÖ´Ù. ÀÌ + ±â´ÉÀ» »ç¿ëÇÏ¸é ¼­¹ö¿¡ Äڵ带 Ãß°¡ÇÏÁö¾Ê°íµµ ¸Å¿ì À¯¿¬ÇÏ°Ô + ·Î±×¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. ·Î±×¸¦ ÆÄÀÌÇÁ¿¡ ¾²±âÀ§ÇØ ÆÄÀϸí + ÀÚ¸®¿¡ ÆÄÀÌÇÁ¹®ÀÚ "|"¿Í µÚ¿¡ Ç¥ÁØÀÔ·ÂÀ¸·Î + ·Î±× Ç׸ñÀ» ÀÐÀ» ½ÇÇàÆÄÀϸíÀ» ÀûÀ¸¸é µÈ´Ù. ¾ÆÆÄÄ¡´Â ¼­¹ö°¡ + ½ÃÀÛÇÒ¶§ ÆÄÀÌÇÁ·Î ¿¬°áÇÒ ·Î±× ÇÁ·Î¼¼½º¸¦ ½ÃÀÛÇÏ°í, ¼­¹ö°¡ + ½ÇÇàµÇ´Â µ¿¾È ÇÁ·Î¼¼½º°¡ Á×À¸¸é ´Ù½Ã ½ÃÀÛÇÑ´Ù. (ÀÌ ¸¶Áö¸· + ±â´É¶§¹®¿¡ ¿ì¸®´Â ÀÌ ¹æ¹ýÀ» "¹ÏÀ» ¼ö ÀÖ´Â ÆÄÀÌÇÁ ·Î±×"¶ó°í + ºÎ¸¥´Ù.)

    + +

    ÆÄÀÌÇÁ·Î ¿¬°áµÈ ·Î±× ÇÁ·Î¼¼½º´Â ºÎ¸ð ¾ÆÆÄÄ¡ httpd ÇÁ·Î¼¼½º°¡ + ¶ç¿ì°í, ÇÁ·Î¼¼½ºÀÇ useridµµ °°´Ù. Áï, ÆÄÀÌÇÁ·Î ¿¬°áµÈ ·Î±× + ÇÁ·Î±×·¥Àº º¸Åë root·Î ½ÇÇàµÈ´Ù. ±×·¯¹Ç·Î ÇÁ·Î±×·¥À» °£´ÜÇÏ°í + ¾ÈÀüÇÏ°Ô ¸¸µå´Â °ÍÀÌ ¸Å¿ì Áß¿äÇÏ´Ù.

    + +

    ÆÄÀÌÇÁ·Î ºÎ¸£´Â Àüü ¸í·É¾î¸¦ µû¿ÈÇ¥·Î ¹­À½À» ¸í½ÉÇ϶ó. + ÀÌ ¿¹´Â Á¢±Ù ·Î±×¿¡ ´ëÇÑ °ÍÀÌÁö¸¸, ¿À·ù ·Î±×µµ ¸¶Âù°¡Áö´Ù.

    + +

    ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö¾Ê°í ·Î±×¸¦ ¼øȯÇÒ ¼ö ÀÖ´Â °ÍÀÌ ÆÄÀÌÇÁ + ·Î±×¸¦ »ç¿ëÇÏ´Â Áß¿äÇÑ ÀÌÀ¯´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â À̸¦ À§ÇØ + rotatelogs¶ó´Â °£´ÜÇÑ + ÇÁ·Î±×·¥À» Æ÷ÇÔÇÑ´Ù. ¿¹¸¦ µé¾î 24½Ã°£¸¶´Ù ·Î±×¸¦ ¼øȯÇÑ´Ù¸é:

    + + + CustomLog "|/usr/local/apache/bin/rotatelogs + /var/log/access_log 86400" common + + +

    ´Ù¸¥ »çÀÌÆ®¿¡ cronolog¶ó´Â ºñ½ÁÇÏÁö¸¸ + ÈξÀ ´õ À¯¿¬ÇÑ ·Î±× ¼øȯ ÇÁ·Î±×·¥ÀÌ ÀÖ´Ù.

    + +

    Á¶°ÇºÎ ·Î±×¿Í °°ÀÌ ÆÄÀÌÇÁ ·Î±×´Â ¸Å¿ì °­·ÂÇÑ µµ±¸Áö¸¸, + ³ªÁß¿¡ ó¸®ÇÏ´Â µîÀÇ ´õ °£´ÜÇÑ ¹æ¹ýÀÌ °¡´ÉÇÑ °æ¿ì »ç¿ëÇؼ­´Â + ¾ÈµÈ´Ù.

    +
    + +
    + °¡»óÈ£½ºÆ® + +

    ¸¹Àº °¡»óÈ£½ºÆ®°¡ ÀÖ´Â ¼­¹ö¸¦ + ¿î¿µÇÒ¶§ ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î ·Î±×ÆÄÀÏÀ» ´Ù·ê ¼ö ÀÖ´Ù. ¸ÕÀú, + È£½ºÆ®°¡ ÇÑ°³ÀÎ ¼­¹ö¿Í °°ÀÌ ·Î±×¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. VirtualHost ¼½¼ÇÀÌ + ¾Æ´Ñ ÁÖ¼­¹ö ¼³Á¤¿¡ ·Î±× Áö½Ã¾î¸¦ µÎ¸é ¸ðµç ¿äûÀÌ °°Àº Á¢±Ù + ·Î±×¿Í ¿À·ù ·Î±×·Î ±â·ÏµÈ´Ù. ÀÌ ¹æ¹ýÀº °¡»óÈ£½ºÆ®º°·Î ½±°Ô + Åë°è󸮸¦ ÇÒ ¼ö ¾ø´Ù.

    + +

    VirtualHost + ¼½¼Ç ¾È¿¡ CustomLog³ª + ErrorLog Áö½Ã¾î¸¦ + »ç¿ëÇϸé ÇØ´ç °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ ¿äû°ú ¿À·ù¸¸ÀÌ ÁöÁ¤µÈ + ÆÄÀÏ¿¡ ±â·ÏµÈ´Ù. ·Î±× Áö½Ã¾î°¡ ¾ø´Â ´Ù¸¥ °¡»óÈ£½ºÆ®´Â °è¼Ó + ÁÖ¼­¹ö ·Î±×¿¡ ·Î±×¸¦ ±â·ÏÇÑ´Ù. ÀÌ ¹æ¹ýÀº °¡»óÈ£½ºÆ® °³¼ö°¡ + ÀûÀ» °æ¿ì ¸Å¿ì À¯¿ëÇÏÁö¸¸, È£½ºÆ® ¼ö°¡ ¸¹´Ù¸é °ü¸®Çϱâ + Èûµé¾îÁø´Ù. ¶Ç, ÆÄÀϱâ¼úÀÚ°¡ + ºÎÁ·ÇÑ ¹®Á¦°¡ ÀÚÁÖ ¹ß»ýÇÑ´Ù.

    + +

    Á¢±Ù ·Î±×ÀÇ °æ¿ì ¸Å¿ì ÁÁÀº ÇØ°áÃ¥ÀÌ ÀÖ´Ù. ·Î±× Çü½Ä¹®ÀÚ¿­¿¡ + °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ Á¤º¸¸¦ Ãß°¡ÇÏ¸é ¸ðµç È£½ºÆ®°¡ °°Àº ·Î±×¸¦ + »ç¿ëÇÏ°í, ³ªÁß¿¡ ·Î±×¸¦ °¡»óÈ£½ºÆ®º°·Î ³ª´­ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ´ÙÀ½ Áö½Ã¾î¸¦ ºÁ¶ó.

    + + + LogFormat "%v %l %u %t \"%r\" %>s %b" + comonvhost
    + CustomLog logs/access_log comonvhost +
    + +

    %v´Â ¿äûÀ» ¼­ºñ½ºÇÏ´Â °¡»óÈ£½ºÆ® À̸§À» + ±â·ÏÇÑ´Ù. ³ªÁß¿¡ split-logfile + °°Àº ÇÁ·Î±×·¥À¸·Î Á¢±Ù ·Î±×¸¦ °¡»óÈ£½ºº°·Î ³ª´­ ¼ö ÀÖ´Ù.

    +
    + +
    + ´Ù¸¥ ·Î±×ÆÄÀÏ + + + + mod_cgi + mod_rewrite + + + PidFile + RewriteLog + RewriteLogLevel + ScriptLog + ScriptLogBuffer + ScriptLogLength + + + +
    + PID ÆÄÀÏ + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ½ÃÀÛÇÒ¶§ logs/httpd.pid + ÆÄÀÏ¿¡ ºÎ¸ð httpd ÇÁ·Î¼¼½ºÀÇ process id¸¦ ÀúÀåÇÑ´Ù. ÀÌ + ÆÄÀϸíÀº PidFile + Áö½Ã¾î·Î º¯°æÇÒ ¼ö ÀÖ´Ù. process-id´Â °ü¸®ÀÚ°¡ ºÎ¸ð ÇÁ·Î¼¼½º¿¡ + ½Ã±×³ÎÀ» º¸³» ¼­¹ö¸¦ Àç½ÃÀÛÇϰųª Á×À϶§ »ç¿ëÇÑ´Ù. + À©µµ¿ìÁî¿¡¼­´Â ´ë½Å -k ¸í·ÉÇà¿É¼ÇÀ» »ç¿ëÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ + Á¤º¸´Â Áß´Ü°ú Àç½ÃÀÛ ÆäÀÌÁö¸¦ + Âü°íÇ϶ó.

    +
    + +
    + ½ºÅ©¸³Æ® ·Î±× + +

    µð¹ö±ëÀ» µ½±âÀ§ÇØ ScriptLog Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + CGI ½ºÅ©¸³Æ®ÀÇ ÀԷ°ú Ãâ·ÂÀ» ±â·ÏÇÒ ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾î´Â + ¿ÀÁ÷ Å×½ºÆ®¿ëÀ¸·Î¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù. ½ÇÁ¦ »ç¿ëÇÏ´Â ¼­¹ö¿¡¼­ + »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â mod_cgi ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    + ÀçÀÛ¼º ·Î±× + +

    mod_rewriteÀÇ °­·ÂÇÏ°í + º¹ÀâÇÑ ±â´ÉÀ» »ç¿ëÇÑ´Ù¸é µð¹ö±ëÀ» À§ÇØ °ÅÀÇ Ç×»ó RewriteLog¸¦ »ç¿ëÇÒ ÇÊ¿ä°¡ + ÀÖ´Ù. ÀÌ ·Î±×ÆÄÀÏÀº ÀçÀÛ¼º ¿£ÁøÀÌ ¾î¶»°Ô ¿äûÀ» º¯È¯ÇÏ´ÂÁö¿¡ + ´ëÇØ ÀÚ¼¼È÷ ¾Ë·ÁÁØ´Ù. ÀÚ¼¼ÇÑ Á¤µµ´Â RewriteLogLevel Áö½Ã¾î·Î + Á¶ÀýÇÑ´Ù.

    +
    +
    +
    + + + + diff --git a/trunk/docs/manual/logs.xml.meta b/trunk/docs/manual/logs.xml.meta new file mode 100644 index 0000000000..fad92b8a75 --- /dev/null +++ b/trunk/docs/manual/logs.xml.meta @@ -0,0 +1,13 @@ + + + + logs + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/misc/index.html b/trunk/docs/manual/misc/index.html new file mode 100644 index 0000000000..5b7bb86fb2 --- /dev/null +++ b/trunk/docs/manual/misc/index.html @@ -0,0 +1,7 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/misc/index.html.en b/trunk/docs/manual/misc/index.html.en new file mode 100644 index 0000000000..f6732a4f25 --- /dev/null +++ b/trunk/docs/manual/misc/index.html.en @@ -0,0 +1,80 @@ + + + +Apache Miscellaneous Documentation - Apache HTTP Server + + + + + +
    <-
    +

    Apache Miscellaneous Documentation

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    Below is a list of additional documentation pages that apply + to the Apache web server development project.

    + +

    Warning

    +

    The documents below have not been fully updated + to take into account changes made in the 2.1 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

    +
    + +
    +
    Performance Notes - Apache + Tuning
    + +
    +

    Notes about how to (run-time and compile-time) configure + Apache for highest performance. Notes explaining why Apache + does some things, and why it doesn't do other things (which + make it slower/faster).

    +
    + +
    Security Tips
    + +
    +

    Some "do"s - and "don't"s - for keeping your Apache web + site secure.

    +
    + +
    URL Rewriting Guide
    + +
    +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems webmasters are usually confronted + with in practice.

    +
    + +
    Relevant Standards
    + +
    +

    This document acts as a reference page for most of the relevant + standards that Apache follows.

    +
    +
    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/index.html.ko.euc-kr b/trunk/docs/manual/misc/index.html.ko.euc-kr new file mode 100644 index 0000000000..c7c11da671 --- /dev/null +++ b/trunk/docs/manual/misc/index.html.ko.euc-kr @@ -0,0 +1,76 @@ + + + +±âŸ ¾ÆÆÄÄ¡ ¹®¼­ - Apache HTTP Server + + + + + +
    <-
    +

    ±âŸ ¾ÆÆÄÄ¡ ¹®¼­

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + +

    ¾Æ·¡´Â ¾ÆÆÄÄ¡ À¥¼­¹ö °³¹ß ÇÁ·ÎÁ§Æ®¿¡ ´ëÇÑ Ãß°¡ ¹®¼­ + ¸ñ·ÏÀÌ´Ù.

    + +

    ÁÖÀÇ

    +

    ¾Æ·¡ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.1 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» + ´ã°í ÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ + »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    +
    + +
    +
    ¾ÆÆÄÄ¡ ¼º´ÉÇâ»ó
    + +
    +

    ÃÖ°íÀÇ ¼º´ÉÀ» ³»±âÀ§ÇØ ¾ÆÆÄÄ¡¸¦ (½ÇÇà½Ã, ÄÄÆÄÀϽÃ) + ¼³Á¤ÇÏ´Â ¹æ¹ýÀ» ´Ù·é´Ù. ¾ÆÆÄÄ¡°¡ ¿Ö ¾î¶² ÀÛ¾÷À» ÇÏ°í + (¾ÆÆÄÄ¡¸¦ ´À¸®°Å³ª ºü¸£°Ô ¸¸µå´Â) ¾î¶² ÀÛ¾÷À» ÇÏÁö ¾Ê´ÂÁö + ¼³¸íÇÑ´Ù.

    +
    + +
    º¸¾È ÆÁ
    + +
    +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¾ÈÀüÇÏ°Ô À¯ÁöÇϱâÀ§ÇØ "ÇÒ ÀÏ"°ú "ÇÏÁö + ¸»¾Æ¾ß ÇÒ ÀÏ".

    +
    + +
    URL ÀçÀÛ¼º Áöħ¼­
    + +
    +

    ÀÌ ¹®¼­´Â mod_rewrite ÂüÁ¶ ¹®¼­¸¦ º¸ÃæÇÑ´Ù. + ÀÌ ¹®¼­´Â À¥°ü¸®ÀÚ°¡ ½ÇÁ¦ ÀÛ¾÷¿¡¼­ ºÎµúÄ¡°ÔµÇ´Â ÀüÇüÀûÀÎ + URL°ü·Ã ¹®Á¦¸¦ ÇØ°áÇϱâÀ§Çؼ­ ¾î¶»°Ô ¾ÆÆÄÄ¡ + mod_rewrite¸¦ »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + +
    °ü·Ã Ç¥ÁØ
    + +
    +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡°¡ µû¸£´Â °ü·Ã Ç¥ÁصéÀ» ¿­°ÅÇÑ´Ù.

    +
    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/index.xml b/trunk/docs/manual/misc/index.xml new file mode 100644 index 0000000000..731945c9a4 --- /dev/null +++ b/trunk/docs/manual/misc/index.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + Apache Miscellaneous Documentation + + + +

    Below is a list of additional documentation pages that apply + to the Apache web server development project.

    + + Warning +

    The documents below have not been fully updated + to take into account changes made in the 2.1 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

    +
    + +
    +
    Performance Notes - Apache + Tuning
    + +
    +

    Notes about how to (run-time and compile-time) configure + Apache for highest performance. Notes explaining why Apache + does some things, and why it doesn't do other things (which + make it slower/faster).

    +
    + +
    Security Tips
    + +
    +

    Some "do"s - and "don't"s - for keeping your Apache web + site secure.

    +
    + +
    URL Rewriting Guide
    + +
    +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems webmasters are usually confronted + with in practice.

    +
    + +
    Relevant Standards
    + +
    +

    This document acts as a reference page for most of the relevant + standards that Apache follows.

    +
    +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/index.xml.ko b/trunk/docs/manual/misc/index.xml.ko new file mode 100644 index 0000000000..227f317512 --- /dev/null +++ b/trunk/docs/manual/misc/index.xml.ko @@ -0,0 +1,75 @@ + + + + + + + + + + + ±âŸ ¾ÆÆÄÄ¡ ¹®¼­ + + + +

    ¾Æ·¡´Â ¾ÆÆÄÄ¡ À¥¼­¹ö °³¹ß ÇÁ·ÎÁ§Æ®¿¡ ´ëÇÑ Ãß°¡ ¹®¼­ + ¸ñ·ÏÀÌ´Ù.

    + + ÁÖÀÇ +

    ¾Æ·¡ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.1 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» + ´ã°í ÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ + »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    +
    + +
    +
    ¾ÆÆÄÄ¡ ¼º´ÉÇâ»ó
    + +
    +

    ÃÖ°íÀÇ ¼º´ÉÀ» ³»±âÀ§ÇØ ¾ÆÆÄÄ¡¸¦ (½ÇÇà½Ã, ÄÄÆÄÀϽÃ) + ¼³Á¤ÇÏ´Â ¹æ¹ýÀ» ´Ù·é´Ù. ¾ÆÆÄÄ¡°¡ ¿Ö ¾î¶² ÀÛ¾÷À» ÇÏ°í + (¾ÆÆÄÄ¡¸¦ ´À¸®°Å³ª ºü¸£°Ô ¸¸µå´Â) ¾î¶² ÀÛ¾÷À» ÇÏÁö ¾Ê´ÂÁö + ¼³¸íÇÑ´Ù.

    +
    + +
    º¸¾È ÆÁ
    + +
    +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¾ÈÀüÇÏ°Ô À¯ÁöÇϱâÀ§ÇØ "ÇÒ ÀÏ"°ú "ÇÏÁö + ¸»¾Æ¾ß ÇÒ ÀÏ".

    +
    + +
    URL ÀçÀÛ¼º Áöħ¼­
    + +
    +

    ÀÌ ¹®¼­´Â mod_rewrite ÂüÁ¶ ¹®¼­¸¦ º¸ÃæÇÑ´Ù. + ÀÌ ¹®¼­´Â À¥°ü¸®ÀÚ°¡ ½ÇÁ¦ ÀÛ¾÷¿¡¼­ ºÎµúÄ¡°ÔµÇ´Â ÀüÇüÀûÀÎ + URL°ü·Ã ¹®Á¦¸¦ ÇØ°áÇϱâÀ§Çؼ­ ¾î¶»°Ô ¾ÆÆÄÄ¡ + mod_rewrite¸¦ »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + +
    °ü·Ã Ç¥ÁØ
    + +
    +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡°¡ µû¸£´Â °ü·Ã Ç¥ÁصéÀ» ¿­°ÅÇÑ´Ù.

    +
    +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/index.xml.meta b/trunk/docs/manual/misc/index.xml.meta new file mode 100644 index 0000000000..47616bdf61 --- /dev/null +++ b/trunk/docs/manual/misc/index.xml.meta @@ -0,0 +1,12 @@ + + + + index + /misc/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/misc/perf-tuning.html b/trunk/docs/manual/misc/perf-tuning.html new file mode 100644 index 0000000000..5eaaf7158e --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.html @@ -0,0 +1,7 @@ +URI: perf-tuning.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: perf-tuning.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/misc/perf-tuning.html.en b/trunk/docs/manual/misc/perf-tuning.html.en new file mode 100644 index 0000000000..d31b0e9ee5 --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.html.en @@ -0,0 +1,1056 @@ + + + +Apache Performance Tuning - Apache HTTP Server + + + + + +
    <-
    +

    Apache Performance Tuning

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    Apache 2.0 is a general-purpose webserver, designed to + provide a balance of flexibility, portability, and performance. + Although it has not been designed specifically to set benchmark + records, Apache 2.0 is capable of high performance in many + real-world situations.

    + +

    Compared to Apache 1.3, release 2.0 contains many additional + optimizations to increase throughput and scalability. Most of + these improvements are enabled by default. However, there are + compile-time and run-time configuration choices that can + significantly affect performance. This document describes the + options that a server administrator can configure to tune the + performance of an Apache 2.0 installation. Some of these + configuration options enable the httpd to better take advantage + of the capabilities of the hardware and OS, while others allow + the administrator to trade functionality for speed.

    + +
    + +
    top
    +
    +

    Hardware and Operating System Issues

    + + + +

    The single biggest hardware issue affecting webserver + performance is RAM. A webserver should never ever have to swap, + as swapping increases the latency of each request beyond a point + that users consider "fast enough". This causes users to hit + stop and reload, further increasing the load. You can, and + should, control the MaxClients setting so that your server + does not spawn so many children it starts swapping. This procedure + for doing this is simple: determine the size of your average Apache + process, by looking at your process list via a tool such as + top, and divide this into your total available memory, + leaving some room for other processes.

    + +

    Beyond that the rest is mundane: get a fast enough CPU, a + fast enough network card, and fast enough disks, where "fast + enough" is something that needs to be determined by + experimentation.

    + +

    Operating system choice is largely a matter of local + concerns. But some guidelines that have proven generally + useful are:

    + +
      +
    • +

      Run the latest stable release and patchlevel of the + operating system that you choose. Many OS suppliers have + introduced significant performance improvements to their + TCP stacks and thread libraries in recent years.

      +
    • + +
    • +

      If your OS supports a sendfile(2) system + call, make sure you install the release and/or patches + needed to enable it. (With Linux, for example, this means + using Linux 2.4 or later. For early releases of Solaris 8, + you may need to apply a patch.) On systems where it is + available, sendfile enables Apache 2 to deliver + static content faster and with lower CPU utilization.

      +
    • +
    + +
    top
    +
    +

    Run-Time Configuration Issues

    + + + + + +

    HostnameLookups and other DNS considerations

    + + + +

    Prior to Apache 1.3, HostnameLookups defaulted to On. + This adds latency to every request because it requires a + DNS lookup to complete before the request is finished. In + Apache 1.3 this setting defaults to Off. If you need + to have addresses in your log files resolved to hostnames, use the + logresolve + program that comes with Apache, on one of the numerous log + reporting packages which are available.

    + +

    It is recommended that you do this sort of postprocessing of + your log files on some machine other than the production web + server machine, in order that this activity not adversely affect + server performance.

    + +

    If you use any Allow + from domain or Deny from domain + directives (i.e., using a hostname, or a domain name, rather than + an IP address) then you will pay for + a double reverse DNS lookup (a reverse, followed by a forward + to make sure that the reverse is not being spoofed). For best + performance, therefore, use IP addresses, rather than names, when + using these directives, if possible.

    + +

    Note that it's possible to scope the directives, such as + within a <Location /server-status> section. + In this case the DNS lookups are only performed on requests + matching the criteria. Here's an example which disables lookups + except for .html and .cgi files:

    + +

    + HostnameLookups off
    + <Files ~ "\.(html|cgi)$">
    + + HostnameLookups on
    +
    + </Files> +

    + +

    But even still, if you just need DNS names in some CGIs you + could consider doing the gethostbyname call in the + specific CGIs that need it.

    + + + +

    FollowSymLinks and SymLinksIfOwnerMatch

    + + + +

    Wherever in your URL-space you do not have an Options + FollowSymLinks, or you do have an Options + SymLinksIfOwnerMatch Apache will have to issue extra + system calls to check up on symlinks. One extra call per + filename component. For example, if you had:

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + Options SymLinksIfOwnerMatch
    +
    + </Directory> +

    + +

    and a request is made for the URI /index.html. + Then Apache will perform lstat(2) on + /www, /www/htdocs, and + /www/htdocs/index.html. The results of these + lstats are never cached, so they will occur on + every single request. If you really desire the symlinks + security checking you can do something like this:

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + Options FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /www/htdocs>
    + + Options -FollowSymLinks +SymLinksIfOwnerMatch
    +
    + </Directory> +

    + +

    This at least avoids the extra checks for the + DocumentRoot path. + Note that you'll need to add similar sections if you + have any Alias or + RewriteRule paths + outside of your document root. For highest performance, + and no symlink protection, set FollowSymLinks + everywhere, and never set SymLinksIfOwnerMatch.

    + + + +

    AllowOverride

    + + + +

    Wherever in your URL-space you allow overrides (typically + .htaccess files) Apache will attempt to open + .htaccess for each filename component. For + example,

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + AllowOverride all
    +
    + </Directory> +

    + +

    and a request is made for the URI /index.html. + Then Apache will attempt to open /.htaccess, + /www/.htaccess, and + /www/htdocs/.htaccess. The solutions are similar + to the previous case of Options FollowSymLinks. + For highest performance use AllowOverride None + everywhere in your filesystem.

    + + + +

    Negotiation

    + + + +

    If at all possible, avoid content-negotiation if you're + really interested in every last ounce of performance. In + practice the benefits of negotiation outweigh the performance + penalties. There's one case where you can speed up the server. + Instead of using a wildcard such as:

    + +

    + DirectoryIndex index +

    + +

    Use a complete list of options:

    + +

    + DirectoryIndex index.cgi index.pl index.shtml index.html +

    + +

    where you list the most common choice first.

    + +

    Also note that explicitly creating a type-map + file provides better performance than using + MultiViews, as the necessary information can be + determined by reading this single file, rather than having to + scan the directory for files.

    + +

    If your site needs content negotiation consider using + type-map files, rather than the Options + MultiViews directive to accomplish the negotiation. See the + Content Negotiation + documentation for a full discussion of the methods of negotiation, + and instructions for creating type-map files.

    + + + +

    Memory-mapping

    + + + +

    In situations where Apache 2.0 needs to look at the contents + of a file being delivered--for example, when doing server-side-include + processing--it normally memory-maps the file if the OS supports + some form of mmap(2).

    + +

    On some platforms, this memory-mapping improves performance. + However, there are cases where memory-mapping can hurt the performance + or even the stability of the httpd:

    + +
      +
    • +

      On some operating systems, mmap does not scale + as well as read(2) when the number of CPUs increases. + On multiprocessor Solaris servers, for example, Apache 2.0 sometimes + delivers server-parsed files faster when mmap is disabled.

      +
    • + +
    • +

      If you memory-map a file located on an NFS-mounted filesystem + and a process on another NFS client machine deletes or truncates + the file, your process may get a bus error the next time it tries + to access the mapped file content.

      +
    • +
    + +

    For installations where either of these factors applies, you + should use EnableMMAP off to disable the memory-mapping + of delivered files. (Note: This directive can be overridden on + a per-directory basis.)

    + + + +

    Sendfile

    + + + +

    In situations where Apache 2.0 can ignore the contents of the file + to be delivered -- for example, when serving static file content -- + it normally uses the kernel sendfile support the file if the OS + supports the sendfile(2) operation.

    + +

    On most platforms, using sendfile improves performance by eliminating + separate read and send mechanics. However, there are cases where using + sendfile can harm the stability of the httpd:

    + +
      +
    • +

      Some platforms may have broken sendfile support that the build + system did not detect, especially if the binaries were built on + another box and moved to such a machine with broken sendfile support.

      +
    • +
    • +

      With an NFS-mounted files, the kernel may be unable + to reliably serve the network file through it's own cache.

      +
    • +
    + +

    For installations where either of these factors applies, you + should use EnableSendfile off to disable sendfile + delivery of file contents. (Note: This directive can be overridden + on a per-directory basis.)

    + + + +

    Process Creation

    + + + +

    Prior to Apache 1.3 the MinSpareServers, MaxSpareServers, and StartServers settings all had drastic effects on + benchmark results. In particular, Apache required a "ramp-up" + period in order to reach a number of children sufficient to serve + the load being applied. After the initial spawning of + StartServers children, + only one child per second would be created to satisfy the + MinSpareServers + setting. So a server being accessed by 100 simultaneous + clients, using the default StartServers of 5 would take on + the order 95 seconds to spawn enough children to handle + the load. This works fine in practice on real-life servers, + because they aren't restarted frequently. But does really + poorly on benchmarks which might only run for ten minutes.

    + +

    The one-per-second rule was implemented in an effort to + avoid swamping the machine with the startup of new children. If + the machine is busy spawning children it can't service + requests. But it has such a drastic effect on the perceived + performance of Apache that it had to be replaced. As of Apache + 1.3, the code will relax the one-per-second rule. It will spawn + one, wait a second, then spawn two, wait a second, then spawn + four, and it will continue exponentially until it is spawning + 32 children per second. It will stop whenever it satisfies the + MinSpareServers + setting.

    + +

    This appears to be responsive enough that it's almost + unnecessary to twiddle the MinSpareServers, MaxSpareServers and StartServers knobs. When more than 4 children are + spawned per second, a message will be emitted to the + ErrorLog. If you + see a lot of these errors then consider tuning these settings. + Use the mod_status output as a guide.

    + +

    Related to process creation is process death induced by the + MaxRequestsPerChild + setting. By default this is 0, + which means that there is no limit to the number of requests + handled per child. If your configuration currently has this set + to some very low number, such as 30, you may want to bump this + up significantly. If you are running SunOS or an old version of + Solaris, limit this to 10000 or so because of memory leaks.

    + +

    When keep-alives are in use, children will be kept busy + doing nothing waiting for more requests on the already open + connection. The default KeepAliveTimeout of 5 + seconds attempts to minimize this effect. The tradeoff here is + between network bandwidth and server resources. In no event + should you raise this above about 60 seconds, as + most of the benefits are lost.

    + + + +
    top
    +
    +

    Compile-Time Configuration Issues

    + + + +

    Choosing an MPM

    + + + +

    Apache 2.x supports pluggable concurrency models, called + Multi-Processing Modules (MPMs). + When building Apache, you must choose an MPM to use. There + are platform-specific MPMs for some platforms: + beos, mpm_netware, + mpmt_os2, and mpm_winnt. For + general Unix-type systems, there are several MPMs from which + to choose. The choice of MPM can affect the speed and scalability + of the httpd:

    + +
      + +
    • The worker MPM uses multiple child + processes with many threads each. Each thread handles + one connection at a time. Worker generally is a good + choice for high-traffic servers because it has a smaller + memory footprint than the prefork MPM.
    • + +
    • The prefork MPM uses multiple child + processes with one thread each. Each process handles + one connection at a time. On many systems, prefork is + comparable in speed to worker, but it uses more memory. + Prefork's threadless design has advantages over worker + in some situations: it can be used with non-thread-safe + third-party modules, and it is easier to debug on platforms + with poor thread debugging support.
    • + +
    + +

    For more information on these and other MPMs, please + see the MPM documentation.

    + + + +

    Modules

    + + + +

    Since memory usage is such an important consideration in + performance, you should attempt to eliminate modules that youare + not actually using. If you have built the modules as DSOs, eliminating modules is a simple + matter of commenting out the associated LoadModule directive for that module. + This allows you to experiment with removing modules, and seeing + if your site still functions in their absense.

    + +

    If, on the other hand, you have modules statically linked + into your Apache binary, you will need to recompile Apache in + order to remove unwanted modules.

    + +

    An associated question that arises here is, of course, what + modules you need, and which ones you don't. The answer here + will, of course, vary from one web site to another. However, the + minimal list of modules which you can get by with tends + to include mod_mime, mod_dir, + and mod_log_config. mod_log_config is, + of course, optional, as you can run a web site without log + files. This is, however, not recommended.

    + + + +

    Atomic Operations

    + + + +

    Some modules, such as mod_cache and + recent development builds of the worker MPM, use APR's + atomic API. This API provides atomic operations that can + be used for lightweight thread synchronization.

    + +

    By default, APR implements these operations using the + most efficient mechanism available on each target + OS/CPU platform. Many modern CPUs, for example, have + an instruction that does an atomic compare-and-swap (CAS) + operation in hardware. On some platforms, however, APR + defaults to a slower, mutex-based implementation of the + atomic API in order to ensure compatibility with older + CPU models that lack such instructions. If you are + building Apache for one of these platforms, and you plan + to run only on newer CPUs, you can select a faster atomic + implementation at build time by configuring Apache with + the --enable-nonportable-atomics option:

    + +

    + ./buildconf
    + ./configure --with-mpm=worker --enable-nonportable-atomics=yes +

    + +

    The --enable-nonportable-atomics option is + relevant for the following platforms:

    + +
      + +
    • Solaris on SPARC
      + By default, APR uses mutex-based atomics on Solaris/SPARC. + If you configure with --enable-nonportable-atomics, + however, APR generates code that uses a SPARC v8plus opcode for + fast hardware compare-and-swap. If you configure Apache with + this option, the atomic operations will be more efficient + (allowing for lower CPU utilization and higher concurrency), + but the resulting executable will run only on UltraSPARC + chips. +
    • + +
    • Linux on x86
      + By default, APR uses mutex-based atomics on Linux. If you + configure with --enable-nonportable-atomics, + however, APR generates code that uses a 486 opcode for fast + hardware compare-and-swap. This will result in more efficient + atomic operations, but the resulting executable will run only + on 486 and later chips (and not on 386). +
    • + +
    + + + +

    mod_status and ExtendedStatus On

    + + + +

    If you include mod_status and you also set + ExtendedStatus On when building and running + Apache, then on every request Apache will perform two calls to + gettimeofday(2) (or times(2) + depending on your operating system), and (pre-1.3) several + extra calls to time(2). This is all done so that + the status report contains timing indications. For highest + performance, set ExtendedStatus off (which is the + default).

    + + + +

    accept Serialization - multiple sockets

    + + + +

    Warning:

    +

    This section has not been fully updated + to take into account changes made in the 2.0 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

    +
    + +

    This discusses a shortcoming in the Unix socket API. Suppose + your web server uses multiple Listen statements to listen on either multiple + ports or multiple addresses. In order to test each socket + to see if a connection is ready Apache uses + select(2). select(2) indicates that a + socket has zero or at least one connection + waiting on it. Apache's model includes multiple children, and + all the idle ones test for new connections at the same time. A + naive implementation looks something like this (these examples + do not match the code, they're contrived for pedagogical + purposes):

    + +

    + for (;;) {
    + + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + process the new_connection;
    +
    + } +

    + +

    But this naive implementation has a serious starvation problem. + Recall that multiple children execute this loop at the same + time, and so multiple children will block at + select when they are in between requests. All + those blocked children will awaken and return from + select when a single request appears on any socket + (the number of children which awaken varies depending on the + operating system and timing issues). They will all then fall + down into the loop and try to accept the + connection. But only one will succeed (assuming there's still + only one connection ready), the rest will be blocked + in accept. This effectively locks those children + into serving requests from that one socket and no other + sockets, and they'll be stuck there until enough new requests + appear on that socket to wake them all up. This starvation + problem was first documented in PR#467. There + are at least two solutions.

    + +

    One solution is to make the sockets non-blocking. In this + case the accept won't block the children, and they + will be allowed to continue immediately. But this wastes CPU + time. Suppose you have ten idle children in + select, and one connection arrives. Then nine of + those children will wake up, try to accept the + connection, fail, and loop back into select, + accomplishing nothing. Meanwhile none of those children are + servicing requests that occurred on other sockets until they + get back up to the select again. Overall this + solution does not seem very fruitful unless you have as many + idle CPUs (in a multiprocessor box) as you have idle children, + not a very likely situation.

    + +

    Another solution, the one used by Apache, is to serialize + entry into the inner loop. The loop looks like this + (differences highlighted):

    + +

    + for (;;) {
    + + accept_mutex_on ();
    + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + accept_mutex_off ();
    + process the new_connection;
    +
    + } +

    + +

    The functions + accept_mutex_on and accept_mutex_off + implement a mutual exclusion semaphore. Only one child can have + the mutex at any time. There are several choices for + implementing these mutexes. The choice is defined in + src/conf.h (pre-1.3) or + src/include/ap_config.h (1.3 or later). Some + architectures do not have any locking choice made, on these + architectures it is unsafe to use multiple + Listen + directives.

    + +

    The directive AcceptMutex can be used to + change the selected mutex implementation at run-time.

    + +
    +
    AcceptMutex flock
    + +
    +

    This method uses the flock(2) system call to + lock a lock file (located by the LockFile directive).

    +
    + +
    AcceptMutex fcntl
    + +
    +

    This method uses the fcntl(2) system call to + lock a lock file (located by the LockFile directive).

    +
    + +
    AcceptMutex sysvsem
    + +
    +

    (1.3 or later) This method uses SysV-style semaphores to + implement the mutex. Unfortunately SysV-style semaphores have + some bad side-effects. One is that it's possible Apache will + die without cleaning up the semaphore (see the + ipcs(8) man page). The other is that the + semaphore API allows for a denial of service attack by any + CGIs running under the same uid as the webserver + (i.e., all CGIs, unless you use something like + suexec or cgiwrapper). For these + reasons this method is not used on any architecture except + IRIX (where the previous two are prohibitively expensive + on most IRIX boxes).

    +
    + +
    AcceptMutex pthread
    + +
    +

    (1.3 or later) This method uses POSIX mutexes and should + work on any architecture implementing the full POSIX threads + specification, however appears to only work on Solaris (2.5 + or later), and even then only in certain configurations. If + you experiment with this you should watch out for your server + hanging and not responding. Static content only servers may + work just fine.

    +
    + +
    AcceptMutex posixsem
    + +
    +

    (2.0 or later) This method uses POSIX semaphores. The + semaphore ownership is not recovered if a thread in the process + holding the mutex segfaults, resulting in a hang of the web + server.

    +
    + +
    + +

    If your system has another method of serialization which + isn't in the above list then it may be worthwhile adding code + for it to APR.

    + +

    Another solution that has been considered but never + implemented is to partially serialize the loop -- that is, let + in a certain number of processes. This would only be of + interest on multiprocessor boxes where it's possible multiple + children could run simultaneously, and the serialization + actually doesn't take advantage of the full bandwidth. This is + a possible area of future investigation, but priority remains + low because highly parallel web servers are not the norm.

    + +

    Ideally you should run servers without multiple + Listen + statements if you want the highest performance. + But read on.

    + + + +

    accept Serialization - single socket

    + + + +

    The above is fine and dandy for multiple socket servers, but + what about single socket servers? In theory they shouldn't + experience any of these same problems because all children can + just block in accept(2) until a connection + arrives, and no starvation results. In practice this hides + almost the same "spinning" behaviour discussed above in the + non-blocking solution. The way that most TCP stacks are + implemented, the kernel actually wakes up all processes blocked + in accept when a single connection arrives. One of + those processes gets the connection and returns to user-space, + the rest spin in the kernel and go back to sleep when they + discover there's no connection for them. This spinning is + hidden from the user-land code, but it's there nonetheless. + This can result in the same load-spiking wasteful behaviour + that a non-blocking solution to the multiple sockets case + can.

    + +

    For this reason we have found that many architectures behave + more "nicely" if we serialize even the single socket case. So + this is actually the default in almost all cases. Crude + experiments under Linux (2.0.30 on a dual Pentium pro 166 + w/128Mb RAM) have shown that the serialization of the single + socket case causes less than a 3% decrease in requests per + second over unserialized single-socket. But unserialized + single-socket showed an extra 100ms latency on each request. + This latency is probably a wash on long haul lines, and only an + issue on LANs. If you want to override the single socket + serialization you can define + SINGLE_LISTEN_UNSERIALIZED_ACCEPT and then + single-socket servers will not serialize at all.

    + + + +

    Lingering Close

    + + + +

    As discussed in + draft-ietf-http-connection-00.txt section 8, in order for + an HTTP server to reliably implement the + protocol it needs to shutdown each direction of the + communication independently (recall that a TCP connection is + bi-directional, each half is independent of the other). This + fact is often overlooked by other servers, but is correctly + implemented in Apache as of 1.2.

    + +

    When this feature was added to Apache it caused a flurry of + problems on various versions of Unix because of a + shortsightedness. The TCP specification does not state that the + FIN_WAIT_2 state has a timeout, but it doesn't prohibit it. + On systems without the timeout, Apache 1.2 induces many sockets + stuck forever in the FIN_WAIT_2 state. In many cases this + can be avoided by simply upgrading to the latest TCP/IP patches + supplied by the vendor. In cases where the vendor has never + released patches (i.e., SunOS4 -- although folks with + a source license can patch it themselves) we have decided to + disable this feature.

    + +

    There are two ways of accomplishing this. One is the socket + option SO_LINGER. But as fate would have it, this + has never been implemented properly in most TCP/IP stacks. Even + on those stacks with a proper implementation (i.e., + Linux 2.0.31) this method proves to be more expensive (cputime) + than the next solution.

    + +

    For the most part, Apache implements this in a function + called lingering_close (in + http_main.c). The function looks roughly like + this:

    + +

    + void lingering_close (int s)
    + {
    + + char junk_buffer[2048];
    +
    + /* shutdown the sending side */
    + shutdown (s, 1);
    +
    + signal (SIGALRM, lingering_death);
    + alarm (30);
    +
    + for (;;) {
    + + select (s for reading, 2 second timeout);
    + if (error) break;
    + if (s is ready for reading) {
    + + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
    + + break;
    +
    + }
    + /* just toss away whatever is here */
    +
    + }
    +
    + }
    +
    + close (s);
    +
    + } +

    + +

    This naturally adds some expense at the end of a connection, + but it is required for a reliable implementation. As HTTP/1.1 + becomes more prevalent, and all connections are persistent, + this expense will be amortized over more requests. If you want + to play with fire and disable this feature you can define + NO_LINGCLOSE, but this is not recommended at all. + In particular, as HTTP/1.1 pipelined persistent connections + come into use lingering_close is an absolute + necessity (and + pipelined connections are faster, so you want to support + them).

    + + + +

    Scoreboard File

    + + + +

    Apache's parent and children communicate with each other + through something called the scoreboard. Ideally this should be + implemented in shared memory. For those operating systems that + we either have access to, or have been given detailed ports + for, it typically is implemented using shared memory. The rest + default to using an on-disk file. The on-disk file is not only + slow, but it is unreliable (and less featured). Peruse the + src/main/conf.h file for your architecture and + look for either USE_MMAP_SCOREBOARD or + USE_SHMGET_SCOREBOARD. Defining one of those two + (as well as their companions HAVE_MMAP and + HAVE_SHMGET respectively) enables the supplied + shared memory code. If your system has another type of shared + memory, edit the file src/main/http_main.c and add + the hooks necessary to use it in Apache. (Send us back a patch + too please.)

    + +
    Historical note: The Linux port of Apache didn't start to + use shared memory until version 1.2 of Apache. This oversight + resulted in really poor and unreliable behaviour of earlier + versions of Apache on Linux.
    + + + +

    DYNAMIC_MODULE_LIMIT

    + + + +

    If you have no intention of using dynamically loaded modules + (you probably don't if you're reading this and tuning your + server for every last ounce of performance) then you should add + -DDYNAMIC_MODULE_LIMIT=0 when building your + server. This will save RAM that's allocated only for supporting + dynamically loaded modules.

    + + + +
    top
    +
    +

    Appendix: Detailed Analysis of a Trace

    + + + +

    Here is a system call trace of Apache 2.0.38 with the worker MPM + on Solaris 8. This trace was collected using:

    + +

    + truss -l -p httpd_child_pid. +

    + +

    The -l option tells truss to log the ID of the + LWP (lightweight process--Solaris's form of kernel-level thread) + that invokes each system call.

    + +

    Other systems may have different system call tracing utilities + such as strace, ktrace, or par. + They all produce similar output.

    + +

    In this trace, a client has requested a 10KB static file + from the httpd. Traces of non-static requests or requests + with content negotiation look wildly different (and quite ugly + in some cases).

    + +
    /67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
    +/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
    + +

    In this trace, the listener thread is running within LWP #67.

    + +
    Note the lack of accept(2) serialization. On this + particular platform, the worker MPM uses an unserialized accept by + default unless it is listening on multiple ports.
    + +
    /65:    lwp_park(0x00000000, 0)                         = 0
    +/67:    lwp_unpark(65, 1)                               = 0
    + +

    Upon accepting the connection, the listener thread wakes up + a worker thread to do the request processing. In this trace, + the worker thread that handles the request is mapped to LWP #65.

    + +
    /65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
    + +

    In order to implement virtual hosts, Apache needs to know + the local socket address used to accept the connection. It + is possible to eliminate this call in many situations (such + as when there are no virtual hosts, or when + Listen directives + are used which do not have wildcard addresses). But + no effort has yet been made to do these optimizations.

    + +
    /65:    brk(0x002170E8)                                 = 0
    +/65:    brk(0x002190E8)                                 = 0
    + +

    The brk(2) calls allocate memory from the heap. + It is rare to see these in a system call trace, because the httpd + uses custom memory allocators (apr_pool and + apr_bucket_alloc) for most request processing. + In this trace, the httpd has just been started, so it must + call malloc(3) to get the blocks of raw memory + with which to create the custom memory allocators.

    + +
    /65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
    +/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
    +/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
    + +

    Next, the worker thread puts the connection to the client (file + descriptor 9) in non-blocking mode. The setsockopt(2) + and getsockopt(2) calls are a side-effect of how + Solaris's libc handles fcntl(2) on sockets.

    + +
    /65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
    + +

    The worker thread reads the request from the client.

    + +
    /65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
    +/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
    + +

    This httpd has been configured with Options FollowSymLinks + and AllowOverride None. Thus it doesn't need to + lstat(2) each directory in the path leading up to the + requested file, nor check for .htaccess files. + It simply calls stat(2) to verify that the file: + 1) exists, and 2) is a regular file, not a directory.

    + +
    /65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
    + +

    In this example, the httpd is able to send the HTTP response + header and the requested file with a single sendfilev(2) + system call. Sendfile semantics vary among operating systems. On some other + systems, it is necessary to do a write(2) or + writev(2) call to send the headers before calling + sendfile(2).

    + +
    /65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
    + +

    This write(2) call records the request in the + access log. Note that one thing missing from this trace is a + time(2) call. Unlike Apache 1.3, Apache 2.0 uses + gettimeofday(3) to look up the time. On some operating + systems, like Linux or Solaris, gettimeofday has an + optimized implementation that doesn't require as much overhead + as a typical system call.

    + +
    /65:    shutdown(9, 1, 1)                               = 0
    +/65:    poll(0xFAF7B980, 1, 2000)                       = 1
    +/65:    read(9, 0xFAF7BC20, 512)                        = 0
    +/65:    close(9)                                        = 0
    + +

    The worker thread does a lingering close of the connection.

    + +
    /65:    close(10)                                       = 0
    +/65:    lwp_park(0x00000000, 0)         (sleeping...)
    + +

    Finally the worker thread closes the file that it has just delivered + and blocks until the listener assigns it another connection.

    + +
    /67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
    + +

    Meanwhile, the listener thread is able to accept another connection + as soon as it has dispatched this connection to a worker thread (subject + to some flow-control logic in the worker MPM that throttles the listener + if all the available workers are busy). Though it isn't apparent from + this trace, the next accept(2) can (and usually does, under + high load conditions) occur in parallel with the worker thread's handling + of the just-accepted connection.

    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/perf-tuning.html.ko.euc-kr b/trunk/docs/manual/misc/perf-tuning.html.ko.euc-kr new file mode 100644 index 0000000000..35921b2ce2 --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.html.ko.euc-kr @@ -0,0 +1,976 @@ + + + +¾ÆÆÄÄ¡ ¼º´ÉÇâ»ó - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ ¼º´ÉÇâ»ó

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ¾ÆÆÄÄ¡ 2.0Àº ±â´É°ú Æ÷Æð¡´É¼º°ú ¼º´ÉÀÇ ±ÕÇüÀÌ ¸Âµµ·Ï + ¼³°èÇÑ ¹ü¿ë À¥¼­¹öÀÌ´Ù. º¥Ä¡¸¶Å© ±â·ÏÀ» ¼¼¿ì±âÀ§ÇØ ¼³°èÇÏÁö + ¾Ê¾ÒÁö¸¸ ¾ÆÆÄÄ¡ 2.0Àº ½ÇÁ¦ ¸¹Àº °æ¿ì ³ôÀº ¼º´ÉÀ» ³½´Ù.

    + +

    ¾ÆÆÄÄ¡ 1.3°ú ºñ±³Çؼ­ 2.0 ¹öÀüÀº 󸮷®°ú È®À强(scalability)À» + ³ôÀ̱âÀ§ÇØ ¸¹Àº ÃÖÀûÈ­¸¦ Çß´Ù. ±âº»°ªÀ¸·Î ´ëºÎºÐ ÃÖÀûÈ­ÇÑ + °ªÀ» »ç¿ëÇÑ´Ù. ±×·¯³ª ÄÄÆÄÀϽà ȤÀº ½ÇÇà½Ã ¼³Á¤ÀÌ ¼º´É¿¡ + Å« ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ 2.0ÀÇ ¼º´ÉÀ» Çâ»óÇϱâÀ§ÇØ + ¼­¹ö °ü¸®ÀÚ°¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Â ¿É¼ÇÀ» ¼³¸íÇÑ´Ù. ¾î¶² ¼³Á¤ + ¿É¼ÇÀº À¥¼­¹ö°¡ Çϵå¿þ¾î¿Í ¿î¿µÃ¼Á¦ÀÇ ±â´ÉÀ» ´õ Àß È°¿ëÇϵµ·Ï + ÇÏ´Â ¹Ý¸é, ¾î¶² ¿É¼ÇÀº ¼Óµµ¸¦ À§ÇØ ±â´ÉÀ» Èñ»ýÇÑ´Ù.

    + +
    + +
    top
    +
    +

    Çϵå¿þ¾î¿Í ¿î¿µÃ¼Á¦¿¡ ´ëÇؼ­

    + + + +

    À¥¼­¹ö ¼º´É¿¡ °¡Àå Å« ¿µÇâÀ» ÁÖ´Â °ÍÀº ¸Þ¸ð¸®´Ù. ½º¿ÒÀº + ¿äû´ç Áö¿¬½Ã°£À» »ç¿ëÀÚ°¡ "ÃæºÐÈ÷ ºü¸£´Ù°í" »ý°¢ÇÏÁö ¸øÇÏ°Ô + ´Ã¸®±â¶§¹®¿¡ À¥¼­¹ö´Â ½º¿ÒÀ» ÇÏ¸é ¾ÈµÈ´Ù. ´À·ÁÁö¸é »ç¿ëÀÚ´Â + Á¤ÁöÇÏ°í ´Ù½Ã Á¢¼ÓÇÏ¿© ºÎÇÏ°¡ °è¼Ó Áõ°¡ÇÑ´Ù. MaxClients Áö½Ã¾î¸¦ Á¶ÀýÇÏ¿© + À¥¼­¹ö°¡ ½º¿ÒÀ» ÇÒ Á¤µµ·Î ¸¹Àº ÀÚ½ÄÀ» ¸¸µéÁö¾Êµµ·Ï ÇØ¾ß + ÇÑ´Ù. ¹æ¹ýÀº °£´ÜÇÏ´Ù: top°ú °°Àº µµ±¸¿¡¼­ + ÇÁ·Î¼¼½º ¸ñ·ÏÀ» º¸°í ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½ºÀÇ Æò±Õ ¸Þ¸ð¸® »ç¿ë·®À» + ¾Ë¾Æ³½ÈÄ, Àüü »ç¿ë°¡´ÉÇÑ ¸Þ¸ð¸®¿¡¼­ ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀÌ »ç¿ëÇÒ + °ø°£À» »« °ª¿¡¼­ ³ª´«´Ù.

    + +

    ³ª¸ÓÁö´Â Æò¹üÇÏ´Ù: ÃæºÐÈ÷ ºü¸¥ CPU, ÃæºÐÈ÷ ºü¸¥ ³×Æ®¿÷Ä«µå, + ÃæºÐÈ÷ ºü¸¥ µð½ºÅ©, ¿©±â¼­ "ÃæºÐÈ÷ ºü¸¥"Àº ½ÇÇèÀ» Çؼ­ °áÁ¤ÇØ¾ß + ÇÑ´Ù.

    + +

    ¿î¿µÃ¼Á¦´Â º¸Åë °¢ÀÚ ¾Ë¾Æ¼­ ¼±ÅÃÇÒ ÀÏÀÌ´Ù. ±×·¯³ª ÀϹÝÀûÀ¸·Î + À¯¿ëÇÏ´Ù°í ÆǸíµÈ ¸î°¡Áö ÁöħÀÌ ÀÖ´Ù:

    + +
      +
    • +

      ¼±ÅÃÇÑ ¿î¿µÃ¼Á¦ÀÇ ÃֽŠ¾ÈÁ¤ ¹öÀü°ú ÆÐÄ¡¸¦ ½ÇÇàÇÑ´Ù. + ¸¹Àº ¿î¿µÃ¼Á¦ Á¦ÀÛ»ç´Â ÃÖ±Ù TCP ½ºÅðú ¾²·¹µå ¶óÀ̺귯¸®¿¡ + ¸¹Àº ¼ÓµµÇâ»óÀ» Çß´Ù.

      +
    • + +
    • +

      ¿î¿µÃ¼Á¦°¡ sendfile(2) ½Ã½ºÅÛÈ£ÃâÀ» + Áö¿øÇÑ´Ù¸é, À̸¦ »ç¿ëÇϱâÀ§ÇÑ ¹öÀüÀ̳ª ÆÐÄ¡¸¦ ¼³Ä¡ÇÏ¿´´ÂÁö + È®ÀÎÇÑ´Ù. (¿¹¸¦ µé¾î, ¸®´ª½º¶ó¸é 2.4 ÀÌ»ó ¹öÀüÀ» ¶æÇÑ´Ù. + Solaris 8 Ãʱ⠹öÀüÀº ÆÐÄ¡°¡ ÇÊ¿äÇÏ´Ù.) Áö¿øÇÏ´Â ½Ã½ºÅÛÀ̶ó¸é + ¾ÆÆÄÄ¡ 2´Â sendfileÀ» »ç¿ëÇÏ¿© CPU¸¦ ´ú + »ç¿ëÇϸç Á¤Àû ÆÄÀÏÀ» ´õ »¡¸® Àü¼ÛÇÒ ¼ö ÀÕ´Ù.

      +
    • +
    + +
    top
    +
    +

    ½ÇÇà½Ã ¼³Á¤¿¡ ´ëÇؼ­

    + + + + + +

    HostnameLookups¿Í DNS¿¡ ´ëÇØ °í·ÁÇÒ Á¡µé

    + + + +

    ¾ÆÆÄÄ¡ 1.3 ÀÌÀü¿¡ HostnameLookupsÀÇ ±âº»°ªÀº + OnÀÌ¿´´Ù. ¿äûÀ» ¸¶Ä¡±âÀü¿¡ DNS °Ë»öÀÌ ³¡³ª¾ß + ÇϹǷΠ¿äû¸¶´Ù Áö¿¬ÀÌ »ý°å´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ÀÌ ¼³Á¤ÀÇ + ±âº»°ªÀÌ Off·Î º¯°æµÇ¾ú´Ù. ·Î±×ÆÄÀÏÀÇ ÁÖ¼Ò¸¦ + È£½ºÆ®¸íÀ¸·Î º¯È¯ÇÏ·Á¸é ¿©·¯ ·Î±×ó¸® ÇÁ·Î±×·¥Áß ÇϳªÀÎ, + ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔµÈ logresolve + ÇÁ·Î±×·¥À» »ç¿ëÇ϶ó.

    + +

    ·Î±×ó¸® ÀÛ¾÷ÀÌ ¼­¹ö ¼º´É¿¡ ¾Ç¿µÇâÀ» ¹ÌÄ¡¹Ç·Î ½ÇÁ¦ + »ç¿ëÇÏ´Â À¥¼­¹ö°¡ ¾Æ´Ñ ´Ù¸¥ ÄÄÇ»ÅÍ¿¡¼­ ·Î±×ÆÄÀÏÀ» ÈÄó¸®Çϱæ + ¹Ù¶õ´Ù.

    + +

    Allow + from domainÀ̳ª Deny from domain + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù¸é (Áï, IP ÁÖ¼Ò°¡ ¾Æ´Ñ È£½ºÆ®¸íÀ̳ª µµ¸ÞÀθíÀ» + »ç¿ëÇÑ´Ù¸é) ºÎµæÀÌ Áߺ¹-¿ª DNS °Ë»öÀ» (¿ª°Ë»öÀ» ÇÑÈÄ ¾ÇÀÇ·Î + º¯°æµÇ¾ú´ÂÁö È®ÀÎÇϱâÀ§ÇØ ´Ù½Ã °Ë»ö) ÇØ¾ß ÇÑ´Ù. ±×·¯¹Ç·Î + ¼º´ÉÀ» ³ôÀ̱âÀ§ÇØ ÀÌ·± Áö½Ã¾î¿¡´Â °¡´ÉÇϸé À̸§´ë½Å IP + ÁÖ¼Ò¸¦ »ç¿ëÇÑ´Ù.

    + +

    <Location /server-status> ¼½¼Ç µîÀ¸·Î + Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ Á¦ÇÑÇÒ ¼ö ÀÖÀ½À» ±â¾ïÇ϶ó. ÀÌ °æ¿ì + Á¶°Ç¿¡ ¸Â´Â ¿äû¿¡¸¸ DNS Á¶È¸¸¦ ÇÑ´Ù. ´ÙÀ½Àº + .html°ú .cgi ÆÄÀϸ¸ DNS °Ë»öÀ» + ÇÏ´Â ¿¹Á¦´Ù:

    + +

    + HostnameLookups off
    + <Files ~ "\.(html|cgi)$">
    + + HostnameLookups on
    +
    + </Files> +

    + +

    ±×·¯³ª CGI¿¡¼­ DNS¸íÀÌ ÇÊ¿äÇÒ »ÓÀ̶ó¸é, ÇÊ¿äÇÑ Æ¯Á¤ + CGI¿¡¼­¸¸ gethostbyname È£ÃâÀ» Çϵµ·Ï °í·ÁÇغ¼ + ¼ö ÀÖ´Ù.

    + + + +

    FollowSymLinks¿Í SymLinksIfOwnerMatch

    + + + +

    URL °ø°£¿¡¼­ Options FollowSymLinks¸¦ + »ç¿ëÇÏÁö¾Ê°í Options SymLinksIfOwnerMatch¸¦ + »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â ½Éº¼¸µÅ©¸¦ °Ë»çÇϱâÀ§ÇØ ½Ã½ºÅÛÈ£ÃâÀ» + Çѹø ´õ ÇØ¾ß ÇÑ´Ù. ÆÄÀϸíÀÇ °¢ ºÎºÐ¸¶´Ù Çѹø¾¿ ´õ È£ÃâÀ» + ÇÑ´Ù. ¿¹¸¦ µé¾î, ¼³Á¤ÀÌ ´ÙÀ½°ú °°°í:

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + Options SymLinksIfOwnerMatch
    +
    + </Directory> +

    + +

    /index.html URI¿¡ ´ëÇÑ ¿äûÀÌ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. + ±×·¯¸é ¾ÆÆÄÄ¡´Â /www, /www/htdocs, + /www/htdocs/index.html °¢°¢¿¡ ´ëÇØ + lstat(2)¸¦ È£ÃâÇÑ´Ù. lstats + °á°ú¸¦ ij½ÌÇÏÁö ¾Ê±â¶§¹®¿¡ ¿äûÀÌ µé¾î¿Ã ¶§¸¶´Ù ¸Å¹ø °°Àº + ÀÛ¾÷À» ÇÑ´Ù. ÁøÂ¥ ½Éº¼¸µÅ© º¸¾È °Ë»ç¸¦ ¿øÇÑ´Ù¸é ´ÙÀ½°ú + °°ÀÌ ÇÒ ¼ö ÀÖ´Ù:

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + Options FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /www/htdocs>
    + + Options -FollowSymLinks +SymLinksIfOwnerMatch
    +
    + </Directory> +

    + +

    ÀÌ °æ¿ì ÃÖ¼ÒÇÑ DocumentRoot °æ·Î´Â °Ë»çÇÏÁö + ¾Ê´Â´Ù. DocumentRoot ¹Û¿¡ ÀÖ´Â °æ·Î·Î Alias³ª RewriteRuleÀ» »ç¿ëÇÑ + °æ¿ì¿¡µµ À§¿Í ºñ½ÁÇÑ ¼½¼ÇÀÌ ÇÊ¿äÇÏ´Ù. ½Éº¼¸µÅ© º¸¾ÈÀ» + °í·ÁÇÏÁö ¾Ê°í ÃÖ°íÀÇ ¼º´ÉÀ» ¾òÀ¸·Á¸é, + FollowSymLinks¸¦ ¼³Á¤ÇÏ°í, + SymLinksIfOwnerMatch´Â Àý´ë·Î ¾ÈµÈ´Ù.

    + + + +

    AllowOverride

    + + + +

    URL °ø°£¿¡¼­ overrides¸¦ Çã¿ëÇÑ´Ù¸é (º¸Åë + .htaccess ÆÄÀÏ) ¾ÆÆÄÄ¡´Â ÆÄÀϸíÀÇ °¢ ºÎºÐ¸¶´Ù + .htaccess¸¦ ¿­±æ ½ÃµµÇÑ´Ù. ¿¹¸¦ µé¾î,

    + +

    + DocumentRoot /www/htdocs
    + <Directory />
    + + AllowOverride all
    +
    + </Directory> +

    + +

    /index.html URI¿¡ ´ëÇÑ ¿äûÀÌ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. + ¾ÆÆÄÄ¡´Â /.htaccess, /www/.htaccess, + /www/htdocs/.htaccess¸¦ ¿­·Á°í ½ÃµµÇÑ´Ù. + ÇØ°áÃ¥Àº ¾ÕÀÇ Options FollowSymLinks °æ¿ì¿Í + ºñ½ÁÇÏ´Ù. ÃÖ°íÀÇ ¼º´ÉÀ» ¾òÀ¸·Á¸é ÆÄÀϽýºÅÛ¿¡ ´ëÇؼ­ Ç×»ó + AllowOverride NoneÀ» »ç¿ëÇÑ´Ù.

    + + + +

    ³»¿ëÇù»ó

    + + + +

    °¡´ÉÇÏ°í ÁøÂ¥ Á¶±ÝÀÇ ¼º´ÉÇâ»ó¿¡µµ °ü½ÉÀÌ ÀÖ´Ù¸é ³»¿ëÇù»óÀ» + ¸·´Â´Ù. ½ÇÁ¦·Î Çù»óÀÇ À̵æÀº ¼º´ÉÀúÇϺ¸´Ù ÀÛ´Ù. ¼­¹ö¸¦ + ºü¸£°Ô ÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½°ú °°ÀÌ ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ´Â ´ë½Å:

    + +

    + DirectoryIndex index +

    + +

    ¿ÏÀüÇÑ ¸ñ·ÏÀ» »ç¿ëÇÑ´Ù:

    + +

    + DirectoryIndex index.cgi index.pl index.shtml index.html +

    + +

    °¡Àå ÈçÇÑ °ÍÀ» ¾Õ¿¡ µÐ´Ù.

    + +

    ¶Ç, µð·ºÅ丮¿¡¼­ ÆÄÀϵéÀ» ã´Â MultiViews + º¸´Ù´Â, ÇÑ ÆÄÀϸ¸ ÀÐÀ¸¸é ÇÊ¿äÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Â + type-map ÆÄÀÏÀ» Á÷Á¢ ¸¸µå´Â °ÍÀÌ ´õ ºü¸§À» + ¸í½ÉÇ϶ó.

    + +

    »çÀÌÆ®¿¡ ³»¿ëÇù»óÀÌ ÇÊ¿äÇÏ´Ù¸é Çù»óÀ» À§ÇØ Options + MultiViews Áö½Ã¾î¸¦ »ç¿ëÇϱ⺸´Ù type-map + ÆÄÀÏÀ» °í·ÁÇ϶ó. Çù»ó¹æ¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í°ú + type-map ÆÄÀÏÀ» ¸¸µå´Â ¹æ¹ýÀº ³»¿ëÇù»ó ¹®¼­¸¦ Âü°íÇ϶ó.

    + + + +

    ¸Þ¸ð¸®´ëÀÀ (memory-mapping)

    + + + +

    ¿¹¸¦ µé¾î, server-side-include¸¦ ó¸®ÇÏ´Â µî ¾ÆÆÄÄ¡ + 2.0ÀÌ Àü¼ÛÇÒ ÆÄÀÏÀ» ÀÐÀ»¶§ ¿î¿µÃ¼Á¦°¡ mmap(2) + µîÀ» Áö¿øÇÑ´Ù¸é ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÑ´Ù.

    + +

    ¿©·¯ Ç÷¡Æû¿¡¼­ ¸Þ¸ð¸®´ëÀÀÀ» ¼º´ÉÀ» Çâ»óÇÑ´Ù. ±×·¯³ª + ¸Þ¸ð¸®´ëÀÀÀÌ ¼­¹öÀÇ ¼º´ÉÀ» ¶³¾îÆ®¸®°í ½ÉÁö¾î ¾ÈÁ¤¼ºÀ» + ÇØÄ¡´Â °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    • +

      ¾î¶² ¿î¿µÃ¼Á¦¿¡¼­ mmapÀº CPU °³¼ö°¡ + ¸¹¾ÆÁú¶§ read(2) ¸¸Å­ È®À强ÀÌ ÁÁÁö ¾Ê´Ù. + ¿¹¸¦ µé¾î, ´ÙÁßÇÁ·Î¼¼¼­ Solaris ¼­¹ö¿¡¼­ ¾ÆÆÄÄ¡ 2.0Àº + Á¾Á¾ mmapÀ» »ç¿ëÇÏÁö ¾ÊÀ»¶§ ¼­¹ö°¡ ó¸®ÇÑ + ÆÄÀÏÀ» ´õ »¡¸® Àü¼ÛÇÑ´Ù.

      +
    • + +
    • +

      NFS ¸¶¿îÆ®ÇÑ ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÏ´Â + µµÁß¿¡ ´Ù¸¥ NFS Ŭ¶óÀ̾ðÆ®¿¡ ÀÖ´Â ÇÁ·Î¼¼½º°¡ ÆÄÀÏÀ» + Áö¿ì°Å³ª ÆÄÀÏÅ©±â¸¦ ÁÙÀ̸é, À¥¼­¹ö ÇÁ·Î¼¼½º°¡ ´ÙÀ½ + ¹ø¿¡ ¸Þ¸ð¸®´ëÀÀÇÑ ÆÄÀϳ»¿ëÀ» ÀÐÀ»¶§ bus error°¡ ¹ß»ýÇÒ + ¼ö ÀÖ´Ù.

      +
    • +
    + +

    À§ÀÇ Á¶°Ç¿¡ ÇØ´çÇϸé Àü¼ÛÇÏ´Â ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÏÁö + ¾Êµµ·Ï EnableMMAP off¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. (ÁÖÀÇ: + ÀÌ Áö½Ã¾î´Â µð·ºÅ丮º°·Î º¯°æÇÒ ¼ö ÀÖ´Ù.)

    + + + +

    Sendfile

    + + + +

    ¾ÆÆÄÄ¡´Â ¿î¿µÃ¼Á¦°¡ sendfile(2)À» Áö¿øÇϸé + Ä¿³Î sendfileÀ» »ç¿ëÇÏ¿© -- ¿¹¸¦ µé¾î, Á¤Àû ÆÄÀÏÀ» ¼­ºñ½ºÇÒ¶§ + -- Àü¼ÛÇÒ ÆÄÀÏÀ» Á÷Á¢ ÀÐÁö¾ÊÀ» ¼ö ÀÖ´Ù.

    + +

    ¿©·¯ Ç÷¡Æû¿¡¼­ sendfileÀ» »ç¿ëÇϸé read¿Í send¸¦ µû·Î + ÇÒ ÇÊ¿ä°¡ ¾ø¾î¼­ »¡¶óÁø´Ù. ±×·¯³ª sendfileÀ» »ç¿ëÇϸé + À¥¼­¹öÀÇ ¾ÈÁ¤¼ºÀ» ÇØÄ¡°ÔµÇ´Â °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    • +

      sendfile Áö¿øÀÌ À߸øµÇ¾ú°í ÄÄÆÄÀÏ ½Ã½ºÅÛÀÌ ÀÌÁ¡À» + ¹ß°ßÇÏÁö ¸øÇÏ´Â Ç÷¡ÆûÀÌ ÀÖ´Ù. ƯÈ÷ ´Ù¸¥ ÄÄÇ»ÅÍ¿¡¼­ + ½ÇÇàÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ¿© sendfile Áö¿øÀÌ À߸øµÈ ÄÄÇ»ÅÍ·Î + °¡Á®¿Â °æ¿ì¿¡ °¡´ÉÇÏ´Ù.

      +
    • +
    • +

      Ä¿³ÎÀº ÀÚ½ÅÀÇ Ä³½¬¸¦ »ç¿ëÇÏ¿© NFS·Î ¸¶¿îÆ®ÇÑ ÆÄÀÏÀ» + ¾ÈÁ¤ÀûÀ¸·Î ¼­ºñ½ºÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ÀÖ´Ù.

      +
    • +
    + +

    À§ÀÇ Á¶°Ç¿¡ ÇØ´çÇϸé ÆÄÀÏÀ» sendfile Àü¼ÛÇÏÁö ¾Êµµ·Ï + EnableSendfile off¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. (ÁÖÀÇ: + ÀÌ Áö½Ã¾î´Â µð·ºÅ丮º°·Î º¯°æÇÒ ¼ö ÀÖ´Ù.)

    + + + +

    ÇÁ·Î¼¼½º »ý¼º

    + + + +

    ¾ÆÆÄÄ¡ 1.3 ÀÌÀü¿¡´Â MinSpareServers, MaxSpareServers, StartServers ¼³Á¤ÀÌ ¸ðµÎ + º¥Ä¡¸¶Å© °á°ú¿¡ Å« ¿µÇâÀ» ¹ÌÃÆ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡´Â ÀÛ¾÷À» + ¼­ºñ½ºÇϱâÀ§ÇØ ÃæºÐÇÑ Àڽļö¿¡ ´Ù´Ù¸¦ ¶§±îÁö "µµ´Þ" ±â°£ÀÌ + ÇÊ¿äÇß´Ù. óÀ½ StartServers°³ ÀÚ½ÄÀ» + ¸¸µçÈÄ, MinSpareServers + ¼³Á¤°ª±îÁö ÃÊ´ç ÀÚ½ÄÀ» Çϳª¾¿ ¸¸µé¾ú´Ù. ±×·¡¼­ StartServers ±âº»°ªÀÌ + 5ÀÎ ¼­¹ö¿¡ Ŭ¶óÀ̾ðÆ® 100°³°¡ µ¿½Ã¿¡ Á¢¼ÓÇϸé + ºÎÇϸ¦ ó¸®Çϱ⿡ ÃæºÐÇÑ ÀÚ½ÄÀ» ¸¸µé±â±îÁö 95ÃÊ°¡ °É·È´Ù. + ÀÚÁÖ Àç½ÃÀÛÇÏÁö ¾Ê´Â ½ÇÁ¦ ¼­¹ö¿¡¼­´Â Àß µ¿ÀÛÇÏÁö¸¸, 10ºÐ°£¸¸ + ½ÇÇàÇÏ´Â º¥Ä¡¸¶Å© °á°ú´Â ¸Å¿ì ³ª»Ú°Ô ³ª¿Â´Ù.

    + +

    ÃÊ´ç ÇÑ°³ ±ÔÄ¢Àº ÀÚ½ÄÀ» »õ·Î ½ÃÀÛÇϸ鼭 ¼­¹ö¿¡ ¹«¸®¸¦ + ÁÖÁö ¾ÊÀ¸·Á°í Á¤Çß´Ù. ÄÄÇ»ÅÍ°¡ ÀÚ½ÄÀ» ½ÃÀÛÇÏ´À¶ó ¹Ù»Ú¸é + ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ÀÌ ±ÔÄ¢ÀÌ ¾ÆÆÄÄ¡ÀÇ Ã¼°¨ + ¼º´É¿¡ ¾Ç¿µÇâÀ» ÁÖ¾î º¯°æÇÏ¿´´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ÃÊ´ç ÇÑ°³ + ±ÔÄ¢Àº ¿ÏÈ­µÇ¾ú´Ù. ÄÚµå´Â ÀÚ½Ä ÇÑ°³¸¦ ¸¸µé°í, 1ÃÊ ½¬°í, + µÎ°³¸¦ ¸¸µé°í, 1ÃÊ ½¬°í, ³×°³¸¦ ¸¸µé°í, ÀÌ·± ½ÄÀ¸·Î ÃÊ´ç + ÀÚ½ÄÀ» 32°³ ¸¸µé¶§±îÁö Áö¼ö·Î Áõ°¡ÇÑ´Ù. Àڽļö°¡ MinSpareServers ¼³Á¤¿¡ ´Ù´Ù¸£¸é + Áõ°¡¸¦ Áß´ÜÇÑ´Ù.

    + +

    ÀÌ °æ¿ì ¹ÝÀÀ¼Óµµ°¡ »¡¶óÁ®¼­ MinSpareServers, MaxSpareServers, StartServers¸¦ °ÅÀÇ ¼³Á¤ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ÀÏÃÊ¿¡ + ÀÚ½ÄÀ» 4°³ ÀÌ»ó »ý¼ºÇϸé ErrorLog¿¡ ±â·ÏÇÑ´Ù. ÀÌ·± ¿À·ù¹®ÀÌ + ¸¹ÀÌ º¸À̸é ÀÌ ¼³Á¤µéÀ» Á¶ÀýÇÏ±æ ¹Ù¶õ´Ù. + mod_status °á°ú°¡ µµ¿òÀÌ µÉ °ÍÀÌ´Ù.

    + +

    ÇÁ·Î¼¼½º »ý¼º°ú °ü·ÃÇÏ¿© MaxRequestsPerChild ¼³Á¤Àº + ÇÁ·Î¼¼½º¸¦ Á¾·áÇÑ´Ù. ±âº»°ªÀº ÀڽĴç ó¸®ÇÒ ¿äû¼ö¿¡ Á¦ÇÑÀÌ + ¾ø´Ù´Â 0ÀÌ´Ù. ÇöÀç ¼³Á¤ÀÌ 30°ú + °°ÀÌ ¸Å¿ì ÀÛÀº °ªÀ¸·Î ¼³Á¤µÇÀÖ´Ù¸é, °ªÀ» »ó´çÈ÷ ³ôÈú ÇÊ¿ä°¡ + ÀÖ´Ù. SunOS³ª ¿À·¡µÈ Solaris ¹öÀüÀ» »ç¿ëÇÑ´Ù¸é, ¸Þ¸ð¸®À¯Ã⶧¹®¿¡ + ÀÌ °ªÀ» 10000 Á¤µµ·Î ¼³Á¤Ç϶ó.

    + +

    ¿¬°áÀ¯Áö(keep-alive)¸¦ »ç¿ëÇÑ´Ù¸é ÀڽĵéÀº ÀÌ¹Ì ¿­¸° + ¿¬°á¿¡¼­ Ãß°¡ ¿äûÀ» ±â´Ù¸®¸ç ¾Æ¹«°Íµµ ÇÏÁö¾Ê±â¶§¹®¿¡ °è¼Ó + ¹Ù»Ú´Ù. KeepAliveTimeoutÀÇ + ±âº»°ª 15 ÃÊ´Â ÀÌ·± Çö»óÀ» ÃÖ¼ÒÈ­ÇÑ´Ù. ³×Æ®¿÷ + ´ë¿ªÆø°ú ¼­¹ö ÀÚ¿ø °£ÀÇ ±ÕÇüÀÌ ¸Â°Ô ¼³Á¤ÇÑ´Ù. + ¿¬°áÀ¯ÁöÀÇ ´ëºÎºÐÀÇ ÀÌÁ¡ÀÌ »ç¶óÁö±â¶§¹®¿¡ ¾î¶² °æ¿ì¿¡µµ + ÀÌ °ªÀ» 60 ÃÊ ÀÌ»óÀ¸·Î ¿Ã¸®Áö ¸¶¶ó.

    + + + +
    top
    +
    +

    ÄÄÆÄÀϽà ¼³Á¤¿¡ ´ëÇؼ­

    + + + +

    MPM ¼±ÅÃ

    + + + +

    ¾ÆÆÄÄ¡ 2.x´Â ´ÙÁß󸮸ðµâ + (MPMs)À̶ó´Â ±³Ã¼ÇÒ ¼ö ÀÖ´Â µ¿±âÈ­ ¸ðµ¨À» Áö¿øÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÒ¶§ MPMÀ» ¼±ÅÃÇØ¾ß ÇÑ´Ù. beos, + mpm_netware, mpmt_os2, + mpm_winnt¿Í °°ÀÌ Æ¯Á¤ Ç÷¡Æû¿¡¼­¸¸ »ç¿ëÇÒ + ¼ö ÀÖ´Â MPMµµ ÀÖ´Ù. ÀϹÝÀûÀÎ À¯´Ð½º·ù ½Ã½ºÅÛÀº ¿©·¯ MPM + Áß¿¡ Çϳª¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. À¥¼­¹öÀÇ ¼Óµµ¿Í + È®À强(scalability)Àº ¾î¶² MPMÀ» ¼±ÅÃÇ߳Ŀ¡ ´Þ·È´Ù:

    + +
      + +
    • worker MPMÀº ¿©·¯ ÀÚ½Ä ÇÁ·Î¼¼½º°¡ + °¢°¢ ¿©·¯ ¾²·¹µå¸¦ »ç¿ëÇÑ´Ù. °¢ ¾²·¹µå´Â Çѹø¿¡ ÇÑ ¿¬°áÀ» + ´ã´çÇÑ´Ù. ÀϹÝÀûÀ¸·Î worker´Â prefork MPM º¸´Ù ÀûÀº + ¸Þ¸ð¸®¸¦ »ç¿ëÇϹǷΠÅë½Å·®ÀÌ ¸¹Àº ¼­¹ö¿¡ ÀûÀýÇÏ´Ù.
    • + +
    • prefork MPMÀº ¾²·¹µå°¡ ÇÑ°³ÀÎ ÀÚ½Ä + ÇÁ·Î¼¼½º¸¦ ¿©·¯°³ »ç¿ëÇÑ´Ù. °¢ ÇÁ·Î¼¼½º´Â Çѹø¿¡ ÇÑ + ¿¬°áÀ» ´ã´çÇÑ´Ù. ¿©·¯ ½Ã½ºÅÛ¿¡¼­ preforkÀÇ ¼Óµµ´Â worker¿Í + ºñ½ÁÇÏÁö¸¸, ´õ ¸¹Àº ¸Þ¸ð¸®¸¦ »ç¿ëÇÑ´Ù. ´ÙÀ½°ú °°Àº »óȲ¿¡¼­ + ¾²·¹µå¸¦ »ç¿ëÇÏÁö ¾Ê´Â prefork ¹æ½ÄÀÌ worker¿¡ ºñÇØ + ÀÌÁ¡À» °¡Áø´Ù: ¾²·¹µå¿¡ ¾ÈÀüÇÏÁö (thread-safe) ¾ÊÀº + Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» »ç¿ëÇÒ ¼ö ÀÖ°í, ¾²·¹µå µð¹ö±ë Áö¿øÀÌ + ºó¾àÇÑ Ç÷¡Æû¿¡¼­ ½±°Ô µð¹ö±ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    + +

    ÀÌ MPMµé°ú ´Ù¸¥ MPM¿¡ ´ëÇØ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â MPM ¹®¼­¸¦ Âü°íÇÏ±æ ¹Ù¶õ´Ù.

    + + + +

    ¸ðµâ

    + + + +

    ¸Þ¸ð¸® »ç¿ë·®ÀÌ ¼º´É¿¡¼­ °¡Àå Áß¿äÇÑ ¿äÀÎÀ̱⶧¹®¿¡ + ½ÇÁ¦·Î »ç¿ëÇÏÁö ¾Ê´Â ¸ðµâÀ» Á¦°ÅÇغ¸ÀÚ. ¸ðµâÀ» DSO·Î ÄÄÆÄÀÏÇß´Ù¸é °£´ÜÈ÷ ±× + ¸ðµâ¿¡ ´ëÇÑ LoadModule Áö½Ã¾î¸¦ ÁÖ¼®Ã³¸®Çϸé + µÈ´Ù. ±×·¡¼­ ¸ðµâÀ» Á¦°ÅÇÏ°í ½ÇÇàÇÏ¿© »çÀÌÆ®°¡ ¸ðµâ¾øÀ̵µ + Á¤»óÀûÀ¸·Î µ¿ÀÛÇÏ´ÂÁö »ìÆ캼 ¼ö ÀÖ´Ù.

    + +

    ¹Ý´ë·Î ¸ðµâÀÌ ¾ÆÆÄÄ¡ ½ÇÇàÆÄÀÏ¿¡ Á¤ÀûÀ¸·Î ¸µÅ©µÇÀÖ´Ù¸é + ¿øÇÏÁö ¾Ê´Â ¸ðµâÀ» Á¦°ÅÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ ÀçÄÄÆÄÀÏÇØ¾ß + ÇÑ´Ù.

    + +

    ¿©±â¼­ ´ç¿¬È÷ ¾î¶² ¸ðµâÀ» »ç¿ëÇÏ°í »ç¿ëÇÏÁö ¸»Áö + Àǹ®ÀÌ »ý±ä´Ù. Á¤´äÀº À¥»çÀÌÆ®¸¶´Ù ´Ù¸£´Ù. ±×·¯³ª ¾Æ¸¶µµ + ÃÖ¼ÒÇÑ mod_mime, + mod_dir, mod_log_config + ¸ðµâÀº »ç¿ëÇÒ °ÍÀÌ´Ù. ¹°·Ð À¥»çÀÌÆ®¿¡ ·Î±×ÆÄÀÏÀÌ ÇÊ¿ä¾ø´Ù¸é + mod_log_config´Â ¾ø¾îµµ µÈ´Ù. ±×·¯³ª ÃßõÇÏÁö + ¾Ê´Â´Ù.

    + + + +

    Atomic ¸í·É

    + + + +

    mod_cache °°Àº ¸ðµâ°ú ÃÖ±Ù °³¹ßÁßÀÎ + worker MPMÀº APRÀÇ atomic API¸¦ »ç¿ëÇÑ´Ù. ÀÌ API´Â °æ·®±Þ + ¾²·¹µå µ¿±âÈ­¸¦ À§ÇÒ atomic ¸í·ÉÀ» Á¦°øÇÑ´Ù.

    + +

    ±âº»ÀûÀ¸·Î APRÀº °¢ ¿î¿µÃ¼Á¦/CPU Ç÷¡Æû¿¡¼­ °¡Àå È¿À²ÀûÀÎ + ¹æ¹ýÀ» »ç¿ëÇÏ¿© ÀÌ ¸í·ÉÀ» ±¸ÇöÇÑ´Ù. ¿¹¸¦ µé¾î, ¿©·¯ ÃֽŠ+ CPU¿¡´Â Çϵå¿þ¾î·Î atomic compare-and-swap (CAS) ¿¬»êÀ» + ÇÏ´Â ¸í·É¾î°¡ ÀÖ´Ù. ±×·¯³ª ¾î¶² Ç÷¡Æû¿¡¼­ APRÀº ÀÌ·± + ¸í·É¾î°¡ ¾ø´Â ¿À·¡µÈ CPU¿Í ȣȯ¼ºÀ» À§ÇØ ´õ ´À¸° mutex±â¹Ý + ±¸ÇöÀ» ±âº»ÀûÀ¸·Î »ç¿ëÇÑ´Ù. ÀÌ·± Ç÷¡Æû¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÒ¶§ ¾ÆÆÄÄ¡¸¦ ÃֽŠCPU¿¡¼­¸¸ ½ÇÇàÇÒ °èȹÀ̶ó¸é, + ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÒ¶§ --enable-nonportable-atomics + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ´õ ºü¸¥ atomic ±¸ÇöÀ» ¼±ÅÃÇÒ ¼ö ÀÖ´Ù:

    + +

    + ./buildconf
    + ./configure --with-mpm=worker --enable-nonportable-atomics=yes +

    + +

    --enable-nonportable-atomics ¿É¼ÇÀº ´ÙÀ½°ú + °°Àº Ç÷¡Æû¿¡ ¿µÇâÀÌ ÀÖ´Ù:

    + +
      + +
    • SPARC¿¡¼­ Solaris
      + ±âº»ÀûÀ¸·Î APRÀº Solaris/SPARC¿¡¼­ mutex±â¹Ý atomicÀ» + »ç¿ëÇÑ´Ù. ±×·¯³ª ±¸¼ºÇÒ¶§ + --enable-nonportable-atomics¸¦ »ç¿ëÇϸé + APRÀº ºü¸¥ Çϵå¿þ¾î compare-and-swapÀ» À§ÇÑ SPARC + v8plus ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé atomic + ¸í·ÉÀÌ ´õ È¿À²ÀûÀÌÁö¸¸ (CPU¸¦ ´ú »ç¿ëÇÏ°í ´õ ³ôÀº + µ¿±âÈ­°¡ °¡´ÉÇÏ´Ù), ÄÄÆÄÀÏÇÑ ½ÇÇàÆÄÀÏÀº UltraSPARC + Ĩ¿¡¼­¸¸ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. +
    • + +
    • Linux on x86
      + ±âº»ÀûÀ¸·Î APRÀº ¸®´ª½º¿¡¼­ mutex±â¹Ý atomicÀ» + »ç¿ëÇÑ´Ù. ±×·¯³ª ±¸¼ºÇÒ¶§ + --enable-nonportable-atomics¸¦ »ç¿ëÇϸé + APRÀº ºü¸¥ Çϵå¿þ¾î compare-and-swapÀ» À§ÇÑ 486 + ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. ´õ È¿À²ÀûÀÎ atomic ¸í·ÉÀÌ °¡´ÉÇÏÁö¸¸, + ÄÄÆÄÀÏÇÑ ½ÇÇàÆÄÀÏÀº 486 ÀÌ»ó Ĩ¿¡¼­¸¸ (386Àº ¾ÈµÈ´Ù) + ½ÇÇàÇÒ ¼ö ÀÖ´Ù. +
    • + +
    + + + +

    mod_status¿Í ExtendedStatus On

    + + + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ¶§ mod_status¸¦ Æ÷ÇÔÇÏ°í + ½ÇÇàÇÒ¶§ ExtendedStatus OnÀ» ¼³Á¤ÇÏ¸é ¾ÆÆÄÄ¡´Â + ¿äûÀ» ¹ÞÀ»¶§¸¶´Ù gettimeofday(2)(ȤÀº ¿î¿µÃ¼Á¦¿¡ + µû¶ó times(2))¸¦ µÎ¹ø È£ÃâÇÏ°í (1.3 ÀÌÀü¿¡´Â) + time(2)µµ Ãß°¡·Î ¿©·¯¹ø È£ÃâÇÑ´Ù. »óÅ º¸°í¼­¿¡ + µ¿À۽ð£ÀÌ ÇÊ¿äÇϱ⠶§¹®ÀÌ´Ù. ÃÖ»óÀÇ ¼º´ÉÀ» ¾òÀ¸·Á¸é + (±âº»°ªÀÎ) ExtendedStatus off¸¦ ¼³Á¤ÇÑ´Ù.

    + + + +

    accept Á÷·ÄÈ­ - ¿©·¯ ¼ÒÄÏ

    + + + +

    ÁÖÀÇ:

    +

    ¾Æ·¡ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» + ´ã°í ÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ + »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    +
    + +

    À¯´Ð½º ¼ÒÄÏ APIÀÇ ´ÜÁ¡À» ¼³¸íÇÑ´Ù. À¥¼­¹ö°¡ ¿©·¯ Æ÷Æ® + ȤÀº ¿©·¯ ÁÖ¼Ò¸¦ ±â´Ù¸®±âÀ§ÇØ ¿©·¯ ListenÀ» »ç¿ëÇÑ´Ù°í °¡Á¤ÇÏÀÚ. + ¿¬°áÀÌ °¡´ÉÇÑÁö °¢ ¼ÒÄÏÀ» °Ë»çÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â + select(2)¸¦ »ç¿ëÇÑ´Ù. select(2)´Â + ¼ÒÄÏ¿¡ ±â´Ù¸®°í ÀÖ´Â ¿¬°áÀÌ ¾ø´ÂÁö ȤÀº ÃÖ¼ÒÇÑ + ÇÑ°³ ÀÖ´ÂÁö ¾Ë·ÁÁØ´Ù. ¾ÆÆÄÄ¡¿¡´Â ¿©·¯ ÀÚ½ÄÀÌ ÀÖ°í, + ½¬°í ÀÖ´Â ¸ðµç ÀÚ½ÄÀº µ¿½Ã¿¡ »õ·Î¿î ¿¬°áÀ» °Ë»çÇÑ´Ù. ¿ø·¡ + ±¸ÇöÀº ´ÙÀ½°ú ºñ½ÁÇÏ´Ù (ÀÌ ¿¹´Â Äڵ忡¼­ °¡Á®¿ÀÁö ¾Ê¾Ò´Ù. + ´ÜÁö ¼³¸íÇϱâÀ§ÇÑ ¿ëµµ·Î ¸¸µé¾ú´Ù.):

    + +

    + for (;;) {
    + + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + process the new_connection;
    +
    + } +

    + +

    ±×·¯³ª À§ÀÇ ´Ü¼øÇÑ ±¸Çö¿¡´Â ½É°¢ÇÑ °í°¥(starvation) + ¹®Á¦°¡ ÀÖ´Ù. ¿©·¯ ÀÚ½ÄÀÌ µ¿½Ã¿¡ ÀÌ ¹Ýº¹¹®À» ½ÇÇàÇϸé, + ¿äûÀ» ±â´Ù¸®¸ç ¸ðµÎ select¿¡¼­ ¸ØÃá´Ù. À̶§ + ¾î¶² ¼ÒÄÏ¿¡ ¿äûÀÌ Çϳª¶óµµ µé¾î¿À¸é ¸ðµç ÀÚ½ÄÀÌ ±ú¾î³­´Ù + (±ú¾î³ª´Â ÀÚ½ÄÀÇ °³¼ö´Â ¿î¿µÃ¼Á¦¿Í ŸÀֿ̹¡ µû¶ó ´Ù¸£´Ù). + À̵éÀº ¸ðµÎ ¿¬°áÀ» acceptÇÏ±æ ½ÃµµÇÑ´Ù. ±×·¯³ª + (¾ÆÁ÷µµ ÇÑ ¿¬°á¸¸ ´ë±âÁßÀ̶ó¸é) ÇÑ Àڽĸ¸ ¼º°øÇÏ°í, ³ª¸ÓÁö´Â + accept¿¡¼­ ¸ØÃá´Ù. ±×·¯¸é ÀÌ ÀڽĵéÀº + ÇÑ ¼ÒÄÏÀÇ ¿äû¸¸À» ¼­ºñ½ºÇϵµ·Ï ¹­¿©¼­, ±× ¼ÒÄÏÀ¸·Î »õ·Î¿î + ¿äûÀÌ ÃæºÐÈ÷ µé¾î¿Í¼­ ¸ðµç ÀÚ½ÄÀ» ±ú¿ï¶§±îÁö Á¤ÁöÇØÀÖ´Ù. + ÀÌ·± °í°¥ ¹®Á¦´Â PR#467¿¡ + óÀ½ º¸°íµÇ¾ú´Ù. ÃÖ¼ÒÇÑ µÎ°¡Áö ÇØ°áÃ¥ÀÌ ÀÖ´Ù.

    + +

    ÇÑ°¡Áö´Â ¼ÒÄÏÀ» ´ë±âÇÏÁö ¾Êµµ·Ï (non-blocking) ¸¸µå´Â + ¹æ¹ýÀÌ´Ù. ÀÌ °æ¿ì ÀÚ½ÄÀÌ accept¸¦ Çصµ ¸ØÃßÁö + ¾Ê°í, Áï½Ã ÁøÇàÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª CPU ½Ã°£À» ³¶ºñÇÑ´Ù. + select¿¡¼­ ½¬´Â ÀÚ½ÄÀÌ 10°³ ÀÖ°í, »õ·Î ¿¬°áÀÌ + ÇÑ°³ µé¾î¿Ô´Ù°í °¡Á¤ÇÏÀÚ. ±×·¯¸é ÀÌ ÀÚ½ÄÁß 9°³´Â ±ú¾î³ª¼­ + ¿¬°áÀ» acceptÇÏ±æ ½ÃµµÇÏ°í ½ÇÆÐÇÏ¸é ¾Æ¹« + Àϵµ ÇÏÁö ¾Ê°í ´Ù½Ã select¸¦ ¹Ýº¹ÇÑ´Ù. ´Ù½Ã + select·Î µ¹¾Æ¿Ã ¶§±îÁö ¾î¶² Àڽĵµ ´Ù¸¥ ¼ÒÄÏ¿¡ + µé¾î¿Â ¿äûÀ» ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. (´ÙÁßÇÁ·Î¼¼¼­ ÄÄÇ»ÅÍ¿¡¼­) + ½¬´Â ÀÚ½Ä °³¼ö¸¸Å­ CPU °³¼ö°¡ ÀÖ´Â µå¹® °æ¿ì°¡ ¾Æ´Ï¶ó¸é + ÀÌ ÇØ°áÃ¥Àº º°·Î ÁÁ¾Æº¸ÀÌÁö ¾Ê´Â´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ¹æ¹ýÀ¸·Î ³»ºÎ ¹Ýº¹¹®¿¡ + ÇÑ Àڽĸ¸À» µé¿©º¸³½´Ù. ¹Ýº¹¹®Àº ´ÙÀ½°ú °°´Ù (Â÷À̸¦ + °­Á¶ÇßÀ½):

    + +

    + for (;;) {
    + + accept_mutex_on ();
    + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + accept_mutex_off ();
    + process the new_connection;
    +
    + } +

    + +

    accept_mutex_on°ú accept_mutex_off + ÇÔ¼ö´Â mutex ¼¼¸¶Æ÷¾î¸¦ + ±¸ÇöÇÑ´Ù. Çѹø¿¡ ¿ÀÁ÷ ÇÑ Àڽĸ¸ÀÌ mutex¸¦ °¡Áú ¼ö ÀÖ´Ù. + mutex¸¦ ±¸ÇöÇÏ´Â ¹æ¹ýÀº ¿©·¯°¡ÁöÀÌ´Ù. ±¸Çö ¹æ¹ýÀº (1.3 + ÀÌÀü) src/conf.h³ª (1.3°ú ±× ÀÌÈÄ) + src/include/ap_config.h¿¡ Á¤ÀǵÇÀÖ´Ù. ¾î¶² + ¾ÆÅ°ÅØÃÄ´Â Àá±Ý(locking) ¹æ¹ýÀ» ¼±ÅÃÇÏÁö ¾Ê±â¶§¹®¿¡, ÀÌ·± + ¾ÆÅ°ÅØÃÄ¿¡¼­ ¿©·¯ Listen Áö½Ã¾î¸¦ »ç¿ëÇϸé + À§ÇèÇÏ´Ù.

    + +

    ½ÇÇà½Ã AcceptMutex Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + mutex ±¸ÇöÀ» º¯°æÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    AcceptMutex flock
    + +
    +

    ÀÌ ¹æ¹ýÀº Àá±ÝÆÄÀÏÀ» Àá±×±âÀ§ÇØ flock(2) + ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù (Àá±ÝÆÄÀÏ À§Ä¡´Â LockFile Áö½Ã¾î·Î ÁöÁ¤).

    +
    + +
    AcceptMutex fcntl
    + +
    +

    ÀÌ ¹æ¹ýÀº Àá±ÝÆÄÀÏÀ» Àá±×±âÀ§ÇØ fcntl(2) + ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù (Àá±ÝÆÄÀÏ À§Ä¡´Â LockFile Áö½Ã¾î·Î ÁöÁ¤).

    +
    + +
    AcceptMutex sysvsem
    + +
    +

    (1.3°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀ» SysV½Ä ¼¼¸¶Æ÷¾î¸¦ »ç¿ëÇÏ¿© + mutex¸¦ ±¸ÇöÇÑ´Ù. ºÒÇàÈ÷µµ SysV½Ä ¼¼¸¶Æ÷¾î´Â ³ª»Û + ºÎÀÛ¿ëÀÌ ÀÖ´Ù. Çϳª´Â ¾ÆÆÄÄ¡°¡ ¼¼¸¶Æ÷¾î¸¦ Á¤¸®ÇÏÁö + ¾Ê°í Á×À» ¼ö ÀÖ´Â Á¡ÀÌ´Ù (ipcs(8) manpage + Âü°í). ´Ù¸¥ Çϳª´Â À¥¼­¹ö¿Í µ¿ÀÏÇÑ uid·Î ½ÇÇàÇÏ´Â + CGI°¡ (Áï, suexec³ª + cgiwrapper¸¦ »ç¿ëÇÏÁö¾Ê´Â ÇÑ ¸ðµç CGI) + ¼¼¸¶Æ÷¾î API¸¦ »ç¿ëÇÏ¿© ¼­ºñ½º°ÅºÎ°ø°ÝÀ» ÇÒ ¼ö ÀÖ´Â + Á¡ÀÌ´Ù. ÀÌ·± ÀÌÀ¯¶§¹®¿¡ IRIX¸¦ Á¦¿ÜÇÑ ¾ÆÅ°ÅØÃÄ¿¡¼­ + ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù (´ëºÎºÐÀÇ IRIX ÄÄÇ»ÅÍ¿¡¼­ + ¾ÕÀÇ µÎ ¹æ¹ýÀº Áö³ªÄ¡°Ô ¹ö°Ì´Ù).

    +
    + +
    AcceptMutex pthread
    + +
    +

    (1.3°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀº POSIX mutex¸¦ »ç¿ëÇϱ⶧¹®¿¡ + POSIX ¾²·¹µå ±Ô¾àÀ» ¿ÏÀüÈ÷ ±¸ÇöÇÑ ¾ÆÅ°ÅØÃĶó¸é ¸ðµÎ + »ç¿ë°¡´ÉÇÏÁö¸¸, (2.5 ÀÌÈÄ) Solaris¿¡¼­¸¸ ±×°Íµµ ƯÁ¤ + ±¸¼º¿¡¼­¸¸ µ¿ÀÛÇÏ´Â µíÇÏ´Ù. ÀÌ ¹æ¹ýÀ» ½ÃµµÇغ»´Ù¸é + ¼­¹ö°¡ ¸ØÃç¼­ ÀÀ´äÀ» ¾ÈÇÏ´ÂÁö »ìÆìºÁ¾ß ÇÑ´Ù. Á¤Àû + ³»¿ë¸¸ ¼­ºñ½ºÇÏ´Â ¼­¹ö´Â Àß µ¿ÀÛÇÏ´Â °Í °°´Ù.

    +
    + +
    AcceptMutex posixsem
    + +
    +

    (2.0°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀº POSIX ¼¼¸¶Æ÷¾î¸¦ »ç¿ëÇÑ´Ù. + mutex¸¦ °¡Áø ÇÁ·Î¼¼½ºÀÇ ¾²·¹µå°¡ Á״´ٸé(segfault) + ¼¼¸¶Æ÷¾î ¼ÒÀ¯±ÇÀÌ È¸º¹µÇÁö ¾Ê¾Æ¼­ À¥¼­¹ö°¡ ¸ØÃá´Ù.

    +
    + +
    + +

    ½Ã½ºÅÛ¿¡ À§ ¸ñ·Ï¿¡ ¾ø´Â Á÷·ÄÈ­(serialization) ¹æ¹ýÀÌ + ÀÖ´Ù¸é ±× ¹æ¹ýÀ» »ç¿ëÇÏ´Â Äڵ带 APR¿¡ Ãß°¡ÇÒ °¡Ä¡°¡ ÀÖ´Ù.

    + +

    °í·Á´Â ÇغÃÁö¸¸ ±¸ÇöÇÏÁö¾ÊÀº ´Ù¸¥ ¹æ¹ýÀº ºÎºÐÀûÀ¸·Î + ¹Ýº¹¹®À» Á÷·ÄÈ­ÇÏ´Â ¹æ¹ýÀÌ´Ù. Áï, ÇÁ·Î¼¼¼­¸¦ ¸î°³¸¸ µé¿©º¸³»´Â + °ÍÀÌ´Ù. ÀÌ ¹æ¹ýÀº ¿©·¯ ÀÚ½ÄÀ» µ¿½Ã¿¡ ½ÇÇàÇÒ ¼ö À־ + Á÷·ÄÈ­¶§¹®¿¡ Àüü ´ë¿ªÆøÀ» È°¿ëÇÏÁö ¸øÇÏ´Â ´ÙÁßÇÁ·Î¼¼¼­ + ÄÄÇ»ÅÍ¿¡¼­¸¸ °ü½ÉÀ» °¡Á®º¼ ¼ö ÀÖ´Ù. ¾ÕÀ¸·Î »ìÆ캼 ºÎºÐÀÌÁö¸¸, + ¸Å¿ì º´·ÄÈ­µÈ À¥¼­¹ö°¡ ÈçÇÏÁö ¾Ê¾Æ¼­ ¿ì¼±¼øÀ§°¡ ³·´Ù.

    + +

    ÃÖ»óÀÇ ¼º´ÉÀ» ¾ò±âÀ§Çؼ­´Â ¿©·¯ Listen ¹®À» »ç¿ëÇÏÁö ¾Ê´Â + °ÍÀÌ ÀÌ»óÀûÀÌ´Ù. ±×·¯³ª °è¼Ó ¼³¸íÇÑ´Ù.

    + + + +

    accept Á÷·ÄÈ­ - ¼ÒÄÏ ÇÑ°³

    + + + +

    ¾ÕÀÇ ¼³¸íÀº ´ÙÁß¼ÒÄÏ ¼­¹ö¿¡´Â ÁÁÁö¸¸, ¼ÒÄÏÀÌ ÇÑ°³ÀÎ + ¼­¹ö´Â ¾î¶²°¡? ¿¬°áÀÌ µµÂøÇÒ¶§±îÁö ¸ðµç ÀÚ½ÄÀÌ + accept(2)¿¡¼­ ¸ØÃçÀֱ⶧¹®¿¡ ÀÌ·Ð»ó °°Àº + ¹®Á¦°¡ ¹ß»ýÇÏÁö ¾Ê°í, °í°¥ ¹®Á¦µµ ¾ø´Ù. ±×·¯³ª ½ÇÁ¦·Î´Â + ¾Õ¿¡¼­ ¸»ÇÑ ´ë±âÇÏÁö ¾Ê´Â (non-blocking) ¹æ¹ý¿¡¼­ ¹ß»ýÇÏ´Â + "°øȸÀü(spinning)" Çö»óÀ» °¨Ãß°í ÀÖ´Ù. ´ëºÎºÐÀÇ TCP ½ºÅÃÀº + ¿¬°áÀÌ µµÂøÇϸé Ä¿³ÎÀÌ accept¿¡¼­ ¸ØÃçÀÖ´Â + ¸ðµç ÀÚ½ÄÀ» ±ú¿ìµµ·Ï ±¸ÇöµÇÀÖ´Ù. ÇÁ·Î¼¼½ºÁß ÇÑ°³°¡ ¿¬°áÀ» + ¾ò°í »ç¿ëÀÚ¿µ¿ªÀ¸·Î µ¹¾Æ°¡°í, ³ª¸ÓÁö´Â Ä¿³Î¿¡¼­ °øȸÀüÇÏ¿© + ¿¬°áÀÌ ¾øÀ½À» ¹ß°ßÇÏ¸é ´Ù½Ã ÀáÀ» ÀÜ´Ù. »ç¿ëÀÚ¿µ¿ª Äڵ忡¼­´Â + ÀÌ·± °øȸÀüÀ» ¾Ë ¼ö ¾øÁö¸¸, ºÐ¸íÈ÷ Á¸ÀçÇÑ´Ù. ±×·¡¼­ ´ÙÁß¼ÒÄÏÀÇ + ´ë±âÇÏÁö ¾Ê´Â ¹æ¹ý°ú µ¿ÀÏÇÏ°Ô ºÎÇϸ¦ ³ôÀÌ´Â ºÒÇÊ¿äÇÑ ÇൿÀÌ + ÀϾ´Ù.

    + +

    ±×·¡¼­ ¿ì¸®´Â ¿©·¯ ¾ÆÅ°ÅØÃÄ¿¡¼­ ¼ÒÄÏÀÌ ÇÑ°³ÀÎ °æ¿ì¿¡µµ + Á÷·ÄÈ­ÇÏ¸é ´õ "Àß" µ¿ÀÛÇÔÀ» ¹ß°ßÇß´Ù. ±×·¡¼­ °ÅÀÇ ´ëºÎºÐÀÇ + °æ¿ì ±âº»ÀûÀ¸·Î Á÷·ÄÈ­¸¦ »ç¿ëÇÑ´Ù. ¸®´ª½º¿¡¼­ (Ä¿³Î 2.0.30, + 128Mb ¸Þ¸ð¸®¿¡ µà¾ó Pentium pro) ½ÇÇèÇÑ °á°ú ¼ÒÄÏ ÇÑ°³¸¦ + Á÷·ÄÈ­Çϸé ÇÏÁö ¾ÊÀº °æ¿ì¿¡ ºñÇØ ÃÊ´ç ¿äûÀÌ 3% ¹Ì¸¸ + ÁÙ¾îµé¾ú´Ù. ±×·¯³ª Á÷·ÄÈ­¸¦ ÇÏÁö ¾ÊÀº °æ¿ì ¿äû´ç 100ms + Áö¿¬ÀÌ ¹ß»ýÇß´Ù. ÀÌ Áö¿¬Àº ¾Æ¸¶µµ LAN¿¡¼­ ¹ß»ýÇÏ´Â ±ä + ¿¬°á¼±¶§¹®ÀÏ °ÍÀÌ´Ù. ¼ÒÄÏÀÌ ÇÑ°³ÀÎ °æ¿ì Á÷·ÄÈ­¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸·Á¸é SINGLE_LISTEN_UNSERIALIZED_ACCEPT¸¦ + Á¤ÀÇÇÑ´Ù.

    + + + +

    Close Áö¿¬(lingering)

    + + + +

    + draft-ietf-http-connection-00.txt 8Àý¿¡¼­ ¼³¸íÇϵíÀÌ + ¾ÈÁ¤ÀûÀÎ À¥¼­¹ö°¡ µÇ·Á¸é, Åë½ÅÀÇ ¾ç ¹æÇâÀ» + µ¶¸³ÀûÀ¸·Î ´ÝÀ» ¼ö ÀÖ¾î¾ß ÇÑ´Ù (TCP ¿¬°áÀº ½Ö¹æÇâÀÌ°í, + ¹æÇâÀº ¼­·Î µ¶¸³ÀûÀÌ´Ù). ÀÌÁ¡À» ´Ù¸¥ ¼­¹ö¿¡¼­´Â ÀÚÁÖ + °£°úÇÏÁö¸¸, ¾ÆÆÄÄ¡´Â 1.2ºÎÅÍ Á¤È®È÷ ±¸ÇöÇØ¿Ô´Ù.

    + +

    ÀÌ ±â´ÉÀ» ºÎÁÖÀÇÇÏ°Ô ¾ÆÆÄÄ¡¿¡ Ãß°¡ÇßÀ»¶§ ¿©·¯ À¯´Ð½º + ¹öÀü¿¡¼­ ¸¹Àº ¹®Á¦°¡ ¹ß»ýÇß´Ù. TCP ±Ô¾àÀº + FIN_WAIT_2¿¡ ŸÀӾƿôÀÌ ÀÖ´Ù°í Á¤ÇÏÁö ¾Ê¾ÒÁö¸¸, + ±ÝÁöÇÏÁöµµ ¾Ê¾Ò´Ù. ŸÀӾƿôÀÌ ¾ø´Â ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡ 1.2´Â + ¸¹Àº ¼ÒÄÏÀ» ¿µ¿øÈ÷ FIN_WAIT_2 »óÅ·Π¸¸µé¾ú´Ù. + ¸¹Àº °æ¿ì ÀÌ ¹®Á¦´Â Á¦Àۻ簡 Á¦°øÇÏ´Â ÃֽŠTCP/IP ÆÐÄ¡¸¦ + Àû¿ëÇÏ¿© ÇØ°áÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Á¦Àۻ簡 ÆÐÄ¡¸¦ ¹ßÇ¥ÇÏÁö + ¾Ê´Â °æ¿ì°¡ (Áï, SunOS4 -- ¼Ò½º ¶óÀ̼±½º°¡ ÀÖ´Â + »ç¶÷Àº Á÷Á¢ ÆÐÄ¡ÇÒ ¼ö ÀÖÁö¸¸) Àֱ⶧¹®¿¡ ÀÌ ±â´ÉÀ» »ç¿ëÇÏÁö + ¾Ê±â·Î °áÁ¤Çß´Ù.

    + +

    ¹æ¹ýÀº µÎ°¡Áö´Ù. Çϳª´Â ¼ÒÄÏ ¿É¼Ç SO_LINGER¸¦ + »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. ±×·¯³ª ºÒÇàÈ÷µµ ´ëºÎºÐÀÇ TCP/IP ½ºÅÃÀº + ÀÌ ¿É¼ÇÀ» ¿Ã¹Ù·Î ±¸ÇöÇÏÁö ¾Ê¾Ò´Ù. ¿Ã¹Ù·Î ±¸ÇöÇÑ ½ºÅÿ¡¼­ + Á¶Â÷µµ (Áï, ¸®´ª½º 2.0.31) ÀÌ ¹æ¹ýÀº ´ÙÀ½ ¹æ¹ýº¸´Ù + ´õ cpu¸¦ Àâ¾Æ¸Ô´Â´Ù.

    + +

    ¾ÆÆÄÄ¡´Â º¸Åë (http_main.c¿¡ ÀÖ´Â) + lingering_close¶ó´Â ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ ÇÔ¼ö´Â + ´ëÃæ ´ÙÀ½°ú °°´Ù:

    + +

    + void lingering_close (int s)
    + {
    + + char junk_buffer[2048];
    +
    + /* shutdown the sending side */
    + shutdown (s, 1);
    +
    + signal (SIGALRM, lingering_death);
    + alarm (30);
    +
    + for (;;) {
    + + select (s for reading, 2 second timeout);
    + if (error) break;
    + if (s is ready for reading) {
    + + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
    + + break;
    +
    + }
    + /* just toss away whatever is here */
    +
    + }
    +
    + }
    +
    + close (s);
    +
    + } +

    + +

    ÀÌ ÄÚµå´Â ¿¬°áÀ» ´ÝÀ»¶§ ´õ CPU¸¦ »ç¿ëÇÏÁö¸¸, ¾ÈÁ¤ÀûÀÎ + ±¸ÇöÀ» À§ÇØ ÇÊ¿äÇÏ´Ù. HTTP/1.1ÀÌ ´õ ³Î¸® ÆÛÁö°í ¸ðµç ¿¬°áÀ» + À¯ÁöÇÑ´Ù¸é(persistent), ¿¬°áÀ» ¹Þ´Â ºñ¿ëÀº ¿©·¯ ¿äûÀ» + ó¸®Çϸ鼭 »ó¼âµÉ °ÍÀÌ´Ù. À§ÇèÇÏ°Ôµµ + NO_LINGCLOSE¸¦ Á¤ÀÇÇÏ¿© ÀÌ ±â´ÉÀ» »ç¿ëÇÏÁö + ¾ÊÀ» ¼ö ÀÖÁö¸¸, Àý´ë·Î ±ÇÇÏÁö ¾Ê´Â´Ù. ƯÈ÷ HTTP/1.1 + ÆÄÀÌÇÁ¶óÀÎ (¿ªÁÖ; ¿¬°áÀ¯Áö »óÅ¿¡¼­ ÀÀ´äÀ» ±â´Ù¸®Áö + ¾Ê°í ¿©·¯ ¿äûÀ» º¸³»´Â ±â¼ú) ¿¬°áÀ¯Áö¿¡´Â + lingering_close°¡ ÇʼöÀûÀÌ´Ù (±×¸®°í + ÆÄÀÌÇÁ¶óÀÎ ¿¬°áÀÌ ´õ ºü¸£±â¶§¹®¿¡ »ç¿ëÇÏ±æ ¹Ù¶ö °ÍÀÌ´Ù).

    + + + +

    Scoreboard ÆÄÀÏ

    + + + +

    ¾ÆÆÄÄ¡ÀÇ ºÎ¸ð¿Í ÀÚ½ÄÀº scoreboard¶ó´Â °ÍÀ» ÅëÇØ ¼­·Î + Åë½ÅÇÑ´Ù. ÀÌ»óÀûÀ¸·Î´Â scoreboard¸¦ °øÀ¯¸Þ¸ð¸®·Î ±¸ÇöÇØ¾ß + ÇÑ´Ù. ¿ì¸® °³¹ßÀÚ°¡ ÇØ´ç ¿î¿µÃ¼Á¦¿¡ Á¢±ÙÇÒ ¼ö Àְųª »ó¼¼ÇÑ + Æ÷Æà °á°ú¸¦ ¹ÞÀº °æ¿ì º¸Åë °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÏ¿© ±¸ÇöÇÑ´Ù. + ³ª¸ÓÁö´Â µð½ºÅ©¿¡ ÀÖ´Â ÆÄÀÏÀ» »ç¿ëÇÏ¿© ±¸ÇöÇÑ´Ù. µð½ºÅ©¿¡ + ÀÖ´Â ÆÄÀÏÀº ´À¸®°í ½Å·Úµµ°¡ ¶³¾îÁø´Ù (±â´Éµµ ´õ Àû´Ù). + src/main/conf.h ÆÄÀÏ¿¡¼­ »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃĸ¦ + ã¾Æ¼­ USE_MMAP_SCOREBOARD ȤÀº + USE_SHMGET_SCOREBOARDÀÎÁö È®ÀÎÇÑ´Ù. µÑÁß + Çϳª¸¦ (°¢°¢ ÇÔ²² »ç¿ëÇÒ HAVE_MMAPÀ̳ª + HAVE_SHMGETµµ °°ÀÌ) Á¤ÀÇÇÏ¸é °øÀ¯¸Þ¸ð¸® Äڵ带 + »ç¿ëÇÑ´Ù. ½Ã½ºÅÛÀÌ ´Ù¸¥ Á¾·ùÀÇ °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÑ´Ù¸é + src/main/http_main.c ÆÄÀÏÀ» ¼öÁ¤ÇÏ¿© ¾ÆÆÄÄ¡¿¡¼­ + °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÈÅ(hook)À» Ãß°¡Ç϶ó. (¶ÇÇÑ + ÆÐÄ¡¸¦ ¿ì¸®¿¡°Ô º¸³»ÁÖ±æ ¹Ù¶õ´Ù.)

    + +
    ¿ª»çÀû ¼³¸í: ¾ÆÆÄÄ¡ÀÇ ¸®´ª½º ¹öÀüÀº ¾ÆÆÄÄ¡ 1.2 ¹öÀüºÎÅÍ + °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇϱ⠽ÃÀÛÇß´Ù. ¸®´ª½º¿¡¼­ Ãʱ⠾ÆÆÄÄ¡ + ¹öÀüÀÌ ´À¸®°í ½Å·Úµµ°¡ ¶³¾îÁ³±â ¶§¹®ÀÌ´Ù.
    + + + +

    DYNAMIC_MODULE_LIMIT

    + + + +

    ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÌÁö ¾Ê´Â´Ù¸é (°¡´ÉÇÑ Á¶±ÝÀÌ¶óµµ + ¼º´ÉÀ» ³ôÀ̱âÀ§ÇØ ÀÌ ±ÛÀ» ÀÐ´Â´Ù¸é ¾Æ¸¶µµ ¸ðµâÀ» µ¿ÀûÀ¸·Î + ÀоîµéÀÌÁö ¾ÊÀ» °ÍÀÌ´Ù), ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ + -DDYNAMIC_MODULE_LIMIT=0À» Ãß°¡ÇÑ´Ù. ±×·¯¸é + ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀ̱âÀ§ÇØ ÇÒ´çÇÏ´Â ¸Þ¸ð¸®¸¦ Àý¾àÇÑ´Ù.

    + + + +
    top
    +
    +

    ºÎ·Ï: ½Ã½ºÅÛÈ£Ãâ ±â·ÏÀ» ÀÚ¼¼È÷ ºÐ¼®Çϱâ

    + + + +

    ´ÙÀ½Àº Solaris 8¿¡¼­ worker MPMÀ» »ç¿ëÇÑ ¾ÆÆÄÄ¡ 2.0.38ÀÇ + ½Ã½ºÅÛÈ£Ãâ ±â·Ï(trace)ÀÌ´Ù. ¾Æ·¡ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© ±â·ÏÀ» + ¾ò¾ú´Ù:

    + +

    + truss -l -p httpd_child_pid. +

    + +

    -l ¿É¼ÇÀ» »ç¿ëÇϸé truss´Â ½Ã½ºÅÛÈ£ÃâÀ» + ÇÏ´Â LWP (lightweight process, °æ·®±Þ ÇÁ·Î¼¼½º--SolarisÀÇ + Ä¿³Î¼öÁØ ¾²·¹µå) ID¸¦ °°ÀÌ ±â·ÏÇÑ´Ù.

    + +

    ´Ù¸¥ ½Ã½ºÅÛ¿¡´Â strace, ktrace, + par °°Àº ½Ã½ºÅÛÈ£Ãâ ÃßÀû µµ±¸°¡ ÀÖ´Ù. °á°ú´Â + ºñ½ÁÇÏ´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®´Â À¥¼­¹ö¿¡°Ô Å©±â°¡ 10KBÀÎ Á¤Àû ÆÄÀÏÀ» ¿äûÇÑ´Ù. + Á¤ÀûÀÎ ÆÄÀÏÀ» ¿äûÇÏÁö ¾Ê°Å³ª ³»¿ëÇù»óÇÏ´Â ¿äûÀ» ÇÑ °æ¿ì + ±â·ÏÀÌ ¸Å¿ì ´Ù¸£´Ù (¶§·Î´Â ¸Å¿ì ¾Ë¾Æº¸±â Èûµé´Ù).

    + +
    /67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
    +/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
    + +

    À§¿¡¼­ ¿¬°á´ë±â(listener) ¾²·¹µå°¡ LWP #67¿¡¼­ ½ÇÇàµÊÀ» + ¾Ë ¼ö ÀÖ´Ù.

    + +
    accept(2) Á÷·ÄÈ­¸¦ »ç¿ëÇÏÁö ¾ÊÀ½À» ÁÖ¸ñÇ϶ó. + ¿©·¯ Æ÷Æ®¸¦ ±â´Ù¸®Áö¾Ê´Â °æ¿ì ÀÌ Ç÷¡ÆûÀÇ worker MPMÀº + ±âº»ÀûÀ¸·Î Á÷·ÄÈ­ÇÏÁö ¾ÊÀº accept¸¦ »ç¿ëÇÑ´Ù.
    + +
    /65:    lwp_park(0x00000000, 0)                         = 0
    +/67:    lwp_unpark(65, 1)                               = 0
    + +

    ¿¬°áÀº ¹Þ¾ÆµéÀÌ°í(accept) ¿¬°á´ë±â ¾²·¹µå´Â + worker ¾²·¹µå¸¦ ±ú¿ö¼­ ¿äûÀ» ó¸®ÇÏ°Ô ÇÑ´Ù. ¾Æ·¡ ±â·Ï¿¡¼­ + ¿äûÀ» ó¸®ÇÏ´Â worker ¾²·¹µå°¡ LWP #65ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù.

    + +
    /65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
    + +

    °¡»óÈ£½ºÆ®¸¦ ±¸ÇöÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â ¿¬°áÀ» ¹Þ¾ÆµéÀÎ + Áö¿ª(local) ¼ÒÄÏ ÁÖ¼Ò¸¦ ¾Ë¾Æ¾ß ÇÑ´Ù. (°¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏÁö + ¾Ê°Å³ª Listen + Áö½Ã¾î¿¡ ¿ÍÀϵåÄ«µå ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì µî) ¸¹Àº °æ¿ì + ÀÌ È£ÃâÀ» ¾ø¾Ù ¼ö ÀÖ´Ù. ±×·¯³ª ¾ÆÁ÷ ÀÌ·± ÃÖÀûÈ­ ÀÛ¾÷ÀÌ + ¾ÈµÇÀÖ´Ù.

    + +
    /65:    brk(0x002170E8)                                 = 0
    +/65:    brk(0x002190E8)                                 = 0
    + +

    brk(2) È£ÃâÀº Èü(heap)¿¡¼­ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. + À¥¼­¹ö´Â ´ëºÎºÐÀÇ ¿äû 󸮽à ÀÚü ¸Þ¸ð¸® + ÇÒ´çÀÚ(apr_pool°ú apr_bucket_alloc)¸¦ + »ç¿ëÇϱ⶧¹®¿¡ ½Ã½ºÅÛÈ£Ãâ ±â·Ï¿¡¼­ ÀÌ ½Ã½ºÅÛÈ£ÃâÀ» º¸±â°¡ + µå¹°´Ù. ÀÌ ±â·Ï¿¡¼­ À¥¼­¹ö´Â ½ÃÀÛÇÏÀÚ¸¶ÀÚ ÀÚü ¸Þ¸ð¸® ÇÒ´çÀÚ°¡ + »ç¿ëÇÒ ¸Þ¸ð¸®ºí·ÏÀ» ¾ò±âÀ§ÇØ malloc(3)À» È£ÃâÇÑ´Ù.

    + +
    /65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
    +/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
    +/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
    + +

    ´ÙÀ½ worker ¾²·¹µå´Â Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á(ÆÄÀϱâ¼úÀÚ 9)À» + ´ë±â¾ÈÇÔ(non-blocking) »óÅ·Π¹Ù²Û´Ù. setsockopt(2)¿Í + getsockopt(2) È£ÃâÀº SolarisÀÇ libc°¡ ¼ÒÄÏ¿¡ + ´ëÇÑ fcntl(2)À» ¾î¶»°Ô ó¸®ÇÏ´ÂÁö º¸¿©ÁØ´Ù.

    + +
    /65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
    + +

    worker ¾²·¹µå´Â Ŭ¶óÀ̾ðÆ®·Î ºÎÅÍ ¿äûÀ» Àд´Ù.

    + +
    /65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
    +/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
    + +

    À¥¼­¹ö ¼³Á¤Àº Options FollowSymLinks¿Í + AllowOverride NoneÀÌ´Ù. ±×·¡¼­ ¿äûÇÑ ÆÄÀÏ°æ·ÎÀÇ + °¢ µð·ºÅ丮¿¡ ´ëÇØ lstat(2)Çϰųª + .htaccess ÆÄÀÏÀ» °Ë»çÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ÆÄÀÏÀ» + °Ë»çÇϱâÀ§ÇØ, 1) ÆÄÀÏÀÌ ÀÖ´ÂÁö, 2) µð·ºÅ丮°¡ ¾Æ´Ñ ÀϹÝÆÄÀÏÀÎÁö, + stat(2) È£Ã⸸ ÇÏ¸é µÈ´Ù.

    + +
    /65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
    + +

    ÀÌ °æ¿ì À¥¼­¹ö´Â ÇѹøÀÇ sendfilev(2) ½Ã½ºÅÛÈ£Ãâ·Î + HTTP ÀÀ´äÇì´õ¿Í ¿äûÇÑ ÆÄÀÏÀ» Àü¼ÛÇÒ ¼ö ÀÖ´Ù. Sendfile Áö¿ø¿©ºÎ´Â + ¿î¿µÃ¼Á¦¸¶´Ù ´Ù¸£´Ù. ´Ù¸¥ ½Ã½ºÅÛÀ̶ó¸é sendfile(2)À» + È£ÃâÇϱâ Àü¿¡ Çì´õ¸¦ º¸³»±âÀ§ÇØ write(2)³ª + writev(2) È£ÃâÀ» ÇÑ´Ù.

    + +
    /65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
    + +

    write(2) È£ÃâÀº Á¢±Ù·Î±×(access log)¿¡ ¿äûÀ» + ±â·ÏÇÑ´Ù. ÀÌ ±â·Ï¿¡ time(2) È£ÃâÀÌ ¾øÀ½À» ÁÖ¸ñÇ϶ó. + ¾ÆÆÄÄ¡ 1.3°ú ´Þ¸® ¾ÆÆÄÄ¡ 2.0Àº ½Ã°£À» ¾Ë±âÀ§ÇØ + gettimeofday(3)¸¦ »ç¿ëÇÑ´Ù. + gettimeofday¸¦ ÃÖÀûÈ­ÇÑ ¸®´ª½º¿Í Solaris °°Àº + ¸î¸î ¿î¿µÃ¼Á¦¿¡¼­´Â ÀϹÝÀûÀÎ ½Ã½ºÅÛÈ£Ã⠺δãÀÌ ¾ø´Ù.

    + +
    /65:    shutdown(9, 1, 1)                               = 0
    +/65:    poll(0xFAF7B980, 1, 2000)                       = 1
    +/65:    read(9, 0xFAF7BC20, 512)                        = 0
    +/65:    close(9)                                        = 0
    + +

    worker ¾²·¹µå´Â ¿¬°áÀ» Áö¿¬´Ý±â(lingering close)ÇÑ´Ù.

    + +
    /65:    close(10)                                       = 0
    +/65:    lwp_park(0x00000000, 0)         (sleeping...)
    + +

    ¸¶Áö¸·À¸·Î worker ¾²·¹µå´Â ¹æ±Ý Àü¼ÛÇÑ ÆÄÀÏÀ» ´Ý°í, + ¿¬°á´ë±â(listener) ¾²·¹µå°¡ ´Ù¸¥ ¿¬°áÀ» ÇÒ´çÇÒ ¶§±îÁö + Á¤ÁöÇÑ´Ù.

    + +
    /67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
    + +

    ±×µ¿¾È ¿¬°á´ë±â ¾²·¹µå´Â ¿¬°áÀ» (¸ðµç worker°¡ ÀÛ¾÷ÁßÀ̸é + ¿¬°á´ë±â ¾²·¹µå¸¦ ¸ØÃß´Â worker MPMÀÇ È帧Á¦¾î ±â´É¿¡ µû¶ó) + worker ¾²·¹µå¿¡ ÇÒ´çÇÏÀÚ¸¶ÀÚ ´Ù¸¥ ¿¬°áÀ» ¹Þ¾ÆµéÀÏ ¼ö ÀÖ´Ù. + ÀÌ ±â·Ï¿¡´Â ³ª¿ÀÁö ¾ÊÁö¸¸, worker ¾²·¹µå°¡ ¹æ±Ý ¹ÞÀº ¿¬°áÀ» + ó¸®ÇÏ´Â µ¿¾È ´ÙÀ½ accept(2)°¡ (¿äûÀÌ ¸Å¿ì + ¸¹Àº °æ¿ì Ç×»ó) ÀϾ ¼ö ÀÖ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/perf-tuning.xml b/trunk/docs/manual/misc/perf-tuning.xml new file mode 100644 index 0000000000..db16fcca24 --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.xml @@ -0,0 +1,1113 @@ + + + + + + + + + Miscellaneous Documentation + + Apache Performance Tuning + + + +

    Apache 2.0 is a general-purpose webserver, designed to + provide a balance of flexibility, portability, and performance. + Although it has not been designed specifically to set benchmark + records, Apache 2.0 is capable of high performance in many + real-world situations.

    + +

    Compared to Apache 1.3, release 2.0 contains many additional + optimizations to increase throughput and scalability. Most of + these improvements are enabled by default. However, there are + compile-time and run-time configuration choices that can + significantly affect performance. This document describes the + options that a server administrator can configure to tune the + performance of an Apache 2.0 installation. Some of these + configuration options enable the httpd to better take advantage + of the capabilities of the hardware and OS, while others allow + the administrator to trade functionality for speed.

    + +
    + +
    + + Hardware and Operating System Issues + +

    The single biggest hardware issue affecting webserver + performance is RAM. A webserver should never ever have to swap, + as swapping increases the latency of each request beyond a point + that users consider "fast enough". This causes users to hit + stop and reload, further increasing the load. You can, and + should, control the MaxClients setting so that your server + does not spawn so many children it starts swapping. This procedure + for doing this is simple: determine the size of your average Apache + process, by looking at your process list via a tool such as + top, and divide this into your total available memory, + leaving some room for other processes.

    + +

    Beyond that the rest is mundane: get a fast enough CPU, a + fast enough network card, and fast enough disks, where "fast + enough" is something that needs to be determined by + experimentation.

    + +

    Operating system choice is largely a matter of local + concerns. But some guidelines that have proven generally + useful are:

    + +
      +
    • +

      Run the latest stable release and patchlevel of the + operating system that you choose. Many OS suppliers have + introduced significant performance improvements to their + TCP stacks and thread libraries in recent years.

      +
    • + +
    • +

      If your OS supports a sendfile(2) system + call, make sure you install the release and/or patches + needed to enable it. (With Linux, for example, this means + using Linux 2.4 or later. For early releases of Solaris 8, + you may need to apply a patch.) On systems where it is + available, sendfile enables Apache 2 to deliver + static content faster and with lower CPU utilization.

      +
    • +
    + +
    + +
    + + Run-Time Configuration Issues + + + + mod_dir + mpm_common + mod_status + + + AllowOverride + DirectoryIndex + HostnameLookups + EnableMMAP + EnableSendfile + KeepAliveTimeout + MaxSpareServers + MinSpareServers + Options + StartServers + + + +
    + + HostnameLookups and other DNS considerations + +

    Prior to Apache 1.3, HostnameLookups defaulted to On. + This adds latency to every request because it requires a + DNS lookup to complete before the request is finished. In + Apache 1.3 this setting defaults to Off. If you need + to have addresses in your log files resolved to hostnames, use the + logresolve + program that comes with Apache, on one of the numerous log + reporting packages which are available.

    + +

    It is recommended that you do this sort of postprocessing of + your log files on some machine other than the production web + server machine, in order that this activity not adversely affect + server performance.

    + +

    If you use any Allow + from domain or Deny from domain + directives (i.e., using a hostname, or a domain name, rather than + an IP address) then you will pay for + a double reverse DNS lookup (a reverse, followed by a forward + to make sure that the reverse is not being spoofed). For best + performance, therefore, use IP addresses, rather than names, when + using these directives, if possible.

    + +

    Note that it's possible to scope the directives, such as + within a <Location /server-status> section. + In this case the DNS lookups are only performed on requests + matching the criteria. Here's an example which disables lookups + except for .html and .cgi files:

    + + + HostnameLookups off
    + <Files ~ "\.(html|cgi)$">
    + + HostnameLookups on
    +
    + </Files> +
    + +

    But even still, if you just need DNS names in some CGIs you + could consider doing the gethostbyname call in the + specific CGIs that need it.

    + +
    + + + +
    + + AllowOverride + +

    Wherever in your URL-space you allow overrides (typically + .htaccess files) Apache will attempt to open + .htaccess for each filename component. For + example,

    + + + DocumentRoot /www/htdocs
    + <Directory />
    + + AllowOverride all
    +
    + </Directory> +
    + +

    and a request is made for the URI /index.html. + Then Apache will attempt to open /.htaccess, + /www/.htaccess, and + /www/htdocs/.htaccess. The solutions are similar + to the previous case of Options FollowSymLinks. + For highest performance use AllowOverride None + everywhere in your filesystem.

    + +
    + +
    + + Negotiation + +

    If at all possible, avoid content-negotiation if you're + really interested in every last ounce of performance. In + practice the benefits of negotiation outweigh the performance + penalties. There's one case where you can speed up the server. + Instead of using a wildcard such as:

    + + + DirectoryIndex index + + +

    Use a complete list of options:

    + + + DirectoryIndex index.cgi index.pl index.shtml index.html + + +

    where you list the most common choice first.

    + +

    Also note that explicitly creating a type-map + file provides better performance than using + MultiViews, as the necessary information can be + determined by reading this single file, rather than having to + scan the directory for files.

    + +

    If your site needs content negotiation consider using + type-map files, rather than the Options + MultiViews directive to accomplish the negotiation. See the + Content Negotiation + documentation for a full discussion of the methods of negotiation, + and instructions for creating type-map files.

    + +
    + +
    + + Memory-mapping + +

    In situations where Apache 2.0 needs to look at the contents + of a file being delivered--for example, when doing server-side-include + processing--it normally memory-maps the file if the OS supports + some form of mmap(2).

    + +

    On some platforms, this memory-mapping improves performance. + However, there are cases where memory-mapping can hurt the performance + or even the stability of the httpd:

    + +
      +
    • +

      On some operating systems, mmap does not scale + as well as read(2) when the number of CPUs increases. + On multiprocessor Solaris servers, for example, Apache 2.0 sometimes + delivers server-parsed files faster when mmap is disabled.

      +
    • + +
    • +

      If you memory-map a file located on an NFS-mounted filesystem + and a process on another NFS client machine deletes or truncates + the file, your process may get a bus error the next time it tries + to access the mapped file content.

      +
    • +
    + +

    For installations where either of these factors applies, you + should use EnableMMAP off to disable the memory-mapping + of delivered files. (Note: This directive can be overridden on + a per-directory basis.)

    + +
    + +
    + + Sendfile + +

    In situations where Apache 2.0 can ignore the contents of the file + to be delivered -- for example, when serving static file content -- + it normally uses the kernel sendfile support the file if the OS + supports the sendfile(2) operation.

    + +

    On most platforms, using sendfile improves performance by eliminating + separate read and send mechanics. However, there are cases where using + sendfile can harm the stability of the httpd:

    + +
      +
    • +

      Some platforms may have broken sendfile support that the build + system did not detect, especially if the binaries were built on + another box and moved to such a machine with broken sendfile support.

      +
    • +
    • +

      With an NFS-mounted files, the kernel may be unable + to reliably serve the network file through it's own cache.

      +
    • +
    + +

    For installations where either of these factors applies, you + should use EnableSendfile off to disable sendfile + delivery of file contents. (Note: This directive can be overridden + on a per-directory basis.)

    + +
    + +
    + + Process Creation + +

    Prior to Apache 1.3 the MinSpareServers, MaxSpareServers, and StartServers settings all had drastic effects on + benchmark results. In particular, Apache required a "ramp-up" + period in order to reach a number of children sufficient to serve + the load being applied. After the initial spawning of + StartServers children, + only one child per second would be created to satisfy the + MinSpareServers + setting. So a server being accessed by 100 simultaneous + clients, using the default StartServers of 5 would take on + the order 95 seconds to spawn enough children to handle + the load. This works fine in practice on real-life servers, + because they aren't restarted frequently. But does really + poorly on benchmarks which might only run for ten minutes.

    + +

    The one-per-second rule was implemented in an effort to + avoid swamping the machine with the startup of new children. If + the machine is busy spawning children it can't service + requests. But it has such a drastic effect on the perceived + performance of Apache that it had to be replaced. As of Apache + 1.3, the code will relax the one-per-second rule. It will spawn + one, wait a second, then spawn two, wait a second, then spawn + four, and it will continue exponentially until it is spawning + 32 children per second. It will stop whenever it satisfies the + MinSpareServers + setting.

    + +

    This appears to be responsive enough that it's almost + unnecessary to twiddle the MinSpareServers, MaxSpareServers and StartServers knobs. When more than 4 children are + spawned per second, a message will be emitted to the + ErrorLog. If you + see a lot of these errors then consider tuning these settings. + Use the mod_status output as a guide.

    + +

    Related to process creation is process death induced by the + MaxRequestsPerChild + setting. By default this is 0, + which means that there is no limit to the number of requests + handled per child. If your configuration currently has this set + to some very low number, such as 30, you may want to bump this + up significantly. If you are running SunOS or an old version of + Solaris, limit this to 10000 or so because of memory leaks.

    + +

    When keep-alives are in use, children will be kept busy + doing nothing waiting for more requests on the already open + connection. The default KeepAliveTimeout of 5 + seconds attempts to minimize this effect. The tradeoff here is + between network bandwidth and server resources. In no event + should you raise this above about 60 seconds, as + most of the benefits are lost.

    + +
    + +
    + +
    + + Compile-Time Configuration Issues + +
    + + Choosing an MPM + +

    Apache 2.x supports pluggable concurrency models, called + Multi-Processing Modules (MPMs). + When building Apache, you must choose an MPM to use. There + are platform-specific MPMs for some platforms: + beos, mpm_netware, + mpmt_os2, and mpm_winnt. For + general Unix-type systems, there are several MPMs from which + to choose. The choice of MPM can affect the speed and scalability + of the httpd:

    + +
      + +
    • The worker MPM uses multiple child + processes with many threads each. Each thread handles + one connection at a time. Worker generally is a good + choice for high-traffic servers because it has a smaller + memory footprint than the prefork MPM.
    • + +
    • The prefork MPM uses multiple child + processes with one thread each. Each process handles + one connection at a time. On many systems, prefork is + comparable in speed to worker, but it uses more memory. + Prefork's threadless design has advantages over worker + in some situations: it can be used with non-thread-safe + third-party modules, and it is easier to debug on platforms + with poor thread debugging support.
    • + +
    + +

    For more information on these and other MPMs, please + see the MPM documentation.

    + +
    + +
    + + Modules + +

    Since memory usage is such an important consideration in + performance, you should attempt to eliminate modules that youare + not actually using. If you have built the modules as DSOs, eliminating modules is a simple + matter of commenting out the associated LoadModule directive for that module. + This allows you to experiment with removing modules, and seeing + if your site still functions in their absense.

    + +

    If, on the other hand, you have modules statically linked + into your Apache binary, you will need to recompile Apache in + order to remove unwanted modules.

    + +

    An associated question that arises here is, of course, what + modules you need, and which ones you don't. The answer here + will, of course, vary from one web site to another. However, the + minimal list of modules which you can get by with tends + to include mod_mime, mod_dir, + and mod_log_config. mod_log_config is, + of course, optional, as you can run a web site without log + files. This is, however, not recommended.

    + +
    + +
    + + Atomic Operations + +

    Some modules, such as mod_cache and + recent development builds of the worker MPM, use APR's + atomic API. This API provides atomic operations that can + be used for lightweight thread synchronization.

    + +

    By default, APR implements these operations using the + most efficient mechanism available on each target + OS/CPU platform. Many modern CPUs, for example, have + an instruction that does an atomic compare-and-swap (CAS) + operation in hardware. On some platforms, however, APR + defaults to a slower, mutex-based implementation of the + atomic API in order to ensure compatibility with older + CPU models that lack such instructions. If you are + building Apache for one of these platforms, and you plan + to run only on newer CPUs, you can select a faster atomic + implementation at build time by configuring Apache with + the --enable-nonportable-atomics option:

    + + + ./buildconf
    + ./configure --with-mpm=worker --enable-nonportable-atomics=yes +
    + +

    The --enable-nonportable-atomics option is + relevant for the following platforms:

    + +
      + +
    • Solaris on SPARC
      + By default, APR uses mutex-based atomics on Solaris/SPARC. + If you configure with --enable-nonportable-atomics, + however, APR generates code that uses a SPARC v8plus opcode for + fast hardware compare-and-swap. If you configure Apache with + this option, the atomic operations will be more efficient + (allowing for lower CPU utilization and higher concurrency), + but the resulting executable will run only on UltraSPARC + chips. +
    • + +
    • Linux on x86
      + By default, APR uses mutex-based atomics on Linux. If you + configure with --enable-nonportable-atomics, + however, APR generates code that uses a 486 opcode for fast + hardware compare-and-swap. This will result in more efficient + atomic operations, but the resulting executable will run only + on 486 and later chips (and not on 386). +
    • + +
    + +
    + +
    + + mod_status and ExtendedStatus On + +

    If you include mod_status and you also set + ExtendedStatus On when building and running + Apache, then on every request Apache will perform two calls to + gettimeofday(2) (or times(2) + depending on your operating system), and (pre-1.3) several + extra calls to time(2). This is all done so that + the status report contains timing indications. For highest + performance, set ExtendedStatus off (which is the + default).

    + +
    + +
    + + accept Serialization - multiple sockets + + Warning: +

    This section has not been fully updated + to take into account changes made in the 2.0 version of the + Apache HTTP Server. Some of the information may still be + relevant, but please use it with care.

    +
    + +

    This discusses a shortcoming in the Unix socket API. Suppose + your web server uses multiple Listen statements to listen on either multiple + ports or multiple addresses. In order to test each socket + to see if a connection is ready Apache uses + select(2). select(2) indicates that a + socket has zero or at least one connection + waiting on it. Apache's model includes multiple children, and + all the idle ones test for new connections at the same time. A + naive implementation looks something like this (these examples + do not match the code, they're contrived for pedagogical + purposes):

    + + + for (;;) {
    + + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + process the new_connection;
    +
    + } +
    + +

    But this naive implementation has a serious starvation problem. + Recall that multiple children execute this loop at the same + time, and so multiple children will block at + select when they are in between requests. All + those blocked children will awaken and return from + select when a single request appears on any socket + (the number of children which awaken varies depending on the + operating system and timing issues). They will all then fall + down into the loop and try to accept the + connection. But only one will succeed (assuming there's still + only one connection ready), the rest will be blocked + in accept. This effectively locks those children + into serving requests from that one socket and no other + sockets, and they'll be stuck there until enough new requests + appear on that socket to wake them all up. This starvation + problem was first documented in PR#467. There + are at least two solutions.

    + +

    One solution is to make the sockets non-blocking. In this + case the accept won't block the children, and they + will be allowed to continue immediately. But this wastes CPU + time. Suppose you have ten idle children in + select, and one connection arrives. Then nine of + those children will wake up, try to accept the + connection, fail, and loop back into select, + accomplishing nothing. Meanwhile none of those children are + servicing requests that occurred on other sockets until they + get back up to the select again. Overall this + solution does not seem very fruitful unless you have as many + idle CPUs (in a multiprocessor box) as you have idle children, + not a very likely situation.

    + +

    Another solution, the one used by Apache, is to serialize + entry into the inner loop. The loop looks like this + (differences highlighted):

    + + + for (;;) {
    + + accept_mutex_on ();
    + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + accept_mutex_off ();
    + process the new_connection;
    +
    + } +
    + +

    The functions + accept_mutex_on and accept_mutex_off + implement a mutual exclusion semaphore. Only one child can have + the mutex at any time. There are several choices for + implementing these mutexes. The choice is defined in + src/conf.h (pre-1.3) or + src/include/ap_config.h (1.3 or later). Some + architectures do not have any locking choice made, on these + architectures it is unsafe to use multiple + Listen + directives.

    + +

    The directive AcceptMutex can be used to + change the selected mutex implementation at run-time.

    + +
    +
    AcceptMutex flock
    + +
    +

    This method uses the flock(2) system call to + lock a lock file (located by the LockFile directive).

    +
    + +
    AcceptMutex fcntl
    + +
    +

    This method uses the fcntl(2) system call to + lock a lock file (located by the LockFile directive).

    +
    + +
    AcceptMutex sysvsem
    + +
    +

    (1.3 or later) This method uses SysV-style semaphores to + implement the mutex. Unfortunately SysV-style semaphores have + some bad side-effects. One is that it's possible Apache will + die without cleaning up the semaphore (see the + ipcs(8) man page). The other is that the + semaphore API allows for a denial of service attack by any + CGIs running under the same uid as the webserver + (i.e., all CGIs, unless you use something like + suexec or cgiwrapper). For these + reasons this method is not used on any architecture except + IRIX (where the previous two are prohibitively expensive + on most IRIX boxes).

    +
    + +
    AcceptMutex pthread
    + +
    +

    (1.3 or later) This method uses POSIX mutexes and should + work on any architecture implementing the full POSIX threads + specification, however appears to only work on Solaris (2.5 + or later), and even then only in certain configurations. If + you experiment with this you should watch out for your server + hanging and not responding. Static content only servers may + work just fine.

    +
    + +
    AcceptMutex posixsem
    + +
    +

    (2.0 or later) This method uses POSIX semaphores. The + semaphore ownership is not recovered if a thread in the process + holding the mutex segfaults, resulting in a hang of the web + server.

    +
    + +
    + +

    If your system has another method of serialization which + isn't in the above list then it may be worthwhile adding code + for it to APR.

    + +

    Another solution that has been considered but never + implemented is to partially serialize the loop -- that is, let + in a certain number of processes. This would only be of + interest on multiprocessor boxes where it's possible multiple + children could run simultaneously, and the serialization + actually doesn't take advantage of the full bandwidth. This is + a possible area of future investigation, but priority remains + low because highly parallel web servers are not the norm.

    + +

    Ideally you should run servers without multiple + Listen + statements if you want the highest performance. + But read on.

    + +
    + +
    + + accept Serialization - single socket + +

    The above is fine and dandy for multiple socket servers, but + what about single socket servers? In theory they shouldn't + experience any of these same problems because all children can + just block in accept(2) until a connection + arrives, and no starvation results. In practice this hides + almost the same "spinning" behaviour discussed above in the + non-blocking solution. The way that most TCP stacks are + implemented, the kernel actually wakes up all processes blocked + in accept when a single connection arrives. One of + those processes gets the connection and returns to user-space, + the rest spin in the kernel and go back to sleep when they + discover there's no connection for them. This spinning is + hidden from the user-land code, but it's there nonetheless. + This can result in the same load-spiking wasteful behaviour + that a non-blocking solution to the multiple sockets case + can.

    + +

    For this reason we have found that many architectures behave + more "nicely" if we serialize even the single socket case. So + this is actually the default in almost all cases. Crude + experiments under Linux (2.0.30 on a dual Pentium pro 166 + w/128Mb RAM) have shown that the serialization of the single + socket case causes less than a 3% decrease in requests per + second over unserialized single-socket. But unserialized + single-socket showed an extra 100ms latency on each request. + This latency is probably a wash on long haul lines, and only an + issue on LANs. If you want to override the single socket + serialization you can define + SINGLE_LISTEN_UNSERIALIZED_ACCEPT and then + single-socket servers will not serialize at all.

    + +
    + +
    + + Lingering Close + +

    As discussed in + draft-ietf-http-connection-00.txt section 8, in order for + an HTTP server to reliably implement the + protocol it needs to shutdown each direction of the + communication independently (recall that a TCP connection is + bi-directional, each half is independent of the other). This + fact is often overlooked by other servers, but is correctly + implemented in Apache as of 1.2.

    + +

    When this feature was added to Apache it caused a flurry of + problems on various versions of Unix because of a + shortsightedness. The TCP specification does not state that the + FIN_WAIT_2 state has a timeout, but it doesn't prohibit it. + On systems without the timeout, Apache 1.2 induces many sockets + stuck forever in the FIN_WAIT_2 state. In many cases this + can be avoided by simply upgrading to the latest TCP/IP patches + supplied by the vendor. In cases where the vendor has never + released patches (i.e., SunOS4 -- although folks with + a source license can patch it themselves) we have decided to + disable this feature.

    + +

    There are two ways of accomplishing this. One is the socket + option SO_LINGER. But as fate would have it, this + has never been implemented properly in most TCP/IP stacks. Even + on those stacks with a proper implementation (i.e., + Linux 2.0.31) this method proves to be more expensive (cputime) + than the next solution.

    + +

    For the most part, Apache implements this in a function + called lingering_close (in + http_main.c). The function looks roughly like + this:

    + + + void lingering_close (int s)
    + {
    + + char junk_buffer[2048];
    +
    + /* shutdown the sending side */
    + shutdown (s, 1);
    +
    + signal (SIGALRM, lingering_death);
    + alarm (30);
    +
    + for (;;) {
    + + select (s for reading, 2 second timeout);
    + if (error) break;
    + if (s is ready for reading) {
    + + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
    + + break;
    +
    + }
    + /* just toss away whatever is here */
    +
    + }
    +
    + }
    +
    + close (s);
    +
    + } +
    + +

    This naturally adds some expense at the end of a connection, + but it is required for a reliable implementation. As HTTP/1.1 + becomes more prevalent, and all connections are persistent, + this expense will be amortized over more requests. If you want + to play with fire and disable this feature you can define + NO_LINGCLOSE, but this is not recommended at all. + In particular, as HTTP/1.1 pipelined persistent connections + come into use lingering_close is an absolute + necessity (and + pipelined connections are faster, so you want to support + them).

    + +
    + +
    + + Scoreboard File + +

    Apache's parent and children communicate with each other + through something called the scoreboard. Ideally this should be + implemented in shared memory. For those operating systems that + we either have access to, or have been given detailed ports + for, it typically is implemented using shared memory. The rest + default to using an on-disk file. The on-disk file is not only + slow, but it is unreliable (and less featured). Peruse the + src/main/conf.h file for your architecture and + look for either USE_MMAP_SCOREBOARD or + USE_SHMGET_SCOREBOARD. Defining one of those two + (as well as their companions HAVE_MMAP and + HAVE_SHMGET respectively) enables the supplied + shared memory code. If your system has another type of shared + memory, edit the file src/main/http_main.c and add + the hooks necessary to use it in Apache. (Send us back a patch + too please.)

    + + Historical note: The Linux port of Apache didn't start to + use shared memory until version 1.2 of Apache. This oversight + resulted in really poor and unreliable behaviour of earlier + versions of Apache on Linux. + +
    + +
    + + DYNAMIC_MODULE_LIMIT + +

    If you have no intention of using dynamically loaded modules + (you probably don't if you're reading this and tuning your + server for every last ounce of performance) then you should add + -DDYNAMIC_MODULE_LIMIT=0 when building your + server. This will save RAM that's allocated only for supporting + dynamically loaded modules.

    + +
    + +
    + +
    + + Appendix: Detailed Analysis of a Trace + +

    Here is a system call trace of Apache 2.0.38 with the worker MPM + on Solaris 8. This trace was collected using:

    + + + truss -l -p httpd_child_pid. + + +

    The -l option tells truss to log the ID of the + LWP (lightweight process--Solaris's form of kernel-level thread) + that invokes each system call.

    + +

    Other systems may have different system call tracing utilities + such as strace, ktrace, or par. + They all produce similar output.

    + +

    In this trace, a client has requested a 10KB static file + from the httpd. Traces of non-static requests or requests + with content negotiation look wildly different (and quite ugly + in some cases).

    + + +
    /67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
    +/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
    +
    + +

    In this trace, the listener thread is running within LWP #67.

    + + Note the lack of accept(2) serialization. On this + particular platform, the worker MPM uses an unserialized accept by + default unless it is listening on multiple ports. + + +
    /65:    lwp_park(0x00000000, 0)                         = 0
    +/67:    lwp_unpark(65, 1)                               = 0
    +
    + +

    Upon accepting the connection, the listener thread wakes up + a worker thread to do the request processing. In this trace, + the worker thread that handles the request is mapped to LWP #65.

    + + +
    /65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
    +
    + +

    In order to implement virtual hosts, Apache needs to know + the local socket address used to accept the connection. It + is possible to eliminate this call in many situations (such + as when there are no virtual hosts, or when + Listen directives + are used which do not have wildcard addresses). But + no effort has yet been made to do these optimizations.

    + + +
    /65:    brk(0x002170E8)                                 = 0
    +/65:    brk(0x002190E8)                                 = 0
    +
    + +

    The brk(2) calls allocate memory from the heap. + It is rare to see these in a system call trace, because the httpd + uses custom memory allocators (apr_pool and + apr_bucket_alloc) for most request processing. + In this trace, the httpd has just been started, so it must + call malloc(3) to get the blocks of raw memory + with which to create the custom memory allocators.

    + + +
    /65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
    +/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
    +/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
    +
    + +

    Next, the worker thread puts the connection to the client (file + descriptor 9) in non-blocking mode. The setsockopt(2) + and getsockopt(2) calls are a side-effect of how + Solaris's libc handles fcntl(2) on sockets.

    + + +
    /65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
    +
    + +

    The worker thread reads the request from the client.

    + + +
    /65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
    +/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
    +
    + +

    This httpd has been configured with Options FollowSymLinks + and AllowOverride None. Thus it doesn't need to + lstat(2) each directory in the path leading up to the + requested file, nor check for .htaccess files. + It simply calls stat(2) to verify that the file: + 1) exists, and 2) is a regular file, not a directory.

    + + +
    /65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
    +
    + +

    In this example, the httpd is able to send the HTTP response + header and the requested file with a single sendfilev(2) + system call. Sendfile semantics vary among operating systems. On some other + systems, it is necessary to do a write(2) or + writev(2) call to send the headers before calling + sendfile(2).

    + + +
    /65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
    +
    + +

    This write(2) call records the request in the + access log. Note that one thing missing from this trace is a + time(2) call. Unlike Apache 1.3, Apache 2.0 uses + gettimeofday(3) to look up the time. On some operating + systems, like Linux or Solaris, gettimeofday has an + optimized implementation that doesn't require as much overhead + as a typical system call.

    + + +
    /65:    shutdown(9, 1, 1)                               = 0
    +/65:    poll(0xFAF7B980, 1, 2000)                       = 1
    +/65:    read(9, 0xFAF7BC20, 512)                        = 0
    +/65:    close(9)                                        = 0
    +
    + +

    The worker thread does a lingering close of the connection.

    + + +
    /65:    close(10)                                       = 0
    +/65:    lwp_park(0x00000000, 0)         (sleeping...)
    +
    + +

    Finally the worker thread closes the file that it has just delivered + and blocks until the listener assigns it another connection.

    + + +
    /67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
    +
    + +

    Meanwhile, the listener thread is able to accept another connection + as soon as it has dispatched this connection to a worker thread (subject + to some flow-control logic in the worker MPM that throttles the listener + if all the available workers are busy). Though it isn't apparent from + this trace, the next accept(2) can (and usually does, under + high load conditions) occur in parallel with the worker thread's handling + of the just-accepted connection.

    + +
    + +
    + diff --git a/trunk/docs/manual/misc/perf-tuning.xml.ko b/trunk/docs/manual/misc/perf-tuning.xml.ko new file mode 100644 index 0000000000..99c2a18748 --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.xml.ko @@ -0,0 +1,1042 @@ + + + + + + + + + Miscellaneous Documentation + + ¾ÆÆÄÄ¡ ¼º´ÉÇâ»ó + + + +

    ¾ÆÆÄÄ¡ 2.0Àº ±â´É°ú Æ÷Æð¡´É¼º°ú ¼º´ÉÀÇ ±ÕÇüÀÌ ¸Âµµ·Ï + ¼³°èÇÑ ¹ü¿ë À¥¼­¹öÀÌ´Ù. º¥Ä¡¸¶Å© ±â·ÏÀ» ¼¼¿ì±âÀ§ÇØ ¼³°èÇÏÁö + ¾Ê¾ÒÁö¸¸ ¾ÆÆÄÄ¡ 2.0Àº ½ÇÁ¦ ¸¹Àº °æ¿ì ³ôÀº ¼º´ÉÀ» ³½´Ù.

    + +

    ¾ÆÆÄÄ¡ 1.3°ú ºñ±³Çؼ­ 2.0 ¹öÀüÀº 󸮷®°ú È®À强(scalability)À» + ³ôÀ̱âÀ§ÇØ ¸¹Àº ÃÖÀûÈ­¸¦ Çß´Ù. ±âº»°ªÀ¸·Î ´ëºÎºÐ ÃÖÀûÈ­ÇÑ + °ªÀ» »ç¿ëÇÑ´Ù. ±×·¯³ª ÄÄÆÄÀϽà ȤÀº ½ÇÇà½Ã ¼³Á¤ÀÌ ¼º´É¿¡ + Å« ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ 2.0ÀÇ ¼º´ÉÀ» Çâ»óÇϱâÀ§ÇØ + ¼­¹ö °ü¸®ÀÚ°¡ ¼³Á¤ÇÒ ¼ö ÀÖ´Â ¿É¼ÇÀ» ¼³¸íÇÑ´Ù. ¾î¶² ¼³Á¤ + ¿É¼ÇÀº À¥¼­¹ö°¡ Çϵå¿þ¾î¿Í ¿î¿µÃ¼Á¦ÀÇ ±â´ÉÀ» ´õ Àß È°¿ëÇϵµ·Ï + ÇÏ´Â ¹Ý¸é, ¾î¶² ¿É¼ÇÀº ¼Óµµ¸¦ À§ÇØ ±â´ÉÀ» Èñ»ýÇÑ´Ù.

    + +
    + +
    + + Çϵå¿þ¾î¿Í ¿î¿µÃ¼Á¦¿¡ ´ëÇؼ­ + +

    À¥¼­¹ö ¼º´É¿¡ °¡Àå Å« ¿µÇâÀ» ÁÖ´Â °ÍÀº ¸Þ¸ð¸®´Ù. ½º¿ÒÀº + ¿äû´ç Áö¿¬½Ã°£À» »ç¿ëÀÚ°¡ "ÃæºÐÈ÷ ºü¸£´Ù°í" »ý°¢ÇÏÁö ¸øÇÏ°Ô + ´Ã¸®±â¶§¹®¿¡ À¥¼­¹ö´Â ½º¿ÒÀ» ÇÏ¸é ¾ÈµÈ´Ù. ´À·ÁÁö¸é »ç¿ëÀÚ´Â + Á¤ÁöÇÏ°í ´Ù½Ã Á¢¼ÓÇÏ¿© ºÎÇÏ°¡ °è¼Ó Áõ°¡ÇÑ´Ù. MaxClients Áö½Ã¾î¸¦ Á¶ÀýÇÏ¿© + À¥¼­¹ö°¡ ½º¿ÒÀ» ÇÒ Á¤µµ·Î ¸¹Àº ÀÚ½ÄÀ» ¸¸µéÁö¾Êµµ·Ï ÇØ¾ß + ÇÑ´Ù. ¹æ¹ýÀº °£´ÜÇÏ´Ù: top°ú °°Àº µµ±¸¿¡¼­ + ÇÁ·Î¼¼½º ¸ñ·ÏÀ» º¸°í ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½ºÀÇ Æò±Õ ¸Þ¸ð¸® »ç¿ë·®À» + ¾Ë¾Æ³½ÈÄ, Àüü »ç¿ë°¡´ÉÇÑ ¸Þ¸ð¸®¿¡¼­ ´Ù¸¥ ÇÁ·Î¼¼½ºµéÀÌ »ç¿ëÇÒ + °ø°£À» »« °ª¿¡¼­ ³ª´«´Ù.

    + +

    ³ª¸ÓÁö´Â Æò¹üÇÏ´Ù: ÃæºÐÈ÷ ºü¸¥ CPU, ÃæºÐÈ÷ ºü¸¥ ³×Æ®¿÷Ä«µå, + ÃæºÐÈ÷ ºü¸¥ µð½ºÅ©, ¿©±â¼­ "ÃæºÐÈ÷ ºü¸¥"Àº ½ÇÇèÀ» Çؼ­ °áÁ¤ÇØ¾ß + ÇÑ´Ù.

    + +

    ¿î¿µÃ¼Á¦´Â º¸Åë °¢ÀÚ ¾Ë¾Æ¼­ ¼±ÅÃÇÒ ÀÏÀÌ´Ù. ±×·¯³ª ÀϹÝÀûÀ¸·Î + À¯¿ëÇÏ´Ù°í ÆǸíµÈ ¸î°¡Áö ÁöħÀÌ ÀÖ´Ù:

    + +
      +
    • +

      ¼±ÅÃÇÑ ¿î¿µÃ¼Á¦ÀÇ ÃֽŠ¾ÈÁ¤ ¹öÀü°ú ÆÐÄ¡¸¦ ½ÇÇàÇÑ´Ù. + ¸¹Àº ¿î¿µÃ¼Á¦ Á¦ÀÛ»ç´Â ÃÖ±Ù TCP ½ºÅðú ¾²·¹µå ¶óÀ̺귯¸®¿¡ + ¸¹Àº ¼ÓµµÇâ»óÀ» Çß´Ù.

      +
    • + +
    • +

      ¿î¿µÃ¼Á¦°¡ sendfile(2) ½Ã½ºÅÛÈ£ÃâÀ» + Áö¿øÇÑ´Ù¸é, À̸¦ »ç¿ëÇϱâÀ§ÇÑ ¹öÀüÀ̳ª ÆÐÄ¡¸¦ ¼³Ä¡ÇÏ¿´´ÂÁö + È®ÀÎÇÑ´Ù. (¿¹¸¦ µé¾î, ¸®´ª½º¶ó¸é 2.4 ÀÌ»ó ¹öÀüÀ» ¶æÇÑ´Ù. + Solaris 8 Ãʱ⠹öÀüÀº ÆÐÄ¡°¡ ÇÊ¿äÇÏ´Ù.) Áö¿øÇÏ´Â ½Ã½ºÅÛÀ̶ó¸é + ¾ÆÆÄÄ¡ 2´Â sendfileÀ» »ç¿ëÇÏ¿© CPU¸¦ ´ú + »ç¿ëÇϸç Á¤Àû ÆÄÀÏÀ» ´õ »¡¸® Àü¼ÛÇÒ ¼ö ÀÕ´Ù.

      +
    • +
    + +
    + +
    + + ½ÇÇà½Ã ¼³Á¤¿¡ ´ëÇؼ­ + + + + mod_dir + mpm_common + mod_status + + + AllowOverride + DirectoryIndex + HostnameLookups + EnableMMAP + EnableSendfile + KeepAliveTimeout + MaxSpareServers + MinSpareServers + Options + StartServers + + + +
    + + HostnameLookups¿Í DNS¿¡ ´ëÇØ °í·ÁÇÒ Á¡µé + +

    ¾ÆÆÄÄ¡ 1.3 ÀÌÀü¿¡ HostnameLookupsÀÇ ±âº»°ªÀº + OnÀÌ¿´´Ù. ¿äûÀ» ¸¶Ä¡±âÀü¿¡ DNS °Ë»öÀÌ ³¡³ª¾ß + ÇϹǷΠ¿äû¸¶´Ù Áö¿¬ÀÌ »ý°å´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ÀÌ ¼³Á¤ÀÇ + ±âº»°ªÀÌ Off·Î º¯°æµÇ¾ú´Ù. ·Î±×ÆÄÀÏÀÇ ÁÖ¼Ò¸¦ + È£½ºÆ®¸íÀ¸·Î º¯È¯ÇÏ·Á¸é ¿©·¯ ·Î±×ó¸® ÇÁ·Î±×·¥Áß ÇϳªÀÎ, + ¾ÆÆÄÄ¡¿¡ Æ÷ÇÔµÈ logresolve + ÇÁ·Î±×·¥À» »ç¿ëÇ϶ó.

    + +

    ·Î±×ó¸® ÀÛ¾÷ÀÌ ¼­¹ö ¼º´É¿¡ ¾Ç¿µÇâÀ» ¹ÌÄ¡¹Ç·Î ½ÇÁ¦ + »ç¿ëÇÏ´Â À¥¼­¹ö°¡ ¾Æ´Ñ ´Ù¸¥ ÄÄÇ»ÅÍ¿¡¼­ ·Î±×ÆÄÀÏÀ» ÈÄó¸®Çϱæ + ¹Ù¶õ´Ù.

    + +

    Allow + from domainÀ̳ª Deny from domain + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù¸é (Áï, IP ÁÖ¼Ò°¡ ¾Æ´Ñ È£½ºÆ®¸íÀ̳ª µµ¸ÞÀθíÀ» + »ç¿ëÇÑ´Ù¸é) ºÎµæÀÌ Áߺ¹-¿ª DNS °Ë»öÀ» (¿ª°Ë»öÀ» ÇÑÈÄ ¾ÇÀÇ·Î + º¯°æµÇ¾ú´ÂÁö È®ÀÎÇϱâÀ§ÇØ ´Ù½Ã °Ë»ö) ÇØ¾ß ÇÑ´Ù. ±×·¯¹Ç·Î + ¼º´ÉÀ» ³ôÀ̱âÀ§ÇØ ÀÌ·± Áö½Ã¾î¿¡´Â °¡´ÉÇϸé À̸§´ë½Å IP + ÁÖ¼Ò¸¦ »ç¿ëÇÑ´Ù.

    + +

    <Location /server-status> ¼½¼Ç µîÀ¸·Î + Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ Á¦ÇÑÇÒ ¼ö ÀÖÀ½À» ±â¾ïÇ϶ó. ÀÌ °æ¿ì + Á¶°Ç¿¡ ¸Â´Â ¿äû¿¡¸¸ DNS Á¶È¸¸¦ ÇÑ´Ù. ´ÙÀ½Àº + .html°ú .cgi ÆÄÀϸ¸ DNS °Ë»öÀ» + ÇÏ´Â ¿¹Á¦´Ù:

    + + + HostnameLookups off
    + <Files ~ "\.(html|cgi)$">
    + + HostnameLookups on
    +
    + </Files> +
    + +

    ±×·¯³ª CGI¿¡¼­ DNS¸íÀÌ ÇÊ¿äÇÒ »ÓÀ̶ó¸é, ÇÊ¿äÇÑ Æ¯Á¤ + CGI¿¡¼­¸¸ gethostbyname È£ÃâÀ» Çϵµ·Ï °í·ÁÇغ¼ + ¼ö ÀÖ´Ù.

    + +
    + + + +
    + + AllowOverride + +

    URL °ø°£¿¡¼­ overrides¸¦ Çã¿ëÇÑ´Ù¸é (º¸Åë + .htaccess ÆÄÀÏ) ¾ÆÆÄÄ¡´Â ÆÄÀϸíÀÇ °¢ ºÎºÐ¸¶´Ù + .htaccess¸¦ ¿­±æ ½ÃµµÇÑ´Ù. ¿¹¸¦ µé¾î,

    + + + DocumentRoot /www/htdocs
    + <Directory />
    + + AllowOverride all
    +
    + </Directory> +
    + +

    /index.html URI¿¡ ´ëÇÑ ¿äûÀÌ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. + ¾ÆÆÄÄ¡´Â /.htaccess, /www/.htaccess, + /www/htdocs/.htaccess¸¦ ¿­·Á°í ½ÃµµÇÑ´Ù. + ÇØ°áÃ¥Àº ¾ÕÀÇ Options FollowSymLinks °æ¿ì¿Í + ºñ½ÁÇÏ´Ù. ÃÖ°íÀÇ ¼º´ÉÀ» ¾òÀ¸·Á¸é ÆÄÀϽýºÅÛ¿¡ ´ëÇؼ­ Ç×»ó + AllowOverride NoneÀ» »ç¿ëÇÑ´Ù.

    + +
    + +
    + + ³»¿ëÇù»ó + +

    °¡´ÉÇÏ°í ÁøÂ¥ Á¶±ÝÀÇ ¼º´ÉÇâ»ó¿¡µµ °ü½ÉÀÌ ÀÖ´Ù¸é ³»¿ëÇù»óÀ» + ¸·´Â´Ù. ½ÇÁ¦·Î Çù»óÀÇ À̵æÀº ¼º´ÉÀúÇϺ¸´Ù ÀÛ´Ù. ¼­¹ö¸¦ + ºü¸£°Ô ÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½°ú °°ÀÌ ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ´Â ´ë½Å:

    + + + DirectoryIndex index + + +

    ¿ÏÀüÇÑ ¸ñ·ÏÀ» »ç¿ëÇÑ´Ù:

    + + + DirectoryIndex index.cgi index.pl index.shtml index.html + + +

    °¡Àå ÈçÇÑ °ÍÀ» ¾Õ¿¡ µÐ´Ù.

    + +

    ¶Ç, µð·ºÅ丮¿¡¼­ ÆÄÀϵéÀ» ã´Â MultiViews + º¸´Ù´Â, ÇÑ ÆÄÀϸ¸ ÀÐÀ¸¸é ÇÊ¿äÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Â + type-map ÆÄÀÏÀ» Á÷Á¢ ¸¸µå´Â °ÍÀÌ ´õ ºü¸§À» + ¸í½ÉÇ϶ó.

    + +

    »çÀÌÆ®¿¡ ³»¿ëÇù»óÀÌ ÇÊ¿äÇÏ´Ù¸é Çù»óÀ» À§ÇØ Options + MultiViews Áö½Ã¾î¸¦ »ç¿ëÇϱ⺸´Ù type-map + ÆÄÀÏÀ» °í·ÁÇ϶ó. Çù»ó¹æ¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í°ú + type-map ÆÄÀÏÀ» ¸¸µå´Â ¹æ¹ýÀº ³»¿ëÇù»ó ¹®¼­¸¦ Âü°íÇ϶ó.

    + +
    + +
    + + ¸Þ¸ð¸®´ëÀÀ (memory-mapping) + +

    ¿¹¸¦ µé¾î, server-side-include¸¦ ó¸®ÇÏ´Â µî ¾ÆÆÄÄ¡ + 2.0ÀÌ Àü¼ÛÇÒ ÆÄÀÏÀ» ÀÐÀ»¶§ ¿î¿µÃ¼Á¦°¡ mmap(2) + µîÀ» Áö¿øÇÑ´Ù¸é ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÑ´Ù.

    + +

    ¿©·¯ Ç÷¡Æû¿¡¼­ ¸Þ¸ð¸®´ëÀÀÀ» ¼º´ÉÀ» Çâ»óÇÑ´Ù. ±×·¯³ª + ¸Þ¸ð¸®´ëÀÀÀÌ ¼­¹öÀÇ ¼º´ÉÀ» ¶³¾îÆ®¸®°í ½ÉÁö¾î ¾ÈÁ¤¼ºÀ» + ÇØÄ¡´Â °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    • +

      ¾î¶² ¿î¿µÃ¼Á¦¿¡¼­ mmapÀº CPU °³¼ö°¡ + ¸¹¾ÆÁú¶§ read(2) ¸¸Å­ È®À强ÀÌ ÁÁÁö ¾Ê´Ù. + ¿¹¸¦ µé¾î, ´ÙÁßÇÁ·Î¼¼¼­ Solaris ¼­¹ö¿¡¼­ ¾ÆÆÄÄ¡ 2.0Àº + Á¾Á¾ mmapÀ» »ç¿ëÇÏÁö ¾ÊÀ»¶§ ¼­¹ö°¡ ó¸®ÇÑ + ÆÄÀÏÀ» ´õ »¡¸® Àü¼ÛÇÑ´Ù.

      +
    • + +
    • +

      NFS ¸¶¿îÆ®ÇÑ ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÏ´Â + µµÁß¿¡ ´Ù¸¥ NFS Ŭ¶óÀ̾ðÆ®¿¡ ÀÖ´Â ÇÁ·Î¼¼½º°¡ ÆÄÀÏÀ» + Áö¿ì°Å³ª ÆÄÀÏÅ©±â¸¦ ÁÙÀ̸é, À¥¼­¹ö ÇÁ·Î¼¼½º°¡ ´ÙÀ½ + ¹ø¿¡ ¸Þ¸ð¸®´ëÀÀÇÑ ÆÄÀϳ»¿ëÀ» ÀÐÀ»¶§ bus error°¡ ¹ß»ýÇÒ + ¼ö ÀÖ´Ù.

      +
    • +
    + +

    À§ÀÇ Á¶°Ç¿¡ ÇØ´çÇϸé Àü¼ÛÇÏ´Â ÆÄÀÏÀ» ¸Þ¸ð¸®´ëÀÀÇÏÁö + ¾Êµµ·Ï EnableMMAP off¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. (ÁÖÀÇ: + ÀÌ Áö½Ã¾î´Â µð·ºÅ丮º°·Î º¯°æÇÒ ¼ö ÀÖ´Ù.)

    + +
    + +
    + + Sendfile + +

    ¾ÆÆÄÄ¡´Â ¿î¿µÃ¼Á¦°¡ sendfile(2)À» Áö¿øÇϸé + Ä¿³Î sendfileÀ» »ç¿ëÇÏ¿© -- ¿¹¸¦ µé¾î, Á¤Àû ÆÄÀÏÀ» ¼­ºñ½ºÇÒ¶§ + -- Àü¼ÛÇÒ ÆÄÀÏÀ» Á÷Á¢ ÀÐÁö¾ÊÀ» ¼ö ÀÖ´Ù.

    + +

    ¿©·¯ Ç÷¡Æû¿¡¼­ sendfileÀ» »ç¿ëÇϸé read¿Í send¸¦ µû·Î + ÇÒ ÇÊ¿ä°¡ ¾ø¾î¼­ »¡¶óÁø´Ù. ±×·¯³ª sendfileÀ» »ç¿ëÇϸé + À¥¼­¹öÀÇ ¾ÈÁ¤¼ºÀ» ÇØÄ¡°ÔµÇ´Â °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    • +

      sendfile Áö¿øÀÌ À߸øµÇ¾ú°í ÄÄÆÄÀÏ ½Ã½ºÅÛÀÌ ÀÌÁ¡À» + ¹ß°ßÇÏÁö ¸øÇÏ´Â Ç÷¡ÆûÀÌ ÀÖ´Ù. ƯÈ÷ ´Ù¸¥ ÄÄÇ»ÅÍ¿¡¼­ + ½ÇÇàÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ¿© sendfile Áö¿øÀÌ À߸øµÈ ÄÄÇ»ÅÍ·Î + °¡Á®¿Â °æ¿ì¿¡ °¡´ÉÇÏ´Ù.

      +
    • +
    • +

      Ä¿³ÎÀº ÀÚ½ÅÀÇ Ä³½¬¸¦ »ç¿ëÇÏ¿© NFS·Î ¸¶¿îÆ®ÇÑ ÆÄÀÏÀ» + ¾ÈÁ¤ÀûÀ¸·Î ¼­ºñ½ºÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ÀÖ´Ù.

      +
    • +
    + +

    À§ÀÇ Á¶°Ç¿¡ ÇØ´çÇϸé ÆÄÀÏÀ» sendfile Àü¼ÛÇÏÁö ¾Êµµ·Ï + EnableSendfile off¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. (ÁÖÀÇ: + ÀÌ Áö½Ã¾î´Â µð·ºÅ丮º°·Î º¯°æÇÒ ¼ö ÀÖ´Ù.)

    + +
    + +
    + + ÇÁ·Î¼¼½º »ý¼º + +

    ¾ÆÆÄÄ¡ 1.3 ÀÌÀü¿¡´Â MinSpareServers, MaxSpareServers, StartServers ¼³Á¤ÀÌ ¸ðµÎ + º¥Ä¡¸¶Å© °á°ú¿¡ Å« ¿µÇâÀ» ¹ÌÃÆ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡´Â ÀÛ¾÷À» + ¼­ºñ½ºÇϱâÀ§ÇØ ÃæºÐÇÑ Àڽļö¿¡ ´Ù´Ù¸¦ ¶§±îÁö "µµ´Þ" ±â°£ÀÌ + ÇÊ¿äÇß´Ù. óÀ½ StartServers°³ ÀÚ½ÄÀ» + ¸¸µçÈÄ, MinSpareServers + ¼³Á¤°ª±îÁö ÃÊ´ç ÀÚ½ÄÀ» Çϳª¾¿ ¸¸µé¾ú´Ù. ±×·¡¼­ StartServers ±âº»°ªÀÌ + 5ÀÎ ¼­¹ö¿¡ Ŭ¶óÀ̾ðÆ® 100°³°¡ µ¿½Ã¿¡ Á¢¼ÓÇϸé + ºÎÇϸ¦ ó¸®Çϱ⿡ ÃæºÐÇÑ ÀÚ½ÄÀ» ¸¸µé±â±îÁö 95ÃÊ°¡ °É·È´Ù. + ÀÚÁÖ Àç½ÃÀÛÇÏÁö ¾Ê´Â ½ÇÁ¦ ¼­¹ö¿¡¼­´Â Àß µ¿ÀÛÇÏÁö¸¸, 10ºÐ°£¸¸ + ½ÇÇàÇÏ´Â º¥Ä¡¸¶Å© °á°ú´Â ¸Å¿ì ³ª»Ú°Ô ³ª¿Â´Ù.

    + +

    ÃÊ´ç ÇÑ°³ ±ÔÄ¢Àº ÀÚ½ÄÀ» »õ·Î ½ÃÀÛÇϸ鼭 ¼­¹ö¿¡ ¹«¸®¸¦ + ÁÖÁö ¾ÊÀ¸·Á°í Á¤Çß´Ù. ÄÄÇ»ÅÍ°¡ ÀÚ½ÄÀ» ½ÃÀÛÇÏ´À¶ó ¹Ù»Ú¸é + ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ÀÌ ±ÔÄ¢ÀÌ ¾ÆÆÄÄ¡ÀÇ Ã¼°¨ + ¼º´É¿¡ ¾Ç¿µÇâÀ» ÁÖ¾î º¯°æÇÏ¿´´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ÃÊ´ç ÇÑ°³ + ±ÔÄ¢Àº ¿ÏÈ­µÇ¾ú´Ù. ÄÚµå´Â ÀÚ½Ä ÇÑ°³¸¦ ¸¸µé°í, 1ÃÊ ½¬°í, + µÎ°³¸¦ ¸¸µé°í, 1ÃÊ ½¬°í, ³×°³¸¦ ¸¸µé°í, ÀÌ·± ½ÄÀ¸·Î ÃÊ´ç + ÀÚ½ÄÀ» 32°³ ¸¸µé¶§±îÁö Áö¼ö·Î Áõ°¡ÇÑ´Ù. Àڽļö°¡ MinSpareServers ¼³Á¤¿¡ ´Ù´Ù¸£¸é + Áõ°¡¸¦ Áß´ÜÇÑ´Ù.

    + +

    ÀÌ °æ¿ì ¹ÝÀÀ¼Óµµ°¡ »¡¶óÁ®¼­ MinSpareServers, MaxSpareServers, StartServers¸¦ °ÅÀÇ ¼³Á¤ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ÀÏÃÊ¿¡ + ÀÚ½ÄÀ» 4°³ ÀÌ»ó »ý¼ºÇϸé ErrorLog¿¡ ±â·ÏÇÑ´Ù. ÀÌ·± ¿À·ù¹®ÀÌ + ¸¹ÀÌ º¸À̸é ÀÌ ¼³Á¤µéÀ» Á¶ÀýÇÏ±æ ¹Ù¶õ´Ù. + mod_status °á°ú°¡ µµ¿òÀÌ µÉ °ÍÀÌ´Ù.

    + +

    ÇÁ·Î¼¼½º »ý¼º°ú °ü·ÃÇÏ¿© MaxRequestsPerChild ¼³Á¤Àº + ÇÁ·Î¼¼½º¸¦ Á¾·áÇÑ´Ù. ±âº»°ªÀº ÀڽĴç ó¸®ÇÒ ¿äû¼ö¿¡ Á¦ÇÑÀÌ + ¾ø´Ù´Â 0ÀÌ´Ù. ÇöÀç ¼³Á¤ÀÌ 30°ú + °°ÀÌ ¸Å¿ì ÀÛÀº °ªÀ¸·Î ¼³Á¤µÇÀÖ´Ù¸é, °ªÀ» »ó´çÈ÷ ³ôÈú ÇÊ¿ä°¡ + ÀÖ´Ù. SunOS³ª ¿À·¡µÈ Solaris ¹öÀüÀ» »ç¿ëÇÑ´Ù¸é, ¸Þ¸ð¸®À¯Ã⶧¹®¿¡ + ÀÌ °ªÀ» 10000 Á¤µµ·Î ¼³Á¤Ç϶ó.

    + +

    ¿¬°áÀ¯Áö(keep-alive)¸¦ »ç¿ëÇÑ´Ù¸é ÀڽĵéÀº ÀÌ¹Ì ¿­¸° + ¿¬°á¿¡¼­ Ãß°¡ ¿äûÀ» ±â´Ù¸®¸ç ¾Æ¹«°Íµµ ÇÏÁö¾Ê±â¶§¹®¿¡ °è¼Ó + ¹Ù»Ú´Ù. KeepAliveTimeoutÀÇ + ±âº»°ª 15 ÃÊ´Â ÀÌ·± Çö»óÀ» ÃÖ¼ÒÈ­ÇÑ´Ù. ³×Æ®¿÷ + ´ë¿ªÆø°ú ¼­¹ö ÀÚ¿ø °£ÀÇ ±ÕÇüÀÌ ¸Â°Ô ¼³Á¤ÇÑ´Ù. + ¿¬°áÀ¯ÁöÀÇ ´ëºÎºÐÀÇ ÀÌÁ¡ÀÌ »ç¶óÁö±â¶§¹®¿¡ ¾î¶² °æ¿ì¿¡µµ + ÀÌ °ªÀ» 60 ÃÊ ÀÌ»óÀ¸·Î ¿Ã¸®Áö ¸¶¶ó.

    + +
    + +
    + +
    + + ÄÄÆÄÀϽà ¼³Á¤¿¡ ´ëÇؼ­ + +
    + + MPM ¼±Åà + +

    ¾ÆÆÄÄ¡ 2.x´Â ´ÙÁß󸮸ðµâ + (MPMs)À̶ó´Â ±³Ã¼ÇÒ ¼ö ÀÖ´Â µ¿±âÈ­ ¸ðµ¨À» Áö¿øÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÒ¶§ MPMÀ» ¼±ÅÃÇØ¾ß ÇÑ´Ù. beos, + mpm_netware, mpmt_os2, + mpm_winnt¿Í °°ÀÌ Æ¯Á¤ Ç÷¡Æû¿¡¼­¸¸ »ç¿ëÇÒ + ¼ö ÀÖ´Â MPMµµ ÀÖ´Ù. ÀϹÝÀûÀÎ À¯´Ð½º·ù ½Ã½ºÅÛÀº ¿©·¯ MPM + Áß¿¡ Çϳª¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. À¥¼­¹öÀÇ ¼Óµµ¿Í + È®À强(scalability)Àº ¾î¶² MPMÀ» ¼±ÅÃÇ߳Ŀ¡ ´Þ·È´Ù:

    + +
      + +
    • worker MPMÀº ¿©·¯ ÀÚ½Ä ÇÁ·Î¼¼½º°¡ + °¢°¢ ¿©·¯ ¾²·¹µå¸¦ »ç¿ëÇÑ´Ù. °¢ ¾²·¹µå´Â Çѹø¿¡ ÇÑ ¿¬°áÀ» + ´ã´çÇÑ´Ù. ÀϹÝÀûÀ¸·Î worker´Â prefork MPM º¸´Ù ÀûÀº + ¸Þ¸ð¸®¸¦ »ç¿ëÇϹǷΠÅë½Å·®ÀÌ ¸¹Àº ¼­¹ö¿¡ ÀûÀýÇÏ´Ù.
    • + +
    • prefork MPMÀº ¾²·¹µå°¡ ÇÑ°³ÀÎ ÀÚ½Ä + ÇÁ·Î¼¼½º¸¦ ¿©·¯°³ »ç¿ëÇÑ´Ù. °¢ ÇÁ·Î¼¼½º´Â Çѹø¿¡ ÇÑ + ¿¬°áÀ» ´ã´çÇÑ´Ù. ¿©·¯ ½Ã½ºÅÛ¿¡¼­ preforkÀÇ ¼Óµµ´Â worker¿Í + ºñ½ÁÇÏÁö¸¸, ´õ ¸¹Àº ¸Þ¸ð¸®¸¦ »ç¿ëÇÑ´Ù. ´ÙÀ½°ú °°Àº »óȲ¿¡¼­ + ¾²·¹µå¸¦ »ç¿ëÇÏÁö ¾Ê´Â prefork ¹æ½ÄÀÌ worker¿¡ ºñÇØ + ÀÌÁ¡À» °¡Áø´Ù: ¾²·¹µå¿¡ ¾ÈÀüÇÏÁö (thread-safe) ¾ÊÀº + Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» »ç¿ëÇÒ ¼ö ÀÖ°í, ¾²·¹µå µð¹ö±ë Áö¿øÀÌ + ºó¾àÇÑ Ç÷¡Æû¿¡¼­ ½±°Ô µð¹ö±ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    + +

    ÀÌ MPMµé°ú ´Ù¸¥ MPM¿¡ ´ëÇØ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â MPM ¹®¼­¸¦ Âü°íÇÏ±æ ¹Ù¶õ´Ù.

    + +
    + +
    + + ¸ðµâ + +

    ¸Þ¸ð¸® »ç¿ë·®ÀÌ ¼º´É¿¡¼­ °¡Àå Áß¿äÇÑ ¿äÀÎÀ̱⶧¹®¿¡ + ½ÇÁ¦·Î »ç¿ëÇÏÁö ¾Ê´Â ¸ðµâÀ» Á¦°ÅÇغ¸ÀÚ. ¸ðµâÀ» DSO·Î ÄÄÆÄÀÏÇß´Ù¸é °£´ÜÈ÷ ±× + ¸ðµâ¿¡ ´ëÇÑ LoadModule Áö½Ã¾î¸¦ ÁÖ¼®Ã³¸®Çϸé + µÈ´Ù. ±×·¡¼­ ¸ðµâÀ» Á¦°ÅÇÏ°í ½ÇÇàÇÏ¿© »çÀÌÆ®°¡ ¸ðµâ¾øÀ̵µ + Á¤»óÀûÀ¸·Î µ¿ÀÛÇÏ´ÂÁö »ìÆ캼 ¼ö ÀÖ´Ù.

    + +

    ¹Ý´ë·Î ¸ðµâÀÌ ¾ÆÆÄÄ¡ ½ÇÇàÆÄÀÏ¿¡ Á¤ÀûÀ¸·Î ¸µÅ©µÇÀÖ´Ù¸é + ¿øÇÏÁö ¾Ê´Â ¸ðµâÀ» Á¦°ÅÇϱâÀ§ÇØ ¾ÆÆÄÄ¡¸¦ ÀçÄÄÆÄÀÏÇØ¾ß + ÇÑ´Ù.

    + +

    ¿©±â¼­ ´ç¿¬È÷ ¾î¶² ¸ðµâÀ» »ç¿ëÇÏ°í »ç¿ëÇÏÁö ¸»Áö + Àǹ®ÀÌ »ý±ä´Ù. Á¤´äÀº À¥»çÀÌÆ®¸¶´Ù ´Ù¸£´Ù. ±×·¯³ª ¾Æ¸¶µµ + ÃÖ¼ÒÇÑ mod_mime, + mod_dir, mod_log_config + ¸ðµâÀº »ç¿ëÇÒ °ÍÀÌ´Ù. ¹°·Ð À¥»çÀÌÆ®¿¡ ·Î±×ÆÄÀÏÀÌ ÇÊ¿ä¾ø´Ù¸é + mod_log_config´Â ¾ø¾îµµ µÈ´Ù. ±×·¯³ª ÃßõÇÏÁö + ¾Ê´Â´Ù.

    + +
    + +
    + + Atomic ¸í·É + +

    mod_cache °°Àº ¸ðµâ°ú ÃÖ±Ù °³¹ßÁßÀÎ + worker MPMÀº APRÀÇ atomic API¸¦ »ç¿ëÇÑ´Ù. ÀÌ API´Â °æ·®±Þ + ¾²·¹µå µ¿±âÈ­¸¦ À§ÇÒ atomic ¸í·ÉÀ» Á¦°øÇÑ´Ù.

    + +

    ±âº»ÀûÀ¸·Î APRÀº °¢ ¿î¿µÃ¼Á¦/CPU Ç÷¡Æû¿¡¼­ °¡Àå È¿À²ÀûÀÎ + ¹æ¹ýÀ» »ç¿ëÇÏ¿© ÀÌ ¸í·ÉÀ» ±¸ÇöÇÑ´Ù. ¿¹¸¦ µé¾î, ¿©·¯ ÃֽŠ+ CPU¿¡´Â Çϵå¿þ¾î·Î atomic compare-and-swap (CAS) ¿¬»êÀ» + ÇÏ´Â ¸í·É¾î°¡ ÀÖ´Ù. ±×·¯³ª ¾î¶² Ç÷¡Æû¿¡¼­ APRÀº ÀÌ·± + ¸í·É¾î°¡ ¾ø´Â ¿À·¡µÈ CPU¿Í ȣȯ¼ºÀ» À§ÇØ ´õ ´À¸° mutex±â¹Ý + ±¸ÇöÀ» ±âº»ÀûÀ¸·Î »ç¿ëÇÑ´Ù. ÀÌ·± Ç÷¡Æû¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÒ¶§ ¾ÆÆÄÄ¡¸¦ ÃֽŠCPU¿¡¼­¸¸ ½ÇÇàÇÒ °èȹÀ̶ó¸é, + ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÒ¶§ --enable-nonportable-atomics + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ´õ ºü¸¥ atomic ±¸ÇöÀ» ¼±ÅÃÇÒ ¼ö ÀÖ´Ù:

    + + + ./buildconf
    + ./configure --with-mpm=worker --enable-nonportable-atomics=yes +
    + +

    --enable-nonportable-atomics ¿É¼ÇÀº ´ÙÀ½°ú + °°Àº Ç÷¡Æû¿¡ ¿µÇâÀÌ ÀÖ´Ù:

    + +
      + +
    • SPARC¿¡¼­ Solaris
      + ±âº»ÀûÀ¸·Î APRÀº Solaris/SPARC¿¡¼­ mutex±â¹Ý atomicÀ» + »ç¿ëÇÑ´Ù. ±×·¯³ª ±¸¼ºÇÒ¶§ + --enable-nonportable-atomics¸¦ »ç¿ëÇϸé + APRÀº ºü¸¥ Çϵå¿þ¾î compare-and-swapÀ» À§ÇÑ SPARC + v8plus ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé atomic + ¸í·ÉÀÌ ´õ È¿À²ÀûÀÌÁö¸¸ (CPU¸¦ ´ú »ç¿ëÇÏ°í ´õ ³ôÀº + µ¿±âÈ­°¡ °¡´ÉÇÏ´Ù), ÄÄÆÄÀÏÇÑ ½ÇÇàÆÄÀÏÀº UltraSPARC + Ĩ¿¡¼­¸¸ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. +
    • + +
    • Linux on x86
      + ±âº»ÀûÀ¸·Î APRÀº ¸®´ª½º¿¡¼­ mutex±â¹Ý atomicÀ» + »ç¿ëÇÑ´Ù. ±×·¯³ª ±¸¼ºÇÒ¶§ + --enable-nonportable-atomics¸¦ »ç¿ëÇϸé + APRÀº ºü¸¥ Çϵå¿þ¾î compare-and-swapÀ» À§ÇÑ 486 + ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. ´õ È¿À²ÀûÀÎ atomic ¸í·ÉÀÌ °¡´ÉÇÏÁö¸¸, + ÄÄÆÄÀÏÇÑ ½ÇÇàÆÄÀÏÀº 486 ÀÌ»ó Ĩ¿¡¼­¸¸ (386Àº ¾ÈµÈ´Ù) + ½ÇÇàÇÒ ¼ö ÀÖ´Ù. +
    • + +
    + +
    + +
    + + mod_status¿Í ExtendedStatus On + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ¶§ mod_status¸¦ Æ÷ÇÔÇÏ°í + ½ÇÇàÇÒ¶§ ExtendedStatus OnÀ» ¼³Á¤ÇÏ¸é ¾ÆÆÄÄ¡´Â + ¿äûÀ» ¹ÞÀ»¶§¸¶´Ù gettimeofday(2)(ȤÀº ¿î¿µÃ¼Á¦¿¡ + µû¶ó times(2))¸¦ µÎ¹ø È£ÃâÇÏ°í (1.3 ÀÌÀü¿¡´Â) + time(2)µµ Ãß°¡·Î ¿©·¯¹ø È£ÃâÇÑ´Ù. »óÅ º¸°í¼­¿¡ + µ¿À۽ð£ÀÌ ÇÊ¿äÇϱ⠶§¹®ÀÌ´Ù. ÃÖ»óÀÇ ¼º´ÉÀ» ¾òÀ¸·Á¸é + (±âº»°ªÀÎ) ExtendedStatus off¸¦ ¼³Á¤ÇÑ´Ù.

    + +
    + +
    + + accept Á÷·ÄÈ­ - ¿©·¯ ¼ÒÄÏ + + ÁÖÀÇ: +

    ¾Æ·¡ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» + ´ã°í ÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ + »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    +
    + +

    À¯´Ð½º ¼ÒÄÏ APIÀÇ ´ÜÁ¡À» ¼³¸íÇÑ´Ù. À¥¼­¹ö°¡ ¿©·¯ Æ÷Æ® + ȤÀº ¿©·¯ ÁÖ¼Ò¸¦ ±â´Ù¸®±âÀ§ÇØ ¿©·¯ ListenÀ» »ç¿ëÇÑ´Ù°í °¡Á¤ÇÏÀÚ. + ¿¬°áÀÌ °¡´ÉÇÑÁö °¢ ¼ÒÄÏÀ» °Ë»çÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â + select(2)¸¦ »ç¿ëÇÑ´Ù. select(2)´Â + ¼ÒÄÏ¿¡ ±â´Ù¸®°í ÀÖ´Â ¿¬°áÀÌ ¾ø´ÂÁö ȤÀº ÃÖ¼ÒÇÑ + ÇÑ°³ ÀÖ´ÂÁö ¾Ë·ÁÁØ´Ù. ¾ÆÆÄÄ¡¿¡´Â ¿©·¯ ÀÚ½ÄÀÌ ÀÖ°í, + ½¬°í ÀÖ´Â ¸ðµç ÀÚ½ÄÀº µ¿½Ã¿¡ »õ·Î¿î ¿¬°áÀ» °Ë»çÇÑ´Ù. ¿ø·¡ + ±¸ÇöÀº ´ÙÀ½°ú ºñ½ÁÇÏ´Ù (ÀÌ ¿¹´Â Äڵ忡¼­ °¡Á®¿ÀÁö ¾Ê¾Ò´Ù. + ´ÜÁö ¼³¸íÇϱâÀ§ÇÑ ¿ëµµ·Î ¸¸µé¾ú´Ù.):

    + + + for (;;) {
    + + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + process the new_connection;
    +
    + } +
    + +

    ±×·¯³ª À§ÀÇ ´Ü¼øÇÑ ±¸Çö¿¡´Â ½É°¢ÇÑ °í°¥(starvation) + ¹®Á¦°¡ ÀÖ´Ù. ¿©·¯ ÀÚ½ÄÀÌ µ¿½Ã¿¡ ÀÌ ¹Ýº¹¹®À» ½ÇÇàÇϸé, + ¿äûÀ» ±â´Ù¸®¸ç ¸ðµÎ select¿¡¼­ ¸ØÃá´Ù. À̶§ + ¾î¶² ¼ÒÄÏ¿¡ ¿äûÀÌ Çϳª¶óµµ µé¾î¿À¸é ¸ðµç ÀÚ½ÄÀÌ ±ú¾î³­´Ù + (±ú¾î³ª´Â ÀÚ½ÄÀÇ °³¼ö´Â ¿î¿µÃ¼Á¦¿Í ŸÀֿ̹¡ µû¶ó ´Ù¸£´Ù). + À̵éÀº ¸ðµÎ ¿¬°áÀ» acceptÇÏ±æ ½ÃµµÇÑ´Ù. ±×·¯³ª + (¾ÆÁ÷µµ ÇÑ ¿¬°á¸¸ ´ë±âÁßÀ̶ó¸é) ÇÑ Àڽĸ¸ ¼º°øÇÏ°í, ³ª¸ÓÁö´Â + accept¿¡¼­ ¸ØÃá´Ù. ±×·¯¸é ÀÌ ÀڽĵéÀº + ÇÑ ¼ÒÄÏÀÇ ¿äû¸¸À» ¼­ºñ½ºÇϵµ·Ï ¹­¿©¼­, ±× ¼ÒÄÏÀ¸·Î »õ·Î¿î + ¿äûÀÌ ÃæºÐÈ÷ µé¾î¿Í¼­ ¸ðµç ÀÚ½ÄÀ» ±ú¿ï¶§±îÁö Á¤ÁöÇØÀÖ´Ù. + ÀÌ·± °í°¥ ¹®Á¦´Â PR#467¿¡ + óÀ½ º¸°íµÇ¾ú´Ù. ÃÖ¼ÒÇÑ µÎ°¡Áö ÇØ°áÃ¥ÀÌ ÀÖ´Ù.

    + +

    ÇÑ°¡Áö´Â ¼ÒÄÏÀ» ´ë±âÇÏÁö ¾Êµµ·Ï (non-blocking) ¸¸µå´Â + ¹æ¹ýÀÌ´Ù. ÀÌ °æ¿ì ÀÚ½ÄÀÌ accept¸¦ Çصµ ¸ØÃßÁö + ¾Ê°í, Áï½Ã ÁøÇàÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª CPU ½Ã°£À» ³¶ºñÇÑ´Ù. + select¿¡¼­ ½¬´Â ÀÚ½ÄÀÌ 10°³ ÀÖ°í, »õ·Î ¿¬°áÀÌ + ÇÑ°³ µé¾î¿Ô´Ù°í °¡Á¤ÇÏÀÚ. ±×·¯¸é ÀÌ ÀÚ½ÄÁß 9°³´Â ±ú¾î³ª¼­ + ¿¬°áÀ» acceptÇÏ±æ ½ÃµµÇÏ°í ½ÇÆÐÇÏ¸é ¾Æ¹« + Àϵµ ÇÏÁö ¾Ê°í ´Ù½Ã select¸¦ ¹Ýº¹ÇÑ´Ù. ´Ù½Ã + select·Î µ¹¾Æ¿Ã ¶§±îÁö ¾î¶² Àڽĵµ ´Ù¸¥ ¼ÒÄÏ¿¡ + µé¾î¿Â ¿äûÀ» ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. (´ÙÁßÇÁ·Î¼¼¼­ ÄÄÇ»ÅÍ¿¡¼­) + ½¬´Â ÀÚ½Ä °³¼ö¸¸Å­ CPU °³¼ö°¡ ÀÖ´Â µå¹® °æ¿ì°¡ ¾Æ´Ï¶ó¸é + ÀÌ ÇØ°áÃ¥Àº º°·Î ÁÁ¾Æº¸ÀÌÁö ¾Ê´Â´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ¹æ¹ýÀ¸·Î ³»ºÎ ¹Ýº¹¹®¿¡ + ÇÑ Àڽĸ¸À» µé¿©º¸³½´Ù. ¹Ýº¹¹®Àº ´ÙÀ½°ú °°´Ù (Â÷À̸¦ + °­Á¶ÇßÀ½):

    + + + for (;;) {
    + + accept_mutex_on ();
    + for (;;) {
    + + fd_set accept_fds;
    +
    + FD_ZERO (&accept_fds);
    + for (i = first_socket; i <= last_socket; ++i) {
    + + FD_SET (i, &accept_fds);
    +
    + }
    + rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
    + if (rc < 1) continue;
    + new_connection = -1;
    + for (i = first_socket; i <= last_socket; ++i) {
    + + if (FD_ISSET (i, &accept_fds)) {
    + + new_connection = accept (i, NULL, NULL);
    + if (new_connection != -1) break;
    +
    + }
    +
    + }
    + if (new_connection != -1) break;
    +
    + }
    + accept_mutex_off ();
    + process the new_connection;
    +
    + } +
    + +

    accept_mutex_on°ú accept_mutex_off + ÇÔ¼ö´Â mutex ¼¼¸¶Æ÷¾î¸¦ + ±¸ÇöÇÑ´Ù. Çѹø¿¡ ¿ÀÁ÷ ÇÑ Àڽĸ¸ÀÌ mutex¸¦ °¡Áú ¼ö ÀÖ´Ù. + mutex¸¦ ±¸ÇöÇÏ´Â ¹æ¹ýÀº ¿©·¯°¡ÁöÀÌ´Ù. ±¸Çö ¹æ¹ýÀº (1.3 + ÀÌÀü) src/conf.h³ª (1.3°ú ±× ÀÌÈÄ) + src/include/ap_config.h¿¡ Á¤ÀǵÇÀÖ´Ù. ¾î¶² + ¾ÆÅ°ÅØÃÄ´Â Àá±Ý(locking) ¹æ¹ýÀ» ¼±ÅÃÇÏÁö ¾Ê±â¶§¹®¿¡, ÀÌ·± + ¾ÆÅ°ÅØÃÄ¿¡¼­ ¿©·¯ Listen Áö½Ã¾î¸¦ »ç¿ëÇϸé + À§ÇèÇÏ´Ù.

    + +

    ½ÇÇà½Ã AcceptMutex Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + mutex ±¸ÇöÀ» º¯°æÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    AcceptMutex flock
    + +
    +

    ÀÌ ¹æ¹ýÀº Àá±ÝÆÄÀÏÀ» Àá±×±âÀ§ÇØ flock(2) + ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù (Àá±ÝÆÄÀÏ À§Ä¡´Â LockFile Áö½Ã¾î·Î ÁöÁ¤).

    +
    + +
    AcceptMutex fcntl
    + +
    +

    ÀÌ ¹æ¹ýÀº Àá±ÝÆÄÀÏÀ» Àá±×±âÀ§ÇØ fcntl(2) + ½Ã½ºÅÛÈ£ÃâÀ» »ç¿ëÇÑ´Ù (Àá±ÝÆÄÀÏ À§Ä¡´Â LockFile Áö½Ã¾î·Î ÁöÁ¤).

    +
    + +
    AcceptMutex sysvsem
    + +
    +

    (1.3°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀ» SysV½Ä ¼¼¸¶Æ÷¾î¸¦ »ç¿ëÇÏ¿© + mutex¸¦ ±¸ÇöÇÑ´Ù. ºÒÇàÈ÷µµ SysV½Ä ¼¼¸¶Æ÷¾î´Â ³ª»Û + ºÎÀÛ¿ëÀÌ ÀÖ´Ù. Çϳª´Â ¾ÆÆÄÄ¡°¡ ¼¼¸¶Æ÷¾î¸¦ Á¤¸®ÇÏÁö + ¾Ê°í Á×À» ¼ö ÀÖ´Â Á¡ÀÌ´Ù (ipcs(8) manpage + Âü°í). ´Ù¸¥ Çϳª´Â À¥¼­¹ö¿Í µ¿ÀÏÇÑ uid·Î ½ÇÇàÇÏ´Â + CGI°¡ (Áï, suexec³ª + cgiwrapper¸¦ »ç¿ëÇÏÁö¾Ê´Â ÇÑ ¸ðµç CGI) + ¼¼¸¶Æ÷¾î API¸¦ »ç¿ëÇÏ¿© ¼­ºñ½º°ÅºÎ°ø°ÝÀ» ÇÒ ¼ö ÀÖ´Â + Á¡ÀÌ´Ù. ÀÌ·± ÀÌÀ¯¶§¹®¿¡ IRIX¸¦ Á¦¿ÜÇÑ ¾ÆÅ°ÅØÃÄ¿¡¼­ + ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù (´ëºÎºÐÀÇ IRIX ÄÄÇ»ÅÍ¿¡¼­ + ¾ÕÀÇ µÎ ¹æ¹ýÀº Áö³ªÄ¡°Ô ¹ö°Ì´Ù).

    +
    + +
    AcceptMutex pthread
    + +
    +

    (1.3°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀº POSIX mutex¸¦ »ç¿ëÇϱ⶧¹®¿¡ + POSIX ¾²·¹µå ±Ô¾àÀ» ¿ÏÀüÈ÷ ±¸ÇöÇÑ ¾ÆÅ°ÅØÃĶó¸é ¸ðµÎ + »ç¿ë°¡´ÉÇÏÁö¸¸, (2.5 ÀÌÈÄ) Solaris¿¡¼­¸¸ ±×°Íµµ ƯÁ¤ + ±¸¼º¿¡¼­¸¸ µ¿ÀÛÇÏ´Â µíÇÏ´Ù. ÀÌ ¹æ¹ýÀ» ½ÃµµÇغ»´Ù¸é + ¼­¹ö°¡ ¸ØÃç¼­ ÀÀ´äÀ» ¾ÈÇÏ´ÂÁö »ìÆìºÁ¾ß ÇÑ´Ù. Á¤Àû + ³»¿ë¸¸ ¼­ºñ½ºÇÏ´Â ¼­¹ö´Â Àß µ¿ÀÛÇÏ´Â °Í °°´Ù.

    +
    + +
    AcceptMutex posixsem
    + +
    +

    (2.0°ú ±× ÀÌÈÄ) ÀÌ ¹æ¹ýÀº POSIX ¼¼¸¶Æ÷¾î¸¦ »ç¿ëÇÑ´Ù. + mutex¸¦ °¡Áø ÇÁ·Î¼¼½ºÀÇ ¾²·¹µå°¡ Á״´ٸé(segfault) + ¼¼¸¶Æ÷¾î ¼ÒÀ¯±ÇÀÌ È¸º¹µÇÁö ¾Ê¾Æ¼­ À¥¼­¹ö°¡ ¸ØÃá´Ù.

    +
    + +
    + +

    ½Ã½ºÅÛ¿¡ À§ ¸ñ·Ï¿¡ ¾ø´Â Á÷·ÄÈ­(serialization) ¹æ¹ýÀÌ + ÀÖ´Ù¸é ±× ¹æ¹ýÀ» »ç¿ëÇÏ´Â Äڵ带 APR¿¡ Ãß°¡ÇÒ °¡Ä¡°¡ ÀÖ´Ù.

    + +

    °í·Á´Â ÇغÃÁö¸¸ ±¸ÇöÇÏÁö¾ÊÀº ´Ù¸¥ ¹æ¹ýÀº ºÎºÐÀûÀ¸·Î + ¹Ýº¹¹®À» Á÷·ÄÈ­ÇÏ´Â ¹æ¹ýÀÌ´Ù. Áï, ÇÁ·Î¼¼¼­¸¦ ¸î°³¸¸ µé¿©º¸³»´Â + °ÍÀÌ´Ù. ÀÌ ¹æ¹ýÀº ¿©·¯ ÀÚ½ÄÀ» µ¿½Ã¿¡ ½ÇÇàÇÒ ¼ö À־ + Á÷·ÄÈ­¶§¹®¿¡ Àüü ´ë¿ªÆøÀ» È°¿ëÇÏÁö ¸øÇÏ´Â ´ÙÁßÇÁ·Î¼¼¼­ + ÄÄÇ»ÅÍ¿¡¼­¸¸ °ü½ÉÀ» °¡Á®º¼ ¼ö ÀÖ´Ù. ¾ÕÀ¸·Î »ìÆ캼 ºÎºÐÀÌÁö¸¸, + ¸Å¿ì º´·ÄÈ­µÈ À¥¼­¹ö°¡ ÈçÇÏÁö ¾Ê¾Æ¼­ ¿ì¼±¼øÀ§°¡ ³·´Ù.

    + +

    ÃÖ»óÀÇ ¼º´ÉÀ» ¾ò±âÀ§Çؼ­´Â ¿©·¯ Listen ¹®À» »ç¿ëÇÏÁö ¾Ê´Â + °ÍÀÌ ÀÌ»óÀûÀÌ´Ù. ±×·¯³ª °è¼Ó ¼³¸íÇÑ´Ù.

    + +
    + +
    + + accept Á÷·ÄÈ­ - ¼ÒÄÏ ÇÑ°³ + +

    ¾ÕÀÇ ¼³¸íÀº ´ÙÁß¼ÒÄÏ ¼­¹ö¿¡´Â ÁÁÁö¸¸, ¼ÒÄÏÀÌ ÇÑ°³ÀÎ + ¼­¹ö´Â ¾î¶²°¡? ¿¬°áÀÌ µµÂøÇÒ¶§±îÁö ¸ðµç ÀÚ½ÄÀÌ + accept(2)¿¡¼­ ¸ØÃçÀֱ⶧¹®¿¡ ÀÌ·Ð»ó °°Àº + ¹®Á¦°¡ ¹ß»ýÇÏÁö ¾Ê°í, °í°¥ ¹®Á¦µµ ¾ø´Ù. ±×·¯³ª ½ÇÁ¦·Î´Â + ¾Õ¿¡¼­ ¸»ÇÑ ´ë±âÇÏÁö ¾Ê´Â (non-blocking) ¹æ¹ý¿¡¼­ ¹ß»ýÇÏ´Â + "°øȸÀü(spinning)" Çö»óÀ» °¨Ãß°í ÀÖ´Ù. ´ëºÎºÐÀÇ TCP ½ºÅÃÀº + ¿¬°áÀÌ µµÂøÇϸé Ä¿³ÎÀÌ accept¿¡¼­ ¸ØÃçÀÖ´Â + ¸ðµç ÀÚ½ÄÀ» ±ú¿ìµµ·Ï ±¸ÇöµÇÀÖ´Ù. ÇÁ·Î¼¼½ºÁß ÇÑ°³°¡ ¿¬°áÀ» + ¾ò°í »ç¿ëÀÚ¿µ¿ªÀ¸·Î µ¹¾Æ°¡°í, ³ª¸ÓÁö´Â Ä¿³Î¿¡¼­ °øȸÀüÇÏ¿© + ¿¬°áÀÌ ¾øÀ½À» ¹ß°ßÇÏ¸é ´Ù½Ã ÀáÀ» ÀÜ´Ù. »ç¿ëÀÚ¿µ¿ª Äڵ忡¼­´Â + ÀÌ·± °øȸÀüÀ» ¾Ë ¼ö ¾øÁö¸¸, ºÐ¸íÈ÷ Á¸ÀçÇÑ´Ù. ±×·¡¼­ ´ÙÁß¼ÒÄÏÀÇ + ´ë±âÇÏÁö ¾Ê´Â ¹æ¹ý°ú µ¿ÀÏÇÏ°Ô ºÎÇϸ¦ ³ôÀÌ´Â ºÒÇÊ¿äÇÑ ÇൿÀÌ + ÀϾ´Ù.

    + +

    ±×·¡¼­ ¿ì¸®´Â ¿©·¯ ¾ÆÅ°ÅØÃÄ¿¡¼­ ¼ÒÄÏÀÌ ÇÑ°³ÀÎ °æ¿ì¿¡µµ + Á÷·ÄÈ­ÇÏ¸é ´õ "Àß" µ¿ÀÛÇÔÀ» ¹ß°ßÇß´Ù. ±×·¡¼­ °ÅÀÇ ´ëºÎºÐÀÇ + °æ¿ì ±âº»ÀûÀ¸·Î Á÷·ÄÈ­¸¦ »ç¿ëÇÑ´Ù. ¸®´ª½º¿¡¼­ (Ä¿³Î 2.0.30, + 128Mb ¸Þ¸ð¸®¿¡ µà¾ó Pentium pro) ½ÇÇèÇÑ °á°ú ¼ÒÄÏ ÇÑ°³¸¦ + Á÷·ÄÈ­Çϸé ÇÏÁö ¾ÊÀº °æ¿ì¿¡ ºñÇØ ÃÊ´ç ¿äûÀÌ 3% ¹Ì¸¸ + ÁÙ¾îµé¾ú´Ù. ±×·¯³ª Á÷·ÄÈ­¸¦ ÇÏÁö ¾ÊÀº °æ¿ì ¿äû´ç 100ms + Áö¿¬ÀÌ ¹ß»ýÇß´Ù. ÀÌ Áö¿¬Àº ¾Æ¸¶µµ LAN¿¡¼­ ¹ß»ýÇÏ´Â ±ä + ¿¬°á¼±¶§¹®ÀÏ °ÍÀÌ´Ù. ¼ÒÄÏÀÌ ÇÑ°³ÀÎ °æ¿ì Á÷·ÄÈ­¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸·Á¸é SINGLE_LISTEN_UNSERIALIZED_ACCEPT¸¦ + Á¤ÀÇÇÑ´Ù.

    + +
    + +
    + + Close Áö¿¬(lingering) + +

    + draft-ietf-http-connection-00.txt 8Àý¿¡¼­ ¼³¸íÇϵíÀÌ + ¾ÈÁ¤ÀûÀÎ À¥¼­¹ö°¡ µÇ·Á¸é, Åë½ÅÀÇ ¾ç ¹æÇâÀ» + µ¶¸³ÀûÀ¸·Î ´ÝÀ» ¼ö ÀÖ¾î¾ß ÇÑ´Ù (TCP ¿¬°áÀº ½Ö¹æÇâÀÌ°í, + ¹æÇâÀº ¼­·Î µ¶¸³ÀûÀÌ´Ù). ÀÌÁ¡À» ´Ù¸¥ ¼­¹ö¿¡¼­´Â ÀÚÁÖ + °£°úÇÏÁö¸¸, ¾ÆÆÄÄ¡´Â 1.2ºÎÅÍ Á¤È®È÷ ±¸ÇöÇØ¿Ô´Ù.

    + +

    ÀÌ ±â´ÉÀ» ºÎÁÖÀÇÇÏ°Ô ¾ÆÆÄÄ¡¿¡ Ãß°¡ÇßÀ»¶§ ¿©·¯ À¯´Ð½º + ¹öÀü¿¡¼­ ¸¹Àº ¹®Á¦°¡ ¹ß»ýÇß´Ù. TCP ±Ô¾àÀº + FIN_WAIT_2¿¡ ŸÀӾƿôÀÌ ÀÖ´Ù°í Á¤ÇÏÁö ¾Ê¾ÒÁö¸¸, + ±ÝÁöÇÏÁöµµ ¾Ê¾Ò´Ù. ŸÀӾƿôÀÌ ¾ø´Â ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡ 1.2´Â + ¸¹Àº ¼ÒÄÏÀ» ¿µ¿øÈ÷ FIN_WAIT_2 »óÅ·Π¸¸µé¾ú´Ù. + ¸¹Àº °æ¿ì ÀÌ ¹®Á¦´Â Á¦Àۻ簡 Á¦°øÇÏ´Â ÃֽŠTCP/IP ÆÐÄ¡¸¦ + Àû¿ëÇÏ¿© ÇØ°áÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Á¦Àۻ簡 ÆÐÄ¡¸¦ ¹ßÇ¥ÇÏÁö + ¾Ê´Â °æ¿ì°¡ (Áï, SunOS4 -- ¼Ò½º ¶óÀ̼±½º°¡ ÀÖ´Â + »ç¶÷Àº Á÷Á¢ ÆÐÄ¡ÇÒ ¼ö ÀÖÁö¸¸) Àֱ⶧¹®¿¡ ÀÌ ±â´ÉÀ» »ç¿ëÇÏÁö + ¾Ê±â·Î °áÁ¤Çß´Ù.

    + +

    ¹æ¹ýÀº µÎ°¡Áö´Ù. Çϳª´Â ¼ÒÄÏ ¿É¼Ç SO_LINGER¸¦ + »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. ±×·¯³ª ºÒÇàÈ÷µµ ´ëºÎºÐÀÇ TCP/IP ½ºÅÃÀº + ÀÌ ¿É¼ÇÀ» ¿Ã¹Ù·Î ±¸ÇöÇÏÁö ¾Ê¾Ò´Ù. ¿Ã¹Ù·Î ±¸ÇöÇÑ ½ºÅÿ¡¼­ + Á¶Â÷µµ (Áï, ¸®´ª½º 2.0.31) ÀÌ ¹æ¹ýÀº ´ÙÀ½ ¹æ¹ýº¸´Ù + ´õ cpu¸¦ Àâ¾Æ¸Ô´Â´Ù.

    + +

    ¾ÆÆÄÄ¡´Â º¸Åë (http_main.c¿¡ ÀÖ´Â) + lingering_close¶ó´Â ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ ÇÔ¼ö´Â + ´ëÃæ ´ÙÀ½°ú °°´Ù:

    + + + void lingering_close (int s)
    + {
    + + char junk_buffer[2048];
    +
    + /* shutdown the sending side */
    + shutdown (s, 1);
    +
    + signal (SIGALRM, lingering_death);
    + alarm (30);
    +
    + for (;;) {
    + + select (s for reading, 2 second timeout);
    + if (error) break;
    + if (s is ready for reading) {
    + + if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
    + + break;
    +
    + }
    + /* just toss away whatever is here */
    +
    + }
    +
    + }
    +
    + close (s);
    +
    + } +
    + +

    ÀÌ ÄÚµå´Â ¿¬°áÀ» ´ÝÀ»¶§ ´õ CPU¸¦ »ç¿ëÇÏÁö¸¸, ¾ÈÁ¤ÀûÀÎ + ±¸ÇöÀ» À§ÇØ ÇÊ¿äÇÏ´Ù. HTTP/1.1ÀÌ ´õ ³Î¸® ÆÛÁö°í ¸ðµç ¿¬°áÀ» + À¯ÁöÇÑ´Ù¸é(persistent), ¿¬°áÀ» ¹Þ´Â ºñ¿ëÀº ¿©·¯ ¿äûÀ» + ó¸®Çϸ鼭 »ó¼âµÉ °ÍÀÌ´Ù. À§ÇèÇÏ°Ôµµ + NO_LINGCLOSE¸¦ Á¤ÀÇÇÏ¿© ÀÌ ±â´ÉÀ» »ç¿ëÇÏÁö + ¾ÊÀ» ¼ö ÀÖÁö¸¸, Àý´ë·Î ±ÇÇÏÁö ¾Ê´Â´Ù. ƯÈ÷ HTTP/1.1 + ÆÄÀÌÇÁ¶óÀÎ ¿¬°áÀ¯Áö »óÅ¿¡¼­ ÀÀ´äÀ» ±â´Ù¸®Áö + ¾Ê°í ¿©·¯ ¿äûÀ» º¸³»´Â ±â¼ú ¿¬°áÀ¯Áö¿¡´Â + lingering_close°¡ ÇʼöÀûÀÌ´Ù (±×¸®°í + ÆÄÀÌÇÁ¶óÀÎ ¿¬°áÀÌ ´õ ºü¸£±â¶§¹®¿¡ »ç¿ëÇÏ±æ ¹Ù¶ö °ÍÀÌ´Ù).

    + +
    + +
    + + Scoreboard ÆÄÀÏ + +

    ¾ÆÆÄÄ¡ÀÇ ºÎ¸ð¿Í ÀÚ½ÄÀº scoreboard¶ó´Â °ÍÀ» ÅëÇØ ¼­·Î + Åë½ÅÇÑ´Ù. ÀÌ»óÀûÀ¸·Î´Â scoreboard¸¦ °øÀ¯¸Þ¸ð¸®·Î ±¸ÇöÇØ¾ß + ÇÑ´Ù. ¿ì¸® °³¹ßÀÚ°¡ ÇØ´ç ¿î¿µÃ¼Á¦¿¡ Á¢±ÙÇÒ ¼ö Àְųª »ó¼¼ÇÑ + Æ÷Æà °á°ú¸¦ ¹ÞÀº °æ¿ì º¸Åë °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÏ¿© ±¸ÇöÇÑ´Ù. + ³ª¸ÓÁö´Â µð½ºÅ©¿¡ ÀÖ´Â ÆÄÀÏÀ» »ç¿ëÇÏ¿© ±¸ÇöÇÑ´Ù. µð½ºÅ©¿¡ + ÀÖ´Â ÆÄÀÏÀº ´À¸®°í ½Å·Úµµ°¡ ¶³¾îÁø´Ù (±â´Éµµ ´õ Àû´Ù). + src/main/conf.h ÆÄÀÏ¿¡¼­ »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃĸ¦ + ã¾Æ¼­ USE_MMAP_SCOREBOARD ȤÀº + USE_SHMGET_SCOREBOARDÀÎÁö È®ÀÎÇÑ´Ù. µÑÁß + Çϳª¸¦ (°¢°¢ ÇÔ²² »ç¿ëÇÒ HAVE_MMAPÀ̳ª + HAVE_SHMGETµµ °°ÀÌ) Á¤ÀÇÇÏ¸é °øÀ¯¸Þ¸ð¸® Äڵ带 + »ç¿ëÇÑ´Ù. ½Ã½ºÅÛÀÌ ´Ù¸¥ Á¾·ùÀÇ °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÑ´Ù¸é + src/main/http_main.c ÆÄÀÏÀ» ¼öÁ¤ÇÏ¿© ¾ÆÆÄÄ¡¿¡¼­ + °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÈÅ(hook)À» Ãß°¡Ç϶ó. (¶ÇÇÑ + ÆÐÄ¡¸¦ ¿ì¸®¿¡°Ô º¸³»ÁÖ±æ ¹Ù¶õ´Ù.)

    + + ¿ª»çÀû ¼³¸í: ¾ÆÆÄÄ¡ÀÇ ¸®´ª½º ¹öÀüÀº ¾ÆÆÄÄ¡ 1.2 ¹öÀüºÎÅÍ + °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇϱ⠽ÃÀÛÇß´Ù. ¸®´ª½º¿¡¼­ Ãʱ⠾ÆÆÄÄ¡ + ¹öÀüÀÌ ´À¸®°í ½Å·Úµµ°¡ ¶³¾îÁ³±â ¶§¹®ÀÌ´Ù. + +
    + +
    + + DYNAMIC_MODULE_LIMIT + +

    ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÌÁö ¾Ê´Â´Ù¸é (°¡´ÉÇÑ Á¶±ÝÀÌ¶óµµ + ¼º´ÉÀ» ³ôÀ̱âÀ§ÇØ ÀÌ ±ÛÀ» ÀÐ´Â´Ù¸é ¾Æ¸¶µµ ¸ðµâÀ» µ¿ÀûÀ¸·Î + ÀоîµéÀÌÁö ¾ÊÀ» °ÍÀÌ´Ù), ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ + -DDYNAMIC_MODULE_LIMIT=0À» Ãß°¡ÇÑ´Ù. ±×·¯¸é + ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀ̱âÀ§ÇØ ÇÒ´çÇÏ´Â ¸Þ¸ð¸®¸¦ Àý¾àÇÑ´Ù.

    + +
    + +
    + +
    + + ºÎ·Ï: ½Ã½ºÅÛÈ£Ãâ ±â·ÏÀ» ÀÚ¼¼È÷ ºÐ¼®Çϱâ + +

    ´ÙÀ½Àº Solaris 8¿¡¼­ worker MPMÀ» »ç¿ëÇÑ ¾ÆÆÄÄ¡ 2.0.38ÀÇ + ½Ã½ºÅÛÈ£Ãâ ±â·Ï(trace)ÀÌ´Ù. ¾Æ·¡ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© ±â·ÏÀ» + ¾ò¾ú´Ù:

    + + + truss -l -p httpd_child_pid. + + +

    -l ¿É¼ÇÀ» »ç¿ëÇϸé truss´Â ½Ã½ºÅÛÈ£ÃâÀ» + ÇÏ´Â LWP (lightweight process, °æ·®±Þ ÇÁ·Î¼¼½º--SolarisÀÇ + Ä¿³Î¼öÁØ ¾²·¹µå) ID¸¦ °°ÀÌ ±â·ÏÇÑ´Ù.

    + +

    ´Ù¸¥ ½Ã½ºÅÛ¿¡´Â strace, ktrace, + par °°Àº ½Ã½ºÅÛÈ£Ãâ ÃßÀû µµ±¸°¡ ÀÖ´Ù. °á°ú´Â + ºñ½ÁÇÏ´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®´Â À¥¼­¹ö¿¡°Ô Å©±â°¡ 10KBÀÎ Á¤Àû ÆÄÀÏÀ» ¿äûÇÑ´Ù. + Á¤ÀûÀÎ ÆÄÀÏÀ» ¿äûÇÏÁö ¾Ê°Å³ª ³»¿ëÇù»óÇÏ´Â ¿äûÀ» ÇÑ °æ¿ì + ±â·ÏÀÌ ¸Å¿ì ´Ù¸£´Ù (¶§·Î´Â ¸Å¿ì ¾Ë¾Æº¸±â Èûµé´Ù).

    + + +
    /67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
    +/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9
    +
    + +

    À§¿¡¼­ ¿¬°á´ë±â(listener) ¾²·¹µå°¡ LWP #67¿¡¼­ ½ÇÇàµÊÀ» + ¾Ë ¼ö ÀÖ´Ù.

    + + accept(2) Á÷·ÄÈ­¸¦ »ç¿ëÇÏÁö ¾ÊÀ½À» ÁÖ¸ñÇ϶ó. + ¿©·¯ Æ÷Æ®¸¦ ±â´Ù¸®Áö¾Ê´Â °æ¿ì ÀÌ Ç÷¡ÆûÀÇ worker MPMÀº + ±âº»ÀûÀ¸·Î Á÷·ÄÈ­ÇÏÁö ¾ÊÀº accept¸¦ »ç¿ëÇÑ´Ù. + + +
    /65:    lwp_park(0x00000000, 0)                         = 0
    +/67:    lwp_unpark(65, 1)                               = 0
    +
    + +

    ¿¬°áÀº ¹Þ¾ÆµéÀÌ°í(accept) ¿¬°á´ë±â ¾²·¹µå´Â + worker ¾²·¹µå¸¦ ±ú¿ö¼­ ¿äûÀ» ó¸®ÇÏ°Ô ÇÑ´Ù. ¾Æ·¡ ±â·Ï¿¡¼­ + ¿äûÀ» ó¸®ÇÏ´Â worker ¾²·¹µå°¡ LWP #65ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù.

    + + +
    /65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0
    +
    + +

    °¡»óÈ£½ºÆ®¸¦ ±¸ÇöÇϱâÀ§ÇØ ¾ÆÆÄÄ¡´Â ¿¬°áÀ» ¹Þ¾ÆµéÀÎ + Áö¿ª(local) ¼ÒÄÏ ÁÖ¼Ò¸¦ ¾Ë¾Æ¾ß ÇÑ´Ù. (°¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏÁö + ¾Ê°Å³ª Listen + Áö½Ã¾î¿¡ ¿ÍÀϵåÄ«µå ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì µî) ¸¹Àº °æ¿ì + ÀÌ È£ÃâÀ» ¾ø¾Ù ¼ö ÀÖ´Ù. ±×·¯³ª ¾ÆÁ÷ ÀÌ·± ÃÖÀûÈ­ ÀÛ¾÷ÀÌ + ¾ÈµÇÀÖ´Ù.

    + + +
    /65:    brk(0x002170E8)                                 = 0
    +/65:    brk(0x002190E8)                                 = 0
    +
    + +

    brk(2) È£ÃâÀº Èü(heap)¿¡¼­ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. + À¥¼­¹ö´Â ´ëºÎºÐÀÇ ¿äû 󸮽à ÀÚü ¸Þ¸ð¸® + ÇÒ´çÀÚ(apr_pool°ú apr_bucket_alloc)¸¦ + »ç¿ëÇϱ⶧¹®¿¡ ½Ã½ºÅÛÈ£Ãâ ±â·Ï¿¡¼­ ÀÌ ½Ã½ºÅÛÈ£ÃâÀ» º¸±â°¡ + µå¹°´Ù. ÀÌ ±â·Ï¿¡¼­ À¥¼­¹ö´Â ½ÃÀÛÇÏÀÚ¸¶ÀÚ ÀÚü ¸Þ¸ð¸® ÇÒ´çÀÚ°¡ + »ç¿ëÇÒ ¸Þ¸ð¸®ºí·ÏÀ» ¾ò±âÀ§ÇØ malloc(3)À» È£ÃâÇÑ´Ù.

    + + +
    /65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
    +/65:    fstat64(9, 0xFAF7B818)                          = 0
    +/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
    +/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
    +/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0
    +
    + +

    ´ÙÀ½ worker ¾²·¹µå´Â Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á(ÆÄÀϱâ¼úÀÚ 9)À» + ´ë±â¾ÈÇÔ(non-blocking) »óÅ·Π¹Ù²Û´Ù. setsockopt(2)¿Í + getsockopt(2) È£ÃâÀº SolarisÀÇ libc°¡ ¼ÒÄÏ¿¡ + ´ëÇÑ fcntl(2)À» ¾î¶»°Ô ó¸®ÇÏ´ÂÁö º¸¿©ÁØ´Ù.

    + + +
    /65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97
    +
    + +

    worker ¾²·¹µå´Â Ŭ¶óÀ̾ðÆ®·Î ºÎÅÍ ¿äûÀ» Àд´Ù.

    + + +
    /65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
    +/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10
    +
    + +

    À¥¼­¹ö ¼³Á¤Àº Options FollowSymLinks¿Í + AllowOverride NoneÀÌ´Ù. ±×·¡¼­ ¿äûÇÑ ÆÄÀÏ°æ·ÎÀÇ + °¢ µð·ºÅ丮¿¡ ´ëÇØ lstat(2)Çϰųª + .htaccess ÆÄÀÏÀ» °Ë»çÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ÆÄÀÏÀ» + °Ë»çÇϱâÀ§ÇØ, 1) ÆÄÀÏÀÌ ÀÖ´ÂÁö, 2) µð·ºÅ丮°¡ ¾Æ´Ñ ÀϹÝÆÄÀÏÀÎÁö, + stat(2) È£Ã⸸ ÇÏ¸é µÈ´Ù.

    + + +
    /65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269
    +
    + +

    ÀÌ °æ¿ì À¥¼­¹ö´Â ÇѹøÀÇ sendfilev(2) ½Ã½ºÅÛÈ£Ãâ·Î + HTTP ÀÀ´äÇì´õ¿Í ¿äûÇÑ ÆÄÀÏÀ» Àü¼ÛÇÒ ¼ö ÀÖ´Ù. Sendfile Áö¿ø¿©ºÎ´Â + ¿î¿µÃ¼Á¦¸¶´Ù ´Ù¸£´Ù. ´Ù¸¥ ½Ã½ºÅÛÀ̶ó¸é sendfile(2)À» + È£ÃâÇϱâ Àü¿¡ Çì´õ¸¦ º¸³»±âÀ§ÇØ write(2)³ª + writev(2) È£ÃâÀ» ÇÑ´Ù.

    + + +
    /65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78
    +
    + +

    write(2) È£ÃâÀº Á¢±Ù·Î±×(access log)¿¡ ¿äûÀ» + ±â·ÏÇÑ´Ù. ÀÌ ±â·Ï¿¡ time(2) È£ÃâÀÌ ¾øÀ½À» ÁÖ¸ñÇ϶ó. + ¾ÆÆÄÄ¡ 1.3°ú ´Þ¸® ¾ÆÆÄÄ¡ 2.0Àº ½Ã°£À» ¾Ë±âÀ§ÇØ + gettimeofday(3)¸¦ »ç¿ëÇÑ´Ù. + gettimeofday¸¦ ÃÖÀûÈ­ÇÑ ¸®´ª½º¿Í Solaris °°Àº + ¸î¸î ¿î¿µÃ¼Á¦¿¡¼­´Â ÀϹÝÀûÀÎ ½Ã½ºÅÛÈ£Ã⠺δãÀÌ ¾ø´Ù.

    + + +
    /65:    shutdown(9, 1, 1)                               = 0
    +/65:    poll(0xFAF7B980, 1, 2000)                       = 1
    +/65:    read(9, 0xFAF7BC20, 512)                        = 0
    +/65:    close(9)                                        = 0
    +
    + +

    worker ¾²·¹µå´Â ¿¬°áÀ» Áö¿¬´Ý±â(lingering close)ÇÑ´Ù.

    + + +
    /65:    close(10)                                       = 0
    +/65:    lwp_park(0x00000000, 0)         (sleeping...)
    +
    + +

    ¸¶Áö¸·À¸·Î worker ¾²·¹µå´Â ¹æ±Ý Àü¼ÛÇÑ ÆÄÀÏÀ» ´Ý°í, + ¿¬°á´ë±â(listener) ¾²·¹µå°¡ ´Ù¸¥ ¿¬°áÀ» ÇÒ´çÇÒ ¶§±îÁö + Á¤ÁöÇÑ´Ù.

    + + +
    /67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)
    +
    + +

    ±×µ¿¾È ¿¬°á´ë±â ¾²·¹µå´Â ¿¬°áÀ» (¸ðµç worker°¡ ÀÛ¾÷ÁßÀ̸é + ¿¬°á´ë±â ¾²·¹µå¸¦ ¸ØÃß´Â worker MPMÀÇ È帧Á¦¾î ±â´É¿¡ µû¶ó) + worker ¾²·¹µå¿¡ ÇÒ´çÇÏÀÚ¸¶ÀÚ ´Ù¸¥ ¿¬°áÀ» ¹Þ¾ÆµéÀÏ ¼ö ÀÖ´Ù. + ÀÌ ±â·Ï¿¡´Â ³ª¿ÀÁö ¾ÊÁö¸¸, worker ¾²·¹µå°¡ ¹æ±Ý ¹ÞÀº ¿¬°áÀ» + ó¸®ÇÏ´Â µ¿¾È ´ÙÀ½ accept(2)°¡ (¿äûÀÌ ¸Å¿ì + ¸¹Àº °æ¿ì Ç×»ó) ÀϾ ¼ö ÀÖ´Ù.

    + +
    + +
    + diff --git a/trunk/docs/manual/misc/perf-tuning.xml.meta b/trunk/docs/manual/misc/perf-tuning.xml.meta new file mode 100644 index 0000000000..e05e0d1787 --- /dev/null +++ b/trunk/docs/manual/misc/perf-tuning.xml.meta @@ -0,0 +1,12 @@ + + + + perf-tuning + /misc/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/misc/relevant_standards.html b/trunk/docs/manual/misc/relevant_standards.html new file mode 100644 index 0000000000..ca9e9006c3 --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.html @@ -0,0 +1,7 @@ +URI: relevant_standards.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: relevant_standards.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/misc/relevant_standards.html.en b/trunk/docs/manual/misc/relevant_standards.html.en new file mode 100644 index 0000000000..6d58e62a89 --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.html.en @@ -0,0 +1,199 @@ + + + +Relevant Standards - Apache HTTP Server + + + + + +
    <-
    +

    Relevant Standards

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    This page documents all the relevant standards that the + Apache HTTP Server follows, along with brief descriptions.

    + +

    In addition to the information listed below, the following resources + should be consulted:

    + + + +

    Notice

    +

    This document is not yet complete.

    +
    + +
    + +
    top
    +
    +

    HTTP Recommendations

    + +

    Regardless of what modules are compiled and used, Apache as a + basic web server complies with the following IETF recommendations:

    + +
    +
    RFC 1945 + (Informational)
    + +
    The Hypertext Transfer Protocol (HTTP) is an application-level + protocol with the lightness and speed necessary for distributed, + collaborative, hypermedia information systems. This documents + HTTP/1.0.
    + +
    RFC 2616 + (Standards Track)
    + +
    The Hypertext Transfer Protocol (HTTP) is an + application-level protocol for distributed, collaborative, + hypermedia information systems. This documents HTTP/1.1.
    + +
    RFC 2396 + (Standards Track)
    + +
    A Uniform Resource Identifier (URI) is a compact string of + characters for identifying an abstract or physical resource.
    +
    + +
    top
    +
    +

    HTML Recommendations

    + +

    Regarding the Hypertext Markup Language, Apache complies with + the following IETF and W3C recommendations:

    + +
    +
    RFC 2854 + (Informational)
    + +
    This document summarizes the history of HTML development, + and defines the "text/html" MIME type by pointing to the relevant + W3C recommendations.
    + +
    HTML 4.01 Specification + (Errata) +
    + +
    This specification defines the HyperText Markup Language (HTML), + the publishing language of the World Wide Web. This specification + defines HTML 4.01, which is a subversion of HTML 4.
    + +
    HTML 3.2 Reference + Specification
    + +
    The HyperText Markup Language (HTML) is a simple markup language + used to create hypertext documents that are portable from one + platform to another. HTML documents are SGML documents.
    + +
    XHTML 1.1 - + Module-based XHTML + (Errata) +
    + +
    This Recommendation defines a new XHTML document type + that is based upon the module framework and modules defined in + Modularization of XHTML.
    + +
    XHTML 1.0 The + Extensible HyperText Markup Language (Second Edition) + (Errata) +
    + +
    This specification defines the Second Edition of XHTML 1.0, + a reformulation of HTML 4 as an XML 1.0 application, and three + DTDs corresponding to the ones defined by HTML 4.
    +
    + +
    top
    +
    +

    Authentication

    + +

    Concerning the different methods of authentication, Apache + follows the following IETF recommendations:

    + +
    +
    RFC 2617 + (Draft standard)
    + +
    "HTTP/1.0", includes the specification for a Basic + Access Authentication scheme.
    + +
    + +
    top
    +
    +

    Language/Country Codes

    + +

    The following links document ISO and other language and country + code information:

    + +
    +
    ISO 639-2
    + +
    ISO 639 provides two sets of language codes, one as a two-letter + code set (639-1) and another as a three-letter code set (this part + of ISO 639) for the representation of names of languages.
    + +
    + ISO 3166-1
    + +
    These pages document the country names (official short names + in English) in alphabetical order as given in ISO 3166-1 and the + corresponding ISO 3166-1-alpha-2 code elements.
    + +
    BCP 47 + (Best Current Practice), + RFC 3066
    + +
    This document describes a language tag for use in cases where + it is desired to indicate the language used in an information + object, how to register values for use in this language tag, + and a construct for matching such language tags.
    + +
    RFC 3282 + (Standards Track)
    + +
    This document defines a "Content-language:" header, for use in + cases where one desires to indicate the language of something that + has RFC 822-like headers, like MIME body parts or Web documents, + and an "Accept-Language:" header for use in cases where one wishes + to indicate one's preferences with regard to language.
    +
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/relevant_standards.html.ko.euc-kr b/trunk/docs/manual/misc/relevant_standards.html.ko.euc-kr new file mode 100644 index 0000000000..e626cc9a36 --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.html.ko.euc-kr @@ -0,0 +1,191 @@ + + + +°ü·Ã Ç¥ÁØ - Apache HTTP Server + + + + + +
    <-
    +

    °ü·Ã Ç¥ÁØ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + +

    ÀÌ ¹®¼­¿¡´Â °£´ÜÇÑ ¼³¸í°ú ÇÔ²² ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ µû¸£´Â + ¸ðµç °ü·Ã Ç¥ÁØÀ» ¿­°ÅÇÑ´Ù.

    + +

    ¾Æ·¡ Á¤º¸¿¡ ´õÇÏ¿© ´ÙÀ½ ÀÚ·áµµ »ìÆìºÁ¾ß ÇÑ´Ù:

    + + + +

    ÁÖÀÇ

    +

    ÀÌ ¹®¼­´Â ¾ÆÁ÷ ¿ÏÀüÇÏÁö ¾Ê´Ù.

    +
    + +
    + +
    top
    +
    +

    HTTP ±Ç°í

    + +

    ¾î¶² ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í »ç¿ëÇÏ´ÂÁö¿Í °ü°è¾øÀÌ ±âº»ÀûÀ¸·Î + À¥¼­¹öÀÎ ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í(recommendation)¸¦ µû¸¥´Ù:

    + +
    +
    RFC 1945 + (Informational)
    + +
    ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (Hypertext Transfer Protocol, + HTTP)Àº ºÐ»ê, Çùµ¿, ÇÏÀÌÆÛ¸Åü Á¤º¸ ½Ã½ºÅÛ¿¡ ÇÊ¿äÇÑ ºü¸£°í + °¡º­¿î ¾îÇø®ÄÉÀÌ¼Ç ¼öÁØ(application-level) ÇÁ·ÎÅäÄÝÀÌ´Ù. + ÀÌ ¹®¼­´Â HTTP/1.0À» ¼³¸íÇÑ´Ù.
    + +
    RFC 2616 + (Standards Track)
    + +
    ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (Hypertext Transfer Protocol, + HTTP)Àº ºÐ»ê, Çùµ¿, ÇÏÀÌÆÛ¸Åü Á¤º¸ ½Ã½ºÅÛÀ» À§ÇÑ ¾îÇø®ÄÉÀÌ¼Ç + ¼öÁØ ÇÁ·ÎÅäÄÝÀÌ´Ù. ÀÌ ¹®¼­´Â HTTP/1.1À» ¼³¸íÇÑ´Ù.
    + +
    RFC 2396 + (Standards Track)
    + +
    Ç¥ÁØ ÀÚ¿ø ½Äº°ÀÚ (Uniform Resource Identifier, URI)´Â + Ãß»óÀû ȤÀº ¹°¸®Àû ÀÚ¿øÀ» ½Äº°ÇϱâÀ§ÇÑ ÂªÀº ¹®ÀÚ¿­ÀÌ´Ù.
    +
    + +
    top
    +
    +

    HTML ±Ç°í

    + +

    ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Hypertext Markup Language, + HTML)¿Í °ü·ÃÇÏ¿© ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í¿Í W3C ±Ç°í¸¦ µû¸¥´Ù:

    + +
    +
    RFC 2854 + (Informational)
    + +
    ÀÌ ¹®¼­´Â HTML °³¹ß°úÁ¤À» ¿ä¾àÇÏ°í, °ü·Ã W3C ±Ç°í¸¦ + ±â¹ÝÀ¸·Î "text/html" MIME typeÀ» Á¤ÀÇÇÑ´Ù.
    + +
    HTML 4.01 ±Ô¾à + (Errata) +
    + +
    ÀÌ ±Ô¾àÀº ¿ùµå¿ÍÀ̵åÀ¥ÀÇ ÃâÆǾð¾îÀÎ ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ + ¾ð¾î (Hypertext Markup Language, HTML)¸¦ Á¤ÀÇÇÑ´Ù. ÀÌ + ±Ô¾àÀº HTML 4ÀÇ ÇÏÀ§¹öÀüÀÎ HTML 4.01À» Á¤ÀÇÇÑ´Ù.
    + +
    HTML 3.2 Âü°í ±Ô¾à
    + +
    ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Hypertext Markup Language, + HTML)´Â Ç÷¡Æû°ú ¹«°üÇÑ ÇÏÀÌÆÛÅؽºÆ® ¹®¼­¸¦ À§ÇÑ °£´ÜÇÑ + ¸¶Å©¾÷ ¾ð¾îÀÌ´Ù. HTML ¹®¼­´Â SGML ¹®¼­À̱⵵ ÇÏ´Ù.
    + +
    XHTML 1.1 - + ¸ðµâ±â¹Ý XHTML + (Á¤¿ÀÇ¥) +
    + +
    ÀÌ ±Ç°í´Â Modularization of XHTML¿¡¼­ Á¤ÀÇÇÑ ¸ðµâ + Ç÷¹ÀÓ¿öÅ©¿Í ¸ðµâµéÀ» ±â¹ÝÀ¸·Î »õ·Î¿î XHTML document typeÀ» + Á¤ÀÇÇÑ´Ù.
    + +
    XHTML 1.0 + È®Àå ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Extensible HyperText Markup + Language) (Second Edition) + (Á¤¿ÀÇ¥) +
    + +
    ÀÌ ¹®¼­´Â HTML 4¸¦ XML 1.0À¸·Î À籸¼ºÇÑ XHTML 1.0ÀÇ + µÎ¹ø° ¹öÀü°ú HTML 4¿¡ ÇØ´çÇÏ´Â ¼¼°¡Áö DTD¸¦ Á¤ÀÇÇÑ´Ù.
    +
    + +
    top
    +
    +

    ÀÎÁõ

    + +

    ÀÎÁõ¹æ¹ý¿¡ ´ëÇØ ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í¸¦ µû¸¥´Ù:

    + +
    +
    RFC 2617 + (Draft standard)
    + +
    Basic Access Authentication ±Ô¾àÀ» Æ÷ÇÔÇÑ "HTTP/1.0".
    + +
    + +
    top
    +
    +

    ¾ð¾î/±¹°¡ ÄÚµå

    + +

    ¾Æ·¡ ¸µÅ©¿¡ ISO¿Í ´Ù¸¥ ¾ð¾î/±¹°¡ ÄÚµå Á¤º¸°¡ ÀÖ´Ù:

    + +
    +
    ISO 639-2
    + +
    ISO 639´Â ¾ð¾îÀÇ À̸§À» ³ªÅ¸³»´Â µÎ°¡Áö ¾ð¾î Äڵ带 + Á¦°øÇÑ´Ù. Çϳª´Â (639-1) µÎ ±ÛÀÚ ÄÚµåÀÌ°í ´Ù¸¥ Çϳª´Â + (ÀÌ ¹®¼­) ¼¼ ±ÛÀÚ ÄÚµåÀÌ´Ù.
    + +
    + ISO 3166-1
    + +
    ÀÌ ¹®¼­´Â ISO 3166-1°ú ISO 3166-1-alpha-2 Äڵ忡 µû¶ó + ¾ËÆĺª ¼ø¼­·Î (¿µ¾î·Î ªÀº °ø½ÄÀ̸§) ±¹°¡¸íÀ» ¿­°ÅÇÑ´Ù.
    + +
    BCP 47 + (Best Current Practice), + RFC 3066
    + +
    ÀÌ ¹®¼­´Â Á¤º¸ °´Ã¼¿¡ »ç¿ëÇÑ ¾ð¾î¸¦ ¾Ë¸®±âÀ§ÇØ »ç¿ëÇÒ + ¾ð¾î ÅÂ±×¿Í ¾ð¾î ű׿¡ »ç¿ëÇÒ °ªÀ» µî·ÏÇÏ´Â ¹æ¹ý, ¾ð¾î + ű׸¦ ã´Â ¹æ½ÄÀ» ¼³¸íÇÑ´Ù.
    + +
    RFC 3282 + (Standards Track)
    + +
    ÀÌ ¹®¼­´Â MIME ³»¿ë ºÎºÐ°ú À¥ ¹®¼­¿Í °°Àº RFC 822½Ä + Çì´õ°¡ ÀÖ´Â Á¤º¸ÀÇ ¾ð¾î¸¦ ¾Ë¸®±âÀ§ÇÑ "Content-language:" + Çì´õ¿Í, ¼±È£ÇÏ´Â ¾ð¾î¸¦ ³ªÅ¸³»´Â "Accept-Language:" Çì´õ¸¦ + Á¤ÀÇÇÑ´Ù.
    +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/relevant_standards.xml b/trunk/docs/manual/misc/relevant_standards.xml new file mode 100644 index 0000000000..87c47749ea --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.xml @@ -0,0 +1,192 @@ + + + + + + + + + Miscellaneous Documentation + + Relevant Standards + + +

    This page documents all the relevant standards that the + Apache HTTP Server follows, along with brief descriptions.

    + +

    In addition to the information listed below, the following resources + should be consulted:

    + + + + Notice +

    This document is not yet complete.

    +
    + +
    + +
    HTTP Recommendations + +

    Regardless of what modules are compiled and used, Apache as a + basic web server complies with the following IETF recommendations:

    + +
    +
    RFC 1945 + (Informational)
    + +
    The Hypertext Transfer Protocol (HTTP) is an application-level + protocol with the lightness and speed necessary for distributed, + collaborative, hypermedia information systems. This documents + HTTP/1.0.
    + +
    RFC 2616 + (Standards Track)
    + +
    The Hypertext Transfer Protocol (HTTP) is an + application-level protocol for distributed, collaborative, + hypermedia information systems. This documents HTTP/1.1.
    + +
    RFC 2396 + (Standards Track)
    + +
    A Uniform Resource Identifier (URI) is a compact string of + characters for identifying an abstract or physical resource.
    +
    + +
    + +
    HTML Recommendations + +

    Regarding the Hypertext Markup Language, Apache complies with + the following IETF and W3C recommendations:

    + +
    +
    RFC 2854 + (Informational)
    + +
    This document summarizes the history of HTML development, + and defines the "text/html" MIME type by pointing to the relevant + W3C recommendations.
    + +
    HTML 4.01 Specification + (Errata) +
    + +
    This specification defines the HyperText Markup Language (HTML), + the publishing language of the World Wide Web. This specification + defines HTML 4.01, which is a subversion of HTML 4.
    + +
    HTML 3.2 Reference + Specification
    + +
    The HyperText Markup Language (HTML) is a simple markup language + used to create hypertext documents that are portable from one + platform to another. HTML documents are SGML documents.
    + +
    XHTML 1.1 - + Module-based XHTML + (Errata) +
    + +
    This Recommendation defines a new XHTML document type + that is based upon the module framework and modules defined in + Modularization of XHTML.
    + +
    XHTML 1.0 The + Extensible HyperText Markup Language (Second Edition) + (Errata) +
    + +
    This specification defines the Second Edition of XHTML 1.0, + a reformulation of HTML 4 as an XML 1.0 application, and three + DTDs corresponding to the ones defined by HTML 4.
    +
    + +
    + +
    Authentication + +

    Concerning the different methods of authentication, Apache + follows the following IETF recommendations:

    + +
    +
    RFC 2617 + (Draft standard)
    + +
    "HTTP/1.0", includes the specification for a Basic + Access Authentication scheme.
    + +
    + +
    + +
    Language/Country Codes + +

    The following links document ISO and other language and country + code information:

    + +
    +
    ISO 639-2
    + +
    ISO 639 provides two sets of language codes, one as a two-letter + code set (639-1) and another as a three-letter code set (this part + of ISO 639) for the representation of names of languages.
    + +
    + ISO 3166-1
    + +
    These pages document the country names (official short names + in English) in alphabetical order as given in ISO 3166-1 and the + corresponding ISO 3166-1-alpha-2 code elements.
    + +
    BCP 47 + (Best Current Practice), + RFC 3066
    + +
    This document describes a language tag for use in cases where + it is desired to indicate the language used in an information + object, how to register values for use in this language tag, + and a construct for matching such language tags.
    + +
    RFC 3282 + (Standards Track)
    + +
    This document defines a "Content-language:" header, for use in + cases where one desires to indicate the language of something that + has RFC 822-like headers, like MIME body parts or Web documents, + and an "Accept-Language:" header for use in cases where one wishes + to indicate one's preferences with regard to language.
    +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/relevant_standards.xml.ko b/trunk/docs/manual/misc/relevant_standards.xml.ko new file mode 100644 index 0000000000..b4458d8415 --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.xml.ko @@ -0,0 +1,184 @@ + + + + + + + + + Miscellaneous Documentation + + °ü·Ã Ç¥ÁØ + + +

    ÀÌ ¹®¼­¿¡´Â °£´ÜÇÑ ¼³¸í°ú ÇÔ²² ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ µû¸£´Â + ¸ðµç °ü·Ã Ç¥ÁØÀ» ¿­°ÅÇÑ´Ù.

    + +

    ¾Æ·¡ Á¤º¸¿¡ ´õÇÏ¿© ´ÙÀ½ ÀÚ·áµµ »ìÆìºÁ¾ß ÇÑ´Ù:

    + + + + ÁÖÀÇ +

    ÀÌ ¹®¼­´Â ¾ÆÁ÷ ¿ÏÀüÇÏÁö ¾Ê´Ù.

    +
    + +
    + +
    HTTP ±Ç°í + +

    ¾î¶² ¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í »ç¿ëÇÏ´ÂÁö¿Í °ü°è¾øÀÌ ±âº»ÀûÀ¸·Î + À¥¼­¹öÀÎ ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í(recommendation)¸¦ µû¸¥´Ù:

    + +
    +
    RFC 1945 + (Informational)
    + +
    ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (Hypertext Transfer Protocol, + HTTP)Àº ºÐ»ê, Çùµ¿, ÇÏÀÌÆÛ¸Åü Á¤º¸ ½Ã½ºÅÛ¿¡ ÇÊ¿äÇÑ ºü¸£°í + °¡º­¿î ¾îÇø®ÄÉÀÌ¼Ç ¼öÁØ(application-level) ÇÁ·ÎÅäÄÝÀÌ´Ù. + ÀÌ ¹®¼­´Â HTTP/1.0À» ¼³¸íÇÑ´Ù.
    + +
    RFC 2616 + (Standards Track)
    + +
    ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (Hypertext Transfer Protocol, + HTTP)Àº ºÐ»ê, Çùµ¿, ÇÏÀÌÆÛ¸Åü Á¤º¸ ½Ã½ºÅÛÀ» À§ÇÑ ¾îÇø®ÄÉÀÌ¼Ç + ¼öÁØ ÇÁ·ÎÅäÄÝÀÌ´Ù. ÀÌ ¹®¼­´Â HTTP/1.1À» ¼³¸íÇÑ´Ù.
    + +
    RFC 2396 + (Standards Track)
    + +
    Ç¥ÁØ ÀÚ¿ø ½Äº°ÀÚ (Uniform Resource Identifier, URI)´Â + Ãß»óÀû ȤÀº ¹°¸®Àû ÀÚ¿øÀ» ½Äº°ÇϱâÀ§ÇÑ ÂªÀº ¹®ÀÚ¿­ÀÌ´Ù.
    +
    + +
    + +
    HTML ±Ç°í + +

    ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Hypertext Markup Language, + HTML)¿Í °ü·ÃÇÏ¿© ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í¿Í W3C ±Ç°í¸¦ µû¸¥´Ù:

    + +
    +
    RFC 2854 + (Informational)
    + +
    ÀÌ ¹®¼­´Â HTML °³¹ß°úÁ¤À» ¿ä¾àÇÏ°í, °ü·Ã W3C ±Ç°í¸¦ + ±â¹ÝÀ¸·Î "text/html" MIME typeÀ» Á¤ÀÇÇÑ´Ù.
    + +
    HTML 4.01 ±Ô¾à + (Errata) +
    + +
    ÀÌ ±Ô¾àÀº ¿ùµå¿ÍÀ̵åÀ¥ÀÇ ÃâÆǾð¾îÀÎ ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ + ¾ð¾î (Hypertext Markup Language, HTML)¸¦ Á¤ÀÇÇÑ´Ù. ÀÌ + ±Ô¾àÀº HTML 4ÀÇ ÇÏÀ§¹öÀüÀÎ HTML 4.01À» Á¤ÀÇÇÑ´Ù.
    + +
    HTML 3.2 Âü°í ±Ô¾à
    + +
    ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Hypertext Markup Language, + HTML)´Â Ç÷¡Æû°ú ¹«°üÇÑ ÇÏÀÌÆÛÅؽºÆ® ¹®¼­¸¦ À§ÇÑ °£´ÜÇÑ + ¸¶Å©¾÷ ¾ð¾îÀÌ´Ù. HTML ¹®¼­´Â SGML ¹®¼­À̱⵵ ÇÏ´Ù.
    + +
    XHTML 1.1 - + ¸ðµâ±â¹Ý XHTML + (Á¤¿ÀÇ¥) +
    + +
    ÀÌ ±Ç°í´Â Modularization of XHTML¿¡¼­ Á¤ÀÇÇÑ ¸ðµâ + Ç÷¹ÀÓ¿öÅ©¿Í ¸ðµâµéÀ» ±â¹ÝÀ¸·Î »õ·Î¿î XHTML document typeÀ» + Á¤ÀÇÇÑ´Ù.
    + +
    XHTML 1.0 + È®Àå ÇÏÀÌÆÛÅؽºÆ® ¸¶Å©¾÷ ¾ð¾î (Extensible HyperText Markup + Language) (Second Edition) + (Á¤¿ÀÇ¥) +
    + +
    ÀÌ ¹®¼­´Â HTML 4¸¦ XML 1.0À¸·Î À籸¼ºÇÑ XHTML 1.0ÀÇ + µÎ¹ø° ¹öÀü°ú HTML 4¿¡ ÇØ´çÇÏ´Â ¼¼°¡Áö DTD¸¦ Á¤ÀÇÇÑ´Ù.
    +
    + +
    + +
    ÀÎÁõ + +

    ÀÎÁõ¹æ¹ý¿¡ ´ëÇØ ¾ÆÆÄÄ¡´Â ´ÙÀ½ IETF ±Ç°í¸¦ µû¸¥´Ù:

    + +
    +
    RFC 2617 + (Draft standard)
    + +
    Basic Access Authentication ±Ô¾àÀ» Æ÷ÇÔÇÑ "HTTP/1.0".
    + +
    + +
    + +
    ¾ð¾î/±¹°¡ ÄÚµå + +

    ¾Æ·¡ ¸µÅ©¿¡ ISO¿Í ´Ù¸¥ ¾ð¾î/±¹°¡ ÄÚµå Á¤º¸°¡ ÀÖ´Ù:

    + +
    +
    ISO 639-2
    + +
    ISO 639´Â ¾ð¾îÀÇ À̸§À» ³ªÅ¸³»´Â µÎ°¡Áö ¾ð¾î Äڵ带 + Á¦°øÇÑ´Ù. Çϳª´Â (639-1) µÎ ±ÛÀÚ ÄÚµåÀÌ°í ´Ù¸¥ Çϳª´Â + (ÀÌ ¹®¼­) ¼¼ ±ÛÀÚ ÄÚµåÀÌ´Ù.
    + +
    + ISO 3166-1
    + +
    ÀÌ ¹®¼­´Â ISO 3166-1°ú ISO 3166-1-alpha-2 Äڵ忡 µû¶ó + ¾ËÆĺª ¼ø¼­·Î (¿µ¾î·Î ªÀº °ø½ÄÀ̸§) ±¹°¡¸íÀ» ¿­°ÅÇÑ´Ù.
    + +
    BCP 47 + (Best Current Practice), + RFC 3066
    + +
    ÀÌ ¹®¼­´Â Á¤º¸ °´Ã¼¿¡ »ç¿ëÇÑ ¾ð¾î¸¦ ¾Ë¸®±âÀ§ÇØ »ç¿ëÇÒ + ¾ð¾î ÅÂ±×¿Í ¾ð¾î ű׿¡ »ç¿ëÇÒ °ªÀ» µî·ÏÇÏ´Â ¹æ¹ý, ¾ð¾î + ű׸¦ ã´Â ¹æ½ÄÀ» ¼³¸íÇÑ´Ù.
    + +
    RFC 3282 + (Standards Track)
    + +
    ÀÌ ¹®¼­´Â MIME ³»¿ë ºÎºÐ°ú À¥ ¹®¼­¿Í °°Àº RFC 822½Ä + Çì´õ°¡ ÀÖ´Â Á¤º¸ÀÇ ¾ð¾î¸¦ ¾Ë¸®±âÀ§ÇÑ "Content-language:" + Çì´õ¿Í, ¼±È£ÇÏ´Â ¾ð¾î¸¦ ³ªÅ¸³»´Â "Accept-Language:" Çì´õ¸¦ + Á¤ÀÇÇÑ´Ù.
    +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/relevant_standards.xml.meta b/trunk/docs/manual/misc/relevant_standards.xml.meta new file mode 100644 index 0000000000..063e5b05bc --- /dev/null +++ b/trunk/docs/manual/misc/relevant_standards.xml.meta @@ -0,0 +1,12 @@ + + + + relevant_standards + /misc/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/misc/rewriteguide.html b/trunk/docs/manual/misc/rewriteguide.html new file mode 100644 index 0000000000..01caef1379 --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.html @@ -0,0 +1,7 @@ +URI: rewriteguide.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: rewriteguide.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/misc/rewriteguide.html.en b/trunk/docs/manual/misc/rewriteguide.html.en new file mode 100644 index 0000000000..ab8cb1863c --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.html.en @@ -0,0 +1,2102 @@ + + + +URL Rewriting Guide - Apache HTTP Server + + + + + +
    <-
    +

    URL Rewriting Guide

    +
    +

    Available Languages:  en  | + ko 

    +
    + +
    +

    Originally written by
    + Ralf S. Engelschall <rse@apache.org>
    + December 1997

    +
    + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonly confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + +
    + +
    top
    +
    +

    Introduction to mod_rewrite

    + + + +

    The Apache module mod_rewrite is a killer + one, i.e. it is a really sophisticated module which provides + a powerful way to do URL manipulations. With it you can do nearly + all types of URL manipulations you ever dreamed about. + The price you have to pay is to accept complexity, because + mod_rewrite's major drawback is that it is + not easy to understand and use for the beginner. And even + Apache experts sometimes discover new aspects where + mod_rewrite can help.

    + +

    In other words: With mod_rewrite you either + shoot yourself in the foot the first time and never use it again + or love it for the rest of your life because of its power. + This paper tries to give you a few initial success events to + avoid the first case by presenting already invented solutions + to you.

    + +
    top
    +
    +

    Practical Solutions

    + + + +

    Here come a lot of practical solutions I've either invented + myself or collected from other people's solutions in the past. + Feel free to learn the black magic of URL rewriting from + these examples.

    + +
    ATTENTION: Depending on your server-configuration + it can be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. It + avoid problems.
    + +
    top
    +
    +

    URL Layout

    + + + +

    Canonical URLs

    + + + +
    +
    Description:
    + +
    +

    On some webservers there are more than one URL for a + resource. Usually there are canonical URLs (which should be + actually used and distributed) and those which are just + shortcuts, internal ones, etc. Independent of which URL the + user supplied with the request he should finally see the + canonical one only.

    +
    + +
    Solution:
    + +
    +

    We do an external HTTP redirect for all non-canonical + URLs to fix them in the location view of the Browser and + for all subsequent requests. In the example ruleset below + we replace /~user by the canonical + /u/user and fix a missing trailing slash for + /u/user.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + + + +

    Canonical Hostnames

    + + + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + + + +

    Moved DocumentRoot

    + + + +
    +
    Description:
    + +
    +

    Usually the DocumentRoot + of the webserver directly relates to the URL "/". + But often this data is not really of top-level priority, it is + perhaps just one entity of a lot of data pools. For instance at + our Intranet sites there are /e/www/ + (the homepage for WWW), /e/sww/ (the homepage for + the Intranet) etc. Now because the data of the DocumentRoot stays at /e/www/ we had + to make sure that all inlined images and other stuff inside this + data pool work for subsequent requests.

    +
    + +
    Solution:
    + +
    +

    We redirect the URL / to + /e/www/: +

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /e/www/  [R]
    +
    + +

    Note that this can also be handled using the RedirectMatch directive:

    + +

    + RedirectMatch ^/$ http://example.com/e/www/ +

    +
    +
    + + + +

    Trailing Slash Problem

    + + + +
    +
    Description:
    + +
    +

    Every webmaster can sing a song about the problem of + the trailing slash on URLs referencing directories. If they + are missing, the server dumps an error, because if you say + /~quux/foo instead of /~quux/foo/ + then the server searches for a file named + foo. And because this file is a directory it + complains. Actually it tries to fix it itself in most of + the cases, but sometimes this mechanism need to be emulated + by you. For instance after you have done a lot of + complicated URL rewritings to CGI scripts etc.

    +
    + +
    Solution:
    + +
    +

    The solution to this subtle problem is to let the server + add the trailing slash automatically. To do this + correctly we have to use an external redirect, so the + browser correctly requests subsequent images etc. If we + only did a internal rewrite, this would only work for the + directory page, but would go wrong when any images are + included into this page with relative URLs, because the + browser would request an in-lined object. For instance, a + request for image.gif in + /~quux/foo/index.html would become + /~quux/image.gif without the external + redirect!

    + +

    So, to do this trick we write:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    The crazy and lazy can even do the following in the + top-level .htaccess file of their homedir. + But notice that this creates some processing + overhead.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + + + +

    Webcluster through Homogeneous URL Layout

    + + + +
    +
    Description:
    + +
    +

    We want to create a homogeneous and consistent URL + layout over all WWW servers on a Intranet webcluster, i.e. + all URLs (per definition server local and thus server + dependent!) become actually server independent! + What we want is to give the WWW namespace a consistent + server-independent layout: no URL should have to include + any physically correct target server. The cluster itself + should drive us automatically to the physical target + host.

    +
    + +
    Solution:
    + +
    +

    First, the knowledge of the target servers come from + (distributed) external maps which contain information + where our users, groups and entities stay. The have the + form

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    We put them into files map.xxx-to-host. + Second we need to instruct all servers to redirect URLs + of the forms

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    to

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    when the URL is not locally valid to a server. The + following ruleset does this for us by the help of the map + files (assuming that server0 is a default server which + will be used if a user has no entry in the map):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + + + +

    Move Homedirs to Different Webserver

    + + + +
    +
    Description:
    + +
    +

    Many webmasters have asked for a solution to the + following situation: They wanted to redirect just all + homedirs on a webserver to another webserver. They usually + need such things when establishing a newer webserver which + will replace the old one over time.

    +
    + +
    Solution:
    + +
    +

    The solution is trivial with mod_rewrite. + On the old webserver we just redirect all + /~user/anypath URLs to + http://newserver/~user/anypath.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + + + +

    Structured Homedirs

    + + + +
    +
    Description:
    + +
    +

    Some sites with thousands of users usually use a + structured homedir layout, i.e. each homedir is in a + subdirectory which begins for instance with the first + character of the username. So, /~foo/anypath + is /home/f/foo/.www/anypath + while /~bar/anypath is + /home/b/bar/.www/anypath.

    +
    + +
    Solution:
    + +
    +

    We use the following ruleset to expand the tilde URLs + into exactly the above layout.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + + + +

    Filesystem Reorganization

    + + + +
    +
    Description:
    + +
    +

    This really is a hardcore example: a killer application + which heavily uses per-directory + RewriteRules to get a smooth look and feel + on the Web while its data structure is never touched or + adjusted. Background: net.sw is + my archive of freely available Unix software packages, + which I started to collect in 1992. It is both my hobby + and job to to this, because while I'm studying computer + science I have also worked for many years as a system and + network administrator in my spare time. Every week I need + some sort of software so I created a deep hierarchy of + directories where I stored the packages:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    In July 1996 I decided to make this archive public to + the world via a nice Web interface. "Nice" means that I + wanted to offer an interface where you can browse + directly through the archive hierarchy. And "nice" means + that I didn't wanted to change anything inside this + hierarchy - not even by putting some CGI scripts at the + top of it. Why? Because the above structure should be + later accessible via FTP as well, and I didn't want any + Web or CGI stuff to be there.

    +
    + +
    Solution:
    + +
    +

    The solution has two parts: The first is a set of CGI + scripts which create all the pages at all directory + levels on-the-fly. I put them under + /e/netsw/.www/ as follows:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    The DATA/ subdirectory holds the above + directory structure, i.e. the real + net.sw stuff and gets + automatically updated via rdist from time to + time. The second part of the problem remains: how to link + these two structures together into one smooth-looking URL + tree? We want to hide the DATA/ directory + from the user while running the appropriate CGI scripts + for the various URLs. Here is the solution: first I put + the following into the per-directory configuration file + in the DocumentRoot + of the server to rewrite the announced URL + /net.sw/ to the internal path + /e/netsw:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    The first rule is for requests which miss the trailing + slash! The second rule does the real thing. And then + comes the killer configuration which stays in the + per-directory config file + /e/netsw/.www/.wwwacl:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  we are reached via /net.sw/ prefix
    +RewriteBase   /net.sw/
    +
    +#  first we rewrite the root dir to
    +#  the handling cgi script
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  strip out the subdirs when
    +#  the browser requests us from perdir pages
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  and now break the rewriting for local files
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  anything else is a subdir which gets handled
    +#  by another cgi script
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Some hints for interpretation:

    + +
      +
    1. Notice the L (last) flag and no + substitution field ('-') in the forth part
    2. + +
    3. Notice the ! (not) character and + the C (chain) flag at the first rule + in the last part
    4. + +
    5. Notice the catch-all pattern in the last rule
    6. +
    +
    +
    + + + +

    NCSA imagemap to Apache mod_imagemap

    + + + +
    +
    Description:
    + +
    +

    When switching from the NCSA webserver to the more + modern Apache webserver a lot of people want a smooth + transition. So they want pages which use their old NCSA + imagemap program to work under Apache with the + modern mod_imagemap. The problem is that there + are a lot of hyperlinks around which reference the + imagemap program via + /cgi-bin/imagemap/path/to/page.map. Under + Apache this has to read just + /path/to/page.map.

    +
    + +
    Solution:
    + +
    +

    We use a global rule to remove the prefix on-the-fly for + all requests:

    + +
    +RewriteEngine  on
    +RewriteRule    ^/cgi-bin/imagemap(.*)  $1  [PT]
    +
    +
    +
    + + + +

    Search pages in more than one directory

    + + + +
    +
    Description:
    + +
    +

    Sometimes it is necessary to let the webserver search + for pages in more than one directory. Here MultiViews or + other techniques cannot help.

    +
    + +
    Solution:
    + +
    +

    We program a explicit ruleset which searches for the + files in the directories.

    + +
    +RewriteEngine on
    +
    +#   first try to find it in custom/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   second try to find it in pub/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   else go on for other Alias or ScriptAlias directives,
    +#   etc.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + + + +

    Set Environment Variables According To URL Parts

    + + + +
    +
    Description:
    + +
    +

    Perhaps you want to keep status information between + requests and use the URL to encode it. But you don't want + to use a CGI wrapper for all pages just to strip out this + information.

    +
    + +
    Solution:
    + +
    +

    We use a rewrite rule to strip out the status information + and remember it via an environment variable which can be + later dereferenced from within XSSI or CGI. This way a + URL /foo/S=java/bar/ gets translated to + /foo/bar/ and the environment variable named + STATUS is set to the value "java".

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + + + +

    Virtual User Hosts

    + + + +
    +
    Description:
    + +
    +

    Assume that you want to provide + www.username.host.domain.com + for the homepage of username via just DNS A records to the + same machine and without any virtualhosts on this + machine.

    +
    + +
    Solution:
    + +
    +

    For HTTP/1.0 requests there is no solution, but for + HTTP/1.1 requests which contain a Host: HTTP header we + can use the following ruleset to rewrite + http://www.username.host.com/anypath + internally to /home/username/anypath:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + + + +

    Redirect Homedirs For Foreigners

    + + + +
    +
    Description:
    + +
    +

    We want to redirect homedir URLs to another webserver + www.somewhere.com when the requesting user + does not stay in the local domain + ourdomain.com. This is sometimes used in + virtual host contexts.

    +
    + +
    Solution:
    + +
    +

    Just a rewrite condition:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + + + +

    Redirect Failing URLs To Other Webserver

    + + + +
    +
    Description:
    + +
    +

    A typical FAQ about URL rewriting is how to redirect + failing requests on webserver A to webserver B. Usually + this is done via ErrorDocument CGI-scripts in Perl, but + there is also a mod_rewrite solution. + But notice that this performs more poorly than using an + ErrorDocument + CGI-script!

    +
    + +
    Solution:
    + +
    +

    The first solution has the best performance but less + flexibility, and is less error safe:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    The problem here is that this will only work for pages + inside the DocumentRoot. While you can add more + Conditions (for instance to also handle homedirs, etc.) + there is better variant:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    This uses the URL look-ahead feature of mod_rewrite. + The result is that this will work for all types of URLs + and is a safe way. But it does a performance impact on + the webserver, because for every request there is one + more internal subrequest. So, if your webserver runs on a + powerful CPU, use this one. If it is a slow machine, use + the first approach or better a ErrorDocument CGI-script.

    +
    +
    + + + +

    Extended Redirection

    + + + +
    +
    Description:
    + +
    +

    Sometimes we need more control (concerning the + character escaping mechanism) of URLs on redirects. + Usually the Apache kernels URL escape function also + escapes anchors, i.e. URLs like "url#anchor". + You cannot use this directly on redirects with + mod_rewrite because the + uri_escape() function of Apache + would also escape the hash character. + How can we redirect to such a URL?

    +
    + +
    Solution:
    + +
    +

    We have to use a kludge by the use of a NPH-CGI script + which does the redirect itself. Because here no escaping + is done (NPH=non-parseable headers). First we introduce a + new URL scheme xredirect: by the following + per-server config-line (should be one of the last rewrite + rules):

    + +
    +RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
    +            [T=application/x-httpd-cgi,L]
    +
    + +

    This forces all URLs prefixed with + xredirect: to be piped through the + nph-xredirect.cgi program. And this program + just looks like:

    + +
    +#!/path/to/perl
    +##
    +##  nph-xredirect.cgi -- NPH/CGI script for extended redirects
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +
    +$| = 1;
    +$url = $ENV{'PATH_INFO'};
    +
    +print "HTTP/1.0 302 Moved Temporarily\n";
    +print "Server: $ENV{'SERVER_SOFTWARE'}\n";
    +print "Location: $url\n";
    +print "Content-type: text/html\n";
    +print "\n";
    +print "<html>\n";
    +print "<head>\n";
    +print "<title>302 Moved Temporarily (EXTENDED)</title>\n";
    +print "</head>\n";
    +print "<body>\n";
    +print "<h1>Moved Temporarily (EXTENDED)</h1>\n";
    +print "The document has moved <a HREF=\"$url\">here</a>.<p>\n";
    +print "</body>\n";
    +print "</html>\n";
    +
    +##EOF##
    +
    + +

    This provides you with the functionality to do + redirects to all URL schemes, i.e. including the one + which are not directly accepted by mod_rewrite. + For instance you can now also redirect to + news:newsgroup via

    + +
    +RewriteRule ^anyurl  xredirect:news:newsgroup
    +
    + +
    Notice: You have not to put [R] or + [R,L] to the above rule because the + xredirect: need to be expanded later + by our special "pipe through" rule above.
    +
    +
    + + + +

    Archive Access Multiplexer

    + + + +
    +
    Description:
    + +
    +

    Do you know the great CPAN (Comprehensive Perl Archive + Network) under http://www.perl.com/CPAN? + This does a redirect to one of several FTP servers around + the world which carry a CPAN mirror and is approximately + near the location of the requesting client. Actually this + can be called an FTP access multiplexing service. While + CPAN runs via CGI scripts, how can a similar approach + implemented via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    First we notice that from version 3.0.0 + mod_rewrite can + also use the "ftp:" scheme on redirects. + And second, the location approximation can be done by a + RewriteMap + over the top-level domain of the client. + With a tricky chained ruleset we can use this top-level + domain as a key to our multiplexing map.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + + + +

    Time-Dependent Rewriting

    + + + +
    +
    Description:
    + +
    +

    When tricks like time-dependent content should happen a + lot of webmasters still use CGI scripts which do for + instance redirects to specialized pages. How can it be done + via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    There are a lot of variables named TIME_xxx + for rewrite conditions. In conjunction with the special + lexicographic comparison patterns <STRING, + >STRING and =STRING we can + do time-dependent redirects:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    This provides the content of foo.day.html + under the URL foo.html from + 07:00-19:00 and at the remaining time the + contents of foo.night.html. Just a nice + feature for a homepage...

    +
    +
    + + + +

    Backward Compatibility for YYYY to XXXX migration

    + + + +
    +
    Description:
    + +
    +

    How can we make URLs backward compatible (still + existing virtually) after migrating document.YYYY + to document.XXXX, e.g. after translating a + bunch of .html files to .phtml?

    +
    + +
    Solution:
    + +
    +

    We just rewrite the name to its basename and test for + existence of the new extension. If it exists, we take + that name, else we rewrite the URL to its original state.

    + + +
    +#   backward compatibility ruleset for
    +#   rewriting document.html to document.phtml
    +#   when and only when document.phtml exists
    +#   but no longer document.html
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   parse out basename, but remember the fact
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   rewrite to document.phtml if exists
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   else reverse the previous basename cutout
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + + + +
    top
    +
    +

    Content Handling

    + + + +

    From Old to New (intern)

    + + + +
    +
    Description:
    + +
    +

    Assume we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. Actually + we want that users of the old URL even not recognize that + the pages was renamed.

    +
    + +
    Solution:
    + +
    +

    We rewrite the old URL to the new one internally via the + following rule:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + + + +

    From Old to New (extern)

    + + + +
    +
    Description:
    + +
    +

    Assume again that we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. But this + time we want that the users of the old URL get hinted to + the new one, i.e. their browsers Location field should + change, too.

    +
    + +
    Solution:
    + +
    +

    We force a HTTP redirect to the new URL which leads to a + change of the browsers and thus the users view:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + + + +

    Browser Dependent Content

    + + + +
    +
    Description:
    + +
    +

    At least for important top-level pages it is sometimes + necessary to provide the optimum of browser dependent + content, i.e. one has to provide a maximum version for the + latest Netscape variants, a minimum version for the Lynx + browsers and a average feature version for all others.

    +
    + +
    Solution:
    + +
    +

    We cannot use content negotiation because the browsers do + not provide their type in that form. Instead we have to + act on the HTTP header "User-Agent". The following condig + does the following: If the HTTP header "User-Agent" + begins with "Mozilla/3", the page foo.html + is rewritten to foo.NS.html and and the + rewriting stops. If the browser is "Lynx" or "Mozilla" of + version 1 or 2 the URL becomes foo.20.html. + All other browsers receive page foo.32.html. + This is done by the following ruleset:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + + + +

    Dynamic Mirror

    + + + +
    +
    Description:
    + +
    +

    Assume there are nice webpages on remote hosts we want + to bring into our namespace. For FTP servers we would use + the mirror program which actually maintains an + explicit up-to-date copy of the remote data on the local + machine. For a webserver we could use the program + webcopy which acts similar via HTTP. But both + techniques have one major drawback: The local copy is + always just as up-to-date as often we run the program. It + would be much better if the mirror is not a static one we + have to establish explicitly. Instead we want a dynamic + mirror with data which gets updated automatically when + there is need (updated data on the remote host).

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature + (flag [P]):

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + + + +

    Reverse Dynamic Mirror

    + + + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + + + +

    Retrieve Missing Data from Intranet

    + + + +
    +
    Description:
    + +
    +

    This is a tricky way of virtually running a corporate + (external) Internet webserver + (www.quux-corp.dom), while actually keeping + and maintaining its data on a (internal) Intranet webserver + (www2.quux-corp.dom) which is protected by a + firewall. The trick is that on the external webserver we + retrieve the requested data on-the-fly from the internal + one.

    +
    + +
    Solution:
    + +
    +

    First, we have to make sure that our firewall still + protects the internal webserver and that only the + external webserver is allowed to retrieve data from it. + For a packet-filtering firewall we could for instance + configure a firewall ruleset like the following:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    Just adjust it to your actual configuration syntax. + Now we can establish the mod_rewrite + rules which request the missing data in the background + through the proxy throughput feature:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + + + +

    Load Balancing

    + + + +
    +
    Description:
    + +
    +

    Suppose we want to load balance the traffic to + www.foo.com over www[0-5].foo.com + (a total of 6 servers). How can this be done?

    +
    + +
    Solution:
    + +
    +

    There are a lot of possible solutions for this problem. + We will discuss first a commonly known DNS-based variant + and then the special one with mod_rewrite:

    + +
      +
    1. + DNS Round-Robin + +

      The simplest method for load-balancing is to use + the DNS round-robin feature of BIND. + Here you just configure www[0-9].foo.com + as usual in your DNS with A(address) records, e.g.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      Then you additionally add the following entry:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      Notice that this seems wrong, but is actually an + intended feature of BIND and can be used + in this way. However, now when www.foo.com gets + resolved, BIND gives out www0-www6 + - but in a slightly permutated/rotated order every time. + This way the clients are spread over the various + servers. But notice that this not a perfect load + balancing scheme, because DNS resolve information + gets cached by the other nameservers on the net, so + once a client has resolved www.foo.com + to a particular wwwN.foo.com, all + subsequent requests also go to this particular name + wwwN.foo.com. But the final result is + ok, because the total sum of the requests are really + spread over the various webservers.

      +
    2. + +
    3. + DNS Load-Balancing + +

      A sophisticated DNS-based method for + load-balancing is to use the program + lbnamed which can be found at + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + It is a Perl 5 program in conjunction with auxilliary + tools which provides a real load-balancing for + DNS.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      In this variant we use mod_rewrite + and its proxy throughput feature. First we dedicate + www0.foo.com to be actually + www.foo.com by using a single

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      entry in the DNS. Then we convert + www0.foo.com to a proxy-only server, + i.e. we configure this machine so all arriving URLs + are just pushed through the internal proxy to one of + the 5 other servers (www1-www5). To + accomplish this we first establish a ruleset which + contacts a load balancing script lb.pl + for all URLs.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      Then we write lb.pl:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- load balancing script
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # the hostname base
      +$first  = 1;         # the first server (not 0 here, because 0 is myself)
      +$last   = 5;         # the last server in the round-robin
      +$domain = "foo.dom"; # the domainname
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + +
      A last notice: Why is this useful? Seems like + www0.foo.com still is overloaded? The + answer is yes, it is overloaded, but with plain proxy + throughput requests, only! All SSI, CGI, ePerl, etc. + processing is completely done on the other machines. + This is the essential point.
      +
    6. + +
    7. + Hardware/TCP Round-Robin + +

      There is a hardware solution available, too. Cisco + has a beast called LocalDirector which does a load + balancing at the TCP/IP level. Actually this is some + sort of a circuit level gateway in front of a + webcluster. If you have enough money and really need + a solution with high performance, use this one.

      +
    8. +
    +
    +
    + + + +

    New MIME-type, New Service

    + + + +
    +
    Description:
    + +
    +

    On the net there are a lot of nifty CGI programs. But + their usage is usually boring, so a lot of webmaster + don't use them. Even Apache's Action handler feature for + MIME-types is only appropriate when the CGI programs + don't need special URLs (actually PATH_INFO + and QUERY_STRINGS) as their input. First, + let us configure a new file type with extension + .scgi (for secure CGI) which will be processed + by the popular cgiwrap program. The problem + here is that for instance we use a Homogeneous URL Layout + (see above) a file inside the user homedirs has the URL + /u/user/foo/bar.scgi. But + cgiwrap needs the URL in the form + /~user/foo/bar.scgi/. The following rule + solves the problem:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    Or assume we have some more nifty programs: + wwwlog (which displays the + access.log for a URL subtree and + wwwidx (which runs Glimpse on a URL + subtree). We have to provide the URL area to these + programs so they know on which area they have to act on. + But usually this ugly, because they are all the times + still requested from that areas, i.e. typically we would + run the swwidx program from within + /u/user/foo/ via hyperlink to

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    which is ugly. Because we have to hard-code + both the location of the area + and the location of the CGI inside the + hyperlink. When we have to reorganize the area, we spend a + lot of time changing the various hyperlinks.

    +
    + +
    Solution:
    + +
    +

    The solution here is to provide a special new URL format + which automatically leads to the proper CGI invocation. + We configure the following:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    Now the hyperlink to search at + /u/user/foo/ reads only

    + +
    +HREF="*"
    +
    + +

    which internally gets automatically transformed to

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    The same approach leads to an invocation for the + access log CGI program when the hyperlink + :log gets used.

    +
    +
    + + + +

    From Static to Dynamic

    + + + +
    +
    Description:
    + +
    +

    How can we transform a static page + foo.html into a dynamic variant + foo.cgi in a seamless way, i.e. without notice + by the browser/user.

    +
    + +
    Solution:
    + +
    +

    We just rewrite the URL to the CGI-script and force the + correct MIME-type so it gets really run as a CGI-script. + This way a request to /~quux/foo.html + internally leads to the invocation of + /~quux/foo.cgi.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + + + +

    On-the-fly Content-Regeneration

    + + + +
    +
    Description:
    + +
    +

    Here comes a really esoteric feature: Dynamically + generated but statically served pages, i.e. pages should be + delivered as pure static pages (read from the filesystem + and just passed through), but they have to be generated + dynamically by the webserver if missing. This way you can + have CGI-generated pages which are statically served unless + one (or a cronjob) removes the static contents. Then the + contents gets refreshed.

    +
    + +
    Solution:
    + +
    + This is done via the following ruleset: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    Here a request to page.html leads to a + internal run of a corresponding page.cgi if + page.html is still missing or has filesize + null. The trick here is that page.cgi is a + usual CGI script which (additionally to its STDOUT) + writes its output to the file page.html. + Once it was run, the server sends out the data of + page.html. When the webmaster wants to force + a refresh the contents, he just removes + page.html (usually done by a cronjob).

    +
    +
    + + + +

    Document With Autorefresh

    + + + +
    +
    Description:
    + +
    +

    Wouldn't it be nice while creating a complex webpage if + the webbrowser would automatically refresh the page every + time we write a new version from within our editor? + Impossible?

    +
    + +
    Solution:
    + +
    +

    No! We just combine the MIME multipart feature, the + webserver NPH feature and the URL manipulation power of + mod_rewrite. First, we establish a new + URL feature: Adding just :refresh to any + URL causes this to be refreshed every time it gets + updated on the filesystem.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    Now when we reference the URL

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    this leads to the internal invocation of the URL

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    The only missing part is the NPH-CGI script. Although + one would usually say "left as an exercise to the reader" + ;-) I will provide this, too.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + + + +

    Mass Virtual Hosting

    + + + +
    +
    Description:
    + +
    +

    The <VirtualHost> feature of Apache is nice + and works great when you just have a few dozens + virtual hosts. But when you are an ISP and have hundreds of + virtual hosts to provide this feature is not the best + choice.

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature (flag [P]):

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   use the canonical hostname on redirects, etc.
    +UseCanonicalName on
    +
    +    :
    +#   add the virtual host in front of the CLF-format
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   enable the rewriting engine in the main server
    +RewriteEngine on
    +
    +#   define two maps: one for fixing the URL and one which defines
    +#   the available virtual hosts with their corresponding
    +#   DocumentRoot.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   Now do the actual virtual host mapping
    +#   via a huge and complicated single rule:
    +#
    +#   1. make sure we don't map for common locations
    +RewriteCond   %{REQUEST_URL}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URL}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URL}  !^/commonurlN/.*
    +#
    +#   2. make sure we have a Host header, because
    +#      currently our approach only supports
    +#      virtual hosting through this header
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. lowercase the hostname
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. lookup this hostname in vhost.map and
    +#      remember it only when it is a path
    +#      (and not "NONE" from above)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. finally we can map the URL to its docroot location
    +#      and remember the virtual host for logging puposes
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + + + +
    top
    +
    +

    Access Restriction

    + + + +

    Blocking of Robots

    + + + +
    +
    Description:
    + +
    +

    How can we block a really annoying robot from + retrieving pages of a specific webarea? A + /robots.txt file containing entries of the + "Robot Exclusion Protocol" is typically not enough to get + rid of such a robot.

    +
    + +
    Solution:
    + +
    +

    We use a ruleset which forbids the URLs of the webarea + /~quux/foo/arc/ (perhaps a very deep + directory indexed area where the robot traversal would + create big server load). We have to make sure that we + forbid access only to the particular robot, i.e. just + forbidding the host where the robot runs is not enough. + This would block users from this host, too. We accomplish + this by also matching the User-Agent HTTP header + information.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + + + +

    Blocked Inline-Images

    + + + +
    +
    Description:
    + +
    +

    Assume we have under http://www.quux-corp.de/~quux/ + some pages with inlined GIF graphics. These graphics are + nice, so others directly incorporate them via hyperlinks to + their pages. We don't like this practice because it adds + useless traffic to our server.

    +
    + +
    Solution:
    + +
    +

    While we cannot 100% protect the images from inclusion, + we can at least restrict the cases where the browser + sends a HTTP Referer header.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + + + +

    Host Deny

    + + + +
    +
    Description:
    + +
    +

    How can we forbid a list of externally configured hosts + from using our server?

    +
    + +
    Solution:
    + +
    +

    For Apache >= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    For Apache <= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ATTENTION! This is a map, not a list, even when we treat it as such.
    +##             mod_rewrite parses it for key/value pairs, so at least a
    +##             dummy value "-" must be present for each entry.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + + + +

    Proxy Deny

    + + + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + + + +

    Special Authentication Variant

    + + + +
    +
    Description:
    + +
    +

    Sometimes a very special authentication is needed, for + instance a authentication which checks for a set of + explicitly configured users. Only these should receive + access and without explicit prompting (which would occur + when using the Basic Auth via mod_auth_basic).

    +
    + +
    Solution:
    + +
    +

    We use a list of rewrite conditions to exclude all except + our friends:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + + + +

    Referer-based Deflector

    + + + +
    +
    Description:
    + +
    +

    How can we program a flexible URL Deflector which acts + on the "Referer" HTTP header and can be configured with as + many referring pages as we like?

    +
    + +
    Solution:
    + +
    +

    Use the following really tricky ruleset...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... in conjunction with a corresponding rewrite + map:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    This automatically redirects the request back to the + referring page (when "-" is used as the value + in the map) or to a specific URL (when an URL is specified + in the map as the second argument).

    +
    +
    + + + +
    top
    +
    +

    Other

    + + + +

    External Rewriting Engine

    + + + +
    +
    Description:
    + +
    +

    A FAQ: How can we solve the FOO/BAR/QUUX/etc. + problem? There seems no solution by the use of + mod_rewrite...

    +
    + +
    Solution:
    + +
    +

    Use an external RewriteMap, i.e. a program which acts + like a RewriteMap. It is run once on startup of Apache + receives the requested URLs on STDIN and has + to put the resulting (usually rewritten) URL on + STDOUT (same order!).

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   disable buffered I/O which would lead
    +#   to deadloops for the Apache server
    +$| = 1;
    +
    +#   read URLs one per line from stdin and
    +#   generate substitution URL on stdout
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    This is a demonstration-only example and just rewrites + all URLs /~quux/foo/... to + /~quux/bar/.... Actually you can program + whatever you like. But notice that while such maps can be + used also by an average user, only the + system administrator can define it.

    +
    +
    + + + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/rewriteguide.html.ko.euc-kr b/trunk/docs/manual/misc/rewriteguide.html.ko.euc-kr new file mode 100644 index 0000000000..c75ef309ba --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.html.ko.euc-kr @@ -0,0 +1,2006 @@ + + + +URL ÀçÀÛ¼º Áöħ¼­ - Apache HTTP Server + + + + + +
    <-
    +

    URL ÀçÀÛ¼º Áöħ¼­

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +
    +

    ¿øÀúÀÚ
    + Ralf S. Engelschall <rse@apache.org>
    + 1997³â 12¿ù

    +
    + +

    ÀÌ ¹®¼­´Â mod_rewrite ÂüÁ¶ ¹®¼­¸¦ º¸ÃæÇÑ´Ù. + ÀÌ ¹®¼­´Â À¥°ü¸®ÀÚ°¡ ½ÇÁ¦ ÀÛ¾÷¿¡¼­ ºÎµúÄ¡°ÔµÇ´Â ÀüÇüÀûÀÎ + URL°ü·Ã ¹®Á¦¸¦ ÇØ°áÇϱâÀ§Çؼ­ ¾î¶»°Ô ¾ÆÆÄÄ¡ + mod_rewrite¸¦ »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù. URL + ÀçÀÛ¼º ±ÔÄ¢À» ¼³Á¤ÇÏ¿© ¹®Á¦¸¦ ÇØ°áÇÏ´Â ¹æ¹ýÀ» ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.

    + +
    + +
    top
    +
    +

    mod_rewrite ¼Ò°³

    + + + +

    ¾ÆÆÄÄ¡ mod_rewrite ¸ðµâÀº ±²ÀåÇÏ´Ù. + Áï, URLÀ» Á¶ÀÛÇÒ ¼ö ÀÖ´Â °­·ÂÇÏ°í ½Ç·Î Á¤±³ÇÑ ¸ðµâÀÌ´Ù. + »ó»óÇØ¿Ô´ø °ÅÀÇ ¸ðµç Á¾·ùÀÇ URL Á¶ÀÛÀÌ °¡´ÉÇÏ´Ù. ±×·¯³ª + ±× ´ë°¡·Î »ç¿ëÇϱ⠺¹ÀâÇÏ´Ù. mod_rewriteÀÇ + ÃÖ´ë ´ÜÁ¡Àº Ãʺ¸ÀÚ°¡ ÀÌÇØÇÏ°í »ç¿ëÇϱ⠽±Áö ¾Ê´Ù´Â Á¡ÀÌ´Ù. + ½ÉÁö¾î ¾ÆÆÄÄ¡ Àü¹®°¡µµ Á¾Á¾ mod_rewriteÀÇ + »õ·Î¿î ¿ëµµ¸¦ ¹ß°ßÇÑ´Ù.

    + +

    ´Ù¸¥ ¸»·Î: mod_rewrite¿¡ ´ëÇØ ´ç½ÅÀº + óÀ½¿¡ °ÌÀ» ¸Ô°í Àý´ë·Î ´Ù½Ã »ç¿ëÇÏÁö ¾Ê°Å³ª, °­·ÂÇÔ¿¡ ¸Å·áµÇ¾î + ¾ÕÀ¸·Î »î µ¿¾È »ç¶û¿¡ ºüÁú °ÍÀÌ´Ù. ÀÌ ±ÛÀº ù¹ø° °æ¿ì¸¦ + ¸·±âÀ§ÇØ ÀÌ¹Ì ¾Ë·ÁÁø ¸î°¡Áö ¼º°ø»ç·Ê¸¦ ¼Ò°³ÇÏ·Á°í ÇÑ´Ù.

    + +
    top
    +
    +

    ½Ç¿ëÀûÀÎ ÇØ°áÃ¥

    + + + +

    ÀÌÁ¦ ³»°¡ Á÷Á¢ ¸¸µé¾ú°Å³ª ´Ù¸¥ »ç¶÷µéÀÌ ¸¸µç ¸¹Àº ½Ç¿ëÀûÀÎ + ÇØ°áÃ¥ÀÌ ³ª¿Â´Ù. ¿¹Á¦¿¡¼­ URL ÀçÀÛ¼ºÀÇ È渶¼úÀ» ¸¶À½²¯ ¹è¿ì±æ + ¹Ù¶õ´Ù.

    + +
    ÁÖÀÇ: ¼­¹ö ¼³Á¤¿¡ µû¶ó »óȲ¿¡ ¸Â°Ô + ¿¹Á¦¸¦ Á¶±Ý ¼öÁ¤ÇØ¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î, Ãß°¡·Î + mod_alias, mod_userdir + µîÀ» »ç¿ëÇÑ´Ù¸é [PT] Ç÷¡±×¸¦ Ãß°¡ÇÑ´Ù. ȤÀº + ÁÖ¼­¹ö¼³Á¤/°¡»óÈ£½ºÆ® »ç¿ëÀå¼Ò°¡ ¾Æ´Ñ .htaccess + »ç¿ëÀå¼Ò¿¡ ¾Ë¸Â°Ô ±ÔÄ¢À» ¼öÁ¤ÇÒ ¼öµµ ÀÖ´Ù. »ç¿ëÇϱâ Àü¿¡ + Ç×»ó ±ÔÄ¢ÀÌ ¾î¶² ±â´ÉÀ» ÇÏ´ÂÁö ÀÌÇØÇϵµ·Ï Çضó. ±×·¯¸é ¹®Á¦¸¦ + ÇÇÇÒ ¼ö ÀÖ´Ù.
    + +
    top
    +
    +

    URL ±¸Á¶

    + + + +

    ±âÁØÀÌ µÇ´Â URL

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÇÑ ¸®¼Ò½º¿¡ ´ëÇØ ¿©·¯ URLÀ» °¡Áö´Â À¥¼­¹ö°¡ ÀÖ´Ù. + º¸Åë (½ÇÁ¦ »ç¿ëÇÏ°í ¾Ë·ÁÁ®¾ß ÇÒ) ±âÁØÀÌ µÇ´Â URL°ú, + ´ÜÃà ȤÀº ³»ºÎ ¿ëµµÀÇ URLÀÌ ÀÖ´Ù. »ç¿ëÀÚ°¡ ¿äû¿¡ + ¾î¶² URLÀ» »ç¿ëÇÏ´øÁö ±âÁØÀÌ µÇ´Â URL¸¸À» º¸¿©Áà¾ß + ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ±âÁØÀÌ µÇÁö¾Ê´Â ¸ðµç URLÀ» ºê¶ó¿ìÀú°¡ ¾Ëµµ·Ï °íÄ¡±âÀ§ÇØ + ¿ÜºÎ HTTP ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. ¿¹¸¦ µé¾î ¾Æ·¡ ±ÔÄ¢Àº + /~user¸¦ ±âÁØÀÌ µÇ´Â /u/user·Î + ´ëüÇÏ°í, /u/user ¸¶Áö¸·¿¡ ½½·¡½¬°¡ ¾ø´Ù¸é + Ãß°¡ÇÑ´Ù.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + + + +

    ±âÁØÀÌ µÇ´Â È£½ºÆ®¸í

    + + + +
    +
    »óȲ¼³¸í:
    + +
    ...
    + +
    ÇØ°áÃ¥:
    + +
    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + + + +

    DocumentRoot¸¦ ¿Å±ä °æ¿ì

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    À¥¼­¹öÀÇ DocumentRoot´Â º¸Åë URL + "/"°ú Á÷Á¢ °ü·ÃÀÖ´Ù. ±×·¯³ª ÀÌ°÷¿¡ ¸ðµç + ÀÚ·á°¡ ÀÖÁö ¾Ê°í, ÀÚ·á°¡ ´Ù¸¥ ¿©·¯ °÷¿¡ Èð¾îÁ®ÀÖ´Â + °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î ÀÎÆ®¶ó³Ý »çÀÌÆ®¿¡ (¿ÜºÎ¸¦ À§ÇÑ + ȨÆäÀÌÁö) /e/www/¿Í (ÀÎÆ®¶ó³ÝÀ» À§ÇÑ + ȨÆäÀÌÁö) /e/sww/°¡ ÀÖ´Ù°í ÇÏÀÚ. ÀÌÁ¦ + DocumentRoot°¡ + /e/www/À̱⶧¹®¿¡, ¿äû¿¡¼­ ÆäÀÌÁö¿¡ + Æ÷ÇÔµÈ ±×¸² µîÀ» ÀÌ°÷¿¡¼­ °¡Á®¿Í¾ß ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿ì¸®´Â URL /¸¦ /e/www/·Î + ¸®´ÙÀÌ·º¼Ç¸¸ ÇÏ¸é µÈ´Ù. »ç¼ÒÇØ º¸ÀÌÁö¸¸ ½ÇÁ¦·Î + mod_rewrite¸¦ »ç¿ëÇؼ­¸¸ °¡´ÉÇÏ´Ù. + (mod_alias µîÀÌ Á¦°øÇÏ´Â) URL + Alias °°Àº ÀüÇüÀûÀÎ ¹æ¹ýÀº ¾ÕºÎºÐ¸¸ + ã´Â´Ù. DocumentRoot°¡ + ¸ðµç URLÀÇ ¾ÕºÎºÐÀ̱⶧¹®¿¡ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ¿© ¸®´ÙÀÌ·º¼ÇÀ» + ÇÒ ¼ö ¾ø´Ù. mod_rewrite¸¦ »ç¿ëÇϸé + ÁøÂ¥ °£´ÜÇÏ´Ù:

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /e/www/  [R]
    +
    +
    +
    + + + +

    ¸¶Áö¸· ½½·¡½¬ ¹®Á¦

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    µð·ºÅ丮¸¦ ÁöĪÇÏ´Â URLÀÇ ¸¶Áö¸· ½½·¡½¬ ¹®Á¦°¡ + ¾ø´Ù¸é ¸ðµç À¥°ü¸®Àڴ ȯȣÇÒ °ÍÀÌ´Ù. ½½·¡½¬°¡ ¾ø´Ù¸é, + Áï /~quux/foo/ ´ë½Å /~quux/foo¸¦ + »ç¿ëÇÏ¸é ¼­¹ö°¡ foo¶ó´Â ÆÄÀÏÀ» + ã±â¶§¹®¿¡ ¿À·ù°¡ ¹ß»ýÇÑ´Ù. ÆÄÀÏÀÌ µð·ºÅ丮À̱⶧¹®¿¡ + ¹Þ¾ÆµéÀÌÁö ¾Ê´Â´Ù. ´ëºÎºÐÀÇ °æ¿ì º¸Åë ¼­¹ö°¡ ÀÚµ¿À¸·Î + URLÀ» °íÄ¡Áö¸¸, °¡²û Á÷Á¢ ÇØÁà¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ + µé¾î, CGI ½ºÅ©¸³Æ® µîÀ¸·Î º¹ÀâÇÑ URL ÀçÀÛ¼ºÀ» ÇÑ ÈÄ¿¡ + ±×·¯ÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀÌ ¹Ì¹¦ÇÑ ¹®Á¦ÀÇ ÇØ°á¹æ¹ýÀº ¼­¹ö°¡ ÀÚµ¿À¸·Î ¸¶Áö¸· + ½½·¡½¬¸¦ Ãß°¡ÇÏ´Â °ÍÀÌ´Ù. ºê¶ó¿ìÀú°¡ ³ª¸ÓÁö ±×¸² µîÀ» + ¿Ã¹Ù·Î ¿äûÇÒ ¼ö ÀÖµµ·Ï, ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» ÇØ¾ß ÇÑ´Ù. + ³»ºÎ ¸®´ÙÀÌ·º¼ÇÀ» ÇÑ´Ù¸é µð·ºÅ丮 ÆäÀÌÁö¿¡¸¸ µ¿ÀÛÇÏ¿© + ÀÌ ÆäÀÌÁö°¡ »ó´ë URL·Î Æ÷ÇÔÇÏ´Â ±×¸²À» ºê¶ó¿ìÀú°¡ + ¿äûÇÒ¶§ ãÀ» ¼ö ¾ø´Ù. ¿¹¸¦ µé¾î, ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» + »ç¿ëÇÏÁö ¾ÊÀ»¶§ /~quux/foo/index.html¿¡¼­ + image.gif¸¦ ¿äûÇϸé + /~quux/image.gif¸¦ ¿äûÇÏ°Ô µÈ´Ù!

    + +

    ±×·¡¼­ À̸¦ ÇØ°áÇϱâÀ§ÇØ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    Ȩµð·ºÅ丮ÀÇ ÃÖ»óÀ§ .htaccess ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù. ±×·¯³ª ó¸®Çϴµ¥ ºÎ´ãÀÌ + µÈ´Ù.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + + + +

    ÀÏ°üµÈ URL ±¸Á¶·Î ¸¸µç À¥Å¬·¯½ºÅÍ

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÎÆ®¶ó³Ý À¥¼­¹ö±ºÀÇ ¸ðµç À¥¼­¹ö¿¡ µ¿ÀÏÇÏ°í ÀÏ°üµÈ + URL ±¸Á¶¸¦ ¸¸µé°í ½Í´Ù. Áï, ¸ðµç (Á¤ÀÇ»ó ¼­¹ö¿¡ ¼ÓÇÏ¿© + ¼­¹ö¿¡ ÀÇÁ¸ÀûÀÎ!) URLÀ» ¼­¹ö µ¶¸³ÀûÀ¸·Î ¸¸µç´Ù! + À¥ À̸§°ø°£¿¡ ¼­¹öµ¶¸³ÀûÀÎ µ¿ÀÏÇÑ ±¸Á¶¸¦ ºÎ¿©ÇØ¾ß ÇÑ´Ù: + URLÀº ½ÇÁ¦ ¼­¹ö¸¦ ÁöĪÇÏ¸é ¾ÈµÈ´Ù. ¼­¹ö±ºÀÌ ÀÚµ¿À¸·Î + ½ÇÁ¦ ¼­¹ö·Î À¯µµÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú »ç¿ëÀÚ, ±×·ì, µ¶¸³Ã¼ÀÇ À§Ä¡ Á¤º¸¸¦ ÀúÀåÇÑ + (ºÐ»êµÈ) ¿ÜºÎ¸Ê¿¡ ½ÇÁ¦ ¼­¹ö Á¤º¸¸¦ ¾ò¾î¿Â´Ù. ¿ÜºÎ¸ÊÀº + ´ÙÀ½°ú °°Àº Çü½ÄÀÌ´Ù

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    ¿ì¸®´Â ÀÌ Á¤º¸¸¦ °¢°¢ map.xxx-to-host + ÆÄÀÏ¿¡ ÀúÀåÇß´Ù. ´ÙÀ½À¸·Î ¸ðµç ¼­¹ö¿¡¼­ URLÀÌ ¼­¹ö¿¡ + ¾ø´Ù¸é ´ÙÀ½°ú °°Àº URLÀ»,

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    ´ÙÀ½°ú °°ÀÌ ¸®´ÙÀÌ·º¼ÇÇÑ´Ù

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    ¾Æ·¡ ±ÔÄ¢Àº ¸ÊÆÄÀÏÀ» »ç¿ëÇÏ¿© ÀÌ ÀÛ¾÷À» ÇÑ´Ù (server0Àº + ¸Ê¿¡ Ç׸ñÀÌ ¾ø´Â °æ¿ì »ç¿ëÇÒ ±âº»¼­¹ö¶ó°í °¡Á¤ÇÑ´Ù):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + + + +

    Ȩµð·ºÅ丮¸¦ ´Ù¸¥ À¥¼­¹ö·Î ÀÌÀü

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¸¹Àº À¥°ü¸®ÀÚ´Â À¥¼­¹öÀÇ ¸ðµç Ȩµð·ºÅ丮¸¦ ´Ù¸¥ + À¥¼­¹ö·Î ÀÌÀüÇÑ °æ¿ì ÇØ°áÃ¥À» ¹°¾îº»´Ù. ÀÌ ¹æ¹ýÀº + ÀÌÀü ¼­¹ö¸¦ ´ëüÇÒ »õ·Î¿î ¼­¹ö¸¦ ±¸¼ºÇϴµ¥ ½Ã°£ÀÌ + °É¸®´Â °æ¿ì¿¡ ÇÊ¿äÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    mod_rewrite¸¦ »ç¿ëÇÏ¸é °£´ÜÇÏ´Ù. + ÀÌÀü À¥¼­¹ö´Â ¸ðµç /~user/anypath URLÀ» + http://newserver/~user/anypath·Î + ¸®´ÙÀÌ·º¼ÇÇÏ¸é µÈ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + + + +

    Ȩµð·ºÅ丮 ±¸Á¶ ¸¸µé±â

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    »ç¿ëÀÚ°¡ ¼öõ¸íÀÎ »çÀÌÆ®´Â º¸Åë Ȩµð·ºÅ丮 ±¸Á¶¸¦ + ¸¸µç´Ù. Áï, ¿¹¸¦ µé¾î À̸§ÀÌ »ç¿ëÀÚ¸íÀÇ Ã¹¹ø° ¹®ÀÚÀÎ + ÇÏÀ§µð·ºÅ丮¿¡ Ȩµð·ºÅ丮¸¦ µÐ´Ù. ±×·¡¼­, + /~foo/anypath´Â + /home/f/foo/.www/anypathÀÌ°í, + /~bar/anypath´Â + /home/b/bar/.www/anypathÀÌ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¹°°áÇ¥½Ã°¡ ÀÖ´Â URLÀ» À§¿Í °°Àº ±¸Á¶·Î º¯È¯ÇϱâÀ§ÇØ + ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + + + +

    ÆÄÀϽýºÅÛ À籸¼º

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÌ ¿¹´Â ½Ç·Î ÇϵåÄÚ¾îÀûÀÌ´Ù: µð·ºÅ丮º° + RewriteRules¸¦ ¸Å¿ì ¸¹ÀÌ »ç¿ëÇÏ¿© ÀÚ·á + ÀÚü´Â ±×´ë·Î µÐü·Î À¥¿¡ ÀڷḦ ÀÚ¿¬½º·´°Ô ºê¶ó¿ì¡Çϵµ·Ï + ÇÑ´Ù. ¹è°æ: ³ª´Â 1992³â ºÎÅÍ ÀÚÀ¯·Ó°Ô »ç¿ëÇÒ ¼ö ÀÖ´Â + À¯´Ð½º ¼ÒÇÁÆ®¿þ¾îµéÀ» net.sw¿¡ + ¸ð¾ÆµÎ°í ÀÖ¾ú´Ù. ÀÌ´Â ³»°¡ ÄÄÇ»ÅÍ°úÇÐÀ» °øºÎÇϸ鼭 + ¿©·¯Çص¿¾È ¿©°¡½Ã°£¿¡ ½Ã½ºÅÛ °ü¸®ÀÚ¿Í ³×Æ®¿÷ °ü¸®ÀÚ¸¦ + ÇؿԱ⶧¹®¿¡ ³» Ãë¹ÌÀÌÀÚ ÀÏÀÌ´Ù. ¸ÅÁÖ¸¶´Ù »õ·Î ¼ÒÇÁÆ®¿þ¾î°¡ + Ãß°¡µÉ ¶§¸¶´Ù µð·ºÅ丮¸¦ ±í°Ô ¸¸µé¾î¿Ô´Ù:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    1996³â 7¿ù ÀÌ ÀúÀå¼Ò¸¦ ¸ÚÀÖ´Â À¥ ÀÎÅÍÆäÀ̽º¸¦ ÅëÇØ + ¼¼»ó¿¡ °ø°³Çϱâ·Î °áÁ¤ÇÞ´Ù. "¸ÚÀÖ´Ù"´Â ¸»Àº, ÃÖ»óÀ§ + µð·ºÅ丮¿¡ CGI ½ºÅ©¸³Æ®¸¦ µÎÁö ¾Ê°íµµ, ÀúÀå¼Ò °èÃþ±¸Á¶¸¦ + Á÷Á¢ ºê¶ó¿ìÁúÇÏ±æ ¹Ù¶õ´Ù´Â ¶æÀÌ´Ù. ¿Ö? ÀúÀå¼Ò¸¦ ³ªÁß¿¡ + FTP·Îµµ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ¸¸µé ¿¹Á¤ÀÌ¿´±â¶§¹®¿¡ À¥À̳ª + CGI¿Í °ü·ÃµÈ ³»¿ëÀ» °°ÀÌ µÎ±â ½È¾ú´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÇØ°áÃ¥Àº µÎ ºÎºÐÀ¸·Î ³ª´¶´Ù: ¸ÕÀú µð·ºÅ丮 ¼öÁØ¿¡¼­ + ÇÊ¿äÇÑ ¸ðµç ÆäÀÌÁö¸¦ µ¿ÀûÀ¸·Î ¸¸µå´Â CGI ½ºÅ©¸³Æ®°¡ + ÇÊ¿äÇÏ´Ù. ³ª´Â ÀÌ ½ºÅ©¸³Æ®µéÀ» ´ÙÀ½°ú °°ÀÌ + /e/netsw/.www/¿¡ µÎ¾ú´Ù:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    DATA/ ÇÏÀ§µð·ºÅ丮¿¡ À§¿¡¼­ ¸»ÇÑ ÀúÀå¼Ò°¡ + ÀÖ´Ù. ½ÇÁ¦ net.swÀÇ ³»¿ëÀº º¸Åë + rdist¸¦ »ç¿ëÇÏ¿© ÀÚµ¿À¸·Î °¡Á®¿Â´Ù. µÎ¹ø° + ºÎºÐÀÌ ³²¾Ò´Ù: ¾î¶»°Ô ÀÌ µÎ ±¸Á¶¸¦ ÇϳªÀÇ ÀÚ¿¬½º·¯¿î + URL ±¸Á¶·Î ¿¬°áÇϴ°¡? »ç¿ëÀÚ¿¡°Ô DATA/ + µð·ºÅ丮¸¦ °¨Ãß°í, URL¸¶´Ù ÀûÀýÇÑ CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ°í + ½Í´Ù. ÇØ°áÃ¥Àº ´ÙÀ½°ú °°´Ù: ¸ÕÀú ¼­¹öÀÇ DocumentRoot¿¡¼­ °ø°³µÈ + URL /net.sw/¸¦ ³»ºÎ °æ·Î /e/netsw·Î + ÀçÀÛ¼ºÇϱâÀ§ÇØ µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    ù¹ø° ±ÔÄ¢Àº ¸¶Áö¸·¿¡ ½½·¡½¬°¡ ¾ø´Â ¿äûÀ» À§Çؼ­ + »ç¿ëÇß´Ù! µÎ¹ø° ±ÔÄ¢ÀÌ ½ÇÁ¦ ÀÛ¾÷À» ÇÑ´Ù. ±×¸®°í µð·ºÅ丮º° + ¼³Á¤ÆÄÀÏ /e/netsw/.www/.wwwacl¿¡ °áÁ¤ÀûÀÎ + ¼³Á¤ÀÌ ³ª¿Â´Ù:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  ¾Õ ºÎºÐÀÌ /net.sw/ ·Î Á¢±ÙÇÑ´Ù
    +RewriteBase   /net.sw/
    +
    +#  ¸ÕÀú ÃÖ»óÀ§ µð·ºÅ丮¸¦
    +#  cgi ½ºÅ©¸³Æ®·Î ÀçÀÛ¼ºÇÑ´Ù
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  ºê¶ó¿ìÀú°¡ µð·ºÅ丮º° ÆäÀÌÁö¸¦ ¿äûÇÑ °æ¿ì
    +#  ÇÏÀ§µð·ºÅ丮¸¦ ÃßÃâÇÑ´Ù
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  ÀÌÁ¦ ÀçÀÛ¼ºÀ» ¸¶Ä£´Ù
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  ´Ù¸¥ cgi ½ºÅ©¸³Æ®°¡ ó¸®ÇÒ
    +#  ÇÏÀ§µð·ºÅ丮°¡ ³²¾Ò´Ù
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Çؼ®À» À§ÇÑ ÈùÆ®:

    + +
      +
    1. ³×¹ø° ºÎºÐ¿¡¼­ ´ëü Çʵå('-')°¡ + ¾ø°í L (last) Ç÷¡±×°¡ ÀÖÀ½À» ÁÖ¸ñÇ϶ó
    2. + +
    3. ¸¶Áö¸· ºÎºÐ¿¡¼­ ù¹ø° ±ÔÄ¢¿¡ ! + (not) ¹®ÀÚ¿Í C (chain) Ç÷¡±×¸¦ ÁÖ¸ñÇ϶ó
    4. + +
    5. ¸¶Áö¸· ±ÔÄ¢¿¡¼­ ±âŸ ÇØ´çÇÏÁö ¾Ê´Â ¸ðµç °æ¿ì¸¦ + Àâ¾Æ³»´Â ÆÐÅÏÀ» ÁÖ¸ñÇ϶ó
    6. +
    +
    +
    + + + +

    NCSA imagemapÀ» ¾ÆÆÄÄ¡ mod_imapÀ¸·Î

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    »ç¶÷µéÀº NCSA À¥¼­¹ö¿¡¼­ Çö´ëÀûÀÎ ¾ÆÆÄÄ¡ À¥¼­¹ö·Î + ÀÚ¿¬½º·´°Ô ¿Å°Ü°¡±æ ¹Ù¶õ´Ù. ±×·¡¼­ ¿À·¡µÈ NCSA + imagemap ÇÁ·Î±×·¥À» »ç¿ëÇÑ ÆäÀÌÁö¸¦ Çö´ëÀûÀÎ + ¾ÆÆÄÄ¡ mod_imap·Î ó¸®ÇÏ±æ ¹Ù¶õ´Ù. + ¹®Á¦´Â imagemap ÇÁ·Î±×·¥À» + /cgi-bin/imagemap/path/to/page.map°ú + °°ÀÌ ÂüÁ¶ÇÏ´Â ÇÏÀÌÆÛ¸µÅ©°¡ ¸¹´Ù´Â °ÍÀÌ´Ù. ¾ÆÆÄÄ¡´Â + /path/to/page.map°ú °°Àº ¿äûÀ» ¹Þ¾Æ¾ß + ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ðµç ¿äû¿¡¼­ ¾ÕºÎºÐÀ» µ¿ÀûÀ¸·Î Á¦°ÅÇÏ´Â Àü¿ª ±ÔÄ¢À» + »ç¿ëÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteRule    ^/cgi-bin/imagemap(.*)  $1  [PT]
    +
    +
    +
    + + + +

    ¿©·¯ µð·ºÅ丮¿¡¼­ ÆäÀÌÁö °Ë»ö

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡²û À¥¼­¹ö°¡ ¿©·¯ µð·ºÅ丮¿¡¼­ ÆÄÀÏÀ» ã¾Æ¾ß ÇÒ + ¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì MultiViews³ª ´Ù¸¥ ¹æ¹ýÀº µµ¿òÀÌ + ¾ÈµÈ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿©·¯ µð·ºÅ丮¿¡¼­ ÆÄÀÏÀ» ã´Â ±ÔÄ¢À» Á÷Á¢ ÇÁ·Î±×·¥ÇÑ´Ù.

    + +
    +RewriteEngine on
    +
    +#   ¸ÕÀú custom/¿¡¼­ ã±æ ½ÃµµÇÏ°í...
    +#   ...ãÀ¸¸é ³¡!
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   µÎ¹ø°·Î pub/¿¡¼­ ã±æ ½ÃµµÇÑ´Ù...
    +#   ...ãÀ¸¸é ³¡!
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   ¸øãÀ¸¸é ´Ù¸¥ Alias³ª ScriptAlias Áö½Ã¾î µîÀ¸·Î ÁøÇàÇÑ´Ù.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + + + +

    URL¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿äûµé°£¿¡ »óÅÂÁ¤º¸¸¦ À¯ÁöÇϱâÀ§ÇØ URL¿¡ Á¤º¸¸¦ + ÀÎÄÚµùÇÏ´Â ¹æ¹ýµµ ÀÖ´Ù. ±×·¯³ª ´ÜÁö ÀÌ Á¤º¸¸¦ Á¦°ÅÇϱâÀ§ÇØ + ¸ðµç ÆäÀÌÁö¿¡ CGI wrapper¸¦ »ç¿ëÇÏ°í ½ÍÁö ¾Ê´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º ±ÔÄ¢À» »ç¿ëÇÏ¿© »óÅÂÁ¤º¸¸¦ ÃßÃâÇÏ°í, ÃßÃâÇÑ + Á¤º¸¸¦ ³ªÁß¿¡ XSSI³ª CGI¿¡¼­ »ç¿ëÇϱâÀ§ÇØ È¯°æº¯¼ö¿¡ + ÀúÀåÇÑ´Ù. ±×·¡¼­ URL /foo/S=java/bar/´Â + /foo/bar/·Î º¯È¯µÇ°í STATUS¶ó´Â + ȯ°æº¯¼ö °ªÀ» "java"·Î ¼³Á¤ÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + + + +

    °¡»ó »ç¿ëÀÚ È£½ºÆ®

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏÁö ¾Ê°í °°Àº ÄÄÇ»ÅÍ·Î DNS A + ·¹Äڵ带 ¼³Á¤ÇÏ¿© + www.username.host.domain.comÀ» + »ç¿ëÀÚÀÇ È¨ÆäÀÌÁö·Î Á¦°øÇÏ°í ½Í´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    HTTP/1.0 ¿äûÀÇ °æ¿ì ¹æ¹ýÀÌ ¾øÁö¸¸, Host: HTTP + Çì´õ¸¦ Æ÷ÇÔÇÑ HTTP/1.1 ¿äûÀº ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÏ¿© + ³»ºÎÀûÀ¸·Î http://www.username.host.com/anypath¸¦ + /home/username/anypath·Î ÀçÀÛ¼ºÇÒ ¼ö + ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + + + +

    Ȩµð·ºÅ丮¸¦ ¿ÜºÎ ¼­¹ö·Î ¸®´ÙÀÌ·º¼Ç

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    Áö¿ª µµ¸ÞÀÎ ourdomain.com ¹Û¿¡¼­ ¿äûÀÌ + µé¾î¿À¸é Ȩµð·ºÅ丮 URLÀ» ´Ù¸¥ À¥¼­¹ö + www.somewhere.comÀ¸·Î ¸®´Ù¸®·º¼ÇÇϱæ + ¹Ù¶õ´Ù. Á¾Á¾ °¡»óÈ£½ºÆ® »ç¿ëÀå¼Ò¿¡¼­ »ç¿ëÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º Á¶°ÇÀ» »ç¿ëÇÏ¸é µÈ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + + + +

    ½ÇÆÐÇÑ URLÀ» ´Ù¸¥ À¥¼­¹ö·Î ¸®´ÙÀÌ·º¼Ç

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    URL ÀçÀÛ¼º¿¡ ´ëÇؼ­ À¥¼­¹ö A¿¡ ÇØ´ç ÆÄÀÏÀÌ ¾ø´Â + °æ¿ì À¥¼­¹ö B·Î ¿äûÀ» ¸®´ÙÀÌ·º¼ÇÇÏ´Â ¹æ¹ýÀ» ÀÚÁÖ + ¹°¾îº»´Ù. º¸Åë Perl·Î ÀÛ¼ºÇÑ ErrorDocument CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏÁö¸¸, mod_rewrite¸¦ »ç¿ëÇÏ´Â + ¹æ¹ýµµ ÀÖ´Ù. ±×·¯³ª ¼º´ÉÀº ErrorDocument CGI ½ºÅ©¸³Æ®º¸´Ù + ¶³¾îÁüÀ» ¸í½ÉÇ϶ó!

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ù¹ø° ¹æ¹ýÀº ºü¸£Áö¸¸ À¯¿¬¼ºÀÌ ¶³¾îÁö°í ¿ÏÀüÇÏÁö + ¾Ê´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    ÀÌ ¹æ¹ýÀÇ ´ÜÁ¡Àº DocumentRoot ¾È¿¡ ÀÖ´Â ÆäÀÌÁö¸¸ + °¡´ÉÇÏ´Ù´Â Á¡ÀÌ´Ù. (¿¹¸¦ µé¾î Ȩµð·ºÅ丮 µîÀ» À§ÇØ) + Á¶°ÇÀ» Ãß°¡ÇÒ ¼ö ÀÖÁö¸¸, ´õ ÁÁÀº ¹æ¹ýÀÌ ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    mod_rewriteÀÇ URL Àü¹æÂüÁ¶(look-ahead)¸¦ + »ç¿ëÇÑ´Ù. ±×·¡¼­ ¸ðµç URL¿¡ µ¿ÀÛÇÏ°í ¾ÈÀüÇÏ´Ù. ±×·¯³ª + ¸ðµç ¿äû¸¶´Ù ³»ºÎ ÇÏÀ§¿äûÀ» Çѹø ´õ Çϱ⶧¹®¿¡ À¥¼­¹ö + ¼º´É¿¡ ¾Ç¿µÇâÀ» ÁØ´Ù. ±×·¡¼­ °­·ÂÇÑ CPU¿¡¼­ À¥¼­¹ö¸¦ + ½ÇÇàÇÑ´Ù¸é »ç¿ëÇ϶ó. ÄÄÇ»ÅÍ°¡ ´À¸®´Ù¸é ù¹ø° ¹æ¹ýÀ̳ª + ´õ ³ªÀº ErrorDocument + CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇ϶ó.

    +
    +
    + + + +

    È®Àå ¸®´ÙÀÌ·º¼Ç

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡²û ¸®´ÙÀÌ·º¼ÇÇÏ´Â URLÀ» ´õ Á¶ÀýÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. + ¾ÆÆÄÄ¡ ³»ºÎ URL escape ÇÔ¼ö´Â "url#anchor" + °°Àº URLÀÇ anchorµµ escapeÇÑ´Ù. ¾ÆÆÄÄ¡ÀÇ + uri_escape() ÇÔ¼ö´Â ¿ì¹°Á¤ÀÚ(#)µµ °°ÀÌ + escapeÇϹǷΠ»ç¿ëÇÒ ¼ö ¾ø´Ù. ±×·¯¸é ¾î¶»°Ô ÀÌ·± URL·Î + ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    Á÷Á¢ ¸®´ÙÀÌ·º¼ÇÇÏ´Â NPH-CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ ÇØ°áÃ¥ÀÌ + ÇÊ¿äÇÏ´Ù. escape¸¦ ÇÏÁö ¾Ê±â¶§¹®ÀÌ´Ù (NPH=non-parseable + headers). ¸ÕÀú ´ÙÀ½ ¼­¹ö¼³Á¤À» ÇÏ¿© (ÀçÀÛ¼º ±ÔÄ¢ÀÇ + ³¡ºÎºÐ¿¡ »ç¿ëÇØ¾ß ÇÑ´Ù) »õ·Î¿î URL scheme + xredirect:¸¦ µµÀÔÇÑ´Ù:

    + +
    +RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
    +            [T=application/x-httpd-cgi,L]
    +
    + +

    ±×·¯¸é xredirect:·Î ½ÃÀÛÇÏ´Â ¸ðµç URLÀº + nph-xredirect.cgi ÇÁ·Î±×·¥À» ÅëÇÏ°Ô µÈ´Ù. + ÇÁ·Î±×·¥Àº ´ÙÀ½°ú °°´Ù:

    + +
    +#!/path/to/perl
    +##
    +##  nph-xredirect.cgi -- NPH/CGI script for extended redirects
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +
    +$| = 1;
    +$url = $ENV{'PATH_INFO'};
    +
    +print "HTTP/1.0 302 Moved Temporarily\n";
    +print "Server: $ENV{'SERVER_SOFTWARE'}\n";
    +print "Location: $url\n";
    +print "Content-type: text/html\n";
    +print "\n";
    +print "<html>\n";
    +print "<head>\n";
    +print "<title>302 Moved Temporarily (EXTENDED)</title>\n";
    +print "</head>\n";
    +print "<body>\n";
    +print "<h1>Moved Temporarily (EXTENDED)</h1>\n";
    +print "The document has moved <a HREF=\"$url\">here</a>.<p>\n";
    +print "</body>\n";
    +print "</html>\n";
    +
    +##EOF##
    +
    + +

    ±×·¯¸é mod_rewrite°¡ Á÷Á¢ ¹ÞÁö¸øÇÏ´Â + ¸ðµç URL schemeÀ¸·Î ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + ´ÙÀ½°ú °°ÀÌ news:newsgroupÀ¸·Î ¸®´ÙÀÌ·º¼ÇÇÒ + ¼ö ÀÖ´Ù

    + +
    +RewriteRule ^anyurl  xredirect:news:newsgroup
    +
    + +
    ÁÖÀÇ: À§ÀÇ Æ¯º°ÇÑ "Åë°ú" ±ÔÄ¢À» »ç¿ëÇÏ¿© + xredirect:¸¦ ¸¶Áö¸·¿¡ È®ÀåÇØ¾ß Çϱ⶧¹®¿¡ + ±ÔÄ¢¿¡ [R]À̳ª [R,L]À» »ç¿ëÇϸé + ¾ÈµÈ´Ù.
    +
    +
    + + + +

    ÀúÀå¼Ò Á¢±Ù Áß°è(multiplexer)

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    http://www.perl.com/CPAN¿¡ + ÀÖ´Â ´ë´ÜÇÑ CPAN (Comprehensive Perl Archive Network)À» + ¾Æ´Â°¡? ÀÌ ÁÖ¼Ò´Â ¼¼°è¿¡ Èð¾îÁø ¿©·¯ CPAN ¹Ì·¯ FTP + ¼­¹öÁß Å¬¶óÀ̾ðÆ®¿¡ °¡±îÀÌ ÀÖ´Â ¼­¹ö·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. + À̸¦ FTP Á¢±Ù Áß°è ¼­ºñ½º¶ó°í ÇÑ´Ù. CPANÀº CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏÁö¸¸, mod_rewrite¸¦ »ç¿ëÇÏ¿© + ºñ½ÁÇÏ°Ô ¸¸µé ¼ö ÀÖÀ»±î?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú mod_rewrite 3.0.0 ¹öÀüºÎÅÍ + ¸®´ÙÀÌ·º¼Ç¿¡ "ftp:" schemeÀ» »ç¿ëÇÒ ¼ö + ÀÖ´Ù. ´ÙÀ½À¸·Î Ŭ¶óÀ̾ðÆ®ÀÇ ÃÖ»óÀ§ µµ¸ÞÀÎÀ» RewriteMap°ú °°ÀÌ + »ç¿ëÇÏ¿© À§Ä¡¸¦ ÃßÁ¤ÇÒ ¼ö ÀÖ´Ù. º¹ÀâÈ÷ ¿«ÀÎ ±ÔÄ¢¿¡¼­ + ÃÖ»óÀ§ µµ¸ÞÀÎÀ» Áß°è¸ÊÀÇ Å°·Î »ç¿ëÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + + + +

    ½Ã°£¿¡ µû¸¥ ÀçÀÛ¼º

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ½Ã°£¿¡ µû¶ó ´Ù¸¥ ³»¿ëÀ» ¼­ºñ½ºÇÏ´Â °æ¿ì ¸¹Àº À¥°ü¸®ÀÚ´Â + Àá½Ã Ưº°ÇÑ ÆäÀÌÁö·Î ¸®´ÙÀÌ·º¼ÇÇϱâÀ§ÇØ CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÑ´Ù. mod_rewrite·Î´Â ¾î¶»°Ô + ÇÒ ¼ö Àִ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º Á¶°Ç¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ¿©·¯ TIME_xxx + º¯¼ö°¡ ÀÖ´Ù. º¯¼ö¿Í Ưº°ÇÑ »çÀü¼ø¼­ ºñ±³ + <STRING, >STRING, + =STRINGÀ» »ç¿ëÇÏ¿© ½Ã°£¿¡ µû¶ó ¸®´ÙÀÌ·º¼ÇÇÒ + ¼ö ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    URL foo.htmlÀ» ¿äûÇϸé + 07:00-19:00 µ¿¾È foo.day.html + ³»¿ëÀ» ¼­ºñ½ºÇÏ°í, ³ª¸ÓÁö ½Ã°£ µ¿¾È + foo.night.html ³»¿ëÀ» ¼­ºñ½ºÇÑ´Ù. ȨÆäÀÌÁö¿¡¼­ + »ç¿ëÇϱâ ÁÁÀº ±â´ÉÀÌ´Ù...

    +
    +
    + + + +

    YYYY¸¦ XXXX·Î ÀÌÀüÇÑ °æ¿ì ¿ªÈ£È¯

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿©·¯ .html ÆÄÀÏÀ» .phtml·Î + º¯È¯ÇÏ´Â µî document.YYYY¸¦ + document.XXXX·Î ÀÌÀüÇÑÈÄ ¿ªÈ£È¯(backward + compatibility) URLÀ» (°¡»óÀûÀ¸·Î Á¸ÀçÇÏ°Ô) ¸¸µé ¼ö + ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    À̸§À» ±âº»À̸§À¸·Î ÀçÀÛ¼ºÇÑÈÄ »õ·Î¿î È®ÀåÀÚ¸¦ + °¡Áø ÆÄÀÏÀÌ ÀÖ´ÂÁö °Ë»çÇÑ´Ù. ÀÖ´Ù¸é ±× ÆÄÀϸíÀ» »ç¿ëÇÏ°í, + ¾øÀ¸¸é URLÀ» ¿ø·¡ »óÅ·ΠÀçÀÛ¼ºÇÑ´Ù.

    + + +
    +#   ¹®¼­.html ÀÌ ¾ø°í
    +#   ¹®¼­.phtml ¸¸ ÀÖ´Â °æ¿ì
    +#   ¹®¼­.html À» ¹®¼­.phtml ·Î
    +#   ÀçÀÛ¼ºÇÏ´Â ¿ªÈ£È¯ ±ÔÄ¢
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   ±âº»À̸§À» ã°í, ã¾Ò´Ù´Â »ç½ÇÀ» ±â¾ïÇÑ´Ù
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   ÆÄÀÏÀÌ ÀÖ´Ù¸é ¹®¼­.phtml ·Î ÀçÀÛ¼ºÇÑ´Ù
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   ¾Æ´Ï¸é ¾Õ¿¡¼­ ãÀº ±âº»À̸§À» µÇµ¹¸°´Ù
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + + + +
    top
    +
    +

    ÄÁÅÙÃ÷ ´Ù·ç±â

    + + + +

    »õ·Î ÀÌÀü (°¨Ãß±â)

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÃÖ±Ù foo.htmlÀ» bar.html·Î + º¯°æÇÏ°í ¿ªÈ£È¯¼ºÀ» À§ÇØ ÀÌÀü URLÀ» °è¼Ó Á¦°øÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. »ç¿ëÀÚ´Â ÀÌÀü URLÀÌ º¯°æµÇ¾ú´Ù´Â + »ç½ÇÀ» ´«Ä¡Ã¤Áö ¸øÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ´ÙÀ½ ±ÔÄ¢À¸·Î ÀÌÀü URLÀ» ³»ºÎÀûÀ¸·Î »õ·Î¿î URL·Î + ÀçÀÛ¼ºÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + + + +

    »õ·Î ÀÌÀü (¾Ë¸®±â)

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ´Ù½Ã foo.htmlÀ» bar.html·Î + º¯°æÇÏ°í ¿ªÈ£È¯¼ºÀ» À§ÇØ ÀÌÀü URLÀ» °è¼Ó Á¦°øÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. ±×·¯³ª ÀÌÁ¦´Â ÀÌÀü URLÀ» »ç¿ëÇϸé + »ç¿ëÀÚ¿¡°Ô »õ·Î¿î URLÀ» ÈùÆ®·Î ¾Ë·ÁÁØ´Ù. Áï, ºê¶ó¿ìÀú + ÁÖ¼ÒâÀÌ º¯ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    »õ·Î¿î URL·Î HTTP ¸®´ÙÀÌ·º¼ÇÇÏ´Ù. ±×·¯¸é ºê¶ó¿ìÀú°¡ + »õ·Î¿î URL¸¦ º¸ÀÌ°í º¯°æ»ç½ÇÀ» »ç¿ëÀÚ°¡ ¾Ë°ÔµÈ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + + + +

    ºê¶ó¿ìÀú¿¡ µû¸¥ ³»¿ë

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÃÖ¼ÒÇÑ Áß¿äÇÑ ÃÖ»óÀ§ ÆäÀÌÁö´Â ºê¶ó¿ìÀú¿¡ ÃÖÀûÈ­µÈ + ³»¿ëÀ¸·Î ¼­ºñ½ºÇؾßÇÒ °æ¿ì°¡ ÀÖ´Ù. Áï, ÃֽŠNetscape + ºê¶ó¿ìÀú¿¡°Ô´Â ÃÖ»óÀÇ ¹öÀüÀ», Lynx ºê¶ó¿ìÀú¿¡°Ô´Â + ÃÖÀú ¹öÀüÀ», ³ª¸ÓÁö ºê¶ó¿ìÀú¿¡´Â Æò±ÕÀûÀÎ ¹öÀüÀ» + Á¦°øÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ºê¶ó¿ìÀú°¡ ³»¿ëÇù»óÀ» À§ÇØ ÀÚ½ÅÀÇ Á¾·ù¿¡ ´ëÇÑ Á¤º¸¸¦ + Á¦°øÇÏÁö ¾Ê±â¶§¹®¿¡ ³»¿ëÇù»óÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ´ë½Å + HTTP "User-Agent" Çì´õ¸¦ »ç¿ëÇÑ´Ù. ´ÙÀ½ ±ÔÄ¢Àº HTTP + "User-Agent" Çì´õ°¡ "Mozilla/3"À¸·Î ½ÃÀÛÇϸé + foo.html ÆäÀÌÁö¸¦ foo.NS.html·Î + ÀçÀÛ¼ºÇÏ°í ÀçÀÛ¼ºÀ» Áß´ÜÇÑ´Ù. ºê¶ó¿ìÀú°¡ "Lynx"³ª + "Mozilla" ¹öÀü 1 ȤÀº 2¶ó¸é URLÀº + foo.20.htmlÀÌ µÈ´Ù. ³ª¸ÓÁö ºê¶ó¿ìÀú´Â + foo.32.html ÆäÀÌÁö¸¦ ¹Þ´Â´Ù. ¾Æ·¡ ±ÔÄ¢ÀÌ + ÀÌ ÀÛ¾÷À» ÇÑ´Ù:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + + + +

    µ¿Àû ¹Ì·¯

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿ÜºÎ È£½ºÆ®¿¡ ¿ì¸® »çÀÌÆ®·Î °¡Á®¿À°í ½ÍÀº ÁÁÀº + À¥ÆäÀÌÁö°¡ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. FTP ¼­¹öÀÇ °æ¿ì Á÷Á¢ ¿ÜºÎ + ÀÚ·áÀÇ Ãֽź¹»çº»À» À¯ÁöÇÏ´Â mirror ÇÁ·Î±×·¥À» + »ç¿ëÇÒ ¼ö ÀÖ°í, À¥¼­¹ö¶ó¸é HTTP·Î ºñ½ÁÇÑ ÀÛ¾÷À» ÇÏ´Â + webcopy ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª + µÎ ¹æ¹ý ¸ðµÎ ´ÜÁ¡ÀÌ ÀÖ´Ù: º¹»çº»Àº °¡²û¾¿ ÇÁ·Î±×·¥À» + ½ÇÇàÇØÁÙ ¶§¸¸ ÃÖ½ÅÆÇÀ¸·Î À¯ÁöµÈ´Ù. Á÷Á¢ ±¸¼ºÇؾßÇÏ´Â + Á¤ÀûÀÎ ¹Ì·¯°¡ ¾Æ´Ï¶ó¸é ÁÁ°Ú´Ù. ´ë½Å (¿ÜºÎ È£½ºÆ®¿¡¼­ + ÀÚ·á°¡ °»½ÅµÇ¸é) ÇÊ¿äÇÒ¶§ ÀÚµ¿À¸·Î ÀڷḦ °»½ÅÇÏ´Â + µ¿Àû ¹Ì·¯°¡ ÇÊ¿äÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    À̸¦ À§ÇØ Proxy Throughput ±â´ÉÀ» (Ç÷¡±× + [P]) »ç¿ëÇÏ¿© ¿ÜºÎ À¥ÆäÀÌÁö ȤÀº ¿ÜºÎ + À¥°ø°£ Àüü¸¦ ¿ì¸® À̸§°ø°£À¸·Î ´ëÀÀÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + + + +

    µ¿Àû ¿ª¹Ì·¯

    + + + +
    +
    »óȲ¼³¸í:
    + +
    ...
    + +
    ÇØ°áÃ¥:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + + + +

    ¾ø´Â ÀڷḦ ÀÎÆ®¶ó³Ý¿¡¼­ °¡Á®¿À±â

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ½ÇÁ¦ ÀڷḦ ¹æÈ­º®ÀÌ º¸È£ÇÏ´Â (³»ºÎ) ÀÎÆ®¶ó³Ý À¥¼­¹ö¿¡ + (www2.quux-corp.dom) ÀúÀåÇϸ鼭, ±â¾÷ÀÇ + (¿ÜºÎ) ÀÎÅÍ³Ý À¥¼­¹ö¸¦ (www.quux-corp.dom) + ½ÇÇàÇÏ´Â °Íó·³ º¸ÀÌ°Ô ÇÑ´Ù. ¿ÜºÎ À¥¼­¹ö´Â ¿äûÇÑ + ÀڷḦ ³»ºÎ À¥¼­¹ö¿¡¼­ °¡Á®¿Â´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú ¹æÈ­º®ÀÌ ³»ºÎ À¥¼­¹ö¸¦ º¸È£ÇÏ°í ¿ÜºÎ À¥¼­¹ö¸¸ÀÌ + ³»ºÎ À¥¼­¹ö¿¡¼­ ÀڷḦ ¾òÀ» ¼ö ÀÖ°Ô ÇÑ´Ù. ´ÙÀ½°ú °°ÀÌ + ÆÐŶÇÊÅ͸µ ¹æÈ­º®À» ¼³Á¤ÇÑ´Ù:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    ½ÇÁ¦ ¼³Á¤¹®¹ý¿¡ ¾Ë¸Â°Ô °íÃĶó. ¾ø´Â ÀڷḦ ³»ºÎÀûÀ¸·Î + proxy throughput ±â´ÉÀ» ÅëÇØ ¿äûÇÏ´Â + mod_rewrite ±ÔÄ¢À» ÀÛ¼ºÇÑ´Ù:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + + + +

    ·Îµå¹ë·±½Ì (ºÎÇÏ ºÐ»êÇϱâ)

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    www.foo.comÀÇ Åë½Å·®À» + www[0-5].foo.com (ÃÑ ¼­¹ö 6´ë)À¸·Î ºÐ»êÇÏ°í + ½Í´Ù. ¾î¶»°Ô Çϴ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸Å¿ì ´Ù¾çÇÑ ¹æ¹ýÀ¸·Î ÀÌ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Ù. + ¸ÕÀú DNS¸¦ »ç¿ëÇÑ Àß ¾Ë·ÁÁø ¹æ¹ýÀ» ¼³¸íÇÏ°í, + mod_rewrite¸¦ »ç¿ëÇÏ´Â °æ¿ì¸¦ »ìÆ캸ÀÚ:

    + +
      +
    1. + DNS Round-Robin + +

      °¡Àå °£´ÜÇÑ ·Îµå¹ë·±½Ì ¹æ¹ýÀº BINDÀÇ + DNS round-robin ¹æ½ÄÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ´ÙÀ½°ú + °°ÀÌ DNS A(address) ·¹Äڵ忡 + www[0-9].foo.comÀ» ¼³Á¤ÇÑ´Ù.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      ±×¸®°í ´ÙÀ½ Ç׸ñÀ» Ãß°¡ÇÑ´Ù:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      À߸øµÈ °Íó·³ º¸ÀÌÁö¸¸, ½ÇÁ¦·Î BINDÀÇ + ÀǵµµÈ ±â´ÉÀÌ´Ù. ÀÌÁ¦ www.foo.comÀ» + ãÀ¸¸é, BIND´Â ¸Å¹ø ¼ø¼­¸¦ Á¶±Ý¾¿ + ¹Ù²ã°¡¸ç www0-www6À» ¹ÝȯÇÑ´Ù. ±×·¡¼­ + Ŭ¶óÀ̾ðÆ®µéÀ» ¿©·¯ ¼­¹ö·Î ºÐ»êÇÑ´Ù. ±×·¯³ª DNS + °Ë»ö °á°ú°¡ ³×Æ®¿÷ÀÇ ´Ù¸¥ ³×ÀÓ¼­¹ö¿¡ ij½¬µÇ¿© + www.foo.comÀ» ãÀº °á°ú°¡ ƯÁ¤ + wwwN.foo.comÀ̸é Ŭ¶óÀ̾ðÆ®ÀÇ ´ÙÀ½ + ¿äûµéµµ °°Àº wwwN.foo.comÀ¸·Î + º¸³»Áö±â¶§¹®¿¡ ¿Ïº®ÇÑ ·Îµå¹ë·±½Ì ±â¹ýÀÌ ¾Æ´ÔÀ» + ÁÖÀÇÇ϶ó. ±×·¯³ª Å©°Ô º¸¸é ¿äûÀÌ ¿©·¯ À¥¼­¹ö¿¡ + ºÐ»êµÇ¹Ç·Î È¿°ú°¡ ÁÁ´Ù.

      +
    2. + +
    3. + DNS ·Îµå¹ë·±½Ì + +

      http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html¿¡ + ÀÖ´Â lbnamed ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© + Á¤±³ÇÑ DNS±â¹Ý ·Îµå¹ë·±½ÌÀ» ÇÒ ¼ö ÀÖ´Ù. DNS°¡ + ½ÇÁ¦ ·Îµå¹ë·±½ÌÀ» Çϵµ·Ï ¸¸µå´Â ¿©·¯ µµ±¸¿Í Perl + 5 ÇÁ·Î±×·¥ÀÌ´Ù.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      ÀÌ ¹æ¹ýÀº mod_rewrite¿Í proxy + throughput ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¸ÕÀú DNS¿¡ ´ÙÀ½ Ç׸ñÀ» + »ç¿ëÇÏ¿© www0.foo.comÀÌ ½ÇÁ¦ + www.foo.comÀ» Àü´ãÇÏ°Ô ÇÑ´Ù

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      ±×¸®°í www0.foo.comÀ» ÇÁ·Ï½ÃÀü¿ë + ¼­¹ö·Î º¯°æÇÑ´Ù. Áï, URLÀ» ¹ÞÀ¸¸é ¼­¹ö´Â ³»ºÎ + ÇÁ·Ï½Ã¸¦ ÅëÇØ ´Ù¸¥ 5´ë ¼­¹öÁß (www1-www5) + ÇÑ´ë·Î º¸³»±â¸¸ ÇÑ´Ù. À̸¦ À§ÇØ ¸ÕÀú ¸ðµç URLÀ» + ·Îµå¹ë·±½Ì ½ºÅ©¸³Æ® lb.pl·Î º¸³»´Â + ±ÔÄ¢À» ¸¸µç´Ù.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      lb.plÀ» ÀÛ¼ºÇÑ´Ù:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- ·Îµå¹ë·±½Ì ½ºÅ©¸³Æ®
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # ±âº» È£½ºÆ®¸í
      +$first  = 1;         # ù¹ø° ¼­¹ö (ÀÚ½ÅÀÌ 0À̱⠶§¹®¿¡, 0À» »ç¿ëÇÏÁö ¾Ê´Â´Ù)
      +$last   = 5;         # round-robin¿¡¼­ ¸¶Áö¸· ¼­¹ö
      +$domain = "foo.dom"; # µµ¸ÞÀθí
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + +
      ¸¶Áö¸· ÁÖÀÇ: ¿Ö ÀÌ ¹æ¹ýÀÌ À¯¿ëÇÑ°¡? + www0.foo.com¿¡ ºÎ´ãÀÌ °¡Áö¾Ê´Â°¡? + ¹°·Ð, ºÎ´ãÀÌ µÈ´Ù. ±×·¯³ª ´Ü¼øÇÑ proxy throughput + ¿äû¸¸ Çϱ⶧¹®¿¡ ±¦Âú´Ù! ¸ðµç SSI, CGI, ePerl + µîÀº ÀüÀûÀ¸·Î ´Ù¸¥ ¼­¹ö°¡ ó¸®ÇÑ´Ù. ÀÌ°ÍÀÌ ÇÙ½ÉÀÌ´Ù.
      +
    6. + +
    7. + Çϵå¿þ¾î/TCP Round-Robin + +

      Çϵå¿þ¾î¸¦ »ç¿ëÇÑ ÇØ°áÃ¥µµ ÀÖ´Ù. Cisco´Â TCP/IP + ¼öÁØ¿¡¼­ ·Îµå¹ë·±½ÌÀ» ÇÏ´Â LocalDirector¶ó´Â ±«¹°À» + ÆÇ´Ù. ½ÇÁ¦·Î´Â À¥¼­¹ö±º ¾Õ´Ü¿¡ À§Ä¡ÇÏ´Â ÀÏÁ¾ÀÇ + ȸ·Î¼öÁØ °ÔÀÌÆ®¿þÀÌ´Ù. ÀÚ±ÝÀÌ ÃæºÐÇÏ°í °í¼º´É + ÇØ°áÃ¥ÀÌ ÇÊ¿äÇÏ´Ù¸é ÀÌ°ÍÀ» »ç¿ëÇ϶ó.

      +
    8. +
    +
    +
    + + + +

    »õ·Î¿î MIME-type, »õ·Î¿î ¼­ºñ½º

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ³×Æ®¿÷¿¡´Â ¸ÚÁø CGI ÇÁ·Î±×·¥µéÀÌ ¸¹´Ù. ±×·¯³ª »ç¿ëÇϱâ + ¹ø°Å·¯¿ö¼­ ¸¹Àº À¥°ü¸®ÀÚ°¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù. ¾ÆÆÄÄ¡ÀÇ + MIME-type¿¡ µû¸¥ Action Çڵ鷯 ±â´Éµµ CGI ÇÁ·Î±×·¥ÀÌ + Ưº°ÇÑ URLÀ» (Á¤È®È÷ PATH_INFO¿Í + QUERY_STRINGS) ÇÁ·Î±×·¥ÀÇ ÀÔ·ÂÀ¸·Î »ç¿ëÇÏÁö + ¾ÊÀ» ¶§¸¸ ÀûÀýÇÏ´Ù. ¸ÕÀú, È®ÀåÀÚ°¡ (secure CGI¸¦ ÁÙ¿©) + .scgiÀÎ ÆÄÀÏÀ» À¯¸íÇÑ cgiwrap + ÇÁ·Î±×·¥À¸·Î ó¸®ÇϱâÀ§ÇØ »õ·Î¿î typeÀ» ¼³Á¤ÇÑ´Ù. + ¹®Á¦´Â (À§¿¡¼­ º») ÀÏ°üµÈ URL ±¸Á¶¸¦ »ç¿ëÇÏ´Â °æ¿ì + »ç¿ëÀÚ È¨µð·ºÅ丮°¡ /u/user/foo/bar.scgi°°Àº + URLÀÎ Á¡ÀÌ´Ù. cgiwrap´Â + /~user/foo/bar.scgi/ Çü½ÄÀÇ URLÀ» + ¿øÇϱ⶧¹®ÀÌ´Ù. ´ÙÀ½ ±ÔÄ¢ÀÌ ¹®Á¦¸¦ ÇØ°áÇÑ´Ù:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    ÀÌÁ¦ ´Ù¸¥ ¸ÚÁø ÇÁ·Î±×·¥, (URL ÇÏÀ§Æ®¸®¿¡ ´ëÇÑ + access.log¸¦ Ãâ·ÂÇÏ´Â) wwwlog¿Í + (URL ÇÏÀ§Æ®¸®¿¡ Glimpse¸¦ ½ÇÇàÇÏ´Â) wwwidx°¡ + ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. ¿ì¸®´Â ÇÁ·Î±×·¥¿¡°Ô ÀÛ¾÷ÇÒ ´ë»óÀÎ + URL ¿µ¿ªÀ» ¾Ë·ÁÁà¾ß ÇÑ´Ù. ±×·¯³ª ¿äûÇÒ¶§¸¶´Ù Ç×»ó + Àû¾îÁà¾ß Çϱ⶧¹®¿¡ ±ò²ûÇÏÁö ¾Ê´Ù. Áï, º¸Åë + /u/user/foo/¿¡ ´ëÇØ swwidx + ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù¸é ´ÙÀ½°ú °°Àº ¸µÅ©¸¦ »ç¿ëÇÑ´Ù

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    ±ò²ûÇÏÁö ¾Ê´Ù. ¸µÅ©¿¡ ¿µ¿ªÀÇ À§Ä¡¿Í + CGI À§Ä¡¸¦ ¸ðµÎ Àû¾î¾ß Çϱ⶧¹®ÀÌ´Ù. + ¿µ¿ªÀ» À籸¼ºÇÑ´Ù¸é ¿©·¯ ÇÏÀÌÆÛ¸µÅ©¸¦ ¼öÁ¤Çϴµ¥ ¸¹Àº + ½Ã°£ÀÌ °É¸± °ÍÀÌ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÇØ°áÃ¥Àº ÀÚµ¿À¸·Î ÀûÀýÇÑ CGI¸¦ ½ÇÇàÇÏ´Â »õ·Î¿î + Ưº°ÇÑ URL Çü½ÄÀ» ¸¸µå´Â °ÍÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    ÀÌÁ¦ /u/user/foo/À» °Ë»öÇÏ´Â ¸µÅ©´Â + ´ÙÀ½°ú °°´Ù

    + +
    +HREF="*"
    +/u/user/foo/* (???)
    +
    + +

    ³»ºÎÀûÀ¸·Î ´ÙÀ½°ú °°ÀÌ ÀÚµ¿º¯È¯µÈ´Ù

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    °°Àº ¹æ¹ýÀ¸·Î ¸µÅ© µÚ¿¡ :log¸¦ »ç¿ëÇÏ¿© + Á¢±Ù ·Î±× CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + + + +

    Á¤Àû¿¡¼­ µ¿ÀûÀ¸·Î

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ºê¶ó¿ìÀú¿Í »ç¿ëÀÚ°¡ ¸ð¸£°Ô ÀÚ¿¬½º·´°Ô Á¤Àû + ÆäÀÌÁö foo.htmlÀ» µ¿ÀûÀÎ foo.cgi·Î + º¯°æÇÒ ¼ö ÀÖ³ª.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    URLÀ» CGI ½ºÅ©¸³Æ®·Î ÀçÀÛ¼ºÇÏ°í, MIME-typeÀ» ¼öÁ¤ÇÏ¿© + CGI ½ºÅ©¸³Æ®·Î ½ÇÇàÇÏ°Ô ÇÑ´Ù. ±×·¡¼­ + /~quux/foo.html¸¦ ¿äûÇÏ¸é ³»ºÎÀûÀ¸·Î + /~quux/foo.cgi¸¦ ½ÇÇàÇÏ°Ô µÈ´Ù.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + + + +

    Áï¼® ÄÁÅÙÃ÷ Àç»ý¼º

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÌ ¹æ¹ýÀº ½Ç·Î ºñ±âÀÌ´Ù: µ¿ÀûÀ¸·Î ÆäÀÌÁö¸¦ »ý¼ºÇÏÁö¸¸, + Á¤ÀûÀ¸·Î ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÑ´Ù. Áï, ÆäÀÌÁö´Â ¼ø¼öÇÏ°Ô + (ÆÄÀϽýºÅÛ¿¡¼­ ÀÐÀº ³»¿ëÀ» ±×´ë·Î) Á¤Àû ÆäÀÌÁö·Î + Àü´ÞµÇÁö¸¸, ¾øÀ» °æ¿ì À¥¼­¹ö°¡ µ¿ÀûÀ¸·Î »ý¼ºÇÑ´Ù. + ±×·¯¸é ´©°¡ (ȤÀº cron ÀÛ¾÷ÀÌ) Á¤Àû ÄÁÅÙÃ÷¸¦ Áö¿ìÁö¾Ê´Â + ÇÑ CGI°¡ »ý¼ºÇÑ ÆäÀÌÁö¸¦ Á¤ÀûÀ¸·Î ¼­ºñ½ºÇÑ´Ù. ÄÁÅÙÃ÷¸¦ + Áö¿ì¸é ³»¿ëÀ» °»½ÅÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    + ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÑ´Ù: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    ¿©±â¼­ page.html¸¦ ¿äûÇÒ¶§ + page.htmlÀÌ ¾ø°Å³ª ÆÄÀÏÅ©±â°¡ 0ÀÎ °æ¿ì + ³»ºÎÀûÀ¸·Î page.cgi¸¦ ½ÇÇàÇÑ´Ù. ¿©±â¼­ + ºñ°áÀº page.cgi°¡ ÀϹÝÀûÀÎ CGI ½ºÅ©¸³Æ®¿Í + °°ÀÌ STDOUT¿¡ Ãâ·ÂÇÏ°í, Ãß°¡·Î Ãâ·ÂÀ» + page.html ÆÄÀÏ¿¡ Àû´Â´Ù. Çѹø ½ÇÇàÇÑÈÄ + ¼­¹ö´Â page.htmlÀÇ Á¤º¸¸¦ º¸³½´Ù. À¥°ü¸®ÀÚ°¡ + °­Àç·Î ³»¿ëÀ» °»½ÅÇÏ°í ½Í´Ù¸é, (º¸Åë cron ÀÛ¾÷ÀÌ) + page.htmlÀ» Áö¿ì±â¸¸ ÇÏ¸é µÈ´Ù.

    +
    +
    + + + +

    ÀÚµ¿À¸·Î »õ·Î °íħÇÏ´Â ¹®¼­

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    º¹ÀâÇÑ À¥ÆäÀÌÁö¸¦ ¸¸µé¶§ ÆíÁýÀÚ°¡ ³»¿ëÀ» ¼öÁ¤ÇÒ + ¶§¸¶´Ù ÀÚµ¿À¸·Î ÆäÀÌÁö¸¦ »õ·Î °íħÇÏ´Â À¥ºê¶ó¿ìÀú°¡ + ÀÖÀ¸¸é ¾ó¸¶³ª ÁÁÀ»±î? ºÒ°¡´ÉÇÑ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    °¡´ÉÇÏ´Ù! MIME multipart ±â´É°ú À¥¼­¹ö NPH ±â´É, + mod_rewriteÀÇ URL Á¶ÀÛ ´É·ÂÀ» °áÇÕÇϸé + µÈ´Ù. ¸ÕÀú, »õ·Î¿î URL ±â´ÉÀ» ¸¸µç´Ù: URL¿¡ + :refresh¸¦ Ãß°¡Çϱ⸸ Çϸé ÆÄÀϽýºÅÛ¿¡¼­ + ¼öÁ¤µÉ ¶§¸¶´Ù »õ·Î °íħÇÑ´Ù.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    ÀÌÁ¦ ´ÙÀ½ URL¿¡ Á¢±ÙÇϸé

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    ´ÙÀ½ URLÀ» ³»ºÎÀûÀ¸·Î ºÎ¸¥´Ù

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    ÀÌÁ¦ NPH-CGI ½ºÅ©¸³Æ®¸¸ ³²¾Ò´Ù. º¸Åë "µ¶ÀÚ¿¡°Ô + ¿¬½ÀÀ¸·Î ³²°ÜµÒ"À̶ó°í ¸»ÇÏÁö¸¸ ;-) ³ª´Â À̰͵µ Á¦°øÇÑ´Ù.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + + + +

    ´ë·®ÀÇ °¡»óÈ£½ºÆ®

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡»óÈ£½ºÆ®°¡ ¸î°³¸¸ ÀÖ´Ù¸é ¾ÆÆÄÄ¡ÀÇ <VirtualHost> + ±â´ÉÀÌ Àß µ¿ÀÛÇÑ´Ù. ±×·¯³ª °¡»óÈ£½ºÆ®°¡ ¼ö¹é°³ ÀÖ´Â + ISP¶ó¸é ÀÌ ±â´ÉÀÌ ÃÖ¼±Àº ¾Æ´Ï´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀÌ ±â´ÉÀ» Á¦°øÇÏ·Á¸é Proxy Throughput + ±â´ÉÀ» (Ç÷¡±× [P]) »ç¿ëÇÏ¿© ¿ÜºÎ À¥ÆäÀÌÁö + ȤÀº Àüü ¿ÜºÎ À¥¿µ¿ªÀ» ¿ì¸®ÀÇ À̸§°ø°£¿¡ ´ëÀÀÇÑ´Ù:

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   ¸®´ÙÀÌ·ºÆ®ÇÒ¶§ Á¤±Ô È£½ºÆ®¸íÀ» »ç¿ëÇÑ´Ù.
    +UseCanonicalName on
    +
    +    :
    +#   °¡»óÈ£½ºÆ®¸¦ CLF Çü½Ä ¾Õ¿¡ Ãß°¡ÇÑ´Ù
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   ÁÖ¼­¹ö¿¡¼­ ÀçÀÛ¼º ¿£ÁøÀ» »ç¿ëÇÑ´Ù
    +RewriteEngine on
    +
    +#   µÎ ¸ÊÀ» Á¤ÀÇÇÑ´Ù: Çϳª´Â URLÀ» °íÄ¡°í,
    +#   ´Ù¸¥ Çϳª´Â °¡»óÈ£½ºÆ®º° DocumentRoot¸¦
    +#   Á¤ÀÇÇÑ´Ù.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   ÀÌÁ¦ Å©°í º¹ÀâÇÑ ±ÔÄ¢ ÇÑ°³¸¦ »ç¿ëÇÏ¿©
    +#   °¡»óÈ£½ºÆ®·Î ´ëÀÀÇÑ´Ù.
    +#
    +#   1. °¡»óÈ£½ºÆ®µéÀÌ °°ÀÌ »ç¿ëÇÏ´Â À§Ä¡´Â ´ëÀÀÇÏÁö ¾Ê´Â´Ù
    +RewriteCond   %{REQUEST_URL}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URL}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URL}  !^/commonurlN/.*
    +#
    +#   2. ¿ì¸®°¡ ÇöÀç »ç¿ëÇÏ´Â ¹æ¹ýÀÌ Host Çì´õ¸¦
    +#      °¡»óÈ£½ºÆ®¸¦ Áö¿øÇϹǷÎ
    +#      Host Çì´õ°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. È£½ºÆ®¸íÀ» ¼Ò¹®ÀÚ·Î ¸¸µç´Ù
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. vhost.map¿¡¼­ È£½ºÆ®¸íÀ» ã°í
    +#      °æ·ÎÀ϶§¸¸ ±â¾ïÇÑ´Ù
    +#      (À§¿¡¼­ "NONE"Àº ¾Æ´Ï´Ù)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. ¸¶Áö¸·À¸·Î URLÀ» ¹®¼­ À§Ä¡·Î ´ëÀÀÇÏ°í
    +#      ·Î±×¿¡ ³²±â±âÀ§ÇØ °¡»óÈ£½ºÆ®¸¦ ±â¾ïÇØ µÐ´Ù
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + + + +
    top
    +
    +

    Á¢±Ù Á¦ÇÑ

    + + + +

    ·Îº¿ ¸·±â

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô Çϸé ƯÁ¤ À¥°ø°£ÀÇ ÆäÀÌÁö¸¦ ±Ü¾î¸ðÀ¸´Â ±ÍÂúÀº + ·Îº¿À» ¸·À» ¼ö ÀÖ³ª? "Robot Exclusion Protocol" Ç׸ñÀ» + ÀúÀåÇÑ /robots.txt ÆÄÀÏÀº º¸Åë ÀÌ·± ·Îº¿À» + ¸·´Âµ¥ ÃæºÐÇÏÁö ¾Ê´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    (¾Æ¸¶µµ µð·ºÅ丮°¡ ±í¾î¼­ ·Îº¿ÀÌ µ¹¾Æ´Ù´Ï¸é ¼­¹ö¿¡ + ºÎ´ãÀÌ Å« °æ¿ì) À¥°ø°£ /~quux/foo/arc/¿¡ + ÀÖ´Â URLµéÀ» °ÅºÎÇÏ´Â ±ÔÄ¢À» »ç¿ëÇÑ´Ù. ¿ì¸®´Â ƯÁ¤ + ·Îº¿ÀÇ Á¢±ÙÀ» ¸·¾Æ¾ß ÇÑ´Ù. Áï, ·Îº¿À» ½ÇÇàÇϴ ȣ½ºÆ®¸¦ + ¸·´Â °ÍÀ¸·Î´Â ºÒÃæºÐÇϸç, ±× È£½ºÆ®ÀÇ »ç¿ëÀÚµµ ¸·¾Æ¹ö¸®°Ô + µÈ´Ù. User-Agent HTTP Çì´õ Á¤º¸µµ ºñ±³ÇÑ´Ù.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + + + +

    ±×¸² ÆÛ°¡±â ¹æÁö

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    http://www.quux-corp.de/~quux/¿¡ ÀÖ´Â + ÆäÀÌÁöµéÀÌ GIF ±×¸²À» Æ÷ÇÔÇÑ´Ù°í °¡Á¤ÇÏÀÚ. ÀÌ ±×¸²ÀÌ + ¸ÚÀ־, ´Ù¸¥ »ç¶÷µéÀÌ ÀÚ½ÅÀÇ ÆäÀÌÁö¿¡ Á÷Á¢ ¸µÅ©¸¦ + °Ç´Ù. ¼­¹ö¿¡ ºÒÇÊ¿äÇÑ ºÎ´ãÀÌ µÇ¹Ç·Î ¸·°í ½Í´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ±×¸²À» 100% º¸È£ÇÒ ¼ö´Â ¾øÁö¸¸, ÃÖ¼ÒÇÑ ºê¶ó¿ìÀú°¡ + HTTP Referer Çì´õ¸¦ º¸³»´Â °æ¿ì Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + + + +

    È£½ºÆ® °ÅºÎ

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ¿ÜºÎ¿¡¼­ ¼­¹ö¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Â È£½ºÆ® ¸ñ·ÏÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¾ÆÆÄÄ¡ >= 1.3b6¿¡¼­:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    ¾ÆÆÄÄ¡ <= 1.3b6¿¡¼­:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ÁÖÀÇ! ÀÌ°ÍÀº ¸ñ·Ïó·³ º¸ÀÌÁö¸¸ ¸ñ·ÏÀÌ ¾Æ´Ï¶ó ¸ÊÀÌ´Ù.
    +##        mod_rewrite´Â ÀÌ Á¤º¸¸¦ Å°/°ª ½ÖÀ¸·Î Çؼ®Çϱ⶧¹®¿¡,
    +##        °¢ Ç׸ñÀÇ °ª ÀÚ¸®¿¡ ÃÖ¼ÒÇÑ "-"°¡ ÇÊ¿äÇÏ´Ù.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + + + +

    ÇÁ·Ï½Ã °ÅºÎ

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ƯÁ¤ È£½ºÆ® ȤÀº ƯÁ¤ È£½ºÆ®ÀÇ »ç¿ëÀÚ°¡ + ¾ÆÆÄÄ¡ ÇÁ·Ï½Ã¸¦ »ç¿ëÇÒ ¼ö ¾øµµ·Ï Çϳª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ ±¸¼ºÆÄÀÏ¿¡¼­ + mod_rewrite°¡ mod_proxy + ¾Æ·¡¿¡(!) ÀÖ¾î¾ß ÇÑ´Ù. ±×·¯¸é mod_rewrite´Â + mod_proxy ÀÌÀü¿¡ ºÒ¸°´Ù. + ÀÌÁ¦ ´ÙÀ½°ú °°ÀÌ Æ¯Á¤ È£½ºÆ®¸¦ °ÅºÎÇϵµ·Ï ¼³Á¤ÇÑ´Ù...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...±×¸®°í ´ÙÀ½Àº user@host¿¡ µû¶ó °ÅºÎÇÑ´Ù:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + + + +

    Ưº°ÇÑ ÀÎÁõ ¹æ½Ä

    + + + +
    +
    »óÈ°¼³¸í:
    + +
    +

    °¡²û ¸Å¿ì Ưº°ÇÑ ÀÎÁõÀÌ ÇÊ¿äÇÒ ¶§°¡ ÀÖ´Ù. ¿¹¸¦ + µé¾î, ¹Ì¸® ¼³Á¤ÇصР»ç¿ëÀÚÀÎÁö °Ë»çÇÑ´Ù. À̵鿡°Ô¸¸ + (mod_auth_basicÀÇ Basic Auth¸¦ »ç¿ëÇÑ + °æ¿ì¿Í ´Þ¸®) º°´Ù¸¥ ¹°À½¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    Ä£±¸¸¸ Á¢±ÙÀÌ °¡´ÉÇϵµ·Ï ÀçÀÛ¼º ±ÔÄ¢µéÀ» »ç¿ëÇÑ´Ù:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + + + +

    Referer±â¹Ý º¯È¯±â(deflector)

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    "Referer" HTTP Çì´õ¿¡ µû¶ó ¿øÇϴ´ë·Î ÂüÁ¶ÆäÀÌÁö¸¦ + ¼³Á¤ÇÒ ¼ö ÀÖ´Â À¯¿¬ÇÑ URL º¯È¯±â¸¦ ¸¸µé ¼ö Àִ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ´ÙÀ½°ú °°ÀÌ º¹ÀâÇÑ ±ÔÄ¢À»...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... ÀçÀÛ¼º ¸Ê°ú °°ÀÌ »ç¿ëÇÑ´Ù:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    ±×·¯¸é ¿äûÀ» ÀÚµ¿À¸·Î (¸Ê¿¡¼­ °ªÀ¸·Î "-"¸¦ + »ç¿ëÇÑ °æ¿ì) ÂüÁ¶ÆäÀÌÁö³ª (URLÀÌ ¸Ê¿¡ ÀÖ´Â °æ¿ì µÎ¹ø° + ¾Æ±Ô¸ÕÆ®·Î) ƯÁ¤ URL·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.

    +
    +
    + + + +
    top
    +
    +

    ±âŸ

    + + + +

    ¿ÜºÎ ÀçÀÛ¼º ¿£Áø

    + + + +
    +
    »óȲ¼³¸í:
    + +
    +

    FAQ: ¾î¶»°Ô ÀÌ·±Àú·± Àâ´ÙÇÑ ¹®Á¦¸¦ Ç® ¼ö Àִ°¡? + mod_rewrite·Î´Â ÇØ°áÃ¥ÀÌ ¾Èº¸ÀδÙ...

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿ÜºÎ RewriteMapÀ» »ç¿ëÇ϶ó. + Áï, ÇÁ·Î±×·¥ÀÌ RewriteMap ¿ªÇÒÀ» + ÇÑ´Ù. ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇÒ¶§ ½ÃÀÛÇÏ¿© + STDIN¿¡¼­ ¿äûÇÑ URLÀ» ¹Þ°í, (°°Àº ¼ø¼­·Î!) + °á°ú (º¸Åë ÀçÀÛ¼ºµÈ) URLÀ» STDOUT¿¡ Ãâ·ÂÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   ¾ÆÆÄÄ¡ ¼­¹ö°¡ ¸ØÃßÁö ¾Êµµ·Ï
    +#   ÀÔÃâ·Â ¹öÆÛ¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù
    +$| = 1;
    +
    +#   stdin¿¡¼­ ÇÑÁÙ¾¿ URLÀ» Àаí
    +#   stdout¿¡ º¯È¯ÇÑ URLÀ» Ãâ·ÂÇÑ´Ù
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    ¼³¸íÇϱâÀ§ÇØ ¸ðµç /~quux/foo/... URLÀ» + /~quux/bar/...·Î ÀçÀÛ¼ºÇÏ´Â ½ºÅ©¸³Æ®¸¦ + ¿¹·Î µé¾ú´Ù. ½ÇÁ¦·Î ¸¶À½´ë·Î ÇÁ·Î±×·¡¹ÖÇÒ ¼ö ÀÖ´Ù. + ±×·¯³ª ÀÏ¹Ý »ç¿ëÀÚ°¡ ÀÌ·± ¸ÊÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù°í ÇÏ´õ¶ó°í, ¿ÀÁ÷ ½Ã½ºÅÛ °ü¸®ÀÚ¸¸ÀÌ ¸ÊÀ» + Á¤ÀÇÇØ¾ß ÇÔÀ» ÁÖÀÇÇ϶ó.

    +
    +
    + + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/rewriteguide.xml b/trunk/docs/manual/misc/rewriteguide.xml new file mode 100644 index 0000000000..170311439b --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.xml @@ -0,0 +1,2103 @@ + + + + + + + + + Miscellaneous Documentation + + URL Rewriting Guide + + + +

    Originally written by
    + Ralf S. Engelschall <rse@apache.org>
    + December 1997

    +
    + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonly confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + +
    + +
    + + Introduction to <code>mod_rewrite</code> + +

    The Apache module mod_rewrite is a killer + one, i.e. it is a really sophisticated module which provides + a powerful way to do URL manipulations. With it you can do nearly + all types of URL manipulations you ever dreamed about. + The price you have to pay is to accept complexity, because + mod_rewrite's major drawback is that it is + not easy to understand and use for the beginner. And even + Apache experts sometimes discover new aspects where + mod_rewrite can help.

    + +

    In other words: With mod_rewrite you either + shoot yourself in the foot the first time and never use it again + or love it for the rest of your life because of its power. + This paper tries to give you a few initial success events to + avoid the first case by presenting already invented solutions + to you.

    + +
    + +
    + + Practical Solutions + +

    Here come a lot of practical solutions I've either invented + myself or collected from other people's solutions in the past. + Feel free to learn the black magic of URL rewriting from + these examples.

    + + ATTENTION: Depending on your server-configuration + it can be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. It + avoid problems. + +
    + +
    + + URL Layout + +
    + + Canonical URLs + +
    +
    Description:
    + +
    +

    On some webservers there are more than one URL for a + resource. Usually there are canonical URLs (which should be + actually used and distributed) and those which are just + shortcuts, internal ones, etc. Independent of which URL the + user supplied with the request he should finally see the + canonical one only.

    +
    + +
    Solution:
    + +
    +

    We do an external HTTP redirect for all non-canonical + URLs to fix them in the location view of the Browser and + for all subsequent requests. In the example ruleset below + we replace /~user by the canonical + /u/user and fix a missing trailing slash for + /u/user.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + +
    + +
    + + Canonical Hostnames + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + +
    + +
    + + Moved <code>DocumentRoot</code> + +
    +
    Description:
    + +
    +

    Usually the DocumentRoot + of the webserver directly relates to the URL "/". + But often this data is not really of top-level priority, it is + perhaps just one entity of a lot of data pools. For instance at + our Intranet sites there are /e/www/ + (the homepage for WWW), /e/sww/ (the homepage for + the Intranet) etc. Now because the data of the DocumentRoot stays at /e/www/ we had + to make sure that all inlined images and other stuff inside this + data pool work for subsequent requests.

    +
    + +
    Solution:
    + +
    +

    We redirect the URL / to + /e/www/: +

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /e/www/  [R]
    +
    + +

    Note that this can also be handled using the RedirectMatch directive:

    + + + RedirectMatch ^/$ http://example.com/e/www/ + +
    +
    + +
    + +
    + + Trailing Slash Problem + +
    +
    Description:
    + +
    +

    Every webmaster can sing a song about the problem of + the trailing slash on URLs referencing directories. If they + are missing, the server dumps an error, because if you say + /~quux/foo instead of /~quux/foo/ + then the server searches for a file named + foo. And because this file is a directory it + complains. Actually it tries to fix it itself in most of + the cases, but sometimes this mechanism need to be emulated + by you. For instance after you have done a lot of + complicated URL rewritings to CGI scripts etc.

    +
    + +
    Solution:
    + +
    +

    The solution to this subtle problem is to let the server + add the trailing slash automatically. To do this + correctly we have to use an external redirect, so the + browser correctly requests subsequent images etc. If we + only did a internal rewrite, this would only work for the + directory page, but would go wrong when any images are + included into this page with relative URLs, because the + browser would request an in-lined object. For instance, a + request for image.gif in + /~quux/foo/index.html would become + /~quux/image.gif without the external + redirect!

    + +

    So, to do this trick we write:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    The crazy and lazy can even do the following in the + top-level .htaccess file of their homedir. + But notice that this creates some processing + overhead.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + +
    + +
    + + Webcluster through Homogeneous URL Layout + +
    +
    Description:
    + +
    +

    We want to create a homogeneous and consistent URL + layout over all WWW servers on a Intranet webcluster, i.e. + all URLs (per definition server local and thus server + dependent!) become actually server independent! + What we want is to give the WWW namespace a consistent + server-independent layout: no URL should have to include + any physically correct target server. The cluster itself + should drive us automatically to the physical target + host.

    +
    + +
    Solution:
    + +
    +

    First, the knowledge of the target servers come from + (distributed) external maps which contain information + where our users, groups and entities stay. The have the + form

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    We put them into files map.xxx-to-host. + Second we need to instruct all servers to redirect URLs + of the forms

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    to

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    when the URL is not locally valid to a server. The + following ruleset does this for us by the help of the map + files (assuming that server0 is a default server which + will be used if a user has no entry in the map):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + +
    + +
    + + Move Homedirs to Different Webserver + +
    +
    Description:
    + +
    +

    Many webmasters have asked for a solution to the + following situation: They wanted to redirect just all + homedirs on a webserver to another webserver. They usually + need such things when establishing a newer webserver which + will replace the old one over time.

    +
    + +
    Solution:
    + +
    +

    The solution is trivial with mod_rewrite. + On the old webserver we just redirect all + /~user/anypath URLs to + http://newserver/~user/anypath.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + +
    + +
    + + Structured Homedirs + +
    +
    Description:
    + +
    +

    Some sites with thousands of users usually use a + structured homedir layout, i.e. each homedir is in a + subdirectory which begins for instance with the first + character of the username. So, /~foo/anypath + is /home/f/foo/.www/anypath + while /~bar/anypath is + /home/b/bar/.www/anypath.

    +
    + +
    Solution:
    + +
    +

    We use the following ruleset to expand the tilde URLs + into exactly the above layout.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + +
    + +
    + + Filesystem Reorganization + +
    +
    Description:
    + +
    +

    This really is a hardcore example: a killer application + which heavily uses per-directory + RewriteRules to get a smooth look and feel + on the Web while its data structure is never touched or + adjusted. Background: net.sw is + my archive of freely available Unix software packages, + which I started to collect in 1992. It is both my hobby + and job to to this, because while I'm studying computer + science I have also worked for many years as a system and + network administrator in my spare time. Every week I need + some sort of software so I created a deep hierarchy of + directories where I stored the packages:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    In July 1996 I decided to make this archive public to + the world via a nice Web interface. "Nice" means that I + wanted to offer an interface where you can browse + directly through the archive hierarchy. And "nice" means + that I didn't wanted to change anything inside this + hierarchy - not even by putting some CGI scripts at the + top of it. Why? Because the above structure should be + later accessible via FTP as well, and I didn't want any + Web or CGI stuff to be there.

    +
    + +
    Solution:
    + +
    +

    The solution has two parts: The first is a set of CGI + scripts which create all the pages at all directory + levels on-the-fly. I put them under + /e/netsw/.www/ as follows:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    The DATA/ subdirectory holds the above + directory structure, i.e. the real + net.sw stuff and gets + automatically updated via rdist from time to + time. The second part of the problem remains: how to link + these two structures together into one smooth-looking URL + tree? We want to hide the DATA/ directory + from the user while running the appropriate CGI scripts + for the various URLs. Here is the solution: first I put + the following into the per-directory configuration file + in the DocumentRoot + of the server to rewrite the announced URL + /net.sw/ to the internal path + /e/netsw:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    The first rule is for requests which miss the trailing + slash! The second rule does the real thing. And then + comes the killer configuration which stays in the + per-directory config file + /e/netsw/.www/.wwwacl:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  we are reached via /net.sw/ prefix
    +RewriteBase   /net.sw/
    +
    +#  first we rewrite the root dir to
    +#  the handling cgi script
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  strip out the subdirs when
    +#  the browser requests us from perdir pages
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  and now break the rewriting for local files
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  anything else is a subdir which gets handled
    +#  by another cgi script
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Some hints for interpretation:

    + +
      +
    1. Notice the L (last) flag and no + substitution field ('-') in the forth part
    2. + +
    3. Notice the ! (not) character and + the C (chain) flag at the first rule + in the last part
    4. + +
    5. Notice the catch-all pattern in the last rule
    6. +
    +
    +
    + +
    + +
    + + NCSA imagemap to Apache <code>mod_imagemap</code> + +
    +
    Description:
    + +
    +

    When switching from the NCSA webserver to the more + modern Apache webserver a lot of people want a smooth + transition. So they want pages which use their old NCSA + imagemap program to work under Apache with the + modern mod_imagemap. The problem is that there + are a lot of hyperlinks around which reference the + imagemap program via + /cgi-bin/imagemap/path/to/page.map. Under + Apache this has to read just + /path/to/page.map.

    +
    + +
    Solution:
    + +
    +

    We use a global rule to remove the prefix on-the-fly for + all requests:

    + +
    +RewriteEngine  on
    +RewriteRule    ^/cgi-bin/imagemap(.*)  $1  [PT]
    +
    +
    +
    + +
    + +
    + + Search pages in more than one directory + +
    +
    Description:
    + +
    +

    Sometimes it is necessary to let the webserver search + for pages in more than one directory. Here MultiViews or + other techniques cannot help.

    +
    + +
    Solution:
    + +
    +

    We program a explicit ruleset which searches for the + files in the directories.

    + +
    +RewriteEngine on
    +
    +#   first try to find it in custom/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   second try to find it in pub/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   else go on for other Alias or ScriptAlias directives,
    +#   etc.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + +
    + +
    + + Set Environment Variables According To URL Parts + +
    +
    Description:
    + +
    +

    Perhaps you want to keep status information between + requests and use the URL to encode it. But you don't want + to use a CGI wrapper for all pages just to strip out this + information.

    +
    + +
    Solution:
    + +
    +

    We use a rewrite rule to strip out the status information + and remember it via an environment variable which can be + later dereferenced from within XSSI or CGI. This way a + URL /foo/S=java/bar/ gets translated to + /foo/bar/ and the environment variable named + STATUS is set to the value "java".

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + +
    + +
    + + Virtual User Hosts + +
    +
    Description:
    + +
    +

    Assume that you want to provide + www.username.host.domain.com + for the homepage of username via just DNS A records to the + same machine and without any virtualhosts on this + machine.

    +
    + +
    Solution:
    + +
    +

    For HTTP/1.0 requests there is no solution, but for + HTTP/1.1 requests which contain a Host: HTTP header we + can use the following ruleset to rewrite + http://www.username.host.com/anypath + internally to /home/username/anypath:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + +
    + +
    + + Redirect Homedirs For Foreigners + +
    +
    Description:
    + +
    +

    We want to redirect homedir URLs to another webserver + www.somewhere.com when the requesting user + does not stay in the local domain + ourdomain.com. This is sometimes used in + virtual host contexts.

    +
    + +
    Solution:
    + +
    +

    Just a rewrite condition:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + +
    + +
    + + Redirect Failing URLs To Other Webserver + +
    +
    Description:
    + +
    +

    A typical FAQ about URL rewriting is how to redirect + failing requests on webserver A to webserver B. Usually + this is done via ErrorDocument CGI-scripts in Perl, but + there is also a mod_rewrite solution. + But notice that this performs more poorly than using an + ErrorDocument + CGI-script!

    +
    + +
    Solution:
    + +
    +

    The first solution has the best performance but less + flexibility, and is less error safe:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    The problem here is that this will only work for pages + inside the DocumentRoot. While you can add more + Conditions (for instance to also handle homedirs, etc.) + there is better variant:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    This uses the URL look-ahead feature of mod_rewrite. + The result is that this will work for all types of URLs + and is a safe way. But it does a performance impact on + the webserver, because for every request there is one + more internal subrequest. So, if your webserver runs on a + powerful CPU, use this one. If it is a slow machine, use + the first approach or better a ErrorDocument CGI-script.

    +
    +
    + +
    + +
    + + Extended Redirection + +
    +
    Description:
    + +
    +

    Sometimes we need more control (concerning the + character escaping mechanism) of URLs on redirects. + Usually the Apache kernels URL escape function also + escapes anchors, i.e. URLs like "url#anchor". + You cannot use this directly on redirects with + mod_rewrite because the + uri_escape() function of Apache + would also escape the hash character. + How can we redirect to such a URL?

    +
    + +
    Solution:
    + +
    +

    We have to use a kludge by the use of a NPH-CGI script + which does the redirect itself. Because here no escaping + is done (NPH=non-parseable headers). First we introduce a + new URL scheme xredirect: by the following + per-server config-line (should be one of the last rewrite + rules):

    + +
    +RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
    +            [T=application/x-httpd-cgi,L]
    +
    + +

    This forces all URLs prefixed with + xredirect: to be piped through the + nph-xredirect.cgi program. And this program + just looks like:

    + +
    +#!/path/to/perl
    +##
    +##  nph-xredirect.cgi -- NPH/CGI script for extended redirects
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +
    +$| = 1;
    +$url = $ENV{'PATH_INFO'};
    +
    +print "HTTP/1.0 302 Moved Temporarily\n";
    +print "Server: $ENV{'SERVER_SOFTWARE'}\n";
    +print "Location: $url\n";
    +print "Content-type: text/html\n";
    +print "\n";
    +print "<html>\n";
    +print "<head>\n";
    +print "<title>302 Moved Temporarily (EXTENDED)</title>\n";
    +print "</head>\n";
    +print "<body>\n";
    +print "<h1>Moved Temporarily (EXTENDED)</h1>\n";
    +print "The document has moved <a HREF=\"$url\">here</a>.<p>\n";
    +print "</body>\n";
    +print "</html>\n";
    +
    +##EOF##
    +
    + +

    This provides you with the functionality to do + redirects to all URL schemes, i.e. including the one + which are not directly accepted by mod_rewrite. + For instance you can now also redirect to + news:newsgroup via

    + +
    +RewriteRule ^anyurl  xredirect:news:newsgroup
    +
    + + Notice: You have not to put [R] or + [R,L] to the above rule because the + xredirect: need to be expanded later + by our special "pipe through" rule above. +
    +
    + +
    + +
    + + Archive Access Multiplexer + +
    +
    Description:
    + +
    +

    Do you know the great CPAN (Comprehensive Perl Archive + Network) under http://www.perl.com/CPAN? + This does a redirect to one of several FTP servers around + the world which carry a CPAN mirror and is approximately + near the location of the requesting client. Actually this + can be called an FTP access multiplexing service. While + CPAN runs via CGI scripts, how can a similar approach + implemented via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    First we notice that from version 3.0.0 + mod_rewrite can + also use the "ftp:" scheme on redirects. + And second, the location approximation can be done by a + RewriteMap + over the top-level domain of the client. + With a tricky chained ruleset we can use this top-level + domain as a key to our multiplexing map.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + +
    + +
    + + Time-Dependent Rewriting + +
    +
    Description:
    + +
    +

    When tricks like time-dependent content should happen a + lot of webmasters still use CGI scripts which do for + instance redirects to specialized pages. How can it be done + via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    There are a lot of variables named TIME_xxx + for rewrite conditions. In conjunction with the special + lexicographic comparison patterns <STRING, + >STRING and =STRING we can + do time-dependent redirects:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    This provides the content of foo.day.html + under the URL foo.html from + 07:00-19:00 and at the remaining time the + contents of foo.night.html. Just a nice + feature for a homepage...

    +
    +
    + +
    + +
    + + Backward Compatibility for YYYY to XXXX migration + +
    +
    Description:
    + +
    +

    How can we make URLs backward compatible (still + existing virtually) after migrating document.YYYY + to document.XXXX, e.g. after translating a + bunch of .html files to .phtml?

    +
    + +
    Solution:
    + +
    +

    We just rewrite the name to its basename and test for + existence of the new extension. If it exists, we take + that name, else we rewrite the URL to its original state.

    + + +
    +#   backward compatibility ruleset for
    +#   rewriting document.html to document.phtml
    +#   when and only when document.phtml exists
    +#   but no longer document.html
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   parse out basename, but remember the fact
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   rewrite to document.phtml if exists
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   else reverse the previous basename cutout
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + +
    + +
    + +
    + + Content Handling + +
    + + From Old to New (intern) + +
    +
    Description:
    + +
    +

    Assume we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. Actually + we want that users of the old URL even not recognize that + the pages was renamed.

    +
    + +
    Solution:
    + +
    +

    We rewrite the old URL to the new one internally via the + following rule:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + +
    + +
    + + From Old to New (extern) + +
    +
    Description:
    + +
    +

    Assume again that we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. But this + time we want that the users of the old URL get hinted to + the new one, i.e. their browsers Location field should + change, too.

    +
    + +
    Solution:
    + +
    +

    We force a HTTP redirect to the new URL which leads to a + change of the browsers and thus the users view:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + +
    + +
    + + Browser Dependent Content + +
    +
    Description:
    + +
    +

    At least for important top-level pages it is sometimes + necessary to provide the optimum of browser dependent + content, i.e. one has to provide a maximum version for the + latest Netscape variants, a minimum version for the Lynx + browsers and a average feature version for all others.

    +
    + +
    Solution:
    + +
    +

    We cannot use content negotiation because the browsers do + not provide their type in that form. Instead we have to + act on the HTTP header "User-Agent". The following condig + does the following: If the HTTP header "User-Agent" + begins with "Mozilla/3", the page foo.html + is rewritten to foo.NS.html and and the + rewriting stops. If the browser is "Lynx" or "Mozilla" of + version 1 or 2 the URL becomes foo.20.html. + All other browsers receive page foo.32.html. + This is done by the following ruleset:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + +
    + +
    + + Dynamic Mirror + +
    +
    Description:
    + +
    +

    Assume there are nice webpages on remote hosts we want + to bring into our namespace. For FTP servers we would use + the mirror program which actually maintains an + explicit up-to-date copy of the remote data on the local + machine. For a webserver we could use the program + webcopy which acts similar via HTTP. But both + techniques have one major drawback: The local copy is + always just as up-to-date as often we run the program. It + would be much better if the mirror is not a static one we + have to establish explicitly. Instead we want a dynamic + mirror with data which gets updated automatically when + there is need (updated data on the remote host).

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature + (flag [P]):

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + +
    + +
    + + Reverse Dynamic Mirror + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + +
    + +
    + + Retrieve Missing Data from Intranet + +
    +
    Description:
    + +
    +

    This is a tricky way of virtually running a corporate + (external) Internet webserver + (www.quux-corp.dom), while actually keeping + and maintaining its data on a (internal) Intranet webserver + (www2.quux-corp.dom) which is protected by a + firewall. The trick is that on the external webserver we + retrieve the requested data on-the-fly from the internal + one.

    +
    + +
    Solution:
    + +
    +

    First, we have to make sure that our firewall still + protects the internal webserver and that only the + external webserver is allowed to retrieve data from it. + For a packet-filtering firewall we could for instance + configure a firewall ruleset like the following:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    Just adjust it to your actual configuration syntax. + Now we can establish the mod_rewrite + rules which request the missing data in the background + through the proxy throughput feature:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + +
    + +
    + + Load Balancing + +
    +
    Description:
    + +
    +

    Suppose we want to load balance the traffic to + www.foo.com over www[0-5].foo.com + (a total of 6 servers). How can this be done?

    +
    + +
    Solution:
    + +
    +

    There are a lot of possible solutions for this problem. + We will discuss first a commonly known DNS-based variant + and then the special one with mod_rewrite:

    + +
      +
    1. + DNS Round-Robin + +

      The simplest method for load-balancing is to use + the DNS round-robin feature of BIND. + Here you just configure www[0-9].foo.com + as usual in your DNS with A(address) records, e.g.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      Then you additionally add the following entry:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      Notice that this seems wrong, but is actually an + intended feature of BIND and can be used + in this way. However, now when www.foo.com gets + resolved, BIND gives out www0-www6 + - but in a slightly permutated/rotated order every time. + This way the clients are spread over the various + servers. But notice that this not a perfect load + balancing scheme, because DNS resolve information + gets cached by the other nameservers on the net, so + once a client has resolved www.foo.com + to a particular wwwN.foo.com, all + subsequent requests also go to this particular name + wwwN.foo.com. But the final result is + ok, because the total sum of the requests are really + spread over the various webservers.

      +
    2. + +
    3. + DNS Load-Balancing + +

      A sophisticated DNS-based method for + load-balancing is to use the program + lbnamed which can be found at + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + It is a Perl 5 program in conjunction with auxilliary + tools which provides a real load-balancing for + DNS.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      In this variant we use mod_rewrite + and its proxy throughput feature. First we dedicate + www0.foo.com to be actually + www.foo.com by using a single

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      entry in the DNS. Then we convert + www0.foo.com to a proxy-only server, + i.e. we configure this machine so all arriving URLs + are just pushed through the internal proxy to one of + the 5 other servers (www1-www5). To + accomplish this we first establish a ruleset which + contacts a load balancing script lb.pl + for all URLs.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      Then we write lb.pl:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- load balancing script
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # the hostname base
      +$first  = 1;         # the first server (not 0 here, because 0 is myself)
      +$last   = 5;         # the last server in the round-robin
      +$domain = "foo.dom"; # the domainname
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + + A last notice: Why is this useful? Seems like + www0.foo.com still is overloaded? The + answer is yes, it is overloaded, but with plain proxy + throughput requests, only! All SSI, CGI, ePerl, etc. + processing is completely done on the other machines. + This is the essential point. +
    6. + +
    7. + Hardware/TCP Round-Robin + +

      There is a hardware solution available, too. Cisco + has a beast called LocalDirector which does a load + balancing at the TCP/IP level. Actually this is some + sort of a circuit level gateway in front of a + webcluster. If you have enough money and really need + a solution with high performance, use this one.

      +
    8. +
    +
    +
    + +
    + +
    + + New MIME-type, New Service + +
    +
    Description:
    + +
    +

    On the net there are a lot of nifty CGI programs. But + their usage is usually boring, so a lot of webmaster + don't use them. Even Apache's Action handler feature for + MIME-types is only appropriate when the CGI programs + don't need special URLs (actually PATH_INFO + and QUERY_STRINGS) as their input. First, + let us configure a new file type with extension + .scgi (for secure CGI) which will be processed + by the popular cgiwrap program. The problem + here is that for instance we use a Homogeneous URL Layout + (see above) a file inside the user homedirs has the URL + /u/user/foo/bar.scgi. But + cgiwrap needs the URL in the form + /~user/foo/bar.scgi/. The following rule + solves the problem:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    Or assume we have some more nifty programs: + wwwlog (which displays the + access.log for a URL subtree and + wwwidx (which runs Glimpse on a URL + subtree). We have to provide the URL area to these + programs so they know on which area they have to act on. + But usually this ugly, because they are all the times + still requested from that areas, i.e. typically we would + run the swwidx program from within + /u/user/foo/ via hyperlink to

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    which is ugly. Because we have to hard-code + both the location of the area + and the location of the CGI inside the + hyperlink. When we have to reorganize the area, we spend a + lot of time changing the various hyperlinks.

    +
    + +
    Solution:
    + +
    +

    The solution here is to provide a special new URL format + which automatically leads to the proper CGI invocation. + We configure the following:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    Now the hyperlink to search at + /u/user/foo/ reads only

    + +
    +HREF="*"
    +
    + +

    which internally gets automatically transformed to

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    The same approach leads to an invocation for the + access log CGI program when the hyperlink + :log gets used.

    +
    +
    + +
    + +
    + + From Static to Dynamic + +
    +
    Description:
    + +
    +

    How can we transform a static page + foo.html into a dynamic variant + foo.cgi in a seamless way, i.e. without notice + by the browser/user.

    +
    + +
    Solution:
    + +
    +

    We just rewrite the URL to the CGI-script and force the + correct MIME-type so it gets really run as a CGI-script. + This way a request to /~quux/foo.html + internally leads to the invocation of + /~quux/foo.cgi.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + +
    + +
    + + On-the-fly Content-Regeneration + +
    +
    Description:
    + +
    +

    Here comes a really esoteric feature: Dynamically + generated but statically served pages, i.e. pages should be + delivered as pure static pages (read from the filesystem + and just passed through), but they have to be generated + dynamically by the webserver if missing. This way you can + have CGI-generated pages which are statically served unless + one (or a cronjob) removes the static contents. Then the + contents gets refreshed.

    +
    + +
    Solution:
    + +
    + This is done via the following ruleset: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    Here a request to page.html leads to a + internal run of a corresponding page.cgi if + page.html is still missing or has filesize + null. The trick here is that page.cgi is a + usual CGI script which (additionally to its STDOUT) + writes its output to the file page.html. + Once it was run, the server sends out the data of + page.html. When the webmaster wants to force + a refresh the contents, he just removes + page.html (usually done by a cronjob).

    +
    +
    + +
    + +
    + + Document With Autorefresh + +
    +
    Description:
    + +
    +

    Wouldn't it be nice while creating a complex webpage if + the webbrowser would automatically refresh the page every + time we write a new version from within our editor? + Impossible?

    +
    + +
    Solution:
    + +
    +

    No! We just combine the MIME multipart feature, the + webserver NPH feature and the URL manipulation power of + mod_rewrite. First, we establish a new + URL feature: Adding just :refresh to any + URL causes this to be refreshed every time it gets + updated on the filesystem.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    Now when we reference the URL

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    this leads to the internal invocation of the URL

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    The only missing part is the NPH-CGI script. Although + one would usually say "left as an exercise to the reader" + ;-) I will provide this, too.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + +
    + +
    + + Mass Virtual Hosting + +
    +
    Description:
    + +
    +

    The VirtualHost feature of Apache is nice + and works great when you just have a few dozens + virtual hosts. But when you are an ISP and have hundreds of + virtual hosts to provide this feature is not the best + choice.

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature (flag [P]):

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   use the canonical hostname on redirects, etc.
    +UseCanonicalName on
    +
    +    :
    +#   add the virtual host in front of the CLF-format
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   enable the rewriting engine in the main server
    +RewriteEngine on
    +
    +#   define two maps: one for fixing the URL and one which defines
    +#   the available virtual hosts with their corresponding
    +#   DocumentRoot.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   Now do the actual virtual host mapping
    +#   via a huge and complicated single rule:
    +#
    +#   1. make sure we don't map for common locations
    +RewriteCond   %{REQUEST_URL}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URL}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URL}  !^/commonurlN/.*
    +#
    +#   2. make sure we have a Host header, because
    +#      currently our approach only supports
    +#      virtual hosting through this header
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. lowercase the hostname
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. lookup this hostname in vhost.map and
    +#      remember it only when it is a path
    +#      (and not "NONE" from above)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. finally we can map the URL to its docroot location
    +#      and remember the virtual host for logging puposes
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + +
    + +
    + +
    + + Access Restriction + +
    + + Blocking of Robots + +
    +
    Description:
    + +
    +

    How can we block a really annoying robot from + retrieving pages of a specific webarea? A + /robots.txt file containing entries of the + "Robot Exclusion Protocol" is typically not enough to get + rid of such a robot.

    +
    + +
    Solution:
    + +
    +

    We use a ruleset which forbids the URLs of the webarea + /~quux/foo/arc/ (perhaps a very deep + directory indexed area where the robot traversal would + create big server load). We have to make sure that we + forbid access only to the particular robot, i.e. just + forbidding the host where the robot runs is not enough. + This would block users from this host, too. We accomplish + this by also matching the User-Agent HTTP header + information.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + +
    + +
    + + Blocked Inline-Images + +
    +
    Description:
    + +
    +

    Assume we have under http://www.quux-corp.de/~quux/ + some pages with inlined GIF graphics. These graphics are + nice, so others directly incorporate them via hyperlinks to + their pages. We don't like this practice because it adds + useless traffic to our server.

    +
    + +
    Solution:
    + +
    +

    While we cannot 100% protect the images from inclusion, + we can at least restrict the cases where the browser + sends a HTTP Referer header.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + +
    + +
    + + Host Deny + +
    +
    Description:
    + +
    +

    How can we forbid a list of externally configured hosts + from using our server?

    +
    + +
    Solution:
    + +
    +

    For Apache >= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    For Apache <= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ATTENTION! This is a map, not a list, even when we treat it as such.
    +##             mod_rewrite parses it for key/value pairs, so at least a
    +##             dummy value "-" must be present for each entry.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + +
    + +
    + + Proxy Deny + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + +
    + +
    + + Special Authentication Variant + +
    +
    Description:
    + +
    +

    Sometimes a very special authentication is needed, for + instance a authentication which checks for a set of + explicitly configured users. Only these should receive + access and without explicit prompting (which would occur + when using the Basic Auth via mod_auth_basic).

    +
    + +
    Solution:
    + +
    +

    We use a list of rewrite conditions to exclude all except + our friends:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + +
    + +
    + + Referer-based Deflector + +
    +
    Description:
    + +
    +

    How can we program a flexible URL Deflector which acts + on the "Referer" HTTP header and can be configured with as + many referring pages as we like?

    +
    + +
    Solution:
    + +
    +

    Use the following really tricky ruleset...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... in conjunction with a corresponding rewrite + map:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    This automatically redirects the request back to the + referring page (when "-" is used as the value + in the map) or to a specific URL (when an URL is specified + in the map as the second argument).

    +
    +
    + +
    + +
    + +
    + + Other + +
    + + External Rewriting Engine + +
    +
    Description:
    + +
    +

    A FAQ: How can we solve the FOO/BAR/QUUX/etc. + problem? There seems no solution by the use of + mod_rewrite...

    +
    + +
    Solution:
    + +
    +

    Use an external RewriteMap, i.e. a program which acts + like a RewriteMap. It is run once on startup of Apache + receives the requested URLs on STDIN and has + to put the resulting (usually rewritten) URL on + STDOUT (same order!).

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   disable buffered I/O which would lead
    +#   to deadloops for the Apache server
    +$| = 1;
    +
    +#   read URLs one per line from stdin and
    +#   generate substitution URL on stdout
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    This is a demonstration-only example and just rewrites + all URLs /~quux/foo/... to + /~quux/bar/.... Actually you can program + whatever you like. But notice that while such maps can be + used also by an average user, only the + system administrator can define it.

    +
    +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/misc/rewriteguide.xml.ko b/trunk/docs/manual/misc/rewriteguide.xml.ko new file mode 100644 index 0000000000..bdb73e5587 --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.xml.ko @@ -0,0 +1,2006 @@ + + + + + + + + + Miscellaneous Documentation + + URL ÀçÀÛ¼º Áöħ¼­ + + + +

    ¿øÀúÀÚ
    + Ralf S. Engelschall <rse@apache.org>
    + 1997³â 12¿ù

    +
    + +

    ÀÌ ¹®¼­´Â mod_rewrite ÂüÁ¶ ¹®¼­¸¦ º¸ÃæÇÑ´Ù. + ÀÌ ¹®¼­´Â À¥°ü¸®ÀÚ°¡ ½ÇÁ¦ ÀÛ¾÷¿¡¼­ ºÎµúÄ¡°ÔµÇ´Â ÀüÇüÀûÀÎ + URL°ü·Ã ¹®Á¦¸¦ ÇØ°áÇϱâÀ§Çؼ­ ¾î¶»°Ô ¾ÆÆÄÄ¡ + mod_rewrite¸¦ »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù. URL + ÀçÀÛ¼º ±ÔÄ¢À» ¼³Á¤ÇÏ¿© ¹®Á¦¸¦ ÇØ°áÇÏ´Â ¹æ¹ýÀ» ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù.

    + +
    + +
    + + <code>mod_rewrite</code> ¼Ò°³ + +

    ¾ÆÆÄÄ¡ mod_rewrite ¸ðµâÀº ±²ÀåÇÏ´Ù. + Áï, URLÀ» Á¶ÀÛÇÒ ¼ö ÀÖ´Â °­·ÂÇÏ°í ½Ç·Î Á¤±³ÇÑ ¸ðµâÀÌ´Ù. + »ó»óÇØ¿Ô´ø °ÅÀÇ ¸ðµç Á¾·ùÀÇ URL Á¶ÀÛÀÌ °¡´ÉÇÏ´Ù. ±×·¯³ª + ±× ´ë°¡·Î »ç¿ëÇϱ⠺¹ÀâÇÏ´Ù. mod_rewriteÀÇ + ÃÖ´ë ´ÜÁ¡Àº Ãʺ¸ÀÚ°¡ ÀÌÇØÇÏ°í »ç¿ëÇϱ⠽±Áö ¾Ê´Ù´Â Á¡ÀÌ´Ù. + ½ÉÁö¾î ¾ÆÆÄÄ¡ Àü¹®°¡µµ Á¾Á¾ mod_rewriteÀÇ + »õ·Î¿î ¿ëµµ¸¦ ¹ß°ßÇÑ´Ù.

    + +

    ´Ù¸¥ ¸»·Î: mod_rewrite¿¡ ´ëÇØ ´ç½ÅÀº + óÀ½¿¡ °ÌÀ» ¸Ô°í Àý´ë·Î ´Ù½Ã »ç¿ëÇÏÁö ¾Ê°Å³ª, °­·ÂÇÔ¿¡ ¸Å·áµÇ¾î + ¾ÕÀ¸·Î »î µ¿¾È »ç¶û¿¡ ºüÁú °ÍÀÌ´Ù. ÀÌ ±ÛÀº ù¹ø° °æ¿ì¸¦ + ¸·±âÀ§ÇØ ÀÌ¹Ì ¾Ë·ÁÁø ¸î°¡Áö ¼º°ø»ç·Ê¸¦ ¼Ò°³ÇÏ·Á°í ÇÑ´Ù.

    + +
    + +
    + + ½Ç¿ëÀûÀÎ ÇØ°áÃ¥ + +

    ÀÌÁ¦ ³»°¡ Á÷Á¢ ¸¸µé¾ú°Å³ª ´Ù¸¥ »ç¶÷µéÀÌ ¸¸µç ¸¹Àº ½Ç¿ëÀûÀÎ + ÇØ°áÃ¥ÀÌ ³ª¿Â´Ù. ¿¹Á¦¿¡¼­ URL ÀçÀÛ¼ºÀÇ È渶¼úÀ» ¸¶À½²¯ ¹è¿ì±æ + ¹Ù¶õ´Ù.

    + + ÁÖÀÇ: ¼­¹ö ¼³Á¤¿¡ µû¶ó »óȲ¿¡ ¸Â°Ô + ¿¹Á¦¸¦ Á¶±Ý ¼öÁ¤ÇØ¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î, Ãß°¡·Î + mod_alias, mod_userdir + µîÀ» »ç¿ëÇÑ´Ù¸é [PT] Ç÷¡±×¸¦ Ãß°¡ÇÑ´Ù. ȤÀº + ÁÖ¼­¹ö¼³Á¤/°¡»óÈ£½ºÆ® »ç¿ëÀå¼Ò°¡ ¾Æ´Ñ .htaccess + »ç¿ëÀå¼Ò¿¡ ¾Ë¸Â°Ô ±ÔÄ¢À» ¼öÁ¤ÇÒ ¼öµµ ÀÖ´Ù. »ç¿ëÇϱâ Àü¿¡ + Ç×»ó ±ÔÄ¢ÀÌ ¾î¶² ±â´ÉÀ» ÇÏ´ÂÁö ÀÌÇØÇϵµ·Ï Çضó. ±×·¯¸é ¹®Á¦¸¦ + ÇÇÇÒ ¼ö ÀÖ´Ù. + +
    + +
    + + URL ±¸Á¶ + +
    + + ±âÁØÀÌ µÇ´Â URL + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÇÑ ¸®¼Ò½º¿¡ ´ëÇØ ¿©·¯ URLÀ» °¡Áö´Â À¥¼­¹ö°¡ ÀÖ´Ù. + º¸Åë (½ÇÁ¦ »ç¿ëÇÏ°í ¾Ë·ÁÁ®¾ß ÇÒ) ±âÁØÀÌ µÇ´Â URL°ú, + ´ÜÃà ȤÀº ³»ºÎ ¿ëµµÀÇ URLÀÌ ÀÖ´Ù. »ç¿ëÀÚ°¡ ¿äû¿¡ + ¾î¶² URLÀ» »ç¿ëÇÏ´øÁö ±âÁØÀÌ µÇ´Â URL¸¸À» º¸¿©Áà¾ß + ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ±âÁØÀÌ µÇÁö¾Ê´Â ¸ðµç URLÀ» ºê¶ó¿ìÀú°¡ ¾Ëµµ·Ï °íÄ¡±âÀ§ÇØ + ¿ÜºÎ HTTP ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. ¿¹¸¦ µé¾î ¾Æ·¡ ±ÔÄ¢Àº + /~user¸¦ ±âÁØÀÌ µÇ´Â /u/user·Î + ´ëüÇÏ°í, /u/user ¸¶Áö¸·¿¡ ½½·¡½¬°¡ ¾ø´Ù¸é + Ãß°¡ÇÑ´Ù.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + +
    + +
    + + ±âÁØÀÌ µÇ´Â È£½ºÆ®¸í + +
    +
    »óȲ¼³¸í:
    + +
    ...
    + +
    ÇØ°áÃ¥:
    + +
    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + +
    + +
    + + <code>DocumentRoot</code>¸¦ ¿Å±ä °æ¿ì + +
    +
    »óȲ¼³¸í:
    + +
    +

    À¥¼­¹öÀÇ DocumentRoot´Â º¸Åë URL + "/"°ú Á÷Á¢ °ü·ÃÀÖ´Ù. ±×·¯³ª ÀÌ°÷¿¡ ¸ðµç + ÀÚ·á°¡ ÀÖÁö ¾Ê°í, ÀÚ·á°¡ ´Ù¸¥ ¿©·¯ °÷¿¡ Èð¾îÁ®ÀÖ´Â + °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î ÀÎÆ®¶ó³Ý »çÀÌÆ®¿¡ (¿ÜºÎ¸¦ À§ÇÑ + ȨÆäÀÌÁö) /e/www/¿Í (ÀÎÆ®¶ó³ÝÀ» À§ÇÑ + ȨÆäÀÌÁö) /e/sww/°¡ ÀÖ´Ù°í ÇÏÀÚ. ÀÌÁ¦ + DocumentRoot°¡ + /e/www/À̱⶧¹®¿¡, ¿äû¿¡¼­ ÆäÀÌÁö¿¡ + Æ÷ÇÔµÈ ±×¸² µîÀ» ÀÌ°÷¿¡¼­ °¡Á®¿Í¾ß ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿ì¸®´Â URL /¸¦ /e/www/·Î + ¸®´ÙÀÌ·º¼Ç¸¸ ÇÏ¸é µÈ´Ù. »ç¼ÒÇØ º¸ÀÌÁö¸¸ ½ÇÁ¦·Î + mod_rewrite¸¦ »ç¿ëÇؼ­¸¸ °¡´ÉÇÏ´Ù. + (mod_alias µîÀÌ Á¦°øÇÏ´Â) URL + Alias °°Àº ÀüÇüÀûÀÎ ¹æ¹ýÀº ¾ÕºÎºÐ¸¸ + ã´Â´Ù. DocumentRoot°¡ + ¸ðµç URLÀÇ ¾ÕºÎºÐÀ̱⶧¹®¿¡ ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ¿© ¸®´ÙÀÌ·º¼ÇÀ» + ÇÒ ¼ö ¾ø´Ù. mod_rewrite¸¦ »ç¿ëÇϸé + ÁøÂ¥ °£´ÜÇÏ´Ù:

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /e/www/  [R]
    +
    +
    +
    + +
    + +
    + + ¸¶Áö¸· ½½·¡½¬ ¹®Á¦ + +
    +
    »óȲ¼³¸í:
    + +
    +

    µð·ºÅ丮¸¦ ÁöĪÇÏ´Â URLÀÇ ¸¶Áö¸· ½½·¡½¬ ¹®Á¦°¡ + ¾ø´Ù¸é ¸ðµç À¥°ü¸®Àڴ ȯȣÇÒ °ÍÀÌ´Ù. ½½·¡½¬°¡ ¾ø´Ù¸é, + Áï /~quux/foo/ ´ë½Å /~quux/foo¸¦ + »ç¿ëÇÏ¸é ¼­¹ö°¡ foo¶ó´Â ÆÄÀÏÀ» + ã±â¶§¹®¿¡ ¿À·ù°¡ ¹ß»ýÇÑ´Ù. ÆÄÀÏÀÌ µð·ºÅ丮À̱⶧¹®¿¡ + ¹Þ¾ÆµéÀÌÁö ¾Ê´Â´Ù. ´ëºÎºÐÀÇ °æ¿ì º¸Åë ¼­¹ö°¡ ÀÚµ¿À¸·Î + URLÀ» °íÄ¡Áö¸¸, °¡²û Á÷Á¢ ÇØÁà¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ + µé¾î, CGI ½ºÅ©¸³Æ® µîÀ¸·Î º¹ÀâÇÑ URL ÀçÀÛ¼ºÀ» ÇÑ ÈÄ¿¡ + ±×·¯ÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀÌ ¹Ì¹¦ÇÑ ¹®Á¦ÀÇ ÇØ°á¹æ¹ýÀº ¼­¹ö°¡ ÀÚµ¿À¸·Î ¸¶Áö¸· + ½½·¡½¬¸¦ Ãß°¡ÇÏ´Â °ÍÀÌ´Ù. ºê¶ó¿ìÀú°¡ ³ª¸ÓÁö ±×¸² µîÀ» + ¿Ã¹Ù·Î ¿äûÇÒ ¼ö ÀÖµµ·Ï, ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» ÇØ¾ß ÇÑ´Ù. + ³»ºÎ ¸®´ÙÀÌ·º¼ÇÀ» ÇÑ´Ù¸é µð·ºÅ丮 ÆäÀÌÁö¿¡¸¸ µ¿ÀÛÇÏ¿© + ÀÌ ÆäÀÌÁö°¡ »ó´ë URL·Î Æ÷ÇÔÇÏ´Â ±×¸²À» ºê¶ó¿ìÀú°¡ + ¿äûÇÒ¶§ ãÀ» ¼ö ¾ø´Ù. ¿¹¸¦ µé¾î, ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» + »ç¿ëÇÏÁö ¾ÊÀ»¶§ /~quux/foo/index.html¿¡¼­ + image.gif¸¦ ¿äûÇϸé + /~quux/image.gif¸¦ ¿äûÇÏ°Ô µÈ´Ù!

    + +

    ±×·¡¼­ À̸¦ ÇØ°áÇϱâÀ§ÇØ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    Ȩµð·ºÅ丮ÀÇ ÃÖ»óÀ§ .htaccess ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù. ±×·¯³ª ó¸®Çϴµ¥ ºÎ´ãÀÌ + µÈ´Ù.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + +
    + +
    + + ÀÏ°üµÈ URL ±¸Á¶·Î ¸¸µç À¥Å¬·¯½ºÅÍ + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÎÆ®¶ó³Ý À¥¼­¹ö±ºÀÇ ¸ðµç À¥¼­¹ö¿¡ µ¿ÀÏÇÏ°í ÀÏ°üµÈ + URL ±¸Á¶¸¦ ¸¸µé°í ½Í´Ù. Áï, ¸ðµç (Á¤ÀÇ»ó ¼­¹ö¿¡ ¼ÓÇÏ¿© + ¼­¹ö¿¡ ÀÇÁ¸ÀûÀÎ!) URLÀ» ¼­¹ö µ¶¸³ÀûÀ¸·Î ¸¸µç´Ù! + À¥ À̸§°ø°£¿¡ ¼­¹öµ¶¸³ÀûÀÎ µ¿ÀÏÇÑ ±¸Á¶¸¦ ºÎ¿©ÇØ¾ß ÇÑ´Ù: + URLÀº ½ÇÁ¦ ¼­¹ö¸¦ ÁöĪÇÏ¸é ¾ÈµÈ´Ù. ¼­¹ö±ºÀÌ ÀÚµ¿À¸·Î + ½ÇÁ¦ ¼­¹ö·Î À¯µµÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú »ç¿ëÀÚ, ±×·ì, µ¶¸³Ã¼ÀÇ À§Ä¡ Á¤º¸¸¦ ÀúÀåÇÑ + (ºÐ»êµÈ) ¿ÜºÎ¸Ê¿¡ ½ÇÁ¦ ¼­¹ö Á¤º¸¸¦ ¾ò¾î¿Â´Ù. ¿ÜºÎ¸ÊÀº + ´ÙÀ½°ú °°Àº Çü½ÄÀÌ´Ù

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    ¿ì¸®´Â ÀÌ Á¤º¸¸¦ °¢°¢ map.xxx-to-host + ÆÄÀÏ¿¡ ÀúÀåÇß´Ù. ´ÙÀ½À¸·Î ¸ðµç ¼­¹ö¿¡¼­ URLÀÌ ¼­¹ö¿¡ + ¾ø´Ù¸é ´ÙÀ½°ú °°Àº URLÀ»,

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    ´ÙÀ½°ú °°ÀÌ ¸®´ÙÀÌ·º¼ÇÇÑ´Ù

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    ¾Æ·¡ ±ÔÄ¢Àº ¸ÊÆÄÀÏÀ» »ç¿ëÇÏ¿© ÀÌ ÀÛ¾÷À» ÇÑ´Ù (server0Àº + ¸Ê¿¡ Ç׸ñÀÌ ¾ø´Â °æ¿ì »ç¿ëÇÒ ±âº»¼­¹ö¶ó°í °¡Á¤ÇÑ´Ù):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + +
    + +
    + + Ȩµð·ºÅ丮¸¦ ´Ù¸¥ À¥¼­¹ö·Î ÀÌÀü + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¸¹Àº À¥°ü¸®ÀÚ´Â À¥¼­¹öÀÇ ¸ðµç Ȩµð·ºÅ丮¸¦ ´Ù¸¥ + À¥¼­¹ö·Î ÀÌÀüÇÑ °æ¿ì ÇØ°áÃ¥À» ¹°¾îº»´Ù. ÀÌ ¹æ¹ýÀº + ÀÌÀü ¼­¹ö¸¦ ´ëüÇÒ »õ·Î¿î ¼­¹ö¸¦ ±¸¼ºÇϴµ¥ ½Ã°£ÀÌ + °É¸®´Â °æ¿ì¿¡ ÇÊ¿äÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    mod_rewrite¸¦ »ç¿ëÇÏ¸é °£´ÜÇÏ´Ù. + ÀÌÀü À¥¼­¹ö´Â ¸ðµç /~user/anypath URLÀ» + http://newserver/~user/anypath·Î + ¸®´ÙÀÌ·º¼ÇÇÏ¸é µÈ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + +
    + +
    + + Ȩµð·ºÅ丮 ±¸Á¶ ¸¸µé±â + +
    +
    »óȲ¼³¸í:
    + +
    +

    »ç¿ëÀÚ°¡ ¼öõ¸íÀÎ »çÀÌÆ®´Â º¸Åë Ȩµð·ºÅ丮 ±¸Á¶¸¦ + ¸¸µç´Ù. Áï, ¿¹¸¦ µé¾î À̸§ÀÌ »ç¿ëÀÚ¸íÀÇ Ã¹¹ø° ¹®ÀÚÀÎ + ÇÏÀ§µð·ºÅ丮¿¡ Ȩµð·ºÅ丮¸¦ µÐ´Ù. ±×·¡¼­, + /~foo/anypath´Â + /home/f/foo/.www/anypathÀÌ°í, + /~bar/anypath´Â + /home/b/bar/.www/anypathÀÌ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¹°°áÇ¥½Ã°¡ ÀÖ´Â URLÀ» À§¿Í °°Àº ±¸Á¶·Î º¯È¯ÇϱâÀ§ÇØ + ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + +
    + +
    + + ÆÄÀϽýºÅÛ À籸¼º + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÌ ¿¹´Â ½Ç·Î ÇϵåÄÚ¾îÀûÀÌ´Ù: µð·ºÅ丮º° + RewriteRules¸¦ ¸Å¿ì ¸¹ÀÌ »ç¿ëÇÏ¿© ÀÚ·á + ÀÚü´Â ±×´ë·Î µÐü·Î À¥¿¡ ÀڷḦ ÀÚ¿¬½º·´°Ô ºê¶ó¿ì¡Çϵµ·Ï + ÇÑ´Ù. ¹è°æ: ³ª´Â 1992³â ºÎÅÍ ÀÚÀ¯·Ó°Ô »ç¿ëÇÒ ¼ö ÀÖ´Â + À¯´Ð½º ¼ÒÇÁÆ®¿þ¾îµéÀ» net.sw¿¡ + ¸ð¾ÆµÎ°í ÀÖ¾ú´Ù. ÀÌ´Â ³»°¡ ÄÄÇ»ÅÍ°úÇÐÀ» °øºÎÇϸ鼭 + ¿©·¯Çص¿¾È ¿©°¡½Ã°£¿¡ ½Ã½ºÅÛ °ü¸®ÀÚ¿Í ³×Æ®¿÷ °ü¸®ÀÚ¸¦ + ÇؿԱ⶧¹®¿¡ ³» Ãë¹ÌÀÌÀÚ ÀÏÀÌ´Ù. ¸ÅÁÖ¸¶´Ù »õ·Î ¼ÒÇÁÆ®¿þ¾î°¡ + Ãß°¡µÉ ¶§¸¶´Ù µð·ºÅ丮¸¦ ±í°Ô ¸¸µé¾î¿Ô´Ù:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    1996³â 7¿ù ÀÌ ÀúÀå¼Ò¸¦ ¸ÚÀÖ´Â À¥ ÀÎÅÍÆäÀ̽º¸¦ ÅëÇØ + ¼¼»ó¿¡ °ø°³Çϱâ·Î °áÁ¤ÇÞ´Ù. "¸ÚÀÖ´Ù"´Â ¸»Àº, ÃÖ»óÀ§ + µð·ºÅ丮¿¡ CGI ½ºÅ©¸³Æ®¸¦ µÎÁö ¾Ê°íµµ, ÀúÀå¼Ò °èÃþ±¸Á¶¸¦ + Á÷Á¢ ºê¶ó¿ìÁúÇÏ±æ ¹Ù¶õ´Ù´Â ¶æÀÌ´Ù. ¿Ö? ÀúÀå¼Ò¸¦ ³ªÁß¿¡ + FTP·Îµµ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ¸¸µé ¿¹Á¤ÀÌ¿´±â¶§¹®¿¡ À¥À̳ª + CGI¿Í °ü·ÃµÈ ³»¿ëÀ» °°ÀÌ µÎ±â ½È¾ú´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÇØ°áÃ¥Àº µÎ ºÎºÐÀ¸·Î ³ª´¶´Ù: ¸ÕÀú µð·ºÅ丮 ¼öÁØ¿¡¼­ + ÇÊ¿äÇÑ ¸ðµç ÆäÀÌÁö¸¦ µ¿ÀûÀ¸·Î ¸¸µå´Â CGI ½ºÅ©¸³Æ®°¡ + ÇÊ¿äÇÏ´Ù. ³ª´Â ÀÌ ½ºÅ©¸³Æ®µéÀ» ´ÙÀ½°ú °°ÀÌ + /e/netsw/.www/¿¡ µÎ¾ú´Ù:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    DATA/ ÇÏÀ§µð·ºÅ丮¿¡ À§¿¡¼­ ¸»ÇÑ ÀúÀå¼Ò°¡ + ÀÖ´Ù. ½ÇÁ¦ net.swÀÇ ³»¿ëÀº º¸Åë + rdist¸¦ »ç¿ëÇÏ¿© ÀÚµ¿À¸·Î °¡Á®¿Â´Ù. µÎ¹ø° + ºÎºÐÀÌ ³²¾Ò´Ù: ¾î¶»°Ô ÀÌ µÎ ±¸Á¶¸¦ ÇϳªÀÇ ÀÚ¿¬½º·¯¿î + URL ±¸Á¶·Î ¿¬°áÇϴ°¡? »ç¿ëÀÚ¿¡°Ô DATA/ + µð·ºÅ丮¸¦ °¨Ãß°í, URL¸¶´Ù ÀûÀýÇÑ CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ°í + ½Í´Ù. ÇØ°áÃ¥Àº ´ÙÀ½°ú °°´Ù: ¸ÕÀú ¼­¹öÀÇ DocumentRoot¿¡¼­ °ø°³µÈ + URL /net.sw/¸¦ ³»ºÎ °æ·Î /e/netsw·Î + ÀçÀÛ¼ºÇϱâÀ§ÇØ µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    ù¹ø° ±ÔÄ¢Àº ¸¶Áö¸·¿¡ ½½·¡½¬°¡ ¾ø´Â ¿äûÀ» À§Çؼ­ + »ç¿ëÇß´Ù! µÎ¹ø° ±ÔÄ¢ÀÌ ½ÇÁ¦ ÀÛ¾÷À» ÇÑ´Ù. ±×¸®°í µð·ºÅ丮º° + ¼³Á¤ÆÄÀÏ /e/netsw/.www/.wwwacl¿¡ °áÁ¤ÀûÀÎ + ¼³Á¤ÀÌ ³ª¿Â´Ù:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  ¾Õ ºÎºÐÀÌ /net.sw/ ·Î Á¢±ÙÇÑ´Ù
    +RewriteBase   /net.sw/
    +
    +#  ¸ÕÀú ÃÖ»óÀ§ µð·ºÅ丮¸¦
    +#  cgi ½ºÅ©¸³Æ®·Î ÀçÀÛ¼ºÇÑ´Ù
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  ºê¶ó¿ìÀú°¡ µð·ºÅ丮º° ÆäÀÌÁö¸¦ ¿äûÇÑ °æ¿ì
    +#  ÇÏÀ§µð·ºÅ丮¸¦ ÃßÃâÇÑ´Ù
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  ÀÌÁ¦ ÀçÀÛ¼ºÀ» ¸¶Ä£´Ù
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  ´Ù¸¥ cgi ½ºÅ©¸³Æ®°¡ ó¸®ÇÒ
    +#  ÇÏÀ§µð·ºÅ丮°¡ ³²¾Ò´Ù
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Çؼ®À» À§ÇÑ ÈùÆ®:

    + +
      +
    1. ³×¹ø° ºÎºÐ¿¡¼­ ´ëü Çʵå('-')°¡ + ¾ø°í L (last) Ç÷¡±×°¡ ÀÖÀ½À» ÁÖ¸ñÇ϶ó
    2. + +
    3. ¸¶Áö¸· ºÎºÐ¿¡¼­ ù¹ø° ±ÔÄ¢¿¡ ! + (not) ¹®ÀÚ¿Í C (chain) Ç÷¡±×¸¦ ÁÖ¸ñÇ϶ó
    4. + +
    5. ¸¶Áö¸· ±ÔÄ¢¿¡¼­ ±âŸ ÇØ´çÇÏÁö ¾Ê´Â ¸ðµç °æ¿ì¸¦ + Àâ¾Æ³»´Â ÆÐÅÏÀ» ÁÖ¸ñÇ϶ó
    6. +
    +
    +
    + +
    + +
    + + NCSA imagemapÀ» ¾ÆÆÄÄ¡ <code>mod_imap</code>À¸·Î + +
    +
    »óȲ¼³¸í:
    + +
    +

    »ç¶÷µéÀº NCSA À¥¼­¹ö¿¡¼­ Çö´ëÀûÀÎ ¾ÆÆÄÄ¡ À¥¼­¹ö·Î + ÀÚ¿¬½º·´°Ô ¿Å°Ü°¡±æ ¹Ù¶õ´Ù. ±×·¡¼­ ¿À·¡µÈ NCSA + imagemap ÇÁ·Î±×·¥À» »ç¿ëÇÑ ÆäÀÌÁö¸¦ Çö´ëÀûÀÎ + ¾ÆÆÄÄ¡ mod_imap·Î ó¸®ÇÏ±æ ¹Ù¶õ´Ù. + ¹®Á¦´Â imagemap ÇÁ·Î±×·¥À» + /cgi-bin/imagemap/path/to/page.map°ú + °°ÀÌ ÂüÁ¶ÇÏ´Â ÇÏÀÌÆÛ¸µÅ©°¡ ¸¹´Ù´Â °ÍÀÌ´Ù. ¾ÆÆÄÄ¡´Â + /path/to/page.map°ú °°Àº ¿äûÀ» ¹Þ¾Æ¾ß + ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ðµç ¿äû¿¡¼­ ¾ÕºÎºÐÀ» µ¿ÀûÀ¸·Î Á¦°ÅÇÏ´Â Àü¿ª ±ÔÄ¢À» + »ç¿ëÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteRule    ^/cgi-bin/imagemap(.*)  $1  [PT]
    +
    +
    +
    + +
    + +
    + + ¿©·¯ µð·ºÅ丮¿¡¼­ ÆäÀÌÁö °Ë»ö + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡²û À¥¼­¹ö°¡ ¿©·¯ µð·ºÅ丮¿¡¼­ ÆÄÀÏÀ» ã¾Æ¾ß ÇÒ + ¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì MultiViews³ª ´Ù¸¥ ¹æ¹ýÀº µµ¿òÀÌ + ¾ÈµÈ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿©·¯ µð·ºÅ丮¿¡¼­ ÆÄÀÏÀ» ã´Â ±ÔÄ¢À» Á÷Á¢ ÇÁ·Î±×·¥ÇÑ´Ù.

    + +
    +RewriteEngine on
    +
    +#   ¸ÕÀú custom/¿¡¼­ ã±æ ½ÃµµÇÏ°í...
    +#   ...ãÀ¸¸é ³¡!
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   µÎ¹ø°·Î pub/¿¡¼­ ã±æ ½ÃµµÇÑ´Ù...
    +#   ...ãÀ¸¸é ³¡!
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   ¸øãÀ¸¸é ´Ù¸¥ Alias³ª ScriptAlias Áö½Ã¾î µîÀ¸·Î ÁøÇàÇÑ´Ù.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + +
    + +
    + + URL¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿äûµé°£¿¡ »óÅÂÁ¤º¸¸¦ À¯ÁöÇϱâÀ§ÇØ URL¿¡ Á¤º¸¸¦ + ÀÎÄÚµùÇÏ´Â ¹æ¹ýµµ ÀÖ´Ù. ±×·¯³ª ´ÜÁö ÀÌ Á¤º¸¸¦ Á¦°ÅÇϱâÀ§ÇØ + ¸ðµç ÆäÀÌÁö¿¡ CGI wrapper¸¦ »ç¿ëÇÏ°í ½ÍÁö ¾Ê´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º ±ÔÄ¢À» »ç¿ëÇÏ¿© »óÅÂÁ¤º¸¸¦ ÃßÃâÇÏ°í, ÃßÃâÇÑ + Á¤º¸¸¦ ³ªÁß¿¡ XSSI³ª CGI¿¡¼­ »ç¿ëÇϱâÀ§ÇØ È¯°æº¯¼ö¿¡ + ÀúÀåÇÑ´Ù. ±×·¡¼­ URL /foo/S=java/bar/´Â + /foo/bar/·Î º¯È¯µÇ°í STATUS¶ó´Â + ȯ°æº¯¼ö °ªÀ» "java"·Î ¼³Á¤ÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + +
    + +
    + + °¡»ó »ç¿ëÀÚ È£½ºÆ® + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏÁö ¾Ê°í °°Àº ÄÄÇ»ÅÍ·Î DNS A + ·¹Äڵ带 ¼³Á¤ÇÏ¿© + www.username.host.domain.comÀ» + »ç¿ëÀÚÀÇ È¨ÆäÀÌÁö·Î Á¦°øÇÏ°í ½Í´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    HTTP/1.0 ¿äûÀÇ °æ¿ì ¹æ¹ýÀÌ ¾øÁö¸¸, Host: HTTP + Çì´õ¸¦ Æ÷ÇÔÇÑ HTTP/1.1 ¿äûÀº ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÏ¿© + ³»ºÎÀûÀ¸·Î http://www.username.host.com/anypath¸¦ + /home/username/anypath·Î ÀçÀÛ¼ºÇÒ ¼ö + ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + +
    + +
    + + Ȩµð·ºÅ丮¸¦ ¿ÜºÎ ¼­¹ö·Î ¸®´ÙÀÌ·º¼Ç + +
    +
    »óȲ¼³¸í:
    + +
    +

    Áö¿ª µµ¸ÞÀÎ ourdomain.com ¹Û¿¡¼­ ¿äûÀÌ + µé¾î¿À¸é Ȩµð·ºÅ丮 URLÀ» ´Ù¸¥ À¥¼­¹ö + www.somewhere.comÀ¸·Î ¸®´Ù¸®·º¼ÇÇϱæ + ¹Ù¶õ´Ù. Á¾Á¾ °¡»óÈ£½ºÆ® »ç¿ëÀå¼Ò¿¡¼­ »ç¿ëÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º Á¶°ÇÀ» »ç¿ëÇÏ¸é µÈ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + +
    + +
    + + ½ÇÆÐÇÑ URLÀ» ´Ù¸¥ À¥¼­¹ö·Î ¸®´ÙÀÌ·º¼Ç + +
    +
    »óȲ¼³¸í:
    + +
    +

    URL ÀçÀÛ¼º¿¡ ´ëÇؼ­ À¥¼­¹ö A¿¡ ÇØ´ç ÆÄÀÏÀÌ ¾ø´Â + °æ¿ì À¥¼­¹ö B·Î ¿äûÀ» ¸®´ÙÀÌ·º¼ÇÇÏ´Â ¹æ¹ýÀ» ÀÚÁÖ + ¹°¾îº»´Ù. º¸Åë Perl·Î ÀÛ¼ºÇÑ ErrorDocument CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏÁö¸¸, mod_rewrite¸¦ »ç¿ëÇÏ´Â + ¹æ¹ýµµ ÀÖ´Ù. ±×·¯³ª ¼º´ÉÀº ErrorDocument CGI ½ºÅ©¸³Æ®º¸´Ù + ¶³¾îÁüÀ» ¸í½ÉÇ϶ó!

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ù¹ø° ¹æ¹ýÀº ºü¸£Áö¸¸ À¯¿¬¼ºÀÌ ¶³¾îÁö°í ¿ÏÀüÇÏÁö + ¾Ê´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    ÀÌ ¹æ¹ýÀÇ ´ÜÁ¡Àº DocumentRoot ¾È¿¡ ÀÖ´Â ÆäÀÌÁö¸¸ + °¡´ÉÇÏ´Ù´Â Á¡ÀÌ´Ù. (¿¹¸¦ µé¾î Ȩµð·ºÅ丮 µîÀ» À§ÇØ) + Á¶°ÇÀ» Ãß°¡ÇÒ ¼ö ÀÖÁö¸¸, ´õ ÁÁÀº ¹æ¹ýÀÌ ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    mod_rewriteÀÇ URL Àü¹æÂüÁ¶(look-ahead)¸¦ + »ç¿ëÇÑ´Ù. ±×·¡¼­ ¸ðµç URL¿¡ µ¿ÀÛÇÏ°í ¾ÈÀüÇÏ´Ù. ±×·¯³ª + ¸ðµç ¿äû¸¶´Ù ³»ºÎ ÇÏÀ§¿äûÀ» Çѹø ´õ Çϱ⶧¹®¿¡ À¥¼­¹ö + ¼º´É¿¡ ¾Ç¿µÇâÀ» ÁØ´Ù. ±×·¡¼­ °­·ÂÇÑ CPU¿¡¼­ À¥¼­¹ö¸¦ + ½ÇÇàÇÑ´Ù¸é »ç¿ëÇ϶ó. ÄÄÇ»ÅÍ°¡ ´À¸®´Ù¸é ù¹ø° ¹æ¹ýÀ̳ª + ´õ ³ªÀº ErrorDocument + CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇ϶ó.

    +
    +
    + +
    + +
    + + È®Àå ¸®´ÙÀÌ·º¼Ç + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡²û ¸®´ÙÀÌ·º¼ÇÇÏ´Â URLÀ» ´õ Á¶ÀýÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. + ¾ÆÆÄÄ¡ ³»ºÎ URL escape ÇÔ¼ö´Â "url#anchor" + °°Àº URLÀÇ anchorµµ escapeÇÑ´Ù. ¾ÆÆÄÄ¡ÀÇ + uri_escape() ÇÔ¼ö´Â ¿ì¹°Á¤ÀÚ(#)µµ °°ÀÌ + escapeÇϹǷΠ»ç¿ëÇÒ ¼ö ¾ø´Ù. ±×·¯¸é ¾î¶»°Ô ÀÌ·± URL·Î + ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    Á÷Á¢ ¸®´ÙÀÌ·º¼ÇÇÏ´Â NPH-CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ ÇØ°áÃ¥ÀÌ + ÇÊ¿äÇÏ´Ù. escape¸¦ ÇÏÁö ¾Ê±â¶§¹®ÀÌ´Ù (NPH=non-parseable + headers). ¸ÕÀú ´ÙÀ½ ¼­¹ö¼³Á¤À» ÇÏ¿© (ÀçÀÛ¼º ±ÔÄ¢ÀÇ + ³¡ºÎºÐ¿¡ »ç¿ëÇØ¾ß ÇÑ´Ù) »õ·Î¿î URL scheme + xredirect:¸¦ µµÀÔÇÑ´Ù:

    + +
    +RewriteRule ^xredirect:(.+) /path/to/nph-xredirect.cgi/$1 \
    +            [T=application/x-httpd-cgi,L]
    +
    + +

    ±×·¯¸é xredirect:·Î ½ÃÀÛÇÏ´Â ¸ðµç URLÀº + nph-xredirect.cgi ÇÁ·Î±×·¥À» ÅëÇÏ°Ô µÈ´Ù. + ÇÁ·Î±×·¥Àº ´ÙÀ½°ú °°´Ù:

    + +
    +#!/path/to/perl
    +##
    +##  nph-xredirect.cgi -- NPH/CGI script for extended redirects
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +
    +$| = 1;
    +$url = $ENV{'PATH_INFO'};
    +
    +print "HTTP/1.0 302 Moved Temporarily\n";
    +print "Server: $ENV{'SERVER_SOFTWARE'}\n";
    +print "Location: $url\n";
    +print "Content-type: text/html\n";
    +print "\n";
    +print "<html>\n";
    +print "<head>\n";
    +print "<title>302 Moved Temporarily (EXTENDED)</title>\n";
    +print "</head>\n";
    +print "<body>\n";
    +print "<h1>Moved Temporarily (EXTENDED)</h1>\n";
    +print "The document has moved <a HREF=\"$url\">here</a>.<p>\n";
    +print "</body>\n";
    +print "</html>\n";
    +
    +##EOF##
    +
    + +

    ±×·¯¸é mod_rewrite°¡ Á÷Á¢ ¹ÞÁö¸øÇÏ´Â + ¸ðµç URL schemeÀ¸·Î ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + ´ÙÀ½°ú °°ÀÌ news:newsgroupÀ¸·Î ¸®´ÙÀÌ·º¼ÇÇÒ + ¼ö ÀÖ´Ù

    + +
    +RewriteRule ^anyurl  xredirect:news:newsgroup
    +
    + + ÁÖÀÇ: À§ÀÇ Æ¯º°ÇÑ "Åë°ú" ±ÔÄ¢À» »ç¿ëÇÏ¿© + xredirect:¸¦ ¸¶Áö¸·¿¡ È®ÀåÇØ¾ß Çϱ⶧¹®¿¡ + ±ÔÄ¢¿¡ [R]À̳ª [R,L]À» »ç¿ëÇϸé + ¾ÈµÈ´Ù. +
    +
    + +
    + +
    + + ÀúÀå¼Ò Á¢±Ù Áß°è(multiplexer) + +
    +
    »óȲ¼³¸í:
    + +
    +

    http://www.perl.com/CPAN¿¡ + ÀÖ´Â ´ë´ÜÇÑ CPAN (Comprehensive Perl Archive Network)À» + ¾Æ´Â°¡? ÀÌ ÁÖ¼Ò´Â ¼¼°è¿¡ Èð¾îÁø ¿©·¯ CPAN ¹Ì·¯ FTP + ¼­¹öÁß Å¬¶óÀ̾ðÆ®¿¡ °¡±îÀÌ ÀÖ´Â ¼­¹ö·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. + À̸¦ FTP Á¢±Ù Áß°è ¼­ºñ½º¶ó°í ÇÑ´Ù. CPANÀº CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏÁö¸¸, mod_rewrite¸¦ »ç¿ëÇÏ¿© + ºñ½ÁÇÏ°Ô ¸¸µé ¼ö ÀÖÀ»±î?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú mod_rewrite 3.0.0 ¹öÀüºÎÅÍ + ¸®´ÙÀÌ·º¼Ç¿¡ "ftp:" schemeÀ» »ç¿ëÇÒ ¼ö + ÀÖ´Ù. ´ÙÀ½À¸·Î Ŭ¶óÀ̾ðÆ®ÀÇ ÃÖ»óÀ§ µµ¸ÞÀÎÀ» RewriteMap°ú °°ÀÌ + »ç¿ëÇÏ¿© À§Ä¡¸¦ ÃßÁ¤ÇÒ ¼ö ÀÖ´Ù. º¹ÀâÈ÷ ¿«ÀÎ ±ÔÄ¢¿¡¼­ + ÃÖ»óÀ§ µµ¸ÞÀÎÀ» Áß°è¸ÊÀÇ Å°·Î »ç¿ëÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + +
    + +
    + + ½Ã°£¿¡ µû¸¥ ÀçÀÛ¼º + +
    +
    »óȲ¼³¸í:
    + +
    +

    ½Ã°£¿¡ µû¶ó ´Ù¸¥ ³»¿ëÀ» ¼­ºñ½ºÇÏ´Â °æ¿ì ¸¹Àº À¥°ü¸®ÀÚ´Â + Àá½Ã Ưº°ÇÑ ÆäÀÌÁö·Î ¸®´ÙÀÌ·º¼ÇÇϱâÀ§ÇØ CGI ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÑ´Ù. mod_rewrite·Î´Â ¾î¶»°Ô + ÇÒ ¼ö Àִ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀçÀÛ¼º Á¶°Ç¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ¿©·¯ TIME_xxx + º¯¼ö°¡ ÀÖ´Ù. º¯¼ö¿Í Ưº°ÇÑ »çÀü¼ø¼­ ºñ±³ + <STRING, >STRING, + =STRINGÀ» »ç¿ëÇÏ¿© ½Ã°£¿¡ µû¶ó ¸®´ÙÀÌ·º¼ÇÇÒ + ¼ö ÀÖ´Ù:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    URL foo.htmlÀ» ¿äûÇϸé + 07:00-19:00 µ¿¾È foo.day.html + ³»¿ëÀ» ¼­ºñ½ºÇÏ°í, ³ª¸ÓÁö ½Ã°£ µ¿¾È + foo.night.html ³»¿ëÀ» ¼­ºñ½ºÇÑ´Ù. ȨÆäÀÌÁö¿¡¼­ + »ç¿ëÇϱâ ÁÁÀº ±â´ÉÀÌ´Ù...

    +
    +
    + +
    + +
    + + YYYY¸¦ XXXX·Î ÀÌÀüÇÑ °æ¿ì ¿ªÈ£È¯ + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿©·¯ .html ÆÄÀÏÀ» .phtml·Î + º¯È¯ÇÏ´Â µî document.YYYY¸¦ + document.XXXX·Î ÀÌÀüÇÑÈÄ ¿ªÈ£È¯(backward + compatibility) URLÀ» (°¡»óÀûÀ¸·Î Á¸ÀçÇÏ°Ô) ¸¸µé ¼ö + ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    À̸§À» ±âº»À̸§À¸·Î ÀçÀÛ¼ºÇÑÈÄ »õ·Î¿î È®ÀåÀÚ¸¦ + °¡Áø ÆÄÀÏÀÌ ÀÖ´ÂÁö °Ë»çÇÑ´Ù. ÀÖ´Ù¸é ±× ÆÄÀϸíÀ» »ç¿ëÇÏ°í, + ¾øÀ¸¸é URLÀ» ¿ø·¡ »óÅ·ΠÀçÀÛ¼ºÇÑ´Ù.

    + + +
    +#   ¹®¼­.html ÀÌ ¾ø°í
    +#   ¹®¼­.phtml ¸¸ ÀÖ´Â °æ¿ì
    +#   ¹®¼­.html À» ¹®¼­.phtml ·Î
    +#   ÀçÀÛ¼ºÇÏ´Â ¿ªÈ£È¯ ±ÔÄ¢
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   ±âº»À̸§À» ã°í, ã¾Ò´Ù´Â »ç½ÇÀ» ±â¾ïÇÑ´Ù
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   ÆÄÀÏÀÌ ÀÖ´Ù¸é ¹®¼­.phtml ·Î ÀçÀÛ¼ºÇÑ´Ù
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   ¾Æ´Ï¸é ¾Õ¿¡¼­ ãÀº ±âº»À̸§À» µÇµ¹¸°´Ù
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + +
    + +
    + +
    + + ÄÁÅÙÃ÷ ´Ù·ç±â + +
    + + »õ·Î ÀÌÀü (°¨Ãß±â) + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÃÖ±Ù foo.htmlÀ» bar.html·Î + º¯°æÇÏ°í ¿ªÈ£È¯¼ºÀ» À§ÇØ ÀÌÀü URLÀ» °è¼Ó Á¦°øÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. »ç¿ëÀÚ´Â ÀÌÀü URLÀÌ º¯°æµÇ¾ú´Ù´Â + »ç½ÇÀ» ´«Ä¡Ã¤Áö ¸øÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ´ÙÀ½ ±ÔÄ¢À¸·Î ÀÌÀü URLÀ» ³»ºÎÀûÀ¸·Î »õ·Î¿î URL·Î + ÀçÀÛ¼ºÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + +
    + +
    + + »õ·Î ÀÌÀü (¾Ë¸®±â) + +
    +
    »óȲ¼³¸í:
    + +
    +

    ´Ù½Ã foo.htmlÀ» bar.html·Î + º¯°æÇÏ°í ¿ªÈ£È¯¼ºÀ» À§ÇØ ÀÌÀü URLÀ» °è¼Ó Á¦°øÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. ±×·¯³ª ÀÌÁ¦´Â ÀÌÀü URLÀ» »ç¿ëÇϸé + »ç¿ëÀÚ¿¡°Ô »õ·Î¿î URLÀ» ÈùÆ®·Î ¾Ë·ÁÁØ´Ù. Áï, ºê¶ó¿ìÀú + ÁÖ¼ÒâÀÌ º¯ÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    »õ·Î¿î URL·Î HTTP ¸®´ÙÀÌ·º¼ÇÇÏ´Ù. ±×·¯¸é ºê¶ó¿ìÀú°¡ + »õ·Î¿î URL¸¦ º¸ÀÌ°í º¯°æ»ç½ÇÀ» »ç¿ëÀÚ°¡ ¾Ë°ÔµÈ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + +
    + +
    + + ºê¶ó¿ìÀú¿¡ µû¸¥ ³»¿ë + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÃÖ¼ÒÇÑ Áß¿äÇÑ ÃÖ»óÀ§ ÆäÀÌÁö´Â ºê¶ó¿ìÀú¿¡ ÃÖÀûÈ­µÈ + ³»¿ëÀ¸·Î ¼­ºñ½ºÇؾßÇÒ °æ¿ì°¡ ÀÖ´Ù. Áï, ÃֽŠNetscape + ºê¶ó¿ìÀú¿¡°Ô´Â ÃÖ»óÀÇ ¹öÀüÀ», Lynx ºê¶ó¿ìÀú¿¡°Ô´Â + ÃÖÀú ¹öÀüÀ», ³ª¸ÓÁö ºê¶ó¿ìÀú¿¡´Â Æò±ÕÀûÀÎ ¹öÀüÀ» + Á¦°øÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ºê¶ó¿ìÀú°¡ ³»¿ëÇù»óÀ» À§ÇØ ÀÚ½ÅÀÇ Á¾·ù¿¡ ´ëÇÑ Á¤º¸¸¦ + Á¦°øÇÏÁö ¾Ê±â¶§¹®¿¡ ³»¿ëÇù»óÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ´ë½Å + HTTP "User-Agent" Çì´õ¸¦ »ç¿ëÇÑ´Ù. ´ÙÀ½ ±ÔÄ¢Àº HTTP + "User-Agent" Çì´õ°¡ "Mozilla/3"À¸·Î ½ÃÀÛÇϸé + foo.html ÆäÀÌÁö¸¦ foo.NS.html·Î + ÀçÀÛ¼ºÇÏ°í ÀçÀÛ¼ºÀ» Áß´ÜÇÑ´Ù. ºê¶ó¿ìÀú°¡ "Lynx"³ª + "Mozilla" ¹öÀü 1 ȤÀº 2¶ó¸é URLÀº + foo.20.htmlÀÌ µÈ´Ù. ³ª¸ÓÁö ºê¶ó¿ìÀú´Â + foo.32.html ÆäÀÌÁö¸¦ ¹Þ´Â´Ù. ¾Æ·¡ ±ÔÄ¢ÀÌ + ÀÌ ÀÛ¾÷À» ÇÑ´Ù:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + +
    + +
    + + µ¿Àû ¹Ì·¯ + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¿ÜºÎ È£½ºÆ®¿¡ ¿ì¸® »çÀÌÆ®·Î °¡Á®¿À°í ½ÍÀº ÁÁÀº + À¥ÆäÀÌÁö°¡ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. FTP ¼­¹öÀÇ °æ¿ì Á÷Á¢ ¿ÜºÎ + ÀÚ·áÀÇ Ãֽź¹»çº»À» À¯ÁöÇÏ´Â mirror ÇÁ·Î±×·¥À» + »ç¿ëÇÒ ¼ö ÀÖ°í, À¥¼­¹ö¶ó¸é HTTP·Î ºñ½ÁÇÑ ÀÛ¾÷À» ÇÏ´Â + webcopy ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª + µÎ ¹æ¹ý ¸ðµÎ ´ÜÁ¡ÀÌ ÀÖ´Ù: º¹»çº»Àº °¡²û¾¿ ÇÁ·Î±×·¥À» + ½ÇÇàÇØÁÙ ¶§¸¸ ÃÖ½ÅÆÇÀ¸·Î À¯ÁöµÈ´Ù. Á÷Á¢ ±¸¼ºÇؾßÇÏ´Â + Á¤ÀûÀÎ ¹Ì·¯°¡ ¾Æ´Ï¶ó¸é ÁÁ°Ú´Ù. ´ë½Å (¿ÜºÎ È£½ºÆ®¿¡¼­ + ÀÚ·á°¡ °»½ÅµÇ¸é) ÇÊ¿äÇÒ¶§ ÀÚµ¿À¸·Î ÀڷḦ °»½ÅÇÏ´Â + µ¿Àû ¹Ì·¯°¡ ÇÊ¿äÇÏ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    À̸¦ À§ÇØ Proxy Throughput ±â´ÉÀ» (Ç÷¡±× + [P]) »ç¿ëÇÏ¿© ¿ÜºÎ À¥ÆäÀÌÁö ȤÀº ¿ÜºÎ + À¥°ø°£ Àüü¸¦ ¿ì¸® À̸§°ø°£À¸·Î ´ëÀÀÇÑ´Ù:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + +
    + +
    + + µ¿Àû ¿ª¹Ì·¯ + +
    +
    »óȲ¼³¸í:
    + +
    ...
    + +
    ÇØ°áÃ¥:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + +
    + +
    + + ¾ø´Â ÀڷḦ ÀÎÆ®¶ó³Ý¿¡¼­ °¡Á®¿À±â + +
    +
    »óȲ¼³¸í:
    + +
    +

    ½ÇÁ¦ ÀڷḦ ¹æÈ­º®ÀÌ º¸È£ÇÏ´Â (³»ºÎ) ÀÎÆ®¶ó³Ý À¥¼­¹ö¿¡ + (www2.quux-corp.dom) ÀúÀåÇϸ鼭, ±â¾÷ÀÇ + (¿ÜºÎ) ÀÎÅÍ³Ý À¥¼­¹ö¸¦ (www.quux-corp.dom) + ½ÇÇàÇÏ´Â °Íó·³ º¸ÀÌ°Ô ÇÑ´Ù. ¿ÜºÎ À¥¼­¹ö´Â ¿äûÇÑ + ÀڷḦ ³»ºÎ À¥¼­¹ö¿¡¼­ °¡Á®¿Â´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú ¹æÈ­º®ÀÌ ³»ºÎ À¥¼­¹ö¸¦ º¸È£ÇÏ°í ¿ÜºÎ À¥¼­¹ö¸¸ÀÌ + ³»ºÎ À¥¼­¹ö¿¡¼­ ÀڷḦ ¾òÀ» ¼ö ÀÖ°Ô ÇÑ´Ù. ´ÙÀ½°ú °°ÀÌ + ÆÐŶÇÊÅ͸µ ¹æÈ­º®À» ¼³Á¤ÇÑ´Ù:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    ½ÇÁ¦ ¼³Á¤¹®¹ý¿¡ ¾Ë¸Â°Ô °íÃĶó. ¾ø´Â ÀڷḦ ³»ºÎÀûÀ¸·Î + proxy throughput ±â´ÉÀ» ÅëÇØ ¿äûÇÏ´Â + mod_rewrite ±ÔÄ¢À» ÀÛ¼ºÇÑ´Ù:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + +
    + +
    + + ·Îµå¹ë·±½Ì (ºÎÇÏ ºÐ»êÇϱâ) + +
    +
    »óȲ¼³¸í:
    + +
    +

    www.foo.comÀÇ Åë½Å·®À» + www[0-5].foo.com (ÃÑ ¼­¹ö 6´ë)À¸·Î ºÐ»êÇÏ°í + ½Í´Ù. ¾î¶»°Ô Çϴ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸Å¿ì ´Ù¾çÇÑ ¹æ¹ýÀ¸·Î ÀÌ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Ù. + ¸ÕÀú DNS¸¦ »ç¿ëÇÑ Àß ¾Ë·ÁÁø ¹æ¹ýÀ» ¼³¸íÇÏ°í, + mod_rewrite¸¦ »ç¿ëÇÏ´Â °æ¿ì¸¦ »ìÆ캸ÀÚ:

    + +
      +
    1. + DNS Round-Robin + +

      °¡Àå °£´ÜÇÑ ·Îµå¹ë·±½Ì ¹æ¹ýÀº BINDÀÇ + DNS round-robin ¹æ½ÄÀ» »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ´ÙÀ½°ú + °°ÀÌ DNS A(address) ·¹Äڵ忡 + www[0-9].foo.comÀ» ¼³Á¤ÇÑ´Ù.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      ±×¸®°í ´ÙÀ½ Ç׸ñÀ» Ãß°¡ÇÑ´Ù:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      À߸øµÈ °Íó·³ º¸ÀÌÁö¸¸, ½ÇÁ¦·Î BINDÀÇ + ÀǵµµÈ ±â´ÉÀÌ´Ù. ÀÌÁ¦ www.foo.comÀ» + ãÀ¸¸é, BIND´Â ¸Å¹ø ¼ø¼­¸¦ Á¶±Ý¾¿ + ¹Ù²ã°¡¸ç www0-www6À» ¹ÝȯÇÑ´Ù. ±×·¡¼­ + Ŭ¶óÀ̾ðÆ®µéÀ» ¿©·¯ ¼­¹ö·Î ºÐ»êÇÑ´Ù. ±×·¯³ª DNS + °Ë»ö °á°ú°¡ ³×Æ®¿÷ÀÇ ´Ù¸¥ ³×ÀÓ¼­¹ö¿¡ ij½¬µÇ¿© + www.foo.comÀ» ãÀº °á°ú°¡ ƯÁ¤ + wwwN.foo.comÀ̸é Ŭ¶óÀ̾ðÆ®ÀÇ ´ÙÀ½ + ¿äûµéµµ °°Àº wwwN.foo.comÀ¸·Î + º¸³»Áö±â¶§¹®¿¡ ¿Ïº®ÇÑ ·Îµå¹ë·±½Ì ±â¹ýÀÌ ¾Æ´ÔÀ» + ÁÖÀÇÇ϶ó. ±×·¯³ª Å©°Ô º¸¸é ¿äûÀÌ ¿©·¯ À¥¼­¹ö¿¡ + ºÐ»êµÇ¹Ç·Î È¿°ú°¡ ÁÁ´Ù.

      +
    2. + +
    3. + DNS ·Îµå¹ë·±½Ì + +

      http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html¿¡ + ÀÖ´Â lbnamed ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© + Á¤±³ÇÑ DNS±â¹Ý ·Îµå¹ë·±½ÌÀ» ÇÒ ¼ö ÀÖ´Ù. DNS°¡ + ½ÇÁ¦ ·Îµå¹ë·±½ÌÀ» Çϵµ·Ï ¸¸µå´Â ¿©·¯ µµ±¸¿Í Perl + 5 ÇÁ·Î±×·¥ÀÌ´Ù.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      ÀÌ ¹æ¹ýÀº mod_rewrite¿Í proxy + throughput ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¸ÕÀú DNS¿¡ ´ÙÀ½ Ç׸ñÀ» + »ç¿ëÇÏ¿© www0.foo.comÀÌ ½ÇÁ¦ + www.foo.comÀ» Àü´ãÇÏ°Ô ÇÑ´Ù

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      ±×¸®°í www0.foo.comÀ» ÇÁ·Ï½ÃÀü¿ë + ¼­¹ö·Î º¯°æÇÑ´Ù. Áï, URLÀ» ¹ÞÀ¸¸é ¼­¹ö´Â ³»ºÎ + ÇÁ·Ï½Ã¸¦ ÅëÇØ ´Ù¸¥ 5´ë ¼­¹öÁß (www1-www5) + ÇÑ´ë·Î º¸³»±â¸¸ ÇÑ´Ù. À̸¦ À§ÇØ ¸ÕÀú ¸ðµç URLÀ» + ·Îµå¹ë·±½Ì ½ºÅ©¸³Æ® lb.pl·Î º¸³»´Â + ±ÔÄ¢À» ¸¸µç´Ù.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      lb.plÀ» ÀÛ¼ºÇÑ´Ù:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- ·Îµå¹ë·±½Ì ½ºÅ©¸³Æ®
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # ±âº» È£½ºÆ®¸í
      +$first  = 1;         # ù¹ø° ¼­¹ö (ÀÚ½ÅÀÌ 0À̱⠶§¹®¿¡, 0À» »ç¿ëÇÏÁö ¾Ê´Â´Ù)
      +$last   = 5;         # round-robin¿¡¼­ ¸¶Áö¸· ¼­¹ö
      +$domain = "foo.dom"; # µµ¸ÞÀθí
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + + ¸¶Áö¸· ÁÖÀÇ: ¿Ö ÀÌ ¹æ¹ýÀÌ À¯¿ëÇÑ°¡? + www0.foo.com¿¡ ºÎ´ãÀÌ °¡Áö¾Ê´Â°¡? + ¹°·Ð, ºÎ´ãÀÌ µÈ´Ù. ±×·¯³ª ´Ü¼øÇÑ proxy throughput + ¿äû¸¸ Çϱ⶧¹®¿¡ ±¦Âú´Ù! ¸ðµç SSI, CGI, ePerl + µîÀº ÀüÀûÀ¸·Î ´Ù¸¥ ¼­¹ö°¡ ó¸®ÇÑ´Ù. ÀÌ°ÍÀÌ ÇÙ½ÉÀÌ´Ù. +
    6. + +
    7. + Çϵå¿þ¾î/TCP Round-Robin + +

      Çϵå¿þ¾î¸¦ »ç¿ëÇÑ ÇØ°áÃ¥µµ ÀÖ´Ù. Cisco´Â TCP/IP + ¼öÁØ¿¡¼­ ·Îµå¹ë·±½ÌÀ» ÇÏ´Â LocalDirector¶ó´Â ±«¹°À» + ÆÇ´Ù. ½ÇÁ¦·Î´Â À¥¼­¹ö±º ¾Õ´Ü¿¡ À§Ä¡ÇÏ´Â ÀÏÁ¾ÀÇ + ȸ·Î¼öÁØ °ÔÀÌÆ®¿þÀÌ´Ù. ÀÚ±ÝÀÌ ÃæºÐÇÏ°í °í¼º´É + ÇØ°áÃ¥ÀÌ ÇÊ¿äÇÏ´Ù¸é ÀÌ°ÍÀ» »ç¿ëÇ϶ó.

      +
    8. +
    +
    +
    + +
    + +
    + + »õ·Î¿î MIME-type, »õ·Î¿î ¼­ºñ½º + +
    +
    »óȲ¼³¸í:
    + +
    +

    ³×Æ®¿÷¿¡´Â ¸ÚÁø CGI ÇÁ·Î±×·¥µéÀÌ ¸¹´Ù. ±×·¯³ª »ç¿ëÇϱâ + ¹ø°Å·¯¿ö¼­ ¸¹Àº À¥°ü¸®ÀÚ°¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù. ¾ÆÆÄÄ¡ÀÇ + MIME-type¿¡ µû¸¥ Action Çڵ鷯 ±â´Éµµ CGI ÇÁ·Î±×·¥ÀÌ + Ưº°ÇÑ URLÀ» (Á¤È®È÷ PATH_INFO¿Í + QUERY_STRINGS) ÇÁ·Î±×·¥ÀÇ ÀÔ·ÂÀ¸·Î »ç¿ëÇÏÁö + ¾ÊÀ» ¶§¸¸ ÀûÀýÇÏ´Ù. ¸ÕÀú, È®ÀåÀÚ°¡ (secure CGI¸¦ ÁÙ¿©) + .scgiÀÎ ÆÄÀÏÀ» À¯¸íÇÑ cgiwrap + ÇÁ·Î±×·¥À¸·Î ó¸®ÇϱâÀ§ÇØ »õ·Î¿î typeÀ» ¼³Á¤ÇÑ´Ù. + ¹®Á¦´Â (À§¿¡¼­ º») ÀÏ°üµÈ URL ±¸Á¶¸¦ »ç¿ëÇÏ´Â °æ¿ì + »ç¿ëÀÚ È¨µð·ºÅ丮°¡ /u/user/foo/bar.scgi°°Àº + URLÀÎ Á¡ÀÌ´Ù. cgiwrap´Â + /~user/foo/bar.scgi/ Çü½ÄÀÇ URLÀ» + ¿øÇϱ⶧¹®ÀÌ´Ù. ´ÙÀ½ ±ÔÄ¢ÀÌ ¹®Á¦¸¦ ÇØ°áÇÑ´Ù:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    ÀÌÁ¦ ´Ù¸¥ ¸ÚÁø ÇÁ·Î±×·¥, (URL ÇÏÀ§Æ®¸®¿¡ ´ëÇÑ + access.log¸¦ Ãâ·ÂÇÏ´Â) wwwlog¿Í + (URL ÇÏÀ§Æ®¸®¿¡ Glimpse¸¦ ½ÇÇàÇÏ´Â) wwwidx°¡ + ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. ¿ì¸®´Â ÇÁ·Î±×·¥¿¡°Ô ÀÛ¾÷ÇÒ ´ë»óÀÎ + URL ¿µ¿ªÀ» ¾Ë·ÁÁà¾ß ÇÑ´Ù. ±×·¯³ª ¿äûÇÒ¶§¸¶´Ù Ç×»ó + Àû¾îÁà¾ß Çϱ⶧¹®¿¡ ±ò²ûÇÏÁö ¾Ê´Ù. Áï, º¸Åë + /u/user/foo/¿¡ ´ëÇØ swwidx + ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù¸é ´ÙÀ½°ú °°Àº ¸µÅ©¸¦ »ç¿ëÇÑ´Ù

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    ±ò²ûÇÏÁö ¾Ê´Ù. ¸µÅ©¿¡ ¿µ¿ªÀÇ À§Ä¡¿Í + CGI À§Ä¡¸¦ ¸ðµÎ Àû¾î¾ß Çϱ⶧¹®ÀÌ´Ù. + ¿µ¿ªÀ» À籸¼ºÇÑ´Ù¸é ¿©·¯ ÇÏÀÌÆÛ¸µÅ©¸¦ ¼öÁ¤Çϴµ¥ ¸¹Àº + ½Ã°£ÀÌ °É¸± °ÍÀÌ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÇØ°áÃ¥Àº ÀÚµ¿À¸·Î ÀûÀýÇÑ CGI¸¦ ½ÇÇàÇÏ´Â »õ·Î¿î + Ưº°ÇÑ URL Çü½ÄÀ» ¸¸µå´Â °ÍÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÑ´Ù:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    ÀÌÁ¦ /u/user/foo/À» °Ë»öÇÏ´Â ¸µÅ©´Â + ´ÙÀ½°ú °°´Ù

    + +
    +HREF="*"
    +/u/user/foo/* (???)
    +
    + +

    ³»ºÎÀûÀ¸·Î ´ÙÀ½°ú °°ÀÌ ÀÚµ¿º¯È¯µÈ´Ù

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    °°Àº ¹æ¹ýÀ¸·Î ¸µÅ© µÚ¿¡ :log¸¦ »ç¿ëÇÏ¿© + Á¢±Ù ·Î±× CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + +
    + +
    + + Á¤Àû¿¡¼­ µ¿ÀûÀ¸·Î + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ºê¶ó¿ìÀú¿Í »ç¿ëÀÚ°¡ ¸ð¸£°Ô ÀÚ¿¬½º·´°Ô Á¤Àû + ÆäÀÌÁö foo.htmlÀ» µ¿ÀûÀÎ foo.cgi·Î + º¯°æÇÒ ¼ö ÀÖ³ª.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    URLÀ» CGI ½ºÅ©¸³Æ®·Î ÀçÀÛ¼ºÇÏ°í, MIME-typeÀ» ¼öÁ¤ÇÏ¿© + CGI ½ºÅ©¸³Æ®·Î ½ÇÇàÇÏ°Ô ÇÑ´Ù. ±×·¡¼­ + /~quux/foo.html¸¦ ¿äûÇÏ¸é ³»ºÎÀûÀ¸·Î + /~quux/foo.cgi¸¦ ½ÇÇàÇÏ°Ô µÈ´Ù.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + +
    + +
    + + Áï¼® ÄÁÅÙÃ÷ Àç»ý¼º + +
    +
    »óȲ¼³¸í:
    + +
    +

    ÀÌ ¹æ¹ýÀº ½Ç·Î ºñ±âÀÌ´Ù: µ¿ÀûÀ¸·Î ÆäÀÌÁö¸¦ »ý¼ºÇÏÁö¸¸, + Á¤ÀûÀ¸·Î ÆäÀÌÁö¸¦ ¼­ºñ½ºÇÑ´Ù. Áï, ÆäÀÌÁö´Â ¼ø¼öÇÏ°Ô + (ÆÄÀϽýºÅÛ¿¡¼­ ÀÐÀº ³»¿ëÀ» ±×´ë·Î) Á¤Àû ÆäÀÌÁö·Î + Àü´ÞµÇÁö¸¸, ¾øÀ» °æ¿ì À¥¼­¹ö°¡ µ¿ÀûÀ¸·Î »ý¼ºÇÑ´Ù. + ±×·¯¸é ´©°¡ (ȤÀº cron ÀÛ¾÷ÀÌ) Á¤Àû ÄÁÅÙÃ÷¸¦ Áö¿ìÁö¾Ê´Â + ÇÑ CGI°¡ »ý¼ºÇÑ ÆäÀÌÁö¸¦ Á¤ÀûÀ¸·Î ¼­ºñ½ºÇÑ´Ù. ÄÁÅÙÃ÷¸¦ + Áö¿ì¸é ³»¿ëÀ» °»½ÅÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    + ´ÙÀ½ ±ÔÄ¢À» »ç¿ëÇÑ´Ù: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    ¿©±â¼­ page.html¸¦ ¿äûÇÒ¶§ + page.htmlÀÌ ¾ø°Å³ª ÆÄÀÏÅ©±â°¡ 0ÀÎ °æ¿ì + ³»ºÎÀûÀ¸·Î page.cgi¸¦ ½ÇÇàÇÑ´Ù. ¿©±â¼­ + ºñ°áÀº page.cgi°¡ ÀϹÝÀûÀÎ CGI ½ºÅ©¸³Æ®¿Í + °°ÀÌ STDOUT¿¡ Ãâ·ÂÇÏ°í, Ãß°¡·Î Ãâ·ÂÀ» + page.html ÆÄÀÏ¿¡ Àû´Â´Ù. Çѹø ½ÇÇàÇÑÈÄ + ¼­¹ö´Â page.htmlÀÇ Á¤º¸¸¦ º¸³½´Ù. À¥°ü¸®ÀÚ°¡ + °­Àç·Î ³»¿ëÀ» °»½ÅÇÏ°í ½Í´Ù¸é, (º¸Åë cron ÀÛ¾÷ÀÌ) + page.htmlÀ» Áö¿ì±â¸¸ ÇÏ¸é µÈ´Ù.

    +
    +
    + +
    + +
    + + ÀÚµ¿À¸·Î »õ·Î °íħÇÏ´Â ¹®¼­ + +
    +
    »óȲ¼³¸í:
    + +
    +

    º¹ÀâÇÑ À¥ÆäÀÌÁö¸¦ ¸¸µé¶§ ÆíÁýÀÚ°¡ ³»¿ëÀ» ¼öÁ¤ÇÒ + ¶§¸¶´Ù ÀÚµ¿À¸·Î ÆäÀÌÁö¸¦ »õ·Î °íħÇÏ´Â À¥ºê¶ó¿ìÀú°¡ + ÀÖÀ¸¸é ¾ó¸¶³ª ÁÁÀ»±î? ºÒ°¡´ÉÇÑ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    °¡´ÉÇÏ´Ù! MIME multipart ±â´É°ú À¥¼­¹ö NPH ±â´É, + mod_rewriteÀÇ URL Á¶ÀÛ ´É·ÂÀ» °áÇÕÇϸé + µÈ´Ù. ¸ÕÀú, »õ·Î¿î URL ±â´ÉÀ» ¸¸µç´Ù: URL¿¡ + :refresh¸¦ Ãß°¡Çϱ⸸ Çϸé ÆÄÀϽýºÅÛ¿¡¼­ + ¼öÁ¤µÉ ¶§¸¶´Ù »õ·Î °íħÇÑ´Ù.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    ÀÌÁ¦ ´ÙÀ½ URL¿¡ Á¢±ÙÇϸé

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    ´ÙÀ½ URLÀ» ³»ºÎÀûÀ¸·Î ºÎ¸¥´Ù

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    ÀÌÁ¦ NPH-CGI ½ºÅ©¸³Æ®¸¸ ³²¾Ò´Ù. º¸Åë "µ¶ÀÚ¿¡°Ô + ¿¬½ÀÀ¸·Î ³²°ÜµÒ"À̶ó°í ¸»ÇÏÁö¸¸ ;-) ³ª´Â À̰͵µ Á¦°øÇÑ´Ù.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + +
    + +
    + + ´ë·®ÀÇ °¡»óÈ£½ºÆ® + +
    +
    »óȲ¼³¸í:
    + +
    +

    °¡»óÈ£½ºÆ®°¡ ¸î°³¸¸ ÀÖ´Ù¸é ¾ÆÆÄÄ¡ÀÇ VirtualHost + ±â´ÉÀÌ Àß µ¿ÀÛÇÑ´Ù. ±×·¯³ª °¡»óÈ£½ºÆ®°¡ ¼ö¹é°³ ÀÖ´Â + ISP¶ó¸é ÀÌ ±â´ÉÀÌ ÃÖ¼±Àº ¾Æ´Ï´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ÀÌ ±â´ÉÀ» Á¦°øÇÏ·Á¸é Proxy Throughput + ±â´ÉÀ» (Ç÷¡±× [P]) »ç¿ëÇÏ¿© ¿ÜºÎ À¥ÆäÀÌÁö + ȤÀº Àüü ¿ÜºÎ À¥¿µ¿ªÀ» ¿ì¸®ÀÇ À̸§°ø°£¿¡ ´ëÀÀÇÑ´Ù:

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   ¸®´ÙÀÌ·ºÆ®ÇÒ¶§ Á¤±Ô È£½ºÆ®¸íÀ» »ç¿ëÇÑ´Ù.
    +UseCanonicalName on
    +
    +    :
    +#   °¡»óÈ£½ºÆ®¸¦ CLF Çü½Ä ¾Õ¿¡ Ãß°¡ÇÑ´Ù
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   ÁÖ¼­¹ö¿¡¼­ ÀçÀÛ¼º ¿£ÁøÀ» »ç¿ëÇÑ´Ù
    +RewriteEngine on
    +
    +#   µÎ ¸ÊÀ» Á¤ÀÇÇÑ´Ù: Çϳª´Â URLÀ» °íÄ¡°í,
    +#   ´Ù¸¥ Çϳª´Â °¡»óÈ£½ºÆ®º° DocumentRoot¸¦
    +#   Á¤ÀÇÇÑ´Ù.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   ÀÌÁ¦ Å©°í º¹ÀâÇÑ ±ÔÄ¢ ÇÑ°³¸¦ »ç¿ëÇÏ¿©
    +#   °¡»óÈ£½ºÆ®·Î ´ëÀÀÇÑ´Ù.
    +#
    +#   1. °¡»óÈ£½ºÆ®µéÀÌ °°ÀÌ »ç¿ëÇÏ´Â À§Ä¡´Â ´ëÀÀÇÏÁö ¾Ê´Â´Ù
    +RewriteCond   %{REQUEST_URL}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URL}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URL}  !^/commonurlN/.*
    +#
    +#   2. ¿ì¸®°¡ ÇöÀç »ç¿ëÇÏ´Â ¹æ¹ýÀÌ Host Çì´õ¸¦
    +#      °¡»óÈ£½ºÆ®¸¦ Áö¿øÇϹǷÎ
    +#      Host Çì´õ°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. È£½ºÆ®¸íÀ» ¼Ò¹®ÀÚ·Î ¸¸µç´Ù
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. vhost.map¿¡¼­ È£½ºÆ®¸íÀ» ã°í
    +#      °æ·ÎÀ϶§¸¸ ±â¾ïÇÑ´Ù
    +#      (À§¿¡¼­ "NONE"Àº ¾Æ´Ï´Ù)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. ¸¶Áö¸·À¸·Î URLÀ» ¹®¼­ À§Ä¡·Î ´ëÀÀÇÏ°í
    +#      ·Î±×¿¡ ³²±â±âÀ§ÇØ °¡»óÈ£½ºÆ®¸¦ ±â¾ïÇØ µÐ´Ù
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + +
    + +
    + +
    + + Á¢±Ù Á¦ÇÑ + +
    + + ·Îº¿ ¸·±â + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô Çϸé ƯÁ¤ À¥°ø°£ÀÇ ÆäÀÌÁö¸¦ ±Ü¾î¸ðÀ¸´Â ±ÍÂúÀº + ·Îº¿À» ¸·À» ¼ö ÀÖ³ª? "Robot Exclusion Protocol" Ç׸ñÀ» + ÀúÀåÇÑ /robots.txt ÆÄÀÏÀº º¸Åë ÀÌ·± ·Îº¿À» + ¸·´Âµ¥ ÃæºÐÇÏÁö ¾Ê´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    (¾Æ¸¶µµ µð·ºÅ丮°¡ ±í¾î¼­ ·Îº¿ÀÌ µ¹¾Æ´Ù´Ï¸é ¼­¹ö¿¡ + ºÎ´ãÀÌ Å« °æ¿ì) À¥°ø°£ /~quux/foo/arc/¿¡ + ÀÖ´Â URLµéÀ» °ÅºÎÇÏ´Â ±ÔÄ¢À» »ç¿ëÇÑ´Ù. ¿ì¸®´Â ƯÁ¤ + ·Îº¿ÀÇ Á¢±ÙÀ» ¸·¾Æ¾ß ÇÑ´Ù. Áï, ·Îº¿À» ½ÇÇàÇϴ ȣ½ºÆ®¸¦ + ¸·´Â °ÍÀ¸·Î´Â ºÒÃæºÐÇϸç, ±× È£½ºÆ®ÀÇ »ç¿ëÀÚµµ ¸·¾Æ¹ö¸®°Ô + µÈ´Ù. User-Agent HTTP Çì´õ Á¤º¸µµ ºñ±³ÇÑ´Ù.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + +
    + +
    + + ±×¸² ÆÛ°¡±â ¹æÁö + +
    +
    »óȲ¼³¸í:
    + +
    +

    http://www.quux-corp.de/~quux/¿¡ ÀÖ´Â + ÆäÀÌÁöµéÀÌ GIF ±×¸²À» Æ÷ÇÔÇÑ´Ù°í °¡Á¤ÇÏÀÚ. ÀÌ ±×¸²ÀÌ + ¸ÚÀ־, ´Ù¸¥ »ç¶÷µéÀÌ ÀÚ½ÅÀÇ ÆäÀÌÁö¿¡ Á÷Á¢ ¸µÅ©¸¦ + °Ç´Ù. ¼­¹ö¿¡ ºÒÇÊ¿äÇÑ ºÎ´ãÀÌ µÇ¹Ç·Î ¸·°í ½Í´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ±×¸²À» 100% º¸È£ÇÒ ¼ö´Â ¾øÁö¸¸, ÃÖ¼ÒÇÑ ºê¶ó¿ìÀú°¡ + HTTP Referer Çì´õ¸¦ º¸³»´Â °æ¿ì Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + +
    + +
    + + È£½ºÆ® °ÅºÎ + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ¿ÜºÎ¿¡¼­ ¼­¹ö¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Â È£½ºÆ® ¸ñ·ÏÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ³ª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¾ÆÆÄÄ¡ >= 1.3b6¿¡¼­:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    ¾ÆÆÄÄ¡ <= 1.3b6¿¡¼­:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ÁÖÀÇ! ÀÌ°ÍÀº ¸ñ·Ïó·³ º¸ÀÌÁö¸¸ ¸ñ·ÏÀÌ ¾Æ´Ï¶ó ¸ÊÀÌ´Ù.
    +##        mod_rewrite´Â ÀÌ Á¤º¸¸¦ Å°/°ª ½ÖÀ¸·Î Çؼ®Çϱ⶧¹®¿¡,
    +##        °¢ Ç׸ñÀÇ °ª ÀÚ¸®¿¡ ÃÖ¼ÒÇÑ "-"°¡ ÇÊ¿äÇÏ´Ù.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + +
    + +
    + + ÇÁ·Ï½Ã °ÅºÎ + +
    +
    »óȲ¼³¸í:
    + +
    +

    ¾î¶»°Ô ƯÁ¤ È£½ºÆ® ȤÀº ƯÁ¤ È£½ºÆ®ÀÇ »ç¿ëÀÚ°¡ + ¾ÆÆÄÄ¡ ÇÁ·Ï½Ã¸¦ »ç¿ëÇÒ ¼ö ¾øµµ·Ï Çϳª?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¸ÕÀú ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ¶§ ±¸¼ºÆÄÀÏ¿¡¼­ + mod_rewrite°¡ mod_proxy + ¾Æ·¡¿¡(!) ÀÖ¾î¾ß ÇÑ´Ù. ±×·¯¸é mod_rewrite´Â + mod_proxy ÀÌÀü¿¡ ºÒ¸°´Ù. + ÀÌÁ¦ ´ÙÀ½°ú °°ÀÌ Æ¯Á¤ È£½ºÆ®¸¦ °ÅºÎÇϵµ·Ï ¼³Á¤ÇÑ´Ù...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...±×¸®°í ´ÙÀ½Àº user@host¿¡ µû¶ó °ÅºÎÇÑ´Ù:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + +
    + +
    + + Ưº°ÇÑ ÀÎÁõ ¹æ½Ä + +
    +
    »óÈ°¼³¸í:
    + +
    +

    °¡²û ¸Å¿ì Ưº°ÇÑ ÀÎÁõÀÌ ÇÊ¿äÇÒ ¶§°¡ ÀÖ´Ù. ¿¹¸¦ + µé¾î, ¹Ì¸® ¼³Á¤ÇصР»ç¿ëÀÚÀÎÁö °Ë»çÇÑ´Ù. À̵鿡°Ô¸¸ + (mod_auth_basicÀÇ Basic Auth¸¦ »ç¿ëÇÑ + °æ¿ì¿Í ´Þ¸®) º°´Ù¸¥ ¹°À½¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    Ä£±¸¸¸ Á¢±ÙÀÌ °¡´ÉÇϵµ·Ï ÀçÀÛ¼º ±ÔÄ¢µéÀ» »ç¿ëÇÑ´Ù:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + +
    + +
    + + Referer±â¹Ý º¯È¯±â(deflector) + +
    +
    »óȲ¼³¸í:
    + +
    +

    "Referer" HTTP Çì´õ¿¡ µû¶ó ¿øÇϴ´ë·Î ÂüÁ¶ÆäÀÌÁö¸¦ + ¼³Á¤ÇÒ ¼ö ÀÖ´Â À¯¿¬ÇÑ URL º¯È¯±â¸¦ ¸¸µé ¼ö Àִ°¡?

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ´ÙÀ½°ú °°ÀÌ º¹ÀâÇÑ ±ÔÄ¢À»...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... ÀçÀÛ¼º ¸Ê°ú °°ÀÌ »ç¿ëÇÑ´Ù:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    ±×·¯¸é ¿äûÀ» ÀÚµ¿À¸·Î (¸Ê¿¡¼­ °ªÀ¸·Î "-"¸¦ + »ç¿ëÇÑ °æ¿ì) ÂüÁ¶ÆäÀÌÁö³ª (URLÀÌ ¸Ê¿¡ ÀÖ´Â °æ¿ì µÎ¹ø° + ¾Æ±Ô¸ÕÆ®·Î) ƯÁ¤ URL·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.

    +
    +
    + +
    + +
    + +
    + + ±âŸ + +
    + + ¿ÜºÎ ÀçÀÛ¼º ¿£Áø + +
    +
    »óȲ¼³¸í:
    + +
    +

    FAQ: ¾î¶»°Ô ÀÌ·±Àú·± Àâ´ÙÇÑ ¹®Á¦¸¦ Ç® ¼ö Àִ°¡? + mod_rewrite·Î´Â ÇØ°áÃ¥ÀÌ ¾Èº¸ÀδÙ...

    +
    + +
    ÇØ°áÃ¥:
    + +
    +

    ¿ÜºÎ RewriteMapÀ» »ç¿ëÇ϶ó. + Áï, ÇÁ·Î±×·¥ÀÌ RewriteMap ¿ªÇÒÀ» + ÇÑ´Ù. ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇÒ¶§ ½ÃÀÛÇÏ¿© + STDIN¿¡¼­ ¿äûÇÑ URLÀ» ¹Þ°í, (°°Àº ¼ø¼­·Î!) + °á°ú (º¸Åë ÀçÀÛ¼ºµÈ) URLÀ» STDOUT¿¡ Ãâ·ÂÇÑ´Ù.

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   ¾ÆÆÄÄ¡ ¼­¹ö°¡ ¸ØÃßÁö ¾Êµµ·Ï
    +#   ÀÔÃâ·Â ¹öÆÛ¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù
    +$| = 1;
    +
    +#   stdin¿¡¼­ ÇÑÁÙ¾¿ URLÀ» Àаí
    +#   stdout¿¡ º¯È¯ÇÑ URLÀ» Ãâ·ÂÇÑ´Ù
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    ¼³¸íÇϱâÀ§ÇØ ¸ðµç /~quux/foo/... URLÀ» + /~quux/bar/...·Î ÀçÀÛ¼ºÇÏ´Â ½ºÅ©¸³Æ®¸¦ + ¿¹·Î µé¾ú´Ù. ½ÇÁ¦·Î ¸¶À½´ë·Î ÇÁ·Î±×·¡¹ÖÇÒ ¼ö ÀÖ´Ù. + ±×·¯³ª ÀÏ¹Ý »ç¿ëÀÚ°¡ ÀÌ·± ¸ÊÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù°í ÇÏ´õ¶ó°í, ¿ÀÁ÷ ½Ã½ºÅÛ °ü¸®ÀÚ¸¸ÀÌ ¸ÊÀ» + Á¤ÀÇÇØ¾ß ÇÔÀ» ÁÖÀÇÇ϶ó.

    +
    +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/misc/rewriteguide.xml.meta b/trunk/docs/manual/misc/rewriteguide.xml.meta new file mode 100644 index 0000000000..9792580d45 --- /dev/null +++ b/trunk/docs/manual/misc/rewriteguide.xml.meta @@ -0,0 +1,12 @@ + + + + rewriteguide + /misc/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/misc/security_tips.html b/trunk/docs/manual/misc/security_tips.html new file mode 100644 index 0000000000..3746e186a7 --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.html @@ -0,0 +1,7 @@ +URI: security_tips.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: security_tips.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/misc/security_tips.html.en b/trunk/docs/manual/misc/security_tips.html.en new file mode 100644 index 0000000000..a815902f7e --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.html.en @@ -0,0 +1,350 @@ + + + +Security Tips - Apache HTTP Server + + + + + +
    <-
    +

    Security Tips

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    Some hints and tips on security issues in setting up a web server. + Some of the suggestions will be general, others specific to Apache.

    +
    + +
    top
    +
    +

    Keep up to Date

    + +

    The Apache HTTP Server has a good record for security and a + developer community highly concerned about security issues. But + it is inevitable that some problems -- small or large -- will be + discovered in software after it is released. For this reason, it + is crucial to keep aware of updates to the software. If you have + obtained your version of the HTTP Server directly from Apache, we + highly recommend you subscribe to the Apache + HTTP Server Announcements List where you can keep informed of + new releases and security updates. Similar services are available + from most third-party distributors of Apache software.

    + +

    Of course, most times that a web server is compromised, it is + not because of problems in the HTTP Server code. Rather, it comes + from problems in add-on code, CGI scripts, or the underlying + Operating System. You must therefore stay aware of problems and + updates with all the software on your system.

    + +
    top
    +
    +

    Permissions on ServerRoot Directories

    + + + +

    In typical operation, Apache is started by the root user, and it + switches to the user defined by the User directive to serve hits. As is the + case with any command that root executes, you must take care that it is + protected from modification by non-root users. Not only must the files + themselves be writeable only by root, but so must the directories, and + parents of all directories. For example, if you choose to place + ServerRoot in /usr/local/apache then it is suggested that you create + that directory as root, with commands like these:

    + +

    + mkdir /usr/local/apache
    + cd /usr/local/apache
    + mkdir bin conf logs
    + chown 0 . bin conf logs
    + chgrp 0 . bin conf logs
    + chmod 755 . bin conf logs +

    + +

    It is assumed that /, /usr, and /usr/local are only modifiable by + root. When you install the httpd executable, you + should ensure that it is similarly protected:

    + +

    + cp httpd /usr/local/apache/bin
    + chown 0 /usr/local/apache/bin/httpd
    + chgrp 0 /usr/local/apache/bin/httpd
    + chmod 511 /usr/local/apache/bin/httpd +

    + +

    You can create an htdocs subdirectory which is modifiable by other + users -- since root never executes any files out of there, and shouldn't + be creating files in there.

    + +

    If you allow non-root users to modify any files that root either + executes or writes on then you open your system to root compromises. + For example, someone could replace the httpd binary so + that the next time you start it, it will execute some arbitrary code. If + the logs directory is writeable (by a non-root user), someone could replace + a log file with a symlink to some other system file, and then root + might overwrite that file with arbitrary data. If the log files + themselves are writeable (by a non-root user), then someone may be + able to overwrite the log itself with bogus data.

    + +
    top
    +
    +

    Server Side Includes

    + + + +

    Server Side Includes (SSI) present a server administrator with + several potential security risks.

    + +

    The first risk is the increased load on the server. All + SSI-enabled files have to be parsed by Apache, whether or not + there are any SSI directives included within the files. While this + load increase is minor, in a shared server environment it can become + significant.

    + +

    SSI files also pose the same risks that are associated with CGI + scripts in general. Using the "exec cmd" element, SSI-enabled files + can execute any CGI script or program under the permissions of the + user and group Apache runs as, as configured in httpd.conf.

    + +

    There are ways to enhance the security of SSI files while still + taking advantage of the benefits they provide.

    + +

    To isolate the damage a wayward SSI file can cause, a server + administrator can enable suexec as + described in the CGI in General section

    + +

    Enabling SSI for files with .html or .htm extensions can be + dangerous. This is especially true in a shared, or high traffic, + server environment. SSI-enabled files should have a separate extension, + such as the conventional .shtml. This helps keep server load at a + minimum and allows for easier management of risk.

    + +

    Another solution is to disable the ability to run scripts and + programs from SSI pages. To do this replace Includes + with IncludesNOEXEC in the Options directive. Note that users may + still use <--#include virtual="..." --> to execute CGI scripts if + these scripts are in directories desginated by a ScriptAlias directive.

    + +
    top
    +
    +

    CGI in General

    + + + +

    First of all, you always have to remember that you must trust the + writers of the CGI scripts/programs or your ability to spot potential + security holes in CGI, whether they were deliberate or accidental. CGI + scripts can run essentially arbitrary commands on your system with the + permissions of the web server user and can therefore be extremely + dangerous if they are not carefully checked.

    + +

    All the CGI scripts will run as the same user, so they have potential + to conflict (accidentally or deliberately) with other scripts e.g. User + A hates User B, so he writes a script to trash User B's CGI database. One + program which can be used to allow scripts to run as different users is + suEXEC which is included with Apache as of + 1.2 and is called from special hooks in the Apache server code. Another + popular way of doing this is with + CGIWrap.

    + +
    top
    +
    +

    Non Script Aliased CGI

    + + + +

    Allowing users to execute CGI scripts in any directory should only be + considered if:

    + +
      +
    • You trust your users not to write scripts which will deliberately + or accidentally expose your system to an attack.
    • +
    • You consider security at your site to be so feeble in other areas, + as to make one more potential hole irrelevant.
    • +
    • You have no users, and nobody ever visits your server.
    • +
    + +
    top
    +
    +

    Script Aliased CGI

    + + + +

    Limiting CGI to special directories gives the admin control over what + goes into those directories. This is inevitably more secure than non + script aliased CGI, but only if users with write access to the + directories are trusted or the admin is willing to test each + new CGI script/program for potential security holes.

    + +

    Most sites choose this option over the non script aliased CGI + approach.

    + +
    top
    +
    +

    Other sources of dynamic content

    + + + +

    + Embedded scripting options which run as part of the server itself, + such as mod_php, mod_perl, mod_tcl, and mod_python, run under the + identity of the server itself (see the User directive), and therefore + scripts executed by these engines potentially can access anything the + server user can. Some scripting engines may provide restrictions, but + it is better to be safe and assume not.

    + +
    top
    +
    +

    Protecting System Settings

    + + + +

    To run a really tight ship, you'll want to stop users from setting + up .htaccess files which can override security features + you've configured. Here's one way to do it.

    + +

    In the server configuration file, put

    + +

    + <Directory />
    + AllowOverride None
    + </Directory> +

    + +

    This prevents the use of .htaccess files in all + directories apart from those specifically enabled.

    + +
    top
    +
    +

    Protect Server Files by Default

    + + + +

    One aspect of Apache which is occasionally misunderstood is the + feature of default access. That is, unless you take steps to change it, + if the server can find its way to a file through normal URL mapping + rules, it can serve it to clients.

    + +

    For instance, consider the following example:

    + +

    + # cd /; ln -s / public_html
    + Accessing http://localhost/~root/ +

    + +

    This would allow clients to walk through the entire filesystem. To + work around this, add the following block to your server's + configuration:

    + +

    + <Directory />
    + Order Deny,Allow
    + Deny from all
    + </Directory> +

    + +

    This will forbid default access to filesystem locations. Add + appropriate Directory blocks to + allow access only in those areas you wish. For example,

    + +

    + <Directory /usr/users/*/public_html>
    + Order Deny,Allow
    + Allow from all
    + </Directory>
    + <Directory /usr/local/httpd>
    + Order Deny,Allow
    + Allow from all
    + </Directory> +

    + +

    Pay particular attention to the interactions of Location and Directory directives; for instance, even + if <Directory /> denies access, a + <Location /> directive might overturn it

    + +

    Also be wary of playing games with the UserDir directive; setting it to + something like "./" would have the same effect, for root, as the first + example above. If you are using Apache 1.3 or above, we strongly + recommend that you include the following line in your server + configuration files:

    + +

    + UserDir disabled root +

    + +
    top
    +
    +

    Watching Your Logs

    + + + +

    To keep up-to-date with what is actually going on against your server + you have to check the Log Files. Even though + the log files only reports what has already happened, they will give you + some understanding of what attacks is thrown against the server and + allows you to check if the necessary level of security is present.

    + +

    A couple of examples:

    + +

    + grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
    + grep "client denied" error_log | tail -n 10 +

    + +

    The first example will list the number of attacks trying to exploit the + Apache Tomcat + Source.JSP Malformed Request Information Disclosure Vulnerability, + the second example will list the ten last denied clients, for example:

    + +

    + [Thu Jul 11 17:18:39 2002] [error] [client foo.bar.com] client denied + by server configuration: /usr/local/apache/htdocs/.htpasswd +

    + +

    As you can see, the log files only report what already has happened, so + if the client had been able to access the .htpasswd file you + would have seen something similar to:

    + +

    + foo.bar.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1" +

    + +

    in your Access Log. This means + you probably commented out the following in your server configuration + file:

    + +

    + <Files ~ "^\.ht">
    + Order allow,deny
    + Deny from all
    + </Files> +

    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/security_tips.html.ko.euc-kr b/trunk/docs/manual/misc/security_tips.html.ko.euc-kr new file mode 100644 index 0000000000..8178dbd4ae --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.html.ko.euc-kr @@ -0,0 +1,343 @@ + + + +º¸¾È ÆÁ - Apache HTTP Server + + + + + +
    <-
    +

    º¸¾È ÆÁ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    À¥¼­¹ö¸¦ ¿î¿µÇÒ¶§ µµ¿òÀÌ µÉ º¸¾È °ü·Ã ÈùÆ®¿Í ÆÁÀÌ´Ù. + ¾î¶² °ÍÀº ÀϹÝÀûÀÌ°í, ¾î¶² °ÍÀº ¾ÆÆÄÄ¡¿¡¸¸ ÇØ´çÇÏ´Â °ÍÀÌ´Ù.

    +
    + +
    top
    +
    +

    ÃÖ½ÅÆÇÀ¸·Î À¯ÁöÇϱâ

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¾ÈÀü°ú º¸¾È ¹®Á¦¿¡ °ü½ÉÀÌ ¸¹Àº °³¹ßÀÚ + °øµ¿Ã¼·Î À¯¸íÇÏ´Ù. ±×·¯³ª Å©°Ç ÀÛ°Ç ¹ßÇ¥ÈÄ ¹ß°ßµÇ´Â ¹®Á¦µéÀ» + ÇÇÇÒ ¼ö ¾ø´Ù. ±×·¡¼­ ¼ÒÇÁÆ®¿þ¾î¸¦ ÃֽŹöÀüÀ¸·Î À¯ÁöÇÏ´Â + °ÍÀÌ Áß¿äÇÏ´Ù. ¾ÆÆÄÄ¡¿¡¼­ Á÷Á¢ À¥¼­¹ö¸¦ ´Ù¿î·ÎµåÇß´Ù¸é, + »õ·Î¿î ¹öÀü°ú º¸¾È ¾÷µ¥ÀÌÆ®¸¦ ¾Ë·ÁÁÖ´Â ¾ÆÆÄÄ¡ + À¥¼­¹ö ¹ßÇ¥ ¸ÞÀϸµ¸®½ºÆ®¸¦ ±¸µ¶ÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù. + ¾ÆÆÄÄ¡ ¼ÒÇÁÆ®¿þ¾î¸¦ ¹èÆ÷ÇÏ´Â ¸¹Àº Á¦»ïÀڵ鵵 ºñ½ÁÇÑ ¼­ºñ½º¸¦ + Á¦°øÇÑ´Ù.

    + +

    ¹°·Ð À¥¼­¹ö Äڵ嶧¹®¿¡ À¥¼­¹ö°¡ °ø°ÝÀ» ´çÇÏ´Â °æ¿ì´Â + ¸¹Áö ¾Ê´Ù. ±×º¸´Ù Ãß°¡ ÄÚµå, CGI ½ºÅ©¸³Æ®, ÇÏÀ§ ¿î¿µÃ¼Á¦ÀÇ + ¹®Á¦·Î °ø°ÝÀ» ´çÇÏ´Â °æ¿ì°¡ ¸¹´Ù. ±×·¯¹Ç·Î Ç×»ó ÁÖÀÇÇϸç + ½Ã½ºÅÛÀÇ ¸ðµç ¼ÒÇÁÆ®¿þ¾î¸¦ ¾÷µ¥ÀÌÆ®ÇØ¾ß ÇÑ´Ù.

    + +
    top
    +
    +

    ServerRoot µð·ºÅ丮 ±ÇÇÑ

    + + + +

    º¸Åë root »ç¿ëÀÚ°¡ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÑ ÈÄ, ¿äûÀ» ¼­ºñ½ºÇϱâÀ§ÇØ + User Áö½Ã¾î·Î + ÁöÁ¤ÇÑ »ç¿ëÀÚ·Î º¯È¯ÇÑ´Ù. root°¡ ½ÇÇàÇÏ´Â ¸í·É¾î°¡ ÀÖ´Ù¸é, + root ÀÌ¿ÜÀÇ »ç¿ëÀÚ°¡ ¼öÁ¤ÇÏÁö ¸øÇϵµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù. ÀÌ + ÆÄÀϵéÀ» root¸¸ ¾µ ¼ö ÀÖ¾î¾ß ÇÏ°í, µð·ºÅ丮¿Í ¸ðµç »óÀ§µð·ºÅ丮µµ + ¸¶Âù°¡Áö´Ù. ¿¹¸¦ µé¾î, ServerRoot·Î /usr/local/apache¸¦ + »ç¿ëÇÑ´Ù¸é root »ç¿ëÀÚ°¡ ´ÙÀ½°ú °°ÀÌ µð·ºÅ丮¸¦ ¸¸µé±æ + Á¦¾ÈÇÑ´Ù:

    + +

    + mkdir /usr/local/apache
    + cd /usr/local/apache
    + mkdir bin conf logs
    + chown 0 . bin conf logs
    + chgrp 0 . bin conf logs
    + chmod 755 . bin conf logs +

    + +

    ±×·¯¸é /, /usr, /usr/local Àº root¸¸ÀÌ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. + httpd ½ÇÇàÆÄÀÏÀ» ¼³Ä¡ÇÒ¶§ ´ÙÀ½°ú °°ÀÌ º¸È£ÇØ¾ß ÇÑ´Ù:

    + +

    + cp httpd /usr/local/apache/bin
    + chown 0 /usr/local/apache/bin/httpd
    + chgrp 0 /usr/local/apache/bin/httpd
    + chmod 511 /usr/local/apache/bin/httpd +

    + +

    htdocs ÇÏÀ§µð·ºÅ丮´Â ´Ù¸¥ »ç¿ëÀÚµéÀÌ ¼öÁ¤ÇÒ ¼ö ÀÖµµ·Ï + ¸¸µé ¼ö ÀÖ´Ù -- root´Â ±×°÷¿¡ ÀÖ´Â ÆÄÀÏÀ» ½ÇÇàÇÏÁöµµ, ¸¸µéÁöµµ + ¾Ê¾Æ¾ß ÇÑ´Ù.

    + +

    root°¡ ¾Æ´Ñ »ç¿ëÀÚ°¡ root°¡ ½ÇÇàÇϰųª ¾²±â°¡´ÉÇÑ ÆÄÀÏÀ» + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù¸é ½Ã½ºÅÛÀÇ root ±ÇÇÑÀ» ÈÉÄ¥ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ´©±º°¡ httpd ½ÇÇàÆÄÀÏÀ» º¯°æÇÏ¿´´Ù¸é ´ÙÀ½¹ø ½ÃÀÛÇÒ¶§ + ÀÓÀÇÀÇ Äڵ带 ½ÇÇàÇÏ°Ô µÈ´Ù. logs µð·ºÅ丮°¡ (root°¡ ¾Æ´Ñ + »ç¿ëÀÚ¿¡°Ô) ¾²±â°¡´ÉÇÏ´Ù¸é ´©±º°¡ ·Î±×ÆÄÀÏÀ» ´Ù¸¥ ½Ã½ºÅÛÆÄÀÏ·Î + ½Éº¼¸µÅ©¸¦ °É¾î¼­ root°¡ ÆÄÀÏ¿¡ ÀÓÀÇÀÇ ÀڷḦ µ¤¾î¾µ ¼ö + ÀÖ´Ù. ·Î±×ÆÄÀÏÀÌ (root°¡ ¾Æ´Ñ »ç¿ëÀÚ¿¡°Ô) ¾²±â°¡´ÉÇÏ´Ù¸é + ´©±º°¡ ·Î±×¿¡ ÀÌ»óÇÑ ÀڷḦ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    Server Side Includes

    + + + +

    Server Side Includes (SSI)´Â ¼­¹ö °ü¸®ÀÚ¿¡°Ô º¸¾È»ó ¸î°¡Áö + ÀáÀçÀûÀÎ À§ÇèÀÌ´Ù.

    + +

    ù¹ø° À§ÇèÀº ¼­¹öÀÇ ºÎÇϸ¦ ´Ã¸®´Â Á¡ÀÌ´Ù. ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡ + SSI Áö½Ã¾î°¡ ÀÖ´ÂÁö ¿©ºÎ¿Í °ü°è¾øÀÌ ¸ðµç SSI ÆÄÀÏÀ» ºÐ¼®ÇØ¾ß + ÇÑ´Ù. Á¶±Ý ºÎÇÏ°¡ ´ÃÁö¸¸, ¼­¹ö¸¦ ¿©·¯ »ç¶÷ÀÌ °°ÀÌ »ç¿ëÇÏ´Â + ȯ°æ¿¡¼­´Â ½É°¢ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç, SSI ÆÄÀÏÀº ÀϹÝÀûÀÎ CGI ½ºÅ©¸³Æ®¿Í µ¿ÀÏÇÑ À§ÇèÀ» + °¡Áø´Ù. SSI ÆÄÀÏ¿¡¼­ "exec cmd"¸¦ »ç¿ëÇϸé httpd.conf¿¡¼­ + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϵµ·Ï ¼³Á¤ÇÑ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑÀ¸·Î CGI + ½ºÅ©¸³Æ®³ª ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀåÁ¡À» È°¿ëÇϸ鼭 SSI ÆÄÀÏÀÇ º¸¾ÈÀ» Çâ»ó½ÃÅ°´Â ¹æ¹ýÀÌ + ÀÖ´Ù.

    + +

    SSI ÆÄÀÏÀÌ °¡Á®¿Ã ¼ö ÀÖ´Â ÇÇÇظ¦ °Ý¸®ÇϱâÀ§ÇØ ¼­¹ö°ü¸®ÀÚ´Â + ÀϹÝÀûÀÎ CGI Àý¿¡¼­ ¼³¸íÇÏ´Â ¹æ¹ýÀ¸·Î + suexec¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù

    + +

    .htmlÀ̳ª .htm È®ÀåÀÚ¸¦ SSI ÆÄÀÏ·Î »ç¿ëÇÏ´Â °ÍÀº À§ÇèÇÏ´Ù. + ƯÈ÷ ¿©·¯ »ç¶÷ÀÌ °øÀ¯Çϰųª Åë½Å·®ÀÌ ¸¹Àº ¼­¹ö ȯ°æ¿¡¼­ + À§ÇèÇÏ´Ù. SSI ÆÄÀÏÀº ÀϹÝÀûÀ¸·Î ¸¹ÀÌ »ç¿ëÇÏ´Â .shtml °°Àº + º°µµÀÇ È®ÀåÀÚ¸¦ °¡Á®¾ß ÇÑ´Ù. ±×·¯¸é ¼­¹ö ºÎÇϸ¦ ÃÖ¼ÒÈ­ÇÏ°í + À§Çè¿ä¼Ò¸¦ ½±°Ô °ü¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº SSI ÆäÀÌÁö°¡ ½ºÅ©¸³Æ®³ª ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö + ¸øÇϵµ·Ï ¸¸µå´Â °ÍÀÌ´Ù. Options Áö½Ã¾î¿¡¼­ Includes + ´ë½Å IncludesNOEXEC¸¦ »ç¿ëÇÑ´Ù. ±×·¡µµ ½ºÅ©¸³Æ®°¡ + ScriptAlias Áö½Ã¾î·Î + ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ ÀÖ´Ù¸é <--#include virtual="..." -->¸¦ + »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÒ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó.

    + +
    top
    +
    +

    ÀϹÝÀûÀÎ CGI

    + + + +

    °á±¹ ´ç½ÅÀº Ç×»ó CGI ½ºÅ©¸³Æ®/ÇÁ·Î±×·¥ÀÇ ÀúÀÚ¸¦ ½Å·ÚÇØ¾ß + ÇÏ°í, °íÀÇ°Ç ½Ç¼öÀÌ°Ç CGIÀÇ ÀáÀçÀûÀÎ º¸¾È»ó ÇãÁ¡À» ¹ß°ßÇÒ + ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ±âº»ÀûÀ¸·Î CGI ½ºÅ©¸³Æ®´Â À¥¼­¹ö »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ½Ã½ºÅÛ¿¡¼­ ¾î¶² ¸í·É¾î¶óµµ ½ÇÇàÇÒ ¼ö Àֱ⶧¹®¿¡ + ÁÖÀÇÀÖ°Ô È®ÀÎÇÏÁö ¾ÊÀ¸¸é ¸Å¿ì À§ÇèÇÏ´Ù.

    + +

    ¸ðµç CGI ½ºÅ©¸³Æ®°¡ °°Àº »ç¿ëÀÚ·Î ½ÇÇàµÇ±â¶§¹®¿¡ ´Ù¸¥ + ½ºÅ©¸³Æ®¿Í (°íÀÇ°Ç ½Ç¼öÀÌ°Ç) Ãæµ¹ÇÒ °¡´É¼ºÀÌ ÀÖ´Ù. ¿¹¸¦ + µé¾î, »ç¿ëÀÚ A´Â »ç¿ëÀÚ B¸¦ ¸Å¿ì ½È¾îÇÏ¿©, »ç¿ëÀÚ BÀÇ CGI + µ¥ÀÌÅͺ£À̽º¸¦ Áö¿ö¹ö¸®´Â ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡ + 1.2 ¹öÀüºÎÅÍ Æ÷ÇԵǾú°í ¾ÆÆÄÄ¡ ¼­¹ö¿¡¼­ Ưº°ÇÑ ÈÅ(hook)À¸·Î + µ¿ÀÛÇÏ´Â suEXEC´Â ½ºÅ©¸³Æ®¸¦ + ´Ù¸¥ »ç¿ëÀÚ·Î ½ÇÇàÇÏ´Â ¹æ¹ýÁß Çϳª´Ù. ´Ù¸¥ ´ëÁßÀûÀÎ ¹æ¹ý¿¡´Â + CGIWrapÀÌ ÀÖ´Ù.

    + +
    top
    +
    +

    ScriptAliasÇÏÁö ¾ÊÀº CGI

    + + + +

    ´ÙÀ½ Á¶°ÇÀ» ¸¸Á·ÇÒ¶§¸¸ »ç¿ëÀÚ°¡ ¾î¶² µð·ºÅ丮¿¡¼­¶óµµ + CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    • ´ç½ÅÀº °íÀÇ°Ç ½Ç¼öÀÌ°Ç »ç¿ëÀÚ°¡ ½Ã½ºÅÛÀ» °ø°Ý¿¡ ³ëÃâ½ÃÅ°´Â + ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÏÁö ¾Ê´Â´Ù°í ¹Ï´Â´Ù.
    • +
    • ½Ã½ºÅÛÀÇ ´Ù¸¥ ºÎºÐÀÇ º¸¾ÈÀÌ ¾àÇؼ­, ÀáÀçÀûÀÎ ÇãÁ¡À» + Çϳª ´õ ¸¸µé¾îµµ ³ªºüÁú °ÍÀÌ ¾ø´Ù°í »ý°¢ÇÏ´Â °æ¿ì.
    • +
    • »ç¿ëÀÚ°¡ ¾ø°í, ¾Æ¸¶ ¾Æ¹«µµ ¼­¹ö¸¦ ¹æ¹®ÇÏÁö¾Ê´Â °æ¿ì.
    • +
    + +
    top
    +
    +

    ScriptAliasÇÑ CGI

    + + + +

    ƯÁ¤ µð·ºÅ丮¿¡¼­¸¸ CGI¸¦ ½ÇÇàÇÒ ¼ö ÀÖµµ·Ï Á¦ÇÑÇÏ¸é °ü¸®ÀÚ´Â + ÀÌµé µð·ºÅ丮¸¦ ÅëÁ¦ÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì´Â scriptaliasÇÏÁö + ¾ÊÀº CGIº¸´Ù È®½ÇÈ÷ ¾ÈÀüÇÏ´Ù. ´Ü, ½Å·ÚÇÏ´Â »ç¿ëÀÚ¸¸ µð·ºÅ丮¿¡ + Á¢±ÙÇÒ ¼ö ÀÖ°í, °ü¸®ÀÚ°¡ »õ·Î¿î CGI ½ºÅ©¸³Æ®/ÇÁ·Î±×·¥ÀÇ + ÀáÀçÀûÀÎ º¸¾È»ó ÇãÁ¡À» °Ë»çÇÒ ¿ëÀÌ°¡ ÀÖ´Ù¸é.

    + +

    ´ëºÎºÐÀÇ »çÀÌÆ®´Â scriptaliasÇÏÁö ¾ÊÀº CGI ¹æ½Ä ´ë½Å + ÀÌ ¹æ½ÄÀ» »ç¿ëÇÑ´Ù.

    + +
    top
    +
    +

    µ¿Àû ³»¿ëÀ» »ý¼ºÇÏ´Â ´Ù¸¥ ¹æ¹ý

    + + + +

    + mod_php, mod_perl, mod_tcl, mod_python °°ÀÌ ¼­¹öÀÇ ÀϺηΠ+ µ¿ÀÛÇÏ´Â ÀÓº£µðµå ½ºÅ©¸³Æ®´Â ¼­¹ö¿Í °°Àº »ç¿ëÀÚ·Î (User Áö½Ã¾î Âü°í) ½ÇÇàµÇ±â¶§¹®¿¡, + ½ºÅ©¸³Æ® ¿£ÁøÀÌ ½ÇÇàÇÏ´Â ½ºÅ©¸³Æ®´Â ÀáÀçÀûÀ¸·Î ¼­¹ö »ç¿ëÀÚ°¡ + Á¢±ÙÇÒ ¼ö ÀÖ´Â ¸ðµç °Í¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù. ¾î¶² ½ºÅ©¸³Æ® ¿£ÁøÀº + ¾î´ÀÁ¤µµ Á¦ÇÑÀ» ÇÏÁö¸¸, ¾ÈÀüÇÏ´Ù°í °¡Á¤ÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù.

    + +
    top
    +
    +

    ½Ã½ºÅÛ ¼³Á¤ º¸È£Çϱâ

    + + + +

    Á¤¸»·Î ¾ÈÀüÇÑ ¼­¹ö¸¦ ¿î¿µÇÏ·Á¸é »ç¿ëÀÚ°¡ + .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© ´ç½ÅÀÌ ¼³Á¤ÇÑ º¸¾È±â´ÉÀ» + º¯°æÇÏ±æ ¹Ù¶óÁö ¾ÊÀ» °ÍÀÌ´Ù. ±×·¯±âÀ§ÇØ ´ÙÀ½°ú °°Àº ¹æ¹ýÀÌ + ÀÖ´Ù.

    + +

    ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½À» Ãß°¡ÇÑ´Ù

    + +

    + <Directory />
    + AllowOverride None
    + </Directory> +

    + +

    ±×·¯¸é »ç¿ë°¡´ÉÇϵµ·Ï ¸í½ÃÀûÀ¸·Î Çã¿ëÇÑ µð·ºÅ丮¸¦ Á¦¿ÜÇÏ°í´Â + .htaccess ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +
    top
    +
    +

    ±âº»ÀûÀ¸·Î ¼­¹ö¿¡ ÀÖ´Â ÆÄÀÏ º¸È£Çϱâ

    + + + +

    »ç¶÷µéÀº Á¾Á¾ ¾ÆÆÄÄ¡ÀÇ ±âº» Á¢±Ù¿¡ ´ëÇØ À߸ø ¾Ë°íÀÖ´Ù. + Áï, ¼­¹ö°¡ ÀϹÝÀûÀÎ URL ´ëÀÀ ±ÔÄ¢À» »ç¿ëÇÏ¿© ÆÄÀÏÀ» ãÀ» + ¼ö ÀÖ´Ù¸é, Ưº°È÷ Á¶Ä¡¸¦ ÇÏÁö ¾Ê´ÂÇÑ Å¬¶óÀ̾ðÆ®¿¡°Ô ÆÄÀÏÀÌ + ¼­ºñ½ºµÉ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ¾Æ·¡¿Í °°Àº °æ¿ì:

    + +

    + # cd /; ln -s / public_html
    + http://localhost/~root/ ¿¡ Á¢±ÙÇÑ´Ù +

    + +

    ±×·¯¸é Ŭ¶óÀ̾ðÆ®´Â Àüü ÆÄÀϽýºÅÛÀ» µ¹¾Æ´Ù´Ò ¼ö ÀÖ´Ù. + À̸¦ ¸·±âÀ§ÇØ ¼­¹ö¼³Á¤¿¡¼­ ´ÙÀ½°ú °°Àº Á¶Ä¡¸¦ ÇÑ´Ù:

    + +

    + <Directory />
    + Order Deny,Allow
    + Deny from all
    + </Directory> +

    + +

    ±×·¯¸é ÆÄÀϽýºÅÛ À§Ä¡¿¡ ´ëÇØ ±âº» Á¢±ÙÀÌ °ÅºÎµÈ´Ù. + ¿øÇÏ´Â ¿µ¿ª¿¡ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ´ÙÀ½°ú °°Àº Directory ºí·ÏÀ» Ãß°¡ÇÑ´Ù.

    + +

    + <Directory /usr/users/*/public_html>
    + Order Deny,Allow
    + Allow from all
    + </Directory>
    + <Directory /usr/local/httpd>
    + Order Deny,Allow
    + Allow from all
    + </Directory> +

    + +

    Location°ú Directory Áö½Ã¾î¸¦ °°ÀÌ »ç¿ëÇÏ´Â + °æ¿ì Ưº°È÷ ÁÖÀǸ¦ ±â¿ï¿©¶ó. ¿¹¸¦ µé¾î, <Directory + />°¡ Á¢±ÙÀ» °ÅºÎÇÏ´õ¶óµµ <Location + /> Áö½Ã¾î°¡ À̸¦ ¹«½ÃÇÒ ¼ö ÀÖ´Ù

    + +

    UserDir Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â °æ¿ì¿¡µµ ÁÖÀÇÇ϶ó. Áö½Ã¾î¸¦ "./" °°ÀÌ ¼³Á¤Çϸé + root »ç¿ëÀÚ¿¡ ´ëÇØ ¹Ù·Î À§ÀÇ °æ¿ì¿Í °°Àº ¹®Á¦°¡ ¹ß»ýÇÑ´Ù. + ¾ÆÆÄÄ¡ 1.3 ÀÌ»óÀ» »ç¿ëÇÑ´Ù¸é ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ¾Æ·¡ ÁÙÀ» Ãß°¡Çϱæ + °­·ÂÈ÷ ±ÇÇÑ´Ù:

    + +

    + UserDir disabled root +

    + +
    top
    +
    +

    ·Î±× »ìÆ캸±â

    + + + +

    ½ÇÁ¦·Î ¼­¹ö¿¡¼­ ¹«½¼ ÀÏÀÌ À־°í ÀÖ´ÂÁö ¾Ë·Á¸é ·Î±×ÆÄÀÏÀ» »ìÆìºÁ¾ß ÇÑ´Ù. ·Î±×ÆÄÀÏÀº + ÀÌ¹Ì ÀϾ Àϸ¸À» º¸°íÇÏÁö¸¸, ¼­¹ö¿¡ ¾î¶² °ø°ÝÀÌ ÀÖ¾ú´ÂÁö + ¾Ë·ÁÁÖ°í ÇöÀç ÇÊ¿äÇÑ ¸¸Å­ ¾ÈÀüÇÑÁö È®ÀÎÇÏ°Ô ÇØÁØ´Ù.

    + +

    ¿©·¯°¡Áö ¿¹:

    + +

    + grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
    + grep "client denied" error_log | tail -n 10 +

    + +

    ù¹ø° ¿¹´Â À߸øµÈ + Source.JSP ¿äûÀ¸·Î ¼­¹öÁ¤º¸¸¦ ¾Ë¾Æ³¾ ¼ö ÀÖ´Â TomcatÀÇ + Ãë¾àÁ¡¸¦ ÀÌ¿ëÇÏ·Á´Â °ø°Ý Ƚ¼ö¸¦ ¾Ë·ÁÁÖ°í, µÎ¹ø° ¿¹´Â + Á¢±ÙÀÌ °ÅºÎµÈ Ãֱ٠Ŭ¶óÀ̾ðÆ® 10°³¸¦ ´ÙÀ½°ú °°ÀÌ º¸¿©ÁØ´Ù:

    + +

    + [Thu Jul 11 17:18:39 2002] [error] [client foo.bar.com] client denied + by server configuration: /usr/local/apache/htdocs/.htpasswd +

    + +

    Àß ¾Ë µíÀÌ ·Î±×ÆÄÀÏÀº ÀÌ¹Ì ¹ß»ýÇÑ »ç°Ç¸¸À» º¸°íÇÑ´Ù. + ±×·¡¼­ Ŭ¶óÀ̾ðÆ®°¡ .htpasswd ÆÄÀÏ¿¡ Á¢±ÙÇÒ + ¼ö ÀÖ¾ú´Ù¸é Á¢±Ù ·Î±×¿¡ + ´ÙÀ½°ú °°Àº ±â·ÏÀÌ ³²À» °ÍÀÌ´Ù:

    + +

    + foo.bar.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1" +

    + +

    Áï, ´ç½ÅÀº ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ ´ÙÀ½ ºÎºÐÀ» ÁÖ¼®Ã³¸®ÇßÀ» + °ÍÀÌ´Ù:

    + +

    + <Files ~ "^\.ht">
    + Order allow,deny
    + Deny from all
    + <Files> +

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/misc/security_tips.xml b/trunk/docs/manual/misc/security_tips.xml new file mode 100644 index 0000000000..422d3317e2 --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.xml @@ -0,0 +1,345 @@ + + + + + + + + + Miscellaneous Documentation + + Security Tips + + +

    Some hints and tips on security issues in setting up a web server. + Some of the suggestions will be general, others specific to Apache.

    +
    + +
    Keep up to Date + +

    The Apache HTTP Server has a good record for security and a + developer community highly concerned about security issues. But + it is inevitable that some problems -- small or large -- will be + discovered in software after it is released. For this reason, it + is crucial to keep aware of updates to the software. If you have + obtained your version of the HTTP Server directly from Apache, we + highly recommend you subscribe to the Apache + HTTP Server Announcements List where you can keep informed of + new releases and security updates. Similar services are available + from most third-party distributors of Apache software.

    + +

    Of course, most times that a web server is compromised, it is + not because of problems in the HTTP Server code. Rather, it comes + from problems in add-on code, CGI scripts, or the underlying + Operating System. You must therefore stay aware of problems and + updates with all the software on your system.

    + +
    + +
    + + Permissions on ServerRoot Directories + +

    In typical operation, Apache is started by the root user, and it + switches to the user defined by the User directive to serve hits. As is the + case with any command that root executes, you must take care that it is + protected from modification by non-root users. Not only must the files + themselves be writeable only by root, but so must the directories, and + parents of all directories. For example, if you choose to place + ServerRoot in /usr/local/apache then it is suggested that you create + that directory as root, with commands like these:

    + + + mkdir /usr/local/apache
    + cd /usr/local/apache
    + mkdir bin conf logs
    + chown 0 . bin conf logs
    + chgrp 0 . bin conf logs
    + chmod 755 . bin conf logs +
    + +

    It is assumed that /, /usr, and /usr/local are only modifiable by + root. When you install the httpd executable, you + should ensure that it is similarly protected:

    + + + cp httpd /usr/local/apache/bin
    + chown 0 /usr/local/apache/bin/httpd
    + chgrp 0 /usr/local/apache/bin/httpd
    + chmod 511 /usr/local/apache/bin/httpd +
    + +

    You can create an htdocs subdirectory which is modifiable by other + users -- since root never executes any files out of there, and shouldn't + be creating files in there.

    + +

    If you allow non-root users to modify any files that root either + executes or writes on then you open your system to root compromises. + For example, someone could replace the httpd binary so + that the next time you start it, it will execute some arbitrary code. If + the logs directory is writeable (by a non-root user), someone could replace + a log file with a symlink to some other system file, and then root + might overwrite that file with arbitrary data. If the log files + themselves are writeable (by a non-root user), then someone may be + able to overwrite the log itself with bogus data.

    + +
    + +
    + + Server Side Includes + +

    Server Side Includes (SSI) present a server administrator with + several potential security risks.

    + +

    The first risk is the increased load on the server. All + SSI-enabled files have to be parsed by Apache, whether or not + there are any SSI directives included within the files. While this + load increase is minor, in a shared server environment it can become + significant.

    + +

    SSI files also pose the same risks that are associated with CGI + scripts in general. Using the "exec cmd" element, SSI-enabled files + can execute any CGI script or program under the permissions of the + user and group Apache runs as, as configured in httpd.conf.

    + +

    There are ways to enhance the security of SSI files while still + taking advantage of the benefits they provide.

    + +

    To isolate the damage a wayward SSI file can cause, a server + administrator can enable suexec as + described in the CGI in General section

    + +

    Enabling SSI for files with .html or .htm extensions can be + dangerous. This is especially true in a shared, or high traffic, + server environment. SSI-enabled files should have a separate extension, + such as the conventional .shtml. This helps keep server load at a + minimum and allows for easier management of risk.

    + +

    Another solution is to disable the ability to run scripts and + programs from SSI pages. To do this replace Includes + with IncludesNOEXEC in the Options directive. Note that users may + still use <--#include virtual="..." --> to execute CGI scripts if + these scripts are in directories desginated by a ScriptAlias directive.

    + +
    + +
    + + CGI in General + +

    First of all, you always have to remember that you must trust the + writers of the CGI scripts/programs or your ability to spot potential + security holes in CGI, whether they were deliberate or accidental. CGI + scripts can run essentially arbitrary commands on your system with the + permissions of the web server user and can therefore be extremely + dangerous if they are not carefully checked.

    + +

    All the CGI scripts will run as the same user, so they have potential + to conflict (accidentally or deliberately) with other scripts e.g. User + A hates User B, so he writes a script to trash User B's CGI database. One + program which can be used to allow scripts to run as different users is + suEXEC which is included with Apache as of + 1.2 and is called from special hooks in the Apache server code. Another + popular way of doing this is with + CGIWrap.

    + +
    + +
    + + Non Script Aliased CGI + +

    Allowing users to execute CGI scripts in any directory should only be + considered if:

    + +
      +
    • You trust your users not to write scripts which will deliberately + or accidentally expose your system to an attack.
    • +
    • You consider security at your site to be so feeble in other areas, + as to make one more potential hole irrelevant.
    • +
    • You have no users, and nobody ever visits your server.
    • +
    + +
    + +
    + + Script Aliased CGI + +

    Limiting CGI to special directories gives the admin control over what + goes into those directories. This is inevitably more secure than non + script aliased CGI, but only if users with write access to the + directories are trusted or the admin is willing to test each + new CGI script/program for potential security holes.

    + +

    Most sites choose this option over the non script aliased CGI + approach.

    + +
    + +
    + + Other sources of dynamic content + +

    + Embedded scripting options which run as part of the server itself, + such as mod_php, mod_perl, mod_tcl, and mod_python, run under the + identity of the server itself (see the User directive), and therefore + scripts executed by these engines potentially can access anything the + server user can. Some scripting engines may provide restrictions, but + it is better to be safe and assume not.

    + +
    + +
    + + Protecting System Settings + +

    To run a really tight ship, you'll want to stop users from setting + up .htaccess files which can override security features + you've configured. Here's one way to do it.

    + +

    In the server configuration file, put

    + + + <Directory />
    + AllowOverride None
    + </Directory> +
    + +

    This prevents the use of .htaccess files in all + directories apart from those specifically enabled.

    + +
    + +
    + + Protect Server Files by Default + +

    One aspect of Apache which is occasionally misunderstood is the + feature of default access. That is, unless you take steps to change it, + if the server can find its way to a file through normal URL mapping + rules, it can serve it to clients.

    + +

    For instance, consider the following example:

    + + + # cd /; ln -s / public_html
    + Accessing http://localhost/~root/ +
    + +

    This would allow clients to walk through the entire filesystem. To + work around this, add the following block to your server's + configuration:

    + + + <Directory />
    + Order Deny,Allow
    + Deny from all
    + </Directory> +
    + +

    This will forbid default access to filesystem locations. Add + appropriate Directory blocks to + allow access only in those areas you wish. For example,

    + + + <Directory /usr/users/*/public_html>
    + Order Deny,Allow
    + Allow from all
    + </Directory>
    + <Directory /usr/local/httpd>
    + Order Deny,Allow
    + Allow from all
    + </Directory> +
    + +

    Pay particular attention to the interactions of Location and Directory directives; for instance, even + if <Directory /> denies access, a + <Location /> directive might overturn it

    + +

    Also be wary of playing games with the UserDir directive; setting it to + something like "./" would have the same effect, for root, as the first + example above. If you are using Apache 1.3 or above, we strongly + recommend that you include the following line in your server + configuration files:

    + + + UserDir disabled root + + +
    + +
    + + Watching Your Logs + +

    To keep up-to-date with what is actually going on against your server + you have to check the Log Files. Even though + the log files only reports what has already happened, they will give you + some understanding of what attacks is thrown against the server and + allows you to check if the necessary level of security is present.

    + +

    A couple of examples:

    + + + grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
    + grep "client denied" error_log | tail -n 10 +
    + +

    The first example will list the number of attacks trying to exploit the + Apache Tomcat + Source.JSP Malformed Request Information Disclosure Vulnerability, + the second example will list the ten last denied clients, for example:

    + + + [Thu Jul 11 17:18:39 2002] [error] [client foo.bar.com] client denied + by server configuration: /usr/local/apache/htdocs/.htpasswd + + +

    As you can see, the log files only report what already has happened, so + if the client had been able to access the .htpasswd file you + would have seen something similar to:

    + + + foo.bar.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1" + + +

    in your Access Log. This means + you probably commented out the following in your server configuration + file:

    + + + <Files ~ "^\.ht">
    + Order allow,deny
    + Deny from all
    + </Files> +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/security_tips.xml.ko b/trunk/docs/manual/misc/security_tips.xml.ko new file mode 100644 index 0000000000..efb54bef22 --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.xml.ko @@ -0,0 +1,335 @@ + + + + + + + + + Miscellaneous Documentation + + º¸¾È ÆÁ + + +

    À¥¼­¹ö¸¦ ¿î¿µÇÒ¶§ µµ¿òÀÌ µÉ º¸¾È °ü·Ã ÈùÆ®¿Í ÆÁÀÌ´Ù. + ¾î¶² °ÍÀº ÀϹÝÀûÀÌ°í, ¾î¶² °ÍÀº ¾ÆÆÄÄ¡¿¡¸¸ ÇØ´çÇÏ´Â °ÍÀÌ´Ù.

    +
    + +
    ÃÖ½ÅÆÇÀ¸·Î À¯ÁöÇϱâ + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ¾ÈÀü°ú º¸¾È ¹®Á¦¿¡ °ü½ÉÀÌ ¸¹Àº °³¹ßÀÚ + °øµ¿Ã¼·Î À¯¸íÇÏ´Ù. ±×·¯³ª Å©°Ç ÀÛ°Ç ¹ßÇ¥ÈÄ ¹ß°ßµÇ´Â ¹®Á¦µéÀ» + ÇÇÇÒ ¼ö ¾ø´Ù. ±×·¡¼­ ¼ÒÇÁÆ®¿þ¾î¸¦ ÃֽŹöÀüÀ¸·Î À¯ÁöÇÏ´Â + °ÍÀÌ Áß¿äÇÏ´Ù. ¾ÆÆÄÄ¡¿¡¼­ Á÷Á¢ À¥¼­¹ö¸¦ ´Ù¿î·ÎµåÇß´Ù¸é, + »õ·Î¿î ¹öÀü°ú º¸¾È ¾÷µ¥ÀÌÆ®¸¦ ¾Ë·ÁÁÖ´Â ¾ÆÆÄÄ¡ + À¥¼­¹ö ¹ßÇ¥ ¸ÞÀϸµ¸®½ºÆ®¸¦ ±¸µ¶ÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù. + ¾ÆÆÄÄ¡ ¼ÒÇÁÆ®¿þ¾î¸¦ ¹èÆ÷ÇÏ´Â ¸¹Àº Á¦»ïÀڵ鵵 ºñ½ÁÇÑ ¼­ºñ½º¸¦ + Á¦°øÇÑ´Ù.

    + +

    ¹°·Ð À¥¼­¹ö Äڵ嶧¹®¿¡ À¥¼­¹ö°¡ °ø°ÝÀ» ´çÇÏ´Â °æ¿ì´Â + ¸¹Áö ¾Ê´Ù. ±×º¸´Ù Ãß°¡ ÄÚµå, CGI ½ºÅ©¸³Æ®, ÇÏÀ§ ¿î¿µÃ¼Á¦ÀÇ + ¹®Á¦·Î °ø°ÝÀ» ´çÇÏ´Â °æ¿ì°¡ ¸¹´Ù. ±×·¯¹Ç·Î Ç×»ó ÁÖÀÇÇϸç + ½Ã½ºÅÛÀÇ ¸ðµç ¼ÒÇÁÆ®¿þ¾î¸¦ ¾÷µ¥ÀÌÆ®ÇØ¾ß ÇÑ´Ù.

    + +
    + +
    + + ServerRoot µð·ºÅ丮 ±ÇÇÑ + +

    º¸Åë root »ç¿ëÀÚ°¡ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÑ ÈÄ, ¿äûÀ» ¼­ºñ½ºÇϱâÀ§ÇØ + User Áö½Ã¾î·Î + ÁöÁ¤ÇÑ »ç¿ëÀÚ·Î º¯È¯ÇÑ´Ù. root°¡ ½ÇÇàÇÏ´Â ¸í·É¾î°¡ ÀÖ´Ù¸é, + root ÀÌ¿ÜÀÇ »ç¿ëÀÚ°¡ ¼öÁ¤ÇÏÁö ¸øÇϵµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù. ÀÌ + ÆÄÀϵéÀ» root¸¸ ¾µ ¼ö ÀÖ¾î¾ß ÇÏ°í, µð·ºÅ丮¿Í ¸ðµç »óÀ§µð·ºÅ丮µµ + ¸¶Âù°¡Áö´Ù. ¿¹¸¦ µé¾î, ServerRoot·Î /usr/local/apache¸¦ + »ç¿ëÇÑ´Ù¸é root »ç¿ëÀÚ°¡ ´ÙÀ½°ú °°ÀÌ µð·ºÅ丮¸¦ ¸¸µé±æ + Á¦¾ÈÇÑ´Ù:

    + + + mkdir /usr/local/apache
    + cd /usr/local/apache
    + mkdir bin conf logs
    + chown 0 . bin conf logs
    + chgrp 0 . bin conf logs
    + chmod 755 . bin conf logs +
    + +

    ±×·¯¸é /, /usr, /usr/local Àº root¸¸ÀÌ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. + httpd ½ÇÇàÆÄÀÏÀ» ¼³Ä¡ÇÒ¶§ ´ÙÀ½°ú °°ÀÌ º¸È£ÇØ¾ß ÇÑ´Ù:

    + + + cp httpd /usr/local/apache/bin
    + chown 0 /usr/local/apache/bin/httpd
    + chgrp 0 /usr/local/apache/bin/httpd
    + chmod 511 /usr/local/apache/bin/httpd +
    + +

    htdocs ÇÏÀ§µð·ºÅ丮´Â ´Ù¸¥ »ç¿ëÀÚµéÀÌ ¼öÁ¤ÇÒ ¼ö ÀÖµµ·Ï + ¸¸µé ¼ö ÀÖ´Ù -- root´Â ±×°÷¿¡ ÀÖ´Â ÆÄÀÏÀ» ½ÇÇàÇÏÁöµµ, ¸¸µéÁöµµ + ¾Ê¾Æ¾ß ÇÑ´Ù.

    + +

    root°¡ ¾Æ´Ñ »ç¿ëÀÚ°¡ root°¡ ½ÇÇàÇϰųª ¾²±â°¡´ÉÇÑ ÆÄÀÏÀ» + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù¸é ½Ã½ºÅÛÀÇ root ±ÇÇÑÀ» ÈÉÄ¥ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ´©±º°¡ httpd ½ÇÇàÆÄÀÏÀ» º¯°æÇÏ¿´´Ù¸é ´ÙÀ½¹ø ½ÃÀÛÇÒ¶§ + ÀÓÀÇÀÇ Äڵ带 ½ÇÇàÇÏ°Ô µÈ´Ù. logs µð·ºÅ丮°¡ (root°¡ ¾Æ´Ñ + »ç¿ëÀÚ¿¡°Ô) ¾²±â°¡´ÉÇÏ´Ù¸é ´©±º°¡ ·Î±×ÆÄÀÏÀ» ´Ù¸¥ ½Ã½ºÅÛÆÄÀÏ·Î + ½Éº¼¸µÅ©¸¦ °É¾î¼­ root°¡ ÆÄÀÏ¿¡ ÀÓÀÇÀÇ ÀڷḦ µ¤¾î¾µ ¼ö + ÀÖ´Ù. ·Î±×ÆÄÀÏÀÌ (root°¡ ¾Æ´Ñ »ç¿ëÀÚ¿¡°Ô) ¾²±â°¡´ÉÇÏ´Ù¸é + ´©±º°¡ ·Î±×¿¡ ÀÌ»óÇÑ ÀڷḦ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    + + Server Side Includes + +

    Server Side Includes (SSI)´Â ¼­¹ö °ü¸®ÀÚ¿¡°Ô º¸¾È»ó ¸î°¡Áö + ÀáÀçÀûÀÎ À§ÇèÀÌ´Ù.

    + +

    ù¹ø° À§ÇèÀº ¼­¹öÀÇ ºÎÇϸ¦ ´Ã¸®´Â Á¡ÀÌ´Ù. ¾ÆÆÄÄ¡´Â ÆÄÀÏ¿¡ + SSI Áö½Ã¾î°¡ ÀÖ´ÂÁö ¿©ºÎ¿Í °ü°è¾øÀÌ ¸ðµç SSI ÆÄÀÏÀ» ºÐ¼®ÇØ¾ß + ÇÑ´Ù. Á¶±Ý ºÎÇÏ°¡ ´ÃÁö¸¸, ¼­¹ö¸¦ ¿©·¯ »ç¶÷ÀÌ °°ÀÌ »ç¿ëÇÏ´Â + ȯ°æ¿¡¼­´Â ½É°¢ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç, SSI ÆÄÀÏÀº ÀϹÝÀûÀÎ CGI ½ºÅ©¸³Æ®¿Í µ¿ÀÏÇÑ À§ÇèÀ» + °¡Áø´Ù. SSI ÆÄÀÏ¿¡¼­ "exec cmd"¸¦ »ç¿ëÇϸé httpd.conf¿¡¼­ + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϵµ·Ï ¼³Á¤ÇÑ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑÀ¸·Î CGI + ½ºÅ©¸³Æ®³ª ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀåÁ¡À» È°¿ëÇϸ鼭 SSI ÆÄÀÏÀÇ º¸¾ÈÀ» Çâ»ó½ÃÅ°´Â ¹æ¹ýÀÌ + ÀÖ´Ù.

    + +

    SSI ÆÄÀÏÀÌ °¡Á®¿Ã ¼ö ÀÖ´Â ÇÇÇظ¦ °Ý¸®ÇϱâÀ§ÇØ ¼­¹ö°ü¸®ÀÚ´Â + ÀϹÝÀûÀÎ CGI Àý¿¡¼­ ¼³¸íÇÏ´Â ¹æ¹ýÀ¸·Î + suexec¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù

    + +

    .htmlÀ̳ª .htm È®ÀåÀÚ¸¦ SSI ÆÄÀÏ·Î »ç¿ëÇÏ´Â °ÍÀº À§ÇèÇÏ´Ù. + ƯÈ÷ ¿©·¯ »ç¶÷ÀÌ °øÀ¯Çϰųª Åë½Å·®ÀÌ ¸¹Àº ¼­¹ö ȯ°æ¿¡¼­ + À§ÇèÇÏ´Ù. SSI ÆÄÀÏÀº ÀϹÝÀûÀ¸·Î ¸¹ÀÌ »ç¿ëÇÏ´Â .shtml °°Àº + º°µµÀÇ È®ÀåÀÚ¸¦ °¡Á®¾ß ÇÑ´Ù. ±×·¯¸é ¼­¹ö ºÎÇϸ¦ ÃÖ¼ÒÈ­ÇÏ°í + À§Çè¿ä¼Ò¸¦ ½±°Ô °ü¸®ÇÒ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ ¹æ¹ýÀº SSI ÆäÀÌÁö°¡ ½ºÅ©¸³Æ®³ª ÇÁ·Î±×·¥À» ½ÇÇàÇÏÁö + ¸øÇϵµ·Ï ¸¸µå´Â °ÍÀÌ´Ù. Options Áö½Ã¾î¿¡¼­ Includes + ´ë½Å IncludesNOEXEC¸¦ »ç¿ëÇÑ´Ù. ±×·¡µµ ½ºÅ©¸³Æ®°¡ + ScriptAlias Áö½Ã¾î·Î + ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ ÀÖ´Ù¸é <--#include virtual="..." -->¸¦ + »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÒ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó.

    + +
    + +
    + + ÀϹÝÀûÀÎ CGI + +

    °á±¹ ´ç½ÅÀº Ç×»ó CGI ½ºÅ©¸³Æ®/ÇÁ·Î±×·¥ÀÇ ÀúÀÚ¸¦ ½Å·ÚÇØ¾ß + ÇÏ°í, °íÀÇ°Ç ½Ç¼öÀÌ°Ç CGIÀÇ ÀáÀçÀûÀÎ º¸¾È»ó ÇãÁ¡À» ¹ß°ßÇÒ + ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ±âº»ÀûÀ¸·Î CGI ½ºÅ©¸³Æ®´Â À¥¼­¹ö »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ½Ã½ºÅÛ¿¡¼­ ¾î¶² ¸í·É¾î¶óµµ ½ÇÇàÇÒ ¼ö Àֱ⶧¹®¿¡ + ÁÖÀÇÀÖ°Ô È®ÀÎÇÏÁö ¾ÊÀ¸¸é ¸Å¿ì À§ÇèÇÏ´Ù.

    + +

    ¸ðµç CGI ½ºÅ©¸³Æ®°¡ °°Àº »ç¿ëÀÚ·Î ½ÇÇàµÇ±â¶§¹®¿¡ ´Ù¸¥ + ½ºÅ©¸³Æ®¿Í (°íÀÇ°Ç ½Ç¼öÀÌ°Ç) Ãæµ¹ÇÒ °¡´É¼ºÀÌ ÀÖ´Ù. ¿¹¸¦ + µé¾î, »ç¿ëÀÚ A´Â »ç¿ëÀÚ B¸¦ ¸Å¿ì ½È¾îÇÏ¿©, »ç¿ëÀÚ BÀÇ CGI + µ¥ÀÌÅͺ£À̽º¸¦ Áö¿ö¹ö¸®´Â ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡ + 1.2 ¹öÀüºÎÅÍ Æ÷ÇԵǾú°í ¾ÆÆÄÄ¡ ¼­¹ö¿¡¼­ Ưº°ÇÑ ÈÅ(hook)À¸·Î + µ¿ÀÛÇÏ´Â suEXEC´Â ½ºÅ©¸³Æ®¸¦ + ´Ù¸¥ »ç¿ëÀÚ·Î ½ÇÇàÇÏ´Â ¹æ¹ýÁß Çϳª´Ù. ´Ù¸¥ ´ëÁßÀûÀÎ ¹æ¹ý¿¡´Â + CGIWrapÀÌ ÀÖ´Ù.

    + +
    + +
    + + ScriptAliasÇÏÁö ¾ÊÀº CGI + +

    ´ÙÀ½ Á¶°ÇÀ» ¸¸Á·ÇÒ¶§¸¸ »ç¿ëÀÚ°¡ ¾î¶² µð·ºÅ丮¿¡¼­¶óµµ + CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    • ´ç½ÅÀº °íÀÇ°Ç ½Ç¼öÀÌ°Ç »ç¿ëÀÚ°¡ ½Ã½ºÅÛÀ» °ø°Ý¿¡ ³ëÃâ½ÃÅ°´Â + ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÏÁö ¾Ê´Â´Ù°í ¹Ï´Â´Ù.
    • +
    • ½Ã½ºÅÛÀÇ ´Ù¸¥ ºÎºÐÀÇ º¸¾ÈÀÌ ¾àÇؼ­, ÀáÀçÀûÀÎ ÇãÁ¡À» + Çϳª ´õ ¸¸µé¾îµµ ³ªºüÁú °ÍÀÌ ¾ø´Ù°í »ý°¢ÇÏ´Â °æ¿ì.
    • +
    • »ç¿ëÀÚ°¡ ¾ø°í, ¾Æ¸¶ ¾Æ¹«µµ ¼­¹ö¸¦ ¹æ¹®ÇÏÁö¾Ê´Â °æ¿ì.
    • +
    + +
    + +
    + + ScriptAliasÇÑ CGI + +

    ƯÁ¤ µð·ºÅ丮¿¡¼­¸¸ CGI¸¦ ½ÇÇàÇÒ ¼ö ÀÖµµ·Ï Á¦ÇÑÇÏ¸é °ü¸®ÀÚ´Â + ÀÌµé µð·ºÅ丮¸¦ ÅëÁ¦ÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì´Â scriptaliasÇÏÁö + ¾ÊÀº CGIº¸´Ù È®½ÇÈ÷ ¾ÈÀüÇÏ´Ù. ´Ü, ½Å·ÚÇÏ´Â »ç¿ëÀÚ¸¸ µð·ºÅ丮¿¡ + Á¢±ÙÇÒ ¼ö ÀÖ°í, °ü¸®ÀÚ°¡ »õ·Î¿î CGI ½ºÅ©¸³Æ®/ÇÁ·Î±×·¥ÀÇ + ÀáÀçÀûÀÎ º¸¾È»ó ÇãÁ¡À» °Ë»çÇÒ ¿ëÀÌ°¡ ÀÖ´Ù¸é.

    + +

    ´ëºÎºÐÀÇ »çÀÌÆ®´Â scriptaliasÇÏÁö ¾ÊÀº CGI ¹æ½Ä ´ë½Å + ÀÌ ¹æ½ÄÀ» »ç¿ëÇÑ´Ù.

    + +
    + +
    + + µ¿Àû ³»¿ëÀ» »ý¼ºÇÏ´Â ´Ù¸¥ ¹æ¹ý + +

    + mod_php, mod_perl, mod_tcl, mod_python °°ÀÌ ¼­¹öÀÇ ÀϺηΠ+ µ¿ÀÛÇÏ´Â ÀÓº£µðµå ½ºÅ©¸³Æ®´Â ¼­¹ö¿Í °°Àº »ç¿ëÀÚ·Î (User Áö½Ã¾î Âü°í) ½ÇÇàµÇ±â¶§¹®¿¡, + ½ºÅ©¸³Æ® ¿£ÁøÀÌ ½ÇÇàÇÏ´Â ½ºÅ©¸³Æ®´Â ÀáÀçÀûÀ¸·Î ¼­¹ö »ç¿ëÀÚ°¡ + Á¢±ÙÇÒ ¼ö ÀÖ´Â ¸ðµç °Í¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù. ¾î¶² ½ºÅ©¸³Æ® ¿£ÁøÀº + ¾î´ÀÁ¤µµ Á¦ÇÑÀ» ÇÏÁö¸¸, ¾ÈÀüÇÏ´Ù°í °¡Á¤ÇÏÁö ¾Ê´Â °ÍÀÌ ÁÁ´Ù.

    + +
    + +
    + + ½Ã½ºÅÛ ¼³Á¤ º¸È£Çϱâ + +

    Á¤¸»·Î ¾ÈÀüÇÑ ¼­¹ö¸¦ ¿î¿µÇÏ·Á¸é »ç¿ëÀÚ°¡ + .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ¿© ´ç½ÅÀÌ ¼³Á¤ÇÑ º¸¾È±â´ÉÀ» + º¯°æÇÏ±æ ¹Ù¶óÁö ¾ÊÀ» °ÍÀÌ´Ù. ±×·¯±âÀ§ÇØ ´ÙÀ½°ú °°Àº ¹æ¹ýÀÌ + ÀÖ´Ù.

    + +

    ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½À» Ãß°¡ÇÑ´Ù

    + + + <Directory />
    + AllowOverride None
    + </Directory> +
    + +

    ±×·¯¸é »ç¿ë°¡´ÉÇϵµ·Ï ¸í½ÃÀûÀ¸·Î Çã¿ëÇÑ µð·ºÅ丮¸¦ Á¦¿ÜÇÏ°í´Â + .htaccess ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +
    + +
    + + ±âº»ÀûÀ¸·Î ¼­¹ö¿¡ ÀÖ´Â ÆÄÀÏ º¸È£Çϱâ + +

    »ç¶÷µéÀº Á¾Á¾ ¾ÆÆÄÄ¡ÀÇ ±âº» Á¢±Ù¿¡ ´ëÇØ À߸ø ¾Ë°íÀÖ´Ù. + Áï, ¼­¹ö°¡ ÀϹÝÀûÀÎ URL ´ëÀÀ ±ÔÄ¢À» »ç¿ëÇÏ¿© ÆÄÀÏÀ» ãÀ» + ¼ö ÀÖ´Ù¸é, Ưº°È÷ Á¶Ä¡¸¦ ÇÏÁö ¾Ê´ÂÇÑ Å¬¶óÀ̾ðÆ®¿¡°Ô ÆÄÀÏÀÌ + ¼­ºñ½ºµÉ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ¾Æ·¡¿Í °°Àº °æ¿ì:

    + + + # cd /; ln -s / public_html
    + http://localhost/~root/ ¿¡ Á¢±ÙÇÑ´Ù +
    + +

    ±×·¯¸é Ŭ¶óÀ̾ðÆ®´Â Àüü ÆÄÀϽýºÅÛÀ» µ¹¾Æ´Ù´Ò ¼ö ÀÖ´Ù. + À̸¦ ¸·±âÀ§ÇØ ¼­¹ö¼³Á¤¿¡¼­ ´ÙÀ½°ú °°Àº Á¶Ä¡¸¦ ÇÑ´Ù:

    + + + <Directory />
    + Order Deny,Allow
    + Deny from all
    + </Directory> +
    + +

    ±×·¯¸é ÆÄÀϽýºÅÛ À§Ä¡¿¡ ´ëÇØ ±âº» Á¢±ÙÀÌ °ÅºÎµÈ´Ù. + ¿øÇÏ´Â ¿µ¿ª¿¡ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ´ÙÀ½°ú °°Àº Directory ºí·ÏÀ» Ãß°¡ÇÑ´Ù.

    + + + <Directory /usr/users/*/public_html>
    + Order Deny,Allow
    + Allow from all
    + </Directory>
    + <Directory /usr/local/httpd>
    + Order Deny,Allow
    + Allow from all
    + </Directory> +
    + +

    Location°ú Directory Áö½Ã¾î¸¦ °°ÀÌ »ç¿ëÇÏ´Â + °æ¿ì Ưº°È÷ ÁÖÀǸ¦ ±â¿ï¿©¶ó. ¿¹¸¦ µé¾î, <Directory + />°¡ Á¢±ÙÀ» °ÅºÎÇÏ´õ¶óµµ <Location + /> Áö½Ã¾î°¡ À̸¦ ¹«½ÃÇÒ ¼ö ÀÖ´Ù

    + +

    UserDir Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â °æ¿ì¿¡µµ ÁÖÀÇÇ϶ó. Áö½Ã¾î¸¦ "./" °°ÀÌ ¼³Á¤Çϸé + root »ç¿ëÀÚ¿¡ ´ëÇØ ¹Ù·Î À§ÀÇ °æ¿ì¿Í °°Àº ¹®Á¦°¡ ¹ß»ýÇÑ´Ù. + ¾ÆÆÄÄ¡ 1.3 ÀÌ»óÀ» »ç¿ëÇÑ´Ù¸é ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡ ¾Æ·¡ ÁÙÀ» Ãß°¡Çϱæ + °­·ÂÈ÷ ±ÇÇÑ´Ù:

    + + + UserDir disabled root + + +
    + +
    + + ·Î±× »ìÆ캸±â + +

    ½ÇÁ¦·Î ¼­¹ö¿¡¼­ ¹«½¼ ÀÏÀÌ À־°í ÀÖ´ÂÁö ¾Ë·Á¸é ·Î±×ÆÄÀÏÀ» »ìÆìºÁ¾ß ÇÑ´Ù. ·Î±×ÆÄÀÏÀº + ÀÌ¹Ì ÀϾ Àϸ¸À» º¸°íÇÏÁö¸¸, ¼­¹ö¿¡ ¾î¶² °ø°ÝÀÌ ÀÖ¾ú´ÂÁö + ¾Ë·ÁÁÖ°í ÇöÀç ÇÊ¿äÇÑ ¸¸Å­ ¾ÈÀüÇÑÁö È®ÀÎÇÏ°Ô ÇØÁØ´Ù.

    + +

    ¿©·¯°¡Áö ¿¹:

    + + + grep -c "/jsp/source.jsp?/jsp/ /jsp/source.jsp??" access_log
    + grep "client denied" error_log | tail -n 10 +
    + +

    ù¹ø° ¿¹´Â À߸øµÈ + Source.JSP ¿äûÀ¸·Î ¼­¹öÁ¤º¸¸¦ ¾Ë¾Æ³¾ ¼ö ÀÖ´Â TomcatÀÇ + Ãë¾àÁ¡¸¦ ÀÌ¿ëÇÏ·Á´Â °ø°Ý Ƚ¼ö¸¦ ¾Ë·ÁÁÖ°í, µÎ¹ø° ¿¹´Â + Á¢±ÙÀÌ °ÅºÎµÈ Ãֱ٠Ŭ¶óÀ̾ðÆ® 10°³¸¦ ´ÙÀ½°ú °°ÀÌ º¸¿©ÁØ´Ù:

    + + + [Thu Jul 11 17:18:39 2002] [error] [client foo.bar.com] client denied + by server configuration: /usr/local/apache/htdocs/.htpasswd + + +

    Àß ¾Ë µíÀÌ ·Î±×ÆÄÀÏÀº ÀÌ¹Ì ¹ß»ýÇÑ »ç°Ç¸¸À» º¸°íÇÑ´Ù. + ±×·¡¼­ Ŭ¶óÀ̾ðÆ®°¡ .htpasswd ÆÄÀÏ¿¡ Á¢±ÙÇÒ + ¼ö ÀÖ¾ú´Ù¸é Á¢±Ù ·Î±×¿¡ + ´ÙÀ½°ú °°Àº ±â·ÏÀÌ ³²À» °ÍÀÌ´Ù:

    + + + foo.bar.com - - [12/Jul/2002:01:59:13 +0200] "GET /.htpasswd HTTP/1.1" + + +

    Áï, ´ç½ÅÀº ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ ´ÙÀ½ ºÎºÐÀ» ÁÖ¼®Ã³¸®ÇßÀ» + °ÍÀÌ´Ù:

    + + + <Files ~ "^\.ht">
    + Order allow,deny
    + Deny from all
    + <Files> +
    + +
    + +
    diff --git a/trunk/docs/manual/misc/security_tips.xml.meta b/trunk/docs/manual/misc/security_tips.xml.meta new file mode 100644 index 0000000000..f0363b5577 --- /dev/null +++ b/trunk/docs/manual/misc/security_tips.xml.meta @@ -0,0 +1,12 @@ + + + + security_tips + /misc/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/allmodules.xml b/trunk/docs/manual/mod/allmodules.xml new file mode 100644 index 0000000000..b79707c619 --- /dev/null +++ b/trunk/docs/manual/mod/allmodules.xml @@ -0,0 +1,87 @@ + + + + core.xml + mod_actions.xml + mod_alias.xml + mod_asis.xml + mod_auth_basic.xml + mod_auth_digest.xml + mod_authn_alias.xml + mod_authn_anon.xml + mod_authn_dbm.xml + mod_authn_default.xml + mod_authn_file.xml + mod_authnz_ldap.xml + mod_authz_dbm.xml + mod_authz_default.xml + mod_authz_groupfile.xml + mod_authz_host.xml + mod_authz_owner.xml + mod_authz_user.xml + mod_autoindex.xml + mod_cache.xml + mod_cern_meta.xml + mod_cgi.xml + mod_cgid.xml + mod_charset_lite.xml + mod_dav.xml + mod_dav_fs.xml + mod_dav_lock.xml + mod_dbd.xml + mod_deflate.xml + mod_dir.xml + mod_disk_cache.xml + mod_dumpio.xml + mod_echo.xml + mod_env.xml + mod_example.xml + mod_expires.xml + mod_ext_filter.xml + mod_file_cache.xml + mod_filter.xml + mod_headers.xml + mod_ident.xml + mod_imagemap.xml + mod_include.xml + mod_info.xml + mod_isapi.xml + mod_ldap.xml + mod_log_config.xml + mod_log_forensic.xml + mod_logio.xml + mod_mem_cache.xml + mod_mime.xml + mod_mime_magic.xml + mod_negotiation.xml + mod_nw_ssl.xml + mod_proxy.xml + mod_proxy_ajp.xml + mod_proxy_balancer.xml + mod_proxy_connect.xml + mod_proxy_ftp.xml + mod_proxy_http.xml + mod_rewrite.xml + mod_setenvif.xml + mod_so.xml + mod_speling.xml + mod_ssl.xml + mod_status.xml + mod_suexec.xml + mod_unique_id.xml + mod_userdir.xml + mod_usertrack.xml + mod_version.xml + mod_vhost_alias.xml + beos.xml + mpm_common.xml + event.xml + leader.xml + mpm_netware.xml + mpmt_os2.xml + perchild.xml + prefork.xml + threadpool.xml + mpm_winnt.xml + worker.xml + diff --git a/trunk/docs/manual/mod/allmodules.xml.de b/trunk/docs/manual/mod/allmodules.xml.de new file mode 100644 index 0000000000..a554febca8 --- /dev/null +++ b/trunk/docs/manual/mod/allmodules.xml.de @@ -0,0 +1,87 @@ + + + + core.xml.de + mod_actions.xml.de + mod_alias.xml + mod_asis.xml + mod_auth_basic.xml + mod_auth_digest.xml + mod_authn_alias.xml + mod_authn_anon.xml + mod_authn_dbm.xml + mod_authn_default.xml + mod_authn_file.xml + mod_authnz_ldap.xml + mod_authz_dbm.xml + mod_authz_default.xml + mod_authz_groupfile.xml + mod_authz_host.xml + mod_authz_owner.xml + mod_authz_user.xml + mod_autoindex.xml + mod_cache.xml + mod_cern_meta.xml + mod_cgi.xml + mod_cgid.xml + mod_charset_lite.xml + mod_dav.xml + mod_dav_fs.xml + mod_dav_lock.xml + mod_dbd.xml + mod_deflate.xml + mod_dir.xml + mod_disk_cache.xml + mod_dumpio.xml + mod_echo.xml + mod_env.xml + mod_example.xml + mod_expires.xml + mod_ext_filter.xml + mod_file_cache.xml + mod_filter.xml + mod_headers.xml + mod_ident.xml + mod_imagemap.xml + mod_include.xml + mod_info.xml + mod_isapi.xml + mod_ldap.xml + mod_log_config.xml + mod_log_forensic.xml + mod_logio.xml + mod_mem_cache.xml + mod_mime.xml + mod_mime_magic.xml + mod_negotiation.xml + mod_nw_ssl.xml + mod_proxy.xml + mod_proxy_ajp.xml + mod_proxy_balancer.xml + mod_proxy_connect.xml + mod_proxy_ftp.xml + mod_proxy_http.xml + mod_rewrite.xml + mod_setenvif.xml + mod_so.xml + mod_speling.xml + mod_ssl.xml + mod_status.xml + mod_suexec.xml + mod_unique_id.xml + mod_userdir.xml + mod_usertrack.xml + mod_version.xml + mod_vhost_alias.xml + beos.xml.de + mpm_common.xml.de + event.xml + leader.xml.de + mpm_netware.xml + mpmt_os2.xml + perchild.xml + prefork.xml.de + threadpool.xml + mpm_winnt.xml.de + worker.xml.de + diff --git a/trunk/docs/manual/mod/allmodules.xml.es b/trunk/docs/manual/mod/allmodules.xml.es new file mode 100644 index 0000000000..64523e6c9e --- /dev/null +++ b/trunk/docs/manual/mod/allmodules.xml.es @@ -0,0 +1,87 @@ + + + + core.xml + mod_actions.xml + mod_alias.xml + mod_asis.xml + mod_auth_basic.xml + mod_auth_digest.xml + mod_authn_alias.xml + mod_authn_anon.xml + mod_authn_dbm.xml + mod_authn_default.xml + mod_authn_file.xml + mod_authnz_ldap.xml + mod_authz_dbm.xml + mod_authz_default.xml + mod_authz_groupfile.xml + mod_authz_host.xml + mod_authz_owner.xml + mod_authz_user.xml + mod_autoindex.xml + mod_cache.xml + mod_cern_meta.xml + mod_cgi.xml + mod_cgid.xml + mod_charset_lite.xml + mod_dav.xml + mod_dav_fs.xml + mod_dav_lock.xml + mod_dbd.xml + mod_deflate.xml + mod_dir.xml + mod_disk_cache.xml + mod_dumpio.xml + mod_echo.xml + mod_env.xml + mod_example.xml + mod_expires.xml + mod_ext_filter.xml + mod_file_cache.xml + mod_filter.xml + mod_headers.xml + mod_ident.xml + mod_imagemap.xml + mod_include.xml + mod_info.xml + mod_isapi.xml + mod_ldap.xml + mod_log_config.xml + mod_log_forensic.xml + mod_logio.xml + mod_mem_cache.xml + mod_mime.xml + mod_mime_magic.xml + mod_negotiation.xml + mod_nw_ssl.xml + mod_proxy.xml + mod_proxy_ajp.xml + mod_proxy_balancer.xml + mod_proxy_connect.xml + mod_proxy_ftp.xml + mod_proxy_http.xml + mod_rewrite.xml + mod_setenvif.xml + mod_so.xml + mod_speling.xml + mod_ssl.xml + mod_status.xml + mod_suexec.xml + mod_unique_id.xml + mod_userdir.xml + mod_usertrack.xml + mod_version.xml + mod_vhost_alias.xml + beos.xml.es + mpm_common.xml + event.xml + leader.xml + mpm_netware.xml + mpmt_os2.xml + perchild.xml + prefork.xml + threadpool.xml + mpm_winnt.xml + worker.xml + diff --git a/trunk/docs/manual/mod/allmodules.xml.ja b/trunk/docs/manual/mod/allmodules.xml.ja new file mode 100644 index 0000000000..9b5096284b --- /dev/null +++ b/trunk/docs/manual/mod/allmodules.xml.ja @@ -0,0 +1,87 @@ + + + + core.xml.ja + mod_actions.xml.ja + mod_alias.xml.ja + mod_asis.xml.ja + mod_auth_basic.xml.ja + mod_auth_digest.xml + mod_authn_alias.xml + mod_authn_anon.xml.ja + mod_authn_dbm.xml.ja + mod_authn_default.xml.ja + mod_authn_file.xml.ja + mod_authnz_ldap.xml + mod_authz_dbm.xml + mod_authz_default.xml.ja + mod_authz_groupfile.xml.ja + mod_authz_host.xml.ja + mod_authz_owner.xml.ja + mod_authz_user.xml.ja + mod_autoindex.xml.ja + mod_cache.xml.ja + mod_cern_meta.xml + mod_cgi.xml.ja + mod_cgid.xml.ja + mod_charset_lite.xml + mod_dav.xml.ja + mod_dav_fs.xml.ja + mod_dav_lock.xml.ja + mod_dbd.xml + mod_deflate.xml.ja + mod_dir.xml.ja + mod_disk_cache.xml.ja + mod_dumpio.xml.ja + mod_echo.xml.ja + mod_env.xml.ja + mod_example.xml + mod_expires.xml.ja + mod_ext_filter.xml.ja + mod_file_cache.xml + mod_filter.xml + mod_headers.xml.ja + mod_ident.xml + mod_imagemap.xml + mod_include.xml.ja + mod_info.xml.ja + mod_isapi.xml + mod_ldap.xml + mod_log_config.xml.ja + mod_log_forensic.xml.ja + mod_logio.xml.ja + mod_mem_cache.xml.ja + mod_mime.xml.ja + mod_mime_magic.xml + mod_negotiation.xml.ja + mod_nw_ssl.xml + mod_proxy.xml.ja + mod_proxy_ajp.xml.ja + mod_proxy_balancer.xml.ja + mod_proxy_connect.xml + mod_proxy_ftp.xml + mod_proxy_http.xml + mod_rewrite.xml + mod_setenvif.xml.ja + mod_so.xml.ja + mod_speling.xml.ja + mod_ssl.xml + mod_status.xml.ja + mod_suexec.xml.ja + mod_unique_id.xml.ja + mod_userdir.xml.ja + mod_usertrack.xml + mod_version.xml.ja + mod_vhost_alias.xml + beos.xml + mpm_common.xml.ja + event.xml + leader.xml + mpm_netware.xml + mpmt_os2.xml + perchild.xml + prefork.xml.ja + threadpool.xml + mpm_winnt.xml.ja + worker.xml.ja + diff --git a/trunk/docs/manual/mod/allmodules.xml.ko b/trunk/docs/manual/mod/allmodules.xml.ko new file mode 100644 index 0000000000..7b559a5faa --- /dev/null +++ b/trunk/docs/manual/mod/allmodules.xml.ko @@ -0,0 +1,87 @@ + + + + core.xml + mod_actions.xml.ko + mod_alias.xml.ko + mod_asis.xml.ko + mod_auth_basic.xml.ko + mod_auth_digest.xml.ko + mod_authn_alias.xml + mod_authn_anon.xml.ko + mod_authn_dbm.xml.ko + mod_authn_default.xml.ko + mod_authn_file.xml.ko + mod_authnz_ldap.xml + mod_authz_dbm.xml.ko + mod_authz_default.xml.ko + mod_authz_groupfile.xml.ko + mod_authz_host.xml.ko + mod_authz_owner.xml.ko + mod_authz_user.xml.ko + mod_autoindex.xml.ko + mod_cache.xml.ko + mod_cern_meta.xml.ko + mod_cgi.xml.ko + mod_cgid.xml.ko + mod_charset_lite.xml.ko + mod_dav.xml.ko + mod_dav_fs.xml.ko + mod_dav_lock.xml + mod_dbd.xml + mod_deflate.xml.ko + mod_dir.xml.ko + mod_disk_cache.xml.ko + mod_dumpio.xml + mod_echo.xml.ko + mod_env.xml.ko + mod_example.xml.ko + mod_expires.xml.ko + mod_ext_filter.xml.ko + mod_file_cache.xml.ko + mod_filter.xml + mod_headers.xml.ko + mod_ident.xml.ko + mod_imagemap.xml.ko + mod_include.xml + mod_info.xml.ko + mod_isapi.xml.ko + mod_ldap.xml + mod_log_config.xml.ko + mod_log_forensic.xml + mod_logio.xml.ko + mod_mem_cache.xml.ko + mod_mime.xml + mod_mime_magic.xml + mod_negotiation.xml + mod_nw_ssl.xml + mod_proxy.xml + mod_proxy_ajp.xml + mod_proxy_balancer.xml + mod_proxy_connect.xml + mod_proxy_ftp.xml + mod_proxy_http.xml + mod_rewrite.xml + mod_setenvif.xml.ko + mod_so.xml.ko + mod_speling.xml.ko + mod_ssl.xml + mod_status.xml.ko + mod_suexec.xml.ko + mod_unique_id.xml.ko + mod_userdir.xml.ko + mod_usertrack.xml + mod_version.xml.ko + mod_vhost_alias.xml + beos.xml.ko + mpm_common.xml + event.xml + leader.xml.ko + mpm_netware.xml + mpmt_os2.xml + perchild.xml + prefork.xml + threadpool.xml + mpm_winnt.xml + worker.xml + diff --git a/trunk/docs/manual/mod/beos.html b/trunk/docs/manual/mod/beos.html new file mode 100644 index 0000000000..3d72b3f9fe --- /dev/null +++ b/trunk/docs/manual/mod/beos.html @@ -0,0 +1,15 @@ +URI: beos.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: beos.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: beos.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: beos.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/beos.html.de b/trunk/docs/manual/mod/beos.html.de new file mode 100644 index 0000000000..fe7379656a --- /dev/null +++ b/trunk/docs/manual/mod/beos.html.de @@ -0,0 +1,108 @@ + + + +beos - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-MPM beos

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ko 

    +
    + + + +
    Beschreibung:Dieses Multi-Processing-Modul ist für BeOS + optimiert.
    Status:MPM
    Modulbezeichner:mpm_beos_module
    Quelltext-Datei:beos.c
    +

    Zusammenfassung

    + +

    Dieses Multi-Processing-Modul (MPM) ist das Standardmodul für BeOS. + Es benutzt einen einzelnen Steuerprozess welcher Threads für die + Bedienung der Anfragen erzeugt.

    +
    + + +
    top
    +

    MaxRequestsPerThread-Direktive

    + + + + + + + +
    Beschreibung:Die maximale Anzahl von Anfragen, die ein einzelner Thread + während seiner Lebensdauer bedient.
    Syntax:MaxRequestsPerThread Anzahl
    Voreinstellung:MaxRequestsPerThread 0
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos
    +

    Die Direktive MaxRequestsPerThread legt die + Anzahl der Anfragen fest, die ein einzelner Server-Thread bedient. Nach + Erreichen der angegebenen Anzahl von Anfragen wird der Thread beendet. + Wird für MaxRequestsPerThread der Wert + 0 angegeben, wird der Thread niemals beendet.

    + +

    Das Setzen von MaxRequestsPerThread auf einen + Wert ungleich null hat zwei Vorteile:

    + +
      +
    • Die Menge des von einem Thread benötigten Speicherplatzes + bei (unvorhergesehenen) Speicherproblemen kann begrenzt werden;
    • + +
    • Threads mit begrenzter Lebensdauer reduzieren die Anzahl + der Threads bei reduzierter Serverlast.
    • +
    + +

    Hinweis:

    +

    Bei KeepAlive-Anfragen wird nur die + erste Anfrage auf das Maximum angerechnet. Das führt dazu, dass + die Anzahl der Verbindungen + pro Thread reduziert wird.

    +
    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/beos.html.en b/trunk/docs/manual/mod/beos.html.en new file mode 100644 index 0000000000..21d442bf82 --- /dev/null +++ b/trunk/docs/manual/mod/beos.html.en @@ -0,0 +1,106 @@ + + + +beos - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM beos

    +
    +

    Available Languages:  de  | + en  | + es  | + ko 

    +
    + + + +
    Description:This Multi-Processing Module is optimized for BeOS.
    Status:MPM
    Module Identifier:mpm_beos_module
    Source File:beos.c
    +

    Summary

    + +

    This Multi-Processing Module (MPM) is the default for BeOS. It uses + a single control process which creates threads to handle requests.

    +
    + + +
    top
    +

    MaxRequestsPerThread Directive

    + + + + + + + +
    Description:Limit on the number of requests that an individual thread +will handle during its life
    Syntax:MaxRequestsPerThread number
    Default:MaxRequestsPerThread 0
    Context:server config
    Status:MPM
    Module:beos
    +

    The MaxRequestsPerThread directive sets + the limit on the number of requests that an individual server thread + will handle. After MaxRequestsPerThread + requests, the thread will die. If MaxRequestsPerThread is 0, then the thread + will never expire.

    + +

    Setting MaxRequestsPerThread to a + non-zero limit has two beneficial effects:

    + +
      +
    • it limits the amount of memory that a thread can consume + by (accidental) memory leakage;
    • + +
    • by giving threads a finite lifetime, it helps reduce + the number of threads when the server load reduces.
    • +
    + +

    Note:

    +

    For KeepAlive requests, only + the first request is counted towards this limit. In effect, it + changes the behavior to limit the number of connections + per thread.

    +
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/beos.html.es b/trunk/docs/manual/mod/beos.html.es new file mode 100644 index 0000000000..b5129d5067 --- /dev/null +++ b/trunk/docs/manual/mod/beos.html.es @@ -0,0 +1,111 @@ + + + +beos - Servidor HTTP Apache + + + + + + +
    <-
    + +
    +

    MPM de Apache beos

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ko 

    +
    + + + +
    Descripción:Este módulo de muiltiprocesamiento está +optimizado para BeOS.
    Estado:MPM
    Identificador de Módulos:mpm_beos_module
    Fichero de Código Fuente:beos.c
    +

    Resumen de contenidos

    + +

    Este módulo de muiltiprocesamiento (MMP) + es el que usa por defecto para BeOS. Usa un + único proceso de control que crea hebras para atender las + peticiones.

    +
    + + +
    top
    +

    MaxRequestsPerThread Directiva

    + + + + + + + +
    Descripción:Limita el número de peticiones que una hebra (thread) puede +atender durante su vida
    Sintaxis:MaxRequestsPerThread number
    Valor por defecto:MaxRequestsPerThread 0
    Contexto:server config
    Estado:MPM
    Módulo:beos
    +

    La directiva MaxRequestsPerThread fija + el número máximo de peticiones que una hebra del + servidor puede atender durante su vida. Despues de atender + MaxRequestsPerThread peticiones, la hebra + termina. Si el límite fijado en MaxRequestsPerThread es 0, entonces la + hebra puede atender peticiones indefinidamente.

    + +

    Fijar la directiva MaxRequestsPerThread + a un límite distinto de cero ofrece dos benefcios + fundamentales:

    + +
      +
    • limita la cantidad de memoria que puede consumir una hebra + si hay una filtración (accidental) de memoria;
    • + +
    • poniendo un límite a la vida de las hebras, se ayuda a + reducir el número de hebras cuando se reduce la carga de + trabajo en el servidor.
    • +
    + +

    Nota:

    Para peticiones KeepAlive, solo la primera + petición se tiene en cuenta para este límite. De hecho, en este + caso el límite se impone sobre el número máximo + de conexiones por hebra.

    +
    + +
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/beos.html.ko.euc-kr b/trunk/docs/manual/mod/beos.html.ko.euc-kr new file mode 100644 index 0000000000..e965386a45 --- /dev/null +++ b/trunk/docs/manual/mod/beos.html.ko.euc-kr @@ -0,0 +1,103 @@ + + + +beos - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ MPM beos

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ko 

    +
    + + + +
    ¼³¸í:BeOS¿¡ ÃÖÀûÈ­µÈ ´ÙÁßó¸® ¸ðµâ.
    »óÅÂ:MPM
    ¸ðµâ¸í:mpm_beos_module
    ¼Ò½ºÆÄÀÏ:beos.c
    +

    ¿ä¾à

    + +

    ÀÌ ´ÙÁßó¸® ¸ðµâ(MPM)Àº BeOS¿¡¼­ ±âº»ÀûÀ¸·Î »ç¿ëÇÑ´Ù. + ÇÑ Á¶Àý ÇÁ·Î¼¼½º°¡ ¿äûÀ» ó¸®ÇÒ ¾²·¹µåµéÀ» ¸¸µç´Ù.

    +
    + + +
    top
    +

    MaxRequestsPerThread Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÇÑ ¾²·¹µå°¡ ½ÇÇàÇÏ´Â µ¿¾È ó¸®ÇÒ ¿äû°³¼ö ÇÑ°è
    ¹®¹ý:MaxRequestsPerThread number
    ±âº»°ª:MaxRequestsPerThread 0
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:MPM
    ¸ðµâ:beos
    +

    MaxRequestsPerThread Áö½Ã¾î´Â + ÇÑ ¼­¹ö ¾²·¹µå°¡ ó¸®ÇÒ ¿äû°³¼ö¸¦ Á¦ÇÑÇÑ´Ù. + MaxRequestsPerThread°³ ¿äûÀ» ó¸®ÇÑÈÄ + ¾²·¹µå´Â Á״´Ù. MaxRequestsPerThread°¡ + 0À̸é Àý´ë·Î ¾²·¹µå¸¦ Á×ÀÌÁö ¾Ê´Â´Ù.

    + +

    MaxRequestsPerThread¸¦ 0ÀÌ ¾Æ´Ñ + °ªÀ¸·Î ¼³Á¤ÇÏ¸é µÎ°¡Áö ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • (¿ì¿¬È÷ ¹ß»ýÇÑ) ¸Þ¸ð¸® À¯Ãâ(memory leakage)¶§¹®¿¡ + ¾²·¹µå°¡ ³¶ºñÇÒ ¸Þ¸ð¸®·®À» Á¦ÇÑÇÑ´Ù;
    • + +
    • ¾²·¹µåÀÇ ¼ö¸íÀ» Á¦ÇÑÇÏ¿© ¼­¹ö ºÎÇÏ°¡ °¨¼ÒÇÒ¶§ + ¾²·¹µå ¼ö¸¦ ÁÙÀδÙ.
    • +
    + +

    ÁÖÀÇ:

    +

    KeepAlive ¿äûÀÇ + °æ¿ì ¿ÀÁ÷ ù¹ø° ¿äû¸¸À» ¼¾´Ù. ±×·¡¼­ ÀÌ Áö½Ã¾î´Â ¾²·¹µå´ç + ¿¬°á °³¼ö¸¦ Á¦ÇÑÇÏ°Ô µÈ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/beos.xml b/trunk/docs/manual/mod/beos.xml new file mode 100644 index 0000000000..beeaffef75 --- /dev/null +++ b/trunk/docs/manual/mod/beos.xml @@ -0,0 +1,102 @@ + + + + + + + + + +beos +This Multi-Processing Module is optimized for BeOS. +MPM +beos.c +mpm_beos_module + + +

    This Multi-Processing Module (MPM) is the default for BeOS. It uses + a single control process which creates threads to handle requests.

    +
    +Setting which addresses and ports Apache +uses + +User + +Group + +Listen + +ListenBacklog + +SendBufferSize + +StartThreads + +MinSpareThreads + +MaxSpareThreads + +MaxClients + +CoreDumpDirectory + +MaxMemFree + +PidFile + +ScoreBoardFile + + + +MaxRequestsPerThread +Limit on the number of requests that an individual thread +will handle during its life +MaxRequestsPerThread number +MaxRequestsPerThread 0 +server config + + +

    The MaxRequestsPerThread directive sets + the limit on the number of requests that an individual server thread + will handle. After MaxRequestsPerThread + requests, the thread will die. If MaxRequestsPerThread is 0, then the thread + will never expire.

    + +

    Setting MaxRequestsPerThread to a + non-zero limit has two beneficial effects:

    + +
      +
    • it limits the amount of memory that a thread can consume + by (accidental) memory leakage;
    • + +
    • by giving threads a finite lifetime, it helps reduce + the number of threads when the server load reduces.
    • +
    + + Note: +

    For KeepAlive requests, only + the first request is counted towards this limit. In effect, it + changes the behavior to limit the number of connections + per thread.

    +
    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/beos.xml.de b/trunk/docs/manual/mod/beos.xml.de new file mode 100644 index 0000000000..335332cc46 --- /dev/null +++ b/trunk/docs/manual/mod/beos.xml.de @@ -0,0 +1,102 @@ + + + + + + + + +beos +Dieses Multi-Processing-Modul ist für BeOS + optimiert. +MPM +beos.c +mpm_beos_module + + +

    Dieses Multi-Processing-Modul (MPM) ist das Standardmodul für BeOS. + Es benutzt einen einzelnen Steuerprozess welcher Threads für die + Bedienung der Anfragen erzeugt.

    +
    +Adress- und Port-Einstellungen + + +User + +Group + +Listen + +ListenBacklog + +SendBufferSize + +StartThreads + +MinSpareThreads + +MaxSpareThreads + +MaxClients + +CoreDumpDirectory + +MaxMemFree + +PidFile + +ScoreBoardFile + + + +MaxRequestsPerThread +Die maximale Anzahl von Anfragen, die ein einzelner Thread + während seiner Lebensdauer bedient. +MaxRequestsPerThread Anzahl +MaxRequestsPerThread 0 +server config + + +

    Die Direktive MaxRequestsPerThread legt die + Anzahl der Anfragen fest, die ein einzelner Server-Thread bedient. Nach + Erreichen der angegebenen Anzahl von Anfragen wird der Thread beendet. + Wird für MaxRequestsPerThread der Wert + 0 angegeben, wird der Thread niemals beendet.

    + +

    Das Setzen von MaxRequestsPerThread auf einen + Wert ungleich null hat zwei Vorteile:

    + +
      +
    • Die Menge des von einem Thread benötigten Speicherplatzes + bei (unvorhergesehenen) Speicherproblemen kann begrenzt werden;
    • + +
    • Threads mit begrenzter Lebensdauer reduzieren die Anzahl + der Threads bei reduzierter Serverlast.
    • +
    + + Hinweis: +

    Bei KeepAlive-Anfragen wird nur die + erste Anfrage auf das Maximum angerechnet. Das führt dazu, dass + die Anzahl der Verbindungen + pro Thread reduziert wird.

    +
    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/beos.xml.es b/trunk/docs/manual/mod/beos.xml.es new file mode 100644 index 0000000000..de5b6732ac --- /dev/null +++ b/trunk/docs/manual/mod/beos.xml.es @@ -0,0 +1,109 @@ + + + + + + + + + +beos +Este módulo de muiltiprocesamiento está +optimizado para BeOS. +MPM +beos.c +mpm_beos_module + + +

    Este módulo de muiltiprocesamiento (MMP) + es el que usa por defecto para BeOS. Usa un + único proceso de control que crea hebras para atender las + peticiones.

    +
    +Configurar las direcciones y los +puertos que usa Apache + +User + +Group + +Listen + +ListenBacklog + +SendBufferSize + +StartThreads + +MinSpareThreads + +MaxSpareThreads + +MaxClients + +CoreDumpDirectory + +MaxMemFree + +PidFile + +ScoreBoardFile + + + +MaxRequestsPerThread +Limita el número de peticiones que una hebra (thread) puede +atender durante su vida +MaxRequestsPerThread number +MaxRequestsPerThread 0 +server config + + +

    La directiva MaxRequestsPerThread fija + el número máximo de peticiones que una hebra del + servidor puede atender durante su vida. Despues de atender + MaxRequestsPerThread peticiones, la hebra + termina. Si el límite fijado en MaxRequestsPerThread es 0, entonces la + hebra puede atender peticiones indefinidamente.

    + +

    Fijar la directiva MaxRequestsPerThread + a un límite distinto de cero ofrece dos benefcios + fundamentales:

    + +
      +
    • limita la cantidad de memoria que puede consumir una hebra + si hay una filtración (accidental) de memoria;
    • + +
    • poniendo un límite a la vida de las hebras, se ayuda a + reducir el número de hebras cuando se reduce la carga de + trabajo en el servidor.
    • +
    + + Nota:

    Para peticiones KeepAlive, solo la primera + petición se tiene en cuenta para este límite. De hecho, en este + caso el límite se impone sobre el número máximo + de conexiones por hebra.

    +
    +
    +
    + +
    + + diff --git a/trunk/docs/manual/mod/beos.xml.ko b/trunk/docs/manual/mod/beos.xml.ko new file mode 100644 index 0000000000..b740c3e389 --- /dev/null +++ b/trunk/docs/manual/mod/beos.xml.ko @@ -0,0 +1,98 @@ + + + + + + + + + +beos +BeOS¿¡ ÃÖÀûÈ­µÈ ´ÙÁßó¸® ¸ðµâ. +MPM +beos.c +mpm_beos_module + + +

    ÀÌ ´ÙÁßó¸® ¸ðµâ(MPM)Àº BeOS¿¡¼­ ±âº»ÀûÀ¸·Î »ç¿ëÇÑ´Ù. + ÇÑ Á¶Àý ÇÁ·Î¼¼½º°¡ ¿äûÀ» ó¸®ÇÒ ¾²·¹µåµéÀ» ¸¸µç´Ù.

    +
    +¾ÆÆÄÄ¡°¡ »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ + +User + +Group + +Listen + +ListenBacklog + +SendBufferSize + +StartThreads + +MinSpareThreads + +MaxSpareThreads + +MaxClients + +CoreDumpDirectory + +MaxMemFree + +PidFile + +ScoreBoardFile + + + +MaxRequestsPerThread +ÇÑ ¾²·¹µå°¡ ½ÇÇàÇÏ´Â µ¿¾È ó¸®ÇÒ ¿äû°³¼ö ÇÑ°è +MaxRequestsPerThread number +MaxRequestsPerThread 0 +server config + + +

    MaxRequestsPerThread Áö½Ã¾î´Â + ÇÑ ¼­¹ö ¾²·¹µå°¡ ó¸®ÇÒ ¿äû°³¼ö¸¦ Á¦ÇÑÇÑ´Ù. + MaxRequestsPerThread°³ ¿äûÀ» ó¸®ÇÑÈÄ + ¾²·¹µå´Â Á״´Ù. MaxRequestsPerThread°¡ + 0À̸é Àý´ë·Î ¾²·¹µå¸¦ Á×ÀÌÁö ¾Ê´Â´Ù.

    + +

    MaxRequestsPerThread¸¦ 0ÀÌ ¾Æ´Ñ + °ªÀ¸·Î ¼³Á¤ÇÏ¸é µÎ°¡Áö ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • (¿ì¿¬È÷ ¹ß»ýÇÑ) ¸Þ¸ð¸® À¯Ãâ(memory leakage)¶§¹®¿¡ + ¾²·¹µå°¡ ³¶ºñÇÒ ¸Þ¸ð¸®·®À» Á¦ÇÑÇÑ´Ù;
    • + +
    • ¾²·¹µåÀÇ ¼ö¸íÀ» Á¦ÇÑÇÏ¿© ¼­¹ö ºÎÇÏ°¡ °¨¼ÒÇÒ¶§ + ¾²·¹µå ¼ö¸¦ ÁÙÀδÙ.
    • +
    + + ÁÖÀÇ: +

    KeepAlive ¿äûÀÇ + °æ¿ì ¿ÀÁ÷ ù¹ø° ¿äû¸¸À» ¼¾´Ù. ±×·¡¼­ ÀÌ Áö½Ã¾î´Â ¾²·¹µå´ç + ¿¬°á °³¼ö¸¦ Á¦ÇÑÇÏ°Ô µÈ´Ù.

    +
    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/beos.xml.meta b/trunk/docs/manual/mod/beos.xml.meta new file mode 100644 index 0000000000..331026e779 --- /dev/null +++ b/trunk/docs/manual/mod/beos.xml.meta @@ -0,0 +1,14 @@ + + + + beos + /mod/ + .. + + + de + en + es + ko + + diff --git a/trunk/docs/manual/mod/core.html b/trunk/docs/manual/mod/core.html new file mode 100644 index 0000000000..424afedab8 --- /dev/null +++ b/trunk/docs/manual/mod/core.html @@ -0,0 +1,11 @@ +URI: core.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: core.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: core.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/core.html.de b/trunk/docs/manual/mod/core.html.de new file mode 100644 index 0000000000..6446016a7d --- /dev/null +++ b/trunk/docs/manual/mod/core.html.de @@ -0,0 +1,3349 @@ + + + +core - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-Kernfunktionen

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    +
    Diese Übersetzung ist möglicherweise + nicht mehr aktuell. Bitte prüfen Sie die englische Version auf + die neuesten Änderungen.
    + +
    Beschreibung:Ständig verfügbare Kernfunktionen des Apache HTTP +Servers
    Status:Core
    +
    + + +
    top
    +

    AcceptPathInfo-Direktive

    + + + + + + + + + +
    Beschreibung:Ressourcen lassen angehängte Pfadangaben zu
    Syntax:AcceptPathInfo On|Off|Default
    Voreinstellung:AcceptPathInfo Default
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Verfügbar ab Apache 2.0.30
    +

    Die Direktive steuert, ob Anfragen akzeptiert oder + abgewiesen werden, bei denen nach der tatsächlichen + Datei (oder einer nicht existierenden Datei in einem existierenden + Verzeichnis) zusätzliche Pfadangaben folgen. Die angehängte + Pfadangabe kann Skripten in der Umgebungsvariable PATH_INFO + verfügbar gemacht werden.

    + +

    Nehmen wir beispielsweise an, dass /test/ auf ein + Verzeichnis zeigt, welches lediglich eine Datei here.html + enthält. Dann wird bei Anfragen nach + /test/here.html/more und + /test/nothere.html/more beides Mal /more + als PATH_INFO ermittelt.

    + +

    Die drei möglichen Argumente für die Direktive + AcceptPathInfo sind:

    + +
    +
    Off
    Eine Anfrage wird nur dann akzeptiert, + wenn sie exakt auf ein existierendes Verzeichnis (oder eine Datei) + abgebildet werden kann. Daher würde eine Anfrage mit einer nach dem + tatsächlichen Dateinamen angehängten Pfadangabe, wie + /test/here.html/more im obigen Beispiel, den Fehler + 404 NOT FOUND (Anm.d.Ü.: nicht gefunden) + zurückgeben.
    + +
    On
    +
    Eine Anfrage wird akzeptiert, wenn eine vorangestellte Pfadangabe + auf ein existierendes Verzeichnis abgebildet werden kann. Das + obige Beispiel /test/here.html/more wird akzeptiert, + wenn /test/here.html auf eine gültige Datei + zeigt.
    + +
    Default
    +
    Die Behandlung von Anfragen mit angehängten Pfadangaben + wird von dem für die Anfrage verantwortlichen Handler bestimmt. Der Core-Handler + für gewöhnliche Dateien weist PATH_INFO-Zugriffe + standardmäßig zurück. Handler, die Skripte bedienen, + wie z.B. cgi-script und + isapi-isa, sind im Allgemeinen darauf + voreingestellt, PATH_INFO zu akzeptieren.
    +
    + +

    Das eigentliche Ziel von AcceptPathInfo ist es, Ihnen + das Überschreiben der Voreinstellung der Handler bezüglich + der Akzeptanz oder Ablehnung von PATH_INFO zu erlauben. + Eine solche Änderung ist zum Beispiel notwendig, wenn Sie einen + Filter wie INCLUDES verwenden, um Inhalte + abhängig von PATH_INFO zu generieren. Der + Core-Handler würde die Anfrage normalerweise abweisen. Verwenden + Sie die folgende Konfiguration, um dennoch solch ein Skript zu + ermöglichen.

    + +

    + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +

    + + +
    +
    top
    +

    AccessFileName-Direktive

    + + + + + + + +
    Beschreibung:Name der dezentralen Konfigurationsdateien
    Syntax:AccessFileName Dateiname [Dateiname] ...
    Voreinstellung:AccessFileName .htaccess
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Aus dieser Namensliste sucht der Server während der + Bearbeitung einer Anfrage in jedem Verzeichnis nach der ersten + existierenden Datei, sofern im betreffenden Verzeichnis dezentrale + Konfigurationsdateien erlaubt sind. + Beispiel:

    + +

    + AccessFileName .acl +

    + +

    Vor der Rücksendung des Dokuments + /usr/local/web/index.html wird der Server + /.acl, /usr/.acl, + /usr/local/.acl und /usr/local/web/.acl + einlesen, solange diese nicht mit

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory> +

    + +

    deaktiviert wurden.

    + +

    Siehe auch

    + +
    +
    top
    +

    AddDefaultCharset-Direktive

    + + + + + + + + +
    Beschreibung:Standard-Charset-Parameter, der bei Antworten vom Content-Type + text/plain oder text/html hinzugefügt wird +
    Syntax:AddDefaultCharset On|Off|Zeichenkodierung
    Voreinstellung:AddDefaultCharset Off
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Die Direktive gibt einen Standardwert für den Charset-Paramter des + Medientyps (den Namen einer Zeichencodierung) an, der einer Antwort + genau dann hinzugefügt wird, wenn der Content-Type der Antwort entweder + text/plain oder text/html ist. Dies sollte jedes + mittels META-Element im Datenteil der Antwort angegebene + Charset überschreiben. Das genaue Verhalten hängt jedoch oft von + der Client-Konfiguration des Benutzers ab. Die Einstellung + AddDefaultCharset Off deaktiviert diese Funktionalität. + AddDefaultCharset On aktiviert die Standard-Zeichenkodierung + iso-8859-1. Jeder andere Wert wird als die zu verwendende + Zeichenkodierung aufgefaßt, die eines der bei IANA registrierten + Charset-Werte zur Verwendung in MIME-Medientypen sein sollte. Zum + Beispiel:

    + +

    + AddDefaultCharset utf-8 +

    + +

    AddDefaultCharset sollte nur verwendet werden, + wenn von allen Textressourcen, für die es gilt, bekannt ist, dass sie + in dieser Zeichkodierung vorliegen, oder wenn es zu unbequem ist, ihre + Zeichenkodierung indivuell zu benennen. Ein solches Beispiel ist das + Hinzufügen des Charset-Parameters zu Ressourcen, die generierte + Inhalte enthalten. Ein Beispiel sind CGI-Skript-Altlasten, die aufgrund von + in die Ausgabe integrierten Daten, die durch den Benutzer übermittelt + wurden, gegen Cross-Site-Scripting-Angriffe verwundbar sind. Eine bessere + Lösung wäre jedoch, diese Skripte zu korrigieren (oder zu + löschen), da die Angabe einer Standard-Zeichencodierung keine + Anwender schützt, die in ihrem Browser die Funktion zur + automatischen Erkennung der Zeichenkodierung aktiviert haben.

    + +

    Siehe auch

    + +
    +
    top
    +

    AddOutputFilterByType-Direktive

    + + + + + + + + +
    Beschreibung:einen Ausgabefilter einem bestimmten MIME-Type +zuordnen
    Syntax:AddOutputFilterByType Filter[;Filter...] +MIME-Type [MIME-Type] ...
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Verfügbar ab Apache 2.0.33
    +

    Die Direktive aktiviert für eine Anfrage abhängig vom + MIME-Type der Antwort einen bestimmten Ausgabe-Filter.

    + +

    Das folgende Beispiel verwendet den Filter DEFLATE, + der von mod_deflate angeboten wird. Er komprimiert + jede Ausgabe, die als text/html oder text/plain + gekennzeichnet ist, (gleichgültig, ob statisch oder dynamisch) + bevor sie an den Client gesendet wird.

    + +

    + AddOutputFilterByType DEFLATE text/html text/plain +

    + +

    Wenn Sie den Inhalt von mehr als einem Filter verarbeiten lassen + wollen, dann müssen deren Namen durch Semikolons voneinander + getrennt werden. Es ist ebenfalls möglich, eine + AddOutputFilterByType-Direktive für + jeden von diesen Filtern zu verwenden.

    + +

    Die folgende Konfiguration sorgt dafür, dass alle + Skriptausgaben, die als text/html gekennzeichnet + sind, zuerst vom INCLUDES-Filter und dann vom + DEFLATE-Filter verarbeitet werden.

    + +

    + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +

    + +

    Hinweis:

    +

    Die Aktivierung von Filtern mittels + AddOutputFilterByType kann in einigen + Fällen ganz oder teilweise fehlschlagen. Beispielsweise + werden keine Filter angewendet, wenn der MIME-Type nicht bestimmt + werden kann und auf die Einstellung der DefaultType-Anweisung zurückfällt, + selbst wenn die DefaultType-Einstellung die gleiche ist.

    + +

    Wenn Sie jedoch sicherstellen wollen, dass der Filter + angewendet wird, sollten Sie den Content-Type z.B. mit + AddType oder + ForceType der Ressource + explizit zuordnen. Das Setzen des Content-Types innerhalb + eines (nicht-nph) CGI-Skriptes funktioniert ebenfalls + zuverlässig.

    + +

    Die Typ-gebundenen Ausgabefilter werden niemals auf + Proxy-Anfragen angewendet.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    AllowEncodedSlashes-Direktive

    + + + + + + + + +
    Beschreibung:Legt fest, ob kodierte Pfadtrennzeichen in URLs durchgereicht +werden dürfen
    Syntax:AllowEncodedSlashes On|Off
    Voreinstellung:AllowEncodedSlashes Off
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    Kompatibilität:Verfügbar ab Apache 2.0.46
    +

    Die AllowEncodedSlashes-Direktive erlaubt die + Verwendung von URLs, welche kodierte Pfadtrennzeichen (%2F + für / und auf entsprechenden Systemen zusätzlich + %5C für \) enthalten. Normalerweise werden + derartige URLs mit einem 404-Fehler (Nicht gefunden) abgewiesen.

    + +

    AllowEncodedSlashes On ist + vor allem in Verbindung mit PATH_INFO hilfreich.

    + +

    Anmerkung

    +

    Das Erlauben von Schrägstrichen impliziert nicht deren + Dekodierung. Vorkommen von %2F oder %5C + (nur auf entsprechenden Systemen) werden unverändert in der + ansonsten dekodierten URL belassen.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    AllowOverride-Direktive

    + + + + + + + +
    Beschreibung:Direktiven-Typen, die in .htaccess-Dateien +erlaubt sind.
    Syntax:AllowOverride All|None|Direktiven-Typ +[Direktiven-Typ] ...
    Voreinstellung:AllowOverride All
    Kontext:Verzeichnis
    Status:Core
    Modul:core
    +

    Wenn der Server eine .htaccess-Datei (wie durch + AccessFileName definiert) + findet, muss er wissen, welche in der Datei angegebenen Direktiven + frühere Konfigurationsanweisungen überschreiben + dürfen.

    + +

    Nur in <Directory>-Abschnitten verfügbar

    + AllowOverride ist nur in <Directory>-Abschnitten + gültig, die ohne reguläre Ausdrücke definiert wurden, nicht + in <Location>-, + <DirectoryMatch>- oder + <Files>-Abschnitten. +
    + +

    Wenn diese Anweisung auf None gesetzt wird, dann + werden .htaccess-Dateien komplett + ignoriert. In diesem Fall wird der Server nicht einmal versuchen, + die .htaccess-Dateien im Dateisystem zu lesen.

    + +

    Wenn diese Anweisung auf All gesetzt wird, dann + ist jede Direktive in den .htaccess-Dateien erlaubt, + die den Kontext + .htaccess besitzt.

    + +

    Der Direktiven-Typ kann eine der folgenden + Anweisungsgruppen sein.

    + +
    +
    AuthConfig
    + +
    + Erlaubt die Verwendung von Autorisierungs-Anweisungen (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require usw.).
    + +
    FileInfo
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung der + Dokumenttypen (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, und + mod_mime-Direktiven Add* und Remove* + usw.).
    + +
    Indexes
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung von + Verzeichnisindizes (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName + usw.).
    + +
    Limit
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung des + Zugriffs von Hosts (Allow, Deny und Order).
    + +
    Options[=Option,...]
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung spezieller + Verzeichniseigenschaften (Options + und XBitHack). Sie + können mit einem Gleichheitszeichen gefolgt von einer + kommaseparierten Liste (ohne Leerzeichen) angeben, welche Optionen mit + der Options-Direktive gesetzt + werden dürfen.
    +
    + +

    Beispiel:

    + +

    + AllowOverride AuthConfig Indexes +

    + +

    Im obigen Beispiel erzeugen alle Direktiven einen internal server + error (Anm.d.Ü.: Server-interner Fehler), die weder der + Gruppe AuthConfig noch der Gruppe Indexes + angehören.

    + +

    Siehe auch

    + +
    +
    top
    +

    AuthName-Direktive

    + + + + + + + +
    Beschreibung:Autorisierungsbereich zur Verwendung in der +HTTP-Authentisierung
    Syntax:AuthName auth-Bereich
    Kontext:Verzeichnis, .htaccess
    AllowOverride:AuthConfig
    Status:Core
    Modul:core
    +

    Die Direktive legt den Namen des Autorisierungsbereiches + (Anm.d.Ü.: Der Autorisierungsbereich wird auch Realm genannt.) + für ein Verzeichnis fest. Dieser Realm wird dem Client mitgeteilt, + damit der Anwender weiß, welchen Benutzernamen und welches Passwort + er zu übermitteln hat. AuthName akzeptiert ein + Argument. Falls der Name des Realm Leerzeichen enthält, muss er in + Anführungszeichen eingeschlossen werden. Um zu funktionieren, muss + die Anweisung von den Direktiven AuthType und Require sowie von + Direktiven wie AuthUserFile + und AuthGroupFile + begleitet werden.

    + +

    Beispiel:

    + +

    + AuthName "Top Secret" +

    + +

    Die AuthName übergebene Zeichenkette ist das, + was in dem von den meisten Browsern angebotenen Passwort-Dialog + angezeigt wird.

    + +

    Siehe auch

    + +
    +
    top
    +

    AuthType-Direktive

    + + + + + + + +
    Beschreibung:Art der Authentisierung
    Syntax:AuthType Basic|Digest
    Kontext:Verzeichnis, .htaccess
    AllowOverride:AuthConfig
    Status:Core
    Modul:core
    +

    Die Direktive wählt die Art der Benutzer-Authentisierung + für ein Verzeichnis aus. Derzeit sind lediglich Basic + und Digest implementiert. + Um zu funktionieren, muss die Anweisung von den Direktiven AuthName und Require sowie von + Direktiven wie AuthUserFile + und AuthGroupFile + begleitet werden.

    + +

    Siehe auch

    + +
    +
    top
    +

    CGIMapExtension-Direktive

    + + + + + + + + +
    Beschreibung:Technik zur Bestimmung des Interpreters für +CGI-Skripte
    Syntax:CGIMapExtension CGI-Pfad .Endung
    Kontext:Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:ausschließlich NetWare
    +

    Die Direktive wird zur Steuerung verwendet, wie Apache + den Interpreter ermittelt, der zur Ausführung von + CGI-Skripten verwendet wird. Beispielsweise bestimmt die Angabe + von CGIMapExtension sys:\foo.nlm .foo, dass + alle CGI-Scripte mit der Endung .foo an den + FOO-Interpreter übergeben werden.

    + +
    +
    top
    +

    ContentDigest-Direktive

    + + + + + + + + +
    Beschreibung:Aktiviert die Generierung von Content-MD5 +HTTP-Response-Headern
    Syntax:ContentDigest On|Off
    Voreinstellung:ContentDigest Off
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:Options
    Status:Core
    Modul:core
    +

    Die Direktive aktiviert die Generierung von + Content-MD5-Headern, wie sie in RFC1864 bzw. RFC2068 + definiert sind.

    + +

    MD5 ist ein Algorithmus zur Berechnung eines "Datenextrakts" + (zuweilen "Fingerabdruck" genannt) (Anm.d.Ü.: Der "Datenextrakt" wird im + Englischen als "message digest" oder "fingerprint" bezeichnet.) + aus beliebig langen Daten. Es gilt als zuverlässig, dass + Veränderungen an den Daten sich in Veränderungen des + Extrakts wiederspiegeln.

    + +

    Der Content-MD5-Header bietet eine + End-to-End-Integritätsprüfung (MIC) (Anm.d.Ü.: MIC steht für + "message integrity check".) des Daten-Inhalts. Ein Proxy oder + Client kann diesen Header prüfen, um zufällige Veränderungen + des Entity-Inhalts bei der Übertragung festzustellen. + Beispielheader:

    + +

    + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== +

    + +

    Beachten Sie bitte, dass dies Performanceprobleme auf Ihrem + System verursachen kann, da der Extrakt bei jeder Anfrage + berechnet wird (der Wert wird nicht zwischengespeichert).

    + +

    Content-MD5 wird nur für Dokumente gesendet, + die von core bedient werden, nicht jedoch bei + Modulen. SSI-Dokumente, CGI-Skript-Ausgaben und Byte-Range-Antworten + besitzen diesen Header beispielsweise nicht.

    + +
    +
    top
    +

    DefaultType-Direktive

    + + + + + + + + +
    Beschreibung:MIME-Content-Type, der gesendet wird, wenn der Server den Typ +nicht auf andere Weise ermitteln kann.
    Syntax:DefaultType MIME-Type
    Voreinstellung:DefaultType text/plain
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Es kann vorkommen, dass der Server ein Dokument ausliefern muss, + dessen Typ er nicht mit Hilfe seiner MIME-Type-Zuordnungen bestimmen + kann.

    + +

    Der Server muss den Client über den Content-Type des + Dokumentes informieren. Daher verwendet er im Falle eines + unbekannten Typs die DefaultType-Einstellung. + Zum Beispiel:

    + +

    + DefaultType image/gif +

    + +

    wäre angemessen für ein Verzeichnis, das viele GIF-Bilder + enthält, deren Dateinamen nicht Endung .gif + besitzen.

    + +

    Beachten Sie bitte, dass die Direktive anders als ForceType lediglich den Standard-MIME-Type + bestimmt. Alle anderen MIME-Type-Definitionen, einschließlich + Dateierweiterungen, die den Medien-Typ anzeigen können, + überschreiben diese Voreinstellung.

    + +
    +
    top
    +

    <Directory>-Direktive

    + + + + + + +
    Beschreibung:Umschließt eine Gruppe von Direktiven, die nur auf +das genannte Verzeichnis des Dateisystems und Unterverzeichnisse angewendet +werden
    Syntax:<Directory Verzeichnispfad> +... </Directory>
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    <Directory> und + </Directory> werden dazu verwendet, eine Gruppe + von Direktiven zusammenzufassen, die nur für das genannte + Verzeichnis und dessen Unterverzeichnisse gelten. Jede Direktive, + die im Verzeichnis-Kontext erlaubt ist, kann verwendet werden. + Verzeichnispfad ist entweder der vollständige Pfad zu + einem Verzeichnis oder eine Zeichenkette mit Platzhaltern wie sie von der + Unix-Shell zum Abgleich verwendet werden. In einer Zeichenkette + mit Platzhaltern (Anm.d.Ü.: sogenannte wild-cards) entspricht + ? einem einzelnen Zeichen und * einer + Zeichenkette beliebiger Länge. Sie können auch auch + []-Zeichenbereiche verwenden. Keiner der Platzhalter + entspricht dem Zeichen "/". Daher passt <Directory + /*/public_html> nicht auf /home/user/public_html, + <Directory /home/*/public_html> jedoch tut es. + Beispiel:

    + +

    + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +

    + +
    +

    Seien Sie vorsichtig mit den Verzeichnispfad-Argumenten. + Sie müssen buchstäblich mit dem Dateisystempfad + übereinstimmen, den der Apache für den Zugriff auf die + Dateien verwendet. Direktiven, die für ein bestimmtes + Verzeichnis gelten, gelten nicht für Dateien in dem Verzeichnis, + auf die über einen anderen Pfad zugegriffen wird, wie z.B. + über verschiedene symbolische Links.

    +
    + +

    Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt + wird. Beispielsweise würde

    + +

    + <Directory ~ "^/www/.*/[0-9]{3}"> +

    + +

    auf Verzeichnisse in /www/ passen, die aus drei + Zahlen bestehen.

    + +

    Wenn mehrere <Directory>-Abschnitte + (ohne reguläre Ausdrücke) auf ein Verzeichnis (oder + ein ihm übergeordnetes Verzeichnis) passen, welches ein Dokument + enthält, dann werden die Direktiven der Reihe nach, angefangen + beim kürzesten passenden Muster, vermischt mit den Direktiven + aus den .htaccess-Dateien, angewendet. + Beispiel:

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +

    + +

    Beim Zugriff auf das Dokument /home/web/dir/doc.html + sind die einzelnen Schritte:

    + +
      +
    • Wende die Direktive AllowOverride None an + (deaktiviere .htaccess-Dateien).
    • + +
    • Wende die Direktive AllowOverride FileInfo + (auf das Verzeichnis /home) an.
    • + +
    • Wende jede FileInfo-Direktive aus + /home/.htaccess, /home/web/.htaccess und + /home/web/dir/.htaccess der Reihe nach an.
    • +
    + +

    Reguläre Ausdrücke werden solange nicht berücksichtigt, + bis alle normalen Abschnitte angewendet wurden. Anschließend + werden alle regulären Ausdrücke in der Reihenfolge + geprüft, in der sie in der Konfigurationsdatei auftauchen. + Beispielsweise wird bei

    + +

    + <Directory ~ abc$>
    + + # ... hier die Direktiven ...
    +
    + </Directory> +

    + +

    der Abschnitt mit dem regulären Ausdruck nicht + berücksichtigt, bis alle normalen + <Directory>-Abschnitte und + .htaccess-Dateien angewendet wurden. Dann erst wird + der reguläre Ausdruck mit /home/abc/public_html/abc + abgeglichen und der entsprechende <Directory>-Abschnitt angewendet.

    + +

    Beachten Sie bitte, dass der vom Apache voreingestellte + Zugriff für <Directory /> + Allow from All ist. Das bedeutet, dass der Apache + jede Datei ausliefert, die durch eine URL abgebildet wird. Es wird + empfohlen, dass Sie dies durch einen Block wie

    + +

    + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +

    + +

    ändern und anschließend für + Verzeichnisse überschreiben, die Sie verfügbar machen + wollen. Für weitere Einzelheiten lesen Sie bitte + die Seite zu den Sicherheitshinweisen.

    + +

    Die Verzeichnisabschnitte erscheinen in der Datei + httpd.conf. <Directory>-Direktiven dürfen nicht + ineinander verschachtelt werden oder innerhalb von <Limit>- oder <LimitExcept>-Abschnitten auftauchen.

    + +

    Siehe auch

    + +
    +
    top
    +

    <DirectoryMatch>-Direktive

    + + + + + + +
    Beschreibung:Umschließt eine Gruppe von Direktiven, die auf + Verzeichnisse des Dateisystems und ihre Unterverzeichnisse abgebildet + werden, welche auf einen regulären Ausdruck passen
    Syntax:<DirectoryMatch regex> +... </DirectoryMatch>
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    <DirectoryMatch> und + </DirectoryMatch> werden dazu verwendet, eine + Gruppe von Direktiven zusammenzufassen, die nur für das + genannte Verzeichnis und dessen Unterverzeichnisse gelten, genauso + wie bei <Directory>. + Als Argument dient jedoch ein regulärer Ausdruck. + Beispielsweise würde

    + +

    + <DirectoryMatch "^/www/.*/[0-9]{3}"> +

    + +

    auf Verzeichnisse in /www/ passen, die aus drei + Zeichen bestehen.

    + +

    Siehe auch

    + +
    +
    top
    +

    DocumentRoot-Direktive

    + + + + + + + +
    Beschreibung:Verzeichnis, welches den Haupt-Dokumentenbaum bildet, der im +Web sichtbar ist.
    Syntax:DocumentRoot Verzeichnis
    Voreinstellung:DocumentRoot /usr/local/apache/htdocs
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive setzt das Verzeichnis, von dem aus + httpd Dateien ausliefert. Sofern nicht eine Direktive + wie Alias greift, hängt + der Server Pfade aus der angeforderten URL an das Wurzelverzeichnis + an, um den Pfad zum Dokument zu bilden. Beispiel:

    + +

    + DocumentRoot /usr/web +

    + +

    Damit bezieht sich ein Zugriff auf + http://www.my.host.com/index.html auf + /usr/web/index.html. Wenn das Verzeichnis nicht + absolut angegeben ist, wird es relativ zu ServerRoot betrachtet.

    + +

    DocumentRoot sollte ohne einen + Schrägstrich am Ende angegeben werden.

    + +

    Siehe auch

    + +
    +
    top
    +

    EnableMMAP-Direktive

    + + + + + + + + +
    Beschreibung:Verwende Memory-Mapping, um Dateien während der +Auslieferung zu lesen
    Syntax:EnableMMAP On|Off
    Voreinstellung:EnableMMAP On
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Die Direktive steuert, ob httpd Memory-Mapping + verwenden darf, wenn er während der Auslieferung den Inhalt einer + Datei lesen muss. Wenn die Bearbeitung einer Anfrage es erfordert, + auf die Daten in einer Datei zuzugreifen -- zum Beispiel bei der + Auslieferung einer mittels mod_include serverseitig + analysierten Datei --, dann verwendet der Apache standardmäßig + Memory-Mapping für diese Datei, sofern das Betriebssystem es + unterstützt.

    + +

    Memory-Mapping bedeutet zuweilen eine Performanceverbesserung. + In einigen Umgebungen ist es jedoch besser, Memory-Mapping zu + deaktivieren, um Problemen während des Betriebs vorzubeugen:

    + +
      +
    • Bei einigen Multiprozessorsystemen kann Memory-Mapping die + Performance von httpd reduzieren.
    • +
    • Bei einem per NFS eingebundenen DocumentRoot kann httpd mit + einem Speicherzugriffsfehler (Anm.d.Ü.: ein so genannter "segmentation + fault") abstürzen, wenn eine Datei gelöscht oder + gekürzt wird, während httpd sie im Speicher + abbildet.
    • +
    + +

    Bei Serverkonfigurationen, die für dieses Problem + anfällig sind, sollten Sie das Memory-Mapping für + auszuliefernde Dateien deaktivieren, indem Sie schreiben:

    + +

    + EnableMMAP Off +

    + +

    Bei per NFS eingebundenen Dateien kann diese Funktion + explizit für die störenden Dateien deaktiviert werden, + indem Sie angeben:

    + +

    + <Directory "/pfad-zu-den-nfs-dateien"> + + EnableMMAP Off + + </Directory> +

    + +
    +
    top
    +

    EnableSendfile-Direktive

    + + + + + + + + + +
    Beschreibung:Verwende die sendfile-Unterstützung des Kernels, um +Dateien an den Client auszuliefern
    Syntax:EnableSendfile On|Off
    Voreinstellung:EnableSendfile On
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Verfügbar ab Apache Version 2.0.44
    +

    Die Direktive steuert, ob httpd die + sendfile-Unterstützung des Kernels verwenden kann, um + Dateiinhalte an den Client zu übermitteln. Wenn die Bearbeitung + einer Anfrage keinen Zugriff auf die Daten in der Datei erfordert -- + zum Beispiel bei der Auslieferung einer statischen Datei -- und das + Betriebssystem es unterstützt, verwendet der Apache + standardmäßig sendfile, um den Dateiinhalt zu + übertragen, ohne die Datei jemals zu lesen.

    + +

    Der sendfile-Mechanismus vermeidet getrennte Lese- und + Sendeoperationen sowie Puffer-Zuweisungen. Bei einigen Plattformen bzw. + Dateisystemen deaktivieren Sie diese Funktion jedoch besser, um Probleme + während des Betriebs zu vermeiden:

    + +
      +
    • Einige Plattformen besitzen u.U. eine fehlerhafte + sendfile-Unterstützung, die das Erstellungssystem nicht erkennt, + insbesondere wenn die Binärdateien auf einem anderen Rechner erstellt + und auf eine solche Maschine mit fehlerhafter sendfile-Unterstützung + übertragen wurden.
    • +
    • Bei einem über das Netzwerk eingebundenen DocumentRoot (z.B. NFS oder SMB) ist der + Kernel möglicherweise nicht in der Lage, die Netzwerkdatei + über seinen eigenen Cache zu bedienen.
    • +
    • Unter Linux löst die Verwendung von sendfile + in Verbindung mit bestimmten Netzwerkkarten und IPv6 + TCP-Checksummenfehler aus.
    • +
    + +

    Bei Serverkonfigurationen, die für dieses Problam + anfällig sind, sollten die diese Funktion deaktivieren, indem + Sie schreiben:

    + +

    + EnableSendfile Off +

    + +

    Bei per NFS oder SMB eingebundenen Dateien kann diese Funktion + explizit für die störenden Dateien deaktiviert werden, indem + Sie angeben:

    + +

    + <Directory "/pfad-zu-den-nfs-dateien"> + + EnableSendfile Off + + </Directory> +

    + +
    +
    top
    +

    ErrorDocument-Direktive

    + + + + + + + + +
    Beschreibung:Das, was der Server im Fehlerfall an den Client +zurückgibt
    Syntax:ErrorDocument Fehlercode Dokument
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Die Syntax der Anführungszeichen bei Textnachrichten hat +sich im Apache 2.0 geändert
    +

    Im Falle eines Problems oder Fehlers kann der Apache + konfiguriert werden, eine der vier Aktionen auszuführen:

    + +
      +
    1. Ausgabe einer einfachen, hartkodierten Fehlermeldung
    2. + +
    3. Ausgabe einer angepassten Meldung
    4. + +
    5. Umleitung zu einem lokalen URL-Pfad der das + Problem bzw. den Fehler behandelt
    6. + +
    7. Umleitung zu einer externen URL, die das Problem + bzw. den Fehler behandelt
    8. +
    + +

    Die erste Option ist Voreinstellung, während die Optionen + 2 bis 4 über die Direktive ErrorDocument + eingestellt werden, welcher der HTTP-Statuscode und eine + URL oder Nachricht folgen. Abhängig vom Problem bzw. Fehler bietet + der Apache manchmal zusätzliche Informationen an.

    + +

    URLs können bei lokalen Adressen mit einem Schrägstrich + (/) beginnen oder eine komplette URL bilden, die der Client + auflösen kann. Alternativ kann eine Nachricht für die + Anzeige im Browser angeboten werden. Beispiel:

    + +

    + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/falsche_urls.pl
    + ErrorDocument 401 /info_zur_anmeldung.html
    + ErrorDocument 403 "Der Zugriff ist nicht erlaubt." +

    + +

    Außerdem kann der spezielle Wert default angegeben + werden, um die schlichte, hartkodierte Nachricht des Apache zu verwenden. + Es wird normalerweise nicht benötigt, doch default + stellt die einfach, im Apache hartkodierte Meldung in Konfigurationen + wieder her, die ansonsten von einem existierenden (Anm.d.Ü.: zuvor + konfigurierten) ErrorDocument erben + würden.

    + +

    + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +

    + +

    Wenn Sie eine ErrorDocument-Anweisung + angeben, die auf eine entfernte URL weist (d.h. irgendetwas mit der + Methode http davor), beachten Sie bitte, dass der Apache + eine Umleitung zum Client sendet, um diesem mitzuteilen, wo das + Dokument zu finden ist, auch wenn das Dokument letztlich wieder zum + gleichen Server führt. Das hat mehrere Auswirkungen. Die + wichtigste ist, dass der Client nicht den Original-Statuscode + erhält sondern statt dessen einen Umleitungs-Statuscode. Dies + wiederum kann Web-Robots und andere Clients verwirren, die den + Statuscode dazu verwenden, herauszufinden ob eine URL gültig ist. + Wenn Sie eine entfernte URL in einer Anweisung + ErrorDocument 401 verwenden, wird der Client + darüber hinaus nicht wissen, dass er den Benutzer zur Eingabe + eines Passwortes auffordern muss, da er den Statuscode 401 nicht + erhält. Deshalb müssen Sie sich auf ein lokales + Dokument beziehen, wenn Sie eine Anweisung ErrorDocument + 401 verwenden.

    + +

    Der Microsoft Internet Explorer (MSIE) ignoriert + standardmäßig serverseitig generierte Fehlermeldungen, wenn + sie "zu kurz" sind und ersetzt sie durch eigene "freundliche" + Fehlermeldungen. Die Größe variiert abhängig von der + Art des Fehlers, im Allgemeinen zeigt der MSIE jedoch den + serverseitig generierten Fehler, anstatt ihn zu verstecken, wenn Ihr + Fehlerdokument größer als 512 Bytes ist. Weitere Informationen + sind im Artikel Q294807 in der Microsoft Knowledgebase article verfügbar.

    + +

    In Versionen vor 2.0 wurden Meldungen durch ein einzelnes + vorangestelltes Anführungszeichen (") erkannt.

    + +

    Siehe auch

    + +
    +
    top
    +

    ErrorLog-Direktive

    + + + + + + + +
    Beschreibung:Ablageort, an dem der Server Fehler protokolliert
    Syntax: ErrorLog Dateiname|syslog[:facility]
    Voreinstellung:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and + OS/2)
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive ErrorLog bestimmt den Namen + der Datei, in welcher der Server alle auftretenden Fehler protokolliert. + Wenn Dateiname nicht absolut ist, wird er relativ zu ServerRoot betrachtet.

    + +

    Beispiel

    + ErrorLog /var/log/httpd/error_log +

    + +

    Wenn der Dateiname mit einem senkrechten Strich (|, + engl.: Pipe) beginnt, wird angenommen, dass es sich um einen Befehl + handelt, der ausgeführt wird, um das Fehlerprotokolls zu + verarbeiten.

    + +

    Beispiel

    + ErrorLog "|/usr/local/bin/httpd_errors" +

    + +

    Die Verwendung von syslog anstelle eines Dateinamens + aktiviert die Protokollierung mittels syslogd(8), sofern das System + es unterstützt. Als Voreinstellung wird der syslog-Typ (syslog + facility) local7 verwendet, Sie können dies jedoch + auch überschreiben, indem Sie die Syntax + syslog:facility verwenden, wobei + facility einer der Namen sein kann, die üblicherweise + in syslog(1) dokumentiert sind.

    + +

    Beispiel

    + ErrorLog syslog:user +

    + +

    SICHERHEITSHINWEIS: Lesen Sie das Dokument Sicherheitshinweise + zu Einzelheiten darüber, warum Ihre Sicherheit gefährdet + sein kann, wenn das Verzeichnis, in dem die Log-Dateien gespeichert + werden, für jemand anderen, als den Benutzer, der den Server + gestartet hat, beschreibbar ist.

    + +

    Anmerkung

    +

    Bei der Eingabe eines Dateipfads auf nicht-Unix-Plattformen sollte + darauf geachtet werden, nur (Vorwärts-)Schrägstriche zu + verwenden, auch wenn die Plattform rückwärts gerichtete + Schrägstriche (Backslashes) erlaubt. Im Allgemeinen ist es eine gute + Idee, innerhalb der Konfigurationsdateien immer + Vorwärts-Schrägstriche zu verwenden.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    FileETag-Direktive

    + + + + + + + + +
    Beschreibung:Dateiattribute, die zur Erstellung des HTTP-Response-Headers +ETag verwendet werden
    Syntax:FileETag Komponente ...
    Voreinstellung:FileETag INode MTime Size
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Wenn dem Dokument eine Datei zugrundeliegt, bestimmt die Direktive + FileETag die Dateiattribute, die zur Erstellung + des HTTP-Response-Headers ETag (Entity-Tag) verwendet + werden. (Der Wert von ETag wird bei der Cache-Verwaltung + zur Einsparung von Netzwerk-Bandbreite benutzt.) Im Apache 1.3.22 und + früher wurde der ETag-Wert stets aus + der I-Node, der Größe und dem Datum der letzten + Änderung (mtime) der Datei gebildet. Die Direktive + FileETag erlaubt es Ihnen, zu bestimmen, + welche dieser Eigenschaften -- falls überhaupt -- verwendet + werden sollen. Die gültigen Schlüsselworte lauten:

    + +
    +
    INode
    +
    Die I-Node-Nummer wird in die Berechnung mit einbezogen
    +
    MTime
    +
    Datum und Uhrzeit der letzten Änderung werden mit einbezogen
    +
    Size
    +
    Die Anzahl der Bytes in der Datei wird mit einbezogen
    +
    All
    +
    Alle verfügbaren Angaben werden verwendet. Die ist + gleichbedeutend mit: +

    FileETag INode MTime Size

    +
    None
    +
    Es wird keine ETag-Angabe in die Antwort eingefügt, + wenn dem Dokument eine Datei zugrundeliegt.
    +
    + +

    Den Schlüsselwörtern INode, MTime + und Size kann entweder ein + oder ein + - vorangestellt werden, was die Änderung einer + Vorgabe erlaubt, die von einem größeren Umfeld + geerbt wurde. Jedes Schlüselwort ohne ein solches Prefix + hebt die ererbte Einstellung sofort und vollständig auf.

    + +

    Wenn die Konfiguration für ein Verzeichnis + FileETag INode MTime Size enthält + und die eines Unterverzeichnisses FileETag -INode, + dann ist die Einstellung für das Unterverzeichnis (die an + jedes Unter-Unterverzeichnis weitervererbt wird, welches dies nicht + überschreibt) äquivalent mit + FileETag MTime Size.

    + +
    +
    top
    +

    <Files>-Direktive

    + + + + + + + +
    Beschreibung:Enthält Direktiven, die sich nur auf passende Dateinamen +beziehen
    Syntax:<Files Dateiname> ... </Files>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Die Direktive <Files> + begrenzt die Reichweite der enthaltenen Anweisungen auf Dateinamen. + Sie ist vergleichbar mit den Direktiven <Directory> und <Location>. Sie muss eine + passende </Files>-Anweisung besitzen. + Die innerhalb dieses Abschnittes angegebenen Direktiven werden auf + jedes Objekt mit einem Basisnamen (letzte Komponente des Dateinamens) + angewendet, der auf die angegebenen Dateinamen passt. <Files>-Container werden, nachdem die + <Directory>-Container + und .htaccess-Dateien gelesen sind, jedoch vor den + <Location>-Containern, + in der Reihenfolge ihres Auftretens ausgeführt. Beachten Sie, dass + <Files>-Anweisungen innerhalb von + <Directory>-Containern + auftreten können, um den Teil des Dateisystems einzuschränken, + den sie betreffen.

    + +

    Das Argument Dateiname kann einen Dateinamen oder eine + Zeichenkette mit Platzhaltern enthalten, wobei ? auf ein + einzelnes Zeichen passt und * auf eine beliebige Folge von + Zeichen. Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt wird. + Beispielsweise würde

    + +

    + <Files ~ "\.(gif|jpe?g|png)$"> +

    + +

    auf die gebräuchlichsten Grafikformate im Internet passen. + <FilesMatch> wird + jedoch bevorzugt.

    + +

    Beachten Sie bitte, dass die <Files>-Container anders als <Directory>- und <Location>-Container innerhalb + von .htaccess-Dateien verwendet werden können. + Dies erlaubt den Anwendern auf Dateiebene die Kontrolle über ihre + eigenen Dateien.

    + +

    Siehe auch

    + +
    +
    top
    +

    <FilesMatch>-Direktive

    + + + + + + + +
    Beschreibung:Enthält Direktiven, die für Dateinamen gelten, die + auf einen regulären Ausdruck passen
    Syntax:<FilesMatch regex> ... </FilesMatch>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Die Direktive <FilesMatch> + begrenzt wie die Direktive <Files> die enthaltenen Anweisungen auf + Dateinamen. Sie akzeptiert jedoch reguläre Ausdrücke. + Beispielsweise würde

    + +

    + <FilesMatch "\.(gif|jpe?g|png)$"> +

    + +

    auf die gebräuchlichsten Grafikformate im Internet passen.

    + +

    Siehe auch

    + +
    +
    top
    +

    ForceType-Direktive

    + + + + + + + + +
    Beschreibung:Erzwingt die Auslieferung aller passendenden Dateien mit dem +angegebenen MIME-Content-Type
    Syntax:ForceType MIME-Type|None
    Kontext:Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Wurde im Apache 2.0 in den Core verschoben
    +

    Wenn sie innerhalb einer .htaccess-Datei, eines + <Directory>-, + <Location>- + <Files>-Containers + angegeben wird, erzwingt die Direktive die Auslieferung aller + entsprechenden Dateien mit dem Content-Type, der durch + MIME-Type definiert wurde. Wenn Sie zum Beispiel ein + Verzeichnis voller GIF-Dateien haben, die Sie nicht alle durch + .gif kennzeichnen wollen, können Sie angeben:

    + +

    + ForceType image/gif +

    + +

    Beachten Sie bitte, dass die Direktive anders als DefaultType alle MIME-Type-Zuordnungen + überschreibt, einschließlich Dateiendungen, die einen + Medientyp bezeichnen könnten.

    + +

    Sie können jede ForceType-Angabe + durch die Verwendung des Wertes None überschreiben:

    + +

    + # erzwinge image/gif für alle Dateien:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # hier jedoch normale MIME-Type-Zuordnungen:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +

    + +
    +
    top
    +

    HostnameLookups-Direktive

    + + + + + + + +
    Beschreibung:Aktiviert DNS-Lookups auf Client-IP-Adressen
    Syntax:HostnameLookups On|Off|Double
    Voreinstellung:HostnameLookups Off
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
    Status:Core
    Modul:core
    +

    Diese Direktive aktiviert die DNS-Abfrage (Anm.d.Ü.: ein sogenannter + DNS-Lookup), so dass Hostnamen protokolliert (und in + REMOTE_HOST an CGIs/SSIs übergeben) werden könnnen. + Der Wert Double bezieht sich auf ein + Double-Reverse-DNS-Lookup. D.h. nachdem ein Reverse-Lookup + durchgeführt wurde, wird dann auf dem Ergebnis ein + Forward-Lookup ausgeführt. Wenigstens eine der IP-Adressen + aus dem Forward-Lookup muss der Originaladresse entsprechen. + (In der "tcpwrappers"-Terminologie wird dies PARANOID + genannt.)

    + +

    Unabhängig von der Einstellung wird ein Double-Reverse-Lookup + durchgeführt, wenn mod_authz_host zur + Zugriffskontrolle per Hostnamen eingesetzt wird. Dies ist aus + Sicherheitsgründen notwendig. Beachten Sie, dass das Ergebnis dieses + Double-Reverse-Lookups nicht generell verfügbar ist, solange Sie + nicht HostnameLookups Double setzen. Wenn beispielsweise + nur HostnameLookups On angegeben ist und eine Anfrage + für ein Objekt erfolgt, welches durch Hostnamen-Beschränkungen + geschützt ist, dann wird CGIs nur das Ergebnis des + Singel-Reverse-Lookups in REMOTE_HOST übergeben, + egal ob das Doble-Reverse-Lookup fehlschlug oder nicht.

    + +

    Die Voreinstellung ist Off, um Netzwerktraffic bei den + Angeboten einzusparen, die nicht tatsächlich Reverse-Lookups + benötigen. Es ist auch für die Endanwender besser, da sie nicht + die zusätzliche Wartezeit ertragen müssen, die ein Lookup mit + sich bringt. Hoch frequentierte Angebote sollten diese Direktive auf + Offlassen. Das Hilfsprogramm logresolve, das standardmäßig in das + Unterverzeichnis bin Ihres Installationsverzeichnisses + kompiliert wird, kann dazu verwendet werden, um offline Hostnamen von + protokollierten IP-Adressen nachzuschlagen.

    + +
    +
    top
    +

    <IfDefine>-Direktive

    + + + + + + + +
    Beschreibung:Schließt Direktiven ein, die nur ausgeführt werden, +wenn eine Testbedingung beim Start wahr ist
    Syntax:<IfDefine [!]Parametername> ... + </IfDefine>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Der Container <IfDefine Test>...</IfDefine> + wird dazu verwendet, Direktiven als bedingt zu kennzeichnen. + Die Direktiven innerhalb eines <IfDefine>-Abschnittes werden nur ausgeführt, + wenn Test wahr ist. Ist Test falsch, wird alles + zwischen der Start- und Endemarkierung ignoriert.

    + +

    In der <IfDefine>-Anweisung kann + Test eine von zwei Formen annehmen:

    + +
      +
    • Parametername
    • + +
    • !Parametername
    • +
    + +

    Im ersten Fall werden die Direktiven zwischen der Start- und + Endemarkierung nur ausgeführt, wenn der Parameter namens + Parametername definiert ist. Die zweite Form kehrt den + Test um und führt die Direktiven nur dann aus, wenn + Parametername nicht definiert ist.

    + +

    Das Argument Parametername ist ein sogenanntes + "Define", das beim beim Start des Servers in der + httpd-Befehlszeile durch + -DParameter angegeben wird.

    + +

    <IfDefine>-Container können + ineinander verschachtelt werden, um einfache Multi-Parameter-Tests + zu implementieren. Beispiel:

    + +

    + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +

    + +
    +
    top
    +

    <IfModule>-Direktive

    + + + + + + + + +
    Beschreibung:Schließt Direktiven ein, die abhängig vom +Vorhandensein oder Fehlen eines speziellen Moduls ausgeführt +werden
    Syntax:<IfModule [!]Modulname|Modulbezeichner> + ... </IfModule>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    Kompatibilität:Modulbezeichner sind ab Version 2.1 + verfügbar.
    +

    Der Container <IfModule + Test>...</IfModule> wird dazu verwendet, + Direktiven als abhängig von dem Vorhandensein eines speziellen + Moduls zu kennzeichnen. Die Direktiven innerhalb eines <IfModule>-Abschnitts werden nur + ausgeführt, wenn Test wahr ist. Ist Test + falsch, wird alles zwischen der Start- und Endemarkierung ignoriert.

    + +

    In der <IfModule>-Anweisung + kann Test eine von zwei Formen annehmen:

    + +
      +
    • Modul
    • + +
    • !Modul
    • +
    + +

    Im ersten Fall werden die Direktiven zwischen der Start- und + Endemarkierung nur ausgeführt, das Modul namens + Modul im Apache enthalten ist -- entweder einkompiliert + oder mittels LoadModule + dynamisch geladen. Die zweite Form dreht den Test um und führt die + Direktiven nur aus, wenn Modul nicht + enthalten ist.

    + +

    Das Argument Modul kann entweder der Modulbezeichner oder + der Dateiname des Moduls zum Zeitpunkt seiner Kompilierung sein. + rewrite_module beispielsweise ist der Bezeichner und + mod_rewrite.c ist der Dateiname. Wenn ein Modul aus mehreren + Quelltext-Dateien besteht, verwenden Sie den Namen der Datei, welche die + Zeichenfolge STANDARD20_MODULE_STUFF enthält.

    + +

    <IfModule>-Container können + inneinander verschachtelt werden, um einfache Multi-Modul-Tests + durchzuführen.

    + +

    Dieser Container sollte verwendet werden, wenn Sie eine + Konfigurationsdatei benötigen, die unabhängig davon funktioniert, + ob ein bestimmtes Modul verfügbar ist oder nicht. Normalerweise + ist es nicht notwendig, Direktiven in <IfModule>-Containern unterzubringen.

    + +
    +
    top
    +

    Include-Direktive

    + + + + + + + +
    Beschreibung:Fügt andere Konfigurationsdateien innerhalb der +Server-Konfigurationsdatei ein
    Syntax:Include Dateiname|Verzeichnis
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
    Status:Core
    Modul:core
    Kompatibilität:Die Platzhalter-Suche ist verfügbar seit +2.0.41
    +

    Die Direktive erlaubt das Einfügen anderer Konfigurationsdateien + in die Konfigurationsdatei des Servers.

    + +

    Shell-typische (fnmatch()) Platzhlaterzeichen können + dazu verwendet werden, mehrere Dateien auf einmal in alphabetischer + Reihenfolge einzufügen. Wenn Include + darüber hinaus auf ein Verzeichnis anstatt auf eine Datei zeigt, + liest der Apache alle Dateien in diesem Verzeichnis und allen + Unterverzeichnissen ein. Das Einfügen ganzer Verzeichnisse ist + jedoch nicht empfehlenswert, da temporäre Dateien sehr leicht + versehentlich in einem Verzeichnis zurückgelassen werden, was + httpd scheitern lassen kann.

    + +

    Der angegebene Dateiname kann ein absoluter Pfad sein oder relativ zum + ServerRoot-Verzeichnis angegeben + werden.

    + +

    Beispiele:

    + +

    + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +

    + +

    Oder Sie geben Pfade relativ zu Ihrem ServerRoot-Verzeichnis an:

    + +

    + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +

    + +

    Der Aufruf von apachectl configtest liefert eine Liste + der Dateien, die während des Konfigurations-Tests verarbeitet + werden:

    + +

    + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +

    + +

    Siehe auch

    + +
    +
    top
    +

    KeepAlive-Direktive

    + + + + + + + +
    Beschreibung:Aktiviert persistente HTTP-Verbindungen
    Syntax:KeepAlive On|Off
    Voreinstellung:KeepAlive On
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Keep-Alive-Erweiterung von HTTP/1.0 und die + HTTP/1.1-Funktionalität persistenter Verbindungen unterstützt + langlebige HTTP-Sitzungen, die es erlauben, mehrere Anfragen über + die gleich TCP-Verbindung zu senden. In einigen Fällen wurde eine + Beschleunigung der Wartezeiten von beinahe 50% für HTML-Dokumente + mit vielen Bildern festgestellt. Um Keep-Alive-Verbindungen zu aktivieren, + setzen Sie KeepAlive On.

    + +

    Bei HTTP/1.0-Clients werden Keep-Alive-Verbindungen nur dann verwendet, + wenn sie vom Client eigens angefordert werden. Desweiteren können + Keep-Alive-Verbindungen bei einem HTTP/1.0-Client nur dann verwendet + werden, wenn die Länge des Inhalts im Voraus bekannt ist. Dies + impliziert, dass dynamische Inhalte wie CGI-Ausgaben, SSI-Seiten und + servergenerierte Verzeichnisauflistungen im Allgemeinen keine + Keep-Alive-Verbindungen mit HTTP/1.0-Clients verwenden. Bei + HTTP/1.1-Clients sind Keep-Alive-Verbindungen Voreinstellung, solange + nichts anderes angegeben ist. Wenn der Client es anfordert, wird + Chunked-Encoding verwendet, um Inhalte mit unbekannter Länge + über persistente Verbindungen zu senden.

    + +

    Siehe auch

    + +
    +
    top
    +

    KeepAliveTimeout-Direktive

    + + + + + + + +
    Beschreibung:Zeitspanne, die der Server während persistenter Verbindungen +auf nachfolgende Anfragen wartet
    Syntax:KeepAliveTimeout Sekunden
    Voreinstellung:KeepAliveTimeout 5
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Dies legt die Anzahl der Sekunden fest, die der Apache auf weitere + Anfragen wartet, bevor er die Verbindung schließt. Nachdem einmal + eine Anfrage entgegen genommen wurde, wird die durch die Direktive + Timeout festgelegte Auszeit + angewendet.

    + +

    Auf stark belasteten Servern kann ein hoher + KeepAliveTimeout-Wert zu Durchsatzminderungen + führen. Je höher die Auszeit angegeben ist, desto länger + ist der Apache damit beschäftigt, auf untätige Clients zu + warten.

    + +
    +
    top
    +

    <Limit>-Direktive

    + + + + + + + +
    Beschreibung:Beschränkt die eingeschlossenen Zugriffskontrollen auf +bestimmte HTTP-Methoden
    Syntax:<Limit Methode [Methode] ... > ... + </Limit>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Zugriffskontrollen gelten normalerweise für alle + Zugriffsmethoden, was normalerweise auch das gewünschte Verhalten ist. + Im Allgemeinen sollten Zugriffskontrollen nicht in einen + <Limit>-Container gepackt + werden.

    + +

    Der Sinn der Direktive <Limit> + ist es, den Effekt der Zugriffskontrollen auf die angegebenen + HTTP-Methoden zu beschränken. Bei allen anderen Methoden haben + die in der <Limit>-Gruppe + enthaltenen Zugriffsbeschränkungen keine Wirkung. + Im folgenden Beispiel gilt die Zugriffskontrolle nur für die + Methoden POST, PUT und DELETE. + Alle anderen Methoden bleiben ungeschützt:

    + +

    + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +

    + +

    Sie können eine oder mehrere der folgenden Methoden angeben: + GET, POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK und UNLOCK. Die Methodennamen + unterscheiden zwischen Groß- und Kleinschreibung. Wenn + GET verwendet wird, sind HEAD-Anfragen + ebenfalls eingeschränkt. Die TRACE-Methode kann nicht + limitiert werden.

    + +
    + Wenn es um Zugriffsbeschränkungen geht, sollte + ein <LimitExcept>-Container sollte immmer einem <Limit>-Container vorgezogen + werden, da <LimitExcept> + einen Schutz gegen beliebige Methoden bietet. +
    + +
    +
    top
    +

    <LimitExcept>-Direktive

    + + + + + + + +
    Beschreibung:Beschränkt Zugriffskontrollen auf alle HTTP-Methoden +außer den genannten
    Syntax:<LimitExcept Methode [Methode] ... > ... + </LimitExcept>
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    <LimitExcept> und + </LimitExcept> werden dazu verwendet, eine Gruppe + von Anweisungen zur Zugriffskontrolle zusammenzufassen, die dann auf + jede HTTP-Methode angewendet werden, die nicht + als Argument angegeben ist. D.h. dies ist das Gegenteil des + <Limit>-Containers + und kann zur Steuerung von Standard- und nicht-Standard-/unbekannten + Methoden verwendet werden. Für weitere Einzelheiten lesen Sie bitte + die Beschreibung zu <Limit>.

    + +

    Beispiel:

    + +

    + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +

    + + +
    +
    top
    +

    LimitInternalRecursion-Direktive

    + + + + + + + + +
    Beschreibung:Bestimmt die maximale Anzahl interner Umleitungen und + verschachtelter Unteranfragen
    Syntax:LimitInternalRecursion Zahl [Zahl]
    Voreinstellung:LimitInternalRecursion 10
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    Kompatibilität:Verfügbar ab Apache 2.0.47
    +

    Eine interne Umleitung erfolgt beispielsweise, wenn die Direktive + Action verwendet wird, welche + die Originalanfrage intern zu einem CGI-Skript weiterleitet. Eine + Unteranfrage (Anm.d.Ü.: engl. Subrequest) ist ein Mechanismus des + Apache, um herauszufinden, was bei einer URI geschehen würde, wäre + sie angefordert worden. mod_dir z.B. verwendet + Unteranfragen, um nach den Dateien zu suchen, die in der DirectoryIndex-Anweisung aufgeführt + sind.

    + +

    LimitInternalRecursion bewahrt den Server vor + einem Absturz, wenn er in eine Endlosschleife aus internen Umleitungen + oder Unteranfragen hineinläuft. Derartige Schleifen werden + gewöhnlich durch Fehlkonfiguration verursacht.

    + +

    Die Direktive setzt zwei verschiedene Begrenzungen, welche je Anfrage + ausgewertet werden. Die erste Zahl bestimmt die maximale + Anzahl der Umleitungen, die aufeinander folgen dürfen. Die zweite + Zahl legt fest, wie tief Unteranfragen ineinander + verschachtelt werden dürfen. Wenn Sie lediglich eine Zahl + angeben, wird sie beiden Begrenzungen zugewiesen.

    + +

    Beispiel

    + LimitInternalRecursion 5 +

    + +
    +
    top
    +

    LimitRequestBody-Direktive

    + + + + + + + + +
    Beschreibung:Begrenzt die Gesamtgröße des vom Client gesendeten +HTTP-Request-Body
    Syntax:LimitRequestBody Bytes
    Voreinstellung:LimitRequestBody 0
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Die Direktive gibt die Anzahl der Bytes zwischen 0 + (unbegrenzt) und 2147483647 (2GB) an, die im Request-Body (Datenteil der + Anfrage) erlaubt sind.

    + +

    Die Direktive LimitRequestBody erlaubt es dem + Benutzer, die Größe des HTTP-Request-Bodys in dem Kontext zu + begrenzen, in dem die Anweisung angegeben ist (Server, pro Verzeichnis, + pro Datei oder pro Adresse). Wenn die Anfrage des Clients dieses Limit + überschreitet, gibt der Server einen Fehler zurück anstatt die + Anfrage zu bearbeiten. Die Größe des Datenteils einer Anfrage + kann sehr stark variieren, abhängig von der Art der Ressource und + den für diese Ressource erlaubten Methoden. CGI-Skripte verwenden + den Datenteil üblicherweise zum Empfang von Formulardaten. Wird + die PUT-Methode angewendet, dann muss der Wert mindestens + so groß sein wie irgendeine Darstellungsform, die der Server + für diese Ressource akzeptieren soll.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Wenn Sie beispielsweise das Hochladen von Dateien zu einer bestimmten + Adresse erlauben, aber die Größe der hochgeladenen Dateien + auf 100K beschränken wollen, können Sie die folgende Anweisung + verwenden:

    + +

    + LimitRequestBody 102400 +

    + + +
    +
    top
    +

    LimitRequestFields-Direktive

    + + + + + + + +
    Beschreibung:Begrenzt die Anzahl der HTTP-Request-Header, die vom Client +entgegengenommen werden
    Syntax:LimitRequestFields Anzahl
    Voreinstellung:LimitRequestFields 100
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Anzahl ist ein Integer-Wert (eine positive Ganzzahl) + zwischen 0 (unbegrenzt) und 32767. Die Voreinstellung wird durch die + Konstante DEFAULT_LIMIT_REQUEST_FIELDS (100 + bei der Auslieferung) zur Kompilierungszeit gesetzt.

    + +

    Die Direktive LimitRequestFields erlaubt es + dem Serveradministrator, die maximale Anzahl der in einem HTTP-Request + erlaubten HTTP-Request-Header zu verändern. Für den Server + muss dieser Wert größer sein als die Anzahl der Headerzeilen, + die ein normaler Client senden könnte. Die Anzahl der Request-Header, + die ein gewöhnlicher Client verwendet, überschreitet selten 20 + Zeilen. Allerdings kann dies zwischen den verschiedenen + Client-Ausführungen variieren, oft abhängig vom Ausmaß, + mit dem der Anwender die genaue Content-Negotiation-Unterstützung + seines Browsers konfiguriert hat. Optionale HTTP-Erweiterungen + äußern sich oft in Form von HTTP-Headern.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann. Der Wert sollte erhöht werden, wenn normale Clients + eine Fehlermeldung vom Server erhalten, die besagt, dass mit der Anfrage + zu viele Headerzeilen gesendet wurden.

    + +

    Beispiel:

    + +

    + LimitRequestFields 50 +

    + + +
    +
    top
    +

    LimitRequestFieldSize-Direktive

    + + + + + + + +
    Beschreibung:Begrenzt die Länge des vom Client gesendeten +HTTP-Request-Headers
    Syntax:LimitRequestFieldsize Bytes
    Voreinstellung:LimitRequestFieldsize 8190
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Die Direktive gibt die Anzahl der Bytes an, die in einem + HTTP-Header erlaubt sind.

    + +

    Die Direktive LimitRequestFieldsize erlaubt es + dem Serveradministrator, die maximale Größe eines + HTTP-Request-Headers zu verringern oder erhöhen. Für den Server + muss der Wert groß genug sein, um eine beliebige Headerzeile einer + normalen Client-Anfrage vorzuhalten. Die Größe variiert stark + zwischen den verschiedenen Client-Ausführungen, oft abhängig vom + Ausmaß, mit dem der Anwender die genaue + Content-Negotiation-Unterstützung seines Browsers konfiguriert hat. + SPNEGO-Authentisierungs-Header können bis zu 12392 Bytes lang + sein.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Beispiel:

    + +

    + LimitRequestFieldSize 4094 +

    + +
    Unter normalen Umständen sollte die Voreinstellung nicht + verändert werden.
    + +
    +
    top
    +

    LimitRequestLine-Direktive

    + + + + + + + +
    Beschreibung:Begrenzt die Länge der vom Client entgegengenommenen +HTTP-Anfragezeile
    Syntax:LimitRequestLine Bytes
    Voreinstellung:LimitRequestLine 8190
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Die Direktive legt die Anzahl der Bytes fest, die in der + HTTP-Anfragezeile erlaubt sind.

    + +

    Die Direktive LimitRequestLine erlaubt es dem + Serveradministrator, die maximale Größe der + HTTP-Anfragezeile zu verringern oder erhöhen. Da + die Anfragezeile aus der HTTP-Methode, der URI und der Protokollversion + besteht, bedeutet die LimitRequestLine-Direktive + eine Beschränkung der Länge der für eine Anfrage an den + Server erlaubten Anfrage-URI. Für den Server muss der Wert groß + genug sein, um jeden seiner Ressourcennamen vorzuhalten, + einschließlich aller Informationen, die im Query-String einer + GET-Anfrage übergeben werden können.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Beispiel:

    + +

    + LimitRequestLine 4094 +

    + +
    Unter normalen Umständen sollte die Voreinstellung nicht + verändert werden.
    + +
    +
    top
    +

    LimitXMLRequestBody-Direktive

    + + + + + + + + +
    Beschreibung:Begrenzt die Größe eines XML-basierten +Request-Bodys
    Syntax:LimitXMLRequestBody Bytes
    Voreinstellung:LimitXMLRequestBody 1000000
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Dies gibt die Grenze für die maximale Größe (in Bytes) + des XML-basierten Request-Bodys an. Der Wert 0 deaktiviert + diese Prüfung.

    + +

    Beispiel:

    + +

    + LimitXMLRequestBody 0 +

    + + +
    +
    top
    +

    <Location>-Direktive

    + + + + + + +
    Beschreibung:Wendet die enthaltenen Direktiven nur auf die entsprechenden +URLs an
    Syntax:<Location + URL-Pfad|URL> ... </Location>
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive <Location> + begrenzt die Reichweite der enthaltenen Anweisungen auf URLs. + Sie ist der Direktive <Directory> ähnlich und startet einen + Abschnitt, der mit der Anweisung </Location> + abgeschlossen wird. <Location>-Container werden, nachdem die + <Directory>-Container + und .htaccess-Dateien gelesen wurden, und nach den + <Files>-Containern, in + der Reihenfolge ausgeführt, in der sie in der Konfigurationsdatei + erscheinen.

    + +

    <Location>-Abschnitte operieren + vollständig außerhalb des Dateisystems. Dies hat mehrere + Konsequenzen. An Wichtigsten, <Location>-Anweisungen sollten nicht dafür + verwendet werden, den Zugriff zu Teilen des Dateisystems zu steuern. Da + mehrere unterschiedliche URLs auf die gleiche Stelle des Dateisystems + zeigen können, könnte eine solche Zugriffskontrolle u.U. + umgangen werden.

    + +

    Wann sollte<Location> verwendet werden

    + +

    Verwenden Sie <Location>, um + Anweisungen auf Inhalte anzuwenden, die außerhalb des Dateisystems + abgelegt sind. Benutzen Sie <Directory> und <Files> für Inhalte, die + innerhalb des Dateisystems abgelegt sind. Eine Ausnahme bildet + <Location />, welches ein einfacher Weg ist, um eine + Konfiguration auf den gesamten Server anzuwenden.

    +
    + +

    Für alle nicht-Proxy-Anfragen ist die entsprechende URL + ein URL-Pfad in der Form /path/. Es dürfen weder ein + Schema, noch ein Hostname, noch ein Port, noch ein Query-String einbezogen + werden. Für Proxy-Anfragen hat die Vergleichs-URL die Form + schema://servername/path. Das Präfix muss angegeben + werden.

    + +

    Die URL kann Platzhalter verwenden. In einer Zeichenfolge mit + Platzhaltern entspricht ? einem einzelnen Zeichen und + *einer beliebigen Zeichenfolge.

    + +

    Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt + wird. Beispielsweise würde

    + +

    + <Location ~ "/(extra|special)/data"> +

    + +

    auf URLs passen, welche die Zeichenfolge /extra/data + oder /special/data enthalten. Die Direktive <LocationMatch> verhält sich + genauso wie <Location> mit + regulären Ausdrücken.

    + +

    Die Funktionalität von <Location> ist insbesondere dann nützlich, + wenn sie mit der SetHandler-Direktive + kombiniert wird. Um zum Beispiel Statusabfragen zu aktivieren, sie aber + nur von Browsern aus foo.com zuzulassen, könnten Sie + schreiben:

    + +

    + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +

    + +

    Anmerkung zu / (Schrägstrich, Slash)

    +

    Das Slash-Zeichen hat eine besondere Bedeutung, je nachdem, wo es + in der URL erscheint. Manche werden sein Verhalten vom Dateisystem + gewohnt sein, wo mehrere aufeinanderfolgende Schrägstriche + häufig zu einem Schrägstrich zusammengefaßt werden + (d.h. /home///foo ist das gleiche wie + /home/foo). Im URL-Raum ist dies nicht notwendigerweise + genauso. Bei der Direktive <LocationMatch> und der <Location>-Version mit regulären Ausdrücken + müssen Sie explizit mehrere Schrägstriche angeben, wenn Sie + genau dies beabsichtigen.

    + +

    Beispielsweise würde <LocationMatch ^/abc> + auf die angeforderte URL /abc passen, nicht aber auf + //abc. Die Direktive <Location> (ohne reguläre Ausdrücke) verhält + sich ähnlich, wenn sie für Proxy-Anfragen verwendet wird. + Wenn <Location> (ohne + reguläre Ausdrücke) jedoch für nicht-Proxy-Anfragen + verwendet wird, werden stillscheigend mehrere Schrächstriche mit + mit einem einzigen Schrägstrich gleichgesetzt. Geben Sie + beispielsweise <Location /abc/def> an und die + Anfrage lautet auf /abc//def, dann greift die Anweisung.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    <LocationMatch>-Direktive

    + + + + + + +
    Beschreibung:Wendet die enthaltenen Direktiven nur auf URLs an, die auf +reguläre Ausdrücke passen
    Syntax:<LocationMatch + regex> ... </LocationMatch>
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive <LocationMatch> + begrenzt die Reichweite der enthaltenen Anweisungen in der gleichen Weise + wie <Location> auf URLs. + Sie verwendet jedoch reguläre Ausdrücke als Argument anstelle + einer einfachen Zeichenkette. Beispielsweise würde

    + +

    + <LocationMatch "/(extra|special)/data"> +

    + +

    auf URLs passen, welche die Zeichenfolge /extra/data + oder /special/data enthalten.

    + +

    Siehe auch

    + +
    +
    top
    +

    LogLevel-Direktive

    + + + + + + + +
    Beschreibung:Steuert die Ausführlichkeit des Fehlerprotokolls
    Syntax:LogLevel Level
    Voreinstellung:LogLevel warn
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    LogLevel stellt die Ausführlichkeit + der Nachrichten ein, die im Fehlerprotokoll aufgezeichnet werden (siehe + Direktive ErrorLog). Die folgenden, + nach absteigender Aussagekraft sortierten Level sind + verfügbar:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level Beschreibung Beispiel
    emerg Notfall - das System ist unbenutzbar."Child cannot open lock file. Exiting" + (Anm.d.Ü.: "Kindprozess kann die Lock-Datei nicht öffnen. + Beende Programm")
    alert Maßnahmen müssen unverzüglich ergriffen + werden."getpwuid: couldn't determine user name from uid" + (Anm.d.Ü.: "getpwuid: kann keinen Benutzernamen aus der UID + ermitteln")
    crit Kritischer Zustand."socket: Failed to get a socket, exiting child" + (Anm.d.Ü.: "socket: Socket-Zuweisung fehlgeschlagen, beende + Kindprozess")
    error Fehlerbedingung."Premature end of script headers" + (Anm.d.Ü.: "Vorzeitiges Ende der Skript-Header")
    warn Warnung."child process 1234 did not exit, sending another SIGHUP" + (Anm.d.Ü.: "Kindprozess 1234 nicht beendet, sende ein weiteres + SIGHUP")
    notice Normaler, aber signifikanter Zustand."httpd: caught SIGBUS, attempting to dump core in ..." + (Anm.d.Ü.: "httpd: SIGBUS empfangen, versuche Speicherabbild nach ... + zu schreiben")
    info Information."Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..." + (Anm.d.Ü.: "Server scheint beschäftigt zu sein, + (möglicherweise müssen Sie StartServers oder + Min/MaxSpareServers erhöhen)")
    debug Debug-Level-Nachrichten"Opening config file ..." + (Anm.d.Ü.: "Öffne Konfigurationsdatei ...")
    + +

    Geben Sie einen bestimmten Level an, denn werden Nachrichten von + allen höheren Leveln ebenso angezeigt. Z.B.: Wenn + LogLevel info eingestellt ist, dann werden Nachrichten der + Log-Level notice und warn ebenso eingetragen.

    + +

    Es wird empfohlen, mindestens den Level crit zu + verwenden.

    + +

    Beispiel:

    + +

    + LogLevel notice +

    + +

    Hinweis

    +

    Beim Protokollieren in eine reguläre Datei können + Nachrichten des Levels notice nicht unterdrückt + werden und werden daher immer protokolliert. Dies trifft allerdings + nicht zu, wenn mittels syslog protokolliert wird.

    +
    + +
    +
    top
    +

    MaxKeepAliveRequests-Direktive

    + + + + + + + +
    Beschreibung:Anzahl der Anfragen, die bei einer persistenten Verbindung +zulässig sind
    Syntax:MaxKeepAliveRequests Anzahl
    Voreinstellung:MaxKeepAliveRequests 100
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive MaxKeepAliveRequests + begrenzt die Anzahl der Anfragen, die pro Verbindung zulässig sind, + wenn KeepAlive eingeschaltet ist. + Bei der Einstellung 0 sind unbegrenzt viele Anfragen + erlaubt. Wir empfehlen für diese Einstellung einen hohen Wert + für eine maximale Serverleistung.

    + +

    Beispiel:

    + +

    + MaxKeepAliveRequests 500 +

    + +
    +
    top
    +

    NameVirtualHost-Direktive

    + + + + + + +
    Beschreibung:Bestimmt eine IP-Adresse für den Betrieb namensbasierter +virtueller Hosts
    Syntax:NameVirtualHost Adresse[:Port]
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Die Direktive NameVirtualHost ist erforderlich, + wenn Sie namensbasierte virtuelle Hosts + konfigurieren möchten.

    + +

    Obwohl Adresse eine Hostname sein kann, wird empfohlen, + dass Sie stets eine IP-Adresse verwenden, z.B.:

    + +

    + NameVirtualHost 111.22.33.44 +

    + +

    Mit der NameVirtualHost-Anweisung geben Sie + die IP-Adresse an, unter der der Server Anfragen für + namensbasierte virtuelle Hosts entgegennimmt. Das ist üblicherweise + die Adresse, zu der die Namen Ihrer namensbasierten virtuellen Hosts + aufgelöst werden. Falls eine Firewall oder ein anderer Proxy die + Anfrage in Empfang nimmt und Sie zu einer weiteren IP-Adresse des Servers + weiterleitet, müssen Sie die IP-Adresse der physikalischen + Schnittstelle der Maschine angeben, welche die Anfragen bedient. + Wenn Sie mehrere namensbasierte Hosts an verschiedenen Adressen + betreiben, wiederholen Sie einfach die Anweisung für jede + Adresse.

    + +

    Anmerkung

    +

    Beachten Sie, dass der "Hauptserver" und jeder + _default_-Server niemals bei einer + Anfrage an einer NameVirtualHost-IP-Adresse + bedient wird (es sei denn, Sie geben aus irgendwelchen Gründen + NameVirtualHost an, definieren dann aber keine + VirtualHosts für diese Adresse).

    +
    + +

    Optional können Sie die Nummer eines Ports angeben, an dem + namensbasierte virtuelle Hosts verwendet werden sollen. Beispiel:

    + +

    + NameVirtualHost 111.22.33.44:8080 +

    + +

    IPv6-Adressen müssen, wie im folgenden Beispiel angegeben, in + eckige Klammern eingeschlossen werden:

    + +

    + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 +

    + +

    Um an allen Schnittstellen Anfragen zu empfangen, können Sie + * als Argument verwenden.

    + +

    + NameVirtualHost * +

    + +

    Argument der Direktive <VirtualHost>

    +

    Beachten Sie, dass das Argument der <VirtualHost>-Anweisung exakt auf das Argument + der NameVirtualHost-Anweisung passen muss.

    + +

    + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    Options-Direktive

    + + + + + + + + +
    Beschreibung:Definiert, welche Eigenschaften oder Funktionen in einem +bestimmten Verzeichnis verfügbar sind
    Syntax:Options + [+|-]Option [[+|-]Option] ...
    Voreinstellung:Options All
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:Options
    Status:Core
    Modul:core
    +

    Die Direktive Options steuert, welche + Eigenschaften bzw. Funktionen in einem bestimmten Verzeichnis + verfügbar sind.

    + +

    Option kann auf None gesetzt werden, wobei + keine der besonderen Eigenschaften verfügbar sind, oder auf eines + oder mehrere der folgenden:

    + +
    +
    All
    + +
    Alle Optionen außer MultiViews. Dies ist + die Voreinstellung.
    + +
    ExecCGI
    + +
    Die Ausführung von CGI-Skripten, welche mod_cgi + verwenden, ist erlaubt.
    + +
    FollowSymLinks
    + +
    Der Server folgt symbolischen Links in diesem Verzeichnis. +
    +

    Auch wenn der Server symbolischen Links folgt, bedeutet dies + nicht, dass der zum Abgleich gegen <Directory>-Abschnitte verwendete Pfadname + wechselt.

    +

    Beachten Sie auch, dass diese Option innerhalb eines + <Location>-Abschnitts + ignoriert wird.

    +
    + +
    Includes
    + +
    + Server Side Includes, die von mod_include bereitgestellt + werden, sind erlaubt.
    + +
    IncludesNOEXEC
    + +
    Server Side Includes sind erlaubt, #exec cmd + und #exec cgi sind jedoch deaktiviert. Es ist aber noch + möglich, CGI-Skripte aus + ScriptAlias-Verzeichnissen mittels + #include virtual einzubinden.
    + +
    Indexes
    + +
    Wenn eine URL, die auf ein Verzeichnis zeigt, in dem sich keine durch + DirectoryIndex definierte + Indexdatei (z.B. index.html) befindet, dann liefert + mod_autoindex eine formatierte Auflistung des + Verzeichnisses zurück.
    + +
    MultiViews
    + +
    "MultiViews" sind bei der Verwendung von + mod_negotiation erlaubt (siehe Content-Negotiation).
    + +
    SymLinksIfOwnerMatch
    + +
    Der Server folgt nur symbolischen Links, bei denen die Zieldatei + bzw. das Zielverzeichnis der gleichen Benutzerkennung gehört, wie + der Link. +

    Anmerkung

    Diese Option wird innerhalb eines + <Location>-Abschnitts + ignoriert.
    +
    + +

    Wenn mehrere Options auf ein Verzeichnis + angewandt werden können, dann wird normalerweise die + spezifischste (Anm.d.Ü.: Gemeint ist die zuletzt + ausgeführte Option.) verwendet und alle anderen werden + ignoriert; die Optionen werden nicht vermischt. (Siehe auch Wie Abschnitte zusammengeführt + werden..) Wenn jedoch allen Optionen der + Options-Anweisung eines der Zeichen + + oder - vorangestellt wird, werden die Optionen + zusammengemischt. Jede Option mit vorangestelltem + wird + zu den momentan gültigen Optionen hinzugefügt und jede Option + mit vorangestelltem - wird aus den derzeit gültigen + Optionen entfernt.

    + +

    So wird zum Beispiel ohne die Zeichen + und + -

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +

    + +

    für das Verzeichnis /web/docs/spec wird jetzt + lediglich Includes gesetzt. Wenn die zweite + Options-Anweisung jedoch +- + und --Zeichen verwenden würde,

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +

    + +

    dann würden die Optionen FollowSymLinks und + Includes für das Verzeichnis /web/docs/spec + gesetzt.

    + +

    Anmerkung

    +

    Die Verwendung von -IncludesNOEXEC oder + -Includes deaktiviert Server Side Includes unabhängig + von der vorigen Einstellung vollständig.

    +
    + +

    Die Voreinstellung ist All, sofern keine anderen Angaben + gemacht wurden.

    + +
    +
    top
    +

    Require-Direktive

    + + + + + + + +
    Beschreibung:Wählt die authentisierten Benutzer aus, die auf eine +Ressource zugreifen können
    Syntax:Require Name [Name] ...
    Kontext:Verzeichnis, .htaccess
    AllowOverride:AuthConfig
    Status:Core
    Modul:core
    +

    Die Direktive wählt aus, welche authentisierten Benutzer auf eine + Ressource zugreifen dürfen. Folgende Syntax ist erlaubt:

    + +
    +
    Require user User-ID [User-ID] + ...
    +
    Nur die genannten Benutzer dürfen auf die Ressource + zugreifen.
    + +
    Require group Gruppenname [Gruppenname] + ...
    +
    Nur Benutzer der genannten Gruppen dürfen auf die + Ressource zugreifen.
    + +
    Require valid-user
    +
    Alle gültigen Benutzer dürfen auf die Ressource + zugreifen.
    +
    + +

    Require muss von den Direktiven + AuthName und AuthType sowie Direktiven wie + AuthUserFile + und AuthGroupFile + (zur Definition von Benutzern und Gruppen) begleitet werden, um + korrekt zu funktionieren. Beispiel:

    + +

    + AuthType Basic
    + AuthName "Geschützte Ressource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +

    + +

    Zugriffskontrollen, die in dieser Form angewandt werden, gelten + für alle Methoden. Dies ist normalerweise + gewünscht. Wenn Sie Zugriffskontrollen nur auf bestimmte + Methoden anwenden möchten, während andere Methoden + ungeschützt bleiben, dann müssen Sie die + Require-Anweisung innerhalb eines + <Limit>-Abschnitts + platzieren.

    + +

    Siehe auch

    + +
    +
    top
    +

    RLimitCPU-Direktive

    + + + + + + + + +
    Beschreibung:Begrenzt den CPU-Verbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden
    Syntax:RLimitCPU Sekunden|max [Sekunden|max]
    Voreinstellung:unbestimmt; verwendet die Voreinstellung des Systems
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Das beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    CPU-Ressourcenbegrenzung wird in Sekunden pro Prozess + ausgedrückt.

    + +

    Siehe auch

    + +
    +
    top
    +

    RLimitMEM-Direktive

    + + + + + + + + +
    Beschreibung:Begrenzt den Speicherverbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden
    Syntax:RLimitMEM Bytes|max [Bytes|max]
    Voreinstellung:unbestimmt; verwendet die Voreinstellung des Systems
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Das beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    Die Begrenzung des Speicherverbrauchs wird in Bytes pro Prozess + ausgedrückt.

    + +

    Siehe auch

    + +
    +
    top
    +

    RLimitNPROC-Direktive

    + + + + + + + + +
    Beschreibung:Begrenzt die Anzahl der Prozesse, die von Prozessen gestartet +werden können, der ihrerseits von Apache-Kinprozessen gestartet +wurden
    Syntax:RLimitNPROC Zahl|max [Zahl|max]
    Voreinstellung:unbestimmt; verwendet die Voreinstellung des Systems
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Dies beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    Prozessbegrenzungen steuern die Anzahl der Prozesse pro Benutzer.

    + +

    Anmerkung

    +

    Wenn CGI-Prozesse nicht unter anderen Benutzerkennungen als der + User-ID des Webservers laufen, dann beschränkt diese Direktive + die Anzahl der Prozesse, die der Server selbst erstellen kann. + Kennzeichen einer solchen Situation sind + cannot fork-Meldungen + (Anm.d.Ü.: kann nicht abspalten) in der + Datei error_log.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    Satisfy-Direktive

    + + + + + + + + + +
    Beschreibung:Zusammenspiel von rechnerbasierter Zugriffskontrolle und +Benutzerauthentisierung
    Syntax:Satisfy Any|All
    Voreinstellung:Satisfy All
    Kontext:Verzeichnis, .htaccess
    AllowOverride:AuthConfig
    Status:Core
    Modul:core
    Kompatibilität:Wird seit Version 2.0.51 von <Limit> und <LimitExcept> beeinflusst
    +

    Verfahrensweise für den Zugriff, falls sowohl Allow als auch Require verwendet werden. Der Parameter kann + entweder All oder Any sein. Die Direktive ist + nur dann nützlich, wenn der Zugriff zu einem bestimmten Bereich + durch Benutzername/Passwort und Clientrechner-Adressen + eingeschränkt ist. In diesem Fall verlangt die Voreinstellung + (All), dass der Client die Adressbeschränkung passiert + und eine gültige Benutzerkennung und ein gültiges + Passwort übermittelt. Mit der Auswahl Any wird dem + Client der Zugriff erlaubt, wenn er entweder die Rechner-Beschänkung + passiert oder einen gültigen Benutzernamen und ein gültiges + Passwort übermittelt. Dies kann verwendet werden, um einen Bereich + mit einem Passwort zu schützen, jedoch Clients von bestimmten + Adressen ohne Abfrage des Passwortes zuzulassen.

    + +

    Wenn Sie beispielsweise möchten, dass Personen aus Ihrem + privaten Netzwerk unbechänkten Zugriff zu Teilen Ihres + Webangebots haben, jedoch verlangen, dass Personen außerhalb + Ihres privaten Netzwerks ein Passwort übergeben müssen, + können Sie eine Konfiguration ähnlich der folgenden + verwenden:

    + +

    + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +

    + +

    Seit Version 2.0.51 können + Satisfy-Anweisungen durch <Limit>- und <LimitExcept>-Abschnitte auf bestimmte Methoden + beschränkt werden.

    + +

    Siehe auch

    + +
    +
    top
    +

    ScriptInterpreterSource-Direktive

    + + + + + + + + + +
    Beschreibung:Methode zur Ermittlung des Interpreters von +CGI-Skripten
    Syntax:ScriptInterpreterSource Registry|Registry-Strict|Script
    Voreinstellung:ScriptInterpreterSource Script
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:ausschließlich Win32; +Die Option Registry-Strict ist verfügbar seit Apache +2.0.
    +

    Die Direktive steuert, wie der Apache den Interpreter zur Ausführung + von CGI-Skripten bestimmt. Die Voreinstellung ist Script. Dies + veranlaßt den Apache, den Interpreter zu verwenden, auf den die + Shebang-Zeile (erste Zeile, beginnt mit #!) im Skript zeigt. + Auf Win32-Systemen sieht diese Zeile üblicherweise so aus:

    + +

    + #!C:/Perl/bin/perl.exe +

    + +

    oder, wenn perl im Pfad (Umgebungsvariable PATH) liegt, + einfach:

    + +

    + #!perl +

    + +

    Die Einstellung ScriptInterpreterSource Registry + veranlaßt eine Suche in HKEY_CLASSES_ROOT der + Windows-Registrierungsdatenbank und verwendet die Endung der Skript-Datei + (z.B. .pl) als Suchargument. Der durch den Unterschlüssel + Shell\ExecCGI\Command oder, falls dieser nicht existiert, + Shell\Open\Command definierte Befehl wird zum Öffnen der + Skript-Datei verwendet. Wenn der Schlüssel zur Dateiendung oder + beide Unterschlüssel fehlen, dann verwendet der Apache die Option + Script.

    + +

    Sicherheit

    +

    Seien Sie vorsichtig, ScriptInterpreterSource Registry bei + Verzeichnissen zu verwenden, auf die eine ScriptAlias-Anweisung zeigt, denn der + Apache versucht jede Datei innerhalb des Verzeichnisses + auszuführen. Die Einstellung Registry kann + unerwünschte Programmaufrufe bei Dateien verursachen, die + üblicherweise nicht ausgeführt werden. Auf den meisten + Windows-Systemen beispielsweise startet der voreingestellte + Öffnen-Befehl für .htm-Dateien den Microsoft + Internet Explorer, so dass jede HTTP-Anfrage nach einer existierenden + .htm-Datei im Skript-Verzeichnis den Browser im Hintergrund + starten würde. Dies ist eine wirksame Methode, Ihr System binnen + etwa einer Minute zum Absturz zu bringen.

    +
    + +

    Die seit Apache 2.0 neue Option Registry-Strict + macht das gleiche wie Registry, verwendet jedoch nur den + Unterschlüssel Shell\ExecCGI\Command. Der Schlüssel + ExecCGI ist gewöhnlich nicht voreingestellt. Er muss + manuell eingerichtet werden und schützt Ihr System so for + versehentlichen Programmaufrufen.

    + +
    +
    top
    +

    ServerAdmin-Direktive

    + + + + + + +
    Beschreibung:E-Mail-Adresse, die der Server in Fehlermeldungen einfügt, +welche an den Client gesendet werden
    Syntax:ServerAdmin E-Mail-Adresse|URL
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    +

    ServerAdmin legt die Kontaktadresse fest, + die der Server in jede Fehlermeldung einfügt, die er an den + Client zurückschickt. Wenn httpd das übergebene + Argument nicht als URL erkennt, nimmt er an, dess es sich um eine + E-Mail-Adresse handelt und stellt in Hyperlinks + mailto: voran. Es ist jedoch sogar sinnvoll, eine + E-Mail-Adresse zu verwenden, da viele CGI-Skripte davon ausgehen. Wenn Sie + eine URL verwenden möchten, sollten Sie auf einem anderen unter Ihrer + Kontrolle stehenden Server verweisen. Andernfalls können Besucher Sie + im Fehlerfall möglicherweise nicht kontaktieren.

    + +

    Es kann sich lohnen, hierfür eine reservierte Adresse + anzugeben, z.B.

    + +

    + ServerAdmin www-admin@foo.example.com +

    + +

    da Anwender nicht unbedingt erwähnen, dass sie vom Server + sprechen!

    + +
    +
    top
    +

    ServerAlias-Direktive

    + + + + + + +
    Beschreibung:Alternativer Name für einen Host, der verwendet wird, wenn +Anfragen einem namensbasierten virtuellen Host zugeordnet werden
    Syntax:ServerAlias Hostname [Hostname] ...
    Kontext:Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive ServerAlias bestimmt die + alternativen Namen eines Hosts zur Verwendung mit namensbasierten virtuellen Hosts.

    + +

    + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +

    + +

    Siehe auch

    + +
    +
    top
    +

    ServerName-Direktive

    + + + + + + + +
    Beschreibung:Rechnername und Port, die der Server dazu verwendet, sich +selbst zu identifizieren
    Syntax:ServerName +voll-qualifizierter-Domainname[:port]
    Kontext:Serverkonfiguration, Virtual Host
    Status:Core
    Modul:core
    Kompatibilität:Diese Direktive löst in Version 2.0 die + Funktionalität der Direktive Port aus + Version 1.3 ab.
    +

    Die Direktive ServerName bestimmt den + Rechnernamen und Port, den der Server dazu verwendet, sich selbst + zu identifizieren. Diese werden bei der Erstellung von Umleitungs-URLs + benötigt. Wenn beispielsweise der Name der Maschine, die den Webserver + beherbergt, simple.example.com lautet, die Maschine jedoch + auch einen DNS-Alias www.example.com besitzt und Sie den + Webserver so identifizieren möchten, sollten Sie die folgende + Anweisung verwenden:

    + +

    + ServerName www.example.com:80 +

    + +

    Wenn kein ServerName angegeben wurde, + dann versucht der Server den Rechnernamen mittels eines Reverse-Lookup + herzuleiten. Wenn kein Port in der + ServerName-Anweisung angegeben wurde, dann + verwendet der Server den Port der eingegangenen Anfrage. Für eine + optimale Zuverlässigkeit und Berechenbarkeit sollten Sie einen + eindeutigen Rechnernamen und Port angeben, in dem Sie die Direktive + ServerName verwenden.

    + +

    Wenn Sie namensbasierte + virtuelle Hosts verwenden, gibt ServerName + innerhalb eines <VirtualHost>-Abschnitts an, welcher + Hostname im Host:-Header der Anfrage auftauchen muss, + damit sie diesem virtuellen Host zugeordnet wird.

    + +

    Lesen Sie bitte die Beschreibung der Direktive UseCanonicalName für Einstellungen, die + bestimmen, ob selbstreferenzierende URLs (z.B. vom Modul + mod_dir) auf den angegebenen Port zeigen oder auf die + Portnummern die in der Anfrage des Clients angegeben ist.

    + +

    Siehe auch

    + +
    +
    top
    +

    ServerPath-Direktive

    + + + + + + +
    Beschreibung:Veralteter URL-Pfad für einen namensbasierten +virtuellen Host, auf den von einem inkompatiblen Browser zugegriffen +wird
    Syntax:ServerPath URL-Pfad
    Kontext:Virtual Host
    Status:Core
    Modul:core
    +

    Die Direktive ServerPath legt den + veralteten (Anm.d.Ü.: Gemeint ist eigentlich "Altlast" aufgrund + antiquierter Clients.) URL-Pfad eines Hosts zur Verwendung mit + namensbasierten virtuellen Hosts fest.

    + +

    Siehe auch

    + +
    +
    top
    +

    ServerRoot-Direktive

    + + + + + + + +
    Beschreibung:Basisverzeichnis der Serverinstallation
    Syntax:ServerRoot Verzeichnis
    Voreinstellung:ServerRoot /usr/local/apache
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Die Direktive ServerRoot bestimmt das + Verzeichnis, in dem der Server installiert ist. Üblicherweise + enthält es die Unterverzeichnisse conf/ und + logs/. Relative Pfadangaben anderer Direktiven (wie z.B. + Include oder LoadModule) werden relativ zu diesem + Verzeichnis betrachtet.

    + +

    Beispiel

    + ServerRoot /home/httpd +

    + +

    Siehe auch

    + +
    +
    top
    +

    ServerSignature-Direktive

    + + + + + + + + +
    Beschreibung:Konfiguriert die Fußzeile von servergenerierten +Dokumenten
    Syntax:ServerSignature On|Off|EMail
    Voreinstellung:ServerSignature Off
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:All
    Status:Core
    Modul:core
    +

    Die Direktive ServerSignature ermöglicht + die Gestaltung einer unter servergenerierten Dokumenten (z.B. + Fehlerdokumente, FTP-Verzeichnislisten von mod_proxy, + mod_info-Ausgaben, ...) angefügten + Fußzeile. Ein möglicher Grund für die Aktivierung einer + solchen Fußzeile ist, dass der Anwender bei einer Kette von + Proxy-Servern oft keine Möglichkeit hat, zu erkennen, welcher der + verketteten Server gegenwärtig die zurückgegebene Fehlermeldung + produziert hat.

    + +

    Die (Vor-)Einstellung Off unterdrückt die + Fußzeile (und ist damit kompatibel zum Verhalten des Apache 1.2 und + früher). Die Einstellung On fügt schlicht eine + Zeile mit der Versionsnummer des Servers und dem Servernamen (ServerName) des bedienenden virtuellen Hosts an. + Die Einstellung EMail erstellt zusätzlich einen + "mailto:"-Verweis zum Serveradministrator (ServerAdmin) des referenzierten Dokuments.

    + +

    Ab Version 2.0.44 werden die Details der angegebenen Versionsnummer des + Servers von der Direktive ServerTokens kontrolliert.

    + +

    Siehe auch

    + +
    +
    top
    +

    ServerTokens-Direktive

    + + + + + + + +
    Beschreibung:Konfiguriert den HTTP-Response-Header +Server
    Syntax:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
    Voreinstellung:ServerTokens Full
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    die Direktive steuert, ob der Response-Header Server, + der an den Client zurückgesendet wird, eine Beschreibung des + allgemeinen Betriesbsystemtyps des Servers wie auch Informationen + über einkompilierte Module enthält.

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    Der Server sendet (z.B.): Server: + Apache
    + +
    ServerTokens Major
    + +
    Der Server sendet (z.B.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Der Server sendet (z.B.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    Der Server sendet (z.B.): Server: + Apache/2.0.41
    + +
    ServerTokens OS
    + +
    Der Server sendet (z.B.): Server: Apache/2.0.41 + (Unix)
    + +
    ServerTokens Full (oder nicht angegeben)
    + +
    Der Server sendet (z.B.): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2
    +
    + +

    Diese Einstellung gilt für den gesamten Server und kann nicht + auf Virtual-Host-Basis aktiviert oder deaktiviert werden.

    + +

    Ab Version 2.0.44 steuert diese Direktive auch die Informationen, die + durch die Direktive ServerSignature + angeboten werden.

    + +

    Siehe auch

    + +
    +
    top
    +

    SetHandler-Direktive

    + + + + + + + + +
    Beschreibung:Erzwingt die Verarbeitung aller passenden Dateien durch +einen Handler
    Syntax:SetHandler Handlername|None
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    Kompatibilität:Seit Apache 2.0 im Core
    +

    Wenn die Direktive innerhalb einer .htaccess-Datei + oder in einem <Directory>- oder + <Location>-Abschnitt + angegeben wird, erzwingt sie, dass alle entsprechenden Dateien von dem + durch Handlername angegebenen Handler analysiert werden. Wenn Sie + beispielsweise ein Verzeichnis haben, dessen Dateien unabhängig von + der Endung gänzlich als Image-Maps interpretiert werden sollen, + können Sie folgendes in eine .htaccess-Datei in + dem Verzeichnis schreiben:

    + +

    + SetHandler imap-file +

    + +

    Noch ein Beispiel: wenn Sie den Server immer, wenn die URL + http://servername/status aufgerufen wird, einen + Statusbericht anzeigen lassen möchten, dann können + Sie folgendes in die httpd.conf schreiben:

    + +

    + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +

    +

    Sie können eine zuvor definierte + SetHandler-Anweisung aufheben, indem Sie den Wert + None verwenden.

    + +

    Siehe auch

    + +
    +
    top
    +

    SetInputFilter-Direktive

    + + + + + + + +
    Beschreibung:Bestimmt die Filter, die Client-Anfragen und POST-Eingaben +verarbeiten
    Syntax:SetInputFilter Filter[;Filter...]
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Die Direktive SetInputFilter bestimmt den oder + die Filter, die Client-Anfragen und POST-Eingaben verarbeiten, wenn + sie vom Server empfangen werden. Diese gelten zusätzlich zu + anderweitig definierten Filtern, einschließlich denen der Direktive + AddInputFilter.

    + +

    Wenn mehr als ein Filter angegeben wird, dann müssen diese + durch Semikolon voneinander getrennt in der Reihenfolge angegeben werden, + in der sie die Daten verarbeiten sollen.

    + +

    Siehe auch

    + +
    +
    top
    +

    SetOutputFilter-Direktive

    + + + + + + + +
    Beschreibung:Bestimmt die Filter, die Antworten des Servers verarbeiten
    Syntax:SetOutputFilter Filter[;Filter...]
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Core
    Modul:core
    +

    Die Direktive SetOutputFilter bestimmt + die Filter, die Antworten des Servers verarbeiten, bevor sie an den + Client gesendet werden. Diese gelten zusätzlich zu anderweitig + definierten Filtern, einschließlich denen der Direktive + AddOutputFilter.

    + +

    Die folgende Konfiguration verarbeitet zum Beispiel alle Dateien + im Verzeichnis /www/data als Server Side Includes.

    + +

    + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +

    + +

    Wenn mehr als ein Filter angegeben wird, dann müssen diese + durch Semikolon voneinander getrennt in der Reihenfolge angegeben werden, + in der sie die Daten verarbeiten sollen.

    + +

    Siehe auch

    + +
    +
    top
    +

    TimeOut-Direktive

    + + + + + + + +
    Beschreibung:Zeitspanne, die der Server auf verschiedene Ereignisse wartet, +bevor er die Anfrage abbricht
    Syntax:TimeOut Sekunden
    Voreinstellung:TimeOut 300
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    Die Direktive TimeOut definiert derzeit die + Zeitspanne, die der Apache auf drei Dinge wartet:

    + +
      +
    1. Die gesamte Zeispanne, die benötigt wird, um eine GET-Anfrage + zu empfangen.
    2. + +
    3. Die Zeitspanne zwischen dem Empfang von TCP-Paketen einer + POST- oder PUT-Anfrage.
    4. + +
    5. Die Zeitspanne zwischen ACKs bei der Übermittlung der + TCP-Pakete der Antwort.
    6. +
    + +

    Wir haben vor, diese Zeitspannen in Zukunft separat konfigurierbar zu + machen. Vor Version 1.2 war der Zeitgeber auf 1200 voreingestellt, wurde + dann aber auf 300 herabgesetzt, was immer noch weit mehr ist, als in den + meisten Situationen benötigt wird. Die Voreinstellung wurde nicht + weiter herabgesetzt, da gelegentlich noch Stellen im Code existieren + können, wo der Zeitgeber nicht zurückgesetzt wird, wenn ein + Paket verschickt wird.

    + +
    +
    top
    +

    UseCanonicalName-Direktive

    + + + + + + + +
    Beschreibung:Bestimmt, wie der Server seinen eigenen Namen und Port +ermittelt
    Syntax:UseCanonicalName On|Off|DNS
    Voreinstellung:UseCanonicalName Off
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
    Status:Core
    Modul:core
    +

    In vielen Situationen muss der Apache eine + selbstreferenzierende URL -- d.h. eine URL, die auf den selben + Server zurück verweist -- zusammenbauen. Bei UseCanonicalName + On verwendet der Apache den Hostnamen und Port, der in der + ServerName-Anweisung angegeben ist, + um den kanonischen Namen des Servers zu erstellen. Dieser Name wird in + allen selbstreferenzierenden URLs sowie in CGI-Skripten für die + Werte von SERVER_NAME und SERVER_PORT + verwendet.

    + +

    Bei UseCanonicalName Off bildet der Apache + selbstreferenzierende URLs, indem er den vom Client übermittelten + Hostnamen und Port verwendet, sofern diese vorhanden sind (andernfalls + wird der kanonische Name, wie oben beschrieben, benutzt). Die Werte + sind die gleichen, die zur Anwendung von namensbasierten virtuellen Hosts + verwendet werden, und sie sind mit den gleichen Clients verfügbar + (Anm.d.Ü.: , die auch in der Lage sind, auf namensbasierte virtuelle Hosts + zuzugreifen, d.h. einen Host-Header mitschicken). + Die CGI-Variablen SERVER_NAME und SERVER_PORT + werden ebenfalls aus den vom Client angeboten Werten erstellt.

    + +

    Ein Intranet-Server, auf den Anwender mit kurzen Namen wie + www zugreifen, ist ein Beispiel, wo dies sinnvoll sein kann. + Sie werden bemerken, dass der Apache den Benutzer auf + http://www.domain.com/splat/ umleitet, wenn dieser einen + Kurznamen und eine URL, die einem Verzeichnis entspricht, ohne + abschließenden Schrägstrich eingibt, wie z.B. + http://www/splat. Wenn Sie Authentisierung aktiviert haben, + bewirkt dies, dass der Benutzer sich zweimal identifizieren muss + (einmal für www und noch einmal für + www.domain.com -- lesen Sie für weitere Informationen die + FAQ zu diesem Thema). Wenn UseCanonicalName + jedoch auf Off gesetzt ist, denn wird der Apache zu + http://www/splat/ umleiten.

    + +

    Es existiert noch eine dritte Option, UseCanonicalName DNS, + die für den Betrieb von IP-basierten Massen-Virtual-Hosts gedacht ist, + um antiquierte Clients zu unterstützen, die keinen + Host:-Header bereit stellen. Um selbstreferenzierende + URLs zu ermitteln, führt der Apache bei dieser Option ein + Reverse-DNS-Lookup auf die IP-Adresse des Servers aus, zu der der Client + Verbindung aufgenommen hat.

    + +

    Warnung

    +

    Wenn CGI-Skripte Vermutungen aufgrund des Wertes von + SERVER_NAME anstellen, können sie durch diese + Option fehlschlagen. Clients steht es im Wesentlichen frei, einen Wert + für den Hostnamen anzugeben, wie er will. Wenn das + CGI-Skript SERVER_NAME jedoch lediglich dazu verwendet, + selbstreferenzierende URLs zu erstellen, sollte das gerade noch + in Ordnung sein.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    <VirtualHost>-Direktive

    + + + + + + +
    Beschreibung:Enthält Direktiven, die nur auf bestimmte Hostnamen oder +IP-Adressen angewendet werden
    Syntax:<VirtualHost + Adresse[:Port] [Adresse[:Port]] + ...> ... </VirtualHost>
    Kontext:Serverkonfiguration
    Status:Core
    Modul:core
    +

    <VirtualHost> und + </VirtualHost> werden dazu verwendet, eine Gruppe + von Direktiven zusammenzufassen, die nur auf einen bestimmten virtuellen + Host angewendet werden. Jede Direktive, die im Virtual-Host-Kontext + zulässig ist, kann verwendet werden. Wenn der Server eine Anfrage + für ein bestimmtes Dokument eines bestimmten virtuellen Hosts + empfängt, dann benutzt er die im + <VirtualHost>-Container enthaltenen + Konfigurationsanweisungen. Adresse kann sein:

    + +
      +
    • Die IP-Adresse des virtuellen Hosts.
    • + +
    • Ein voll qualifizierter Domainname für die IP-Adresse des + virtuellen Hosts.
    • + +
    • Das Zeichen *, welches nur in Kombination mit + NameVirtualHost * verwendet wird, um allen IP-Adressen + zu entsprechen.
    • + +
    • Die Zeichenkette _default_, die nur mit IP-basierten + virtuellen Hosts verwendet wird, um nicht zugewiesene IP-Adressen + aufzufangen.
    • +
    + +

    Beispiel

    + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +

    + +

    IPv6-Adressen müssen in eckigen Klammern angegeben werden, da die + optionale Portnummer sonst nicht erkannt werden kann. Hier ein + IPv6-Beispiel:

    + +

    + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +

    + +

    Jeder virtuelle Host muss einer anderen IP-Adresse, einem anderen Port + oder einem anderen Hostnamen für den Server entsprechen. Im ersten + Fall muss die Servermaschine so eingerichtet sein, dass sie IP-Pakete + für mehrere Adressen akzeptiert. (Wenn der Rechner nicht mehrere + Netzwerkkarten besitzt, kann dies mit dem Befehl ifconfig + alias durchgeführt werden -- sofern Ihr Betriebssystem das + unterstützt).

    + +

    Anmerkung

    +

    Die Verwendung von <VirtualHost> + beeinflusst nicht, an welchen Adressen der Apache + lauscht. Sie müssen mit Listen sicherstellen, dass der Apache + an der richtigen Adresse lauscht.

    +
    + +

    Bei der Verwendung IP-basierter virtuellen Hosts kann der spezielle + Name _default_ benutzt werden. In diesem Fall weist + der Apache jede IP-Adresse diesem virtuellen Host zu, die nicht explizit in + einem anderen virtuellen Host angegeben ist. Falls kein virtueller Host + _default_ angegeben ist, wird die "Hauptserver"-Konfiguration, + die aus allen Definitionen außerhalb der Virtual-Host-Abschnitte + besteht, für nicht passende IPs verwendet. (Beachten Sie jedoch, + dass eine IP-Adressen die zu einer NameVirtualHost-Anweisung passt, weder den + "Hauptserver" noch den virtuellen Host _default_ verwendet. + Lesen Sie für weitere Details die Dokumentation zu namensbasierten virtuell Hosts.)

    + +

    Sie können einen speziellen :Port angeben, + um den entsprechenden Port zu wechseln. Falls nicht angegeben, wird + er auf den gleichen Port voreingestellt, wie die letzte + Listen-Anweisung des + Hauptservers. Sie können auch :* angeben, um alle + Ports dieser Adresse zu akzeptieren. (Dies wird zusammen mit + _default_ empfohlen.)

    + +

    Sicherheit

    +

    Lesen Sie das Dokument Sicherheitshinweise für + Details, warum Ihre Sicherheit gefährdet sein kann, wenn das + Verzeichnis, in dem Protokolldateien gespeichert werden, für + jemanden anderes als den Benutzer beschreibbar ist, der den Server + gestartet hat.

    +
    + +

    Siehe auch

    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/core.html.en b/trunk/docs/manual/mod/core.html.en new file mode 100644 index 0000000000..613ccfbec0 --- /dev/null +++ b/trunk/docs/manual/mod/core.html.en @@ -0,0 +1,3190 @@ + + + +core - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Core Features

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + +
    Description:Core Apache HTTP Server features that are always +available
    Status:Core
    +
    + + +
    top
    +

    AcceptPathInfo Directive

    + + + + + + + + + +
    Description:Resources accept trailing pathname information
    Syntax:AcceptPathInfo On|Off|Default
    Default:AcceptPathInfo Default
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Available in Apache 2.0.30 and later
    + +

    This directive controls whether requests that contain trailing + pathname information that follows an actual filename (or + non-existent file in an existing directory) will be accepted or + rejected. The trailing pathname information can be made + available to scripts in the PATH_INFO environment + variable.

    + +

    For example, assume the location /test/ points to + a directory that contains only the single file + here.html. Then requests for + /test/here.html/more and + /test/nothere.html/more both collect + /more as PATH_INFO.

    + +

    The three possible arguments for the + AcceptPathInfo directive are:

    +
    +
    Off
    A request will only be accepted if it + maps to a literal path that exists. Therefore a request with + trailing pathname information after the true filename such as + /test/here.html/more in the above example will return + a 404 NOT FOUND error.
    + +
    On
    A request will be accepted if a + leading path component maps to a file that exists. The above + example /test/here.html/more will be accepted if + /test/here.html maps to a valid file.
    + +
    Default
    The treatment of requests with + trailing pathname information is determined by the handler responsible for the request. + The core handler for normal files defaults to rejecting + PATH_INFO requests. Handlers that serve scripts, such as cgi-script and isapi-isa, generally accept + PATH_INFO by default.
    +
    + +

    The primary purpose of the AcceptPathInfo + directive is to allow you to override the handler's choice of + accepting or rejecting PATH_INFO. This override is required, + for example, when you use a filter, such + as INCLUDES, to generate content + based on PATH_INFO. The core handler would usually reject + the request, so you can use the following configuration to enable + such a script:

    + +

    + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +

    + + +
    +
    top
    +

    AccessFileName Directive

    + + + + + + + +
    Description:Name of the distributed configuration file
    Syntax:AccessFileName filename [filename] ...
    Default:AccessFileName .htaccess
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    While processing a request the server looks for + the first existing configuration file from this list of names in + every directory of the path to the document, if distributed + configuration files are enabled for that + directory. For example:

    + +

    + AccessFileName .acl +

    + +

    before returning the document + /usr/local/web/index.html, the server will read + /.acl, /usr/.acl, + /usr/local/.acl and /usr/local/web/.acl + for directives, unless they have been disabled with

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory> +

    + +

    See also

    + +
    +
    top
    +

    AddDefaultCharset Directive

    + + + + + + + + +
    Description:Default charset parameter to be added when a response +content-type is text/plain or text/html
    Syntax:AddDefaultCharset On|Off|charset
    Default:AddDefaultCharset Off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    This directive specifies a default value for the media type + charset parameter (the name of a character encoding) to be added + to a response if and only if the response's content-type is either + text/plain or text/html. This should override + any charset specified in the body of the response via a META + element, though the exact behavior is often dependent on the user's client + configuration. A setting of AddDefaultCharset Off + disables this functionality. AddDefaultCharset On enables + a default charset of iso-8859-1. Any other value is assumed + to be the charset to be used, which should be one of the + IANA registered + charset values for use in MIME media types. + For example:

    + +

    + AddDefaultCharset utf-8 +

    + +

    AddDefaultCharset should only be used when all + of the text resources to which it applies are known to be in that + character encoding and it is too inconvenient to label their charset + individually. One such example is to add the charset parameter + to resources containing generated content, such as legacy CGI + scripts, that might be vulnerable to cross-site scripting attacks + due to user-provided data being included in the output. Note, however, + that a better solution is to just fix (or delete) those scripts, since + setting a default charset does not protect users that have enabled + the "auto-detect character encoding" feature on their browser.

    + +

    See also

    + +
    +
    top
    +

    AddOutputFilterByType Directive

    + + + + + + + + +
    Description:assigns an output filter to a particular MIME-type
    Syntax:AddOutputFilterByType filter[;filter...] +MIME-type [MIME-type] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Available in Apache 2.0.33 and later
    +

    This directive activates a particular output filter for a request depending on the + response MIME-type.

    + +

    The following example uses the DEFLATE filter, which + is provided by mod_deflate. It will compress all + output (either static or dynamic) which is labeled as + text/html or text/plain before it is sent + to the client.

    + +

    + AddOutputFilterByType DEFLATE text/html text/plain +

    + +

    If you want the content to be processed by more than one filter, their + names have to be separated by semicolons. It's also possible to use one + AddOutputFilterByType directive for each of + these filters.

    + +

    The configuration below causes all script output labeled as + text/html to be processed at first by the + INCLUDES filter and then by the DEFLATE + filter.

    + +

    + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +

    + +

    Note

    +

    Enabling filters with AddOutputFilterByType + may fail partially or completely in some cases. For example, no + filters are applied if the MIME-type could not be determined and falls + back to the DefaultType setting, + even if the DefaultType is the + same.

    + +

    However, if you want to make sure, that the filters will be + applied, assign the content type to a resource explicitly, for + example with AddType or + ForceType. Setting the + content type within a (non-nph) CGI script is also safe.

    + +

    The by-type output filters are never applied on proxy requests.

    +
    + +

    See also

    + +
    +
    top
    +

    AllowEncodedSlashes Directive

    + + + + + + + + +
    Description:Determines whether encoded path separators in URLs are allowed to +be passed through
    Syntax:AllowEncodedSlashes On|Off
    Default:AllowEncodedSlashes Off
    Context:server config, virtual host
    Status:Core
    Module:core
    Compatibility:Available in Apache 2.0.46 and later
    +

    The AllowEncodedSlashes directive allows URLs + which contain encoded path separators (%2F for / + and additionally %5C for \ on according systems) + to be used. Normally such URLs are refused with a 404 (Not found) error.

    + +

    Turning AllowEncodedSlashes On is + mostly useful when used in conjunction with PATH_INFO.

    + +

    Note

    +

    Allowing encoded slashes does not imply decoding. + Occurrences of %2F or %5C (only on + according systems) will be left as such in the otherwise decoded URL + string.

    +
    + +

    See also

    + +
    +
    top
    +

    AllowOverride Directive

    + + + + + + + +
    Description:Types of directives that are allowed in +.htaccess files
    Syntax:AllowOverride All|None|directive-type +[directive-type] ...
    Default:AllowOverride All
    Context:directory
    Status:Core
    Module:core
    +

    When the server finds an .htaccess file (as + specified by AccessFileName) + it needs to know which directives declared in that file can override + earlier configuration directives.

    + +

    Only available in <Directory> sections

    + AllowOverride is valid only in + <Directory> + sections specified without regular expressions, not in <Location>, <DirectoryMatch> or + <Files> sections. +
    + +

    When this directive is set to None, then + .htaccess files are completely ignored. + In this case, the server will not even attempt to read + .htaccess files in the filesystem.

    + +

    When this directive is set to All, then any + directive which has the .htaccess Context is allowed in + .htaccess files.

    + +

    The directive-type can be one of the following + groupings of directives.

    + +
    +
    AuthConfig
    + +
    + + Allow use of the authorization directives (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require, etc.).
    + +
    FileInfo
    + +
    + Allow use of the directives controlling document types (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, and + mod_mime Add* and Remove* + directives, etc.).
    + +
    Indexes
    + +
    + Allow use of the directives controlling directory indexing + (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, + etc.).
    + +
    Limit
    + +
    + Allow use of the directives controlling host access (Allow, Deny and Order).
    + +
    Options[=Option,...]
    + +
    + Allow use of the directives controlling specific directory + features (Options and + XBitHack). + An equal sign may be given followed by a comma (but no spaces) + separated lists of options that may be set using the Options command.
    +
    + +

    Example:

    + +

    + AllowOverride AuthConfig Indexes +

    + +

    In the example above all directives that are neither in the group + AuthConfig nor Indexes cause an internal + server error.

    + +

    See also

    + +
    +
    top
    +

    AuthName Directive

    + + + + + + + +
    Description:Authorization realm for use in HTTP +authentication
    Syntax:AuthName auth-domain
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Core
    Module:core
    +

    This directive sets the name of the authorization realm for a + directory. This realm is given to the client so that the user + knows which username and password to send. + AuthName takes a single argument; if the + realm name contains spaces, it must be enclosed in quotation + marks. It must be accompanied by AuthType and Require directives, and directives such + as AuthUserFile and + AuthGroupFile to + work.

    + +

    For example:

    + +

    + AuthName "Top Secret" +

    + +

    The string provided for the AuthName is what will + appear in the password dialog provided by most browsers.

    + +

    See also

    + +
    +
    top
    +

    AuthType Directive

    + + + + + + + +
    Description:Type of user authentication
    Syntax:AuthType Basic|Digest
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Core
    Module:core
    +

    This directive selects the type of user authentication for a + directory. Only Basic and Digest are + currently implemented. + + It must be accompanied by AuthName and Require directives, and directives such + as AuthUserFile and + AuthGroupFile to + work.

    + +

    See also

    + +
    +
    top
    +

    CGIMapExtension Directive

    + + + + + + + + +
    Description:Technique for locating the interpreter for CGI +scripts
    Syntax:CGIMapExtension cgi-path .extension
    Context:directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:NetWare only
    +

    This directive is used to control how Apache finds the + interpreter used to run CGI scripts. For example, setting + CGIMapExtension sys:\foo.nlm .foo will + cause all CGI script files with a .foo extension to + be passed to the FOO interpreter.

    + +
    +
    top
    +

    ContentDigest Directive

    + + + + + + + + +
    Description:Enables the generation of Content-MD5 HTTP Response +headers
    Syntax:ContentDigest On|Off
    Default:ContentDigest Off
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Core
    Module:core
    +

    This directive enables the generation of + Content-MD5 headers as defined in RFC1864 + respectively RFC2068.

    + +

    MD5 is an algorithm for computing a "message digest" + (sometimes called "fingerprint") of arbitrary-length data, with + a high degree of confidence that any alterations in the data + will be reflected in alterations in the message digest.

    + +

    The Content-MD5 header provides an end-to-end + message integrity check (MIC) of the entity-body. A proxy or + client may check this header for detecting accidental + modification of the entity-body in transit. Example header:

    + +

    + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== +

    + +

    Note that this can cause performance problems on your server + since the message digest is computed on every request (the + values are not cached).

    + +

    Content-MD5 is only sent for documents served + by the core, and not by any module. For example, + SSI documents, output from CGI scripts, and byte range responses + do not have this header.

    + +
    +
    top
    +

    DefaultType Directive

    + + + + + + + + +
    Description:MIME content-type that will be sent if the +server cannot determine a type in any other way
    Syntax:DefaultType MIME-type
    Default:DefaultType text/plain
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    There will be times when the server is asked to provide a + document whose type cannot be determined by its MIME types + mappings.

    + +

    The server must inform the client of the content-type of the + document, so in the event of an unknown type it uses the + DefaultType. For example:

    + +

    + DefaultType image/gif +

    + +

    would be appropriate for a directory which contained many GIF + images with filenames missing the .gif extension.

    + +

    Note that unlike ForceType, this directive only + provides the default mime-type. All other mime-type definitions, + including filename extensions, that might identify the media type + will override this default.

    + +
    +
    top
    +

    <Directory> Directive

    + + + + + + +
    Description:Enclose a group of directives that apply only to the +named file-system directory and sub-directories
    Syntax:<Directory directory-path> +... </Directory>
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    <Directory> and + </Directory> are used to enclose a group of + directives that will apply only to the named directory and + sub-directories of that directory. Any directive that is allowed + in a directory context may be used. Directory-path is + either the full path to a directory, or a wild-card string using + Unix shell-style matching. In a wild-card string, ? matches + any single character, and * matches any sequences of + characters. You may also use [] character ranges. None + of the wildcards match a `/' character, so <Directory + /*/public_html> will not match + /home/user/public_html, but <Directory + /home/*/public_html> will match. Example:

    + +

    + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +

    + +
    +

    Be careful with the directory-path arguments: + They have to literally match the filesystem path which Apache uses + to access the files. Directives applied to a particular + <Directory> will not apply to files accessed from + that same directory via a different path, such as via different symbolic + links.

    +
    + +

    Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + +

    + <Directory ~ "^/www/.*/[0-9]{3}"> +

    + +

    would match directories in /www/ that consisted of + three numbers.

    + +

    If multiple (non-regular expression) <Directory> sections + match the directory (or one of its parents) containing a document, + then the directives are applied in the order of shortest match + first, interspersed with the directives from the .htaccess files. For example, + with

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +

    + +

    for access to the document /home/web/dir/doc.html + the steps are:

    + +
      +
    • Apply directive AllowOverride None + (disabling .htaccess files).
    • + +
    • Apply directive AllowOverride FileInfo (for + directory /home).
    • + +
    • Apply any FileInfo directives in + /home/.htaccess, /home/web/.htaccess and + /home/web/dir/.htaccess in that order.
    • +
    + +

    Regular expressions are not considered until after all of the + normal sections have been applied. Then all of the regular + expressions are tested in the order they appeared in the + configuration file. For example, with

    + +

    + <Directory ~ abc$>
    + + # ... directives here ...
    +
    + </Directory> +

    + +

    the regular expression section won't be considered until after + all normal <Directory>s and + .htaccess files have been applied. Then the regular + expression will match on /home/abc/public_html/abc and + the corresponding <Directory> will + be applied.

    + +

    Note that the default Apache access for + <Directory /> is Allow from All. + This means that Apache will serve any file mapped from an URL. It is + recommended that you change this with a block such + as

    + +

    + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +

    + +

    and then override this for directories you + want accessible. See the Security Tips page for more + details.

    + +

    The directory sections occur in the httpd.conf file. + <Directory> directives + cannot nest, and cannot appear in a <Limit> or <LimitExcept> section.

    + +

    See also

    + +
    +
    top
    +

    <DirectoryMatch> Directive

    + + + + + + +
    Description:Enclose directives that apply to +file-system directories matching a regular expression and their +subdirectories
    Syntax:<DirectoryMatch regex> +... </DirectoryMatch>
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    <DirectoryMatch> and + </DirectoryMatch> are used to enclose a group + of directives which will apply only to the named directory and + sub-directories of that directory, the same as <Directory>. However, it + takes as an argument a regular expression. For example:

    + +

    + <DirectoryMatch "^/www/(.+/)?[0-9]{3}"> +

    + +

    would match directories in /www/ that consisted of three + numbers.

    + +

    See also

    + +
    +
    top
    +

    DocumentRoot Directive

    + + + + + + + +
    Description:Directory that forms the main document tree visible +from the web
    Syntax:DocumentRoot directory-path
    Default:DocumentRoot /usr/local/apache/htdocs
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    This directive sets the directory from which httpd + will serve files. Unless matched by a directive like Alias, the server appends the + path from the requested URL to the document root to make the + path to the document. Example:

    + +

    + DocumentRoot /usr/web +

    + +

    then an access to + http://www.my.host.com/index.html refers to + /usr/web/index.html. If the directory-path is + not absolute then it is assumed to be relative to the ServerRoot.

    + +

    The DocumentRoot should be specified without + a trailing slash.

    + +

    See also

    + +
    +
    top
    +

    EnableMMAP Directive

    + + + + + + + + +
    Description:Use memory-mapping to read files during delivery
    Syntax:EnableMMAP On|Off
    Default:EnableMMAP On
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    This directive controls whether the httpd may use + memory-mapping if it needs to read the contents of a file during + delivery. By default, when the handling of a request requires + access to the data within a file -- for example, when delivering a + server-parsed file using mod_include -- Apache + memory-maps the file if the OS supports it.

    + +

    This memory-mapping sometimes yields a performance improvement. + But in some environments, it is better to disable the memory-mapping + to prevent operational problems:

    + +
      +
    • On some multiprocessor systems, memory-mapping can reduce the + performance of the httpd.
    • +
    • With an NFS-mounted DocumentRoot, + the httpd may crash due to a segmentation fault if a file + is deleted or truncated while the httpd has it + memory-mapped.
    • +
    + +

    For server configurations that are vulnerable to these problems, + you should disable memory-mapping of delivered files by specifying:

    + +

    + EnableMMAP Off +

    + +

    For NFS mounted files, this feature may be disabled explicitly for + the offending files by specifying:

    + +

    + <Directory "/path-to-nfs-files"> + + EnableMMAP Off + + </Directory> +

    + +
    +
    top
    +

    EnableSendfile Directive

    + + + + + + + + + +
    Description:Use the kernel sendfile support to deliver files to the client
    Syntax:EnableSendfile On|Off
    Default:EnableSendfile On
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Available in version 2.0.44 and later
    +

    This directive controls whether httpd may use the + sendfile support from the kernel to transmit file contents to the client. + By default, when the handling of a request requires no access + to the data within a file -- for example, when delivering a + static file -- Apache uses sendfile to deliver the file contents + without ever reading the file if the OS supports it.

    + +

    This sendfile mechanism avoids separate read and send operations, + and buffer allocations. But on some platforms or within some + filesystems, it is better to disable this feature to avoid + operational problems:

    + +
      +
    • Some platforms may have broken sendfile support that the build + system did not detect, especially if the binaries were built on + another box and moved to such a machine with broken sendfile + support.
    • +
    • On Linux the use of sendfile triggers TCP-checksum + offloading bugs on certain networking cards when using IPv6.
    • +
    • With a network-mounted DocumentRoot (e.g., NFS or SMB), + the kernel may be unable to serve the network file through + its own cache.
    • +
    + +

    For server configurations that are vulnerable to these problems, + you should disable this feature by specifying:

    + +

    + EnableSendfile Off +

    + +

    For NFS or SMB mounted files, this feature may be disabled explicitly + for the offending files by specifying:

    + +

    + <Directory "/path-to-nfs-files"> + + EnableSendfile Off + + </Directory> +

    + +
    +
    top
    +

    ErrorDocument Directive

    + + + + + + + + +
    Description:What the server will return to the client +in case of an error
    Syntax:ErrorDocument error-code document
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Quoting syntax for text messages is different in Apache +2.0
    +

    In the event of a problem or error, Apache can be configured + to do one of four things,

    + +
      +
    1. output a simple hardcoded error message
    2. + +
    3. output a customized message
    4. + +
    5. redirect to a local URL-path to handle the + problem/error
    6. + +
    7. redirect to an external URL to handle the + problem/error
    8. +
    + +

    The first option is the default, while options 2-4 are + configured using the ErrorDocument + directive, which is followed by the HTTP response code and a URL + or a message. Apache will sometimes offer additional information + regarding the problem/error.

    + +

    URLs can begin with a slash (/) for local web-paths (relative + to the DocumentRoot), or be a + full URL which the client can resolve. Alternatively, a message + can be provided to be displayed by the browser. Examples:

    + +

    + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/bad_urls.pl
    + ErrorDocument 401 /subscription_info.html
    + ErrorDocument 403 "Sorry can't allow you access today" +

    + +

    Additionally, the special value default can be used + to specify Apache's simple hardcoded message. While not required + under normal circumstances, default will restore + Apache's simple hardcoded message for configurations that would + otherwise inherit an existing ErrorDocument.

    + +

    + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +

    + +

    Note that when you specify an ErrorDocument + that points to a remote URL (ie. anything with a method such as + http in front of it), Apache will send a redirect to the + client to tell it where to find the document, even if the + document ends up being on the same server. This has several + implications, the most important being that the client will not + receive the original error status code, but instead will + receive a redirect status code. This in turn can confuse web + robots and other clients which try to determine if a URL is + valid using the status code. In addition, if you use a remote + URL in an ErrorDocument 401, the client will not + know to prompt the user for a password since it will not + receive the 401 status code. Therefore, if you use an + ErrorDocument 401 directive then it must refer to a local + document.

    + +

    Microsoft Internet Explorer (MSIE) will by default ignore + server-generated error messages when they are "too small" and substitute + its own "friendly" error messages. The size threshold varies depending on + the type of error, but in general, if you make your error document + greater than 512 bytes, then MSIE will show the server-generated + error rather than masking it. More information is available in + Microsoft Knowledge Base article Q294807.

    + +

    Although most error messages can be overriden, there are certain + circumstances where the internal messages are used regardless of the + setting of ErrorDocument. In + particular, if a malformed request is detected, normal request processing + will be immediately halted and the internal error message returned. + This is necessary to guard against security problems caused by + bad requests.

    + +

    Prior to version 2.0, messages were indicated by prefixing + them with a single unmatched double quote character.

    + +

    See also

    + +
    +
    top
    +

    ErrorLog Directive

    + + + + + + + +
    Description:Location where the server will log errors
    Syntax: ErrorLog file-path|syslog[:facility]
    Default:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2)
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The ErrorLog directive sets the name of + the file to which the server will log any errors it encounters. If + the file-path is not absolute then it is assumed to be + relative to the ServerRoot.

    + +

    Example

    + ErrorLog /var/log/httpd/error_log +

    + +

    If the file-path + begins with a pipe (|) then it is assumed to be a command to spawn + to handle the error log.

    + +

    Example

    + ErrorLog "|/usr/local/bin/httpd_errors" +

    + +

    Using syslog instead of a filename enables logging + via syslogd(8) if the system supports it. The default is to use + syslog facility local7, but you can override this by + using the syslog:facility syntax where + facility can be one of the names usually documented in + syslog(1).

    + +

    Example

    + ErrorLog syslog:user +

    + +

    SECURITY: See the security tips + document for details on why your security could be compromised + if the directory where log files are stored is writable by + anyone other than the user that starts the server.

    +

    Note

    +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    + +

    See also

    + +
    +
    top
    +

    FileETag Directive

    + + + + + + + + +
    Description:File attributes used to create the ETag +HTTP response header
    Syntax:FileETag component ...
    Default:FileETag INode MTime Size
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    + The FileETag directive configures the file + attributes that are used to create the ETag (entity + tag) response header field when the document is based on a file. + (The ETag value is used in cache management to save + network bandwidth.) In Apache 1.3.22 and earlier, the + ETag value was always formed + from the file's inode, size, and last-modified time (mtime). The + FileETag directive allows you to choose + which of these -- if any -- should be used. The recognized keywords are: +

    + +
    +
    INode
    +
    The file's i-node number will be included in the calculation
    +
    MTime
    +
    The date and time the file was last modified will be included
    +
    Size
    +
    The number of bytes in the file will be included
    +
    All
    +
    All available fields will be used. This is equivalent to: +

    FileETag INode MTime Size

    +
    None
    +
    If a document is file-based, no ETag field will be + included in the response
    +
    + +

    The INode, MTime, and Size + keywords may be prefixed with either + or -, + which allow changes to be made to the default setting inherited + from a broader scope. Any keyword appearing without such a prefix + immediately and completely cancels the inherited setting.

    + +

    If a directory's configuration includes + FileETag INode MTime Size, and a + subdirectory's includes FileETag -INode, + the setting for that subdirectory (which will be inherited by + any sub-subdirectories that don't override it) will be equivalent to + FileETag MTime Size.

    + +
    +
    top
    +

    <Files> Directive

    + + + + + + + +
    Description:Contains directives that apply to matched +filenames
    Syntax:<Files filename> ... </Files>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    The <Files> directive + limits the scope of the enclosed directives by filename. It is comparable + to the <Directory> + and <Location> + directives. It should be matched with a </Files> + directive. The directives given within this section will be applied to + any object with a basename (last component of filename) matching the + specified filename. <Files> + sections are processed in the order they appear in the + configuration file, after the <Directory> sections and + .htaccess files are read, but before <Location> sections. Note + that <Files> can be nested + inside <Directory> sections to restrict the + portion of the filesystem they apply to.

    + +

    The filename argument should include a filename, or + a wild-card string, where ? matches any single character, + and * matches any sequences of characters. Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + +

    + <Files ~ "\.(gif|jpe?g|png)$"> +

    + +

    would match most common Internet graphics formats. <FilesMatch> is preferred, + however.

    + +

    Note that unlike <Directory> and <Location> sections, <Files> sections can be used inside + .htaccess files. This allows users to control access to + their own files, at a file-by-file level.

    + + +

    See also

    + +
    +
    top
    +

    <FilesMatch> Directive

    + + + + + + + +
    Description:Contains directives that apply to regular-expression matched +filenames
    Syntax:<FilesMatch regex> ... </FilesMatch>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    The <FilesMatch> directive + limits the scope of the enclosed directives by filename, just as the + <Files> directive + does. However, it accepts a regular expression. For example:

    + +

    + <FilesMatch "\.(gif|jpe?g|png)$"> +

    + +

    would match most common Internet graphics formats.

    + +

    See also

    + +
    +
    top
    +

    ForceType Directive

    + + + + + + + + +
    Description:Forces all matching files to be served with the specified +MIME content-type
    Syntax:ForceType MIME-type|None
    Context:directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Moved to the core in Apache 2.0
    +

    When placed into an .htaccess file or a + <Directory>, or + <Location> or + <Files> + section, this directive forces all matching files to be served + with the content type identification given by + MIME-type. For example, if you had a directory full of + GIF files, but did not want to label them all with .gif, + you might want to use:

    + +

    + ForceType image/gif +

    + +

    Note that unlike DefaultType, + this directive overrides all mime-type associations, including + filename extensions, that might identify the media type.

    + +

    You can override any ForceType setting + by using the value of None:

    + +

    + # force all files to be image/gif:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # but normal mime-type associations here:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +

    + +
    +
    top
    +

    HostnameLookups Directive

    + + + + + + + +
    Description:Enables DNS lookups on client IP addresses
    Syntax:HostnameLookups On|Off|Double
    Default:HostnameLookups Off
    Context:server config, virtual host, directory
    Status:Core
    Module:core
    +

    This directive enables DNS lookups so that host names can be + logged (and passed to CGIs/SSIs in REMOTE_HOST). + The value Double refers to doing double-reverse + DNS lookup. That is, after a reverse lookup is performed, a forward + lookup is then performed on that result. At least one of the IP + addresses in the forward lookup must match the original + address. (In "tcpwrappers" terminology this is called + PARANOID.)

    + +

    Regardless of the setting, when mod_authz_host is + used for controlling access by hostname, a double reverse lookup + will be performed. This is necessary for security. Note that the + result of this double-reverse isn't generally available unless you + set HostnameLookups Double. For example, if only + HostnameLookups On and a request is made to an object + that is protected by hostname restrictions, regardless of whether + the double-reverse fails or not, CGIs will still be passed the + single-reverse result in REMOTE_HOST.

    + +

    The default is Off in order to save the network + traffic for those sites that don't truly need the reverse + lookups done. It is also better for the end users because they + don't have to suffer the extra latency that a lookup entails. + Heavily loaded sites should leave this directive + Off, since DNS lookups can take considerable + amounts of time. The utility logresolve, compiled by + default to the bin subdirectory of your installation + directory, can be used to look up host names from logged IP addresses + offline.

    + +
    +
    top
    +

    <IfDefine> Directive

    + + + + + + + +
    Description:Encloses directives that will be processed only +if a test is true at startup
    Syntax:<IfDefine [!]parameter-name> ... + </IfDefine>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    The <IfDefine test>...</IfDefine> + section is used to mark directives that are conditional. The + directives within an <IfDefine> + section are only processed if the test is true. If + test is false, everything between the start and end markers is + ignored.

    + +

    The test in the <IfDefine> section directive can be one of two forms:

    + +
      +
    • parameter-name
    • + +
    • !parameter-name
    • +
    + +

    In the former case, the directives between the start and end + markers are only processed if the parameter named + parameter-name is defined. The second format reverses + the test, and only processes the directives if + parameter-name is not defined.

    + +

    The parameter-name argument is a define as given on + the httpd command line via -Dparameter- + , at the time the server was started.

    + +

    <IfDefine> sections are + nest-able, which can be used to implement simple + multiple-parameter tests. Example:

    + +

    + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +

    + +
    +
    top
    +

    <IfModule> Directive

    + + + + + + + + +
    Description:Encloses directives that are processed conditional on the +presence or absence of a specific module
    Syntax:<IfModule [!]module-file|module-identifier> ... + </IfModule>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    Compatibility:Module identifiers are available in version 2.1 and +later.
    +

    The <IfModule test>...</IfModule> + section is used to mark directives that are conditional on the presence of + a specific module. The directives within an <IfModule> section are only processed if the test + is true. If test is false, everything between the start and + end markers is ignored.

    + +

    The test in the <IfModule> section directive can be one of two forms:

    + +
      +
    • module
    • + +
    • !module
    • +
    + +

    In the former case, the directives between the start and end + markers are only processed if the module named module + is included in Apache -- either compiled in or + dynamically loaded using LoadModule. The second format reverses the test, + and only processes the directives if module is + not included.

    + +

    The module argument can be either the module identifier or + the file name of the module, at the time it was compiled. For example, + rewrite_module is the identifier and + mod_rewrite.c is the file name. If a module consists of + several source files, use the name of the file containing the string + STANDARD20_MODULE_STUFF.

    + +

    <IfModule> sections are + nest-able, which can be used to implement simple multiple-module + tests.

    + +
    This section should only be used if you need to have one + configuration file that works whether or not a specific module + is available. In normal operation, directives need not be + placed in <IfModule> + sections.
    + +
    +
    top
    +

    Include Directive

    + + + + + + + +
    Description:Includes other configuration files from within +the server configuration files
    Syntax:Include file-path|directory-path
    Context:server config, virtual host, directory
    Status:Core
    Module:core
    Compatibility:Wildcard matching available in 2.0.41 and later
    +

    This directive allows inclusion of other configuration files + from within the server configuration files.

    + +

    Shell-style (fnmatch()) wildcard characters can be used to + include several files at once, in alphabetical order. In + addition, if Include points to a directory, + rather than a file, Apache will read all files in that directory + and any subdirectory. But including entire directories is not + recommended, because it is easy to accidentally leave temporary + files in a directory that can cause httpd to + fail.

    + +

    The file path specified may be an absolute path, or may be relative + to the ServerRoot directory.

    + +

    Examples:

    + +

    + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +

    + +

    Or, providing paths relative to your ServerRoot directory:

    + +

    + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +

    + +

    Running apachectl configtest will give you a list + of the files that are being processed during the configuration + check:

    + +

    + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +

    + +

    See also

    + +
    +
    top
    +

    KeepAlive Directive

    + + + + + + + +
    Description:Enables HTTP persistent connections
    Syntax:KeepAlive On|Off
    Default:KeepAlive On
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The Keep-Alive extension to HTTP/1.0 and the persistent + connection feature of HTTP/1.1 provide long-lived HTTP sessions + which allow multiple requests to be sent over the same TCP + connection. In some cases this has been shown to result in an + almost 50% speedup in latency times for HTML documents with + many images. To enable Keep-Alive connections, set + KeepAlive On.

    + +

    For HTTP/1.0 clients, Keep-Alive connections will only be + used if they are specifically requested by a client. In + addition, a Keep-Alive connection with an HTTP/1.0 client can + only be used when the length of the content is known in + advance. This implies that dynamic content such as CGI output, + SSI pages, and server-generated directory listings will + generally not use Keep-Alive connections to HTTP/1.0 clients. + For HTTP/1.1 clients, persistent connections are the default + unless otherwise specified. If the client requests it, chunked + encoding will be used in order to send content of unknown + length over persistent connections.

    + +

    See also

    + +
    +
    top
    +

    KeepAliveTimeout Directive

    + + + + + + + +
    Description:Amount of time the server will wait for subsequent +requests on a persistent connection
    Syntax:KeepAliveTimeout seconds
    Default:KeepAliveTimeout 5
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The number of seconds Apache will wait for a subsequent + request before closing the connection. Once a request has been + received, the timeout value specified by the + Timeout directive applies.

    + +

    Setting KeepAliveTimeout to a high value + may cause performance problems in heavily loaded servers. The + higher the timeout, the more server processes will be kept + occupied waiting on connections with idle clients.

    + +
    +
    top
    +

    <Limit> Directive

    + + + + + + + +
    Description:Restrict enclosed access controls to only certain HTTP +methods
    Syntax:<Limit method [method] ... > ... + </Limit>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    Access controls are normally effective for + all access methods, and this is the usual + desired behavior. In the general case, access control + directives should not be placed within a + <Limit> section.

    + +

    The purpose of the <Limit> + directive is to restrict the effect of the access controls to the + nominated HTTP methods. For all other methods, the access + restrictions that are enclosed in the <Limit> bracket will have no + effect. The following example applies the access control + only to the methods POST, PUT, and + DELETE, leaving all other methods unprotected:

    + +

    + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +

    + +

    The method names listed can be one or more of: GET, + POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK, and UNLOCK. The method name is + case-sensitive. If GET is used it will also + restrict HEAD requests. The TRACE method + cannot be limited.

    + +
    A <LimitExcept> section should always be + used in preference to a <Limit> section when restricting access, + since a <LimitExcept> section provides protection + against arbitrary methods.
    + + +
    +
    top
    +

    <LimitExcept> Directive

    + + + + + + + +
    Description:Restrict access controls to all HTTP methods +except the named ones
    Syntax:<LimitExcept method [method] ... > ... + </LimitExcept>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    <LimitExcept> and + </LimitExcept> are used to enclose + a group of access control directives which will then apply to any + HTTP access method not listed in the arguments; + i.e., it is the opposite of a <Limit> section and can be used to control + both standard and nonstandard/unrecognized methods. See the + documentation for <Limit> for more details.

    + +

    For example:

    + +

    + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +

    + + +
    +
    top
    +

    LimitInternalRecursion Directive

    + + + + + + + + +
    Description:Determine maximum number of internal redirects and nested +subrequests
    Syntax:LimitInternalRecursion number [number]
    Default:LimitInternalRecursion 10
    Context:server config, virtual host
    Status:Core
    Module:core
    Compatibility:Available in Apache 2.0.47 and later
    +

    An internal redirect happens, for example, when using the Action directive, which internally + redirects the original request to a CGI script. A subrequest is Apache's + mechanism to find out what would happen for some URI if it were requested. + For example, mod_dir uses subrequests to look for the + files listed in the DirectoryIndex + directive.

    + +

    LimitInternalRecursion prevents the server + from crashing when entering an infinite loop of internal redirects or + subrequests. Such loops are usually caused by misconfigurations.

    + +

    The directive stores two different limits, which are evaluated on + per-request basis. The first number is the maximum number of + internal redirects, that may follow each other. The second number + determines, how deep subrequests may be nested. If you specify only one + number, it will be assigned to both limits.

    + +

    Example

    + LimitInternalRecursion 5 +

    + +
    +
    top
    +

    LimitRequestBody Directive

    + + + + + + + + +
    Description:Restricts the total size of the HTTP request body sent +from the client
    Syntax:LimitRequestBody bytes
    Default:LimitRequestBody 0
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    This directive specifies the number of bytes from 0 + (meaning unlimited) to 2147483647 (2GB) that are allowed in a + request body.

    + +

    The LimitRequestBody directive allows + the user to set a limit on the allowed size of an HTTP request + message body within the context in which the directive is given + (server, per-directory, per-file or per-location). If the client + request exceeds that limit, the server will return an error + response instead of servicing the request. The size of a normal + request message body will vary greatly depending on the nature of + the resource and the methods allowed on that resource. CGI scripts + typically use the message body for retrieving form information. + Implementations of the PUT method will require + a value at least as large as any representation that the server + wishes to accept for that resource.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service + attacks.

    + +

    If, for example, you are permitting file upload to a particular + location, and wish to limit the size of the uploaded file to 100K, + you might use the following directive:

    + +

    + LimitRequestBody 102400 +

    + + +
    +
    top
    +

    LimitRequestFields Directive

    + + + + + + + +
    Description:Limits the number of HTTP request header fields that +will be accepted from the client
    Syntax:LimitRequestFields number
    Default:LimitRequestFields 100
    Context:server config
    Status:Core
    Module:core
    +

    Number is an integer from 0 (meaning unlimited) to + 32767. The default value is defined by the compile-time + constant DEFAULT_LIMIT_REQUEST_FIELDS (100 as + distributed).

    + +

    The LimitRequestFields directive allows + the server administrator to modify the limit on the number of + request header fields allowed in an HTTP request. A server needs + this value to be larger than the number of fields that a normal + client request might include. The number of request header fields + used by a client rarely exceeds 20, but this may vary among + different client implementations, often depending upon the extent + to which a user has configured their browser to support detailed + content negotiation. Optional HTTP extensions are often expressed + using request header fields.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks. + The value should be increased if normal clients see an error + response from the server that indicates too many fields were + sent in the request.

    + +

    For example:

    + +

    + LimitRequestFields 50 +

    + + +
    +
    top
    +

    LimitRequestFieldSize Directive

    + + + + + + + +
    Description:Limits the size of the HTTP request header allowed from the +client
    Syntax:LimitRequestFieldsize bytes
    Default:LimitRequestFieldsize 8190
    Context:server config
    Status:Core
    Module:core
    +

    This directive specifies the number of bytes + that will be allowed in an HTTP request header.

    + +

    The LimitRequestFieldSize directive + allows the server administrator to reduce or increase the limit + on the allowed size of an HTTP request header field. A server + needs this value to be large enough to hold any one header field + from a normal client request. The size of a normal request header + field will vary greatly among different client implementations, + often depending upon the extent to which a user has configured + their browser to support detailed content negotiation. SPNEGO + authentication headers can be up to 12392 bytes.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks.

    + +

    For example:

    + +

    + LimitRequestFieldSize 4094 +

    + +
    Under normal conditions, the value should not be changed from + the default.
    + + +
    +
    top
    +

    LimitRequestLine Directive

    + + + + + + + +
    Description:Limit the size of the HTTP request line that will be accepted +from the client
    Syntax:LimitRequestLine bytes
    Default:LimitRequestLine 8190
    Context:server config
    Status:Core
    Module:core
    +

    This directive sets the number of bytes that will be + allowed on the HTTP request-line.

    + +

    The LimitRequestLine directive allows + the server administrator to reduce or increase the limit on the allowed size + of a client's HTTP request-line. Since the request-line consists of the + HTTP method, URI, and protocol version, the + LimitRequestLine directive places a + restriction on the length of a request-URI allowed for a request + on the server. A server needs this value to be large enough to + hold any of its resource names, including any information that + might be passed in the query part of a GET request.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks.

    + +

    For example:

    + +

    + LimitRequestLine 4094 +

    + +
    Under normal conditions, the value should not be changed from + the default.
    + +
    +
    top
    +

    LimitXMLRequestBody Directive

    + + + + + + + + +
    Description:Limits the size of an XML-based request body
    Syntax:LimitXMLRequestBody bytes
    Default:LimitXMLRequestBody 1000000
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    Limit (in bytes) on maximum size of an XML-based request + body. A value of 0 will disable any checking.

    + +

    Example:

    + +

    + LimitXMLRequestBody 0 +

    + + +
    +
    top
    +

    <Location> Directive

    + + + + + + +
    Description:Applies the enclosed directives only to matching +URLs
    Syntax:<Location + URL-path|URL> ... </Location>
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The <Location> directive + limits the scope of the enclosed directives by URL. It is similar to the + <Directory> + directive, and starts a subsection which is terminated with a + </Location> directive. <Location> sections are processed in the + order they appear in the configuration file, after the <Directory> sections and + .htaccess files are read, and after the <Files> sections.

    + +

    <Location> sections operate + completely outside the filesystem. This has several consequences. + Most importantly, <Location> + directives should not be used to control access to filesystem + locations. Since several different URLs may map to the same + filesystem location, such access controls may by circumvented.

    + +

    When to use <Location>

    + +

    Use <Location> to apply + directives to content that lives outside the filesystem. For + content that lives in the filesystem, use <Directory> and <Files>. An exception is + <Location />, which is an easy way to + apply a configuration to the entire server.

    +
    + +

    For all origin (non-proxy) requests, the URL to be matched is a + URL-path of the form /path/. No scheme, hostname, + port, or query string may be included. For proxy requests, the + URL to be matched is of the form + scheme://servername/path, and you must include the + prefix.

    + +

    The URL may use wildcards. In a wild-card string, ? matches + any single character, and * matches any sequences of + characters.

    + +

    Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + +

    + <Location ~ "/(extra|special)/data"> +

    + +

    would match URLs that contained the substring /extra/data + or /special/data. The directive <LocationMatch> behaves + identical to the regex version of <Location>.

    + +

    The <Location> + functionality is especially useful when combined with the + SetHandler + directive. For example, to enable status requests, but allow them + only from browsers at foo.com, you might use:

    + +

    + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +

    + +

    Note about / (slash)

    +

    The slash character has special meaning depending on where in a + URL it appears. People may be used to its behavior in the filesystem + where multiple adjacent slashes are frequently collapsed to a single + slash (i.e., /home///foo is the same as + /home/foo). In URL-space this is not necessarily true. + The <LocationMatch> + directive and the regex version of <Location> require you to explicitly specify multiple + slashes if that is your intention.

    + +

    For example, <LocationMatch ^/abc> would match + the request URL /abc but not the request URL + //abc. The (non-regex) <Location> directive behaves similarly when used for + proxy requests. But when (non-regex) <Location> is used for non-proxy requests it will + implicitly match multiple slashes with a single slash. For example, + if you specify <Location /abc/def> and the + request is to /abc//def then it will match.

    +
    + +

    See also

    + +
    +
    top
    +

    <LocationMatch> Directive

    + + + + + + +
    Description:Applies the enclosed directives only to regular-expression +matching URLs
    Syntax:<LocationMatch + regex> ... </LocationMatch>
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The <LocationMatch> directive + limits the scope of the enclosed directives by URL, in an identical manner + to <Location>. However, + it takes a regular expression as an argument instead of a simple + string. For example:

    + +

    + <LocationMatch "/(extra|special)/data"> +

    + +

    would match URLs that contained the substring /extra/data + or /special/data.

    + +

    See also

    + +
    +
    top
    +

    LogLevel Directive

    + + + + + + + +
    Description:Controls the verbosity of the ErrorLog
    Syntax:LogLevel level
    Default:LogLevel warn
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    LogLevel adjusts the verbosity of the + messages recorded in the error logs (see ErrorLog directive). The following + levels are available, in order of decreasing + significance:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level Description Example
    emerg Emergencies - system is unusable."Child cannot open lock file. Exiting"
    alert Action must be taken immediately."getpwuid: couldn't determine user name from uid"
    crit Critical Conditions."socket: Failed to get a socket, exiting child"
    error Error conditions."Premature end of script headers"
    warn Warning conditions."child process 1234 did not exit, sending another + SIGHUP"
    notice Normal but significant condition."httpd: caught SIGBUS, attempting to dump core in + ..."
    info Informational."Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..."
    debug Debug-level messages"Opening config file ..."
    + +

    When a particular level is specified, messages from all + other levels of higher significance will be reported as well. + E.g., when LogLevel info is specified, + then messages with log levels of notice and + warn will also be posted.

    + +

    Using a level of at least crit is + recommended.

    + +

    For example:

    + +

    + LogLevel notice +

    + +

    Note

    +

    When logging to a regular file messages of the level + notice cannot be suppressed and thus are always + logged. However, this doesn't apply when logging is done + using syslog.

    +
    + +
    +
    top
    +

    MaxKeepAliveRequests Directive

    + + + + + + + +
    Description:Number of requests allowed on a persistent +connection
    Syntax:MaxKeepAliveRequests number
    Default:MaxKeepAliveRequests 100
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The MaxKeepAliveRequests directive + limits the number of requests allowed per connection when + KeepAlive is on. If it is + set to 0, unlimited requests will be allowed. We + recommend that this setting be kept to a high value for maximum + server performance.

    + +

    For example:

    + +

    + MaxKeepAliveRequests 500 +

    + +
    +
    top
    +

    NameVirtualHost Directive

    + + + + + + +
    Description:Designates an IP address for name-virtual +hosting
    Syntax:NameVirtualHost addr[:port]
    Context:server config
    Status:Core
    Module:core
    +

    The NameVirtualHost directive is a + required directive if you want to configure name-based virtual hosts.

    + +

    Although addr can be hostname it is recommended + that you always use an IP address, e.g.

    + +

    + NameVirtualHost 111.22.33.44 +

    + +

    With the NameVirtualHost directive you + specify the IP address on which the server will receive requests + for the name-based virtual hosts. This will usually be the address + to which your name-based virtual host names resolve. In cases + where a firewall or other proxy receives the requests and forwards + them on a different IP address to the server, you must specify the + IP address of the physical interface on the machine which will be + servicing the requests. If you have multiple name-based hosts on + multiple addresses, repeat the directive for each address.

    + +

    Note

    +

    Note, that the "main server" and any _default_ servers + will never be served for a request to a + NameVirtualHost IP address (unless for some + reason you specify NameVirtualHost but then + don't define any VirtualHosts for that + address).

    +
    + +

    Optionally you can specify a port number on which the + name-based virtual hosts should be used, e.g.

    + +

    + NameVirtualHost 111.22.33.44:8080 +

    + +

    IPv6 addresses must be enclosed in square brackets, as shown + in the following example:

    + +

    + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 +

    + +

    To receive requests on all interfaces, you can use an argument of + *

    + +

    + NameVirtualHost * +

    + +

    Argument to <VirtualHost> + directive

    +

    Note that the argument to the <VirtualHost> directive must + exactly match the argument to the NameVirtualHost directive.

    + +

    + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +

    +
    + +

    See also

    + +
    +
    top
    +

    Options Directive

    + + + + + + + + +
    Description:Configures what features are available in a particular +directory
    Syntax:Options + [+|-]option [[+|-]option] ...
    Default:Options All
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Core
    Module:core
    +

    The Options directive controls which + server features are available in a particular directory.

    + +

    option can be set to None, in which + case none of the extra features are enabled, or one or more of + the following:

    + +
    +
    All
    + +
    All options except for MultiViews. This is the default + setting.
    + +
    ExecCGI
    + +
    + Execution of CGI scripts using mod_cgi + is permitted.
    + +
    FollowSymLinks
    + +
    + + The server will follow symbolic links in this directory. +
    +

    Even though the server follows the symlink it does not + change the pathname used to match against <Directory> sections.

    +

    Note also, that this option gets ignored if set + inside a <Location> + section.

    +
    + +
    Includes
    + +
    + Server-side includes provided by mod_include + are permitted.
    + +
    IncludesNOEXEC
    + +
    + + Server-side includes are permitted, but the #exec + cmd and #exec cgi are disabled. It is still + possible to #include virtual CGI scripts from + ScriptAliased + directories.
    + +
    Indexes
    + +
    + If a URL which maps to a directory is requested, and there + is no DirectoryIndex + (e.g., index.html) in that directory, then + mod_autoindex will return a formatted listing + of the directory.
    + +
    MultiViews
    + +
    + Content negotiated + "MultiViews" are allowed using + mod_negotiation.
    + +
    SymLinksIfOwnerMatch
    + +
    The server will only follow symbolic links for which the + target file or directory is owned by the same user id as the + link. + +

    Note

    This option gets ignored if + set inside a <Location> section.
    +
    +
    + +

    Normally, if multiple Options could + apply to a directory, then the most specific one is used and + others are ignored; the options are not merged. (See how sections are merged.) + However if all the options on the + Options directive are preceded by a + + or - symbol, the options are + merged. Any options preceded by a + are added to the + options currently in force, and any options preceded by a + - are removed from the options currently in + force.

    + +

    For example, without any + and - symbols:

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +

    + +

    then only Includes will be set for the + /web/docs/spec directory. However if the second + Options directive uses the + and + - symbols:

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +

    + +

    then the options FollowSymLinks and + Includes are set for the /web/docs/spec + directory.

    + +

    Note

    +

    Using -IncludesNOEXEC or + -Includes disables server-side includes completely + regardless of the previous setting.

    +
    + +

    The default in the absence of any other settings is + All.

    + +
    +
    top
    +

    Require Directive

    + + + + + + + +
    Description:Selects which authenticated users can access +a resource
    Syntax:Require entity-name [entity-name] ...
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Core
    Module:core
    +

    This directive selects which authenticated users can access + a resource. The allowed syntaxes are:

    + +
    +
    Require user userid [userid] + ...
    +
    Only the named users can access the resource.
    + +
    Require group group-name [group-name] + ...
    +
    Only users in the named groups can access the resource.
    + +
    Require valid-user
    +
    All valid users can access the resource.
    +
    + +

    Require must be accompanied by + AuthName and AuthType directives, and directives such + as AuthUserFile + and AuthGroupFile (to + define users and groups) in order to work correctly. Example:

    + +

    + AuthType Basic
    + AuthName "Restricted Resource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +

    + +

    Access controls which are applied in this way are effective for + all methods. This is what is normally + desired. If you wish to apply access controls only to + specific methods, while leaving other methods unprotected, then + place the Require statement into a + <Limit> + section.

    + +

    See also

    + +
    +
    top
    +

    RLimitCPU Directive

    + + + + + + + + +
    Description:Limits the CPU consumption of processes launched +by Apache children
    Syntax:RLimitCPU seconds|max [seconds|max]
    Default:Unset; uses operating system defaults
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit should + be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    CPU resource limits are expressed in seconds per + process.

    + +

    See also

    + +
    +
    top
    +

    RLimitMEM Directive

    + + + + + + + + +
    Description:Limits the memory consumption of processes launched +by Apache children
    Syntax:RLimitMEM bytes|max [bytes|max]
    Default:Unset; uses operating system defaults
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit should + be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    Memory resource limits are expressed in bytes per + process.

    + +

    See also

    + +
    +
    top
    +

    RLimitNPROC Directive

    + + + + + + + + +
    Description:Limits the number of processes that can be launched by +processes launched by Apache children
    Syntax:RLimitNPROC number|max [number|max]
    Default:Unset; uses operating system defaults
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit + should be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    Process limits control the number of processes per user.

    + +

    Note

    +

    If CGI processes are not running + under user ids other than the web server user id, this directive + will limit the number of processes that the server itself can + create. Evidence of this situation will be indicated by + cannot fork messages in the + error_log.

    +
    + +

    See also

    + +
    +
    top
    +

    Satisfy Directive

    + + + + + + + + + +
    Description:Interaction between host-level access control and +user authentication
    Syntax:Satisfy Any|All
    Default:Satisfy All
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Core
    Module:core
    Compatibility:Influenced by <Limit> and <LimitExcept> in version 2.0.51 and +later
    +

    Access policy if both Allow and Require used. The parameter can be + either All or Any. This directive is only + useful if access to a particular area is being restricted by both + username/password and client host address. In this case + the default behavior (All) is to require that the client + passes the address access restriction and enters a valid + username and password. With the Any option the client will be + granted access if they either pass the host restriction or enter a + valid username and password. This can be used to password restrict + an area, but to let clients from particular addresses in without + prompting for a password.

    + +

    For example, if you wanted to let people on your network have + unrestricted access to a portion of your website, but require that + people outside of your network provide a password, you could use a + configuration similar to the following:

    + +

    + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +

    + +

    Since version 2.0.51 Satisfy directives can + be restricted to particular methods by <Limit> and <LimitExcept> sections.

    + +

    See also

    + +
    +
    top
    +

    ScriptInterpreterSource Directive

    + + + + + + + + + +
    Description:Technique for locating the interpreter for CGI +scripts
    Syntax:ScriptInterpreterSource Registry|Registry-Strict|Script
    Default:ScriptInterpreterSource Script
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Win32 only; +option Registry-Strict is available in Apache 2.0 and +later
    +

    This directive is used to control how Apache finds the + interpreter used to run CGI scripts. The default setting is + Script. This causes Apache to use the interpreter pointed to + by the shebang line (first line, starting with #!) in the + script. On Win32 systems this line usually looks like:

    + +

    + #!C:/Perl/bin/perl.exe +

    + +

    or, if perl is in the PATH, simply:

    + +

    + #!perl +

    + +

    Setting ScriptInterpreterSource Registry will + cause the Windows Registry tree HKEY_CLASSES_ROOT to be + searched using the script file extension (e.g., .pl) as a + search key. The command defined by the registry subkey + Shell\ExecCGI\Command or, if it does not exist, by the subkey + Shell\Open\Command is used to open the script file. If the + registry keys cannot be found, Apache falls back to the behavior of the + Script option.

    + +

    Security

    +

    Be careful when using ScriptInterpreterSource + Registry with ScriptAlias'ed directories, because + Apache will try to execute every file within this + directory. The Registry setting may cause undesired + program calls on files which are typically not executed. For + example, the default open command on .htm files on + most Windows systems will execute Microsoft Internet Explorer, so + any HTTP request for an .htm file existing within the + script directory would start the browser in the background on the + server. This is a good way to crash your system within a minute or + so.

    +
    + +

    The option Registry-Strict which is new in Apache + 2.0 does the same thing as Registry but uses only the + subkey Shell\ExecCGI\Command. The + ExecCGI key is not a common one. It must be + configured manually in the windows registry and hence prevents + accidental program calls on your system.

    + +
    +
    top
    +

    ServerAdmin Directive

    + + + + + + +
    Description:Email address that the server includes in error +messages sent to the client
    Syntax:ServerAdmin email-address|URL
    Context:server config, virtual host
    Status:Core
    Module:core
    +

    The ServerAdmin sets the contact address + that the server includes in any error messages it returns to the + client. If the httpd doesn't recognize the supplied argument + as an URL, it + assumes, that it's an email-address and prepends it with + mailto: in hyperlink targets. However, it's recommended to + actually use an email address, since there are a lot of CGI scripts that + make that assumption. If you want to use an URL, it should point to another + server under your control. Otherwise users may not be able to contact you in + case of errors.

    + +

    It may be worth setting up a dedicated address for this, e.g.

    + +

    + ServerAdmin www-admin@foo.example.com +

    +

    as users do not always mention that they are talking about the + server!

    + +
    +
    top
    +

    ServerAlias Directive

    + + + + + + +
    Description:Alternate names for a host used when matching requests +to name-virtual hosts
    Syntax:ServerAlias hostname [hostname] ...
    Context:virtual host
    Status:Core
    Module:core
    +

    The ServerAlias directive sets the + alternate names for a host, for use with name-based virtual hosts.

    + +

    + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +

    + +

    See also

    + +
    +
    top
    +

    ServerName Directive

    + + + + + + + +
    Description:Hostname and port that the server uses to identify +itself
    Syntax:ServerName fully-qualified-domain-name[:port]
    Context:server config, virtual host
    Status:Core
    Module:core
    Compatibility:In version 2.0, this + directive supersedes the functionality of the Port + directive from version 1.3.
    +

    The ServerName directive sets the hostname and + port that the server uses to identify itself. This is used when + creating redirection URLs. For example, if the name of the + machine hosting the web server is simple.example.com, + but the machine also has the DNS alias www.example.com + and you wish the web server to be so identified, the following + directive should be used:

    + +

    + ServerName www.example.com:80 +

    + +

    If no ServerName is specified, then the + server attempts to deduce the hostname by performing a reverse + lookup on the IP address. If no port is specified in the + ServerName, then the server will use the port + from the incoming + request. For optimal reliability and predictability, you should + specify an explicit hostname and port using the + ServerName directive.

    + +

    If you are using name-based virtual hosts, + the ServerName inside a + <VirtualHost> + section specifies what hostname must appear in the request's + Host: header to match this virtual host.

    + +

    See the description of the + UseCanonicalName directive for + settings which determine whether self-referential URL's (e.g., by the + mod_dir module) will refer to the + specified port, or to the port number given in the client's request. +

    + +

    See also

    + +
    +
    top
    +

    ServerPath Directive

    + + + + + + +
    Description:Legacy URL pathname for a name-based virtual host that +is accessed by an incompatible browser
    Syntax:ServerPath URL-path
    Context:virtual host
    Status:Core
    Module:core
    +

    The ServerPath directive sets the legacy + URL pathname for a host, for use with name-based virtual hosts.

    + +

    See also

    + +
    +
    top
    +

    ServerRoot Directive

    + + + + + + + +
    Description:Base directory for the server installation
    Syntax:ServerRoot directory-path
    Default:ServerRoot /usr/local/apache
    Context:server config
    Status:Core
    Module:core
    +

    The ServerRoot directive sets the + directory in which the server lives. Typically it will contain the + subdirectories conf/ and logs/. Relative + paths in other configuration directives (such as Include or LoadModule, for example) are taken as + relative to this directory.

    + +

    Example

    + ServerRoot /home/httpd +

    + + +

    See also

    + +
    +
    top
    +

    ServerSignature Directive

    + + + + + + + + +
    Description:Configures the footer on server-generated documents
    Syntax:ServerSignature On|Off|EMail
    Default:ServerSignature Off
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Core
    Module:core
    +

    The ServerSignature directive allows the + configuration of a trailing footer line under server-generated + documents (error messages, mod_proxy ftp directory + listings, mod_info output, ...). The reason why you + would want to enable such a footer line is that in a chain of proxies, + the user often has no possibility to tell which of the chained servers + actually produced a returned error message.

    + +

    The Off + setting, which is the default, suppresses the footer line (and is + therefore compatible with the behavior of Apache-1.2 and + below). The On setting simply adds a line with the + server version number and ServerName of the serving virtual host, + and the EMail setting additionally creates a + "mailto:" reference to the ServerAdmin of the referenced + document.

    + +

    After version 2.0.44, the details of the server version number + presented are controlled by the ServerTokens directive.

    + +

    See also

    + +
    +
    top
    +

    ServerTokens Directive

    + + + + + + + +
    Description:Configures the Server HTTP response +header
    Syntax:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
    Default:ServerTokens Full
    Context:server config
    Status:Core
    Module:core
    +

    This directive controls whether Server response + header field which is sent back to clients includes a + description of the generic OS-type of the server as well as + information about compiled-in modules.

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    Server sends (e.g.): Server: + Apache
    + +
    ServerTokens Major
    + +
    Server sends (e.g.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Server sends (e.g.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    Server sends (e.g.): Server: + Apache/2.0.41
    + +
    ServerTokens OS
    + +
    Server sends (e.g.): Server: Apache/2.0.41 + (Unix)
    + +
    ServerTokens Full (or not specified)
    + +
    Server sends (e.g.): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2
    +
    + +

    This setting applies to the entire server, and cannot be + enabled or disabled on a virtualhost-by-virtualhost basis.

    + +

    After version 2.0.44, this directive also controls the + information presented by the ServerSignature directive.

    + +

    See also

    + +
    +
    top
    +

    SetHandler Directive

    + + + + + + + + +
    Description:Forces all matching files to be processed by a +handler
    Syntax:SetHandler handler-name|None
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    Compatibility:Moved into the core in Apache 2.0
    +

    When placed into an .htaccess file or a + <Directory> or + <Location> + section, this directive forces all matching files to be parsed + through the handler given by + handler-name. For example, if you had a directory you + wanted to be parsed entirely as imagemap rule files, regardless + of extension, you might put the following into an + .htaccess file in that directory:

    + +

    + SetHandler imap-file +

    + +

    Another example: if you wanted to have the server display a + status report whenever a URL of + http://servername/status was called, you might put + the following into httpd.conf:

    + +

    + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +

    + +

    You can override an earlier defined SetHandler + directive by using the value None.

    + +

    See also

    + +
    +
    top
    +

    SetInputFilter Directive

    + + + + + + + +
    Description:Sets the filters that will process client requests and POST +input
    Syntax:SetInputFilter filter[;filter...]
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    The SetInputFilter directive sets the + filter or filters which will process client requests and POST + input when they are received by the server. This is in addition to + any filters defined elsewhere, including the + AddInputFilter + directive.

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content.

    + +

    See also

    + +
    +
    top
    +

    SetOutputFilter Directive

    + + + + + + + +
    Description:Sets the filters that will process responses from the +server
    Syntax:SetOutputFilter filter[;filter...]
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Core
    Module:core
    +

    The SetOutputFilter directive sets the filters + which will process responses from the server before they are + sent to the client. This is in addition to any filters defined + elsewhere, including the + AddOutputFilter + directive.

    + +

    For example, the following configuration will process all files + in the /www/data/ directory for server-side + includes.

    + +

    + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content.

    + +

    See also

    + +
    +
    top
    +

    TimeOut Directive

    + + + + + + + +
    Description:Amount of time the server will wait for +certain events before failing a request
    Syntax:TimeOut seconds
    Default:TimeOut 300
    Context:server config
    Status:Core
    Module:core
    +

    The TimeOut directive currently defines + the amount of time Apache will wait for three things:

    + +
      +
    1. The total amount of time it takes to receive a GET + request.
    2. + +
    3. The amount of time between receipt of TCP packets on a + POST or PUT request.
    4. + +
    5. The amount of time between ACKs on transmissions of TCP + packets in responses.
    6. +
    + +

    We plan on making these separately configurable at some point + down the road. The timer used to default to 1200 before 1.2, + but has been lowered to 300 which is still far more than + necessary in most situations. It is not set any lower by + default because there may still be odd places in the code where + the timer is not reset when a packet is sent.

    + +
    +
    top
    +

    UseCanonicalName Directive

    + + + + + + + +
    Description:Configures how the server determines its own name and +port
    Syntax:UseCanonicalName On|Off|DNS
    Default:UseCanonicalName Off
    Context:server config, virtual host, directory
    Status:Core
    Module:core
    +

    In many situations Apache must construct a self-referential + URL -- that is, a URL that refers back to the same server. With + UseCanonicalName On Apache will use the hostname and port + specified in the ServerName + directive to construct the canonical name for the server. This name + is used in all self-referential URLs, and for the values of + SERVER_NAME and SERVER_PORT in CGIs.

    + +

    With UseCanonicalName Off Apache will form + self-referential URLs using the hostname and port supplied by + the client if any are supplied (otherwise it will use the + canonical name, as defined above). These values are the same + that are used to implement name based virtual hosts, + and are available with the same clients. The CGI variables + SERVER_NAME and SERVER_PORT will be + constructed from the client supplied values as well.

    + +

    An example where this may be useful is on an intranet server + where you have users connecting to the machine using short + names such as www. You'll notice that if the users + type a shortname, and a URL which is a directory, such as + http://www/splat, without the trailing + slash then Apache will redirect them to + http://www.domain.com/splat/. If you have + authentication enabled, this will cause the user to have to + authenticate twice (once for www and once again + for www.domain.com -- see the + FAQ on this subject for more information). But if + UseCanonicalName is set Off, then + Apache will redirect to http://www/splat/.

    + +

    There is a third option, UseCanonicalName DNS, + which is intended for use with mass IP-based virtual hosting to + support ancient clients that do not provide a + Host: header. With this option Apache does a + reverse DNS lookup on the server IP address that the client + connected to in order to work out self-referential URLs.

    + +

    Warning

    +

    If CGIs make assumptions about the values of SERVER_NAME + they may be broken by this option. The client is essentially free + to give whatever value they want as a hostname. But if the CGI is + only using SERVER_NAME to construct self-referential URLs + then it should be just fine.

    +
    + +

    See also

    + +
    +
    top
    +

    <VirtualHost> Directive

    + + + + + + +
    Description:Contains directives that apply only to a specific +hostname or IP address
    Syntax:<VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>
    Context:server config
    Status:Core
    Module:core
    +

    <VirtualHost> and + </VirtualHost> are used to enclose a group of + directives that will apply only to a particular virtual host. Any + directive that is allowed in a virtual host context may be + used. When the server receives a request for a document on a + particular virtual host, it uses the configuration directives + enclosed in the <VirtualHost> + section. Addr can be:

    + +
      +
    • The IP address of the virtual host;
    • + +
    • A fully qualified domain name for the IP address of the + virtual host;
    • + +
    • The character *, which is used only in combination with + NameVirtualHost * to match all IP addresses; or
    • + +
    • The string _default_, which is used only + with IP virtual hosting to catch unmatched IP addresses.
    • +
    + +

    Example

    + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +

    + + +

    IPv6 addresses must be specified in square brackets because + the optional port number could not be determined otherwise. An + IPv6 example is shown below:

    + +

    + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +

    + +

    Each Virtual Host must correspond to a different IP address, + different port number or a different host name for the server, + in the former case the server machine must be configured to + accept IP packets for multiple addresses. (If the machine does + not have multiple network interfaces, then this can be + accomplished with the ifconfig alias command -- if + your OS supports it).

    + +

    Note

    +

    The use of <VirtualHost> does + not affect what addresses Apache listens on. You + may need to ensure that Apache is listening on the correct addresses + using Listen.

    +
    + +

    When using IP-based virtual hosting, the special name + _default_ can be specified in + which case this virtual host will match any IP address that is + not explicitly listed in another virtual host. In the absence + of any _default_ virtual host the "main" server config, + consisting of all those definitions outside any VirtualHost + section, is used when no IP-match occurs. (But note that any IP + address that matches a NameVirtualHost directive will use neither + the "main" server config nor the _default_ virtual host. + See the name-based virtual hosting + documentation for further details.)

    + +

    You can specify a :port to change the port that is + matched. If unspecified then it defaults to the same port as the + most recent Listen + statement of the main server. You may also specify :* + to match all ports on that address. (This is recommended when used + with _default_.)

    + +

    Security

    +

    See the security tips + document for details on why your security could be compromised if the + directory where log files are stored is writable by anyone other + than the user that starts the server.

    +
    + +

    See also

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/core.html.ja.euc-jp b/trunk/docs/manual/mod/core.html.ja.euc-jp new file mode 100644 index 0000000000..a38574a77f --- /dev/null +++ b/trunk/docs/manual/mod/core.html.ja.euc-jp @@ -0,0 +1,3212 @@ + + + +core - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥³¥¢µ¡Ç½

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + +
    ÀâÌÀ:¾ï¤Ë»ÈÍѲÄǽ¤Ê Apache HTTP ¥µ¡¼¥Ð¤Î¥³¥¢µ¡Ç½
    ¥¹¥Æ¡¼¥¿¥¹:Core
    +
    + + +
    top
    +

    AcceptPathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:¸å¤Ë³¤¯¥Ñ¥¹Ì¾¾ðÊó¤ò¼õ¤±ÉÕ¤±¤ë¥ê¥½¡¼¥¹¤Î»ØÄê
    ¹½Ê¸:AcceptPathInfo On|Off|Default
    ¥Ç¥Õ¥©¥ë¥È:AcceptPathInfo Default
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0.30 °Ê¹ß¤Ç»ÈÍѲÄǽ
    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë̾ (¤â¤·¤¯¤Ï¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î + ¸ºß¤·¤Ê¤¤¥Õ¥¡¥¤¥ë) ¤Î¸å¤Ë³¤¯¥Ñ¥¹Ì¾¾ðÊ󤬤¢¤ë¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤ë¤« + µñÈݤ¹¤ë¤«¤òÀ©¸æ¤·¤Þ¤¹¡£Â³¤­¤Î¥Ñ¥¹Ì¾¾ðÊó¤Ï¥¹¥¯¥ê¥×¥È¤Ë¤Ï PATH_INFO + ´Ä¶­ÊÑ¿ô¤È¤·¤ÆÍøÍѲÄǽ¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢/test/ ¤¬¡¢here.html ¤È¤¤¤¦¥Õ¥¡¥¤¥ë + °ì¤Ä¤Î¤ß¤¬¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ò»Ø¤·¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£¤½¤¦¤¹¤ë¤È¡¢ + /test/here.html/more ¤È /test/nothere.html/more + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ÏξÊý¤È¤â /more ¤ò PATH_INFO ¤È¤·¤Þ¤¹¡£

    + +

    AcceptPathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë»ØÄê²Äǽ¤Ê + »°¤Ä¤Î°ú¿ô¤Ï:

    + +
    +
    Off
    ¥ê¥¯¥¨¥¹¥È¤Ï¸ºß¤¹¤ë¥Ñ¥¹¤Ë¤½¤Î¤Þ¤Þ + ¥Þ¥Ã¥×¤µ¤ì¤ë¾ì¹ç¤Ë¤Î¤ß¼õ¤±ÉÕ¤±¤é¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¾å¤ÎÎã¤Î + /test/here.html/more ¤Î¤è¤¦¤Ë¡¢ËÜÅö¤Î¥Õ¥¡¥¤¥ë̾¤Î + ¸å¤Ë¥Ñ¥¹Ì¾¾ðÊó¤¬Â³¤¯¥ê¥¯¥¨¥¹¥È¤Ë¤Ï 404 NOT FOUND ¥¨¥é¡¼¤¬ÊÖ¤ê¤Þ¤¹¡£
    + +
    On
    Á°¤ÎÊý¤Î¥Ñ¥¹¤¬Â¸ºß¤¹¤ë¥Õ¥¡¥¤¥ë¤Ë¥Þ¥Ã¥×¤¹¤ë¾ì¹ç¤Ï + ¥ê¥¯¥¨¥¹¥È¤¬¼õ¤±ÉÕ¤±¤é¤ì¤Þ¤¹¡£¾å¤ÎÎã¤Î /test/here.html/more + ¤Ï /test/here.html ¤¬Í­¸ú¤Ê¥Õ¥¡¥¤¥ë¤Ë¥Þ¥Ã¥×¤¹¤ì¤Ð + ¼õ¤±ÉÕ¤±¤é¤ì¤Þ¤¹¡£
    + +
    Default
    ³¤­¤Î¥Ñ¥¹Ì¾¾ðÊó¤Î°·¤¤¤Ï¥ê¥¯¥¨¥¹¥È¤Î + ¥Ï¥ó¥É¥é¤Ç·è¤Þ¤ê¤Þ¤¹¡£ + ÉáÄ̤Υե¡¥¤¥ë¤Î¤¿¤á¤Î¥³¥¢¥Ï¥ó¥É¥é¤Î¥Ç¥Õ¥©¥ë¥È¤Ï PATH_INFO ¤òµñÈݤ·¤Þ¤¹¡£ + cgi-script ¤ä isapi-isa ¤Î¤è¤¦¤Ë¥¹¥¯¥ê¥×¥È¤ò°·¤¦¥Ï¥ó¥É¥é¤Ï + °ìÈÌŪ¤Ë¥Ç¥Õ¥©¥ë¥È¤Ç PATH_INFO ¤ò¼õ¤±ÉÕ¤±¤Þ¤¹¡£
    +
    + +

    AcceptPathInfo ¤Î¼ç¤ÊÌÜŪ¤Ï¥Ï¥ó¥É¥é¤Î PATH_INFO ¤ò + ¼õ¤±ÉÕ¤±¤ë¤«µñÈݤ¹¤ë¤«¤ÎÁªÂò¤ò¾å½ñ¤­¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤Ç¤¹¡£ + Î㤨¤Ð¡¢¤³¤ì¤ÏÎ㤨¤Ð INCLUDES ¤Î¤è¤¦¤Ê + ¥Õ¥£¥ë¥¿¤ò»È¤Ã¤Æ PATH_INFO ¤Ë + ´ð¤Å¤¤¤Æ¥³¥ó¥Æ¥ó¥Ä¤òÀ¸À®¤·¤Æ¤¤¤ë¤È¤­¤ËɬÍפˤʤê¤Þ¤¹¡£

    + +

    + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +

    + +
    +
    top
    +

    AccessFileName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ʬ»¶ÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°
    ¹½Ê¸:AccessFileName filename [filename] ...
    ¥Ç¥Õ¥©¥ë¥È:AccessFileName .htaccess
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë¤È¤­¡¢¥µ¡¼¥Ð¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ÂФ·¤Æʬ»¶ÀßÄê¥Õ¥¡¥¤¥ë¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ì¤Ð¡¢ + ¤½¤Î¥É¥­¥å¥á¥ó¥È¤Ø¤Î + ¥Ñ¥¹¾å¤Ë¤¢¤ëÁ´¤Æ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¡¢¤³¤³¤Ç»ØÄꤵ¤ì¤¿Ì¾Á°¤Î°ìÍ÷¤ÎÃæ¤Ç + ºÇ½é¤Ë¸«¤Ä¤«¤Ã¤¿¥Õ¥¡¥¤¥ë¤ò¤½¤ì¤¾¤ìÀßÄê¥Õ¥¡¥¤¥ë¤È¤·¤ÆÆɤ߹þ¤ß¤Þ¤¹¡£Î㤨¤Ð:

    + +

    + AccessFileName .acl +

    + +

    ¤È¤¤¤¦ÀßÄ꤬¤¢¤ë¤È¡¢°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢ + ¥É¥­¥å¥á¥ó¥È /usr/local/web/index.html + ¤òÊÖ¤¹Á°¤Ë¡¢¥µ¡¼¥Ð¤Ï /.acl, /usr/.acl, + /usr/local/.acl, /usr/local/web/.acl ¤«¤é + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÆɤ߹þ¤ß¤Þ¤¹¡£

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory> +

    + +

    »²¾È

    + +
    +
    top
    +

    AddDefaultCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥ì¥¹¥Ý¥ó¥¹¤Î¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤¬ text/plain ¤¢¤ë¤¤¤Ï +text/html ¤Î¾ì¹ç¤ËÄɲ乤ë¥Ç¥Õ¥©¥ë¥È¤Î charset ¥Ñ¥é¥á¡¼¥¿
    ¹½Ê¸:AddDefaultCharset On|Off|charset
    ¥Ç¥Õ¥©¥ë¥È:AddDefaultCharset Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¥ì¥¹¥Ý¥ó¥¹¤Î¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤¬ text/plain + ¤¢¤ë¤¤¤Ï text/html + ¤Î¾ì¹ç¤Ë¸Â¤ê¤Þ¤¹¤¬¡¢¥ì¥¹¥Ý¥ó¥¹¤ËÄɲ乤ë¥á¥Ç¥£¥¢¥¿¥¤¥×¤Îʸ»ú¥»¥Ã¥È¥Ñ¥é¥á¡¼¥¿ + (ʸ»ú¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î̾Á°) ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤò¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï¥ì¥¹¥Ý¥ó¥¹ (ÌõÃí: ¥ì¥¹¥Ý¥ó¥¹¤Î HTML) Æâ¤Ç META + Í×ÁǤǻØÄꤵ¤ì¤¿¡¢¤É¤Î¤è¤¦¤Êʸ»ú¥»¥Ã¥È¤â̵¸ú¤Ë¤·¤Þ¤¹¤¬¡¢ + ºÇ½ªÅª¤ÊµóÆ°¤Ï¥æ¡¼¥¶¤Î¥¯¥é¥¤¥¢¥ó¥È¦¤ÎÀßÄê¤Ç·è¤Þ¤ê¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤Ï AddDefaultCharset Off ¤È¤¤¤¦ÀßÄê¤Ç̵¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + AddDefaultCharset On ¤Ë¤¹¤ì¤Ð¡¢ + Apache ÆâÉô¤Î¥Ç¥Õ¥©¥ë¥Èʸ»ú¥»¥Ã¥È iso-8859-1 ¤ËÀßÄꤵ¤ì¤Þ¤¹¡£ + ¤½¤Î¾ charset ¤Ë»ØÄê¤Ç¤­¤ëÃͤǤ¢¤ì¤Ð¡¢¤É¤ó¤ÊÃͤǤâ»È¤¨¤Þ¤¹¡£ + »ØÄꤹ¤ëÃͤϡ¢MIME ¥á¥Ç¥£¥¢¥¿¥¤¥×¤È¤·¤Æ»È¤ï¤ì¤ë + IANA + ¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ëʸ»ú¥»¥Ã¥È̾¤Î¤¦¤Á¤Î°ì¤Ä¤Ë¤¹¤Ù¤­¤Ç¤¹¡£ + Î㤨¤Ð:

    + +

    + AddDefaultCharset utf-8 +

    + +

    AddDefaultCharset ¤ò»È¤¦¤È¤­¤Ï¡¢Á´¤Æ¤Î¥Æ¥­¥¹¥È¥ê¥½¡¼¥¹¤¬ + »ØÄꤹ¤ëʸ»ú¥¨¥ó¥³¡¼¥É¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤Èʬ¤«¤Ã¤Æ¤¤¤Æ¡¢¤«¤Ä¡¢ + ¥ê¥½¡¼¥¹¤Î¸Ä¡¹¤Ëʸ»ú¥»¥Ã¥È¤ò»ØÄꤹ¤ë¤Î¤¬ÂçÊѤʾì¹ç¤Î¤ß¤Ç¤¹¡£ + Îã¤òµó¤²¤ë¤È¡¢¥ì¥¬¥·¡¼¤Ê CGI ¥¹¥¯¥ê¥×¥È¤Ê¤É¤Î¡¢Æ°Åª¤ËÀ¸À®¤µ¤ì¤ë + ¥³¥ó¥Æ¥ó¥Ä¤ò´Þ¤à¥ê¥½¡¼¥¹¤Ëʸ»ú¥»¥Ã¥È¥Ñ¥é¥á¡¼¥¿¤òÄɲ乤ë¾ì¹ç¤Ç¡¢ + ¥æ¡¼¥¶¤ÎÆþÎϥǡ¼¥¿¤¬½ÐÎϤËÆþ¤ê¡¢¥¯¥í¥¹¥µ¥¤¥È¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¤¬ + °ú¤­µ¯¤³¤µ¤ì¤¦¤ë¾ì¹ç¤Ç¤¹¡£¥Ç¥Õ¥©¥ë¥Èʸ»ú¥»¥Ã¥È¤ò¥»¥Ã¥È¤·¤¿¤È¤·¤Æ¤â¡¢ + ¥Ö¥é¥¦¥¶¤Î "ʸ»ú¥¨¥ó¥³¡¼¥É¤Î¼«Æ°ÁªÂò" µ¡Ç½¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¥æ¡¼¥¶¤ò + ¼é¤ë¤³¤È¤Ë¤Ï¤Ê¤é¤Ê¤¤¤Î¤Ç¡¢¤â¤Á¤í¤ó¤è¤êÎɤ¤²ò·èºö¤Ïñ¤Ë¥¹¥¯¥ê¥×¥È¤ò½¤Àµ + (¤¢¤ë¤¤¤Ïºï½ü) ¤¹¤ë¤³¤È¤Ç¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddOutputFilterByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:MIME-type ¤Ë½ÐÎÏ¥Õ¥£¥ë¥¿¤ò³ä¤êÅö¤Æ¤ë
    ¹½Ê¸:AddOutputFilterByType filter[;filter...] MIME-type +[MIME-type] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0.33 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï±þÅú¤Î MIME-type ¤Ë±þ¤¸¤Æ½ÐÎÏ¥Õ¥£¥ë¥¿¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    ¼¡¤ÎÎã¤Ï mod_deflate ¤Î DEFLATE ¥Õ¥£¥ë¥¿¤ò + »È¤Ã¤Æ¤¤¤Þ¤¹¡£text/html ¤È text/plain ¤Î + ¤¹¤Ù¤Æ¤Î½ÐÎÏ (ÀÅŪ¤Ê¤â¤Î¤âưŪ¤Ê¤â¤Î¤â) ¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ëÁ°¤Ë + °µ½Ì¤·¤Þ¤¹¡£

    + +

    + AddOutputFilterByType DEFLATE text/html text/plain +

    + +

    Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤Ç¥³¥ó¥Æ¥ó¥Ä¤ò½èÍý¤µ¤»¤¿¤¤¤È¤­¤Ï¡¢¤½¤ì¤¾¤ì¤Î̾Á°¤ò¥»¥ß¥³¥í¥ó¤Ç + ʬ¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£³Æ¥Õ¥£¥ë¥¿¤ËÂФ·¤Æ + AddOutputFilterByType ¤ò°ì¤Ä¤º¤Ä½ñ¤¯¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    ¼¡¤ÎÎã¤Ï text/html ¤Î¥¹¥¯¥ê¥×¥È¤Î¤¹¤Ù¤Æ¤Î½ÐÎϤò + ¤Þ¤º INCLUDES ¥Õ¥£¥ë¥¿¤Ç½èÍý¤·¡¢¤µ¤é¤Ë DEFLATE ¥Õ¥£¥ë¥¿¤Ë¤«¤±¤Þ¤¹¡£

    + +

    + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +

    + +

    Ãí:

    +

    AddOutputFilterByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê + Í­¸ú¤Ë¤·¤¿¥Õ¥£¥ë¥¿¤Ï¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢ÉôʬŪ¤â¤·¤¯¤Ï´°Á´¤ËŬÍѤµ¤ì¤Ê¤¤¤³¤È¤¬ + ¤¢¤ê¤Þ¤¹¡£Î㤨¤Ð¡¢MIME ¥¿¥¤¥×¤¬¤¬·èÄê¤Ç¤­¤Ê¤¤¤È¤­¤Ë¤Ï + DefaultType ¤ÎÀßÄ꤬Ʊ¤¸¤À¤Ã¤¿¤È¤·¤Æ¤â¡¢ + DefaultType ÀßÄê¤ò»È¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +

    ¤·¤«¤·¡¢³Î¼Â¤Ë¥Õ¥£¥ë¥¿¤¬Å¬ÍѤµ¤ì¤ë¤è¤¦¤Ë¤·¤¿¤¤¤È¤­¤Ï¡¢¥ê¥½¡¼¥¹¤Ë + ÌÀ¼¨Åª¤Ë¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò³ä¤êÅö¤Æ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ë¤ÏÎ㤨¤Ð + AddType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + ForceType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¡£ + (nph¤Ç¤Ê¤¤) CGI ¥¹¥¯¥ê¥×¥È¤Ç¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤òÀßÄꤹ¤ë¤È¤¤¤¦¤â¤Î¤Ç¤â + Âç¾æÉפǤ¹¡£

    + +

    ¥¿¥¤¥×Ëè¤Î½ÐÎÏ¥Õ¥£¥ë¥¿¤Ï¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Ë¤Ï·è¤·¤ÆŬÍѤµ¤ì¤Þ¤»¤ó¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    AllowEncodedSlashes ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:URL Ãæ¤ÎÉä¹æ²½¤µ¤ì¤¿¥Ñ¥¹Ê¬Î¥Ê¸»ú¤¬Àè¤ËÅÁ¤¨¤é¤ì¤ë¤Î¤òµö²Ä¤¹¤ë¤«¤É¤¦¤«¤ò +·èÄꤹ¤ë
    ¹½Ê¸:AllowEncodedSlashes On|Off
    ¥Ç¥Õ¥©¥ë¥È:AllowEncodedSlashes Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0.46 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    AllowEncodedSlashes ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÉä¹æ²½¤µ¤ì¤¿ + ¥Ñ¥¹Ê¬Î¥Ê¸»ú (/ ¤Ï %2F¡¢¤µ¤é¤Ë¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤Æ¤Ï + \ ¤ËÂбþ¤¹¤ë %5C) ¤¬Â¸ºß¤¹¤ë URL ¤Î»ÈÍѤò + µö²Ä¤¹¤ë¤«¤É¤¦¤«¤ò·èÄꤷ¤Þ¤¹¡£Ä̾ï¤Ï¤½¤Î¤è¤¦¤Ê URL ¤Ï 404 (Not found) ¥¨¥é¡¼ + ¤ÇµñÈݤµ¤ì¤Þ¤¹¡£

    + +

    AllowEncodedSlashes On ¤Ë¤è¤ë + ¥Ñ¥¹Ê¬Î¥Ê¸»ú¤Î»ÈÍѤϡ¢PATH_INFO ¤È¹ç¤ï¤»¤Æ + »È¤¦¤È¤­¤Ë°ìÈÖÌò¤ËΩ¤Á¤Þ¤¹¡£

    +

    Turning AllowEncodedSlashes On is + mostly useful when used in conjunction with PATH_INFO.

    + +

    Ãí

    +

    Éä¹æ²½¤µ¤ì¤¿¥¹¥é¥Ã¥·¥å¤òµö²Ä¤¹¤ë¤³¤È¤Ï¡¢Éü¹æ¤ò¤¹¤ë¤³¤È¤ò + °ÕÌ£¤·¤Þ¤»¤ó¡£%2F ¤ä (´Ø·¸¤¹¤ë¥·¥¹¥Æ¥à¤Ç¤Î) + %5C ¤Ï¡¢Â¾¤ÎÉôʬ¤¬Éü¹æ¤µ¤ì¤¿ URL ¤ÎÃæ¤Ç¤â¤½¤Î¤Þ¤Þ¤Î·Á¼°¤Ç + »Ä¤µ¤ì¤Þ¤¹¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    AllowOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:.htaccess ¤Çµö²Ä¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¼ïÎà
    ¹½Ê¸:AllowOverride All|None|directive-type +[directive-type] ...
    ¥Ç¥Õ¥©¥ë¥È:AllowOverride All
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¥µ¡¼¥Ð¤¬ (AccessFileName ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿) + .htaccess ¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤¿»þ¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ç + Àë¸À¤µ¤ì¤¿¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¤è¤êÁ°¤ËÄêµÁ¤µ¤ì¤¿ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ¾å½ñ¤­¤Ç¤­¤ë¤«¤òÃΤëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    <Directory> ¥»¥¯¥·¥ç¥ó¤Ç¤Î¤ß»ÈÍѲÄǽ

    + AllowOverride ¤ÏÀµµ¬É½¸½Ìµ¤·¤Î<Directory> + ¥»¥¯¥·¥ç¥ó¤Ç¤Î¤ßÍ­¸ú¤Ç¡¢<Location> ¤ä <DirectoryMatch> + ¤ä <Files> ¥»¥¯¥·¥ç¥ó¤Ç¤Ï̵¸ú¤Ç¤¹¡£ +
    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò None ¤ËÀßÄꤹ¤ë¤È¡¢.htaccess ¥Õ¥¡¥¤¥ë¤Ï´°Á´¤Ë + ̵»ë¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢¥µ¡¼¥Ð¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î .htaccess ¥Õ¥¡¥¤¥ë¤òÆɤळ¤È¤ò + »î¤ß¤µ¤¨¤·¤Þ¤»¤ó¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ All ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë»þ¤Ë¤Ï¡¢ + .htaccess ¤È¤¤¤¦ ¥³¥ó¥Æ¥­¥¹¥È ¤ò»ý¤Ä + Á´¤Æ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ÍøÍѤǤ­¤Þ¤¹¡£

    + +

    directive-type ¤Ë¤Ï¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö·²¤Î + ¥­¡¼¥ï¡¼¥É¤Î¤É¤ì¤«¤ò»ØÄꤷ¤Þ¤¹¡£

    + +
    +
    AuthConfig
    + +
    + + ǧ¾Ú¤Ë´Ø¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤòµö²Ä¤¹¤ë (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require ¤Ê¤É)¡£
    + +
    FileInfo
    + +
    + ¥É¥­¥å¥á¥ó¥È¥¿¥¤¥×¤òÀ©¸æ¤¹¤ë¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤòµö²Ä¤¹¤ë (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, + mod_mime ¤Î Add* ¤È Remove* + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ê¤É)¡£
    + +
    Indexes
    + +
    + ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀ©¸æ¤¹¤ë¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤòµö²Ä¤¹¤ë + (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName + ¤Ê¤É)¡£
    + +
    Limit
    + +
    + ¥Û¥¹¥È¤Ø¤Î¥¢¥¯¥»¥¹À©¸æ¤ò¹Ô¤¦¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤòµö²Ä¤¹¤ë (Allow, Deny, Order).
    + +
    Options[=Option,...]
    + +
    + ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤ª¤±¤ëµ¡Ç½¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤòµö²Ä¤¹¤ë + (Options ¤È + XBitHack)¡£ + Options ¤ÇÀßÄꤹ¤ë¥ª¥×¥·¥ç¥ó + ¤ò¡¢(¶õÇò¤ò´Þ¤á¤Ê¤¤) ¥³¥ó¥Þ¶èÀÚ¤ê¤Î¥ê¥¹¥È¤Ë¤·¤ÆÅù¹æ¤Î¸å¤Ë³¤±¤ë¤³¤È¤Ç + ÀßÄê¤Ç¤­¤Þ¤¹¡£
    +
    + +

    Îã:

    + +

    + AllowOverride AuthConfig Indexes +

    + +

    ¾å¤ÎÎã¤Ç¤Ï AuthConfig ¤È Indexes ¤Î¤É¤Á¤é¤Ë¤â + °¤µ¤Ê¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¹¤Ù¤ÆÆâÉô¥µ¡¼¥Ð¥¨¥é¡¼¤ò°ú¤­µ¯¤³¤·¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AuthName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:HTTP ǧ¾Ú¤Îǧ²ÄÎΰè (ÌõÃí: realm)
    ¹½Ê¸:AuthName auth-domain
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ¹¤ëǧ²ÄÎΰè (ÌõÃí: realm) + ¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£ + ǧ²ÄÎΰè¤Ï¡¢ÍøÍѼԤ¬¤É¤Î¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤òÁ÷¿®¤¹¤ì¤Ð¤è¤¤¤Î¤«¤ò + ¥¯¥é¥¤¥¢¥ó¥È¤Ë¶µ¤¨¤ë¤¿¤á¤ËÍøÍѤ·¤Þ¤¹¡£ + AuthName ¤Ï°ì¤Ä¤Î°ú¿ô¤ò¤È¤ê¡¢ + ¥¹¥Ú¡¼¥¹¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¤Ë¤Ï¡¢ + °úÍÑÉä¤Ç³ç¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + AuthType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + Require ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¡¢ + AuthUserFile ¤ä + AuthGroupFile ¤Ê¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + °ì½ï¤ËÍøÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Î㤨¤Ð:

    + +

    + AuthName "Top Secret" +

    + +

    ¤³¤³¤Ç AuthName ¤Ë»ØÄꤷ¤¿Ê¸»úÎ󤬡¢ + ÂçÉôʬ¤Î¥Ö¥é¥¦¥¶¤Î¥Ñ¥¹¥ï¡¼¥É¥À¥¤¥¢¥í¥°¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AuthType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥æ¡¼¥¶Ç§¾Ú¤Î¼ïÎà
    ¹½Ê¸:AuthType Basic|Digest
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÂоݥǥ£¥ì¥¯¥È¥ê¤ÇÍøÍѤ¹¤ë¥æ¡¼¥¶¡¼Ç§¾Ú¤Î¼ïÎà¤òÁª¤Ó¤Þ¤¹¡£ + ¤¿¤À¡¢¸½ºß¤Î¤È¤³¤í¤Ï Basic ¤È Digest ¤·¤« + ¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ + + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï AuthName¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + Require ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¡¢ + AuthUserFile ¤ä AuthGroupFile ¤Ê¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + °ì½ï¤ËÍøÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    CGIMapExtension ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Î°ÌÃÖ¤òÄ´¤Ù¤ë¤¿¤á¤Î¼êË¡
    ¹½Ê¸:CGIMapExtension cgi-path .extension
    ¥Ç¥Õ¥©¥ë¥È:None
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:NetWare ¤Î¤ß
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache ¤¬ CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë¤¿¤á¤Î + ¥¤¥ó¥¿¡¼¥×¥ê¥¿¤òõ¤¹ÊýË¡¤òÀ©¸æ¤·¤Þ¤¹¡£ + Î㤨¤Ð¡¢CGIMapExtension sys:\foo.nlm .foo ¤ÈÀßÄꤹ¤ë¤È + .foo ¤È¤¤¤¦³ÈÄ¥»Ò¤Î¤¹¤Ù¤Æ¤Î CGI ¥¹¥¯¥ê¥×¥È¤Ï FOO ¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ë + ÅϤµ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    ContentDigest ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:Content-MD5 HTTP ±þÅú¥Ø¥Ã¥À¤ÎÀ¸À®¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:ContentDigest On|Off
    ¥Ç¥Õ¥©¥ë¥È:ContentDigest Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Options
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢RFC1864 µÚ¤Ó RFC2068 ¤Ë¤ª¤¤¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë + Content-MD5 ¥Ø¥Ã¥À¡¼¤ÎÀ¸À®¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    MD5 ¤Ï¡¢Ç¤°ÕĹ¤Î¥Ç¡¼¥¿¤Î¡Ö¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¡×(¡Ö»ØÌæ¡× + ¤Èɽ¸½¤µ¤ì¤ë¤³¤È¤â¤¢¤ë) ¤ò·×»»¤¹¤ë¥¢¥ë¥´¥ê¥º¥à¤Ç¡¢ + ¥Ç¡¼¥¿¤ÎÊѹ¹¤¬¤¢¤Ã¤¿¾ì¹ç¤Ë¤ÏÈó¾ï¤Ë¹â¤¤¿®ÍêÅ٤ǥá¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¤ËÊѹ¹¤¬ + È¿±Ç¤µ¤ì¤Þ¤¹¡£

    + +

    Content-MD5 ¥Ø¥Ã¥À¤Ï¡¢¥¨¥ó¥É¥Ä¡¼¥¨¥ó¥É¤Ç + ¥¨¥ó¥Æ¥£¥Æ¥£¥Ü¥Ç¥£¡¼¤Ë´Þ¤Þ¤ì¤ë¥á¥Ã¥»¡¼¥¸¤Î´°Á´À­¥Á¥§¥Ã¥¯ + (Message Integrity Check - MIC)¤òÄ󶡤·¤Þ¤¹¡£ + ¤³¤Î¥Ø¥Ã¥À¤òÄ´¤Ù¤ë¤³¤È¤Ç¡¢¥×¥í¥­¥·¤ä¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢ + ÅÓÃæ·ÐÏ©¤Ë¤ª¤±¤ë¥¨¥ó¥Æ¥£¥Æ¥£¥Ü¥Ç¥£¤Îͽ´ü¤»¤ÌÊѹ¹¤Ê¤É¤ò + ¸¡½Ð¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥Ø¥Ã¥À¤ÎÎã:

    + +

    + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== +

    + +

    ¥ê¥¯¥¨¥¹¥ÈËè¤Ë¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¤ò·×»»¤¹¤ë (Ãͤϥ­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó) + ¤³¤È¤«¤é¡¢ + ¥µ¡¼¥Ð¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬Äã²¼¤¹¤ë¤³¤È¤Ë¤Ä¤¤¤ÆÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Content-MD5¤Ï¡¢core µ¡Ç½¤Ë¤è¤ê½èÍý¤µ¤ì¤¿ + ¥É¥­¥å¥á¥ó¥È¤òÁ÷¤ë¤È¤­¤Î¤ßÍ­¸ú¤Ç¤¢¤ê¡¢ + SSI ¥É¥­¥å¥á¥ó¥È¤ä CGI ¥¹¥¯¥ê¥×¥È¤Î½ÐÎÏ¡¢¥Ð¥¤¥È¥ì¥ó¥¸¤ò»ØÄꤷ¤¿ + ±þÅú¤Î¾ì¹ç¤Ë¤Ï¤³¤Î¥Ø¥Ã¥À¤ÏÉÕÍ¿¤µ¤ì¤Þ¤»¤ó¡£ +

    + +
    +
    top
    +

    DefaultType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò·èÄê¤Ç¤­¤Ê¤¤¤È¤­¤Ë +Á÷¤é¤ì¤ë MIME ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×
    ¹½Ê¸:DefaultType MIME-type
    ¥Ç¥Õ¥©¥ë¥È:DefaultType text/plain
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¥µ¡¼¥Ð¤Ï¡¢MIME ¤Î¥¿¥¤¥×¥Þ¥Ã¥×¤«¤é¤Ï·èÄê¤Ç¤­¤Ê¤¤ + ¥É¥­¥å¥á¥ó¥È¤ÎÁ÷¿®¤òÍ׵ᤵ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤Î¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÄÌÃΤ¹¤ëɬÍפ¬ + ¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢¤³¤Î¤è¤¦¤Ë¥¿¥¤¥×¤¬Ì¤ÃΤξì¹ç¤Ï + DefaultType ¤Ç»ØÄꤵ¤ì¤¿¥¿¥¤¥×¤òÍøÍѤ·¤Þ¤¹¡£ + Îã:

    + +

    + DefaultType image/gif +

    + +

    ¤³¤ì¤Ï .gif ¤È¤¤¤¦³ÈÄ¥»Ò¤¬¥Õ¥¡¥¤¥ë̾¤Ë´Þ¤Þ¤ì¤Æ¤¤¤Ê¤¤ + ¿¤¯¤Î GIF ²èÁü¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ËŬ¤·¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ForceType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + °ã¤Ã¤Æ¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ç¥Õ¥©¥ë¥È¤Î MIME ¥¿¥¤¥×¤òÄ󶡤¹¤ë¤À¤±¤Ç + ¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò´Þ¤á¡¢ + ¥á¥Ç¥£¥¢¥¿¥¤¥×¤ò·èÄê¤Ç¤­¤ë¾¤Î MIME ¥¿¥¤¥×¤ÎÄêµÁ¤¬¤¢¤ì¤Ð + ¤³¤Î¥Ç¥Õ¥©¥ë¥È¤Ï¾å½ñ¤­¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    <Directory> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:»ØÄê¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤È¤Î¤ß¤Ë +ŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    ¹½Ê¸:<Directory directory-path> +... </Directory>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    »ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Î¤ß + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬÍѤµ¤»¤ë¤¿¤á¤Ë¤Ï¡¢ + <Directory> ¤È + </Directory> ¤òÂФȤ·¤Æ¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö·²¤ò°Ï¤¤¤Þ¤¹¡£ + ¤½¤ÎÃæ¤Ë¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê¥³¥ó¥Æ¥­¥¹¥È¤Çµö²Ä¤µ¤ì¤¿Á´¤Æ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÍøÍѤǤ­¤Þ¤¹¡£ + directive-path ¤Ï¡¢¥Õ¥ë¥Ñ¥¹¤â¤·¤¯¤Ï Unix ¤Î¥·¥§¥ë·Á¼°¤Î + ¥ï¥¤¥ë¥É¥«¡¼¥É¤ò»ØÄꤷ¤Þ¤¹¡£ + ? ¤ÏǤ°Õ¤Î 1 ʸ»ú¡¢* ¤ÏǤ°Õ¤Îʸ»úÎó¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + ¥·¥§¥ë¤Ë¤ª¤±¤ë»ØÄêƱÍÍ¡¢Ê¸»ú¤ÎÈϰϤò [] ¤Ç»ØÄê¤Ç¤­¤Þ¤¹¡£ + ¥ï¥¤¥ë¥É¥«¡¼¥É¤Ï `/' ʸ»ú¤Ë¤Ï¥Þ¥Ã¥Á¤·¤Þ¤»¤ó¤Î¤Ç¡¢ + /home/user/public_html ¤Ë¤Ï + <Directory /*/public_html> ¤Ï¥Þ¥Ã¥Á¤·¤Þ¤»¤ó¤¬¡¢ + <Directory /home/*/public_html> ¤Ï¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + Îã:

    + +

    + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +

    + +
    +

    directory-path °ú¿ô¤Ë¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤: ¤½¤Î°ú¿ô¤Ï +Apache ¤¬¥Õ¥¡¥¤¥ë¤ò¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Ë»È¤¦¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ñ¥¹¤Ë +¤½¤Î¤Þ¤Þ¥Þ¥Ã¥Á¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¢¤ë <Directory> ¤Ë +ŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Ê̤Υ·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò¤¿¤É¤Ã¤¿¤ê¤·¤Æ +Ʊ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤ò°ã¤¦¥Ñ¥¹¤Ç¥¢¥¯¥»¥¹¤·¤¿¾ì¹ç¤Ë¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£

    +
    + +

    ~ ¤È¤¤¤¦Ê¸»ú¤ò + Éղ乤뤳¤È¤Ç³ÈÄ¥Àµµ¬É½¸½¤òÍøÍѤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð:

    + +

    + <Directory ~ "^/www/.*/[0-9]{3}"> +

    + +

    ¤È¤¤¤Ã¤¿»ØÄê¤Î¾ì¹ç¡¢/www/ °Ê²¼¤Ë¤¢¤ë¿ô»ú + 3 ʸ»ú¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + +

    ¤â¤·Ê£¿ô¤Î (Àµµ¬É½¸½°Ê³°¤Î) <Directory>¥»¥¯¥·¥ç¥ó¤¬ + ¥É¥­¥å¥á¥ó¥È¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê (¤ä¤½¤Î¾å°Ì¥Ç¥£¥ì¥¯¥È¥ê¤Î¤É¤ì¤«) ¤È¥Þ¥Ã¥Á¤·¤¿¤Ê¤é¤Ð¡¢ + .htaccess ¥Õ¥¡¥¤¥ë¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤âÆɤ߹þ¤ß¤Ä¤Ä¡¢ + û¤¤¥Ñ¥¹¤«¤é½ç¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢

    + +

    + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +

    + +

    ¤ÈÀßÄꤷ¡¢¥É¥­¥å¥á¥ó¥È /home/web/dir/doc.html ¤Ø¤Î + ¥¢¥¯¥»¥¹¤¬¤¢¤Ã¤¿¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ËÆ°ºî¤·¤Þ¤¹:

    + +
      +
    • AllowOverride None ¤¬Å¬ÍѤµ¤ì¤ë¡£ + (.htaccess ¥Õ¥¡¥¤¥ë¤Ï̵¸ú¤Ë¤Ê¤ë)
    • + +
    • AllowOverride FileInfo ¤¬Å¬ÍѤµ¤ì¤ë + (/home ¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ)¡£
    • + +
    • /home/.htaccess, /home/web/.htaccess, + /home/web/.htaccess ¤Î½ç¤Ë¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ëÃæ¤Î + FileInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Å¬ÍѤµ¤ì¤ë¡£
    • +
    + +

    Àµµ¬É½¸½¤Ï¡¢Ä̾ï¤Î¥»¥¯¥·¥ç¥ó¤¬¤¹¤Ù¤ÆŬÍѤµ¤ì¤ë¤Þ¤Ç + ¹Í褵¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¸å¡¢Á´¤Æ¤ÎÀµµ¬É½¸½¤¬ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤¿½ç¤Ç»î¤µ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢°Ê²¼¤Î¤è¤¦¤Ê¾ì¹ç¤Ë

    + +

    + <Directory ~ abc$>
    + + # ... directives here ...
    +
    + </Directory> +

    + +

    Àµµ¬É½¸½¤Î¥»¥¯¥·¥ç¥ó¤Ï¤¹¤Ù¤Æ¤ÎÄ̾ï¤Î <Directory> ¤È + .htaccess ¤ÎŬÍѤ¬½ª¤ï¤ë¤Þ¤Ç¹Í褵¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¸å¤Ç¡¢Àµµ¬É½¸½¤Ï /home/abc/public_html/abc ¤Ë¥Þ¥Ã¥Á¤·¡¢ + Âбþ¤¹¤ë <Directory> ¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£

    + +

    Apache ¤Î¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï <Directory /> ¤Ø¤Î¥¢¥¯¥»¥¹¤Ï + Allow from All ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤ì¤Ï¡¢URL ¤«¤é¥Þ¥Ã¥×¤µ¤ì¤¿¤É¤Î¥Õ¥¡¥¤¥ë¤Ç¤â Apache ¤ÏÁ÷¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + ¤³¤ì¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤·¤ÆÊѹ¹¤¹¤ë¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +

    + +

    ¤½¤·¤Æ¥¢¥¯¥»¥¹¤ò²Äǽ¤Ë¤·¤¿¤¤¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ + ¸ÄÊ̤ËÀßÄꤹ¤ì¤Ð¤è¤¤¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¤¢¤¿¤ê¤Ë¤Ä¤¤¤Æ¤Ï¡¢¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë¥³¥Ä¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê¥»¥¯¥·¥ç¥ó¤Ï httpd.conf ¥Õ¥¡¥¤¥ë½ñ¤­¤Þ¤¹¡£ + <Directory> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÆþ¤ì»Ò¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤º¡¢ + <Limit> ¤ä <LimitExcept> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ë¤â + µ­½Ò¤Ç¤­¤Þ¤»¤ó¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    <DirectoryMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Àµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È +¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤È¤Î¤ß¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    ¹½Ê¸:<DirectoryMatch regex> +... </DirectoryMatch>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <Directory> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱÍͤˡ¢<DirectoryMatch> + ¤È </DirectoryMatch> ¤Ï»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤È + ¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Î¤ßŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö·²¤ò°Ï¤¤¤Þ¤¹¡£ + ¤·¤«¤·¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï°ú¿ô¤È¤·¤ÆÀµµ¬É½¸½¤ò¤È¤ê¤Þ¤¹¡£Î㤨¤Ð:

    + +

    + <DirectoryMatch "^/www/(.+/)?[0-9]{3}"> +

    + +

    ¤Ï /www/ °Ê²¼¤Ë¤¢¤ë¿ô»ú 3 ʸ»ú¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    DocumentRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¦¥§¥Ö¤«¤é¸«¤¨¤ë¥á¥¤¥ó¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Ë¤Ê¤ë +¥Ç¥£¥ì¥¯¥È¥ê
    ¹½Ê¸:DocumentRoot directory-path
    ¥Ç¥Õ¥©¥ë¥È:DocumentRoot /usr/local/apache/htdocs
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢httpd + ¤¬¥Õ¥¡¥¤¥ë¤òÄ󶡤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤òÀßÄꤷ¤Þ¤¹¡£ + Alias ¤Î¤è¤¦¤Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¥Þ¥Ã¥Á¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢ + ¥É¥­¥å¥á¥ó¥È¤Î (ÌõÃí:¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î) ¥Ñ¥¹¤òÀ¸À®¤¹¤ë¤¿¤á¤Ë¡¢ + ¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ URL ¤Î¥Ñ¥¹Éôʬ¤ò¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È¤ËÉÕÍ¿¤·¤Þ¤¹¡£ + Îã:

    + +

    + DocumentRoot /usr/web +

    + +

    ¤³¤Î¾ì¹ç¡¢ + http://www.my.host.com/index.html ¤Ø¤Î¥¢¥¯¥»¥¹¤¬¤¢¤ì¤Ð + /usr/web/index.html ¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£ + directory-path ¤¬ÀäÂХѥ¹¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢ + ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£

    + +

    DocumentRoot ¤ÏºÇ¸å¤Î¥¹¥é¥Ã¥·¥å̵¤·¤Ç + »ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    EnableMMAP ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ÇÛÁ÷Ãæ¤Ë¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤à¤¿¤á¤Ë¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò +»È¤¦¤«¤É¤¦¤«
    ¹½Ê¸:EnableMMAP On|Off
    ¥Ç¥Õ¥©¥ë¥È:EnableMMAP On
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÇÛÁ÷Ãæ¤Ë¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÆɤ߹þ¤àɬÍפ¬¤¢¤ë¤È¤­¤Ë + httpd ¤¬¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò»È¤¦¤«¤É¤¦¤«¤òÀ©¸æ¤·¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢ + Î㤨¤Ð¡¢mod_include ¤ò»È¤Ã¤Æ SSI ¥Õ¥¡¥¤¥ë¤òÇÛÁ÷ + ¤¹¤ë¤È¤­¤Î¤è¤¦¤Ë¡¢¥Õ¥¡¥¤¥ë¤ÎÅÓÃæ¤Î¥Ç¡¼¥¿¤ò¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ë¤È¤­¤Ë¤Ï + Apache ¤Ï OS ¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ì¤Ð¥Õ¥¡¥¤¥ë¤ò¥á¥â¥ê¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£

    + +

    + ¤³¤Î¥á¥â¥ê¥Þ¥Ã¥×¤ÏÀ­Ç½¤Î¸þ¾å¤ò»ý¤¿¤é¤¹¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤·¤«¤·¡¢´Ä¶­¤Ë¤è¤Ã¤Æ¤Ï±¿ÍѾå¤ÎÌäÂê¤òËɤ°¤¿¤á¤Ë¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò + »ÈÍѤ·¤Ê¤¤¤è¤¦¤Ë¤·¤¿Êý¤¬Îɤ¤¾ì¹ç¤â¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¥Þ¥ë¥Á¥×¥í¥»¥Ã¥µ¥·¥¹¥Æ¥à¤ÎÃæ¤Ë¤Ï¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò¤¹¤ë¤È + httpd ¤ÎÀ­Ç½¤¬Íî¤Á¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    • NFS ¥Þ¥¦¥ó¥È¤µ¤ì¤¿ DocumentRoot + ¤Ç¤Ï¡¢httpd ¤¬¥á¥â¥ê¥Þ¥Ã¥×¤·¤Æ¤¤¤ë´Ö¤Ë¥Õ¥¡¥¤¥ë¤¬ºï½ü¤µ¤ì¤¿¤ê + û¤¯¤Ê¤Ã¤¿¤ê¤·¤¿¤È¤­¤Ëµ¯¤³¤ë¥»¥°¥á¥ó¥Æ¡¼¥·¥ç¥ó¥Õ¥©¡¼¥ë¥È¤Î¤¿¤á¤Ë + httpd ¤¬¥¯¥é¥Ã¥·¥å¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    + +

    ¤³¤ì¤é¤ÎÌäÂê¤ËÅö¤Æ¤Ï¤Þ¤ë¥µ¡¼¥Ð¤ÎÀßÄê¤Î¾ì¹ç¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ + ¥Õ¥¡¥¤¥ë¤ÎÇÛÁ÷»þ¤Î¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò»ÈÍÑÉԲĤˤ·¤Æ¤¯¤À¤µ¤¤:

    + +

    + EnableMMAP Off +

    + +

    NFS ¥Þ¥¦¥ó¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢ÌäÂê¤Î¤¢¤ë¥Õ¥¡¥¤¥ë¤Ë¤Î¤ßÌÀ¼¨Åª¤Ë + ¤³¤Îµ¡Ç½¤ò»ÈÍÑÉԲĤˤ·¤Þ¤¹:

    + +

    + <Directory "/path-to-nfs-files"> + + EnableMMAP Off + + </Directory> +

    + +
    +
    top
    +

    EnableSendfile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ø¤ÎÇÛÁ÷»þ¤Ë¥«¡¼¥Í¥ë¤Î sendfile ¥µ¥Ý¡¼¥È¤ò +»È¤¦¤«¤É¤¦¤«
    ¹½Ê¸:EnableSendfile On|Off
    ¥Ç¥Õ¥©¥ë¥È:EnableSendfile On
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0.44 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¤Ë¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÁ÷¤ë¤È¤­¤Ë + httpd ¤¬¥«¡¼¥Í¥ë¤Î + sendfile ¥µ¥Ý¡¼¥È¤ò»È¤¦¤«¤É¤¦¤«¤òÀ©¸æ¤·¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢ + Î㤨¤ÐÀÅŪ¤Ê¥Õ¥¡¥¤¥ë¤ÎÇÛÁ÷¤Î¤è¤¦¤Ë¡¢¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤Ë¥Õ¥¡¥¤¥ë¤Î + ÅÓÃæ¤Î¥Ç¡¼¥¿¤Î¥¢¥¯¥»¥¹¤òɬÍפȤ·¤Ê¤¤¤È¤­¤Ë¤Ï¡¢Apache ¤Ï OS ¤¬ + ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ì¤Ð¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤à¤³¤È¤Ê¤¯ sendfile ¤ò»È¤Ã¤Æ + ¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÁ÷¤ê¤Þ¤¹¡£

    + +

    sendfile ¤Ï read ¤È send ¤òÊÌ¡¹¤Ë¹Ô¤Ê¤¦¤³¤È¤È¡¢¥Ð¥Ã¥Õ¥¡¤Î³ä¤êÅö¤Æ¤ò + ²óÈò¤·¤Þ¤¹¡£¤·¤«¤·¡¢¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤ä¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎÃæ¤Ë¤Ï + ±¿ÍѾå¤ÎÌäÂê¤òÈò¤±¤ë¤¿¤á¤Ë¤³¤Îµ¡Ç½¤ò»ÈÍÑÉԲĤˤ·¤¿Êý¤¬Îɤ¤¾ì¹ç¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤ÎÃæ¤Ë¤Ï¥Ó¥ë¥É¥·¥¹¥Æ¥à¤¬¸¡ÃΤǤ­¤Ê¤«¤Ã¤¿¡¢²õ¤ì¤¿ + sendfile ¤Î¥µ¥Ý¡¼¥È¤¬Â¸ºß¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤ÏÆÃ¤Ë + ¥Ð¥¤¥Ê¥ê¤¬Ê̤Υޥ·¥ó¤Ç¥Ó¥ë¥É¤µ¤ì¡¢²õ¤ì¤¿ sendfile ¤Î¤¢¤ë¥Þ¥·¥ó¤Ë + °ÜÆ°¤·¤¿¤È¤­¤Ëµ¯¤³¤ê¤Þ¤¹¡£
    • +
    • Linux ¤Ç¤Ï¡¢sendfile ¤òÍѤ¤¤ë¤È¡¢ + IPv6 »ÈÍÑ»þ¤Ë¸ºß¤¹¤ëÆÃÄê¥Í¥Ã¥È¥ï¡¼¥¯¥«¡¼¥É¤Î TCP-checksum + ¥ª¥Õ¥í¡¼¥É¤Î¥Ð¥°¤òƧ¤ó¤Ç¤·¤Þ¤¤¤Þ¤¹¡£
    • +
    • ¥Í¥Ã¥È¥ï¡¼¥¯¥Þ¥¦¥ó¥È¤µ¤ì¤¿ DocumentRoot + (Î㤨¤Ð NFS ¤ä SMB) + ¤Ç¤Ï¡¢¥«¡¼¥Í¥ë¤Ï¼«¿È¤Î¥­¥ã¥Ã¥·¥å¤ò»È¤Ã¤Æ¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î¥Õ¥¡¥¤¥ë¤ò + Á÷¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    + +

    ¤³¤ì¤é¤ÎÌäÂê¤ËÅö¤Æ¤Ï¤Þ¤ë¥µ¡¼¥Ð¤ÎÀßÄê¤Î¾ì¹ç¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ + ¤³¤Îµ¡Ç½¤ò»ÈÍÑÉԲĤˤ·¤Æ¤¯¤À¤µ¤¤:

    + + +

    + EnableSendfile Off +

    + +

    NFS ¤ä SMB ¥Þ¥¦¥ó¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢ÌäÂê¤Î¤¢¤ë¥Õ¥¡¥¤¥ë¤Ë¤Î¤ßÌÀ¼¨Åª¤Ë + ¤³¤Îµ¡Ç½¤ò»ÈÍÑÉԲĤˤ·¤Þ¤¹:

    + +

    + <Directory "/path-to-nfs-files"> + + EnableSendfile Off + + </Directory> +

    + +
    +
    top
    +

    ErrorDocument ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤Ë¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¤â¤Î
    ¹½Ê¸:ErrorDocument error-code document
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0 ¤Ç¤Ï¥Æ¥­¥¹¥È¤ò¥¯¥¦¥©¡¼¥È¤¹¤ë¹½Ê¸¤¬°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤«¤é +ÊѤï¤Ã¤Æ¤¤¤Þ¤¹¡£
    +

    ÌäÂê¤ä¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤ÎÆ°ºî¤È¤·¤Æ¡¢ + Apache ¤Ë¤Ï°Ê²¼¤Î»Í¤Ä¤Î¤¦¤Á°ì¤Ä¤ÎÆ°ºî¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
      +
    1. Apache ɸ½à¤Î´Êñ¤Ê¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤òɽ¼¨
    2. + +
    3. ¼«Ê¬¤Ç»ØÄꤷ¤¿¥á¥Ã¥»¡¼¥¸¤òɽ¼¨
    4. + +
    5. ÌäÂê¤ä¥¨¥é¡¼¤Î½èÍý¤ò¤¹¤ë°Ù¤Ë¡¢¼«¥µ¡¼¥ÐÆâ¤Î + URL-path ¤Ø¥ê¥À¥¤¥ì¥¯¥È
    6. + +
    7. ÌäÂê¤ä¥¨¥é¡¼¤Î½èÍý¤ò¤¹¤ë°Ù¤Ë¡¢³°Éô¤Î URL ¤Ø¥ê¥À¥¤¥ì¥¯¥È
    8. +
    + +

    ºÇ½é¤Î¤â¤Î¤¬¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¡¢2 ÈÖÌܤ«¤é 4 ÈÖÌܤϡ¢ + ErrorDocument¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢ + HTTP ¤Î¥ì¥¹¥Ý¥ó¥¹¥³¡¼¥É¤È¡¢¥á¥Ã¥»¡¼¥¸¤« URL ¤ò»ØÄꤹ¤ë¤³¤È¤ÇÀßÄꤷ¤Þ¤¹¡£ + Apache ¤¬ÌäÂê¤â¤·¤¯¤Ï¥¨¥é¡¼¤Ë´Ø¤¹¤ëÄɲþðÊó¤òÄ󶡤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    URL ¤Î¾ì¹ç¤Ï¡¢¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤ë (/) ¥í¡¼¥«¥ë¤Î web-path ( + DocumentRoot ¤«¤é¤ÎÁêÂХѥ¹ + ) ¤«¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬²ò·è¤Ç¤­¤ë´°Á´¤Ê URL ¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤â¤·¤¯¤Ï¡¢¥Ö¥é¥¦¥¶¤Ëɽ¼¨¤µ¤ì¤ë¥á¥Ã¥»¡¼¥¸¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£ + Îã:

    + +

    + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/bad_urls.pl
    + ErrorDocument 401 /subscription_info.html
    + ErrorDocument 403 "Sorry can't allow you access today" +

    + +

    ²Ã¤¨¤Æ¡¢ÆÃÊ̤ÊÃÍ default ¤ò»È¤Ã¤Æ Apache ¤Ë + ¥Ï¡¼¥É¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ë´Êñ¤Ê¥á¥Ã¥»¡¼¥¸¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Ä̾ï¤ÏɬÍפǤϤ¢¤ê¤Þ¤»¤ó¤¬¡¢default ¤ò»È¤¦¤È + ´û¸¤Î ErrorDocument ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤ò + ·Ñ¾µ¤¹¤ë¤È¤³¤í¤Ç¡¢Apache ¤Î¥Ï¡¼¥É¥³¡¼¥É¤µ¤ì¤¿´Êñ¤Ê¥á¥Ã¥»¡¼¥¸¤Ë + Ì᤹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +

    + +

    ¥ê¥â¡¼¥È URL (Î㤨¤Ð¡¢Æ¬¤Ë http ¤ÈÉÕÍ¿¤·¤¿ÊýË¡) ¤ò + ErrorDocument ¤Ë»ØÄꤹ¤ë¤È¤­¡¢ + ¤¿¤È¤¨Ê¸½ñ¤¬Æ±¤¸¥µ¡¼¥Ð¤Ë¤¢¤í¤¦¤È¤â¡¢¥É¥­¥å¥á¥ó¥È¤¬¤É¤³¤Ë¤¢¤ë¤«¤òÄÌÃΤ¹¤ë¤¿¤á¤Ë¡¢ + Apache ¤Ï¥ê¥À¥¤¥ì¥¯¥È¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷½Ð¤¹¤ë¤È¤¤¤¦¤³¤È¤Ë¡¢Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤ì¤Ë¤Ï¤¤¤í¤¤¤í¤È´ØÏ¢¤·¤Æµ¯¤³¤ëÌäÂ꤬¤¢¤ê¤Þ¤¹¡£ + Ãæ¤Ç¤âºÇ¤â½ÅÍפʤΤϡ¢¥¯¥é¥¤¥¢¥ó¥È¤Ï¸µ¡¹¤Î¥¨¥é¡¼¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤ò¼õ¤±¼è¤é¤º¡¢ + Âå¤ï¤ê¤Ë¥ê¥À¥¤¥ì¥¯¥È¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤ò¼õ¤±¼è¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤ò»È¤Ã¤Æ URL ¤¬Í­¸ú¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò·èÄꤷ¤è¤¦¤È¤¹¤ë + ¥¦¥§¥Ö¥í¥Ü¥Ã¥È¤ä¤½¤Î¾¥¯¥é¥¤¥¢¥ó¥È¤ò¡¢º®Í𤵤»¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤µ¤é¤Ë¡¢ErrorDocument 401 ¤Ë¥ê¥â¡¼¥È¤Î URL ¤ò»ØÄꤹ¤ë¤È¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤Ï 401 ¤È¤¤¤¦¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤ò¼õ¤±¼è¤é¤Ê¤¤¤¿¤á¡¢ + ¥Ñ¥¹¥ï¡¼¥É¤ò¥æ¡¼¥¶¡¼¤ËÆþÎÏÍ׵ᤷ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤¬¤ï¤«¤ê¤Þ¤»¤ó¡£ + ½¾¤Ã¤Æ¡¢ErrorDocument 401 ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¾ì¹ç¤Ï¡¢ + ɬ¤º¥í¡¼¥«¥ë¤Êʸ½ñ¤ò»²¾È¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    Microsoft Internet Explorer (MSIE) ¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥µ¡¼¥Ð¤¬À¸À®¤·¤¿¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤¬ + ¡Ö¾®¤µ¤¹¤®¤ë¡×¤È¤­¤Ë¤Ï̵»ë¤ò¤·¤Æ¼«Ê¬¼«¿È¤Î¡Ö¤ä¤µ¤·¤¤¡×¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ç + ÃÖ´¹¤·¤Þ¤¹¡£¥µ¥¤¥º¤Î¤·¤­¤¤Ãͤϥ¨¥é¡¼¤Î¼ïÎà¤Ë¤è¤Ã¤Æ°Û¤Ê¤ê¤Þ¤¹¤¬¡¢ + °ìÈÌŪ¤Ë¤Ï¥¨¥é¡¼¤Îʸ½ñ¤ò 512 ¥Ð¥¤¥È¤è¤ê¤â¿¤­¤¯¤¹¤ë¤È¡¢MSIE ¤Ï + ¥µ¡¼¥Ð¤¬À¸À®¤·¤¿¥¨¥é¡¼¤ò±£¤µ¤º¤Ëɽ¼¨¤·¤Þ¤¹¡£¾Ü¤·¤¤¾ðÊó¤Ï Microsoft + Knowledge Base ¤Îµ­»ö Q294807 + ¤Ë¤¢¤ê¤Þ¤¹¡£

    + +

    ¤Û¤È¤ó¤É¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò¾å½ñ¤­¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ÆÃÄê¤Î¾õ¶·²¼¤Ç¤Ï + ErrorDocument ¤ÎÀßÄê¤Ë¤«¤«¤ï¤é¤º + Æ⢤Υá¥Ã¥»¡¼¥¸¤¬»È¤ï¤ì¤Þ¤¹¡£ + Æäˡ¢ÉÔÀµ¤Ê·Á¼°¤Î¥ê¥¯¥¨¥¹¥È¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¡¢Ä̾ï¤Î¥ê¥¯¥¨¥¹¥È½èÍý¤Ï + ¨ºÂ¤ËÃæ»ß¤µ¤ì¡¢Æ⢤Υ¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î½èÃÖ¤ÏÉÔÀµ¤Ê¥ê¥¯¥¨¥¹¥È¤Ë¤è¤Ã¤Æ°ú¤­µ¯¤³¤µ¤ì¤ë¡¢¥»¥­¥å¥ê¥Æ¥£ÌäÂ꤫¤é + ¼é¤ë¤¿¤á¤ËɬÍפÊÁ¼Ã֤Ǥ¹¡£

    + +

    2.0 ¤è¤êÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢ÂФˤʤäƤ¤¤Ê¤¤Æó½Å°úÍÑÉä¤ò + ÀèƬ¤ËÉÕ¤±¤ë¤³¤È¤Ë¤è¤ê¥á¥Ã¥»¡¼¥¸¤Ç¤¢¤ë¤³¤È¤ò»ØÄꤷ¤Æ¤¤¤Þ¤·¤¿¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    ErrorLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¥¨¥é¡¼¤ò¥í¥°¼ý½¸¤¹¤ë¾ì½ê
    ¹½Ê¸: ErrorLog file-path|syslog[:facility]
    ¥Ç¥Õ¥©¥ë¥È:ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2)
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ErrorLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¡¼¥Ð¤ËÀ¸¤¸¤¿¤µ¤Þ¤¶¤Þ¤Ê¥¨¥é¡¼¤ò + µ­Ï¿¤¹¤ë°Ù¤Î¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤷ¤Þ¤¹¡£ + file-path ¤¬ÀäÂХѥ¹¤Ç¤Ê¤¤¤È¤­¤Ï¡¢ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + ErrorLog /var/log/httpd/error_log +

    + +

    file-path ¤¬¥Ñ¥¤¥× (|) ¤«¤é»Ï¤Þ¤ë¾ì¹ç¤Ï¡¢ + ¥¨¥é¡¼¥í¥°¤ò½èÍý¤¹¤ë¤¿¤á¤Ë¼Â¹Ô¤µ¤ì¤ë¥³¥Þ¥ó¥É¤¬ + »ØÄꤵ¤ì¤Æ¤¤¤ë¤È²ò¼á¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + ErrorLog "|/usr/local/bin/httpd_errors" +

    + +

    ¥Õ¥¡¥¤¥ë̾¤ÎÊѤï¤ê¤Ë syslog ¤È»ØÄꤹ¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ¥·¥¹¥Æ¥à¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ì¤Ð syslogd(8) ¤òÍøÍѤ·¤¿¥í¥®¥ó¥°¤¬Í­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢local7 ¥Õ¥¡¥·¥ê¥Æ¥£¤È¤Ê¤ê¤Þ¤¹¤¬¡¢ + syslog:facility ¤È¤¤¤Ã¤¿·Á¤Çµ­½Ò¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ + Ä̾ï syslog(1) ¤Î¥É¥­¥å¥á¥ó¥È¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¥Õ¥¡¥·¥ê¥Æ¥£¤Î°ì¤Ä¤ò»È¤¦¤è¤¦¤Ë + ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Îã

    + ErrorLog syslog:user +

    + +

    ¥»¥­¥å¥ê¥Æ¥£: + ¥í¥°¥Õ¥¡¥¤¥ë¤ò³ÊǼ¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤¬¡¢¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿¥æ¡¼¥¶°Ê³°¤Î + ¥æ¡¼¥¶¤Ë¤è¤Ã¤Æ½ñ¤­¹þ¤á¤ë¾ì¹ç¤Ë¥»¥­¥å¥ê¥Æ¥£¤¬Çˤé¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë¤³¤È¤Ë + ´Ø¤¹¤ë¾ÜºÙ¤Ï ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë¥³¥Ä ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +

    Ãí

    +

    Unix °Ê³°¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÆþÎϤ¹¤ë¤È¤­¤Ï¡¢ + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤¬¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Î»ÈÍѤòµö¤·¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢ + ³Î¼Â¤Ë¥¹¥é¥Ã¥·¥å¤Î¤ß¤¬»ÈÍѤµ¤ì¤ë¤è¤¦¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£°ìÈÌŪ¤Ë¤Ï¡¢ + ÀßÄê¥Õ¥¡¥¤¥ëÁ´È̤ǥ¹¥é¥Ã¥·¥å¤Î¤ß¤ò»È¤¦Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    FileETag ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ETag HTTP ±þÅú¥Ø¥Ã¥À¤òºîÀ®¤¹¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤ë +¥Õ¥¡¥¤¥ë¤Î°À­
    ¹½Ê¸:FileETag component ...
    ¥Ç¥Õ¥©¥ë¥È:FileETag INode MTime Size
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    + FileETag ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥É¥­¥å¥á¥ó¥È¤¬¥Õ¥¡¥¤¥ë¤Ë´ð¤Å¤¤¤¿¤â¤Î¤Ç¤¢¤ë¤È¤­¤Ë¡¢ + ETag (¥¨¥ó¥Æ¥£¥Æ¥£¥¿¥°) ±þÅú¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤òºîÀ®¤¹¤ë¤È¤­¤Ë»ÈÍѤ¹¤ë + ¥Õ¥¡¥¤¥ë¤Î°À­¤òÀßÄꤷ¤Þ¤¹¡£ (ETag ¤ÎÃͤϥͥåȥ¥¯¤ÎÂÓ°è¤òÀáÌ󤹤뤿¤á¤Î + ¥­¥ã¥Ã¥·¥å¤Î´ÉÍý¤Ç»È¤ï¤ì¤Þ¤¹¡£) Apache 1.3.22 °ÊÁ°¤Ç¤Ï¡¢ETag ¤ÎÃÍ¤Ï + ¾ï¤Ë¥Õ¥¡¥¤¥ë¤Î inode, ¥µ¥¤¥º¡¢ºÇ½ª½¤Àµ»þ¹ï (mtime) ¤«¤éºîÀ® + ¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¡£FileETag ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢¤³¤ì¤é¤Î¤É¤ì¤ò»È¤¦¤«¤ò + Áª¤Ö¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Ç§¼±¤µ¤ì¤ë¥­¡¼¥ï¡¼¥É¤Ï: +

    + +
    +
    INode
    +
    ¥Õ¥¡¥¤¥ë¤Î inode ÈÖ¹æ¤ò·×»»¤Ë»È¤¤¤Þ¤¹
    +
    MTime
    +
    ¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤ò»È¤¤¤Þ¤¹
    +
    Size
    +
    ¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤Î¥Ð¥¤¥È¿ô¤ò»È¤¤¤Þ¤¹
    +
    All
    +
    »ÈÍѲÄǽ¤Ê¤¹¤Ù¤Æ¤Î¥Õ¥£¡¼¥ë¥É¤ò»È¤¤¤Þ¤¹¡£ + ¤³¤ì¤Ï

    FileETag INode MTime Size

    ¤ÈÅù²Á¤Ç¤¹¡£
    +
    None
    +
    ¥É¥­¥å¥á¥ó¥È¤¬¥Õ¥¡¥¤¥ë¤Ë´ð¤Å¤¤¤¿¤â¤Î¤Ç¤â¡¢ETag ¥Õ¥£¡¼¥ë¥É¤ò + ±þÅú¤ËÉղä·¤Þ¤»¤ó
    +
    + +

    INode, MTime, Size ¥­¡¼¥ï¡¼¥É¤Ë¤Ï + + ¤ä - ¤òÁ°¤ËÉÕ¤±¤Æ + »ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤³¤Î¾ì¹ç¤Ï¡¢¤è¤ê¹­¤¤ÈϰϤ«¤é·Ñ¾µ¤µ¤ì¤¿ + ¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤ËÊѹ¹¤ò²Ã¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤Î¤è¤¦¤ÊÀÜƬ¼­¤Î + ̵¤¤¥­¡¼¥ï¡¼¥É¤ò»ØÄꤹ¤ë¤È¡¢Â¨ºÂ¤Ë·Ñ¾µ¤·¤¿ÀßÄê¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    ¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄê¤Ë + FileETag INode MTime Size ¤¬¤¢¤ê¡¢ + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄê¤Ë FileETag -INode ¤¬¤¢¤ë¤È¤­¤Ï¡¢ + ¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄê¤Ï (ÀßÄ꤬¾å½ñ¤­¤µ¤ì¤Ê¤±¤ì¤Ð¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤â·Ñ¾µ¤µ¤ì¤Þ¤¹) FileETag MTime Size + ¤ÈƱ¤¸¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    <Files> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë̾¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    ¹½Ê¸:<Files filename> ... </Files>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <Files> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¤½¤ÎÃæ¤Ë¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈϰϤò¥Õ¥¡¥¤¥ë̾¤ÇÀ©¸Â¤·¤Þ¤¹¡£ + <Directory> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Ʊ¤¸¤è¤¦¤Êµ¡Ç½¤ò»ý¤Á¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢</Files> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈÂÐ¤Ë + ¤Ê¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤Î¥»¥¯¥·¥ç¥óÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥Ù¡¼¥¹Ì¾ (¥Õ¥¡¥¤¥ë̾¤ÎºÇ¸å¤ÎÉôʬ) + ¤¬»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë̾¤Ë¥Þ¥Ã¥Á¤¹¤ë¤¹¤Ù¤Æ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + <Files> ¥»¥¯¥·¥ç¥ó¤Ï + <Directory> ¥»¥¯¥·¥ç¥ó¤È + .htaccess ¤¬Æɤ߹þ¤Þ¤ì¤¿¸å¡¢ + <Location> ¥»¥¯¥·¥ç¥ó¤è¤ê¤ÏÀè¤Ë + ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤¿½ç¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + <Files> ¤Ï¡¢ + <Directory> ¥»¥¯¥·¥ç¥óÆâ¤Ë + ¥Í¥¹¥È¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¡¢ + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ìÉô¤Ë¤Î¤ß¸ÂÄꤷ¤ÆŬÍѤµ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    filename °ú¿ô¤Ï¡¢¥Õ¥¡¥¤¥ë̾¤«¥ï¥¤¥ë¥É¥«¡¼¥Éʸ»úÎó + ¤Ç¡¢¥ï¥¤¥ë¥É¥«¡¼¥É¤Ç¤Ï ? ¤Ï°ì¤Ä¤Îʸ»ú¡¢* ¤ÏǤ°Õ¤Îʸ»úÎó¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + ~ ¤È¤¤¤¦Ê¸»ú¤òÉղ乤뤳¤È¤Ç³ÈÄ¥Àµµ¬É½¸½¤ò»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð¡¢

    + +

    + <Files ~ "\.(gif|jpe?g|png)$"> +

    + +

    ¤È¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢°ìÈÌŪ¤Ê¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Î²èÁü¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + ¤¿¤À¤·¡¢ + <FilesMatch> ¤ò»È¤¦Êý¤¬ + ¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤Á¤Ê¤ß¤Ë¡¢<Directory> ¤È <Location> ¥»¥¯¥·¥ç¥ó¤È¤Ï°Û¤Ê¤ê¡¢ + <Files> + ¤Ï .htaccess ¥Õ¥¡¥¤¥ëÆâ¤ÇÍøÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥æ¡¼¥¶¤¬¥Õ¥¡¥¤¥ëËè¤Ë¥¢¥¯¥»¥¹¤ÎÀ©¸æ¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë + ¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    <FilesMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Àµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë̾¤ËŬÍѤµ¤ì¤ë +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    ¹½Ê¸:<FilesMatch regex> ... </FilesMatch>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <FilesMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + <Files> + ¥Ç¥£¥ì¥¯¥Æ¥£¥ÖƱÍͤˤ½¤ÎÃæ¤Ë¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈϰϤò¥Õ¥¡¥¤¥ë̾¤ÇÀ©¸Â¤·¤Þ¤¹¡£¤¿¤À¤·¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤ÏÀµµ¬É½¸½¤ò»ØÄꤷ¤Þ¤¹¡£ + Î㤨¤Ð:

    + +

    + <FilesMatch "\.(gif|jpe?g|png)$"> +

    + +

    ¤Ï°ìÈÌŪ¤Ê¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Î²èÁü·Á¼°¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    ForceType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¤¹¤Ù¤Æ¤Î¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¤¬»ØÄê¤Î MIME ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ç +Á÷¤é¤ì¤ë¤è¤¦¤Ë¤¹¤ë
    ¹½Ê¸:ForceType MIME-type|None
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0 ¤Ç core ¤Ë°ÜÆ°
    +

    .htaccess ¤ä <Directory> ¥»¥¯¥·¥ç¥ó¡¢ + <Location> ¥»¥¯¥·¥ç¥ó¡¢ + <Files> ¥»¥¯¥·¥ç¥ó¤Ë + ½ñ¤«¤ì¤¿¾ì¹ç¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤³¤Ë¤¢¤ë¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤¬ + MIME-type + ¤Ç»ØÄꤵ¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤È¤·¤Æ°·¤ï¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ + GIF ¥Õ¥¡¥¤¥ë¤Ð¤«¤ê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬¤¢¤Ã¤Æ¡¢¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò .gif + ¤Ç½ª¤ï¤é¤»¤¿¤¯¤Ï¤Ê¤¤¤È¤­¤Ë¡¢°Ê²¼¤Î¤â¤Î¤ò»ÈÍѤ·¤Þ¤¹:

    + +

    + ForceType image/gif +

    + +

    DefaultType ¤È°ã¤Ã¤Æ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥á¥Ç¥£¥¢¥¿¥¤¥×¤ò·è¤á¤ë¤³¤È¤¬¤Ç¤­¤ë¤«¤â¤·¤ì¤Ê¤¤ + ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤â´Þ¤á¡¢¤¹¤Ù¤Æ¤Î MIME ¥¿¥¤¥×¤Î´ØÏ¢ÉÕ¤±¤ò + ¾å½ñ¤­¤¹¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    None ¤È¤¤¤¦Ãͤò»È¤¦¤³¤È¤Ç ForceType ¤Î + ÀßÄê¤ò̵¸ú¤Ë¤Ç¤­¤Þ¤¹:

    + +

    + # force all files to be image/gif:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # but normal mime-type associations here:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +

    + +
    +
    top
    +

    HostnameLookups ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤Î IP ¥¢¥É¥ì¥¹¤Î DNS ¥ë¥Ã¥¯¥¢¥Ã¥×¤ò +Í­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:HostnameLookups On|Off|Double
    ¥Ç¥Õ¥©¥ë¥È:HostnameLookups Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥Û¥¹¥È̾¤ò¥í¥°¼ý½¸¤Ç¤­¤ë¤è¤¦¤Ë + DNS ¥ë¥Ã¥¯¥¢¥Ã¥×¤òÍ­¸ú¤Ë¤·¤Þ¤¹ + (¤µ¤é¤Ë¡¢CGI/SSI ¤Ë REMOTE_HOST ÊÑ¿ô¤È¤·¤ÆÅϤ·¤Þ¤¹)¡£ + Double¤ò»ØÄꤷ¤¿¾ì¹ç¡¢2 ½Å¤ÎµÕ°ú¤­¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢µÕ°ú¤­¤Î¸å¤Ë¡¢¤½¤Î·ë²Ì¤ËÂФ·¤ÆÀµ°ú¤­¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£Àµ°ú¤­¤Î + ·ë²Ì¤Î IP ¥¢¥É¥ì¥¹¤ÎÃæ¤Ë¥ª¥ê¥¸¥Ê¥ë¤Î¥¢¥É¥ì¥¹¤È°ìÃפ¹¤ë¤â¤Î¤¬¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£("tcpwrappers" ¤ÎÍѸì¤Ç¤Ï PARANOID ¤È¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¡£)

    + +

    mod_authz_host ¤Ç¥Û¥¹¥È̾¤Ë¤è¤ë¥¢¥¯¥»¥¹ + À©¸æ¤ò¹Ô¤Ê¤¦¾ì¹ç¤Ë¤Ï¡¢ + ÀßÄê¤ÎÇ¡²¿¤Ë¤è¤é¤º 2 ½Å¤ÎµÕ°ú¤­¤¬¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥»¥­¥å¥ê¥Æ¥£¤òÊݤĤ¿¤á¤ËɬÍפǤ¹¡£ + HostnameLookups Double ¤òÀßÄꤷ¤Ê¤¤¸Â¤ê¡¢ + ¾¤ÎÉôʬ¤Ï¤³¤Î 2 ½ÅµÕ°ú¤­¤Î·ë²Ì¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢HostnameLookups On ¤ÈÀßÄꤷ¤Æ¤¢¤ë¾õÂ֤ǡ¢ + ¥Û¥¹¥È̾¤Ë¤è¤ë¥¢¥¯¥»¥¹À©¸Â¤ò¹Ô¤Ê¤Ã¤¿¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¤¿¤È¤¹¤ë¤È¡¢2 ½Å¤ÎµÕ°ú¤­¤¬À®¸ù¤¹¤ë¤«Èݤ«¤Ë¤è¤é¤º¡¢ + REMOTE_HOST ¤Ë¤ÏÄ̾ï¤ÎµÕ°ú¤­·ë²Ì¤¬ÅϤµ¤ì¤Þ¤¹¡£

    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥Ç¥Õ¥©¥ë¥È¤Ï + ËÜÅö¤ËµÕ°ú¤­¤òɬÍפȤ·¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¥µ¥¤¥È¤Î + ¥Í¥Ã¥È¥ï¡¼¥¯¥È¥é¥Õ¥£¥Ã¥¯¤òÄ㸺¤µ¤»¤ë¤¿¤á¤Ë¡¢Off ¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¥ë¥Ã¥¯¥¢¥Ã¥×¤Ë¤è¤ë;·×¤ÊÃٱ䤬¤Ê¤¯¤Ê¤ë¤¿¤á¡¢ + ¥¨¥ó¥É¥æ¡¼¥¶¤Ë¤È¤Ã¤Æ¤âÎɤ¤¤Ç¤·¤ç¤¦¡£ + DNS ¤Î¥ë¥Ã¥¯¥¢¥Ã¥×¤Ë¤Ï¡¢¤«¤Ê¤ê¤Î»þ´Ö¤¬É¬ÍפȤʤë¾ì¹ç¤¬Â¿¤¯¡¢ + Éé²Ù¤Î¹â¤¤¥µ¥¤¥È¤Ç¤Ï¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Off ¤Ë¤¹¤Ù¤­¤Ç¤¹¡£ + ¤Ê¤ª¡¢/support ¥Ç¥£¥ì¥¯¥È¥ê¤Ë´Þ¤Þ¤ì¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï + ¥¤¥ó¥¹¥È¡¼¥ë¥Ç¥£¥ì¥¯¥È¥ê¤Î bin ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤ë logresolve ¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ë¤è¤ê¡¢ + Apache ¤ÎÆ°ºî¤È¤ÏÊ̤ˡ¢¥í¥°¤Ë»Ä¤µ¤ì¤Æ¤¤¤ë IP ¥¢¥É¥ì¥¹¤«¤é¥Û¥¹¥È̾¤ò + ¥ë¥Ã¥¯¥¢¥Ã¥×¤¹¤ë¤³¤È¤¬²Äǽ¤Ç¤¹¡£

    + +
    +
    top
    +

    <IfDefine> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:µ¯Æ°»þ¤Ë¥Æ¥¹¥È¤¬¿¿¤Ç¤¢¤ë¤È¤­¤Î¤ß¤Ë½èÍý¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +°Ï¤à
    ¹½Ê¸:<IfDefine [!]parameter-name> ... + </IfDefine>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <IfDefine test>...</IfDefine> + ¥»¥¯¥·¥ç¥ó¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¾ò·ïÉÕ¤­¤Ç»ØÄꤹ¤ë¤¿¤á¤ËÍøÍѤ·¤Þ¤¹¡£ + <IfDefine> ¥»¥¯¥·¥ç¥ó¤Ë + ´Þ¤Þ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢test¤¬ + ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤È¤­¤Î¤ß½èÍý¤µ¤ì¤Þ¤¹¡£ + ¤â¤· test ¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢ + ³«»Ï¤È½ªÎ»¤Î»ØÄê¤Î´Ö¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +

    <IfDefine> ¥»¥¯¥·¥ç¥ó¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë + »ØÄꤹ¤ë test ¤Ï¡¢ + ¼¡¤ÎÆó¤Ä¤Î·Á¼°¤Î¤¦¤Á¤Î°ì¤Ä¤ò¤È¤ê¤Þ¤¹:

    + +
      +
    • parameter-name
    • + +
    • !parameter-name
    • +
    + +

    Á°¼Ô¤Î¾ì¹ç¤Ë¤Ï¡¢parameter-name ¤È̾ÉÕ¤±¤é¤ì¤¿¥Ñ¥é¥á¡¼¥¿¤¬ + ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð³«»Ï¤È½ªÎ»¤Î´Ö¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬½èÍý¤µ¤ì¤Þ¤¹¡£ + ¸å¼Ô¤Î¾ì¹ç¤ÏµÕ¤Ç¡¢parameter-name ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤ + ¾ì¹ç¤Ë½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    parameter-name °ú¿ô¤Ï¡¢¥µ¡¼¥Ð¤òµ¯Æ°¤¹¤ëºÝ¤Ë + httpd ¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ë + -Dparameter- ¤È¤¤¤¦·Á¤Ç»ØÄꤹ¤ë¤ÈÄêµÁ¤µ¤ì¤Þ¤¹¡£

    + +

    <IfDefine> ¥»¥¯¥·¥ç¥ó¤Ï + Æþ¤ì»Ò¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¡¢Ê£¿ô¤Î¥Ñ¥é¥á¡¼¥¿¤Ë¤è¤ë¥Æ¥¹¥È¤ò¤¹¤ë¤¿¤á¤Ë»ÈÍѤǤ­¤Þ¤¹¡£ + Îã:

    + +

    + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +

    + +
    +
    top
    +

    <IfModule> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥â¥¸¥å¡¼¥ë¤Î¸ºß¤¹¤ë¤«¤·¤Ê¤¤¤«¤Ë±þ¤¸¤Æ½èÍý¤µ¤ì¤ë +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    ¹½Ê¸:<IfModule [!]module-file|module-identifier> ... + </IfModule>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:¥â¥¸¥å¡¼¥ë¼±Ê̻ҤϥС¼¥¸¥ç¥ó 2.1 °Ê¹ß¤Ç»ÈÍѲÄǽ¡£
    +

    <IfModule test>...</IfModule> + ¥»¥¯¥·¥ç¥ó¤Ï¡¢¥â¥¸¥å¡¼¥ë¤¬Â¸ºß¤¹¤ë¤È¤­¤Ë½èÍý¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »ØÄꤹ¤ë¤¿¤á¤ËÍøÍѤ·¤Þ¤¹¡£ + <IfModule> ¥»¥¯¥·¥ç¥ó¤Ë + ´Þ¤Þ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢test + ¤Ç»ØÄꤹ¤ë¥â¥¸¥å¡¼¥ë¤¬ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤È¤­¤Î¤ß½èÍý¤µ¤ì¤Þ¤¹¡£ + ¤â¤· test ¤¬ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢³«»Ï¤È½ªÎ»¤Î´Ö¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +

    <IfModule> ¥»¥¯¥·¥ç¥ó¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë + »ØÄꤹ¤ë test ¤Ï¡¢ + ¼¡¤ÎÆó¤Ä¤Î·Á¼°¤Î¤¦¤Á¤Î°ì¤Ä¤ò¤È¤ê¤Þ¤¹¡£

    + +
      +
    • module
    • + +
    • !module
    • +
    + +

    Á°¼Ô¤Î¾ì¹ç¤Ï¡¢module ¤È̾ÉÕ¤±¤é¤ì¤¿¥â¥¸¥å¡¼¥ë¤¬ + Apache ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ì¤Ð + (¥³¥ó¥Ñ¥¤¥ëºÑ¤ß¤Î¤â¤Î¤È¡¢LoadModule ¤òÍøÍѤ·¤Æ + ưŪ¤ËÆɤ߹þ¤ó¤À¤â¤Î¤ÎξÊý)¡¢ + ³«»Ï¤È½ªÎ»¤Î´Ö¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬½èÍý¤µ¤ì¤Þ¤¹¡£ + ¸å¼Ô¤Î¾ì¹ç¤ÏµÕ¤Ç¡¢module ¤¬ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤¤ + ¾ì¹ç¤Ë½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    module °ú¿ô¤Ï¡¢¥â¥¸¥å¡¼¥ë¼±Ê̻Ҥ« + ¥³¥ó¥Ñ¥¤¥ë¤ò¤·¤¿»þ¤Î¥â¥¸¥å¡¼¥ë¤Î¥Õ¥¡¥¤¥ë̾¤Ç¤¹¡£ + Î㤨¤Ð¡¢rewrite_module ¤Ï¼±ÊÌ»Ò¤Ç + mod_rewrite.c ¤Ï¥Õ¥¡¥¤¥ë̾¤Ç¤¹¡£ + ¥â¥¸¥å¡¼¥ë¤¬Ê£¿ô¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤«¤é¹½À®¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢Ê¸»úÎó + STANDARD20_MODULE_STUFF ¤¬¤¢¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò + »È¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    + +

    <IfModule> ¥»¥¯¥·¥ç¥ó¤Ï + Æþ¤ì»Ò¤Ë¤¹¤ë¤³¤È¤¬²Äǽ¤Ç¤¢¤ê¡¢ + Ê£¿ô¤Î¥â¥¸¥å¡¼¥ë¤Î¥Æ¥¹¥È¤ò¹Ô¤Ê¤¦¤¿¤á¤Ë»ÈÍѤǤ­¤Þ¤¹¡£

    + +
    ÆÃÄê¤Î¥â¥¸¥å¡¼¥ë¤Î¸ºß¤Ë´Ø¤ï¤é¤ºÆ°ºî¤¹¤ë + ÀßÄê¥Õ¥¡¥¤¥ë¤Î¸¶Ëܤ¬É¬ÍפʤȤ­¤Ë¤Î¤ß¤³¤Î¥»¥¯¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£ + Ä̾ï¤ÎÆ°ºî¤Ç¤Ï¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + <IfModule> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ë + Æþ¤ì¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
    + +
    +
    top
    +

    Include ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ëÃ椫¤é¾¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ò¼è¤ê¹þ¤à
    ¹½Ê¸:Include file-path|directory-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:¥ï¥¤¥ë¥É¥«¡¼¥É¤Ë¤è¤ë¥Þ¥Ã¥Á¤Ï 2.0.41 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤«¤é + ¾¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¤ò¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È½ç¤Ë°ìÅÙ¤ËÆɤ߹þ¤à¤¿¤á¤Ë¡¢ + ¥·¥§¥ë·Á¼° (fnmatch) ¤Î¥ï¥¤¥ë¥É¥«¡¼¥Éʸ»ú¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤µ¤é¤Ë¡¢Include ¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤¿¾ì¹ç¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥êÆâ¤ÎÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò + ¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È½ç¤ËÆɤ߹þ¤ó¤Ç¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤È¤·¤Æ½èÍý¤·¤Þ¤¹¡£ + ¤·¤«¤·¡¢¥Ç¥£¥ì¥¯¥È¥êÁ´ÂΤòÆɤ߹þ¤à¤Î¤Ï¤ª´«¤á¤Ç¤­¤Þ¤»¤ó¡£ + ¤Õ¤È¤·¤¿¤³¤È¤«¤é httpd ¤¬Æɤ߹þ¤ß¤Ë¼ºÇÔ¤¹¤ë¤è¤¦¤Ê + °ì»þ¥Õ¥¡¥¤¥ë¤ò¥Ç¥£¥ì¥¯¥È¥ê¤Ë»Ä¤·¤Æ¤·¤Þ¤¦¤è¤¦¤Ê¤³¤È¤¬¤è¤¯¤¢¤ë¤«¤é¤Ç¤¹¡£

    + +

    »ØÄꤹ¤ë¥Õ¥¡¥¤¥ë¥Ñ¥¹¤ÏÀäÂХѥ¹¤«¡¢ + ServerRoot ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î + ÁêÂХѥ¹¤«¡¢¤Î¤É¤Á¤é¤«¤Ç¤¹¡£

    + +

    Îã:

    + +

    + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +

    + +

    ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤Î¾ì¹ç¤Ï:

    + +

    + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +

    + +

    apachectl configtest ¤ò¼Â¹Ô¤¹¤ë¤È¡¢ÀßÄê¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¤¤ë»þ¤Ë + Æɤ߹þ¤Þ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î¥ê¥¹¥È¤¬É½¼¨¤µ¤ì¤Þ¤¹:

    + +

    + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +

    + +

    »²¾È

    + +
    +
    top
    +

    KeepAlive ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:HTTP ¤Î»ý³Ū¤ÊÀܳ¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:KeepAlive On|Off
    ¥Ç¥Õ¥©¥ë¥È:KeepAlive On
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    HTTP/1.0 ¤Î Keep-Alive ³ÈÄ¥¤È HTTP/1.1 ¤Î»ý³ŪÀܳ¤Îµ¡Ç½¤Ï¡¢ + Ê£¿ô¤Î¥ê¥¯¥¨¥¹¥È¤¬Æ±¤¸ TCP ¤ÎÀܳ¤ÇÁ÷¤é¤ì¤ë¡¢Ä¹»þ´Ö»ý³¤¹¤ë + HTTP ¥»¥Ã¥·¥ç¥ó¤òÄ󶡤·¤Þ¤¹¡£¤¿¤¯¤µ¤ó¤Î²èÁü¤¬ + ´Þ¤Þ¤ì¤ë HTML ¥É¥­¥å¥á¥ó¥È¤Ç¤Ï¾ì¹ç¤Ë¤è¤Ã¤Æ¤ÏÃÙ±ä»þ´Ö¤¬ 50% û½Ì¤µ¤ì¤ë·ë²Ì¤â + ¤Ç¤Æ¤¤¤Þ¤¹¡£Keep-Alive Àܳ¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï + KeepAlive On ¤ÈÀßÄꤷ¤Þ¤¹¡£

    + +

    HTTP/1.0 ¤ËÂбþ¤·¤¿¥¯¥é¥¤¥¢¥ó¥È¤ÎºÝ¤Ë¤Ï¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤è¤êÆäËÍ׵᤬¤¢¤Ã¤¿¾ì¹ç¤Î¤ß Keep-Alive Àܳ¤È¤Ê¤ê¤Þ¤¹¡£ + ¤µ¤é¤Ë¡¢HTTP/1.0 ¥¯¥é¥¤¥¢¥ó¥È¤Ç¤Ï¡¢¥³¥ó¥Æ¥ó¥Ä¤ÎÍÆÎ̤¬Àè¤Ë + (ÌõÃí: Í×µá¤ËÂФ·¤Æ±þÅú¤òÊÖ¤¹Á°¤Ë) ¤ï¤«¤ë¾ì¹ç¤Î¤ß Keep-Alive + Àܳ¤òÍøÍѤǤ­¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢CGI ¤Î½ÐÎϤä SSI ¤Î¥Ú¡¼¥¸¡¢ + ¥µ¡¼¥Ð¤¬À¸À®¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È¤Î¤è¤¦¤ÊưŪ¥³¥ó¥Æ¥ó¥Ä¤ò + HTTP/1.0 ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¾ì¹ç¤Ë¤Ï Keep-Alive Àܳ¤ò»È¤¨¤Ê¤¤¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + HTTP/1.1 ¤ËÂбþ¤·¤¿¥¯¥é¥¤¥¢¥ó¥È¤ÎºÝ¤Ë¤Ï¡¢ + Æä˻ØÄꤵ¤ì¤Ê¤¤¸Â¤ê¤Ï¥Ç¥Õ¥©¥ë¥È¤È¤·¤Æ»ý³Ū¤ÊÀܳ¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤¬Í׵᤹¤ì¤Ð¡¢¥³¥ó¥Æ¥ó¥Ä¤ÎÍÆÎ̤òȽÊ̤Ǥ­¤Ê¤¤¤â¤Î¤ò + »ý³Ū¤ÊÀܳ¤òÄ̤·¤ÆÁ÷¤ë¤¿¤á¤Ë¡¢¥Á¥ã¥ó¥¯¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤¬ÍѤ¤¤é¤ì¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    KeepAliveTimeout ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»ý³Ū¤ÊÀܳ¤Ç¼¡¤Î¥ê¥¯¥¨¥¹¥È¤¬Íè¤ë¤Þ¤Ç¥µ¡¼¥Ð¤¬ÂԤĻþ´Ö
    ¹½Ê¸:KeepAliveTimeout seconds
    ¥Ç¥Õ¥©¥ë¥È:KeepAliveTimeout 5
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    Àܳ¤òÊĤ¸¤ëÁ°¤Ë¡¢Apache ¤¬¼¡¤Î¥ê¥¯¥¨¥¹¥È¤ò²¿ÉÃÂԤĤ«¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿¸å¤Ï¡¢Timeout ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ + »ØÄꤵ¤ì¤¿¥¿¥¤¥à¥¢¥¦¥ÈÃͤ¬»È¤ï¤ì¤Þ¤¹¡£

    + +

    KeepAliveTimeout ¤òÂ礭¤ÊÃͤËÀßÄꤹ¤ë¤È¡¢ + Éé²Ù¤Î¹â¤¤¥µ¡¼¥Ð¤Ë¤ª¤¤¤Æ¤Ï¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤ÎÌäÂê¤ò°ú¤­µ¯¤³¤¹¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£ + ¥¿¥¤¥à¥¢¥¦¥È¤¬Ä¹¤±¤ì¤ÐŤ¤¤Û¤É¡¢¤è¤ê¿¤¯¤Î¥µ¡¼¥Ð¥×¥í¥»¥¹¤¬ + ³èȯ¤Ç¤Ê¤¤¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤ÎÀܳ¤Î½ªÎ»¤òÂÔ¤Á³¤±¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    <Limit> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:°Ï¤¤¤ÎÃæ¤Ë¤¢¤ë¥¢¥¯¥»¥¹À©¸æ¤ÎŬÍѤòÆÃÄê¤Î HTTP ¥á¥½¥Ã¥É¤Î¤ß¤Ë +À©¸Â¤¹¤ë
    ¹½Ê¸:<Limit method [method] ... > ... + </Limit>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¥¢¥¯¥»¥¹À©¸æ¤Ï¡¢Ä̾ïÁ´¤Æ¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤ËÂФ·¤Æ + ±Æ¶Á¤·¡¢ÉáÄ̤Ϥ³¤ì¤¬Ë¾¤Þ¤·¤¤µóÆ°¤Ç¤¹¡£ + ¤½¤¦¤·¤¿¤³¤È¤«¤é¡¢ÂçÉôʬ¤Î¾ì¹ç¤Ë¤Ï¥¢¥¯¥»¥¹À©¸æ¤Ë´Ø¤ï¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + <Limit> ¥»¥¯¥·¥ç¥óÆâ¤Ë + ½ñ¤¯¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    <Limit> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÌÜŪ¤Ï¡¢¥¢¥¯¥»¥¹À©¸æ¤ÎÈϰϤò + »ØÄꤵ¤ì¤¿ HTTP ¥á¥½¥Ã¥É¤Ë¸ÂÄꤹ¤ë¤¿¤á¤Ç¤¹¡£ + ¤½¤ì°Ê³°¤Î¥á¥½¥Ã¥É¤Ï¡¢<Limit> ¤Ç°Ï¤ï¤ì¤¿¥¢¥¯¥»¥¹À©¸æ¤Î + ±Æ¶Á¤ò¼õ¤±¤Þ¤»¤ó¡£ + °Ê²¼¤ÎÎã¤Ï¡¢POST, PUT, DELETE ¤Î¥á¥½¥Ã¥É¤ËÂФ·¤Æ¤Î¤ß¥¢¥¯¥»¥¹¤ÎÀ©¸æ¤ò¹Ô¤Ê¤¤¡¢ + ¤½¤ì°Ê³°¤Î¥á¥½¥Ã¥É¤Ë¤Ä¤¤¤Æ¤ÏÀ©¸Â¤·¤Þ¤»¤ó:

    + +

    + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +

    + +

    ¥á¥½¥Ã¥É̾¤Ë¤Ï°Ê²¼¤ÎÃ椫¤é°ì¤Ä°Ê¾å¤òÎóµó¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹: + GET, + POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK, UNLOCK. ¥á¥½¥Ã¥É̾¤Ï + Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤¹¡£ GET ¤ò»ØÄꤷ¤¿¾ì¹ç¤Ë¤Ï + HEAD ¥ê¥¯¥¨¥¹¥È¤Ë¤âÀ©¸Â¤¬¤«¤«¤ê¤Þ¤¹¡£TRACE + ¥á¥½¥Ã¥É¤ËÀ©¸Â¤ò¤«¤±¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£

    + +
    ¥¢¥¯¥»¥¹À©¸æ¤¬ÌÜŪ¤Î¾ì¹ç¤Ï + <Limit> + ¥»¥¯¥·¥ç¥ó¤ÎÂå¤ï¤ê¤Ë <LimitExcept> ¥»¥¯¥·¥ç¥ó¤ò»ÈÍѤ·¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ + <LimitExcept> + ¥»¥¯¥·¥ç¥ó¤Ç¤ÏÉÔÆÃÄê¤Î¥á¥½¥Ã¥É¤ËÂФ·¤Æ¤âËɸæ¤Ç¤­¤ë¤«¤é¤Ç¤¹¡£
    + + +
    +
    top
    +

    <LimitExcept> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»ØÄꤵ¤ì¤¿¤â¤Î°Ê³°¤Î HTTP ¥á¥½¥Ã¥É¤Ë¥¢¥¯¥»¥¹À©¸æ¤ò +À©¸Â¤¹¤ë
    ¹½Ê¸:<LimitExcept method [method] ... > ... + </LimitExcept>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <LimitExcept> ¤È + </LimitExcept> ¤Ï¡¢°ú¿ô¤Ë + ´Þ¤Þ¤ì¤Æ¤¤¤Ê¤¤ + HTTP ¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤ËŬÍѤ¹¤ë¤¿¤á¤Î¥¢¥¯¥»¥¹À©¸æ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò³ç¤ë¤¿¤á¤ËÍøÍѤ·¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢<Limit> ¥»¥¯¥·¥ç¥ó¤ÎÈ¿ÂФÎÆ°ºî¤ò¤·¡¢ + ɸ½à¤Î¥á¥½¥Ã¥É¤Èɸ½à³°¤ä̤ǧ¼±¤Î¥á¥½¥Ã¥É¤Î¾ì¹ç¤ÎξÊý¤òÀßÄê¤Ç¤­¤Þ¤¹¡£ + <Limit> ¤Î¥É¥­¥å¥á¥ó¥È¤â + Ê»¤»¤Æ»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Îã:

    + +

    + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +

    + + +
    +
    top
    +

    LimitInternalRecursion ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤ÈÆþ¤ì»Ò¤Ë¤Ê¤Ã¤¿¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤ÎºÇÂç¿ô¤ò·èÄꤹ¤ë
    ¹½Ê¸:LimitInternalRecursion number [number]
    ¥Ç¥Õ¥©¥ë¥È:LimitInternalRecursion 10
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0.47 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤ÏÎ㤨¤Ð Action ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤Ã¤Æ¤¤¤ë¤È¤­¤Ëµ¯¤³¤ê¤Þ¤¹¡£Action ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¸µ¡¹¤Î¥ê¥¯¥¨¥¹¥È¤ò CGI ¥¹¥¯¥ê¥×¥È¤ËÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤Ï¤¤¤¯¤Ä¤«¤Î URI ¤ËÂФ·¤Æ¡¢¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¤È¤­¤Ë + ²¿¤¬µ¯¤³¤ë¤«¤òÄ´¤Ù¤ë¤¿¤á¤Î Apache ¤Îµ¡¹½¤Ç¤¹¡£Î㤨¤Ð¡¢mod_dir + ¤Ï DirectoryIndex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤¬¥ê¥¹¥È¤¹¤ë¥Õ¥¡¥¤¥ë¤òÄ´¤Ù¤ë¤¿¤á¤Ë¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤ò»È¤¤¤Þ¤¹¡£

    + +

    LimitInternalRecursion ¤ÏÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤ä + ¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤¬Ìµ¸Â¥ë¡¼¥×¤Ë´Ù¤Ã¤¿¤È¤­¤Î¥µ¡¼¥Ð¥¯¥é¥Ã¥·¥å¤òËɤ®¤Þ¤¹¡£ + ÉáÄÌ¡¢¤½¤Î¤è¤¦¤Ê¥ë¡¼¥×¤ÏÀßÄê¤Ë¼ºÇÔ¤·¤¿¤È¤­¤ËȯÀ¸¤·¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥ê¥¯¥¨¥¹¥ÈËè¤Ëɾ²Á¤µ¤ì¤ë¡¢Æó¤Ä¤Î°ã¤¦¸Â³¦Ãͤò + ÀßÄꤷ¤Þ¤¹¡£ºÇ½é¤Î number ¤Ï¡¢µ¯¤³¤êÆÀ¤ë + ÆâÉô¥ê¥¯¥¨¥¹¥È¤ÎºÇÂçÃͤòÀßÄꤷ¤Þ¤¹¡£Æó¤Ä¤á¤Î number ¤Ï + ¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤¬Æþ¤ì»Ò¤Ë¤Ç¤­¤ë¿¼¤µ¤òÀßÄꤷ¤Þ¤¹¡£number ¤ò + °ì¤Ä¤À¤±»ØÄꤷ¤¿¤È¤­¤Ï¡¢Î¾Êý¤Î¸Â³¦Ãͤˤ½¤ÎÃͤ¬ÀßÄꤵ¤ì¤Þ¤¹¡£

    + +

    Îã

    + LimitInternalRecursion 5 +

    + +
    +
    top
    +

    LimitRequestBody ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤«¤éÁ÷¤é¤ì¤ë HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤Î +ÁíÎ̤òÀ©¸Â¤¹¤ë
    ¹½Ê¸:LimitRequestBody bytes
    ¥Ç¥Õ¥©¥ë¥È:LimitRequestBody 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥ê¥¯¥¨¥¹¥È¥Ü¥Ç¥£¤Ëµö¤µ¤ì¤ë¥Ð¥¤¥È¿ô¡¢bytes + ¤ò 0 (̵À©¸Â¤ò°ÕÌ£¤·¤Þ¤¹) ¤«¤é 2147483647 (2GB) ¤Þ¤Ç¤Î¿ôÃͤǻØÄꤷ¤Þ¤¹¡£

    + +

    LimitRequestBody ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬½ñ¤«¤ì¤¿¥³¥ó¥Æ¥­¥¹¥È + (¥µ¡¼¥ÐÁ´ÂΡ¢¥Ç¥£¥ì¥¯¥È¥ê¡¢¥Õ¥¡¥¤¥ë¡¢¥í¥±¡¼¥·¥ç¥ó) Æâ¤Ç + µöÍƤ¹¤ë HTTP ¥ê¥¯¥¨¥¹¥È¥á¥Ã¥»¡¼¥¸¥Ü¥Ç¥£¤Î¥µ¥¤¥º¤ËÀ©¸Â¤ò¤«¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤¬¤½¤ÎÀ©¸ÂÃͤò±Û¤¨¤Æ¤¤¤ì¤Ð¡¢ + ¥µ¡¼¥Ð¤Ï¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤»¤º¤Ë¥¨¥é¡¼¤òÊÖ¤·¤Þ¤¹¡£ + ÉáÄ̤Υꥯ¥¨¥¹¥È¥á¥Ã¥»¡¼¥¸¥Ü¥Ç¥£¤Î¥µ¥¤¥º¤Ï¡¢¥ê¥½¡¼¥¹¤Î¼ïÎà¤ä + µö²Ä¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É¤Ë¤è¤Ã¤ÆÂ礭¤¯ÊѤï¤ê¤Þ¤¹¡£ + CGI ¥¹¥¯¥ê¥×¥È¤Ï¡¢¤è¤¯¾ðÊó¤ò¼õ¿®¤¹¤ë¤¿¤á¤Ë + ¥á¥Ã¥»¡¼¥¸¥Ü¥Ç¥£¤ò»È¤¤¤Þ¤¹¡£ + PUT ¥á¥½¥Ã¥É¤Î¼ÂÁõ¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤȤ·¤Æ + ¾¯¤Ê¤¯¤È¤â¤¢¤ë¥ê¥½¡¼¥¹¤ËÂФ·¤Æ¥µ¡¼¥Ð¤¬¼õ¤±ÉÕ¤±¤è¤¦¤È¤¹¤ë + ɽ¸½¤ÎÂ礭¤µ¤Û¤É¤ÎÃͤòɬÍפȤ·¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ´ÉÍý¼Ô¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î°Û¾ï¤Ê¥ê¥¯¥¨¥¹¥È¤òÀ©¸æ¤Ç¤­¤ë¤è¤¦¤Ë¤·¡¢ + ²¿¤é¤«¤Î·Á¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â (ÌõÃí:DoS) ¤òÈò¤±¤ë¤Î¤ËÍ­¸ú¤Ç¤¹¡£

    + +

    ¤¢¤ë¾ì½ê¤Ø¤Î¥Õ¥¡¥¤¥ë¥¢¥Ã¥×¥í¡¼¥É¤òµö²Ä¤¹¤ë¾ì¹ç¤Ë¡¢ + ¥¢¥Ã¥×¥í¡¼¥É¤Ç¤­¤ë¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤ò 100K ¤ËÀ©¸Â¤·¤¿¤±¤ì¤Ð¡¢ + °Ê²¼¤Î¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹:

    + +

    + LimitRequestBody 102400 +

    + + +
    +
    top
    +

    LimitRequestFields ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Î¿ô¤ò +À©¸Â¤¹¤ë
    ¹½Ê¸:LimitRequestFields number
    ¥Ç¥Õ¥©¥ë¥È:LimitRequestFields 100
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    number ¤Ë¤Ï¡¢0 (̵À©¸Â¤ò°ÕÌ£¤·¤Þ¤¹) ¤«¤é 32767 + ¤Þ¤Ç¤ÎÀ°¿ô¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢Äê¿ô DEFAULT_LIMIT_REQUEST_FIELDS + ¤Ë¤è¤ê¥³¥ó¥Ñ¥¤¥ë»þ¤ËÄêµÁ¤µ¤ì¤Þ¤¹ (ÇÛÉÛ»þ¤Ë¤Ï 100 ¤È»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹)¡£

    + +

    LimitRequestBody ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¡¼¥Ð´ÉÍý¼Ô¤¬ HTTP ¥ê¥¯¥¨¥¹¥ÈÃæ¤Ë¤ª¤¤¤Æµö²Ä¤¹¤ë¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¿ô¤ò + »ØÄꤷ¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¤³¤ÎÃͤˤÏÄ̾ï¤Î¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤Ë´Þ¤Þ¤ì¤ë¤Ç¤¢¤í¤¦ + ¥Õ¥£¡¼¥ë¥É¤Î¿ô¤è¤êÂ礭¤ÊÃͤ¬É¬ÍפȤ·¤Þ¤¹¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤Ë¤è¤ê»È¤ï¤ì¤¿Í×µá¥Ø¥Ã¥À¡¼¥Õ¥£¡¼¥ë¥É¤Î¿ô¤¬ + 20 ¤òĶ¤¨¤ë¤³¤È¤Ï¤Û¤È¤ó¤É¤¢¤ê¤Þ¤»¤ó¤¬¡¢ + ¤³¤ì¤Ï¼ï¡¹¤Î¥¯¥é¥¤¥¢¥ó¥È¤Î¼ÂÁõ¤è¤Ã¤ÆÊѤï¤ê¡¢ + ¾ÜºÙ¤Ê¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò¤¹¤ë¤¿¤á¤Î¥Ö¥é¥¦¥¶¤ÎÀßÄê¤Þ¤Ç¤Ë¤â + ±Æ¶Á¤µ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¥ª¥×¥·¥ç¥ó¤Î HTTP ³ÈÄ¥¤Ï¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ò»È¤Ã¤Æ¸½¤µ¤ì¤ë¾ì¹ç¤¬ + ¿¤¯¤¢¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ´ÉÍý¼Ô¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î°Û¾ï¤Ê¥ê¥¯¥¨¥¹¥È¤òÀ©¸æ¤Ç¤­¤ë¤è¤¦¤Ë¤·¡¢ + ²¿¤é¤«¤Î·Á¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â (ÌõÃí:DoS) ¤òÈò¤±¤ë¤Î¤ËÍ­¸ú¤Ç¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤Î¥Õ¥£¡¼¥ë¥É¤¬Â¿²á¤®¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¥¨¥é¡¼±þÅú¤¬ + ÉáÄ̤Υ¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¤ë¤è¤¦¤Ê»þ¤Ï¤³¤ÎÃͤòÁý¤ä¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Îã:

    + +

    + LimitRequestFields 50 +

    + + +
    +
    top
    +

    LimitRequestFieldSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤Î +¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    ¹½Ê¸:LimitRequestFieldsize bytes
    ¥Ç¥Õ¥©¥ë¥È:LimitRequestFieldsize 8190
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À°ì¤Ä¤Ç¼õÉÕ¤±¤ë + ¥Ð¥¤¥È¿ô bytes ¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    LimitRequestFieldSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ÇµöÍƤµ¤ì¤ë¥µ¥¤¥º¤òÁý¸º¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤȤ·¤Æ¡¢ + °ìÈÌŪ¤Ê¥¯¥é¥¤¥¢¥ó¥È¤«¤é¥ê¥¯¥¨¥¹¥È¤¬Á÷¤é¤ì¤¿ºÝ¤Ë¡¢¤½¤Î¥ê¥¯¥¨¥¹¥È¤Ë + ÉÕ°¤·¤Æ¤¤¤ë¤É¤Î¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Ë¤Ä¤¤¤Æ¤â¡¢ + ½½Ê¬Â­¤ê¤ëÂ礭¤µ¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + °ìÈÌŪ¤Ê¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Î¥µ¥¤¥º¤È¤¤¤Ã¤Æ¤â¡¢¤½¤ÎÂ礭¤µ¤Ï¸Ä¡¹¤Î + ¥¯¥é¥¤¥¢¥ó¥È¤Î¼ÂÁõ¤Ë¤è¤Ã¤ÆÂ礭¤¯°Û¤Ê¤ê¡¢ + ¾ÜºÙ¤Ê¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤«¤É¤¦¤«¤Î¡¢ + ¥Ö¥é¥¦¥¶¤ÎÀßÄê¤Ë¤â±Æ¶Á¤µ¤ì¤¿¤ê¤·¤Þ¤¹¡£ + SPNEGO ǧ¾Ú¥Ø¥Ã¥À¤Ç¤Ï 12392 ¥Ð¥¤¥È¤Ë¤Þ¤ÇµÚ¤Ö¤³¤È¤¹¤é¤¢¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ´ÉÍý¼Ô¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î°Û¾ï¤Ê¥ê¥¯¥¨¥¹¥È¤òÀ©¸æ¤Ç¤­¤ë¤è¤¦¤Ë¤·¡¢ + ²¿¤é¤«¤Î·Á¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â (ÌõÃí:DoS) ¤òÈò¤±¤ë¤Î¤ËÍ­¸ú¤Ç¤¹¡£

    + +

    Îã:

    + +

    + LimitRequestFieldSize 4094 +

    + +
    Ä̾ï¤Ï¥Ç¥Õ¥©¥ë¥È¤«¤éÊѹ¹¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
    + + +
    +
    top
    +

    LimitRequestLine ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¹Ô¤Î¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    ¹½Ê¸:LimitRequestLine bytes
    ¥Ç¥Õ¥©¥ë¥È:LimitRequestLine 8190
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢HTTP ¥ê¥¯¥¨¥¹¥È¹ÔÆâ¤ÇµöÍƤµ¤ì¤ë¥Ð¥¤¥È¿ô + bytes ¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    LimitRequestLine ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¹Ô¤ÎµöÍÆ¥µ¥¤¥º¤òÁý¸º¤Ç¤­¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¹Ô¤Ï¡¢HTTP¥á¥½¥Ã¥É¡¢URI¡¢¥×¥í¥È¥³¥ë¥Ð¡¼¥¸¥ç¥ó¤«¤éÀ®¤Ã¤Æ¤ª¤ê¡¢ + LimitRequestLine ¤Ï¥µ¡¼¥Ð¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + µöÍƤ¹¤ë¥ê¥¯¥¨¥¹¥È URI ¤ÎŤµ¤òÀ©¸Â¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¡¢GET ¥ê¥¯¥¨¥¹¥È¤Î¥¯¥¨¥êÉôʬ¤â´Þ¤á¤Æ¡¢¥ê¥½¡¼¥¹¤Î̾Á°¤¬Æþ¤ë¤Ë­¤ë + Â礭¤µ¤òɬÍפȤ·¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ´ÉÍý¼Ô¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î°Û¾ï¤Ê¥ê¥¯¥¨¥¹¥È¤òÀ©¸æ¤Ç¤­¤ë¤è¤¦¤Ë¤·¡¢ + ²¿¤é¤«¤Î·Á¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â (ÌõÃí:DoS) ¤òÈò¤±¤ë¤Î¤ËÍ­¸ú¤Ç¤¹¡£

    + +

    Îã:

    + +

    + LimitRequestLine 4094 +

    + +
    Ä̾ï¤Ï¥Ç¥Õ¥©¥ë¥È¤«¤éÊѹ¹¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
    + +
    +
    top
    +

    LimitXMLRequestBody ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:XML ·Á¼°¤Î¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤Î¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    ¹½Ê¸:LimitXMLRequestBody bytes
    ¥Ç¥Õ¥©¥ë¥È:LimitXMLRequestBody 1000000
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    XML ·Á¼°¤Î¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤ÎºÇÂçÃͤò (¥Ð¥¤¥Èñ°Ì¤Ç) À©¸Â¤·¤Þ¤¹¡£ + ÃÍ¤Ë 0 ¤ò»ØÄꤹ¤ë¤È¥Á¥§¥Ã¥¯¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    Îã:

    + +

    + LimitXMLRequestBody 0 +

    + + +
    +
    top
    +

    <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:°Ï¤ó¤À¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Þ¥Ã¥Á¤¹¤ë URL ¤Î¤ß¤ËŬÍÑ
    ¹½Ê¸:<Location + URL-path|URL> ... </Location>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + URL ¤Ë¤è¤êÃæ¤Ë½ñ¤«¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈϰϤòÀ©¸Â¤·¤Þ¤¹¡£ + <Directory> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È»÷¤Æ¤¤¤Æ¡¢ + </Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç½ªÎ»¤¹¤ë + ¥µ¥Ö¥»¥¯¥·¥ç¥ó¤ò³«»Ï¤·¤Þ¤¹¡£ + <Location> ¥»¥¯¥·¥ç¥ó¤Ï¡¢ + <Directory> ¥»¥¯¥·¥ç¥ó¤È + .htaccess ¤ÎÆɤ߹þ¤ß¤Î¸å¡¢ + <Files> ¥»¥¯¥·¥ç¥ó¤ò + ŬÍѤ·¤¿¸å¤Ë¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤¿½ç¤Ë½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    <Location> ¥»¥¯¥·¥ç¥ó¤Ï + ´°Á´¤Ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤È´ØÏ¢¤»¤º¤ËÆ°ºî¤·¤Þ¤¹¡£¤³¤Î¤³¤È¤«¤éƳ¤«¤ì¤ë + ·ë²Ì¤Ë¤Ï¤¤¤Ä¤¯¤«Ãí°Õ¤¹¤ëÅÀ¤¬¤¢¤ê¤Þ¤¹¡£ºÇ¤â½ÅÍפʤâ¤Î¤Ï¡¢ + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤ؤΥ¢¥¯¥»¥¹À©¸æ¤Ë <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤Ù¤­¤Ç¤Ï¤Ê¤¤ + ¤È¤¤¤¦¤³¤È¤Ç¤¹¡£Ê£¿ô¤Î URL ¤¬¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎƱ¤¸°ÌÃ֤˥ޥåפµ¤ì¤ë + ²Äǽ¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢¤½¤Î¤è¤¦¤Ê¥¢¥¯¥»¥¹À©¸æ¤Ï²óÈò¤µ¤ì¤Æ¤·¤Þ¤¦²ÄǽÀ­¤¬ + ¤¢¤ê¤Þ¤¹¡£

    + +

    ¤¤¤Ä <Location> ¤ò»È¤¦¤«

    + +

    <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à³°¤Î¥³¥ó¥Æ¥ó¥Ä¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬÍѤ¹¤ë¤È¤­¤Ë + »ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë¸ºß¤¹¤ë¥³¥ó¥Æ¥ó¥Ä¤ËÂФ·¤Æ¤Ï¡¢ + <Directory> ¤È <Files> ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£ + Îã³°¤Ï¡¢<Location /> ¤Ç¡¢¤³¤ì¤Ï¥µ¡¼¥ÐÁ´ÂΤËÂФ·¤Æ + ÀßÄê¤òŬÍѤ¹¤ë´Êñ¤ÊÊýË¡¤Ç¤¹¡£

    +
    + +

    Á´¤Æ¤Î (¥×¥í¥­¥·°Ê³°¤Î) ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¡¢ + URL ¤Ï /path/ ¤È¤¤¤¦¡¢ + ÀÜƬ¼­ http://servername ¤ò´Þ¤Þ¤Ê¤¤·Á¤Ç¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Î¾ì¹ç¤Ë¤Ï¡¢scheme://servername/path + ¤È¤¤¤¦ÀÜƬ¼­¤ò´Þ¤à·Á¤Ç¥Þ¥Ã¥Á¤·¡¢ÀÜƬ¼­¤ò´Þ¤á¤Æ»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    URL ¤Ë¤Ï¥ï¥¤¥ë¥É¥«¡¼¥É¤òÍøÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ? ¤ÏǤ°Õ¤Î°ìʸ»ú¡¢* ¤ÏǤ°Õ¤Îʸ»úÎó¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + +

    ~ ¤È¤¤¤¦Ê¸»ú¤òÄɲ乤뤳¤È¤Ç¡¢³ÈÄ¥Àµµ¬É½¸½¤ò + ÍøÍѤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð:

    + +

    + <Location ~ "/(extra|special)/data"> +

    + +

    ¤Ï URL ¤Ë /extra/data ¤« /special/data ¤È¤¤¤¦Ê¸»úÎó¤¬ + ´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + <LocationMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + <Location> ¤ÎÀµµ¬É½¸½ + ÈǤȤޤ俤¯Æ±¤¸Æ°ºî¤ò¤·¤Þ¤¹¡£

    + +

    <Location> µ¡Ç½¤Ï¡¢SetHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Áȹç¤ï¤»¤ÆÍøÍѤ¹¤ë¤ÈÆäËÊØÍø¤Ç¤¹¡£ + Î㤨¤Ð¡¢foo.com ¤Î¥Ö¥é¥¦¥¶¤«¤é¤Î¤ß¥¹¥Æ¡¼¥¿¥¹¤Î»²¾È¤òÍ­¸ú¤Ë¤·¤¿¤±¤ì¤Ð¡¢ + ¼¡¤Î¤è¤¦¤Ë¤¹¤ì¤ÐÎɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +

    + +

    / (¥¹¥é¥Ã¥·¥å) ¤Ë´Ø¤¹¤ëÃí

    +

    ¥¹¥é¥Ã¥·¥åʸ»ú¤Ï¡¢URL Æâ¤Ë¸½¤ì¤ë¾ì½ê¤Ë±þ¤¸¤ÆÊѲ½¤¹¤ë + ÆÃÊ̤ʰÕÌ£¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë¤ª¤¤¤ÆÍøÍѤ¹¤ë¾ì¹ç¤Ë¤ÏÊ£¿ô¤Î¥¹¥é¥Ã¥·¥å¤Ç¤â°ì¤Ä¤Î + ¥¹¥é¥Ã¥·¥å¤È¤·¤Æ°·¤ï¤ì¤ë¤³¤È¤¬Â¿¤¤¤Ç¤¹¤¬¡¢ + (¤¹¤Ê¤ï¤Á¡¢/home///foo ¤Ï + /home/foo ¤ÈƱ¤¸¤¤¤Ã¤¿¤è¤¦¤Ë) + URL ¤Ë¤ª¤¤¤Æ¤Ïɬ¤º¤·¤â¤½¤¦¤Ê¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + <LocationMatch> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤äÀµµ¬É½¸½¤òÍøÍѤ·¤¿ + <Location> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ + Ê£¿ô¤Î¥¹¥é¥Ã¥·¥å¤Ë¥Þ¥Ã¥Á¤µ¤»¤¿¤¤¤È¤­¤Ë¤Ï¡¢¡¢ÌÀ¼¨Åª¤Ëµ­½Ò¤¹¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢<LocationMatch ^/abc> ¤Ï¡¢ + /abc ¤È¤¤¤¦¥ê¥¯¥¨¥¹¥È URL ¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¤¬¡¢ + //abc ¤È¤¤¤¦¥ê¥¯¥¨¥¹¥È URL ¤Ë¤Ï¥Þ¥Ã¥Á¤·¤Þ¤»¤ó¡£ + (Àµµ¬É½¸½¤Ç¤Ê¤¤) <Location> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + proxy ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤ÆÍøÍѤ¹¤ëºÝ¤Ë¤ÏƱÍͤﶤëÉñ¤¤¤ò¤·¤Þ¤¹¤¬¡¢ + (Àµµ¬É½¸½¤Ç¤Ê¤¤) <Location> ¤ò proxy + ¤Ç¤Ê¤¤¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤ÆÍøÍѤ¹¤ëºÝ¤Ë¤Ï¡¢ + °ì¤Ä¤Î¥¹¥é¥Ã¥·¥å¤ÇÊ£¿ô¤Î¥¹¥é¥Ã¥·¥å¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ + Î㤨¤Ð¡¢<Location /abc/def> ¤È»ØÄꤷ¡¢ + /abc//def ¤È¤¤¤¦¥ê¥¯¥¨¥¹¥È¤¬¤¢¤ì¤Ð¡¢ + ¥Þ¥Ã¥Á¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    <LocationMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:°Ï¤ó¤À¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÀµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë URL ¤Î¤ß¤Ë +ŬÍÑ
    ¹½Ê¸:<LocationMatch + regex> ... </LocationMatch>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <LocationMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + <Location> ¤ÈƱ¤¸ÍÍ¤Ë + URL ¤Ë¤è¤êÃæ¤Ë½ñ¤«¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍÑÈϰϤòÀ©¸Â¤·¤Þ¤¹¡£ + ⤷¡¢°ú¿ô¤ÏÉáÄ̤Îʸ»úÎó¤Ç¤Ï¤Ê¤¯¡¢Àµµ¬É½¸½¤È¤Ê¤ê¤Þ¤¹¡£Î㤨¤Ð¡¢

    + +

    + <LocationMatch "/(extra|special)/data"> +

    + +

    ¤Ï URL ¤Ë /extra/data ¤« /special/data + ¤È¤¤¤¦Ê¸»úÎ󤬴ޤޤì¤Æ¤¤¤ë¾ì¹ç¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    LogLevel ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ErrorLog ¤Î¾éĹÀ­¤òÀ©¸æ¤¹¤ë
    ¹½Ê¸:LogLevel level
    ¥Ç¥Õ¥©¥ë¥È:LogLevel warn
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    LogLevel ¤Ï¡¢¥¨¥é¡¼¥í¥° (ErrorLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ¸«¤Æ¤¯¤À¤µ¤¤) ¤Øµ­Ï¿¤¹¤ë¥á¥Ã¥»¡¼¥¸¤Î¾éĹÀ­¤òÄ´À°¤·¤Þ¤¹¡£ + °Ê²¼¤Î level ¤ò»ØÄê¤Ç¤­¡¢½ç¤Ë½ÅÍ×ÅÙ¤¬²¼¤¬¤Ã¤Æ¤¤¤­¤Þ¤¹¡£

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥ì¥Ù¥ë ÀâÌÀ Îã
    emerg ¶ÛµÞ - ¥·¥¹¥Æ¥à¤¬ÍøÍѤǤ­¤Ê¤¤Child cannot open lock file. Exiting + (»Ò¥×¥í¥»¥¹¤¬¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤ò³«¤±¤Ê¤¤¤¿¤á½ªÎ»¤·¤¿)
    alert ľ¤Á¤ËÂн褬ɬÍ×getpwuid: couldn't determine user name from uid + (getpwuid: UID ¤«¤é¥æ¡¼¥¶Ì¾¤òÆÃÄê¤Ç¤­¤Ê¤«¤Ã¤¿)
    crit Ã×̿Ū¤Ê¾õÂÖsocket: Failed to get a socket, exiting child + (socket: ¥½¥±¥Ã¥È¤¬ÆÀ¤é¤ì¤Ê¤¤¤¿¤á¡¢»Ò¥×¥í¥»¥¹¤ò½ªÎ»¤µ¤»¤¿)
    error ¥¨¥é¡¼Premature end of script headers + (¥¹¥¯¥ê¥×¥È¤Î¥Ø¥Ã¥À¤¬Â­¤ê¤Ê¤¤¤Þ¤Þ¤Ç½ª¤ï¤Ã¤¿)
    warn ·Ù¹ðchild process 1234 did not exit, sending another SIGHUP + (»Ò¥×¥í¥»¥¹ 1234 ¤¬½ªÎ»¤·¤Ê¤«¤Ã¤¿¡£¤â¤¦°ìÅÙ SIGHUP ¤òÁ÷¤ë)
    notice ÉáÄ̤À¤¬¡¢½ÅÍפʾðÊóhttpd: caught SIGBUS, attempting to dump core in ... + (httpd: SIGBUS ¥·¥°¥Ê¥ë¤ò¼õ¤±¡¢... ¤Ø¥³¥¢¥À¥ó¥×¤ò¤·¤¿)
    info ÄɲþðÊó"Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..." (¡Ö¥µ¡¼¥Ð¤ÏÉé²Ù¤¬¹â¤¤¡¢ + (StartServers ¤ä Min/MaxSpareServers ¤ÎÃͤòÁý¤ä¤¹É¬Íפ¬¤¢¤ë¤«¤â)¡×)
    debug ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸"Opening config file ..." (ÀßÄê¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¤¤ë...)
    + +

    ÆÃÄê¤Î¥ì¥Ù¥ë¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¡¢¤½¤ì¤è¤ê¹â¤¤¥ì¥Ù¥ë¤ÎÁ´¤Æ¤Î¥á¥Ã¥»¡¼¥¸¤¬ + Êó¹ð¤µ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢LogLevel info ¤Ë»ØÄꤹ¤ë¤È¡¢ + notice ¤È warn ¤âÊó¹ð¤µ¤ì¤Þ¤¹¡£

    + +

    ¤Ê¤ª crit °Ê¾å¤Î¥ì¥Ù¥ë¤ò»ØÄꤹ¤ë¤³¤È¤¬¿ä¾©¤µ¤ì¤Þ¤¹¡£

    + +

    Îã:

    + +

    + LogLevel notice +

    + +

    Ãí

    +

    ¥Õ¥¡¥¤¥ë¤Ë¥í¥°¤ò½ÐÎϤ¹¤ë¾ì¹ç¡¢notice + ¥ì¥Ù¥ë¤Î¥á¥Ã¥»¡¼¥¸¤ÏÍÞÀ©¤µ¤ì¤º¡¢¤¹¤Ù¤Æ¥í¥°¤Ë½ÐÎϤµ¤ì¤Þ¤¹¡£ + ¤·¤«¤· syslog ¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¤³¤ì¤ÏÅö¤Æ¤Ï¤Þ¤ê¤Þ¤»¤ó¡£

    +
    + +
    +
    top
    +

    MaxKeepAliveRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»ý³Ū¤ÊÀܳ¾å¤Çµö²Ä¤µ¤ì¤ë¥ê¥¯¥¨¥¹¥È¤Î¿ô
    ¹½Ê¸:MaxKeepAliveRequests number
    ¥Ç¥Õ¥©¥ë¥È:MaxKeepAliveRequests 100
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    MaxKeepAliveRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + KeepAlive ¤¬Í­¸ú¤Ê¾ì¹ç¤Ë¡¢ + °ì²ó¤ÎÀܳ¤Ç¼õ¤±ÉÕ¤±²Äǽ¤Ê¥ê¥¯¥¨¥¹¥È¤Î¿ô¤òÀ©¸Â¤·¤Þ¤¹¡£ + 0 ¤ËÀßÄꤷ¤Æ¤¤¤ì¤Ð¡¢¼õ¤±ÉÕ¤±¤ë¥ê¥¯¥¨¥¹¥È¤Ï̵À©¸Â¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ÎÀßÄê¤Ï¡¢¥µ¡¼¥ÐÀ­Ç½¤ò¸þ¾å¤µ¤»¤ë¤¿¤á¤Ë¡¢Â礭¤Ê¿ôÃͤò»ØÄꤹ¤ë¤³¤È´«¤á¤Þ¤¹¡£ +

    + +

    Îã:

    + +

    + MaxKeepAliveRequests 500 +

    + +
    +
    top
    +

    NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¤¿¤á¤Î IP ¥¢¥É¥ì¥¹¤ò»ØÄê
    ¹½Ê¸:NameVirtualHost addr[:port]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤ò¹Ô¤Ê¤¤¤¿¤¤¾ì¹ç¤Ë + ɬÍפȤʤë¤â¤Î¤Ç¤¹¡£

    + +

    addr ¤Ë¤Ï¥Û¥¹¥È̾¤ò»ØÄê¤Ç¤­¤Þ¤¹¤¬¡¢ + ¾ï¤Ë IP ¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ë¤Î¤¬¿ä¾©¤µ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢

    + +

    + NameVirtualHost 111.22.33.44 +

    + +

    NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + ÍøÍѤ·¤Æ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤ë IP ¥¢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢ÉáÄ̤Ï̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥¢¥É¥ì¥¹¤Ç¤¹¡£ + ¤¿¤À¤·¡¢¥Õ¥¡¥¤¥¢¡¼¥¦¥©¡¼¥ë¤ä¾¤Î¥×¥í¥­¥·¤¬¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¡¢ + °ã¤¦ IP ¥¢¥É¥ì¥¹¤Î¥µ¡¼¥Ð¤Ë¥Õ¥©¥ï¡¼¥É¤¹¤ë¤È¤¤¤¦¾ì¹ç¤Ï¡¢ + ¥ê¥¯¥¨¥¹¥È¤òÄ󶡤·¤¿¤¤¥Þ¥·¥ó¾å¤ÎʪÍý¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î + IP ¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + Ê£¿ô¤Î¥¢¥É¥ì¥¹¤ÇÊ£¿ô¤Î̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»ØÄꤹ¤ë¾ì¹ç¤Ï + ³Æ¥¢¥É¥ì¥¹¤ËÂФ·¤Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¤¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãæ

    +

    ¡Ö¼ç¥µ¡¼¥Ð¡×¤ä¡¢¤É¤Î _default_ ¥µ¡¼¥Ð¤â¡¢ + NameVirtualHost ¤Ç»ØÄꤷ¤¿ IP ¥¢¥É¥ì¥¹¤Ø¤Î¥ê¥¯¥¨¥¹¥È + ¤ò½èÍý¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó (¤Ê¤¼¤« + NameVirtualHost ¤ò + »ØÄꤷ¤¿¤±¤É¤½¤Î¥¢¥É¥ì¥¹¤Ë VirtualHost ¤òÄêµÁ¤·¤Ê¤«¤Ã¤¿¾ì¹ç¤ò½ü¤¯)¡£

    +
    + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥Ý¡¼¥ÈÈÖ¹æ¤ò»ØÄꤹ¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£ + Î㤨¤Ð

    + +

    + NameVirtualHost 111.22.33.44:8080 +

    + +

    IPV6 ¤Î¥¢¥É¥ì¥¹¤Ï¼¡¤ÎÎã¤Î¤è¤¦¤Ë³Ñ³ç¸Ì¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹:

    + +

    + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 +

    + +

    ¤¹¤Ù¤Æ¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + °ú¿ô¤È¤·¤Æ * ¤ò»È¤¤¤Þ¤¹¡£

    + +

    + NameVirtualHost * +

    + +

    <VirtualHost> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô

    +

    <VirtualHost> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤Ï NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤ËÀµ³Î¤Ë + ¹ç¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +

    +
    + + +

    »²¾È

    + +
    +
    top
    +

    Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ»ÈÍѲÄǽ¤Êµ¡Ç½¤òÀßÄꤹ¤ë
    ¹½Ê¸:Options + [+|-]option [[+|-]option] ...
    ¥Ç¥Õ¥©¥ë¥È:Options All
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Options
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ + ¤É¤Îµ¡Ç½¤¬»ÈÍѲÄǽ¤«¤òÀ©¸æ¤·¤Þ¤¹¡£

    + +

    option ¤ò None¤Ë»ØÄꤹ¤ë¤È¡¢ + ÆÃÊ̤ʵ¡Ç½¤ÏÁ´¤Æ̵¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤Þ¤¿¡¢°Ê²¼¤Î¼¨¤¹ 1 ¸Ä°Ê¾å¤Î¤â¤Î¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£

    + +
    +
    All
    + +
    MultiViews ¤ò½ü¤¤¤¿Á´¤Æ¤Îµ¡Ç½¤¬Í­¸ú¤È¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤¬¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£
    + +
    ExecCGI
    + +
    + mod_cgi ¤Ë¤è¤ë CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤òµö²Ä¤·¤Þ¤¹¡£
    + +
    FollowSymLinks
    + +
    + ¥µ¡¼¥Ð¤¬¡¢¤³¤Î¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ç¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò¤¿¤É¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ +

    ¥µ¡¼¥Ð¤¬¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò¤¿¤É¤ë¾ì¹ç¤Ç¤â¡¢ + <Directory> ¥»¥¯¥·¥ç¥ó¤Ë + ¥Þ¥Ã¥Á¤µ¤»¤ë¤¿¤á¤Î + ¥Ñ¥¹Ì¾¤ÏÊѹ¹¤µ¤ì¤Þ¤»¤ó¡£

    +

    <Location> Æâ¤Ë + ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Æ¤â̵»ë¤µ¤ì¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    Includes
    + +
    + mod_include ¤¬Ä󶡤¹¤ë SSI ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
    + +
    IncludesNOEXEC
    + +
    + SSI ¤ÏÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¤¬¡¢#exec ¥³¥Þ¥ó¥É ¤È #exec CGI ¤Ï̵¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¿¤À¤·¡¢#include virtual ¤Ë¤è¤ê¡¢ScriptAlias ¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ç + CGI ¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ï²Äǽ¤Ç¤¹¡£
    + +
    Indexes
    + +
    + ¤â¤·¡¢URL ¤¬¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Þ¥Ã¥×¤¹¤ë¥ê¥¯¥¨¥¹¥È¤Ç¤¢¤Ã¤Æ¡¢ + ³î¤Ä DirectoryIndex ¤Ç»ØÄꤷ¤¿¥Õ¥¡¥¤¥ë (Î㤨¤Ð¡¢index.html) ¤¬ + ¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë̵¤±¤ì¤Ð¡¢mod_autoindex ¤¬ + ¥Ç¥£¥ì¥¯¥È¥êÆâ¤Î°ìÍ÷¤òÀ°·Á¤·¤ÆÊÖ¤·¤Þ¤¹¡£
    + +
    MultiViews
    + +
    + mod_negotiation ¤Ë¤è¤ë + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + ¤µ¤ì¤¿ "MultiViews" ¤òµö²Ä¤·¤Þ¤¹¡£
    + +
    SymLinksIfOwnerMatch
    + +
    + ¥·¥ó¥Ü¥ê¥Ã¥¯Àè¤Î¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤¬¡¢ + ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Î½êÍ­¥æ¡¼¥¶ ID ¤ÈƱ¤¸¾ì¹ç¤Ë¤Î¤ß¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò + ¤¿¤É¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + +

    Ãí

    <Location> Æâ¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤ò + »ØÄꤷ¤Æ¤â̵»ë¤µ¤ì¤Þ¤¹¡£
    +
    +
    + +

    Ä̾¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤ÆÊ£¿ô¤Î Options ¤¬ + ŬÍѲÄǽ¤Ê¾ì¹ç¡¢ + ºÇ¤â¶á¤¤¤â¤Î°ì¤Ä¤Î¤ß¤¬Å¬ÍѤµ¤ì¡¢Â¾¤Î¤â¤Î¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£ + Ê£¿ô¤Î»ØÄ꤬¥Þ¡¼¥¸¤µ¤ì¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£(¥»¥¯¥·¥ç¥ó¤Î¥Þ¡¼¥¸ÊýË¡¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£) + ¤·¤«¤·¡¢¤¹¤Ù¤Æ¤Î Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + ¤ä - ÉÕ¤­¤Ç + »ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¥ª¥×¥·¥ç¥ó¤ÎÃͤϥޡ¼¥¸¤µ¤ì¤Þ¤¹¡£ + + ¤òƬ¤Ë¤Ä¤±¤ì¤Ð¸½ºß¤ÎÀßÄê¤Ë²Ã¤¨¤é¤ì¡¢ + - ¤òÉÕ¤±¤ì¤Ð¸½ºß¤ÎÀßÄ꤫¤éºï½ü¤µ¤ì¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢+ ¤ä - ¤òÍøÍѤ·¤Ê¤¤¾ì¹ç¤Ï:

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +

    + +

    /web/docs/spec ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ï¡¢ + Includes ¤À¤±¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£ + ¤·¤«¤·¡¢2 ÈÖÌܤΠOptions ¤Ç + ¤ä - ¤òÍøÍѤ·¤Æ¤ß¤ë¤È:

    + +

    + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +

    + +

    /web/docs/spec ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ï¡¢ FollowSymLinks ¤È + Includes ¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£

    + +

    Ãí

    +

    -IncludesNOEXEC ¤â¤·¤¯¤Ï + -Includes ¤ò»ØÄꤹ¤ë¤È¡¢ + Á°¤ÎÀßÄ꤬¤É¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤è¤¦¤È¤â SSI ¤Ï̵¸ú¤È¤Ê¤ê¤Þ¤¹¡£

    +
    + +

    ¤É¤Î¤è¤¦¤ÊÀßÄê¤â¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï All ¤Ë + ¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    Require ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¤É¤Îǧ¾ÚºÑ¤ß¥æ¡¼¥¶¤¬¥ê¥½¡¼¥¹¤ò¥¢¥¯¥»¥¹¤Ç¤­¤ë¤«¤òÁªÂò¤¹¤ë
    ¹½Ê¸:Require entity-name [entity-name] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¤É¤Îǧ¾ÚºÑ¤ß¤Î¥æ¡¼¥¶¤¬¥ê¥½¡¼¥¹¤Ë + ¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤«¤ò»ØÄꤷ¤Þ¤¹¡£ + °Ê²¼¤Î¤è¤¦¤Ê¹½Ê¸¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    Require user userid [userid] ...
    + +
    »ØÄꤵ¤ì¤¿¥æ¡¼¥¶¤Î¤ß¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤·¤Þ¤¹¡£
    + +
    Require group group-name [group-name] ...
    + +
    »ØÄꤵ¤ì¤¿¥°¥ë¡¼¥×¤Ë°¤¹¤ë¥æ¡¼¥¶¤Î¤ß¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤·¤Þ¤¹¡£
    + +
    Require valid-user
    + +
    Á´¤Æ¤Îǧ¾Ú¤µ¤ì¤¿¥æ¡¼¥¶¤Ë¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤·¤Þ¤¹¡£
    +
    + +

    Require ¤Ï¡¢Àµ¤·¤¯Æ°ºî¤¹¤ë¤¿¤á¤Ë¤Ï AuthName µÚ¤Ó AuthType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä¡¢ + (¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤ò»ØÄꤹ¤ë¤¿¤á¤Ë) AuthUserFile µÚ¤Ó AuthGroupFile + ¤È¤¤¤Ã¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¶¦¤Ë + »ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð:

    + +

    + AuthType Basic
    + AuthName "Restricted Resource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +

    + +

    ¤³¤Î¤è¤¦¤Ë¤·¤ÆŬÍѤµ¤ì¤¿¥¢¥¯¥»¥¹À©¸æ¤Ï¡¢Á´¤Æ¤Î¥á¥½¥Ã¥É¤Ë + ÂФ·¤Æ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + Ä̾ï¤Ï¡¢¤³¤ì¤¬Ë¾¤Þ¤·¤¤Æ°ºî¤Ç¤¹¡£ + ¤â¤·¡¢ÆÃÄê¤Î¥á¥½¥Ã¥É¤ËÂФ·¤Æ¤Î¤ß¥¢¥¯¥»¥¹¤ÎÀ©¸æ¤òŬÍѤ·¡¢ + ¾¤Î¥á¥½¥Ã¥É¤ÏÀ©¸Â¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢<Limit> ¥»¥¯¥·¥ç¥óÆâ¤Ë + Require ¤ò + »ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    RLimitCPU ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤Î CPU ¾ÃÈñÎ̤ò +À©¸Â¤¹¤ë
    ¹½Ê¸:RLimitCPU seconds|max [seconds|max]
    ¥Ç¥Õ¥©¥ë¥È:̤ÀßÄê¡£¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¥Ç¥Õ¥©¥ë¥È¤ò»ÈÍÑ
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    °ì¤Ä¤«Æó¤Ä¤Î¥Ñ¥é¥á¡¼¥¿¤ò¤È¤ê¤Þ¤¹¡£ + ºÇ½é¤Î¥Ñ¥é¥á¡¼¥¿¤ÏÁ´¥×¥í¥»¥¹¤ËÂФ¹¤ë¥ê¥½¡¼¥¹¤Î¥½¥Õ¥È¥ê¥ß¥Ã¥È¤òÀßÄꤷ¡¢ + 2 ÈÖÌܤΥѥé¥á¡¼¥¿¤ÏºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤òÀßÄꤷ¤Þ¤¹¡£ + ¥Ñ¥é¥á¡¼¥¿¤Ë¤Ï¿ô»ú¤«¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ÎºÇÂç¤È¤Ê¤ë + max ¤Î¤É¤Á¤é¤«¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤ò¾å¤²¤ë¤¿¤á¤Ë¤Ï¡¢¥µ¡¼¥Ð¤ò + root ¤Ç¼Â¹Ô¤¹¤ë¤«µ¯Æ°¤µ¤ì¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£

    + +

    ¤Á¤Ê¤ß¤Ë¡¢¤³¤ÎÀßÄê¤Ï Apache ¤Î»Ò¥×¥í¥»¥¹¼«ÂΤǤϤʤ¯¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿ Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥×¥í¥»¥¹¤Ë + ŬÍѤµ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ë¤Ï CGI ¤ä SSI ¤«¤é¼Â¹Ô¤µ¤ì¤¿¥³¥Þ¥ó¥É¤¬´Þ¤Þ¤ì¤Þ¤¹¤¬¡¢Apache ¤Î + ¿Æ¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥í¥°¤Î¥Ñ¥¤¥×¥×¥í¥»¥¹¤Ê¤É¤Ë¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£

    + +

    CPU ¥ê¥½¡¼¥¹¤Î¥ê¥ß¥Ã¥È¤Ï¥×¥í¥»¥¹¤¢¤¿¤ê¤ÎÉÿô¤Çɽ¤ï¤µ¤ì¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    RLimitMEM ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤Î¥á¥â¥ê¾ÃÈñÎ̤ò +À©¸Â¤¹¤ë
    ¹½Ê¸:RLimitMEM bytes|max [bytes|max]
    ¥Ç¥Õ¥©¥ë¥È:̤ÀßÄê¡£¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¥Ç¥Õ¥©¥ë¥È¤ò»ÈÍÑ
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    °ì¤Ä¤«Æó¤Ä¤Î¥Ñ¥é¥á¡¼¥¿¤ò¤ò¤È¤ê¤Þ¤¹¡£ + ºÇ½é¤Î¥Ñ¥é¥á¡¼¥¿¤ÏÁ´¥×¥í¥»¥¹¤ËÂФ¹¤ë¥ê¥½¡¼¥¹¤Î¥½¥Õ¥È¥ê¥ß¥Ã¥È¤òÀßÄꤷ¡¢ + 2 ÈÖÌܤΥѥé¥á¡¼¥¿¤ÏºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤òÀßÄꤷ¤Þ¤¹¡£ + ¥Ñ¥é¥á¡¼¥¿¤Ë¤Ï¿ô»ú¤«¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ÎºÇÂç¤È¤Ê¤ë + max ¤Î¤É¤Á¤é¤«¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤ò¾å¤²¤ë¤¿¤á¤Ë¤Ï¡¢¥µ¡¼¥Ð¤ò + root ¤Ç¼Â¹Ô¤¹¤ë¤«µ¯Æ°¤µ¤ì¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£

    + +

    ¤³¤ÎÀßÄê¤Ï Apache ¤Î»Ò¥×¥í¥»¥¹¼«ÂΤǤϤʤ¯¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿ Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥×¥í¥»¥¹¤Ë + ŬÍѤµ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ë¤Ï CGI ¤ä SSI ¤«¤é¼Â¹Ô¤µ¤ì¤¿¥³¥Þ¥ó¥É¤¬´Þ¤Þ¤ì¤Þ¤¹¤¬¡¢Apache ¤Î + ¿Æ¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥í¥°¤Î¥Ñ¥¤¥×¥×¥í¥»¥¹¤Ê¤É¤Ë¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£

    + +

    ¥á¥â¥ê¥ê¥½¡¼¥¹¤Î¥ê¥ß¥Ã¥È¤Ï¥×¥í¥»¥¹¤¢¤¿¤ê¤Î¥Ð¥¤¥È¿ô¤Çɽ¤ï¤µ¤ì¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    RLimitNPROC ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤¬µ¯Æ°¤¹¤ë¥×¥í¥»¥¹¤Î +¿ô¤òÀ©¸Â¤¹¤ë
    ¹½Ê¸:RLimitNPROC number|max [number|max]
    ¥Ç¥Õ¥©¥ë¥È:̤ÀßÄê¡£¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¥Ç¥Õ¥©¥ë¥È¤ò»ÈÍÑ
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    °ì¤Ä¤«Æó¤Ä¤Î¥Ñ¥é¥á¡¼¥¿¤ò¤È¤ê¤Þ¤¹¡£ + ºÇ½é¤Î¥Ñ¥é¥á¡¼¥¿¤ÏÁ´¥×¥í¥»¥¹¤ËÂФ¹¤ë¥ê¥½¡¼¥¹¤Î¥½¥Õ¥È¥ê¥ß¥Ã¥È¤òÀßÄꤷ¡¢ + 2 ÈÖÌܤΥѥé¥á¡¼¥¿¤ÏºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤òÀßÄꤷ¤Þ¤¹¡£ + ¥Ñ¥é¥á¡¼¥¿¤Ë¤Ï¿ô»ú¤«¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ÎºÇÂç¤È¤Ê¤ë + max ¤Î¤É¤Á¤é¤«¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ºÇÂç¤Î¥ê¥½¡¼¥¹¥ê¥ß¥Ã¥È¤ò¾å¤²¤ë¤¿¤á¤Ë¤Ï¡¢¥µ¡¼¥Ð¤ò + root ¤Ç¼Â¹Ô¤¹¤ë¤«µ¯Æ°¤µ¤ì¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£

    + +

    ¤³¤ÎÀßÄê¤Ï Apache ¤Î»Ò¥×¥í¥»¥¹¼«ÂΤǤϤʤ¯¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿ Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥×¥í¥»¥¹¤Ë + ŬÍѤµ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ë¤Ï CGI ¤ä SSI ¤«¤é¼Â¹Ô¤µ¤ì¤¿¥³¥Þ¥ó¥É¤¬´Þ¤Þ¤ì¤Þ¤¹¤¬¡¢Apache ¤Î + ¿Æ¥×¥í¥»¥¹¤«¤é fork ¤µ¤ì¤¿¥í¥°¤Î¥Ñ¥¤¥×¥×¥í¥»¥¹¤Ê¤É¤Ë¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£

    + +

    ¥×¥í¥»¥¹¤ÎÀ©¸Â¤Ï¡¢¥æ¡¼¥¶¤¢¤¿¤ê¤Î¥×¥í¥»¥¹¿ô¤ÇÀ©¸æ¤µ¤ì¤Þ¤¹¡£

    + +

    Ãí

    +

    CGI ¥×¥í¥»¥¹¤¬¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¥æ¡¼¥¶ ID °Ê³°¤Ç¼Â¹Ô¤µ¤ì¤ë¤Î¤Ç + ̵¤±¤ì¤Ð¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥µ¡¼¥Ð¼«¿È¤¬À¸À®¤Ç¤­¤ë¥×¥í¥»¥¹¤Î¿ô¤òÀ©¸Â¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê¾õ¶·¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢error_log Ãæ¤Î + cannot fork ¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸¤Ë¤è¤ê + ³Îǧ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    Satisfy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:¥Û¥¹¥È¥ì¥Ù¥ë¤Î¥¢¥¯¥»¥¹À©¸æ¤È¥æ¡¼¥¶Ç§¾Ú¤È¤ÎÁê¸ßºîÍѤò»ØÄê
    ¹½Ê¸:Satisfy Any|All
    ¥Ç¥Õ¥©¥ë¥È:Satisfy All
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0.51 °Ê¹ß¤Ç¤Ï <Limit> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È <LimitExcept> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î±Æ¶Á¤ò¼õ¤±¤ë +
    +

    Allow ¤È + Require ¤ÎξÊý¤¬»È¤ï¤ì¤Æ¤¤¤ë¤È¤­¤Î + ¥¢¥¯¥»¥¹¥Ý¥ê¥·¡¼¤òÀßÄꤷ¤Þ¤¹¡£¥Ñ¥é¥á¡¼¥¿¤Ï All ¤« Any + ¤Ç¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¢¤ë¾ì½ê¤Ø¤Î¥¢¥¯¥»¥¹¤¬¥æ¡¼¥¶Ì¾/¥Ñ¥¹¥ï¡¼¥É + ¤È¥¯¥é¥¤¥¢¥ó¥È¤Î¥Û¥¹¥È¤Î¥¢¥É¥ì¥¹¤ÇÀ©¸Â¤µ¤ì¤Æ¤¤¤ë¤È¤­¤Ë¤Î¤ß + ÌòΩ¤Á¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî (All) ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤¬¥¢¥É¥ì¥¹¤Ë¤è¤ë + ¥¢¥¯¥»¥¹À©¸Â¤òËþ¤¿¤·¡¢¤«¤ÄÀµ¤·¤¤¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤òÆþÎϤ¹¤ë¤³¤È¤ò + Í׵ᤷ¤Þ¤¹¡£Any ¤Ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï¥Û¥¹¥È¤ÎÀ©¸Â¤òËþ¤¿¤¹¤«¡¢ + Àµ¤·¤¤¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤò¤¹¤ë¤«¤ò¤¹¤ì¤Ð¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¤¢¤ë¾ì½ê¤ò¥Ñ¥¹¥ï¡¼¥É¤ÇÊݸ¤ë¤±¤ì¤É¡¢ÆÃÄê¤Î¥¢¥É¥ì¥¹¤«¤é¤Î + ¥¯¥é¥¤¥¢¥ó¥È¤Ë¤Ï¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎϤòÍ׵᤻¤º¤Ë¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë¡¢ + ¤È¤¤¤¦¤è¤¦¤Ê¤È¤­¤Ë»ÈÍѤǤ­¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢Æ±¤¸¥Í¥Ã¥È¥ï¡¼¥¯¾å¤Ë¤¤¤ë¿Í¤Ë¤Ï¥¦¥§¥Ö¥µ¥¤¥È¤Î¤¢¤ëÉôʬ¤Ë¤Ä¤¤¤Æ + ̵À©¸Â¤Î¥¢¥¯¥»¥¹¤òµö¤·¤¿¤¤¤±¤ì¤É¡¢³°¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Î¿Í¤Ë¤Ï + ¥Ñ¥¹¥ï¡¼¥É¤òÄ󶡤µ¤»¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¼¡¤Î¤è¤¦¤ÊÀßÄê¤ò¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹:

    + +

    + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +

    + +

    ¥Ð¡¼¥¸¥ç¥ó 2.0.51 ¤«¤é¤Ï + <Limit> ¥»¥¯¥·¥ç¥ó¤È + <LimitExcept> ¥»¥¯¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç + Satisfy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + ŬÍѤµ¤ì¤ë¥á¥½¥Ã¥É¤òÀ©¸Â¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£

    + +

    »²¾È

    + +
    +
    top
    +

    ScriptInterpreterSource ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Î°ÌÃÖ¤òÄ´¤Ù¤ë¤¿¤á¤Î¼êË¡
    ¹½Ê¸:ScriptInterpreterSource Registry|Registry-Strict|Script
    ¥Ç¥Õ¥©¥ë¥È:ScriptInterpreterSource Script
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Win32 ¤Î¤ß¡£ +¥ª¥×¥·¥ç¥ó Registry-Strict ¤Ï Apache 2.0 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Apache ¤Ç CGI ¥¹¥¯¥ê¥×¥È¤ò + ¼Â¹Ô¤¹¤ë¾ì¹ç¤ËÍøÍѤ¹¤ë¥¤¥ó¥¿¡¼¥×¥ê¥¿¤ò¡¢ + ¤É¤Î¤è¤¦¤Ëõ¤·½Ð¤¹¤«¤Ë¤Ä¤¤¤ÆÀ©¸æ¤¹¤ë¤¿¤á¤Ë»ÈÍѤ·¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤Ï Script ¤Ç¤¹¡£¤³¤ì¤Ï¥¹¥¯¥ê¥×¥È¤Î + shebang ¹Ô (ºÇ½é¤Î¹Ô¤Ç #! ¤«¤é»Ï¤Þ¤ë¤â¤Î) + ¤Ë»Ø¤µ¤ì¤Æ¤¤¤ë¥¤¥ó¥¿¡¼¥×¥ê¥¿¤ò»ÈÍѤ·¤Þ¤¹¡£Win32 ¤Ç¤Ï¤½¤Î¹Ô¤Ï + °Ê²¼¤ÎÍͤˤʤê¤Þ¤¹¡£

    + +

    + #!C:/Perl/bin/perl.exe +

    + +

    ¤â¤·¤¯¤Ï¡¢perl ¤¬ PATH ¤Ë¤¢¤ë¾ì¹ç¤Ïñ¤Ë:

    + +

    + #!perl +

    + +

    ScriptInterpreterSource Registry ¤ò»ØÄꤹ¤ë¤È¡¢ + ¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò (Î㤨¤Ð¡¢.pl) ¤ò + ¥­¡¼¤È¤·¤Æ¡¢Windows ¤Î¥ì¥¸¥¹¥È¥ê¥Ä¥ê¡¼ HKEY_CLASSES_ROOT + ¤ò¸¡º÷¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¥ì¥¸¥¹¥È¥ê¤Î¥µ¥Ö¥­¡¼ + Shell\ExecCGI\Command ¤«¡¢¤½¤ì¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ï + Shell\Open\Command ¤¬¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤ò³«¤¯¤¿¤á¤Ë + »È¤ï¤ì¤Þ¤¹¡£¥ì¥¸¥¹¥È¥ê¥­¡¼¤¬¸«¤Ä¤«¤é¤Ê¤¤¤È¤­¤Ï¡¢Apache ¤Ï Script + ¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤¿¤È¤­¤ÎÆ°ºî¤ËÌá¤ê¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    ScriptInterpreterSource Registry ¤ò ScriptAlias ¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ç»È¤¦¤È¤­¤Ï + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£Apache ¤Ï¤½¤Î¥Ç¥£¥ì¥¯¥È¥êÃæ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò + ¼Â¹Ô¤·¤è¤¦¤È¤·¤Þ¤¹¡£Registry ¤È¤¤¤¦ÀßÄê¤ÏÄ̾ï¤Ï¼Â¹Ô¤µ¤ì¤Ê¤¤ + ¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ˾¤Þ¤·¤¯¤Ê¤¤¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤¬È¯À¸¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð¡¢¤Û¤È¤ó¤É¤Î Windows ¥·¥¹¥Æ¥à¤Ç¡¢ + .htm ¥Õ¥¡¥¤¥ë¤Î¥Ç¥Õ¥©¥ë¥È¤Î¡Ö³«¤¯¡×¥³¥Þ¥ó¥É¤Ï + Microsoft Internet Explorer ¤ò¼Â¹Ô¤·¤Þ¤¹¤Î¤Ç¡¢¥¹¥¯¥ê¥×¥È¤Ë»ØÄꤵ¤ì¤¿ + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë .htm ¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¥µ¡¼¥Ð¤Î + ¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Ç¥Ö¥é¥¦¥¶¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤Ï¡¢°ìʬÆ⤯¤é¤¤¤Ç + ¥·¥¹¥Æ¥à¤ò¥¯¥é¥Ã¥·¥å¤µ¤ë¤¿¤á¤ÎÎɤ¤ÊýË¡¤Ç¤¹¡£

    +
    + +

    Apache 2.0 ¤«¤éƳÆþ¤µ¤ì¤¿¥ª¥×¥·¥ç¥ó Registry-Strict ¤Ï + Registry ¤ÈƱ¤¸¤³¤È¤ò¹Ô¤Ê¤¤¤Þ¤¹¤¬¡¢¥µ¥Ö¥­¡¼ + Shell\ExecCGI\Command ¤Î¤ß¤ò»È¤¤¤Þ¤¹¡£ + ExecCGI ¥­¡¼¤ÏÉáÄ̤˻Ȥï¤ì¤ë¥­¡¼¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£Windows + ¥ì¥¸¥¹¥È¥ê¤Ë¼êÆ°¤ÇÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢¥·¥¹¥Æ¥à¤Ç¤Î¶öȯŪ¤Ê¥×¥í¥°¥é¥à¤Î + ¼Â¹Ô¤òËɤ°¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
    +
    top
    +

    ServerAdmin ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ë´Þ¤á¤ëÅŻҥ᡼¥ë¤Î +¥¢¥É¥ì¥¹
    ¹½Ê¸:ServerAdmin email-address|URL
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ServerAdmin ¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤¹¤µ¤Þ¤¶¤Þ¤Ê + ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸Ãæ¤Ëµ­½Ò¤¹¤ë¡¢ + Ìä¹ç¤»¥¢¥É¥ì¥¹¤òÀßÄꤷ¤Þ¤¹¡£Í¿¤¨¤é¤ì¤¿°ú¿ô¤ò httpd ¤¬ + URL ¤Èǧ¼±¤·¤Ê¤¤¾ì¹ç¤Ï¡¢email-address ¤À¤È²ò¼á¤·¤Æ¡¢ + ¥Ï¥¤¥Ñ¡¼¥ê¥ó¥¯¤Î¥¿¡¼¥²¥Ã¥È¤Ë mailto: ¤òÉÕ¤±¤Þ¤¹¡£ + ¼ÂºÝ¤Ë¤Ï¡¢¤³¤³¤Ë¤ÏÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤ò»È¤¦¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¿¤¯¤Î CGI ¥¹¥¯¥ê¥×¥È¤Ï¤½¤¦¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡£ + URL ¤ò»È¤¦¾ì¹ç¤Ï¡¢¤¢¤Ê¤¿¤Î´ÉÍý²¼¤Ë¤¢¤ëÊÌ¥µ¡¼¥Ð¤ò»Ø¤¹¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤¦¤Ç¤Ê¤¤¤È¡¢¥¨¥é¡¼¤¬µ¯¤³¤Ã¤¿¤È¤­¤ËÏ¢Íí¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¯¤Ê¤Ã¤Æ + ¤·¤Þ¤¤¤Þ¤¹¡£ +

    + +

    ¤½¤ÎºÝ¡¢¤³¤ì¤Î¤¿¤á¤ËÀìÍѤΥ¢¥É¥ì¥¹¤òÀßÄꤹ¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ + Î㤨¤Ð¡¢

    + +

    + ServerAdmin www-admin@foo.example.com +

    + +

    ¤È¤¤¤Ã¤¿¤è¤¦¤Ë¤·¤Þ¤¹¡£¥æ¡¼¥¶¤Ï¤¤¤Ä¤â¥µ¡¼¥Ð¤Ë´Ø¤¹¤ëÏäǤ¢¤ë¤È¤¤¤¦¤³¤È¤ò + ÌÀµ­¤·¤Æ¤¯¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤Î¤Ç¡£

    + + +
    +
    top
    +

    ServerAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤ò̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥Þ¥Ã¥Á¤µ¤»¤Æ¤¤¤ë¤È¤­¤Ë +»ÈÍѤµ¤ì¤ë¥Û¥¹¥È¤ÎÊÌ̾
    ¹½Ê¸:ServerAlias hostname [hostname] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ServerAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥Í¡¼¥à¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤ª¤¤¤Æ + »ÈÍѤ¹¤ë¥Û¥¹¥È¤ÎÊÌ̾¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +

    + +

    »²¾È

    + +
    +
    top
    +

    ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤ò¼¨¤¹¤È¤­¤Ë»È¤¦¥Û¥¹¥È̾¤È¥Ý¡¼¥È
    ¹½Ê¸:ServerName fully-qualified-domain-name[:port]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ð¡¼¥¸¥ç¥ó 2.0 ¤Ç¤Ï¥Ð¡¼¥¸¥ç¥ó 1.3 ¤Î + Port ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Îµ¡Ç½¤â´Þ¤ß¤Þ¤¹¡£
    +

    ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤ò¼¨¤¹¥Û¥¹¥È̾¤È¥Ý¡¼¥È¤òÀßÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë URL ¤òÀ¸À®¤¹¤ëºÝ¤ËÍøÍѤµ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢¥¦¥§¥Ö¥µ¡¼¥Ð¤òÆ°¤«¤·¤Æ¤¤¤ë¥Þ¥·¥ó¤Ï simple.example.com + ¤Ç¡¢DNS ¤Î¥¨¥¤¥ê¥¢¥¹ www.example.com ¤â¤¢¤ë¤È¤­¤Ë¡¢ + ¥¦¥§¥Ö¥µ¡¼¥Ð¤¬¸å¼Ô¤È¤·¤Æǧ¼±¤µ¤ì¤ÆÍߤ·¤¤¤È¤­¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤¤¤Þ¤¹¡£

    + +

    + ServerName www.example.com:80 +

    + +

    ServerName ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï IP ¥¢¥É¥ì¥¹¤«¤éµÕ°ú¤­¤ò¹Ô¤Ê¤¦¤³¤È¤Ç¥Û¥¹¥È̾¤òÃÎ¤í¤¦¤È¤·¤Þ¤¹¡£ + ServerName ¤Ë¥Ý¡¼¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï¥ê¥¯¥¨¥¹¥È¤¬Íè¤Æ¤¤¤ë + ¥Ý¡¼¥È¤ò»È¤¤¤Þ¤¹¡£ºÇ¹â¤Î¿®ÍêÀ­¤È³Î¼ÂÀ­¤ò¤â¤¿¤é¤¹¤¿¤á¤Ë¤Ï¡¢ + ServerName ¤ò»È¤Ã¤Æ¥Û¥¹¥È̾¤È¥Ý¡¼¥È¤òÌÀ¼¨Åª¤Ë + »ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È + ¤òÍøÍѤ·¤Æ¤¤¤ë¾ì¹ç¡¢<VirtualHost> ¥»¥¯¥·¥ç¥óÆâ¤Î + ServerName ¤Ï¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥Þ¥Ã¥Á¤¹¤ë¤¿¤á¤Ë + ²¿¤¬¥ê¥¯¥¨¥¹¥È¤Î Host: ¥Ø¥Ã¥À¤Ë¸½¤ì¤ëɬÍפ¬¤¢¤ë¤Î¤«¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    ¼«¸Ê»²¾È URL (Î㤨¤Ð mod_dir ¥â¥¸¥å¡¼¥ë¤Ë¤è¤ë¤â¤Î¤Ê¤É) + ¤¬»ØÄꤵ¤ì¤¿¥Ý¡¼¥È¤ò»È¤¦¤«¡¢¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤Î¥Ý¡¼¥ÈÈÖ¹æ¤ò»È¤¦¤«¤ò + ·èÄꤹ¤ëÀßÄê¤Ï UseCanonicalName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    »²¾È

    + +
    +
    top
    +

    ServerPath ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Èó¸ß´¹¤Î¥Ö¥é¥¦¥¶¤¬Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥¢¥¯¥»¥¹¤·¤¿¤È¤­¤Î +¤¿¤á¤Î¸ß´¹ÍÑ URL ¥Ñ¥¹Ì¾
    ¹½Ê¸:ServerPath URL-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ServerPath ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥Í¡¼¥à¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤ª¤¤¤ÆÍøÍѤ¹¤ë + ¸ß´¹ÍÑ URL ¥Ñ¥¹Ì¾¤òÀßÄꤷ¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    ServerRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤¿¥µ¡¼¥Ð¤Î¥Ù¡¼¥¹¥Ç¥£¥ì¥¯¥È¥ê
    ¹½Ê¸:ServerRoot directory-path
    ¥Ç¥Õ¥©¥ë¥È:ServerRoot /usr/local/apache
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ServerRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¡¼¥Ð¤¬Â¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤òÀßÄꤷ¤Þ¤¹¡£ + Ä̾conf/ ¤ä logs/ ¤È¤¤¤Ã¤¿¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤¬ + ¸ºß¤·¤Þ¤¹¡£ + ¤Þ¤¿¡¢Â¾¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö (Î㤨¤Ð Include ¤ä LoadModule ¤Ê¤É) ¤Ë¤ª¤±¤ëÁêÂХѥ¹¤Ï¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤ÎÁêÂаÌÃ֤Ȥʤê¤Þ¤¹¡£

    + +

    Îã

    + ServerRoot /home/httpd +

    + + + +

    »²¾È

    + +
    +
    top
    +

    ServerSignature ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬À¸À®¤¹¤ë¥É¥­¥å¥á¥ó¥È¤Î¥Õ¥Ã¥¿¤òÀßÄê
    ¹½Ê¸:ServerSignature On|Off|EMail
    ¥Ç¥Õ¥©¥ë¥È:ServerSignature Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ServerSignature ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¡¼¥Ð¤¬À¸À®¤¹¤ë¥É¥­¥å¥á¥ó¥È + (¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¡¢mod_proxy ¤Ë¤ª¤±¤ë FTP ¤Î¥Ç¥£¥ì¥¯¥È¥ê¥ê¥¹¥È¡¢ + mod_info ¤Î½ÐÎÏ¡¢Åù¡¹) + ¤ÎºÇ²¼¹Ô¤ËÉÕÍ¿¤¹¤ë¥Õ¥Ã¥¿¤ÎÀßÄê¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê¥Õ¥Ã¥¿¹Ô¤òÍ­¸ú¤Ë¤·¤¿¤¤Íýͳ¤Ë¤Ï¡¢ + ¥×¥í¥­¥·¤¬Ê£¿ôÏ¢¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¡¢¥æ¡¼¥¶¤Ï¤É¤Î¥µ¡¼¥Ð¤¬ÊÖ¤·¤¿ + ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤«¤òÃΤë¼êÃʤ¬¤Û¤È¤ó¤É̵¤¤¤È¤¤¤¦¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£

    + + +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤¢¤ë Off ¤ËÀßÄê¤ò¤¹¤ë¤È¡¢¥Õ¥Ã¥¿¹Ô¤¬ÍÞÀ©¤µ¤ì¤Þ¤¹ + (¤½¤·¤Æ¡¢Apache-1.2 °ÊÁ°¤È¸ß´¹¤ÎÆ°ºî¤ò¤·¤Þ¤¹)¡£ + On ¤ËÀßÄꤷ¤¿¾ì¹ç¤Ï¡¢Ã±¤Ë¥É¥­¥å¥á¥ó¥È¤ÎÃæ¤Ë¡¢¥µ¡¼¥Ð¤Î¥Ð¡¼¥¸¥ç¥ó¡¢ + ²ÔÆ°Ãæ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î ServerName ¤Î½ñ¤«¤ì¤¿¹Ô¤òÄɲä·¡¢ + EMail ¤Ë¤·¤¿¾ì¹ç¤Ï¤µ¤é¤Ë»²¾È¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤ËÂФ¹¤ë ServerAdmin ¤ò»Ø¤¹ "mailto:" ¤¬Äɲ䵤ì¤Þ¤¹¡£

    + +

    ¥Ð¡¼¥¸¥ç¥ó 2.0.44 °Ê¹ß¤Ç¤Ï¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï ServerSignature + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤êɽ¼¨¤µ¤ì¤ë¾ðÊó¤âÀ©¸æ¤·¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    ServerTokens ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Server HTTP ±þÅú¥Ø¥Ã¥À¤òÀßÄꤹ¤ë
    ¹½Ê¸:ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
    ¥Ç¥Õ¥©¥ë¥È:ServerTokens Full
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤êÊÖ¤¹ Server + ±þÅú¥Ø¥Ã¥ÀÆâ¤Ë¡¢¥µ¡¼¥Ð¤Î°ìÈÌŪ¤Ê OS ¼ïÊ̤䡢 + ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤ÆÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤Î¾ðÊó¤ò + ´Þ¤á¤ë¤«¤É¤¦¤«¤ò»ØÄꤷ¤Þ¤¹¡£

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    ¥µ¡¼¥Ð¤Ï (Î㤨¤Ð): Server: + Apache ¤È¤¤¤Ã¤¿¤è¤¦¤ËÁ÷¤ê¤Þ¤¹¡£
    + +
    ServerTokens Major
    + +
    Server sends (e.g.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Server sends (e.g.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    ¥µ¡¼¥Ð¤Ï (Î㤨¤Ð): Server: + Apache/2.0.41 ¤È¤¤¤Ã¤¿¤è¤¦¤ËÁ÷¤ê¤Þ¤¹¡£
    + +
    ServerTokens OS
    + +
    ¥µ¡¼¥Ð¤Ï (Î㤨¤Ð): Server: Apache/2.0.41 + (Unix) ¤È¤¤¤Ã¤¿¤è¤¦¤ËÁ÷¤ê¤Þ¤¹¡£
    + +
    ServerTokens Full (¤â¤·¤¯¤Ï̤»ØÄê)
    + +
    ¥µ¡¼¥Ð¤Ï (Î㤨¤Ð): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2 ¤È¤¤¤Ã¤¿¤è¤¦¤ËÁ÷¤ê¤Þ¤¹¡£
    +
    + +

    ¤³¤ÎÀßÄê¤Ï¥µ¡¼¥ÐÁ´ÂΤËŬÍѤµ¤ì¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¾å¤ÇÍ­¸ú¤Ë¤·¤¿¤ê + ̵¸ú¤Ë¤·¤¿¤ê¤Ï¤Ç¤­¤Þ¤»¤ó¡£

    + +

    ¥Ð¡¼¥¸¥ç¥ó 2.0.44 °Ê¹ß¤Ç¤Ï¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï ServerSignature + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤êɽ¼¨¤µ¤ì¤ë¾ðÊó¤âÀ©¸æ¤·¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    SetHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¤¬¥Ï¥ó¥É¥é¤Ç½èÍý¤µ¤ì¤ë¤è¤¦¤Ë¤¹¤ë
    ¹½Ê¸:SetHandler handler-name|None
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    ¸ß´¹À­:Apache 2.0 ¤Ç core ¤Ë°ÜÆ°
    +

    .htaccess ¤ä <Directory> + ¥»¥¯¥·¥ç¥ó¡¢<Location> + ¥»¥¯¥·¥ç¥ó¤Ë½ñ¤«¤ì¤¿¾ì¹ç¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤³¤Ë¤¢¤ë¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤¬ + handler-name ¤Ç»ØÄꤵ¤ì¤¿¥Ï¥ó¥É¥é¤Ç°·¤ï¤ì¤ë¤³¤È¤ò¶¯À©¤·¤Þ¤¹¡£Î㤨¤Ð¡¢³ÈÄ¥»Ò¤Ë´Ø¤ï¤é¤º¡¢ + ¥Ç¥£¥ì¥¯¥È¥êÁ´ÂΤ¬¥¤¥á¡¼¥¸¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤È¤·¤Æ²òÀϤ·¤ÆÍߤ·¤¤¾ì¹ç¤Ë¤Ï¡¢ + °Ê²¼¤ò¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î .htaccess + ¥Õ¥¡¥¤¥ë¤Ëµ­½Ò¤·¤Þ¤¹:

    + +

    + SetHandler imap-file +

    + +

    Ê̤ÎÎã: URL http://servername/status + ¤¬»ØÄꤵ¤ì¤¿¤È¤­¤Ë¥µ¡¼¥Ð¤¬¾õÂÖÊó¹ð¤ò¤¹¤ë¤è¤¦¤Ë¤·¤¿¤¤¤È¤­¤Ï¡¢°Ê²¼¤ò + httpd.conf ¤Ëµ­½Ò¤·¤Þ¤¹:

    + +

    + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +

    + +

    None ¤È¤¤¤¦ÃͤòÀßÄꤹ¤ë¤³¤È¤Ç¡¢ + Á°¤ÎÊý¤Î SetHandler ¤ÇÄêµÁ¤µ¤ì¤¿ÀßÄê¤ò̵¸ú¤Ë¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    SetInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ä POST ¤ÎÆþÎϤò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÀßÄꤹ¤ë
    ¹½Ê¸:SetInputFilter filter[;filter...]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    SetInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î + ¥ê¥¯¥¨¥¹¥È¤ä POST ¤ÎÆþÎϤò¥µ¡¼¥Ð¤¬¼õ¤±¼è¤Ã¤¿¤È¤­¤Ë½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤ò + ÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï AddInputFilter + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò´Þ¤á¡¢Â¾¤Î¾ì½ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¥ë¥¿¤ÎÀßÄê¤Ë + Äɲ䵤ì¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤ò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥Ç¡¼¥¿¤ò½èÍý¤¹¤ë½çÈÖ¤Ë + ¥»¥ß¥³¥í¥ó¤Ç¶èÀÚ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + + +

    »²¾È

    + +
    +
    top
    +

    SetOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤Î±þÅú¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÀßÄꤹ¤ë
    ¹½Ê¸:SetOutputFilter filter[;filter...]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    SetOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥µ¡¼¥Ð¤Î±þÅú¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤êÊÖ¤µ¤ì¤ëÁ°¤Ë½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÀßÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï AddOutputFilter + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò´Þ¤á¡¢Â¾¤Î¾ì½ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¥ë¥¿¤ÎÀßÄê¤Ë + Äɲ䵤ì¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢°Ê²¼¤ÎÀßÄê¤Ï /www/data/ ¥Ç¥£¥ì¥¯¥È¥ê¤Î¤¹¤Ù¤Æ¤Î + ¥Õ¥¡¥¤¥ë¤ò SSI ¤Ç½èÍý¤·¤Þ¤¹¡£

    + +

    + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +

    + +

    Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤ò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥Ç¡¼¥¿¤ò½èÍý¤¹¤ë½çÈÖ¤Ë + ¥»¥ß¥³¥í¥ó¤Ç¶èÀÚ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    TimeOut ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:³Æ¥¤¥Ù¥ó¥È¤Ë¤Ä¤¤¤Æ¡¢¥ê¥¯¥¨¥¹¥È¤ò¼ºÇÔ¤µ¤»¤ë¤Þ¤Ç¤Ë¥µ¡¼¥Ð¤¬ +ÂԤĻþ´Ö¤òÀßÄê
    ¹½Ê¸:TimeOut seconds
    ¥Ç¥Õ¥©¥ë¥È:TimeOut 300
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    TimeOut ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¸½ºß¤Î¤È¤³¤í + °Ê²¼¤Î»°¤Ä¤ÎÂÔ¤Á»þ´Ö¤Ë¤Ä¤¤¤Æ¤ÎÄêµÁ¤ò¹Ô¤¤¤Þ¤¹:

    + +
      +
    1. GET ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤ë¤Î¤Ë¤«¤«¤ëÁí»þ´Ö
    2. + +
    3. POST ¤ä PUT¥ê¥¯¥¨¥¹¥È¤Ë¤ª¤¤¤Æ¡¢¼¡¤Î TCP ¥Ñ¥±¥Ã¥È¤¬ÆϤ¯¤Þ¤Ç¤ÎÂÔ¤Á»þ´Ö
    4. + +
    5. ¥ì¥¹¥Ý¥ó¥¹¤òÊÖ¤¹ºÝ¡¢TCP ¤Î ACK ¤¬µ¢¤Ã¤Æ¤¯¤ë¤Þ¤Ç¤Î»þ´Ö
    6. +
    + +

    ¾­Íè¤Ë¤ÏÊÌ¡¹¤ÎÀßÄê¤ò¤¹¤ë¤³¤È¤¬²Äǽ¤Ë¤Ç¤­¤ë¤è¤¦¹ÍθÃæ¤Ç¤¹¡£ + Apache 1.2 °ÊÁ°¤Ï¥¿¥¤¥Þ¡¼¤Ï 1200 ¤¬¥Ç¥Õ¥©¥ë¥È¤Ç¤·¤¿¤¬¡¢ + 300 ¤Ë²¼¤²¤é¤ì¤Þ¤·¤¿¡£300 ¤Ç¤â¤Û¤È¤ó¤É¤Î¾ì¹ç¤Ï½½Ê¬¤¹¤®¤ëÃͤǤ¹¡£ + ¥³¡¼¥ÉÃæ¤ÎÊѤʾì½ê¤Ë¤Þ¤À¥Ñ¥±¥Ã¥È¤òÁ÷¤ëºÝ¤Ë¥¿¥¤¥Þ¤ò¥ê¥»¥Ã¥È¤·¤Ê¤¤ + ¾ì½ê¤¬¤¢¤ë¤«¤â¤·¤ì¤Ê¤¤¤Î¤Ç¡¢¥Ç¥Õ¥©¥ë¥È¤ò¤è¤ê¾®¤µ¤¤ÃͤˤϤ·¤Æ¤¤¤Þ¤»¤ó¡£

    + + +
    +
    top
    +

    UseCanonicalName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤Î̾Á°¤È¥Ý¡¼¥È¤ò·èÄꤹ¤ëÊýË¡¤òÀßÄꤹ¤ë
    ¹½Ê¸:UseCanonicalName On|Off|Dns
    ¥Ç¥Õ¥©¥ë¥È:UseCanonicalName Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    ¿¤¯¤Î¾õ¶·¤Ç Apache ¤Ï¼«¸Ê»²¾È URL¡¢¤¹¤Ê¤ï¤Á + Ʊ¤¸¥µ¡¼¥Ð¤ò»Ø¤¹ URL¡¢¤òºîÀ®¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + UseCanonicalName On ¤Î¾ì¹ç¤Ï¡¢ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë + ¥Û¥¹¥È̾¤È¥Ý¡¼¥ÈÈÖ¹æ¤ò»È¤Ã¤Æ¡¢¤½¤ÎÀµµ¬Ì¾ (¼«¸Ê»²¾È¤Î̾Á°) ¤òÀ¸À®¤·¤Þ¤¹¡£ + ¤³¤Î̾Á°¤Ï¡¢¤¹¤Ù¤Æ¤Î¼«¸Ê»²¾È URL ¤Ç»È¤ï¤ì¤Þ¤¹¤·¡¢CGI ¤Î + SERVER_NAME ¤È SERVER_PORT ¤Ç¤â»È¤ï¤ì¤Þ¤¹¡£

    + +

    UseCanonicalName Off ¤Î¾ì¹ç¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤¬¥Û¥¹¥È̾¤È¥Ý¡¼¥È¤ò»ØÄꤷ¤¿¤È¤­¤Ë¤Ï¡¢ + ¤½¤ì¤é¤ò¸µ¤Ë¼«¸Ê»²¾È URL ¤òºîÀ®¤·¤Þ¤¹ (»ØÄ꤬¤Ê¤«¤Ã¤¿¤È¤­¤Ï + ¾å¤ÎÄêµÁ¤ÈƱÍͤˤ·¤ÆÀµµ¬Ì¾¤ò²ò·è¤·¤Þ¤¹)¡£ + ¤³¤ì¤é¤ÎÃͤÏ̾Á°¥Ù¡¼¥¹¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò¼ÂÁõ¤Ç»È¤ï¤ì¤Æ¤¤¤ë¤Î¤ÈƱ¤¸Ãͤǡ¢ + Ʊ¤¸¥¯¥é¥¤¥¢¥ó¥È¤Ç¼èÆÀ¤Ç¤­¤ëÃͤˤʤäƤ¤¤Þ¤¹¡£ + CGI ÊÑ¿ô SERVER_NAME ¤È SERVER_PORT + ¤â¥¯¥é¥¤¥¢¥ó¥È¤«¤éÍ¿¤¨¤é¤ì¤¿Ãͤ«¤éºîÀ®¤µ¤ì¤Þ¤¹¡£

    + +

    ¤³¤Î¤è¤¦¤ÊµóÆ°¤¬ÊØÍø¤ÊÎã¤Ï¡¢¥¤¥ó¥È¥é¥Í¥Ã¥È¤Î¥µ¡¼¥Ð¤Ç www + ¤Î¤è¤¦¤Êû¤¤Ì¾Á°¤Ç¥æ¡¼¥¶¤¬¥Þ¥·¥ó¤ËÀܳ¤¹¤ë¤È¤­¤Ç¤¹¡£ + ¥æ¡¼¥¶¤ÎÆþÎϤÇû¤¤¥Û¥¹¥È̾¤¬»È¤ï¤ì¤Æ¤¤¤Æ¡¢URL ¤¬ºÇ¸å¤Î¥¹¥é¥Ã¥·¥å̵¤·¤Î + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ê¤Ã¤Æ¤¤¤ë http://www/splat ¤Î¤è¤¦¤Ê¤È¤­¡¢ + Apache ¤Ï¥ê¥¯¥¨¥¹¥È¤ò http://www.domain.com/splat/ + ¤Ø¥ê¥À¥¤¥ì¥¯¥È¤·¤Þ¤¹¡£ + ǧ¾Ú¤ò¤¹¤ë¤è¤¦¤ËÀßÄꤷ¤Æ¤¤¤ë¤È¡¢¤³¤Î¾ì¹ç + ¥æ¡¼¥¶¤Ï 2 ²óǧ¾Ú¤ò¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¯¤Ê¤ê¤Þ¤¹ (www ¤Ë + ÂФ·¤Æ 1 ²ó¡¢www.domain.com ¤ËÂФ·¤Æ¤â¤¦ 1 ²ó -- + ¾ÜºÙ¤Ï ¤³¤ÎÏÃÂê¤Î + FAQ ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤)¡£ + ¤·¤«¤· UseCanonicalName ¤¬ Off ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¡¢ + Apache ¤Ï http://www/splat/ ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤·¤Þ¤¹¡£

    + +

    »°¤ÄÌܤΥª¥×¥·¥ç¥ó UseCanonicalName DNS ¤Ï¡¢ + Â絬ÌÏ¤Ê IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥Æ¥£¥ó¥°¤Ç¡¢ + Host: ¥Ø¥Ã¥À¤òÄ󶡤·¤Ê¤¤¸Å¤¤¥¯¥é¥¤¥¢¥ó¥È¤ò + ¥µ¥Ý¡¼¥È¤¹¤ë¾ì¹ç¤òÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç¤Ï Apache ¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬Àܳ¤·¤¿ IP ¥¢¥É¥ì¥¹¤ËÂФ·¤Æ + DNS ¤ÎµÕ°ú¤­¤ò¹Ô¤Ê¤Ã¤Æ¡¢¼«¸Ê»²¾È URL ¤òºîÀ®¤·¤Þ¤¹¡£

    + +

    ·Ù¹ð

    +

    CGI ¤¬ SERVER_NAME ¤Ë´Ø¤·¤Æ²¿¤é¤«¤ÎÁ°Äó¾ò·ï¤ò + ²¾Äꤷ¤Æ¤¤¤ë¤È¤­¤Ë¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ÎÀßÄê¤Ë¤è¤Ã¤Æ¤ÏÆ°ºî¤·¤Ê¤¯ + ¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¥¯¥é¥¤¥¢¥ó¥È¤Ï¼Â¼ÁŪ¤Ë¤Ï¥Û¥¹¥È̾¤È¤·¤Æ + ²¿¤Ç¤â˾¤ß¤ÎÃͤò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£CGI ¤¬ + SERVER_NAME ¤ò»È¤Ã¤Æ¼«¸Ê»²¾È URL ¤òºîÀ®¤¹¤ë¤³¤È¤·¤«¤·¤Ê¤¤ + ¾ì¹ç¤Ï¡¢¤É¤ÎÀßÄê¤ò¹Ô¤Ê¤Ã¤Æ¤âÂç¾æÉפʤϤº¤Ç¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    <VirtualHost> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î¥Û¥¹¥È̾¤ä IP ¥¢¥É¥ì¥¹¤Î¤ß¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +°Ï¤à
    ¹½Ê¸:<VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Core
    ¥â¥¸¥å¡¼¥ë:core
    +

    <VirtualHost> µÚ¤Ó + </VirtualHost> ¤Ï¡¢ + ÆÃÄê¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤Æ¤Î¤ßŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö·²¤ò³ç¤ë + ¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥³¥ó¥Æ¥­¥¹¥È¤Çµö²Ä¤µ¤ì¤ëÁ´¤Æ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ØÄê²Äǽ¤Ç¤¹¡£ + ¥µ¡¼¥Ð¤¬¡¢»ØÄꤵ¤ì¤¿¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤¢¤ë¥É¥­¥å¥á¥ó¥È¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿¾ì¹ç¡¢ + <VirtualHost> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ë¤¢¤ë + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£ + Addr¤Ï¡¢¼¡¤Î¤â¤Î¤¬ÍøÍѤǤ­¤Þ¤¹:

    + +
      +
    • ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î IP ¥¢¥É¥ì¥¹
    • + +
    • ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î IP ¤ËÂбþ¤¹¤ë´°Á´¤Ê¥É¥á¥¤¥ó̾
    • + +
    • NameVirtualHost * ¤È¶¦¤Ë»È¤ï¤ì¤ë¡¢ + ¤¹¤Ù¤Æ¤Î IP ¥¢¥É¥ì¥¹¤Ë¥Þ¥Ã¥Á¤¹¤ëʸ»ú *
    • + +
    • IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¾¤Î¤â¤Î¤Ë¥Þ¥Ã¥Á¤·¤Ê¤¤ IP ¥¢¥É¥ì¥¹ + ¤Î¤¿¤á¤Îʸ»úÎó _default_
    • +
    + +

    Îã

    + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +

    + +

    IPv6 ¥¢¥É¥ì¥¹¤Ï¥ª¥×¥·¥ç¥ó¤Î¥Ý¡¼¥ÈÈÖ¹æ¤Î»ØÄê¤È¶èÊ̤¹¤ë¤¿¤á¤Ë¡¢ + ³Ñ³ç¸Ì¤Ç³ç¤Ã¤Æ»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¼¡¤Ï IPv6 ¤ÎÎã¤Ç¤¹:

    + +

    + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +

    + +

    ³Æ¡¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤Ï¤½¤ì¤¾¤ì°ã¤¦ IP ¥¢¥É¥ì¥¹¡¢¥Ý¡¼¥ÈÈÖ¹æ + ¤â¤·¤¯¤Ï¥Û¥¹¥È̾¤ËÂбþ¤¹¤ëɬÍפ¬¤¢¤ê¡¢ + 1 ÈÖÌܤξì¹ç¤Ë¤ÏÊ£¿ô¤Î¥¢¥É¥ì¥¹¤Ç IP ¥Ñ¥±¥Ã¥È¤ò¼õ¿®¤Ç¤­¤ë¤è¤¦¤Ë + ¥µ¡¼¥Ð¥Þ¥·¥ó¤òÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + (¤â¤·¡¢¥Þ¥·¥ó¤¬Ê£¿ô¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È»ý¤¿¤Ê¤¤¾ì¹ç¤Ï¡¢ + (OS¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ì¤Ð) ifconfig alias ¥³¥Þ¥ó¥É¤Ë¤è¤ê + ãÀ®¤Ç¤­¤Þ¤¹)¡£

    + +

    :port ¤È¤¤¤Ã¤¿·Á¼°¤Çµ­½Ò¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥Þ¥Ã¥Á¤µ¤»¤ë¥Ý¡¼¥È¤òÊѹ¹²Äǽ¤Ç¤¹¡£ + ¤³¤Î»ØÄê¤ò¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¼ç¥µ¡¼¥ÐÀßÄê¤Ë¤ª¤±¤ë + °ìÈֺǸå¤Ë Port ¤Ç»ØÄꤵ¤ì¤¿¥Ý¡¼¥È¤¬ + ¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ê¤Þ¤¹¡£ + :* ¤ò»ØÄꤹ¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥¢¥É¥ì¥¹¾å¤ÎÁ´¤Æ¤Î¥Ý¡¼¥È¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£(_default_ ¤Î¤È¤­¤Ï + ¤³¤ì¤ò»È¤¦¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£)

    + +

    ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤·¤Æ: + ¥µ¡¼¥Ð¡¼¤òµ¯Æ°¤·¤¿°Ê³°¤Î¥æ¡¼¥¶¤¬¥í¥°¥Õ¥¡¥¤¥ë¤¬Êݴɤµ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ½ñ¤­¹þ¤ß²Äǽ¤Ê¤È¤­¤Ë¤Ê¤¼¥»¥­¥å¥ê¥Æ¥£¤¬Çˤé¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë¤«¤Î¾ÜºÙ¤Ï + ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë¥³¥Ä ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãí°ÕÅÀ

    +

    <VirtualHost> ¤Ï Apache ¤¬ Listen ¤¹¤ë + IP ¥¢¥É¥ì¥¹¤Ë¤Ï±Æ¶Á¤òÍ¿¤¨¤Þ¤»¤ó¡£ + Listen ¤ò + »È¤Ã¤Æ Apache ¤¬Àµ¤·¤¤¥¢¥É¥ì¥¹¤ò listen ¤¹¤ë¤è¤¦¤ËÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    +
    + +

    IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ÆÃÊ̤Ê̾Á° + _default_ ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤½¤Î¾ì¹ç¤Ï + ¤½¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï¾¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÇÌÀ¼¨Åª¤Ëµó¤²¤é¤ì¤Æ¤¤¤Ê¤¤ + ¤¹¤Ù¤Æ¤Î IP ¥¢¥É¥ì¥¹¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£_default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬Ìµ¤¤ + ¾ì¹ç¤Ë IP ¤¬¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç»ØÄꤵ¤ì¤¿¤â¤Î¤Ë¥Þ¥Ã¥Á¤·¤Ê¤¤¤È¤­¤Ï¡¢ + VirtualHost ¥»¥¯¥·¥ç¥ó¤Î³°¤Î¤¹¤Ù¤Æ¤ÎÄêµÁ¤«¤é¤Ê¤ë¡Ö¼ç¡×¥µ¡¼¥ÐÀßÄ꤬ + »È¤ï¤ì¤Þ¤¹¡£(¤¿¤À¤·¡¢NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¥Þ¥Ã¥Á¤¹¤ë + ¤¹¤Ù¤Æ¤Î IP ¥¢¥É¥ì¥¹¤Ï¡Ö¼ç¡×¥µ¡¼¥ÐÀßÄê¤â _default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤â + »È¤ï¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¾Ü¤·¤¯¤Ï ¥Í¡¼¥à¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£)

    + +

    :port ¤È¤¤¤Ã¤¿·Á¼°¤Çµ­½Ò¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥Þ¥Ã¥Á¤µ¤»¤ë¥Ý¡¼¥È¤òÊѹ¹²Äǽ¤Ç¤¹¡£ + ¤³¤Î»ØÄê¤ò¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¼ç¥µ¡¼¥ÐÀßÄê¤Ë¤ª¤±¤ë + °ìÈֺǸå¤Ë Listen ¤Ç»ØÄꤵ¤ì¤¿ + ¥Ý¡¼¥È¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ê¤Þ¤¹¡£ + :* ¤ò»ØÄꤹ¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥¢¥É¥ì¥¹¾å¤ÎÁ´¤Æ¤Î¥Ý¡¼¥È¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£(_default_ ¤Î¤È¤­¤Ï + ¤³¤ì¤ò»È¤¦¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£)

    + +

    :port ¤È¤¤¤Ã¤¿·Á¼°¤Çµ­½Ò¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥Þ¥Ã¥Á¤µ¤»¤ë¥Ý¡¼¥È¤òÊѹ¹²Äǽ¤Ç¤¹¡£ + ¤³¤Î»ØÄê¤ò¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¼ç¥µ¡¼¥ÐÀßÄê¤Ë¤ª¤±¤ë + °ìÈֺǸå¤Ë Port ¤Ç»ØÄꤵ¤ì¤¿¥Ý¡¼¥È¤¬ + ¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ê¤Þ¤¹¡£ + :* ¤ò»ØÄꤹ¤ë¤³¤È¤Ë¤è¤ê¡¢ + ¥¢¥É¥ì¥¹¾å¤ÎÁ´¤Æ¤Î¥Ý¡¼¥È¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£(_default_ ¤Î¤È¤­¤Ï + ¤³¤ì¤ò»È¤¦¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£)

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    ¥µ¡¼¥Ð¡¼¤òµ¯Æ°¤·¤¿°Ê³°¤Î¥æ¡¼¥¶¤¬¥í¥°¥Õ¥¡¥¤¥ë¤¬Êݴɤµ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ½ñ¤­¹þ¤ß²Äǽ¤Ê¤È¤­¤Ë¤Ê¤¼¥»¥­¥å¥ê¥Æ¥£¤¬Çˤé¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë¤«¤Î¾ÜºÙ¤Ï + ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë¥³¥Ä ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/core.xml b/trunk/docs/manual/mod/core.xml new file mode 100644 index 0000000000..4a9eb1c63c --- /dev/null +++ b/trunk/docs/manual/mod/core.xml @@ -0,0 +1,3138 @@ + + + + + + + + + +core +Core Apache HTTP Server features that are always +available +Core + + +AcceptPathInfo +Resources accept trailing pathname information +AcceptPathInfo On|Off|Default +AcceptPathInfo Default +server config +virtual hostdirectory +.htaccess +FileInfo +Available in Apache 2.0.30 and later + + + +

    This directive controls whether requests that contain trailing + pathname information that follows an actual filename (or + non-existent file in an existing directory) will be accepted or + rejected. The trailing pathname information can be made + available to scripts in the PATH_INFO environment + variable.

    + +

    For example, assume the location /test/ points to + a directory that contains only the single file + here.html. Then requests for + /test/here.html/more and + /test/nothere.html/more both collect + /more as PATH_INFO.

    + +

    The three possible arguments for the + AcceptPathInfo directive are:

    +
    +
    Off
    A request will only be accepted if it + maps to a literal path that exists. Therefore a request with + trailing pathname information after the true filename such as + /test/here.html/more in the above example will return + a 404 NOT FOUND error.
    + +
    On
    A request will be accepted if a + leading path component maps to a file that exists. The above + example /test/here.html/more will be accepted if + /test/here.html maps to a valid file.
    + +
    Default
    The treatment of requests with + trailing pathname information is determined by the handler responsible for the request. + The core handler for normal files defaults to rejecting + PATH_INFO requests. Handlers that serve scripts, such as cgi-script and isapi-isa, generally accept + PATH_INFO by default.
    +
    + +

    The primary purpose of the AcceptPathInfo + directive is to allow you to override the handler's choice of + accepting or rejecting PATH_INFO. This override is required, + for example, when you use a filter, such + as INCLUDES, to generate content + based on PATH_INFO. The core handler would usually reject + the request, so you can use the following configuration to enable + such a script:

    + + + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +
    + +
    +
    + + +AccessFileName +Name of the distributed configuration file +AccessFileName filename [filename] ... +AccessFileName .htaccess +server configvirtual host + + + +

    While processing a request the server looks for + the first existing configuration file from this list of names in + every directory of the path to the document, if distributed + configuration files are enabled for that + directory. For example:

    + + + AccessFileName .acl + + +

    before returning the document + /usr/local/web/index.html, the server will read + /.acl, /usr/.acl, + /usr/local/.acl and /usr/local/web/.acl + for directives, unless they have been disabled with

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory> +
    +
    +AllowOverride +Configuration Files +.htaccess Files +
    + + +AddDefaultCharset +Default charset parameter to be added when a response +content-type is text/plain or text/html +AddDefaultCharset On|Off|charset +AddDefaultCharset Off +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    This directive specifies a default value for the media type + charset parameter (the name of a character encoding) to be added + to a response if and only if the response's content-type is either + text/plain or text/html. This should override + any charset specified in the body of the response via a META + element, though the exact behavior is often dependent on the user's client + configuration. A setting of AddDefaultCharset Off + disables this functionality. AddDefaultCharset On enables + a default charset of iso-8859-1. Any other value is assumed + to be the charset to be used, which should be one of the + IANA registered + charset values for use in MIME media types. + For example:

    + + + AddDefaultCharset utf-8 + + +

    AddDefaultCharset should only be used when all + of the text resources to which it applies are known to be in that + character encoding and it is too inconvenient to label their charset + individually. One such example is to add the charset parameter + to resources containing generated content, such as legacy CGI + scripts, that might be vulnerable to cross-site scripting attacks + due to user-provided data being included in the output. Note, however, + that a better solution is to just fix (or delete) those scripts, since + setting a default charset does not protect users that have enabled + the "auto-detect character encoding" feature on their browser.

    +
    +AddCharset +
    + + +AddOutputFilterByType +assigns an output filter to a particular MIME-type +AddOutputFilterByType filter[;filter...] +MIME-type [MIME-type] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Available in Apache 2.0.33 and later + + +

    This directive activates a particular output filter for a request depending on the + response MIME-type.

    + +

    The following example uses the DEFLATE filter, which + is provided by mod_deflate. It will compress all + output (either static or dynamic) which is labeled as + text/html or text/plain before it is sent + to the client.

    + + + AddOutputFilterByType DEFLATE text/html text/plain + + +

    If you want the content to be processed by more than one filter, their + names have to be separated by semicolons. It's also possible to use one + AddOutputFilterByType directive for each of + these filters.

    + +

    The configuration below causes all script output labeled as + text/html to be processed at first by the + INCLUDES filter and then by the DEFLATE + filter.

    + + + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +
    + + Note +

    Enabling filters with AddOutputFilterByType + may fail partially or completely in some cases. For example, no + filters are applied if the MIME-type could not be determined and falls + back to the DefaultType setting, + even if the DefaultType is the + same.

    + +

    However, if you want to make sure, that the filters will be + applied, assign the content type to a resource explicitly, for + example with AddType or + ForceType. Setting the + content type within a (non-nph) CGI script is also safe.

    + +

    The by-type output filters are never applied on proxy requests.

    +
    +
    + +AddOutputFilter +SetOutputFilter +filters +
    + + +AllowEncodedSlashes +Determines whether encoded path separators in URLs are allowed to +be passed through +AllowEncodedSlashes On|Off +AllowEncodedSlashes Off +server configvirtual host + +Available in Apache 2.0.46 and later + + +

    The AllowEncodedSlashes directive allows URLs + which contain encoded path separators (%2F for / + and additionally %5C for \ on according systems) + to be used. Normally such URLs are refused with a 404 (Not found) error.

    + +

    Turning AllowEncodedSlashes On is + mostly useful when used in conjunction with PATH_INFO.

    + + Note +

    Allowing encoded slashes does not imply decoding. + Occurrences of %2F or %5C (only on + according systems) will be left as such in the otherwise decoded URL + string.

    +
    +
    +AcceptPathInfo +
    + + +AllowOverride +Types of directives that are allowed in +.htaccess files +AllowOverride All|None|directive-type +[directive-type] ... +AllowOverride All +directory + + +

    When the server finds an .htaccess file (as + specified by AccessFileName) + it needs to know which directives declared in that file can override + earlier configuration directives.

    + + Only available in <Directory> sections + AllowOverride is valid only in + Directory + sections specified without regular expressions, not in Location, DirectoryMatch or + Files sections. + + +

    When this directive is set to None, then + .htaccess files are completely ignored. + In this case, the server will not even attempt to read + .htaccess files in the filesystem.

    + +

    When this directive is set to All, then any + directive which has the .htaccess Context is allowed in + .htaccess files.

    + +

    The directive-type can be one of the following + groupings of directives.

    + +
    +
    AuthConfig
    + +
    + + Allow use of the authorization directives (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require, etc.).
    + +
    FileInfo
    + +
    + Allow use of the directives controlling document types (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, and + mod_mime Add* and Remove* + directives, etc.).
    + +
    Indexes
    + +
    + Allow use of the directives controlling directory indexing + (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, + etc.).
    + +
    Limit
    + +
    + Allow use of the directives controlling host access (Allow, Deny and Order).
    + +
    Options[=Option,...]
    + +
    + Allow use of the directives controlling specific directory + features (Options and + XBitHack). + An equal sign may be given followed by a comma (but no spaces) + separated lists of options that may be set using the Options command.
    +
    + +

    Example:

    + + + AllowOverride AuthConfig Indexes + + +

    In the example above all directives that are neither in the group + AuthConfig nor Indexes cause an internal + server error.

    +
    + +AccessFileName +Configuration Files +.htaccess Files +
    + + +AuthName +Authorization realm for use in HTTP +authentication +AuthName auth-domain +directory.htaccess + +AuthConfig + + +

    This directive sets the name of the authorization realm for a + directory. This realm is given to the client so that the user + knows which username and password to send. + AuthName takes a single argument; if the + realm name contains spaces, it must be enclosed in quotation + marks. It must be accompanied by AuthType and Require directives, and directives such + as AuthUserFile and + AuthGroupFile to + work.

    + +

    For example:

    + + + AuthName "Top Secret" + + +

    The string provided for the AuthName is what will + appear in the password dialog provided by most browsers.

    +
    +Authentication, Authorization, and + Access Control +
    + + +AuthType +Type of user authentication +AuthType Basic|Digest +directory.htaccess + +AuthConfig + + +

    This directive selects the type of user authentication for a + directory. Only Basic and Digest are + currently implemented. + + It must be accompanied by AuthName and Require directives, and directives such + as AuthUserFile and + AuthGroupFile to + work.

    +
    +Authentication, Authorization, +and Access Control +
    + + +CGIMapExtension +Technique for locating the interpreter for CGI +scripts +CGIMapExtension cgi-path .extension +directory.htaccess + +FileInfo +NetWare only + + +

    This directive is used to control how Apache finds the + interpreter used to run CGI scripts. For example, setting + CGIMapExtension sys:\foo.nlm .foo will + cause all CGI script files with a .foo extension to + be passed to the FOO interpreter.

    +
    +
    + + +ContentDigest +Enables the generation of Content-MD5 HTTP Response +headers +ContentDigest On|Off +ContentDigest Off +server configvirtual host +directory.htaccess + +Options +Experimental + + +

    This directive enables the generation of + Content-MD5 headers as defined in RFC1864 + respectively RFC2068.

    + +

    MD5 is an algorithm for computing a "message digest" + (sometimes called "fingerprint") of arbitrary-length data, with + a high degree of confidence that any alterations in the data + will be reflected in alterations in the message digest.

    + +

    The Content-MD5 header provides an end-to-end + message integrity check (MIC) of the entity-body. A proxy or + client may check this header for detecting accidental + modification of the entity-body in transit. Example header:

    + + + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== + + +

    Note that this can cause performance problems on your server + since the message digest is computed on every request (the + values are not cached).

    + +

    Content-MD5 is only sent for documents served + by the core, and not by any module. For example, + SSI documents, output from CGI scripts, and byte range responses + do not have this header.

    +
    +
    + + +DefaultType +MIME content-type that will be sent if the +server cannot determine a type in any other way +DefaultType MIME-type +DefaultType text/plain +server configvirtual host +directory.htaccess + +FileInfo + + +

    There will be times when the server is asked to provide a + document whose type cannot be determined by its MIME types + mappings.

    + +

    The server must inform the client of the content-type of the + document, so in the event of an unknown type it uses the + DefaultType. For example:

    + + + DefaultType image/gif + + +

    would be appropriate for a directory which contained many GIF + images with filenames missing the .gif extension.

    + +

    Note that unlike ForceType, this directive only + provides the default mime-type. All other mime-type definitions, + including filename extensions, that might identify the media type + will override this default.

    +
    +
    + + +Directory +Enclose a group of directives that apply only to the +named file-system directory and sub-directories +<Directory directory-path> +... </Directory> +server configvirtual host + + + +

    Directory and + </Directory> are used to enclose a group of + directives that will apply only to the named directory and + sub-directories of that directory. Any directive that is allowed + in a directory context may be used. Directory-path is + either the full path to a directory, or a wild-card string using + Unix shell-style matching. In a wild-card string, ? matches + any single character, and * matches any sequences of + characters. You may also use [] character ranges. None + of the wildcards match a `/' character, so <Directory + /*/public_html> will not match + /home/user/public_html, but <Directory + /home/*/public_html> will match. Example:

    + + + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +
    + + +

    Be careful with the directory-path arguments: + They have to literally match the filesystem path which Apache uses + to access the files. Directives applied to a particular + <Directory> will not apply to files accessed from + that same directory via a different path, such as via different symbolic + links.

    +
    + +

    Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + + + <Directory ~ "^/www/.*/[0-9]{3}"> + + +

    would match directories in /www/ that consisted of + three numbers.

    + +

    If multiple (non-regular expression) Directory sections + match the directory (or one of its parents) containing a document, + then the directives are applied in the order of shortest match + first, interspersed with the directives from the .htaccess files. For example, + with

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +
    + +

    for access to the document /home/web/dir/doc.html + the steps are:

    + +
      +
    • Apply directive AllowOverride None + (disabling .htaccess files).
    • + +
    • Apply directive AllowOverride FileInfo (for + directory /home).
    • + +
    • Apply any FileInfo directives in + /home/.htaccess, /home/web/.htaccess and + /home/web/dir/.htaccess in that order.
    • +
    + +

    Regular expressions are not considered until after all of the + normal sections have been applied. Then all of the regular + expressions are tested in the order they appeared in the + configuration file. For example, with

    + + + <Directory ~ abc$>
    + + # ... directives here ...
    +
    + </Directory> +
    + +

    the regular expression section won't be considered until after + all normal Directorys and + .htaccess files have been applied. Then the regular + expression will match on /home/abc/public_html/abc and + the corresponding Directory will + be applied.

    + +

    Note that the default Apache access for + <Directory /> is Allow from All. + This means that Apache will serve any file mapped from an URL. It is + recommended that you change this with a block such + as

    + + + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +
    + +

    and then override this for directories you + want accessible. See the Security Tips page for more + details.

    + +

    The directory sections occur in the httpd.conf file. + Directory directives + cannot nest, and cannot appear in a Limit or LimitExcept section.

    +
    +How <Directory>, + <Location> and <Files> sections work for an + explanation of how these different sections are combined when a + request is received +
    + + +DirectoryMatch +Enclose directives that apply to +file-system directories matching a regular expression and their +subdirectories +<DirectoryMatch regex> +... </DirectoryMatch> +server configvirtual host + + + +

    DirectoryMatch and + </DirectoryMatch> are used to enclose a group + of directives which will apply only to the named directory and + sub-directories of that directory, the same as Directory. However, it + takes as an argument a regular expression. For example:

    + + + <DirectoryMatch "^/www/(.+/)?[0-9]{3}"> + + +

    would match directories in /www/ that consisted of three + numbers.

    +
    +Directory for +a description of how regular expressions are mixed in with normal +Directorys +How <Directory>, <Location> and +<Files> sections work for an explanation of how these different +sections are combined when a request is received +
    + + +DocumentRoot +Directory that forms the main document tree visible +from the web +DocumentRoot directory-path +DocumentRoot /usr/local/apache/htdocs +server configvirtual host + + + +

    This directive sets the directory from which httpd + will serve files. Unless matched by a directive like Alias, the server appends the + path from the requested URL to the document root to make the + path to the document. Example:

    + + + DocumentRoot /usr/web + + +

    then an access to + http://www.my.host.com/index.html refers to + /usr/web/index.html. If the directory-path is + not absolute then it is assumed to be relative to the ServerRoot.

    + +

    The DocumentRoot should be specified without + a trailing slash.

    +
    +Mapping URLs to Filesystem +Location +
    + + +EnableMMAP +Use memory-mapping to read files during delivery +EnableMMAP On|Off +EnableMMAP On +server configvirtual host +directory.htaccess + +FileInfo + + +

    This directive controls whether the httpd may use + memory-mapping if it needs to read the contents of a file during + delivery. By default, when the handling of a request requires + access to the data within a file -- for example, when delivering a + server-parsed file using mod_include -- Apache + memory-maps the file if the OS supports it.

    + +

    This memory-mapping sometimes yields a performance improvement. + But in some environments, it is better to disable the memory-mapping + to prevent operational problems:

    + +
      +
    • On some multiprocessor systems, memory-mapping can reduce the + performance of the httpd.
    • +
    • With an NFS-mounted DocumentRoot, + the httpd may crash due to a segmentation fault if a file + is deleted or truncated while the httpd has it + memory-mapped.
    • +
    + +

    For server configurations that are vulnerable to these problems, + you should disable memory-mapping of delivered files by specifying:

    + + + EnableMMAP Off + + +

    For NFS mounted files, this feature may be disabled explicitly for + the offending files by specifying:

    + + + <Directory "/path-to-nfs-files"> + + EnableMMAP Off + + </Directory> + +
    +
    + + +EnableSendfile +Use the kernel sendfile support to deliver files to the client +EnableSendfile On|Off +EnableSendfile On +server configvirtual host +directory.htaccess + +FileInfo +Available in version 2.0.44 and later + + +

    This directive controls whether httpd may use the + sendfile support from the kernel to transmit file contents to the client. + By default, when the handling of a request requires no access + to the data within a file -- for example, when delivering a + static file -- Apache uses sendfile to deliver the file contents + without ever reading the file if the OS supports it.

    + +

    This sendfile mechanism avoids separate read and send operations, + and buffer allocations. But on some platforms or within some + filesystems, it is better to disable this feature to avoid + operational problems:

    + +
      +
    • Some platforms may have broken sendfile support that the build + system did not detect, especially if the binaries were built on + another box and moved to such a machine with broken sendfile + support.
    • +
    • On Linux the use of sendfile triggers TCP-checksum + offloading bugs on certain networking cards when using IPv6.
    • +
    • With a network-mounted DocumentRoot (e.g., NFS or SMB), + the kernel may be unable to serve the network file through + its own cache.
    • +
    + +

    For server configurations that are vulnerable to these problems, + you should disable this feature by specifying:

    + + + EnableSendfile Off + + +

    For NFS or SMB mounted files, this feature may be disabled explicitly + for the offending files by specifying:

    + + + <Directory "/path-to-nfs-files"> + + EnableSendfile Off + + </Directory> + +
    +
    + + +ErrorDocument +What the server will return to the client +in case of an error +ErrorDocument error-code document +server configvirtual host +directory.htaccess + +FileInfo +Quoting syntax for text messages is different in Apache +2.0 + + +

    In the event of a problem or error, Apache can be configured + to do one of four things,

    + +
      +
    1. output a simple hardcoded error message
    2. + +
    3. output a customized message
    4. + +
    5. redirect to a local URL-path to handle the + problem/error
    6. + +
    7. redirect to an external URL to handle the + problem/error
    8. +
    + +

    The first option is the default, while options 2-4 are + configured using the ErrorDocument + directive, which is followed by the HTTP response code and a URL + or a message. Apache will sometimes offer additional information + regarding the problem/error.

    + +

    URLs can begin with a slash (/) for local web-paths (relative + to the DocumentRoot), or be a + full URL which the client can resolve. Alternatively, a message + can be provided to be displayed by the browser. Examples:

    + + + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/bad_urls.pl
    + ErrorDocument 401 /subscription_info.html
    + ErrorDocument 403 "Sorry can't allow you access today" +
    + +

    Additionally, the special value default can be used + to specify Apache's simple hardcoded message. While not required + under normal circumstances, default will restore + Apache's simple hardcoded message for configurations that would + otherwise inherit an existing ErrorDocument.

    + + + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +
    + +

    Note that when you specify an ErrorDocument + that points to a remote URL (ie. anything with a method such as + http in front of it), Apache will send a redirect to the + client to tell it where to find the document, even if the + document ends up being on the same server. This has several + implications, the most important being that the client will not + receive the original error status code, but instead will + receive a redirect status code. This in turn can confuse web + robots and other clients which try to determine if a URL is + valid using the status code. In addition, if you use a remote + URL in an ErrorDocument 401, the client will not + know to prompt the user for a password since it will not + receive the 401 status code. Therefore, if you use an + ErrorDocument 401 directive then it must refer to a local + document.

    + +

    Microsoft Internet Explorer (MSIE) will by default ignore + server-generated error messages when they are "too small" and substitute + its own "friendly" error messages. The size threshold varies depending on + the type of error, but in general, if you make your error document + greater than 512 bytes, then MSIE will show the server-generated + error rather than masking it. More information is available in + Microsoft Knowledge Base article Q294807.

    + +

    Although most error messages can be overriden, there are certain + circumstances where the internal messages are used regardless of the + setting of ErrorDocument. In + particular, if a malformed request is detected, normal request processing + will be immediately halted and the internal error message returned. + This is necessary to guard against security problems caused by + bad requests.

    + +

    Prior to version 2.0, messages were indicated by prefixing + them with a single unmatched double quote character.

    +
    + +documentation of + customizable responses +
    + + +ErrorLog +Location where the server will log errors + ErrorLog file-path|syslog[:facility] +ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2) +server configvirtual host + + + +

    The ErrorLog directive sets the name of + the file to which the server will log any errors it encounters. If + the file-path is not absolute then it is assumed to be + relative to the ServerRoot.

    + + Example + ErrorLog /var/log/httpd/error_log + + +

    If the file-path + begins with a pipe (|) then it is assumed to be a command to spawn + to handle the error log.

    + + Example + ErrorLog "|/usr/local/bin/httpd_errors" + + +

    Using syslog instead of a filename enables logging + via syslogd(8) if the system supports it. The default is to use + syslog facility local7, but you can override this by + using the syslog:facility syntax where + facility can be one of the names usually documented in + syslog(1).

    + + Example + ErrorLog syslog:user + + +

    SECURITY: See the security tips + document for details on why your security could be compromised + if the directory where log files are stored is writable by + anyone other than the user that starts the server.

    + Note +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    +
    +LogLevel +Apache Log Files +
    + + +FileETag +File attributes used to create the ETag +HTTP response header +FileETag component ... +FileETag INode MTime Size +server configvirtual host +directory.htaccess + +FileInfo + + +

    + The FileETag directive configures the file + attributes that are used to create the ETag (entity + tag) response header field when the document is based on a file. + (The ETag value is used in cache management to save + network bandwidth.) In Apache 1.3.22 and earlier, the + ETag value was always formed + from the file's inode, size, and last-modified time (mtime). The + FileETag directive allows you to choose + which of these -- if any -- should be used. The recognized keywords are: +

    + +
    +
    INode
    +
    The file's i-node number will be included in the calculation
    +
    MTime
    +
    The date and time the file was last modified will be included
    +
    Size
    +
    The number of bytes in the file will be included
    +
    All
    +
    All available fields will be used. This is equivalent to: + FileETag INode MTime Size
    +
    None
    +
    If a document is file-based, no ETag field will be + included in the response
    +
    + +

    The INode, MTime, and Size + keywords may be prefixed with either + or -, + which allow changes to be made to the default setting inherited + from a broader scope. Any keyword appearing without such a prefix + immediately and completely cancels the inherited setting.

    + +

    If a directory's configuration includes + FileETag INode MTime Size, and a + subdirectory's includes FileETag -INode, + the setting for that subdirectory (which will be inherited by + any sub-subdirectories that don't override it) will be equivalent to + FileETag MTime Size.

    +
    +
    + + +Files +Contains directives that apply to matched +filenames +<Files filename> ... </Files> +server configvirtual host +directory.htaccess + +All + + +

    The Files directive + limits the scope of the enclosed directives by filename. It is comparable + to the Directory + and Location + directives. It should be matched with a </Files> + directive. The directives given within this section will be applied to + any object with a basename (last component of filename) matching the + specified filename. Files + sections are processed in the order they appear in the + configuration file, after the Directory sections and + .htaccess files are read, but before Location sections. Note + that Files can be nested + inside Directory sections to restrict the + portion of the filesystem they apply to.

    + +

    The filename argument should include a filename, or + a wild-card string, where ? matches any single character, + and * matches any sequences of characters. Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + + + <Files ~ "\.(gif|jpe?g|png)$"> + + +

    would match most common Internet graphics formats. FilesMatch is preferred, + however.

    + +

    Note that unlike Directory and Location sections, Files sections can be used inside + .htaccess files. This allows users to control access to + their own files, at a file-by-file level.

    + +
    +How <Directory>, <Location> + and <Files> sections work for an explanation of how these + different sections are combined when a request is received +
    + + +FilesMatch +Contains directives that apply to regular-expression matched +filenames +<FilesMatch regex> ... </FilesMatch> +server configvirtual host +directory.htaccess + +All + + +

    The FilesMatch directive + limits the scope of the enclosed directives by filename, just as the + Files directive + does. However, it accepts a regular expression. For example:

    + + + <FilesMatch "\.(gif|jpe?g|png)$"> + + +

    would match most common Internet graphics formats.

    +
    + +How <Directory>, <Location> + and <Files> sections work for an explanation of how these + different sections are combined when a request is received +
    + + +ForceType +Forces all matching files to be served with the specified +MIME content-type +ForceType MIME-type|None +directory.htaccess + +FileInfo +Moved to the core in Apache 2.0 + + +

    When placed into an .htaccess file or a + Directory, or + Location or + Files + section, this directive forces all matching files to be served + with the content type identification given by + MIME-type. For example, if you had a directory full of + GIF files, but did not want to label them all with .gif, + you might want to use:

    + + + ForceType image/gif + + +

    Note that unlike DefaultType, + this directive overrides all mime-type associations, including + filename extensions, that might identify the media type.

    + +

    You can override any ForceType setting + by using the value of None:

    + + + # force all files to be image/gif:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # but normal mime-type associations here:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +
    +
    +
    + + +HostnameLookups +Enables DNS lookups on client IP addresses +HostnameLookups On|Off|Double +HostnameLookups Off +server configvirtual host +directory + + +

    This directive enables DNS lookups so that host names can be + logged (and passed to CGIs/SSIs in REMOTE_HOST). + The value Double refers to doing double-reverse + DNS lookup. That is, after a reverse lookup is performed, a forward + lookup is then performed on that result. At least one of the IP + addresses in the forward lookup must match the original + address. (In "tcpwrappers" terminology this is called + PARANOID.)

    + +

    Regardless of the setting, when mod_authz_host is + used for controlling access by hostname, a double reverse lookup + will be performed. This is necessary for security. Note that the + result of this double-reverse isn't generally available unless you + set HostnameLookups Double. For example, if only + HostnameLookups On and a request is made to an object + that is protected by hostname restrictions, regardless of whether + the double-reverse fails or not, CGIs will still be passed the + single-reverse result in REMOTE_HOST.

    + +

    The default is Off in order to save the network + traffic for those sites that don't truly need the reverse + lookups done. It is also better for the end users because they + don't have to suffer the extra latency that a lookup entails. + Heavily loaded sites should leave this directive + Off, since DNS lookups can take considerable + amounts of time. The utility logresolve, compiled by + default to the bin subdirectory of your installation + directory, can be used to look up host names from logged IP addresses + offline.

    +
    +
    + + +IfDefine +Encloses directives that will be processed only +if a test is true at startup +<IfDefine [!]parameter-name> ... + </IfDefine> +server configvirtual host +directory.htaccess + +All + + +

    The <IfDefine test>...</IfDefine> + section is used to mark directives that are conditional. The + directives within an IfDefine + section are only processed if the test is true. If + test is false, everything between the start and end markers is + ignored.

    + +

    The test in the IfDefine section directive can be one of two forms:

    + +
      +
    • parameter-name
    • + +
    • !parameter-name
    • +
    + +

    In the former case, the directives between the start and end + markers are only processed if the parameter named + parameter-name is defined. The second format reverses + the test, and only processes the directives if + parameter-name is not defined.

    + +

    The parameter-name argument is a define as given on + the httpd command line via -Dparameter- + , at the time the server was started.

    + +

    IfDefine sections are + nest-able, which can be used to implement simple + multiple-parameter tests. Example:

    + + + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +
    +
    +
    + + +IfModule +Encloses directives that are processed conditional on the +presence or absence of a specific module +<IfModule [!]module-file|module-identifier> ... + </IfModule> +server configvirtual host +directory.htaccess + +All +Module identifiers are available in version 2.1 and +later. + + +

    The <IfModule test>...</IfModule> + section is used to mark directives that are conditional on the presence of + a specific module. The directives within an IfModule section are only processed if the test + is true. If test is false, everything between the start and + end markers is ignored.

    + +

    The test in the IfModule section directive can be one of two forms:

    + +
      +
    • module
    • + +
    • !module
    • +
    + +

    In the former case, the directives between the start and end + markers are only processed if the module named module + is included in Apache -- either compiled in or + dynamically loaded using LoadModule. The second format reverses the test, + and only processes the directives if module is + not included.

    + +

    The module argument can be either the module identifier or + the file name of the module, at the time it was compiled. For example, + rewrite_module is the identifier and + mod_rewrite.c is the file name. If a module consists of + several source files, use the name of the file containing the string + STANDARD20_MODULE_STUFF.

    + +

    IfModule sections are + nest-able, which can be used to implement simple multiple-module + tests.

    + + This section should only be used if you need to have one + configuration file that works whether or not a specific module + is available. In normal operation, directives need not be + placed in IfModule + sections. +
    +
    + + +Include +Includes other configuration files from within +the server configuration files +Include file-path|directory-path +server configvirtual host +directory + +Wildcard matching available in 2.0.41 and later + + +

    This directive allows inclusion of other configuration files + from within the server configuration files.

    + +

    Shell-style (fnmatch()) wildcard characters can be used to + include several files at once, in alphabetical order. In + addition, if Include points to a directory, + rather than a file, Apache will read all files in that directory + and any subdirectory. But including entire directories is not + recommended, because it is easy to accidentally leave temporary + files in a directory that can cause httpd to + fail.

    + +

    The file path specified may be an absolute path, or may be relative + to the ServerRoot directory.

    + +

    Examples:

    + + + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +
    + +

    Or, providing paths relative to your ServerRoot directory:

    + + + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +
    + +

    Running apachectl configtest will give you a list + of the files that are being processed during the configuration + check:

    + + + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +
    +
    + +apachectl +
    + + +KeepAlive +Enables HTTP persistent connections +KeepAlive On|Off +KeepAlive On +server configvirtual host + + + +

    The Keep-Alive extension to HTTP/1.0 and the persistent + connection feature of HTTP/1.1 provide long-lived HTTP sessions + which allow multiple requests to be sent over the same TCP + connection. In some cases this has been shown to result in an + almost 50% speedup in latency times for HTML documents with + many images. To enable Keep-Alive connections, set + KeepAlive On.

    + +

    For HTTP/1.0 clients, Keep-Alive connections will only be + used if they are specifically requested by a client. In + addition, a Keep-Alive connection with an HTTP/1.0 client can + only be used when the length of the content is known in + advance. This implies that dynamic content such as CGI output, + SSI pages, and server-generated directory listings will + generally not use Keep-Alive connections to HTTP/1.0 clients. + For HTTP/1.1 clients, persistent connections are the default + unless otherwise specified. If the client requests it, chunked + encoding will be used in order to send content of unknown + length over persistent connections.

    +
    + +MaxKeepAliveRequests +
    + + +KeepAliveTimeout +Amount of time the server will wait for subsequent +requests on a persistent connection +KeepAliveTimeout seconds +KeepAliveTimeout 5 +server configvirtual host + + + +

    The number of seconds Apache will wait for a subsequent + request before closing the connection. Once a request has been + received, the timeout value specified by the + Timeout directive applies.

    + +

    Setting KeepAliveTimeout to a high value + may cause performance problems in heavily loaded servers. The + higher the timeout, the more server processes will be kept + occupied waiting on connections with idle clients.

    +
    +
    + + +Limit +Restrict enclosed access controls to only certain HTTP +methods +<Limit method [method] ... > ... + </Limit> +server configvirtual host +directory.htaccess + +All + + +

    Access controls are normally effective for + all access methods, and this is the usual + desired behavior. In the general case, access control + directives should not be placed within a + Limit section.

    + +

    The purpose of the Limit + directive is to restrict the effect of the access controls to the + nominated HTTP methods. For all other methods, the access + restrictions that are enclosed in the Limit bracket will have no + effect. The following example applies the access control + only to the methods POST, PUT, and + DELETE, leaving all other methods unprotected:

    + + + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +
    + +

    The method names listed can be one or more of: GET, + POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK, and UNLOCK. The method name is + case-sensitive. If GET is used it will also + restrict HEAD requests. The TRACE method + cannot be limited.

    + + A LimitExcept section should always be + used in preference to a Limit section when restricting access, + since a LimitExcept section provides protection + against arbitrary methods. + +
    +
    + + +LimitExcept +Restrict access controls to all HTTP methods +except the named ones +<LimitExcept method [method] ... > ... + </LimitExcept> +server configvirtual host +directory.htaccess + +All + + +

    LimitExcept and + </LimitExcept> are used to enclose + a group of access control directives which will then apply to any + HTTP access method not listed in the arguments; + i.e., it is the opposite of a Limit section and can be used to control + both standard and nonstandard/unrecognized methods. See the + documentation for Limit for more details.

    + +

    For example:

    + + + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +
    + +
    +
    + + +LimitInternalRecursion +Determine maximum number of internal redirects and nested +subrequests +LimitInternalRecursion number [number] +LimitInternalRecursion 10 +server configvirtual host + +Available in Apache 2.0.47 and later + + +

    An internal redirect happens, for example, when using the Action directive, which internally + redirects the original request to a CGI script. A subrequest is Apache's + mechanism to find out what would happen for some URI if it were requested. + For example, mod_dir uses subrequests to look for the + files listed in the DirectoryIndex + directive.

    + +

    LimitInternalRecursion prevents the server + from crashing when entering an infinite loop of internal redirects or + subrequests. Such loops are usually caused by misconfigurations.

    + +

    The directive stores two different limits, which are evaluated on + per-request basis. The first number is the maximum number of + internal redirects, that may follow each other. The second number + determines, how deep subrequests may be nested. If you specify only one + number, it will be assigned to both limits.

    + + Example + LimitInternalRecursion 5 + +
    +
    + + +LimitRequestBody +Restricts the total size of the HTTP request body sent +from the client +LimitRequestBody bytes +LimitRequestBody 0 +server configvirtual host +directory.htaccess + +All + + +

    This directive specifies the number of bytes from 0 + (meaning unlimited) to 2147483647 (2GB) that are allowed in a + request body.

    + +

    The LimitRequestBody directive allows + the user to set a limit on the allowed size of an HTTP request + message body within the context in which the directive is given + (server, per-directory, per-file or per-location). If the client + request exceeds that limit, the server will return an error + response instead of servicing the request. The size of a normal + request message body will vary greatly depending on the nature of + the resource and the methods allowed on that resource. CGI scripts + typically use the message body for retrieving form information. + Implementations of the PUT method will require + a value at least as large as any representation that the server + wishes to accept for that resource.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service + attacks.

    + +

    If, for example, you are permitting file upload to a particular + location, and wish to limit the size of the uploaded file to 100K, + you might use the following directive:

    + + + LimitRequestBody 102400 + + +
    +
    + + +LimitRequestFields +Limits the number of HTTP request header fields that +will be accepted from the client +LimitRequestFields number +LimitRequestFields 100 +server config + + +

    Number is an integer from 0 (meaning unlimited) to + 32767. The default value is defined by the compile-time + constant DEFAULT_LIMIT_REQUEST_FIELDS (100 as + distributed).

    + +

    The LimitRequestFields directive allows + the server administrator to modify the limit on the number of + request header fields allowed in an HTTP request. A server needs + this value to be larger than the number of fields that a normal + client request might include. The number of request header fields + used by a client rarely exceeds 20, but this may vary among + different client implementations, often depending upon the extent + to which a user has configured their browser to support detailed + content negotiation. Optional HTTP extensions are often expressed + using request header fields.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks. + The value should be increased if normal clients see an error + response from the server that indicates too many fields were + sent in the request.

    + +

    For example:

    + + + LimitRequestFields 50 + + +
    +
    + + +LimitRequestFieldSize +Limits the size of the HTTP request header allowed from the +client +LimitRequestFieldsize bytes +LimitRequestFieldsize 8190 +server config + + +

    This directive specifies the number of bytes + that will be allowed in an HTTP request header.

    + +

    The LimitRequestFieldSize directive + allows the server administrator to reduce or increase the limit + on the allowed size of an HTTP request header field. A server + needs this value to be large enough to hold any one header field + from a normal client request. The size of a normal request header + field will vary greatly among different client implementations, + often depending upon the extent to which a user has configured + their browser to support detailed content negotiation. SPNEGO + authentication headers can be up to 12392 bytes.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks.

    + +

    For example:

    + + + LimitRequestFieldSize 4094 + + + Under normal conditions, the value should not be changed from + the default. + +
    +
    + + +LimitRequestLine +Limit the size of the HTTP request line that will be accepted +from the client +LimitRequestLine bytes +LimitRequestLine 8190 +server config + + +

    This directive sets the number of bytes that will be + allowed on the HTTP request-line.

    + +

    The LimitRequestLine directive allows + the server administrator to reduce or increase the limit on the allowed size + of a client's HTTP request-line. Since the request-line consists of the + HTTP method, URI, and protocol version, the + LimitRequestLine directive places a + restriction on the length of a request-URI allowed for a request + on the server. A server needs this value to be large enough to + hold any of its resource names, including any information that + might be passed in the query part of a GET request.

    + +

    This directive gives the server administrator greater + control over abnormal client request behavior, which may be + useful for avoiding some forms of denial-of-service attacks.

    + +

    For example:

    + + + LimitRequestLine 4094 + + + Under normal conditions, the value should not be changed from + the default. +
    +
    + + +LimitXMLRequestBody +Limits the size of an XML-based request body +LimitXMLRequestBody bytes +LimitXMLRequestBody 1000000 +server configvirtual host +directory.htaccess +All + + +

    Limit (in bytes) on maximum size of an XML-based request + body. A value of 0 will disable any checking.

    + +

    Example:

    + + + LimitXMLRequestBody 0 + + +
    +
    + + +Location +Applies the enclosed directives only to matching +URLs +<Location + URL-path|URL> ... </Location> +server configvirtual host + + + +

    The Location directive + limits the scope of the enclosed directives by URL. It is similar to the + Directory + directive, and starts a subsection which is terminated with a + </Location> directive. Location sections are processed in the + order they appear in the configuration file, after the Directory sections and + .htaccess files are read, and after the Files sections.

    + +

    Location sections operate + completely outside the filesystem. This has several consequences. + Most importantly, Location + directives should not be used to control access to filesystem + locations. Since several different URLs may map to the same + filesystem location, such access controls may by circumvented.

    + + When to use <directive + type="section">Location</directive> + +

    Use Location to apply + directives to content that lives outside the filesystem. For + content that lives in the filesystem, use Directory and Files. An exception is + <Location />, which is an easy way to + apply a configuration to the entire server.

    +
    + +

    For all origin (non-proxy) requests, the URL to be matched is a + URL-path of the form /path/. No scheme, hostname, + port, or query string may be included. For proxy requests, the + URL to be matched is of the form + scheme://servername/path, and you must include the + prefix.

    + +

    The URL may use wildcards. In a wild-card string, ? matches + any single character, and * matches any sequences of + characters.

    + +

    Extended regular + expressions can also be used, with the addition of the + ~ character. For example:

    + + + <Location ~ "/(extra|special)/data"> + + +

    would match URLs that contained the substring /extra/data + or /special/data. The directive LocationMatch behaves + identical to the regex version of Location.

    + +

    The Location + functionality is especially useful when combined with the + SetHandler + directive. For example, to enable status requests, but allow them + only from browsers at foo.com, you might use:

    + + + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +
    + + Note about / (slash) +

    The slash character has special meaning depending on where in a + URL it appears. People may be used to its behavior in the filesystem + where multiple adjacent slashes are frequently collapsed to a single + slash (i.e., /home///foo is the same as + /home/foo). In URL-space this is not necessarily true. + The LocationMatch + directive and the regex version of Location require you to explicitly specify multiple + slashes if that is your intention.

    + +

    For example, <LocationMatch ^/abc> would match + the request URL /abc but not the request URL + //abc. The (non-regex) Location directive behaves similarly when used for + proxy requests. But when (non-regex) Location is used for non-proxy requests it will + implicitly match multiple slashes with a single slash. For example, + if you specify <Location /abc/def> and the + request is to /abc//def then it will match.

    +
    +
    +How <Directory>, <Location> + and <Files> sections work for an explanation of how these + different sections are combined when a request is received +
    + + +LocationMatch +Applies the enclosed directives only to regular-expression +matching URLs +<LocationMatch + regex> ... </LocationMatch> +server configvirtual host + + + +

    The LocationMatch directive + limits the scope of the enclosed directives by URL, in an identical manner + to Location. However, + it takes a regular expression as an argument instead of a simple + string. For example:

    + + + <LocationMatch "/(extra|special)/data"> + + +

    would match URLs that contained the substring /extra/data + or /special/data.

    +
    + +How <Directory>, <Location> + and <Files> sections work for an explanation of how these + different sections are combined when a request is received +
    + + +LogLevel +Controls the verbosity of the ErrorLog +LogLevel level +LogLevel warn +server configvirtual host + + + +

    LogLevel adjusts the verbosity of the + messages recorded in the error logs (see ErrorLog directive). The following + levels are available, in order of decreasing + significance:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level Description Example
    emerg Emergencies - system is unusable."Child cannot open lock file. Exiting"
    alert Action must be taken immediately."getpwuid: couldn't determine user name from uid"
    crit Critical Conditions."socket: Failed to get a socket, exiting child"
    error Error conditions."Premature end of script headers"
    warn Warning conditions."child process 1234 did not exit, sending another + SIGHUP"
    notice Normal but significant condition."httpd: caught SIGBUS, attempting to dump core in + ..."
    info Informational."Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..."
    debug Debug-level messages"Opening config file ..."
    + +

    When a particular level is specified, messages from all + other levels of higher significance will be reported as well. + E.g., when LogLevel info is specified, + then messages with log levels of notice and + warn will also be posted.

    + +

    Using a level of at least crit is + recommended.

    + +

    For example:

    + + + LogLevel notice + + + Note +

    When logging to a regular file messages of the level + notice cannot be suppressed and thus are always + logged. However, this doesn't apply when logging is done + using syslog.

    +
    +
    +
    + + +MaxKeepAliveRequests +Number of requests allowed on a persistent +connection +MaxKeepAliveRequests number +MaxKeepAliveRequests 100 +server configvirtual host + + + +

    The MaxKeepAliveRequests directive + limits the number of requests allowed per connection when + KeepAlive is on. If it is + set to 0, unlimited requests will be allowed. We + recommend that this setting be kept to a high value for maximum + server performance.

    + +

    For example:

    + + + MaxKeepAliveRequests 500 + +
    +
    + + +NameVirtualHost +Designates an IP address for name-virtual +hosting +NameVirtualHost addr[:port] +server config + + +

    The NameVirtualHost directive is a + required directive if you want to configure name-based virtual hosts.

    + +

    Although addr can be hostname it is recommended + that you always use an IP address, e.g.

    + + + NameVirtualHost 111.22.33.44 + + +

    With the NameVirtualHost directive you + specify the IP address on which the server will receive requests + for the name-based virtual hosts. This will usually be the address + to which your name-based virtual host names resolve. In cases + where a firewall or other proxy receives the requests and forwards + them on a different IP address to the server, you must specify the + IP address of the physical interface on the machine which will be + servicing the requests. If you have multiple name-based hosts on + multiple addresses, repeat the directive for each address.

    + + Note +

    Note, that the "main server" and any _default_ servers + will never be served for a request to a + NameVirtualHost IP address (unless for some + reason you specify NameVirtualHost but then + don't define any VirtualHosts for that + address).

    +
    + +

    Optionally you can specify a port number on which the + name-based virtual hosts should be used, e.g.

    + + + NameVirtualHost 111.22.33.44:8080 + + +

    IPv6 addresses must be enclosed in square brackets, as shown + in the following example:

    + + + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 + + +

    To receive requests on all interfaces, you can use an argument of + *

    + + + NameVirtualHost * + + + Argument to <directive type="section">VirtualHost</directive> + directive +

    Note that the argument to the VirtualHost directive must + exactly match the argument to the NameVirtualHost directive.

    + + + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +
    +
    +
    + +Virtual Hosts +documentation + +
    + + +Options +Configures what features are available in a particular +directory +Options + [+|-]option [[+|-]option] ... +Options All +server configvirtual host +directory.htaccess + +Options + + +

    The Options directive controls which + server features are available in a particular directory.

    + +

    option can be set to None, in which + case none of the extra features are enabled, or one or more of + the following:

    + +
    +
    All
    + +
    All options except for MultiViews. This is the default + setting.
    + +
    ExecCGI
    + +
    + Execution of CGI scripts using mod_cgi + is permitted.
    + +
    FollowSymLinks
    + +
    + + The server will follow symbolic links in this directory. + +

    Even though the server follows the symlink it does not + change the pathname used to match against Directory sections.

    +

    Note also, that this option gets ignored if set + inside a Location + section.

    +
    + +
    Includes
    + +
    + Server-side includes provided by mod_include + are permitted.
    + +
    IncludesNOEXEC
    + +
    + + Server-side includes are permitted, but the #exec + cmd and #exec cgi are disabled. It is still + possible to #include virtual CGI scripts from + ScriptAliased + directories.
    + +
    Indexes
    + +
    + If a URL which maps to a directory is requested, and there + is no DirectoryIndex + (e.g., index.html) in that directory, then + mod_autoindex will return a formatted listing + of the directory.
    + +
    MultiViews
    + +
    + Content negotiated + "MultiViews" are allowed using + mod_negotiation.
    + +
    SymLinksIfOwnerMatch
    + +
    The server will only follow symbolic links for which the + target file or directory is owned by the same user id as the + link. + + Note This option gets ignored if + set inside a Location section. +
    +
    + +

    Normally, if multiple Options could + apply to a directory, then the most specific one is used and + others are ignored; the options are not merged. (See how sections are merged.) + However if all the options on the + Options directive are preceded by a + + or - symbol, the options are + merged. Any options preceded by a + are added to the + options currently in force, and any options preceded by a + - are removed from the options currently in + force.

    + +

    For example, without any + and - symbols:

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +
    + +

    then only Includes will be set for the + /web/docs/spec directory. However if the second + Options directive uses the + and + - symbols:

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +
    + +

    then the options FollowSymLinks and + Includes are set for the /web/docs/spec + directory.

    + + Note +

    Using -IncludesNOEXEC or + -Includes disables server-side includes completely + regardless of the previous setting.

    +
    + +

    The default in the absence of any other settings is + All.

    +
    +
    + + +Require +Selects which authenticated users can access +a resource +Require entity-name [entity-name] ... +directory.htaccess + +AuthConfig + + +

    This directive selects which authenticated users can access + a resource. The allowed syntaxes are:

    + +
    +
    Require user userid [userid] + ...
    +
    Only the named users can access the resource.
    + +
    Require group group-name [group-name] + ...
    +
    Only users in the named groups can access the resource.
    + +
    Require valid-user
    +
    All valid users can access the resource.
    +
    + +

    Require must be accompanied by + AuthName and AuthType directives, and directives such + as AuthUserFile + and AuthGroupFile (to + define users and groups) in order to work correctly. Example:

    + + + AuthType Basic
    + AuthName "Restricted Resource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +
    + +

    Access controls which are applied in this way are effective for + all methods. This is what is normally + desired. If you wish to apply access controls only to + specific methods, while leaving other methods unprotected, then + place the Require statement into a + Limit + section.

    +
    +Satisfy +mod_authz_host +
    + + +RLimitCPU +Limits the CPU consumption of processes launched +by Apache children +RLimitCPU seconds|max [seconds|max] +Unset; uses operating system defaults +server configvirtual host +directory.htaccess +All + + +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit should + be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    CPU resource limits are expressed in seconds per + process.

    +
    +RLimitMEM +RLimitNPROC +
    + + +RLimitMEM +Limits the memory consumption of processes launched +by Apache children +RLimitMEM bytes|max [bytes|max] +Unset; uses operating system defaults +server configvirtual host +directory.htaccess +All + + +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit should + be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    Memory resource limits are expressed in bytes per + process.

    +
    +RLimitCPU +RLimitNPROC +
    + + +RLimitNPROC +Limits the number of processes that can be launched by +processes launched by Apache children +RLimitNPROC number|max [number|max] +Unset; uses operating system defaults +server configvirtual host +directory.htaccess +All + + +

    Takes 1 or 2 parameters. The first parameter sets the soft + resource limit for all processes and the second parameter sets + the maximum resource limit. Either parameter can be a number, + or max to indicate to the server that the limit + should be set to the maximum allowed by the operating system + configuration. Raising the maximum resource limit requires that + the server is running as root, or in the initial startup + phase.

    + +

    This applies to processes forked off from Apache children + servicing requests, not the Apache children themselves. This + includes CGI scripts and SSI exec commands, but not any + processes forked off from the Apache parent such as piped + logs.

    + +

    Process limits control the number of processes per user.

    + + Note +

    If CGI processes are not running + under user ids other than the web server user id, this directive + will limit the number of processes that the server itself can + create. Evidence of this situation will be indicated by + cannot fork messages in the + error_log.

    +
    +
    +RLimitMEM +RLimitCPU +
    + + +Satisfy +Interaction between host-level access control and +user authentication +Satisfy Any|All +Satisfy All +directory.htaccess + +AuthConfig +Influenced by Limit and LimitExcept in version 2.0.51 and +later + + +

    Access policy if both Allow and Require used. The parameter can be + either All or Any. This directive is only + useful if access to a particular area is being restricted by both + username/password and client host address. In this case + the default behavior (All) is to require that the client + passes the address access restriction and enters a valid + username and password. With the Any option the client will be + granted access if they either pass the host restriction or enter a + valid username and password. This can be used to password restrict + an area, but to let clients from particular addresses in without + prompting for a password.

    + +

    For example, if you wanted to let people on your network have + unrestricted access to a portion of your website, but require that + people outside of your network provide a password, you could use a + configuration similar to the following:

    + + + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +
    + +

    Since version 2.0.51 Satisfy directives can + be restricted to particular methods by Limit and LimitExcept sections.

    +
    + Allow + Require +
    + + +ScriptInterpreterSource +Technique for locating the interpreter for CGI +scripts +ScriptInterpreterSource Registry|Registry-Strict|Script +ScriptInterpreterSource Script +server configvirtual host +directory.htaccess +FileInfo +Win32 only; +option Registry-Strict is available in Apache 2.0 and +later + + +

    This directive is used to control how Apache finds the + interpreter used to run CGI scripts. The default setting is + Script. This causes Apache to use the interpreter pointed to + by the shebang line (first line, starting with #!) in the + script. On Win32 systems this line usually looks like:

    + + + #!C:/Perl/bin/perl.exe + + +

    or, if perl is in the PATH, simply:

    + + + #!perl + + +

    Setting ScriptInterpreterSource Registry will + cause the Windows Registry tree HKEY_CLASSES_ROOT to be + searched using the script file extension (e.g., .pl) as a + search key. The command defined by the registry subkey + Shell\ExecCGI\Command or, if it does not exist, by the subkey + Shell\Open\Command is used to open the script file. If the + registry keys cannot be found, Apache falls back to the behavior of the + Script option.

    + + Security +

    Be careful when using ScriptInterpreterSource + Registry with ScriptAlias'ed directories, because + Apache will try to execute every file within this + directory. The Registry setting may cause undesired + program calls on files which are typically not executed. For + example, the default open command on .htm files on + most Windows systems will execute Microsoft Internet Explorer, so + any HTTP request for an .htm file existing within the + script directory would start the browser in the background on the + server. This is a good way to crash your system within a minute or + so.

    +
    + +

    The option Registry-Strict which is new in Apache + 2.0 does the same thing as Registry but uses only the + subkey Shell\ExecCGI\Command. The + ExecCGI key is not a common one. It must be + configured manually in the windows registry and hence prevents + accidental program calls on your system.

    +
    +
    + + +ServerAdmin +Email address that the server includes in error +messages sent to the client +ServerAdmin email-address|URL +server configvirtual host + + + +

    The ServerAdmin sets the contact address + that the server includes in any error messages it returns to the + client. If the httpd doesn't recognize the supplied argument + as an URL, it + assumes, that it's an email-address and prepends it with + mailto: in hyperlink targets. However, it's recommended to + actually use an email address, since there are a lot of CGI scripts that + make that assumption. If you want to use an URL, it should point to another + server under your control. Otherwise users may not be able to contact you in + case of errors.

    + +

    It may be worth setting up a dedicated address for this, e.g.

    + + + ServerAdmin www-admin@foo.example.com + +

    as users do not always mention that they are talking about the + server!

    +
    +
    + + +ServerAlias +Alternate names for a host used when matching requests +to name-virtual hosts +ServerAlias hostname [hostname] ... +virtual host + + +

    The ServerAlias directive sets the + alternate names for a host, for use with name-based virtual hosts.

    + + + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +
    +
    +Apache Virtual Host documentation +
    + + +ServerName +Hostname and port that the server uses to identify +itself +ServerName fully-qualified-domain-name[:port] +server configvirtual host + +In version 2.0, this + directive supersedes the functionality of the Port + directive from version 1.3. + + +

    The ServerName directive sets the hostname and + port that the server uses to identify itself. This is used when + creating redirection URLs. For example, if the name of the + machine hosting the web server is simple.example.com, + but the machine also has the DNS alias www.example.com + and you wish the web server to be so identified, the following + directive should be used:

    + + + ServerName www.example.com:80 + + +

    If no ServerName is specified, then the + server attempts to deduce the hostname by performing a reverse + lookup on the IP address. If no port is specified in the + ServerName, then the server will use the port + from the incoming + request. For optimal reliability and predictability, you should + specify an explicit hostname and port using the + ServerName directive.

    + +

    If you are using name-based virtual hosts, + the ServerName inside a + VirtualHost + section specifies what hostname must appear in the request's + Host: header to match this virtual host.

    + +

    See the description of the + UseCanonicalName directive for + settings which determine whether self-referential URL's (e.g., by the + mod_dir module) will refer to the + specified port, or to the port number given in the client's request. +

    +
    + +Issues Regarding DNS and + Apache +Apache virtual host + documentation +UseCanonicalName +NameVirtualHost +ServerAlias +
    + + +ServerPath +Legacy URL pathname for a name-based virtual host that +is accessed by an incompatible browser +ServerPath URL-path +virtual host + + +

    The ServerPath directive sets the legacy + URL pathname for a host, for use with name-based virtual hosts.

    +
    +Apache Virtual Host documentation +
    + + +ServerRoot +Base directory for the server installation +ServerRoot directory-path +ServerRoot /usr/local/apache +server config + + +

    The ServerRoot directive sets the + directory in which the server lives. Typically it will contain the + subdirectories conf/ and logs/. Relative + paths in other configuration directives (such as Include or LoadModule, for example) are taken as + relative to this directory.

    + + Example + ServerRoot /home/httpd + + +
    +the -d + option to httpd +the + security tips for information on how to properly set + permissions on the ServerRoot +
    + + +ServerSignature +Configures the footer on server-generated documents +ServerSignature On|Off|EMail +ServerSignature Off +server configvirtual host +directory.htaccess + +All + + +

    The ServerSignature directive allows the + configuration of a trailing footer line under server-generated + documents (error messages, mod_proxy ftp directory + listings, mod_info output, ...). The reason why you + would want to enable such a footer line is that in a chain of proxies, + the user often has no possibility to tell which of the chained servers + actually produced a returned error message.

    + +

    The Off + setting, which is the default, suppresses the footer line (and is + therefore compatible with the behavior of Apache-1.2 and + below). The On setting simply adds a line with the + server version number and ServerName of the serving virtual host, + and the EMail setting additionally creates a + "mailto:" reference to the ServerAdmin of the referenced + document.

    + +

    After version 2.0.44, the details of the server version number + presented are controlled by the ServerTokens directive.

    +
    +ServerTokens +
    + + +ServerTokens +Configures the Server HTTP response +header +ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full +ServerTokens Full +server config + + +

    This directive controls whether Server response + header field which is sent back to clients includes a + description of the generic OS-type of the server as well as + information about compiled-in modules.

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    Server sends (e.g.): Server: + Apache
    + +
    ServerTokens Major
    + +
    Server sends (e.g.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Server sends (e.g.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    Server sends (e.g.): Server: + Apache/2.0.41
    + +
    ServerTokens OS
    + +
    Server sends (e.g.): Server: Apache/2.0.41 + (Unix)
    + +
    ServerTokens Full (or not specified)
    + +
    Server sends (e.g.): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2
    +
    + +

    This setting applies to the entire server, and cannot be + enabled or disabled on a virtualhost-by-virtualhost basis.

    + +

    After version 2.0.44, this directive also controls the + information presented by the ServerSignature directive.

    +
    +ServerSignature +
    + + +SetHandler +Forces all matching files to be processed by a +handler +SetHandler handler-name|None +server configvirtual host +directory.htaccess + +FileInfo +Moved into the core in Apache 2.0 + + +

    When placed into an .htaccess file or a + Directory or + Location + section, this directive forces all matching files to be parsed + through the handler given by + handler-name. For example, if you had a directory you + wanted to be parsed entirely as imagemap rule files, regardless + of extension, you might put the following into an + .htaccess file in that directory:

    + + + SetHandler imap-file + + +

    Another example: if you wanted to have the server display a + status report whenever a URL of + http://servername/status was called, you might put + the following into httpd.conf:

    + + + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +
    + +

    You can override an earlier defined SetHandler + directive by using the value None.

    +
    + +AddHandler + +
    + + +SetInputFilter +Sets the filters that will process client requests and POST +input +SetInputFilter filter[;filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    The SetInputFilter directive sets the + filter or filters which will process client requests and POST + input when they are received by the server. This is in addition to + any filters defined elsewhere, including the + AddInputFilter + directive.

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content.

    +
    +Filters documentation +
    + + +SetOutputFilter +Sets the filters that will process responses from the +server +SetOutputFilter filter[;filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    The SetOutputFilter directive sets the filters + which will process responses from the server before they are + sent to the client. This is in addition to any filters defined + elsewhere, including the + AddOutputFilter + directive.

    + +

    For example, the following configuration will process all files + in the /www/data/ directory for server-side + includes.

    + + + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +
    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content.

    +
    +Filters documentation +
    + + +TimeOut +Amount of time the server will wait for +certain events before failing a request +TimeOut seconds +TimeOut 300 +server config + + +

    The TimeOut directive currently defines + the amount of time Apache will wait for three things:

    + +
      +
    1. The total amount of time it takes to receive a GET + request.
    2. + +
    3. The amount of time between receipt of TCP packets on a + POST or PUT request.
    4. + +
    5. The amount of time between ACKs on transmissions of TCP + packets in responses.
    6. +
    + +

    We plan on making these separately configurable at some point + down the road. The timer used to default to 1200 before 1.2, + but has been lowered to 300 which is still far more than + necessary in most situations. It is not set any lower by + default because there may still be odd places in the code where + the timer is not reset when a packet is sent.

    +
    +
    + + +UseCanonicalName +Configures how the server determines its own name and +port +UseCanonicalName On|Off|DNS +UseCanonicalName Off +server configvirtual host +directory + + +

    In many situations Apache must construct a self-referential + URL -- that is, a URL that refers back to the same server. With + UseCanonicalName On Apache will use the hostname and port + specified in the ServerName + directive to construct the canonical name for the server. This name + is used in all self-referential URLs, and for the values of + SERVER_NAME and SERVER_PORT in CGIs.

    + +

    With UseCanonicalName Off Apache will form + self-referential URLs using the hostname and port supplied by + the client if any are supplied (otherwise it will use the + canonical name, as defined above). These values are the same + that are used to implement name based virtual hosts, + and are available with the same clients. The CGI variables + SERVER_NAME and SERVER_PORT will be + constructed from the client supplied values as well.

    + +

    An example where this may be useful is on an intranet server + where you have users connecting to the machine using short + names such as www. You'll notice that if the users + type a shortname, and a URL which is a directory, such as + http://www/splat, without the trailing + slash then Apache will redirect them to + http://www.domain.com/splat/. If you have + authentication enabled, this will cause the user to have to + authenticate twice (once for www and once again + for www.domain.com -- see the + FAQ on this subject for more information). But if + UseCanonicalName is set Off, then + Apache will redirect to http://www/splat/.

    + +

    There is a third option, UseCanonicalName DNS, + which is intended for use with mass IP-based virtual hosting to + support ancient clients that do not provide a + Host: header. With this option Apache does a + reverse DNS lookup on the server IP address that the client + connected to in order to work out self-referential URLs.

    + + Warning +

    If CGIs make assumptions about the values of SERVER_NAME + they may be broken by this option. The client is essentially free + to give whatever value they want as a hostname. But if the CGI is + only using SERVER_NAME to construct self-referential URLs + then it should be just fine.

    +
    +
    +ServerName +Listen +
    + + +VirtualHost +Contains directives that apply only to a specific +hostname or IP address +<VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost> +server config + + +

    VirtualHost and + </VirtualHost> are used to enclose a group of + directives that will apply only to a particular virtual host. Any + directive that is allowed in a virtual host context may be + used. When the server receives a request for a document on a + particular virtual host, it uses the configuration directives + enclosed in the VirtualHost + section. Addr can be:

    + +
      +
    • The IP address of the virtual host;
    • + +
    • A fully qualified domain name for the IP address of the + virtual host;
    • + +
    • The character *, which is used only in combination with + NameVirtualHost * to match all IP addresses; or
    • + +
    • The string _default_, which is used only + with IP virtual hosting to catch unmatched IP addresses.
    • +
    + + Example + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +
    + + +

    IPv6 addresses must be specified in square brackets because + the optional port number could not be determined otherwise. An + IPv6 example is shown below:

    + + + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +
    + +

    Each Virtual Host must correspond to a different IP address, + different port number or a different host name for the server, + in the former case the server machine must be configured to + accept IP packets for multiple addresses. (If the machine does + not have multiple network interfaces, then this can be + accomplished with the ifconfig alias command -- if + your OS supports it).

    + + Note +

    The use of VirtualHost does + not affect what addresses Apache listens on. You + may need to ensure that Apache is listening on the correct addresses + using Listen.

    +
    + +

    When using IP-based virtual hosting, the special name + _default_ can be specified in + which case this virtual host will match any IP address that is + not explicitly listed in another virtual host. In the absence + of any _default_ virtual host the "main" server config, + consisting of all those definitions outside any VirtualHost + section, is used when no IP-match occurs. (But note that any IP + address that matches a NameVirtualHost directive will use neither + the "main" server config nor the _default_ virtual host. + See the name-based virtual hosting + documentation for further details.)

    + +

    You can specify a :port to change the port that is + matched. If unspecified then it defaults to the same port as the + most recent Listen + statement of the main server. You may also specify :* + to match all ports on that address. (This is recommended when used + with _default_.)

    + + Security +

    See the security tips + document for details on why your security could be compromised if the + directory where log files are stored is writable by anyone other + than the user that starts the server.

    +
    +
    +Apache Virtual Host documentation +Issues Regarding DNS and + Apache +Setting + which addresses and ports Apache uses +How <Directory>, <Location> + and <Files> sections work for an explanation of how these + different sections are combined when a request is received +
    + +
    diff --git a/trunk/docs/manual/mod/core.xml.de b/trunk/docs/manual/mod/core.xml.de new file mode 100644 index 0000000000..5c7835da0f --- /dev/null +++ b/trunk/docs/manual/mod/core.xml.de @@ -0,0 +1,3289 @@ + + + + + + + + + +core +Ständig verfügbare Kernfunktionen des Apache HTTP +Servers +Core + + +AcceptPathInfo +Ressourcen lassen angehängte Pfadangaben zu +AcceptPathInfo On|Off|Default +AcceptPathInfo Default +server config +virtual hostdirectory +.htaccess +FileInfo +Verfügbar ab Apache 2.0.30 + + +

    Die Direktive steuert, ob Anfragen akzeptiert oder + abgewiesen werden, bei denen nach der tatsächlichen + Datei (oder einer nicht existierenden Datei in einem existierenden + Verzeichnis) zusätzliche Pfadangaben folgen. Die angehängte + Pfadangabe kann Skripten in der Umgebungsvariable PATH_INFO + verfügbar gemacht werden.

    + +

    Nehmen wir beispielsweise an, dass /test/ auf ein + Verzeichnis zeigt, welches lediglich eine Datei here.html + enthält. Dann wird bei Anfragen nach + /test/here.html/more und + /test/nothere.html/more beides Mal /more + als PATH_INFO ermittelt.

    + +

    Die drei möglichen Argumente für die Direktive + AcceptPathInfo sind:

    + +
    +
    Off
    Eine Anfrage wird nur dann akzeptiert, + wenn sie exakt auf ein existierendes Verzeichnis (oder eine Datei) + abgebildet werden kann. Daher würde eine Anfrage mit einer nach dem + tatsächlichen Dateinamen angehängten Pfadangabe, wie + /test/here.html/more im obigen Beispiel, den Fehler + 404 NOT FOUND nicht gefunden + zurückgeben.
    + +
    On
    +
    Eine Anfrage wird akzeptiert, wenn eine vorangestellte Pfadangabe + auf ein existierendes Verzeichnis abgebildet werden kann. Das + obige Beispiel /test/here.html/more wird akzeptiert, + wenn /test/here.html auf eine gültige Datei + zeigt.
    + +
    Default
    +
    Die Behandlung von Anfragen mit angehängten Pfadangaben + wird von dem für die Anfrage verantwortlichen Handler bestimmt. Der Core-Handler + für gewöhnliche Dateien weist PATH_INFO-Zugriffe + standardmäßig zurück. Handler, die Skripte bedienen, + wie z.B. cgi-script und + isapi-isa, sind im Allgemeinen darauf + voreingestellt, PATH_INFO zu akzeptieren.
    +
    + +

    Das eigentliche Ziel von AcceptPathInfo ist es, Ihnen + das Überschreiben der Voreinstellung der Handler bezüglich + der Akzeptanz oder Ablehnung von PATH_INFO zu erlauben. + Eine solche Änderung ist zum Beispiel notwendig, wenn Sie einen + Filter wie INCLUDES verwenden, um Inhalte + abhängig von PATH_INFO zu generieren. Der + Core-Handler würde die Anfrage normalerweise abweisen. Verwenden + Sie die folgende Konfiguration, um dennoch solch ein Skript zu + ermöglichen.

    + + + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +
    + +
    +
    + + +AccessFileName +Name der dezentralen Konfigurationsdateien +AccessFileName Dateiname [Dateiname] ... +AccessFileName .htaccess +server configvirtual host + + + +

    Aus dieser Namensliste sucht der Server während der + Bearbeitung einer Anfrage in jedem Verzeichnis nach der ersten + existierenden Datei, sofern im betreffenden Verzeichnis dezentrale + Konfigurationsdateien erlaubt sind. + Beispiel:

    + + + AccessFileName .acl + + +

    Vor der Rücksendung des Dokuments + /usr/local/web/index.html wird der Server + /.acl, /usr/.acl, + /usr/local/.acl und /usr/local/web/.acl + einlesen, solange diese nicht mit

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory> +
    + +

    deaktiviert wurden.

    +
    +AllowOverride +Konfigurationsdateien +.htaccess-Dateien +
    + + +AddDefaultCharset +Standard-Charset-Parameter, der bei Antworten vom Content-Type + text/plain oder text/html hinzugefügt wird + +AddDefaultCharset On|Off|Zeichenkodierung +AddDefaultCharset Off +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    Die Direktive gibt einen Standardwert für den Charset-Paramter des + Medientyps (den Namen einer Zeichencodierung) an, der einer Antwort + genau dann hinzugefügt wird, wenn der Content-Type der Antwort entweder + text/plain oder text/html ist. Dies sollte jedes + mittels META-Element im Datenteil der Antwort angegebene + Charset überschreiben. Das genaue Verhalten hängt jedoch oft von + der Client-Konfiguration des Benutzers ab. Die Einstellung + AddDefaultCharset Off deaktiviert diese Funktionalität. + AddDefaultCharset On aktiviert die Standard-Zeichenkodierung + iso-8859-1. Jeder andere Wert wird als die zu verwendende + Zeichenkodierung aufgefaßt, die eines der bei IANA registrierten + Charset-Werte zur Verwendung in MIME-Medientypen sein sollte. Zum + Beispiel:

    + + + AddDefaultCharset utf-8 + + +

    AddDefaultCharset sollte nur verwendet werden, + wenn von allen Textressourcen, für die es gilt, bekannt ist, dass sie + in dieser Zeichkodierung vorliegen, oder wenn es zu unbequem ist, ihre + Zeichenkodierung indivuell zu benennen. Ein solches Beispiel ist das + Hinzufügen des Charset-Parameters zu Ressourcen, die generierte + Inhalte enthalten. Ein Beispiel sind CGI-Skript-Altlasten, die aufgrund von + in die Ausgabe integrierten Daten, die durch den Benutzer übermittelt + wurden, gegen Cross-Site-Scripting-Angriffe verwundbar sind. Eine bessere + Lösung wäre jedoch, diese Skripte zu korrigieren (oder zu + löschen), da die Angabe einer Standard-Zeichencodierung keine + Anwender schützt, die in ihrem Browser die Funktion zur + automatischen Erkennung der Zeichenkodierung aktiviert haben.

    +
    +AddCharset +
    + + +AddOutputFilterByType +einen Ausgabefilter einem bestimmten MIME-Type +zuordnen +AddOutputFilterByType Filter[;Filter...] +MIME-Type [MIME-Type] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Verfügbar ab Apache 2.0.33 + + +

    Die Direktive aktiviert für eine Anfrage abhängig vom + MIME-Type der Antwort einen bestimmten Ausgabe-Filter.

    + +

    Das folgende Beispiel verwendet den Filter DEFLATE, + der von mod_deflate angeboten wird. Er komprimiert + jede Ausgabe, die als text/html oder text/plain + gekennzeichnet ist, (gleichgültig, ob statisch oder dynamisch) + bevor sie an den Client gesendet wird.

    + + + AddOutputFilterByType DEFLATE text/html text/plain + + +

    Wenn Sie den Inhalt von mehr als einem Filter verarbeiten lassen + wollen, dann müssen deren Namen durch Semikolons voneinander + getrennt werden. Es ist ebenfalls möglich, eine + AddOutputFilterByType-Direktive für + jeden von diesen Filtern zu verwenden.

    + +

    Die folgende Konfiguration sorgt dafür, dass alle + Skriptausgaben, die als text/html gekennzeichnet + sind, zuerst vom INCLUDES-Filter und dann vom + DEFLATE-Filter verarbeitet werden.

    + + + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +
    + + Hinweis: +

    Die Aktivierung von Filtern mittels + AddOutputFilterByType kann in einigen + Fällen ganz oder teilweise fehlschlagen. Beispielsweise + werden keine Filter angewendet, wenn der MIME-Type nicht bestimmt + werden kann und auf die Einstellung der DefaultType-Anweisung zurückfällt, + selbst wenn die DefaultType-Einstellung die gleiche ist.

    + +

    Wenn Sie jedoch sicherstellen wollen, dass der Filter + angewendet wird, sollten Sie den Content-Type z.B. mit + AddType oder + ForceType der Ressource + explizit zuordnen. Das Setzen des Content-Types innerhalb + eines (nicht-nph) CGI-Skriptes funktioniert ebenfalls + zuverlässig.

    + +

    Die Typ-gebundenen Ausgabefilter werden niemals auf + Proxy-Anfragen angewendet.

    +
    +
    + +AddOutputFilter +SetOutputFilter +Filter +
    + + +AllowEncodedSlashes +Legt fest, ob kodierte Pfadtrennzeichen in URLs durchgereicht +werden dürfen +AllowEncodedSlashes On|Off +AllowEncodedSlashes Off +server configvirtual host + +Verfügbar ab Apache 2.0.46 + + +

    Die AllowEncodedSlashes-Direktive erlaubt die + Verwendung von URLs, welche kodierte Pfadtrennzeichen (%2F + für / und auf entsprechenden Systemen zusätzlich + %5C für \) enthalten. Normalerweise werden + derartige URLs mit einem 404-Fehler (Nicht gefunden) abgewiesen.

    + +

    AllowEncodedSlashes On ist + vor allem in Verbindung mit PATH_INFO hilfreich.

    + + Anmerkung +

    Das Erlauben von Schrägstrichen impliziert nicht deren + Dekodierung. Vorkommen von %2F oder %5C + (nur auf entsprechenden Systemen) werden unverändert in der + ansonsten dekodierten URL belassen.

    +
    +
    +AcceptPathInfo +
    + + +AllowOverride +Direktiven-Typen, die in .htaccess-Dateien +erlaubt sind. +AllowOverride All|None|Direktiven-Typ +[Direktiven-Typ] ... +AllowOverride All +directory + + +

    Wenn der Server eine .htaccess-Datei (wie durch + AccessFileName definiert) + findet, muss er wissen, welche in der Datei angegebenen Direktiven + frühere Konfigurationsanweisungen überschreiben + dürfen.

    + + Nur in <Directory>-Abschnitten verfügbar + AllowOverride ist nur in Directory-Abschnitten + gültig, die ohne reguläre Ausdrücke definiert wurden, nicht + in Location-, + DirectoryMatch- oder + Files-Abschnitten. + + +

    Wenn diese Anweisung auf None gesetzt wird, dann + werden .htaccess-Dateien komplett + ignoriert. In diesem Fall wird der Server nicht einmal versuchen, + die .htaccess-Dateien im Dateisystem zu lesen.

    + +

    Wenn diese Anweisung auf All gesetzt wird, dann + ist jede Direktive in den .htaccess-Dateien erlaubt, + die den Kontext + .htaccess besitzt.

    + +

    Der Direktiven-Typ kann eine der folgenden + Anweisungsgruppen sein.

    + +
    +
    AuthConfig
    + +
    + Erlaubt die Verwendung von Autorisierungs-Anweisungen (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require usw.).
    + +
    FileInfo
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung der + Dokumenttypen (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, und + mod_mime-Direktiven Add* und Remove* + usw.).
    + +
    Indexes
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung von + Verzeichnisindizes (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName + usw.).
    + +
    Limit
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung des + Zugriffs von Hosts (Allow, Deny und Order).
    + +
    Options[=Option,...]
    + +
    + Erlaubt die Verwendung von Direktiven zur Steuerung spezieller + Verzeichniseigenschaften (Options + und XBitHack). Sie + können mit einem Gleichheitszeichen gefolgt von einer + kommaseparierten Liste (ohne Leerzeichen) angeben, welche Optionen mit + der Options-Direktive gesetzt + werden dürfen.
    +
    + +

    Beispiel:

    + + + AllowOverride AuthConfig Indexes + + +

    Im obigen Beispiel erzeugen alle Direktiven einen internal server + error Server-interner Fehler, die weder der + Gruppe AuthConfig noch der Gruppe Indexes + angehören.

    +
    + +AccessFileName +Konfigurationsdateien +.htaccess-Dateien +
    + + +AuthName +Autorisierungsbereich zur Verwendung in der +HTTP-Authentisierung +AuthName auth-Bereich +directory.htaccess + +AuthConfig + + +

    Die Direktive legt den Namen des Autorisierungsbereiches + Der Autorisierungsbereich wird auch Realm genannt. + für ein Verzeichnis fest. Dieser Realm wird dem Client mitgeteilt, + damit der Anwender weiß, welchen Benutzernamen und welches Passwort + er zu übermitteln hat. AuthName akzeptiert ein + Argument. Falls der Name des Realm Leerzeichen enthält, muss er in + Anführungszeichen eingeschlossen werden. Um zu funktionieren, muss + die Anweisung von den Direktiven AuthType und Require sowie von + Direktiven wie AuthUserFile + und AuthGroupFile + begleitet werden.

    + +

    Beispiel:

    + + + AuthName "Top Secret" + + +

    Die AuthName übergebene Zeichenkette ist das, + was in dem von den meisten Browsern angebotenen Passwort-Dialog + angezeigt wird.

    +
    +Authentisierung, Autorisierung und + Zugriffskontrolle +
    + + +AuthType +Art der Authentisierung +AuthType Basic|Digest +directory.htaccess + +AuthConfig + + +

    Die Direktive wählt die Art der Benutzer-Authentisierung + für ein Verzeichnis aus. Derzeit sind lediglich Basic + und Digest implementiert. + Um zu funktionieren, muss die Anweisung von den Direktiven AuthName und Require sowie von + Direktiven wie AuthUserFile + und AuthGroupFile + begleitet werden.

    +
    +Authentisierung, Autorisierung und + Zugriffskontrolle +
    + + +CGIMapExtension +Technik zur Bestimmung des Interpreters für +CGI-Skripte +CGIMapExtension CGI-Pfad .Endung +directory.htaccess + +FileInfo +ausschließlich NetWare + + +

    Die Direktive wird zur Steuerung verwendet, wie Apache + den Interpreter ermittelt, der zur Ausführung von + CGI-Skripten verwendet wird. Beispielsweise bestimmt die Angabe + von CGIMapExtension sys:\foo.nlm .foo, dass + alle CGI-Scripte mit der Endung .foo an den + FOO-Interpreter übergeben werden.

    +
    +
    + + +ContentDigest +Aktiviert die Generierung von Content-MD5 +HTTP-Response-Headern +ContentDigest On|Off +ContentDigest Off +server configvirtual host +directory.htaccess + +Options +Experimental + + +

    Die Direktive aktiviert die Generierung von + Content-MD5-Headern, wie sie in RFC1864 bzw. RFC2068 + definiert sind.

    + +

    MD5 ist ein Algorithmus zur Berechnung eines "Datenextrakts" + (zuweilen "Fingerabdruck" genannt) Der "Datenextrakt" wird im + Englischen als "message digest" oder "fingerprint" bezeichnet. + aus beliebig langen Daten. Es gilt als zuverlässig, dass + Veränderungen an den Daten sich in Veränderungen des + Extrakts wiederspiegeln.

    + +

    Der Content-MD5-Header bietet eine + End-to-End-Integritätsprüfung (MIC) MIC steht für + "message integrity check". des Daten-Inhalts. Ein Proxy oder + Client kann diesen Header prüfen, um zufällige Veränderungen + des Entity-Inhalts bei der Übertragung festzustellen. + Beispielheader:

    + + + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== + + +

    Beachten Sie bitte, dass dies Performanceprobleme auf Ihrem + System verursachen kann, da der Extrakt bei jeder Anfrage + berechnet wird (der Wert wird nicht zwischengespeichert).

    + +

    Content-MD5 wird nur für Dokumente gesendet, + die von core bedient werden, nicht jedoch bei + Modulen. SSI-Dokumente, CGI-Skript-Ausgaben und Byte-Range-Antworten + besitzen diesen Header beispielsweise nicht.

    +
    +
    + + +DefaultType +MIME-Content-Type, der gesendet wird, wenn der Server den Typ +nicht auf andere Weise ermitteln kann. +DefaultType MIME-Type +DefaultType text/plain +server configvirtual host +directory.htaccess + +FileInfo + + +

    Es kann vorkommen, dass der Server ein Dokument ausliefern muss, + dessen Typ er nicht mit Hilfe seiner MIME-Type-Zuordnungen bestimmen + kann.

    + +

    Der Server muss den Client über den Content-Type des + Dokumentes informieren. Daher verwendet er im Falle eines + unbekannten Typs die DefaultType-Einstellung. + Zum Beispiel:

    + + + DefaultType image/gif + + +

    wäre angemessen für ein Verzeichnis, das viele GIF-Bilder + enthält, deren Dateinamen nicht Endung .gif + besitzen.

    + +

    Beachten Sie bitte, dass die Direktive anders als ForceType lediglich den Standard-MIME-Type + bestimmt. Alle anderen MIME-Type-Definitionen, einschließlich + Dateierweiterungen, die den Medien-Typ anzeigen können, + überschreiben diese Voreinstellung.

    +
    +
    + + +Directory +Umschließt eine Gruppe von Direktiven, die nur auf +das genannte Verzeichnis des Dateisystems und Unterverzeichnisse angewendet +werden +<Directory Verzeichnispfad> +... </Directory> +server configvirtual host + + + +

    Directory und + </Directory> werden dazu verwendet, eine Gruppe + von Direktiven zusammenzufassen, die nur für das genannte + Verzeichnis und dessen Unterverzeichnisse gelten. Jede Direktive, + die im Verzeichnis-Kontext erlaubt ist, kann verwendet werden. + Verzeichnispfad ist entweder der vollständige Pfad zu + einem Verzeichnis oder eine Zeichenkette mit Platzhaltern wie sie von der + Unix-Shell zum Abgleich verwendet werden. In einer Zeichenkette + mit Platzhaltern sogenannte wild-cards entspricht + ? einem einzelnen Zeichen und * einer + Zeichenkette beliebiger Länge. Sie können auch auch + []-Zeichenbereiche verwenden. Keiner der Platzhalter + entspricht dem Zeichen "/". Daher passt <Directory + /*/public_html> nicht auf /home/user/public_html, + <Directory /home/*/public_html> jedoch tut es. + Beispiel:

    + + + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +
    + + +

    Seien Sie vorsichtig mit den Verzeichnispfad-Argumenten. + Sie müssen buchstäblich mit dem Dateisystempfad + übereinstimmen, den der Apache für den Zugriff auf die + Dateien verwendet. Direktiven, die für ein bestimmtes + Verzeichnis gelten, gelten nicht für Dateien in dem Verzeichnis, + auf die über einen anderen Pfad zugegriffen wird, wie z.B. + über verschiedene symbolische Links.

    +
    + +

    Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt + wird. Beispielsweise würde

    + + + <Directory ~ "^/www/.*/[0-9]{3}"> + + +

    auf Verzeichnisse in /www/ passen, die aus drei + Zahlen bestehen.

    + +

    Wenn mehrere Directory-Abschnitte + (ohne reguläre Ausdrücke) auf ein Verzeichnis (oder + ein ihm übergeordnetes Verzeichnis) passen, welches ein Dokument + enthält, dann werden die Direktiven der Reihe nach, angefangen + beim kürzesten passenden Muster, vermischt mit den Direktiven + aus den .htaccess-Dateien, angewendet. + Beispiel:

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +
    + +

    Beim Zugriff auf das Dokument /home/web/dir/doc.html + sind die einzelnen Schritte:

    + +
      +
    • Wende die Direktive AllowOverride None an + (deaktiviere .htaccess-Dateien).
    • + +
    • Wende die Direktive AllowOverride FileInfo + (auf das Verzeichnis /home) an.
    • + +
    • Wende jede FileInfo-Direktive aus + /home/.htaccess, /home/web/.htaccess und + /home/web/dir/.htaccess der Reihe nach an.
    • +
    + +

    Reguläre Ausdrücke werden solange nicht berücksichtigt, + bis alle normalen Abschnitte angewendet wurden. Anschließend + werden alle regulären Ausdrücke in der Reihenfolge + geprüft, in der sie in der Konfigurationsdatei auftauchen. + Beispielsweise wird bei

    + + + <Directory ~ abc$>
    + + # ... hier die Direktiven ...
    +
    + </Directory> +
    + +

    der Abschnitt mit dem regulären Ausdruck nicht + berücksichtigt, bis alle normalen + Directory-Abschnitte und + .htaccess-Dateien angewendet wurden. Dann erst wird + der reguläre Ausdruck mit /home/abc/public_html/abc + abgeglichen und der entsprechende Directory-Abschnitt angewendet.

    + +

    Beachten Sie bitte, dass der vom Apache voreingestellte + Zugriff für <Directory /> + Allow from All ist. Das bedeutet, dass der Apache + jede Datei ausliefert, die durch eine URL abgebildet wird. Es wird + empfohlen, dass Sie dies durch einen Block wie

    + + + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +
    + +

    ändern und anschließend für + Verzeichnisse überschreiben, die Sie verfügbar machen + wollen. Für weitere Einzelheiten lesen Sie bitte + die Seite zu den Sicherheitshinweisen.

    + +

    Die Verzeichnisabschnitte erscheinen in der Datei + httpd.conf. Directory-Direktiven dürfen nicht + ineinander verschachtelt werden oder innerhalb von Limit- oder LimitExcept-Abschnitten auftauchen.

    +
    +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +DirectoryMatch +Umschließt eine Gruppe von Direktiven, die auf + Verzeichnisse des Dateisystems und ihre Unterverzeichnisse abgebildet + werden, welche auf einen regulären Ausdruck passen +<DirectoryMatch regex> +... </DirectoryMatch> +server configvirtual host + + + +

    DirectoryMatch und + </DirectoryMatch> werden dazu verwendet, eine + Gruppe von Direktiven zusammenzufassen, die nur für das + genannte Verzeichnis und dessen Unterverzeichnisse gelten, genauso + wie bei Directory. + Als Argument dient jedoch ein regulärer Ausdruck. + Beispielsweise würde

    + + + <DirectoryMatch "^/www/.*/[0-9]{3}"> + + +

    auf Verzeichnisse in /www/ passen, die aus drei + Zeichen bestehen.

    +
    +Directory + für eine Beschreibung, wie reguläre Ausdrücke mit + normalen Directory-Anweisungen + vermischt werden. +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +DocumentRoot +Verzeichnis, welches den Haupt-Dokumentenbaum bildet, der im +Web sichtbar ist. +DocumentRoot Verzeichnis +DocumentRoot /usr/local/apache/htdocs +server configvirtual host + + + +

    Die Direktive setzt das Verzeichnis, von dem aus + httpd Dateien ausliefert. Sofern nicht eine Direktive + wie Alias greift, hängt + der Server Pfade aus der angeforderten URL an das Wurzelverzeichnis + an, um den Pfad zum Dokument zu bilden. Beispiel:

    + + + DocumentRoot /usr/web + + +

    Damit bezieht sich ein Zugriff auf + http://www.my.host.com/index.html auf + /usr/web/index.html. Wenn das Verzeichnis nicht + absolut angegeben ist, wird es relativ zu ServerRoot betrachtet.

    + +

    DocumentRoot sollte ohne einen + Schrägstrich am Ende angegeben werden.

    +
    +URLs auf das Dateisystem +abbilden +
    + + +EnableMMAP +Verwende Memory-Mapping, um Dateien während der +Auslieferung zu lesen +EnableMMAP On|Off +EnableMMAP On +server configvirtual host +directory.htaccess + +FileInfo + + +

    Die Direktive steuert, ob httpd Memory-Mapping + verwenden darf, wenn er während der Auslieferung den Inhalt einer + Datei lesen muss. Wenn die Bearbeitung einer Anfrage es erfordert, + auf die Daten in einer Datei zuzugreifen -- zum Beispiel bei der + Auslieferung einer mittels mod_include serverseitig + analysierten Datei --, dann verwendet der Apache standardmäßig + Memory-Mapping für diese Datei, sofern das Betriebssystem es + unterstützt.

    + +

    Memory-Mapping bedeutet zuweilen eine Performanceverbesserung. + In einigen Umgebungen ist es jedoch besser, Memory-Mapping zu + deaktivieren, um Problemen während des Betriebs vorzubeugen:

    + +
      +
    • Bei einigen Multiprozessorsystemen kann Memory-Mapping die + Performance von httpd reduzieren.
    • +
    • Bei einem per NFS eingebundenen DocumentRoot kann httpd mit + einem Speicherzugriffsfehler ein so genannter "segmentation + fault" abstürzen, wenn eine Datei gelöscht oder + gekürzt wird, während httpd sie im Speicher + abbildet.
    • +
    + +

    Bei Serverkonfigurationen, die für dieses Problem + anfällig sind, sollten Sie das Memory-Mapping für + auszuliefernde Dateien deaktivieren, indem Sie schreiben:

    + + + EnableMMAP Off + + +

    Bei per NFS eingebundenen Dateien kann diese Funktion + explizit für die störenden Dateien deaktiviert werden, + indem Sie angeben:

    + + + <Directory "/pfad-zu-den-nfs-dateien"> + + EnableMMAP Off + + </Directory> + +
    +
    + + +EnableSendfile +Verwende die sendfile-Unterstützung des Kernels, um +Dateien an den Client auszuliefern +EnableSendfile On|Off +EnableSendfile On +server configvirtual host +directory.htaccess + +FileInfo +Verfügbar ab Apache Version 2.0.44 + + +

    Die Direktive steuert, ob httpd die + sendfile-Unterstützung des Kernels verwenden kann, um + Dateiinhalte an den Client zu übermitteln. Wenn die Bearbeitung + einer Anfrage keinen Zugriff auf die Daten in der Datei erfordert -- + zum Beispiel bei der Auslieferung einer statischen Datei -- und das + Betriebssystem es unterstützt, verwendet der Apache + standardmäßig sendfile, um den Dateiinhalt zu + übertragen, ohne die Datei jemals zu lesen.

    + +

    Der sendfile-Mechanismus vermeidet getrennte Lese- und + Sendeoperationen sowie Puffer-Zuweisungen. Bei einigen Plattformen bzw. + Dateisystemen deaktivieren Sie diese Funktion jedoch besser, um Probleme + während des Betriebs zu vermeiden:

    + +
      +
    • Einige Plattformen besitzen u.U. eine fehlerhafte + sendfile-Unterstützung, die das Erstellungssystem nicht erkennt, + insbesondere wenn die Binärdateien auf einem anderen Rechner erstellt + und auf eine solche Maschine mit fehlerhafter sendfile-Unterstützung + übertragen wurden.
    • +
    • Bei einem über das Netzwerk eingebundenen DocumentRoot (z.B. NFS oder SMB) ist der + Kernel möglicherweise nicht in der Lage, die Netzwerkdatei + über seinen eigenen Cache zu bedienen.
    • +
    • Unter Linux löst die Verwendung von sendfile + in Verbindung mit bestimmten Netzwerkkarten und IPv6 + TCP-Checksummenfehler aus.
    • +
    + +

    Bei Serverkonfigurationen, die für dieses Problam + anfällig sind, sollten die diese Funktion deaktivieren, indem + Sie schreiben:

    + + + EnableSendfile Off + + +

    Bei per NFS oder SMB eingebundenen Dateien kann diese Funktion + explizit für die störenden Dateien deaktiviert werden, indem + Sie angeben:

    + + + <Directory "/pfad-zu-den-nfs-dateien"> + + EnableSendfile Off + + </Directory> + +
    +
    + + +ErrorDocument +Das, was der Server im Fehlerfall an den Client +zurückgibt +ErrorDocument Fehlercode Dokument +server configvirtual host +directory.htaccess + +FileInfo +Die Syntax der Anführungszeichen bei Textnachrichten hat +sich im Apache 2.0 geändert + + +

    Im Falle eines Problems oder Fehlers kann der Apache + konfiguriert werden, eine der vier Aktionen auszuführen:

    + +
      +
    1. Ausgabe einer einfachen, hartkodierten Fehlermeldung
    2. + +
    3. Ausgabe einer angepassten Meldung
    4. + +
    5. Umleitung zu einem lokalen URL-Pfad der das + Problem bzw. den Fehler behandelt
    6. + +
    7. Umleitung zu einer externen URL, die das Problem + bzw. den Fehler behandelt
    8. +
    + +

    Die erste Option ist Voreinstellung, während die Optionen + 2 bis 4 über die Direktive ErrorDocument + eingestellt werden, welcher der HTTP-Statuscode und eine + URL oder Nachricht folgen. Abhängig vom Problem bzw. Fehler bietet + der Apache manchmal zusätzliche Informationen an.

    + +

    URLs können bei lokalen Adressen mit einem Schrägstrich + (/) beginnen oder eine komplette URL bilden, die der Client + auflösen kann. Alternativ kann eine Nachricht für die + Anzeige im Browser angeboten werden. Beispiel:

    + + + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/falsche_urls.pl
    + ErrorDocument 401 /info_zur_anmeldung.html
    + ErrorDocument 403 "Der Zugriff ist nicht erlaubt." +
    + +

    Außerdem kann der spezielle Wert default angegeben + werden, um die schlichte, hartkodierte Nachricht des Apache zu verwenden. + Es wird normalerweise nicht benötigt, doch default + stellt die einfach, im Apache hartkodierte Meldung in Konfigurationen + wieder her, die ansonsten von einem existierenden zuvor + konfigurierten ErrorDocument erben + würden.

    + + + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +
    + +

    Wenn Sie eine ErrorDocument-Anweisung + angeben, die auf eine entfernte URL weist (d.h. irgendetwas mit der + Methode http davor), beachten Sie bitte, dass der Apache + eine Umleitung zum Client sendet, um diesem mitzuteilen, wo das + Dokument zu finden ist, auch wenn das Dokument letztlich wieder zum + gleichen Server führt. Das hat mehrere Auswirkungen. Die + wichtigste ist, dass der Client nicht den Original-Statuscode + erhält sondern statt dessen einen Umleitungs-Statuscode. Dies + wiederum kann Web-Robots und andere Clients verwirren, die den + Statuscode dazu verwenden, herauszufinden ob eine URL gültig ist. + Wenn Sie eine entfernte URL in einer Anweisung + ErrorDocument 401 verwenden, wird der Client + darüber hinaus nicht wissen, dass er den Benutzer zur Eingabe + eines Passwortes auffordern muss, da er den Statuscode 401 nicht + erhält. Deshalb müssen Sie sich auf ein lokales + Dokument beziehen, wenn Sie eine Anweisung ErrorDocument + 401 verwenden.

    + +

    Der Microsoft Internet Explorer (MSIE) ignoriert + standardmäßig serverseitig generierte Fehlermeldungen, wenn + sie "zu kurz" sind und ersetzt sie durch eigene "freundliche" + Fehlermeldungen. Die Größe variiert abhängig von der + Art des Fehlers, im Allgemeinen zeigt der MSIE jedoch den + serverseitig generierten Fehler, anstatt ihn zu verstecken, wenn Ihr + Fehlerdokument größer als 512 Bytes ist. Weitere Informationen + sind im Artikel Q294807 in der Microsoft Knowledgebase article verfügbar.

    + +

    In Versionen vor 2.0 wurden Meldungen durch ein einzelnes + vorangestelltes Anführungszeichen (") erkannt.

    +
    + +Dokumentation zu individuellen +Fehlermeldungen +
    + + +ErrorLog +Ablageort, an dem der Server Fehler protokolliert + ErrorLog Dateiname|syslog[:facility] +ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and + OS/2) +server configvirtual host + + + +

    Die Direktive ErrorLog bestimmt den Namen + der Datei, in welcher der Server alle auftretenden Fehler protokolliert. + Wenn Dateiname nicht absolut ist, wird er relativ zu ServerRoot betrachtet.

    + + Beispiel + ErrorLog /var/log/httpd/error_log + + +

    Wenn der Dateiname mit einem senkrechten Strich (|, + engl.: Pipe) beginnt, wird angenommen, dass es sich um einen Befehl + handelt, der ausgeführt wird, um das Fehlerprotokolls zu + verarbeiten.

    + + Beispiel + ErrorLog "|/usr/local/bin/httpd_errors" + + +

    Die Verwendung von syslog anstelle eines Dateinamens + aktiviert die Protokollierung mittels syslogd(8), sofern das System + es unterstützt. Als Voreinstellung wird der syslog-Typ (syslog + facility) local7 verwendet, Sie können dies jedoch + auch überschreiben, indem Sie die Syntax + syslog:facility verwenden, wobei + facility einer der Namen sein kann, die üblicherweise + in syslog(1) dokumentiert sind.

    + + Beispiel + ErrorLog syslog:user + + +

    SICHERHEITSHINWEIS: Lesen Sie das Dokument Sicherheitshinweise + zu Einzelheiten darüber, warum Ihre Sicherheit gefährdet + sein kann, wenn das Verzeichnis, in dem die Log-Dateien gespeichert + werden, für jemand anderen, als den Benutzer, der den Server + gestartet hat, beschreibbar ist.

    + + Anmerkung +

    Bei der Eingabe eines Dateipfads auf nicht-Unix-Plattformen sollte + darauf geachtet werden, nur (Vorwärts-)Schrägstriche zu + verwenden, auch wenn die Plattform rückwärts gerichtete + Schrägstriche (Backslashes) erlaubt. Im Allgemeinen ist es eine gute + Idee, innerhalb der Konfigurationsdateien immer + Vorwärts-Schrägstriche zu verwenden.

    +
    +
    +LogLevel +Apache-Log-Dateien +
    + + +FileETag +Dateiattribute, die zur Erstellung des HTTP-Response-Headers +ETag verwendet werden +FileETag Komponente ... +FileETag INode MTime Size +server configvirtual host +directory.htaccess + +FileInfo + + +

    Wenn dem Dokument eine Datei zugrundeliegt, bestimmt die Direktive + FileETag die Dateiattribute, die zur Erstellung + des HTTP-Response-Headers ETag (Entity-Tag) verwendet + werden. (Der Wert von ETag wird bei der Cache-Verwaltung + zur Einsparung von Netzwerk-Bandbreite benutzt.) Im Apache 1.3.22 und + früher wurde der ETag-Wert stets aus + der I-Node, der Größe und dem Datum der letzten + Änderung (mtime) der Datei gebildet. Die Direktive + FileETag erlaubt es Ihnen, zu bestimmen, + welche dieser Eigenschaften -- falls überhaupt -- verwendet + werden sollen. Die gültigen Schlüsselworte lauten:

    + +
    +
    INode
    +
    Die I-Node-Nummer wird in die Berechnung mit einbezogen
    +
    MTime
    +
    Datum und Uhrzeit der letzten Änderung werden mit einbezogen
    +
    Size
    +
    Die Anzahl der Bytes in der Datei wird mit einbezogen
    +
    All
    +
    Alle verfügbaren Angaben werden verwendet. Die ist + gleichbedeutend mit: + FileETag INode MTime Size
    +
    None
    +
    Es wird keine ETag-Angabe in die Antwort eingefügt, + wenn dem Dokument eine Datei zugrundeliegt.
    +
    + +

    Den Schlüsselwörtern INode, MTime + und Size kann entweder ein + oder ein + - vorangestellt werden, was die Änderung einer + Vorgabe erlaubt, die von einem größeren Umfeld + geerbt wurde. Jedes Schlüselwort ohne ein solches Prefix + hebt die ererbte Einstellung sofort und vollständig auf.

    + +

    Wenn die Konfiguration für ein Verzeichnis + FileETag INode MTime Size enthält + und die eines Unterverzeichnisses FileETag -INode, + dann ist die Einstellung für das Unterverzeichnis (die an + jedes Unter-Unterverzeichnis weitervererbt wird, welches dies nicht + überschreibt) äquivalent mit + FileETag MTime Size.

    +
    +
    + + +Files +Enthält Direktiven, die sich nur auf passende Dateinamen +beziehen +<Files Dateiname> ... </Files> +server configvirtual host +directory.htaccess + +All + + +

    Die Direktive Files + begrenzt die Reichweite der enthaltenen Anweisungen auf Dateinamen. + Sie ist vergleichbar mit den Direktiven Directory und Location. Sie muss eine + passende </Files>-Anweisung besitzen. + Die innerhalb dieses Abschnittes angegebenen Direktiven werden auf + jedes Objekt mit einem Basisnamen (letzte Komponente des Dateinamens) + angewendet, der auf die angegebenen Dateinamen passt. Files-Container werden, nachdem die + Directory-Container + und .htaccess-Dateien gelesen sind, jedoch vor den + Location-Containern, + in der Reihenfolge ihres Auftretens ausgeführt. Beachten Sie, dass + Files-Anweisungen innerhalb von + Directory-Containern + auftreten können, um den Teil des Dateisystems einzuschränken, + den sie betreffen.

    + +

    Das Argument Dateiname kann einen Dateinamen oder eine + Zeichenkette mit Platzhaltern enthalten, wobei ? auf ein + einzelnes Zeichen passt und * auf eine beliebige Folge von + Zeichen. Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt wird. + Beispielsweise würde

    + + + <Files ~ "\.(gif|jpe?g|png)$"> + + +

    auf die gebräuchlichsten Grafikformate im Internet passen. + FilesMatch wird + jedoch bevorzugt.

    + +

    Beachten Sie bitte, dass die Files-Container anders als Directory- und Location-Container innerhalb + von .htaccess-Dateien verwendet werden können. + Dies erlaubt den Anwendern auf Dateiebene die Kontrolle über ihre + eigenen Dateien.

    +
    +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +FilesMatch +Enthält Direktiven, die für Dateinamen gelten, die + auf einen regulären Ausdruck passen +<FilesMatch regex> ... </FilesMatch> +server configvirtual host +directory.htaccess + +All + + +

    Die Direktive FilesMatch + begrenzt wie die Direktive Files die enthaltenen Anweisungen auf + Dateinamen. Sie akzeptiert jedoch reguläre Ausdrücke. + Beispielsweise würde

    + + + <FilesMatch "\.(gif|jpe?g|png)$"> + + +

    auf die gebräuchlichsten Grafikformate im Internet passen.

    +
    + +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +ForceType +Erzwingt die Auslieferung aller passendenden Dateien mit dem +angegebenen MIME-Content-Type +ForceType MIME-Type|None +directory.htaccess + +FileInfo +Wurde im Apache 2.0 in den Core verschoben + + +

    Wenn sie innerhalb einer .htaccess-Datei, eines + Directory-, + Location- + Files-Containers + angegeben wird, erzwingt die Direktive die Auslieferung aller + entsprechenden Dateien mit dem Content-Type, der durch + MIME-Type definiert wurde. Wenn Sie zum Beispiel ein + Verzeichnis voller GIF-Dateien haben, die Sie nicht alle durch + .gif kennzeichnen wollen, können Sie angeben:

    + + + ForceType image/gif + + +

    Beachten Sie bitte, dass die Direktive anders als DefaultType alle MIME-Type-Zuordnungen + überschreibt, einschließlich Dateiendungen, die einen + Medientyp bezeichnen könnten.

    + +

    Sie können jede ForceType-Angabe + durch die Verwendung des Wertes None überschreiben:

    + + + # erzwinge image/gif für alle Dateien:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # hier jedoch normale MIME-Type-Zuordnungen:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +
    +
    +
    + + +HostnameLookups +Aktiviert DNS-Lookups auf Client-IP-Adressen +HostnameLookups On|Off|Double +HostnameLookups Off +server configvirtual host +directory + + +

    Diese Direktive aktiviert die DNS-Abfrage ein sogenannter + DNS-Lookup, so dass Hostnamen protokolliert (und in + REMOTE_HOST an CGIs/SSIs übergeben) werden könnnen. + Der Wert Double bezieht sich auf ein + Double-Reverse-DNS-Lookup. D.h. nachdem ein Reverse-Lookup + durchgeführt wurde, wird dann auf dem Ergebnis ein + Forward-Lookup ausgeführt. Wenigstens eine der IP-Adressen + aus dem Forward-Lookup muss der Originaladresse entsprechen. + (In der "tcpwrappers"-Terminologie wird dies PARANOID + genannt.)

    + +

    Unabhängig von der Einstellung wird ein Double-Reverse-Lookup + durchgeführt, wenn mod_authz_host zur + Zugriffskontrolle per Hostnamen eingesetzt wird. Dies ist aus + Sicherheitsgründen notwendig. Beachten Sie, dass das Ergebnis dieses + Double-Reverse-Lookups nicht generell verfügbar ist, solange Sie + nicht HostnameLookups Double setzen. Wenn beispielsweise + nur HostnameLookups On angegeben ist und eine Anfrage + für ein Objekt erfolgt, welches durch Hostnamen-Beschränkungen + geschützt ist, dann wird CGIs nur das Ergebnis des + Singel-Reverse-Lookups in REMOTE_HOST übergeben, + egal ob das Doble-Reverse-Lookup fehlschlug oder nicht.

    + +

    Die Voreinstellung ist Off, um Netzwerktraffic bei den + Angeboten einzusparen, die nicht tatsächlich Reverse-Lookups + benötigen. Es ist auch für die Endanwender besser, da sie nicht + die zusätzliche Wartezeit ertragen müssen, die ein Lookup mit + sich bringt. Hoch frequentierte Angebote sollten diese Direktive auf + Offlassen. Das Hilfsprogramm + logresolve, das standardmäßig in das + Unterverzeichnis bin Ihres Installationsverzeichnisses + kompiliert wird, kann dazu verwendet werden, um offline Hostnamen von + protokollierten IP-Adressen nachzuschlagen.

    +
    +
    + + +IfDefine +Schließt Direktiven ein, die nur ausgeführt werden, +wenn eine Testbedingung beim Start wahr ist +<IfDefine [!]Parametername> ... + </IfDefine> +server configvirtual host +directory.htaccess + +All + + +

    Der Container <IfDefine Test>...</IfDefine> + wird dazu verwendet, Direktiven als bedingt zu kennzeichnen. + Die Direktiven innerhalb eines IfDefine-Abschnittes werden nur ausgeführt, + wenn Test wahr ist. Ist Test falsch, wird alles + zwischen der Start- und Endemarkierung ignoriert.

    + +

    In der IfDefine-Anweisung kann + Test eine von zwei Formen annehmen:

    + +
      +
    • Parametername
    • + +
    • !Parametername
    • +
    + +

    Im ersten Fall werden die Direktiven zwischen der Start- und + Endemarkierung nur ausgeführt, wenn der Parameter namens + Parametername definiert ist. Die zweite Form kehrt den + Test um und führt die Direktiven nur dann aus, wenn + Parametername nicht definiert ist.

    + +

    Das Argument Parametername ist ein sogenanntes + "Define", das beim beim Start des Servers in der + httpd-Befehlszeile durch + -DParameter angegeben wird.

    + +

    IfDefine-Container können + ineinander verschachtelt werden, um einfache Multi-Parameter-Tests + zu implementieren. Beispiel:

    + + + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +
    +
    +
    + + +IfModule +Schließt Direktiven ein, die abhängig vom +Vorhandensein oder Fehlen eines speziellen Moduls ausgeführt +werden +<IfModule [!]Modulname|Modulbezeichner> + ... </IfModule> +server configvirtual host +directory.htaccess + +All +Modulbezeichner sind ab Version 2.1 + verfügbar. + + + +

    Der Container <IfModule + Test>...</IfModule> wird dazu verwendet, + Direktiven als abhängig von dem Vorhandensein eines speziellen + Moduls zu kennzeichnen. Die Direktiven innerhalb eines IfModule-Abschnitts werden nur + ausgeführt, wenn Test wahr ist. Ist Test + falsch, wird alles zwischen der Start- und Endemarkierung ignoriert.

    + +

    In der IfModule-Anweisung + kann Test eine von zwei Formen annehmen:

    + +
      +
    • Modul
    • + +
    • !Modul
    • +
    + +

    Im ersten Fall werden die Direktiven zwischen der Start- und + Endemarkierung nur ausgeführt, das Modul namens + Modul im Apache enthalten ist -- entweder einkompiliert + oder mittels LoadModule + dynamisch geladen. Die zweite Form dreht den Test um und führt die + Direktiven nur aus, wenn Modul nicht + enthalten ist.

    + +

    Das Argument Modul kann entweder der Modulbezeichner oder + der Dateiname des Moduls zum Zeitpunkt seiner Kompilierung sein. + rewrite_module beispielsweise ist der Bezeichner und + mod_rewrite.c ist der Dateiname. Wenn ein Modul aus mehreren + Quelltext-Dateien besteht, verwenden Sie den Namen der Datei, welche die + Zeichenfolge STANDARD20_MODULE_STUFF enthält.

    + +

    IfModule-Container können + inneinander verschachtelt werden, um einfache Multi-Modul-Tests + durchzuführen.

    + +

    Dieser Container sollte verwendet werden, wenn Sie eine + Konfigurationsdatei benötigen, die unabhängig davon funktioniert, + ob ein bestimmtes Modul verfügbar ist oder nicht. Normalerweise + ist es nicht notwendig, Direktiven in IfModule-Containern unterzubringen.

    +
    +
    + + +Include +Fügt andere Konfigurationsdateien innerhalb der +Server-Konfigurationsdatei ein +Include Dateiname|Verzeichnis +server configvirtual host +directory + +Die Platzhalter-Suche ist verfügbar seit +2.0.41 + + +

    Die Direktive erlaubt das Einfügen anderer Konfigurationsdateien + in die Konfigurationsdatei des Servers.

    + +

    Shell-typische (fnmatch()) Platzhlaterzeichen können + dazu verwendet werden, mehrere Dateien auf einmal in alphabetischer + Reihenfolge einzufügen. Wenn Include + darüber hinaus auf ein Verzeichnis anstatt auf eine Datei zeigt, + liest der Apache alle Dateien in diesem Verzeichnis und allen + Unterverzeichnissen ein. Das Einfügen ganzer Verzeichnisse ist + jedoch nicht empfehlenswert, da temporäre Dateien sehr leicht + versehentlich in einem Verzeichnis zurückgelassen werden, was + httpd scheitern lassen kann.

    + +

    Der angegebene Dateiname kann ein absoluter Pfad sein oder relativ zum + ServerRoot-Verzeichnis angegeben + werden.

    + +

    Beispiele:

    + + + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +
    + +

    Oder Sie geben Pfade relativ zu Ihrem ServerRoot-Verzeichnis an:

    + + + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +
    + +

    Der Aufruf von apachectl configtest liefert eine Liste + der Dateien, die während des Konfigurations-Tests verarbeitet + werden:

    + + + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +
    +
    + +apachectl +
    + + +KeepAlive +Aktiviert persistente HTTP-Verbindungen +KeepAlive On|Off +KeepAlive On +server configvirtual host + + + +

    Die Keep-Alive-Erweiterung von HTTP/1.0 und die + HTTP/1.1-Funktionalität persistenter Verbindungen unterstützt + langlebige HTTP-Sitzungen, die es erlauben, mehrere Anfragen über + die gleich TCP-Verbindung zu senden. In einigen Fällen wurde eine + Beschleunigung der Wartezeiten von beinahe 50% für HTML-Dokumente + mit vielen Bildern festgestellt. Um Keep-Alive-Verbindungen zu aktivieren, + setzen Sie KeepAlive On.

    + +

    Bei HTTP/1.0-Clients werden Keep-Alive-Verbindungen nur dann verwendet, + wenn sie vom Client eigens angefordert werden. Desweiteren können + Keep-Alive-Verbindungen bei einem HTTP/1.0-Client nur dann verwendet + werden, wenn die Länge des Inhalts im Voraus bekannt ist. Dies + impliziert, dass dynamische Inhalte wie CGI-Ausgaben, SSI-Seiten und + servergenerierte Verzeichnisauflistungen im Allgemeinen keine + Keep-Alive-Verbindungen mit HTTP/1.0-Clients verwenden. Bei + HTTP/1.1-Clients sind Keep-Alive-Verbindungen Voreinstellung, solange + nichts anderes angegeben ist. Wenn der Client es anfordert, wird + Chunked-Encoding verwendet, um Inhalte mit unbekannter Länge + über persistente Verbindungen zu senden.

    +
    + +MaxKeepAliveRequests +
    + + +KeepAliveTimeout +Zeitspanne, die der Server während persistenter Verbindungen +auf nachfolgende Anfragen wartet +KeepAliveTimeout Sekunden +KeepAliveTimeout 5 +server configvirtual host + + + +

    Dies legt die Anzahl der Sekunden fest, die der Apache auf weitere + Anfragen wartet, bevor er die Verbindung schließt. Nachdem einmal + eine Anfrage entgegen genommen wurde, wird die durch die Direktive + Timeout festgelegte Auszeit + angewendet.

    + +

    Auf stark belasteten Servern kann ein hoher + KeepAliveTimeout-Wert zu Durchsatzminderungen + führen. Je höher die Auszeit angegeben ist, desto länger + ist der Apache damit beschäftigt, auf untätige Clients zu + warten.

    +
    +
    + + +Limit +Beschränkt die eingeschlossenen Zugriffskontrollen auf +bestimmte HTTP-Methoden +<Limit Methode [Methode] ... > ... + </Limit> +server configvirtual host +directory.htaccess + +All + + +

    Zugriffskontrollen gelten normalerweise für alle + Zugriffsmethoden, was normalerweise auch das gewünschte Verhalten ist. + Im Allgemeinen sollten Zugriffskontrollen nicht in einen + Limit-Container gepackt + werden.

    + +

    Der Sinn der Direktive Limit + ist es, den Effekt der Zugriffskontrollen auf die angegebenen + HTTP-Methoden zu beschränken. Bei allen anderen Methoden haben + die in der Limit-Gruppe + enthaltenen Zugriffsbeschränkungen keine Wirkung. + Im folgenden Beispiel gilt die Zugriffskontrolle nur für die + Methoden POST, PUT und DELETE. + Alle anderen Methoden bleiben ungeschützt:

    + + + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +
    + +

    Sie können eine oder mehrere der folgenden Methoden angeben: + GET, POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK und UNLOCK. Die Methodennamen + unterscheiden zwischen Groß- und Kleinschreibung. Wenn + GET verwendet wird, sind HEAD-Anfragen + ebenfalls eingeschränkt. Die TRACE-Methode kann nicht + limitiert werden.

    + + + Wenn es um Zugriffsbeschränkungen geht, sollte + ein LimitExcept-Container sollte immmer einem Limit-Container vorgezogen + werden, da LimitExcept + einen Schutz gegen beliebige Methoden bietet. + +
    +
    + + +LimitExcept +Beschränkt Zugriffskontrollen auf alle HTTP-Methoden +außer den genannten +<LimitExcept Methode [Methode] ... > ... + </LimitExcept> +server configvirtual host +directory.htaccess + +All + + +

    LimitExcept und + </LimitExcept> werden dazu verwendet, eine Gruppe + von Anweisungen zur Zugriffskontrolle zusammenzufassen, die dann auf + jede HTTP-Methode angewendet werden, die nicht + als Argument angegeben ist. D.h. dies ist das Gegenteil des + Limit-Containers + und kann zur Steuerung von Standard- und nicht-Standard-/unbekannten + Methoden verwendet werden. Für weitere Einzelheiten lesen Sie bitte + die Beschreibung zu Limit.

    + +

    Beispiel:

    + + + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +
    + +
    +
    + + +LimitInternalRecursion +Bestimmt die maximale Anzahl interner Umleitungen und + verschachtelter Unteranfragen +LimitInternalRecursion Zahl [Zahl] +LimitInternalRecursion 10 +server configvirtual host + +Verfügbar ab Apache 2.0.47 + + +

    Eine interne Umleitung erfolgt beispielsweise, wenn die Direktive + Action verwendet wird, welche + die Originalanfrage intern zu einem CGI-Skript weiterleitet. Eine + Unteranfrage engl. Subrequest ist ein Mechanismus des + Apache, um herauszufinden, was bei einer URI geschehen würde, wäre + sie angefordert worden. mod_dir z.B. verwendet + Unteranfragen, um nach den Dateien zu suchen, die in der DirectoryIndex-Anweisung aufgeführt + sind.

    + +

    LimitInternalRecursion bewahrt den Server vor + einem Absturz, wenn er in eine Endlosschleife aus internen Umleitungen + oder Unteranfragen hineinläuft. Derartige Schleifen werden + gewöhnlich durch Fehlkonfiguration verursacht.

    + +

    Die Direktive setzt zwei verschiedene Begrenzungen, welche je Anfrage + ausgewertet werden. Die erste Zahl bestimmt die maximale + Anzahl der Umleitungen, die aufeinander folgen dürfen. Die zweite + Zahl legt fest, wie tief Unteranfragen ineinander + verschachtelt werden dürfen. Wenn Sie lediglich eine Zahl + angeben, wird sie beiden Begrenzungen zugewiesen.

    + + Beispiel + LimitInternalRecursion 5 + +
    +
    + + +LimitRequestBody +Begrenzt die Gesamtgröße des vom Client gesendeten +HTTP-Request-Body +LimitRequestBody Bytes +LimitRequestBody 0 +server configvirtual host +directory.htaccess + +All + + +

    Die Direktive gibt die Anzahl der Bytes zwischen 0 + (unbegrenzt) und 2147483647 (2GB) an, die im Request-Body (Datenteil der + Anfrage) erlaubt sind.

    + +

    Die Direktive LimitRequestBody erlaubt es dem + Benutzer, die Größe des HTTP-Request-Bodys in dem Kontext zu + begrenzen, in dem die Anweisung angegeben ist (Server, pro Verzeichnis, + pro Datei oder pro Adresse). Wenn die Anfrage des Clients dieses Limit + überschreitet, gibt der Server einen Fehler zurück anstatt die + Anfrage zu bearbeiten. Die Größe des Datenteils einer Anfrage + kann sehr stark variieren, abhängig von der Art der Ressource und + den für diese Ressource erlaubten Methoden. CGI-Skripte verwenden + den Datenteil üblicherweise zum Empfang von Formulardaten. Wird + die PUT-Methode angewendet, dann muss der Wert mindestens + so groß sein wie irgendeine Darstellungsform, die der Server + für diese Ressource akzeptieren soll.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Wenn Sie beispielsweise das Hochladen von Dateien zu einer bestimmten + Adresse erlauben, aber die Größe der hochgeladenen Dateien + auf 100K beschränken wollen, können Sie die folgende Anweisung + verwenden:

    + + + LimitRequestBody 102400 + + +
    +
    + + +LimitRequestFields +Begrenzt die Anzahl der HTTP-Request-Header, die vom Client +entgegengenommen werden +LimitRequestFields Anzahl +LimitRequestFields 100 +server config + + +

    Anzahl ist ein Integer-Wert (eine positive Ganzzahl) + zwischen 0 (unbegrenzt) und 32767. Die Voreinstellung wird durch die + Konstante DEFAULT_LIMIT_REQUEST_FIELDS (100 + bei der Auslieferung) zur Kompilierungszeit gesetzt.

    + +

    Die Direktive LimitRequestFields erlaubt es + dem Serveradministrator, die maximale Anzahl der in einem HTTP-Request + erlaubten HTTP-Request-Header zu verändern. Für den Server + muss dieser Wert größer sein als die Anzahl der Headerzeilen, + die ein normaler Client senden könnte. Die Anzahl der Request-Header, + die ein gewöhnlicher Client verwendet, überschreitet selten 20 + Zeilen. Allerdings kann dies zwischen den verschiedenen + Client-Ausführungen variieren, oft abhängig vom Ausmaß, + mit dem der Anwender die genaue Content-Negotiation-Unterstützung + seines Browsers konfiguriert hat. Optionale HTTP-Erweiterungen + äußern sich oft in Form von HTTP-Headern.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann. Der Wert sollte erhöht werden, wenn normale Clients + eine Fehlermeldung vom Server erhalten, die besagt, dass mit der Anfrage + zu viele Headerzeilen gesendet wurden.

    + +

    Beispiel:

    + + + LimitRequestFields 50 + + +
    +
    + + +LimitRequestFieldSize +Begrenzt die Länge des vom Client gesendeten +HTTP-Request-Headers +LimitRequestFieldsize Bytes +LimitRequestFieldsize 8190 +server config + + +

    Die Direktive gibt die Anzahl der Bytes an, die in einem + HTTP-Header erlaubt sind.

    + +

    Die Direktive LimitRequestFieldsize erlaubt es + dem Serveradministrator, die maximale Größe eines + HTTP-Request-Headers zu verringern oder erhöhen. Für den Server + muss der Wert groß genug sein, um eine beliebige Headerzeile einer + normalen Client-Anfrage vorzuhalten. Die Größe variiert stark + zwischen den verschiedenen Client-Ausführungen, oft abhängig vom + Ausmaß, mit dem der Anwender die genaue + Content-Negotiation-Unterstützung seines Browsers konfiguriert hat. + SPNEGO-Authentisierungs-Header können bis zu 12392 Bytes lang + sein.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Beispiel:

    + + + LimitRequestFieldSize 4094 + + + Unter normalen Umständen sollte die Voreinstellung nicht + verändert werden. +
    +
    + + +LimitRequestLine +Begrenzt die Länge der vom Client entgegengenommenen +HTTP-Anfragezeile +LimitRequestLine Bytes +LimitRequestLine 8190 +server config + + +

    Die Direktive legt die Anzahl der Bytes fest, die in der + HTTP-Anfragezeile erlaubt sind.

    + +

    Die Direktive LimitRequestLine erlaubt es dem + Serveradministrator, die maximale Größe der + HTTP-Anfragezeile zu verringern oder erhöhen. Da + die Anfragezeile aus der HTTP-Methode, der URI und der Protokollversion + besteht, bedeutet die LimitRequestLine-Direktive + eine Beschränkung der Länge der für eine Anfrage an den + Server erlaubten Anfrage-URI. Für den Server muss der Wert groß + genug sein, um jeden seiner Ressourcennamen vorzuhalten, + einschließlich aller Informationen, die im Query-String einer + GET-Anfrage übergeben werden können.

    + +

    Die Direktive gibt dem Serveradministrator eine größere + Kontrolle gegenüber abnormalem Verhalten von Clients, was bei der + Vermeidung einiger Formen von Denial-of-Service-Attacken hilfreich + sein kann.

    + +

    Beispiel:

    + + + LimitRequestLine 4094 + + + Unter normalen Umständen sollte die Voreinstellung nicht + verändert werden. +
    +
    + + +LimitXMLRequestBody +Begrenzt die Größe eines XML-basierten +Request-Bodys +LimitXMLRequestBody Bytes +LimitXMLRequestBody 1000000 +server configvirtual host +directory.htaccess +All + + +

    Dies gibt die Grenze für die maximale Größe (in Bytes) + des XML-basierten Request-Bodys an. Der Wert 0 deaktiviert + diese Prüfung.

    + +

    Beispiel:

    + + + LimitXMLRequestBody 0 + + +
    +
    + + +Location +Wendet die enthaltenen Direktiven nur auf die entsprechenden +URLs an +<Location + URL-Pfad|URL> ... </Location> +server configvirtual host + + + +

    Die Direktive Location + begrenzt die Reichweite der enthaltenen Anweisungen auf URLs. + Sie ist der Direktive Directory ähnlich und startet einen + Abschnitt, der mit der Anweisung </Location> + abgeschlossen wird. Location-Container werden, nachdem die + Directory-Container + und .htaccess-Dateien gelesen wurden, und nach den + Files-Containern, in + der Reihenfolge ausgeführt, in der sie in der Konfigurationsdatei + erscheinen.

    + +

    Location-Abschnitte operieren + vollständig außerhalb des Dateisystems. Dies hat mehrere + Konsequenzen. An Wichtigsten, Location-Anweisungen sollten nicht dafür + verwendet werden, den Zugriff zu Teilen des Dateisystems zu steuern. Da + mehrere unterschiedliche URLs auf die gleiche Stelle des Dateisystems + zeigen können, könnte eine solche Zugriffskontrolle u.U. + umgangen werden.

    + + Wann sollte<directive + type="section">Location</directive> verwendet werden + +

    Verwenden Sie Location, um + Anweisungen auf Inhalte anzuwenden, die außerhalb des Dateisystems + abgelegt sind. Benutzen Sie Directory und Files für Inhalte, die + innerhalb des Dateisystems abgelegt sind. Eine Ausnahme bildet + <Location />, welches ein einfacher Weg ist, um eine + Konfiguration auf den gesamten Server anzuwenden.

    +
    + +

    Für alle nicht-Proxy-Anfragen ist die entsprechende URL + ein URL-Pfad in der Form /path/. Es dürfen weder ein + Schema, noch ein Hostname, noch ein Port, noch ein Query-String einbezogen + werden. Für Proxy-Anfragen hat die Vergleichs-URL die Form + schema://servername/path. Das Präfix muss angegeben + werden.

    + +

    Die URL kann Platzhalter verwenden. In einer Zeichenfolge mit + Platzhaltern entspricht ? einem einzelnen Zeichen und + *einer beliebigen Zeichenfolge.

    + +

    Erweiterte reguläre Ausdrücke können ebenfalls + verwendet werden, indem das Zeichen ~ hinzugefügt + wird. Beispielsweise würde

    + + + <Location ~ "/(extra|special)/data"> + + +

    auf URLs passen, welche die Zeichenfolge /extra/data + oder /special/data enthalten. Die Direktive LocationMatch verhält sich + genauso wie Location mit + regulären Ausdrücken.

    + +

    Die Funktionalität von Location ist insbesondere dann nützlich, + wenn sie mit der SetHandler-Direktive + kombiniert wird. Um zum Beispiel Statusabfragen zu aktivieren, sie aber + nur von Browsern aus foo.com zuzulassen, könnten Sie + schreiben:

    + + + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +
    + + Anmerkung zu / (Schrägstrich, Slash) +

    Das Slash-Zeichen hat eine besondere Bedeutung, je nachdem, wo es + in der URL erscheint. Manche werden sein Verhalten vom Dateisystem + gewohnt sein, wo mehrere aufeinanderfolgende Schrägstriche + häufig zu einem Schrägstrich zusammengefaßt werden + (d.h. /home///foo ist das gleiche wie + /home/foo). Im URL-Raum ist dies nicht notwendigerweise + genauso. Bei der Direktive LocationMatch und der Location-Version mit regulären Ausdrücken + müssen Sie explizit mehrere Schrägstriche angeben, wenn Sie + genau dies beabsichtigen.

    + +

    Beispielsweise würde <LocationMatch ^/abc> + auf die angeforderte URL /abc passen, nicht aber auf + //abc. Die Direktive Location (ohne reguläre Ausdrücke) verhält + sich ähnlich, wenn sie für Proxy-Anfragen verwendet wird. + Wenn Location (ohne + reguläre Ausdrücke) jedoch für nicht-Proxy-Anfragen + verwendet wird, werden stillscheigend mehrere Schrächstriche mit + mit einem einzigen Schrägstrich gleichgesetzt. Geben Sie + beispielsweise <Location /abc/def> an und die + Anfrage lautet auf /abc//def, dann greift die Anweisung.

    +
    +
    +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +LocationMatch +Wendet die enthaltenen Direktiven nur auf URLs an, die auf +reguläre Ausdrücke passen +<LocationMatch + regex> ... </LocationMatch> +server configvirtual host + + + +

    Die Direktive LocationMatch + begrenzt die Reichweite der enthaltenen Anweisungen in der gleichen Weise + wie Location auf URLs. + Sie verwendet jedoch reguläre Ausdrücke als Argument anstelle + einer einfachen Zeichenkette. Beispielsweise würde

    + + + <LocationMatch "/(extra|special)/data"> + + +

    auf URLs passen, welche die Zeichenfolge /extra/data + oder /special/data enthalten.

    +
    + +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + + +LogLevel +Steuert die Ausführlichkeit des Fehlerprotokolls +LogLevel Level +LogLevel warn +server configvirtual host + + + +

    LogLevel stellt die Ausführlichkeit + der Nachrichten ein, die im Fehlerprotokoll aufgezeichnet werden (siehe + Direktive ErrorLog). Die folgenden, + nach absteigender Aussagekraft sortierten Level sind + verfügbar:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level Beschreibung Beispiel
    emerg Notfall - das System ist unbenutzbar."Child cannot open lock file. Exiting" + "Kindprozess kann die Lock-Datei nicht öffnen. + Beende Programm"
    alert Maßnahmen müssen unverzüglich ergriffen + werden."getpwuid: couldn't determine user name from uid" + "getpwuid: kann keinen Benutzernamen aus der UID + ermitteln"
    crit Kritischer Zustand."socket: Failed to get a socket, exiting child" + "socket: Socket-Zuweisung fehlgeschlagen, beende + Kindprozess"
    error Fehlerbedingung."Premature end of script headers" + "Vorzeitiges Ende der Skript-Header"
    warn Warnung."child process 1234 did not exit, sending another SIGHUP" + "Kindprozess 1234 nicht beendet, sende ein weiteres + SIGHUP"
    notice Normaler, aber signifikanter Zustand."httpd: caught SIGBUS, attempting to dump core in ..." + "httpd: SIGBUS empfangen, versuche Speicherabbild nach ... + zu schreiben"
    info Information."Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..." + "Server scheint beschäftigt zu sein, + (möglicherweise müssen Sie StartServers oder + Min/MaxSpareServers erhöhen)"
    debug Debug-Level-Nachrichten"Opening config file ..." + "Öffne Konfigurationsdatei ..."
    + +

    Geben Sie einen bestimmten Level an, denn werden Nachrichten von + allen höheren Leveln ebenso angezeigt. Z.B.: Wenn + LogLevel info eingestellt ist, dann werden Nachrichten der + Log-Level notice und warn ebenso eingetragen.

    + +

    Es wird empfohlen, mindestens den Level crit zu + verwenden.

    + +

    Beispiel:

    + + + LogLevel notice + + + Hinweis +

    Beim Protokollieren in eine reguläre Datei können + Nachrichten des Levels notice nicht unterdrückt + werden und werden daher immer protokolliert. Dies trifft allerdings + nicht zu, wenn mittels syslog protokolliert wird.

    +
    +
    +
    + + +MaxKeepAliveRequests +Anzahl der Anfragen, die bei einer persistenten Verbindung +zulässig sind +MaxKeepAliveRequests Anzahl +MaxKeepAliveRequests 100 +server configvirtual host + + + +

    Die Direktive MaxKeepAliveRequests + begrenzt die Anzahl der Anfragen, die pro Verbindung zulässig sind, + wenn KeepAlive eingeschaltet ist. + Bei der Einstellung 0 sind unbegrenzt viele Anfragen + erlaubt. Wir empfehlen für diese Einstellung einen hohen Wert + für eine maximale Serverleistung.

    + +

    Beispiel:

    + + + MaxKeepAliveRequests 500 + +
    +
    + + +NameVirtualHost +Bestimmt eine IP-Adresse für den Betrieb namensbasierter +virtueller Hosts +NameVirtualHost Adresse[:Port] +server config + + +

    Die Direktive NameVirtualHost ist erforderlich, + wenn Sie namensbasierte virtuelle Hosts + konfigurieren möchten.

    + +

    Obwohl Adresse eine Hostname sein kann, wird empfohlen, + dass Sie stets eine IP-Adresse verwenden, z.B.:

    + + + NameVirtualHost 111.22.33.44 + + +

    Mit der NameVirtualHost-Anweisung geben Sie + die IP-Adresse an, unter der der Server Anfragen für + namensbasierte virtuelle Hosts entgegennimmt. Das ist üblicherweise + die Adresse, zu der die Namen Ihrer namensbasierten virtuellen Hosts + aufgelöst werden. Falls eine Firewall oder ein anderer Proxy die + Anfrage in Empfang nimmt und Sie zu einer weiteren IP-Adresse des Servers + weiterleitet, müssen Sie die IP-Adresse der physikalischen + Schnittstelle der Maschine angeben, welche die Anfragen bedient. + Wenn Sie mehrere namensbasierte Hosts an verschiedenen Adressen + betreiben, wiederholen Sie einfach die Anweisung für jede + Adresse.

    + + Anmerkung +

    Beachten Sie, dass der "Hauptserver" und jeder + _default_-Server niemals bei einer + Anfrage an einer NameVirtualHost-IP-Adresse + bedient wird (es sei denn, Sie geben aus irgendwelchen Gründen + NameVirtualHost an, definieren dann aber keine + VirtualHosts für diese Adresse).

    +
    + +

    Optional können Sie die Nummer eines Ports angeben, an dem + namensbasierte virtuelle Hosts verwendet werden sollen. Beispiel:

    + + + NameVirtualHost 111.22.33.44:8080 + + +

    IPv6-Adressen müssen, wie im folgenden Beispiel angegeben, in + eckige Klammern eingeschlossen werden:

    + + + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 + + +

    Um an allen Schnittstellen Anfragen zu empfangen, können Sie + * als Argument verwenden.

    + + + NameVirtualHost * + + + Argument der Direktive <directive + type="section">VirtualHost</directive> +

    Beachten Sie, dass das Argument der VirtualHost-Anweisung exakt auf das Argument + der NameVirtualHost-Anweisung passen muss.

    + + + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +
    +
    +
    +Dokumentation zu virtuellen Hosts +
    + + +Options +Definiert, welche Eigenschaften oder Funktionen in einem +bestimmten Verzeichnis verfügbar sind +Options + [+|-]Option [[+|-]Option] ... +Options All +server configvirtual host +directory.htaccess + +Options + + +

    Die Direktive Options steuert, welche + Eigenschaften bzw. Funktionen in einem bestimmten Verzeichnis + verfügbar sind.

    + +

    Option kann auf None gesetzt werden, wobei + keine der besonderen Eigenschaften verfügbar sind, oder auf eines + oder mehrere der folgenden:

    + +
    +
    All
    + +
    Alle Optionen außer MultiViews. Dies ist + die Voreinstellung.
    + +
    ExecCGI
    + +
    Die Ausführung von CGI-Skripten, welche mod_cgi + verwenden, ist erlaubt.
    + +
    FollowSymLinks
    + +
    Der Server folgt symbolischen Links in diesem Verzeichnis. + +

    Auch wenn der Server symbolischen Links folgt, bedeutet dies + nicht, dass der zum Abgleich gegen Directory-Abschnitte verwendete Pfadname + wechselt.

    +

    Beachten Sie auch, dass diese Option innerhalb eines + Location-Abschnitts + ignoriert wird.

    +
    + +
    Includes
    + +
    + Server Side Includes, die von mod_include bereitgestellt + werden, sind erlaubt.
    + +
    IncludesNOEXEC
    + +
    Server Side Includes sind erlaubt, #exec cmd + und #exec cgi sind jedoch deaktiviert. Es ist aber noch + möglich, CGI-Skripte aus + ScriptAlias-Verzeichnissen mittels + #include virtual einzubinden.
    + +
    Indexes
    + +
    Wenn eine URL, die auf ein Verzeichnis zeigt, in dem sich keine durch + DirectoryIndex definierte + Indexdatei (z.B. index.html) befindet, dann liefert + mod_autoindex eine formatierte Auflistung des + Verzeichnisses zurück.
    + +
    MultiViews
    + +
    "MultiViews" sind bei der Verwendung von + mod_negotiation erlaubt (siehe Content-Negotiation).
    + +
    SymLinksIfOwnerMatch
    + +
    Der Server folgt nur symbolischen Links, bei denen die Zieldatei + bzw. das Zielverzeichnis der gleichen Benutzerkennung gehört, wie + der Link. + Anmerkung Diese Option wird innerhalb eines + Location-Abschnitts + ignoriert.
    +
    + +

    Wenn mehrere Options auf ein Verzeichnis + angewandt werden können, dann wird normalerweise die + spezifischste Gemeint ist die zuletzt + ausgeführte Option. verwendet und alle anderen werden + ignoriert; die Optionen werden nicht vermischt. (Siehe auch Wie Abschnitte zusammengeführt + werden..) Wenn jedoch allen Optionen der + Options-Anweisung eines der Zeichen + + oder - vorangestellt wird, werden die Optionen + zusammengemischt. Jede Option mit vorangestelltem + wird + zu den momentan gültigen Optionen hinzugefügt und jede Option + mit vorangestelltem - wird aus den derzeit gültigen + Optionen entfernt.

    + +

    So wird zum Beispiel ohne die Zeichen + und + -

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +
    + +

    für das Verzeichnis /web/docs/spec wird jetzt + lediglich Includes gesetzt. Wenn die zweite + Options-Anweisung jedoch +- + und --Zeichen verwenden würde,

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +
    + +

    dann würden die Optionen FollowSymLinks und + Includes für das Verzeichnis /web/docs/spec + gesetzt.

    + + Anmerkung +

    Die Verwendung von -IncludesNOEXEC oder + -Includes deaktiviert Server Side Includes unabhängig + von der vorigen Einstellung vollständig.

    +
    + +

    Die Voreinstellung ist All, sofern keine anderen Angaben + gemacht wurden.

    +
    +
    + + +Require +Wählt die authentisierten Benutzer aus, die auf eine +Ressource zugreifen können +Require Name [Name] ... +directory.htaccess + +AuthConfig + + +

    Die Direktive wählt aus, welche authentisierten Benutzer auf eine + Ressource zugreifen dürfen. Folgende Syntax ist erlaubt:

    + +
    +
    Require user User-ID [User-ID] + ...
    +
    Nur die genannten Benutzer dürfen auf die Ressource + zugreifen.
    + +
    Require group Gruppenname [Gruppenname] + ...
    +
    Nur Benutzer der genannten Gruppen dürfen auf die + Ressource zugreifen.
    + +
    Require valid-user
    +
    Alle gültigen Benutzer dürfen auf die Ressource + zugreifen.
    +
    + +

    Require muss von den Direktiven + AuthName und AuthType sowie Direktiven wie + AuthUserFile + und AuthGroupFile + (zur Definition von Benutzern und Gruppen) begleitet werden, um + korrekt zu funktionieren. Beispiel:

    + + + AuthType Basic
    + AuthName "Geschützte Ressource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +
    + +

    Zugriffskontrollen, die in dieser Form angewandt werden, gelten + für alle Methoden. Dies ist normalerweise + gewünscht. Wenn Sie Zugriffskontrollen nur auf bestimmte + Methoden anwenden möchten, während andere Methoden + ungeschützt bleiben, dann müssen Sie die + Require-Anweisung innerhalb eines + Limit-Abschnitts + platzieren.

    +
    +Satisfy +mod_authz_host +
    + + +RLimitCPU +Begrenzt den CPU-Verbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden +RLimitCPU Sekunden|max [Sekunden|max] +unbestimmt; verwendet die Voreinstellung des Systems +server configvirtual host +directory.htaccess +All + + +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Das beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    CPU-Ressourcenbegrenzung wird in Sekunden pro Prozess + ausgedrückt.

    +
    +RLimitMEM +RLimitNPROC +
    + + +RLimitMEM +Begrenzt den Speicherverbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden +RLimitMEM Bytes|max [Bytes|max] +unbestimmt; verwendet die Voreinstellung des Systems +server configvirtual host +directory.htaccess +All + + +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Das beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    Die Begrenzung des Speicherverbrauchs wird in Bytes pro Prozess + ausgedrückt.

    +
    +RLimitCPU +RLimitNPROC +
    + + +RLimitNPROC +Begrenzt die Anzahl der Prozesse, die von Prozessen gestartet +werden können, der ihrerseits von Apache-Kinprozessen gestartet +wurden +RLimitNPROC Zahl|max [Zahl|max] +unbestimmt; verwendet die Voreinstellung des Systems +server configvirtual host +directory.htaccess +All + + +

    Akzeptiert einen oder zwei Parameter. Der erste Paramater setzt eine + weiche Ressourcenbegrenzung für alle Prozesse, der zweite Parameter + setzt die Maximalgrenze für die Ressourcennutzung. Jeder der + Parameter kann eine Zahl oder max sein. max + zeigt dem Server an, dass das vom Betriebssystem erlaubte Maximum + verwendet werden soll. Das Anheben der maximal erlaubten Ressourcennutzung + erfordert, dass der Server als root läuft, zumindest in + der anfänglichen Startphase.

    + +

    Dies wird auf Prozesse angewendet, die von Anfragen bearbeitenden + Apache-Kindprozessen abgespalten werden, nicht auf die + Apache-Kindprozesse selbst. Dies beinhaltet CGI-Skripte und + SSI-exec-Befehle, nicht jedoch Prozesse, die vom Apache-Elternprozess + abgespalten werden, wie z.B. Protokollierung.

    + +

    Prozessbegrenzungen steuern die Anzahl der Prozesse pro Benutzer.

    + + Anmerkung +

    Wenn CGI-Prozesse nicht unter anderen Benutzerkennungen als der + User-ID des Webservers laufen, dann beschränkt diese Direktive + die Anzahl der Prozesse, die der Server selbst erstellen kann. + Kennzeichen einer solchen Situation sind + cannot fork-Meldungen + kann nicht abspalten in der + Datei error_log.

    +
    +
    +RLimitMEM +RLimitCPU +
    + + +Satisfy +Zusammenspiel von rechnerbasierter Zugriffskontrolle und +Benutzerauthentisierung +Satisfy Any|All +Satisfy All +directory.htaccess + +AuthConfig +Wird seit Version 2.0.51 von Limit und LimitExcept beeinflusst + + +

    Verfahrensweise für den Zugriff, falls sowohl Allow als auch Require verwendet werden. Der Parameter kann + entweder All oder Any sein. Die Direktive ist + nur dann nützlich, wenn der Zugriff zu einem bestimmten Bereich + durch Benutzername/Passwort und Clientrechner-Adressen + eingeschränkt ist. In diesem Fall verlangt die Voreinstellung + (All), dass der Client die Adressbeschränkung passiert + und eine gültige Benutzerkennung und ein gültiges + Passwort übermittelt. Mit der Auswahl Any wird dem + Client der Zugriff erlaubt, wenn er entweder die Rechner-Beschänkung + passiert oder einen gültigen Benutzernamen und ein gültiges + Passwort übermittelt. Dies kann verwendet werden, um einen Bereich + mit einem Passwort zu schützen, jedoch Clients von bestimmten + Adressen ohne Abfrage des Passwortes zuzulassen.

    + +

    Wenn Sie beispielsweise möchten, dass Personen aus Ihrem + privaten Netzwerk unbechänkten Zugriff zu Teilen Ihres + Webangebots haben, jedoch verlangen, dass Personen außerhalb + Ihres privaten Netzwerks ein Passwort übergeben müssen, + können Sie eine Konfiguration ähnlich der folgenden + verwenden:

    + + + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +
    + +

    Seit Version 2.0.51 können + Satisfy-Anweisungen durch Limit- und LimitExcept-Abschnitte auf bestimmte Methoden + beschränkt werden.

    +
    + Allow + Require +
    + + +ScriptInterpreterSource +Methode zur Ermittlung des Interpreters von +CGI-Skripten +ScriptInterpreterSource Registry|Registry-Strict|Script +ScriptInterpreterSource Script +server configvirtual host +directory.htaccess +FileInfo +ausschließlich Win32; +Die Option Registry-Strict ist verfügbar seit Apache +2.0. + + +

    Die Direktive steuert, wie der Apache den Interpreter zur Ausführung + von CGI-Skripten bestimmt. Die Voreinstellung ist Script. Dies + veranlaßt den Apache, den Interpreter zu verwenden, auf den die + Shebang-Zeile (erste Zeile, beginnt mit #!) im Skript zeigt. + Auf Win32-Systemen sieht diese Zeile üblicherweise so aus:

    + + + #!C:/Perl/bin/perl.exe + + +

    oder, wenn perl im Pfad (Umgebungsvariable PATH) liegt, + einfach:

    + + + #!perl + + +

    Die Einstellung ScriptInterpreterSource Registry + veranlaßt eine Suche in HKEY_CLASSES_ROOT der + Windows-Registrierungsdatenbank und verwendet die Endung der Skript-Datei + (z.B. .pl) als Suchargument. Der durch den Unterschlüssel + Shell\ExecCGI\Command oder, falls dieser nicht existiert, + Shell\Open\Command definierte Befehl wird zum Öffnen der + Skript-Datei verwendet. Wenn der Schlüssel zur Dateiendung oder + beide Unterschlüssel fehlen, dann verwendet der Apache die Option + Script.

    + + Sicherheit +

    Seien Sie vorsichtig, ScriptInterpreterSource Registry bei + Verzeichnissen zu verwenden, auf die eine ScriptAlias-Anweisung zeigt, denn der + Apache versucht jede Datei innerhalb des Verzeichnisses + auszuführen. Die Einstellung Registry kann + unerwünschte Programmaufrufe bei Dateien verursachen, die + üblicherweise nicht ausgeführt werden. Auf den meisten + Windows-Systemen beispielsweise startet der voreingestellte + Öffnen-Befehl für .htm-Dateien den Microsoft + Internet Explorer, so dass jede HTTP-Anfrage nach einer existierenden + .htm-Datei im Skript-Verzeichnis den Browser im Hintergrund + starten würde. Dies ist eine wirksame Methode, Ihr System binnen + etwa einer Minute zum Absturz zu bringen.

    +
    + +

    Die seit Apache 2.0 neue Option Registry-Strict + macht das gleiche wie Registry, verwendet jedoch nur den + Unterschlüssel Shell\ExecCGI\Command. Der Schlüssel + ExecCGI ist gewöhnlich nicht voreingestellt. Er muss + manuell eingerichtet werden und schützt Ihr System so for + versehentlichen Programmaufrufen.

    +
    +
    + + +ServerAdmin +E-Mail-Adresse, die der Server in Fehlermeldungen einfügt, +welche an den Client gesendet werden +ServerAdmin E-Mail-Adresse|URL +server configvirtual host + + + +

    ServerAdmin legt die Kontaktadresse fest, + die der Server in jede Fehlermeldung einfügt, die er an den + Client zurückschickt. Wenn httpd das übergebene + Argument nicht als URL erkennt, nimmt er an, dess es sich um eine + E-Mail-Adresse handelt und stellt in Hyperlinks + mailto: voran. Es ist jedoch sogar sinnvoll, eine + E-Mail-Adresse zu verwenden, da viele CGI-Skripte davon ausgehen. Wenn Sie + eine URL verwenden möchten, sollten Sie auf einem anderen unter Ihrer + Kontrolle stehenden Server verweisen. Andernfalls können Besucher Sie + im Fehlerfall möglicherweise nicht kontaktieren.

    + +

    Es kann sich lohnen, hierfür eine reservierte Adresse + anzugeben, z.B.

    + + + ServerAdmin www-admin@foo.example.com + + +

    da Anwender nicht unbedingt erwähnen, dass sie vom Server + sprechen!

    +
    +
    + + +ServerAlias +Alternativer Name für einen Host, der verwendet wird, wenn +Anfragen einem namensbasierten virtuellen Host zugeordnet werden +ServerAlias Hostname [Hostname] ... +virtual host + + +

    Die Direktive ServerAlias bestimmt die + alternativen Namen eines Hosts zur Verwendung mit namensbasierten virtuellen Hosts.

    + + + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +
    +
    +Apache-Dokumentation zu virtuellen + Hosts +
    + + +ServerName +Rechnername und Port, die der Server dazu verwendet, sich +selbst zu identifizieren +ServerName +voll-qualifizierter-Domainname[:port] +server configvirtual host + +Diese Direktive löst in Version 2.0 die + Funktionalität der Direktive Port aus + Version 1.3 ab. + + +

    Die Direktive ServerName bestimmt den + Rechnernamen und Port, den der Server dazu verwendet, sich selbst + zu identifizieren. Diese werden bei der Erstellung von Umleitungs-URLs + benötigt. Wenn beispielsweise der Name der Maschine, die den Webserver + beherbergt, simple.example.com lautet, die Maschine jedoch + auch einen DNS-Alias www.example.com besitzt und Sie den + Webserver so identifizieren möchten, sollten Sie die folgende + Anweisung verwenden:

    + + + ServerName www.example.com:80 + + +

    Wenn kein ServerName angegeben wurde, + dann versucht der Server den Rechnernamen mittels eines Reverse-Lookup + herzuleiten. Wenn kein Port in der + ServerName-Anweisung angegeben wurde, dann + verwendet der Server den Port der eingegangenen Anfrage. Für eine + optimale Zuverlässigkeit und Berechenbarkeit sollten Sie einen + eindeutigen Rechnernamen und Port angeben, in dem Sie die Direktive + ServerName verwenden.

    + +

    Wenn Sie namensbasierte + virtuelle Hosts verwenden, gibt ServerName + innerhalb eines VirtualHost-Abschnitts an, welcher + Hostname im Host:-Header der Anfrage auftauchen muss, + damit sie diesem virtuellen Host zugeordnet wird.

    + +

    Lesen Sie bitte die Beschreibung der Direktive UseCanonicalName für Einstellungen, die + bestimmen, ob selbstreferenzierende URLs (z.B. vom Modul + mod_dir) auf den angegebenen Port zeigen oder auf die + Portnummern die in der Anfrage des Clients angegeben ist.

    +
    + +Probleme bezüglich DNS und +Apache +Apache-Dokumentation zu virtuellen + Hosts +UseCanonicalName +NameVirtualHost +ServerAlias +
    + + +ServerPath +Veralteter URL-Pfad für einen namensbasierten +virtuellen Host, auf den von einem inkompatiblen Browser zugegriffen +wird +ServerPath URL-Pfad +virtual host + + +

    Die Direktive ServerPath legt den + veralteten Gemeint ist eigentlich "Altlast" aufgrund + antiquierter Clients. URL-Pfad eines Hosts zur Verwendung mit + namensbasierten virtuellen Hosts fest.

    +
    +Apache-Dokumentation zu virtuellen + Hosts +
    + + +ServerRoot +Basisverzeichnis der Serverinstallation +ServerRoot Verzeichnis +ServerRoot /usr/local/apache +server config + + +

    Die Direktive ServerRoot bestimmt das + Verzeichnis, in dem der Server installiert ist. Üblicherweise + enthält es die Unterverzeichnisse conf/ und + logs/. Relative Pfadangaben anderer Direktiven (wie z.B. + Include oder LoadModule) werden relativ zu diesem + Verzeichnis betrachtet.

    + + Beispiel + ServerRoot /home/httpd + +
    +Die httpd-Option + -d +Sicherheitshinweise + für Informationen, wie die Rechte auf das ServerRoot-Verzeichnis richtig gesetzt werden +
    + + +ServerSignature +Konfiguriert die Fußzeile von servergenerierten +Dokumenten +ServerSignature On|Off|EMail +ServerSignature Off +server configvirtual host +directory.htaccess + +All + + +

    Die Direktive ServerSignature ermöglicht + die Gestaltung einer unter servergenerierten Dokumenten (z.B. + Fehlerdokumente, FTP-Verzeichnislisten von mod_proxy, + mod_info-Ausgaben, ...) angefügten + Fußzeile. Ein möglicher Grund für die Aktivierung einer + solchen Fußzeile ist, dass der Anwender bei einer Kette von + Proxy-Servern oft keine Möglichkeit hat, zu erkennen, welcher der + verketteten Server gegenwärtig die zurückgegebene Fehlermeldung + produziert hat.

    + +

    Die (Vor-)Einstellung Off unterdrückt die + Fußzeile (und ist damit kompatibel zum Verhalten des Apache 1.2 und + früher). Die Einstellung On fügt schlicht eine + Zeile mit der Versionsnummer des Servers und dem Servernamen (ServerName) des bedienenden virtuellen Hosts an. + Die Einstellung EMail erstellt zusätzlich einen + "mailto:"-Verweis zum Serveradministrator (ServerAdmin) des referenzierten Dokuments.

    + +

    Ab Version 2.0.44 werden die Details der angegebenen Versionsnummer des + Servers von der Direktive ServerTokens kontrolliert.

    +
    +ServerTokens +
    + + +ServerTokens +Konfiguriert den HTTP-Response-Header +Server +ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full +ServerTokens Full +server config + + +

    die Direktive steuert, ob der Response-Header Server, + der an den Client zurückgesendet wird, eine Beschreibung des + allgemeinen Betriesbsystemtyps des Servers wie auch Informationen + über einkompilierte Module enthält.

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    Der Server sendet (z.B.): Server: + Apache
    + +
    ServerTokens Major
    + +
    Der Server sendet (z.B.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Der Server sendet (z.B.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    Der Server sendet (z.B.): Server: + Apache/2.0.41
    + +
    ServerTokens OS
    + +
    Der Server sendet (z.B.): Server: Apache/2.0.41 + (Unix)
    + +
    ServerTokens Full (oder nicht angegeben)
    + +
    Der Server sendet (z.B.): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2
    +
    + +

    Diese Einstellung gilt für den gesamten Server und kann nicht + auf Virtual-Host-Basis aktiviert oder deaktiviert werden.

    + +

    Ab Version 2.0.44 steuert diese Direktive auch die Informationen, die + durch die Direktive ServerSignature + angeboten werden.

    +
    +ServerSignature +
    + + +SetHandler +Erzwingt die Verarbeitung aller passenden Dateien durch +einen Handler +SetHandler Handlername|None +server configvirtual host +directory.htaccess + +FileInfo +Seit Apache 2.0 im Core + + +

    Wenn die Direktive innerhalb einer .htaccess-Datei + oder in einem Directory- oder + Location-Abschnitt + angegeben wird, erzwingt sie, dass alle entsprechenden Dateien von dem + durch Handlername angegebenen Handler analysiert werden. Wenn Sie + beispielsweise ein Verzeichnis haben, dessen Dateien unabhängig von + der Endung gänzlich als Image-Maps interpretiert werden sollen, + können Sie folgendes in eine .htaccess-Datei in + dem Verzeichnis schreiben:

    + + + SetHandler imap-file + + +

    Noch ein Beispiel: wenn Sie den Server immer, wenn die URL + http://servername/status aufgerufen wird, einen + Statusbericht anzeigen lassen möchten, dann können + Sie folgendes in die httpd.conf schreiben:

    + + + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +
    +

    Sie können eine zuvor definierte + SetHandler-Anweisung aufheben, indem Sie den Wert + None verwenden.

    +
    +AddHandler +
    + + +SetInputFilter +Bestimmt die Filter, die Client-Anfragen und POST-Eingaben +verarbeiten +SetInputFilter Filter[;Filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    Die Direktive SetInputFilter bestimmt den oder + die Filter, die Client-Anfragen und POST-Eingaben verarbeiten, wenn + sie vom Server empfangen werden. Diese gelten zusätzlich zu + anderweitig definierten Filtern, einschließlich denen der Direktive + AddInputFilter.

    + +

    Wenn mehr als ein Filter angegeben wird, dann müssen diese + durch Semikolon voneinander getrennt in der Reihenfolge angegeben werden, + in der sie die Daten verarbeiten sollen.

    +
    +Filter-Dokumentation +
    + + +SetOutputFilter +Bestimmt die Filter, die Antworten des Servers verarbeiten +SetOutputFilter Filter[;Filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    Die Direktive SetOutputFilter bestimmt + die Filter, die Antworten des Servers verarbeiten, bevor sie an den + Client gesendet werden. Diese gelten zusätzlich zu anderweitig + definierten Filtern, einschließlich denen der Direktive + AddOutputFilter.

    + +

    Die folgende Konfiguration verarbeitet zum Beispiel alle Dateien + im Verzeichnis /www/data als Server Side Includes.

    + + + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +
    + +

    Wenn mehr als ein Filter angegeben wird, dann müssen diese + durch Semikolon voneinander getrennt in der Reihenfolge angegeben werden, + in der sie die Daten verarbeiten sollen.

    +
    +Filter-Dokumentation +
    + + +TimeOut +Zeitspanne, die der Server auf verschiedene Ereignisse wartet, +bevor er die Anfrage abbricht +TimeOut Sekunden +TimeOut 300 +server config + + +

    Die Direktive TimeOut definiert derzeit die + Zeitspanne, die der Apache auf drei Dinge wartet:

    + +
      +
    1. Die gesamte Zeispanne, die benötigt wird, um eine GET-Anfrage + zu empfangen.
    2. + +
    3. Die Zeitspanne zwischen dem Empfang von TCP-Paketen einer + POST- oder PUT-Anfrage.
    4. + +
    5. Die Zeitspanne zwischen ACKs bei der Übermittlung der + TCP-Pakete der Antwort.
    6. +
    + +

    Wir haben vor, diese Zeitspannen in Zukunft separat konfigurierbar zu + machen. Vor Version 1.2 war der Zeitgeber auf 1200 voreingestellt, wurde + dann aber auf 300 herabgesetzt, was immer noch weit mehr ist, als in den + meisten Situationen benötigt wird. Die Voreinstellung wurde nicht + weiter herabgesetzt, da gelegentlich noch Stellen im Code existieren + können, wo der Zeitgeber nicht zurückgesetzt wird, wenn ein + Paket verschickt wird.

    +
    +
    + + +UseCanonicalName +Bestimmt, wie der Server seinen eigenen Namen und Port +ermittelt +UseCanonicalName On|Off|DNS +UseCanonicalName Off +server configvirtual host +directory + + +

    In vielen Situationen muss der Apache eine + selbstreferenzierende URL -- d.h. eine URL, die auf den selben + Server zurück verweist -- zusammenbauen. Bei UseCanonicalName + On verwendet der Apache den Hostnamen und Port, der in der + ServerName-Anweisung angegeben ist, + um den kanonischen Namen des Servers zu erstellen. Dieser Name wird in + allen selbstreferenzierenden URLs sowie in CGI-Skripten für die + Werte von SERVER_NAME und SERVER_PORT + verwendet.

    + +

    Bei UseCanonicalName Off bildet der Apache + selbstreferenzierende URLs, indem er den vom Client übermittelten + Hostnamen und Port verwendet, sofern diese vorhanden sind (andernfalls + wird der kanonische Name, wie oben beschrieben, benutzt). Die Werte + sind die gleichen, die zur Anwendung von namensbasierten virtuellen Hosts + verwendet werden, und sie sind mit den gleichen Clients verfügbar + , die auch in der Lage sind, auf namensbasierte virtuelle Hosts + zuzugreifen, d.h. einen Host-Header mitschicken. + Die CGI-Variablen SERVER_NAME und SERVER_PORT + werden ebenfalls aus den vom Client angeboten Werten erstellt.

    + +

    Ein Intranet-Server, auf den Anwender mit kurzen Namen wie + www zugreifen, ist ein Beispiel, wo dies sinnvoll sein kann. + Sie werden bemerken, dass der Apache den Benutzer auf + http://www.domain.com/splat/ umleitet, wenn dieser einen + Kurznamen und eine URL, die einem Verzeichnis entspricht, ohne + abschließenden Schrägstrich eingibt, wie z.B. + http://www/splat. Wenn Sie Authentisierung aktiviert haben, + bewirkt dies, dass der Benutzer sich zweimal identifizieren muss + (einmal für www und noch einmal für + www.domain.com -- lesen Sie für weitere Informationen die + FAQ zu diesem Thema). Wenn UseCanonicalName + jedoch auf Off gesetzt ist, denn wird der Apache zu + http://www/splat/ umleiten.

    + +

    Es existiert noch eine dritte Option, UseCanonicalName DNS, + die für den Betrieb von IP-basierten Massen-Virtual-Hosts gedacht ist, + um antiquierte Clients zu unterstützen, die keinen + Host:-Header bereit stellen. Um selbstreferenzierende + URLs zu ermitteln, führt der Apache bei dieser Option ein + Reverse-DNS-Lookup auf die IP-Adresse des Servers aus, zu der der Client + Verbindung aufgenommen hat.

    + + Warnung +

    Wenn CGI-Skripte Vermutungen aufgrund des Wertes von + SERVER_NAME anstellen, können sie durch diese + Option fehlschlagen. Clients steht es im Wesentlichen frei, einen Wert + für den Hostnamen anzugeben, wie er will. Wenn das + CGI-Skript SERVER_NAME jedoch lediglich dazu verwendet, + selbstreferenzierende URLs zu erstellen, sollte das gerade noch + in Ordnung sein.

    +
    +
    +ServerName +Listen +
    + + +VirtualHost +Enthält Direktiven, die nur auf bestimmte Hostnamen oder +IP-Adressen angewendet werden +<VirtualHost + Adresse[:Port] [Adresse[:Port]] + ...> ... </VirtualHost> +server config + + +

    VirtualHost und + </VirtualHost> werden dazu verwendet, eine Gruppe + von Direktiven zusammenzufassen, die nur auf einen bestimmten virtuellen + Host angewendet werden. Jede Direktive, die im Virtual-Host-Kontext + zulässig ist, kann verwendet werden. Wenn der Server eine Anfrage + für ein bestimmtes Dokument eines bestimmten virtuellen Hosts + empfängt, dann benutzt er die im + VirtualHost-Container enthaltenen + Konfigurationsanweisungen. Adresse kann sein:

    + +
      +
    • Die IP-Adresse des virtuellen Hosts.
    • + +
    • Ein voll qualifizierter Domainname für die IP-Adresse des + virtuellen Hosts.
    • + +
    • Das Zeichen *, welches nur in Kombination mit + NameVirtualHost * verwendet wird, um allen IP-Adressen + zu entsprechen.
    • + +
    • Die Zeichenkette _default_, die nur mit IP-basierten + virtuellen Hosts verwendet wird, um nicht zugewiesene IP-Adressen + aufzufangen.
    • +
    + + Beispiel + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +
    + +

    IPv6-Adressen müssen in eckigen Klammern angegeben werden, da die + optionale Portnummer sonst nicht erkannt werden kann. Hier ein + IPv6-Beispiel:

    + + + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +
    + +

    Jeder virtuelle Host muss einer anderen IP-Adresse, einem anderen Port + oder einem anderen Hostnamen für den Server entsprechen. Im ersten + Fall muss die Servermaschine so eingerichtet sein, dass sie IP-Pakete + für mehrere Adressen akzeptiert. (Wenn der Rechner nicht mehrere + Netzwerkkarten besitzt, kann dies mit dem Befehl ifconfig + alias durchgeführt werden -- sofern Ihr Betriebssystem das + unterstützt).

    + + Anmerkung +

    Die Verwendung von VirtualHost + beeinflusst nicht, an welchen Adressen der Apache + lauscht. Sie müssen mit Listen sicherstellen, dass der Apache + an der richtigen Adresse lauscht.

    +
    + +

    Bei der Verwendung IP-basierter virtuellen Hosts kann der spezielle + Name _default_ benutzt werden. In diesem Fall weist + der Apache jede IP-Adresse diesem virtuellen Host zu, die nicht explizit in + einem anderen virtuellen Host angegeben ist. Falls kein virtueller Host + _default_ angegeben ist, wird die "Hauptserver"-Konfiguration, + die aus allen Definitionen außerhalb der Virtual-Host-Abschnitte + besteht, für nicht passende IPs verwendet. (Beachten Sie jedoch, + dass eine IP-Adressen die zu einer NameVirtualHost-Anweisung passt, weder den + "Hauptserver" noch den virtuellen Host _default_ verwendet. + Lesen Sie für weitere Details die Dokumentation zu namensbasierten virtuell Hosts.)

    + +

    Sie können einen speziellen :Port angeben, + um den entsprechenden Port zu wechseln. Falls nicht angegeben, wird + er auf den gleichen Port voreingestellt, wie die letzte + Listen-Anweisung des + Hauptservers. Sie können auch :* angeben, um alle + Ports dieser Adresse zu akzeptieren. (Dies wird zusammen mit + _default_ empfohlen.)

    + + Sicherheit +

    Lesen Sie das Dokument Sicherheitshinweise für + Details, warum Ihre Sicherheit gefährdet sein kann, wenn das + Verzeichnis, in dem Protokolldateien gespeichert werden, für + jemanden anderes als den Benutzer beschreibbar ist, der den Server + gestartet hat.

    +
    +
    +Apache-Dokumentation zu virtuellen + Hosts +Probleme bezüglich DNS und + Apache +Bestimmen, welche Adressen und Ports + der Apache verwendet +Wie die Abschnitte <Directory>, + <Location> und <Files> arbeiten für eine + Erläuterung, wie diese verschiedenen Abschnitte miteinander + kombiniert werden, wenn eine Anfrage empfangen wird +
    + +
    diff --git a/trunk/docs/manual/mod/core.xml.ja b/trunk/docs/manual/mod/core.xml.ja new file mode 100644 index 0000000000..0f60f6f2e2 --- /dev/null +++ b/trunk/docs/manual/mod/core.xml.ja @@ -0,0 +1,3141 @@ + + + + + + + + + +core +$B>o$K;HMQ2DG=$J(B Apache HTTP $B%5!<%P$N%3%"5!G=(B +Core + + +AcceptPathInfo +$B8e$KB3$/%Q%9L>>pJs$r +AcceptPathInfo On|Off|Default +AcceptPathInfo Default +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 2.0.30 $B0J9_$G;HMQ2DG=(B + + + +

    $B$3$N%G%#%l%/%F%#%V$O(B ($B$b$7$/$OB8:_$9$k%G%#%l%/%H%j$N(B + $BB8:_$7$J$$%U%!%$%k(B) $B$N8e$KB3$/%Q%9L>>pJs$,$"$k%j%/%(%9%H$r>pJs$O%9%/%j%W%H$K$O(B PATH_INFO + $B4D6-JQ?t$H$7$FMxMQ2DG=$K$J$j$^$9!#(B

    + +

    $BNc$($P!"(B/test/ $B$,!"(Bhere.html $B$H$$$&%U%!%$%k(B + $B0l$D$N$_$,$"$k%G%#%l%/%H%j$r;X$7$F$$$k$H$7$^$9!#$=$&$9$k$H!"(B + /test/here.html/more $B$H(B /test/nothere.html/more + $B$X$N%j%/%(%9%H$ON>J}$H$b(B /more $B$r(B PATH_INFO $B$H$7$^$9!#(B

    + +

    AcceptPathInfo $B%G%#%l%/%F%#%V$K;XDj2DG=$J(B + $B;0$D$N0z?t$O(B:

    + +
    +
    Off
    $B%j%/%(%9%H$OB8:_$9$k%Q%9$K$=$N$^$^(B + $B%^%C%W$5$l$k>l9g$K$N$_e$NNc$N(B + /test/here.html/more $B$N$h$&$K!"K\Ev$N%U%!%$%kL>$N(B + $B8e$K%Q%9L>>pJs$,B3$/%j%/%(%9%H$K$O(B 404 NOT FOUND $B%(%i!<$,JV$j$^$9!#(B
    + +
    On
    $BA0$NJ}$N%Q%9$,B8:_$9$k%U%!%$%k$K%^%C%W$9$k>l9g$O(B + $B%j%/%(%9%H$,e$NNc$N(B /test/here.html/more + $B$O(B /test/here.html $B$,M-8z$J%U%!%$%k$K%^%C%W$9$l$P(B + $B + +
    Default
    $BB3$-$N%Q%9L>>pJs$N07$$$O%j%/%(%9%H$N(B + $B%O%s%I%i(B$B$G7h$^$j$^$9!#(B + $BIaDL$N%U%!%$%k$N$?$a$N%3%"%O%s%I%i$N%G%U%)%k%H$O(B PATH_INFO $B$r5qH]$7$^$9!#(B + cgi-script $B$d(B isapi-isa $B$N$h$&$K%9%/%j%W%H$r07$&%O%s%I%i$O(B + $B0lHLE*$K%G%U%)%k%H$G(B PATH_INFO $B$r +
    + +

    AcceptPathInfo $B$NPATH_INFO $B$r(B + $Be=q$-$G$-$k$h$&$K$9$k$3$H$G$9!#(B + $BNc$($P!"$3$l$ONc$($P(B INCLUDES $B$N$h$&$J(B + $B%U%#%k%?(B$B$r;H$C$F(B PATH_INFO $B$K(B + $B4p$E$$$F%3%s%F%s%D$r@8@.$7$F$$$k$H$-$KI,MW$K$J$j$^$9!#(B

    + + + <Files "mypaths.shtml">
    + + Options +Includes
    + SetOutputFilter INCLUDES
    + AcceptPathInfo On
    +
    + </Files> +
    +
    +
    + + +AccessFileName +$BJ,;6@_Dj%U%!%$%k$NL>A0(B +AccessFileName filename [filename] ... +AccessFileName .htaccess +server configvirtual host + + + +

    $B%j%/%(%9%H$r=hM}$9$k$H$-!"%5!<%P$O%G%#%l%/%H%j$K(B + $BBP$7$FJ,;6@_Dj%U%!%$%k$,(B$BM-8z$K$J$C$F$$$l$P(B$B!"(B + $B$=$N%I%-%e%a%s%H$X$N(B + $B%Q%9>e$K$"$kA4$F$N%G%#%l%/%H%j$+$i!"$3$3$G;XDj$5$l$?L>A0$N0lMw$NCf$G(B + $B:G=i$K8+$D$+$C$?%U%!%$%k$r$=$l$>$l@_Dj%U%!%$%k$H$7$FFI$_9~$_$^$9!#Nc$($P(B:

    + + + AccessFileName .acl + + +

    $B$H$$$&@_Dj$,$"$k$H!"0J2<$N$h$&$K$7$FL58z$K$5$l$F$$$J$$8B$j!"(B + $B%I%-%e%a%s%H(B /usr/local/web/index.html + $B$rJV$9A0$K!"%5!<%P$O(B /.acl, /usr/.acl, + /usr/local/.acl, /usr/local/web/.acl $B$+$i(B + $B%G%#%l%/%F%#%V$rFI$_9~$_$^$9!#(B

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory> +
    +
    +AllowOverride +$B@_Dj%U%!%$%k(B +.htaccess $B%U%!%$%k(B +
    + + +AddDefaultCharset +$B%l%9%]%s%9$N%3%s%F%s%H%?%$%W$,(B text/plain $B$"$k$$$O(B +text/html $B$N>l9g$KDI2C$9$k%G%U%)%k%H$N(B charset $B%Q%i%a!<%?(B +AddDefaultCharset On|Off|charset +AddDefaultCharset Off +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    $B%l%9%]%s%9$N%3%s%F%s%H%?%$%W$,(B text/plain + $B$"$k$$$O(B text/html + $B$N>l9g$K8B$j$^$9$,!"%l%9%]%s%9$KDI2C$9$k%a%G%#%"%?%$%W$NJ8;z%;%C%H%Q%i%a!<%?(B + ($BJ8;z%(%s%3!<%G%#%s%0$NL>A0(B) $B$N%G%U%)%k%HCM$r!"$3$N%G%#%l%/%F%#%V$G;XDj$7$^$9!#(B + $B$3$l$O%l%9%]%s%9(B $B%l%9%]%s%9$N(B HTML $BFb$G(B META + $BMWAG$G;XDj$5$l$?!"$I$N$h$&$JJ8;z%;%C%H$bL58z$K$7$^$9$,!"(B + $B:G=*E*$J5sF0$O%f!<%6$N%/%i%$%"%s%HB&$N@_Dj$G7h$^$j$^$9!#(B + $B$3$N5!G=$O(B AddDefaultCharset Off $B$H$$$&@_Dj$GL58z$K$J$j$^$9!#(B + AddDefaultCharset On $B$K$9$l$P!"(B + Apache $BFbIt$N%G%U%)%k%HJ8;z%;%C%H(B iso-8859-1 $B$K@_Dj$5$l$^$9!#(B + $B$=$NB>(B charset $B$K;XDj$G$-$kCM$G$"$l$P!"$I$s$JCM$G$b;H$($^$9!#(B + $B;XDj$9$kCM$O!"(BMIME $B%a%G%#%"%?%$%W$H$7$F;H$o$l$k(B + IANA + $B$KEPO?$5$l$F$$$kJ8;z%;%C%HL>(B$B$N$&$A$N0l$D$K$9$Y$-$G$9!#(B + $BNc$($P(B:

    + + + AddDefaultCharset utf-8 + + +

    AddDefaultCharset $B$r;H$&$H$-$O!"A4$F$N%F%-%9%H%j%=!<%9$,(B + $B;XDj$9$kJ8;z%(%s%3!<%I$K$J$C$F$$$k$HJ,$+$C$F$$$F!"$+$D!"(B + $B%j%=!<%9$N8D!9$KJ8;z%;%C%H$r;XDj$9$k$N$,BgJQ$J>l9g$N$_$G$9!#(B + $BNc$r5s$2$k$H!"%l%,%7!<$J(B CGI $B%9%/%j%W%H$J$I$N!"F0E*$K@8@.$5$l$k(B + $B%3%s%F%s%D$r4^$`%j%=!<%9$KJ8;z%;%C%H%Q%i%a!<%?$rDI2C$9$k>l9g$G!"(B + $B%f!<%6$NF~NO%G!<%?$,=PNO$KF~$j!"%/%m%9%5%$%H%9%/%j%W%F%#%s%0$,(B + $B0z$-5/$3$5$l$&$k>l9g$G$9!#%G%U%)%k%HJ8;z%;%C%H$r%;%C%H$7$?$H$7$F$b!"(B + $B%V%i%&%6$N(B "$BJ8;z%(%s%3!<%I$N<+F0A*Br(B" $B5!G=$,M-8z$K$J$C$F$$$k%f!<%6$r(B + $B + +AddCharset + + + +AddOutputFilterByType +MIME-type $B$K=PNO%U%#%k%?$r3d$jEv$F$k(B +AddOutputFilterByType filter[;filter...] MIME-type +[MIME-type] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 2.0.33 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O1~Ez$N(B MIME-type $B$K1~$8$F=PNO(B$B%U%#%k%?(B$B$r;HMQ$9$k$h$&$K$7$^$9!#(B

    + +

    $Bmod_deflate $B$N(B DEFLATE $B%U%#%k%?$r(B + $B;H$C$F$$$^$9!#(Btext/html $B$H(B text/plain $B$N(B + $B$9$Y$F$N=PNO(B ($B@EE*$J$b$N$bF0E*$J$b$N$b(B) $B$r%/%i%$%"%s%H$KAw$i$l$kA0$K(B + $B05=L$7$^$9!#(B

    + + + AddOutputFilterByType DEFLATE text/html text/plain + + +

    $BJ#?t$N%U%#%k%?$G%3%s%F%s%D$r=hM}$5$;$?$$$H$-$O!"$=$l$>$l$NL>A0$r%;%_%3%m%s$G(B + $BJ,$1$kI,MW$,$"$j$^$9!#3F%U%#%k%?$KBP$7$F(B + AddOutputFilterByType $B$r0l$D$:$D=q$/$3$H$b$G$-$^$9!#(B

    + +

    $Btext/html $B$N%9%/%j%W%H$N$9$Y$F$N=PNO$r(B + $B$^$:(B INCLUDES $B%U%#%k%?$G=hM}$7!"$5$i$K(B DEFLATE $B%U%#%k%?$K$+$1$^$9!#(B

    + + + <Location /cgi-bin/>
    + + Options Includes
    + AddOutputFilterByType INCLUDES;DEFLATE text/html
    +
    + </Location> +
    + + $BCm(B: +

    AddOutputFilterByType $B%G%#%l%/%F%#%V$K$h$j(B + $BM-8z$K$7$?%U%#%k%?$O>l9g$K$h$C$F$O!"ItJ,E*$b$7$/$O40A4$KE,MQ$5$l$J$$$3$H$,(B + $B$"$j$^$9!#Nc$($P!"(BMIME $B%?%$%W$,$,7hDj$G$-$J$$$H$-$K$O(B + DefaultType $B$N@_Dj$,F1$8$@$C$?$H$7$F$b!"(B + DefaultType $B@_Dj$r;H$&$h$&$K$J$j$^$9!#(B

    +

    $B$7$+$7!"3NAddType $B%G%#%l%/%F%#%V$d(B + ForceType $B%G%#%l%/%F%#%V$r;H$$$^$9!#(B + (nph$B$G$J$$(B) CGI $B%9%/%j%W%H$G%3%s%F%s%H%?%$%W$r@_Dj$9$k$H$$$&$b$N$G$b(B + $BBg>fIW$G$9!#(B

    + +

    $B%?%$%WKh$N=PNO%U%#%k%?$O%W%m%-%7%j%/%(%9%H$K$O7h$7$FE,MQ$5$l$^$;$s!#(B

    +
    +
    + +AddOutputFilter +SetOutputFilter +$B%U%#%k%?(B +
    + + +AllowEncodedSlashes +URL $BCf$NId9f2=$5$l$?%Q%9J,N%J8;z$,@h$KEA$($i$l$k$N$r5v2D$9$k$+$I$&$+$r(B +$B7hDj$9$k(B +AllowEncodedSlashes On|Off +AllowEncodedSlashes Off +server configvirtual host + +Apache 2.0.46 $B0J9_$G;HMQ2DG=(B + + +

    AllowEncodedSlashes $B%G%#%l%/%F%#%V$OId9f2=$5$l$?(B + $B%Q%9J,N%J8;z(B (/ $B$O(B %2F$B!"$5$i$K%7%9%F%`$K$h$C$F$O(B + \ $B$KBP1~$9$k(B %5C) $B$,B8:_$9$k(B URL $B$N;HMQ$r(B + $B5v2D$9$k$+$I$&$+$r7hDj$7$^$9!#DL>o$O$=$N$h$&$J(B URL $B$O(B 404 (Not found) $B%(%i!<(B + $B$G5qH]$5$l$^$9!#(B

    + +

    AllowEncodedSlashes On $B$K$h$k(B + $B%Q%9J,N%J8;z$N;HMQ$O!"(BPATH_INFO $B$H9g$o$;$F(B + $B;H$&$H$-$K0lHVLr$KN)$A$^$9!#(B

    +

    Turning AllowEncodedSlashes On is + mostly useful when used in conjunction with PATH_INFO.

    + + $BCm(B +

    $BId9f2=$5$l$?%9%i%C%7%e$r5v2D$9$k$3$H$O!"(B$BI|9f(B$B$r$9$k$3$H$r(B + $B0UL#(B$B$7$^$;$s(B$B!#(B%2F $B$d(B ($B4X78$9$k%7%9%F%`$G$N(B) + %5C $B$O!"B>$NItJ,$,I|9f$5$l$?(B URL $B$NCf$G$b$=$N$^$^$N7A<0$G(B + $B;D$5$l$^$9!#(B

    +
    +
    +AcceptPathInfo +
    + + + +AllowOverride +.htaccess $B$G5v2D$5$l$k%G%#%l%/%F%#%V$N +AllowOverride All|None|directive-type +[directive-type] ... +AllowOverride All +directory + + +

    $B%5!<%P$,(B (AccessFileName $B$K$h$C$F;XDj$5$l$?(B) + .htaccess $B%U%!%$%k$r8+$D$1$?;~!"$=$N%U%!%$%k$NCf$G(B + $B@k8@$5$l$?$I$N%G%#%l%/%F%#%V$,$h$jA0$KDj5A$5$l$?@_Dj%G%#%l%/%F%#%V$r(B + $B>e=q$-$G$-$k$+$rCN$kI,MW$,$"$j$^$9!#(B

    + + <Directory> $B%;%/%7%g%s$G$N$_;HMQ2DG=(B + AllowOverride $B$O@55,I=8=L5$7$N(BDirectory + $B%;%/%7%g%s$G$N$_M-8z$G!"(BLocation $B$d(B DirectoryMatch + $B$d(B Files $B%;%/%7%g%s$G$OL58z$G$9!#(B + + +

    $B$3$N%G%#%l%/%F%#%V$r(B None $B$K@_Dj$9$k$H!"(B.htaccess $B%U%!%$%k$O40A4$K(B + $BL5;k$5$l$^$9!#(B + $B$3$N>l9g!"%5!<%P$O%U%!%$%k%7%9%F%`$N(B .htaccess $B%U%!%$%k$rFI$`$3$H$r(B + $B;n$_$5$($7$^$;$s!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$,(B All $B$K@_Dj$5$l$F$$$k;~$K$O!"(B + .htaccess $B$H$$$&(B $B%3%s%F%-%9%H(B $B$r;}$D(B + $BA4$F$N%G%#%l%/%F%#%V$,MxMQ$G$-$^$9!#(B

    + +

    directive-type $B$K$O!"0J2<$N%G%#%l%/%F%#%V72$N(B + $B%-!<%o!<%I$N$I$l$+$r;XDj$7$^$9!#(B

    + +
    +
    AuthConfig
    + +
    + + $BG'>Z$K4X$9$k%G%#%l%/%F%#%V$N;HMQ$r5v2D$9$k(B (AuthDBMGroupFile, + AuthDBMUserFile, + AuthGroupFile, + AuthName, + AuthType, AuthUserFile, Require $B$J$I(B)$B!#(B
    + +
    FileInfo
    + +
    + $B%I%-%e%a%s%H%?%$%W$r@)8f$9$k$?$a$N%G%#%l%/%F%#%V$N;HMQ$r5v2D$9$k(B (DefaultType, ErrorDocument, ForceType, LanguagePriority, + SetHandler, SetInputFilter, SetOutputFilter, + mod_mime $B$N(B Add* $B$H(B Remove* + $B%G%#%l%/%F%#%V(B$B$J$I(B)$B!#(B
    + +
    Indexes
    + +
    + $B%G%#%l%/%H%j%$%s%G%C%/%9$r@)8f$9$k$?$a$N%G%#%l%/%F%#%V$N;HMQ$r5v2D$9$k(B + (AddDescription, + AddIcon, AddIconByEncoding, + AddIconByType, + DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName + $B$J$I(B)$B!#(B
    + +
    Limit
    + +
    + $B%[%9%H$X$N%"%/%;%9@)8f$r9T$&$?$a$N%G%#%l%/%F%#%V$N;HMQ$r5v2D$9$k(B (Allow, Deny, Order).
    + +
    Options[=Option,...]
    + +
    + $BFCDj$N%G%#%l%/%H%j$K$*$1$k5!G=$r;XDj$9$k$?$a$N%G%#%l%/%F%#%V$N;HMQ$r5v2D$9$k(B + (Options $B$H(B + XBitHack)$B!#(B + Options $B$G@_Dj$9$k%*%W%7%g%s(B + $B$r!"(B($B6uGr$r4^$a$J$$(B) $B%3%s%^6h@Z$j$N%j%9%H$K$7$FEy9f$N8e$KB3$1$k$3$H$G(B + $B@_Dj$G$-$^$9!#(B
    +
    + +

    $BNc(B:

    + + + AllowOverride AuthConfig Indexes + + +

    $B>e$NNc$G$O(B AuthConfig $B$H(B Indexes $B$N$I$A$i$K$b(B + $BB0$5$J$$%G%#%l%/%F%#%V$O$9$Y$FFbIt%5!<%P%(%i!<$r0z$-5/$3$7$^$9!#(B

    +
    + +AccessFileName +$B@_Dj%U%!%$%k(B +.htaccess $B%U%!%$%k(B +
    + + +AuthName +HTTP $BG'>Z$NG'2DNN0h(B ($BLuCm(B: realm) +AuthName auth-domain +directory.htaccess + +AuthConfig + + +

    $B$3$N%G%#%l%/%F%#%V$O%G%#%l%/%H%j$KBP$9$kG'2DNN0h(B ($BLuCm(B: realm) + $B$NL>A0$r;XDj$7$^$9!#(B + $BG'2DNN0h$O!"MxMQ$H%Q%9%o!<%I$rAw?.$9$l$P$h$$$N$+$r(B + $B%/%i%$%"%s%H$K65$($k$?$a$KMxMQ$7$^$9!#(B + AuthName $B$O0l$D$N0z?t$r$H$j!"(B + $B%9%Z!<%9$,4^$^$l$k>l9g$K$O!"(B + $B0zMQId$G3g$i$J$1$l$P$J$j$^$;$s!#(B + $B$3$N%G%#%l%/%F%#%V$O(B + AuthType $B%G%#%l%/%F%#%V$d(B + Require $B%G%#%l%/%F%#%V$H!"(B + AuthUserFile $B$d(B + AuthGroupFile $B$J$I$N%G%#%l%/%F%#%V$H(B + $B0l=o$KMxMQ$9$kI,MW$,$"$j$^$9!#(B

    + +

    $BNc$($P(B:

    + + + AuthName "Top Secret" + + +

    $B$3$3$G(B AuthName $B$K;XDj$7$?J8;zNs$,!"(B + $BBgItJ,$N%V%i%&%6$N%Q%9%o!<%I%@%$%"%m%0$KI=<($5$l$^$9!#(B

    +
    +$BG'>Z!">5G'!"%"%/%;%9@)8f(B +
    + + +AuthType +$B%f!<%6G'>Z$N +AuthType Basic|Digest +directory.htaccess + +AuthConfig + + +

    $B$3$N%G%#%l%/%F%#%V$OBP>]%G%#%l%/%H%j$GMxMQ$9$k%f!<%6!Z$NBasic $B$H(B Digest $B$7$+(B + $BAuthName$B%G%#%l%/%F%#%V$d(B + Require $B%G%#%l%/%F%#%V$H!"(B + AuthUserFile $B$d(B AuthGroupFile $B$J$I$N%G%#%l%/%F%#%V$H(B + $B0l=o$KMxMQ$9$kI,MW$,$"$j$^$9!#(B

    +
    +$BG'>Z!">5G'!"%"%/%;%9@)8f(B +
    + + +CGIMapExtension +CGI $B%9%/%j%W%H$N%$%s%?!<%W%j%?$N0LCV$rD4$Y$k$?$a$N +CGIMapExtension cgi-path .extension +None +directory.htaccess + +FileInfo +NetWare $B$N$_(B + + +

    $B$3$N%G%#%l%/%F%#%V$O(B Apache $B$,(B CGI $B%9%/%j%W%H$rCGIMapExtension sys:\foo.nlm .foo $B$H@_Dj$9$k$H(B + .foo $B$H$$$&3HD%;R$N$9$Y$F$N(B CGI $B%9%/%j%W%H$O(B FOO $B%$%s%?!<%W%j%?$K(B + $BEO$5$l$^$9!#(B

    +
    +
    + + +ContentDigest +Content-MD5 HTTP $B1~Ez%X%C%@$N@8@.$rM-8z$K$9$k(B +ContentDigest On|Off +ContentDigest Off +server configvirtual host +directory.htaccess + +Options +Experimental + + +

    $B$3$N%G%#%l%/%F%#%V$O!"(BRFC1864 $B5Z$S(B RFC2068 $B$K$*$$$FDj5A$5$l$F$$$k(B + Content-MD5 $B%X%C%@!<$N@8@.$rM-8z$K$7$^$9!#(B

    + +

    MD5 $B$O!"G$0UD9$N%G!<%?$N!V%a%C%;!<%8%@%$%8%'%9%H!W(B($B!V;XLf!W(B + $B$HI=8=$5$l$k$3$H$b$"$k(B) $B$r7W;;$9$k%"%k%4%j%:%`$G!"(B + $B%G!<%?$NJQ99$,$"$C$?>l9g$K$OHs>o$K9b$$?.MjEY$G%a%C%;!<%8%@%$%8%'%9%H$KJQ99$,(B + $BH?1G$5$l$^$9!#(B

    + +

    Content-MD5 $B%X%C%@$O!"%(%s%I%D!<%(%s%I$G(B + $B%(%s%F%#%F%#%\%G%#!<$K4^$^$l$k%a%C%;!<%8$N40A4@-%A%'%C%/(B + (Message Integrity Check - MIC)$B$rDs6!$7$^$9!#(B + $B$3$N%X%C%@$rD4$Y$k$3$H$G!"%W%m%-%7$d%/%i%$%"%s%H$O!"(B + $BESCf7PO)$K$*$1$k%(%s%F%#%F%#%\%G%#$NM=4|$;$LJQ99$J$I$r(B + $B8!=P$9$k$3$H$,$G$-$^$9!#%X%C%@$NNc(B:

    + + + Content-MD5: AuLb7Dp1rqtRtxz2m9kRpA== + + +

    $B%j%/%(%9%HKh$K%a%C%;!<%8%@%$%8%'%9%H$r7W;;$9$k(B ($BCM$O%-%c%C%7%e$5$l$^$;$s(B) + $B$3$H$+$i!"(B + $B%5!<%P%Q%U%)!<%^%s%9$,Dc2<$9$k$3$H$K$D$$$FCm0U$7$F$/$@$5$$!#(B

    + +

    Content-MD5$B$O!"(Bcore $B5!G=$K$h$j=hM}$5$l$?(B + $B%I%-%e%a%s%H$rAw$k$H$-$N$_M-8z$G$"$j!"(B + SSI $B%I%-%e%a%s%H$d(B CGI $B%9%/%j%W%H$N=PNO!"%P%$%H%l%s%8$r;XDj$7$?(B + $B1~Ez$N>l9g$K$O$3$N%X%C%@$OIUM?$5$l$^$;$s!#(B +

    +
    +
    + + +DefaultType +$B%5!<%P$,%3%s%F%s%H%?%$%W$r7hDj$G$-$J$$$H$-$K(B +$BAw$i$l$k(B MIME $B%3%s%F%s%H%?%$%W(B +DefaultType MIME-type +DefaultType text/plain +server configvirtual host +directory.htaccess + +FileInfo + + +

    $B%5!<%P$O!"(BMIME $B$N%?%$%W%^%C%W$+$i$O7hDj$G$-$J$$(B + $B%I%-%e%a%s%H$NAw?.$rMW5a$5$l$k$3$H$,$"$j$^$9!#(B

    + +

    $B%5!<%P$O!"%I%-%e%a%s%H$N%3%s%F%s%H%?%$%W$r%/%i%$%"%s%H$KDLCN$9$kI,MW$,(B + $B$"$j$^$9$N$G!"$3$N$h$&$K%?%$%W$,L$CN$N>l9g$O(B + DefaultType $B$G;XDj$5$l$?%?%$%W$rMxMQ$7$^$9!#(B + $BNc(B:

    + + + DefaultType image/gif + + +

    $B$3$l$O(B .gif $B$H$$$&3HD%;R$,%U%!%$%kL>$K4^$^$l$F$$$J$$(B + $BB?$/$N(B GIF $B2hA|$,4^$^$l$F$$$k%G%#%l%/%H%j$KE,$7$F$$$k$G$7$g$&!#(B

    + +

    ForceType $B%G%#%l%/%F%#%V$H(B + $B0c$C$F!"$3$N%G%#%l%/%F%#%V$O%G%U%)%k%H$N(B MIME $B%?%$%W$rDs6!$9$k$@$1$G(B + $B$"$k$3$H$KCm0U$7$F$/$@$5$$!#%U%!%$%kL>$N3HD%;R$r4^$a!"(B + $B%a%G%#%"%?%$%W$r7hDj$G$-$kB>$N(B MIME $B%?%$%W$NDj5A$,$"$l$P(B + $B$3$N%G%U%)%k%H$O>e=q$-$5$l$^$9!#(B

    +
    +
    + + +Directory +$B;XDj$N%U%!%$%k%7%9%F%`$N%G%#%l%/%H%j$H%5%V%G%#%l%/%H%j$H$N$_$K(B +$BE,MQ$5$l$k%G%#%l%/%F%#%V$r0O$`(B +<Directory directory-path> +... </Directory> +server configvirtual host + + + +

    $B;XDj$5$l$?%G%#%l%/%H%j$H$=$N%5%V%G%#%l%/%H%j$K$N$_(B + $B%G%#%l%/%F%#%V$rE,MQ$5$;$k$?$a$K$O!"(B + Directory $B$H(B + </Directory> $B$rBP$H$7$F!"%G%#%l%/%F%#%V72$r0O$$$^$9!#(B + $B$=$NCf$K$O!"%G%#%l%/%H%j%3%s%F%-%9%H$G5v2D$5$l$?A4$F$N%G%#%l%/%F%#%V$r(B + $BMxMQ$G$-$^$9!#(B + directive-path $B$O!"%U%k%Q%9$b$7$/$O(B Unix $B$N%7%'%k7A<0$N(B + $B%o%$%k%I%+!<%I$r;XDj$7$^$9!#(B + ? $B$OG$0U$N(B 1 $BJ8;z!"(B* $B$OG$0U$NJ8;zNs$K%^%C%A$7$^$9!#(B + $B%7%'%k$K$*$1$k;XDjF1MM!"J8;z$NHO0O$r(B [] $B$G;XDj$G$-$^$9!#(B + $B%o%$%k%I%+!<%I$O(B `/' $BJ8;z$K$O%^%C%A$7$^$;$s$N$G!"(B + /home/user/public_html $B$K$O(B + <Directory /*/public_html> $B$O%^%C%A$7$^$;$s$,!"(B + <Directory /home/*/public_html> $B$O%^%C%A$7$^$9!#(B + $BNc(B:

    + + + <Directory /usr/local/httpd/htdocs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory> +
    + + +

    directory-path $B0z?t$K$OCm0U$7$F$/$@$5$$(B: $B$=$N0z?t$O(B +Apache $B$,%U%!%$%k$r%"%/%;%9$9$k$?$a$K;H$&%U%!%$%k%7%9%F%`$N%Q%9$K(B +$B$=$N$^$^%^%C%A$9$kI,MW$,$"$j$^$9!#$"$k(B <Directory> $B$K(B +$BE,MQ$5$l$k%G%#%l%/%F%#%V$O!"JL$N%7%s%\%j%C%/%j%s%/$r$?$I$C$?$j$7$F(B +$BF1$8%G%#%l%/%H%j$r0c$&%Q%9$G%"%/%;%9$7$?>l9g$K$OE,MQ$5$l$^$;$s!#(B

    +
    + +

    ~ $B$H$$$&J8;z$r(B + $BIU2C$9$k$3$H$G3HD%@55,I=8=$rMxMQ$9$k$3$H$b$G$-$^$9!#(B + $BNc$($P(B:

    + + + <Directory ~ "^/www/.*/[0-9]{3}"> + + +

    $B$H$$$C$?;XDj$N>l9g!"(B/www/ $B0J2<$K$"$k?t;z(B + 3 $BJ8;z$N%G%#%l%/%H%j$K%^%C%A$7$^$9!#(B

    + +

    $B$b$7J#?t$N(B ($B@55,I=8=0J30$N(B) Directory$B%;%/%7%g%s$,(B + $B%I%-%e%a%s%H$r4^$`%G%#%l%/%H%j(B ($B$d$=$N>e0L%G%#%l%/%H%j$N$I$l$+(B) $B$H%^%C%A$7$?$J$i$P!"(B + .htaccess $B%U%!%$%k$N%G%#%l%/%F%#%V$bFI$_9~$_$D$D!"(B + $BC;$$%Q%9$+$i=g$KE,MQ$5$l$^$9!#(B + $BNc$($P!"(B

    + + + <Directory />
    + + AllowOverride None
    +
    + </Directory>
    +
    + <Directory /home/>
    + + AllowOverride FileInfo
    +
    + </Directory> +
    + +

    $B$H@_Dj$7!"%I%-%e%a%s%H(B /home/web/dir/doc.html $B$X$N(B + $B%"%/%;%9$,$"$C$?>l9g$K$O0J2<$N$h$&$KF0:n$7$^$9(B:

    + +
      +
    • AllowOverride None $B$,E,MQ$5$l$k!#(B + (.htaccess $B%U%!%$%k$OL58z$K$J$k(B)
    • + +
    • AllowOverride FileInfo $B$,E,MQ$5$l$k(B + (/home $B%G%#%l%/%H%j$KBP$7$F(B)$B!#(B
    • + +
    • /home/.htaccess, /home/web/.htaccess, + /home/web/.htaccess $B$N=g$K$=$l$i$N%U%!%$%kCf$N(B + FileInfo $B%G%#%l%/%F%#%V$,E,MQ$5$l$k!#(B
    • +
    + +

    $B@55,I=8=$O!"DL>o$N%;%/%7%g%s$,$9$Y$FE,MQ$5$l$k$^$G(B + $B9MN8$5$l$^$;$s!#(B + $B$=$N8e!"A4$F$N@55,I=8=$,@_Dj%U%!%$%k$K8=$l$?=g$G;n$5$l$^$9!#(B + $BNc$($P!"0J2<$N$h$&$J>l9g$K(B

    + + + <Directory ~ abc$>
    + + # ... directives here ...
    +
    + </Directory> +
    + +

    $B@55,I=8=$N%;%/%7%g%s$O$9$Y$F$NDL>o$N(B Directory $B$H(B + .htaccess $B$NE,MQ$,=*$o$k$^$G9MN8$5$l$^$;$s!#(B + $B$=$N8e$G!"@55,I=8=$O(B /home/abc/public_html/abc $B$K%^%C%A$7!"(B + $BBP1~$9$k(B Directory $B$,E,MQ$5$l$^$9!#(B

    + +

    Apache $B$N%G%U%)%k%H$G$O(B <Directory /> $B$X$N%"%/%;%9$O(B + Allow from All $B$K$J$C$F$$$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$3$l$O!"(BURL $B$+$i%^%C%W$5$l$?$I$N%U%!%$%k$G$b(B Apache $B$OAw$k$H$$$&$3$H$G$9!#(B + $B$3$l$O0J2<$N$h$&$K$7$FJQ99$9$k$3$H$,?d>)$5$l$F$$$^$9!#(B

    + + + <Directory />
    + + Order Deny,Allow
    + Deny from All
    +
    + </Directory> +
    + +

    $B$=$7$F%"%/%;%9$r(B$B2DG=$K$7$?$$(B$B%G%#%l%/%H%j$KBP$7$F(B + $B8DJL$K@_Dj$9$l$P$h$$$G$7$g$&!#(B + $B$3$N$"$?$j$K$D$$$F$O!"(B$B%;%-%e%j%F%#$K4X$9$k%3%D(B$B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    + +

    $B%G%#%l%/%H%j%;%/%7%g%s$O(B httpd.conf $B%U%!%$%k=q$-$^$9!#(B + Directory + $B%G%#%l%/%F%#%V$OF~$l;R$K$9$k$3$H$,$G$-$:!"(B + Limit $B$d(B LimitExcept $B%;%/%7%g%s$NCf$K$b(B + $B5-=R$G$-$^$;$s!#(B

    + +
    +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +DirectoryMatch +$B@55,I=8=$K%^%C%A$9$k%U%!%$%k%7%9%F%`$N%G%#%l%/%H%j$H(B +$B%5%V%G%#%l%/%H%j$H$N$_$KE,MQ$5$l$k%G%#%l%/%F%#%V$r0O$`(B +<DirectoryMatch regex> +... </DirectoryMatch> +server configvirtual host + + + +

    Directory + $B%G%#%l%/%F%#%V$HF1MM$K!"(BDirectoryMatch + $B$H(B </DirectoryMatch> $B$O;XDj$5$l$?%G%#%l%/%H%j$H(B + $B$=$N%5%V%G%#%l%/%H%j$K$N$_E,MQ$5$l$k%G%#%l%/%F%#%V72$r0O$$$^$9!#(B + $B$7$+$7!"$3$N%G%#%l%/%F%#%V$O0z?t$H$7$F@55,I=8=$r$H$j$^$9!#Nc$($P(B:

    + + + <DirectoryMatch "^/www/(.+/)?[0-9]{3}"> + + +

    $B$O(B /www/ $B0J2<$K$"$k?t;z(B 3 $BJ8;z$N%G%#%l%/%H%j$K%^%C%A$7$^$9!#(B

    + +
    +$BDL>o$N(B Directory $B$H@55,I=8=$N;XDj$,(B +$BE,MQ$5$l$k=gHV$K$D$$$F$O(B Directory +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +DocumentRoot +$B%&%'%V$+$i8+$($k%a%$%s$N%I%-%e%a%s%H%D%j!<$K$J$k(B +$B%G%#%l%/%H%j(B +DocumentRoot directory-path +DocumentRoot /usr/local/apache/htdocs +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O!"(Bhttpd + $B$,%U%!%$%k$rDs6!$9$k%G%#%l%/%H%j$r@_Dj$7$^$9!#(B + Alias $B$N$h$&$J%G%#%l%/%F%#%V$K%^%C%A$7$J$$>l9g$K$O!"(B + $B%I%-%e%a%s%H$N(B ($BLuCm(B:$B%U%!%$%k%7%9%F%`>e$N(B) $B%Q%9$r@8@.$9$k$?$a$K!"(B + $B%j%/%(%9%H$5$l$?(B URL $B$N%Q%9ItJ,$r%I%-%e%a%s%H%k!<%H$KIUM?$7$^$9!#(B + $BNc(B:

    + + + DocumentRoot /usr/web + + +

    $B$3$N>l9g!"(B + http://www.my.host.com/index.html $B$X$N%"%/%;%9$,$"$l$P(B + /usr/web/index.html $B$,JV$5$l$^$9!#(B + directory-path $B$,@dBP%Q%9$G$J$$>l9g$O!"(B + ServerRoot + $B$+$i$NAjBP%Q%9$H$_$J$5$l$^$9!#(B

    + +

    DocumentRoot $B$O:G8e$N%9%i%C%7%eL5$7$G(B + $B;XDj$9$kI,MW$,$"$j$^$9!#(B

    +
    +URL $B$r%U%!%$%k%7%9%F%`$N0LCV$K(B +$B%^%C%W$9$k(B +
    + + +EnableMMAP +$BG[AwCf$K%U%!%$%k$rFI$_9~$`$?$a$K%a%b%j%^%C%T%s%0$r(B +$B;H$&$+$I$&$+(B +EnableMMAP On|Off +EnableMMAP On +server configvirtual host +directory.htaccess + +FileInfo + + +

    $B$3$N%G%#%l%/%F%#%V$OG[AwCf$K%U%!%$%k$NFbMF$rFI$_9~$`I,MW$,$"$k$H$-$K(B + httpd $B$,%a%b%j%^%C%T%s%0$r;H$&$+$I$&$+$r@)8f$7$^$9!#(B + $B%G%U%)%k%H$G$O!"(B + $BNc$($P!"(Bmod_include $B$r;H$C$F(B SSI $B%U%!%$%k$rG[Aw(B + $B$9$k$H$-$N$h$&$K!"%U%!%$%k$NESCf$N%G!<%?$r%"%/%;%9$9$kI,MW$,$"$k$H$-$K$O(B + Apache $B$O(B OS $B$,%5%]!<%H$7$F$$$l$P%U%!%$%k$r%a%b%j$K%^%C%W$7$^$9!#(B

    + +

    + $B$3$N%a%b%j%^%C%W$O@-G=$N8~>e$r;}$?$i$9$3$H$,$"$j$^$9!#(B + $B$7$+$7!"4D6-$K$h$C$F$O1?MQ>e$NLdBj$rKI$0$?$a$K%a%b%j%^%C%T%s%0$r(B + $B;HMQ$7$J$$$h$&$K$7$?J}$,NI$$>l9g$b$"$j$^$9(B:

    + +
      +
    • $B%^%k%A%W%m%;%C%5%7%9%F%`$NCf$K$O%a%b%j%^%C%T%s%0$r$9$k$H(B + httpd $B$N@-G=$,Mn$A$k$b$N$,$"$j$^$9!#(B
    • +
    • NFS $B%^%&%s%H$5$l$?(B DocumentRoot + $B$G$O!"(Bhttpd $B$,%a%b%j%^%C%W$7$F$$$k4V$K%U%!%$%k$,:o=|$5$l$?$j(B + $BC;$/$J$C$?$j$7$?$H$-$K5/$3$k%;%0%a%s%F!<%7%g%s%U%)!<%k%H$N$?$a$K(B + httpd $B$,%/%i%C%7%e$9$k2DG=@-$,$"$j$^$9!#(B
    • +
    + +

    $B$3$l$i$NLdBj$KEv$F$O$^$k%5!<%P$N@_Dj$N>l9g$O!"0J2<$N$h$&$K$7$F(B + $B%U%!%$%k$NG[Aw;~$N%a%b%j%^%C%T%s%0$r;HMQIT2D$K$7$F$/$@$5$$(B:

    + + + EnableMMAP Off + + +

    NFS $B%^%&%s%H$5$l$?%U%!%$%k$K$O!"LdBj$N$"$k%U%!%$%k$K$N$_L@<(E*$K(B + $B$3$N5!G=$r;HMQIT2D$K$7$^$9(B:

    + + + <Directory "/path-to-nfs-files"> + + EnableMMAP Off + + </Directory> + +
    +
    + + +EnableSendfile +$B%U%!%$%k$N%/%i%$%"%s%H$X$NG[Aw;~$K%+!<%M%k$N(B sendfile $B%5%]!<%H$r(B +$B;H$&$+$I$&$+(B +EnableSendfile On|Off +EnableSendfile On +server configvirtual host +directory.htaccess + +FileInfo +$B%P!<%8%g%s(B 2.0.44 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O%/%i%$%"%s$K%U%!%$%k$NFbMF$rAw$k$H$-$K(B + httpd $B$,%+!<%M%k$N(B + sendfile $B%5%]!<%H$r;H$&$+$I$&$+$r@)8f$7$^$9!#%G%U%)%k%H$G$O!"(B + $BNc$($P@EE*$J%U%!%$%k$NG[Aw$N$h$&$K!"%j%/%(%9%H$N=hM}$K%U%!%$%k$N(B + $BESCf$N%G!<%?$N%"%/%;%9$rI,MW$H$7$J$$$H$-$K$O!"(BApache $B$O(B OS $B$,(B + $B%5%]!<%H$7$F$$$l$P%U%!%$%k$rFI$_9~$`$3$H$J$/(B sendfile $B$r;H$C$F(B + $B%U%!%$%k$NFbMF$rAw$j$^$9!#(B

    + +

    sendfile $B$O(B read $B$H(B send $B$rJL!9$K9T$J$&$3$H$H!"%P%C%U%!$N3d$jEv$F$r(B + $B2sHr$7$^$9!#$7$+$7!"%W%i%C%H%U%)!<%`$d%U%!%$%k%7%9%F%`$NCf$K$O(B + $B1?MQ>e$NLdBj$rHr$1$k$?$a$K$3$N5!G=$r;HMQIT2D$K$7$?J}$,NI$$>l9g$,$"$j$^$9(B:

    + +
      +
    • $B%W%i%C%H%U%)!<%`$NCf$K$O%S%k%I%7%9%F%`$,8!CN$G$-$J$+$C$?!"2u$l$?(B + sendfile $B$N%5%]!<%H$,B8:_$9$k$b$N$,$"$j$^$9!#$3$l$OFC$K(B + $B%P%$%J%j$,JL$N%^%7%s$G%S%k%I$5$l!"2u$l$?(B sendfile $B$N$"$k%^%7%s$K(B + $B0\F0$7$?$H$-$K5/$3$j$^$9!#(B
    • +
    • Linux $B$G$O!"(Bsendfile $B$rMQ$$$k$H!"(B + IPv6 $B;HMQ;~$KB8:_$9$kFCDj%M%C%H%o!<%/%+!<%I$N(B TCP-checksum + $B%*%U%m!<%I$N%P%0$rF'$s$G$7$^$$$^$9!#(B
    • +
    • $B%M%C%H%o!<%/%^%&%s%H$5$l$?(B DocumentRoot + ($BNc$($P(B NFS $B$d(B SMB) + $B$G$O!"%+!<%M%k$O<+?H$N%-%c%C%7%e$r;H$C$F%M%C%H%o!<%/$+$i$N%U%!%$%k$r(B + $BAw$k$3$H$,$G$-$J$$$3$H$,$"$j$^$9!#(B
    • +
    + +

    $B$3$l$i$NLdBj$KEv$F$O$^$k%5!<%P$N@_Dj$N>l9g$O!"0J2<$N$h$&$K$7$F(B + $B$3$N5!G=$r;HMQIT2D$K$7$F$/$@$5$$(B:

    + + + + EnableSendfile Off + + +

    NFS $B$d(B SMB $B%^%&%s%H$5$l$?%U%!%$%k$K$O!"LdBj$N$"$k%U%!%$%k$K$N$_L@<(E*$K(B + $B$3$N5!G=$r;HMQIT2D$K$7$^$9(B:

    + + + <Directory "/path-to-nfs-files"> + + EnableSendfile Off + + </Directory> + +
    +
    + + +ErrorDocument +$B%(%i!<$,H/@8$7$?$H$-$K%5!<%P$,%/%i%$%"%s%H$KAw$k$b$N(B +ErrorDocument error-code document +server configvirtual host +directory.htaccess + +FileInfo +Apache 2.0 $B$G$O%F%-%9%H$r%/%&%)!<%H$9$k9=J8$,0JA0$N%P!<%8%g%s$+$i(B +$BJQ$o$C$F$$$^$9!#(B + + +

    $BLdBj$d%(%i!<$,H/@8$7$?$H$-$NF0:n$H$7$F!"(B + Apache $B$K$O0J2<$N;M$D$N$&$A0l$D$NF0:n$r@_Dj$9$k$3$H$,$G$-$^$9!#(B

    + +
      +
    1. Apache $BI8=`$N4JC1$J%(%i!<%a%C%;!<%8$rI=<((B
    2. + +
    3. $B<+J,$G;XDj$7$?%a%C%;!<%8$rI=<((B
    4. + +
    5. $BLdBj$d%(%i!<$N=hM}$r$9$k0Y$K!"<+%5!<%PFb$N(B + URL-path $B$X%j%@%$%l%/%H(B
    6. + +
    7. $BLdBj$d%(%i!<$N=hM}$r$9$k0Y$K!"30It$N(B URL $B$X%j%@%$%l%/%H(B
    8. +
    + +

    $B:G=i$N$b$N$,%G%U%)%k%H$NF0:n$G!"(B2 $BHVL\$+$i(B 4 $BHVL\$O!"(B + ErrorDocument$B%G%#%l%/%F%#%V$K$h$j!"(B + HTTP $B$N%l%9%]%s%9%3!<%I$H!"%a%C%;!<%8$+(B URL $B$r;XDj$9$k$3$H$G@_Dj$7$^$9!#(B + Apache $B$,LdBj$b$7$/$O%(%i!<$K4X$9$kDI2C>pJs$rDs6!$9$k$3$H$,$"$j$^$9!#(B

    + +

    URL $B$N>l9g$O!"%9%i%C%7%e$G;O$^$k(B (/) $B%m!<%+%k$N(B web-path ( + DocumentRoot $B$+$i$NAjBP%Q%9(B + ) $B$+!"%/%i%$%"%s%H$,2r7h$G$-$k40A4$J(B URL $B$r;XDj$7$^$9!#(B + $B$b$7$/$O!"%V%i%&%6$KI=<($5$l$k%a%C%;!<%8$r;XDj$G$-$^$9!#(B + $BNc(B:

    + + + ErrorDocument 500 http://foo.example.com/cgi-bin/tester
    + ErrorDocument 404 /cgi-bin/bad_urls.pl
    + ErrorDocument 401 /subscription_info.html
    + ErrorDocument 403 "Sorry can't allow you access today" +
    + +

    $B2C$($F!"FCJL$JCM(B default $B$r;H$C$F(B Apache $B$K(B + $B%O!<%I%3!<%I$5$l$F$$$k4JC1$J%a%C%;!<%8$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $BDL>o$OI,MW$G$O$"$j$^$;$s$,!"(Bdefault $B$r;H$&$H(B + $B4{B8$N(B ErrorDocument $B%G%#%l%/%F%#%V$N@_Dj$r(B + $B7Q>5$9$k$H$3$m$G!"(BApache $B$N%O!<%I%3!<%I$5$l$?4JC1$J%a%C%;!<%8$K(B + $BLa$9$3$H$,$G$-$^$9!#(B

    + + + ErrorDocument 404 /cgi-bin/bad_urls.pl

    + <Directory /web/docs>
    + + ErrorDocument 404 default
    +
    + </Directory> +
    + +

    $B%j%b!<%H(B URL ($BNc$($P!"F,$K(B http $B$HIUM?$7$?J}K!(B) $B$r(B + ErrorDocument $B$K;XDj$9$k$H$-!"(B + $B$?$H$(J8=q$,F1$8%5!<%P$K$"$m$&$H$b!"%I%-%e%a%s%H$,$I$3$K$"$k$+$rDLCN$9$k$?$a$K!"(B + Apache $B$O%j%@%$%l%/%H$r%/%i%$%"%s%H$KAw=P$9$k$H$$$&$3$H$K!"Cm0U$7$F$/$@$5$$!#(B + $B$3$l$K$O$$$m$$$m$H4XO"$7$F5/$3$kLdBj$,$"$j$^$9!#(B + $BCf$G$b:G$b=EMW$J$N$O!"%/%i%$%"%s%H$O85!9$N%(%i!<%9%F!<%?%9%3!<%I$r%/%i%$%"%s%H$r!":.Mp$5$;$k$+$b$7$l$^$;$s!#(B + $B$5$i$K!"(BErrorDocument 401 $B$K%j%b!<%H$N(B URL $B$r;XDj$9$k$H!"(B + $B%/%i%$%"%s%H$O(B 401 $B$H$$$&%9%F!<%?%9%3!<%I$r$C$F!"(BErrorDocument 401 $B$H$$$&%G%#%l%/%F%#%V$r;H$&>l9g$O!"(B + $BI,$:%m!<%+%k$JJ8=q$r;2>H$7$J$1$l$P$J$j$^$;$s!#(B

    + +

    Microsoft Internet Explorer (MSIE) $B$O%G%U%)%k%H$G$O%5!<%P$,@8@.$7$?%(%i!<%a%C%;!<%8$,(B + $B!V>.$5$9$.$k!W$H$-$K$OL5;k$r$7$F<+J,<+?H$N!V$d$5$7$$!W%(%i!<%a%C%;!<%8$G(B + $BCV49$7$^$9!#%5%$%:$N$7$-$$CM$O%(%i!<$N\$7$$>pJs$O(B Microsoft + Knowledge Base $B$N5-;v(B Q294807 + $B$K$"$j$^$9!#(B

    + +

    $B$[$H$s$I$N%(%i!<%a%C%;!<%8$r>e=q$-$9$k$3$H$,$G$-$^$9$,!"FCDj$N>u672<$G$O(B + ErrorDocument $B$N@_Dj$K$+$+$o$i$:(B + $BFbB"$N%a%C%;!<%8$,;H$o$l$^$9!#(B + $BFC$K!"IT@5$J7A<0$N%j%/%(%9%H$,8!=P$5$l$?>l9g!"DL>o$N%j%/%(%9%H=hM}$O(B + $BB(:B$KCf;_$5$l!"FbB"$N%(%i!<%a%C%;!<%8$,JV$5$l$^$9!#(B + $B$3$N=hCV$OIT@5$J%j%/%(%9%H$K$h$C$F0z$-5/$3$5$l$k!"%;%-%e%j%F%#LdBj$+$i(B + $B + +

    2.0 $B$h$jA0$N%P!<%8%g%s$G$O!"BP$K$J$C$F$$$J$$Fs=E0zMQId$r(B + $B@hF,$KIU$1$k$3$H$K$h$j%a%C%;!<%8$G$"$k$3$H$r;XDj$7$F$$$^$7$?!#(B

    + +
    + +$B%+%9%?%^%$%:2DG=$J(B +$B%(%i!<1~Ez$N%I%-%e%a%s%F!<%7%g%s(B +
    + + +ErrorLog +$B%5!<%P$,%(%i!<$r%m%0<}=8$9$k>l=j(B + ErrorLog file-path|syslog[:facility] +ErrorLog logs/error_log (Unix) ErrorLog logs/error.log (Windows and OS/2) +server configvirtual host + + + +

    ErrorLog $B%G%#%l%/%F%#%V$O!"(B + $B%5!<%P$K@8$8$?$5$^$6$^$J%(%i!<$r(B + $B5-O?$9$k0Y$N%U%!%$%k$NL>A0$r@_Dj$7$^$9!#(B + file-path $B$,@dBP%Q%9$G$J$$$H$-$O!"(BServerRoot $B$+$i$NAjBP%Q%9$H$_$J$5$l$^$9!#(B

    + + $BNc(B + ErrorLog /var/log/httpd/error_log + + +

    file-path $B$,%Q%$%W(B (|) $B$+$i;O$^$k>l9g$O!"(B + $B%(%i!<%m%0$r=hM}$9$k$?$a$K + + $BNc(B + ErrorLog "|/usr/local/bin/httpd_errors" + + +

    $B%U%!%$%kL>$NJQ$o$j$K(B syslog $B$H;XDj$9$k$3$H$K$h$C$F!"(B + $B%7%9%F%`$,%5%]!<%H$7$F$$$l$P(B syslogd(8) $B$rMxMQ$7$?%m%.%s%0$,M-8z$K$J$j$^$9!#(B + $B%G%U%)%k%H$G$O!"(Blocal7 $B%U%!%7%j%F%#$H$J$j$^$9$,!"(B + syslog:facility $B$H$$$C$?7A$G5-=R$9$k$3$H$K$h$j!"(B + $BDL>o(B syslog(1) $B$N%I%-%e%a%s%H$G@bL@$5$l$F$$$k%U%!%7%j%F%#$N0l$D$r;H$&$h$&$K(B + $B$9$k$3$H$,$G$-$^$9!#(B

    + + $BNc(B + ErrorLog syslog:user + + +

    $B%;%-%e%j%F%#(B: + $B%m%0%U%!%$%k$r3JG<$9$k%G%#%l%/%H%j$,!"%5!<%P$r5/F0$7$?%f!<%60J30$N(B + $B%f!<%6$K$h$C$F=q$-9~$a$k>l9g$K%;%-%e%j%F%#$,GK$i$l$k2DG=@-$,$"$k$3$H$K(B + $B4X$9$k>\:Y$O(B $B%;%-%e%j%F%#$K4X$9$k%3%D(B $B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    + $BCm(B +

    Unix $B0J30$N%W%i%C%H%U%)!<%`$G%U%!%$%k$N%Q%9$rF~NO$9$k$H$-$O!"(B + $B%W%i%C%H%U%)!<%`$,%P%C%/%9%i%C%7%e$N;HMQ$r5v$7$F$$$?$H$7$F$b!"(B + $B3N + + +LogLevel +Apache $B%m%0%U%!%$%k(B + + + +FileETag +ETag HTTP $B1~Ez%X%C%@$r:n@.$9$k$?$a$K;HMQ$5$l$k(B +$B%U%!%$%k$NB0@-(B +FileETag component ... +FileETag INode MTime Size +server configvirtual host +directory.htaccess + +FileInfo + + +

    + FileETag $B%G%#%l%/%F%#%V$O(B + $B%I%-%e%a%s%H$,%U%!%$%k$K4p$E$$$?$b$N$G$"$k$H$-$K!"(B + ETag ($B%(%s%F%#%F%#%?%0(B) $B1~Ez%X%C%@%U%#!<%k%I$r:n@.$9$k$H$-$K;HMQ$9$k(B + $B%U%!%$%k$NB0@-$r@_Dj$7$^$9!#(B (ETag $B$NCM$O%M%C%H%o!<%/$NBS0h$r@aLs$9$k$?$a$N(B + $B%-%c%C%7%e$N4IM}$G;H$o$l$^$9!#(B) Apache 1.3.22 $B0JA0$G$O!"(BETag $B$NCM$O(B + $B>o$K(B$B%U%!%$%k$N(B inode, $B%5%$%:!":G=*=$@5;~9o(B (mtime) $B$+$i:n@.(B + $B$5$l$F$$$^$7$?!#(BFileETag $B%G%#%l%/%F%#%V$K$h$j!"$3$l$i$N$I$l$r;H$&$+$r(B + $BA*$V$3$H$,$G$-$^$9!#G'<1$5$l$k%-!<%o!<%I$O(B: +

    + +
    +
    INode
    +
    $B%U%!%$%k$N(B inode $BHV9f$r7W;;$K;H$$$^$9(B
    +
    MTime
    +
    $B%U%!%$%k$N:G=*=$@5;~9o$r;H$$$^$9(B
    +
    Size
    +
    $B%U%!%$%k$NCf?H$N%P%$%H?t$r;H$$$^$9(B
    +
    All
    +
    $B;HMQ2DG=$J$9$Y$F$N%U%#!<%k%I$r;H$$$^$9!#(B + $B$3$l$O(B FileETag INode MTime Size $B$HEy2A$G$9!#(B
    +
    None
    +
    $B%I%-%e%a%s%H$,%U%!%$%k$K4p$E$$$?$b$N$G$b!"(BETag $B%U%#!<%k%I$r(B + $B1~Ez$KIU2C$7$^$;$s(B
    +
    + +

    INode, MTime, Size $B%-!<%o!<%I$K$O(B + + $B$d(B - $B$rA0$KIU$1$F(B + $B;XDj$9$k$3$H$b$G$-$^$9!#$3$N>l9g$O!"$h$j9-$$HO0O$+$i7Q>5$5$l$?(B + $B%G%U%)%k%H$N@_Dj$KJQ99$r2C$($k$h$&$K$J$j$^$9!#$=$N$h$&$J@\F,<-$N(B + $BL5$$%-!<%o!<%I$r;XDj$9$k$H!"B(:B$K7Q>5$7$?@_Dj$rL58z$K$7$^$9!#(B

    + +

    $B$"$k%G%#%l%/%H%j$N@_Dj$K(B + FileETag INode MTime Size $B$,$"$j!"(B + $B%5%V%G%#%l%/%H%j$N@_Dj$K(B FileETag -INode $B$,$"$k$H$-$O!"(B + $B$=$N%5%V%G%#%l%/%H%j$N@_Dj$O(B ($B@_Dj$,>e=q$-$5$l$J$1$l$P%5%V%G%#%l%/%H%j$N(B + $B%5%V%G%#%l%/%H%j$K$b7Q>5$5$l$^$9(B) FileETag MTime Size + $B$HF1$8$K$J$j$^$9!#(B

    +
    +
    + + +Files +$B%^%C%A$9$k%U%!%$%kL>$KE,MQ$5$l$k%G%#%l%/%F%#%V$r0O$`(B +<Files filename> ... </Files> +server configvirtual host +directory.htaccess + +All + + +

    Files $B%G%#%l%/%F%#%V$O!"(B + $B$=$NCf$K$"$k%G%#%l%/%F%#%V$NE,MQHO0O$r%U%!%$%kL>$G@)8B$7$^$9!#(B + Directory $B%G%#%l%/%F%#%V$d(B Location $B%G%#%l%/%F%#%V$H(B + $BF1$8$h$&$J5!G=$r;}$A$^$9!#(B + $B$3$l$O!"(B</Files> $B%G%#%l%/%F%#%V$HBP$K(B + $B$J$C$F$$$J$1$l$P$J$j$^$;$s!#(B + $B$3$N%;%/%7%g%sCf$N%G%#%l%/%F%#%V$O!"%Y!<%9L>(B ($B%U%!%$%kL>$N:G8e$NItJ,(B) + $B$,;XDj$5$l$?%U%!%$%kL>$K%^%C%A$9$k$9$Y$F$N%*%V%8%'%/%H$KE,MQ$5$l$^$9!#(B + Files $B%;%/%7%g%s$O(B + Directory $B%;%/%7%g%s$H(B + .htaccess $B$,FI$_9~$^$l$?8e!"(B + Location $B%;%/%7%g%s$h$j$O@h$K(B + $B@_Dj%U%!%$%k$K8=$l$?=g$KE,MQ$5$l$^$9!#(B + Files $B$O!"(B + Directory $B%;%/%7%g%sFb$K(B + $B%M%9%H$5$;$k$3$H$,$G$-!"(B + $B%U%!%$%k%7%9%F%`$N0lIt$K$N$_8BDj$7$FE,MQ$5$;$k$3$H$,$G$-$^$9!#(B

    + +

    filename $B0z?t$O!"%U%!%$%kL>$+%o%$%k%I%+!<%IJ8;zNs(B + $B$G!"%o%$%k%I%+!<%I$G$O(B ? $B$O0l$D$NJ8;z!"(B* $B$OG$0U$NJ8;zNs$K%^%C%A$7$^$9!#(B + ~ $B$H$$$&J8;z$rIU2C$9$k$3$H$G3HD%@55,I=8=$r;H$&$3$H$b$G$-$^$9!#(B + $BNc$($P!"(B

    + + + <Files ~ "\.(gif|jpe?g|png)$"> + + +

    $B$H$9$k$3$H$K$h$j!"0lHLE*$J%$%s%?!<%M%C%H$N2hA|%U%)!<%^%C%H$K%^%C%A$7$^$9!#(B + $B$?$@$7!"(B + FilesMatch $B$r;H$&J}$,(B + $B?d>)$5$l$F$$$^$9!#(B

    + +

    $B$A$J$_$K!"(BDirectory $B$H(B Location $B%;%/%7%g%s$H$O0[$J$j!"(B + Files + $B$O(B .htaccess $B%U%!%$%kFb$GMxMQ$9$k$3$H$,$G$-$^$9!#(B + $B$3$l$K$h$j!"%f!<%6$,%U%!%$%kKh$K%"%/%;%9$N@)8f$r9T$J$&$3$H$,$G$-$k$h$&$K(B + $B$J$C$F$$$^$9!#(B

    + +
    +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +FilesMatch +$B@55,I=8=$K%^%C%A$9$k%U%!%$%kL>$KE,MQ$5$l$k(B +$B%G%#%l%/%F%#%V$r0O$`(B +<FilesMatch regex> ... </FilesMatch> +server configvirtual host +directory.htaccess + +All + + +

    FilesMatch $B%G%#%l%/%F%#%V$O!"(B + Files + $B%G%#%l%/%F%#%VF1MM$K$=$NCf$K$"$k%G%#%l%/%F%#%V$NE,MQHO0O$r%U%!%$%kL>$G@)8B$7$^$9!#$?$@$7!"(B + $B$3$N%G%#%l%/%F%#%V$K$O@55,I=8=$r;XDj$7$^$9!#(B + $BNc$($P(B:

    + + + <FilesMatch "\.(gif|jpe?g|png)$"> + + +

    $B$O0lHLE*$J%$%s%?!<%M%C%H$N2hA|7A<0$K%^%C%A$7$^$9!#(B

    +
    + +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +ForceType +$B$9$Y$F$N%^%C%A$9$k%U%!%$%k$,;XDj$N(B MIME $B%3%s%F%s%H%?%$%W$G(B +$BAw$i$l$k$h$&$K$9$k(B +ForceType MIME-type|None +directory.htaccess + +FileInfo +Apache 2.0 $B$G(B core $B$K0\F0(B + + +

    .htaccess $B$d(B Directory $B%;%/%7%g%s!"(B + Location $B%;%/%7%g%s!"(B + Files $B%;%/%7%g%s$K(B + $B=q$+$l$?>l9g!"$3$N%G%#%l%/%F%#%V$O$=$3$K$"$k$9$Y$F$N%U%!%$%k$,(B + MIME-type + $B$G;XDj$5$l$?%3%s%F%s%H%?%$%W$H$7$F07$o$l$k$h$&$K$7$^$9!#$?$H$($P!"(B + GIF $B%U%!%$%k$P$+$j$N%G%#%l%/%H%j$,$"$C$F!"$9$Y$F$N%U%!%$%k$r(B .gif + $B$G=*$o$i$;$?$/$O$J$$$H$-$K!"0J2<$N$b$N$r;HMQ$7$^$9(B:

    + + + ForceType image/gif + + +

    DefaultType $B$H0c$C$F(B + $B$3$N%G%#%l%/%F%#%V$O%a%G%#%"%?%$%W$r7h$a$k$3$H$,$G$-$k$+$b$7$l$J$$(B + $B%U%!%$%k$N3HD%;R$b4^$a!"$9$Y$F$N(B MIME $B%?%$%W$N4XO"IU$1$r(B + $B>e=q$-$9$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    + +

    None $B$H$$$&CM$r;H$&$3$H$G(B ForceType $B$N(B + $B@_Dj$rL58z$K$G$-$^$9(B:

    + + + # force all files to be image/gif:
    + <Location /images>
    + + ForceType image/gif
    +
    + </Location>
    +
    + # but normal mime-type associations here:
    + <Location /images/mixed>
    + + ForceType None
    +
    + </Location> +
    +
    +
    + + +HostnameLookups +$B%/%i%$%"%s%H$N(B IP $B%"%I%l%9$N(B DNS $B%k%C%/%"%C%W$r(B +$BM-8z$K$9$k(B +HostnameLookups On|Off|Double +HostnameLookups Off +server configvirtual host +directory + + +

    $B$3$N%G%#%l%/%F%#%V$O!"%[%9%HL>$r%m%0<}=8$G$-$k$h$&$K(B + DNS $B%k%C%/%"%C%W$rM-8z$K$7$^$9(B + ($B$5$i$K!"(BCGI/SSI $B$K(B REMOTE_HOST $BJQ?t$H$7$FEO$7$^$9(B)$B!#(B + Double$B$r;XDj$7$?>l9g!"(B2 $B=E$N5U0z$-$r9T$J$$$^$9!#(B + $B$D$^$j!"5U0z$-$N8e$K!"$=$N7k2L$KBP$7$F@50z$-$r9T$J$$$^$9!#@50z$-$N(B + $B7k2L$N(B IP $B%"%I%l%9$NCf$K%*%j%8%J%k$N%"%I%l%9$H0lCW$9$k$b$N$,$J$1$l$P(B + $B$J$j$^$;$s!#(B("tcpwrappers" $B$NMQ8l$G$O(B PARANOID $B$H8F$P$l$F$$$^$9!#(B)

    + +

    mod_authz_host $B$G%[%9%HL>$K$h$k%"%/%;%9(B + $B@)8f$r9T$J$&>l9g$K$O!"(B + $B@_Dj$NG!2?$K$h$i$:(B 2 $B=E$N5U0z$-$,HostnameLookups Double $B$r@_Dj$7$J$$8B$j!"(B + $BB>$NItJ,$O$3$N(B 2 $B=E5U0z$-$N7k2L$r;H$&$3$H$O$G$-$^$;$s!#(B + $BNc$($P!"(BHostnameLookups On $B$H@_Dj$7$F$"$k>uBV$G!"(B + $B%[%9%HL>$K$h$k%"%/%;%9@)8B$r9T$J$C$?%*%V%8%'%/%H$X$N(B + $B%j%/%(%9%H$rREMOTE_HOST $B$K$ODL>o$N5U0z$-7k2L$,EO$5$l$^$9!#(B

    + +

    $B%G%#%l%/%F%#%V$N%G%U%)%k%H$O(B + $BK\Ev$K5U0z$-$rI,MW$H$7$F$$$k$o$1$G$O$J$$%5%$%H$N(B + $B%M%C%H%o!<%/%H%i%U%#%C%/$rDc8:$5$;$k$?$a$K!"(BOff $B$K$J$C$F$$$^$9!#(B + $B%k%C%/%"%C%W$K$h$kM>7W$JCY1d$,$J$/$J$k$?$a!"(B + $B%(%s%I%f!<%6$K$H$C$F$bNI$$$G$7$g$&!#(B + DNS $B$N%k%C%/%"%C%W$K$O!"$+$J$j$N;~4V$,I,MW$H$J$k>l9g$,B?$/!"(B + $BIi2Y$N9b$$%5%$%H$G$O$3$N%G%#%l%/%F%#%V$O(B Off $B$K$9$Y$-$G$9!#(B + $B$J$*!"(B/support $B%G%#%l%/%H%j$K4^$^$l!"%G%U%)%k%H$G$O(B + $B%$%s%9%H!<%k%G%#%l%/%H%j$N(B bin $B%5%V%G%#%l%/%H%j$K(B + $B%$%s%9%H!<%k$5$l$k(B logresolve $B%f!<%F%#%j%F%#$K$h$j!"(B + Apache $B$NF0:n$H$OJL$K!"%m%0$K;D$5$l$F$$$k(B IP $B%"%I%l%9$+$i%[%9%HL>$r(B + $B%k%C%/%"%C%W$9$k$3$H$,2DG=$G$9!#(B

    +
    +
    + + +IfDefine +$B5/F0;~$K%F%9%H$,??$G$"$k$H$-$N$_$K=hM}$5$l$k%G%#%l%/%F%#%V$r(B +$B0O$`(B +<IfDefine [!]parameter-name> ... + </IfDefine> +server configvirtual host +directory.htaccess + +All + + +

    <IfDefine test>...</IfDefine> + $B%;%/%7%g%s$O!"(B + $B%G%#%l%/%F%#%V$r>r7oIU$-$G;XDj$9$k$?$a$KMxMQ$7$^$9!#(B + IfDefine $B%;%/%7%g%s$K(B + $B4^$^$l$k%G%#%l%/%F%#%V$O!"(Btest$B$,(B + $BDj5A$5$l$F$$$k$H$-$N$_=hM}$5$l$^$9!#(B + $B$b$7(B test $B$,Dj5A$5$l$F$$$J$1$l$P!"(B + $B3+;O$H=*N;$N;XDj$N4V$N%G%#%l%/%F%#%V$OL5;k$5$l$^$9!#(B

    + +

    IfDefine $B%;%/%7%g%s%G%#%l%/%F%#%V$K(B + $B;XDj$9$k(B test $B$O!"(B + $B + +

      +
    • parameter-name
    • + +
    • !parameter-name
    • +
    + +

    $BA0l9g$K$O!"(Bparameter-name $B$HL>IU$1$i$l$?%Q%i%a!<%?$,(B + $BDj5A$5$l$F$$$l$P3+;O$H=*N;$N4V$N%G%#%l%/%F%#%V$,=hM}$5$l$^$9!#(B + $B8el9g$O5U$G!"(Bparameter-name $B$,;XDj$5$l$F(B$B$$$J$$(B + $B>l9g$K=hM}$5$l$^$9!#(B

    + +

    parameter-name $B0z?t$O!"%5!<%P$r5/F0$9$k:]$K(B + httpd $B$N%3%^%s%I%i%$%s$K(B + -Dparameter- $B$H$$$&7A$G;XDj$9$k$HDj5A$5$l$^$9!#(B

    + +

    IfDefine $B%;%/%7%g%s$O(B + $BF~$l;R$K$9$k$3$H$,$G$-!"J#?t$N%Q%i%a!<%?$K$h$k%F%9%H$r$9$k$?$a$K;HMQ$G$-$^$9!#(B + $BNc(B:

    + + + httpd -DReverseProxy ...
    +
    + # httpd.conf
    + <IfDefine ReverseProxy>
    + + LoadModule rewrite_module modules/mod_rewrite.so
    + LoadModule proxy_module modules/libproxy.so
    +
    + </IfDefine> +
    +
    +
    + + +IfModule +$B%b%8%e!<%k$NB8:_$9$k$+$7$J$$$+$K1~$8$F=hM}$5$l$k(B +$B%G%#%l%/%F%#%V$r0O$`(B +<IfModule [!]module-file|module-identifier> ... + </IfModule> +server configvirtual host +directory.htaccess + +All +$B%b%8%e!<%k<1JL;R$O%P!<%8%g%s(B 2.1 $B0J9_$G;HMQ2DG=!#(B + + +

    <IfModule test>...</IfModule> + $B%;%/%7%g%s$O!"%b%8%e!<%k$,B8:_$9$k$H$-$K=hM}$5$l$k%G%#%l%/%F%#%V$r(B + $B;XDj$9$k$?$a$KMxMQ$7$^$9!#(B + IfModule $B%;%/%7%g%s$K(B + $B4^$^$l$k%G%#%l%/%F%#%V$O!"(Btest + $B$G;XDj$9$k%b%8%e!<%k$,AH$_9~$^$l$F$$$k$H$-$N$_=hM}$5$l$^$9!#(B + $B$b$7(B test $B$,AH$_9~$^$l$F$$$J$1$l$P!"3+;O$H=*N;$N4V$N%G%#%l%/%F%#%V(B + $B$OL5;k$5$l$^$9!#(B

    + +

    IfModule $B%;%/%7%g%s%G%#%l%/%F%#%V$K(B + $B;XDj$9$k(B test $B$O!"(B + $B + +

      +
    • module
    • + +
    • !module
    • +
    + +

    $BA0l9g$O!"(Bmodule $B$HL>IU$1$i$l$?%b%8%e!<%k$,(B + Apache $B$KAH$_9~$^$l$F$$$l$P(B + ($B%3%s%Q%$%k:Q$_$N$b$N$H!"(BLoadModule $B$rMxMQ$7$F(B + $BF0E*$KFI$_9~$s$@$b$N$NN>J}(B)$B!"(B + $B3+;O$H=*N;$N4V$N%G%#%l%/%F%#%V$,=hM}$5$l$^$9!#(B + $B8el9g$O5U$G!"(Bmodule $B$,AH$_9~$^$l$F(B$B$$$J$$(B + $B>l9g$K=hM}$5$l$^$9!#(B

    + +

    module $B0z?t$O!"%b%8%e!<%k<1JL;R$+(B + $B%3%s%Q%$%k$r$7$?;~$N%b%8%e!<%k$N%U%!%$%kL>$G$9!#(B + $BNc$($P!"(Brewrite_module $B$O<1JL;R$G(B + mod_rewrite.c $B$O%U%!%$%kL>$G$9!#(B + $B%b%8%e!<%k$,J#?t$N%=!<%9%U%!%$%k$+$i9=@.$5$l$F$$$k>l9g$O!"J8;zNs(B + STANDARD20_MODULE_STUFF $B$,$"$k%U%!%$%k$NL>A0$r(B + $B;H$C$F$/$@$5$$!#(B

    + +

    IfModule $B%;%/%7%g%s$O(B + $BF~$l;R$K$9$k$3$H$,2DG=$G$"$j!"(B + $BJ#?t$N%b%8%e!<%k$N%F%9%H$r9T$J$&$?$a$K;HMQ$G$-$^$9!#(B

    + + $BFCDj$N%b%8%e!<%k$NB8:_$K4X$o$i$:F0:n$9$k(B + $B@_Dj%U%!%$%k$N86K\$,I,MW$J$H$-$K$N$_$3$N%;%/%7%g%s$r;HMQ$7$F$/$@$5$$!#(B + $BDL>o$NF0:n$G$O!"%G%#%l%/%F%#%V$r(B + IfModule $B%;%/%7%g%s$NCf$K(B + $BF~$l$kI,MW$O$"$j$^$;$s!#(B +
    +
    + + +Include +$B%5!<%P@_Dj%U%!%$%kCf$+$iB>$N@_Dj%U%!%$%k$r +Include file-path|directory-path +server configvirtual host +directory + +$B%o%$%k%I%+!<%I$K$h$k%^%C%A$O(B 2.0.41 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$K$h$j!"%5!<%P$N@_Dj%U%!%$%k$+$i(B + $BB>$N@_Dj%U%!%$%k$r%$%s%/%k!<%I$9$k$3$H$,$G$-$^$9!#(B

    + +

    $BJ#?t$N%U%!%$%k$r%"%k%U%!%Y%C%H=g$K0lEY$KFI$_9~$`$?$a$K!"(B + $B%7%'%k7A<0(B (fnmatch) $B$N%o%$%k%I%+!<%IJ8;z$r;H$&$3$H$,$G$-$^$9!#(B + $B$5$i$K!"(BInclude $B$K%G%#%l%/%H%j$r;XDj$7$?>l9g$O!"(B + $B%G%#%l%/%H%j$H$=$N%5%V%G%#%l%/%H%jFb$NA4$F$N%U%!%$%k$r(B + $B%"%k%U%!%Y%C%H=g$KFI$_9~$s$G!"@_Dj%U%!%$%k$H$7$F=hM}$7$^$9!#(B + $B$7$+$7!"%G%#%l%/%H%jA4BN$rFI$_9~$`$N$O$*4+$a$G$-$^$;$s!#(B + $B$U$H$7$?$3$H$+$i(B httpd $B$,FI$_9~$_$K<:GT$9$k$h$&$J(B + $B0l;~%U%!%$%k$r%G%#%l%/%H%j$K;D$7$F$7$^$&$h$&$J$3$H$,$h$/$"$k$+$i$G$9!#(B

    + +

    $B;XDj$9$k%U%!%$%k%Q%9$O@dBP%Q%9$+!"(B + ServerRoot $B%G%#%l%/%H%j$+$i$N(B + $BAjBP%Q%9$+!"$N$I$A$i$+$G$9!#(B

    + +

    $BNc(B:

    + + + Include /usr/local/apache2/conf/ssl.conf
    + Include /usr/local/apache2/conf/vhosts/*.conf +
    + +

    ServerRoot $B$+$i$NAjBP%Q%9$N>l9g$O(B:

    + + + Include conf/ssl.conf
    + Include conf/vhosts/*.conf +
    + +

    apachectl configtest $B$r + + + root@host# apachectl configtest
    + Processing config file: /usr/local/apache2/conf/ssl.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost1.conf
    + Processing config file: /usr/local/apache2/conf/vhosts/vhost2.conf
    + Syntax OK +
    + + +apachectl + + + +KeepAlive +HTTP $B$N;}B3E*$J@\B3$rM-8z$K$9$k(B +KeepAlive On|Off +KeepAlive On +server configvirtual host + + + +

    HTTP/1.0 $B$N(B Keep-Alive $B3HD%$H(B HTTP/1.1 $B$N;}B3E*@\B3$N5!G=$O!"(B + $BJ#?t$N%j%/%(%9%H$,F1$8(B TCP $B$N@\B3$GAw$i$l$k!"D9;~4V;}B3$9$k(B + HTTP $B%;%C%7%g%s$rDs6!$7$^$9!#$?$/$5$s$N2hA|$,(B + $B4^$^$l$k(B HTML $B%I%-%e%a%s%H$G$O>l9g$K$h$C$F$OCY1d;~4V$,(B 50% $BC;=L$5$l$k7k2L$b(B + $B$G$F$$$^$9!#(BKeep-Alive $B@\B3$rM-8z$K$9$k$K$O(B + KeepAlive On $B$H@_Dj$7$^$9!#(B

    + +

    HTTP/1.0 $B$KBP1~$7$?%/%i%$%"%s%H$N:]$K$O!"(B + $B%/%i%$%"%s%H$h$jFC$KMW5a$,$"$C$?>l9g$N$_(B Keep-Alive $B@\B3$H$J$j$^$9!#(B + $B$5$i$K!"(BHTTP/1.0 $B%/%i%$%"%s%H$G$O!"%3%s%F%s%D$NMFNL$,@h$K(B + ($BLuCm(B: $BMW5a$KBP$7$F1~Ez$rJV$9A0$K(B) $B$o$+$k>l9g$N$_(B Keep-Alive + $B@\B3$rMxMQ$G$-$^$9!#(B + $B$3$l$O!"(BCGI $B$N=PNO$d(B SSI $B$N%Z!<%8!"(B + $B%5!<%P$,@8@.$7$?%G%#%l%/%H%j$N%j%9%H$N$h$&$JF0E*%3%s%F%s%D$r(B + HTTP/1.0 $B%/%i%$%"%s%H$KAw$k>l9g$K$O(B Keep-Alive $B@\B3$r;H$($J$$$3$H$r0UL#$7$^$9!#(B + HTTP/1.1 $B$KBP1~$7$?%/%i%$%"%s%H$N:]$K$O!"(B + $BFC$K;XDj$5$l$J$$8B$j$O%G%U%)%k%H$H$7$F;}B3E*$J@\B3$,9T$J$o$l$^$9!#(B + $B%/%i%$%"%s%H$,MW5a$9$l$P!"%3%s%F%s%D$NMFNL$rH=JL$G$-$J$$$b$N$r(B + $B;}B3E*$J@\B3$rDL$7$FAw$k$?$a$K!"%A%c%s%/%(%s%3!<%G%#%s%0$,MQ$$$i$l$^$9!#(B

    +
    + +MaxKeepAliveRequests +
    + + +KeepAliveTimeout +$B;}B3E*$J@\B3$G +KeepAliveTimeout seconds +KeepAliveTimeout 5 +server configvirtual host + + + +

    $B@\B3$rJD$8$kA0$K!"(BApache $B$,Timeout $B%G%#%l%/%F%#%V$K$h$C$F(B + $B;XDj$5$l$?%?%$%`%"%&%HCM$,;H$o$l$^$9!#(B

    + +

    KeepAliveTimeout $B$rBg$-$JCM$K@_Dj$9$k$H!"(B + $BIi2Y$N9b$$%5!<%P$K$*$$$F$O%Q%U%)!<%^%s%9$NLdBj$r0z$-5/$3$9>l9g$,$"$j$^$9!#(B + $B%?%$%`%"%&%H$,D9$1$l$PD9$$$[$I!"$h$jB?$/$N%5!<%P%W%m%;%9$,(B + $B3hH/$G$J$$%/%i%$%"%s%H$+$i$N@\B3$N=*N;$rBT$AB3$1$k$3$H$K$J$j$^$9!#(B

    +
    +
    + + +Limit +$B0O$$$NCf$K$"$k%"%/%;%9@)8f$NE,MQ$rFCDj$N(B HTTP $B%a%=%C%I$N$_$K(B +$B@)8B$9$k(B +<Limit method [method] ... > ... + </Limit> +server configvirtual host +directory.htaccess + +All + + +

    $B%"%/%;%9@)8f$O!"DL>o(B$BA4$F$N(B$B%"%/%;%9%a%=%C%I$KBP$7$F(B + $B1F6A$7!"IaDL$O$3$l$,K>$^$7$$5sF0$G$9!#(B + $B$=$&$7$?$3$H$+$i!"BgItJ,$N>l9g$K$O%"%/%;%9@)8f$K4X$o$k%G%#%l%/%F%#%V$r(B + Limit $B%;%/%7%g%sFb$K(B + $B=q$/$Y$-$G$O$"$j$^$;$s!#(B

    + +

    Limit $B%G%#%l%/%F%#%V$N(B + $BL\E*$O!"%"%/%;%9@)8f$NHO0O$r(B + $B;XDj$5$l$?(B HTTP $B%a%=%C%I$K8BDj$9$k$?$a$G$9!#(B + $B$=$l0J30$N%a%=%C%I$O!"(BLimit $B$G0O$o$l$?%"%/%;%9@)8f$N(B + $B1F6A$r$B!#(B + $B0J2<$NNc$O!"(BPOST, PUT, DELETE $B$N%a%=%C%I$KBP$7$F$N$_%"%/%;%9$N@)8f$r9T$J$$!"(B + $B$=$l0J30$N%a%=%C%I$K$D$$$F$O@)8B$7$^$;$s(B:

    + + + <Limit POST PUT DELETE>
    + + Require valid-user
    +
    + </Limit> +
    + +

    $B%a%=%C%IL>$K$O0J2<$NCf$+$i0l$D0J>e$rNs5s$9$k$3$H$,$G$-$^$9(B: + GET, + POST, PUT, DELETE, + CONNECT, OPTIONS, + PATCH, PROPFIND, PROPPATCH, + MKCOL, COPY, MOVE, + LOCK, UNLOCK. $B%a%=%C%IL>$O(B + $BBgJ8;z>.J8;z$r6hJL$7$^$9!#(B GET $B$r;XDj$7$?>l9g$K$O(B + HEAD $B%j%/%(%9%H$K$b@)8B$,$+$+$j$^$9!#(BTRACE + $B%a%=%C%I$K@)8B$r$+$1$k$3$H$O$G$-$^$;$s!#(B

    + + $B%"%/%;%9@)8f$,L\E*$N>l9g$O(B + Limit + $B%;%/%7%g%s$NBe$o$j$K(B LimitExcept $B%;%/%7%g%s$r;HMQ$7$?J}$,NI$$$G$7$g$&!#(B + LimitExcept + $B%;%/%7%g%s$G$OITFCDj$N%a%=%C%I$KBP$7$F$bKI8f$G$-$k$+$i$G$9!#(B + +
    +
    + + +LimitExcept +$B;XDj$5$l$?$b$N0J30$N(B HTTP $B%a%=%C%I$K%"%/%;%9@)8f$r(B +$B@)8B$9$k(B +<LimitExcept method [method] ... > ... + </LimitExcept> +server configvirtual host +directory.htaccess + +All + + +

    LimitExcept $B$H(B + </LimitExcept> $B$O!"0z?t$K(B + $B4^$^$l$F$$$J$$(B + HTTP $B$N%"%/%;%9%a%=%C%I$KE,MQ$9$k$?$a$N%"%/%;%9@)8f(B + $B%G%#%l%/%F%#%V$r3g$k$?$a$KMxMQ$7$^$9!#(B + $B$D$^$j!"(BLimit $B%;%/%7%g%s$NH?BP$NF0:n$r$7!"(B + $BI8=`$N%a%=%C%I$HI8=`30$dL$G'<1$N%a%=%C%I$N>l9g$NN>J}$r@_Dj$G$-$^$9!#(B + Limit $B$N%I%-%e%a%s%H$b(B + $BJ;$;$F;2>H$7$F$/$@$5$$!#(B

    + +

    $BNc(B:

    + + + <LimitExcept POST GET>
    + + Require valid-user
    +
    + </LimitExcept> +
    + +
    +
    + + +LimitInternalRecursion +$BFbIt%j%@%$%l%/%H$HF~$l;R$K$J$C$?%5%V%j%/%(%9%H$N:GBg?t$r7hDj$9$k(B +LimitInternalRecursion number [number] +LimitInternalRecursion 10 +server configvirtual host + +Apache 2.0.47 $B0J9_$G;HMQ2DG=(B + + +

    $BFbIt%j%@%$%l%/%H$ONc$($P(B Action $B%G%#%l%/%F%#%V$r(B + $B;H$C$F$$$k$H$-$K5/$3$j$^$9!#(BAction $B%G%#%l%/%F%#%V$O(B + $B85!9$N%j%/%(%9%H$r(B CGI $B%9%/%j%W%H$KFbIt%j%@%$%l%/%H$r9T$J$$$^$9!#(B + $B%5%V%j%/%(%9%H$O$$$/$D$+$N(B URI $B$KBP$7$F!"%j%/%(%9%H$5$l$?$H$-$K(B + $B2?$,5/$3$k$+$rD4$Y$k$?$a$N(B Apache $B$N5!9=$G$9!#Nc$($P!"(Bmod_dir + $B$O(B DirectoryIndex $B%G%#%l%/%F%#%V(B + $B$,%j%9%H$9$k%U%!%$%k$rD4$Y$k$?$a$K%5%V%j%/%(%9%H$r;H$$$^$9!#(B

    + +

    LimitInternalRecursion $B$OFbIt%j%@%$%l%/%H$d(B + $B%5%V%j%/%(%9%H$,L58B%k!<%W$K4Y$C$?$H$-$N%5!<%P%/%i%C%7%e$rKI$.$^$9!#(B + $BIaDL!"$=$N$h$&$J%k!<%W$O@_Dj$K<:GT$7$?$H$-$KH/@8$7$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O!"%j%/%(%9%HKh$KI>2A$5$l$k!"Fs$D$N0c$&8B3&CM$r(B + $B@_Dj$7$^$9!#:G=i$N(B number $B$O!"5/$3$jF@$k(B + $BFbIt%j%/%(%9%H$N:GBgCM$r@_Dj$7$^$9!#Fs$D$a$N(B number $B$O(B + $B%5%V%j%/%(%9%H$,F~$l;R$K$G$-$k?<$5$r@_Dj$7$^$9!#(Bnumber $B$r(B + $B0l$D$@$1;XDj$7$?$H$-$O!"N>J}$N8B3&CM$K$=$NCM$,@_Dj$5$l$^$9!#(B

    + + $BNc(B + LimitInternalRecursion 5 + +
    +
    + + +LimitRequestBody +$B%/%i%$%"%s%H$+$iAw$i$l$k(B HTTP $B%j%/%(%9%H$N%\%G%#$N(B +$BAmNL$r@)8B$9$k(B +LimitRequestBody bytes +LimitRequestBody 0 +server configvirtual host +directory.htaccess + +All + + +

    $B$3$N%G%#%l%/%F%#%V$O!"%j%/%(%9%H%\%G%#$K5v$5$l$k%P%$%H?t!"(Bbytes + $B$r(B 0 ($BL5@)8B$r0UL#$7$^$9(B) $B$+$i(B 2147483647 (2GB) $B$^$G$N?tCM$G;XDj$7$^$9!#(B

    + +

    LimitRequestBody $B%G%#%l%/%F%#%V$O!"(B + $B%G%#%l%/%F%#%V$,=q$+$l$?%3%s%F%-%9%H(B + ($B%5!<%PA4BN!"%G%#%l%/%H%j!"%U%!%$%k!"%m%1!<%7%g%s(B) $BFb$G(B + $B5vMF$9$k(B HTTP $B%j%/%(%9%H%a%C%;!<%8%\%G%#$N%5%$%:$K@)8B$r$+$1$k$3$H$,$G$-$^$9!#(B + $B%/%i%$%"%s%H$N%j%/%(%9%H$,$=$N@)8BCM$r1[$($F$$$l$P!"(B + $B%5!<%P$O%j%/%(%9%H$r=hM}$;$:$K%(%i!<$rJV$7$^$9!#(B + $BIaDL$N%j%/%(%9%H%a%C%;!<%8%\%G%#$N%5%$%:$O!"%j%=!<%9$NpJs$rPUT $B%a%=%C%I$N/$J$/$H$b$"$k%j%=!<%9$KBP$7$F%5!<%P$, + +

    $B$3$N%G%#%l%/%F%#%V$O!"(B + $B4IM}o$J%j%/%(%9%H$r@)8f$G$-$k$h$&$K$7!"(B + $B2?$i$+$N7A$N%5!<%S%95qH]967b(B ($BLuCm(B:DoS) $B$rHr$1$k$N$KM-8z$G$9!#(B

    + +

    $B$"$k>l=j$X$N%U%!%$%k%"%C%W%m!<%I$r5v2D$9$k>l9g$K!"(B + $B%"%C%W%m!<%I$G$-$k%U%!%$%k$N%5%$%:$r(B 100K $B$K@)8B$7$?$1$l$P!"(B + $B0J2<$N$h$&$K;XDj$7$^$9(B:

    + + + LimitRequestBody 102400 + + +
    +
    + + +LimitRequestFields +$B%/%i%$%"%s%H$+$i$N(B HTTP $B%j%/%(%9%H$N%X%C%@%U%#!<%k%I$N?t$r(B +$B@)8B$9$k(B +LimitRequestFields number +LimitRequestFields 100 +server config + + +

    number $B$K$O!"(B0 ($BL5@)8B$r0UL#$7$^$9(B) $B$+$i(B 32767 + $B$^$G$N@0?t$r;XDj$7$^$9!#(B + $B%G%U%)%k%HCM$O!"Dj?t(B DEFAULT_LIMIT_REQUEST_FIELDS + $B$K$h$j%3%s%Q%$%k;~$KDj5A$5$l$^$9(B ($BG[I[;~$K$O(B 100 $B$H;XDj$5$l$F$$$^$9(B)$B!#(B

    + +

    LimitRequestBody $B%G%#%l%/%F%#%V$O!"(B + $B%5!<%P4IM}o$N%/%i%$%"%s%H$+$i$N%j%/%(%9%H$K4^$^$l$k$G$"$m$&(B + $B%U%#!<%k%I$N?t$h$jBg$-$JCM$,I,MW$H$7$^$9!#(B + $B%/%i%$%"%s%H$K$h$j;H$o$l$?MW5a%X%C%@!<%U%#!<%k%I$N?t$,(B + 20 $B$rD6$($k$3$H$O$[$H$s$I$"$j$^$;$s$,!"(B + $B$3$l$O\:Y$J%3%s%F%s%H%M%4%7%(!<%7%g%s$r$9$k$?$a$N%V%i%&%6$N@_Dj$^$G$K$b(B + $B1F6A$5$l$k$3$H$,$"$j$^$9!#(B + $B%*%W%7%g%s$N(B HTTP $B3HD%$O%j%/%(%9%H%X%C%@%U%#!<%k%I$r;H$C$F8=$5$l$k>l9g$,(B + $BB?$/$"$j$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O!"(B + $B4IM}o$J%j%/%(%9%H$r@)8f$G$-$k$h$&$K$7!"(B + $B2?$i$+$N7A$N%5!<%S%95qH]967b(B ($BLuCm(B:DoS) $B$rHr$1$k$N$KM-8z$G$9!#(B + $B%j%/%(%9%H$N%U%#!<%k%I$,B?2a$.$k$3$H$r0UL#$9$k%(%i!<1~Ez$,(B + $BIaDL$N%/%i%$%"%s%H$KJV$5$l$k$h$&$J;~$O$3$NCM$rA}$d$7$F$/$@$5$$!#(B

    + +

    $BNc(B:

    + + + LimitRequestFields 50 + + +
    +
    + + +LimitRequestFieldSize +$B%/%i%$%"%s%H$+$i$N(B HTTP $B%j%/%(%9%H$N%X%C%@$N(B +$B%5%$%:$r@)8B$9$k(B +LimitRequestFieldsize bytes +LimitRequestFieldsize 8190 +server config + + +

    $B$3$N%G%#%l%/%F%#%V$O!"(BHTTP $B%j%/%(%9%H%X%C%@0l$D$Gbytes $B$r;XDj$7$^$9!#(B

    + +

    LimitRequestFieldSize $B%G%#%l%/%F%#%V$O!"(B + HTTP $B%j%/%(%9%H%X%C%@$G5vMF$5$l$k%5%$%:$rA}8:$5$;$k$3$H$,$G$-$^$9!#(B + $B%5!<%P$O!"$3$N%G%#%l%/%F%#%V$NCM$H$7$F!"(B + $B0lHLE*$J%/%i%$%"%s%H$+$i%j%/%(%9%H$,Aw$i$l$?:]$K!"$=$N%j%/%(%9%H$K(B + $BIUB0$7$F$$$k$I$N%X%C%@%U%#!<%k%I$K$D$$$F$b!"(B + $B==J,B-$j$kBg$-$5$K$J$C$F$$$J$1$l$P$J$j$^$;$s!#(B + $B0lHLE*$J%j%/%(%9%H%X%C%@$N%5%$%:$H$$$C$F$b!"$=$NBg$-$5$O8D!9$N(B + $B%/%i%$%"%s%H$N\:Y$J%3%s%F%s%H%M%4%7%(!<%7%g%s$r%5%]!<%H$9$k$+$I$&$+$N!"(B + $B%V%i%&%6$N@_Dj$K$b1F6A$5$l$?$j$7$^$9!#(B + SPNEGO $BG'>Z%X%C%@$G$O(B 12392 $B%P%$%H$K$^$G5Z$V$3$H$9$i$"$j$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O!"(B + $B4IM}o$J%j%/%(%9%H$r@)8f$G$-$k$h$&$K$7!"(B + $B2?$i$+$N7A$N%5!<%S%95qH]967b(B ($BLuCm(B:DoS) $B$rHr$1$k$N$KM-8z$G$9!#(B

    + +

    $BNc(B:

    + + + LimitRequestFieldSize 4094 + + + $BDL>o$O%G%U%)%k%H$+$iJQ99$9$kI,MW$O$"$j$^$;$s!#(B + +
    +
    + + +LimitRequestLine +$B%/%i%$%"%s%H$+$i$N(B HTTP $B%j%/%(%9%H9T$N%5%$%:$r@)8B$9$k(B +LimitRequestLine bytes +LimitRequestLine 8190 +server config + + +

    $B$3$N%G%#%l%/%F%#%V$O!"(BHTTP $B%j%/%(%9%H9TFb$G5vMF$5$l$k%P%$%H?t(B + bytes $B$r;XDj$7$^$9!#(B

    + +

    LimitRequestLine $B%G%#%l%/%F%#%V$K$h$j!"(B + $B%/%i%$%"%s%H$+$i$N(B HTTP $B%j%/%(%9%H9T$N5vMF%5%$%:$rA}8:$G$-$^$9!#(B + $B%j%/%(%9%H9T$O!"(BHTTP$B%a%=%C%I!"(BURI$B!"%W%m%H%3%k%P!<%8%g%s$+$i@.$C$F$*$j!"(B + LimitRequestLine $B$O%5!<%P$X$N%j%/%(%9%H$KBP$7$F(B + $B5vMF$9$k%j%/%(%9%H(B URI $B$ND9$5$r@)8B$9$k$3$H$K$J$j$^$9!#(B + $B%5!<%P$O!"(BGET $B%j%/%(%9%H$N%/%(%jItJ,$b4^$a$F!"%j%=!<%9$NL>A0$,F~$k$KB-$k(B + $BBg$-$5$rI,MW$H$7$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O!"(B + $B4IM}o$J%j%/%(%9%H$r@)8f$G$-$k$h$&$K$7!"(B + $B2?$i$+$N7A$N%5!<%S%95qH]967b(B ($BLuCm(B:DoS) $B$rHr$1$k$N$KM-8z$G$9!#(B

    + +

    $BNc(B:

    + + + LimitRequestLine 4094 + + + $BDL>o$O%G%U%)%k%H$+$iJQ99$9$kI,MW$O$"$j$^$;$s!#(B +
    +
    + + +LimitXMLRequestBody +XML $B7A<0$N%j%/%(%9%H$N%\%G%#$N%5%$%:$r@)8B$9$k(B +LimitXMLRequestBody bytes +LimitXMLRequestBody 1000000 +server configvirtual host +directory.htaccess +All + + +

    XML $B7A<0$N%j%/%(%9%H$N%\%G%#$N:GBgCM$r(B ($B%P%$%HC10L$G(B) $B@)8B$7$^$9!#(B + $BCM$K(B 0 $B$r;XDj$9$k$H%A%'%C%/$rL58z$K$7$^$9!#(B

    + +

    $BNc(B:

    + + + LimitXMLRequestBody 0 + + +
    +
    + + +Location +$B0O$s$@%G%#%l%/%F%#%V$r%^%C%A$9$k(B URL $B$N$_$KE,MQ(B +<Location + URL-path|URL> ... </Location> +server configvirtual host + + + +

    Location $B%G%#%l%/%F%#%V$O!"(B + URL $B$K$h$jCf$K=q$+$l$?%G%#%l%/%F%#%V$NE,MQHO0O$r@)8B$7$^$9!#(B + Directory + $B%G%#%l%/%F%#%V$H;w$F$$$F!"(B + </Location> $B%G%#%l%/%F%#%V$G=*N;$9$k(B + $B%5%V%;%/%7%g%s$r3+;O$7$^$9!#(B + Location $B%;%/%7%g%s$O!"(B + Directory $B%;%/%7%g%s$H(B + .htaccess $B$NFI$_9~$_$N8e!"(B + Files $B%;%/%7%g%s$r(B + $BE,MQ$7$?8e$K!"@_Dj%U%!%$%k$K8=$l$?=g$K=hM}$5$l$^$9!#(B

    + +

    Location $B%;%/%7%g%s$O(B + $B40A4$K%U%!%$%k%7%9%F%`$H4XO"$;$:$KF0:n$7$^$9!#$3$N$3$H$+$iF3$+$l$k(B + $B7k2L$K$O$$$D$/$+Cm0U$9$kE@$,$"$j$^$9!#:G$b=EMW$J$b$N$O!"(B + $B%U%!%$%k%7%9%F%`$N0LCV$X$N%"%/%;%9@)8f$K(B Location $B%G%#%l%/%F%#%V$r;H$&$Y$-$G$O$J$$(B + $B$H$$$&$3$H$G$9!#J#?t$N(B URL $B$,%U%!%$%k%7%9%F%`$NF1$80LCV$K%^%C%W$5$l$k(B + $B2DG=$,$"$j$^$9$N$G!"$=$N$h$&$J%"%/%;%9@)8f$O2sHr$5$l$F$7$^$&2DG=@-$,(B + $B$"$j$^$9!#(B

    + + $B$$$D(B <directive + type="section">Location</directive> $B$r;H$&$+(B + +

    Location $B%G%#%l%/%F%#%V$O(B + $B%U%!%$%k%7%9%F%`30$N%3%s%F%s%D$K%G%#%l%/%F%#%V$rE,MQ$9$k$H$-$K(B + $B;HMQ$7$F$/$@$5$$!#%U%!%$%k%7%9%F%`$KB8:_$9$k%3%s%F%s%D$KBP$7$F$O!"(B + Directory $B$H(B Files $B$r;H$C$F$/$@$5$$!#(B + $BNc30$O!"(B<Location /> $B$G!"$3$l$O%5!<%PA4BN$KBP$7$F(B + $B@_Dj$rE,MQ$9$k4JC1$JJ}K!$G$9!#(B

    +
    + +

    $BA4$F$N(B ($B%W%m%-%70J30$N(B) $B%j%/%(%9%H$KBP$7!"(B + URL $B$O(B /path/ $B$H$$$&!"(B + $B@\F,<-(B http://servername $B$r4^$^$J$$7A$G%^%C%A$7$^$9!#(B + $B%W%m%-%7%j%/%(%9%H$N>l9g$K$O!"(Bscheme://servername/path + $B$H$$$&@\F,<-$r4^$`7A$G%^%C%A$7!"@\F,<-$r4^$a$F;XDj$9$kI,MW$,$"$j$^$9!#(B

    + +

    URL $B$K$O%o%$%k%I%+!<%I$rMxMQ$9$k$3$H$,$G$-$^$9!#(B + ? $B$OG$0U$N0lJ8;z!"(B* $B$OG$0U$NJ8;zNs$K%^%C%A$7$^$9!#(B

    + +

    ~ $B$H$$$&J8;z$rDI2C$9$k$3$H$G!"3HD%@55,I=8=$r(B + $BMxMQ$9$k$3$H$b$G$-$^$9!#(B + $BNc$($P(B:

    + + + <Location ~ "/(extra|special)/data"> + + +

    $B$O(B URL $B$K(B /extra/data $B$+(B /special/data $B$H$$$&J8;zNs$,(B + $B4^$^$l$F$$$k>l9g$K%^%C%A$7$^$9!#(B + LocationMatch $B%G%#%l%/%F%#%V$O(B + Location $B$N@55,I=8=(B + $BHG$H$^$C$?$/F1$8F0:n$r$7$^$9!#(B

    + +

    Location $B5!G=$O!"(BSetHandler $B%G%#%l%/%F%#%V$H(B + $BAH9g$o$;$FMxMQ$9$k$HFC$KJXMx$G$9!#(B + $BNc$($P!"(Bfoo.com $B$N%V%i%&%6$+$i$N$_%9%F!<%?%9$N;2>H$rM-8z$K$7$?$1$l$P!"(B + $B + + + <Location /status>
    + + SetHandler server-status
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    +
    + </Location> +
    + +/ ($B%9%i%C%7%e(B) $B$K4X$9$kCm(B +

    $B%9%i%C%7%eJ8;z$O!"(BURL $BFb$K8=$l$k>l=j$K1~$8$FJQ2=$9$k(B + $BFCJL$J0UL#$r;}$C$F$$$^$9!#(B + $B%U%!%$%k%7%9%F%`$K$*$$$FMxMQ$9$k>l9g$K$OJ#?t$N%9%i%C%7%e$G$b0l$D$N(B + $B%9%i%C%7%e$H$7$F07$o$l$k$3$H$,B?$$$G$9$,!"(B + ($B$9$J$o$A(B$B!"(B/home///foo $B$O(B + /home/foo $B$HF1$8$$$C$?$h$&$K(B) + URL $B$K$*$$$F$OI,$:$7$b$=$&$J$k$o$1$G$O$"$j$^$;$s!#(B + LocationMatch + $B%G%#%l%/%F%#%V$d@55,I=8=$rMxMQ$7$?(B + Location $B%G%#%l%/%F%#%V$G!"(B + $BJ#?t$N%9%i%C%7%e$K%^%C%A$5$;$?$$$H$-$K$O!"!"L@<(E*$K5-=R$9$k(B + $BI,MW$,$"$j$^$9!#(B

    + +

    $BNc$($P!"(B<LocationMatch ^/abc> $B$O!"(B + /abc $B$H$$$&%j%/%(%9%H(B URL $B$K%^%C%A$7$^$9$,!"(B + //abc $B$H$$$&%j%/%(%9%H(B URL $B$K$O%^%C%A$7$^$;$s!#(B + ($B@55,I=8=$G$J$$(B) Location + $B%G%#%l%/%F%#%V$O!"(B + proxy $B%j%/%(%9%H$KBP$7$FMxMQ$9$k:]$K$OF1MM$N?6$kIq$$$r$7$^$9$,!"(B + ($B@55,I=8=$G$J$$(B) Location $B$r(B proxy + $B$G$J$$%j%/%(%9%H$KBP$7$FMxMQ$9$k:]$K$O!"(B + $B0l$D$N%9%i%C%7%e$GJ#?t$N%9%i%C%7%e$K%^%C%A$7$^$9!#(B + $BNc$($P!"(B<Location /abc/def> $B$H;XDj$7!"(B + /abc//def $B$H$$$&%j%/%(%9%H$,$"$l$P!"(B + $B%^%C%A$9$k$3$H$K$J$j$^$9!#(B

    + +
    +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +LocationMatch +$B0O$s$@%G%#%l%/%F%#%V$r@55,I=8=$K%^%C%A$9$k(B URL $B$N$_$K(B +$BE,MQ(B +<LocationMatch + regex> ... </LocationMatch> +server configvirtual host + + + +

    LocationMatch $B%G%#%l%/%F%#%V$O!"(B + Location $B$HF1$8MM$K(B + URL $B$K$h$jCf$K=q$+$l$?%G%#%l%/%F%#%V$NE,MQHO0O$r@)8B$7$^$9!#(B + $BC"$7!"0z?t$OIaDL$NJ8;zNs$G$O$J$/!"@55,I=8=$H$J$j$^$9!#Nc$($P!"(B

    + + + <LocationMatch "/(extra|special)/data"> + + +

    $B$O(B URL $B$K(B /extra/data $B$+(B /special/data + $B$H$$$&J8;zNs$,4^$^$l$F$$$k>l9g$K%^%C%A$7$^$9!#(B

    +
    + +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + + +LogLevel +ErrorLog $B$N>iD9@-$r@)8f$9$k(B +LogLevel level +LogLevel warn +server configvirtual host + + + +

    LogLevel $B$O!"%(%i!<%m%0(B (ErrorLog $B%G%#%l%/%F%#%V$r(B + $B8+$F$/$@$5$$(B) $B$X5-O?$9$k%a%C%;!<%8$N>iD9@-$rD4@0$7$^$9!#(B + $B0J2<$N(B level $B$r;XDj$G$-!"=g$K=EMWEY$,2<$,$C$F$$$-$^$9!#(B

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%l%Y%k(B $B@bL@(B $BNc(B
    emerg $B6[5^(B - $B%7%9%F%`$,MxMQ$G$-$J$$(BChild cannot open lock file. Exiting + ($B;R%W%m%;%9$,%m%C%/%U%!%$%k$r3+$1$J$$$?$a=*N;$7$?(B)
    alert $BD>$A$KBP=h$,I,MW(Bgetpwuid: couldn't determine user name from uid + (getpwuid: UID $B$+$i%f!<%6L>$rFCDj$G$-$J$+$C$?(B)
    crit $BCWL?E*$J>uBV(Bsocket: Failed to get a socket, exiting child + (socket: $B%=%1%C%H$,F@$i$l$J$$$?$a!";R%W%m%;%9$r=*N;$5$;$?(B)
    error $B%(%i!<(BPremature end of script headers + ($B%9%/%j%W%H$N%X%C%@$,B-$j$J$$$^$^$G=*$o$C$?(B)
    warn $B7Y9p(Bchild process 1234 did not exit, sending another SIGHUP + ($B;R%W%m%;%9(B 1234 $B$,=*N;$7$J$+$C$?!#$b$&0lEY(B SIGHUP $B$rAw$k(B)
    notice $BIaDL$@$,!"=EMW$J>pJs(Bhttpd: caught SIGBUS, attempting to dump core in ... + (httpd: SIGBUS $B%7%0%J%k$r +
    info $BDI2C>pJs(B"Server seems busy, (you may need to increase + StartServers, or Min/MaxSpareServers)..." ($B!V%5!<%P$OIi2Y$,9b$$!"(B + (StartServers $B$d(B Min/MaxSpareServers $B$NCM$rA}$d$9I,MW$,$"$k$+$b(B)$B!W(B)
    debug $B%G%P%C%0%a%C%;!<%8(B"Opening config file ..." ($B@_Dj%U%!%$%k$r3+$$$F$$$k(B...)
    + +

    $BFCDj$N%l%Y%k$,;XDj$5$l$?>l9g!"$=$l$h$j9b$$%l%Y%k$NA4$F$N%a%C%;!<%8$,(B + $BJs9p$5$l$^$9!#(B + $BNc$($P(B$B!"(BLogLevel info $B$K;XDj$9$k$H!"(B + notice $B$H(B warn $B$bJs9p$5$l$^$9!#(B

    + +

    $B$J$*(B crit $B0J>e$N%l%Y%k$r;XDj$9$k$3$H$,?d>)$5$l$^$9!#(B

    + +

    $BNc(B:

    + + + LogLevel notice + + + $BCm(B +

    $B%U%!%$%k$K%m%0$r=PNO$9$k>l9g!"(Bnotice + $B%l%Y%k$N%a%C%;!<%8$OM^@)$5$l$:!"$9$Y$F%m%0$K=PNO$5$l$^$9!#(B + $B$7$+$7(B syslog $B$r;HMQ$7$F$$$k>l9g$O!"(B + $B$3$l$OEv$F$O$^$j$^$;$s!#(B

    +
    +
    +
    + + +MaxKeepAliveRequests +$B;}B3E*$J@\B3>e$G5v2D$5$l$k%j%/%(%9%H$N?t(B +MaxKeepAliveRequests number +MaxKeepAliveRequests 100 +server configvirtual host + + + +

    MaxKeepAliveRequests $B%G%#%l%/%F%#%V$O!"(B + KeepAlive $B$,M-8z$J>l9g$K!"(B + $B0l2s$N@\B3$G0 $B$K@_Dj$7$F$$$l$P!"e$5$;$k$?$a$K!"Bg$-$J?tCM$r;XDj$9$k$3$H4+$a$^$9!#(B +

    + +

    $BNc(B:

    + + + MaxKeepAliveRequests 500 + +
    +
    + + +NameVirtualHost +$BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$N$?$a$N(B IP $B%"%I%l%9$r;XDj(B +NameVirtualHost addr[:port] +server config + + +

    NameVirtualHost $B%G%#%l%/%F%#%V$O!"(B + $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H(B$B$N@_Dj$r9T$J$$$?$$>l9g$K(B + $BI,MW$H$J$k$b$N$G$9!#(B

    + +

    addr $B$K$O%[%9%HL>$r;XDj$G$-$^$9$,!"(B + $B>o$K(B IP $B%"%I%l%9$r;XDj$9$k$N$,?d>)$5$l$^$9!#(B + $BNc$($P!"(B

    + + + NameVirtualHost 111.22.33.44 + + +

    NameVirtualHost $B%G%#%l%/%F%#%V$O!"(B + $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r(B + $BMxMQ$7$F%j%/%(%9%H$rA0%Y!<%9$N%P!<%A%c%k%[%9%H%"%I%l%9$G$9!#(B + $B$?$@$7!"%U%!%$%"!<%&%)!<%k$dB>$N%W%m%-%7$,%j%/%(%9%H$rl9g$O!"(B + $B%j%/%(%9%H$rDs6!$7$?$$%^%7%s>e$NJ*M}%$%s%?!<%U%'!<%9$N(B + IP $B%"%I%l%9$r;XDj$9$kI,MW$,$"$j$^$9!#(B + $BJ#?t$N%"%I%l%9$GJ#?t$NL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r;XDj$9$k>l9g$O(B + $B3F%"%I%l%9$KBP$7$F%G%#%l%/%F%#%V$r=q$$$F$/$@$5$$!#(B

    + + $BCf(B +

    $B!V_default_ $B%5!<%P$b!"(B + NameVirtualHost $B$G;XDj$7$?(B IP $B%"%I%l%9$X$N%j%/%(%9%H(B + $B$r=hM}$9$k$3$H$O(B$B$"$j$^$;$s(B ($B$J$<$+(B + NameVirtualHost $B$r(B + $B;XDj$7$?$1$I$=$N%"%I%l%9$K(B VirtualHost $B$rDj5A$7$J$+$C$?>l9g$r=|$/(B)$B!#(B

    +
    + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$K%]!<%HHV9f$r;XDj$9$k$3$H$b2DG=$G$9!#(B + $BNc$($P(B

    + + + NameVirtualHost 111.22.33.44:8080 + + +

    IPV6 $B$N%"%I%l%9$O + + + NameVirtualHost [fe80::a00:20ff:fea7:ccea]:8080 + + +

    $B$9$Y$F$N%$%s%?%U%'!<%9$X$N%j%/%(%9%H$r* $B$r;H$$$^$9!#(B

    + + + NameVirtualHost * + + + <directive type="section">VirtualHost</directive> $B%G%#%l%/%F%#%V$N0z?t(B +

    VirtualHost $B%G%#%l%/%F%#%V$N0z?t$O(B NameVirtualHost $B%G%#%l%/%F%#%V$N0z?t$K@53N$K(B + $B9g$C$F$$$kI,MW$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    + + + NameVirtualHost 1.2.3.4
    + <VirtualHost 1.2.3.4>
    + # ...
    + </VirtualHost>
    +
    +
    + +
    + +$B%P!<%A%c%k%[%9%H@bL@=q(B + + +
    + + +Options +$B%G%#%l%/%H%j$KBP$7$F;HMQ2DG=$J5!G=$r@_Dj$9$k(B +Options + [+|-]option [[+|-]option] ... +Options All +server configvirtual host +directory.htaccess + +Options + + +

    Options $B%G%#%l%/%F%#%V$O!"FCDj$N%G%#%l%/%H%j$KBP$7$F(B + $B$I$N5!G=$,;HMQ2DG=$+$r@)8f$7$^$9!#(B

    + +

    option $B$r(B None$B$K;XDj$9$k$H!"(B + $BFCJL$J5!G=$OA4$FL58z$K$J$j$^$9!#(B + $B$^$?!"0J2<$N<($9(B 1 $B8D0J>e$N$b$N$r;XDj$G$-$^$9!#(B

    + +
    +
    All
    + +
    MultiViews $B$r=|$$$?A4$F$N5!G=$,M-8z$H$J$j$^$9!#(B + $B$3$l$,%G%U%)%k%H$G$9!#(B
    + +
    ExecCGI
    + +
    + mod_cgi $B$K$h$k(B CGI $B%9%/%j%W%H$N + +
    FollowSymLinks
    + +
    + $B%5!<%P$,!"$3$N%G%#%l%/%H%jFb$G%7%s%\%j%C%/%j%s%/$r$?$I$l$k$h$&$K$7$^$9!#(B +

    $B%5!<%P$,%7%s%\%j%C%/%j%s%/$r$?$I$k>l9g$G$b!"(B + Directory $B%;%/%7%g%s$K(B + $B%^%C%A$5$;$k$?$a$N(B + $B%Q%9L>$O(B$BJQ99$5$l$^$;$s(B$B!#(B

    +

    Location $BFb$K(B + $B$3$N%*%W%7%g%s$r;XDj$7$F$b(B$BL5;k$5$l$k(B$B$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B

    + +
    Includes
    + +
    + mod_include $B$,Ds6!$9$k(B SSI $B$rM-8z$K$7$^$9!#(B
    + +
    IncludesNOEXEC
    + +
    + SSI $B$OM-8z$K$J$j$^$9$,!"(B#exec $B%3%^%s%I(B $B$H(B #exec CGI $B$OL58z$K$J$j$^$9!#(B + $B$?$@$7!"(B#include virtual $B$K$h$j!"(BScriptAlias $B$5$l$?%G%#%l%/%H%j$G(B + CGI $B$r + +
    Indexes
    + +
    + $B$b$7!"(BURL $B$,%G%#%l%/%H%j$K%^%C%W$9$k%j%/%(%9%H$G$"$C$F!"(B + $B3n$D(B DirectoryIndex $B$G;XDj$7$?%U%!%$%k(B ($BNc$($P!"(Bindex.html) $B$,(B + $B%G%#%l%/%H%jFb$KL5$1$l$P!"(Bmod_autoindex $B$,(B + $B%G%#%l%/%H%jFb$N0lMw$r@07A$7$FJV$7$^$9!#(B
    + +
    MultiViews
    + +
    + mod_negotiation $B$K$h$k(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $B$5$l$?(B "MultiViews" $B$r5v2D$7$^$9!#(B
    + +
    SymLinksIfOwnerMatch
    + +
    + $B%7%s%\%j%C%/@h$N%U%!%$%k$^$?$O%G%#%l%/%H%j$,!"(B + $B%7%s%\%j%C%/%j%s%/$N=jM-%f!<%6(B ID $B$HF1$8>l9g$K$N$_%7%s%\%j%C%/%j%s%/$r(B + $B$?$I$l$k$h$&$K$7$^$9!#(B + + $BCm(B Location $BFb$K$3$N%*%W%7%g%s$r(B + $B;XDj$7$F$bL5;k$5$l$^$9!#(B +
    +
    + +

    $BDL>o!"%G%#%l%/%H%j$KBP$7$FJ#?t$N(B Options $B$,(B + $BE,MQ2DG=$J>l9g!"(B + $B:G$b6a$$$b$N0l$D$N$_$,E,MQ$5$l!"B>$N$b$N$OL5;k$5$l$^$9!#(B + $BJ#?t$N;XDj$,%^!<%8$5$l$k$o$1$G$O$"$j$^$;$s!#(B($B%;%/%7%g%s$N%^!<%8J}K!(B$B$r;2>H$7$F$/$@$5$$!#(B) + $B$7$+$7!"$9$Y$F$N(B Options $B%G%#%l%/%F%#%V$,(B + $B$d(B - $BIU$-$G(B + $B;XDj$5$l$?>l9g$O%*%W%7%g%s$NCM$O%^!<%8$5$l$^$9!#(B + + $B$rF,$K$D$1$l$P8=:_$N@_Dj$K2C$($i$l!"(B + - $B$rIU$1$l$P8=:_$N@_Dj$+$i:o=|$5$l$^$9!#(B

    + +

    $BNc$($P!"(B+ $B$d(B - $B$rMxMQ$7$J$$>l9g$O(B:

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options Includes
    +
    + </Directory> +
    + +

    /web/docs/spec $B$H$$$&%G%#%l%/%H%j$K$O!"(B + Includes $B$@$1$,E,MQ$5$l$^$9!#(B + $B$7$+$7!"(B2 $BHVL\$N(B Options $B$G(B + $B$d(B - $B$rMxMQ$7$F$_$k$H(B:

    + + + <Directory /web/docs>
    + + Options Indexes FollowSymLinks
    +
    + </Directory>
    +
    + <Directory /web/docs/spec>
    + + Options +Includes -Indexes
    +
    + </Directory> +
    + +

    /web/docs/spec $B$H$$$&%G%#%l%/%H%j$K$O!"(B FollowSymLinks $B$H(B + Includes $B$,E,MQ$5$l$^$9!#(B

    + + $BCm(B +

    -IncludesNOEXEC $B$b$7$/$O(B + -Includes $B$r;XDj$9$k$H!"(B + $BA0$N@_Dj$,$I$N$h$&$K$J$C$F$$$h$&$H$b(B SSI $B$OL58z$H$J$j$^$9!#(B

    +
    + +

    $B$I$N$h$&$J@_Dj$b$5$l$F$$$J$1$l$P!"%G%U%)%k%H$G$O(B All $B$K(B + $B$J$j$^$9!#(B

    +
    +
    + + +Require +$B$I$NG'>Z:Q$_%f!<%6$,%j%=!<%9$r%"%/%;%9$G$-$k$+$rA*Br$9$k(B +Require entity-name [entity-name] ... +directory.htaccess + +AuthConfig + + +

    $B$3$N%G%#%l%/%F%#%V$O!"$I$NG'>Z:Q$_$N%f!<%6$,%j%=!<%9$K(B + $B%"%/%;%9$9$k$3$H$,$G$-$k$+$r;XDj$7$^$9!#(B + $B0J2<$N$h$&$J9=J8$K$J$j$^$9!#(B

    + +
    +
    Require user userid [userid] ...
    + +
    $B;XDj$5$l$?%f!<%6$N$_!"%G%#%l%/%H%j$X$N%"%/%;%9$r5v2D$7$^$9!#(B
    + +
    Require group group-name [group-name] ...
    + +
    $B;XDj$5$l$?%0%k!<%W$KB0$9$k%f!<%6$N$_!"%G%#%l%/%H%j$X$N%"%/%;%9$r5v2D$7$^$9!#(B
    + +
    Require valid-user
    + +
    $BA4$F$NG'>Z$5$l$?%f!<%6$K!"%G%#%l%/%H%j$X$N%"%/%;%9$r5v2D$7$^$9!#(B
    +
    + +

    Require $B$O!"@5$7$/F0:n$9$k$?$a$K$O(B AuthName $B5Z$S(B AuthType $B%G%#%l%/%F%#%V$d!"(B + ($B%f!<%6$H%0%k!<%W$r;XDj$9$k$?$a$K(B) AuthUserFile $B5Z$S(B AuthGroupFile + $B$H$$$C$?%G%#%l%/%F%#%V$H6&$K(B + $B;XDj$9$kI,MW$,$"$j$^$9!#(B + $BNc$($P(B:

    + + + AuthType Basic
    + AuthName "Restricted Resource"
    + AuthUserFile /web/users
    + AuthGroupFile /web/groups
    + Require group admin +
    + +

    $B$3$N$h$&$K$7$FE,MQ$5$l$?%"%/%;%9@)8f$O!"(B$BA4$F$N(B$B%a%=%C%I$K(B + $BBP$7$F9T$J$o$l$^$9!#(B + $BDL>o$O!"$3$l$,K>$^$7$$F0:n$G$9!#(B + $B$b$7!"FCDj$N%a%=%C%I$KBP$7$F$N$_%"%/%;%9$N@)8f$rE,MQ$7!"(B + $BB>$N%a%=%C%I$O@)8B$7$J$$>l9g$K$O!"(BLimit $B%;%/%7%g%sFb$K(B + Require $B$r(B + $B;XDj$7$F$/$@$5$$!#(B

    + +
    +Satisfy +mod_authz_host +
    + + +RLimitCPU +Apache $B$N;R%W%m%;%9$+$i5/F0$5$l$?%W%m%;%9$N(B CPU $B>CHqNL$r(B +$B@)8B$9$k(B +RLimitCPU seconds|max [seconds|max] +$BL$@_Dj!#%*%Z%l!<%F%#%s%0%7%9%F%`$N%G%U%)%k%H$r;HMQ(B +server configvirtual host +directory.htaccess +All + + +

    $B0l$D$+Fs$D$N%Q%i%a!<%?$r$H$j$^$9!#(B + $B:G=i$N%Q%i%a!<%?$OA4%W%m%;%9$KBP$9$k%j%=!<%9$N%=%U%H%j%_%C%H$r@_Dj$7!"(B + 2 $BHVL\$N%Q%i%a!<%?$O:GBg$N%j%=!<%9%j%_%C%H$r@_Dj$7$^$9!#(B + $B%Q%i%a!<%?$K$O?t;z$+!"%*%Z%l!<%F%#%s%0%7%9%F%`$N:GBg$H$J$k(B + max $B$N$I$A$i$+$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B:GBg$N%j%=!<%9%j%_%C%H$r>e$2$k$?$a$K$O!"%5!<%P$r(B + root $B$G + +

    $B$A$J$_$K!"$3$N@_Dj$O(B Apache $B$N;R%W%m%;%9<+BN$G$O$J$/!"(B + $B%j%/%(%9%H$r + +

    CPU $B%j%=!<%9$N%j%_%C%H$O%W%m%;%9$"$?$j$NIC?t$GI=$o$5$l$^$9!#(B

    + +
    +RLimitMEM +RLimitNPROC +
    + + +RLimitMEM +Apache $B$N;R%W%m%;%9$+$i5/F0$5$l$?%W%m%;%9$N%a%b%j>CHqNL$r(B +$B@)8B$9$k(B +RLimitMEM bytes|max [bytes|max] +$BL$@_Dj!#%*%Z%l!<%F%#%s%0%7%9%F%`$N%G%U%)%k%H$r;HMQ(B +server configvirtual host +directory.htaccess +All + + +

    $B0l$D$+Fs$D$N%Q%i%a!<%?$r$r$H$j$^$9!#(B + $B:G=i$N%Q%i%a!<%?$OA4%W%m%;%9$KBP$9$k%j%=!<%9$N%=%U%H%j%_%C%H$r@_Dj$7!"(B + 2 $BHVL\$N%Q%i%a!<%?$O:GBg$N%j%=!<%9%j%_%C%H$r@_Dj$7$^$9!#(B + $B%Q%i%a!<%?$K$O?t;z$+!"%*%Z%l!<%F%#%s%0%7%9%F%`$N:GBg$H$J$k(B + max $B$N$I$A$i$+$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B:GBg$N%j%=!<%9%j%_%C%H$r>e$2$k$?$a$K$O!"%5!<%P$r(B + root $B$G + +

    $B$3$N@_Dj$O(B Apache $B$N;R%W%m%;%9<+BN$G$O$J$/!"(B + $B%j%/%(%9%H$r + +

    $B%a%b%j%j%=!<%9$N%j%_%C%H$O%W%m%;%9$"$?$j$N%P%$%H?t$GI=$o$5$l$^$9!#(B

    +
    +RLimitCPU +RLimitNPROC +
    + + +RLimitNPROC +Apache $B$N;R%W%m%;%9$+$i5/F0$5$l$?%W%m%;%9$,5/F0$9$k%W%m%;%9$N(B +$B?t$r@)8B$9$k(B +RLimitNPROC number|max [number|max] +$BL$@_Dj!#%*%Z%l!<%F%#%s%0%7%9%F%`$N%G%U%)%k%H$r;HMQ(B +server configvirtual host +directory.htaccess +All + + +

    $B0l$D$+Fs$D$N%Q%i%a!<%?$r$H$j$^$9!#(B + $B:G=i$N%Q%i%a!<%?$OA4%W%m%;%9$KBP$9$k%j%=!<%9$N%=%U%H%j%_%C%H$r@_Dj$7!"(B + 2 $BHVL\$N%Q%i%a!<%?$O:GBg$N%j%=!<%9%j%_%C%H$r@_Dj$7$^$9!#(B + $B%Q%i%a!<%?$K$O?t;z$+!"%*%Z%l!<%F%#%s%0%7%9%F%`$N:GBg$H$J$k(B + max $B$N$I$A$i$+$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B:GBg$N%j%=!<%9%j%_%C%H$r>e$2$k$?$a$K$O!"%5!<%P$r(B + root $B$G + +

    $B$3$N@_Dj$O(B Apache $B$N;R%W%m%;%9<+BN$G$O$J$/!"(B + $B%j%/%(%9%H$r + +

    $B%W%m%;%9$N@)8B$O!"%f!<%6$"$?$j$N%W%m%;%9?t$G@)8f$5$l$^$9!#(B

    + + $BCm(B +

    CGI $B%W%m%;%9$,%&%'%V%5!<%P$N%f!<%6(B ID $B0J30$G$BL5$1$l$P(B$B!"(B + $B$3$N%G%#%l%/%F%#%V$O!"%5!<%P<+?H$,@8@.$G$-$k%W%m%;%9$N?t$r@)8B$9$k$3$H$K$J$j$^$9!#(B + $B$=$N$h$&$J>u67$K$J$C$F$$$k$+$I$&$+$O!"(Berror_log $BCf$N(B + cannot fork $B$H$$$&%a%C%;!<%8$K$h$j(B + $B3NG'$9$k$3$H$,$G$-$^$9!#(B

    + + +RLimitMEM +RLimitCPU + + + +Satisfy +$B%[%9%H%l%Y%k$N%"%/%;%9@)8f$H%f!<%6G'>Z$H$NAj8_:nMQ$r;XDj(B +Satisfy Any|All +Satisfy All +directory.htaccess + +AuthConfig +$B%P!<%8%g%s(B 2.0.51 $B0J9_$G$O(B Limit $B%G%#%l%/%F%#%V$H(B LimitExcept $B%G%#%l%/%F%#%V$N1F6A$r + + +

    Allow $B$H(B + Require $B$NN>J}$,;H$o$l$F$$$k$H$-$N(B + $B%"%/%;%9%]%j%7!<$r@_Dj$7$^$9!#%Q%i%a!<%?$O(B All $B$+(B Any + $B$G$9!#$3$N%G%#%l%/%F%#%V$O$"$k>l=j$X$N%"%/%;%9$,%f!<%6L>(B/$B%Q%9%o!<%I(B + $B$H(B$B%/%i%$%"%s%H$N%[%9%H$N%"%I%l%9$G@)8B$5$l$F$$$k$H$-$K$N$_(B + $BLrN)$A$^$9!#%G%U%)%k%H$NF0:n(B (All) $B$O%/%i%$%"%s%H$,%"%I%l%9$K$h$k(B + $B%"%/%;%9@)8B$rK~$?$7!"(B$B$+$D(B$B@5$7$$%f!<%6L>$H%Q%9%o!<%I$rF~NO$9$k$3$H$r(B + $BMW5a$7$^$9!#(BAny $B$G$O!"%/%i%$%"%s%H$O%[%9%H$N@)8B$rK~$?$9$+!"(B + $B@5$7$$%f!<%6L>$H%Q%9%o!<%I$NF~NO$r$9$k$+$r$9$l$P%"%/%;%9$r5v2D$5$l$^$9!#(B + $B$3$l$O!"$"$k>l=j$r%Q%9%o!<%I$GJ]8n$9$k$1$l$I!"FCDj$N%"%I%l%9$+$i$N(B + $B%/%i%$%"%s%H$K$O%Q%9%o!<%I$NF~NO$rMW5a$;$:$K%"%/%;%9$r5v2D$9$k!"(B + $B$H$$$&$h$&$J$H$-$K;HMQ$G$-$^$9!#(B

    + +

    $BNc$($P!"F1$8%M%C%H%o!<%/>e$K$$$k?M$K$O%&%'%V%5%$%H$N$"$kItJ,$K$D$$$F(B + $BL5@)8B$N%"%/%;%9$r5v$7$?$$$1$l$I!"30$N%M%C%H%o!<%/$N?M$K$O(B + $B%Q%9%o!<%I$rDs6!$5$;$k$h$&$K$9$k$?$a$K$O!" + + + Require valid-user
    + Allow from 192.168.1
    + Satisfy Any +
    + +

    $B%P!<%8%g%s(B 2.0.51 $B$+$i$O(B + Limit $B%;%/%7%g%s$H(B + LimitExcept $B%;%/%7%g%s$r;HMQ$9$k$3$H$G(B + Satisfy $B%G%#%l%/%F%#%V$,(B + $BE,MQ$5$l$k%a%=%C%I$r@)8B$9$k$3$H$,(B + $B$G$-$k$h$&$K$J$j$^$7$?!#(B

    +
    + Allow + Require +
    + + +ScriptInterpreterSource +CGI $B%9%/%j%W%H$N%$%s%?!<%W%j%?$N0LCV$rD4$Y$k$?$a$N +ScriptInterpreterSource Registry|Registry-Strict|Script +ScriptInterpreterSource Script +server configvirtual host +directory.htaccess +FileInfo +Win32 $B$N$_!#(B +$B%*%W%7%g%s(B Registry-Strict $B$O(B Apache 2.0 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O!"(BApache $B$G(B CGI $B%9%/%j%W%H$r(B + $Bl9g$KMxMQ$9$k%$%s%?!<%W%j%?$r!"(B + $B$I$N$h$&$KC5$7=P$9$+$K$D$$$F@)8f$9$k$?$a$K;HMQ$7$^$9!#(B + $B%G%U%)%k%H$N@_Dj$O(B Script $B$G$9!#$3$l$O%9%/%j%W%H$N(B + shebang $B9T(B ($B:G=i$N9T$G(B #! $B$+$i;O$^$k$b$N(B) + $B$K;X$5$l$F$$$k%$%s%?!<%W%j%?$r;HMQ$7$^$9!#(BWin32 $B$G$O$=$N9T$O(B + $B0J2<$NMM$K$J$j$^$9!#(B

    + + + #!C:/Perl/bin/perl.exe + + +

    $B$b$7$/$O!"(Bperl $B$,(B PATH $B$K$"$k>l9g$OC1$K(B:

    + + + #!perl + + +

    ScriptInterpreterSource Registry $B$r;XDj$9$k$H!"(B + $B%9%/%j%W%H%U%!%$%k$N3HD%;R(B ($BNc$($P!"(B.pl) $B$r(B + $B%-!<$H$7$F!"(BWindows $B$N%l%8%9%H%j%D%j!<(B HKEY_CLASSES_ROOT + $B$r8!:w$9$k$h$&$K$J$j$^$9!#%l%8%9%H%j$N%5%V%-!<(B + Shell\ExecCGI\Command $B$+!"$=$l$,B8:_$7$J$$>l9g$O(B + Shell\Open\Command $B$,%9%/%j%W%H%U%!%$%k$r3+$/$?$a$K(B + $B;H$o$l$^$9!#%l%8%9%H%j%-!<$,8+$D$+$i$J$$$H$-$O!"(BApache $B$O(B Script + $B%*%W%7%g%s$,;XDj$5$l$?$H$-$NF0:n$KLa$j$^$9!#(B

    + + $B%;%-%e%j%F%#(B +

    ScriptInterpreterSource Registry $B$r(B ScriptAlias $B$5$l$?%G%#%l%/%H%j$G;H$&$H$-$O(B + $BCm0U$7$F$/$@$5$$!#(BApache $B$O$=$N%G%#%l%/%H%jCf$N(B$B$9$Y$F$N(B$B%U%!%$%k$r(B + $BRegistry $B$H$$$&@_Dj$ODL>o$O$^$7$/$J$$%W%m%0%i%`$N.htm $B%U%!%$%k$N%G%U%)%k%H$N!V3+$/!W%3%^%s%I$O(B + Microsoft Internet Explorer $B$r.htm $B%U%!%$%k$X$N%j%/%(%9%H$O%5!<%P$N(B + $B%P%C%/%0%i%&%s%I$G%V%i%&%6$r + + +

    Apache 2.0 $B$+$iF3F~$5$l$?%*%W%7%g%s(B Registry-Strict $B$O(B + Registry $B$HF1$8$3$H$r9T$J$$$^$9$,!"%5%V%-!<(B + Shell\ExecCGI\Command $B$N$_$r;H$$$^$9!#(B + ExecCGI $B%-!<$OIaDL$K;H$o$l$k%-!<$G$O$"$j$^$;$s!#(BWindows + $B%l%8%9%H%j$K + + + + +ServerAdmin +$B%5!<%P$,%/%i%$%"%s%H$KAw$k%(%i!<%a%C%;!<%8$K4^$a$kEE;R%a!<%k$N(B +$B%"%I%l%9(B +ServerAdmin email-address|URL +server configvirtual host + + + +

    ServerAdmin $B$O!"%/%i%$%"%s%H$KJV$9$5$^$6$^$J(B + $B%(%i!<%a%C%;!<%8Cf$K5-=R$9$k!"(B + $BLd9g$;%"%I%l%9$r@_Dj$7$^$9!#M?$($i$l$?0z?t$r(B httpd $B$,(B + URL $B$HG'<1$7$J$$>l9g$O!"(Bemail-address $B$@$H2rmailto: $B$rIU$1$^$9!#(B + $B)$5$l$F$$$^$9!#(B + $BB?$/$N(B CGI $B%9%/%j%W%H$O$=$&$J$C$F$$$k$3$H$r2>Dj$7$F$$$^$9!#(B + URL $B$r;H$&>l9g$O!"$"$J$?$N4IM}2<$K$"$kJL%5!<%P$r;X$9$h$&$K$7$F$/$@$5$$!#(B + $B$=$&$G$J$$$H!"%(%i!<$,5/$3$C$?$H$-$KO"Mm$r$9$k$3$H$,$G$-$J$/$J$C$F(B + $B$7$^$$$^$9!#(B +

    + +

    $B$=$N:]!"$3$l$N$?$a$K@lMQ$N%"%I%l%9$r@_Dj$9$k$N$,NI$$$G$7$g$&!#(B + $BNc$($P!"(B

    + + + ServerAdmin www-admin@foo.example.com + + +

    $B$H$$$C$?$h$&$K$7$^$9!#%f!<%6$O$$$D$b%5!<%P$K4X$9$kOC$G$"$k$H$$$&$3$H$r(B + $BL@5-$7$F$/$k$o$1$G$O$"$j$^$;$s$N$G!#(B

    + +
    +
    + + +ServerAlias +$B%j%/%(%9%H$rL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$K%^%C%A$5$;$F$$$k$H$-$K(B +$B;HMQ$5$l$k%[%9%H$NJLL>(B +ServerAlias hostname [hostname] ... +virtual host + + +

    ServerAlias $B%G%#%l%/%F%#%V$O!"(B$B%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H(B$B$K$*$$$F(B + $B;HMQ$9$k%[%9%H$NJLL>$r;XDj$7$^$9!#(B

    + + + <VirtualHost *>
    + ServerName server.domain.com
    + ServerAlias server server2.domain.com server2
    + # ...
    + </VirtualHost> +
    +
    +Apache $B%P!<%A%c%k%[%9%H@bL@=q(B +
    + + +ServerName +$B%5!<%P$,<+J,<+?H$r<($9$H$-$K;H$&%[%9%HL>$H%]!<%H(B +ServerName fully-qualified-domain-name[:port] +server configvirtual host + +$B$3$N%G%#%l%/%F%#%V$O%P!<%8%g%s(B 2.0 $B$G$O%P!<%8%g%s(B 1.3 $B$N(B + Port $B%G%#%l%/%F%#%V$N5!G=$b4^$_$^$9!#(B + + +

    ServerName $B%G%#%l%/%F%#%V$O!"(B + $B%5!<%P$,<+J,<+?H$r<($9%[%9%HL>$H%]!<%H$r@_Dj$7$^$9!#(B + $B$3$l$O!"%j%@%$%l%/%H$9$k(B URL $B$r@8@.$9$k:]$KMxMQ$5$l$^$9!#(B + $BNc$($P!"%&%'%V%5!<%P$rF0$+$7$F$$$k%^%7%s$O(B simple.example.com + $B$G!"(BDNS $B$N%(%$%j%"%9(B www.example.com $B$b$"$k$H$-$K!"(B + $B%&%'%V%5!<%P$,8e + + + ServerName www.example.com:80 + + +

    ServerName $B$,;XDj$5$l$F$$$J$$$H$-$O!"(B + $B%5!<%P$O(B IP $B%"%I%l%9$+$i5U0z$-$r9T$J$&$3$H$G%[%9%HL>$rCN$m$&$H$7$^$9!#(B + ServerName $B$K%]!<%H$,;XDj$5$l$F$$$J$$$H$-$O!"(B + $B%5!<%P$O%j%/%(%9%H$,Mh$F$$$k(B + $B%]!<%H$r;H$$$^$9!#:G9b$N?.Mj@-$H3NServerName $B$r;H$C$F%[%9%HL>$H%]!<%H$rL@<(E*$K(B + $B;XDj$7$F$/$@$5$$!#(B

    + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H(B + $B$rMxMQ$7$F$$$k>l9g!"(BVirtualHost $B%;%/%7%g%sFb$N(B + ServerName $B$O$3$N%P!<%A%c%k%[%9%H$K%^%C%A$9$k$?$a$K(B + $B2?$,%j%/%(%9%H$N(B Host: $B%X%C%@$K8=$l$kI,MW$,$"$k$N$+$r;XDj$7$^$9!#(B

    + +

    $B<+8J;2>H(B URL ($BNc$($P(B mod_dir $B%b%8%e!<%k$K$h$k$b$N$J$I(B) + $B$,;XDj$5$l$?%]!<%H$r;H$&$+!"%/%i%$%"%s%H$N%j%/%(%9%H$N%]!<%HHV9f$r;H$&$+$r(B + $B7hDj$9$k@_Dj$O(B UseCanonicalName + $B%G%#%l%/%F%#%V$r;2>H$7$F$/$@$5$$!#(B

    +
    + +DNS $B$H(B Apache $B$K4X$9$kOC(B +Apache $B%P!<%A%c%k%[%9%H@bL@=q(B +UseCanonicalName +NameVirtualHost +ServerAlias +
    + + +ServerPath +$BHs8_49$N%V%i%&%6$,L>A0%Y!<%9$N%P!<%A%c%k%[%9%H$K%"%/%;%9$7$?$H$-$N(B +$B$?$a$N8_49MQ(B URL $B%Q%9L>(B +ServerPath URL-path +virtual host + + +

    ServerPath $B%G%#%l%/%F%#%V$O!"(B$B%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H(B$B$K$*$$$FMxMQ$9$k(B + $B8_49MQ(B URL $B%Q%9L>$r@_Dj$7$^$9!#(B

    +
    +Apache $B%P!<%A%c%k%[%9%H@bL@=q(B +
    + + +ServerRoot +$B%$%s%9%H!<%k$5$l$?%5!<%P$N%Y!<%9%G%#%l%/%H%j(B +ServerRoot directory-path +ServerRoot /usr/local/apache +server config + + +

    ServerRoot $B%G%#%l%/%F%#%V$O!"(B + $B%5!<%P$,B8:_$9$k%G%#%l%/%H%j$r@_Dj$7$^$9!#(B + $BDL>o!"(Bconf/ $B$d(B logs/ $B$H$$$C$?%5%V%G%#%l%/%H%j$,(B + $BB8:_$7$^$9!#(B + $B$^$?!"B>$N@_Dj%G%#%l%/%F%#%V(B ($BNc$($P(B Include $B$d(B LoadModule $B$J$I(B) $B$K$*$1$kAjBP%Q%9$O!"(B + $B$3$N%G%#%l%/%H%j$+$i$NAjBP0LCV$H$J$j$^$9!#(B

    + + $BNc(B + ServerRoot /home/httpd + + + +
    +httpd $B$N(B -d + $B%*%W%7%g%s(B +ServerRoot $B$N8"8B$rE,@Z$K@_Dj$9$kJ}K!$O(B$B%;%-%e%j%F%#$N$3$D(B +
    + + +ServerSignature +$B%5!<%P$,@8@.$9$k%I%-%e%a%s%H$N%U%C%?$r@_Dj(B +ServerSignature On|Off|EMail +ServerSignature Off +server configvirtual host +directory.htaccess + +All + + +

    ServerSignature $B%G%#%l%/%F%#%V$O!"(B + $B%5!<%P$,@8@.$9$k%I%-%e%a%s%H(B + ($B%(%i!<%a%C%;!<%8!"(Bmod_proxy $B$K$*$1$k(B FTP $B$N%G%#%l%/%H%j%j%9%H!"(B + mod_info $B$N=PNO!"Ey!9(B) + $B$N:G2<9T$KIUM?$9$k%U%C%?$N@_Dj$r9T$J$$$^$9!#(B + $B$=$N$h$&$J%U%C%?9T$rM-8z$K$7$?$$M}M3$K$O!"(B + $B%W%m%-%7$,J#?tO"$J$C$F$$$k>l9g$K!"%f!<%6$O$I$N%5!<%P$,JV$7$?(B + $B%(%i!<%a%C%;!<%8$+$rCN$k + + +

    $B%G%U%)%k%H$G$"$k(B Off $B$K@_Dj$r$9$k$H!"%U%C%?9T$,M^@)$5$l$^$9(B + ($B$=$7$F!"(BApache-1.2 $B0JA0$H8_49$NF0:n$r$7$^$9(B)$B!#(B + On $B$K@_Dj$7$?>l9g$O!"C1$K%I%-%e%a%s%H$NCf$K!"%5!<%P$N%P!<%8%g%s!"(B + $B2TF0Cf$N%P!<%A%c%k%[%9%H$N(B ServerName $B$N=q$+$l$?9T$rDI2C$7!"(B + EMail $B$K$7$?>l9g$O$5$i$K;2>H$5$l$?%I%-%e%a%s%H$KBP$9$k(B ServerAdmin $B$r;X$9(B "mailto:" $B$,DI2C$5$l$^$9!#(B

    + +

    $B%P!<%8%g%s(B 2.0.44 $B0J9_$G$O$3$N%G%#%l%/%F%#%V$O(B ServerSignature + $B%G%#%l%/%F%#%V$K$h$jI=<($5$l$k>pJs$b@)8f$7$^$9!#(B

    +
    +ServerTokens +
    + + +ServerTokens +Server HTTP $B1~Ez%X%C%@$r@_Dj$9$k(B +ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full +ServerTokens Full +server config + + +

    $B$3$N%G%#%l%/%F%#%V$O!"%/%i%$%"%s%H$KAw$jJV$9(B Server + $B1~Ez%X%C%@Fb$K!"%5!<%P$N0lHLE*$J(B OS $BpJs$r(B + $B4^$a$k$+$I$&$+$r;XDj$7$^$9!#(B

    + +
    +
    ServerTokens Prod[uctOnly]
    + +
    $B%5!<%P$O(B ($BNc$($P(B): Server: + Apache $B$H$$$C$?$h$&$KAw$j$^$9!#(B
    + +
    ServerTokens Major
    + +
    Server sends (e.g.): Server: + Apache/2
    + +
    ServerTokens Minor
    + +
    Server sends (e.g.): Server: + Apache/2.0
    + +
    ServerTokens Min[imal]
    + +
    $B%5!<%P$O(B ($BNc$($P(B): Server: + Apache/2.0.41 $B$H$$$C$?$h$&$KAw$j$^$9!#(B
    + +
    ServerTokens OS
    + +
    $B%5!<%P$O(B ($BNc$($P(B): Server: Apache/2.0.41 + (Unix) $B$H$$$C$?$h$&$KAw$j$^$9!#(B
    + +
    ServerTokens Full ($B$b$7$/$OL$;XDj(B)
    + +
    $B%5!<%P$O(B ($BNc$($P(B): Server: Apache/2.0.41 + (Unix) PHP/4.2.2 MyMod/1.2 $B$H$$$C$?$h$&$KAw$j$^$9!#(B
    +
    + +

    $B$3$N@_Dj$O%5!<%PA4BN$KE,MQ$5$l!"%P!<%A%c%k%[%9%H>e$GM-8z$K$7$?$j(B + $BL58z$K$7$?$j$O$G$-$^$;$s!#(B

    + +

    $B%P!<%8%g%s(B 2.0.44 $B0J9_$G$O$3$N%G%#%l%/%F%#%V$O(B ServerSignature + $B%G%#%l%/%F%#%V$K$h$jI=<($5$l$k>pJs$b@)8f$7$^$9!#(B

    +
    +ServerSignature +
    + + +SetHandler +$B%^%C%A$9$k%U%!%$%k$,%O%s%I%i$G=hM}$5$l$k$h$&$K$9$k(B +SetHandler handler-name|None +server configvirtual host +directory.htaccess + +FileInfo +Apache 2.0 $B$G(B core $B$K0\F0(B + + +

    .htaccess $B$d(B Directory + $B%;%/%7%g%s!"(BLocation + $B%;%/%7%g%s$K=q$+$l$?>l9g!"(B + $B$3$N%G%#%l%/%F%#%V$O$=$3$K$"$k$9$Y$F$N%U%!%$%k$,(B + handler-name $B$G;XDj$5$l$?(B$B%O%s%I%i(B$B$G07$o$l$k$3$H$r6/@)$7$^$9!#Nc$($P!"3HD%;R$K4X$o$i$:!"(B + $B%G%#%l%/%H%jA4BN$,%$%a!<%8%^%C%W%U%!%$%k$H$7$F2r@O$7$FM_$7$$>l9g$K$O!"(B + $B0J2<$r$=$N%G%#%l%/%H%j$N(B .htaccess + $B%U%!%$%k$K5-=R$7$^$9(B:

    + + + SetHandler imap-file + + +

    $BJL$NNc(B: URL http://servername/status + $B$,;XDj$5$l$?$H$-$K%5!<%P$,>uBVJs9p$r$9$k$h$&$K$7$?$$$H$-$O!"0J2<$r(B + httpd.conf $B$K5-=R$7$^$9(B:

    + + + <Location /status>
    + + SetHandler server-status
    +
    + </Location> +
    + +

    None $B$H$$$&CM$r@_Dj$9$k$3$H$G!"(B + $BA0$NJ}$N(B SetHandler $B$GDj5A$5$l$?@_Dj$rL58z$K$9$k$3$H$,(B + $B$G$-$^$9!#(B

    + +
    + +AddHandler + +
    + + +SetInputFilter +$B%/%i%$%"%s%H$N%j%/%(%9%H$d(B POST $B$NF~NO$r=hM}$9$k%U%#%k%?$r@_Dj$9$k(B +SetInputFilter filter[;filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    SetInputFilter $B%G%#%l%/%F%#%V$O%/%i%$%"%s%H$N(B + $B%j%/%(%9%H$d(B POST $B$NF~NO$r%5!<%P$,AddInputFilter + $B%G%#%l%/%F%#%V$r4^$a!"B>$N>l=j$GDj5A$5$l$F$$$k%U%#%k%?$N@_Dj$K(B + $BDI2C$5$l$^$9!#(B

    + +

    $BJ#?t$N%U%#%k%?$r;XDj$9$k$H$-$O!"%G!<%?$r=hM}$9$k=gHV$K(B + $B%;%_%3%m%s$G6h@Z$kI,MW$,$"$j$^$9!#(B

    + +
    +$B%U%#%k%?(B$B@bL@=q(B +
    + + +SetOutputFilter +$B%5!<%P$N1~Ez$r=hM}$9$k%U%#%k%?$r@_Dj$9$k(B +SetOutputFilter filter[;filter...] +server configvirtual host +directory.htaccess + +FileInfo + + +

    SetOutputFilter $B%G%#%l%/%F%#%V$O(B + $B%5!<%P$N1~Ez$r%/%i%$%"%s%H$KAw$jJV$5$l$kA0$K=hM}$9$k%U%#%k%?$r@_Dj$7$^$9!#(B + $B$3$l$O(B AddOutputFilter + $B%G%#%l%/%F%#%V$r4^$a!"B>$N>l=j$GDj5A$5$l$F$$$k%U%#%k%?$N@_Dj$K(B + $BDI2C$5$l$^$9!#(B

    + +

    $BNc$($P!"0J2<$N@_Dj$O(B /www/data/ $B%G%#%l%/%H%j$N$9$Y$F$N(B + $B%U%!%$%k$r(B SSI $B$G=hM}$7$^$9!#(B

    + + + <Directory /www/data/>
    + + SetOutputFilter INCLUDES
    +
    + </Directory> +
    + +

    $BJ#?t$N%U%#%k%?$r;XDj$9$k$H$-$O!"%G!<%?$r=hM}$9$k=gHV$K(B + $B%;%_%3%m%s$G6h@Z$kI,MW$,$"$j$^$9!#(B

    +
    +$B%U%#%k%?(B$B@bL@=q(B +
    + + +TimeOut +$B3F%$%Y%s%H$K$D$$$F!"%j%/%(%9%H$r<:GT$5$;$k$^$G$K%5!<%P$,(B +$BBT$D;~4V$r@_Dj(B +TimeOut seconds +TimeOut 300 +server config + + +

    TimeOut $B%G%#%l%/%F%#%V$O!"8=:_$N$H$3$m(B + $B0J2<$N;0$D$NBT$A;~4V$K$D$$$F$NDj5A$r9T$$$^$9(B:

    + +
      +
    1. GET $B%j%/%(%9%H$r + +
    2. POST $B$d(B PUT$B%j%/%(%9%H$K$*$$$F!" + +
    3. $B%l%9%]%s%9$rJV$9:]!"(BTCP $B$N(B ACK $B$,5"$C$F$/$k$^$G$N;~4V(B
    4. +
    + +

    $B>-Mh$K$OJL!9$N@_Dj$r$9$k$3$H$,2DG=$K$G$-$k$h$&9MN8Cf$G$9!#(B + Apache 1.2 $B0JA0$O%?%$%^!<$O(B 1200 $B$,%G%U%)%k%H$G$7$?$,!"(B + 300 $B$K2<$2$i$l$^$7$?!#(B300 $B$G$b$[$H$s$I$N>l9g$O==J,$9$.$kCM$G$9!#(B + $B%3!<%ICf$NJQ$J>l=j$K$^$@%Q%1%C%H$rAw$k:]$K%?%$%^$r%j%;%C%H$7$J$$(B + $B>l=j$,$"$k$+$b$7$l$J$$$N$G!"%G%U%)%k%H$r$h$j>.$5$$CM$K$O$7$F$$$^$;$s!#(B

    + +
    +
    + + +UseCanonicalName +$B%5!<%P$,<+J,<+?H$NL>A0$H%]!<%H$r7hDj$9$kJ}K!$r@_Dj$9$k(B +UseCanonicalName On|Off|Dns +UseCanonicalName Off +server configvirtual host +directory + + +

    $BB?$/$N>u67$G(B Apache $B$O(B$B<+8J;2>H(B URL$B!"$9$J$o$A(B + $BF1$8%5!<%P$r;X$9(B URL$B!"$r:n@.$9$kI,MW$,$"$j$^$9!#(B + UseCanonicalName On $B$N>l9g$O!"(BServerName $B%G%#%l%/%F%#%V$G;XDj$5$l$F$$$k(B + $B%[%9%HL>$H%]!<%HHV9f$r;H$C$F!"$=$N@55,L>(B ($B<+8J;2>H$NL>A0(B) $B$r@8@.$7$^$9!#(B + $B$3$NL>A0$O!"$9$Y$F$N<+8J;2>H(B URL $B$G;H$o$l$^$9$7!"(BCGI $B$N(B + SERVER_NAME $B$H(B SERVER_PORT $B$G$b;H$o$l$^$9!#(B

    + +

    UseCanonicalName Off $B$N>l9g!"(B + $B%/%i%$%"%s%H$,%[%9%HL>$H%]!<%H$r;XDj$7$?$H$-$K$O!"(B + $B$=$l$i$r85$K<+8J;2>H(B URL $B$r:n@.$7$^$9(B ($B;XDj$,$J$+$C$?$H$-$O(B + $B>e$NDj5A$HF1MM$K$7$F@55,L>$r2r7h$7$^$9(B)$B!#(B + $B$3$l$i$NCM$O(B$BL>A0%Y!<%9$N(B + $B%P!<%A%c%k%[%9%H(B$B$rSERVER_NAME $B$H(B SERVER_PORT + $B$b%/%i%$%"%s%H$+$iM?$($i$l$?CM$+$i:n@.$5$l$^$9!#(B

    + +

    $B$3$N$h$&$J5sF0$,JXMx$JNc$O!"%$%s%H%i%M%C%H$N%5!<%P$G(B www + $B$N$h$&$JC;$$L>A0$G%f!<%6$,%^%7%s$K@\B3$9$k$H$-$G$9!#(B + $B%f!<%6$NF~NO$GC;$$%[%9%HL>$,;H$o$l$F$$$F!"(BURL $B$,(B$B:G8e$N%9%i%C%7%eL5$7$N(B + $B%G%#%l%/%H%j$K$J$C$F$$$k(B http://www/splat $B$N$h$&$J$H$-!"(B + Apache $B$O%j%/%(%9%H$r(B http://www.domain.com/splat/ + $B$X%j%@%$%l%/%H$7$^$9!#(B + $BG'>Z$r$9$k$h$&$K@_Dj$7$F$$$k$H!"$3$N>l9g(B + $B%f!<%6$O(B 2 $B2sG'>Z$r$7$J$1$l$P$J$i$J$/$J$j$^$9(B (www $B$K(B + $BBP$7$F(B 1 $B2s!"(Bwww.domain.com $B$KBP$7$F$b$&(B 1 $B2s(B -- + $B>\:Y$O(B $B$3$NOCBj$N(B + FAQ $B$r;2>H$7$F$/$@$5$$(B)$B!#(B + $B$7$+$7(B UseCanonicalName $B$,(B Off $B$K$J$C$F$$$k$H!"(B + Apache $B$O(B http://www/splat/ $B$K%j%@%$%l%/%H$7$^$9!#(B

    + +

    $B;0$DL\$N%*%W%7%g%s(B UseCanonicalName DNS $B$O!"(B + $BBg5,LO$J(B IP $B%Y!<%9$N%P!<%A%c%k%[%9%F%#%s%0$G!"(B + Host: $B%X%C%@$rDs6!$7$J$$8E$$%/%i%$%"%s%H$r(B + $B%5%]!<%H$9$k>l9g$rA[Dj$7$F$$$^$9!#(B + $B$3$N%*%W%7%g%s$G$O(B Apache $B$O!"%/%i%$%"%s%H$,@\B3$7$?(B IP $B%"%I%l%9$KBP$7$F(B + DNS $B$N5U0z$-$r9T$J$C$F!"<+8J;2>H(B URL $B$r:n@.$7$^$9!#(B

    + + $B7Y9p(B +

    CGI $B$,(B SERVER_NAME $B$K4X$7$F2?$i$+$NA0Ds>r7o$r(B + $B2>Dj$7$F$$$k$H$-$K$O!"$3$N%*%W%7%g%s$N@_Dj$K$h$C$F$OF0:n$7$J$/(B + $B$J$k$+$b$7$l$^$;$s!#%/%i%$%"%s%H$O$H$7$F(B + $B2?$G$bK>$_$NCM$r;XDj$9$k$3$H$,$G$-$^$9!#(BCGI $B$,(B + SERVER_NAME $B$r;H$C$F<+8J;2>H(B URL $B$r:n@.$9$k$3$H$7$+$7$J$$(B + $B>l9g$O!"$I$N@_Dj$r9T$J$C$F$bBg>fIW$J$O$:$G$9!#(B

    +
    +ServerName +Listen +
    + + +VirtualHost +$BFCDj$N%[%9%HL>$d(B IP $B%"%I%l%9$N$_$KE,MQ$5$l$k%G%#%l%/%F%#%V$r(B +$B0O$`(B +<VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost> +server config + + +

    VirtualHost $B5Z$S(B + </VirtualHost> $B$O!"(B + $BFCDj$N%P!<%A%c%k%[%9%H$KBP$7$F$N$_E,MQ$5$l$k%G%#%l%/%F%#%V72$r3g$k(B + $B$?$a$K;H$o$l$^$9!#(B + $B%P!<%A%c%k%[%9%H%3%s%F%-%9%H$G5v2D$5$l$kA4$F$N%G%#%l%/%F%#%V$r;XDj2DG=$G$9!#(B + $B%5!<%P$,!";XDj$5$l$?%P!<%A%c%k%[%9%H$K$"$k%I%-%e%a%s%H$X$N(B + $B%j%/%(%9%H$rl9g!"(B + VirtualHost $B%;%/%7%g%s$NCf$K$"$k(B + $B%G%#%l%/%F%#%V$,E,MQ$5$l$^$9!#(B + Addr$B$O!" + +

      +
    • $B%P!<%A%c%k%[%9%H$N(B IP $B%"%I%l%9(B
    • + +
    • $B%P!<%A%c%k%[%9%H$N(B IP $B$KBP1~$9$k40A4$J%I%a%$%sL>(B
    • + +
    • NameVirtualHost * $B$H6&$K;H$o$l$k!"(B + $B$9$Y$F$N(B IP $B%"%I%l%9$K%^%C%A$9$kJ8;z(B *
    • + +
    • IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$GB>$N$b$N$K%^%C%A$7$J$$(B IP $B%"%I%l%9(B + $B$N$?$a$NJ8;zNs(B _default_
    • +
    + + $BNc(B + <VirtualHost 10.1.2.3>
    + + ServerAdmin webmaster@host.foo.com
    + DocumentRoot /www/docs/host.foo.com
    + ServerName host.foo.com
    + ErrorLog logs/host.foo.com-error_log
    + TransferLog logs/host.foo.com-access_log
    +
    + </VirtualHost> +
    + +

    IPv6 $B%"%I%l%9$O%*%W%7%g%s$N%]!<%HHV9f$N;XDj$H6hJL$9$k$?$a$K!"(B + $B3Q3g8L$G3g$C$F;XDj$9$kI,MW$,$"$j$^$9!# + + + <VirtualHost [fe80::a00:20ff:fea7:ccea]>
    + + ServerAdmin webmaster@host.example.com
    + DocumentRoot /www/docs/host.example.com
    + ServerName host.example.com
    + ErrorLog logs/host.example.com-error_log
    + TransferLog logs/host.example.com-access_log
    +
    + </VirtualHost> +
    + +

    $B3F!9$N%P!<%A%c%k%[%9%H$K$O$=$l$>$l0c$&(B IP $B%"%I%l%9!"%]!<%HHV9f(B + $B$b$7$/$O%[%9%HL>$KBP1~$9$kI,MW$,$"$j!"(B + 1 $BHVL\$N>l9g$K$OJ#?t$N%"%I%l%9$G(B IP $B%Q%1%C%H$rl9g$O!"(B + (OS$B$,%5%]!<%H$7$F$$$l$P(B) ifconfig alias $B%3%^%s%I$K$h$j(B + $BC#@.$G$-$^$9(B)$B!#(B

    + +

    :port $B$H$$$C$?7A<0$G5-=R$9$k$3$H$K$h$j!"(B + $B%^%C%A$5$;$k%]!<%H$rJQ992DG=$G$9!#(B + $B$3$N;XDj$r$7$J$$>l9g$K$O!"Port $B$G;XDj$5$l$?%]!<%H$,(B + $B%G%U%)%k%H$H$J$j$^$9!#(B + :* $B$r;XDj$9$k$3$H$K$h$j!"(B + $B%"%I%l%9>e$NA4$F$N%]!<%H$K%^%C%A$7$^$9!#(B(_default_ $B$N$H$-$O(B + $B$3$l$r;H$&$3$H$,?d>)$5$l$F$$$^$9!#(B)

    + +

    $B%;%-%e%j%F%#$K4X$7$F(B: + $B%5!<%P!<$r5/F0$7$?0J30$N%f!<%6$,%m%0%U%!%$%k$,J]4I$5$l$k%G%#%l%/%H%j$K(B + $B=q$-9~$_2DG=$J$H$-$K$J$<%;%-%e%j%F%#$,GK$i$l$k2DG=@-$,$"$k$+$N>\:Y$O(B + $B%;%-%e%j%F%#$K4X$9$k%3%D(B $B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    + + $BCm0UE@(B +

    VirtualHost $B$O(B Apache $B$,(B Listen $B$9$k(B + IP $B%"%I%l%9$K$O1F6A$rM?$((B$B$^$;$s(B$B!#(B + Listen $B$r(B + $B;H$C$F(B Apache $B$,@5$7$$%"%I%l%9$r(B listen $B$9$k$h$&$K@_Dj$9$kI,MW$,$"$j$^$9!#(B

    +
    + +

    IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$r;H$C$F$$$k>l9g$O!"FCJL$JL>A0(B + _default_ $B$r;XDj$9$k$3$H$,$G$-$^$9!#$=$N>l9g$O(B + $B$=$N%P!<%A%c%k%[%9%H$OB>$N%P!<%A%c%k%[%9%H$GL@<(E*$K5s$2$i$l$F$$$J$$(B + $B$9$Y$F$N(B IP $B%"%I%l%9$K%^%C%A$7$^$9!#(B_default_ $B%P!<%A%c%k%[%9%H$,L5$$(B + $B>l9g$K(B IP $B$,%P!<%A%c%k%[%9%H$G;XDj$5$l$?$b$N$K%^%C%A$7$J$$$H$-$O!"(B + VirtualHost $B%;%/%7%g%s$N30$N$9$Y$F$NDj5A$+$i$J$k!VNameVirtualHost $B%G%#%l%/%F%#%V$K%^%C%A$9$k(B + $B$9$Y$F$N(B IP $B%"%I%l%9$O!V_default_ $B%P!<%A%c%k%[%9%H$b(B + $B;H$o$J$$$3$H$KCm0U$7$F$/$@$5$$!#>\$7$/$O(B $B%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H(B $B$r(B + $B;2>H$7$F$/$@$5$$!#(B)

    + +

    :port $B$H$$$C$?7A<0$G5-=R$9$k$3$H$K$h$j!"(B + $B%^%C%A$5$;$k%]!<%H$rJQ992DG=$G$9!#(B + $B$3$N;XDj$r$7$J$$>l9g$K$O!"Listen $B$G;XDj$5$l$?(B + $B%]!<%H$,%G%U%)%k%H$H$J$j$^$9!#(B + :* $B$r;XDj$9$k$3$H$K$h$j!"(B + $B%"%I%l%9>e$NA4$F$N%]!<%H$K%^%C%A$7$^$9!#(B(_default_ $B$N$H$-$O(B + $B$3$l$r;H$&$3$H$,?d>)$5$l$F$$$^$9!#(B)

    + +

    :port $B$H$$$C$?7A<0$G5-=R$9$k$3$H$K$h$j!"(B + $B%^%C%A$5$;$k%]!<%H$rJQ992DG=$G$9!#(B + $B$3$N;XDj$r$7$J$$>l9g$K$O!"Port $B$G;XDj$5$l$?%]!<%H$,(B + $B%G%U%)%k%H$H$J$j$^$9!#(B + :* $B$r;XDj$9$k$3$H$K$h$j!"(B + $B%"%I%l%9>e$NA4$F$N%]!<%H$K%^%C%A$7$^$9!#(B(_default_ $B$N$H$-$O(B + $B$3$l$r;H$&$3$H$,?d>)$5$l$F$$$^$9!#(B)

    + + $B%;%-%e%j%F%#(B +

    $B%5!<%P!<$r5/F0$7$?0J30$N%f!<%6$,%m%0%U%!%$%k$,J]4I$5$l$k%G%#%l%/%H%j$K(B + $B=q$-9~$_2DG=$J$H$-$K$J$<%;%-%e%j%F%#$,GK$i$l$k2DG=@-$,$"$k$+$N>\:Y$O(B + $B%;%-%e%j%F%#$K4X$9$k%3%D(B $B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    +
    +Apache $B%P!<%A%c%k%[%9%H@bL@=q(B +DNS $B$H(B Apache $B$K4X$9$kOC(B +Apache $B$,;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj(B +$B%j%/%(%9%H$r + <Directory>, <Location>, <Files> $B%;%/%7%g%s$NF0:nK!(B +
    + +
    diff --git a/trunk/docs/manual/mod/core.xml.meta b/trunk/docs/manual/mod/core.xml.meta new file mode 100644 index 0000000000..79ae78c3c4 --- /dev/null +++ b/trunk/docs/manual/mod/core.xml.meta @@ -0,0 +1,13 @@ + + + + core + /mod/ + .. + + + de + en + ja + + diff --git a/trunk/docs/manual/mod/directive-dict.html b/trunk/docs/manual/mod/directive-dict.html new file mode 100644 index 0000000000..1ed62d36a9 --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.html @@ -0,0 +1,11 @@ +URI: directive-dict.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: directive-dict.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: directive-dict.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/directive-dict.html.en b/trunk/docs/manual/mod/directive-dict.html.en new file mode 100644 index 0000000000..909bbcf57c --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.html.en @@ -0,0 +1,291 @@ + + + +Terms Used to Describe Directives - Apache HTTP Server + + + + + +
    <-
    +

    Terms Used to Describe Directives

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    This document describes the terms that are used to describe + each Apache configuration + directive.

    +
    + +
    top
    +
    +

    Description

    + +

    A brief description of the purpose of the directive.

    +
    top
    +
    +

    Syntax

    + +

    This indicates the format of the directive as it would + appear in a configuration file. This syntax is extremely + directive-specific, and is described in detail in the + directive's definition. Generally, the directive name is + followed by a series of one or more space-separated arguments. + If an argument contains a space, the argument must be enclosed + in double quotes. Optional arguments are enclosed in square + brackets. Where an argument can take on more than one possible + value, the possible values are separated by vertical bars "|". + Literal text is presented in the default font, while + argument-types for which substitution is necessary are + emphasized. Directives which can take a variable + number of arguments will end in "..." indicating that the last + argument is repeated.

    + +

    Directives use a great number of different argument types. A + few common ones are defined below.

    + +
    +
    URL
    + +
    A complete Uniform Resource Locator including a scheme, + hostname, and optional pathname as in + http://www.example.com/path/to/file.html
    + +
    URL-path
    + +
    The part of a url which follows the scheme and + hostname as in /path/to/file.html. The + url-path represents a web-view of a resource, as + opposed to a file-system view.
    + +
    file-path
    + +
    The path to a file in the local file-system beginning + with the root directory as in + /usr/local/apache/htdocs/path/to/file.html. + Unless otherwise specified, a file-path which does + not begin with a slash will be treated as relative to the ServerRoot.
    + +
    directory-path
    + +
    The path to a directory in the local file-system + beginning with the root directory as in + /usr/local/apache/htdocs/path/to/.
    + +
    filename
    + +
    The name of a file with no accompanying path information + as in file.html.
    + +
    regex
    + +
    A Perl-compatible regular + expression. The directive definition will specify what the + regex is matching against.
    + +
    extension
    + +
    In general, this is the part of the filename + which follows the last dot. However, Apache recognizes + multiple filename extensions, so if a filename + contains more than one dot, each dot-separated part of the + filename following the first dot is an extension. + For example, the filename file.html.en + contains two extensions: .html and + .en. For Apache directives, you may specify + extensions with or without the leading dot. In + addition, extensions are not case sensitive.
    + +
    MIME-type
    + +
    A method of describing the format of a file which + consists of a major format type and a minor format type, + separated by a slash as in text/html.
    + +
    env-variable
    + +
    The name of an environment + variable defined in the Apache configuration process. + Note this is not necessarily the same as an operating system + environment variable. See the environment variable documentation for + more details.
    +
    +
    top
    +
    +

    Default

    + +

    If the directive has a default value (i.e., if you + omit it from your configuration entirely, the Apache Web server + will behave as though you set it to a particular value), it is + described here. If there is no default value, this section + should say "None". Note that the default listed here + is not necessarily the same as the value the directive takes in + the default httpd.conf distributed with the server.

    +
    top
    +
    +

    Context

    + +

    This indicates where in the server's configuration files the + directive is legal. It's a comma-separated list of one or more + of the following values:

    + +
    +
    server config
    + +
    This means that the directive may be used in the server + configuration files (e.g., httpd.conf), but + not within any + <VirtualHost> + or <Directory> + containers. It is not allowed in .htaccess files + at all.
    + +
    virtual host
    + +
    This context means that the directive may appear inside + <VirtualHost> + containers in the server + configuration files.
    + +
    directory
    + +
    A directive marked as being valid in this context may be + used inside <Directory>, <Location>, <Files>, and <Proxy> containers + in the server configuration files, subject to the restrictions + outlined in Configuration + Sections.
    + +
    .htaccess
    + +
    If a directive is valid in this context, it means that it + can appear inside per-directory + .htaccess files. It may not be processed, though + depending upon the overrides currently active.
    +
    + +

    The directive is only allowed within the designated + context; if you try to use it elsewhere, you'll get a + configuration error that will either prevent the server from + handling requests in that context correctly, or will keep the + server from operating at all -- i.e., the server won't + even start.

    + +

    The valid locations for the directive are actually the + result of a Boolean OR of all of the listed contexts. In other + words, a directive that is marked as being valid in + "server config, .htaccess" can be used in the + httpd.conf file and in .htaccess + files, but not within any <Directory> or + <VirtualHost> + containers.

    +
    top
    +
    +

    Override

    + +

    This directive attribute indicates which configuration + override must be active in order for the directive to be + processed when it appears in a .htaccess file. If + the directive's context + doesn't permit it to appear in .htaccess files, + then no context will be listed.

    + +

    Overrides are activated by the AllowOverride directive, and apply + to a particular scope (such as a directory) and all + descendants, unless further modified by other + AllowOverride directives at + lower levels. The documentation for that directive also lists the + possible override names available.

    +
    top
    +
    +

    Status

    + +

    This indicates how tightly bound into the Apache Web server + the directive is; in other words, you may need to recompile the + server with an enhanced set of modules in order to gain access + to the directive and its functionality. Possible values for + this attribute are:

    + +
    +
    Core
    + +
    If a directive is listed as having "Core" status, that + means it is part of the innermost portions of the Apache Web + server, and is always available.
    + +
    MPM
    + +
    A directive labeled as having "MPM" status is provided by + a Multi-Processing Module. This + type of directive will be available if and only if you are + using one of the MPMs listed on the Module line of the directive + definition.
    + +
    Base
    + +
    A directive labeled as having "Base" status is supported + by one of the standard Apache modules which is compiled into + the server by default, and is therefore normally available + unless you've taken steps to remove the module from your + configuration.
    + +
    Extension
    + +
    A directive with "Extension" status is provided by one of + the modules included with the Apache server kit, but the + module isn't normally compiled into the server. To enable the + directive and its functionality, you will need to change the + server build configuration files and re-compile Apache.
    + +
    Experimental
    + +
    "Experimental" status indicates that the directive is + available as part of the Apache kit, but you're on your own + if you try to use it. The directive is being documented for + completeness, and is not necessarily supported. The module + which provides the directive may or may not be compiled in by + default; check the top of the page which describes the + directive and its module to see if it remarks on the + availability.
    +
    +
    top
    +
    +

    Module

    + +

    This quite simply lists the name of the source module which + defines the directive.

    +
    top
    +
    +

    Compatibility

    + +

    If the directive wasn't part of the original Apache version + 2 distribution, the version in which it was introduced should + be listed here. In addition, if the directive is available + only on certain platforms, it will be noted here.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directive-dict.html.ja.euc-jp b/trunk/docs/manual/mod/directive-dict.html.ja.euc-jp new file mode 100644 index 0000000000..516c198059 --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.html.ja.euc-jp @@ -0,0 +1,301 @@ + + + +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î²òÀâ¤Ë»È¤ï¤ì¤ëÍѸì - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î²òÀâ¤Ë»È¤ï¤ì¤ëÍѸì

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ï³Æ Apache ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤òÀâÌÀ¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Æ¤¤¤ëÍѸì¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ÀâÌÀ

    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÌÜŪ¤Î´Êñ¤ÊÀâÌÀ¡£

    +
    top
    +
    +

    ¹½Ê¸

    + +

    ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î½ñ¼°¤ò¼¨¤·¤Þ¤¹¡£ + ¤³¤Î¹½Ê¸¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥ÖÆÃÍ­¤Ê¤Î¤Ç¡¢¾ÜºÙ¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀâÌÀ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£°ìÈÌŪ¤Ë¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö̾¤Î¸å¤Ë¤Ï + ¶õÇò¤Ë¤è¤êʬ³ä¤µ¤ì¤¿¤¤¤¯¤Ä¤«¤Î°ú¿ô¤¬Â³¤­¤Þ¤¹¡£ + °ú¿ô¤¬¶õÇò¤ò´Þ¤à¤È¤­¤ÏÆó½Å°úÍÑÉä (ÌõÃí: ") + ¤Ç°Ï¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ ¥ª¥×¥·¥ç¥Ê¥ë¤Ê°ú¿ô¤Ï³ç¸Ì + (ÌõÃí: []) ¤Ç°Ï¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ + °ú¿ô¤¬Ê£¿ô¤ÎÃͤò¼è¤êÆÀ¤ë¾ì¹ç¤Ï¡¢¤½¤ì¤é¤ÎÃͤϿ⾤ÎËÀ "|" + ¤Ç ʬ³ä¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + Êѹ¹¤µ¤ì¤Ê¤¤¥Æ¥­¥¹¥È¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¤Çɽ¼¨¤µ¤ì¡¢ÃÖ´¹¤ÎɬÍ×¤Ê + °ú¿ô¤Ï¶¯Ä´¤µ¤ì¤Æɽ¼¨¤µ¤ì¤Þ¤¹¡£ + °ú¿ô¤Î¿ô¤¬ÊѤï¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏºÇ¸å¤Î + °ú¿ô¤¬·«¤êÊÖ¤µ¤ì¤ë¤³¤È¤ò¼¨¤¹¤¿¤á¤Ë "..." + ¤Ç½ª¤ï¤ê¤Þ¤¹¡£

    + +

    + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¿¤¯¤Î°ã¤¦·¿¤Î°ú¿ô¤ò¤È¤ê¤Þ¤¹¡£¤¤¤¯¤Ä¤«¡¢Îɤ¯ + »È¤ï¤ì¤ë¤â¤Î¤ò°Ê²¼¤ÇÄêµÁ¤·¤Þ¤¹¡£

    + +
    +
    URL
    + +
    http://www.example.com/path/to/file.html + ¤Î¤è¤¦¤Ë¡¢ + ¥¹¥­¡¼¥à¡¢¥Û¥¹¥È̾¡¢¥Ñ¥¹Ì¾(¾Êά²Äǽ)¤ò´Þ¤ó¤Ç¤¤¤ë´°Á´¤Ê + Uniform Resource Locator¡£
    + +
    URL-path
    + +
    /path/to/file.html ¤Î¤è¤¦¤Ë¡¢¥¹¥­¡¼¥à¤È + ¥Û¥¹¥È̾¤Î¸å¤Ë³¤¯ url + ¤Î°ìÉô¡£url-path ¤Ï + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤«¤é¤Î»ëÅÀ¤Ç¤Ï¤Ê¤¯¡¢ + ¥¦¥§¥Ö¤«¤é¤Î»ëÅÀ¤Ç¥ê¥½¡¼¥¹¤òɽ¸½¤·¤Þ¤¹¡£
    + +
    file-path
    + +
    /usr/local/apache/htdocs/path/to/file.html + ¤Î¤è¤¦¤Ë¡¢ + ¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤«¤é»Ï¤Þ¤ë¥í¡¼¥«¥ë¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¡£ + Ä̾¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤é¤Ê¤¤ file-path ¤Ï ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ °·¤ï¤ì¤Þ¤¹¡£
    + +
    directory-path
    + +
    /usr/local/apache/htdocs/path/to/ + ¤Î¤è¤¦¤Ë¡¢ + ¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤«¤é»Ï¤Þ¤ë¥í¡¼¥«¥ë¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î + ¥Ñ¥¹¡£
    + +
    filename
    + +
    file.html ¤Î¤è¤¦¤Ë¡¢¥Ñ¥¹¾ðÊó¤ÎÉÕ¤¤¤Æ¤¤¤Ê¤¤ + ¥Õ¥¡¥¤¥ë̾¡£
    + +
    regex
    + +
    Perl ¸ß´¹¤ÎÀµµ¬É½¸½¤Ç¤¹¡£ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÄêµÁ¤¬ regex + ¤¬²¿¤ËÂФ·¤Æ¥Þ¥Ã¥Á¤ò¹Ô¤Ê¤¦¤Î¤«¤ò»ØÄꤷ¤Þ¤¹¡£
    + +
    extension
    + +
    °ìÈÌŪ¤Ë¤Ï filename + ¤ÎºÇ¸å¤Î¥É¥Ã¥È¤Î¸å¤ÎÉôʬ¤Ç¤¹¡£ ¤·¤«¤·¡¢Apache + ¤ÏÊ£¿ô¤Î¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤òǧ¼±¤·¤Þ¤¹¤Î¤Ç¡¢filename + ¤ËÊ£¿ô¤Î¥É¥Ã¥È¤¬¤¢¤ë¤È¡¢ºÇ½é¤Î¥É¥Ã¥È¤Î¸å¤Î¡¢¤½¤ì¤¾¤ì¤Î¥É¥Ã¥È¤ÇʬΥ¤µ¤ì¤¿Éôʬ¤¬ + extension (ÌõÃí: ³ÈÄ¥»Ò) + ¤Ë¤Ê¤ê¤Þ¤¹¡£Î㤨¤Ð¡¢filename + file.html.en + ¤Ë¤ÏÆó¤Ä¤Î³ÈÄ¥»Ò¤¬¤¢¤ê¤Þ¤¹¡£.html ¤È + .en ¤Ç¤¹¡£Apache + ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢extension + ¤Ï¥É¥Ã¥ÈÉÕ¤­¤Ç¤â̵¤·¤Ç¤â»ØÄê¤Ç¤­¤Þ¤¹¡£¤µ¤é¤Ë¡¢extension + ¤Ï Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£
    + +
    MIME-type
    + +
    text/html ¤Î¤è¤¦¤Ë¡¢¥¹¥é¥Ã¥·¥å¤ÇʬΥ¤µ¤ì¤¿ + ¼ç¥Õ¥©¡¼¥Þ¥Ã¥È¤ÈÉû¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¤è¤Ã¤Æ¥Õ¥¡¥¤¥ë¤Î·Á¼°¤ò + ɽ¤¹ÊýË¡¤Ç¤¹¡£
    + +
    env-variable
    + +
    Apache ¤ÎÀßÄê¤Ë¤è¤êÄêµÁ¤µ¤ì¤ë ´Ä¶­ÊÑ¿ô¤Î̾Á°¤Ç¤¹¡£¤³¤ì¤Ï¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î + ´Ä¶­ÊÑ¿ô¤ÈƱ¤¸¤È¤Ï¸Â¤é¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¾ÜºÙ¤Ï ´Ä¶­ÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
    +
    +
    top
    +
    +

    ¥Ç¥Õ¥©¥ë¥È

    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¥Ç¥Õ¥©¥ë¥ÈÃÍ + (¤¹¤Ê¤ï¤Á¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤«¤é + ¾Êά¤µ¤ì¤Æ¤¤¤Æ¤â¡¢Apache + ¥¦¥§¥Ö¥µ¡¼¥Ð¤ÏÆÃÄê¤ÎÃͤËÀßÄꤵ¤ì¤Æ¤¤¤ë¤«¤Î¤è¤¦¤Ë + Æ°ºî¤·¤Þ¤¹) ¤¬¤¢¤ë¾ì¹ç¤Ï¤³¤³¤Ëµ­½Ò¤µ¤ì¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃͤÎ̵¤¤¾ì¹ç¡¢¤³¤³¤Ï "None" ¤È + ½ñ¤«¤ì¤Þ¤¹¡£¤³¤³¤Ç½ñ¤«¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Ï¥µ¡¼¥Ð¤È¶¦¤ËÇÛÉÛ¤µ¤ì¤Æ¤¤¤ë + ¥Ç¥Õ¥©¥ë¥È¤Î httpd.conf + Æâ¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃÍ¤È + °ã¤¦²ÄǽÀ­¤¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥³¥ó¥Æ¥­¥¹¥È

    + +

    + ¤³¤ì¤Ï¡¢¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î¤É¤³¤Ç¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ê¤Î¤«¤ò¼¨¤·¤Þ¤¹¡£ + ¼¡¤Ë¼¨¤¹Ãͤ¬°ì¤Ä°Ê¾å¥«¥ó¥Þ¶èÀÚ¤ê¤ÇÎóµó¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    +
    ¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    + +
    ¤³¤ì¤Ï¡¢¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë + (Î㤨¤Ð¡¢httpd.conf, + srm.conf, access.conf) + Æâ¤Ç¤Ï»ÈÍѤǤ­¤Þ¤¹¤¬¡¢ + <VirtualHost> ¤ä + <Directory> ¤ÎÃæ¤Ç¤Ï + »ÈÍѤǤ­¤Ê¤¤¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + .htaccess¥Õ¥¡¥¤¥ë¤Ç¤Î»ÈÍѤϵö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£
    + +
    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    + +
    ¤³¤ì¤Ï¡¢¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤Î + <VirtualHost> + ¤ÎÃæ¤Ç»ÈÍѤǤ­¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£
    + +
    ¥Ç¥£¥ì¥¯¥È¥ê
    + +
    ¤³¤ì¤Ï¡¢¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤Î + <Directory>, + <Location>, + <Files>, + <Proxy> + ¥³¥ó¥Æ¥Ê¤ÎÃæ¤Ç¡¢ ÀßÄꥻ¥¯¥·¥ç¥ó + ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ëÀ©¸Â¤Î²¼¤Ç»ÈÍѤǤ­¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£
    + +
    .htaccess
    + +
    ¤³¤ì¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥êËè¤Î + .htaccess ¥Õ¥¡¥¤¥ëÆâ¤Ç + »ÈÍѲÄǽ¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ ¤¿¤À¡¢¾å½ñ¤­ + ¤ÎÀßÄê¤Ë¤è¤Ã¤Æ¤Ï¡¢½èÍý¤µ¤ì¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    +
    + +

    + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï»Ø¼¨¤µ¤ì¤¿¥³¥ó¥Æ¥­¥¹¥È¤Ç¤Î¤ßµö²Ä¤µ¤ì¤Þ¤¹¡£ + ¾¤Î¾ì½ê¤Ç»È¤ª¤¦¤È¤¹¤ë¤È¡¢¥µ¡¼¥Ð¤¬¤½¤Î¥³¥ó¥Æ¥­¥¹¥È¤òÀµ¤·¤¯°·¤¨¤Ê¤¯ + ¤Ê¤ë¤è¤¦¤ÊÀßÄꥨ¥é¡¼¤¬È¯À¸¤¹¤ë¤«¡¢¥µ¡¼¥Ð¤¬¤Þ¤Ã¤¿¤¯Æ°ºî¤·¤Ê¤¯¤Ê¤ë¡¢ + ¤¹¤Ê¤ï¤Á¡¢¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤Ê¤¯¤Ê¤ë¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÍ­¸ú¤Ê°ÌÃ֤ϡ¢¼ÂºÝ¤Ïµó¤²¤é¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥­¥¹¥È¤Î + ÏÀÍýÏ (ÌõÃí: Boolen OR) + ¤Ë¤Ê¤ê¤Þ¤¹¡£¸À¤¤´¹¤¨¤ë¤È¡¢ + "¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¡¢.htaccess" ¤ÇÍ­¸ú¤À¤È + µ­¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï httpd.conf + ¥Õ¥¡¥¤¥ë¤È .htaccess + ¥Õ¥¡¥¤¥ë¤È¤ÇÍ­¸ú¤Ç¤¹¤¬¡¢ <Directory> + ¤ä <VirtualHost> + ¤ÎÃæ¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ¾å½ñ¤­

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°À­¤Ï¡¢.htaccess + ¥Õ¥¡¥¤¥ëÃæ¤Ë + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¸½¤ì¤¿¤È¤­¤Ë¡¢¤½¤ì¤Î½èÍý¤òÍ­¸ú¤Ë¤¹¤ë¤¿¤á¤Ë + ¤É¤ÎÀßÄê¤Î¾å½ñ¤­¤¬É¬Íפ«¤ò¼¨¤·¤Þ¤¹¡£ ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ¥³¥ó¥Æ¥­¥¹¥È + ¤¬¡¢.htaccess + ¥Õ¥¡¥¤¥ëÃæ¤Ç¤Ïµö²Ä¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢ ¤³¤Î°À­¤Ï + "ŬÍÑÉÔ²Ä" ¤È½ñ¤«¤ì¤Þ¤¹¡£

    + +

    ¾å½ñ¤­¤Ï¡¢AllowOverride + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤ÆÍ­¸ú¤Ë¤µ¤ì¡¢ + ÆÃÄê¤Î¥¹¥³¡¼¥×(¥Ç¥£¥ì¥¯¥È¥ê¤Ê¤É)¤È¡¢ + ¤µ¤é¤Ë²¼°Ì¤Î¥ì¥Ù¥ë¤Î AllowOverride + ¤Ç½¤Àµ¤µ¤ì¤Ê¤¤¸Â¤ê¡¢ ¤½¤ÎÇÛ²¼¤ËÂФ·¤ÆŬÍѤµ¤ì¤Þ¤¹¡£ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥É¥­¥å¥á¥ó¥È¤Ï¼è¤êÆÀ¤ë¾å½ñ¤­¤Î̾Á°¤âµó¤²¤Þ¤¹¡£

    +
    top
    +
    +

    ¥¹¥Æ¡¼¥¿¥¹

    + +

    ¤³¤ì¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ Apache + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¤É¤ì¤¯¤é¤¤¤­¤Ä¤¯ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¤ò + ¼¨¤·¤Þ¤¹¡£¸À¤¤´¹¤¨¤ì¤Ð¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤½¤Îµ¡Ç½¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¡¢ + ¥â¥¸¥å¡¼¥ë¤Î¿ô¤òÁý¤ä¤·¤Æ¡¢¥µ¡¼¥Ð¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Ê¤¤ + ¤È¤¤¤¦¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + ¤³¤Î°À­¤¬¼è¤êÆÀ¤ëÃͤϰʲ¼¤Î¤â¤Î¤Ç¤¹:

    + +
    +
    Core
    + +
    "Core" ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Î´ðËܤȤʤë¤Ù¤­¤â¤Î¤Ç¤¢¤ê¡¢ + ¾ï¤Ë»ÈÍѲÄǽ¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£
    + +
    MPM
    + +
    "MPM" ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¼ïÎà¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÄêµÁ¤Î¥â¥¸¥å¡¼¥ë¤Î¹Ô¤Ë»È¤Ã¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤Î̾Á°¤¬½ñ¤«¤ì¤Æ¤¤¤ë + ¾ì¹ç¤Ë¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
    + +
    Base
    + +
    "Base" ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥Ç¥Õ¥©¥ë¥È¤Ç¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ëɸ½à¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Î°ì¤Ä¤Ç¥µ + ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Æ¡¢¤ï¤¶¤ï¤¶ÀßÄ꤫¤é¥â¥¸¥å¡¼¥ë¤òºï½ü¤·¤¿¤È¤­¤ò½ü¤¤¤Æ¡¢ + Ä̾ï¤Ç¤Ï»ÈÍѲÄǽ¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£
    + +
    Extension
    + +
    "Extension" ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ Apache + ¥µ¡¼¥Ð¤ÎÇÛÉÛʪ¤ËƱº­¤µ¤ì¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤Î°ì¤Ä¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Î¡¢ + Ä̾ï¤Ç¤Ï¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤½¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢¥µ¡¼¥Ð¥Ó¥ë¥ÉÍѤÎÀßÄê¥Õ¥¡¥¤¥ë¤ò + Êѹ¹¤·¤Æ Apache + ¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
    + +
    Experimental
    + +
    "Experimental" ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Apache + ÇÛÉÛʪ¤Ë + Ʊº­¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Î¡¢»î¤·¤¿¤¤¾ì¹ç¤Ï¼«¸ÊÀÕǤ¤Ç¹Ô¤Ê¤¦ + ɬÍפ¬¤¢¤ë¤È¤¤¤¦¤³¤È¤ò¼¨¤·¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¤¹¤Ù¤Æ¤Î¥É¥­¥å¥á¥ó¥È¤ò + ´°Á´¤Ë¤½¤í¤ï¤»¤ë¤¿¤á¤Ë²òÀ⤵¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤È¤Ï¸Â¤ê¤Þ¤»¤ó¡£ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÄ󶡤¹¤ë¥â¥¸¥å¡¼¥ë¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¤â + ¤·¤ì¤Þ¤»¤ó¤·¡¢¤½¤¦¤Ç¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£»ÈÍѲÄǽ¤«¤É¤¦¤«¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¥â¥¸¥å¡¼¥ë¤ÎÀâÌÀ¤ò¤·¤Æ¤¤¤ë¥Ú¡¼¥¸¤ÎÀèƬ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£
    +
    +
    top
    +
    +

    ¥â¥¸¥å¡¼¥ë

    + +

    + ¤³¤ì¤Ïñ½ã¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤Î̾Á°¤òµ­ºÜ¤·¤Þ¤¹¡£

    +
    top
    +
    +

    ¸ß´¹À­

    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ Apache 2 + ¤ÎÇÛÉÛ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Æ³Æþ¤µ¤ì¤¿¥Ð¡¼¥¸¥ç¥ó¤¬¤³¤³¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤Þ¤¿¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ÆÃÄê¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤Î¤ß¸ºß¤¹¤ë¤È¤­¤â + ¤³¤³¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directive-dict.html.ko.euc-kr b/trunk/docs/manual/mod/directive-dict.html.ko.euc-kr new file mode 100644 index 0000000000..ae2609fa3d --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.html.ko.euc-kr @@ -0,0 +1,250 @@ + + + +Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ »ç¿ëÇÑ ¿ë¾îµé - Apache HTTP Server + + + + + +
    <-
    +

    Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ »ç¿ëÇÑ ¿ë¾îµé

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤ + Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ »ç¿ëÇÑ ¿ë¾îµéÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¼³¸í (Description)

    + +

    Áö½Ã¾îÀÇ ¸ñÀû¿¡ ´ëÇÑ °£´ÜÇÑ ¼³¸í.

    +
    top
    +
    +

    ¹®¹ý (Syntax)

    + +

    ¼³Á¤ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ Áö½Ã¾îÀÇ Çü½ÄÀ» ¾Ë·ÁÁØ´Ù. ÀÌ ¹®¹ýÀº + Áö½Ã¾î¸¶´Ù ¸Å¿ì ´Ù¸£¸ç, Áö½Ã¾î¸¦ Á¤ÀÇÇÒ ¶§¸¶´Ù ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù. + ÀϹÝÀûÀ¸·Î Áö½Ã¾î À̸§ µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ ¾Æ±Ô¸ÕÆ®µéÀÌ + ³ª¿Â´Ù. ¾Æ±Ô¸ÕÆ®°¡ °ø¹éÀ» Æ÷ÇÔÇÑ´Ù¸é ¾Æ±Ô¸ÕÆ®¸¦ ½Öµû¿ÈÇ¥·Î + ¹­¾î¾ß ÇÑ´Ù. ¼±ÅÃÀûÀÎ ¾Æ±Ô¸ÕÆ®´Â Áß°ýÈ£·Î ¹­´Â´Ù. ¾Æ±Ô¸ÕÆ®°¡ + ¿©·¯ °ªÁß ÇϳªÀÏ °æ¿ì °ªµéÀ» ¼öÁ÷¸·´ë "|"·Î ±¸ºÐÇÑ´Ù. + ¹®ÀÚ±×´ë·Î »ç¿ëÇÒ ºÎºÐÀº ±âº» ¹®ÀÚü·Î ¾²°í, ´ëüÇÒ ¾Æ±Ô¸ÕÆ®´Â + °­Á¶ÇÑ´Ù. ¾Æ±Ô¸ÕÆ® °³¼ö°¡ Á¤ÇØÁöÁö¾ÊÀº Áö½Ã¾î´Â + ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®°¡ ¹Ýº¹µÊÀ» ³ªÅ¸³»´Â "..."À¸·Î ³¡³­´Ù.

    + +

    Áö½Ã¾î´Â ¸Å¿ì ´Ù¾çÇÑ Á¾·ùÀÇ ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ´Â´Ù. ÀÌÁß ÀÚÁÖ + »ç¿ëÇÏ´Â °ÍÀº ¾Æ·¡¿Í °°´Ù.

    + +
    +
    URL
    + +
    http://www.example.com/path/to/file.html°ú + °°ÀÌ ½ºÅ´(scheme), È£½ºÆ®¸í, ¼±ÅÃÀûÀÎ °æ·Î¸íÀ» Æ÷ÇÔÇÑ + ¿ÏÀüÇÑ Uniform Resource Locator
    + +
    URL-path
    + +
    /path/to/file.html°ú °°ÀÌ url¿¡¼­ + ½ºÅ´°ú È£½ºÆ®¸í µÚ¿¡ ³ª¿À´Â ºÎºÐ. url-path´Â + ÆÄÀϽýºÅÛ¿¡¼­ º» ½ÃÁ¡ÀÌ ¾Æ´Ñ À¥¿¡¼­ º» ½ÃÁ¡¿¡¼­ÀÇ ÀڷḦ + ³ªÅ¸³½´Ù.
    + +
    file-path
    + +
    /usr/local/apache/htdocs/path/to/file.html°ú + °°ÀÌ root µð·ºÅ丮·Î ½ÃÀÛÇÏ´Â ÆÄÀϽýºÅÛ»óÀÇ ÆÄÀÏ °æ·Î. µû·Î + ¾ð±ÞÇÏÁö¾ÊÀ¸¸é, ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾ÊÀº file-path´Â + ServerRoot¿¡ »ó´ë°æ·Î·Î + Ãë±ÞÇÑ´Ù.
    + +
    directory-path
    + +
    /usr/local/apache/htdocs/path/to/¿Í °°ÀÌ + root µð·ºÅ丮·Î ½ÃÀÛÇÏ´Â ÆÄÀϽýºÅÛ»óÀÇ µð·ºÅ丮 °æ·Î.
    + +
    filename
    + +
    file.html°ú °°ÀÌ °æ·Î Á¤º¸°¡ ¾ø´Â ÆÄÀϸí.
    + +
    regex
    + +
    Perl Çü½ÄÀÇ Á¤±ÔÇ¥Çö½Ä(regular + expression). Áö½Ã¾î´Â regex·Î ¹«¾ùÀΰ¡¸¦ °Ë»öÇÑ´Ù.
    + +
    extension
    + +
    ÀϹÝÀûÀ¸·Î filename¿¡¼­ ¸¶Áö¸· ¸¶Ä§Ç¥ µÚ¿¡ + ³ª¿À´Â ºÎºÐÀÌ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡´Â ¿©·¯ È®ÀåÀÚ¸¦ ÀνÄÇÒ + ¼ö Àֱ⶧¹®¿¡, filename¿¡ ¸¶Ä§Ç¥°¡ ¿©·¯°³ Æ÷ÇÔµÈ + °æ¿ì ¸¶Ä§Ç¥·Î ±¸ºÐµÈ ¸ðµç ºÎºÐÀ» È®ÀåÀÚ(extension)·Î + ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, ÆÄÀϸí file.html.enÀº + .html°ú .enÀ̶ó´Â µÎ°¡Áö È®ÀåÀÚ¸¦ + °¡Áø´Ù. ¾ÆÆÄÄ¡ Áö½Ã¾î¿¡¼­ extension¿¡ ÁöÁ¤ÇÑ + °ª ¾Õ¿¡ ¸¶Ä§Ç¥°¡ À־ µÇ°í ¾ø¾îµµ µÈ´Ù. ¶Ç, + extensionÀº ´ë¼Ò¹®ÀÚ¸¦ °¡¸®Áö¾Ê´Â´Ù.
    + +
    MIME-type
    + +
    text/html°ú °°ÀÌ ½½·¡½¬·Î major format + type°ú minor format type¸¦ ±¸ºÐÇÏ¿© ÆÄÀÏÀÇ Çü½ÄÀ» ¼³¸íÇÏ´Â + ¹æ½Ä.
    + +
    env-variable
    + +
    ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ Á¤ÀÇÇÑ È¯°æº¯¼ö + À̸§. ¿î¿µÃ¼Á¦ÀÇ È¯°æº¯¼ö¿Í ´Ù¸§À» ÁÖÀÇÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº + ȯ°æº¯¼ö ¹®¼­¸¦ Âü°íÇ϶ó.
    +
    +
    top
    +
    +

    ±âº»°ª (Default)

    + +

    Áö½Ã¾î¿¡ ±âº»°ªÀÌ ÀÖ´Ù¸é (¿¹¸¦ µé¾î, ¼³Á¤¿¡¼­ + Áö½Ã¾î¸¦ »ý·«ÇÑ °æ¿ì ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ °ªÀ» »ç¿ëÇÑ´Ù.) + ÀÌ Ç׸ñ¿¡ ³ª¿Â´Ù. ±âº»°ªÀÌ ¾ø´Ù¸é ÀÌ Ç׸ñÀº + "None"À̾î¾ß ÇÑ´Ù. ±âº»°ªÀÌ ¼­¹ö¿¡ Æ÷ÇÔµÈ ±âº» + httpd.confÀÇ Áö½Ã¾î °ª°ú ´Ù¸¦ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó.

    +
    top
    +
    +

    »ç¿ëÀå¼Ò (Context)

    + +

    ¼­¹öÀÇ ¼³Á¤ÆÄÀÏÁß ¾î´À°÷¿¡¼­ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + ¾Ë·ÁÁØ´Ù. ´ÙÀ½ °ªµéÀ» ½°Ç¥·Î ±¸ºÐÇÑ ¸ñ·ÏÀÌ´Ù:

    + +
    +
    ÁÖ¼­¹ö¼³Á¤ (server config)
    + +
    Áö½Ã¾î¸¦ ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ (¿¹¸¦ µé¾î, + httpd.conf) »ç¿ëÇÒ ¼ö ÀÖÀ¸³ª, <VirtualHost>³ª + <Directory>¿¡¼­ + »ç¿ëÇÒ ¼ö ¾øÀ½À» ¶æÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + .htaccess ÆÄÀÏ¿¡¼­µµ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    °¡»óÈ£½ºÆ® (virtual host)
    + +
    Áö½Ã¾î¸¦ ¼­¹ö ¼³Á¤ÆÄÀÏÀÇ <VirtualHost> ¾È¿¡¼­ »ç¿ëÇÒ ¼ö + ÀÖÀ½À» ¶æÇÑ´Ù.
    + +
    µð·ºÅ丮 (directory)
    + +
    Áö½Ã¾î°¡ ¼½¼Ç ¼³Á¤¿¡ + ¼³¸íÇÑ Á¦¾àÀ» µû¸£¸ç, ¼­¹ö ¼³Á¤ÆÄÀÏÀÇ <Directory>, <Location>, <Files>, <Proxy>¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖÀ½À» ¶æÇÑ´Ù.
    + +
    .htaccess
    + +
    Áö½Ã¾î¸¦ µð·ºÅ丮º° .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÀ½À» ¶æÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ÇöÀç »ç¿ëÇÏ´Â + overrides °ª¿¡ µû¶ó ¹«½ÃµÉ ¼ö + ÀÖ´Ù.
    +
    + +

    Áö½Ã¾î´Â ÁöÁ¤µÈ Àå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ + °÷¿¡¼­ »ç¿ëÇÏ¸é ¼³Á¤¿À·ù°¡ ¹ß»ýÇÏ°í ¼­¹ö´Â ºÎºÐ¿¡ ´ëÇÑ ¿äûÀ» + ¿Ã¹Ù·Î ó¸®ÇÏÁö ¸øÇϰųª ÀÛµ¿ÀÌ, ¿¹¸¦ µé¾î ½ÃÀÛÁ¶Â÷µµ, + ¾ÈµÉ ¼ö ÀÖ´Ù.

    + +

    Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â Àå¼Ò´Â ¿­°ÅÇÑ Àå¼Ò¸¦ ¸ðµÎ + ºÒ¸°(boolean) ORÇÑ °á°úÀÌ´Ù. Áï, + "server config, .htaccess"¿¡¼­ °¡´ÉÇÏ´Ù´Â + Áö½Ã¾î´Â httpd.conf ÆÄÀÏ°ú .htaccess + ÆÄÀÏ¿¡¼­´Â »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, <Directory>³ª <VirtualHost>¿¡¼­´Â »ç¿ëÇÒ ¼ö ¾ø´Ù.

    +
    top
    +
    +

    Override ¿É¼Ç (Override)

    + +

    ÀÌ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÏ·Á¸é + ¾î¶² override ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÏ´ÂÁö¸¦ ³ªÅ¸³½´Ù. Áö½Ã¾îÀÇ + »ç¿ëÀå¼Ò°¡ Áö½Ã¾î¸¦ .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù°í ÇÑ´Ù¸é ¾î¶² »ç¿ëÀå¼Òµµ ³ª¿ÀÁö + ¾Ê´Â´Ù.

    + +

    Overrides´Â AllowOverride Áö½Ã¾î·Î Áö½ÃÇÏ°í, + (µð·ºÅ丮 µîÀÇ) ƯÁ¤ ¹üÀ§¿Í ÇÏÀ§ ¹üÀ§¿¡¼­ ´Ù¸¥ AllowOverride Áö½Ã¾î·Î ´Ù¸¥ °ªÀ» + ¼³Á¤ÇÏÁö¾Ê¾Ò´Ù¸é ÇÏÀ§ ¹üÀ§¿¡µµ ±×´ë·Î Àû¿ëµÈ´Ù. Áö½Ã¾î ¼³¸í¿¡ + »ç¿ë°¡´ÉÇÑ override À̸§µéÀÌ ³ª¿Â´Ù.

    +
    top
    +
    +

    »óÅÂ (Status)

    + +

    Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ ¾ó¸¶³ª ±ä¹ÐÈ÷ ¹­¿©ÀÖ´ÂÁö¸¦ + ³ªÅ¸³½´Ù. Áï, ±× Áö½Ã¾î³ª ±â´ÉÀ» »ç¿ëÇϱâÀ§ÇØ ¼­¹ö¸¦ + ¸ðµâ°ú °°ÀÌ ´Ù½Ã ÄÄÆÄÀÏÇÒ ÇÊ¿ä°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù. + °¡´ÉÇÑ °ªÀº ´ÙÀ½°ú °°´Ù:

    + +
    +
    Core
    + +
    Áö½Ã¾î°¡ "Core" »óŸ¦ °¡Áö¸é, Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ À¥¼­¹ö + Çٽɺκп¡ ¼ÓÇÏ°í Ç×»ó »ç¿ë°¡´ÉÇÔÀ» ¶æÇÑ´Ù.
    + +
    MPM
    + +
    "MPM" »óÅÂÀÎ Áö½Ã¾î´Â ´ÙÁßó¸® + ¸ðµâÀ» Á¦°øÇÑ´Ù. ÀÌ·± Áö½Ã¾î´Â Áö½Ã¾î ¼³¸í¿¡¼­ ¸ðµâ¿¡ ¿­°ÅµÈ MPMÁß Çϳª¸¦ »ç¿ëÇÒ¶§¸¸ + °¡´ÉÇÏ´Ù.
    + +
    Base
    + +
    ±âº»ÀûÀ¸·Î ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵǹǷΠÁ÷Á¢ ±¸¼º¿¡¼­ + ¸ðµâÀ» Á¦°ÅÇÏÁö ¾Ê¾Ò´Ù¸é ÀϹÝÀûÀ¸·Î »ç¿ë°¡´ÉÇÑ Ç¥ÁØ ¾ÆÆÄÄ¡ + ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾î´Â "Base" »óÅÂÀÌ´Ù.
    + +
    Extension
    + +
    ¾ÆÆÄÄ¡ ¼­¹ö ¹èÆ÷º»¿¡´Â Æ÷ÇÔµÇÀÖÁö¸¸ º¸Åë ¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀϵÇÁö¾Ê´Â ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾î´Â "Extension" »óÅÂÀÌ´Ù. + ÀÌ·± Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á¸é ¼­¹ö ÄÄÆÄÀÏ ±¸¼ºÆÄÀÏÀ» ¼öÁ¤ÇÏ°í + ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù.
    + +
    Experimental
    + +
    "Experimental"Àº Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖÁö¸¸, + »ç¿ëÀº ÀÚ½ÅÀÇ Ã¥ÀÓÀÓÀ» ³ªÅ¸³½´Ù. Áö½Ã¾î´Â ¹®¼­È­µÇÀÖÁö¸¸, + ½ÇÁ¦¿Í ´Ù¸¦ ¼ö ÀÖ´Ù. Áö½Ã¾î¸¦ Á¦°øÇÏ´Â ¸ðµâÀº ±âº»ÀûÀ¸·Î + ¾ÆÆÄÄ¡¿Í °°ÀÌ ÄÄÆÄÀ쵃 ¼öµµ ¾ÈµÉ ¼öµµ ÀÖ´Ù. Áö½Ã¾î¿Í ¸ðµâÀ» + ¼³¸íÇÏ´Â ¹®¼­ ¾Õ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö »ìÆìºÁ¶ó.
    +
    +
    top
    +
    +

    ¸ðµâ (Module)

    + +

    ´Ü¼øÈ÷ Áö½Ã¾î¸¦ Á¤ÀÇÇÑ ¼Ò½º ¸ðµâ¸íÀ» ¿­°ÅÇÑ´Ù.

    +
    top
    +
    +

    Áö¿ø (Compatibility)

    + +

    Áö½Ã¾î°¡ ¿ø·¡ ¾ÆÆÄÄ¡ ¹öÀü 2 ¹èÆ÷º»ÀÇ ÀϺΰ¡ ¾Æ´Ï¿´´Ù¸é, + Áö½Ã¾î¸¦ Ãß°¡Çϱ⠽ÃÀÛÇÑ ¹öÀüÀÌ ¿©±â ³ª¿Â´Ù. ¶Ç, ¾î¶² + Ç÷¡Æû¿¡¼­¸¸ »ç¿ë°¡´ÉÇÑ Áö½Ã¾îµµ ¿©±â ³ª¿Â´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directive-dict.xml b/trunk/docs/manual/mod/directive-dict.xml new file mode 100644 index 0000000000..8ae121370f --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.xml @@ -0,0 +1,289 @@ + + + + + + + + + + Terms Used to Describe Directives + + +

    This document describes the terms that are used to describe + each Apache configuration + directive.

    +
    +Configuration files + +
    Description + +

    A brief description of the purpose of the directive.

    +
    + +
    Syntax + +

    This indicates the format of the directive as it would + appear in a configuration file. This syntax is extremely + directive-specific, and is described in detail in the + directive's definition. Generally, the directive name is + followed by a series of one or more space-separated arguments. + If an argument contains a space, the argument must be enclosed + in double quotes. Optional arguments are enclosed in square + brackets. Where an argument can take on more than one possible + value, the possible values are separated by vertical bars "|". + Literal text is presented in the default font, while + argument-types for which substitution is necessary are + emphasized. Directives which can take a variable + number of arguments will end in "..." indicating that the last + argument is repeated.

    + +

    Directives use a great number of different argument types. A + few common ones are defined below.

    + +
    +
    URL
    + +
    A complete Uniform Resource Locator including a scheme, + hostname, and optional pathname as in + http://www.example.com/path/to/file.html
    + +
    URL-path
    + +
    The part of a url which follows the scheme and + hostname as in /path/to/file.html. The + url-path represents a web-view of a resource, as + opposed to a file-system view.
    + +
    file-path
    + +
    The path to a file in the local file-system beginning + with the root directory as in + /usr/local/apache/htdocs/path/to/file.html. + Unless otherwise specified, a file-path which does + not begin with a slash will be treated as relative to the ServerRoot.
    + +
    directory-path
    + +
    The path to a directory in the local file-system + beginning with the root directory as in + /usr/local/apache/htdocs/path/to/.
    + +
    filename
    + +
    The name of a file with no accompanying path information + as in file.html.
    + +
    regex
    + +
    A Perl-compatible regular + expression. The directive definition will specify what the + regex is matching against.
    + +
    extension
    + +
    In general, this is the part of the filename + which follows the last dot. However, Apache recognizes + multiple filename extensions, so if a filename + contains more than one dot, each dot-separated part of the + filename following the first dot is an extension. + For example, the filename file.html.en + contains two extensions: .html and + .en. For Apache directives, you may specify + extensions with or without the leading dot. In + addition, extensions are not case sensitive.
    + +
    MIME-type
    + +
    A method of describing the format of a file which + consists of a major format type and a minor format type, + separated by a slash as in text/html.
    + +
    env-variable
    + +
    The name of an environment + variable defined in the Apache configuration process. + Note this is not necessarily the same as an operating system + environment variable. See the environment variable documentation for + more details.
    +
    +
    + +
    Default + +

    If the directive has a default value (i.e., if you + omit it from your configuration entirely, the Apache Web server + will behave as though you set it to a particular value), it is + described here. If there is no default value, this section + should say "None". Note that the default listed here + is not necessarily the same as the value the directive takes in + the default httpd.conf distributed with the server.

    +
    + +
    Context + +

    This indicates where in the server's configuration files the + directive is legal. It's a comma-separated list of one or more + of the following values:

    + +
    +
    server config
    + +
    This means that the directive may be used in the server + configuration files (e.g., httpd.conf), but + not within any + VirtualHost + or Directory + containers. It is not allowed in .htaccess files + at all.
    + +
    virtual host
    + +
    This context means that the directive may appear inside + VirtualHost + containers in the server + configuration files.
    + +
    directory
    + +
    A directive marked as being valid in this context may be + used inside Directory, Location, Files, and Proxy containers + in the server configuration files, subject to the restrictions + outlined in Configuration + Sections.
    + +
    .htaccess
    + +
    If a directive is valid in this context, it means that it + can appear inside per-directory + .htaccess files. It may not be processed, though + depending upon the overrides currently active.
    +
    + +

    The directive is only allowed within the designated + context; if you try to use it elsewhere, you'll get a + configuration error that will either prevent the server from + handling requests in that context correctly, or will keep the + server from operating at all -- i.e., the server won't + even start.

    + +

    The valid locations for the directive are actually the + result of a Boolean OR of all of the listed contexts. In other + words, a directive that is marked as being valid in + "server config, .htaccess" can be used in the + httpd.conf file and in .htaccess + files, but not within any Directory or + VirtualHost + containers.

    +
    + +
    Override + +

    This directive attribute indicates which configuration + override must be active in order for the directive to be + processed when it appears in a .htaccess file. If + the directive's context + doesn't permit it to appear in .htaccess files, + then no context will be listed.

    + +

    Overrides are activated by the AllowOverride directive, and apply + to a particular scope (such as a directory) and all + descendants, unless further modified by other + AllowOverride directives at + lower levels. The documentation for that directive also lists the + possible override names available.

    +
    + +
    Status + +

    This indicates how tightly bound into the Apache Web server + the directive is; in other words, you may need to recompile the + server with an enhanced set of modules in order to gain access + to the directive and its functionality. Possible values for + this attribute are:

    + +
    +
    Core
    + +
    If a directive is listed as having "Core" status, that + means it is part of the innermost portions of the Apache Web + server, and is always available.
    + +
    MPM
    + +
    A directive labeled as having "MPM" status is provided by + a Multi-Processing Module. This + type of directive will be available if and only if you are + using one of the MPMs listed on the Module line of the directive + definition.
    + +
    Base
    + +
    A directive labeled as having "Base" status is supported + by one of the standard Apache modules which is compiled into + the server by default, and is therefore normally available + unless you've taken steps to remove the module from your + configuration.
    + +
    Extension
    + +
    A directive with "Extension" status is provided by one of + the modules included with the Apache server kit, but the + module isn't normally compiled into the server. To enable the + directive and its functionality, you will need to change the + server build configuration files and re-compile Apache.
    + +
    Experimental
    + +
    "Experimental" status indicates that the directive is + available as part of the Apache kit, but you're on your own + if you try to use it. The directive is being documented for + completeness, and is not necessarily supported. The module + which provides the directive may or may not be compiled in by + default; check the top of the page which describes the + directive and its module to see if it remarks on the + availability.
    +
    +
    + +
    Module + +

    This quite simply lists the name of the source module which + defines the directive.

    +
    + +
    Compatibility + +

    If the directive wasn't part of the original Apache version + 2 distribution, the version in which it was introduced should + be listed here. In addition, if the directive is available + only on certain platforms, it will be noted here.

    +
    + +
    + diff --git a/trunk/docs/manual/mod/directive-dict.xml.ja b/trunk/docs/manual/mod/directive-dict.xml.ja new file mode 100644 index 0000000000..0d08bca4ac --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.xml.ja @@ -0,0 +1,295 @@ + + + + + + + + + + $B%G%#%l%/%F%#%V$N2r@b$K;H$o$l$kMQ8l(B + + +

    $B$3$NJ8=q$O3F(B Apache $B@_Dj%G%#%l%/%F%#%V(B + $B$r@bL@$9$k$?$a$K;H$o$l$F$$$kMQ8l$r@bL@$7$^$9!#(B

    +
    +$B@_Dj%U%!%$%k(B + +
    $B@bL@(B + +

    $B%G%#%l%/%F%#%V$NL\E*$N4JC1$J@bL@!#(B

    +
    + +
    $B9=J8(B + +

    $B@_Dj%U%!%$%kCf$N%G%#%l%/%F%#%V$N=q<0$r<($7$^$9!#(B + $B$3$N9=J8$O%G%#%l%/%F%#%VFCM-$J$N$G!">\:Y$O%G%#%l%/%F%#%V$N@bL@$r(B + $B;2>H$7$F$/$@$5$$!#0lHLE*$K!"%G%#%l%/%F%#%VL>$N8e$K$O(B + $B6uGr$K$h$jJ,3d$5$l$?$$$/$D$+$N0z?t$,B3$-$^$9!#(B + $B0z?t$,6uGr$r4^$`$H$-$OFs=E0zMQId(B ($BLuCm(B: ") + $B$G0O$^$l$F$$$^$9!#(B $B%*%W%7%g%J%k$J0z?t$O3g8L(B + ($BLuCm(B: []) $B$G0O$^$l$F$$$^$9!#(B + $B0z?t$,J#?t$NCM$rl9g$O!"$=$l$i$NCM$O?bD>$NK@(B "|" + $B$G(B $BJ,3d$5$l$F$$$^$9!#(B + $BJQ99$5$l$J$$%F%-%9%H$O%G%U%)%k%H$N%U%)%s%H$GI=<($5$l!"CV49$NI,MW$J(B + $B0z?t$O(B$B6/D4$5$l$F(B$BI=<($5$l$^$9!#(B + $B0z?t$N?t$,JQ$o$k%G%#%l%/%F%#%V$O:G8e$N(B + $B0z?t$,7+$jJV$5$l$k$3$H$r<($9$?$a$K(B "..." + $B$G=*$o$j$^$9!#(B

    + +

    + $B%G%#%l%/%F%#%V$OB?$/$N0c$&7?$N0z?t$r$H$j$^$9!#$$$/$D$+!"NI$/(B + $B;H$o$l$k$b$N$r0J2<$GDj5A$7$^$9!#(B

    + +
    +
    URL
    + +
    http://www.example.com/path/to/file.html + $B$N$h$&$K!"(B + $B%9%-!<%`!"%[%9%HL>!"%Q%9L>(B($B>JN,2DG=(B)$B$r4^$s$G$$$k40A4$J(B + Uniform Resource Locator$B!#(B
    + +
    URL-path
    + +
    /path/to/file.html $B$N$h$&$K!"%9%-!<%`$H(B + $B%[%9%HL>$N8e$KB3$/(B url + $B$N0lIt!#(Burl-path $B$O(B + $B%U%!%$%k%7%9%F%`$+$i$N;kE@$G$O$J$/!"(B + $B%&%'%V$+$i$N;kE@$G%j%=!<%9$rI=8=$7$^$9!#(B
    + +
    file-path
    + +
    /usr/local/apache/htdocs/path/to/file.html + $B$N$h$&$K!"(B + $B%k!<%H%G%#%l%/%H%j$+$i;O$^$k%m!<%+%k$N%U%!%$%k%7%9%F%`>e$N%U%!%$%k$X$N%Q%9!#(B + $BDL>o!"%9%i%C%7%e$G;O$^$i$J$$(B file-path $B$O(B ServerRoot + $B$+$i$NAjBP%Q%9$H$7$F(B $B07$o$l$^$9!#(B
    + +
    directory-path
    + +
    /usr/local/apache/htdocs/path/to/ + $B$N$h$&$K!"(B + $B%k!<%H%G%#%l%/%H%j$+$i;O$^$k%m!<%+%k$N%U%!%$%k%7%9%F%`$N%G%#%l%/%H%j$X$N(B + $B%Q%9!#(B
    + +
    filename
    + +
    file.html $B$N$h$&$K!"%Q%9>pJs$NIU$$$F$$$J$$(B + $B%U%!%$%kL>!#(B
    + +
    regex
    + +
    Perl $B8_49$N(B$B@55,I=8=(B$B$G$9!#(B + $B%G%#%l%/%F%#%V$NDj5A$,(B regex + $B$,2?$KBP$7$F%^%C%A$r9T$J$&$N$+$r;XDj$7$^$9!#(B
    + +
    extension
    + +
    $B0lHLE*$K$O(B filename + $B$N:G8e$N%I%C%H$N8e$NItJ,$G$9!#(B $B$7$+$7!"(BApache + $B$OJ#?t$N%U%!%$%k$N3HD%;R$rG'<1$7$^$9$N$G!"(Bfilename + $B$KJ#?t$N%I%C%H$,$"$k$H!":G=i$N%I%C%H$N8e$N!"$=$l$>$l$N%I%C%H$GJ,N%$5$l$?ItJ,$,(B + extension ($BLuCm(B: $B3HD%;R(B) + $B$K$J$j$^$9!#Nc$($P!"(Bfilename + file.html.en + $B$K$OFs$D$N3HD%;R$,$"$j$^$9!#(B.html $B$H(B + .en $B$G$9!#(BApache + $B$N%G%#%l%/%F%#%V$G$O!"(Bextension + $B$O%I%C%HIU$-$G$bL5$7$G$b;XDj$G$-$^$9!#$5$i$K!"(Bextension + $B$O(B $BBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B
    + +
    MIME-type
    + +
    text/html $B$N$h$&$K!"%9%i%C%7%e$GJ,N%$5$l$?(B + $B + +
    env-variable
    + +
    Apache $B$N@_Dj$K$h$jDj5A$5$l$k(B $B4D6-JQ?t(B$B$NL>A0$G$9!#$3$l$O%*%Z%l!<%F%#%s%0%7%9%F%`$N(B + $B4D6-JQ?t$HF1$8$H$O8B$i$J$$$3$H$KCm0U$7$F$/$@$5$$!#>\:Y$O(B $B4D6-JQ?t$N@bL@(B$B$r;2>H$7$F$/$@$5$$!#(B
    +
    +
    + +
    $B%G%U%)%k%H(B + +

    $B%G%#%l%/%F%#%V$K%G%U%)%k%HCM(B + ($B$9$J$o$A(B$B!"@_Dj%U%!%$%k$+$i(B + $B>JN,$5$l$F$$$F$b!"(BApache + $B%&%'%V%5!<%P$OFCDj$NCM$K@_Dj$5$l$F$$$k$+$N$h$&$K(B + $BF0:n$7$^$9(B) $B$,$"$k>l9g$O$3$3$K5-=R$5$l$^$9!#(B + $B%G%U%)%k%HCM$NL5$$>l9g!"$3$3$O(B "None" $B$H(B + $B=q$+$l$^$9!#$3$3$G=q$+$l$F$$$k%G%U%)%k%H$O%5!<%P$H6&$KG[I[$5$l$F$$$k(B + $B%G%U%)%k%H$N(B httpd.conf + $BFb$K=q$+$l$F$$$k%G%#%l%/%F%#%V$NCM$H(B + $B0c$&2DG=@-$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    + +
    $B%3%s%F%-%9%H(B + +

    + $B$3$l$O!"%5!<%P$N@_Dj%U%!%$%kCf$N$I$3$G%G%#%l%/%F%#%V$,M-8z$J$N$+$r<($7$^$9!#(B + $Be%+%s%^6h@Z$j$GNs5s$5$l$F$$$^$9!#(B

    + +
    +
    $B%5!<%P@_Dj%U%!%$%k(B
    + +
    $B$3$l$O!"%5!<%P@_Dj%U%!%$%k(B + ($BNc$($P(B$B!"(Bhttpd.conf, + srm.conf, access.conf) + $BFb$G$O;HMQ$G$-$^$9$,!"(B + VirtualHost $B$d(B + Directory $B$NCf$G$O(B + $B;HMQ$G$-$J$$(B$B$3$H$r<($7$^$9!#(B + .htaccess$B%U%!%$%k$G$N;HMQ$O5v2D$5$l$F$$$^$;$s!#(B
    + +
    $B%P!<%A%c%k%[%9%H(B
    + +
    $B$3$l$O!"%5!<%P@_Dj%U%!%$%k$N(B + VirtualHost + $B$NCf$G;HMQ$G$-$k$3$H$r<($7$^$9!#(B
    + +
    $B%G%#%l%/%H%j(B
    + +
    $B$3$l$O!"%5!<%P@_Dj%U%!%$%k$N(B + Directory, + Location, + Files, + Proxy + $B%3%s%F%J$NCf$G!"(B $B@_Dj%;%/%7%g%s(B + $B$G@bL@$5$l$F$$$k@)8B$N2<$G;HMQ$G$-$k$3$H$r<($7$^$9!#(B
    + +
    .htaccess
    + +
    $B$3$l$O!"%G%#%l%/%H%j(B$BKh(B$B$N(B + .htaccess $B%U%!%$%kFb$G(B + $B;HMQ2DG=$G$"$k$3$H$r<($7$^$9!#(B $B$?$@!"(B$B>e=q$-(B + $B$N@_Dj$K$h$C$F$O!"=hM}$5$l$J$$$+$b$7$l$^$;$s!#(B
    +
    + +

    + $B%G%#%l%/%F%#%V$O;X<($5$l$?%3%s%F%-%9%H$G(B$B$N$_(B$B5v2D$5$l$^$9!#(B + $BB>$N>l=j$G;H$*$&$H$9$k$H!"%5!<%P$,$=$N%3%s%F%-%9%H$r@5$7$/07$($J$/(B + $B$J$k$h$&$J@_Dj%(%i!<$,H/@8$9$k$+!"%5!<%P$,$^$C$?$/F0:n$7$J$/$J$k!"(B + $B$9$J$o$A(B$B!"%5!<%P$,5/F0$7$J$/$J$k$H$$$&$3$H$K$J$j$^$9!#(B

    + +

    + $B%G%#%l%/%F%#%V$NM-8z$J0LCV$O!"$B%5!<%P@_Dj%U%!%$%k!"(B.htaccess" $B$GM-8z$@$H(B + $B5-$5$l$F$$$k%G%#%l%/%F%#%V$O(B httpd.conf + $B%U%!%$%k$H(B .htaccess + $B%U%!%$%k$H$GM-8z$G$9$,!"(B Directory + $B$d(B VirtualHost + $B$NCf$G$O;HMQ$G$-$^$;$s!#(B

    +
    + +
    $B>e=q$-(B + +

    $B$3$N%G%#%l%/%F%#%V$NB0@-$O!"(B.htaccess + $B%U%!%$%kCf$K(B + $B%G%#%l%/%F%#%V$,8=$l$?$H$-$K!"$=$l$N=hM}$rM-8z$K$9$k$?$a$K(B + $B$I$N@_Dj$N>e=q$-$,I,MW$+$r<($7$^$9!#(B $B%G%#%l%/%F%#%V$N(B + $B%3%s%F%-%9%H(B + $B$,!"(B.htaccess + $B%U%!%$%kCf$G$O5v2D$7$F$$$J$$>l9g$O!"(B $B$3$NB0@-$O(B + "$BE,MQIT2D(B" $B$H=q$+$l$^$9!#(B

    + +

    $B>e=q$-$O!"(BAllowOverride + $B%G%#%l%/%F%#%V$K$h$C$FM-8z$K$5$l!"(B + $BFCDj$N%9%3!<%W(B($B%G%#%l%/%H%j$J$I(B)$B$H!"(B + $B$5$i$K2<0L$N%l%Y%k$N(B AllowOverride + $B$G=$@5$5$l$J$$8B$j!"(B $B$=$NG[2<$KBP$7$FE,MQ$5$l$^$9!#(B + $B%G%#%l%/%F%#%V$N%I%-%e%a%s%H$Oe=q$-$NL>A0$b5s$2$^$9!#(B

    +
    + +
    $B%9%F!<%?%9(B + +

    $B$3$l$O%G%#%l%/%F%#%V$,(B Apache + $B%&%'%V%5!<%P$K$I$l$/$i$$$-$D$/AH$_9~$^$l$F$$$k$+$r(B + $B<($7$^$9!#8@$$49$($l$P!"%G%#%l%/%F%#%V$H$=$N5!G=$rMxMQ$9$k$?$a$K!"(B + $B%b%8%e!<%k$N?t$rA}$d$7$F!"%5!<%P$r:F%3%s%Q%$%k$9$kI,MW$,$"$k$+$b$7$l$J$$(B + $B$H$$$&$3$H$r<($7$^$9!#(B + $B$3$NB0@-$, + +

    +
    Core
    + +
    "Core" $B$N%G%#%l%/%F%#%V$O(B Apache + $B%&%'%V%5!<%P$N4pK\$H$J$k$Y$-$b$N$G$"$j!"(B + $B>o$K;HMQ2DG=$G$"$k$3$H$r<($7$^$9!#(B
    + +
    MPM
    + +
    "MPM" $B$N%G%#%l%/%F%#%V$O(B$B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B$B$GDs6!$5$l$F$$$^$9!#(B + $B$3$N$B%b%8%e!<%k(B$B$N9T$K;H$C$F$$$k%b%8%e!<%k$NL>A0$,=q$+$l$F$$$k(B + $B>l9g$K$N$_;HMQ2DG=$G$9!#(B
    + +
    Base
    + +
    "Base" $B$N%G%#%l%/%F%#%V$O(B + $B%G%U%)%k%H$G%5!<%P$KAH$_9~$^$l$F$$$kI8=`%b%8%e!<%k$NCf$N0l$D$G%5(B + $B%]!<%H$5$l$F$$$F!"$o$6$o$6@_Dj$+$i%b%8%e!<%k$r:o=|$7$?$H$-$r=|$$$F!"(B + $BDL>o$G$O;HMQ2DG=$G$"$k$3$H$r<($7$^$9!#(B
    + +
    Extension
    + +
    "Extension" $B$N%G%#%l%/%F%#%V$O!"(B Apache + $B%5!<%P$NG[I[J*$KF1:-$5$l$F$$$k%b%8%e!<%k$N0l$D$GDs6!$5$l$F$$$k$b$N$N!"(B + $BDL>o$G$O%5!<%P$KAH$_9~$^$l$F$$$J$$$3$H$r<($7$^$9!#(B + $B%G%#%l%/%F%#%V$H$=$N5!G=$rM-8z$K$9$k$K$O!"%5!<%P%S%k%IMQ$N@_Dj%U%!%$%k$r(B + $BJQ99$7$F(B Apache + $B$r:F%3%s%Q%$%k$9$kI,MW$,$"$j$^$9!#(B
    + +
    Experimental
    + +
    "Experimental" $B$N%G%#%l%/%F%#%V$O!"(BApache + $BG[I[J*$K(B + $BF1:-$5$l$F$$$k$b$N$N!";n$7$?$$>l9g$O<+8J@UG$$G9T$J$&(B + $BI,MW$,$"$k$H$$$&$3$H$r<($7$^$9!#%G%#%l%/%F%#%V$O!"$9$Y$F$N%I%-%e%a%s%H$r(B + $B40A4$K$=$m$o$;$k$?$a$K2r@b$5$l$F$$$^$9$,!"%5%]!<%H$5$l$F$$$k$H$O8B$j$^$;$s!#(B + $B%G%#%l%/%F%#%V$rDs6!$9$k%b%8%e!<%k$O%G%U%)%k%H$GAH$_9~$^$l$F$$$k$+$b(B + $B$7$l$^$;$s$7!"$=$&$G$J$$$+$b$7$l$^$;$s!#;HMQ2DG=$+$I$&$+$O!"(B + $B%G%#%l%/%F%#%V$H%b%8%e!<%k$N@bL@$r$7$F$$$k%Z!<%8$N@hF,$rD4$Y$F$/$@$5$$!#(B
    +
    +
    + +
    $B%b%8%e!<%k(B + +

    + $B$3$l$OC1=c$K%G%#%l%/%F%#%V$,Dj5A$5$l$F$$$k%b%8%e!<%k$NL>A0$r5-:\$7$^$9!#(B

    +
    + +
    $B8_49@-(B + +

    $B%G%#%l%/%F%#%V$,(B Apache 2 + $B$NG[I[$KAH$_9~$^$l$F$$$J$+$C$?>l9g!"(B + $B%G%#%l%/%F%#%V$,F3F~$5$l$?%P!<%8%g%s$,$3$3$K=q$+$l$F$$$^$9!#(B + $B$^$?!"%G%#%l%/%F%#%V$,FCDj$N%W%i%C%H%U%)!<%`$K$N$_B8:_$9$k$H$-$b(B + $B$3$3$K=q$+$l$F$$$^$9!#(B

    +
    +
    diff --git a/trunk/docs/manual/mod/directive-dict.xml.ko b/trunk/docs/manual/mod/directive-dict.xml.ko new file mode 100644 index 0000000000..c7381b7929 --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.xml.ko @@ -0,0 +1,249 @@ + + + + + + + + + + Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ »ç¿ëÇÑ ¿ë¾îµé + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤ + Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ »ç¿ëÇÑ ¿ë¾îµéÀ» ¼³¸íÇÑ´Ù.

    +
    +¼³Á¤ÆÄÀÏ + +
    ¼³¸í (Description) + +

    Áö½Ã¾îÀÇ ¸ñÀû¿¡ ´ëÇÑ °£´ÜÇÑ ¼³¸í.

    +
    + +
    ¹®¹ý (Syntax) + +

    ¼³Á¤ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ Áö½Ã¾îÀÇ Çü½ÄÀ» ¾Ë·ÁÁØ´Ù. ÀÌ ¹®¹ýÀº + Áö½Ã¾î¸¶´Ù ¸Å¿ì ´Ù¸£¸ç, Áö½Ã¾î¸¦ Á¤ÀÇÇÒ ¶§¸¶´Ù ÀÚ¼¼È÷ ¼³¸íÇÑ´Ù. + ÀϹÝÀûÀ¸·Î Áö½Ã¾î À̸§ µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ ¾Æ±Ô¸ÕÆ®µéÀÌ + ³ª¿Â´Ù. ¾Æ±Ô¸ÕÆ®°¡ °ø¹éÀ» Æ÷ÇÔÇÑ´Ù¸é ¾Æ±Ô¸ÕÆ®¸¦ ½Öµû¿ÈÇ¥·Î + ¹­¾î¾ß ÇÑ´Ù. ¼±ÅÃÀûÀÎ ¾Æ±Ô¸ÕÆ®´Â Áß°ýÈ£·Î ¹­´Â´Ù. ¾Æ±Ô¸ÕÆ®°¡ + ¿©·¯ °ªÁß ÇϳªÀÏ °æ¿ì °ªµéÀ» ¼öÁ÷¸·´ë "|"·Î ±¸ºÐÇÑ´Ù. + ¹®ÀÚ±×´ë·Î »ç¿ëÇÒ ºÎºÐÀº ±âº» ¹®ÀÚü·Î ¾²°í, ´ëüÇÒ ¾Æ±Ô¸ÕÆ®´Â + °­Á¶ÇÑ´Ù. ¾Æ±Ô¸ÕÆ® °³¼ö°¡ Á¤ÇØÁöÁö¾ÊÀº Áö½Ã¾î´Â + ¸¶Áö¸· ¾Æ±Ô¸ÕÆ®°¡ ¹Ýº¹µÊÀ» ³ªÅ¸³»´Â "..."À¸·Î ³¡³­´Ù.

    + +

    Áö½Ã¾î´Â ¸Å¿ì ´Ù¾çÇÑ Á¾·ùÀÇ ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ´Â´Ù. ÀÌÁß ÀÚÁÖ + »ç¿ëÇÏ´Â °ÍÀº ¾Æ·¡¿Í °°´Ù.

    + +
    +
    URL
    + +
    http://www.example.com/path/to/file.html°ú + °°ÀÌ ½ºÅ´(scheme), È£½ºÆ®¸í, ¼±ÅÃÀûÀÎ °æ·Î¸íÀ» Æ÷ÇÔÇÑ + ¿ÏÀüÇÑ Uniform Resource Locator
    + +
    URL-path
    + +
    /path/to/file.html°ú °°ÀÌ url¿¡¼­ + ½ºÅ´°ú È£½ºÆ®¸í µÚ¿¡ ³ª¿À´Â ºÎºÐ. url-path´Â + ÆÄÀϽýºÅÛ¿¡¼­ º» ½ÃÁ¡ÀÌ ¾Æ´Ñ À¥¿¡¼­ º» ½ÃÁ¡¿¡¼­ÀÇ ÀڷḦ + ³ªÅ¸³½´Ù.
    + +
    file-path
    + +
    /usr/local/apache/htdocs/path/to/file.html°ú + °°ÀÌ root µð·ºÅ丮·Î ½ÃÀÛÇÏ´Â ÆÄÀϽýºÅÛ»óÀÇ ÆÄÀÏ °æ·Î. µû·Î + ¾ð±ÞÇÏÁö¾ÊÀ¸¸é, ½½·¡½¬·Î ½ÃÀÛÇÏÁö¾ÊÀº file-path´Â + ServerRoot¿¡ »ó´ë°æ·Î·Î + Ãë±ÞÇÑ´Ù.
    + +
    directory-path
    + +
    /usr/local/apache/htdocs/path/to/¿Í °°ÀÌ + root µð·ºÅ丮·Î ½ÃÀÛÇÏ´Â ÆÄÀϽýºÅÛ»óÀÇ µð·ºÅ丮 °æ·Î.
    + +
    filename
    + +
    file.html°ú °°ÀÌ °æ·Î Á¤º¸°¡ ¾ø´Â ÆÄÀϸí.
    + +
    regex
    + +
    Perl Çü½ÄÀÇ Á¤±ÔÇ¥Çö½Ä(regular + expression). Áö½Ã¾î´Â regex·Î ¹«¾ùÀΰ¡¸¦ °Ë»öÇÑ´Ù.
    + +
    extension
    + +
    ÀϹÝÀûÀ¸·Î filename¿¡¼­ ¸¶Áö¸· ¸¶Ä§Ç¥ µÚ¿¡ + ³ª¿À´Â ºÎºÐÀÌ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡´Â ¿©·¯ È®ÀåÀÚ¸¦ ÀνÄÇÒ + ¼ö Àֱ⶧¹®¿¡, filename¿¡ ¸¶Ä§Ç¥°¡ ¿©·¯°³ Æ÷ÇÔµÈ + °æ¿ì ¸¶Ä§Ç¥·Î ±¸ºÐµÈ ¸ðµç ºÎºÐÀ» È®ÀåÀÚ(extension)·Î + ó¸®ÇÑ´Ù. ¿¹¸¦ µé¾î, ÆÄÀϸí file.html.enÀº + .html°ú .enÀ̶ó´Â µÎ°¡Áö È®ÀåÀÚ¸¦ + °¡Áø´Ù. ¾ÆÆÄÄ¡ Áö½Ã¾î¿¡¼­ extension¿¡ ÁöÁ¤ÇÑ + °ª ¾Õ¿¡ ¸¶Ä§Ç¥°¡ À־ µÇ°í ¾ø¾îµµ µÈ´Ù. ¶Ç, + extensionÀº ´ë¼Ò¹®ÀÚ¸¦ °¡¸®Áö¾Ê´Â´Ù.
    + +
    MIME-type
    + +
    text/html°ú °°ÀÌ ½½·¡½¬·Î major format + type°ú minor format type¸¦ ±¸ºÐÇÏ¿© ÆÄÀÏÀÇ Çü½ÄÀ» ¼³¸íÇÏ´Â + ¹æ½Ä.
    + +
    env-variable
    + +
    ¾ÆÆÄÄ¡ ¼³Á¤¿¡¼­ Á¤ÀÇÇÑ È¯°æº¯¼ö + À̸§. ¿î¿µÃ¼Á¦ÀÇ È¯°æº¯¼ö¿Í ´Ù¸§À» ÁÖÀÇÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº + ȯ°æº¯¼ö ¹®¼­¸¦ Âü°íÇ϶ó.
    +
    +
    + +
    ±âº»°ª (Default) + +

    Áö½Ã¾î¿¡ ±âº»°ªÀÌ ÀÖ´Ù¸é (¿¹¸¦ µé¾î, ¼³Á¤¿¡¼­ + Áö½Ã¾î¸¦ »ý·«ÇÑ °æ¿ì ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÌ °ªÀ» »ç¿ëÇÑ´Ù.) + ÀÌ Ç׸ñ¿¡ ³ª¿Â´Ù. ±âº»°ªÀÌ ¾ø´Ù¸é ÀÌ Ç׸ñÀº + "None"À̾î¾ß ÇÑ´Ù. ±âº»°ªÀÌ ¼­¹ö¿¡ Æ÷ÇÔµÈ ±âº» + httpd.confÀÇ Áö½Ã¾î °ª°ú ´Ù¸¦ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó.

    +
    + +
    »ç¿ëÀå¼Ò (Context) + +

    ¼­¹öÀÇ ¼³Á¤ÆÄÀÏÁß ¾î´À°÷¿¡¼­ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + ¾Ë·ÁÁØ´Ù. ´ÙÀ½ °ªµéÀ» ½°Ç¥·Î ±¸ºÐÇÑ ¸ñ·ÏÀÌ´Ù:

    + +
    +
    ÁÖ¼­¹ö¼³Á¤ (server config)
    + +
    Áö½Ã¾î¸¦ ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ (¿¹¸¦ µé¾î, + httpd.conf) »ç¿ëÇÒ ¼ö ÀÖÀ¸³ª, VirtualHost³ª + Directory¿¡¼­ + »ç¿ëÇÒ ¼ö ¾øÀ½À» ¶æÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + .htaccess ÆÄÀÏ¿¡¼­µµ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    °¡»óÈ£½ºÆ® (virtual host)
    + +
    Áö½Ã¾î¸¦ ¼­¹ö ¼³Á¤ÆÄÀÏÀÇ VirtualHost ¾È¿¡¼­ »ç¿ëÇÒ ¼ö + ÀÖÀ½À» ¶æÇÑ´Ù.
    + +
    µð·ºÅ丮 (directory)
    + +
    Áö½Ã¾î°¡ ¼½¼Ç ¼³Á¤¿¡ + ¼³¸íÇÑ Á¦¾àÀ» µû¸£¸ç, ¼­¹ö ¼³Á¤ÆÄÀÏÀÇ Directory, Location, Files, Proxy¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖÀ½À» ¶æÇÑ´Ù.
    + +
    .htaccess
    + +
    Áö½Ã¾î¸¦ µð·ºÅ丮º° .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÀ½À» ¶æÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ÇöÀç »ç¿ëÇÏ´Â + overrides °ª¿¡ µû¶ó ¹«½ÃµÉ ¼ö + ÀÖ´Ù.
    +
    + +

    Áö½Ã¾î´Â ÁöÁ¤µÈ Àå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ + °÷¿¡¼­ »ç¿ëÇÏ¸é ¼³Á¤¿À·ù°¡ ¹ß»ýÇÏ°í ¼­¹ö´Â ºÎºÐ¿¡ ´ëÇÑ ¿äûÀ» + ¿Ã¹Ù·Î ó¸®ÇÏÁö ¸øÇϰųª ÀÛµ¿ÀÌ, ¿¹¸¦ µé¾î ½ÃÀÛÁ¶Â÷µµ, + ¾ÈµÉ ¼ö ÀÖ´Ù.

    + +

    Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â Àå¼Ò´Â ¿­°ÅÇÑ Àå¼Ò¸¦ ¸ðµÎ + ºÒ¸°(boolean) ORÇÑ °á°úÀÌ´Ù. Áï, + "server config, .htaccess"¿¡¼­ °¡´ÉÇÏ´Ù´Â + Áö½Ã¾î´Â httpd.conf ÆÄÀÏ°ú .htaccess + ÆÄÀÏ¿¡¼­´Â »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, Directory³ª VirtualHost¿¡¼­´Â »ç¿ëÇÒ ¼ö ¾ø´Ù.

    +
    + +
    Override ¿É¼Ç (Override) + +

    ÀÌ Áö½Ã¾î¸¦ .htaccess ÆÄÀÏ¿¡¼­ »ç¿ëÇÏ·Á¸é + ¾î¶² override ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÏ´ÂÁö¸¦ ³ªÅ¸³½´Ù. Áö½Ã¾îÀÇ + »ç¿ëÀå¼Ò°¡ Áö½Ã¾î¸¦ .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù°í ÇÑ´Ù¸é ¾î¶² »ç¿ëÀå¼Òµµ ³ª¿ÀÁö + ¾Ê´Â´Ù.

    + +

    Overrides´Â AllowOverride Áö½Ã¾î·Î Áö½ÃÇÏ°í, + (µð·ºÅ丮 µîÀÇ) ƯÁ¤ ¹üÀ§¿Í ÇÏÀ§ ¹üÀ§¿¡¼­ ´Ù¸¥ AllowOverride Áö½Ã¾î·Î ´Ù¸¥ °ªÀ» + ¼³Á¤ÇÏÁö¾Ê¾Ò´Ù¸é ÇÏÀ§ ¹üÀ§¿¡µµ ±×´ë·Î Àû¿ëµÈ´Ù. Áö½Ã¾î ¼³¸í¿¡ + »ç¿ë°¡´ÉÇÑ override À̸§µéÀÌ ³ª¿Â´Ù.

    +
    + +
    »óÅÂ (Status) + +

    Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ ¾ó¸¶³ª ±ä¹ÐÈ÷ ¹­¿©ÀÖ´ÂÁö¸¦ + ³ªÅ¸³½´Ù. Áï, ±× Áö½Ã¾î³ª ±â´ÉÀ» »ç¿ëÇϱâÀ§ÇØ ¼­¹ö¸¦ + ¸ðµâ°ú °°ÀÌ ´Ù½Ã ÄÄÆÄÀÏÇÒ ÇÊ¿ä°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù. + °¡´ÉÇÑ °ªÀº ´ÙÀ½°ú °°´Ù:

    + +
    +
    Core
    + +
    Áö½Ã¾î°¡ "Core" »óŸ¦ °¡Áö¸é, Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ À¥¼­¹ö + Çٽɺκп¡ ¼ÓÇÏ°í Ç×»ó »ç¿ë°¡´ÉÇÔÀ» ¶æÇÑ´Ù.
    + +
    MPM
    + +
    "MPM" »óÅÂÀÎ Áö½Ã¾î´Â ´ÙÁßó¸® + ¸ðµâÀ» Á¦°øÇÑ´Ù. ÀÌ·± Áö½Ã¾î´Â Áö½Ã¾î ¼³¸í¿¡¼­ ¸ðµâ¿¡ ¿­°ÅµÈ MPMÁß Çϳª¸¦ »ç¿ëÇÒ¶§¸¸ + °¡´ÉÇÏ´Ù.
    + +
    Base
    + +
    ±âº»ÀûÀ¸·Î ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵǹǷΠÁ÷Á¢ ±¸¼º¿¡¼­ + ¸ðµâÀ» Á¦°ÅÇÏÁö ¾Ê¾Ò´Ù¸é ÀϹÝÀûÀ¸·Î »ç¿ë°¡´ÉÇÑ Ç¥ÁØ ¾ÆÆÄÄ¡ + ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾î´Â "Base" »óÅÂÀÌ´Ù.
    + +
    Extension
    + +
    ¾ÆÆÄÄ¡ ¼­¹ö ¹èÆ÷º»¿¡´Â Æ÷ÇÔµÇÀÖÁö¸¸ º¸Åë ¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀϵÇÁö¾Ê´Â ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾î´Â "Extension" »óÅÂÀÌ´Ù. + ÀÌ·± Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á¸é ¼­¹ö ÄÄÆÄÀÏ ±¸¼ºÆÄÀÏÀ» ¼öÁ¤ÇÏ°í + ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù.
    + +
    Experimental
    + +
    "Experimental"Àº Áö½Ã¾î°¡ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖÁö¸¸, + »ç¿ëÀº ÀÚ½ÅÀÇ Ã¥ÀÓÀÓÀ» ³ªÅ¸³½´Ù. Áö½Ã¾î´Â ¹®¼­È­µÇÀÖÁö¸¸, + ½ÇÁ¦¿Í ´Ù¸¦ ¼ö ÀÖ´Ù. Áö½Ã¾î¸¦ Á¦°øÇÏ´Â ¸ðµâÀº ±âº»ÀûÀ¸·Î + ¾ÆÆÄÄ¡¿Í °°ÀÌ ÄÄÆÄÀ쵃 ¼öµµ ¾ÈµÉ ¼öµµ ÀÖ´Ù. Áö½Ã¾î¿Í ¸ðµâÀ» + ¼³¸íÇÏ´Â ¹®¼­ ¾Õ¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö »ìÆìºÁ¶ó.
    +
    +
    + +
    ¸ðµâ (Module) + +

    ´Ü¼øÈ÷ Áö½Ã¾î¸¦ Á¤ÀÇÇÑ ¼Ò½º ¸ðµâ¸íÀ» ¿­°ÅÇÑ´Ù.

    +
    + +
    Áö¿ø (Compatibility) + +

    Áö½Ã¾î°¡ ¿ø·¡ ¾ÆÆÄÄ¡ ¹öÀü 2 ¹èÆ÷º»ÀÇ ÀϺΰ¡ ¾Æ´Ï¿´´Ù¸é, + Áö½Ã¾î¸¦ Ãß°¡Çϱ⠽ÃÀÛÇÑ ¹öÀüÀÌ ¿©±â ³ª¿Â´Ù. ¶Ç, ¾î¶² + Ç÷¡Æû¿¡¼­¸¸ »ç¿ë°¡´ÉÇÑ Áö½Ã¾îµµ ¿©±â ³ª¿Â´Ù.

    +
    + +
    + diff --git a/trunk/docs/manual/mod/directive-dict.xml.meta b/trunk/docs/manual/mod/directive-dict.xml.meta new file mode 100644 index 0000000000..fbf596604d --- /dev/null +++ b/trunk/docs/manual/mod/directive-dict.xml.meta @@ -0,0 +1,13 @@ + + + + directive-dict + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/directives.html b/trunk/docs/manual/mod/directives.html new file mode 100644 index 0000000000..29278cdb7c --- /dev/null +++ b/trunk/docs/manual/mod/directives.html @@ -0,0 +1,19 @@ +URI: directives.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: directives.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: directives.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: directives.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: directives.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/directives.html.de b/trunk/docs/manual/mod/directives.html.de new file mode 100644 index 0000000000..3b8740c4d8 --- /dev/null +++ b/trunk/docs/manual/mod/directives.html.de @@ -0,0 +1,428 @@ + + + +Verzeichnis der Direktiven - Apache HTTP Server + + + + + +
    <-
    +

    Verzeichnis der Direktiven

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Hier sind alle Apache-Direktiven aufgeführt, die in der + Standard-Apache-Distribution verfügbar sind. Sie sind in + einem einheitlichen Format beschrieben. Ein Glossar + erläutert die in der Beschreibung verwendeten Begriffe. +

    + +

    + Außerdem existiert eine Kurzreferenz der Direktiven, welche + zu jeder Direktive eine Zusammenfassung der Details enthält. +

    + +

     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

    +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directives.html.en b/trunk/docs/manual/mod/directives.html.en new file mode 100644 index 0000000000..363b1fe056 --- /dev/null +++ b/trunk/docs/manual/mod/directives.html.en @@ -0,0 +1,429 @@ + + + +Directive Index - Apache HTTP Server + + + + + +
    <-
    +

    Directive Index

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Each Apache directive available in the standard Apache + distribution is listed here. They are described using a + consistent format, and there is a dictionary of the terms used in their + descriptions available. +

    + +

    + A Directive Quick-Reference + is also available giving details about each directive in a + summary form. +

    + +

     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

    +
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directives.html.es b/trunk/docs/manual/mod/directives.html.es new file mode 100644 index 0000000000..2d5c22cf05 --- /dev/null +++ b/trunk/docs/manual/mod/directives.html.es @@ -0,0 +1,431 @@ + + + +Índice de Directivas - Servidor HTTP Apache + + + + + +
    <-
    +

    Índice de Directivas

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Todas las directivas disponibles en la distribución + estándar de Apache están en la lista que se muestra más + abajo. Cada una se describe usando un formato uniforme, y existe + un glosario + de los términos usados en las descripciones que puede + consultar. +

    + +

    + También existe una Guía Rápida de + Referencia de Directivas con información de cada + directiva de forma resumida. +

    + +

     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

    +
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directives.html.ja.euc-jp b/trunk/docs/manual/mod/directives.html.ja.euc-jp new file mode 100644 index 0000000000..02249f1b96 --- /dev/null +++ b/trunk/docs/manual/mod/directives.html.ja.euc-jp @@ -0,0 +1,426 @@ + + + +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö°ìÍ÷ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö°ìÍ÷

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + ɸ½à Apache ÇÛÉۤˤ¢¤ë¤¹¤Ù¤Æ¤Î Apache ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ìÍ÷¤Ç¤¹¡£ + ¤³¤ì¤é¤Ï°ì´Ó¤·¤¿·Á¼°¤Ç½ñ¤«¤ì¤Æ¤¤¤Æ¡¢»È¤ï¤ì¤Æ¤¤¤ëÍѸì¤Î + ÍѸ콸 ¤âÍÑ°Õ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ +

    +

    + ³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î³µÍפòÀâÌÀ¤·¤¿ ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¥¯¥¤¥Ã¥¯¥ê¥Õ¥¡¥ì¥ó¥¹¤â + ¤¢¤ê¤Þ¤¹¡£ +

    + +

     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

    +
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directives.html.ko.euc-kr b/trunk/docs/manual/mod/directives.html.ko.euc-kr new file mode 100644 index 0000000000..5b48bbd452 --- /dev/null +++ b/trunk/docs/manual/mod/directives.html.ko.euc-kr @@ -0,0 +1,423 @@ + + + +Áö½Ã¾î ¸ñ·Ï - Apache HTTP Server + + + + + +
    <-
    +

    Áö½Ã¾î ¸ñ·Ï

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + ´ÙÀ½Àº Ç¥ÁØ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡¼­ »ç¿ë°¡´ÉÇÑ Áö½Ã¾î ¸ñ·ÏÀÌ´Ù. + À̵éÀ» µ¿ÀÏÇÑ Çü½ÄÀ¸·Î ¼³¸íÇÏ¿´°í, ¼³¸í¿¡ »ç¿ëÇÑ ¿ë¾î + »çÀüµµ ÀÖ´Ù. +

    + +

    + °¢ Áö½Ã¾î¸¦ ¿ä¾àÇÏ¿© ¼³¸íÇÑ Áö½Ã¾î ºü¸¥ÂüÁ¶µµ ÀÖ´Ù. +

    + +

     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X 

    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/directives.xml b/trunk/docs/manual/mod/directives.xml new file mode 100644 index 0000000000..4334944475 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml @@ -0,0 +1,40 @@ + + + + + + + + + Directive Index + +

    + Each Apache directive available in the standard Apache + distribution is listed here. They are described using a + consistent format, and there is a dictionary of the terms used in their + descriptions available. +

    + +

    + A Directive Quick-Reference + is also available giving details about each directive in a + summary form. +

    +
    +
    diff --git a/trunk/docs/manual/mod/directives.xml.de b/trunk/docs/manual/mod/directives.xml.de new file mode 100644 index 0000000000..b4b39382d1 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml.de @@ -0,0 +1,40 @@ + + + + + + + + + Verzeichnis der Direktiven + +

    + Hier sind alle Apache-Direktiven aufgeführt, die in der + Standard-Apache-Distribution verfügbar sind. Sie sind in + einem einheitlichen Format beschrieben. Ein Glossar + erläutert die in der Beschreibung verwendeten Begriffe. +

    + +

    + Außerdem existiert eine Kurzreferenz der Direktiven, welche + zu jeder Direktive eine Zusammenfassung der Details enthält. +

    +
    +
    diff --git a/trunk/docs/manual/mod/directives.xml.es b/trunk/docs/manual/mod/directives.xml.es new file mode 100644 index 0000000000..6107c25af6 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml.es @@ -0,0 +1,42 @@ + + + + + + + + + Índice de Directivas + +

    + Todas las directivas disponibles en la distribución + estándar de Apache están en la lista que se muestra más + abajo. Cada una se describe usando un formato uniforme, y existe + un glosario + de los términos usados en las descripciones que puede + consultar. +

    + +

    + También existe una Guía Rápida de + Referencia de Directivas con información de cada + directiva de forma resumida. +

    +
    +
    + diff --git a/trunk/docs/manual/mod/directives.xml.ja b/trunk/docs/manual/mod/directives.xml.ja new file mode 100644 index 0000000000..a0ca7ed422 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml.ja @@ -0,0 +1,38 @@ + + + + + + + + + $B%G%#%l%/%F%#%V0lMw(B + +

    + $BI8=`(B Apache $BG[I[$K$"$k$9$Y$F$N(B Apache $B$N%G%#%l%/%F%#%V$N0lMw$G$9!#(B + $B$3$l$i$O0l4S$7$?7A<0$G=q$+$l$F$$$F!";H$o$l$F$$$kMQ8l$N(B + $BMQ8l=8(B $B$bMQ0U$5$l$F$$$^$9!#(B +

    +

    + $B3F%G%#%l%/%F%#%V$N35MW$r@bL@$7$?(B $B%G%#%l%/%F%#%V%/%$%C%/%j%U%!%l%s%9(B$B$b(B + $B$"$j$^$9!#(B +

    +
    +
    diff --git a/trunk/docs/manual/mod/directives.xml.ko b/trunk/docs/manual/mod/directives.xml.ko new file mode 100644 index 0000000000..c66d4ba1e6 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml.ko @@ -0,0 +1,37 @@ + + + + + + + + + Áö½Ã¾î ¸ñ·Ï + +

    + ´ÙÀ½Àº Ç¥ÁØ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡¼­ »ç¿ë°¡´ÉÇÑ Áö½Ã¾î ¸ñ·ÏÀÌ´Ù. + À̵éÀ» µ¿ÀÏÇÑ Çü½ÄÀ¸·Î ¼³¸íÇÏ¿´°í, ¼³¸í¿¡ »ç¿ëÇÑ ¿ë¾î + »çÀüµµ ÀÖ´Ù. +

    + +

    + °¢ Áö½Ã¾î¸¦ ¿ä¾àÇÏ¿© ¼³¸íÇÑ Áö½Ã¾î ºü¸¥ÂüÁ¶µµ ÀÖ´Ù. +

    +
    +
    diff --git a/trunk/docs/manual/mod/directives.xml.meta b/trunk/docs/manual/mod/directives.xml.meta new file mode 100644 index 0000000000..9049742913 --- /dev/null +++ b/trunk/docs/manual/mod/directives.xml.meta @@ -0,0 +1,15 @@ + + + + directives + /mod/ + .. + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/mod/event.html b/trunk/docs/manual/mod/event.html new file mode 100644 index 0000000000..df756d5213 --- /dev/null +++ b/trunk/docs/manual/mod/event.html @@ -0,0 +1,3 @@ +URI: event.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/event.html.en b/trunk/docs/manual/mod/event.html.en new file mode 100644 index 0000000000..bc4680cbb7 --- /dev/null +++ b/trunk/docs/manual/mod/event.html.en @@ -0,0 +1,83 @@ + + + +event - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM event

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:An experimental variant of the standard worker +MPM
    Status:MPM
    Module Identifier:mpm_event_module
    Source File:event.c
    +

    Summary

    + +

    Warning

    +

    This MPM is experimental, so it may or may not work + as expected.

    +
    + +

    To use the event MPM, add + --with-mpm=event to the configure + script's arguments when building the httpd.

    + +

    This MPM depends on APR's atomic compare-and-swap operations for + thread synchronization. If you are compiling for an x86 target + and you don't need to support 386s, or you are compiling for a + SPARC and you don't need to run on pre-UltraSPARC chips, add + --enable-nonportable-atomics=yes to the + configure script's arguments. This will cause + APR to implement atomic operations + using efficient opcodes not available in older CPUs.

    +
    + + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/event.xml b/trunk/docs/manual/mod/event.xml new file mode 100644 index 0000000000..20dc8158ed --- /dev/null +++ b/trunk/docs/manual/mod/event.xml @@ -0,0 +1,94 @@ + + + + + + + + +event +An experimental variant of the standard worker +MPM +MPM +event.c +mpm_event_module + + + Warning +

    This MPM is experimental, so it may or may not work + as expected.

    +
    + +

    To use the event MPM, add + --with-mpm=event to the configure + script's arguments when building the httpd.

    + +

    This MPM depends on APR's atomic compare-and-swap operations for + thread synchronization. If you are compiling for an x86 target + and you don't need to support 386s, or you are compiling for a + SPARC and you don't need to run on pre-UltraSPARC chips, add + --enable-nonportable-atomics=yes to the + configure script's arguments. This will cause + APR to implement atomic operations + using efficient opcodes not available in older CPUs.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +SendBufferSize + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +ScoreBoardFile + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/event.xml.meta b/trunk/docs/manual/mod/event.xml.meta new file mode 100644 index 0000000000..daffdde3d9 --- /dev/null +++ b/trunk/docs/manual/mod/event.xml.meta @@ -0,0 +1,11 @@ + + + + event + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/index.html b/trunk/docs/manual/mod/index.html new file mode 100644 index 0000000000..15e69b0703 --- /dev/null +++ b/trunk/docs/manual/mod/index.html @@ -0,0 +1,19 @@ +URI: index.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/index.html.de b/trunk/docs/manual/mod/index.html.de new file mode 100644 index 0000000000..75df7a2ea3 --- /dev/null +++ b/trunk/docs/manual/mod/index.html.de @@ -0,0 +1,198 @@ + + + +Modul-Index - Apache HTTP Server + + + + + +
    <-
    +

    Modul-Index

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Unten ist eine Liste aller Module angegeben, die als Bestandteil der + Apache-Distribution mitgeliefert werden. Bitte beachten Sie auch die + vollständige alphabetische Liste aller + Apache-Direktiven. +

    +
    + +
    top
    +

    Kernfunktionen und + Multi-Processing-Module

    +
    +
    core
    Ständig verfügbare Kernfunktionen des Apache HTTP +Servers
    +
    mpm_common
    Eine Sammlung von Direktiven, die in mehr als einem + Multi-Processing-Modul (MPM) implementiert sind.
    +
    beos
    Dieses Multi-Processing-Modul ist für BeOS + optimiert.
    +
    event
    An experimental variant of the standard worker +MPM
    +
    leader
    Eine experimentelle Variante des Standard-MPMs + worker
    +
    mpm_netware
    Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    +
    mpmt_os2
    Hybrid multi-process, multi-threaded MPM for OS/2
    +
    perchild
    Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    +
    prefork
    Implementiert einen im Voraus forkenden Webserver ohne + Thread-Unterstützung
    +
    threadpool
    Yet another experimental variant of the standard +worker MPM
    +
    mpm_winnt
    Das Multi-Processing-Modul ist optimiert für + Windows NT.
    +
    worker
    Multi-Processing-Modul, das einen Hybrid-Webserver mit + Multi-Thread und Multi-Prozess-Unterstützung implementiert
    +
    +
    top
    +

    Andere Module

    +

     A  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V 

    +
    mod_actions
    Dieses Modul ermöglicht die Ausführung von CGI-Skripten + in Abhängigkeit von Medientypen und Anfragemethoden.
    +
    mod_alias
    Provides for mapping different parts of the host + filesystem in the document tree and for URL redirection
    +
    mod_asis
    Sends files that contain their own +HTTP headers
    +
    mod_auth_basic
    Basic authentication
    +
    mod_auth_digest
    User authentication using MD5 + Digest Authentication.
    +
    mod_authn_alias
    Provides the ability to create extended authentication + providers based on actual providers
    +
    mod_authn_anon
    Allows "anonymous" user access to authenticated + areas
    +
    mod_authn_dbm
    User authentication using DBM files
    +
    mod_authn_default
    Authentication fallback module
    +
    mod_authn_file
    User authentication using text files
    +
    mod_authnz_ldap
    Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    +
    mod_authz_dbm
    Group authorization using DBM files
    +
    mod_authz_default
    Authorization fallback module
    +
    mod_authz_groupfile
    Group authorization using plaintext files
    +
    mod_authz_host
    Group authorizations based on host (name or IP +address)
    +
    mod_authz_owner
    Authorization based on file ownership
    +
    mod_authz_user
    User Authorization
    +
    mod_autoindex
    Generates directory indexes, + automatically, similar to the Unix ls command or the + Win32 dir shell command
    +
    mod_cache
    Content cache keyed to URIs.
    +
    mod_cern_meta
    CERN httpd metafile semantics
    +
    mod_cgi
    Execution of CGI scripts
    +
    mod_cgid
    Execution of CGI scripts using an + external CGI daemon
    +
    mod_charset_lite
    Specify character set translation or recoding
    +
    mod_dav
    Distributed Authoring and Versioning +(WebDAV) functionality
    +
    mod_dav_fs
    filesystem provider for mod_dav
    +
    mod_dav_lock
    generic locking module for mod_dav
    +
    mod_dbd
    Manages SQL database connections
    +
    mod_deflate
    Compress content before it is delivered to the +client
    +
    mod_dir
    Provides for "trailing slash" redirects and + serving directory index files
    +
    mod_disk_cache
    Content cache storage manager keyed to URIs
    +
    mod_dumpio
    Dumps all I/O to error log as desired.
    +
    mod_echo
    A simple echo server to illustrate protocol +modules
    +
    mod_env
    Modifies the environment which is passed to CGI scripts and +SSI pages
    +
    mod_example
    Illustrates the Apache module API
    +
    mod_expires
    Generation of Expires and +Cache-Control HTTP headers according to user-specified +criteria
    +
    mod_ext_filter
    Pass the response body through an external program before +delivery to the client
    +
    mod_file_cache
    Caches a static list of files in memory
    +
    mod_filter
    Context-sensitive smart filter configuration module
    +
    mod_headers
    Customization of HTTP request and response +headers
    +
    mod_ident
    RFC 1413 ident lookups
    +
    mod_imagemap
    Server-side imagemap processing
    +
    mod_include
    Server-parsed html documents (Server Side Includes)
    +
    mod_info
    Provides a comprehensive overview of the server +configuration
    +
    mod_isapi
    ISAPI Extensions within Apache for Windows
    +
    mod_ldap
    LDAP connection pooling and result caching services for use +by other LDAP modules
    +
    mod_log_config
    Logging of the requests made to the server
    +
    mod_log_forensic
    Forensic Logging of the requests made to the server
    +
    mod_logio
    Logging of input and output bytes per request
    +
    mod_mem_cache
    Content cache keyed to URIs
    +
    mod_mime
    Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding)
    +
    mod_mime_magic
    Determines the MIME type of a file + by looking at a few bytes of its contents
    +
    mod_negotiation
    Provides for content negotiation
    +
    mod_nw_ssl
    Enable SSL encryption for NetWare
    +
    mod_proxy
    HTTP/1.1 proxy/gateway server
    +
    mod_proxy_ajp
    AJP support module for +mod_proxy
    +
    mod_proxy_balancer
    mod_proxy extension for load balancing
    +
    mod_proxy_connect
    mod_proxy extension for +CONNECT request handling
    +
    mod_proxy_ftp
    FTP support module for +mod_proxy
    +
    mod_proxy_http
    HTTP support module for +mod_proxy
    +
    mod_rewrite
    Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    +
    mod_setenvif
    Allows the setting of environment variables based +on characteristics of the request
    +
    mod_so
    Loading of executable code and +modules into the server at start-up or restart time
    +
    mod_speling
    Attempts to correct mistaken URLs that +users might have entered by ignoring capitalization and by +allowing up to one misspelling
    +
    mod_ssl
    Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    +
    mod_status
    Provides information on server activity and +performance
    +
    mod_suexec
    Allows CGI scripts to run as a specified user +and Group
    +
    mod_unique_id
    Provides an environment variable with a unique +identifier for each request
    +
    mod_userdir
    User-specific directories
    +
    mod_usertrack
    +Clickstream logging of user activity on a site +
    +
    mod_version
    Version dependent configuration
    +
    mod_vhost_alias
    Provides for dynamically configured mass virtual +hosting
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/index.html.en b/trunk/docs/manual/mod/index.html.en new file mode 100644 index 0000000000..fde3e72f5c --- /dev/null +++ b/trunk/docs/manual/mod/index.html.en @@ -0,0 +1,196 @@ + + + +Module Index - Apache HTTP Server + + + + + +
    <-
    +

    Module Index

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Below is a list of all of the modules that come as part of + the Apache distribution. See also the complete + alphabetical list of all Apache + directives. +

    +
    + +
    top
    +

    Core Features and Multi-Processing + Modules

    +
    +
    core
    Core Apache HTTP Server features that are always +available
    +
    mpm_common
    A collection of directives that are implemented by +more than one multi-processing module (MPM)
    +
    beos
    This Multi-Processing Module is optimized for BeOS.
    +
    event
    An experimental variant of the standard worker +MPM
    +
    leader
    An experimental variant of the standard worker +MPM
    +
    mpm_netware
    Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    +
    mpmt_os2
    Hybrid multi-process, multi-threaded MPM for OS/2
    +
    perchild
    Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    +
    prefork
    Implements a non-threaded, pre-forking web server
    +
    threadpool
    Yet another experimental variant of the standard +worker MPM
    +
    mpm_winnt
    This Multi-Processing Module is optimized for Windows +NT.
    +
    worker
    Multi-Processing Module implementing a hybrid + multi-threaded multi-process web server
    +
    +
    top
    +

    Other Modules

    +

     A  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V 

    +
    mod_actions
    This module provides for executing CGI scripts based on +media type or request method.
    +
    mod_alias
    Provides for mapping different parts of the host + filesystem in the document tree and for URL redirection
    +
    mod_asis
    Sends files that contain their own +HTTP headers
    +
    mod_auth_basic
    Basic authentication
    +
    mod_auth_digest
    User authentication using MD5 + Digest Authentication.
    +
    mod_authn_alias
    Provides the ability to create extended authentication + providers based on actual providers
    +
    mod_authn_anon
    Allows "anonymous" user access to authenticated + areas
    +
    mod_authn_dbm
    User authentication using DBM files
    +
    mod_authn_default
    Authentication fallback module
    +
    mod_authn_file
    User authentication using text files
    +
    mod_authnz_ldap
    Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    +
    mod_authz_dbm
    Group authorization using DBM files
    +
    mod_authz_default
    Authorization fallback module
    +
    mod_authz_groupfile
    Group authorization using plaintext files
    +
    mod_authz_host
    Group authorizations based on host (name or IP +address)
    +
    mod_authz_owner
    Authorization based on file ownership
    +
    mod_authz_user
    User Authorization
    +
    mod_autoindex
    Generates directory indexes, + automatically, similar to the Unix ls command or the + Win32 dir shell command
    +
    mod_cache
    Content cache keyed to URIs.
    +
    mod_cern_meta
    CERN httpd metafile semantics
    +
    mod_cgi
    Execution of CGI scripts
    +
    mod_cgid
    Execution of CGI scripts using an + external CGI daemon
    +
    mod_charset_lite
    Specify character set translation or recoding
    +
    mod_dav
    Distributed Authoring and Versioning +(WebDAV) functionality
    +
    mod_dav_fs
    filesystem provider for mod_dav
    +
    mod_dav_lock
    generic locking module for mod_dav
    +
    mod_dbd
    Manages SQL database connections
    +
    mod_deflate
    Compress content before it is delivered to the +client
    +
    mod_dir
    Provides for "trailing slash" redirects and + serving directory index files
    +
    mod_disk_cache
    Content cache storage manager keyed to URIs
    +
    mod_dumpio
    Dumps all I/O to error log as desired.
    +
    mod_echo
    A simple echo server to illustrate protocol +modules
    +
    mod_env
    Modifies the environment which is passed to CGI scripts and +SSI pages
    +
    mod_example
    Illustrates the Apache module API
    +
    mod_expires
    Generation of Expires and +Cache-Control HTTP headers according to user-specified +criteria
    +
    mod_ext_filter
    Pass the response body through an external program before +delivery to the client
    +
    mod_file_cache
    Caches a static list of files in memory
    +
    mod_filter
    Context-sensitive smart filter configuration module
    +
    mod_headers
    Customization of HTTP request and response +headers
    +
    mod_ident
    RFC 1413 ident lookups
    +
    mod_imagemap
    Server-side imagemap processing
    +
    mod_include
    Server-parsed html documents (Server Side Includes)
    +
    mod_info
    Provides a comprehensive overview of the server +configuration
    +
    mod_isapi
    ISAPI Extensions within Apache for Windows
    +
    mod_ldap
    LDAP connection pooling and result caching services for use +by other LDAP modules
    +
    mod_log_config
    Logging of the requests made to the server
    +
    mod_log_forensic
    Forensic Logging of the requests made to the server
    +
    mod_logio
    Logging of input and output bytes per request
    +
    mod_mem_cache
    Content cache keyed to URIs
    +
    mod_mime
    Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding)
    +
    mod_mime_magic
    Determines the MIME type of a file + by looking at a few bytes of its contents
    +
    mod_negotiation
    Provides for content negotiation
    +
    mod_nw_ssl
    Enable SSL encryption for NetWare
    +
    mod_proxy
    HTTP/1.1 proxy/gateway server
    +
    mod_proxy_ajp
    AJP support module for +mod_proxy
    +
    mod_proxy_balancer
    mod_proxy extension for load balancing
    +
    mod_proxy_connect
    mod_proxy extension for +CONNECT request handling
    +
    mod_proxy_ftp
    FTP support module for +mod_proxy
    +
    mod_proxy_http
    HTTP support module for +mod_proxy
    +
    mod_rewrite
    Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    +
    mod_setenvif
    Allows the setting of environment variables based +on characteristics of the request
    +
    mod_so
    Loading of executable code and +modules into the server at start-up or restart time
    +
    mod_speling
    Attempts to correct mistaken URLs that +users might have entered by ignoring capitalization and by +allowing up to one misspelling
    +
    mod_ssl
    Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    +
    mod_status
    Provides information on server activity and +performance
    +
    mod_suexec
    Allows CGI scripts to run as a specified user +and Group
    +
    mod_unique_id
    Provides an environment variable with a unique +identifier for each request
    +
    mod_userdir
    User-specific directories
    +
    mod_usertrack
    +Clickstream logging of user activity on a site +
    +
    mod_version
    Version dependent configuration
    +
    mod_vhost_alias
    Provides for dynamically configured mass virtual +hosting
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/index.html.es b/trunk/docs/manual/mod/index.html.es new file mode 100644 index 0000000000..2a5b17f029 --- /dev/null +++ b/trunk/docs/manual/mod/index.html.es @@ -0,0 +1,199 @@ + + + +Índice de Módulos - Servidor HTTP Apache + + + + + +
    <-
    +

    Índice de Módulos

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + Abajo se muestra una lista con todos los módulos que forman + parte de la distribución de Apache. Consulte también la lista + alfabética completa de las + directivas de Apache. +

    +
    + +
    top
    +

    Funcionalidad Básica y Módulos + de MultiProcesamiento

    +
    +
    core
    Core Apache HTTP Server features that are always +available
    +
    mpm_common
    A collection of directives that are implemented by +more than one multi-processing module (MPM)
    +
    beos
    Este módulo de muiltiprocesamiento está +optimizado para BeOS.
    +
    event
    An experimental variant of the standard worker +MPM
    +
    leader
    An experimental variant of the standard worker +MPM
    +
    mpm_netware
    Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    +
    mpmt_os2
    Hybrid multi-process, multi-threaded MPM for OS/2
    +
    perchild
    Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    +
    prefork
    Implements a non-threaded, pre-forking web server
    +
    threadpool
    Yet another experimental variant of the standard +worker MPM
    +
    mpm_winnt
    This Multi-Processing Module is optimized for Windows +NT.
    +
    worker
    Multi-Processing Module implementing a hybrid + multi-threaded multi-process web server
    +
    +
    top
    +

    Otros Módulos

    +

     A  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V 

    +
    mod_actions
    This module provides for executing CGI scripts based on +media type or request method.
    +
    mod_alias
    Provides for mapping different parts of the host + filesystem in the document tree and for URL redirection
    +
    mod_asis
    Sends files that contain their own +HTTP headers
    +
    mod_auth_basic
    Basic authentication
    +
    mod_auth_digest
    User authentication using MD5 + Digest Authentication.
    +
    mod_authn_alias
    Provides the ability to create extended authentication + providers based on actual providers
    +
    mod_authn_anon
    Allows "anonymous" user access to authenticated + areas
    +
    mod_authn_dbm
    User authentication using DBM files
    +
    mod_authn_default
    Authentication fallback module
    +
    mod_authn_file
    User authentication using text files
    +
    mod_authnz_ldap
    Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    +
    mod_authz_dbm
    Group authorization using DBM files
    +
    mod_authz_default
    Authorization fallback module
    +
    mod_authz_groupfile
    Group authorization using plaintext files
    +
    mod_authz_host
    Group authorizations based on host (name or IP +address)
    +
    mod_authz_owner
    Authorization based on file ownership
    +
    mod_authz_user
    User Authorization
    +
    mod_autoindex
    Generates directory indexes, + automatically, similar to the Unix ls command or the + Win32 dir shell command
    +
    mod_cache
    Content cache keyed to URIs.
    +
    mod_cern_meta
    CERN httpd metafile semantics
    +
    mod_cgi
    Execution of CGI scripts
    +
    mod_cgid
    Execution of CGI scripts using an + external CGI daemon
    +
    mod_charset_lite
    Specify character set translation or recoding
    +
    mod_dav
    Distributed Authoring and Versioning +(WebDAV) functionality
    +
    mod_dav_fs
    filesystem provider for mod_dav
    +
    mod_dav_lock
    generic locking module for mod_dav
    +
    mod_dbd
    Manages SQL database connections
    +
    mod_deflate
    Compress content before it is delivered to the +client
    +
    mod_dir
    Provides for "trailing slash" redirects and + serving directory index files
    +
    mod_disk_cache
    Content cache storage manager keyed to URIs
    +
    mod_dumpio
    Dumps all I/O to error log as desired.
    +
    mod_echo
    A simple echo server to illustrate protocol +modules
    +
    mod_env
    Modifies the environment which is passed to CGI scripts and +SSI pages
    +
    mod_example
    Illustrates the Apache module API
    +
    mod_expires
    Generation of Expires and +Cache-Control HTTP headers according to user-specified +criteria
    +
    mod_ext_filter
    Pass the response body through an external program before +delivery to the client
    +
    mod_file_cache
    Caches a static list of files in memory
    +
    mod_filter
    Context-sensitive smart filter configuration module
    +
    mod_headers
    Customization of HTTP request and response +headers
    +
    mod_ident
    RFC 1413 ident lookups
    +
    mod_imagemap
    Server-side imagemap processing
    +
    mod_include
    Server-parsed html documents (Server Side Includes)
    +
    mod_info
    Provides a comprehensive overview of the server +configuration
    +
    mod_isapi
    ISAPI Extensions within Apache for Windows
    +
    mod_ldap
    LDAP connection pooling and result caching services for use +by other LDAP modules
    +
    mod_log_config
    Logging of the requests made to the server
    +
    mod_log_forensic
    Forensic Logging of the requests made to the server
    +
    mod_logio
    Logging of input and output bytes per request
    +
    mod_mem_cache
    Content cache keyed to URIs
    +
    mod_mime
    Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding)
    +
    mod_mime_magic
    Determines the MIME type of a file + by looking at a few bytes of its contents
    +
    mod_negotiation
    Provides for content negotiation
    +
    mod_nw_ssl
    Enable SSL encryption for NetWare
    +
    mod_proxy
    HTTP/1.1 proxy/gateway server
    +
    mod_proxy_ajp
    AJP support module for +mod_proxy
    +
    mod_proxy_balancer
    mod_proxy extension for load balancing
    +
    mod_proxy_connect
    mod_proxy extension for +CONNECT request handling
    +
    mod_proxy_ftp
    FTP support module for +mod_proxy
    +
    mod_proxy_http
    HTTP support module for +mod_proxy
    +
    mod_rewrite
    Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    +
    mod_setenvif
    Allows the setting of environment variables based +on characteristics of the request
    +
    mod_so
    Loading of executable code and +modules into the server at start-up or restart time
    +
    mod_speling
    Attempts to correct mistaken URLs that +users might have entered by ignoring capitalization and by +allowing up to one misspelling
    +
    mod_ssl
    Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    +
    mod_status
    Provides information on server activity and +performance
    +
    mod_suexec
    Allows CGI scripts to run as a specified user +and Group
    +
    mod_unique_id
    Provides an environment variable with a unique +identifier for each request
    +
    mod_userdir
    User-specific directories
    +
    mod_usertrack
    +Clickstream logging of user activity on a site +
    +
    mod_version
    Version dependent configuration
    +
    mod_vhost_alias
    Provides for dynamically configured mass virtual +hosting
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/index.html.ja.euc-jp b/trunk/docs/manual/mod/index.html.ja.euc-jp new file mode 100644 index 0000000000..62c77abd6e --- /dev/null +++ b/trunk/docs/manual/mod/index.html.ja.euc-jp @@ -0,0 +1,184 @@ + + + +¥â¥¸¥å¡¼¥ë°ìÍ÷ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥â¥¸¥å¡¼¥ë°ìÍ÷

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + °Ê²¼¤Ï Apache ¤ÎÇÛÉۤΰìÉô¤È¤·¤ÆÇÛ¤é¤ì¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¥â¥¸¥å¡¼¥ë¤Î + °ìÍ÷¤Ç¤¹¡£¤¹¤Ù¤Æ¤Î Apache + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È½ç¤Î¥ê¥¹¥È¤â¸«¤Æ¤¯¤À¤µ¤¤¡£ +

    +
    + +
    top
    +

    ¥³¥¢µ¡Ç½¤È MPM

    +
    +
    core
    ¾ï¤Ë»ÈÍѲÄǽ¤Ê Apache HTTP ¥µ¡¼¥Ð¤Î¥³¥¢µ¡Ç½
    +
    mpm_common
    Æó¤Ä°Ê¾å¤Î¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) +¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥³¥ì¥¯¥·¥ç¥ó
    +
    beos
    This Multi-Processing Module is optimized for BeOS.
    +
    event
    An experimental variant of the standard worker +MPM
    +
    leader
    An experimental variant of the standard worker +MPM
    +
    mpm_netware
    Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    +
    mpmt_os2
    Hybrid multi-process, multi-threaded MPM for OS/2
    +
    perchild
    Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    +
    prefork
    ¥¹¥ì¥Ã¥É¤ò»È¤ï¤º¡¢Àè¹Ô¤·¤Æ fork ¤ò¹Ô¤Ê¤¦¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼ÂÁõ +
    +
    threadpool
    Yet another experimental variant of the standard +worker MPM
    +
    mpm_winnt
    Windows NT +¸þ¤±¤ËºÇŬ²½¤µ¤ì¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë
    +
    worker
    ¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤È¥Þ¥ë¥Á¥×¥í¥»¥¹¤Î¥Ï¥¤¥Ö¥ê¥Ã¥É·¿ +¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼ÂÁõ¤·¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë
    +
    +
    top
    +

    ¾¤Î¥â¥¸¥å¡¼¥ë

    +

     A  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V 

    +
    mod_actions
    ¥á¥Ç¥£¥¢¥¿¥¤¥×¤ä¥ê¥¯¥¨¥¹¥È¥á¥½¥Ã¥É¤Ë±þ¤¸¤Æ +CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ëµ¡Ç½¤òÄó¶¡
    +
    mod_alias
    ¥Û¥¹¥È¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¤¤¤í¤¤¤í¤Ê°ã¤¦¾ì½ê¤ò + ¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Ë¥Þ¥Ã¥×¤¹¤ëµ¡Ç½¤È¡¢ + URL ¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò¹Ô¤Ê¤¦µ¡Ç½¤òÄ󶡤¹¤ë
    +
    mod_asis
    ¼«Ê¬ÍѤΠHTTP ¥Ø¥Ã¥À¤Î½ñ¤«¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤òÁ÷¿®¤¹¤ë
    +
    mod_auth_basic
    ´ðËÜǧ¾Ú
    +
    mod_auth_digest
    User authentication using MD5 + Digest Authentication.
    +
    mod_authn_alias
    Provides the ability to create extended authentication + providers based on actual providers
    +
    mod_authn_anon
    ǧ¾Ú¤¬É¬ÍפÊÎΰè¤Ø¤Î "anonymous" ¥æ¡¼¥¶¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë +
    +
    mod_authn_dbm
    DBM ¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥æ¡¼¥¶Ç§¾Ú
    +
    mod_authn_default
    ǧ¾Ú¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥â¥¸¥å¡¼¥ë
    +
    mod_authn_file
    ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥æ¡¼¥¶Ç§¾Ú
    +
    mod_authnz_ldap
    Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    +
    mod_authz_dbm
    Group authorization using DBM files
    +
    mod_authz_default
    ¾µÇ§¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥â¥¸¥å¡¼¥ë
    +
    mod_authz_groupfile
    ¥×¥ì¡¼¥ó¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥°¥ë¡¼¥×¾µÇ§
    +
    mod_authz_host
    ¥Û¥¹¥È (̾Á°¤â¤·¤¯¤Ï IP ¥¢¥É¥ì¥¹) ¤Ë´ð¤Å¤¤¤¿¥°¥ë¡¼¥×¾µÇ§
    +
    mod_authz_owner
    ¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤Ë´ð¤Å¤¤¤¿¾µÇ§
    +
    mod_authz_user
    ¥æ¡¼¥¶¾µÇ§
    +
    mod_autoindex
    Unix ¤Î ls ¥³¥Þ¥ó¥É¤ä + Win32 ¤Î dir ¥·¥§¥ë¥³¥Þ¥ó¥É¤Ë»÷¤¿ + ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀ¸À®¤¹¤ë
    +
    mod_cache
    URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å
    +
    mod_cern_meta
    CERN httpd metafile semantics
    +
    mod_cgi
    CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
    +
    mod_cgid
    ³°Éô CGI ¥Ç¡¼¥â¥ó¤ò»È¤Ã¤¿ CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
    +
    mod_charset_lite
    Specify character set translation or recoding
    +
    mod_dav
    ʬ»¶¥ª¡¼¥µ¥ê¥ó¥°¤È¥Ð¡¼¥¸¥ç¥ó´ÉÍý +(WebDAV) µ¡Ç½
    +
    mod_dav_fs
    mod_dav ¤Î¤¿¤á¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥×¥í¥Ð¥¤¥À
    +
    mod_dav_lock
    mod_dav ÍѤÎÈÆÍÑ¥í¥Ã¥¯¥â¥¸¥å¡¼¥ë
    +
    mod_dbd
    Manages SQL database connections
    +
    mod_deflate
    ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤é¤ì¤ëÁ°¤Ë¥³¥ó¥Æ¥ó¥Ä¤ò°µ½Ì¤¹¤ë
    +
    mod_dir
    ¡ÖºÇ¸å¤Î¥¹¥é¥Ã¥·¥å¡×¤Î¥ê¥À¥¤¥ì¥¯¥È¤È¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Î +¥¤¥ó¥Ç¥Ã¥¯¥¹¥Õ¥¡¥¤¥ë¤ò°·¤¦µ¡Ç½¤òÄ󶡤¹¤ë
    +
    mod_disk_cache
    URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¥­¥ã¥Ã¥·¥å¥¹¥È¥ì¡¼¥¸´ÉÍý
    +
    mod_dumpio
    ˾¤à¤è¤¦¤Ë¤¹¤Ù¤Æ¤Î I/O ¤ò¥¨¥é¡¼¥í¥°¤Ë¥À¥ó¥×¤¹¤ë
    +
    mod_echo
    ¥×¥í¥È¥³¥ë¥â¥¸¥å¡¼¥ë¤Î³µÍפò¼¨¤¹¤¿¤á¤Îñ½ã¤Ê¥¨¥³¡¼¥µ¡¼¥Ð +
    +
    mod_env
    CGI ¥¹¥¯¥ê¥×¥ÈµÚ¤Ó SSI +¥Ú¡¼¥¸¤ËÅϤµ¤ì¤ë´Ä¶­ÊÑ¿ô¤òÊѹ¹¤¹¤ëµ¡Ç½¤òÄ󶡤¹¤ë
    +
    mod_example
    Illustrates the Apache module API
    +
    mod_expires
    ¥æ¡¼¥¶¤Î»ØÄꤷ¤¿´ð½à¤Ë´ð¤Å¤¤¤¿ Expires ¤È +Cache-Control HTTP ¥Ø¥Ã¥À¤ÎÀ¸À®
    +
    mod_ext_filter
    ¥ì¥¹¥Ý¥ó¥¹¤Î¥Ü¥Ç¥£¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ëÁ°¤Ë³°Éô¥×¥í¥°¥é¥à¤Ç½èÍý¤¹¤ë
    +
    mod_file_cache
    Caches a static list of files in memory
    +
    mod_filter
    Context-sensitive smart filter configuration module
    +
    mod_headers
    HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤È±þÅú¤Î¥Ø¥Ã¥À¤Î¥«¥¹¥¿¥Þ¥¤¥º
    +
    mod_ident
    RFC 1413 ident lookups
    +
    mod_imagemap
    Server-side imagemap processing
    +
    mod_include
    ¥µ¡¼¥Ð¤¬¥Ñ¡¼¥¹¤¹¤ë html ¥É¥­¥å¥á¥ó¥È (Server Side Includes)
    +
    mod_info
    ¥µ¡¼¥Ð¤ÎÀßÄê¤ÎÊñ³çŪ¤Ê³µ´Ñ¤òÄ󶡤¹¤ë
    +
    mod_isapi
    ISAPI Extensions within Apache for Windows
    +
    mod_ldap
    LDAP connection pooling and result caching services for use +by other LDAP modules
    +
    mod_log_config
    ¥µ¡¼¥Ð¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Î¥í¥®¥ó¥°
    +
    mod_log_forensic
    ¥µ¡¼¥Ð¤ËÁ÷¤é¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î forensic ¥í¥®¥ó¥°
    +
    mod_logio
    ¥ê¥¯¥¨¥¹¥ÈËè¤ËÆþÎϥХ¤¥È¿ô¤È½ÐÎϥХ¤¥È¿ô¤È¤ò¥í¥®¥ó¥°
    +
    mod_mem_cache
    URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å
    +
    mod_mime
    ¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤È¥Õ¥¡¥¤¥ë¤Î¿¶¤ëÉñ¤¤ + (¥Ï¥ó¥É¥é¤È¥Õ¥£¥ë¥¿)¡¢ÆâÍÆ (MIME ¥¿¥¤¥×¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°) + ¤È¤ò´ØÏ¢ÉÕ¤±¤ë
    +
    mod_mime_magic
    Determines the MIME type of a file + by looking at a few bytes of its contents
    +
    mod_negotiation
    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + µ¡Ç½¤òÄ󶡤¹¤ë
    +
    mod_nw_ssl
    Enable SSL encryption for NetWare
    +
    mod_proxy
    HTTP/1.1 ¥×¥í¥­¥·/¥²¡¼¥È¥¦¥§¥¤¥µ¡¼¥Ð
    +
    mod_proxy_ajp
    mod_proxy ¤Ç AJP +¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¤Î¥â¥¸¥å¡¼¥ë
    +
    mod_proxy_balancer
    Éé²Ùʬ»¶¤Î¤¿¤á¤Î mod_proxy ³ÈÄ¥
    +
    mod_proxy_connect
    mod_proxy extension for +CONNECT request handling
    +
    mod_proxy_ftp
    FTP support module for +mod_proxy
    +
    mod_proxy_http
    HTTP support module for +mod_proxy
    +
    mod_rewrite
    Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    +
    mod_setenvif
    ¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤Ë´ð¤Å¤¤¤¿´Ä¶­ÊÑ¿ô¤ÎÀßÄê¤ò²Äǽ¤Ë¤¹¤ë
    +
    mod_so
    µ¯Æ°»þ¤äºÆµ¯Æ°»þ¤Ë¼Â¹Ô¥³¡¼¥É¤È¥â¥¸¥å¡¼¥ë¤ò¥µ¡¼¥Ð¤Ë¥í¡¼¥É¤¹¤ë +
    +
    mod_speling
    ¥æ¡¼¥¶¤¬ÆþÎϤ·¤¿¤Ç¤¢¤í¤¦´Ö°ã¤Ã¤¿ URL ¤ò¡¢ +Âçʸ»ú¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤¹¤ë¤³¤È¤È°ì¤Ä°Ê²¼¤ÎÄÖ¤ê´Ö°ã¤¤¤òµöÍƤ¹¤ë¤³¤È¤Ç +½¤Àµ¤ò»î¤ß¤ë
    +
    mod_ssl
    Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    +
    mod_status
    ¥µ¡¼¥Ð¤Î³èÆ°¾õ¶·¤ÈÀ­Ç½¤Ë´Ø¤¹¤ë¾ðÊó¤òÄ󶡤¹¤ë
    +
    mod_suexec
    »ØÄꤵ¤ì¤¿¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤Ç CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë
    +
    mod_unique_id
    ¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë°ì°Õ¤Ê¼±Ê̻ҤÎÆþ¤Ã¤¿´Ä¶­ÊÑ¿ô¤ò +Ä󶡤¹¤ë
    +
    mod_userdir
    ¥æ¡¼¥¶ÀìÍѤΥǥ£¥ì¥¯¥È¥ê¤òÄó¶¡ +
    +
    mod_usertrack
    +Clickstream logging of user activity on a site +
    +
    mod_version
    ¥Ð¡¼¥¸¥ç¥ó°Í¸¤ÎÀßÄê
    +
    mod_vhost_alias
    Provides for dynamically configured mass virtual +hosting
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/index.html.ko.euc-kr b/trunk/docs/manual/mod/index.html.ko.euc-kr new file mode 100644 index 0000000000..e2b9e33f51 --- /dev/null +++ b/trunk/docs/manual/mod/index.html.ko.euc-kr @@ -0,0 +1,177 @@ + + + +¸ðµâ ¸ñ·Ï - Apache HTTP Server + + + + + +
    <-
    +

    ¸ðµâ ¸ñ·Ï

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    + ´ÙÀ½Àº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ ¸ðµç ¸ðµâ ¸ñ·ÏÀÌ´Ù. ¸ðµç ¾ÆÆÄÄ¡ Áö½Ã¾î ¸ñ·Ïµµ + Âü°íÇ϶ó. +

    +
    + +
    top
    +

    ÇÙ½É ±â´É°ú ´ÙÁßó¸® ¸ðµâ

    +
    +
    core
    Core Apache HTTP Server features that are always +available
    +
    mpm_common
    A collection of directives that are implemented by +more than one multi-processing module (MPM)
    +
    beos
    BeOS¿¡ ÃÖÀûÈ­µÈ ´ÙÁßó¸® ¸ðµâ.
    +
    event
    An experimental variant of the standard worker +MPM
    +
    leader
    Ç¥ÁØ worker MPMÀÇ ½ÇÇèÀûÀÎ º¯Çü
    +
    mpm_netware
    Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    +
    mpmt_os2
    Hybrid multi-process, multi-threaded MPM for OS/2
    +
    perchild
    Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    +
    prefork
    Implements a non-threaded, pre-forking web server
    +
    threadpool
    Yet another experimental variant of the standard +worker MPM
    +
    mpm_winnt
    This Multi-Processing Module is optimized for Windows +NT.
    +
    worker
    Multi-Processing Module implementing a hybrid + multi-threaded multi-process web server
    +
    +
    top
    +

    ´Ù¸¥ ¸ðµâ

    +

     A  |  C  |  D  |  E  |  F  |  H  |  I  |  L  |  M  |  N  |  P  |  R  |  S  |  U  |  V 

    +
    mod_actions
    ÀÌ ¸ðµâÀº ¹Ìµð¾îÁ¾·ù³ª ¿äû¸Þ¼­µå¿¡ µû¶ó CGI +½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù.
    +
    mod_alias
    ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐµéÀ» ¹®¼­ °èÃþ±¸Á¶¿¡ Æ÷ÇÔÇÏ°í, + URL ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÑ´Ù
    +
    mod_asis
    HTTP Çì´õ¸¦ Æ÷ÇÔÇÑ ÆÄÀÏÀ» º¸³½´Ù
    +
    mod_auth_basic
    Basic authentication
    +
    mod_auth_digest
    MD5 Digest AuthenticationÀ» »ç¿ëÇÑ »ç¿ëÀÚÀÎÁõ.
    +
    mod_authn_alias
    Provides the ability to create extended authentication + providers based on actual providers
    +
    mod_authn_anon
    ÀÎÁõ¿µ¿ª¿¡ "À͸í(anonymous)" »ç¿ëÀÚÀÇ Á¢±ÙÀ» +Çã¿ëÇÑ´Ù
    +
    mod_authn_dbm
    DBM ÆÄÀÏÀ» »ç¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ
    +
    mod_authn_default
    ÃÖÈÄ ÀÎÁõ¸ðµâ
    +
    mod_authn_file
    ¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ
    +
    mod_authnz_ldap
    Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    +
    mod_authz_dbm
    DBM ÆÄÀÏÀ» »ç¿ëÇÑ ±×·ì ÀÎÁõ
    +
    mod_authz_default
    ÃÖÈÄ ±ÇÇѺο©¸ðµâ
    +
    mod_authz_groupfile
    ÀÏ¹Ý ¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ ±×·ì ±ÇÇѺο©
    +
    mod_authz_host
    È£½ºÆ® (À̸§À̳ª IP ÁÖ¼Ò)¸¦ »ç¿ëÇÑ ±×·ì ±ÇÇѺο©
    +
    mod_authz_owner
    ÆÄÀÏ ¼ÒÀ¯ÀÚ¸¦ ÀÌ¿ëÇÑ ±ÇÇѺο©
    +
    mod_authz_user
    »ç¿ëÀÚ ±ÇÇѺο©
    +
    mod_autoindex
    ÀÚµ¿À¸·Î À¯´Ð½ºÀÇ ls ¸í·É¾î³ª Win32ÀÇ + dir ½©¸í·É¾î¿Í À¯»çÇÑ µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù
    +
    mod_cache
    URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù.
    +
    mod_cern_meta
    CERN À¥¼­¹ö ¸ÞŸÆÄÀÏ Áö¿ø
    +
    mod_cgi
    CGI ½ºÅ©¸³Æ® ½ÇÇà
    +
    mod_cgid
    ¿ÜºÎ CGI µ¥¸óÀ» »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇà
    +
    mod_charset_lite
    ¹®ÀÚÁýÇÕ º¯È¯À» ÁöÁ¤
    +
    mod_dav
    Distributed Authoring and Versioning +(WebDAV) ±â´É
    +
    mod_dav_fs
    mod_davÀ» À§ÇÑ ÆÄÀϽýºÅÛ Á¦°øÀÚ
    +
    mod_dav_lock
    generic locking module for mod_dav
    +
    mod_dbd
    Manages SQL database connections
    +
    mod_deflate
    ³»¿ëÀ» Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ ¾ÐÃàÇÑ´Ù
    +
    mod_dir
    "¸¶Áö¸· ½½·¡½¬" ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÏ°í µð·ºÅ丮 +index ÆÄÀÏÀ» ¼­ºñ½ºÇÑ´Ù
    +
    mod_disk_cache
    Content cache storage manager keyed to URIs
    +
    mod_dumpio
    Dumps all I/O to error log as desired.
    +
    mod_echo
    ÇÁ·ÎÅäÄÝ ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇÑ °£´ÜÇÑ echo ¼­¹ö
    +
    mod_env
    CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ +¼öÁ¤ÇÑ´Ù
    +
    mod_example
    ¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇÑ´Ù
    +
    mod_expires
    »ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ ±âÁØ¿¡ µû¶ó Expires¿Í +Cache-Control HTTP Çì´õ¸¦ »ý¼ºÇÑ´Ù
    +
    mod_ext_filter
    ÀÀ´ä ³»¿ëÀ» ¿ÜºÎ ÇÁ·Î±×·¥À¸·Î ó¸®ÇÑ ÈÄ Å¬¶óÀ̾ðÆ®·Î +º¸³½´Ù
    +
    mod_file_cache
    ¸Þ¸ð¸®¿¡ Á¤Àû ÆÄÀϵéÀ» ij½¬
    +
    mod_filter
    Context-sensitive smart filter configuration module
    +
    mod_headers
    HTTP ¿äû Çì´õ¿Í ÀÀ´ä Çì´õ ¼öÁ¤
    +
    mod_ident
    RFC 1413 ident °Ë»ö
    +
    mod_imap
    ¼­¹öÃø À̹ÌÁö¸Ê(imagemap) ó¸®
    +
    mod_include
    Server-parsed html documents (Server Side Includes)
    +
    mod_info
    ¼­¹ö ¼³Á¤¿¡ ´ëÇÑ Á¾ÇÕÀûÀÎ Á¤º¸¸¦ º¸¿©ÁØ´Ù
    +
    mod_isapi
    Windows¿ë ¾ÆÆÄÄ¡¿¡¼­ ISAPI Extension »ç¿ë
    +
    mod_ldap
    LDAP connection pooling and result caching services for use +by other LDAP modules
    +
    mod_log_config
    ¼­¹ö·ÎÀÇ ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    +
    mod_log_forensic
    Forensic Logging of the requests made to the server
    +
    mod_logio
    ¿äû´ç ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·Ï
    +
    mod_mem_cache
    URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù.
    +
    mod_mime
    Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding)
    +
    mod_mime_magic
    Determines the MIME type of a file + by looking at a few bytes of its contents
    +
    mod_negotiation
    Provides for content negotiation
    +
    mod_nw_ssl
    Enable SSL encryption for NetWare
    +
    mod_proxy
    HTTP/1.1 proxy/gateway server
    +
    mod_proxy_ajp
    AJP support module for +mod_proxy
    +
    mod_proxy_balancer
    mod_proxy extension for load balancing
    +
    mod_proxy_connect
    mod_proxy extension for +CONNECT request handling
    +
    mod_proxy_ftp
    FTP support module for +mod_proxy
    +
    mod_proxy_http
    HTTP support module for +mod_proxy
    +
    mod_rewrite
    Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    +
    mod_setenvif
    ¿äûÀÇ ¼º°Ý¿¡ µû¶ó ȯ°æº¯¼ö ¼³Á¤À» º¯°æÇÑ´Ù
    +
    mod_so
    ½ÃÀÛÇÒ¶§ ȤÀº Àç½ÃÀÛÇÒ¶§ ½ÇÇà°¡´ÉÇÑ ÄÚµå¿Í ¸ðµâÀ» +¼­¹ö·Î ÀоîµéÀδÙ
    +
    mod_speling
    »ç¿ëÀÚ°¡ ´ë¼Ò¹®ÀÚ¸¦ À߸ø »ç¿ëÇϰųª ¸ÂÃã¹ýÀÌ Æ²¸®´Â +°ÍÀ» Çѹø±îÁö Çã¿ëÇÏ¿© À߸øµÈ URLÀ» °íÄ¡·Á°í ½ÃµµÇÑ´Ù
    +
    mod_ssl
    Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    +
    mod_status
    ¼­¹ö È°µ¿°ú ¼º´É¿¡ ´ëÇÑ Á¤º¸¸¦ Á¦°øÇÑ´Ù
    +
    mod_suexec
    CGI ½ºÅ©¸³Æ®¸¦ ƯÁ¤ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑÀ¸·Î ½ÇÇàÇÑ´Ù
    +
    mod_unique_id
    °¢ ¿äû¸¶´Ù À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ °¡Áö´Â ȯ°æº¯¼ö¸¦ +Á¦°øÇÑ´Ù
    +
    mod_userdir
    »ç¿ëÀÚº° µð·ºÅ丮
    +
    mod_usertrack
    +Clickstream logging of user activity on a site +
    +
    mod_version
    ¹öÀüº° ¼³Á¤
    +
    mod_vhost_alias
    Provides for dynamically configured mass virtual +hosting
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/index.xml b/trunk/docs/manual/mod/index.xml new file mode 100644 index 0000000000..ba22a592b1 --- /dev/null +++ b/trunk/docs/manual/mod/index.xml @@ -0,0 +1,37 @@ + + + + + + + + + Module Index + +

    + Below is a list of all of the modules that come as part of + the Apache distribution. See also the complete + alphabetical list of all Apache + directives. +

    +
    + Multi-Processing Modules (MPMs) + + Directive Quick Reference + +
    diff --git a/trunk/docs/manual/mod/index.xml.de b/trunk/docs/manual/mod/index.xml.de new file mode 100644 index 0000000000..dccb899012 --- /dev/null +++ b/trunk/docs/manual/mod/index.xml.de @@ -0,0 +1,37 @@ + + + + + + + + + Modul-Index + +

    + Unten ist eine Liste aller Module angegeben, die als Bestandteil der + Apache-Distribution mitgeliefert werden. Bitte beachten Sie auch die + vollständige alphabetische Liste aller + Apache-Direktiven. +

    +
    + Multi-Processing-Module (MPMs) + + Kurzreferenz der Direktiven + +
    diff --git a/trunk/docs/manual/mod/index.xml.es b/trunk/docs/manual/mod/index.xml.es new file mode 100644 index 0000000000..cd8b22db53 --- /dev/null +++ b/trunk/docs/manual/mod/index.xml.es @@ -0,0 +1,41 @@ + + + + + + + + + + Índice de Módulos + +

    + Abajo se muestra una lista con todos los módulos que forman + parte de la distribución de Apache. Consulte también la lista + alfabética completa de las + directivas de Apache. +

    +
    + Módulos de MultiProcesamiento + (MPMs) + + Guía Rápida de Referencia de + Directivas + +
    + diff --git a/trunk/docs/manual/mod/index.xml.ja b/trunk/docs/manual/mod/index.xml.ja new file mode 100644 index 0000000000..d493d2c04e --- /dev/null +++ b/trunk/docs/manual/mod/index.xml.ja @@ -0,0 +1,36 @@ + + + + + + + + + $B%b%8%e!<%k0lMw(B + +

    + $B0J2<$O(B Apache $B$NG[I[$N0lIt$H$7$FG[$i$l$F$$$k$9$Y$F$N%b%8%e!<%k$N(B + $B0lMw$G$9!#$9$Y$F$N(B Apache + $B%G%#%l%/%F%#%V(B $B$N%"%k%U%!%Y%C%H=g$N%j%9%H$b8+$F$/$@$5$$!#(B +

    +
    + $B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPMs) + + $B%G%#%l%/%F%#%V(B $B%/%$%C%/%j%U%!%l%s%9(B + +
    diff --git a/trunk/docs/manual/mod/index.xml.ko b/trunk/docs/manual/mod/index.xml.ko new file mode 100644 index 0000000000..9b35f2a507 --- /dev/null +++ b/trunk/docs/manual/mod/index.xml.ko @@ -0,0 +1,36 @@ + + + + + + + + + ¸ðµâ ¸ñ·Ï + +

    + ´ÙÀ½Àº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ ¸ðµç ¸ðµâ ¸ñ·ÏÀÌ´Ù. ¸ðµç ¾ÆÆÄÄ¡ Áö½Ã¾î ¸ñ·Ïµµ + Âü°íÇ϶ó. +

    +
    + ´ÙÁß󸮸ðµâ (MPM) + + Áö½Ã¾î ºü¸¥Âü°í + +
    diff --git a/trunk/docs/manual/mod/index.xml.meta b/trunk/docs/manual/mod/index.xml.meta new file mode 100644 index 0000000000..cfaaf6c2c2 --- /dev/null +++ b/trunk/docs/manual/mod/index.xml.meta @@ -0,0 +1,15 @@ + + + + index + /mod/ + .. + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/mod/leader.html b/trunk/docs/manual/mod/leader.html new file mode 100644 index 0000000000..05175a8004 --- /dev/null +++ b/trunk/docs/manual/mod/leader.html @@ -0,0 +1,11 @@ +URI: leader.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: leader.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: leader.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/leader.html.de b/trunk/docs/manual/mod/leader.html.de new file mode 100644 index 0000000000..1eb3673714 --- /dev/null +++ b/trunk/docs/manual/mod/leader.html.de @@ -0,0 +1,94 @@ + + + +leader - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-MPM leader

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ko 

    +
    + + + +
    Beschreibung:Eine experimentelle Variante des Standard-MPMs + worker
    Status:MPM
    Modulbezeichner:mpm_leader_module
    Quelltext-Datei:leader.c
    +

    Zusammenfassung

    + +

    Warnung

    +

    Dieses MPM ist noch experimentell und funktioniert möglicherweise + nicht wie erwartet.

    +
    + +

    Dies ist eine experimentelle Variante des Standard-MPMs + worker. Das Modul verwendet ein + Leader/Followers-Design-Pattern, um die Arbeit zwischen Threads zu + koordinieren. Weitere Informationen finden Sie unter http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf.

    + +

    Um bei der Erstellung des httpd das MPM + leader zu verwenden, fügen Sie den Argumenten + des configure-Skripts --with-mpm=leader + hinzu.

    + +

    Dieses MPM baut auf den atomaren APR-Vergleichs- und -Tauschoperationen + für die Thread-Synchronisation auf. Wenn Sie für einen + x86-Rechner kompilieren, ohne dass 386-Unterstützung benötigt + wird, oder wenn Sie für einen SPARC-Rechner kompilieren und keine + pre-UltraSPARC-Chips betreiben müssen, fügen Sie den Argumenten + des configure-Skripts + --enable-nonportable-atomics=yes hinzu. Dies veranlasst die + APR veranlasst dazu, atomare Operationen einzusetzen, welche effizienten + Befehlscode verwenden, der älteren CPUs nicht zur Verfügung + stehen.

    +
    + + +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/leader.html.en b/trunk/docs/manual/mod/leader.html.en new file mode 100644 index 0000000000..15eadece14 --- /dev/null +++ b/trunk/docs/manual/mod/leader.html.en @@ -0,0 +1,91 @@ + + + +leader - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM leader

    +
    +

    Available Languages:  de  | + en  | + ko 

    +
    + + + +
    Description:An experimental variant of the standard worker +MPM
    Status:MPM
    Module Identifier:mpm_leader_module
    Source File:leader.c
    +

    Summary

    + +

    Warning

    +

    This MPM is experimental, so it may or may not work + as expected.

    +
    + +

    This is an experimental variant of the standard + worker MPM. It uses a Leader/Followers design pattern + to coordinate work among threads. For more info, see http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf.

    + +

    To use the leader MPM, add + --with-mpm=leader to the configure + script's arguments when building the httpd.

    + +

    This MPM depends on APR's atomic compare-and-swap operations for + thread synchronization. If you are compiling for an x86 target + and you don't need to support 386s, or you are compiling for a + SPARC and you don't need to run on pre-UltraSPARC chips, add + --enable-nonportable-atomics=yes to the + configure script's arguments. This will cause + APR to implement atomic operations + using efficient opcodes not available in older CPUs.

    +
    + + +
    +
    +

    Available Languages:  de  | + en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/leader.html.ko.euc-kr b/trunk/docs/manual/mod/leader.html.ko.euc-kr new file mode 100644 index 0000000000..ab377b93ea --- /dev/null +++ b/trunk/docs/manual/mod/leader.html.ko.euc-kr @@ -0,0 +1,91 @@ + + + +leader - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ MPM leader

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:Ç¥ÁØ worker MPMÀÇ ½ÇÇèÀûÀÎ º¯Çü
    »óÅÂ:MPM
    ¸ðµâ¸í:mpm_leader_module
    ¼Ò½ºÆÄÀÏ:leader.c
    +

    ¿ä¾à

    + +

    ÁÖÀÇ

    +

    ÀÌ MPMÀº ½ÇÇèÀûÀÎ »óÅ·Î, ±â´ëÇÑ´ë·Î µ¿ÀÛÇÏÁö¾ÊÀ» ¼ö ÀÖ´Ù.

    +
    + +

    ÀÌ ¸ðµâÀº Ç¥ÁØ worker MPMÀÇ ½ÇÇèÀûÀÎ + º¯ÇüÀÌ´Ù. ÀÌ ¸ðµâÀº ¾²·¹µå°£ÀÇ Çùµ¿À» À§ÇØ Leader/Followers + µðÀÚÀÎÆÐÅÏÀ» »ç¿ëÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf¸¦ Âü°íÇ϶ó.

    + +

    leader MPMÀ» »ç¿ëÇÏ·Á¸é, + httpd¸¦ ÄÄÆÄÀÏÇÒ¶§ configure + ½ºÅ©¸³Æ® ¾Æ±Ô¸ÕÆ®¿¡ --with-mpm=leader¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ÀÌ MPMÀº ¾²·¹µå µ¿±â¸¦ À§ÇØ APRÀÇ atomic compare-and-swap + ¸í·ÉÀ» »ç¿ëÇÑ´Ù. x86¿ëÀ¸·Î ÄÄÆÄÀÏÇÏÁö¸¸ 386À» Áö¿øÇÒ ÇÊ¿ä°¡ + ¾ø°Å³ª, SPARC¿ëÀ¸·Î ÄÄÆÄÀÏÇÏÁö¸¸ UltraSPARC Ĩ ÀÌÀü¿¡¼­ + ½ÇÇàÇÏÁö ¾Ê´Â´Ù¸é, configure ½ºÅ©¸³Æ® ¾Æ±Ô¸ÕÆ®¿¡ + --enable-nonportable-atomics=yes¸¦ »ç¿ëÇ϶ó. + ±×·¯¸é APRÀÌ ¿À·¡µÈ CPU¿¡´Â ¾ø´Â ´õ È¿À²ÀûÀÎ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© + atomic ¸í·ÉÀ» ±¸ÇöÇÑ´Ù.

    +
    + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/leader.xml b/trunk/docs/manual/mod/leader.xml new file mode 100644 index 0000000000..4224f5ea2a --- /dev/null +++ b/trunk/docs/manual/mod/leader.xml @@ -0,0 +1,100 @@ + + + + + + + + +leader +An experimental variant of the standard worker +MPM +MPM +leader.c +mpm_leader_module + + + Warning +

    This MPM is experimental, so it may or may not work + as expected.

    +
    + +

    This is an experimental variant of the standard + worker MPM. It uses a Leader/Followers design pattern + to coordinate work among threads. For more info, see http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf.

    + +

    To use the leader MPM, add + --with-mpm=leader to the configure + script's arguments when building the httpd.

    + +

    This MPM depends on APR's atomic compare-and-swap operations for + thread synchronization. If you are compiling for an x86 target + and you don't need to support 386s, or you are compiling for a + SPARC and you don't need to run on pre-UltraSPARC chips, add + --enable-nonportable-atomics=yes to the + configure script's arguments. This will cause + APR to implement atomic operations + using efficient opcodes not available in older CPUs.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +SendBufferSize + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +ScoreBoardFile + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/leader.xml.de b/trunk/docs/manual/mod/leader.xml.de new file mode 100644 index 0000000000..7201b4a90b --- /dev/null +++ b/trunk/docs/manual/mod/leader.xml.de @@ -0,0 +1,102 @@ + + + + + + + + +leader +Eine experimentelle Variante des Standard-MPMs + worker +MPM +leader.c +mpm_leader_module + + + Warnung +

    Dieses MPM ist noch experimentell und funktioniert möglicherweise + nicht wie erwartet.

    +
    + +

    Dies ist eine experimentelle Variante des Standard-MPMs + worker. Das Modul verwendet ein + Leader/Followers-Design-Pattern, um die Arbeit zwischen Threads zu + koordinieren. Weitere Informationen finden Sie unter http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf.

    + +

    Um bei der Erstellung des httpd das MPM + leader zu verwenden, fügen Sie den Argumenten + des configure-Skripts --with-mpm=leader + hinzu.

    + +

    Dieses MPM baut auf den atomaren APR-Vergleichs- und -Tauschoperationen + für die Thread-Synchronisation auf. Wenn Sie für einen + x86-Rechner kompilieren, ohne dass 386-Unterstützung benötigt + wird, oder wenn Sie für einen SPARC-Rechner kompilieren und keine + pre-UltraSPARC-Chips betreiben müssen, fügen Sie den Argumenten + des configure-Skripts + --enable-nonportable-atomics=yes hinzu. Dies veranlasst die + APR veranlasst dazu, atomare Operationen einzusetzen, welche effizienten + Befehlscode verwenden, der älteren CPUs nicht zur Verfügung + stehen.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +SendBufferSize + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +ScoreBoardFile + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +User + + +
    diff --git a/trunk/docs/manual/mod/leader.xml.ko b/trunk/docs/manual/mod/leader.xml.ko new file mode 100644 index 0000000000..398eb0c429 --- /dev/null +++ b/trunk/docs/manual/mod/leader.xml.ko @@ -0,0 +1,98 @@ + + + + + + + + +leader +Ç¥ÁØ worker MPMÀÇ ½ÇÇèÀûÀÎ º¯Çü +MPM +leader.c +mpm_leader_module + + + ÁÖÀÇ +

    ÀÌ MPMÀº ½ÇÇèÀûÀÎ »óÅ·Î, ±â´ëÇÑ´ë·Î µ¿ÀÛÇÏÁö¾ÊÀ» ¼ö ÀÖ´Ù.

    +
    + +

    ÀÌ ¸ðµâÀº Ç¥ÁØ worker MPMÀÇ ½ÇÇèÀûÀÎ + º¯ÇüÀÌ´Ù. ÀÌ ¸ðµâÀº ¾²·¹µå°£ÀÇ Çùµ¿À» À§ÇØ Leader/Followers + µðÀÚÀÎÆÐÅÏÀ» »ç¿ëÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf¸¦ Âü°íÇ϶ó.

    + +

    leader MPMÀ» »ç¿ëÇÏ·Á¸é, + httpd¸¦ ÄÄÆÄÀÏÇÒ¶§ configure + ½ºÅ©¸³Æ® ¾Æ±Ô¸ÕÆ®¿¡ --with-mpm=leader¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ÀÌ MPMÀº ¾²·¹µå µ¿±â¸¦ À§ÇØ APRÀÇ atomic compare-and-swap + ¸í·ÉÀ» »ç¿ëÇÑ´Ù. x86¿ëÀ¸·Î ÄÄÆÄÀÏÇÏÁö¸¸ 386À» Áö¿øÇÒ ÇÊ¿ä°¡ + ¾ø°Å³ª, SPARC¿ëÀ¸·Î ÄÄÆÄÀÏÇÏÁö¸¸ UltraSPARC Ĩ ÀÌÀü¿¡¼­ + ½ÇÇàÇÏÁö ¾Ê´Â´Ù¸é, configure ½ºÅ©¸³Æ® ¾Æ±Ô¸ÕÆ®¿¡ + --enable-nonportable-atomics=yes¸¦ »ç¿ëÇ϶ó. + ±×·¯¸é APRÀÌ ¿À·¡µÈ CPU¿¡´Â ¾ø´Â ´õ È¿À²ÀûÀÎ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© + atomic ¸í·ÉÀ» ±¸ÇöÇÑ´Ù.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +SendBufferSize + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +ScoreBoardFile + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/leader.xml.meta b/trunk/docs/manual/mod/leader.xml.meta new file mode 100644 index 0000000000..48428c2130 --- /dev/null +++ b/trunk/docs/manual/mod/leader.xml.meta @@ -0,0 +1,13 @@ + + + + leader + /mod/ + .. + + + de + en + ko + + diff --git a/trunk/docs/manual/mod/mod_actions.html b/trunk/docs/manual/mod/mod_actions.html new file mode 100644 index 0000000000..8b9470135e --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.html @@ -0,0 +1,15 @@ +URI: mod_actions.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_actions.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_actions.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_actions.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_actions.html.de b/trunk/docs/manual/mod/mod_actions.html.de new file mode 100644 index 0000000000..340810fd33 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.html.de @@ -0,0 +1,168 @@ + + + +mod_actions - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-Modul mod_actions

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + + + +
    Beschreibung:Dieses Modul ermöglicht die Ausführung von CGI-Skripten + in Abhängigkeit von Medientypen und Anfragemethoden.
    Status:Base
    Modulbezeichner:actions_module
    Quelltext-Datei:mod_actions.c
    +

    Zusammenfassung

    + +

    Das Modul besitzt zwei Direktiven. Die Direktive Action erlaubt die Ausführung von + CGI-Skripten immer dann, wenn eine Anfrage zu einem bestimmten MIME-Type + erfolgt. Die Direktive Script + erlaubt die Ausführung von CGI-Skripten abhängig von einer + bestimmten Methode, die in der Anfrage verwendet wird. Dies macht es + deutlich einfacher, Skripte auszuführen, die Dateien + verarbeiten.

    +
    + + +
    top
    +

    Action-Direktive

    + + + + + + + + +
    Beschreibung:Aktiviert ein CGI-Skript für einen bestimmten Handler oder + Content-Type
    Syntax:Action Aktionsart CGI-Skript [virtual]
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis, .htaccess
    AllowOverride:FileInfo
    Status:Base
    Modul:mod_actions
    Kompatibilität:Der Schalter virtual und die Übergabe des + Handlers wurden in Apache 2.1 eingeführt.
    +

    Die Direktive fügt eine Aktion hinzu, welche das + CGI-Skript aktiviert, sobald die Aktionsart durch + eine Anfrage ausgelöst wird. CGI-Skript ist der URL-Pfad + zu einer Ressource, die unter Verwendung von ScriptAlias oder AddHandler als CGI-Skript gekennzeichnet + wurde. Die Aktionsart kann entweder ein Handler oder ein MIME-Type sein. Die URL und + den Dateipfad des angeforderten Dokuments in den + Standard-CGI-Umgebungsvariablen PATH_INFO und + PATH_TRANSLATED übergeben. Der für die jeweilige + Anfrage verwendete Handler wird in der Umgebungsvariablen + REDIRECT_HANDLER übergeben.

    + +

    Beispiele

    + # Anfragen für Dateien eines bestimmten MIME-Types:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Dateien einer bestimmten Dateiendung
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +

    + +

    Im ersten Beispiel werden Anfragen für Dateien mit dem MIME-Type + image/gif von dem angegebenen CGI-Skript + /cgi-bin/images.cgi bearbeitet.

    + +

    Im zweiten Beispiel werden Anfragen für Dateien mit der Dateiendung + .xyz von dem angegebenen CGI-Skript + /cgi-bin/program.cgi bearbeitet.

    + +

    Der optionale Schalter virtual deaktiviert die Prüfung + auf Existenz der angeforderten Datei. Dies ist beispielsweise + nützlich, wenn Sie die Direktive Action in + Verbindung mit virtuellen Adressräumen verwenden möchten.

    + +

    Beispiel

    + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +

    + +

    Siehe auch

    + +
    +
    top
    +

    Script-Direktive

    + + + + + + +
    Beschreibung:Aktiviert ein CGI-Skript für eine bestimmte + Anfragemethode.
    Syntax:Script Methode CGI-Skript
    Kontext:Serverkonfiguration, Virtual Host, Verzeichnis
    Status:Base
    Modul:mod_actions
    +

    Die Direktive fügt eine Aktion hinzu, welche das + CGI-Skript aktiviert, wenn eine Datei unter der Verwendung der + Methode Methode angefordert wird. CGI-Skript ist der + URL-Pfad zu einer Ressource, die unter Verwendung von ScriptAlias oder AddHandler als CGI-Skript gekennzeichnet + wurde. Die URL und der Dateipfad des angeforderten Dokuments werden in den + Standard-CGI-Umgebungsvariablen PATH_INFO und + PATH_TRANSLATED übergeben.

    + +
    + Der Methodenname kann frei gewählt werden. Bei Methodennamen + wird zwischen Groß- und Kleinschreibung unterschieden, so + dass Script PUT und Script put zu vollkommen + unterschiedlichen Ergebnissen führen. +
    + +

    Beachten Sie, dass der Script-Befehl nur + Voreinstellungen für Aktionen definiert. Wird ein CGI-Skript + - oder eine andere Ressource, die in der Lage ist, die angeforderte + Methode intern zu bearbeiten - aufgerufen, so wird diese(s) verwendet. + Beachten Sie auch, dass Script mit der Methode + GET nur dann aufgerufen wird, wenn Query-Argumente vorhanden + sind (z.B. foo.html?hi). Andernfalls wird die Anfrage normal + bearbeitet.

    + +

    Beispiele

    + # Für <ISINDEX>-ähnliches Suchen
    + Script GET /cgi-bin/search
    +
    + # Ein CGI-PUT-Handler
    + Script PUT /~bob/put.cgi
    +

    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_actions.html.en b/trunk/docs/manual/mod/mod_actions.html.en new file mode 100644 index 0000000000..c198a46f29 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.html.en @@ -0,0 +1,165 @@ + + + +mod_actions - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_actions

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + + + +
    Description:This module provides for executing CGI scripts based on +media type or request method.
    Status:Base
    Module Identifier:actions_module
    Source File:mod_actions.c
    +

    Summary

    + +

    This module has two directives. The Action directive lets you run CGI + scripts whenever a file of a certain MIME content type is requested. The + Script directive lets + you run CGI scripts whenever a particular method is used in a + request. This makes it much easier to execute scripts that process + files.

    +
    + + +
    top
    +

    Action Directive

    + + + + + + + + +
    Description:Activates a CGI script for a particular handler or +content-type
    Syntax:Action action-type cgi-script [virtual]
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_actions
    Compatibility:The virtual modifier and handler passing were +introduced in Apache 2.1
    +

    This directive adds an action, which will activate + cgi-script when action-type is triggered by the + request. The cgi-script is the URL-path to a resource + that has been designated as a CGI script using ScriptAlias or AddHandler. The + action-type can be either a handler or a MIME content type. It + sends the URL and file path of the requested document using the + standard CGI PATH_INFO and PATH_TRANSLATED + environment variables. The handler used for the particular request is + passed using the REDIRECT_HANDLER variable.

    + +

    Examples

    + # Requests for files of a particular MIME content type:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Files of a particular file extension
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +

    + +

    In the first example, requests for files with a MIME content + type of image/gif will be handled by the + specified cgi script /cgi-bin/images.cgi.

    + +

    In the second example, requests for files with a file extension of + .xyz are handled by the specified cgi script + /cgi-bin/program.cgi.

    + +

    The optional virtual modifier turns off the check + whether the requested file really exists. This is useful, for example, + if you want to use the Action directive in + virtual locations.

    + +

    Example

    + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +

    + +

    See also

    + +
    +
    top
    +

    Script Directive

    + + + + + + +
    Description:Activates a CGI script for a particular request +method.
    Syntax:Script method cgi-script
    Context:server config, virtual host, directory
    Status:Base
    Module:mod_actions
    +

    This directive adds an action, which will activate + cgi-script when a file is requested using the method of + method. The cgi-script is the URL-path to a + resource that has been designated as a CGI script using ScriptAlias or AddHandler. The URL and + file path of the requested document is sent using the standard CGI + PATH_INFO and PATH_TRANSLATED environment + variables.

    + +
    + Any arbitrary method name may be used. Method names are + case-sensitive, so Script PUT and + Script put have two entirely different + effects. +
    + +

    Note that the Script command defines default + actions only. If a CGI script is called, or some other resource that is + capable of handling the requested method internally, it will do + so. Also note that Script with a method of + GET will only be called if there are query arguments present + (e.g., foo.html?hi). Otherwise, the request will + proceed normally.

    + +

    Examples

    + # For <ISINDEX>-style searching
    + Script GET /cgi-bin/search
    +
    + # A CGI PUT handler
    + Script PUT /~bob/put.cgi
    +

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_actions.html.ja.euc-jp b/trunk/docs/manual/mod/mod_actions.html.ja.euc-jp new file mode 100644 index 0000000000..ef048cb325 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.html.ja.euc-jp @@ -0,0 +1,173 @@ + + + +mod_actions - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_actions

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥á¥Ç¥£¥¢¥¿¥¤¥×¤ä¥ê¥¯¥¨¥¹¥È¥á¥½¥Ã¥É¤Ë±þ¤¸¤Æ +CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ëµ¡Ç½¤òÄó¶¡
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:actions_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_actions.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¤ÏÆó¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¤¢¤ê¤Þ¤¹¡£Action + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÆÃÄê¤Î MIME ¥¿¥¤¥×¤Î¥Õ¥¡¥¤¥ë¤ò¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¾ì¹ç¤Ë + CGI ¥¹¥¯¥ê¥×¥È¤¬¼Â¹Ô¤µ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£Script + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥ê¥¯¥¨¥¹¥È¤ÇÆÃÄê¤Î¥á¥½¥Ã¥É¤¬»ÈÍѤµ¤ì¤¿¤È¤­¤Ë CGI + ¥¹¥¯¥ê¥×¥È¤¬¼Â¹Ô¤µ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¥Õ¥¡¥¤¥ë¤ò½èÍý¤¹¤ë¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ò¤º¤Ã¤È´Êñ¤Ë¤·¤Þ¤¹¡£

    +
    + + +
    top
    +

    Action ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î¥Ï¥ó¥É¥é¤ä¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ËÂФ·¤Æ CGI ¤ò¼Â¹Ô¤¹¤ë¤è¤¦¤Ë +ÀßÄê
    ¹½Ê¸:Action action-type cgi-script [virtual]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_actions
    ¸ß´¹À­:virtual ½¤¾þ»Ò¤È¥Ï¥ó¥É¥éÅϤ·¤Ï +Apache 2.1 ¤ÇƳÆþ¤µ¤ì¤Þ¤·¤¿
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï action-type + ¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¤È¤­¤Ë cgi-script + ¤¬¼Â¹Ô¤µ¤ì¤ë¤È¤¤¤¦Æ°ºî¤òÄɲä·¤Þ¤¹¡£cgi-script ¤Ï + ScriptAlias ¤ä + AddHandler ¤Ë¤è¤Ã¤Æ + CGI ¥¹¥¯¥ê¥×¥È¤ËÀßÄꤵ¤ì¤¿¥ê¥½¡¼¥¹¤Ø¤Î URL-path ¤Ç¤¹¡£ + Action-type ¤Ë¤Ï + handler ¤« MIME + ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Î URL + ¤È¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤Ïɸ½à CGI ´Ä¶­ÊÑ¿ô PATH_INFO ¤È + PATH_TRANSLATED ¤ò»È¤Ã¤ÆÅÁ¤¨¤é¤ì¤Þ¤¹¡£ + ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ»ÈÍѤµ¤ì¤ë¥Ï¥ó¥É¥é¤Ø¤Ï¡¢ + REDIRECT_HANDLER ÊÑ¿ô¤ò»È¤Ã¤ÆÅϤ»¤Þ¤¹¡£

    + +

    Îã

    + # Requests for files of a particular MIME content type:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Files of a particular file extension
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +

    + +

    ºÇ½é¤ÎÎã¤Ç¤Ï¡¢MIME ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤¬ image/gif + ¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¡¢»ØÄꤷ¤¿¥¹¥¯¥ê¥×¥È + /cgi-bin/images.cgi ¤Ç½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    2 ÈÖÌܤÎÎã¤Ç¤Ï¡¢³ÈÄ¥»Ò¤¬ .xyz + ¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¡¢»ØÄꤷ¤¿¥¹¥¯¥ê¥×¥È + /cgi-bin/program.cgi ¤Ç½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    ¥ª¥×¥·¥ç¥ó¤Î virtual ½¤¾þ»Ò¤ò»ÈÍѤ¹¤ë¤È¡¢ + ¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤¬¼ÂºÝ¤Ë¸ºß¤¹¤ë¤«¤É¤¦¤«¤ò¸¡ºº¤·¤Ê¤¤¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤ÏÎ㤨¤Ð¡¢Action ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Ð¡¼¥Á¥ã¥ë¤Ê + Location ¤Ë»ÈÍѤ·¤¿¤¤¡¢¤È¤¤¤Ã¤¿¾ì¹ç¤ËÊØÍø¤Ç¤¹¡£

    + +

    Îã

    + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +

    + +

    »²¾È

    + +
    +
    top
    +

    Script ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¥á¥½¥Ã¥É¤ËÂФ·¤Æ CGI ¥¹¥¯¥ê¥×¥È¤ò +¼Â¹Ô¤¹¤ë¤è¤¦¤ËÀßÄê
    ¹½Ê¸:Script method cgi-script
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_actions
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï method + ¤È¤¤¤¦¥á¥½¥Ã¥É¤ò»È¤Ã¤Æ¥ê¥¯¥¨¥¹¥È¤¬¹Ô¤Ê¤ï¤ì¤¿¤È¤­¤Ë + cgi-script ¤ò¼Â¹Ô¤¹¤ë¤È¤¤¤¦Æ°ºî¤òÄɲä·¤Þ¤¹¡£ + cgi-script ¤Ï + ScriptAlias ¤ä + AddHandler ¤Ë¤è¤Ã¤Æ + CGI ¥¹¥¯¥ê¥×¥È¤ËÀßÄꤵ¤ì¤¿¥ê¥½¡¼¥¹¤Ø¤Î URL-path ¤Ç¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Î URL ¤È¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤Ïɸ½à CGI + ´Ä¶­ÊÑ¿ô PATH_INFO ¤È PATH_TRANSLATED + ¤ò»È¤Ã¤ÆÅÁ¤¨¤é¤ì¤Þ¤¹¡£

    + +
    + Ǥ°Õ¤Î¥á¥½¥Ã¥É̾¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥á¥½¥Ã¥É̾¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ + Script PUT ¤È Script put + ¤Ï¤Þ¤Ã¤¿¤¯°ã¤Ã¤¿¸ú²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£ +
    + +

    Script ¥³¥Þ¥ó¥É¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤ò + Äɲ乤ë¤À¤±¤Ç¤¢¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤â¤· CGI ¥¹¥¯¥ê¥×¥È¤¬¸Æ¤Ð¤ì¤¿¤ê¡¢¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ + ¥á¥½¥Ã¥É¤òÆâÉô¤Ç°·¤¦¤³¤È¤Î¤Ç¤­¤ë¾¤Î¥ê¥½¡¼¥¹¤¬¤¢¤ì¤Ð¡¢¤½¤ì¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + GET ¥á¥½¥Ã¥É¤Î Script ¤ÏÌä¹ç¤» + °ú¿ô¤¬¤¢¤ë¾ì¹ç¤Ë¤Î¤ß + (¤¿¤È¤¨¤Ð¡¢foo.html?hi) ¸Æ¤Ð¤ì¤ë¤È¤¤¤¦¤³¤È¤Ë¤âÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ÏÄ̾ïÄ̤ê½èÍý¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + # For <ISINDEX>-style searching
    + Script GET /cgi-bin/search
    +
    + # A CGI PUT handler
    + Script PUT /~bob/put.cgi
    +

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_actions.html.ko.euc-kr b/trunk/docs/manual/mod/mod_actions.html.ko.euc-kr new file mode 100644 index 0000000000..1d6551a2fb --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.html.ko.euc-kr @@ -0,0 +1,164 @@ + + + +mod_actions - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_actions

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:ÀÌ ¸ðµâÀº ¹Ìµð¾îÁ¾·ù³ª ¿äû¸Þ¼­µå¿¡ µû¶ó CGI +½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù.
    »óÅÂ:Base
    ¸ðµâ¸í:actions_module
    ¼Ò½ºÆÄÀÏ:mod_actions.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâ¿¡´Â µÎ°¡Áö Áö½Ã¾î°¡ ÀÖ´Ù. Action Áö½Ã¾î´Â ¿äûÇÏ´Â + ÆÄÀÏÀÇ MIME content type¿¡ µû¶ó CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù. + Script Áö½Ã¾î´Â + ¿äûÀÌ Æ¯Á¤ ¸Þ¼­µå¸¦ »ç¿ëÇÒ °æ¿ì CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù. + ±×·¡¼­ ÆÄÀÏÀ» ó¸®ÇÏ´Â ½ºÅ©¸³Æ®¸¦ ¸Å¿ì ½±°Ô ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    + + +
    top
    +

    Action Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ƯÁ¤ Çڵ鷯³ª content-type¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù
    ¹®¹ý:Action action-type cgi-script [virtual]
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_actions
    Áö¿ø:virtual ¼öÁ¤ÀÚ¿Í Çڵ鷯´Â ¾ÆÆÄÄ¡ +2.1¶§ Ãß°¡µÇ¾ú´Ù
    +

    ÀÌ Áö½Ã¾î´Â ¿äûÀÌ action-typeÀ̸é + cgi-script¸¦ ½ÇÇàÇÏ´Â ÇൿÀ» ¼­¹ö¿¡ Ãß°¡ÇÑ´Ù. + cgi-script´Â ScriptAlias³ª AddHandler¸¦ »ç¿ëÇÏ¿© CGI + ½ºÅ©¸³Æ®·Î ÁöÁ¤ÇÑ ¸®¼Ò½ºÀÇ URL°æ·ÎÀÌ´Ù. + action-type¿¡´Â Çڵ鷯³ª MIME content typeÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾î´Â PATH_INFO¿Í + PATH_TRANSLATED CGI Ç¥ÁØ È¯°æº¯¼ö·Î ¿äûÇÑ + ¹®¼­ÀÇ URL°ú ÆÄÀÏ°æ·Î¸¦ Àü´ÞÇÑ´Ù. REDIRECT_HANDLER + º¯¼ö·Î ƯÁ¤ ¿äû¿¡ »ç¿ëÇÒ Çڵ鷯¸¦ Àü´ÞÇÑ´Ù.

    + +

    ¿¹Á¦

    + # ƯÁ¤ MIME content typeÀÇ ÆÄÀÏ ¿äû:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # ƯÁ¤ÇÑ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏ
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +

    + +

    ù¹ø° ¿¹¿¡¼­ MIME content typeÀÌ image/gifÀÎ + ÆÄÀÏÀ» ¿äûÇϸé ÁöÁ¤ÇÑ cgi ½ºÅ©¸³Æ® /cgi-bin/images.cgi°¡ + ó¸®ÇÑ´Ù.

    + +

    µÎ¹ø° ¿¹¿¡¼­ È®ÀåÀÚ°¡ .xyzÀÎ ÆÄÀÏÀ» ¿äûÇϸé + ÁöÁ¤ÇÑ cgi ½ºÅ©¸³Æ® /cgi-bin/program.cgi°¡ + ó¸®ÇÑ´Ù.

    +

    In the second example, requests for files with a file extension of + .xyz are handled instead by the specified cgi script + /cgi-bin/program.cgi.

    + +

    ¼±ÅÃÀûÀÎ virtual ¼öÁ¤ÀÚ´Â ¿äûÇÑ ÆÄÀÏÀÌ + ½ÇÁ¦·Î Á¸ÀçÇÏ´ÂÁö °Ë»çÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. ¿¹¸¦ µé¾î, °¡»óÀÇ + À§Ä¡¿¡ Action Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á´Â + °æ¿ì À¯¿ëÇÏ´Ù.

    + +

    ¿¹Á¦

    + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +

    + +

    Âü°í

    + +
    +
    top
    +

    Script Áö½Ã¾î

    + + + + + + +
    ¼³¸í:ƯÁ¤ ¿äû¸Þ¼­µå¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù.
    ¹®¹ý:Script method cgi-script
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory
    »óÅÂ:Base
    ¸ðµâ:mod_actions
    +

    ÀÌ Áö½Ã¾î´Â ÆÄÀÏÀ» method ¸Þ¼­µå¸¦ »ç¿ëÇÏ¿© + ¿äûÇϸé cgi-script¸¦ ½ÇÇàÇÏ´Â ÇൿÀ» ¼­¹ö¿¡ + Ãß°¡ÇÑ´Ù. cgi-script´Â ScriptAlias³ª AddHandler¸¦ »ç¿ëÇÏ¿© CGI + ½ºÅ©¸³Æ®·Î ÁöÁ¤ÇÑ ¸®¼Ò½ºÀÇ URL°æ·ÎÀÌ´Ù. ÀÌ Áö½Ã¾î´Â + PATH_INFO¿Í PATH_TRANSLATED CGI + Ç¥ÁØ È¯°æº¯¼ö·Î ¿äûÇÑ ¹®¼­ÀÇ URL°ú ÆÄÀÏ°æ·Î¸¦ Àü´ÞÇÑ´Ù.

    + +
    + ¾î¶² ¸Þ¼­µå À̸§ÀÌ¶óµµ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¸Þ¼­µå À̸§Àº + ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÑ´Ù. ±×·¡¼­ Script PUT°ú + Script putÀº ¿ÏÀüÈ÷ ´Ù¸£´Ù. +
    + +

    Script ¸í·É¾î´Â ±âº»ÀûÀÎ Çൿ¸¸À» + ó¸®ÇÔÀ» ÁÖÀÇÇ϶ó. CGI ½ºÅ©¸³Æ®°¡ ºÒ¸®°Å³ª, ¿äûÇÑ ¸Þ¼­µå¸¦ + ¾Ë¾Æ¼­ ó¸®ÇÒ ¼ö ÀÖ´Â ¸®¼Ò½ºÀÇ °æ¿ì ±×´ë·Î ó¸®ÇÑ´Ù. + GET ¸Þ¼­µåÀÇ Script´Â + ÁúÀǾƱԸÕÆ®°¡ ÀÖÀ»¶§¸¸ (¿¹, foo.html?hi) »ç¿ëÇÔÀ» + ÁÖÀÇÇ϶ó. ÁúÀǾƱԸÕÆ®°¡ ¾ø´Ù¸é Á¤»óÀûÀ¸·Î ¿äûÀ» ó¸®ÇÑ´Ù.

    + +

    ¿¹Á¦

    + # <ISINDEX>½Ä °Ë»öÀ» À§ÇØ
    + Script GET /cgi-bin/search
    +
    + # CGI PUT Çڵ鷯
    + Script PUT /~bob/put.cgi
    +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_actions.xml b/trunk/docs/manual/mod/mod_actions.xml new file mode 100644 index 0000000000..4dfb90d486 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.xml @@ -0,0 +1,154 @@ + + + + + + + + + +mod_actions + +This module provides for executing CGI scripts based on +media type or request method. + +Base +mod_actions.c +actions_module + + +

    This module has two directives. The Action directive lets you run CGI + scripts whenever a file of a certain MIME content type is requested. The + Script directive lets + you run CGI scripts whenever a particular method is used in a + request. This makes it much easier to execute scripts that process + files.

    +
    + +mod_cgi +Dynamic Content with CGI +Apache's Handler Use + + +Action +Activates a CGI script for a particular handler or +content-type +Action action-type cgi-script [virtual] + +server configvirtual host +directory.htaccess + +FileInfo +The virtual modifier and handler passing were +introduced in Apache 2.1 + + +

    This directive adds an action, which will activate + cgi-script when action-type is triggered by the + request. The cgi-script is the URL-path to a resource + that has been designated as a CGI script using ScriptAlias or AddHandler. The + action-type can be either a handler or a MIME content type. It + sends the URL and file path of the requested document using the + standard CGI PATH_INFO and PATH_TRANSLATED + environment variables. The handler used for the particular request is + passed using the REDIRECT_HANDLER variable.

    + + Examples + # Requests for files of a particular MIME content type:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Files of a particular file extension
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +
    + +

    In the first example, requests for files with a MIME content + type of image/gif will be handled by the + specified cgi script /cgi-bin/images.cgi.

    + +

    In the second example, requests for files with a file extension of + .xyz are handled by the specified cgi script + /cgi-bin/program.cgi.

    + +

    The optional virtual modifier turns off the check + whether the requested file really exists. This is useful, for example, + if you want to use the Action directive in + virtual locations.

    + + Example + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +
    +
    + +AddHandler +
    + + +Script +Activates a CGI script for a particular request +method. +Script method cgi-script + +server configvirtual host +directory + +

    This directive adds an action, which will activate + cgi-script when a file is requested using the method of + method. The cgi-script is the URL-path to a + resource that has been designated as a CGI script using ScriptAlias or AddHandler. The URL and + file path of the requested document is sent using the standard CGI + PATH_INFO and PATH_TRANSLATED environment + variables.

    + + + Any arbitrary method name may be used. Method names are + case-sensitive, so Script PUT and + Script put have two entirely different + effects. + + +

    Note that the Script command defines default + actions only. If a CGI script is called, or some other resource that is + capable of handling the requested method internally, it will do + so. Also note that Script with a method of + GET will only be called if there are query arguments present + (e.g., foo.html?hi). Otherwise, the request will + proceed normally.

    + + Examples + # For <ISINDEX>-style searching
    + Script GET /cgi-bin/search
    +
    + # A CGI PUT handler
    + Script PUT /~bob/put.cgi
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_actions.xml.de b/trunk/docs/manual/mod/mod_actions.xml.de new file mode 100644 index 0000000000..ed2bab6a59 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.xml.de @@ -0,0 +1,157 @@ + + + + + + + + + +mod_actions + +Dieses Modul ermöglicht die Ausführung von CGI-Skripten + in Abhängigkeit von Medientypen und Anfragemethoden. + +Base +mod_actions.c +actions_module + + +

    Das Modul besitzt zwei Direktiven. Die Direktive Action erlaubt die Ausführung von + CGI-Skripten immer dann, wenn eine Anfrage zu einem bestimmten MIME-Type + erfolgt. Die Direktive Script + erlaubt die Ausführung von CGI-Skripten abhängig von einer + bestimmten Methode, die in der Anfrage verwendet wird. Dies macht es + deutlich einfacher, Skripte auszuführen, die Dateien + verarbeiten.

    +
    + +mod_cgi +Dynamische Inhalte mit CGI +Die Verwendung von Handlern + + +Action +Aktiviert ein CGI-Skript für einen bestimmten Handler oder + Content-Type +Action Aktionsart CGI-Skript [virtual] + +server configvirtual host +directory.htaccess + +FileInfo +Der Schalter virtual und die Übergabe des + Handlers wurden in Apache 2.1 eingeführt. + + +

    Die Direktive fügt eine Aktion hinzu, welche das + CGI-Skript aktiviert, sobald die Aktionsart durch + eine Anfrage ausgelöst wird. CGI-Skript ist der URL-Pfad + zu einer Ressource, die unter Verwendung von ScriptAlias oder AddHandler als CGI-Skript gekennzeichnet + wurde. Die Aktionsart kann entweder ein Handler oder ein MIME-Type sein. Die URL und + den Dateipfad des angeforderten Dokuments in den + Standard-CGI-Umgebungsvariablen PATH_INFO und + PATH_TRANSLATED übergeben. Der für die jeweilige + Anfrage verwendete Handler wird in der Umgebungsvariablen + REDIRECT_HANDLER übergeben.

    + + Beispiele + # Anfragen für Dateien eines bestimmten MIME-Types:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Dateien einer bestimmten Dateiendung
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +
    + +

    Im ersten Beispiel werden Anfragen für Dateien mit dem MIME-Type + image/gif von dem angegebenen CGI-Skript + /cgi-bin/images.cgi bearbeitet.

    + +

    Im zweiten Beispiel werden Anfragen für Dateien mit der Dateiendung + .xyz von dem angegebenen CGI-Skript + /cgi-bin/program.cgi bearbeitet.

    + +

    Der optionale Schalter virtual deaktiviert die Prüfung + auf Existenz der angeforderten Datei. Dies ist beispielsweise + nützlich, wenn Sie die Direktive Action in + Verbindung mit virtuellen Adressräumen verwenden möchten.

    + + Beispiel + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +
    +
    + +AddHandler +
    + + +Script +Aktiviert ein CGI-Skript für eine bestimmte + Anfragemethode. +Script Methode CGI-Skript + +server configvirtual host +directory + +

    Die Direktive fügt eine Aktion hinzu, welche das + CGI-Skript aktiviert, wenn eine Datei unter der Verwendung der + Methode Methode angefordert wird. CGI-Skript ist der + URL-Pfad zu einer Ressource, die unter Verwendung von ScriptAlias oder AddHandler als CGI-Skript gekennzeichnet + wurde. Die URL und der Dateipfad des angeforderten Dokuments werden in den + Standard-CGI-Umgebungsvariablen PATH_INFO und + PATH_TRANSLATED übergeben.

    + + + Der Methodenname kann frei gewählt werden. Bei Methodennamen + wird zwischen Groß- und Kleinschreibung unterschieden, so + dass Script PUT und Script put zu vollkommen + unterschiedlichen Ergebnissen führen. + + +

    Beachten Sie, dass der Script-Befehl nur + Voreinstellungen für Aktionen definiert. Wird ein CGI-Skript + - oder eine andere Ressource, die in der Lage ist, die angeforderte + Methode intern zu bearbeiten - aufgerufen, so wird diese(s) verwendet. + Beachten Sie auch, dass Script mit der Methode + GET nur dann aufgerufen wird, wenn Query-Argumente vorhanden + sind (z.B. foo.html?hi). Andernfalls wird die Anfrage normal + bearbeitet.

    + + Beispiele + # Für <ISINDEX>-ähnliches Suchen
    + Script GET /cgi-bin/search
    +
    + # Ein CGI-PUT-Handler
    + Script PUT /~bob/put.cgi
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_actions.xml.ja b/trunk/docs/manual/mod/mod_actions.xml.ja new file mode 100644 index 0000000000..fd313b87a1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.xml.ja @@ -0,0 +1,158 @@ + + + + + + + + + +mod_actions + +$B%a%G%#%"%?%$%W$d%j%/%(%9%H%a%=%C%I$K1~$8$F(B +CGI $B%9%/%j%W%H$r + +Base +mod_actions.c +actions_module + + +

    $B$3$N%b%8%e!<%k$K$OFs$D$N%G%#%l%/%F%#%V$,$"$j$^$9!#(BAction + $B%G%#%l%/%F%#%V$OFCDj$N(B MIME $B%?%$%W$N%U%!%$%k$r%j%/%(%9%H$5$l$?>l9g$K(B + CGI $B%9%/%j%W%H$,Script + $B%G%#%l%/%F%#%V$O%j%/%(%9%H$GFCDj$N%a%=%C%I$,;HMQ$5$l$?$H$-$K(B CGI + $B%9%/%j%W%H$, +

    + +mod_cgi +CGI $B$K$h$kF0E*%3%s%F%s%D(B +Apache $B$N%O%s%I%i$N;HMQ(B + + +Action +$BFCDj$N%O%s%I%i$d%3%s%F%s%H%?%$%W$KBP$7$F(B CGI $B$r +Action action-type cgi-script [virtual] + +server configvirtual host +directory.htaccess + +FileInfo +virtual $B=$>~;R$H%O%s%I%iEO$7$O(B +Apache 2.1 $B$GF3F~$5$l$^$7$?(B + + +

    $B$3$N%G%#%l%/%F%#%V$O(B action-type + $B$,%j%/%(%9%H$5$l$?$H$-$K(B cgi-script + $B$,cgi-script $B$O(B + ScriptAlias $B$d(B + AddHandler $B$K$h$C$F(B + CGI $B%9%/%j%W%H$K@_Dj$5$l$?%j%=!<%9$X$N(B URL-path $B$G$9!#(B + Action-type $B$K$O(B + handler $B$+(B MIME + $B%3%s%F%s%H%?%$%W$r;XDj$G$-$^$9!#%j%/%(%9%H$5$l$?%I%-%e%a%s%H$N(B URL + $B$H%U%!%$%k$N%Q%9$OI8=`(B CGI $B4D6-JQ?t(B PATH_INFO $B$H(B + PATH_TRANSLATED $B$r;H$C$FEA$($i$l$^$9!#(B + $BFCDj$N%j%/%(%9%H$KBP$7$F;HMQ$5$l$k%O%s%I%i$X$O!"(B + REDIRECT_HANDLER $BJQ?t$r;H$C$FEO$;$^$9!#(B

    + + $BNc(B + # Requests for files of a particular MIME content type:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # Files of a particular file extension
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +
    + +

    $B:G=i$NNc$G$O!"(BMIME $B%3%s%F%s%H%?%$%W$,(B image/gif + $B$N%U%!%$%k$X$N%j%/%(%9%H$O!";XDj$7$?%9%/%j%W%H(B + /cgi-bin/images.cgi $B$G=hM}$5$l$^$9!#(B

    + +

    2 $BHVL\$NNc$G$O!"3HD%;R$,(B .xyz + $B$N%U%!%$%k$X$N%j%/%(%9%H$O!";XDj$7$?%9%/%j%W%H(B + /cgi-bin/program.cgi $B$G=hM}$5$l$^$9!#(B

    + +

    $B%*%W%7%g%s$N(B virtual $B=$>~;R$r;HMQ$9$k$H!"(B + $B%j%/%(%9%H$5$l$?%U%!%$%k$,Action $B%G%#%l%/%F%#%V$r%P!<%A%c%k$J(B + Location $B$K;HMQ$7$?$$!"$H$$$C$?>l9g$KJXMx$G$9!#(B

    + + $BNc(B + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +
    +
    + +AddHandler +
    + + +Script +$BFCDj$N%j%/%(%9%H%a%=%C%I$KBP$7$F(B CGI $B%9%/%j%W%H$r(B +$B +Script method cgi-script + +server configvirtual host +directory + +

    $B$3$N%G%#%l%/%F%#%V$O(B method + $B$H$$$&%a%=%C%I$r;H$C$F%j%/%(%9%H$,9T$J$o$l$?$H$-$K(B + cgi-script $B$rcgi-script $B$O(B + ScriptAlias $B$d(B + AddHandler $B$K$h$C$F(B + CGI $B%9%/%j%W%H$K@_Dj$5$l$?%j%=!<%9$X$N(B URL-path $B$G$9!#(B + $B%j%/%(%9%H$5$l$?%I%-%e%a%s%H$N(B URL $B$H%U%!%$%k$N%Q%9$OI8=`(B CGI + $B4D6-JQ?t(B PATH_INFO $B$H(B PATH_TRANSLATED + $B$r;H$C$FEA$($i$l$^$9!#(B

    + + + $BG$0U$N%a%=%C%IL>$r;HMQ$9$k$3$H$,$G$-$^$9!#(B + $B%a%=%C%IL>$OBgJ8;z>.J8;z$r6hJL$7$^$9(B$B!#$G$9$+$i!"(B + Script PUT $B$H(B Script put + $B$O$^$C$?$/0c$C$?8z2L$K$J$j$^$9!#(B + + +

    Script $B%3%^%s%I$O%G%U%)%k%H$NF0:n$r(B + $BDI2C$9$k$@$1$G$"$k$3$H$K(B + $BCm0U$7$F$/$@$5$$!#$b$7(B CGI $B%9%/%j%W%H$,8F$P$l$?$j!"%j%/%(%9%H$5$l$?(B + $B%a%=%C%I$rFbIt$G07$&$3$H$N$G$-$kB>$N%j%=!<%9$,$"$l$P!"$=$l$,9T$J$o$l$^$9!#(B + GET $B%a%=%C%I$N(B Script $B$OLd9g$;(B + $B0z?t$,$"$k>l9g$K$N$_(B + ($B$?$H$($P(B$B!"(Bfoo.html?hi) $B8F$P$l$k$H$$$&$3$H$K$bCm0U$7$F$/$@$5$$!#(B + $B$=$&$G$J$$>l9g$O!"%j%/%(%9%H$ODL>oDL$j=hM}$5$l$^$9!#(B

    + + $BNc(B + # For <ISINDEX>-style searching
    + Script GET /cgi-bin/search
    +
    + # A CGI PUT handler
    + Script PUT /~bob/put.cgi
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_actions.xml.ko b/trunk/docs/manual/mod/mod_actions.xml.ko new file mode 100644 index 0000000000..b09e43713c --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.xml.ko @@ -0,0 +1,153 @@ + + + + + + + + + +mod_actions + +ÀÌ ¸ðµâÀº ¹Ìµð¾îÁ¾·ù³ª ¿äû¸Þ¼­µå¿¡ µû¶ó CGI +½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù. + +Base +mod_actions.c +actions_module + + +

    ÀÌ ¸ðµâ¿¡´Â µÎ°¡Áö Áö½Ã¾î°¡ ÀÖ´Ù. Action Áö½Ã¾î´Â ¿äûÇÏ´Â + ÆÄÀÏÀÇ MIME content type¿¡ µû¶ó CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù. + Script Áö½Ã¾î´Â + ¿äûÀÌ Æ¯Á¤ ¸Þ¼­µå¸¦ »ç¿ëÇÒ °æ¿ì CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù. + ±×·¡¼­ ÆÄÀÏÀ» ó¸®ÇÏ´Â ½ºÅ©¸³Æ®¸¦ ¸Å¿ì ½±°Ô ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    + +mod_cgi +CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º +¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë + + +Action +ƯÁ¤ Çڵ鷯³ª content-type¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù +Action action-type cgi-script [virtual] + +server configvirtual host +directory.htaccess + +FileInfo +virtual ¼öÁ¤ÀÚ¿Í Çڵ鷯´Â ¾ÆÆÄÄ¡ +2.1¶§ Ãß°¡µÇ¾ú´Ù + + +

    ÀÌ Áö½Ã¾î´Â ¿äûÀÌ action-typeÀ̸é + cgi-script¸¦ ½ÇÇàÇÏ´Â ÇൿÀ» ¼­¹ö¿¡ Ãß°¡ÇÑ´Ù. + cgi-script´Â ScriptAlias³ª AddHandler¸¦ »ç¿ëÇÏ¿© CGI + ½ºÅ©¸³Æ®·Î ÁöÁ¤ÇÑ ¸®¼Ò½ºÀÇ URL°æ·ÎÀÌ´Ù. + action-type¿¡´Â Çڵ鷯³ª MIME content typeÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾î´Â PATH_INFO¿Í + PATH_TRANSLATED CGI Ç¥ÁØ È¯°æº¯¼ö·Î ¿äûÇÑ + ¹®¼­ÀÇ URL°ú ÆÄÀÏ°æ·Î¸¦ Àü´ÞÇÑ´Ù. REDIRECT_HANDLER + º¯¼ö·Î ƯÁ¤ ¿äû¿¡ »ç¿ëÇÒ Çڵ鷯¸¦ Àü´ÞÇÑ´Ù.

    + + ¿¹Á¦ + # ƯÁ¤ MIME content typeÀÇ ÆÄÀÏ ¿äû:
    + Action image/gif /cgi-bin/images.cgi
    +
    + # ƯÁ¤ÇÑ È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏ
    + AddHandler my-file-type .xyz
    + Action my-file-type /cgi-bin/program.cgi
    +
    + +

    ù¹ø° ¿¹¿¡¼­ MIME content typeÀÌ image/gifÀÎ + ÆÄÀÏÀ» ¿äûÇϸé ÁöÁ¤ÇÑ cgi ½ºÅ©¸³Æ® /cgi-bin/images.cgi°¡ + ó¸®ÇÑ´Ù.

    + +

    µÎ¹ø° ¿¹¿¡¼­ È®ÀåÀÚ°¡ .xyzÀÎ ÆÄÀÏÀ» ¿äûÇϸé + ÁöÁ¤ÇÑ cgi ½ºÅ©¸³Æ® /cgi-bin/program.cgi°¡ + ó¸®ÇÑ´Ù.

    +

    In the second example, requests for files with a file extension of + .xyz are handled instead by the specified cgi script + /cgi-bin/program.cgi.

    + +

    ¼±ÅÃÀûÀÎ virtual ¼öÁ¤ÀÚ´Â ¿äûÇÑ ÆÄÀÏÀÌ + ½ÇÁ¦·Î Á¸ÀçÇÏ´ÂÁö °Ë»çÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. ¿¹¸¦ µé¾î, °¡»óÀÇ + À§Ä¡¿¡ Action Áö½Ã¾î¸¦ »ç¿ëÇÏ·Á´Â + °æ¿ì À¯¿ëÇÏ´Ù.

    + + ¿¹Á¦ + <Location /news>
    + + SetHandler news-handler
    + Action news-handler /cgi-bin/news.cgi virtual
    +
    + </Location> +
    +
    + +AddHandler +
    + + +Script +ƯÁ¤ ¿äû¸Þ¼­µå¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù. +Script method cgi-script + +server configvirtual host +directory + +

    ÀÌ Áö½Ã¾î´Â ÆÄÀÏÀ» method ¸Þ¼­µå¸¦ »ç¿ëÇÏ¿© + ¿äûÇϸé cgi-script¸¦ ½ÇÇàÇÏ´Â ÇൿÀ» ¼­¹ö¿¡ + Ãß°¡ÇÑ´Ù. cgi-script´Â ScriptAlias³ª AddHandler¸¦ »ç¿ëÇÏ¿© CGI + ½ºÅ©¸³Æ®·Î ÁöÁ¤ÇÑ ¸®¼Ò½ºÀÇ URL°æ·ÎÀÌ´Ù. ÀÌ Áö½Ã¾î´Â + PATH_INFO¿Í PATH_TRANSLATED CGI + Ç¥ÁØ È¯°æº¯¼ö·Î ¿äûÇÑ ¹®¼­ÀÇ URL°ú ÆÄÀÏ°æ·Î¸¦ Àü´ÞÇÑ´Ù.

    + + + ¾î¶² ¸Þ¼­µå À̸§ÀÌ¶óµµ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¸Þ¼­µå À̸§Àº + ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÑ´Ù. ±×·¡¼­ Script PUT°ú + Script putÀº ¿ÏÀüÈ÷ ´Ù¸£´Ù. + + +

    Script ¸í·É¾î´Â ±âº»ÀûÀÎ Çൿ¸¸À» + ó¸®ÇÔÀ» ÁÖÀÇÇ϶ó. CGI ½ºÅ©¸³Æ®°¡ ºÒ¸®°Å³ª, ¿äûÇÑ ¸Þ¼­µå¸¦ + ¾Ë¾Æ¼­ ó¸®ÇÒ ¼ö ÀÖ´Â ¸®¼Ò½ºÀÇ °æ¿ì ±×´ë·Î ó¸®ÇÑ´Ù. + GET ¸Þ¼­µåÀÇ Script´Â + ÁúÀǾƱԸÕÆ®°¡ ÀÖÀ»¶§¸¸ (¿¹, foo.html?hi) »ç¿ëÇÔÀ» + ÁÖÀÇÇ϶ó. ÁúÀǾƱԸÕÆ®°¡ ¾ø´Ù¸é Á¤»óÀûÀ¸·Î ¿äûÀ» ó¸®ÇÑ´Ù.

    + + ¿¹Á¦ + # <ISINDEX>½Ä °Ë»öÀ» À§ÇØ
    + Script GET /cgi-bin/search
    +
    + # CGI PUT Çڵ鷯
    + Script PUT /~bob/put.cgi
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_actions.xml.meta b/trunk/docs/manual/mod/mod_actions.xml.meta new file mode 100644 index 0000000000..917590df17 --- /dev/null +++ b/trunk/docs/manual/mod/mod_actions.xml.meta @@ -0,0 +1,14 @@ + + + + mod_actions + /mod/ + .. + + + de + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_alias.html b/trunk/docs/manual/mod/mod_alias.html new file mode 100644 index 0000000000..cbf64dede2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.html @@ -0,0 +1,11 @@ +URI: mod_alias.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_alias.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_alias.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_alias.html.en b/trunk/docs/manual/mod/mod_alias.html.en new file mode 100644 index 0000000000..c3dbac7e1e --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.html.en @@ -0,0 +1,376 @@ + + + +mod_alias - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_alias

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Provides for mapping different parts of the host + filesystem in the document tree and for URL redirection
    Status:Base
    Module Identifier:alias_module
    Source File:mod_alias.c
    +

    Summary

    + +

    The directives contained in this module allow for manipulation + and control of URLs as requests arrive at the server. The + Alias and ScriptAlias directives are used to + map between URLs and filesystem paths. This allows for content + which is not directly under the DocumentRoot served as part of the web + document tree. The ScriptAlias directive has the + additional effect of marking the target directory as containing + only CGI scripts.

    + +

    The Redirect + directives are used to instruct clients to make a new request with + a different URL. They are often used when a resource has moved to + a new location.

    + +

    mod_alias is designed to handle simple URL + manipulation tasks. For more complicated tasks such as + manipulating the query string, use the tools provided by + mod_rewrite.

    + +
    + +
    top
    +
    +

    Order of Processing

    + +

    Aliases and Redirects occuring in different contexts are processed +like other directives according to standard merging rules. But when multiple +Aliases or Redirects occur in the same context (for example, in the +same <VirtualHost> +section) they are processed in a particular order.

    + +

    First, all Redirects are processed before Aliases are processed, +and therefore a request that matches a Redirect or RedirectMatch will never have Aliases +applied. Second, the Aliases and Redirects are processed in the order +they appear in the configuration files, with the first match taking +precedence.

    + +

    For this reason, when two or more of these directives apply to the +same sub-path, you must list the most specific path first in order for +all the directives to have an effect. For example, the following +configuration will work as expected:

    + +

    +Alias /foo/bar /baz
    +Alias /foo /gaq +

    + +

    But if the above two directives were reversed in order, the +/foo Alias +would always match before the /foo/bar Alias, so the latter directive would be +ignored.

    + +
    +
    top
    +

    Alias Directive

    + + + + + + +
    Description:Maps URLs to filesystem locations
    Syntax:Alias URL-path +file-path|directory-path
    Context:server config, virtual host
    Status:Base
    Module:mod_alias
    + +

    The Alias directive allows documents to + be stored in the local filesystem other than under the + DocumentRoot. URLs with a + (%-decoded) path beginning with url-path will be mapped + to local files beginning with directory-path.

    + +

    Example:

    + Alias /image /ftp/pub/image +

    + +

    A request for http://myserver/image/foo.gif would cause the + server to return the file /ftp/pub/image/foo.gif.

    + +

    Note that if you include a trailing / on the + url-path then the server will require a trailing / in + order to expand the alias. That is, if you use Alias + /icons/ /usr/local/apache/icons/ then the url + /icons will not be aliased.

    + +

    Note that you may need to specify additional <Directory> sections which + cover the destination of aliases. Aliasing occurs before + <Directory> sections + are checked, so only the destination of aliases are affected. + (Note however <Location> + sections are run through once before aliases are performed, so + they will apply.)

    + +

    In particular, if you are creating an Alias to a + directory outside of your DocumentRoot, you may need to explicitly + permit access to the target directory.

    + +

    Example:

    + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +

    + + +
    +
    top
    +

    AliasMatch Directive

    + + + + + + +
    Description:Maps URLs to filesystem locations using regular +expressions
    Syntax:AliasMatch regex +file-path|directory-path
    Context:server config, virtual host
    Status:Base
    Module:mod_alias
    +

    This directive is equivalent to Alias, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, and + if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to activate the /icons directory, one might + use:

    + +

    + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 +

    + +
    +
    top
    +

    Redirect Directive

    + + + + + + + +
    Description:Sends an external redirect asking the client to fetch +a different URL
    Syntax:Redirect [status] URL-path +URL
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_alias
    +

    The Redirect directive maps an old URL into a new one. The + new URL is returned to the client which attempts to fetch it + again with the new address. URL-path a (%-decoded) + path; any requests for documents beginning with this path will + be returned a redirect error to a new (%-encoded) URL beginning + with URL.

    + +

    Example:

    + Redirect /service http://foo2.bar.com/service +

    + +

    If the client requests http://myserver/service/foo.txt, it + will be told to access http://foo2.bar.com/service/foo.txt + instead.

    + +

    Note

    Redirect directives take precedence over +Alias and ScriptAlias directives, irrespective of their ordering in +the configuration file. Also, URL-path must be a fully +qualified URL, not a relative path, even when used with .htaccess files or +inside of <Directory> +sections.

    + +

    If no status argument is given, the redirect will + be "temporary" (HTTP status 302). This indicates to the client + that the resource has moved temporarily. The status + argument can be used to return other HTTP status codes:

    + +
    +
    permanent
    + +
    Returns a permanent redirect status (301) indicating that + the resource has moved permanently.
    + +
    temp
    + +
    Returns a temporary redirect status (302). This is the + default.
    + +
    seeother
    + +
    Returns a "See Other" status (303) indicating that the + resource has been replaced.
    + +
    gone
    + +
    Returns a "Gone" status (410) indicating that the + resource has been permanently removed. When this status is + used the URL argument should be omitted.
    +
    + +

    Other status codes can be returned by giving the numeric + status code as the value of status. If the status is + between 300 and 399, the URL argument must be present, + otherwise it must be omitted. Note that the status must be + known to the Apache code (see the function + send_error_response in http_protocol.c).

    + +

    Example:

    + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +

    + + +
    +
    top
    +

    RedirectMatch Directive

    + + + + + + + +
    Description:Sends an external redirect based on a regular expression match +of the current URL
    Syntax:RedirectMatch [status] regex +URL
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_alias
    +

    This directive is equivalent to Redirect, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, and + if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to redirect all GIF files to like-named JPEG files on + another server, one might use:

    + +

    + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg +

    + +
    +
    top
    +

    RedirectPermanent Directive

    + + + + + + + +
    Description:Sends an external permanent redirect asking the client to fetch +a different URL
    Syntax:RedirectPermanent URL-path URL
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_alias
    +

    This directive makes the client know that the Redirect is + permanent (status 301). Exactly equivalent to Redirect + permanent.

    + +
    +
    top
    +

    RedirectTemp Directive

    + + + + + + + +
    Description:Sends an external temporary redirect asking the client to fetch +a different URL
    Syntax:RedirectTemp URL-path URL
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_alias
    +

    This directive makes the client know that the Redirect is + only temporary (status 302). Exactly equivalent to + Redirect temp.

    + +
    +
    top
    +

    ScriptAlias Directive

    + + + + + + +
    Description:Maps a URL to a filesystem location and designates the +target as a CGI script
    Syntax:ScriptAlias URL-path +file-path|directory-path
    Context:server config, virtual host
    Status:Base
    Module:mod_alias
    +

    The ScriptAlias directive has the same + behavior as the Alias + directive, except that in addition it marks the target directory + as containing CGI scripts that will be processed by mod_cgi's cgi-script handler. URLs with a + (%-decoded) path beginning with URL-path will be mapped + to scripts beginning with the second argument which is a full + pathname in the local filesystem.

    + +

    Example:

    + ScriptAlias /cgi-bin/ /web/cgi-bin/ +

    + +

    A request for http://myserver/cgi-bin/foo would cause the + server to run the script /web/cgi-bin/foo.

    + +
    +
    top
    +

    ScriptAliasMatch Directive

    + + + + + + +
    Description:Maps a URL to a filesystem location using a regular expression +and designates the target as a CGI script
    Syntax:ScriptAliasMatch regex +file-path|directory-path
    Context:server config, virtual host
    Status:Base
    Module:mod_alias
    +

    This directive is equivalent to ScriptAlias, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, + and if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to activate the standard /cgi-bin, one + might use:

    + +

    + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_alias.html.ja.euc-jp b/trunk/docs/manual/mod/mod_alias.html.ja.euc-jp new file mode 100644 index 0000000000..0c3ea66a41 --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.html.ja.euc-jp @@ -0,0 +1,385 @@ + + + +mod_alias - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_alias

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥Û¥¹¥È¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¤¤¤í¤¤¤í¤Ê°ã¤¦¾ì½ê¤ò + ¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Ë¥Þ¥Ã¥×¤¹¤ëµ¡Ç½¤È¡¢ + URL ¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò¹Ô¤Ê¤¦µ¡Ç½¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:alias_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_alias.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥Ð¤Ë¥ê¥¯¥¨¥¹¥È¤¬ÅþÃ夷¤¿¤È¤­¤Ë + URL ¤ÎÁàºî¤äÀ©¸æ¤ò¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£Alias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È ScriptAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + URL ¤È¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ñ¥¹¤ò¥Þ¥Ã¥×¤¹¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤ì¤Ï + DocumentRoot + ¤Î²¼¤Ë¤Ê¤¤¥É¥­¥å¥á¥ó¥È¤ò¥¦¥§¥Ö¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Î°ìÉô¤È¤·¤Æ + Á÷¤é¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ScriptAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ï¥Þ¥Ã¥×Àè¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬ CGI + ¥¹¥¯¥ê¥×¥È¤Î¤ß¤Ç¤¢¤ë¤³¤È¤ò¼¨¤¹¤È¤¤¤¦Äɲäθú²Ì¤¬¤¢¤ê¤Þ¤¹¡£ +

    + +

    Redirect ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥¯¥é¥¤¥¢¥ó¥È¤Ë°ã¤Ã¤¿ + URL ¤Ë¿·¤·¤¤¥ê¥¯¥¨¥¹¥È¤òÁ÷¤ë¤è¤¦¤Ë»Ø¼¨¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢ + ¥ê¥½¡¼¥¹¤¬¿·¤·¤¤¾ì½ê¤Ë°ÜÆ°¤·¤¿¤È¤­¤Ë¤è¤¯»ÈÍѤµ¤ì¤Þ¤¹¡£

    + +

    mod_alias ¤Ï´Êñ¤Ê URL Áàºî¸þ¤±¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤è¤êÊ£»¨¤ÊÁàºî¡¢¥¯¥¨¥ê¡¼¥¹¥È¥ê¥ó¥°¤ÎÁàºî¤Ë¤Ï¡¢mod_rewrite + ¤ÇÄ󶡤µ¤ì¤ë¥Ä¡¼¥ë¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    + +
    top
    +
    +

    ½èÍý¤Î½çÈÖ

    + +

    ÍÍ¡¹¤Ê¥³¥ó¥Æ¥­¥¹¥ÈÃæ¤Ç¤Î Alias ¤ä Redirect ¤Ï¾¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È +Ʊ¤¸¤è¤¦¤Ëɸ½à¤Î ¥Þ¡¼¥¸µ¬Â§ ¤Ë +½¾¤Ã¤Æ½èÍý¤µ¤ì¤Þ¤¹¡£¤¿¤À¤·¡¢(Î㤨¤Ð <VirtualHost> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Î¤è¤¦¤Ë) Ê£¿ô¤Î Alias ¤ä Redirect ¤¬ +Ʊ¤¸¥³¥ó¥Æ¥­¥¹¥ÈÃæ¤Ë¸½¤ì¤¿¾ì¹ç¤Ï·è¤Þ¤Ã¤¿½çÈ֤ǽèÍý¤µ¤ì¤Þ¤¹¡£

    + +

    ¤Þ¤º¡¢Alias ¤ÎÁ°¤Ë¤¹¤Ù¤Æ¤Î Redirect ¤¬½èÍý¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢Redirect ¤« RedirectMatch ¤Ë¥Þ¥Ã¥Á¤¹¤ë¥ê¥¯¥¨¥¹¥È¤Ë¤Ï +Alias ¤Ï·è¤·¤ÆŬÍѤµ¤ì¤Þ¤»¤ó¡£¼¡¤Ë¡¢Alias ¤È Redirect ¤¬ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î +½çÈÖ¤ËŬÍѤµ¤ì¡¢ºÇ½é¤Ë¥Þ¥Ã¥Á¤·¤¿¤â¤Î¤¬Í¥À褵¤ì¤Þ¤¹¡£

    + +

    ¤Ç¤¹¤«¤é¡¢Æó¤Ä°Ê¾å¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Æ±¤¸¥Ñ¥¹¤ËŬÍѤµ¤ì¤ë¤È¤­¤Ï¡¢ +¤¹¤Ù¤Æ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸ú²Ì¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¤è¤ê¾Ü¤·¤¤¥Ñ¥¹¤òÀè¤Ë½ñ¤¯ +ɬÍפ¬¤¢¤ê¤Þ¤¹¡£Î㤨¤Ð¡¢¼¡¤ÎÀßÄê¤Ï´üÂÔÄ̤ê¤ÎÆ°ºî¤ò¤·¤Þ¤¹:

    + +

    +Alias /foo/bar /baz
    +Alias /foo /gaq +

    + +

    ¤·¤«¤·¡¢¾åµ­¤ÎÆó¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î½çÈÖ¤¬µÕ¤Ë¤Ê¤ë¤È¡¢ +/foo Alias ¤¬ +¾ï¤Ë /foo/bar Alias ¤è¤êÀè¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¤Î¤Ç¡¢¸å¼Ô¤Ï +·è¤·¤ÆŬÍѤµ¤ì¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    Alias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤˥ޥåפ¹¤ë
    ¹½Ê¸:Alias URL-path +file-path|directory-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    Alias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥É¥­¥å¥á¥ó¥È¤ò + ¥í¡¼¥«¥ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î + DocumentRoot + °Ê³°¤Î¾ì½ê¤ËÊݴɤ¹¤ë¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£ + URL ¤Î (% ¤¬Éü¹æ¤µ¤ì¤¿) ¥Ñ¥¹¤¬ url-path ¤Ç»Ï¤Þ¤ë¤â¤Î¤Ï + directory-filename + ¤Ç»Ï¤Þ¤ë¥í¡¼¥«¥ë¥Õ¥¡¥¤¥ë¤Ë¥Þ¥Ã¥×¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + Alias /image /ftp/pub/image +

    + +

    http://myserver/image/foo.gif ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¡¢¥µ¡¼¥Ð¤Ï + ¥Õ¥¡¥¤¥ë /ftp/pub/image/foo.gif ¤òÊÖ¤·¤Þ¤¹¡£

    + +

    ¤â¤· url-path ¤ÎºÇ¸å¤Ë / + ¤ò½ñ¤¤¤¿¤Ê¤é¡¢¥µ¡¼¥Ð¤¬¥¨¥¤¥ê¥¢¥¹¤òŸ³«¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ºÇ¸å¤Î / + ¤¬É¬Íפˤʤ뤳¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤¹¤Ê¤ï¤Á¡¢Alias /icons/ + /usr/local/apache/icons/ ¤È¤¤¤¦¤â¤Î¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + /icons ¤È¤¤¤¦ url ¤Ï¥¨¥¤¥ê¥¢¥¹¤µ¤ì¤Þ¤»¤ó¡£

    + +

    ¥¨¥¤¥ê¥¢¥¹¤Î¹Ô¤­Àè¤ò´Þ¤ó¤Ç¤¤¤ë <Directory> + ¥»¥¯¥·¥ç¥ó¤òÄɲ乤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¥¨¥¤¥ê¥¢¥¹¤ÎŸ³«¤Ï <Directory> + ¥»¥¯¥·¥ç¥ó¤òÄ´¤Ù¤ëÁ°¤Ë¹Ô¤Ê¤ï¤ì¤Þ¤¹¤Î¤Ç¡¢ + ¥¨¥¤¥ê¥¢¥¹¤Î¹Ô¤­Àè¤Î <Directory> ¥»¥¯¥·¥ç¥ó¤Î¤ß + ¸ú²Ì¤¬¤¢¤ê¤Þ¤¹¡£ + (¤·¤«¤·¡¢<Location> + ¥»¥¯¥·¥ç¥ó¤Ï¥¨¥¤¥ê¥¢¥¹¤¬½èÍý¤µ¤ì¤ëÁ°¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + ¤³¤Á¤é¤ÏŬÍѤµ¤ì¤Þ¤¹¡£)

    + +

    Æäˡ¢Alias ¤ò + DocumentRoot + ¥Ç¥£¥ì¥¯¥È¥ê¤Î³°Â¦¤ËÇÛÃÖ¤·¤¿¾ì¹ç¤Ï¡¢¹Ô¤­Àè¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ¹¤ë + ¥¢¥¯¥»¥¹¸¢¸Â¤òÌÀ¼¨Åª¤ËÀ©¸Â¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤Ç¤·¤ç¤¦¡£

    + +

    Îã

    + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +

    + + +
    +
    top
    +

    AliasMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Àµµ¬É½¸½¤ò»È¤Ã¤Æ URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤˥ޥåפ¹¤ë
    ¹½Ê¸:AliasMatch regex +file-path|directory-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Alias + ¤È¤Û¤È¤ó¤ÉƱ¤¸¤Ç¤¹¤¬¡¢´Êñ¤ÊÀèƬ¤«¤é¤Î¥Þ¥Ã¥Á¤ò¹Ô¤Ê¤¦¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ɸ½àÀµµ¬É½¸½¤òÍøÍѤ·¤Þ¤¹¡£¤³¤³¤Ç»ØÄꤵ¤ì¤¿Àµµ¬É½¸½¤È URL ¤Î¥Ñ¥¹ + ¤¬¹ç¤¦¤«¤É¤¦¤«¤òÄ´¤Ù¡¢¹ç¤¦¾ì¹ç¤Ï³ç¸Ì¤Ç³ç¤é¤ì¤¿¥Þ¥Ã¥Á¤ò + Í¿¤¨¤é¤ì¤¿Ê¸»úÎó¤ÇÃÖ¤­´¹¤¨¡¢¤½¤ì¤ò¥Õ¥¡¥¤¥ë̾¤È¤·¤Æ»ÈÍѤ·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ + /icons ¥Ç¥£¥ì¥¯¥È¥ê¤ò»È¤¦ + ¤¿¤á¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤¬»ÈÍѤǤ­¤Þ¤¹:

    + +

    + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 +

    + +
    +
    top
    +

    Redirect ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò +Á÷¤ë
    ¹½Ê¸:Redirect [status] URL-path +URL
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    Redirect ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¸Å¤¤ URL ¤ò¿·¤·¤¤¤â¤Î¤Ø¥Þ¥Ã¥×¤·¤Þ¤¹¡£ + ¿·¤·¤¤ URL ¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¤Þ¤¹¡£¤½¤·¤Æ¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤Ï¿·¤·¤¤¥¢¥É¥ì¥¹¤ò¤â¤¦°ì²ó¼èÆÀ¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + URL-path (% ¤¬Éü¹æ¤µ¤ì¤¿) ¥Ñ¥¹¤Ç»Ï¤Þ¤ë¥É¥­¥å¥á¥ó¥È¤Ø¤Î + ¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤Ï URL ¤Ç»Ï¤Þ¤ë¿·¤·¤¤ + (% ¤¬Éä¹æ²½¤µ¤ì¤¿) URL ¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¥¨¥é¡¼¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + Redirect /service http://foo2.bar.com/service +

    + +

    ¥¯¥é¥¤¥¢¥ó¥È¤Ï http://myserver/service/foo.txt + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤Ê¤¦¤È¡¢Âå¤ï¤ê¤Ë http://foo2.bar.com/service/foo.txt + ¤ò¥¢¥¯¥»¥¹¤¹¤ë¤è¤¦¤Ë¹ð¤²¤é¤ì¤Þ¤¹¡£

    + +

    Ãí°Õ

    ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î½çÈ֤˴ؤï¤é¤º¡¢ +Redirect ·Ï¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Alias +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È ScriptAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤è¤ê¤âÍ¥À褵¤ì¤Þ¤¹¡£ +¤Þ¤¿¡¢.htaccess ¥Õ¥¡¥¤¥ë¤ä <Directory> +¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ç»È¤ï¤ì¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢URL-path +¤ÏÁêÂХѥ¹¤Ç¤Ï¤Ê¤¯¡¢´°Á´¤Ê URL ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¤â¤· status °ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¥ê¥À¥¤¥ì¥¯¥È¤Ï + "temporary" (HTTP ¥¹¥Æ¡¼¥¿¥¹ 302) ¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë + ¥ê¥½¡¼¥¹¤¬°ì»þŪ¤Ë°ÜÆ°¤·¤¿¤È¤¤¤¦¤³¤È¤ò¼¨¤·¤Þ¤¹¡£Status + °ú¿ô¤Ï ¾¤Î HTTP ¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤òÊÖ¤¹¤¿¤á¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    permanent
    + +
    ±Êµ×¤Ë¥ê¥À¥¤¥ì¥¯¥È¤ò¤¹¤ë¥¹¥Æ¡¼¥¿¥¹ (301) ¤òÊÖ¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¥ê¥½¡¼¥¹¤¬±Êµ×¤Ë°ÜÆ°¤·¤¿¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
    + +
    temp
    + +
    °ì»þŪ¤Ê¥ê¥À¥¤¥ì¥¯¥È¥¹¥Æ¡¼¥¿¥¹ (302) + ¤òÊÖ¤·¤Þ¤¹¡£¤³¤ì¤¬¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£
    + +
    seeother
    + +
    "See Other" ¥¹¥Æ¡¼¥¿¥¹ (303) ¤òÊÖ¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¥ê¥½¡¼¥¹¤¬Â¾¤Î¤â¤Î¤ÇÃÖ¤­´¹¤¨¤é¤ì¤¿¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£
    + +
    gone
    + +
    "Gone" ¥¹¥Æ¡¼¥¿¥¹ (410) ¤òÊÖ¤·¤Þ¤¹¡£¤³¤ì¤Ï¥ê¥½¡¼¥¹¤¬±Êµ×¤Ë + ºï½ü¤µ¤ì¤¿¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£¤³¤Î¥¹¥Æ¡¼¥¿¥¹¤¬»ÈÍѤµ¤ì¤¿¾ì¹ç¡¢ + url °ú¿ô¤Ï¾Êά¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
    +
    + +

    Status ¤ÎÃͤ˥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤ò¿ôÃͤÇÍ¿¤¨¤ë¤³¤È¤Ç + ¾¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤âÊÖ¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥¹¥Æ¡¼¥¿¥¹¤¬ 300 ¤È 399 + ¤Î´Ö¤Ë¤¢¤ë¾ì¹ç¡¢url °ú¿ô¤Ï¸ºß¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ + ¤½¤Î¾¤Î¾ì¹ç¤Ï¾Êά¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤¿¤À¤·¡¢ + ¥¹¥Æ¡¼¥¿¥¹¤Ï Apache ¤Î¥³¡¼¥É¤¬ÃΤäƤ¤¤ë¤â¤Î¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹ + (http_protocol.c ¤Î´Ø¿ô send_error_response + ¤ò¸«¤Æ¤¯¤À¤µ¤¤)¡£

    +

    Îã:

    + +

    Îã

    + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +

    + + +
    +
    top
    +

    RedirectMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¸½ºß¤Î URL ¤Ø¤ÎÀµµ¬É½¸½¤Î¥Þ¥Ã¥Á¤Ë¤è¤ê +³°Éô¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    ¹½Ê¸:RedirectMatch [status] regex +URL
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Redirect + ¤È¤Û¤È¤ó¤ÉƱ¤¸¤Ç¤¹¤¬¡¢´Êñ¤ÊÀèƬ¤«¤é¤Î¥Þ¥Ã¥Á¤ò¹Ô¤Ê¤¦¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ɸ½àÀµµ¬É½¸½¤òÍøÍѤ·¤Þ¤¹¡£¤³¤³¤Ç»ØÄꤵ¤ì¤¿Àµµ¬É½¸½¤È URL-path + ¤¬¹ç¤¦¤«¤É¤¦¤«¤òÄ´¤Ù¡¢¹ç¤¦¾ì¹ç¤Ï³ç¸Ì¤Ç³ç¤é¤ì¤¿¥Þ¥Ã¥Á¤ò + Í¿¤¨¤é¤ì¤¿Ê¸»úÎó¤ÇÃÖ¤­´¹¤¨¡¢¤½¤ì¤ò¥Õ¥¡¥¤¥ë̾¤È¤·¤Æ»ÈÍѤ·¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢¤¹¤Ù¤Æ¤Î GIF ¥Õ¥¡¥¤¥ë¤òÊÌ¥µ¡¼¥Ð¤ÎƱÍͤÊ̾Á°¤Î JPEG + ¥Õ¥¡¥¤¥ë¤Ë¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤Ë¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤ò»È¤¤¤Þ¤¹: +

    + +

    + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg +

    + +
    +
    top
    +

    RedirectPermanent ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î±Êµ×Ū¤Ê +¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    ¹½Ê¸:RedirectPermanent URL-path URL
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë Redirect ¤¬±Êµ×Ū¤Ê¤â¤Î + (¥¹¥Æ¡¼¥¿¥¹ 301) ¤Ç¤¢¤ë¤³¤È¤òÃΤ餻¤Þ¤¹¡£ + Redirect permanent ¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤Ç¤¹¡£

    + +
    +
    top
    +

    RedirectTemp ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î°ì»þŪ¤Ê +¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    ¹½Ê¸:RedirectTemp URL-path URL
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë Redirect + ¤¬°ì»þŪ¤Ê¤â¤Î¤Ç¤¢¤ë (¥¹¥Æ¡¼¥¿¥¹ 302) ¤³¤È¤òÃΤ餻¤Þ¤¹¡£ + Redirect temp ¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤Ç¤¹¡£

    + +
    +
    top
    +

    ScriptAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤إޥåפ·¡¢¥Þ¥Ã¥×Àè¤ò +CGI ¥¹¥¯¥ê¥×¥È¤Ë»ØÄê
    ¹½Ê¸:ScriptAlias URL-path +file-path|directory-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ScriptAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Âоݥǥ£¥ì¥¯¥È¥ê¤Ë + mod_cgi ¤Î cgi-script + ¥Ï¥ó¥É¥é¤Ç½èÍý¤µ¤ì¤ë CGI + ¥¹¥¯¥ê¥×¥È¤¬¤¢¤ë¤³¤È¤ò¼¨¤¹°Ê³°¤Ï + Alias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱ¤¸¿¶¤ëÉñ¤¤¤ò¤·¤Þ¤¹¡£ + URL ¤Î (% ¤¬Éü¹æ¤µ¤ì¤¿) ¥Ñ¥¹¤¬ URL-path ¤Ç»Ï¤Þ¤ë¤â¤Î¤Ï + ¥í¡¼¥«¥ë¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î + ¥Õ¥ë¥Ñ¥¹¤Ç¤¢¤ëÆóÈÖÌܤΰú¿ô¤Ë¥Þ¥Ã¥×¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + ScriptAlias /cgi-bin/ /web/cgi-bin/ +

    + +

    http://myserver/cgi-bin/foo + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¥µ¡¼¥Ð¤Ï¥¹¥¯¥ê¥×¥È + /web/cgi-bin/foo ¤ò¼Â¹Ô¤·¤Þ¤¹¡£

    + +
    +
    top
    +

    ScriptAliasMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:URL ¤òÀµµ¬É½¸½¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤إޥåפ·¡¢¥Þ¥Ã¥×Àè¤ò +CGI ¥¹¥¯¥ê¥×¥È¤Ë»ØÄê
    ¹½Ê¸:ScriptAliasMatch regex +file-path|directory-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_alias
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï ScriptAlias + ¤È¤Û¤È¤ó¤ÉƱ¤¸¤Ç¤¹¤¬¡¢´Êñ¤ÊÀèƬ¤«¤é¤Î¥Þ¥Ã¥Á¤ò¹Ô¤Ê¤¦¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ɸ½àÀµµ¬É½¸½¤òÍøÍѤ·¤Þ¤¹¡£¤³¤³¤Ç»ØÄꤵ¤ì¤¿Àµµ¬É½¸½¤È URL-path + ¤¬¹ç¤¦¤«¤É¤¦¤«¤òÄ´¤Ù¡¢¹ç¤¦¾ì¹ç¤Ï³ç¸Ì¤Ç³ç¤é¤ì¤¿¥Þ¥Ã¥Á¤ò + Í¿¤¨¤é¤ì¤¿Ê¸»úÎó¤ÇÃÖ¤­´¹¤¨¡¢¤½¤ì¤ò¥Õ¥¡¥¤¥ë̾¤È¤·¤Æ»ÈÍѤ·¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢É¸½à¤Î /cgi-bin + ¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤ò»È¤¤¤Þ¤¹: +

    + +

    + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_alias.html.ko.euc-kr b/trunk/docs/manual/mod/mod_alias.html.ko.euc-kr new file mode 100644 index 0000000000..e9db1ef908 --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.html.ko.euc-kr @@ -0,0 +1,354 @@ + + + +mod_alias - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_alias

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐµéÀ» ¹®¼­ °èÃþ±¸Á¶¿¡ Æ÷ÇÔÇÏ°í, + URL ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:alias_module
    ¼Ò½ºÆÄÀÏ:mod_alias.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾îµéÀ» »ç¿ëÇÏ¿© ¼­¹ö°¡ ¿äûÀ» + ¹ÞÀ»¶§ URLÀ» ¼öÁ¤Çϰųª Á¶ÀÛÇÒ ¼ö ÀÖ´Ù. Alias¿Í ScriptAlias Áö½Ã¾î´Â URLÀ» + ÆÄÀϽýºÅÛ °æ·Î·Î ´ëÀÀÇÑ´Ù. ±×·¡¼­ DocumentRoot ¾Æ·¡¿¡ ¾ø´Â ³»¿ëÀ» + À¥À¸·Î ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù. ¶Ç, ScriptAlias Áö½Ã¾î´Â ÁöÁ¤ÇÑ + µð·ºÅ丮¿¡ CGI ½ºÅ©¸³Æ®¹Û¿¡ ¾ø´Ù°í ¾Ë¸°´Ù.

    + +

    Redirect Áö½Ã¾î´Â + Ŭ¶óÀ̾ðÆ®¿¡°Ô ´Ù¸¥ URL·Î »õ·Î¿î ¿äûÀ» Çϵµ·Ï Áö½ÃÇÑ´Ù. + ÀÚ¿øÀ» »õ·Î¿î Àå¼Ò·Î ¿Å±ä °æ¿ì ÀÚÁÖ »ç¿ëÇÑ´Ù.

    + +

    mod_alias´Â °£´ÜÇÑ URL Á¶ÀÛÀ» À§ÇØ + ¼³°èµÇ¾ú´Ù. ÁúÀǹ®ÀÚ¿­ Á¶ÀÛ°ú °°Àº º¹ÀâÇÑ ÀÛ¾÷Àº + mod_rewrite°¡ Á¦°øÇÏ´Â ±â´ÉÀ» ÀÌ¿ëÇ϶ó.

    + +
    + +
    top
    +
    +

    ó¸® ¼ø¼­

    + +

    ¼­·Î ´Ù¸¥ »ç¿ëÀå¼Ò¿¡¼­ Alias¿Í Redirect¸¦ »ç¿ëÇÏ¸é ´Ù¸¥ Áö½Ã¾î¿Í +°°ÀÌ Ç¥ÁØ °áÇÕ ¹æ¹ý¿¡ +µû¶ó ó¸®ÇÑ´Ù. ±×·¯³ª °°Àº »ç¿ëÀå¼Ò¿¡ (¿¹¸¦ µé¾î, °°Àº <VirtualHost> ¼½¼Ç¿¡) +Alias¿Í Redirect¸¦ »ç¿ëÇÏ¸é ¾Æ·¡ ¼ø¼­´ë·Î ó¸®ÇÑ´Ù.

    + +

    ¸ÕÀú ¸ðµç Redirect¸¦ ó¸®ÇÑ ÈÄ Alias¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ +Redirect³ª RedirectMatch¿¡ ÇØ´çÇÏ´Â ¿äûÀº +Àý´ë·Î AliasÇÏÁö ¾Ê´Â´Ù. ±×¸®°í Alias¿Í Redirect´Â ¼³Á¤ÆÄÀÏ¿¡¼­ +ù¹ø°·Î ³ª¿À´Â °ÍÀ» »ç¿ëÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ Áö½Ã¾î°¡ µ¿ÀÏÇÑ ÇÏÀ§°æ·Î¿¡ ÇØ´çÇÏ´Â °æ¿ì ¸ðµç +Áö½Ã¾î¸¦ Àû¿ëÇϱâÀ§Çؼ­´Â °¡Àå »ó¼¼ÇÑ °æ·Î¸¦ ¸ÕÀú »ç¿ëÇØ¾ß ÇÑ´Ù. +¿¹¸¦ µé¾î, ´ÙÀ½ ¼³Á¤Àº ÀǵµÇÑ´ë·Î µ¿ÀÛÇÑ´Ù:

    + +

    +Alias /foo/bar /baz
    +Alias /foo /gaq +

    + +

    ±×·¯³ª À§ÀÇ µÎ Áö½Ã¾î ¼ø¼­¸¦ ¹Ù²Ù¸é /foo/bar +Alias ÀÌÀü¿¡ +/foo Alias¸¦ +Àû¿ëÇϹǷΠÇ×»ó µÎ¹ø° Áö½Ã¾î¸¦ ¹«½ÃÇÑ´Ù.

    + +
    +
    top
    +

    Alias Áö½Ã¾î

    + + + + + + +
    ¼³¸í:URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÑ´Ù
    ¹®¹ý:Alias URL-path +file-path|directory-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    + +

    Alias Áö½Ã¾î¸¦ »ç¿ëÇϸé ÆÄÀϽýºÅÛ¿¡¼­ + DocumentRoot ¹Û¿¡ ÀÖ´Â + ¹®¼­µµ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù. url-path·Î ½ÃÀÛÇÏ´Â + (%·Î ÀÎÄÚµùµÈ) URLÀ» directory-path·Î ½ÃÀÛÇÏ´Â + ÆÄÀÏ¿¡ ´ëÀÀÇÑ´Ù.

    + +

    ¿¹Á¦:

    + Alias /image /ftp/pub/image +

    + +

    http://myserver/image/foo.gif¸¦ ¿äûÇÏ¸é ¼­¹ö´Â + /ftp/pub/image/foo.gif ÆÄÀÏÀ» ³Ñ°ÜÁØ´Ù.

    + +

    url-path ³¡¿¡ /¸¦ Æ÷ÇÔÇϸé, URL ³¡¿¡ /¸¦ + »ç¿ëÇؾ߸¸ ¿µÇâÀÌ ÀÖÀ½À» ÁÖÀÇÇ϶ó. Áï, Alias /icons/ + /usr/local/apache/icons/ ¼³Á¤Àº url /icons¿Í + °ü°è°¡ ¾ø´Ù.

    + +

    ´ëÀÀÀÇ ´ë»óÀ» Æ÷ÇÔÇÏ´Â ¿©·¯ <Directory> ¼½¼ÇÀÌ + ÇÊ¿äÇÒÁöµµ ¸ð¸¥´Ù. ÀÌ Áö½Ã¾î´Â <Directory> ¼½¼ÇÀ» °Ë»çÇϱâ Àü¿¡ + ó¸®ÇϹǷÎ, ´ëÀÀÀÇ ´ë»ó¸¸ ¼½¼ÇÀÇ ¿µÇâÀ» ¹Þ´Â´Ù. (±×·¯³ª + <Location> + ¼½¼ÇÀº ÀÌ Áö½Ã¾î¸¦ ó¸®Çϱâ Àü¿¡ Çѹø¸¸ °Ë»çÇϹǷΠÁöÁ¤ÇÑ + URL ÀÌÇÏ Àüü¿¡ ¿µÇâÀ» ÁØ´Ù.)

    + +

    ƯÈ÷ DocumentRoot + ¹Û¿¡ ÀÖ´Â µð·ºÅ丮·Î Alias¸¦ ¸¸µé¾ú´Ù¸é, Á÷Á¢ + ´ë»ó µð·ºÅ丮ÀÇ Á¢±ÙÀ» Çã¿ëÇØÁà¾ß ÇÑ´Ù.

    + +

    ¿¹Á¦:

    + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +

    + + +
    +
    top
    +

    AliasMatch Áö½Ã¾î

    + + + + + + +
    ¼³¸í:Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÑ´Ù
    ¹®¹ý:AliasMatch regex +file-path|directory-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ÀÌ Áö½Ã¾î´Â Alias¿Í + °°Áö¸¸, °£´ÜÈ÷ URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» + »ç¿ëÇÑ´Ù. ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, + ¼­¹ö´Â °ýÈ£·Î ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î, ´ÙÀ½°ú °°ÀÌ /icons µð·ºÅ丮¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù:

    + +

    + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 +

    + +
    +
    top
    +

    Redirect Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    ¹®¹ý:Redirect [status] URL-path +URL
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    Redirect Áö½Ã¾î´Â ÀÌÀü URLÀ» »õ·Î¿î URL·Î ´ëÀÀÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®¿¡°Ô »õ·Î¿î URLÀ» º¸³»°í, Ŭ¶óÀ̾ðÆ®´Â »õ·Î¿î + ÁÖ¼Ò·Î ´Ù½Ã Çѹø Á¢¼ÓÇÑ´Ù. (%·Î ÀÎÄÚµùµÈ) URL-path·Î + ½ÃÀÛÇÏ´Â ¿äûÀ» ¹ÞÀ¸¸é (%·Î ÀÎÄÚµùµÈ) URL·Î ½ÃÀÛÇÏ´Â + »õ·Î¿î URL·Î ¸®´ÙÀÌ·º¼Ç ¿À·ù¸¦ º¸³½´Ù.

    + +

    ¿¹Á¦:

    + Redirect /service http://foo2.bar.com/service +

    + +

    Ŭ¶óÀ̾ðÆ®°¡ http://myserver/service/foo.txt¸¦ ¿äûÇϸé + ´ë½Å http://foo2.bar.com/service/foo.txt¿¡ Á¢±ÙÇ϶ó´Â ÀÀ´äÀ» + ¹Þ´Â´Ù.

    + +

    ÁÖÀÇ

    Redirect Áö½Ã¾î´Â ¼³Á¤ÆÄÀÏ¿¡¼­ +³ª¿À´Â ¼ø¼­¿Í °ü°è¾øÀÌ Alias¿Í ScriptAlias Áö½Ã¾îº¸´Ù ¿ì¼±¼øÀ§°¡ +³ô´Ù. ¶Ç, .htaccess ÆÄÀÏÀ̳ª <Directory> ¼½¼Ç¿¡¼­ »ç¿ëÇÏ´õ¶óµµ +URL-path¿¡´Â »ó´ë°æ·Î°¡ ¾Æ´Ï¶ó ¹Ýµå½Ã ¿ÏÀüÇÑ URLÀ» +»ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    status ¾Æ±Ô¸ÕÆ®¸¦ ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é, "Àӽà + (temporary)" (HTTP »óÅ 302) ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. Áï, + Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÚ¿øÀ» Àӽ÷Π¿Å°å´Ù°í ¾Ë¸°´Ù. status + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÏ¿© ´Ù¸¥ HTTP »óÅÂÄڵ带 ¹ÝȯÇÒ ¼ö ÀÖ´Ù:

    + +
    +
    permanent
    + +
    ÀÚ¿øÀ» ¿ÏÀüÈ÷ ¿Å°åÀ½À» ¶æÇÏ´Â ¿µ±¸ ¸®´ÙÀÌ·º¼Ç »óŸ¦ + (301) ¹ÝȯÇÑ´Ù.
    + +
    temp
    + +
    Àӽà ¸®´ÙÀÌ·º¼Ç »óŸ¦ (302) ¹ÝȯÇÑ´Ù. ±âº»°ªÀÌ´Ù.
    + +
    seeother
    + +
    ÀÚ¿øÀÌ ±³Ã¼µÇ¾úÀ½À» ¶æÇÏ´Â "ÂüÁ¶ (See Other)" »óŸ¦ + (303) ¹ÝȯÇÑ´Ù.
    + +
    gone
    + +
    ÀÚ¿øÀÌ ¿µ±¸È÷ »èÁ¦µÇ¾úÀ½À» ¶æÇÏ´Â "¼Ò¸ê (Gone)" »óŸ¦ + (410) ¹ÝȯÇÑ´Ù. ÀÌ »óŸ¦ »ç¿ëÇϸé URL ¾Æ±Ô¸ÕÆ®¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    +
    + +

    status¿¡ ¼ýÀÚ »óÅÂÄڵ带 »ç¿ëÇÏ¿© ´Ù¸¥ »óÅÂÄڵ嵵 + ¹ÝȯÇÒ ¼ö ÀÖ´Ù. »óÅ°¡ 300°ú 399 »çÀ̶ó¸é URL + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇØ¾ß ÇÏ°í, ¾Æ´Ï¶ó¸é »ý·«ÇØ¾ß ÇÑ´Ù. ´Ü, ¾ÆÆÄÄ¡ + Äڵ忡 »óÅ°¡ Á¤ÀǵÇÀÖ¾î¾ß ÇÑ´Ù (http_protocol.cÀÇ + send_error_response ÇÔ¼ö Âü°í).

    + +

    ¿¹Á¦:

    + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +

    + + +
    +
    top
    +

    RedirectMatch Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÇöÀç URLÀÌ Á¤±ÔÇ¥Çö½Ä¿¡ ÇØ´çÇÏ¸é ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» +º¸³½´Ù
    ¹®¹ý:RedirectMatch [status] regex +URL
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ÀÌ Áö½Ã¾î´Â Redirect¿Í °°Áö¸¸, °£´ÜÈ÷ + URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÑ´Ù. + ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, ¼­¹ö´Â °ýÈ£·Î + ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½Àº + ¸ðµç GIF ÆÄÀÏ ¿äû¿¡ ´ëÇØ ´Ù¸¥ ¼­¹öÀÇ ºñ½ÁÇÑ À̸§À» °¡Áø + JPEG ÆÄÀÏ·Î ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù:

    + +

    + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg +

    + +
    +
    top
    +

    RedirectPermanent Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¿µ±¸ ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    ¹®¹ý:RedirectPermanent URL-path URL
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ÀÌ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀÌ ¿µ±¸ÀûÀÓÀ» (»óÅ + 301) ¾Ë¸°´Ù. Redirect permanent¿Í Á¤È®È÷ °°´Ù.

    + +
    +
    top
    +

    RedirectTemp Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +Àӽà ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    ¹®¹ý:RedirectTemp URL-path URL
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ÀÌ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀÌ ÀÓ½ÃÀûÀÓÀ» (»óÅ + 302) ¾Ë¸°´Ù. Redirect temp¿Í Á¤È®È÷ °°´Ù.

    + +
    +
    top
    +

    ScriptAlias Áö½Ã¾î

    + + + + + + +
    ¼³¸í:URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÏ°í ´ë»óÀÌ CGI +½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù
    ¹®¹ý:ScriptAlias URL-path +file-path|directory-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ScriptAlias Áö½Ã¾î´Â Alias Áö½Ã¾î¿Í ºñ½ÁÇÏÁö¸¸, + Ãß°¡·Î ´ë»ó µð·ºÅ丮¿¡ mod_cgiÀÇ cgi-script + Çڵ鷯°¡ ó¸®ÇÒ CGI ½ºÅ©¸³Æ®°¡ ÀÖ´Ù°í ¾Ë¸°´Ù. + URL-path·Î ½ÃÀÛÇÏ´Â (%·Î ÀÎÄÚµùµÈ) URLÀ» ÆÄÀϽýºÅÛÀÇ + Àý´ë°æ·ÎÀÎ µÎ¹ø° ¾Æ±Ô¸ÕÆ®·Î ½ÃÀÛÇÏ´Â ½ºÅ©¸³Æ®¿¡ ´ëÀÀÇÑ´Ù.

    + +

    ¿¹Á¦:

    + ScriptAlias /cgi-bin/ /web/cgi-bin/ +

    + +

    http://myserver/cgi-bin/foo¸¦ ¿äûÇÏ¸é ¼­¹ö´Â + /web/cgi-bin/foo ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù.

    + +
    +
    top
    +

    ScriptAliasMatch Áö½Ã¾î

    + + + + + + +
    ¼³¸í:Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÏ°í ´ë»óÀÌ CGI ½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù
    ¹®¹ý:ScriptAliasMatch regex +file-path|directory-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_alias
    +

    ÀÌ Áö½Ã¾î´Â ScriptAlias¿Í °°Áö¸¸, °£´ÜÈ÷ + URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÑ´Ù. + ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, ¼­¹ö´Â °ýÈ£·Î + ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°ÀÌ Ç¥ÁØÀûÀÎ /cgi-binÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + +

    + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_alias.xml b/trunk/docs/manual/mod/mod_alias.xml new file mode 100644 index 0000000000..7bd327bbb4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.xml @@ -0,0 +1,364 @@ + + + + + + + + + +mod_alias +Provides for mapping different parts of the host + filesystem in the document tree and for URL redirection +Base +mod_alias.c +alias_module + + +

    The directives contained in this module allow for manipulation + and control of URLs as requests arrive at the server. The + Alias and ScriptAlias directives are used to + map between URLs and filesystem paths. This allows for content + which is not directly under the DocumentRoot served as part of the web + document tree. The ScriptAlias directive has the + additional effect of marking the target directory as containing + only CGI scripts.

    + +

    The Redirect + directives are used to instruct clients to make a new request with + a different URL. They are often used when a resource has moved to + a new location.

    + +

    mod_alias is designed to handle simple URL + manipulation tasks. For more complicated tasks such as + manipulating the query string, use the tools provided by + mod_rewrite.

    + +
    + +mod_rewrite Mapping URLs to the filesystem + +
    Order of Processing + +

    Aliases and Redirects occuring in different contexts are processed +like other directives according to standard merging rules. But when multiple +Aliases or Redirects occur in the same context (for example, in the +same VirtualHost +section) they are processed in a particular order.

    + +

    First, all Redirects are processed before Aliases are processed, +and therefore a request that matches a Redirect or RedirectMatch will never have Aliases +applied. Second, the Aliases and Redirects are processed in the order +they appear in the configuration files, with the first match taking +precedence.

    + +

    For this reason, when two or more of these directives apply to the +same sub-path, you must list the most specific path first in order for +all the directives to have an effect. For example, the following +configuration will work as expected:

    + + +Alias /foo/bar /baz
    +Alias /foo /gaq +
    + +

    But if the above two directives were reversed in order, the +/foo Alias +would always match before the /foo/bar Alias, so the latter directive would be +ignored.

    + +
    + + +Alias +Maps URLs to filesystem locations +Alias URL-path +file-path|directory-path +server configvirtual host + + + + +

    The Alias directive allows documents to + be stored in the local filesystem other than under the + DocumentRoot. URLs with a + (%-decoded) path beginning with url-path will be mapped + to local files beginning with directory-path.

    + + Example: + Alias /image /ftp/pub/image + + +

    A request for http://myserver/image/foo.gif would cause the + server to return the file /ftp/pub/image/foo.gif.

    + +

    Note that if you include a trailing / on the + url-path then the server will require a trailing / in + order to expand the alias. That is, if you use Alias + /icons/ /usr/local/apache/icons/ then the url + /icons will not be aliased.

    + +

    Note that you may need to specify additional Directory sections which + cover the destination of aliases. Aliasing occurs before + Directory sections + are checked, so only the destination of aliases are affected. + (Note however Location + sections are run through once before aliases are performed, so + they will apply.)

    + +

    In particular, if you are creating an Alias to a + directory outside of your DocumentRoot, you may need to explicitly + permit access to the target directory.

    + + Example: + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +
    + +
    +
    + + +AliasMatch +Maps URLs to filesystem locations using regular +expressions +AliasMatch regex +file-path|directory-path +server configvirtual host + + + +

    This directive is equivalent to Alias, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, and + if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to activate the /icons directory, one might + use:

    + + + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 + +
    +
    + + +Redirect +Sends an external redirect asking the client to fetch +a different URL +Redirect [status] URL-path +URL +server configvirtual host +directory.htaccess +FileInfo + + +

    The Redirect directive maps an old URL into a new one. The + new URL is returned to the client which attempts to fetch it + again with the new address. URL-path a (%-decoded) + path; any requests for documents beginning with this path will + be returned a redirect error to a new (%-encoded) URL beginning + with URL.

    + + Example: + Redirect /service http://foo2.bar.com/service + + +

    If the client requests http://myserver/service/foo.txt, it + will be told to access http://foo2.bar.com/service/foo.txt + instead.

    + +Note

    Redirect directives take precedence over +Alias and ScriptAlias directives, irrespective of their ordering in +the configuration file. Also, URL-path must be a fully +qualified URL, not a relative path, even when used with .htaccess files or +inside of Directory +sections.

    + +

    If no status argument is given, the redirect will + be "temporary" (HTTP status 302). This indicates to the client + that the resource has moved temporarily. The status + argument can be used to return other HTTP status codes:

    + +
    +
    permanent
    + +
    Returns a permanent redirect status (301) indicating that + the resource has moved permanently.
    + +
    temp
    + +
    Returns a temporary redirect status (302). This is the + default.
    + +
    seeother
    + +
    Returns a "See Other" status (303) indicating that the + resource has been replaced.
    + +
    gone
    + +
    Returns a "Gone" status (410) indicating that the + resource has been permanently removed. When this status is + used the URL argument should be omitted.
    +
    + +

    Other status codes can be returned by giving the numeric + status code as the value of status. If the status is + between 300 and 399, the URL argument must be present, + otherwise it must be omitted. Note that the status must be + known to the Apache code (see the function + send_error_response in http_protocol.c).

    + + Example: + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +
    + +
    +
    + + +RedirectMatch +Sends an external redirect based on a regular expression match +of the current URL +RedirectMatch [status] regex +URL +server configvirtual host +directory.htaccess +FileInfo + + +

    This directive is equivalent to Redirect, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, and + if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to redirect all GIF files to like-named JPEG files on + another server, one might use:

    + + + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg + +
    +
    + + +RedirectTemp +Sends an external temporary redirect asking the client to fetch +a different URL +RedirectTemp URL-path URL +server configvirtual host +directory.htaccess +FileInfo + + +

    This directive makes the client know that the Redirect is + only temporary (status 302). Exactly equivalent to + Redirect temp.

    +
    +
    + + +RedirectPermanent +Sends an external permanent redirect asking the client to fetch +a different URL +RedirectPermanent URL-path URL +server configvirtual host +directory.htaccess +FileInfo + + +

    This directive makes the client know that the Redirect is + permanent (status 301). Exactly equivalent to Redirect + permanent.

    +
    +
    + + +ScriptAlias +Maps a URL to a filesystem location and designates the +target as a CGI script +ScriptAlias URL-path +file-path|directory-path +server configvirtual host + + + +

    The ScriptAlias directive has the same + behavior as the Alias + directive, except that in addition it marks the target directory + as containing CGI scripts that will be processed by mod_cgi's cgi-script handler. URLs with a + (%-decoded) path beginning with URL-path will be mapped + to scripts beginning with the second argument which is a full + pathname in the local filesystem.

    + + Example: + ScriptAlias /cgi-bin/ /web/cgi-bin/ + + +

    A request for http://myserver/cgi-bin/foo would cause the + server to run the script /web/cgi-bin/foo.

    +
    +
    + + +ScriptAliasMatch +Maps a URL to a filesystem location using a regular expression +and designates the target as a CGI script +ScriptAliasMatch regex +file-path|directory-path +server configvirtual host + + + +

    This directive is equivalent to ScriptAlias, but makes use of standard + regular expressions, instead of simple prefix matching. The + supplied regular expression is matched against the URL-path, + and if it matches, the server will substitute any parenthesized + matches into the given string and use it as a filename. For + example, to activate the standard /cgi-bin, one + might use:

    + + + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_alias.xml.ja b/trunk/docs/manual/mod/mod_alias.xml.ja new file mode 100644 index 0000000000..7d54b2688b --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.xml.ja @@ -0,0 +1,378 @@ + + + + + + + + + +mod_alias +$B%[%9%H%U%!%$%k%7%9%F%`>e$N$$$m$$$m$J0c$&>l=j$r(B + $B%I%-%e%a%s%H%D%j!<$K%^%C%W$9$k5!G=$H!"(B + URL $B$N%j%@%$%l%/%H$r9T$J$&5!G=$rDs6!$9$k(B +Base +mod_alias.c +alias_module + + +

    $B$3$N%b%8%e!<%k$N%G%#%l%/%F%#%V$O%5!<%P$K%j%/%(%9%H$,E~Ce$7$?$H$-$K(B + URL $B$NA`:n$d@)8f$r$9$k$3$H$r2DG=$K$7$^$9!#(BAlias + $B%G%#%l%/%F%#%V$H(B ScriptAlias + $B%G%#%l%/%F%#%V$O(B + URL $B$H%U%!%$%k%7%9%F%`$N%Q%9$r%^%C%W$9$k$?$a$K;HMQ$5$l$^$9!#$3$l$O(B + DocumentRoot + $B$N2<$K$J$$%I%-%e%a%s%H$r%&%'%V$N%I%-%e%a%s%H%D%j!<$N0lIt$H$7$F(B + $BAw$i$l$k$h$&$K$7$^$9!#(BScriptAlias + $B%G%#%l%/%F%#%V$K$O%^%C%W@h$N%G%#%l%/%H%j$,(B CGI + $B%9%/%j%W%H$N$_$G$"$k$3$H$r<($9$H$$$&DI2C$N8z2L$,$"$j$^$9!#(B +

    + +

    Redirect $B%G%#%l%/%F%#%V$O(B + $B%/%i%$%"%s%H$K0c$C$?(B + URL $B$K?7$7$$%j%/%(%9%H$rAw$k$h$&$K;X<($7$^$9!#$3$l$O!"(B + $B%j%=!<%9$,?7$7$$>l=j$K0\F0$7$?$H$-$K$h$/;HMQ$5$l$^$9!#(B

    + +

    mod_alias $B$O4JC1$J(B URL $BA`:n8~$1$K@_7W$5$l$F$$$^$9!#(B + $B$h$jJ#;($JA`:n!"%/%(%j!<%9%H%j%s%0$NA`:n$K$O!"(Bmod_rewrite + $B$GDs6!$5$l$k%D!<%k$r;HMQ$7$F$/$@$5$$!#(B

    + +
    + +mod_rewrite URL $B$+$i%U%!%$%k%7%9%F%`>e$N0LCV$X$N%^%C%T%s%0(B + +
    $B=hM}$N=gHV(B + +

    $BMM!9$J%3%s%F%-%9%HCf$G$N(B Alias $B$d(B Redirect $B$OB>$N%G%#%l%/%F%#%V$H(B +$BF1$8$h$&$KI8=`$N(B $B%^!<%85,B'(B $B$K(B +$B=>$C$F=hM}$5$l$^$9!#$?$@$7!"(B($BNc$($P(B VirtualHost $B%;%/%7%g%s$NCf$N$h$&$K(B) $BJ#?t$N(B Alias $B$d(B Redirect $B$,(B +$BF1$8%3%s%F%-%9%HCf$K8=$l$?>l9g$O7h$^$C$?=gHV$G=hM}$5$l$^$9!#(B

    + +

    $B$^$:!"(BAlias $B$NA0$K$9$Y$F$N(B Redirect $B$,=hM}$5$l$^$9!#$G$9$+$i!"(BRedirect $B$+(B RedirectMatch $B$K%^%C%A$9$k%j%/%(%9%H$K$O(B +Alias $B$O7h$7$FE,MQ$5$l$^$;$s!# + +

    $B$G$9$+$i!"Fs$D0J>e$N%G%#%l%/%F%#%V$,F1$8%Q%9$KE,MQ$5$l$k$H$-$O!"(B +$B$9$Y$F$N%G%#%l%/%F%#%V$N8z2L$rF@$k$?$a$K$O$h$j>\$7$$%Q%9$r@h$K=q$/(B +$BI,MW$,$"$j$^$9!#Nc$($P!" + + +Alias /foo/bar /baz
    +Alias /foo /gaq +
    + +

    $B$7$+$7!">e5-$NFs$D$N%G%#%l%/%F%#%V$N=gHV$,5U$K$J$k$H!"(B +/foo Alias $B$,(B +$B>o$K(B /foo/bar Alias $B$h$j@h$K%^%C%A$7$^$9$N$G!"8e + +

    + + +Alias +URL $B$r%U%!%$%k%7%9%F%`$N0LCV$K%^%C%W$9$k(B +Alias URL-path +file-path|directory-path +server config +virtual host + + + +

    Alias $B%G%#%l%/%F%#%V$O%I%-%e%a%s%H$r(B + $B%m!<%+%k%U%!%$%k%7%9%F%`$N(B + DocumentRoot + $B0J30$N>l=j$KJ]4I$9$k$3$H$r2DG=$K$7$^$9!#(B + URL $B$N(B (% $B$,I|9f$5$l$?(B) $B%Q%9$,(B url-path $B$G;O$^$k$b$N$O(B + directory-filename + $B$G;O$^$k%m!<%+%k%U%!%$%k$K%^%C%W$5$l$^$9!#(B

    + + $BNc(B + Alias /image /ftp/pub/image + + +

    http://myserver/image/foo.gif $B$X$N%j%/%(%9%H$KBP$7$F!"%5!<%P$O(B + $B%U%!%$%k(B /ftp/pub/image/foo.gif $B$rJV$7$^$9!#(B

    + +

    $B$b$7(B url-path $B$N:G8e$K(B / + $B$r=q$$$?$J$i!"%5!<%P$,%(%$%j%"%9$rE83+$9$k$?$a$K$O!":G8e$N(B / + $B$,I,MW$K$J$k$3$H$KCm0U$7$F$/$@$5$$!#$9$J$o$A!"(BAlias /icons/ + /usr/local/apache/icons/ $B$H$$$&$b$N$r;HMQ$7$F$$$k>l9g$O!"(B + /icons $B$H$$$&(B url $B$O%(%$%j%"%9$5$l$^$;$s!#(B

    + +

    $B%(%$%j%"%9$N(B$B9T$-@h(B$B$r4^$s$G$$$k(B Directory + $B%;%/%7%g%s$rDI2C$9$kI,MW$,$"$k$+$b$7$l$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B + $B%(%$%j%"%9$NE83+$O(B Directory + $B%;%/%7%g%s$rD4$Y$kA0$K9T$J$o$l$^$9$N$G!"(B + $B%(%$%j%"%9$N9T$-@h$N(B Directory $B%;%/%7%g%s$N$_(B + $B8z2L$,$"$j$^$9!#(B + ($B$7$+$7!"(BLocation + $B%;%/%7%g%s$O%(%$%j%"%9$,=hM}$5$l$kA0$K + +

    $BFC$K!"(BAlias $B$r(B + DocumentRoot + $B%G%#%l%/%H%j$N30B&$KG[CV$7$?>l9g$O!"9T$-@h$N%G%#%l%/%H%j$KBP$9$k(B + $B%"%/%;%98"8B$rL@<(E*$K@)8B$7$J$1$l$P$J$i$J$$$G$7$g$&!#(B

    + + $BNc(B + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +
    + +
    +
    + + +AliasMatch +$B@55,I=8=$r;H$C$F(B URL $B$r%U%!%$%k%7%9%F%`$N0LCV$K%^%C%W$9$k(B +AliasMatch regex +file-path|directory-path +server config +virtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O(B Alias + $B$H$[$H$s$IF1$8$G$9$,!"4JC1$J@hF,$+$i$N%^%C%A$r9T$J$&$N$G$O$J$/!"(B + $BI8=`@55,I=8=$rMxMQ$7$^$9!#$3$3$G;XDj$5$l$?@55,I=8=$H(B URL $B$N%Q%9(B + $B$,9g$&$+$I$&$+$rD4$Y!"9g$&>l9g$O3g8L$G3g$i$l$?%^%C%A$r(B + $BM?$($i$l$?J8;zNs$GCV$-49$(!"$=$l$r%U%!%$%kL>$H$7$F;HMQ$7$^$9!#$?$H$($P!"(B + /icons $B%G%#%l%/%H%j$r;H$&(B + $B$?$a$K$O0J2<$N$h$&$J$b$N$,;HMQ$G$-$^$9(B:

    + + + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 + +
    +
    + + +Redirect +$B%/%i%$%"%s%H$,0c$&(B URL $B$r +Redirect [status] URL-path +URL +server config +virtual host +directory.htaccess +FileInfo + + +

    Redirect $B%G%#%l%/%F%#%V$O8E$$(B URL $B$r?7$7$$$b$N$X%^%C%W$7$^$9!#(B + $B?7$7$$(B URL $B$,%/%i%$%"%s%H$KJV$5$l$^$9!#$=$7$F!"(B + $B%/%i%$%"%s%H$O?7$7$$%"%I%l%9$r$b$&0l2sURL-path (% $B$,I|9f$5$l$?(B) $B%Q%9$G;O$^$k%I%-%e%a%s%H$X$N(B + $B$9$Y$F$N%j%/%(%9%H$O(B URL $B$G;O$^$k?7$7$$(B + (% $B$,Id9f2=$5$l$?(B) URL $B$X$N%j%@%$%l%/%H%(%i!<$,JV$5$l$^$9!#(B

    + + $BNc(B + Redirect /service http://foo2.bar.com/service + + +

    $B%/%i%$%"%s%H$O(B http://myserver/service/foo.txt + $B$X$N%j%/%(%9%H$r9T$J$&$H!"Be$o$j$K(B http://foo2.bar.com/service/foo.txt + $B$r%"%/%;%9$9$k$h$&$K9p$2$i$l$^$9!#(B

    + +$BCm0U(B

    $B@_Dj%U%!%$%kCf$N=gHV$K4X$o$i$:!"(B +Redirect $B7O$N%G%#%l%/%F%#%V$O(B Alias +$B%G%#%l%/%F%#%V$H(B ScriptAlias $B%G%#%l%/%F%#%V$h$j$bM%@h$5$l$^$9!#(B +$B$^$?!"(B.htaccess $B%U%!%$%k$d(B Directory +$B%;%/%7%g%s$NCf$G;H$o$l$F$$$?$H$7$F$b!"(BURL-path +$B$OAjBP%Q%9$G$O$J$/!"40A4$J(B URL $B$G$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B$b$7(B status $B0z?t$,M?$($i$l$F$$$J$1$l$P!"%j%@%$%l%/%H$O(B + "temporary" (HTTP $B%9%F!<%?%9(B 302) $B$K$J$j$^$9!#$3$l$O%/%i%$%"%s%H$K(B + $B%j%=!<%9$,0l;~E*$K0\F0$7$?$H$$$&$3$H$r<($7$^$9!#(BStatus + $B0z?t$O(B $BB>$N(B HTTP $B$N%9%F!<%?%9%3!<%I$rJV$9$?$a$K;HMQ$9$k$3$H$,$G$-$^$9(B:

    + +
    +
    permanent
    + +
    $B1J5W$K%j%@%$%l%/%H$r$9$k%9%F!<%?%9(B (301) $B$rJV$7$^$9!#(B + $B$3$l$O%j%=!<%9$,1J5W$K0\F0$7$?$H$$$&$3$H$r0UL#$7$^$9!#(B
    + +
    temp
    + +
    $B0l;~E*$J%j%@%$%l%/%H%9%F!<%?%9(B (302) + $B$rJV$7$^$9!#$3$l$,%G%U%)%k%H$G$9!#(B
    + +
    seeother
    + +
    "See Other" $B%9%F!<%?%9(B (303) $B$rJV$7$^$9!#(B + $B$3$l$O%j%=!<%9$,B>$N$b$N$GCV$-49$($i$l$?$3$H$r0UL#$7$^$9!#(B
    + +
    gone
    + +
    "Gone" $B%9%F!<%?%9(B (410) $B$rJV$7$^$9!#$3$l$O%j%=!<%9$,1J5W$K(B + $B:o=|$5$l$?$3$H$r0UL#$7$^$9!#$3$N%9%F!<%?%9$,;HMQ$5$l$?>l9g!"(B + url $B0z?t$O>JN,$5$l$J$1$l$P$J$j$^$;$s!#(B
    +
    + +

    Status $B$NCM$K%9%F!<%?%9%3!<%I$r?tCM$GM?$($k$3$H$G(B + $BB>$N%9%F!<%?%9%3!<%I$bJV$9$3$H$,$G$-$^$9!#%9%F!<%?%9$,(B 300 $B$H(B 399 + $B$N4V$K$"$k>l9g!"(Burl $B0z?t$OB8:_$7$F$$$J$1$l$P$$$1$^$;$s!#(B + $B$=$NB>$N>l9g$O>JN,$5$l$F$$$J$1$l$P$J$j$^$;$s!#$?$@$7!"(B + $B%9%F!<%?%9$O(B Apache $B$N%3!<%I$,CN$C$F$$$k$b$N$G$"$kI,MW$,$"$j$^$9(B + (http_protocol.c $B$N4X?t(B send_error_response + $B$r8+$F$/$@$5$$(B)$B!#(B

    +

    $BNc(B:

    + + $BNc(B + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +
    + +
    +
    + + +RedirectMatch +$B8=:_$N(B URL $B$X$N@55,I=8=$N%^%C%A$K$h$j(B +$B30It$X$N%j%@%$%l%/%H$rAw$k(B +RedirectMatch [status] regex +URL +server config +virtual host +directory.htaccess +FileInfo + + +

    $B$3$N%G%#%l%/%F%#%V$O(B Redirect + $B$H$[$H$s$IF1$8$G$9$,!"4JC1$J@hF,$+$i$N%^%C%A$r9T$J$&$N$G$O$J$/!"(B + $BI8=`@55,I=8=$rMxMQ$7$^$9!#$3$3$G;XDj$5$l$?@55,I=8=$H(B URL-path + $B$,9g$&$+$I$&$+$rD4$Y!"9g$&>l9g$O3g8L$G3g$i$l$?%^%C%A$r(B + $BM?$($i$l$?J8;zNs$GCV$-49$(!"$=$l$r%U%!%$%kL>$H$7$F;HMQ$7$^$9!#(B + $B$?$H$($P!"$9$Y$F$N(B GIF $B%U%!%$%k$rJL%5!<%P$NF1MM$JL>A0$N(B JPEG + $B%U%!%$%k$K%j%@%$%l%/%H$9$k$K$O!"0J2<$N$h$&$J$b$N$r;H$$$^$9(B: +

    + + + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg + +
    +
    + + +RedirectTemp +$B%/%i%$%"%s%H$,0c$&(B URL $B$r +RedirectTemp URL-path URL +server config +virtual host +directory.htaccess +FileInfo + + +

    $B$3$N%G%#%l%/%F%#%V$O%/%i%$%"%s%H$K(B Redirect + $B$,0l;~E*$J$b$N$G$"$k(B ($B%9%F!<%?%9(B 302) $B$3$H$rCN$i$;$^$9!#(B + Redirect temp $B$H$^$C$?$/F1$8$G$9!#(B

    +
    +
    + + +RedirectPermanent +$B%/%i%$%"%s%H$,0c$&(B URL $B$r +RedirectPermanent URL-path URL +server config +virtual host +directory.htaccess +FileInfo + + +

    $B$3$N%G%#%l%/%F%#%V$O%/%i%$%"%s%H$K(B Redirect $B$,1J5WE*$J$b$N(B + ($B%9%F!<%?%9(B 301) $B$G$"$k$3$H$rCN$i$;$^$9!#(B + Redirect permanent $B$H$^$C$?$/F1$8$G$9!#(B

    +
    +
    + + +ScriptAlias +URL $B$r%U%!%$%k%7%9%F%`$N0LCV$X%^%C%W$7!"%^%C%W@h$r(B +CGI $B%9%/%j%W%H$K;XDj(B +ScriptAlias URL-path +file-path|directory-path +server config +virtual host + + + +

    ScriptAlias $B%G%#%l%/%F%#%V$O!"BP>]%G%#%l%/%H%j$K(B + mod_cgi $B$N(B cgi-script + $B%O%s%I%i$G=hM}$5$l$k(B CGI + $B%9%/%j%W%H$,$"$k$3$H$r<($90J30$O(B + Alias + $B%G%#%l%/%F%#%V$HF1$8?6$kIq$$$r$7$^$9!#(B + URL $B$N(B (% $B$,I|9f$5$l$?(B) $B%Q%9$,(B URL-path $B$G;O$^$k$b$N$O(B + $B%m!<%+%k$N%U%!%$%k%7%9%F%`$N(B + $B%U%k%Q%9$G$"$kFsHVL\$N0z?t$K%^%C%W$5$l$^$9!#(B

    + + $BNc(B + ScriptAlias /cgi-bin/ /web/cgi-bin/ + + +

    http://myserver/cgi-bin/foo + $B$X$N%j%/%(%9%H$KBP$7$F%5!<%P$O%9%/%j%W%H(B + /web/cgi-bin/foo $B$r + + + + +ScriptAliasMatch +URL $B$r@55,I=8=$r;H$C$F%U%!%$%k%7%9%F%`$N0LCV$X%^%C%W$7!"%^%C%W@h$r(B +CGI $B%9%/%j%W%H$K;XDj(B +ScriptAliasMatch regex +file-path|directory-path +server config +virtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O(B ScriptAlias + $B$H$[$H$s$IF1$8$G$9$,!"4JC1$J@hF,$+$i$N%^%C%A$r9T$J$&$N$G$O$J$/!"(B + $BI8=`@55,I=8=$rMxMQ$7$^$9!#$3$3$G;XDj$5$l$?@55,I=8=$H(B URL-path + $B$,9g$&$+$I$&$+$rD4$Y!"9g$&>l9g$O3g8L$G3g$i$l$?%^%C%A$r(B + $BM?$($i$l$?J8;zNs$GCV$-49$(!"$=$l$r%U%!%$%kL>$H$7$F;HMQ$7$^$9!#(B + $B$?$H$($P!"I8=`$N(B /cgi-bin + $B$r;HMQ$9$k$h$&$K$9$k$?$a$K$O!"0J2<$N$h$&$J$b$N$r;H$$$^$9(B: +

    + + + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_alias.xml.ko b/trunk/docs/manual/mod/mod_alias.xml.ko new file mode 100644 index 0000000000..115d18ebf2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.xml.ko @@ -0,0 +1,341 @@ + + + + + + + + + +mod_alias +ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐµéÀ» ¹®¼­ °èÃþ±¸Á¶¿¡ Æ÷ÇÔÇÏ°í, + URL ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÑ´Ù +Base +mod_alias.c +alias_module + + +

    ÀÌ ¸ðµâÀÌ Á¦°øÇÏ´Â Áö½Ã¾îµéÀ» »ç¿ëÇÏ¿© ¼­¹ö°¡ ¿äûÀ» + ¹ÞÀ»¶§ URLÀ» ¼öÁ¤Çϰųª Á¶ÀÛÇÒ ¼ö ÀÖ´Ù. Alias¿Í ScriptAlias Áö½Ã¾î´Â URLÀ» + ÆÄÀϽýºÅÛ °æ·Î·Î ´ëÀÀÇÑ´Ù. ±×·¡¼­ DocumentRoot ¾Æ·¡¿¡ ¾ø´Â ³»¿ëÀ» + À¥À¸·Î ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù. ¶Ç, ScriptAlias Áö½Ã¾î´Â ÁöÁ¤ÇÑ + µð·ºÅ丮¿¡ CGI ½ºÅ©¸³Æ®¹Û¿¡ ¾ø´Ù°í ¾Ë¸°´Ù.

    + +

    Redirect Áö½Ã¾î´Â + Ŭ¶óÀ̾ðÆ®¿¡°Ô ´Ù¸¥ URL·Î »õ·Î¿î ¿äûÀ» Çϵµ·Ï Áö½ÃÇÑ´Ù. + ÀÚ¿øÀ» »õ·Î¿î Àå¼Ò·Î ¿Å±ä °æ¿ì ÀÚÁÖ »ç¿ëÇÑ´Ù.

    + +

    mod_alias´Â °£´ÜÇÑ URL Á¶ÀÛÀ» À§ÇØ + ¼³°èµÇ¾ú´Ù. ÁúÀǹ®ÀÚ¿­ Á¶ÀÛ°ú °°Àº º¹ÀâÇÑ ÀÛ¾÷Àº + mod_rewrite°¡ Á¦°øÇÏ´Â ±â´ÉÀ» ÀÌ¿ëÇ϶ó.

    + +
    + +mod_rewrite URLÀ» ÆÄÀϽýºÅÛ¿¡ ´ëÀÀ + +
    ó¸® ¼ø¼­ + +

    ¼­·Î ´Ù¸¥ »ç¿ëÀå¼Ò¿¡¼­ Alias¿Í Redirect¸¦ »ç¿ëÇÏ¸é ´Ù¸¥ Áö½Ã¾î¿Í +°°ÀÌ Ç¥ÁØ °áÇÕ ¹æ¹ý¿¡ +µû¶ó ó¸®ÇÑ´Ù. ±×·¯³ª °°Àº »ç¿ëÀå¼Ò¿¡ (¿¹¸¦ µé¾î, °°Àº VirtualHost ¼½¼Ç¿¡) +Alias¿Í Redirect¸¦ »ç¿ëÇÏ¸é ¾Æ·¡ ¼ø¼­´ë·Î ó¸®ÇÑ´Ù.

    + +

    ¸ÕÀú ¸ðµç Redirect¸¦ ó¸®ÇÑ ÈÄ Alias¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ +Redirect³ª RedirectMatch¿¡ ÇØ´çÇÏ´Â ¿äûÀº +Àý´ë·Î AliasÇÏÁö ¾Ê´Â´Ù. ±×¸®°í Alias¿Í Redirect´Â ¼³Á¤ÆÄÀÏ¿¡¼­ +ù¹ø°·Î ³ª¿À´Â °ÍÀ» »ç¿ëÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ Áö½Ã¾î°¡ µ¿ÀÏÇÑ ÇÏÀ§°æ·Î¿¡ ÇØ´çÇÏ´Â °æ¿ì ¸ðµç +Áö½Ã¾î¸¦ Àû¿ëÇϱâÀ§Çؼ­´Â °¡Àå »ó¼¼ÇÑ °æ·Î¸¦ ¸ÕÀú »ç¿ëÇØ¾ß ÇÑ´Ù. +¿¹¸¦ µé¾î, ´ÙÀ½ ¼³Á¤Àº ÀǵµÇÑ´ë·Î µ¿ÀÛÇÑ´Ù:

    + + +Alias /foo/bar /baz
    +Alias /foo /gaq +
    + +

    ±×·¯³ª À§ÀÇ µÎ Áö½Ã¾î ¼ø¼­¸¦ ¹Ù²Ù¸é /foo/bar +Alias ÀÌÀü¿¡ +/foo Alias¸¦ +Àû¿ëÇϹǷΠÇ×»ó µÎ¹ø° Áö½Ã¾î¸¦ ¹«½ÃÇÑ´Ù.

    + +
    + + +Alias +URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÑ´Ù +Alias URL-path +file-path|directory-path +server configvirtual host + + + + +

    Alias Áö½Ã¾î¸¦ »ç¿ëÇϸé ÆÄÀϽýºÅÛ¿¡¼­ + DocumentRoot ¹Û¿¡ ÀÖ´Â + ¹®¼­µµ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù. url-path·Î ½ÃÀÛÇÏ´Â + (%·Î ÀÎÄÚµùµÈ) URLÀ» directory-path·Î ½ÃÀÛÇÏ´Â + ÆÄÀÏ¿¡ ´ëÀÀÇÑ´Ù.

    + + ¿¹Á¦: + Alias /image /ftp/pub/image + + +

    http://myserver/image/foo.gif¸¦ ¿äûÇÏ¸é ¼­¹ö´Â + /ftp/pub/image/foo.gif ÆÄÀÏÀ» ³Ñ°ÜÁØ´Ù.

    + +

    url-path ³¡¿¡ /¸¦ Æ÷ÇÔÇϸé, URL ³¡¿¡ /¸¦ + »ç¿ëÇؾ߸¸ ¿µÇâÀÌ ÀÖÀ½À» ÁÖÀÇÇ϶ó. Áï, Alias /icons/ + /usr/local/apache/icons/ ¼³Á¤Àº url /icons¿Í + °ü°è°¡ ¾ø´Ù.

    + +

    ´ëÀÀÀÇ ´ë»óÀ» Æ÷ÇÔÇÏ´Â ¿©·¯ Directory ¼½¼ÇÀÌ + ÇÊ¿äÇÒÁöµµ ¸ð¸¥´Ù. ÀÌ Áö½Ã¾î´Â Directory ¼½¼ÇÀ» °Ë»çÇϱâ Àü¿¡ + ó¸®ÇϹǷÎ, ´ëÀÀÀÇ ´ë»ó¸¸ ¼½¼ÇÀÇ ¿µÇâÀ» ¹Þ´Â´Ù. (±×·¯³ª + Location + ¼½¼ÇÀº ÀÌ Áö½Ã¾î¸¦ ó¸®Çϱâ Àü¿¡ Çѹø¸¸ °Ë»çÇϹǷΠÁöÁ¤ÇÑ + URL ÀÌÇÏ Àüü¿¡ ¿µÇâÀ» ÁØ´Ù.)

    + +

    ƯÈ÷ DocumentRoot + ¹Û¿¡ ÀÖ´Â µð·ºÅ丮·Î Alias¸¦ ¸¸µé¾ú´Ù¸é, Á÷Á¢ + ´ë»ó µð·ºÅ丮ÀÇ Á¢±ÙÀ» Çã¿ëÇØÁà¾ß ÇÑ´Ù.

    + + ¿¹Á¦: + Alias /image /ftp/pub/image
    + <Directory /ftp/pub/image>
    + + Order allow,deny
    + Allow from all
    +
    + </Directory> +
    + +
    +
    + + +AliasMatch +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÑ´Ù +AliasMatch regex +file-path|directory-path +server configvirtual host + + + +

    ÀÌ Áö½Ã¾î´Â Alias¿Í + °°Áö¸¸, °£´ÜÈ÷ URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» + »ç¿ëÇÑ´Ù. ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, + ¼­¹ö´Â °ýÈ£·Î ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î, ´ÙÀ½°ú °°ÀÌ /icons µð·ºÅ丮¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù:

    + + + AliasMatch ^/icons(.*) /usr/local/apache/icons$1 + +
    +
    + + +Redirect +Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù +Redirect [status] URL-path +URL +server configvirtual host +directory.htaccess +FileInfo + + +

    Redirect Áö½Ã¾î´Â ÀÌÀü URLÀ» »õ·Î¿î URL·Î ´ëÀÀÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®¿¡°Ô »õ·Î¿î URLÀ» º¸³»°í, Ŭ¶óÀ̾ðÆ®´Â »õ·Î¿î + ÁÖ¼Ò·Î ´Ù½Ã Çѹø Á¢¼ÓÇÑ´Ù. (%·Î ÀÎÄÚµùµÈ) URL-path·Î + ½ÃÀÛÇÏ´Â ¿äûÀ» ¹ÞÀ¸¸é (%·Î ÀÎÄÚµùµÈ) URL·Î ½ÃÀÛÇÏ´Â + »õ·Î¿î URL·Î ¸®´ÙÀÌ·º¼Ç ¿À·ù¸¦ º¸³½´Ù.

    + + ¿¹Á¦: + Redirect /service http://foo2.bar.com/service + + +

    Ŭ¶óÀ̾ðÆ®°¡ http://myserver/service/foo.txt¸¦ ¿äûÇϸé + ´ë½Å http://foo2.bar.com/service/foo.txt¿¡ Á¢±ÙÇ϶ó´Â ÀÀ´äÀ» + ¹Þ´Â´Ù.

    + +ÁÖÀÇ

    Redirect Áö½Ã¾î´Â ¼³Á¤ÆÄÀÏ¿¡¼­ +³ª¿À´Â ¼ø¼­¿Í °ü°è¾øÀÌ Alias¿Í ScriptAlias Áö½Ã¾îº¸´Ù ¿ì¼±¼øÀ§°¡ +³ô´Ù. ¶Ç, .htaccess ÆÄÀÏÀ̳ª Directory ¼½¼Ç¿¡¼­ »ç¿ëÇÏ´õ¶óµµ +URL-path¿¡´Â »ó´ë°æ·Î°¡ ¾Æ´Ï¶ó ¹Ýµå½Ã ¿ÏÀüÇÑ URLÀ» +»ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    status ¾Æ±Ô¸ÕÆ®¸¦ ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é, "Àӽà + (temporary)" (HTTP »óÅ 302) ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. Áï, + Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÚ¿øÀ» Àӽ÷Π¿Å°å´Ù°í ¾Ë¸°´Ù. status + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÏ¿© ´Ù¸¥ HTTP »óÅÂÄڵ带 ¹ÝȯÇÒ ¼ö ÀÖ´Ù:

    + +
    +
    permanent
    + +
    ÀÚ¿øÀ» ¿ÏÀüÈ÷ ¿Å°åÀ½À» ¶æÇÏ´Â ¿µ±¸ ¸®´ÙÀÌ·º¼Ç »óŸ¦ + (301) ¹ÝȯÇÑ´Ù.
    + +
    temp
    + +
    Àӽà ¸®´ÙÀÌ·º¼Ç »óŸ¦ (302) ¹ÝȯÇÑ´Ù. ±âº»°ªÀÌ´Ù.
    + +
    seeother
    + +
    ÀÚ¿øÀÌ ±³Ã¼µÇ¾úÀ½À» ¶æÇÏ´Â "ÂüÁ¶ (See Other)" »óŸ¦ + (303) ¹ÝȯÇÑ´Ù.
    + +
    gone
    + +
    ÀÚ¿øÀÌ ¿µ±¸È÷ »èÁ¦µÇ¾úÀ½À» ¶æÇÏ´Â "¼Ò¸ê (Gone)" »óŸ¦ + (410) ¹ÝȯÇÑ´Ù. ÀÌ »óŸ¦ »ç¿ëÇϸé URL ¾Æ±Ô¸ÕÆ®¸¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    +
    + +

    status¿¡ ¼ýÀÚ »óÅÂÄڵ带 »ç¿ëÇÏ¿© ´Ù¸¥ »óÅÂÄڵ嵵 + ¹ÝȯÇÒ ¼ö ÀÖ´Ù. »óÅ°¡ 300°ú 399 »çÀ̶ó¸é URL + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇØ¾ß ÇÏ°í, ¾Æ´Ï¶ó¸é »ý·«ÇØ¾ß ÇÑ´Ù. ´Ü, ¾ÆÆÄÄ¡ + Äڵ忡 »óÅ°¡ Á¤ÀǵÇÀÖ¾î¾ß ÇÑ´Ù (http_protocol.cÀÇ + send_error_response ÇÔ¼ö Âü°í).

    + + ¿¹Á¦: + Redirect permanent /one http://example.com/two
    + Redirect 303 /three http://example.com/other +
    + +
    +
    + + +RedirectMatch +ÇöÀç URLÀÌ Á¤±ÔÇ¥Çö½Ä¿¡ ÇØ´çÇÏ¸é ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» +º¸³½´Ù +RedirectMatch [status] regex +URL +server configvirtual host +directory.htaccess +FileInfo + + +

    ÀÌ Áö½Ã¾î´Â Redirect¿Í °°Áö¸¸, °£´ÜÈ÷ + URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÑ´Ù. + ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, ¼­¹ö´Â °ýÈ£·Î + ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½Àº + ¸ðµç GIF ÆÄÀÏ ¿äû¿¡ ´ëÇØ ´Ù¸¥ ¼­¹öÀÇ ºñ½ÁÇÑ À̸§À» °¡Áø + JPEG ÆÄÀÏ·Î ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù:

    + + + RedirectMatch (.*)\.gif$ http://www.anotherserver.com$1.jpg + +
    +
    + + +RedirectTemp +Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +Àӽà ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù +RedirectTemp URL-path URL +server configvirtual host +directory.htaccess +FileInfo + + +

    ÀÌ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀÌ ÀÓ½ÃÀûÀÓÀ» (»óÅ + 302) ¾Ë¸°´Ù. Redirect temp¿Í Á¤È®È÷ °°´Ù.

    +
    +
    + + +RedirectPermanent +Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¿µ±¸ ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù +RedirectPermanent URL-path URL +server configvirtual host +directory.htaccess +FileInfo + + +

    ÀÌ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀÌ ¿µ±¸ÀûÀÓÀ» (»óÅ + 301) ¾Ë¸°´Ù. Redirect permanent¿Í Á¤È®È÷ °°´Ù.

    +
    +
    + + +ScriptAlias +URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÏ°í ´ë»óÀÌ CGI +½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù +ScriptAlias URL-path +file-path|directory-path +server configvirtual host + + + +

    ScriptAlias Áö½Ã¾î´Â Alias Áö½Ã¾î¿Í ºñ½ÁÇÏÁö¸¸, + Ãß°¡·Î ´ë»ó µð·ºÅ丮¿¡ mod_cgiÀÇ cgi-script + Çڵ鷯°¡ ó¸®ÇÒ CGI ½ºÅ©¸³Æ®°¡ ÀÖ´Ù°í ¾Ë¸°´Ù. + URL-path·Î ½ÃÀÛÇÏ´Â (%·Î ÀÎÄÚµùµÈ) URLÀ» ÆÄÀϽýºÅÛÀÇ + Àý´ë°æ·ÎÀÎ µÎ¹ø° ¾Æ±Ô¸ÕÆ®·Î ½ÃÀÛÇÏ´Â ½ºÅ©¸³Æ®¿¡ ´ëÀÀÇÑ´Ù.

    + + ¿¹Á¦: + ScriptAlias /cgi-bin/ /web/cgi-bin/ + + +

    http://myserver/cgi-bin/foo¸¦ ¿äûÇÏ¸é ¼­¹ö´Â + /web/cgi-bin/foo ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÑ´Ù.

    +
    +
    + + +ScriptAliasMatch +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÏ°í ´ë»óÀÌ CGI ½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù +ScriptAliasMatch regex +file-path|directory-path +server configvirtual host + + + +

    ÀÌ Áö½Ã¾î´Â ScriptAlias¿Í °°Áö¸¸, °£´ÜÈ÷ + URLÀÇ ¾ÕºÎºÐ¸¸ ºñ±³ÇÏ´Â ´ë½Å Ç¥ÁØ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÑ´Ù. + ÁöÁ¤ÇÑ Á¤±ÔÇ¥Çö½ÄÀ» URL °æ·Î¿Í ºñ±³ÇÏ¿© ¸Â´Ù¸é, ¼­¹ö´Â °ýÈ£·Î + ¹­Àº ºÎºÐÀ» ´ëüÇÏ¿© ÆÄÀϸíÀ¸·Î »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°ÀÌ Ç¥ÁØÀûÀÎ /cgi-binÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + + + ScriptAliasMatch ^/cgi-bin(.*) /usr/local/apache/cgi-bin$1 + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_alias.xml.meta b/trunk/docs/manual/mod/mod_alias.xml.meta new file mode 100644 index 0000000000..7f438145fc --- /dev/null +++ b/trunk/docs/manual/mod/mod_alias.xml.meta @@ -0,0 +1,13 @@ + + + + mod_alias + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_asis.html b/trunk/docs/manual/mod/mod_asis.html new file mode 100644 index 0000000000..66ab1a743a --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.html @@ -0,0 +1,11 @@ +URI: mod_asis.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_asis.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_asis.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_asis.html.en b/trunk/docs/manual/mod/mod_asis.html.en new file mode 100644 index 0000000000..597d7a7fda --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.html.en @@ -0,0 +1,112 @@ + + + +mod_asis - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_asis

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Sends files that contain their own +HTTP headers
    Status:Base
    Module Identifier:asis_module
    Source File:mod_asis.c
    +

    Summary

    + +

    This module provides the handler send-as-is + which causes Apache to send the document without adding most of + the usual HTTP headers.

    + +

    This can be used to send any kind of data from the server, + including redirects and other special HTTP responses, without + requiring a cgi-script or an nph script.

    + +

    For historical reasons, this module will also process any + file with the mime type httpd/send-as-is.

    +
    +

    Directives

    +

    This module provides no + directives.

    +

    Topics

    +

    See also

    +
    +
    top
    +
    +

    Usage

    + +

    In the server configuration file, associate files with the + send-as-is handler e.g.

    + +

    AddHandler send-as-is asis

    + +

    The contents of any file with a .asis extension + will then be sent by Apache to the client with almost no + changes. Clients will need HTTP headers to be attached, so do + not forget them. A Status: header is also required; the data + should be the 3-digit HTTP response code, followed by a textual + message.

    + +

    Here's an example of a file whose contents are sent as + is so as to tell the client that a file has + redirected.

    + + +

    + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +

    + +

    Notes:

    +

    The server always adds a Date: and Server: + header to the data returned to the client, so these should not be + included in the file. The server does not add a + Last-Modified header; it probably should.

    +
    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_asis.html.ja.euc-jp b/trunk/docs/manual/mod/mod_asis.html.ja.euc-jp new file mode 100644 index 0000000000..f79b17058d --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.html.ja.euc-jp @@ -0,0 +1,110 @@ + + + +mod_asis - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_asis

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¼«Ê¬ÍѤΠHTTP ¥Ø¥Ã¥À¤Î½ñ¤«¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤òÁ÷¿®¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:asis_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_asis.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥Ï¥ó¥É¥é send-as-is + ¤òÄ󶡤·¤Þ¤¹¡£¤³¤Î¥Ï¥ó¥É¥é¤ÏÄ̾ï¤Î HTTP + ¥Ø¥Ã¥À¤ò¤Û¤È¤ó¤ÉÄɲ乤뤳¤È¤Ê¤¯¥É¥­¥å¥á¥ó¥È¤òÁ÷¿®¤·¤Þ¤¹¡£

    + +

    ¤³¤ì¤Ï¥µ¡¼¥Ð¤«¤é¤É¤ó¤Ê¼ïÎà¤Î¥Ç¡¼¥¿¤òÁ÷¤ë¤È¤­¤Ë¤â»ÈÍѤǤ­¤Þ¤¹¡£ + Cgi ¥¹¥¯¥ê¥×¥È¤ä nph ¥¹¥¯¥ê¥×¥È¤¬Ìµ¤¯¤Æ¤â¥ê¥À¥¤¥ì¥¯¥È¤ä¾¤ÎÆÃÊÌ¤Ê + HTTP ±þÅú¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Îò»ËŪ¤ÊÍýͳ¤Ë¤è¤ê¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mime ¥¿¥¤¥× + httpd/send-as-is ¤Î¥Õ¥¡¥¤¥ë¤â½èÍý¤·¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    +

    ¥È¥Ô¥Ã¥¯

    +

    »²¾È

    +
    +
    top
    +
    +

    »ÈÍÑË¡

    + +

    ¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤Ç¡¢¥Õ¥¡¥¤¥ë¤È send-as-is + ¥Ï¥ó¥É¥é¤òÎ㤨¤Ð°Ê²¼¤Î¤è¤¦¤Ë´ØÏ¢ÉÕ¤±¤Æ¤¯¤À¤µ¤¤¡£

    + +

    AddHandler send-as-is asis

    + +

    ³ÈÄ¥»Ò¤¬ .asis ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ÎÆâÍÆ¤Ï Apache + ¤«¤é¥¯¥é¥¤¥¢¥ó¥È¤Ø¤Û¤È¤ó¤ÉÊѹ¹Ìµ¤¯Á÷¤é¤ì¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¤Ë¤Ï + HTTP ¥Ø¥Ã¥À¤¬É¬ÍפǤ¹¤Î¤Ç¡¢¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤ò˺¤ì¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + Status: ¥Ø¥Ã¥À¤âɬÍפǤ¹¡£¥Ç¡¼¥¿¤Ï 3 ·å¤Î HTTP + ±þÅú¥³¡¼¥É¤È¡¢¤½¤Î¸å¤Ë¥Æ¥­¥¹¥È¥á¥Ã¥»¡¼¥¸¤¬Â³¤¤¤¿¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¤³¤ì¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë¥Õ¥¡¥¤¥ë¤¬°ÜÆ°¤·¤¿¤³¤È¤òÃΤ餻¤ë¤¿¤á¤Ë + as is (¤½¤Î¤Þ¤Þ) ¤ÇÁ÷¤é¤ì¤ë¥Õ¥¡¥¤¥ë¤ÎÆâÍƤÎÎã¤Ç¤¹¡£ +

    + + +

    + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +

    + +

    Ãí°Õ

    +

    Ãí°Õ: ¥µ¡¼¥Ð¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¤ë¥Ç¡¼¥¿¤Ë¾ï¤Ë Date: + ¤È Server: ¥Ø¥Ã¥À¤òÄɲä·¤Þ¤¹¤Î¤Ç¡¢ + ¤½¤ì¤é¤¬¥Õ¥¡¥¤¥ë¤Ë½ñ¤«¤ì¤Æ¤¤¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£ + ¥µ¡¼¥Ð¤Ï Last-Modified ¥Ø¥Ã¥À¤òÄɲä·¤Þ¤»¤ó¡£ + ¤ª¤½¤é¤¯¤Ï¤½¤¦¤¹¤Ù¤­¤Ç¤·¤ç¤¦¤±¤ì¤É¡£

    +
    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_asis.html.ko.euc-kr b/trunk/docs/manual/mod/mod_asis.html.ko.euc-kr new file mode 100644 index 0000000000..211f8b6275 --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.html.ko.euc-kr @@ -0,0 +1,108 @@ + + + +mod_asis - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_asis

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:HTTP Çì´õ¸¦ Æ÷ÇÔÇÑ ÆÄÀÏÀ» º¸³½´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:asis_module
    ¼Ò½ºÆÄÀÏ:mod_asis.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡°¡ ÀϹÝÀûÀÎ HTTP Çì´õÀÇ ´ëºÎºÐÀ» Ãß°¡ÇÏÁö¾Ê°í + ¹®¼­¸¦ º¸³»µµ·Ï ¸¸µå´Â send-as-is Çڵ鷯¸¦ + Á¦°øÇÑ´Ù.

    + +

    ±×·¡¼­ ¼­¹ö´Â cgi ½ºÅ©¸³Æ®³ª nph ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏÁö¾Ê°íµµ + ¸®´ÙÀÌ·º¼Ç°ú ´Ù¸¥ Ưº°ÇÑ HTTP ÀÀ´ä µî ¾î¶² ÀÚ·áµµ º¸³¾ ¼ö + ÀÖ´Ù.

    + +

    °ú°Å¿¡ ÀÌ ¸ðµâÀº mime typeÀÌ httpd/send-as-isÀÎ + ÆÄÀϵµ ó¸®Çß´Ù.

    +
    +

    Áö½Ã¾îµé

    +

    ÀÌ ¸ðµâ¿¡´Â Áö½Ã¾î°¡ ¾ø½À´Ï´Ù.

    +

    ÁÖÁ¦

    +

    Âü°í

    +
    +
    top
    +
    +

    »ç¿ë¹ý

    + +

    ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ ÆÄÀÏ°ú send-as-is Çڵ鷯¸¦ + ¿¹¸¦ µé¾î ´ÙÀ½°ú °°ÀÌ ¿¬°áÇÑ´Ù.

    + +

    AddHandler send-as-is asis

    + +

    ¾ÆÆÄÄ¡´Â .asis È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏÀÇ ³»¿ëÀ» + °ÅÀÇ ¼öÁ¤ÇÏÁö¾Ê°í Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù. Ŭ¶óÀ̾ðÆ®´Â HTTP + Çì´õ°¡ ÇÊ¿äÇϹǷΠ»©¸ÔÁö¸¶¶ó. Status: Çì´õµµ ÇÊ¿äÇÏ´Ù. ÀÌ + Çì´õÀÇ ³»¿ëÀº ¼¼ÀÚ¸® ¼ýÀÚÀÎ HTTP ÀÀ´äÄÚµå¿Í ±× µÚÀÇ ¹®±¸ÀÌ´Ù.

    + +

    ´ÙÀ½Àº ³»¿ë ±×´ë·Î Ŭ¶óÀ̾ðÆ®¿¡°Ô ÆÄÀÏÀÌ + ¸®´ÙÀ̷¼ǵǾú´Ù°í ¾Ë¸®´Â ÆÄÀÏÀÇ ¿¹ÀÌ´Ù.

    + + +

    + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +

    + +

    ÁÖÀÇ:

    +

    ¼­¹ö´Â ÀڷḦ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³¾¶§ Ç×»ó Date:¿Í + Server: Çì´õ¸¦ Ãß°¡ÇϹǷÎ, ÆÄÀÏ¿¡ ÀÌ Çì´õ°¡ + ÀÖÀ¸¸é ¾ÈµÈ´Ù. ¼­¹ö´Â Last-Modified Çì´õ¸¦ + Ãß°¡ÇÏÁö ¾Ê´Â´Ù. ±×·¡¼­ ¾Æ¸¶µµ ÀÌ Çì´õ´Â Æ÷ÇÔÇØ¾ß + ÇÑ´Ù.

    +
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_asis.xml b/trunk/docs/manual/mod/mod_asis.xml new file mode 100644 index 0000000000..2f8fbd3ceb --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.xml @@ -0,0 +1,94 @@ + + + + + + + + + +mod_asis +Sends files that contain their own +HTTP headers +Base +mod_asis.c +asis_module + + +

    This module provides the handler send-as-is + which causes Apache to send the document without adding most of + the usual HTTP headers.

    + +

    This can be used to send any kind of data from the server, + including redirects and other special HTTP responses, without + requiring a cgi-script or an nph script.

    + +

    For historical reasons, this module will also process any + file with the mime type httpd/send-as-is.

    +
    + +mod_headers +mod_cern_meta +Apache's Handler Use + +
    Usage + +

    In the server configuration file, associate files with the + send-as-is handler e.g.

    + + AddHandler send-as-is asis + +

    The contents of any file with a .asis extension + will then be sent by Apache to the client with almost no + changes. Clients will need HTTP headers to be attached, so do + not forget them. A Status: header is also required; the data + should be the 3-digit HTTP response code, followed by a textual + message.

    + +

    Here's an example of a file whose contents are sent as + is so as to tell the client that a file has + redirected.

    + + + + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +
    + + Notes: +

    The server always adds a Date: and Server: + header to the data returned to the client, so these should not be + included in the file. The server does not add a + Last-Modified header; it probably should.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_asis.xml.ja b/trunk/docs/manual/mod/mod_asis.xml.ja new file mode 100644 index 0000000000..be933dbc5a --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.xml.ja @@ -0,0 +1,93 @@ + + + + + + + + + +mod_asis +$B<+J,MQ$N(B HTTP $B%X%C%@$N=q$+$l$F$$$k%U%!%$%k$rAw?.$9$k(B +Base +mod_asis.c +asis_module + + +

    $B$3$N%b%8%e!<%k$O%O%s%I%i(B send-as-is + $B$rDs6!$7$^$9!#$3$N%O%s%I%i$ODL>o$N(B HTTP + $B%X%C%@$r$[$H$s$IDI2C$9$k$3$H$J$/%I%-%e%a%s%H$rAw?.$7$^$9!#(B

    + +

    $B$3$l$O%5!<%P$+$i$I$s$J$NFCJL$J(B + HTTP $B1~Ez$rAw$k$3$H$,$G$-$^$9!#(B

    + +

    $BNr;KE*$JM}M3$K$h$j!"$3$N%b%8%e!<%k$O(B mime $B%?%$%W(B + httpd/send-as-is $B$N%U%!%$%k$b=hM}$7$^$9!#(B

    +
    + +mod_headers +mod_cern_meta +Apache $B$N%O%s%I%i$N;HMQ(B + +
    $B;HMQK!(B + +

    $B%5!<%P@_Dj%U%!%$%k$G!"%U%!%$%k$H(B send-as-is + $B%O%s%I%i$rNc$($P0J2<$N$h$&$K4XO"IU$1$F$/$@$5$$!#(B

    + + AddHandler send-as-is asis + +

    $B3HD%;R$,(B .asis $B$N$9$Y$F$N%U%!%$%k$NFbMF$O(B Apache + $B$+$i%/%i%$%"%s%H$X$[$H$s$IJQ99L5$/Aw$i$l$^$9!#%/%i%$%"%s%H$K$O(B + HTTP $B%X%C%@$,I,MW$G$9$N$G!"%U%!%$%k$K=q$/$3$H$rK:$l$J$$$G$/$@$5$$!#(B + Status: $B%X%C%@$bI,MW$G$9!#%G!<%?$O(B 3 $B7e$N(B HTTP + $B1~Ez%3!<%I$H!"$=$N8e$K%F%-%9%H%a%C%;!<%8$,B3$$$?$b$N$G$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B$3$l$O%/%i%$%"%s%H$K%U%!%$%k$,0\F0$7$?$3$H$rCN$i$;$k$?$a$K(B + as is ($B$=$N$^$^(B) $B$GAw$i$l$k%U%!%$%k$NFbMF$NNc$G$9!#(B +

    + + + + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +
    + + $BCm0U(B +

    $BCm0U(B: $B%5!<%P$O%/%i%$%"%s%H$KJV$5$l$k%G!<%?$K>o$K(B Date: + $B$H(B Server: $B%X%C%@$rDI2C$7$^$9$N$G!"(B + $B$=$l$i$,%U%!%$%k$K=q$+$l$F$$$F$O$$$1$^$;$s!#(B + $B%5!<%P$O(B Last-Modified $B%X%C%@$rDI2C(B$B$7$^$;$s(B$B!#(B + $B$*$=$i$/$O$=$&$9$Y$-$G$7$g$&$1$l$I!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_asis.xml.ko b/trunk/docs/manual/mod/mod_asis.xml.ko new file mode 100644 index 0000000000..7220bfdbb7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.xml.ko @@ -0,0 +1,91 @@ + + + + + + + + + +mod_asis +HTTP Çì´õ¸¦ Æ÷ÇÔÇÑ ÆÄÀÏÀ» º¸³½´Ù +Base +mod_asis.c +asis_module + + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡°¡ ÀϹÝÀûÀÎ HTTP Çì´õÀÇ ´ëºÎºÐÀ» Ãß°¡ÇÏÁö¾Ê°í + ¹®¼­¸¦ º¸³»µµ·Ï ¸¸µå´Â send-as-is Çڵ鷯¸¦ + Á¦°øÇÑ´Ù.

    + +

    ±×·¡¼­ ¼­¹ö´Â cgi ½ºÅ©¸³Æ®³ª nph ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏÁö¾Ê°íµµ + ¸®´ÙÀÌ·º¼Ç°ú ´Ù¸¥ Ưº°ÇÑ HTTP ÀÀ´ä µî ¾î¶² ÀÚ·áµµ º¸³¾ ¼ö + ÀÖ´Ù.

    + +

    °ú°Å¿¡ ÀÌ ¸ðµâÀº mime typeÀÌ httpd/send-as-isÀÎ + ÆÄÀϵµ ó¸®Çß´Ù.

    +
    + +mod_headers +mod_cern_meta +¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë + +
    »ç¿ë¹ý + +

    ¼­¹ö ¼³Á¤ÆÄÀÏ¿¡¼­ ÆÄÀÏ°ú send-as-is Çڵ鷯¸¦ + ¿¹¸¦ µé¾î ´ÙÀ½°ú °°ÀÌ ¿¬°áÇÑ´Ù.

    + + AddHandler send-as-is asis + +

    ¾ÆÆÄÄ¡´Â .asis È®ÀåÀÚ¸¦ °¡Áø ÆÄÀÏÀÇ ³»¿ëÀ» + °ÅÀÇ ¼öÁ¤ÇÏÁö¾Ê°í Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù. Ŭ¶óÀ̾ðÆ®´Â HTTP + Çì´õ°¡ ÇÊ¿äÇϹǷΠ»©¸ÔÁö¸¶¶ó. Status: Çì´õµµ ÇÊ¿äÇÏ´Ù. ÀÌ + Çì´õÀÇ ³»¿ëÀº ¼¼ÀÚ¸® ¼ýÀÚÀÎ HTTP ÀÀ´äÄÚµå¿Í ±× µÚÀÇ ¹®±¸ÀÌ´Ù.

    + +

    ´ÙÀ½Àº ³»¿ë ±×´ë·Î Ŭ¶óÀ̾ðÆ®¿¡°Ô ÆÄÀÏÀÌ + ¸®´ÙÀ̷¼ǵǾú´Ù°í ¾Ë¸®´Â ÆÄÀÏÀÇ ¿¹ÀÌ´Ù.

    + + + + Status: 301 Now where did I leave that URL
    + Location: http://xyz.abc.com/foo/bar.html
    + Content-type: text/html
    +
    + <html>
    + <head>
    + <title>Lame excuses'R'us</title>
    + </head>
    + <body>
    + <h1>Fred's exceptionally wonderful page has moved to
    + <a href="http://xyz.abc.com/foo/bar.html">Joe's</a> + site.
    + </h1>
    + </body>
    + </html> +
    + + ÁÖÀÇ: +

    ¼­¹ö´Â ÀڷḦ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³¾¶§ Ç×»ó Date:¿Í + Server: Çì´õ¸¦ Ãß°¡ÇϹǷÎ, ÆÄÀÏ¿¡ ÀÌ Çì´õ°¡ + ÀÖÀ¸¸é ¾ÈµÈ´Ù. ¼­¹ö´Â Last-Modified Çì´õ¸¦ + Ãß°¡ÇÏÁö ¾Ê´Â´Ù. ±×·¡¼­ ¾Æ¸¶µµ ÀÌ Çì´õ´Â Æ÷ÇÔÇØ¾ß + ÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_asis.xml.meta b/trunk/docs/manual/mod/mod_asis.xml.meta new file mode 100644 index 0000000000..f829c41d1d --- /dev/null +++ b/trunk/docs/manual/mod/mod_asis.xml.meta @@ -0,0 +1,13 @@ + + + + mod_asis + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_auth_basic.html b/trunk/docs/manual/mod/mod_auth_basic.html new file mode 100644 index 0000000000..e93a9911e6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.html @@ -0,0 +1,11 @@ +URI: mod_auth_basic.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_auth_basic.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_auth_basic.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_auth_basic.html.en b/trunk/docs/manual/mod/mod_auth_basic.html.en new file mode 100644 index 0000000000..73c776ce34 --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.html.en @@ -0,0 +1,130 @@ + + + +mod_auth_basic - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_auth_basic

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Basic authentication
    Status:Base
    Module Identifier:auth_basic_module
    Source File:mod_auth_basic.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module allows the use of HTTP Basic Authentication to + restrict access by looking up users in the given providers. + HTTP Digest Authentication is provided by + mod_auth_digest.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    AuthBasicAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization and authentication are passed to +lower level modules
    Syntax:AuthBasicAuthoritative On|Off
    Default:AuthBasicAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_auth_basic
    +

    Setting the AuthBasicAuthoritative directive + explicitly to Off allows for both + authentication and authorization to be passed on to lower level + modules (as defined in the modules.c files) if there is + no userID or rule matching the + supplied userID. If there is a userID and/or rule specified, the usual + password and access checks will be applied and a failure will give + an "Authentication Required" reply.

    + +

    So if a userID appears in the database of more than one module; + or if a valid Require + directive applies to more than one module; then the first module + will verify the credentials; and no access is passed on; + regardless of the AuthBasicAuthoritative + setting.

    + +

    By default control is not passed on and an unknown userID or + rule will result in an "Authentication Required" reply. Not setting + it thus keeps the system secure and forces an NCSA compliant + behaviour.

    + +
    +
    top
    +

    AuthBasicProvider Directive

    + + + + + + + + +
    Description:Sets the authentication provider(s) for this location
    Syntax:AuthBasicProvider On|Off|provider-name +[provider-name] ...
    Default:AuthBasicProvider On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_auth_basic
    +

    The AuthBasicProvider directive sets + which provider is used to authenticate the users for this location. + Setting the value to On will choose the default provider + (file). Since the file provider is implemented + by the mod_authn_file module, you have to make sure, + that the module is present in the server.

    + +

    Example

    + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +

    + +

    See mod_authn_dbm and mod_authn_file + for providers.

    + +

    The value Off clears the provider list and sets it back + to the default.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_auth_basic.html.ja.euc-jp b/trunk/docs/manual/mod/mod_auth_basic.html.ja.euc-jp new file mode 100644 index 0000000000..097578ea35 --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.html.ja.euc-jp @@ -0,0 +1,133 @@ + + + +mod_auth_basic - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_auth_basic

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:´ðËÜǧ¾Ú
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:auth_basic_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_auth_basic.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    Í¿¤¨¤é¤ì¤¿¥×¥í¥Ð¥¤¥À (ÌõÃí: ǧ¾Ú¤Ç¤Î¾È²ñ¤ò¹Ô¤¦Ì䤤¹ç¤ï¤»Àè) + ¤Ç¥æ¡¼¥¶¤ò¸¡º÷¤·¡¢HTTP ´ðËÜǧ¾Ú¤Ç¥¢¥¯¥»¥¹À©¸Â¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + HTTP ¥À¥¤¥¸¥§¥¹¥Èǧ¾Ú¤Ë¤Ä¤¤¤Æ¤Ï mod_auth_digest + ¤ÇÄ󶡤µ¤ì¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    AuthBasicAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ǧ¾Ú¤È¾µÇ§¤ò¡¢¤è¤êÄ㤤¥ì¥Ù¥ë¤Î¥â¥¸¥å¡¼¥ë¤Ë°Ü¹Ô¤µ¤»¤ë¤«¤ò +ÀßÄꤷ¤Þ¤¹¡£
    ¹½Ê¸:AuthBasicAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthBasicAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_auth_basic
    +

    AuthBasicAuthoritative + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÌÀ¼¨Åª¤Ë Off¤ËÀßÄꤹ¤ë¤È¡¢ + Í¿¤¨¤é¤ì¤¿Ç§¾Ú¥æ¡¼¥¶ ID ¤ËÂФ·¤Æ¥æ¡¼¥¶ ID ¤¬¤Ê¤¤ + ¤Þ¤¿¤Ï¥ë¡¼¥ë¤¬¤Ê¤¤¾ì¹ç¤Ë¡¢ + ǧ¾Ú¤È¾µÇ§¤ÎξÊý¤Î¥×¥í¥»¥¹¤¬¡¢ + ¤è¤êÄ㤤¥ì¥Ù¥ë¤Î¥â¥¸¥å¡¼¥ë (modules.c ¥Õ¥¡¥¤¥ë¤ÇÄêµÁ) ¤Ë°Ü¹Ô¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£ + ¥æ¡¼¥¶ ID ¤¬¤¢¤ë¡¢¤«¤Ä¤Þ¤¿¤Ï¡¢¥ë¡¼¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + Ä̾ï¤Î¥Ñ¥¹¥ï¡¼¥É¤È¥¢¥¯¥»¥¹¥Á¥§¥Ã¥¯¤¬Å¬ÍѤµ¤ì¤Æ¡¢ + ǧ¾Ú¤Ë¼ºÇÔ¤¹¤ë¤È "Authentication Required" ±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    ¤Ç¤¹¤«¤é¡¢Æó¤Ä°Ê¾å¤Î¥â¥¸¥å¡¼¥ë¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÇƱ°ì¤Î + ¥æ¡¼¥¶ ID ¤¬¸½¤ï¤ì¤¿¤ê¡¢ + ¤Þ¤¿¤Ï¡¢Àµ¤·¤¤ Require + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Æó¤Ä°Ê¾å¤Î¥â¥¸¥å¡¼¥ë¤Ç¸½¤ï¤ì¤¿¤ê¤·¤¿¾ì¹ç¤Ï¡¢ + °ì¤ÄÌܤΥ⥸¥å¡¼¥ë¤¬Ç§Äê¤ò¹Ô¤Ã¤Æ¡¢AuthAuthoritative + ÀßÄê¤Ë´Ø¤ï¤é¤º¡¢¥¢¥¯¥»¥¹¤Ï°Ü¹Ô¤·¤Þ¤»¤ó¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢À©¸æ¤Ï°Ü¹Ô¤·¤Þ¤»¤ó¡£¤½¤·¤Æ¡¢Ì¤ÃΤΥ桼¥¶ ID ¤ä + ¥ë¡¼¥ë¤¬¤¢¤Ã¤Æ¤â "Authentication Required" ±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÀßÄꤷ¤Ê¤¤¤³¤È¤Ç¥·¥¹¥Æ¥à¤Î°ÂÁ´¤ò°Ý»ý¤Ç¤­¤Æ¡¢¤Þ¤¿¡¢ + NCSA ½àµò¤ÎµóÆ°¤ò¶¯À©¤Ç¤­¤Þ¤¹¡£

    + +
    +
    top
    +

    AuthBasicProvider ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¤³¤Î°ÌÃÖ¤ËÂФ¹¤ëǧ¾Ú¥×¥í¥Ð¥¤¥À¤òÀßÄꤷ¤Þ¤¹¡£
    ¹½Ê¸:AuthBasicProvider On|Off|provider-name +[provider-name] ...
    ¥Ç¥Õ¥©¥ë¥È:AuthBasicProvider On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_auth_basic
    +

    AuthBasicProvider ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ + ¤³¤Î°ÌÃÖ¤ËÂФ¹¤ë¥æ¡¼¥¶Ç§¾Ú¤ËÍѤ¤¤é¤ì¤ëǧ¾Ú¥×¥í¥Ð¥¤¥À¤òÀßÄꤷ¤Þ¤¹¡£ + On ¤ËÀßÄꤹ¤ë¤È¥Ç¥Õ¥©¥ë¥È¤Îǧ¾Ú¥×¥í¥Ð¥¤¥À + (file) ¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£file + ¥×¥í¥Ð¥¤¥À¤Ï mod_authn_file + ¥â¥¸¥å¡¼¥ë¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤¬¥µ¡¼¥Ð¤ËÆþ¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Example

    + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +

    + +

    ǧ¾Ú¥×¥í¥Ð¥¤¥À¤Ë¤Ä¤¤¤Æ¤Ï + mod_authn_dbm ¤È mod_authn_file + ¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    Off ¤Ï¥×¥í¥Ð¥¤¥À¥ê¥¹¥È¤ò¥¯¥ê¥¢¤·¤Æ¡¢¥Ç¥Õ¥©¥ë¥È¤Î + ¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_auth_basic.html.ko.euc-kr b/trunk/docs/manual/mod/mod_auth_basic.html.ko.euc-kr new file mode 100644 index 0000000000..5ee5ae1521 --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.html.ko.euc-kr @@ -0,0 +1,128 @@ + + + +mod_auth_basic - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_auth_basic

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:Basic authentication
    »óÅÂ:Base
    ¸ðµâ¸í:auth_basic_module
    ¼Ò½ºÆÄÀÏ:mod_auth_basic.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ÇØ´ç Á¦°øÀÚ(provider)¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚº°·Î + Á¢±ÙÀ» Á¦ÇÑÇÏ´Â HTTP Basic AuthenticationÀ» Á¦°øÇÑ´Ù. + HTTP Digest AuthenticationÀº mod_auth_digest°¡ + Á¦°øÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthBasicAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ÀÎÁõ°ú ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ¿¡ ³Ñ°ÜÁÙÁö °áÁ¤ÇÑ´Ù
    ¹®¹ý:AuthBasicAuthoritative On|Off
    ±âº»°ª:AuthBasicAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_auth_basic
    +

    AuthBasicAuthoritative Áö½Ã¾î¸¦ + Off·Î ¼³Á¤Çϸé ÁÖ¾îÁø »ç¿ëÀÚ ¾ÆÀ̵𿡠ÇØ´çÇÏ´Â + »ç¿ëÀÚ ¾ÆÀ̵𳪠±ÔÄ¢À» + ãÀ» ¼ö ¾ø´Â °æ¿ì ÀÎÁõ°ú ±ÇÇѺο© ¸ðµÎ¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù. ÁÖ¾îÁø »ç¿ëÀÚ + ¾ÆÀ̵𳪠±ÔÄ¢À» ã¾Ò´Ù¸é º¸Å붧¿Í °°ÀÌ ¾ÏÈ£¿Í Á¢±ÙÇã¿ë¿©ºÎ¸¦ + °Ë»çÇÏ°í, ½ÇÆÐÇϸé "Authentication Required (ÀÎÁõ ÇÊ¿ä)" + ÀÀ´äÀ» ÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ ¸ðµâÀÇ µ¥ÀÌÅͺ£À̽º¿¡ »ç¿ëÀÚ ¾ÆÀ̵𰡠Àְųª + À¯È¿ÇÑ Require Áö½Ã¾î¸¦ + ¿©·¯ ¸ðµâ¿¡ Àû¿ëÇϸé, ù¹ø° ¸ðµâÀÌ »ç¿ëÀÚ¸¦ °Ë»çÇÏ°í, + AuthBasicAuthoritative ¼³Á¤°ú °ü°è¾øÀÌ + Á¢±ÙÀ» ³Ñ±âÁö¾Ê´Â´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â »ç¿ëÀÚ ¾ÆÀ̵ð¿Í + ±ÔÄ¢ÀÎ °æ¿ì "Authentication Required (ÀÎÁõ ÇÊ¿ä)" ÀÀ´äÀ» + ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, + NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + +
    +
    top
    +

    AuthBasicProvider Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthBasicProvider On|Off|provider-name +[provider-name] ...
    ±âº»°ª:AuthBasicProvider On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_auth_basic
    +

    AuthBasicProvider Áö½Ã¾î´Â ÀÌ + À§Ä¡¿¡¼­ »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ Á¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. °ªÀÌ + OnÀÌ¸é ±âº»Á¦°øÀÚ(file)¸¦ ¼±ÅÃÇÑ´Ù. + mod_authn_file ¸ðµâÀÌ file + Á¦°øÀÚ¸¦ ±¸ÇöÇϱ⶧¹®¿¡ ¼­¹ö¿¡ ÀÌ ¸ðµâÀÌ ÀÖ´ÂÁö È®ÀÎÇØ¾ß + ÇÑ´Ù.

    + +

    ¿¹Á¦

    + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +

    + +

    Á¦°øÀÚ´Â mod_authn_dbm°ú + mod_authn_fileÀ» Âü°íÇ϶ó.

    + +

    °ªÀÌ OffÀ̸é Á¦°øÀÚ ¸ñ·ÏÀ» Áö¿ì°í ±âº»»óÅ·Π+ µ¹¾Æ°£´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_auth_basic.xml b/trunk/docs/manual/mod/mod_auth_basic.xml new file mode 100644 index 0000000000..a3fa5af59e --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.xml @@ -0,0 +1,112 @@ + + + + + + + + + +mod_auth_basic +Basic authentication +Base +mod_auth_basic.c +auth_basic_module +Available in Apache 2.1 and later + + +

    This module allows the use of HTTP Basic Authentication to + restrict access by looking up users in the given providers. + HTTP Digest Authentication is provided by + mod_auth_digest.

    +
    +AuthName +AuthType + + +AuthBasicProvider +Sets the authentication provider(s) for this location +AuthBasicProvider On|Off|provider-name +[provider-name] ... +AuthBasicProvider On +directory.htaccess + +AuthConfig + + +

    The AuthBasicProvider directive sets + which provider is used to authenticate the users for this location. + Setting the value to On will choose the default provider + (file). Since the file provider is implemented + by the mod_authn_file module, you have to make sure, + that the module is present in the server.

    + + Example + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +
    + +

    See mod_authn_dbm and mod_authn_file + for providers.

    + +

    The value Off clears the provider list and sets it back + to the default.

    +
    +
    + + +AuthBasicAuthoritative +Sets whether authorization and authentication are passed to +lower level modules +AuthBasicAuthoritative On|Off +AuthBasicAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthBasicAuthoritative directive + explicitly to Off allows for both + authentication and authorization to be passed on to lower level + modules (as defined in the modules.c files) if there is + no userID or rule matching the + supplied userID. If there is a userID and/or rule specified, the usual + password and access checks will be applied and a failure will give + an "Authentication Required" reply.

    + +

    So if a userID appears in the database of more than one module; + or if a valid Require + directive applies to more than one module; then the first module + will verify the credentials; and no access is passed on; + regardless of the AuthBasicAuthoritative + setting.

    + +

    By default control is not passed on and an unknown userID or + rule will result in an "Authentication Required" reply. Not setting + it thus keeps the system secure and forces an NCSA compliant + behaviour.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_auth_basic.xml.ja b/trunk/docs/manual/mod/mod_auth_basic.xml.ja new file mode 100644 index 0000000000..dcfdba215f --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.xml.ja @@ -0,0 +1,113 @@ + + + + + + + + + +mod_auth_basic +$B4pK\G'>Z(B +Base +mod_auth_basic.c +auth_basic_module +Apache 2.1 $B0J9_(B + + +

    $BM?$($i$l$?%W%m%P%$%@(B ($BLuCm(B: $BG'>Z$G$N>H2q$r9T$&Ld$$9g$o$;@h(B) + $B$G%f!<%6$r8!:w$7!"(BHTTP $B4pK\G'>Z$G%"%/%;%9@)8B$G$-$k$h$&$K$J$j$^$9!#(B + HTTP $B%@%$%8%'%9%HG'>Z$K$D$$$F$O(B mod_auth_digest + $B$GDs6!$5$l$^$9!#(B

    +
    +AuthName +AuthType + + +AuthBasicProvider +$B$3$N0LCV$KBP$9$kG'>Z%W%m%P%$%@$r@_Dj$7$^$9!#(B +AuthBasicProvider On|Off|provider-name +[provider-name] ... +AuthBasicProvider On +directory.htaccess +AuthConfig + + +

    AuthBasicProvider $B%G%#%l%/%F%#%V$G!"(B + $B$3$N0LCV$KBP$9$k%f!<%6G'>Z$KMQ$$$i$l$kG'>Z%W%m%P%$%@$r@_Dj$7$^$9!#(B + On $B$K@_Dj$9$k$H%G%U%)%k%H$NG'>Z%W%m%P%$%@(B + (file) $B$,;HMQ$5$l$^$9!#(Bfile + $B%W%m%P%$%@$O(B mod_authn_file + $B%b%8%e!<%k$G + + Example + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +
    + +

    $BG'>Z%W%m%P%$%@$K$D$$$F$O(B + mod_authn_dbm $B$H(B mod_authn_file + $B$r$4Mw2<$5$$!#(B

    + +

    Off $B$O%W%m%P%$%@%j%9%H$r%/%j%"$7$F!"%G%U%)%k%H$N(B + $B>uBV$KLa$7$^$9!#(B

    +
    +
    + + +AuthBasicAuthoritative +$BG'>Z$H>5G'$r!"$h$jDc$$%l%Y%k$N%b%8%e!<%k$K0\9T$5$;$k$+$r(B +$B@_Dj$7$^$9!#(B +AuthBasicAuthoritative On|Off +AuthBasicAuthoritative On +directory.htaccess +AuthConfig + + +

    AuthBasicAuthoritative + $B%G%#%l%/%F%#%V$GL@<(E*$K(B Off$B$K@_Dj$9$k$H!"(B + $BM?$($i$l$?G'>Z%f!<%6(B ID $B$KBP$7$F(B$B%f!<%6(B ID $B$,$J$$(B + $B$^$?$O(B$B%k!<%k$,$J$$(B$B>l9g$K!"(B + $BG'>Z$H>5G'$NN>J}$N%W%m%;%9$,!"(B + $B$h$jDc$$%l%Y%k$N%b%8%e!<%k(B (modules.c $B%U%!%$%k$GDj5A(B) $B$K0\9T$9$k$h$&$K$G$-$^$9!#(B + $B%f!<%6(B ID $B$,$"$k!"$+$D$^$?$O!"%k!<%k$,;XDj$5$l$F$$$k>l9g$O!"(B + $BDL>o$N%Q%9%o!<%I$H%"%/%;%9%A%'%C%/$,E,MQ$5$l$F!"(B + $BG'>Z$K<:GT$9$k$H(B "Authentication Required" $B1~Ez$,JV$5$l$^$9!#(B

    + +

    $B$G$9$+$i!"Fs$D0J>e$N%b%8%e!<%k$N%G!<%?%Y!<%9$GF10l$N(B + $B%f!<%6(B ID $B$,8=$o$l$?$j!"(B + $B$^$?$O!"@5$7$$(B Require + $B%G%#%l%/%F%#%V$,Fs$D0J>e$N%b%8%e!<%k$G8=$o$l$?$j$7$?>l9g$O!"(B + $B0l$DL\$N%b%8%e!<%k$,G'Dj$r9T$C$F!"(BAuthAuthoritative + $B@_Dj$K4X$o$i$:!"%"%/%;%9$O0\9T$7$^$;$s!#(B

    + +

    $B%G%U%)%k%H$G$O!"@)8f$O0\9T$7$^$;$s!#$=$7$F!"L$CN$N%f!<%6(B ID $B$d(B + $B%k!<%k$,$"$C$F$b(B "Authentication Required" $B1~Ez$,JV$5$l$^$9!#(B + $B$G$9$+$i!"$3$N%G%#%l%/%F%#%V$r@_Dj$7$J$$$3$H$G%7%9%F%`$N0BA4$r0];}$G$-$F!"$^$?!"(B + NCSA $B=`5r$N5sF0$r6/@)$G$-$^$9!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_auth_basic.xml.ko b/trunk/docs/manual/mod/mod_auth_basic.xml.ko new file mode 100644 index 0000000000..208865a99e --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.xml.ko @@ -0,0 +1,110 @@ + + + + + + + + + +mod_auth_basic +Basic authentication +Base +mod_auth_basic.c +auth_basic_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ÇØ´ç Á¦°øÀÚ(provider)¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚº°·Î + Á¢±ÙÀ» Á¦ÇÑÇÏ´Â HTTP Basic AuthenticationÀ» Á¦°øÇÑ´Ù. + HTTP Digest AuthenticationÀº mod_auth_digest°¡ + Á¦°øÇÑ´Ù.

    +
    +AuthName +AuthType + + +AuthBasicProvider +ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù +AuthBasicProvider On|Off|provider-name +[provider-name] ... +AuthBasicProvider On +directory.htaccess + +AuthConfig + + +

    AuthBasicProvider Áö½Ã¾î´Â ÀÌ + À§Ä¡¿¡¼­ »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ Á¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. °ªÀÌ + OnÀÌ¸é ±âº»Á¦°øÀÚ(file)¸¦ ¼±ÅÃÇÑ´Ù. + mod_authn_file ¸ðµâÀÌ file + Á¦°øÀÚ¸¦ ±¸ÇöÇϱ⶧¹®¿¡ ¼­¹ö¿¡ ÀÌ ¸ðµâÀÌ ÀÖ´ÂÁö È®ÀÎÇØ¾ß + ÇÑ´Ù.

    + + ¿¹Á¦ + <Location /secure>
    + + AuthBasicProvider dbm
    + AuthDBMType SDBM
    + AuthDBMUserFile /www/etc/dbmpasswd
    + Require valid-user
    +
    + </Location> +
    + +

    Á¦°øÀÚ´Â mod_authn_dbm°ú + mod_authn_fileÀ» Âü°íÇ϶ó.

    + +

    °ªÀÌ OffÀ̸é Á¦°øÀÚ ¸ñ·ÏÀ» Áö¿ì°í ±âº»»óÅ·Π+ µ¹¾Æ°£´Ù.

    +
    +
    + + +AuthBasicAuthoritative +ÀÎÁõ°ú ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ¿¡ ³Ñ°ÜÁÙÁö °áÁ¤ÇÑ´Ù +AuthBasicAuthoritative On|Off +AuthBasicAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthBasicAuthoritative Áö½Ã¾î¸¦ + Off·Î ¼³Á¤Çϸé ÁÖ¾îÁø »ç¿ëÀÚ ¾ÆÀ̵𿡠ÇØ´çÇÏ´Â + »ç¿ëÀÚ ¾ÆÀ̵𳪠±ÔÄ¢À» + ãÀ» ¼ö ¾ø´Â °æ¿ì ÀÎÁõ°ú ±ÇÇѺο© ¸ðµÎ¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù. ÁÖ¾îÁø »ç¿ëÀÚ + ¾ÆÀ̵𳪠±ÔÄ¢À» ã¾Ò´Ù¸é º¸Å붧¿Í °°ÀÌ ¾ÏÈ£¿Í Á¢±ÙÇã¿ë¿©ºÎ¸¦ + °Ë»çÇÏ°í, ½ÇÆÐÇϸé "Authentication Required (ÀÎÁõ ÇÊ¿ä)" + ÀÀ´äÀ» ÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ ¸ðµâÀÇ µ¥ÀÌÅͺ£À̽º¿¡ »ç¿ëÀÚ ¾ÆÀ̵𰡠Àְųª + À¯È¿ÇÑ Require Áö½Ã¾î¸¦ + ¿©·¯ ¸ðµâ¿¡ Àû¿ëÇϸé, ù¹ø° ¸ðµâÀÌ »ç¿ëÀÚ¸¦ °Ë»çÇÏ°í, + AuthBasicAuthoritative ¼³Á¤°ú °ü°è¾øÀÌ + Á¢±ÙÀ» ³Ñ±âÁö¾Ê´Â´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â »ç¿ëÀÚ ¾ÆÀ̵ð¿Í + ±ÔÄ¢ÀÎ °æ¿ì "Authentication Required (ÀÎÁõ ÇÊ¿ä)" ÀÀ´äÀ» + ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, + NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_auth_basic.xml.meta b/trunk/docs/manual/mod/mod_auth_basic.xml.meta new file mode 100644 index 0000000000..ef31679fba --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_basic.xml.meta @@ -0,0 +1,13 @@ + + + + mod_auth_basic + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_auth_digest.html b/trunk/docs/manual/mod/mod_auth_digest.html new file mode 100644 index 0000000000..ff5152833c --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.html @@ -0,0 +1,7 @@ +URI: mod_auth_digest.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_auth_digest.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_auth_digest.html.en b/trunk/docs/manual/mod/mod_auth_digest.html.en new file mode 100644 index 0000000000..05a3fbcc2a --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.html.en @@ -0,0 +1,332 @@ + + + +mod_auth_digest - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_auth_digest

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:User authentication using MD5 + Digest Authentication.
    Status:Experimental
    Module Identifier:auth_digest_module
    Source File:mod_auth_digest.c
    +

    Summary

    + +

    This module implements HTTP Digest Authentication. However, it + has not been extensively tested and is therefore marked + experimental.

    +
    + +
    top
    +
    +

    Using Digest Authentication

    + +

    Using MD5 Digest authentication is very simple. Simply set + up authentication normally, using AuthType Digest and + AuthDigestProvider + instead of the normal AuthType Basic and + AuthBasicProvider. + Then add a AuthDigestDomain directive containing at least the root + URI(s) for this protection space.

    + +

    Appropriate user (text) files can be created using the + htdigest tool.

    + +

    Example:

    + <Location /private/>
    + + AuthType Digest
    + AuthName "private area"
    + AuthDigestDomain /private/ http://mirror.my.dom/private2/
    +
    + AuthDigestProvider file
    + AuthUserFile /web/auth/.digest_pw
    + Require valid-user
    +
    + </Location> +

    + +

    Note

    +

    Digest authentication is more secure than Basic authentication, + but only works with supporting browsers. As of September 2004, major + browsers that support digest authentication include Amaya, Konqueror, MS Internet Explorer + for Mac OS X and Windows (although the Windows version fails when + used with a query string -- see "Working with MS + Internet Explorer" below for a workaround), Mozilla, + Netscape 7, Opera, and Safari. lynx does not + support digest authentication. Since digest authentication is not as + widely implemented as basic authentication, you should use it only + in environments where all users will have supporting browsers.

    +
    +
    top
    +
    +

    Working with MS Internet Explorer

    +

    The Digest authentication implementation in current Internet + Explorer for Windows implementations has known issues, namely that + GET requests with a query string are not RFC compliant. + There are a few ways to work around this issue.

    + +

    + The first way is to use POST requests instead of + GET requests to pass data to your program. This method + is the simplest approach if your application can work with this + limitation. +

    + +

    Since version 2.0.51 Apache also provides a workaround in the + AuthDigestEnableQueryStringHack environment variable. + If AuthDigestEnableQueryStringHack is set for the + request, Apache will take steps to work around the MSIE bug and + remove the request URI from the digest comparison. Using this + method would look similar to the following.

    + +

    Using Digest Authentication with MSIE:

    + BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On +

    + +

    See the BrowserMatch + directive for more details on conditionally setting environment + variables

    +
    +
    top
    +

    AuthDigestAlgorithm Directive

    + + + + + + + + +
    Description:Selects the algorithm used to calculate the challenge and +response hashes in digest authentication
    Syntax:AuthDigestAlgorithm MD5|MD5-sess
    Default:AuthDigestAlgorithm MD5
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestAlgorithm directive + selects the algorithm used to calculate the challenge and response + hashes.

    + +
    + MD5-sess is not correctly implemented yet. +
    + + +
    +
    top
    +

    AuthDigestDomain Directive

    + + + + + + + +
    Description:URIs that are in the same protection space for digest +authentication
    Syntax:AuthDigestDomain URI [URI] ...
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestDomain directive allows + you to specify one or more URIs which are in the same protection + space (i.e. use the same realm and username/password info). + The specified URIs are prefixes; the client will assume + that all URIs "below" these are also protected by the same + username/password. The URIs may be either absolute URIs (i.e. + including a scheme, host, port, etc.) or relative URIs.

    + +

    This directive should always be specified and + contain at least the (set of) root URI(s) for this space. + Omitting to do so will cause the client to send the + Authorization header for every request sent to this + server. Apart from increasing the size of the request, it may + also have a detrimental effect on performance if AuthDigestNcCheck is on.

    + +

    The URIs specified can also point to different servers, in + which case clients (which understand this) will then share + username/password info across multiple servers without + prompting the user each time.

    + +
    +
    top
    +

    AuthDigestNcCheck Directive

    + + + + + + + +
    Description:Enables or disables checking of the nonce-count sent by the +server
    Syntax:AuthDigestNcCheck On|Off
    Default:AuthDigestNcCheck Off
    Context:server config
    Status:Experimental
    Module:mod_auth_digest
    +
    + Not implemented yet. +
    + + +
    +
    top
    +

    AuthDigestNonceFormat Directive

    + + + + + + + +
    Description:Determines how the nonce is generated
    Syntax:AuthDigestNonceFormat format
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +
    Not implemented yet.
    + + +
    +
    top
    +

    AuthDigestNonceLifetime Directive

    + + + + + + + + +
    Description:How long the server nonce is valid
    Syntax:AuthDigestNonceLifetime seconds
    Default:AuthDigestNonceLifetime 300
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestNonceLifetime directive + controls how long the server nonce is valid. When the client + contacts the server using an expired nonce the server will send + back a 401 with stale=true. If seconds is + greater than 0 then it specifies the amount of time for which the + nonce is valid; this should probably never be set to less than 10 + seconds. If seconds is less than 0 then the nonce never + expires. +

    + +
    +
    top
    +

    AuthDigestProvider Directive

    + + + + + + + + +
    Description:Sets the authentication provider(s) for this location
    Syntax:AuthDigestProvider On|Off|provider-name +[provider-name] ...
    Default:AuthDigestProvider On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestProvider directive sets + which provider is used to authenticate the users for this location. + Setting the value to On will choose the default provider + (file). Since the file provider is implemented + by the mod_authn_file module, you have to make sure, + that the module is present in the server.

    + +

    See mod_authn_dbm and mod_authn_file + for providers.

    + +

    The value Off clears the provider list and sets it back + to the default.

    + +
    +
    top
    +

    AuthDigestQop Directive

    + + + + + + + + +
    Description:Determines the quality-of-protection to use in digest +authentication
    Syntax:AuthDigestQop none|auth|auth-int [auth|auth-int]
    Default:AuthDigestQop auth
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestQop directive determines + the quality-of-protection to use. auth will + only do authentication (username/password); auth-int is + authentication plus integrity checking (an MD5 hash of the entity + is also computed and checked); none will cause the module + to use the old RFC-2069 digest algorithm (which does not include + integrity checking). Both auth and auth-int may + be specified, in which the case the browser will choose which of + these to use. none should only be used if the browser for + some reason does not like the challenge it receives otherwise.

    + +
    + auth-int is not implemented yet. +
    + +
    +
    top
    +

    AuthDigestShmemSize Directive

    + + + + + + + +
    Description:The amount of shared memory to allocate for keeping track +of clients
    Syntax:AuthDigestShmemSize size
    Default:AuthDigestShmemSize 1000
    Context:server config
    Status:Experimental
    Module:mod_auth_digest
    +

    The AuthDigestShmemSize directive defines + the amount of shared memory, that will be allocated at the server + startup for keeping track of clients. Note that the shared memory + segment cannot be set less than the space that is necessary for + tracking at least one client. This value is dependant on your + system. If you want to find out the exact value, you may simply + set AuthDigestShmemSize to the value of + 0 and read the error message after trying to start the + server.

    + +

    The size is normally expressed in Bytes, but you + may let the number follow a K or an M to + express your value as KBytes or MBytes. For example, the following + directives are all equivalent:

    + +

    + AuthDigestShmemSize 1048576
    + AuthDigestShmemSize 1024K
    + AuthDigestShmemSize 1M +

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_auth_digest.html.ko.euc-kr b/trunk/docs/manual/mod/mod_auth_digest.html.ko.euc-kr new file mode 100644 index 0000000000..ae9f10d49a --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.html.ko.euc-kr @@ -0,0 +1,321 @@ + + + +mod_auth_digest - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_auth_digest

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:MD5 Digest AuthenticationÀ» »ç¿ëÇÑ »ç¿ëÀÚÀÎÁõ.
    »óÅÂ:Experimental
    ¸ðµâ¸í:auth_digest_module
    ¼Ò½ºÆÄÀÏ:mod_auth_digest.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº HTTP Digest AuthenticationÀ» ±¸ÇöÇÑ´Ù. + ±×·¯³ª ¸¹Àº Å×½ºÆ®¸¦ °ÅÄ¡Áö ¾ÊÀº ½ÇÇèÀûÀÎ ¸ðµâÀÌ´Ù.

    +
    + +
    top
    +
    +

    Digest Authentication »ç¿ëÇϱâ

    + +

    MD5 Digest authenticationÀº ¸Å¿ì ½±°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù. + AuthType Basic°ú AuthBasicProvider ´ë½Å + AuthType Digest¿Í AuthDigestProvider¸¦ + »ç¿ëÇÏ¿© °£´ÜÈ÷ ÀÎÁõÀ» ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×¸®°í ÃÖ¼ÒÇÑ º¸È£ÇÏ·Á´Â + ¿µ¿ªÀÇ ±âº» URIÀ» AuthDigestDomain Áö½Ã¾î¿¡ »ç¿ëÇÑ´Ù.

    + +

    htdigest µµ±¸¸¦ + »ç¿ëÇÏ¿© »ç¿ëÀÚ (¹®ÀÚ)ÆÄÀÏÀ» ¸¸µé ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦:

    + <Location /private/>
    + + AuthType Digest
    + AuthName "private area"
    + AuthDigestDomain /private/ http://mirror.my.dom/private2/
    +
    + AuthDigestProvider file
    + AuthUserFile /web/auth/.digest_pw
    + Require valid-user
    +
    + </Location> +

    + +

    ÁÖÀÇ

    +

    Digest authenticationÀº Basic authenticationº¸´Ù ´õ + ¾ÈÀüÇÏÁö¸¸, ºê¶ó¿ìÀú°¡ Áö¿øÇØ¾ß ÇÑ´Ù. 2002³â 11¿ù ÇöÀç digest + authenticationÀ» Áö¿øÇÏ´Â ºê¶ó¿ìÀú¿¡´Â Amaya, Konqueror, (Windows¿ëÀº + ÁúÀǹ®ÀÚ¿­°ú ÇÔ²² »ç¿ëÇÏ¸é ¾ÈµÇÁö¸¸ - ÇØ°á¹æ¹ýÀº ¾Æ·¡ "MS Internet Explorer ¹®Á¦ ÇØ°áÇϱâ"¸¦ Âü°í) + Mac OS X¿Í Windows¿ë MS Internet + Explorer, Mozilla, + Netscape ¹öÀü 7, Opera, + Safari µîÀÌ ÀÖ´Ù. + lynx´Â digest authenticationÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù. digest authenticationÀÌ + basic authentication ¸¸Å­ ³Î¸® ±¸ÇöµÇÁö ¾Ê¾Ò±â¶§¹®¿¡ ¸ðµç + »ç¿ëÀÚ°¡ Áö¿øÇÏ´Â ºê¶ó¿ìÀú¸¦ »ç¿ëÇÏ´Â °æ¿ì¿¡¸¸ »ç¿ëÇØ¾ß + ÇÑ´Ù.

    +
    +
    top
    +
    +

    MS Internet Explorer ¹®Á¦ ÇØ°áÇϱâ

    +

    ÇöÀç Windows¿ë Internet Explorer´Â Digest authentication + »ç¿ë½Ã ÁúÀǹ®ÀÚ¿­ÀÌ ÀÖ´Â GET ¿äûÀ» RFC¿Í ´Ù¸£°Ô + ó¸®ÇÏ´Â ¹®Á¦°¡ ÀÖ´Ù. ¸î°¡Áö ¹æ¹ýÀ¸·Î ÀÌ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö + ÀÖ´Ù.

    + +

    + ù¹ø°´Â ÇÁ·Î±×·¥¿¡ ÀڷḦ ³Ñ°ÜÁÖ±âÀ§ÇØ GET + ´ë½Å POST ¿äûÀ» »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀÌ ¹æ¹ýÀÌ + °¡´ÉÇÏ´Ù¸é °¡Àå °£´ÜÇÑ ÇØ°áÃ¥ÀÌ´Ù. +

    + +

    ¶Ç, ¾ÆÆÄÄ¡ 2.0.51ºÎÅÍ AuthDigestEnableQueryStringHack + ȯ°æº¯¼ö¸¦ Á¦°øÇÏ¿© ¹®Á¦¸¦ ÇØ°áÇÑ´Ù. ¿äû¿¡ + AuthDigestEnableQueryStringHackÀ» ¼³Á¤Çϸé + ¾ÆÆÄÄ¡´Â MSIE ¹ö±×¸¦ ÇÇÇØ°¥ Á¶Ä¡¸¦ ÃëÇÏ°í ¿äû URI¸¦ digest + ºñ±³¿¡¼­ Á¦¿ÜÇÑ´Ù. ÀÌ ¹æ¹ýÀº ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    MSIE¿¡¼­ Digest Authentication »ç¿ëÇϱâ:

    + BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On +

    + +

    ¼±ÅÃÀûÀΠȯ°æº¯¼ö ¼³Á¤¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº BrowserMatch Áö½Ã¾î¸¦ + Âü°íÇ϶ó.

    +
    +
    top
    +

    AuthDigestAlgorithm Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:digest authentication¿¡¼­ challenge¿Í response +hash¸¦ °è»êÇÏ´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÑ´Ù
    ¹®¹ý:AuthDigestAlgorithm MD5|MD5-sess
    ±âº»°ª:AuthDigestAlgorithm MD5
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestAlgorithm Áö½Ã¾î´Â + challenge¿Í response hash¸¦ °è»êÇÏ´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÑ´Ù.

    + +
    + MD5-sess´Â ¾ÆÁ÷ ¿ÏÀüÈ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. +
    + + +
    +
    top
    +

    AuthDigestDomain Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:digest authentication¿¡¼­ °°Àº º¸È£¿µ¿ª¿¡ ¼ÓÇÏ´Â +URIµé
    ¹®¹ý:AuthDigestDomain URI [URI] ...
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestDomain Áö½Ã¾î´Â °°Àº + º¸È£¿µ¿ª¿¡ ÀÖ´Â (¿¹¸¦ µé¾î °°Àº ¿µ¿ª°ú »ç¿ëÀÚ¸í/¾ÏÈ£ + Á¤º¸¸¦ »ç¿ëÇÏ´Â) URIµéÀ» ÁöÁ¤ÇÑ´Ù. ÁöÁ¤ÇÑ URI´Â Á¢µÎ»ç·Î + »ç¿ëÇÑ´Ù. Ŭ¶óÀ̾ðÆ®´Â URI "¾Æ·¡" ¸ðµÎ¸¦ + °°Àº »ç¿ëÀÚ¸í/¾ÏÈ£·Î º¸È£ÇÑ´Ù°í °¡Á¤ÇÑ´Ù. URI´Â + (Áï, ½ºÅ´(scheme), È£½ºÆ®, Æ÷Æ® µîÀ» Æ÷ÇÔÇÏ´Â) + Àý´ë URLÀ̰ųª »ó´ë URIÀÌ´Ù.

    + +

    ÀÌ Áö½Ã¾î´Â Ç×»ó ÁöÁ¤ÇØ¾ß Çϸç, ÃÖ¼ÒÇÑ ¿µ¿ªµéÀÇ + ±âº» URI(µé)¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. »ý·«Çϸé Ŭ¶óÀ̾ðÆ®´Â + ÀÌ ¼­¹ö·Î º¸³»´Â ¸ðµç ¿äû¿¡ Authorization Çì´õ¸¦ + Æ÷ÇÔÇÑ´Ù. ±×·¯¸é ¿äûÀÇ Å©±â°¡ Ä¿Áö¸ç, AuthDigestNcCheck¸¦ + »ç¿ëÇÑ´Ù¸é ¼º´É¿¡ ³ª»Û ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ ¼­¹öÀÇ URI¸¦ ÁöÁ¤Çϸé, (À̸¦ ÀÌÇØÇÏ´Â) Ŭ¶óÀ̾ðÆ®´Â + ¿©·¯ ¼­¹ö¸¶´Ù ¸Å¹ø »ç¿ëÀÚ¿¡°Ô ¹¯Áö¾Ê°í °°Àº »ç¿ëÀÚ¸í/¾ÏÈ£¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    top
    +

    AuthDigestNcCheck Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¼­¹ö°¡ º¸³»´Â nonce-count¸¦ °Ë»çÇÒÁö ¿©ºÎ
    ¹®¹ý:AuthDigestNcCheck On|Off
    ±âº»°ª:AuthDigestNcCheck Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +
    + ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. +
    + + +
    +
    top
    +

    AuthDigestNonceFormat Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:nonce¸¦ ¸¸µå´Â ¹æ¹ýÀ» °áÁ¤ÇÑ´Ù
    ¹®¹ý:AuthDigestNonceFormat format
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +
    ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù.
    + + +
    +
    top
    +

    AuthDigestNonceLifetime Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¼­¹ö nonce°¡ À¯È¿ÇÑ ±â°£
    ¹®¹ý:AuthDigestNonceLifetime seconds
    ±âº»°ª:AuthDigestNonceLifetime 300
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestNonceLifetime Áö½Ã¾î´Â + ¼­¹ö nonce°¡ À¯È¿ÇÑ ±â°£À» Á¶ÀýÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¸¸±âµÈ + nonce¸¦ °¡Áö°í ¼­¹ö¿¡ Á¢±ÙÇÏ¸é ¼­¹ö´Â stale=true¿Í + ÇÔ²² 401À» ¹ÝȯÇÑ´Ù. seconds°¡ 0º¸´Ù Å©¸é nonce°¡ + À¯È¿ÇÑ ±â°£À» ÁöÁ¤ÇÑ´Ù. ¾Æ¸¶µµ 10 Ãʺ¸´Ù ÀÛ°Ô ¼³Á¤ÇÏ¸é ¾ÈµÈ´Ù. + seconds°¡ 0º¸´Ù ÀÛÀ¸¸é nonce´Â ¿µ¿øÈ÷ ¸¸±âµÇÁö + ¾Ê´Â´Ù. +

    + +
    +
    top
    +

    AuthDigestProvider Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthDigestProvider On|Off|provider-name +[provider-name] ...
    ±âº»°ª:AuthDigestProvider On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestProvider Áö½Ã¾î´Â ÀÌ + À§Ä¡¿¡¼­ »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ Á¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. °ªÀÌ + OnÀÌ¸é ±âº»Á¦°øÀÚ(file)¸¦ »ç¿ëÇÑ´Ù. + mod_authn_file ¸ðµâÀÌ file + Á¦°øÀÚ¸¦ ±¸ÇöÇϱ⶧¹®¿¡ ¼­¹ö¿¡ ÀÌ ¸ðµâÀÌ ÀÖ´ÂÁö È®ÀÎÇØ¾ß + ÇÑ´Ù.

    + +

    Á¦°øÀÚ´Â mod_authn_dbm°ú + mod_authn_fileÀ» Âü°íÇ϶ó.

    + +

    °ªÀÌ OffÀ̸é Á¦°øÀÚ ¸ñ·ÏÀ» Áö¿ì°í ±âº»»óÅ·Π+ µ¹¾Æ°£´Ù.

    + +
    +
    top
    +

    AuthDigestQop Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:digest authentication°¡ »ç¿ëÇÒ +º¸È£¼öÁØ(quality-of-protection)À» ÁöÁ¤ÇÑ´Ù.
    ¹®¹ý:AuthDigestQop none|auth|auth-int [auth|auth-int]
    ±âº»°ª:AuthDigestQop auth
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestQop Áö½Ã¾î´Â + º¸È£¼öÁØ(quality-of-protection)À» ÁöÁ¤ÇÑ´Ù. + auth´Â (»ç¿ëÀÚ¸í/¾ÏÈ£) ÀÎÁõ¸¸ ÇÏ°í, + auth-int´Â ÀÎÁõ°ú ¿Ï°á¼º °Ë»ç¸¦ (MD5 Çؽ¬µµ + °è»êÇÏ¿© °Ë»çÇÑ´Ù) ÇÑ´Ù. noneÀº (¿Ï°á¼º °Ë»ç¸¦ + ÇÏÁö¾Ê´Â) ¿À·¡µÈ RFC-2069 digest ¾Ë°í¸®ÁòÀ» »ç¿ëÇÑ´Ù. + auth¿Í auth-int¸¦ ¸ðµÎ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ºê¶ó¿ìÀú´Â ¾î¶² °ÍÀ» »ç¿ëÇÒÁö ¼±ÅÃÇÑ´Ù. + ºê¶ó¿ìÀú°¡ ¾î´ø ÀÌÀ¯¿¡¼­°Ç challenge¸¦ ÁÁ¾ÆÇÏÁö ¾Ê´Â´Ù¸é + noneÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +
    + auth-int´Â ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. +
    + +
    +
    top
    +

    AuthDigestShmemSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ÇÒ´çÇÏ´Â °øÀ¯¸Þ¸ð¸®·®
    ¹®¹ý:AuthDigestShmemSize size
    ±âº»°ª:AuthDigestShmemSize 1000
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_auth_digest
    +

    AuthDigestShmemSize Áö½Ã¾î´Â + Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ÇÒ´çÇÏ´Â + °øÀ¯¸Þ¸ð¸®·®À» Á¤ÀÇÇÑ´Ù. °øÀ¯¸Þ¸ð¸®´Â ÃÖ¼ÒÇÑ ÇϳªÀÇ + Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ÇÊ¿äÇÑ °ø°£º¸´Ù ÀÛÀ» ¼ö ¾øÀ½À» + ÁÖÀÇÇ϶ó. ÀÌ °ªÀº ½Ã½ºÅÛ¿¡ µû¶ó ´Ù¸£´Ù. Á¤È®ÇÑ °ªÀ» ¾Ë·Á¸é + AuthDigestShmemSize¸¦ 0À¸·Î + ¼³Á¤ÇÏ°í ¼­¹ö¸¦ ½ÃÀÛÇÑÈÄ ¿À·ù¹®À» Âü°íÇ϶ó.

    + +

    size´Â º¸Åë ¹ÙÀÌÆ® ´ÜÀ§ÀÌÁö¸¸, µÚ¿¡ + K³ª MÀ» »ç¿ëÇÏ¿© KBytes³ª MBytes¸¦ + ³ªÅ¸³¾ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ Áö½Ã¾îµéÀº ¸ðµÎ °°´Ù:

    + +

    + AuthDigestShmemSize 1048576
    + AuthDigestShmemSize 1024K
    + AuthDigestShmemSize 1M +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_auth_digest.xml b/trunk/docs/manual/mod/mod_auth_digest.xml new file mode 100644 index 0000000000..d71b35f13a --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.xml @@ -0,0 +1,343 @@ + + + + + + + + + +mod_auth_digest +User authentication using MD5 + Digest Authentication. +Experimental +mod_auth_digest.c +auth_digest_module + + +

    This module implements HTTP Digest Authentication. However, it + has not been extensively tested and is therefore marked + experimental.

    +
    + +AuthName +AuthType +Require +Satisfy + +
    Using Digest Authentication + +

    Using MD5 Digest authentication is very simple. Simply set + up authentication normally, using AuthType Digest and + AuthDigestProvider + instead of the normal AuthType Basic and + AuthBasicProvider. + Then add a AuthDigestDomain directive containing at least the root + URI(s) for this protection space.

    + +

    Appropriate user (text) files can be created using the + htdigest tool.

    + + Example: + <Location /private/>
    + + AuthType Digest
    + AuthName "private area"
    + AuthDigestDomain /private/ http://mirror.my.dom/private2/
    +
    + AuthDigestProvider file
    + AuthUserFile /web/auth/.digest_pw
    + Require valid-user
    +
    + </Location> +
    + + Note +

    Digest authentication is more secure than Basic authentication, + but only works with supporting browsers. As of September 2004, major + browsers that support digest authentication include Amaya, Konqueror, MS Internet Explorer + for Mac OS X and Windows (although the Windows version fails when + used with a query string -- see "Working with MS + Internet Explorer" below for a workaround), Mozilla, + Netscape 7, Opera, and Safari. lynx does not + support digest authentication. Since digest authentication is not as + widely implemented as basic authentication, you should use it only + in environments where all users will have supporting browsers.

    +
    +
    + +
    Working with MS Internet Explorer +

    The Digest authentication implementation in current Internet + Explorer for Windows implementations has known issues, namely that + GET requests with a query string are not RFC compliant. + There are a few ways to work around this issue.

    + +

    + The first way is to use POST requests instead of + GET requests to pass data to your program. This method + is the simplest approach if your application can work with this + limitation. +

    + +

    Since version 2.0.51 Apache also provides a workaround in the + AuthDigestEnableQueryStringHack environment variable. + If AuthDigestEnableQueryStringHack is set for the + request, Apache will take steps to work around the MSIE bug and + remove the request URI from the digest comparison. Using this + method would look similar to the following.

    + + Using Digest Authentication with MSIE: + BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On + + +

    See the BrowserMatch + directive for more details on conditionally setting environment + variables

    +
    + + + +AuthDigestProvider +Sets the authentication provider(s) for this location +AuthDigestProvider On|Off|provider-name +[provider-name] ... +AuthDigestProvider On +directory.htaccess + +AuthConfig + + +

    The AuthDigestProvider directive sets + which provider is used to authenticate the users for this location. + Setting the value to On will choose the default provider + (file). Since the file provider is implemented + by the mod_authn_file module, you have to make sure, + that the module is present in the server.

    + +

    See mod_authn_dbm and mod_authn_file + for providers.

    + +

    The value Off clears the provider list and sets it back + to the default.

    +
    +
    + + +AuthDigestQop +Determines the quality-of-protection to use in digest +authentication +AuthDigestQop none|auth|auth-int [auth|auth-int] +AuthDigestQop auth +directory.htaccess + +AuthConfig + + +

    The AuthDigestQop directive determines + the quality-of-protection to use. auth will + only do authentication (username/password); auth-int is + authentication plus integrity checking (an MD5 hash of the entity + is also computed and checked); none will cause the module + to use the old RFC-2069 digest algorithm (which does not include + integrity checking). Both auth and auth-int may + be specified, in which the case the browser will choose which of + these to use. none should only be used if the browser for + some reason does not like the challenge it receives otherwise.

    + + + auth-int is not implemented yet. + +
    +
    + + +AuthDigestNonceLifetime +How long the server nonce is valid +AuthDigestNonceLifetime seconds +AuthDigestNonceLifetime 300 +directory.htaccess + +AuthConfig + + +

    The AuthDigestNonceLifetime directive + controls how long the server nonce is valid. When the client + contacts the server using an expired nonce the server will send + back a 401 with stale=true. If seconds is + greater than 0 then it specifies the amount of time for which the + nonce is valid; this should probably never be set to less than 10 + seconds. If seconds is less than 0 then the nonce never + expires. +

    +
    +
    + + +AuthDigestNonceFormat +Determines how the nonce is generated +AuthDigestNonceFormat format +directory.htaccess + +AuthConfig + + + Not implemented yet. + + + + + +AuthDigestNcCheck +Enables or disables checking of the nonce-count sent by the +server +AuthDigestNcCheck On|Off +AuthDigestNcCheck Off +server config + + + + Not implemented yet. + + + + + + +AuthDigestAlgorithm +Selects the algorithm used to calculate the challenge and +response hashes in digest authentication +AuthDigestAlgorithm MD5|MD5-sess +AuthDigestAlgorithm MD5 +directory.htaccess + +AuthConfig + + +

    The AuthDigestAlgorithm directive + selects the algorithm used to calculate the challenge and response + hashes.

    + + + MD5-sess is not correctly implemented yet. + + +
    +
    + + +AuthDigestDomain +URIs that are in the same protection space for digest +authentication +AuthDigestDomain URI [URI] ... +directory.htaccess + +AuthConfig + + +

    The AuthDigestDomain directive allows + you to specify one or more URIs which are in the same protection + space (i.e. use the same realm and username/password info). + The specified URIs are prefixes; the client will assume + that all URIs "below" these are also protected by the same + username/password. The URIs may be either absolute URIs (i.e. + including a scheme, host, port, etc.) or relative URIs.

    + +

    This directive should always be specified and + contain at least the (set of) root URI(s) for this space. + Omitting to do so will cause the client to send the + Authorization header for every request sent to this + server. Apart from increasing the size of the request, it may + also have a detrimental effect on performance if AuthDigestNcCheck is on.

    + +

    The URIs specified can also point to different servers, in + which case clients (which understand this) will then share + username/password info across multiple servers without + prompting the user each time.

    +
    +
    + + +AuthDigestShmemSize +The amount of shared memory to allocate for keeping track +of clients +AuthDigestShmemSize size +AuthDigestShmemSize 1000 +server config + + +

    The AuthDigestShmemSize directive defines + the amount of shared memory, that will be allocated at the server + startup for keeping track of clients. Note that the shared memory + segment cannot be set less than the space that is necessary for + tracking at least one client. This value is dependant on your + system. If you want to find out the exact value, you may simply + set AuthDigestShmemSize to the value of + 0 and read the error message after trying to start the + server.

    + +

    The size is normally expressed in Bytes, but you + may let the number follow a K or an M to + express your value as KBytes or MBytes. For example, the following + directives are all equivalent:

    + + + AuthDigestShmemSize 1048576
    + AuthDigestShmemSize 1024K
    + AuthDigestShmemSize 1M +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_auth_digest.xml.ko b/trunk/docs/manual/mod/mod_auth_digest.xml.ko new file mode 100644 index 0000000000..89c25ebeb2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.xml.ko @@ -0,0 +1,329 @@ + + + + + + + + + +mod_auth_digest +MD5 Digest AuthenticationÀ» »ç¿ëÇÑ »ç¿ëÀÚÀÎÁõ. +Experimental +mod_auth_digest.c +auth_digest_module + + +

    ÀÌ ¸ðµâÀº HTTP Digest AuthenticationÀ» ±¸ÇöÇÑ´Ù. + ±×·¯³ª ¸¹Àº Å×½ºÆ®¸¦ °ÅÄ¡Áö ¾ÊÀº ½ÇÇèÀûÀÎ ¸ðµâÀÌ´Ù.

    +
    + +AuthName +AuthType +Require +Satisfy + +
    Digest Authentication »ç¿ëÇϱâ + +

    MD5 Digest authenticationÀº ¸Å¿ì ½±°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù. + AuthType Basic°ú AuthBasicProvider ´ë½Å + AuthType Digest¿Í AuthDigestProvider¸¦ + »ç¿ëÇÏ¿© °£´ÜÈ÷ ÀÎÁõÀ» ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×¸®°í ÃÖ¼ÒÇÑ º¸È£ÇÏ·Á´Â + ¿µ¿ªÀÇ ±âº» URIÀ» AuthDigestDomain Áö½Ã¾î¿¡ »ç¿ëÇÑ´Ù.

    + +

    htdigest µµ±¸¸¦ + »ç¿ëÇÏ¿© »ç¿ëÀÚ (¹®ÀÚ)ÆÄÀÏÀ» ¸¸µé ¼ö ÀÖ´Ù.

    + + ¿¹Á¦: + <Location /private/>
    + + AuthType Digest
    + AuthName "private area"
    + AuthDigestDomain /private/ http://mirror.my.dom/private2/
    +
    + AuthDigestProvider file
    + AuthUserFile /web/auth/.digest_pw
    + Require valid-user
    +
    + </Location> +
    + + ÁÖÀÇ +

    Digest authenticationÀº Basic authenticationº¸´Ù ´õ + ¾ÈÀüÇÏÁö¸¸, ºê¶ó¿ìÀú°¡ Áö¿øÇØ¾ß ÇÑ´Ù. 2002³â 11¿ù ÇöÀç digest + authenticationÀ» Áö¿øÇÏ´Â ºê¶ó¿ìÀú¿¡´Â Amaya, Konqueror, (Windows¿ëÀº + ÁúÀǹ®ÀÚ¿­°ú ÇÔ²² »ç¿ëÇÏ¸é ¾ÈµÇÁö¸¸ - ÇØ°á¹æ¹ýÀº ¾Æ·¡ "MS Internet Explorer ¹®Á¦ ÇØ°áÇϱâ"¸¦ Âü°í) + Mac OS X¿Í Windows¿ë MS Internet + Explorer, Mozilla, + Netscape ¹öÀü 7, Opera, + Safari µîÀÌ ÀÖ´Ù. + lynx´Â digest authenticationÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù. digest authenticationÀÌ + basic authentication ¸¸Å­ ³Î¸® ±¸ÇöµÇÁö ¾Ê¾Ò±â¶§¹®¿¡ ¸ðµç + »ç¿ëÀÚ°¡ Áö¿øÇÏ´Â ºê¶ó¿ìÀú¸¦ »ç¿ëÇÏ´Â °æ¿ì¿¡¸¸ »ç¿ëÇØ¾ß + ÇÑ´Ù.

    +
    +
    + +
    MS Internet Explorer ¹®Á¦ ÇØ°áÇϱâ +

    ÇöÀç Windows¿ë Internet Explorer´Â Digest authentication + »ç¿ë½Ã ÁúÀǹ®ÀÚ¿­ÀÌ ÀÖ´Â GET ¿äûÀ» RFC¿Í ´Ù¸£°Ô + ó¸®ÇÏ´Â ¹®Á¦°¡ ÀÖ´Ù. ¸î°¡Áö ¹æ¹ýÀ¸·Î ÀÌ ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö + ÀÖ´Ù.

    + +

    + ù¹ø°´Â ÇÁ·Î±×·¥¿¡ ÀڷḦ ³Ñ°ÜÁÖ±âÀ§ÇØ GET + ´ë½Å POST ¿äûÀ» »ç¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀÌ ¹æ¹ýÀÌ + °¡´ÉÇÏ´Ù¸é °¡Àå °£´ÜÇÑ ÇØ°áÃ¥ÀÌ´Ù. +

    + +

    ¶Ç, ¾ÆÆÄÄ¡ 2.0.51ºÎÅÍ AuthDigestEnableQueryStringHack + ȯ°æº¯¼ö¸¦ Á¦°øÇÏ¿© ¹®Á¦¸¦ ÇØ°áÇÑ´Ù. ¿äû¿¡ + AuthDigestEnableQueryStringHackÀ» ¼³Á¤Çϸé + ¾ÆÆÄÄ¡´Â MSIE ¹ö±×¸¦ ÇÇÇØ°¥ Á¶Ä¡¸¦ ÃëÇÏ°í ¿äû URI¸¦ digest + ºñ±³¿¡¼­ Á¦¿ÜÇÑ´Ù. ÀÌ ¹æ¹ýÀº ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù.

    + + MSIE¿¡¼­ Digest Authentication »ç¿ëÇϱâ: + BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On + + +

    ¼±ÅÃÀûÀΠȯ°æº¯¼ö ¼³Á¤¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº BrowserMatch Áö½Ã¾î¸¦ + Âü°íÇ϶ó.

    +
    + + + +AuthDigestProvider +ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù +AuthDigestProvider On|Off|provider-name +[provider-name] ... +AuthDigestProvider On +directory.htaccess + +AuthConfig + + +

    AuthDigestProvider Áö½Ã¾î´Â ÀÌ + À§Ä¡¿¡¼­ »ç¿ëÀÚ¸¦ ÀÎÁõÇÒ Á¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. °ªÀÌ + OnÀÌ¸é ±âº»Á¦°øÀÚ(file)¸¦ »ç¿ëÇÑ´Ù. + mod_authn_file ¸ðµâÀÌ file + Á¦°øÀÚ¸¦ ±¸ÇöÇϱ⶧¹®¿¡ ¼­¹ö¿¡ ÀÌ ¸ðµâÀÌ ÀÖ´ÂÁö È®ÀÎÇØ¾ß + ÇÑ´Ù.

    + +

    Á¦°øÀÚ´Â mod_authn_dbm°ú + mod_authn_fileÀ» Âü°íÇ϶ó.

    + +

    °ªÀÌ OffÀ̸é Á¦°øÀÚ ¸ñ·ÏÀ» Áö¿ì°í ±âº»»óÅ·Π+ µ¹¾Æ°£´Ù.

    +
    +
    + + +AuthDigestQop +digest authentication°¡ »ç¿ëÇÒ +º¸È£¼öÁØ(quality-of-protection)À» ÁöÁ¤ÇÑ´Ù. +AuthDigestQop none|auth|auth-int [auth|auth-int] +AuthDigestQop auth +directory.htaccess + +AuthConfig + + +

    AuthDigestQop Áö½Ã¾î´Â + º¸È£¼öÁØ(quality-of-protection)À» ÁöÁ¤ÇÑ´Ù. + auth´Â (»ç¿ëÀÚ¸í/¾ÏÈ£) ÀÎÁõ¸¸ ÇÏ°í, + auth-int´Â ÀÎÁõ°ú ¿Ï°á¼º °Ë»ç¸¦ (MD5 Çؽ¬µµ + °è»êÇÏ¿© °Ë»çÇÑ´Ù) ÇÑ´Ù. noneÀº (¿Ï°á¼º °Ë»ç¸¦ + ÇÏÁö¾Ê´Â) ¿À·¡µÈ RFC-2069 digest ¾Ë°í¸®ÁòÀ» »ç¿ëÇÑ´Ù. + auth¿Í auth-int¸¦ ¸ðµÎ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ºê¶ó¿ìÀú´Â ¾î¶² °ÍÀ» »ç¿ëÇÒÁö ¼±ÅÃÇÑ´Ù. + ºê¶ó¿ìÀú°¡ ¾î´ø ÀÌÀ¯¿¡¼­°Ç challenge¸¦ ÁÁ¾ÆÇÏÁö ¾Ê´Â´Ù¸é + noneÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    + + + auth-int´Â ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. + +
    +
    + + +AuthDigestNonceLifetime +¼­¹ö nonce°¡ À¯È¿ÇÑ ±â°£ +AuthDigestNonceLifetime seconds +AuthDigestNonceLifetime 300 +directory.htaccess + +AuthConfig + + +

    AuthDigestNonceLifetime Áö½Ã¾î´Â + ¼­¹ö nonce°¡ À¯È¿ÇÑ ±â°£À» Á¶ÀýÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ ¸¸±âµÈ + nonce¸¦ °¡Áö°í ¼­¹ö¿¡ Á¢±ÙÇÏ¸é ¼­¹ö´Â stale=true¿Í + ÇÔ²² 401À» ¹ÝȯÇÑ´Ù. seconds°¡ 0º¸´Ù Å©¸é nonce°¡ + À¯È¿ÇÑ ±â°£À» ÁöÁ¤ÇÑ´Ù. ¾Æ¸¶µµ 10 Ãʺ¸´Ù ÀÛ°Ô ¼³Á¤ÇÏ¸é ¾ÈµÈ´Ù. + seconds°¡ 0º¸´Ù ÀÛÀ¸¸é nonce´Â ¿µ¿øÈ÷ ¸¸±âµÇÁö + ¾Ê´Â´Ù. +

    +
    +
    + + +AuthDigestNonceFormat +nonce¸¦ ¸¸µå´Â ¹æ¹ýÀ» °áÁ¤ÇÑ´Ù +AuthDigestNonceFormat format +directory.htaccess + +AuthConfig + + + ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. + + + + + +AuthDigestNcCheck +¼­¹ö°¡ º¸³»´Â nonce-count¸¦ °Ë»çÇÒÁö ¿©ºÎ +AuthDigestNcCheck On|Off +AuthDigestNcCheck Off +server config + + + + ¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. + + + + + + +AuthDigestAlgorithm +digest authentication¿¡¼­ challenge¿Í response +hash¸¦ °è»êÇÏ´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÑ´Ù +AuthDigestAlgorithm MD5|MD5-sess +AuthDigestAlgorithm MD5 +directory.htaccess + +AuthConfig + + +

    AuthDigestAlgorithm Áö½Ã¾î´Â + challenge¿Í response hash¸¦ °è»êÇÏ´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÑ´Ù.

    + + + MD5-sess´Â ¾ÆÁ÷ ¿ÏÀüÈ÷ ±¸ÇöµÇÁö ¾Ê¾Ò´Ù. + + +
    +
    + + +AuthDigestDomain +digest authentication¿¡¼­ °°Àº º¸È£¿µ¿ª¿¡ ¼ÓÇÏ´Â +URIµé +AuthDigestDomain URI [URI] ... +directory.htaccess + +AuthConfig + + +

    AuthDigestDomain Áö½Ã¾î´Â °°Àº + º¸È£¿µ¿ª¿¡ ÀÖ´Â (¿¹¸¦ µé¾î °°Àº ¿µ¿ª°ú »ç¿ëÀÚ¸í/¾ÏÈ£ + Á¤º¸¸¦ »ç¿ëÇÏ´Â) URIµéÀ» ÁöÁ¤ÇÑ´Ù. ÁöÁ¤ÇÑ URI´Â Á¢µÎ»ç·Î + »ç¿ëÇÑ´Ù. Ŭ¶óÀ̾ðÆ®´Â URI "¾Æ·¡" ¸ðµÎ¸¦ + °°Àº »ç¿ëÀÚ¸í/¾ÏÈ£·Î º¸È£ÇÑ´Ù°í °¡Á¤ÇÑ´Ù. URI´Â + (Áï, ½ºÅ´(scheme), È£½ºÆ®, Æ÷Æ® µîÀ» Æ÷ÇÔÇÏ´Â) + Àý´ë URLÀ̰ųª »ó´ë URIÀÌ´Ù.

    + +

    ÀÌ Áö½Ã¾î´Â Ç×»ó ÁöÁ¤ÇØ¾ß Çϸç, ÃÖ¼ÒÇÑ ¿µ¿ªµéÀÇ + ±âº» URI(µé)¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. »ý·«Çϸé Ŭ¶óÀ̾ðÆ®´Â + ÀÌ ¼­¹ö·Î º¸³»´Â ¸ðµç ¿äû¿¡ Authorization Çì´õ¸¦ + Æ÷ÇÔÇÑ´Ù. ±×·¯¸é ¿äûÀÇ Å©±â°¡ Ä¿Áö¸ç, AuthDigestNcCheck¸¦ + »ç¿ëÇÑ´Ù¸é ¼º´É¿¡ ³ª»Û ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ ¼­¹öÀÇ URI¸¦ ÁöÁ¤Çϸé, (À̸¦ ÀÌÇØÇÏ´Â) Ŭ¶óÀ̾ðÆ®´Â + ¿©·¯ ¼­¹ö¸¶´Ù ¸Å¹ø »ç¿ëÀÚ¿¡°Ô ¹¯Áö¾Ê°í °°Àº »ç¿ëÀÚ¸í/¾ÏÈ£¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + + +AuthDigestShmemSize +Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ÇÒ´çÇÏ´Â °øÀ¯¸Þ¸ð¸®·® +AuthDigestShmemSize size +AuthDigestShmemSize 1000 +server config + + +

    AuthDigestShmemSize Áö½Ã¾î´Â + Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ÇÒ´çÇÏ´Â + °øÀ¯¸Þ¸ð¸®·®À» Á¤ÀÇÇÑ´Ù. °øÀ¯¸Þ¸ð¸®´Â ÃÖ¼ÒÇÑ ÇϳªÀÇ + Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ÇÊ¿äÇÑ °ø°£º¸´Ù ÀÛÀ» ¼ö ¾øÀ½À» + ÁÖÀÇÇ϶ó. ÀÌ °ªÀº ½Ã½ºÅÛ¿¡ µû¶ó ´Ù¸£´Ù. Á¤È®ÇÑ °ªÀ» ¾Ë·Á¸é + AuthDigestShmemSize¸¦ 0À¸·Î + ¼³Á¤ÇÏ°í ¼­¹ö¸¦ ½ÃÀÛÇÑÈÄ ¿À·ù¹®À» Âü°íÇ϶ó.

    + +

    size´Â º¸Åë ¹ÙÀÌÆ® ´ÜÀ§ÀÌÁö¸¸, µÚ¿¡ + K³ª MÀ» »ç¿ëÇÏ¿© KBytes³ª MBytes¸¦ + ³ªÅ¸³¾ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ Áö½Ã¾îµéÀº ¸ðµÎ °°´Ù:

    + + + AuthDigestShmemSize 1048576
    + AuthDigestShmemSize 1024K
    + AuthDigestShmemSize 1M +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_auth_digest.xml.meta b/trunk/docs/manual/mod/mod_auth_digest.xml.meta new file mode 100644 index 0000000000..d976dc5c9e --- /dev/null +++ b/trunk/docs/manual/mod/mod_auth_digest.xml.meta @@ -0,0 +1,12 @@ + + + + mod_auth_digest + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_authn_alias.html b/trunk/docs/manual/mod/mod_authn_alias.html new file mode 100644 index 0000000000..6abb4b348d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_alias.html @@ -0,0 +1,3 @@ +URI: mod_authn_alias.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_authn_alias.html.en b/trunk/docs/manual/mod/mod_authn_alias.html.en new file mode 100644 index 0000000000..da70607b0c --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_alias.html.en @@ -0,0 +1,121 @@ + + + +mod_authn_alias - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authn_alias

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Provides the ability to create extended authentication + providers based on actual providers
    Status:Extension
    Module Identifier:authn_alias_module
    Source File:mod_authn_alias.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module allows extended authentication providers to be created + within the configuration file and assigned an alias name. The alias + providers can then be referenced through the directives + AuthBasicProvider or + AuthDigestProvider in + the same way as a base authentication provider. Besides the ability + to create and alias an extended provider, it also allows the same + extended authentication provider to be reference by multiple + locations.

    + +
    +

    Directives

    + +

    Topics

    +
    +
    top
    +
    +

    Example

    +

    The example below creates two different ldap authentication + provider aliases based on the ldap provider. This allows + a single authenticated location can be serviced by multiple + ldap hosts:

    + +

    Example

    + LoadModule authn_alias_module modules/mod_authn_alias.so

    + <AuthnProviderAlias ldap ldap-alias1>
    + + AuthLDAPBindDN cn=youruser,o=ctx
    + AuthLDAPBindPassword yourpassword
    + AuthLDAPURL ldap://ldap.host/o=ctx
    +
    + </AuthnProviderAlias>

    + <AuthnProviderAlias ldap ldap-other-alias>
    + + AuthLDAPBindDN cn=yourotheruser,o=dev
    + AuthLDAPBindPassword yourotherpassword
    + AuthLDAPURL ldap://other.ldap.host/o=dev?cn
    +
    + </AuthnProviderAlias>

    + + Alias /secure /webpages/secure
    + <Directory /webpages/secure>
    + + Order deny,allow
    + Allow from all

    + + AuthBasicProvider ldap-other-alias ldap-alias1

    + + AuthType Basic
    + AuthName LDAP_Protected_Place
    + AuthzLDAPAuthoritative off
    + require valid-user
    +
    + </Directory>
    +

    +
    +
    top
    +

    <AuthnProviderAlias> Directive

    + + + + + + +
    Description:Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    Syntax:<AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>
    Context:server config, virtual host
    Status:Extension
    Module:mod_authn_alias
    +

    <AuthnProviderAlias> and + </AuthnProviderAlias> are used to enclose a group of + authentication directives that can be referenced by the alias name + using one of the directives + AuthBasicProvider or + AuthDigestProvider.

    + + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_alias.xml b/trunk/docs/manual/mod/mod_authn_alias.xml new file mode 100644 index 0000000000..6ba51d0c1b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_alias.xml @@ -0,0 +1,107 @@ + + + + + + + + + +mod_authn_alias +Provides the ability to create extended authentication + providers based on actual providers +Extension +mod_authn_alias.c +authn_alias_module +Available in Apache 2.1 and later + + +

    This module allows extended authentication providers to be created + within the configuration file and assigned an alias name. The alias + providers can then be referenced through the directives + AuthBasicProvider or + AuthDigestProvider in + the same way as a base authentication provider. Besides the ability + to create and alias an extended provider, it also allows the same + extended authentication provider to be reference by multiple + locations.

    + +
    + +
    Example +

    The example below creates two different ldap authentication + provider aliases based on the ldap provider. This allows + a single authenticated location can be serviced by multiple + ldap hosts:

    + + Example + LoadModule authn_alias_module modules/mod_authn_alias.so

    + <AuthnProviderAlias ldap ldap-alias1>
    + + AuthLDAPBindDN cn=youruser,o=ctx
    + AuthLDAPBindPassword yourpassword
    + AuthLDAPURL ldap://ldap.host/o=ctx
    +
    + </AuthnProviderAlias>

    + <AuthnProviderAlias ldap ldap-other-alias>
    + + AuthLDAPBindDN cn=yourotheruser,o=dev
    + AuthLDAPBindPassword yourotherpassword
    + AuthLDAPURL ldap://other.ldap.host/o=dev?cn
    +
    + </AuthnProviderAlias>

    + + Alias /secure /webpages/secure
    + <Directory /webpages/secure>
    + + Order deny,allow
    + Allow from all

    + + AuthBasicProvider ldap-other-alias ldap-alias1

    + + AuthType Basic
    + AuthName LDAP_Protected_Place
    + AuthzLDAPAuthoritative off
    + require valid-user
    +
    + </Directory>
    +
    +
    + + +AuthnProviderAlias +Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias +<AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias> +server configvirtual host + + + +

    AuthnProviderAlias and + </AuthnProviderAlias> are used to enclose a group of + authentication directives that can be referenced by the alias name + using one of the directives + AuthBasicProvider or + AuthDigestProvider.

    + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_alias.xml.meta b/trunk/docs/manual/mod/mod_authn_alias.xml.meta new file mode 100644 index 0000000000..276887d0e1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_alias.xml.meta @@ -0,0 +1,11 @@ + + + + mod_authn_alias + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_authn_anon.html b/trunk/docs/manual/mod/mod_authn_anon.html new file mode 100644 index 0000000000..3afcbf615b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.html @@ -0,0 +1,11 @@ +URI: mod_authn_anon.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authn_anon.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authn_anon.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authn_anon.html.en b/trunk/docs/manual/mod/mod_authn_anon.html.en new file mode 100644 index 0000000000..107cdd30ab --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.html.en @@ -0,0 +1,224 @@ + + + +mod_authn_anon - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authn_anon

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Allows "anonymous" user access to authenticated + areas
    Status:Extension
    Module Identifier:authn_anon_module
    Source File:mod_authn_anon.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authentication front-ends such as + mod_auth_basic to authenticate users similar + to anonymous-ftp sites, i.e. have a 'magic' user id + 'anonymous' and the email address as a password. These email + addresses can be logged.

    + +

    Combined with other (database) access control methods, this + allows for effective user tracking and customization according + to a user profile while still keeping the site open for + 'unregistered' users. One advantage of using Auth-based user + tracking is that, unlike magic-cookies and funny URL + pre/postfixes, it is completely browser independent and it + allows users to share URLs.

    + +

    When using mod_auth_basic, this module is invoked + via the AuthBasicProvider + directive with the anon value.

    +
    + +
    top
    +
    +

    Example

    +

    The example below is combined with "normal" htpasswd-file based + authentication and allows users in additionally as 'guests' with the + following properties:

    + +
      +
    • It insists that the user enters a userID. + (Anonymous_NoUserID)
    • + +
    • It insists that the user enters a password. + (Anonymous_MustGiveEmail)
    • + +
    • The password entered must be a valid email address, i.e. + contain at least one '@' and a '.'. + (Anonymous_VerifyEmail)
    • + +
    • The userID must be one of anonymous guest www test + welcome and comparison is not case + sensitive. (Anonymous)
    • + +
    • And the Email addresses entered in the passwd field are + logged to the error log file. + (Anonymous_LogEmail)
    • +
    + +

    Example

    + <Directory /foo> + + AuthName "Use 'anonymous' & Email address for guest entry"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +

    +
    +
    top
    +

    Anonymous Directive

    + + + + + + + +
    Description:Specifies userIDs that are allowed access without +password verification
    Syntax:Anonymous user [user] ...
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_anon
    +

    A list of one or more 'magic' userIDs which are allowed + access without password verification. The userIDs are space + separated. It is possible to use the ' and " quotes to allow a + space in a userID as well as the \ escape character.

    + +

    Please note that the comparison is + case-IN-sensitive.
    + It's strongly recommended that the magic username + 'anonymous' is always one of the allowed + userIDs.

    + +

    Example:

    + Anonymous anonymous "Not Registered" "I don't know" +

    + +

    This would allow the user to enter without password + verification by using the userIDs "anonymous", + "AnonyMous", "Not Registered" and "I Don't Know".

    + +

    As of Apache 2.1 it is possible to specify the userID as + "*". That allows any supplied userID to be + accepted.

    + +
    +
    top
    +

    Anonymous_LogEmail Directive

    + + + + + + + + +
    Description:Sets whether the password entered will be logged in the +error log
    Syntax:Anonymous_LogEmail On|Off
    Default:Anonymous_LogEmail On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_anon
    +

    When set On, the default, the 'password' entered + (which hopefully contains a sensible email address) is logged in + the error log.

    + +
    +
    top
    +

    Anonymous_MustGiveEmail Directive

    + + + + + + + + +
    Description:Specifies whether blank passwords are allowed
    Syntax:Anonymous_MustGiveEmail On|Off
    Default:Anonymous_MustGiveEmail On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_anon
    +

    Specifies whether the user must specify an email address as + the password. This prohibits blank passwords.

    + +
    +
    top
    +

    Anonymous_NoUserID Directive

    + + + + + + + + +
    Description:Sets whether the userID field may be empty
    Syntax:Anonymous_NoUserID On|Off
    Default:Anonymous_NoUserID Off
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_anon
    +

    When set On, users can leave the userID (and + perhaps the password field) empty. This can be very convenient for + MS-Explorer users who can just hit return or click directly on the + OK button; which seems a natural reaction.

    + +
    +
    top
    +

    Anonymous_VerifyEmail Directive

    + + + + + + + + +
    Description:Sets whether to check the password field for a correctly +formatted email address
    Syntax:Anonymous_VerifyEmail On|Off
    Default:Anonymous_VerifyEmail Off
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_anon
    +

    When set On the 'password' entered is checked for + at least one '@' and a '.' to encourage users to enter valid email + addresses (see the above Anonymous_LogEmail).

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_anon.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authn_anon.html.ja.euc-jp new file mode 100644 index 0000000000..31373f2319 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.html.ja.euc-jp @@ -0,0 +1,224 @@ + + + +mod_authn_anon - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authn_anon

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:ǧ¾Ú¤¬É¬ÍפÊÎΰè¤Ø¤Î "anonymous" ¥æ¡¼¥¶¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë +
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authn_anon_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authn_anon.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_auth_basic ¤Î¤è¤¦¤Ê + ǧ¾Ú¥Õ¥í¥ó¥È¥¨¥ó¥É¤È¤·¤Æ¡¢anonymous-ftp ¥µ¥¤¥È¤Î¤è¤¦¤Ê¡¢¡ÖËâË¡¤Î¡×¥æ¡¼¥¶ ID + 'anonymous' ¤ÈÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤ò¥Ñ¥¹¥ï¡¼¥É¤Ë¤·¤¿¥æ¡¼¥¶Ç§¾Ú¤ò + ¹Ô¤Ê¤¦µ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£¤³¤ÎÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ï¥í¥°¼ý½¸¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +

    ¾¤Î (¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤è¤ë) ¥¢¥¯¥»¥¹À©¸æÊýË¡¤ÈÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¡¢ + ¡Ö̤ÅÐÏ¿¡×¥æ¡¼¥¶¤ËÂФ·¤Æ¥µ¥¤¥È¤ò¸ø³«¤·¤Ä¤Ä¡¢¸úΨ¤è¤¯¥æ¡¼¥¶ÄÉÀפ·¤¿¤ê¡¢ + ¥æ¡¼¥¶¤Î¥×¥í¥Õ¥¡¥¤¥ë¤Ë±þ¤¸¤¿¥«¥¹¥¿¥Þ¥¤¥º¤ò¤·¤¿¤ê¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Êǧ¾Ú¤Ë´ð¤Å¤¤¤¿¥æ¡¼¥¶ÄÉÀפÎÍøÅÀ¤Î°ì¤Ä¤Ï¡¢ + ¥Þ¥¸¥Ã¥¯¥¯¥Ã¥­¡¼¤Ë´ð¤Å¤¯¥æ¡¼¥¶ÄÉÀ×ÊýË¡¤ä¡¢ + ÄÁ̯¤Ê URL ¤ÎÀÜƬ¼­¤äÀÜÈø¼­¤òÍøÍѤ·¤¿¥æ¡¼¥¶ÄÉÀ×ÊýË¡¤È¤Ï°Û¤Ê¤ê¡¢ + ´°Á´¤Ë¥Ö¥é¥¦¥¶Èó°Í¸¤Ç¤¢¤ê¡¢¥æ¡¼¥¶´Ö¤Ç URL ¤ò¶¦Í­¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤È¤¤¤¦ + ÅÀ¤Ç¤¹¡£

    + +

    mod_auth_basic ¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï + AuthBasicProvider ¤Ë + anon ¤È¤¤¤¦ÃͤòÀßÄꤹ¤ë¤³¤È¤Çµ¯Æ°¤µ¤ì¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    Îã

    +

    °Ê²¼¤ÎÎã¤Ï¡ÖÉáÄ̡פΠhtpasswd ¥Õ¥¡¥¤¥ë¤Ë´ð¤Å¤¤¤¿Ç§¾Ú¤ÈÁȤ߹ç¤ï¤µ¤ì¤Æ + ¤ª¤ê¡¢°Ê²¼¤ÎÍ×·ï¤ò¸«¤¿¤¹¥æ¡¼¥¶¤ò¡Ö¥²¥¹¥È¡×¤È¤·¤Æµö²Ä¤·¤Þ¤¹:

    + +
      +
    • ¥æ¡¼¥¶¤Ï userID ¤òÆþÎϤ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + (Anonymous_NoUserID)
    • + +
    • ¥æ¡¼¥¶¤Ï¥Ñ¥¹¥ï¡¼¥É¤òÆþÎϤ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + (Anonymous_MustGiveEmail)
    • + +
    • ÆþÎϤµ¤ì¤¿¥Ñ¥¹¥ï¡¼¥É¤ÏÍ­¸ú¤ÊÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ç¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£¤¹¤Ê¤ï¤Á¡¢¾¯¤¯¤È¤â°ì¤Ä¤Î '@' ¤È '.' ¤¬ + ´Þ¤Þ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + (Anonymous_VerifyEmail)
    • + +
    • userID ¤Ï anonymous guest www test + welcome ¤Î¤É¤ì¤«¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¥æ¡¼¥¶Ì¾¤ÎÈæ³Ó¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£
    • + +
    • ¥Ñ¥¹¥ï¡¼¥ÉÍó¤ËÆþÎϤµ¤ì¤¿ÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ï¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤Ë + ¥í¥®¥ó¥°¤µ¤ì¤Þ¤¹¡£ + (Anonymous_LogEmail)
    • +
    + +

    Îã

    + <Directory /foo> + + AuthName "Use 'anonymous' & Email address for guest entry"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +

    +
    +
    top
    +

    Anonymous ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ñ¥¹¥ï¡¼¥É¤Î¸¡ººÌµ¤·¤Ç¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë userID ¤ò»ØÄꤹ¤ë +
    ¹½Ê¸:Anonymous user [user] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_anon
    +

    ¥Ñ¥¹¥ï¡¼¥É¤Î¸¡ºº¤ò¤·¤Ê¤¤¤Ç¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë¡ÖËâË¡¤Î¡× userID ¤ò + ÀßÄꤷ¤Þ¤¹¡£userID Ãæ¤Ë¶õÇò¤ò»È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¡¢ + ¥¨¥¹¥±¡¼¥×ʸ»ú \ ¤Ë¤è¤ëÊýË¡¤È¡¢°úÍÑÉä ' ¤È " ¤Ë¤è¤ë¥¯¥ª¡¼¥Æ¥£¥ó¥° + ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥æ¡¼¥¶Ì¾¤ÎÈæ³Ó¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
    + ËâË¡¤Î¥æ¡¼¥¶Ì¾ 'anonymous' ¤¬µö²Ä¤µ¤ì¤Æ¤¤¤ë userID ¤Ë + ´Þ¤à¤è¤¦¤Ë¤¹¤ë¤³¤È¤Ï¶¯¤¯¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    Îã:

    + Anonymous anonymous "Not Registered" "I don't know" +

    + +

    ¤³¤ì¤Ï¡¢userID "anonymous", + "AnonyMous", "Not Registered", "I Don't Know" ¤Î¤É¤ì¤«¤ò»È¤Ã¤Æ¤â + ¥Ñ¥¹¥ï¡¼¥É̵¤·¤Ç¥æ¡¼¥¶¤¬¥µ¥¤¥È¤ËÆþ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    Apache 2.1 ¤Ç¤Ï userID ¤Ë "*" ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢¤¹¤Ù¤Æ¤ÎuserID ¤òµö²Ä¤·¤Þ¤¹¡£

    + +
    +
    top
    +

    Anonymous_LogEmail ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ÆþÎϤµ¤ì¤¿¥Ñ¥¹¥ï¡¼¥É¤¬¥¨¥é¡¼¥í¥°¤Ë¥í¥®¥ó¥°¤µ¤ì¤ë¤«¤É¤¦¤«¤ò +ÀßÄꤹ¤ë
    ¹½Ê¸:Anonymous_LogEmail On|Off
    ¥Ç¥Õ¥©¥ë¥È:Anonymous_LogEmail On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_anon
    +

    ¥Ç¥Õ¥©¥ë¥È¤Î On ¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢ + ÆþÎϤµ¤ì¤¿ (¤Þ¤Ã¤È¤¦¤ÊÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ç¤¢¤ë¤³¤È¤¬ + ´üÂÔ¤µ¤ì¤ë) ¡Ö¥Ñ¥¹¥ï¡¼¥É¡×¤¬¥¨¥é¡¼¥í¥°¤Ë¥í¥®¥ó¥°¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    Anonymous_MustGiveEmail ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¶õ¥Ñ¥¹¥ï¡¼¥É¤òµö²Ä¤¹¤ë¤«¤É¤¦¤«¤ò»ØÄꤹ¤ë
    ¹½Ê¸:Anonymous_MustGiveEmail On|Off
    ¥Ç¥Õ¥©¥ë¥È:Anonymous_MustGiveEmail On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_anon
    +

    ¥æ¡¼¥¶¤¬¥Ñ¥¹¥ï¡¼¥É¤È¤·¤ÆÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¤«¤É¤¦¤«¤ò + ÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï¶õ¥Ñ¥¹¥ï¡¼¥É¤ò¶Ø»ß¤·¤Þ¤¹¡£

    + +
    +
    top
    +

    Anonymous_NoUserID ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¶õ userID ¤òµö²Ä¤¹¤ë¤«¤ò»ØÄꤹ¤ë
    ¹½Ê¸:Anonymous_NoUserID On|Off
    ¥Ç¥Õ¥©¥ë¥È:Anonymous_NoUserID Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_anon
    +

    On ¤ËÀßÄꤹ¤ë¤È¡¢¥æ¡¼¥¶¤Ï userID (¤È¤ª¤½¤é¤¯¤Ï + ¥Ñ¥¹¥ï¡¼¥ÉÍó¤â) ¶õ¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ïñ¤Ë¥ê¥¿¡¼¥ó¥­¡¼¤ò + ᤤ¤¿¤ê OK ¥Ü¥¿¥ó¤òľÀÜ¥¯¥ê¥Ã¥¯¤·¤¿¤ê¤¹¤ë MS-Explorer ¥æ¡¼¥¶¤Ë¤Ï + Èó¾ï¤ËÊØÍø¤Ç¤¹¡£¤½¤Î¤è¤¦¤ÊÁàºî¤Ï¤´¤¯¤´¤¯¼«Á³¤Ê¤â¤Î¤Ç¤·¤ç¤¦¡£

    + +
    +
    top
    +

    Anonymous_VerifyEmail ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Ñ¥¹¥ï¡¼¥ÉÍó¤¬Àµ¤·¤¤·Á¼°¤ÎÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ç¤¢¤ë¤³¤È¤ò +Ä´¤Ù¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    ¹½Ê¸:Anonymous_VerifyEmail On|Off
    ¥Ç¥Õ¥©¥ë¥È:Anonymous_VerifyEmail Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_anon
    +

    On ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥æ¡¼¥¶¤¬Í­¸ú¤ÊÅŻҥ᡼¥ë + ¥¢¥É¥ì¥¹¤òÆþÎϤ¹¤ë¤³¤È¤ò¿ä¾©¤¹¤ë¤¿¤á¡¢ÆþÎϤµ¤ì¤¿¡Ö¥Ñ¥¹¥ï¡¼¥É¡×¤Ï + ¾¯¤Ê¤¯¤È¤â°ì¤Ä¤Î '@' ¤È '.' ¤ò´Þ¤ó¤Ç¤¤¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤Þ¤¹ + (¾å¤Î Anonymous_LogEmail »²¾È)¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_anon.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authn_anon.html.ko.euc-kr new file mode 100644 index 0000000000..14a5e98d36 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.html.ko.euc-kr @@ -0,0 +1,211 @@ + + + +mod_authn_anon - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authn_anon

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÀÎÁõ¿µ¿ª¿¡ "À͸í(anonymous)" »ç¿ëÀÚÀÇ Á¢±ÙÀ» +Çã¿ëÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:authn_anon_module
    ¼Ò½ºÆÄÀÏ:mod_authn_anon.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_auth_basic µî ÀÎÁõ¾Õ´Ü¸ðµâÀ» + À§ÇØ (¿¹¸¦ µé¾î 'Ưº°ÇÑ' »ç¿ëÀÚ ¾ÆÀ̵ð 'anonymous'¿Í + ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ¾ÏÈ£·Î »ç¿ëÇÏ´Â) À͸í-ftp »çÀÌÆ®¿Í À¯»çÇÑ + »ç¿ëÀÚ ÀÎÁõÀ» ÇÑ´Ù. ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ·Î±×¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ (µ¥ÀÌÅͺ£À̽º) Á¢±ÙÁ¦¾î ¹æ½Ä°ú ÇÔ²² »ç¿ëÇÏ¿© + 'µî·ÏÇÏÁö¾ÊÀº' »ç¿ëÀÚ¿¡°Ô »çÀÌÆ®¸¦ ¿­¾îµÎ¸é¼­ È¿À²ÀûÀÎ »ç¿ëÀÚ + ÃßÀû°ú »ç¿ëÀÚÁ¤ÀÇ°¡ °¡´ÉÇÏ´Ù. ÀÎÁõ±â¹Ý »ç¿ëÀÚ ÃßÀûÀº ÄíÅ°³ª + ±«»óÇÑ URL Á¢µÎ»ç/Á¢¹Ì»ç¿Í ´Þ¸® ¿ÏÀüÈ÷ ºê¶ó¿ìÀú µ¶¸³ÀûÀÌ°í + »ç¿ëÀÚ°¡ URLÀ» °øÀ¯ÇÒ ¼ö ÀÖ´Ù´Â ÀåÁ¡ÀÌ ÀÖ´Ù.

    + +

    mod_auth_basicÀ» »ç¿ëÇÒ¶§ AuthBasicProviderÀÇ + °ªÀ¸·Î anonÀ» ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¿¹Á¦

    +

    ´ÙÀ½ ¿¹´Â "ÀϹÝÀûÀÎ" htpasswd-ÆÄÀϱâ¹Ý ÀÎÁõ¿¡ Ãß°¡·Î + »ç¿ëÀÚ°¡ ´ÙÀ½ Á¶°ÇÀ» ¸¸Á·ÇÑ´Ù¸é '¼Õ´Ô(guest)'À¸·Î Á¢±ÙÇÒ + ¼ö ÀÖµµ·Ï ÇÑ´Ù:

    + +
      +
    • »ç¿ëÀÚ´Â »ç¿ëÀÚ ¾ÆÀ̵𸦠ÀÔ·ÂÇØ¾ß ÇÑ´Ù. (Anonymous_NoUserID)
    • + +
    • »ç¿ëÀÚ´Â ¾ÏÈ£¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. (Anonymous_MustGiveEmail)
    • + +
    • ¾ÏÈ£·Î À¯È¿ÇÑ ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. ¿¹¸¦ + µé¾î ÃÖ¼ÒÇÑ '@'¿Í '.' ÇÑ°³¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. (Anonymous_VerifyEmail)
    • + +
    • »ç¿ëÀÚ ¾ÆÀ̵ð´Â anonymous guest www test + welcome Áß ÇϳªÀ̸ç, ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö + ¾Ê´Â´Ù. (Anonymous)
    • + +
    • ±×¸®°í ¾ÏÈ£·Î ÀÔ·ÂÇÑ ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ¿À·ù·Î±×ÆÄÀÏ¿¡ + ±â·ÏÇÑ´Ù. (Anonymous_LogEmail)
    • +
    + +

    ¿¹Á¦

    + <Directory /foo> + + AuthName "¼Õ´ÔÀ¸·Î ¹æ¹®ÇÏ·Á¸é 'anonymous'¿Í ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +

    +
    +
    top
    +

    Anonymous Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¾ÏÈ£°Ë»ç¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÒ »ç¿ëÀÚ ¾ÆÀ̵ðµéÀ» +ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:Anonymous user [user] ...
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_anon
    +

    ¾ÏÈ£°Ë»ç¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÒ 'Ưº°ÇÑ' »ç¿ëÀÚ ¾ÆÀ̵ð ¸ñ·Ï. + »ç¿ëÀÚ ¾ÆÀ̵ðµéÀ» °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. µû¿ÈÇ¥ '¿Í "³ª Å»Ãâ¹®ÀÚ + \¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ ¾ÆÀ̵ð ¾È¿¡ °ø¹éÀ» Æ÷ÇÔÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÀ̵ð´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾ÊÀ½À» + ÁÖÀÇÇ϶ó.
    + Çã¿ëÇÒ »ç¿ëÀÚ ¾ÆÀ̵𿡠Ưº°ÇÑ »ç¿ëÀÚ¸íÀÎ + 'anonymous'¸¦ Ç×»ó Æ÷ÇÔÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + +

    ¿¹Á¦:

    + Anonymous anonymous "Not Registered" "I don't know" +

    + +

    "anonymous", "AnonyMous", "Not Registered", "I Don't Know" + µî »ç¿ëÀÚ ¾ÆÀ̵𸦠»ç¿ëÇÏ¸é ¾ÏÈ£°Ë»ç¾øÀÌ »ç¿ëÀÚ¸¦ Çã¿ëÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.1¿¡¼­´Â »ç¿ëÀÚ ¾ÆÀ̵ð·Î "*"¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯¸é ¾î¶² »ç¿ëÀÚ ¾ÆÀ̵ð¶óµµ + ¹Þ¾ÆµéÀδÙ.

    + +
    +
    top
    +

    Anonymous_LogEmail Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ÀÔ·ÂÇÑ ¾ÏÈ£¸¦ ¿À·ù·Î±×¿¡ ±â·ÏÇÒÁö ¿©ºÎ
    ¹®¹ý:Anonymous_LogEmail On|Off
    ±âº»°ª:Anonymous_LogEmail On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_anon
    +

    ±âº»°ªÀÎ OnÀ¸·Î ¼³Á¤Çϸé (¾Æ¸¶µµ ÀüÀÚ¿ìÆí + ÁÖ¼ÒÀÏ) ÀÔ·ÂÇÑ '¾ÏÈ£'¸¦ ¿À·ù·Î±×¿¡ ±â·ÏÇÑ´Ù.

    + +
    +
    top
    +

    Anonymous_MustGiveEmail Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¾ÏÈ£°¡ ¾ø¾îµµ °¡´ÉÇÑÁö ¿©ºÎ
    ¹®¹ý:Anonymous_MustGiveEmail On|Off
    ±âº»°ª:Anonymous_MustGiveEmail On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_anon
    +

    »ç¿ëÀÚ°¡ ¾ÏÈ£·Î ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ÀÔ·ÂÇØ¾ß ÇÏ´ÂÁö ¿©ºÎ¸¦ + °áÁ¤ÇÑ´Ù. ¾ÏÈ£°¡ ¾øÀ¸¸é °ÅºÎÇÑ´Ù.

    + +
    +
    top
    +

    Anonymous_NoUserID Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:»ç¿ëÀÚ ¾ÆÀ̵𰡠¾ø¾îµµ °¡´ÉÇÏÁö ¿©ºÎ
    ¹®¹ý:Anonymous_NoUserID On|Off
    ±âº»°ª:Anonymous_NoUserID Off
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_anon
    +

    OnÀ¸·Î ¼³Á¤ÇÏ¸é »ç¿ëÀÚ´Â »ç¿ëÀÚ ¾ÆÀ̵𸦠+ (¾Æ¸¶ ¾ÏÈ£µµ) ÀÔ·ÂÇÏÁö ¾Ê¾Æµµ µÈ´Ù. ÀÌ´Â ÀÚ¿¬½º·´°Ô ±×³É + returnÀ» Ä¡°Å³ª OK ¹öÆ°À» Ŭ¸¯ÇÏ´Â MS-Explorer »ç¿ëÀÚ¿¡°Ô + ¸Å¿ì Æí¸®ÇÏ´Ù.

    + +
    +
    top
    +

    Anonymous_VerifyEmail Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¾ÏÈ£°¡ ¿Ã¹Ù¸¥ Çü½ÄÀÇ ÀüÀÚ¿ìÆí ÁÖ¼ÒÀÎÁö °Ë»ç +¿©ºÎ
    ¹®¹ý:Anonymous_VerifyEmail On|Off
    ±âº»°ª:Anonymous_VerifyEmail Off
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_anon
    +

    OnÀ¸·Î ¼³Á¤ÇÏ¸é »ç¿ëÀÚ°¡ ¿Ã¹Ù¸¥ ÀüÀÚ¿ìÆí + ÁÖ¼Ò¸¦ ÀÔ·ÂÇϵµ·Ï ÀÔ·ÂÇÑ '¾ÏÈ£'°¡ ÃÖ¼ÒÇÑ '@'¿Í '.'¸¦ ÇÑ°³¾¿ + Æ÷ÇÔÇÏ´ÂÁö °Ë»çÇÑ´Ù (À§ÀÇ Anonymous_LogEmail Âü°í).

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_anon.xml b/trunk/docs/manual/mod/mod_authn_anon.xml new file mode 100644 index 0000000000..82ab3667d7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.xml @@ -0,0 +1,208 @@ + + + + + + + + + +mod_authn_anon +Allows "anonymous" user access to authenticated + areas +Extension +mod_authn_anon.c +authn_anon_module +Available in Apache 2.1 and later + + +

    This module provides authentication front-ends such as + mod_auth_basic to authenticate users similar + to anonymous-ftp sites, i.e. have a 'magic' user id + 'anonymous' and the email address as a password. These email + addresses can be logged.

    + +

    Combined with other (database) access control methods, this + allows for effective user tracking and customization according + to a user profile while still keeping the site open for + 'unregistered' users. One advantage of using Auth-based user + tracking is that, unlike magic-cookies and funny URL + pre/postfixes, it is completely browser independent and it + allows users to share URLs.

    + +

    When using mod_auth_basic, this module is invoked + via the AuthBasicProvider + directive with the anon value.

    +
    + +
    Example +

    The example below is combined with "normal" htpasswd-file based + authentication and allows users in additionally as 'guests' with the + following properties:

    + +
      +
    • It insists that the user enters a userID. + (Anonymous_NoUserID)
    • + +
    • It insists that the user enters a password. + (Anonymous_MustGiveEmail)
    • + +
    • The password entered must be a valid email address, i.e. + contain at least one '@' and a '.'. + (Anonymous_VerifyEmail)
    • + +
    • The userID must be one of anonymous guest www test + welcome and comparison is not case + sensitive. (Anonymous)
    • + +
    • And the Email addresses entered in the passwd field are + logged to the error log file. + (Anonymous_LogEmail)
    • +
    + + Example + <Directory /foo> + + AuthName "Use 'anonymous' & Email address for guest entry"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +
    +
    + + +Anonymous +Specifies userIDs that are allowed access without +password verification +Anonymous user [user] ... +directory.htaccess + +AuthConfig + + +

    A list of one or more 'magic' userIDs which are allowed + access without password verification. The userIDs are space + separated. It is possible to use the ' and " quotes to allow a + space in a userID as well as the \ escape character.

    + +

    Please note that the comparison is + case-IN-sensitive.
    + It's strongly recommended that the magic username + 'anonymous' is always one of the allowed + userIDs.

    + + Example: + Anonymous anonymous "Not Registered" "I don't know" + + +

    This would allow the user to enter without password + verification by using the userIDs "anonymous", + "AnonyMous", "Not Registered" and "I Don't Know".

    + +

    As of Apache 2.1 it is possible to specify the userID as + "*". That allows any supplied userID to be + accepted.

    +
    +
    + + +Anonymous_LogEmail +Sets whether the password entered will be logged in the +error log +Anonymous_LogEmail On|Off +Anonymous_LogEmail On +directory.htaccess + +AuthConfig + + +

    When set On, the default, the 'password' entered + (which hopefully contains a sensible email address) is logged in + the error log.

    +
    +
    + + +Anonymous_MustGiveEmail +Specifies whether blank passwords are allowed +Anonymous_MustGiveEmail On|Off +Anonymous_MustGiveEmail On +directory.htaccess + +AuthConfig + + +

    Specifies whether the user must specify an email address as + the password. This prohibits blank passwords.

    +
    +
    + + +Anonymous_NoUserID +Sets whether the userID field may be empty +Anonymous_NoUserID On|Off +Anonymous_NoUserID Off +directory.htaccess + +AuthConfig + + +

    When set On, users can leave the userID (and + perhaps the password field) empty. This can be very convenient for + MS-Explorer users who can just hit return or click directly on the + OK button; which seems a natural reaction.

    +
    +
    + + +Anonymous_VerifyEmail +Sets whether to check the password field for a correctly +formatted email address +Anonymous_VerifyEmail On|Off +Anonymous_VerifyEmail Off +directory.htaccess + +AuthConfig + + +

    When set On the 'password' entered is checked for + at least one '@' and a '.' to encourage users to enter valid email + addresses (see the above Anonymous_LogEmail).

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_anon.xml.ja b/trunk/docs/manual/mod/mod_authn_anon.xml.ja new file mode 100644 index 0000000000..3858e3656d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.xml.ja @@ -0,0 +1,207 @@ + + + + + + + + + +mod_authn_anon +$BG'>Z$,I,MW$JNN0h$X$N(B "anonymous" $B%f!<%6$N%"%/%;%9$r5v2D$9$k(B + +Extension +mod_authn_anon.c +authn_anon_module +Apache 2.1 $B0J9_(B + + +

    $B$3$N%b%8%e!<%k$O(B mod_auth_basic $B$N$h$&$J(B + $BG'>Z%U%m%s%H%(%s%I$H$7$F!"(Banonymous-ftp $B%5%$%H$N$h$&$J!"!VKbK!$N!W%f!<%6(B ID + 'anonymous' $B$HEE;R%a!<%k%"%I%l%9$r%Q%9%o!<%I$K$7$?%f!<%6G'>Z$r(B + $B9T$J$&5!G=$rDs6!$7$^$9!#$3$NEE;R%a!<%k%"%I%l%9$O%m%0<}=8$9$k$3$H$,(B + $B$G$-$^$9!#(B

    + +

    $BB>$N(B ($B%G!<%?%Y!<%9$K$h$k(B) $B%"%/%;%9@)8fJ}K!$HAH$_9g$o$;$k$3$H$G!"(B + $B!VL$EPO?!W%f!<%6$KBP$7$F%5%$%H$r8x3+$7$D$D!"8zN($h$/%f!<%6DI@W$7$?$j!"(B + $B%f!<%6$N%W%m%U%!%$%k$K1~$8$?%+%9%?%^%$%:$r$7$?$j$G$-$^$9!#(B + $B$3$N$h$&$JG'>Z$K4p$E$$$?%f!<%6DI@W$NMxE@$N0l$D$O!"(B + $B%^%8%C%/%/%C%-!<$K4p$E$/%f!<%6DI@WJ}K!$d!"(B + $BDAL/$J(B URL $B$N@\F,<-$d@\Hx<-$rMxMQ$7$?%f!<%6DI@WJ}K!$H$O0[$J$j!"(B + $B40A4$K%V%i%&%6Hs0MB8$G$"$j!"%f!<%64V$G(B URL $B$r6&M-$9$k$3$H$,$G$-$k$H$$$&(B + $BE@$G$9!#(B

    + +

    mod_auth_basic $B$r;HMQ$7$F$$$k>l9g$O!"$3$N%b%8%e!<%k$O(B + AuthBasicProvider $B$K(B + anon $B$H$$$&CM$r@_Dj$9$k$3$H$G5/F0$5$l$^$9!#(B

    +
    + +
    $BNc(B +

    $B0J2<$NNc$O!VIaDL!W$N(B htpasswd $B%U%!%$%k$K4p$E$$$?G'>Z$HAH$_9g$o$5$l$F(B + $B$*$j!"0J2<$NMW7o$r8+$?$9%f!<%6$r!V%2%9%H!W$H$7$F5v2D$7$^$9(B:

    + +
      +
    • $B%f!<%6$O(B userID $B$rF~NO$7$J$1$l$P$J$j$^$;$s!#(B + (Anonymous_NoUserID)
    • + +
    • $B%f!<%6$O%Q%9%o!<%I$rF~NO$7$J$1$l$P$J$j$^$;$s!#(B + (Anonymous_MustGiveEmail)
    • + +
    • $BF~NO$5$l$?%Q%9%o!<%I$OM-8z$JEE;R%a!<%k%"%I%l%9$G$J$1$l$P(B + $B$J$j$^$;$s!#(B$B$9$J$o$A(B$B!">/$/$H$b0l$D$N(B '@' $B$H(B '.' $B$,(B + $B4^$^$l$F$$$kI,MW$,$"$j$^$9!#(B + (Anonymous_VerifyEmail)
    • + +
    • userID $B$O(B anonymous guest www test + welcome $B$N$I$l$+$G$J$1$l$P$J$j$^$;$s!#(B + $B%f!<%6L>$NHf3S$OBgJ8;z>.J8;z$r6hJL(B$B$7$^$;$s!#(B
    • + +
    • $B%Q%9%o!<%IMs$KF~NO$5$l$?EE;R%a!<%k%"%I%l%9$O%(%i!<%m%0%U%!%$%k$K(B + $B%m%.%s%0$5$l$^$9!#(B + (Anonymous_LogEmail)
    • +
    + + $BNc(B + <Directory /foo> + + AuthName "Use 'anonymous' & Email address for guest entry"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +
    +
    + + +Anonymous +$B%Q%9%o!<%I$N8!::L5$7$G%"%/%;%9$r5v2D$9$k(B userID $B$r;XDj$9$k(B + +Anonymous user [user] ... +directory.htaccess + +AuthConfig + + +

    $B%Q%9%o!<%I$N8!::$r$7$J$$$G%"%/%;%9$r5v2D$9$k!VKbK!$N!W(B userID $B$r(B + $B@_Dj$7$^$9!#(BuserID $BCf$K6uGr$r;H$($k$h$&$K$9$k$?$a!"(B + $B%(%9%1!<%WJ8;z(B \ $B$K$h$kJ}K!$H!"0zMQId(B ' $B$H(B " $B$K$h$k%/%*!<%F%#%s%0(B + $B$r;H$&$3$H$,$G$-$^$9!#(B

    + +

    $B%f!<%6L>$NHf3S$O(B$BBgJ8;z>.J8;z$r6hJL$7$J$$(B$B$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B
    + $BKbK!$N%f!<%6L>(B 'anonymous' $B$,5v2D$5$l$F$$$k(B userID $B$K(B + $B4^$`$h$&$K$9$k$3$H$O6/$/?d>)$5$l$F$$$^$9!#(B

    + + $BNc(B: + Anonymous anonymous "Not Registered" "I don't know" + + +

    $B$3$l$O!"(BuserID "anonymous", + "AnonyMous", "Not Registered", "I Don't Know" $B$N$I$l$+$r;H$C$F$b(B + $B%Q%9%o!<%IL5$7$G%f!<%6$,%5%$%H$KF~$l$k$h$&$K$7$^$9!#(B

    + +

    Apache 2.1 $B$G$O(B userID $B$K(B "*" $B$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B$3$N>l9g!"(B$B$9$Y$F$N(BuserID $B$r5v2D$7$^$9!#(B

    +
    +
    + + +Anonymous_LogEmail +$BF~NO$5$l$?%Q%9%o!<%I$,%(%i!<%m%0$K%m%.%s%0$5$l$k$+$I$&$+$r(B +$B@_Dj$9$k(B +Anonymous_LogEmail On|Off +Anonymous_LogEmail On +directory.htaccess + +AuthConfig + + +

    $B%G%U%)%k%H$N(B On $B$K@_Dj$5$l$?>l9g$O!"(B + $BF~NO$5$l$?(B ($B$^$C$H$&$JEE;R%a!<%k%"%I%l%9$G$"$k$3$H$,(B + $B4|BT$5$l$k(B) $B!V%Q%9%o!<%I!W$,%(%i!<%m%0$K%m%.%s%0$5$l$^$9!#(B

    +
    +
    + + +Anonymous_MustGiveEmail +$B6u%Q%9%o!<%I$r5v2D$9$k$+$I$&$+$r;XDj$9$k(B +Anonymous_MustGiveEmail On|Off +Anonymous_MustGiveEmail On +directory.htaccess + +AuthConfig + + +

    $B%f!<%6$,%Q%9%o!<%I$H$7$FEE;R%a!<%k%"%I%l%9$r;XDj$9$kI,MW$,$"$k$+$I$&$+$r(B + $B@_Dj$7$^$9!#$3$l$O6u%Q%9%o!<%I$r6X;_$7$^$9!#(B

    +
    +
    + + +Anonymous_NoUserID +$B6u(B userID $B$r5v2D$9$k$+$r;XDj$9$k(B +Anonymous_NoUserID On|Off +Anonymous_NoUserID Off +directory.htaccess + +AuthConfig + + +

    On $B$K@_Dj$9$k$H!"%f!<%6$O(B userID ($B$H$*$=$i$/$O(B + $B%Q%9%o!<%IMs$b(B) $B6u$K$9$k$3$H$,$G$-$^$9!#$3$l$OC1$K%j%?!<%s%-!<$r(B + $BC!$$$?$j(B OK $B%\%?%s$rD>@\%/%j%C%/$7$?$j$9$k(B MS-Explorer $B%f!<%6$K$O(B + $BHs>o$KJXMx$G$9!#$=$N$h$&$JA`:n$O$4$/$4$/<+A3$J$b$N$G$7$g$&!#(B

    +
    +
    + + +Anonymous_VerifyEmail +$B%Q%9%o!<%IMs$,@5$7$$7A<0$NEE;R%a!<%k%"%I%l%9$G$"$k$3$H$r(B +$BD4$Y$k$+$I$&$+$r@_Dj$9$k(B +Anonymous_VerifyEmail On|Off +Anonymous_VerifyEmail Off +directory.htaccess + +AuthConfig + + +

    On $B$K@_Dj$5$l$F$$$k>l9g!"%f!<%6$,M-8z$JEE;R%a!<%k(B + $B%"%I%l%9$rF~NO$9$k$3$H$r?d>)$9$k$?$a!"F~NO$5$l$?!V%Q%9%o!<%I!W$O(B + $B>/$J$/$H$b0l$D$N(B '@' $B$H(B '.' $B$r4^$s$G$$$k$+$I$&$+$rD4$Y$^$9(B + ($B>e$N(B Anonymous_LogEmail $B;2>H(B)$B!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_anon.xml.ko b/trunk/docs/manual/mod/mod_authn_anon.xml.ko new file mode 100644 index 0000000000..ca2821edf6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.xml.ko @@ -0,0 +1,196 @@ + + + + + + + + + +mod_authn_anon +ÀÎÁõ¿µ¿ª¿¡ "À͸í(anonymous)" »ç¿ëÀÚÀÇ Á¢±ÙÀ» +Çã¿ëÇÑ´Ù +Extension +mod_authn_anon.c +authn_anon_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº mod_auth_basic µî ÀÎÁõ¾Õ´Ü¸ðµâÀ» + À§ÇØ (¿¹¸¦ µé¾î 'Ưº°ÇÑ' »ç¿ëÀÚ ¾ÆÀ̵ð 'anonymous'¿Í + ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ¾ÏÈ£·Î »ç¿ëÇÏ´Â) À͸í-ftp »çÀÌÆ®¿Í À¯»çÇÑ + »ç¿ëÀÚ ÀÎÁõÀ» ÇÑ´Ù. ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ·Î±×¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    + +

    ´Ù¸¥ (µ¥ÀÌÅͺ£À̽º) Á¢±ÙÁ¦¾î ¹æ½Ä°ú ÇÔ²² »ç¿ëÇÏ¿© + 'µî·ÏÇÏÁö¾ÊÀº' »ç¿ëÀÚ¿¡°Ô »çÀÌÆ®¸¦ ¿­¾îµÎ¸é¼­ È¿À²ÀûÀÎ »ç¿ëÀÚ + ÃßÀû°ú »ç¿ëÀÚÁ¤ÀÇ°¡ °¡´ÉÇÏ´Ù. ÀÎÁõ±â¹Ý »ç¿ëÀÚ ÃßÀûÀº ÄíÅ°³ª + ±«»óÇÑ URL Á¢µÎ»ç/Á¢¹Ì»ç¿Í ´Þ¸® ¿ÏÀüÈ÷ ºê¶ó¿ìÀú µ¶¸³ÀûÀÌ°í + »ç¿ëÀÚ°¡ URLÀ» °øÀ¯ÇÒ ¼ö ÀÖ´Ù´Â ÀåÁ¡ÀÌ ÀÖ´Ù.

    + +

    mod_auth_basicÀ» »ç¿ëÇÒ¶§ AuthBasicProviderÀÇ + °ªÀ¸·Î anonÀ» ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    + +
    ¿¹Á¦ +

    ´ÙÀ½ ¿¹´Â "ÀϹÝÀûÀÎ" htpasswd-ÆÄÀϱâ¹Ý ÀÎÁõ¿¡ Ãß°¡·Î + »ç¿ëÀÚ°¡ ´ÙÀ½ Á¶°ÇÀ» ¸¸Á·ÇÑ´Ù¸é '¼Õ´Ô(guest)'À¸·Î Á¢±ÙÇÒ + ¼ö ÀÖµµ·Ï ÇÑ´Ù:

    + +
      +
    • »ç¿ëÀÚ´Â »ç¿ëÀÚ ¾ÆÀ̵𸦠ÀÔ·ÂÇØ¾ß ÇÑ´Ù. (Anonymous_NoUserID)
    • + +
    • »ç¿ëÀÚ´Â ¾ÏÈ£¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. (Anonymous_MustGiveEmail)
    • + +
    • ¾ÏÈ£·Î À¯È¿ÇÑ ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. ¿¹¸¦ + µé¾î ÃÖ¼ÒÇÑ '@'¿Í '.' ÇÑ°³¸¦ Æ÷ÇÔÇØ¾ß ÇÑ´Ù. (Anonymous_VerifyEmail)
    • + +
    • »ç¿ëÀÚ ¾ÆÀ̵ð´Â anonymous guest www test + welcome Áß ÇϳªÀ̸ç, ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö + ¾Ê´Â´Ù. (Anonymous)
    • + +
    • ±×¸®°í ¾ÏÈ£·Î ÀÔ·ÂÇÑ ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ¿À·ù·Î±×ÆÄÀÏ¿¡ + ±â·ÏÇÑ´Ù. (Anonymous_LogEmail)
    • +
    + + ¿¹Á¦ + <Directory /foo> + + AuthName "¼Õ´ÔÀ¸·Î ¹æ¹®ÇÏ·Á¸é 'anonymous'¿Í ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ »ç¿ëÇ϶ó"
    + AuthType Basic
    + AuthBasicProvider file anon
    + AuthUserFile /path/to/your/.htpasswd
    +
    + Anonymous_NoUserID off
    + Anonymous_MustGiveEmail on
    + Anonymous_VerifyEmail on
    + Anonymous_LogEmail on
    + Anonymous anonymous guest www test welcome
    +
    + Order Deny,Allow
    + Allow from all
    +
    + Require valid-user
    +
    + </Directory> +
    +
    + + +Anonymous +¾ÏÈ£°Ë»ç¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÒ »ç¿ëÀÚ ¾ÆÀ̵ðµéÀ» +ÁöÁ¤ÇÑ´Ù +Anonymous user [user] ... +directory.htaccess + +AuthConfig + + +

    ¾ÏÈ£°Ë»ç¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÒ 'Ưº°ÇÑ' »ç¿ëÀÚ ¾ÆÀ̵ð ¸ñ·Ï. + »ç¿ëÀÚ ¾ÆÀ̵ðµéÀ» °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. µû¿ÈÇ¥ '¿Í "³ª Å»Ãâ¹®ÀÚ + \¸¦ »ç¿ëÇÏ¿© »ç¿ëÀÚ ¾ÆÀ̵ð ¾È¿¡ °ø¹éÀ» Æ÷ÇÔÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÀ̵ð´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾ÊÀ½À» + ÁÖÀÇÇ϶ó.
    + Çã¿ëÇÒ »ç¿ëÀÚ ¾ÆÀ̵𿡠Ưº°ÇÑ »ç¿ëÀÚ¸íÀÎ + 'anonymous'¸¦ Ç×»ó Æ÷ÇÔÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + + ¿¹Á¦: + Anonymous anonymous "Not Registered" "I don't know" + + +

    "anonymous", "AnonyMous", "Not Registered", "I Don't Know" + µî »ç¿ëÀÚ ¾ÆÀ̵𸦠»ç¿ëÇÏ¸é ¾ÏÈ£°Ë»ç¾øÀÌ »ç¿ëÀÚ¸¦ Çã¿ëÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.1¿¡¼­´Â »ç¿ëÀÚ ¾ÆÀ̵ð·Î "*"¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯¸é ¾î¶² »ç¿ëÀÚ ¾ÆÀ̵ð¶óµµ + ¹Þ¾ÆµéÀδÙ.

    +
    +
    + + +Anonymous_LogEmail +ÀÔ·ÂÇÑ ¾ÏÈ£¸¦ ¿À·ù·Î±×¿¡ ±â·ÏÇÒÁö ¿©ºÎ +Anonymous_LogEmail On|Off +Anonymous_LogEmail On +directory.htaccess + +AuthConfig + + +

    ±âº»°ªÀÎ OnÀ¸·Î ¼³Á¤Çϸé (¾Æ¸¶µµ ÀüÀÚ¿ìÆí + ÁÖ¼ÒÀÏ) ÀÔ·ÂÇÑ '¾ÏÈ£'¸¦ ¿À·ù·Î±×¿¡ ±â·ÏÇÑ´Ù.

    +
    +
    + + +Anonymous_MustGiveEmail +¾ÏÈ£°¡ ¾ø¾îµµ °¡´ÉÇÑÁö ¿©ºÎ +Anonymous_MustGiveEmail On|Off +Anonymous_MustGiveEmail On +directory.htaccess + +AuthConfig + + +

    »ç¿ëÀÚ°¡ ¾ÏÈ£·Î ÀüÀÚ¿ìÆí ÁÖ¼Ò¸¦ ÀÔ·ÂÇØ¾ß ÇÏ´ÂÁö ¿©ºÎ¸¦ + °áÁ¤ÇÑ´Ù. ¾ÏÈ£°¡ ¾øÀ¸¸é °ÅºÎÇÑ´Ù.

    +
    +
    + + +Anonymous_NoUserID +»ç¿ëÀÚ ¾ÆÀ̵𰡠¾ø¾îµµ °¡´ÉÇÏÁö ¿©ºÎ +Anonymous_NoUserID On|Off +Anonymous_NoUserID Off +directory.htaccess + +AuthConfig + + +

    OnÀ¸·Î ¼³Á¤ÇÏ¸é »ç¿ëÀÚ´Â »ç¿ëÀÚ ¾ÆÀ̵𸦠+ (¾Æ¸¶ ¾ÏÈ£µµ) ÀÔ·ÂÇÏÁö ¾Ê¾Æµµ µÈ´Ù. ÀÌ´Â ÀÚ¿¬½º·´°Ô ±×³É + returnÀ» Ä¡°Å³ª OK ¹öÆ°À» Ŭ¸¯ÇÏ´Â MS-Explorer »ç¿ëÀÚ¿¡°Ô + ¸Å¿ì Æí¸®ÇÏ´Ù.

    +
    +
    + + +Anonymous_VerifyEmail +¾ÏÈ£°¡ ¿Ã¹Ù¸¥ Çü½ÄÀÇ ÀüÀÚ¿ìÆí ÁÖ¼ÒÀÎÁö °Ë»ç +¿©ºÎ +Anonymous_VerifyEmail On|Off +Anonymous_VerifyEmail Off +directory.htaccess + +AuthConfig + + +

    OnÀ¸·Î ¼³Á¤ÇÏ¸é »ç¿ëÀÚ°¡ ¿Ã¹Ù¸¥ ÀüÀÚ¿ìÆí + ÁÖ¼Ò¸¦ ÀÔ·ÂÇϵµ·Ï ÀÔ·ÂÇÑ '¾ÏÈ£'°¡ ÃÖ¼ÒÇÑ '@'¿Í '.'¸¦ ÇÑ°³¾¿ + Æ÷ÇÔÇÏ´ÂÁö °Ë»çÇÑ´Ù (À§ÀÇ Anonymous_LogEmail Âü°í).

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_anon.xml.meta b/trunk/docs/manual/mod/mod_authn_anon.xml.meta new file mode 100644 index 0000000000..fe1306c9ba --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_anon.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authn_anon + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authn_dbm.html b/trunk/docs/manual/mod/mod_authn_dbm.html new file mode 100644 index 0000000000..a4472a2cfd --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.html @@ -0,0 +1,11 @@ +URI: mod_authn_dbm.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authn_dbm.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authn_dbm.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authn_dbm.html.en b/trunk/docs/manual/mod/mod_authn_dbm.html.en new file mode 100644 index 0000000000..ddf453fe21 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.html.en @@ -0,0 +1,136 @@ + + + +mod_authn_dbm - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authn_dbm

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:User authentication using DBM files
    Status:Extension
    Module Identifier:authn_dbm_module
    Source File:mod_authn_dbm.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authentication front-ends such as + mod_auth_digest and mod_auth_basic + to authenticate users by looking up users in dbm password + files. Similar functionality is provided by + mod_authn_file.

    + +

    When using mod_auth_basic or + mod_auth_digest, this module is invoked via the + AuthBasicProvider or + AuthDigestProvider + with the dbm value.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    AuthDBMType Directive

    + + + + + + + + +
    Description:Sets the type of database file that is used to +store passwords
    Syntax:AuthDBMType default|SDBM|GDBM|NDBM|DB
    Default:AuthDBMType default
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_dbm
    +

    Sets the type of database file that is used to store the passwords. + The default database type is determined at compile time. The + availability of other types of database files also depends on + compile-time settings.

    + +

    It is crucial that whatever program you use to create your password + files is configured to use the same type of database.

    + +
    +
    top
    +

    AuthDBMUserFile Directive

    + + + + + + + +
    Description:Sets the name of a database file containing the list of users and +passwords for authentication
    Syntax:AuthDBMUserFile file-path
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authn_dbm
    +

    The AuthDBMUserFile directive sets the + name of a DBM file containing the list of users and passwords for + user authentication. File-path is the absolute path to + the user file.

    + +

    The user file is keyed on the username. The value for a user is + the encrypted password, optionally followed by a colon and arbitrary + data. The colon and the data following it will be ignored by the + server.

    + +

    Security:

    +

    Make sure that the AuthDBMUserFile is stored + outside the document tree of the web-server; do not put it in + the directory that it protects. Otherwise, clients will be able to + download the AuthDBMUserFile.

    +
    + +

    Important compatibility note: The implementation of + dbmopen in the apache modules reads the string length of + the hashed values from the DBM data structures, rather than relying + upon the string being NULL-appended. Some applications, such as + the Netscape web server, rely upon the string being + NULL-appended, so if you are having trouble using DBM files + interchangeably between applications this may be a part of the + problem.

    + +

    A perl script called + dbmmanage is included with + Apache. This program can be used to create and update DBM + format password files for use with this module.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_dbm.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authn_dbm.html.ja.euc-jp new file mode 100644 index 0000000000..02ef9288f7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.html.ja.euc-jp @@ -0,0 +1,135 @@ + + + +mod_authn_dbm - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authn_dbm

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:DBM ¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥æ¡¼¥¶Ç§¾Ú
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authn_dbm_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authn_dbm.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    Ëܥ⥸¥å¡¼¥ë¤Ï mod_auth_digest ¤ä + mod_auth_basic ¤È¤¤¤Ã¤¿Ç§¾Ú¥Õ¥í¥ó¥È¥¨¥ó¥É¤ËÂФ·¤Æ¡¢ + dbm ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ëÆ⤫¤é¤Î¥æ¡¼¥¶¸¡º÷¤Ë¤è¤ë + ¥æ¡¼¥¶Ç§¾Úµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£»÷¤¿¤è¤¦¤Êµ¡Ç½¤Ï mod_authn_file + ¤Ç¤âÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    mod_auth_basic ¤ä mod_auth_digest + ¤ò»ÈÍѤ¹¤ëºÝ¤Ë¤Ï¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï + AuthBasicProvider ¤ä + AuthDigestPrivider + ¤Ç dbm ¤È»ØÄꤹ¤ë¤³¤È¤Çµ¯Æ°¤µ¤ì¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    AuthDBMType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Ñ¥¹¥ï¡¼¥É¤òÊݸ¤¹¤ë¤¿¤á¤ËɬÍפʥǡ¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Î¼ïÎà¤ò +ÀßÄꤹ¤ë
    ¹½Ê¸:AuthDBMType default|SDBM|GDBM|NDBM|DB
    ¥Ç¥Õ¥©¥ë¥È:AuthDBMType default
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_dbm
    +

    ¥Ñ¥¹¥ï¡¼¥É¤òÊݸ¤¹¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Î¼ïÎà¤ò + ÀßÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¼ïÎà¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë·è¤Þ¤ê¤Þ¤¹¡£ + ¾¤Î¼ïÎà¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬»ÈÍѲÄǽ¤«¤É¤¦¤«¤â ¥³¥ó¥Ñ¥¤¥ë»þ¤ÎÀßÄê¤Ë°Í¸¤·¤Þ¤¹¡£

    + +

    ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¤Î¤Ë»ÈÍѤ¹¤ë¥×¥í¥°¥é¥à¤¬Æ±¤¸¼ïÎà¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò + »ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤹ¤ë¤³¤È¤ÏÈó¾ï¤Ë½ÅÍפǤ¹¡£

    + +
    +
    top
    +

    AuthDBMUserFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ǧ¾ÚÍѤΥ桼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î¥ê¥¹¥È¤òÊÝ»ý¤·¤Æ¤¤¤ë +¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthDBMUserFile file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authn_dbm
    +

    AuthDBMUserFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ǧ¾ÚÍѤΥ桼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î¥ê¥¹¥È¤òÊÝ»ý¤·¤Æ¤¤¤ë DBM ¥Õ¥¡¥¤¥ë¤Î + ̾Á°¤òÀßÄꤷ¤Þ¤¹¡£File-path ¤Ï¥æ¡¼¥¶¥Õ¥¡¥¤¥ë¤Ø¤Î + ÀäÂХѥ¹¤Ç¤¹¡£

    + +

    ¥æ¡¼¥¶¥Õ¥¡¥¤¥ë¤Î¥­¡¼¤Ï¥æ¡¼¥¶Ì¾¤Ç¤¹¡£¥æ¡¼¥¶¤ËÂФ·¤ÆÊÖ¤µ¤ì¤ëÃÍ¤Ï + °Å¹æ²½¤µ¤ì¤¿¥Ñ¥¹¥ï¡¼¥É¤Ç¡¢¤½¤Î¸å¤Ë¡¢¥³¥í¥ó¤Ë³¤¤¤ÆǤ°Õ¤Î¥Ç¡¼¥¿¤¬ + ³¤¤¤Æ¤¤¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£¥³¥í¥ó¤È¤½¤Î¸å¤Î¥Ç¡¼¥¿¤Ï¥µ¡¼¥Ð¤Ï + ̵»ë¤·¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    AuthDBMUserFile ¤Ï¡¢ + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Î³°Â¦¤ËÊݴɤ¹¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + Êݸ¤è¤¦¤È¤·¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Ë¤Ï + ÃÖ¤«¤Ê¤¤¤Ç²¼¤µ¤¤¡£ + ¤½¤¦¤·¤Ê¤¤¤È¥¯¥é¥¤¥¢¥ó¥È¤¬ AuthUserFile ¤ò + ¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Æ¤·¤Þ¤¤¤Þ¤¹¡£

    +
    + +

    ½ÅÍפʸߴ¹À­¤Ë´Ø¤¹¤ëÃí°Õ: apache module ¤Î dbmopen ¤Î¼ÂÁõ¤Ï + ʸ»úÎó¤¬ NULL ¤Ç½ª¤ï¤Ã¤Æ¤¤¤ë¤³¤È¤Ë°Í¸¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢DBM ¥Ç¡¼¥¿¥¹¥È¥é¥¯¥Á¥ã + ¤Î¥Ï¥Ã¥·¥åÃͤÎʸ»úÎó¤ÎŤµ¤òÆɤ߼è¤ê¤Þ¤¹¡£Netscape ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ê¤É¡¢ + ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÃæ¤Ë¤Ïʸ»úÎó¤¬ NULL ¤Ç½ª¤ï¤Ã¤Æ¤¤¤ë¤³¤È¤Ë°Í¸¤·¤Æ¤¤¤ë + ¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢°Û¤Ê¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó´Ö¤Ç¤Î DBM ¥Õ¥¡¥¤¥ë¤Î + »ÈÍѤËÌäÂ꤬¤¢¤ë¾ì¹ç¤Ï¡¢¤³¤ì¤¬¸¶°ø¤Ë¤Ê¤Ã¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    Apache ¤Ë¤Ï dbmmanage ¤È¤¤¤¦ + perl ¥¹¥¯¥ê¥×¥È¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥×¥í¥°¥é¥à¤ò»È¤Ã¤Æ¤³¤Î + ¥â¥¸¥å¡¼¥ë¤¬»ÈÍѤ¹¤ë DBM ¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤¿¤ê + ¹¹¿·¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_dbm.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authn_dbm.html.ko.euc-kr new file mode 100644 index 0000000000..ae6ca77e4b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.html.ko.euc-kr @@ -0,0 +1,131 @@ + + + +mod_authn_dbm - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authn_dbm

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:DBM ÆÄÀÏÀ» »ç¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ
    »óÅÂ:Extension
    ¸ðµâ¸í:authn_dbm_module
    ¼Ò½ºÆÄÀÏ:mod_authn_dbm.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_auth_digest³ª + mod_auth_basic ÀÎÁõ¾Õ´Ü¸ðµâÀ» À§ÇØ + dbm ¾ÏÈ£ÆÄÀÏ¿¡¼­ »ç¿ëÀÚ¸¦ ã¾Æ¼­ ÀÎÁõÇÑ´Ù. + mod_authn_file°ú ±â´ÉÀÌ ºñ½ÁÇÑ´Ù.

    + +

    mod_auth_basicÀ̳ª + mod_auth_digest¸¦ »ç¿ëÇÒ¶§ AuthBasicProvider³ª + AuthDigestProviderÀÇ + °ªÀ¸·Î dbmÀ» ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthDBMType Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ +ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthDBMType default|SDBM|GDBM|NDBM|DB
    ±âº»°ª:AuthDBMType default
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_dbm
    +

    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. ±âº» + µ¥ÀÌÅͺ£À̽º Á¾·ù´Â ÄÄÆÄÀ϶§ ÆÇ´ÜÇÑ´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ´Ù¸¥ + µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ùµµ ÄÄÆÄÀÏ + ¼³Á¤¿¡ ´Þ·È´Ù.

    + +

    ¾ÏÈ£ÆÄÀÏÀ» ¸¸µå´Â ÇÁ·Î±×·¥ÀÌ °°Àº Á¾·ùÀÇ µ¥ÀÌÅͺ£À̽º¸¦ + »ç¿ëÇϵµ·Ï ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +
    +
    top
    +

    AuthDBMUserFile Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÎÁõÇÒ »ç¿ëÀÚ¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthDBMUserFile file-path
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authn_dbm
    +

    AuthDBMUserFile Áö½Ã¾î´Â »ç¿ëÀÚ + ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â DBM ÆÄÀϸíÀ» + ÁöÁ¤ÇÑ´Ù. File-path´Â ÆÄÀÏÀÇ Àý´ë°æ·ÎÀÌ´Ù.

    + +

    ÆÄÀÏÀº »ç¿ëÀÚ¸íÀ» Å°·Î »ç¿ëÇÑ´Ù. »ç¿ëÀÚ¿¡ ´ëÇÑ °ªÀº + ÀÎÄÚµùµÈ ¾ÏÈ£ÀÌ´Ù. ¾ÏÈ£ µÚ¿¡ Äݷаú ÀÓÀÇÀÇ Á¤º¸°¡ ³ª¿Ã ¼ö + ÀÖ´Ù. ¼­¹ö´Â Äݷаú µÚ¿¡ ³ª¿À´Â Á¤º¸¸¦ ¹«½ÃÇÑ´Ù.

    + +

    º¸¾È:

    +

    AuthDBMUserFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ ÀÖÀ½À» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ °°ÀÌ + µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthDBMUserFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö + ÀÖ´Ù.

    +
    + +

    Áß¿äÇÑ È£È¯¼º ÁÖÀÇ: ¾ÆÆÄÄ¡ ¸ðµâÀÇ dbmopen + ±¸ÇöÀº ¹®ÀÚ¿­ ³¡ÀÇ NULL¿¡ ÀÇÁ¸ÇÏÁö¾Ê°í DBM ÀڷᱸÁ¶¿¡¼­ + Çؽ̰ªÀÇ ¹®ÀÚ¿­ ±æÀ̸¦ Àд´Ù. Netscape À¥¼­¹ö µî ¾î¶² + ÇÁ·Î±×·¥Àº ¹®ÀÚ¿­ÀÌ NULL·Î ³¡³­´Ù°í °¡Á¤Çϱ⶧¹®¿¡ ¿©·¯ + ÇÁ·Î±×·¥ÀÌ DBM ÆÄÀÏÀ» »ç¿ëÇÏ¸é ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â dbmmanage¶ó´Â + Perl ½ºÅ©¸³Æ®¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ÀÌ ¸ðµâÀÌ »ç¿ëÇÒ + DBMÇü½Ä ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé°í ¼öÁ¤ÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_dbm.xml b/trunk/docs/manual/mod/mod_authn_dbm.xml new file mode 100644 index 0000000000..ae9a2f1550 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.xml @@ -0,0 +1,119 @@ + + + + + + + + + +mod_authn_dbm +User authentication using DBM files +Extension +mod_authn_dbm.c +authn_dbm_module +Available in Apache 2.1 and later + + +

    This module provides authentication front-ends such as + mod_auth_digest and mod_auth_basic + to authenticate users by looking up users in dbm password + files. Similar functionality is provided by + mod_authn_file.

    + +

    When using mod_auth_basic or + mod_auth_digest, this module is invoked via the + AuthBasicProvider or + AuthDigestProvider + with the dbm value.

    +
    + +AuthName +AuthType + + AuthBasicProvider + + + AuthDigestProvider + + + +AuthDBMUserFile +Sets the name of a database file containing the list of users and +passwords for authentication +AuthDBMUserFile file-path +directory.htaccess + +AuthConfig + + +

    The AuthDBMUserFile directive sets the + name of a DBM file containing the list of users and passwords for + user authentication. File-path is the absolute path to + the user file.

    + +

    The user file is keyed on the username. The value for a user is + the encrypted password, optionally followed by a colon and arbitrary + data. The colon and the data following it will be ignored by the + server.

    + + Security: +

    Make sure that the AuthDBMUserFile is stored + outside the document tree of the web-server; do not put it in + the directory that it protects. Otherwise, clients will be able to + download the AuthDBMUserFile.

    +
    + +

    Important compatibility note: The implementation of + dbmopen in the apache modules reads the string length of + the hashed values from the DBM data structures, rather than relying + upon the string being NULL-appended. Some applications, such as + the Netscape web server, rely upon the string being + NULL-appended, so if you are having trouble using DBM files + interchangeably between applications this may be a part of the + problem.

    + +

    A perl script called + dbmmanage is included with + Apache. This program can be used to create and update DBM + format password files for use with this module.

    +
    +
    + + +AuthDBMType +Sets the type of database file that is used to +store passwords +AuthDBMType default|SDBM|GDBM|NDBM|DB +AuthDBMType default +directory.htaccess + +AuthConfig + + +

    Sets the type of database file that is used to store the passwords. + The default database type is determined at compile time. The + availability of other types of database files also depends on + compile-time settings.

    + +

    It is crucial that whatever program you use to create your password + files is configured to use the same type of database.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_dbm.xml.ja b/trunk/docs/manual/mod/mod_authn_dbm.xml.ja new file mode 100644 index 0000000000..eba531e72b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.xml.ja @@ -0,0 +1,119 @@ + + + + + + + + + +mod_authn_dbm +DBM $B%U%!%$%k$rMQ$$$?%f!<%6G'>Z(B +Extension +mod_authn_dbm.c +authn_dbm_module +Apache 2.1 $B0J9_(B + + +

    $BK\%b%8%e!<%k$O(B mod_auth_digest $B$d(B + mod_auth_basic $B$H$$$C$?G'>Z%U%m%s%H%(%s%I$KBP$7$F!"(B + dbm $B%Q%9%o!<%I%U%!%$%kFb$+$i$N%f!<%68!:w$K$h$k(B + $B%f!<%6G'>Z5!G=$rDs6!$7$^$9!#;w$?$h$&$J5!G=$O(B mod_authn_file + $B$G$bDs6!$5$l$F$$$^$9!#(B

    + +

    mod_auth_basic $B$d(B mod_auth_digest + $B$r;HMQ$9$k:]$K$O!"$3$N%b%8%e!<%k$O(B + AuthBasicProvider $B$d(B + AuthDigestPrivider + $B$G(B dbm $B$H;XDj$9$k$3$H$G5/F0$5$l$^$9!#(B

    +
    + +AuthName +AuthType + + AuthBasicProvider + + + AuthDigestProvider + + + +AuthDBMUserFile +$BG'>ZMQ$N%f!<%6$H%Q%9%o!<%I$N%j%9%H$rJ];}$7$F$$$k(B +$B%G!<%?%Y!<%9%U%!%$%kL>$r@_Dj$9$k(B +AuthDBMUserFile file-path +directory.htaccess + +AuthConfig + + +

    AuthDBMUserFile $B%G%#%l%/%F%#%V$O(B + $BG'>ZMQ$N%f!<%6$H%Q%9%o!<%I$N%j%9%H$rJ];}$7$F$$$k(B DBM $B%U%!%$%k$N(B + $BL>A0$r@_Dj$7$^$9!#(BFile-path $B$O%f!<%6%U%!%$%k$X$N(B + $B@dBP%Q%9$G$9!#(B

    + +

    $B%f!<%6%U%!%$%k$N%-!<$O%f!<%6L>$G$9!#%f!<%6$KBP$7$FJV$5$l$kCM$O(B + $B0E9f2=$5$l$?%Q%9%o!<%I$G!"$=$N8e$K!"%3%m%s$KB3$$$FG$0U$N%G!<%?$,(B + $BB3$$$F$$$k$3$H$b$"$j$^$9!#%3%m%s$H$=$N8e$N%G!<%?$O%5!<%P$O(B + $BL5;k$7$^$9!#(B

    + + $B%;%-%e%j%F%#(B +

    AuthDBMUserFile $B$O!"(B + $B%&%'%V%5!<%P$N%I%-%e%a%s%H%D%j!<$N30B&$KJ]4I$9$k$h$&$K$7$F$/$@$5$$!#(B + $BJ]8n$7$h$&$H$7$F$$$k%G%#%l%/%H%j0J2<$K$O(B + $BCV$+$J$$$G2<$5$$(B$B!#(B + $B$=$&$7$J$$$H%/%i%$%"%s%H$,(B AuthUserFile $B$r(B + $B%@%&%s%m!<%I$G$-$F$7$^$$$^$9!#(B

    +
    + +

    $B=EMW$J8_49@-$K4X$9$kCm0U(B: apache module $B$N(B dbmopen $B$Nl9g$O!"$3$l$,860x$K$J$C$F$$$k2DG=@-$,$"$j$^$9!#(B

    + +

    Apache $B$K$O(B dbmmanage $B$H$$$&(B + perl $B%9%/%j%W%H$,4^$^$l$F$$$^$9!#$3$N%W%m%0%i%`$r;H$C$F$3$N(B + $B%b%8%e!<%k$,;HMQ$9$k(B DBM $B%U%)!<%^%C%H$N%Q%9%o!<%I%U%!%$%k$r:n@.$7$?$j(B + $B99?7$7$?$j$9$k$3$H$,$G$-$^$9!#(B

    +
    +
    + + +AuthDBMType +$B%Q%9%o!<%I$rJ]B8$9$k$?$a$KI,MW$J%G!<%?%Y!<%9%U%!%$%k$N +AuthDBMType default|SDBM|GDBM|NDBM|DB +AuthDBMType default +directory.htaccess + +AuthConfig + + +

    $B%Q%9%o!<%I$rJ]B8$9$k$?$a$K;HMQ$9$k%G!<%?%Y!<%9%U%!%$%k$N$N$B%3%s%Q%$%k;~$N@_Dj(B$B$K0MB8$7$^$9!#(B

    + +

    $B%Q%9%o!<%I%U%!%$%k$r:n@.$9$k$N$K;HMQ$9$k%W%m%0%i%`$,F1$8o$K=EMW$G$9!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_dbm.xml.ko b/trunk/docs/manual/mod/mod_authn_dbm.xml.ko new file mode 100644 index 0000000000..ae51595b5a --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.xml.ko @@ -0,0 +1,113 @@ + + + + + + + + + +mod_authn_dbm +DBM ÆÄÀÏÀ» »ç¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ +Extension +mod_authn_dbm.c +authn_dbm_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº mod_auth_digest³ª + mod_auth_basic ÀÎÁõ¾Õ´Ü¸ðµâÀ» À§ÇØ + dbm ¾ÏÈ£ÆÄÀÏ¿¡¼­ »ç¿ëÀÚ¸¦ ã¾Æ¼­ ÀÎÁõÇÑ´Ù. + mod_authn_file°ú ±â´ÉÀÌ ºñ½ÁÇÑ´Ù.

    + +

    mod_auth_basicÀ̳ª + mod_auth_digest¸¦ »ç¿ëÇÒ¶§ AuthBasicProvider³ª + AuthDigestProviderÀÇ + °ªÀ¸·Î dbmÀ» ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    + +AuthName +AuthType + + AuthBasicProvider + + + AuthDigestProvider + + + +AuthDBMUserFile +ÀÎÁõÇÒ »ç¿ëÀÚ¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù +AuthDBMUserFile file-path +directory.htaccess + +AuthConfig + + +

    AuthDBMUserFile Áö½Ã¾î´Â »ç¿ëÀÚ + ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â DBM ÆÄÀϸíÀ» + ÁöÁ¤ÇÑ´Ù. File-path´Â ÆÄÀÏÀÇ Àý´ë°æ·ÎÀÌ´Ù.

    + +

    ÆÄÀÏÀº »ç¿ëÀÚ¸íÀ» Å°·Î »ç¿ëÇÑ´Ù. »ç¿ëÀÚ¿¡ ´ëÇÑ °ªÀº + ÀÎÄÚµùµÈ ¾ÏÈ£ÀÌ´Ù. ¾ÏÈ£ µÚ¿¡ Äݷаú ÀÓÀÇÀÇ Á¤º¸°¡ ³ª¿Ã ¼ö + ÀÖ´Ù. ¼­¹ö´Â Äݷаú µÚ¿¡ ³ª¿À´Â Á¤º¸¸¦ ¹«½ÃÇÑ´Ù.

    + + º¸¾È: +

    AuthDBMUserFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ ÀÖÀ½À» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ °°ÀÌ + µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthDBMUserFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö + ÀÖ´Ù.

    +
    + +

    Áß¿äÇÑ È£È¯¼º ÁÖÀÇ: ¾ÆÆÄÄ¡ ¸ðµâÀÇ dbmopen + ±¸ÇöÀº ¹®ÀÚ¿­ ³¡ÀÇ NULL¿¡ ÀÇÁ¸ÇÏÁö¾Ê°í DBM ÀڷᱸÁ¶¿¡¼­ + Çؽ̰ªÀÇ ¹®ÀÚ¿­ ±æÀ̸¦ Àд´Ù. Netscape À¥¼­¹ö µî ¾î¶² + ÇÁ·Î±×·¥Àº ¹®ÀÚ¿­ÀÌ NULL·Î ³¡³­´Ù°í °¡Á¤Çϱ⶧¹®¿¡ ¿©·¯ + ÇÁ·Î±×·¥ÀÌ DBM ÆÄÀÏÀ» »ç¿ëÇÏ¸é ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â dbmmanage¶ó´Â + Perl ½ºÅ©¸³Æ®¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ÀÌ ¸ðµâÀÌ »ç¿ëÇÒ + DBMÇü½Ä ¾ÏÈ£ÆÄÀÏÀ» ¸¸µé°í ¼öÁ¤ÇÑ´Ù.

    +
    +
    + + +AuthDBMType +¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ +ÁöÁ¤ÇÑ´Ù +AuthDBMType default|SDBM|GDBM|NDBM|DB +AuthDBMType default +directory.htaccess + +AuthConfig + + +

    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. ±âº» + µ¥ÀÌÅͺ£À̽º Á¾·ù´Â ÄÄÆÄÀ϶§ ÆÇ´ÜÇÑ´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ´Ù¸¥ + µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ùµµ ÄÄÆÄÀÏ + ¼³Á¤¿¡ ´Þ·È´Ù.

    + +

    ¾ÏÈ£ÆÄÀÏÀ» ¸¸µå´Â ÇÁ·Î±×·¥ÀÌ °°Àº Á¾·ùÀÇ µ¥ÀÌÅͺ£À̽º¸¦ + »ç¿ëÇϵµ·Ï ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_dbm.xml.meta b/trunk/docs/manual/mod/mod_authn_dbm.xml.meta new file mode 100644 index 0000000000..ac0ad44727 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_dbm.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authn_dbm + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authn_default.html b/trunk/docs/manual/mod/mod_authn_default.html new file mode 100644 index 0000000000..9a1beb27aa --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.html @@ -0,0 +1,11 @@ +URI: mod_authn_default.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authn_default.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authn_default.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authn_default.html.en b/trunk/docs/manual/mod/mod_authn_default.html.en new file mode 100644 index 0000000000..2ec16976e0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.html.en @@ -0,0 +1,80 @@ + + + +mod_authn_default - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authn_default

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Authentication fallback module
    Status:Base
    Module Identifier:authn_default_module
    Source File:mod_authn_default.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module is designed to be the fallback module, if you don't + have configured an authentication module like + mod_auth_basic. It simply rejects any + credentials supplied by the user.

    +
    +

    Directives

    + +
    + +
    top
    +

    AuthDefaultAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authentication is passed to lower level +modules
    Syntax:AuthDefaultAuthoritative On|Off
    Default:AuthDefaultAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authn_default
    +

    Setting the AuthDefaultAuthoritative directive + explicitly to Off allows for authentication to be passed on + to lower level modules (as defined in the modules.c + files).

    + +

    Note

    +

    Normally there are no lower level modules, since + mod_authn_default is defined to be already on + a very low level. Therefore you should leave the value of + AuthDefaultAuthoritative as default + (On).

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_default.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authn_default.html.ja.euc-jp new file mode 100644 index 0000000000..5b1d02d8ac --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.html.ja.euc-jp @@ -0,0 +1,80 @@ + + + +mod_authn_default - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authn_default

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:ǧ¾Ú¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authn_default_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authn_default.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    mod_auth_basic ¤Î¤è¤¦¤Êǧ¾Ú¥â¥¸¥å¡¼¥ë¤ò + ÀßÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢Ëܥ⥸¥å¡¼¥ë¤¬¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤È¤Ê¤ê¤Þ¤¹¡£ + ¥æ¡¼¥¶¤«¤éÄ󼨤µ¤ì¤¿¤É¤ó¤Ê¾Ú½ñ¤âñ¤ËµñÈݤ·¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    AuthDefaultAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¼¡¤ÎÄ㼡¥ì¥Ù¥ë¤Îǧ¾Ú¥â¥¸¥å¡¼¥ë¤ËÀ©¸æ¤òÅϤ¹¤«¤É¤¦¤«¤ò +ÀßÄꤷ¤Þ¤¹
    ¹½Ê¸:AuthDefaultAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthDefaultAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authn_default
    +

    AuthDefaultAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÌÀ¼¨Åª¤Ë Off ¤ËÀßÄꤹ¤ë¤È¡¢ + ǧ¾Ú¤ò¼¡¤Î (modules.c ¥Õ¥¡¥¤¥ë¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë) + Ä㼡¥ì¥Ù¥ë¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤ·¤Þ¤¹¡£ +

    + +

    Ãí°Õ

    +

    mod_authn_default ¼«ÂΤ¬¤È¤Æ¤âÄ㤤 + ¥ì¥Ù¥ë¤È¤·¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢Ä̾ï¤Ï¤³¤ì¤è¤ê¤âÄ㼡¤Î + ¥â¥¸¥å¡¼¥ë¤Ï¸ºß¤·¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é + AuthDefaultAuthoritative ¤Ï¥Ç¥Õ¥©¥ë¥È + (On) ¤Î¤Þ¤Þ¤Ë¤·¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_default.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authn_default.html.ko.euc-kr new file mode 100644 index 0000000000..10dfa99058 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.html.ko.euc-kr @@ -0,0 +1,76 @@ + + + +mod_authn_default - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authn_default

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÃÖÈÄ ÀÎÁõ¸ðµâ
    »óÅÂ:Base
    ¸ðµâ¸í:authn_default_module
    ¼Ò½ºÆÄÀÏ:mod_authn_default.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_auth_basic°ú °°Àº ÀÎÁõ¸ðµâÀ» + ¼³Á¤ÇÏÁö¾ÊÀº ÃÖÈÄÀÇ °æ¿ì ´ë½Å »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº »ç¿ëÀÚ°¡ + Á¦°øÇÑ ¾î¶°ÇÑ Á¤º¸µµ °ÅºÎÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    AuthDefaultAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ÀÎÁõÀ» Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthDefaultAuthoritative On|Off
    ±âº»°ª:AuthDefaultAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authn_default
    +

    AuthDefaultAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ÀÎÁõÀ» ³Ñ°ÜÁØ´Ù.

    + +

    ÁÖÀÇ

    +

    mod_authn_default°¡ ÀÌ¹Ì ¸Å¿ì + Àú¼öÁØÀ¸·Î Á¤ÀǵÇÀֱ⠶§¹®¿¡ º¸Åë ´õ ³·Àº ¸ðµâÀÌ ¾ø´Ù. + ±×·¯¹Ç·Î AuthDefaultAuthoritative¸¦ + ±âº»°ª(On)À¸·Î ³²°ÜµÖ¾ß ÇÑ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_default.xml b/trunk/docs/manual/mod/mod_authn_default.xml new file mode 100644 index 0000000000..67d26388ea --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.xml @@ -0,0 +1,65 @@ + + + + + + + + + +mod_authn_default +Authentication fallback module +Base +mod_authn_default.c +authn_default_module +Available in Apache 2.1 and later + + +

    This module is designed to be the fallback module, if you don't + have configured an authentication module like + mod_auth_basic. It simply rejects any + credentials supplied by the user.

    +
    + + +AuthDefaultAuthoritative +Sets whether authentication is passed to lower level +modules +AuthDefaultAuthoritative On|Off +AuthDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthDefaultAuthoritative directive + explicitly to Off allows for authentication to be passed on + to lower level modules (as defined in the modules.c + files).

    + + Note +

    Normally there are no lower level modules, since + mod_authn_default is defined to be already on + a very low level. Therefore you should leave the value of + AuthDefaultAuthoritative as default + (On).

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_default.xml.ja b/trunk/docs/manual/mod/mod_authn_default.xml.ja new file mode 100644 index 0000000000..0ae9df5d90 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.xml.ja @@ -0,0 +1,65 @@ + + + + + + + + + +mod_authn_default +$BG'>Z%U%)!<%k%P%C%/%b%8%e!<%k(B +Base +mod_authn_default.c +authn_default_module +Apache 2.1 $B0J9_(B + + +

    mod_auth_basic $B$N$h$&$JG'>Z%b%8%e!<%k$r(B + $B@_Dj$7$J$+$C$?>l9g$O!"K\%b%8%e!<%k$,%U%)!<%k%P%C%/$H$J$j$^$9!#(B + $B%f!<%6$+$iDs<($5$l$?$I$s$J>Z=q$bC1$K5qH]$7$^$9!#(B

    +
    + + +AuthDefaultAuthoritative +$BZ%b%8%e!<%k$K@)8f$rEO$9$+$I$&$+$r(B +$B@_Dj$7$^$9(B +AuthDefaultAuthoritative On|Off +AuthDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthDefaultAuthoritative $B%G%#%l%/%F%#%V$r(B + $BL@<(E*$K(B Off $B$K@_Dj$9$k$H!"(B + $BG'>Z$rmodules.c $B%U%!%$%k$GDj5A$5$l$F$$$k(B) + $BDc + + $BCm0U(B +

    mod_authn_default $B<+BN$,(B$B$H$F$bDc$$(B + $B%l%Y%k$H$7$FDj5A$5$l$F$$$^$9$N$G!"DL>o$O$3$l$h$j$bDcAuthDefaultAuthoritative $B$O%G%U%)%k%H(B + (On) $B$N$^$^$K$7$?$[$&$,NI$$$G$7$g$&!#(B

    + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_default.xml.ko b/trunk/docs/manual/mod/mod_authn_default.xml.ko new file mode 100644 index 0000000000..4ad596583e --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.xml.ko @@ -0,0 +1,61 @@ + + + + + + + + + +mod_authn_default +ÃÖÈÄ ÀÎÁõ¸ðµâ +Base +mod_authn_default.c +authn_default_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº mod_auth_basic°ú °°Àº ÀÎÁõ¸ðµâÀ» + ¼³Á¤ÇÏÁö¾ÊÀº ÃÖÈÄÀÇ °æ¿ì ´ë½Å »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº »ç¿ëÀÚ°¡ + Á¦°øÇÑ ¾î¶°ÇÑ Á¤º¸µµ °ÅºÎÇÑ´Ù.

    +
    + + +AuthDefaultAuthoritative +ÀÎÁõÀ» Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthDefaultAuthoritative On|Off +AuthDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthDefaultAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ÀÎÁõÀ» ³Ñ°ÜÁØ´Ù.

    + + ÁÖÀÇ +

    mod_authn_default°¡ ÀÌ¹Ì ¸Å¿ì + Àú¼öÁØÀ¸·Î Á¤ÀǵÇÀֱ⠶§¹®¿¡ º¸Åë ´õ ³·Àº ¸ðµâÀÌ ¾ø´Ù. + ±×·¯¹Ç·Î AuthDefaultAuthoritative¸¦ + ±âº»°ª(On)À¸·Î ³²°ÜµÖ¾ß ÇÑ´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_default.xml.meta b/trunk/docs/manual/mod/mod_authn_default.xml.meta new file mode 100644 index 0000000000..ec19eb6a6c --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_default.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authn_default + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authn_file.html b/trunk/docs/manual/mod/mod_authn_file.html new file mode 100644 index 0000000000..d3f6ce2a68 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.html @@ -0,0 +1,11 @@ +URI: mod_authn_file.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authn_file.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authn_file.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authn_file.html.en b/trunk/docs/manual/mod/mod_authn_file.html.en new file mode 100644 index 0000000000..464599ace0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.html.en @@ -0,0 +1,132 @@ + + + +mod_authn_file - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authn_file

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:User authentication using text files
    Status:Base
    Module Identifier:authn_file_module
    Source File:mod_authn_file.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authentication front-ends such as + mod_auth_digest and mod_auth_basic + to authenticate users by looking up users in plain text password files. + Similar functionality is provided by mod_authn_dbm.

    + +

    When using mod_auth_basic or + mod_auth_digest, this module is invoked via the + AuthBasicProvider or + AuthDigestProvider + with the file value.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    AuthUserFile Directive

    + + + + + + + +
    Description:Sets the name of a text file containing the list of users and +passwords for authentication
    Syntax:AuthUserFile file-path
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authn_file
    +

    The AuthUserFile directive sets the name + of a textual file containing the list of users and passwords for + user authentication. File-path is the path to the user + file. If it is not absolute, it is treated as relative to the + ServerRoot.

    + +

    Each line of the user file contains a username followed by + a colon, followed by the encrypted password. If the same user + ID is defined multiple times, mod_authn_file will + use the first occurrence to verify the password.

    + +

    The utility htpasswd + which is installed as part of the binary distribution, or which + can be found in src/support, is used to maintain + the password file for HTTP Basic Authentication. See the + man page for more details. + In short:

    + +

    Create a password file Filename with + username as the initial ID. It will prompt for + the password:

    + +

    + htpasswd -c Filename username +

    + +

    Add or modify username2 in the password file + Filename:

    + +

    + htpasswd Filename username2 +

    + +

    Note that searching large text files is very + inefficient; AuthDBMUserFile should be used + instead.

    + +

    If you are using HTTP Digest Authentication, the htpasswd tool is not sufficient. + You have to use htdigest + instead. Note that you cannot mix user data for Digest Authentication + and Basic Authentication within the same file.

    + +

    Security

    +

    Make sure that the AuthUserFile is + stored outside the document tree of the web-server. Do + not put it in the directory that it protects. + Otherwise, clients may be able to download the + AuthUserFile.

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_file.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authn_file.html.ja.euc-jp new file mode 100644 index 0000000000..7e479c2494 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.html.ja.euc-jp @@ -0,0 +1,142 @@ + + + +mod_authn_file - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authn_file

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥æ¡¼¥¶Ç§¾Ú
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authn_file_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authn_file.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    Ëܥ⥸¥å¡¼¥ë¤Ï mod_auth_digest ¤ä + mod_auth_basic ¤È¤¤¤Ã¤¿Ç§¾Ú¥Õ¥í¥ó¥È¥¨¥ó¥É¤ËÂФ·¤Æ¡¢ + ¥×¥ì¥¤¥ó¥Æ¥­¥¹¥È¤Î¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ëÆ⤫¤é¥æ¡¼¥¶¤ò¸¡º÷¤¹¤ë¤³¤È¤Ç¡¢ + ¥æ¡¼¥¶Ç§¾Úµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£»÷¤¿¤è¤¦¤Êµ¡Ç½¤Ï mod_authn_dbm + ¤Ç¤âÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    mod_auth_basic ¤ä mod_auth_digest + ¤ò»ÈÍѤ¹¤ëºÝ¤Ë¤Ï¡¢ + AuthBasicProvider ¤ä + AuthDigestPrivider + ¤Ç file ¤È»ØÄꤹ¤ë¤³¤È¤Ç¤³¤Î¥â¥¸¥å¡¼¥ë¤Ïµ¯Æ°¤µ¤ì¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    AuthUserFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ǧ¾Ú¤Ë»ÈÍѤ¹¤ë¥æ¡¼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î°ìÍ÷¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ë¡¢ +¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthUserFile file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authn_file
    +

    AuthUserFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥æ¡¼¥¶Ç§¾Ú¤Î¤¿¤á¤Î¥æ¡¼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î°ìÍ÷¤ò³ÊǼ¤·¤¿ + ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤷ¤Þ¤¹¡£file-path + ¤Ï¥æ¡¼¥¶¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤Ç¤¹¡£ + ¤â¤·ÀäÂХѥ¹¤Ç¤Ê¤±¤ì¤Ð¡¢ + ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    ¥æ¡¼¥¶¥Õ¥¡¥¤¥ë¤Î³Æ¹Ô¤Ë¤Ï¡¢¥æ¡¼¥¶Ì¾¡¢¥³¥í¥ó¡¢ + °Å¹æ²½¤·¤¿¥Ñ¥¹¥ï¡¼¥É¤òµ­½Ò¤·¤Þ¤¹¡£ + Ʊ°ì¥æ¡¼¥¶ ID ¤¬Ê£¿ô²óÅÐÏ¿¤µ¤ì¤¿»þ¤Ï¡¢ + mod_authn_file + ¤ÏºÇ½é¤Ë¸«¤Ä¤«¤Ã¤¿¥Ñ¥¹¥ï¡¼¥É¤ò»ÈÍѤ·¤Æǧ¾Ú¤·¤Þ¤¹¡£

    + +

    ¥Ð¥¤¥Ê¥êÇÛÉۤΰìÉô¤È¤·¤Æ¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤ë¤«¡¢ + ¤¢¤ë¤¤¤Ï src/support ¤Ë¤¢¤ë + htpasswd + ¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ç¡¢¤³¤Î HTTP ´ðËÜǧ¾Ú + Íѥѥ¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤ò¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¤·¤Þ¤¹¡£ + ¾ÜºÙ¤Ï man + ¥Ú¡¼¥¸¤ò¤´Í÷ĺ¤¯¤È¤·¤Æ¡¢´Êñ¤Ë¤Ï:

    + +

    ½é´ü ID username ¤Ç¡¢Filename + ¤È¤¤¤¦¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë¤òÀ¸À®¤·¤Þ¤¹¡£ + ¼¡¤Î¥³¥Þ¥ó¥É¤òȯ¹Ô¤¹¤ë¤È¥Ñ¥¹¥ï¡¼¥É¤¬Í׵ᤵ¤ì¤Þ¤¹:

    + +

    + htpasswd -c Filename username +

    + +

    ¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ë Filename ¤Ë¡¢username2 + ¤òÄɲä·¤¿¤ê½¤Àµ¤·¤¿¤ê¤·¤Þ¤¹:

    + +

    + htpasswd Filename username2 +

    + +

    (ÌõÃí: Èó¾ï¤Ë¿¤¯¤Î¥æ¡¼¥¶¤òÅÐÏ¿¤¹¤ë¤ÈÂ礭¤Ê¥Õ¥¡¥¤¥ë¤Ë¤Ê¤ê¤Þ¤¹¤¬) + Â礭¤Ê¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤ò¸¡º÷¤¹¤ë¤Î¤ÏÈó¾ï¤Ë¸úΨ¤¬°­¤¤ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¤è¤¦¤ÊɬÍפΤ¢¤ë»þ¤Ï¡¢ + AuthDBMUserFile + ¤òÂå¤ï¤ê¤Ë»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    + +

    HTTP ¥À¥¤¥¸¥§¥¹¥Èǧ¾Ú¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï¡¢ + htpasswd + ¥×¥í¥°¥é¥à¤Ç¤ÏÉÔ½½Ê¬¤Ç¤¹¡£¤½¤ÎÂå¤ï¤ê¤Ë + htdigest + ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£¥À¥¤¥¸¥§¥¹¥Èǧ¾ÚÍѤΥǡ¼¥¿¤È + ´ðËÜǧ¾ÚÍѤΥǡ¼¥¿¤òƱ°ì¥Õ¥¡¥¤¥ë¤Ëº®¤¼¤ÆÊݸ¤Ç¤­¤Ê¤¤¡¢ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    AuthUserFile + ¤Ï¡¢¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Î³°Â¦¤ËÊݴɤ¹¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + Êݸ¤è¤¦¤È¤·¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Ë¤Ï¡¢ÃÖ¤«¤Ê¤¤¤Ç²¼¤µ¤¤¡£ + ¤½¤¦¤·¤Ê¤¤¤È AuthUserFile ¤Ï + ¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Æ¤·¤Þ¤¤¤Þ¤¹¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_file.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authn_file.html.ko.euc-kr new file mode 100644 index 0000000000..9146e1712c --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.html.ko.euc-kr @@ -0,0 +1,129 @@ + + + +mod_authn_file - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authn_file

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ
    »óÅÂ:Base
    ¸ðµâ¸í:authn_file_module
    ¼Ò½ºÆÄÀÏ:mod_authn_file.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈÄ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_auth_digest¿Í + mod_auth_basic °°Àº ÀÎÁõ¾Õ´Ü¸ðµâÀ» À§ÇØ + ÀÏ¹Ý ¹®ÀÚ ¾ÏÈ£ÆÄÀÏ¿¡¼­ »ç¿ëÀÚ¸¦ ã¾Æ¼­ ÀÎÁõÇÑ´Ù. + mod_authn_dbm°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    + +

    mod_auth_basicÀ̳ª + mod_auth_digest¸¦ »ç¿ëÇÒ¶§ AuthBasicProvider³ª + AuthDigestProviderÀÇ + °ªÀ» file·Î ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthUserFile Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÎÁõÇÒ »ç¿ëÀÚ¸í¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthUserFile file-path
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authn_file
    +

    AuthUserFile Áö½Ã¾î´Â »ç¿ëÀÚ ÀÎÁõ¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. + File-path´Â ÆÄÀÏ°æ·ÎÀÌ´Ù. Àý´ë°æ·Î¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é ServerRootÀÇ + »ó´ë°æ·Î·Î ó¸®ÇÑ´Ù.

    + +

    ÆÄÀÏÀÇ °¢ ÁÙ¿¡´Â »ç¿ëÀÚ¸í, ÄÝ·Ð, ÀÎÄÚµùµÈ ¾ÏÈ£°¡ ¼ø¼­´ë·Î + ³ª¿Â´Ù. ¿©·¯ ÁÙ¿¡¼­ µ¿ÀÏÇÑ »ç¿ëÀÚ ¾ÆÀ̵𸦠Á¤ÀÇÇϸé, + mod_authn_file´Â ù¹ø°·Î ³ª¿À´Â ¾ÏÈ£¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ÄÄÆÄÀÏµÈ ¹èÆ÷º»À̳ª src/support¿¡ ÀÖ´Â htpasswd µµ±¸´Â HTTP + Basic Authentication¿¡ »ç¿ëÇÒ ¾ÏÈ£ÆÄÀÏÀ» °ü¸®ÇÑ´Ù. + ÀÚ¼¼ÇÑ ³»¿ëÀº manpage¸¦ + Âü°íÇ϶ó. ¿ä¾àÇϸé:

    + +

    Ãʱ⠾ÆÀ̵ð usernameÀ» °¡Áø ¾ÏÈ£ÆÄÀÏ + FilenameÀ» ¸¸µç´Ù. ¾ÏÈ£¸¦ ¹°¾îº»´Ù:

    + +

    + htpasswd -c Filename username +

    + +

    ¾ÏÈ£ÆÄÀÏ Filename¿¡ username2¸¦ + Ãß°¡Çϰųª ¼öÁ¤ÇÑ´Ù:

    + +

    + htpasswd Filename username2 +

    + +

    Å« ¹®ÀÚÆÄÀÏÀ» °Ë»öÇÏ´Â °ÍÀº ¸Å¿ì ºñÈ¿À²ÀûÀÓÀ» + ÁÖÀÇÇ϶ó. »ç¿ëÀÚ°¡ ¸¹´Ù¸é ´ë½Å AuthDBMUserFileÀ» »ç¿ëÇØ¾ß + ÇÑ´Ù.

    + +

    HTTP Digest AuthenticationÀ» »ç¿ëÇÑ´Ù¸é htpasswd µµ±¸·Î ¾ÈµÈ´Ù. + ´ë½Å htdigest¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. Digest Authentication°ú Basic AuthenticationÀ» + À§ÇÑ ÀڷḦ °°Àº ÆÄÀÏ¿¡ ¼¯¾î¼­ »ç¿ëÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    + +

    º¸¾È

    +

    AuthUserFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ + °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthUserFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authn_file.xml b/trunk/docs/manual/mod/mod_authn_file.xml new file mode 100644 index 0000000000..d473122fc6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.xml @@ -0,0 +1,117 @@ + + + + + + + + + +mod_authn_file +User authentication using text files +Base +mod_authn_file.c +authn_file_module +Available in Apache 2.1 and later + + +

    This module provides authentication front-ends such as + mod_auth_digest and mod_auth_basic + to authenticate users by looking up users in plain text password files. + Similar functionality is provided by mod_authn_dbm.

    + +

    When using mod_auth_basic or + mod_auth_digest, this module is invoked via the + AuthBasicProvider or + AuthDigestProvider + with the file value.

    +
    + + AuthBasicProvider + + + AuthDigestProvider + +htpasswd +htdigest + + +AuthUserFile +Sets the name of a text file containing the list of users and +passwords for authentication +AuthUserFile file-path +directory.htaccess + +AuthConfig + + +

    The AuthUserFile directive sets the name + of a textual file containing the list of users and passwords for + user authentication. File-path is the path to the user + file. If it is not absolute, it is treated as relative to the + ServerRoot.

    + +

    Each line of the user file contains a username followed by + a colon, followed by the encrypted password. If the same user + ID is defined multiple times, mod_authn_file will + use the first occurrence to verify the password.

    + +

    The utility htpasswd + which is installed as part of the binary distribution, or which + can be found in src/support, is used to maintain + the password file for HTTP Basic Authentication. See the + man page for more details. + In short:

    + +

    Create a password file Filename with + username as the initial ID. It will prompt for + the password:

    + + + htpasswd -c Filename username + + +

    Add or modify username2 in the password file + Filename:

    + + + htpasswd Filename username2 + + +

    Note that searching large text files is very + inefficient; AuthDBMUserFile should be used + instead.

    + +

    If you are using HTTP Digest Authentication, the + htpasswd tool is not sufficient. + You have to use htdigest + instead. Note that you cannot mix user data for Digest Authentication + and Basic Authentication within the same file.

    + + Security +

    Make sure that the AuthUserFile is + stored outside the document tree of the web-server. Do + not put it in the directory that it protects. + Otherwise, clients may be able to download the + AuthUserFile.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_file.xml.ja b/trunk/docs/manual/mod/mod_authn_file.xml.ja new file mode 100644 index 0000000000..e615a89633 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.xml.ja @@ -0,0 +1,125 @@ + + + + + + + + + +mod_authn_file +$B%F%-%9%H%U%!%$%k$rMQ$$$?%f!<%6G'>Z(B +Base +mod_authn_file.c +authn_file_module +Apache 2.1 $B0J9_(B + + +

    $BK\%b%8%e!<%k$O(B mod_auth_digest $B$d(B + mod_auth_basic $B$H$$$C$?G'>Z%U%m%s%H%(%s%I$KBP$7$F!"(B + $B%W%l%$%s%F%-%9%H$N%Q%9%o!<%I%U%!%$%kFb$+$i%f!<%6$r8!:w$9$k$3$H$G!"(B + $B%f!<%6G'>Z5!G=$rDs6!$7$^$9!#;w$?$h$&$J5!G=$O(B mod_authn_dbm + $B$G$bDs6!$5$l$F$$$^$9!#(B

    + +

    mod_auth_basic $B$d(B mod_auth_digest + $B$r;HMQ$9$k:]$K$O!"(B + AuthBasicProvider $B$d(B + AuthDigestPrivider + $B$G(B file $B$H;XDj$9$k$3$H$G$3$N%b%8%e!<%k$O5/F0$5$l$^$9!#(B

    +
    + + AuthBasicProvider + + + AuthDigestProvider + +htpasswd +htdigest + + +AuthUserFile +$BG'>Z$K;HMQ$9$k%f!<%6$H%Q%9%o!<%I$N0lMw$,3JG<$5$l$F$$$k!"(B +$B%F%-%9%H%U%!%$%k$NL>A0$r@_Dj$9$k(B +AuthUserFile file-path +directory.htaccess + +AuthConfig + + +

    AuthUserFile $B%G%#%l%/%F%#%V$O!"(B + $B%f!<%6G'>Z$N$?$a$N%f!<%6$H%Q%9%o!<%I$N0lMw$r3JG<$7$?(B + $B%F%-%9%H%U%!%$%k$NL>A0$r@_Dj$7$^$9!#(Bfile-path + $B$O%f!<%6%U%!%$%k$X$N%Q%9$G$9!#(B + $B$b$7@dBP%Q%9$G$J$1$l$P!"(B + ServerRoot + $B$+$i$NAjBP%Q%9$H$7$F07$o$l$^$9!#(B

    + +

    $B%f!<%6%U%!%$%k$N3F9T$K$O!"%f!<%6L>!"%3%m%s!"(B + $B0E9f2=$7$?%Q%9%o!<%I$r5-=R$7$^$9!#(B + $BF10l%f!<%6(B ID $B$,J#?t2sEPO?$5$l$?;~$O!"(B + mod_authn_file + $B$O:G=i$K8+$D$+$C$?%Q%9%o!<%I$r;HMQ$7$FG'>Z$7$^$9!#(B

    + +

    $B%P%$%J%jG[I[$N0lIt$H$7$F%$%s%9%H!<%k$5$l$k$+!"(B + $B$"$k$$$O(B src/support $B$K$"$k(B + htpasswd + $B%f!<%F%#%j%F%#$G!"$3$N(B HTTP $B4pK\G'>Z(B + $BMQ%Q%9%o!<%I%U%!%$%k$r%a%$%s%F%J%s%9$7$^$9!#(B + $B>\:Y$O(B man + $B%Z!<%8(B$B$r$4MwD:$/$H$7$F!"4JC1$K$O(B:

    + +

    $B=i4|(B ID username $B$G!"(BFilename + $B$H$$$&%Q%9%o!<%I%U%!%$%k$r@8@.$7$^$9!#(B + $B + + + htpasswd -c Filename username + + +

    $B%Q%9%o!<%I%U%!%$%k(B Filename $B$K!"(Busername2 + $B$rDI2C$7$?$j=$@5$7$?$j$7$^$9(B:

    + + + htpasswd Filename username2 + + +

    ($BLuCm(B: $BHs>o$KB?$/$N%f!<%6$rEPO?$9$k$HBg$-$J%U%!%$%k$K$J$j$^$9$,(B) + $BBg$-$J%F%-%9%H%U%!%$%k$r8!:w$9$k$N$O(B$BHs>o$K8zN($,0-$$(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#$=$N$h$&$JI,MW$N$"$k;~$O!"(B + AuthDBMUserFile + $B$rBe$o$j$K;H$C$F$/$@$5$$!#(B

    + +

    HTTP $B%@%$%8%'%9%HG'>Z(B$B$r;HMQ$9$k>l9g$O!"(B + htpasswd + $B%W%m%0%i%`$G$OIT==J,$G$9!#$=$NBe$o$j$K(B + htdigest + $B$r;HMQ$7$F$/$@$5$$!#%@%$%8%'%9%HG'>ZMQ$N%G!<%?$H(B + $B4pK\G'>ZMQ$N%G!<%?$rF10l%U%!%$%k$K:.$<$FJ]B8$G$-$J$$!"(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B

    + + $B%;%-%e%j%F%#(B +

    AuthUserFile + $B$O!"%&%'%V%5!<%P$N%I%-%e%a%s%H%D%j!<$N30B&$KJ]4I$9$k$h$&$K$7$F$/$@$5$$!#(B + $BJ]8n$7$h$&$H$7$F$$$k%G%#%l%/%H%j0J2<$K$O!"(B$BCV$+$J$$$G2<$5$$(B$B!#(B + $B$=$&$7$J$$$H(B AuthUserFile $B$O(B + $B%@%&%s%m!<%I$G$-$F$7$^$$$^$9!#(B

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_file.xml.ko b/trunk/docs/manual/mod/mod_authn_file.xml.ko new file mode 100644 index 0000000000..44dfd59ed4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.xml.ko @@ -0,0 +1,115 @@ + + + + + + + + + +mod_authn_file +¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ »ç¿ëÀÚ ÀÎÁõ +Base +mod_authn_file.c +authn_file_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈÄ + + +

    ÀÌ ¸ðµâÀº mod_auth_digest¿Í + mod_auth_basic °°Àº ÀÎÁõ¾Õ´Ü¸ðµâÀ» À§ÇØ + ÀÏ¹Ý ¹®ÀÚ ¾ÏÈ£ÆÄÀÏ¿¡¼­ »ç¿ëÀÚ¸¦ ã¾Æ¼­ ÀÎÁõÇÑ´Ù. + mod_authn_dbm°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    + +

    mod_auth_basicÀ̳ª + mod_auth_digest¸¦ »ç¿ëÇÒ¶§ AuthBasicProvider³ª + AuthDigestProviderÀÇ + °ªÀ» file·Î ¼³Á¤Çϸé ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù.

    +
    + + AuthBasicProvider + + + AuthDigestProvider + +htpasswd +htdigest + + +AuthUserFile +ÀÎÁõÇÒ »ç¿ëÀÚ¸í¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù +AuthUserFile file-path +directory.htaccess + +AuthConfig + + +

    AuthUserFile Áö½Ã¾î´Â »ç¿ëÀÚ ÀÎÁõ¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. + File-path´Â ÆÄÀÏ°æ·ÎÀÌ´Ù. Àý´ë°æ·Î¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é ServerRootÀÇ + »ó´ë°æ·Î·Î ó¸®ÇÑ´Ù.

    + +

    ÆÄÀÏÀÇ °¢ ÁÙ¿¡´Â »ç¿ëÀÚ¸í, ÄÝ·Ð, ÀÎÄÚµùµÈ ¾ÏÈ£°¡ ¼ø¼­´ë·Î + ³ª¿Â´Ù. ¿©·¯ ÁÙ¿¡¼­ µ¿ÀÏÇÑ »ç¿ëÀÚ ¾ÆÀ̵𸦠Á¤ÀÇÇϸé, + mod_authn_file´Â ù¹ø°·Î ³ª¿À´Â ¾ÏÈ£¸¦ + »ç¿ëÇÑ´Ù.

    + +

    ÄÄÆÄÀÏµÈ ¹èÆ÷º»À̳ª src/support¿¡ ÀÖ´Â htpasswd µµ±¸´Â HTTP + Basic Authentication¿¡ »ç¿ëÇÒ ¾ÏÈ£ÆÄÀÏÀ» °ü¸®ÇÑ´Ù. + ÀÚ¼¼ÇÑ ³»¿ëÀº manpage¸¦ + Âü°íÇ϶ó. ¿ä¾àÇϸé:

    + +

    Ãʱ⠾ÆÀ̵ð usernameÀ» °¡Áø ¾ÏÈ£ÆÄÀÏ + FilenameÀ» ¸¸µç´Ù. ¾ÏÈ£¸¦ ¹°¾îº»´Ù:

    + + + htpasswd -c Filename username + + +

    ¾ÏÈ£ÆÄÀÏ Filename¿¡ username2¸¦ + Ãß°¡Çϰųª ¼öÁ¤ÇÑ´Ù:

    + + + htpasswd Filename username2 + + +

    Å« ¹®ÀÚÆÄÀÏÀ» °Ë»öÇÏ´Â °ÍÀº ¸Å¿ì ºñÈ¿À²ÀûÀÓÀ» + ÁÖÀÇÇ϶ó. »ç¿ëÀÚ°¡ ¸¹´Ù¸é ´ë½Å AuthDBMUserFileÀ» »ç¿ëÇØ¾ß + ÇÑ´Ù.

    + +

    HTTP Digest AuthenticationÀ» »ç¿ëÇÑ´Ù¸é htpasswd µµ±¸·Î ¾ÈµÈ´Ù. + ´ë½Å htdigest¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. Digest Authentication°ú Basic AuthenticationÀ» + À§ÇÑ ÀڷḦ °°Àº ÆÄÀÏ¿¡ ¼¯¾î¼­ »ç¿ëÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    + + º¸¾È +

    AuthUserFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ + °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthUserFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authn_file.xml.meta b/trunk/docs/manual/mod/mod_authn_file.xml.meta new file mode 100644 index 0000000000..f3c4a4458f --- /dev/null +++ b/trunk/docs/manual/mod/mod_authn_file.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authn_file + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authnz_ldap.html b/trunk/docs/manual/mod/mod_authnz_ldap.html new file mode 100644 index 0000000000..54401c8484 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authnz_ldap.html @@ -0,0 +1,3 @@ +URI: mod_authnz_ldap.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_authnz_ldap.html.en b/trunk/docs/manual/mod/mod_authnz_ldap.html.en new file mode 100644 index 0000000000..c9bc4fa338 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authnz_ldap.html.en @@ -0,0 +1,940 @@ + + + +mod_authnz_ldap - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authnz_ldap

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Allows an LDAP directory to be used to store the database +for HTTP Basic authentication.
    Status:Extension
    Module Identifier:authnz_ldap_module
    Source File:mod_authnz_ldap.c
    Compatibility:Available in version 2.1 and later
    +

    Summary

    + +

    This module provides authentication front-ends such as + mod_auth_basic to authenticate users through + an ldap directory.

    + +

    mod_authnz_ldap supports the following features:

    + +
      +
    • Known to support the OpenLDAP SDK (both 1.x + and 2.x), + Novell LDAP SDK and the iPlanet + (Netscape) SDK.
    • + +
    • Complex authorization policies can be implemented by + representing the policy with LDAP filters.
    • + +
    • Uses extensive caching of LDAP operations via mod_ldap.
    • + +
    • Support for LDAP over SSL (requires the Netscape SDK) or + TLS (requires the OpenLDAP 2.x SDK or Novell LDAP SDK).
    • +
    + +

    When using mod_auth_basic, this module is invoked + via the AuthBasicProvider + directive with the ldap value.

    +
    + +
    top
    +
    top
    +
    +

    Operation

    + +

    There are two phases in granting access to a user. The first + phase is authentication, in which the mod_authnz_ldap + authentication provider verifies that the user's credentials are valid. + This is also called the search/bind phase. The second phase is + authorization, in which mod_authnz_ldap determines + if the authenticated user is allowed access to the resource in + question. This is also known as the compare + phase.

    + +

    mod_authnz_ldap registers both an authn_ldap authentication + provider and an authz_ldap authorization handler. The authn_ldap + authentication provider can be enabled through the + AuthBasicProvider directive + using the ldap value. The authz_ldap handler extends the + Require directive's authorization types + by adding ldap-user, ldap-dn and ldap-group + values.

    + +

    The Authentication + Phase

    + +

    During the authentication phase, mod_authnz_ldap + searches for an entry in the directory that matches the username + that the HTTP client passes. If a single unique match is found, + then mod_authnz_ldap attempts to bind to the + directory server using the DN of the entry plus the password + provided by the HTTP client. Because it does a search, then a + bind, it is often referred to as the search/bind phase. Here are + the steps taken during the search/bind phase.

    + +
      +
    1. Generate a search filter by combining the attribute and + filter provided in the AuthLDAPURL directive with + the username passed by the HTTP client.
    2. + +
    3. Search the directory using the generated filter. If the + search does not return exactly one entry, deny or decline + access.
    4. + +
    5. Fetch the distinguished name of the entry retrieved from + the search and attempt to bind to the LDAP server using the + DN and the password passed by the HTTP client. If the bind is + unsuccessful, deny or decline access.
    6. +
    + +

    The following directives are used during the search/bind + phase

    + + + + + + + + + + + + + + + + + + + + +
    AuthLDAPURLSpecifies the LDAP server, the + base DN, the attribute to use in the search, as well as the + extra search filter to use.
    AuthLDAPBindDNAn optional DN to bind with + during the search phase.
    AuthLDAPBindPasswordAn optional password to bind + with during the search phase.
    + + +

    The Authorization Phase

    + +

    During the authorization phase, mod_authnz_ldap + attempts to determine if the user is authorized to access the + resource. Many of these checks require + mod_authnz_ldap to do a compare operation on the + LDAP server. This is why this phase is often referred to as the + compare phase. mod_authnz_ldap accepts the + following Require + directives to determine if the credentials are acceptable:

    + +
      +
    • Grant access if there is a require ldap-user directive, and the + username in the directive matches the username passed by the + client.
    • + +
    • Grant access if there is a require + ldap-dn directive, and the DN in the directive matches + the DN fetched from the LDAP directory.
    • + +
    • Grant access if there is a require ldap-group directive, and + the DN fetched from the LDAP directory (or the username + passed by the client) occurs in the LDAP group.
    • + +
    • Grant access if there is a + require ldap-attribute + directive, and the attribute fetched from the LDAP directory + matches the given value.
    • + +
    • Grant access if there is a + require ldap-filter + directive, and the search filter successfully finds a single user + object that matches the dn of the authenticated user.
    • + +
    • otherwise, deny or decline access
    • +
    + +

    Other Require values may also be + used which may require loading additional authorization modules.

    + + + + +

    mod_authnz_ldap uses the following directives during the + compare phase:

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AuthLDAPURL The attribute specified in the + URL is used in compare operations for the require + ldap-user operation.
    AuthLDAPCompareDNOnServerDetermines the behavior of the + require ldap-dn directive.
    AuthLDAPGroupAttributeDetermines the attribute to + use for comparisons in the require ldap-group + directive.
    AuthLDAPGroupAttributeIsDNSpecifies whether to use the + user DN or the username when doing comparisons for the + require ldap-group directive.
    + +
    top
    +
    +

    The require Directives

    + +

    Apache's Require + directives are used during the authorization phase to ensure that + a user is allowed to access a resource. mod_authnz_ldap extends the + authorization types with ldap-user, ldap-dn, + ldap-group, ldap-attribute and + ldap-filter. Other authorization types may also be + used but may require that additional authorization modules be loaded.

    + +

    require valid-user

    + +

    If this directive exists, mod_authnz_ldap grants + access to any user that has successfully authenticated during the + search/bind phase. Requires that mod_authz_user be + loaded and that the + AuthzLDAPAuthoritative + directive be set to off.

    + + +

    require ldap-user

    + +

    The require ldap-user directive specifies what + usernames can access the resource. Once + mod_authnz_ldap has retrieved a unique DN from the + directory, it does an LDAP compare operation using the username + specified in the require ldap-user to see if that username + is part of the just-fetched LDAP entry. Multiple users can be + granted access by putting multiple usernames on the line, + separated with spaces. If a username has a space in it, then it + must be surrounded with double quotes. Multiple users can also be + granted access by using multiple require ldap-user + directives, with one user per line. For example, with a AuthLDAPURL of + ldap://ldap/o=Airius?cn (i.e., cn is + used for searches), the following require directives could be used + to restrict access:

    +

    +require ldap-user "Barbara Jenson"
    +require ldap-user "Fred User"
    +require ldap-user "Joe Manager"
    +

    + +

    Because of the way that mod_authnz_ldap handles this + directive, Barbara Jenson could sign on as Barbara + Jenson, Babs Jenson or any other cn that + she has in her LDAP entry. Only the single require + ldap-user line is needed to support all values of the attribute + in the user's entry.

    + +

    If the uid attribute was used instead of the + cn attribute in the URL above, the above three lines + could be condensed to

    +

    require ldap-user bjenson fuser jmanager

    + + +

    require ldap-group

    + +

    This directive specifies an LDAP group whose members are + allowed access. It takes the distinguished name of the LDAP + group. Note: Do not surround the group name with quotes. + For example, assume that the following entry existed in + the LDAP directory:

    +

    +dn: cn=Administrators, o=Airius
    +objectClass: groupOfUniqueNames
    +uniqueMember: cn=Barbara Jenson, o=Airius
    +uniqueMember: cn=Fred User, o=Airius
    +

    + +

    The following directive would grant access to both Fred and + Barbara:

    +

    require ldap-group cn=Administrators, o=Airius

    + +

    Behavior of this directive is modified by the AuthLDAPGroupAttribute and + AuthLDAPGroupAttributeIsDN + directives.

    + + +

    require ldap-dn

    + +

    The require ldap-dn directive allows the administrator + to grant access based on distinguished names. It specifies a DN + that must match for access to be granted. If the distinguished + name that was retrieved from the directory server matches the + distinguished name in the require ldap-dn, then + authorization is granted. Note: do not surround the distinguished + name with quotes.

    + +

    The following directive would grant access to a specific + DN:

    +

    require ldap-dn cn=Barbara Jenson, o=Airius

    + +

    Behavior of this directive is modified by the AuthLDAPCompareDNOnServer + directive.

    + + +

    require ldap-attribute

    + +

    The require ldap-attribute directive allows the + administrator to grant access based on attributes of the authenticated + user in the LDAP directory. If the attribute in the directory + matches the value given in the configuration, access is granted.

    + +

    The following directive would grant access to anyone with + the attribute employeeType = active

    + +

    require ldap-attribute employeeType=active

    + +

    Multiple attribute/value pairs can be specified on the same line + separated by spaces or they can be specified in multiple + require ldap-attribute directives. The effect of listing + multiple attribute/values pairs is an OR operation. Access will be + granted if any of the listed attribute values match the value of the + corresponding attribute in the user object. If the value of the + attribute contains a space, only the value must be within double quotes.

    + +

    The following directive would grant access to anyone with + the city attribute equal to "San Jose" or status equal to "Active"

    + +

    require ldap-attribute city="San Jose" status=active

    + + + +

    require ldap-filter

    + +

    The require ldap-filter directive allows the + administrator to grant access based on a complex LDAP search filter. + If the dn returned by the filter search matches the authenticated user + dn, access is granted.

    + +

    The following directive would grant access to anyone having a cell phone + and is in the marketing department

    + +

    require ldap-filter &(cell=*)(department=marketing)

    + +

    The difference between the require ldap-filter directive and the + require ldap-attribute directive is that ldap-filter + performs a search operation on the LDAP directory using the specified search + filter rather than a simple attribute comparison. If a simple attribute + comparison is all that is required, the comparison operation performed by + ldap-attribute will be faster than the search operation + used by ldap-filter especially within a large directory.

    + + + +
    top
    +
    +

    Examples

    + +
      +
    • + Grant access to anyone who exists in the LDAP directory, + using their UID for searches. +

      +AuthLDAPURL ldap://ldap1.airius.com:389/ou=People, o=Airius?uid?sub?(objectClass=*)
      +require valid-user +

      +
    • + +
    • + The next example is the same as above; but with the fields + that have useful defaults omitted. Also, note the use of a + redundant LDAP server. +

      AuthLDAPURL ldap://ldap1.airius.com ldap2.airius.com/ou=People, o=Airius
      +require valid-user +

      +
    • + +
    • + The next example is similar to the previous one, but it + uses the common name instead of the UID. Note that this + could be problematical if multiple people in the directory + share the same cn, because a search on cn + must return exactly one entry. That's why + this approach is not recommended: it's a better idea to + choose an attribute that is guaranteed unique in your + directory, such as uid. +

      +AuthLDAPURL ldap://ldap.airius.com/ou=People, o=Airius?cn
      +require valid-user +

      +
    • + +
    • + Grant access to anybody in the Administrators group. The + users must authenticate using their UID. +

      +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid
      +require ldap-group cn=Administrators, o=Airius +

      +
    • + +
    • + The next example assumes that everyone at Airius who + carries an alphanumeric pager will have an LDAP attribute + of qpagePagerID. The example will grant access + only to people (authenticated via their UID) who have + alphanumeric pagers: +

      +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid??(qpagePagerID=*)
      +require valid-user +

      +
    • + +
    • +

      The next example demonstrates the power of using filters + to accomplish complicated administrative requirements. + Without filters, it would have been necessary to create a + new LDAP group and ensure that the group's members remain + synchronized with the pager users. This becomes trivial + with filters. The goal is to grant access to anyone who has + a pager, plus grant access to Joe Manager, who doesn't + have a pager, but does need to access the same + resource:

      +

      +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid??(|(qpagePagerID=*)(uid=jmanager))
      +require valid-user +

      + +

      This last may look confusing at first, so it helps to + evaluate what the search filter will look like based on who + connects, as shown below. If + Fred User connects as fuser, the filter would look + like

      + +

      (&(|(qpagePagerID=*)(uid=jmanager))(uid=fuser))

      + +

      The above search will only succeed if fuser has a + pager. When Joe Manager connects as jmanager, the + filter looks like

      + +

      (&(|(qpagePagerID=*)(uid=jmanager))(uid=jmanager))

      + +

      The above search will succeed whether jmanager + has a pager or not.

      +
    • +
    +
    top
    +
    +

    Using TLS

    + +

    To use TLS, see the mod_ldap directives LDAPTrustedClientCert, LDAPTrustedGlobalCert and LDAPTrustedMode.

    + +

    An optional second parameter can be added to the + AuthLDAPURL to override + the default connection type set by LDAPTrustedMode. + This will allow the connection established by an ldap:// Url + to be upgraded to a secure connection on the same port.

    +
    top
    +
    +

    Using SSL

    + +

    To use SSL, see the mod_ldap directives LDAPTrustedClientCert, LDAPTrustedGlobalCert and LDAPTrustedMode.

    + +

    To specify a secure LDAP server, use ldaps:// in the + AuthLDAPURL + directive, instead of ldap://.

    +
    top
    +
    +

    Using Microsoft + FrontPage with mod_authnz_ldap

    + +

    Normally, FrontPage uses FrontPage-web-specific user/group + files (i.e., the mod_authn_file and + mod_authz_groupfile modules) to handle all + authentication. Unfortunately, it is not possible to just + change to LDAP authentication by adding the proper directives, + because it will break the Permissions forms in + the FrontPage client, which attempt to modify the standard + text-based authorization files.

    + +

    Once a FrontPage web has been created, adding LDAP + authentication to it is a matter of adding the following + directives to every .htaccess file + that gets created in the web

    +
    +AuthLDAPURL            "the url"
    +AuthzLDAPAuthoritative off
    +AuthGroupFile mygroupfile
    +require group mygroupfile
    +
    + +

    AuthzLDAPAuthoritative + must be off to allow mod_authnz_ldap to decline group + authentication so that Apache will fall back to file + authentication for checking group membership. This allows the + FrontPage-managed group file to be used.

    + +

    How It Works

    + +

    FrontPage restricts access to a web by adding the require + valid-user directive to the .htaccess + files. The require valid-user directive will succeed for + any user who is valid as far as LDAP is + concerned. This means that anybody who has an entry in + the LDAP directory is considered a valid user, whereas FrontPage + considers only those people in the local user file to be + valid. By substituting the ldap-group with group file authorization, + Apache is allowed to consult the local user file (which is managed by + FrontPage) - instead of LDAP - when handling authorizing the user.

    + +

    Once directives have been added as specified above, + FrontPage users will be able to perform all management + operations from the FrontPage client.

    + + +

    Caveats

    + +
      +
    • When choosing the LDAP URL, the attribute to use for + authentication should be something that will also be valid + for putting into a mod_authn_file user file. + The user ID is ideal for this.
    • + +
    • When adding users via FrontPage, FrontPage administrators + should choose usernames that already exist in the LDAP + directory (for obvious reasons). Also, the password that the + administrator enters into the form is ignored, since Apache + will actually be authenticating against the password in the + LDAP database, and not against the password in the local user + file. This could cause confusion for web administrators.
    • + + +
    • Apache must be compiled with mod_auth_basic, + mod_authn_file and + mod_authz_groupfile in order to + use FrontPage support. This is because Apache will still use + the mod_authz_groupfile group file for determine + the extent of a user's access to the FrontPage web.
    • + +
    • The directives must be put in the .htaccess + files. Attempting to put them inside <Location> or <Directory> directives won't work. This + is because mod_authnz_ldap has to be able to grab + the AuthGroupFile + directive that is found in FrontPage .htaccess + files so that it knows where to look for the valid user list. If + the mod_authnz_ldap directives aren't in the same + .htaccess file as the FrontPage directives, then + the hack won't work, because mod_authnz_ldap will + never get a chance to process the .htaccess file, + and won't be able to find the FrontPage-managed user file.
    • +
    + +
    +
    top
    +

    AuthLDAPBindDN Directive

    + + + + + + + +
    Description:Optional DN to use in binding to the LDAP server
    Syntax:AuthLDAPBindDN distinguished-name
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    An optional DN used to bind to the server when searching for + entries. If not provided, mod_authnz_ldap will use + an anonymous bind.

    + +
    +
    top
    +

    AuthLDAPBindPassword Directive

    + + + + + + + +
    Description:Password used in conjuction with the bind DN
    Syntax:AuthLDAPBindPassword password
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    A bind password to use in conjunction with the bind DN. Note + that the bind password is probably sensitive data, and should be + properly protected. You should only use the AuthLDAPBindDN and AuthLDAPBindPassword if you + absolutely need them to search the directory.

    + +
    +
    top
    +

    AuthLDAPCharsetConfig Directive

    + + + + + + +
    Description:Language to charset conversion configuration file
    Syntax:AuthLDAPCharsetConfig file-path
    Context:server config
    Status:Extension
    Module:mod_authnz_ldap
    +

    The AuthLDAPCharsetConfig directive sets the location + of the language to charset conversion configuration file. File-path is relative + to the ServerRoot. This file specifies + the list of language extensions to character sets. + Most administrators use the provided charset.conv + file, which associates common language extensions to character sets.

    + +

    The file contains lines in the following format:

    + +

    + Language-Extension charset [Language-String] ... +

    + +

    The case of the extension does not matter. Blank lines, and lines + beginning with a hash character (#) are ignored.

    + +
    +
    top
    +

    AuthLDAPCompareDNOnServer Directive

    + + + + + + + + +
    Description:Use the LDAP server to compare the DNs
    Syntax:AuthLDAPCompareDNOnServer on|off
    Default:AuthLDAPCompareDNOnServer on
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    When set, mod_authnz_ldap will use the LDAP + server to compare the DNs. This is the only foolproof way to + compare DNs. mod_authnz_ldap will search the + directory for the DN specified with the require dn directive, then, + retrieve the DN and compare it with the DN retrieved from the user + entry. If this directive is not set, + mod_authnz_ldap simply does a string comparison. It + is possible to get false negatives with this approach, but it is + much faster. Note the mod_ldap cache can speed up + DN comparison in most situations.

    + +
    +
    top
    +

    AuthLDAPDereferenceAliases Directive

    + + + + + + + + +
    Description:When will the module de-reference aliases
    Syntax:AuthLDAPDereferenceAliases never|searching|finding|always
    Default:AuthLDAPDereferenceAliases Always
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    This directive specifies when mod_authnz_ldap will + de-reference aliases during LDAP operations. The default is + always.

    + +
    +
    top
    +

    AuthLDAPGroupAttribute Directive

    + + + + + + + +
    Description:LDAP attributes used to check for group membership
    Syntax:AuthLDAPGroupAttribute attribute
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    This directive specifies which LDAP attributes are used to + check for group membership. Multiple attributes can be used by + specifying this directive multiple times. If not specified, + then mod_authnz_ldap uses the member and + uniquemember attributes.

    + +
    +
    top
    +

    AuthLDAPGroupAttributeIsDN Directive

    + + + + + + + + +
    Description:Use the DN of the client username when checking for +group membership
    Syntax:AuthLDAPGroupAttributeIsDN on|off
    Default:AuthLDAPGroupAttributeIsDN on
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    When set on, this directive says to use the + distinguished name of the client username when checking for group + membership. Otherwise, the username will be used. For example, + assume that the client sent the username bjenson, + which corresponds to the LDAP DN cn=Babs Jenson, + o=Airius. If this directive is set, + mod_authnz_ldap will check if the group has + cn=Babs Jenson, o=Airius as a member. If this + directive is not set, then mod_authnz_ldap will + check if the group has bjenson as a member.

    + +
    +
    top
    +

    AuthLDAPRemoteUserIsDN Directive

    + + + + + + + + +
    Description:Use the DN of the client username to set the REMOTE_USER +environment variable
    Syntax:AuthLDAPRemoteUserIsDN on|off
    Default:AuthLDAPRemoteUserIsDN off
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    If this directive is set to on, the value of the + REMOTE_USER environment variable will be set to the full + distinguished name of the authenticated user, rather than just + the username that was passed by the client. It is turned off by + default.

    + +
    +
    top
    +

    AuthLDAPUrl Directive

    + + + + + + + +
    Description:URL specifying the LDAP search parameters
    Syntax:AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    An RFC 2255 URL which specifies the LDAP search parameters + to use. The syntax of the URL is

    +

    ldap://host:port/basedn?attribute?scope?filter

    + +
    +
    ldap
    + +
    For regular ldap, use the + string ldap. For secure LDAP, use ldaps + instead. Secure LDAP is only available if Apache was linked + to an LDAP library with SSL support.
    + +
    host:port
    + +
    +

    The name/port of the ldap server (defaults to + localhost:389 for ldap, and + localhost:636 for ldaps). To + specify multiple, redundant LDAP servers, just list all + servers, separated by spaces. mod_authnz_ldap + will try connecting to each server in turn, until it makes a + successful connection.

    + +

    Once a connection has been made to a server, that + connection remains active for the life of the + httpd process, or until the LDAP server goes + down.

    + +

    If the LDAP server goes down and breaks an existing + connection, mod_authnz_ldap will attempt to + re-connect, starting with the primary server, and trying + each redundant server in turn. Note that this is different + than a true round-robin search.

    +
    + +
    basedn
    + +
    The DN of the branch of the + directory where all searches should start from. At the very + least, this must be the top of your directory tree, but + could also specify a subtree in the directory.
    + +
    attribute
    + +
    The attribute to search for. + Although RFC 2255 allows a comma-separated list of + attributes, only the first attribute will be used, no + matter how many are provided. If no attributes are + provided, the default is to use uid. It's a good + idea to choose an attribute that will be unique across all + entries in the subtree you will be using.
    + +
    scope
    + +
    The scope of the search. Can be either one or + sub. Note that a scope of base is + also supported by RFC 2255, but is not supported by this + module. If the scope is not provided, or if base scope + is specified, the default is to use a scope of + sub.
    + +
    filter
    + +
    A valid LDAP search filter. If + not provided, defaults to (objectClass=*), which + will search for all objects in the tree. Filters are + limited to approximately 8000 characters (the definition of + MAX_STRING_LEN in the Apache source code). This + should be than sufficient for any application.
    +
    + +

    When doing searches, the attribute, filter and username passed + by the HTTP client are combined to create a search filter that + looks like + (&(filter)(attribute=username)).

    + +

    For example, consider an URL of + ldap://ldap.airius.com/o=Airius?cn?sub?(posixid=*). When + a client attempts to connect using a username of Babs + Jenson, the resulting search filter will be + (&(posixid=*)(cn=Babs Jenson)).

    + +

    An optional parameter can be added to allow the LDAP Url to override + the connection type. This parameter can be one of the following:

    + +
    +
    NONE
    +
    Establish an unsecure connection on the default LDAP port. This + is the same as ldap:// on port 389.
    +
    SSL
    +
    Establish a secure connection on the default secure LDAP port. + This is the same as ldaps://
    +
    TLS | STARTTLS
    +
    Establish an upgraded secure connection on the default LDAP port. + This connection will be initiated on port 389 by default and then + upgraded to a secure connection on the same port.
    +
    + +

    See above for examples of AuthLDAPURL URLs.

    + +
    +
    top
    +

    AuthzLDAPAuthoritative Directive

    + + + + + + + + +
    Description:Prevent other authentication modules from +authenticating the user if this one fails
    Syntax:AuthzLDAPAuthoritative on|off
    Default:AuthzLDAPAuthoritative on
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authnz_ldap
    +

    Set to off if this module should let other + authentication modules attempt to authenticate the user, should + authentication with this module fail. Control is only passed on + to lower modules if there is no DN or rule that matches the + supplied user name (as passed by the client).

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authnz_ldap.xml b/trunk/docs/manual/mod/mod_authnz_ldap.xml new file mode 100644 index 0000000000..526de29f98 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authnz_ldap.xml @@ -0,0 +1,936 @@ + + + + + + + + + +mod_authnz_ldap +Allows an LDAP directory to be used to store the database +for HTTP Basic authentication. +Extension +mod_authnz_ldap.c +authnz_ldap_module +Available in version 2.1 and later + + +

    This module provides authentication front-ends such as + mod_auth_basic to authenticate users through + an ldap directory.

    + +

    mod_authnz_ldap supports the following features:

    + +
      +
    • Known to support the OpenLDAP SDK (both 1.x + and 2.x), + Novell LDAP SDK and the iPlanet + (Netscape) SDK.
    • + +
    • Complex authorization policies can be implemented by + representing the policy with LDAP filters.
    • + +
    • Uses extensive caching of LDAP operations via mod_ldap.
    • + +
    • Support for LDAP over SSL (requires the Netscape SDK) or + TLS (requires the OpenLDAP 2.x SDK or Novell LDAP SDK).
    • +
    + +

    When using mod_auth_basic, this module is invoked + via the AuthBasicProvider + directive with the ldap value.

    +
    + +mod_ldap +mod_auth_basic +mod_authz_user +mod_authz_groupfile + +
    Contents + + +
    + +
    Operation + +

    There are two phases in granting access to a user. The first + phase is authentication, in which the mod_authnz_ldap + authentication provider verifies that the user's credentials are valid. + This is also called the search/bind phase. The second phase is + authorization, in which mod_authnz_ldap determines + if the authenticated user is allowed access to the resource in + question. This is also known as the compare + phase.

    + +

    mod_authnz_ldap registers both an authn_ldap authentication + provider and an authz_ldap authorization handler. The authn_ldap + authentication provider can be enabled through the + AuthBasicProvider directive + using the ldap value. The authz_ldap handler extends the + Require directive's authorization types + by adding ldap-user, ldap-dn and ldap-group + values.

    + +
    The Authentication + Phase + +

    During the authentication phase, mod_authnz_ldap + searches for an entry in the directory that matches the username + that the HTTP client passes. If a single unique match is found, + then mod_authnz_ldap attempts to bind to the + directory server using the DN of the entry plus the password + provided by the HTTP client. Because it does a search, then a + bind, it is often referred to as the search/bind phase. Here are + the steps taken during the search/bind phase.

    + +
      +
    1. Generate a search filter by combining the attribute and + filter provided in the AuthLDAPURL directive with + the username passed by the HTTP client.
    2. + +
    3. Search the directory using the generated filter. If the + search does not return exactly one entry, deny or decline + access.
    4. + +
    5. Fetch the distinguished name of the entry retrieved from + the search and attempt to bind to the LDAP server using the + DN and the password passed by the HTTP client. If the bind is + unsuccessful, deny or decline access.
    6. +
    + +

    The following directives are used during the search/bind + phase

    + + + + + + + + + + + + + + + + + + + + +
    AuthLDAPURLSpecifies the LDAP server, the + base DN, the attribute to use in the search, as well as the + extra search filter to use.
    AuthLDAPBindDNAn optional DN to bind with + during the search phase.
    AuthLDAPBindPasswordAn optional password to bind + with during the search phase.
    +
    + +
    The Authorization Phase + +

    During the authorization phase, mod_authnz_ldap + attempts to determine if the user is authorized to access the + resource. Many of these checks require + mod_authnz_ldap to do a compare operation on the + LDAP server. This is why this phase is often referred to as the + compare phase. mod_authnz_ldap accepts the + following Require + directives to determine if the credentials are acceptable:

    + +
      +
    • Grant access if there is a require ldap-user directive, and the + username in the directive matches the username passed by the + client.
    • + +
    • Grant access if there is a require + ldap-dn directive, and the DN in the directive matches + the DN fetched from the LDAP directory.
    • + +
    • Grant access if there is a require ldap-group directive, and + the DN fetched from the LDAP directory (or the username + passed by the client) occurs in the LDAP group.
    • + +
    • Grant access if there is a + require ldap-attribute + directive, and the attribute fetched from the LDAP directory + matches the given value.
    • + +
    • Grant access if there is a + require ldap-filter + directive, and the search filter successfully finds a single user + object that matches the dn of the authenticated user.
    • + +
    • otherwise, deny or decline access
    • +
    + +

    Other Require values may also be + used which may require loading additional authorization modules.

    + +
      +
    • Grant access if there is a require + valid-user directive. (requires + mod_authz_user)
    • + +
    • Grant access if there is a require group directive, and + mod_authz_groupfile has been loaded with the + AuthGroupFile + directive set.
    • + +
    • others...
    • +
    + + +

    mod_authnz_ldap uses the following directives during the + compare phase:

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AuthLDAPURL The attribute specified in the + URL is used in compare operations for the require + ldap-user operation.
    AuthLDAPCompareDNOnServerDetermines the behavior of the + require ldap-dn directive.
    AuthLDAPGroupAttributeDetermines the attribute to + use for comparisons in the require ldap-group + directive.
    AuthLDAPGroupAttributeIsDNSpecifies whether to use the + user DN or the username when doing comparisons for the + require ldap-group directive.
    +
    +
    + +
    The require Directives + +

    Apache's Require + directives are used during the authorization phase to ensure that + a user is allowed to access a resource. mod_authnz_ldap extends the + authorization types with ldap-user, ldap-dn, + ldap-group, ldap-attribute and + ldap-filter. Other authorization types may also be + used but may require that additional authorization modules be loaded.

    + +
    require valid-user + +

    If this directive exists, mod_authnz_ldap grants + access to any user that has successfully authenticated during the + search/bind phase. Requires that mod_authz_user be + loaded and that the + AuthzLDAPAuthoritative + directive be set to off.

    +
    + +
    require ldap-user + +

    The require ldap-user directive specifies what + usernames can access the resource. Once + mod_authnz_ldap has retrieved a unique DN from the + directory, it does an LDAP compare operation using the username + specified in the require ldap-user to see if that username + is part of the just-fetched LDAP entry. Multiple users can be + granted access by putting multiple usernames on the line, + separated with spaces. If a username has a space in it, then it + must be surrounded with double quotes. Multiple users can also be + granted access by using multiple require ldap-user + directives, with one user per line. For example, with a AuthLDAPURL of + ldap://ldap/o=Airius?cn (i.e., cn is + used for searches), the following require directives could be used + to restrict access:

    + +require ldap-user "Barbara Jenson"
    +require ldap-user "Fred User"
    +require ldap-user "Joe Manager"
    +
    + +

    Because of the way that mod_authnz_ldap handles this + directive, Barbara Jenson could sign on as Barbara + Jenson, Babs Jenson or any other cn that + she has in her LDAP entry. Only the single require + ldap-user line is needed to support all values of the attribute + in the user's entry.

    + +

    If the uid attribute was used instead of the + cn attribute in the URL above, the above three lines + could be condensed to

    +require ldap-user bjenson fuser jmanager +
    + +
    require ldap-group + +

    This directive specifies an LDAP group whose members are + allowed access. It takes the distinguished name of the LDAP + group. Note: Do not surround the group name with quotes. + For example, assume that the following entry existed in + the LDAP directory:

    + +dn: cn=Administrators, o=Airius
    +objectClass: groupOfUniqueNames
    +uniqueMember: cn=Barbara Jenson, o=Airius
    +uniqueMember: cn=Fred User, o=Airius
    +
    + +

    The following directive would grant access to both Fred and + Barbara:

    +require ldap-group cn=Administrators, o=Airius + +

    Behavior of this directive is modified by the AuthLDAPGroupAttribute and + AuthLDAPGroupAttributeIsDN + directives.

    +
    + +
    require ldap-dn + +

    The require ldap-dn directive allows the administrator + to grant access based on distinguished names. It specifies a DN + that must match for access to be granted. If the distinguished + name that was retrieved from the directory server matches the + distinguished name in the require ldap-dn, then + authorization is granted. Note: do not surround the distinguished + name with quotes.

    + +

    The following directive would grant access to a specific + DN:

    +require ldap-dn cn=Barbara Jenson, o=Airius + +

    Behavior of this directive is modified by the AuthLDAPCompareDNOnServer + directive.

    +
    + +
    require ldap-attribute + +

    The require ldap-attribute directive allows the + administrator to grant access based on attributes of the authenticated + user in the LDAP directory. If the attribute in the directory + matches the value given in the configuration, access is granted.

    + +

    The following directive would grant access to anyone with + the attribute employeeType = active

    + + require ldap-attribute employeeType=active + +

    Multiple attribute/value pairs can be specified on the same line + separated by spaces or they can be specified in multiple + require ldap-attribute directives. The effect of listing + multiple attribute/values pairs is an OR operation. Access will be + granted if any of the listed attribute values match the value of the + corresponding attribute in the user object. If the value of the + attribute contains a space, only the value must be within double quotes.

    + +

    The following directive would grant access to anyone with + the city attribute equal to "San Jose" or status equal to "Active"

    + + require ldap-attribute city="San Jose" status=active + +
    + +
    require ldap-filter + +

    The require ldap-filter directive allows the + administrator to grant access based on a complex LDAP search filter. + If the dn returned by the filter search matches the authenticated user + dn, access is granted.

    + +

    The following directive would grant access to anyone having a cell phone + and is in the marketing department

    + + require ldap-filter &(cell=*)(department=marketing) + +

    The difference between the require ldap-filter directive and the + require ldap-attribute directive is that ldap-filter + performs a search operation on the LDAP directory using the specified search + filter rather than a simple attribute comparison. If a simple attribute + comparison is all that is required, the comparison operation performed by + ldap-attribute will be faster than the search operation + used by ldap-filter especially within a large directory.

    + +
    + +
    + +
    Examples + +
      +
    • + Grant access to anyone who exists in the LDAP directory, + using their UID for searches. + +AuthLDAPURL ldap://ldap1.airius.com:389/ou=People, o=Airius?uid?sub?(objectClass=*)
      +require valid-user +
      +
    • + +
    • + The next example is the same as above; but with the fields + that have useful defaults omitted. Also, note the use of a + redundant LDAP server. +AuthLDAPURL ldap://ldap1.airius.com ldap2.airius.com/ou=People, o=Airius
      +require valid-user +
      +
    • + +
    • + The next example is similar to the previous one, but it + uses the common name instead of the UID. Note that this + could be problematical if multiple people in the directory + share the same cn, because a search on cn + must return exactly one entry. That's why + this approach is not recommended: it's a better idea to + choose an attribute that is guaranteed unique in your + directory, such as uid. + +AuthLDAPURL ldap://ldap.airius.com/ou=People, o=Airius?cn
      +require valid-user +
      +
    • + +
    • + Grant access to anybody in the Administrators group. The + users must authenticate using their UID. + +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid
      +require ldap-group cn=Administrators, o=Airius +
      +
    • + +
    • + The next example assumes that everyone at Airius who + carries an alphanumeric pager will have an LDAP attribute + of qpagePagerID. The example will grant access + only to people (authenticated via their UID) who have + alphanumeric pagers: + +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid??(qpagePagerID=*)
      +require valid-user +
      +
    • + +
    • +

      The next example demonstrates the power of using filters + to accomplish complicated administrative requirements. + Without filters, it would have been necessary to create a + new LDAP group and ensure that the group's members remain + synchronized with the pager users. This becomes trivial + with filters. The goal is to grant access to anyone who has + a pager, plus grant access to Joe Manager, who doesn't + have a pager, but does need to access the same + resource:

      + +AuthLDAPURL ldap://ldap.airius.com/o=Airius?uid??(|(qpagePagerID=*)(uid=jmanager))
      +require valid-user +
      + +

      This last may look confusing at first, so it helps to + evaluate what the search filter will look like based on who + connects, as shown below. If + Fred User connects as fuser, the filter would look + like

      + + (&(|(qpagePagerID=*)(uid=jmanager))(uid=fuser)) + +

      The above search will only succeed if fuser has a + pager. When Joe Manager connects as jmanager, the + filter looks like

      + + (&(|(qpagePagerID=*)(uid=jmanager))(uid=jmanager)) + +

      The above search will succeed whether jmanager + has a pager or not.

      +
    • +
    +
    + +
    Using TLS + +

    To use TLS, see the mod_ldap directives LDAPTrustedClientCert, LDAPTrustedGlobalCert and LDAPTrustedMode.

    + +

    An optional second parameter can be added to the + AuthLDAPURL to override + the default connection type set by LDAPTrustedMode. + This will allow the connection established by an ldap:// Url + to be upgraded to a secure connection on the same port.

    +
    + +
    Using SSL + +

    To use SSL, see the mod_ldap directives LDAPTrustedClientCert, LDAPTrustedGlobalCert and LDAPTrustedMode.

    + +

    To specify a secure LDAP server, use ldaps:// in the + AuthLDAPURL + directive, instead of ldap://.

    +
    + +
    Using Microsoft + FrontPage with mod_authnz_ldap + +

    Normally, FrontPage uses FrontPage-web-specific user/group + files (i.e., the mod_authn_file and + mod_authz_groupfile modules) to handle all + authentication. Unfortunately, it is not possible to just + change to LDAP authentication by adding the proper directives, + because it will break the Permissions forms in + the FrontPage client, which attempt to modify the standard + text-based authorization files.

    + +

    Once a FrontPage web has been created, adding LDAP + authentication to it is a matter of adding the following + directives to every .htaccess file + that gets created in the web

    +
    +AuthLDAPURL            "the url"
    +AuthzLDAPAuthoritative off
    +AuthGroupFile mygroupfile
    +require group mygroupfile
    +
    + +

    AuthzLDAPAuthoritative + must be off to allow mod_authnz_ldap to decline group + authentication so that Apache will fall back to file + authentication for checking group membership. This allows the + FrontPage-managed group file to be used.

    + +
    How It Works + +

    FrontPage restricts access to a web by adding the require + valid-user directive to the .htaccess + files. The require valid-user directive will succeed for + any user who is valid as far as LDAP is + concerned. This means that anybody who has an entry in + the LDAP directory is considered a valid user, whereas FrontPage + considers only those people in the local user file to be + valid. By substituting the ldap-group with group file authorization, + Apache is allowed to consult the local user file (which is managed by + FrontPage) - instead of LDAP - when handling authorizing the user.

    + +

    Once directives have been added as specified above, + FrontPage users will be able to perform all management + operations from the FrontPage client.

    +
    + +
    Caveats + +
      +
    • When choosing the LDAP URL, the attribute to use for + authentication should be something that will also be valid + for putting into a mod_authn_file user file. + The user ID is ideal for this.
    • + +
    • When adding users via FrontPage, FrontPage administrators + should choose usernames that already exist in the LDAP + directory (for obvious reasons). Also, the password that the + administrator enters into the form is ignored, since Apache + will actually be authenticating against the password in the + LDAP database, and not against the password in the local user + file. This could cause confusion for web administrators.
    • + + +
    • Apache must be compiled with mod_auth_basic, + mod_authn_file and + mod_authz_groupfile in order to + use FrontPage support. This is because Apache will still use + the mod_authz_groupfile group file for determine + the extent of a user's access to the FrontPage web.
    • + +
    • The directives must be put in the .htaccess + files. Attempting to put them inside Location or Directory directives won't work. This + is because mod_authnz_ldap has to be able to grab + the AuthGroupFile + directive that is found in FrontPage .htaccess + files so that it knows where to look for the valid user list. If + the mod_authnz_ldap directives aren't in the same + .htaccess file as the FrontPage directives, then + the hack won't work, because mod_authnz_ldap will + never get a chance to process the .htaccess file, + and won't be able to find the FrontPage-managed user file.
    • +
    +
    +
    + + +AuthzLDAPAuthoritative +Prevent other authentication modules from +authenticating the user if this one fails +AuthzLDAPAuthoritative on|off +AuthzLDAPAuthoritative on +directory.htaccess + +AuthConfig + + +

    Set to off if this module should let other + authentication modules attempt to authenticate the user, should + authentication with this module fail. Control is only passed on + to lower modules if there is no DN or rule that matches the + supplied user name (as passed by the client).

    +
    +
    + + +AuthLDAPBindDN +Optional DN to use in binding to the LDAP server +AuthLDAPBindDN distinguished-name +directory.htaccess + +AuthConfig + + +

    An optional DN used to bind to the server when searching for + entries. If not provided, mod_authnz_ldap will use + an anonymous bind.

    +
    +
    + + +AuthLDAPBindPassword +Password used in conjuction with the bind DN +AuthLDAPBindPassword password +directory.htaccess + +AuthConfig + + +

    A bind password to use in conjunction with the bind DN. Note + that the bind password is probably sensitive data, and should be + properly protected. You should only use the AuthLDAPBindDN and AuthLDAPBindPassword if you + absolutely need them to search the directory.

    +
    +
    + + +AuthLDAPCharsetConfig +Language to charset conversion configuration file +AuthLDAPCharsetConfig file-path +server config + + + +

    The AuthLDAPCharsetConfig directive sets the location + of the language to charset conversion configuration file. File-path is relative + to the ServerRoot. This file specifies + the list of language extensions to character sets. + Most administrators use the provided charset.conv + file, which associates common language extensions to character sets.

    + +

    The file contains lines in the following format:

    + + + Language-Extension charset [Language-String] ... + + +

    The case of the extension does not matter. Blank lines, and lines + beginning with a hash character (#) are ignored.

    +
    +
    + + +AuthLDAPCompareDNOnServer +Use the LDAP server to compare the DNs +AuthLDAPCompareDNOnServer on|off +AuthLDAPCompareDNOnServer on +directory.htaccess + +AuthConfig + + +

    When set, mod_authnz_ldap will use the LDAP + server to compare the DNs. This is the only foolproof way to + compare DNs. mod_authnz_ldap will search the + directory for the DN specified with the require dn directive, then, + retrieve the DN and compare it with the DN retrieved from the user + entry. If this directive is not set, + mod_authnz_ldap simply does a string comparison. It + is possible to get false negatives with this approach, but it is + much faster. Note the mod_ldap cache can speed up + DN comparison in most situations.

    +
    +
    + + +AuthLDAPDereferenceAliases +When will the module de-reference aliases +AuthLDAPDereferenceAliases never|searching|finding|always +AuthLDAPDereferenceAliases Always +directory.htaccess + +AuthConfig + + +

    This directive specifies when mod_authnz_ldap will + de-reference aliases during LDAP operations. The default is + always.

    +
    +
    + + +AuthLDAPGroupAttribute +LDAP attributes used to check for group membership +AuthLDAPGroupAttribute attribute +directory.htaccess + +AuthConfig + + +

    This directive specifies which LDAP attributes are used to + check for group membership. Multiple attributes can be used by + specifying this directive multiple times. If not specified, + then mod_authnz_ldap uses the member and + uniquemember attributes.

    +
    +
    + + +AuthLDAPGroupAttributeIsDN +Use the DN of the client username when checking for +group membership +AuthLDAPGroupAttributeIsDN on|off +AuthLDAPGroupAttributeIsDN on +directory.htaccess + +AuthConfig + + +

    When set on, this directive says to use the + distinguished name of the client username when checking for group + membership. Otherwise, the username will be used. For example, + assume that the client sent the username bjenson, + which corresponds to the LDAP DN cn=Babs Jenson, + o=Airius. If this directive is set, + mod_authnz_ldap will check if the group has + cn=Babs Jenson, o=Airius as a member. If this + directive is not set, then mod_authnz_ldap will + check if the group has bjenson as a member.

    +
    +
    + + +AuthLDAPRemoteUserIsDN +Use the DN of the client username to set the REMOTE_USER +environment variable +AuthLDAPRemoteUserIsDN on|off +AuthLDAPRemoteUserIsDN off +directory.htaccess + +AuthConfig + + +

    If this directive is set to on, the value of the + REMOTE_USER environment variable will be set to the full + distinguished name of the authenticated user, rather than just + the username that was passed by the client. It is turned off by + default.

    +
    +
    + + +AuthLDAPUrl +URL specifying the LDAP search parameters +AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS] +directory.htaccess + +AuthConfig + + +

    An RFC 2255 URL which specifies the LDAP search parameters + to use. The syntax of the URL is

    +ldap://host:port/basedn?attribute?scope?filter + +
    +
    ldap
    + +
    For regular ldap, use the + string ldap. For secure LDAP, use ldaps + instead. Secure LDAP is only available if Apache was linked + to an LDAP library with SSL support.
    + +
    host:port
    + +
    +

    The name/port of the ldap server (defaults to + localhost:389 for ldap, and + localhost:636 for ldaps). To + specify multiple, redundant LDAP servers, just list all + servers, separated by spaces. mod_authnz_ldap + will try connecting to each server in turn, until it makes a + successful connection.

    + +

    Once a connection has been made to a server, that + connection remains active for the life of the + httpd process, or until the LDAP server goes + down.

    + +

    If the LDAP server goes down and breaks an existing + connection, mod_authnz_ldap will attempt to + re-connect, starting with the primary server, and trying + each redundant server in turn. Note that this is different + than a true round-robin search.

    +
    + +
    basedn
    + +
    The DN of the branch of the + directory where all searches should start from. At the very + least, this must be the top of your directory tree, but + could also specify a subtree in the directory.
    + +
    attribute
    + +
    The attribute to search for. + Although RFC 2255 allows a comma-separated list of + attributes, only the first attribute will be used, no + matter how many are provided. If no attributes are + provided, the default is to use uid. It's a good + idea to choose an attribute that will be unique across all + entries in the subtree you will be using.
    + +
    scope
    + +
    The scope of the search. Can be either one or + sub. Note that a scope of base is + also supported by RFC 2255, but is not supported by this + module. If the scope is not provided, or if base scope + is specified, the default is to use a scope of + sub.
    + +
    filter
    + +
    A valid LDAP search filter. If + not provided, defaults to (objectClass=*), which + will search for all objects in the tree. Filters are + limited to approximately 8000 characters (the definition of + MAX_STRING_LEN in the Apache source code). This + should be than sufficient for any application.
    +
    + +

    When doing searches, the attribute, filter and username passed + by the HTTP client are combined to create a search filter that + looks like + (&(filter)(attribute=username)).

    + +

    For example, consider an URL of + ldap://ldap.airius.com/o=Airius?cn?sub?(posixid=*). When + a client attempts to connect using a username of Babs + Jenson, the resulting search filter will be + (&(posixid=*)(cn=Babs Jenson)).

    + +

    An optional parameter can be added to allow the LDAP Url to override + the connection type. This parameter can be one of the following:

    + +
    +
    NONE
    +
    Establish an unsecure connection on the default LDAP port. This + is the same as ldap:// on port 389.
    +
    SSL
    +
    Establish a secure connection on the default secure LDAP port. + This is the same as ldaps://
    +
    TLS | STARTTLS
    +
    Establish an upgraded secure connection on the default LDAP port. + This connection will be initiated on port 389 by default and then + upgraded to a secure connection on the same port.
    +
    + +

    See above for examples of AuthLDAPURL URLs.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authnz_ldap.xml.meta b/trunk/docs/manual/mod/mod_authnz_ldap.xml.meta new file mode 100644 index 0000000000..d63d25c3c1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authnz_ldap.xml.meta @@ -0,0 +1,11 @@ + + + + mod_authnz_ldap + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_authz_dbm.html b/trunk/docs/manual/mod/mod_authz_dbm.html new file mode 100644 index 0000000000..5b5cdad64d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.html @@ -0,0 +1,7 @@ +URI: mod_authz_dbm.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_dbm.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_dbm.html.en b/trunk/docs/manual/mod/mod_authz_dbm.html.en new file mode 100644 index 0000000000..362801aea5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.html.en @@ -0,0 +1,185 @@ + + + +mod_authz_dbm - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_dbm

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + + +
    Description:Group authorization using DBM files
    Status:Extension
    Module Identifier:authz_dbm_module
    Source File:mod_authz_dbm.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site by group membership. Similar functionality is + provided by mod_authz_groupfile.

    +
    + + +
    top
    +

    AuthDBMGroupFile Directive

    + + + + + + + +
    Description:Sets the name of the database file containing the list +of user groups for authorization
    Syntax:AuthDBMGroupFile file-path
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authz_dbm
    +

    The AuthDBMGroupFile directive sets the + name of a DBM file containing the list of user groups for user + authorization. File-path is the absolute path to the + group file.

    + +

    The group file is keyed on the username. The value for a + user is a comma-separated list of the groups to which the users + belongs. There must be no whitespace within the value, and it + must never contain any colons.

    + +

    Security

    +

    Make sure that the AuthDBMGroupFile is + stored outside the document tree of the web-server. Do + not put it in the directory that it protects. + Otherwise, clients will be able to download the + AuthDBMGroupFile unless otherwise + protected.

    +
    + +

    Combining Group and Password DBM files: In some cases it is + easier to manage a single database which contains both the + password and group details for each user. This simplifies any + support programs that need to be written: they now only have to + deal with writing to and locking a single DBM file. This can be + accomplished by first setting the group and password files to + point to the same DBM:

    + +

    + AuthDBMGroupFile /www/userbase
    + AuthDBMUserFile /www/userbase +

    + +

    The key for the single DBM is the username. The value consists + of

    + +

    + Encrypted Password : List of Groups [ : (ignored) ] +

    + +

    The password section contains the encrypted + password as before. This is followed by a colon and the comma + separated list of groups. Other data may optionally be left in the + DBM file after another colon; it is ignored by the authorization + module. This is what www.telescope.org uses for its combined + password and group database.

    + +
    +
    top
    +

    AuthzDBMAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization will be passed on to lower level +modules
    Syntax:AuthzDBMAuthoritative On|Off
    Default:AuthzDBMAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authz_dbm
    +

    Setting the AuthzDBMAuthoritative + directive explicitly to Off allows group authorization + to be passed on to lower level modules (as defined in the + modules.c file) if there is no group found + for the the supplied userID. If there are any groups + specified, the usual checks will be applied and a failure will + give an Authentication Required reply.

    + +

    So if a userID appears in the database of more than one module; + or if a valid Require + directive applies to more than one module; then the first module + will verify the credentials; and no access is passed on; + regardless of the AuthAuthoritative setting.

    + +

    A common use for this is in conjunction with one of the + auth providers; such as mod_authn_dbm or + mod_authn_file. Whereas this DBM module supplies + the bulk of the user credential checking; a few (administrator) related + accesses fall through to a lower level with a well protected + .htpasswd file.

    + +

    By default, control is not passed on and an unknown group + will result in an Authentication Required reply. Not + setting it thus keeps the system secure and forces an NCSA + compliant behaviour.

    + +

    Security

    +

    Do consider the implications of allowing a user to + allow fall-through in his .htaccess file; and verify that this + is really what you want; Generally it is easier to just secure + a single .htpasswd file, than it is to secure a + database which might have more access interfaces.

    +
    + +
    +
    top
    +

    AuthzDBMType Directive

    + + + + + + + + +
    Description:Sets the type of database file that is used to +store list of user groups
    Syntax:AuthzDBMType default|SDBM|GDBM|NDBM|DB
    Default:AuthzDBMType default
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authz_dbm
    +

    Sets the type of database file that is used to store the list + of user groups. + The default database type is determined at compile time. The + availability of other types of database files also depends on + compile-time settings.

    + +

    It is crucial that whatever program you use to create your group + files is configured to use the same type of database.

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_dbm.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_dbm.html.ko.euc-kr new file mode 100644 index 0000000000..f8fb022a78 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.html.ko.euc-kr @@ -0,0 +1,170 @@ + + + +mod_authz_dbm - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_dbm

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:DBM ÆÄÀÏÀ» »ç¿ëÇÑ ±×·ì ÀÎÁõ
    »óÅÂ:Extension
    ¸ðµâ¸í:authz_dbm_module
    ¼Ò½ºÆÄÀÏ:mod_authz_dbm.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ÀÎÁõÇÑ »ç¿ëÀÚÀÇ ±×·ì±ÇÇÑÀ¸·Î À¥ÀÇ ÀϺθ¦ Á¢±ÙÇÒ + ¼ö ÀÖ´ÂÁö °áÁ¤ÇÏ¿© ±ÇÇѺο©¸¦ ÇÑ´Ù. + mod_authz_groupfile°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthDBMGroupFile Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthDBMGroupFile file-path
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authz_dbm
    +

    AuthDBMGroupFile Áö½Ã¾î´Â ÀÎÁõ¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â DBM ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. + File-path´Â ÆÄÀÏÀÇ Àý´ë°æ·ÎÀÌ´Ù.

    + +

    ÆÄÀÏÀº »ç¿ëÀÚ¸íÀ» Å°·Î »ç¿ëÇÑ´Ù. »ç¿ëÀÚ¿¡ ´ëÇÑ °ªÀº ½°Ç¥·Î + ±¸ºÐÇÑ »ç¿ëÀÚ°¡ ¼ÓÇÑ ±×·ì ¸ñ·ÏÀÌ´Ù. °ª¿¡ °ø¹éÀ̳ª ÄÝ·ÐÀ» + »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    º¸¾È

    +

    AuthDBMGroupFileÀÌ À¥¼­¹öÀÇ + ¹®¼­µé ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 + ¾È¿¡ °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthDBMGroupFile¸¦ ´Ù¿î·ÎµåÇÒ ¼ö + ÀÖ´Ù.

    +
    + +

    ±×·ì DBM ÆÄÀÏ°ú ¾ÏÈ£ DBM ÆÄÀÏÀ» °°ÀÌ »ç¿ëÇϱâ: »ç¿ëÀÚ¿¡ + ´ëÇÑ ¾ÏÈ£¿Í ±×·ì Á¤º¸ ¸ðµÎ¸¦ ÇÑ µ¥ÀÌÅͺ£À̽º¿¡¼­ °ü¸®ÇÏ´Â + °ÍÀÌ ½¬¿ï¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì ÀÛ¼ºÇÒ Áö¿ø ÇÁ·Î±×·¥ÀÌ °£´ÜÇØÁø´Ù. + ÇÁ·Î±×·¥Àº ÇÑ DBM ÆÄÀϸ¸À» Àá±×°í ¾²¸é µÈ´Ù. ±×·ìÆÄÀÏ°ú + ¾ÏÈ£ÆÄÀÏÀ» °°Àº DBMÆÄÀÏ·Î ¼³Á¤ÇÏ¸é °¡´ÉÇÏ´Ù:

    + +

    + AuthDBMGroupFile /www/userbase
    + AuthDBMUserFile /www/userbase +

    + +

    ÀÌ ÅëÇÕ DBMÀÇ Å°´Â »ç¿ëÀÚ¸íÀÌ´Ù. °ªÀº ´ÙÀ½°ú °°´Ù

    + +

    + ÀÎÄÚµùµÈ ¾ÏÈ£ : ±×·ì ¸ñ·Ï [ : (¹«½Ã) ] +

    + +

    ¾ÏÈ£ ºÎºÐÀº Àü°ú °°ÀÌ ÀÎÄÚµùµÈ ¾ÏÈ£ÀÌ´Ù. ÄÝ·Ð µÚ¿¡ ½°Ç¥·Î + ±¸ºÐÇÑ ±×·ì ¸ñ·ÏÀÌ ³ª¿Â´Ù. ¶Ç ´Ù½Ã ÄÝ·Ð ´ÙÀ½¿¡ ´Ù¸¥ Á¤º¸¸¦ + ±â·ÏÇÒ ¼ö ÀÖ´Ù. ÀÌ ºÎºÐÀº ÀÎÁõ¸ðµâÀÌ ¹«½ÃÇÑ´Ù. + www.telescope.org´Â ÀÌ·¸°Ô ¾ÏÈ£ µ¥ÀÌÅͺ£À̽º¿Í ±×·ì + µ¥ÀÌÅͺ£À̽º¸¦ °°ÀÌ »ç¿ëÇÑ´Ù.

    + +
    +
    top
    +

    AuthzDBMAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthzDBMAuthoritative On|Off
    ±âº»°ª:AuthzDBMAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authz_dbm
    +

    AuthzDBMAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ ¾ÆÀ̵𿡠´ëÇÑ + ±×·ìÀÌ ¾ø´Â °æ¿ì ±×·ì ±ÇÇѺο©¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù. ÁöÁ¤ÇÑ ±×·ìÀÌ ÀÖ´Ù¸é + º¸Å붧¿Í °°ÀÌ °Ë»çÇÏ°í, ½ÇÆÐÇϸé ÀÎÁõ ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ ¸ðµâÀÇ µ¥ÀÌÅͺ£À̽º¿¡ »ç¿ëÀÚ ¾ÆÀ̵𰡠Àְųª + À¯È¿ÇÑ Require Áö½Ã¾î¸¦ + ¿©·¯ ¸ðµâ¿¡ Àû¿ëÇϸé, ù¹ø° ¸ðµâÀÌ »ç¿ëÀÚ¸¦ °Ë»çÇÏ°í, + AuthAuthoritative ¼³Á¤°ú °ü°è¾øÀÌ + Á¢±ÙÀ» ³Ñ±âÁö¾Ê´Â´Ù.

    + +

    ÀϹÝÀûÀ¸·Î mod_authn_dbmÀ̳ª + mod_authn_file°ú °°Àº ÀÎÁõÁ¦°øÀÚ¿Í °°ÀÌ + »ç¿ëÇÑ´Ù. ´ë·®ÀÇ »ç¿ëÀÚ °Ë»ç¿¡ ´ëÇÑ °Ë»ç´Â DBM ¸ðµâÀ» + »ç¿ëÇÏÁö¸¸, ¼Ò¼ö(°ü¸®ÀÚ)¿¡ ´ëÇÑ °Ë»ç´Â Àß º¸È£µÈ + .htpasswd ÆÄÀÏ·Î ³Ñ±ä´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô + À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + +

    º¸¾È

    +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ°Ô µÇ´ÂÁö »ìÆ캸°í, + ÀÌ·± ÇൿÀ» Çã¿ëÇÒÁö °áÁ¤Ç϶ó. ÀϹÝÀûÀ¸·Î ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î + Á¢±ÙÇÒ ¼ö ÀÖ´Â µ¥ÀÌÅͺ£À̽º¸¦ º¸È£ÇÏ´Â °Íº¸´Ù ÇϳªÀÇ + .htpasswd ÆÄÀÏÀ» º¸È£ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    +
    + +
    +
    top
    +

    AuthzDBMType Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthzDBMType default|SDBM|GDBM|NDBM|DB
    ±âº»°ª:AuthzDBMType default
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authz_dbm
    +

    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. + µ¥ÀÌÅͺ£À̽º Á¾·ù ±âº»°ªÀº ÄÄÆÄÀ϶§ Á¤ÇØÁø´Ù. »ç¿ëÇÒ ¼ö + ÀÖ´Â ´Ù¸¥ µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ùµµ ÄÄÆÄÀÏ ¼³Á¤¿¡ ´Þ·È´Ù.

    + +

    ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç ÇÁ·Î±×·¥ÀÌ °°Àº Á¾·ùÀÇ µ¥ÀÌÅͺ£À̽º¸¦ + »ç¿ëÇϵµ·Ï ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_dbm.xml b/trunk/docs/manual/mod/mod_authz_dbm.xml new file mode 100644 index 0000000000..6d6ca04ff3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.xml @@ -0,0 +1,169 @@ + + + + + + + + + +mod_authz_dbm +Group authorization using DBM files +Extension +mod_authz_dbm.c +authz_dbm_module +Available in Apache 2.1 and later + + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site by group membership. Similar functionality is + provided by mod_authz_groupfile.

    +
    + +Require +Satisfy + + +AuthDBMGroupFile +Sets the name of the database file containing the list +of user groups for authorization +AuthDBMGroupFile file-path +directory.htaccess + +AuthConfig + + +

    The AuthDBMGroupFile directive sets the + name of a DBM file containing the list of user groups for user + authorization. File-path is the absolute path to the + group file.

    + +

    The group file is keyed on the username. The value for a + user is a comma-separated list of the groups to which the users + belongs. There must be no whitespace within the value, and it + must never contain any colons.

    + + Security +

    Make sure that the AuthDBMGroupFile is + stored outside the document tree of the web-server. Do + not put it in the directory that it protects. + Otherwise, clients will be able to download the + AuthDBMGroupFile unless otherwise + protected.

    +
    + +

    Combining Group and Password DBM files: In some cases it is + easier to manage a single database which contains both the + password and group details for each user. This simplifies any + support programs that need to be written: they now only have to + deal with writing to and locking a single DBM file. This can be + accomplished by first setting the group and password files to + point to the same DBM:

    + + + AuthDBMGroupFile /www/userbase
    + AuthDBMUserFile /www/userbase +
    + +

    The key for the single DBM is the username. The value consists + of

    + + + Encrypted Password : List of Groups [ : (ignored) ] + + +

    The password section contains the encrypted + password as before. This is followed by a colon and the comma + separated list of groups. Other data may optionally be left in the + DBM file after another colon; it is ignored by the authorization + module. This is what www.telescope.org uses for its combined + password and group database.

    +
    +
    + + +AuthzDBMType +Sets the type of database file that is used to +store list of user groups +AuthzDBMType default|SDBM|GDBM|NDBM|DB +AuthzDBMType default +directory.htaccess + +AuthConfig + + +

    Sets the type of database file that is used to store the list + of user groups. + The default database type is determined at compile time. The + availability of other types of database files also depends on + compile-time settings.

    + +

    It is crucial that whatever program you use to create your group + files is configured to use the same type of database.

    +
    +
    + + +AuthzDBMAuthoritative +Sets whether authorization will be passed on to lower level +modules +AuthzDBMAuthoritative On|Off +AuthzDBMAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthzDBMAuthoritative + directive explicitly to Off allows group authorization + to be passed on to lower level modules (as defined in the + modules.c file) if there is no group found + for the the supplied userID. If there are any groups + specified, the usual checks will be applied and a failure will + give an Authentication Required reply.

    + +

    So if a userID appears in the database of more than one module; + or if a valid Require + directive applies to more than one module; then the first module + will verify the credentials; and no access is passed on; + regardless of the AuthAuthoritative setting.

    + +

    A common use for this is in conjunction with one of the + auth providers; such as mod_authn_dbm or + mod_authn_file. Whereas this DBM module supplies + the bulk of the user credential checking; a few (administrator) related + accesses fall through to a lower level with a well protected + .htpasswd file.

    + +

    By default, control is not passed on and an unknown group + will result in an Authentication Required reply. Not + setting it thus keeps the system secure and forces an NCSA + compliant behaviour.

    + + Security +

    Do consider the implications of allowing a user to + allow fall-through in his .htaccess file; and verify that this + is really what you want; Generally it is easier to just secure + a single .htpasswd file, than it is to secure a + database which might have more access interfaces.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_dbm.xml.ko b/trunk/docs/manual/mod/mod_authz_dbm.xml.ko new file mode 100644 index 0000000000..25b90e553d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.xml.ko @@ -0,0 +1,153 @@ + + + + + + + + + +mod_authz_dbm +DBM ÆÄÀÏÀ» »ç¿ëÇÑ ±×·ì ÀÎÁõ +Extension +mod_authz_dbm.c +authz_dbm_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ÀÎÁõÇÑ »ç¿ëÀÚÀÇ ±×·ì±ÇÇÑÀ¸·Î À¥ÀÇ ÀϺθ¦ Á¢±ÙÇÒ + ¼ö ÀÖ´ÂÁö °áÁ¤ÇÏ¿© ±ÇÇѺο©¸¦ ÇÑ´Ù. + mod_authz_groupfile°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    +
    + +Require +Satisfy + + +AuthDBMGroupFile +ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù +AuthDBMGroupFile file-path +directory.htaccess + +AuthConfig + + +

    AuthDBMGroupFile Áö½Ã¾î´Â ÀÎÁõ¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â DBM ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. + File-path´Â ÆÄÀÏÀÇ Àý´ë°æ·ÎÀÌ´Ù.

    + +

    ÆÄÀÏÀº »ç¿ëÀÚ¸íÀ» Å°·Î »ç¿ëÇÑ´Ù. »ç¿ëÀÚ¿¡ ´ëÇÑ °ªÀº ½°Ç¥·Î + ±¸ºÐÇÑ »ç¿ëÀÚ°¡ ¼ÓÇÑ ±×·ì ¸ñ·ÏÀÌ´Ù. °ª¿¡ °ø¹éÀ̳ª ÄÝ·ÐÀ» + »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + + º¸¾È +

    AuthDBMGroupFileÀÌ À¥¼­¹öÀÇ + ¹®¼­µé ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 + ¾È¿¡ °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthDBMGroupFile¸¦ ´Ù¿î·ÎµåÇÒ ¼ö + ÀÖ´Ù.

    +
    + +

    ±×·ì DBM ÆÄÀÏ°ú ¾ÏÈ£ DBM ÆÄÀÏÀ» °°ÀÌ »ç¿ëÇϱâ: »ç¿ëÀÚ¿¡ + ´ëÇÑ ¾ÏÈ£¿Í ±×·ì Á¤º¸ ¸ðµÎ¸¦ ÇÑ µ¥ÀÌÅͺ£À̽º¿¡¼­ °ü¸®ÇÏ´Â + °ÍÀÌ ½¬¿ï¶§°¡ ÀÖ´Ù. ÀÌ °æ¿ì ÀÛ¼ºÇÒ Áö¿ø ÇÁ·Î±×·¥ÀÌ °£´ÜÇØÁø´Ù. + ÇÁ·Î±×·¥Àº ÇÑ DBM ÆÄÀϸ¸À» Àá±×°í ¾²¸é µÈ´Ù. ±×·ìÆÄÀÏ°ú + ¾ÏÈ£ÆÄÀÏÀ» °°Àº DBMÆÄÀÏ·Î ¼³Á¤ÇÏ¸é °¡´ÉÇÏ´Ù:

    + + + AuthDBMGroupFile /www/userbase
    + AuthDBMUserFile /www/userbase +
    + +

    ÀÌ ÅëÇÕ DBMÀÇ Å°´Â »ç¿ëÀÚ¸íÀÌ´Ù. °ªÀº ´ÙÀ½°ú °°´Ù

    + + + ÀÎÄÚµùµÈ ¾ÏÈ£ : ±×·ì ¸ñ·Ï [ : (¹«½Ã) ] + + +

    ¾ÏÈ£ ºÎºÐÀº Àü°ú °°ÀÌ ÀÎÄÚµùµÈ ¾ÏÈ£ÀÌ´Ù. ÄÝ·Ð µÚ¿¡ ½°Ç¥·Î + ±¸ºÐÇÑ ±×·ì ¸ñ·ÏÀÌ ³ª¿Â´Ù. ¶Ç ´Ù½Ã ÄÝ·Ð ´ÙÀ½¿¡ ´Ù¸¥ Á¤º¸¸¦ + ±â·ÏÇÒ ¼ö ÀÖ´Ù. ÀÌ ºÎºÐÀº ÀÎÁõ¸ðµâÀÌ ¹«½ÃÇÑ´Ù. + www.telescope.org´Â ÀÌ·¸°Ô ¾ÏÈ£ µ¥ÀÌÅͺ£À̽º¿Í ±×·ì + µ¥ÀÌÅͺ£À̽º¸¦ °°ÀÌ »ç¿ëÇÑ´Ù.

    +
    +
    + + +AuthzDBMType +¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù +AuthzDBMType default|SDBM|GDBM|NDBM|DB +AuthzDBMType default +directory.htaccess + +AuthConfig + + +

    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. + µ¥ÀÌÅͺ£À̽º Á¾·ù ±âº»°ªÀº ÄÄÆÄÀ϶§ Á¤ÇØÁø´Ù. »ç¿ëÇÒ ¼ö + ÀÖ´Â ´Ù¸¥ µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ùµµ ÄÄÆÄÀÏ ¼³Á¤¿¡ ´Þ·È´Ù.

    + +

    ¾ÏÈ£ÆÄÀÏÀ» ¸¸µç ÇÁ·Î±×·¥ÀÌ °°Àº Á¾·ùÀÇ µ¥ÀÌÅͺ£À̽º¸¦ + »ç¿ëÇϵµ·Ï ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    +
    +
    + + +AuthzDBMAuthoritative +±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthzDBMAuthoritative On|Off +AuthzDBMAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzDBMAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ ¾ÆÀ̵𿡠´ëÇÑ + ±×·ìÀÌ ¾ø´Â °æ¿ì ±×·ì ±ÇÇѺο©¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù. ÁöÁ¤ÇÑ ±×·ìÀÌ ÀÖ´Ù¸é + º¸Å붧¿Í °°ÀÌ °Ë»çÇÏ°í, ½ÇÆÐÇϸé ÀÎÁõ ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù.

    + +

    ±×·¡¼­ ¿©·¯ ¸ðµâÀÇ µ¥ÀÌÅͺ£À̽º¿¡ »ç¿ëÀÚ ¾ÆÀ̵𰡠Àְųª + À¯È¿ÇÑ Require Áö½Ã¾î¸¦ + ¿©·¯ ¸ðµâ¿¡ Àû¿ëÇϸé, ù¹ø° ¸ðµâÀÌ »ç¿ëÀÚ¸¦ °Ë»çÇÏ°í, + AuthAuthoritative ¼³Á¤°ú °ü°è¾øÀÌ + Á¢±ÙÀ» ³Ñ±âÁö¾Ê´Â´Ù.

    + +

    ÀϹÝÀûÀ¸·Î mod_authn_dbmÀ̳ª + mod_authn_file°ú °°Àº ÀÎÁõÁ¦°øÀÚ¿Í °°ÀÌ + »ç¿ëÇÑ´Ù. ´ë·®ÀÇ »ç¿ëÀÚ °Ë»ç¿¡ ´ëÇÑ °Ë»ç´Â DBM ¸ðµâÀ» + »ç¿ëÇÏÁö¸¸, ¼Ò¼ö(°ü¸®ÀÚ)¿¡ ´ëÇÑ °Ë»ç´Â Àß º¸È£µÈ + .htpasswd ÆÄÀÏ·Î ³Ñ±ä´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô + À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + + º¸¾È +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ°Ô µÇ´ÂÁö »ìÆ캸°í, + ÀÌ·± ÇൿÀ» Çã¿ëÇÒÁö °áÁ¤Ç϶ó. ÀϹÝÀûÀ¸·Î ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î + Á¢±ÙÇÒ ¼ö ÀÖ´Â µ¥ÀÌÅͺ£À̽º¸¦ º¸È£ÇÏ´Â °Íº¸´Ù ÇϳªÀÇ + .htpasswd ÆÄÀÏÀ» º¸È£ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_dbm.xml.meta b/trunk/docs/manual/mod/mod_authz_dbm.xml.meta new file mode 100644 index 0000000000..90320dfe0b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_dbm.xml.meta @@ -0,0 +1,12 @@ + + + + mod_authz_dbm + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_authz_default.html b/trunk/docs/manual/mod/mod_authz_default.html new file mode 100644 index 0000000000..612b1b6899 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.html @@ -0,0 +1,11 @@ +URI: mod_authz_default.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_default.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authz_default.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_default.html.en b/trunk/docs/manual/mod/mod_authz_default.html.en new file mode 100644 index 0000000000..f879464e2b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.html.en @@ -0,0 +1,80 @@ + + + +mod_authz_default - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_default

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Authorization fallback module
    Status:Base
    Module Identifier:authz_default_module
    Source File:mod_authz_default.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module is designed to be the fallback module, if you don't + have configured an authorization module like + mod_authz_user or mod_authz_groupfile. + It simply rejects any authorization request.

    +
    +

    Directives

    + +
    + +
    top
    +

    AuthzDefaultAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization is passed to lower level +modules
    Syntax:AuthzDefaultAuthoritative On|Off
    Default:AuthzDefaultAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authz_default
    +

    Setting the AuthzDefaultAuthoritative directive + explicitly to Off allows for authorization to be passed on + to lower level modules (as defined in the modules.c + files).

    + +

    Note

    +

    Normally there are no lower level modules, since + mod_authz_default is defined to be already on + a very low level. Therefore you should leave the value of + AuthzDefaultAuthoritative as default + (On).

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_default.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authz_default.html.ja.euc-jp new file mode 100644 index 0000000000..b6bb0e61cf --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.html.ja.euc-jp @@ -0,0 +1,79 @@ + + + +mod_authz_default - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authz_default

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¾µÇ§¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authz_default_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authz_default.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_authz_user ¤ä + mod_authz_groupfile ¤È¤¤¤Ã¤¿¾µÇ§¥â¥¸¥å¡¼¥ë¤ò + ÀßÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Î¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥â¥¸¥å¡¼¥ë¤È¤·¤ÆÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤É¤Î¤è¤¦¤Ê¾µÇ§¥ê¥¯¥¨¥¹¥È¤âñ¤ËµñÈݤ·¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    AuthzDefaultAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¾µÇ§¤¬Äã°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthzDefaultAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthzDefaultAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_default
    +

    AuthzDefaultAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÌÀ¼¨Åª¤Ë Off ¤ËÀßÄꤹ¤ë¤È + ǧ¾Ú¤ò¼¡¤Î (modules.c ¥Õ¥¡¥¤¥ë¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë) + Äã°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤ¹¤³¤È¤òµö²Ä¤·¤Þ¤¹¡£

    + +

    Ãí°Õ

    +

    mod_authz_default ¼«ÂΤ¬¤È¤Æ¤âÄ㤤 + ¥ì¥Ù¥ë¤È¤·¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢Ä̾ï¤Ï¤³¤ì¤è¤ê¤âÄ㼡¤Î + ¥â¥¸¥å¡¼¥ë¤Ï¸ºß¤·¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é + AuthDefaultAuthoritative ¤Ï¥Ç¥Õ¥©¥ë¥È + (On) ¤Î¤Þ¤Þ¤Ë¤·¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_default.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_default.html.ko.euc-kr new file mode 100644 index 0000000000..6df2e7aa8c --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.html.ko.euc-kr @@ -0,0 +1,78 @@ + + + +mod_authz_default - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_default

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÃÖÈÄ ±ÇÇѺο©¸ðµâ
    »óÅÂ:Base
    ¸ðµâ¸í:authz_default_module
    ¼Ò½ºÆÄÀÏ:mod_authz_default.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_authz_user³ª + mod_authz_groupfile¿Í °°Àº ±ÇÇѺο©¸ðµâÀ» + ¼³Á¤ÇÏÁö¾ÊÀº ÃÖÈÄÀÇ °æ¿ì ´ë½Å »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº ¸ðµç ±ÇÇѺο© + ¿äûÀ» °ÅºÎÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    AuthzDefaultAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthzDefaultAuthoritative On|Off
    ±âº»°ª:AuthzDefaultAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authz_default
    +

    AuthzDefaultAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ±ÇÇѺο©¸¦ ³Ñ°ÜÁØ´Ù.

    + +

    ÁÖÀÇ

    +

    mod_authz_default°¡ ÀÌ¹Ì ¸Å¿ì + Àú¼öÁØÀ¸·Î Á¤ÀǵÇÀֱ⠶§¹®¿¡ º¸Åë ´õ ³·Àº ¸ðµâÀÌ + ¾ø´Ù. ±×·¯¹Ç·Î + AuthzDefaultAuthoritative¸¦ + ±âº»°ª(On)À¸·Î ³²°ÜµÖ¾ß ÇÑ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_default.xml b/trunk/docs/manual/mod/mod_authz_default.xml new file mode 100644 index 0000000000..ba58eb5ff1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.xml @@ -0,0 +1,65 @@ + + + + + + + + + +mod_authz_default +Authorization fallback module +Base +mod_authz_default.c +authz_default_module +Available in Apache 2.1 and later + + +

    This module is designed to be the fallback module, if you don't + have configured an authorization module like + mod_authz_user or mod_authz_groupfile. + It simply rejects any authorization request.

    +
    + + +AuthzDefaultAuthoritative +Sets whether authorization is passed to lower level +modules +AuthzDefaultAuthoritative On|Off +AuthzDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthzDefaultAuthoritative directive + explicitly to Off allows for authorization to be passed on + to lower level modules (as defined in the modules.c + files).

    + + Note +

    Normally there are no lower level modules, since + mod_authz_default is defined to be already on + a very low level. Therefore you should leave the value of + AuthzDefaultAuthoritative as default + (On).

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_default.xml.ja b/trunk/docs/manual/mod/mod_authz_default.xml.ja new file mode 100644 index 0000000000..a29d25d620 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.xml.ja @@ -0,0 +1,64 @@ + + + + + + + + + +mod_authz_default +$B>5G'%U%)!<%k%P%C%/%b%8%e!<%k(B +Base +mod_authz_default.c +authz_default_module +Apache 2.1 $B0J9_(B + + +

    $B$3$N%b%8%e!<%k$O(B mod_authz_user $B$d(B + mod_authz_groupfile $B$H$$$C$?>5G'%b%8%e!<%k$r(B + $B@_Dj$7$J$+$C$?>l9g$N%U%)!<%k%P%C%/%b%8%e!<%k$H$7$F@_7W$5$l$F$$$^$9!#(B + $B$I$N$h$&$J>5G'%j%/%(%9%H$bC1$K5qH]$7$^$9!#(B

    +
    + + +AuthzDefaultAuthoritative +$B>5G'$,Dc0L$N%b%8%e!<%k$KEO$5$l$k$+$I$&$+$r@_Dj$9$k(B +AuthzDefaultAuthoritative On|Off +AuthzDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzDefaultAuthoritative $B%G%#%l%/%F%#%V$r(B + $BL@<(E*$K(B Off $B$K@_Dj$9$k$H(B + $BG'>Z$rmodules.c $B%U%!%$%k$GDj5A$5$l$F$$$k(B) + $BDc0L$N%b%8%e!<%k$KEO$9$3$H$r5v2D$7$^$9!#(B

    + + $BCm0U(B +

    mod_authz_default $B<+BN$,(B$B$H$F$bDc$$(B + $B%l%Y%k$H$7$FDj5A$5$l$F$$$^$9$N$G!"DL>o$O$3$l$h$j$bDcAuthDefaultAuthoritative $B$O%G%U%)%k%H(B + (On) $B$N$^$^$K$7$?$[$&$,NI$$$G$7$g$&!#(B

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_default.xml.ko b/trunk/docs/manual/mod/mod_authz_default.xml.ko new file mode 100644 index 0000000000..39a0e5528f --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.xml.ko @@ -0,0 +1,63 @@ + + + + + + + + + +mod_authz_default +ÃÖÈÄ ±ÇÇѺο©¸ðµâ +Base +mod_authz_default.c +authz_default_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº mod_authz_user³ª + mod_authz_groupfile¿Í °°Àº ±ÇÇѺο©¸ðµâÀ» + ¼³Á¤ÇÏÁö¾ÊÀº ÃÖÈÄÀÇ °æ¿ì ´ë½Å »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº ¸ðµç ±ÇÇѺο© + ¿äûÀ» °ÅºÎÇÑ´Ù.

    +
    + + +AuthzDefaultAuthoritative +±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthzDefaultAuthoritative On|Off +AuthzDefaultAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzDefaultAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ±ÇÇѺο©¸¦ ³Ñ°ÜÁØ´Ù.

    + + ÁÖÀÇ +

    mod_authz_default°¡ ÀÌ¹Ì ¸Å¿ì + Àú¼öÁØÀ¸·Î Á¤ÀǵÇÀֱ⠶§¹®¿¡ º¸Åë ´õ ³·Àº ¸ðµâÀÌ + ¾ø´Ù. ±×·¯¹Ç·Î + AuthzDefaultAuthoritative¸¦ + ±âº»°ª(On)À¸·Î ³²°ÜµÖ¾ß ÇÑ´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_default.xml.meta b/trunk/docs/manual/mod/mod_authz_default.xml.meta new file mode 100644 index 0000000000..ca7213c64d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_default.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authz_default + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.html b/trunk/docs/manual/mod/mod_authz_groupfile.html new file mode 100644 index 0000000000..eae1ea3510 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.html @@ -0,0 +1,11 @@ +URI: mod_authz_groupfile.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_groupfile.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authz_groupfile.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.html.en b/trunk/docs/manual/mod/mod_authz_groupfile.html.en new file mode 100644 index 0000000000..63dbe2bdac --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.html.en @@ -0,0 +1,125 @@ + + + +mod_authz_groupfile - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_groupfile

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Group authorization using plaintext files
    Status:Base
    Module Identifier:authz_groupfile_module
    Source File:mod_authz_groupfile.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site by group membership. Similar functionality is + provided by mod_authz_dbm.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    AuthGroupFile Directive

    + + + + + + + +
    Description:Sets the name of a text file containing the list +of user groups for authorization
    Syntax:AuthGroupFile file-path
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authz_groupfile
    +

    The AuthGroupFile directive sets the + name of a textual file containing the list of user groups for user + authorization. File-path is the path to the group + file. If it is not absolute, it is treated as relative to the ServerRoot.

    + +

    Each line of the group file contains a groupname followed by a + colon, followed by the member usernames separated by spaces.

    + +

    Example:

    + mygroup: bob joe anne +

    + +

    Note that searching large text files is very + inefficient; AuthDBMGroupFile provides a much better performance.

    + +

    Security

    +

    Make sure that the AuthGroupFile is + stored outside the document tree of the web-server; do not + put it in the directory that it protects. Otherwise, clients may + be able to download the AuthGroupFile.

    +
    + +
    +
    top
    +

    AuthzGroupFileAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization will be passed on to lower level +modules
    Syntax:AuthzGroupFileAuthoritative On|Off
    Default:AuthzGroupFileAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authz_groupfile
    +

    Setting the AuthzGroupFileAuthoritative + directive explicitly to Off allows for + group authorization to be passed on to lower level modules (as defined + in the modules.c files) if there is no + group matching the supplied userID.

    + +

    By default, control is not passed on and an unknown group + will result in an Authentication Required reply. Not + setting it thus keeps the system secure and forces an NCSA + compliant behaviour.

    + +

    Security

    +

    Do consider the implications of allowing a user to + allow fall-through in his .htaccess file; and verify + that this is really what you want; Generally it is easier to just + secure a single .htpasswd file, than it is to secure + a database which might have more access interfaces.

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authz_groupfile.html.ja.euc-jp new file mode 100644 index 0000000000..2c7a124339 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.html.ja.euc-jp @@ -0,0 +1,132 @@ + + + +mod_authz_groupfile - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authz_groupfile

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥×¥ì¡¼¥ó¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÍѤ¤¤¿¥°¥ë¡¼¥×¾µÇ§
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authz_groupfile_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authz_groupfile.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ïǧ¾Ú¤µ¤ì¤¿¥æ¡¼¥¶¤¬¥°¥ë¡¼¥×¤Î¥á¥ó¥Ð¡¼¤« + Èݤ«¤Ë¤è¤Ã¤Æ¥¦¥§¥Ö¥µ¥¤¥È¤Î°ìÉô¤Ø¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë¤«µñÈݤ¹¤ë¤«¤Î + ¾µÇ§µ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£Æ±Íͤε¡Ç½¤Ï mod_authz_dbm + ¤Ë¤è¤Ã¤Æ¤âÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    AuthGroupFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¾Úǧ¤Ë»ÈÍѤ¹¤ë¥æ¡¼¥¶¥°¥ë¡¼¥×¤Î°ìÍ÷¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ë¡¢ +¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthGroupFile file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_groupfile
    +

    AuthGroupFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¾Úǧ¤Ë»ÈÍѤ¹¤ë¥æ¡¼¥¶¥°¥ë¡¼¥×¤Î°ìÍ÷¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ë¡¢ + ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤷ¤Þ¤¹¡£ + file-path ¤Ï¥°¥ë¡¼¥×¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤Ç¤¹¡£ + ÀäÂХѥ¹¤Ç¤Ê¤±¤ì¤Ð¡¢ + ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    ¥°¥ë¡¼¥×¥Õ¥¡¥¤¥ë³Æ¹Ô¤Ï¡¢¥°¥ë¡¼¥×̾¡¢¥³¥í¥ó¡¢¤½¤·¤Æ + ¥¹¥Ú¡¼¥¹¶èÀÚ¤ê¤Ç¤½¤Î¥á¥ó¥Ð¡¼¤Î¥æ¡¼¥¶Ì¾¤òµ­½Ò¤·¤Þ¤¹¡£

    + +

    Îã:

    + mygroup: bob joe anne +

    + +

    Â礭¤Ê¥Õ¥¡¥¤¥ë¤òõº÷¤¹¤ë¤Î¤Ï¡¢Èó¾ï¤Ë¸úΨ¤¬°­¤¤¤È¤¤¤¦ÅÀ¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ï¡¢ + AuthDBMGroupFile + ¤ÎÊý¤¬¤º¤Ã¤ÈÎɤ¤À­Ç½¤òȯ´ø¤·¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    AuthGroupFile ¤Ï¡¢ + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Î³°Â¦¤Ë + Êݴɤ¹¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + Êݸ¤è¤¦¤È¤·¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Ë¤Ï¡¢ÃÖ¤«¤Ê¤¤¤Ç²¼¤µ¤¤¡£ + ¤½¤¦¤·¤Ê¤¤¤È¥¯¥é¥¤¥¢¥ó¥È¤¬ AuthGroupFile ¤ò + ¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Æ¤·¤Þ¤¦²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    AuthzGroupFileAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¾µÇ§¤¬²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthzGroupFileAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthzGroupFileAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_groupfile
    +

    AuthzGroupFileAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÌÀ¼¨Åª¤Ë Off ¤ËÀßÄꤹ¤ë¤È userID ¤ËÂбþ¤¹¤ë + ¥°¥ë¡¼¥×¤¬¤Ê¤¤¾ì¹ç¤Ë¡¢ + (module.c ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë) ²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤Ë¥°¥ë¡¼¥×¾µÇ§¤ò + ÅϤ¹¤³¤È¤òµö²Ä¤·¤Þ¤¹¡£

    + + +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏÀ©¸æ¤ÏÅϤµ¤ì¤º¡¢Ì¤ÃΤΥ°¥ë¡¼¥×¤Î¾ì¹ç¤Ï Authentication + Required ±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¤³¤ì¤òÀßÄꤷ¤Ê¤¤¤È + ¥·¥¹¥Æ¥à¤ò°ÂÁ´¤ËÊݤĤ³¤È¤¬¤Ç¤­¡¢NCSA ¸ß´¹¤Î¿¶¤ëÉñ¤¤¤ò¤µ¤»¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    ¥æ¡¼¥¶¤Î .htaccess ¥Õ¥¡¥¤¥ë¤Ç¾¤Î¾µÇ§¼êÃʤؤΠ+ °Ñ¾ù¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤Î°ÕÌ£¤¹¤ë¤È¤³¤í¤Ï½½Ê¬¤Ë¹Íθ¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£ + ¤½¤·¤Æ¤½¤ì¤¬¡¢ËÜÅö¤Ë˾¤àµóÆ°¤Ç¤¢¤ë¤³¤È¤ò³Î¤«¤á¤Æ¤¯¤À¤µ¤¤¡£ + Ä̾ï¤Ï°ì¤Ä¤Î .htpasswd ¥Õ¥¡¥¤¥ë¤ò°ÂÁ´¤Ë¤¹¤ëÊý¤¬ + ¤è¤ê¿¤¯¤Î¥¢¥¯¥»¥¹¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò»ý¤Ä¤«¤â¤·¤ì¤Ê¤¤¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò + °ÂÁ´¤Ë¤¹¤ë¤è¤ê¤â´Êñ¤Ç¤¹¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_groupfile.html.ko.euc-kr new file mode 100644 index 0000000000..fcfe067d8f --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.html.ko.euc-kr @@ -0,0 +1,121 @@ + + + +mod_authz_groupfile - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_groupfile

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÀÏ¹Ý ¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ ±×·ì ±ÇÇѺο©
    »óÅÂ:Base
    ¸ðµâ¸í:authz_groupfile_module
    ¼Ò½ºÆÄÀÏ:mod_authz_groupfile.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ÀÎÁõÇÑ »ç¿ëÀÚÀÇ ±×·ì±ÇÇÑÀ¸·Î À¥»çÀÌÆ®ÀÇ ÀϺθ¦ + Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö °áÁ¤ÇÏ¿© ±ÇÇѺο©¸¦ ÇÑ´Ù. + mod_authz_dbm°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthGroupFile Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:AuthGroupFile file-path
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authz_groupfile
    +

    AuthGroupFile Áö½Ã¾î´Â »ç¿ëÀÚ + ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» + ÁöÁ¤ÇÑ´Ù. File-path´Â ±×·ìÆÄÀÏ °æ·ÎÀÌ´Ù. Àý´ë°æ·Î¸¦ + »ç¿ëÇÏÁö ¾ÊÀ¸¸é ServerRootÀÇ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ.

    + +

    ±×·ìÆÄÀÏÀÇ °¢ ÁÙ¿¡´Â ±×·ì¸í, ÄÝ·Ð, °ø¹éÀ¸·Î ±¸ºÐÇÑ + »ç¿ëÀÚ¸íµéÀÌ ¼ø¼­´ë·Î ³ª¿Â´Ù.

    + +

    ¿¹Á¦:

    + mygroup: bob joe anne +

    + +

    ¸¹Àº ±×·ìÀ» ÀúÀåÇÑ Å« ¹®ÀÚÆÄÀÏÀ» °Ë»öÇÏ´Â °ÍÀº ¸Å¿ì + ºñÈ¿À²ÀûÀÓÀ» ÁÖÀÇÇ϶ó. AuthDBMGroupFileÀÌ ´õ ¼º´ÉÀÌ ÁÁ´Ù.

    + +

    º¸¾È

    +

    AuthGroupFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ + °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthGroupFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    +
    top
    +

    AuthzGroupFileAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthzGroupFileAuthoritative On|Off
    ±âº»°ª:AuthzGroupFileAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authz_groupfile
    +

    AuthzGroupFileAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ ¾ÆÀ̵𿡠´ëÇÑ + ±×·ìÀÌ ¾ø´Â °æ¿ì ±×·ì ±ÇÇѺο©¸¦ + (modules.c ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î + ³Ñ°ÜÁØ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô + À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + +

    º¸¾È

    +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ°Ô µÇ´ÂÁö »ìÆ캸°í, + ÀÌ·± ÇൿÀ» Çã¿ëÇÒÁö °áÁ¤Ç϶ó. ÀϹÝÀûÀ¸·Î ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î + Á¢±ÙÇÒ ¼ö ÀÖ´Â µ¥ÀÌÅͺ£À̽º¸¦ º¸È£ÇÏ´Â °Íº¸´Ù ÇϳªÀÇ + .htpasswd ÆÄÀÏÀ» º¸È£ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.xml b/trunk/docs/manual/mod/mod_authz_groupfile.xml new file mode 100644 index 0000000000..d3aed88d66 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.xml @@ -0,0 +1,110 @@ + + + + + + + + + +mod_authz_groupfile +Group authorization using plaintext files +Base +mod_authz_groupfile.c +authz_groupfile_module +Available in Apache 2.1 and later + + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site by group membership. Similar functionality is + provided by mod_authz_dbm.

    +
    + +Require +Satisfy + + +AuthGroupFile +Sets the name of a text file containing the list +of user groups for authorization +AuthGroupFile file-path +directory.htaccess + +AuthConfig + + +

    The AuthGroupFile directive sets the + name of a textual file containing the list of user groups for user + authorization. File-path is the path to the group + file. If it is not absolute, it is treated as relative to the ServerRoot.

    + +

    Each line of the group file contains a groupname followed by a + colon, followed by the member usernames separated by spaces.

    + + Example: + mygroup: bob joe anne + + +

    Note that searching large text files is very + inefficient; AuthDBMGroupFile provides a much better performance.

    + + Security +

    Make sure that the AuthGroupFile is + stored outside the document tree of the web-server; do not + put it in the directory that it protects. Otherwise, clients may + be able to download the AuthGroupFile.

    +
    +
    +
    + + +AuthzGroupFileAuthoritative +Sets whether authorization will be passed on to lower level +modules +AuthzGroupFileAuthoritative On|Off +AuthzGroupFileAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthzGroupFileAuthoritative + directive explicitly to Off allows for + group authorization to be passed on to lower level modules (as defined + in the modules.c files) if there is no + group matching the supplied userID.

    + +

    By default, control is not passed on and an unknown group + will result in an Authentication Required reply. Not + setting it thus keeps the system secure and forces an NCSA + compliant behaviour.

    + + Security +

    Do consider the implications of allowing a user to + allow fall-through in his .htaccess file; and verify + that this is really what you want; Generally it is easier to just + secure a single .htpasswd file, than it is to secure + a database which might have more access interfaces.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.xml.ja b/trunk/docs/manual/mod/mod_authz_groupfile.xml.ja new file mode 100644 index 0000000000..0c31db5069 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.xml.ja @@ -0,0 +1,115 @@ + + + + + + + + + +mod_authz_groupfile +$B%W%l!<%s%F%-%9%H%U%!%$%k$rMQ$$$?%0%k!<%W>5G'(B +Base +mod_authz_groupfile.c +authz_groupfile_module +Apache 2.1 $B0J9_(B + + +

    $B$3$N%b%8%e!<%k$OG'>Z$5$l$?%f!<%6$,%0%k!<%W$N%a%s%P!<$+(B + $BH]$+$K$h$C$F%&%'%V%5%$%H$N0lIt$X$N%"%/%;%9$r5v2D$9$k$+5qH]$9$k$+$N(B + $B>5G'5!G=$rDs6!$7$^$9!#F1MM$N5!G=$O(B mod_authz_dbm + $B$K$h$C$F$bDs6!$5$l$F$$$^$9!#(B

    +
    + +Require +Satisfy + + +AuthGroupFile +$B>ZG'$K;HMQ$9$k%f!<%6%0%k!<%W$N0lMw$,3JG<$5$l$F$$$k!"(B +$B%F%-%9%H%U%!%$%k$NL>A0$r@_Dj$9$k(B +AuthGroupFile file-path +directory.htaccess + +AuthConfig + + +

    AuthGroupFile $B%G%#%l%/%F%#%V$O!"(B + $B>ZG'$K;HMQ$9$k%f!<%6%0%k!<%W$N0lMw$,3JG<$5$l$F$$$k!"(B + $B%F%-%9%H%U%!%$%k$NL>A0$r@_Dj$7$^$9!#(B + file-path $B$O%0%k!<%W%U%!%$%k$X$N%Q%9$G$9!#(B + $B@dBP%Q%9$G$J$1$l$P!"(B + ServerRoot + $B$+$i$NAjBP%Q%9$H$7$F07$o$l$^$9!#(B

    + +

    $B%0%k!<%W%U%!%$%k3F9T$O!"%0%k!<%WL>!"%3%m%s!"$=$7$F(B + $B%9%Z!<%96h@Z$j$G$=$N%a%s%P!<$N%f!<%6L>$r5-=R$7$^$9!#(B

    + + $BNc(B: + mygroup: bob joe anne + + +

    $BBg$-$J%U%!%$%k$rC5:w$9$k$N$O!"(B$BHs>o$K(B$B8zN($,0-$$$H$$$&E@$K(B + $BCm0U$7$F$/$@$5$$!#$=$N$h$&$J>l9g$O!"(B + AuthDBMGroupFile + $B$NJ}$,$:$C$HNI$$@-G=$rH/4x$7$^$9!#(B

    + + $B%;%-%e%j%F%#(B +

    AuthGroupFile $B$O!"(B + $B%&%'%V%5!<%P$N%I%-%e%a%s%H%D%j!<$N30B&$K(B + $BJ]4I$9$k$h$&$K$7$F$/$@$5$$!#(B + $BJ]8n$7$h$&$H$7$F$$$k%G%#%l%/%H%j0J2<$K$O!"(B$BCV$+$J$$$G2<$5$$(B$B!#(B + $B$=$&$7$J$$$H%/%i%$%"%s%H$,(B AuthGroupFile $B$r(B + $B%@%&%s%m!<%I$G$-$F$7$^$&2DG=@-$,$"$j$^$9!#(B

    +
    +
    +
    + + +AuthzGroupFileAuthoritative +$B>5G'$,2<0L$N%b%8%e!<%k$KEO$5$l$k$+$I$&$+$r@_Dj$9$k(B +AuthzGroupFileAuthoritative On|Off +AuthzGroupFileAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzGroupFileAuthoritative $B%G%#%l%/%F%#%V$r(B + $BL@<(E*$K(B Off $B$K@_Dj$9$k$H(B userID $B$KBP1~$9$k(B + $B%0%k!<%W$,$J$$>l9g$K(B$B!"(B + (module.c $B$GDj5A$5$l$F$$$k(B) $B2<0L$N%b%8%e!<%k$K%0%k!<%W>5G'$r(B + $BEO$9$3$H$r5v2D$7$^$9!#(B

    + + +

    $B%G%U%)%k%H$G$O@)8f$OEO$5$l$:!"L$CN$N%0%k!<%W$N>l9g$O(B Authentication + Required $B1~Ez$,JV$5$l$^$9!#$G$9$+$i!"$3$l$r@_Dj$7$J$$$H(B + $B%7%9%F%`$r0BA4$KJ]$D$3$H$,$G$-!"(BNCSA $B8_49$N?6$kIq$$$r$5$;$k$3$H$K$J$j$^$9!#(B

    + + $B%;%-%e%j%F%#(B +

    $B%f!<%6$N(B .htaccess $B%U%!%$%k$GB>$N>5G'y$,$G$-$k$h$&$K$9$k$3$H$N0UL#$9$k$H$3$m$O==J,$K9MN8$7$F$*$$$F$/$@$5$$!#(B + $B$=$7$F$=$l$,!"K\Ev$KK>$`5sF0$G$"$k$3$H$r3N$+$a$F$/$@$5$$!#(B + $BDL>o$O0l$D$N(B .htpasswd $B%U%!%$%k$r0BA4$K$9$kJ}$,(B + $B$h$jB?$/$N%"%/%;%9%$%s%?%U%'!<%9$r;}$D$+$b$7$l$J$$%G!<%?%Y!<%9$r(B + $B0BA4$K$9$k$h$j$b4JC1$G$9!#(B

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.xml.ko b/trunk/docs/manual/mod/mod_authz_groupfile.xml.ko new file mode 100644 index 0000000000..50fdbf27c6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.xml.ko @@ -0,0 +1,106 @@ + + + + + + + + + +mod_authz_groupfile +ÀÏ¹Ý ¹®ÀÚÆÄÀÏÀ» ÀÌ¿ëÇÑ ±×·ì ±ÇÇѺο© +Base +mod_authz_groupfile.c +authz_groupfile_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ÀÎÁõÇÑ »ç¿ëÀÚÀÇ ±×·ì±ÇÇÑÀ¸·Î À¥»çÀÌÆ®ÀÇ ÀϺθ¦ + Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö °áÁ¤ÇÏ¿© ±ÇÇѺο©¸¦ ÇÑ´Ù. + mod_authz_dbm°ú ±â´ÉÀÌ ºñ½ÁÇÏ´Ù.

    +
    + +Require +Satisfy + + +AuthGroupFile +ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù +AuthGroupFile file-path +directory.htaccess + +AuthConfig + + +

    AuthGroupFile Áö½Ã¾î´Â »ç¿ëÀÚ + ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» + ÁöÁ¤ÇÑ´Ù. File-path´Â ±×·ìÆÄÀÏ °æ·ÎÀÌ´Ù. Àý´ë°æ·Î¸¦ + »ç¿ëÇÏÁö ¾ÊÀ¸¸é ServerRootÀÇ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ.

    + +

    ±×·ìÆÄÀÏÀÇ °¢ ÁÙ¿¡´Â ±×·ì¸í, ÄÝ·Ð, °ø¹éÀ¸·Î ±¸ºÐÇÑ + »ç¿ëÀÚ¸íµéÀÌ ¼ø¼­´ë·Î ³ª¿Â´Ù.

    + + ¿¹Á¦: + mygroup: bob joe anne + + +

    ¸¹Àº ±×·ìÀ» ÀúÀåÇÑ Å« ¹®ÀÚÆÄÀÏÀ» °Ë»öÇÏ´Â °ÍÀº ¸Å¿ì + ºñÈ¿À²ÀûÀÓÀ» ÁÖÀÇÇ϶ó. AuthDBMGroupFileÀÌ ´õ ¼º´ÉÀÌ ÁÁ´Ù.

    + + º¸¾È +

    AuthGroupFileÀÌ À¥¼­¹öÀÇ ¹®¼­µé + ¹Û¿¡ À§Ä¡ÇÔÀ» È®ÀÎÇ϶ó. ÀÌ ÆÄÀÏÀ» º¸È£ÇÒ µð·ºÅ丮 ¾È¿¡ + °°ÀÌ µÎÁö ¸¶¶ó. ±×·¸Áö ¾ÊÀ¸¸é, Ŭ¶óÀ̾ðÆ®°¡ + AuthGroupFileÀ» ´Ù¿î·ÎµåÇÒ ¼ö ÀÖ´Ù.

    +
    +
    +
    + + +AuthzGroupFileAuthoritative +±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthzGroupFileAuthoritative On|Off +AuthzGroupFileAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzGroupFileAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ ¾ÆÀ̵𿡠´ëÇÑ + ±×·ìÀÌ ¾ø´Â °æ¿ì ±×·ì ±ÇÇѺο©¸¦ + (modules.c ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î + ³Ñ°ÜÁØ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ ¼³Á¤ÇÏÁö¾ÊÀ¸¸é ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô + À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + + º¸¾È +

    »ç¿ëÀÚ°¡ ÀÚ½ÅÀÇ .htaccess ÆÄÀÏÀ» »ç¿ëÇÏ°Ô µÇ´ÂÁö »ìÆ캸°í, + ÀÌ·± ÇൿÀ» Çã¿ëÇÒÁö °áÁ¤Ç϶ó. ÀϹÝÀûÀ¸·Î ¿©·¯°¡Áö ¹æ¹ýÀ¸·Î + Á¢±ÙÇÒ ¼ö ÀÖ´Â µ¥ÀÌÅͺ£À̽º¸¦ º¸È£ÇÏ´Â °Íº¸´Ù ÇϳªÀÇ + .htpasswd ÆÄÀÏÀ» º¸È£ÇÏ´Â °ÍÀÌ ´õ ½±´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_groupfile.xml.meta b/trunk/docs/manual/mod/mod_authz_groupfile.xml.meta new file mode 100644 index 0000000000..148ddde160 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_groupfile.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authz_groupfile + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authz_host.html b/trunk/docs/manual/mod/mod_authz_host.html new file mode 100644 index 0000000000..fc883205f3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.html @@ -0,0 +1,11 @@ +URI: mod_authz_host.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_host.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authz_host.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_host.html.en b/trunk/docs/manual/mod/mod_authz_host.html.en new file mode 100644 index 0000000000..62f01c768f --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.html.en @@ -0,0 +1,333 @@ + + + +mod_authz_host - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_host

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Group authorizations based on host (name or IP +address)
    Status:Base
    Module Identifier:authz_host_module
    Source File:mod_authz_host.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    The directives provided by mod_authz_host are + used in <Directory>, + <Files>, and + <Location> sections + as well as .htaccess + files to control access to particular parts of the server. + Access can be controlled based on the client hostname, IP address, or + other characteristics of the client request, as captured in environment variables. The Allow and Deny directives are used to + specify which clients are or are not allowed access to the server, + while the Order + directive sets the default access state, and configures how the + Allow and Deny directives interact with each + other.

    + +

    Both host-based access restrictions and password-based + authentication may be implemented simultaneously. In that case, + the Satisfy directive is used + to determine how the two sets of restrictions interact.

    + +

    In general, access restriction directives apply to all + access methods (GET, PUT, + POST, etc). This is the desired behavior in most + cases. However, it is possible to restrict some methods, while + leaving other methods unrestricted, by enclosing the directives + in a <Limit> section.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    Allow Directive

    + + + + + + + +
    Description:Controls which hosts can access an area of the +server
    Syntax: Allow from all|host|env=env-variable +[host|env=env-variable] ...
    Context:directory, .htaccess
    Override:Limit
    Status:Base
    Module:mod_authz_host
    +

    The Allow directive affects which hosts can + access an area of the server. Access can be controlled by + hostname, IP Address, IP Address range, or by other + characteristics of the client request captured in environment + variables.

    + +

    The first argument to this directive is always + from. The subsequent arguments can take three + different forms. If Allow from all is specified, then + all hosts are allowed access, subject to the configuration of the + Deny and Order directives as discussed + below. To allow only particular hosts or groups of hosts to access + the server, the host can be specified in any of the + following formats:

    + +
    +
    A (partial) domain-name
    + +
    +

    Example:

    + Allow from apache.org
    + Allow from .net example.edu +

    +

    Hosts whose names match, or end in, this string are allowed + access. Only complete components are matched, so the above + example will match foo.apache.org but it will not + match fooapache.org. This configuration will cause + Apache to perform a double reverse DNS lookup on the client IP + address, regardless of the setting of the HostnameLookups directive. It will do + a reverse DNS lookup on the IP address to find the associated + hostname, and then do a forward lookup on the hostname to assure + that it matches the original IP address. Only if the forward + and reverse DNS are consistent and the hostname matches will + access be allowed.

    + +
    A full IP address
    + +
    +

    Example:

    + Allow from 10.1.2.3
    + Allow from 192.168.1.104 192.168.1.205 +

    +

    An IP address of a host allowed access

    + +
    A partial IP address
    + +
    +

    Example:

    + Allow from 10.1
    + Allow from 10 172.20 192.168.2 +

    +

    The first 1 to 3 bytes of an IP address, for subnet + restriction.

    + +
    A network/netmask pair
    + +
    +

    Example:

    + Allow from 10.1.0.0/255.255.0.0 +

    +

    A network a.b.c.d, and a netmask w.x.y.z. For more + fine-grained subnet restriction.

    + +
    A network/nnn CIDR specification
    + +
    +

    Example:

    + Allow from 10.1.0.0/16 +

    +

    Similar to the previous case, except the netmask consists of + nnn high-order 1 bits.

    +
    + +

    Note that the last three examples above match exactly the + same set of hosts.

    + +

    IPv6 addresses and IPv6 subnets can be specified as shown + below:

    + +

    + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +

    + +

    The third format of the arguments to the + Allow directive allows access to the server + to be controlled based on the existence of an environment variable. When Allow from + env=env-variable is specified, then the request is + allowed access if the environment variable env-variable + exists. The server provides the ability to set environment + variables in a flexible way based on characteristics of the client + request using the directives provided by + mod_setenvif. Therefore, this directive can be + used to allow access based on such factors as the clients + User-Agent (browser type), Referer, or + other HTTP request header fields.

    + +

    Example:

    + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +

    + +

    In this case, browsers with a user-agent string beginning + with KnockKnock/2.0 will be allowed access, and all + others will be denied.

    + +
    +
    top
    +

    Deny Directive

    + + + + + + + +
    Description:Controls which hosts are denied access to the +server
    Syntax: Deny from all|host|env=env-variable +[host|env=env-variable] ...
    Context:directory, .htaccess
    Override:Limit
    Status:Base
    Module:mod_authz_host
    +

    This directive allows access to the server to be restricted + based on hostname, IP address, or environment variables. The + arguments for the Deny directive are + identical to the arguments for the Allow directive.

    + +
    +
    top
    +

    Order Directive

    + + + + + + + + +
    Description:Controls the default access state and the order in which +Allow and Deny are +evaluated.
    Syntax: Order ordering
    Default:Order Deny,Allow
    Context:directory, .htaccess
    Override:Limit
    Status:Base
    Module:mod_authz_host
    +

    The Order directive controls the default + access state and the order in which Allow and Deny directives are evaluated. + Ordering is one of

    + +
    +
    Deny,Allow
    + +
    The Deny directives + are evaluated before the Allow directives. Access is + allowed by default. Any client which does not match a + Deny directive or does + match an Allow + directive will be allowed access to the server.
    + +
    Allow,Deny
    + +
    The Allow + directives are evaluated before the Deny directives. Access is denied + by default. Any client which does not match an Allow directive or does match a + Deny directive will be + denied access to the server.
    + +
    Mutual-failure
    + +
    Only those hosts which appear on the Allow list and do not appear on + the Deny list are + granted access. This ordering has the same effect as Order + Allow,Deny and is deprecated in favor of that + configuration.
    +
    + +

    Keywords may only be separated by a comma; no whitespace is + allowed between them. Note that in all cases every Allow and Deny statement is evaluated.

    + +

    In the following example, all hosts in the apache.org domain + are allowed access; all other hosts are denied access.

    + +

    + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +

    + +

    In the next example, all hosts in the apache.org domain are + allowed access, except for the hosts which are in the + foo.apache.org subdomain, who are denied access. All hosts not + in the apache.org domain are denied access because the default + state is to deny access to the server.

    + +

    + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +

    + +

    On the other hand, if the Order in the last + example is changed to Deny,Allow, all hosts will + be allowed access. This happens because, regardless of the + actual ordering of the directives in the configuration file, + the Allow from apache.org will be evaluated last + and will override the Deny from foo.apache.org. + All hosts not in the apache.org domain will also + be allowed access because the default state will change to + allow.

    + +

    The presence of an Order directive can affect + access to a part of the server even in the absence of accompanying + Allow and Deny directives because of its effect + on the default access state. For example,

    + +

    + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +

    + +

    will deny all access to the /www directory + because the default access state will be set to + deny.

    + +

    The Order directive controls the order of access + directive processing only within each phase of the server's + configuration processing. This implies, for example, that an + Allow or Deny directive occurring in a + <Location> section will + always be evaluated after an Allow or Deny directive occurring in a + <Directory> section or + .htaccess file, regardless of the setting of the + Order directive. For details on the merging + of configuration sections, see the documentation on How Directory, Location and Files sections + work.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_host.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authz_host.html.ja.euc-jp new file mode 100644 index 0000000000..b7047711ad --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.html.ja.euc-jp @@ -0,0 +1,347 @@ + + + +mod_authz_host - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authz_host

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥Û¥¹¥È (̾Á°¤â¤·¤¯¤Ï IP ¥¢¥É¥ì¥¹) ¤Ë´ð¤Å¤¤¤¿¥°¥ë¡¼¥×¾µÇ§
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authz_host_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authz_host.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    mod_authz_host ¤Ë¤è¤êÄ󶡤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥µ¡¼¥Ð¤ÎÆÃÄê¤ÎÉôʬ¤Ø¤Î + ¥¢¥¯¥»¥¹¤òÀ©¸æ¤¹¤ë¤¿¤á¤Ë <Directory>, <Files>, <Location> + ¤È .htaccess ¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¤Î¥Û¥¹¥È̾¡¢IP + ¥¢¥É¥ì¥¹¤ä ´Ä¶­ÊÑ¿ô¤È¤·¤Æ¼èÆÀ¤µ¤ì¤¿¡¢¤½¤Î¾¤Î¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤Ë´ð¤Å¤¤¤Æ + ¥¢¥¯¥»¥¹À©¸æ¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Allow ¤È + Deny ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¤É¤Î¤è¤¦¤Ê¥¯¥é¥¤¥¢¥ó¥È¤Ë¥¢¥¯¥»¥¹¤ò + µö²Ä¤¹¤ë¡¢¤·¤Ê¤¤¤«¤ò»ØÄꤹ¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£°ìÊý¡¢ + Order ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹¾õÂ֤ȡ¢ + Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤Î¤ª¸ß¤¤¤Ø¤Î±Æ¶Á¤Î»ÅÊý¤òÀßÄꤷ¤Þ¤¹¡£ +

    + +

    ¥Û¥¹¥È¤Ë¤è¤ë¥¢¥¯¥»¥¹À©¸Â¤È¥Ñ¥¹¥ï¡¼¥É¤Ë¤è¤ëǧ¾Ú¤òƱ»þ¤Ë + ¹Ô¤Ê¤¦¤³¤È¤¬²Äǽ¤Ç¤¹¡£¤½¤Î¾ì¹ç¡¢¤½¤ÎÆó¤Ä¤ÎÀ©¸Â¤Î´Ø·¸¤ò»ØÄꤹ¤ë¤¿¤á¤Ë + Satisfy + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Þ¤¹¡£

    + +

    °ìÈÌŪ¤Ë¤Ï¡¢¥¢¥¯¥»¥¹À©¸Â¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¹¤Ù¤Æ¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã¥É + (GET, PUT, POST ¤Ê¤É) + ¤ËŬÍѤµ¤ì¤Þ¤¹¡£¤½¤·¤Æ¡¢¤Û¤È¤ó¤É¤Î¾ì¹ç¤³¤ì¤¬Ë¾¤Þ¤·¤¤Æ°ºî¤Ç¤¹¡£ + ¤·¤«¤·¡¢<Limit> + ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤Ç¡¢ + °ìÉô¤Î¥á¥½¥Ã¥É¤Ë¤Î¤ßÀ©¸Â¤ò¤«¤±¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤Î¤¢¤ëÎΰè¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¥Û¥¹¥È¤òÀ©¸æ¤¹¤ë
    ¹½Ê¸: Allow from all|host|env=env-variable +[host|env=env-variable] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Limit
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_host
    +

    Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤É¤Î¥Û¥¹¥È¤¬ + ¥µ¡¼¥Ð¤Î¤¢¤ëÎΰè¤ò¥¢¥¯¥»¥¹¤Ç¤­¤ë¤«¤Ë±Æ¶Á¤òÍ¿¤¨¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹¤Ï¥Û¥¹¥È̾¡¢IP ¥¢¥É¥ì¥¹¡¢IP ¥¢¥É¥ì¥¹¤ÎÈϰϤ䡢 + ´Ä¶­ÊÑ¿ô¤È¤·¤Æ¼èÆÀ¤µ¤ì¤¿¡¢¤½¤Î¾¤Î¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤Î + ÆÃħ¤Ë¤è¤Ã¤ÆÀ©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎºÇ½é¤Î°ú¿ô¤Ï¾ï¤Ë from ¤Ç¤¹¡£ + ¤½¤ì¤Ë³¤¯°ú¿ô¤Ï»°¤Ä¤Î°ã¤Ã¤¿·Á¼°¤¬¤¢¤ê¤Þ¤¹¡£Allow from + all ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤Ë¥¢¥¯¥»¥¹¤òµö²Ä¤·¡¢ + ¥¢¥¯¥»¥¹À©¸Â¤Ï²¼¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢ + Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È Order + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤Ç·è¤Þ¤ê¤Þ¤¹¡£ + ÆÃÄê¤Î¥Û¥¹¥È¤ä¥Û¥¹¥È·²¤Ë¤Î¤ß¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + °Ê²¼¤Î¤É¤ì¤«¤Î·Á¼°¤Ç host ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    ¥É¥á¥¤¥ó̾ (¤Î°ìÉô)
    + +
    +

    Îã

    + Allow from apache.org
    + Allow from .net example.edu +

    +

    ¤³¤Îʸ»úÎó¤Ë¹ç¤¦¤«¡¢¤³¤ì¤Ç½ª¤ï¤ë̾Á°¤Î¥Û¥¹¥È¤Î¥¢¥¯¥»¥¹¤¬µö²Ä¤µ¤ì¤Þ¤¹¡£ + ³ÆÉôʬ¤¬´°Á´¤Ë¹ç¤¦¤â¤Î¤À¤±¤ËŬÍѤµ¤ì¤Þ¤¹¤Î¤Ç¡¢¾å¤ÎÎã¤Ï + foo.apache.org ¤Ë¤Ï¥Þ¥Ã¥Á¤·¤Þ¤¹¤¬¡¢ + fooapache.org ¤Ë¤Ï¥Þ¥Ã¥Á¤·¤Þ¤»¤ó¡£ + ¤³¤ÎÀßÄê¤ò¤¹¤ë¤È¡¢Apache ¤Ï + HostnameLookups + ¤ÎÀßÄê¤Ë´Ø¤ï¤é¤º¡¢¥¯¥é¥¤¥¢¥ó¥È¤Î IP ¥¢¥É¥ì¥¹¤ËÂФ·¤Æ + DNS ¤Î 2 ½ÅµÕ°ú¤­¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ¥Û¥¹¥È̾¤«¤é¥ª¥ê¥¸¥Ê¥ë¤Î IP ¥¢¥É¥ì¥¹¤ò½ç°ú¤­¤·¤Þ¤¹¡£ + ½ç°ú¤­¤ÈµÕ°ú¤­¤¬°ìÃפ·¡¢¥Û¥¹¥È̾¤¬³ºÅö¤·¤¿¾ì¹ç¤Ë¤Î¤ß¡¢ + ¥¢¥¯¥»¥¹¤¬µö²Ä¤µ¤ì¤Þ¤¹¡£

    + +
    ´°Á´¤Ê IP ¥¢¥É¥ì¥¹
    + +
    +

    Îã

    + Allow from 10.1.2.3
    + Allow from 192.168.1.104 192.168.1.205 +

    +

    ¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë IP ¥¢¥É¥ì¥¹¤Ç¤¹¡£

    + +
    IP ¥¢¥É¥ì¥¹¤Î°ìÉô
    + +
    +

    Îã

    + Allow from 10.1
    + Allow from 10 172.20 192.168.2 +

    +

    ¥µ¥Ö¥Í¥Ã¥È¤ÎÀ©¸ÂÍѤΡ¢IP + ¥¢¥É¥ì¥¹¤ÎºÇ½é¤Î°ì¤Ä¤«¤é»°¤Ä¤Þ¤Ç¤Î¥Ð¥¤¥È¤Ç¤¹¡£

    + +
    ¥Í¥Ã¥È¥ï¡¼¥¯/¥Í¥Ã¥È¥Þ¥¹¥¯ ¤ÎÂÐ
    + +
    +

    Îã

    + Allow from 10.1.0.0/255.255.0.0 +

    +

    ¥Í¥Ã¥È¥ï¡¼¥¯ a.b.c.d ¤È¥Í¥Ã¥È¥Þ¥¹¥¯ w.x.y.z ¤Ç¤¹¡£ + ¤è¤êºÙγÅ٤Υµ¥Ö¥Í¥Ã¥ÈÀ©¸ÂÍѤǤ¹¡£

    + +
    ¥Í¥Ã¥È¥ï¡¼¥¯/nnn CIDR »ØÄê
    + +
    +

    Îã

    + Allow from 10.1.0.0/16 +

    +

    ¥Í¥Ã¥È¥Þ¥¹¥¯¤¬ nnn ¤Î¾å°Ì¥Ó¥Ã¥È¤¬ 1 + ¤È¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î¤«¤é¤Ê¤ë¤³¤È°Ê³°¤ÏÁ°¤Î¤â¤Î¤ÈƱ¤¸¤Ç¤¹¡£

    +
    + +

    Ãí: ºÇ¸å¤Î»°¤Ä¤ÎÎã¤Ï¤Þ¤Ã¤¿¤¯Æ±¤¸¥Û¥¹¥È¤Ë¹ç¤¤¤Þ¤¹¡£

    + + +

    IPv6 ¥¢¥É¥ì¥¹¤È IPv6 ¤Î¥µ¥Ö¥Í¥Ã¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë»ØÄê¤Ç¤­¤Þ¤¹:

    + +

    + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +

    + +

    Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤Î»°¤ÄÌܤηÁ¼°¤Ï¡¢ + ´Ä¶­ÊÑ¿ô + ¤Î¸ºß¤Ë¤è¤ê¥¢¥¯¥»¥¹¤ÎÀ©¸æ¤ò¹Ô¤Ê¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤â¤Î¤Ç¤¹¡£ + Allow from env=env-variable + ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢´Ä¶­ÊÑ¿ô env-variable + ¤¬Â¸ºß¤·¤¿¾ì¹ç¤Ë¥ê¥¯¥¨¥¹¥È¤Ï¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£¥µ¡¼¥Ð¤Ï + mod_setenvif + ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È + ¤ÎÆÃħ¤Ë´ð¤Å¤¤¤Æ½ÀÆð¤Ë´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î + User-Agent (¥Ö¥é¥¦¥¶¤Î¼ïÎà)¡¢Referer + ¤ä¾¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Ê¤É¤Ë´ð¤Å¤¤¤Æ + ¥¢¥¯¥»¥¹µö²Ä¤ò¤¹¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    + +

    Example:

    + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +

    + +

    ¤³¤Î¾ì¹ç¡¢user-agent ¤Îʸ»úÎó¤¬ KnockKnock/2.0 + ¤Ç»Ï¤Þ¤ë¥Ö¥é¥¦¥¶¤Î¤ß¤¬¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¡¢ + ¾¤Î¤â¤Î¤Ï¥¢¥¯¥»¥¹¤òµñÈݤµ¤ì¤Þ¤¹¡£

    + + +
    +
    top
    +

    Deny ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¥¢¥¯¥»¥¹¤òµñÈݤ¹¤ë¥Û¥¹¥È¤òÀ©¸æ¤¹¤ë
    ¹½Ê¸: Deny from all|host|env=env-variable +[host|env=env-variable] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Limit
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_host
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Û¥¹¥È̾¡¢IP + ¥¢¥É¥ì¥¹¡¢´Ä¶­ÊÑ¿ô¤Ë´ð¤Å¤¤¤Æ¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹¤òÀ©¸Â¤·¤Þ¤¹¡£ + Deny ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤Ï Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤Ç¤¹¡£

    + +
    +
    top
    +

    Order ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹²Äǽ¤Ê¾õÂ֤ȡ¢Allow ¤È +Deny ¤¬É¾²Á¤µ¤ì¤ë½çÈÖ¤òÀ©¸æ¤¹¤ë
    ¹½Ê¸: Order ordering
    ¥Ç¥Õ¥©¥ë¥È:Order Deny,Allow
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Limit
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_host
    +

    Order ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹¤Î¾õÂÖ¤È + Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬É¾²Á¤µ¤ì¤ë½çÈÖ¤òÀ©¸æ¤·¤Þ¤¹¡£ + Ordering ¤Ï°Ê²¼¤Î¤É¤ì¤«¤Ç¤¹¡£

    + +
    +
    Deny,Allow
    + +
    Deny ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÁ°¤Ëɾ²Á¤µ¤ì¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹¤Ï¥Ç¥Õ¥©¥ë¥È¤Çµö²Ä¤µ¤ì¤Þ¤¹¡£Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¹ç¤ï¤Ê¤¤¤«¡¢Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¹ç¤¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£
    + +
    Allow,Deny
    + +
    Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÁ°¤Ëɾ²Á¤µ¤ì¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇµñÈݤµ¤ì¤Þ¤¹¡£Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¹ç¤ï¤Ê¤¤¤«¡¢Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¹ç¤¦¥¯¥é¥¤¥¢¥ó¥È¤Ï¥¢¥¯¥»¥¹¤òµñÈݤµ¤ì¤Þ¤¹¡£ +
    + +
    Mutual-failure
    + +
    Allow ¤Î¥ê¥¹¥È¤Ë¸½¤ì¤Æ¡¢ + Deny + ¤Î¥ê¥¹¥È¤Ë¸½¤ì¤Ê¤¤¥Û¥¹¥È¤Î¤ß¤¬¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î½çÈÖÉÕ¤±¤Ï Order Allow,Deny ¤ÈƱ¤¸¸ú²Ì¤ò»ý¤Á¡¢ + ¤½¤ÎÀßÄê¤ÎÊý¤¬¹¥¤Þ¤·¤¤¤¿¤á¤ËÈó¿ä¾©¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
    +
    + +

    ¥­¡¼¥ï¡¼¥É¤Ï¥³¥ó¥Þ¤ÇʬΥ¤¹¤ë¤³¤È¤À¤±¤¬²Äǽ¤Ç¤¹¡£ + ´Ö¤Ë¶õÇò¤¬¤¢¤Ã¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£¤É¤Î¾ì¹ç¤Ç¤â¡¢Allow ¤È + Deny ʸ¤Ï + Á´¤Æɾ²Á¤µ¤ì¤ë¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ +

    + +

    °Ê²¼¤ÎÎã¤Ç¤Ï¡¢apache.org + ¥É¥á¥¤¥ó¤Î¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤Ï¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ + ¾¤Î¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤Ï¥¢¥¯¥»¥¹¤òµñÈݤµ¤ì¤Þ¤¹¡£

    + +

    + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +

    + +

    ¼¡¤ÎÎã¤Ç¤Ï¡¢foo.apache.org ¥µ¥Ö¥É¥á¥¤¥ó¤Ë¤¢¤ë¥Û¥¹¥È°Ê³°¤Î¡¢ + apache.org ¥É¥á¥¤¥ó¤Î¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤¬¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ + apache.org + ¥É¥á¥¤¥ó¤Ç¤Ê¤¤¥Û¥¹¥È¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Î¾õÂÖ¤¬¥¢¥¯¥»¥¹µñÈݤΤ¿¤á¡¢ + ¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹¤òµñÈݤµ¤ì¤Þ¤¹¡£

    + +

    + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +

    + +

    °ìÊý¡¢¾å¤ÎÎã¤Î Order ¤¬ Deny,Allow + ¤ËÊѤï¤Ã¤Æ¤¤¤ì¤Ð¡¢¤¹¤Ù¤Î¥Û¥¹¥È¤Ë¥¢¥¯¥»¥¹¤¬µö²Ä¤µ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î¼ÂºÝ¤Î½çÈ֤˴ؤï¤é¤º¡¢ + Allow from apache.org ¤¬ºÇ¸å¤Ëɾ²Á¤µ¤ì¤Æ¡¢ + Deny from foo.apache.org ¤ò¾å½ñ¤­¤¹¤ë¤«¤é¤Ç¤¹¡£ + apache.org + ¥É¥á¥¤¥ó¤Ë¤Ê¤¤¥Û¥¹¥È¤â¡¢¥Ç¥Õ¥©¥ë¥È¤Î¾õÂÖ¤¬ allow + ¤ËÊѲ½¤¹¤ë¤¿¤á¤Ë¡¢¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ +

    + +

    Order + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹¤Î¾õÂ֤˱ƶÁ¤òÍ¿¤¨¤ë¤Î¤Ç¡¢ + Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Ìµ¤¯¤Æ¤â¡¢¥µ¡¼¥Ð¤Î¥¢¥¯¥»¥¹¤Ë±Æ¶Á¤òÍ¿¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢

    + +

    + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +

    + +

    ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹¾õÂÖ¤¬ deny ¤Ë¤Ê¤ë¤¿¤á¡¢ + /www ¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¤¹¤Ù¤Æ¤Î¥¢¥¯¥»¥¹¤òµñÈݤ·¤Þ¤¹¡£ +

    + +

    Order + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥Ð¤ÎÀßÄê½èÍý¤Î³ÆÃʳ¬¤Ç¤À¤± + ¥¢¥¯¥»¥¹¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î½èÍý¤Î½çÈÖ¤òÊѹ¹¤·¤Þ¤¹¡£¤³¤ì¤Ï¡¢¤¿¤È¤¨¤Ð¡¢ + Order ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤Ë´Ø¤ï¤é¤º¡¢ + <Location> ¥»¥¯¥·¥ç¥ó¤Î + Allow ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + Deny ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + Directory ¥»¥¯¥·¥ç¥ó¤ä + .htaccess ¥Õ¥¡¥¤¥ë¤Î Allow + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä Deny + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤è¤ê¤â¾ï¤Ë¸å¤Ëɾ²Á¤µ¤ì¤ë¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + ÀßÄꥻ¥¯¥·¥ç¥ó¤Î¥Þ¡¼¥¸¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢ + Directory,Location, Files + ¥»¥¯¥·¥ç¥ó¤ÎÆ°ºîÊýË¡ ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_host.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_host.html.ko.euc-kr new file mode 100644 index 0000000000..e765732648 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.html.ko.euc-kr @@ -0,0 +1,310 @@ + + + +mod_authz_host - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_host

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:È£½ºÆ® (À̸§À̳ª IP ÁÖ¼Ò)¸¦ »ç¿ëÇÑ ±×·ì ±ÇÇѺο©
    »óÅÂ:Base
    ¸ðµâ¸í:authz_host_module
    ¼Ò½ºÆÄÀÏ:mod_authz_host.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    <Directory>, + <Files>, + <Location> + ¼½¼Ç°ú .htaccess + ÆÄÀÏ¿¡¼­ ¼­¹öÀÇ Æ¯Á¤ ºÎºÐÀÇ Á¢±ÙÀ» Á¦¾îÇϱâÀ§ÇØ + mod_authz_host°¡ Á¦°øÇÏ´Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®ÀÇ È£½ºÆ®¸í, IP ÁÖ¼Ò, ȯ°æº¯¼ö¿¡ ±â·ÏµÈ ¿äûÀÇ Æ¯¼º¿¡ µû¶ó + Á¢±ÙÀ» Á¦¾îÇÑ´Ù. Allow¿Í Deny Áö½Ã¾î´Â ¾î¶² + Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö¸¦ Áö½ÃÇÏ°í, Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î + Á¢±ÙÀ» Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í ¾î¶»°Ô Allow Áö½Ã¾î¿Í Deny Áö½Ã¾î°¡ ¼­·Î ¿µÇâÀ» + ¹ÌÄ¡´ÂÁö °áÁ¤ÇÑ´Ù.

    + +

    È£½ºÆ®±â¹Ý Á¢±ÙÁ¦ÇÑ°ú ¾ÏÈ£±â¹Ý ÀÎÁõÀ» µ¿½Ã¿¡ »ç¿ëÇÒ ¼öµµ + ÀÖ´Ù. ÀÌ °æ¿ì Satisfy + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¾î¶»°Ô µÎ Á¦ÇÑÀÌ ¼­·Î ¿µÇâÀ» ¹ÌÄ¡´ÂÁö + °áÁ¤ÇÑ´Ù.

    + +

    ÀϹÝÀûÀ¸·Î Á¢±ÙÁ¦ÇÑ Áö½Ã¾î´Â (GET, + PUT, POST µî) ¸ðµç ¸Þ¼­µå¿¡ Àû¿ëµÇ¸ç, + ÀÌ ÇൿÀº ´ëºÎºÐÀÇ °æ¿ì ¹Ù¶÷Á÷ÇÏ´Ù. ±×·¯³ª <Limit> ¼½¼Ç¾È¿¡ + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ƯÁ¤ ¸Þ¼­µå¿¡¸¸ Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    Allow Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¼­¹öÀÇ ÀϺο¡ Á¢±ÙÇÒ ¼ö Àִ ȣ½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù
    ¹®¹ý: Allow from all|host|env=env-variable +[host|env=env-variable] ...
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:Limit
    »óÅÂ:Base
    ¸ðµâ:mod_authz_host
    +

    Allow Áö½Ã¾î´Â ¾î¶² È£½ºÆ®°¡ ¼­¹öÀÇ + ÀϺο¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö Áö½ÃÇÑ´Ù. È£½ºÆ®¸í, IP ÁÖ¼Ò, IP + ÁÖ¼Ò¿µ¿ª, ȯ°æº¯¼ö¿¡ ±â·ÏµÈ ´Ù¸¥ Ư¼º¿¡ µû¶ó Á¢±ÙÀ» Á¶ÀýÇÒ + ¼ö ÀÖ´Ù.

    + +

    ÀÌ Áö½Ã¾îÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â Ç×»ó fromÀÌ´Ù. + ´ÙÀ½ ¾Æ±Ô¸ÕÆ®¿¡´Â ¼¼°¡Áö Çü½ÄÀÌ ÀÖ´Ù. Allow from allÀ» + »ç¿ëÇϸé, ¾Æ·¡¿¡¼­ ¼³¸íÇÒ Deny¿Í Order Áö½Ã¾î ¼³Á¤¿¡ + µû¶ó ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀ» Çã°¡ÇÑ´Ù. ƯÁ¤ È£½ºÆ®¸¸ ¼­¹ö·Î + Á¢±ÙÀ» Çã¿ëÇÏ·Á¸é ´ÙÀ½°ú °°Àº Çü½ÄÀ¸·Î host¸¦ Áö½ÃÇÒ + ¼ö ÀÖ´Ù:

    + +
    +
    È£½ºÆ®¸í (ÀϺÎ)
    + +
    +

    ¿¹Á¦:

    + Allow from apache.org +

    +

    È£½ºÆ®¸íÀÌ ÀÌ ¹®ÀÚ¿­°ú °°°Å³ª ÀÌ ¹®ÀÚ¿­·Î ³¡³ª¸é Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±×·¡¼­ ÀÌ °æ¿ì foo.apache.org´Â + ÇØ´çµÇ°í, fooapache.org´Â ÇØ´çµÇÁö ¾Ê´Â´Ù. + ÀÌ ¼³Á¤À» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â HostnameLookups Áö½Ã¾î ¼³Á¤°ú + °ü°è¾øÀÌ Å¬¶óÀ̾ðÆ® IP ÁÖ¼Ò¸¦ °¡Áö°í Áߺ¹-¿ª DNS °Ë»öÀ» + ÇÑ´Ù. Áï, È£½ºÆ®¸íÀ» ã±âÀ§ÇØ IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÀ» ÇÑ + ÈÄ, ´Ù½Ã È£½ºÆ®¸íÀ¸·Î °Ë»öÇÏ¿© ¿ø·¡ IP ÁÖ¼Ò¿Í ÀÏÄ¡ÇÏ´ÂÁö + È®ÀÎÇÑ´Ù. °á°ú°¡ °°°í È£½ºÆ®¸íÀÌ ¼³Á¤°ª¿¡ ÇØ´çÇϸé, Á¢±ÙÀ» + Çã¿ëÇÑ´Ù.

    + +
    IP ÁÖ¼Ò Àüü
    + +
    +

    ¿¹Á¦:

    + Allow from 10.1.2.3 +

    +

    Á¢±ÙÀ» Çã°¡Çϴ ȣ½ºÆ®ÀÇ IP ÁÖ¼Ò

    + +
    IP ÁÖ¼Ò ÀϺÎ
    + +
    +

    ¿¹Á¦:

    + Allow from 10.1 +

    +

    ¼­ºê³×Æ®¿öÅ©·Î Á¦ÇÑÇϱâÀ§ÇØ IP ÁÖ¼Ò ¾ÕÀÇ 1¿¡¼­ 3 + ¹ÙÀÌÆ®.

    + +
    ³×Æ®¿öÅ©/³Ý¸Å½ºÅ© ½Ö
    + +
    +

    ¿¹Á¦:

    + Allow from 10.1.0.0/255.255.0.0 +

    +

    ³×Æ®¿öÅ© a.b.c.d¿Í ³Ý¸Å½ºÅ© w.x.y.z. ´õ ¼¼¹ÐÇÏ°Ô + ¼­ºê³×Æ®¿öÅ©·Î Á¦ÇÑÇÒ¶§ »ç¿ëÇÑ´Ù.

    + +
    ³×Æ®¿öÅ©/nnn CIDR ±Ô¾à
    + +
    +

    ¿¹Á¦:

    + Allow from 10.1.0.0/16 +

    +

    ¾ÕÀÇ °æ¿ì¿Í °°Áö¸¸, »óÀ§ nnn°³ ºñÆ® °ªÀÌ 1ÀÎ ³Ý¸Å½ºÅ©¸¦ + »ç¿ëÇÑ´Ù.

    +
    + +

    ¸¶Áö¸· ¼¼°¡Áö ¿¹´Â Á¤È®È÷ µ¿ÀÏÇÑ È£½ºÆ®µéÀ» ÁöĪÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ IPv6 ÁÖ¼Ò¿Í IPv6 ¼­ºê³×Æ®¿öÅ©¸¦ ÁöÁ¤ÇÒ ¼öµµ + ÀÖ´Ù:

    + +

    + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +

    + +

    Allow Áö½Ã¾î ¾Æ±Ô¸ÕÆ®ÀÇ ¼¼¹ø° + Çü½ÄÀº ȯ°æº¯¼ö À¯¹«¿¡ µû¶ó Á¢±ÙÀ» + Á¦¾îÇÑ´Ù. Allow from env=env-variableÀ» + »ç¿ëÇϸé, env-variable ȯ°æº¯¼ö°¡ Á¤ÀÇµÈ °æ¿ì + Á¢±ÙÀ» Çã°¡ÇÑ´Ù. mod_setenvif°¡ Á¦°øÇÏ´Â + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Ŭ¶óÀ̾ðÆ® ¿äûÀÇ Æ¯¼º¿¡ µû¶ó ÀÚÀ¯·Ó°Ô + ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×·¯¹Ç·Î ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + Ŭ¶óÀ̾ðÆ® User-Agent (ºê¶ó¿ìÀú Á¾·ù), + Referer, ´Ù¸¥ HTTP ¿äû Çì´õ¿¡ µû¶ó Á¢±ÙÀ» + Çã°¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦:

    + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +

    + +

    ÀÌ °æ¿ì user-agent ¹®ÀÚ¿­ÀÌ KnockKnock/2.0À¸·Î + ½ÃÀÛÇÏ´Â ºê¶ó¿ìÀúÀÇ Á¢±ÙÀº Çã¿ëÇÏ°í, ³ª¸ÓÁö´Â ¸ðµÎ °ÅºÎÇÑ´Ù.

    + +
    +
    top
    +

    Deny Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¼­¹ö Á¢±ÙÀ» °ÅºÎÇÒ È£½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù
    ¹®¹ý: Deny from all|host|env=env-variable +[host|env=env-variable] ...
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:Limit
    »óÅÂ:Base
    ¸ðµâ:mod_authz_host
    +

    ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© È£½ºÆ®¸í, IP ÁÖ¼Ò, ȯ°æº¯¼ö¿¡ µû¶ó + ¼­¹ö Á¢±ÙÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. Deny + Áö½Ã¾îÀÇ ¾Æ±Ô¸ÕÆ®´Â Allow Áö½Ã¾î¿Í µ¿ÀÏÇÏ´Ù.

    + +
    +
    top
    +

    Order Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í +Allow¿Í Deny +󸮼ø¼­¸¦ Á¤ÇÑ´Ù.
    ¹®¹ý: Order ordering
    ±âº»°ª:Order Deny,Allow
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:Limit
    »óÅÂ:Base
    ¸ðµâ:mod_authz_host
    +

    Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» + Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í Allow¿Í Deny Áö½Ã¾î 󸮼ø¼­¸¦ + Á¤ÇÑ´Ù. orderingÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù

    + +
    +
    Deny,Allow
    + +
    Deny + Áö½Ã¾î¸¦ Allow + Áö½Ã¾î º¸´Ù ¸ÕÀú »ìÆ캻´Ù. ±×¸®°í ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÑ´Ù. + Deny³ª + Allow Áö½Ã¾î¿¡ + ÇØ´çµÇÁö ¾Ê´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» Çã¿ëÇÑ´Ù.
    + +
    Allow,Deny
    + +
    Allow + Áö½Ã¾î¸¦ Deny Áö½Ã¾î º¸´Ù ¸ÕÀú + »ìÆ캻´Ù. ±×¸®°í ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù. + Deny³ª + Allow Áö½Ã¾î¿¡ + ÇØ´çµÇÁö ¾Ê´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» °ÅºÎÇÑ´Ù.
    + +
    Mutual-failure
    + +
    Deny + ¸ñ·Ï¿¡´Â ¾È³ª¿À°í Allow ¸ñ·Ï¿¡¸¸ ³ª¿À´Â + È£½ºÆ®¸¸ Á¢±ÙÀ» Çã¿ëÇÑ´Ù. Order Allow,Deny¿Í + °°Àº ÀÏÀ» Çϱ⶧¹®¿¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    +
    + +

    Å°¿öµå´Â ½°Ç¥·Î¸¸ ±¸ºÐÇÑ´Ù; »çÀÌ¿¡ °ø¹éÀÌ ÀÖÀ¸¸é + ¾ÈµÈ´Ù. ¸ðµç °æ¿ì Allow¿Í Deny ¸ðµÎ »ìÆ캽À» + ¸í½ÉÇ϶ó.

    + +

    ¾Æ·¡ ¿¹¿¡¼­ apache.org µµ¸ÞÀÎÀÇ ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀº + Çã¿ëÇÏÁö¸¸, ´Ù¸¥ È£½ºÆ®´Â ¸ðµÎ °ÅºÎÇÑ´Ù.

    + +

    + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +

    + +

    ¾Æ·¡ ¿¹¿¡¼­ foo.apache.org ÇÏÀ§µµ¸ÞÀο¡ Àִ ȣ½ºÆ®¸¸ + °ÅºÎÇÏ°í, apache.org µµ¸ÞÀο¡ Àִ ȣ½ºÆ®´Â ¸ðµÎ Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î Á¢±ÙÀ» °ÅºÎÇϱ⶧¹®¿¡ apache.org µµ¸ÞÀο¡ + ¼ÓÇÏÁö ¾Ê´Â È£½ºÆ®´Â Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +

    + +

    ¹Ý´ë·Î À§ÀÇ Order¸¦ + Deny,Allow·Î º¯°æÇϸé, ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ Áö½Ã¾î°¡ ³ª¿À´Â ¼ø¼­¿Í °ü°è¾øÀÌ + Allow from apache.org¸¦ Á¦ÀÏ ¸¶Áö¸·¿¡ ó¸®ÇÏ¿© + Deny from foo.apache.orgÀÇ È¿°ú¸¦ ¹«½ÃÇϱâ + ¶§¹®ÀÌ´Ù. ¶Ç, ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã°¡ÇϹǷΠ+ apache.org µµ¸ÞÀο¡ ¼ÓÇÏÁö ¾Ê´Â È£½ºÆ®µµ ¸ðµÎ + Á¢±ÙÀ» Çã°¡ÇÑ´Ù.

    + +

    Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» + Çã¿ëÇÒÁö °ÅºÎÇÒÁö¸¦ Á¤Çϱ⶧¹®¿¡ Allow³ª Deny Áö½Ã¾î¸¦ »ç¿ëÇÏÁö + ¾Ê¾Æµµ Á¢±Ù°¡´É ¿©ºÎ¿¡ ¿µÇâÀ» ÁØ´Ù. ¿¹¸¦ µé¾î,

    + +

    + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +

    + +

    ´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» °ÅºÎÇϱ⶧¹®¿¡ + /www µð·ºÅ丮¿¡ ´ëÇÑ ¸ðµç Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    Order Áö½Ã¾î°¡ Á¤ÇÏ´Â Á¢±Ù Áö½Ã¾î + 󸮼ø¼­´Â ÇØ´ç ¼­¹ö¼³Á¤ 󸮴ܰ迡¸¸ ¿µÇâÀ» ÁØ´Ù. Áï, + Order Áö½Ã¾î ¼³Á¤°ú °ü°è¾øÀÌ <Location> ¼½¼Ç ¾È¿¡ + ÀÖ´Â Allow³ª + Deny Áö½Ã¾î´Â + <Directory> + ¼½¼ÇÀ̳ª .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Allow¿Í Deny Áö½Ã¾î¸¦ ¸ðµÎ ó¸®ÇÑ + ÈÄ¿¡ ó¸®ÇÑ´Ù. ¼³Á¤ ¼½¼ÇµéÀÌ °áÇÕÇÏ´Â ¹æ¹ý¿¡ ´ëÇؼ­´Â ¾î¶»°Ô Directory, Location, Files + ¼½¼ÇÀÌ µ¿ÀÛÇϳª ¹®¼­¸¦ Âü°íÇ϶ó.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_host.xml b/trunk/docs/manual/mod/mod_authz_host.xml new file mode 100644 index 0000000000..6baf0a4436 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.xml @@ -0,0 +1,336 @@ + + + + + + + + + +mod_authz_host +Group authorizations based on host (name or IP +address) +Base +mod_authz_host.c +authz_host_module +Available in Apache 2.1 and later + + +

    The directives provided by mod_authz_host are + used in Directory, + Files, and + Location sections + as well as .htaccess + files to control access to particular parts of the server. + Access can be controlled based on the client hostname, IP address, or + other characteristics of the client request, as captured in environment variables. The Allow and Deny directives are used to + specify which clients are or are not allowed access to the server, + while the Order + directive sets the default access state, and configures how the + Allow and Deny directives interact with each + other.

    + +

    Both host-based access restrictions and password-based + authentication may be implemented simultaneously. In that case, + the Satisfy directive is used + to determine how the two sets of restrictions interact.

    + +

    In general, access restriction directives apply to all + access methods (GET, PUT, + POST, etc). This is the desired behavior in most + cases. However, it is possible to restrict some methods, while + leaving other methods unrestricted, by enclosing the directives + in a Limit section.

    +
    + +Satisfy +Require + + +Allow +Controls which hosts can access an area of the +server + Allow from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + + +

    The Allow directive affects which hosts can + access an area of the server. Access can be controlled by + hostname, IP Address, IP Address range, or by other + characteristics of the client request captured in environment + variables.

    + +

    The first argument to this directive is always + from. The subsequent arguments can take three + different forms. If Allow from all is specified, then + all hosts are allowed access, subject to the configuration of the + Deny and Order directives as discussed + below. To allow only particular hosts or groups of hosts to access + the server, the host can be specified in any of the + following formats:

    + +
    +
    A (partial) domain-name
    + +
    + Example: + Allow from apache.org
    + Allow from .net example.edu +
    +

    Hosts whose names match, or end in, this string are allowed + access. Only complete components are matched, so the above + example will match foo.apache.org but it will not + match fooapache.org. This configuration will cause + Apache to perform a double reverse DNS lookup on the client IP + address, regardless of the setting of the HostnameLookups directive. It will do + a reverse DNS lookup on the IP address to find the associated + hostname, and then do a forward lookup on the hostname to assure + that it matches the original IP address. Only if the forward + and reverse DNS are consistent and the hostname matches will + access be allowed.

    + +
    A full IP address
    + +
    + Example: + Allow from 10.1.2.3
    + Allow from 192.168.1.104 192.168.1.205 +
    +

    An IP address of a host allowed access

    + +
    A partial IP address
    + +
    + Example: + Allow from 10.1
    + Allow from 10 172.20 192.168.2 +
    +

    The first 1 to 3 bytes of an IP address, for subnet + restriction.

    + +
    A network/netmask pair
    + +
    + Example: + Allow from 10.1.0.0/255.255.0.0 + +

    A network a.b.c.d, and a netmask w.x.y.z. For more + fine-grained subnet restriction.

    + +
    A network/nnn CIDR specification
    + +
    + Example: + Allow from 10.1.0.0/16 + +

    Similar to the previous case, except the netmask consists of + nnn high-order 1 bits.

    +
    + +

    Note that the last three examples above match exactly the + same set of hosts.

    + +

    IPv6 addresses and IPv6 subnets can be specified as shown + below:

    + + + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +
    + +

    The third format of the arguments to the + Allow directive allows access to the server + to be controlled based on the existence of an environment variable. When Allow from + env=env-variable is specified, then the request is + allowed access if the environment variable env-variable + exists. The server provides the ability to set environment + variables in a flexible way based on characteristics of the client + request using the directives provided by + mod_setenvif. Therefore, this directive can be + used to allow access based on such factors as the clients + User-Agent (browser type), Referer, or + other HTTP request header fields.

    + + Example: + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +
    + +

    In this case, browsers with a user-agent string beginning + with KnockKnock/2.0 will be allowed access, and all + others will be denied.

    +
    +
    + + +Deny +Controls which hosts are denied access to the +server + Deny from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + + +

    This directive allows access to the server to be restricted + based on hostname, IP address, or environment variables. The + arguments for the Deny directive are + identical to the arguments for the Allow directive.

    +
    +
    + + +Order +Controls the default access state and the order in which +Allow and Deny are +evaluated. + Order ordering +Order Deny,Allow +directory.htaccess + +Limit + + +

    The Order directive controls the default + access state and the order in which Allow and Deny directives are evaluated. + Ordering is one of

    + +
    +
    Deny,Allow
    + +
    The Deny directives + are evaluated before the Allow directives. Access is + allowed by default. Any client which does not match a + Deny directive or does + match an Allow + directive will be allowed access to the server.
    + +
    Allow,Deny
    + +
    The Allow + directives are evaluated before the Deny directives. Access is denied + by default. Any client which does not match an Allow directive or does match a + Deny directive will be + denied access to the server.
    + +
    Mutual-failure
    + +
    Only those hosts which appear on the Allow list and do not appear on + the Deny list are + granted access. This ordering has the same effect as Order + Allow,Deny and is deprecated in favor of that + configuration.
    +
    + +

    Keywords may only be separated by a comma; no whitespace is + allowed between them. Note that in all cases every Allow and Deny statement is evaluated.

    + +

    In the following example, all hosts in the apache.org domain + are allowed access; all other hosts are denied access.

    + + + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +
    + +

    In the next example, all hosts in the apache.org domain are + allowed access, except for the hosts which are in the + foo.apache.org subdomain, who are denied access. All hosts not + in the apache.org domain are denied access because the default + state is to deny access to the server.

    + + + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +
    + +

    On the other hand, if the Order in the last + example is changed to Deny,Allow, all hosts will + be allowed access. This happens because, regardless of the + actual ordering of the directives in the configuration file, + the Allow from apache.org will be evaluated last + and will override the Deny from foo.apache.org. + All hosts not in the apache.org domain will also + be allowed access because the default state will change to + allow.

    + +

    The presence of an Order directive can affect + access to a part of the server even in the absence of accompanying + Allow and Deny directives because of its effect + on the default access state. For example,

    + + + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +
    + +

    will deny all access to the /www directory + because the default access state will be set to + deny.

    + +

    The Order directive controls the order of access + directive processing only within each phase of the server's + configuration processing. This implies, for example, that an + Allow or Deny directive occurring in a + Location section will + always be evaluated after an Allow or Deny directive occurring in a + Directory section or + .htaccess file, regardless of the setting of the + Order directive. For details on the merging + of configuration sections, see the documentation on How Directory, Location and Files sections + work.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_host.xml.ja b/trunk/docs/manual/mod/mod_authz_host.xml.ja new file mode 100644 index 0000000000..e2bc1ba7fd --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.xml.ja @@ -0,0 +1,341 @@ + + + + + + + + + +mod_authz_host +$B%[%9%H(B ($BL>A0$b$7$/$O(B IP $B%"%I%l%9(B) $B$K4p$E$$$?%0%k!<%W>5G'(B +Base +mod_authz_host.c +authz_host_module +Apache 2.1 $B0J9_(B + + +

    mod_authz_host $B$K$h$jDs6!$5$l$k%G%#%l%/%F%#%V$O(B + $B%5!<%P$NFCDj$NItJ,$X$N(B + $B%"%/%;%9$r@)8f$9$k$?$a$K(B Directory, Files, Location + $B$H(B .htaccess $B%U%!%$%k$G;HMQ$5$l$^$9!#%/%i%$%"%s%H$N%[%9%HL>!"(BIP + $B%"%I%l%9$d(B $B4D6-JQ?t(B$B$H$7$F$N%j%/%(%9%H$NFCD'$K4p$E$$$F(B + $B%"%/%;%9@)8f$r9T$J$&$3$H$,$G$-$^$9!#(BAllow $B$H(B + Deny $B%G%#%l%/%F%#%V$O(B + $B$I$N$h$&$J%/%i%$%"%s%H$K%"%/%;%9$r(B + $B5v2D$9$k!"$7$J$$$+$r;XDj$9$k$?$a$K;HMQ$5$l$^$9!#0lJ}!"(B + Order $B%G%#%l%/%F%#%V$O(B + $B%G%U%)%k%H$N%"%/%;%9>uBV$H!"(B + Allow $B%G%#%l%/%F%#%V$H(B + Deny + $B%G%#%l%/%F%#%V$H$N$*8_$$$X$N1F6A$N;EJ}$r@_Dj$7$^$9!#(B +

    + +

    $B%[%9%H$K$h$k%"%/%;%9@)8B$H%Q%9%o!<%I$K$h$kG'>Z$rF1;~$K(B + $B9T$J$&$3$H$,2DG=$G$9!#$=$N>l9g!"$=$NFs$D$N@)8B$N4X78$r;XDj$9$k$?$a$K(B + Satisfy + $B%G%#%l%/%F%#%V$r;HMQ$7$^$9!#(B

    + +

    $B0lHLE*$K$O!"%"%/%;%9@)8B%G%#%l%/%F%#%V$O$9$Y$F$N%"%/%;%9%a%=%C%I(B + (GET, PUT, POST $B$J$I(B) + $B$KE,MQ$5$l$^$9!#$=$7$F!"$[$H$s$I$N>l9g$3$l$,K>$^$7$$F0:n$G$9!#(B + $B$7$+$7!"(BLimit + $B%;%/%7%g%s$NCf$K%G%#%l%/%F%#%V$r=q$/$3$H$G!"(B + $B0lIt$N%a%=%C%I$K$N$_@)8B$r$+$1$k$3$H$b$G$-$^$9!#(B

    +
    + +Satisfy +Require + + +Allow +$B%5!<%P$N$"$kNN0h$K%"%/%;%9$G$-$k%[%9%H$r@)8f$9$k(B + Allow from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + + +

    Allow $B%G%#%l%/%F%#%V$O$I$N%[%9%H$,(B + $B%5!<%P$N$"$kNN0h$r%"%/%;%9$G$-$k$+$K1F6A$rM?$($^$9!#(B + $B%"%/%;%9$O%[%9%HL>!"(BIP $B%"%I%l%9!"(BIP $B%"%I%l%9$NHO0O$d!"(B + $B4D6-JQ?t$H$7$F$N%/%i%$%"%s%H$N%j%/%(%9%H$N(B + $BFCD'$K$h$C$F@)8f$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$N:G=i$N0z?t$O>o$K(B from $B$G$9!#(B + $B$=$l$KB3$/0z?t$O;0$D$N0c$C$?7A<0$,$"$j$^$9!#(BAllow from + all $B$,;XDj$5$l$F$$$l$P!"$9$Y$F$N%[%9%H$K%"%/%;%9$r5v2D$7!"(B + $B%"%/%;%9@)8B$O2<$G@bL@$5$l$F$$$k$h$&$K!"(B + Deny + $B%G%#%l%/%F%#%V$H(B Order + $B%G%#%l%/%F%#%V$N@_Dj$G7h$^$j$^$9!#(B + $BFCDj$N%[%9%H$d%[%9%H72$K$N$_%5!<%P$X$N%"%/%;%9$r5v2D$9$k$?$a$K$O!"(B + $B0J2<$N$I$l$+$N7A<0$G(B host $B$r;XDj$9$k$3$H$,$G$-$^$9(B:

    + +
    +
    $B%I%a%$%sL>(B ($B$N0lIt(B)
    + +
    + $BNc(B + Allow from apache.org
    + Allow from .net example.edu +
    +

    $B$3$NJ8;zNs$K9g$&$+!"$3$l$G=*$o$kL>A0$N%[%9%H$N%"%/%;%9$,5v2D$5$l$^$9!#(B + $B3FItJ,$,40A4$K9g$&$b$N$@$1$KE,MQ$5$l$^$9$N$G!">e$NNc$O(B + foo.apache.org $B$K$O%^%C%A$7$^$9$,!"(B + fooapache.org $B$K$O%^%C%A$7$^$;$s!#(B + $B$3$N@_Dj$r$9$k$H!"(BApache $B$O(B + HostnameLookups + $B$N@_Dj$K4X$o$i$:!"%/%i%$%"%s%H$N(B IP $B%"%I%l%9$KBP$7$F(B + DNS $B$N(B 2 $B=E5U0z$-$r9T$J$$$^$9!#(B + $B%[%9%HL>$+$i%*%j%8%J%k$N(B IP $B%"%I%l%9$r=g0z$-$7$^$9!#(B + $B=g0z$-$H5U0z$-$,0lCW$7!"%[%9%HL>$,3:Ev$7$?>l9g$K$N$_!"(B + $B%"%/%;%9$,5v2D$5$l$^$9!#(B

    + +
    $B40A4$J(B IP $B%"%I%l%9(B
    + +
    + $BNc(B + Allow from 10.1.2.3
    + Allow from 192.168.1.104 192.168.1.205 +
    +

    $B%"%/%;%9$r5v2D$9$k(B IP $B%"%I%l%9$G$9!#(B

    + +
    IP $B%"%I%l%9$N0lIt(B
    + +
    + $BNc(B + Allow from 10.1
    + Allow from 10 172.20 192.168.2 +
    +

    $B%5%V%M%C%H$N@)8BMQ$N!"(BIP + $B%"%I%l%9$N:G=i$N0l$D$+$i;0$D$^$G$N%P%$%H$G$9!#(B

    + +
    $B%M%C%H%o!<%/(B/$B%M%C%H%^%9%/(B $B$NBP(B
    + +
    + $BNc(B + Allow from 10.1.0.0/255.255.0.0 + +

    $B%M%C%H%o!<%/(B a.b.c.d $B$H%M%C%H%^%9%/(B w.x.y.z $B$G$9!#(B + $B$h$j:YN3EY$N%5%V%M%C%H@)8BMQ$G$9!#(B

    + +
    $B%M%C%H%o!<%/(B/nnn CIDR $B;XDj(B
    + +
    + $BNc(B + Allow from 10.1.0.0/16 + +

    $B%M%C%H%^%9%/$,(B nnn $B$N>e0L%S%C%H$,(B 1 + $B$H$J$C$F$$$k$b$N$+$i$J$k$3$H0J30$OA0$N$b$N$HF1$8$G$9!#(B

    +
    + +

    $BCm(B: $B:G8e$N;0$D$NNc$O$^$C$?$/F1$8%[%9%H$K9g$$$^$9!#(B

    + + +

    IPv6 $B%"%I%l%9$H(B IPv6 $B$N%5%V%M%C%H$O0J2<$N$h$&$K;XDj$G$-$^$9(B:

    + + + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +
    + +

    Allow $B%G%#%l%/%F%#%V$N0z?t$N;0$DL\$N7A<0$O!"(B + $B4D6-JQ?t(B + $B$NB8:_$K$h$j%"%/%;%9$N@)8f$r9T$J$($k$h$&$K$9$k$b$N$G$9!#(B + Allow from env=env-variable + $B$,;XDj$5$l$F$$$k$H!"4D6-JQ?t(B env-variable + $B$,B8:_$7$?>l9g$K%j%/%(%9%H$O%"%/%;%9$r5v2D$5$l$^$9!#%5!<%P$O(B + mod_setenvif + $B$N%G%#%l%/%F%#%V$K$h$j!"%/%i%$%"%s%H$N%j%/%(%9%H(B + $B$NFCD'$K4p$E$$$F=@Fp$K4D6-JQ?t$r@_Dj$9$k5!G=$rDs6!$7$^$9!#(B + $B$G$9$+$i!"$3$N%G%#%l%/%F%#%V$O%/%i%$%"%s%H$N(B + User-Agent ($B%V%i%&%6$NReferer + $B$dB>$N(B HTTP $B%j%/%(%9%H$N%X%C%@%U%#!<%k%I$J$I$K4p$E$$$F(B + $B%"%/%;%95v2D$r$9$k$?$a$K;H$&$3$H$,$G$-$^$9!#(B +

    + + Example: + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +
    + +

    $B$3$N>l9g!"(Buser-agent $B$NJ8;zNs$,(B KnockKnock/2.0 + $B$G;O$^$k%V%i%&%6$N$_$,%"%/%;%9$r5v2D$5$l!"(B + $BB>$N$b$N$O%"%/%;%9$r5qH]$5$l$^$9!#(B

    + +
    +
    + + +Deny +$B%5!<%P$,%"%/%;%9$r5qH]$9$k%[%9%H$r@)8f$9$k(B + Deny from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + +

    $B$3$N%G%#%l%/%F%#%V$O%[%9%HL>!"(BIP + $B%"%I%l%9!"4D6-JQ?t$K4p$E$$$F%5!<%P$X$N%"%/%;%9$r@)8B$7$^$9!#(B + Deny $B%G%#%l%/%F%#%V$N0z?t$O(B Allow + $B%G%#%l%/%F%#%V$H$^$C$?$/F1$8$G$9!#(B

    +
    + +
    + + +Order +$B%G%U%)%k%H$N%"%/%;%92DG=$J>uBV$H!"(BAllow $B$H(B +Deny $B$,I>2A$5$l$k=gHV$r@)8f$9$k(B + Order ordering +Order Deny,Allow +directory.htaccess + +Limit + + +

    Order $B%G%#%l%/%F%#%V$O%G%U%)%k%H$N%"%/%;%9$N>uBV$H(B + Allow $B%G%#%l%/%F%#%V$H(B + Deny + $B%G%#%l%/%F%#%V$,I>2A$5$l$k=gHV$r@)8f$7$^$9!#(B + Ordering $B$O0J2<$N$I$l$+$G$9!#(B

    + +
    +
    Deny,Allow
    + +
    Deny $B%G%#%l%/%F%#%V$,(B + Allow + $B%G%#%l%/%F%#%V$NA0$KI>2A$5$l$^$9!#(B + $B%"%/%;%9$O%G%U%)%k%H$G5v2D$5$l$^$9!#(BDeny + $B%G%#%l%/%F%#%V$K9g$o$J$$$+!"(BAllow + $B%G%#%l%/%F%#%V$K9g$&%/%i%$%"%s%H$O%"%/%;%9$r5v2D$5$l$^$9!#(B
    + +
    Allow,Deny
    + +
    Allow + $B%G%#%l%/%F%#%V$,(B Deny + $B%G%#%l%/%F%#%V$NA0$KI>2A$5$l$^$9!#(B + $B%"%/%;%9$O%G%U%)%k%H$G5qH]$5$l$^$9!#(BAllow + $B%G%#%l%/%F%#%V$K9g$o$J$$$+!"(BDeny + $B%G%#%l%/%F%#%V$K9g$&%/%i%$%"%s%H$O%"%/%;%9$r5qH]$5$l$^$9!#(B +
    + +
    Mutual-failure
    + +
    Allow $B$N%j%9%H$K8=$l$F!"(B + Deny + $B$N%j%9%H$K8=$l$J$$%[%9%H$N$_$,%"%/%;%9$r5v2D$5$l$^$9!#(B + $B$3$N=gHVIU$1$O(B Order Allow,Deny $B$HF1$88z2L$r;}$A!"(B + $B$=$N@_Dj$NJ}$,9%$^$7$$$?$a$KHs?d>)$H$J$C$F$$$^$9!#(B
    +
    + +

    $B%-!<%o!<%I$O%3%s%^$GJ,N%$9$k$3$H$@$1$,2DG=$G$9!#(B + $B4V$K(B$B6uGr$,$"$C$F$O$$$1$^$;$s(B$B!#$I$N>l9g$G$b!"(BAllow $B$H(B + Deny $BJ8$O(B + $BA4$FI>2A$5$l$k$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B +

    + +

    $B0J2<$NNc$G$O!"(Bapache.org + $B%I%a%$%s$N$9$Y$F$N%[%9%H$O%"%/%;%9$r5v2D$5$l$^$9!#(B + $BB>$N$9$Y$F$N%[%9%H$O%"%/%;%9$r5qH]$5$l$^$9!#(B

    + + + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +
    + +

    $BuBV$,%"%/%;%95qH]$N$?$a!"(B + $B%5!<%P$X$N%"%/%;%9$r5qH]$5$l$^$9!#(B

    + + + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +
    + +

    $B0lJ}!">e$NNc$N(B Order $B$,(B Deny,Allow + $B$KJQ$o$C$F$$$l$P!"$9$Y$N%[%9%H$K%"%/%;%9$,5v2D$5$l$^$9!#(B + $B$3$l$O!"@_Dj%U%!%$%kCf$NAllow from apache.org $B$,:G8e$KI>2A$5$l$F!"(B + Deny from foo.apache.org $B$r>e=q$-$9$k$+$i$G$9!#(B + apache.org + $B%I%a%$%s$K$J$$%[%9%H$b!"%G%U%)%k%H$N>uBV$,(B allow + $B$KJQ2=$9$k$?$a$K!"%"%/%;%9$r5v2D$5$l$^$9!#(B +

    + +

    Order + $B%G%#%l%/%F%#%V$O%G%U%)%k%H$N%"%/%;%9$N>uBV$K1F6A$rM?$($k$N$G!"(B + Allow $B%G%#%l%/%F%#%V$H(B + Deny + $B%G%#%l%/%F%#%V$,L5$/$F$b!"%5!<%P$N%"%/%;%9$K1F6A$rM?$($k$3$H$,$G$-$^$9!#(B + $B$?$H$($P!"(B

    + + + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +
    + +

    $B$O%G%U%)%k%H$N%"%/%;%9>uBV$,(B deny $B$K$J$k$?$a!"(B + /www $B%G%#%l%/%H%j$X$N$9$Y$F$N%"%/%;%9$r5qH]$7$^$9!#(B +

    + +

    Order + $B%G%#%l%/%F%#%V$O%5!<%P$N@_Dj=hM}$N3FCJ3,$G$@$1(B + $B%"%/%;%9%G%#%l%/%F%#%V$N=hM}$N=gHV$rJQ99$7$^$9!#$3$l$O!"$?$H$($P!"(B + Order $B%G%#%l%/%F%#%V$N@_Dj$K4X$o$i$:!"(B + Location $B%;%/%7%g%s$N(B + Allow $B%G%#%l%/%F%#%V$d(B + Deny $B%G%#%l%/%F%#%V$O!"(B + Directory $B%;%/%7%g%s$d(B + .htaccess $B%U%!%$%k$N(B Allow + $B%G%#%l%/%F%#%V$d(B Deny + $B%G%#%l%/%F%#%V$h$j$b>o$K8e$KI>2A$5$l$k$H$$$&$3$H$r0UL#$7$^$9!#(B + $B@_Dj%;%/%7%g%s$N%^!<%8$N>\:Y$K$D$$$F$O!"(B + Directory,Location, Files + $B%;%/%7%g%s$NF0:nJ}K!(B $B$r;2>H$7$F$/$@$5$$!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_host.xml.ko b/trunk/docs/manual/mod/mod_authz_host.xml.ko new file mode 100644 index 0000000000..76ab7186d5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.xml.ko @@ -0,0 +1,313 @@ + + + + + + + + + +mod_authz_host +È£½ºÆ® (À̸§À̳ª IP ÁÖ¼Ò)¸¦ »ç¿ëÇÑ ±×·ì ±ÇÇѺο© +Base +mod_authz_host.c +authz_host_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    Directory, + Files, + Location + ¼½¼Ç°ú .htaccess + ÆÄÀÏ¿¡¼­ ¼­¹öÀÇ Æ¯Á¤ ºÎºÐÀÇ Á¢±ÙÀ» Á¦¾îÇϱâÀ§ÇØ + mod_authz_host°¡ Á¦°øÇÏ´Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®ÀÇ È£½ºÆ®¸í, IP ÁÖ¼Ò, ȯ°æº¯¼ö¿¡ ±â·ÏµÈ ¿äûÀÇ Æ¯¼º¿¡ µû¶ó + Á¢±ÙÀ» Á¦¾îÇÑ´Ù. Allow¿Í Deny Áö½Ã¾î´Â ¾î¶² + Ŭ¶óÀ̾ðÆ®°¡ ¼­¹ö¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö¸¦ Áö½ÃÇÏ°í, Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î + Á¢±ÙÀ» Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í ¾î¶»°Ô Allow Áö½Ã¾î¿Í Deny Áö½Ã¾î°¡ ¼­·Î ¿µÇâÀ» + ¹ÌÄ¡´ÂÁö °áÁ¤ÇÑ´Ù.

    + +

    È£½ºÆ®±â¹Ý Á¢±ÙÁ¦ÇÑ°ú ¾ÏÈ£±â¹Ý ÀÎÁõÀ» µ¿½Ã¿¡ »ç¿ëÇÒ ¼öµµ + ÀÖ´Ù. ÀÌ °æ¿ì Satisfy + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¾î¶»°Ô µÎ Á¦ÇÑÀÌ ¼­·Î ¿µÇâÀ» ¹ÌÄ¡´ÂÁö + °áÁ¤ÇÑ´Ù.

    + +

    ÀϹÝÀûÀ¸·Î Á¢±ÙÁ¦ÇÑ Áö½Ã¾î´Â (GET, + PUT, POST µî) ¸ðµç ¸Þ¼­µå¿¡ Àû¿ëµÇ¸ç, + ÀÌ ÇൿÀº ´ëºÎºÐÀÇ °æ¿ì ¹Ù¶÷Á÷ÇÏ´Ù. ±×·¯³ª Limit ¼½¼Ç¾È¿¡ + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ƯÁ¤ ¸Þ¼­µå¿¡¸¸ Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    +
    + +Satisfy +Require + + +Allow +¼­¹öÀÇ ÀϺο¡ Á¢±ÙÇÒ ¼ö Àִ ȣ½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù + Allow from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + + +

    Allow Áö½Ã¾î´Â ¾î¶² È£½ºÆ®°¡ ¼­¹öÀÇ + ÀϺο¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö Áö½ÃÇÑ´Ù. È£½ºÆ®¸í, IP ÁÖ¼Ò, IP + ÁÖ¼Ò¿µ¿ª, ȯ°æº¯¼ö¿¡ ±â·ÏµÈ ´Ù¸¥ Ư¼º¿¡ µû¶ó Á¢±ÙÀ» Á¶ÀýÇÒ + ¼ö ÀÖ´Ù.

    + +

    ÀÌ Áö½Ã¾îÀÇ Ã¹¹ø° ¾Æ±Ô¸ÕÆ®´Â Ç×»ó fromÀÌ´Ù. + ´ÙÀ½ ¾Æ±Ô¸ÕÆ®¿¡´Â ¼¼°¡Áö Çü½ÄÀÌ ÀÖ´Ù. Allow from allÀ» + »ç¿ëÇϸé, ¾Æ·¡¿¡¼­ ¼³¸íÇÒ Deny¿Í Order Áö½Ã¾î ¼³Á¤¿¡ + µû¶ó ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀ» Çã°¡ÇÑ´Ù. ƯÁ¤ È£½ºÆ®¸¸ ¼­¹ö·Î + Á¢±ÙÀ» Çã¿ëÇÏ·Á¸é ´ÙÀ½°ú °°Àº Çü½ÄÀ¸·Î host¸¦ Áö½ÃÇÒ + ¼ö ÀÖ´Ù:

    + +
    +
    È£½ºÆ®¸í (ÀϺÎ)
    + +
    + ¿¹Á¦: + Allow from apache.org + +

    È£½ºÆ®¸íÀÌ ÀÌ ¹®ÀÚ¿­°ú °°°Å³ª ÀÌ ¹®ÀÚ¿­·Î ³¡³ª¸é Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±×·¡¼­ ÀÌ °æ¿ì foo.apache.org´Â + ÇØ´çµÇ°í, fooapache.org´Â ÇØ´çµÇÁö ¾Ê´Â´Ù. + ÀÌ ¼³Á¤À» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â HostnameLookups Áö½Ã¾î ¼³Á¤°ú + °ü°è¾øÀÌ Å¬¶óÀ̾ðÆ® IP ÁÖ¼Ò¸¦ °¡Áö°í Áߺ¹-¿ª DNS °Ë»öÀ» + ÇÑ´Ù. Áï, È£½ºÆ®¸íÀ» ã±âÀ§ÇØ IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÀ» ÇÑ + ÈÄ, ´Ù½Ã È£½ºÆ®¸íÀ¸·Î °Ë»öÇÏ¿© ¿ø·¡ IP ÁÖ¼Ò¿Í ÀÏÄ¡ÇÏ´ÂÁö + È®ÀÎÇÑ´Ù. °á°ú°¡ °°°í È£½ºÆ®¸íÀÌ ¼³Á¤°ª¿¡ ÇØ´çÇϸé, Á¢±ÙÀ» + Çã¿ëÇÑ´Ù.

    + +
    IP ÁÖ¼Ò Àüü
    + +
    + ¿¹Á¦: + Allow from 10.1.2.3 + +

    Á¢±ÙÀ» Çã°¡Çϴ ȣ½ºÆ®ÀÇ IP ÁÖ¼Ò

    + +
    IP ÁÖ¼Ò ÀϺÎ
    + +
    + ¿¹Á¦: + Allow from 10.1 + +

    ¼­ºê³×Æ®¿öÅ©·Î Á¦ÇÑÇϱâÀ§ÇØ IP ÁÖ¼Ò ¾ÕÀÇ 1¿¡¼­ 3 + ¹ÙÀÌÆ®.

    + +
    ³×Æ®¿öÅ©/³Ý¸Å½ºÅ© ½Ö
    + +
    + ¿¹Á¦: + Allow from 10.1.0.0/255.255.0.0 + +

    ³×Æ®¿öÅ© a.b.c.d¿Í ³Ý¸Å½ºÅ© w.x.y.z. ´õ ¼¼¹ÐÇÏ°Ô + ¼­ºê³×Æ®¿öÅ©·Î Á¦ÇÑÇÒ¶§ »ç¿ëÇÑ´Ù.

    + +
    ³×Æ®¿öÅ©/nnn CIDR ±Ô¾à
    + +
    + ¿¹Á¦: + Allow from 10.1.0.0/16 + +

    ¾ÕÀÇ °æ¿ì¿Í °°Áö¸¸, »óÀ§ nnn°³ ºñÆ® °ªÀÌ 1ÀÎ ³Ý¸Å½ºÅ©¸¦ + »ç¿ëÇÑ´Ù.

    +
    + +

    ¸¶Áö¸· ¼¼°¡Áö ¿¹´Â Á¤È®È÷ µ¿ÀÏÇÑ È£½ºÆ®µéÀ» ÁöĪÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ IPv6 ÁÖ¼Ò¿Í IPv6 ¼­ºê³×Æ®¿öÅ©¸¦ ÁöÁ¤ÇÒ ¼öµµ + ÀÖ´Ù:

    + + + Allow from fe80::a00:20ff:fea7:ccea
    + Allow from fe80::a00:20ff:fea7:ccea/10 +
    + +

    Allow Áö½Ã¾î ¾Æ±Ô¸ÕÆ®ÀÇ ¼¼¹ø° + Çü½ÄÀº ȯ°æº¯¼ö À¯¹«¿¡ µû¶ó Á¢±ÙÀ» + Á¦¾îÇÑ´Ù. Allow from env=env-variableÀ» + »ç¿ëÇϸé, env-variable ȯ°æº¯¼ö°¡ Á¤ÀÇµÈ °æ¿ì + Á¢±ÙÀ» Çã°¡ÇÑ´Ù. mod_setenvif°¡ Á¦°øÇÏ´Â + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© Ŭ¶óÀ̾ðÆ® ¿äûÀÇ Æ¯¼º¿¡ µû¶ó ÀÚÀ¯·Ó°Ô + ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×·¯¹Ç·Î ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + Ŭ¶óÀ̾ðÆ® User-Agent (ºê¶ó¿ìÀú Á¾·ù), + Referer, ´Ù¸¥ HTTP ¿äû Çì´õ¿¡ µû¶ó Á¢±ÙÀ» + Çã°¡ÇÒ ¼ö ÀÖ´Ù.

    + + ¿¹Á¦: + SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
    + <Directory /docroot>
    + + Order Deny,Allow
    + Deny from all
    + Allow from env=let_me_in
    +
    + </Directory> +
    + +

    ÀÌ °æ¿ì user-agent ¹®ÀÚ¿­ÀÌ KnockKnock/2.0À¸·Î + ½ÃÀÛÇÏ´Â ºê¶ó¿ìÀúÀÇ Á¢±ÙÀº Çã¿ëÇÏ°í, ³ª¸ÓÁö´Â ¸ðµÎ °ÅºÎÇÑ´Ù.

    +
    +
    + + +Deny +¼­¹ö Á¢±ÙÀ» °ÅºÎÇÒ È£½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù + Deny from all|host|env=env-variable +[host|env=env-variable] ... +directory.htaccess + +Limit + + +

    ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© È£½ºÆ®¸í, IP ÁÖ¼Ò, ȯ°æº¯¼ö¿¡ µû¶ó + ¼­¹ö Á¢±ÙÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. Deny + Áö½Ã¾îÀÇ ¾Æ±Ô¸ÕÆ®´Â Allow Áö½Ã¾î¿Í µ¿ÀÏÇÏ´Ù.

    +
    +
    + + +Order +±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í +Allow¿Í Deny +󸮼ø¼­¸¦ Á¤ÇÑ´Ù. + Order ordering +Order Deny,Allow +directory.htaccess + +Limit + + +

    Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» + Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í Allow¿Í Deny Áö½Ã¾î 󸮼ø¼­¸¦ + Á¤ÇÑ´Ù. orderingÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù

    + +
    +
    Deny,Allow
    + +
    Deny + Áö½Ã¾î¸¦ Allow + Áö½Ã¾î º¸´Ù ¸ÕÀú »ìÆ캻´Ù. ±×¸®°í ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÑ´Ù. + Deny³ª + Allow Áö½Ã¾î¿¡ + ÇØ´çµÇÁö ¾Ê´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» Çã¿ëÇÑ´Ù.
    + +
    Allow,Deny
    + +
    Allow + Áö½Ã¾î¸¦ Deny Áö½Ã¾î º¸´Ù ¸ÕÀú + »ìÆ캻´Ù. ±×¸®°í ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù. + Deny³ª + Allow Áö½Ã¾î¿¡ + ÇØ´çµÇÁö ¾Ê´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±ÙÀ» °ÅºÎÇÑ´Ù.
    + +
    Mutual-failure
    + +
    Deny + ¸ñ·Ï¿¡´Â ¾È³ª¿À°í Allow ¸ñ·Ï¿¡¸¸ ³ª¿À´Â + È£½ºÆ®¸¸ Á¢±ÙÀ» Çã¿ëÇÑ´Ù. Order Allow,Deny¿Í + °°Àº ÀÏÀ» Çϱ⶧¹®¿¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    +
    + +

    Å°¿öµå´Â ½°Ç¥·Î¸¸ ±¸ºÐÇÑ´Ù; »çÀÌ¿¡ °ø¹éÀÌ ÀÖÀ¸¸é + ¾ÈµÈ´Ù. ¸ðµç °æ¿ì Allow¿Í Deny ¸ðµÎ »ìÆ캽À» + ¸í½ÉÇ϶ó.

    + +

    ¾Æ·¡ ¿¹¿¡¼­ apache.org µµ¸ÞÀÎÀÇ ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀº + Çã¿ëÇÏÁö¸¸, ´Ù¸¥ È£½ºÆ®´Â ¸ðµÎ °ÅºÎÇÑ´Ù.

    + + + Order Deny,Allow
    + Deny from all
    + Allow from apache.org +
    + +

    ¾Æ·¡ ¿¹¿¡¼­ foo.apache.org ÇÏÀ§µµ¸ÞÀο¡ Àִ ȣ½ºÆ®¸¸ + °ÅºÎÇÏ°í, apache.org µµ¸ÞÀο¡ Àִ ȣ½ºÆ®´Â ¸ðµÎ Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î Á¢±ÙÀ» °ÅºÎÇϱ⶧¹®¿¡ apache.org µµ¸ÞÀο¡ + ¼ÓÇÏÁö ¾Ê´Â È£½ºÆ®´Â Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + + + Order Allow,Deny
    + Allow from apache.org
    + Deny from foo.apache.org +
    + +

    ¹Ý´ë·Î À§ÀÇ Order¸¦ + Deny,Allow·Î º¯°æÇϸé, ¸ðµç È£½ºÆ®ÀÇ Á¢±ÙÀ» + Çã¿ëÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ Áö½Ã¾î°¡ ³ª¿À´Â ¼ø¼­¿Í °ü°è¾øÀÌ + Allow from apache.org¸¦ Á¦ÀÏ ¸¶Áö¸·¿¡ ó¸®ÇÏ¿© + Deny from foo.apache.orgÀÇ È¿°ú¸¦ ¹«½ÃÇϱâ + ¶§¹®ÀÌ´Ù. ¶Ç, ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã°¡ÇϹǷΠ+ apache.org µµ¸ÞÀο¡ ¼ÓÇÏÁö ¾Ê´Â È£½ºÆ®µµ ¸ðµÎ + Á¢±ÙÀ» Çã°¡ÇÑ´Ù.

    + +

    Order Áö½Ã¾î´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» + Çã¿ëÇÒÁö °ÅºÎÇÒÁö¸¦ Á¤Çϱ⶧¹®¿¡ Allow³ª Deny Áö½Ã¾î¸¦ »ç¿ëÇÏÁö + ¾Ê¾Æµµ Á¢±Ù°¡´É ¿©ºÎ¿¡ ¿µÇâÀ» ÁØ´Ù. ¿¹¸¦ µé¾î,

    + + + <Directory /www>
    + + Order Allow,Deny
    +
    + </Directory> +
    + +

    ´Â ±âº»ÀûÀ¸·Î Á¢±ÙÀ» °ÅºÎÇϱ⶧¹®¿¡ + /www µð·ºÅ丮¿¡ ´ëÇÑ ¸ðµç Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    Order Áö½Ã¾î°¡ Á¤ÇÏ´Â Á¢±Ù Áö½Ã¾î + 󸮼ø¼­´Â ÇØ´ç ¼­¹ö¼³Á¤ 󸮴ܰ迡¸¸ ¿µÇâÀ» ÁØ´Ù. Áï, + Order Áö½Ã¾î ¼³Á¤°ú °ü°è¾øÀÌ Location ¼½¼Ç ¾È¿¡ + ÀÖ´Â Allow³ª + Deny Áö½Ã¾î´Â + Directory + ¼½¼ÇÀ̳ª .htaccess ÆÄÀÏ¿¡ ÀÖ´Â Allow¿Í Deny Áö½Ã¾î¸¦ ¸ðµÎ ó¸®ÇÑ + ÈÄ¿¡ ó¸®ÇÑ´Ù. ¼³Á¤ ¼½¼ÇµéÀÌ °áÇÕÇÏ´Â ¹æ¹ý¿¡ ´ëÇؼ­´Â ¾î¶»°Ô Directory, Location, Files + ¼½¼ÇÀÌ µ¿ÀÛÇϳª ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_host.xml.meta b/trunk/docs/manual/mod/mod_authz_host.xml.meta new file mode 100644 index 0000000000..e5b027e528 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_host.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authz_host + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authz_owner.html b/trunk/docs/manual/mod/mod_authz_owner.html new file mode 100644 index 0000000000..f23a815ffe --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.html @@ -0,0 +1,11 @@ +URI: mod_authz_owner.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_owner.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authz_owner.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_owner.html.en b/trunk/docs/manual/mod/mod_authz_owner.html.en new file mode 100644 index 0000000000..be7ad185b9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.html.en @@ -0,0 +1,185 @@ + + + +mod_authz_owner - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_owner

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Authorization based on file ownership
    Status:Extension
    Module Identifier:authz_owner_module
    Source File:mod_authz_owner.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module authorizes access to files by comparing the userid used + for HTTP authentication (the web userid) with the file-system owner or + group of the requested file. The supplied username and password + must be already properly verified by an authentication module, + such as mod_auth_basic or + mod_auth_digest. mod_authz_owner + recognizes two arguments for the Require directive, file-owner and + file-group, as follows:

    + +
    +
    file-owner
    +
    The supplied web-username must match the system's name for the + owner of the file being requested. That is, if the operating system + says the requested file is owned by jones, then the + username used to access it through the web must be jones + as well.
    + +
    file-group
    +
    The name of the system group that owns the file must be present + in a group database, which is provided, for example, by mod_authz_groupfile or mod_authz_dbm, + and the web-username must be a member of that group. For example, if + the operating system says the requested file is owned by (system) + group accounts, the group accounts must + appear in the group database and the web-username used in the request + must be a member of that group.
    +
    + +

    Note

    +

    If mod_authz_owner is used in order to authorize + a resource that is not actually present in the filesystem + (i.e. a virtual resource), it will deny the access.

    + +

    Particularly it will never authorize content negotiated + "MultiViews" resources.

    +
    +
    +

    Directives

    + +

    Topics

    +

    See also

    +
    +
    top
    +
    +

    Configuration Examples

    + +

    Require file-owner

    +

    Consider a multi-user system running the Apache Web server, with + each user having his or her own files in ~/public_html/private. Assuming that there is a single + AuthDBMUserFile database + that lists all of their web-usernames, and that these usernames match + the system's usernames that actually own the files on the server, then + the following stanza would allow only the user himself access to his + own files. User jones would not be allowed to access + files in /home/smith/public_html/private unless they + were owned by jones instead of smith.

    + +

    + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +

    + + +

    Require file-group

    +

    Consider a system similar to the one described above, but with + some users that share their project files in + ~/public_html/project-foo. The files are owned by the + system group foo and there is a single AuthDBMGroupFile database that + contains all of the web-usernames and their group membership, + i.e. they must be at least member of a group named + foo. So if jones and smith + are both member of the group foo, then both will be + authorized to access the project-foo directories of + each other.

    + +

    + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +

    + +
    +
    top
    +

    AuthzOwnerAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization will be passed on to lower level +modules
    Syntax:AuthzOwnerAuthoritative On|Off
    Default:AuthzOwnerAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_authz_owner
    +

    Setting the AuthzOwnerAuthoritative + directive explicitly to Off allows for + user authorization to be passed on to lower level modules (as defined + in the modules.c files) if:

    + +
      +
    • in the case of file-owner the file-system owner does not + match the supplied web-username or could not be determined, or
    • + +
    • in the case of file-group the file-system group does not + contain the supplied web-username or could not be determined.
    • +
    + +

    Note that setting the value to Off also allows the + combination of file-owner and file-group, so + access will be allowed if either one or the other (or both) match.

    + +

    By default, control is not passed on and an authorization failure + will result in an "Authentication Required" reply. Not + setting it to Off thus keeps the system secure and forces + an NCSA compliant behaviour.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_owner.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authz_owner.html.ja.euc-jp new file mode 100644 index 0000000000..2ba82b5417 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.html.ja.euc-jp @@ -0,0 +1,187 @@ + + + +mod_authz_owner - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authz_owner

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤Ë´ð¤Å¤¤¤¿¾µÇ§
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authz_owner_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authz_owner.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î + ½êÍ­¼Ô¤ä¥°¥ë¡¼¥×¤ò HTTP ǧ¾Ú¤Ë»È¤ï¤ì¤¿¥æ¡¼¥¶ ID (¥¦¥§¥Ö¥æ¡¼¥¶ ID) ¤È + Èæ³Ó¤¹¤ë¤³¤È¤Ç¥¢¥¯¥»¥¹¤ò¾µÇ§¤·¤Þ¤¹¡£Ä󶡤µ¤ì¤¿¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤Ï + mod_auth_basic ¤ä + mod_auth_digest ¤Î¤è¤¦¤Êǧ¾Ú¥â¥¸¥å¡¼¥ë¤Ç´û¤Ë + ŬÀڤ˸¡¾Ú¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£mod_authz_owner + ¤Ï°Ê²¼¤Î¤è¤¦¤Ë¡¢Require ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î file-owner ¤È + file-group ¤È¤¤¤¦Æó¤Ä¤Î°ú¿ô¤òǧ¼±¤·¤Þ¤¹:

    + +
    +
    file-owner
    +
    Ä󶡤µ¤ì¤¿¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤Ï¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤Î + ¥·¥¹¥Æ¥à¤Ë¤ª¤±¤ë̾Á°¤È°ìÃפ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥° + ¥·¥¹¥Æ¥à¤¬¥Õ¥¡¥¤¥ë¤Ï jones ¤Ë¤è¤ê½êÍ­¤µ¤ì¤Æ¤¤¤ë + ¤È¸À¤Ã¤¿¤È¤­¤Ï¡¢¥¦¥§¥Ö¤«¤é¤Î¥¢¥¯¥»¥¹¤Ë»È¤ï¤ì¤ë¥æ¡¼¥¶Ì¾¤â + jones ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
    + +
    file-group
    +
    ¥Õ¥¡¥¤¥ë¤ò½êÍ­¤¹¤ë¥·¥¹¥Æ¥à¤Î¥°¥ë¡¼¥×¤Î̾Á°¤¬¡¢Î㤨¤Ð + mod_authz_groupfile ¤ä mod_authz_dbm + ¤Ë¤è¤êÄ󶡤µ¤ì¤ë¥°¥ë¡¼¥×¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¸ºß¤·¤Æ¤¤¤Æ¡¢ + ¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤¬¤½¤Î¥°¥ë¡¼¥×¤Ë°¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤¬¥Õ¥¡¥¤¥ë¤Ï (¥·¥¹¥Æ¥à¤Î) ¥°¥ë¡¼¥× + accounts ¤Ë¤è¤ê½êÍ­¤µ¤ì¤Æ¤¤¤ë¤È¸À¤Ã¤¿¤È¤­¤Ï¡¢ + accounts ¤¬¥°¥ë¡¼¥×¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¸ºß¤·¤Æ¡¢ + ¥ê¥¯¥¨¥¹¥È¤Ë»ÈÍѤµ¤ì¤¿¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤¬¤½¤Î¥°¥ë¡¼¥×¤Ë°¤·¤Æ¤¤¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£
    +
    + +

    Ãí

    +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë¼ÂºÝ¤Ë¤Ï¸ºß¤·¤Ê¤¤¥ê¥½¡¼¥¹ + (¤Ä¤Þ¤ê ¥Ð¡¼¥Á¥ã¥ë¤Ê¥ê¥½¡¼¥¹) ¤Î¾µÇ§¤Ë + mod_authz_owner ¤¬»ÈÍѤµ¤ì¤¿¤È¤­¤Ï¡¢ + ¥¢¥¯¥»¥¹¤ÏµñÈݤµ¤ì¤Þ¤¹¡£

    + +

    Æäˡ¢¥³¥ó¥Æ¥ó¥È + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤µ¤ì¤¿"MultiViews" ¤Î¥ê¥½¡¼¥¹¤Ï + ·è¤·¤Æ¾µÇ§¤·¤Þ¤»¤ó¡£

    +
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +

    »²¾È

    +
    +
    top
    +
    +

    ÀßÄêÎã

    + +

    Require file-owner

    +

    Ê£¿ô¥æ¡¼¥¶¤Î¥·¥¹¥Æ¥à¤Ç Apache ¥¦¥§¥Ö¥µ¡¼¥Ð¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤Æ¡¢ + ~/public_html/private ¤Ë³Æ¥æ¡¼¥¶¤¬¥Õ¥¡¥¤¥ë¤òÃÖ¤¤¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£ + AuthDBMUserFile + ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬°ì¤Ä¤À¤±¤¢¤ê¡¢¤¹¤Ù¤Æ¤Î¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤¬Îóµó¤µ¤ì¤Æ¤ª¤ê¡¢ + ¤³¤Î¥æ¡¼¥¶Ì¾¤¬¥µ¡¼¥Ð¤Ç¼ÂºÝ¤Ë¥Õ¥¡¥¤¥ë¤ò½êÍ­¤·¤Æ¤¤¤ë¥æ¡¼¥¶Ì¾¤È°ìÃפ·¤Æ¤¤¤ë¾ì¹ç¡¢ + ¼¡¤ÎÀá¤Î¤è¤¦¤ÊÀßÄê¤Ç¡¢¥æ¡¼¥¶¤¬¼«Ê¬¼«¿È¤Î¥Õ¥¡¥¤¥ë¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + /home/smith/public_html/private ¤ÎÃæ¤Î¥Õ¥¡¥¤¥ë¤Ï¡¢½êÍ­¼Ô¤¬ + smith ¤ÎÂå¤ï¤ê¤Ë jones ¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢ + jones ¤Ë¤Ï¥¢¥¯¥»¥¹¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó¡£

    + +

    + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +

    + + +

    Require file-group

    +

    ¾åµ­¤Î¤è¤¦¤Ê¥·¥¹¥Æ¥à¤Ç¡¢¿ô¿Í¤Î¥æ¡¼¥¶¤¬¥×¥í¥¸¥§¥¯¥È¤Î¥Õ¥¡¥¤¥ë¤ò + ~/public_html/project-foo ¤Ç¶¦Í­¤·¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¤Ï¥·¥¹¥Æ¥à¤Î¥°¥ë¡¼¥× foo ¤Ë½êÍ­¤µ¤ì¤Æ¤¤¤Æ¡¢ + AuthDBMGroupFile + ¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬°ì¤Ä¤À¤±¤¢¤ê¡¢¤½¤³¤Ë¤¹¤Ù¤Æ¤Î¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤È + ¥°¥ë¡¼¥×¤Î¥á¥ó¥Ð¤¬Îóµó¤µ¤ì¤Æ¤¤¤ë¡¢¤Ä¤Þ¤ê¡¢¤½¤ì¤é¤Î + ¥æ¡¼¥¶¤Ï¾¯¤Ê¤¯¤È¤â foo ¤È¤¤¤¦¥°¥ë¡¼¥×¤Ë°¤·¤Æ¤¤¤ë¡¢¤È¤·¤Þ¤¹¡£ + jones ¤Èsmith ¤ÎÆó¿Í¶¦¤¬¥°¥ë¡¼¥× + foo ¤Î¥á¥ó¥Ð¤Ç¤¢¤ë¾ì¹ç¡¢¤É¤Á¤é¤Î¿Í¤âξÊý¤Î + project-foo ¤Ë¥¢¥¯¥»¥¹¤¬µö²Ä¤µ¤ì¤Þ¤¹¡£

    + +

    + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +

    + +
    +
    top
    +

    AuthzOwnerAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¾µÇ§¤¬²¼°Ì¾µÇ§¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthzOwnerAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthzOwnerAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_authz_owner
    +

    AuthzOwnerAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÌÀ¼¨Åª¤Ë Off ¤ËÀßÄꤹ¤ë¤È¡¢°Ê²¼¤Î¾ì¹ç¤Ëǧ¾Ú¤¬ + (modules.c ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë) ²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤Ë + ÅϤµ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹:

    + +
      +
    • file-owner ¤Î¾ì¹ç¤Ï¡¢Ä󶡤µ¤ì¤¿¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤Ë + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î½êÍ­¼Ô¤¬°ìÃפ·¤Ê¤¤¤«¡¢½êÍ­¼Ô¤¬¤ï¤«¤é¤Ê¤¤¾ì¹ç¡£
    • + +
    • file-group ¤Î¾ì¹ç¤Ï¡¢Ä󶡤µ¤ì¤¿¥¦¥§¥Ö¥æ¡¼¥¶Ì¾¤¬ + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥°¥ë¡¼¥×¤Ë¸ºß¤·¤Ê¤¤¤«¡¢¤ï¤«¤é¤Ê¤¤¾ì¹ç¡£
    • +
    + +

    Ãͤò Off ¤ËÀßÄꤹ¤ë¤È¡¢file-owner ¤È + file-group ¤òÁȤ߹ç¤ï¤»¤ë¤³¤È¤â¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¡¢ + ¤½¤Î¾ì¹ç¤Ï¤É¤Á¤é¤« (ξÊý¤Ç¤â) ¤Ë¥Þ¥Ã¥Á¤·¤¿¾ì¹ç¤Ë¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤Þ¤¹¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏÀ©¸æ¤ÏÅϤµ¤ì¤º¡¢Ì¤ÃΤΥ°¥ë¡¼¥×¤Î¾ì¹ç¤Ï Authentication + Required ±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢Off ¤ËÀßÄꤷ¤Ê¤¤¤³¤È¤Ç + ¥·¥¹¥Æ¥à¤ò°ÂÁ´¤ËÊݤĤ³¤È¤¬¤Ç¤­¡¢NCSA ¸ß´¹¤Î¿¶¤ëÉñ¤¤¤ò¤µ¤»¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_owner.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_owner.html.ko.euc-kr new file mode 100644 index 0000000000..d248e514d5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.html.ko.euc-kr @@ -0,0 +1,182 @@ + + + +mod_authz_owner - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_owner

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÆÄÀÏ ¼ÒÀ¯ÀÚ¸¦ ÀÌ¿ëÇÑ ±ÇÇѺο©
    »óÅÂ:Extension
    ¸ðµâ¸í:authz_owner_module
    ¼Ò½ºÆÄÀÏ:mod_authz_owner.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº HTTP ÀÎÁõ¿¡ »ç¿ëÇÑ »ç¿ëÀÚ ¾ÆÀ̵ð(À¥ »ç¿ëÀÚ + ¾ÆÀ̵ð)¸¦ ¿äûÇÑ ÆÄÀÏÀÇ ÆÄÀϽýºÅÛ ¼ÒÀ¯ÀÚ/±×·ì°ú ºñ±³ÇÏ¿© + ÆÄÀÏÀÇ Á¢±Ù±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù. ¿©±â¼­ »ç¿ëÀÚ¸í°ú ¾ÏÈ£´Â ÀÌ¹Ì + mod_auth_basicÀ̳ª + mod_auth_digest °°Àº ÀÎÁõ¸ðµâÀÇ È®ÀÎÀ» + °ÅÃÆ´Ù. mod_authz_owner´Â Require Áö½Ã¾îÀÇ ´ÙÀ½ µÎ ¾Æ±Ô¸ÕÆ®, + file-owner¿Í file-groupÀ» ó¸®ÇÑ´Ù:

    + +
    +
    file-owner
    +
    À¥ »ç¿ëÀÚ¸íÀÌ ¿äûÇÑ ÆÄÀÏ ¼ÒÀ¯ÀÚÀÇ ½Ã½ºÅÛ À̸§°ú °°¾Æ¾ß + ÇÑ´Ù. Áï, ¿î¿µÃ¼Á¦°¡ ¿äûÇÑ ÆÄÀÏÀÇ ¼ÒÀ¯ÀÚ°¡ + jones¶ó¸é, À¥À» ÅëÇØ ÆÄÀÏ¿¡ Á¢±ÙÇÏ´Â »ç¿ëÀÚµµ + ¸¶Âù°¡Áö·Î jonesÀ̾î¾ß ÇÑ´Ù.
    + +
    file-group
    +
    ÆÄÀÏÀ» ¼ÒÀ¯ÇÑ ½Ã½ºÅÛ ±×·ì¸íÀÌ + mod_authz_groupfileÀ̳ª + mod_authz_dbm°ú °°Àº ±×·ì µ¥ÀÌÅͺ£À̽º¿¡ + ÀÖ°í, À¥ »ç¿ëÀÚ¸íÀÌ ÇØ´ç ±×·ì¿¡ ¼ÓÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¿î¿µÃ¼Á¦°¡ ¿äûÇÑ ÆÄÀÏÀ» accounts (½Ã½ºÅÛ) + ±×·ìÀÌ ¼ÒÀ¯ÇÏ°í ÀÖ´Ù¸é, ±×·ì µ¥ÀÌÅͺ£À̽º¿¡ + accounts¶ó´Â ±×·ìÀÌ ÀÖ°í ¿äû¿¡ »ç¿ëÇÑ À¥ + »ç¿ëÀÚ¸íÀÌ ±× ±×·ì¿¡ ¼ÓÇØ¾ß ÇÑ´Ù.
    +
    + +

    ÁÖÀÇ

    +

    mod_authz_owner°¡ ½ÇÁ¦·Î ÆÄÀϽýºÅÛ¿¡ + ÀÖÁö ¾Ê´Â ÀÚ¿øÀ» (Áï, °¡»ó ÀÚ¿ø) ±ÇÇѺο©ÇÑ´Ù¸é, + Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    ƯÈ÷ ³»¿ëÇù»óÇÑ + "MultiViews" ÀÚ¿øÀ» ±ÇÇѺο©ÇÏÁö ¾Ê´Â´Ù.

    +
    +
    +

    Áö½Ã¾îµé

    + +

    ÁÖÁ¦

    +

    Âü°í

    +
    +
    top
    +
    +

    ¼³Á¤ ¿¹Á¦

    + +

    Require file-owner

    +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¿î¿µÇÏ´Â ´ÙÁß»ç¿ëÀÚ ½Ã½ºÅÛ¿¡¼­ °¢ »ç¿ëÀÚ°¡ + ~/public_html/private¿¡ ÀÚ½ÅÀÇ ÆÄÀÏÀ» ÀúÀåÇÑ´Ù°í + °¡Á¤ÇÏÀÚ. ¸ðµç À¥ »ç¿ëÀÚ¸íÀ» ÀúÀåÇÏ´Â AuthDBMUserFile + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ°í, ¿©±â¿¡ ÀúÀåµÈ »ç¿ëÀÚ¸íÀº ¼­¹ö¿¡¼­ + ½ÇÁ¦ ÆÄÀÏÀ» ¼ÒÀ¯ÇÏ´Â ½Ã½ºÅÛ »ç¿ëÀÚ¸í°ú µ¿ÀÏÇÏ´Ù. ÀÌ °æ¿ì + ¾Æ·¡ ¼³Á¤Àº ÆÄÀÏ ¼ÒÀ¯ÀÚ¿¡°Ô¸¸ Á¢±ÙÀ» Çã¿ëÇÑ´Ù. »ç¿ëÀÚ + jones´Â ÆÄÀÏÀ» jones°¡ ¾Æ´Ñ + smith°¡ ¼ÒÀ¯ÇÏ°í ÀÖ´Â ÇÑ + /home/smith/public_html/private¿¡ ÀÖ´Â ÆÄÀÏ¿¡ + Á¢±ÙÇÒ ¼ö ¾ø´Ù.

    + +

    + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +

    + + +

    Require file-group

    +

    À§¿Í »óȲÀÌ ºñ½ÁÇÏÁö¸¸ ¿©·¯¸íÀÌ + ~/public_html/project-foo¿¡ ÇÁ·ÎÁ§Æ® ÆÄÀÏÀ» + °øÀ¯ÇÑ´Ù°í °¡Á¤ÇÏÀÚ. ÆÄÀϵéÀº ½Ã½ºÅÛ ±×·ì foo°¡ + ¼ÒÀ¯Çϸç, ¸ðµç À¥ »ç¿ëÀÚ¸í°ú »ç¿ëÀÚ ±×·ìÀ» ±â·ÏÇÏ´Â AuthDBMGroupFile + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ´Ù. Áï, ÃÖ¼ÒÇÑ foo¶ó´Â + ±×·ì¿¡ ±¸¼º¿øÀÌ ÀÖ´Ù. jones¿Í + smith°¡ ¸ðµÎ ±×·ì fooÀÇ + ±¸¼º¿øÀ̶ó¸é, µÑ ¸ðµÎ project-foo µð·ºÅ丮¿¡ + Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    + +

    + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +

    + +
    +
    top
    +

    AuthzOwnerAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthzOwnerAuthoritative On|Off
    ±âº»°ª:AuthzOwnerAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Extension
    ¸ðµâ:mod_authz_owner
    +

    AuthzOwnerAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤ÇÏ¸é ´ÙÀ½°ú °°Àº °æ¿ì »ç¿ëÀÚ + ±ÇÇѺο©¸¦ (modules.c ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ + ¸ðµâ·Î ³Ñ°ÜÁØ´Ù.

    + +
      +
    • file-owner¸¦ »ç¿ëÇϸé ÆÄÀϽýºÅÛ ¼ÒÀ¯ÀÚ¸¦ + ¾Ë ¼ö ¾ø°Å³ª ÁÖ¾îÁø À¥ »ç¿ëÀÚ¸í°ú ´Ù¸¥ °æ¿ì
    • + +
    • file-groupÀ» »ç¿ëÇϸé ÆÄÀϽýºÅÛ ±×·ìÀ» + ¾Ë ¼ö ¾ø°Å³ª ÁÖ¾îÁø À¥ »ç¿ëÀÚ¸íÀÌ ±¸¼º¿øÀÌ ¾Æ´Ñ °æ¿ì.
    • +
    + +

    ¶Ç, °ªÀ» Off·Î ¼³Á¤Çϸé + file-owner¿Í file-groupÀ» °áÇÕÇÏ¿©, + µÑ Áß Çϳª¸¸ ¸¸Á·Çصµ Á¢±ÙÀ» Çã°¡ÇÑ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ Off·Î ¼³Á¤ÇÏÁö¾ÊÀ¸¸é + ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_owner.xml b/trunk/docs/manual/mod/mod_authz_owner.xml new file mode 100644 index 0000000000..66e68954fe --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.xml @@ -0,0 +1,170 @@ + + + + + + + + + +mod_authz_owner +Authorization based on file ownership +Extension +mod_authz_owner.c +authz_owner_module +Available in Apache 2.1 and later + + +

    This module authorizes access to files by comparing the userid used + for HTTP authentication (the web userid) with the file-system owner or + group of the requested file. The supplied username and password + must be already properly verified by an authentication module, + such as mod_auth_basic or + mod_auth_digest. mod_authz_owner + recognizes two arguments for the Require directive, file-owner and + file-group, as follows:

    + +
    +
    file-owner
    +
    The supplied web-username must match the system's name for the + owner of the file being requested. That is, if the operating system + says the requested file is owned by jones, then the + username used to access it through the web must be jones + as well.
    + +
    file-group
    +
    The name of the system group that owns the file must be present + in a group database, which is provided, for example, by mod_authz_groupfile or mod_authz_dbm, + and the web-username must be a member of that group. For example, if + the operating system says the requested file is owned by (system) + group accounts, the group accounts must + appear in the group database and the web-username used in the request + must be a member of that group.
    +
    + + Note +

    If mod_authz_owner is used in order to authorize + a resource that is not actually present in the filesystem + (i.e. a virtual resource), it will deny the access.

    + +

    Particularly it will never authorize content negotiated + "MultiViews" resources.

    +
    +
    +Require +Satisfy + +
    Configuration Examples + +
    Require file-owner +

    Consider a multi-user system running the Apache Web server, with + each user having his or her own files in ~/public_html/private. Assuming that there is a single + AuthDBMUserFile database + that lists all of their web-usernames, and that these usernames match + the system's usernames that actually own the files on the server, then + the following stanza would allow only the user himself access to his + own files. User jones would not be allowed to access + files in /home/smith/public_html/private unless they + were owned by jones instead of smith.

    + + + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +
    +
    + +
    Require file-group +

    Consider a system similar to the one described above, but with + some users that share their project files in + ~/public_html/project-foo. The files are owned by the + system group foo and there is a single AuthDBMGroupFile database that + contains all of the web-usernames and their group membership, + i.e. they must be at least member of a group named + foo. So if jones and smith + are both member of the group foo, then both will be + authorized to access the project-foo directories of + each other.

    + + + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +
    +
    +
    + + +AuthzOwnerAuthoritative +Sets whether authorization will be passed on to lower level +modules +AuthzOwnerAuthoritative On|Off +AuthzOwnerAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthzOwnerAuthoritative + directive explicitly to Off allows for + user authorization to be passed on to lower level modules (as defined + in the modules.c files) if:

    + +
      +
    • in the case of file-owner the file-system owner does not + match the supplied web-username or could not be determined, or
    • + +
    • in the case of file-group the file-system group does not + contain the supplied web-username or could not be determined.
    • +
    + +

    Note that setting the value to Off also allows the + combination of file-owner and file-group, so + access will be allowed if either one or the other (or both) match.

    + +

    By default, control is not passed on and an authorization failure + will result in an "Authentication Required" reply. Not + setting it to Off thus keeps the system secure and forces + an NCSA compliant behaviour.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_owner.xml.ja b/trunk/docs/manual/mod/mod_authz_owner.xml.ja new file mode 100644 index 0000000000..6233bbdfec --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.xml.ja @@ -0,0 +1,169 @@ + + + + + + + + + +mod_authz_owner +$B%U%!%$%k$N=jM-5G'(B +Extension +mod_authz_owner.c +authz_owner_module +Apache 2.1 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%b%8%e!<%k$O%j%/%(%9%H$5$l$?%U%!%$%k$N%U%!%$%k%7%9%F%`$N(B + $B=jM-Z$K;H$o$l$?%f!<%6(B ID ($B%&%'%V%f!<%6(B ID) $B$H(B + $BHf3S$9$k$3$H$G%"%/%;%9$r>5G'$7$^$9!#Ds6!$5$l$?%f!<%6L>$H%Q%9%o!<%I$O(B + mod_auth_basic $B$d(B + mod_auth_digest $B$N$h$&$JG'>Z%b%8%e!<%k$G4{$K(B + $BE,@Z$K8!>Z$5$l$F$$$kI,MW$,$"$j$^$9!#(Bmod_authz_owner + $B$O0J2<$N$h$&$K!"(BRequire $B%G%#%l%/%F%#%V$N(B file-owner $B$H(B + file-group $B$H$$$&Fs$D$N0z?t$rG'<1$7$^$9(B:

    + +
    +
    file-owner
    +
    $BDs6!$5$l$?%&%'%V%f!<%6L>$O%j%/%(%9%H$5$l$?%U%!%$%k$N=jM-A0$H0lCW$9$kI,MW$,$"$j$^$9!#$D$^$j!"%*%Z%l!<%F%#%s%0(B + $B%7%9%F%`$,%U%!%$%k$O(B jones $B$K$h$j=jM-$5$l$F$$$k(B + $B$H8@$C$?$H$-$O!"%&%'%V$+$i$N%"%/%;%9$K;H$o$l$k%f!<%6L>$b(B + jones $B$G$J$1$l$P$J$j$^$;$s!#(B
    + +
    file-group
    +
    $B%U%!%$%k$r=jM-$9$k%7%9%F%`$N%0%k!<%W$NL>A0$,!"Nc$($P(B + mod_authz_groupfile $B$d(B mod_authz_dbm + $B$K$h$jDs6!$5$l$k%0%k!<%W%G!<%?%Y!<%9$KB8:_$7$F$$$F!"(B + $B%&%'%V%f!<%6L>$,$=$N%0%k!<%W$KB0$7$F$$$J$1$l$P$J$j$^$;$s!#(B + $BNc$($P!"%*%Z%l!<%F%#%s%0%7%9%F%`$,%U%!%$%k$O(B ($B%7%9%F%`$N(B) $B%0%k!<%W(B + accounts $B$K$h$j=jM-$5$l$F$$$k$H8@$C$?$H$-$O!"(B + accounts $B$,%0%k!<%W%G!<%?%Y!<%9$KB8:_$7$F!"(B + $B%j%/%(%9%H$K;HMQ$5$l$?%&%'%V%f!<%6L>$,$=$N%0%k!<%W$KB0$7$F$$$k(B + $BI,MW$,$"$j$^$9!#(B
    +
    + + $BCm(B +

    $B%U%!%$%k%7%9%F%`$K$B$D$^$j(B $B%P!<%A%c%k$J%j%=!<%9(B) $B$N>5G'$K(B + mod_authz_owner $B$,;HMQ$5$l$?$H$-$O!"(B + $B%"%/%;%9$O5qH]$5$l$^$9!#(B

    + +

    $BFC$K!"(B$B%3%s%F%s%H(B + $B%M%4%7%(!<%7%g%s$5$l$?(B"MultiViews" $B$N%j%=!<%9$O(B + $B7h$7$F>5G'$7$^$;$s!#(B

    +
    +
    +Require +Satisfy + +
    $B@_DjNc(B + +
    Require file-owner +

    $BJ#?t%f!<%6$N%7%9%F%`$G(B Apache $B%&%'%V%5!<%P$,~/public_html/private $B$K3F%f!<%6$,%U%!%$%k$rCV$$$F$$$k$H$7$^$9!#(B + AuthDBMUserFile + $B%G!<%?%Y!<%9$,0l$D$@$1$"$j!"$9$Y$F$N%&%'%V%f!<%6L>$,Ns5s$5$l$F$*$j!"(B + $B$3$N%f!<%6L>$,%5!<%P$G$H0lCW$7$F$$$k>l9g!"(B + $B/home/smith/public_html/private $B$NCf$N%U%!%$%k$O!"=jM-smith $B$NBe$o$j$K(B jones $B$K$J$C$F$$$J$$8B$j!"(B + jones $B$K$O%"%/%;%9$O5v2D$5$l$^$;$s!#(B

    + + + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +
    +
    + +
    Require file-group +

    $B>e5-$N$h$&$J%7%9%F%`$G!"?t?M$N%f!<%6$,%W%m%8%'%/%H$N%U%!%$%k$r(B + ~/public_html/project-foo $B$G6&M-$7$F$$$k$H$7$^$9!#(B + $B%U%!%$%k$O%7%9%F%`$N%0%k!<%W(B foo $B$K=jM-$5$l$F$$$F!"(B + AuthDBMGroupFile + $B%G!<%?%Y!<%9$,0l$D$@$1$"$j!"$=$3$K$9$Y$F$N%&%'%V%f!<%6L>$H(B + $B%0%k!<%W$N%a%s%P$,Ns5s$5$l$F$$$k!"(B$B$D$^$j(B$B!"$=$l$i$N(B + $B%f!<%6$O>/$J$/$H$b(B foo $B$H$$$&%0%k!<%W$KB0$7$F$$$k!"$H$7$^$9!#(B + jones $B$H(Bsmith $B$NFs?M6&$,%0%k!<%W(B + foo $B$N%a%s%P$G$"$k>l9g!"$I$A$i$N?M$bN>J}$N(B + project-foo $B$K%"%/%;%9$,5v2D$5$l$^$9!#(B

    + + + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +
    +
    +
    + + +AuthzOwnerAuthoritative +$B>5G'$,2<0L>5G'%b%8%e!<%k$KEO$5$l$k$+$I$&$+$r@_Dj$9$k(B +AuthzOwnerAuthoritative On|Off +AuthzOwnerAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzOwnerAuthoritative $B%G%#%l%/%F%#%V$r(B + $BL@<(E*$K(B Off $B$K@_Dj$9$k$H!"0J2<$N>l9g$KG'>Z$,(B + (modules.c $B$GDj5A$5$l$F$$$k(B) $B2<0L$N%b%8%e!<%k$K(B + $BEO$5$l$k$h$&$K$7$^$9(B:

    + +
      +
    • file-owner $B$N>l9g$O!"Ds6!$5$l$?%&%'%V%f!<%6L>$K(B + $B%U%!%$%k%7%9%F%`$N=jM-l9g!#(B
    • + +
    • file-group $B$N>l9g$O!"Ds6!$5$l$?%&%'%V%f!<%6L>$,(B + $B%U%!%$%k%7%9%F%`%0%k!<%W$KB8:_$7$J$$$+!"$o$+$i$J$$>l9g!#(B
    • +
    + +

    $BCM$r(B Off $B$K@_Dj$9$k$H!"(Bfile-owner $B$H(B + file-group $B$rAH$_9g$o$;$k$3$H$b$G$-$k$h$&$K$J$j!"(B + $B$=$N>l9g$O$I$A$i$+(B ($BN>J}$G$b(B) $B$K%^%C%A$7$?>l9g$K%"%/%;%9$r5v2D$5$l$^$9!#(B

    + +

    $B%G%U%)%k%H$G$O@)8f$OEO$5$l$:!"L$CN$N%0%k!<%W$N>l9g$O(B Authentication + Required $B1~Ez$,JV$5$l$^$9!#$G$9$+$i!"(BOff $B$K@_Dj$7$J$$$3$H$G(B + $B%7%9%F%`$r0BA4$KJ]$D$3$H$,$G$-!"(BNCSA $B8_49$N?6$kIq$$$r$5$;$k$3$H$K$J$j$^$9!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_owner.xml.ko b/trunk/docs/manual/mod/mod_authz_owner.xml.ko new file mode 100644 index 0000000000..e0b675230b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.xml.ko @@ -0,0 +1,166 @@ + + + + + + + + + +mod_authz_owner +ÆÄÀÏ ¼ÒÀ¯ÀÚ¸¦ ÀÌ¿ëÇÑ ±ÇÇѺο© +Extension +mod_authz_owner.c +authz_owner_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº HTTP ÀÎÁõ¿¡ »ç¿ëÇÑ »ç¿ëÀÚ ¾ÆÀ̵ð(À¥ »ç¿ëÀÚ + ¾ÆÀ̵ð)¸¦ ¿äûÇÑ ÆÄÀÏÀÇ ÆÄÀϽýºÅÛ ¼ÒÀ¯ÀÚ/±×·ì°ú ºñ±³ÇÏ¿© + ÆÄÀÏÀÇ Á¢±Ù±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù. ¿©±â¼­ »ç¿ëÀÚ¸í°ú ¾ÏÈ£´Â ÀÌ¹Ì + mod_auth_basicÀ̳ª + mod_auth_digest °°Àº ÀÎÁõ¸ðµâÀÇ È®ÀÎÀ» + °ÅÃÆ´Ù. mod_authz_owner´Â Require Áö½Ã¾îÀÇ ´ÙÀ½ µÎ ¾Æ±Ô¸ÕÆ®, + file-owner¿Í file-groupÀ» ó¸®ÇÑ´Ù:

    + +
    +
    file-owner
    +
    À¥ »ç¿ëÀÚ¸íÀÌ ¿äûÇÑ ÆÄÀÏ ¼ÒÀ¯ÀÚÀÇ ½Ã½ºÅÛ À̸§°ú °°¾Æ¾ß + ÇÑ´Ù. Áï, ¿î¿µÃ¼Á¦°¡ ¿äûÇÑ ÆÄÀÏÀÇ ¼ÒÀ¯ÀÚ°¡ + jones¶ó¸é, À¥À» ÅëÇØ ÆÄÀÏ¿¡ Á¢±ÙÇÏ´Â »ç¿ëÀÚµµ + ¸¶Âù°¡Áö·Î jonesÀ̾î¾ß ÇÑ´Ù.
    + +
    file-group
    +
    ÆÄÀÏÀ» ¼ÒÀ¯ÇÑ ½Ã½ºÅÛ ±×·ì¸íÀÌ + mod_authz_groupfileÀ̳ª + mod_authz_dbm°ú °°Àº ±×·ì µ¥ÀÌÅͺ£À̽º¿¡ + ÀÖ°í, À¥ »ç¿ëÀÚ¸íÀÌ ÇØ´ç ±×·ì¿¡ ¼ÓÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¿î¿µÃ¼Á¦°¡ ¿äûÇÑ ÆÄÀÏÀ» accounts (½Ã½ºÅÛ) + ±×·ìÀÌ ¼ÒÀ¯ÇÏ°í ÀÖ´Ù¸é, ±×·ì µ¥ÀÌÅͺ£À̽º¿¡ + accounts¶ó´Â ±×·ìÀÌ ÀÖ°í ¿äû¿¡ »ç¿ëÇÑ À¥ + »ç¿ëÀÚ¸íÀÌ ±× ±×·ì¿¡ ¼ÓÇØ¾ß ÇÑ´Ù.
    +
    + + ÁÖÀÇ +

    mod_authz_owner°¡ ½ÇÁ¦·Î ÆÄÀϽýºÅÛ¿¡ + ÀÖÁö ¾Ê´Â ÀÚ¿øÀ» (Áï, °¡»ó ÀÚ¿ø) ±ÇÇѺο©ÇÑ´Ù¸é, + Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    ƯÈ÷ ³»¿ëÇù»óÇÑ + "MultiViews" ÀÚ¿øÀ» ±ÇÇѺο©ÇÏÁö ¾Ê´Â´Ù.

    +
    +
    +Require +Satisfy + +
    ¼³Á¤ ¿¹Á¦ + +
    Require file-owner +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¿î¿µÇÏ´Â ´ÙÁß»ç¿ëÀÚ ½Ã½ºÅÛ¿¡¼­ °¢ »ç¿ëÀÚ°¡ + ~/public_html/private¿¡ ÀÚ½ÅÀÇ ÆÄÀÏÀ» ÀúÀåÇÑ´Ù°í + °¡Á¤ÇÏÀÚ. ¸ðµç À¥ »ç¿ëÀÚ¸íÀ» ÀúÀåÇÏ´Â AuthDBMUserFile + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ°í, ¿©±â¿¡ ÀúÀåµÈ »ç¿ëÀÚ¸íÀº ¼­¹ö¿¡¼­ + ½ÇÁ¦ ÆÄÀÏÀ» ¼ÒÀ¯ÇÏ´Â ½Ã½ºÅÛ »ç¿ëÀÚ¸í°ú µ¿ÀÏÇÏ´Ù. ÀÌ °æ¿ì + ¾Æ·¡ ¼³Á¤Àº ÆÄÀÏ ¼ÒÀ¯ÀÚ¿¡°Ô¸¸ Á¢±ÙÀ» Çã¿ëÇÑ´Ù. »ç¿ëÀÚ + jones´Â ÆÄÀÏÀ» jones°¡ ¾Æ´Ñ + smith°¡ ¼ÒÀ¯ÇÏ°í ÀÖ´Â ÇÑ + /home/smith/public_html/private¿¡ ÀÖ´Â ÆÄÀÏ¿¡ + Á¢±ÙÇÒ ¼ö ¾ø´Ù.

    + + + <Directory /home/*/public_html/private>
    + + AuthType Basic
    + AuthName MyPrivateFiles
    + AuthBasicProvider dbm
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + Satisfy All
    + Require file-owner
    +
    + </Directory> +
    +
    + +
    Require file-group +

    À§¿Í »óȲÀÌ ºñ½ÁÇÏÁö¸¸ ¿©·¯¸íÀÌ + ~/public_html/project-foo¿¡ ÇÁ·ÎÁ§Æ® ÆÄÀÏÀ» + °øÀ¯ÇÑ´Ù°í °¡Á¤ÇÏÀÚ. ÆÄÀϵéÀº ½Ã½ºÅÛ ±×·ì foo°¡ + ¼ÒÀ¯Çϸç, ¸ðµç À¥ »ç¿ëÀÚ¸í°ú »ç¿ëÀÚ ±×·ìÀ» ±â·ÏÇÏ´Â AuthDBMGroupFile + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ´Ù. Áï, ÃÖ¼ÒÇÑ foo¶ó´Â + ±×·ì¿¡ ±¸¼º¿øÀÌ ÀÖ´Ù. jones¿Í + smith°¡ ¸ðµÎ ±×·ì fooÀÇ + ±¸¼º¿øÀ̶ó¸é, µÑ ¸ðµÎ project-foo µð·ºÅ丮¿¡ + Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    + + + <Directory /home/*/public_html/project-foo>
    + + AuthType Basic
    + AuthName "Project Foo Files"
    + AuthBasicProvider dbm
    +
    + # combined user/group database
    + AuthDBMUserFile /usr/local/apache2/etc/.htdbm-all
    + AuthDBMGroupFile /usr/local/apache2/etc/.htdbm-all
    +
    + Satisfy All
    + Require file-group
    +
    + </Directory> +
    +
    +
    + + +AuthzOwnerAuthoritative +±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthzOwnerAuthoritative On|Off +AuthzOwnerAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzOwnerAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤ÇÏ¸é ´ÙÀ½°ú °°Àº °æ¿ì »ç¿ëÀÚ + ±ÇÇѺο©¸¦ (modules.c ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ + ¸ðµâ·Î ³Ñ°ÜÁØ´Ù.

    + +
      +
    • file-owner¸¦ »ç¿ëÇϸé ÆÄÀϽýºÅÛ ¼ÒÀ¯ÀÚ¸¦ + ¾Ë ¼ö ¾ø°Å³ª ÁÖ¾îÁø À¥ »ç¿ëÀÚ¸í°ú ´Ù¸¥ °æ¿ì
    • + +
    • file-groupÀ» »ç¿ëÇϸé ÆÄÀϽýºÅÛ ±×·ìÀ» + ¾Ë ¼ö ¾ø°Å³ª ÁÖ¾îÁø À¥ »ç¿ëÀÚ¸íÀÌ ±¸¼º¿øÀÌ ¾Æ´Ñ °æ¿ì.
    • +
    + +

    ¶Ç, °ªÀ» Off·Î ¼³Á¤Çϸé + file-owner¿Í file-groupÀ» °áÇÕÇÏ¿©, + µÑ Áß Çϳª¸¸ ¸¸Á·Çصµ Á¢±ÙÀ» Çã°¡ÇÑ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â ±×·ìÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ Off·Î ¼³Á¤ÇÏÁö¾ÊÀ¸¸é + ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_owner.xml.meta b/trunk/docs/manual/mod/mod_authz_owner.xml.meta new file mode 100644 index 0000000000..181113fda0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_owner.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authz_owner + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_authz_user.html b/trunk/docs/manual/mod/mod_authz_user.html new file mode 100644 index 0000000000..bbf7fe111d --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.html @@ -0,0 +1,11 @@ +URI: mod_authz_user.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_authz_user.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_authz_user.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_authz_user.html.en b/trunk/docs/manual/mod/mod_authz_user.html.en new file mode 100644 index 0000000000..565b05390b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.html.en @@ -0,0 +1,84 @@ + + + +mod_authz_user - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_authz_user

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:User Authorization
    Status:Base
    Module Identifier:authz_user_module
    Source File:mod_authz_user.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site. mod_authz_user grants + access if the authenticated user is listed in a Require user + directive. Alternatively require valid-user can be used to + grant access to all successfully authenticated users.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    AuthzUserAuthoritative Directive

    + + + + + + + + +
    Description:Sets whether authorization will be passed on to lower level +modules
    Syntax:AuthzUserAuthoritative On|Off
    Default:AuthzUserAuthoritative On
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Base
    Module:mod_authz_user
    +

    Setting the AuthzUserAuthoritative + directive explicitly to Off allows for + user authorization to be passed on to lower level modules (as defined + in the modules.c files) if there is no + user matching the supplied userID.

    + +

    By default, control is not passed on and an unknown user + will result in an Authentication Required reply. Not + setting it to Off thus keeps the system secure and forces + an NCSA compliant behaviour.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_user.html.ja.euc-jp b/trunk/docs/manual/mod/mod_authz_user.html.ja.euc-jp new file mode 100644 index 0000000000..933fbc14ce --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.html.ja.euc-jp @@ -0,0 +1,83 @@ + + + +mod_authz_user - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_authz_user

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥æ¡¼¥¶¾µÇ§
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:authz_user_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_authz_user.c
    ¸ß´¹À­:Apache 2.1 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢Ç§¾Ú¤µ¤ì¤¿¥æ¡¼¥¶¤Ë¥¦¥§¥Ö¥µ¥¤¥È¤Î°ìÉô¤Ø¤Î + ¥¢¥¯¥»¥¹¤òµö²Ä¤·¤¿¤êµñÈݤ·¤¿¤ê¤¹¤ë¤¿¤á¤Î¾µÇ§µ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£ + mod_authz_user ¤Ïǧ¾Ú¤µ¤ì¤¿¥æ¡¼¥¶¤¬ + Require user ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë½ñ¤«¤ì¤Æ¤¤¤ì¤Ð + ¥¢¥¯¥»¥¹¤òǧ¤á¤Þ¤¹¡£Ç§¾Ú¤ËÀ®¸ù¤·¤¿¥æ¡¼¥¶¤¹¤Ù¤Æ¤Ë¥¢¥¯¥»¥¹¤ò + µö²Ä¤¹¤ë¤Ë¤Ï¡¢Âå¤ï¤ê¤Ë require valid-user ¤ò + »È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    AuthzUserAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¾µÇ§¤¬²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    ¹½Ê¸:AuthzUserAuthoritative On|Off
    ¥Ç¥Õ¥©¥ë¥È:AuthzUserAuthoritative On
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:AuthConfig
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_authz_user
    +

    AuthzUserAuthoritative ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÌÀ¼¨Åª¤Ë Off ¤ËÀßÄꤹ¤ë¤È userID ¤ËÂбþ¤¹¤ë + ¥°¥ë¡¼¥×¤¬¤Ê¤¤¾ì¹ç¤Ë¡¢ + (module.c ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë) ²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤Ë¥°¥ë¡¼¥×¾µÇ§¤ò + ÅϤ¹¤³¤È¤òµö²Ä¤·¤Þ¤¹¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏÀ©¸æ¤ÏÅϤµ¤ì¤º¡¢Ì¤ÃΤΥ°¥ë¡¼¥×¤Î¾ì¹ç¤Ï Authentication + Required ±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¤³¤ì¤òÀßÄꤷ¤Ê¤¤¤È + ¥·¥¹¥Æ¥à¤ò°ÂÁ´¤ËÊݤĤ³¤È¤¬¤Ç¤­¡¢NCSA ¸ß´¹¤Î¿¶¤ëÉñ¤¤¤ò¤µ¤»¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_user.html.ko.euc-kr b/trunk/docs/manual/mod/mod_authz_user.html.ko.euc-kr new file mode 100644 index 0000000000..745970cb75 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.html.ko.euc-kr @@ -0,0 +1,81 @@ + + + +mod_authz_user - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_authz_user

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:»ç¿ëÀÚ ±ÇÇѺο©
    »óÅÂ:Base
    ¸ðµâ¸í:authz_user_module
    ¼Ò½ºÆÄÀÏ:mod_authz_user.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ±ÇÇÑÀ» ºÎ¿©ÇÏ¿©, ÀÎÁõÇÑ »ç¿ëÀÚ°¡ À¥»çÀÌÆ®ÀÇ + ÀϺο¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö °áÁ¤ÇÑ´Ù. + mod_authz_user´Â Require user + Áö½Ã¾î ¸ñ·Ï¿¡ ÀÎÁõÇÑ »ç¿ëÀÚ°¡ µé¾îÀÖÀ¸¸é Á¢±ÙÀ» Çã¿ëÇÑ´Ù. + ¶Ç, require valid-user´Â ¼º°øÀûÀ¸·Î ÀÎÁõÇÑ + »ç¿ëÀÚ ¸ðµÎ¿¡°Ô Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    AuthzUserAuthoritative Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    ¹®¹ý:AuthzUserAuthoritative On|Off
    ±âº»°ª:AuthzUserAuthoritative On
    »ç¿ëÀå¼Ò:directory, .htaccess
    Override ¿É¼Ç:AuthConfig
    »óÅÂ:Base
    ¸ðµâ:mod_authz_user
    +

    AuthzUserAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ°¡ + ¾ø´Â °æ¿ì »ç¿ëÀÚ ±ÇÇѺο©¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â »ç¿ëÀÚÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ Off·Î ¼³Á¤ÇÏÁö¾ÊÀ¸¸é + ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_authz_user.xml b/trunk/docs/manual/mod/mod_authz_user.xml new file mode 100644 index 0000000000..c9d006971b --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.xml @@ -0,0 +1,67 @@ + + + + + + + + + +mod_authz_user +User Authorization +Base +mod_authz_user.c +authz_user_module +Available in Apache 2.1 and later + + +

    This module provides authorization capabilities so that + authenticated users can be allowed or denied access to portions + of the web site. mod_authz_user grants + access if the authenticated user is listed in a Require user + directive. Alternatively require valid-user can be used to + grant access to all successfully authenticated users.

    +
    +Require +Satisfy + + +AuthzUserAuthoritative +Sets whether authorization will be passed on to lower level +modules +AuthzUserAuthoritative On|Off +AuthzUserAuthoritative On +directory.htaccess + +AuthConfig + + +

    Setting the AuthzUserAuthoritative + directive explicitly to Off allows for + user authorization to be passed on to lower level modules (as defined + in the modules.c files) if there is no + user matching the supplied userID.

    + +

    By default, control is not passed on and an unknown user + will result in an Authentication Required reply. Not + setting it to Off thus keeps the system secure and forces + an NCSA compliant behaviour.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_user.xml.ja b/trunk/docs/manual/mod/mod_authz_user.xml.ja new file mode 100644 index 0000000000..444f1172e8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.xml.ja @@ -0,0 +1,66 @@ + + + + + + + + + +mod_authz_user +$B%f!<%6>5G'(B +Base +mod_authz_user.c +authz_user_module +Apache 2.1 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%b%8%e!<%k$O!"G'>Z$5$l$?%f!<%6$K%&%'%V%5%$%H$N0lIt$X$N(B + $B%"%/%;%9$r5v2D$7$?$j5qH]$7$?$j$9$k$?$a$N>5G'5!G=$rDs6!$7$^$9!#(B + mod_authz_user $B$OG'>Z$5$l$?%f!<%6$,(B + Require user $B%G%#%l%/%F%#%V$K=q$+$l$F$$$l$P(B + $B%"%/%;%9$rG'$a$^$9!#G'>Z$K@.8y$7$?%f!<%6$9$Y$F$K%"%/%;%9$r(B + $B5v2D$9$k$K$O!"Be$o$j$K(B require valid-user $B$r(B + $B;H$&$3$H$,$G$-$^$9!#(B

    +
    +Require +Satisfy + + +AuthzUserAuthoritative +$B>5G'$,2<0L$N%b%8%e!<%k$KEO$5$l$k$+$I$&$+$r@_Dj$9$k(B +AuthzUserAuthoritative On|Off +AuthzUserAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzUserAuthoritative $B%G%#%l%/%F%#%V$r(B + $BL@<(E*$K(B Off $B$K@_Dj$9$k$H(B userID $B$KBP1~$9$k(B + $B%0%k!<%W$,$J$$>l9g$K(B$B!"(B + (module.c $B$GDj5A$5$l$F$$$k(B) $B2<0L$N%b%8%e!<%k$K%0%k!<%W>5G'$r(B + $BEO$9$3$H$r5v2D$7$^$9!#(B

    + +

    $B%G%U%)%k%H$G$O@)8f$OEO$5$l$:!"L$CN$N%0%k!<%W$N>l9g$O(B Authentication + Required $B1~Ez$,JV$5$l$^$9!#$G$9$+$i!"$3$l$r@_Dj$7$J$$$H(B + $B%7%9%F%`$r0BA4$KJ]$D$3$H$,$G$-!"(BNCSA $B8_49$N?6$kIq$$$r$5$;$k$3$H$K$J$j$^$9!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_user.xml.ko b/trunk/docs/manual/mod/mod_authz_user.xml.ko new file mode 100644 index 0000000000..ce1ac16c6f --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.xml.ko @@ -0,0 +1,64 @@ + + + + + + + + + +mod_authz_user +»ç¿ëÀÚ ±ÇÇѺο© +Base +mod_authz_user.c +authz_user_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ±ÇÇÑÀ» ºÎ¿©ÇÏ¿©, ÀÎÁõÇÑ »ç¿ëÀÚ°¡ À¥»çÀÌÆ®ÀÇ + ÀϺο¡ Á¢±ÙÇÒ ¼ö ÀÖ´ÂÁö °áÁ¤ÇÑ´Ù. + mod_authz_user´Â Require user + Áö½Ã¾î ¸ñ·Ï¿¡ ÀÎÁõÇÑ »ç¿ëÀÚ°¡ µé¾îÀÖÀ¸¸é Á¢±ÙÀ» Çã¿ëÇÑ´Ù. + ¶Ç, require valid-user´Â ¼º°øÀûÀ¸·Î ÀÎÁõÇÑ + »ç¿ëÀÚ ¸ðµÎ¿¡°Ô Á¢±ÙÀ» Çã¿ëÇÑ´Ù.

    +
    +Require +Satisfy + + +AuthzUserAuthoritative +±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ +AuthzUserAuthoritative On|Off +AuthzUserAuthoritative On +directory.htaccess + +AuthConfig + + +

    AuthzUserAuthoritative Áö½Ã¾î¸¦ + Á÷Á¢ Off·Î ¼³Á¤Çϸé ÇØ´ç »ç¿ëÀÚ°¡ + ¾ø´Â °æ¿ì »ç¿ëÀÚ ±ÇÇѺο©¸¦ (modules.c + ÆÄÀÏ¿¡¼­ Á¤ÀÇÇÑ) Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁØ´Ù.

    + +

    ±âº»ÀûÀ¸·Î Á¦¾î¸¦ ³Ñ±âÁö¾Ê°í, ¸ð¸£´Â »ç¿ëÀÚÀÇ °æ¿ì ÀÎÁõ + ÇÊ¿ä ÀÀ´äÀ» ÇÑ´Ù. ÀÌ Áö½Ã¾î¸¦ Off·Î ¼³Á¤ÇÏÁö¾ÊÀ¸¸é + ½Ã½ºÅÛÀÌ ¾ÈÀüÇÏ°Ô À¯ÁöµÇ¸ç, NCSA À¥¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_authz_user.xml.meta b/trunk/docs/manual/mod/mod_authz_user.xml.meta new file mode 100644 index 0000000000..eb2e5157a4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_authz_user.xml.meta @@ -0,0 +1,13 @@ + + + + mod_authz_user + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_autoindex.html b/trunk/docs/manual/mod/mod_autoindex.html new file mode 100644 index 0000000000..16baec2f69 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.html @@ -0,0 +1,11 @@ +URI: mod_autoindex.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_autoindex.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_autoindex.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_autoindex.html.en b/trunk/docs/manual/mod/mod_autoindex.html.en new file mode 100644 index 0000000000..cdc25e91f5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.html.en @@ -0,0 +1,893 @@ + + + +mod_autoindex - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_autoindex

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Generates directory indexes, + automatically, similar to the Unix ls command or the + Win32 dir shell command
    Status:Base
    Module Identifier:autoindex_module
    Source File:mod_autoindex.c
    +

    Summary

    + +

    The index of a directory can come from one of two + sources:

    + +
      +
    • A file written by the user, typically called + index.html. The DirectoryIndex directive sets the + name of this file. This is controlled by + mod_dir.
    • + +
    • Otherwise, a listing generated by the server. The other + directives control the format of this listing. The AddIcon, AddIconByEncoding and + AddIconByType are + used to set a list of icons to display for various file types; + for each file listed, the first icon listed that matches the + file is displayed. These are controlled by + mod_autoindex.
    • +
    +

    The two functions are separated so that you can completely + remove (or replace) automatic index generation should you want + to.

    + +

    Automatic index generation is enabled with using + Options +Indexes. See the + Options directive for + more details.

    + +

    If the FancyIndexing option is given with the IndexOptions directive, + the column headers are links that control the order of the + display. If you select a header link, the listing will be + regenerated, sorted by the values in that column. Selecting the + same header repeatedly toggles between ascending and descending + order. These column header links are suppressed with + IndexOptions directive's + SuppressColumnSorting option.

    + +

    Note that when the display is sorted by "Size", it's the + actual size of the files that's used, not the + displayed value - so a 1010-byte file will always be displayed + before a 1011-byte file (if in ascending order) even though + they both are shown as "1K".

    +
    + +
    top
    +
    +

    Autoindex Request Query Arguments

    + + +

    Apache 2.0.23 reorganized the Query Arguments for Column + Sorting, and introduced an entire group of new query options. + To effectively eliminate all client control over the output, + the IndexOptions + IgnoreClient option was introduced.

    + +

    The column sorting headers themselves are self-referencing + hyperlinks that add the sort query options shown below. Any + option below may be added to any request for the directory + resource.

    + +
      +
    • C=N sorts the directory by file name
    • + +
    • C=M sorts the directory by last-modified + date, then file name
    • + +
    • C=S sorts the directory by size, then file + name
    • + +
    • C=D sorts the directory by description, then + file name
    • + +
    • O=A sorts the listing in Ascending + Order
    • + +
    • O=D sorts the listing in Descending + Order
    • + +
    • F=0 formats the listing as a simple list + (not FancyIndexed)
    • + +
    • F=1 formats the listing as a FancyIndexed + list
    • + +
    • F=2 formats the listing as an + HTMLTable FancyIndexed list
    • + +
    • V=0 disables version sorting
    • + +
    • V=1 enables version sorting
    • + +
    • P=pattern lists only files matching + the given pattern
    • +
    + +

    Note that the 'P'attern query argument is tested + after the usual IndexIgnore directives are processed, + and all file names are still subjected to the same criteria as + any other autoindex listing. The Query Arguments parser in + mod_autoindex will stop abruptly when an unrecognized + option is encountered. The Query Arguments must be well formed, + according to the table above.

    + +

    The simple example below, which can be clipped and saved in + a header.html file, illustrates these query options. Note that + the unknown "X" argument, for the submit button, is listed last + to assure the arguments are all parsed before mod_autoindex + encounters the X=Go input.

    + +

    + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +

    + +
    +
    top
    +

    AddAlt Directive

    + + + + + + + +
    Description:Alternate text to display for a file, instead of an +icon selected by filename
    Syntax:AddAlt string file [file] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    AddAlt provides the alternate text to + display for a file, instead of an icon, for FancyIndexing. + File is a file extension, partial filename, wild-card + expression or full filename for files to describe. + If String contains any whitespace, you have to enclose it + in quotes (" or '). This alternate text + is displayed if the client is image-incapable, has image loading + disabled, or fails to retrieve the icon.

    + +

    Examples

    + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +

    + +
    +
    top
    +

    AddAltByEncoding Directive

    + + + + + + + +
    Description:Alternate text to display for a file instead of an icon +selected by MIME-encoding
    Syntax:AddAltByEncoding string MIME-encoding +[MIME-encoding] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    AddAltByEncoding provides the alternate + text to display for a file, instead of an icon, for FancyIndexing. + MIME-encoding is a valid content-encoding, such as + x-compress. If String contains any whitespace, + you have to enclose it in quotes (" or '). + This alternate text is displayed if the client is image-incapable, + has image loading disabled, or fails to retrieve the icon.

    + +

    Example

    + AddAltByEncoding gzip x-gzip +

    + +
    +
    top
    +

    AddAltByType Directive

    + + + + + + + +
    Description:Alternate text to display for a file, instead of an +icon selected by MIME content-type
    Syntax:AddAltByType string MIME-type +[MIME-type] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    AddAltByType sets the alternate text to + display for a file, instead of an icon, for FancyIndexing. + MIME-type is a valid content-type, such as + text/html. If String contains any whitespace, + you have to enclose it in quotes (" or '). + This alternate text is displayed if the client is image-incapable, + has image loading disabled, or fails to retrieve the icon.

    + +

    Example

    + AddAltByType 'plain text' text/plain +

    + +
    +
    top
    +

    AddDescription Directive

    + + + + + + + +
    Description:Description to display for a file
    Syntax:AddDescription string file [file] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    This sets the description to display for a file, for + FancyIndexing. + File is a file extension, partial filename, wild-card + expression or full filename for files to describe. + String is enclosed in double quotes (").

    + +

    Example

    + AddDescription "The planet Mars" /web/pics/mars.gif +

    + +

    The typical, default description field is 23 bytes wide. 6 + more bytes are added by the IndexOptions SuppressIcon option, 7 bytes are + added by the IndexOptions SuppressSize option, and 19 bytes are + added by the IndexOptions SuppressLastModified option. + Therefore, the widest default the description column is ever + assigned is 55 bytes.

    + +

    See the DescriptionWidth IndexOptions keyword for details on overriding the size + of this column, or allowing descriptions of unlimited length.

    + +

    Caution

    +

    Descriptive text defined with AddDescription + may contain HTML markup, such as tags and character entities. If the + width of the description column should happen to truncate a tagged + element (such as cutting off the end of a bolded phrase), the + results may affect the rest of the directory listing.

    +
    + +
    +
    top
    +

    AddIcon Directive

    + + + + + + + +
    Description:Icon to display for a file selected by name
    Syntax:AddIcon icon name [name] +...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    This sets the icon to display next to a file ending in + name for FancyIndexing. Icon is either a (%-escaped) + relative URL to the icon, or of the format + (alttext,url) where alttext + is the text tag given for an icon for non-graphical browsers.

    + +

    Name is either ^^DIRECTORY^^ for directories, + ^^BLANKICON^^ for blank lines (to format the list + correctly), a file extension, a wildcard expression, a partial + filename or a complete filename.

    + +

    Examples

    + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +

    + +

    AddIconByType + should be used in preference to AddIcon, + when possible.

    + +
    +
    top
    +

    AddIconByEncoding Directive

    + + + + + + + +
    Description:Icon to display next to files selected by MIME +content-encoding
    Syntax:AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    This sets the icon to display next to files with FancyIndexing. + Icon is either a (%-escaped) relative URL to the icon, + or of the format (alttext,url) + where alttext is the text tag given for an icon for + non-graphical browsers.

    + +

    MIME-encoding is a wildcard expression matching + required the content-encoding.

    + +

    Example

    + AddIconByEncoding /icons/compress.xbm x-compress +

    + +
    +
    top
    +

    AddIconByType Directive

    + + + + + + + +
    Description:Icon to display next to files selected by MIME +content-type
    Syntax:AddIconByType icon MIME-type +[MIME-type] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    This sets the icon to display next to files of type + MIME-type for FancyIndexing. + Icon is either a (%-escaped) relative URL to the icon, + or of the format (alttext,url) + where alttext is the text tag given for an icon for + non-graphical browsers.

    + +

    MIME-type is a wildcard expression matching + required the mime types.

    + +

    Example

    + AddIconByType (IMG,/icons/image.xbm) image/* +

    + +
    +
    top
    +

    DefaultIcon Directive

    + + + + + + + +
    Description:Icon to display for files when no specific icon is +configured
    Syntax:DefaultIcon url-path
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The DefaultIcon directive sets the icon + to display for files when no specific icon is known, for FancyIndexing. + Url-path is a (%-escaped) relative URL to the icon.

    + +

    Example

    + DefaultIcon /icon/unknown.xbm +

    + +
    +
    top
    +

    HeaderName Directive

    + + + + + + + +
    Description:Name of the file that will be inserted at the top +of the index listing
    Syntax:HeaderName filename
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The HeaderName directive sets the name + of the file that will be inserted at the top of the index + listing. Filename is the name of the file to include.

    + +

    Example

    + HeaderName HEADER.html +

    + +
    +

    Both HeaderName and ReadmeName now treat + Filename as a URI path relative to the one used to + access the directory being indexed. If Filename begins + with a slash, it will be taken to be relative to the DocumentRoot.

    + +

    Example

    + HeaderName /include/HEADER.html +

    + +

    Filename must resolve to a document with a major + content type of text/* (e.g., + text/html, text/plain, etc.). This means + that filename may refer to a CGI script if the script's + actual file type (as opposed to its output) is marked as + text/html such as with a directive like:

    + +

    + AddType text/html .cgi +

    + +

    Content negotiation + will be performed if Options + MultiViews is in effect. If filename resolves + to a static text/html document (not a CGI script) and + either one of the options + Includes or IncludesNOEXEC is enabled, + the file will be processed for server-side includes (see the + mod_include documentation).

    +
    + +

    If the file specified by HeaderName contains + the beginnings of an HTML document (<html>, <head>, etc.) + then you will probably want to set IndexOptions + +SuppressHTMLPreamble, so that these tags are not + repeated.

    + +
    +
    top
    +

    IndexIgnore Directive

    + + + + + + + +
    Description:Adds to the list of files to hide when listing +a directory
    Syntax:IndexIgnore file [file] ...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The IndexIgnore directive adds to the + list of files to hide when listing a directory. File is a + shell-style wildcard expression or full + filename. Multiple IndexIgnore directives add + to the list, rather than the replacing the list of ignored + files. By default, the list contains . (the current + directory).

    + +

    + IndexIgnore README .htaccess *.bak *~ +

    + +
    +
    top
    +

    IndexOptions Directive

    + + + + + + + +
    Description:Various configuration settings for directory +indexing
    Syntax:IndexOptions [+|-]option [[+|-]option] +...
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The IndexOptions directive specifies the + behavior of the directory indexing. Option can be one + of

    + +
    +
    DescriptionWidth=[n | *] (Apache 2.0.23 and + later)
    + +
    The DescriptionWidth keyword allows you to + specify the width of the description column in + characters.
    + +
    -DescriptionWidth (or unset) allows + mod_autoindex to calculate the best width.
    + +
    DescriptionWidth=n fixes the column width to + n bytes wide.
    + +
    DescriptionWidth=* grows the column to the + width necessary to accommodate the longest description + string.
    + +
    See the section on AddDescription for dangers + inherent in truncating descriptions.
    + +
    FancyIndexing
    + +
    This turns on fancy indexing of directories.
    + +
    FoldersFirst (Apache + 2.0.23 and later)
    + +
    If this option is enabled, subdirectory listings will + always appear first, followed by normal files in the + directory. The listing is basically broken into two + components, the files and the subdirectories, and each is + sorted separately and then displayed subdirectories-first. + For instance, if the sort order is descending by name, and + FoldersFirst is enabled, subdirectory + Zed will be listed before subdirectory + Beta, which will be listed before normal files + Gamma and Alpha. This option + only has an effect if FancyIndexing is also enabled.
    + +
    HTMLTable (Experimental, + Apache 2.0.23 and later)
    + +
    This experimental option with FancyIndexing constructs a + simple table for the fancy directory listing. Note this will + confuse older browsers. It is particularly necessary if file + names or description text will alternate between + left-to-right and right-to-left reading order, as can happen + on WinNT or other utf-8 enabled platforms.
    + +
    IconsAreLinks
    + +
    This makes the icons part of the anchor for the filename, for + fancy indexing.
    + +
    IconHeight[=pixels]
    + +
    Presence of this option, when used with IconWidth, will cause + the server to include height and width + attributes in the img tag for the file icon. This allows + browser to precalculate the page layout without having to wait until + all the images have been loaded. If no value is given for the option, + it defaults to the standard height of the icons supplied with the Apache + software.
    + +
    IconWidth[=pixels]
    + +
    Presence of this option, when used with IconHeight, + will cause the server to include height and + width attributes in the img tag for + the file icon. This allows browser to precalculate the page + layout without having to wait until all the images have been + loaded. If no value is given for the option, it defaults to + the standard width of the icons supplied with the Apache + software.
    + +
    IgnoreCase
    + +
    If this option is enabled, names are sorted in a case-insensitive + manner. For instance, if the sort order is ascending by name, and + IgnoreCase is enabled, file Zeta will be listed after file alfa + (Note: file GAMMA will always be listed before file gamma).
    + +
    IgnoreClient
    + +
    This option causes mod_autoindex to ignore all + query variables from the client, including sort order (implies + SuppressColumnSorting.)
    + +
    NameWidth=[n + | *]
    + +
    The NameWidth keyword allows you to specify the width + of the filename column in bytes.
    + +
    -NameWidth (or unset) allows mod_autoindex to calculate the best width.
    + +
    NameWidth=n fixes the column width to + n bytes wide.
    + +
    NameWidth=* grows the column to the necessary + width.
    + +
    ScanHTMLTitles
    + +
    This enables the extraction of the title from HTML documents + for fancy indexing. If the file does not have a description + given by AddDescription + then httpd will read the document for the value of the + title element. This is CPU and disk intensive.
    + +
    ShowForbidden
    + +
    If specified, Apache will show files normally hidden because + the subrequest returned HTTP_UNAUTHORIZED or HTTP_FORBIDDEN
    + +
    SuppressColumnSorting
    + +
    If specified, Apache will not make the column headings in a + FancyIndexed directory listing into links for sorting. The + default behavior is for them to be links; selecting the + column heading will sort the directory listing by the values + in that column. Prior to Apache 2.0.23, this also + disabled parsing the Query Arguments for the sort + string. That behavior is now controlled by IndexOptions + IgnoreClient in Apache 2.0.23.
    + +
    SuppressDescription
    + +
    This will suppress the file description in fancy indexing + listings. By default, no file descriptions are defined, and + so the use of this option will regain 23 characters of screen + space to use for something else. See AddDescription for information about setting the file + description. See also the DescriptionWidth + index option to limit the size of the description column.
    + +
    SuppressHTMLPreamble
    + +
    If the directory actually contains a file specified by the + HeaderName + directive, the module usually includes the contents of the file + after a standard HTML preamble (<html>, + <head>, et cetera). The + SuppressHTMLPreamble option disables this behaviour, + causing the module to start the display with the header file + contents. The header file must contain appropriate HTML instructions + in this case. If there is no header file, the preamble is generated + as usual.
    + +
    SuppressIcon (Apache + 2.0.23 and later)
    + +
    This will suppress the icon in fancy indexing listings. + Combining both SuppressIcon and + SuppressRules yields proper HTML 3.2 output, which + by the final specification prohibits img and + hr elements from the pre block (used to + format FancyIndexed listings.)
    + +
    SuppressLastModified
    + +
    This will suppress the display of the last modification date, + in fancy indexing listings.
    + +
    SuppressRules + (Apache 2.0.23 and later)
    + +
    This will suppress the horizontal rule lines (hr + elements) in directory listings. Combining both SuppressIcon and + SuppressRules yields proper HTML 3.2 output, which + by the final specification prohibits img and + hr elements from the pre block (used to + format FancyIndexed listings.)
    + +
    SuppressSize
    + +
    This will suppress the file size in fancy indexing listings.
    + +
    TrackModified (Apache + 2.0.23 and later)
    + +
    This returns the Last-Modified and ETag values for the listed + directory in the HTTP header. It is only valid if the + operating system and file system return appropriate stat() + results. Some Unix systems do so, as do OS2's JFS and Win32's + NTFS volumes. OS2 and Win32 FAT volumes, for example, do not. + Once this feature is enabled, the client or proxy can track + changes to the list of files when they perform a HEAD + request. Note some operating systems correctly track new and + removed files, but do not track changes for sizes or dates of + the files within the directory. Changes to the size + or date stamp of an existing file will not update the + Last-Modified header on all Unix platforms. If this + is a concern, leave this option disabled.
    + +
    VersionSort + (Apache 2.0a3 and later)
    + +
    The VersionSort keyword causes files containing + version numbers to sort in a natural way. Strings are sorted as + usual, except that substrings of digits in the name and + description are compared according to their numeric value. + +

    Example:

    + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +

    + +

    If the number starts with a zero, then it is considered to + be a fraction:

    + +

    + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +

    +
    + +
    XHTML + (Apache 2.0.49 and later)
    + +
    The XHTML keyword forces mod_autoindex + to emit XHTML 1.0 code instead of HTML 3.2.
    +
    + + +
    Incremental IndexOptions
    +
    +

    Apache 1.3.3 introduced some significant changes in the + handling of IndexOptions directives. In + particular:

    + +
      +
    • Multiple IndexOptions directives for a + single directory are now merged together. The result of: + +

      + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +

      + +

      will be the equivalent of

      + +

      + IndexOptions HTMLTable SuppressColumnsorting +

      +
    • + +
    • The addition of the incremental syntax (i.e., prefixing + keywords with + or -).
    • +
    + +

    Whenever a '+' or '-' prefixed keyword is encountered, it + is applied to the current IndexOptions + settings (which may have been inherited from an upper-level + directory). However, whenever an unprefixed keyword is processed, it + clears all inherited options and any incremental settings encountered + so far. Consider the following example:

    + +

    + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +

    + +

    The net effect is equivalent to IndexOptions FancyIndexing + +SuppressSize, because the unprefixed FancyIndexing + discarded the incremental keywords before it, but allowed them to + start accumulating again afterward.

    + +

    To unconditionally set the IndexOptions for + a particular directory, clearing the inherited settings, specify + keywords without any + or - prefixes.

    +
    +
    + +
    +
    top
    +

    IndexOrderDefault Directive

    + + + + + + + + +
    Description:Sets the default ordering of the directory index
    Syntax:IndexOrderDefault Ascending|Descending +Name|Date|Size|Description
    Default:IndexOrderDefault Ascending Name
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The IndexOrderDefault directive is used + in combination with the FancyIndexing index option. By default, fancyindexed + directory listings are displayed in ascending order by filename; the + IndexOrderDefault allows you to change this + initial display order.

    + +

    IndexOrderDefault takes two + arguments. The first must be either Ascending or + Descending, indicating the direction of the sort. + The second argument must be one of the keywords Name, + Date, Size, or Description, + and identifies the primary key. The secondary key is + always the ascending filename.

    + +

    You can force a directory listing to only be displayed in a + particular order by combining this directive with the SuppressColumnSorting index option; this will prevent + the client from requesting the directory listing in a different + order.

    + +
    +
    top
    +

    IndexStyleSheet Directive

    + + + + + + + +
    Description:Adds a CSS stylesheet to the directory index
    Syntax:IndexStyleSheet url-path
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The IndexStyleSheet directive sets the name of + the file that will be used as the CSS for the index listing. +

    +

    Example

    + + IndexStyleSheet "/css/style.css" +

    + +
    +
    top
    +

    ReadmeName Directive

    + + + + + + + +
    Description:Name of the file that will be inserted at the end +of the index listing
    Syntax:ReadmeName filename
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_autoindex
    +

    The ReadmeName directive sets the name + of the file that will be appended to the end of the index + listing. Filename is the name of the file to include, and + is taken to be relative to the location being indexed. If + Filename begins with a slash, it will be taken to be + relative to the DocumentRoot. +

    + +

    Example

    + ReadmeName FOOTER.html +

    + +

    Example 2

    + ReadmeName /include/FOOTER.html +

    + +

    See also HeaderName, where this behavior is described in greater + detail.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_autoindex.html.ja.euc-jp b/trunk/docs/manual/mod/mod_autoindex.html.ja.euc-jp new file mode 100644 index 0000000000..0f26c66764 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.html.ja.euc-jp @@ -0,0 +1,985 @@ + + + +mod_autoindex - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_autoindex

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:Unix ¤Î ls ¥³¥Þ¥ó¥É¤ä + Win32 ¤Î dir ¥·¥§¥ë¥³¥Þ¥ó¥É¤Ë»÷¤¿ + ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÀ¸À®¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:autoindex_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_autoindex.c
    +

    ³µÍ×

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÏÆó¤Ä¤Î¾ðÊ󸻤Τ¦¤Á¤Î + °ì¤Ä¤«¤éÀ¸À®¤Ç¤­¤Þ¤¹:

    + +
      +
    • ÉáÄÌ¤Ï index.html ¤È¸Æ¤Ð¤ì¤ë + ¥æ¡¼¥¶¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿¥Õ¥¡¥¤¥ë¡£ + DirectoryIndex + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤³¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤Ï mod_dir ¤ÇÀ©¸æ¤µ¤ì¤Þ¤¹¡£
    • + +
    • ¤â¤·¤¯¤Ï¡¢¥µ¡¼¥Ð¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤¿°ìÍ÷¡£ + ¤½¤Î¾¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤³¤Î°ìÍ÷¤Î½ñ¼°¤òÀ©¸æ¤·¤Þ¤¹¡£ + AddIcon, AddIconByEncoding ¤È + AddIconByType + ¤ò»È¤¦¤³¤È¤Ç¡¢ÍÍ¡¹¤Ê¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤ËÂФ·¤Æ¥¢¥¤¥³¥ó°ìÍ÷¤ò + ¥»¥Ã¥È¤·¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢¥ê¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ëËè¤Ë¡¢ + ¥Õ¥¡¥¤¥ë¤Ë¥Þ¥Ã¥Á¤·¤¿°ìÈֺǽé¤Î¥¢¥¤¥³¥ó¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï mod_autoindex ¤ÇÀ©¸æ¤µ¤ì¤Þ¤¹¡£
    • +
    +

    ˾¤à¤Ê¤é¤Ð¡¢¼«Æ°¥¤¥ó¥Ç¥Ã¥¯¥¹À¸À®¤ò´°Á´¤Ë½üµî (¤¢¤ë¤¤¤ÏÃÖ´¹) + ¤Ç¤­¤ë¤è¤¦¤Ë¡¢¤³¤ÎÆó¤Ä¤Îµ¡Ç½¤ÏʬΥ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¼«Æ°¥¤¥ó¥Ç¥Ã¥¯¥¹À¸À®¤Ï Options +Indexes + ¤ò»È¤¦¤³¤È¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢ + Options + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    ¤â¤· FancyIndexing¥ª¥×¥·¥ç¥ó¤¬ + IndexOptions + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÍ¿¤¨¤é¤ì¤Æ¤¤¤ë¤Ê¤é¤Ð¡¢ + Îó¤ÎÀèƬ¤Ïɽ¼¨¤Î½çÈÖ¤òÀ©¸æ¤¹¤ë¥ê¥ó¥¯¤Ë¤Ê¤ê¤Þ¤¹¡£ + ÀèƬ¤Î¥ê¥ó¥¯¤òÁªÂò¤¹¤ë¤È¡¢°ìÍ÷¤ÏºÆÀ¸À®¤µ¤ì¤Æ + ¤½¤ÎÎó¤ÎÃͤǥ½¡¼¥È¤µ¤ì¤Þ¤¹¡£ + Ʊ¤¸ÀèƬ¤ò³¤±¤ÆÁªÂò¤¹¤ë¤È¡¢¸ò¸ß¤Ë¾º½ç¤È¹ß½ç¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤é¤ÎÎó¤ÎÀèƬ¤Î¥ê¥ó¥¯¤Ï¡¢ + IndexOptions + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + SuppressColumnSorting + ¥ª¥×¥·¥ç¥ó¤Ç¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    "Size" ¤Ç¥½¡¼¥È¤·¤¿¾ì¹ç¤Ï¡¢ÍѤ¤¤é¤ì¤ë¤Î¤Ï + ¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤Ç¤¢¤Ã¤Æ¡¢ + ɽ¼¨¤ÎÃͤǤϤʤ¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤ - + ¤¿¤È¤¨Î¾Êý¤È¤â¤¬ "1K" ¤Èɽ¼¨¤µ¤ì¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢ + 1010 ¥Ð¥¤¥È¤Î¥Õ¥¡¥¤¥ë¤Ïɬ¤º 1011 + ¥Ð¥¤¥È¤Î¥Õ¥¡¥¤¥ë¤è¤ê¤âÁ° (¾º½ç¤Î¾ì¹ç) ¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    Autoindex ¥ê¥¯¥¨¥¹¥È¥¯¥¨¥ê¡¼°ú¿ô

    + + +

    Apache 2.0.23 ¤Ç¡¢ + ¥³¥é¥à¥½¡¼¥È¤Î¤¿¤á¤Ë¥¯¥¨¥ê¡¼°ú¿ô¤òºÆÊÔÀ®¤·¤Æ¡¢ + ¿·¤·¤¤¥¯¥¨¥ê¡¼¥ª¥×¥·¥ç¥ó¤Î¥°¥ë¡¼¥×¤òƳÆþ¤·¤Þ¤·¤¿¡£ + ½ÐÎϤËÂФ¹¤ë¥¯¥é¥¤¥¢¥ó¥È¤Î¤¹¤Ù¤Æ¤ÎÀ©¸æ¤ò¸úΨŪ¤ËËõ¾Ã + ¤Ç¤­¤ë¤è¤¦¤Ë¡¢ + IndexOptions + IgnoreClient ¤¬Æ³Æþ¤µ¤ì¤Þ¤·¤¿¡£

    + +

    ¥³¥é¥à¥½¡¼¥È¤Î¥Ø¥Ã¥À¤½¤ì¼«ÂΤ¬¡¢ + ²¼µ­¤Î¥½¡¼¥È¥¯¥¨¥ê¡¼¥ª¥×¥·¥ç¥ó¤òÉղ乤ë + ¼«Ê¬¼«¿È¤ò»²¾È¤¹¤ë¥ê¥ó¥¯¤Ç¤¹¡£ + ²¼µ­¤Î¥ª¥×¥·¥ç¥ó¤Î¤É¤ì¤Ç¤â¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¥ê¥½¡¼¥¹¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ë²Ã¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
      +
    • C=N ¤Ï¡¢¥Õ¥¡¥¤¥ë̾¤Ç¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • C=M ¤Ï¡¢¹¹¿·Æü»þ¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¡¢¥Õ¥¡¥¤¥ë̾¤Î½ç¤Ç¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • C=S ¤Ï¡¢¥µ¥¤¥º¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¡¢¥Õ¥¡¥¤¥ë̾¤Î½ç¤Ç¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • C=D ¤Ï¡¢ÀâÌÀ¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¡¢¥Õ¥¡¥¤¥ë̾¤Î½ç¤Ç¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • O=A ¤Ï¡¢¾º½ç¤Çɽ¤ò¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • O=D ¤Ï¡¢¹ß½ç¤Çɽ¤ò¥½¡¼¥È¤·¤Þ¤¹¡£
    • + +
    • F=0 ¤Ï¡¢Ã±½ã¤Êɽ¤Î½ñ¼°¤Ë¤·¤Þ¤¹¡£ + (FancyIndex ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£)
    • + +
    • F=1 ¤Ï¡¢FancyIndex + ɽ¼¨¤Îɽ¤Î½ñ¼°¤Ë¤·¤Þ¤¹¡£
    • + +
    • F=2 ¤Ï¡¢É½¤ò HTML + ¤Î¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤¿ FancyIndex ¤Î½ñ¼°¤Ë¤·¤Þ¤¹¡£
    • + +
    • V=0 + ¤Ï¡¢¥Ð¡¼¥¸¥ç¥ó¤Ë¤è¤ë¥½¡¼¥È¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
    • + +
    • V=1 + ¤Ï¡¢¥Ð¡¼¥¸¥ç¥ó¤Ë¤è¤ë¥½¡¼¥È¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
    • + +
    • P=pattern + ¤Ï¡¢Í¿¤¨¤é¤ì¤¿ pattern + ¤ËŬ¹ç¤·¤¿¥Õ¥¡¥¤¥ë¤Î¤ß¤òɽ¼¨¤·¤Þ¤¹¡£
    • +
    + +

    "P (¥Ñ¥¿¡¼¥ó¤Î P)" ¥¯¥¨¥ê¡¼°ú¿ô¤Ï¡¢ + Ä̾ï¤Î IndexIgnore + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬½èÍý¤µ¤ì¤¿¸å¤Ë¸¡ºº¤µ¤ì¡¢ + ¥Õ¥¡¥¤¥ë̾Á´¤Æ¤¬¡¢Â¾¤Î autoindex + ¥ê¥¹¥È½èÍý¤ÈƱÍͤÎȽÄê´ð½à²¼¤ËÃÖ¤«¤ì³¤±¤ë + ¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + mod_autoindex ¤Î¥¯¥¨¥ê¡¼°ú¿ô¥Ñ¡¼¥µ (²òÀÏ) ¤Ï¡¢ + ǧ¼±ÉÔǽ¤Ê¥ª¥×¥·¥ç¥ó¤Ë¤Ö¤Ä¤«¤ë¤È¨ºÂ¤ËÄä»ß¤·¤Þ¤¹¡£ + ¥¯¥¨¥ê¡¼°ú¿ô¤Ï¾å¤Îɽ¤Ë½¾¤Ã¤Æ + Àµ¤·¤¤·Á¼°¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ²¼¤Îñ½ã¤ÊÎã¤Ï¡¢¤³¤ì¤é¤Î¥¯¥¨¥ê¡¼¥ª¥×¥·¥ç¥ó¤ò + ɽ¤·¤Þ¤¹¡£¤³¤ì¤ò¤½¤Î¤Þ¤ÞÀÚ¤ê¼è¤Ã¤Æ HEADER.html + ¥Õ¥¡¥¤¥ë¤ËÊݸ¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + mod_autoindex ¤¬ X=Go ÆþÎϤˤ֤Ĥ«¤ëÁ°¤Ë + °ú¿ô¤¬Á´¤Æ²ò¼á¤µ¤ì¤ë¤è¤¦¤Ë¡¢ + ̤ÃΤΰú¿ô "X" ¤Ï¥ê¥¹¥È¤ÎºÇ¸å¤ËÃÖ¤«¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +

    + +
    +
    top
    +

    AddAlt ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ë +ɽ¼¨¤µ¤ì¤ë¡¢¥Õ¥¡¥¤¥ë̾¤ÇÁªÂò¤µ¤ì¤¿ÂåÂإƥ­¥¹¥È
    ¹½Ê¸:AddAlt string file [file] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    AddAlt ¤Ï¡¢FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ëɽ¼¨¤¹¤ëÂåÂإƥ­¥¹¥È¤òÄ󶡤·¤Þ¤¹¡£ + file ¤Ï¡¢ÀâÌÀ¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¡¢ + ¥Õ¥¡¥¤¥ë̾¤Î°ìÉô¡¢¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¡¢´°Á´¤Ê¥Õ¥¡¥¤¥ë̾¤Î + ¤É¤ì¤«¤Ë¤Ê¤ê¤Þ¤¹¡£ + string ¤Ë¶õÇò¤¬¤¢¤ë¾ì¹ç¤Ï°úÍÑÉä (" + ¤« ') ¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Îʸ»úÎó¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬²èÁü¤òɽ¼¨¤Ç¤­¤Ê¤¤¾ì¹ç¤ä + ²èÁü¤Î¥í¡¼¥É¤ò̵¸ú¤Ë¤·¤Æ¤¤¤ë¾ì¹ç¤ä + ¥¢¥¤¥³¥ó¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +

    + +
    +
    top
    +

    AddAltByEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ëɽ¼¨¤µ¤ì¤ë¡¢MIME Éä¹æ²½ÊýË¡¤ÇÁªÂò¤µ¤ì¤¿ +ÂåÂإƥ­¥¹¥È
    ¹½Ê¸:AddAltByEncoding string MIME-encoding +[MIME-encoding] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    AddAltByEncoding ¤Ï¡¢ + FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ëɽ¼¨¤¹¤ëÂåÂØʸ»úÎó¤òÄ󶡤·¤Þ¤¹¡£ + MIME-encoding ¤ÏÍ­¸ú¤ÊÉä¹æ²½¡¢Î㤨¤Ð + x-compress + ¤Ç¤¹¡£ + string ¤Ë¶õÇò¤¬¤¢¤ë¤È¤­¤Ï¡¢°úÍÑÉä (" ¤« + ') ¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Îʸ»úÎó¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬²èÁü¤òɽ¼¨¤Ç¤­¤Ê¤¤¾ì¹ç¤ä + ²èÁü¤Î¥í¡¼¥É¤ò̵¸ú¤Ë¤·¤Æ¤¤¤ë¾ì¹ç¤ä + ¥¢¥¤¥³¥ó¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + AddAltByEncoding gzip x-gzip +

    + +
    +
    top
    +

    AddAltByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ë +ɽ¼¨¤µ¤ì¤ë¡¢MIME ¥¿¥¤¥×¤ÇÁªÂò¤µ¤ì¤¿ÂåÂإƥ­¥¹¥È
    ¹½Ê¸:AddAltByType string MIME-type +[MIME-type] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    AddAltByType ¤Ï¡¢ + FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ëɽ¼¨¤¹¤ëÂåÂØʸ»úÎó¤òÀßÄꤷ¤Þ¤¹¡£ + MIME-type ¤ÏÍ­¸ú¤Ê¥¿¥¤¥×¡¢Î㤨¤Ð + text/html + ¤Ç¤¹¡£ + string ¤Ë¶õÇò¤¬¤¢¤ë¤È¤­¤Ï¡¢°úÍÑÉä (" ¤« + ') ¤Ç°Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Îʸ»úÎó¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬²èÁü¤òɽ¼¨¤Ç¤­¤Ê¤¤¾ì¹ç¤ä + ²èÁü¤Î¥í¡¼¥É¤ò̵¸ú¤Ë¤·¤Æ¤¤¤ë¾ì¹ç¤ä + ¥¢¥¤¥³¥ó¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + AddAltByType 'plain text' text/plain +

    + +
    +
    top
    +

    AddDescription ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æɽ¼¨¤¹¤ëÀâÌÀ
    ¹½Ê¸:AddDescription string file [file] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æɽ¼¨¤¹¤ëÀâÌÀ¤òÀßÄꤷ¤Þ¤¹¡£ + file ¤ÏÀâÌÀ¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¡¢ + ¥Õ¥¡¥¤¥ë̾¤Î°ìÉô¡¢¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¡¢´°Á´¤Ê¥Õ¥¡¥¤¥ë̾¤Î + ¤É¤ì¤«¤Ë¤Ê¤ê¤Þ¤¹¡£ + string ¤ÏÆó½Å°úÍÑÉä (") ¤Ç°Ï¤Þ¤ì¤Þ¤¹¡£

    + +

    Îã

    + AddDescription "The planet Mars" /web/pics/mars.gif +

    + +

    Ä̾ï¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÀâÌÀÎΰè¤Ï 23 ¥Ð¥¤¥È¤ÎÉý¤Ç¤¹¡£ + IndexOptions SuppressIcon + ¥ª¥×¥·¥ç¥ó¤Ç 6 ¥Ð¥¤¥ÈÄɲᢠ+ IndexOptions SuppressSize + ¥ª¥×¥·¥ç¥ó¤Ç 7 ¥Ð¥¤¥ÈÄɲᢠ+ IndexOptions SuppressLastModified + ¥ª¥×¥·¥ç¥ó¤Ç 19 ¥Ð¥¤¥ÈÄɲ䵤ì¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¥Ç¥Õ¥©¥ë¥È¤ÎÀâÌÀ¥³¥é¥à¤ÎºÇÂçÉý¤Ï + 55 ¥Ð¥¤¥È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥³¥é¥à¤ÎÂ礭¤µ¤ò¾å½ñ¤­¤·¤¿¤ê¡¢ + ÀâÌÀ¤¬ÌµÀ©¸ÂŤǤâ¤è¤¤¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Î¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï¡¢ + DescriptionWidth + ¤È¤¤¤¦ + IndexOptions + ¤Î¥­¡¼¥ï¡¼¥É¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    ·Ù¹ð

    +

    AddDescription + ¤ÇÄêµÁ¤µ¤ì¤¿ÀâÌÀ¥Æ¥­¥¹¥È¤Ï¡¢¥¿¥°¤äʸ»úÎó¤È¤¤¤Ã¤¿ + HTML ¥Þ¡¼¥¯¥¢¥Ã¥×¤ò´Þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤â¤·¡¢ÀâÌÀ¥³¥é¥à¤ÎÉý¤Ë¤è¤Ã¤Æ¥¿¥°ÉÕ¤±¤µ¤ì¤¿Í×ÁǤ¬´Ý¤á¹þ¤Þ¤ì¤¿ + (ÂÀ»ú¤Î¸ì¶ç¤ÎºÇ¸å¤¬ÀÚ¤ì¤ë¤È¤¤¤Ã¤¿) ¾ì¹ç¡¢ + ½ÐÎÏ·ë²Ì¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Î»Ä¤ê¤ÎÉôʬ¤Ë±Æ¶Á¤òÍ¿¤¨¤ë¤Ç¤·¤ç¤¦¡£

    +
    + +
    +
    top
    +

    AddIcon ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò̾Á°¤ÇÁªÂò
    ¹½Ê¸:AddIcon icon name +[name] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢ + name ¤Ç½ª¤ï¤ë¥Õ¥¡¥¤¥ë¤ÎÎÙ¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤òÀßÄꤷ¤Þ¤¹¡£ + icon ¤Ï¡¢(% ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿) ¥¢¥¤¥³¥ó¤Ø¤ÎÁêÂÐ URL + ¤«¡¢Â¾¤Î½ñ¼° (alttext, url) ¤Ç¤¹¡£ + ¤³¤³¤Ç alttext + ¤Ï¡¢Èó¥°¥é¥Õ¥£¥«¥ë¥Ö¥é¥¦¥¶¸þ¤±¤Ë¥¢¥¤¥³¥ó¤ËÉÕ¤±¤é¤ì¤¿¥Æ¥­¥¹¥È¥¿¥°¤Ç¤¹¡£ +

    + +

    name ¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê¤ËÂбþ¤¹¤ë ^^DIRECTORY^^ + ¤«¡¢¶õÇò¹Ô¤ËÂбþ¤¹¤ë ^^BLANKICON^^ (°ìÍ÷¤¬Àµ¤·¤¯É½¼¨¤µ¤ì¤ë¤¿¤á¤Ë) ¤«¡¢ + ¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤«¡¢¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¤«¡¢¥Õ¥¡¥¤¥ë̾¤Î°ìÉô¤« + ´°Á´¤Ê¥Õ¥¡¥¤¥ë̾¤Ç¤¹¡£

    + +

    Îã

    + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +

    + +

    ¤â¤·²Äǽ¤Ê¤é¡¢ + AddIcon + ¤è¤ê + AddIconByType + ¤òÍ¥ÀèŪ¤Ë»È¤¦¤Ù¤­¤Ç¤·¤ç¤¦¡£

    + +
    +
    top
    +

    AddIconByEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò MIME +Éä¹æ²½ÊýË¡¤ÇÁªÂò
    ¹½Ê¸:AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥Õ¥¡¥¤¥ë¤ÎÎÙ¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤òÀßÄꤷ¤Þ¤¹¡£ + icon ¤Ï¡¢(% ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿) ¥¢¥¤¥³¥ó¤Ø¤ÎÁêÂÐ URL + ¤«¡¢Â¾¤Î½ñ¼° (alttext, url) ¤Ç¤¹¡£ + ¤³¤³¤Ç alttext + ¤Ï¡¢Èó¥°¥é¥Õ¥£¥«¥ë¥Ö¥é¥¦¥¶¸þ¤±¤Ë¥¢¥¤¥³¥ó¤ËÉÕ¤±¤é¤ì¤¿¥Æ¥­¥¹¥È¥¿¥°¤Ç¤¹¡£ +

    + +

    MIME-encoding ¤Ï¡¢Í׵ᤵ¤ì¤¿¥¨¥ó¥³¡¼¥É¤Ë³ºÅö¤¹¤ë + ¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¤Ç¤¹¡£

    + +

    Îã

    + AddIconByEncoding /icons/compress.xbm x-compress +

    + +
    +
    top
    +

    AddIconByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤ÎÎÙ¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò +MIME ¥¿¥¤¥×¤Ë¤è¤Ã¤ÆÁªÂò
    ¹½Ê¸:AddIconByType icon MIME-type +[MIME-type] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢¥Õ¥¡¥¤¥ë¤ÎÎÙ¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤òÀßÄꤷ¤Þ¤¹¡£ + icon ¤Ï¡¢(% ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿) ¥¢¥¤¥³¥ó¤Ø¤ÎÁêÂÐ URL + ¤«¡¢Â¾¤Î½ñ¼° (alttext, url) ¤Ç¤¹¡£ + ¤³¤³¤Ç alttext + ¤Ï¡¢Èó¥°¥é¥Õ¥£¥«¥ë¥Ö¥é¥¦¥¶¸þ¤±¤Ë¥¢¥¤¥³¥ó¤ËÉÕ¤±¤é¤ì¤¿¥Æ¥­¥¹¥È¥¿¥°¤Ç¤¹¡£ +

    + +

    MIME-type ¤Ï¡¢Í׵ᤵ¤ì¤¿¥¿¥¤¥×¤Ë³ºÅö¤¹¤ë + ¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¤Ç¤¹¡£

    + +

    Îã

    + AddIconByType (IMG,/icons/image.xbm) image/* +

    + +
    +
    top
    +

    DefaultIcon ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î¥¢¥¤¥³¥ó¤¬²¿¤âÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤»þ¤Ë +¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó
    ¹½Ê¸:DefaultIcon url-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    FancyIndexing + ¤Ë¤ª¤¤¤Æ¡¢ + ÆÃÄê¤Î¥¢¥¤¥³¥ó¤¬¤Ê¤¤¾ì¹ç¤Ë¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤òÀßÄꤷ¤Þ¤¹¡£ + url-path ¤Ï¡¢(% ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿) ¥¢¥¤¥³¥ó¤Ø¤ÎÁêÂÐ URL + ¤Ç¤¹¡£

    + +

    Îã

    + DefaultIcon /icon/unknown.xbm +

    + +
    +
    top
    +

    HeaderName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ: +¥¤¥ó¥Ç¥Ã¥¯¥¹°ìÍ÷¤ÎÀèƬ¤ËÁÞÆþ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°
    ¹½Ê¸:HeaderName filename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    HeaderName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥¤¥ó¥Ç¥Ã¥¯¥¹°ìÍ÷¤ÎÀèƬ¤ËÁÞÆþ¤¹¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤷ¤Þ¤¹¡£ + Filename ¤Ï¼è¤ê¹þ¤à¥Õ¥¡¥¤¥ë¤Î̾Á°¤Ç¤¹¡£

    + +

    Îã

    + HeaderName HEADER.html +

    + +
    +

    HeaderName ¤â ReadmeName + ¤âξÊý¤È¤â¸½ºß¤Ï¡¢filename + ¤ò¥¤¥ó¥Ç¥Ã¥¯¥¹¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ËÍѤ¤¤é¤ì¤¿ URI + ¤ËÂФ¹¤ëÁêÂÐ URI ¥Ñ¥¹¤È¤·¤Æ°·¤¤¤Þ¤¹¡£ + filename ¤¬¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤ë¾ì¹ç¤Ï¡¢ + DocumentRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + HeaderName /include/HEADER.html +

    + +

    filename ¤Ï + ¥á¥¸¥ã¡¼¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤¬ "text/*" + (Î㤨¤Ð¡¢text/html, + text/plain Åù¤Ç¤¹¡£) + ¤Î¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ²ò·è + ¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤ì¤Ï¤Ä¤Þ¤ê¡¢ + ¤â¤· CGI ¥¹¥¯¥ê¥×¥È¤Î¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤¬ + ¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤è¤¦¤Ë¤·¤Æ¼ÂºÝ¤Î½ÐÎÏ¤È¤Ï°Û¤Ê¤Ã¤Æ + text/html ¤È¤·¤Æ¥Þ¡¼¥¯¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢ + filename + ¤Ï CGI ¥¹¥¯¥ê¥×¥È¤ò»²¾È¤¹¤ë¤«¤âÃΤì¤Ê¤¤¡¢ + ¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹:

    + +

    + AddType text/html .cgi +

    + +

    Options MultiViews ¤¬ + Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + ¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + ¤â¤· filename ¤¬ (CGI ¥¹¥¯¥ê¥×¥È¤Ç¤Ê¤¤) ÀÅŪ¤Ê + text/html ¥É¥­¥å¥á¥ó¥È¤Ç²ò·è¤µ¤ì¡¢ + options + Includes ¤« IncludesNOEXEC + ¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥Õ¥¡¥¤¥ë¤Ï¥µ¡¼¥Ð¡¼¥µ¥¤¥É¥¤¥ó¥¯¥ë¡¼¥É¤Ç½èÍý¤µ¤ì¤Þ¤¹ + (mod_include ¥É¥­¥å¥á¥ó¥È¤ò»²¾È¤·¤Æ²¼¤µ¤¤)¡£

    +
    + +

    ¤â¤· HeaderName ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤¬ + HTML ¥É¥­¥å¥á¥ó¥È¤Î³«»ÏÉôʬ (<html>, <head>, + Åù) ¤ò´Þ¤ó¤Ç¤¤¤¿¤é¡¢ + IndexOptions + +SuppressHTMLPreamble + ¤òÀßÄꤷ¤Æ¡¢¤³¤ì¤é¤Î¥¿¥°¤¬·«¤êÊÖ¤µ¤ì¤Ê¤¤¤è¤¦¤Ë¤·¤¿¤¤¤È»×¤¦¤Ç¤·¤ç¤¦¡£

    + +
    +
    top
    +

    IndexIgnore ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤ò¹Ô¤Ê¤¦ºÝ¤Ë̵»ë¤¹¤Ù¤­ +¥Õ¥¡¥¤¥ë¥ê¥¹¥È¤ËÄɲÃ
    ¹½Ê¸:IndexIgnore file [file] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    IndexIgnore ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¤Î°ìÍ÷¤ò¹Ô¤¦ºÝ¤Ë̵»ë¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¥ê¥¹¥È¤ËÄɲä·¤Þ¤¹¡£ + file ¤Ï¡¢ + ¥·¥§¥ë·Á¼°¤Î¥ï¥¤¥ë¥É¥«¡¼¥Éɽ¸½¤«´°Á´¤Ê¥Õ¥¡¥¤¥ë̾¤Ç¤¹¡£ + IndexIgnore ¤¬Ê£¿ô¤¢¤ë¾ì¹ç¤Ï¡¢Ìµ»ë¤¹¤ë¥ê¥¹¥È¤ËÄɲ䬹Ԥï¤ì¡¢ + ÃÖ´¹¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥ê¥¹¥È¤Ë¤Ï . + (¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê) ¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    + IndexIgnore README .htaccess *.bak *~ +

    + +
    +
    top
    +

    IndexOptions ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÎÍÍ¡¹¤ÊÀßÄê¹àÌÜ +
    ¹½Ê¸:IndexOptions [+|-]option [[+|-]option] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    IndexOptions + ¤Ï¡¢¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÎµóÆ°¤ò»ØÄꤷ¤Þ¤¹¡£ + option ¤Ï¼¡¤Î¤É¤ì¤«¤Ç¤¹:

    + +
    +
    DescriptionWidth=[n | *] + (2.0.23 °Ê¹ß)
    + +
    DescriptionWidth + ¥­¡¼¥ï¡¼¥É¤ÏÀâÌÀ¥³¥é¥à¤ÎÉý¤òʸ»ú¿ô¤Ç»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    + +
    -DescriptionWidth (¤Þ¤¿¤ÏÈóÀßÄê) ¤Ç¡¢ + mod_autoindex ¤¬ºÇŬ¤ÊÉý¤ò·×»»¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£
    + +
    DescriptionWidth=n + ¤Ç¡¢¥³¥é¥àÉý¤ò n ¥Ð¥¤¥È¤Ë¸ÇÄꤷ¤Þ¤¹¡£
    + +
    DescriptionWidth=* + ¤Ï¡¢ºÇŤÎÀâÌÀ¤Ë¹ç¤ï¤»¤ÆɬÍפÊŤµ¤Þ¤Ç¥³¥é¥à¤ò±ä¤Ð¤·¤Þ¤¹¡£
    + +
    ÀâÌÀ¤ò´Ý¤á¹þ¤ó¤À¾ì¹çÆÃÍ­¤Î´í¸±¤Ë¤Ä¤¤¤Æ¤Ï + AddDescription + ¥»¥¯¥·¥ç¥ó¤ò¤ªÆɤ߲¼¤µ¤¤¡£
    + +
    FancyIndexing
    + +
    ¾þ¤êÉÕ¤­¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò¥ª¥ó¤Ë¤·¤Þ¤¹¡£
    + +
    FoldersFirst + (2.0.23 °Ê¹ß)
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ë¤Ê¤Ã¤¿¾ì¹ç¡¢¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î°ìÍ÷¤Ï + ɬ¤ººÇ½é¤Ë¸½¤ï¤ì¤Æ¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ÎÄ̾ï¤Î¥Õ¥¡¥¤¥ë¤Ï + ¤½¤Î¸å¤Ë³¤­¤Þ¤¹¡£ + °ìÍ÷¤Ï´ðËÜŪ¤Ë¤Ï¡¢¥Õ¥¡¥¤¥ë¤È¥Ç¥£¥ì¥¯¥È¥ê¤ÎÆó¤Ä¤ÎÉôʬ¤Ëʬ¤±¤é¤ì¤Æ¡¢ + ¤½¤ì¤¾¤ì¤ÏÊÌ¡¹¤Ë¥½¡¼¥È¤µ¤ì¡¢¤½¤Î¸å¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤òÀè¤Ë¤·¤Æ + ɽ¼¨¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£Î㤨¤Ð¥½¡¼¥È½ç¤¬Ì¾Á°¤Î¹ß½ç¤Ë¤Ê¤Ã¤Æ¤¤¤Æ¡¢ + FoldersFirst ¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê Zed ¤Ï¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê + Beta ¤è¤ê¤âÁ°¤Ë¥ê¥¹¥È¤µ¤ì¡¢Ä̾ï¤Î¥Õ¥¡¥¤¥ë + Gamma ¤ä Alpha + ¤è¤ê¤âÁ°¤Ë¥ê¥¹¥È¤µ¤ì¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï + FancyIndexing + ¤âÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¤Î¤ß¡¢¸ú²Ì¤¬¤¢¤ê¤Þ¤¹¡£
    + +
    HTMLTable (¼Â¸³Åª¡¢ + Apache 2.0.23 °Ê¹ß)
    + +
    ¤³¤Î¼Â¸³Åª¤Ê¥ª¥×¥·¥ç¥ó¤Ï FancyIndexing ¤È¤È¤â¤Ë»ØÄꤹ¤ë¤³¤È¤Ç¡¢ + ¾þ¤ê¤ÎÉÕ¤¤¤¿¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Î¤¿¤á¤Ë¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤¿Ã±½ã¤Êɽ¤òºî¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¸Å¤¤¥Ö¥é¥¦¥¶¤òº®Í𤵤»¤ë¤«¤â¤·¤ì¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + WinNT ¤ä¤½¤Î¾ utf-8 + ¤¬Í­¸ú¤Ê¥×¥é¥Ã¥È¥Û¡¼¥à¤Î¤è¤¦¤Ë¡¢¥Õ¥¡¥¤¥ë̾¤äÀâÌÀ¥Æ¥­¥¹¥È¤¬ + ±¦Æɤߤˤʤ俤꺸Æɤߤˤʤꤨ¤ë¾ì¹ç¤ÏÆäËɬÍפǤ¹¡£
    + +
    IconsAreLinks
    + +
    ¤³¤ì¤Ï¡¢FancyIndexing ¤Ë¤ª¤¤¤Æ¡¢ + ¥¢¥¤¥³¥ó¤â¥Õ¥¡¥¤¥ë̾¤Ø¤Î¥ê¥ó¥¯¤Î°ìÉô¤Ë¤·¤Þ¤¹¡£
    + +
    IconHeight[=pixels]
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤¬¡¢IconWidth ¤È¤È¤â¤Ë»È¤ï¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï¥Õ¥¡¥¤¥ë¥¢¥¤¥³¥ó¤Î¤¿¤á¤Î img + ¥¿¥°¤Ë height ¤È width + °À­¤ò¼è¤ê¹þ¤à¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤Ã¤Æ¡¢¥¤¥á¡¼¥¸Á´¤Æ¤ò¥í¡¼¥É¤·½ª¤ï¤ë¤Þ¤ÇÂÔ¤¿¤Ê¤¯¤Æ¤â¡¢ + ¥Ö¥é¥¦¥¶¤Ï¥Ú¡¼¥¸¥ì¥¤¥¢¥¦¥È¤ò¤¢¤é¤«¤¸¤á·×»»¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë²¿¤âÃͤ¬Í¿¤¨¤é¤ì¤Ê¤±¤ì¤Ð¡¢Apache + ¥½¥Õ¥È¥¦¥§¥¢¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¥¢¥¤¥³¥ó¤Îɸ½à¤Î¹â¤µ¤¬ + ¥Ç¥Õ¥©¥ë¥È¤Ê¤ê¤Þ¤¹¡£
    + +
    IconWidth[=pixels]
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤¬¡¢IconHeight ¤È¤È¤â¤Ë»È¤ï¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï¥Õ¥¡¥¤¥ë¥¢¥¤¥³¥ó¤Î¤¿¤á¤Î img + ¥¿¥°¤Ë height ¤È width + °À­¤ò¼è¤ê¹þ¤à¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤Ã¤Æ¡¢¥¤¥á¡¼¥¸Á´¤Æ¤ò¥í¡¼¥É¤·½ª¤ï¤ë¤Þ¤ÇÂÔ¤¿¤Ê¤¯¤Æ¤â¡¢ + ¥Ö¥é¥¦¥¶¤Ï¥Ú¡¼¥¸¥ì¥¤¥¢¥¦¥È¤ò¤¢¤é¤«¤¸¤á·×»»¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ë²¿¤âÃͤ¬Í¿¤¨¤é¤ì¤Ê¤±¤ì¤Ð¡¢Apache + ¥½¥Õ¥È¥¦¥§¥¢¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¥¢¥¤¥³¥ó¤Îɸ½à¤Î¹â¤µ¤¬ + ¥Ç¥Õ¥©¥ë¥È¤Ê¤ê¤Þ¤¹¡£
    + +
    IgnoreCase
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ç¤¢¤ë¤È¡¢¥Õ¥¡¥¤¥ë̾¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë¥½¡¼¥È¤µ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¥Õ¥¡¥¤¥ë̾¤¬¾º½ç¤Ç¥½¡¼¥È¤µ¤ì¡¢IgnoreCase ¤¬Í­¸ú¤Ç¤¢¤ì¤Ð¡¢ + Zeta ¤Ï alfa ¤Î¸å¤Ë¥ê¥¹¥È¤µ¤ì¤Þ¤¹ + (Ãí°Õ: GAMMA ¤Ï¾ï¤Ë gamma ¤ÎÁ°¤Ë¤Ê¤ê¤Þ¤¹)¡£
    + +
    IgnoreClient
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç mod_autoindex ¤Ï¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤ÎÁ´¤Æ¤Î¥¯¥¨¥ê¡¼ÊÑ¿ô¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¥½¡¼¥È½ç¤â´Þ¤ß¤Þ¤¹¡£ + (¤Ä¤Þ¤ê SuppressColumnSorting + ¤ò°Å¤Ë°ÕÌ£¤·¤Þ¤¹¡£)
    + +
    NameWidth=[n + | *]
    + +
    NameWidth ¥­¡¼¥ï¡¼¥É¤Ç¥Õ¥¡¥¤¥ë̾¥³¥é¥à¤ÎÉý¤ò¥Ð¥¤¥È¿ô¤Ç + »ØÄê¤Ç¤­¤Þ¤¹¡£
    + +
    -NameWidth (¤Þ¤¿¤ÏÈóÀßÄê) ¤Ç¡¢ + mod_autoindex ¤¬ºÇŬ¤ÊÉý¤ò·×»»¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£
    + +
    NameWidth=n + ¤Ç¡¢¥³¥é¥àÉý¤ò n ¥Ð¥¤¥È¤Ë¸ÇÄꤷ¤Þ¤¹¡£
    + +
    NameWidth=* + ¤Ï¡¢É¬ÍפÊŤµ¤Þ¤Ç¥³¥é¥à¤ò±ä¤Ð¤·¤Þ¤¹¡£
    + +
    ScanHTMLTitles
    + +
    FancyIndexing ¤Î¤¿¤á¤Ë¡¢ + HTML ¥É¥­¥å¥á¥ó¥È¤«¤é¥¿¥¤¥È¥ë¤ò¼è¤ê½Ð¤¹¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£ + ¤â¤·¥Õ¥¡¥¤¥ë¤Ë + AddDescription + ¤ÇÀâÌÀ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢ + httpd ¤Ï title ¥¿¥°¤ÎÃͤòÆɤि¤á¤Ë¥É¥­¥å¥á¥ó¥È¤òÆɤ߻Ϥá¤Þ¤¹¡£ + ¤³¤ì¤Ï CPU ¤ä disk ¤ËÉé²Ù¤ò¤«¤±¤Þ¤¹¡£
    + +
    ShowForbidden
    + +
    »ØÄꤷ¤¿¾ì¹ç¤Ç¤¢¤Ã¤Æ¤â¡¢¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤Î·ë²Ì¤¬ HTTP_UNAUTHORIZED ¤ä + HTTP_FORBIDDEN ¤Î¥Õ¥¡¥¤¥ë¤ÏÄ̾ïÄ̤걣¤µ¤ì¤¿¾õÂ֤Τޤޡ¢ + ¥Õ¥¡¥¤¥ë°ìÍ÷¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
    + +
    SuppressColumnSorting
    + +
    ¤â¤·»ØÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢Apache ¤Ï + FancyIndexing ¤Çɽ¼¨¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Ç¤Î + ¥³¥é¥à¤ÎÀèƬ¤ò¡¢¥½¡¼¥È¤Î¤¿¤á¤Î¥ê¥ó¥¯¤Ë¤·¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤ÎµóÆ°¤Ï¡¢¥ê¥ó¥¯¤È¤·¤Þ¤¹¡£ + ¥³¥é¥à¤ÎÀèƬ¤òÁª¤Ö¤È¥³¥é¥à¤ÎÃͤ˽¾¤Ã¤Æ¥Ç¥£¥ì¥¯¥È¥ê¥ê¥¹¥È¤ò + ¥½¡¼¥È¤·¤Þ¤¹¡£ + Apache 2.0.23 °ÊÁ°¤Ç¤Ï¡¢¤³¤ì¤ÏƱ»þ¤Ë + ¥½¡¼¥Èʸ»úÎó¤Î¤¿¤á¤Î¥¯¥¨¥ê¡¼°ú¿ô¤Î²òÀϤâ̵¸ú¤Ë¤·¤Þ¤¹¡£ + + ¤³¤ÎµóÆ°¤Ï Apache 2.0.23 ¤Ç¤Ï + IndexOptions + IgnoreClient ¤ÇÀ©¸æ¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
    + +
    SuppressDescription
    + +
    ¤³¤ì¤Ï FancyIndexing ¤Ë¤ª¤±¤ë¥Õ¥¡¥¤¥ë¤ÎÀâÌÀ¤ò¾Ãµî¤·¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢ÀâÌÀ¤ÏÄêµÁ¤µ¤ì¤Æ¤ª¤é¤º¡¢ + ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¦¤È¾¤Î¤¿¤á¤Ë 23 + ʸ»ú¤Î¶õÇò¤ò²Ô¤°¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ ¥Õ¥¡¥¤¥ë¤ÎÀâÌÀ¤Ë´Ø¤¹¤ë¾ðÊó¤Ï¡¢ + AddDescription + ¤ò¤´Í÷²¼¤µ¤¤¡£¤Þ¤¿¡¢ÀâÌÀ¤Î¥³¥é¥à¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë + DescriptionWidth + ¥¤¥ó¥Ç¥Ã¥¯¥¹¥ª¥×¥·¥ç¥ó¤â¤´Í÷²¼¤µ¤¤¡£
    + +
    SuppressHTMLPreamble
    + +
    Ä̾ + HeaderName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤷ¤¿¥Õ¥¡¥¤¥ë¤ò + ¥Ç¥£¥ì¥¯¥È¥ê¤¬¼ÂºÝ¤Ë´Þ¤ó¤Ç¤¤¤ì¤Ð¡¢É¸½àŪ¤Ê HTML ¥×¥ê¥¢¥ó¥Ö¥ë + (<html>, <head>, Åù) ¤Î¸å¤Ë¡¢ + ¥â¥¸¥å¡¼¥ë¤Ï¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Þ¤¹¡£ + SuppressHTMLPreamble ¥ª¥×¥·¥ç¥ó¤Ï¡¢ + ¤³¤ÎµóÆ°¤ò̵¸ú¤Ë¤Ç¤­¤Æ¡¢ + ¥â¥¸¥å¡¼¥ë¤¬¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤«¤éɽ¼¨¤ò»Ï¤á¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ë¤ÏÀµ¤·¤¤ HTML + Ì¿Îá¤ò´Þ¤ó¤Ç¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ï¡¢¥×¥ê¥¢¥ó¥Ö¥ë¤ÏÄ̾ïÄ̤ê + À¸À®¤µ¤ì¤Þ¤¹¡£
    + +
    SuppressIcon (Apache + 2.0.23 °Ê¹ß)
    + +
    + ¤³¤ì¤Ï FancyIndexing ¤Î°ìÍ÷¤«¤é¥¢¥¤¥³¥ó¤ò¾Ãµî¤·¤Þ¤¹¡£ + SuppressIcon ¤È SuppressRules + ¤ÈÁȹç¤ï¤»¤ë¤³¤È¤Ë¤è¤Ã¤ÆÀµ¤·¤¤ HTML 3.2 ¤Î½ÐÎϤ¬ÆÀ¤é¤ì¤Þ¤¹¡£ + Àµ¤·¤¤ HTML 3.2 ½ÐÎϤϡ¢ºÇ½ªµ¬³Ê¤Ë¤ª¤¤¤Æ img ¤È hr + ¤¬ pre ¥Ö¥í¥Ã¥¯¤ËÆþ¤ë (FancyIndexing °ìÍ÷¤Ç½ñ¼°¤Ë»È¤ï¤ì¤Æ¤¤¤Þ¤¹) + ¤³¤È¤ò¶Ø»ß¤·¤Æ¤¤¤Þ¤¹¡£
    + +
    SuppressLastModified
    + +
    FancyIndexing °ìÍ÷¤Ë¤ª¤¤¤ÆºÇ½ª¹¹¿·Æü»þ¤Îɽ¼¨¤ò¾Ãµî¤·¤Þ¤¹¡£
    + +
    SuppressRules + (Apache 2.0.23 °Ê¹ß)
    + +
    ¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Ë¤ª¤¤¤Æ¿åÊ¿¶èÀÚ¤êÀþ (hr ¥¿¥°) ¤ò¾Ãµî¤·¤Þ¤¹¡£ + SuppressIcon ¤È SuppressRules + ¤ÈÁȹç¤ï¤»¤ë¤³¤È¤Ë¤è¤Ã¤ÆÀµ¤·¤¤ HTML 3.2 ¤Î½ÐÎϤ¬ÆÀ¤é¤ì¤Þ¤¹¡£ + Àµ¤·¤¤ HTML 3.2 ½ÐÎϤϡ¢ºÇ½ªµ¬³Ê¤Ë¤ª¤¤¤Æ img ¤È hr + ¤¬ pre ¥Ö¥í¥Ã¥¯¤ËÆþ¤ë (FancyIndexing °ìÍ÷¤Ç½ñ¼°¤Ë»È¤ï¤ì¤Æ¤¤¤Þ¤¹) + ¤³¤È¤ò¶Ø»ß¤·¤Æ¤¤¤Þ¤¹¡£
    + +
    SuppressSize
    + +
    FancyIndexing °ìÍ÷¤Ë¤ª¤¤¤Æ¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤Îɽ¼¨¤ò¾Ãµî¤·¤Þ¤¹¡£
    + +
    TrackModified + (Apache 2.0.23 °Ê¹ß)
    + +
    ¤³¤ì¤Ï HTTP ¥Ø¥Ã¥ÀÃæ¤Ë¡¢ + ¥ê¥¹¥È¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤ÎºÇ½ª¹¹¿·Æü¤ä ETag Ãͤò´Þ¤á¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ä¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ + ŬÀÚ¤Ê stat() ¤ÎÊÖ¤êÃͤòÊÖ¤¹¾ì¹ç¤Ë¤Î¤ßÍ­¸ú¤Ç¤¹¡£ + ¤¤¤¯¤Ä¤«¤Î UNIX ¥·¥¹¥Æ¥à¡¢OS2 ¤Î JFS ¤ä Win32 ¤Î NTFS + ¥Ü¥ê¥å¡¼¥à¤Ï¤½¤¦¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + Î㤨¤Ð¡¢OS2 ¤È Win32 FAT ¥Ü¥ê¥å¡¼¥à¤Ï¤½¤¦¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤³¤Îµ¡Ç½¤¬Í­¸ú¤Ë¤Ê¤ë¤È¡¢¥¯¥é¥¤¥¢¥ó¥È¤ä¥×¥í¥­¥·¤Ï + HEAD ¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤¦¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ¥Õ¥¡¥¤¥ë°ìÍ÷¤ÎÊѲ½¤òÄÉÀפ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¤¤¯¤Ä¤«¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ï¡¢¿·µ¬¥Õ¥¡¥¤¥ë¤ä + °ÜÆ°¥Õ¥¡¥¤¥ë¤ÏÀµ¤·¤¯ÄÉÀפ¹¤ë¤±¤ì¤É¤â¡¢ + ¥Ç¥£¥ì¥¯¥È¥êÃæ¤Î¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤äÆüÉÕ¤ÏÄÉÀפʤ¤¤È¤¤¤¦¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ´û¤Ë¸ºß¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤äÆüÉդΥ¹¥¿¥ó¥×¤¬ÊѲ½¤·¤Æ¤â¡¢ + Á´¤Æ¤Î Unix ¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Ï¡¢ + ºÇ½ª¹¹¿·Æü¥Ø¥Ã¥À¡¼¤ò¹¹¿·¤·¤Þ¤»¤ó¡£ + ¤â¤·¤³¤ì¤¬½ÅÍפǤ¢¤ì¤Ð¡¢ + ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò̵¸ú¤Î¤Þ¤Þ¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
    + +
    VersionSort + (Apache 2.0a3 °Ê¹ß)
    + +
    VersionSort ¥­¡¼¥ï¡¼¥É¤Ï¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤ò´Þ¤ó¤À¥Õ¥¡¥¤¥ë¤¬ + ¼«Á³¤ÊÊýË¡¤Ç¥½¡¼¥È¤µ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ʸ»úÎó¤ÏÄ̾ïÄ̤꥽¡¼¥È¤µ¤ì¡¢ + ¤½¤ì°Ê³°¤Î¡¢ÀâÌÀ¤ä̾Á°Ãæ¤Î¿ô¤È¤Ê¤ëÉôʬʸ»úÎó¤Ï + ¤½¤Î¿ôÃͤÇÈæ³Ó¤µ¤ì¤Þ¤¹¡£ + +

    Îã:

    + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +

    + +

    Èֹ椬 0 ¤«¤é»Ï¤Þ¤ë¾ì¹ç¤Ï¡¢Ã¼¿ô¤È¹Í¤¨¤é¤ì¤Þ¤¹

    + +

    + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +

    +
    + +
    XHTML + (Apache 2.0.49 °Ê¹ß)
    + +
    XHTML ¥­¡¼¥ï¡¼¥É¤ò»ØÄꤹ¤ë¤È¡¢mod_autoindex + ¤Ï HTML 3.2 ¤ÎÂå¤ï¤ê¤Ë XHTML 1.0 ¤Î¥³¡¼¥É¤ò½ÐÎϤ¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
    +
    + + +
    Áý¸º»ØÄê¤Ç¤­¤ë IndexOptions
    +
    +

    Apache 1.3.3 ¤Ç¤Ï¡¢ + IndexOptions + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°·¤¤¤Ç´ö¤Ä¤«¤ÎÂ礭¤ÊÊѲ½¤¬Æ³Æþ¤µ¤ì¤Þ¤·¤¿¡£ + Æäˡ¢

    + +
      +
    • °ì¤Ä¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ¹¤ëÊ£¿ô¤Î + IndexOptions + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¸½ºß¤Ç¤Ï°ì¤Ä¤Ë¥Þ¡¼¥¸¤µ¤ì¤Þ¤¹¡£ + ¾å¤ÎÎã¤Î·ë²Ì¤Ï¡¢ + +

      + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +

      + +

      ¤ÈƱ°ì¤Ë¤Ê¤ê¤Þ¤¹¡£

      + +

      + IndexOptions HTMLTable SuppressColumnsorting +

      +
    • + +
    • Áý¸º¹½Ê¸ + (¤¹¤Ê¤ï¤Á¡¢'+' ¤ä '-' + ¤ÎÀÜƬ¼­¤¬ÉÕ¤¯¥­¡¼¥ï¡¼¥É) ¤ÎÄɲá£
    • +
    + +

    '+' ¤ä '-' ÀÜƬ¼­¤ÎÉÕ¤¤¤¿¥­¡¼¥ï¡¼¥É¤Ë½Ð²ñ¤¦¤È¤½¤ì¤Ï¡¢ + ¤½¤Î»þÅÀ¤Ç¤Î IndexOptions + ¤ÎÀßÄê (¤³¤ì¤Ï¾åή¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¼õ¤±·Ñ¤®¤Þ¤¹) + ¤ËÂФ·¤ÆŬ±þ¤µ¤ì¤Þ¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢ÀÜƬ¼­¤ÎÉÕ¤«¤Ê¤¤¥­¡¼¥ï¡¼¥É¤¬½èÍý¤µ¤ì¤¿¾ì¹ç¤Ï¡¢ + ¼õ¤±·Ñ¤¤¤À¥ª¥×¥·¥ç¥óÁ´¤Æ¤È¤½¤ì¤Þ¤Ç½Ð²ñ¤Ã¤¿Áý¸ºÀßÄêÁ´¤Æ¤¬ + ¾Ãµî¤µ¤ì¤Þ¤¹¡£¼¡¤ÎÎã¤ò¹Í¤¨¤Æ¤ß¤Æ¤¯¤À¤µ¤¤:

    + +

    + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +

    + +

    Ãæ¿È¤Î¸ú²Ì¤Ï + IndexOptions FancyIndexing +SuppressSize + ¤ÈƱ°ì¤Ç¤¹¡£ + ÀÜƬ¼­¤ÎÉÕ¤«¤Ê¤¤ FancyIndexing + ¤Ç¤½¤ì°ÊÁ°¤ÎÁý¸º¥­¡¼¥ï¡¼¥É¤ò̵¸ú¤Ë¤µ¤ì¤Æ¡¢ + ¤½¤Î¸å¤ÎÎßÀѤ¬»Ï¤Þ¤ë¤«¤é¤Ç¤¹¡£

    + +

    ̵¾ò·ï¤Ë IndexOptions + ¤ò¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ÇÀßÄꤹ¤ë¤³¤È¤Ë¤è¤Ã¤Æ + ·Ñ¾µ¤·¤¿ÀßÄê¤ò¾Ãµî¤·¤Æ¡¢+ ¤ä - + ÀÜƬ¼­¤ÎÉÕ¤«¤Ê¤¤¥­¡¼¥ï¡¼¥É¤ÇÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    + +
    +
    top
    +

    IndexOrderDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ: +¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤Îɸ½à¤Î½çÈÖÉÕ¤±¤òÀßÄê
    ¹½Ê¸:IndexOrderDefault Ascending|Descending +Name|Date|Size|Description
    ¥Ç¥Õ¥©¥ë¥È:IndexOrderDefault Ascending Name
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    IndexOrderDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + FancyIndexing + ¥¤¥ó¥Ç¥Ã¥¯¥¹¥ª¥×¥·¥ç¥ó¤ÈÊ»¤»¤ÆÍѤ¤¤ì¤ì¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢FancyIndexing + ¤Î¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Ï¥Õ¥¡¥¤¥ë̾¤Î¾º½ç¤Çɽ¼¨¤µ¤ì¤Þ¤¹¡£ + IndexOrderDefault + ¤Ç¡¢½é´ü¾õÂÖ¤Îɽ¼¨½çÈÖ¤òÊѤ¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    IndexOrderDefault + ¤ÏÆó¤Ä¤Î°ú¿ô¤ò¤È¤ê¤Þ¤¹¡£°ì¤ÄÌܤϥ½¡¼¥È¤ÎÊý¸þ¤ò»Ø¼¨¤¹¤ë + Ascending ¤« Descending ¤Î¤¤¤º¤ì¤«¤Ç¤¹¡£ + Æó¤ÄÌܤΰú¿ô¤Ï Name, Date, + Size ¤« Description + ¤Î¤¤¤º¤ì¤«°ì¤Ä¤Î¥­¡¼¥ï¡¼¥É¤Ç¤¢¤Ã¤Æ¡¢¥×¥é¥¤¥Þ¥ê¥­¡¼¤ò»ØÄꤷ¤Þ¤¹¡£ + Æó¤ÄÌܤΥ­¡¼¤Ï¾ï¤Ë¥Õ¥¡¥¤¥ë̾¤Î¾º½ç¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È SuppressColumnSorting + ¥¤¥ó¥Ç¥Ã¥¯¥¹¥ª¥×¥·¥ç¥ó¤È¤òÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤ò¤¢¤ëÆÃÄê¤Î½çÈ֤ǤΤßɽ¼¨¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤¬Ê̤νçÈ֤ǥǥ£¥ì¥¯¥È¥ê°ìÍ÷¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ë¤³¤È¤òËɤ®¤Þ¤¹¡£

    + +
    +
    top
    +

    IndexStyleSheet ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ë CSS ¥¹¥¿¥¤¥ë¥·¡¼¥È¤òÄɲ乤ë
    ¹½Ê¸:IndexStyleSheet url-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    IndexStyleSheet ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥¤¥ó¥Ç¥Ã¥¯¥¹É½¼¨¤Ë»ÈÍѤµ¤ì¤ë CSS ¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤷ¤Þ¤¹¡£ +

    +

    Îã

    + + IndexStyleSheet "/css/style.css" +

    + +
    +
    top
    +

    ReadmeName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¤¥ó¥Ç¥Ã¥¯¥¹°ìÍ÷¤ÎºÇ¸å¤ËÁÞÆþ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°
    ¹½Ê¸:ReadmeName filename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_autoindex
    +

    ReadmeName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Î½ª¤ï¤ê¤ËÉÕ¤±²Ã¤¨¤é¤ì¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤷ¤Þ¤¹¡£ + filename ¤ÏÁÞÆþ¤¹¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°¤Ç¡¢ + °ìÍ÷¤Î¹Ô¤ï¤ì¤Æ¤¤¤ë°ÌÃÖ¤«¤éÁêÂÐŪ¤Ê¤â¤Î¤È¤·¤Æ²ò¼á¤µ¤ì¤Þ¤¹¡£ + filename ¤¬¥¹¥é¥Ã¥·¥å¤Ç»Ï¤Þ¤ë¾ì¹ç¤Ï¡¢ + DocumentRoot + ¤«¤é¤ÎÁêÂХѥ¹¤È¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + ReadmeName FOOTER.html +

    + +

    Îã 2

    + ReadmeName /include/FOOTER.html +

    + +

    ¤è¤ê¾ÜºÙ¤Ë¤Þ¤Ç¤³¤ÎµóÆ°¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Æ¤¤¤ë HeaderName + ¤â¤´Í÷²¼¤µ¤¤¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_autoindex.html.ko.euc-kr b/trunk/docs/manual/mod/mod_autoindex.html.ko.euc-kr new file mode 100644 index 0000000000..a1be084d83 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.html.ko.euc-kr @@ -0,0 +1,835 @@ + + + +mod_autoindex - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_autoindex

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:ÀÚµ¿À¸·Î À¯´Ð½ºÀÇ ls ¸í·É¾î³ª Win32ÀÇ + dir ½©¸í·É¾î¿Í À¯»çÇÑ µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:autoindex_module
    ¼Ò½ºÆÄÀÏ:mod_autoindex.c
    +

    ¿ä¾à

    + +

    µð·ºÅ丮 ¸ñ·ÏÀº ¾ò´Â ¹æ¹ýÀº µÎ°¡Áö´Ù:

    + +
      +
    • º¸Åë index.htmlÀ̶õ À̸§À¸·Î »ç¿ëÀÚ°¡ + ÀÛ¼ºÇÑ ÆÄÀÏ. ÀÌ ÆÄÀÏÀÇ À̸§Àº DirectoryIndex Áö½Ã¾î·Î + ÁöÁ¤ÇÑ´Ù. ÀÌ ÀÛ¾÷Àº mod_dirÀÌ ÇÑ´Ù.
    • + +
    • ¾Æ´Ï¸é ¼­¹ö°¡ ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ ¸ñ·ÏÀÇ Çü½ÄÀ» ÁöÁ¤ÇÏ´Â + Áö½Ã¾îµéÀÌ ÀÖ´Ù. AddIcon, AddIconByEncoding, + AddIconByTypeÀº + ¿©·¯ ÆÄÀÏÁ¾·ù¸¶´Ù º¸¿©ÁÙ ¾ÆÀÌÄܵéÀ» ÁöÁ¤ÇÑ´Ù. °¢ ÆÄÀÏ¿¡ + ´ëÀÀÇϴ ù¹ø° ¾ÆÀÌÄÜÀ» º¸ÀδÙ. ÀÌ ÀÛ¾÷À» + mod_autoindex°¡ ÇÑ´Ù.
    • +
    +

    ÀÌ µÎ ±â´ÉÀº ¼­·Î º°°³·Î, ¿øÇÑ´Ù¸é ÀÚµ¿ ¸ñ·Ï »ý¼ºÀ» ¿ÏÀüÈ÷ + Á¦¿ÜÇÒ (ȤÀº ´ëüÇÒ) ¼ö ÀÖ´Ù.

    + +

    ÀÚµ¿ ¸ñ·Ï »ý¼ºÀº Options +Indexes·Î °¡´ÉÇÏ´Ù. + ÀÚ¼¼ÇÑ ³»¿ëÀº Options + Áö½Ã¾î¸¦ Âü°íÇ϶ó.

    + +

    IndexOptions + Áö½Ã¾î¿¡ FancyIndexing ¿É¼ÇÀ» ÁÖ¸é, ¿­ À̸§À» Ãâ·ÂÇÒ + ¼ø¼­¸¦ ¹Ù²Ù´Â ¸µÅ©·Î ¸¸µç´Ù. À̸§ ¸µÅ©¸¦ ¼±ÅÃÇÏ¸é ±× ¿­ÀÇ + °ª ¼ø¼­·Î ¸ñ·ÏÀ» ´Ù½Ã ¸¸µç´Ù. °°Àº À̸§À» ¹Ýº¹Çؼ­ ¼±ÅÃÇϸé + ¿À¸§Â÷¼ø°ú ³»¸²Â÷¼ø »çÀ̸¦ ¿À°£´Ù. IndexOptions Áö½Ã¾îÀÇ + SuppressColumnSorting ¿É¼ÇÀº ÀÌ·± ¿­ À̸§ ¸µÅ©¸¦ + ¸¸µéÁö ¾Ê´Â´Ù.

    + +

    "Size(Å©±â)" ¼øÀ¸·Î º¼¶§ Ãâ·ÂµÇ´Â °ª ¼ø¼­°¡ ¾Æ´Ï¶ó ½ÇÁ¦ + ÆÄÀÏÅ©±â ¼ø¼­ÀÓÀ» ÁÖÀÇÇ϶ó. Áï, 1010 ¹ÙÀÌÆ® ÆÄÀÏ°ú 1011 + ¹ÙÀÌÆ® ÆÄÀÏÀº µÑ´Ù "1K"·Î º¸ÀÌ´õ¶óµµ Ç×»ó 1010 ¹ÙÀÌÆ® ÆÄÀÏÀÌ + ¾Õ¿¡ ³ª¿Â´Ù.

    +
    + +
    top
    +
    +

    Autoindex ¿äû ¾Æ±Ô¸ÕÆ®

    + + +

    ¾ÆÆÄÄ¡ 2.0.23´Â ¿­¼ø¼­¿¡ ´ëÇÑ ¿äû ¾Æ±Ô¸ÕÆ®¸¦ Á¤¸®ÇÏ°í, + »õ·Î¿î ¿É¼ÇµéÀ» Ãß°¡Çß´Ù. Ãâ·ÂÀ» Ŭ¶óÀ̾ðÆ®°¡ Á¶ÀýÇÒ ¼ö + ¾øµµ·Ï ¸¸µå´Â IndexOptions + IgnoreClient ¿É¼ÇÀÌ Ãß°¡µÇ¾ú´Ù.

    + +

    ¿­¼ø¼­ À̸§Àº ¾Æ·¡ ³ª¿Â ¼ø¼­ ¿äû ¿É¼ÇÀ» ´õÇÑ ÀÚ±âÂüÁ¶ + ¸µÅ©´Ù. ¾Æ·¡ ¿É¼ÇÀº µð·ºÅ丮 ÀÚ¿ø¿¡ ´ëÇÑ ¾î¶² ¿äû¿¡µµ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
      +
    • C=NÀº ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=MÀº ÃÖ±Ù ¼öÁ¤ÀÏ ¼ø, ±×¸®°í ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=S´Â Å©±â ¼ø, ±×¸®°í ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=D´Â ¼³¸í ¼ø, ±×¸®°í ÆÄÀϸí + ¼øÀÌ´Ù
    • + +
    • O=A´Â ¿À¸§Â÷¼øÀ¸·Î ¸ñ·ÏÀ» Á¤·ÄÇÑ´Ù
    • + +
    • O=D´Â ³»¸²Â÷¼øÀ¸·Î ¸ñ·ÏÀ» Á¤·ÄÇÑ´Ù
    • + +
    • F=0Àº (FancyIndexed°¡ ¾Æ´Ñ) °£´ÜÇÑ ¸ñ·Ï Çü½ÄÀÌ´Ù
    • + +
    • F=1Àº FancyIndexed ¸ñ·Ï Çü½ÄÀÌ´Ù
    • + +
    • F=2´Â HTMLTable FancyIndexed ¸ñ·Ï + Çü½ÄÀÌ´Ù
    • + +
    • V=0Àº ¹öÀü ¼øÀ¸·Î Á¤·ÄÇÏÁö ¾Ê´Â´Ù
    • + +
    • V=1Àº ¹öÀü ¼øÀ¸·Î Á¤·ÄÇÑ´Ù
    • + +
    • P=patternÀº ÁÖ¾îÁø pattern¿¡ + ÇØ´çÇÏ´Â ÆÄÀϸ¸À» ¸ñ·ÏÀ¸·Î ¸¸µç´Ù
    • +
    + +

    'P'attern ¾Æ±Ô¸ÕÆ®´Â ÀϹÝÀûÀÎ IndexIgnore Áö½Ã¾î¸¦ ó¸®ÇÑ ÈÄ¿¡ + °Ë»çÇϱ⶧¹®¿¡, ¸ñ·ÏÀº ´Ù¸¥ autoindex Á¶°ÇÀ» µû¸§À» ÁÖÀÇÇ϶ó. + mod_autoindexÀÇ ¿äû ¾Æ±Ô¸ÕÆ®¸¦ ÀоîµéÀ϶§ + ¾Ë ¼ö ¾ø´Â ¿É¼ÇÀ» ¹ß°ßÇÏ¸é ´õ ÀÌ»ó ÀÐÁö¾Ê´Â´Ù. ¿äû ¾Æ±Ô¸ÕÆ®´Â + À§ÀÇ Ç¥¿¡ µû¶ó ¸¸µé¾î¾ß ÇÑ´Ù.

    + +

    header.html ÆÄÀÏ¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¾Æ·¡ °£´ÜÇÑ ¿¹Á¦´Â + ÀÌ ¿É¼ÇµéÀ» ¼³¸íÇÑ´Ù. submit ¹öÅÏÀÇ ¾Ë ¼ö ¾ø´Â "X" ¾Æ±Ô¸ÕÆ®´Â + mod_autoindex°¡ X=Go Àü±îÁö ¸ðµç ¾Æ±Ô¸ÕÆ®¸¦ ÀоîµéÀÓÀ» + È®ÀÎÇϱâÀ§ÇØ ¸¶Áö¸·¿¡ »ç¿ëÇß´Ù.

    + +

    + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +

    + +
    +
    top
    +

    AddAlt Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÆÄÀϸíÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ ¼³¸í±Û
    ¹®¹ý:AddAlt string file [file] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    AddAlt´Â FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. File¿¡´Â + ¼³¸íÇÒ ÆÄÀÏÀÇ ÆÄÀÏ È®ÀåÀÚ, ÆÄÀϸí ÀϺÎ, ¿ÍÀϵåÄ«µå Ç¥Çö, + Àüü ÆÄÀϸíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. String¿¡ °ø¹éÀÌ + µé¾î°£´Ù¸é µû¿ÈÇ¥(" ȤÀº ')·Î + ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ + ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + +

    ¿¹Á¦

    + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +

    + +
    +
    top
    +

    AddAltByEncoding Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:MIME-encodingÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û
    ¹®¹ý:AddAltByEncoding string MIME-encoding +[MIME-encoding] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    AddAltByEncodingÀº FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. MIME-encodingÀº + x-compress¿Í °°Àº À¯È¿ÇÑ content-encodingÀÌ´Ù. + String¿¡ °ø¹éÀÌ µé¾î°£´Ù¸é µû¿ÈÇ¥(" + ȤÀº ')·Î ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ + º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì + ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + +

    ¿¹Á¦

    + AddAltByEncoding gzip x-gzip +

    + +
    +
    top
    +

    AddAltByType Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û
    ¹®¹ý:AddAltByType string MIME-type +[MIME-type] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    AddAltByTypeÀº FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. MIME-typeÀº + text/html°ú °°Àº À¯È¿ÇÑ content-typeÀÌ´Ù. + String¿¡ °ø¹éÀÌ µé¾î°£´Ù¸é µû¿ÈÇ¥(" + ȤÀº ')·Î ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ + º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì + ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + +

    ¿¹Á¦

    + AddAltByType 'plain text' text/plain +

    + +
    +
    top
    +

    AddDescription Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÆÄÀÏ¿¡ ´ëÇÑ ¼³¸í
    ¹®¹ý:AddDescription string file [file] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ ÆÄÀÏ¿¡ ´ëÇÑ ¼³¸íÀ» ÁöÁ¤ÇÑ´Ù. + File¿¡´Â ¼³¸íÇÒ ÆÄÀÏÀÇ ÆÄÀÏ È®ÀåÀÚ, ÆÄÀϸí ÀϺÎ, + ¿ÍÀϵåÄ«µå Ç¥Çö, Àüü ÆÄÀϸíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. StringÀº + µû¿ÈÇ¥(")·Î ¹­¾î¾ß ÇÑ´Ù.

    + +

    ¿¹Á¦

    + AddDescription "The planet Mars" /web/pics/mars.gif +

    + +

    ÀüÇüÀûÀÎ ±âº» ¼³¸í ÇʵåÆøÀº 23 ¹ÙÀÌÆ®´Ù. IndexOptions + SuppressIcon ¿É¼ÇÀ» »ç¿ëÇÏ¸é ±âº»Æø¿¡ 6 ¹ÙÀÌÆ®¸¦ + ´õ Ãß°¡ÇÏ°í, IndexOptions SuppressSize ¿É¼ÇÀº 7 ¹ÙÀÌÆ®¸¦, + IndexOptions SuppressLastModified ¿É¼ÇÀº 19 + ¹ÙÀÌÆ®¸¦ ´õ Ãß°¡ÇÑ´Ù. ±×·¯¹Ç·Î °¡Àå ³ÐÀº ¼³¸íÆøÀº 55 ¹ÙÀÌÆ®´Ù.

    + +

    ÀÌ ÇʵåÀÇ Æø¸¦ ¹Ù²Ù°Å³ª ¼³¸íÀÇ ±æÀ̸¦ ¹«ÇÑ´ë·Î ¸¸µå·Á¸é + DescriptionWidth IndexOptions Å°¿öµå¸¦ Âü°íÇ϶ó.

    + +

    Á¶½É

    +

    AddDescriptionÀ¸·Î ÁöÁ¤ÇÑ ¼³¸í±Û¿¡ + ű׳ª character entity(¿ªÁÖ; &lt;, &amp; µîÀ» + ÁöĪ)°°Àº HTMLÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Æø¶§¹®¿¡ + űװ¡ ÀÖ´Â ºÎºÐÀÌ Â©¸®°ÔµÇ¸é (¿¹¸¦ µé¾î ±½ÀºÃ¼ ºÎºÐ ³¡ÀÌ + ©¸®¸é) ³ª¸ÓÁö µð·ºÅ丮 ¸ñ·Ï¿¡ ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù.

    +
    + +
    +
    top
    +

    AddIcon Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:À̸§À¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    ¹®¹ý:AddIcon icon name [name] +...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ nameÀ¸·Î ³¡³ª´Â + ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. IconÀº + ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    Name¿¡´Â µð·ºÅ丮¸¦ ³ªÅ¸³»´Â ^^DIRECTORY^^, + (¸ñ·Ï Çü½ÄÀ» ¿Ã¹Ù·Î ¸ÂÃß±âÀ§ÇØ) ºóÁÙÀ» ³ªÅ¸³»´Â + ^^BLANKICON^^, ÆÄÀÏ È®ÀåÀÚ, ¿ÍÀϵåÄ«µå Ç¥Çö, + ÆÄÀϸí ÀϺΠȤÀº Àüü¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦

    + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +

    + +

    °¡´ÉÇϸé AddIconº¸´Ù´Â AddIconByTypeÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +
    +
    top
    +

    AddIconByEncoding Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:MIME content-encodingÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    ¹®¹ý:AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ + ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. IconÀº + ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    MIME-encoding´Â content-encoding¿¡ ÇØ´çÇÏ´Â + ¿ÍÀϵåÄ«µå Ç¥ÇöÀÌ´Ù.

    + +

    ¿¹Á¦

    + AddIconByEncoding /icons/compress.xbm x-compress +

    + +
    +
    top
    +

    AddIconByType Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    ¹®¹ý:AddIconByType icon MIME-type +[MIME-type] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ + MIME-typeÀÇ ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. + IconÀº ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    MIME-typeÀº mime type¿¡ ÇØ´çÇÏ´Â ¿ÍÀϵåÄ«µå + Ç¥ÇöÀÌ´Ù.

    + +

    ¿¹Á¦

    + AddIconByType (IMG,/icons/image.xbm) image/* +

    + +
    +
    top
    +

    DefaultIcon Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ƯÁ¤ ¾ÆÀÌÄÜÀ» ¼³Á¤ÇÏÁö¾ÊÀº ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    ¹®¹ý:DefaultIcon url-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    DefaultIcon Áö½Ã¾î´Â FancyIndexing¿¡¼­ + ƯÁ¤ ¾ÆÀÌÄÜÀ» ¼³Á¤ÇÏÁö¾ÊÀº ÆÄÀÏ ¿·¿¡ ³ª¿Ã ¾ÆÀÌÄÜÀÌ´Ù. + IconÀº ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URLÀÌ´Ù.

    + +

    ¿¹Á¦

    + DefaultIcon /icon/unknown.xbm +

    + +
    +
    top
    +

    HeaderName Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÆÄÀϸñ·Ï À§¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§
    ¹®¹ý:HeaderName filename
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    HeaderName Áö½Ã¾î´Â ÆÄÀϸñ·Ï ¾Õ¿¡ + »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. FilenameÀº »ðÀÔÇÒ + ÆÄÀϸíÀÌ´Ù.

    + +

    ¿¹Á¦

    + HeaderName HEADER.html +

    + +
    +

    ÇöÀç HeaderName°ú ReadmeName µÑ ¸ðµÎ + FilenameÀ» Á¢±ÙÇÏ·Á´Â µð·ºÅ丮ÀÇ »ó´ë URI °æ·Î·Î + ¹Þ¾ÆµéÀδÙ. FilenameÀÌ ½½·¡½¬·Î ½ÃÀÛÇϸé DocumentRoot¿¡ »ó´ëÀûÀÎ °æ·Î·Î + ¹Þ¾ÆµéÀδÙ.

    + +

    ¿¹Á¦

    + HeaderName /include/HEADER.html +

    + +

    Filename¿¡´Â major content typeÀÌ text/*ÀÎ + (¿¹¸¦ µé¾î, text/html, text/plain, + µî) ¹®¼­¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. Áï, ½ºÅ©¸³Æ®ÀÇ (Ãâ·ÂÀÌ ¾Æ´Ñ) ½ÇÁ¦ ÆÄÀÏ + typeÀ» ´ÙÀ½°ú °°ÀÌ text/html·Î ÁöÁ¤ÇÑ´Ù¸é + filenameÀ¸·Î CGI ½ºÅ©¸³Æ®¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù:

    + +

    + AddType text/html .cgi +

    + +

    Options + MultiViewsÀ» »ç¿ëÇÏ¸é ³»¿ëÇù»óÀ» ÇÑ´Ù. + filenameÀÌ (CGI ½ºÅ©¸³Æ®°¡ ¾Æ´Ñ) °íÁ¤µÈ + text/html ¹®¼­ÀÌ°í options Includes³ª + IncludesNOEXEC Áß Çϳª¸¦ »ç¿ëÇÑ´Ù¸é ÆÄÀÏÀ» + server-side includes·Î ó¸®ÇÑ´Ù. (mod_include + ¹®¼­ Âü°í)

    +
    + +

    HeaderNameÀ¸·Î ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ + (<html>, <head>, µî) HTML ¹®¼­ ½ÃÀۺκÐÀÌ Æ÷ÇÔµÇÀÖ´Ù¸é + IndexOptions + +SuppressHTMLPreambleÀ» »ç¿ëÇÏ¿© ÀÌ ºÎºÐÀ» Ãß°¡ÇÏÁö¾Ê´Â + °ÍÀÌ ÁÁ´Ù.

    + +
    +
    top
    +

    IndexIgnore Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:µð·ºÅ丮 ¸ñ·Ï¿¡¼­ ¼û±æ ÆÄÀϸñ·ÏÀ» Ãß°¡ÇÑ´Ù
    ¹®¹ý:IndexIgnore file [file] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    IndexIgnore Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ °¨Ãâ ÆÄÀϸñ·ÏÀ» Ãß°¡ÇÑ´Ù. File¿¡´Â °¨Ãâ + (½©¿¡¼­ »ç¿ëÇÏ´Â) È­ÀϵåÄ«µå Ç¥ÇöÀ̳ª Àüü ÆÄÀϸíÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿©·¯ IndexIgnore Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ±âÁ¸ÀÇ + °¨Ãâ ÆÄÀϸñ·ÏÀ» ´ëüÇÏÁö¾Ê°í ¸ñ·Ï¿¡ ÁöÁ¤ÇÑ ÆÄÀϵéÀ» Ãß°¡ÇÑ´Ù. + ±âº»ÀûÀ¸·Î ¸ñ·ÏÀº .À» (ÇöÀç µð·ºÅ丮) Æ÷ÇÔÇÑ´Ù.

    + +

    + IndexIgnore README .htaccess *.bak *~ +

    + +
    +
    top
    +

    IndexOptions Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:µð·ºÅ丮 ¸ñ·ÏÀÇ ¿©·¯ ¼³Á¤µé
    ¹®¹ý:IndexOptions [+|-]option [[+|-]option] +...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    IndexOptions Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·ÏÀ» ¼³Á¤ÇÑ´Ù. OptionÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù

    + +
    +
    DescriptionWidth=[n | *] (¾ÆÆÄÄ¡ + 2.0.23 ÀÌÈÄ)
    + +
    DescriptionWidth Å°¿öµå¸¦ »ç¿ëÇÏ¿© ¹®ÀÚ´ÜÀ§·Î + ¼³¸í¿­ÀÇ ÆøÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    -DescriptionWidth¸¦ ÁöÁ¤Çϸé (ȤÀº ¾Æ¹«°Íµµ + ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é) mod_autoindex°¡ ÃÖÀûÀÇ + ÆøÀ» °è»êÇÑ´Ù.
    + +
    DescriptionWidth=nÀº ¿­ÀÇ + ÆøÀ» n ¹ÙÀÌÆ®·Î °íÁ¤ÇÑ´Ù.
    + +
    DescriptionWidth=*Àº ¿­ÀÇ ÆøÀ» °¡Àå ±ä + ¼³¸í±ÛÀ» ´ãÀ» ¼ö Àִ¸¸Å­ ´Ã¸°´Ù.
    + +
    ¼³Á¤ÀÌ Â©¸± ¼ö ÀÖ´Â ¹®Á¦´Â AddDescription + ÀýÀ» Âü°íÇ϶ó.
    + +
    FancyIndexing
    + +
    µð·ºÅ丮ÀÇ fancy ¸ñ·ÏÀ» ¸¸µç´Ù.
    + +
    FoldersFirst + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé ÇÏÀ§µð·ºÅ丮 ¸ñ·ÏÀÌ Ç×»ó + ¸ÕÀú ³ª¿À°í, µð·ºÅ丮¿¡ ÀÖ´Â ÀÏ¹Ý ÆÄÀÏÀÌ µÚ¿¡ ³ª¿Â´Ù. + ±âº»ÀûÀ¸·Î ¸ñ·ÏÀº ÆÄÀÏ°ú ÇÏÀ§µð·ºÅ丮·Î ³ª´µ°í, µû·Î + °¢°¢ÀÇ ¼ø¼­¸¦ Á¤¸®ÇÏ¿© ÇÏÀ§µð·ºÅ丮µéÀ» ¸ÕÀú º¸ÀδÙ. + ¿¹¸¦ µé¾î, À̸§ ¿ª¼øÀ¸·Î Á¤·ÄÇÏ°í FoldersFirst¸¦ + »ç¿ëÇÑ´Ù¸é ÇÏÀ§µð·ºÅ丮 Zed°¡ ÇÏÀ§µð·ºÅ丮 + Beta ¾Õ¿¡ ³ª¿À°í, ÇÏÀ§µð·ºÅ丮 Beta´Â + ÀÏ¹Ý ÆÄÀÏ Gamma¿Í Alpha ¾Õ¿¡ + ³ª¿Â´Ù. ÀÌ ¿É¼ÇÀº FancyIndexingÀ» ÇÔ²² »ç¿ëÇÒ¶§¸¸ È¿°ú°¡ + ÀÖ´Ù.
    + +
    HTMLTable (½ÇÇèÀû, + ¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    ÀÌ ½ÇÇèÀûÀÎ FancyIndexing ¿É¼ÇÀº °£´ÜÇÑ HTML Ç¥·Î + fancy µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ ¿É¼ÇÀº ¿À·¡µÈ ºê¶ó¿ìÀú¸¦ + È¥¶õ½º·´°Ô ÇÒ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó. ÀÌ ¿É¼ÇÀº WinNT³ª ´Ù¸¥ + utf-8 »ç¿ë Ç÷¡Æû¿¡¼­ ÆÄÀϸíÀ̳ª ¼³¸í¹®ÀÇ Àб⠼ø¼­(¿ÞÂÊ¿¡¼­ + ¿À¸¥ÂÊ È¤Àº ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î)°¡ ´Ù¸¦¶§ Ưº°È÷ À¯¿ëÇÏ´Ù.
    + +
    IconsAreLinks
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏ¸í ¸µÅ©¿¡ ¾ÆÀÌÄÜÀ» Æ÷ÇÔÇÑ´Ù.
    + +
    IconHeight[=pixels]
    + +
    ÀÌ ¿É¼ÇÀ» IconWidth¿Í °°ÀÌ »ç¿ëÇÏ¸é ¼­¹ö´Â ÆÄÀÏ ¾ÆÀÌÄÜÀÇ + img ű׿¡ height¿Í width + ¼Ó¼ºÀ» Æ÷ÇÔÇÑ´Ù. ±×·¯¸é ºê¶ó¿ìÀú´Â ¸ðµç À̹ÌÁö¸¦ ¹ÞÁö¾ÊÀº + »óȲ¿¡¼­µµ ÆäÀÌÁö ±¸¼ºÀ» ¹Ì¸® °è»êÇÒ ¼ö ÀÖ´Ù. ¿É¼Ç¿¡ °ªÀ» + ÁÖÁö¾ÊÀ¸¸é ¾ÆÆÄÄ¡°¡ Á¦°øÇÏ´Â ¾ÆÀÌÄÜÀÇ Ç¥ÁØ ³ôÀ̸¦ »ç¿ëÇÑ´Ù.
    + +
    IconWidth[=pixels]
    + +
    ÀÌ ¿É¼ÇÀ» IconHeight¿Í °°ÀÌ »ç¿ëÇϸé + ¼­¹ö´Â ÆÄÀÏ ¾ÆÀÌÄÜÀÇ img ű׿¡ + height¿Í width ¼Ó¼ºÀ» Æ÷ÇÔÇÑ´Ù. + ±×·¯¸é ºê¶ó¿ìÀú´Â ¸ðµç À̹ÌÁö¸¦ ¹ÚÁö¾ÊÀº »óȲ¿¡¼­µµ ÆäÀÌÁö + ±¸¼ºÀ» ¹Ì¸® °è»êÇÒ ¼ö ÀÖ´Ù. ¿É¼Ç¿¡ °ªÀ» ÁÖÁö¾ÊÀ¸¸é ¾ÆÆÄÄ¡°¡ + Á¦°øÇÏ´Â ¾ÆÀÌÄÜÀÇ Ç¥ÁØ ÆøÀ» »ç¿ëÇÑ´Ù.
    + +
    IgnoreCase
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¸é ´ë¼Ò¹®ÀÚ ±¸º°ÇÏÁö¾Ê°í À̸§À» Á¤·ÄÇÑ´Ù. + ¿¹¸¦ µé¾î, À̸§À¸·Î ¿À¸§Â÷¼øÀÌ°í IgnoreCase¸¦ »ç¿ëÇϸé + ÆÄÀÏ Zeta´Â ÆÄÀÏ alfa µÚ¿¡ ³ª¿Â´Ù (ÁÖÀÇ: ÆÄÀÏ GAMMA´Â + Ç×»ó ÆÄÀÏ gamma ¾Õ¿¡ ³ª¿Â´Ù).
    + +
    IgnoreClient
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé mod_autoindex´Â + ¼ø¼­¸¦ Æ÷ÇÔÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ º¸³»´Â ¸ðµç ÁúÀǺ¯¼ö¸¦ ¹«½ÃÇÑ´Ù. + (SuppressColumnSortingÀ» °¡Á¤ÇÑ´Ù.)
    + +
    NameWidth=[n + | *]
    + +
    NameWidth Å°¿öµå´Â ¹ÙÀÌÆ®´ÜÀ§·Î ÆÄÀϸí + ¿­ÀÇ ÆøÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    -NameWidthÀ» ÁöÁ¤Çϸé (ȤÀº ¾Æ¹«°Íµµ + ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é) mod_autoindex°¡ ÃÖÀûÀÇ + ÆøÀ» °è»êÇÑ´Ù.
    + +
    NameWidth=n´Â ¿­ÀÇ ÆøÀ» n + ¹ÙÀÌÆ®·Î °íÁ¤ÇÑ´Ù.
    + +
    NameWidth=*Àº ¿­ÀÇ ÆøÀ» ÇÊ¿äÇѸ¸Å­ ´Ã¸°´Ù.
    + +
    ScanHTMLTitles
    + +
    fancy ¸ñ·Ï¿¡¼­ HTML ¹®¼­ÀÇ titleÀ» »Ì´Â´Ù. ÆÄÀÏ¿¡ + AddDescription·Î + ÁöÁ¤ÇÑ ¼³¸íÀÌ ¾ø´Ù¸é À¥¼­¹ö´Â ¹®¼­ÀÇ title + ¿ä¼Ò°ªÀ» ÀоîµéÀδÙ. ÀÌ ÀÛ¾÷Àº CPU¿Í µð½ºÅ©¸¦ ¸¹ÀÌ »ç¿ëÇÑ´Ù.
    + +
    SuppressColumnSorting
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â FancyIndexed µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ ¿­ À̸§À» ¼ø¼­¸¦ ¹Ù²Ù´Â ¸µÅ©·Î ¸¸µéÁö ¾Ê´Â´Ù. + º¸ÅëÀº ¿­ À̸§À» ¸µÅ©·Î ¸¸µé¾î¼­, ¿­ À̸§À» ¼±ÅÃÇÏ¸é ±× + ¿­¿¡ ÀÖ´Â °ª¼ø¼­·Î µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ¾ÆÆÄÄ¡ + 2.0.23 ÀÌÀü¿¡´Â ¼ø¼­ ¾Æ±Ô¸ÕÆ®µµ ÀÐÁö ¾Ê¾Ò´Ù. + ¾ÆÆÄÄ¡ 2.0.23¿¡¼­´Â IndexOptions + IgnoreClient¸¦ »ç¿ëÇÏ¿© ¼ø¼­ ¾Æ±Ô¸ÕÆ®¸¦ ÀÐÁö ¾Ê´Â´Ù.
    + +
    SuppressDescription
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏ ¼³¸íÀ» Æ÷ÇÔÇÏÁö ¾Ê´Â´Ù. ±âº»ÀûÀ¸·Î + ¾î¶² ÆÄÀÏ ¼³¸íµµ Á¤ÀǵÇÀÖÁö¾Ê°í, ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé 23 + ¹®ÀÚ °ø°£À» ´Ù¸¥ ¿ëµµ·Î »ç¿ëÇÑ´Ù. ÆÄÀÏ ¼³¸íÀ» ÁöÁ¤ÇÏ´Â + ¹æ¹ýÀº AddDescriptionÀ» Âü°íÇ϶ó. ¼³¸í¿­ÀÇ Å©±â¸¦ + ÁöÁ¤ÇÏ´Â DescriptionWidth + ¿É¼Çµµ Âü°íÇ϶ó.
    + +
    SuppressHTMLPreamble
    + +
    µð·ºÅ丮¿¡ HeaderName Áö½Ã¾î·Î + ÁöÁ¤ÇÑ ÆÄÀÏÀÌ ÀÖ´Â °æ¿ì ¸ðµâÀº º¸Åë Ç¥ÁØ HTML ½ÃÀۺκР+ (<html>, <head>, + et cetera) µÚ¿¡ ÆÄÀÏ ³»¿ëÀ» ÷°¡ÇÑ´Ù. ±×·¯³ª + SuppressHTMLPreamble ¿É¼ÇÀ» »ç¿ëÇϸé óÀ½ºÎÅÍ + header ÆÄÀÏ ³»¿ëÀ» Æ÷ÇÔÇÑ´Ù. ÀÌ °æ¿ì header ÆÄÀÏ¿¡´Â ÀûÀýÇÑ + HTML ¸í·ÉÀÌ ÀÖ¾î¾ß ÇÑ´Ù. header ÆÄÀÏÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ + ½ÃÀۺκÐÀÌ ¸¸µé¾îÁø´Ù.
    + +
    SuppressIcon + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    fancy ¸ñ·Ï¿¡¼­ ¾ÆÀÌÄÜÀ» »«´Ù. SuppressIcon°ú + SuppressRules¸¦ °°ÀÌ »ç¿ëÇϸé, (FancyIndexed + ¸ñ·ÏÀÌ »ç¿ëÇÑ) pre ¾È¿¡ img¿Í + hr ¿ä¼Ò »ç¿ëÀ» ±ÝÁöÇÑ ¸¶Áö¸· Ç¥ÁØÀÎ HTML 3.2¿¡ + ¾Ë¸ÂÀº Ãâ·ÂÀÌ µÈ´Ù.
    + +
    SuppressLastModified
    + +
    fancy ¸ñ·Ï¿¡¼­ ¸¶Áö¸· ¼öÁ¤ÀÏÀ» Ç¥½ÃÇÏÁö ¾Ê´Â´Ù.
    + +
    SuppressRules + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    µð·ºÅ丮 ¸ñ·Ï¿¡¼­ ¼öÆòÁÙÀ» (hr ¿ä¼Ò) + »ç¿ëÇÏÁö ¾Ê´Â´Ù. SuppressIcon°ú + SuppressRules¸¦ °°ÀÌ »ç¿ëÇϸé, (FancyIndexed + ¸ñ·ÏÀÌ »ç¿ëÇÑ) pre ¾È¿¡ img¿Í + hr ¿ä¼Ò »ç¿ëÀ» ±ÝÁöÇÑ ¸¶Áö¸· Ç¥ÁØÀÎ HTML 3.2¿¡ + ¾Ë¸ÂÀº Ãâ·ÂÀÌ µÈ´Ù.
    + +
    SuppressSize
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏÅ©±â¸¦ Ç¥½ÃÇÏÁö ¾Ê´Â´Ù.
    + +
    TrackModified + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    µð·ºÅ丮 ¸ñ·ÏÀÇ HTTP Çì´õ¿¡ Last-Modified¿Í ETag °ªÀ» + Æ÷ÇÔÇÑ´Ù. ÀÌ ¿É¼ÇÀº ¿î¿µÃ¼Á¦¿Í ÆÄÀϽýºÅÛ¿¡¼­ ÀûÀýÇÑ stat() + °á°ú¸¦ ¾òÀ» ¼ö ÀÖÀ»¶§¸¸ À¯È¿ÇÏ´Ù. À¯´Ð½º ½Ã½ºÅÛ°ú OS2ÀÇ + JFS, Win32ÀÇ NTFS¿¡¼­´Â °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î, OS2¿Í Win32ÀÇ + FATÀº ºÒ°¡´ÉÇÏ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇϸé Ŭ¶óÀ̾ðÆ®³ª ÇÁ·Ï½Ã´Â + HEAD ¿äûÀ» »ç¿ëÇÏ¿© ÆÄÀϸñ·ÏÀÇ º¯È­¸¦ ÃßÀûÇÒ + ¼ö ÀÖ´Ù. ¾î¶² ¿î¿µÃ¼Á¦´Â »õ·Î¿î ÆÄÀÏ°ú »èÁ¦ÇÑ ÆÄÀÏÀ» ¿Ã¹Ù·Î + ÃßÀûÇÏÁö¸¸, µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏÀÇ Å©±â³ª ³¯Â¥ º¯È­¸¦ + ÃßÀûÇÏÁö ¸øÇÔÀ» ÁÖÀÇÇ϶ó. ¸ðµç À¯´Ð½º Ç÷¡Æû¿¡¼­ + ±âÁ¸ ÆÄÀÏÀÇ Å©±â³ª ³¯Â¥ º¯È­½Ã Last-Modified Çì´õ°¡ + ¹Ù²îÁö¾Ê´Â´Ù. ÀÌ·± º¯È­°¡ Áß¿äÇÏ´Ù¸é ÀÌ ¿É¼ÇÀ» + »ç¿ëÇÏÁö ¸¶¶ó.
    + +
    VersionSort + (¾ÆÆÄÄ¡ 2.0a3 ÀÌÈÄ)
    + +
    VersionSort Å°¿öµå´Â ¹öÀü ¹øÈ£¸¦ Æ÷ÇÔÇÑ + ÆÄÀϸíÀ» ÀÚ¿¬½º·´°Ô Á¤·ÄÇÑ´Ù. ¹®ÀÚ ºÎºÐÀº Á¤»óÀûÀÎ ¼ø¼­¸¦ + Á¤·ÄÇÏÁö¸¸, ÆÄÀÏ°ú ¼³¸í¿¡ ÀÖ´Â ¼ýÀÚ ºÎºÐÀº ¼ýÀÚ°ªÀ¸·Î + ºñ±³ÇÑ´Ù. + +

    ¿¹Á¦:

    + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +

    + +

    ¼ö°¡ 0À¸·Î ½ÃÀÛÇϸé, ±× ¼ö¸¦ ºÐ¼ö·Î Ãë±ÞÇÑ´Ù:

    + +

    + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +

    +
    + +
    XHTML + (¾ÆÆÄÄ¡ 2.0.49 ÀÌÈÄ)
    + +
    XHTML Å°¿öµå¸¦ »ç¿ëÇϸé + mod_autoindex´Â HTML 3.2 ´ë½Å XHTML 1.0 + Äڵ带 »ý¼ºÇÑ´Ù.
    +
    + + +
    Á¡ÁøÀûÀÎ IndexOptions
    +
    +

    ¾ÆÆÄÄ¡ 1.3.3¿¡¼­ IndexOptions + Áö½Ã¾î 󸮹æ½ÄÀÌ Å©°Ô º¯È­µÇ¾ú´Ù. Ưº°È÷:

    + +
      +
    • ÀÌÁ¦ ÇÑ µð·ºÅ丮¿¡ ´ëÇÑ ¿©·¯ + IndexOptions Áö½Ã¾îµéÀ» ¼­·Î °áÇÕÇÑ´Ù. + ´ÙÀ½ÀÇ °á°ú´Â: + +

      + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +

      + +

      ´ÙÀ½°ú °°´Ù

      + +

      + IndexOptions HTMLTable SuppressColumnsorting +

      +
    • + +
    • (¿¹¸¦ µé¾î, Å°¿öµå ¾Õ¿¡ +³ª + -¸¦ ºÙÀÌ´Â) Á¡ÁøÀûÀÎ ¹®¹ýÀÌ Ãß°¡µÇ¾ú´Ù.
    • +
    + +

    Å°¿öµå ¾Õ¿¡ '+'³ª '-'°¡ ºÙÀ»¶§¸¶´Ù ÇØ´ç Å°¿öµå°¡ ÇöÀç + (»óÀ§ µð·ºÅ丮¿¡¼­ »ó¼ÓµÇ¾úÀ») IndexOptions + ¼³Á¤¿¡ ¹Ý¿µµÈ´Ù. ±×·¯³ª ¾Õ¿¡ ¾Æ¹«°Íµµ ¾ø´Â Å°¿öµå¸¦ ¸¸³ª¸é + ¾ÆÁ÷±îÁö »ó¼ÓµÇ°Å³ª Á¡ÁøÀûÀ¸·Î º¯°æµÈ ¼³Á¤À» ¸ðµÎ Áö¿î´Ù. + ´ÙÀ½ ¿¹Á¦¸¦ »ìÆ캸ÀÚ:

    + +

    + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +

    + +

    ¾Õ¿¡ ¾Æ¹«°Íµµ ¾ø´Â FancyIndexingÀÌ ÀÌÀüÀÇ + Á¡ÁøÀûÀÎ ¼³Á¤À» Áö¿ö¹ö·ÈÁö¸¸ ¼³Á¤ÀÌ ´Ù½Ã Ãß°¡µÇ¿© °á°ú´Â + IndexOptions FancyIndexing +SuppressSize¿Í °°´Ù.

    + +

    ƯÁ¤ µð·ºÅ丮¿¡ ´ëÇØ ¹«Á¶°ÇÀûÀÎ + IndexOptions¸¦ ¼³Á¤ÇÏ·Á¸é Å°¿öµå + ¾Õ¿¡ +³ª -¸¦ »ç¿ëÇÏÁö¸»°í + »ó¼ÓµÈ ¼³Á¤À» Áö¿î´Ù.

    +
    +
    + +
    +
    top
    +

    IndexOrderDefault Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:µð·ºÅ丮 ¸ñ·ÏÀÇ ±âº» ¼ø¼­¸¦ ¼³Á¤ÇÑ´Ù
    ¹®¹ý:IndexOrderDefault Ascending|Descending +Name|Date|Size|Description
    ±âº»°ª:IndexOrderDefault Ascending Name
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    IndexOrderDefault Áö½Ã¾î´Â FancyIndexing + ¸ñ·Ï ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î fancyindexed µð·ºÅ丮 + ¸ñ·ÏÀº ÆÄÀÏ¸í ¿À¸§Â÷¼øÀÌ´Ù. IndexOrderDefault´Â + ÀÌ Ãʱ⠼ø¼­¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù.

    + +

    IndexOrderDefault´Â µÎ ¾Æ±Ô¸ÕÆ®¸¦ + ¹Þ´Â´Ù. ù¹ø°´Â ¼ø¼­ÀÇ ¹æÇâÀ» Áö½ÃÇÏ´Â Ascending + (¿À¸¥Â÷¼ø) À̳ª Descending (³»¸²Â÷¼ø) Áß Çϳª´Ù. + µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ÀÏÂ÷ ¼ø¼­¸¦ ³ªÅ¸³»´Â Å°¿öµå Name, + Date, Size, Description + Áß Çϳª´Ù. ÀÌÂ÷ ¼ø¼­´Â Ç×»ó ÆÄÀÏ¸í ¿À¸§Â÷¼øÀÌ´Ù.

    + +

    ÀÌ Áö½Ã¾î¿Í SuppressColumnSorting ¸ñ·Ï ¿É¼ÇÀ» °°ÀÌ »ç¿ëÇϸé + ƯÁ¤ ¼ø¼­·Î¸¸ µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â + ´Ù¸¥ ¼ø¼­·Î µð·ºÅ丮 ¸ñ·ÏÀ» ¿äûÇÏÁö ¸øÇÑ´Ù.

    + +
    +
    top
    +

    IndexStyleSheet Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:µð·ºÅ丮 ¸ñ·Ï¿¡ CSS ½ºÅ¸ÀϽ¬Æ®¸¦ Ãß°¡ÇÑ´Ù
    ¹®¹ý:IndexStyleSheet url-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    IndexStyleSheet Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ CSS·Î »ç¿ëÇÒ ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. +

    +

    Example

    + + IndexStyleSheet "/css/style.css" +

    + +
    +
    top
    +

    ReadmeName Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÆÄÀϸñ·Ï ¸¶Áö¸·¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§
    ¹®¹ý:ReadmeName filename
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_autoindex
    +

    ReadmeName Áö½Ã¾î´Â ÆÄÀϸñ·Ï ³¡¿¡ + »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. FilenameÀº Æ÷ÇÔÇÒ + ÆÄÀϸíÀÌ°í, ¸ñ·ÏÀ» ¸¸µé·Á´Â À§Ä¡ÀÇ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ. + FilenameÀÌ ½½·¡½¬·Î ½ÃÀÛÇϸé DocumentRoot¿¡ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ. +

    + +

    ¿¹Á¦

    + ReadmeName FOOTER.html +

    + +

    ¿¹Á¦ 2

    + ReadmeName /include/FOOTER.html +

    + +

    ÀÌ µ¿ÀÛÀ» ÀÚ¼¼È÷ ¼³¸íÇÑ HeaderNameµµ Âü°íÇ϶ó.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_autoindex.xml b/trunk/docs/manual/mod/mod_autoindex.xml new file mode 100644 index 0000000000..49e75e111a --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.xml @@ -0,0 +1,941 @@ + + + + + + + + +mod_autoindex + +Generates directory indexes, + automatically, similar to the Unix ls command or the + Win32 dir shell command +Base +mod_autoindex.c +autoindex_module + + +

    The index of a directory can come from one of two + sources:

    + +
      +
    • A file written by the user, typically called + index.html. The DirectoryIndex directive sets the + name of this file. This is controlled by + mod_dir.
    • + +
    • Otherwise, a listing generated by the server. The other + directives control the format of this listing. The AddIcon, AddIconByEncoding and + AddIconByType are + used to set a list of icons to display for various file types; + for each file listed, the first icon listed that matches the + file is displayed. These are controlled by + mod_autoindex.
    • +
    +

    The two functions are separated so that you can completely + remove (or replace) automatic index generation should you want + to.

    + +

    Automatic index generation is enabled with using + Options +Indexes. See the + Options directive for + more details.

    + +

    If the FancyIndexing option is given with the IndexOptions directive, + the column headers are links that control the order of the + display. If you select a header link, the listing will be + regenerated, sorted by the values in that column. Selecting the + same header repeatedly toggles between ascending and descending + order. These column header links are suppressed with + IndexOptions directive's + SuppressColumnSorting option.

    + +

    Note that when the display is sorted by "Size", it's the + actual size of the files that's used, not the + displayed value - so a 1010-byte file will always be displayed + before a 1011-byte file (if in ascending order) even though + they both are shown as "1K".

    +
    + +
    + Autoindex Request Query Arguments + +

    Apache 2.0.23 reorganized the Query Arguments for Column + Sorting, and introduced an entire group of new query options. + To effectively eliminate all client control over the output, + the IndexOptions + IgnoreClient option was introduced.

    + +

    The column sorting headers themselves are self-referencing + hyperlinks that add the sort query options shown below. Any + option below may be added to any request for the directory + resource.

    + +
      +
    • C=N sorts the directory by file name
    • + +
    • C=M sorts the directory by last-modified + date, then file name
    • + +
    • C=S sorts the directory by size, then file + name
    • + +
    • C=D sorts the directory by description, then + file name
    • + +
    • O=A sorts the listing in Ascending + Order
    • + +
    • O=D sorts the listing in Descending + Order
    • + +
    • F=0 formats the listing as a simple list + (not FancyIndexed)
    • + +
    • F=1 formats the listing as a FancyIndexed + list
    • + +
    • F=2 formats the listing as an + HTMLTable FancyIndexed list
    • + +
    • V=0 disables version sorting
    • + +
    • V=1 enables version sorting
    • + +
    • P=pattern lists only files matching + the given pattern
    • +
    + +

    Note that the 'P'attern query argument is tested + after the usual IndexIgnore directives are processed, + and all file names are still subjected to the same criteria as + any other autoindex listing. The Query Arguments parser in + mod_autoindex will stop abruptly when an unrecognized + option is encountered. The Query Arguments must be well formed, + according to the table above.

    + +

    The simple example below, which can be clipped and saved in + a header.html file, illustrates these query options. Note that + the unknown "X" argument, for the submit button, is listed last + to assure the arguments are all parsed before mod_autoindex + encounters the X=Go input.

    + + + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +
    + +
    + + +AddAlt +Alternate text to display for a file, instead of an +icon selected by filename +AddAlt string file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAlt provides the alternate text to + display for a file, instead of an icon, for FancyIndexing. + File is a file extension, partial filename, wild-card + expression or full filename for files to describe. + If String contains any whitespace, you have to enclose it + in quotes (" or '). This alternate text + is displayed if the client is image-incapable, has image loading + disabled, or fails to retrieve the icon.

    + + Examples + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +
    +
    +
    + + +AddAltByEncoding +Alternate text to display for a file instead of an icon +selected by MIME-encoding +AddAltByEncoding string MIME-encoding +[MIME-encoding] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAltByEncoding provides the alternate + text to display for a file, instead of an icon, for FancyIndexing. + MIME-encoding is a valid content-encoding, such as + x-compress. If String contains any whitespace, + you have to enclose it in quotes (" or '). + This alternate text is displayed if the client is image-incapable, + has image loading disabled, or fails to retrieve the icon.

    + + Example + AddAltByEncoding gzip x-gzip + +
    +
    + + +AddAltByType +Alternate text to display for a file, instead of an +icon selected by MIME content-type +AddAltByType string MIME-type +[MIME-type] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAltByType sets the alternate text to + display for a file, instead of an icon, for FancyIndexing. + MIME-type is a valid content-type, such as + text/html. If String contains any whitespace, + you have to enclose it in quotes (" or '). + This alternate text is displayed if the client is image-incapable, + has image loading disabled, or fails to retrieve the icon.

    + + Example + AddAltByType 'plain text' text/plain + +
    +
    + + +AddDescription +Description to display for a file +AddDescription string file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    This sets the description to display for a file, for + FancyIndexing. + File is a file extension, partial filename, wild-card + expression or full filename for files to describe. + String is enclosed in double quotes (").

    + + Example + AddDescription "The planet Mars" /web/pics/mars.gif + + +

    The typical, default description field is 23 bytes wide. 6 + more bytes are added by the IndexOptions SuppressIcon option, 7 bytes are + added by the IndexOptions SuppressSize option, and 19 bytes are + added by the IndexOptions SuppressLastModified option. + Therefore, the widest default the description column is ever + assigned is 55 bytes.

    + +

    See the DescriptionWidth IndexOptions keyword for details on overriding the size + of this column, or allowing descriptions of unlimited length.

    + + Caution +

    Descriptive text defined with AddDescription + may contain HTML markup, such as tags and character entities. If the + width of the description column should happen to truncate a tagged + element (such as cutting off the end of a bolded phrase), the + results may affect the rest of the directory listing.

    +
    +
    +
    + + +AddIcon +Icon to display for a file selected by name +AddIcon icon name [name] +... +server configvirtual host +directory.htaccess + +Indexes + + +

    This sets the icon to display next to a file ending in + name for FancyIndexing. Icon is either a (%-escaped) + relative URL to the icon, or of the format + (alttext,url) where alttext + is the text tag given for an icon for non-graphical browsers.

    + +

    Name is either ^^DIRECTORY^^ for directories, + ^^BLANKICON^^ for blank lines (to format the list + correctly), a file extension, a wildcard expression, a partial + filename or a complete filename.

    + + Examples + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +
    + +

    AddIconByType + should be used in preference to AddIcon, + when possible.

    +
    +
    + + +AddIconByEncoding +Icon to display next to files selected by MIME +content-encoding +AddIconByEncoding icon MIME-encoding +[MIME-encoding] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    This sets the icon to display next to files with FancyIndexing. + Icon is either a (%-escaped) relative URL to the icon, + or of the format (alttext,url) + where alttext is the text tag given for an icon for + non-graphical browsers.

    + +

    MIME-encoding is a wildcard expression matching + required the content-encoding.

    + + Example + AddIconByEncoding /icons/compress.xbm x-compress + +
    +
    + + +AddIconByType +Icon to display next to files selected by MIME +content-type +AddIconByType icon MIME-type +[MIME-type] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    This sets the icon to display next to files of type + MIME-type for FancyIndexing. + Icon is either a (%-escaped) relative URL to the icon, + or of the format (alttext,url) + where alttext is the text tag given for an icon for + non-graphical browsers.

    + +

    MIME-type is a wildcard expression matching + required the mime types.

    + + Example + AddIconByType (IMG,/icons/image.xbm) image/* + +
    +
    + + +DefaultIcon +Icon to display for files when no specific icon is +configured +DefaultIcon url-path +server configvirtual host +directory.htaccess + +Indexes + + +

    The DefaultIcon directive sets the icon + to display for files when no specific icon is known, for FancyIndexing. + Url-path is a (%-escaped) relative URL to the icon.

    + + Example + DefaultIcon /icon/unknown.xbm + +
    +
    + + +HeaderName +Name of the file that will be inserted at the top +of the index listing +HeaderName filename +server configvirtual host +directory.htaccess + +Indexes + + +

    The HeaderName directive sets the name + of the file that will be inserted at the top of the index + listing. Filename is the name of the file to include.

    + + Example + HeaderName HEADER.html + + + +

    Both HeaderName and ReadmeName now treat + Filename as a URI path relative to the one used to + access the directory being indexed. If Filename begins + with a slash, it will be taken to be relative to the DocumentRoot.

    + + Example + HeaderName /include/HEADER.html + + +

    Filename must resolve to a document with a major + content type of text/* (e.g., + text/html, text/plain, etc.). This means + that filename may refer to a CGI script if the script's + actual file type (as opposed to its output) is marked as + text/html such as with a directive like:

    + + + AddType text/html .cgi + + +

    Content negotiation + will be performed if Options + MultiViews is in effect. If filename resolves + to a static text/html document (not a CGI script) and + either one of the options + Includes or IncludesNOEXEC is enabled, + the file will be processed for server-side includes (see the + mod_include documentation).

    +
    + +

    If the file specified by HeaderName contains + the beginnings of an HTML document (<html>, <head>, etc.) + then you will probably want to set IndexOptions + +SuppressHTMLPreamble, so that these tags are not + repeated.

    +
    +
    + + +IndexIgnore +Adds to the list of files to hide when listing +a directory +IndexIgnore file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    The IndexIgnore directive adds to the + list of files to hide when listing a directory. File is a + shell-style wildcard expression or full + filename. Multiple IndexIgnore directives add + to the list, rather than the replacing the list of ignored + files. By default, the list contains . (the current + directory).

    + + + IndexIgnore README .htaccess *.bak *~ + +
    +
    + + +IndexOptions +Various configuration settings for directory +indexing +IndexOptions [+|-]option [[+|-]option] +... +server configvirtual host +directory.htaccess + +Indexes + + +

    The IndexOptions directive specifies the + behavior of the directory indexing. Option can be one + of

    + +
    +
    DescriptionWidth=[n | *] (Apache 2.0.23 and + later)
    + +
    The DescriptionWidth keyword allows you to + specify the width of the description column in + characters.
    + +
    -DescriptionWidth (or unset) allows + mod_autoindex to calculate the best width.
    + +
    DescriptionWidth=n fixes the column width to + n bytes wide.
    + +
    DescriptionWidth=* grows the column to the + width necessary to accommodate the longest description + string.
    + +
    See the section on AddDescription for dangers + inherent in truncating descriptions.
    + +
    FancyIndexing
    + +
    This turns on fancy indexing of directories.
    + +
    FoldersFirst (Apache + 2.0.23 and later)
    + +
    If this option is enabled, subdirectory listings will + always appear first, followed by normal files in the + directory. The listing is basically broken into two + components, the files and the subdirectories, and each is + sorted separately and then displayed subdirectories-first. + For instance, if the sort order is descending by name, and + FoldersFirst is enabled, subdirectory + Zed will be listed before subdirectory + Beta, which will be listed before normal files + Gamma and Alpha. This option + only has an effect if FancyIndexing is also enabled.
    + +
    HTMLTable (Experimental, + Apache 2.0.23 and later)
    + +
    This experimental option with FancyIndexing constructs a + simple table for the fancy directory listing. Note this will + confuse older browsers. It is particularly necessary if file + names or description text will alternate between + left-to-right and right-to-left reading order, as can happen + on WinNT or other utf-8 enabled platforms.
    + +
    IconsAreLinks
    + +
    This makes the icons part of the anchor for the filename, for + fancy indexing.
    + +
    IconHeight[=pixels]
    + +
    Presence of this option, when used with IconWidth, will cause + the server to include height and width + attributes in the img tag for the file icon. This allows + browser to precalculate the page layout without having to wait until + all the images have been loaded. If no value is given for the option, + it defaults to the standard height of the icons supplied with the Apache + software.
    + +
    IconWidth[=pixels]
    + +
    Presence of this option, when used with IconHeight, + will cause the server to include height and + width attributes in the img tag for + the file icon. This allows browser to precalculate the page + layout without having to wait until all the images have been + loaded. If no value is given for the option, it defaults to + the standard width of the icons supplied with the Apache + software.
    + +
    IgnoreCase
    + +
    If this option is enabled, names are sorted in a case-insensitive + manner. For instance, if the sort order is ascending by name, and + IgnoreCase is enabled, file Zeta will be listed after file alfa + (Note: file GAMMA will always be listed before file gamma).
    + +
    IgnoreClient
    + +
    This option causes mod_autoindex to ignore all + query variables from the client, including sort order (implies + SuppressColumnSorting.)
    + +
    NameWidth=[n + | *]
    + +
    The NameWidth keyword allows you to specify the width + of the filename column in bytes.
    + +
    -NameWidth (or unset) allows mod_autoindex to calculate the best width.
    + +
    NameWidth=n fixes the column width to + n bytes wide.
    + +
    NameWidth=* grows the column to the necessary + width.
    + +
    ScanHTMLTitles
    + +
    This enables the extraction of the title from HTML documents + for fancy indexing. If the file does not have a description + given by AddDescription + then httpd will read the document for the value of the + title element. This is CPU and disk intensive.
    + +
    ShowForbidden
    + +
    If specified, Apache will show files normally hidden because + the subrequest returned HTTP_UNAUTHORIZED or HTTP_FORBIDDEN
    + +
    SuppressColumnSorting
    + +
    If specified, Apache will not make the column headings in a + FancyIndexed directory listing into links for sorting. The + default behavior is for them to be links; selecting the + column heading will sort the directory listing by the values + in that column. Prior to Apache 2.0.23, this also + disabled parsing the Query Arguments for the sort + string. That behavior is now controlled by IndexOptions + IgnoreClient in Apache 2.0.23.
    + +
    SuppressDescription
    + +
    This will suppress the file description in fancy indexing + listings. By default, no file descriptions are defined, and + so the use of this option will regain 23 characters of screen + space to use for something else. See AddDescription for information about setting the file + description. See also the DescriptionWidth + index option to limit the size of the description column.
    + +
    SuppressHTMLPreamble
    + +
    If the directory actually contains a file specified by the + HeaderName + directive, the module usually includes the contents of the file + after a standard HTML preamble (<html>, + <head>, et cetera). The + SuppressHTMLPreamble option disables this behaviour, + causing the module to start the display with the header file + contents. The header file must contain appropriate HTML instructions + in this case. If there is no header file, the preamble is generated + as usual.
    + +
    SuppressIcon (Apache + 2.0.23 and later)
    + +
    This will suppress the icon in fancy indexing listings. + Combining both SuppressIcon and + SuppressRules yields proper HTML 3.2 output, which + by the final specification prohibits img and + hr elements from the pre block (used to + format FancyIndexed listings.)
    + +
    SuppressLastModified
    + +
    This will suppress the display of the last modification date, + in fancy indexing listings.
    + +
    SuppressRules + (Apache 2.0.23 and later)
    + +
    This will suppress the horizontal rule lines (hr + elements) in directory listings. Combining both SuppressIcon and + SuppressRules yields proper HTML 3.2 output, which + by the final specification prohibits img and + hr elements from the pre block (used to + format FancyIndexed listings.)
    + +
    SuppressSize
    + +
    This will suppress the file size in fancy indexing listings.
    + +
    TrackModified (Apache + 2.0.23 and later)
    + +
    This returns the Last-Modified and ETag values for the listed + directory in the HTTP header. It is only valid if the + operating system and file system return appropriate stat() + results. Some Unix systems do so, as do OS2's JFS and Win32's + NTFS volumes. OS2 and Win32 FAT volumes, for example, do not. + Once this feature is enabled, the client or proxy can track + changes to the list of files when they perform a HEAD + request. Note some operating systems correctly track new and + removed files, but do not track changes for sizes or dates of + the files within the directory. Changes to the size + or date stamp of an existing file will not update the + Last-Modified header on all Unix platforms. If this + is a concern, leave this option disabled.
    + +
    VersionSort + (Apache 2.0a3 and later)
    + +
    The VersionSort keyword causes files containing + version numbers to sort in a natural way. Strings are sorted as + usual, except that substrings of digits in the name and + description are compared according to their numeric value. + + Example: + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +
    + +

    If the number starts with a zero, then it is considered to + be a fraction:

    + + + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +
    +
    + +
    XHTML + (Apache 2.0.49 and later)
    + +
    The XHTML keyword forces mod_autoindex + to emit XHTML 1.0 code instead of HTML 3.2.
    +
    + + +
    Incremental IndexOptions
    +
    +

    Apache 1.3.3 introduced some significant changes in the + handling of IndexOptions directives. In + particular:

    + +
      +
    • Multiple IndexOptions directives for a + single directory are now merged together. The result of: + + + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +
      + +

      will be the equivalent of

      + + + IndexOptions HTMLTable SuppressColumnsorting + +
    • + +
    • The addition of the incremental syntax (i.e., prefixing + keywords with + or -).
    • +
    + +

    Whenever a '+' or '-' prefixed keyword is encountered, it + is applied to the current IndexOptions + settings (which may have been inherited from an upper-level + directory). However, whenever an unprefixed keyword is processed, it + clears all inherited options and any incremental settings encountered + so far. Consider the following example:

    + + + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +
    + +

    The net effect is equivalent to IndexOptions FancyIndexing + +SuppressSize, because the unprefixed FancyIndexing + discarded the incremental keywords before it, but allowed them to + start accumulating again afterward.

    + +

    To unconditionally set the IndexOptions for + a particular directory, clearing the inherited settings, specify + keywords without any + or - prefixes.

    +
    +
    +
    +
    + + +IndexOrderDefault +Sets the default ordering of the directory index +IndexOrderDefault Ascending|Descending +Name|Date|Size|Description +IndexOrderDefault Ascending Name +server configvirtual host +directory.htaccess + +Indexes + + +

    The IndexOrderDefault directive is used + in combination with the FancyIndexing index option. By default, fancyindexed + directory listings are displayed in ascending order by filename; the + IndexOrderDefault allows you to change this + initial display order.

    + +

    IndexOrderDefault takes two + arguments. The first must be either Ascending or + Descending, indicating the direction of the sort. + The second argument must be one of the keywords Name, + Date, Size, or Description, + and identifies the primary key. The secondary key is + always the ascending filename.

    + +

    You can force a directory listing to only be displayed in a + particular order by combining this directive with the SuppressColumnSorting index option; this will prevent + the client from requesting the directory listing in a different + order.

    +
    +
    + + +IndexStyleSheet +Adds a CSS stylesheet to the directory index +IndexStyleSheet url-path +server configvirtual host +directory.htaccess + +Indexes + + +

    The IndexStyleSheet directive sets the name of + the file that will be used as the CSS for the index listing. +

    + + Example + IndexStyleSheet "/css/style.css" + +
    +
    + + +ReadmeName +Name of the file that will be inserted at the end +of the index listing +ReadmeName filename +server configvirtual host +directory.htaccess + +Indexes + + +

    The ReadmeName directive sets the name + of the file that will be appended to the end of the index + listing. Filename is the name of the file to include, and + is taken to be relative to the location being indexed. If + Filename begins with a slash, it will be taken to be + relative to the DocumentRoot. +

    + + Example + ReadmeName FOOTER.html + + + Example 2 + ReadmeName /include/FOOTER.html + + +

    See also HeaderName, where this behavior is described in greater + detail.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_autoindex.xml.ja b/trunk/docs/manual/mod/mod_autoindex.xml.ja new file mode 100644 index 0000000000..f971eefd6f --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.xml.ja @@ -0,0 +1,1024 @@ + + + + + + + + + +mod_autoindex +Unix $B$N(B ls $B%3%^%s%I$d(B + Win32 $B$N(B dir $B%7%'%k%3%^%s%I$K;w$?(B + $B%G%#%l%/%H%j%$%s%G%C%/%9$r@8@.$9$k(B +Base +mod_autoindex.c +autoindex_module + + +

    $B%G%#%l%/%H%j$N%$%s%G%C%/%9$OFs$D$N>pJs8;$N$&$A$N(B + $B0l$D$+$i@8@.$G$-$^$9(B:

    + +
      +
    • $BIaDL$O(B index.html $B$H8F$P$l$k(B + $B%f!<%6$K$h$C$F=q$+$l$?%U%!%$%k!#(B + DirectoryIndex + $B%G%#%l%/%F%#%V$G$3$N%U%!%$%kL>$r@_Dj$7$^$9!#(B + $B$3$l$O(B mod_dir $B$G@)8f$5$l$^$9!#(B
    • + +
    • $B$b$7$/$O!"%5!<%P$K$h$C$F@8@.$5$l$?0lMw!#(B + $B$=$NB>$N%G%#%l%/%F%#%V$G$3$N0lMw$N=q<0$r@)8f$7$^$9!#(B + AddIcon, AddIconByEncoding $B$H(B + AddIconByType + $B$r;H$&$3$H$G!"MM!9$J%U%!%$%k%?%$%W$KBP$7$F%"%$%3%s0lMw$r(B + $B%;%C%H$7$^$9!#$D$^$j!"%j%9%H$5$l$?%U%!%$%kKh$K!"(B + $B%U%!%$%k$K%^%C%A$7$?0lHV:G=i$N%"%$%3%s$,I=<($5$l$^$9!#(B + $B$3$l$i$O(B mod_autoindex $B$G@)8f$5$l$^$9!#(B
    • +
    +

    $BK>$`$J$i$P!"<+F0%$%s%G%C%/%9@8@.$r40A4$K=|5n(B ($B$"$k$$$OCV49(B) + $B$G$-$k$h$&$K!"$3$NFs$D$N5!G=$OJ,N%$5$l$F$$$^$9!#(B

    + +

    $B<+F0%$%s%G%C%/%9@8@.$O(B Options +Indexes + $B$r;H$&$3$H$GM-8z$K$J$j$^$9!#>\:Y$K$D$$$F$O!"(B + Options + $B%G%#%l%/%F%#%V$r$4Mw2<$5$$!#(B

    + +

    $B$b$7(B FancyIndexing$B%*%W%7%g%s$,(B + IndexOptions + $B%G%#%l%/%F%#%V$KM?$($i$l$F$$$k$J$i$P!"(B + $BNs$N@hF,$OI=<($N=gHV$r@)8f$9$k%j%s%/$K$J$j$^$9!#(B + $B@hF,$N%j%s%/$rA*Br$9$k$H!"0lMw$O:F@8@.$5$l$F(B + $B$=$NNs$NCM$G%=!<%H$5$l$^$9!#(B + $BF1$8@hF,$rB3$1$FA*Br$9$k$H!"8r8_$K>:=g$H9_=g$H$K$J$j$^$9!#(B + $B$3$l$i$NNs$N@hF,$N%j%s%/$O!"(B + IndexOptions + $B%G%#%l%/%F%#%V$N(B + SuppressColumnSorting + $B%*%W%7%g%s$G>C$9$3$H$,$G$-$^$9!#(B

    + +

    "Size" $B$G%=!<%H$7$?>l9g$O!"MQ$$$i$l$k$N$O(B + $B$B%U%!%$%k$N%5%$%:$G$"$C$F!"(B + $BI=<($NCM$G$O$J$$$3$H$KCm0U$7$F$/$@$5$$(B - + $B$?$H$(N>J}$H$b$,(B "1K" $B$HI=<($5$l$F$$$?$H$7$F$b!"(B + 1010 $B%P%$%H$N%U%!%$%k$OI,$:(B 1011 + $B%P%$%H$N%U%!%$%k$h$j$bA0(B ($B>:=g$N>l9g(B) $B$KI=<($5$l$^$9!#(B

    +
    + +
    + Autoindex $B%j%/%(%9%H%/%(%j!<0z?t(B + +

    Apache 2.0.23 $B$G!"(B + $B%3%i%`%=!<%H$N$?$a$K%/%(%j!<0z?t$r:FJT@.$7$F!"(B + $B?7$7$$%/%(%j!<%*%W%7%g%s$N%0%k!<%W$rF3F~$7$^$7$?!#(B + $B=PNO$KBP$9$k%/%i%$%"%s%H$N$9$Y$F$N@)8f$r8zN(E*$KKu>C(B + $B$G$-$k$h$&$K!"(B + IndexOptions + IgnoreClient $B$,F3F~$5$l$^$7$?!#(B

    + +

    $B%3%i%`%=!<%H$N%X%C%@$=$l<+BN$,!"(B + $B2<5-$N%=!<%H%/%(%j!<%*%W%7%g%s$rIU2C$9$k(B + $B<+J,<+?H$r;2>H$9$k%j%s%/$G$9!#(B + $B2<5-$N%*%W%7%g%s$N$I$l$G$b!"(B + $B%G%#%l%/%H%j%j%=!<%9$X$N%j%/%(%9%H$K2C$($k$3$H$,$G$-$^$9!#(B

    + +
      +
    • C=N $B$O!"%U%!%$%kL>$G%=!<%H$7$^$9!#(B
    • + +
    • C=M $B$O!"99?7F|;~!"(B + $B%G%#%l%/%H%j!"%U%!%$%kL>$N=g$G%=!<%H$7$^$9!#(B
    • + +
    • C=S $B$O!"%5%$%:!"(B + $B%G%#%l%/%H%j!"%U%!%$%kL>$N=g$G%=!<%H$7$^$9!#(B
    • + +
    • C=D $B$O!"@bL@!"(B + $B%G%#%l%/%H%j!"%U%!%$%kL>$N=g$G%=!<%H$7$^$9!#(B
    • + +
    • O=A $B$O!">:=g$GI=$r%=!<%H$7$^$9!#(B
    • + +
    • O=D $B$O!"9_=g$GI=$r%=!<%H$7$^$9!#(B
    • + +
    • F=0 $B$O!"C1=c$JI=$N=q<0$K$7$^$9!#(B + (FancyIndex $B$G$O$"$j$^$;$s!#(B)
    • + +
    • F=1 $B$O!"(BFancyIndex + $BI=<($NI=$N=q<0$K$7$^$9!#(B
    • + +
    • F=2 $B$O!"I=$r(B HTML + $B$N%F!<%V%k$r;H$C$?(B FancyIndex $B$N=q<0$K$7$^$9!#(B
    • + +
    • V=0 + $B$O!"%P!<%8%g%s$K$h$k%=!<%H$rL58z$K$7$^$9!#(B
    • + +
    • V=1 + $B$O!"%P!<%8%g%s$K$h$k%=!<%H$rM-8z$K$7$^$9!#(B
    • + +
    • P=pattern + $B$O!"M?$($i$l$?(B pattern + $B$KE,9g$7$?%U%!%$%k$N$_$rI=<($7$^$9!#(B
    • +
    + +

    "P ($B%Q%?!<%s$N(B P)" $B%/%(%j!<0z?t$O!"(B + $BDL>o$N(B IndexIgnore + $B%G%#%l%/%F%#%V$,=hM}$5$l$?(B$B8e(B$B$K8!::$5$l!"(B + $B%U%!%$%kL>A4$F$,!"B>$N(B autoindex + $B%j%9%H=hM}$HF1MM$NH=Dj4p=`2<$KCV$+$lB3$1$k(B + $B$3$H$KCm0U$7$F$/$@$5$$!#(B + mod_autoindex $B$N%/%(%j!<0z?t%Q!<%5(B ($B2r@O(B) $B$O!"(B + $BG'<1ITG=$J%*%W%7%g%s$K$V$D$+$k$HB(:B$KDd;_$7$^$9!#(B + $B%/%(%j!<0z?t$O>e$NI=$K=>$C$F(B + $B@5$7$$7A<0$K$J$C$F$$$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B2<$NC1=c$JNc$O!"$3$l$i$N%/%(%j!<%*%W%7%g%s$r(B + $BI=$7$^$9!#$3$l$r$=$N$^$^@Z$j + + + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +
    + +

    + + +AddAlt +$B%"%$%3%s$NBe$o$j$K(B +$BI=<($5$l$k!"%U%!%$%kL>$GA*Br$5$l$?BeBX%F%-%9%H(B +AddAlt string file [file] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    AddAlt $B$O!"(BFancyIndexing + $B$K$*$$$F!"%"%$%3%s$NBe$o$j$KI=<($9$kBeBX%F%-%9%H$rDs6!$7$^$9!#(B + file $B$O!"@bL@$9$k%U%!%$%k$N%U%!%$%k3HD%;R!"(B + $B%U%!%$%kL>$N0lIt!"%o%$%k%I%+!<%II=8=!"40A4$J%U%!%$%kL>$N(B + $B$I$l$+$K$J$j$^$9!#(B + string $B$K6uGr$,$"$k>l9g$O0zMQId(B (" + $B$+(B ') $B$G0O$`I,MW$,$"$j$^$9!#(B + $B$3$NJ8;zNs$O!"%/%i%$%"%s%H$,2hA|$rI=<($G$-$J$$>l9g$d(B + $B2hA|$N%m!<%I$rL58z$K$7$F$$$k>l9g$d(B + $B%"%$%3%s$N + + $BNc(B + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +
    + + + + +AddAltByEncoding +$B%"%$%3%s$NBe$o$j$KI=<($5$l$k!"(BMIME $BId9f2=J}K!$GA*Br$5$l$?(B +$BBeBX%F%-%9%H(B +AddAltByEncoding string MIME-encoding +[MIME-encoding] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    AddAltByEncoding $B$O!"(B + FancyIndexing + $B$K$*$$$F!"%"%$%3%s$NBe$o$j$KI=<($9$kBeBXJ8;zNs$rDs6!$7$^$9!#(B + MIME-encoding $B$OM-8z$JId9f2=!"Nc$($P(B + x-compress + $B$G$9!#(B + string $B$K6uGr$,$"$k$H$-$O!"0zMQId(B (" $B$+(B + ') $B$G0O$`I,MW$,$"$j$^$9!#(B + $B$3$NJ8;zNs$O!"%/%i%$%"%s%H$,2hA|$rI=<($G$-$J$$>l9g$d(B + $B2hA|$N%m!<%I$rL58z$K$7$F$$$k>l9g$d(B + $B%"%$%3%s$N + + $BNc(B + AddAltByEncoding gzip x-gzip + + + + + +AddAltByType +$B%"%$%3%s$NBe$o$j$K(B +$BI=<($5$l$k!"(BMIME $B%?%$%W$GA*Br$5$l$?BeBX%F%-%9%H(B +AddAltByType string MIME-type +[MIME-type] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    AddAltByType $B$O!"(B + FancyIndexing + $B$K$*$$$F!"%"%$%3%s$NBe$o$j$KI=<($9$kBeBXJ8;zNs$r@_Dj$7$^$9!#(B + MIME-type $B$OM-8z$J%?%$%W!"Nc$($P(B + text/html + $B$G$9!#(B + string $B$K6uGr$,$"$k$H$-$O!"0zMQId(B (" $B$+(B + ') $B$G0O$`I,MW$,$"$j$^$9!#(B + $B$3$NJ8;zNs$O!"%/%i%$%"%s%H$,2hA|$rI=<($G$-$J$$>l9g$d(B + $B2hA|$N%m!<%I$rL58z$K$7$F$$$k>l9g$d(B + $B%"%$%3%s$N + + $BNc(B + AddAltByType 'plain text' text/plain + + + + + +AddDescription +$B%U%!%$%k$KBP$7$FI=<($9$k@bL@(B +AddDescription string file [file] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    FancyIndexing + $B$K$*$$$F!"%U%!%$%k$KBP$7$FI=<($9$k@bL@$r@_Dj$7$^$9!#(B + file $B$O@bL@$9$k%U%!%$%k$N%U%!%$%k3HD%;R!"(B + $B%U%!%$%kL>$N0lIt!"%o%$%k%I%+!<%II=8=!"40A4$J%U%!%$%kL>$N(B + $B$I$l$+$K$J$j$^$9!#(B + string $B$OFs=E0zMQId(B (") $B$G0O$^$l$^$9!#(B

    + + $BNc(B + AddDescription "The planet Mars" /web/pics/mars.gif + + +

    $BDL>o$N%G%U%)%k%H$N@bL@NN0h$O(B 23 $B%P%$%H$NI}$G$9!#(B + IndexOptions SuppressIcon + $B%*%W%7%g%s$G(B 6 $B%P%$%HDI2C!"(B + IndexOptions SuppressSize + $B%*%W%7%g%s$G(B 7 $B%P%$%HDI2C!"(B + IndexOptions SuppressLastModified + $B%*%W%7%g%s$G(B 19 $B%P%$%HDI2C$5$l$^$9!#(B + $B$G$9$+$i!"%G%U%)%k%H$N@bL@%3%i%`$N:GBgI}$O(B + 55 $B%P%$%H$K$J$j$^$9!#(B

    + +

    $B$3$N%3%i%`$NBg$-$5$r>e=q$-$7$?$j!"(B + $B@bL@$,L5@)8BD9$G$b$h$$$h$&$K$9$k$?$a$N>\:Y$K4X$7$F$O!"(B + DescriptionWidth + $B$H$$$&(B + IndexOptions + $B$N%-!<%o!<%I$r$4Mw2<$5$$!#(B

    + + $B7Y9p(B +

    AddDescription + $B$GDj5A$5$l$?@bL@%F%-%9%H$O!"%?%0$dJ8;zNs$H$$$C$?(B + HTML $B%^!<%/%"%C%W$r4^$`$3$H$,$G$-$^$9!#(B + $B$b$7!"@bL@%3%i%`$NI}$K$h$C$F%?%0IU$1$5$l$?MWAG$,4]$a9~$^$l$?(B + ($BB@;z$N8l6g$N:G8e$,@Z$l$k$H$$$C$?(B) $B>l9g!"(B + $B=PNO7k2L$O!"%G%#%l%/%H%j0lMw$N;D$j$NItJ,$K1F6A$rM?$($k$G$7$g$&!#(B

    +
    +
    +
    + + +AddIcon +$B%U%!%$%k$KI=<($9$k%"%$%3%s$rL>A0$GA*Br(B +AddIcon icon name +[name] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    FancyIndexing + $B$K$*$$$F!"(B + name $B$G=*$o$k%U%!%$%k$NNY$KI=<($9$k%"%$%3%s$r@_Dj$7$^$9!#(B + icon $B$O!"(B(% $B$G%(%9%1!<%W$5$l$?(B) $B%"%$%3%s$X$NAjBP(B URL + $B$+!"B>$N=q<0(B (alttext, url) $B$G$9!#(B + $B$3$3$G(B alttext + $B$O!"Hs%0%i%U%#%+%k%V%i%&%68~$1$K%"%$%3%s$KIU$1$i$l$?%F%-%9%H%?%0$G$9!#(B +

    + +

    name $B$O!"%G%#%l%/%H%j$KBP1~$9$k(B ^^DIRECTORY^^ + $B$+!"6uGr9T$KBP1~$9$k(B ^^BLANKICON^^ ($B0lMw$,@5$7$/I=<($5$l$k$?$a$K(B) $B$+!"(B + $B%U%!%$%k3HD%;R$+!"%o%$%k%I%+!<%II=8=$+!"%U%!%$%kL>$N0lIt$+(B + $B40A4$J%U%!%$%kL>$G$9!#(B

    + + $BNc(B + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +
    + +

    $B$b$72DG=$J$i!"(B + AddIcon + $B$h$j(B + AddIconByType + $B$rM%@hE*$K;H$&$Y$-$G$7$g$&!#(B

    +
    +
    + + +AddIconByEncoding +$B%U%!%$%k$KI=<($9$k%"%$%3%s$r(B MIME +$BId9f2=J}K!$GA*Br(B +AddIconByEncoding icon MIME-encoding +[MIME-encoding] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    FancyIndexing + $B$K$*$$$F!"%U%!%$%k$NNY$KI=<($9$k%"%$%3%s$r@_Dj$7$^$9!#(B + icon $B$O!"(B(% $B$G%(%9%1!<%W$5$l$?(B) $B%"%$%3%s$X$NAjBP(B URL + $B$+!"B>$N=q<0(B (alttext, url) $B$G$9!#(B + $B$3$3$G(B alttext + $B$O!"Hs%0%i%U%#%+%k%V%i%&%68~$1$K%"%$%3%s$KIU$1$i$l$?%F%-%9%H%?%0$G$9!#(B +

    + +

    MIME-encoding $B$O!"MW5a$5$l$?%(%s%3!<%I$K3:Ev$9$k(B + $B%o%$%k%I%+!<%II=8=$G$9!#(B

    + + $BNc(B + AddIconByEncoding /icons/compress.xbm x-compress + +
    +
    + + +AddIconByType +$B%U%!%$%k$NNY$KI=<($9$k%"%$%3%s$r(B +MIME $B%?%$%W$K$h$C$FA*Br(B +AddIconByType icon MIME-type +[MIME-type] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    FancyIndexing + $B$K$*$$$F!"%U%!%$%k$NNY$KI=<($9$k%"%$%3%s$r@_Dj$7$^$9!#(B + icon $B$O!"(B(% $B$G%(%9%1!<%W$5$l$?(B) $B%"%$%3%s$X$NAjBP(B URL + $B$+!"B>$N=q<0(B (alttext, url) $B$G$9!#(B + $B$3$3$G(B alttext + $B$O!"Hs%0%i%U%#%+%k%V%i%&%68~$1$K%"%$%3%s$KIU$1$i$l$?%F%-%9%H%?%0$G$9!#(B +

    + +

    MIME-type $B$O!"MW5a$5$l$?%?%$%W$K3:Ev$9$k(B + $B%o%$%k%I%+!<%II=8=$G$9!#(B

    + + $BNc(B + AddIconByType (IMG,/icons/image.xbm) image/* + +
    +
    + + +DefaultIcon +$BFCDj$N%"%$%3%s$,2?$b@_Dj$5$l$F$$$J$$;~$K(B +$B%U%!%$%k$KI=<($9$k%"%$%3%s(B +DefaultIcon url-path +server config +virtual host +directory.htaccess + +Indexes + + +

    FancyIndexing + $B$K$*$$$F!"(B + $BFCDj$N%"%$%3%s$,$J$$>l9g$K%U%!%$%k$KI=<($9$k%"%$%3%s$r@_Dj$7$^$9!#(B + url-path $B$O!"(B(% $B$G%(%9%1!<%W$5$l$?(B) $B%"%$%3%s$X$NAjBP(B URL + $B$G$9!#(B

    + + $BNc(B + DefaultIcon /icon/unknown.xbm + +
    +
    + + +HeaderName + +$B%$%s%G%C%/%90lMw$N@hF,$KA^F~$5$l$k%U%!%$%k$NL>A0(B +HeaderName filename +server config +virtual host +directory.htaccess + +Indexes + + +

    HeaderName + $B%G%#%l%/%F%#%V$O!"(B + $B%$%s%G%C%/%90lMw$N@hF,$KA^F~$9$k%U%!%$%k$NL>A0$r@_Dj$7$^$9!#(B + Filename $B$OA0$G$9!#(B

    + + $BNc(B + HeaderName HEADER.html + + + +

    HeaderName $B$b(B ReadmeName + $B$bN>J}$H$b8=:_$O!"(Bfilename + $B$r%$%s%G%C%/%9$5$l$F$$$k%G%#%l%/%H%j$KMQ$$$i$l$?(B URI + $B$KBP$9$kAjBP(B URI $B%Q%9$H$7$F07$$$^$9!#(B + filename $B$,%9%i%C%7%e$G;O$^$k>l9g$O!"(B + DocumentRoot + $B$+$i$NAjBP%Q%9$H$J$j$^$9!#(B

    + + $BNc(B + HeaderName /include/HEADER.html + + +

    filename $B$O(B + $B%a%8%c!<%3%s%F%s%H%?%$%W$,(B "text/*" + ($BNc$($P(B$B!"(Btext/html, + text/plain $BEy$G$9!#(B) + $B$N%I%-%e%a%s%H$H$7$F2r7h(B + $B$5$l$J$1$l$P$J$j$^$;$s!#$3$l$O$D$^$j!"(B + $B$b$7(B CGI $B%9%/%j%W%H$Ntext/html $B$H$7$F%^!<%/$5$l$F$$$k>l9g!"(B + filename + $B$O(B CGI $B%9%/%j%W%H$r;2>H$9$k$+$bCN$l$J$$!"(B + $B$H$$$&$3$H$r0UL#$7$^$9(B:

    + + + AddType text/html .cgi + + +

    Options MultiViews $B$,(B + $BM-8z$K$J$C$F$$$k>l9g$O!"(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $B$,9T$J$o$l$^$9!#(B + $B$b$7(B filename $B$,(B (CGI $B%9%/%j%W%H$G$J$$(B) $B@EE*$J(B + text/html $B%I%-%e%a%s%H$G2r7h$5$l!"(B + options + Includes $B$+(B IncludesNOEXEC + $B$,M-8z$K$J$C$F$$$k>l9g$O!"(B + $B%U%!%$%k$O%5!<%P!<%5%$%I%$%s%/%k!<%I$G=hM}$5$l$^$9(B + (mod_include $B%I%-%e%a%s%H$r;2>H$7$F2<$5$$(B)$B!#(B

    +
    + +

    $B$b$7(B HeaderName $B$G;XDj$5$l$?%U%!%$%k$,(B + HTML $B%I%-%e%a%s%H$N3+;OItJ,(B (<html>, <head>, + $BEy(B) $B$r4^$s$G$$$?$i!"(B + IndexOptions + +SuppressHTMLPreamble + $B$r@_Dj$7$F!"$3$l$i$N%?%0$,7+$jJV$5$l$J$$$h$&$K$7$?$$$H;W$&$G$7$g$&!#(B

    +
    +
    + + +IndexIgnore +$B%G%#%l%/%H%j0lMw$r9T$J$&:]$KL5;k$9$Y$-(B +$B%U%!%$%k%j%9%H$KDI2C(B +IndexIgnore file [file] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    IndexIgnore $B%G%#%l%/%F%#%V$O!"(B + $B%G%#%l%/%H%j$N0lMw$r9T$&:]$KL5;k$9$Y$-%U%!%$%k%j%9%H$KDI2C$7$^$9!#(B + file $B$O!"(B + $B%7%'%k7A<0$N%o%$%k%I%+!<%II=8=$+40A4$J%U%!%$%kL>$G$9!#(B + IndexIgnore $B$,J#?t$"$k>l9g$O!"L5;k$9$k%j%9%H$KDI2C$,9T$o$l!"(B + $BCV49$O9T$o$l$^$;$s!#%G%U%)%k%H$G$O%j%9%H$K$O(B . + ($B%+%l%s%H%G%#%l%/%H%j(B) $B$,4^$^$l$F$$$^$9!#(B

    + + + IndexIgnore README .htaccess *.bak *~ + +
    +
    + + +IndexOptions +$B%G%#%l%/%H%j%$%s%G%C%/%9$NMM!9$J@_Dj9`L\(B + +IndexOptions [+|-]option [[+|-]option] ... +server config +virtual host +directory.htaccess + +Indexes + + +

    IndexOptions + $B$O!"%G%#%l%/%H%j%$%s%G%C%/%9$N5sF0$r;XDj$7$^$9!#(B + option $B$O + +

    +
    DescriptionWidth=[n | *] + (2.0.23 $B0J9_(B)
    + +
    DescriptionWidth + $B%-!<%o!<%I$O@bL@%3%i%`$NI}$rJ8;z?t$G;XDj$9$k$3$H$,$G$-$^$9!#(B
    + +
    -DescriptionWidth ($B$^$?$OHs@_Dj(B) $B$G!"(B + mod_autoindex $B$,:GE,$JI}$r7W;;$9$k$h$&$K$G$-$^$9!#(B
    + +
    DescriptionWidth=n + $B$G!"%3%i%`I}$r(B n $B%P%$%H$K8GDj$7$^$9!#(B
    + +
    DescriptionWidth=* + $B$O!":GD9$N@bL@$K9g$o$;$FI,MW$JD9$5$^$G%3%i%`$r1d$P$7$^$9!#(B
    + +
    $B@bL@$r4]$a9~$s$@>l9gFCM-$N4m81$K$D$$$F$O(B + AddDescription + $B%;%/%7%g%s$r$*FI$_2<$5$$!#(B
    + +
    FancyIndexing
    + +
    $B>~$jIU$-%$%s%G%C%/%9$r%*%s$K$7$^$9!#(B
    + +
    FoldersFirst + (2.0.23 $B0J9_(B)
    + +
    $B$3$N%*%W%7%g%s$,M-8z$K$J$C$?>l9g!"%5%V%G%#%l%/%H%j$N0lMw$O(B + $BI,$:(B$B:G=i$K8=$o$l$F!"$=$N%G%#%l%/%H%j$NDL>o$N%U%!%$%k$O(B + $B$=$N8e$KB3$-$^$9!#(B + $B0lMw$O4pK\E*$K$O!"%U%!%$%k$H%G%#%l%/%H%j$NFs$D$NItJ,$KJ,$1$i$l$F!"(B + $B$=$l$>$l$OJL!9$K%=!<%H$5$l!"$=$N8e%5%V%G%#%l%/%H%j$r@h$K$7$F(B + $BI=<($,9T$J$o$l$^$9!#Nc$($P%=!<%H=g$,L>A0$N9_=g$K$J$C$F$$$F!"(B + FoldersFirst $B$,M-8z$K$J$C$F$$$k>l9g$O!"(B + $B%5%V%G%#%l%/%H%j(B Zed $B$O%5%V%G%#%l%/%H%j(B + Beta $B$h$j$bA0$K%j%9%H$5$l!"DL>o$N%U%!%$%k(B + Gamma $B$d(B Alpha + $B$h$j$bA0$K%j%9%H$5$l$^$9!#(B$B$3$N%*%W%7%g%s$O(B + FancyIndexing + $B$bM-8z$K$J$C$F$$$k$H$-$K$N$_!"8z2L$,$"$j$^$9!#(B
    + +
    HTMLTable ($B
    + +
    $B$3$N~$j$NIU$$$?%G%#%l%/%H%j0lMw$N$?$a$K%F!<%V%k$r;H$C$?C1=c$JI=$r:n$j$^$9!#(B + $B$3$l$O8E$$%V%i%&%6$r:.Mp$5$;$k$+$b$7$l$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B + WinNT $B$d$=$NB>(B utf-8 + $B$,M-8z$J%W%i%C%H%[!<%`$N$h$&$K!"%U%!%$%kL>$d@bL@%F%-%9%H$,(B + $B1&FI$_$K$J$C$?$j:8FI$_$K$J$j$($k>l9g$OFC$KI,MW$G$9!#(B
    + +
    IconsAreLinks
    + +
    $B$3$l$O!"(BFancyIndexing $B$K$*$$$F!"(B + $B%"%$%3%s$b%U%!%$%kL>$X$N%j%s%/$N0lIt$K$7$^$9!#(B
    + +
    IconHeight[=pixels]
    + +
    $B$3$N%*%W%7%g%s$,!"(BIconWidth $B$H$H$b$K;H$o$l$F$$$k>l9g$O!"(B + $B%5!<%P$O%U%!%$%k%"%$%3%s$N$?$a$N(B img + $B%?%0$K(B height $B$H(B width + $BB0@-$r + +
    IconWidth[=pixels]
    + +
    $B$3$N%*%W%7%g%s$,!"(BIconHeight $B$H$H$b$K;H$o$l$F$$$k>l9g$O!"(B + $B%5!<%P$O%U%!%$%k%"%$%3%s$N$?$a$N(B img + $B%?%0$K(B height $B$H(B width + $BB0@-$r + +
    IgnoreCase
    + +
    $B$3$N%*%W%7%g%s$,M-8z$G$"$k$H!"%U%!%$%kL>$OBgJ8;z>.J8;z$r6hJL$;$:$K%=!<%H$5$l$^$9!#(B + $BNc$($P%U%!%$%kL>$,>:=g$G%=!<%H$5$l!"(BIgnoreCase $B$,M-8z$G$"$l$P!"(B + Zeta $B$O(B alfa $B$N8e$K%j%9%H$5$l$^$9(B + ($BCm0U(B: GAMMA $B$O>o$K(B gamma $B$NA0$K$J$j$^$9(B)$B!#(B
    + +
    IgnoreClient
    + +
    $B$3$N%*%W%7%g%s$G(B mod_autoindex $B$O!"(B + $B%/%i%$%"%s%H$+$i$NA4$F$N%/%(%j!SuppressColumnSorting + $B$r0E$K0UL#$7$^$9!#(B)
    + +
    NameWidth=[n + | *]
    + +
    NameWidth $B%-!<%o!<%I$G%U%!%$%kL>%3%i%`$NI}$r%P%$%H?t$G(B + $B;XDj$G$-$^$9!#(B
    + +
    -NameWidth ($B$^$?$OHs@_Dj(B) $B$G!"(B + mod_autoindex $B$,:GE,$JI}$r7W;;$9$k$h$&$K$G$-$^$9!#(B
    + +
    NameWidth=n + $B$G!"%3%i%`I}$r(B n $B%P%$%H$K8GDj$7$^$9!#(B
    + +
    NameWidth=* + $B$O!"I,MW$JD9$5$^$G%3%i%`$r1d$P$7$^$9!#(B
    + +
    ScanHTMLTitles
    + +
    FancyIndexing $B$N$?$a$K!"(B + HTML $B%I%-%e%a%s%H$+$i%?%$%H%k$rAddDescription + $B$G@bL@$,M?$($i$l$F$$$J$1$l$P!"(B + httpd $B$O(B title $B%?%0$NCM$rFI$`$?$a$K%I%-%e%a%s%H$rFI$_;O$a$^$9!#(B + $B$3$l$O(B CPU $B$d(B disk $B$KIi2Y$r$+$1$^$9!#(B
    + +
    ShowForbidden
    + +
    $B;XDj$7$?>l9g$G$"$C$F$b!"%5%V%j%/%(%9%H$N7k2L$,(B HTTP_UNAUTHORIZED $B$d(B + HTTP_FORBIDDEN $B$N%U%!%$%k$ODL>oDL$j1#$5$l$?>uBV$N$^$^!"(B + $B%U%!%$%k0lMw$,@8@.$5$l$^$9!#(B
    + +
    SuppressColumnSorting
    + +
    $B$b$7;XDj$5$l$F$$$l$P!"(BApache $B$O(B + FancyIndexing $B$GI=<($5$l$F$$$k%G%#%l%/%H%j0lMw$G$N(B + $B%3%i%`$N@hF,$r!"%=!<%H$N$?$a$N%j%s%/$K$7$J$/$J$j$^$9!#(B + $B%G%U%)%k%H$N5sF0$O!"%j%s%/$H$7$^$9!#(B + $B%3%i%`$N@hF,$rA*$V$H%3%i%`$NCM$K=>$C$F%G%#%l%/%H%j%j%9%H$r(B + $B%=!<%H$7$^$9!#(B + Apache 2.0.23 $B0JA0$G$O!"$3$l$OF1;~$K(B + $B%=!<%HJ8;zNs$N$?$a$N%/%(%j!<0z?t$N2r@O$bL58z$K$7$^$9!#(B + + $B$3$N5sF0$O(B Apache 2.0.23 $B$G$O(B + IndexOptions + IgnoreClient $B$G@)8f$5$l$k$h$&$K$J$C$F$$$^$9!#(B
    + +
    SuppressDescription
    + +
    $B$3$l$O(B FancyIndexing $B$K$*$1$k%U%!%$%k$N@bL@$r>C5n$7$^$9!#(B + $B%G%U%)%k%H$G$O!"@bL@$ODj5A$5$l$F$*$i$:!"(B + $B$3$N%*%W%7%g%s$r;H$&$HB>$N$?$a$K(B 23 + $BJ8;z$N6uGr$r2T$0$3$H$,$G$-$^$9!#(B $B%U%!%$%k$N@bL@$K4X$9$k>pJs$O!"(B + AddDescription + $B$r$4Mw2<$5$$!#$^$?!"@bL@$N%3%i%`%5%$%:$r@)8B$9$k(B + DescriptionWidth + $B%$%s%G%C%/%9%*%W%7%g%s$b$4Mw2<$5$$!#(B
    + +
    SuppressHTMLPreamble
    + +
    $BDL>o!"(B + HeaderName + $B%G%#%l%/%F%#%V$G;XDj$7$?%U%!%$%k$r(B + $B%G%#%l%/%H%j$,<html>, <head>, $BEy(B) $B$N8e$K!"(B + $B%b%8%e!<%k$O%U%!%$%k$NCf?H$r%$%s%/%k!<%I$7$^$9!#(B + SuppressHTMLPreamble $B%*%W%7%g%s$O!"(B + $B$3$N5sF0$rL58z$K$G$-$F!"(B + $B%b%8%e!<%k$,%X%C%@!<%U%!%$%k$NCf?H$+$iI=<($r;O$a$^$9!#(B + $B$3$N>l9g!"%X%C%@!<%U%!%$%k$O@5$7$$(B HTML + $BL?Na$r4^$s$G$$$J$1$l$P$J$j$^$;$s!#(B + $B%X%C%@!<%U%!%$%k$,B8:_$7$J$$>l9g$O!"%W%j%"%s%V%k$ODL>oDL$j(B + $B@8@.$5$l$^$9!#(B
    + +
    SuppressIcon (Apache + 2.0.23 $B0J9_(B)
    + +
    + $B$3$l$O(B FancyIndexing $B$N0lMw$+$i%"%$%3%s$r>C5n$7$^$9!#(B + SuppressIcon $B$H(B SuppressRules + $B$HAH9g$o$;$k$3$H$K$h$C$F@5$7$$(B HTML 3.2 $B$N=PNO$,F@$i$l$^$9!#(B + $B@5$7$$(B HTML 3.2 $B=PNO$O!":G=*5,3J$K$*$$$F(B img $B$H(B hr + $B$,(B pre $B%V%m%C%/$KF~$k(B (FancyIndexing $B0lMw$G=q<0$K;H$o$l$F$$$^$9(B) + $B$3$H$r6X;_$7$F$$$^$9!#(B
    + +
    SuppressLastModified
    + +
    FancyIndexing $B0lMw$K$*$$$F:G=*99?7F|;~$NI=<($r>C5n$7$^$9!#(B
    + +
    SuppressRules + (Apache 2.0.23 $B0J9_(B)
    + +
    $B%G%#%l%/%H%j0lMw$K$*$$$F?eJ?6h@Z$j@~(B (hr $B%?%0(B) $B$r>C5n$7$^$9!#(B + SuppressIcon $B$H(B SuppressRules + $B$HAH9g$o$;$k$3$H$K$h$C$F@5$7$$(B HTML 3.2 $B$N=PNO$,F@$i$l$^$9!#(B + $B@5$7$$(B HTML 3.2 $B=PNO$O!":G=*5,3J$K$*$$$F(B img $B$H(B hr + $B$,(B pre $B%V%m%C%/$KF~$k(B (FancyIndexing $B0lMw$G=q<0$K;H$o$l$F$$$^$9(B) + $B$3$H$r6X;_$7$F$$$^$9!#(B
    + +
    SuppressSize
    + +
    FancyIndexing $B0lMw$K$*$$$F%U%!%$%k%5%$%:$NI=<($r>C5n$7$^$9!#(B
    + +
    TrackModified + (Apache 2.0.23 $B0J9_(B)
    + +
    $B$3$l$O(B HTTP $B%X%C%@Cf$K!"(B + $B%j%9%H$5$l$?%G%#%l%/%H%j$N:G=*99?7F|$d(B ETag $BCM$r4^$a$^$9!#(B + $B$3$l$O!"%*%Z%l!<%F%#%s%0%7%9%F%`$d%U%!%$%k%7%9%F%`$,(B + $BE,@Z$J(B stat() $B$NJV$jCM$rJV$9>l9g$K$N$_M-8z$G$9!#(B + $B$$$/$D$+$N(B UNIX $B%7%9%F%`!"(BOS2 $B$N(B JFS $B$d(B Win32 $B$N(B NTFS + $B%\%j%e!<%`$O$=$&$J$C$F$$$^$9!#(B + $BNc$($P!"(BOS2 $B$H(B Win32 FAT $B%\%j%e!<%`$O$=$&$G$O$"$j$^$;$s!#(B + $B$3$N5!G=$,M-8z$K$J$k$H!"%/%i%$%"%s%H$d%W%m%-%7$O(B + HEAD $B%j%/%(%9%H$r9T$&$3$H$K$h$C$F!"(B + $B%U%!%$%k0lMw$NJQ2=$rDI@W$9$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B + $B$$$/$D$+$N%*%Z%l!<%F%#%s%0%7%9%F%`$O!"?75,%U%!%$%k$d(B + $B0\F0%U%!%$%k$O@5$7$/DI@W$9$k$1$l$I$b!"(B + $B%G%#%l%/%H%jCf$N%U%!%$%k$N%5%$%:$dF|IU$ODI@W$J$$$H$$$&$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B + $B4{$KB8:_$9$k%U%!%$%k$N%5%$%:$dF|IU$N%9%?%s%W$,JQ2=$7$F$b!"(B + $BA4$F$N(B Unix $B%W%i%C%H%[!<%`$G$O!"(B + $B:G=*99?7F|%X%C%@!<$r99?7$7$^$;$s!#(B + $B$b$7$3$l$,=EMW$G$"$l$P!"(B + $B$3$N%*%W%7%g%s$rL58z$N$^$^$K$7$F$/$@$5$$!#(B
    + +
    VersionSort + (Apache 2.0a3 $B0J9_(B)
    + +
    VersionSort $B%-!<%o!<%I$O%P!<%8%g%sHV9f$r4^$s$@%U%!%$%k$,(B + $B<+A3$JJ}K!$G%=!<%H$5$l$k$h$&$K$7$^$9!#(B + $BJ8;zNs$ODL>oDL$j%=!<%H$5$l!"(B + $B$=$l0J30$N!"@bL@$dL>A0Cf$N?t$H$J$kItJ,J8;zNs$O(B + $B$=$N?tCM$GHf3S$5$l$^$9!#(B + + $BNc(B: + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +
    + +

    $BHV9f$,(B 0 $B$+$i;O$^$k>l9g$O!"C + + + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +
    +

    + +
    XHTML + (Apache 2.0.49 $B0J9_(B)
    + +
    XHTML $B%-!<%o!<%I$r;XDj$9$k$H!"(Bmod_autoindex + $B$O(B HTML 3.2 $B$NBe$o$j$K(B XHTML 1.0 $B$N%3!<%I$r=PNO$9$k$h$&$K$J$j$^$9!#(B
    +
    + + +
    $BA}8:;XDj$G$-$k(B IndexOptions
    +
    +

    Apache 1.3.3 $B$G$O!"(B + IndexOptions + $B%G%#%l%/%F%#%V$N07$$$G4v$D$+$NBg$-$JJQ2=$,F3F~$5$l$^$7$?!#(B + $BFC$K!"(B

    + +
      +
    • $B0l$D$N%G%#%l%/%H%j$KBP$9$kJ#?t$N(B + IndexOptions + $B%G%#%l%/%F%#%V$O!"8=:_$G$O0l$D$K%^!<%8$5$l$^$9!#(B + $B>e$NNc$N7k2L$O!"(B + + + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +
      + +

      $B$HF10l$K$J$j$^$9!#(B

      + + + IndexOptions HTMLTable SuppressColumnsorting + +
    • + +
    • $BA}8:9=J8(B + ($B$9$J$o$A(B$B!"(B'+' $B$d(B '-' + $B$N@\F,<-$,IU$/%-!<%o!<%I(B) $B$NDI2C!#(B
    • +
    + +

    '+' $B$d(B '-' $B@\F,<-$NIU$$$?%-!<%o!<%I$K=P2q$&$H$=$l$O!"(B + $B$=$N;~E@$G$N(B IndexOptions + $B$N@_Dj(B ($B$3$l$O>eN.$N%G%#%l%/%H%j$rl9g$O!"(B + $BC5n$5$l$^$9!# + + + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +
    + +

    $BCf?H$N8z2L$O(B + IndexOptions FancyIndexing +SuppressSize + $B$HF10l$G$9!#(B + $B@\F,<-$NIU$+$J$$(B FancyIndexing + $B$G$=$l0JA0$NA}8:%-!<%o!<%I$rL58z$K$5$l$F!"(B + $B$=$N8e$NN_@Q$,;O$^$k$+$i$G$9!#(B

    + +

    $BL5>r7o$K(B IndexOptions + $B$r$"$k%G%#%l%/%H%j$G@_Dj$9$k$3$H$K$h$C$F(B + $B7Q>5$7$?@_Dj$r>C5n$7$F!"(B+ $B$d(B - + $B@\F,<-$NIU$+$J$$%-!<%o!<%I$G@_Dj$7$F$/$@$5$$!#(B

    +
    +
    +
    +
    + + +IndexOrderDefault + +$B%G%#%l%/%H%j%$%s%G%C%/%9$NI8=`$N=gHVIU$1$r@_Dj(B +IndexOrderDefault Ascending|Descending +Name|Date|Size|Description +IndexOrderDefault Ascending Name +server config +virtual host +directory.htaccess + +Indexes + + +

    IndexOrderDefault $B%G%#%l%/%F%#%V$O(B + FancyIndexing + $B%$%s%G%C%/%9%*%W%7%g%s$HJ;$;$FMQ$$$l$l$^$9!#(B + $B%G%U%)%k%H$G$O!"(BFancyIndexing + $B$N%G%#%l%/%H%j0lMw$O%U%!%$%kL>$N>:=g$GI=<($5$l$^$9!#(B + IndexOrderDefault + $B$G!"=i4|>uBV$NI=<(=gHV$rJQ$($k$3$H$,$G$-$^$9!#(B

    + +

    IndexOrderDefault + $B$OFs$D$N0z?t$r$H$j$^$9!#0l$DL\$O%=!<%H$NJ}8~$r;X<($9$k(B + Ascending $B$+(B Descending $B$N$$$:$l$+$G$9!#(B + $BFs$DL\$N0z?t$O(B Name, Date, + Size $B$+(B Description + $B$N$$$:$l$+0l$D$N%-!<%o!<%I$G$"$C$F!"%W%i%$%^%j%-!<$r;XDj$7$^$9!#(B + $BFs$DL\$N%-!<$O(B$B>o$K(B$B%U%!%$%kL>$N>:=g$K$J$j$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$H(B SuppressColumnSorting + $B%$%s%G%C%/%9%*%W%7%g%s$H$rAH$_9g$o$;$k$3$H$G!"(B + $B%G%#%l%/%H%j0lMw$r$"$kFCDj$N=gHV$G$N$_I=<($9$k$h$&$K$G$-$^$9!#(B + $B$3$l$O!"(B + $B%/%i%$%"%s%H$,JL$N=gHV$G%G%#%l%/%H%j0lMw$r%j%/%(%9%H$9$k$3$H$rKI$.$^$9!#(B

    +
    +
    + + +IndexStyleSheet +$B%G%#%l%/%H%j%$%s%G%C%/%9$K(B CSS $B%9%?%$%k%7!<%H$rDI2C$9$k(B +IndexStyleSheet url-path +server configvirtual host +directory.htaccess + +Indexes + + +

    IndexStyleSheet $B%G%#%l%/%F%#%V$O(B + $B%$%s%G%C%/%9I=<($K;HMQ$5$l$k(B CSS $B$N%U%!%$%kL>$r@_Dj$7$^$9!#(B +

    + + $BNc(B + IndexStyleSheet "/css/style.css" + +
    +
    + + +ReadmeName +$B%$%s%G%C%/%90lMw$N:G8e$KA^F~$5$l$k%U%!%$%k$NL>A0(B +ReadmeName filename +server config +virtual host +directory.htaccess + +Indexes + + +

    ReadmeName $B%G%#%l%/%F%#%V$O!"(B + $B%$%s%G%C%/%9$N=*$o$j$KIU$12C$($i$l$k%U%!%$%k$NL>A0$r@_Dj$7$^$9!#(B + filename $B$OA^F~$9$k%U%!%$%k$NL>A0$G!"(B + $B0lMw$N9T$o$l$F$$$k0LCV$+$iAjBPE*$J$b$N$H$7$F2rfilename $B$,%9%i%C%7%e$G;O$^$k>l9g$O!"(B + DocumentRoot + $B$+$i$NAjBP%Q%9$H$J$j$^$9!#(B

    + + $BNc(B + ReadmeName FOOTER.html + + + $BNc(B 2 + ReadmeName /include/FOOTER.html + + +

    $B$h$j>\:Y$K$^$G$3$N5sF0$K$D$$$F5-=R$7$F$$$k(B HeaderName + $B$b$4Mw2<$5$$!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_autoindex.xml.ko b/trunk/docs/manual/mod/mod_autoindex.xml.ko new file mode 100644 index 0000000000..799a373d24 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.xml.ko @@ -0,0 +1,884 @@ + + + + + + + + +mod_autoindex + +ÀÚµ¿À¸·Î À¯´Ð½ºÀÇ ls ¸í·É¾î³ª Win32ÀÇ + dir ½©¸í·É¾î¿Í À¯»çÇÑ µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù +Base +mod_autoindex.c +autoindex_module + + +

    µð·ºÅ丮 ¸ñ·ÏÀº ¾ò´Â ¹æ¹ýÀº µÎ°¡Áö´Ù:

    + +
      +
    • º¸Åë index.htmlÀ̶õ À̸§À¸·Î »ç¿ëÀÚ°¡ + ÀÛ¼ºÇÑ ÆÄÀÏ. ÀÌ ÆÄÀÏÀÇ À̸§Àº DirectoryIndex Áö½Ã¾î·Î + ÁöÁ¤ÇÑ´Ù. ÀÌ ÀÛ¾÷Àº mod_dirÀÌ ÇÑ´Ù.
    • + +
    • ¾Æ´Ï¸é ¼­¹ö°¡ ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ ¸ñ·ÏÀÇ Çü½ÄÀ» ÁöÁ¤ÇÏ´Â + Áö½Ã¾îµéÀÌ ÀÖ´Ù. AddIcon, AddIconByEncoding, + AddIconByTypeÀº + ¿©·¯ ÆÄÀÏÁ¾·ù¸¶´Ù º¸¿©ÁÙ ¾ÆÀÌÄܵéÀ» ÁöÁ¤ÇÑ´Ù. °¢ ÆÄÀÏ¿¡ + ´ëÀÀÇϴ ù¹ø° ¾ÆÀÌÄÜÀ» º¸ÀδÙ. ÀÌ ÀÛ¾÷À» + mod_autoindex°¡ ÇÑ´Ù.
    • +
    +

    ÀÌ µÎ ±â´ÉÀº ¼­·Î º°°³·Î, ¿øÇÑ´Ù¸é ÀÚµ¿ ¸ñ·Ï »ý¼ºÀ» ¿ÏÀüÈ÷ + Á¦¿ÜÇÒ (ȤÀº ´ëüÇÒ) ¼ö ÀÖ´Ù.

    + +

    ÀÚµ¿ ¸ñ·Ï »ý¼ºÀº Options +Indexes·Î °¡´ÉÇÏ´Ù. + ÀÚ¼¼ÇÑ ³»¿ëÀº Options + Áö½Ã¾î¸¦ Âü°íÇ϶ó.

    + +

    IndexOptions + Áö½Ã¾î¿¡ FancyIndexing ¿É¼ÇÀ» ÁÖ¸é, ¿­ À̸§À» Ãâ·ÂÇÒ + ¼ø¼­¸¦ ¹Ù²Ù´Â ¸µÅ©·Î ¸¸µç´Ù. À̸§ ¸µÅ©¸¦ ¼±ÅÃÇÏ¸é ±× ¿­ÀÇ + °ª ¼ø¼­·Î ¸ñ·ÏÀ» ´Ù½Ã ¸¸µç´Ù. °°Àº À̸§À» ¹Ýº¹Çؼ­ ¼±ÅÃÇϸé + ¿À¸§Â÷¼ø°ú ³»¸²Â÷¼ø »çÀ̸¦ ¿À°£´Ù. IndexOptions Áö½Ã¾îÀÇ + SuppressColumnSorting ¿É¼ÇÀº ÀÌ·± ¿­ À̸§ ¸µÅ©¸¦ + ¸¸µéÁö ¾Ê´Â´Ù.

    + +

    "Size(Å©±â)" ¼øÀ¸·Î º¼¶§ Ãâ·ÂµÇ´Â °ª ¼ø¼­°¡ ¾Æ´Ï¶ó ½ÇÁ¦ + ÆÄÀÏÅ©±â ¼ø¼­ÀÓÀ» ÁÖÀÇÇ϶ó. Áï, 1010 ¹ÙÀÌÆ® ÆÄÀÏ°ú 1011 + ¹ÙÀÌÆ® ÆÄÀÏÀº µÑ´Ù "1K"·Î º¸ÀÌ´õ¶óµµ Ç×»ó 1010 ¹ÙÀÌÆ® ÆÄÀÏÀÌ + ¾Õ¿¡ ³ª¿Â´Ù.

    +
    + +
    + Autoindex ¿äû ¾Æ±Ô¸ÕÆ® + +

    ¾ÆÆÄÄ¡ 2.0.23´Â ¿­¼ø¼­¿¡ ´ëÇÑ ¿äû ¾Æ±Ô¸ÕÆ®¸¦ Á¤¸®ÇÏ°í, + »õ·Î¿î ¿É¼ÇµéÀ» Ãß°¡Çß´Ù. Ãâ·ÂÀ» Ŭ¶óÀ̾ðÆ®°¡ Á¶ÀýÇÒ ¼ö + ¾øµµ·Ï ¸¸µå´Â IndexOptions + IgnoreClient ¿É¼ÇÀÌ Ãß°¡µÇ¾ú´Ù.

    + +

    ¿­¼ø¼­ À̸§Àº ¾Æ·¡ ³ª¿Â ¼ø¼­ ¿äû ¿É¼ÇÀ» ´õÇÑ ÀÚ±âÂüÁ¶ + ¸µÅ©´Ù. ¾Æ·¡ ¿É¼ÇÀº µð·ºÅ丮 ÀÚ¿ø¿¡ ´ëÇÑ ¾î¶² ¿äû¿¡µµ + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
      +
    • C=NÀº ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=MÀº ÃÖ±Ù ¼öÁ¤ÀÏ ¼ø, ±×¸®°í ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=S´Â Å©±â ¼ø, ±×¸®°í ÆÄÀÏ¸í ¼øÀÌ´Ù
    • + +
    • C=D´Â ¼³¸í ¼ø, ±×¸®°í ÆÄÀϸí + ¼øÀÌ´Ù
    • + +
    • O=A´Â ¿À¸§Â÷¼øÀ¸·Î ¸ñ·ÏÀ» Á¤·ÄÇÑ´Ù
    • + +
    • O=D´Â ³»¸²Â÷¼øÀ¸·Î ¸ñ·ÏÀ» Á¤·ÄÇÑ´Ù
    • + +
    • F=0Àº (FancyIndexed°¡ ¾Æ´Ñ) °£´ÜÇÑ ¸ñ·Ï Çü½ÄÀÌ´Ù
    • + +
    • F=1Àº FancyIndexed ¸ñ·Ï Çü½ÄÀÌ´Ù
    • + +
    • F=2´Â HTMLTable FancyIndexed ¸ñ·Ï + Çü½ÄÀÌ´Ù
    • + +
    • V=0Àº ¹öÀü ¼øÀ¸·Î Á¤·ÄÇÏÁö ¾Ê´Â´Ù
    • + +
    • V=1Àº ¹öÀü ¼øÀ¸·Î Á¤·ÄÇÑ´Ù
    • + +
    • P=patternÀº ÁÖ¾îÁø pattern¿¡ + ÇØ´çÇÏ´Â ÆÄÀϸ¸À» ¸ñ·ÏÀ¸·Î ¸¸µç´Ù
    • +
    + +

    'P'attern ¾Æ±Ô¸ÕÆ®´Â ÀϹÝÀûÀÎ IndexIgnore Áö½Ã¾î¸¦ ó¸®ÇÑ ÈÄ¿¡ + °Ë»çÇϱ⶧¹®¿¡, ¸ñ·ÏÀº ´Ù¸¥ autoindex Á¶°ÇÀ» µû¸§À» ÁÖÀÇÇ϶ó. + mod_autoindexÀÇ ¿äû ¾Æ±Ô¸ÕÆ®¸¦ ÀоîµéÀ϶§ + ¾Ë ¼ö ¾ø´Â ¿É¼ÇÀ» ¹ß°ßÇÏ¸é ´õ ÀÌ»ó ÀÐÁö¾Ê´Â´Ù. ¿äû ¾Æ±Ô¸ÕÆ®´Â + À§ÀÇ Ç¥¿¡ µû¶ó ¸¸µé¾î¾ß ÇÑ´Ù.

    + +

    header.html ÆÄÀÏ¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¾Æ·¡ °£´ÜÇÑ ¿¹Á¦´Â + ÀÌ ¿É¼ÇµéÀ» ¼³¸íÇÑ´Ù. submit ¹öÅÏÀÇ ¾Ë ¼ö ¾ø´Â "X" ¾Æ±Ô¸ÕÆ®´Â + mod_autoindex°¡ X=Go Àü±îÁö ¸ðµç ¾Æ±Ô¸ÕÆ®¸¦ ÀоîµéÀÓÀ» + È®ÀÎÇϱâÀ§ÇØ ¸¶Áö¸·¿¡ »ç¿ëÇß´Ù.

    + + + <form action="" method="get">
    + + Show me a <select name="F">
    + + <option value="0"> Plain list</option>
    + <option value="1" selected="selected"> Fancy list</option>
    + <option value="2"> Table list</option>
    +
    + </select>
    + Sorted by <select name="C">
    + + <option value="N" selected="selected"> Name</option>
    + <option value="M"> Date Modified</option>
    + <option value="S"> Size</option>
    + <option value="D"> Description</option>
    +
    + </select>
    + <select name="O">
    + + <option value="A" selected="selected"> Ascending</option>
    + <option value="D"> Descending</option>
    +
    + </select>
    + <select name="V">
    + + <option value="0" selected="selected"> in Normal order</option>
    + <option value="1"> in Version order</option>
    +
    + </select>
    + Matching <input type="text" name="P" value="*" />
    + <input type="submit" name="X" value="Go" />
    +
    + </form> +
    + +
    + + +AddAlt +ÆÄÀϸíÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ ¼³¸í±Û +AddAlt string file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAlt´Â FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. File¿¡´Â + ¼³¸íÇÒ ÆÄÀÏÀÇ ÆÄÀÏ È®ÀåÀÚ, ÆÄÀϸí ÀϺÎ, ¿ÍÀϵåÄ«µå Ç¥Çö, + Àüü ÆÄÀϸíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. String¿¡ °ø¹éÀÌ + µé¾î°£´Ù¸é µû¿ÈÇ¥(" ȤÀº ')·Î + ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ + ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + + ¿¹Á¦ + AddAlt "PDF file" *.pdf
    + AddAlt Compressed *.gz *.zip *.Z +
    +
    +
    + + +AddAltByEncoding +MIME-encodingÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û +AddAltByEncoding string MIME-encoding +[MIME-encoding] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAltByEncodingÀº FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. MIME-encodingÀº + x-compress¿Í °°Àº À¯È¿ÇÑ content-encodingÀÌ´Ù. + String¿¡ °ø¹éÀÌ µé¾î°£´Ù¸é µû¿ÈÇ¥(" + ȤÀº ')·Î ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ + º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì + ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + + ¿¹Á¦ + AddAltByEncoding gzip x-gzip + +
    +
    + + +AddAltByType +MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û +AddAltByType string MIME-type +[MIME-type] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    AddAltByTypeÀº FancyIndexing¿¡¼­ + ÆÄÀÏ¿¡ ´ëÇÑ ¾ÆÀÌÄÜ´ë½Å º¸ÀÏ ±ÛÀ» ÁöÁ¤ÇÑ´Ù. MIME-typeÀº + text/html°ú °°Àº À¯È¿ÇÑ content-typeÀÌ´Ù. + String¿¡ °ø¹éÀÌ µé¾î°£´Ù¸é µû¿ÈÇ¥(" + ȤÀº ')·Î ¹­¾î¾ß ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®°¡ À̹ÌÁö¸¦ + º¼ ¼ö ¾ø°Å³ª, À̹ÌÁö¸¦ ÀÐÁö¾Ê°Å³ª, ¾ÆÀÌÄÜÀ» ¸ø ¾òÀº °æ¿ì + ÀÌ Ãß°¡ ±ÛÀÌ º¸ÀÌ°Ô µÈ´Ù.

    + + ¿¹Á¦ + AddAltByType 'plain text' text/plain + +
    +
    + + +AddDescription +ÆÄÀÏ¿¡ ´ëÇÑ ¼³¸í +AddDescription string file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ ÆÄÀÏ¿¡ ´ëÇÑ ¼³¸íÀ» ÁöÁ¤ÇÑ´Ù. + File¿¡´Â ¼³¸íÇÒ ÆÄÀÏÀÇ ÆÄÀÏ È®ÀåÀÚ, ÆÄÀϸí ÀϺÎ, + ¿ÍÀϵåÄ«µå Ç¥Çö, Àüü ÆÄÀϸíÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. StringÀº + µû¿ÈÇ¥(")·Î ¹­¾î¾ß ÇÑ´Ù.

    + + ¿¹Á¦ + AddDescription "The planet Mars" /web/pics/mars.gif + + +

    ÀüÇüÀûÀÎ ±âº» ¼³¸í ÇʵåÆøÀº 23 ¹ÙÀÌÆ®´Ù. IndexOptions + SuppressIcon ¿É¼ÇÀ» »ç¿ëÇÏ¸é ±âº»Æø¿¡ 6 ¹ÙÀÌÆ®¸¦ + ´õ Ãß°¡ÇÏ°í, IndexOptions SuppressSize ¿É¼ÇÀº 7 ¹ÙÀÌÆ®¸¦, + IndexOptions SuppressLastModified ¿É¼ÇÀº 19 + ¹ÙÀÌÆ®¸¦ ´õ Ãß°¡ÇÑ´Ù. ±×·¯¹Ç·Î °¡Àå ³ÐÀº ¼³¸íÆøÀº 55 ¹ÙÀÌÆ®´Ù.

    + +

    ÀÌ ÇʵåÀÇ Æø¸¦ ¹Ù²Ù°Å³ª ¼³¸íÀÇ ±æÀ̸¦ ¹«ÇÑ´ë·Î ¸¸µå·Á¸é + DescriptionWidth IndexOptions Å°¿öµå¸¦ Âü°íÇ϶ó.

    + + Á¶½É +

    AddDescriptionÀ¸·Î ÁöÁ¤ÇÑ ¼³¸í±Û¿¡ + ű׳ª character entity&lt;, &amp; µîÀ» + ÁöĪ°°Àº HTMLÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª Æø¶§¹®¿¡ + űװ¡ ÀÖ´Â ºÎºÐÀÌ Â©¸®°ÔµÇ¸é (¿¹¸¦ µé¾î ±½ÀºÃ¼ ºÎºÐ ³¡ÀÌ + ©¸®¸é) ³ª¸ÓÁö µð·ºÅ丮 ¸ñ·Ï¿¡ ¿µÇâÀ» ÁÙ ¼ö ÀÖ´Ù.

    +
    +
    +
    + + +AddIcon +À̸§À¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ +AddIcon icon name [name] +... +server configvirtual host +directory.htaccess + +Indexes + + +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ nameÀ¸·Î ³¡³ª´Â + ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. IconÀº + ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    Name¿¡´Â µð·ºÅ丮¸¦ ³ªÅ¸³»´Â ^^DIRECTORY^^, + (¸ñ·Ï Çü½ÄÀ» ¿Ã¹Ù·Î ¸ÂÃß±âÀ§ÇØ) ºóÁÙÀ» ³ªÅ¸³»´Â + ^^BLANKICON^^, ÆÄÀÏ È®ÀåÀÚ, ¿ÍÀϵåÄ«µå Ç¥Çö, + ÆÄÀϸí ÀϺΠȤÀº Àüü¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + + ¿¹Á¦ + AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
    + AddIcon /icons/dir.xbm ^^DIRECTORY^^
    + AddIcon /icons/backup.xbm *~ +
    + +

    °¡´ÉÇϸé AddIconº¸´Ù´Â AddIconByTypeÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    +
    +
    + + +AddIconByEncoding +MIME content-encodingÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ +AddIconByEncoding icon MIME-encoding +[MIME-encoding] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ + ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. IconÀº + ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    MIME-encoding´Â content-encoding¿¡ ÇØ´çÇÏ´Â + ¿ÍÀϵåÄ«µå Ç¥ÇöÀÌ´Ù.

    + + ¿¹Á¦ + AddIconByEncoding /icons/compress.xbm x-compress + +
    +
    + + +AddIconByType +MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ +AddIconByType icon MIME-type +[MIME-type] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    ÀÌ Áö½Ã¾î´Â FancyIndexing¿¡¼­ + MIME-typeÀÇ ÆÄÀÏ ¿·¿¡ º¸¿©ÁÙ ¾ÆÀÌÄÜÀ» ÁöÁ¤ÇÑ´Ù. + IconÀº ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URL ȤÀº + (alttext,url) Çü½ÄÀÌ´Ù. + ¿©±â¼­ alttext´Â ±×¸²À» º¸¿©ÁÙ ¼ö ¾ø´Â ºê¶ó¿ìÀú°¡ + ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ¹®±¸ÀÌ´Ù.

    + +

    MIME-typeÀº mime type¿¡ ÇØ´çÇÏ´Â ¿ÍÀϵåÄ«µå + Ç¥ÇöÀÌ´Ù.

    + + ¿¹Á¦ + AddIconByType (IMG,/icons/image.xbm) image/* + +
    +
    + + +DefaultIcon +ƯÁ¤ ¾ÆÀÌÄÜÀ» ¼³Á¤ÇÏÁö¾ÊÀº ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ +DefaultIcon url-path +server configvirtual host +directory.htaccess + +Indexes + + +

    DefaultIcon Áö½Ã¾î´Â FancyIndexing¿¡¼­ + ƯÁ¤ ¾ÆÀÌÄÜÀ» ¼³Á¤ÇÏÁö¾ÊÀº ÆÄÀÏ ¿·¿¡ ³ª¿Ã ¾ÆÀÌÄÜÀÌ´Ù. + IconÀº ¾ÆÀÌÄÜÀÇ (%-escaped) »ó´ë URLÀÌ´Ù.

    + + ¿¹Á¦ + DefaultIcon /icon/unknown.xbm + +
    +
    + + +HeaderName +ÆÄÀϸñ·Ï À§¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§ +HeaderName filename +server configvirtual host +directory.htaccess + +Indexes + + +

    HeaderName Áö½Ã¾î´Â ÆÄÀϸñ·Ï ¾Õ¿¡ + »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. FilenameÀº »ðÀÔÇÒ + ÆÄÀϸíÀÌ´Ù.

    + + ¿¹Á¦ + HeaderName HEADER.html + + + +

    ÇöÀç HeaderName°ú ReadmeName µÑ ¸ðµÎ + FilenameÀ» Á¢±ÙÇÏ·Á´Â µð·ºÅ丮ÀÇ »ó´ë URI °æ·Î·Î + ¹Þ¾ÆµéÀδÙ. FilenameÀÌ ½½·¡½¬·Î ½ÃÀÛÇϸé DocumentRoot¿¡ »ó´ëÀûÀÎ °æ·Î·Î + ¹Þ¾ÆµéÀδÙ.

    + + ¿¹Á¦ + HeaderName /include/HEADER.html + + +

    Filename¿¡´Â major content typeÀÌ text/*ÀÎ + (¿¹¸¦ µé¾î, text/html, text/plain, + µî) ¹®¼­¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. Áï, ½ºÅ©¸³Æ®ÀÇ (Ãâ·ÂÀÌ ¾Æ´Ñ) ½ÇÁ¦ ÆÄÀÏ + typeÀ» ´ÙÀ½°ú °°ÀÌ text/html·Î ÁöÁ¤ÇÑ´Ù¸é + filenameÀ¸·Î CGI ½ºÅ©¸³Æ®¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù:

    + + + AddType text/html .cgi + + +

    Options + MultiViewsÀ» »ç¿ëÇÏ¸é ³»¿ëÇù»óÀ» ÇÑ´Ù. + filenameÀÌ (CGI ½ºÅ©¸³Æ®°¡ ¾Æ´Ñ) °íÁ¤µÈ + text/html ¹®¼­ÀÌ°í options Includes³ª + IncludesNOEXEC Áß Çϳª¸¦ »ç¿ëÇÑ´Ù¸é ÆÄÀÏÀ» + server-side includes·Î ó¸®ÇÑ´Ù. (mod_include + ¹®¼­ Âü°í)

    +
    + +

    HeaderNameÀ¸·Î ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ + (<html>, <head>, µî) HTML ¹®¼­ ½ÃÀۺκÐÀÌ Æ÷ÇÔµÇÀÖ´Ù¸é + IndexOptions + +SuppressHTMLPreambleÀ» »ç¿ëÇÏ¿© ÀÌ ºÎºÐÀ» Ãß°¡ÇÏÁö¾Ê´Â + °ÍÀÌ ÁÁ´Ù.

    +
    +
    + + +IndexIgnore +µð·ºÅ丮 ¸ñ·Ï¿¡¼­ ¼û±æ ÆÄÀϸñ·ÏÀ» Ãß°¡ÇÑ´Ù +IndexIgnore file [file] ... +server configvirtual host +directory.htaccess + +Indexes + + +

    IndexIgnore Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ °¨Ãâ ÆÄÀϸñ·ÏÀ» Ãß°¡ÇÑ´Ù. File¿¡´Â °¨Ãâ + (½©¿¡¼­ »ç¿ëÇÏ´Â) È­ÀϵåÄ«µå Ç¥ÇöÀ̳ª Àüü ÆÄÀϸíÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿©·¯ IndexIgnore Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ±âÁ¸ÀÇ + °¨Ãâ ÆÄÀϸñ·ÏÀ» ´ëüÇÏÁö¾Ê°í ¸ñ·Ï¿¡ ÁöÁ¤ÇÑ ÆÄÀϵéÀ» Ãß°¡ÇÑ´Ù. + ±âº»ÀûÀ¸·Î ¸ñ·ÏÀº .À» (ÇöÀç µð·ºÅ丮) Æ÷ÇÔÇÑ´Ù.

    + + + IndexIgnore README .htaccess *.bak *~ + +
    +
    + + +IndexOptions +µð·ºÅ丮 ¸ñ·ÏÀÇ ¿©·¯ ¼³Á¤µé +IndexOptions [+|-]option [[+|-]option] +... +server configvirtual host +directory.htaccess + +Indexes + + +

    IndexOptions Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·ÏÀ» ¼³Á¤ÇÑ´Ù. OptionÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù

    + +
    +
    DescriptionWidth=[n | *] (¾ÆÆÄÄ¡ + 2.0.23 ÀÌÈÄ)
    + +
    DescriptionWidth Å°¿öµå¸¦ »ç¿ëÇÏ¿© ¹®ÀÚ´ÜÀ§·Î + ¼³¸í¿­ÀÇ ÆøÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    -DescriptionWidth¸¦ ÁöÁ¤Çϸé (ȤÀº ¾Æ¹«°Íµµ + ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é) mod_autoindex°¡ ÃÖÀûÀÇ + ÆøÀ» °è»êÇÑ´Ù.
    + +
    DescriptionWidth=nÀº ¿­ÀÇ + ÆøÀ» n ¹ÙÀÌÆ®·Î °íÁ¤ÇÑ´Ù.
    + +
    DescriptionWidth=*Àº ¿­ÀÇ ÆøÀ» °¡Àå ±ä + ¼³¸í±ÛÀ» ´ãÀ» ¼ö Àִ¸¸Å­ ´Ã¸°´Ù.
    + +
    ¼³Á¤ÀÌ Â©¸± ¼ö ÀÖ´Â ¹®Á¦´Â AddDescription + ÀýÀ» Âü°íÇ϶ó.
    + +
    FancyIndexing
    + +
    µð·ºÅ丮ÀÇ fancy ¸ñ·ÏÀ» ¸¸µç´Ù.
    + +
    FoldersFirst + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé ÇÏÀ§µð·ºÅ丮 ¸ñ·ÏÀÌ Ç×»ó + ¸ÕÀú ³ª¿À°í, µð·ºÅ丮¿¡ ÀÖ´Â ÀÏ¹Ý ÆÄÀÏÀÌ µÚ¿¡ ³ª¿Â´Ù. + ±âº»ÀûÀ¸·Î ¸ñ·ÏÀº ÆÄÀÏ°ú ÇÏÀ§µð·ºÅ丮·Î ³ª´µ°í, µû·Î + °¢°¢ÀÇ ¼ø¼­¸¦ Á¤¸®ÇÏ¿© ÇÏÀ§µð·ºÅ丮µéÀ» ¸ÕÀú º¸ÀδÙ. + ¿¹¸¦ µé¾î, À̸§ ¿ª¼øÀ¸·Î Á¤·ÄÇÏ°í FoldersFirst¸¦ + »ç¿ëÇÑ´Ù¸é ÇÏÀ§µð·ºÅ丮 Zed°¡ ÇÏÀ§µð·ºÅ丮 + Beta ¾Õ¿¡ ³ª¿À°í, ÇÏÀ§µð·ºÅ丮 Beta´Â + ÀÏ¹Ý ÆÄÀÏ Gamma¿Í Alpha ¾Õ¿¡ + ³ª¿Â´Ù. ÀÌ ¿É¼ÇÀº FancyIndexingÀ» ÇÔ²² »ç¿ëÇÒ¶§¸¸ È¿°ú°¡ + ÀÖ´Ù.
    + +
    HTMLTable (½ÇÇèÀû, + ¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    ÀÌ ½ÇÇèÀûÀÎ FancyIndexing ¿É¼ÇÀº °£´ÜÇÑ HTML Ç¥·Î + fancy µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ ¿É¼ÇÀº ¿À·¡µÈ ºê¶ó¿ìÀú¸¦ + È¥¶õ½º·´°Ô ÇÒ ¼ö ÀÖÀ½À» ÁÖÀÇÇ϶ó. ÀÌ ¿É¼ÇÀº WinNT³ª ´Ù¸¥ + utf-8 »ç¿ë Ç÷¡Æû¿¡¼­ ÆÄÀϸíÀ̳ª ¼³¸í¹®ÀÇ Àб⠼ø¼­(¿ÞÂÊ¿¡¼­ + ¿À¸¥ÂÊ È¤Àº ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î)°¡ ´Ù¸¦¶§ Ưº°È÷ À¯¿ëÇÏ´Ù.
    + +
    IconsAreLinks
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏ¸í ¸µÅ©¿¡ ¾ÆÀÌÄÜÀ» Æ÷ÇÔÇÑ´Ù.
    + +
    IconHeight[=pixels]
    + +
    ÀÌ ¿É¼ÇÀ» IconWidth¿Í °°ÀÌ »ç¿ëÇÏ¸é ¼­¹ö´Â ÆÄÀÏ ¾ÆÀÌÄÜÀÇ + img ű׿¡ height¿Í width + ¼Ó¼ºÀ» Æ÷ÇÔÇÑ´Ù. ±×·¯¸é ºê¶ó¿ìÀú´Â ¸ðµç À̹ÌÁö¸¦ ¹ÞÁö¾ÊÀº + »óȲ¿¡¼­µµ ÆäÀÌÁö ±¸¼ºÀ» ¹Ì¸® °è»êÇÒ ¼ö ÀÖ´Ù. ¿É¼Ç¿¡ °ªÀ» + ÁÖÁö¾ÊÀ¸¸é ¾ÆÆÄÄ¡°¡ Á¦°øÇÏ´Â ¾ÆÀÌÄÜÀÇ Ç¥ÁØ ³ôÀ̸¦ »ç¿ëÇÑ´Ù.
    + +
    IconWidth[=pixels]
    + +
    ÀÌ ¿É¼ÇÀ» IconHeight¿Í °°ÀÌ »ç¿ëÇϸé + ¼­¹ö´Â ÆÄÀÏ ¾ÆÀÌÄÜÀÇ img ű׿¡ + height¿Í width ¼Ó¼ºÀ» Æ÷ÇÔÇÑ´Ù. + ±×·¯¸é ºê¶ó¿ìÀú´Â ¸ðµç À̹ÌÁö¸¦ ¹ÚÁö¾ÊÀº »óȲ¿¡¼­µµ ÆäÀÌÁö + ±¸¼ºÀ» ¹Ì¸® °è»êÇÒ ¼ö ÀÖ´Ù. ¿É¼Ç¿¡ °ªÀ» ÁÖÁö¾ÊÀ¸¸é ¾ÆÆÄÄ¡°¡ + Á¦°øÇÏ´Â ¾ÆÀÌÄÜÀÇ Ç¥ÁØ ÆøÀ» »ç¿ëÇÑ´Ù.
    + +
    IgnoreCase
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¸é ´ë¼Ò¹®ÀÚ ±¸º°ÇÏÁö¾Ê°í À̸§À» Á¤·ÄÇÑ´Ù. + ¿¹¸¦ µé¾î, À̸§À¸·Î ¿À¸§Â÷¼øÀÌ°í IgnoreCase¸¦ »ç¿ëÇϸé + ÆÄÀÏ Zeta´Â ÆÄÀÏ alfa µÚ¿¡ ³ª¿Â´Ù (ÁÖÀÇ: ÆÄÀÏ GAMMA´Â + Ç×»ó ÆÄÀÏ gamma ¾Õ¿¡ ³ª¿Â´Ù).
    + +
    IgnoreClient
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé mod_autoindex´Â + ¼ø¼­¸¦ Æ÷ÇÔÇÏ¿© Ŭ¶óÀ̾ðÆ®°¡ º¸³»´Â ¸ðµç ÁúÀǺ¯¼ö¸¦ ¹«½ÃÇÑ´Ù. + (SuppressColumnSortingÀ» °¡Á¤ÇÑ´Ù.)
    + +
    NameWidth=[n + | *]
    + +
    NameWidth Å°¿öµå´Â ¹ÙÀÌÆ®´ÜÀ§·Î ÆÄÀϸí + ¿­ÀÇ ÆøÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    -NameWidthÀ» ÁöÁ¤Çϸé (ȤÀº ¾Æ¹«°Íµµ + ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é) mod_autoindex°¡ ÃÖÀûÀÇ + ÆøÀ» °è»êÇÑ´Ù.
    + +
    NameWidth=n´Â ¿­ÀÇ ÆøÀ» n + ¹ÙÀÌÆ®·Î °íÁ¤ÇÑ´Ù.
    + +
    NameWidth=*Àº ¿­ÀÇ ÆøÀ» ÇÊ¿äÇѸ¸Å­ ´Ã¸°´Ù.
    + +
    ScanHTMLTitles
    + +
    fancy ¸ñ·Ï¿¡¼­ HTML ¹®¼­ÀÇ titleÀ» »Ì´Â´Ù. ÆÄÀÏ¿¡ + AddDescription·Î + ÁöÁ¤ÇÑ ¼³¸íÀÌ ¾ø´Ù¸é À¥¼­¹ö´Â ¹®¼­ÀÇ title + ¿ä¼Ò°ªÀ» ÀоîµéÀδÙ. ÀÌ ÀÛ¾÷Àº CPU¿Í µð½ºÅ©¸¦ ¸¹ÀÌ »ç¿ëÇÑ´Ù.
    + +
    SuppressColumnSorting
    + +
    ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¸é ¾ÆÆÄÄ¡´Â FancyIndexed µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ ¿­ À̸§À» ¼ø¼­¸¦ ¹Ù²Ù´Â ¸µÅ©·Î ¸¸µéÁö ¾Ê´Â´Ù. + º¸ÅëÀº ¿­ À̸§À» ¸µÅ©·Î ¸¸µé¾î¼­, ¿­ À̸§À» ¼±ÅÃÇÏ¸é ±× + ¿­¿¡ ÀÖ´Â °ª¼ø¼­·Î µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ¾ÆÆÄÄ¡ + 2.0.23 ÀÌÀü¿¡´Â ¼ø¼­ ¾Æ±Ô¸ÕÆ®µµ ÀÐÁö ¾Ê¾Ò´Ù. + ¾ÆÆÄÄ¡ 2.0.23¿¡¼­´Â IndexOptions + IgnoreClient¸¦ »ç¿ëÇÏ¿© ¼ø¼­ ¾Æ±Ô¸ÕÆ®¸¦ ÀÐÁö ¾Ê´Â´Ù.
    + +
    SuppressDescription
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏ ¼³¸íÀ» Æ÷ÇÔÇÏÁö ¾Ê´Â´Ù. ±âº»ÀûÀ¸·Î + ¾î¶² ÆÄÀÏ ¼³¸íµµ Á¤ÀǵÇÀÖÁö¾Ê°í, ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé 23 + ¹®ÀÚ °ø°£À» ´Ù¸¥ ¿ëµµ·Î »ç¿ëÇÑ´Ù. ÆÄÀÏ ¼³¸íÀ» ÁöÁ¤ÇÏ´Â + ¹æ¹ýÀº AddDescriptionÀ» Âü°íÇ϶ó. ¼³¸í¿­ÀÇ Å©±â¸¦ + ÁöÁ¤ÇÏ´Â DescriptionWidth + ¿É¼Çµµ Âü°íÇ϶ó.
    + +
    SuppressHTMLPreamble
    + +
    µð·ºÅ丮¿¡ HeaderName Áö½Ã¾î·Î + ÁöÁ¤ÇÑ ÆÄÀÏÀÌ ÀÖ´Â °æ¿ì ¸ðµâÀº º¸Åë Ç¥ÁØ HTML ½ÃÀۺκР+ (<html>, <head>, + et cetera) µÚ¿¡ ÆÄÀÏ ³»¿ëÀ» ÷°¡ÇÑ´Ù. ±×·¯³ª + SuppressHTMLPreamble ¿É¼ÇÀ» »ç¿ëÇϸé óÀ½ºÎÅÍ + header ÆÄÀÏ ³»¿ëÀ» Æ÷ÇÔÇÑ´Ù. ÀÌ °æ¿ì header ÆÄÀÏ¿¡´Â ÀûÀýÇÑ + HTML ¸í·ÉÀÌ ÀÖ¾î¾ß ÇÑ´Ù. header ÆÄÀÏÀÌ ¾ø´Ù¸é ÀϹÝÀûÀÎ + ½ÃÀۺκÐÀÌ ¸¸µé¾îÁø´Ù.
    + +
    SuppressIcon + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    fancy ¸ñ·Ï¿¡¼­ ¾ÆÀÌÄÜÀ» »«´Ù. SuppressIcon°ú + SuppressRules¸¦ °°ÀÌ »ç¿ëÇϸé, (FancyIndexed + ¸ñ·ÏÀÌ »ç¿ëÇÑ) pre ¾È¿¡ img¿Í + hr ¿ä¼Ò »ç¿ëÀ» ±ÝÁöÇÑ ¸¶Áö¸· Ç¥ÁØÀÎ HTML 3.2¿¡ + ¾Ë¸ÂÀº Ãâ·ÂÀÌ µÈ´Ù.
    + +
    SuppressLastModified
    + +
    fancy ¸ñ·Ï¿¡¼­ ¸¶Áö¸· ¼öÁ¤ÀÏÀ» Ç¥½ÃÇÏÁö ¾Ê´Â´Ù.
    + +
    SuppressRules + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    µð·ºÅ丮 ¸ñ·Ï¿¡¼­ ¼öÆòÁÙÀ» (hr ¿ä¼Ò) + »ç¿ëÇÏÁö ¾Ê´Â´Ù. SuppressIcon°ú + SuppressRules¸¦ °°ÀÌ »ç¿ëÇϸé, (FancyIndexed + ¸ñ·ÏÀÌ »ç¿ëÇÑ) pre ¾È¿¡ img¿Í + hr ¿ä¼Ò »ç¿ëÀ» ±ÝÁöÇÑ ¸¶Áö¸· Ç¥ÁØÀÎ HTML 3.2¿¡ + ¾Ë¸ÂÀº Ãâ·ÂÀÌ µÈ´Ù.
    + +
    SuppressSize
    + +
    fancy ¸ñ·Ï¿¡¼­ ÆÄÀÏÅ©±â¸¦ Ç¥½ÃÇÏÁö ¾Ê´Â´Ù.
    + +
    TrackModified + (¾ÆÆÄÄ¡ 2.0.23 ÀÌÈÄ)
    + +
    µð·ºÅ丮 ¸ñ·ÏÀÇ HTTP Çì´õ¿¡ Last-Modified¿Í ETag °ªÀ» + Æ÷ÇÔÇÑ´Ù. ÀÌ ¿É¼ÇÀº ¿î¿µÃ¼Á¦¿Í ÆÄÀϽýºÅÛ¿¡¼­ ÀûÀýÇÑ stat() + °á°ú¸¦ ¾òÀ» ¼ö ÀÖÀ»¶§¸¸ À¯È¿ÇÏ´Ù. À¯´Ð½º ½Ã½ºÅÛ°ú OS2ÀÇ + JFS, Win32ÀÇ NTFS¿¡¼­´Â °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î, OS2¿Í Win32ÀÇ + FATÀº ºÒ°¡´ÉÇÏ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇϸé Ŭ¶óÀ̾ðÆ®³ª ÇÁ·Ï½Ã´Â + HEAD ¿äûÀ» »ç¿ëÇÏ¿© ÆÄÀϸñ·ÏÀÇ º¯È­¸¦ ÃßÀûÇÒ + ¼ö ÀÖ´Ù. ¾î¶² ¿î¿µÃ¼Á¦´Â »õ·Î¿î ÆÄÀÏ°ú »èÁ¦ÇÑ ÆÄÀÏÀ» ¿Ã¹Ù·Î + ÃßÀûÇÏÁö¸¸, µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏÀÇ Å©±â³ª ³¯Â¥ º¯È­¸¦ + ÃßÀûÇÏÁö ¸øÇÔÀ» ÁÖÀÇÇ϶ó. ¸ðµç À¯´Ð½º Ç÷¡Æû¿¡¼­ + ±âÁ¸ ÆÄÀÏÀÇ Å©±â³ª ³¯Â¥ º¯È­½Ã Last-Modified Çì´õ°¡ + ¹Ù²îÁö¾Ê´Â´Ù. ÀÌ·± º¯È­°¡ Áß¿äÇÏ´Ù¸é ÀÌ ¿É¼ÇÀ» + »ç¿ëÇÏÁö ¸¶¶ó.
    + +
    VersionSort + (¾ÆÆÄÄ¡ 2.0a3 ÀÌÈÄ)
    + +
    VersionSort Å°¿öµå´Â ¹öÀü ¹øÈ£¸¦ Æ÷ÇÔÇÑ + ÆÄÀϸíÀ» ÀÚ¿¬½º·´°Ô Á¤·ÄÇÑ´Ù. ¹®ÀÚ ºÎºÐÀº Á¤»óÀûÀÎ ¼ø¼­¸¦ + Á¤·ÄÇÏÁö¸¸, ÆÄÀÏ°ú ¼³¸í¿¡ ÀÖ´Â ¼ýÀÚ ºÎºÐÀº ¼ýÀÚ°ªÀ¸·Î + ºñ±³ÇÑ´Ù. + + ¿¹Á¦: + foo-1.7
    + foo-1.7.2
    + foo-1.7.12
    + foo-1.8.2
    + foo-1.8.2a
    + foo-1.12 +
    + +

    ¼ö°¡ 0À¸·Î ½ÃÀÛÇϸé, ±× ¼ö¸¦ ºÐ¼ö·Î Ãë±ÞÇÑ´Ù:

    + + + foo-1.001
    + foo-1.002
    + foo-1.030
    + foo-1.04 +
    +
    + +
    XHTML + (¾ÆÆÄÄ¡ 2.0.49 ÀÌÈÄ)
    + +
    XHTML Å°¿öµå¸¦ »ç¿ëÇϸé + mod_autoindex´Â HTML 3.2 ´ë½Å XHTML 1.0 + Äڵ带 »ý¼ºÇÑ´Ù.
    +
    + + +
    Á¡ÁøÀûÀÎ IndexOptions
    +
    +

    ¾ÆÆÄÄ¡ 1.3.3¿¡¼­ IndexOptions + Áö½Ã¾î 󸮹æ½ÄÀÌ Å©°Ô º¯È­µÇ¾ú´Ù. Ưº°È÷:

    + +
      +
    • ÀÌÁ¦ ÇÑ µð·ºÅ丮¿¡ ´ëÇÑ ¿©·¯ + IndexOptions Áö½Ã¾îµéÀ» ¼­·Î °áÇÕÇÑ´Ù. + ´ÙÀ½ÀÇ °á°ú´Â: + + + <Directory /foo> + + IndexOptions HTMLTable
      + IndexOptions SuppressColumnsorting +
      + </Directory> +
      + +

      ´ÙÀ½°ú °°´Ù

      + + + IndexOptions HTMLTable SuppressColumnsorting + +
    • + +
    • (¿¹¸¦ µé¾î, Å°¿öµå ¾Õ¿¡ +³ª + -¸¦ ºÙÀÌ´Â) Á¡ÁøÀûÀÎ ¹®¹ýÀÌ Ãß°¡µÇ¾ú´Ù.
    • +
    + +

    Å°¿öµå ¾Õ¿¡ '+'³ª '-'°¡ ºÙÀ»¶§¸¶´Ù ÇØ´ç Å°¿öµå°¡ ÇöÀç + (»óÀ§ µð·ºÅ丮¿¡¼­ »ó¼ÓµÇ¾úÀ») IndexOptions + ¼³Á¤¿¡ ¹Ý¿µµÈ´Ù. ±×·¯³ª ¾Õ¿¡ ¾Æ¹«°Íµµ ¾ø´Â Å°¿öµå¸¦ ¸¸³ª¸é + ¾ÆÁ÷±îÁö »ó¼ÓµÇ°Å³ª Á¡ÁøÀûÀ¸·Î º¯°æµÈ ¼³Á¤À» ¸ðµÎ Áö¿î´Ù. + ´ÙÀ½ ¿¹Á¦¸¦ »ìÆ캸ÀÚ:

    + + + IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
    + IndexOptions +SuppressSize +
    + +

    ¾Õ¿¡ ¾Æ¹«°Íµµ ¾ø´Â FancyIndexingÀÌ ÀÌÀüÀÇ + Á¡ÁøÀûÀÎ ¼³Á¤À» Áö¿ö¹ö·ÈÁö¸¸ ¼³Á¤ÀÌ ´Ù½Ã Ãß°¡µÇ¿© °á°ú´Â + IndexOptions FancyIndexing +SuppressSize¿Í °°´Ù.

    + +

    ƯÁ¤ µð·ºÅ丮¿¡ ´ëÇØ ¹«Á¶°ÇÀûÀÎ + IndexOptions¸¦ ¼³Á¤ÇÏ·Á¸é Å°¿öµå + ¾Õ¿¡ +³ª -¸¦ »ç¿ëÇÏÁö¸»°í + »ó¼ÓµÈ ¼³Á¤À» Áö¿î´Ù.

    +
    +
    +
    +
    + + +IndexOrderDefault +µð·ºÅ丮 ¸ñ·ÏÀÇ ±âº» ¼ø¼­¸¦ ¼³Á¤ÇÑ´Ù +IndexOrderDefault Ascending|Descending +Name|Date|Size|Description +IndexOrderDefault Ascending Name +server configvirtual host +directory.htaccess + +Indexes + + +

    IndexOrderDefault Áö½Ã¾î´Â FancyIndexing + ¸ñ·Ï ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î fancyindexed µð·ºÅ丮 + ¸ñ·ÏÀº ÆÄÀÏ¸í ¿À¸§Â÷¼øÀÌ´Ù. IndexOrderDefault´Â + ÀÌ Ãʱ⠼ø¼­¸¦ º¯°æÇÒ ¼ö ÀÖ´Ù.

    + +

    IndexOrderDefault´Â µÎ ¾Æ±Ô¸ÕÆ®¸¦ + ¹Þ´Â´Ù. ù¹ø°´Â ¼ø¼­ÀÇ ¹æÇâÀ» Áö½ÃÇÏ´Â Ascending + (¿À¸¥Â÷¼ø) À̳ª Descending (³»¸²Â÷¼ø) Áß Çϳª´Ù. + µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ÀÏÂ÷ ¼ø¼­¸¦ ³ªÅ¸³»´Â Å°¿öµå Name, + Date, Size, Description + Áß Çϳª´Ù. ÀÌÂ÷ ¼ø¼­´Â Ç×»ó ÆÄÀÏ¸í ¿À¸§Â÷¼øÀÌ´Ù.

    + +

    ÀÌ Áö½Ã¾î¿Í SuppressColumnSorting ¸ñ·Ï ¿É¼ÇÀ» °°ÀÌ »ç¿ëÇϸé + ƯÁ¤ ¼ø¼­·Î¸¸ µð·ºÅ丮 ¸ñ·ÏÀ» ¸¸µç´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â + ´Ù¸¥ ¼ø¼­·Î µð·ºÅ丮 ¸ñ·ÏÀ» ¿äûÇÏÁö ¸øÇÑ´Ù.

    +
    +
    + + +IndexStyleSheet +µð·ºÅ丮 ¸ñ·Ï¿¡ CSS ½ºÅ¸ÀϽ¬Æ®¸¦ Ãß°¡ÇÑ´Ù +IndexStyleSheet url-path +server configvirtual host +directory.htaccess + +Indexes + + +

    IndexStyleSheet Áö½Ã¾î´Â µð·ºÅ丮 + ¸ñ·Ï¿¡¼­ CSS·Î »ç¿ëÇÒ ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. +

    + + Example + IndexStyleSheet "/css/style.css" + +
    +
    + + +ReadmeName +ÆÄÀϸñ·Ï ¸¶Áö¸·¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§ +ReadmeName filename +server configvirtual host +directory.htaccess + +Indexes + + +

    ReadmeName Áö½Ã¾î´Â ÆÄÀϸñ·Ï ³¡¿¡ + »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. FilenameÀº Æ÷ÇÔÇÒ + ÆÄÀϸíÀÌ°í, ¸ñ·ÏÀ» ¸¸µé·Á´Â À§Ä¡ÀÇ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ. + FilenameÀÌ ½½·¡½¬·Î ½ÃÀÛÇϸé DocumentRoot¿¡ »ó´ë°æ·Î·Î ¹Þ¾ÆµéÀδÙ. +

    + + ¿¹Á¦ + ReadmeName FOOTER.html + + + ¿¹Á¦ 2 + ReadmeName /include/FOOTER.html + + +

    ÀÌ µ¿ÀÛÀ» ÀÚ¼¼È÷ ¼³¸íÇÑ HeaderNameµµ Âü°íÇ϶ó.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_autoindex.xml.meta b/trunk/docs/manual/mod/mod_autoindex.xml.meta new file mode 100644 index 0000000000..df5f14e406 --- /dev/null +++ b/trunk/docs/manual/mod/mod_autoindex.xml.meta @@ -0,0 +1,13 @@ + + + + mod_autoindex + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_cache.html b/trunk/docs/manual/mod/mod_cache.html new file mode 100644 index 0000000000..cba0697e27 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.html @@ -0,0 +1,11 @@ +URI: mod_cache.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_cache.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_cache.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_cache.html.en b/trunk/docs/manual/mod/mod_cache.html.en new file mode 100644 index 0000000000..cd7e3ff10f --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.html.en @@ -0,0 +1,435 @@ + + + +mod_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Content cache keyed to URIs.
    Status:Extension
    Module Identifier:cache_module
    Source File:mod_cache.c
    +

    Summary

    + +

    mod_cache implements an RFC 2616 compliant HTTP + content cache that can be used to cache either local or proxied content. + mod_cache requires the services of one or more storage + management modules. Two storage management modules are included in + the base Apache distribution:

    +
    +
    mod_disk_cache
    +
    implements a disk based storage manager.
    + +
    mod_mem_cache
    +
    implements a memory based storage manager. + mod_mem_cache can be configured to operate in two + modes: caching open file descriptors or caching objects in heap storage. + mod_mem_cache can be used to cache locally generated content + or to cache backend server content for mod_proxy when + configured using ProxyPass + (aka reverse proxy)
    +
    + +

    Content is stored in and retrieved from the cache using URI based keys. Content with + access protection is not cached.

    +
    + +
    top
    +
    top
    +
    +

    Sample Configuration

    +

    Sample httpd.conf

    + #
    + # Sample Cache Configuration
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + # If you want to use mod_disk_cache instead of mod_mem_cache, + # uncomment the line above and comment out the LoadModule line below. + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +

    +
    +
    top
    +

    CacheDefaultExpire Directive

    + + + + + + + +
    Description:The default duration to cache a document when no expiry date is specified.
    Syntax:CacheDefaultExpire seconds
    Default:CacheDefaultExpire 3600 (one hour)
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    The CacheDefaultExpire directive specifies a default time, + in seconds, to cache a document if neither an expiry date nor last-modified date are provided + with the document. The value specified with the CacheMaxExpire + directive does not override this setting.

    + +

    + CacheDefaultExpire 86400 +

    + +
    +
    top
    +

    CacheDisable Directive

    + + + + + + +
    Description:Disable caching of specified URLs
    Syntax:CacheDisable url-string
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    The CacheDisable directive instructs + mod_cache to not cache urls at or below + url-string.

    + +

    Example

    + CacheDisable /local_files +

    + +
    +
    top
    +

    CacheEnable Directive

    + + + + + + +
    Description:Enable caching of specified URLs using a specified storage +manager
    Syntax:CacheEnable cache_type url-string
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    The CacheEnable directive instructs + mod_cache to cache urls at or below + url-string. The cache storage manager is specified with the + cache_type argument. cache_type mem + instructs mod_cache to use the memory based storage + manager implemented by mod_mem_cache. + cache_type disk instructs + mod_cache to use the disk based storage manager + implemented by mod_disk_cache. + cache_type fd instructs + mod_cache to use the file descriptor cache implemented + by mod_mem_cache.

    +

    In the event that the URL space overlaps between different + CacheEnable directives (as in the example below), + each possible storage manager will be run until the first one that + actually processes the request. The order in which the storage managers are + run is determined by the order of the CacheEnable + directives in the configuration file.

    + +

    + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +

    + +
    +
    top
    +

    CacheIgnoreCacheControl Directive

    + + + + + + + +
    Description:Ignore request to not serve cached content to client
    Syntax:CacheIgnoreCacheControl On|Off
    Default:CacheIgnoreCacheControl Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    Ordinarily, requests containing a Cache-Control: no-cache or + Pragma: no-cache header value will not be served from the cache. The + CacheIgnoreCacheControl directive allows this + behavior to be overridden. CacheIgnoreCacheControl + On tells the server to attempt to serve the resource from the cache even + if the request contains no-cache header values. Resources requiring + authorization will never be cached.

    + +

    + CacheIgnoreCacheControl On +

    + +

    Warning:

    + This directive will allow serving from the cache even if the client has + requested that the document not be served from the cache. This might + result in stale content being served. +
    + +

    See also

    + +
    +
    top
    +

    CacheIgnoreHeaders Directive

    + + + + + + + +
    Description:Do not store the given HTTP header(s) in the cache. +
    Syntax:CacheIgnoreHeaders header-string [header-string] ...
    Default:CacheIgnoreHeaders None
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    According to RFC 2616, hop-by-hop HTTP headers are not stored in + the cache. The following HTTP headers are hop-by-hop headers and thus + do not get stored in the cache in any case regardless of the + setting of CacheIgnoreHeaders:

    + +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders specifies additional HTTP + headers that should not to be stored in the cache. For example, it makes + sense in some cases to prevent cookies from being stored in the cache.

    + +

    CacheIgnoreHeaders takes a space separated list + of HTTP headers that should not be stored in the cache. If only hop-by-hop + headers not should be stored in the cache (the RFC 2616 compliant + behaviour), CacheIgnoreHeaders can be set to + None.

    + +

    Example 1

    + CacheIgnoreHeaders Set-Cookie +

    + +

    Example 2

    + CacheIgnoreHeaders None +

    + +

    Warning:

    + If headers like Expires which are needed for proper cache + management are not stored due to a + CacheIgnoreHeaders setting, the behaviour of + mod_cache is undefined. +
    + +
    +
    top
    +

    CacheIgnoreNoLastMod Directive

    + + + + + + + +
    Description:Ignore the fact that a response has no Last Modified +header.
    Syntax:CacheIgnoreNoLastMod On|Off
    Default:CacheIgnoreNoLastMod Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    Ordinarily, documents without a last-modified date are not cached. + Under some circumstances the last-modified date is removed (during + mod_include processing for example) or not provided + at all. The CacheIgnoreNoLastMod directive + provides a way to specify that documents without last-modified dates + should be considered for caching, even without a last-modified date. + If neither a last-modified date nor an expiry date are provided with + the document then the value specified by the + CacheDefaultExpire directive will be used to + generate an expiration date.

    + +

    + CacheIgnoreNoLastMod On +

    + +
    +
    top
    +

    CacheLastModifiedFactor Directive

    + + + + + + + +
    Description:The factor used to compute an expiry date based on the +LastModified date.
    Syntax:CacheLastModifiedFactor float
    Default:CacheLastModifiedFactor 0.1
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    In the event that a document does not provide an expiry date but does + provide a last-modified date, an expiry date can be calculated based on + the time since the document was last modified. The + CacheLastModifiedFactor directive specifies a + factor to be used in the generation of this expiry date + according to the following formula: + + expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period + + For example, if the document was last modified 10 hours ago, and + factor is 0.1 then the expiry-period will be set to + 10*0.1 = 1 hour. If the current time was 3:00pm then the computed + expiry-date would be 3:00pm + 1hour = 4:00pm. + + If the expiry-period would be longer than that set by + CacheMaxExpire, then the latter takes + precedence.

    + +

    + CacheLastModifiedFactor 0.5 +

    + +
    +
    top
    +

    CacheMaxExpire Directive

    + + + + + + + +
    Description:The maximum time in seconds to cache a document
    Syntax:CacheMaxExpire seconds
    Default:CacheMaxExpire 86400 (one day)
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    The CacheMaxExpire directive specifies the maximum number of + seconds for which cachable HTTP documents will be retained without checking the origin + server. Thus, documents will be out of date at most this number of seconds. This maximum + value is enforced even if an expiry date was supplied with the document.

    + +

    + CacheMaxExpire 604800 +

    + +
    +
    top
    +

    CacheStoreNoStore Directive

    + + + + + + + +
    Description:Attempt to cache requests or responses that have been marked as no-store.
    Syntax:CacheStoreNoStore On|Off
    Default:CacheStoreNoStore Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    Ordinarily, requests or responses with Cache-Control: no-store header + values will not be stored in the cache. The + CacheStoreNoCache directive allows this + behavior to be overridden. CacheStoreNoCache On + tells the server to attempt to cache the resource even if it contains + no-store header values. Resources requiring authorization will + never be cached.

    + +

    + CacheStoreNoStore On +

    + +

    Warning:

    + As described in RFC 2616, the no-store directive is intended to + "prevent the inadvertent release or retention of sensitive information + (for example, on backup tapes)." Enabling this option could store + sensitive information in the cache. You are hereby warned. +
    + +

    See also

    + +
    +
    top
    +

    CacheStorePrivate Directive

    + + + + + + + +
    Description:Attempt to cache responses that the server has marked as private
    Syntax:CacheStorePrivate On|Off
    Default:CacheStorePrivate Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_cache
    +

    Ordinarily, responses with Cache-Control: private header values will not + be stored in the cache. The CacheStorePrivate + directive allows this behavior to be overridden. + CacheStorePrivate On + tells the server to attempt to cache the resource even if it contains + private header values. Resources requiring authorization will + never be cached.

    + +

    + CacheStorePrivate On +

    + +

    Warning:

    + This directive will allow caching even if the upstream server has + requested that the resource not be cached. This directive is only + ideal for a 'private' cache. +
    + +

    See also

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cache.html.ja.euc-jp b/trunk/docs/manual/mod/mod_cache.html.ja.euc-jp new file mode 100644 index 0000000000..84298bdbb8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.html.ja.euc-jp @@ -0,0 +1,441 @@ + + + +mod_cache - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:cache_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_cache.c
    +

    ³µÍ×

    + +
    + ¤³¤ì¤Ï¼Â¸³Åª¤Ê¥â¥¸¥å¡¼¥ë¤Ç¤¹¡£Ê¸½ñ¤â¤Þ¤À³«È¯Ãæ¤Ç¤¹... +
    + +

    mod_cache ¤Ï¥í¡¼¥«¥ë¤Î¥³¥ó¥Æ¥ó¥Ä¤ä¥×¥í¥­¥·¤µ¤ì¤¿ + ¥³¥ó¥Æ¥ó¥Ä¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë RFC 2616 ½àµò¤Î + HTTP ¥³¥ó¥Æ¥ó¥Ä¥­¥ã¥Ã¥·¥å¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£mod_cache + ¤ÎÆ°ºî¤Ë¤Ï¥¹¥È¥ì¡¼¥¸¤ò´ÉÍý¤¹¤ë¥â¥¸¥å¡¼¥ë¤¬É¬ÍפǤ¹¡£É¸½à + Apache ÇÛÉۤˤÏÆó¤Ä¥¹¥È¥ì¡¼¥¸´ÉÍý¥â¥¸¥å¡¼¥ë¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹:

    + +
    +
    mod_disk_cache
    +
    ¥Ç¥£¥¹¥¯¤ò»ÈÍѤ·¤¿¥¹¥È¥ì¡¼¥¸´ÉÍýµ¡¹½¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£
    + +
    mod_mem_cache
    +
    ¥á¥â¥ê¤ò»ÈÍѤ·¤¿¥¹¥È¥ì¡¼¥¸´ÉÍýµ¡¹½¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£ + mod_mem_cache ¤Ï¼¡¤ÎÆó¤Ä¤Î¥â¡¼¥É¤Î¤É¤Á¤é¤«¤ÇÆ°ºî¤¹¤ë + ¤è¤¦¤ËÀßÄê¤Ç¤­¤Þ¤¹: ¥ª¡¼¥×¥ó¤µ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¥â¡¼¥É¤«¡¢ + ¥Ò¡¼¥×¾å¤Ç¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î¼«ÂΤò¥­¥ã¥Ã¥·¥å¤ò¤¹¤ë¥â¡¼¥É¤Ç¤¹¡£ + mod_mem_cache ¤Ï¥í¡¼¥«¥ë¤ÇÀ¸À®¤µ¤ì¤ë¥³¥ó¥Æ¥ó¥Ä¤ä¡¢ + mod_proxy ¤¬ + ProxyPass ¤ò»È¤Ã¤ÆÀßÄꤵ¤ì¤Æ¤¤¤ë + ¤È¤­¤Î (¤Ä¤Þ¤ê¥ê¥Ð¡¼¥¹¥×¥í¥­¥· ¤Ç¤Î) ¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤Î + ¥³¥ó¥Æ¥ó¥Ä¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¤Î¤Ë»È¤¨¤Þ¤¹¡£
    +
    + +

    ¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å¤Ø¤ÎÊݸ¤È¼èÆÀ¤Ï URI ¤Ë´ð¤Å¤¤¤¿¥­¡¼¤¬»È¤ï¤ì¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹Êݸî¤Î¤«¤±¤é¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥Ä¤Ï¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    top
    +
    +

    ¥µ¥ó¥×¥ëÀßÄê

    +

    Sample httpd.conf

    + #
    + # Sample Cache Configuration
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + # If you want to use mod_disk_cache instead of mod_mem_cache, + # uncomment the line above and comment out the LoadModule line below. + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +

    +
    +
    top
    +

    CacheDefaultExpire ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:´üÆü¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ë¥É¥­¥å¥á¥ó¥È¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¥Ç¥Õ¥©¥ë¥È¤Î´ü´Ö
    ¹½Ê¸:CacheDefaultExpire seconds
    ¥Ç¥Õ¥©¥ë¥È:CacheDefaultExpire 3600 (1»þ´Ö)
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    CacheDefaultExpire ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤Ë + Í­¸ú´ü¸Â (expiry) ¤äºÇ½ª½¤Àµ»þ¹ï (last-modified) ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Î + ¥Ç¥Õ¥©¥ë¥È¤Î»þ´Ö¤ò»ØÄꤷ¤Þ¤¹¡£CacheMaxExpire + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿ÃͤϤ³¤ÎÀßÄê¤ò¾å½ñ¤­¤·¤Þ¤»¤ó¡£

    + +

    + CacheDefaultExpire 86400 +

    + +
    +
    top
    +

    CacheDisable ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î URL ¤ò¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤
    ¹½Ê¸:CacheDisable url-string
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    CacheDisable ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + mod_cache ¥â¥¸¥å¡¼¥ë¤¬ url-string °Ê²¼¤Î + URL ¤ò¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    Îã

    + CacheDisable /local_files +

    + +
    +
    top
    +

    CacheEnable ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:»ØÄꤷ¤¿¥¹¥È¥ì¡¼¥¸´ÉÍýÊý¼°¤ò»È¤Ã¤Æ¤Î¥­¥ã¥Ã¥·¥å¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:CacheEnable cache_type url-string
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    CacheEnable ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç mod_cache + ¥â¥¸¥å¡¼¥ë¤¬ url-string °Ê²¼¤Î URL ¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¥­¥ã¥Ã¥·¥å¥¹¥È¥ì¡¼¥¸´ÉÍýÊý¼°¤Ï cache_type °ú¿ô¤Ç»ØÄꤷ¤Þ¤¹¡£ + cache_type mem ¤Ç¡¢ + mod_mem_cache ¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¥á¥â¥ê¤ò»È¤Ã¤¿¥¹¥È¥ì¡¼¥¸ + ´ÉÍýÊý¼°¤ò»È¤¦¤è¤¦¤Ë mod_cache ¤Ë»Ø¼¨¤·¤Þ¤¹¡£ + cache_type disk ¤Ç¡¢ + mod_disk_cache ¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥¹¥¯¤ò»È¤Ã¤¿¥¹¥È¥ì¡¼¥¸ + ´ÉÍý¤ò»È¤¦¤è¤¦¤Ë mod_cache ¤Ë»Ø¼¨¤·¤Þ¤¹¡£ + cache_type fd ¤Ï mod_cache ¤Ë + mod_mem_cache ¤Ë¤è¤ê¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î + ¥­¥ã¥Ã¥·¥å¤ò»È¤¦¤è¤¦¤Ë»Ø¼¨¤·¤Þ¤¹¡£

    + +

    (²¼¤ÎÎã¤Î¤è¤¦¤Ë) CacheEnable ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + URL ¶õ´Ö¤¬½ÅÊ£¤·¤Æ¤¤¤ë¤È¤­¤Ï¡¢³ºÅö¤¹¤ë¥¹¥È¥ì¡¼¥¸Êý¼°¤ò½ç¤Ë»î¤·¤Æ¡¢ + ¼ÂºÝ¤Ë¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤¬¤Ç¤­¤ë¤È¡¢¤½¤ÎÊý¼°¤Ç½èÍý¤·¤Þ¤¹¡£ + ¥¹¥È¥ì¡¼¥¸´ÉÍýÊý¼°¤¬¼Â¹Ô¤µ¤ì¤ë½çÈÖ¤ÏÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î + CacheEnable ¤Î½çÈ֤ˤè¤ê·èÄꤵ¤ì¤Þ¤¹¡£

    + +

    + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +

    + +
    +
    top
    +

    CacheIgnoreCacheControl ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤µ¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥Ä¤òÊÖ¤µ¤Ê¤¤¤è¤¦¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é +¥ê¥¯¥¨¥¹¥È¤µ¤ì¤Æ¤â̵»ë¤¹¤ë
    ¹½Ê¸:CacheIgnoreCacheControl On|Off
    ¥Ç¥Õ¥©¥ë¥È:CacheIgnoreCacheControl Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    Cache-Control: no-cache ¥Ø¥Ã¥À¤ä Pragma: no-store ¥Ø¥Ã¥À¤Î¤¢¤ë¥ê¥¯¥¨¥¹¥È¤Ë + ÂФ·¤Æ¤Ï¡¢Ä̾省¥ã¥Ã¥·¥å¤ò»È¤¤¤Þ¤»¤ó¡£CacheIgnoreCacheControl + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È¡¢¤³¤ÎÆ°ºî¤ò¾å½ñ¤­¤Ç¤­¤Þ¤¹¡£ + CacheIgnoreCacheControl On ¤È¤¹¤ë¤È¡¢ + ¥ê¥¯¥¨¥¹¥È¤Ë no-cache ¤È¤¤¤¦Ãͤ¬¤¢¤Ã¤Æ¤â¡¢¥­¥ã¥Ã¥·¥å¤ò»È¤Ã¤Æ¥É¥­¥å¥á¥ó¥È¤ò + ÊÖ¤¹¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£Ç§¾Ú¤òɬÍפȤ¹¤ë¥É¥­¥å¥á¥ó¥È¤Ï·è¤·¤Æ + ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    + +

    + CacheIgnoreCacheControl On +

    + +

    ·Ù¹ð

    + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È¡¢¥É¥­¥å¥á¥ó¥È¼èÆÀ»þ¤Ë¥­¥ã¥Ã¥·¥å¤ò»È¤ï¤Ê¤¤¤è¤¦¤Ë + ¥¯¥é¥¤¥¢¥ó¥È¤¬¥ê¥¯¥¨¥¹¥È¤·¤Æ¤¤¤ë¤Ë¤â¤«¤«¤ï¤é¤º¡¢¥­¥ã¥Ã¥·¥å¤ò + »È¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤Î·ë²Ì¡¢ + ¸Å¤¤¥³¥ó¥Æ¥ó¥Ä¤¬Á÷¤é¤ì³¤±¤ë¤³¤È¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤«¤â¤·¤ì¤Þ¤»¤ó¡£ +
    + +

    »²¾È

    + +
    +
    top
    +

    CacheIgnoreHeaders ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»ØÄꤵ¤ì¤¿ HTTP ¥Ø¥Ã¥À¤ò¥­¥ã¥Ã¥·¥å¤ËÊݸ¤·¤Ê¤¤¡£ +
    ¹½Ê¸:CacheIgnoreHeaders header-string [header-string] ...
    ¥Ç¥Õ¥©¥ë¥È:CacheIgnoreHeaders None
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    RFC 2616 ¤Ë¤è¤ë¤È¡¢hop-by-hop HTTP ¥Ø¥Ã¥À¤Ï¥­¥ã¥Ã¥·¥å¤Ë¤ÏÊݴɤµ¤ì¤Þ¤»¤ó¡£ + °Ê²¼¤Î¥Ø¥Ã¥À¤Ï hop-by-hop ¥Ø¥Ã¥À¤Ë³ºÅö¤·¤Þ¤¹¤Î¤Ç¡¢ + CacheIgnoreHeaders + ¤ÎÀßÄê¤Ë´Ø·¸¤Ê¤¯¥­¥ã¥Ã¥·¥å¤Ë¤ÏÊݴɤµ¤ì¤Þ¤»¤ó:

    +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders ¤Ç + ¥­¥ã¥Ã¥·¥å¤ËÊݴɤ·¤Ê¤¤ÄɲäΠHTTP ¥Ø¥Ã¥À¤ò»ØÄꤷ¤Þ¤¹¡£ + Î㤨¤Ð¡¢¥¯¥Ã¥­¡¼¤ò¥­¥ã¥Ã¥·¥å¤ËÊݴɤ·¤Ê¤¤¤è¤¦¤Ë¤·¤¿Êý¤¬¤è¤¤¾ì¹ç¤â + ¤¢¤ë¤Ç¤·¤ç¤¦¡£

    + +

    CacheIgnoreHeaders ¤Î°ú¿ô¤Ï¡¢ + ¥­¥ã¥Ã¥·¥å¤ËÊݴɤ·¤Ê¤¤ HTTP ¥Ø¥Ã¥À¤ò¶õÇò¶èÀÚ¤ê¤Ë¤·¤¿¥ê¥¹¥È·Á¼°¤Ç¤¹¡£ + ¥­¥ã¥Ã¥·¥å¤ËÊݴɤ·¤Ê¤¤¥Ø¥Ã¥À¤¬ hop-by-hop ¥Ø¥Ã¥À¤À¤±¤Î¾ì¹ç + (RFC 2616 ½àµò¤ÎÆ°ºî¤Î¤È¤­) ¤Ï¡¢ + CacheIgnoreHeaders ¤ò None + ¤ËÀßÄê¤Ç¤­¤Þ¤¹¡£

    + +

    Îã 1

    + CacheIgnoreHeaders Set-Cookie +

    + +

    Îã 2

    + CacheIgnoreHeaders None +

    + +

    ·Ù¹ð:

    + Expires ¤Î¤è¤¦¤ÊŬÀڤΥ­¥ã¥Ã¥·¥å´ÉÍý¤Î¤¿¤á¤ËɬÍ×¤Ê + ¥Ø¥Ã¥À¤¬ CacheIgnoreHeaders ¤ÎÀßÄê¤Ë¤è¤ê + Êݴɤµ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢mod_cache ¤ÎÆ°ºî¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ +
    + +
    +
    top
    +

    CacheIgnoreNoLastMod ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:±þÅú¤Ë Last Modified ¤¬Ìµ¤¯¤Æ¤âµ¤¤Ë¤·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë
    ¹½Ê¸:CacheIgnoreNoLastMod On|Off
    ¥Ç¥Õ¥©¥ë¥È:CacheIgnoreNoLastMod Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    Ä̾Last-Modified ¤Ë¤è¤ëºÇ½ª½¤Àµ»þ¹ï¤Î̵¤¤¥É¥­¥å¥á¥ó¥È¤Ï¥­¥ã¥Ã¥·¥å + ¤µ¤ì¤Þ¤»¤ó¡£(Î㤨¤Ð mod_include ¤Ë¤è¤ë½èÍý¤Î¤È¤­¤Ê¤É¤Ë) + Last-Modified »þ¹ï¤¬¾Ãµî¤µ¤ì¤¿¤ê¡¢¤½¤â¤½¤âºÇ½é¤«¤éÄ󶡤µ¤ì¤Æ¤¤¤Ê¤¤ + ¾õ¶·¤¬¤¢¤ê¤Þ¤¹¡£CacheIgnoreNoLastMod + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È¡¢Last-Modified Æü»þ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤ + ¥É¥­¥å¥á¥ó¥È¤Ç¤â¥­¥ã¥Ã¥·¥å¤¹¤ë¤è¤¦¤Ë»ØÄê¤Ç¤­¤Þ¤¹¡£¥É¥­¥å¥á¥ó¥È¤Ë + ºÇ½ª½¤Àµ»þ¹ï (Last-Modified) Í­¸ú´ü¸Â (expiry) ¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢Í­¸ú´ü¸Â¤Î + À¸À®¤Ë CacheDefaultExpire ¤¬»È¤ï¤ì¤Þ¤¹¡£

    + +

    + CacheIgnoreNoLastMod On +

    + +
    +
    top
    +

    CacheLastModifiedFactor ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:LastModified ¤ÎÆüÉդ˴ð¤Å¤¤¤ÆÍ­¸ú´ü¸Â (expiry) +¤ò·×»»¤¹¤ë¤¿¤á¤Î½Å¤ß¤ò»ØÄꤹ¤ë +
    ¹½Ê¸:CacheLastModifiedFactor float
    ¥Ç¥Õ¥©¥ë¥È:CacheLastModifiedFactor 0.1
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    ¥É¥­¥å¥á¥ó¥È¤Ë Last-Modified ¤ÎÆüÉÕ¤¬Ìµ¤¤¤±¤ì¤É¤âÍ­¸ú´ü¸Â (expiry) + ¤ÎÆüÉÕ¤¬¤¢¤ë¤È¤¤¤¦¤È¤­¤Ë¡¢Í­¸ú´ü¸Â¤òºÇ½ª½¤Àµ»þ¹ï¤«¤é¤Î·Ð²á»þ´Ö¤È¤·¤Æ + ·×»»¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£Í­¸ú´ü¸Â¤ò¼¡¤Î·×»»¼°¤Ë½¾¤Ã¤ÆÀ¸À®¤¹¤ë¤Î¤Ç¤¹¤¬¡¢ + ¤½¤Î¤È¤­¤Ë»È¤ï¤ì¤ë factor ¤ò + CacheLastModifiedFactor ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤷ¤Þ¤¹¡£ +

    + +

    expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period

    + +

    Î㤨¤Ð¡¢¥É¥­¥å¥á¥ó¥È¤¬ 10 »þ´ÖÁ°¤ËºÇ¸å¤Ë½¤Àµ¤µ¤ì¤Æ¤¤¤Æ¡¢ + factor ¤¬ 0.1 ¤Ç¤¢¤ì¤Ð¡¢´üÆü¤Ï 10*0.1 = 1 »þ´Ö¤Ë + ÀßÄꤵ¤ì¤Þ¤¹¡£¸½ºß»þ¹ï¤¬ 3:00pm ¤Ç¤¢¤ì¤Ð¡¢·×»»¤µ¤ì¤¿´üÆü¤Ï + 3:00pm + 1hour = 4:00pm ¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ´üÆü¤¬ CacheMaxExpire ¤ÇÀßÄꤵ¤ì¤Æ¤¤¤ëÃÍ + ¤è¤êÂ礭¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢CacheMaxExpire + ¤ÎÀßÄêÃͤ¬Í¥À褵¤ì¤Þ¤¹¡£

    + +

    + CacheLastModifiedFactor 0.5 +

    + +
    +
    top
    +

    CacheMaxExpire ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥É¥­¥å¥á¥ó¥È¤ò¥­¥ã¥Ã¥·¥å¤¹¤ëºÇÂç»þ´Ö¤òÉÿô¤Ç¸½¤·¤¿¤â¤Î
    ¹½Ê¸:CacheMaxExpire seconds
    ¥Ç¥Õ¥©¥ë¥È:CacheMaxExpire 86400 (°ìÆü)
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    CacheMaxExpire ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥­¥ã¥Ã¥·¥å¤¹¤ë HTTP ¥É¥­¥å¥á¥ó¥È¤ò¡¢¸µ¤Î¥µ¡¼¥Ð¤ËÌ䤤¹ç¤ï¤»¤Ê¤¤¤Þ¤ÞºÇÂ粿Éà + ÊÝ»ý¤·¤Æ¤â¤è¤¤¤«¤ò»ØÄꤷ¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢¥É¥­¥å¥á¥ó¥È¤ÏºÇÂç¤Ç¤³¤ÎÉÿô´Ö¤Ö¤ó¸Å¤¯ + ¤Ê¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ÎºÇÂçÃͤϡ¢(ÌõÃí:¥ì¥¹¥Ý¥ó¥¹Ãæ¤Ç)¥É¥­¥å¥á¥ó¥È¤È¶¦¤Ë + ¥É¥­¥å¥á¥ó¥È¤Î´üÆü¤¬Ä󶡤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤âŬÍѤµ¤ì¤Þ¤¹¡£

    + +

    + CacheMaxExpire 604800 +

    + +
    +
    top
    +

    CacheStoreNoStore ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:no-store ¤È»ØÄꤵ¤ì¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Î¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¡£
    ¹½Ê¸:CacheStoreNoStore On|Off
    ¥Ç¥Õ¥©¥ë¥È:CacheStoreNoStore Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    Ä̾ï Cache-Control: no-store ¥Ø¥Ã¥À¤Î¤Ä¤¤¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Ï + ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£CacheStoreNoCache + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤³¤ÎµóÆ°¤ò¾å½ñ¤­¤Ç¤­¤Þ¤¹¡£ + CacheStoreNoCache On ¤Ç no-store ¥Ø¥Ã¥À¤Î¤Ä¤¤¤Æ¤¤¤ë + ¥ê¥½¡¼¥¹¤ËÂФ·¤Æ¤â¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¿¤À¤·Ç§¾Ú¤Îµá¤á¤é¤ì¤ë¥ê¥½¡¼¥¹¤Ï ·è¤·¤Æ ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    + +

    + CacheStoreNoStore On +

    + +

    ·Ù¹ð:

    + RFC 2616 ¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë no-store ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + "ÉÔÃí°Õ¤Ë¤è¤ëµ¡Ì©¾ðÊó¤Îϳ±Ì¤ä»Äα (¥Ð¥Ã¥¯¥¢¥Ã¥×¥Æ¡¼¥×Åù) ¤òËɤ°" + ÌÜŪ¤Ç»È¤ï¤ì¤Þ¤¹¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢ + µ¡Ì©¾ðÊó¤òÊÝ»ý¤¹¤ë¤³¤È¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡£ + ¤Ç¤¹¤Î¤Ç¡¢¤³¤³¤Ç·Ù¹ð¤·¤Æ¤ª¤­¤Þ¤¹¡£ +
    + +

    »²¾È

    + +
    +
    top
    +

    CacheStorePrivate ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:private ¤È»ØÄꤵ¤ì¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Î¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¡£
    ¹½Ê¸:CacheStorePrivate On|Off
    ¥Ç¥Õ¥©¥ë¥È:CacheStorePrivate Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_cache
    +

    Ä̾ï Cache-Control: private ¥Ø¥Ã¥À¤Î¤Ä¤¤¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Ï + ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£CacheStorePrivate + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤³¤ÎµóÆ°¤ò¾å½ñ¤­¤Ç¤­¤Þ¤¹¡£ + CacheStorePrivate On ¤Ç private ¥Ø¥Ã¥À¤Î¤Ä¤¤¤Æ¤¤¤ë + ¥ê¥½¡¼¥¹¤ËÂФ·¤Æ¤â¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¿¤À¤·Ç§¾Ú¤Îµá¤á¤é¤ì¤ë¥ê¥½¡¼¥¹¤Ï ·è¤·¤Æ ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    + +

    + CacheStorePrivate On +

    + +

    ·Ù¹ð:

    + ¾åή¥µ¡¼¥Ð¤¬¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤¤è¤¦¤Ë»ØÄꤷ¤Æ¤­¤Æ¤â¡¢ + ¤½¤ì¤ò̵»ë¤·¤Æ¥­¥ã¥Ã¥·¥å¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ˾¤Þ¤·¤¤µóÆ°¤Ë¤Ê¤ë¤Î¤Ï¡¢ËÜÅö¤Ë 'private' ¤Ê¥­¥ã¥Ã¥·¥å¤Ë¤Ä¤¤¤Æ¤Î¤ß¤Ç¤·¤ç¤¦¡£ +
    + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cache.html.ko.euc-kr b/trunk/docs/manual/mod/mod_cache.html.ko.euc-kr new file mode 100644 index 0000000000..6cb77c1e4c --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.html.ko.euc-kr @@ -0,0 +1,347 @@ + + + +mod_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_cache

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù.
    »óÅÂ:Experimental
    ¸ðµâ¸í:cache_module
    ¼Ò½ºÆÄÀÏ:mod_cache.c
    +

    ¿ä¾à

    + +
    + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... +
    + +

    mod_cache´Â °°Àº ÄÄÇ»ÅÍ¿¡ ÀÖ´Â ³»¿ëÀ̳ª + ÇÁ·Ï½ÃµÈ ³»¿ëÀ» ij½¬ÇÒ ¼ö ÀÖ´Â RFC 2616 + ȣȯ HTTP ³»¿ëij½¬¸¦ ±¸ÇöÇÑ´Ù. mod_cache¸¦ + »ç¿ëÇÏ·Á¸é ÀúÀå°ü¸®¸ðµâ(storage management module)ÀÌ ÇÊ¿äÇÏ´Ù. + ±âº» ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡´Â µÎ°¡Áö ÀúÀå°ü¸®¸ðµâÀÌ ÀÖ´Ù:

    +
    +
    mod_disk_cache
    +
    ´Â µð½ºÅ©±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ ±¸ÇöÇÑ´Ù.
    + +
    mod_mem_cache
    +
    ´Â ¸Þ¸ð¸®±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ ±¸ÇöÇÑ´Ù. + mod_mem_cache´Â ÆÄÀϱâ¼úÀÚ¸¦ ij½¬Çϰųª + Èü(heap) °ø°£¿¡ °´Ã¼¸¦ ij½¬ÇÏ´Â µÎ°¡Áö ¹æ½ÄÁß ÇÑ°¡Áö ¹æ¹ýÀ¸·Î + µ¿ÀÛÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. mod_mem_cache´Â + ÀÚ½ÅÀÌ »ý¼ºÇÑ ³»¿ëÀ» ij½¬Çϰųª, (¿ªÇÁ·Ï½Ã(reverse proxy)·Î + ¾Ë·ÁÁø) ProxyPass¸¦ + »ç¿ëÇÏ¿© mod_proxy¸¦ À§ÇØ µÞ´Ü ¼­¹ö³»¿ëÀ» + ij½¬ÇÒ ¼ö ÀÖ´Ù.
    +
    + +

    ³»¿ëÀ» URI¸¦ Åä´ë·Î ¸¸µç Å°·Î ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±Ùº¸È£°¡ µÈ ³»¿ëÀº ij½¬ÇÏÁö¾Ê´Â´Ù.

    +
    + +
    top
    +
    top
    +
    +

    ¼³Á¤¿¹

    +

    Sample httpd.conf

    + #
    + # ¿¹Á¦ ij½¬ ¼³Á¤
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheSize 256
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +

    +
    +
    top
    +

    CacheDefaultExpire Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¸¸±â½Ã°£À» ÁöÁ¤ÇÏÁö¾ÊÀº ¹®¼­¸¦ ij½¬ÇÒ ±âº» ±â°£.
    ¹®¹ý:CacheDefaultExpire seconds
    ±âº»°ª:CacheDefaultExpire 3600 (one hour)
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    CacheDefaultExpire Áö½Ã¾î´Â ¹®¼­ÀÇ + ¸¸±â½Ã°£°ú ÃÖ±Ù¼öÁ¤½Ã°£ÀÌ ¾ø´Â °æ¿ì ¹®¼­¸¦ ij½¬ÇÒ ÃÊ´ÜÀ§ + ±âº» ½Ã°£À» ÁöÁ¤ÇÑ´Ù. CacheMaxExpire·Î + ÁöÁ¤ÇÑ °ªÀÌ ÀÌ ¼³Á¤À» ¹«½ÃÇÏÁö ¾Ê´Â´Ù.

    + +

    + CacheDefaultExpire 86400 +

    + +
    +
    top
    +

    CacheDisable Áö½Ã¾î

    + + + + + + +
    ¼³¸í:ƯÁ¤ URLÀ» ij½¬ÇÏÁö ¾Ê´Â´Ù
    ¹®¹ý:CacheDisable url-string
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    CacheDisable Áö½Ã¾î¸¦ »ç¿ëÇϸé + mod_cache°¡ url-string ÀÌÇÏÀÇ + urlµéÀ» ij½¬ÇÏÁö ¾Ê´Â´Ù.

    + +

    ¿¹Á¦

    + CacheDisable /local_files +

    + +
    +
    top
    +

    CacheEnable Áö½Ã¾î

    + + + + + + +
    ¼³¸í:ÁöÁ¤ÇÑ ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÏ¿© ÁöÁ¤ÇÑ URLÀ» ij½¬ÇÑ´Ù
    ¹®¹ý:CacheEnable cache_type url-string
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    CacheEnable Áö½Ã¾î¸¦ »ç¿ëÇϸé + mod_cache°¡ url-string ÀÌÇÏ + urlµéÀ» ij½¬ÇÑ´Ù. ij½¬ ÀúÀå°ü¸®ÀÚ´Â cache_type + ¾Æ±Ô¸ÕÆ®·Î ÁöÁ¤ÇÑ´Ù. cache_type memÀº + mod_mem_cache°¡ ±¸ÇöÇÏ´Â ¸Þ¸ð¸®±â¹Ý + ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÑ´Ù. cache_type disk´Â + mod_disk_cache°¡ ±¸ÇöÇÏ´Â µð½ºÅ©±â¹Ý + ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÑ´Ù. cache_type fd´Â + mod_mem_cache°¡ ±¸ÇöÇÏ´Â ÆÄÀϱâ¼úÀÚ Ä³½¬¸¦ + »ç¿ëÇÑ´Ù.

    +

    (¾Æ·¡ ¿¹¿Í °°ÀÌ) URL °ø°£ÀÌ ´Ù¸¥ + CacheEnable Áö½Ã¾î¿Í °ãÄ¡¸é ½ÇÁ¦·Î + ÇÑ ÀúÀå°ü¸®ÀÚ°¡ ¿äûÀ» ó¸®ÇÒ¶§±îÁö µÎ ÀúÀå°ü¸®ÀÚ¸¦ ¸ðµÎ + ½ÇÇàÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ CacheEnable + Áö½Ã¾îÀÇ ¼ø¼­´ë·Î ÀúÀå°ü¸®ÀÚ°¡ ½ÇÇàµÈ´Ù.

    + +

    + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +

    + +
    +
    top
    +

    CacheIgnoreCacheControl Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®°¡ ij½¬ÇÏÁö¾Ê´Â ³»¿ëÀ» ¿äûÇÔÀ» ¹«½ÃÇÑ´Ù.
    ¹®¹ý:CacheIgnoreCacheControl On|Off
    ±âº»°ª:CacheIgnoreCacheControl Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    º¸Åë no-cache³ª no-store Çì´õ°ªÀ» °¡Áø ¹®¼­´Â ij½¬¿¡ + ÀúÀåÇÏÁö¾Ê´Â´Ù. CacheIgnoreCacheControl + Áö½Ã¾î´Â ÀÌ·± ÇൿÀ» º¯°æÇÑ´Ù. + CacheIgnoreCacheControl OnÀ» »ç¿ëÇϸé + ¼­¹ö´Â ¹®¼­¿¡ no-cache³ª no-store Çì´õ°ªÀÌ À־ ¹®¼­¸¦ + ij½¬ÇÑ´Ù. ÀÎÁõÀÌ ÇÊ¿äÇÑ ¹®¼­´Â Àý´ë·Î ij½¬ÇÏÁö + ¾Ê´Â´Ù.

    + +

    + CacheIgnoreCacheControl On +

    + +
    +
    top
    +

    CacheIgnoreHeaders Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÁöÁ¤ÇÑ HTTP Çì´õ(µé)¸¦ ÀúÀåÇÏÁö ¾Ê´Â´Ù +
    ¹®¹ý:CacheIgnoreHeaders header-string [header-string] ...
    ±âº»°ª:CacheIgnoreHeaders None
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    RFC 2616¿¡ µû¸£¸é È©°£(hop-by-hop) HTTP Çì´õ´Â ij½¬¿¡ + ÀúÀåÇÏÁö ¾Ê´Â´Ù. È©°£ HTTP Çì´õ¿¡´Â ´ÙÀ½°ú °°Àº °ÍÀÌ ÀÖÀ¸¸ç, + CacheIgnoreHeaders ¼³Á¤°ú °ü°è¾øÀÌ + ¾î¶² °æ¿ì¿¡µµ ij½¬¿¡ ÀúÀåµÇÁö ¾Ê´Â´Ù.

    + +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders´Â ij½¬¿¡ ÀúÀåÇϸé + ¾ÈµÇ´Â HTTP Çì´õ¸¦ Ãß°¡·Î ÁöÁ¤ÇÑ´Ù. ¿¹¸¦ µé¾î, ÄíÅ°(cookie)¸¦ + ij½¬¿¡ ÀúÀåÇÏ¸é ¾ÈµÇ´Â °æ¿ì°¡ ÀÖ´Ù.

    + +

    CacheIgnoreHeaders´Â ij½¬¿¡ ÀúÀåÇÏÁö + ¾ÊÀ» HTTP Çì´õµéÀ» °ø¹éÀ¸·Î ±¸ºÐÇÑ ¸ñ·ÏÀ» ¹Þ´Â´Ù. (RFC 2616¿¡ + µû¶ó) ij½¬¿¡ È©°£ Çì´õ¸¸ ÀúÀåÇÏÁö ¾ÊÀ¸·Á¸é, + CacheIgnoreHeaders¸¦ + NoneÀ¸·Î ¼³Á¤ÇÑ´Ù.

    + +

    ¿¹Á¦ 1

    + CacheIgnoreHeaders Set-Cookie +

    + +

    ¿¹Á¦ 2

    + CacheIgnoreHeaders None +

    + +

    °æ°í:

    + CacheIgnoreHeaders ¼³Á¤À» »ç¿ëÇÏ¿© + Expires °°ÀÌ Ä³½¬ °ü¸®¿¡ ÇÊ¿äÇÑ Çì´õ¸¦ ÀúÀåÇÏÁö + ¾ÊÀ¸¸é, mod_cache´Â ºñÁ¤»óÀûÀ¸·Î µ¿ÀÛÇÑ´Ù. +
    + +
    +
    top
    +

    CacheIgnoreNoLastMod Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÀ´ä¿¡ Last Modified Çì´õ°¡ ¾ø´Ù´Â »ç½ÇÀ» ¹«½ÃÇÑ´Ù.
    ¹®¹ý:CacheIgnoreNoLastMod On|Off
    ±âº»°ª:CacheIgnoreNoLastMod Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    º¸Åë ÃÖ±Ù¼öÁ¤ÀÏÀÌ ¾ø´Â ¹®¼­´Â ij½¬ÇÏÁö ¾Ê´Â´Ù. ¾î¶² °æ¿ì + ÃÖ±Ù¼öÁ¤ÀÏÀ» (¿¹¸¦ µé¾î mod_include ó¸®Áß¿¡) + »©°Å³ª óÀ½ºÎÅÍ ¾ø¾úÀ» ¼ö°¡ ÀÖ´Ù. + CacheIgnoreNoLastMod Áö½Ã¾î´Â ÃÖ±Ù¼öÁ¤ÀÏÀÌ + ¾ø´Â ¹®¼­µµ ¹Ýµå½Ã ij½¬Çϵµ·Ï ¸¸µç´Ù. ¹®¼­¿¡ ÃÖ±Ù¼öÁ¤ÀÏ°ú + ¸¸±â½Ã°£ÀÌ ¾ø´Â °æ¿ì CacheDefaultExpire + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªÀ» ¸¸±â½Ã°£À¸·Î »ç¿ëÇÑ´Ù.

    + +

    + CacheIgnoreNoLastMod On +

    + +
    +
    top
    +

    CacheLastModifiedFactor Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:LastModified ½Ã°£À¸·Î ¸¸±â½Ã°£À» °è»êÇϴµ¥ »ç¿ëÇÏ´Â +°è¼ö.
    ¹®¹ý:CacheLastModifiedFactor float
    ±âº»°ª:CacheLastModifiedFactor 0.1
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    ¹®¼­¿¡ ¸¸±â½Ã°£Àº ¾øÁö¸¸ ÃÖ±Ù¼öÁ¤ÀÏÀÌ ÀÖ´Â °æ¿ì ÃÖ±Ù¼öÁ¤ÀÏ + ÀÌÈÄ Áö³­ ½Ã°£À¸·Î ¸¸±â½Ã°£À» °è»êÇÑ´Ù. + CacheLastModifiedFactor Áö½Ã¾î´Â + ¸¸±â½Ã°£À» °è»êÇÏ´Â ´ÙÀ½ °ø½Ä¿¡¼­ »ç¿ëÇÒ factor¸¦ + ÁöÁ¤ÇÑ´Ù: + + expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period + + ¿¹¸¦ µé¾î, ¹®¼­°¡ 10 ½Ã°£ Àü¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú°í factor°¡ + 0.1À̶ó¸é ¸¸±â±â°£Àº 10*01 = 1 ½Ã°£ÀÌ µÈ´Ù. ÇöÀç ½Ã°£ÀÌ + 3:00pmÀ̶ó¸é ¸¸±â½Ã°£Àº 3:00pm + 1½Ã°£ = 4:00pmÀÌ´Ù. + + ¸¸±â±â°£ÀÌ CacheMaxExpire º¸´Ù ±æ´Ù¸é + CacheMaxExpire¸¦ »ç¿ëÇÑ´Ù.

    + +

    + CacheLastModifiedFactor 0.5 +

    + +
    +
    top
    +

    CacheMaxExpire Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¹®¼­¸¦ ij½¬ÇÏ´Â ÃÊ´ÜÀ§ ÃÖ´ë½Ã°£
    ¹®¹ý:CacheMaxExpire seconds
    ±âº»°ª:CacheMaxExpire 86400 (ÇÏ·ç)
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_cache
    +

    CacheMaxExpire Áö½Ã¾î´Â ½ÇÁ¦ ¼­¹ö¸¦ + °Ë»çÇÏÁö¾Ê°í ij½¬°¡´ÉÇÑ HTTP ¹®¼­¸¦ À¯ÁöÇÒ ¼ö ÀÖ´Â ÃÊ´ÜÀ§ + ÃÖ´ë½Ã°£À» ÁöÁ¤ÇÑ´Ù. Áï, ¹®¼­´Â ÃÖ´ëÇÑ ÀÌ ¼³Á¤°ª¸¸Å­ ¿À·¡µÇ¾ú´Ù. + ¹®¼­°¡ ¸¸±â½Ã°£À» ÁöÁ¤ÇÏ¿©µµ ÀÌ ÃÖ´ë°ªÀ» ÁöŲ´Ù.

    + +

    + CacheMaxExpire 604800 +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cache.xml b/trunk/docs/manual/mod/mod_cache.xml new file mode 100644 index 0000000000..cda4ea22d0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.xml @@ -0,0 +1,417 @@ + + + + + + + + + +mod_cache +Content cache keyed to URIs. +Extension +mod_cache.c +cache_module + + +

    mod_cache implements an RFC 2616 compliant HTTP + content cache that can be used to cache either local or proxied content. + mod_cache requires the services of one or more storage + management modules. Two storage management modules are included in + the base Apache distribution:

    +
    +
    mod_disk_cache
    +
    implements a disk based storage manager.
    + +
    mod_mem_cache
    +
    implements a memory based storage manager. + mod_mem_cache can be configured to operate in two + modes: caching open file descriptors or caching objects in heap storage. + mod_mem_cache can be used to cache locally generated content + or to cache backend server content for mod_proxy when + configured using ProxyPass + (aka reverse proxy)
    +
    + +

    Content is stored in and retrieved from the cache using URI based keys. Content with + access protection is not cached.

    +
    + + + +
    Sample Configuration + Sample httpd.conf + #
    + # Sample Cache Configuration
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + # If you want to use mod_disk_cache instead of mod_mem_cache, + # uncomment the line above and comment out the LoadModule line below. + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +
    +
    + + +CacheEnable +Enable caching of specified URLs using a specified storage +manager +CacheEnable cache_type url-string +server configvirtual host + + + +

    The CacheEnable directive instructs + mod_cache to cache urls at or below + url-string. The cache storage manager is specified with the + cache_type argument. cache_type mem + instructs mod_cache to use the memory based storage + manager implemented by mod_mem_cache. + cache_type disk instructs + mod_cache to use the disk based storage manager + implemented by mod_disk_cache. + cache_type fd instructs + mod_cache to use the file descriptor cache implemented + by mod_mem_cache.

    +

    In the event that the URL space overlaps between different + CacheEnable directives (as in the example below), + each possible storage manager will be run until the first one that + actually processes the request. The order in which the storage managers are + run is determined by the order of the CacheEnable + directives in the configuration file.

    + + + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +
    +
    +
    + + +CacheDisable +Disable caching of specified URLs +CacheDisable url-string +server configvirtual host + + + +

    The CacheDisable directive instructs + mod_cache to not cache urls at or below + url-string.

    + + Example + CacheDisable /local_files + +
    + +
    + +CacheMaxExpire +The maximum time in seconds to cache a document +CacheMaxExpire seconds +CacheMaxExpire 86400 (one day) +server configvirtual host + + + +

    The CacheMaxExpire directive specifies the maximum number of + seconds for which cachable HTTP documents will be retained without checking the origin + server. Thus, documents will be out of date at most this number of seconds. This maximum + value is enforced even if an expiry date was supplied with the document.

    + + + CacheMaxExpire 604800 + +
    +
    + + +CacheDefaultExpire +The default duration to cache a document when no expiry date is specified. +CacheDefaultExpire seconds +CacheDefaultExpire 3600 (one hour) +server configvirtual host + + + +

    The CacheDefaultExpire directive specifies a default time, + in seconds, to cache a document if neither an expiry date nor last-modified date are provided + with the document. The value specified with the CacheMaxExpire + directive does not override this setting.

    + + + CacheDefaultExpire 86400 + +
    +
    + + +CacheIgnoreNoLastMod +Ignore the fact that a response has no Last Modified +header. +CacheIgnoreNoLastMod On|Off +CacheIgnoreNoLastMod Off +server configvirtual host + + + +

    Ordinarily, documents without a last-modified date are not cached. + Under some circumstances the last-modified date is removed (during + mod_include processing for example) or not provided + at all. The CacheIgnoreNoLastMod directive + provides a way to specify that documents without last-modified dates + should be considered for caching, even without a last-modified date. + If neither a last-modified date nor an expiry date are provided with + the document then the value specified by the + CacheDefaultExpire directive will be used to + generate an expiration date.

    + + + CacheIgnoreNoLastMod On + +
    +
    + + +CacheIgnoreCacheControl +Ignore request to not serve cached content to client +CacheIgnoreCacheControl On|Off +CacheIgnoreCacheControl Off +server configvirtual host + + + +

    Ordinarily, requests containing a Cache-Control: no-cache or + Pragma: no-cache header value will not be served from the cache. The + CacheIgnoreCacheControl directive allows this + behavior to be overridden. CacheIgnoreCacheControl + On tells the server to attempt to serve the resource from the cache even + if the request contains no-cache header values. Resources requiring + authorization will never be cached.

    + + + CacheIgnoreCacheControl On + + + Warning: + This directive will allow serving from the cache even if the client has + requested that the document not be served from the cache. This might + result in stale content being served. + +
    +CacheStorePrivate +CacheStoreNoStore +
    + + +CacheLastModifiedFactor +The factor used to compute an expiry date based on the +LastModified date. +CacheLastModifiedFactor float +CacheLastModifiedFactor 0.1 +server configvirtual host + + + +

    In the event that a document does not provide an expiry date but does + provide a last-modified date, an expiry date can be calculated based on + the time since the document was last modified. The + CacheLastModifiedFactor directive specifies a + factor to be used in the generation of this expiry date + according to the following formula: + + expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period + + For example, if the document was last modified 10 hours ago, and + factor is 0.1 then the expiry-period will be set to + 10*0.1 = 1 hour. If the current time was 3:00pm then the computed + expiry-date would be 3:00pm + 1hour = 4:00pm. + + If the expiry-period would be longer than that set by + CacheMaxExpire, then the latter takes + precedence.

    + + + CacheLastModifiedFactor 0.5 + +
    +
    + + +CacheIgnoreHeaders +Do not store the given HTTP header(s) in the cache. + +CacheIgnoreHeaders header-string [header-string] ... +CacheIgnoreHeaders None +server configvirtual host + + + +

    According to RFC 2616, hop-by-hop HTTP headers are not stored in + the cache. The following HTTP headers are hop-by-hop headers and thus + do not get stored in the cache in any case regardless of the + setting of CacheIgnoreHeaders:

    + +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders specifies additional HTTP + headers that should not to be stored in the cache. For example, it makes + sense in some cases to prevent cookies from being stored in the cache.

    + +

    CacheIgnoreHeaders takes a space separated list + of HTTP headers that should not be stored in the cache. If only hop-by-hop + headers not should be stored in the cache (the RFC 2616 compliant + behaviour), CacheIgnoreHeaders can be set to + None.

    + + Example 1 + CacheIgnoreHeaders Set-Cookie + + + Example 2 + CacheIgnoreHeaders None + + + Warning: + If headers like Expires which are needed for proper cache + management are not stored due to a + CacheIgnoreHeaders setting, the behaviour of + mod_cache is undefined. + +
    +
    + + +CacheStorePrivate +Attempt to cache responses that the server has marked as private +CacheStorePrivate On|Off +CacheStorePrivate Off +server configvirtual host + + + +

    Ordinarily, responses with Cache-Control: private header values will not + be stored in the cache. The CacheStorePrivate + directive allows this behavior to be overridden. + CacheStorePrivate On + tells the server to attempt to cache the resource even if it contains + private header values. Resources requiring authorization will + never be cached.

    + + + CacheStorePrivate On + + + Warning: + This directive will allow caching even if the upstream server has + requested that the resource not be cached. This directive is only + ideal for a 'private' cache. + +
    +CacheIgnoreCacheControl +CacheStoreNoStore +
    + + +CacheStoreNoStore +Attempt to cache requests or responses that have been marked as no-store. +CacheStoreNoStore On|Off +CacheStoreNoStore Off +server configvirtual host + + + +

    Ordinarily, requests or responses with Cache-Control: no-store header + values will not be stored in the cache. The + CacheStoreNoCache directive allows this + behavior to be overridden. CacheStoreNoCache On + tells the server to attempt to cache the resource even if it contains + no-store header values. Resources requiring authorization will + never be cached.

    + + + CacheStoreNoStore On + + + Warning: + As described in RFC 2616, the no-store directive is intended to + "prevent the inadvertent release or retention of sensitive information + (for example, on backup tapes)." Enabling this option could store + sensitive information in the cache. You are hereby warned. + +
    +CacheIgnoreCacheControl +CacheStorePrivate +
    +
    diff --git a/trunk/docs/manual/mod/mod_cache.xml.ja b/trunk/docs/manual/mod/mod_cache.xml.ja new file mode 100644 index 0000000000..d950826132 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.xml.ja @@ -0,0 +1,423 @@ + + + + + + + + + +mod_cache +URI $B$r%-!<$K$7$?%3%s%F%s%D$N%-%c%C%7%e(B +Extension +mod_cache.c +cache_module + + + + $B$3$l$O + +

    mod_cache $B$O%m!<%+%k$N%3%s%F%s%D$d%W%m%-%7$5$l$?(B + $B%3%s%F%s%D$r%-%c%C%7%e$9$k$?$a$K;H$o$l$k(B RFC 2616 $B=`5r$N(B + HTTP $B%3%s%F%s%D%-%c%C%7%e$rmod_cache + $B$NF0:n$K$O%9%H%l!<%8$r4IM}$9$k%b%8%e!<%k$,I,MW$G$9!#I8=`(B + Apache $BG[I[$K$OFs$D%9%H%l!<%84IM}%b%8%e!<%k$,4^$^$l$F$$$^$9(B:

    + +
    +
    mod_disk_cache
    +
    $B%G%#%9%/$r;HMQ$7$?%9%H%l!<%84IM}5!9=$r + +
    mod_mem_cache
    +
    $B%a%b%j$r;HMQ$7$?%9%H%l!<%84IM}5!9=$rmod_mem_cache $B$Oe$G$N%*%V%8%'%/%H$N<+BN$r%-%c%C%7%e$r$9$k%b!<%I$G$9!#(B + mod_mem_cache $B$O%m!<%+%k$G@8@.$5$l$k%3%s%F%s%D$d!"(B + mod_proxy $B$,(B + ProxyPass $B$r;H$C$F@_Dj$5$l$F$$$k(B + $B$H$-$N(B ($B$D$^$j(B$B%j%P!<%9%W%m%-%7(B $B$G$N(B) $B%P%C%/%(%s%I%5!<%P$N(B + $B%3%s%F%s%D$r%-%c%C%7%e$9$k$N$K;H$($^$9!#(B
    +
    + +

    $B%3%s%F%s%D$N%-%c%C%7%e$X$NJ]B8$H +

    + + + +
    $B%5%s%W%k@_Dj(B + Sample httpd.conf + #
    + # Sample Cache Configuration
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + # If you want to use mod_disk_cache instead of mod_mem_cache, + # uncomment the line above and comment out the LoadModule line below. + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +
    +
    + + +CacheEnable +$B;XDj$7$?%9%H%l!<%84IM}J}<0$r;H$C$F$N%-%c%C%7%e$rM-8z$K$9$k(B +CacheEnable cache_type url-string +server configvirtual host + + + +

    CacheEnable $B%G%#%l%/%F%#%V$G(B mod_cache + $B%b%8%e!<%k$,(B url-string $B0J2<$N(B URL $B$r%-%c%C%7%e$9$k$h$&$K$7$^$9!#(B + $B%-%c%C%7%e%9%H%l!<%84IM}J}<0$O(B cache_type $B0z?t$G;XDj$7$^$9!#(B + cache_type mem $B$G!"(B + mod_mem_cache $B$Gmod_cache $B$K;X<($7$^$9!#(B + cache_type disk $B$G!"(B + mod_disk_cache $B$Gmod_cache $B$K;X<($7$^$9!#(B + cache_type fd $B$O(B mod_cache $B$K(B + mod_mem_cache $B$K$h$j + +

    ($B2<$NNc$N$h$&$K(B) CacheEnable $B%G%#%l%/%F%#%V$N(B + URL $B6u4V$,=EJ#$7$F$$$k$H$-$O!"3:Ev$9$k%9%H%l!<%8J}<0$r=g$K;n$7$F!"(B + $BCacheEnable $B$N=gHV$K$h$j7hDj$5$l$^$9!#(B

    + + + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +
    +
    +
    + + +CacheDisable +$BFCDj$N(B URL $B$r%-%c%C%7%e$7$J$$(B +CacheDisable url-string +server configvirtual host + + + +

    CacheDisable $B%G%#%l%/%F%#%V$G(B + mod_cache $B%b%8%e!<%k$,(B url-string $B0J2<$N(B + URL $B$r%-%c%C%7%e(B$B$7$J$$(B$B$h$&$K$7$^$9!#(B

    + + $BNc(B + CacheDisable /local_files + +
    + +
    + +CacheMaxExpire +$B%I%-%e%a%s%H$r%-%c%C%7%e$9$k:GBg;~4V$rIC?t$G8=$7$?$b$N(B +CacheMaxExpire seconds +CacheMaxExpire 86400 ($B0lF|(B) +server configvirtual host + + + +

    CacheMaxExpire $B%G%#%l%/%F%#%V$O!"(B + $B%-%c%C%7%e$9$k(B HTTP $B%I%-%e%a%s%H$r!"85$N%5!<%P$KLd$$9g$o$;$J$$$^$^:GBg2?IC(B + $BJ];}$7$F$b$h$$$+$r;XDj$7$^$9!#$D$^$j!"%I%-%e%a%s%H$O:GBg$G$3$NIC?t4V$V$s8E$/(B + $B$J$k$3$H$K$J$j$^$9!#$3$N:GBgCM$O!"(B($BLuCm(B:$B%l%9%]%s%9Cf$G(B)$B%I%-%e%a%s%H$H6&$K(B + $B%I%-%e%a%s%H$N4|F|$,Ds6!$5$l$F$$$k>l9g$G$bE,MQ$5$l$^$9!#(B

    + + + CacheMaxExpire 604800 + +
    +
    + + +CacheDefaultExpire +$B4|F|$,;XDj$5$l$F$$$J$$$H$-$K%I%-%e%a%s%H$r%-%c%C%7%e$9$k%G%U%)%k%H$N4|4V(B +CacheDefaultExpire seconds +CacheDefaultExpire 3600 (1$B;~4V(B) +server configvirtual host + + + +

    CacheDefaultExpire $B%G%#%l%/%F%#%V$O!"%I%-%e%a%s%H$K(B + $BM-8z4|8B(B (expiry) $B$d:G=*=$@5;~9o(B (last-modified) $B$,;XDj$5$l$F$$$J$$>l9g$N(B + $B%G%U%)%k%H$N;~4V$r;XDj$7$^$9!#(BCacheMaxExpire + $B%G%#%l%/%F%#%V$G;XDj$5$l$?CM$O$3$N@_Dj$r>e=q$-(B$B$7$^$;$s(B$B!#(B

    + + + CacheDefaultExpire 86400 + +
    +
    + + +CacheIgnoreNoLastMod +$B1~Ez$K(B Last Modified $B$,L5$/$F$b5$$K$7$J$$$h$&$K$9$k(B +CacheIgnoreNoLastMod On|Off +CacheIgnoreNoLastMod Off +server configvirtual host + + + +

    $BDL>o!"(BLast-Modified $B$K$h$k:G=*=$@5;~9o$NL5$$%I%-%e%a%s%H$O%-%c%C%7%e(B + $B$5$l$^$;$s!#(B($BNc$($P(B mod_include $B$K$h$k=hM}$N$H$-$J$I$K(B) + Last-Modified $B;~9o$,>C5n$5$l$?$j!"$=$b$=$b:G=i$+$iDs6!$5$l$F$$$J$$(B + $B>u67$,$"$j$^$9!#(BCacheIgnoreNoLastMod + $B%G%#%l%/%F%#%V$r;H$&$H!"(BLast-Modified $BF|;~$,;XDj$5$l$F$$$J$$(B + $B%I%-%e%a%s%H$G$b%-%c%C%7%e$9$k$h$&$K;XDj$G$-$^$9!#%I%-%e%a%s%H$K(B + $B:G=*=$@5;~9o(B (Last-Modified) $BM-8z4|8B(B (expiry) $B$,$J$$>l9g$O!"M-8z4|8B$N(B + $B@8@.$K(B CacheDefaultExpire $B$,;H$o$l$^$9!#(B

    + + + CacheIgnoreNoLastMod On + +
    +
    + + +CacheIgnoreCacheControl +$B%-%c%C%7%e$5$l$F$$$k%3%s%F%s%D$rJV$5$J$$$h$&$K%/%i%$%"%s%H$+$i(B +$B%j%/%(%9%H$5$l$F$bL5;k$9$k(B +CacheIgnoreCacheControl On|Off +CacheIgnoreCacheControl Off +server configvirtual host + + + +

    Cache-Control: no-cache $B%X%C%@$d(B Pragma: no-store $B%X%C%@$N$"$k%j%/%(%9%H$K(B + $BBP$7$F$O!"DL>o%-%c%C%7%e$r;H$$$^$;$s!#(BCacheIgnoreCacheControl + $B%G%#%l%/%F%#%V$r;H$&$H!"$3$NF0:n$r>e=q$-$G$-$^$9!#(B + CacheIgnoreCacheControl On $B$H$9$k$H!"(B + $B%j%/%(%9%H$K(B no-cache $B$H$$$&CM$,$"$C$F$b!"%-%c%C%7%e$r;H$C$F%I%-%e%a%s%H$r(B + $BJV$9$h$&$K$J$j$^$9!#G'>Z$rI,MW$H$9$k%I%-%e%a%s%H$O(B$B7h$7$F(B + $B%-%c%C%7%e$5$l$^$;$s!#(B

    + + + CacheIgnoreCacheControl On + + + $B7Y9p(B + $B$3$N%G%#%l%/%F%#%V$r;H$&$H!"%I%-%e%a%s%H +
    +CacheStorePrivate +CacheStoreNoStore +
    + + +CacheLastModifiedFactor +LastModified $B$NF|IU$K4p$E$$$FM-8z4|8B(B (expiry) +$B$r7W;;$9$k$?$a$N=E$_$r;XDj$9$k(B + +CacheLastModifiedFactor float +CacheLastModifiedFactor 0.1 +server configvirtual host + + + +

    $B%I%-%e%a%s%H$K(B Last-Modified $B$NF|IU$,L5$$$1$l$I$bM-8z4|8B(B (expiry) + $B$NF|IU$,$"$k$H$$$&$H$-$K!"M-8z4|8B$r:G=*=$@5;~9o$+$i$N7P2a;~4V$H$7$F(B + $B7W;;$9$k$h$&$K$G$-$^$9!#M-8z4|8B$r$C$F@8@.$9$k$N$G$9$,!"(B + $B$=$N$H$-$K;H$o$l$k(B factor $B$r(B + CacheLastModifiedFactor $B%G%#%l%/%F%#%V$G;XDj$7$^$9!#(B +

    + +

    expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period

    + +

    $BNc$($P!"%I%-%e%a%s%H$,(B 10 $B;~4VA0$K:G8e$K=$@5$5$l$F$$$F!"(B + factor $B$,(B 0.1 $B$G$"$l$P!"4|F|$O(B 10*0.1 = 1 $B;~4V$K(B + $B@_Dj$5$l$^$9!#8=:_;~9o$,(B 3:00pm $B$G$"$l$P!"7W;;$5$l$?4|F|$O(B + 3:00pm + 1hour = 4:00pm $B$K$J$j$^$9!#(B

    + +

    $B4|F|$,(B CacheMaxExpire $B$G@_Dj$5$l$F$$$kCM(B + $B$h$jBg$-$/$J$C$F$7$^$C$F$$$k>l9g$O!"(BCacheMaxExpire + $B$N@_DjCM$,M%@h$5$l$^$9!#(B

    + + + CacheLastModifiedFactor 0.5 + +
    +
    + + +CacheIgnoreHeaders +$B;XDj$5$l$?(B HTTP $B%X%C%@$r%-%c%C%7%e$KJ]B8$7$J$$!#(B + +CacheIgnoreHeaders header-string [header-string] ... +CacheIgnoreHeaders None +server configvirtual host + + + +

    RFC 2616 $B$K$h$k$H!"(Bhop-by-hop HTTP $B%X%C%@$O%-%c%C%7%e$K$OJ]4I$5$l$^$;$s!#(B + $B0J2<$N%X%C%@$O(B hop-by-hop $B%X%C%@$K3:Ev$7$^$9$N$G!"(B + CacheIgnoreHeaders + $B$N@_Dj$K(B$B4X78$J$/(B$B%-%c%C%7%e$K$OJ]4I$5$l$^$;$s(B:

    +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders $B$G(B + $B%-%c%C%7%e$KJ]4I$7$J$$DI2C$N(B HTTP $B%X%C%@$r;XDj$7$^$9!#(B + $BNc$($P!"%/%C%-!<$r%-%c%C%7%e$KJ]4I$7$J$$$h$&$K$7$?J}$,$h$$>l9g$b(B + $B$"$k$G$7$g$&!#(B

    + +

    CacheIgnoreHeaders $B$N0z?t$O!"(B + $B%-%c%C%7%e$KJ]4I$7$J$$(B HTTP $B%X%C%@$r6uGr6h@Z$j$K$7$?%j%9%H7A<0$G$9!#(B + $B%-%c%C%7%e$KJ]4I$7$J$$%X%C%@$,(B hop-by-hop $B%X%C%@$@$1$N>l9g(B + (RFC 2616 $B=`5r$NF0:n$N$H$-(B) $B$O!"(B + CacheIgnoreHeaders $B$r(B None + $B$K@_Dj$G$-$^$9!#(B

    + + $BNc(B 1 + CacheIgnoreHeaders Set-Cookie + + + $BNc(B 2 + CacheIgnoreHeaders None + + + $B7Y9p(B: + Expires $B$N$h$&$JE,@Z$N%-%c%C%7%e4IM}$N$?$a$KI,MW$J(B + $B%X%C%@$,(B CacheIgnoreHeaders $B$N@_Dj$K$h$j(B + $BJ]4I$5$l$F$$$J$$$H$-$O!"(Bmod_cache $B$NF0:n$ODj5A$5$l$F$$$^$;$s!#(B + +
    +
    + + +CacheStorePrivate +private $B$H;XDj$5$l$F$$$k%l%9%]%s%9$N%-%c%C%7%e$r;n$_$k!#(B +CacheStorePrivate On|Off +CacheStorePrivate Off +server configvirtual host + + + +

    $BDL>o(B Cache-Control: private $B%X%C%@$N$D$$$F$$$k%l%9%]%s%9$O(B + $B%-%c%C%7%e$5$l$^$;$s!#(BCacheStorePrivate + $B%G%#%l%/%F%#%V$G$3$N5sF0$r>e=q$-$G$-$^$9!#(B + CacheStorePrivate On $B$G(B private $B%X%C%@$N$D$$$F$$$k(B + $B%j%=!<%9$KBP$7$F$b%-%c%C%7%e$r;n$_$k$h$&$K$J$j$^$9!#(B + $B$?$@$7G'>Z$N5a$a$i$l$k%j%=!<%9$O(B $B7h$7$F(B $B%-%c%C%7%e$5$l$^$;$s!#(B

    + + + CacheStorePrivate On + + + $B7Y9p(B: + $B>eN.%5!<%P$,%-%c%C%7%e$7$J$$$h$&$K;XDj$7$F$-$F$b!"(B + $B$=$l$rL5;k$7$F%-%c%C%7%e$9$k$h$&$K$J$j$^$9!#(B + $BK>$^$7$$5sF0$K$J$k$N$O!"K\Ev$K(B 'private' $B$J%-%c%C%7%e$K$D$$$F$N$_$G$7$g$&!#(B + +
    +CacheIgnoreCacheControl +CacheStoreNoStore +
    + + +CacheStoreNoStore +no-store $B$H;XDj$5$l$F$$$k%l%9%]%s%9$N%-%c%C%7%e$r;n$_$k!#(B +CacheStoreNoStore On|Off +CacheStoreNoStore Off +server configvirtual host + + + +

    $BDL>o(B Cache-Control: no-store $B%X%C%@$N$D$$$F$$$k%l%9%]%s%9$O(B + $B%-%c%C%7%e$5$l$^$;$s!#(BCacheStoreNoCache + $B%G%#%l%/%F%#%V$G$3$N5sF0$r>e=q$-$G$-$^$9!#(B + CacheStoreNoCache On $B$G(B no-store $B%X%C%@$N$D$$$F$$$k(B + $B%j%=!<%9$KBP$7$F$b%-%c%C%7%e$r;n$_$k$h$&$K$J$j$^$9!#(B + $B$?$@$7G'>Z$N5a$a$i$l$k%j%=!<%9$O(B $B7h$7$F(B $B%-%c%C%7%e$5$l$^$;$s!#(B

    + + + CacheStoreNoStore On + + + $B7Y9p(B: + RFC 2616 $B$K5-:\$5$l$F$$$k$h$&$K(B no-store $B%G%#%l%/%F%#%V$O!"(B + "$BITCm0U$K$h$k5!L)>pJs$NO31L$d;DN1(B ($B%P%C%/%"%C%W%F!<%WEy(B) $B$rKI$0(B" + $BL\E*$G;H$o$l$^$9$,!"$3$N%*%W%7%g%s$rM-8z$K$9$k$H!"(B + $B5!L)>pJs$rJ];}$9$k$3$H$K$J$C$F$7$^$$$^$9!#(B + $B$G$9$N$G!"$3$3$G7Y9p$7$F$*$-$^$9!#(B + +
    +CacheIgnoreCacheControl +CacheStorePrivate +
    +
    diff --git a/trunk/docs/manual/mod/mod_cache.xml.ko b/trunk/docs/manual/mod/mod_cache.xml.ko new file mode 100644 index 0000000000..fe5f0ca501 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.xml.ko @@ -0,0 +1,346 @@ + + + + + + + + + +mod_cache +URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù. +Experimental +mod_cache.c +cache_module + + + + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... + + +

    mod_cache´Â °°Àº ÄÄÇ»ÅÍ¿¡ ÀÖ´Â ³»¿ëÀ̳ª + ÇÁ·Ï½ÃµÈ ³»¿ëÀ» ij½¬ÇÒ ¼ö ÀÖ´Â RFC 2616 + ȣȯ HTTP ³»¿ëij½¬¸¦ ±¸ÇöÇÑ´Ù. mod_cache¸¦ + »ç¿ëÇÏ·Á¸é ÀúÀå°ü¸®¸ðµâ(storage management module)ÀÌ ÇÊ¿äÇÏ´Ù. + ±âº» ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡´Â µÎ°¡Áö ÀúÀå°ü¸®¸ðµâÀÌ ÀÖ´Ù:

    +
    +
    mod_disk_cache
    +
    ´Â µð½ºÅ©±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ ±¸ÇöÇÑ´Ù.
    + +
    mod_mem_cache
    +
    ´Â ¸Þ¸ð¸®±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ ±¸ÇöÇÑ´Ù. + mod_mem_cache´Â ÆÄÀϱâ¼úÀÚ¸¦ ij½¬Çϰųª + Èü(heap) °ø°£¿¡ °´Ã¼¸¦ ij½¬ÇÏ´Â µÎ°¡Áö ¹æ½ÄÁß ÇÑ°¡Áö ¹æ¹ýÀ¸·Î + µ¿ÀÛÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. mod_mem_cache´Â + ÀÚ½ÅÀÌ »ý¼ºÇÑ ³»¿ëÀ» ij½¬Çϰųª, (¿ªÇÁ·Ï½Ã(reverse proxy)·Î + ¾Ë·ÁÁø) ProxyPass¸¦ + »ç¿ëÇÏ¿© mod_proxy¸¦ À§ÇØ µÞ´Ü ¼­¹ö³»¿ëÀ» + ij½¬ÇÒ ¼ö ÀÖ´Ù.
    +
    + +

    ³»¿ëÀ» URI¸¦ Åä´ë·Î ¸¸µç Å°·Î ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±Ùº¸È£°¡ µÈ ³»¿ëÀº ij½¬ÇÏÁö¾Ê´Â´Ù.

    +
    + + + +
    ¼³Á¤¿¹ + Sample httpd.conf + #
    + # ¿¹Á¦ ij½¬ ¼³Á¤
    + #
    + LoadModule cache_module modules/mod_cache.so
    +
    + <IfModule mod_cache.c>
    + + #LoadModule disk_cache_module modules/mod_disk_cache.so
    + <IfModule mod_disk_cache.c>
    + + CacheRoot c:/cacheroot
    + CacheSize 256
    + CacheEnable disk /
    + CacheDirLevels 5
    + CacheDirLength 3
    +
    + </IfModule>
    +
    + LoadModule mem_cache_module modules/mod_mem_cache.so
    + <IfModule mod_mem_cache.c>
    + + CacheEnable mem /
    + MCacheSize 4096
    + MCacheMaxObjectCount 100
    + MCacheMinObjectSize 1
    + MCacheMaxObjectSize 2048
    +
    + </IfModule>
    +
    + </IfModule> +
    +
    + + +CacheEnable +ÁöÁ¤ÇÑ ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÏ¿© ÁöÁ¤ÇÑ URLÀ» ij½¬ÇÑ´Ù +CacheEnable cache_type url-string +server configvirtual host + + + +

    CacheEnable Áö½Ã¾î¸¦ »ç¿ëÇϸé + mod_cache°¡ url-string ÀÌÇÏ + urlµéÀ» ij½¬ÇÑ´Ù. ij½¬ ÀúÀå°ü¸®ÀÚ´Â cache_type + ¾Æ±Ô¸ÕÆ®·Î ÁöÁ¤ÇÑ´Ù. cache_type memÀº + mod_mem_cache°¡ ±¸ÇöÇÏ´Â ¸Þ¸ð¸®±â¹Ý + ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÑ´Ù. cache_type disk´Â + mod_disk_cache°¡ ±¸ÇöÇÏ´Â µð½ºÅ©±â¹Ý + ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÑ´Ù. cache_type fd´Â + mod_mem_cache°¡ ±¸ÇöÇÏ´Â ÆÄÀϱâ¼úÀÚ Ä³½¬¸¦ + »ç¿ëÇÑ´Ù.

    +

    (¾Æ·¡ ¿¹¿Í °°ÀÌ) URL °ø°£ÀÌ ´Ù¸¥ + CacheEnable Áö½Ã¾î¿Í °ãÄ¡¸é ½ÇÁ¦·Î + ÇÑ ÀúÀå°ü¸®ÀÚ°¡ ¿äûÀ» ó¸®ÇÒ¶§±îÁö µÎ ÀúÀå°ü¸®ÀÚ¸¦ ¸ðµÎ + ½ÇÇàÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ CacheEnable + Áö½Ã¾îÀÇ ¼ø¼­´ë·Î ÀúÀå°ü¸®ÀÚ°¡ ½ÇÇàµÈ´Ù.

    + + + CacheEnable mem /manual
    + CacheEnable fd /images
    + CacheEnable disk /
    +
    +
    +
    + + +CacheDisable +ƯÁ¤ URLÀ» ij½¬ÇÏÁö ¾Ê´Â´Ù +CacheDisable url-string +server configvirtual host + + + +

    CacheDisable Áö½Ã¾î¸¦ »ç¿ëÇϸé + mod_cache°¡ url-string ÀÌÇÏÀÇ + urlµéÀ» ij½¬ÇÏÁö ¾Ê´Â´Ù.

    + + ¿¹Á¦ + CacheDisable /local_files + +
    + +
    + +CacheMaxExpire +¹®¼­¸¦ ij½¬ÇÏ´Â ÃÊ´ÜÀ§ ÃÖ´ë½Ã°£ +CacheMaxExpire seconds +CacheMaxExpire 86400 (ÇÏ·ç) +server configvirtual host + + + +

    CacheMaxExpire Áö½Ã¾î´Â ½ÇÁ¦ ¼­¹ö¸¦ + °Ë»çÇÏÁö¾Ê°í ij½¬°¡´ÉÇÑ HTTP ¹®¼­¸¦ À¯ÁöÇÒ ¼ö ÀÖ´Â ÃÊ´ÜÀ§ + ÃÖ´ë½Ã°£À» ÁöÁ¤ÇÑ´Ù. Áï, ¹®¼­´Â ÃÖ´ëÇÑ ÀÌ ¼³Á¤°ª¸¸Å­ ¿À·¡µÇ¾ú´Ù. + ¹®¼­°¡ ¸¸±â½Ã°£À» ÁöÁ¤ÇÏ¿©µµ ÀÌ ÃÖ´ë°ªÀ» ÁöŲ´Ù.

    + + + CacheMaxExpire 604800 + +
    +
    + + +CacheDefaultExpire +¸¸±â½Ã°£À» ÁöÁ¤ÇÏÁö¾ÊÀº ¹®¼­¸¦ ij½¬ÇÒ ±âº» ±â°£. +CacheDefaultExpire seconds +CacheDefaultExpire 3600 (one hour) +server configvirtual host + + + +

    CacheDefaultExpire Áö½Ã¾î´Â ¹®¼­ÀÇ + ¸¸±â½Ã°£°ú ÃÖ±Ù¼öÁ¤½Ã°£ÀÌ ¾ø´Â °æ¿ì ¹®¼­¸¦ ij½¬ÇÒ ÃÊ´ÜÀ§ + ±âº» ½Ã°£À» ÁöÁ¤ÇÑ´Ù. CacheMaxExpire·Î + ÁöÁ¤ÇÑ °ªÀÌ ÀÌ ¼³Á¤À» ¹«½ÃÇÏÁö ¾Ê´Â´Ù.

    + + + CacheDefaultExpire 86400 + +
    +
    + + +CacheIgnoreNoLastMod +ÀÀ´ä¿¡ Last Modified Çì´õ°¡ ¾ø´Ù´Â »ç½ÇÀ» ¹«½ÃÇÑ´Ù. +CacheIgnoreNoLastMod On|Off +CacheIgnoreNoLastMod Off +server configvirtual host + + + +

    º¸Åë ÃÖ±Ù¼öÁ¤ÀÏÀÌ ¾ø´Â ¹®¼­´Â ij½¬ÇÏÁö ¾Ê´Â´Ù. ¾î¶² °æ¿ì + ÃÖ±Ù¼öÁ¤ÀÏÀ» (¿¹¸¦ µé¾î mod_include ó¸®Áß¿¡) + »©°Å³ª óÀ½ºÎÅÍ ¾ø¾úÀ» ¼ö°¡ ÀÖ´Ù. + CacheIgnoreNoLastMod Áö½Ã¾î´Â ÃÖ±Ù¼öÁ¤ÀÏÀÌ + ¾ø´Â ¹®¼­µµ ¹Ýµå½Ã ij½¬Çϵµ·Ï ¸¸µç´Ù. ¹®¼­¿¡ ÃÖ±Ù¼öÁ¤ÀÏ°ú + ¸¸±â½Ã°£ÀÌ ¾ø´Â °æ¿ì CacheDefaultExpire + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªÀ» ¸¸±â½Ã°£À¸·Î »ç¿ëÇÑ´Ù.

    + + + CacheIgnoreNoLastMod On + +
    +
    + + +CacheIgnoreCacheControl +Ŭ¶óÀ̾ðÆ®°¡ ij½¬ÇÏÁö¾Ê´Â ³»¿ëÀ» ¿äûÇÔÀ» ¹«½ÃÇÑ´Ù. +CacheIgnoreCacheControl On|Off +CacheIgnoreCacheControl Off +server configvirtual host + + + +

    º¸Åë no-cache³ª no-store Çì´õ°ªÀ» °¡Áø ¹®¼­´Â ij½¬¿¡ + ÀúÀåÇÏÁö¾Ê´Â´Ù. CacheIgnoreCacheControl + Áö½Ã¾î´Â ÀÌ·± ÇൿÀ» º¯°æÇÑ´Ù. + CacheIgnoreCacheControl OnÀ» »ç¿ëÇϸé + ¼­¹ö´Â ¹®¼­¿¡ no-cache³ª no-store Çì´õ°ªÀÌ À־ ¹®¼­¸¦ + ij½¬ÇÑ´Ù. ÀÎÁõÀÌ ÇÊ¿äÇÑ ¹®¼­´Â Àý´ë·Î ij½¬ÇÏÁö + ¾Ê´Â´Ù.

    + + + CacheIgnoreCacheControl On + +
    +
    + + +CacheLastModifiedFactor +LastModified ½Ã°£À¸·Î ¸¸±â½Ã°£À» °è»êÇϴµ¥ »ç¿ëÇÏ´Â +°è¼ö. +CacheLastModifiedFactor float +CacheLastModifiedFactor 0.1 +server configvirtual host + + + +

    ¹®¼­¿¡ ¸¸±â½Ã°£Àº ¾øÁö¸¸ ÃÖ±Ù¼öÁ¤ÀÏÀÌ ÀÖ´Â °æ¿ì ÃÖ±Ù¼öÁ¤ÀÏ + ÀÌÈÄ Áö³­ ½Ã°£À¸·Î ¸¸±â½Ã°£À» °è»êÇÑ´Ù. + CacheLastModifiedFactor Áö½Ã¾î´Â + ¸¸±â½Ã°£À» °è»êÇÏ´Â ´ÙÀ½ °ø½Ä¿¡¼­ »ç¿ëÇÒ factor¸¦ + ÁöÁ¤ÇÑ´Ù: + + expiry-period = time-since-last-modified-date * factor + expiry-date = current-date + expiry-period + + ¿¹¸¦ µé¾î, ¹®¼­°¡ 10 ½Ã°£ Àü¿¡ ¸¶Áö¸·À¸·Î ¼öÁ¤µÇ¾ú°í factor°¡ + 0.1À̶ó¸é ¸¸±â±â°£Àº 10*01 = 1 ½Ã°£ÀÌ µÈ´Ù. ÇöÀç ½Ã°£ÀÌ + 3:00pmÀ̶ó¸é ¸¸±â½Ã°£Àº 3:00pm + 1½Ã°£ = 4:00pmÀÌ´Ù. + + ¸¸±â±â°£ÀÌ CacheMaxExpire º¸´Ù ±æ´Ù¸é + CacheMaxExpire¸¦ »ç¿ëÇÑ´Ù.

    + + + CacheLastModifiedFactor 0.5 + +
    +
    + + +CacheIgnoreHeaders +ij½¬¿¡ ÁöÁ¤ÇÑ HTTP Çì´õ(µé)¸¦ ÀúÀåÇÏÁö ¾Ê´Â´Ù + +CacheIgnoreHeaders header-string [header-string] ... +CacheIgnoreHeaders None +server configvirtual host + + + +

    RFC 2616¿¡ µû¸£¸é È©°£(hop-by-hop) HTTP Çì´õ´Â ij½¬¿¡ + ÀúÀåÇÏÁö ¾Ê´Â´Ù. È©°£ HTTP Çì´õ¿¡´Â ´ÙÀ½°ú °°Àº °ÍÀÌ ÀÖÀ¸¸ç, + CacheIgnoreHeaders ¼³Á¤°ú °ü°è¾øÀÌ + ¾î¶² °æ¿ì¿¡µµ ij½¬¿¡ ÀúÀåµÇÁö ¾Ê´Â´Ù.

    + +
      +
    • Connection
    • +
    • Keep-Alive
    • +
    • Proxy-Authenticate
    • +
    • Proxy-Authorization
    • +
    • TE
    • +
    • Trailers
    • +
    • Transfer-Encoding
    • +
    • Upgrade
    • +
    + +

    CacheIgnoreHeaders´Â ij½¬¿¡ ÀúÀåÇϸé + ¾ÈµÇ´Â HTTP Çì´õ¸¦ Ãß°¡·Î ÁöÁ¤ÇÑ´Ù. ¿¹¸¦ µé¾î, ÄíÅ°(cookie)¸¦ + ij½¬¿¡ ÀúÀåÇÏ¸é ¾ÈµÇ´Â °æ¿ì°¡ ÀÖ´Ù.

    + +

    CacheIgnoreHeaders´Â ij½¬¿¡ ÀúÀåÇÏÁö + ¾ÊÀ» HTTP Çì´õµéÀ» °ø¹éÀ¸·Î ±¸ºÐÇÑ ¸ñ·ÏÀ» ¹Þ´Â´Ù. (RFC 2616¿¡ + µû¶ó) ij½¬¿¡ È©°£ Çì´õ¸¸ ÀúÀåÇÏÁö ¾ÊÀ¸·Á¸é, + CacheIgnoreHeaders¸¦ + NoneÀ¸·Î ¼³Á¤ÇÑ´Ù.

    + + ¿¹Á¦ 1 + CacheIgnoreHeaders Set-Cookie + + + ¿¹Á¦ 2 + CacheIgnoreHeaders None + + + °æ°í: + CacheIgnoreHeaders ¼³Á¤À» »ç¿ëÇÏ¿© + Expires °°ÀÌ Ä³½¬ °ü¸®¿¡ ÇÊ¿äÇÑ Çì´õ¸¦ ÀúÀåÇÏÁö + ¾ÊÀ¸¸é, mod_cache´Â ºñÁ¤»óÀûÀ¸·Î µ¿ÀÛÇÑ´Ù. + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_cache.xml.meta b/trunk/docs/manual/mod/mod_cache.xml.meta new file mode 100644 index 0000000000..7713d67822 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cache.xml.meta @@ -0,0 +1,13 @@ + + + + mod_cache + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_cern_meta.html b/trunk/docs/manual/mod/mod_cern_meta.html new file mode 100644 index 0000000000..a0a4d49c4b --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.html @@ -0,0 +1,7 @@ +URI: mod_cern_meta.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_cern_meta.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_cern_meta.html.en b/trunk/docs/manual/mod/mod_cern_meta.html.en new file mode 100644 index 0000000000..d6526f00c7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.html.en @@ -0,0 +1,128 @@ + + + +mod_cern_meta - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_cern_meta

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:CERN httpd metafile semantics
    Status:Extension
    Module Identifier:cern_meta_module
    Source File:mod_cern_meta.c
    +

    Summary

    + +

    Emulate the CERN HTTPD Meta file semantics. Meta files are HTTP + headers that can be output in addition to the normal range of + headers for each file accessed. They appear rather like the + Apache .asis files, and are able to provide a crude way of + influencing the Expires: header, as well as providing other + curiosities. There are many ways to manage meta information, + this one was chosen because there is already a large number of + CERN users who can exploit this module.

    + +

    More information on the CERN metafile semantics is available.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    MetaDir Directive

    + + + + + + + + +
    Description:Name of the directory to find CERN-style meta information +files
    Syntax:MetaDir directory
    Default:MetaDir .web
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_cern_meta
    +

    Specifies the name of the directory in which Apache can find + meta information files. The directory is usually a 'hidden' + subdirectory of the directory that contains the file being + accessed. Set to "." to look in the same directory + as the file:

    + +

    MetaDir .

    + +

    Or, to set it to a subdirectory of the directory containing the + files:

    + +

    MetaDir .meta

    + +
    +
    top
    +

    MetaFiles Directive

    + + + + + + + + +
    Description:Activates CERN meta-file processing
    Syntax:MetaFiles on|off
    Default:MetaFiles off
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_cern_meta
    +

    Turns on/off Meta file processing on a per-directory basis.

    + +
    +
    top
    +

    MetaSuffix Directive

    + + + + + + + + +
    Description:File name suffix for the file containg CERN-style +meta information
    Syntax:MetaSuffix suffix
    Default:MetaSuffix .meta
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_cern_meta
    +

    Specifies the file name suffix for the file containing the + meta information. For example, the default values for the two + directives will cause a request to + DOCUMENT_ROOT/somedir/index.html to look in + DOCUMENT_ROOT/somedir/.web/index.html.meta and + will use its contents to generate additional MIME header + information.

    + +

    Example:

    + MetaSuffix .meta +

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cern_meta.html.ko.euc-kr b/trunk/docs/manual/mod/mod_cern_meta.html.ko.euc-kr new file mode 100644 index 0000000000..c9b60f901f --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.html.ko.euc-kr @@ -0,0 +1,120 @@ + + + +mod_cern_meta - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_cern_meta

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + + +
    ¼³¸í:CERN À¥¼­¹ö ¸ÞŸÆÄÀÏ Áö¿ø
    »óÅÂ:Extension
    ¸ðµâ¸í:cern_meta_module
    ¼Ò½ºÆÄÀÏ:mod_cern_meta.c
    +

    ¿ä¾à

    + +

    CERN À¥¼­¹ö ¸ÞŸÆÄÀÏÀ» Èä³»³½´Ù. ¸ÞŸÆÄÀÏÀº Á¢±ÙÇÏ´Â + ÆÄÀÏ¿¡ ´ëÇØ ÀϹÝÀûÀÎ Çì´õ¿Ü¿¡ Ãß°¡·Î Ãâ·ÂÇÒ HTTP Çì´õ¸¦ + ´ã°íÀÖ´Ù. ¾ÆÆÄÄ¡ .asis ÆÄÀÏ°ú ºñ½ÁÇÏ°í, Expires: Çì´õ¸¦ + ¼öÁ¤Çϰųª ´Ù¸¥ ½Å±âÇÑ ÀϵéÀ» ÇÒ ¼ö ÀÖ´Ù. ¸ÞŸ Á¤º¸¸¦ ´Ù·ç´Â + ¹æ¹ýÀº ´Ù¾çÇÏÁö¸¸, ÀÌ¹Ì ÀÌ ¸ðµâÀ» »ç¿ëÇÏ´Â ¸¹Àº CERN »ç¿ëÀÚµéÀ» + À§ÇØ ÀÌ ¹æ¹ýÀ» ¼±ÅÃÇß´Ù.

    + +

    ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â CERN metafile semantics¸¦ Âü°íÇ϶ó.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    MetaDir Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:CERN ¸ÞŸÁ¤º¸¸¦ ãÀ» µð·ºÅ丮 À̸§
    ¹®¹ý:MetaDir directory
    ±âº»°ª:MetaDir .web
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_cern_meta
    +

    ¾ÆÆÄÄ¡°¡ ¸ÞŸÁ¤º¸ ÆÄÀÏÀ» ãÀ» µð·ºÅ丮¸íÀ» ÁöÁ¤ÇÑ´Ù. + µð·ºÅ丮´Â º¸Åë Á¢±ÙÇÒ ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮ÀÇ '°¨ÃçÁø' + ÇÏÀ§µð·ºÅ丮´Ù. "."À¸·Î ÁöÁ¤ÇÏ¸é °°Àº µð·ºÅ丮¿¡¼­ + ÆÄÀÏÀ» ã´Â´Ù:

    + +

    MetaDir .

    + +

    ¾Æ´Ï¸é ÆÄÀÏÀÌ ÀÖ´Â ÇÏÀ§µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù:

    + +

    MetaDir .meta

    + +
    +
    top
    +

    MetaFiles Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:CERN ¸ÞŸÆÄÀÏÀ» ó¸®ÇÑ´Ù
    ¹®¹ý:MetaFiles on|off
    ±âº»°ª:MetaFiles off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_cern_meta
    +

    µð·ºÅ丮º°·Î ¸ÞŸÆÄÀÏ Ã³¸®¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    + +
    +
    top
    +

    MetaSuffix Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:CERN ¸ÞŸÁ¤º¸¸¦ ÀúÀåÇÏ´Â ÆÄÀÏÀÇ Á¢¹Ì»ç
    ¹®¹ý:MetaSuffix suffix
    ±âº»°ª:MetaSuffix .meta
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_cern_meta
    +

    ¸ÞŸÁ¤º¸¸¦ ÀúÀåÇÏ´Â ÆÄÀÏÀÇ Á¢¹Ì»ç¸¦ ÁöÁ¤ÇÑ´Ù. ¿¹¸¦ µé¾î, + µÎ Áö½Ã¾îÀÇ ±âº»°ªÀ» »ç¿ëÇÒ °æ¿ì + DOCUMENT_ROOT/somedir/index.htmlÀ» ¿äûÇϸé + DOCUMENT_ROOT/somedir/.web/index.html.metaÀÇ + ³»¿ëÀ» Âü°íÇÏ¿© MIME Çì´õ Á¤º¸¸¦ Ãß°¡ÇÑ´Ù.

    + +

    ¿¹Á¦:

    + MetaSuffix .meta +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cern_meta.xml b/trunk/docs/manual/mod/mod_cern_meta.xml new file mode 100644 index 0000000000..0ada7882c3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.xml @@ -0,0 +1,120 @@ + + + + + + + + + +mod_cern_meta +CERN httpd metafile semantics +Extension +mod_cern_meta.c +cern_meta_module + + +

    Emulate the CERN HTTPD Meta file semantics. Meta files are HTTP + headers that can be output in addition to the normal range of + headers for each file accessed. They appear rather like the + Apache .asis files, and are able to provide a crude way of + influencing the Expires: header, as well as providing other + curiosities. There are many ways to manage meta information, + this one was chosen because there is already a large number of + CERN users who can exploit this module.

    + +

    More information on the CERN metafile semantics is available.

    +
    + +mod_headers +mod_asis + + +MetaFiles +Activates CERN meta-file processing +MetaFiles on|off +MetaFiles off +server config +virtual host +directory +.htaccess +Indexes + + +

    Turns on/off Meta file processing on a per-directory basis.

    +
    +
    + + +MetaDir +Name of the directory to find CERN-style meta information +files +MetaDir directory +MetaDir .web +server config +virtual host +directory +.htaccess +Indexes + + +

    Specifies the name of the directory in which Apache can find + meta information files. The directory is usually a 'hidden' + subdirectory of the directory that contains the file being + accessed. Set to "." to look in the same directory + as the file:

    + + MetaDir . + +

    Or, to set it to a subdirectory of the directory containing the + files:

    + + MetaDir .meta +
    +
    + + +MetaSuffix +File name suffix for the file containg CERN-style +meta information +MetaSuffix suffix +MetaSuffix .meta +server config +virtual host +directory +.htaccess +Indexes + + +

    Specifies the file name suffix for the file containing the + meta information. For example, the default values for the two + directives will cause a request to + DOCUMENT_ROOT/somedir/index.html to look in + DOCUMENT_ROOT/somedir/.web/index.html.meta and + will use its contents to generate additional MIME header + information.

    + + Example: + MetaSuffix .meta + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_cern_meta.xml.ko b/trunk/docs/manual/mod/mod_cern_meta.xml.ko new file mode 100644 index 0000000000..ee9d80057a --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.xml.ko @@ -0,0 +1,112 @@ + + + + + + + + + +mod_cern_meta +CERN À¥¼­¹ö ¸ÞŸÆÄÀÏ Áö¿ø +Extension +mod_cern_meta.c +cern_meta_module + + +

    CERN À¥¼­¹ö ¸ÞŸÆÄÀÏÀ» Èä³»³½´Ù. ¸ÞŸÆÄÀÏÀº Á¢±ÙÇÏ´Â + ÆÄÀÏ¿¡ ´ëÇØ ÀϹÝÀûÀÎ Çì´õ¿Ü¿¡ Ãß°¡·Î Ãâ·ÂÇÒ HTTP Çì´õ¸¦ + ´ã°íÀÖ´Ù. ¾ÆÆÄÄ¡ .asis ÆÄÀÏ°ú ºñ½ÁÇÏ°í, Expires: Çì´õ¸¦ + ¼öÁ¤Çϰųª ´Ù¸¥ ½Å±âÇÑ ÀϵéÀ» ÇÒ ¼ö ÀÖ´Ù. ¸ÞŸ Á¤º¸¸¦ ´Ù·ç´Â + ¹æ¹ýÀº ´Ù¾çÇÏÁö¸¸, ÀÌ¹Ì ÀÌ ¸ðµâÀ» »ç¿ëÇÏ´Â ¸¹Àº CERN »ç¿ëÀÚµéÀ» + À§ÇØ ÀÌ ¹æ¹ýÀ» ¼±ÅÃÇß´Ù.

    + +

    ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â CERN metafile semantics¸¦ Âü°íÇ϶ó.

    +
    + +mod_headers +mod_asis + + +MetaFiles +CERN ¸ÞŸÆÄÀÏÀ» ó¸®ÇÑ´Ù +MetaFiles on|off +MetaFiles off +server config +virtual host +directory +.htaccess +Indexes + + +

    µð·ºÅ丮º°·Î ¸ÞŸÆÄÀÏ Ã³¸®¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    +
    +
    + + +MetaDir +CERN ¸ÞŸÁ¤º¸¸¦ ãÀ» µð·ºÅ丮 À̸§ +MetaDir directory +MetaDir .web +server config +virtual host +directory +.htaccess +Indexes + + +

    ¾ÆÆÄÄ¡°¡ ¸ÞŸÁ¤º¸ ÆÄÀÏÀ» ãÀ» µð·ºÅ丮¸íÀ» ÁöÁ¤ÇÑ´Ù. + µð·ºÅ丮´Â º¸Åë Á¢±ÙÇÒ ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮ÀÇ '°¨ÃçÁø' + ÇÏÀ§µð·ºÅ丮´Ù. "."À¸·Î ÁöÁ¤ÇÏ¸é °°Àº µð·ºÅ丮¿¡¼­ + ÆÄÀÏÀ» ã´Â´Ù:

    + + MetaDir . + +

    ¾Æ´Ï¸é ÆÄÀÏÀÌ ÀÖ´Â ÇÏÀ§µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù:

    + + MetaDir .meta +
    +
    + + +MetaSuffix +CERN ¸ÞŸÁ¤º¸¸¦ ÀúÀåÇÏ´Â ÆÄÀÏÀÇ Á¢¹Ì»ç +MetaSuffix suffix +MetaSuffix .meta +server config +virtual host +directory +.htaccess +Indexes + + +

    ¸ÞŸÁ¤º¸¸¦ ÀúÀåÇÏ´Â ÆÄÀÏÀÇ Á¢¹Ì»ç¸¦ ÁöÁ¤ÇÑ´Ù. ¿¹¸¦ µé¾î, + µÎ Áö½Ã¾îÀÇ ±âº»°ªÀ» »ç¿ëÇÒ °æ¿ì + DOCUMENT_ROOT/somedir/index.htmlÀ» ¿äûÇϸé + DOCUMENT_ROOT/somedir/.web/index.html.metaÀÇ + ³»¿ëÀ» Âü°íÇÏ¿© MIME Çì´õ Á¤º¸¸¦ Ãß°¡ÇÑ´Ù.

    + + ¿¹Á¦: + MetaSuffix .meta + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_cern_meta.xml.meta b/trunk/docs/manual/mod/mod_cern_meta.xml.meta new file mode 100644 index 0000000000..7ede4771e1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cern_meta.xml.meta @@ -0,0 +1,12 @@ + + + + mod_cern_meta + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_cgi.html b/trunk/docs/manual/mod/mod_cgi.html new file mode 100644 index 0000000000..7970a36c34 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.html @@ -0,0 +1,11 @@ +URI: mod_cgi.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_cgi.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_cgi.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_cgi.html.en b/trunk/docs/manual/mod/mod_cgi.html.en new file mode 100644 index 0000000000..e2f0d82269 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.html.en @@ -0,0 +1,247 @@ + + + +mod_cgi - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_cgi

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Execution of CGI scripts
    Status:Base
    Module Identifier:cgi_module
    Source File:mod_cgi.c
    +

    Summary

    + + + +

    Any file that has the mime type + application/x-httpd-cgi or handler + cgi-script (Apache 1.1 or later) will be treated + as a CGI script, and run by the server, with its output being + returned to the client. Files acquire this type either by + having a name containing an extension defined by the + AddType directive, or by being + in a ScriptAlias + directory.

    + +

    When the server invokes a CGI script, it will add a variable + called DOCUMENT_ROOT to the environment. This + variable will contain the value of the + DocumentRoot configuration + variable.

    + +

    For an introduction to using CGI scripts with Apache, see + our tutorial on Dynamic Content + With CGI.

    + +

    When using a multi-threaded MPM under unix, the module + mod_cgid should be used in place of + this module. At the user level, the two modules are essentially + identical.

    +
    + +
    top
    +
    +

    CGI Environment variables

    +

    The server will set the CGI environment variables as described + in the CGI + specification, with the following provisions:

    + +
    +
    PATH_INFO
    + +
    This will not be available if the AcceptPathInfo directive is explicitly set to + off. The default behavior, if AcceptPathInfo is not given, is that mod_cgi will accept path info (trailing + /more/path/info following the script filename in the URI), + while the core server will return a 404 NOT FOUND error for requests + with additional path info. Omitting the AcceptPathInfo directive has the same effect as setting + it On for mod_cgi requests.
    + +
    REMOTE_HOST
    + +
    This will only be set if HostnameLookups is set to on (it + is off by default), and if a reverse DNS lookup of the accessing + host's address indeed finds a host name.
    + +
    REMOTE_IDENT
    + +
    This will only be set if IdentityCheck is set to + on and the accessing host supports the ident + protocol. Note that the contents of this variable cannot be + relied upon because it can easily be faked, and if there is a + proxy between the client and the server, it is usually + totally useless.
    + +
    REMOTE_USER
    + +
    This will only be set if the CGI script is subject to + authentication.
    +
    +
    top
    +
    +

    CGI Debugging

    +

    Debugging CGI scripts has traditionally been difficult, mainly + because it has not been possible to study the output (standard + output and error) for scripts which are failing to run + properly. These directives, included in Apache 1.2 and later, + provide more detailed logging of errors when they occur.

    + +

    CGI Logfile Format

    +

    When configured, the CGI error log logs any CGI which does not + execute properly. Each CGI script which fails to operate causes + several lines of information to be logged. The first two lines + are always of the format:

    + +

    + %% [time] request-line
    + %% HTTP-status CGI-script-filename +

    + +

    If the error is that CGI script cannot be run, the log file + will contain an extra two lines:

    + +

    + %%error
    + error-message +

    + +

    Alternatively, if the error is the result of the script + returning incorrect header information (often due to a bug in + the script), the following information is logged:

    + +

    + %request
    + All HTTP request headers received
    + POST or PUT entity (if any)
    + %response
    + All headers output by the CGI script
    + %stdout
    + CGI standard output
    + %stderr
    + CGI standard error
    +

    + +

    (The %stdout and %stderr parts may be missing if the script did + not output anything on standard output or standard error).

    + +
    +
    top
    +

    ScriptLog Directive

    + + + + + + +
    Description:Location of the CGI script error logfile
    Syntax:ScriptLog file-path
    Context:server config, virtual host
    Status:Base
    Module:mod_cgi, mod_cgid
    +

    The ScriptLog directive sets the CGI + script error logfile. If no ScriptLog is given, + no error log is created. If given, any CGI errors are logged into the + filename given as argument. If this is a relative file or path it is + taken relative to the ServerRoot. +

    + +

    Example

    + ScriptLog logs/cgi_log +

    + +

    This log will be opened as the user the child processes run + as, i.e. the user specified in the main User directive. This means that + either the directory the script log is in needs to be writable + by that user or the file needs to be manually created and set + to be writable by that user. If you place the script log in + your main logs directory, do NOT change the + directory permissions to make it writable by the user the child + processes run as.

    + +

    Note that script logging is meant to be a debugging feature + when writing CGI scripts, and is not meant to be activated + continuously on running servers. It is not optimized for speed + or efficiency, and may have security problems if used in a + manner other than that for which it was designed.

    + +
    +
    top
    +

    ScriptLogBuffer Directive

    + + + + + + + +
    Description:Maximum amount of PUT or POST requests that will be recorded +in the scriptlog
    Syntax:ScriptLogBuffer bytes
    Default:ScriptLogBuffer 1024
    Context:server config, virtual host
    Status:Base
    Module:mod_cgi, mod_cgid
    +

    The size of any PUT or POST entity body that is logged to + the file is limited, to prevent the log file growing too big + too quickly if large bodies are being received. By default, up + to 1024 bytes are logged, but this can be changed with this + directive.

    + +
    +
    top
    +

    ScriptLogLength Directive

    + + + + + + + +
    Description:Size limit of the CGI script logfile
    Syntax:ScriptLogLength bytes
    Default:ScriptLogLength 10385760
    Context:server config, virtual host
    Status:Base
    Module:mod_cgi, mod_cgid
    +

    ScriptLogLength can be used to limit the + size of the CGI script logfile. Since the logfile logs a lot of + information per CGI error (all request headers, all script output) + it can grow to be a big file. To prevent problems due to unbounded + growth, this directive can be used to set an maximum file-size for + the CGI logfile. If the file exceeds this size, no more + information will be written to it.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgi.html.ja.euc-jp b/trunk/docs/manual/mod/mod_cgi.html.ja.euc-jp new file mode 100644 index 0000000000..fa17a7672e --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.html.ja.euc-jp @@ -0,0 +1,254 @@ + + + +mod_cgi - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_cgi

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:cgi_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_cgi.c
    +

    ³µÍ×

    + + + +

    Mime ¥¿¥¤¥×¤¬ application/x-httpd-cgi + ¤Ç¤¢¤ë¤«¡¢¥Ï¥ó¥É¥é cgi-script (Apache 1.1 °Ê¹ß) + ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Ï CGI ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ°·¤ï¤ì¡¢ + ¥µ¡¼¥Ð¤Ë¤è¤ê¼Â¹Ô¤µ¤ì¡¢¤½¤Î½ÐÎϤ¬¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¤Ï¡¢AddType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë»ØÄꤵ¤ì¤¿ ³ÈÄ¥»Ò¤ò̾Á°¤Ë´Þ¤à¤«¡¢ + ScriptAlias + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¸ºß¤¹¤ë¤³¤È¤Ë¤è¤ê¤³¤Î¥¿¥¤¥×¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤¬ CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë¤È¤­¤Ë¤Ï¡¢ + DOCUMENT_ROOT + ¤È¸Æ¤Ð¤ì¤ëÊÑ¿ô¤ò´Ä¶­¤ËÄɲä·¤Þ¤¹¡£¤³¤ÎÊÑ¿ô¤Ï + DocumentRoot + ¤ÎÃͤòÊÝ»ý¤·¤Þ¤¹¡£

    + +

    Apache ¤Ç CGI ¥¹¥¯¥ê¥×¥È¤ò»ÈÍѤ¹¤ë¤¿¤á¤Î¥¤¥ó¥È¥í¥À¥¯¥·¥ç¥ó¤Ï¡¢ + CGI ¤Ë¤è¤ëưŪ¥³¥ó¥Æ¥ó¥Ä + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Unix ¤Ç¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤Î MPM ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Î + Âå¤ï¤ê¤Ë mod_cgid ¤ò»È¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¥æ¡¼¥¶¥ì¥Ù¥ë¤Ç¤Ï¤³¤ÎÆó¤Ä¤Î¥â¥¸¥å¡¼¥ë¤ÏËܼÁŪ¤Ë¤ÏƱ°ì¤Ç¤¹¡£

    +
    + +
    top
    +
    +

    CGI ´Ä¶­ÊÑ¿ô

    +

    ¥µ¡¼¥Ð¤Ï CGI + µ¬³Ê ¤Ç·è¤á¤é¤ì¤Æ¤¤¤ë CGI + ´Ä¶­ÊÑ¿ô¤òÀßÄꤷ¤Þ¤¹¡£°Ê²¼¤Î¤â¤Î¤Ï¡¢¾ò·ïÉÕ¤­¤ÇÀßÄꤵ¤ì¤Þ¤¹¡£

    + +
    +
    PATH_INFO
    + +
    ¤³¤ì¤Ï AcceptPathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ÌÀ¼¨Åª¤Ë off + ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤ÏÀßÄꤵ¤ì¤Þ¤»¤ó¡£¥Ç¥Õ¥©¥ë¥È¤Î¡¢ + AcceptPathInfo ¤¬ + »ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Î¿¶¤ëÉñ¤¤¤Ç¤Ï¡¢mod_cgi ¤Ï¥Ñ¥¹¾ðÊó + (URI ¤Î¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾¤Î¸å¤Ë³¤¯ /more/path/info) ¤ò + ¼õ¤±ÉÕ¤±¤Þ¤¹¤¬¡¢¥³¥¢¤Ï¥µ¡¼¥Ð¤Ï¥Ñ¥¹¾ðÊó¤Î¤¢¤ë¥ê¥¯¥¨¥¹¥È¤Ë + ÂФ·¤Æ 404 NOT FOUND ¥¨¥é¡¼¤òÊÖ¤·¤Þ¤¹¡£AcceptPathInfo + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ¾Êά¤¹¤ë¤È¡¢mod_cgi ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + On ¤ò + ÀßÄꤷ¤¿¤Î¤ÈƱ¤¸¸ú²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£
    + +
    REMOTE_HOST
    + +
    HostnameLookups + ¤¬ on (¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï off ¤Ç¤¹) + ¤Ç¡¢¥¢¥¯¥»¥¹¤·¤Æ¤¤¤ë¥Û¥¹¥È¤Î¥¢¥É¥ì¥¹¤Î DNS + ¤ÎµÕ°ú¤­¤¬¼ÂºÝ¤Ë¥Û¥¹¥È̾¤ò¸«¤Ä¤±¤¿¤È¤­¤Ë¤Î¤ßÀßÄꤵ¤ì¤Þ¤¹¡£
    + +
    REMOTE_IDENT
    + +
    IdentityCheck + ¤¬ on ¤ËÀßÄꤵ¤ì¤Æ¤¤¤Æ¡¢¥¢¥¯¥»¥¹¤·¤Æ¤¤¤ë¥Û¥¹¥È¤¬ + ident ¥×¥í¥È¥³¥ë¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤È¤­¤Ë¤Î¤ßÀßÄꤵ¤ì¤Þ¤¹¡£ + ¤³¤ì¤Ï´Êñ¤Ëµ¶¤ë¤³¤È¤¬¤Ç¤­¡¢¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð¤Î´Ö¤Ë + ¥×¥í¥­¥·¤¬¤¢¤ì¤Ð¤Þ¤Ã¤¿¤¯Ìò¤ËΩ¤¿¤Ê¤¤¤Î¤Ç¡¢ + ¤³¤ÎÊÑ¿ô¤ÎÃͤϿ®ÍѤǤ­¤Ê¤¤¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    + +
    REMOTE_USER
    + +
    CGI + ¥¹¥¯¥ê¥×¥È¤Ëǧ¾Ú¤¬É¬ÍפʤȤ­¤Ë¤Î¤ßÀßÄꤵ¤ì¤Þ¤¹¡£
    +
    +
    top
    +
    +

    CGI ¤Î¥Ç¥Ð¥Ã¥°

    +

    CGI ¥¹¥¯¥ê¥×¥È¤Î¥Ç¥Ð¥Ã¥°¤Ï¡¢Àµ¤·¤¯Æ°ºî¤·¤Æ¤¤¤Ê¤¤¥¹¥¯¥ê¥×¥È¤Î½ÐÎÏ + (ɸ½à½ÐÎϤȥ¨¥é¡¼) + ¤òÄ´¤Ù¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤¿¤á¤Ë¡¢Æñ¤·¤¤¾õÂÖ¤¬Â³¤¤¤Æ¤¤¤Þ¤·¤¿¡£ + ¤³¤ì¤é¤Î Apache 1.2 °Ê¹ß¤Ë¤¢¤ë + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤è¤ê¾ÜºÙ¤Ê¥¨¥é¡¼¤Î¥í¥°¼ý½¸¤òÄ󶡤·¤Þ¤¹¡£

    + +

    CGI ¥í¥°¥Õ¥¡¥¤¥ë¤Î½ñ¼°

    +

    ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ë¤Ï¡¢CGI ¥¨¥é¡¼¥í¥°¤ÏŬÀÚ¤ËÆ°ºî¤·¤Ê¤¤¤¹¤Ù¤Æ¤Î + CGI ¤ò¥í¥°¼ý½¸¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤ÎÀµ¤·¤¯Æ°ºî¤·¤Ê¤¤ CGI + ¥¹¥¯¥ê¥×¥È¤Ï Ê£¿ô¤Î¹Ô¤Ë¤ï¤¿¤ë¾ðÊó¤¬¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£ºÇ½é¤Î + 2 ¹Ô¤Ï¾ï¤Ë°Ê²¼¤Î½ñ¼°¤Ç¤¹:

    + +

    + %% [time] request-line
    + %% HTTP-status CGI-script-filename +

    + +

    ¥¨¥é¡¼¤¬¡¢CGI ¥¹¥¯¥ê¥×¥È¤¬¼Â¹Ô¤Ç¤­¤Ê¤¤¤È¤¤¤¦¤â¤Î¤Ç¤¢¤ë¾ì¹ç¤Ï¡¢ + ¥í¥°¥Õ¥¡¥¤¥ë¤Ï¤µ¤é¤Ë¤â¤¦ 2 ¹Ô½ñ¤«¤ì¤Þ¤¹:

    + +

    + %%error
    + error-message +

    + +

    ¤½¤¦¤Ç¤Ï¤Ê¤¯¡¢¥¨¥é¡¼¤¬Àµ¤·¤¯¤Ê¤¤¥Ø¥Ã¥À¾ðÊó¤òÊÖ¤¹·ë²Ì¤Ç¤¢¤ë¾ì¹ç + (¥¹¥¯¥ê¥×¥È¤Î¥Ð¥°¤Ç¤¢¤ë¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹)¡¢ + °Ê²¼¤Î¾ðÊó¤¬¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹:

    + +

    + %request
    + ¼õ¤±¼è¤Ã¤¿¤¹¤Ù¤Æ¤Î HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À
    + (¤â¤·¤¢¤ì¤Ð) POST ¤ä PUT ¤ÎÃæ¿È
    + %response
    + CGI ¥¹¥¯¥ê¥×¥È¤Ë¤è¤ê½ÐÎϤµ¤ì¤¿¤¹¤Ù¤Æ¤Î¥Ø¥Ã¥À
    + %stdout
    + CGI ɸ½à½ÐÎÏ
    + %stderr
    + CGI ɸ½à¥¨¥é¡¼
    +

    + +

    (¥¹¥¯¥ê¥×¥È¤¬É¸½à½ÐÎϤäɸ½à¥¨¥é¡¼¤Ë²¿¤â½ÐÎϤ·¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ + %stdout ¤ä %stderr ¤Ï¤¢¤ê¤Þ¤»¤ó)¡£

    + +
    +
    top
    +

    ScriptLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥È¤Î¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤Î¾ì½ê
    ¹½Ê¸:ScriptLog file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_cgi, mod_cgid
    +

    ScriptLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï CGI ¥¹¥¯¥ê¥×¥È¤Î + ¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤òÀßÄꤷ¤Þ¤¹¡£ScriptLog ¤¬ + ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ + ¥¨¥é¡¼¥í¥°¤ÏºîÀ®¤µ¤ì¤Þ¤»¤ó¡£ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢CGI + ¤Î¥¨¥é¡¼¤Ï¤¹¤Ù¤Æ°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë̾¤Ë¥í¥°¤µ¤ì¤Þ¤¹¡£ + ÁêÂХѥ¹¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + ServerRoot¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ + °·¤ï¤ì¤Þ¤¹¡£

    + +

    Îã

    + ScriptLog logs/cgi_log +

    + +

    ¤³¤Î¥í¥°¤Ï»Ò¥×¥í¥»¥¹¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¥æ¡¼¥¶¤È¤·¤Æ¥ª¡¼¥×¥ó¤µ¤ì¤Þ¤¹¡£ + ¤¹¤Ê¤ï¤Á¡¢User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿ + ¥æ¡¼¥¶¤Ç¤¹¡£¤³¤ì¤Ï¡¢¥¹¥¯¥ê¥×¥È¥í¥°¤¬½ñ¤«¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤¬¤½¤Î¥æ¡¼¥¶¤Ç + ½ñ¤­¹þ¤ß²Äǽ¤«¡¢¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤¬¼êÆ°¤ÇºîÀ®¤µ¤ì¡¢¤½¤Î¥æ¡¼¥¶¤Ç + ½ñ¤­¹þ¤ß²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥¹¥¯¥ê¥×¥È¥í¥°¤ò + ¥¢¥¯¥»¥¹¥í¥°¤Ê¤É¤Î¤¿¤á¤Î¥í¥°¥Ç¥£¥ì¥¯¥È¥ê¤Ë½ñ¤«¤ì¤ë¤è¤¦¤Ë¤·¤¿¤È¤­¤Ï¡¢ + ¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò»Ò¥×¥í¥»¥¹¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥æ¡¼¥¶¤Î¸¢¸Â¤Ç + ½ñ¤­¹þ¤ß²Äǽ¤Ë¤Ï¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥¹¥¯¥ê¥×¥È¤Î¥í¥°¼ý½¸¤Ï CGI ¥¹¥¯¥ê¥×¥È¤ò½ñ¤¯¤È¤­¤Î + ¥Ç¥Ð¥Ã¥°ÍѤε¡Ç½¤È¤·¤Æ°Õ¿Þ¤µ¤ì¤Æ¤¤¤Æ¡¢Ä̾ï¤Î¥µ¡¼¥Ð¤Ç + ¾ï¤Ë»ÈÍѤµ¤ì¤ë¤è¤¦¤Ë¤Ï°Õ¿Þ¤µ¤ì¤Æ¤¤¤Ê¤¤¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ®ÅÙ¤ä¸úΨ¤ÏºÇŬ²½¤µ¤ì¤Æ¤ª¤é¤º¡¢À߷פµ¤ì¤¿°Ê³°¤ÎÊýË¡¤Ç»ÈÍѤµ¤ì¤ë¤È + ¥»¥­¥å¥ê¥Æ¥£¤ÎÌäÂ꤬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    ScriptLogBuffer ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¹¥¯¥ê¥×¥È¥í¥°¤Ëµ­Ï¿¤µ¤ì¤ë PUT ¤ä POST ¥ê¥¯¥¨¥¹¥È¤ÎÆâÍƤξå¸Â
    ¹½Ê¸:ScriptLogBuffer bytes
    ¥Ç¥Õ¥©¥ë¥È:ScriptLogBuffer 1024
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_cgi, mod_cgid
    +

    Â礭¤ÊËÜÂΤò¼õ¤±¼è¤Ã¤¿¤È¤­¤Ë¥í¥°¥Õ¥¡¥¤¥ë¤¬¤¹¤°¤ËÂ礭¤¯¤Ê¤ê¤¹¤®¤ë + ÌäÂê¤òÈò¤±¤ë¤¿¤á¤Ë¡¢¥Õ¥¡¥¤¥ë¤Ë¥í¥°¼ý½¸¤µ¤ì¤ë PUT ¤È POST + ¤ÎËÜÂΤÎÂ礭¤µ¤ÏÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢1024 + ¥Ð¥¤¥È¤Þ¤Ç¤¬¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¤¬¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤ì¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    + +
    +
    top
    +

    ScriptLogLength ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥È¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤Î¾å¸Â
    ¹½Ê¸:ScriptLogLength bytes
    ¥Ç¥Õ¥©¥ë¥È:ScriptLogLength 10385760
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_cgi, mod_cgid
    +

    ScriptLogLength ¤Ï CGI ¥¹¥¯¥ê¥×¥È¤Î¥í¥°¥Õ¥¡¥¤¥ë + ¤ÎÂ礭¤µ¤òÀ©¸Â¤¹¤ë¤¿¤á¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥í¥°¥Õ¥¡¥¤¥ë¤Ï + CGI ¤Î¥¨¥é¡¼Ëè¤ËÂçÎ̤ξðÊó (¥ê¥¯¥¨¥¹¥È¤Î¤¹¤Ù¤Æ¤Î¥Ø¥Ã¥À¡¢ + ¤¹¤Ù¤Æ¤Î½ÐÎÏ)¤ò¥í¥°¤·¤Þ¤¹¤Î¤Ç¡¢¤¹¤°¤ËÂ礭¤Ê¥Õ¥¡¥¤¥ë¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤ÎÂ礭¤µ¤ÎÀ©¸Â¤¬¤Ê¤¤¤³¤È¤Ë¤è¤ëÌäÂê¤òËɤ°¤¿¤á¤Ë¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ CGI ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Î + ºÇÂç¤Î¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¤¬¤³¤ÎÂ礭¤µ¤òĶ¤¨¤¿¾ì¹ç¤Ï¡¢¤½¤ì°Ê¾å¤Ï½ñ¤­¹þ¤Þ¤ì¤Þ¤»¤ó¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgi.html.ko.euc-kr b/trunk/docs/manual/mod/mod_cgi.html.ko.euc-kr new file mode 100644 index 0000000000..e26d6c4b6b --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.html.ko.euc-kr @@ -0,0 +1,234 @@ + + + +mod_cgi - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_cgi

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:CGI ½ºÅ©¸³Æ® ½ÇÇà
    »óÅÂ:Base
    ¸ðµâ¸í:cgi_module
    ¼Ò½ºÆÄÀÏ:mod_cgi.c
    +

    ¿ä¾à

    + + + +

    ¼­¹ö´Â mime typeÀÌ application/x-httpd-cgiÀ̰ųª + (¾ÆÆÄÄ¡ 1.1 ÀÌÈÄ) Çڵ鷯°¡ cgi-scriptÀÎ ¸ðµç + ÆÄÀÏÀ» CGI ½ºÅ©¸³Æ®·Î ÀνÄÇÏ¿©, ½ÇÇàÇÏ°í, ±× °á°ú¸¦ Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³½´Ù. ÆÄÀÏÀÌ AddType + Áö½Ã¾î·Î ÁöÁ¤ÇÑ È®ÀåÀÚ¸¦ °¡Áö°Å³ª, ScriptAlias µð·ºÅ丮 ¾È¿¡ + ÀÖÀ¸¸é CGI·Î 󸮵ȴÙ.

    + +

    ¼­¹ö´Â CGI ½ºÅ©¸³Æ®¸¦ ºÎ¸¦¶§ DOCUMENT_ROOT¶ó´Â + ȯ°æº¯¼ö¸¦ Ãß°¡ÇÑ´Ù. ÀÌ º¯¼ö´Â DocumentRoot ¼³Á¤°ªÀ» °¡Áø´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡¼­ CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇÑ ¼Ò°³´Â + CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º ÅõÅ丮¾óÀ» + Âü°íÇ϶ó.

    + +

    À¯´Ð½º¿¡¼­ ´ÙÁß¾²·¹µå MPMÀ» »ç¿ëÇÑ´Ù¸é ÀÌ ¸ðµâ´ë½Å + mod_cgid ¸ðµâÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. »ç¿ëÀÚ + ÀÔÀå¿¡¼­ ÀÌ µÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î µ¿ÀÏÇÏ´Ù.

    +
    + +
    top
    +
    +

    CGI ȯ°æº¯¼ö

    +

    ¼­¹ö´Â ´ÙÀ½°ú °°Àº ¹æ¹ýÀ¸·Î CGI Ç¥ÁØÀÌ ¼³¸íÇÏ´Â + CGI ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù:

    + +
    +
    PATH_INFO
    + +
    ÀÌ º¯¼ö´Â AcceptPathInfo Áö½Ã¾î¸¦ Á÷Á¢ off·Î + ÁöÁ¤ÇÑ °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù. AcceptPathInfo°¡ ¾ø´Â °æ¿ì ¼­¹ö´Â ±âº»ÀûÀ¸·Î + °æ·Î Á¤º¸°¡ ÀÖ´Â ¿äû¿¡ ´ëÇØ 404 NOT FOUND ¿À·ù¸¦ ³»Áö¸¸, + mod_cgi´Â °æ·Î Á¤º¸¸¦ (URI¿¡¼­ ½ºÅ©¸³Æ® + ÆÄÀÏ¸í µÚ¿¡ ³ª¿À´Â /more/path/info) ¹Þ´Â´Ù. + AcceptPathInfo Áö½Ã¾î¸¦ »ý·«Çϸé + mod_cgi ¿äû¿¡ ´ëÇؼ­ AcceptPathInfo¸¦ OnÀ¸·Î + ¼³Á¤ÇÑ °Í°ú °°´Ù.
    + +
    REMOTE_HOST
    + +
    ÀÌ º¯¼ö´Â HostnameLookups°¡ onÀÌ°í (±âº»°ªÀº + off), Á¢¼ÓÇÑ È£½ºÆ® ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ½ÇÁ¦ È£½ºÆ®¸íÀ» + ãÀº °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù.
    + +
    REMOTE_IDENT
    + +
    ÀÌ º¯¼ö´Â IdentityCheck°¡ onÀÌ°í, Á¢¼ÓÇÑ + È£½ºÆ®°¡ ident ÇÁ·ÎÅäÄÝÀ» Áö¿øÇÏ´Â °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù. + ½±°Ô ÀÌ °ªÀ» ¼ÓÀÏ ¼ö Àֱ⶧¹®¿¡ ÀÌ º¯¼öÀÇ ³»¿ëÀ» ¹ÏÀ¸¸é + ¾ÈµÇ°í, Ŭ¶óÀ̾ðÆ®¿Í ¼­¹ö »çÀÌ¿¡ ÇÁ·Ï½Ã°¡ ÀÖ´Ù¸é º¯¼ö + ³»¿ëÀÌ ¿ÏÀüÈ÷ ¹«ÀǹÌÇÔÀ» ÁÖÀÇÇ϶ó.
    + +
    REMOTE_USER
    + +
    CGI ½ºÅ©¸³Æ®°¡ ÀÎÁõÀ» °ÅÃľßÇÏ´Â °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù.
    +
    +
    top
    +
    +

    CGI µð¹ö±ë

    +

    ¾îµð¿¡¼­ À߸ø ½ÇÇàµÇ´ÂÁö ½ºÅ©¸³Æ®ÀÇ Ãâ·ÂÀ» (Ç¥ÁØÃâ·Â°ú + Ç¥ÁØ¿À·ù) º¼ ¼ö ¾ø±â¶§¹®¿¡ CGI ½ºÅ©¸³Æ®´Â ÀüÅëÀûÀ¸·Î µð¹ö±ëÇϱâ + ¾î·Á¿ü´Ù. ¾ÆÆÄÄ¡ 1.2 ÀÌÈÄ¿¡ Ãß°¡µÈ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¹ß»ýÇÑ + ¿À·ù¸¦ ÀÚ¼¼È÷ ·Î±×¿¡ ³²±æ ¼ö ÀÖ´Ù.

    + +

    CGI ·Î±×ÆÄÀÏ Çü½Ä

    +

    CGI ¿À·ù·Î±×´Â Á¤»óÀûÀ¸·Î ½ÇÇàÇÏÁö ¸øÇÑ CGI¸¦ ±â·ÏÇÑ´Ù. + ¿À·ù°¡ ¹ß»ýÇÑ CGI ½ºÅ©¸³Æ®´Â ·Î±×¿¡ ¿©·¯ ÁÙÀÇ Á¤º¸¸¦ ³²±ä´Ù. + ù¹ø° µÎ ÁÙÀº Ç×»ó ¾Æ·¡¿Í °°Àº Çü½ÄÀÌ´Ù:

    + +

    + %% [½Ã°£] ¿äûÁÙ
    + %% HTTP-»óÅ CGI-½ºÅ©¸³Æ®-ÆÄÀϸí +

    + +

    CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÒ ¼ö ¾ø´Â ¿À·ùÀÎ °æ¿ì ·Î±×ÆÄÀÏ¿¡ + Ãß°¡·Î µÎ ÁÙÀ» ´õ ±â·ÏÇÑ´Ù:

    + +

    + %%error
    + ¿À·ù¹® +

    + +

    ½ºÅ©¸³Æ®°¡ (º¸Åë ½ºÅ©¸³Æ®ÀÇ ¹ö±×¶§¹®¿¡) À߸øµÈ Çì´õ + Á¤º¸¸¦ ¹ÝȯÇÏ´Â °æ¿ì, ´ÙÀ½ ³»¿ëÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù:

    + +

    + %request
    + ¹ÞÀº ¸ðµç HTTP Çì´õ
    + (ÀÖ´Ù¸é) POST³ª PUT ³»¿ë
    + %response
    + CGI ½ºÅ©¸³Æ® Ãâ·ÂÀÇ ¸ðµç Çì´õ
    + %stdout
    + CGI Ç¥ÁØÃâ·Â
    + %stderr
    + CGI Ç¥ÁØ¿À·ù
    +

    + +

    (½ºÅ©¸³Æ®°¡ Ç¥ÁØÃâ·ÂÀ̳ª Ç¥ÁØ¿À·ù¿¡ ¾Æ¹« ³»¿ëµµ Ãâ·ÂÇÏÁö + ¾Ê¾Ò´Ù¸é %stdout°ú %stderr ºÎºÐÀº »ý·«µÉ ¼ö ÀÖ´Ù).

    + +
    +
    top
    +

    ScriptLog Áö½Ã¾î

    + + + + + + +
    ¼³¸í:CGI ½ºÅ©¸³Æ® ¿À·ù·Î±×ÆÄÀÏÀÇ À§Ä¡
    ¹®¹ý:ScriptLog file-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_cgi, mod_cgid
    +

    ScriptLog Áö½Ã¾î´Â CGI ½ºÅ©¸³Æ® + ¿À·ù·Î±×ÆÄÀÏÀ» ÁöÁ¤ÇÑ´Ù. ScriptLog¸¦ + »ç¿ëÇÏÁö¾ÊÀ¸¸é ¿À·ù·Î±×¸¦ ¸¸µéÁö ¾Ê´Â´Ù. »ç¿ëÇÏ¸é ¾Æ±Ô¸ÕÆ®·Î + ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ CGI ¿À·ù¸¦ ±â·ÏÇÑ´Ù. »ó´ë°æ·Î¸¦ ÁöÁ¤Çϸé + ServerRoot¿¡ »ó´ë°æ·Î·Î + ¹Þ¾ÆµéÀδÙ. +

    + +

    ¿¹Á¦

    + ScriptLog logs/cgi_log +

    + +

    ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ, Áï User Áö½Ã¾î·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ·Î±×¸¦ ¿¬´Ù. ±×·¡¼­ ±× »ç¿ëÀÚ°¡ ½ºÅ©¸³Æ® ·Î±×°¡ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ ÀÖ´øÁö, Á÷Á¢ ¹Ì¸® ÆÄÀÏÀ» ¸¸µé¾î¼­ + ±× »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀ» Áà¾ß ÇÑ´Ù. ½ºÅ©¸³Æ® ·Î±×¸¦ ÁÖ ·Î±× + µð·ºÅ丮¿¡ µÐ´Ù¸é ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀ» + ÁÖ±âÀ§ÇØ µð·ºÅ丮 ±ÇÇÑÀ» º¯°æÇÏÁö ¸¶¶ó.

    + +

    ½ºÅ©¸³Æ® ·Î±×´Â CGI ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÒ¶§ µð¹ö±ëÀ» À§ÇÑ + ¿ëµµÀÌÁö ¼­¹ö¸¦ ½ÇÇàÇÏ´Â µ¿¾È °è¼Ó »ç¿ëÇϱâÀ§ÇÔÀÌ ¾Æ´ÔÀ» + ÁÖÀÇÇ϶ó. ¼Óµµ¿Í È¿À²¼º¸é¿¡¼­ ÃÖÀûÈ­°¡ ¾ÈµÇÀÖ°í, ¼³°èÇÑ + ¸ñÀûÀÌ¿ÜÀÇ ¹æ¹ýÀ¸·Î »ç¿ëÇÏ¸é º¸¾È»ó ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    + +
    +
    top
    +

    ScriptLogBuffer Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:½ºÅ©¸³Æ® ·Î±×¿¡ ±â·ÏÇÒ PUT ȤÀº POST ¿äûÀÇ ÃÖ´ë·®
    ¹®¹ý:ScriptLogBuffer bytes
    ±âº»°ª:ScriptLogBuffer 1024
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_cgi, mod_cgid
    +

    Å« ³»¿ëÀ» ¹Þ¾Æ¼­ ·Î±×ÆÄÀÏÀÌ ³Ê¹« »¡¸® Ä¿Áö´Â Çö»óÀ» ¸·±âÀ§ÇØ + ÆÄÀÏ¿¡ ±â·ÏÇÒ PUT ȤÀº POST ³»¿ëÀÇ Å©±â¸¦ Á¦ÇÑÇÑ´Ù. ±âº»ÀûÀ¸·Î + 1024 ¹ÙÀÌÆ®±îÁö ·Î±×¿¡ ±â·ÏÇÏÁö¸¸, ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    top
    +

    ScriptLogLength Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:CGI ½ºÅ©¸³Æ® ·Î±×ÆÄÀÏÀÇ Å©±â Á¦ÇÑ
    ¹®¹ý:ScriptLogLength bytes
    ±âº»°ª:ScriptLogLength 10385760
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_cgi, mod_cgid
    +

    ScriptLogLength´Â CGI ½ºÅ©¸³Æ® + ·Î±×ÆÄÀÏÀÇ Å©±â¸¦ Á¦ÇÑÇÑ´Ù. CGI ¿À·ù°¡ ¹ß»ýÇÒ¶§¸¶´Ù (¸ðµç + ¿äû Çì´õ, ¸ðµç ½ºÅ©¸³Æ® Ãâ·Â µî) ¸¹Àº Á¤º¸°¡ ·Î±×¿¡ + ±â·ÏµÇ±â¶§¹®¿¡ ÆÄÀÏÀÌ ¸Å¿ì Ä¿Áú ¼ö ÀÖ´Ù. ÆÄÀÏÀÌ ¹«ÇÑÈ÷ Ä¿Áö´Â + ¹®Á¦¸¦ ¸·±âÀ§ÇØ ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© CGI ·Î±×ÆÄÀÏÀÇ ÃÖ´ë + ÆÄÀÏÅ©±â¸¦ ¼³Á¤ÇÑ´Ù. ÆÄÀÏÀÇ Å©±â°¡ ¼³Á¤ÇÑ °ªÀ» ³ÑÀ¸¸é ´õ + ÀÌ»ó Á¤º¸¸¦ ±â·ÏÇÏÁö¾Ê´Â´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgi.xml b/trunk/docs/manual/mod/mod_cgi.xml new file mode 100644 index 0000000000..6f4158edf1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.xml @@ -0,0 +1,240 @@ + + + + + + + + + +mod_cgi +Execution of CGI scripts +Base +mod_cgi.c +cgi_module + + + + +

    Any file that has the mime type + application/x-httpd-cgi or handler + cgi-script (Apache 1.1 or later) will be treated + as a CGI script, and run by the server, with its output being + returned to the client. Files acquire this type either by + having a name containing an extension defined by the + AddType directive, or by being + in a ScriptAlias + directory.

    + +

    When the server invokes a CGI script, it will add a variable + called DOCUMENT_ROOT to the environment. This + variable will contain the value of the + DocumentRoot configuration + variable.

    + +

    For an introduction to using CGI scripts with Apache, see + our tutorial on Dynamic Content + With CGI.

    + +

    When using a multi-threaded MPM under unix, the module + mod_cgid should be used in place of + this module. At the user level, the two modules are essentially + identical.

    +
    + +AcceptPathInfo +Options +ScriptAlias +AddHandler +Running CGI programs under different + user IDs +CGI Specification + +
    CGI Environment variables +

    The server will set the CGI environment variables as described + in the CGI + specification, with the following provisions:

    + +
    +
    PATH_INFO
    + +
    This will not be available if the AcceptPathInfo directive is explicitly set to + off. The default behavior, if AcceptPathInfo is not given, is that mod_cgi will accept path info (trailing + /more/path/info following the script filename in the URI), + while the core server will return a 404 NOT FOUND error for requests + with additional path info. Omitting the AcceptPathInfo directive has the same effect as setting + it On for mod_cgi requests.
    + +
    REMOTE_HOST
    + +
    This will only be set if HostnameLookups is set to on (it + is off by default), and if a reverse DNS lookup of the accessing + host's address indeed finds a host name.
    + +
    REMOTE_IDENT
    + +
    This will only be set if IdentityCheck is set to + on and the accessing host supports the ident + protocol. Note that the contents of this variable cannot be + relied upon because it can easily be faked, and if there is a + proxy between the client and the server, it is usually + totally useless.
    + +
    REMOTE_USER
    + +
    This will only be set if the CGI script is subject to + authentication.
    +
    +
    + +
    CGI Debugging +

    Debugging CGI scripts has traditionally been difficult, mainly + because it has not been possible to study the output (standard + output and error) for scripts which are failing to run + properly. These directives, included in Apache 1.2 and later, + provide more detailed logging of errors when they occur.

    + +
    CGI Logfile Format +

    When configured, the CGI error log logs any CGI which does not + execute properly. Each CGI script which fails to operate causes + several lines of information to be logged. The first two lines + are always of the format:

    + + + %% [time] request-line
    + %% HTTP-status CGI-script-filename +
    + +

    If the error is that CGI script cannot be run, the log file + will contain an extra two lines:

    + + + %%error
    + error-message +
    + +

    Alternatively, if the error is the result of the script + returning incorrect header information (often due to a bug in + the script), the following information is logged:

    + + + %request
    + All HTTP request headers received
    + POST or PUT entity (if any)
    + %response
    + All headers output by the CGI script
    + %stdout
    + CGI standard output
    + %stderr
    + CGI standard error
    +
    + +

    (The %stdout and %stderr parts may be missing if the script did + not output anything on standard output or standard error).

    +
    +
    + + +ScriptLog +Location of the CGI script error logfile +ScriptLog file-path +server config +virtual host +mod_cgimod_cgid + + + +

    The ScriptLog directive sets the CGI + script error logfile. If no ScriptLog is given, + no error log is created. If given, any CGI errors are logged into the + filename given as argument. If this is a relative file or path it is + taken relative to the ServerRoot. +

    + + Example + ScriptLog logs/cgi_log + + +

    This log will be opened as the user the child processes run + as, i.e. the user specified in the main User directive. This means that + either the directory the script log is in needs to be writable + by that user or the file needs to be manually created and set + to be writable by that user. If you place the script log in + your main logs directory, do NOT change the + directory permissions to make it writable by the user the child + processes run as.

    + +

    Note that script logging is meant to be a debugging feature + when writing CGI scripts, and is not meant to be activated + continuously on running servers. It is not optimized for speed + or efficiency, and may have security problems if used in a + manner other than that for which it was designed.

    +
    +
    + + +ScriptLogLength +Size limit of the CGI script logfile +ScriptLogLength bytes +ScriptLogLength 10385760 +server config +virtual host +mod_cgimod_cgid + + + +

    ScriptLogLength can be used to limit the + size of the CGI script logfile. Since the logfile logs a lot of + information per CGI error (all request headers, all script output) + it can grow to be a big file. To prevent problems due to unbounded + growth, this directive can be used to set an maximum file-size for + the CGI logfile. If the file exceeds this size, no more + information will be written to it.

    +
    +
    + + +ScriptLogBuffer +Maximum amount of PUT or POST requests that will be recorded +in the scriptlog +ScriptLogBuffer bytes +ScriptLogBuffer 1024 +server config +virtual host +mod_cgimod_cgid + + + +

    The size of any PUT or POST entity body that is logged to + the file is limited, to prevent the log file growing too big + too quickly if large bodies are being received. By default, up + to 1024 bytes are logged, but this can be changed with this + directive.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_cgi.xml.ja b/trunk/docs/manual/mod/mod_cgi.xml.ja new file mode 100644 index 0000000000..969cc22514 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.xml.ja @@ -0,0 +1,245 @@ + + + + + + + + + +mod_cgi +CGI $B%9%/%j%W%H$N +Base +mod_cgi.c +cgi_module + + + + +

    Mime $B%?%$%W$,(B application/x-httpd-cgi + $B$G$"$k$+!"%O%s%I%i(B cgi-script (Apache 1.1 $B0J9_(B) + $B$,;XDj$5$l$F$$$k%U%!%$%k$O(B CGI $B%9%/%j%W%H$H$7$F07$o$l!"(B + $B%5!<%P$K$h$jAddType + $B%G%#%l%/%F%#%V$K;XDj$5$l$?(B $B3HD%;R$rL>A0$K4^$`$+!"(B + ScriptAlias + $B%G%#%l%/%H%j$KB8:_$9$k$3$H$K$h$j$3$N%?%$%W$K$J$j$^$9!#(B

    + +

    $B%5!<%P$,(B CGI $B%9%/%j%W%H$rDOCUMENT_ROOT + $B$H8F$P$l$kJQ?t$r4D6-$KDI2C$7$^$9!#$3$NJQ?t$O(B + DocumentRoot + $B$NCM$rJ];}$7$^$9!#(B

    + +

    Apache $B$G(B CGI $B%9%/%j%W%H$r;HMQ$9$k$?$a$N%$%s%H%m%@%/%7%g%s$O!"(B + CGI $B$K$h$kF0E*%3%s%F%s%D(B + $B$r;2>H$7$F$/$@$5$$!#(B

    + +

    Unix $B$G%^%k%A%9%l%C%I$N(B MPM $B$r;H$C$F$$$k>l9g$O!"$3$N%b%8%e!<%k$N(B + $BBe$o$j$K(B mod_cgid $B$r;H$&I,MW$,$"$j$^$9!#(B + $B%f!<%6%l%Y%k$G$O$3$NFs$D$N%b%8%e!<%k$OK\ +

    + +AcceptPathInfo +Options +ScriptAlias +AddHandler +CGI $B%W%m%0%i%`$rJL$N%f!<%6(B ID $B$G +CGI $B5,3J=q(B + +
    CGI $B4D6-JQ?t(B +

    $B%5!<%P$O(B CGI + $B5,3J(B $B$G7h$a$i$l$F$$$k(B CGI + $B4D6-JQ?t$r@_Dj$7$^$9!#0J2<$N$b$N$O!">r7oIU$-$G@_Dj$5$l$^$9!#(B

    + +
    +
    PATH_INFO
    + +
    $B$3$l$O(B AcceptPathInfo $B%G%#%l%/%F%#%V$,L@<(E*$K(B off + $B$K@_Dj$5$l$F$$$k>l9g$O@_Dj$5$l$^$;$s!#%G%U%)%k%H$N!"(B + AcceptPathInfo $B$,(B + $B;XDj$5$l$F$$$J$$$H$-$N?6$kIq$$$G$O!"(Bmod_cgi $B$O%Q%9>pJs(B + (URI $B$N%9%/%j%W%H$N%U%!%$%kL>$N8e$KB3$/(B /more/path/info) $B$r(B + $BpJs$N$"$k%j%/%(%9%H$K(B + $BBP$7$F(B 404 NOT FOUND $B%(%i!<$rJV$7$^$9!#(BAcceptPathInfo + $B%G%#%l%/%F%#%V$r(B + $B>JN,$9$k$H!"(Bmod_cgi $B$X$N%j%/%(%9%H$KBP$7$F(B + On $B$r(B + $B@_Dj$7$?$N$HF1$88z2L$K$J$j$^$9!#(B
    + +
    REMOTE_HOST
    + +
    HostnameLookups + $B$,(B on ($B%G%U%)%k%H$G$O(B off $B$G$9(B) + $B$G!"%"%/%;%9$7$F$$$k%[%9%H$N%"%I%l%9$N(B DNS + $B$N5U0z$-$,$r8+$D$1$?$H$-$K$N$_@_Dj$5$l$^$9!#(B
    + +
    REMOTE_IDENT
    + +
    IdentityCheck + $B$,(B on $B$K@_Dj$5$l$F$$$F!"%"%/%;%9$7$F$$$k%[%9%H$,(B + ident $B%W%m%H%3%k$r%5%]!<%H$7$F$$$k$H$-$K$N$_@_Dj$5$l$^$9!#(B + $B$3$l$O4JC1$K56$k$3$H$,$G$-!"%/%i%$%"%s%H$H%5!<%P$N4V$K(B + $B%W%m%-%7$,$"$l$P$^$C$?$/Lr$KN)$?$J$$$N$G!"(B + $B$3$NJQ?t$NCM$O?.MQ$G$-$J$$$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B +
    + +
    REMOTE_USER
    + +
    CGI + $B%9%/%j%W%H$KG'>Z$,I,MW$J$H$-$K$N$_@_Dj$5$l$^$9!#(B
    +
    +
    + +
    CGI $B$N%G%P%C%0(B +

    CGI $B%9%/%j%W%H$N%G%P%C%0$O!"@5$7$/F0:n$7$F$$$J$$%9%/%j%W%H$N=PNO(B + ($BI8=`=PNO$H%(%i!<(B) + $B$rD4$Y$k$3$H$,$G$-$J$$$?$a$K!"Fq$7$$>uBV$,B3$$$F$$$^$7$?!#(B + $B$3$l$i$N(B Apache 1.2 $B0J9_$K$"$k(B + $B%G%#%l%/%F%#%V$O$h$j>\:Y$J%(%i!<$N%m%0<}=8$rDs6!$7$^$9!#(B

    + +
    CGI $B%m%0%U%!%$%k$N=q<0(B +

    $B@_Dj$5$l$F$$$k$H$-$K$O!"(BCGI $B%(%i!<%m%0$OE,@Z$KF0:n$7$J$$$9$Y$F$N(B + CGI $B$r%m%0<}=8$7$^$9!#$=$l$>$l$N@5$7$/F0:n$7$J$$(B CGI + $B%9%/%j%W%H$O(B $BJ#?t$N9T$K$o$?$k>pJs$,%m%0<}=8$5$l$^$9!#:G=i$N(B + 2 $B9T$O>o$K0J2<$N=q<0$G$9(B:

    + + + %% [time] request-line
    + %% HTTP-status CGI-script-filename +
    + +

    $B%(%i!<$,!"(BCGI $B%9%/%j%W%H$,l9g$O!"(B + $B%m%0%U%!%$%k$O$5$i$K$b$&(B 2 $B9T=q$+$l$^$9(B:

    + + + %%error
    + error-message +
    + +

    $B$=$&$G$O$J$/!"%(%i!<$,@5$7$/$J$$%X%C%@>pJs$rJV$97k2L$G$"$k>l9g(B + ($B%9%/%j%W%H$N%P%0$G$"$k$3$H$,$h$/$"$j$^$9(B)$B!"(B + $B0J2<$N>pJs$,%m%0<}=8$5$l$^$9(B:

    + + + %request
    + $B
    + ($B$b$7$"$l$P(B) POST $B$d(B PUT $B$NCf?H(B
    + %response
    + CGI $B%9%/%j%W%H$K$h$j=PNO$5$l$?$9$Y$F$N%X%C%@(B
    + %stdout
    + CGI $BI8=`=PNO(B
    + %stderr
    + CGI $BI8=`%(%i!<(B
    +
    + +

    ($B%9%/%j%W%H$,I8=`=PNO$dI8=`%(%i!<$K2?$b=PNO$7$J$+$C$?>l9g$O!"(B + %stdout $B$d(B %stderr $B$O$"$j$^$;$s(B)$B!#(B

    +
    +
    + + +ScriptLog +CGI $B%9%/%j%W%H$N%(%i!<%m%0%U%!%$%k$N>l=j(B +ScriptLog file-path +server config +virtual host + +mod_cgimod_cgid + + + +

    ScriptLog $B%G%#%l%/%F%#%V$O(B CGI $B%9%/%j%W%H$N(B + $B%(%i!<%m%0%U%!%$%k$r@_Dj$7$^$9!#(BScriptLog $B$,(B + $B@_Dj$5$l$F$$$J$$$H$-$O!"(B + $B%(%i!<%m%0$O:n@.$5$l$^$;$s!#@_Dj$5$l$F$$$k$H$-$O!"(BCGI + $B$N%(%i!<$O$9$Y$F0z?t$H$7$FM?$($i$l$F$$$k%U%!%$%kL>$K%m%0$5$l$^$9!#(B + $BAjBP%Q%9$G;XDj$5$l$F$$$k$H$-$O!"(B + ServerRoot$B$+$i$NAjBP%Q%9$H$7$F(B + $B07$o$l$^$9!#(B

    + + $BNc(B + ScriptLog logs/cgi_log + + +

    $B$3$N%m%0$O;R%W%m%;%9$,$B$9$J$o$A(B$B!"(BUser $B%G%#%l%/%F%#%V$G;XDj$5$l$?(B + $B%f!<%6$G$9!#$3$l$O!"%9%/%j%W%H%m%0$,=q$+$l$k%G%#%l%/%H%j$,$=$N%f!<%6$G(B + $B=q$-9~$_2DG=$+!"%9%/%j%W%H%U%!%$%k$,$B$7$J$$(B$B$h$&$K$7$F$/$@$5$$!#(B

    + +

    $B%9%/%j%W%H$N%m%0<}=8$O(B CGI $B%9%/%j%W%H$r=q$/$H$-$N(B + $B%G%P%C%0MQ$N5!G=$H$7$F0U?^$5$l$F$$$F!"DL>o$N%5!<%P$G(B + $B>o$K;HMQ$5$l$k$h$&$K$O0U?^$5$l$F$$$J$$$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B + $BB.EY$d8zN($O:GE,2=$5$l$F$*$i$:!"@_7W$5$l$?0J30$NJ}K!$G;HMQ$5$l$k$H(B + $B%;%-%e%j%F%#$NLdBj$,$"$k$+$b$7$l$^$;$s!#(B

    + + + + +ScriptLogLength +CGI $B%9%/%j%W%H$N%m%0%U%!%$%k$NBg$-$5$N>e8B(B +ScriptLogLength bytes +ScriptLogLength 10385760 +server config +virtual host + +mod_cgimod_cgid + + + +

    ScriptLogLength $B$O(B CGI $B%9%/%j%W%H$N%m%0%U%!%$%k(B + $B$NBg$-$5$r@)8B$9$k$?$a$K;HMQ$9$k$3$H$,$G$-$^$9!#%m%0%U%!%$%k$O(B + CGI $B$N%(%i!pJs(B ($B%j%/%(%9%H$N$9$Y$F$N%X%C%@!"(B + $B$9$Y$F$N=PNO(B)$B$r%m%0$7$^$9$N$G!"$9$0$KBg$-$J%U%!%$%k$K$J$j$^$9!#(B + $B$3$NBg$-$5$N@)8B$,$J$$$3$H$K$h$kLdBj$rKI$0$?$a$K!"(B + $B$3$N%G%#%l%/%F%#%V$r;H$C$F(B CGI $B$N%m%0%U%!%$%k$N(B + $B:GBg$N%U%!%$%k%5%$%:$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + $B%U%!%$%k$,$3$NBg$-$5$rD6$($?>l9g$O!"$=$l0J>e$O=q$-9~$^$l$^$;$s!#(B

    +
    +
    + + +ScriptLogBuffer +$B%9%/%j%W%H%m%0$K5-O?$5$l$k(B PUT $B$d(B POST $B%j%/%(%9%H$NFbMF$N>e8B(B +ScriptLogBuffer bytes +ScriptLogBuffer 1024 +server config +virtual host + +mod_cgimod_cgid + + + +

    $BBg$-$JK\BN$r + + + + diff --git a/trunk/docs/manual/mod/mod_cgi.xml.ko b/trunk/docs/manual/mod/mod_cgi.xml.ko new file mode 100644 index 0000000000..cee62c1899 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.xml.ko @@ -0,0 +1,227 @@ + + + + + + + + + +mod_cgi +CGI ½ºÅ©¸³Æ® ½ÇÇà +Base +mod_cgi.c +cgi_module + +

    + + +

    ¼­¹ö´Â mime typeÀÌ application/x-httpd-cgiÀ̰ųª + (¾ÆÆÄÄ¡ 1.1 ÀÌÈÄ) Çڵ鷯°¡ cgi-scriptÀÎ ¸ðµç + ÆÄÀÏÀ» CGI ½ºÅ©¸³Æ®·Î ÀνÄÇÏ¿©, ½ÇÇàÇÏ°í, ±× °á°ú¸¦ Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³½´Ù. ÆÄÀÏÀÌ AddType + Áö½Ã¾î·Î ÁöÁ¤ÇÑ È®ÀåÀÚ¸¦ °¡Áö°Å³ª, ScriptAlias µð·ºÅ丮 ¾È¿¡ + ÀÖÀ¸¸é CGI·Î 󸮵ȴÙ.

    + +

    ¼­¹ö´Â CGI ½ºÅ©¸³Æ®¸¦ ºÎ¸¦¶§ DOCUMENT_ROOT¶ó´Â + ȯ°æº¯¼ö¸¦ Ãß°¡ÇÑ´Ù. ÀÌ º¯¼ö´Â DocumentRoot ¼³Á¤°ªÀ» °¡Áø´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡¼­ CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇÑ ¼Ò°³´Â + CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º ÅõÅ丮¾óÀ» + Âü°íÇ϶ó.

    + +

    À¯´Ð½º¿¡¼­ ´ÙÁß¾²·¹µå MPMÀ» »ç¿ëÇÑ´Ù¸é ÀÌ ¸ðµâ´ë½Å + mod_cgid ¸ðµâÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. »ç¿ëÀÚ + ÀÔÀå¿¡¼­ ÀÌ µÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î µ¿ÀÏÇÏ´Ù.

    +
    + +AcceptPathInfo +Options +ScriptAlias +AddHandler +´Ù¸¥ »ç¿ëÀÚ ID·Î CGI ÇÁ·Î±×·¥ +½ÇÇàÇϱâ +CGI Ç¥ÁØ + +
    CGI ȯ°æº¯¼ö +

    ¼­¹ö´Â ´ÙÀ½°ú °°Àº ¹æ¹ýÀ¸·Î CGI Ç¥ÁØÀÌ ¼³¸íÇÏ´Â + CGI ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù:

    + +
    +
    PATH_INFO
    + +
    ÀÌ º¯¼ö´Â AcceptPathInfo Áö½Ã¾î¸¦ Á÷Á¢ off·Î + ÁöÁ¤ÇÑ °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù. AcceptPathInfo°¡ ¾ø´Â °æ¿ì ¼­¹ö´Â ±âº»ÀûÀ¸·Î + °æ·Î Á¤º¸°¡ ÀÖ´Â ¿äû¿¡ ´ëÇØ 404 NOT FOUND ¿À·ù¸¦ ³»Áö¸¸, + mod_cgi´Â °æ·Î Á¤º¸¸¦ (URI¿¡¼­ ½ºÅ©¸³Æ® + ÆÄÀÏ¸í µÚ¿¡ ³ª¿À´Â /more/path/info) ¹Þ´Â´Ù. + AcceptPathInfo Áö½Ã¾î¸¦ »ý·«Çϸé + mod_cgi ¿äû¿¡ ´ëÇؼ­ AcceptPathInfo¸¦ OnÀ¸·Î + ¼³Á¤ÇÑ °Í°ú °°´Ù.
    + +
    REMOTE_HOST
    + +
    ÀÌ º¯¼ö´Â HostnameLookups°¡ onÀÌ°í (±âº»°ªÀº + off), Á¢¼ÓÇÑ È£½ºÆ® ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ½ÇÁ¦ È£½ºÆ®¸íÀ» + ãÀº °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù.
    + +
    REMOTE_IDENT
    + +
    ÀÌ º¯¼ö´Â IdentityCheck°¡ onÀÌ°í, Á¢¼ÓÇÑ + È£½ºÆ®°¡ ident ÇÁ·ÎÅäÄÝÀ» Áö¿øÇÏ´Â °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù. + ½±°Ô ÀÌ °ªÀ» ¼ÓÀÏ ¼ö Àֱ⶧¹®¿¡ ÀÌ º¯¼öÀÇ ³»¿ëÀ» ¹ÏÀ¸¸é + ¾ÈµÇ°í, Ŭ¶óÀ̾ðÆ®¿Í ¼­¹ö »çÀÌ¿¡ ÇÁ·Ï½Ã°¡ ÀÖ´Ù¸é º¯¼ö + ³»¿ëÀÌ ¿ÏÀüÈ÷ ¹«ÀǹÌÇÔÀ» ÁÖÀÇÇ϶ó.
    + +
    REMOTE_USER
    + +
    CGI ½ºÅ©¸³Æ®°¡ ÀÎÁõÀ» °ÅÃľßÇÏ´Â °æ¿ì¿¡¸¸ ¼³Á¤ÇÑ´Ù.
    +
    +
    + +
    CGI µð¹ö±ë +

    ¾îµð¿¡¼­ À߸ø ½ÇÇàµÇ´ÂÁö ½ºÅ©¸³Æ®ÀÇ Ãâ·ÂÀ» (Ç¥ÁØÃâ·Â°ú + Ç¥ÁØ¿À·ù) º¼ ¼ö ¾ø±â¶§¹®¿¡ CGI ½ºÅ©¸³Æ®´Â ÀüÅëÀûÀ¸·Î µð¹ö±ëÇϱâ + ¾î·Á¿ü´Ù. ¾ÆÆÄÄ¡ 1.2 ÀÌÈÄ¿¡ Ãß°¡µÈ Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¹ß»ýÇÑ + ¿À·ù¸¦ ÀÚ¼¼È÷ ·Î±×¿¡ ³²±æ ¼ö ÀÖ´Ù.

    + +
    CGI ·Î±×ÆÄÀÏ Çü½Ä +

    CGI ¿À·ù·Î±×´Â Á¤»óÀûÀ¸·Î ½ÇÇàÇÏÁö ¸øÇÑ CGI¸¦ ±â·ÏÇÑ´Ù. + ¿À·ù°¡ ¹ß»ýÇÑ CGI ½ºÅ©¸³Æ®´Â ·Î±×¿¡ ¿©·¯ ÁÙÀÇ Á¤º¸¸¦ ³²±ä´Ù. + ù¹ø° µÎ ÁÙÀº Ç×»ó ¾Æ·¡¿Í °°Àº Çü½ÄÀÌ´Ù:

    + + + %% [½Ã°£] ¿äûÁÙ
    + %% HTTP-»óÅ CGI-½ºÅ©¸³Æ®-ÆÄÀϸí +
    + +

    CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÒ ¼ö ¾ø´Â ¿À·ùÀÎ °æ¿ì ·Î±×ÆÄÀÏ¿¡ + Ãß°¡·Î µÎ ÁÙÀ» ´õ ±â·ÏÇÑ´Ù:

    + + + %%error
    + ¿À·ù¹® +
    + +

    ½ºÅ©¸³Æ®°¡ (º¸Åë ½ºÅ©¸³Æ®ÀÇ ¹ö±×¶§¹®¿¡) À߸øµÈ Çì´õ + Á¤º¸¸¦ ¹ÝȯÇÏ´Â °æ¿ì, ´ÙÀ½ ³»¿ëÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù:

    + + + %request
    + ¹ÞÀº ¸ðµç HTTP Çì´õ
    + (ÀÖ´Ù¸é) POST³ª PUT ³»¿ë
    + %response
    + CGI ½ºÅ©¸³Æ® Ãâ·ÂÀÇ ¸ðµç Çì´õ
    + %stdout
    + CGI Ç¥ÁØÃâ·Â
    + %stderr
    + CGI Ç¥ÁØ¿À·ù
    +
    + +

    (½ºÅ©¸³Æ®°¡ Ç¥ÁØÃâ·ÂÀ̳ª Ç¥ÁØ¿À·ù¿¡ ¾Æ¹« ³»¿ëµµ Ãâ·ÂÇÏÁö + ¾Ê¾Ò´Ù¸é %stdout°ú %stderr ºÎºÐÀº »ý·«µÉ ¼ö ÀÖ´Ù).

    +
    +
    + + +ScriptLog +CGI ½ºÅ©¸³Æ® ¿À·ù·Î±×ÆÄÀÏÀÇ À§Ä¡ +ScriptLog file-path +server config +virtual host +mod_cgimod_cgid + + + +

    ScriptLog Áö½Ã¾î´Â CGI ½ºÅ©¸³Æ® + ¿À·ù·Î±×ÆÄÀÏÀ» ÁöÁ¤ÇÑ´Ù. ScriptLog¸¦ + »ç¿ëÇÏÁö¾ÊÀ¸¸é ¿À·ù·Î±×¸¦ ¸¸µéÁö ¾Ê´Â´Ù. »ç¿ëÇÏ¸é ¾Æ±Ô¸ÕÆ®·Î + ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ CGI ¿À·ù¸¦ ±â·ÏÇÑ´Ù. »ó´ë°æ·Î¸¦ ÁöÁ¤Çϸé + ServerRoot¿¡ »ó´ë°æ·Î·Î + ¹Þ¾ÆµéÀδÙ. +

    + + ¿¹Á¦ + ScriptLog logs/cgi_log + + +

    ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ, Áï User Áö½Ã¾î·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ·Î±×¸¦ ¿¬´Ù. ±×·¡¼­ ±× »ç¿ëÀÚ°¡ ½ºÅ©¸³Æ® ·Î±×°¡ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ ÀÖ´øÁö, Á÷Á¢ ¹Ì¸® ÆÄÀÏÀ» ¸¸µé¾î¼­ + ±× »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀ» Áà¾ß ÇÑ´Ù. ½ºÅ©¸³Æ® ·Î±×¸¦ ÁÖ ·Î±× + µð·ºÅ丮¿¡ µÐ´Ù¸é ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀ» + ÁÖ±âÀ§ÇØ µð·ºÅ丮 ±ÇÇÑÀ» º¯°æÇÏÁö ¸¶¶ó.

    + +

    ½ºÅ©¸³Æ® ·Î±×´Â CGI ½ºÅ©¸³Æ®¸¦ ÀÛ¼ºÇÒ¶§ µð¹ö±ëÀ» À§ÇÑ + ¿ëµµÀÌÁö ¼­¹ö¸¦ ½ÇÇàÇÏ´Â µ¿¾È °è¼Ó »ç¿ëÇϱâÀ§ÇÔÀÌ ¾Æ´ÔÀ» + ÁÖÀÇÇ϶ó. ¼Óµµ¿Í È¿À²¼º¸é¿¡¼­ ÃÖÀûÈ­°¡ ¾ÈµÇÀÖ°í, ¼³°èÇÑ + ¸ñÀûÀÌ¿ÜÀÇ ¹æ¹ýÀ¸·Î »ç¿ëÇÏ¸é º¸¾È»ó ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    +
    +
    + + +ScriptLogLength +CGI ½ºÅ©¸³Æ® ·Î±×ÆÄÀÏÀÇ Å©±â Á¦ÇÑ +ScriptLogLength bytes +ScriptLogLength 10385760 +server config +virtual host +mod_cgimod_cgid + + + +

    ScriptLogLength´Â CGI ½ºÅ©¸³Æ® + ·Î±×ÆÄÀÏÀÇ Å©±â¸¦ Á¦ÇÑÇÑ´Ù. CGI ¿À·ù°¡ ¹ß»ýÇÒ¶§¸¶´Ù (¸ðµç + ¿äû Çì´õ, ¸ðµç ½ºÅ©¸³Æ® Ãâ·Â µî) ¸¹Àº Á¤º¸°¡ ·Î±×¿¡ + ±â·ÏµÇ±â¶§¹®¿¡ ÆÄÀÏÀÌ ¸Å¿ì Ä¿Áú ¼ö ÀÖ´Ù. ÆÄÀÏÀÌ ¹«ÇÑÈ÷ Ä¿Áö´Â + ¹®Á¦¸¦ ¸·±âÀ§ÇØ ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© CGI ·Î±×ÆÄÀÏÀÇ ÃÖ´ë + ÆÄÀÏÅ©±â¸¦ ¼³Á¤ÇÑ´Ù. ÆÄÀÏÀÇ Å©±â°¡ ¼³Á¤ÇÑ °ªÀ» ³ÑÀ¸¸é ´õ + ÀÌ»ó Á¤º¸¸¦ ±â·ÏÇÏÁö¾Ê´Â´Ù.

    +
    +
    + + +ScriptLogBuffer +½ºÅ©¸³Æ® ·Î±×¿¡ ±â·ÏÇÒ PUT ȤÀº POST ¿äûÀÇ ÃÖ´ë·® +ScriptLogBuffer bytes +ScriptLogBuffer 1024 +server config +virtual host +mod_cgimod_cgid + + + +

    Å« ³»¿ëÀ» ¹Þ¾Æ¼­ ·Î±×ÆÄÀÏÀÌ ³Ê¹« »¡¸® Ä¿Áö´Â Çö»óÀ» ¸·±âÀ§ÇØ + ÆÄÀÏ¿¡ ±â·ÏÇÒ PUT ȤÀº POST ³»¿ëÀÇ Å©±â¸¦ Á¦ÇÑÇÑ´Ù. ±âº»ÀûÀ¸·Î + 1024 ¹ÙÀÌÆ®±îÁö ·Î±×¿¡ ±â·ÏÇÏÁö¸¸, ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + + diff --git a/trunk/docs/manual/mod/mod_cgi.xml.meta b/trunk/docs/manual/mod/mod_cgi.xml.meta new file mode 100644 index 0000000000..d7b279d2f4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgi.xml.meta @@ -0,0 +1,13 @@ + + + + mod_cgi + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_cgid.html b/trunk/docs/manual/mod/mod_cgid.html new file mode 100644 index 0000000000..f89ee3c782 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.html @@ -0,0 +1,11 @@ +URI: mod_cgid.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_cgid.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_cgid.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_cgid.html.en b/trunk/docs/manual/mod/mod_cgid.html.en new file mode 100644 index 0000000000..349010e983 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.html.en @@ -0,0 +1,105 @@ + + + +mod_cgid - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_cgid

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Execution of CGI scripts using an + external CGI daemon
    Status:Base
    Module Identifier:cgid_module
    Source File:mod_cgid.c
    Compatibility:Unix threaded MPMs only
    +

    Summary

    + +

    Except for the optimizations and the additional ScriptSock directive noted below, + mod_cgid behaves similarly to mod_cgi. + See the mod_cgi summary for additional details + about Apache and CGI.

    + +

    On certain unix operating systems, forking a process from a + multi-threaded server is a very expensive operation because the + new process will replicate all the threads of the parent + process. In order to avoid incurring this expense on each CGI + invocation, mod_cgid creates an external daemon that is + responsible for forking child processes to run CGI scripts. The + main server communicates with this daemon using a unix domain + socket.

    + +

    This module is used by default instead of + mod_cgi whenever a multi-threaded MPM + is selected during the compilation process. At the user level, + this module is identical in configuration and operation to + mod_cgi. The only exception is the + additional directive ScriptSock which gives the + name of the socket to use for communication with the cgi + daemon.

    +
    + + +
    top
    +

    ScriptSock Directive

    + + + + + + + +
    Description:The name of the socket to use for communication with +the cgi daemon
    Syntax:ScriptSock file-path
    Default:ScriptSock logs/cgisock
    Context:server config, virtual host
    Status:Base
    Module:mod_cgid
    +

    This directive sets the name of the socket to use for + communication with the CGI daemon. The socket will be opened + using the permissions of the user who starts Apache (usually + root). To maintain the security of communications with CGI + scripts, it is important that no other user has permission to + write in the directory where the socket is located.

    + +

    Example

    + ScriptSock /var/run/cgid.sock +

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgid.html.ja.euc-jp b/trunk/docs/manual/mod/mod_cgid.html.ja.euc-jp new file mode 100644 index 0000000000..a36f4fabb9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.html.ja.euc-jp @@ -0,0 +1,98 @@ + + + +mod_cgid - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_cgid

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:³°Éô CGI ¥Ç¡¼¥â¥ó¤ò»È¤Ã¤¿ CGI ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:cgid_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_cgid.c
    ¸ß´¹À­:Unix ¤Î¥¹¥ì¥Ã¥É MPM ¤Î¤ß
    +

    ³µÍ×

    + +

    ºÇŬ²½¤¬»Ü¤µ¤ì¤Æ¤¤¤ë¤³¤È¤È¡¢°Ê²¼¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ëÄɲäΠScriptSock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ü¤¤¤Æ¤Ï¡¢ + mod_cgid ¤Ï mod_cgi ¤ÈƱÍͤΠ+ Æ°ºî¤ò¤·¤Þ¤¹¡£Apache ¤È CGI ¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï + mod_cgi ¤Î³µÍפòÆɤó¤Ç¤¯¤À¤µ¤¤¡£

    + +

    Unix ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ÎÃæ¤Ë¤Ï¡¢¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤Î¥µ¡¼¥Ð¤«¤é + ¥×¥í¥»¥¹¤ò fork ¤¹¤ë¤Î¤¬Èó¾ï¤Ë¥³¥¹¥È¤Î¹â¤¤Æ°ºî¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + Íýͳ¤Ï¡¢¿·¤·¤¤¥×¥í¥»¥¹¤¬¿Æ¥×¥í¥»¥¹¤Î¥¹¥ì¥Ã¥É¤¹¤Ù¤Æ¤òÊ£À½¤¹¤ë¤«¤é¤Ç¤¹¡£ + ³Æ CGI µ¯Æ°»þ¤Ë¤³¤Î¥³¥¹¥È¤¬¤«¤«¤ë¤Î¤òËɤ°¤¿¤á¤Ë¡¢mod_cgid + ¤Ï»Ò¥×¥í¥»¥¹¤ò fork ¤·¤Æ CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë¤¿¤á¤Î + ³°Éô¥Ç¡¼¥â¥ó¤ò¼Â¹Ô¤·¤Þ¤¹¡£ + ¼ç¥µ¡¼¥Ð¤Ï unix ¥É¥á¥¤¥ó¥½¥±¥Ã¥È¤ò»È¤Ã¤Æ¤³¤Î¥Ç¡¼¥â¥ó¤ÈÄÌ¿®¤·¤Þ¤¹¡£

    + +

    ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥Þ¥ë¥Á¥¹¥ì¥Ã¥É MPM ¤¬Áª¤Ð¤ì¤¿¤È¤­¤Ï + mod_cgi ¤ÎÂå¤ï¤ê¤Ëɬ¤º¤³¤Î¥â¥¸¥å¡¼¥ë¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£ + ¥æ¡¼¥¶¤Î¥ì¥Ù¥ë¤Ç¤Ï¤³¤Î¥â¥¸¥å¡¼¥ë¤ÎÀßÄê¤ÈÆ°ºî¤Ï mod_cgi + ¤È¤Þ¤Ã¤¿¤¯Æ±¤¸¤Ç¤¹¡£Í£°ì¤ÎÎã³°¤Ï ScriptSock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + Äɲäǡ¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï CGI ¥Ç¡¼¥â¥ó¤È¤ÎÄÌ¿®ÍѤΥ½¥±¥Ã¥È¤Î̾Á°¤ò + »ØÄꤷ¤Þ¤¹¡£

    +
    + + +
    top
    +

    ScriptSock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:CGI ¥Ç¡¼¥â¥ó¤È¤ÎÄÌ¿®¤Ë»È¤ï¤ì¤ë¥½¥±¥Ã¥È¤Î̾Á°
    ¹½Ê¸:ScriptSock file-path
    ¥Ç¥Õ¥©¥ë¥È:ScriptSock logs/cgisock
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_cgid
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï CGI ¥Ç¡¼¥â¥ó¤È¤ÎÄÌ¿®¤Ë»È¤ï¤ì¤ë¥½¥±¥Ã¥È¤Î + ̾Á°¤òÀßÄꤷ¤Þ¤¹¡£¥½¥±¥Ã¥È¤Ï Apache ¤¬µ¯Æ°¤µ¤ì¤¿¥æ¡¼¥¶ (Ä̾ï root) ¤Î + ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÍѤ¤¤Æ¥ª¡¼¥×¥ó¤µ¤ì¤Þ¤¹¡£CGI ¥¹¥¯¥ê¥×¥È¤È¤ÎÄÌ¿®¤Î + ¥»¥­¥å¥ê¥Æ¥£¤òÊݤĤ¿¤á¤Ë¡¢¥½¥±¥Ã¥È¤Î¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ¾¤Î¥æ¡¼¥¶¤¬½ñ¤­¹þ¤ß¸¢¸Â¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬½ÅÍפǤ¹¡£

    + +

    Îã

    + ScriptSock /var/run/cgid.sock +

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgid.html.ko.euc-kr b/trunk/docs/manual/mod/mod_cgid.html.ko.euc-kr new file mode 100644 index 0000000000..4b634b3eab --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.html.ko.euc-kr @@ -0,0 +1,99 @@ + + + +mod_cgid - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_cgid

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:¿ÜºÎ CGI µ¥¸óÀ» »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇà
    »óÅÂ:Base
    ¸ðµâ¸í:cgid_module
    ¼Ò½ºÆÄÀÏ:mod_cgid.c
    Áö¿ø:À¯´Ð½º¿¡¼­ ¾²·¹µå¸¦ »ç¿ëÇÏ´Â MPMs Àü¿ë
    +

    ¿ä¾à

    + +

    ¾Æ·¡¿¡¼­ ¼³¸íÇÏ´Â Ãß°¡µÈ ScriptSock Áö½Ã¾î¸¦ Á¦¿ÜÇÏ°í + mod_cgid´Â mod_cgi¿Í + ºñ½ÁÇÏ°Ô µ¿ÀÛÇÑ´Ù. ¾ÆÆÄÄ¡¿Í CGI¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº + mod_cgi¸¦ Âü°íÇ϶ó.

    + +

    ¾î¶² À¯´Ð½º ¿î¿µÃ¼Á¦ÀÇ °æ¿ì ´ÙÁß¾²·¹µå ¼­¹ö¿¡¼­ ÇÁ·Î¼¼½º¸¦ + Æ÷Å©(fork)ÇÏ¸é »õ·Î¿î ÇÁ·Î¼¼½º°¡ ºÎ¸ð ÇÁ·Î¼¼½ºÀÇ ¸ðµç ¾²·¹µå¸¦ + º¹Á¦ÇØ¾ß ÇϹǷΠºÎ´ãÀÌ µÈ´Ù. CGI ½ÇÇึ´Ù ÀÌ·± ºÎ´ãÀ» ÁÖÁö + ¾Ê±âÀ§ÇØ mod_cgid´Â CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ´Â + ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ Æ÷Å©ÇÏ´Â ¿ÜºÎ µ¥¸óÀ» ¸¸µç´Ù. ÁÖ¼­¹ö´Â ÀÌ + µ¥¸ó°ú À¯´Ð½º¼ÒÄÏ(unix domain socket)À» »ç¿ëÇÏ¿© Åë½ÅÇÑ´Ù.

    + +

    ÄÄÆÄÀÏÇÒ¶§ ´ÙÁß¾²·¹µå MPMÀ» ¼±ÅÃÇÏ¸é ±âº»ÀûÀ¸·Î + mod_cgi ´ë½Å ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù. »ç¿ëÀÚ + ÀÔÀå¿¡¼­ ÀÌ ¸ðµâÀÇ ¼³Á¤°ú µ¿ÀÛÀº mod_cgi¿Í + µ¿ÀÏÇÏ´Ù. À¯ÀÏÇÑ Â÷ÀÌÁ¡Àº cgi µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ + ¼ÒÄÏÀÇ À̸§À» ¼³Á¤ÇÏ´Â ScriptSock Áö½Ã¾î°¡ + Ãß°¡µÈ Á¡ÀÌ´Ù.

    +
    + + +
    top
    +

    ScriptSock Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:cgi µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ¼ÒÄÏÀÇ À̸§
    ¹®¹ý:ScriptSock file-path
    ±âº»°ª:ScriptSock logs/cgisock
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_cgid
    +

    ÀÌ Áö½Ã¾î´Â CGI µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ¼ÒÄÏÀÇ À̸§À» + ÁöÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÑ »ç¿ëÀÚ (º¸Åë root) ±ÇÇÑÀ¸·Î ¼ÒÄÏÀ» + ¿¬´Ù. CGI ½ºÅ©¸³Æ®¿Í Åë½ÅÀÇ º¸¾ÈÀ» À§ÇØ ´Ù¸¥ »ç¿ëÀÚ°¡ ¼ÒÄÏÀÌ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀ» °¡ÁöÁö¾Ê´Â °ÍÀÌ Áß¿äÇÏ´Ù.

    + +

    ¿¹Á¦

    + ScriptSock /var/run/cgid.sock +

    + + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_cgid.xml b/trunk/docs/manual/mod/mod_cgid.xml new file mode 100644 index 0000000000..1d6c85aa5d --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.xml @@ -0,0 +1,100 @@ + + + + + + + + + +mod_cgid +Execution of CGI scripts using an + external CGI daemon +Base +mod_cgid.c +cgid_module +Unix threaded MPMs only + + +

    Except for the optimizations and the additional ScriptSock directive noted below, + mod_cgid behaves similarly to mod_cgi. + See the mod_cgi summary for additional details + about Apache and CGI.

    + +

    On certain unix operating systems, forking a process from a + multi-threaded server is a very expensive operation because the + new process will replicate all the threads of the parent + process. In order to avoid incurring this expense on each CGI + invocation, mod_cgid creates an external daemon that is + responsible for forking child processes to run CGI scripts. The + main server communicates with this daemon using a unix domain + socket.

    + +

    This module is used by default instead of + mod_cgi whenever a multi-threaded MPM + is selected during the compilation process. At the user level, + this module is identical in configuration and operation to + mod_cgi. The only exception is the + additional directive ScriptSock which gives the + name of the socket to use for communication with the cgi + daemon.

    +
    + +mod_cgi +Running CGI programs under different + user IDs + + +ScriptLog + + + +ScriptLogLength + + + +ScriptLogBuffer + + + +ScriptSock +The name of the socket to use for communication with +the cgi daemon +ScriptSock file-path +ScriptSock logs/cgisock +server config +virtual host + + +

    This directive sets the name of the socket to use for + communication with the CGI daemon. The socket will be opened + using the permissions of the user who starts Apache (usually + root). To maintain the security of communications with CGI + scripts, it is important that no other user has permission to + write in the directory where the socket is located.

    + + Example + ScriptSock /var/run/cgid.sock + + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_cgid.xml.ja b/trunk/docs/manual/mod/mod_cgid.xml.ja new file mode 100644 index 0000000000..3c92243cf9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.xml.ja @@ -0,0 +1,93 @@ + + + + + + + + + +mod_cgid +$B30It(B CGI $B%G!<%b%s$r;H$C$?(B CGI $B%9%/%j%W%H$N +Base +mod_cgid.c +cgid_module +Unix $B$N%9%l%C%I(B MPM $B$N$_(B + + +

    $B:GE,2=$,;\$5$l$F$$$k$3$H$H!"0J2<$G@bL@$5$l$F$$$kDI2C$N(B ScriptSock $B%G%#%l%/%F%#%V$r=|$$$F$O!"(B + mod_cgid $B$O(B mod_cgi $B$HF1MM$N(B + $BF0:n$r$7$^$9!#(BApache $B$H(B CGI $B$K4X$9$k>\:Y$O(B + mod_cgi $B$N35MW$rFI$s$G$/$@$5$$!#(B

    + +

    Unix $B%*%Z%l!<%F%#%s%0%7%9%F%`$NCf$K$O!"%^%k%A%9%l%C%I$N%5!<%P$+$i(B + $B%W%m%;%9$r(B fork $B$9$k$N$,Hs>o$K%3%9%H$N9b$$F0:n$K$J$C$F$$$k$b$N$,$"$j$^$9!#(B + $BM}M3$O!"?7$7$$%W%m%;%9$,?F%W%m%;%9$N%9%l%C%I$9$Y$F$rJ#@=$9$k$+$i$G$9!#(B + $B3F(B CGI $B5/F0;~$K$3$N%3%9%H$,$+$+$k$N$rKI$0$?$a$K!"(Bmod_cgid + $B$O;R%W%m%;%9$r(B fork $B$7$F(B CGI $B%9%/%j%W%H$r + +

    $B%3%s%Q%$%k;~$K%^%k%A%9%l%C%I(B MPM $B$,A*$P$l$?$H$-$O(B + mod_cgi $B$NBe$o$j$KI,$:$3$N%b%8%e!<%k$,;HMQ$5$l$^$9!#(B + $B%f!<%6$N%l%Y%k$G$O$3$N%b%8%e!<%k$N@_Dj$HF0:n$O(B mod_cgi + $B$H$^$C$?$/F1$8$G$9!#M#0l$NNc30$O(B ScriptSock $B%G%#%l%/%F%#%V$N(B + $BDI2C$G!"$3$N%G%#%l%/%F%#%V$O(B CGI $B%G!<%b%s$H$NDL?.MQ$N%=%1%C%H$NL>A0$r(B + $B;XDj$7$^$9!#(B

    +
    + +mod_cgi +CGI $B%W%m%0%i%`$r0c$&%f!<%6(B ID $B$G + + +ScriptLog + + + +ScriptLogLength + + + +ScriptLogBuffer + + + +ScriptSock +CGI $B%G!<%b%s$H$NDL?.$K;H$o$l$k%=%1%C%H$NL>A0(B +ScriptSock file-path +ScriptSock logs/cgisock +server config +virtual host + + +

    $B$3$N%G%#%l%/%F%#%V$O(B CGI $B%G!<%b%s$H$NDL?.$K;H$o$l$k%=%1%C%H$N(B + $BL>A0$r@_Dj$7$^$9!#%=%1%C%H$O(B Apache $B$,5/F0$5$l$?%f!<%6(B ($BDL>o(B root) $B$N(B + $B%Q!<%_%C%7%g%s$rMQ$$$F%*!<%W%s$5$l$^$9!#(BCGI $B%9%/%j%W%H$H$NDL?.$N(B + $B%;%-%e%j%F%#$rJ]$D$?$a$K!"%=%1%C%H$NB8:_$9$k%G%#%l%/%H%j$K(B + $BB>$N%f!<%6$,=q$-9~$_8"8B$r;}$C$F$$$J$$$h$&$K$9$k$3$H$,=EMW$G$9!#(B

    + + $BNc(B + ScriptSock /var/run/cgid.sock + + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_cgid.xml.ko b/trunk/docs/manual/mod/mod_cgid.xml.ko new file mode 100644 index 0000000000..08a4ac4dca --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.xml.ko @@ -0,0 +1,92 @@ + + + + + + + + + +mod_cgid +¿ÜºÎ CGI µ¥¸óÀ» »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇà +Base +mod_cgid.c +cgid_module +À¯´Ð½º¿¡¼­ ¾²·¹µå¸¦ »ç¿ëÇÏ´Â MPMs Àü¿ë + + +

    ¾Æ·¡¿¡¼­ ¼³¸íÇÏ´Â Ãß°¡µÈ ScriptSock Áö½Ã¾î¸¦ Á¦¿ÜÇÏ°í + mod_cgid´Â mod_cgi¿Í + ºñ½ÁÇÏ°Ô µ¿ÀÛÇÑ´Ù. ¾ÆÆÄÄ¡¿Í CGI¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº + mod_cgi¸¦ Âü°íÇ϶ó.

    + +

    ¾î¶² À¯´Ð½º ¿î¿µÃ¼Á¦ÀÇ °æ¿ì ´ÙÁß¾²·¹µå ¼­¹ö¿¡¼­ ÇÁ·Î¼¼½º¸¦ + Æ÷Å©(fork)ÇÏ¸é »õ·Î¿î ÇÁ·Î¼¼½º°¡ ºÎ¸ð ÇÁ·Î¼¼½ºÀÇ ¸ðµç ¾²·¹µå¸¦ + º¹Á¦ÇØ¾ß ÇϹǷΠºÎ´ãÀÌ µÈ´Ù. CGI ½ÇÇึ´Ù ÀÌ·± ºÎ´ãÀ» ÁÖÁö + ¾Ê±âÀ§ÇØ mod_cgid´Â CGI ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ´Â + ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ Æ÷Å©ÇÏ´Â ¿ÜºÎ µ¥¸óÀ» ¸¸µç´Ù. ÁÖ¼­¹ö´Â ÀÌ + µ¥¸ó°ú À¯´Ð½º¼ÒÄÏ(unix domain socket)À» »ç¿ëÇÏ¿© Åë½ÅÇÑ´Ù.

    + +

    ÄÄÆÄÀÏÇÒ¶§ ´ÙÁß¾²·¹µå MPMÀ» ¼±ÅÃÇÏ¸é ±âº»ÀûÀ¸·Î + mod_cgi ´ë½Å ÀÌ ¸ðµâÀ» »ç¿ëÇÑ´Ù. »ç¿ëÀÚ + ÀÔÀå¿¡¼­ ÀÌ ¸ðµâÀÇ ¼³Á¤°ú µ¿ÀÛÀº mod_cgi¿Í + µ¿ÀÏÇÏ´Ù. À¯ÀÏÇÑ Â÷ÀÌÁ¡Àº cgi µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ + ¼ÒÄÏÀÇ À̸§À» ¼³Á¤ÇÏ´Â ScriptSock Áö½Ã¾î°¡ + Ãß°¡µÈ Á¡ÀÌ´Ù.

    +
    + +mod_cgi +
    ´Ù¸¥ »ç¿ëÀÚ ID·Î CGI ÇÁ·Î±×·¥ +½ÇÇàÇϱâ + + +ScriptLog + + + +ScriptLogLength + + + +ScriptLogBuffer + + + +ScriptSock +cgi µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ¼ÒÄÏÀÇ À̸§ +ScriptSock file-path +ScriptSock logs/cgisock +server config +virtual host + + +

    ÀÌ Áö½Ã¾î´Â CGI µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ¼ÒÄÏÀÇ À̸§À» + ÁöÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÑ »ç¿ëÀÚ (º¸Åë root) ±ÇÇÑÀ¸·Î ¼ÒÄÏÀ» + ¿¬´Ù. CGI ½ºÅ©¸³Æ®¿Í Åë½ÅÀÇ º¸¾ÈÀ» À§ÇØ ´Ù¸¥ »ç¿ëÀÚ°¡ ¼ÒÄÏÀÌ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀ» °¡ÁöÁö¾Ê´Â °ÍÀÌ Áß¿äÇÏ´Ù.

    + + ¿¹Á¦ + ScriptSock /var/run/cgid.sock + + +
    +
    + + + diff --git a/trunk/docs/manual/mod/mod_cgid.xml.meta b/trunk/docs/manual/mod/mod_cgid.xml.meta new file mode 100644 index 0000000000..6fbca83827 --- /dev/null +++ b/trunk/docs/manual/mod/mod_cgid.xml.meta @@ -0,0 +1,13 @@ + + + + mod_cgid + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_charset_lite.html b/trunk/docs/manual/mod/mod_charset_lite.html new file mode 100644 index 0000000000..1592ea0133 --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.html @@ -0,0 +1,7 @@ +URI: mod_charset_lite.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_charset_lite.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_charset_lite.html.en b/trunk/docs/manual/mod/mod_charset_lite.html.en new file mode 100644 index 0000000000..511793be47 --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.html.en @@ -0,0 +1,209 @@ + + + +mod_charset_lite - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_charset_lite

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:Specify character set translation or recoding
    Status:Experimental
    Module Identifier:charset_lite_module
    Source File:mod_charset_lite.c
    +

    Summary

    + +

    This is an experimental module and should + be used with care. Experiment with your + mod_charset_lite configuration to ensure that it + performs the desired function.

    + +

    mod_charset_lite allows the administrator to + specify the source character set of objects as well as the + character set they should be translated into before sending to the + client. mod_charset_lite does not translate the + data itself but instead tells Apache what translation to + perform. mod_charset_lite is applicable to EBCDIC + and ASCII host environments. In an EBCDIC environment, Apache + normally translates text content from the code page of the Apache + process locale to ISO-8859-1. mod_charset_lite + can be used to specify that a different translation is to be + performed. In an ASCII environment, Apache normally performs no + translation, so mod_charset_lite is needed in + order for any translation to take place.

    + +

    This module provides a small subset of configuration + mechanisms implemented by Russian Apache and its associated + mod_charset.

    +
    + +
    top
    +
    +

    Common Problems

    + +

    Invalid character set names

    + +

    The character set name parameters of CharsetSourceEnc and + CharsetDefault + must be acceptable to the translation mechanism used by APR on the + system where mod_charset_lite is deployed. These + character set names are not standardized and are usually not the + same as the corresponding values used in http headers. Currently, + APR can only use iconv(3), so you can easily test your character + set names using the iconv(1) program, as follows:

    + +

    + iconv -f charsetsourceenc-value -t charsetdefault-value +

    + + +

    Mismatch between character set of content and translation + rules

    + +

    If the translation rules don't make sense for the content, + translation can fail in various ways, including:

    + +
      +
    • The translation mechanism may return a bad return code, + and the connection will be aborted.
    • + +
    • The translation mechanism may silently place special + characters (e.g., question marks) in the output buffer when + it cannot translate the input buffer.
    • +
    + +
    +
    top
    +

    CharsetDefault Directive

    + + + + + + + +
    Description:Charset to translate into
    Syntax:CharsetDefault charset
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Experimental
    Module:mod_charset_lite
    +

    The CharsetDefault directive specifies the + charset that content in the associated container should be + translated to.

    + +

    The value of the charset argument must be accepted + as a valid character set name by the character set support in + APR. Generally, this means that it must be supported by + iconv.

    + +

    Example

    + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +

    + +
    +
    top
    +

    CharsetOptions Directive

    + + + + + + + + +
    Description:Configures charset translation behavior
    Syntax:CharsetOptions option [option] ...
    Default:CharsetOptions DebugLevel=0 NoImplicitAdd
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Experimental
    Module:mod_charset_lite
    +

    The CharsetOptions directive configures certain + behaviors of mod_charset_lite. Option can + be one of

    + +
    +
    DebugLevel=n
    + +
    The DebugLevel keyword allows you to specify + the level of debug messages generated by + mod_charset_lite. By default, no messages are + generated. This is equivalent to DebugLevel=0. + With higher numbers, more debug messages are generated, and + server performance will be degraded. The actual meanings of + the numeric values are described with the definitions of the + DBGLVL_ constants near the beginning of + mod_charset_lite.c.
    + +
    ImplicitAdd | NoImplicitAdd
    + +
    The ImplicitAdd keyword specifies that + mod_charset_lite should implicitly insert its + filter when the configuration specifies that the character + set of content should be translated. If the filter chain is + explicitly configured using the AddOutputFilter directive, NoImplicitAdd + should be specified so that mod_charset_lite + doesn't add its filter.
    +
    + +
    +
    top
    +

    CharsetSourceEnc Directive

    + + + + + + + +
    Description:Source charset of files
    Syntax:CharsetSourceEnc charset
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Experimental
    Module:mod_charset_lite
    +

    The CharsetSourceEnc directive specifies the + source charset of files in the associated container.

    + +

    The value of the charset argument must be accepted + as a valid character set name by the character set support in + APR. Generally, this means that it must be supported by + iconv.

    + +

    Example

    + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +

    + +

    The character set names in this example work with the iconv + translation support in Solaris 8.

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_charset_lite.html.ko.euc-kr b/trunk/docs/manual/mod/mod_charset_lite.html.ko.euc-kr new file mode 100644 index 0000000000..e19e6d428a --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.html.ko.euc-kr @@ -0,0 +1,196 @@ + + + +mod_charset_lite - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_charset_lite

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + + +
    ¼³¸í:¹®ÀÚÁýÇÕ º¯È¯À» ÁöÁ¤
    »óÅÂ:Experimental
    ¸ðµâ¸í:charset_lite_module
    ¼Ò½ºÆÄÀÏ:mod_charset_lite.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ ¸ðµâÀÌ°í, ÁÖÀÇÀÖ°Ô + »ç¿ëÇØ¾ß ÇÑ´Ù. ¿øÇÏ´Â µ¿ÀÛÀ» ÇÏ´ÂÁö + mod_charset_lite ¼³Á¤À» ½ÃÇèÇغÁ¶ó.

    + +

    mod_charset_lite¸¦ »ç¿ëÇÏ¿© ¹®¼­ ¿øº»ÀÇ + ¹®ÀÚÁýÇÕ°ú ¹®¼­¸¦ Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ º¯È¯ÇÒ ¹®ÀÚÁýÇÕÀ» + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. mod_charset_lite´Â Á÷Á¢ + ÀڷḦ º¯È¯ÇÏÁö¾Ê°í ´ë½Å ¾ÆÆÄÄ¡¿¡°Ô º¯È¯Ç϶ó°í ¿äûÇÑ´Ù. + mod_charset_lite´Â EBCDIC°ú ASCII ȯ°æ¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. EBCDIC ȯ°æ¿¡¼­ ¾ÆÆÄÄ¡´Â º¸Åë ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½ºÀÇ + ÄÚµåÆäÀÌÁö¿¡¼­ ISO-8859-1 ¹®ÀÚÁýÇÕÀ¸·Î ¹®¼­¸¦ º¯È¯ÇÑ´Ù. + mod_charset_lite¸¦ »ç¿ëÇÏ¿© ´Ù¸¥ º¯È¯À» + Áö½ÃÇÒ ¼ö ÀÖ´Ù. ASCII ȯ°æ¿¡¼­ ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î º¯È¯À» + ÇÏÁö ¾Ê±â¶§¹®¿¡, ¾î¶² º¯È¯À» À§Çؼ­´Â + mod_charset_lite°¡ ÇÊ¿äÇÏ´Ù.

    + +

    ÀÌ ¸ðµâÀº ·¯½Ã¾ÆÆÇ ¾ÆÆÄÄ¡ÀÇ mod_charsetÀÌ + Á¦°øÇÏ´Â ¼³Á¤ÀÇ ÀϺθ¦ Á¦°øÇÑ´Ù.

    +
    + +
    top
    +
    +

    ÀϹÝÀûÀÎ ¹®Á¦Á¡

    + +

    À߸øµÈ ¹®ÀÚÁýÇÕ À̸§

    + +

    mod_charset_lite¸¦ »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ + ARP ¹ø¿ª±â´ÉÀÌ CharsetSourceEnc¿Í + CharsetDefaultÀÇ + ÆĶó¹ÌÅÍÀÎ ¹®ÀÚÁýÇÕ À̸§À» ó¸®ÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ¹®ÀÚÁýÇÕ + À̸§Àº Ç¥ÁØÈ­µÇÁö ¾Ê¾Ò°í, http Çì´õ¿¡ »ç¿ëÇÏ´Â °ª°ú Ç×»ó + °°Áö´Â ¾Ê´Ù. ÇöÀç APRÀº iconv(3)¸¸À» »ç¿ëÇϱ⶧¹®¿¡, + ´ÙÀ½°ú °°ÀÌ iconv(1) ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© ƯÁ¤ ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö ½±°Ô ¾Ë ¼ö ÀÖ´Ù:

    + +

    + iconv -f charsetsourceenc-value -t charsetdefault-value +

    + + +

    ³»¿ë°ú º¯È¯±ÔÄ¢ÀÇ ¹®ÀÚÁýÇÕÀÌ ¼­·Î ´Ù¸§

    + +

    º¯È¯±ÔÄ¢ÀÌ »óȲ¿¡ ¸ÂÁö¾ÊÀ¸¸é ´ÙÀ½°ú °°Àº ¿©·¯ ¹æ½ÄÀ¸·Î + º¯È¯ÀÌ ½ÇÆÐÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    • º¯È¯±â´ÉÀÌ ½ÇÆÐ ¹ÝȯÄڵ带 ¹ÝȯÇÏ°í ¿¬°áÀÌ ²÷¾îÁú + ¼ö ÀÖ´Ù.
    • + +
    • ÀԷ¹öÆÛ¸¦ º¯È¯ÇÏÁö ¸øÇÒ¶§ Ãâ·Â¹öÆÛ¿¡ ´ë½Å Ưº°ÇÑ + ¹®ÀÚ¸¦ (¿¹, ¹°À½Ç¥) ÀûÀ» ¼ö ÀÖ´Ù.
    • +
    + +
    +
    top
    +

    CharsetDefault Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:º¯È¯ÇÒ ¹®ÀÚÁýÇÕ
    ¹®¹ý:CharsetDefault charset
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Experimental
    ¸ðµâ:mod_charset_lite
    +

    CharsetDefault Áö½Ã¾î´Â Áö½Ã¾î¸¦ + »ç¿ëÇÑ À§Ä¡¿¡ ÀÖ´Â ¿øº»À» º¯È¯ÇÒ ¹®ÀÚÁýÇÕÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    charset ¾Æ±Ô¸ÕÆ®¿¡´Â APRÀÌ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î iconv°¡ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕÀ» + ÀǹÌÇÑ´Ù.

    + +

    ¿¹Á¦

    + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +

    + +
    +
    top
    +

    CharsetOptions Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¹®ÀÚÁýÇÕ º¯È¯ ±â´ÉÀ» ¼³Á¤
    ¹®¹ý:CharsetOptions option [option] ...
    ±âº»°ª:CharsetOptions DebugLevel=0 NoImplicitAdd
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Experimental
    ¸ðµâ:mod_charset_lite
    +

    CharsetOptions Áö½Ã¾î´Â + mod_charset_liteÀÇ ±â´ÉÀ» ¼³Á¤ÇÑ´Ù. + Option¿¡´Â ¾Æ·¡ Ç׸ñµéÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù

    + +
    +
    DebugLevel=n
    + +
    DebugLevel Å°¿öµå´Â + mod_charset_lite°¡ ±â·ÏÇÏ´Â µð¹ö±×¹®±¸ÀÇ + ¼öÁØÀ» ¼³Á¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ¾î¶² °Íµµ ±â·ÏÇÏÁö ¾Ê´Â´Ù. + ÀÌ´Â DebugLevel=0°ú °°´Ù. ³ôÀº ¼ýÀÚ¸¦ »ç¿ëÇÒ¼ö·Ï + ´õ ¸¹Àº µð¹ö±×¹®±¸¸¦ ±â·ÏÇÏ°ÔµÇ¾î ¼­¹ö ¼º´ÉÀÌ ¶³¾îÁø´Ù. + ¼ýÀÚ°ªÀÇ ½ÇÁ¦ Àǹ̴ mod_charset_lite.c ¾ÕºÎºÐÀÇ + DBGLVL_ »ó¼ö Á¤ÀǸ¦ Âü°íÇ϶ó.
    + +
    ImplicitAdd | NoImplicitAdd
    + +
    ImplicitAdd Å°¿öµå´Â ³»¿ëÀ» º¯È¯ÇÒ + ¹®ÀÚÁýÇÕÀ» ÁöÁ¤Çϸé ÀÚµ¿À¸·Î mod_charset_lite¸¦ + ÇÊÅÍ¿¡ Ãß°¡ÇÑ´Ù. AddOutputFilter Áö½Ã¾î·Î ÇÊÅͼø¼­¸¦ Á÷Á¢ + ÁöÁ¤ÇÑ´Ù¸é, NoImplicitAdd¸¦ »ç¿ëÇÏ¿© + mod_charset_lite°¡ ÀÚµ¿À¸·Î ÇÊÅÍ¿¡ + Ãß°¡µÇÁö¾Êµµ·Ï ÇØ¾ß ÇÑ´Ù.
    +
    + +
    +
    top
    +

    CharsetSourceEnc Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÆÄÀÏ ¿øº»ÀÇ ¹®ÀÚÁýÇÕ
    ¹®¹ý:CharsetSourceEnc charset
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Experimental
    ¸ðµâ:mod_charset_lite
    +

    CharsetSourceEnc Áö½Ã¾î´Â Áö½Ã¾î¸¦ + »ç¿ëÇÑ À§Ä¡¿¡ ÀÖ´Â ÆÄÀÏµé ¿øº»ÀÇ ¹®ÀÚÁýÇÕÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    charset ¾Æ±Ô¸ÕÆ®¿¡´Â APRÀÌ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î iconv°¡ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕÀ» + ÀǹÌÇÑ´Ù.

    + +

    ¿¹Á¦

    + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +

    + +

    Solaris 8ÀÇ iconv°¡ ÀÌ ¿¹Á¦ÀÇ ¹®ÀÚÁýÇÕÀ» Áö¿øÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_charset_lite.xml b/trunk/docs/manual/mod/mod_charset_lite.xml new file mode 100644 index 0000000000..db8c7eec27 --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.xml @@ -0,0 +1,199 @@ + + + + + + + + + +mod_charset_lite +Specify character set translation or recoding +Experimental +mod_charset_lite.c +charset_lite_module + + +

    This is an experimental module and should + be used with care. Experiment with your + mod_charset_lite configuration to ensure that it + performs the desired function.

    + +

    mod_charset_lite allows the administrator to + specify the source character set of objects as well as the + character set they should be translated into before sending to the + client. mod_charset_lite does not translate the + data itself but instead tells Apache what translation to + perform. mod_charset_lite is applicable to EBCDIC + and ASCII host environments. In an EBCDIC environment, Apache + normally translates text content from the code page of the Apache + process locale to ISO-8859-1. mod_charset_lite + can be used to specify that a different translation is to be + performed. In an ASCII environment, Apache normally performs no + translation, so mod_charset_lite is needed in + order for any translation to take place.

    + +

    This module provides a small subset of configuration + mechanisms implemented by Russian Apache and its associated + mod_charset.

    +
    + +
    Common Problems + +
    Invalid character set names + +

    The character set name parameters of CharsetSourceEnc and + CharsetDefault + must be acceptable to the translation mechanism used by APR on the + system where mod_charset_lite is deployed. These + character set names are not standardized and are usually not the + same as the corresponding values used in http headers. Currently, + APR can only use iconv(3), so you can easily test your character + set names using the iconv(1) program, as follows:

    + + + iconv -f charsetsourceenc-value -t charsetdefault-value + +
    + +
    Mismatch between character set of content and translation + rules + +

    If the translation rules don't make sense for the content, + translation can fail in various ways, including:

    + +
      +
    • The translation mechanism may return a bad return code, + and the connection will be aborted.
    • + +
    • The translation mechanism may silently place special + characters (e.g., question marks) in the output buffer when + it cannot translate the input buffer.
    • +
    +
    +
    + + +CharsetSourceEnc +Source charset of files +CharsetSourceEnc charset +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    The CharsetSourceEnc directive specifies the + source charset of files in the associated container.

    + +

    The value of the charset argument must be accepted + as a valid character set name by the character set support in + APR. Generally, this means that it must be supported by + iconv.

    + + Example + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +
    + +

    The character set names in this example work with the iconv + translation support in Solaris 8.

    +
    +
    + + +CharsetDefault +Charset to translate into +CharsetDefault charset +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    The CharsetDefault directive specifies the + charset that content in the associated container should be + translated to.

    + +

    The value of the charset argument must be accepted + as a valid character set name by the character set support in + APR. Generally, this means that it must be supported by + iconv.

    + + Example + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +
    +
    +
    + + +CharsetOptions +Configures charset translation behavior +CharsetOptions option [option] ... +CharsetOptions DebugLevel=0 NoImplicitAdd +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    The CharsetOptions directive configures certain + behaviors of mod_charset_lite. Option can + be one of

    + +
    +
    DebugLevel=n
    + +
    The DebugLevel keyword allows you to specify + the level of debug messages generated by + mod_charset_lite. By default, no messages are + generated. This is equivalent to DebugLevel=0. + With higher numbers, more debug messages are generated, and + server performance will be degraded. The actual meanings of + the numeric values are described with the definitions of the + DBGLVL_ constants near the beginning of + mod_charset_lite.c.
    + +
    ImplicitAdd | NoImplicitAdd
    + +
    The ImplicitAdd keyword specifies that + mod_charset_lite should implicitly insert its + filter when the configuration specifies that the character + set of content should be translated. If the filter chain is + explicitly configured using the AddOutputFilter directive, NoImplicitAdd + should be specified so that mod_charset_lite + doesn't add its filter.
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_charset_lite.xml.ko b/trunk/docs/manual/mod/mod_charset_lite.xml.ko new file mode 100644 index 0000000000..997cb98795 --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.xml.ko @@ -0,0 +1,186 @@ + + + + + + + + + +mod_charset_lite +¹®ÀÚÁýÇÕ º¯È¯À» ÁöÁ¤ +Experimental +mod_charset_lite.c +charset_lite_module + + +

    ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ ¸ðµâÀÌ°í, ÁÖÀÇÀÖ°Ô + »ç¿ëÇØ¾ß ÇÑ´Ù. ¿øÇÏ´Â µ¿ÀÛÀ» ÇÏ´ÂÁö + mod_charset_lite ¼³Á¤À» ½ÃÇèÇغÁ¶ó.

    + +

    mod_charset_lite¸¦ »ç¿ëÇÏ¿© ¹®¼­ ¿øº»ÀÇ + ¹®ÀÚÁýÇÕ°ú ¹®¼­¸¦ Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ º¯È¯ÇÒ ¹®ÀÚÁýÇÕÀ» + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. mod_charset_lite´Â Á÷Á¢ + ÀڷḦ º¯È¯ÇÏÁö¾Ê°í ´ë½Å ¾ÆÆÄÄ¡¿¡°Ô º¯È¯Ç϶ó°í ¿äûÇÑ´Ù. + mod_charset_lite´Â EBCDIC°ú ASCII ȯ°æ¿¡¼­ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. EBCDIC ȯ°æ¿¡¼­ ¾ÆÆÄÄ¡´Â º¸Åë ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½ºÀÇ + ÄÚµåÆäÀÌÁö¿¡¼­ ISO-8859-1 ¹®ÀÚÁýÇÕÀ¸·Î ¹®¼­¸¦ º¯È¯ÇÑ´Ù. + mod_charset_lite¸¦ »ç¿ëÇÏ¿© ´Ù¸¥ º¯È¯À» + Áö½ÃÇÒ ¼ö ÀÖ´Ù. ASCII ȯ°æ¿¡¼­ ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î º¯È¯À» + ÇÏÁö ¾Ê±â¶§¹®¿¡, ¾î¶² º¯È¯À» À§Çؼ­´Â + mod_charset_lite°¡ ÇÊ¿äÇÏ´Ù.

    + +

    ÀÌ ¸ðµâÀº ·¯½Ã¾ÆÆÇ ¾ÆÆÄÄ¡ÀÇ mod_charsetÀÌ + Á¦°øÇÏ´Â ¼³Á¤ÀÇ ÀϺθ¦ Á¦°øÇÑ´Ù.

    +
    + +
    ÀϹÝÀûÀÎ ¹®Á¦Á¡ + +
    À߸øµÈ ¹®ÀÚÁýÇÕ À̸§ + +

    mod_charset_lite¸¦ »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ + ARP ¹ø¿ª±â´ÉÀÌ CharsetSourceEnc¿Í + CharsetDefaultÀÇ + ÆĶó¹ÌÅÍÀÎ ¹®ÀÚÁýÇÕ À̸§À» ó¸®ÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ¹®ÀÚÁýÇÕ + À̸§Àº Ç¥ÁØÈ­µÇÁö ¾Ê¾Ò°í, http Çì´õ¿¡ »ç¿ëÇÏ´Â °ª°ú Ç×»ó + °°Áö´Â ¾Ê´Ù. ÇöÀç APRÀº iconv(3)¸¸À» »ç¿ëÇϱ⶧¹®¿¡, + ´ÙÀ½°ú °°ÀÌ iconv(1) ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© ƯÁ¤ ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö ½±°Ô ¾Ë ¼ö ÀÖ´Ù:

    + + + iconv -f charsetsourceenc-value -t charsetdefault-value + +
    + +
    ³»¿ë°ú º¯È¯±ÔÄ¢ÀÇ ¹®ÀÚÁýÇÕÀÌ ¼­·Î ´Ù¸§ + +

    º¯È¯±ÔÄ¢ÀÌ »óȲ¿¡ ¸ÂÁö¾ÊÀ¸¸é ´ÙÀ½°ú °°Àº ¿©·¯ ¹æ½ÄÀ¸·Î + º¯È¯ÀÌ ½ÇÆÐÇÒ ¼ö ÀÖ´Ù:

    + +
      +
    • º¯È¯±â´ÉÀÌ ½ÇÆÐ ¹ÝȯÄڵ带 ¹ÝȯÇÏ°í ¿¬°áÀÌ ²÷¾îÁú + ¼ö ÀÖ´Ù.
    • + +
    • ÀԷ¹öÆÛ¸¦ º¯È¯ÇÏÁö ¸øÇÒ¶§ Ãâ·Â¹öÆÛ¿¡ ´ë½Å Ưº°ÇÑ + ¹®ÀÚ¸¦ (¿¹, ¹°À½Ç¥) ÀûÀ» ¼ö ÀÖ´Ù.
    • +
    +
    +
    + + +CharsetSourceEnc +ÆÄÀÏ ¿øº»ÀÇ ¹®ÀÚÁýÇÕ +CharsetSourceEnc charset +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    CharsetSourceEnc Áö½Ã¾î´Â Áö½Ã¾î¸¦ + »ç¿ëÇÑ À§Ä¡¿¡ ÀÖ´Â ÆÄÀÏµé ¿øº»ÀÇ ¹®ÀÚÁýÇÕÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    charset ¾Æ±Ô¸ÕÆ®¿¡´Â APRÀÌ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î iconv°¡ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕÀ» + ÀǹÌÇÑ´Ù.

    + + ¿¹Á¦ + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +
    + +

    Solaris 8ÀÇ iconv°¡ ÀÌ ¿¹Á¦ÀÇ ¹®ÀÚÁýÇÕÀ» Áö¿øÇÑ´Ù.

    +
    +
    + + +CharsetDefault +º¯È¯ÇÒ ¹®ÀÚÁýÇÕ +CharsetDefault charset +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    CharsetDefault Áö½Ã¾î´Â Áö½Ã¾î¸¦ + »ç¿ëÇÑ À§Ä¡¿¡ ÀÖ´Â ¿øº»À» º¯È¯ÇÒ ¹®ÀÚÁýÇÕÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    charset ¾Æ±Ô¸ÕÆ®¿¡´Â APRÀÌ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕ + À̸§À» »ç¿ëÇØ¾ß ÇÑ´Ù. ÀϹÝÀûÀ¸·Î iconv°¡ Áö¿øÇÏ´Â ¹®ÀÚÁýÇÕÀ» + ÀǹÌÇÑ´Ù.

    + + ¿¹Á¦ + <Directory /export/home/trawick/apacheinst/htdocs/convert>
    + + CharsetSourceEnc UTF-16BE
    + CharsetDefault ISO-8859-1
    +
    + </Directory> +
    +
    +
    + + +CharsetOptions +¹®ÀÚÁýÇÕ º¯È¯ ±â´ÉÀ» ¼³Á¤ +CharsetOptions option [option] ... +CharsetOptions DebugLevel=0 NoImplicitAdd +server config +virtual hostdirectory +.htaccess + +FileInfo + + +

    CharsetOptions Áö½Ã¾î´Â + mod_charset_liteÀÇ ±â´ÉÀ» ¼³Á¤ÇÑ´Ù. + Option¿¡´Â ¾Æ·¡ Ç׸ñµéÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù

    + +
    +
    DebugLevel=n
    + +
    DebugLevel Å°¿öµå´Â + mod_charset_lite°¡ ±â·ÏÇÏ´Â µð¹ö±×¹®±¸ÀÇ + ¼öÁØÀ» ¼³Á¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ¾î¶² °Íµµ ±â·ÏÇÏÁö ¾Ê´Â´Ù. + ÀÌ´Â DebugLevel=0°ú °°´Ù. ³ôÀº ¼ýÀÚ¸¦ »ç¿ëÇÒ¼ö·Ï + ´õ ¸¹Àº µð¹ö±×¹®±¸¸¦ ±â·ÏÇÏ°ÔµÇ¾î ¼­¹ö ¼º´ÉÀÌ ¶³¾îÁø´Ù. + ¼ýÀÚ°ªÀÇ ½ÇÁ¦ Àǹ̴ mod_charset_lite.c ¾ÕºÎºÐÀÇ + DBGLVL_ »ó¼ö Á¤ÀǸ¦ Âü°íÇ϶ó.
    + +
    ImplicitAdd | NoImplicitAdd
    + +
    ImplicitAdd Å°¿öµå´Â ³»¿ëÀ» º¯È¯ÇÒ + ¹®ÀÚÁýÇÕÀ» ÁöÁ¤Çϸé ÀÚµ¿À¸·Î mod_charset_lite¸¦ + ÇÊÅÍ¿¡ Ãß°¡ÇÑ´Ù. AddOutputFilter Áö½Ã¾î·Î ÇÊÅͼø¼­¸¦ Á÷Á¢ + ÁöÁ¤ÇÑ´Ù¸é, NoImplicitAdd¸¦ »ç¿ëÇÏ¿© + mod_charset_lite°¡ ÀÚµ¿À¸·Î ÇÊÅÍ¿¡ + Ãß°¡µÇÁö¾Êµµ·Ï ÇØ¾ß ÇÑ´Ù.
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_charset_lite.xml.meta b/trunk/docs/manual/mod/mod_charset_lite.xml.meta new file mode 100644 index 0000000000..f1fbc29def --- /dev/null +++ b/trunk/docs/manual/mod/mod_charset_lite.xml.meta @@ -0,0 +1,12 @@ + + + + mod_charset_lite + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_dav.html b/trunk/docs/manual/mod/mod_dav.html new file mode 100644 index 0000000000..347f8cf256 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.html @@ -0,0 +1,11 @@ +URI: mod_dav.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_dav.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_dav.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_dav.html.en b/trunk/docs/manual/mod/mod_dav.html.en new file mode 100644 index 0000000000..bfe35206ff --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.html.en @@ -0,0 +1,268 @@ + + + +mod_dav - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dav

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Distributed Authoring and Versioning +(WebDAV) functionality
    Status:Extension
    Module Identifier:dav_module
    Source File:mod_dav.c
    +

    Summary

    + +

    This module provides class 1 and class 2 WebDAV ('Web-based Distributed + Authoring and Versioning') functionality for Apache. This + extension to the HTTP protocol allows creating, moving, + copying, and deleting resources and collections on a remote web + server.

    +
    + +
    top
    +
    +

    Enabling WebDAV

    +

    To enable mod_dav, add the following to a + container in your httpd.conf file:

    + +

    Dav On

    + +

    This enables the DAV file system provider, which is implemented + by the mod_dav_fs module. Therefore, that module + must be compiled into the server or loaded at runtime using the + LoadModule directive.

    + +

    In addition, a location for the DAV lock database must be + specified in the global section of your httpd.conf + file using the DavLockDB + directive:

    + +

    + DavLockDB /usr/local/apache2/var/DavLock +

    + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running.

    + +

    You may wish to add a <Limit> clause inside the <Location> directive to limit access to + DAV-enabled locations. If you want to set the maximum amount of + bytes that a DAV client can send at one request, you have to use + the LimitXMLRequestBody + directive. The "normal" LimitRequestBody directive has no effect on DAV + requests.

    + +

    Full Example

    + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +

    + +

    mod_dav is a descendent of Greg Stein's mod_dav for Apache 1.3. More + information about the module is available from that site.

    +
    top
    +
    +

    Security Issues

    + +

    Since DAV access methods allow remote clients to manipulate + files on the server, you must take particular care to assure that + your server is secure before enabling mod_dav.

    + +

    Any location on the server where DAV is enabled should be + protected by authentication. The use of HTTP Basic Authentication + is not recommended. You should use at least HTTP Digest + Authentication, which is provided by the + mod_auth_digest module. Nearly all WebDAV clients + support this authentication method. An alternative is Basic + Authentication over an SSL enabled + connection.

    + +

    In order for mod_dav to manage files, it must + be able to write to the directories and files under its control + using the User and + Group under which + Apache is running. New files created will also be owned by this + User and Group. For this reason, it is + important to control access to this account. The DAV repository + is considered private to Apache; modifying files outside of Apache + (for example using FTP or filesystem-level tools) should not be + allowed.

    + +

    mod_dav may be subject to various kinds of + denial-of-service attacks. The LimitXMLRequestBody directive can be + used to limit the amount of memory consumed in parsing large DAV + requests. The DavDepthInfinity directive can be + used to prevent PROPFIND requests on a very large + repository from consuming large amounts of memory. Another + possible denial-of-service attack involves a client simply filling + up all available disk space with many large files. There is no + direct way to prevent this in Apache, so you should avoid giving + DAV access to untrusted users.

    +
    top
    +
    +

    Complex Configurations

    + +

    One common request is to use mod_dav to + manipulate dynamic files (PHP scripts, CGI scripts, etc). This is + difficult because a GET request will always run the + script, rather than downloading its contents. One way to avoid + this is to map two different URLs to the content, one of which + will run the script, and one of which will allow it to be + downloaded and manipulated with DAV.

    + +

    +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +

    + +

    With this setup, http://example.com/phparea can be + used to access the output of the PHP scripts, and + http://example.com/php-source can be used with a DAV + client to manipulate them.

    +
    +
    top
    +

    Dav Directive

    + + + + + + + +
    Description:Enable WebDAV HTTP methods
    Syntax:Dav On|Off|provider-name
    Default:Dav Off
    Context:directory
    Status:Extension
    Module:mod_dav
    +

    Use the Dav directive to enable the + WebDAV HTTP methods for the given container:

    + +

    + <Location /foo>
    + + Dav On
    +
    + </Location> +

    + +

    The value On is actually an alias for the default + provider filesystem which is served by the mod_dav_fs module. Note, that once you have DAV enabled + for some location, it cannot be disabled for sublocations. + For a complete configuration example have a look at the section above.

    + +
    + Do not enable WebDAV until you have secured your server. Otherwise + everyone will be able to distribute files on your system. +
    + +
    +
    top
    +

    DavDepthInfinity Directive

    + + + + + + + +
    Description:Allow PROPFIND, Depth: Infinity requests
    Syntax:DavDepthInfinity on|off
    Default:DavDepthInfinity off
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_dav
    +

    Use the DavDepthInfinity directive to + allow the processing of PROPFIND requests containing the + header 'Depth: Infinity'. Because this type of request could constitute + a denial-of-service attack, by default it is not allowed.

    + +
    +
    top
    +

    DavMinTimeout Directive

    + + + + + + + +
    Description:Minimum amount of time the server holds a lock on +a DAV resource
    Syntax:DavMinTimeout seconds
    Default:DavMinTimeout 0
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_dav
    +

    When a client requests a DAV resource lock, it can also + specify a time when the lock will be automatically removed by + the server. This value is only a request, and the server can + ignore it or inform the client of an arbitrary value.

    + +

    Use the DavMinTimeout directive to specify, in + seconds, the minimum lock timeout to return to a client. + Microsoft Web Folders defaults to a timeout of 120 seconds; the + DavMinTimeout can override this to a higher value + (like 600 seconds) to reduce the chance of the client losing + the lock due to network latency.

    + +

    Example

    + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav.html.ja.euc-jp b/trunk/docs/manual/mod/mod_dav.html.ja.euc-jp new file mode 100644 index 0000000000..c94c1c441e --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.html.ja.euc-jp @@ -0,0 +1,274 @@ + + + +mod_dav - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_dav

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:ʬ»¶¥ª¡¼¥µ¥ê¥ó¥°¤È¥Ð¡¼¥¸¥ç¥ó´ÉÍý +(WebDAV) µ¡Ç½
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:dav_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_dav.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥¯¥é¥¹ 1 ¤È¥¯¥é¥¹ 2 ¤Î + WebDAV + ('¥¦¥§¥Ö¥Ù¡¼¥¹¤Îʬ»¶¥ª¡¼¥µ¥ê¥ó¥°¤È¥Ð¡¼¥¸¥ç¥ó´ÉÍý') + µ¡Ç½¤ò Apache ¤ËÄ󶡤·¤Þ¤¹¡£ + ¤³¤Î HTTP ¥×¥í¥È¥³¥ë¤Î³ÈÄ¥¤Ë¤è¤ê¡¢¥ê¥â¡¼¥È¤Î¥¦¥§¥Ö¥µ¡¼¥Ð¾å¤Ë¤¢¤ë + ¥ê¥½¡¼¥¹¤ä¥³¥ì¥¯¥·¥ç¥ó¤ò + ºîÀ®¡¢°ÜÆ°¡¢Ê£À½¡¢ºï½ü¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    Enabling WebDAV

    +

    mod_dav ¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢httpd.conf + ¥Õ¥¡¥¤¥ëÃæ¤Î¥³¥ó¥Æ¥Ê¤Ë¼¡¤ò²Ã¤¨¤Þ¤¹:

    + +

    Dav On

    + +

    ¤³¤ì¤Ï DAV ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥×¥í¥Ð¥¤¥À¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£DAV + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥×¥í¥Ð¥¤¥À¤Ï mod_dav_fs + ¥â¥¸¥å¡¼¥ë¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë + ¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¡¢¤¢¤ë¤¤¤Ï + LoadModule + ¤ò»ÈÍѤ·¤Æ¼Â¹Ô»þ¤Ë¥í¡¼¥É¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¤µ¤é¤Ë¡¢DAV ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ì½ê¤¬ + DavLockDB ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ + httd.conf ¥Õ¥¡¥¤¥ë¤Î¥°¥í¡¼¥Ð¥ë¥»¥¯¥·¥ç¥ó¤Ë»ØÄꤵ¤ì¤Æ¤¤¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    + DavLockDB /usr/local/apache2/var/DavLock +

    + +

    ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ï Apache ¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë + User ¤È Group ¤Ë½ñ¤­¹þ¤ß¸¢¸Â¤¬¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    <Limit> + Àá¤ò <Location> + ¥Ç¥£¥ì¥¯¥Æ¥£¥ÖÆâÉô¤ËÄɲ䷤ơ¢DAV ¤¬Í­¸ú¤Ê¾ì½ê¤Ø¤Î + ¥¢¥¯¥»¥¹¤òÀ©¸Â¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£DAV ¥¯¥é¥¤¥¢¥ó¥È¤¬ + °ìÅ٤Υꥯ¥¨¥¹¥È¤ÇÁ÷¿®¤Ç¤­¤ëºÇÂç¥Ð¥¤¥È¿ô¤ò»ØÄꤷ¤¿¤¤¤È¤­¤Ï¡¢ + LimitXMLRequestBody + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¡ÖÄ̾ï¤Î¡× + LimitRequestBody + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï DAV ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤Ï¸úÎϤò»ý¤Á¤Þ¤»¤ó¡£

    + +

    ´°Á´¤ÊÎã

    + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +

    + +

    mod_dav ¤Ï Greg Stein ¤µ¤ó¤Î Apache 1.3 ÍѤΠmod_dav ¤Ë + ͳÍ褹¤ë¤â¤Î¤Ç¤¹¡£¤½¤Î¥µ¥¤¥È¤«¤é¤è¤ê¿¤¯¤Î¾ðÊó¤ò¼ê¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ¥»¥­¥å¥ê¥Æ¥£¤ÎÌäÂê

    + +

    DAV ¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤Ï±ó³Ö¥¯¥é¥¤¥¢¥ó¥È¤¬¥µ¡¼¥Ð¤Î¥Õ¥¡¥¤¥ë¤ò + Áàºî¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¤Î¤Ç¡¢ mod_dav ¤ò»ÈÍѤ¹¤ë + Á°¤Ë¡¢¥µ¡¼¥Ð¤¬°ÂÁ´¤Ç¤¢¤ë¤³¤È¤òÆäËÃí°Õ¤·¤Æ³Îǧ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¥µ¡¼¥Ð¾å¤Î DAV ¤¬»ÈÍѲÄǽ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì½ê¤Ï¤¹¤Ù¤Æǧ¾Ú¤ÇÊݸ¤Æ¤¯¤À¤µ¤¤¡£ + HTTP ´ðËÜǧ¾Ú¤Î»ÈÍѤϿ侩¤Ç¤­¤Þ¤»¤ó¡£¾¯¤Ê¤¯¤È¤â + mod_auth_digest ¥â¥¸¥å¡¼¥ë¤ÇÄ󶡤µ¤ì¤ë HTTP + ¥À¥¤¥¸¥§¥¹¥Èǧ¾Ú¤òÍѤ¤¤ë¤Ù¤­¤Ç¤¹¡£WebDAV ¥¯¥é¥¤¥¢¥ó¥È¤Î¤Û¤È¤ó¤É¤Ï + ¤³¤Îǧ¾ÚÊýË¡¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¡£Âå¤ï¤ê¤Ë¡¢SSL ¤¬ + Í­¸ú¤Ê¥³¥Í¥¯¥·¥ç¥ó¤òÄ̤·¤¿´ðËÜǧ¾Ú¤ò»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    mod_dav ¤¬¥Õ¥¡¥¤¥ë¤òÁàºî¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ´ÉÍý²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¥Õ¥¡¥¤¥ë¤È¤Ë Apache ¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë User ¤È Group ¤Ç½ñ¤­¹þ¤ß²Äǽ¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¿·¤·¤¯ºîÀ®¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤â¤³¤Î User + ¤È Group ¤Ë½êÍ­¤µ¤ì¤ë + ¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ÎÍýͳ¤«¤é¡¢¤½¤Î¥¢¥«¥¦¥ó¥È¤Ø¤Î¥¢¥¯¥»¥¹¤òÀ©¸æ¤¹¤ë¤³¤È¤Ï + ½ÅÍפǤ¹¡£DAV ¥ê¥Ý¥¸¥È¥ê¤Ï Apache ÀìÍѤΤâ¤Î¤À¤È¤ß¤Ê¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + Apache °Ê³°¤ÎÊýË¡¤Ç¥Õ¥¡¥¤¥ë¤ò½¤Àµ¤¹¤ë¤³¤È (Î㤨¤Ð FTP ¤ä¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à + ÍѤΥġ¼¥ë¤Ê¤É¤ò»È¤Ã¤Æ) ¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£

    + +

    mod_dav ¤Ï¤¤¤í¤¤¤í¤Ê¼ïÎà¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â¤Ë¤µ¤é¤µ¤ì¤ë + ¤«¤â¤·¤ì¤Þ¤»¤ó¡£LimitXMLRequestBody ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È + Â礭¤Ê DAV ¥ê¥¯¥¨¥¹¥È¤ò²òÀϤ¹¤ë¤È¤­¤Ë¾ÃÈñ¤µ¤ì¤ë¥á¥â¥ê¤ÎÎ̤òÀ©¸Â¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£DavDepthInfinity ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + PROPFIND ¥ê¥¯¥¨¥¹¥È¤¬µðÂç¥ê¥Ý¥¸¥È¥ê¤ÇÂçÎ̤Υá¥â¥ê¤ò¾ÃÈñ¤¹¤ë¤Î¤ò + Ëɤ°¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Â¾¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â¤Ë¤Ïñ½ã¤Ë»ÈÍѲÄǽ¤Ê¥Ç¥£¥¹¥¯Îΰè¤ò + ¿¤¯¤ÎÂ礭¤Ê¥Õ¥¡¥¤¥ë¤ÇËä¤á¤Æ¤·¤Þ¤¦¤ó¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤òľÀÜËɤ°ÊýË¡¤Ï + Apache ¤Ë¤Ï¤¢¤ê¤Þ¤»¤ó¤Î¤Ç¡¢¿®ÍѤǤ­¤Ê¤¤¥æ¡¼¥¶¤Ë DAV ¥¢¥¯¥»¥¹¤òÄ󶡤¹¤ë¤Î¤Ï + Èò¤±¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    Ê£»¨¤ÊÀßÄê

    + +

    ¤è¤¯¤¢¤ëÍ×µá¤Ë¡¢mod_dav ¤ò»È¤Ã¤ÆưŪ¤Ê¥Õ¥¡¥¤¥ë + (PHP ¥¹¥¯¥ê¥×¥È¡¢CGI ¥¹¥¯¥ê¥×¥È¤Ê¤É) ¤òÁàºî¤·¤¿¤¤¤È¤¤¤¦¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Î¼Â¸½¤Ï¡¢GET ¥ê¥¯¥¨¥¹¥È¤Ï¥¹¥¯¥ê¥×¥È¤ÎÆâÍƤò¥À¥¦¥ó¥í¡¼¥É¤µ¤»¤ë + Âå¤ï¤ê¤Ë¡¢¥¹¥¯¥ê¥×¥È¤ò¾ï¤Ë¼Â¹Ô¤µ¤»¤Æ¤·¤Þ¤¦¤Î¤ÇÆñ¤·¤¯¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤ò²óÈò¤¹¤ëÊýË¡¤Ë¤Ï¡¢Æó¤Ä¤Î°ã¤¦ URL ¤òƱ¤¸¥³¥ó¥Æ¥ó¥Ä¤Ë¥Þ¥Ã¥×¤·¡¢ + °ì¤Ä¤Ï¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤µ¤»¡¢¤â¤¦°ì¤Ä¤Ï¥À¥¦¥ó¥í¡¼¥É¤µ¤»¤¿¤ê¡¢DAV ¤«¤é + Áàºî¤µ¤ì¤¿¤ê¤¹¤ë¤è¤¦¤ËÀßÄꤹ¤ë¤È¤¤¤¦¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +

    + +

    ¤³¤ÎÀßÄê¤Ë¤è¤ê¡¢http://example.com/phparea ¤ò PHP ¥¹¥¯¥ê¥×¥È¤Î + ½ÐÎϤò¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¡¢ + http://example.com/php-source ¤ò DAV ¥¯¥é¥¤¥¢¥ó¥È¤Ë¤è¤ë + ¤¬Áàºî¤Î¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    +
    top
    +

    Dav ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:WebDAV HTTP ¥á¥½¥Ã¥É¤òÍ­¸ú¤Ë¤·¤Þ¤¹
    ¹½Ê¸:Dav On|Off|provider-name
    ¥Ç¥Õ¥©¥ë¥È:Dav Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dav
    +

    Í¿¤¨¤é¤ì¤¿¥³¥ó¥Æ¥Ê¤Ç WebDAV HTTP ¥á¥½¥Ã¥É¤¬»È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï + ¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    + <Location /foo>
    + + Dav On
    +
    + </Location> +

    + +

    On ¤È¤¤¤¦»ØÄê¤Ï¼ÂºÝ¤Ë¤Ï mod_dav_fs + ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥×¥í¥Ð¥¤¥À¡¢filesystem + ¤Ø¤Î¥¨¥¤¥ê¥¢¥¹¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£°ìÅÙ¤¢¤ë¥í¥±¡¼¥·¥ç¥ó¤Ç DAV + ¤òÍ­¸ú¤Ë¤·¤¿¸å¤Ï¡¢¤½¤Î¥µ¥Ö¥í¥±¡¼¥·¥ç¥ó¤Ç̵¸ú²½¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£´°Á´¤ÊÀßÄêÎã¤Ï¾åµ­¤Î¥»¥¯¥·¥ç¥ó ¤ò¤´Í÷²¼¤µ¤¤¡£

    + +
    + ¥µ¡¼¥Ð¤Î¥»¥­¥å¥ê¥Æ¥£¤¬³ÎÊݤǤ­¤ë¤Þ¤Ç WebDAV ¤òÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¤½¤¦¤·¤Ê¤±¤ì¤Ðï¤Ç¤â¤½¤Î¥µ¡¼¥Ð¤Ç¥Õ¥¡¥¤¥ë¤òÇÛÉÛ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë + ¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡£ +
    + +
    +
    top
    +

    DavDepthInfinity ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:PROPFIND, Depth: Infinity ¥ê¥¯¥¨¥¹¥È¤òµö²Ä¤·¤Þ¤¹
    ¹½Ê¸:DavDepthInfinity on|off
    ¥Ç¥Õ¥©¥ë¥È:DavDepthInfinity off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dav
    +

    'Depth: Infinity' ¤ò´Þ¤ó¤Ç¤¤¤ë + PROPFIND ¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢ + DavDepthInfinity + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¡£¤³¤Î¥¿¥¤¥×¤Î¥ê¥¯¥¨¥¹¥È¤Ï + denial-of-service ¥¢¥¿¥Ã¥¯¤È¤Ê¤ê¤¦¤ë¤Î¤Ç¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    DavMinTimeout ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬ DAV ¥ê¥½¡¼¥¹¤Î¥í¥Ã¥¯¤ò°Ý»ý¤¹¤ëºÇ¾®»þ´Ö¤Ç¤¹¡£ +
    ¹½Ê¸:DavMinTimeout seconds
    ¥Ç¥Õ¥©¥ë¥È:DavMinTimeout 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dav
    +

    ¥¯¥é¥¤¥¢¥ó¥È¤¬ DAV ¥ê¥½¡¼¥¹¥í¥Ã¥¯¤òÍ׵ᤷ¤¿¾ì¹ç¡¢ + ¥í¥Ã¥¯¤¬¥µ¡¼¥Ð¤Ë¤è¤Ã¤Æ¼«Æ°Åª¤Ë²ò½ü¤µ¤ì¤ë¤Þ¤Ç¤Î»þ´Ö¤ò + Ʊ»þ¤Ë»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ÎÃͤÏñ¤Ê¤ë¥ê¥¯¥¨¥¹¥È¤Ç¤¢¤Ã¤Æ¡¢ + ¥µ¡¼¥Ð¤Ï¤³¤ì¤ò̵»ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤·¡¢ + Ǥ°Õ¤ÎÃͤò¥¯¥é¥¤¥¢¥ó¥È¤ËÄÌÃΤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    ¥¯¥é¥¤¥¢¥ó¥È¤ËÌ᤹¥í¥Ã¥¯¥¿¥¤¥à¥¢¥¦¥È¤ÎºÇ¾®»þ´Ö¤ò¡¢ + Éäǡ¢»ØÄꤹ¤ë¤¿¤á¤Ë DavMinTimeout + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¡£ + ¥Þ¥¤¥¯¥í¥½¥Õ¥È¤Î¥¦¥§¥Ö¥Õ¥©¥ë¥À¤Î¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï 120 ÉäǤ¹¤¬¡¨ + ¥Í¥Ã¥È¥ï¡¼¥¯¤ÎÃÙ±ä¤Î¤»¤¤¤Ç¥¯¥é¥¤¥¢¥ó¥È¤¬¥í¥Ã¥¯¤ò¼º¤¦¤Î¤ò¸º¤é¤¹¤¿¤á¤Ë¡¢ + DavMinTimeout ¤ò»È¤Ã¤Æ + ¤³¤ì¤ò¤â¤Ã¤ÈÂ礭¤ÊÃÍ (Î㤨¤Ð 600 ÉÃ) ¤Ë¾å½ñ¤­¤Ç¤­¤Þ¤¹¡£

    + +

    Îã

    + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav.html.ko.euc-kr b/trunk/docs/manual/mod/mod_dav.html.ko.euc-kr new file mode 100644 index 0000000000..9a7907a359 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.html.ko.euc-kr @@ -0,0 +1,263 @@ + + + +mod_dav - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_dav

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:Distributed Authoring and Versioning +(WebDAV) ±â´É
    »óÅÂ:Extension
    ¸ðµâ¸í:dav_module
    ¼Ò½ºÆÄÀÏ:mod_dav.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡¿¡ WebDAV + ('Web-based Distributed Authoring and Versioning') class 1°ú + class 2 ±â´ÉÀ» Ãß°¡ÇÑ´Ù. WebDAV´Â ¿ø°Ý À¥¼­¹öÀÇ ÀÚ¿ø°ú + ÄÝ·º¼Ç(collection)À» (¿ªÁÖ; ÄÝ·º¼ÇÀº ÆÄÀϽýºÅÛÀÇ µð·ºÅ丮¿Í + °°Àº °³³äÀÌ´Ù) ¸¸µé°í, ¿Å±â°í, º¹»çÇÏ°í, Áö¿ï + ¼ö ÀÖµµ·Ï HTTP ÇÁ·ÎÅäÄÝÀ» È®ÀåÇÑ °ÍÀÌ´Ù.

    +
    + +
    top
    +
    +

    WebDAV »ç¿ëÇϱâ

    +

    mod_dav¸¦ »ç¿ëÇÏ·Á¸é httpd.conf + ÆÄÀÏ¿¡ ¾Æ·¡°ú °°ÀÌ Ãß°¡ÇÑ´Ù:

    + +

    Dav On

    + +

    ±×·¯¸é mod_dav_fs ¸ðµâÀÌ ±¸ÇöÇÏ´Â DAV + ÆÄÀϽýºÅÛ Á¦°øÀÚ(provider)¸¦ »ç¿ëÇÑ´Ù. ±×·¯¹Ç·Î ÀÌ ¸ðµâµµ + ¼­¹ö¿¡ °°ÀÌ ÄÄÆÄÀϵÇÀְųª LoadModule Áö½Ã¾î·Î ½ÇÇàÁß¿¡ + Àоîµé¿©¾ß ÇÑ´Ù.

    + +

    ¶Ç, DAV Àá±Ý(lock) µ¥ÀÌÅͺ£À̽ºÀÇ À§Ä¡¸¦ httpd.conf + ÆÄÀÏÀÇ Àü¿ª ºÎºÐ¿¡ DavLockDB Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ÁöÁ¤ÇØ¾ß ÇÑ´Ù:

    + +

    + DavLockDB /usr/local/apache2/var/DavLock +

    + +

    ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â User¿Í GroupÀº Àá±Ý µ¥ÀÌÅͺ£À̽º°¡ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù.

    + +

    DAV¸¦ »ç¿ëÇÏ´Â À§Ä¡¿¡ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ <Location> Áö½Ã¾î + ¾È¿¡ <Limit> + Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. DAV Ŭ¶óÀ̾ðÆ®°¡ ÇѹøÀÇ ¿äû¿¡ + º¸³¾ ¼ö ÀÖ´Â ÃÖ´ë ¹ÙÀÌÆ®¼ö¸¦ Á¦ÇÑÇÏ·Á¸é LimitXMLRequestBody Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + "ÀϹÝÀûÀÎ" LimitRequestBody + Áö½Ã¾î´Â DAV ¿äû°ú °ü°è¾ø´Ù.

    + +

    Àüü ¿¹Á¦

    + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +

    + +

    mod_dav´Â Greg SteinÀÌ ¸¸µç Apache 1.3¿ë mod_dav¸¦ + ±â¹ÝÀ¸·Î ¸¸µé¾ú´Ù. ¸ðµâ¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â ±× »çÀÌÆ®¸¦ + Âü°íÇ϶ó.

    +
    top
    +
    +

    º¸¾È ¹®Á¦

    + +

    DAV¸¦ »ç¿ëÇÏ¸é ¿ø°Ý Ŭ¶óÀ̾ðÆ®°¡ ¼­¹öÀÇ ÆÄÀÏÀ» Á¶ÀÛÇÒ + ¼ö Àֱ⶧¹®¿¡, mod_dav¸¦ »ç¿ëÇϱâ Àü¿¡ + ¼­¹ö°¡ ¾ÈÀüÇÑÁö Ưº°È÷ °ü½ÉÀ» °¡Á®¾ß ÇÑ´Ù.

    + +

    ¼­¹ö¿¡¼­ DAV°¡ °¡´ÉÇÑ À§Ä¡´Â ÀÎÁõÀ¸·Î º¸È£ÇØ¾ß ÇÑ´Ù. + HTTP Basic Authentication´Â ÃßõÇÏÁö ¾Ê´Â´Ù. ÃÖ¼ÒÇÑ + mod_auth_digest ¸ðµâÀÌ Á¦°øÇÏ´Â HTTP Digest + AuthenticationÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. °ÅÀÇ ¸ðµç WebDAV Ŭ¶óÀ̾ðÆ®´Â + ÀÌ ÀÎÁõ ¹æ½ÄÀ» Áö¿øÇÑ´Ù. ¾Æ´Ï¸é SSL + ¿¬°á¿¡¼­ Basic AuthenticationÀ» »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    + +

    mod_dav°¡ ÆÄÀÏÀ» Á¶ÀÛÇÏ·Á¸é, ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇÏ´Â User¿Í + GroupÀº ÇØ´ç + µð·ºÅ丮¿Í ÆÄÀÏ¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù. ¶Ç, »õ·Î »ý¼ºÇÑ + ÆÄÀÏÀº User¿Í + GroupÀÌ ¼ÒÀ¯ÇÏ°Ô + µÈ´Ù. ±×·¡¼­ ¾Æ¹«³ª ÀÌ °èÁ¤¿¡ Á¢±ÙÇÒ ¼ö ¾øµµ·Ï Ç϶ó. DAV + ÀúÀå¼Ò´Â ¾ÆÆÄÄ¡¸¸ Á¢±ÙÇÒ ¼ö ÀÖ´Ù°í °¡Á¤ÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ÅëÇÏÁö¾Ê°í + (¿¹¸¦ µé¾î FTP³ª ÆÄÀϽýºÅÛ µµ±¸¸¦ »ç¿ëÇÏ¿©) ÆÄÀÏÀ» ¼öÁ¤ÇÔÀ» + Çã¿ëÇÏ¸é ¾ÈµÈ´Ù.

    + +

    mod_dav´Â ¿©·¯ ¼­ºñ½º°ÅºÎ °ø°ÝÀÇ ´ë»óÀÌ + µÉ ¼ö ÀÖ´Ù. LimitXMLRequestBody Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Å« DAV ¿äûÀ» ÀÐÀ»¶§ ¸Þ¸ð¸®·®À» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. + DavDepthInfinity + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¸¹Àº ¸Þ¸ð¸®¸¦ ¼Ò¸ðÇϱâÀ§ÇÑ ¸Å¿ì Å« ÀúÀå¼ÒÀÇ + PROPFIND ¿äûÀ» ¸·À» ¼ö ÀÖ´Ù. ´Ü¼øÈ÷ Ŭ¶óÀ̾ðÆ®°¡ + ¿©·¯ Å« ÆÄÀϵé·Î µð½ºÅ©°ø°£À» ä¿ì´Â ¼­ºñ½º°ÅºÎ °ø°Ýµµ °¡´ÉÇÏ´Ù. + ¾ÆÆÄÄ¡¿¡¼­ À̸¦ ¸·À» Á÷Á¢ÀûÀÎ ¹æ¹ýÀº ¾ø´Ù. ±×·¯¹Ç·Î ½Å·ÚÇÏÁö¾Ê´Â + »ç¿ëÀÚ¿¡°Ô DAV Á¢±ÙÀ» Çã¿ëÇÏÁö ¾Êµµ·ÏÇ϶ó.

    +
    top
    +
    +

    º¹ÀâÇÑ ¼³Á¤

    + +

    ÀϹÝÀûÀÎ Áú¹®Áß Çϳª´Â (PHP ½ºÅ©¸³Æ®, CGI ½ºÅ©¸³Æ® µî) + µ¿ÀûÆÄÀÏ ÀÛ¾÷À» À§ÇØ mod_dav¸¦ »ç¿ëÇÏ´Â + ¹æ¹ýÀÌ´Ù. ÀÌ´Â GET ¿äûÀÌ ÆÄÀÏ ³»¿ëÀ» ´Ù¿î·ÎµåÇÏÁö + ¾Ê°í Ç×»ó ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇϹǷΠ¾î·Æ´Ù. ÇØ°á¹æ¹ýÁß Çϳª´Â + ³»¿ë¿¡ µÎ°³ÀÇ URLÀ» ´ëÀÀÇÏ´Â °ÍÀÌ´Ù. ÇÑ URLÀº ½ºÅ©¸³Æ®¸¦ + ½ÇÇàÇÏ°í, ´Ù¸¥ URL·Î´Â ÆÄÀÏÀ» ´Ù¿î·ÎµåÇÏ¿© DAV·Î ÀÛ¾÷ÇÒ + ¼ö ÀÖ´Ù.

    + +

    +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +

    + +

    ÀÌ ¼³Á¤¿¡¼­ http://example.com/phparea´Â + PHP ½ºÅ©¸³Æ®ÀÇ °á°ú¸¦ º¸¿©ÁÖ°í, + http://example.com/php-source·Î´Â DAV Ŭ¶óÀ̾ðÆ®¿¡¼­ + ½ºÅ©¸³Æ®¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +
    top
    +

    Dav Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:WebDAV HTTP ¸Þ½áµå¸¦ ½ÃÀÛÇÑ´Ù
    ¹®¹ý:Dav On|Off|provider-name
    ±âº»°ª:Dav Off
    »ç¿ëÀå¼Ò:directory
    »óÅÂ:Extension
    ¸ðµâ:mod_dav
    +

    ÁöÁ¤ÇÑ À§Ä¡¿¡¼­ WebDAV HTTP ¸Þ½áµå¸¦ »ç¿ëÇÏ·Á¸é + Dav Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù:

    + +

    + <Location /foo>
    + + Dav On
    +
    + </Location> +

    + +

    On °ªÀº ½ÇÁ¦·Î mod_dav_fs + ¸ðµâÀÌ Á¦°øÇÏ´Â ±âº» Á¦°øÀÚÀÎ filesystemÀÇ + º°ÄªÀÌ´Ù. ¾î¶² À§Ä¡¿¡¼­ DAV¸¦ ½ÃÀÛÇϸé ÇÏÀ§°ø°£¿¡¼­ DAV¸¦ + »ç¿ë¾ÈÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó. ¿ÏÀüÇÑ + ¼³Á¤¿¹´Â À§ÀÇ ÀýÀ» Âü°íÇ϶ó.

    + +
    + ¼­¹ö¸¦ ¾ÈÀüÇÏ°Ô ±¸¼ºÇÒ¶§±îÁö WebDAVÀ» »ç¿ëÇÏÁö ¸¶¶ó. ±×·¸Áö + ¾ÊÀ¸¸é ´©±¸¶óµµ ¼­¹ö¸¦ ÅëÇØ ÆÄÀÏÀ» ºÐ¹èÇÒ ¼ö ÀÖ°Ô µÈ´Ù. +
    + +
    +
    top
    +

    DavDepthInfinity Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:PROPFINDÀÇ Depth: Infinity ¿äûÀ» Çã°¡ÇÑ´Ù
    ¹®¹ý:DavDepthInfinity on|off
    ±âº»°ª:DavDepthInfinity off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory
    »óÅÂ:Extension
    ¸ðµâ:mod_dav
    +

    DavDepthInfinity Áö½Ã¾î¸¦ »ç¿ëÇϸé + 'Depth: Infinity' Çì´õ¸¦ °¡Áø PROPFIND ¿äûÀ» + Çã°¡ÇÑ´Ù. ÀÌ·± ¿äûÀ» »ç¿ëÇÏ¿© ¼­ºñ½º°ÅºÎ °ø°ÝÀÌ °¡´ÉÇϱâ + ¶§¹®¿¡ ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö ¾Ê´Â´Ù.

    + +
    +
    top
    +

    DavMinTimeout Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¼­¹ö°¡ DAV ÀÚ¿ø¿¡ ´ëÇØ À¯ÁöÇÒ Àá±ÝÀÇ Ãּҽð£
    ¹®¹ý:DavMinTimeout seconds
    ±âº»°ª:DavMinTimeout 0
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory
    »óÅÂ:Extension
    ¸ðµâ:mod_dav
    +

    Ŭ¶óÀ̾ðÆ®°¡ DAV ÀÚ¿ø¿¡ Àá±Ý(lock)À» ¿äûÇÒ¶§ ¼­¹ö°¡ + ¾Ë¾Æ¼­ Àá±ÝÀ» Á¦°ÅÇÒ ¼ö ÀÖ´Â ½Ã°£À» °°ÀÌ ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù. ÀÌ °ªÀº + ´ÜÁö ¿äûÀÏ»ÓÀ̸ç, ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ ¿äûÇÑ °ªÀ» ¹«½ÃÇÏ°í + Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÓÀÇÀÇ ½Ã°£À» ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.

    + +

    DavMinTimeout Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³¾ ÃÖ¼Ò Àá±Ý ½Ã°£À» (ÃÊ´ÜÀ§) ÁöÁ¤ÇÑ´Ù. Microsoft Web Folders´Â + ±âº»°ªÀ¸·Î 120 Ãʸ¦ »ç¿ëÇÑ´Ù. DavMinTimeout¿¡ + (600 ÃÊ¿Í °°ÀÌ) ´õ ³ôÀº °ªÀ» »ç¿ëÇϸé Ŭ¶óÀ̾ðÆ®°¡ ³×Æ®¿÷ + Áö¿¬¶§¹®¿¡ Àá±ÝÀ» ÀҰԵǴ °æ¿ì¸¦ ÁÙÀÏ ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦

    + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav.xml b/trunk/docs/manual/mod/mod_dav.xml new file mode 100644 index 0000000000..cd2d8f0259 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.xml @@ -0,0 +1,255 @@ + + + + + + + + + +mod_dav +Distributed Authoring and Versioning +(WebDAV) functionality +Extension +mod_dav.c +dav_module + + +

    This module provides class 1 and class 2 WebDAV ('Web-based Distributed + Authoring and Versioning') functionality for Apache. This + extension to the HTTP protocol allows creating, moving, + copying, and deleting resources and collections on a remote web + server.

    +
    +DavLockDB +LimitXMLRequestBody +WebDAV Resources + +
    Enabling WebDAV +

    To enable mod_dav, add the following to a + container in your httpd.conf file:

    + + Dav On + +

    This enables the DAV file system provider, which is implemented + by the mod_dav_fs module. Therefore, that module + must be compiled into the server or loaded at runtime using the + LoadModule directive.

    + +

    In addition, a location for the DAV lock database must be + specified in the global section of your httpd.conf + file using the DavLockDB + directive:

    + + + DavLockDB /usr/local/apache2/var/DavLock + + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running.

    + +

    You may wish to add a Limit clause inside the Location directive to limit access to + DAV-enabled locations. If you want to set the maximum amount of + bytes that a DAV client can send at one request, you have to use + the LimitXMLRequestBody + directive. The "normal" LimitRequestBody directive has no effect on DAV + requests.

    + + Full Example + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +
    + +

    mod_dav is a descendent of Greg Stein's mod_dav for Apache 1.3. More + information about the module is available from that site.

    +
    + +
    Security Issues + +

    Since DAV access methods allow remote clients to manipulate + files on the server, you must take particular care to assure that + your server is secure before enabling mod_dav.

    + +

    Any location on the server where DAV is enabled should be + protected by authentication. The use of HTTP Basic Authentication + is not recommended. You should use at least HTTP Digest + Authentication, which is provided by the + mod_auth_digest module. Nearly all WebDAV clients + support this authentication method. An alternative is Basic + Authentication over an SSL enabled + connection.

    + +

    In order for mod_dav to manage files, it must + be able to write to the directories and files under its control + using the User and + Group under which + Apache is running. New files created will also be owned by this + User and Group. For this reason, it is + important to control access to this account. The DAV repository + is considered private to Apache; modifying files outside of Apache + (for example using FTP or filesystem-level tools) should not be + allowed.

    + +

    mod_dav may be subject to various kinds of + denial-of-service attacks. The LimitXMLRequestBody directive can be + used to limit the amount of memory consumed in parsing large DAV + requests. The DavDepthInfinity directive can be + used to prevent PROPFIND requests on a very large + repository from consuming large amounts of memory. Another + possible denial-of-service attack involves a client simply filling + up all available disk space with many large files. There is no + direct way to prevent this in Apache, so you should avoid giving + DAV access to untrusted users.

    +
    + +
    Complex Configurations + +

    One common request is to use mod_dav to + manipulate dynamic files (PHP scripts, CGI scripts, etc). This is + difficult because a GET request will always run the + script, rather than downloading its contents. One way to avoid + this is to map two different URLs to the content, one of which + will run the script, and one of which will allow it to be + downloaded and manipulated with DAV.

    + + +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +
    + +

    With this setup, http://example.com/phparea can be + used to access the output of the PHP scripts, and + http://example.com/php-source can be used with a DAV + client to manipulate them.

    +
    + + +Dav +Enable WebDAV HTTP methods +Dav On|Off|provider-name +Dav Off +directory + + +

    Use the Dav directive to enable the + WebDAV HTTP methods for the given container:

    + + + <Location /foo>
    + + Dav On
    +
    + </Location> +
    + +

    The value On is actually an alias for the default + provider filesystem which is served by the mod_dav_fs module. Note, that once you have DAV enabled + for some location, it cannot be disabled for sublocations. + For a complete configuration example have a look at the section above.

    + + + Do not enable WebDAV until you have secured your server. Otherwise + everyone will be able to distribute files on your system. + +
    +
    + + +DavMinTimeout +Minimum amount of time the server holds a lock on +a DAV resource +DavMinTimeout seconds +DavMinTimeout 0 +server configvirtual host +directory + + +

    When a client requests a DAV resource lock, it can also + specify a time when the lock will be automatically removed by + the server. This value is only a request, and the server can + ignore it or inform the client of an arbitrary value.

    + +

    Use the DavMinTimeout directive to specify, in + seconds, the minimum lock timeout to return to a client. + Microsoft Web Folders defaults to a timeout of 120 seconds; the + DavMinTimeout can override this to a higher value + (like 600 seconds) to reduce the chance of the client losing + the lock due to network latency.

    + + Example + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +
    +
    +
    + + +DavDepthInfinity +Allow PROPFIND, Depth: Infinity requests +DavDepthInfinity on|off +DavDepthInfinity off +server configvirtual host +directory + + +

    Use the DavDepthInfinity directive to + allow the processing of PROPFIND requests containing the + header 'Depth: Infinity'. Because this type of request could constitute + a denial-of-service attack, by default it is not allowed.

    +
    +
    + +
    + + diff --git a/trunk/docs/manual/mod/mod_dav.xml.ja b/trunk/docs/manual/mod/mod_dav.xml.ja new file mode 100644 index 0000000000..209d91f348 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.xml.ja @@ -0,0 +1,258 @@ + + + + + + + + + +mod_dav +$BJ,;6%*!<%5%j%s%0$H%P!<%8%g%s4IM}(B +(WebDAV) $B5!G=(B +Extension +mod_dav.c +dav_module + + +

    $B$3$N%b%8%e!<%k$O%/%i%9(B 1 $B$H%/%i%9(B 2 $B$N(B + WebDAV + ('$B%&%'%V%Y!<%9$NJ,;6%*!<%5%j%s%0$H%P!<%8%g%s4IM}(B') + $B5!G=$r(B Apache $B$KDs6!$7$^$9!#(B + $B$3$N(B HTTP $B%W%m%H%3%k$N3HD%$K$h$j!"%j%b!<%H$N%&%'%V%5!<%P>e$K$"$k(B + $B%j%=!<%9$d%3%l%/%7%g%s$r(B + $B:n@.!"0\F0!"J#@=!":o=|$G$-$k$h$&$K$J$j$^$9!#(B

    +
    +DavLockDB +LimitXMLRequestBody +WebDAV Resources + +
    Enabling WebDAV +

    mod_dav $B$rM-8z$K$9$k$K$O!"(Bhttpd.conf + $B%U%!%$%kCf$N%3%s%F%J$K + + Dav On + +

    $B$3$l$O(B DAV $B%U%!%$%k%7%9%F%`%W%m%P%$%@$rM-8z$K$7$^$9!#(BDAV + $B%U%!%$%k%7%9%F%`%W%m%P%$%@$O(B mod_dav_fs + $B%b%8%e!<%k$GLoadModule + $B$r;HMQ$7$F + +

    $B$5$i$K!"(BDAV $B%m%C%/%G!<%?%Y!<%9$N>l=j$,(B + DavLockDB $B%G%#%l%/%F%#%V$r;H$C$F(B + httd.conf $B%U%!%$%k$N%0%m!<%P%k%;%/%7%g%s$K;XDj$5$l$F$$$k(B + $BI,MW$,$"$j$^$9!#(B

    + + + DavLockDB /usr/local/apache2/var/DavLock + + +

    $B%m%C%/%G!<%?%Y!<%9%U%!%$%k$N$"$k%G%#%l%/%H%j$O(B Apache $B$,User $B$H(B Group $B$K=q$-9~$_8"8B$,$"$kI,MW$,$"$j$^$9!#(B

    + +

    Limit + $B@a$r(B Location + $B%G%#%l%/%F%#%VFbIt$KDI2C$7$F!"(BDAV $B$,M-8z$J>l=j$X$N(B + $B%"%/%;%9$r@)8B$9$k$3$H$b$G$-$^$9!#(BDAV $B%/%i%$%"%s%H$,(B + $B0lEY$N%j%/%(%9%H$GAw?.$G$-$k:GBg%P%$%H?t$r;XDj$7$?$$$H$-$O!"(B + LimitXMLRequestBody + $B%G%#%l%/%F%#%V$r;HMQ$9$kI,MW$,$"$j$^$9!#!VDL>o$N!W(B + LimitRequestBody + $B%G%#%l%/%F%#%V$O(B DAV $B%j%/%(%9%H$KBP$7$F$O8zNO$r;}$A$^$;$s!#(B

    + + $B40A4$JNc(B + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +
    + +

    mod_dav $B$O(B Greg Stein $B$5$s$N(B Apache 1.3 $BMQ$N(B mod_dav $B$K(B + $BM3Mh$9$k$b$N$G$9!#$=$N%5%$%H$+$i$h$jB?$/$N>pJs$r +

    + +
    $B%;%-%e%j%F%#$NLdBj(B + +

    DAV $B$N%"%/%;%9%a%=%C%I$O1s3V%/%i%$%"%s%H$,%5!<%P$N%U%!%$%k$r(B + $BA`:n$9$k$3$H$r2DG=$K$7$^$9$N$G!"(B mod_dav $B$r;HMQ$9$k(B + $BA0$K!"%5!<%P$,0BA4$G$"$k$3$H$rFC$KCm0U$7$F3NG'$7$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B%5!<%P>e$N(B DAV $B$,;HMQ2DG=$K$J$C$F$$$k>l=j$O$9$Y$FG'>Z$GJ]8n$7$F$/$@$5$$!#(B + HTTP $B4pK\G'>Z$N;HMQ$O?d>)$G$-$^$;$s!#>/$J$/$H$b(B + mod_auth_digest $B%b%8%e!<%k$GDs6!$5$l$k(B HTTP + $B%@%$%8%'%9%HG'>Z$rMQ$$$k$Y$-$G$9!#(BWebDAV $B%/%i%$%"%s%H$N$[$H$s$I$O(B + $B$3$NG'>ZJ}K!$KBP1~$7$F$$$^$9!#Be$o$j$K!"(BSSL $B$,(B + $BM-8z$J%3%M%/%7%g%s$rDL$7$?4pK\G'>Z$r;H$&$3$H$b$G$-$^$9!#(B

    + +

    mod_dav $B$,%U%!%$%k$rA`:n$G$-$k$h$&$K$9$k$?$a$K$O!"(B + $B4IM}2<$N%G%#%l%/%H%j$H%U%!%$%k$H$K(B Apache $B$,User $B$H(B Group $B$G=q$-9~$_2DG=$G$"$kI,MW$,$"$j$^$9!#(B + $B?7$7$/:n@.$5$l$k%U%!%$%k$b$3$N(B User + $B$H(B Group $B$K=jM-$5$l$k(B + $B$3$H$K$J$j$^$9!#$3$NM}M3$+$i!"$=$N%"%+%&%s%H$X$N%"%/%;%9$r@)8f$9$k$3$H$O(B + $B=EMW$G$9!#(BDAV $B%j%]%8%H%j$O(B Apache $B@lMQ$N$b$N$@$H$_$J$5$l$F$$$^$9!#(B + Apache $B0J30$NJ}K!$G%U%!%$%k$r=$@5$9$k$3$H(B ($BNc$($P(B FTP $B$d%U%!%$%k%7%9%F%`(B + $BMQ$N%D!<%k$J$I$r;H$C$F(B) $B$O5v2D$5$l$F$$$^$;$s!#(B

    + +

    mod_dav $B$O$$$m$$$m$JLimitXMLRequestBody $B%G%#%l%/%F%#%V$r;H$&$H(B + $BBg$-$J(B DAV $B%j%/%(%9%H$r2r@O$9$k$H$-$K>CHq$5$l$k%a%b%j$NNL$r@)8B$9$k$3$H$,(B + $B$G$-$^$9!#(BDavDepthInfinity $B%G%#%l%/%F%#%V$O(B + PROPFIND $B%j%/%(%9%H$,5pBg%j%]%8%H%j$GBgNL$N%a%b%j$r>CHq$9$k$N$r(B + $BKI$0$3$H$,$G$-$^$9!#B>$N%5!<%S%95qH]967b$K$OC1=c$K;HMQ2DG=$J%G%#%9%/NN0h$r(B + $BB?$/$NBg$-$J%U%!%$%k$GKd$a$F$7$^$&$s$b$N$,$"$j$^$9!#$3$l$rD>@\KI$0J}K!$O(B + Apache $B$K$O$"$j$^$;$s$N$G!"?.MQ$G$-$J$$%f!<%6$K(B DAV $B%"%/%;%9$rDs6!$9$k$N$O(B + $BHr$1$?J}$,NI$$$G$7$g$&!#(B

    +
    + +
    $BJ#;($J@_Dj(B + +

    $B$h$/$"$kMW5a$K!"(Bmod_dav $B$r;H$C$FF0E*$J%U%!%$%k(B + (PHP $B%9%/%j%W%H!"(BCGI $B%9%/%j%W%H$J$I(B) $B$rA`:n$7$?$$$H$$$&$b$N$,$"$j$^$9!#(B + $B$3$l$NGET $B%j%/%(%9%H$O%9%/%j%W%H$NFbMF$r%@%&%s%m!<%I$5$;$k(B + $BBe$o$j$K!"%9%/%j%W%H$r>o$K + + +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +
    + +

    $B$3$N@_Dj$K$h$j!"(Bhttp://example.com/phparea $B$r(B PHP $B%9%/%j%W%H$N(B + $B=PNO$r%"%/%;%9$9$k$?$a$K;H$&$3$H$,$G$-!"(B + http://example.com/php-source $B$r(B DAV $B%/%i%$%"%s%H$K$h$k(B + $B$,A`:n$N$?$a$K;H$&$3$H$,$G$-$^$9!#(B

    +
    + + +Dav +WebDAV HTTP $B%a%=%C%I$rM-8z$K$7$^$9(B +Dav On|Off|provider-name +Dav Off +directory + + +

    $BM?$($i$l$?%3%s%F%J$G(B WebDAV HTTP $B%a%=%C%I$,;H$($k$h$&$K$9$k$K$O(B + $B + + + <Location /foo>
    + + Dav On
    +
    + </Location> +
    + +

    On $B$H$$$&;XDj$Omod_dav_fs + $B$GDs6!$5$l$F$$$k%G%U%)%k%H$N%W%m%P%$%@!"(Bfilesystem + $B$X$N%(%$%j%"%9$K$J$C$F$$$^$9!#0lEY$"$k%m%1!<%7%g%s$G(B DAV + $B$rM-8z$K$7$?8e$O!"$=$N%5%V%m%1!<%7%g%s$G(B$BL58z2=$9$k$3$H$O$G$-$J$$(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#40A4$J@_DjNc$O(B$B>e5-$N%;%/%7%g%s(B $B$r$4Mw2<$5$$!#(B

    + + + $B%5!<%P$N%;%-%e%j%F%#$,3NJ]$G$-$k$^$G(B WebDAV $B$rM-8z$K$7$J$$$G$/$@$5$$!#(B + $B$=$&$7$J$1$l$PC/$G$b$=$N%5!<%P$G%U%!%$%k$rG[I[$9$k$3$H$,$G$-$k$h$&$K(B + $B$J$C$F$7$^$$$^$9!#(B + +
    +
    + + +DavMinTimeout +$B%5!<%P$,(B DAV $B%j%=!<%9$N%m%C%/$r0];}$9$k:G>.;~4V$G$9!#(B + +DavMinTimeout seconds +DavMinTimeout 0 +server configvirtual host +directory + + +

    $B%/%i%$%"%s%H$,(B DAV $B%j%=!<%9%m%C%/$rMW5a$7$?>l9g!"(B + $B%m%C%/$,%5!<%P$K$h$C$F<+F0E*$K2r=|$5$l$k$^$G$N;~4V$r(B + $BF1;~$K;XDj$9$k$3$H$,$G$-$^$9!#$3$NCM$OC1$J$k%j%/%(%9%H$G$"$C$F!"(B + $B%5!<%P$O$3$l$rL5;k$9$k$3$H$b$G$-$^$9$7!"(B + $BG$0U$NCM$r%/%i%$%"%s%H$KDLCN$9$k$3$H$b$G$-$^$9!#(B

    + +

    $B%/%i%$%"%s%H$KLa$9%m%C%/%?%$%`%"%&%H$N:G>.;~4V$r!"(B + $BIC$G!";XDj$9$k$?$a$K(B DavMinTimeout + $B%G%#%l%/%F%#%V$r;H$$$^$9!#(B + $B%^%$%/%m%=%U%H$N%&%'%V%U%)%k%@$N%G%U%)%k%H$G$O(B 120 $BIC$G$9$,!((B + $B%M%C%H%o!<%/$NCY1d$N$;$$$G%/%i%$%"%s%H$,%m%C%/$r<:$&$N$r8:$i$9$?$a$K!"(B + DavMinTimeout $B$r;H$C$F(B + $B$3$l$r$b$C$HBg$-$JCM(B ($BNc$($P(B 600 $BIC(B) $B$K>e=q$-$G$-$^$9!#(B

    + + $BNc(B + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +
    +
    +
    + + +DavDepthInfinity +PROPFIND, Depth: Infinity $B%j%/%(%9%H$r5v2D$7$^$9(B +DavDepthInfinity on|off +DavDepthInfinity off +server configvirtual host +directory + + +

    'Depth: Infinity' $B$r4^$s$G$$$k(B + PROPFIND $B%j%/%(%9%H$r=hM}$G$-$k$h$&$K$9$k$K$O!"(B + DavDepthInfinity + $B%G%#%l%/%F%#%V$r;H$$$^$9!#$3$N%?%$%W$N%j%/%(%9%H$O(B + denial-of-service $B%"%?%C%/$H$J$j$&$k$N$G!"(B + $B%G%U%)%k%H$G$O5v2D$5$l$F$$$^$;$s!#(B

    +
    +
    + +
    + + diff --git a/trunk/docs/manual/mod/mod_dav.xml.ko b/trunk/docs/manual/mod/mod_dav.xml.ko new file mode 100644 index 0000000000..7f1ebf5038 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.xml.ko @@ -0,0 +1,248 @@ + + + + + + + + + +mod_dav +Distributed Authoring and Versioning +(WebDAV) ±â´É +Extension +mod_dav.c +dav_module + + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡¿¡ WebDAV + ('Web-based Distributed Authoring and Versioning') class 1°ú + class 2 ±â´ÉÀ» Ãß°¡ÇÑ´Ù. WebDAV´Â ¿ø°Ý À¥¼­¹öÀÇ ÀÚ¿ø°ú + ÄÝ·º¼Ç(collection)À» ÄÝ·º¼ÇÀº ÆÄÀϽýºÅÛÀÇ µð·ºÅ丮¿Í + °°Àº °³³äÀÌ´Ù ¸¸µé°í, ¿Å±â°í, º¹»çÇÏ°í, Áö¿ï + ¼ö ÀÖµµ·Ï HTTP ÇÁ·ÎÅäÄÝÀ» È®ÀåÇÑ °ÍÀÌ´Ù.

    +
    +DavLockDB +LimitXMLRequestBody +WebDAV Á¤º¸ + +
    WebDAV »ç¿ëÇϱâ +

    mod_dav¸¦ »ç¿ëÇÏ·Á¸é httpd.conf + ÆÄÀÏ¿¡ ¾Æ·¡°ú °°ÀÌ Ãß°¡ÇÑ´Ù:

    + + Dav On + +

    ±×·¯¸é mod_dav_fs ¸ðµâÀÌ ±¸ÇöÇÏ´Â DAV + ÆÄÀϽýºÅÛ Á¦°øÀÚ(provider)¸¦ »ç¿ëÇÑ´Ù. ±×·¯¹Ç·Î ÀÌ ¸ðµâµµ + ¼­¹ö¿¡ °°ÀÌ ÄÄÆÄÀϵÇÀְųª LoadModule Áö½Ã¾î·Î ½ÇÇàÁß¿¡ + Àоîµé¿©¾ß ÇÑ´Ù.

    + +

    ¶Ç, DAV Àá±Ý(lock) µ¥ÀÌÅͺ£À̽ºÀÇ À§Ä¡¸¦ httpd.conf + ÆÄÀÏÀÇ Àü¿ª ºÎºÐ¿¡ DavLockDB Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ÁöÁ¤ÇØ¾ß ÇÑ´Ù:

    + + + DavLockDB /usr/local/apache2/var/DavLock + + +

    ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â User¿Í GroupÀº Àá±Ý µ¥ÀÌÅͺ£À̽º°¡ + ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù.

    + +

    DAV¸¦ »ç¿ëÇÏ´Â À§Ä¡¿¡ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ Location Áö½Ã¾î + ¾È¿¡ Limit + Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. DAV Ŭ¶óÀ̾ðÆ®°¡ ÇѹøÀÇ ¿äû¿¡ + º¸³¾ ¼ö ÀÖ´Â ÃÖ´ë ¹ÙÀÌÆ®¼ö¸¦ Á¦ÇÑÇÏ·Á¸é LimitXMLRequestBody Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + "ÀϹÝÀûÀÎ" LimitRequestBody + Áö½Ã¾î´Â DAV ¿äû°ú °ü°è¾ø´Ù.

    + + Àüü ¿¹Á¦ + DavLockDB /usr/local/apache2/var/DavLock
    +
    + <Location /foo>
    + + Dav On
    +
    + AuthType Basic
    + AuthName DAV
    + AuthUserFile user.passwd
    +
    + <LimitExcept GET OPTIONS>
    + + require user admin
    +
    + </LimitExcept>
    +
    + </Location>
    +
    + +

    mod_dav´Â Greg SteinÀÌ ¸¸µç Apache 1.3¿ë mod_dav¸¦ + ±â¹ÝÀ¸·Î ¸¸µé¾ú´Ù. ¸ðµâ¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â ±× »çÀÌÆ®¸¦ + Âü°íÇ϶ó.

    +
    + +
    º¸¾È ¹®Á¦ + +

    DAV¸¦ »ç¿ëÇÏ¸é ¿ø°Ý Ŭ¶óÀ̾ðÆ®°¡ ¼­¹öÀÇ ÆÄÀÏÀ» Á¶ÀÛÇÒ + ¼ö Àֱ⶧¹®¿¡, mod_dav¸¦ »ç¿ëÇϱâ Àü¿¡ + ¼­¹ö°¡ ¾ÈÀüÇÑÁö Ưº°È÷ °ü½ÉÀ» °¡Á®¾ß ÇÑ´Ù.

    + +

    ¼­¹ö¿¡¼­ DAV°¡ °¡´ÉÇÑ À§Ä¡´Â ÀÎÁõÀ¸·Î º¸È£ÇØ¾ß ÇÑ´Ù. + HTTP Basic Authentication´Â ÃßõÇÏÁö ¾Ê´Â´Ù. ÃÖ¼ÒÇÑ + mod_auth_digest ¸ðµâÀÌ Á¦°øÇÏ´Â HTTP Digest + AuthenticationÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. °ÅÀÇ ¸ðµç WebDAV Ŭ¶óÀ̾ðÆ®´Â + ÀÌ ÀÎÁõ ¹æ½ÄÀ» Áö¿øÇÑ´Ù. ¾Æ´Ï¸é SSL + ¿¬°á¿¡¼­ Basic AuthenticationÀ» »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    + +

    mod_dav°¡ ÆÄÀÏÀ» Á¶ÀÛÇÏ·Á¸é, ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇÏ´Â User¿Í + GroupÀº ÇØ´ç + µð·ºÅ丮¿Í ÆÄÀÏ¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù. ¶Ç, »õ·Î »ý¼ºÇÑ + ÆÄÀÏÀº User¿Í + GroupÀÌ ¼ÒÀ¯ÇÏ°Ô + µÈ´Ù. ±×·¡¼­ ¾Æ¹«³ª ÀÌ °èÁ¤¿¡ Á¢±ÙÇÒ ¼ö ¾øµµ·Ï Ç϶ó. DAV + ÀúÀå¼Ò´Â ¾ÆÆÄÄ¡¸¸ Á¢±ÙÇÒ ¼ö ÀÖ´Ù°í °¡Á¤ÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ÅëÇÏÁö¾Ê°í + (¿¹¸¦ µé¾î FTP³ª ÆÄÀϽýºÅÛ µµ±¸¸¦ »ç¿ëÇÏ¿©) ÆÄÀÏÀ» ¼öÁ¤ÇÔÀ» + Çã¿ëÇÏ¸é ¾ÈµÈ´Ù.

    + +

    mod_dav´Â ¿©·¯ ¼­ºñ½º°ÅºÎ °ø°ÝÀÇ ´ë»óÀÌ + µÉ ¼ö ÀÖ´Ù. LimitXMLRequestBody Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Å« DAV ¿äûÀ» ÀÐÀ»¶§ ¸Þ¸ð¸®·®À» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù. + DavDepthInfinity + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¸¹Àº ¸Þ¸ð¸®¸¦ ¼Ò¸ðÇϱâÀ§ÇÑ ¸Å¿ì Å« ÀúÀå¼ÒÀÇ + PROPFIND ¿äûÀ» ¸·À» ¼ö ÀÖ´Ù. ´Ü¼øÈ÷ Ŭ¶óÀ̾ðÆ®°¡ + ¿©·¯ Å« ÆÄÀϵé·Î µð½ºÅ©°ø°£À» ä¿ì´Â ¼­ºñ½º°ÅºÎ °ø°Ýµµ °¡´ÉÇÏ´Ù. + ¾ÆÆÄÄ¡¿¡¼­ À̸¦ ¸·À» Á÷Á¢ÀûÀÎ ¹æ¹ýÀº ¾ø´Ù. ±×·¯¹Ç·Î ½Å·ÚÇÏÁö¾Ê´Â + »ç¿ëÀÚ¿¡°Ô DAV Á¢±ÙÀ» Çã¿ëÇÏÁö ¾Êµµ·ÏÇ϶ó.

    +
    + +
    º¹ÀâÇÑ ¼³Á¤ + +

    ÀϹÝÀûÀÎ Áú¹®Áß Çϳª´Â (PHP ½ºÅ©¸³Æ®, CGI ½ºÅ©¸³Æ® µî) + µ¿ÀûÆÄÀÏ ÀÛ¾÷À» À§ÇØ mod_dav¸¦ »ç¿ëÇÏ´Â + ¹æ¹ýÀÌ´Ù. ÀÌ´Â GET ¿äûÀÌ ÆÄÀÏ ³»¿ëÀ» ´Ù¿î·ÎµåÇÏÁö + ¾Ê°í Ç×»ó ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇϹǷΠ¾î·Æ´Ù. ÇØ°á¹æ¹ýÁß Çϳª´Â + ³»¿ë¿¡ µÎ°³ÀÇ URLÀ» ´ëÀÀÇÏ´Â °ÍÀÌ´Ù. ÇÑ URLÀº ½ºÅ©¸³Æ®¸¦ + ½ÇÇàÇÏ°í, ´Ù¸¥ URL·Î´Â ÆÄÀÏÀ» ´Ù¿î·ÎµåÇÏ¿© DAV·Î ÀÛ¾÷ÇÒ + ¼ö ÀÖ´Ù.

    + + +Alias /phparea /home/gstein/php_files
    +Alias /php-source /home/gstein/php_files
    +<Location /php-source> + + DAV On
    + ForceType text/plain
    +
    +</Location> +
    + +

    ÀÌ ¼³Á¤¿¡¼­ http://example.com/phparea´Â + PHP ½ºÅ©¸³Æ®ÀÇ °á°ú¸¦ º¸¿©ÁÖ°í, + http://example.com/php-source·Î´Â DAV Ŭ¶óÀ̾ðÆ®¿¡¼­ + ½ºÅ©¸³Æ®¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    + + +Dav +WebDAV HTTP ¸Þ½áµå¸¦ ½ÃÀÛÇÑ´Ù +Dav On|Off|provider-name +Dav Off +directory + + +

    ÁöÁ¤ÇÑ À§Ä¡¿¡¼­ WebDAV HTTP ¸Þ½áµå¸¦ »ç¿ëÇÏ·Á¸é + Dav Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù:

    + + + <Location /foo>
    + + Dav On
    +
    + </Location> +
    + +

    On °ªÀº ½ÇÁ¦·Î mod_dav_fs + ¸ðµâÀÌ Á¦°øÇÏ´Â ±âº» Á¦°øÀÚÀÎ filesystemÀÇ + º°ÄªÀÌ´Ù. ¾î¶² À§Ä¡¿¡¼­ DAV¸¦ ½ÃÀÛÇϸé ÇÏÀ§°ø°£¿¡¼­ DAV¸¦ + »ç¿ë¾ÈÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó. ¿ÏÀüÇÑ + ¼³Á¤¿¹´Â À§ÀÇ ÀýÀ» Âü°íÇ϶ó.

    + + + ¼­¹ö¸¦ ¾ÈÀüÇÏ°Ô ±¸¼ºÇÒ¶§±îÁö WebDAVÀ» »ç¿ëÇÏÁö ¸¶¶ó. ±×·¸Áö + ¾ÊÀ¸¸é ´©±¸¶óµµ ¼­¹ö¸¦ ÅëÇØ ÆÄÀÏÀ» ºÐ¹èÇÒ ¼ö ÀÖ°Ô µÈ´Ù. + +
    +
    + + +DavMinTimeout +¼­¹ö°¡ DAV ÀÚ¿ø¿¡ ´ëÇØ À¯ÁöÇÒ Àá±ÝÀÇ Ãּҽð£ +DavMinTimeout seconds +DavMinTimeout 0 +server configvirtual host +directory + + +

    Ŭ¶óÀ̾ðÆ®°¡ DAV ÀÚ¿ø¿¡ Àá±Ý(lock)À» ¿äûÇÒ¶§ ¼­¹ö°¡ + ¾Ë¾Æ¼­ Àá±ÝÀ» Á¦°ÅÇÒ ¼ö ÀÖ´Â ½Ã°£À» °°ÀÌ ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù. ÀÌ °ªÀº + ´ÜÁö ¿äûÀÏ»ÓÀ̸ç, ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ ¿äûÇÑ °ªÀ» ¹«½ÃÇÏ°í + Ŭ¶óÀ̾ðÆ®¿¡°Ô ÀÓÀÇÀÇ ½Ã°£À» ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.

    + +

    DavMinTimeout Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô + º¸³¾ ÃÖ¼Ò Àá±Ý ½Ã°£À» (ÃÊ´ÜÀ§) ÁöÁ¤ÇÑ´Ù. Microsoft Web Folders´Â + ±âº»°ªÀ¸·Î 120 Ãʸ¦ »ç¿ëÇÑ´Ù. DavMinTimeout¿¡ + (600 ÃÊ¿Í °°ÀÌ) ´õ ³ôÀº °ªÀ» »ç¿ëÇϸé Ŭ¶óÀ̾ðÆ®°¡ ³×Æ®¿÷ + Áö¿¬¶§¹®¿¡ Àá±ÝÀ» ÀҰԵǴ °æ¿ì¸¦ ÁÙÀÏ ¼ö ÀÖ´Ù.

    + + ¿¹Á¦ + <Location /MSWord>
    + + DavMinTimeout 600
    +
    + </Location> +
    +
    +
    + + +DavDepthInfinity +PROPFINDÀÇ Depth: Infinity ¿äûÀ» Çã°¡ÇÑ´Ù +DavDepthInfinity on|off +DavDepthInfinity off +server configvirtual host +directory + + +

    DavDepthInfinity Áö½Ã¾î¸¦ »ç¿ëÇϸé + 'Depth: Infinity' Çì´õ¸¦ °¡Áø PROPFIND ¿äûÀ» + Çã°¡ÇÑ´Ù. ÀÌ·± ¿äûÀ» »ç¿ëÇÏ¿© ¼­ºñ½º°ÅºÎ °ø°ÝÀÌ °¡´ÉÇϱâ + ¶§¹®¿¡ ±âº»ÀûÀ¸·Î Çã¿ëÇÏÁö ¾Ê´Â´Ù.

    +
    +
    + +
    + + diff --git a/trunk/docs/manual/mod/mod_dav.xml.meta b/trunk/docs/manual/mod/mod_dav.xml.meta new file mode 100644 index 0000000000..927ffa2c6c --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav.xml.meta @@ -0,0 +1,13 @@ + + + + mod_dav + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_dav_fs.html b/trunk/docs/manual/mod/mod_dav_fs.html new file mode 100644 index 0000000000..44954c4ddb --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.html @@ -0,0 +1,11 @@ +URI: mod_dav_fs.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_dav_fs.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_dav_fs.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_dav_fs.html.en b/trunk/docs/manual/mod/mod_dav_fs.html.en new file mode 100644 index 0000000000..203b8bf39b --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.html.en @@ -0,0 +1,97 @@ + + + +mod_dav_fs - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dav_fs

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:filesystem provider for mod_dav
    Status:Extension
    Module Identifier:dav_fs_module
    Source File:mod_dav_fs.c
    +

    Summary

    + +

    This module requires the service of mod_dav. It acts as a support module for mod_dav and provides access to resources located in the + server's file system. The formal name of this provider is + filesystem. mod_dav backend providers + will be invoked by using the Dav + directive:

    + +

    Example

    + Dav filesystem +

    + +

    Since filesystem is the default provider for + mod_dav, you may simply use the value + On instead.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    DavLockDB Directive

    + + + + + + +
    Description:Location of the DAV lock database
    Syntax:DavLockDB file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_dav_fs
    +

    Use the DavLockDB directive to specify + the full path to the lock database, excluding an extension. If + the path is not absolute, it will be taken relative to ServerRoot. The implementation of + mod_dav_fs uses a SDBM database to track user + locks.

    + + + +

    Example

    + DavLockDB var/DavLock +

    + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running. For security reasons, you should create a + directory for this purpose rather than changing the permissions on + an existing directory. In the above example, Apache will create + files in the var/ directory under the ServerRoot with the base filename + DavLock and extension name chosen by the server.

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav_fs.html.ja.euc-jp b/trunk/docs/manual/mod/mod_dav_fs.html.ja.euc-jp new file mode 100644 index 0000000000..e0b320460d --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.html.ja.euc-jp @@ -0,0 +1,89 @@ + + + +mod_dav_fs - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_dav_fs

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:mod_dav ¤Î¤¿¤á¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥×¥í¥Ð¥¤¥À
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:dav_fs_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_dav_fs.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_dav + ¤Î¥µ¡¼¥Ó¥¹¤òɬÍפȤ·¤Þ¤¹¡£mod_dav + ¤Î¥µ¥Ý¡¼¥È¥â¥¸¥å¡¼¥ë¤È¤·¤ÆÆ°ºî¤·¡¢¥µ¡¼¥Ð¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Ë + °ÌÃÖ¤¹¤ë¥ê¥½¡¼¥¹¤Ø¤Î¥¢¥¯¥»¥¹¤òÄ󶡤·¤Þ¤¹¡£¤³¤Î¥×¥í¥Ð¥¤¥À¤ÎÀµ¼°¤Ê̾Á°¤Ï + filesystem ¤Ç¤¹¡£mod_dav + ¥Ð¥Ã¥¯¥¨¥ó¥É¥×¥í¥Ð¥¤¥À¤Ï Dav + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æµ¯Æ°¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + Dav filesystem +

    + +

    filesystem ¤Ï mod_dav + ¤Î¥Ç¥Õ¥©¥ë¥È¥×¥í¥Ð¥¤¥À¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤«¤é¡¢Âå¤ï¤ê¤Ëñ¤Ë + On ¤È»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    DavLockDB ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:DAV ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î°ÌÃÖ
    ¹½Ê¸:DavLockDB file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dav_fs
    +

    ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥Õ¥ë¥Ñ¥¹¤ò¡¢³ÈÄ¥»Ò¤ò½ü¤¤¤¿·Á¤Ç + »ØÄꤹ¤ë¤Ë¤Ï¡¢DavLockDB + ¤ò»È¤¤¤Þ¤¹¡£¥Ñ¥¹¤¬ÀäÂХѥ¹¤Ç¤Ê¤±¤ì¤Ð¡¢ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È²ò¼á¤µ¤ì¤Þ¤¹¡£ + mod_dav_fs ¼ÂÁõ¤Ç¤Ï¡¢¥æ¡¼¥¶¥í¥Ã¥¯¤ò + ÄÉÀפ¹¤ë¤¿¤á¤Ë SDBM ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò»È¤¤¤Þ¤¹¡£

    + + + +

    Îã

    + DavLockDB logs/DavLock +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav_fs.html.ko.euc-kr b/trunk/docs/manual/mod/mod_dav_fs.html.ko.euc-kr new file mode 100644 index 0000000000..600a0d6795 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.html.ko.euc-kr @@ -0,0 +1,96 @@ + + + +mod_dav_fs - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_dav_fs

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:mod_davÀ» À§ÇÑ ÆÄÀϽýºÅÛ Á¦°øÀÚ
    »óÅÂ:Extension
    ¸ðµâ¸í:dav_fs_module
    ¼Ò½ºÆÄÀÏ:mod_dav_fs.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº mod_dav ¼­ºñ½º¿¡ ÇÊ¿äÇÏ´Ù. + mod_dav¸¦ Áö¿øÇÏ´Â ¸ðµâ·Î ¼­¹öÀÇ ÆÄÀϽýºÅÛ¿¡ + ÀÖ´Â ÀÚ¿øÀ» Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ÀÌ Á¦°øÀÚ(provider)ÀÇ + Á¤½Ä¸íĪÀº filesystemÀÌ´Ù. Dav Áö½Ã¾î¸¦ ÁöÁ¤ÇÏ¿© + mod_dav µÞ´Ü Á¦°øÀÚ¸¦ »ç¿ëÇÑ´Ù:

    + +

    ¿¹Á¦

    + Dav filesystem +

    + +

    filesystemÀÌ mod_davÀÇ + ±âº» Á¦°øÀÚÀ̹ǷΠ´ë½Å OnÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    DavLockDB Áö½Ã¾î

    + + + + + + +
    ¼³¸í:DAV Àá±Ý µ¥ÀÌÅͺ£À̽º À§Ä¡
    ¹®¹ý:DavLockDB file-path
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_dav_fs
    +

    DavLockDB Áö½Ã¾î´Â Àá±Ý µ¥ÀÌÅͺ£À̽ºÀÇ + Àüü °æ·Î¸¦ È®ÀåÀÚ¸¦ Á¦¿ÜÇÏ°í ÁöÁ¤ÇÑ´Ù. Àý´ë°æ·Î°¡ ¾Æ´Ï¸é + ServerRoot¿¡ »ó´ë°æ·Î·Î + ó¸®ÇÑ´Ù. mod_dav_fs´Â Àá±ÝÀ» SDBM µ¥ÀÌÅͺ£À̽º¿¡ + ±â·ÏÇÑ´Ù.

    + + + +

    ¿¹Á¦

    + DavLockDB var/DavLock +

    + +

    ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â User¿Í + GroupÀº Àá±Ý + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù. + º¸¾È»ó ÀÌÀ¯·Î ±âÁ¸ µð·ºÅ丮ÀÇ ±ÇÇÑÀ» ¹Ù²Ù±âº¸´Ù´Â Àá±Ý + µ¥ÀÌÅͺ£À̽º¿ë µð·ºÅ丮¸¦ ¸¸µé¾î¾ß ÇÑ´Ù. À§ÀÇ °æ¿ì ¾ÆÆÄÄ¡´Â + ServerRoot ¾Æ·¡ + var/ µð·ºÅ丮¿¡ ¼­¹ö°¡ ¼±ÅÃÇÑ È®Àå¸íÀ» °¡Áø + DavLock ÆÄÀÏÀ» ¸¸µç´Ù.

    + + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav_fs.xml b/trunk/docs/manual/mod/mod_dav_fs.xml new file mode 100644 index 0000000000..e595a2e230 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.xml @@ -0,0 +1,87 @@ + + + + + + + + + +mod_dav_fs +filesystem provider for mod_dav +Extension +mod_dav_fs.c +dav_fs_module + + +

    This module requires the service of mod_dav. It acts as a support module for mod_dav and provides access to resources located in the + server's file system. The formal name of this provider is + filesystem. mod_dav backend providers + will be invoked by using the Dav + directive:

    + + Example + Dav filesystem + + +

    Since filesystem is the default provider for + mod_dav, you may simply use the value + On instead.

    +
    +mod_dav + + +DavLockDB +Location of the DAV lock database +DavLockDB file-path +server configvirtual host + + + +

    Use the DavLockDB directive to specify + the full path to the lock database, excluding an extension. If + the path is not absolute, it will be taken relative to ServerRoot. The implementation of + mod_dav_fs uses a SDBM database to track user + locks.

    + + + + Example + DavLockDB var/DavLock + + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running. For security reasons, you should create a + directory for this purpose rather than changing the permissions on + an existing directory. In the above example, Apache will create + files in the var/ directory under the ServerRoot with the base filename + DavLock and extension name chosen by the server.

    + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_dav_fs.xml.ja b/trunk/docs/manual/mod/mod_dav_fs.xml.ja new file mode 100644 index 0000000000..24616fffb4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.xml.ja @@ -0,0 +1,76 @@ + + + + + + + + + +mod_dav_fs +mod_dav $B$N$?$a$N%U%!%$%k%7%9%F%`%W%m%P%$%@(B +Extension +mod_dav_fs.c +dav_fs_module + + +

    $B$3$N%b%8%e!<%k$O(B mod_dav + $B$N%5!<%S%9$r(B$BI,MW$H$7$^$9(B$B!#(Bmod_dav + $B$N%5%]!<%H%b%8%e!<%k$H$7$FF0:n$7!"%5!<%P%U%!%$%k%7%9%F%`>e$K(B + $B0LCV$9$k%j%=!<%9$X$N%"%/%;%9$rDs6!$7$^$9!#$3$N%W%m%P%$%@$N@5<0$JL>A0$O(B + filesystem $B$G$9!#(Bmod_dav + $B%P%C%/%(%s%I%W%m%P%$%@$O(B Dav + $B%G%#%l%/%F%#%V$r;HMQ$7$F5/F0$5$l$^$9!#(B

    + + $BNc(B + Dav filesystem + + +

    filesystem $B$O(B mod_dav + $B$N%G%U%)%k%H%W%m%P%$%@$K$J$C$F$$$^$9$+$i!"Be$o$j$KC1$K(B + On $B$H;XDj$9$k$3$H$b$G$-$^$9!#(B

    +
    +mod_dav + + +DavLockDB +DAV $B%m%C%/%G!<%?%Y!<%9$N0LCV(B +DavLockDB file-path +server configvirtual host + + + +

    $B%m%C%/%G!<%?%Y!<%9$X$N%U%k%Q%9$r!"3HD%;R$r=|$$$?7A$G(B + $B;XDj$9$k$K$O!"(BDavLockDB + $B$r;H$$$^$9!#%Q%9$,@dBP%Q%9$G$J$1$l$P!"(BServerRoot $B$+$i$NAjBP%Q%9$H2rmod_dav_fs $B + + + + $BNc(B + DavLockDB logs/DavLock + + + + + + diff --git a/trunk/docs/manual/mod/mod_dav_fs.xml.ko b/trunk/docs/manual/mod/mod_dav_fs.xml.ko new file mode 100644 index 0000000000..56664593f6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.xml.ko @@ -0,0 +1,83 @@ + + + + + + + + + +mod_dav_fs +mod_davÀ» À§ÇÑ ÆÄÀϽýºÅÛ Á¦°øÀÚ +Extension +mod_dav_fs.c +dav_fs_module + +

    +

    ÀÌ ¸ðµâÀº mod_dav ¼­ºñ½º¿¡ ÇÊ¿äÇÏ´Ù. + mod_dav¸¦ Áö¿øÇÏ´Â ¸ðµâ·Î ¼­¹öÀÇ ÆÄÀϽýºÅÛ¿¡ + ÀÖ´Â ÀÚ¿øÀ» Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ÀÌ Á¦°øÀÚ(provider)ÀÇ + Á¤½Ä¸íĪÀº filesystemÀÌ´Ù. Dav Áö½Ã¾î¸¦ ÁöÁ¤ÇÏ¿© + mod_dav µÞ´Ü Á¦°øÀÚ¸¦ »ç¿ëÇÑ´Ù:

    + + ¿¹Á¦ + Dav filesystem + + +

    filesystemÀÌ mod_davÀÇ + ±âº» Á¦°øÀÚÀ̹ǷΠ´ë½Å OnÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    +
    +mod_dav + + +DavLockDB +DAV Àá±Ý µ¥ÀÌÅͺ£À̽º À§Ä¡ +DavLockDB file-path +server configvirtual host + + + +

    DavLockDB Áö½Ã¾î´Â Àá±Ý µ¥ÀÌÅͺ£À̽ºÀÇ + Àüü °æ·Î¸¦ È®ÀåÀÚ¸¦ Á¦¿ÜÇÏ°í ÁöÁ¤ÇÑ´Ù. Àý´ë°æ·Î°¡ ¾Æ´Ï¸é + ServerRoot¿¡ »ó´ë°æ·Î·Î + ó¸®ÇÑ´Ù. mod_dav_fs´Â Àá±ÝÀ» SDBM µ¥ÀÌÅͺ£À̽º¿¡ + ±â·ÏÇÑ´Ù.

    + + + + ¿¹Á¦ + DavLockDB var/DavLock + + +

    ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â User¿Í + GroupÀº Àá±Ý + µ¥ÀÌÅͺ£À̽º°¡ ÀÖ´Â µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Á®¾ß ÇÑ´Ù. + º¸¾È»ó ÀÌÀ¯·Î ±âÁ¸ µð·ºÅ丮ÀÇ ±ÇÇÑÀ» ¹Ù²Ù±âº¸´Ù´Â Àá±Ý + µ¥ÀÌÅͺ£À̽º¿ë µð·ºÅ丮¸¦ ¸¸µé¾î¾ß ÇÑ´Ù. À§ÀÇ °æ¿ì ¾ÆÆÄÄ¡´Â + ServerRoot ¾Æ·¡ + var/ µð·ºÅ丮¿¡ ¼­¹ö°¡ ¼±ÅÃÇÑ È®Àå¸íÀ» °¡Áø + DavLock ÆÄÀÏÀ» ¸¸µç´Ù.

    + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_dav_fs.xml.meta b/trunk/docs/manual/mod/mod_dav_fs.xml.meta new file mode 100644 index 0000000000..9e23cbfc4e --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_fs.xml.meta @@ -0,0 +1,13 @@ + + + + mod_dav_fs + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_dav_lock.html b/trunk/docs/manual/mod/mod_dav_lock.html new file mode 100644 index 0000000000..495493eaf7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.html @@ -0,0 +1,7 @@ +URI: mod_dav_lock.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_dav_lock.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_dav_lock.html.en b/trunk/docs/manual/mod/mod_dav_lock.html.en new file mode 100644 index 0000000000..ddf81e751b --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.html.en @@ -0,0 +1,101 @@ + + + +mod_dav_lock - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dav_lock

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    Description:generic locking module for mod_dav
    Status:Extension
    Module Identifier:dav_lock_module
    Source File:mod_dav_lock.c
    Compatibility:Available in version 2.1 and later
    +

    Summary

    + +

    This module implements a generic locking API which can be used by any + backend provider of mod_dav. It requires at least + the service of mod_dav. But without a backend provider + which makes use of it, it's useless and should not be loaded into the + server. A sample backend module which actually utilizes + mod_dav_lock, is mod_dav_svn, the subversion provider module.

    + +

    Note that mod_dav_fs does not need this + generic locking module, because it uses it's own more specialized + version.

    + +

    In order to make mod_dav_lock functional, you just have + to specify the location of the lock database using the DavGenericLockDB directive described + below.

    + +

    Developer's Note

    +

    In order to retrieve the pointer to the locking provider function, you + have to use the ap_lookup_provider API with the arguments + dav-lock, generic and 0.

    +
    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    DavGenericLockDB Directive

    + + + + + + +
    Description:Location of the DAV lock database
    Syntax:DavGenericLockDB file-path
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_dav_lock
    +

    Use the DavGenericLockDB directive to specify + the full path to the lock database, excluding an extension. If + the path is not absolute, it will be taken relative to ServerRoot. The implementation of + mod_dav_lock uses a SDBM database to track user + locks.

    + +

    Example

    + DavGenericLockDB var/DavLock +

    + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running. For security reasons, you should create a + directory for this purpose rather than changing the permissions on + an existing directory. In the above example, Apache will create + files in the var/ directory under the ServerRoot with the base filename + DavLock and extension name chosen by the server.

    + + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav_lock.html.ja.euc-jp b/trunk/docs/manual/mod/mod_dav_lock.html.ja.euc-jp new file mode 100644 index 0000000000..a630b29263 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.html.ja.euc-jp @@ -0,0 +1,105 @@ + + + +mod_dav_lock - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_dav_lock

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    ÀâÌÀ:mod_dav ÍѤÎÈÆÍÑ¥í¥Ã¥¯¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:dav_lock_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_dav_lock.c
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_dav ¤Î¤É¤Î¥Ð¥Ã¥¯¥¨¥ó¥É + ¤«¤é¤Ç¤â»È¤¨¤ëÈÆÍÑ¥í¥Ã¥¯ API ¤òÄ󶡤·¤Þ¤¹¡£ + »ÈÍѤˤϺÇÄã¸Â mod_dav + ¤òɬÍפȤ·¤Þ¤¹¤¬¡¢¤³¤ì¤òÍøÍѤ¹¤ë¥Ð¥Ã¥¯¥¨¥ó¥É¤¬Â¸ºß¤·¤Ê¤¤¤ÈÌò¤ËΩ¤¿¤Ê¤¤¤Î¤Ç¡¢ + ¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ï¥µ¡¼¥Ð¤ËÆɤ߹þ¤à¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + mod_dav_lock + ¤ò¼ÂºÝ¤ËÍøÍѤ¹¤ë¥Ð¥Ã¥¯¥¨¥ó¥É¥â¥¸¥å¡¼¥ë¤ÎÎã¤È¤·¤Æ¤Ï subversion + ¥×¥í¥Ð¥¤¥À¥â¥¸¥å¡¼¥ë¤Î mod_dav_svn ¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    mod_dav_fs ¤ÏÆò½¤µ¤ì¤¿ÀìÍѤΥС¼¥¸¥ç¥ó¤ò + »È¤¦¤¿¤á¡¢¤³¤ÎÈÆÍѥ⥸¥å¡¼¥ë¤ÏɬÍפʤ¤¤³¤È¤ËÃí°Õ¤·¤Æ + ¤¯¤À¤µ¤¤¡£

    + +

    mod_dav_lock ¤òµ¡Ç½¤µ¤»¤ë¤Ë¤Ï¡¢ + °Ê²¼¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë DavGenericLockDB ¤ò»È¤Ã¤Æ + ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ì½ê¤ò»ØÄꤹ¤ë¤À¤±¤Ç¤¹¡£

    + +

    ³«È¯¼Ô¸þ¤±¤Î¥á¥â

    +

    ¥í¥Ã¥¯¤òÄ󶡤·¤Æ¤¤¤ë´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ap_lookup_provider API ¤ò¡¢°ú¿ô dav-lock, + generic, 0 ¤ò»ØÄꤷ¤Æ»È¤¦É¬Íפ¬ + ¤¢¤ê¤Þ¤¹¡£

    +
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    DavGenericLockDB ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:DAV ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ì½ê
    ¹½Ê¸:DavGenericLockDB file-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dav_lock
    +

    DavGenericLockDB ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤Ã¤Æ¡¢³ÈÄ¥»Ò¤ò½ü¤¤¤¿¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥Õ¥ë¥Ñ¥¹¤ò + »ØÄꤷ¤Þ¤¹¡£ÀäÂХѥ¹¤Ç¤Ê¤¤¤È¤­¤Ï ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ + °·¤ï¤ì¤Þ¤¹¡£mod_dav_lock ¤Î¼ÂÁõ¤Ç¤Ï¥æ¡¼¥¶¤Î + ¥í¥Ã¥¯¤òÄÉÀפ¹¤ë¤Î¤Ë SDBM ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò»È¤¤¤Þ¤¹¡£

    + +

    Îã

    + DavGenericLockDB var/DavLock +

    + +

    ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ï + Apache ¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë User + ¤È Group ¤Ë¤è¤Ã¤Æ + ½ñ¤­¹þ¤ß²Äǽ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤«¤é¡¢ + ´û¸¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÊѹ¹¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ÀìÍѤΥǥ£¥ì¥¯¥È¥ê¤òºî¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£¾å¤ÎÎã¤Ç¤Ï¡¢ + Apache ¤Ï ServerRoot ¤Î²¼¤Î var/ + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡¢¥Õ¥¡¥¤¥ë̾¤ÎËÜÂΤ¬ DavLock ¤Ç + ¥µ¡¼¥Ð¤¬ÁªÂò¤·¤¿³ÈÄ¥»Ò¤ò»ý¤Ä¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤Þ¤¹¡£

    + + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dav_lock.xml b/trunk/docs/manual/mod/mod_dav_lock.xml new file mode 100644 index 0000000000..1f44a297fe --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.xml @@ -0,0 +1,92 @@ + + + + + + + + + +mod_dav_lock +generic locking module for mod_dav +Extension +mod_dav_lock.c +dav_lock_module +Available in version 2.1 and later + + +

    This module implements a generic locking API which can be used by any + backend provider of mod_dav. It requires at least + the service of mod_dav. But without a backend provider + which makes use of it, it's useless and should not be loaded into the + server. A sample backend module which actually utilizes + mod_dav_lock, is mod_dav_svn, the subversion provider module.

    + +

    Note that mod_dav_fs does not need this + generic locking module, because it uses it's own more specialized + version.

    + +

    In order to make mod_dav_lock functional, you just have + to specify the location of the lock database using the DavGenericLockDB directive described + below.

    + + Developer's Note +

    In order to retrieve the pointer to the locking provider function, you + have to use the ap_lookup_provider API with the arguments + dav-lock, generic and 0.

    +
    +
    +mod_dav + + +DavGenericLockDB +Location of the DAV lock database +DavGenericLockDB file-path +server configvirtual host +directory + + + +

    Use the DavGenericLockDB directive to specify + the full path to the lock database, excluding an extension. If + the path is not absolute, it will be taken relative to ServerRoot. The implementation of + mod_dav_lock uses a SDBM database to track user + locks.

    + + Example + DavGenericLockDB var/DavLock + + +

    The directory containing the lock database file must be + writable by the User + and Group under which + Apache is running. For security reasons, you should create a + directory for this purpose rather than changing the permissions on + an existing directory. In the above example, Apache will create + files in the var/ directory under the ServerRoot with the base filename + DavLock and extension name chosen by the server.

    + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_dav_lock.xml.ja b/trunk/docs/manual/mod/mod_dav_lock.xml.ja new file mode 100644 index 0000000000..932d3ad1a4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.xml.ja @@ -0,0 +1,96 @@ + + + + + + + + + +mod_dav_lock +mod_dav $BMQ$NHFMQ%m%C%/%b%8%e!<%k(B +Extension +mod_dav_lock.c +dav_lock_module + $B%P!<%8%g%s(B 2.1 $B0J9_(B + + +

    $B$3$N%b%8%e!<%k$O(B mod_dav $B$N$I$N%P%C%/%(%s%I(B + $B$+$i$G$b;H$($kHFMQ%m%C%/(B API $B$rDs6!$7$^$9!#(B + $B;HMQ$K$O:GDc8B(B mod_dav + $B$rI,MW$H$7$^$9$,!"$3$l$rMxMQ$9$k%P%C%/%(%s%I$,B8:_$7$J$$$HLr$KN)$?$J$$$N$G!"(B + $B$=$N$h$&$J>l9g$O%5!<%P$KFI$_9~$`$Y$-$G$O$"$j$^$;$s!#(B + mod_dav_lock + $B$rmod_dav_svn $B$,$"$j$^$9!#(B

    + +

    mod_dav_fs $B$OFC2=$5$l$?@lMQ$N%P!<%8%g%s$r(B + $B;H$&$?$a!"$3$NHFMQ%b%8%e!<%k$O(B$BI,MW$J$$(B$B$3$H$KCm0U$7$F(B + $B$/$@$5$$!#(B

    + +

    mod_dav_lock $B$r5!G=$5$;$k$K$O!"(B + $B0J2<$G@bL@$5$l$F$$$k(B DavGenericLockDB $B$r;H$C$F(B + $B%m%C%/%G!<%?%Y!<%9$N>l=j$r;XDj$9$k$@$1$G$9!#(B

    + + $B3+H/<T8~$1$N%a%b(B +

    $B%m%C%/$rDs6!$7$F$$$k4X?t$X$N%]%$%s%?$rap_lookup_provider API $B$r!"0z?t(B dav-lock, + generic, 0 $B$r;XDj$7$F;H$&I,MW$,(B + $B$"$j$^$9!#(B

    +
    +
    +mod_dav + + +DavGenericLockDB +DAV $B%m%C%/%G!<%?%Y!<%9$N>l=j(B +DavGenericLockDB file-path +server configvirtual host +directory + + + +

    DavGenericLockDB $B%G%#%l%/%F%#%V$r(B + $B;H$C$F!"3HD%;R$r=|$$$?%m%C%/%G!<%?%Y!<%9$X$N%U%k%Q%9$r(B + $B;XDj$7$^$9!#@dBP%Q%9$G$J$$$H$-$O(B ServerRoot $B$+$i$NAjBP%Q%9$H$7$F(B + $B07$o$l$^$9!#(Bmod_dav_lock $B$N + + $BNc(B + DavGenericLockDB var/DavLock + + +

    $B%m%C%/%G!<%?%Y!<%9%U%!%$%k$N$"$k%G%#%l%/%H%j$O(B + Apache $B$,User + $B$H(B Group $B$K$h$C$F(B + $B=q$-9~$_2DG=$G$J$1$l$P$J$j$^$;$s!#%;%-%e%j%F%#>e$NM}M3$+$i!"(B + $B4{B8$N%G%#%l%/%H%j$N%Q!<%_%C%7%g%s$rJQ99$9$k$N$G$O$J$/!"(B + $B@lMQ$N%G%#%l%/%H%j$r:n$k$N$,NI$$$G$7$g$&!#>e$NNc$G$O!"(B + Apache $B$O(B ServerRoot $B$N2<$N(B var/ + $B%G%#%l%/%H%j$K!"%U%!%$%kL>$NK\BN$,(B DavLock $B$G(B + $B%5!<%P$,A*Br$7$?3HD%;R$r;}$D%U%!%$%k$r:n@.$7$^$9!#(B

    + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_dav_lock.xml.meta b/trunk/docs/manual/mod/mod_dav_lock.xml.meta new file mode 100644 index 0000000000..c5e6cd4d61 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dav_lock.xml.meta @@ -0,0 +1,12 @@ + + + + mod_dav_lock + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_dbd.html b/trunk/docs/manual/mod/mod_dbd.html new file mode 100644 index 0000000000..53de34db2f --- /dev/null +++ b/trunk/docs/manual/mod/mod_dbd.html @@ -0,0 +1,3 @@ +URI: mod_dbd.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_dbd.html.en b/trunk/docs/manual/mod/mod_dbd.html.en new file mode 100644 index 0000000000..fef43f4c26 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dbd.html.en @@ -0,0 +1,238 @@ + + + +mod_dbd - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dbd

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Manages SQL database connections
    Status:Experimental
    Module Identifier:dbd_module
    Source File:mod_dbd.c
    Compatibility:Version 2.1 and higher
    +

    Summary

    + +

    mod_dbd manages SQL database connections using + apr_dbd. + It provides database connections on request to modules + requiring SQL database functions, and takes care of + managing databases with optimal efficiency and scalability + for both threaded and non-threaded MPMs.

    +
    + +
    top
    +
    +

    Connection Pooling

    +

    This module manages database connections, in a manner + optimised for the platform. On non-threaded platforms, + it provides a persistent connection in the manner of + classic LAMP (Linux, Apache, Mysql, Perl/PHP/Python). + On threaded platform, it provides an altogether more + scalable and efficient connection pool, as + described in this article at ApacheTutor. mod_dbd supersedes + the modules presented in that article.

    +
    top
    +
    +

    Apache DBD API

    +

    mod_dbd exports three functions for other modules + to use. The API is as follows:

    + +
    typedef struct {
    +    apr_dbd_t *handle;
    +    apr_dbd_driver_t *driver;
    +    apr_hash_t *prepared;
    +} ap_dbd_t;
    +
    +/* Export functions to access the database */
    +
    +/* acquire a connection that MUST be explicitly closed.
    + * Returns NULL on error
    + */
    +AP_DECLARE(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*);
    +
    +/* release a connection acquired with ap_dbd_open */
    +AP_DECLARE(void) ap_dbd_close(server_rec*, ap_dbd_t*);
    +
    +/* acquire a connection that will have the lifetime of a request
    + * and MUST NOT be explicitly closed.  Return NULL on error.
    + * This is the preferred function for most applications.
    + */
    +AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*);
    +
    +/* Also export them as optional functions for modules that prefer it */
    +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_open, (apr_pool_t*, server_rec*));
    +APR_DECLARE_OPTIONAL_FN(void, ap_dbd_close, (server_rec*, ap_dbd_t*));
    +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_acquire, (request_rec*));
    +
    top
    +
    +

    SQL Prepared Statements

    +

    mod_dbd supports SQL prepared statements on behalf + of modules that may wish to use them. Each prepared statement + must be assigned a name (label), and they are stored in a hash: + the prepared field of an ap_dbd_t. + Hash entries are of type apr_dbd_prepared_t + and can be used in any of the apr_dbd prepared statement + SQL query or select commands.

    + +

    It is up to dbd user modules to use the prepared statements + and document what statements can be specified in httpd.conf.

    +
    +
    top
    +

    DBDExptime Directive

    + + + + + + +
    Description:Keepalive time for idle connections
    Syntax:DBDExptime time-in-seconds
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    Set the time to keep idle connections alive where the number + of connections specified in DBDKeep has been exceeded (threaded + platforms only).

    + +
    +
    top
    +

    DBDKeep Directive

    + + + + + + +
    Description:Maximum sustainednumber of connections
    Syntax:DBDKeep number
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    Set the maximum number of connections per process to be + sustained, other than for handling peak demand (threaded + platforms only).

    + +
    +
    top
    +

    DBDMax Directive

    + + + + + + +
    Description:Maximum number of connections
    Syntax:DBDMax number
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    Set the hard maximum number of connections per process + (threaded platforms only).

    + +
    +
    top
    +

    DBDMin Directive

    + + + + + + +
    Description:Minimum number of connections
    Syntax:DBDMin number
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    Set the minimum number of connections per process (threaded + platforms only).

    + +
    +
    top
    +

    DBDParams Directive

    + + + + + + +
    Description:Parameters for database connection
    Syntax:DBDParams +param1=value1[,param2=value2]
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    As required by the underlying driver. Typically this will be + used to pass whatever cannot be defaulted amongst username, + password, database name, hostname and port number for connection.

    + +
    +
    top
    +

    DBDPersist Directive

    + + + + + + +
    Description:Whether to use persistent connections
    Syntax:DBDPersist 0|1
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    If set to 0, persistent and pooled connections are disabled. + A new database connection is opened when requested by a client, + and closed immediately on release. This option is for debugging + and low-usage servers.

    + +

    The default is to enable a pool of persistent connections + (or a single LAMP-style persistent connection in the case of a + non-threaded server), and should almost always be used in operation.

    + +
    +
    top
    +

    DBDPrepareSQL Directive

    + + + + + + +
    Description:Define an SQL prepared statement
    Syntax:DBDPrepareSQL "SQL statement" label
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    For modules such as authentication that use repeatedly use a + single SQL statement, optimum performance is achieved by preparing + the statement at startup rather than every time it is used. + This directive prepares an SQL statement and assigns it a label.

    + +
    +
    top
    +

    DBDriver Directive

    + + + + + + +
    Description:Specify an SQL driver
    Syntax:DBDriver name
    Context:server config, virtual host
    Status:Experimental
    Module:mod_dbd
    +

    Selects an apr_dbd driver by name. The driver must be installed + on your system (on most systems, it will be a shared object or dll). + For example, DBDriver mysql will select the MySQL + driver in apr_dbd_mysql.so.

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dbd.xml b/trunk/docs/manual/mod/mod_dbd.xml new file mode 100644 index 0000000000..cf923e0248 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dbd.xml @@ -0,0 +1,218 @@ + + + + + + + + + +mod_dbd +Manages SQL database connections +Experimental +mod_dbd.c +dbd_module +Version 2.1 and higher + + +

    mod_dbd manages SQL database connections using + apr_dbd. + It provides database connections on request to modules + requiring SQL database functions, and takes care of + managing databases with optimal efficiency and scalability + for both threaded and non-threaded MPMs.

    +
    + +
    Connection Pooling +

    This module manages database connections, in a manner + optimised for the platform. On non-threaded platforms, + it provides a persistent connection in the manner of + classic LAMP (Linux, Apache, Mysql, Perl/PHP/Python). + On threaded platform, it provides an altogether more + scalable and efficient connection pool, as + described in this article at ApacheTutor. mod_dbd supersedes + the modules presented in that article.

    +
    + +
    Apache DBD API +

    mod_dbd exports three functions for other modules + to use. The API is as follows:

    + + +
    typedef struct {
    +    apr_dbd_t *handle;
    +    apr_dbd_driver_t *driver;
    +    apr_hash_t *prepared;
    +} ap_dbd_t;
    +
    +/* Export functions to access the database */
    +
    +/* acquire a connection that MUST be explicitly closed.
    + * Returns NULL on error
    + */
    +AP_DECLARE(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*);
    +
    +/* release a connection acquired with ap_dbd_open */
    +AP_DECLARE(void) ap_dbd_close(server_rec*, ap_dbd_t*);
    +
    +/* acquire a connection that will have the lifetime of a request
    + * and MUST NOT be explicitly closed.  Return NULL on error.
    + * This is the preferred function for most applications.
    + */
    +AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*);
    +
    +/* Also export them as optional functions for modules that prefer it */
    +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_open, (apr_pool_t*, server_rec*));
    +APR_DECLARE_OPTIONAL_FN(void, ap_dbd_close, (server_rec*, ap_dbd_t*));
    +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_acquire, (request_rec*));
    +
    +
    + +
    SQL Prepared Statements +

    mod_dbd supports SQL prepared statements on behalf + of modules that may wish to use them. Each prepared statement + must be assigned a name (label), and they are stored in a hash: + the prepared field of an ap_dbd_t. + Hash entries are of type apr_dbd_prepared_t + and can be used in any of the apr_dbd prepared statement + SQL query or select commands.

    + +

    It is up to dbd user modules to use the prepared statements + and document what statements can be specified in httpd.conf.

    +
    + + +DBDriver +Specify an SQL driver +DBDriver name +server configvirtual host + + + +

    Selects an apr_dbd driver by name. The driver must be installed + on your system (on most systems, it will be a shared object or dll). + For example, DBDriver mysql will select the MySQL + driver in apr_dbd_mysql.so.

    +
    +
    + + +DBDParams +Parameters for database connection +DBDParams +param1=value1[,param2=value2] +server configvirtual host + + + +

    As required by the underlying driver. Typically this will be + used to pass whatever cannot be defaulted amongst username, + password, database name, hostname and port number for connection.

    +
    +
    + + +DBDPersist +Whether to use persistent connections +DBDPersist 0|1 +server configvirtual host + + + +

    If set to 0, persistent and pooled connections are disabled. + A new database connection is opened when requested by a client, + and closed immediately on release. This option is for debugging + and low-usage servers.

    + +

    The default is to enable a pool of persistent connections + (or a single LAMP-style persistent connection in the case of a + non-threaded server), and should almost always be used in operation.

    +
    +
    + + +DBDPrepareSQL +Define an SQL prepared statement +DBDPrepareSQL "SQL statement" label +server configvirtual host + + + +

    For modules such as authentication that use repeatedly use a + single SQL statement, optimum performance is achieved by preparing + the statement at startup rather than every time it is used. + This directive prepares an SQL statement and assigns it a label.

    +
    +
    + + +DBDMin +Minimum number of connections +DBDMin number +server configvirtual host + + + +

    Set the minimum number of connections per process (threaded + platforms only).

    +
    +
    + + +DBDKeep +Maximum sustainednumber of connections +DBDKeep number +server configvirtual host + + + +

    Set the maximum number of connections per process to be + sustained, other than for handling peak demand (threaded + platforms only).

    +
    +
    + + +DBDMax +Maximum number of connections +DBDMax number +server configvirtual host + + + +

    Set the hard maximum number of connections per process + (threaded platforms only).

    +
    +
    + + +DBDExptime +Keepalive time for idle connections +DBDExptime time-in-seconds +server configvirtual host + + + +

    Set the time to keep idle connections alive where the number + of connections specified in DBDKeep has been exceeded (threaded + platforms only).

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_dbd.xml.meta b/trunk/docs/manual/mod/mod_dbd.xml.meta new file mode 100644 index 0000000000..220ab319b7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dbd.xml.meta @@ -0,0 +1,11 @@ + + + + mod_dbd + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_deflate.html b/trunk/docs/manual/mod/mod_deflate.html new file mode 100644 index 0000000000..dd4e6dce92 --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.html @@ -0,0 +1,11 @@ +URI: mod_deflate.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_deflate.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_deflate.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_deflate.html.en b/trunk/docs/manual/mod/mod_deflate.html.en new file mode 100644 index 0000000000..6810ce44eb --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.html.en @@ -0,0 +1,382 @@ + + + +mod_deflate - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_deflate

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Compress content before it is delivered to the +client
    Status:Extension
    Module Identifier:deflate_module
    Source File:mod_deflate.c
    +

    Summary

    + +

    The mod_deflate module provides + the DEFLATE output filter that allows output from + your server to be compressed before being sent to the client over + the network.

    +
    + +
    top
    +
    +

    Sample Configurations

    +

    This is a simple sample configuration for the impatient.

    + +

    Compress only a few types

    + AddOutputFilterByType DEFLATE text/html text/plain text/xml +

    + +

    The following configuration, while resulting in more compressed content, + is also much more complicated. Do not use this unless you fully understand + all the configuration details.

    + +

    Compress everything except images

    + <Location />
    + + # Insert filter
    + SetOutputFilter DEFLATE
    +
    + # Netscape 4.x has some problems...
    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    +
    + # Netscape 4.06-4.08 have some more problems
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    +
    + # MSIE masquerades as Netscape, but it is fine
    + # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    +
    + # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
    + # the above regex won't work. You can use the following
    + # workaround to get the desired effect:
    + BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    +
    + # Don't compress images
    + SetEnvIfNoCase Request_URI \
    + + \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    +
    +
    + # Make sure proxies don't deliver the wrong content
    + Header append Vary User-Agent env=!dont-vary
    +
    + </Location> +

    + +
    top
    +
    +

    Enabling Compression

    + +

    Output Compression

    +

    Compression is implemented by the DEFLATE + filter. The following directive + will enable compression for documents in the container where it + is placed:

    + +

    + SetOutputFilter DEFLATE +

    + +

    Some popular browsers cannot handle compression of all content + so you may want to set the gzip-only-text/html note to + 1 to only allow html files to be compressed (see + below). If you set this to anything but 1 it + will be ignored.

    + +

    If you want to restrict the compression to particular MIME types + in general, you may use the AddOutputFilterByType directive. Here is an example of + enabling compression only for the html files of the Apache + documentation:

    + +

    + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +

    + +

    For browsers that have problems even with compression of all file + types, use the BrowserMatch directive to set the no-gzip + note for that particular browser so that no compression will be + performed. You may combine no-gzip with gzip-only-text/html to get the best results. In that case + the former overrides the latter. Take a look at the following + excerpt from the configuration example + defined in the section above:

    + +

    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +

    + +

    At first we probe for a User-Agent string that + indicates a Netscape Navigator version of 4.x. These versions + cannot handle compression of types other than + text/html. The versions 4.06, 4.07 and 4.08 also + have problems with decompressing html files. Thus, we completely + turn off the deflate filter for them.

    + +

    The third BrowserMatch + directive fixes the guessed identity of the user agent, because + the Microsoft Internet Explorer identifies itself also as "Mozilla/4" + but is actually able to handle requested compression. Therefore we + match against the additional string "MSIE" (\b means + "word boundary") in the User-Agent Header and turn off + the restrictions defined before.

    + +

    Note

    + The DEFLATE filter is always inserted after RESOURCE + filters like PHP or SSI. It never touches internal subrequests. +
    +

    Note

    + There is a environment variable force-gzip, + set via SetEnv, which + will ignore the accept-encoding setting of your browser and will + send compressed output. +
    + + +

    Output Decompression

    +

    The mod_deflate module also provides a filter for + inflating/uncompressing a gzip compressed response body. In order to activate + this feature you have to insert the INFLATE filter into + the outputfilter chain using SetOutputFilter or AddOutputFilter, for example:

    + +

    + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +

    + +

    This Example will uncompress gzip'ed output from example.com, so other + filters can do further processing with it. +

    + + +

    Input Decompression

    +

    The mod_deflate module also provides a filter for + decompressing a gzip compressed request body . In order to activate + this feature you have to insert the DEFLATE filter into + the input filter chain using SetInputFilter or AddInputFilter, for example:

    + +

    + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +

    + +

    Now if a request contains a Content-Encoding: + gzip header, the body will be automatically decompressed. + Few browsers have the ability to gzip request bodies. However, + some special applications actually do support request + compression, for instance some WebDAV clients.

    + +

    Note on Content-Length

    +

    If you evaluate the request body yourself, don't trust + the Content-Length header! + The Content-Length header reflects the length of the + incoming data from the client and not the byte count of + the decompressed data stream.

    +
    + +
    top
    +
    +

    Dealing with proxy servers

    + +

    The mod_deflate module sends a Vary: + Accept-Encoding HTTP response header to alert proxies that + a cached response should be sent only to clients that send the + appropriate Accept-Encoding request header. This + prevents compressed content from being sent to a client that will + not understand it.

    + +

    If you use some special exclusions dependent + on, for example, the User-Agent header, you must + manually configure an addition to the Vary header + to alert proxies of the additional restrictions. For example, + in a typical configuration where the addition of the DEFLATE + filter depends on the User-Agent, you should add:

    + +

    + Header append Vary User-Agent +

    + +

    If your decision about compression depends on other information + than request headers (e.g. HTTP version), you have to set the + Vary header to the value *. This prevents + compliant proxies from caching entirely.

    + +

    Example

    + Header set Vary * +

    +
    +
    top
    +

    DeflateBufferSize Directive

    + + + + + + + +
    Description:Fragment size to be compressed at one time by zlib
    Syntax:DeflateBufferSize value
    Default:DeflateBufferSize 8096
    Context:server config, virtual host
    Status:Extension
    Module:mod_deflate
    +

    The DeflateBufferSize directive specifies + the size in bytes of the fragments that zlib should compress at one + time.

    + +
    +
    top
    +

    DeflateCompressionLevel Directive

    + + + + + + + + +
    Description:How much compression do we apply to the output
    Syntax:DeflateCompressionLevel value
    Default:Zlib's default
    Context:server config, virtual host
    Status:Extension
    Module:mod_deflate
    Compatibility:This directive is available since Apache 2.0.45
    +

    The DeflateCompressionLevel directive specifies + what level of compression should be used, the higher the value, + the better the compression, but the more CPU time is required to + achieve this.

    +

    The value must between 1 (less compression) and 9 (more compression).

    + +
    +
    top
    +

    DeflateFilterNote Directive

    + + + + + + + +
    Description:Places the compression ratio in a note for logging
    Syntax:DeflateFilterNote [type] notename
    Context:server config, virtual host
    Status:Extension
    Module:mod_deflate
    Compatibility:type is available since Apache 2.0.45
    +

    The DeflateFilterNote directive + specifies that a note about compression ratios should be attached + to the request. The name of the note is the value specified for + the directive. You can use that note for statistical purposes by + adding the value to your access log.

    + +

    Example

    + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    If you want to extract more accurate values from your logs, you + can use the type argument to specify the type of data + left as note for logging. type can be one of:

    + +
    +
    Input
    +
    Store the byte count of the filter's input stream in the note.
    + +
    Output
    +
    Store the byte count of the filter's output stream in the note.
    + +
    Ratio
    +
    Store the compression ratio (output/input * 100) + in the note. This is the default, if the type argument + is omitted.
    +
    + +

    Thus you may log it this way:

    + +

    Accurate Logging

    + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    See also

    + +
    +
    top
    +

    DeflateMemLevel Directive

    + + + + + + + +
    Description:How much memory should be used by zlib for compression
    Syntax:DeflateMemLevel value
    Default:DeflateMemLevel 9
    Context:server config, virtual host
    Status:Extension
    Module:mod_deflate
    +

    The DeflateMemLevel directive specifies + how much memory should be used by zlib for compression + (a value between 1 and 9).

    + +
    +
    top
    +

    DeflateWindowSize Directive

    + + + + + + + +
    Description:Zlib compression window size
    Syntax:DeflateWindowSize value
    Default:DeflateWindowSize 15
    Context:server config, virtual host
    Status:Extension
    Module:mod_deflate
    +

    The DeflateWindowSize directive specifies the + zlib compression window size (a value between 1 and 15). Generally, the + higher the window size, the higher can the compression ratio be expected.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_deflate.html.ja.euc-jp b/trunk/docs/manual/mod/mod_deflate.html.ja.euc-jp new file mode 100644 index 0000000000..619ea7290d --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.html.ja.euc-jp @@ -0,0 +1,383 @@ + + + +mod_deflate - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_deflate

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤é¤ì¤ëÁ°¤Ë¥³¥ó¥Æ¥ó¥Ä¤ò°µ½Ì¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:deflate_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_deflate.c
    +

    ³µÍ×

    + +

    mod_deflate ¥â¥¸¥å¡¼¥ë¤Ï DEFLATE + ½ÐÎÏ¥Õ¥£¥ë¥¿¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤Ï¥µ¡¼¥Ð¤«¤é¤Î½ÐÎϤò¡¢¥Í¥Ã¥È¥ï¡¼¥¯¤ò + Ä̤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ëÁ°¤Ë°µ½Ì¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥µ¥ó¥×¥ëÀßÄê

    +

    ²¼¤Ë¤»¤Ã¤«¤Á¤Ê¿Í¸þ¤±¤Î´Êñ¤ÊÀßÄêÎã¤ò¼¨¤·¤Þ¤¹¡£

    + +

    ¿ô¥¿¥¤¥×¤Î¤ß°µ½Ì¤¹¤ë

    + AddOutputFilterByType DEFLATE text/html text/plain text/xml +

    + +

    °Ê²¼¤ÎÀßÄê¤Ï¥³¥ó¥Æ¥ó¥Ä¤ò¤è¤ê°µ½Ì¤·¤Þ¤¹¤¬¡¢¤º¤Ã¤ÈÊ£»¨¤ÊÀßÄê¤Ë¤Ê¤ê¤Þ¤¹¡£ + ÀßÄê¤Î¶ù¡¹¤Þ¤Ç¤è¤¯Íý²ò¤·¤Ê¤¤¤Ç»È¤ï¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£

    + +

    ²èÁü°Ê³°Á´¤Æ°µ½Ì¤¹¤ë

    + <Location />
    + + # Insert filter
    + SetOutputFilter DEFLATE
    +
    + # Netscape 4.x has some problems...
    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    +
    + # Netscape 4.06-4.08 have some more problems
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    +
    + # MSIE masquerades as Netscape, but it is fine
    + # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    +
    + # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
    + # the above regex won't work. You can use the following
    + # workaround to get the desired effect:
    + BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    +
    + # Don't compress images
    + SetEnvIfNoCase Request_URI \
    + + \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    +
    +
    + # Make sure proxies don't deliver the wrong content
    + Header append Vary User-Agent env=!dont-vary
    +
    + </Location> +

    + +
    top
    +
    +

    °µ½Ì¤òÍ­¸ú¤Ë¤¹¤ë

    + +

    Output Compression

    +

    °µ½Ìµ¡Ç½¤Ï DEFLATE ¥Õ¥£¥ë¥¿ + ¤Ë¤è¤ê¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤¢¤ë + ¥³¥ó¥Æ¥ÊÃæ¤Î¥É¥­¥å¥á¥ó¥È¤ò°µ½Ì¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹:

    + +

    + SetOutputFilter DEFLATE +

    + +

    ¤è¤¯»È¤ï¤ì¤Æ¤¤¤ë¥Ö¥é¥¦¥¶¤Ç¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥Ä¤ËÂФ¹¤ë + °µ½Ì¤ò°·¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é¡¢gzip-only-text/html + ¥Î¡¼¥È¤ò 1 ¤Ë¤·¤Æ¡¢html ¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ¤Î¤ß + °µ½Ì¤¬Æ¯¤¯¤è¤¦¤Ë¤·¤¿Êý¤¬¤è¤¤¤«¤â¤·¤ì¤Þ¤»¤ó (°Ê²¼»²¾È) + ¤³¤ÎÃͤò 1 °Ê³°¤ÎÃͤËÀßÄꤷ¤¿¾ì¹ç¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +

    Ä̾ÆÃÄê¤ÎMIME¥¿¥¤¥×¤Ë¤Ä¤¤¤Æ¤Î¤ß°µ½Ì¤·¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢ + AddOutputFilterByType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Þ¤¹¡£¼¡¤Ë Apache ¤Î¥É¥­¥å¥á¥ó¥È¤Î html + ¥Õ¥¡¥¤¥ë¤Î¤ß¤Î°µ½Ì¤òÍ­¸ú¤Ë¤¹¤ëÎã¤ò¼¨¤·¤Þ¤¹¡£

    + +

    + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +

    + +

    Á´¤Æ¤Î¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤Ç¤Î°µ½Ì¤ËÌäÂê¤òÊú¤¨¤Æ¤¤¤ë¥Ö¥é¥¦¥¶¤ËÂФ·¤Æ¤Ï¡¢ + BrowserMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¡¢ÆÃÄê¤Î¥Ö¥é¥¦¥¶¤Ë no-gzip + ¥Î¡¼¥È¤ò¥»¥Ã¥È¤·¡¢°µ½Ì¤¬¹Ô¤Ê¤ï¤ì¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£ + no-gzip ¤È gzip-only-text/html + ¤òÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¾å¼ê¤¯Âнè¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢Á°¼Ô¤¬¸å¼Ô¤ò¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹¡£ + ¾åµ­¤ÎÀßÄêÎã¤ÎÈ´¿è¤ò + ¼¡¤Ë¼¨¤·¤Þ¤¹¤Î¤Ç¤´Í÷²¼¤µ¤¤¡£

    + +

    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +

    + +

    ¤Þ¤º»Ï¤á¤Ë User-Agent ʸ»úÎ󤫤é Netscape Navigator + 4.x ¤Ç¤¢¤ë¤«¤É¤¦¤«¤òÄ´¤Ù¤Þ¤¹¡£¤³¤ì¤é¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢ + text/html °Ê³°¤Î¥¿¥¤¥×¤Î°µ½Ì¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£ + 4.06, 4.07, 4.08 ¤Ï html ¥Õ¥¡¥¤¥ë¤Î¿­Ä¥¤Ë¤âÌäÂê¤òÊú¤¨¤Æ¤¤¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¤³¤ì¤é¤ËÂФ·¤Æ¤Ï¡¢´°Á´¤Ë deflate ¥Õ¥£¥ë¥¿¤ò¥ª¥Õ¤Ë¤·¤Þ¤¹¡£

    + +

    3 ÈÖÌܤΠBrowserMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢¿ä¬¤·¤¿¥æ¡¼¥¶¡¼¥¨¡¼¥¸¥§¥ó¥È¤ò½¤Àµ¤·¤Þ¤¹¡£ + ¤Ê¤¼¤Ê¤é Microsoft Internet Explorer ¤â "Mozilla/4" ¤ÈÆÃÄꤵ¤ì¤Þ¤¹¤¬¡¢ + ¤³¤ì¤é¤Ï¼ÂºÝ¤Ë¤Ï°µ½Ì¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤ë¤«¤é¤Ç¤¹¡£ + User-Agent ¥Ø¥Ã¥À¤ò "MSIE" + (\b ¤Ï¡Öñ¸ì¤Î¶­³¦¡×¤ò°ÕÌ£¤·¤Þ¤¹) ¤ÎÄɲÃʸ»ú¤Ç¸¡ºº¤·¤Æ¡¢ + ¤³¤ì°ÊÁ°¤ËÀßÄꤷ¤¿À©¸Â¤òºÆ¤Ó²ò½ü¤·¤Þ¤¹¡£

    + +

    Ãí

    + DEFLATE ¥Õ¥£¥ë¥¿¤Ïɬ¤º¡¢PHP ¤ä SSI ¤È¤¤¤Ã¤¿ RESOURCE + ¥Õ¥£¥ë¥¿¤Î¸å¤Ë¤Ê¤ê¤Þ¤¹¡£ + DEFLATE ¥Õ¥£¥ë¥¿¤ÏÆâÉôŪ¤Ê¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤ò´ØÃΤ·¤Þ¤»¤ó¡£ +
    +

    Ãí

    + SetEnv ¤ÇÀßÄꤵ¤ì¤ë + force-gzip ´Ä¶­ÊÑ¿ô¤¬¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ì¤Ï + ¥Ö¥é¥¦¥¶¤Î accept-encoding ÀßÄê¤ò̵»ë¤·¡¢°µ½Ì¤·¤¿½ÐÎϤò¤·¤Þ¤¹¡£ +
    + + +

    ½ÐÎϤο­Ä¹

    +

    mod_deflate ¥â¥¸¥å¡¼¥ë¤Ï¡¢gzip °µ½Ì¤µ¤ì¤¿¥ì¥¹¥Ý¥ó¥¹ + ËÜʸ¤ò inflate/uncompress ¤¹¤ë¥Õ¥£¥ë¥¿¤âÄ󶡤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢SetOutputFilter + ¤ä AddOutputFilter ¤ò»È¤Ã¤Æ¡¢ + INFLATE ¥Õ¥£¥ë¥¿¤ò½ÐÎÏ¥Õ¥£¥ë¥¿¥Á¥§¥¤¥ó¤ËÁÞÆþ¤·¤Þ¤¹¡£ + Î㤨¤Ð¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +

    + +

    ¤³¤ÎÎã¤Ç¤Ï¡¢example.com ¤«¤é¤Î gzip °µ½Ì¤µ¤ì¤¿½ÐÎϤò¿­Ä¹¤·¡¢ + ¤½¤Î¾¤Î¥Õ¥£¥ë¥¿¤¬¤µ¤é¤Ë¤½¤Î½ÐÎϤò½èÍý¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ +

    + + +

    ÆþÎϤο­Ä¥

    +

    mod_deflate ¥â¥¸¥å¡¼¥ë¤Ï¡¢gzip + ¤Ç°µ½Ì¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥ÈËÜÂΤò¿­Ä¥¤¹¤ë¥Õ¥£¥ë¥¿¤âÄ󶡤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢SetInputFilter + ¤« AddInputFilter ¤ò»ÈÍѤ·¤Æ¡¢ + DEFLATE ¥Õ¥£¥ë¥¿¤òÆþÎÏ¥Õ¥£¥ë¥¿¥Á¥§¥¤¥ó¤ËÁȤ߹þ¤ß¤Þ¤¹¡£ + Î㤨¤Ð¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +

    + +

    ¤³¤ÎÀßÄê¤Ç¤¢¤ì¤Ð¡¢Content-Encoding: gzip + ¥Ø¥Ã¥À¤ò´Þ¤à¥ê¥¯¥¨¥¹¥È¤¬Íè¤ë¤È¡¢ËÜÂΤϼ«Æ°Åª¤Ë¿­Ä¥¤µ¤ì¤Þ¤¹¡£ + gzip ¥ê¥¯¥¨¥¹¥ÈËÜÂΤòÁ÷¿®¤¹¤ë¥Ö¥é¥¦¥¶¤Ï¤¢¤Þ¤ê¤¢¤ê¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢Î㤨¤Ð WebDAV + ¥¯¥é¥¤¥¢¥ó¥È¤Î´ö¤Ä¤«¤Ê¤É¡¢ÆÃÊ̤ʥ¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç¥ê¥¯¥¨¥¹¥È¤Î + °µ½Ì¤ò¼ÂºÝ¤Ë¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£

    + +

    Content-Length ¤Ë´Ø¤¹¤ëÃí°Õ

    +

    ¥ê¥¯¥¨¥¹¥ÈËÜÂΤ½¤ì¼«ÂΤòɾ²Á¤¹¤ë¾ì¹ç¤Ï¡¢Content-Length + ¥Ø¥Ã¥À¤ò¿®ÍѤ·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£Content-Length ¥Ø¥Ã¥À¤Ï¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤«¤éÁ÷¿®¤µ¤ì¤ë¥Ç¡¼¥¿¤ÎŤµ¤òÈ¿±Ç¤·¤Æ¤¤¤ë¤Î¤Ç¤¢¤Ã¤Æ¡¢ + ¿­Ä¥¤µ¤ì¤¿¥Ç¡¼¥¿¥¹¥È¥ê¡¼¥à¤Î¥Ð¥¤¥È¥«¥¦¥ó¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    Proxy ¥µ¡¼¥Ð¤Ç¤Î°·¤¤

    + +

    mod_deflate ¥â¥¸¥å¡¼¥ë¤Ï Vary: Accept-Encoding + HTTP ±þÅú¥Ø¥Ã¥À¤òÁ÷¿®¤·¤Æ¡¢Å¬ÀÚ¤Ê Accept-Encoding + ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤òÁ÷¿®¤¹¤ë¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¤Î¤ß¡¢ + ¥×¥í¥¯¥·¥µ¡¼¥Ð¤¬¥­¥ã¥Ã¥·¥å¤·¤¿±þÅú¤òÁ÷¿®¤¹¤ë¤è¤¦¤ËÃí°Õ¤ò´­µ¯¤·¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë¤·¤Æ¡¢°µ½Ì¤ò°·¤¦¤³¤È¤Î¤Ç¤­¤Ê¤¤¥¯¥é¥¤¥¢¥ó¥È¤Ë + °µ½Ì¤µ¤ì¤¿ÆâÍƤ¬Á÷¤é¤ì¤ë¤³¤È¤Î¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    ¤â¤·ÆÃÊ̤˲¿¤«¤Ë°Í¸¤·¤Æ½ü³°¤·¤¿¤¤¾ì¹ç¡¢Î㤨¤Ð User-Agent + ¥Ø¥Ã¥À¤Ê¤É¤Ë°Í¸¤·¤Æ¤¤¤ë¾ì¹ç¡¢¼êÆ°¤Ç Vary ¥Ø¥Ã¥À¤òÀßÄꤷ¤Æ¡¢ + ÄɲäÎÀ©¸Â¤Ë¤Ä¤¤¤Æ¥×¥í¥¯¥·¥µ¡¼¥Ð¤ËÃí°Õ¤ò¹Ô¤Ê¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + Î㤨¤Ð User-Agent ¤Ë°Í¸¤·¤Æ DEFLATE + ¤òÄɲ乤ëŵ·¿Åª¤ÊÀßÄê¤Ç¤Ï¡¢¼¡¤Î¤è¤¦¤ËÄɲ乤뤳¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + Header append Vary User-Agent +

    + +

    ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À°Ê³°¤Î¾ðÊó (Î㤨¤Ð HTTP ¥Ð¡¼¥¸¥ç¥ó) + ¤Ë°Í¸¤·¤Æ°µ½Ì¤¹¤ë¤«¤É¤¦¤«·è¤á¤ë¾ì¹ç¡¢ + Vary ¥Ø¥Ã¥À¤ò * ¤ËÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë¤¹¤ë¤È¡¢»ÅÍͤ˽àµò¤·¤¿¥×¥í¥¯¥·¤Ï¥­¥ã¥Ã¥·¥å¤òÁ´¤¯¹Ô¤Ê¤ï¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + Header set Vary * +

    +
    +
    top
    +

    DeflateBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:zlib ¤¬°ìÅ٤˰µ½Ì¤¹¤ë²ô¤ÎÂ礭¤µ
    ¹½Ê¸:DeflateBufferSize value
    ¥Ç¥Õ¥©¥ë¥È:DeflateBufferSize 8096
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_deflate
    +

    DeflateBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + zlib ¤¬°ìÅ٤˰µ½Ì¤¹¤ë²ô¤ÎÂ礭¤µ¤ò¥Ð¥¤¥Èñ°Ì¤Ç»ØÄꤷ¤Þ¤¹¡£

    + +
    +
    top
    +

    DeflateCompressionLevel ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:½ÐÎϤËÂФ·¤Æ¹Ô¤Ê¤¦°µ½Ì¤ÎÄøÅÙ
    ¹½Ê¸:DeflateCompressionLevel value
    ¥Ç¥Õ¥©¥ë¥È:Zlib ¤Î¥Ç¥Õ¥©¥ë¥È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_deflate
    ¸ß´¹À­:This directive is available since Apache 2.0.45
    +

    DeflateCompressionLevel ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + °µ½Ì¤ÎÄøÅÙ¤òÀßÄꤷ¤Þ¤¹¡£Â礭¤ÊÃͤǤϡ¢¤è¤ê°µ½Ì¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¤¬¡¢ + CPU »ñ¸»¤ò¾ÃÈñ¤·¤Þ¤¹¡£

    +

    ÃÍ¤Ï 1 (Äã°µ½Ì) ¤«¤é 9 (¹â°µ½Ì) ¤Ç¤¹¡£

    + +
    +
    top
    +

    DeflateFilterNote ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥í¥®¥ó¥°ÍѤ˰µ½ÌÈæ¤ò¥á¥â¤ËÄɲÃ
    ¹½Ê¸:DeflateFilterNote [type] notename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_deflate
    ¸ß´¹À­:type is available since Apache 2.0.45
    +

    DeflateFilterNote ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + °µ½ÌÈæ¤Ë´Ø¤¹¤ë¥á¥â¤¬¥ê¥¯¥¨¥¹¥È¤ËÉղ䵤ì¤ë¤³¤È¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥á¥â (note) ¤Î̾Á°¤Ï¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë»ØÄꤵ¤ì¤¿ÃͤǤ¹¡£ + ¥á¥â¤Ï¥¢¥¯¥»¥¹¥í¥°¤Ë + Ãͤòµ­Ï¿¤·¡¢Åý·×¤ò¼è¤ëÌÜŪ¤Ë¤â»È¤¨¤Þ¤¹¡£

    + +

    Îã

    + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    ¥í¥°¤«¤é¤â¤Ã¤ÈÀºÌ©¤ÊÃͤòÃê½Ð¤·¤¿¤¤¾ì¹ç¤Ï¡¢type + °ú¿ô¤ò»ÈÍѤ·¤Æ¡¢¥Ç¡¼¥¿¥¿¥¤¥×¤ò¥í¥°¤Î¥á¥â¤È¤·¤Æ»Ä¤¹¤è¤¦¤Ë»ØÄê¤Ç¤­¤Þ¤¹¡£ + type ¤Ï¼¡¤Î¤¦¤Á¤Î°ì¤Ä¤Ç¤¹¡£

    + +
    +
    Input
    +
    ¥Õ¥£¥ë¥¿¤ÎÆþÎÏ¥¹¥È¥ê¡¼¥à¤Î¥Ð¥¤¥È¥«¥¦¥ó¥È¤ò¥á¥â¤ËÊݸ¤¹¤ë¡£
    + +
    Output
    +
    ¥Õ¥£¥ë¥¿¤Î½ÐÎÏ¥¹¥È¥ê¡¼¥à¤Î¥Ð¥¤¥È¥«¥¦¥ó¥È¤ò¥á¥â¤ËÊݸ¤¹¤ë¡£
    + +
    Ratio
    +
    °µ½ÌΨ (½ÐÎÏ / ÆþÎÏ * 100) ¤ò¥á¥â¤ËÊݸ¤¹¤ë¡£ + type °ú¿ô¤ò¾Êά¤·¤¿¾ì¹ç¤Ï¡¢¤³¤ì¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ê¤Þ¤¹¡£
    +
    + +

    ¤Þ¤È¤á¤ë¤È¡¢¼¡¤Î¤è¤¦¤Ë¥í¥°¤ò¼è¤ë¤³¤È¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    + +

    ÀºÌ©¤Ê¥í¥°ºÎ¼è

    + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    »²¾È

    + +
    +
    top
    +

    DeflateMemLevel ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:zlib ¤¬°µ½Ì¤Ë»È¤¦¥á¥â¥ê¤Î¥ì¥Ù¥ë¤ò»ØÄê
    ¹½Ê¸:DeflateMemLevel value
    ¥Ç¥Õ¥©¥ë¥È:DeflateMemLevel 9
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_deflate
    +

    DeflateMemLevel ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + zlib ¤¬°µ½Ì¤Ë»È¤¦¥á¥â¥ê¤Î¥ì¥Ù¥ë¤òÀßÄꤷ¤Þ¤¹ (1 ¤«¤é 9 ¤Î´Ö¤ÎÃÍ)¡£ + (ÌõÃí: 2 ¤òÄì¤È¤¹¤ëÂпô¤ÎÃͤˤʤê¤Þ¤¹¡£ + 8 ÄøÅÙ¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£)

    + +
    +
    top
    +

    DeflateWindowSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Zlib ¤Î°µ½ÌÍÑ¥¦¥£¥ó¥É¥¦¤ÎÂ礭¤µ
    ¹½Ê¸:DeflateWindowSize value
    ¥Ç¥Õ¥©¥ë¥È:DeflateWindowSize 15
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_deflate
    +

    DeflateWindowSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + zlib ¤Î°µ½ÌÍÑ¥¦¥£¥ó¥É¥¦ (ÌõÃí: zlib ¤Ç»ÈÍѤµ¤ì¤ëÍúÎò¥Ð¥Ã¥Õ¥¡) + ¤ÎÂ礭¤µ¤ò»ØÄꤷ¤Þ¤¹ (1 ¤«¤é 15 ¤Î´Ö¤ÎÃÍ)¡£ + °ìÈÌŪ¤ËÂ礭¤Ê¥¦¥£¥ó¥É¥¦¥µ¥¤¥º¤ò»ÈÍѤ¹¤ë¤È°µ½ÌΨ¤¬¸þ¾å¤·¤Þ¤¹¡£ + (ÌõÃí: 2 ¤òÄì¤È¤¹¤ëÂпô¤ÎÃͤˤʤê¤Þ¤¹¡£ + 8 ¤«¤é 15 ¤Ë¤¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£)

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_deflate.html.ko.euc-kr b/trunk/docs/manual/mod/mod_deflate.html.ko.euc-kr new file mode 100644 index 0000000000..1772bfe109 --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.html.ko.euc-kr @@ -0,0 +1,366 @@ + + + +mod_deflate - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_deflate

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:³»¿ëÀ» Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ ¾ÐÃàÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:deflate_module
    ¼Ò½ºÆÄÀÏ:mod_deflate.c
    +

    ¿ä¾à

    + +

    mod_deflate ¸ðµâÀº ¼­¹öÀÇ Ãâ·ÂÀ» ³×Æ®¿÷À¸·Î + Ŭ¶óÀ̾ðÆ®¿¡ º¸³»±â Àü¿¡ ¾ÐÃàÇÏ´Â DEFLATE Ãâ·ÂÇÊÅ͸¦ + Á¦°øÇÑ´Ù.

    +
    + +
    top
    +
    +

    °ßº» ¼³Á¤

    +

    ±ÞÇÑ »ç¶÷À» À§ÇÑ °ßº» ¼³Á¤ÀÌ´Ù.

    + +

    ÀϺΠtype¸¸ ¾ÐÃà

    + AddOutputFilterByType DEFLATE text/html text/plain text/xml +

    + +

    ¾Æ·¡ ¼³Á¤Àº ¿ä¾àÇÏ¿´Áö¸¸ ±×·¡µµ º¹ÀâÇÏ´Ù. ¼³Á¤À» ¿ÏÀüÈ÷ + ÀÌÇØÇÑ ÈÄ »ç¿ëÇ϶ó.

    + +

    À̹ÌÁö¸¦ Á¦¿ÜÇÑ ¸ðµç °ÍÀ» ¾ÐÃà

    + <Location />
    + + # ÇÊÅ͸¦ Ãß°¡ÇÑ´Ù
    + SetOutputFilter DEFLATE
    +
    + # Netscape 4.x¿¡ ¹®Á¦°¡ ÀÖ´Ù...
    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    +
    + # Netscape 4.06-4.08¿¡ ´õ ¹®Á¦°¡ ÀÖ´Ù
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    +
    + # MSIEÀº Netscape¶ó°í ÀÚ½ÅÀ» ¾Ë¸®Áö¸¸, ¹®Á¦°¡ ¾ø´Ù
    + # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    +
    + # ÁÖÀÇ: ¾ÆÆÄÄ¡ 2.0.48±îÁö mod_setenvifÀÇ ¹ö±×¶§¹®¿¡
    + # À§ÀÇ Á¤±ÔÇ¥Çö½ÄÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù. ¿øÇÏ´Â È¿°ú¸¦
    + # ¾ò±âÀ§ÇØ ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÏ¿© »ç¿ëÇÑ´Ù:
    + BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    +
    + # À̹ÌÁö¸¦ ¾ÐÃàÇÏÁö ¾Ê´Â´Ù
    + SetEnvIfNoCase Request_URI \
    + + \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    +
    +
    + # ÇÁ·Ï½Ã°¡ À߸øµÈ ³»¿ëÀ» Àü´ÞÇÏÁö¾Êµµ·Ï ÇÑ´Ù
    + Header append Vary User-Agent env=!dont-vary
    +
    + </Location> +

    + +
    top
    +
    +

    ¾ÐÃàÇϱâ

    + +

    Ãâ·Â ¾ÐÃà

    +

    DEFLATE ÇÊÅÍ°¡ + ¾ÐÃàÀ» ÇÑ´Ù. ´ÙÀ½ Áö½Ã¾î´Â Áö½Ã¾î°¡ ÀÖ´Â À§Ä¡ÀÇ ¹®¼­¸¦ + ¾ÐÃàÇÑ´Ù:

    + +

    + SetOutputFilter DEFLATE +

    + +

    ¸ðµç ³»¿ëÀ» ¾ÐÃàÇϸé ó¸®ÇÏÁö ¸øÇÏ´Â ºê¶ó¿ìÀú°¡ Àֱ⶧¹®¿¡ + html ÆÄÀϸ¸À» ¾ÐÃàÇϱâÀ§ÇØ (¾Æ·¡ Âü°í) + gzip-only-text/htmlÀ» 1·Î ¼³Á¤ÇÒÁöµµ + ¸ð¸¥´Ù. À̸¦ 1ÀÌ ¾Æ´Ñ °ªÀ¸·Î ¼³Á¤Çϸé + ¹«½ÃÇÑ´Ù.

    + +

    º¸Åë Ưº°ÇÑ MIME type¸¸ ¾ÐÃàÇÏ·Á¸é AddOutputFilterByType Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ´ÙÀ½ ¼³Á¤Àº html ÆÄÀϸ¸À» ¾ÐÃàÇÑ´Ù:

    + +

    + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +

    + +

    ¾ÐÃàÇÑ ÆÄÀÏÀ» ó¸®ÇÏÁö ¸øÇÏ´Â ºê¶ó¿ìÀú¿¡°Ô´Â ¾ÐÃàÇÏÁö¾Ê°í + º¸³»±æÀ§ÇØ BrowserMatch Áö½Ã¾î¿¡ no-gzipÀ» + ¼³Á¤ÇÑ´Ù. ÃÖÀûÀÇ °á°ú¸¦ ¾ò±âÀ§ÇØ no-gzip°ú + gzip-only-text/htmlÀ» °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ÀÌ °æ¿ì ÀüÀÚ°¡ ÈÄÀÚ¸¦ ¹«½ÃÇÑ´Ù. À§ ÀýÀÇ ¼³Á¤ ¿¹Á¦ ÀϺθ¦ »ìÆ캸ÀÚ:

    + +

    + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +

    + +

    ¸ÕÀú User-Agent ¹®ÀÚ¿­À» º¸°í Netscape + Navigator ¹öÀü 4.xÀÎÁö °Ë»çÇÑ´Ù. ÀÌ ¹öÀüÀº text/htmlÀÌ + ¾Æ´Ñ typeÀÇ ¾ÐÃàÀ» ó¸®ÇÏÁö ¸øÇÑ´Ù. ¹öÀü 4.06, 4.07, 4.08Àº + html ÆÄÀÏ ¾ÐÃàÀ» ó¸®Çϴ´뵵 ¹®Á¦°¡ ÀÖ´Ù. ±×·¡¼­ ¿ì¸®´Â + ÀÌ °æ¿ì deflate ÇÊÅ͸¦ ¿ÏÀüÈ÷ »ç¿ëÇÏÁö¾Ê´Â´Ù.

    + +

    ¼¼¹ø° BrowserMatch + Áö½Ã¾î´Â Microsoft Internet Explorer°¡ ÀÚ½ÅÀ» "Mozilla/4"·Î + ¾Ë¸®Áö¸¸ ¾ÐÃàµÈ ¿äûÀ» ó¸®ÇÒ ¼ö Àֱ⶧¹®¿¡ user agent + ÃßÃøÀ» ¼öÁ¤ÇÑ´Ù. User-Agent Çì´õ¿¡¼­ "MSIE" + (\b´Â "´Ü¾î °æ°è"¸¦ ¶æÇÑ´Ù) ¹®ÀÚ¿­À» ¹ß°ßÇϸé + ¾Õ¿¡¼­ ¼³Á¤ÇÑ Á¦¾àÀ» Ǭ´Ù.

    + +

    ÁÖÀÇ

    + DEFLATE ÇÊÅÍ´Â Ç×»ó PHP³ª SSI¿Í °°Àº RESOURCE + ÇÊÅÍ µÚ¿¡ µé¾î°£´Ù. ¶Ç, ³»ºÎ ÇÏÀ§¿äû(subrequest)¿¡ ¿µÇâÀ» + ÁÖÁö ¾Ê´Â´Ù. +
    +

    ÁÖÀÇ

    + SetEnv·Î + force-gzip ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ¸é ºê¶ó¿ìÀúÀÇ + accept-encoding ¼³Á¤À» ¹«½ÃÇÏ°í ¾ÐÃàµÈ °á°ú¸¦ º¸³½´Ù. +
    + + +

    Ãâ·Â ¾ÐÃàÇ®±â

    +

    mod_deflate ¸ðµâÀº gzipÀ¸·Î ¾ÐÃàµÈ + ÀÀ´ä ³»¿ëÀ» Ǫ´Â ÇÊÅ͵µ Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é + ´ÙÀ½°ú °°ÀÌ SetOutputFilter³ª AddOutputFilter¸¦ »ç¿ëÇÏ¿© + Ãâ·ÂÇÊÅͼø¼­¿¡ INFLATE ÇÊÅ͸¦ Ãß°¡ÇÑ´Ù.

    + +

    + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +

    + +

    ÀÌ ¿¹Á¦´Â example.comÀÌ º¸³½ gzipÀ¸·Î ¾ÐÃàµÈ °á°úÀÇ + ¾ÐÃàÀ» Ç®¾î¼­, ´Ù¸¥ ÇÊÅÍ°¡ ´õ ó¸®ÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. +

    + + +

    ÀÔ·Â ¾ÐÃàÇ®±â

    +

    mod_deflate ¸ðµâÀº gzipÀ¸·Î ¾ÐÃàµÈ ¿äû + ³»¿ëÀ» Ǫ´Â ÇÊÅ͵µ Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é ´ÙÀ½°ú + °°ÀÌ SetInputFilter³ª + AddInputFilter¸¦ + »ç¿ëÇÏ¿© ÀÔ·ÂÇÊÅͼø¼­¿¡ DEFLATE ÇÊÅ͸¦ + Ãß°¡ÇÑ´Ù.

    + +

    + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +

    + +

    ¿äû¿¡ Content-Encoding: gzip Çì´õ°¡ ÀÖ´Ù¸é + ÀÚµ¿À¸·Î ¾ÐÃàµÈ ³»¿ëÀ» Ǭ´Ù. gzip ¿äûÀ» ÇÒ ¼ö ÀÖ´Â + ºê¶ó¿ìÀú´Â µå¹°´Ù. ±×·¯³ª ¾î¶² WebDAV Ŭ¶óÀ̾ðÆ®¿Í °°Àº + Ưº°ÇÑ ÇÁ·Î±×·¥Àº ¿äû ¾ÐÃàÀ» Áö¿øÇÑ´Ù.

    + +

    Content-Length¿¡ ´ëÇÑ ÁÖÀÇ

    +

    ¿äû ³»¿ëÀ» Á÷Á¢ »ìÆ캻´Ù¸é, Content-Length + Çì´õ¸¦ ¹ÏÁö¸¶¶ó! Content-Length Çì´õ´Â Ŭ¶óÀ̾ðÆ®°¡ + º¸³½ ³»¿ëÀÇ ±æÀÌÀÌÁö, ¾ÐÃàÀ» Ǭ °á°úÀÇ ¹ÙÀÌÆ®¼ö°¡ + ¾Æ´Ï´Ù.

    +
    + +
    top
    +
    +

    ÇÁ·Ï½Ã ¼­¹ö ´Ù·ç±â

    + +

    mod_deflate ¸ðµâÀº ÇÁ·Ï½Ã°¡ ÀÚ½ÅÀÌ Ä³½¬ÇÑ + ÀÀ´äÀ» ÀûÀýÇÑ Accept-Encoding ¿äû Çì´õ¸¦ º¸³½ + Ŭ¶óÀ̾ðÆ®¿¡°Ô¸¸ º¸³»µµ·Ï Vary: + Accept-Encoding HTTP ÀÀ´ä Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ + ¾ÐÃàµÈ ³»¿ëÀ» ÀÌÇØÇÒ ¼ö ¾ø´Â Ŭ¶óÀ̾ðÆ®¿¡ ¾ÐÃàµÈ ³»¿ëÀ» + º¸³»Áö¾Êµµ·Ï ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, User-Agent Çì´õ µî¿¡ µû¶ó Ưº°È÷ + ÇÊÅÍ Àû¿ëÀ» Ãë¼ÒÇÑ´Ù¸é, ÇÁ·Ï½Ã¿¡°Ô ÀÌ·¯ÇÑ Á¦ÇÑÀ» ¾Ë·ÁÁÖ±âÀ§ÇØ + Á÷Á¢ Vary Çì´õ¿¡ Ãß°¡ÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¼³Á¤ÀÌ User-Agent¿¡ µû¶ó DEFLATE + ÇÊÅ͸¦ Ãß°¡ÇÑ´Ù¸é ´ÙÀ½À» »ç¿ëÇÑ´Ù:

    + +

    + Header append Vary User-Agent +

    + +

    ¿äû Çì´õ¿ÜÀÇ ´Ù¸¥ Á¤º¸¿¡ (¿¹¸¦ µé¾î, HTTP ¹öÀü) + µû¶ó ¾ÐÃà ¿©ºÎ°¡ °áÁ¤µÈ´Ù¸é, Vary Çì´õ°ªÀ» + *·Î ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±×·¯¸é Ç¥ÁØÀ» µû¸£´Â ÇÁ·Ï½Ã´Â + ij½¬¸¦ ÇÏÁö ¾Ê°Ô µÈ´Ù.

    + +

    ¿¹Á¦

    + Header set Vary * +

    +
    +
    top
    +

    DeflateBufferSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:zlibÀÌ Çѹø¿¡ ¾ÐÃàÇÒ Å©±â
    ¹®¹ý:DeflateBufferSize value
    ±âº»°ª:DeflateBufferSize 8096
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_deflate
    +

    DeflateBufferSize Áö½Ã¾î´Â zlibÀÌ + Çѹø¿¡ ¾ÐÃàÇÒ ¹ÙÀÌÆ®¼ö¸¦ ÁöÁ¤ÇÑ´Ù.

    + +
    +
    top
    +

    DeflateCompressionLevel Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:Ãâ·ÂÀ» ¾î´ÀÁ¤µµ ¾ÐÃàÇϴ°¡
    ¹®¹ý:DeflateCompressionLevel value
    ±âº»°ª:Zlib's default
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_deflate
    Áö¿ø:¾ÆÆÄÄ¡ 2.0.45 ºÎÅÍ
    +

    DeflateCompressionLevel Áö½Ã¾î´Â + »ç¿ëÇÒ ¾ÐÃà¼öÁØÀ» ¼±ÅÃÇÑ´Ù. °ªÀÌ Å¬¼ö·Ï ¾ÐÃà·üÀÌ Áõ°¡ÇÏÁö¸¸, + CPU¸¦ ´õ ¸¹ÀÌ »ç¿ëÇÑ´Ù.

    +

    (°¡Àå ´ú ¾ÐÃà) 1°ú (°¡Àå ¸¹ÀÌ ¾ÐÃà) 9 »çÀÌÀÇ °ªÀ» ÁöÁ¤ÇÑ´Ù.

    + +
    +
    top
    +

    DeflateFilterNote Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¾ÐÃà·üÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    ¹®¹ý:DeflateFilterNote [type] notename
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_deflate
    Áö¿ø:typeÀº ¾ÆÆÄÄ¡ 2.0.4 ºÎÅÍ
    +

    DeflateFilterNote Áö½Ã¾î´Â ¿äûÀÇ + ¾ÐÃà·üÀ» ·Î±×¿¡ ±â·ÏÇÏ´Â ±âÈ£¸¦ ÁöÁ¤ÇÑ´Ù. ±âÈ£ À̸§Àº Áö½Ã¾î·Î + ÁöÁ¤ÇÑ °ªÀÌ´Ù. Åë°è¸¦ À§ÇØ Á¢±Ù + ·Î±×¿¡¼­ ±âÈ£¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹Á¦

    + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    ·Î±×¿¡¼­ ´õ Á¤È®ÇÑ °ªÀ» ÃßÃâÇÏ·Á¸é type ¾Æ±Ô¸ÕÆ®·Î + ±â·ÏÇÒ ÀڷḦ ¼±ÅÃÇÑ´Ù. type´Â ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
    +
    Input
    +
    ÇÊÅÍ ÀԷ½ºÆ®¸²ÀÇ ¹ÙÀÌÆ®¼ö¸¦ ÀúÀåÇÑ´Ù.
    + +
    Output
    +
    ÇÊÅÍ Ãâ·Â½ºÆ®¸²ÀÇ ¹ÙÀÌÆ®¼ö¸¦ ÀúÀåÇÑ´Ù..
    + +
    Ratio
    +
    ¾ÐÃà·üÀ» (output/input * 100) ÀúÀåÇÑ´Ù. + type ¾Æ±Ô¸ÕÆ®¸¦ »ý·«ÇÏ¸é »ç¿ëÇÏ´Â ±âº»°ªÀÌ´Ù.
    +
    + +

    ±×·¡¼­ ÀÌ·¸°Ô ·Î±×¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù:

    + +

    Á¤¹ÐÇÑ ·Î±×

    + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +

    + +

    Âü°í

    + +
    +
    top
    +

    DeflateMemLevel Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:zlibÀÌ ¾ÐÃàÇÒ¶§ »ç¿ëÇÏ´Â ¸Þ¸ð¸®·®
    ¹®¹ý:DeflateMemLevel value
    ±âº»°ª:DeflateMemLevel 9
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_deflate
    +

    DeflateMemLevel Áö½Ã¾î´Â zlibÀÌ + ¾ÐÃàÇÒ¶§ ¾ó¸¶¸¸Å­ ¸Þ¸ð¸®¸¦ »ç¿ëÇÒÁö °áÁ¤ÇÑ´Ù. (1°ú 9 »çÀÌÀÇ + °ª)

    + +
    +
    top
    +

    DeflateWindowSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Zlib ¾ÐÃà window size
    ¹®¹ý:DeflateWindowSize value
    ±âº»°ª:DeflateWindowSize 15
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_deflate
    +

    DeflateWindowSize Áö½Ã¾î´Â zlib + ¾ÐÃà window size¸¦ (1°ú 15 »çÀÌÀÇ °ª) ÁöÁ¤ÇÑ´Ù. ÀϹÝÀûÀ¸·Î + window size°¡ Ŭ¼ö·Ï ¾ÐÃà·üÀÌ Áõ°¡ÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_deflate.xml b/trunk/docs/manual/mod/mod_deflate.xml new file mode 100644 index 0000000000..c1cbbf84b5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.xml @@ -0,0 +1,365 @@ + + + + + + + + + +mod_deflate +Compress content before it is delivered to the +client +Extension +mod_deflate.c +deflate_module + + +

    The mod_deflate module provides + the DEFLATE output filter that allows output from + your server to be compressed before being sent to the client over + the network.

    +
    +Filters + + + +
    Enabling Compression + +
    Output Compression +

    Compression is implemented by the DEFLATE + filter. The following directive + will enable compression for documents in the container where it + is placed:

    + + + SetOutputFilter DEFLATE + + +

    Some popular browsers cannot handle compression of all content + so you may want to set the gzip-only-text/html note to + 1 to only allow html files to be compressed (see + below). If you set this to anything but 1 it + will be ignored.

    + +

    If you want to restrict the compression to particular MIME types + in general, you may use the AddOutputFilterByType directive. Here is an example of + enabling compression only for the html files of the Apache + documentation:

    + + + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +
    + +

    For browsers that have problems even with compression of all file + types, use the BrowserMatch directive to set the no-gzip + note for that particular browser so that no compression will be + performed. You may combine no-gzip with gzip-only-text/html to get the best results. In that case + the former overrides the latter. Take a look at the following + excerpt from the configuration example + defined in the section above:

    + + + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +
    + +

    At first we probe for a User-Agent string that + indicates a Netscape Navigator version of 4.x. These versions + cannot handle compression of types other than + text/html. The versions 4.06, 4.07 and 4.08 also + have problems with decompressing html files. Thus, we completely + turn off the deflate filter for them.

    + +

    The third BrowserMatch + directive fixes the guessed identity of the user agent, because + the Microsoft Internet Explorer identifies itself also as "Mozilla/4" + but is actually able to handle requested compression. Therefore we + match against the additional string "MSIE" (\b means + "word boundary") in the User-Agent Header and turn off + the restrictions defined before.

    + + Note + The DEFLATE filter is always inserted after RESOURCE + filters like PHP or SSI. It never touches internal subrequests. + + Note + There is a environment variable force-gzip, + set via SetEnv, which + will ignore the accept-encoding setting of your browser and will + send compressed output. + + +
    +
    Output Decompression +

    The mod_deflate module also provides a filter for + inflating/uncompressing a gzip compressed response body. In order to activate + this feature you have to insert the INFLATE filter into + the outputfilter chain using SetOutputFilter or AddOutputFilter, for example:

    + + + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +
    + +

    This Example will uncompress gzip'ed output from example.com, so other + filters can do further processing with it. +

    + +
    +
    Input Decompression +

    The mod_deflate module also provides a filter for + decompressing a gzip compressed request body . In order to activate + this feature you have to insert the DEFLATE filter into + the input filter chain using SetInputFilter or AddInputFilter, for example:

    + + + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +
    + +

    Now if a request contains a Content-Encoding: + gzip header, the body will be automatically decompressed. + Few browsers have the ability to gzip request bodies. However, + some special applications actually do support request + compression, for instance some WebDAV clients.

    + + Note on Content-Length +

    If you evaluate the request body yourself, don't trust + the Content-Length header! + The Content-Length header reflects the length of the + incoming data from the client and not the byte count of + the decompressed data stream.

    +
    +
    +
    + +
    Dealing with proxy servers + +

    The mod_deflate module sends a Vary: + Accept-Encoding HTTP response header to alert proxies that + a cached response should be sent only to clients that send the + appropriate Accept-Encoding request header. This + prevents compressed content from being sent to a client that will + not understand it.

    + +

    If you use some special exclusions dependent + on, for example, the User-Agent header, you must + manually configure an addition to the Vary header + to alert proxies of the additional restrictions. For example, + in a typical configuration where the addition of the DEFLATE + filter depends on the User-Agent, you should add:

    + + + Header append Vary User-Agent + + +

    If your decision about compression depends on other information + than request headers (e.g. HTTP version), you have to set the + Vary header to the value *. This prevents + compliant proxies from caching entirely.

    + + Example + Header set Vary * + +
    + + +DeflateFilterNote +Places the compression ratio in a note for logging +DeflateFilterNote [type] notename +server configvirtual host + +type is available since Apache 2.0.45 + + +

    The DeflateFilterNote directive + specifies that a note about compression ratios should be attached + to the request. The name of the note is the value specified for + the directive. You can use that note for statistical purposes by + adding the value to your access log.

    + + Example + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +
    + +

    If you want to extract more accurate values from your logs, you + can use the type argument to specify the type of data + left as note for logging. type can be one of:

    + +
    +
    Input
    +
    Store the byte count of the filter's input stream in the note.
    + +
    Output
    +
    Store the byte count of the filter's output stream in the note.
    + +
    Ratio
    +
    Store the compression ratio (output/input * 100) + in the note. This is the default, if the type argument + is omitted.
    +
    + +

    Thus you may log it this way:

    + + Accurate Logging + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +
    +
    +mod_log_config +
    + + +DeflateBufferSize +Fragment size to be compressed at one time by zlib +DeflateBufferSize value +DeflateBufferSize 8096 +server configvirtual host + + + +

    The DeflateBufferSize directive specifies + the size in bytes of the fragments that zlib should compress at one + time.

    +
    +
    + + +DeflateWindowSize +Zlib compression window size +DeflateWindowSize value +DeflateWindowSize 15 +server configvirtual host + + + +

    The DeflateWindowSize directive specifies the + zlib compression window size (a value between 1 and 15). Generally, the + higher the window size, the higher can the compression ratio be expected.

    +
    +
    + + + +DeflateMemLevel +How much memory should be used by zlib for compression +DeflateMemLevel value +DeflateMemLevel 9 +server configvirtual host + + + +

    The DeflateMemLevel directive specifies + how much memory should be used by zlib for compression + (a value between 1 and 9).

    +
    +
    + + +DeflateCompressionLevel +How much compression do we apply to the output +DeflateCompressionLevel value +Zlib's default +server configvirtual host + +This directive is available since Apache 2.0.45 + + +

    The DeflateCompressionLevel directive specifies + what level of compression should be used, the higher the value, + the better the compression, but the more CPU time is required to + achieve this.

    +

    The value must between 1 (less compression) and 9 (more compression).

    +
    +
    + + +
    + diff --git a/trunk/docs/manual/mod/mod_deflate.xml.ja b/trunk/docs/manual/mod/mod_deflate.xml.ja new file mode 100644 index 0000000000..e4855c65ff --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.xml.ja @@ -0,0 +1,355 @@ + + + + + + + + + +mod_deflate +$B%/%i%$%"%s%H$XAw$i$l$kA0$K%3%s%F%s%D$r05=L$9$k(B +Extension +mod_deflate.c +deflate_module + + +

    mod_deflate $B%b%8%e!<%k$O(B DEFLATE + $B=PNO%U%#%k%?$rDs6!$7$^$9!#$3$l$O%5!<%P$+$i$N=PNO$r!"%M%C%H%o!<%/$r(B + $BDL$7$F%/%i%$%"%s%H$KAw$kA0$K05=L$9$k$3$H$r2DG=$K$7$^$9!#(B

    +
    +Filters + + + +
    $B05=L$rM-8z$K$9$k(B + +
    Output Compression +

    $B05=L5!G=$O(B DEFLATE $B%U%#%k%?(B + $B$K$h$j + + + SetOutputFilter DEFLATE + + +

    $B$h$/;H$o$l$F$$$k%V%i%&%6$G$O!"$9$Y$F$N%3%s%F%s%D$KBP$9$k(B + $B05=L$r07$($k$o$1$G$O$"$j$^$;$s!#$G$9$+$i!"(Bgzip-only-text/html + $B%N!<%H$r(B 1 $B$K$7$F!"(Bhtml $B%U%!%$%k$KBP$7$F$N$_(B + $B05=L$,F/$/$h$&$K$7$?J}$,$h$$$+$b$7$l$^$;$s(B ($B0J2<;2>H(B) + $B$3$NCM$r(B 1 $B0J30$NCM(B$B$K@_Dj$7$?>l9g$OL5;k$5$l$^$9!#(B

    + +

    $BDL>o!"FCDj$N(BMIME$B%?%$%W$K$D$$$F$N$_05=L$7$?$$$N$G$"$l$P!"(B + AddOutputFilterByType + $B%G%#%l%/%F%#%V$r;HMQ$7$^$9!# + + + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +
    + +

    $BA4$F$N%U%!%$%k%?%$%W$G$N05=L$KLdBj$rJz$($F$$$k%V%i%&%6$KBP$7$F$O!"(B + BrowserMatch + $B%G%#%l%/%F%#%V$r;HMQ$7$F!"FCDj$N%V%i%&%6$K(B no-gzip + $B%N!<%H$r%;%C%H$7!"05=L$,9T$J$o$l$J$$$h$&$K$7$^$9!#(B + no-gzip $B$H(B gzip-only-text/html + $B$rAH$_9g$o$;$k$3$H$G>el9g!"A0e5-$N(B$B@_DjNc(B$B$NH4?h$r(B + $B + + + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +
    + +

    $B$^$:;O$a$K(B User-Agent $BJ8;zNs$+$i(B Netscape Navigator + 4.x $B$G$"$k$+$I$&$+$rD4$Y$^$9!#$3$l$i$N%P!<%8%g%s$G$O!"(B + text/html $B0J30$N%?%$%W$N05=L$r07$&$3$H$,$G$-$^$;$s!#(B + 4.06, 4.07, 4.08 $B$O(B html $B%U%!%$%k$N?-D%$K$bLdBj$rJz$($F$$$^$9!#(B + $B$G$9$+$i$3$l$i$KBP$7$F$O!"40A4$K(B deflate $B%U%#%k%?$r%*%U$K$7$^$9!#(B

    + +

    3 $BHVL\$N(B BrowserMatch + $B%G%#%l%/%F%#%V$G!"?dB,$7$?%f!<%6!<%(!<%8%'%s%H$r=$@5$7$^$9!#(B + $B$J$<$J$i(B Microsoft Internet Explorer $B$b(B "Mozilla/4" $B$HFCDj$5$l$^$9$,!"(B + $B$3$l$i$OUser-Agent $B%X%C%@$r(B "MSIE" + (\b $B$O!VC18l$N6-3&!W$r0UL#$7$^$9(B) $B$NDI2CJ8;z$G8!::$7$F!"(B + $B$3$l0JA0$K@_Dj$7$?@)8B$r:F$S2r=|$7$^$9!#(B

    + + $BCm(B + DEFLATE $B%U%#%k%?$OI,$:!"(BPHP $B$d(B SSI $B$H$$$C$?(B RESOURCE + $B%U%#%k%?$N8e$K$J$j$^$9!#(B + DEFLATE $B%U%#%k%?$OFbItE*$J%5%V%j%/%(%9%H$r4XCN$7$^$;$s!#(B + + $BCm(B + SetEnv $B$G@_Dj$5$l$k(B + force-gzip $B4D6-JQ?t$,$"$j$^$9$,!"$3$l$O(B + $B%V%i%&%6$N(B accept-encoding $B@_Dj$rL5;k$7!"05=L$7$?=PNO$r$7$^$9!#(B + + +
    +
    $B=PNO$N?-D9(B +

    mod_deflate $B%b%8%e!<%k$O!"(Bgzip $B05=L$5$l$?%l%9%]%s%9(B + $BK\J8$r(B inflate/uncompress $B$9$k%U%#%k%?$bDs6!$7$F$$$^$9!#(B + $B$3$N5!G=$rM-8z$K$9$k$K$O!"(BSetOutputFilter + $B$d(B AddOutputFilter $B$r;H$C$F!"(B + INFLATE $B%U%#%k%?$r=PNO%U%#%k%?%A%'%$%s$KA^F~$7$^$9!#(B + $BNc$($P + + + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +
    + +

    $B$3$NNc$G$O!"(Bexample.com $B$+$i$N(B gzip $B05=L$5$l$?=PNO$r?-D9$7!"(B + $B$=$NB>$N%U%#%k%?$,$5$i$K$=$N=PNO$r=hM}$G$-$k$h$&$K$7$^$9!#(B +

    + +
    +
    $BF~NO$N?-D%(B +

    mod_deflate $B%b%8%e!<%k$O!"(Bgzip + $B$G05=L$5$l$?%j%/%(%9%HK\BN$r?-D%$9$k%U%#%k%?$bDs6!$7$F$$$^$9!#(B + $B$3$N5!G=$rM-8z$K$9$k$K$O!"(BSetInputFilter + $B$+(B AddInputFilter $B$r;HMQ$7$F!"(B + DEFLATE $B%U%#%k%?$rF~NO%U%#%k%?%A%'%$%s$KAH$_9~$_$^$9!#(B + $BNc$($P + + + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +
    + +

    $B$3$N@_Dj$G$"$l$P!"(BContent-Encoding: gzip + $B%X%C%@$r4^$`%j%/%(%9%H$,Mh$k$H!"K\BN$O<+F0E*$K?-D%$5$l$^$9!#(B + gzip $B%j%/%(%9%HK\BN$rAw?.$9$k%V%i%&%6$O$"$^$j$"$j$^$;$s!#(B + $B$7$+$7!"Nc$($P(B WebDAV + $B%/%i%$%"%s%H$N4v$D$+$J$I!"FCJL$J%"%W%j%1!<%7%g%s$G%j%/%(%9%H$N(B + $B05=L$r + + Content-Length $B$K4X$9$kCm0U(B +

    $B%j%/%(%9%HK\BN$=$l<+BN$rI>2A$9$k>l9g$O!"(BContent-Length + $B%X%C%@$r?.MQ$7$J$$$G$/$@$5$$(B$B!#(BContent-Length $B%X%C%@$O!"(B + $B%/%i%$%"%s%H$+$iAw?.$5$l$k%G!<%?$ND9$5$rH?1G$7$F$$$k$N$G$"$C$F!"(B + $B?-D%$5$l$?%G!<%?%9%H%j!<%`$N(B$B%P%$%H%+%&%s%H$G$O$"$j$^$;$s(B$B!#(B

    + +
    +
    + +
    Proxy $B%5!<%P$G$N07$$(B + +

    mod_deflate $B%b%8%e!<%k$O(B Vary: Accept-Encoding + HTTP $B1~Ez%X%C%@$rAw?.$7$F!"E,@Z$J(B Accept-Encoding + $B%j%/%(%9%H%X%C%@$rAw?.$9$k%/%i%$%"%s%H$KBP$7$F$N$_!"(B + $B%W%m%/%7%5!<%P$,%-%c%C%7%e$7$?1~Ez$rAw?.$9$k$h$&$KCm0U$r4-5/$7$^$9!#(B + $B$3$N$h$&$K$7$F!"05=L$r07$&$3$H$N$G$-$J$$%/%i%$%"%s%H$K(B + $B05=L$5$l$?FbMF$,Aw$i$l$k$3$H$N$J$$$h$&$K$7$^$9!#(B

    + +

    $B$b$7FCJL$K2?$+$K0MB8$7$F=|30$7$?$$>l9g!"Nc$($P(B User-Agent + $B%X%C%@$J$I$K0MB8$7$F$$$k>l9g!"Vary $B%X%C%@$r@_Dj$7$F!"(B + $BDI2C$N@)8B$K$D$$$F%W%m%/%7%5!<%P$KCm0U$r9T$J$&I,MW$,$"$j$^$9!#(B + $BNc$($P(B User-Agent $B$K0MB8$7$F(B DEFLATE + $B$rDI2C$9$kE57?E*$J@_Dj$G$O!" + + + Header append Vary User-Agent + + +

    $B%j%/%(%9%H%X%C%@0J30$N>pJs(B ($BNc$($P(B HTTP $B%P!<%8%g%s(B) + $B$K0MB8$7$F05=L$9$k$+$I$&$+7h$a$k>l9g!"(B + Vary $B%X%C%@$r(B * $B$K@_Dj$9$kI,MW$,$"$j$^$9!#(B + $B$3$N$h$&$K$9$k$H!";EMM$K=`5r$7$?%W%m%/%7$O%-%c%C%7%e$rA4$/9T$J$o$J$/$J$j$^$9!#(B

    + + $BNc(B + Header set Vary * + +
    + + +DeflateFilterNote +$B%m%.%s%0MQ$K05=LHf$r%a%b$KDI2C(B +DeflateFilterNote [type] notename +server config +virtual host +type is available since Apache 2.0.45 + + +

    DeflateFilterNote $B%G%#%l%/%F%#%V$O(B + $B05=LHf$K4X$9$k%a%b$,%j%/%(%9%H$KIU2C$5$l$k$3$H$r;XDj$7$^$9!#(B + $B%a%b(B (note) $B$NL>A0$O%G%#%l%/%F%#%V$K;XDj$5$l$?CM$G$9!#(B + $B%a%b$O(B$B%"%/%;%9%m%0(B$B$K(B + $BCM$r5-O?$7!"E}7W$r + + $BNc(B + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +
    + +

    $B%m%0$+$i$b$C$H@:L)$JCM$rCj=P$7$?$$>l9g$O!"(Btype + $B0z?t$r;HMQ$7$F!"%G!<%?%?%$%W$r%m%0$N%a%b$H$7$F;D$9$h$&$K;XDj$G$-$^$9!#(B + type $B$O + +

    +
    Input
    +
    $B%U%#%k%?$NF~NO%9%H%j!<%`$N%P%$%H%+%&%s%H$r%a%b$KJ]B8$9$k!#(B
    + +
    Output
    +
    $B%U%#%k%?$N=PNO%9%H%j!<%`$N%P%$%H%+%&%s%H$r%a%b$KJ]B8$9$k!#(B
    + +
    Ratio
    +
    $B05=LN((B ($B=PNO(B / $BF~NO(B * 100) $B$r%a%b$KJ]B8$9$k!#(B + type $B0z?t$r>JN,$7$?>l9g$O!"$3$l$,%G%U%)%k%H$H$J$j$^$9!#(B
    +
    + +

    $B$^$H$a$k$H!" + + $B@:L)$J%m%0:N<h(B + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +
    + +mod_log_config + + + +DeflateBufferSize +zlib $B$,0lEY$K05=L$9$k2t$NBg$-$5(B +DeflateBufferSize value +DeflateBufferSize 8096 +server config +virtual host + + +

    DeflateBufferSize $B%G%#%l%/%F%#%V$O(B + zlib $B$,0lEY$K05=L$9$k2t$NBg$-$5$r%P%$%HC10L$G;XDj$7$^$9!#(B

    +
    +
    + + +DeflateWindowSize +Zlib $B$N05=LMQ%&%#%s%I%&$NBg$-$5(B +DeflateWindowSize value +DeflateWindowSize 15 +server config +virtual host + + +

    DeflateWindowSize $B%G%#%l%/%F%#%V$O(B + zlib $B$N05=LMQ%&%#%s%I%&(B ($BLuCm(B: zlib $B$G;HMQ$5$l$kMzNr%P%C%U%!(B) + $B$NBg$-$5$r;XDj$7$^$9(B (1 $B$+$i(B 15 $B$N4V$NCM(B)$B!#(B + $B0lHLE*$KBg$-$J%&%#%s%I%&%5%$%:$r;HMQ$9$k$H05=LN($,8~>e$7$^$9!#(B + ($BLuCm(B: 2 $B$rDl$H$9$kBP?t$NCM$K$J$j$^$9!#(B + 8 $B$+$i(B 15 $B$K$9$k$N$,NI$$$G$7$g$&!#(B)

    +
    +
    + + +DeflateMemLevel +zlib $B$,05=L$K;H$&%a%b%j$N%l%Y%k$r;XDj(B +DeflateMemLevel value +DeflateMemLevel 9 +server config +virtual host + + +

    DeflateMemLevel $B%G%#%l%/%F%#%V$O(B + zlib $B$,05=L$K;H$&%a%b%j$N%l%Y%k$r@_Dj$7$^$9(B (1 $B$+$i(B 9 $B$N4V$NCM(B)$B!#(B + ($BLuCm(B: 2 $B$rDl$H$9$kBP?t$NCM$K$J$j$^$9!#(B + 8 $BDxEY$,NI$$$G$7$g$&!#(B)

    +
    +
    + + +DeflateCompressionLevel +$B=PNO$KBP$7$F9T$J$&05=L$NDxEY(B +DeflateCompressionLevel value +Zlib $B$N%G%U%)%k%H(B +server configvirtual host + +This directive is available since Apache 2.0.45 + + +

    DeflateCompressionLevel $B%G%#%l%/%F%#%V$O(B + $B05=L$NDxEY$r@_Dj$7$^$9!#Bg$-$JCM$G$O!"$h$j05=L$,9T$J$o$l$^$9$,!"(B + CPU $B;q8;$r>CHq$7$^$9!#(B

    +

    $BCM$O(B 1 ($BDc05=L(B) $B$+$i(B 9 ($B9b05=L(B) $B$G$9!#(B

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_deflate.xml.ko b/trunk/docs/manual/mod/mod_deflate.xml.ko new file mode 100644 index 0000000000..fc8663735c --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.xml.ko @@ -0,0 +1,346 @@ + + + + + + + + + +mod_deflate +³»¿ëÀ» Ŭ¶óÀ̾ðÆ®·Î º¸³»±â Àü¿¡ ¾ÐÃàÇÑ´Ù +Extension +mod_deflate.c +deflate_module + + +

    mod_deflate ¸ðµâÀº ¼­¹öÀÇ Ãâ·ÂÀ» ³×Æ®¿÷À¸·Î + Ŭ¶óÀ̾ðÆ®¿¡ º¸³»±â Àü¿¡ ¾ÐÃàÇÏ´Â DEFLATE Ãâ·ÂÇÊÅ͸¦ + Á¦°øÇÑ´Ù.

    +
    +ÇÊÅÍ + + + +
    ¾ÐÃàÇϱâ + +
    Ãâ·Â ¾ÐÃà +

    DEFLATE ÇÊÅÍ°¡ + ¾ÐÃàÀ» ÇÑ´Ù. ´ÙÀ½ Áö½Ã¾î´Â Áö½Ã¾î°¡ ÀÖ´Â À§Ä¡ÀÇ ¹®¼­¸¦ + ¾ÐÃàÇÑ´Ù:

    + + + SetOutputFilter DEFLATE + + +

    ¸ðµç ³»¿ëÀ» ¾ÐÃàÇϸé ó¸®ÇÏÁö ¸øÇÏ´Â ºê¶ó¿ìÀú°¡ Àֱ⶧¹®¿¡ + html ÆÄÀϸ¸À» ¾ÐÃàÇϱâÀ§ÇØ (¾Æ·¡ Âü°í) + gzip-only-text/htmlÀ» 1·Î ¼³Á¤ÇÒÁöµµ + ¸ð¸¥´Ù. À̸¦ 1ÀÌ ¾Æ´Ñ °ªÀ¸·Î ¼³Á¤Çϸé + ¹«½ÃÇÑ´Ù.

    + +

    º¸Åë Ưº°ÇÑ MIME type¸¸ ¾ÐÃàÇÏ·Á¸é AddOutputFilterByType Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ´ÙÀ½ ¼³Á¤Àº html ÆÄÀϸ¸À» ¾ÐÃàÇÑ´Ù:

    + + + <Directory "/your-server-root/manual">
    + + AddOutputFilterByType DEFLATE text/html
    +
    + </Directory> +
    + +

    ¾ÐÃàÇÑ ÆÄÀÏÀ» ó¸®ÇÏÁö ¸øÇÏ´Â ºê¶ó¿ìÀú¿¡°Ô´Â ¾ÐÃàÇÏÁö¾Ê°í + º¸³»±æÀ§ÇØ BrowserMatch Áö½Ã¾î¿¡ no-gzipÀ» + ¼³Á¤ÇÑ´Ù. ÃÖÀûÀÇ °á°ú¸¦ ¾ò±âÀ§ÇØ no-gzip°ú + gzip-only-text/htmlÀ» °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ÀÌ °æ¿ì ÀüÀÚ°¡ ÈÄÀÚ¸¦ ¹«½ÃÇÑ´Ù. À§ ÀýÀÇ ¼³Á¤ ¿¹Á¦ ÀϺθ¦ »ìÆ캸ÀÚ:

    + + + BrowserMatch ^Mozilla/4 gzip-only-text/html
    + BrowserMatch ^Mozilla/4\.0[678] no-gzip
    + BrowserMatch \bMSIE !no-gzip !gzip-only-text/html +
    + +

    ¸ÕÀú User-Agent ¹®ÀÚ¿­À» º¸°í Netscape + Navigator ¹öÀü 4.xÀÎÁö °Ë»çÇÑ´Ù. ÀÌ ¹öÀüÀº text/htmlÀÌ + ¾Æ´Ñ typeÀÇ ¾ÐÃàÀ» ó¸®ÇÏÁö ¸øÇÑ´Ù. ¹öÀü 4.06, 4.07, 4.08Àº + html ÆÄÀÏ ¾ÐÃàÀ» ó¸®Çϴ´뵵 ¹®Á¦°¡ ÀÖ´Ù. ±×·¡¼­ ¿ì¸®´Â + ÀÌ °æ¿ì deflate ÇÊÅ͸¦ ¿ÏÀüÈ÷ »ç¿ëÇÏÁö¾Ê´Â´Ù.

    + +

    ¼¼¹ø° BrowserMatch + Áö½Ã¾î´Â Microsoft Internet Explorer°¡ ÀÚ½ÅÀ» "Mozilla/4"·Î + ¾Ë¸®Áö¸¸ ¾ÐÃàµÈ ¿äûÀ» ó¸®ÇÒ ¼ö Àֱ⶧¹®¿¡ user agent + ÃßÃøÀ» ¼öÁ¤ÇÑ´Ù. User-Agent Çì´õ¿¡¼­ "MSIE" + (\b´Â "´Ü¾î °æ°è"¸¦ ¶æÇÑ´Ù) ¹®ÀÚ¿­À» ¹ß°ßÇϸé + ¾Õ¿¡¼­ ¼³Á¤ÇÑ Á¦¾àÀ» Ǭ´Ù.

    + + ÁÖÀÇ + DEFLATE ÇÊÅÍ´Â Ç×»ó PHP³ª SSI¿Í °°Àº RESOURCE + ÇÊÅÍ µÚ¿¡ µé¾î°£´Ù. ¶Ç, ³»ºÎ ÇÏÀ§¿äû(subrequest)¿¡ ¿µÇâÀ» + ÁÖÁö ¾Ê´Â´Ù. + + ÁÖÀÇ + SetEnv·Î + force-gzip ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ¸é ºê¶ó¿ìÀúÀÇ + accept-encoding ¼³Á¤À» ¹«½ÃÇÏ°í ¾ÐÃàµÈ °á°ú¸¦ º¸³½´Ù. + + +
    +
    Ãâ·Â ¾ÐÃàÇ®±â +

    mod_deflate ¸ðµâÀº gzipÀ¸·Î ¾ÐÃàµÈ + ÀÀ´ä ³»¿ëÀ» Ǫ´Â ÇÊÅ͵µ Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é + ´ÙÀ½°ú °°ÀÌ SetOutputFilter³ª AddOutputFilter¸¦ »ç¿ëÇÏ¿© + Ãâ·ÂÇÊÅͼø¼­¿¡ INFLATE ÇÊÅ͸¦ Ãß°¡ÇÑ´Ù.

    + + + <Location /dav-area>
    + + ProxyPass http://example.com/
    + SetOutputFilter INFLATE
    +
    + </Location> +
    + +

    ÀÌ ¿¹Á¦´Â example.comÀÌ º¸³½ gzipÀ¸·Î ¾ÐÃàµÈ °á°úÀÇ + ¾ÐÃàÀ» Ç®¾î¼­, ´Ù¸¥ ÇÊÅÍ°¡ ´õ ó¸®ÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. +

    + +
    +
    ÀÔ·Â ¾ÐÃàÇ®±â +

    mod_deflate ¸ðµâÀº gzipÀ¸·Î ¾ÐÃàµÈ ¿äû + ³»¿ëÀ» Ǫ´Â ÇÊÅ͵µ Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é ´ÙÀ½°ú + °°ÀÌ SetInputFilter³ª + AddInputFilter¸¦ + »ç¿ëÇÏ¿© ÀÔ·ÂÇÊÅͼø¼­¿¡ DEFLATE ÇÊÅ͸¦ + Ãß°¡ÇÑ´Ù.

    + + + <Location /dav-area>
    + + SetInputFilter DEFLATE
    +
    + </Location> +
    + +

    ¿äû¿¡ Content-Encoding: gzip Çì´õ°¡ ÀÖ´Ù¸é + ÀÚµ¿À¸·Î ¾ÐÃàµÈ ³»¿ëÀ» Ǭ´Ù. gzip ¿äûÀ» ÇÒ ¼ö ÀÖ´Â + ºê¶ó¿ìÀú´Â µå¹°´Ù. ±×·¯³ª ¾î¶² WebDAV Ŭ¶óÀ̾ðÆ®¿Í °°Àº + Ưº°ÇÑ ÇÁ·Î±×·¥Àº ¿äû ¾ÐÃàÀ» Áö¿øÇÑ´Ù.

    + + Content-Length¿¡ ´ëÇÑ ÁÖÀÇ +

    ¿äû ³»¿ëÀ» Á÷Á¢ »ìÆ캻´Ù¸é, Content-Length + Çì´õ¸¦ ¹ÏÁö¸¶¶ó! Content-Length Çì´õ´Â Ŭ¶óÀ̾ðÆ®°¡ + º¸³½ ³»¿ëÀÇ ±æÀÌÀÌÁö, ¾ÐÃàÀ» Ǭ °á°úÀÇ ¹ÙÀÌÆ®¼ö°¡ + ¾Æ´Ï´Ù.

    +
    +
    +
    + +
    ÇÁ·Ï½Ã ¼­¹ö ´Ù·ç±â + +

    mod_deflate ¸ðµâÀº ÇÁ·Ï½Ã°¡ ÀÚ½ÅÀÌ Ä³½¬ÇÑ + ÀÀ´äÀ» ÀûÀýÇÑ Accept-Encoding ¿äû Çì´õ¸¦ º¸³½ + Ŭ¶óÀ̾ðÆ®¿¡°Ô¸¸ º¸³»µµ·Ï Vary: + Accept-Encoding HTTP ÀÀ´ä Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ + ¾ÐÃàµÈ ³»¿ëÀ» ÀÌÇØÇÒ ¼ö ¾ø´Â Ŭ¶óÀ̾ðÆ®¿¡ ¾ÐÃàµÈ ³»¿ëÀ» + º¸³»Áö¾Êµµ·Ï ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, User-Agent Çì´õ µî¿¡ µû¶ó Ưº°È÷ + ÇÊÅÍ Àû¿ëÀ» Ãë¼ÒÇÑ´Ù¸é, ÇÁ·Ï½Ã¿¡°Ô ÀÌ·¯ÇÑ Á¦ÇÑÀ» ¾Ë·ÁÁÖ±âÀ§ÇØ + Á÷Á¢ Vary Çì´õ¿¡ Ãß°¡ÇØ¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, + ¼³Á¤ÀÌ User-Agent¿¡ µû¶ó DEFLATE + ÇÊÅ͸¦ Ãß°¡ÇÑ´Ù¸é ´ÙÀ½À» »ç¿ëÇÑ´Ù:

    + + + Header append Vary User-Agent + + +

    ¿äû Çì´õ¿ÜÀÇ ´Ù¸¥ Á¤º¸¿¡ (¿¹¸¦ µé¾î, HTTP ¹öÀü) + µû¶ó ¾ÐÃà ¿©ºÎ°¡ °áÁ¤µÈ´Ù¸é, Vary Çì´õ°ªÀ» + *·Î ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±×·¯¸é Ç¥ÁØÀ» µû¸£´Â ÇÁ·Ï½Ã´Â + ij½¬¸¦ ÇÏÁö ¾Ê°Ô µÈ´Ù.

    + + ¿¹Á¦ + Header set Vary * + +
    + + +DeflateFilterNote +¾ÐÃà·üÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù +DeflateFilterNote [type] notename +server configvirtual host + +typeÀº ¾ÆÆÄÄ¡ 2.0.4 ºÎÅÍ + + +

    DeflateFilterNote Áö½Ã¾î´Â ¿äûÀÇ + ¾ÐÃà·üÀ» ·Î±×¿¡ ±â·ÏÇÏ´Â ±âÈ£¸¦ ÁöÁ¤ÇÑ´Ù. ±âÈ£ À̸§Àº Áö½Ã¾î·Î + ÁöÁ¤ÇÑ °ªÀÌ´Ù. Åë°è¸¦ À§ÇØ Á¢±Ù + ·Î±×¿¡¼­ ±âÈ£¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + + ¿¹Á¦ + DeflateFilterNote ratio
    +
    + LogFormat '"%r" %b (%{ratio}n) "%{User-agent}i"' deflate
    + CustomLog logs/deflate_log deflate +
    + +

    ·Î±×¿¡¼­ ´õ Á¤È®ÇÑ °ªÀ» ÃßÃâÇÏ·Á¸é type ¾Æ±Ô¸ÕÆ®·Î + ±â·ÏÇÒ ÀڷḦ ¼±ÅÃÇÑ´Ù. type´Â ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
    +
    Input
    +
    ÇÊÅÍ ÀԷ½ºÆ®¸²ÀÇ ¹ÙÀÌÆ®¼ö¸¦ ÀúÀåÇÑ´Ù.
    + +
    Output
    +
    ÇÊÅÍ Ãâ·Â½ºÆ®¸²ÀÇ ¹ÙÀÌÆ®¼ö¸¦ ÀúÀåÇÑ´Ù..
    + +
    Ratio
    +
    ¾ÐÃà·üÀ» (output/input * 100) ÀúÀåÇÑ´Ù. + type ¾Æ±Ô¸ÕÆ®¸¦ »ý·«ÇÏ¸é »ç¿ëÇÏ´Â ±âº»°ªÀÌ´Ù.
    +
    + +

    ±×·¡¼­ ÀÌ·¸°Ô ·Î±×¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù:

    + + Á¤¹ÐÇÑ ·Î±× + DeflateFilterNote Input instream
    + DeflateFilterNote Output outstream
    + DeflateFilterNote Ratio ratio
    +
    + LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    + CustomLog logs/deflate_log deflate +
    +
    +mod_log_config +
    + + +DeflateBufferSize +zlibÀÌ Çѹø¿¡ ¾ÐÃàÇÒ Å©±â +DeflateBufferSize value +DeflateBufferSize 8096 +server configvirtual host + + + +

    DeflateBufferSize Áö½Ã¾î´Â zlibÀÌ + Çѹø¿¡ ¾ÐÃàÇÒ ¹ÙÀÌÆ®¼ö¸¦ ÁöÁ¤ÇÑ´Ù.

    +
    +
    + + +DeflateWindowSize +Zlib ¾ÐÃà window size +DeflateWindowSize value +DeflateWindowSize 15 +server configvirtual host + + + +

    DeflateWindowSize Áö½Ã¾î´Â zlib + ¾ÐÃà window size¸¦ (1°ú 15 »çÀÌÀÇ °ª) ÁöÁ¤ÇÑ´Ù. ÀϹÝÀûÀ¸·Î + window size°¡ Ŭ¼ö·Ï ¾ÐÃà·üÀÌ Áõ°¡ÇÑ´Ù.

    +
    +
    + + + +DeflateMemLevel +zlibÀÌ ¾ÐÃàÇÒ¶§ »ç¿ëÇÏ´Â ¸Þ¸ð¸®·® +DeflateMemLevel value +DeflateMemLevel 9 +server configvirtual host + + + +

    DeflateMemLevel Áö½Ã¾î´Â zlibÀÌ + ¾ÐÃàÇÒ¶§ ¾ó¸¶¸¸Å­ ¸Þ¸ð¸®¸¦ »ç¿ëÇÒÁö °áÁ¤ÇÑ´Ù. (1°ú 9 »çÀÌÀÇ + °ª)

    +
    +
    + + +DeflateCompressionLevel +Ãâ·ÂÀ» ¾î´ÀÁ¤µµ ¾ÐÃàÇϴ°¡ +DeflateCompressionLevel value +Zlib's default +server configvirtual host + +¾ÆÆÄÄ¡ 2.0.45 ºÎÅÍ + + +

    DeflateCompressionLevel Áö½Ã¾î´Â + »ç¿ëÇÒ ¾ÐÃà¼öÁØÀ» ¼±ÅÃÇÑ´Ù. °ªÀÌ Å¬¼ö·Ï ¾ÐÃà·üÀÌ Áõ°¡ÇÏÁö¸¸, + CPU¸¦ ´õ ¸¹ÀÌ »ç¿ëÇÑ´Ù.

    +

    (°¡Àå ´ú ¾ÐÃà) 1°ú (°¡Àå ¸¹ÀÌ ¾ÐÃà) 9 »çÀÌÀÇ °ªÀ» ÁöÁ¤ÇÑ´Ù.

    +
    +
    + + +
    + diff --git a/trunk/docs/manual/mod/mod_deflate.xml.meta b/trunk/docs/manual/mod/mod_deflate.xml.meta new file mode 100644 index 0000000000..8486f1ffda --- /dev/null +++ b/trunk/docs/manual/mod/mod_deflate.xml.meta @@ -0,0 +1,13 @@ + + + + mod_deflate + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_dir.html b/trunk/docs/manual/mod/mod_dir.html new file mode 100644 index 0000000000..be6c14c870 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.html @@ -0,0 +1,11 @@ +URI: mod_dir.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_dir.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_dir.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_dir.html.en b/trunk/docs/manual/mod/mod_dir.html.en new file mode 100644 index 0000000000..6f580e3a10 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.html.en @@ -0,0 +1,169 @@ + + + +mod_dir - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dir

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Provides for "trailing slash" redirects and + serving directory index files
    Status:Base
    Module Identifier:dir_module
    Source File:mod_dir.c
    +

    Summary

    + +

    The index of a directory can come from one of two sources:

    + +
      +
    • A file written by the user, typically called + index.html. The DirectoryIndex directive sets the + name of this file. This is controlled by + mod_dir.
    • + +
    • Otherwise, a listing generated by the server. This is + provided by mod_autoindex.
    • +
    +

    The two functions are separated so that you can completely + remove (or replace) automatic index generation should you want + to.

    + +

    A "trailing slash" redirect is issued when the server + receives a request for a URL + http://servername/foo/dirname where + dirname is a directory. Directories require a + trailing slash, so mod_dir issues a redirect to + http://servername/foo/dirname/.

    +
    +

    Directives

    + +
    + +
    top
    +

    DirectoryIndex Directive

    + + + + + + + + +
    Description:List of resources to look for when the client requests +a directory
    Syntax:DirectoryIndex + local-url [local-url] ...
    Default:DirectoryIndex index.html
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_dir
    +

    The DirectoryIndex directive sets the + list of resources to look for, when the client requests an index + of the directory by specifying a / at the end of the directory + name. Local-url is the (%-encoded) URL of a document on + the server relative to the requested directory; it is usually the + name of a file in the directory. Several URLs may be given, in + which case the server will return the first one that it finds. If + none of the resources exist and the Indexes option is + set, the server will generate its own listing of the + directory.

    + +

    Example

    + DirectoryIndex index.html +

    + +

    then a request for http://myserver/docs/ would + return http://myserver/docs/index.html if it + exists, or would list the directory if it did not.

    + +

    Note that the documents do not need to be relative to the + directory;

    + +

    + DirectoryIndex index.html index.txt /cgi-bin/index.pl +

    + +

    would cause the CGI script /cgi-bin/index.pl to be + executed if neither index.html or index.txt + existed in a directory.

    + +
    +
    top
    +

    DirectorySlash Directive

    + + + + + + + + + +
    Description:Toggle trailing slash redirects on or off
    Syntax:DirectorySlash On|Off
    Default:DirectorySlash On
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_dir
    Compatibility:Available in version 2.0.51 and later
    +

    The DirectorySlash directive determines, whether + mod_dir should fixup URLs pointing to a directory or + not.

    + +

    Typically if a user requests a resource without a trailing slash, which + points to a directory, mod_dir redirects him to the same + ressource, but with trailing slash for some good reasons:

    + +
      +
    • The user is finally requesting the canonical URL of the resource
    • +
    • mod_autoindex works correctly. Since it doesn't emit + the path in the link, it would point to the wrong path.
    • +
    • DirectoryIndex will be evaluated + only for directories requested with trailing slash.
    • +
    • Relative URL references inside html pages will work correctly.
    • +
    + +

    Well, if you don't want this effect and the reasons above don't + apply to you, you can turn off the redirect with:

    + +

    + # see security warning below!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +

    + +

    Security Warning

    +

    Turning off the trailing slash redirect may result in an information + disclosure. Consider a situation where mod_autoindex is + active (Options +Indexes) and DirectoryIndex is set to a valid resource (say, + index.html) and there's no other special handler defined for + that URL. In this case a request with a trailing slash would show the + index.html file. But a request without trailing slash + would list the directory contents.

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dir.html.ja.euc-jp b/trunk/docs/manual/mod/mod_dir.html.ja.euc-jp new file mode 100644 index 0000000000..abe4df2a58 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.html.ja.euc-jp @@ -0,0 +1,180 @@ + + + +mod_dir - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_dir

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¡ÖºÇ¸å¤Î¥¹¥é¥Ã¥·¥å¡×¤Î¥ê¥À¥¤¥ì¥¯¥È¤È¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Î +¥¤¥ó¥Ç¥Ã¥¯¥¹¥Õ¥¡¥¤¥ë¤ò°·¤¦µ¡Ç½¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:dir_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_dir.c
    +

    ³µÍ×

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¡¢¼¡¤ÎÆó¤Ä¤Î¤¦¤Á¤É¤Á¤é¤«¤¬ÍøÍѤµ¤ì¤Þ¤¹:

    + +
      +
    • °ì¤ÄÌܤϡ¢¥æ¡¼¥¶¤¬ºîÀ®¤·¤¿¥Õ¥¡¥¤¥ë¤òÍѤ¤¤ë¤â¤Î¤Ç¡¢Ä̾ï + index.html ¤È¤¤¤¦¥Õ¥¡¥¤¥ë̾¤ò»È¤¤¤Þ¤¹¡£¤³¤Î¥Õ¥¡¥¤¥ë̾¤Ï¡¢ + DirectoryIndex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + »ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Îµ¡Ç½¤Ï mod_dir + ¥â¥¸¥å¡¼¥ë¤ÇÄ󶡤µ¤ì¤Þ¤¹¡£
    • + +
    • ¤â¤¦°ì¤Ä¤ÎÊýË¡¤Ï¡¢ + ¥µ¡¼¥Ð¤Ë¤è¤Ã¤Æ¼«Æ°Åª¤ËÀ¸À®¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¥ê¥¹¥È¤òÍѤ¤¤ë¾ì¹ç¤Ç¤¹¡£ + ¤³¤Îµ¡Ç½¤Ï¡¢mod_autoindex + ¥â¥¸¥å¡¼¥ë¤Ë¤è¤êÄ󶡤µ¤ì¤Þ¤¹¡£
    • +
    + +

    ¼«Æ°Åª¤Ê¥¤¥ó¥Ç¥Ã¥¯¥¹À¸À®µ¡Ç½¤òºï½ü (¤â¤·¤¯¤Ï¸ò´¹) + ¤Ç¤­¤ë¤è¤¦¤Ë¡¢¤³¤ÎÆó¤Ä¤Îµ¡Ç½¤ÏʬΥ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤Ê¤ª http://servername/foo/dirname ¤È¤¤¤¦ URL + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤¬¤¢¤Ã¤¿ºÝ¤Ë¡¢dirname + ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê¤¬¤¢¤ì¤Ð¡¢¡ÖºÇ¸å¤Ë¥¹¥é¥Ã¥·¥å¤ò¤Ä¤±¤¿·Á¡×¤Î URL + ¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷½Ð¤·¤Þ¤¹¡£ + ¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤Ï¥¹¥é¥Ã¥·¥å¤Ç½ª¤ï¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¡¢ + mod_dir ¤Ï¡¢http://servername/foo/dirname/ + ¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷½Ð¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    DirectoryIndex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤¬¥Ç¥£¥ì¥¯¥È¥ê¤ò¥ê¥¯¥¨¥¹¥È¤·¤¿¤È¤­¤ËÄ´¤Ù¤ë +¥ê¥½¡¼¥¹¤Î¥ê¥¹¥È
    ¹½Ê¸:DirectoryIndex + local-url [local-url] ...
    ¥Ç¥Õ¥©¥ë¥È:DirectoryIndex index.html
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_dir
    +

    + ¥¯¥é¥¤¥¢¥ó¥È¤¬¡¢¥Ç¥£¥ì¥¯¥È¥ê̾¤ÎºÇ¸å¤Ë¡Ö/¡× + ¤ò»ØÄꤷ¤Æ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÍ׵᤹¤ë¾ì¹ç¤Ëõ¤¹¥ê¥½¡¼¥¹¤Î¥ê¥¹¥È¤ò + DirectoryIndex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£ + Local-url + ¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤ËÂбþ¤¹¤ë¡¢¥µ¡¼¥Ð¾å¤Î¥É¥­¥å¥á¥ó¥È¤Î + (% ¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿) URL ¤Ç¡¢ÉáÄ̤ϥǥ£¥ì¥¯¥È¥êÃæ¤Î¥Õ¥¡¥¤¥ë¤Î̾Á°¤Ç¤¹¡£ + Ê£¿ô¤Î URL ¤¬ÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢ºÇ½é¤Ë¸«¤Ä¤«¤Ã¤¿¤â¤Î¤òÊÖ¤·¤Þ¤¹¡£ + ¤½¤ì¤é¤¬¸«¤Ä¤«¤é¤º¡¢Indexes + ¥ª¥×¥·¥ç¥ó¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È¤òÀ¸À®¤·¤Þ¤¹¡£ +

    + +

    Îã

    + DirectoryIndex index.html +

    + +

    http://myserver/docs/ ¤Ø¤Î¥¢¥¯¥»¥¹¤¬¤¢¤ê¡¢ + http://myserver/docs/index.html + ¤¬Â¸ºß¤¹¤ì¤Ð¡¢¤³¤Î URL ¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£ + ¤â¤·Â¸ºß¤·¤Ê¤±¤ì¤Ð¡¢¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    Ãí: ¥É¥­¥å¥á¥ó¥È¤¬Æ±¤¸¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë¸ºß¤¹¤ë¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£ +

    + +

    + DirectoryIndex index.html index.txt /cgi-bin/index.pl +

    + +

    ¤È¤·¤¿¾ì¹ç¡¢index.html ¤È index.txt + ¤Î¤É¤Á¤é¤â¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë¸ºß¤·¤Ê¤¤¾ì¹ç¡¢CGI ¥¹¥¯¥ê¥×¥È + /cgi-bin/index.pl ¤¬¼Â¹Ô¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    DirectorySlash ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:¥Ñ¥¹ËöÈø¤Î¥¹¥é¥Ã¥·¥å¤Ç¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤«¤É¤¦¤«¤Î¥ª¥ó¥ª¥Õ¤ò¥È¥°¥ë¤µ¤»¤ë
    ¹½Ê¸:DirectorySlash On|Off
    ¥Ç¥Õ¥©¥ë¥È:DirectorySlash On
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_dir
    ¸ß´¹À­:2.0.51 °Ê¹ß
    +

    Í×µá¤Î¤¢¤Ã¤¿ URL ¤¬¥Ç¥£¥ì¥¯¥È¥ê¤ò»Ø¤¹¤«¤É¤¦¤«¤ò¡¢ + mod_dir ¤¬Ä´À°¤¹¤ë¤Ù¤­¤«¤É¤¦¤«¤ò + DirectorySlash + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    ŵ·¿Åª¤Ë¤Ï¡¢¥æ¡¼¥¶¤¬ËöÈø¤Î¥¹¥é¥Ã¥·¥å̵¤·¤Ç¥ê¥½¡¼¥¹¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤òȯ¹Ô¤·¡¢ + ¤½¤·¤Æ¡¢¤½¤Î¥ê¥½¡¼¥¹¤¬¥Ç¥£¥ì¥¯¥È¥ê¤ò»Ø¤·¤Æ¤¤¤¿¾ì¹ç¡¢mod_dir + ¤Ï¡¢ËöÈø¤Ë¥¹¥é¥Ã¥·¥å¤òÉղä·¤¿¾å¤ÇƱ¤¸¥ê¥½¡¼¥¹¤Ë¥ê¥À¥¤¥ì¥¯¥È¤µ¤»¤Þ¤¹¡£ + ¤³¤ÎµóÆ°¤Ë¤Ï´ö¤Ä¤«Íýͳ¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¥æ¡¼¥¶¤Ï¡¢ºÇ½ªÅª¤Ë¤Ï¥ê¥½¡¼¥¹¤ÎÊÌ̾ URL ¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ë¤³¤È¤Ë¤Ê¤ë¡£
    • +
    • mod_autoindex ¤¬´üÂÔÄ̤ê¤ËÆ°¤¯¡£mod_autoindex + ¤ÎÀ¸À®¤¹¤ë¥ê¥ó¥¯¤Ï¥Ñ¥¹¤ò½ÐÎϤ·¤Þ¤»¤ó¤Î¤Ç¡¢¥¹¥é¥Ã¥·¥å¤¬¤Ê¤¤¾ì¹ç¤Ï´Ö°ã¤Ã¤¿¥Ñ¥¹¤ò + »Ø¤·¤Æ¤·¤Þ¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
    • +
    • DirectoryIndex ¤Ï¡¢ + ËöÈø¤Ë¥¹¥é¥Ã¥·¥å¤¬¤Ä¤¤¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¤Ë¤Ä¤¤¤Æ¤Î¤ßɾ²Á¤µ¤ì¤ë¡£
    • +
    • HTML ¥Ú¡¼¥¸¤ÎÁêÂÐ URL »²¾È¤¬Àµ¤·¤¯Æ°ºî¤¹¤ë¡£
    • +
    + +

    ¤È¤Ï¤¤¤¨¡¢¤â¤·¤³¤¦¤¤¤Ã¤¿¸ú²Ì¤ò˾¤Þ¤Ê¤¤¡¢¤«¤Ä¡¢ + ¾åµ­¤Î¤è¤¦¤ÊÍýͳ¤¬Åö¤Æ¤Ï¤Þ¤é¤Ê¤¤¾ì¹ç¤Ï¡¢¥ê¥À¥¤¥ì¥¯¥È¤ò¼¡¤Î¤è¤¦¤Ë¤·¤Æ¥ª¥Õ¤Ë¤Ç¤­¤Þ¤¹:

    + +

    + # see security warning below!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +

    + +

    ¥»¥­¥å¥ê¥Æ¥£·Ù¹ð

    +

    ËöÈø¤Î¥¹¥é¥Ã¥·¥å¤Ç¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò¥ª¥Õ¤Ë¤¹¤ë¤È¡¢·ë²ÌŪ¤Ë¾ðÊóϳ±Ì¤ò + ¾·¤¯¤³¤È¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + mod_autoindex ¤¬Í­¸ú (Options +Indexes) ¤Ç¡¢ + DirectoryIndex ¤¬Í­¸ú¤Ê¥ê¥½¡¼¥¹ (Î㤨¤Ð + index.html) ¤ò»Ø¤·¤Æ¤¤¤Æ¡¢¤Þ¤¿¡¢Í×µá¤Î¤¢¤Ã¤¿ URL ¤ËÆÃÊÌ¤Ê + ¥Ï¥ó¥É¥é¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤ò¹Í¤¨¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤Î¾ì¹çËöÈø¤Ë¥¹¥é¥Ã¥·¥å¤Î¤Ä¤¤¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤Ï index.html + ¥Õ¥¡¥¤¥ë¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£¤·¤«¤·¥¹¥é¥Ã¥·¥å¤Î¤Ê¤¤¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¤ÎÆâÍÆ°ìÍ÷¤òÊÖ¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dir.html.ko.euc-kr b/trunk/docs/manual/mod/mod_dir.html.ko.euc-kr new file mode 100644 index 0000000000..bfc23c7d64 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.html.ko.euc-kr @@ -0,0 +1,167 @@ + + + +mod_dir - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_dir

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:"¸¶Áö¸· ½½·¡½¬" ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÏ°í µð·ºÅ丮 +index ÆÄÀÏÀ» ¼­ºñ½ºÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:dir_module
    ¼Ò½ºÆÄÀÏ:mod_dir.c
    +

    ¿ä¾à

    + +

    µð·ºÅ丮ÀÇ index´Â ´ÙÀ½ µÑÁß ÇÑ°¡Áö ¹æ¹ýÀ¸·Î Á¦°øµÈ´Ù:

    + +
      +
    • »ç¿ëÀÚ°¡ ÀÛ¼ºÇÑ º¸Åë index.htmlÀ̶ó´Â + ÆÄÀÏ. DirectoryIndex + Áö½Ã¾î´Â ÀÌ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. mod_dir°¡ + ÀÌ Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù.
    • + +
    • ¾Æ´Ï¶ó¸é ¼­¹ö°¡ ¸¸µç ¸ñ·Ï. mod_autoindex°¡ + ÀÌ ±â´ÉÀ» Á¦°øÇÑ´Ù.
    • +
    +

    µÎ ±â´ÉÀº ¼­·Î º°°³·Î ¿øÇÑ´Ù¸é ÀÚµ¿ index »ý¼ºÀ» ¿ÏÀüÈ÷ + ¾ø¾Ù (ȤÀº ±³Ã¼ÇÒ) ¼ö ÀÖ´Ù.

    + +

    dirnameÀÌ µð·ºÅ丮¶ó¸é ¼­¹ö´Â URL + http://servername/foo/dirname ¿äûÀ» ¹ÞÀ¸¸é + "¸¶Áö¸· ½½·¡½¬" ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. µð·ºÅ丮¿¡´Â ¸¶Áö¸· + ½½·¡½¬°¡ ÇÊ¿äÇÏ´Ù. ±×·¡¼­ mod_dirÀº + http://servername/foo/dirname/·Î ¸®´ÙÀÌ·º¼ÇÀ» + º¸³½´Ù.

    +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    DirectoryIndex Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:Ŭ¶óÀ̾ðÆ®°¡ µð·ºÅ丮¸¦ ¿äûÇÒ¶§ ã¾Æº¼ ÀÚ¿ø ¸ñ·Ï
    ¹®¹ý:DirectoryIndex + local-url [local-url] ...
    ±âº»°ª:DirectoryIndex index.html
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_dir
    +

    DirectoryIndex Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®°¡ + µð·ºÅ丮¸í ³¡¿¡ /¸¦ ºÙ¿©¼­ µð·ºÅ丮ÀÇ index¸¦ ¿äûÇÒ¶§ ã¾Æº¼ + ÀÚ¿ø ¸ñ·ÏÀ» ÁöÁ¤ÇÑ´Ù. Local-urlÀº ¿äûÇÑ µð·ºÅ丮¿¡ + »ó´ëÀûÀÎ ¹®¼­ÀÇ (%·Î ÀÎÄÚµùµÈ) URLÀÌ´Ù. º¸ÅëÀº µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϸíÀÌ´Ù. ¿©·¯ URLÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ°í, ÀÌ °æ¿ì ¼­¹ö´Â + ù¹ø°·Î ãÀº ÆÄÀÏÀ» º¸³½´Ù. ÀÚ¿øÀ» ãÀ» ¼ö ¾ø°í + Indexes ¿É¼ÇÀ» ¼³Á¤ÇÏ¿´´Ù¸é ¼­¹ö´Â Á÷Á¢ µð·ºÅ丮 + ¸ñ·ÏÀ» ¸¸µç´Ù.

    + +

    ¿¹Á¦

    + DirectoryIndex index.html +

    + +

    ÀÌ °æ¿ì http://myserver/docs/¸¦ ¿äûÇÒ¶§ + http://myserver/docs/index.htmlÀÌ ÀÖÀ¸¸é À̸¦ + º¸³»°í, ¾ø´Ù¸é µð·ºÅ丮 ¸ñ·ÏÀ» º¸³½´Ù.

    + +

    ¹®¼­°¡ ¹Ýµå½Ã µð·ºÅ丮¿¡ »ó´ëÀûÀÏ ÇÊ¿ä´Â ¾ø´Ù.

    + +

    + DirectoryIndex index.html index.txt /cgi-bin/index.pl +

    + +

    ÀÌ °æ¿ì µð·ºÅ丮¿¡ index.htmlÀ̳ª + index.txt°¡ ¾øÀ¸¸é CGI ½ºÅ©¸³Æ® + /cgi-bin/index.plÀ» ½ÇÇàÇÑ´Ù.

    + +
    +
    top
    +

    DirectorySlash Áö½Ã¾î

    + + + + + + + + + +
    ¼³¸í:¸¶Áö¸· ½½·¡½¬ ¸®´ÙÀÌ·º¼ÇÀ» Å°°í ²ö´Ù
    ¹®¹ý:DirectorySlash On|Off
    ±âº»°ª:DirectorySlash On
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_dir
    Áö¿ø:¾ÆÆÄÄ¡ 2.0.51 ÀÌÈĺÎÅÍ
    +

    DirectorySlash Áö½Ã¾î´Â + mod_dir°¡ µð·ºÅ丮¸¦ °¡¸®Å°´Â URLÀ» ¼öÁ¤ÇÒÁö + ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    + +

    »ç¿ëÀÚ°¡ ¸¶Áö¸· ½½·¡½¬¾øÀÌ µð·ºÅ丮¿¡ ÇØ´çÇÏ´Â ÀÚ¿øÀ» + ¿äûÇϸé, mod_dir´Â º¸Åë ´ÙÀ½°ú °°Àº ÀÌÀ¯·Î + »ç¿ëÀÚ¸¦ ¸¶Áö¸· ½½·¡½¬¸¦ ºÙÀÎ µ¿ÀÏÇÑ ÀÚ¿øÀ¸·Î + ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.

    + +
      +
    • »ç¿ëÀÚ´Â °á±¹ ÀÚ¿øÀÇ Á¤±Ô URLÀ» ¿äûÇÏ°Ô µÈ´Ù
    • +
    • mod_autoindex°¡ ¿Ã¹Ù·Î µ¿ÀÛÇÑ´Ù. ÀÌ + ±â´ÉÀÌ ¾ø´Ù¸é ÀÌ ¸ðµâÀº ¸µÅ©¿¡ À߸øµÈ °æ·Î¸¦ ¾²°Ô µÈ´Ù.
    • +
    • DirectoryIndex´Â + ¸¶Áö¸· ½½·¡½¬°¡ ÀÖ´Â µð·ºÅ丮 ¿äû¸¸À» ó¸®ÇÑ´Ù.
    • +
    • html ÆäÀÌÁö¿¡ ÀÖ´Â »ó´ëÀûÀÎ URL ÂüÁ¶°¡ ¿Ã¹Ù·Î µ¿ÀÛÇÑ´Ù.
    • +
    + +

    ±×·±µ¥ ÀÌ ±â´ÉÀ» ¿øÇÏÁö ¾Ê°Å³ª À§¿¡ µç ÀÌÀ¯°¡ + ´ç½Å¿¡°Ô ¾Ë¸ÂÁö ¾Ê´Ù¸é ´ÙÀ½°ú °°ÀÌ ¸®´ÙÀÌ·º¼ÇÀ» ÇÏÁö ¾ÊÀ» + ¼ö ÀÖ´Ù.

    + +

    + # ¾Æ·¡ º¸¾È °æ°í Âü°í!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +

    + +

    º¸¾È °æ°í

    +

    ¸¶Áö¸· ½½·¡½¬ ¸®´ÙÀÌ·º¼ÇÀ» ²ô¸é Á¤º¸°¡ À¯ÃâµÉ ¼ö ÀÖ´Ù. + (Options +Indexes) mod_autoindex¸¦ + »ç¿ëÇÏ°í DirectoryIndex¸¦ + (index.html °°Àº) À¯È¿ÇÑ ÀÚ¿øÀ¸·Î ¼³Á¤ÇÏ¿´Áö¸¸ + ÇØ´ç URL¿¡ ´Ù¸¥ Ưº°ÇÑ Çڵ鷯°¡ ¾ø´Â »óȲÀ» »ó»óÇغ¸¶ó. + ÀÌ °æ¿ì ¸¶Áö¸· ½½·¡½¬°¡ ÀÖ´Â ¿äûÀº index.html + ÆÄÀÏÀ» º¸¿©ÁØ´Ù. ±×·¯³ª ¸¶Áö¸· ½½·¡½¬°¡ ¾ø´Â ¿äûÀº + µð·ºÅ丮 ³»¿ëÀ» º¸¿©ÁØ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dir.xml b/trunk/docs/manual/mod/mod_dir.xml new file mode 100644 index 0000000000..af703ff116 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.xml @@ -0,0 +1,154 @@ + + + + + + + + +mod_dir +Provides for "trailing slash" redirects and + serving directory index files +Base +mod_dir.c +dir_module + + +

    The index of a directory can come from one of two sources:

    + +
      +
    • A file written by the user, typically called + index.html. The DirectoryIndex directive sets the + name of this file. This is controlled by + mod_dir.
    • + +
    • Otherwise, a listing generated by the server. This is + provided by mod_autoindex.
    • +
    +

    The two functions are separated so that you can completely + remove (or replace) automatic index generation should you want + to.

    + +

    A "trailing slash" redirect is issued when the server + receives a request for a URL + http://servername/foo/dirname where + dirname is a directory. Directories require a + trailing slash, so mod_dir issues a redirect to + http://servername/foo/dirname/.

    +
    + + +DirectoryIndex +List of resources to look for when the client requests +a directory +DirectoryIndex + local-url [local-url] ... +DirectoryIndex index.html +server configvirtual host +directory.htaccess +Indexes + + +

    The DirectoryIndex directive sets the + list of resources to look for, when the client requests an index + of the directory by specifying a / at the end of the directory + name. Local-url is the (%-encoded) URL of a document on + the server relative to the requested directory; it is usually the + name of a file in the directory. Several URLs may be given, in + which case the server will return the first one that it finds. If + none of the resources exist and the Indexes option is + set, the server will generate its own listing of the + directory.

    + + Example + DirectoryIndex index.html + + +

    then a request for http://myserver/docs/ would + return http://myserver/docs/index.html if it + exists, or would list the directory if it did not.

    + +

    Note that the documents do not need to be relative to the + directory;

    + + + DirectoryIndex index.html index.txt /cgi-bin/index.pl + + +

    would cause the CGI script /cgi-bin/index.pl to be + executed if neither index.html or index.txt + existed in a directory.

    +
    +
    + + +DirectorySlash +Toggle trailing slash redirects on or off +DirectorySlash On|Off +DirectorySlash On +server configvirtual host +directory.htaccess +Indexes +Available in version 2.0.51 and later + + +

    The DirectorySlash directive determines, whether + mod_dir should fixup URLs pointing to a directory or + not.

    + +

    Typically if a user requests a resource without a trailing slash, which + points to a directory, mod_dir redirects him to the same + ressource, but with trailing slash for some good reasons:

    + +
      +
    • The user is finally requesting the canonical URL of the resource
    • +
    • mod_autoindex works correctly. Since it doesn't emit + the path in the link, it would point to the wrong path.
    • +
    • DirectoryIndex will be evaluated + only for directories requested with trailing slash.
    • +
    • Relative URL references inside html pages will work correctly.
    • +
    + +

    Well, if you don't want this effect and the reasons above don't + apply to you, you can turn off the redirect with:

    + + + # see security warning below!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +
    + + Security Warning +

    Turning off the trailing slash redirect may result in an information + disclosure. Consider a situation where mod_autoindex is + active (Options +Indexes) and DirectoryIndex is set to a valid resource (say, + index.html) and there's no other special handler defined for + that URL. In this case a request with a trailing slash would show the + index.html file. But a request without trailing slash + would list the directory contents.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_dir.xml.ja b/trunk/docs/manual/mod/mod_dir.xml.ja new file mode 100644 index 0000000000..b5c1400ab4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.xml.ja @@ -0,0 +1,164 @@ + + + + + + + + + +mod_dir +$B!V:G8e$N%9%i%C%7%e!W$N%j%@%$%l%/%H$H!"%G%#%l%/%H%j$N(B +$B%$%s%G%C%/%9%U%!%$%k$r07$&5!G=$rDs6!$9$k(B +Base +mod_dir.c +dir_module + + +

    $B%G%#%l%/%H%j%$%s%G%C%/%9$O!" + +

      +
    • $B0l$DL\$O!"%f!<%6$,:n@.$7$?%U%!%$%k$rMQ$$$k$b$N$G!"DL>o(B + index.html $B$H$$$&%U%!%$%kL>$r;H$$$^$9!#$3$N%U%!%$%kL>$O!"(B + DirectoryIndex $B%G%#%l%/%F%#%V$G(B + $B;XDj$9$k$3$H$,$G$-$^$9!#$3$N5!G=$O(B mod_dir + $B%b%8%e!<%k$GDs6!$5$l$^$9!#(B
    • + +
    • $B$b$&0l$D$NJ}K!$O!"(B + $B%5!<%P$K$h$C$F<+F0E*$K@8@.$5$l$k%G%#%l%/%H%j%j%9%H$rMQ$$$k>l9g$G$9!#(B + $B$3$N5!G=$O!"(Bmod_autoindex + $B%b%8%e!<%k$K$h$jDs6!$5$l$^$9!#(B
    • +
    + +

    $B<+F0E*$J%$%s%G%C%/%9@8@.5!G=$r:o=|(B ($B$b$7$/$O8r49(B) + $B$G$-$k$h$&$K!"$3$NFs$D$N5!G=$OJ,N%$5$l$F$$$^$9!#(B

    + +

    $B$J$*(B http://servername/foo/dirname $B$H$$$&(B URL + $B$X$N%j%/%(%9%H$,$"$C$?:]$K!"(Bdirname + $B$H$$$&%G%#%l%/%H%j$,$"$l$P!"!V:G8e$K%9%i%C%7%e$r$D$1$?7A!W$N(B URL + $B$X$N%j%@%$%l%/%H$rAw=P$7$^$9!#(B + $B%G%#%l%/%H%j$X$N%"%/%;%9$O%9%i%C%7%e$G=*$o$C$F$$$kI,MW$,$"$j!"(B + mod_dir $B$O!"(Bhttp://servername/foo/dirname/ + $B$X$N%j%@%$%l%/%H$rAw=P$9$k$3$H$K$J$j$^$9!#(B

    +
    + + +DirectoryIndex +$B%/%i%$%"%s%H$,%G%#%l%/%H%j$r%j%/%(%9%H$7$?$H$-$KD4$Y$k(B +$B%j%=!<%9$N%j%9%H(B +DirectoryIndex + local-url [local-url] ... +DirectoryIndex index.html +server configvirtual host +directory.htaccess +Indexes + + +

    + $B%/%i%$%"%s%H$,!"%G%#%l%/%H%jL>$N:G8e$K!V(B/$B!W(B + $B$r;XDj$7$F%G%#%l%/%H%j%$%s%G%C%/%9$rMW5a$9$k>l9g$KC5$9%j%=!<%9$N%j%9%H$r(B + DirectoryIndex $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#(B + Local-url + $B$O!"%j%/%(%9%H$5$l$?%G%#%l%/%H%j$KBP1~$9$k!"%5!<%P>e$N%I%-%e%a%s%H$N(B + (% $B%(%s%3!<%I$5$l$?(B) URL $B$G!"IaDL$O%G%#%l%/%H%jCf$N%U%!%$%k$NL>A0$G$9!#(B + $BJ#?t$N(B URL $B$,@_Dj$5$l$?>l9g$K$O!":G=i$K8+$D$+$C$?$b$N$rJV$7$^$9!#(B + $B$=$l$i$,8+$D$+$i$:!"(BIndexes + $B%*%W%7%g%s$,%;%C%H$5$l$F$$$k>l9g!"%G%#%l%/%H%j$N%j%9%H$r@8@.$7$^$9!#(B +

    + + $BNc(B + DirectoryIndex index.html + + +

    http://myserver/docs/ $B$X$N%"%/%;%9$,$"$j!"(B + http://myserver/docs/index.html + $B$,B8:_$9$l$P!"$3$N(B URL $B$,JV$5$l$^$9!#(B + $B$b$7B8:_$7$J$1$l$P!"%G%#%l%/%H%j$N%j%9%H$,JV$5$l$^$9!#(B

    + +

    $BCm(B: $B%I%-%e%a%s%H$,F1$8%G%#%l%/%H%jFb$KB8:_$9$k$OI,MW$"$j$^$;$s!#(B +

    + + + DirectoryIndex index.html index.txt /cgi-bin/index.pl + + +

    $B$H$7$?>l9g!"(Bindex.html $B$H(B index.txt + $B$N$I$A$i$b%G%#%l%/%H%jFb$KB8:_$7$J$$>l9g!"(BCGI $B%9%/%j%W%H(B + /cgi-bin/index.pl $B$, + + + + +DirectorySlash +$B%Q%9KvHx$N%9%i%C%7%e$G%j%@%$%l%/%H$9$k$+$I$&$+$N%*%s%*%U$r%H%0%k$5$;$k(B +DirectorySlash On|Off +DirectorySlash On +server configvirtual host +directory.htaccess +Indexes +2.0.51 $B0J9_(B + + +

    $BMW5a$N$"$C$?(B URL $B$,%G%#%l%/%H%j$r;X$9$+$I$&$+$r!"(B + mod_dir $B$,D4@0$9$k$Y$-$+$I$&$+$r(B + DirectorySlash + $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#(B

    + +

    $BE57?E*$K$O!"%f!<%6$,KvHx$N%9%i%C%7%eL5$7$G%j%=!<%9$X$N%j%/%(%9%H$rH/9T$7!"(B + $B$=$7$F!"$=$N%j%=!<%9$,%G%#%l%/%H%j$r;X$7$F$$$?>l9g!"(Bmod_dir + $B$O!"KvHx$K%9%i%C%7%e$r(B$BIU2C(B$B$7$?>e$GF1$8%j%=!<%9$K%j%@%$%l%/%H$5$;$^$9!#(B + $B$3$N5sF0$K$O4v$D$+M}M3$,$"$j$^$9(B:

    + +
      +
    • $B%f!<%6$O!":G=*E*$K$O%j%=!<%9$NJLL>(B URL $B$r%j%/%(%9%H$9$k$3$H$K$J$k!#(B
    • +
    • mod_autoindex $B$,4|BTDL$j$KF0$/!#(Bmod_autoindex + $B$N@8@.$9$k%j%s%/$O%Q%9$r=PNO$7$^$;$s$N$G!"%9%i%C%7%e$,$J$$>l9g$O4V0c$C$?%Q%9$r(B + $B;X$7$F$7$^$&$3$H$K$J$j$^$9!#(B
    • +
    • DirectoryIndex $B$O!"(B + $BKvHx$K%9%i%C%7%e$,$D$$$F$$$k%j%/%(%9%H$K$D$$$F(B$B$N$_(B$BI>2A$5$l$k!#(B
    • +
    • HTML $B%Z!<%8$NAjBP(B URL $B;2>H$,@5$7$/F0:n$9$k!#(B
    • +
    + +

    $B$H$O$$$(!"$b$7$3$&$$$C$?8z2L$rK>$^$J$$!"$+$D!"(B + $B>e5-$N$h$&$JM}M3$,Ev$F$O$^$i$J$$>l9g$O!"%j%@%$%l%/%H$r + + + # see security warning below!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +
    + + $B%;%-%e%j%F%#7Y9p(B +

    $BKvHx$N%9%i%C%7%e$G$N%j%@%$%l%/%H$r%*%U$K$9$k$H!"7k2LE*$K>pJsO31L$r(B + $B>7$/$3$H$K$J$k$+$b$7$l$^$;$s!#(B + mod_autoindex $B$,M-8z(B (Options +Indexes) $B$G!"(B + DirectoryIndex $B$,M-8z$J%j%=!<%9(B ($BNc$($P(B + index.html) $B$r;X$7$F$$$F!"$^$?!"MW5a$N$"$C$?(B URL $B$KFCJL$J(B + $B%O%s%I%i$,@_Dj$5$l$F$$$J$$>l9g$r9M$($F$_$F$/$@$5$$!#(B + $B$3$N>l9gKvHx$K%9%i%C%7%e$N$D$$$F$$$k%j%/%(%9%H$KBP$7$F$O(B index.html + $B%U%!%$%k$,JV$5$l$^$9!#(B$B$7$+$7%9%i%C%7%e$N$J$$%j%/%(%9%H$KBP$7$F$O!"(B + $B%G%#%l%/%H%j$NFbMF0lMw$rJV$7$F$7$^$$$^$9!#(B

    + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_dir.xml.ko b/trunk/docs/manual/mod/mod_dir.xml.ko new file mode 100644 index 0000000000..8f75054f56 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.xml.ko @@ -0,0 +1,150 @@ + + + + + + + + +mod_dir +"¸¶Áö¸· ½½·¡½¬" ¸®´ÙÀÌ·º¼ÇÀ» Á¦°øÇÏ°í µð·ºÅ丮 +index ÆÄÀÏÀ» ¼­ºñ½ºÇÑ´Ù +Base +mod_dir.c +dir_module + + +

    µð·ºÅ丮ÀÇ index´Â ´ÙÀ½ µÑÁß ÇÑ°¡Áö ¹æ¹ýÀ¸·Î Á¦°øµÈ´Ù:

    + +
      +
    • »ç¿ëÀÚ°¡ ÀÛ¼ºÇÑ º¸Åë index.htmlÀ̶ó´Â + ÆÄÀÏ. DirectoryIndex + Áö½Ã¾î´Â ÀÌ ÆÄÀÏÀÇ À̸§À» ÁöÁ¤ÇÑ´Ù. mod_dir°¡ + ÀÌ Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù.
    • + +
    • ¾Æ´Ï¶ó¸é ¼­¹ö°¡ ¸¸µç ¸ñ·Ï. mod_autoindex°¡ + ÀÌ ±â´ÉÀ» Á¦°øÇÑ´Ù.
    • +
    +

    µÎ ±â´ÉÀº ¼­·Î º°°³·Î ¿øÇÑ´Ù¸é ÀÚµ¿ index »ý¼ºÀ» ¿ÏÀüÈ÷ + ¾ø¾Ù (ȤÀº ±³Ã¼ÇÒ) ¼ö ÀÖ´Ù.

    + +

    dirnameÀÌ µð·ºÅ丮¶ó¸é ¼­¹ö´Â URL + http://servername/foo/dirname ¿äûÀ» ¹ÞÀ¸¸é + "¸¶Áö¸· ½½·¡½¬" ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù. µð·ºÅ丮¿¡´Â ¸¶Áö¸· + ½½·¡½¬°¡ ÇÊ¿äÇÏ´Ù. ±×·¡¼­ mod_dirÀº + http://servername/foo/dirname/·Î ¸®´ÙÀÌ·º¼ÇÀ» + º¸³½´Ù.

    +
    + + +DirectoryIndex +Ŭ¶óÀ̾ðÆ®°¡ µð·ºÅ丮¸¦ ¿äûÇÒ¶§ ã¾Æº¼ ÀÚ¿ø ¸ñ·Ï +DirectoryIndex + local-url [local-url] ... +DirectoryIndex index.html +server configvirtual host +directory.htaccess +Indexes + + +

    DirectoryIndex Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®°¡ + µð·ºÅ丮¸í ³¡¿¡ /¸¦ ºÙ¿©¼­ µð·ºÅ丮ÀÇ index¸¦ ¿äûÇÒ¶§ ã¾Æº¼ + ÀÚ¿ø ¸ñ·ÏÀ» ÁöÁ¤ÇÑ´Ù. Local-urlÀº ¿äûÇÑ µð·ºÅ丮¿¡ + »ó´ëÀûÀÎ ¹®¼­ÀÇ (%·Î ÀÎÄÚµùµÈ) URLÀÌ´Ù. º¸ÅëÀº µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϸíÀÌ´Ù. ¿©·¯ URLÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ°í, ÀÌ °æ¿ì ¼­¹ö´Â + ù¹ø°·Î ãÀº ÆÄÀÏÀ» º¸³½´Ù. ÀÚ¿øÀ» ãÀ» ¼ö ¾ø°í + Indexes ¿É¼ÇÀ» ¼³Á¤ÇÏ¿´´Ù¸é ¼­¹ö´Â Á÷Á¢ µð·ºÅ丮 + ¸ñ·ÏÀ» ¸¸µç´Ù.

    + + ¿¹Á¦ + DirectoryIndex index.html + + +

    ÀÌ °æ¿ì http://myserver/docs/¸¦ ¿äûÇÒ¶§ + http://myserver/docs/index.htmlÀÌ ÀÖÀ¸¸é À̸¦ + º¸³»°í, ¾ø´Ù¸é µð·ºÅ丮 ¸ñ·ÏÀ» º¸³½´Ù.

    + +

    ¹®¼­°¡ ¹Ýµå½Ã µð·ºÅ丮¿¡ »ó´ëÀûÀÏ ÇÊ¿ä´Â ¾ø´Ù.

    + + + DirectoryIndex index.html index.txt /cgi-bin/index.pl + + +

    ÀÌ °æ¿ì µð·ºÅ丮¿¡ index.htmlÀ̳ª + index.txt°¡ ¾øÀ¸¸é CGI ½ºÅ©¸³Æ® + /cgi-bin/index.plÀ» ½ÇÇàÇÑ´Ù.

    +
    +
    + + +DirectorySlash +¸¶Áö¸· ½½·¡½¬ ¸®´ÙÀÌ·º¼ÇÀ» Å°°í ²ö´Ù +DirectorySlash On|Off +DirectorySlash On +server configvirtual host +directory.htaccess +Indexes +¾ÆÆÄÄ¡ 2.0.51 ÀÌÈĺÎÅÍ + + +

    DirectorySlash Áö½Ã¾î´Â + mod_dir°¡ µð·ºÅ丮¸¦ °¡¸®Å°´Â URLÀ» ¼öÁ¤ÇÒÁö + ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù.

    + +

    »ç¿ëÀÚ°¡ ¸¶Áö¸· ½½·¡½¬¾øÀÌ µð·ºÅ丮¿¡ ÇØ´çÇÏ´Â ÀÚ¿øÀ» + ¿äûÇϸé, mod_dir´Â º¸Åë ´ÙÀ½°ú °°Àº ÀÌÀ¯·Î + »ç¿ëÀÚ¸¦ ¸¶Áö¸· ½½·¡½¬¸¦ ºÙÀÎ µ¿ÀÏÇÑ ÀÚ¿øÀ¸·Î + ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.

    + +
      +
    • »ç¿ëÀÚ´Â °á±¹ ÀÚ¿øÀÇ Á¤±Ô URLÀ» ¿äûÇÏ°Ô µÈ´Ù
    • +
    • mod_autoindex°¡ ¿Ã¹Ù·Î µ¿ÀÛÇÑ´Ù. ÀÌ + ±â´ÉÀÌ ¾ø´Ù¸é ÀÌ ¸ðµâÀº ¸µÅ©¿¡ À߸øµÈ °æ·Î¸¦ ¾²°Ô µÈ´Ù.
    • +
    • DirectoryIndex´Â + ¸¶Áö¸· ½½·¡½¬°¡ ÀÖ´Â µð·ºÅ丮 ¿äû¸¸À» ó¸®ÇÑ´Ù.
    • +
    • html ÆäÀÌÁö¿¡ ÀÖ´Â »ó´ëÀûÀÎ URL ÂüÁ¶°¡ ¿Ã¹Ù·Î µ¿ÀÛÇÑ´Ù.
    • +
    + +

    ±×·±µ¥ ÀÌ ±â´ÉÀ» ¿øÇÏÁö ¾Ê°Å³ª À§¿¡ µç ÀÌÀ¯°¡ + ´ç½Å¿¡°Ô ¾Ë¸ÂÁö ¾Ê´Ù¸é ´ÙÀ½°ú °°ÀÌ ¸®´ÙÀÌ·º¼ÇÀ» ÇÏÁö ¾ÊÀ» + ¼ö ÀÖ´Ù.

    + + + # ¾Æ·¡ º¸¾È °æ°í Âü°í!
    + <Location /some/path>
    + + DirectorySlash Off
    + SetHandler some-handler
    +
    + </Location> +
    + + º¸¾È °æ°í +

    ¸¶Áö¸· ½½·¡½¬ ¸®´ÙÀÌ·º¼ÇÀ» ²ô¸é Á¤º¸°¡ À¯ÃâµÉ ¼ö ÀÖ´Ù. + (Options +Indexes) mod_autoindex¸¦ + »ç¿ëÇÏ°í DirectoryIndex¸¦ + (index.html °°Àº) À¯È¿ÇÑ ÀÚ¿øÀ¸·Î ¼³Á¤ÇÏ¿´Áö¸¸ + ÇØ´ç URL¿¡ ´Ù¸¥ Ưº°ÇÑ Çڵ鷯°¡ ¾ø´Â »óȲÀ» »ó»óÇغ¸¶ó. + ÀÌ °æ¿ì ¸¶Áö¸· ½½·¡½¬°¡ ÀÖ´Â ¿äûÀº index.html + ÆÄÀÏÀ» º¸¿©ÁØ´Ù. ±×·¯³ª ¸¶Áö¸· ½½·¡½¬°¡ ¾ø´Â ¿äûÀº + µð·ºÅ丮 ³»¿ëÀ» º¸¿©ÁØ´Ù.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_dir.xml.meta b/trunk/docs/manual/mod/mod_dir.xml.meta new file mode 100644 index 0000000000..9f9e57b9c3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dir.xml.meta @@ -0,0 +1,13 @@ + + + + mod_dir + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_disk_cache.html b/trunk/docs/manual/mod/mod_disk_cache.html new file mode 100644 index 0000000000..84207adab3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.html @@ -0,0 +1,11 @@ +URI: mod_disk_cache.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_disk_cache.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_disk_cache.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_disk_cache.html.en b/trunk/docs/manual/mod/mod_disk_cache.html.en new file mode 100644 index 0000000000..18bd5eef0a --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.html.en @@ -0,0 +1,178 @@ + + + +mod_disk_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_disk_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Content cache storage manager keyed to URIs
    Status:Extension
    Module Identifier:disk_cache_module
    Source File:mod_disk_cache.c
    +

    Summary

    + +

    mod_disk_cache implements a disk based storage + manager. It is primarily of use in conjunction + mod_cache.

    + +

    Content is stored in and retrieved from the cache using URI based + keys. Content with access protection is not cached.

    + +

    htcacheclean can be used to maintain the cache + size at a maximum level.

    + +

    Note:

    +

    mod_disk_cache requires the services of + mod_cache.

    +
    +
    + + +
    top
    +

    CacheDirLength Directive

    + + + + + + + +
    Description:The number of characters in subdirectory names
    Syntax:CacheDirLength length
    Default:CacheDirLength 2
    Context:server config, virtual host
    Status:Extension
    Module:mod_disk_cache
    +

    The CacheDirLength directive sets the number + of characters for each subdirectory name in the cache hierarchy.

    + +
    +

    The result of CacheDirLevels* CacheDirLength + must not be higher than 20.

    +
    + +

    + CacheDirLength 4 +

    + +
    +
    top
    +

    CacheDirLevels Directive

    + + + + + + + +
    Description:The number of levels of subdirectories in the +cache.
    Syntax:CacheDirLevels levels
    Default:CacheDirLevels 3
    Context:server config, virtual host
    Status:Extension
    Module:mod_disk_cache
    +

    The CacheDirLevels directive sets the number + of subdirectory levels in the cache. Cached data will be saved this + many directory levels below the CacheRoot directory.

    + +
    +

    The result of CacheDirLevels* + CacheDirLength must + not be higher than 20.

    +
    + +

    + CacheDirLevels 5 +

    + +
    +
    top
    +

    CacheMaxFileSize Directive

    + + + + + + + +
    Description:The maximum size (in bytes) of a document to be placed in the +cache
    Syntax:CacheMaxFileSize bytes
    Default:CacheMaxFileSize 1000000
    Context:server config, virtual host
    Status:Extension
    Module:mod_disk_cache
    +

    The CacheMaxFileSize directive sets the + maximum size, in bytes, for a document to be considered for storage in + the cache.

    + +

    + CacheMaxFileSize 64000 +

    + +
    +
    top
    +

    CacheMinFileSize Directive

    + + + + + + + +
    Description:The minimum size (in bytes) of a document to be placed in the +cache
    Syntax:CacheMinFileSize bytes
    Default:CacheMinFileSize 1
    Context:server config, virtual host
    Status:Extension
    Module:mod_disk_cache
    +

    The CacheMinFileSize directive sets the + minimum size, in bytes, for a document to be considered for storage + in the cache.

    + +

    + CacheMinFileSize 64 +

    + +
    +
    top
    +

    CacheRoot Directive

    + + + + + + +
    Description:The directory root under which cache files are +stored
    Syntax:CacheRoot directory
    Context:server config, virtual host
    Status:Extension
    Module:mod_disk_cache
    +

    The CacheRoot directive defines the name of + the directory on the disk to contain cache files. If the mod_disk_cache module has been loaded or compiled in to the + Apache server, this directive must be defined. Failing to + provide a value for CacheRoot will result in + a configuration file processing error. The CacheDirLevels and CacheDirLength directives define + the structure of the directories under the specified root directory.

    + +

    + CacheRoot c:/cacheroot +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_disk_cache.html.ja.euc-jp b/trunk/docs/manual/mod/mod_disk_cache.html.ja.euc-jp new file mode 100644 index 0000000000..fce4d9301c --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.html.ja.euc-jp @@ -0,0 +1,174 @@ + + + +mod_disk_cache - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_disk_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¥­¥ã¥Ã¥·¥å¥¹¥È¥ì¡¼¥¸´ÉÍý
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:disk_cache_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_disk_cache.c
    +

    ³µÍ×

    + +

    mod_disk_cache ¤Ï¥Ç¥£¥¹¥¯¤ò»ÈÍѤ·¤¿¥¹¥È¥ì¡¼¥¸ + ´ÉÍýµ¡¹½¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£¼ç¤Ë + mod_cache ¤ÈÁȤ߹ç¤ï¤»¤Æ»È¤ï¤ì¤Þ¤¹¡£

    + +

    ¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å¤Ø¤ÎÊݸ¤È¼èÆÀ¤Ï URI ¤Ë´ð¤Å¤¤¤¿¥­¡¼¤¬»È¤ï¤ì¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹Êݸî¤Î¤«¤±¤é¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥Ä¤Ï¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    + +

    ¥­¥ã¥Ã¥·¥å¤ÎÂ礭¤µ¤òºÇÂç¥ì¥Ù¥ë¤Ç°Ý»ý¤¹¤ë¤¿¤á¤Ë + htcacheclean ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Ãí:

    +

    mod_disk_cache ¤Ï + mod_cache ¤òɬÍפȤ·¤Þ¤¹

    +
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    CacheDirLength ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê̾¤Îʸ»ú¿ô
    ¹½Ê¸:CacheDirLength length
    ¥Ç¥Õ¥©¥ë¥È:CacheDirLength 2
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_disk_cache
    +

    CacheDirLength ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥­¥ã¥Ã¥·¥å + ³¬Áؤγƥµ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Îʸ»ú¿ô¤òÀßÄꤷ¤Þ¤¹¡£

    + +
    +

    CacheDirLevels* + CacheDirLength ¤Î + ·ë²Ì¤Ï 20 °ÊÆâ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +

    + CacheDirLength 4 +

    + +
    +
    top
    +

    CacheDirLevels ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î¿¼¤µ¤Î¿ô
    ¹½Ê¸:CacheDirLevels levels
    ¥Ç¥Õ¥©¥ë¥È:CacheDirLevels 3
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_disk_cache
    +

    CacheDirLevels ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥­¥ã¥Ã¥·¥å¤Î + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î¿¼¤µ¤òÀßÄꤷ¤Þ¤¹¡£¥­¥ã¥Ã¥·¥å¥Ç¡¼¥¿¤Ï CacheRoot ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é + ¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¿¼¤µÊ¬²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÊݸ¤µ¤ì¤Þ¤¹¡£

    + +
    +

    CacheDirLevels* + CacheDirLength ¤Î + ·ë²Ì¤Ï 20 °ÊÆâ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +

    + CacheDirLevels 5 +

    + +
    +
    top
    +

    CacheMaxFileSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇÂç¤Î (¥Ð¥¤¥È¤Ç¤Î) ¥µ¥¤¥º
    ¹½Ê¸:CacheMaxFileSize bytes
    ¥Ç¥Õ¥©¥ë¥È:CacheMaxFileSize 1000000
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_disk_cache
    +

    CacheMaxFileSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤ò + ¥­¥ã¥Ã¥·¥å¤¹¤ë¤«¤É¤¦¤«¤òȽÄꤹ¤ë¡¢ºÇÂç¤Î¥µ¥¤¥º¤ò¥Ð¥¤¥È¿ô¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    + CacheMaxFileSize 64000 +

    + +
    +
    top
    +

    CacheMinFileSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇ¾®¸Â¤Î (¥Ð¥¤¥È¤Ç¤Î) Â礭¤µ
    ¹½Ê¸:CacheMinFileSize bytes
    ¥Ç¥Õ¥©¥ë¥È:CacheMinFileSize 1
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_disk_cache
    +

    CacheMinFileSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤ò + ¥­¥ã¥Ã¥·¥å¤¹¤ë¤«¤É¤¦¤«¤òȽÄꤹ¤ë¡¢ºÇ¾®¤Î¥µ¥¤¥º¤ò¥Ð¥¤¥È¿ô¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    + CacheMinFileSize 64 +

    + +
    +
    top
    +

    CacheRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë¤¬Êݴɤµ¤ì¤ë¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê
    ¹½Ê¸:CacheRoot directory
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_disk_cache
    +

    CacheRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë¤ò + Êݴɤ¹¤ë¤¿¤á¤Î¥Ç¥£¥¹¥¯¾å¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£mod_disk_cache ¥â¥¸¥å¡¼¥ë¤¬ Apache ¥µ¡¼¥Ð¤Ë¥í¡¼¥É¤µ¤ì¤Æ + ¤¤¤ë¤«¡¢ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ì¤Ð¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïɬ¤º + ÄêµÁ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + CacheRoot ¤ÎÃͤò»ØÄꤷ¤Ê¤±¤ì¤Ð¡¢ + ÀßÄê¥Õ¥¡¥¤¥ë¤Î½èÍý¤Ç¥¨¥é¡¼¤Ë¤Ê¤ê¤Þ¤¹¡£CacheDirLevels ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È CacheDirLength ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + »ØÄꤵ¤ì¤¿¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¹½À®¤òÄêµÁ¤·¤Þ¤¹¡£

    + +

    + CacheRoot c:/cacheroot +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_disk_cache.html.ko.euc-kr b/trunk/docs/manual/mod/mod_disk_cache.html.ko.euc-kr new file mode 100644 index 0000000000..0ea6be4213 --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.html.ko.euc-kr @@ -0,0 +1,175 @@ + + + +mod_disk_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_disk_cache

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:Content cache storage manager keyed to URIs
    »óÅÂ:Experimental
    ¸ðµâ¸í:disk_cache_module
    ¼Ò½ºÆÄÀÏ:mod_disk_cache.c
    +

    ¿ä¾à

    + +
    + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... +
    + +

    mod_disk_cache´Â µð½ºÅ©±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ + ±¸ÇöÇÑ´Ù. ÀÌ ¸ðµâÀº ±âº»ÀûÀ¸·Î mod_proxy¿Í + °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    ³»¿ëÀ» URI¸¦ Åä´ë·Î ¸¸µç Å°·Î ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±Ùº¸È£°¡ µÈ ³»¿ëÀº ij½¬ÇÏÁö¾Ê´Â´Ù.

    + +

    ÁÖÀÇ:

    +

    mod_disk_cache´Â + mod_cache°¡ ÇÊ¿äÇÏ´Ù.

    +
    +
    + + +
    top
    +

    CacheDirLength Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÇÏÀ§µð·ºÅ丮¸íÀÇ ¹®ÀÚ°³¼ö
    ¹®¹ý:CacheDirLength length
    ±âº»°ª:CacheDirLength 2
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_disk_cache
    +

    CacheDirLength Áö½Ã¾î´Â ij½¬ + °èÃþ±¸Á¶¿¡¼­ °¢ ÇÏÀ§µð·ºÅ丮¸íÀÇ ¹®ÀÚ¼ö¸¦ ÁöÁ¤ÇÑ´Ù.

    + +
    +

    CacheDirLevels¿Í + CacheDirLength¸¦ °öÇÏ¿© 20 º¸´Ù + Å©¸é ¾ÈµÈ´Ù.

    +
    + +

    + CacheDirLength 4 +

    + +
    +
    top
    +

    CacheDirLevels Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬ÀÇ ÇÏÀ§µð·ºÅ丮 ±íÀÌ.
    ¹®¹ý:CacheDirLevels levels
    ±âº»°ª:CacheDirLevels 3
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_disk_cache
    +

    CacheDirLevels Áö½Ã¾î´Â ij½¬ÀÇ + ÇÏÀ§µð·ºÅ丮 ±íÀ̸¦ ÁöÁ¤ÇÑ´Ù. ij½¬µÈ ÀڷḦ CacheRoot µð·ºÅ丮 + ¾Æ·¡ ÀÌ ±íÀ̱îÁö ÀúÀåÇÑ´Ù.

    + +
    +

    CacheDirLevels¿Í CacheDirLength¸¦ + °öÇÏ¿© 20 º¸´Ù Å©¸é ¾ÈµÈ´Ù.

    +
    + +

    + CacheDirLevels 5 +

    + +
    +
    top
    +

    CacheMaxFileSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ëÅ©±â (¹ÙÀÌÆ® ´ÜÀ§)
    ¹®¹ý:CacheMaxFileSize bytes
    ±âº»°ª:CacheMaxFileSize 1000000
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_disk_cache
    +

    CacheMaxFileSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ëÅ©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + +

    + CacheMaxFileSize 64000 +

    + +
    +
    top
    +

    CacheMinFileSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼ÒÅ©±â (¹ÙÀÌÆ® ´ÜÀ§)
    ¹®¹ý:CacheMinFileSize bytes
    ±âº»°ª:CacheMinFileSize 1
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_disk_cache
    +

    CacheMinFileSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼ÒÅ©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + +

    + CacheMinFileSize 64 +

    + +
    +
    top
    +

    CacheRoot Áö½Ã¾î

    + + + + + + +
    ¼³¸í:ij½¬ ÆÄÀÏÀ» ÀúÀåÇÒ µð·ºÅ丮 root
    ¹®¹ý:CacheRoot directory
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_disk_cache
    +

    CacheRoot Áö½Ã¾î´Â µð½ºÅ©¿¡¼­ + ij½¬ ÆÄÀÏÀ» ÀúÀåÇÒ µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. mod_disk_cache ¸ðµâÀ» ¾ÆÆÄÄ¡ ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀÏÇÏ¿´°Å³ª + ÀоîµéÀÎ °æ¿ì ¹Ýµå½Ã ÀÌ Áö½Ã¾î¸¦ Á¤ÀÇÇØ¾ß ÇÑ´Ù. + CacheRoot¿¡ °ªÀÌ ¾øÀ¸¸é ¼³Á¤ÆÄÀÏÀ» + ó¸®ÇÏÁö ¾Ê´Â´Ù. CacheDirLevels¿Í CacheDirLength Áö½Ã¾î´Â + ÀÌ Áö½Ã¾î·Î ÁöÁ¤ÇÑ root µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 ±¸Á¶¸¦ Áö½ÃÇÑ´Ù.

    + +

    + CacheRoot c:/cacheroot +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_disk_cache.xml b/trunk/docs/manual/mod/mod_disk_cache.xml new file mode 100644 index 0000000000..a2880abbc3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.xml @@ -0,0 +1,164 @@ + + + + + + + + + +mod_disk_cache +Content cache storage manager keyed to URIs +Extension +mod_disk_cache.c +disk_cache_module + + +

    mod_disk_cache implements a disk based storage + manager. It is primarily of use in conjunction + mod_cache.

    + +

    Content is stored in and retrieved from the cache using URI based + keys. Content with access protection is not cached.

    + +

    htcacheclean can be used to maintain the cache + size at a maximum level.

    + + Note: +

    mod_disk_cache requires the services of + mod_cache.

    +
    +
    + + +CacheRoot +The directory root under which cache files are +stored +CacheRoot directory +server configvirtual host + + + +

    The CacheRoot directive defines the name of + the directory on the disk to contain cache files. If the mod_disk_cache module has been loaded or compiled in to the + Apache server, this directive must be defined. Failing to + provide a value for CacheRoot will result in + a configuration file processing error. The CacheDirLevels and CacheDirLength directives define + the structure of the directories under the specified root directory.

    + + + CacheRoot c:/cacheroot + +
    +
    + + +CacheDirLevels +The number of levels of subdirectories in the +cache. +CacheDirLevels levels +CacheDirLevels 3 +server configvirtual host + + + +

    The CacheDirLevels directive sets the number + of subdirectory levels in the cache. Cached data will be saved this + many directory levels below the CacheRoot directory.

    + + +

    The result of CacheDirLevels* + CacheDirLength must + not be higher than 20.

    +
    + + + CacheDirLevels 5 + +
    +
    + + +CacheDirLength +The number of characters in subdirectory names +CacheDirLength length +CacheDirLength 2 +server configvirtual host + + + +

    The CacheDirLength directive sets the number + of characters for each subdirectory name in the cache hierarchy.

    + + +

    The result of CacheDirLevels* CacheDirLength + must not be higher than 20.

    +
    + + + CacheDirLength 4 + +
    +
    + + +CacheMinFileSize +The minimum size (in bytes) of a document to be placed in the +cache +CacheMinFileSize bytes +CacheMinFileSize 1 +server configvirtual host + + + +

    The CacheMinFileSize directive sets the + minimum size, in bytes, for a document to be considered for storage + in the cache.

    + + + CacheMinFileSize 64 + +
    +
    + + +CacheMaxFileSize +The maximum size (in bytes) of a document to be placed in the +cache +CacheMaxFileSize bytes +CacheMaxFileSize 1000000 +server configvirtual host + + + +

    The CacheMaxFileSize directive sets the + maximum size, in bytes, for a document to be considered for storage in + the cache.

    + + + CacheMaxFileSize 64000 + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_disk_cache.xml.ja b/trunk/docs/manual/mod/mod_disk_cache.xml.ja new file mode 100644 index 0000000000..56aa3bc2c5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.xml.ja @@ -0,0 +1,159 @@ + + + + + + + + + +mod_disk_cache +URI $B$r%-!<$K$7$?%3%s%F%s%D%-%c%C%7%e%9%H%l!<%84IM}(B +Extension +mod_disk_cache.c +disk_cache_module + + +

    mod_disk_cache $B$O%G%#%9%/$r;HMQ$7$?%9%H%l!<%8(B + $B4IM}5!9=$rmod_cache $B$HAH$_9g$o$;$F;H$o$l$^$9!#(B

    + +

    $B%3%s%F%s%D$N%-%c%C%7%e$X$NJ]B8$H + +

    $B%-%c%C%7%e$NBg$-$5$r:GBg%l%Y%k$G0];}$9$k$?$a$K(B + htcacheclean $B$r;H$&$3$H$,$G$-$^$9!#(B

    + + $BCm(B: +

    mod_disk_cache $B$O(B + mod_cache $B$rI,MW$H$7$^$9(B

    +
    +
    + + +CacheRoot +$B%-%c%C%7%e%U%!%$%k$,J]4I$5$l$k%k!<%H%G%#%l%/%H%j(B +CacheRoot directory +server configvirtual host + + + +

    CacheRoot $B%G%#%l%/%F%#%V$O%-%c%C%7%e%U%!%$%k$r(B + $BJ]4I$9$k$?$a$N%G%#%9%/>e$N%G%#%l%/%H%j$r;XDj$7$^$9!#(Bmod_disk_cache $B%b%8%e!<%k$,(B Apache $B%5!<%P$K%m!<%I$5$l$F(B + $B$$$k$+!"AH$_9~$^$l$F$$$l$P!"$3$N%G%#%l%/%F%#%V$O(B$BI,$:(B + $BDj5A$7$J$1$l$P$J$j$^$;$s!#(B + CacheRoot $B$NCM$r;XDj$7$J$1$l$P!"(B + $B@_Dj%U%!%$%k$N=hM}$G%(%i!<$K$J$j$^$9!#(BCacheDirLevels $B%G%#%l%/%F%#%V$H(B CacheDirLength $B%G%#%l%/%F%#%V$,(B + $B;XDj$5$l$?%k!<%H%G%#%l%/%H%j2<$N%G%#%l%/%H%j9=@.$rDj5A$7$^$9!#(B

    + + + CacheRoot c:/cacheroot + +
    +
    + + +CacheDirLevels +$B%-%c%C%7%e$N%5%V%G%#%l%/%H%j$N?<$5$N?t(B +CacheDirLevels levels +CacheDirLevels 3 +server configvirtual host + + + +

    CacheDirLevels $B%G%#%l%/%F%#%V$O%-%c%C%7%e$N(B + $B%5%V%G%#%l%/%H%j$N?<$5$r@_Dj$7$^$9!#%-%c%C%7%e%G!<%?$O(B CacheRoot $B%G%#%l%/%H%j$+$i(B + $B$3$N%G%#%l%/%H%j$N?<$5J,2<$N%G%#%l%/%H%j$KJ]B8$5$l$^$9!#(B

    + + +

    CacheDirLevels* + CacheDirLength $B$N(B + $B7k2L$O(B 20 $B0JFb$G$J$1$l$P$J$j$^$;$s!#(B

    +
    + + + CacheDirLevels 5 + +
    +
    + + +CacheDirLength +$B%5%V%G%#%l%/%H%jL>$NJ8;z?t(B +CacheDirLength length +CacheDirLength 2 +server configvirtual host + + + +

    CacheDirLength $B%G%#%l%/%F%#%V$O%-%c%C%7%e(B + $B3,AX$N3F%5%V%G%#%l%/%H%j$NJ8;z?t$r@_Dj$7$^$9!#(B

    + + +

    CacheDirLevels* + CacheDirLength $B$N(B + $B7k2L$O(B 20 $B0JFb$G$J$1$l$P$J$j$^$;$s!#(B

    +
    + + + CacheDirLength 4 + +
    +
    + + +CacheMinFileSize +$B%-%c%C%7%e$KJ]4I$5$l$k%I%-%e%a%s%H$N:G>.8B$N(B ($B%P%$%H$G$N(B) $BBg$-$5(B +CacheMinFileSize bytes +CacheMinFileSize 1 +server configvirtual host + + + +

    CacheMinFileSize $B%G%#%l%/%F%#%V$O!"%I%-%e%a%s%H$r(B + $B%-%c%C%7%e$9$k$+$I$&$+$rH=Dj$9$k!":G>.$N%5%$%:$r%P%$%H?t$G@_Dj$7$^$9!#(B

    + + + CacheMinFileSize 64 + +
    +
    + + +CacheMaxFileSize +$B%-%c%C%7%e$KJ]4I$5$l$k%I%-%e%a%s%H$N:GBg$N(B ($B%P%$%H$G$N(B) $B%5%$%:(B +CacheMaxFileSize bytes +CacheMaxFileSize 1000000 +server configvirtual host + + + +

    CacheMaxFileSize $B%G%#%l%/%F%#%V$O!"%I%-%e%a%s%H$r(B + $B%-%c%C%7%e$9$k$+$I$&$+$rH=Dj$9$k!":GBg$N%5%$%:$r%P%$%H?t$G@_Dj$7$^$9!#(B

    + + + CacheMaxFileSize 64000 + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_disk_cache.xml.ko b/trunk/docs/manual/mod/mod_disk_cache.xml.ko new file mode 100644 index 0000000000..d18bee7ac0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.xml.ko @@ -0,0 +1,159 @@ + + + + + + + + + +mod_disk_cache +Content cache storage manager keyed to URIs +Experimental +mod_disk_cache.c +disk_cache_module + + + + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... + + +

    mod_disk_cache´Â µð½ºÅ©±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ + ±¸ÇöÇÑ´Ù. ÀÌ ¸ðµâÀº ±âº»ÀûÀ¸·Î mod_proxy¿Í + °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    ³»¿ëÀ» URI¸¦ Åä´ë·Î ¸¸µç Å°·Î ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±Ùº¸È£°¡ µÈ ³»¿ëÀº ij½¬ÇÏÁö¾Ê´Â´Ù.

    + + ÁÖÀÇ: +

    mod_disk_cache´Â + mod_cache°¡ ÇÊ¿äÇÏ´Ù.

    +
    +
    + + +CacheRoot +ij½¬ ÆÄÀÏÀ» ÀúÀåÇÒ µð·ºÅ丮 root +CacheRoot directory +server configvirtual host + + + +

    CacheRoot Áö½Ã¾î´Â µð½ºÅ©¿¡¼­ + ij½¬ ÆÄÀÏÀ» ÀúÀåÇÒ µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. mod_disk_cache ¸ðµâÀ» ¾ÆÆÄÄ¡ ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀÏÇÏ¿´°Å³ª + ÀоîµéÀÎ °æ¿ì ¹Ýµå½Ã ÀÌ Áö½Ã¾î¸¦ Á¤ÀÇÇØ¾ß ÇÑ´Ù. + CacheRoot¿¡ °ªÀÌ ¾øÀ¸¸é ¼³Á¤ÆÄÀÏÀ» + ó¸®ÇÏÁö ¾Ê´Â´Ù. CacheDirLevels¿Í CacheDirLength Áö½Ã¾î´Â + ÀÌ Áö½Ã¾î·Î ÁöÁ¤ÇÑ root µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 ±¸Á¶¸¦ Áö½ÃÇÑ´Ù.

    + + + CacheRoot c:/cacheroot + +
    +
    + + +CacheDirLevels +ij½¬ÀÇ ÇÏÀ§µð·ºÅ丮 ±íÀÌ. +CacheDirLevels levels +CacheDirLevels 3 +server configvirtual host + + + +

    CacheDirLevels Áö½Ã¾î´Â ij½¬ÀÇ + ÇÏÀ§µð·ºÅ丮 ±íÀ̸¦ ÁöÁ¤ÇÑ´Ù. ij½¬µÈ ÀڷḦ CacheRoot µð·ºÅ丮 + ¾Æ·¡ ÀÌ ±íÀ̱îÁö ÀúÀåÇÑ´Ù.

    + + +

    CacheDirLevels¿Í CacheDirLength¸¦ + °öÇÏ¿© 20 º¸´Ù Å©¸é ¾ÈµÈ´Ù.

    +
    + + + CacheDirLevels 5 + +
    +
    + + +CacheDirLength +ÇÏÀ§µð·ºÅ丮¸íÀÇ ¹®ÀÚ°³¼ö +CacheDirLength length +CacheDirLength 2 +server configvirtual host + + + +

    CacheDirLength Áö½Ã¾î´Â ij½¬ + °èÃþ±¸Á¶¿¡¼­ °¢ ÇÏÀ§µð·ºÅ丮¸íÀÇ ¹®ÀÚ¼ö¸¦ ÁöÁ¤ÇÑ´Ù.

    + + +

    CacheDirLevels¿Í + CacheDirLength¸¦ °öÇÏ¿© 20 º¸´Ù + Å©¸é ¾ÈµÈ´Ù.

    +
    + + + CacheDirLength 4 + +
    +
    + + +CacheMinFileSize +ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼ÒÅ©±â (¹ÙÀÌÆ® ´ÜÀ§) +CacheMinFileSize bytes +CacheMinFileSize 1 +server configvirtual host + + + +

    CacheMinFileSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼ÒÅ©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + + + CacheMinFileSize 64 + +
    +
    + + +CacheMaxFileSize +ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ëÅ©±â (¹ÙÀÌÆ® ´ÜÀ§) +CacheMaxFileSize bytes +CacheMaxFileSize 1000000 +server configvirtual host + + + +

    CacheMaxFileSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ëÅ©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + + + CacheMaxFileSize 64000 + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_disk_cache.xml.meta b/trunk/docs/manual/mod/mod_disk_cache.xml.meta new file mode 100644 index 0000000000..acba111bee --- /dev/null +++ b/trunk/docs/manual/mod/mod_disk_cache.xml.meta @@ -0,0 +1,13 @@ + + + + mod_disk_cache + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_dumpio.html b/trunk/docs/manual/mod/mod_dumpio.html new file mode 100644 index 0000000000..2548737a8b --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.html @@ -0,0 +1,7 @@ +URI: mod_dumpio.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_dumpio.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_dumpio.html.en b/trunk/docs/manual/mod/mod_dumpio.html.en new file mode 100644 index 0000000000..8620a4c445 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.html.en @@ -0,0 +1,106 @@ + + + +mod_dumpio - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_dumpio

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    Description:Dumps all I/O to error log as desired.
    Status:Extension
    Module Identifier:dumpio_module
    Source File:mod_dumpio.c
    +

    Summary

    + +

    mod_dumpio allows for the logging of + all input received by Apache and/or all output sent by + Apache to be logged (dumped) to the error.log file. +

    + +

    The data logging is done right after SSL decoding (for + input) and right before SSL encoding (for output). As can + be expected, this can produce extreme volumes of data, + and should only be used when debugging problems.

    +
    +

    Directives

    + +

    Topics

    +
    +
    top
    +
    +

    Enabling dumpio Support

    + + +

    To enable the module, it should be compiled and + loaded in to your running Apache configuration. Logging + can then be enabled or disabled via the below directives.

    +
    +
    top
    +

    DumpIOInput Directive

    + + + + + + + + +
    Description:Dump all input data to the error log
    Syntax:DumpIOInput On|Off
    Default:DumpIOInput Off
    Context:server config
    Status:Extension
    Module:mod_dumpio
    Compatibility:DumpIOInput is only available in Apache 2.1.3 and +later.
    +

    Enable dumping of all input.

    + +

    Example

    + DumpIOInput On +

    + +
    +
    top
    +

    DumpIOOutput Directive

    + + + + + + + + +
    Description:Dump all output data to the error log
    Syntax:DumpIOOutput On|Off
    Default:DumpIOOutput Off
    Context:server config
    Status:Extension
    Module:mod_dumpio
    Compatibility:DumpIOOutput is only available in Apache 2.1.3 and +later.
    +

    Enable dumping of all output.

    + +

    Example

    + DumpIOOutput On +

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dumpio.html.ja.euc-jp b/trunk/docs/manual/mod/mod_dumpio.html.ja.euc-jp new file mode 100644 index 0000000000..289a609add --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.html.ja.euc-jp @@ -0,0 +1,105 @@ + + + +mod_dumpio - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_dumpio

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    ÀâÌÀ:˾¤à¤è¤¦¤Ë¤¹¤Ù¤Æ¤Î I/O ¤ò¥¨¥é¡¼¥í¥°¤Ë¥À¥ó¥×¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:dumpio_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_dumpio.c
    +

    ³µÍ×

    + +

    mod_dumpio ¤ò»È¤¦¤È¡¢Apache ¤¬¼õ¤±¼è¤Ã¤¿¤¹¤Ù¤Æ¤ÎÆþÎÏ¤È + Apache ¤Ë¤è¤êÁ÷¤é¤ì¤¿¤¹¤Ù¤Æ¤Î½ÐÎϤȤΡ¢Î¾Êý¤â¤·¤¯¤Ï¤É¤Á¤é¤«°ìÊý¤ò¡¢ + ¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤Ë¥í¥°¼ý½¸ (ÌõÃí: ¥À¥ó¥× dump) + ¤Ç¤­¤Þ¤¹¡£

    + +

    ¥Ç¡¼¥¿¤Î¥í¥®¥ó¥°¤Ï¡¢SSL Éü¹æ²½¤Îľ¸å (ÆþÎÏ) ¤È SSL + °Å¹æ²½¤ÎľÁ° (½ÐÎÏ) ¤Ë¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£¤´ÁÛÁü¤ÎÄ̤ꡢ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¤È¤Æ¤Ä¤â¤Ê¤¤¥Ç¡¼¥¿Î̤ò½ÐÎϤ·¤Þ¤¹¤Î¤Ç¡¢ + ÌäÂê¤ò¥Ç¥Ð¥Ã¥°¤·¤Æ¤¤¤ë¤È¤­¤Ë¤Î¤ß»ÈÍѤ¹¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    dumpio ¥µ¥Ý¡¼¥È¤òÍ­¸ú¤Ë¤¹¤ë

    + + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢¥â¥¸¥å¡¼¥ë¤¬¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤Æ¡¢ + ¼Â¹Ô¤¹¤ë Apache ¤ÎÀßÄê¤Ç¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¥í¥®¥ó¥°µ¡Ç½¤Ï¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤ÆÍ­¸ú¤Ë¤·¤¿¤ê + ̵¸ú¤Ë¤·¤¿¤ê¤Ç¤­¤Þ¤¹¡£

    +
    +
    top
    +

    DumpIOInput ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¨¥é¡¼¥í¥°¤Ë¤¹¤Ù¤Æ¤ÎÆþÎϥǡ¼¥¿¤ò¥À¥ó¥×
    ¹½Ê¸:DumpIOInput On|Off
    ¥Ç¥Õ¥©¥ë¥È:DumpIOInput Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dumpio
    ¸ß´¹À­:DumpIOInput ¤Ï Apache 2.1.3 °Ê¹ß¤Î¤ß¤Ç»ÈÍѲÄǽ
    +

    ¤¹¤Ù¤Æ¤ÎÆþÎϤΥÀ¥ó¥×¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    Îã

    + DumpIOInput On +

    + +
    +
    top
    +

    DumpIOOutput ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¨¥é¡¼¥í¥°¤Ë¤¹¤Ù¤Æ¤Î½ÐÎϥǡ¼¥¿¤ò¥À¥ó¥×
    ¹½Ê¸:DumpIOOutput On|Off
    ¥Ç¥Õ¥©¥ë¥È:DumpIOOutput Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_dumpio
    ¸ß´¹À­:DumpIOOutput ¤Ï Apache 2.1.3 °Ê¹ß¤Ç¤Î¤ß»ÈÍѲÄǽ
    +

    ¤¹¤Ù¤Æ¤Î½ÐÎϤΥÀ¥ó¥×¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    Îã

    + DumpIOOutput On +

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_dumpio.xml b/trunk/docs/manual/mod/mod_dumpio.xml new file mode 100644 index 0000000000..21b680b68b --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.xml @@ -0,0 +1,90 @@ + + + + + + + + + +mod_dumpio +Dumps all I/O to error log as desired. +Extension +mod_dumpio.c +dumpio_module + + +

    mod_dumpio allows for the logging of + all input received by Apache and/or all output sent by + Apache to be logged (dumped) to the error.log file. +

    + +

    The data logging is done right after SSL decoding (for + input) and right before SSL encoding (for output). As can + be expected, this can produce extreme volumes of data, + and should only be used when debugging problems.

    +
    + +
    + Enabling dumpio Support + +

    To enable the module, it should be compiled and + loaded in to your running Apache configuration. Logging + can then be enabled or disabled via the below directives.

    +
    + + + +DumpIOInput +Dump all input data to the error log +DumpIOInput On|Off +DumpIOInput Off +server config +DumpIOInput is only available in Apache 2.1.3 and +later. + + +

    Enable dumping of all input.

    + + Example + DumpIOInput On + +
    + +
    + + + +DumpIOOutput +Dump all output data to the error log +DumpIOOutput On|Off +DumpIOOutput Off +server config +DumpIOOutput is only available in Apache 2.1.3 and +later. + + +

    Enable dumping of all output.

    + + Example + DumpIOOutput On + +
    + +
    +
    diff --git a/trunk/docs/manual/mod/mod_dumpio.xml.ja b/trunk/docs/manual/mod/mod_dumpio.xml.ja new file mode 100644 index 0000000000..5b95ac7cb5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.xml.ja @@ -0,0 +1,89 @@ + + + + + + + + + +mod_dumpio +$BK>$`$h$&$K$9$Y$F$N(B I/O $B$r%(%i!<%m%0$K%@%s%W$9$k(B +Extension +mod_dumpio.c +dumpio_module + + +

    mod_dumpio $B$r;H$&$H!"(BApache $B$,J}$b$7$/$O$I$A$i$+0lJ}$r!"(B + $B%(%i!<%m%0%U%!%$%k$K%m%0<}=8(B $B%@%s%W(B dump + $B$G$-$^$9!#(B

    + +

    $B%G!<%?$N%m%.%s%0$O!"(BSSL $BI|9f2=$ND>8e(B ($BF~NO(B) $B$H(B SSL + $B0E9f2=$ND>A0(B ($B=PNO(B) $B$K9T$J$o$l$^$9!#$4A[A|$NDL$j!"(B + $B$3$N%b%8%e!<%k$O$H$F$D$b$J$$%G!<%?NL$r=PNO$7$^$9$N$G!"(B + $BLdBj$r%G%P%C%0$7$F$$$k$H$-$K$N$_;HMQ$9$k$h$&$K$7$F$/$@$5$$!#(B

    +
    + +
    + dumpio $B%5%]!<%H$rM-8z$K$9$k(B + +

    $B$3$N%b%8%e!<%k$rM-8z$K$9$k$K$O!"%b%8%e!<%k$,%3%s%Q%$%k$5$l$F$$$F!"(B + $B +

    + + + +DumpIOInput +$B%(%i!<%m%0$K$9$Y$F$NF~NO%G!<%?$r%@%s%W(B +DumpIOInput On|Off +DumpIOInput Off +server config +DumpIOInput $B$O(B Apache 2.1.3 $B0J9_$N$_$G;HMQ2DG=(B + + +

    $B$9$Y$F$NF~NO$N%@%s%W$rM-8z$K$7$^$9!#(B

    + + $BNc(B + DumpIOInput On + +
    + +
    + + + +DumpIOOutput +$B%(%i!<%m%0$K$9$Y$F$N=PNO%G!<%?$r%@%s%W(B +DumpIOOutput On|Off +DumpIOOutput Off +server config +DumpIOOutput $B$O(B Apache 2.1.3 $B0J9_$G$N$_;HMQ2DG=(B + + +

    $B$9$Y$F$N=PNO$N%@%s%W$rM-8z$K$7$^$9!#(B

    + + $BNc(B + DumpIOOutput On + +
    + +
    +
    diff --git a/trunk/docs/manual/mod/mod_dumpio.xml.meta b/trunk/docs/manual/mod/mod_dumpio.xml.meta new file mode 100644 index 0000000000..94eb2c2ba3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_dumpio.xml.meta @@ -0,0 +1,12 @@ + + + + mod_dumpio + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_echo.html b/trunk/docs/manual/mod/mod_echo.html new file mode 100644 index 0000000000..f4db4ba0ed --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.html @@ -0,0 +1,11 @@ +URI: mod_echo.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_echo.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_echo.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_echo.html.en b/trunk/docs/manual/mod/mod_echo.html.en new file mode 100644 index 0000000000..779ed24058 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.html.en @@ -0,0 +1,73 @@ + + + +mod_echo - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_echo

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:A simple echo server to illustrate protocol +modules
    Status:Experimental
    Module Identifier:echo_module
    Source File:mod_echo.c
    Compatibility:Available in Apache 2.0 and later
    +

    Summary

    + +

    This module provides an example protocol module to illustrate the + concept. It provides a simple echo server. Telnet to it and type + stuff, and it will echo it.

    +
    +

    Directives

    + +
    + +
    top
    +

    ProtocolEcho Directive

    + + + + + + + +
    Description:Turn the echo server on or off
    Syntax:ProtocolEcho On|Off
    Context:server config, virtual host
    Status:Experimental
    Module:mod_echo
    Compatibility:ProtocolEcho is only available in 2.0 and +later.
    +

    The ProtocolEcho directive enables or + disables the echo server.

    + +

    Example

    + ProtocolEcho On +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_echo.html.ja.euc-jp b/trunk/docs/manual/mod/mod_echo.html.ja.euc-jp new file mode 100644 index 0000000000..bec9817767 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.html.ja.euc-jp @@ -0,0 +1,72 @@ + + + +mod_echo - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_echo

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥×¥í¥È¥³¥ë¥â¥¸¥å¡¼¥ë¤Î³µÍפò¼¨¤¹¤¿¤á¤Îñ½ã¤Ê¥¨¥³¡¼¥µ¡¼¥Ð +
    ¥¹¥Æ¡¼¥¿¥¹:Experimental
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:echo_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_echo.c
    ¸ß´¹À­:Apache 2.0 °Ê¹ß
    +

    ³µÍ×

    + +

    Ëܥ⥸¥å¡¼¥ë¤Ï¥³¥ó¥»¥×¥È¤òÅÁ¤¨¤ë¤¿¤á¤Î¥×¥í¥È¥³¥ë¥â¥¸¥å¡¼¥ë¤Î + ¼ÂÁõÎã¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£Ã±½ã¤Ê¥¨¥³¡¼¥µ¡¼¥Ð¤òÄ󶡤·¤Þ¤¹¡£ + Telnet ¤ÇÀܳ¤·¡¢Ê¸»úÎó¤òÁ÷¿®¤¹¤ë¤È¡¢¥¨¥³¡¼¤òÊÖ¤·¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    ProtocolEcho ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¨¥³¡¼¥µ¡¼¥Ð¤ÎÍ­¸ú̵¸ú¤òÀßÄꤷ¤Þ¤¹¡£
    ¹½Ê¸:ProtocolEcho On|Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Experimental
    ¥â¥¸¥å¡¼¥ë:mod_echo
    ¸ß´¹À­:Apache 2.0 °Ê¹ß
    +

    ProtocolEcho ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + ¥¨¥³¡¼¥µ¡¼¥Ð¤ÎÍ­¸ú̵¸ú¤òÀßÄꤷ¤Þ¤¹¡£

    + +

    Îã

    + ProtocolEcho On +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_echo.html.ko.euc-kr b/trunk/docs/manual/mod/mod_echo.html.ko.euc-kr new file mode 100644 index 0000000000..a3efaef473 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.html.ko.euc-kr @@ -0,0 +1,71 @@ + + + +mod_echo - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_echo

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:ÇÁ·ÎÅäÄÝ ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇÑ °£´ÜÇÑ echo ¼­¹ö
    »óÅÂ:Experimental
    ¸ðµâ¸í:echo_module
    ¼Ò½ºÆÄÀÏ:mod_echo.c
    Áö¿ø:Apache 2.0 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ÇÁ·ÎÅäÄÝ ¸ðµâÀÇ °³³äÀ» ¼³¸íÇϱâÀ§ÇÑ ¿¹Á¦ÀÌ´Ù. + ÀÌ ¸ðµâÀº °£´ÜÇÑ echo ¼­¹ö¸¦ ±¸ÇöÇÑ´Ù. ÀÌ ¼­¹ö·Î telnetÇÏ¿© + ¹«¾ð°¡¸¦ ÀÔ·ÂÇϸé, ¼­¹ö´Â ÀÔ·ÂÇÑ ³»¿ëÀÌ ±×´ë·Î ¹ÝȯÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    ProtocolEcho Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:echo ¼­¹ö¸¦ Å°°í ²ö´Ù
    ¹®¹ý:ProtocolEcho On|Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Experimental
    ¸ðµâ:mod_echo
    Áö¿ø:ProtocolEcho´Â 2.0 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù.
    +

    ProtocolEcho Áö½Ã¾î´Â echo ¼­¹ö¸¦ + Å°°í ²ö´Ù.

    + +

    ¿¹Á¦

    + ProtocolEcho On +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_echo.xml b/trunk/docs/manual/mod/mod_echo.xml new file mode 100644 index 0000000000..84c86cff11 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.xml @@ -0,0 +1,60 @@ + + + + + + + + + +mod_echo +A simple echo server to illustrate protocol +modules +Experimental +mod_echo.c +echo_module +Available in Apache 2.0 and later + + +

    This module provides an example protocol module to illustrate the + concept. It provides a simple echo server. Telnet to it and type + stuff, and it will echo it.

    +
    + + + +ProtocolEcho +Turn the echo server on or off +ProtocolEcho On|Off +server config +virtual host +ProtocolEcho is only available in 2.0 and +later. + + +

    The ProtocolEcho directive enables or + disables the echo server.

    + + Example + ProtocolEcho On + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_echo.xml.ja b/trunk/docs/manual/mod/mod_echo.xml.ja new file mode 100644 index 0000000000..fb4859960e --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.xml.ja @@ -0,0 +1,59 @@ + + + + + + + + + +mod_echo +$B%W%m%H%3%k%b%8%e!<%k$N35MW$r<($9$?$a$NC1=c$J%(%3!<%5!<%P(B + +Experimental +mod_echo.c +echo_module +Apache 2.0 $B0J9_(B + + +

    $BK\%b%8%e!<%k$O%3%s%;%W%H$rEA$($k$?$a$N%W%m%H%3%k%b%8%e!<%k$N(B + $B +

    + + + +ProtocolEcho +$B%(%3!<%5!<%P$NM-8zL58z$r@_Dj$7$^$9!#(B +ProtocolEcho On|Off +server config +virtual host +Apache 2.0 $B0J9_(B + + +

    ProtocolEcho $B%G%#%l%/%F%#%V$G(B + $B%(%3!<%5!<%P$NM-8zL58z$r@_Dj$7$^$9!#(B

    + + $BNc(B + ProtocolEcho On + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_echo.xml.ko b/trunk/docs/manual/mod/mod_echo.xml.ko new file mode 100644 index 0000000000..9d43bfe250 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.xml.ko @@ -0,0 +1,58 @@ + + + + + + + + + +mod_echo +ÇÁ·ÎÅäÄÝ ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇÑ °£´ÜÇÑ echo ¼­¹ö +Experimental +mod_echo.c +echo_module +Apache 2.0 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ÇÁ·ÎÅäÄÝ ¸ðµâÀÇ °³³äÀ» ¼³¸íÇϱâÀ§ÇÑ ¿¹Á¦ÀÌ´Ù. + ÀÌ ¸ðµâÀº °£´ÜÇÑ echo ¼­¹ö¸¦ ±¸ÇöÇÑ´Ù. ÀÌ ¼­¹ö·Î telnetÇÏ¿© + ¹«¾ð°¡¸¦ ÀÔ·ÂÇϸé, ¼­¹ö´Â ÀÔ·ÂÇÑ ³»¿ëÀÌ ±×´ë·Î ¹ÝȯÇÑ´Ù.

    +
    + + + +ProtocolEcho +echo ¼­¹ö¸¦ Å°°í ²ö´Ù +ProtocolEcho On|Off +server config +virtual host +ProtocolEcho´Â 2.0 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. + + +

    ProtocolEcho Áö½Ã¾î´Â echo ¼­¹ö¸¦ + Å°°í ²ö´Ù.

    + + ¿¹Á¦ + ProtocolEcho On + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_echo.xml.meta b/trunk/docs/manual/mod/mod_echo.xml.meta new file mode 100644 index 0000000000..88f36723c9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_echo.xml.meta @@ -0,0 +1,13 @@ + + + + mod_echo + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_env.html b/trunk/docs/manual/mod/mod_env.html new file mode 100644 index 0000000000..00d518a79e --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.html @@ -0,0 +1,11 @@ +URI: mod_env.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_env.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_env.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_env.html.en b/trunk/docs/manual/mod/mod_env.html.en new file mode 100644 index 0000000000..afbe339046 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.html.en @@ -0,0 +1,117 @@ + + + +mod_env - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_env

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Modifies the environment which is passed to CGI scripts and +SSI pages
    Status:Base
    Module Identifier:env_module
    Source File:mod_env.c
    +

    Summary

    + +

    This module allows for control of the environment that will + be provided to CGI scripts and SSI pages. Environment variables + may be passed from the shell which invoked the httpd + process. Alternatively, environment variables may be set or unset within + the configuration process.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    PassEnv Directive

    + + + + + + + +
    Description:Passes environment variables from the shell
    Syntax:PassEnv env-variable [env-variable] +...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_env
    +

    Specifies one or more environment variables to pass to CGI + scripts and SSI pages from the environment of the shell which + invoked the httpd process.

    + +

    Example

    + PassEnv LD_LIBRARY_PATH +

    + +
    +
    top
    +

    SetEnv Directive

    + + + + + + + +
    Description:Sets environment variables
    Syntax:SetEnv env-variable value
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_env
    +

    Sets an environment variable, which is then passed on to CGI + scripts and SSI pages.

    + +

    Example

    + SetEnv SPECIAL_PATH /foo/bin +

    + +
    +
    top
    +

    UnsetEnv Directive

    + + + + + + + +
    Description:Removes variables from the environment
    Syntax:UnsetEnv env-variable [env-variable] +...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_env
    +

    Removes one or more environment variables from those passed + on to CGI scripts and SSI pages.

    + +

    Example

    + UnsetEnv LD_LIBRARY_PATH +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_env.html.ja.euc-jp b/trunk/docs/manual/mod/mod_env.html.ja.euc-jp new file mode 100644 index 0000000000..d6e8925f11 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.html.ja.euc-jp @@ -0,0 +1,117 @@ + + + +mod_env - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_env

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:CGI ¥¹¥¯¥ê¥×¥ÈµÚ¤Ó SSI +¥Ú¡¼¥¸¤ËÅϤµ¤ì¤ë´Ä¶­ÊÑ¿ô¤òÊѹ¹¤¹¤ëµ¡Ç½¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:env_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_env.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¤è¤ê CGI ¥¹¥¯¥ê¥×¥È¤È SSI + ¥Ú¡¼¥¸¤ËŬÍѤµ¤ì¤ë´Ä¶­ÊÑ¿ô¤òÀ©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ´Ä¶­ÊÑ¿ô¤Ï httpd ¥×¥í¥»¥¹¤òµ¯Æ°¤·¤¿¥·¥§¥ë¤«¤éÅϤµ¤ì¤Þ¤¹¡£¤Þ¤¿¡¢ + ÀßÄê¥Õ¥¡¥¤¥ë¤Ç´Ä¶­ÊÑ¿ô¤òÀßÄꤷ¤¿¤ê¡¢ºï½ü¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    PassEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥·¥§¥ë¤«¤é¤Î´Ä¶­ÊÑ¿ô¤òÅϤ¹
    ¹½Ê¸:PassEnv env-variable [env-variable] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_env
    + +

    httpd ¥×¥í¥»¥¹¤òµ¯Æ°¤·¤¿¥·¥§¥ë¤Î´Ä¶­¤«¤é CGI ¥¹¥¯¥ê¥×¥È¤È + SSI ¥Ú¡¼¥¸¤ËÅϤ¹´Ä¶­ÊÑ¿ô¤ò°ì¤Ä°Ê¾å»ØÄꤷ¤Þ¤¹¡£

    + +

    Îã

    + PassEnv LD_LIBRARY_PATH +

    + +
    +
    top
    +

    SetEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    ¹½Ê¸:SetEnv env-variable value
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_env
    +

    ´Ä¶­ÊÑ¿ô¤òÀßÄꤷ¡¢¤½¤ì¤ò CGI ¥¹¥¯¥ê¥×¥È¤È SSI + ¥Ú¡¼¥¸¤ËÅϤ¹¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    Îã

    + SetEnv SPECIAL_PATH /foo/bin +

    + +
    +
    top
    +

    UnsetEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:´Ä¶­¤«¤éÊÑ¿ô¤ò¼è¤ê½ü¤¯
    ¹½Ê¸:UnsetEnv env-variable [env-variable] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_env
    +

    CGI ¥¹¥¯¥ê¥×¥È¤È SSI + ¥Ú¡¼¥¸¤ËÅϤµ¤ì¤ë´Ä¶­ÊÑ¿ô¤«¤é»ØÄꤵ¤ì¤¿´Ä¶­ÊÑ¿ô¤ò¼è¤ê½ü¤­¤Þ¤¹¡£

    + +

    Îã

    + UnsetEnv LD_LIBRARY_PATH +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_env.html.ko.euc-kr b/trunk/docs/manual/mod/mod_env.html.ko.euc-kr new file mode 100644 index 0000000000..2cf2bc1ad5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.html.ko.euc-kr @@ -0,0 +1,114 @@ + + + +mod_env - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_env

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ +¼öÁ¤ÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:env_module
    ¼Ò½ºÆÄÀÏ:mod_env.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ + Á¶ÀýÇÑ´Ù. À¥¼­¹ö¸¦ ½ÃÀÛÇÑ ½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Ã ¼ö ÀÖ´Ù. + ¾Æ´Ï¸é ¼³Á¤°úÁ¤Áß¿¡ ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ°í Á¦°ÅÇÒ ¼ö ÀÖ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    PassEnv Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Â´Ù
    ¹®¹ý:PassEnv env-variable [env-variable] +...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_env
    +

    À¥¼­¹ö¸¦ ½ÇÇàÇÑ ½©ÀÇ Æ¯Á¤ ȯ°æº¯¼ö¸¦ CGI ½ºÅ©¸³Æ®³ª + SSI ÆäÀÌÁö·Î Àü´ÞÇÑ´Ù.

    + +

    ¿¹Á¦

    + PassEnv LD_LIBRARY_PATH +

    + +
    +
    top
    +

    SetEnv Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    ¹®¹ý:SetEnv env-variable value
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_env
    +

    CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    ¿¹Á¦

    + SetEnv SPECIAL_PATH /foo/bin +

    + +
    +
    top
    +

    UnsetEnv Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ȯ°æº¯¼ö¸¦ Á¦°ÅÇÑ´Ù
    ¹®¹ý:UnsetEnv env-variable [env-variable] +...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_env
    +

    CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ ȯ°æº¯¼ö¸¦ Àü´ÞÇÏÁö ¾Ê´Â´Ù.

    + +

    ¿¹Á¦

    + UnsetEnv LD_LIBRARY_PATH +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_env.xml b/trunk/docs/manual/mod/mod_env.xml new file mode 100644 index 0000000000..b940b0da43 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.xml @@ -0,0 +1,98 @@ + + + + + + + + + +mod_env +Modifies the environment which is passed to CGI scripts and +SSI pages +Base +mod_env.c +env_module + +

    This module allows for control of the environment that will + be provided to CGI scripts and SSI pages. Environment variables + may be passed from the shell which invoked the httpd + process. Alternatively, environment variables may be set or unset within + the configuration process.

    +
    +Environment Variables + + +PassEnv +Passes environment variables from the shell +PassEnv env-variable [env-variable] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    Specifies one or more environment variables to pass to CGI + scripts and SSI pages from the environment of the shell which + invoked the httpd process.

    + + Example + PassEnv LD_LIBRARY_PATH + +
    +
    + + +SetEnv +Sets environment variables +SetEnv env-variable value +server configvirtual host +directory.htaccess +FileInfo + + +

    Sets an environment variable, which is then passed on to CGI + scripts and SSI pages.

    + + Example + SetEnv SPECIAL_PATH /foo/bin + +
    +
    + + +UnsetEnv +Removes variables from the environment +UnsetEnv env-variable [env-variable] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    Removes one or more environment variables from those passed + on to CGI scripts and SSI pages.

    + + Example + UnsetEnv LD_LIBRARY_PATH + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_env.xml.ja b/trunk/docs/manual/mod/mod_env.xml.ja new file mode 100644 index 0000000000..0f492f0f3b --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.xml.ja @@ -0,0 +1,99 @@ + + + + + + + + + +mod_env +CGI $B%9%/%j%W%H5Z$S(B SSI +$B%Z!<%8$KEO$5$l$k4D6-JQ?t$rJQ99$9$k5!G=$rDs6!$9$k(B +Base +mod_env.c +env_module + +

    $B$3$N%b%8%e!<%k$K$h$j(B CGI $B%9%/%j%W%H$H(B SSI + $B%Z!<%8$KE,MQ$5$l$k4D6-JQ?t$r@)8f$9$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B + $B4D6-JQ?t$O(B httpd $B%W%m%;%9$r5/F0$7$?%7%'%k$+$iEO$5$l$^$9!#$^$?!"(B + $B@_Dj%U%!%$%k$G4D6-JQ?t$r@_Dj$7$?$j!":o=|$7$?$j$9$k$3$H$,$G$-$^$9!#(B +

    +
    +$B4D6-JQ?t(B + + +PassEnv +$B%7%'%k$+$i$N4D6-JQ?t$rEO$9(B +PassEnv env-variable [env-variable] +... + +server configvirtual host +directory.htaccess +FileInfo + + + +

    httpd $B%W%m%;%9$r5/F0$7$?%7%'%k$N4D6-$+$i(B CGI $B%9%/%j%W%H$H(B + SSI $B%Z!<%8$KEO$94D6-JQ?t$r0l$D0J>e;XDj$7$^$9!#(B

    + + $BNc(B + PassEnv LD_LIBRARY_PATH + +
    +
    + + +SetEnv +$B4D6-JQ?t$r@_Dj$9$k(B +SetEnv env-variable value +server configvirtual host +directory.htaccess +FileInfo + + +

    $B4D6-JQ?t$r@_Dj$7!"$=$l$r(B CGI $B%9%/%j%W%H$H(B SSI + $B%Z!<%8$KEO$9$h$&$K$7$^$9!#(B

    + + $BNc(B + SetEnv SPECIAL_PATH /foo/bin + +
    +
    + + +UnsetEnv +$B4D6-$+$iJQ?t$r +UnsetEnv env-variable [env-variable] +... + +server configvirtual host +directory.htaccess +FileInfo + + +

    CGI $B%9%/%j%W%H$H(B SSI + $B%Z!<%8$KEO$5$l$k4D6-JQ?t$+$i;XDj$5$l$?4D6-JQ?t$r + + $BNc(B + UnsetEnv LD_LIBRARY_PATH + + + + + diff --git a/trunk/docs/manual/mod/mod_env.xml.ko b/trunk/docs/manual/mod/mod_env.xml.ko new file mode 100644 index 0000000000..c0bcc631a6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.xml.ko @@ -0,0 +1,93 @@ + + + + + + + + + +mod_env +CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ +¼öÁ¤ÇÑ´Ù +Base +mod_env.c +env_module +

    +

    ÀÌ ¸ðµâÀº CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ + Á¶ÀýÇÑ´Ù. À¥¼­¹ö¸¦ ½ÃÀÛÇÑ ½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Ã ¼ö ÀÖ´Ù. + ¾Æ´Ï¸é ¼³Á¤°úÁ¤Áß¿¡ ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ°í Á¦°ÅÇÒ ¼ö ÀÖ´Ù.

    +
    +ȯ°æº¯¼ö + + +PassEnv +½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Â´Ù +PassEnv env-variable [env-variable] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    À¥¼­¹ö¸¦ ½ÇÇàÇÑ ½©ÀÇ Æ¯Á¤ ȯ°æº¯¼ö¸¦ CGI ½ºÅ©¸³Æ®³ª + SSI ÆäÀÌÁö·Î Àü´ÞÇÑ´Ù.

    + + ¿¹Á¦ + PassEnv LD_LIBRARY_PATH + +
    +
    + + +SetEnv +ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù +SetEnv env-variable value +server configvirtual host +directory.htaccess +FileInfo + + +

    CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ Àü´ÞÇÒ È¯°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.

    + + ¿¹Á¦ + SetEnv SPECIAL_PATH /foo/bin + +
    +
    + + +UnsetEnv +ȯ°æº¯¼ö¸¦ Á¦°ÅÇÑ´Ù +UnsetEnv env-variable [env-variable] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    CGI ½ºÅ©¸³Æ®³ª SSI ÆäÀÌÁö¿¡ ȯ°æº¯¼ö¸¦ Àü´ÞÇÏÁö ¾Ê´Â´Ù.

    + + ¿¹Á¦ + UnsetEnv LD_LIBRARY_PATH + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_env.xml.meta b/trunk/docs/manual/mod/mod_env.xml.meta new file mode 100644 index 0000000000..0998725cf8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_env.xml.meta @@ -0,0 +1,13 @@ + + + + mod_env + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_example.html b/trunk/docs/manual/mod/mod_example.html new file mode 100644 index 0000000000..41b1d56e32 --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.html @@ -0,0 +1,7 @@ +URI: mod_example.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_example.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_example.html.en b/trunk/docs/manual/mod/mod_example.html.en new file mode 100644 index 0000000000..e8eadced76 --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.html.en @@ -0,0 +1,156 @@ + + + +mod_example - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_example

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:Illustrates the Apache module API
    Status:Experimental
    Module Identifier:example_module
    Source File:mod_example.c
    +

    Summary

    + +

    Some files in the modules/experimental directory + under the Apache distribution directory tree are provided as an + example to those that wish to write modules that use the Apache + API.

    + +

    The main file is mod_example.c, which + illustrates all the different callback mechanisms and call + syntaxes. By no means does an add-on module need to include + routines for all of the callbacks - quite the contrary!

    + +

    The example module is an actual working module. If you link + it into your server, enable the "example-handler" handler for a + location, and then browse to that location, you will see a + display of some of the tracing the example module did as the + various callbacks were made.

    +
    + +
    top
    +
    +

    Compiling the example module

    + +

    To include the example module in your server, follow the + steps below:

    + +
      +
    1. + Run configure with --enable-example + option.
    2. + +
    3. Make the server (run "make").
    4. +
    + +

    To add another module of your own:

    + +
      +
    1. cp modules/experimental/mod_example.c + modules/new_module/mod_myexample.c
    2. + +
    3. Modify the file.
    4. + +
    5. Create modules/new_module/config.m4. +
        +
      1. Add APACHE_MODPATH_INIT(new_module).
      2. +
      3. Copy APACHE_MODULE line with "example" from + modules/experimental/config.m4.
      4. +
      5. Replace the first argument "example" with myexample.
      6. +
      7. Replace the second argument with brief description of your module. + It will be used in configure --help.
      8. +
      9. If your module needs additional C compiler flags, linker flags or + libraries, add them to CFLAGS, LDFLAGS and LIBS accordingly. + See other config.m4 files in modules directory for + examples.
      10. +
      11. Add APACHE_MODPATH_FINISH.
      12. +
      +
    6. + +
    7. Create module/new_module/Makefile.in. + If your module doesn't need special build instructions, + all you need to have in that file is + include $(top_srcdir)/build/special.mk.
    8. + +
    9. Run ./buildconf from the top-level directory.
    10. + +
    11. Build the server with --enable-myexample
    12. + +
    +
    top
    +
    +

    Using the mod_example Module

    + +

    To activate the example module, include a block similar to + the following in your httpd.conf file:

    +

    + <Location /example-info>
    + SetHandler example-handler
    + </Location> +

    + +

    As an alternative, you can put the following into a .htaccess file + and then request the file "test.example" from that location:

    +

    + AddHandler example-handler .example +

    + +

    After reloading/restarting your server, you should be able + to browse to this location and see the brief display mentioned + earlier.

    +
    +
    top
    +

    Example Directive

    + + + + + + +
    Description:Demonstration directive to illustrate the Apache module +API
    Syntax:Example
    Context:server config, virtual host, directory, .htaccess
    Status:Experimental
    Module:mod_example
    +

    The Example directive just sets a demonstration + flag which the example module's content handler displays. It + takes no arguments. If you browse to an URL to which the + example content-handler applies, you will get a display of the + routines within the module and how and in what order they were + called to service the document request. The effect of this + directive one can observe under the point "Example + directive declared here: YES/NO".

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_example.html.ko.euc-kr b/trunk/docs/manual/mod/mod_example.html.ko.euc-kr new file mode 100644 index 0000000000..4f5aecc417 --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.html.ko.euc-kr @@ -0,0 +1,155 @@ + + + +mod_example - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_example

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇÑ´Ù
    »óÅÂ:Experimental
    ¸ðµâ¸í:example_module
    ¼Ò½ºÆÄÀÏ:mod_example.c
    +

    ¿ä¾à

    + +

    ¾ÆÆÄÄ¡ ¹èÆ÷º» modules/experimental µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϵéÀº ¾ÆÆÄÄ¡ API¸¦ »ç¿ëÇÏ¿© ¸ðµâÀ» ÀÛ¼ºÇÏ·Á´Â »ç¶÷µéÀ» + µ½±âÀ§ÇÑ ¿¹Á¦´Ù.

    + +

    mod_example.c´Â ¸ðµç Äݹé(callback) ±¸Á¶¿Í + È£Ãâ ¹®¹ýÀ» ¼³¸íÇÏ´Â ÆÄÀÏÀÌ´Ù. ´ç½ÅÀº ¸ðµâ¿¡ ÀÌ ¸ðµç ÄݹéÀ» + ±¸ÇöÇÒ ÇÊ¿ä°¡ ¾ø´Ù. »ç½Ç Á¤¹Ý´ë´Ù!

    + +

    example ¸ðµâÀº ½ÇÁ¦·Î µ¿ÀÛÇÏ´Â ¸ðµâÀÌ´Ù. ÀÌ ¸ðµâÀ» ¼­¹ö¿¡ + ¿¬°áÇÏ°í ƯÁ¤ À§Ä¡¿¡ "example-handler" Çڵ鷯¸¦ ÇÒ´çÇÏ¿© + ±×°÷À» ºê¶ó¿ì¡Çϸé example ¸ðµâÀÇ ¿©·¯ ÄݹéÀ» È®ÀÎÇÒ ¼ö + ÀÖ´Ù.

    +
    + +
    top
    +
    +

    example ¸ðµâ ÄÄÆÄÀÏÇϱâ

    + +

    ¼­¹ö¿¡ example ¸ðµâÀ» Æ÷ÇÔÇÏ·Á¸é ´ÙÀ½ °úÁ¤À» °ÅÄ£´Ù:

    + +
      +
    1. + --enable-example ¿É¼Ç°ú ÇÔ²² + configure¸¦ ½ÇÇàÇÑ´Ù.
    2. + +
    3. ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑ´Ù ("make"¸¦ ½ÇÇàÇÑ´Ù).
    4. +
    + +

    ÀÚ½ÅÀÌ ¸¸µç ¸ðµâÀ» Ãß°¡ÇÏ·Á¸é:

    + +
      +
    1. cp modules/experimental/mod_example.c + modules/new_module/mod_myexample.c
    2. + +
    3. ÆÄÀÏÀ» ¼öÁ¤ÇÑ´Ù.
    4. + +
    5. modules/new_module/config.m4 ÆÄÀÏÀ» ¸¸µç´Ù. +
        +
      1. APACHE_MODPATH_INIT(new_module)À» + Ãß°¡ÇÑ´Ù.
      2. +
      3. modules/experimental/config.m4 ÆÄÀÏ¿¡¼­ + "example"ÀÌ ÀÖ´Â APACHE_MODULE ÁÙÀ» º¹»çÇؿ´Ù.
      4. +
      5. ù¹ø° ¾Æ±Ô¸ÕÆ® "example"À» myexample·Î + º¯°æÇÑ´Ù.
      6. +
      7. µÎ¹ø° ¾Æ±Ô¸ÕÆ® ÀÚ¸®¿¡ ÀÚ½ÅÀÌ ¸¸µç ¸ðµâ¿¡ ´ëÇÑ + °£´ÜÇÑ ¼³¸íÀ» Àû´Â´Ù. configure --help¸¦ + ½ÇÇàÇÏ¸é ¿©±â¿¡ ±â·ÏÇÑ ¼³¸íÀ» º¸¿©ÁØ´Ù.
      8. +
      9. ¸ðµâÀ» ÄÄÆÄÀÏÇÒ¶§ Ưº°ÇÑ C ÄÄÆÄÀÏ·¯ ¿É¼Ç, ¸µÄ¿ + ¿É¼Ç, ¶óÀ̺귯¸®°¡ ÇÊ¿äÇÏ¸é °¢°¢ CFLAGS, LDFLAGS, + LIBS¿¡ Ãß°¡ÇÑ´Ù. modules µð·ºÅ丮¿¡ ÀÖ´Â ´Ù¸¥ + config.m4 ÆÄÀϵéÀ» Âü°íÇ϶ó.
      10. +
      11. APACHE_MODPATH_FINISH¸¦ Ãß°¡ÇÑ´Ù.
      12. +
      +
    6. + +
    7. module/new_module/Makefile.in ÆÄÀÏÀ» + ¸¸µç´Ù. ¸ðµâÀ» ÄÄÆÄÀÏÇϴµ¥ Ưº°ÇÑ ¸í·É¾î°¡ ÇÊ¿ä¾ø´Ù¸é, + ÆÄÀÏ¿¡ include $(top_srcdir)/build/special.mk¸¸ + À־ µÈ´Ù.
    8. + +
    9. ÃÖ»óÀ§ µð·ºÅ丮¿¡¼­ ./buildconf ¸¦ ½ÇÇàÇÑ´Ù.
    10. + +
    11. --enable-myexample ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑ´Ù
    12. + +
    +
    top
    +
    +

    mod_example ¸ðµâ »ç¿ëÇϱâ

    + +

    example ¸ðµâÀ» »ç¿ëÇÏ·Á¸é httpd.conf ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°Àº ¼³Á¤À» Ãß°¡Ç϶ó:

    +

    + <Location /example-info>
    + SetHandler example-handler
    + </Location> +

    + +

    ¾Æ´Ï¸é .htaccess + ÆÄÀÏ¿¡ ´ÙÀ½°ú °°Àº ³»¿ëÀ» Ãß°¡ÇÏ°í, ±× À§Ä¡¿¡¼­ "test.example" + °°Àº ÆÄÀÏÀ» ¿äûÇ϶ó:

    +

    + AddHandler example-handler .example +

    + +

    ¼­¹ö¸¦ Àç½ÃÀÛÇÑ ÈÄ ÀÌ À§Ä¡¸¦ ºê¶ó¿ì¡ÇÏ¸é ¾Õ¿¡¼­ ¸»ÇÑ + ³»¿ëÀ» º¸°ÔµÉ °ÍÀÌ´Ù.

    +
    +
    top
    +

    Example Áö½Ã¾î

    + + + + + + +
    ¼³¸í:¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇϱâÀ§ÇÑ ¿¹Á¦ Áö½Ã¾î
    ¹®¹ý:Example
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    »óÅÂ:Experimental
    ¸ðµâ:mod_example
    +

    Example Áö½Ã¾î´Â example ¸ðµâÀÇ + ³»¿ëÇڵ鷯°¡ °£´ÜÇÑ ¹®±¸¸¦ º¸ÀÏÁö ¿©ºÎ¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¾Ê´Â´Ù. example ³»¿ëÇڵ鷯¸¦ Àû¿ëÇÑ URL¿¡ + Á¢¼ÓÇÏ¸é ¹®¼­ ¿äûÀ» ¼­ºñ½ºÇϱâÀ§ÇØ ¸ðµâ¾È¿¡ ÇÔ¼öµéÀÌ ¾î¶»°Ô + ±×¸®°í ¾î¶² ¼ø¼­·Î ºÒ¸®´ÂÁö ¾Ë ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾îÀÇ È¿°ú´Â + "Example directive declared here: YES/NO"·Î + È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_example.xml b/trunk/docs/manual/mod/mod_example.xml new file mode 100644 index 0000000000..59db18296e --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.xml @@ -0,0 +1,141 @@ + + + + + + + + + +mod_example +Illustrates the Apache module API +Experimental +mod_example.c +example_module + + +

    Some files in the modules/experimental directory + under the Apache distribution directory tree are provided as an + example to those that wish to write modules that use the Apache + API.

    + +

    The main file is mod_example.c, which + illustrates all the different callback mechanisms and call + syntaxes. By no means does an add-on module need to include + routines for all of the callbacks - quite the contrary!

    + +

    The example module is an actual working module. If you link + it into your server, enable the "example-handler" handler for a + location, and then browse to that location, you will see a + display of some of the tracing the example module did as the + various callbacks were made.

    +
    + +
    Compiling the example module + +

    To include the example module in your server, follow the + steps below:

    + +
      +
    1. + Run configure with --enable-example + option.
    2. + +
    3. Make the server (run "make").
    4. +
    + +

    To add another module of your own:

    + +
      +
    1. cp modules/experimental/mod_example.c + modules/new_module/mod_myexample.c
    2. + +
    3. Modify the file.
    4. + +
    5. Create modules/new_module/config.m4. +
        +
      1. Add APACHE_MODPATH_INIT(new_module).
      2. +
      3. Copy APACHE_MODULE line with "example" from + modules/experimental/config.m4.
      4. +
      5. Replace the first argument "example" with myexample.
      6. +
      7. Replace the second argument with brief description of your module. + It will be used in configure --help.
      8. +
      9. If your module needs additional C compiler flags, linker flags or + libraries, add them to CFLAGS, LDFLAGS and LIBS accordingly. + See other config.m4 files in modules directory for + examples.
      10. +
      11. Add APACHE_MODPATH_FINISH.
      12. +
      +
    6. + +
    7. Create module/new_module/Makefile.in. + If your module doesn't need special build instructions, + all you need to have in that file is + include $(top_srcdir)/build/special.mk.
    8. + +
    9. Run ./buildconf from the top-level directory.
    10. + +
    11. Build the server with --enable-myexample
    12. + +
    +
    + +
    Using the <code>mod_example</code> Module + +

    To activate the example module, include a block similar to + the following in your httpd.conf file:

    + + <Location /example-info>
    + SetHandler example-handler
    + </Location> +
    + +

    As an alternative, you can put the following into a .htaccess file + and then request the file "test.example" from that location:

    + + AddHandler example-handler .example + + +

    After reloading/restarting your server, you should be able + to browse to this location and see the brief display mentioned + earlier.

    +
    + + +Example +Demonstration directive to illustrate the Apache module +API +Example +server config +virtual hostdirectory +.htaccess + + +

    The Example directive just sets a demonstration + flag which the example module's content handler displays. It + takes no arguments. If you browse to an URL to which the + example content-handler applies, you will get a display of the + routines within the module and how and in what order they were + called to service the document request. The effect of this + directive one can observe under the point "Example + directive declared here: YES/NO".

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_example.xml.ko b/trunk/docs/manual/mod/mod_example.xml.ko new file mode 100644 index 0000000000..07817574bb --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.xml.ko @@ -0,0 +1,138 @@ + + + + + + + + + +mod_example +¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇÑ´Ù +Experimental +mod_example.c +example_module + + +

    ¾ÆÆÄÄ¡ ¹èÆ÷º» modules/experimental µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϵéÀº ¾ÆÆÄÄ¡ API¸¦ »ç¿ëÇÏ¿© ¸ðµâÀ» ÀÛ¼ºÇÏ·Á´Â »ç¶÷µéÀ» + µ½±âÀ§ÇÑ ¿¹Á¦´Ù.

    + +

    mod_example.c´Â ¸ðµç Äݹé(callback) ±¸Á¶¿Í + È£Ãâ ¹®¹ýÀ» ¼³¸íÇÏ´Â ÆÄÀÏÀÌ´Ù. ´ç½ÅÀº ¸ðµâ¿¡ ÀÌ ¸ðµç ÄݹéÀ» + ±¸ÇöÇÒ ÇÊ¿ä°¡ ¾ø´Ù. »ç½Ç Á¤¹Ý´ë´Ù!

    + +

    example ¸ðµâÀº ½ÇÁ¦·Î µ¿ÀÛÇÏ´Â ¸ðµâÀÌ´Ù. ÀÌ ¸ðµâÀ» ¼­¹ö¿¡ + ¿¬°áÇÏ°í ƯÁ¤ À§Ä¡¿¡ "example-handler" Çڵ鷯¸¦ ÇÒ´çÇÏ¿© + ±×°÷À» ºê¶ó¿ì¡Çϸé example ¸ðµâÀÇ ¿©·¯ ÄݹéÀ» È®ÀÎÇÒ ¼ö + ÀÖ´Ù.

    +
    + +
    example ¸ðµâ ÄÄÆÄÀÏÇϱâ + +

    ¼­¹ö¿¡ example ¸ðµâÀ» Æ÷ÇÔÇÏ·Á¸é ´ÙÀ½ °úÁ¤À» °ÅÄ£´Ù:

    + +
      +
    1. + --enable-example ¿É¼Ç°ú ÇÔ²² + configure¸¦ ½ÇÇàÇÑ´Ù.
    2. + +
    3. ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑ´Ù ("make"¸¦ ½ÇÇàÇÑ´Ù).
    4. +
    + +

    ÀÚ½ÅÀÌ ¸¸µç ¸ðµâÀ» Ãß°¡ÇÏ·Á¸é:

    + +
      +
    1. cp modules/experimental/mod_example.c + modules/new_module/mod_myexample.c
    2. + +
    3. ÆÄÀÏÀ» ¼öÁ¤ÇÑ´Ù.
    4. + +
    5. modules/new_module/config.m4 ÆÄÀÏÀ» ¸¸µç´Ù. +
        +
      1. APACHE_MODPATH_INIT(new_module)À» + Ãß°¡ÇÑ´Ù.
      2. +
      3. modules/experimental/config.m4 ÆÄÀÏ¿¡¼­ + "example"ÀÌ ÀÖ´Â APACHE_MODULE ÁÙÀ» º¹»çÇؿ´Ù.
      4. +
      5. ù¹ø° ¾Æ±Ô¸ÕÆ® "example"À» myexample·Î + º¯°æÇÑ´Ù.
      6. +
      7. µÎ¹ø° ¾Æ±Ô¸ÕÆ® ÀÚ¸®¿¡ ÀÚ½ÅÀÌ ¸¸µç ¸ðµâ¿¡ ´ëÇÑ + °£´ÜÇÑ ¼³¸íÀ» Àû´Â´Ù. configure --help¸¦ + ½ÇÇàÇÏ¸é ¿©±â¿¡ ±â·ÏÇÑ ¼³¸íÀ» º¸¿©ÁØ´Ù.
      8. +
      9. ¸ðµâÀ» ÄÄÆÄÀÏÇÒ¶§ Ưº°ÇÑ C ÄÄÆÄÀÏ·¯ ¿É¼Ç, ¸µÄ¿ + ¿É¼Ç, ¶óÀ̺귯¸®°¡ ÇÊ¿äÇÏ¸é °¢°¢ CFLAGS, LDFLAGS, + LIBS¿¡ Ãß°¡ÇÑ´Ù. modules µð·ºÅ丮¿¡ ÀÖ´Â ´Ù¸¥ + config.m4 ÆÄÀϵéÀ» Âü°íÇ϶ó.
      10. +
      11. APACHE_MODPATH_FINISH¸¦ Ãß°¡ÇÑ´Ù.
      12. +
      +
    6. + +
    7. module/new_module/Makefile.in ÆÄÀÏÀ» + ¸¸µç´Ù. ¸ðµâÀ» ÄÄÆÄÀÏÇϴµ¥ Ưº°ÇÑ ¸í·É¾î°¡ ÇÊ¿ä¾ø´Ù¸é, + ÆÄÀÏ¿¡ include $(top_srcdir)/build/special.mk¸¸ + À־ µÈ´Ù.
    8. + +
    9. ÃÖ»óÀ§ µð·ºÅ丮¿¡¼­ ./buildconf ¸¦ ½ÇÇàÇÑ´Ù.
    10. + +
    11. --enable-myexample ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑ´Ù
    12. + +
    +
    + +
    <code>mod_example</code> ¸ðµâ »ç¿ëÇϱâ + +

    example ¸ðµâÀ» »ç¿ëÇÏ·Á¸é httpd.conf ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°Àº ¼³Á¤À» Ãß°¡Ç϶ó:

    + + <Location /example-info>
    + SetHandler example-handler
    + </Location> +
    + +

    ¾Æ´Ï¸é .htaccess + ÆÄÀÏ¿¡ ´ÙÀ½°ú °°Àº ³»¿ëÀ» Ãß°¡ÇÏ°í, ±× À§Ä¡¿¡¼­ "test.example" + °°Àº ÆÄÀÏÀ» ¿äûÇ϶ó:

    + + AddHandler example-handler .example + + +

    ¼­¹ö¸¦ Àç½ÃÀÛÇÑ ÈÄ ÀÌ À§Ä¡¸¦ ºê¶ó¿ì¡ÇÏ¸é ¾Õ¿¡¼­ ¸»ÇÑ + ³»¿ëÀ» º¸°ÔµÉ °ÍÀÌ´Ù.

    +
    + + +Example +¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇϱâÀ§ÇÑ ¿¹Á¦ Áö½Ã¾î +Example +server config +virtual hostdirectory +.htaccess + + +

    Example Áö½Ã¾î´Â example ¸ðµâÀÇ + ³»¿ëÇڵ鷯°¡ °£´ÜÇÑ ¹®±¸¸¦ º¸ÀÏÁö ¿©ºÎ¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â + ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¾Ê´Â´Ù. example ³»¿ëÇڵ鷯¸¦ Àû¿ëÇÑ URL¿¡ + Á¢¼ÓÇÏ¸é ¹®¼­ ¿äûÀ» ¼­ºñ½ºÇϱâÀ§ÇØ ¸ðµâ¾È¿¡ ÇÔ¼öµéÀÌ ¾î¶»°Ô + ±×¸®°í ¾î¶² ¼ø¼­·Î ºÒ¸®´ÂÁö ¾Ë ¼ö ÀÖ´Ù. ÀÌ Áö½Ã¾îÀÇ È¿°ú´Â + "Example directive declared here: YES/NO"·Î + È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_example.xml.meta b/trunk/docs/manual/mod/mod_example.xml.meta new file mode 100644 index 0000000000..8581ac2b68 --- /dev/null +++ b/trunk/docs/manual/mod/mod_example.xml.meta @@ -0,0 +1,12 @@ + + + + mod_example + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_expires.html b/trunk/docs/manual/mod/mod_expires.html new file mode 100644 index 0000000000..c3692c250c --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.html @@ -0,0 +1,11 @@ +URI: mod_expires.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_expires.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_expires.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_expires.html.en b/trunk/docs/manual/mod/mod_expires.html.en new file mode 100644 index 0000000000..5c4d71ad16 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.html.en @@ -0,0 +1,247 @@ + + + +mod_expires - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_expires

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Generation of Expires and +Cache-Control HTTP headers according to user-specified +criteria
    Status:Extension
    Module Identifier:expires_module
    Source File:mod_expires.c
    +

    Summary

    + +

    This module controls the setting of the Expires + HTTP header and the max-age directive of the + Cache-Control HTTP header in server responses. The + expiration date can set to be relative to either the time the + source file was last modified, or to the time of the client + access.

    + +

    These HTTP headers are an instruction to the client about the + document's validity and persistence. If cached, the document may + be fetched from the cache rather than from the source until this + time has passed. After that, the cache copy is considered + "expired" and invalid, and a new copy must be obtained from the + source.

    + +

    To modify Cache-Control directives other than + max-age (see RFC + 2616 section 14.9), you can use the Header directive.

    + +
    + +
    top
    +
    +

    Alternate Interval Syntax

    +

    The ExpiresDefault and + ExpiresByType directives + can also be defined in a more readable syntax of the form:

    + +

    + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +

    + +

    where <base> is one of:

    + +
      +
    • access
    • + +
    • now (equivalent to + 'access')
    • + +
    • modification
    • +
    + +

    The plus keyword is optional. <num> + should be an integer value [acceptable to atoi()], + and <type> is one of:

    + +
      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    For example, any of the following directives can be used to + make documents expire 1 month after being accessed, by + default:

    + +

    + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +

    + +

    The expiry time can be fine-tuned by adding several + '<num> <type>' clauses:

    + +

    + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +

    + +

    Note that if you use a modification date based setting, the + Expires header will not be added to content + that does not come from a file on disk. This is due to the fact + that there is no modification time for such content.

    +
    +
    top
    +

    ExpiresActive Directive

    + + + + + + + +
    Description:Enables generation of Expires +headers
    Syntax:ExpiresActive On|Off
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_expires
    +

    This directive enables or disables the generation of the + Expires and Cache-Control headers for + the document realm in question. (That is, if found in an + .htaccess file, for instance, it applies only to + documents generated from that directory.) If set to + Off, the headers will not be generated for any + document in the realm (unless overridden at a lower level, such as + an .htaccess file overriding a server config + file). If set to On, the headers will be added to + served documents according to the criteria defined by the + ExpiresByType and + ExpiresDefault + directives (q.v.).

    + +

    Note that this directive does not guarantee that an + Expires or Cache-Control header will be + generated. If the criteria aren't met, no header will be sent, and + the effect will be as though this directive wasn't even + specified.

    + +
    +
    top
    +

    ExpiresByType Directive

    + + + + + + + +
    Description:Value of the Expires header configured +by MIME type
    Syntax:ExpiresByType MIME-type +<code>seconds
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_expires
    +

    This directive defines the value of the Expires + header and the max-age directive of the + Cache-Control header generated for documents of the + specified type (e.g., text/html). The second + argument sets the number of seconds that will be added to a base + time to construct the expiration date. The Cache-Control: + max-age is calculated by subtracting the request time from + the expiration date and expressing the result in seconds.

    + +

    The base time is either the last modification time of the + file, or the time of the client's access to the document. Which + should be used is specified by the + <code> field; M + means that the file's last modification time should be used as + the base time, and A means the client's access + time should be used.

    + +

    The difference in effect is subtle. If M is used, + all current copies of the document in all caches will expire at + the same time, which can be good for something like a weekly + notice that's always found at the same URL. If A is + used, the date of expiration is different for each client; this + can be good for image files that don't change very often, + particularly for a set of related documents that all refer to + the same images (i.e., the images will be accessed + repeatedly within a relatively short timespan).

    + +

    Example:

    + # enable expirations
    + ExpiresActive On
    + # expire GIF images after a month in the client's cache
    + ExpiresByType image/gif A2592000
    + # HTML documents are good for a week from the
    + # time they were changed
    + ExpiresByType text/html M604800 +

    + +

    Note that this directive only has effect if + ExpiresActive On has been specified. It overrides, + for the specified MIME type only, any expiration date + set by the ExpiresDefault + directive.

    + +

    You can also specify the expiration time calculation using + an alternate syntax, described earlier in + this document.

    + +
    +
    top
    +

    ExpiresDefault Directive

    + + + + + + + +
    Description:Default algorithm for calculating expiration time
    Syntax:ExpiresDefault <code>seconds
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Extension
    Module:mod_expires
    +

    This directive sets the default algorithm for calculating the + expiration time for all documents in the affected realm. It can be + overridden on a type-by-type basis by the ExpiresByType directive. See the + description of that directive for details about the syntax of the + argument, and the alternate syntax + description as well.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_expires.html.ja.euc-jp b/trunk/docs/manual/mod/mod_expires.html.ja.euc-jp new file mode 100644 index 0000000000..0e6d264ae2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.html.ja.euc-jp @@ -0,0 +1,233 @@ + + + +mod_expires - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_expires

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥æ¡¼¥¶¤Î»ØÄꤷ¤¿´ð½à¤Ë´ð¤Å¤¤¤¿ Expires ¤È +Cache-Control HTTP ¥Ø¥Ã¥À¤ÎÀ¸À®
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:expires_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_expires.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥µ¡¼¥Ð±þÅú¤Î Expires HTTP ¥Ø¥Ã¥À + ¤È Cache-Control ¥Ø¥Ã¥À¤Î max-age ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÀßÄê¤òÀ©¸æ¤·¤Þ¤¹¡£¸µ¤Î¥Õ¥¡¥¤¥ë¤¬ºîÀ®¤µ¤ì¤¿»þ¹ï¤Þ¤¿¤Ï + ¥¯¥é¥¤¥¢¥ó¥È¤Î¥¢¥¯¥»¥¹»þ¹ï¤Î¤É¤Á¤é¤«¤Ë´ð¤Å¤¤¤Æ´ü¸ÂÀÚ¤ìÆü¤ò + ÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤ì¤é¤Î¥Ø¥Ã¥À¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ëʸ½ñ¤Î + Í­¸úÀ­¤È·Ñ³À­¤ò»Ø¼¨¤·¤Þ¤¹¡£Ê¸½ñ¤¬¥­¥ã¥Ã¥·¥å¤µ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢ + »ØÄê»þ¹ï¤Ë㤹¤ë¤Þ¤Ç¤Ï¡¢¸µ¤Î¾ì½ê¤«¤é¼èÆÀ¤¹¤ëÂå¤ï¤ê¤Ë + ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤½¤Î¸å¤Ï¡¢ + ¥­¥ã¥Ã¥·¥å¤Ë¤¢¤ë¥³¥Ô¡¼¤Ï´ü¸ÂÀÚ¤ì (expired) ¤Ç̵¸ú¤Ç¤¢¤ë¤È¤µ¤ì¡¢ + ¸µ¤Î¾ì½ê¤«¤é¿·¤·¤¤¤â¤Î¤ò¼èÆÀ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    max-age °Ê³° (RFC + 2616 section 14.9 »²¾È) ¤Î Cache-Control ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + Áàºî¤¹¤ë¤Ë¤Ï Header ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    ÂåÂØ´ü´Ö»ØÄ깽ʸ

    + +

    ExpiresDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + ExpiresByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + °Ê²¼¤Î¤è¤êÆɤ߰פ¤¹½Ê¸¤ò»È¤Ã¤ÆÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +

    + +

    <base> ¤Ï°Ê²¼¤Î¤É¤ì¤«¤Ç¤¹:

    + +
      +
    • access
    • + +
    • now ('access' ¤ÈÅù²Á)
    • + +
    • modification
    • +
    + +

    plus ¥­¡¼¥ï¡¼¥É¤Ï¾Êά²Äǽ¤Ç¤¹¡£<num> + ¤Ï (atoi() ¤¬¼õ¤±ÉÕ¤±¤ë) À°¿ôÃÍ¡¢ + <type> ¤Ï°Ê²¼¤Î¤É¤ì¤«¤Ç¤¹:

    + +
      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    Î㤨¤Ð¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤É¤ì¤â¥Ç¥Õ¥©¥ë¥È¤Çʸ½ñ¤¬¥¢¥¯¥»¥¹¤Î 1 ¥ö·î¸å¤Ë + ´ü¸Â¤¬ÀÚ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë»È¤¨¤Þ¤¹:

    + +

    + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +

    + +

    ´ü¸ÂÀÚ¤ì»þ¹ï¤Ï¤¤¤¯¤Ä¤« + '<num> <type>' Àá¤òÄɲ乤뤳¤È¤Ç¤è¤êºÙ¤«¤¯ + À©¸æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +

    + +

    ½¤Àµ»þ¹ï¤Ë´ð¤Å¤¤¤¿ÀßÄê¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¡¢Expires ¥Ø¥Ã¥À¤Ï + ¥Ç¥£¥¹¥¯¤Î¥Õ¥¡¥¤¥ë°Ê³°¤Î¥³¥ó¥Æ¥ó¥Ä¤Ë¤ÏÄɲ䵤ì¤Ê¤¤¤³¤È¤ËÃí°Õ + ¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¤è¤¦¤Ê¥³¥ó¥Æ¥ó¥Ä¤Ë¤Ï½¤Àµ»þ¹ï¤Ï¸ºß¤·¤Ê¤¤¤«¤é¤Ç¤¹¡£

    +
    +
    top
    +

    ExpiresActive ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Expires ¥Ø¥Ã¥À¤ÎÀ¸À®¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:ExpiresActive On|Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_expires
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÂбþ¤¹¤ë¥É¥­¥å¥á¥ó¥È¤ÎÎΰè¤Ç + Expires ¤È Cache-Control¥Ø¥Ã¥À¤ò + Í­¸ú¤Ë¤¹¤ë¤«Ìµ¸ú¤Ë¤¹¤ë¤«¤ò·è¤á¤Þ¤¹¡£ + (Î㤨¤Ð¡¢.htaccess ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î + ʸ½ñ¤Î¤ß¤ËŬÍѤµ¤ì¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£) Off ¤Ë + ÀßÄꤵ¤ì¤¿¾ì¹ç¤ÏÂбþÎΰè¤Ç¤½¤ì¤é¤Î¥Ø¥Ã¥À¤Ï + À¸À®¤µ¤ì¤Þ¤»¤ó (.htaccess ¤¬¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤ÎÀßÄê¤ò + ¾å½ñ¤­¤¹¤ë¡¢¤È¤¤¤¦¤è¤¦¤Ê²¼°Ì¥ì¥Ù¥ë¤Ç¤Î¾å½ñ¤­¤¬¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð)¡£ + On ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Ø¥Ã¥À¤Ï ExpiresByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + ExpiresDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤Î´ð½à¤Ë½¾¤Ã¤Æʸ½ñ¤Ë¥Ø¥Ã¥À¤òÄɲä·¤Þ¤¹ (³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö»²¾È)¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Expires ¤È + Cache-Control ¥Ø¥Ã¥À¤Î¸ºß¤ò + Êݾڤ¹¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£´ð½à¤¬Ëþ¤¿¤µ¤ì¤Æ + ¤¤¤Ê¤¤¾ì¹ç¤Ï¥Ø¥Ã¥À¤ÏÄɲ䵤줺¡¢·ë²Ì¤È¤·¤Æ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + »ØÄꤵ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¤«¤Î¤è¤¦¤Ë¤µ¤¨¸«¤¨¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    ExpiresByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:MIME ¥¿¥¤¥×¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë Expires ¥Ø¥Ã¥À¤ÎÃÍ
    ¹½Ê¸:ExpiresByType MIME-type +<code>seconds
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_expires
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï»ØÄꤵ¤ì¤¿¥¿¥¤¥×¤Î¥É¥­¥å¥á¥ó¥È + (Î㤨¤Ð text/html) + ¤ËÂФ·¤ÆÀ¸À®¤µ¤ì¤ë Expires ¥Ø¥Ã¥À¤È Cache-Control + ¥Ø¥Ã¥À¤Î max-age ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤòÄêµÁ¤·¤Þ¤¹¡£ + Æó¤ÄÌܤΰú¿ô¤Ï´ü¸ÂÀÚ¤ì¤ÎÆü»þ¤òÀ¸À®¤¹¤ë¤¿¤á¤Î´ð½à»þ¹ï¤ËÄɲ䵤ì¤ë + Éÿô¤òÀßÄꤷ¤Þ¤¹¡£Cache-Control: + max-age ¤Ï´ü¸ÂÀÚ¤ì¤Î»þ¹ï¤«¤é¥ê¥¯¥¨¥¹¥È»þ¹ï¤ò°ú¤¤¤¿¤â¤Î¤òÉÃ¤Ç + ɽ¤¹¤³¤È¤ÇÀ¸À®¤µ¤ì¤Þ¤¹¡£

    + +

    ´ð½à»þ¹ï¤Ï¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤«¡¢¥¯¥é¥¤¥¢¥ó¥È¤Î¥É¥­¥å¥á¥ó¥È¤Ø¤Î + ¥¢¥¯¥»¥¹»þ¹ï¤Ç¤¹¡£¤É¤Á¤é¤ò»È¤¦¤Ù¤­¤«¤Ï <code> + ¤Ë¤è¤Ã¤Æ»ØÄꤷ¤Þ¤¹¡£M ¤Ï´ð½à»þ¹ï¤È¤·¤Æ + ¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤ò¤È¤¤¤¦°ÕÌ£¤Ç¡¢A ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î + ¥¢¥¯¥»¥¹»þ¹ï¤ò»È¤¦¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¸ú²Ì¤Ë¤ÏÈù̯¤Ê°ã¤¤¤¬¤¢¤ê¤Þ¤¹¡£M ¤¬»ÈÍѤµ¤ì¤¿¾ì¹ç¤Ï¡¢ + ¤¹¤Ù¤Æ¤Î¥­¥ã¥Ã¥·¥å¤Ë¤¢¤ë¸½ºß¤Î¥É¥­¥å¥á¥ó¥È¥­¥ã¥Ã¥·¥å¤ÏƱ»þ¤Ë´ü¸Â¤¬ + ÀÚ¤ì¤Þ¤¹¡£¤³¤ì¤ÏƱ¤¸ URL ¤ËËè½µ¾ï¤ËÃÖ¤«¤ì¤ëÊ󤻤Τ褦¤Ê¤â¤Î¤Ë¤Ï + Èó¾ï¤ËÍ­¸ú¤Ç¤¹¡£A ¤¬»ÈÍѤµ¤ì¤¿¾ì¹ç¤Ï¡¢´ü¸ÂÀÚ¤ì¤Î + »þ´Ö¤Ï³Æ¥¯¥é¥¤¥¢¥ó¥È¤è¤Ã¤Æ°Û¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤Ï¤¢¤Þ¤êÊѹ¹¤µ¤ì¤Ê¤¤ + ²èÁü¥Õ¥¡¥¤¥ë¤Ê¤É¡¢Æä˴ØÏ¢¤¹¤ë¥É¥­¥å¥á¥ó¥È·²¤¬¤¹¤Ù¤ÆƱ¤¸²èÁü¤ò + »²¾È¤¹¤ë¤È¤­ (¤¹¤Ê¤ï¤Á²èÁü¤¬Èæ³ÓŪû¤¤´ü´ÖÆâ¤Ë·«¤êÊÖ¤· + ¥¢¥¯¥»¥¹¤µ¤ì¤ë¤È¤­) ¤ËÍ­¸ú¤Ç¤¹¡£

    + +

    Îã:

    + # enable expirations
    + ExpiresActive On
    + # expire GIF images after a month in the client's cache
    + ExpiresByType image/gif A2592000
    + # HTML documents are good for a week from the
    + # time they were changed
    + ExpiresByType text/html M604800 +

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï ExpiresActive On ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë + ¤È¤­¤Î¤ßÍ­¸ú¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤Ï¡¢ + »ØÄꤵ¤ì¤¿ MIME ¥¿¥¤¥×¤ËÂФ·¤Æ¤Î¤ß ExpiresDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + ÀßÄꤵ¤ì¤¿´ü¸ÂÀÚ¤ì´üÆü¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    ¤³¤Îʸ½ñ¤ÎÁ°¤ÎÊý¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ëÂåÂع½Ê¸¤ò + »È¤Ã¤Æ´ü¸ÂÀÚ¤ì´üÆü¤Î·×»»ÊýË¡¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +
    +
    top
    +

    ExpiresDefault ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:´ü¸ÂÀÚ¤ì´üÆü¤ò·×»»¤¹¤ë¥Ç¥Õ¥©¥ë¥È¥¢¥ë¥´¥ê¥º¥à
    ¹½Ê¸:ExpiresDefault <code>seconds
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Indexes
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_expires
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÂбþ¤¹¤ëÈϰϤΤ¹¤Ù¤Æ¤Î¥É¥­¥å¥á¥ó¥È¤ËÂФ·¤Æ + ¥Ç¥Õ¥©¥ë¥È¤Î´ü¸ÂÀÚ¤ì´üÆü¤Î·×»»¥¢¥ë¥´¥ê¥º¥à¤òÀßÄꤷ¤Þ¤¹¡£ExpiresByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ + ¥¿¥¤¥×Ëè¤Ë¾å½ñ¤­¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£°ú¿ô¤Î¹½Ê¸¤Ï¤½¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÀâÌÀ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢ÂåÂع½Ê¸¤â + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_expires.html.ko.euc-kr b/trunk/docs/manual/mod/mod_expires.html.ko.euc-kr new file mode 100644 index 0000000000..d027b68554 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.html.ko.euc-kr @@ -0,0 +1,225 @@ + + + +mod_expires - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_expires

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:»ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ ±âÁØ¿¡ µû¶ó Expires¿Í +Cache-Control HTTP Çì´õ¸¦ »ý¼ºÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:expires_module
    ¼Ò½ºÆÄÀÏ:mod_expires.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ¼­¹ö ÀÀ´äÀÇ Expires HTTP Çì´õ¿Í + Cache-Control HTTP Çì´õÀÇ max-age + Áö½Ã¾î ¼³Á¤À» Á¶ÀýÇÑ´Ù. ¸¸±âÀÏÀ» ÆÄÀÏÀÌ ¸¶Á÷¸· ¼öÁ¤µÈ ½Ã°£ + ȤÀº Ŭ¶óÀ̾ðÆ®°¡ Á¢¼ÓÇÑ ½Ã°£¿¡ »ó´ëÀûÀ¸·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ HTTP Çì´õµéÀº Ŭ¶óÀ̾ðÆ®¿¡°Ô ¹®¼­ÀÇ + À¯È¿¼º°ú Áö¼Ó¼ºÀ» ¾Ë·ÁÁØ´Ù. ÀÌ ½Ã°£ÀÌ ¾ÆÁ÷ Áö³ªÁö¾Ê¾Ò´Ù¸é, + ¹®¼­¸¦ ij½¬¿¡¼­ °¡Á®¿Íµµ µÈ´Ù. ¸¸±âÀÏÀÌ Áö³µ´Ù¸é ij½¬µÈ + °ÍÀ» "¸¸·áµÇ°í" À¯È¿ÇÏÁö ¾Ê´Ù°í °£ÁÖÇÏ¿©, ¼Ò½º¿¡¼­ ¹®¼­¸¦ + »õ·Î ¾ò¾î¿Í¾ß ÇÑ´Ù.

    + +

    Header Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© max-age ¿ÜÀÇ ´Ù¸¥ + Cache-Control Áö½Ã¾î(RFC + 2616, 14.9 Àý Âü°í)¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    +

    Áö½Ã¾îµé

    + +

    ÁÖÁ¦

    +
    +
    top
    +
    +

    ´Ù¸¥ ³»ºÎ ¹®¹ý

    +

    ExpiresDefault¿Í + ExpiresByType + Áö½Ã¾î¸¦ ´õ Àбâ ÁÁÀº Çü½ÄÀ¸·Î ±â¼úÇÒ ¼ö ÀÖ´Ù:

    + +

    + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +

    + +

    <base>´Â ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
      +
    • access
    • + +
    • now ('access'¿Í °°À½)
    • + +
    • modification
    • +
    + +

    plus Å°¿öµå´Â ¾ø¾îµµ µÈ´Ù. <num>Àº + [atoi()¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â] Á¤¼ö°ªÀÌ´Ù. + <type>Àº ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    ¿¹¸¦ µé¾î, ´ÙÀ½ ¸ðµÎ´Â ¹®¼­°¡ ±âº»ÀûÀ¸·Î Á¢¼ÓµÈÁö 1´ÞÈÄ¿¡ + ¸¸±âµÈ´Ù°í ¼³Á¤ÇÑ´Ù:

    + +

    + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +

    + +

    '<num> <type>' ±¸¹®À» ¹Ýº¹Çؼ­ »ç¿ëÇÏ¿© + ¸¸±â½Ã°£À» ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù:

    + +

    + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +

    + +

    ¸¸¾à ¼öÁ¤½Ã°£(modification)À» ±âÁØÀ¸·Î ¸¸±â½Ã°£À» ¼³Á¤ÇÏ´Â + °æ¿ì ³»¿ëÀ» µð½ºÅ©¿¡ ÀÖ´Â ÆÄÀÏ¿¡¼­ °¡Á®¿ÀÁö ¾Ê´Â´Ù¸é Expires + Çì´õ¸¦ ºÙÀÌÁö ¾Ê´Â´Ù. ÀÌ °æ¿ì ³»¿ë¿¡ ¼öÁ¤½Ã°£ÀÌ + ¾ø±â ¶§¹®ÀÌ´Ù.

    +
    +
    top
    +

    ExpiresActive Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:Expires Çì´õ¸¦ »ý¼ºÇÑ´Ù
    ¹®¹ý:ExpiresActive On|Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_expires
    +

    ÀÌ Áö½Ã¾î´Â ÇØ´ç ¿µ¿ª¿¡ ´ëÇØ (Áï, .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÑ´Ù¸é ±× µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â ¹®¼­µé¸¸ ÇØ´çµÈ´Ù.) + Expires¿Í Cache-Control Çì´õ¸¦ + »ý¼ºÇÒÁö À¯¹«¸¦ °áÁ¤ÇÑ´Ù. (.htaccess ÆÄÀÏ µîÀ¸·Î + ´õ ÇÏÀ§ ´Ü°è¿¡¼­ ¼­¹ö¼³Á¤À» º¯°æÇÏÁö¾Ê´Â ÇÑ) + OffÀ̸é ÇØ´ç ¿µ¿ª¿¡ ÀÖ´Â ¹®¼­¿¡ À̵é Çì´õ¸¦ + »ý¼ºÇÏÁö ¾Ê´Â´Ù. OnÀ̸é ExpiresByType°ú ExpiresDefault Áö½Ã¾î·Î + (ÇØ´ç Ç׸ñÀ» Âü°íÇ϶ó) ÁöÁ¤ÇÑ ±ÔÄ¢¿¡ µû¶ó ¼­ºñ½ºÇÏ·Á´Â + ¹®¼­¿¡ ÀÌ Çì´õµéÀ» »ý¼ºÇÑ´Ù.

    + +

    ÀÌ Áö½Ã¾î°¡ Expires³ª Cache-Control + Çì´õ¸¦ º¸ÀåÇÏÁö´Â ¾Ê´Â´Ù. ±ÔÄ¢¿¡ ÇØ´çÇÏÁö ¾Ê´Ù¸é ¸¶Ä¡ ÀÌ + Áö½Ã¾î°¡ ¾ø´Â °Íó·³ Çì´õ¸¦ ¸¸µéÁö ¾Ê´Â´Ù.

    + +
    +
    top
    +

    ExpiresByType Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:MIME typeÀ¸·Î Expires Çì´õ°ªÀ» ¼³Á¤ÇÑ´Ù
    ¹®¹ý:ExpiresByType MIME-type +<code>seconds
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_expires
    +

    ÀÌ Áö½Ã¾î´Â ƯÁ¤ Á¾·ùÀÇ (¿¡¸¦ µé¾î, + text/html) ¹®¼­¿¡ ´ëÇÑ Expires + Çì´õ°ª°ú Cache-Control Çì´õÀÇ max-age + Áö½Ã¾î°ªÀ» Á¤ÀÇÇÑ´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ¸¸±â½Ã°£À» °áÁ¤ÇÒ¶§ + ±âÁØ ½Ã°£¿¡ ´õÇÒ ÃÊ´ÜÀ§ °ªÀ» ÁöÁ¤ÇÑ´Ù. Cache-Control: + max-age´Â ¸¸±â½Ã°£¿¡¼­ ¿äûÇÑ ½Ã°£À» »©¼­ °è»êÇÏ°í, + °á°ú´Â ÃÊ´ÜÀ§·Î Ç¥½ÃÇÑ´Ù.

    + +

    ±âÁØ ½Ã°£Àº ÆÄÀÏÀÇ ÃÖ±Ù ¼öÁ¤½Ã°£ ȤÀº Ŭ¶óÀ̾ðÆ®°¡ ¹®¼­¿¡ + Á¢±ÙÇÑ ½Ã°£ÀÌ´Ù. À̶² °ÍÀ» »ç¿ëÇÒÁö´Â + <code> Çʵå·Î °áÁ¤ÇØ¾ß ÇÑ´Ù. + MÀº ±âÁØ ½Ã°£À¸·Î ÆÄÀÏÀÇ ÃÖ±Ù ¼öÁ¤½Ã°£À» + »ç¿ëÇÏ°í, A´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±Ù ½Ã°£À» »ç¿ëÇÑ´Ù.

    + +

    Â÷ÀÌ´Â ¹Ì¹¦ÇÏ´Ù. MÀ» »ç¿ëÇϸé ij½¬¿¡ ÀÖ´Â + ¸ðµç º¹»çº»ÀÌ °°Àº ½Ã°£¿¡ ¸¸·áµÈ´Ù. ±×·¡¼­ Ç×»ó °°Àº URL·Î + ã¾Æº¼ ¼ö ÀÖ´Â ÁÖ°£ÀÏÁ¤ °°Àº ¿ëµµ¿¡ ÁÁ´Ù. A¸¦ + »ç¿ëÇÏ¸é º¹»çº»ÀÇ ¸¸±â½Ã°£ÀÌ °¢°¢ ´Ù¸£´Ù. ÀÌ´Â ÀÚÁÖ ¼öÁ¤µÇÁö¾Ê´Â + ±×¸²ÆÄÀÏ¿¡, ƯÈ÷ ¿©·¯ ¹®¼­¿¡¼­ °°Àº ±×¸²À» ÂüÁ¶ÇÒ¶§ (¿¹¸¦ + µé¾î, À̹ÌÁö´Â »ó´ëÀûÀ¸·Î ªÀº ±â°£µ¿¾È ¹Ýº¹Çؼ­ Á¢±ÙµÈ´Ù), + À¯¿ëÇÏ´Ù.

    + +

    ¿¹Á¦:

    + # ¸¸±âÇì´õ¸¦ »ç¿ëÇÑ´Ù
    + ExpiresActive On
    + # Ŭ¶óÀ̾ðÆ® ij½¬ÀÇ GIF ±×¸²Àº ÇÑ ´ÞÈÄ¿¡ ¸¸±âÇÑ´Ù
    + ExpiresByType image/gif A2592000
    + # HTML ¹®¼­´Â º¯°æÈÄ ÀÏÁÖÀÏ°£ À¯È¿ÇÏ´Ù + ExpiresByType text/html M604800 +

    + +

    ÀÌ Áö½Ã¾î´Â ExpiresActive OnÀ» »ç¿ëÇÒ¶§¸¸ + À¯È¿ÇÔÀ» ÁÖÀÇÇ϶ó. ExpiresDefault Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ƯÁ¤ MIME type¿¡ ´ëÇؼ­¸¸ ¸¸±â½Ã°£À» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾Õ¿¡¼­ ¼³¸íÇÑ ´Ù¸¥ ¹®¹ýÀ» »ç¿ëÇÏ¿© + ¸¸±â½Ã°£À» °è»êÇÒ ¼öµµ ÀÖ´Ù.

    + +
    +
    top
    +

    ExpiresDefault Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¸¸±â½Ã°£À» °è»êÇÏ´Â ±âº» ¾Ë°í¸®Áò
    ¹®¹ý:ExpiresDefault <code>seconds
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Extension
    ¸ðµâ:mod_expires
    +

    ÀÌ Áö½Ã¾î´Â ÇØ´ç ¿µ¿ª¿¡ ÀÖ´Â ¸ðµç ¹®¼­ÀÇ ¸¸±â½Ã°£À» + °è»êÇÏ´Â ±âº» ¾Ë°í¸®ÁòÀ» ÁöÁ¤ÇÑ´Ù. ExpiresByType Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Á¾·ùº°·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¾Æ±Ô¸ÕÆ® ¹®¹ý¿¡ ´ëÇÑ + ÀÚ¼¼ÇÑ ¼³¸íÀº ±× Áö½Ã¾î¿Í ´Ù¸¥ ¹®¹ýÀ» + Âü°íÇ϶ó.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_expires.xml b/trunk/docs/manual/mod/mod_expires.xml new file mode 100644 index 0000000000..6fdc12af69 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.xml @@ -0,0 +1,231 @@ + + + + + + + + + +mod_expires +Generation of Expires and +Cache-Control HTTP headers according to user-specified +criteria +Extension +mod_expires.c +expires_module + + +

    This module controls the setting of the Expires + HTTP header and the max-age directive of the + Cache-Control HTTP header in server responses. The + expiration date can set to be relative to either the time the + source file was last modified, or to the time of the client + access.

    + +

    These HTTP headers are an instruction to the client about the + document's validity and persistence. If cached, the document may + be fetched from the cache rather than from the source until this + time has passed. After that, the cache copy is considered + "expired" and invalid, and a new copy must be obtained from the + source.

    + +

    To modify Cache-Control directives other than + max-age (see RFC + 2616 section 14.9), you can use the Header directive.

    + +
    + +
    Alternate Interval Syntax +

    The ExpiresDefault and + ExpiresByType directives + can also be defined in a more readable syntax of the form:

    + + + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +
    + +

    where <base> is one of:

    + +
      +
    • access
    • + +
    • now (equivalent to + 'access')
    • + +
    • modification
    • +
    + +

    The plus keyword is optional. <num> + should be an integer value [acceptable to atoi()], + and <type> is one of:

    + +
      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    For example, any of the following directives can be used to + make documents expire 1 month after being accessed, by + default:

    + + + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +
    + +

    The expiry time can be fine-tuned by adding several + '<num> <type>' clauses:

    + + + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +
    + +

    Note that if you use a modification date based setting, the + Expires header will not be added to content + that does not come from a file on disk. This is due to the fact + that there is no modification time for such content.

    +
    + + +ExpiresActive +Enables generation of Expires +headers +ExpiresActive On|Off +server config +virtual hostdirectory +.htaccess +Indexes + + +

    This directive enables or disables the generation of the + Expires and Cache-Control headers for + the document realm in question. (That is, if found in an + .htaccess file, for instance, it applies only to + documents generated from that directory.) If set to + Off, the headers will not be generated for any + document in the realm (unless overridden at a lower level, such as + an .htaccess file overriding a server config + file). If set to On, the headers will be added to + served documents according to the criteria defined by the + ExpiresByType and + ExpiresDefault + directives (q.v.).

    + +

    Note that this directive does not guarantee that an + Expires or Cache-Control header will be + generated. If the criteria aren't met, no header will be sent, and + the effect will be as though this directive wasn't even + specified.

    +
    +
    + + +ExpiresByType +Value of the Expires header configured +by MIME type +ExpiresByType MIME-type +<code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    This directive defines the value of the Expires + header and the max-age directive of the + Cache-Control header generated for documents of the + specified type (e.g., text/html). The second + argument sets the number of seconds that will be added to a base + time to construct the expiration date. The Cache-Control: + max-age is calculated by subtracting the request time from + the expiration date and expressing the result in seconds.

    + +

    The base time is either the last modification time of the + file, or the time of the client's access to the document. Which + should be used is specified by the + <code> field; M + means that the file's last modification time should be used as + the base time, and A means the client's access + time should be used.

    + +

    The difference in effect is subtle. If M is used, + all current copies of the document in all caches will expire at + the same time, which can be good for something like a weekly + notice that's always found at the same URL. If A is + used, the date of expiration is different for each client; this + can be good for image files that don't change very often, + particularly for a set of related documents that all refer to + the same images (i.e., the images will be accessed + repeatedly within a relatively short timespan).

    + + Example: + # enable expirations
    + ExpiresActive On
    + # expire GIF images after a month in the client's cache
    + ExpiresByType image/gif A2592000
    + # HTML documents are good for a week from the
    + # time they were changed
    + ExpiresByType text/html M604800 +
    + +

    Note that this directive only has effect if + ExpiresActive On has been specified. It overrides, + for the specified MIME type only, any expiration date + set by the ExpiresDefault + directive.

    + +

    You can also specify the expiration time calculation using + an alternate syntax, described earlier in + this document.

    +
    +
    + + +ExpiresDefault +Default algorithm for calculating expiration time +ExpiresDefault <code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    This directive sets the default algorithm for calculating the + expiration time for all documents in the affected realm. It can be + overridden on a type-by-type basis by the ExpiresByType directive. See the + description of that directive for details about the syntax of the + argument, and the alternate syntax + description as well.

    +
    +
    +
    + diff --git a/trunk/docs/manual/mod/mod_expires.xml.ja b/trunk/docs/manual/mod/mod_expires.xml.ja new file mode 100644 index 0000000000..99e678bcfb --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.xml.ja @@ -0,0 +1,219 @@ + + + + + + + + + +mod_expires +$B%f!<%6$N;XDj$7$?4p=`$K4p$E$$$?(B Expires $B$H(B +Cache-Control HTTP $B%X%C%@$N@8@.(B +Extension +mod_expires.c +expires_module + + +

    $B$3$N%b%8%e!<%k$O%5!<%P1~Ez$N(B Expires HTTP $B%X%C%@(B + $B$H(B Cache-Control $B%X%C%@$N(B max-age $B%G%#%l%/%F%#%V$N(B + $B@_Dj$r@)8f$7$^$9!#85$N%U%!%$%k$,:n@.$5$l$?;~9o$^$?$O(B + $B%/%i%$%"%s%H$N%"%/%;%9;~9o$N$I$A$i$+$K4p$E$$$F4|8B@Z$lF|$r(B + $B@_Dj$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$l$i$N%X%C%@$O%/%i%$%"%s%H$KJ8=q$N(B + $BM-8z@-$H7QB3@-$r;X<($7$^$9!#J8=q$,%-%c%C%7%e$5$l$?>l9g$K$O!"(B + $B;XDj;~9o$KC#$9$k$^$G$O!"85$N>l=j$+$il=j$+$i?7$7$$$b$N$r + +

    max-age $B0J30(B (RFC + 2616 section 14.9 $B;2>H(B) $B$N(B Cache-Control $B$N%G%#%l%/%F%#%V$r(B + $BA`:n$9$k$K$O(B Header $B%G%#%l%/%F%#%V$r(B + $B;H$&$3$H$,$G$-$^$9!#(B

    + +
    $BBeBX4|4V;XDj9=J8(B + +

    ExpiresDefault $B%G%#%l%/%F%#%V$H(B + ExpiresByType $B%G%#%l%/%F%#%V$O(B + $B0J2<$N$h$jFI$_0W$$9=J8$r;H$C$FDj5A$9$k$3$H$,$G$-$^$9(B:

    + + + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +
    + +

    <base> $B$O0J2<$N$I$l$+$G$9(B:

    + +
      +
    • access
    • + +
    • now ('access' $B$HEy2A(B)
    • + +
    • modification
    • +
    + +

    plus $B%-!<%o!<%I$O>JN,2DG=$G$9!#(B<num> + $B$O(B (atoi() $B$, + +

      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    $BNc$($P!"0J2<$N%G%#%l%/%F%#%V$O$I$l$b%G%U%)%k%H$GJ8=q$,%"%/%;%9$N(B 1 $B%v7n8e$K(B + $B4|8B$,@Z$l$k$h$&$K$9$k$?$a$K;H$($^$9(B:

    + + + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +
    + +

    $B4|8B@Z$l;~9o$O$$$/$D$+(B + '<num> <type>' $B@a$rDI2C$9$k$3$H$G$h$j:Y$+$/(B + $B@)8f$9$k$3$H$,$G$-$^$9(B:

    + + + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +
    + +

    $B=$@5;~9o$K4p$E$$$?@_Dj$r;HMQ$7$F$$$k>l9g!"(BExpires $B%X%C%@$O(B + $B%G%#%9%/$N%U%!%$%k0J30$N%3%s%F%s%D$K$O(B$BDI2C$5$l$J$$(B$B$3$H$KCm0U(B + $B$7$F$/$@$5$$!#$=$N$h$&$J%3%s%F%s%D$K$O=$@5;~9o$OB8:_$7$J$$$+$i$G$9!#(B

    +
    + + +ExpiresActive +Expires $B%X%C%@$N@8@.$rM-8z$K$9$k(B +ExpiresActive On|Off +server config +virtual hostdirectory +.htaccess +Indexes + + +

    $B$3$N%G%#%l%/%F%#%V$OBP1~$9$k%I%-%e%a%s%H$NNN0h$G(B + Expires $B$H(B Cache-Control$B%X%C%@$r(B + $BM-8z$K$9$k$+L58z$K$9$k$+$r7h$a$^$9!#(B + ($BNc$($P!"(B.htaccess $B%U%!%$%k$G$O$=$N%G%#%l%/%H%j$N(B + $BJ8=q$N$_$KE,MQ$5$l$k$H$$$&$3$H$G$9!#(B) Off $B$K(B + $B@_Dj$5$l$?>l9g$OBP1~NN0h$G$=$l$i$N%X%C%@$O(B + $B@8@.$5$l$^$;$s(B (.htaccess $B$,%5!<%P@_Dj%U%!%$%k$N@_Dj$r(B + $B>e=q$-$9$k!"$H$$$&$h$&$J2<0L%l%Y%k$G$N>e=q$-$,$5$l$F$$$J$1$l$P(B)$B!#(B + On $B$K@_Dj$5$l$F$$$l$P!"%X%C%@$O(B ExpiresByType $B%G%#%l%/%F%#%V$H(B + ExpiresDefault $B%G%#%l%/%F%#%V(B + $B$N4p=`$K=>$C$FJ8=q$K%X%C%@$rDI2C$7$^$9(B ($B3F%G%#%l%/%F%#%V;2>H(B)$B!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O(B Expires $B$H(B + Cache-Control $B%X%C%@$NB8:_$r(B + $BJ]>Z$9$k$o$1$G$O$J$$$3$H$KCm0U$7$F$/$@$5$$!#4p=`$,K~$?$5$l$F(B + $B$$$J$$>l9g$O%X%C%@$ODI2C$5$l$:!"7k2L$H$7$F$3$N%G%#%l%/%F%#%V$,(B + $B;XDj$5$l$F$$$J$+$C$?$+$N$h$&$K$5$(8+$($k$3$H$K$J$j$^$9!#(B

    +
    +
    + + +ExpiresByType +MIME $B%?%$%W$K$h$C$F@_Dj$5$l$k(B Expires $B%X%C%@$NCM(B +ExpiresByType MIME-type +<code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    $B$3$N%G%#%l%/%F%#%V$O;XDj$5$l$?%?%$%W$N%I%-%e%a%s%H(B + ($BNc$($P(B text/html) + $B$KBP$7$F@8@.$5$l$k(B Expires $B%X%C%@$H(B Cache-Control + $B%X%C%@$N(B max-age $B%G%#%l%/%F%#%V$NCM$rDj5A$7$^$9!#(B + $BFs$DL\$N0z?t$O4|8B@Z$l$NF|;~$r@8@.$9$k$?$a$N4p=`;~9o$KDI2C$5$l$k(B + $BIC?t$r@_Dj$7$^$9!#(BCache-Control: + max-age $B$O4|8B@Z$l$N;~9o$+$i%j%/%(%9%H;~9o$r0z$$$?$b$N$rIC$G(B + $BI=$9$3$H$G@8@.$5$l$^$9!#(B

    + +

    $B4p=`;~9o$O%U%!%$%k$N:G=*=$@5;~9o$+!"%/%i%$%"%s%H$N%I%-%e%a%s%H$X$N(B + $B%"%/%;%9;~9o$G$9!#$I$A$i$r;H$&$Y$-$+$O(B <code> + $B$K$h$C$F;XDj$7$^$9!#(BM $B$O4p=`;~9o$H$7$F(B + $B%U%!%$%k$N:G=*=$@5;~9o$r$H$$$&0UL#$G!"(BA $B$O%/%i%$%"%s%H$N(B + $B%"%/%;%9;~9o$r;H$&$H$$$&0UL#$K$J$j$^$9!#(B

    + +

    $B8z2L$K$OHyL/$J0c$$$,$"$j$^$9!#(BM $B$,;HMQ$5$l$?>l9g$O!"(B + $B$9$Y$F$N%-%c%C%7%e$K$"$k8=:_$N%I%-%e%a%s%H%-%c%C%7%e$OF1;~$K4|8B$,(B + $B@Z$l$^$9!#$3$l$OF1$8(B URL $B$KKh=5>o$KCV$+$l$kJs$;$N$h$&$J$b$N$K$O(B + $BHs>o$KM-8z$G$9!#(BA $B$,;HMQ$5$l$?>l9g$O!"4|8B@Z$l$N(B + $B;~4V$O3F%/%i%$%"%s%H$h$C$F0[$J$j$^$9!#$3$l$O$"$^$jJQ99$5$l$J$$(B + $B2hA|%U%!%$%k$J$I!"FC$K4XO"$9$k%I%-%e%a%s%H72$,$9$Y$FF1$82hA|$r(B + $B;2>H$9$k$H$-(B ($B$9$J$o$A(B$B2hA|$,Hf3SE*C;$$4|4VFb$K7+$jJV$7(B + $B%"%/%;%9$5$l$k$H$-(B) $B$KM-8z$G$9!#(B

    + + $BNc(B: + # enable expirations
    + ExpiresActive On
    + # expire GIF images after a month in the client's cache
    + ExpiresByType image/gif A2592000
    + # HTML documents are good for a week from the
    + # time they were changed
    + ExpiresByType text/html M604800 +
    + +

    $B$3$N%G%#%l%/%F%#%V$O(B ExpiresActive On $B$,;XDj$5$l$F$$$k(B + $B$H$-$N$_M-8z$G$"$k$3$H$KCm0U$7$F$/$@$5$$!#$3$l$O!"(B + $B;XDj$5$l$?(B MIME $B%?%$%W$KBP$7$F(B$B$N$_(B ExpiresDefault $B%G%#%l%/%F%#%V$G(B + $B@_Dj$5$l$?4|8B@Z$l4|F|$r>e=q$-$7$^$9!#(B

    + +

    $B$3$NJ8=q$NA0$NJ}$G@bL@$5$l$F$$$k(B$BBeBX9=J8(B$B$r(B + $B;H$C$F4|8B@Z$l4|F|$N7W;;J}K!$r;XDj$9$k$3$H$b$G$-$^$9!#(B

    +
    +
    + + +ExpiresDefault +$B4|8B@Z$l4|F|$r7W;;$9$k%G%U%)%k%H%"%k%4%j%:%`(B +ExpiresDefault <code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    $B$3$N%G%#%l%/%F%#%V$OBP1~$9$kHO0O$N$9$Y$F$N%I%-%e%a%s%H$KBP$7$F(B + $B%G%U%)%k%H$N4|8B@Z$l4|F|$N7W;;%"%k%4%j%:%`$r@_Dj$7$^$9!#(BExpiresByType $B%G%#%l%/%F%#%V$K$h$C$F(B + $B%?%$%WKh$K>e=q$-$9$k$3$H$,$G$-$^$9!#0z?t$N9=J8$O$=$N%G%#%l%/%F%#%V$N(B + $B@bL@$r;2>H$7$F$/$@$5$$!#$^$?!"(B$BBeBX9=J8(B$B$b(B + $B;2>H$7$F$/$@$5$$!#(B

    +
    +
    +
    + diff --git a/trunk/docs/manual/mod/mod_expires.xml.ko b/trunk/docs/manual/mod/mod_expires.xml.ko new file mode 100644 index 0000000000..1e8c17b5d3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.xml.ko @@ -0,0 +1,211 @@ + + + + + + + + + +mod_expires +»ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ ±âÁØ¿¡ µû¶ó Expires¿Í +Cache-Control HTTP Çì´õ¸¦ »ý¼ºÇÑ´Ù +Extension +mod_expires.c +expires_module + + +

    ÀÌ ¸ðµâÀº ¼­¹ö ÀÀ´äÀÇ Expires HTTP Çì´õ¿Í + Cache-Control HTTP Çì´õÀÇ max-age + Áö½Ã¾î ¼³Á¤À» Á¶ÀýÇÑ´Ù. ¸¸±âÀÏÀ» ÆÄÀÏÀÌ ¸¶Á÷¸· ¼öÁ¤µÈ ½Ã°£ + ȤÀº Ŭ¶óÀ̾ðÆ®°¡ Á¢¼ÓÇÑ ½Ã°£¿¡ »ó´ëÀûÀ¸·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ HTTP Çì´õµéÀº Ŭ¶óÀ̾ðÆ®¿¡°Ô ¹®¼­ÀÇ + À¯È¿¼º°ú Áö¼Ó¼ºÀ» ¾Ë·ÁÁØ´Ù. ÀÌ ½Ã°£ÀÌ ¾ÆÁ÷ Áö³ªÁö¾Ê¾Ò´Ù¸é, + ¹®¼­¸¦ ij½¬¿¡¼­ °¡Á®¿Íµµ µÈ´Ù. ¸¸±âÀÏÀÌ Áö³µ´Ù¸é ij½¬µÈ + °ÍÀ» "¸¸·áµÇ°í" À¯È¿ÇÏÁö ¾Ê´Ù°í °£ÁÖÇÏ¿©, ¼Ò½º¿¡¼­ ¹®¼­¸¦ + »õ·Î ¾ò¾î¿Í¾ß ÇÑ´Ù.

    + +

    Header Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© max-age ¿ÜÀÇ ´Ù¸¥ + Cache-Control Áö½Ã¾î(RFC + 2616, 14.9 Àý Âü°í)¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    ´Ù¸¥ ³»ºÎ ¹®¹ý +

    ExpiresDefault¿Í + ExpiresByType + Áö½Ã¾î¸¦ ´õ Àбâ ÁÁÀº Çü½ÄÀ¸·Î ±â¼úÇÒ ¼ö ÀÖ´Ù:

    + + + ExpiresDefault "<base> [plus] {<num> + <type>}*"
    + ExpiresByType type/encoding "<base> [plus] + {<num> <type>}*" +
    + +

    <base>´Â ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
      +
    • access
    • + +
    • now ('access'¿Í °°À½)
    • + +
    • modification
    • +
    + +

    plus Å°¿öµå´Â ¾ø¾îµµ µÈ´Ù. <num>Àº + [atoi()¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â] Á¤¼ö°ªÀÌ´Ù. + <type>Àº ´ÙÀ½Áß ÇϳªÀÌ´Ù:

    + +
      +
    • years
    • +
    • months
    • +
    • weeks
    • +
    • days
    • +
    • hours
    • +
    • minutes
    • +
    • seconds
    • +
    + +

    ¿¹¸¦ µé¾î, ´ÙÀ½ ¸ðµÎ´Â ¹®¼­°¡ ±âº»ÀûÀ¸·Î Á¢¼ÓµÈÁö 1´ÞÈÄ¿¡ + ¸¸±âµÈ´Ù°í ¼³Á¤ÇÑ´Ù:

    + + + ExpiresDefault "access plus 1 month"
    + ExpiresDefault "access plus 4 weeks"
    + ExpiresDefault "access plus 30 days" +
    + +

    '<num> <type>' ±¸¹®À» ¹Ýº¹Çؼ­ »ç¿ëÇÏ¿© + ¸¸±â½Ã°£À» ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù:

    + + + ExpiresByType text/html "access plus 1 month 15 + days 2 hours"
    + ExpiresByType image/gif "modification plus 5 hours 3 + minutes" +
    + +

    ¸¸¾à ¼öÁ¤½Ã°£(modification)À» ±âÁØÀ¸·Î ¸¸±â½Ã°£À» ¼³Á¤ÇÏ´Â + °æ¿ì ³»¿ëÀ» µð½ºÅ©¿¡ ÀÖ´Â ÆÄÀÏ¿¡¼­ °¡Á®¿ÀÁö ¾Ê´Â´Ù¸é Expires + Çì´õ¸¦ ºÙÀÌÁö ¾Ê´Â´Ù. ÀÌ °æ¿ì ³»¿ë¿¡ ¼öÁ¤½Ã°£ÀÌ + ¾ø±â ¶§¹®ÀÌ´Ù.

    +
    + + +ExpiresActive +Expires Çì´õ¸¦ »ý¼ºÇÑ´Ù +ExpiresActive On|Off +server config +virtual hostdirectory +.htaccess +Indexes + + +

    ÀÌ Áö½Ã¾î´Â ÇØ´ç ¿µ¿ª¿¡ ´ëÇØ (Áï, .htaccess + ÆÄÀÏ¿¡¼­ »ç¿ëÇÑ´Ù¸é ±× µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â ¹®¼­µé¸¸ ÇØ´çµÈ´Ù.) + Expires¿Í Cache-Control Çì´õ¸¦ + »ý¼ºÇÒÁö À¯¹«¸¦ °áÁ¤ÇÑ´Ù. (.htaccess ÆÄÀÏ µîÀ¸·Î + ´õ ÇÏÀ§ ´Ü°è¿¡¼­ ¼­¹ö¼³Á¤À» º¯°æÇÏÁö¾Ê´Â ÇÑ) + OffÀ̸é ÇØ´ç ¿µ¿ª¿¡ ÀÖ´Â ¹®¼­¿¡ À̵é Çì´õ¸¦ + »ý¼ºÇÏÁö ¾Ê´Â´Ù. OnÀ̸é ExpiresByType°ú ExpiresDefault Áö½Ã¾î·Î + (ÇØ´ç Ç׸ñÀ» Âü°íÇ϶ó) ÁöÁ¤ÇÑ ±ÔÄ¢¿¡ µû¶ó ¼­ºñ½ºÇÏ·Á´Â + ¹®¼­¿¡ ÀÌ Çì´õµéÀ» »ý¼ºÇÑ´Ù.

    + +

    ÀÌ Áö½Ã¾î°¡ Expires³ª Cache-Control + Çì´õ¸¦ º¸ÀåÇÏÁö´Â ¾Ê´Â´Ù. ±ÔÄ¢¿¡ ÇØ´çÇÏÁö ¾Ê´Ù¸é ¸¶Ä¡ ÀÌ + Áö½Ã¾î°¡ ¾ø´Â °Íó·³ Çì´õ¸¦ ¸¸µéÁö ¾Ê´Â´Ù.

    +
    +
    + + +ExpiresByType +MIME typeÀ¸·Î Expires Çì´õ°ªÀ» ¼³Á¤ÇÑ´Ù +ExpiresByType MIME-type +<code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    ÀÌ Áö½Ã¾î´Â ƯÁ¤ Á¾·ùÀÇ (¿¡¸¦ µé¾î, + text/html) ¹®¼­¿¡ ´ëÇÑ Expires + Çì´õ°ª°ú Cache-Control Çì´õÀÇ max-age + Áö½Ã¾î°ªÀ» Á¤ÀÇÇÑ´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ¸¸±â½Ã°£À» °áÁ¤ÇÒ¶§ + ±âÁØ ½Ã°£¿¡ ´õÇÒ ÃÊ´ÜÀ§ °ªÀ» ÁöÁ¤ÇÑ´Ù. Cache-Control: + max-age´Â ¸¸±â½Ã°£¿¡¼­ ¿äûÇÑ ½Ã°£À» »©¼­ °è»êÇÏ°í, + °á°ú´Â ÃÊ´ÜÀ§·Î Ç¥½ÃÇÑ´Ù.

    + +

    ±âÁØ ½Ã°£Àº ÆÄÀÏÀÇ ÃÖ±Ù ¼öÁ¤½Ã°£ ȤÀº Ŭ¶óÀ̾ðÆ®°¡ ¹®¼­¿¡ + Á¢±ÙÇÑ ½Ã°£ÀÌ´Ù. À̶² °ÍÀ» »ç¿ëÇÒÁö´Â + <code> Çʵå·Î °áÁ¤ÇØ¾ß ÇÑ´Ù. + MÀº ±âÁØ ½Ã°£À¸·Î ÆÄÀÏÀÇ ÃÖ±Ù ¼öÁ¤½Ã°£À» + »ç¿ëÇÏ°í, A´Â Ŭ¶óÀ̾ðÆ®ÀÇ Á¢±Ù ½Ã°£À» »ç¿ëÇÑ´Ù.

    + +

    Â÷ÀÌ´Â ¹Ì¹¦ÇÏ´Ù. MÀ» »ç¿ëÇϸé ij½¬¿¡ ÀÖ´Â + ¸ðµç º¹»çº»ÀÌ °°Àº ½Ã°£¿¡ ¸¸·áµÈ´Ù. ±×·¡¼­ Ç×»ó °°Àº URL·Î + ã¾Æº¼ ¼ö ÀÖ´Â ÁÖ°£ÀÏÁ¤ °°Àº ¿ëµµ¿¡ ÁÁ´Ù. A¸¦ + »ç¿ëÇÏ¸é º¹»çº»ÀÇ ¸¸±â½Ã°£ÀÌ °¢°¢ ´Ù¸£´Ù. ÀÌ´Â ÀÚÁÖ ¼öÁ¤µÇÁö¾Ê´Â + ±×¸²ÆÄÀÏ¿¡, ƯÈ÷ ¿©·¯ ¹®¼­¿¡¼­ °°Àº ±×¸²À» ÂüÁ¶ÇÒ¶§ (¿¹¸¦ + µé¾î, À̹ÌÁö´Â »ó´ëÀûÀ¸·Î ªÀº ±â°£µ¿¾È ¹Ýº¹Çؼ­ Á¢±ÙµÈ´Ù), + À¯¿ëÇÏ´Ù.

    + + ¿¹Á¦: + # ¸¸±âÇì´õ¸¦ »ç¿ëÇÑ´Ù
    + ExpiresActive On
    + # Ŭ¶óÀ̾ðÆ® ij½¬ÀÇ GIF ±×¸²Àº ÇÑ ´ÞÈÄ¿¡ ¸¸±âÇÑ´Ù
    + ExpiresByType image/gif A2592000
    + # HTML ¹®¼­´Â º¯°æÈÄ ÀÏÁÖÀÏ°£ À¯È¿ÇÏ´Ù + ExpiresByType text/html M604800 +
    + +

    ÀÌ Áö½Ã¾î´Â ExpiresActive OnÀ» »ç¿ëÇÒ¶§¸¸ + À¯È¿ÇÔÀ» ÁÖÀÇÇ϶ó. ExpiresDefault Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ƯÁ¤ MIME type¿¡ ´ëÇؼ­¸¸ ¸¸±â½Ã°£À» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾Õ¿¡¼­ ¼³¸íÇÑ ´Ù¸¥ ¹®¹ýÀ» »ç¿ëÇÏ¿© + ¸¸±â½Ã°£À» °è»êÇÒ ¼öµµ ÀÖ´Ù.

    +
    +
    + + +ExpiresDefault +¸¸±â½Ã°£À» °è»êÇÏ´Â ±âº» ¾Ë°í¸®Áò +ExpiresDefault <code>seconds +server configvirtual host +directory.htaccess +Indexes + + +

    ÀÌ Áö½Ã¾î´Â ÇØ´ç ¿µ¿ª¿¡ ÀÖ´Â ¸ðµç ¹®¼­ÀÇ ¸¸±â½Ã°£À» + °è»êÇÏ´Â ±âº» ¾Ë°í¸®ÁòÀ» ÁöÁ¤ÇÑ´Ù. ExpiresByType Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Á¾·ùº°·Î ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¾Æ±Ô¸ÕÆ® ¹®¹ý¿¡ ´ëÇÑ + ÀÚ¼¼ÇÑ ¼³¸íÀº ±× Áö½Ã¾î¿Í ´Ù¸¥ ¹®¹ýÀ» + Âü°íÇ϶ó.

    +
    +
    +
    + diff --git a/trunk/docs/manual/mod/mod_expires.xml.meta b/trunk/docs/manual/mod/mod_expires.xml.meta new file mode 100644 index 0000000000..ee1b828e32 --- /dev/null +++ b/trunk/docs/manual/mod/mod_expires.xml.meta @@ -0,0 +1,13 @@ + + + + mod_expires + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_ext_filter.html b/trunk/docs/manual/mod/mod_ext_filter.html new file mode 100644 index 0000000000..aacf8a658e --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.html @@ -0,0 +1,11 @@ +URI: mod_ext_filter.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_ext_filter.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_ext_filter.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_ext_filter.html.en b/trunk/docs/manual/mod/mod_ext_filter.html.en new file mode 100644 index 0000000000..043ce5288d --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.html.en @@ -0,0 +1,376 @@ + + + +mod_ext_filter - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_ext_filter

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Pass the response body through an external program before +delivery to the client
    Status:Extension
    Module Identifier:ext_filter_module
    Source File:mod_ext_filter.c
    +

    Summary

    + +

    mod_ext_filter presents a simple and familiar + programming model for filters. With + this module, a program which reads from stdin and writes to stdout + (i.e., a Unix-style filter command) can be a filter for + Apache. This filtering mechanism is much slower than using a + filter which is specially written for the Apache API and runs + inside of the Apache server process, but it does have the + following benefits:

    + +
      +
    • the programming model is much simpler
    • + +
    • any programming/scripting language can be used, provided + that it allows the program to read from standard input and + write to standard output
    • + +
    • existing programs can be used unmodified as Apache + filters
    • +
    + +

    Even when the performance characteristics are not suitable + for production use, mod_ext_filter can be used as + a prototype environment for filters.

    + +
    +

    Directives

    + +

    Topics

    +

    See also

    +
    +
    top
    +
    +

    Examples

    + +

    Generating HTML from some other type of response

    +

    + # mod_ext_filter directive to define a filter
    + # to HTML-ize text/c files using the external
    + # program /usr/bin/enscript, with the type of
    + # the result set to text/html
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # core directive to cause the new filter to
    + # be run on output
    + SetOutputFilter c-to-html
    +
    + # mod_mime directive to set the type of .c
    + # files to text/c
    + AddType text/c .c
    +
    + # mod_ext_filter directive to set the debug
    + # level just high enough to see a log message
    + # per request showing the configuration in force
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +

    + + +

    Implementing a content encoding filter

    +

    Note: this gzip example is just for the purposes of illustration. + Please refer to mod_deflate for a practical + implementation.

    + +

    + # mod_ext_filter directive to define the external filter
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # core directive to cause the gzip filter to be
    + # run on output
    + SetOutputFilter gzip
    +
    + # mod_header directive to add
    + # "Content-Encoding: gzip" header field
    + Header set Content-Encoding gzip
    +
    + </Location> +

    + + +

    Slowing down the server

    +

    + # mod_ext_filter directive to define a filter
    + # which runs everything through cat; cat doesn't
    + # modify anything; it just introduces extra pathlength
    + # and consumes more resources
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # core directive to cause the slowdown filter to
    + # be run several times on output
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +

    + + +

    Using sed to replace text in the response

    +

    + # mod_ext_filter directive to define a filter which
    + # replaces text in the response
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # core directive to cause the fixtext filter to
    + # be run on output
    + SetOutputFilter fixtext
    +
    + </Location> +

    + + +

    Tracing another filter

    +

    + # Trace the data read and written by mod_deflate
    + # for a particular client (IP 192.168.1.31)
    + # experiencing compression problems.
    + # This filter will trace what goes into mod_deflate.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # This filter will trace what goes after mod_deflate.
    + # Note that without the ftype parameter, the default
    + # filter type of AP_FTYPE_RESOURCE would cause the
    + # filter to be placed *before* mod_deflate in the filter
    + # chain. Giving it a numeric value slightly higher than
    + # AP_FTYPE_CONTENT_SET will ensure that it is placed
    + # after mod_deflate.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +

    + +

    Here is the filter which traces the data:

    + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +

    + +
    +
    top
    +

    ExtFilterDefine Directive

    + + + + + + +
    Description:Define an external filter
    Syntax:ExtFilterDefine filtername parameters
    Context:server config
    Status:Extension
    Module:mod_ext_filter
    +

    The ExtFilterDefine directive defines the + characteristics of an external filter, including the program to + run and its arguments.

    + +

    filtername specifies the name of the filter being + defined. This name can then be used in SetOutputFilter + directives. It must be unique among all registered filters. + At the present time, no error is reported by the + register-filter API, so a problem with duplicate names isn't + reported to the user.

    + +

    Subsequent parameters can appear in any order and define the + external command to run and certain other characteristics. The + only required parameter is cmd=. These parameters + are:

    + +
    +
    cmd=cmdline
    + +
    The cmd= keyword allows you to specify the + external command to run. If there are arguments after the + program name, the command line should be surrounded in + quotation marks (e.g., cmd="/bin/mypgm + arg1 arg2".) Normal shell quoting is + not necessary since the program is run directly, bypassing the shell. + Program arguments are blank-delimited. A backslash can be used to + escape blanks which should be part of a program argument. Any + backslashes which are part of the argument must be escaped with + backslash themselves. In addition to the standard CGI environment + variables, DOCUMENT_URI, DOCUMENT_PATH_INFO, and + QUERY_STRING_UNESCAPED will also be set for the program.
    + +
    mode=mode
    + +
    Use mode=output (the default) for filters which + process the response. Use mode=input for filters + which process the request. mode=input is new with + Apache 2.1.
    + +
    intype=imt
    + +
    This parameter specifies the internet media type (i.e., + MIME type) of documents which should be filtered. By default, + all documents are filtered. If intype= is + specified, the filter will be disabled for documents of other + types.
    + +
    outtype=imt
    + +
    This parameter specifies the internet media type (i.e., + MIME type) of filtered documents. It is useful when the + filter changes the internet media type as part of the + filtering operation. By default, the internet media type is + unchanged.
    + +
    PreservesContentLength
    + +
    The PreservesContentLength keyword specifies + that the filter preserves the content length. This is not the + default, as most filters change the content length. In the + event that the filter doesn't modify the length, this keyword + should be specified.
    + +
    ftype=filtertype
    + +
    This parameter specifies the numeric value for filter type + that the filter should be registered as. The default value, + AP_FTYPE_RESOURCE, is sufficient in most cases. If the filter + needs to operate at a different point in the filter chain than + resource filters, then this parameter will be necessary. See + the AP_FTYPE_foo definitions in util_filter.h for appropriate + values.
    + +
    disableenv=env
    + +
    This parameter specifies the name of an environment variable + which, if set, will disable the filter.
    + +
    enableenv=env
    + +
    This parameter specifies the name of an environment variable + which must be set, or the filter will be disabled.
    +
    + +
    +
    top
    +

    ExtFilterOptions Directive

    + + + + + + + +
    Description:Configure mod_ext_filter options
    Syntax:ExtFilterOptions option [option] ...
    Default:ExtFilterOptions DebugLevel=0 NoLogStderr
    Context:directory
    Status:Extension
    Module:mod_ext_filter
    +

    The ExtFilterOptions directive specifies + special processing options for mod_ext_filter. + Option can be one of

    + +
    +
    DebugLevel=n
    + +
    + The DebugLevel keyword allows you to specify + the level of debug messages generated by + mod_ext_filter. By default, no debug messages + are generated. This is equivalent to + DebugLevel=0. With higher numbers, more debug + messages are generated, and server performance will be + degraded. The actual meanings of the numeric values are + described with the definitions of the DBGLVL_ constants + near the beginning of mod_ext_filter.c. + +

    Note: The core directive LogLevel should be used to cause debug messages to + be stored in the Apache error log.

    +
    + +
    LogStderr | NoLogStderr
    + +
    The LogStderr keyword specifies that + messages written to standard error by the external filter + program will be saved in the Apache error log. + NoLogStderr disables this feature.
    +
    + +

    Example

    + ExtFilterOptions LogStderr DebugLevel=0 +

    + +

    Messages written to the filter's standard error will be stored + in the Apache error log. No debug messages will be generated by + mod_ext_filter.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ext_filter.html.ja.euc-jp b/trunk/docs/manual/mod/mod_ext_filter.html.ja.euc-jp new file mode 100644 index 0000000000..3aeead25e6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.html.ja.euc-jp @@ -0,0 +1,367 @@ + + + +mod_ext_filter - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_ext_filter

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥ì¥¹¥Ý¥ó¥¹¤Î¥Ü¥Ç¥£¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ëÁ°¤Ë³°Éô¥×¥í¥°¥é¥à¤Ç½èÍý¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:ext_filter_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_ext_filter.c
    +

    ³µÍ×

    + +

    mod_ext_filter ¤Ç¤Ï ¥Õ¥£¥ë¥¿ + ¤Î´·¤ì¿Æ¤·¤ó¤Àñ½ã¤Ê¥×¥í¥°¥é¥ß¥ó¥°¥â¥Ç¥ë¤¬Ä󶡤µ¤ì¤Þ¤¹¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤ò + »È¤¨¤Ð¡¢É¸½àÆþÎϤ«¤éÆɤ߹þ¤ó¤Ç¡¢É¸½à½ÐÎϤ˽ñ¤­½Ð¤¹¥×¥í¥°¥é¥à + (¤¹¤Ê¤ï¤Á Unix ·Á¼°¤Î¥Õ¥£¥ë¥¿¥³¥Þ¥ó¥É) ¤ò Apache ¤Î¥Õ¥£¥ë¥¿¤Ë¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£¤³¤Î¥Õ¥£¥ë¥¿¤Îµ¡¹½¤Ï¡¢Apache API ¸þ¤±¤Ë½ñ¤«¤ì¤¿ Apache + ¥µ¡¼¥Ð¥×¥í¥»¥¹Æâ¤Ç¼Â¹Ô¤µ¤ì¤ëÀìÍѤΥե£¥ë¥¿¤è¤ê¤â¤º¤Ã¤ÈÃÙ¤¤¤Ç¤¹¤¬¡¢ + °Ê²¼¤Î¤è¤¦¤ÊÍøÅÀ¤â¤¢¤ê¤Þ¤¹¡£

    + +
      +
    • ¤º¤Ã¤È¥·¥ó¥×¥ë¤Ê¥×¥í¥°¥é¥ß¥ó¥°¥â¥Ç¥ë
    • + +
    • ¥×¥í¥°¥é¥à¤¬É¸½àÆþÎϤ«¤éÆɤó¤Çɸ½à½ÐÎϤ˽ñ¤¯¤â¤Î¤Ç¤¢¤ë¸Â¤ê¡¢ + ¤É¤ó¤Ê¥×¥í¥°¥é¥à¸À¸ì¤ä¥¹¥¯¥ê¥×¥È¸À¸ì¤Ç¤â»È¤¦¤³¤È¤¬¤Ç¤­¤ë
    • + +
    • ´û¸¤Î¥×¥í¥°¥é¥à¤òÊѹ¹¤¹¤ë¤³¤È¤Ê¤¯ Apache ¤Î¥Õ¥£¥ë¥¿¤È¤·¤Æ + »È¤¦¤³¤È¤¬¤Ç¤­¤ë
    • +
    + +

    À­Ç½¤ÎÌäÂê¤Ë¤è¤ê¼Â±¿ÍѤËŬ¤µ¤Ê¤¤¤È¤·¤Æ¤â¡¢¥Õ¥£¥ë¥¿¤Î¥×¥í¥È¥¿¥¤¥×ÍѤΠ+ ´Ä¶­¤È¤·¤Æ¤Ï mod_ext_filter ¤Ï»È¤¨¤Þ¤¹¡£

    + +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +

    »²¾È

    +
    +
    top
    +
    +

    Îã

    + +

    ¾¤Î¥¿¥¤¥×¤Î¥ì¥¹¥Ý¥ó¥¹¤«¤é HTML ¤òÀ¸À®¤¹¤ë

    +

    + # mod_ext_filter directive to define a filter
    + # to HTML-ize text/c files using the external
    + # program /usr/bin/enscript, with the type of
    + # the result set to text/html
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # core directive to cause the new filter to
    + # be run on output
    + SetOutputFilter c-to-html
    +
    + # mod_mime directive to set the type of .c
    + # files to text/c
    + AddType text/c .c
    +
    + # mod_ext_filter directive to set the debug
    + # level just high enough to see a log message
    + # per request showing the configuration in force
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +

    + + +

    ¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î¥Õ¥£¥ë¥¿¤ò¼ÂÁõ¤¹¤ë

    +

    Ãí: ¤³¤Î gzip ¤ÎÎã¤Ï¥Ç¥âÍѤǤ¹¡£¼ÂÍÑŪ¤Ê¼ÂÁõ¤Ï + mod_deflate ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + # mod_ext_filter directive to define the external filter
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # core directive to cause the gzip filter to be
    + # run on output
    + SetOutputFilter gzip
    +
    + # mod_header directive to add
    + # "Content-Encoding: gzip" header field
    + Header set Content-Encoding gzip
    +
    + </Location> +

    + + +

    ¥µ¡¼¥Ð¤òÃÙ¤¯¤¹¤ë

    +

    + # mod_ext_filter directive to define a filter
    + # which runs everything through cat; cat doesn't
    + # modify anything; it just introduces extra pathlength
    + # and consumes more resources
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # core directive to cause the slowdown filter to
    + # be run several times on output
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +

    + + +

    sed ¤ò»È¤Ã¤Æ±þÅúÃæ¤Î¥Æ¥­¥¹¥È¤òÃÖ´¹¤¹¤ë

    +

    + # mod_ext_filter directive to define a filter which
    + # replaces text in the response
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # core directive to cause the fixtext filter to
    + # be run on output
    + SetOutputFilter fixtext
    +
    + </Location> +

    + + +

    Ê̤Υե£¥ë¥¿¤Î¥È¥ì¡¼¥¹

    +

    + # Trace the data read and written by mod_deflate
    + # for a particular client (IP 192.168.1.31)
    + # experiencing compression problems.
    + # This filter will trace what goes into mod_deflate.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # This filter will trace what goes after mod_deflate.
    + # Note that without the ftype parameter, the default
    + # filter type of AP_FTYPE_RESOURCE would cause the
    + # filter to be placed *before* mod_deflate in the filter
    + # chain. Giving it a numeric value slightly higher than
    + # AP_FTYPE_CONTENT_SET will ensure that it is placed
    + # after mod_deflate.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +

    + +

    ¥Ç¡¼¥¿¤ò¥È¥ì¡¼¥¹¤¹¤ë¥Õ¥£¥ë¥¿:

    + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +

    + +
    +
    top
    +

    ExtFilterDefine ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:³°Éô¥Õ¥£¥ë¥¿¤òÄêµÁ
    ¹½Ê¸:ExtFilterDefine filtername parameters
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_ext_filter
    +

    ExtFilterDefine ¤Ï¡¢¼Â¹Ô¤¹¤ë¥×¥í¥°¥é¥à¤ä + °ú¿ô¤Ê¤É¡¢³°Éô¥Õ¥£¥ë¥¿¤ÎÆÃÀ­¤òÄêµÁ¤·¤Þ¤¹¡£

    + +

    filtername ¤ÏÄêµÁ¤¹¤ë¥Õ¥£¥ë¥¿¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤Î̾Á°¤Ï¸å¤Ç SetOutputFilter + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄê¤Ç¤­¤Þ¤¹¡£Ì¾Á°¤ÏÅÐÏ¿¤µ¤ì¤ë¤¹¤Ù¤Æ¤Î¥Õ¥£¥ë¥¿¤Ç + °ì°Õ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¸½»þÅÀ¤Ç¤Ï¡¢¥Õ¥£¥ë¥¿¤ÎÅÐÏ¿ API ¤«¤é¤Ï + ¥¨¥é¡¼¤ÏÊó¹ð¤µ¤ì¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é¡¢½ÅÊ£¤¹¤ë̾Á°¤ò»È¤Ã¤Æ¤·¤Þ¤Ã¤¿¤È¤­¤Ç¤â + ¥æ¡¼¥¶¤Ë¤Ï¤½¤Î¤³¤È¤ÏÊó¹ð¤µ¤ì¤Þ¤»¤ó¡£

    + +

    ³¤¯¥Ñ¥é¥á¡¼¥¿¤Î½çÈ֤ϴط¸Ìµ¤¯¡¢¤½¤ì¤é¤Ï¼Â¹Ô¤¹¤ë³°Éô¥³¥Þ¥ó¥É¤È¡¢ + ¾¤ÎÆÃÀ­¤òÄêµÁ¤·¤Þ¤¹¡£cmd= ¤À¤±¤¬É¬¿Ü¤Î¥Ñ¥é¥á¡¼¥¿¤Ç¤¹¡£ + »ØÄê²Äǽ¤Ê¥Ñ¥é¥á¡¼¥¿¤Ï:

    + +
    +
    cmd=cmdline
    + +
    cmd= ¥­¡¼¥ï¡¼¥É¤Ï¼Â¹Ô¤¹¤ë³°Éô¥³¥Þ¥ó¥É¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥×¥í¥°¥é¥à̾¤Î¸å¤Ë°ú¿ô¤¬¤¢¤ë¾ì¹ç¤Ï¡¢¥³¥Þ¥ó¥É¹Ô¤Ï°úÍÑÉä¤Ç°Ï¤à + ɬÍפ¬¤¢¤ê¤Þ¤¹ (Î㤨¤Ð¡¢cmd="/bin/mypgm + arg1 arg2" ¤Î¤è¤¦¤Ë)¡£¥×¥í¥°¥é¥à¤Ï + ¥·¥§¥ë·Ðͳ¤Ç¤Ê¤¯¡¢Ä¾Àܼ¹Ԥµ¤ì¤Þ¤¹¤Î¤Ç¡¢Ä̾ï¤Î¥·¥§¥ëÍѤΠ+ ¥¨¥¹¥±¡¼¥×¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£¥×¥í¥°¥é¥à¤Î°ú¿ô¤Ï¶õÇò¤Ç¶èÀÚ¤é¤ì¤Þ¤¹¡£ + ¥×¥í¥°¥é¥à¤Î°ú¿ô¤Î°ìÉô¤È¤Ê¤ëɬÍפΤ¢¤ë¶õÇò¤Ï¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹¤Ç¥¨¥¹¥±¡¼¥× + ¤Ç¤­¤Þ¤¹¡£°ú¿ô¤Î°ìÉô¤Ë¤Ê¤ë¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ï¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ç + ¥¨¥¹¥±¡¼¥×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£É¸½à¤Î CGI ´Ä¶­ÊÑ¿ô¤Ë²Ã¤¨¤Æ¡¢ + ´Ä¶­ÊÑ¿ô DOCUMENT_URI, DOCUMENT_PATH_INFO, and + QUERY_STRING_UNESCAPED ¤¬¥×¥í¥°¥é¥à¤Î¤¿¤á¤ËÀßÄꤵ¤ì¤Þ¤¹¡£
    + +
    mode=mode
    + +
    ±þÅú¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤Ë¤Ï mode=output (¥Ç¥Õ¥©¥ë¥È) + ¤ò»È¤¤¤Þ¤¹¡£¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤Ë¤Ï mode=input + ¤ò»È¤¤¤Þ¤¹¡£mode=input ¤Ï Apache 2.1 ¤«¤é¤Î¿·¤·¤¤µ¡Ç½¤Ç¤¹¡£
    + +
    intype=imt
    + +
    ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï¥Õ¥£¥ë¥¿¤µ¤ì¤ë¤Ù¤­¥É¥­¥å¥á¥ó¥È¤Î + ¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥á¥Ç¥£¥¢¥¿¥¤¥× (¤¹¤Ê¤ï¤Á¡¢MIME ¥¿¥¤¥×) ¤ò + »ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¤¹¤Ù¤Æ¤Î¥É¥­¥å¥á¥ó¥È¤¬¥Õ¥£¥ë¥¿¤µ¤ì¤Þ¤¹¡£ + intype= ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¥Õ¥£¥ë¥¿¤Ï»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤ + ¥É¥­¥å¥á¥ó¥È¤Ë¤ÏŬÍѤµ¤ì¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£
    + +
    outtype=imt
    + +
    ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï¥Õ¥£¥ë¥¿¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Î + ¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥á¥Ç¥£¥¢¥¿¥¤¥× (¤¹¤Ê¤ï¤Á¡¢MIME ¥¿¥¤¥×) ¤ò + »ØÄꤷ¤Þ¤¹¡£¥Õ¥£¥ë¥¿Æ°ºî¤Ë¤È¤â¤Ê¤Ã¤Æ¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥á¥Ç¥£¥¢¥¿¥¤¥×¤¬ + ÊѤï¤ë¾ì¹ç¤ËÍ­ÍѤǤ¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥á¥Ç¥£¥¢¥¿¥¤¥×¤Ï + Êѹ¹¤µ¤ì¤Þ¤»¤ó¡£
    + +
    PreservesContentLength
    + +
    PreservesContentLength ¥­¡¼¥ï¡¼¥É¤Ï¥Õ¥£¥ë¥¿¤¬ + content length (ÌõÃí: ¥³¥ó¥Æ¥ó¥È¤ÎŤµ) + ¤òÊѹ¹¤·¤Ê¤¤¤È¤¤¤¦¤³¤È¤ò»ØÄꤷ¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¥Õ¥£¥ë¥¿¤Ï + content length ¤òÊѹ¹¤¹¤ë¤¿¤á¡¢¤³¤ì¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¥Õ¥£¥ë¥¿¤¬Ä¹¤µ¤òÊѤ¨¤Ê¤¤¤È¤­¤Ï¡¢¤³¤Î¥­¡¼¥ï¡¼¥É¤ò»ØÄꤹ¤ë¤È + ¤è¤¤¤Ç¤·¤ç¤¦¡£
    + +
    ftype=filtertype
    + +
    ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï¥Õ¥£¥ë¥¿¤¬ÅÐÏ¿¤µ¤ì¤ë¤Ù¤­¥Õ¥£¥ë¥¿¥¿¥¤¥×¤Î + ¿ôÃͤò»ØÄꤷ¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¾ì¹ç¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Î AP_FTYPE_RESOURCE ¤Ç + ½½Ê¬¤Ç¤¹¡£¥Õ¥£¥ë¥¿¤¬¥Õ¥£¥ë¥¿¥Á¥§¡¼¥ó¤ÎÊ̤ξì½ê¤ÇÆ°ºî¤¹¤ëɬÍפ¬¤¢¤ë + ¾ì¹ç¤Ï¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£»ØÄê²Äǽ¤ÊÃÍ¤Ï + util_filter.h ¤Î AP_FTYPE_foo ÄêµÁ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
    + +
    disableenv=env
    + +
    ÀßÄꤵ¤ì¤Æ¤¤¤¿¾ì¹ç¤Ë¥Õ¥£¥ë¥¿¤ò̵¸ú¤Ë¤¹¤ë¤¿¤á¤Î´Ä¶­ÊÑ¿ô¤ò + »ØÄꤷ¤Þ¤¹¡£
    + +
    enableenv=env
    + +
    ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï¥Õ¥£¥ë¥¿¤¬Í­¸ú¤Ë¤Ê¤ë¤¿¤á¤ËÀßÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð + ¤Ê¤é¤Ê¤¤´Ä¶­ÊÑ¿ô¤ò»ØÄꤷ¤Þ¤¹¡£
    +
    + +
    +
    top
    +

    ExtFilterOptions ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:mod_ext_filter ¤Î¥ª¥×¥·¥ç¥ó¤òÀßÄê
    ¹½Ê¸:ExtFilterOptions option [option] ...
    ¥Ç¥Õ¥©¥ë¥È:ExtFilterOptions DebugLevel=0 NoLogStderr
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_ext_filter
    +

    ExtFilterOptions ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + mod_ext_filter ¤ÎÆÃÊ̤ʽèÍýÍѤΥª¥×¥·¥ç¥ó¤ò + »ØÄꤷ¤Þ¤¹¡£Option ¤Ë¤Ï°Ê²¼¤Î¤É¤ì¤«¤ò»ØÄꤷ¤Þ¤¹¡£

    + +
    +
    DebugLevel=n
    + +
    + DebugLevel ¤Ç mod_ext_filter + ¤ÎÀ¸À®¤¹¤ë¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤Î¥ì¥Ù¥ë¤òÀßÄê¤Ç¤­¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤ÏÀ¸À®¤µ¤ì¤Þ¤»¤ó¡£ + ¤³¤ì¤Ï DebugLevel=0 ¤ÈÀßÄꤹ¤ë¤Î¤ÈƱ¤¸¤Ç¤¹¡£ + ¿ô»ú¤¬Â礭¤¯¤Ê¤ì¤Ð¤Ê¤ë¤Û¤É¡¢¤è¤ê¿¤¯¤Î¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤¬ + À¸À®¤µ¤ì¡¢¥µ¡¼¥Ð¤ÎÀ­Ç½¤ÏÍî¤Á¤Þ¤¹¡£¿ôÃͤμºݤΰÕÌ£¤Ï + mod_ext_filter.c ¤ÎÀèƬ¶á¤¯¤Î DBGLVL_ Äê¿ô¤Î + ÄêµÁ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + +

    Ãí: ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤ò Apache ¤Î¥¨¥é¡¼¥í¥°¤Ë + Êݸ¤¹¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢core ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + LogLevel + ¤ò»È¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    +
    + +
    LogStderr | NoLogStderr
    + +
    LogStderr ¥­¡¼¥ï¡¼¥É¤Ï³°Éô¥Õ¥£¥ë¥¿¥×¥í¥°¥é¥à¤Ë¤è¤ê + ɸ½à¥¨¥é¡¼ (ÌõÃí: stderr) ¤Ë½ñ¤«¤ì¤¿¥á¥Ã¥»¡¼¥¸¤ò + Apache ¤Î¥¨¥é¡¼¥í¥°¤ËÊݸ¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£NoLogStderr ¤Ï + µÕ¤ËÊݸ¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£
    +
    + +

    Îã

    + ExtFilterOptions LogStderr DebugLevel=0 +

    + +

    ¤³¤ÎÎã¤Ç¤Ï¡¢¥Õ¥£¥ë¥¿¤Îɸ½à½ÐÎϤ˽ñ¤«¤ì¤¿¥á¥Ã¥»¡¼¥¸¤Ï + Apache ¤Î¥¨¥é¡¼¥í¥°¤ËÊݸ¤µ¤ì¤Þ¤¹¡£mod_ext_filter ¤«¤é¤Ï + ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤ÏÀ¸À®¤µ¤ì¤Þ¤»¤ó¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ext_filter.html.ko.euc-kr b/trunk/docs/manual/mod/mod_ext_filter.html.ko.euc-kr new file mode 100644 index 0000000000..2dbc868a1a --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.html.ko.euc-kr @@ -0,0 +1,354 @@ + + + +mod_ext_filter - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_ext_filter

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:ÀÀ´ä ³»¿ëÀ» ¿ÜºÎ ÇÁ·Î±×·¥À¸·Î ó¸®ÇÑ ÈÄ Å¬¶óÀ̾ðÆ®·Î +º¸³½´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:ext_filter_module
    ¼Ò½ºÆÄÀÏ:mod_ext_filter.c
    +

    ¿ä¾à

    + +

    mod_ext_filter¸¦ »ç¿ëÇÏ¸é °£´ÜÇÏ°í Àͼ÷ÇÑ + ¹æ¹ýÀ¸·Î ÇÊÅ͸¦ ¸¸µé ¼ö ÀÖ´Ù. + Ç¥ÁØÀԷ¿¡¼­ Àаí Ç¥ÁØÃâ·Â¿¡ ¾²´Â ÇÁ·Î±×·¥(Áï, À¯´Ð½º½Ä + ÇÊÅÍ ¸í·É¾î)À» ¾ÆÆÄÄ¡ ÇÊÅÍ·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ·± ÇÊÅÍ´Â + ¾ÆÆÄÄ¡ API·Î ¾²¿©Áö°í ¾ÆÆÄÄ¡ ¼­¹ö ÇÁ·Î¼¼½º ¾È¿¡¼­ ½ÇÇàµÇ´Â + ÇÊÅÍ¿¡ ºñÇØ ¸Å¿ì ´À¸®Áö¸¸, ´ÙÀ½°ú °°Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ÇÁ·Î±×·¡¹Ö ¸ðµ¨ÀÌ ¸Å¿ì °£´ÜÇÏ´Ù
    • + +
    • ÇÁ·Î±×·¥ÀÌ Ç¥ÁØÀԷ¿¡¼­ Àаí Ç¥ÁØÃâ·Â¿¡ ¾µ ¼ö¸¸ ÀÖ´Ù¸é + ¾î¶² ÇÁ·Î±×·¡¹Ö/½ºÅ©¸³Æ® ¾ð¾î¶óµµ »ç¿ëÇÒ ¼ö ÀÖ´Ù
    • + +
    • ÀÌ¹Ì ÀÖ´Â ÇÁ·Î±×·¥À» ¼öÁ¤¾øÀÌ ¾ÆÆÄÄ¡ ÇÊÅÍ·Î »ç¿ëÇÒ + ¼ö ÀÖ´Ù
    • +
    + +

    ½ÇÁ¦ »ç¿ëÇϱ⿡´Â ¼º´ÉÀÌ ¶³¾îÁöÁö¸¸, + mod_ext_filter¸¦ »ç¿ëÇÏ¿© ÇÊÅ͸¦ »¡¸® ¸¸µé¾îº¼ + ¼ö ÀÖ´Ù.

    + +
    +

    Áö½Ã¾îµé

    + +

    ÁÖÁ¦

    +

    Âü°í

    +
    +
    top
    +
    +

    ¿¹Á¦

    + +

    ´Ù¸¥ typeÀÇ ÀÀ´äÀ» HTML·Î ¸¸µç´Ù

    +

    + # mod_ext_filter Áö½Ã¾î¸¦ °¡Áö°í
    + # ¿ÜºÎ ÇÁ·Î±×·¥ /usr/bin/enscript¸¦ »ç¿ëÇÏ¿©
    + # ¹®¼­ÆÄÀÏ°ú text/c ÆÄÀÏÀ» HTML·Î ¸¸µé°í °á°úÀÇ
    + # typeÀ» text/html·Î º¯°æÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÑ´Ù
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # Ãâ·Â¿¡ »õ·Î¿î ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter c-to-html
    +
    + # .c ÆÄÀÏÀÇ typeÀ» text/c·Î ¸¸µå´Â mod_mime
    + # Áö½Ã¾î
    + AddType text/c .c
    +
    + # µð¹ö±× ¼öÁØÀ» ³ô¿©¼­ ¿äû¸¶´Ù ÇöÀç ¼³Á¤À»
    + # ¾Ë·ÁÁÖ´Â ·Î±×¹®À» ±â·ÏÇÏ´Â mod_ext_filter
    + # Áö½Ã¾î
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +

    + + +

    content ÀÎÄÚµù ÇÊÅÍ ±¸ÇöÇϱâ

    +

    Note: ¾Æ·¡ gzip ¿¹Á¦´Â ´ÜÁö ¼³¸íÀ» ¿¹·Î µç °ÍÀÌ´Ù. + ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÏ·Á¸é mod_deflate¸¦ + Âü°íÇÏ±æ ¹Ù¶õ´Ù.

    + +

    + # ¿ÜºÎ ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â mod_ext_filter Áö½Ã¾î
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # Ãâ·ÂÇÒ¶§ gzip ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter gzip
    +
    + # "Content-Encoding: gzip" Çì´õ¸¦ Ãß°¡ÇÏ´Â
    + # mod_header Áö½Ã¾î
    + Header set Content-Encoding gzip
    +
    + </Location> +

    + + +

    ¼­¹ö¸¦ ´À¸®°Ô Çϱâ

    +

    + # catÀ¸·Î ¸ðµç ³»¿ëÀ» Åë°úÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â
    + # mod_ext_filter Áö½Ã¾î; catÀº ¾Æ¹«°Íµµ ¼öÁ¤ÇÏÁö
    + # ¾Ê´Â´Ù; ´ÜÁö 󸮰æ·Î¸¦ ±æ°Ô ÇÏ¿© ÀÚ¿øÀ» ´õ ¼Ò¸ðÇÑ´Ù
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # Ãâ·ÂÇÒ¶§ slowdown ÇÊÅ͸¦ ¿©·¯¹ø ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +

    + + +

    sed¸¦ »ç¿ëÇÏ¿© ÀÀ´ä¿¡¼­ ±ÛÀ» ´ëüÇϱâ

    +

    + # ÀÀ´ä¿¡¼­ ±ÛÀ» ´ëüÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â
    + # mod_ext_filter Áö½Ã¾î
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # Ãâ·ÂÇÒ¶§ fixtext ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter fixtext
    +
    + </Location> +

    + + +

    ´Ù¸¥ ÇÊÅ͸¦ ÃßÀûÇϱâ

    +

    + # ¾ÐÃà ¹®Á¦°¡ Àִ ƯÁ¤ Ŭ¶óÀ̾ðÆ®(IP 192.168.1.31)¿¡
    + # ´ëÇØ mod_deflate°¡ ÀÐ°í ¾²´Â ÀڷḦ ÃßÀûÇÑ´Ù.
    + # ÀÌ ÇÊÅÍ´Â mod_deflate·Î º¸³»±â Àü ÀڷḦ ÃßÀûÇÑ´Ù.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # ÀÌ ÇÊÅÍ´Â mod_deflate¿¡¼­ ³ª¿À´Â ÀڷḦ ÃßÀûÇÑ´Ù.
    + # ftype ÆĶó¹ÌÅ͸¦ »ç¿ëÇÏÁö¾Ê´Â °æ¿ì, ±âº» ÇÊÅÍÇü
    + # AP_FTYPE_RESOURCE´Â ÇÊÅÍ ¼ø¼­¸¦ mod_deflate *ÀÌÀü¿¡*
    + # µÐ´Ù. AP_FTYPE_CONTENT_SET º¸´Ù Á¶±Ý ³ôÀº ¼ýÀÚ°ªÀ»
    + # ÁöÁ¤Çϸé mod_deflate ÀÌÈÄ¿¡ ½ÇÇàÇÑ´Ù.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +

    + +

    ´ÙÀ½Àº ÀڷḦ ÃßÀûÇÏ´Â ÇÊÅÍÀÌ´Ù:

    + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +

    + +
    +
    top
    +

    ExtFilterDefine Áö½Ã¾î

    + + + + + + +
    ¼³¸í:¿ÜºÎ ÇÊÅ͸¦ Á¤ÀÇÇÑ´Ù
    ¹®¹ý:ExtFilterDefine filtername parameters
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Extension
    ¸ðµâ:mod_ext_filter
    +

    ExtFilterDefine Áö½Ã¾î´Â ¿ÜºÎ + ÇÊÅÍÀÇ ¼ºÁú°ú ½ÇÇàÇÒ ÇÁ·Î±×·¥, ¾Æ±Ô¸ÕÆ®¸¦ Á¤ÀÇÇÑ´Ù.

    + +

    filternameÀº Á¤ÀÇÇÒ ÇÊÅÍ À̸§À» ÁöÁ¤ÇÑ´Ù. + ÀÌ À̸§À» SetOutputFilter Áö½Ã¾î¿¡¼­ »ç¿ëÇÑ´Ù. µî·ÏÇÑ ¸ðµç + ÇÊÅ͵鰣¿¡ À̸§ÀÌ °ãÄ¡¸é ¾ÈµÈ´Ù. ÇöÀç ÇÊÅ͵î·Ï API´Â + ¿À·ù¸¦ º¸°íÇÏÁö ¾Ê´Â´Ù. ±×·¡¼­ »ç¿ëÀÚ´Â À̸§ÀÌ °ãÄ¡´Â ¹®Á¦¸¦ + ¾ËÁö ¸øÇÑ´Ù.

    + +

    ½ÇÇàÇÒ ¿ÜºÎ ¸í·É¾î¿Í ´Ù¸¥ ¼ºÁúÀ» Á¤ÀÇÇÏ´Â ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®´Â + ¾î¶² ¼ø¼­·Î ³ª¿Íµµ °¡´ÉÇÏ´Ù. ´Ü, cmd= ÆĶó¹ÌÅÍ´Â + ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ÆĶó¹ÌÅÍ´Â ´ÙÀ½°ú °°´Ù:

    + +
    +
    cmd=cmdline
    + +
    cmd= Å°¿öµå´Â ½ÇÇàÇÒ ¿ÜºÎ ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù. + ÇÁ·Î±×·¥¸í µÚ¿¡ ¾Æ±Ô¸ÕÆ®°¡ ÀÖ´Ù¸é ¸í·ÉÇàÀ» ½Öµû¿ÈÇ¥·Î + ¹­¾î¾ß ÇÑ´Ù (¿¹¸¦ µé¾î, + cmd="/bin/mypgm arg1 + arg2"). ½©À» °ÅÄ¡Áö¾Ê°í Á÷Á¢ ÇÁ·Î±×·¥À» + ½ÇÇàÇϱ⶧¹®¿¡ ÀϹÝÀûÀÎ ½© µû¿ÈÇ¥´Â ÇÊ¿ä¾ø´Ù. ÇÁ·Î±×·¥ + ¾Æ±Ô¸ÕÆ®µéÀº °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. ÇÁ·Î±×·¥ ¾Æ±Ô¸ÕÆ®¿¡ °ø¹éÀÌ + ÀÖ´Ù¸é °ø¹é ¾Õ¿¡ ¹é½½·¡½¬·Î »ç¿ëÇØ¾ß ÇÑ´Ù. ¹é½½·¡½¬°¡ + ¾Æ±Ô¸ÕÆ®ÀÇ ÀϺζó¸é ¹é½½·¡½¬¸¦ µÎ¹ø »ç¿ëÇØ¾ß ÇÑ´Ù. ÇÁ·Î±×·¥À» + ½ÇÇàÇÒ¶§ Ç¥ÁØ CGI ȯ°æº¯¼ö¿Í Ãß°¡·Î DOCUMENT_URI, + DOCUMENT_PATH_INFO, QUERY_STRING_UNESCAPED º¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.
    + +
    mode=mode
    + +
    ÀÀ´äÀ» ó¸®ÇÏ´Â ÇÊÅÍ´Â (±âº»°ªÀÎ) mode=outputÀ» + »ç¿ëÇÑ´Ù. ¿äûÀ» ó¸®ÇÏ´Â ÇÊÅÍ´Â mode=inputÀ» + »ç¿ëÇÑ´Ù. mode=inputÀº ¾ÆÆÄÄ¡ 2.1¿¡ Ãß°¡µÇ¾ú´Ù.
    + +
    intype=imt
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅͷΠó¸®ÇÒ ¹®¼­ÀÇ ÀÎÅÍ³Ý media + type(Áï, MIME type)À» ÁöÁ¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ¸ðµç + ¹®¼­¸¦ ÇÊÅͷΠó¸®ÇÑ´Ù. intype=À» ÁöÁ¤Çϸé + ´Ù¸¥ typeÀÇ ¹®¼­´Â ÇÊÅͷΠó¸®ÇÏÁö ¾Ê´Â´Ù.
    + +
    outtype=imt
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅͷΠó¸®ÇÑ ¹®¼­ÀÇ ÀÎÅÍ³Ý media + type(Áï, MIME type)À» ÁöÁ¤ÇÑ´Ù. ÇÊÅÍó¸® ÀÛ¾÷Áß¿¡ + ÀÎÅÍ³Ý media typeÀ» º¯°æÇÒ¶§ À¯¿ëÇÏ´Ù. ±âº»ÀûÀ¸·Î, ÀÎÅÍ³Ý + media typeÀº º¯ÇÏÁö ¾Ê´Â´Ù.
    + +
    PreservesContentLength
    + +
    PreservesContentLength Å°¿öµå´Â ÇÊÅÍ°¡ + content length¸¦ À¯ÁöÇϵµ·Ï ÇÑ´Ù. ´ëºÎºÐÀÇ ÇÊÅÍ°¡ content + length¸¦ º¯°æÇϹǷΠÀÌ Å°¿öµå´Â ±âº»°ªÀÌ ¾Æ´Ï´Ù. ÇÊÅÍ°¡ + ±æÀ̸¦ À¯ÁöÇÒ¶§¸¸ ÀÌ Å°¿öµå¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    ftype=filtertype
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅÍ Á¾·ù¿¡ ´ëÇÑ ¼ýÀÚ°ªÀ» ÁöÁ¤ÇÑ´Ù. + ´ëºÎºÐÀÇ °æ¿ì ±âº»°ªÀÎ AP_FTYPE_RESOURCE°¡ Àû´çÇÏ´Ù. + ÇÊÅ͸¦ ½ÇÇàÇÏ´Â ¼ø¼­°¡ ÀÚ¿øÇÊÅÍ¿Í ´Þ¶ó¾ßÇÏ´Â °æ¿ì ÀÌ + ÆĶó¹ÌÅÍ°¡ ÇÊ¿äÇÏ´Ù. Àû´çÇÑ °ªÀ» ¾Ë·Á¸é util_filter.h¿¡ + ÀÖ´Â AP_FTYPE_* Á¤ÀǸ¦ Âü°íÇ϶ó.
    + +
    disableenv=env
    + +
    ÀÌ ÆĶó¹ÌÅÍ·Î ¼³Á¤ÇÑ È¯°æº¯¼ö°¡ Á¤ÀǵǾú´Ù¸é ÇÊÅ͸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    enableenv=env
    + +
    ÀÌ ÆĶó¹ÌÅÍ·Î ¼³Á¤ÇÑ È¯°æº¯¼ö°¡ Á¤ÀÇµÈ °æ¿ì ÇÊÅ͸¦ + »ç¿ëÇÑ´Ù.
    +
    + +
    +
    top
    +

    ExtFilterOptions Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:mod_ext_filter ¿É¼ÇÀ» ¼³Á¤ÇÑ´Ù
    ¹®¹ý:ExtFilterOptions option [option] ...
    ±âº»°ª:ExtFilterOptions DebugLevel=0 NoLogStderr
    »ç¿ëÀå¼Ò:directory
    »óÅÂ:Extension
    ¸ðµâ:mod_ext_filter
    +

    ExtFilterOptions Áö½Ã¾î´Â + mod_ext_filterÀÇ Æ¯º°ÇÑ Ã³¸®¿É¼ÇÀ» ÁöÁ¤ÇÑ´Ù. + OptionÀº ´ÙÀ½Áß Çϳª´Ù.

    + +
    +
    DebugLevel=n
    + +
    + DebugLevel Å°¿öµå´Â + mod_ext_filter°¡ ±â·ÏÇÏ´Â µð¹ö±× ¹®±¸ + ¼öÁØÀ» Á¤ÇÑ´Ù. ±âº»°ªÀº µð¹ö±×¹®À» ±â·ÏÇÏÁö ¾Ê´Â´Ù. + ÀÌ´Â DebugLevel=0°ú °°´Ù. ³ôÀº ¼ýÀÚ¸¦ + »ç¿ëÇÒ¼ö·Ï, ´õ ¸¹Àº µð¹ö±×¹®ÀÌ ±â·ÏµÇ°í ¼­¹ö ¼º´ÉÀÌ + ¶³¾îÁø´Ù. ¼ýÀÚ°ªÀÇ ½ÇÁ¦ Àǹ̴ mod_ext_filter.c + ¾ÕºÎºÐ¿¡ ÀÖ´Â DBGLVL_ »ó¼ö Á¤ÀÇ¿¡ ¼³¸íµÇÀÖ´Ù. + +

    ÁÖÀÇ: ÇÊÅÍ ·Î±×¸¦ ±â·ÏÇÏ·Á¸é core Áö½Ã¾î LogLevelÀ» »ç¿ëÇÏ¿© µð¹ö±×¹®À» + ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇØ¾ß ÇÑ´Ù.

    +
    + +
    LogStderr | NoLogStderr
    + +
    LogStderr Å°¿öµå´Â ¿ÜºÎ ÇÊÅÍ ÇÁ·Î±×·¥ÀÌ + Ç¥ÁØ¿À·ù·Î Ãâ·ÂÇÏ´Â ¹®±¸¸¦ ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇÑ´Ù. + NoLogStderr´Â ÀÌ ±â´ÉÀ» ÇÏÁö ¾Ê´Â´Ù.
    +
    + +

    ¿¹Á¦

    + ExtFilterOptions LogStderr DebugLevel=0 +

    + +

    À§ÀÇ ¼³Á¤À» »ç¿ëÇϸé ÇÊÅÍ°¡ Ç¥ÁØ¿À·ù·Î Ãâ·ÂÇÏ´Â ¹®±¸¸¦ + ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇÏ°í, mod_ext_filter´Â + ÀÚü µð¹ö±×¹®À» ±â·ÏÇÏÁö ¾Ê´Â´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ext_filter.xml b/trunk/docs/manual/mod/mod_ext_filter.xml new file mode 100644 index 0000000000..61a62d803d --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.xml @@ -0,0 +1,355 @@ + + + + + + + + + +mod_ext_filter +Pass the response body through an external program before +delivery to the client +Extension +mod_ext_filter.c +ext_filter_module + + +

    mod_ext_filter presents a simple and familiar + programming model for filters. With + this module, a program which reads from stdin and writes to stdout + (i.e., a Unix-style filter command) can be a filter for + Apache. This filtering mechanism is much slower than using a + filter which is specially written for the Apache API and runs + inside of the Apache server process, but it does have the + following benefits:

    + +
      +
    • the programming model is much simpler
    • + +
    • any programming/scripting language can be used, provided + that it allows the program to read from standard input and + write to standard output
    • + +
    • existing programs can be used unmodified as Apache + filters
    • +
    + +

    Even when the performance characteristics are not suitable + for production use, mod_ext_filter can be used as + a prototype environment for filters.

    + +
    +Filters + +
    Examples + +
    Generating HTML from some other type of response + + # mod_ext_filter directive to define a filter
    + # to HTML-ize text/c files using the external
    + # program /usr/bin/enscript, with the type of
    + # the result set to text/html
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # core directive to cause the new filter to
    + # be run on output
    + SetOutputFilter c-to-html
    +
    + # mod_mime directive to set the type of .c
    + # files to text/c
    + AddType text/c .c
    +
    + # mod_ext_filter directive to set the debug
    + # level just high enough to see a log message
    + # per request showing the configuration in force
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +
    +
    + +
    Implementing a content encoding filter +

    Note: this gzip example is just for the purposes of illustration. + Please refer to mod_deflate for a practical + implementation.

    + + + # mod_ext_filter directive to define the external filter
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # core directive to cause the gzip filter to be
    + # run on output
    + SetOutputFilter gzip
    +
    + # mod_header directive to add
    + # "Content-Encoding: gzip" header field
    + Header set Content-Encoding gzip
    +
    + </Location> +
    +
    + +
    Slowing down the server + + # mod_ext_filter directive to define a filter
    + # which runs everything through cat; cat doesn't
    + # modify anything; it just introduces extra pathlength
    + # and consumes more resources
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # core directive to cause the slowdown filter to
    + # be run several times on output
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +
    +
    + +
    Using sed to replace text in the response + + # mod_ext_filter directive to define a filter which
    + # replaces text in the response
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # core directive to cause the fixtext filter to
    + # be run on output
    + SetOutputFilter fixtext
    +
    + </Location> +
    +
    + +
    Tracing another filter + + # Trace the data read and written by mod_deflate
    + # for a particular client (IP 192.168.1.31)
    + # experiencing compression problems.
    + # This filter will trace what goes into mod_deflate.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # This filter will trace what goes after mod_deflate.
    + # Note that without the ftype parameter, the default
    + # filter type of AP_FTYPE_RESOURCE would cause the
    + # filter to be placed *before* mod_deflate in the filter
    + # chain. Giving it a numeric value slightly higher than
    + # AP_FTYPE_CONTENT_SET will ensure that it is placed
    + # after mod_deflate.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +
    + + Here is the filter which traces the data: + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +
    +
    +
    + + +ExtFilterDefine +Define an external filter +ExtFilterDefine filtername parameters +server config + + +

    The ExtFilterDefine directive defines the + characteristics of an external filter, including the program to + run and its arguments.

    + +

    filtername specifies the name of the filter being + defined. This name can then be used in SetOutputFilter + directives. It must be unique among all registered filters. + At the present time, no error is reported by the + register-filter API, so a problem with duplicate names isn't + reported to the user.

    + +

    Subsequent parameters can appear in any order and define the + external command to run and certain other characteristics. The + only required parameter is cmd=. These parameters + are:

    + +
    +
    cmd=cmdline
    + +
    The cmd= keyword allows you to specify the + external command to run. If there are arguments after the + program name, the command line should be surrounded in + quotation marks (e.g., cmd="/bin/mypgm + arg1 arg2".) Normal shell quoting is + not necessary since the program is run directly, bypassing the shell. + Program arguments are blank-delimited. A backslash can be used to + escape blanks which should be part of a program argument. Any + backslashes which are part of the argument must be escaped with + backslash themselves. In addition to the standard CGI environment + variables, DOCUMENT_URI, DOCUMENT_PATH_INFO, and + QUERY_STRING_UNESCAPED will also be set for the program.
    + +
    mode=mode
    + +
    Use mode=output (the default) for filters which + process the response. Use mode=input for filters + which process the request. mode=input is new with + Apache 2.1.
    + +
    intype=imt
    + +
    This parameter specifies the internet media type (i.e., + MIME type) of documents which should be filtered. By default, + all documents are filtered. If intype= is + specified, the filter will be disabled for documents of other + types.
    + +
    outtype=imt
    + +
    This parameter specifies the internet media type (i.e., + MIME type) of filtered documents. It is useful when the + filter changes the internet media type as part of the + filtering operation. By default, the internet media type is + unchanged.
    + +
    PreservesContentLength
    + +
    The PreservesContentLength keyword specifies + that the filter preserves the content length. This is not the + default, as most filters change the content length. In the + event that the filter doesn't modify the length, this keyword + should be specified.
    + +
    ftype=filtertype
    + +
    This parameter specifies the numeric value for filter type + that the filter should be registered as. The default value, + AP_FTYPE_RESOURCE, is sufficient in most cases. If the filter + needs to operate at a different point in the filter chain than + resource filters, then this parameter will be necessary. See + the AP_FTYPE_foo definitions in util_filter.h for appropriate + values.
    + +
    disableenv=env
    + +
    This parameter specifies the name of an environment variable + which, if set, will disable the filter.
    + +
    enableenv=env
    + +
    This parameter specifies the name of an environment variable + which must be set, or the filter will be disabled.
    +
    +
    +
    + + +ExtFilterOptions +Configure mod_ext_filter options +ExtFilterOptions option [option] ... +ExtFilterOptions DebugLevel=0 NoLogStderr +directory + + +

    The ExtFilterOptions directive specifies + special processing options for mod_ext_filter. + Option can be one of

    + +
    +
    DebugLevel=n
    + +
    + The DebugLevel keyword allows you to specify + the level of debug messages generated by + mod_ext_filter. By default, no debug messages + are generated. This is equivalent to + DebugLevel=0. With higher numbers, more debug + messages are generated, and server performance will be + degraded. The actual meanings of the numeric values are + described with the definitions of the DBGLVL_ constants + near the beginning of mod_ext_filter.c. + +

    Note: The core directive LogLevel should be used to cause debug messages to + be stored in the Apache error log.

    +
    + +
    LogStderr | NoLogStderr
    + +
    The LogStderr keyword specifies that + messages written to standard error by the external filter + program will be saved in the Apache error log. + NoLogStderr disables this feature.
    +
    + + Example + ExtFilterOptions LogStderr DebugLevel=0 + + +

    Messages written to the filter's standard error will be stored + in the Apache error log. No debug messages will be generated by + mod_ext_filter.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_ext_filter.xml.ja b/trunk/docs/manual/mod/mod_ext_filter.xml.ja new file mode 100644 index 0000000000..9698644617 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.xml.ja @@ -0,0 +1,344 @@ + + + + + + + + + +mod_ext_filter +$B%l%9%]%s%9$N%\%G%#$r%/%i%$%"%s%H$KAw$kA0$K30It%W%m%0%i%`$G=hM}$9$k(B +Extension +mod_ext_filter.c +ext_filter_module + + +

    mod_ext_filter $B$G$O(B $B%U%#%k%?(B + $B$N47$l?F$7$s$@C1=c$J%W%m%0%i%_%s%0%b%G%k$,Ds6!$5$l$^$9!#$3$N%b%8%e!<%k$r(B + $B;H$($P!"I8=`F~NO$+$iFI$_9~$s$G!"I8=`=PNO$K=q$-=P$9%W%m%0%i%`(B + ($B$9$J$o$A(B Unix $B7A<0$N%U%#%k%?%3%^%s%I(B) $B$r(B Apache $B$N%U%#%k%?$K$9$k$3$H$,(B + $B$G$-$^$9!#$3$N%U%#%k%?$N5!9=$O!"(BApache API $B8~$1$K=q$+$l$?(B Apache + $B%5!<%P%W%m%;%9Fb$G + +

      +
    • $B$:$C$H%7%s%W%k$J%W%m%0%i%_%s%0%b%G%k(B
    • + +
    • $B%W%m%0%i%`$,I8=`F~NO$+$iFI$s$GI8=`=PNO$K=q$/$b$N$G$"$k8B$j!"(B + $B$I$s$J%W%m%0%i%`8@8l$d%9%/%j%W%H8@8l$G$b;H$&$3$H$,$G$-$k(B
    • + +
    • $B4{B8$N%W%m%0%i%`$rJQ99$9$k$3$H$J$/(B Apache $B$N%U%#%k%?$H$7$F(B + $B;H$&$3$H$,$G$-$k(B
    • +
    + +

    $B@-G=$NLdBj$K$h$jmod_ext_filter $B$O;H$($^$9!#(B

    + +
    +$B%U%#%k%?(B + +
    $BNc(B + +
    $BB>$N%?%$%W$N%l%9%]%s%9$+$i(B HTML $B$r@8@.$9$k(B + + # mod_ext_filter directive to define a filter
    + # to HTML-ize text/c files using the external
    + # program /usr/bin/enscript, with the type of
    + # the result set to text/html
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # core directive to cause the new filter to
    + # be run on output
    + SetOutputFilter c-to-html
    +
    + # mod_mime directive to set the type of .c
    + # files to text/c
    + AddType text/c .c
    +
    + # mod_ext_filter directive to set the debug
    + # level just high enough to see a log message
    + # per request showing the configuration in force
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +
    +
    + +
    $B%3%s%F%s%H%(%s%3!<%G%#%s%0$N%U%#%k%?$r<BAu$9$k(B +

    $BCm(B: $B$3$N(B gzip $B$NNc$O%G%bMQ$G$9!#mod_deflate $B$r;2>H$7$F$/$@$5$$!#(B

    + + + # mod_ext_filter directive to define the external filter
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # core directive to cause the gzip filter to be
    + # run on output
    + SetOutputFilter gzip
    +
    + # mod_header directive to add
    + # "Content-Encoding: gzip" header field
    + Header set Content-Encoding gzip
    +
    + </Location> +
    +
    + +
    $B%5!<%P$rCY$/$9$k(B + + # mod_ext_filter directive to define a filter
    + # which runs everything through cat; cat doesn't
    + # modify anything; it just introduces extra pathlength
    + # and consumes more resources
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # core directive to cause the slowdown filter to
    + # be run several times on output
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +
    +
    + +
    sed $B$r;H$C$F1~EzCf$N%F%-%9%H$rCV49$9$k(B + + # mod_ext_filter directive to define a filter which
    + # replaces text in the response
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # core directive to cause the fixtext filter to
    + # be run on output
    + SetOutputFilter fixtext
    +
    + </Location> +
    +
    + +
    $BJL$N%U%#%k%?$N%H%l!<%9(B + + # Trace the data read and written by mod_deflate
    + # for a particular client (IP 192.168.1.31)
    + # experiencing compression problems.
    + # This filter will trace what goes into mod_deflate.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # This filter will trace what goes after mod_deflate.
    + # Note that without the ftype parameter, the default
    + # filter type of AP_FTYPE_RESOURCE would cause the
    + # filter to be placed *before* mod_deflate in the filter
    + # chain. Giving it a numeric value slightly higher than
    + # AP_FTYPE_CONTENT_SET will ensure that it is placed
    + # after mod_deflate.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +
    + + $B%G!<%?$r%H%l!<%9$9$k%U%#%k%?(B: + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +
    +
    +
    + + +ExtFilterDefine +$B30It%U%#%k%?$rDj5A(B +ExtFilterDefine filtername parameters +server config + + +

    ExtFilterDefine $B$O!" + +

    filtername $B$ODj5A$9$k%U%#%k%?$NL>A0$r;XDj$7$^$9!#(B + $B$3$NL>A0$O8e$G(B SetOutputFilter + $B%G%#%l%/%F%#%V$G;XDj$G$-$^$9!#L>A0$OEPO?$5$l$k$9$Y$F$N%U%#%k%?$G(B + $B0l0U$G$J$/$F$O$J$j$^$;$s!#(B$B8=;~E@$G$O!"%U%#%k%?$NEPO?(B API $B$+$i$O(B + $B%(%i!<$OJs9p$5$l$^$;$s!#$G$9$+$i!"=EJ#$9$kL>A0$r;H$C$F$7$^$C$?$H$-$G$b(B + $B%f!<%6$K$O$=$N$3$H$OJs9p$5$l$^$;$s!#(B

    + +

    $BB3$/%Q%i%a!<%?$N=gHV$O4X78L5$/!"$=$l$i$O$NFC@-$rDj5A$7$^$9!#(Bcmd= $B$@$1$,I,?\$N%Q%i%a!<%?$G$9!#(B + $B;XDj2DG=$J%Q%i%a!<%?$O(B:

    + +
    +
    cmd=cmdline
    + +
    cmd= $B%-!<%o!<%I$O$N8e$K0z?t$,$"$k>l9g$O!"%3%^%s%I9T$O0zMQId$G0O$`(B + $BI,MW$,$"$j$^$9(B ($BNc$($P(B$B!"(Bcmd="/bin/mypgm + arg1 arg2" $B$N$h$&$K(B)$B!#%W%m%0%i%`$O(B + $B%7%'%k7PM3$G$J$/!"D>@\o$N%7%'%kMQ$N(B + $B%(%9%1!<%W$OI,MW$"$j$^$;$s!#%W%m%0%i%`$N0z?t$O6uGr$G6h@Z$i$l$^$9!#(B + $B%W%m%0%i%`$N0z?t$N0lIt$H$J$kI,MW$N$"$k6uGr$O%P%C%/%9%Z!<%9$G%(%9%1!<%W(B + $B$G$-$^$9!#0z?t$N0lIt$K$J$k%P%C%/%9%i%C%7%e$O%P%C%/%9%i%C%7%e$G(B + $B%(%9%1!<%W$9$kI,MW$,$"$j$^$9!#I8=`$N(B CGI $B4D6-JQ?t$K2C$($F!"(B + $B4D6-JQ?t(B DOCUMENT_URI, DOCUMENT_PATH_INFO, and + QUERY_STRING_UNESCAPED $B$,%W%m%0%i%`$N$?$a$K@_Dj$5$l$^$9!#(B
    + +
    mode=mode
    + +
    $B1~Ez$r=hM}$9$k%U%#%k%?$K$O(B mode=output ($B%G%U%)%k%H(B) + $B$r;H$$$^$9!#%j%/%(%9%H$r=hM}$9$k%U%#%k%?$K$O(B mode=input + $B$r;H$$$^$9!#(Bmode=input $B$O(B Apache 2.1 $B$+$i$N?7$7$$5!G=$G$9!#(B
    + +
    intype=imt
    + +
    $B$3$N%Q%i%a!<%?$O%U%#%k%?$5$l$k$Y$-%I%-%e%a%s%H$N(B + $B%$%s%?!<%M%C%H%a%G%#%"%?%$%W(B ($B$9$J$o$A(B$B!"(BMIME $B%?%$%W(B) $B$r(B + $B;XDj$7$^$9!#%G%U%)%k%H$G$O$9$Y$F$N%I%-%e%a%s%H$,%U%#%k%?$5$l$^$9!#(B + intype= $B$,;XDj$5$l$F$$$l$P!"%U%#%k%?$O;XDj$5$l$F$$$J$$(B + $B%I%-%e%a%s%H$K$OE,MQ$5$l$J$/$J$j$^$9!#(B
    + +
    outtype=imt
    + +
    $B$3$N%Q%i%a!<%?$O%U%#%k%?$5$l$?%I%-%e%a%s%H$N(B + $B%$%s%?!<%M%C%H%a%G%#%"%?%$%W(B ($B$9$J$o$A(B$B!"(BMIME $B%?%$%W(B) $B$r(B + $B;XDj$7$^$9!#%U%#%k%?F0:n$K$H$b$J$C$F%$%s%?!<%M%C%H%a%G%#%"%?%$%W$,(B + $BJQ$o$k>l9g$KM-MQ$G$9!#%G%U%)%k%H$G$O%$%s%?!<%M%C%H%a%G%#%"%?%$%W$O(B + $BJQ99$5$l$^$;$s!#(B
    + +
    PreservesContentLength
    + +
    PreservesContentLength $B%-!<%o!<%I$O%U%#%k%?$,(B + content length $B%3%s%F%s%H$ND9$5(B + $B$rJQ99$7$J$$$H$$$&$3$H$r;XDj$7$^$9!#$[$H$s$I$N%U%#%k%?$O(B + content length $B$rJQ99$9$k$?$a!"$3$l$O%G%U%)%k%H$G$O$"$j$^$;$s!#(B + $B%U%#%k%?$,D9$5$rJQ$($J$$$H$-$O!"$3$N%-!<%o!<%I$r;XDj$9$k$H(B + $B$h$$$G$7$g$&!#(B
    + +
    ftype=filtertype
    + +
    $B$3$N%Q%i%a!<%?$O%U%#%k%?$,EPO?$5$l$k$Y$-%U%#%k%?%?%$%W$N(B + $B?tCM$r;XDj$7$^$9!#$[$H$s$I$N>l9g$O!"%G%U%)%k%H$N(B AP_FTYPE_RESOURCE $B$G(B + $B==J,$G$9!#%U%#%k%?$,%U%#%k%?%A%'!<%s$NJL$N>l=j$GF0:n$9$kI,MW$,$"$k(B + $B>l9g$O!"$3$N%Q%i%a!<%?$r;XDj$9$kI,MW$,$"$j$^$9!#;XDj2DG=$JCM$O(B + util_filter.h $B$N(B AP_FTYPE_foo $BDj5A$r;2>H$7$F$/$@$5$$!#(B
    + +
    disableenv=env
    + +
    $B@_Dj$5$l$F$$$?>l9g$K%U%#%k%?$rL58z$K$9$k$?$a$N4D6-JQ?t$r(B + $B;XDj$7$^$9!#(B
    + +
    enableenv=env
    + +
    $B$3$N%Q%i%a!<%?$O%U%#%k%?$,M-8z$K$J$k$?$a$K@_Dj$5$l$F$$$J$1$l$P(B + $B$J$i$J$$4D6-JQ?t$r;XDj$7$^$9!#(B
    +
    +
    +
    + + +ExtFilterOptions +mod_ext_filter $B$N%*%W%7%g%s$r@_Dj(B +ExtFilterOptions option [option] ... +ExtFilterOptions DebugLevel=0 NoLogStderr +directory + + +

    ExtFilterOptions $B%G%#%l%/%F%#%V$O(B + mod_ext_filter $B$NFCJL$J=hM}MQ$N%*%W%7%g%s$r(B + $B;XDj$7$^$9!#(BOption $B$K$O0J2<$N$I$l$+$r;XDj$7$^$9!#(B

    + +
    +
    DebugLevel=n
    + +
    + DebugLevel $B$G(B mod_ext_filter + $B$N@8@.$9$k%G%P%C%0%a%C%;!<%8$N%l%Y%k$r@_Dj$G$-$^$9!#(B + $B%G%U%)%k%H$G$O!"%G%P%C%0%a%C%;!<%8$O@8@.$5$l$^$;$s!#(B + $B$3$l$O(B DebugLevel=0 $B$H@_Dj$9$k$N$HF1$8$G$9!#(B + $B?t;z$,Bg$-$/$J$l$P$J$k$[$I!"$h$jB?$/$N%G%P%C%0%a%C%;!<%8$,(B + $B@8@.$5$l!"%5!<%P$N@-G=$OMn$A$^$9!#?tCM$Nmod_ext_filter.c $B$N@hF,6a$/$N(B DBGLVL_ $BDj?t$N(B + $BDj5A$G@bL@$5$l$F$$$^$9!#(B + +

    $BCm(B: $B%G%P%C%0%a%C%;!<%8$r(B Apache $B$N%(%i!<%m%0$K(B + $BJ]B8$9$k$h$&$K$9$k$?$a$K$O!"(Bcore $B$N%G%#%l%/%F%#%V(B + LogLevel + $B$r;H$&I,MW$,$"$j$^$9!#(B

    +
    + +
    LogStderr | NoLogStderr
    + +
    LogStderr $B%-!<%o!<%I$O30It%U%#%k%?%W%m%0%i%`$K$h$j(B + $BI8=`%(%i!<(B stderr $B$K=q$+$l$?%a%C%;!<%8$r(B + Apache $B$N%(%i!<%m%0$KJ]B8$9$k$h$&$K$7$^$9!#(BNoLogStderr $B$O(B + $B5U$KJ]B8$7$J$$$h$&$K$7$^$9!#(B
    +
    + + $BNc(B + ExtFilterOptions LogStderr DebugLevel=0 + + +

    $B$3$NNc$G$O!"%U%#%k%?$NI8=`=PNO$K=q$+$l$?%a%C%;!<%8$O(B + Apache $B$N%(%i!<%m%0$KJ]B8$5$l$^$9!#(Bmod_ext_filter $B$+$i$O(B + $B%G%P%C%0%a%C%;!<%8$O@8@.$5$l$^$;$s!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_ext_filter.xml.ko b/trunk/docs/manual/mod/mod_ext_filter.xml.ko new file mode 100644 index 0000000000..2d68dd5a8b --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.xml.ko @@ -0,0 +1,330 @@ + + + + + + + + + +mod_ext_filter +ÀÀ´ä ³»¿ëÀ» ¿ÜºÎ ÇÁ·Î±×·¥À¸·Î ó¸®ÇÑ ÈÄ Å¬¶óÀ̾ðÆ®·Î +º¸³½´Ù +Extension +mod_ext_filter.c +ext_filter_module + + +

    mod_ext_filter¸¦ »ç¿ëÇÏ¸é °£´ÜÇÏ°í Àͼ÷ÇÑ + ¹æ¹ýÀ¸·Î ÇÊÅ͸¦ ¸¸µé ¼ö ÀÖ´Ù. + Ç¥ÁØÀԷ¿¡¼­ Àаí Ç¥ÁØÃâ·Â¿¡ ¾²´Â ÇÁ·Î±×·¥(Áï, À¯´Ð½º½Ä + ÇÊÅÍ ¸í·É¾î)À» ¾ÆÆÄÄ¡ ÇÊÅÍ·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ·± ÇÊÅÍ´Â + ¾ÆÆÄÄ¡ API·Î ¾²¿©Áö°í ¾ÆÆÄÄ¡ ¼­¹ö ÇÁ·Î¼¼½º ¾È¿¡¼­ ½ÇÇàµÇ´Â + ÇÊÅÍ¿¡ ºñÇØ ¸Å¿ì ´À¸®Áö¸¸, ´ÙÀ½°ú °°Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    • ÇÁ·Î±×·¡¹Ö ¸ðµ¨ÀÌ ¸Å¿ì °£´ÜÇÏ´Ù
    • + +
    • ÇÁ·Î±×·¥ÀÌ Ç¥ÁØÀԷ¿¡¼­ Àаí Ç¥ÁØÃâ·Â¿¡ ¾µ ¼ö¸¸ ÀÖ´Ù¸é + ¾î¶² ÇÁ·Î±×·¡¹Ö/½ºÅ©¸³Æ® ¾ð¾î¶óµµ »ç¿ëÇÒ ¼ö ÀÖ´Ù
    • + +
    • ÀÌ¹Ì ÀÖ´Â ÇÁ·Î±×·¥À» ¼öÁ¤¾øÀÌ ¾ÆÆÄÄ¡ ÇÊÅÍ·Î »ç¿ëÇÒ + ¼ö ÀÖ´Ù
    • +
    + +

    ½ÇÁ¦ »ç¿ëÇϱ⿡´Â ¼º´ÉÀÌ ¶³¾îÁöÁö¸¸, + mod_ext_filter¸¦ »ç¿ëÇÏ¿© ÇÊÅ͸¦ »¡¸® ¸¸µé¾îº¼ + ¼ö ÀÖ´Ù.

    + +
    +ÇÊÅÍ + +
    ¿¹Á¦ + +
    ´Ù¸¥ typeÀÇ ÀÀ´äÀ» HTML·Î ¸¸µç´Ù + + # mod_ext_filter Áö½Ã¾î¸¦ °¡Áö°í
    + # ¿ÜºÎ ÇÁ·Î±×·¥ /usr/bin/enscript¸¦ »ç¿ëÇÏ¿©
    + # ¹®¼­ÆÄÀÏ°ú text/c ÆÄÀÏÀ» HTML·Î ¸¸µé°í °á°úÀÇ
    + # typeÀ» text/html·Î º¯°æÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÑ´Ù
    + ExtFilterDefine c-to-html mode=output \
    + + intype=text/c outtype=text/html \
    + cmd="/usr/bin/enscript --color -W html -Ec -o - -"
    +
    +
    + <Directory "/export/home/trawick/apacheinst/htdocs/c">
    + + # Ãâ·Â¿¡ »õ·Î¿î ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter c-to-html
    +
    + # .c ÆÄÀÏÀÇ typeÀ» text/c·Î ¸¸µå´Â mod_mime
    + # Áö½Ã¾î
    + AddType text/c .c
    +
    + # µð¹ö±× ¼öÁØÀ» ³ô¿©¼­ ¿äû¸¶´Ù ÇöÀç ¼³Á¤À»
    + # ¾Ë·ÁÁÖ´Â ·Î±×¹®À» ±â·ÏÇÏ´Â mod_ext_filter
    + # Áö½Ã¾î
    + ExtFilterOptions DebugLevel=1
    +
    + </Directory> +
    +
    + +
    content ÀÎÄÚµù ÇÊÅÍ ±¸ÇöÇϱâ +

    Note: ¾Æ·¡ gzip ¿¹Á¦´Â ´ÜÁö ¼³¸íÀ» ¿¹·Î µç °ÍÀÌ´Ù. + ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÏ·Á¸é mod_deflate¸¦ + Âü°íÇÏ±æ ¹Ù¶õ´Ù.

    + + + # ¿ÜºÎ ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â mod_ext_filter Áö½Ã¾î
    + ExtFilterDefine gzip mode=output cmd=/bin/gzip
    +
    + <Location /gzipped>
    + + # Ãâ·ÂÇÒ¶§ gzip ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter gzip
    +
    + # "Content-Encoding: gzip" Çì´õ¸¦ Ãß°¡ÇÏ´Â
    + # mod_header Áö½Ã¾î
    + Header set Content-Encoding gzip
    +
    + </Location> +
    +
    + +
    ¼­¹ö¸¦ ´À¸®°Ô Çϱâ + + # catÀ¸·Î ¸ðµç ³»¿ëÀ» Åë°úÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â
    + # mod_ext_filter Áö½Ã¾î; catÀº ¾Æ¹«°Íµµ ¼öÁ¤ÇÏÁö
    + # ¾Ê´Â´Ù; ´ÜÁö 󸮰æ·Î¸¦ ±æ°Ô ÇÏ¿© ÀÚ¿øÀ» ´õ ¼Ò¸ðÇÑ´Ù
    + ExtFilterDefine slowdown mode=output cmd=/bin/cat \
    + + preservescontentlength
    +
    +
    + <Location />
    + + # Ãâ·ÂÇÒ¶§ slowdown ÇÊÅ͸¦ ¿©·¯¹ø ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + #
    + SetOutputFilter slowdown;slowdown;slowdown
    +
    + </Location> +
    +
    + +
    sed¸¦ »ç¿ëÇÏ¿© ÀÀ´ä¿¡¼­ ±ÛÀ» ´ëüÇϱâ + + # ÀÀ´ä¿¡¼­ ±ÛÀ» ´ëüÇÏ´Â ÇÊÅ͸¦ Á¤ÀÇÇÏ´Â
    + # mod_ext_filter Áö½Ã¾î
    + #
    + ExtFilterDefine fixtext mode=output intype=text/html \
    + + cmd="/bin/sed s/verdana/arial/g"
    +
    +
    + <Location />
    + + # Ãâ·ÂÇÒ¶§ fixtext ÇÊÅ͸¦ ½ÇÇàÇÏ´Â core Áö½Ã¾î
    + SetOutputFilter fixtext
    +
    + </Location> +
    +
    + +
    ´Ù¸¥ ÇÊÅ͸¦ ÃßÀûÇϱâ + + # ¾ÐÃà ¹®Á¦°¡ Àִ ƯÁ¤ Ŭ¶óÀ̾ðÆ®(IP 192.168.1.31)¿¡
    + # ´ëÇØ mod_deflate°¡ ÀÐ°í ¾²´Â ÀڷḦ ÃßÀûÇÑ´Ù.
    + # ÀÌ ÇÊÅÍ´Â mod_deflate·Î º¸³»±â Àü ÀڷḦ ÃßÀûÇÑ´Ù.
    + ExtFilterDefine tracebefore \
    + + cmd="/bin/tracefilter.pl /tmp/tracebefore" \
    + EnableEnv=trace_this_client
    +
    +
    + # ÀÌ ÇÊÅÍ´Â mod_deflate¿¡¼­ ³ª¿À´Â ÀڷḦ ÃßÀûÇÑ´Ù.
    + # ftype ÆĶó¹ÌÅ͸¦ »ç¿ëÇÏÁö¾Ê´Â °æ¿ì, ±âº» ÇÊÅÍÇü
    + # AP_FTYPE_RESOURCE´Â ÇÊÅÍ ¼ø¼­¸¦ mod_deflate *ÀÌÀü¿¡*
    + # µÐ´Ù. AP_FTYPE_CONTENT_SET º¸´Ù Á¶±Ý ³ôÀº ¼ýÀÚ°ªÀ»
    + # ÁöÁ¤Çϸé mod_deflate ÀÌÈÄ¿¡ ½ÇÇàÇÑ´Ù.
    + ExtFilterDefine traceafter \
    + + cmd="/bin/tracefilter.pl /tmp/traceafter" \
    + EnableEnv=trace_this_client ftype=21
    +
    +
    + <Directory /usr/local/docs>
    + + SetEnvIf Remote_Addr 192.168.1.31 trace_this_client
    + SetOutputFilter tracebefore;deflate;traceafter
    +
    + </Directory> +
    + + ´ÙÀ½Àº ÀڷḦ ÃßÀûÇÏ´Â ÇÊÅÍÀÌ´Ù: + #!/usr/local/bin/perl -w
    + use strict;
    +
    + open(SAVE, ">$ARGV[0]")
    + + or die "can't open $ARGV[0]: $?";
    +
    +
    + while (<STDIN>) {
    + + print SAVE $_;
    + print $_;
    +
    + }
    +
    + close(SAVE); +
    +
    +
    + + +ExtFilterDefine +¿ÜºÎ ÇÊÅ͸¦ Á¤ÀÇÇÑ´Ù +ExtFilterDefine filtername parameters +server config + + +

    ExtFilterDefine Áö½Ã¾î´Â ¿ÜºÎ + ÇÊÅÍÀÇ ¼ºÁú°ú ½ÇÇàÇÒ ÇÁ·Î±×·¥, ¾Æ±Ô¸ÕÆ®¸¦ Á¤ÀÇÇÑ´Ù.

    + +

    filternameÀº Á¤ÀÇÇÒ ÇÊÅÍ À̸§À» ÁöÁ¤ÇÑ´Ù. + ÀÌ À̸§À» SetOutputFilter Áö½Ã¾î¿¡¼­ »ç¿ëÇÑ´Ù. µî·ÏÇÑ ¸ðµç + ÇÊÅ͵鰣¿¡ À̸§ÀÌ °ãÄ¡¸é ¾ÈµÈ´Ù. ÇöÀç ÇÊÅ͵î·Ï API´Â + ¿À·ù¸¦ º¸°íÇÏÁö ¾Ê´Â´Ù. ±×·¡¼­ »ç¿ëÀÚ´Â À̸§ÀÌ °ãÄ¡´Â ¹®Á¦¸¦ + ¾ËÁö ¸øÇÑ´Ù.

    + +

    ½ÇÇàÇÒ ¿ÜºÎ ¸í·É¾î¿Í ´Ù¸¥ ¼ºÁúÀ» Á¤ÀÇÇÏ´Â ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®´Â + ¾î¶² ¼ø¼­·Î ³ª¿Íµµ °¡´ÉÇÏ´Ù. ´Ü, cmd= ÆĶó¹ÌÅÍ´Â + ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ÆĶó¹ÌÅÍ´Â ´ÙÀ½°ú °°´Ù:

    + +
    +
    cmd=cmdline
    + +
    cmd= Å°¿öµå´Â ½ÇÇàÇÒ ¿ÜºÎ ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù. + ÇÁ·Î±×·¥¸í µÚ¿¡ ¾Æ±Ô¸ÕÆ®°¡ ÀÖ´Ù¸é ¸í·ÉÇàÀ» ½Öµû¿ÈÇ¥·Î + ¹­¾î¾ß ÇÑ´Ù (¿¹¸¦ µé¾î, + cmd="/bin/mypgm arg1 + arg2"). ½©À» °ÅÄ¡Áö¾Ê°í Á÷Á¢ ÇÁ·Î±×·¥À» + ½ÇÇàÇϱ⶧¹®¿¡ ÀϹÝÀûÀÎ ½© µû¿ÈÇ¥´Â ÇÊ¿ä¾ø´Ù. ÇÁ·Î±×·¥ + ¾Æ±Ô¸ÕÆ®µéÀº °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. ÇÁ·Î±×·¥ ¾Æ±Ô¸ÕÆ®¿¡ °ø¹éÀÌ + ÀÖ´Ù¸é °ø¹é ¾Õ¿¡ ¹é½½·¡½¬·Î »ç¿ëÇØ¾ß ÇÑ´Ù. ¹é½½·¡½¬°¡ + ¾Æ±Ô¸ÕÆ®ÀÇ ÀϺζó¸é ¹é½½·¡½¬¸¦ µÎ¹ø »ç¿ëÇØ¾ß ÇÑ´Ù. ÇÁ·Î±×·¥À» + ½ÇÇàÇÒ¶§ Ç¥ÁØ CGI ȯ°æº¯¼ö¿Í Ãß°¡·Î DOCUMENT_URI, + DOCUMENT_PATH_INFO, QUERY_STRING_UNESCAPED º¯¼ö¸¦ ¼³Á¤ÇÑ´Ù.
    + +
    mode=mode
    + +
    ÀÀ´äÀ» ó¸®ÇÏ´Â ÇÊÅÍ´Â (±âº»°ªÀÎ) mode=outputÀ» + »ç¿ëÇÑ´Ù. ¿äûÀ» ó¸®ÇÏ´Â ÇÊÅÍ´Â mode=inputÀ» + »ç¿ëÇÑ´Ù. mode=inputÀº ¾ÆÆÄÄ¡ 2.1¿¡ Ãß°¡µÇ¾ú´Ù.
    + +
    intype=imt
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅͷΠó¸®ÇÒ ¹®¼­ÀÇ ÀÎÅÍ³Ý media + type(Áï, MIME type)À» ÁöÁ¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ¸ðµç + ¹®¼­¸¦ ÇÊÅͷΠó¸®ÇÑ´Ù. intype=À» ÁöÁ¤Çϸé + ´Ù¸¥ typeÀÇ ¹®¼­´Â ÇÊÅͷΠó¸®ÇÏÁö ¾Ê´Â´Ù.
    + +
    outtype=imt
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅͷΠó¸®ÇÑ ¹®¼­ÀÇ ÀÎÅÍ³Ý media + type(Áï, MIME type)À» ÁöÁ¤ÇÑ´Ù. ÇÊÅÍó¸® ÀÛ¾÷Áß¿¡ + ÀÎÅÍ³Ý media typeÀ» º¯°æÇÒ¶§ À¯¿ëÇÏ´Ù. ±âº»ÀûÀ¸·Î, ÀÎÅÍ³Ý + media typeÀº º¯ÇÏÁö ¾Ê´Â´Ù.
    + +
    PreservesContentLength
    + +
    PreservesContentLength Å°¿öµå´Â ÇÊÅÍ°¡ + content length¸¦ À¯ÁöÇϵµ·Ï ÇÑ´Ù. ´ëºÎºÐÀÇ ÇÊÅÍ°¡ content + length¸¦ º¯°æÇϹǷΠÀÌ Å°¿öµå´Â ±âº»°ªÀÌ ¾Æ´Ï´Ù. ÇÊÅÍ°¡ + ±æÀ̸¦ À¯ÁöÇÒ¶§¸¸ ÀÌ Å°¿öµå¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    ftype=filtertype
    + +
    ÀÌ ÆĶó¹ÌÅÍ´Â ÇÊÅÍ Á¾·ù¿¡ ´ëÇÑ ¼ýÀÚ°ªÀ» ÁöÁ¤ÇÑ´Ù. + ´ëºÎºÐÀÇ °æ¿ì ±âº»°ªÀÎ AP_FTYPE_RESOURCE°¡ Àû´çÇÏ´Ù. + ÇÊÅ͸¦ ½ÇÇàÇÏ´Â ¼ø¼­°¡ ÀÚ¿øÇÊÅÍ¿Í ´Þ¶ó¾ßÇÏ´Â °æ¿ì ÀÌ + ÆĶó¹ÌÅÍ°¡ ÇÊ¿äÇÏ´Ù. Àû´çÇÑ °ªÀ» ¾Ë·Á¸é util_filter.h¿¡ + ÀÖ´Â AP_FTYPE_* Á¤ÀǸ¦ Âü°íÇ϶ó.
    + +
    disableenv=env
    + +
    ÀÌ ÆĶó¹ÌÅÍ·Î ¼³Á¤ÇÑ È¯°æº¯¼ö°¡ Á¤ÀǵǾú´Ù¸é ÇÊÅ͸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    enableenv=env
    + +
    ÀÌ ÆĶó¹ÌÅÍ·Î ¼³Á¤ÇÑ È¯°æº¯¼ö°¡ Á¤ÀÇµÈ °æ¿ì ÇÊÅ͸¦ + »ç¿ëÇÑ´Ù.
    +
    +
    +
    + + +ExtFilterOptions +mod_ext_filter ¿É¼ÇÀ» ¼³Á¤ÇÑ´Ù +ExtFilterOptions option [option] ... +ExtFilterOptions DebugLevel=0 NoLogStderr +directory + + +

    ExtFilterOptions Áö½Ã¾î´Â + mod_ext_filterÀÇ Æ¯º°ÇÑ Ã³¸®¿É¼ÇÀ» ÁöÁ¤ÇÑ´Ù. + OptionÀº ´ÙÀ½Áß Çϳª´Ù.

    + +
    +
    DebugLevel=n
    + +
    + DebugLevel Å°¿öµå´Â + mod_ext_filter°¡ ±â·ÏÇÏ´Â µð¹ö±× ¹®±¸ + ¼öÁØÀ» Á¤ÇÑ´Ù. ±âº»°ªÀº µð¹ö±×¹®À» ±â·ÏÇÏÁö ¾Ê´Â´Ù. + ÀÌ´Â DebugLevel=0°ú °°´Ù. ³ôÀº ¼ýÀÚ¸¦ + »ç¿ëÇÒ¼ö·Ï, ´õ ¸¹Àº µð¹ö±×¹®ÀÌ ±â·ÏµÇ°í ¼­¹ö ¼º´ÉÀÌ + ¶³¾îÁø´Ù. ¼ýÀÚ°ªÀÇ ½ÇÁ¦ Àǹ̴ mod_ext_filter.c + ¾ÕºÎºÐ¿¡ ÀÖ´Â DBGLVL_ »ó¼ö Á¤ÀÇ¿¡ ¼³¸íµÇÀÖ´Ù. + +

    ÁÖÀÇ: ÇÊÅÍ ·Î±×¸¦ ±â·ÏÇÏ·Á¸é core Áö½Ã¾î LogLevelÀ» »ç¿ëÇÏ¿© µð¹ö±×¹®À» + ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇØ¾ß ÇÑ´Ù.

    +
    + +
    LogStderr | NoLogStderr
    + +
    LogStderr Å°¿öµå´Â ¿ÜºÎ ÇÊÅÍ ÇÁ·Î±×·¥ÀÌ + Ç¥ÁØ¿À·ù·Î Ãâ·ÂÇÏ´Â ¹®±¸¸¦ ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇÑ´Ù. + NoLogStderr´Â ÀÌ ±â´ÉÀ» ÇÏÁö ¾Ê´Â´Ù.
    +
    + + ¿¹Á¦ + ExtFilterOptions LogStderr DebugLevel=0 + + +

    À§ÀÇ ¼³Á¤À» »ç¿ëÇϸé ÇÊÅÍ°¡ Ç¥ÁØ¿À·ù·Î Ãâ·ÂÇÏ´Â ¹®±¸¸¦ + ¾ÆÆÄÄ¡ ¿À·ù·Î±×¿¡ ±â·ÏÇÏ°í, mod_ext_filter´Â + ÀÚü µð¹ö±×¹®À» ±â·ÏÇÏÁö ¾Ê´Â´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_ext_filter.xml.meta b/trunk/docs/manual/mod/mod_ext_filter.xml.meta new file mode 100644 index 0000000000..3cf7e6ec18 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ext_filter.xml.meta @@ -0,0 +1,13 @@ + + + + mod_ext_filter + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_file_cache.html b/trunk/docs/manual/mod/mod_file_cache.html new file mode 100644 index 0000000000..1fc51cd79c --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.html @@ -0,0 +1,7 @@ +URI: mod_file_cache.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_file_cache.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_file_cache.html.en b/trunk/docs/manual/mod/mod_file_cache.html.en new file mode 100644 index 0000000000..2091d9015b --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.html.en @@ -0,0 +1,212 @@ + + + +mod_file_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_file_cache

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:Caches a static list of files in memory
    Status:Experimental
    Module Identifier:file_cache_module
    Source File:mod_file_cache.c
    +

    Summary

    + + +
    + This module should be used with care. You can easily create a broken + site using mod_file_cache, so read this document + carefully. +
    + +

    Caching frequently requested files that change very + infrequently is a technique for reducing server load. + mod_file_cache provides two techniques for caching + frequently requested static files. Through configuration + directives, you can direct mod_file_cache to either + open then mmap() a file, or to pre-open a file and save + the file's open file handle. Both techniques reduce server + load when processing requests for these files by doing part of the work + (specifically, the file I/O) for serving the file when the + server is started rather than during each request.

    + +

    Notice: You cannot use this for speeding up CGI programs or + other files which are served by special content handlers. It + can only be used for regular files which are usually served by + the Apache core content handler.

    + +

    This module is an extension of and borrows heavily from the + mod_mmap_static module in Apache 1.3.

    +
    +

    Directives

    + +

    Topics

    +
    +
    top
    +
    +

    Using mod_file_cache

    + +

    mod_file_cache caches a list of statically + configured files via MMapFile or CacheFile directives in the main server configuration.

    + +

    Not all platforms support both directives. For example, Apache + on Windows does not currently support the MMapStatic directive, while + other platforms, like AIX, support both. You will receive an error + message in the server error log if you attempt to use an + unsupported directive. If given an unsupported directive, the + server will start but the file will not be cached. On platforms + that support both directives, you should experiment with both to + see which works best for you.

    + +

    MMapFile Directive

    + +

    The MMapFile + directive of mod_file_cache maps a list of + statically configured files into memory through the system call + mmap(). This system call is available on most modern + Unix derivates, but not on all. There are sometimes system-specific + limits on the size and number of files that can be + mmap()ed, experimentation is probably the easiest way + to find out.

    + +

    This mmap()ing is done once at server start or + restart, only. So whenever one of the mapped files changes on the + filesystem you have to restart the server (see the Stopping and Restarting documentation). + To reiterate that point: if the files are modified in place + without restarting the server you may end up serving requests that + are completely bogus. You should update files by unlinking the old + copy and putting a new copy in place. Most tools such as + rdist and mv do this. The reason why this + modules doesn't take care of changes to the files is that this check + would need an extra stat() every time which is a waste + and against the intent of I/O reduction.

    + + +

    CacheFile Directive

    + +

    The CacheFile + directive of mod_file_cache opens an active + handle or file descriptor to the file (or files) + listed in the configuration directive and places these open file + handles in the cache. When the file is requested, the server + retrieves the handle from the cache and passes it to the + sendfile() (or TransmitFile() on Windows), + socket API.

    + + + +

    This file handle caching is done once at server start or + restart, only. So whenever one of the cached files changes on + the filesystem you have to restart the server (see the + Stopping and Restarting + documentation). To reiterate that point: if the files are + modified in place without restarting the server you + may end up serving requests that are completely bogus. You + should update files by unlinking the old copy and putting a new + copy in place. Most tools such as rdist and + mv do this.

    + + +

    Note

    +

    Don't bother asking for a directive which recursively + caches all the files in a directory. Try this instead... See the + Include directive, and consider + this command:

    + +

    + find /www/htdocs -type f -print \
    + | sed -e 's/.*/mmapfile &/' > /www/conf/mmap.conf +

    +
    +
    +
    top
    +

    CacheFile Directive

    + + + + + + +
    Description:Cache a list of file handles at startup time
    Syntax:CacheFile file-path [file-path] ...
    Context:server config
    Status:Experimental
    Module:mod_file_cache
    +

    The CacheFile directive opens handles to + one or more files (given as whitespace separated arguments) and + places these handles into the cache at server startup + time. Handles to cached files are automatically closed on a server + shutdown. When the files have changed on the filesystem, the + server should be restarted to to re-cache them.

    + +

    Be careful with the file-path arguments: They have + to literally match the filesystem path Apache's URL-to-filename + translation handlers create. We cannot compare inodes or other + stuff to match paths through symbolic links etc. + because that again would cost extra stat() system + calls which is not acceptable. This module may or may not work + with filenames rewritten by mod_alias or + mod_rewrite.

    + +

    Example

    + CacheFile /usr/local/apache/htdocs/index.html +

    + +
    +
    top
    +

    MMapFile Directive

    + + + + + + +
    Description:Map a list of files into memory at startup time
    Syntax:MMapFile file-path [file-path] ...
    Context:server config
    Status:Experimental
    Module:mod_file_cache
    +

    The MMapFile directive maps one or more files + (given as whitespace separated arguments) into memory at server + startup time. They are automatically unmapped on a server + shutdown. When the files have changed on the filesystem at + least a HUP or USR1 signal should be send to + the server to re-mmap() them.

    + +

    Be careful with the file-path arguments: They have + to literally match the filesystem path Apache's URL-to-filename + translation handlers create. We cannot compare inodes or other + stuff to match paths through symbolic links etc. + because that again would cost extra stat() system + calls which is not acceptable. This module may or may not work + with filenames rewritten by mod_alias or + mod_rewrite.

    + +

    Example

    + MMapFile /usr/local/apache/htdocs/index.html +

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_file_cache.html.ko.euc-kr b/trunk/docs/manual/mod/mod_file_cache.html.ko.euc-kr new file mode 100644 index 0000000000..453bbe580d --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.html.ko.euc-kr @@ -0,0 +1,200 @@ + + + +mod_file_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_file_cache

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + + +
    ¼³¸í:¸Þ¸ð¸®¿¡ Á¤Àû ÆÄÀϵéÀ» ij½¬
    »óÅÂ:Experimental
    ¸ðµâ¸í:file_cache_module
    ¼Ò½ºÆÄÀÏ:mod_file_cache.c
    +

    ¿ä¾à

    + + +
    + ÀÌ ¸ðµâÀº Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß ÇÑ´Ù. mod_file_cache¸¦ + »ç¿ëÇÏ¿© »çÀÌÆ®¸¦ ¾û¸ÁÀ¸·Î ¸¸µé±â ½±±â¶§¹®¿¡ ÀÌ ¹®¼­¸¦ + ²Ä²ÄÈ÷ ÀÐ±æ ¹Ù¶õ´Ù. +
    + +

    °ÅÀÇ º¯ÇÏÁö ¾Ê°í ÀÚÁÖ ¿äûµÇ´Â ÆÄÀÏÀ» ij½¬¿¡ + ÀúÀåÇÏ¿© ¼­¹ö ºÎÇϸ¦ ÁÙÀÏ ¼ö ÀÖ´Ù. mod_file_cache´Â + ÀÚÁÖ ¿äûµÇ´Â Á¤Àû ÆÄÀÏÀ» µÎ°¡Áö ¹æ½ÄÀ¸·Î ij½¬¿¡ + ÀúÀåÇÑ´Ù. ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© mod_file_cache°¡ + ÆÄÀÏÀ» ¿­°í(open) mmap()ÇÒÁö ¾Æ´Ï¸é ÆÄÀÏÀ» + ¿­°í ÆÄÀÏ ÇÚµéÀ» ÀúÀåÇÒÁö °áÁ¤ÇÑ´Ù. µÎ ¹æ½Ä ¸ðµÎ + ÆÄÀÏÀ» ¼­ºñ½ºÇϱâÀ§ÇØ ÇÊ¿äÇÑ ÀÛ¾÷ÀÇ ÀϺθ¦ (ƯÈ÷ ÆÄÀÏ ÀÔÃâ·Â + ÀÛ¾÷) ÆÄÀÏÀ» ¿äûÇÒ ¶§¸¶´Ù ¸Å¹ø ÇÏ´Â ´ë½Å ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + Çѹø¸¸ ÇÏ¿© ¼­¹ö ºÎÇÏ°¡ °¨¼ÒÇÑ´Ù.

    + +

    ÁÖÀÇ: ÀÌ ¹æ¹ýÀº CGI ÇÁ·Î±×·¥À̳ª Ưº°ÇÑ ³»¿ëÇڵ鷯¸¦ + ÅëÇØ ¼­ºñ½ºÇÏ´Â ÆÄÀÏÀÇ ¼­ºñ½º ¼Óµµ¸¦ ³ôÀÏ ¼ö ¾ø´Ù. ÀÌ ¹æ¹ýÀº + º¸Åë ¾ÆÆÄÄ¡ core ³»¿ëÇڵ鷯°¡ ¼­ºñ½ºÇÏ´Â ÀϹÝÆÄÀÏ¿¡¸¸ + Àû¿ëµÈ´Ù.

    + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡ 1.3¿¡ ÀÖ´Â mod_mmap_static + ¸ðµâÀÇ ±â´ÉÀ» È®ÀåÇÑ °á°ú´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    ÁÖÁ¦

    +
    +
    top
    +
    +

    mod_file_cache »ç¿ëÇϱâ

    + +

    mod_file_cache´Â ÁÖ¼­¹ö ¼³Á¤¿¡¼­ MMapFile°ú CacheFile Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼³Á¤ÇÑ Á¤Àû ÆÄÀϵéÀ» ij½¬¿¡ ÀúÀåÇÑ´Ù.

    + +

    ¸ðµç Ç÷¡ÆûÀÌ µÎ Áö½Ã¾î¸¦ ¸ðµÎ Áö¿øÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. + ¿¹¸¦ µé¾î, À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡´Â ÇöÀç MMapStatic Áö½Ã¾î¸¦ + Áö¿øÇÏÁö ¾ÊÁö¸¸, AIX °°Àº ´Ù¸¥ Ç÷¡ÆûÀº µÑ ¸ðµÎ¸¦ Áö¿øÇÑ´Ù. + Áö¿øÇÏÁö¾Ê´Â Áö½Ã¾î¸¦ »ç¿ëÇÒ °æ¿ì ¼­¹ö ¿À·ù ·Î±×¿¡ ¿À·ù¹®À» + ³²±ä´Ù. Áö¿øÇÏÁö¾Ê´Â Áö½Ã¾î¸¦ »ç¿ëÇصµ ¼­¹ö´Â µ¿ÀÛÇÏÁö¸¸ + ÆÄÀÏÀ» ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù. µÎ Áö½Ã¾î¸¦ ¸ðµÎ Áö¿øÇÏ´Â + Ç÷¡ÆûÀ» »ç¿ëÇÑ´Ù¸é ¾î¶² ¹æ½ÄÀÌ ´õ ÁÁÀºÁö ½ÇÇèÇغ¸¶ó.

    + +

    MMapFile Áö½Ã¾î

    + +

    mod_file_cacheÀÇ MMapFile Áö½Ã¾î´Â + ¼³Á¤ÇÑ Á¤Àû ÆÄÀϵéÀ» mmap() ½Ã½ºÅÛÈ£ÃâÀ» + »ç¿ëÇÏ¿© ¸Þ¸ð¸®¿¡ ´ëÀÀÇÑ´Ù. ÃֽŠÀ¯´Ð½º·ù ¿î¿µÃ¼Á¦¶ó¸é + º¸Åë ÀÌ ½Ã½ºÅÛÈ£ÃâÀÌ ÀÖÁö¸¸, ¾ø´Â ¿î¿µÃ¼Á¦µµ ÀÖ´Ù. ¶Ç, + mmap()ÇÒ ¼ö ÀÖ´Â ÆÄÀÏ Å©±â¿Í °³¼ö¸¦ ½Ã½ºÅÛÀÌ + Á¦ÇÑÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¹Ì¸® ½ÇÇèÇغ¸´Â °ÍÀÌ ÁÁ´Ù.

    + +

    ¼­¹ö´Â ½ÃÀÛÇÒ¶§¿Í Àç½ÃÀÛÇÒ¶§¸¸ mmap()ÇÑ´Ù. + ±×·¡¼­ ÆÄÀϽýºÅÛ¿¡¼­ ÇØ´ç ÆÄÀÏÁß Çϳª¶óµµ º¯°æµÇ¸é ¼­¹ö¸¦ + Àç½ÃÀÛÇØ¾ß ÇÑ´Ù (Áß´Ü°ú + Àç½ÃÀÛ ¹®¼­ Âü°í). ´Ù½Ã ¸»Çؼ­ ÆÄÀÏÀÌ º¯°æµÇ¾ú´Âµ¥ + ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö ¾ÊÀ¸¸é ¿ÏÀüÈ÷ ÀÌ»óÇÏ°Ô ¿äûÀ» ¼­ºñ½ºÇÒÁöµµ + ¸ð¸¥´Ù. ÀÌÀü ÆÄÀÏÀ» Áö¿ì°í(unlink) ±× ÀÚ¸®¿¡ »õ·Î¿î ÆÄÀÏÀ» + ¸¸µé´Â ¹æ½ÄÀ¸·Î ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. rdist³ª + mv¿Í °°Àº ´ë´Ù¼öÀÇ µµ±¸°¡ ÀÌ·± ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù. + ¸Å¹ø Ãß°¡·Î ºÒÇÊ¿äÇÑ stat() °Ë»ç°¡ ÇÊ¿äÇÏ°í + ÀÔÃâ·Â °¨¼Ò¶ó´Â ¿ø·¡ Àǵµ¿¡ ¹ÝÇϱ⶧¹®¿¡ ÀÌ ¸ðµâÀº ÆÄÀÏÀÇ + º¯È­¸¦ ¹«½ÃÇÑ´Ù.

    + + +

    CacheFile Áö½Ã¾î

    + +

    mod_file_cacheÀÇ CacheFile Áö½Ã¾î´Â + ¼³Á¤ Áö½Ã¾î¿¡ ¿­°ÅÇÑ ÆÄÀÏ(°ú ÆÄÀϵé)À» ¿­¾î¼­ ÆÄÀÏÀÇ + ÇÚµé(handle) ȤÀº ÆÄÀÏ ±â¼úÀÚ(file descriptor)¸¦ + ij½¬¿¡ ÀúÀåÇÑ´Ù. ÆÄÀÏÀ» ¿äûÇÏ¸é ¼­¹ö´Â ij½¬¿¡¼­ ÇÚµéÀ» + ã¾Æ¼­ ¼ÒÄÏ API sendfile()¿¡ (À©µµ¿ìÁî¿¡¼­´Â + TransmitFile()) ³Ñ±ä´Ù.

    + + + +

    ¼­¹ö´Â ½ÃÀÛÇÒ¶§¿Í Àç½ÃÀÛÇÒ¶§¸¸ ÆÄÀÏ ÇÚµéÀ» ij½¬ÇÑ´Ù. + ±×·¡¼­ ÆÄÀϽýºÅÛ¿¡¼­ ij½¬ÇÑ ÆÄÀÏÁß Çϳª¶óµµ º¯°æµÇ¸é + ¼­¹ö¸¦ Àç½ÃÀÛÇØ¾ß ÇÑ´Ù (Áß´Ü°ú Àç½ÃÀÛ ¹®¼­ Âü°í). + ´Ù½Ã ¸»Çؼ­ ÆÄÀÏÀÌ º¯°æµÇ¾ú´Âµ¥ ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö ¾ÊÀ¸¸é + ¿ÏÀüÈ÷ ÀÌ»óÇÏ°Ô ¿äûÀ» ¼­ºñ½ºÇÒÁöµµ ¸ð¸¥´Ù. ÀÌÀü ÆÄÀÏÀ» + Áö¿ì°í(unlink) ±× ÀÚ¸®¿¡ »õ·Î¿î ÆÄÀÏÀ» ¸¸µå´Â ¹æ½ÄÀ¸·Î + ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. rdist³ª mv¿Í + °°Àº ´ë´Ù¼öÀÇ µµ±¸°¡ ÀÌ·± ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù.

    + + +

    ÁÖÀÇ

    +

    µð·ºÅ丮ÀÇ ¸ðµç ÆÄÀÏÀ» Àç±ÍÀûÀ¸·Î ij½¬¿¡ ÀúÀåÇÏ´Â Áö½Ã¾î´Â + ¾ø´Ù. ´ë½Å ´ÙÀ½°ú °°ÀÌ Çغ¸¶ó... Include Áö½Ã¾î¸¦ Âü°íÇÏ¿© ´ÙÀ½°ú + °°Àº ¸í·É¾î¸¦ ½ÇÇàÇÑ´Ù:

    + +

    + find /www/htdocs -type f -print \
    + | sed -e 's/.*/mmapfile &/' > /www/conf/mmap.conf +

    +
    +
    +
    top
    +

    CacheFile Áö½Ã¾î

    + + + + + + +
    ¼³¸í:½ÃÀ۽à ¿©·¯ ÆÄÀÏ ÇÚµéÀ» ij½¬ÇÑ´Ù
    ¹®¹ý:CacheFile file-path [file-path] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_file_cache
    +

    CacheFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + ¿©·¯ ÆÄÀÏÀ» ¿­°í(open) ÆÄÀϵéÀÇ ÇÚµéÀ» ij½¬¿¡ ÀúÀåÇÑ´Ù. + ¼­¹ö Á¾·á½Ã ÀÚµ¿À¸·Î ij½¬ÇÑ ÆÄÀÏÀÇ ÇÚµéÀ» ´Ý´Â´Ù(close). + ÆÄÀϽýºÅÛ¿¡¼­ ÆÄÀÏÀÌ º¯°æµÇ¸é ÆÄÀÏÀ» ´Ù½Ã ij½¬ÇϱâÀ§ÇØ + ¼­¹ö¸¦ Àç½ÃÀÛÇØ¾ß ÇÑ´Ù.

    + +

    file-path ¾Æ±Ô¸ÕÆ®¸¦ Á¶½ÉÇضó. ¾Æ±Ô¸ÕÆ®´Â + ¾ÆÆÄÄ¡ÀÇ URL-ÆÄÀÏ¸í º¯È¯ Çڵ鷯°¡ ¸¸µç ÆÄÀϽýºÅÛ °æ·Î¿Í + Á¤È®È÷ ÀÏÄ¡ÇØ¾ß ÇÑ´Ù. Çѹø ´õ ºÒÇÊ¿äÇÑ stat() + ½Ã½ºÅÛÈ£ÃâÀÌ ÇÊ¿äÇϱ⶧¹®¿¡ inode³ª ½Éº¼¸µÅ© µîÀ» + °æ·Î¸¦ ÁöÁ¤ÇÒ ¼ö ¾ø´Ù. ÀÌ ¸ðµâÀº mod_alias³ª + mod_rewrite·Î ÀçÀÛ¼ºÇÑ ÆÄÀϸíÀ» ´Ù·ê ¼ö + Àֱ⵵ ¾ø±âµµ ÇÏ´Ù.

    + +

    ¿¹Á¦

    + CacheFile /usr/local/apache/htdocs/index.html +

    + +
    +
    top
    +

    MMapFile Áö½Ã¾î

    + + + + + + +
    ¼³¸í:½ÃÀ۽à ¿©·¯ ÆÄÀÏÀ» ¸Þ¸ð¸®¿¡ ´ëÀÀÇÑ´Ù
    ¹®¹ý:MMapFile file-path [file-path] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_file_cache
    +

    MMapFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + (°ø¹éÀ¸·Î ±¸ºÐÇÑ ¾Æ±Ô¸ÕÆ®·Î ÁöÁ¤ÇÑ) ¿©·¯ ÆÄÀÏÀ» ¸Þ¸ð¸®¿¡ + ´ëÀÀÇÑ´Ù(map). ¼­¹ö Á¾·á½Ã ÀÚµ¿À¸·Î ´ëÀÀÀ» Ǭ´Ù(unmap). + ÆÄÀϽýºÅÛ¿¡¼­ ÆÄÀÏÀÌ º¯°æµÇ¸é ÆÄÀϵéÀ» ´Ù½Ã + mmap()ÇϱâÀ§ÇØ ÃÖ¼ÒÇÑ ¼­¹ö¿¡ HUPÀ̳ª + USR1 ½Ã±×³ÎÀ» º¸³»¾ß ÇÑ´Ù.

    + +

    file-path ¾Æ±Ô¸ÕÆ®¸¦ Á¶½ÉÇضó. ¾Æ±Ô¸ÕÆ®´Â + ¾ÆÆÄÄ¡ÀÇ URL-ÆÄÀÏ¸í º¯È¯ Çڵ鷯°¡ ¸¸µç ÆÄÀϽýºÅÛ °æ·Î¿Í + Á¤È®È÷ ÀÏÄ¡ÇØ¾ß ÇÑ´Ù. Çѹø ´õ ºÒÇÊ¿äÇÑ stat() + ½Ã½ºÅÛÈ£ÃâÀÌ ÇÊ¿äÇϱ⶧¹®¿¡ inode³ª ½Éº¼¸µÅ© µîÀ» + °æ·Î¸¦ ÁöÁ¤ÇÒ ¼ö ¾ø´Ù. ÀÌ ¸ðµâÀº mod_alias³ª + mod_rewrite·Î ÀçÀÛ¼ºÇÑ ÆÄÀϸíÀ» ´Ù·ê ¼ö + Àֱ⵵ ¾ø±âµµ ÇÏ´Ù.

    + +

    ¿¹Á¦

    + MMapFile /usr/local/apache/htdocs/index.html +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_file_cache.xml b/trunk/docs/manual/mod/mod_file_cache.xml new file mode 100644 index 0000000000..03d693a467 --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.xml @@ -0,0 +1,199 @@ + + + + + + + + + +mod_file_cache +Caches a static list of files in memory +Experimental +mod_file_cache.c +file_cache_module + + + + + This module should be used with care. You can easily create a broken + site using mod_file_cache, so read this document + carefully. + + +

    Caching frequently requested files that change very + infrequently is a technique for reducing server load. + mod_file_cache provides two techniques for caching + frequently requested static files. Through configuration + directives, you can direct mod_file_cache to either + open then mmap() a file, or to pre-open a file and save + the file's open file handle. Both techniques reduce server + load when processing requests for these files by doing part of the work + (specifically, the file I/O) for serving the file when the + server is started rather than during each request.

    + +

    Notice: You cannot use this for speeding up CGI programs or + other files which are served by special content handlers. It + can only be used for regular files which are usually served by + the Apache core content handler.

    + +

    This module is an extension of and borrows heavily from the + mod_mmap_static module in Apache 1.3.

    +
    + +
    Using mod_file_cache + +

    mod_file_cache caches a list of statically + configured files via MMapFile or CacheFile directives in the main server configuration.

    + +

    Not all platforms support both directives. For example, Apache + on Windows does not currently support the MMapStatic directive, while + other platforms, like AIX, support both. You will receive an error + message in the server error log if you attempt to use an + unsupported directive. If given an unsupported directive, the + server will start but the file will not be cached. On platforms + that support both directives, you should experiment with both to + see which works best for you.

    + +
    MMapFile Directive + +

    The MMapFile + directive of mod_file_cache maps a list of + statically configured files into memory through the system call + mmap(). This system call is available on most modern + Unix derivates, but not on all. There are sometimes system-specific + limits on the size and number of files that can be + mmap()ed, experimentation is probably the easiest way + to find out.

    + +

    This mmap()ing is done once at server start or + restart, only. So whenever one of the mapped files changes on the + filesystem you have to restart the server (see the Stopping and Restarting documentation). + To reiterate that point: if the files are modified in place + without restarting the server you may end up serving requests that + are completely bogus. You should update files by unlinking the old + copy and putting a new copy in place. Most tools such as + rdist and mv do this. The reason why this + modules doesn't take care of changes to the files is that this check + would need an extra stat() every time which is a waste + and against the intent of I/O reduction.

    +
    + +
    CacheFile Directive + +

    The CacheFile + directive of mod_file_cache opens an active + handle or file descriptor to the file (or files) + listed in the configuration directive and places these open file + handles in the cache. When the file is requested, the server + retrieves the handle from the cache and passes it to the + sendfile() (or TransmitFile() on Windows), + socket API.

    + + + +

    This file handle caching is done once at server start or + restart, only. So whenever one of the cached files changes on + the filesystem you have to restart the server (see the + Stopping and Restarting + documentation). To reiterate that point: if the files are + modified in place without restarting the server you + may end up serving requests that are completely bogus. You + should update files by unlinking the old copy and putting a new + copy in place. Most tools such as rdist and + mv do this.

    +
    + + Note +

    Don't bother asking for a directive which recursively + caches all the files in a directory. Try this instead... See the + Include directive, and consider + this command:

    + + + find /www/htdocs -type f -print \
    + | sed -e 's/.*/mmapfile &/' > /www/conf/mmap.conf +
    +
    +
    + + +MMapFile +Map a list of files into memory at startup time +MMapFile file-path [file-path] ... +server config + + +

    The MMapFile directive maps one or more files + (given as whitespace separated arguments) into memory at server + startup time. They are automatically unmapped on a server + shutdown. When the files have changed on the filesystem at + least a HUP or USR1 signal should be send to + the server to re-mmap() them.

    + +

    Be careful with the file-path arguments: They have + to literally match the filesystem path Apache's URL-to-filename + translation handlers create. We cannot compare inodes or other + stuff to match paths through symbolic links etc. + because that again would cost extra stat() system + calls which is not acceptable. This module may or may not work + with filenames rewritten by mod_alias or + mod_rewrite.

    + + Example + MMapFile /usr/local/apache/htdocs/index.html + +
    +
    + + +CacheFile +Cache a list of file handles at startup time +CacheFile file-path [file-path] ... +server config + + +

    The CacheFile directive opens handles to + one or more files (given as whitespace separated arguments) and + places these handles into the cache at server startup + time. Handles to cached files are automatically closed on a server + shutdown. When the files have changed on the filesystem, the + server should be restarted to to re-cache them.

    + +

    Be careful with the file-path arguments: They have + to literally match the filesystem path Apache's URL-to-filename + translation handlers create. We cannot compare inodes or other + stuff to match paths through symbolic links etc. + because that again would cost extra stat() system + calls which is not acceptable. This module may or may not work + with filenames rewritten by mod_alias or + mod_rewrite.

    + + Example + CacheFile /usr/local/apache/htdocs/index.html + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_file_cache.xml.ko b/trunk/docs/manual/mod/mod_file_cache.xml.ko new file mode 100644 index 0000000000..4c52d8eb1f --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.xml.ko @@ -0,0 +1,190 @@ + + + + + + + + + +mod_file_cache +¸Þ¸ð¸®¿¡ Á¤Àû ÆÄÀϵéÀ» ij½¬ +Experimental +mod_file_cache.c +file_cache_module + + + + + ÀÌ ¸ðµâÀº Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß ÇÑ´Ù. mod_file_cache¸¦ + »ç¿ëÇÏ¿© »çÀÌÆ®¸¦ ¾û¸ÁÀ¸·Î ¸¸µé±â ½±±â¶§¹®¿¡ ÀÌ ¹®¼­¸¦ + ²Ä²ÄÈ÷ ÀÐ±æ ¹Ù¶õ´Ù. + + +

    °ÅÀÇ º¯ÇÏÁö ¾Ê°í ÀÚÁÖ ¿äûµÇ´Â ÆÄÀÏÀ» ij½¬¿¡ + ÀúÀåÇÏ¿© ¼­¹ö ºÎÇϸ¦ ÁÙÀÏ ¼ö ÀÖ´Ù. mod_file_cache´Â + ÀÚÁÖ ¿äûµÇ´Â Á¤Àû ÆÄÀÏÀ» µÎ°¡Áö ¹æ½ÄÀ¸·Î ij½¬¿¡ + ÀúÀåÇÑ´Ù. ¼³Á¤ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© mod_file_cache°¡ + ÆÄÀÏÀ» ¿­°í(open) mmap()ÇÒÁö ¾Æ´Ï¸é ÆÄÀÏÀ» + ¿­°í ÆÄÀÏ ÇÚµéÀ» ÀúÀåÇÒÁö °áÁ¤ÇÑ´Ù. µÎ ¹æ½Ä ¸ðµÎ + ÆÄÀÏÀ» ¼­ºñ½ºÇϱâÀ§ÇØ ÇÊ¿äÇÑ ÀÛ¾÷ÀÇ ÀϺθ¦ (ƯÈ÷ ÆÄÀÏ ÀÔÃâ·Â + ÀÛ¾÷) ÆÄÀÏÀ» ¿äûÇÒ ¶§¸¶´Ù ¸Å¹ø ÇÏ´Â ´ë½Å ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + Çѹø¸¸ ÇÏ¿© ¼­¹ö ºÎÇÏ°¡ °¨¼ÒÇÑ´Ù.

    + +

    ÁÖÀÇ: ÀÌ ¹æ¹ýÀº CGI ÇÁ·Î±×·¥À̳ª Ưº°ÇÑ ³»¿ëÇڵ鷯¸¦ + ÅëÇØ ¼­ºñ½ºÇÏ´Â ÆÄÀÏÀÇ ¼­ºñ½º ¼Óµµ¸¦ ³ôÀÏ ¼ö ¾ø´Ù. ÀÌ ¹æ¹ýÀº + º¸Åë ¾ÆÆÄÄ¡ core ³»¿ëÇڵ鷯°¡ ¼­ºñ½ºÇÏ´Â ÀϹÝÆÄÀÏ¿¡¸¸ + Àû¿ëµÈ´Ù.

    + +

    ÀÌ ¸ðµâÀº ¾ÆÆÄÄ¡ 1.3¿¡ ÀÖ´Â mod_mmap_static + ¸ðµâÀÇ ±â´ÉÀ» È®ÀåÇÑ °á°ú´Ù.

    +
    + +
    mod_file_cache »ç¿ëÇϱâ + +

    mod_file_cache´Â ÁÖ¼­¹ö ¼³Á¤¿¡¼­ MMapFile°ú CacheFile Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¼³Á¤ÇÑ Á¤Àû ÆÄÀϵéÀ» ij½¬¿¡ ÀúÀåÇÑ´Ù.

    + +

    ¸ðµç Ç÷¡ÆûÀÌ µÎ Áö½Ã¾î¸¦ ¸ðµÎ Áö¿øÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. + ¿¹¸¦ µé¾î, À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡´Â ÇöÀç MMapStatic Áö½Ã¾î¸¦ + Áö¿øÇÏÁö ¾ÊÁö¸¸, AIX °°Àº ´Ù¸¥ Ç÷¡ÆûÀº µÑ ¸ðµÎ¸¦ Áö¿øÇÑ´Ù. + Áö¿øÇÏÁö¾Ê´Â Áö½Ã¾î¸¦ »ç¿ëÇÒ °æ¿ì ¼­¹ö ¿À·ù ·Î±×¿¡ ¿À·ù¹®À» + ³²±ä´Ù. Áö¿øÇÏÁö¾Ê´Â Áö½Ã¾î¸¦ »ç¿ëÇصµ ¼­¹ö´Â µ¿ÀÛÇÏÁö¸¸ + ÆÄÀÏÀ» ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù. µÎ Áö½Ã¾î¸¦ ¸ðµÎ Áö¿øÇÏ´Â + Ç÷¡ÆûÀ» »ç¿ëÇÑ´Ù¸é ¾î¶² ¹æ½ÄÀÌ ´õ ÁÁÀºÁö ½ÇÇèÇغ¸¶ó.

    + +
    MMapFile Áö½Ã¾î + +

    mod_file_cacheÀÇ MMapFile Áö½Ã¾î´Â + ¼³Á¤ÇÑ Á¤Àû ÆÄÀϵéÀ» mmap() ½Ã½ºÅÛÈ£ÃâÀ» + »ç¿ëÇÏ¿© ¸Þ¸ð¸®¿¡ ´ëÀÀÇÑ´Ù. ÃֽŠÀ¯´Ð½º·ù ¿î¿µÃ¼Á¦¶ó¸é + º¸Åë ÀÌ ½Ã½ºÅÛÈ£ÃâÀÌ ÀÖÁö¸¸, ¾ø´Â ¿î¿µÃ¼Á¦µµ ÀÖ´Ù. ¶Ç, + mmap()ÇÒ ¼ö ÀÖ´Â ÆÄÀÏ Å©±â¿Í °³¼ö¸¦ ½Ã½ºÅÛÀÌ + Á¦ÇÑÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¹Ì¸® ½ÇÇèÇغ¸´Â °ÍÀÌ ÁÁ´Ù.

    + +

    ¼­¹ö´Â ½ÃÀÛÇÒ¶§¿Í Àç½ÃÀÛÇÒ¶§¸¸ mmap()ÇÑ´Ù. + ±×·¡¼­ ÆÄÀϽýºÅÛ¿¡¼­ ÇØ´ç ÆÄÀÏÁß Çϳª¶óµµ º¯°æµÇ¸é ¼­¹ö¸¦ + Àç½ÃÀÛÇØ¾ß ÇÑ´Ù (Áß´Ü°ú + Àç½ÃÀÛ ¹®¼­ Âü°í). ´Ù½Ã ¸»Çؼ­ ÆÄÀÏÀÌ º¯°æµÇ¾ú´Âµ¥ + ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö ¾ÊÀ¸¸é ¿ÏÀüÈ÷ ÀÌ»óÇÏ°Ô ¿äûÀ» ¼­ºñ½ºÇÒÁöµµ + ¸ð¸¥´Ù. ÀÌÀü ÆÄÀÏÀ» Áö¿ì°í(unlink) ±× ÀÚ¸®¿¡ »õ·Î¿î ÆÄÀÏÀ» + ¸¸µé´Â ¹æ½ÄÀ¸·Î ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. rdist³ª + mv¿Í °°Àº ´ë´Ù¼öÀÇ µµ±¸°¡ ÀÌ·± ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù. + ¸Å¹ø Ãß°¡·Î ºÒÇÊ¿äÇÑ stat() °Ë»ç°¡ ÇÊ¿äÇÏ°í + ÀÔÃâ·Â °¨¼Ò¶ó´Â ¿ø·¡ Àǵµ¿¡ ¹ÝÇϱ⶧¹®¿¡ ÀÌ ¸ðµâÀº ÆÄÀÏÀÇ + º¯È­¸¦ ¹«½ÃÇÑ´Ù.

    +
    + +
    CacheFile Áö½Ã¾î + +

    mod_file_cacheÀÇ CacheFile Áö½Ã¾î´Â + ¼³Á¤ Áö½Ã¾î¿¡ ¿­°ÅÇÑ ÆÄÀÏ(°ú ÆÄÀϵé)À» ¿­¾î¼­ ÆÄÀÏÀÇ + ÇÚµé(handle) ȤÀº ÆÄÀÏ ±â¼úÀÚ(file descriptor)¸¦ + ij½¬¿¡ ÀúÀåÇÑ´Ù. ÆÄÀÏÀ» ¿äûÇÏ¸é ¼­¹ö´Â ij½¬¿¡¼­ ÇÚµéÀ» + ã¾Æ¼­ ¼ÒÄÏ API sendfile()¿¡ (À©µµ¿ìÁî¿¡¼­´Â + TransmitFile()) ³Ñ±ä´Ù.

    + + + +

    ¼­¹ö´Â ½ÃÀÛÇÒ¶§¿Í Àç½ÃÀÛÇÒ¶§¸¸ ÆÄÀÏ ÇÚµéÀ» ij½¬ÇÑ´Ù. + ±×·¡¼­ ÆÄÀϽýºÅÛ¿¡¼­ ij½¬ÇÑ ÆÄÀÏÁß Çϳª¶óµµ º¯°æµÇ¸é + ¼­¹ö¸¦ Àç½ÃÀÛÇØ¾ß ÇÑ´Ù (Áß´Ü°ú Àç½ÃÀÛ ¹®¼­ Âü°í). + ´Ù½Ã ¸»Çؼ­ ÆÄÀÏÀÌ º¯°æµÇ¾ú´Âµ¥ ¼­¹ö¸¦ Àç½ÃÀÛÇÏÁö ¾ÊÀ¸¸é + ¿ÏÀüÈ÷ ÀÌ»óÇÏ°Ô ¿äûÀ» ¼­ºñ½ºÇÒÁöµµ ¸ð¸¥´Ù. ÀÌÀü ÆÄÀÏÀ» + Áö¿ì°í(unlink) ±× ÀÚ¸®¿¡ »õ·Î¿î ÆÄÀÏÀ» ¸¸µå´Â ¹æ½ÄÀ¸·Î + ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. rdist³ª mv¿Í + °°Àº ´ë´Ù¼öÀÇ µµ±¸°¡ ÀÌ·± ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù.

    +
    + + ÁÖÀÇ +

    µð·ºÅ丮ÀÇ ¸ðµç ÆÄÀÏÀ» Àç±ÍÀûÀ¸·Î ij½¬¿¡ ÀúÀåÇÏ´Â Áö½Ã¾î´Â + ¾ø´Ù. ´ë½Å ´ÙÀ½°ú °°ÀÌ Çغ¸¶ó... Include Áö½Ã¾î¸¦ Âü°íÇÏ¿© ´ÙÀ½°ú + °°Àº ¸í·É¾î¸¦ ½ÇÇàÇÑ´Ù:

    + + + find /www/htdocs -type f -print \
    + | sed -e 's/.*/mmapfile &/' > /www/conf/mmap.conf +
    +
    +
    + + +MMapFile +½ÃÀ۽à ¿©·¯ ÆÄÀÏÀ» ¸Þ¸ð¸®¿¡ ´ëÀÀÇÑ´Ù +MMapFile file-path [file-path] ... +server config + + +

    MMapFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + (°ø¹éÀ¸·Î ±¸ºÐÇÑ ¾Æ±Ô¸ÕÆ®·Î ÁöÁ¤ÇÑ) ¿©·¯ ÆÄÀÏÀ» ¸Þ¸ð¸®¿¡ + ´ëÀÀÇÑ´Ù(map). ¼­¹ö Á¾·á½Ã ÀÚµ¿À¸·Î ´ëÀÀÀ» Ǭ´Ù(unmap). + ÆÄÀϽýºÅÛ¿¡¼­ ÆÄÀÏÀÌ º¯°æµÇ¸é ÆÄÀϵéÀ» ´Ù½Ã + mmap()ÇϱâÀ§ÇØ ÃÖ¼ÒÇÑ ¼­¹ö¿¡ HUPÀ̳ª + USR1 ½Ã±×³ÎÀ» º¸³»¾ß ÇÑ´Ù.

    + +

    file-path ¾Æ±Ô¸ÕÆ®¸¦ Á¶½ÉÇضó. ¾Æ±Ô¸ÕÆ®´Â + ¾ÆÆÄÄ¡ÀÇ URL-ÆÄÀÏ¸í º¯È¯ Çڵ鷯°¡ ¸¸µç ÆÄÀϽýºÅÛ °æ·Î¿Í + Á¤È®È÷ ÀÏÄ¡ÇØ¾ß ÇÑ´Ù. Çѹø ´õ ºÒÇÊ¿äÇÑ stat() + ½Ã½ºÅÛÈ£ÃâÀÌ ÇÊ¿äÇϱ⶧¹®¿¡ inode³ª ½Éº¼¸µÅ© µîÀ» + °æ·Î¸¦ ÁöÁ¤ÇÒ ¼ö ¾ø´Ù. ÀÌ ¸ðµâÀº mod_alias³ª + mod_rewrite·Î ÀçÀÛ¼ºÇÑ ÆÄÀϸíÀ» ´Ù·ê ¼ö + Àֱ⵵ ¾ø±âµµ ÇÏ´Ù.

    + + ¿¹Á¦ + MMapFile /usr/local/apache/htdocs/index.html + +
    +
    + + +CacheFile +½ÃÀ۽à ¿©·¯ ÆÄÀÏ ÇÚµéÀ» ij½¬ÇÑ´Ù +CacheFile file-path [file-path] ... +server config + + +

    CacheFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ + ¿©·¯ ÆÄÀÏÀ» ¿­°í(open) ÆÄÀϵéÀÇ ÇÚµéÀ» ij½¬¿¡ ÀúÀåÇÑ´Ù. + ¼­¹ö Á¾·á½Ã ÀÚµ¿À¸·Î ij½¬ÇÑ ÆÄÀÏÀÇ ÇÚµéÀ» ´Ý´Â´Ù(close). + ÆÄÀϽýºÅÛ¿¡¼­ ÆÄÀÏÀÌ º¯°æµÇ¸é ÆÄÀÏÀ» ´Ù½Ã ij½¬ÇϱâÀ§ÇØ + ¼­¹ö¸¦ Àç½ÃÀÛÇØ¾ß ÇÑ´Ù.

    + +

    file-path ¾Æ±Ô¸ÕÆ®¸¦ Á¶½ÉÇضó. ¾Æ±Ô¸ÕÆ®´Â + ¾ÆÆÄÄ¡ÀÇ URL-ÆÄÀÏ¸í º¯È¯ Çڵ鷯°¡ ¸¸µç ÆÄÀϽýºÅÛ °æ·Î¿Í + Á¤È®È÷ ÀÏÄ¡ÇØ¾ß ÇÑ´Ù. Çѹø ´õ ºÒÇÊ¿äÇÑ stat() + ½Ã½ºÅÛÈ£ÃâÀÌ ÇÊ¿äÇϱ⶧¹®¿¡ inode³ª ½Éº¼¸µÅ© µîÀ» + °æ·Î¸¦ ÁöÁ¤ÇÒ ¼ö ¾ø´Ù. ÀÌ ¸ðµâÀº mod_alias³ª + mod_rewrite·Î ÀçÀÛ¼ºÇÑ ÆÄÀϸíÀ» ´Ù·ê ¼ö + Àֱ⵵ ¾ø±âµµ ÇÏ´Ù.

    + + ¿¹Á¦ + CacheFile /usr/local/apache/htdocs/index.html + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_file_cache.xml.meta b/trunk/docs/manual/mod/mod_file_cache.xml.meta new file mode 100644 index 0000000000..b50023875d --- /dev/null +++ b/trunk/docs/manual/mod/mod_file_cache.xml.meta @@ -0,0 +1,12 @@ + + + + mod_file_cache + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_filter.html b/trunk/docs/manual/mod/mod_filter.html new file mode 100644 index 0000000000..522140ca97 --- /dev/null +++ b/trunk/docs/manual/mod/mod_filter.html @@ -0,0 +1,3 @@ +URI: mod_filter.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_filter.html.en b/trunk/docs/manual/mod/mod_filter.html.en new file mode 100644 index 0000000000..c4a1e689bb --- /dev/null +++ b/trunk/docs/manual/mod/mod_filter.html.en @@ -0,0 +1,435 @@ + + + +mod_filter - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_filter

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Context-sensitive smart filter configuration module
    Status:Experimental
    Module Identifier:filter_module
    Source File:mod_filter.c
    Compatibility:Version 2.1 and higher
    +

    Summary

    + +

    This module enables smart, context-sensitive configuration of + output content filters. For example, apache can be configured to + process different content-types through different filters, even + when the content-type is not known in advance (e.g. in a proxy).

    + +

    mod_filter works by introducing indirection into + the filter chain. Instead of inserting filters in the chain, we insert + a filter harness which in turn dispatches conditionally + to a filter provider. Any content filter may be used as a provider + to mod_filter; no change to existing filter modules is + required (although it may be possible to simplify them).

    +
    + +
    top
    +
    +

    Smart Filtering

    +

    In the traditional filtering model, filters are inserted unconditionally + using AddOutputFilter and family. + Each filter then needs to determine whether to run, and there is little + flexibility available for server admins to allow the chain to be + configured dynamically.

    + +

    mod_filter by contrast gives server administrators a + great deal of flexibility in configuring the filter chain. In fact, + filters can be inserted based on any Request Header, Response Header + or Environment Variable. This generalises the limited flexibility offered + by AddOutputFilterByType, and fixes + it to work correctly with dynamic content, regardless of the + content generator. The ability to dispatch based on Environment + Variables offers the full flexibility of configuration with + mod_rewrite to anyone who needs it.

    +
    top
    +
    +

    Filter Declarations, Providers and Chains

    +

    + [This image displays the traditional filter model]
    + Figure 1: The traditional filter model

    + +

    In the traditional model, output filters are a simple chain + from the content generator (handler) to the client. This works well + provided the filter chain can be correctly configured, but presents + problems when the filters need to be configured dynamically based on + the outcome of the handler.

    + +

    + [This image shows the mod_filter model]
    + Figure 2: The mod_filter model

    + +

    mod_filter works by introducing indirection into + the filter chain. Instead of inserting filters in the chain, we insert + a filter harness which in turn dispatches conditionally + to a filter provider. Any content filter may be used as a provider + to mod_filter; no change to existing filter modules + is required (although it may be possible to simplify them). There can be + multiple providers for one filter, but no more than one provider will + run for any single request.

    + +

    A filter chain comprises any number of instances of the filter + harness, each of which may have any number of providers. A special + case is that of a single provider with unconditional dispatch: this + is equivalent to inserting the provider filter directly into the chain.

    +
    top
    +
    +

    Configuring the Chain

    +

    There are three stages to configuring a filter chain with + mod_filter. For details of the directives, see below.

    + +
    +
    Declare Filters
    +
    The FilterDeclare directive + declares a filter, assigning it a name and filter type. Required + only if the filter is not the default type AP_FTYPE_RESOURCE.
    + +
    Register Providers
    +
    The FilterProvider + directive registers a provider with a filter. The filter may have + been declared with FilterDeclare; if not, FilterProvider will implicitly + declare it with the default type AP_FTYPE_RESOURCE. The provider + must have been + registered with ap_register_output_filter by some module. + The remaining arguments to FilterProvider are a dispatch criterion and a match string. + The former may be an HTTP request or response header, an environment + variable, or the Handler used by this request. The latter is matched + to it for each request, to determine whether this provider will be + used to implement the filter for this request.
    + +
    Configure the Chain
    +
    The above directives build components of a smart filter chain, + but do not configure it to run. The FilterChain directive builds a filter chain from smart + filters declared, offering the flexibility to insert filters at the + beginning or end of the chain, remove a filter, or clear the chain.
    +
    +
    top
    +
    +

    Examples

    +
    +
    Server side Includes (SSI)
    +
    A simple case of using mod_filter in place of + AddOutputFilterByType +

    + FilterDeclare SSI
    + FilterProvider SSI INCLUDES resp=Content-Type $text/html
    + FilterChain SSI +

    +
    + +
    Server side Includes (SSI)
    +
    The same as the above but dispatching on handler (classic + SSI behaviour; .shtml files get processed). +

    + FilterProvider SSI INCLUDES Handler server-parsed
    + FilterChain SSI +

    +
    + +
    Emulating mod_gzip with mod_deflate
    +
    Insert INFLATE filter only if "gzip" is NOT in the + Accept-Encoding header. This filter runs with ftype CONTENT_SET. +

    + FilterDeclare gzip CONTENT_SET
    + FilterProvider gzip inflate req=Accept-Encoding !$gzip
    + FilterChain gzip +

    +
    + +
    Image Downsampling
    +
    Suppose we want to downsample all web images, and have filters + for GIF, JPEG and PNG. +

    + FilterProvider unpack jpeg_unpack Content-Type $image/jpeg
    + FilterProvider unpack gif_unpack Content-Type $image/gif
    + FilterProvider unpack png_unpack Content-Type $image/png
    +
    + FilterProvider downsample downsample_filter Content-Type $image
    + FilterProtocol downsample "change=yes"
    +
    + FilterProvider repack jpeg_pack Content-Type $image/jpeg
    + FilterProvider repack gif_pack Content-Type $image/gif
    + FilterProvider repack png_pack Content-Type $image/png
    + <Location /image-filter>
    + + FilterChain unpack downsample repack
    +
    + </Location> +

    +
    +
    +
    top
    +
    +

    Protocol Handling

    +

    Historically, each filter is responsible for ensuring that whatever + changes it makes are correctly represented in the HTTP response headers, + and that it does not run when it would make an illegal change. This + imposes a burden on filter authors to re-implement some common + functionality in every filter:

    + +
      +
    • Many filters will change the content, invalidating existing content + tags, checksums, hashes, and lengths.
    • + +
    • Filters that require an entire, unbroken response in input need to + ensure they don't get byteranges from a backend.
    • + +
    • Filters that transform output in a filter need to ensure they don't + violate a Cache-Control: no-transform header from the + backend.
    • + +
    • Filters may make responses uncacheable.
    • +
    + +

    mod_filter aims to offer generic handling of these + details of filter implementation, reducing the complexity required of + content filter modules. This is work-in-progress; the + FilterProtocol implements + some of this functionality, but there are no API calls yet.

    + +

    At the same time, mod_filter should not interfere + with a filter that wants to handle all aspects of the protocol. By + default (i.e. in the absence of any FilterProtocol directives), mod_filter + will leave the headers untouched.

    +
    +
    top
    +

    FilterChain Directive

    + + + + + + + +
    Description:Configure the filter chain
    Syntax:FilterChain [+=-@!]filter-name ...
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Experimental
    Module:mod_filter
    +

    This configures an actual filter chain, from declared filters. + FilterChain takes any number of arguments, + each optionally preceded with a single-character control that + determines what to do:

    + +
    +
    +filter-name
    +
    Add filter-name to the end of the filter chain
    + +
    @filter-name
    +
    Insert filter-name at the start of the filter chain
    + +
    -filter-name
    +
    Remove filter-name from the filter chain
    + +
    =filter-name
    +
    Empty the filter chain and insert filter-name
    + +
    !
    +
    Empty the filter chain
    + +
    filter-name
    +
    Equivalent to +filter-name
    +
    + +
    +
    top
    +

    FilterDeclare Directive

    + + + + + + + +
    Description:Declare a smart filter
    Syntax:FilterDeclare filter-name [type]
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Experimental
    Module:mod_filter
    +

    This directive declares an output filter together with a + header or environment variable that will determine runtime + configuration. The first argument is a filter-name + for use in FilterProvider, + FilterChain and + FilterProtocol directives.

    + +

    The final (optional) argument + is the type of filter, and takes values of ap_filter_type + - namely RESOURCE (the default), CONTENT_SET, + PROTOCOL, TRANSCODE, CONNECTION + or NETWORK.

    + +
    +
    top
    +

    FilterProtocol Directive

    + + + + + + + +
    Description:Deal with correct HTTP protocol handling
    Syntax:FilterProtocol filter-name [provider-name] + proto-flags
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Experimental
    Module:mod_filter
    +

    This directs mod_filter to deal with ensuring the + filter doesn't run when it shouldn't, and that the HTTP response + headers are correctly set taking into account the effects of the + filter.

    + +

    There are two forms of this directive. With three arguments, it + applies specifically to a filter-name and a + provider-name for that filter. + With two arguments it applies to a filter-name whenever the + filter runs any provider.

    + +

    proto-flags is one or more of

    + +
    +
    change=yes
    +
    The filter changes the content, including possibly the content + length
    + +
    change=1:1
    +
    The filter changes the content, but will not change the content + length
    + +
    byteranges=no
    +
    The filter cannot work on byteranges and requires complete input
    + +
    proxy=no
    +
    The filter should not run in a proxy context
    + +
    proxy=transform
    +
    The filter transforms the response in a manner incompatible with + the HTTP Cache-Control: no-transform header.
    + +
    cache=no
    +
    The filter renders the output uncacheable (eg by introducing randomised + content changes)
    +
    + +
    +
    top
    +

    FilterProvider Directive

    + + + + + + + +
    Description:Register a content filter
    Syntax:FilterProvider filter-name provider-name + [req|resp|env]=dispatch match
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Experimental
    Module:mod_filter
    +

    This directive registers a provider for the smart filter. + The provider will be called if and only if the match declared + here matches the value of the header or environment variable declared + as dispatch.

    + +

    + provider-name must have been registered by loading + a module that registers the name with + ap_register_output_filter. + +

    + +

    The dispatch argument is a string with optional + req=, resp= or env= prefix + causing it to dispatch on (respectively) the request header, response + header, or environment variable named. In the absence of a + prefix, it defaults to a response header. A special case is the + word handler, which causes mod_filter + to dispatch on the content handler.

    + +

    The match argument specifies a match that will be applied to + the filter's dispatch criterion. The match may be + a string match (exact match or substring), a regexp, an integer (greater, + lessthan or equals), or unconditional. The first characters of the + match argument determines this:

    + +

    First, if the first character is an exclamation mark + (!), this reverses the rule, so the provider will be used + if and only if the match fails.

    + +

    Second, it interprets the first character excluding + any leading ! as follows:

    + + + + + + + + + + + +
    CharacterDescription
    (none)exact match
    $substring match
    /regexp match (delimited by a second /)
    =integer equality
    <integer less-than
    <=integer less-than or equal
    >integer greater-than
    >=integer greater-than or equal
    *Unconditional match
    + +
    +
    top
    +

    FilterTrace Directive

    + + + + + + +
    Description:Get debug/diagnostic information from + mod_filter
    Syntax:FilterTrace filter-name level
    Context:server config, virtual host, directory
    Status:Experimental
    Module:mod_filter
    +

    This directive generates debug information from + mod_filter. + It is designed to help test and debug providers (filter modules), although + it may also help with mod_filter itself.

    + +

    The debug output depends on the level set:

    +
    +
    0 (default)
    +
    No debug information is generated.
    + +
    1
    +
    mod_filter will record buckets and brigades + passing through the filter to the error log, before the provider has + processed them. This is similar to the information generated by + mod_diagnostics. +
    + +
    2 (not yet implemented)
    +
    Will dump the full data passing through to a tempfile before the + provider. For single-user debug only; this will not + support concurrent hits.
    +
    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_filter.xml b/trunk/docs/manual/mod/mod_filter.xml new file mode 100644 index 0000000000..8e2231ee06 --- /dev/null +++ b/trunk/docs/manual/mod/mod_filter.xml @@ -0,0 +1,426 @@ + + + + + + + + + +mod_filter +Context-sensitive smart filter configuration module +Experimental +mod_filter.c +filter_module +Version 2.1 and higher + + +

    This module enables smart, context-sensitive configuration of + output content filters. For example, apache can be configured to + process different content-types through different filters, even + when the content-type is not known in advance (e.g. in a proxy).

    + +

    mod_filter works by introducing indirection into + the filter chain. Instead of inserting filters in the chain, we insert + a filter harness which in turn dispatches conditionally + to a filter provider. Any content filter may be used as a provider + to mod_filter; no change to existing filter modules is + required (although it may be possible to simplify them).

    +
    + +
    Smart Filtering +

    In the traditional filtering model, filters are inserted unconditionally + using AddOutputFilter and family. + Each filter then needs to determine whether to run, and there is little + flexibility available for server admins to allow the chain to be + configured dynamically.

    + +

    mod_filter by contrast gives server administrators a + great deal of flexibility in configuring the filter chain. In fact, + filters can be inserted based on any Request Header, Response Header + or Environment Variable. This generalises the limited flexibility offered + by AddOutputFilterByType, and fixes + it to work correctly with dynamic content, regardless of the + content generator. The ability to dispatch based on Environment + Variables offers the full flexibility of configuration with + mod_rewrite to anyone who needs it.

    +
    + +
    Filter Declarations, Providers and Chains +

    + [This image displays the traditional filter model]
    + Figure 1: The traditional filter model

    + +

    In the traditional model, output filters are a simple chain + from the content generator (handler) to the client. This works well + provided the filter chain can be correctly configured, but presents + problems when the filters need to be configured dynamically based on + the outcome of the handler.

    + +

    + [This image shows the mod_filter model]
    + Figure 2: The mod_filter model

    + +

    mod_filter works by introducing indirection into + the filter chain. Instead of inserting filters in the chain, we insert + a filter harness which in turn dispatches conditionally + to a filter provider. Any content filter may be used as a provider + to mod_filter; no change to existing filter modules + is required (although it may be possible to simplify them). There can be + multiple providers for one filter, but no more than one provider will + run for any single request.

    + +

    A filter chain comprises any number of instances of the filter + harness, each of which may have any number of providers. A special + case is that of a single provider with unconditional dispatch: this + is equivalent to inserting the provider filter directly into the chain.

    +
    + +
    Configuring the Chain +

    There are three stages to configuring a filter chain with + mod_filter. For details of the directives, see below.

    + +
    +
    Declare Filters
    +
    The FilterDeclare directive + declares a filter, assigning it a name and filter type. Required + only if the filter is not the default type AP_FTYPE_RESOURCE.
    + +
    Register Providers
    +
    The FilterProvider + directive registers a provider with a filter. The filter may have + been declared with FilterDeclare; if not, FilterProvider will implicitly + declare it with the default type AP_FTYPE_RESOURCE. The provider + must have been + registered with ap_register_output_filter by some module. + The remaining arguments to FilterProvider are a dispatch criterion and a match string. + The former may be an HTTP request or response header, an environment + variable, or the Handler used by this request. The latter is matched + to it for each request, to determine whether this provider will be + used to implement the filter for this request.
    + +
    Configure the Chain
    +
    The above directives build components of a smart filter chain, + but do not configure it to run. The FilterChain directive builds a filter chain from smart + filters declared, offering the flexibility to insert filters at the + beginning or end of the chain, remove a filter, or clear the chain.
    +
    +
    + +
    Examples +
    +
    Server side Includes (SSI)
    +
    A simple case of using mod_filter in place of + AddOutputFilterByType + + FilterDeclare SSI
    + FilterProvider SSI INCLUDES resp=Content-Type $text/html
    + FilterChain SSI +
    +
    + +
    Server side Includes (SSI)
    +
    The same as the above but dispatching on handler (classic + SSI behaviour; .shtml files get processed). + + FilterProvider SSI INCLUDES Handler server-parsed
    + FilterChain SSI +
    +
    + +
    Emulating mod_gzip with mod_deflate
    +
    Insert INFLATE filter only if "gzip" is NOT in the + Accept-Encoding header. This filter runs with ftype CONTENT_SET. + + FilterDeclare gzip CONTENT_SET
    + FilterProvider gzip inflate req=Accept-Encoding !$gzip
    + FilterChain gzip +
    +
    + +
    Image Downsampling
    +
    Suppose we want to downsample all web images, and have filters + for GIF, JPEG and PNG. + + FilterProvider unpack jpeg_unpack Content-Type $image/jpeg
    + FilterProvider unpack gif_unpack Content-Type $image/gif
    + FilterProvider unpack png_unpack Content-Type $image/png
    +
    + FilterProvider downsample downsample_filter Content-Type $image
    + FilterProtocol downsample "change=yes"
    +
    + FilterProvider repack jpeg_pack Content-Type $image/jpeg
    + FilterProvider repack gif_pack Content-Type $image/gif
    + FilterProvider repack png_pack Content-Type $image/png
    + <Location /image-filter>
    + + FilterChain unpack downsample repack
    +
    + </Location> +
    +
    +
    +
    + +
    Protocol Handling +

    Historically, each filter is responsible for ensuring that whatever + changes it makes are correctly represented in the HTTP response headers, + and that it does not run when it would make an illegal change. This + imposes a burden on filter authors to re-implement some common + functionality in every filter:

    + +
      +
    • Many filters will change the content, invalidating existing content + tags, checksums, hashes, and lengths.
    • + +
    • Filters that require an entire, unbroken response in input need to + ensure they don't get byteranges from a backend.
    • + +
    • Filters that transform output in a filter need to ensure they don't + violate a Cache-Control: no-transform header from the + backend.
    • + +
    • Filters may make responses uncacheable.
    • +
    + +

    mod_filter aims to offer generic handling of these + details of filter implementation, reducing the complexity required of + content filter modules. This is work-in-progress; the + FilterProtocol implements + some of this functionality, but there are no API calls yet.

    + +

    At the same time, mod_filter should not interfere + with a filter that wants to handle all aspects of the protocol. By + default (i.e. in the absence of any FilterProtocol directives), mod_filter + will leave the headers untouched.

    +
    + + +FilterDeclare +Declare a smart filter +FilterDeclare filter-name [type] +server configvirtual host +directory.htaccess +Options + + +

    This directive declares an output filter together with a + header or environment variable that will determine runtime + configuration. The first argument is a filter-name + for use in FilterProvider, + FilterChain and + FilterProtocol directives.

    + +

    The final (optional) argument + is the type of filter, and takes values of ap_filter_type + - namely RESOURCE (the default), CONTENT_SET, + PROTOCOL, TRANSCODE, CONNECTION + or NETWORK.

    +
    +
    + + +FilterProvider +Register a content filter +FilterProvider filter-name provider-name + [req|resp|env]=dispatch match +server configvirtual host +directory.htaccess +Options + + +

    This directive registers a provider for the smart filter. + The provider will be called if and only if the match declared + here matches the value of the header or environment variable declared + as dispatch.

    + +

    + provider-name must have been registered by loading + a module that registers the name with + ap_register_output_filter. + +

    + +

    The dispatch argument is a string with optional + req=, resp= or env= prefix + causing it to dispatch on (respectively) the request header, response + header, or environment variable named. In the absence of a + prefix, it defaults to a response header. A special case is the + word handler, which causes mod_filter + to dispatch on the content handler.

    + +

    The match argument specifies a match that will be applied to + the filter's dispatch criterion. The match may be + a string match (exact match or substring), a regexp, an integer (greater, + lessthan or equals), or unconditional. The first characters of the + match argument determines this:

    + +

    First, if the first character is an exclamation mark + (!), this reverses the rule, so the provider will be used + if and only if the match fails.

    + +

    Second, it interprets the first character excluding + any leading ! as follows:

    + + + + + + + + + + + + +
    CharacterDescription
    (none)exact match
    $substring match
    /regexp match (delimited by a second /)
    =integer equality
    <integer less-than
    <=integer less-than or equal
    >integer greater-than
    >=integer greater-than or equal
    *Unconditional match
    +
    +
    + + +FilterChain +Configure the filter chain +FilterChain [+=-@!]filter-name ... +server configvirtual host +directory.htaccess +Options + + +

    This configures an actual filter chain, from declared filters. + FilterChain takes any number of arguments, + each optionally preceded with a single-character control that + determines what to do:

    + +
    +
    +filter-name
    +
    Add filter-name to the end of the filter chain
    + +
    @filter-name
    +
    Insert filter-name at the start of the filter chain
    + +
    -filter-name
    +
    Remove filter-name from the filter chain
    + +
    =filter-name
    +
    Empty the filter chain and insert filter-name
    + +
    !
    +
    Empty the filter chain
    + +
    filter-name
    +
    Equivalent to +filter-name
    +
    +
    +
    + + +FilterProtocol +Deal with correct HTTP protocol handling +FilterProtocol filter-name [provider-name] + proto-flags +server configvirtual host +directory.htaccess +Options + + +

    This directs mod_filter to deal with ensuring the + filter doesn't run when it shouldn't, and that the HTTP response + headers are correctly set taking into account the effects of the + filter.

    + +

    There are two forms of this directive. With three arguments, it + applies specifically to a filter-name and a + provider-name for that filter. + With two arguments it applies to a filter-name whenever the + filter runs any provider.

    + +

    proto-flags is one or more of

    + +
    +
    change=yes
    +
    The filter changes the content, including possibly the content + length
    + +
    change=1:1
    +
    The filter changes the content, but will not change the content + length
    + +
    byteranges=no
    +
    The filter cannot work on byteranges and requires complete input
    + +
    proxy=no
    +
    The filter should not run in a proxy context
    + +
    proxy=transform
    +
    The filter transforms the response in a manner incompatible with + the HTTP Cache-Control: no-transform header.
    + +
    cache=no
    +
    The filter renders the output uncacheable (eg by introducing randomised + content changes)
    +
    +
    +
    + + +FilterTrace +Get debug/diagnostic information from + mod_filter +FilterTrace filter-name level +server configvirtual host +directory + + +

    This directive generates debug information from + mod_filter. + It is designed to help test and debug providers (filter modules), although + it may also help with mod_filter itself.

    + +

    The debug output depends on the level set:

    +
    +
    0 (default)
    +
    No debug information is generated.
    + +
    1
    +
    mod_filter will record buckets and brigades + passing through the filter to the error log, before the provider has + processed them. This is similar to the information generated by + mod_diagnostics. +
    + +
    2 (not yet implemented)
    +
    Will dump the full data passing through to a tempfile before the + provider. For single-user debug only; this will not + support concurrent hits.
    +
    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_filter.xml.meta b/trunk/docs/manual/mod/mod_filter.xml.meta new file mode 100644 index 0000000000..2c0aaddacd --- /dev/null +++ b/trunk/docs/manual/mod/mod_filter.xml.meta @@ -0,0 +1,11 @@ + + + + mod_filter + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_headers.html b/trunk/docs/manual/mod/mod_headers.html new file mode 100644 index 0000000000..3729f8da6c --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.html @@ -0,0 +1,11 @@ +URI: mod_headers.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_headers.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_headers.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_headers.html.en b/trunk/docs/manual/mod/mod_headers.html.en new file mode 100644 index 0000000000..d414304c4d --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.html.en @@ -0,0 +1,354 @@ + + + +mod_headers - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_headers

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Customization of HTTP request and response +headers
    Status:Extension
    Module Identifier:headers_module
    Source File:mod_headers.c
    Compatibility:RequestHeader +is available only in Apache 2.0
    +

    Summary

    + +

    This module provides directives to control and modify HTTP + request and response headers. Headers can be merged, replaced + or removed.

    +
    + +
    top
    +
    +

    Order of Processing

    + +

    The directives provided by mod_headers can + occur almost anywhere within the server configuration, and can be + limited in scope by enclosing them in configuration sections.

    + +

    Order of processing is important and is affected both by the + order in the configuration file and by placement in configuration sections. These + two headers have a different effect if reversed:

    + +

    + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +

    + +

    This way round, the MirrorID header is not set. If + reversed, the MirrorID header is set to "mirror 12".

    +
    top
    +
    +

    Early and Late Processing

    +

    mod_headers can be applied either early or late + in the request. The normal mode is late, when Request Headers are + set immediately before running the content generator and Response + Headers just as the response is sent down the wire. Always use + Late mode in an operational server.

    + +

    Early mode is designed as a test/debugging aid for developers. + Directives defined using the early keyword are set + right at the beginning of processing the request. This means + they can be used to simulate different requests and set up test + cases, but it also means that headers may be changed at any time + by other modules before generating a Response.

    + +

    Because early directives are processed before the request path's + configuration is traversed, early headers can only be set in a + main server or virtual host context. Early directives cannot depend + on a request path, so they will fail in contexts such as + <Directory> or <Location>.

    +
    top
    +
    +

    Examples

    + +
      +
    1. + Copy all request headers that begin with "TS" to the + response headers: + +

      + Header echo ^TS +

      +
    2. + +
    3. + Add a header, MyHeader, to the response including a + timestamp for when the request was received and how long it + took to begin serving the request. This header can be used by + the client to intuit load on the server or in isolating + bottlenecks between the client and the server. + +

      + Header add MyHeader "%D %t" +

      + +

      results in this header being added to the response:

      + +

      + MyHeader: D=3775428 t=991424704447256 +

      +
    4. + +
    5. + Say hello to Joe + +

      + Header add MyHeader "Hello Joe. It took %D microseconds \
      + for Apache to serve this request." +

      + +

      results in this header being added to the response:

      + +

      + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache + to serve this request. +

      +
    6. + +
    7. + Conditionally send MyHeader on the response if and + only if header "MyRequestHeader" is present on the request. This + is useful for constructing headers in response to some client + stimulus. Note that this example requires the services of the + mod_setenvif module. + +

      + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader
      +

      + +

      If the header MyRequestHeader: value is present on + the HTTP request, the response will contain the following header:

      + +

      + MyHeader: D=3775428 t=991424704447256 mytext +

      +
    8. +
    +
    +
    top
    +

    Header Directive

    + + + + + + + +
    Description:Configure HTTP response headers
    Syntax:Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_headers
    +

    This directive can replace, merge or remove HTTP response + headers. The header is modified just after the content handler + and output filters are run, allowing outgoing headers to be + modified.

    + +

    The optional condition can be either onsuccess + or always. It determines, which internal header table should be + operated on. onsuccess stands for 2xx + status codes and always for all status codes (including + 2xx). Especially if you want to unset headers + set by certain modules, you should try out, which table is affected.

    + +

    The action it performs is determined by the second + argument. This can be one of the following values:

    + +
    +
    set
    +
    The response header is set, replacing any previous header + with this name. The value may be a format string.
    + +
    append
    +
    The response header is appended to any existing header of + the same name. When a new value is merged onto an existing + header it is separated from the existing header with a comma. + This is the HTTP standard way of giving a header multiple values.
    + +
    add
    +
    The response header is added to the existing set of headers, + even if this header already exists. This can result in two + (or more) headers having the same name. This can lead to + unforeseen consequences, and in general "append" should be + used instead.
    + +
    unset
    +
    The response header of this name is removed, if it exists. + If there are multiple headers of the same name, all will be + removed. value must be omitted.
    + +
    echo
    +
    Request headers with this name are echoed back in the + response headers. header may be a regular expression. + value must be omitted.
    +
    + +

    This argument is followed by a header name, which + can include the final colon, but it is not required. Case is + ignored for set, append, add + and unset. The header name for echo + is case sensitive and may be a regular expression.

    + +

    For add, append and set a + value is specified as the third argument. If value + contains spaces, it should be surrounded by doublequotes. + value may be a character string, a string containing format + specifiers or a combination of both. The following format specifiers + are supported in value:

    + + + + + + + + + + + + +
    FormatDescription
    %%The percent sign
    %tThe time the request was received in Universal Coordinated Time + since the epoch (Jan. 1, 1970) measured in microseconds. The value + is preceded by t=.
    %DThe time from when the request was received to the time the + headers are sent on the wire. This is a measure of the duration + of the request. The value is preceded by D=.
    %{FOOBAR}eThe contents of the environment + variable FOOBAR.
    %{FOOBAR}sThe contents of the SSL environment + variable FOOBAR, if mod_ssl is enabled.
    + +

    Note

    +

    The %s format specifier is only available in + Apache 2.1 and later; it can be used instead of %e + to avoid the overhead of enabling SSLOptions + +StdEnvVars. If SSLOptions +StdEnvVars must + be enabled anyway for some other reason, %e will be + more efficient than %s.

    +
    + +

    The Header directive may be followed by an + an additional argument, which may be used to specify conditions under + which the action will be taken, or may be the keyword early + to specify early processing. If the + environment variable specified in the + env=... argument exists (or if the environment + variable does not exist and env=!... is specified) + then the action specified by the Header directive + will take effect. Otherwise, the directive will have no effect + on the request.

    + +

    Except in early mode, the + Header directives are processed just + before the response is sent to the network. These means that it is + possible to set and/or override most headers, except for those headers + added by the header filter.

    + +
    +
    top
    +

    RequestHeader Directive

    + + + + + + + +
    Description:Configure HTTP request headers
    Syntax:RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_headers
    +

    This directive can replace, merge or remove HTTP request + headers. The header is modified just before the content handler + is run, allowing incoming headers to be modified. The action it + performs is determined by the first argument. This can be one + of the following values:

    + +
    +
    set
    +
    The request header is set, replacing any previous header + with this name
    + +
    append
    +
    The request header is appended to any existing header of the + same name. When a new value is merged onto an existing header + it is separated from the existing header with a comma. This + is the HTTP standard way of giving a header multiple + values.
    + +
    add
    +
    The request header is added to the existing set of headers, + even if this header already exists. This can result in two + (or more) headers having the same name. This can lead to + unforeseen consequences, and in general append should be + used instead.
    + +
    unset
    +
    The request header of this name is removed, if it exists. If + there are multiple headers of the same name, all will be removed. + value must be omitted.
    +
    + +

    This argument is followed by a header name, which can + include the final colon, but it is not required. Case is + ignored. For add, append and + set a value is given as the third argument. If + value contains spaces, it should be surrounded by double + quotes. For unset, no value should be given. + value may be a character string, a string containing format + specifiers or a combination of both. The supported format specifiers + are the same as for the Header, + please have a look there for details.

    + +

    The RequestHeader directive may be followed by + an additional argument, which may be used to specify conditions under + which the action will be taken, or may be the keyword early + to specify early processing. If the + environment + variable specified in the env=... argument + exists (or if the environment variable does not exist and + env=!... is specified) then the action specified + by the RequestHeader directive will take effect. + Otherwise, the directive will have no effect on the request.

    + +

    Except in early mode, the + RequestHeader directive is processed + just before the request is run by its handler in the fixup phase. + This should allow headers generated by the browser, or by Apache + input filters to be overridden or modified.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_headers.html.ja.euc-jp b/trunk/docs/manual/mod/mod_headers.html.ja.euc-jp new file mode 100644 index 0000000000..59d6c7d943 --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.html.ja.euc-jp @@ -0,0 +1,347 @@ + + + +mod_headers - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_headers

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤È±þÅú¤Î¥Ø¥Ã¥À¤Î¥«¥¹¥¿¥Þ¥¤¥º
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:headers_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_headers.c
    ¸ß´¹À­:RequestHeader +¤Ï Apache 2.0 °Ê¹ß¤Î¤ß¤Ç»ÈÍѲÄǽ
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï HTTP ¤Î¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤È±þÅú¥Ø¥Ã¥À¤òÀ©¸æ¤·¡¢ + Êѹ¹¤¹¤ë¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÄ󶡤·¤Þ¤¹¡£¥Ø¥Ã¥À¤òÄɲä·¤¿¤ê¡¢ + ÃÖ¤­´¹¤¨¤¿¤ê¡¢ºï½ü¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    ½èÍý¤Î½çÈÖ

    + +

    mod_header ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥ÐÀßÄê¤Î¤Û¤Ü¤É¤³¤Ë¤Ç¤â + ½ñ¤¯¤³¤È¤¬¤Ç¤­¡¢±Æ¶Á¤¹¤ëÈϰϤòÀßÄêÍÑ¥»¥¯¥·¥ç¥ó¤Ç°Ï¤à¤³¤È¤Ç¸ÂÄꤹ¤ë + ¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ½èÍý¤Î½çÈ֤ϽÅÍפǡ¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î½çÈ֤ȡ¢ÀßÄêÍÑ¥»¥¯¥·¥ç¥óÆâ¤Î°ÌÃ֤ȤÎξÊý¤Ë + ±Æ¶Á¤µ¤ì¤Þ¤¹¡£°Ê²¼¤ÎÆó¤Ä¤Î¥Ø¥Ã¥À¤Ï½çÈÖ¤¬µÕ¤Ë¤Ê¤ë¤È + °ã¤¦·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹:

    + +

    + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +

    + +

    ¤³¤Î½çÈ֤ξì¹ç¤Ï¡¢MirrorID ¥Ø¥Ã¥À¤ÏÀßÄꤵ¤ì¤Þ¤»¤ó¡£ + µÕ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¡¢MirrorID ¥Ø¥Ã¥À¤Ï "mirror 12" ¤ËÀßÄꤵ¤ì¤Þ¤¹¡£

    +
    top
    +
    +

    Áá´ü½èÍý¡¢¸å´ü½èÍý

    +

    mod_headers ¤Ç¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ÎÁá´ü¤«¸å´ü¤«¤Î + ¤É¤Á¤é¤ÇŬÍѤ¹¤ë¤«¤òÁª¤Ù¤Þ¤¹¡£Ä̾ï¤Ï¸å´ü¥â¡¼¥É¤Ç¡¢ + ¥³¥ó¥Æ¥ó¥ÄÀ¸À®¤¬¼Â¹Ô¤µ¤ì¤ëľÁ°¤Ë¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤¬¥»¥Ã¥È¤µ¤ì¡¢ + ¥ì¥¹¥Ý¥ó¥¹¤È¤·¤ÆÁ÷½Ð¤µ¤ì¤ëľÁ°¤Ë¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À¤¬¥»¥Ã¥È¤µ¤ì¤Þ¤¹¡£ + ±¿ÍÑÃæ¤Î¥µ¡¼¥Ð¤Ç¤Ïɬ¤º¸å´ü¥â¡¼¥É¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Áá´ü¥â¡¼¥É¤Ï³«È¯¼Ô¸þ¤±¤Î¥Æ¥¹¥È/¥Ç¥Ð¥Ã¥°ÍѤËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ + early ¥­¡¼¥ï¡¼¥É»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤Ã¤Æ¡¢ + ¥ê¥¯¥¨¥¹¥È½èÍý¤Î³«»ÏÃÏÅÀ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢°Û¤Ê¤ë¥ê¥¯¥¨¥¹¥È¤ò»î¤·¤¿¤ê¥Æ¥¹¥È¥±¡¼¥¹¤ò¥»¥Ã¥È¥¢¥Ã¥×¤¹¤ë¤Î¤Ë + ³èÍѤǤ­¤ë°ìÊý¤Ç¡¢¥ì¥¹¥Ý¥ó¥¹¤òÀ¸À®¤¹¤ëÁ°¤Ë¾¤Î¥â¥¸¥å¡¼¥ë¤Ë¤è¤Ã¤Æ + ¥Ø¥Ã¥À¤¬½ñ¤­´¹¤¨¤é¤ì¤Æ¤·¤Þ¤¦¤«¤â¤·¤ì¤Ê¤¤¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£

    + +

    early ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¥ê¥¯¥¨¥¹¥È¥Ñ¥¹¤ÎÀßÄ꤬²ò·è¤µ¤ì¤ëÁ°¤Ë + ½èÍý¤µ¤ì¤ë¤Î¤Ç¡¢¥á¥¤¥ó¥µ¡¼¥Ð¤«¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥³¥ó¥Æ¥­¥¹¥È¤Ç¤Î¤ß¡¢ + Áá´ü¥Ø¥Ã¥À¤ò¥»¥Ã¥È¤Ç¤­¤Þ¤¹¡£early ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥ê¥¯¥¨¥¹¥È¥Ñ¥¹¤Ë + °Í¸¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¤Î¤Ç¡¢<Directory> ¤ä + <Location> ¤È¤¤¤Ã¤¿¥³¥ó¥Æ¥­¥¹¥ÈÆâ¤Ç¤Ï»ÈÍÑ + ¤Ç¤­¤Þ¤»¤ó¡£

    +
    top
    +
    +

    Îã

    + +
      +
    1. ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥ÀÃæ¤Î "TS" ¤Ç»Ï¤Þ¤ë¥Õ¥£¡¼¥ë¥É¤ò¤¹¤Ù¤Æ±þÅú¥Ø¥Ã¥À¤Ë + ¥³¥Ô¡¼¤·¤Þ¤¹: +

      + Header echo ^TS +

      +
    2. + +
    3. + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿»þ¹ï¤È¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤·¤¿»þ´Ö¤òÆþ¤ì¤¿¥Ø¥Ã¥À¡¢ + MyHeader ¤ò±þÅú¤ËÄɲä·¤Þ¤¹¡£¤³¤Î¥Ø¥Ã¥À¤Ï¥¯¥é¥¤¥¢¥ó¥È¤¬ + ¥µ¡¼¥Ð¤ÎÉé²Ù¤òľ´ÑŪ¤ËÃΤ뤿¤á¤ä¡¢¥¯¥é¥¤¥¢¥ó¥È-¥µ¡¼¥Ð´Ö¤Î + ¥Ü¥È¥ë¥Í¥Ã¥¯¤òÄ´¤Ù¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + +

      + Header add MyHeader "%D %t" +

      + +

      ¾åµ­¤ÎÀßÄê¤Ç¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ê¥Ø¥Ã¥À¤¬±þÅú¤ËÄɲ䵤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹:

      + +

      + MyHeader: D=3775428 t=991424704447256 +

      +
    4. + +
    5. + Joe ¤Ë¤¢¤¤¤µ¤Ä¤ò¤·¤Þ¤¹: + +

      + Header add MyHeader "Hello Joe. It took %D microseconds for Apache to serve this request." +

      + +

      °Ê²¼¤Î¤è¤¦¤Ê¥Ø¥Ã¥À¤¬±þÅú¤ËÄɲ䵤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹

      + +

      + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache to serve this request. +

      +
    6. + +
    7. ¥ê¥¯¥¨¥¹¥È¤Ë "MyRequestHeader" ¤¬¤¢¤ë¤È¤­¤Ë¸Â¤ê MyHeader ¤ò±þÅú¤Ë + ÉÕ¤±¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÎÍ×µá¤Ë±þ¤¨¤Æ¥Ø¥Ã¥À¤òºîÀ®¤¹¤ë¤È¤­¤Ë + Ìò¤ËΩ¤Á¤Þ¤¹¡£¤³¤ÎÎã¤Ç¤Ï mod_setenvif ¥â¥¸¥å¡¼¥ë¤¬É¬Íפʤ³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + +

      + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader +

      + +

      ¤â¤· HTTP ¥ê¥¯¥¨¥¹¥È¤Ë MyRequestHeader: value ¥Ø¥Ã¥À¤¬ + ¤¢¤ë¤È¡¢±þÅú¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ê¥Ø¥Ã¥À¤¬Éղ䵤ì¤Þ¤¹¡£

      + +

      + MyHeader: D=3775428 t=991424704447256 mytext +

      +
    8. +
    +
    +
    top
    +

    Header ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:HTTP ±þÅú¥Ø¥Ã¥À¤ÎÀßÄê
    ¹½Ê¸:Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_headers
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï HTTP ±þÅú¥Ø¥Ã¥À¤òÃÖ´¹¡¢Äɲᢺï½ü¤Ç¤­¤Þ¤¹¡£ + ¥Ø¥Ã¥À¤Ï¥³¥ó¥Æ¥ó¥È¥Ï¥ó¥É¥é¤ä½ÐÎÏ¥Õ¥£¥ë¥¿¤¬¼Â¹Ô¤µ¤ì¤¿Ä¾¸å¤Ë¼Â¹Ô¤µ¤ì¡¢ + ½Ð¤Æ¹Ô¤¯¥Ø¥Ã¥À¤òÊѹ¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥ª¥×¥·¥ç¥ó¤Î condition ¤Ï onsuccess ¤« + always ¤Î¤É¤Á¤é¤«¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£¤³¤ì¤ÏÆâÉô¥Ø¥Ã¥À¥Æ¡¼¥Ö¥ë¤Î¤É¤ì¤ò + Áàºî¤¹¤ë¤«¤ò·èÄꤷ¤Þ¤¹¡£onsuccess ¤Ï 2xx + ¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤Î¡¢always ¤ÏÁ´¤Æ¤Î¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É + (2xx ¤ò´Þ¤à) ¤Î°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤¢¤ë¥â¥¸¥å¡¼¥ë¤Ç¥»¥Ã¥È¤µ¤ì¤ë¥Ø¥Ã¥À¤ò¥¢¥ó¥»¥Ã¥È¤·¤¿¤¤¾ì¹ç¤ÏÆäˡ¢ + ¤É¤Î¥Æ¡¼¥Ö¥ë¤¬±Æ¶Á¤ò¼õ¤±¤ë¤«¤ò¼ÂºÝ¤Ë»î¤·¤¿¤Û¤¦¤¬¤è¤¤¤Ç¤·¤ç¤¦¡£

    + +

    ¹Ô¤Ê¤¦½èÍý¤ÏÆóÈÖÌܤΤΰú¿ô¤Ç·è¤Þ¤ê¤Þ¤¹¡£ + ¤³¤Î°ú¿ô¤Ë¤Ï¼¡¤ÎÃͤò»ØÄê¤Ç¤­¤Þ¤¹:

    + +
    +
    set
    +
    ±þÅú¥Ø¥Ã¥À¤òÀßÄꤷ¤Þ¤¹¡£Æ±¤¸Ì¾Á°¤Î¥Ø¥Ã¥À¤¬Â¸ºß¤¹¤ë¾ì¹ç¤Ï¤½¤ì¤ò + ÃÖ¤­´¹¤¨¤Þ¤¹¡£value ¤Ë¤Ï¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ò + »ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
    + +
    append
    +
    ±þÅú¥Ø¥Ã¥À¤ò´û¤Ë¸ºß¤¹¤ëƱ¤¸Ì¾Á°¤Î¥Ø¥Ã¥À¤ËÄɲä·¤Þ¤¹¡£ + ¿·¤·¤¤Ãͤ¬´û¸¤Î¥Ø¥Ã¥À¤ËÄɲ䵤ì¤ë¤È¤­¤Ë¤Ï¡¢´û¸¤Î¥Ø¥Ã¥À¤Î + ¸å¤Ë¥³¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤ÆÄɲ䵤ì¤Þ¤¹¡£¤³¤ì¤Ï¥Ø¥Ã¥À¤ËÊ£¿ô¤ÎÃͤò + »ØÄꤹ¤ë¤È¤­¤Î HTTP ¤Îɸ½à¤ÎÊýË¡¤Ç¤¹¡£
    + +
    add
    +
    ¥Ø¥Ã¥À¤¬´û¤Ë¸ºß¤·¤Æ¤¤¤ë¤È¤­¤Ç¤µ¤¨¤â¡¢±þÅú¥Ø¥Ã¥À¤ò + ´û¸¤Î¥Ø¥Ã¥À¤ËÄɲä·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢Æó¤Ä (¤«¤½¤ì°Ê¾å) ¤Î + ¥Ø¥Ã¥À¤Î̾Á°¤¬Æ±¤¸¤Ë¤Ê¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤½¤Î·ë²Ì¡¢ÁÛÄê¤Ç¤­¤Ê¤¤ + ¤³¤È¤¬µ¯¤³¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢°ìÈÌŪ¤Ë¤Ï append ¤ÎÊý¤ò + »È¤¦Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£
    + +
    unset
    +
    ¤â¤·»ØÄꤵ¤ì¤¿Ì¾Á°¤Î±þÅú¥Ø¥Ã¥À¤¬Â¸ºß¤·¤Æ¤¤¤ì¤Ð¡¢ºï½ü¤µ¤ì¤Þ¤¹¡£ + Ʊ¤¸Ì¾Á°¤Î¥Ø¥Ã¥À¤¬Ê£¿ô¤¢¤ë¤È¤­¤Ï¡¢¤¹¤Ù¤Æºï½ü¤µ¤ì¤Þ¤¹¡£ + value ¤ò¤Ä¤±¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£
    + +
    echo
    +
    »ØÄꤵ¤ì¤¿¤â¤Î¤ÈƱ¤¸Ì¾Á°¤Î¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ò±þÅú¥Ø¥Ã¥À¤Ç + ¤½¤Î¤Þ¤ÞÊÖ¤·¤Þ¤¹¡£header ¤Ë¤ÏÀµµ¬É½¸½¤â»ØÄê¤Ç¤­¤Þ¤¹¡£ + value ¤ò¤Ä¤±¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£
    +
    + +

    ¤³¤Î°ú¿ô¤Î¸å¤Ë¤Ï¥Ø¥Ã¥À̾ (header) ¤¬Â³¤­¤Þ¤¹¡£ + ¥Ø¥Ã¥À̾¤Ë¤ÏºÇ¸å¤Ë¥³¥í¥ó¤ò´Þ¤á¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢Ìµ¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£ + set, append, add, + unset ¤Ç¤ÏÂçʸ»ú¾®Ê¸»ú¤Ï + ¶èÊ̤µ¤ì¤Þ¤»¤ó¡£echo ¤Î header ̾¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¡¢ + Àµµ¬É½¸½¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    add, append, + set ¤Ç¤Ï value ¤ò»°¤ÄÌܤΠ+ °ú¿ô¤È¤·¤Æ»ØÄꤷ¤Þ¤¹¡£value ¤Ë¶õÇò¤¬¤¢¤ë¾ì¹ç¤ÏÆó½Å°úÍÑÉä¤Ç + °Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£value ¤Ïʸ»ú¤Î¤ß¤«¤é¤Ê¤ëʸ»úÎó¡¢ + ¥Õ¥©¡¼¥Þ¥Ã¥È»Ø¼¨»Ò¤ò´Þ¤àʸ»úÎ󡢤⤷¤¯¤ÏξÊý¤«¤é¤Ê¤ëʸ»úÎó¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£ + value ¤Ï°Ê²¼¤Î¥Õ¥©¡¼¥Þ¥Ã¥È»Ø¼¨»Ò¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹:

    + + + + + + + + + + + + +
    ¥Õ¥©¡¼¥Þ¥Ã¥È²òÀâ
    %%¥Ñ¡¼¥»¥ó¥Èµ­¹æ
    %t¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤Ã¤¿»þ¹ï¤ò¡¢ + Universal Coordinated Time ¤Ç¤Î»Ï¤Þ¤ê¤Î»þ¹ï (Jan. 1, 1970) ¤«¤é·Ð²á¤·¤¿ + »þ´Ö¤ò¥Þ¥¤¥¯¥íÉäȤ·¤Æ¸½¤·¤¿¤â¤Î¡£Ãͤκǽé¤Ë¤Ï + t= ¤¬Éղ䵤ì¤Þ¤¹¡£
    %D¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤Ã¤¿»þ¹ï¤È¡¢¥Ø¥Ã¥À¤òÁ÷¤ê½Ð¤·¤¿ + »þ´Ö¤È¤Îº¹¡£¤³¤ì¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤¬Â¸ºß¤·¤Æ¤¤¤¿´ü´Ö¤ò¸½¤·¤Þ¤¹¡£ + Ãͤκǽé¤Ë¤Ï D= ¤¬Éղ䵤ì¤Þ¤¹¡£
    %{FOOBAR}e´Ä¶­ÊÑ¿ô + FOOBAR ¤ÎÃͤǤ¹¡£
    %{FOOBAR}smod_ssl ¤¬Í­¸ú¤Ê¾ì¹ç¡¢ + SSL ´Ä¶­ÊÑ¿ô FOOBAR + ¤ÎÆâÍÆ
    + +

    Ãí

    +

    %s ¥Õ¥©¡¼¥Þ¥Ã¥È»ØÄê»Ò¤Ï 2.1 °Ê¹ß¤Ç¤Î¤ßÍøÍѤǤ­¤Þ¤¹¡£ + SSLOptions +StdEnvVars ¤òÍ­¸ú¤Ë¤¹¤ë¤³¤È¤Ë¤è¤ë¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤ò + Èò¤±¤ë¤¿¤á¡¢%e ¤ÎÂå¤ï¤ê¤È¤·¤Æ»È¤¨¤Þ¤¹¡£ + ¾¤ÎÍýͳ¤Ê¤É¤¬¤¢¤Ã¤Æ¡¢¤É¤¦¤·¤Æ¤â SSLOptions +StdEnvVars + ¤òÍ­¸ú¤Ë¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¾ì¹ç¤Ï¡¢%e ¤Î¤Û¤¦¤¬ + %s ¤è¤ê¤â½èÍý¸úΨ¤ÏÎɤ¤¤Ç¤¹¡£

    +
    + +

    Header ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤ÏÄɲäΰú¿ô¤ò»ý¤¿¤»¤ë¤³¤È¤¬ + ¤Ç¤­¤Æ¡¢¤É¤¦¤¤¤Ã¤¿¥¢¥¯¥·¥ç¥ó¤¬¹Ô¤ï¤ì¤¿¤«¤Î¾ò·ï¤ò»ØÄꤷ¤¿¤ê¡¢ + Áá´ü½èÍý ¤ò»ØÄꤹ¤ë early ¥­¡¼¥ï¡¼¥É¤ò + »ØÄê¤Ç¤­¤Þ¤¹¡£ + env=... °ú¿ô¤Ç»ØÄꤵ¤ì¤¿ ´Ä¶­ÊÑ¿ô ¤¬Â¸ºß¤¹¤ë (¤â¤·¤¯¤Ï env=!... + ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Æ´Ä¶­ÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤¤) ¾ì¹ç¤Ï¡¢Header + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿Æ°ºî¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤½¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤Ï²¿¤â¤·¤Þ¤»¤ó¡£

    + +

    Áá´ü½èÍý¥â¡¼¥É¤Î¾ì¹ç°Ê³°¤Ç¤Ï¡¢ + Header + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï±þÅú¤¬¥Í¥Ã¥È¥ï¡¼¥¯¤ËÁ÷¤é¤ì¤ëľÁ°¤Ë + ½èÍý¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥Ø¥Ã¥À¥Õ¥£¥ë¥¿¤Ë¤è¤êÄɲ䵤ì¤ë¥Ø¥Ã¥À¤ò + ½ü¤­¡¢¤Û¤È¤ó¤É¤Î¥Ø¥Ã¥À¤òÀßÄꤷ¤¿¤ê¾å½ñ¤­¤·¤¿¤ê¤¹¤ë¤³¤È¤¬ + ²Äǽ¡¢¤È¤¤¤¦¤³¤È¤Ç¤¹¡£

    + +
    +
    top
    +

    RequestHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ÎÀßÄê
    ¹½Ê¸:RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_headers
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤òÃÖ´¹¡¢Äɲᢺï½ü¤Ç¤­¤Þ¤¹¡£ + ¥Ø¥Ã¥À¤Ï¥³¥ó¥Æ¥ó¥È¥Ï¥ó¥É¥é¤¬¼Â¹Ô¤µ¤ì¤ëľÁ°¤Ë¼Â¹Ô¤µ¤ì¡¢ + Æþ¤Ã¤ÆÍè¤ë¥Ø¥Ã¥À¤òÊѹ¹¤¹¤ë¤³¤È¤¬²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¹Ô¤Ê¤¦½èÍý¤ÏÂè 1 °ú¿ô¤Ë¤è¤ê·è¤Þ¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤Ï°Ê²¼¤ÎÃͤò»ØÄê + ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    set
    +
    ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤òÀßÄꤷ¤Þ¤¹¡£Æ±¤¸Ì¾Á°¤Î¥Ø¥Ã¥À¤¬Â¸ºß¤·¤Æ¤¤¤ë¤È¡¢ + ¤½¤ì¤òÃÖ¤­´¹¤¨¤Þ¤¹¡£
    + +
    append
    +
    ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ï¡¢´û¤Ë¸ºß¤¹¤ëƱ¤¸Ì¾Á°¤Î¥Ø¥Ã¥À¤ËÄɲ䵤ì¤Þ¤¹¡£ + ¿·¤·¤¤Ãͤ¬´û¸¤Î¥Ø¥Ã¥À¤ËÄɲ䵤ì¤ë¤È¤­¤Ë¤Ï¡¢´û¸¤Î¥Ø¥Ã¥À¤Î + ¸å¤Ë¥³¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤ÆÄɲ䵤ì¤Þ¤¹¡£¤³¤ì¤Ï¥Ø¥Ã¥À¤ËÊ£¿ô¤ÎÃͤò + »ØÄꤹ¤ë¤È¤­¤Î HTTP ¤Îɸ½à¤ÎÊýË¡¤Ç¤¹¡£
    + +
    add
    +
    ¥Ø¥Ã¥À¤¬´û¤Ë¸ºß¤·¤Æ¤¤¤ë¤È¤­¤Ç¤µ¤¨¤â¡¢¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ò + ´û¸¤Î¥Ø¥Ã¥À¤ËÄɲä·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢Æó¤Ä (¤«¤½¤ì°Ê¾å) ¤Î + ¥Ø¥Ã¥À¤Î̾Á°¤¬Æ±¤¸¤Ë¤Ê¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤½¤Î·ë²Ì¡¢ÁÛÄê¤Ç¤­¤Ê¤¤ + ¤³¤È¤¬µ¯¤³¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢°ìÈÌŪ¤Ë¤Ï append ¤ÎÊý¤ò + »È¤¦Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£
    + +
    unset
    +
    ¤â¤·»ØÄꤵ¤ì¤¿Ì¾Á°¤Î¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤¬Â¸ºß¤·¤Æ¤¤¤ì¤Ð¡¢ºï½ü¤µ¤ì¤Þ¤¹¡£ + Ʊ¤¸Ì¾Á°¤ÎÊ£¿ô¤Î¥Ø¥Ã¥À¤¬¤¢¤ë¤È¤­¤Ï¡¢¤¹¤Ù¤Æºï½ü¤µ¤ì¤Þ¤¹¡£ + value ¤ò¤Ä¤±¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£
    +
    + +

    ¤³¤Î°ú¿ô¤Î¸å¤Ë¤Ï¥Ø¥Ã¥À̾ (header) ¤¬Â³¤­¤Þ¤¹¡£ + ¥Ø¥Ã¥À̾¤Ë¤ÏºÇ¸å¤Ë¥³¥í¥ó¤ò´Þ¤á¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢Ìµ¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£ + Âçʸ»ú¾®Ê¸»ú¤Ï¶èÊ̤µ¤ì¤Þ¤»¤ó¡£add, + append, set ¤Î¾ì¹ç¤Ï¡¢value ¤¬»°¤ÄÌܤΠ+ °ú¿ô¤È¤·¤Æ»ØÄꤵ¤ì¤Þ¤¹¡£value ¤Ë¶õÇò¤¬¤¢¤ë¾ì¹ç¤ÏÆó½Å°úÍÑÉä¤Ç + °Ï¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£unset ¤Î¾ì¹ç¤Ï¡¢value ¤Ï»ØÄꤷ¤Þ¤»¤ó¡£ + value ¤Ïʸ»úÎó¡¢¥Õ¥©¡¼¥Þ¥Ã¥È»ØÄê»Ò¡¢¤¢¤ë¤¤¤Ï¡¢¤½¤Îº®¹ç¤Ç¤¹¡£ + »È¤¦¤³¤È¤Î¤Ç¤­¤ë¥Õ¥©¡¼¥Þ¥Ã¥È»ØÄê»Ò¤Ï¡¢Header ¤ÈƱ¤¸¤Ç¤¹¤Î¤Ç¡¢ + ¾ÜºÙ¤Ï¤½¤Á¤é¤ò¤´Í÷¤¯¤À¤µ¤¤¡£

    + +

    RequestHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¤É¤¦¤¤¤Ã¤¿¾ò·ï²¼¤Ç¥¢¥¯¥·¥ç¥ó¤ò¹Ô¤¦¤«¤ò»ØÄꤹ¤ëÄɲðú¿ô + ¤¢¤ë¤¤¤Ï¡¢Áá´ü½èÍý ¤ò»ØÄꤹ¤ë early + ¥­¡¼¥ï¡¼¥É¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + env=... ¤Î°ú¿ô¤ÇÀßÄꤵ¤ì¤Æ¤¤¤ë + ´Ä¶­ÊÑ¿ô ¤¬Â¸ºß¤·¤Æ¤¤¤ë + (¤¢¤ë¤¤¤Ï env=!... ¤Ç»ØÄꤵ¤ì¤¿´Ä¶­ÊÑ¿ô¤¬ + ¸ºß¤·¤Ê¤¤) ¾ì¹ç¡¢RequestHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Í­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¸úÎϤò»ý¤Á¤Þ¤»¤ó¡£

    + +

    early ¥â¡¼¥É¤Ç¤Ê¤¤¾ì¹ç¤Ë¸Â¤ê¡¢ + RequestHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + fixup ¥Õ¥§¡¼¥º¤Ç¥ê¥¯¥¨¥¹¥È¤¬¥Ï¥ó¥É¥é¤Ë°·¤ï¤ì¤ëľÁ°¤Ë + ½èÍý¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥Ö¥é¥¦¥¶¤ä Apache ¤ÎÆþÎÏ¥Õ¥£¥ë¥¿¤Ë¤è¤ê + À¸À®¤µ¤ì¤¿¥Ø¥Ã¥À¤ò¾å½ñ¤­¤·¤¿¤ê½¤Àµ¤·¤¿¤ê¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_headers.html.ko.euc-kr b/trunk/docs/manual/mod/mod_headers.html.ko.euc-kr new file mode 100644 index 0000000000..b304214026 --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.html.ko.euc-kr @@ -0,0 +1,337 @@ + + + +mod_headers - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_headers

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:HTTP ¿äû Çì´õ¿Í ÀÀ´ä Çì´õ ¼öÁ¤
    »óÅÂ:Extension
    ¸ðµâ¸í:headers_module
    ¼Ò½ºÆÄÀÏ:mod_headers.c
    Áö¿ø:RequestHeader´Â ¾ÆÆÄÄ¡ 2.0¿¡¸¸ +ÀÖ´Ù
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº HTTP ¿äû Çì´õ¿Í ÀÀ´ä Çì´õ¸¦ Á¶ÀýÇÏ°í ¼öÁ¤ÇÏ´Â + Áö½Ã¾îµéÀ» Á¦°øÇÑ´Ù. Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    ó¸® ¼ø¼­

    + +

    mod_headers°¡ Á¦°øÇÏ´Â Áö½Ã¾î´Â ¼­¹ö¼³Á¤ÀÇ + °ÅÀÇ ¸ðµç Àå¼Ò¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, ¼³Á¤ ¼½¼ÇÀ¸·Î °¨½Î¼­ Áö½Ã¾îÀÇ + ¹üÀ§¸¦ Á¦ÇÑÇÒ ¼öµµ ÀÖ´Ù.

    + +

    󸮼ø¼­´Â Áß¿äÇϸç, ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â ¼ø¼­¿Í ¼³Á¤ ¼½¼ÇÀÇ ¿µÇâÀ» ¹Þ´Â´Ù. + ´ÙÀ½ µÎ Áö½Ã¾î¸¦ ¹Ý´ë·Î ÀûÀ¸¸é È¿°ú°¡ ´Þ¶óÁø´Ù.

    + +

    + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +

    + +

    À§¿Í °°ÀÌ ÀûÀ¸¸é MirrorID Çì´õ°¡ ³ª¿ÀÁö + ¾Ê´Â´Ù. ¹Ý´ë·Î ÀûÀ¸¸é MirrorID Çì´õ¸¦ "mirror 12"·Î ¼³Á¤ÇÑ´Ù.

    +
    top
    +
    +

    À̸¥(early) ó¸®¿Í ´ÊÀº(late) ó¸®

    +

    mod_headers¸¦ ¿äû Ãʱ⳪ ³ªÁß¿¡ Àû¿ëÇÒ + ¼ö ÀÖ´Ù. º¸ÅëÀº ³»¿ë»ý¼ºÀÚ¸¦ ½ÇÇàÇϱâ Á÷Àü¿¡ ¿äû Çì´õ¸¦ + ¼³Á¤ÇÏ°í ÀÀ´äÀ» ³×Æ®¿÷¿¡ ¾µ¶§ ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÏ´Â ´ÊÀº(late) + ¹æ½ÄÀ» »ç¿ëÇÑ´Ù. ½ÇÁ¦ ¼­ºñ½ºÇÏ´Â ¼­¹ö¿¡¼­´Â Ç×»ó ´À¸° ¹æ½ÄÀ» + »ç¿ëÇ϶ó.

    + +

    À̸¥(early) ¹æ½ÄÀº °³¹ßÀÚ¸¦ À§ÇØ °Ë»ç/µð¹ö±ë¿ëÀ¸·Î ¸¸µé¾ú´Ù. + early Å°¿öµå¸¦ »ç¿ëÇÏ¿© Á¤ÀÇÇÑ Áö½Ã¾î´Â ¿äûÀ» + ó¸®Çϱ⠽ÃÀÛÇÒ¶§ ¼³Á¤ÇÑ´Ù. Áï, ´Ù¸¥ ¿äûÀ» ¸ðÀǽÇÇèÇϰųª + °Ë»ç¸¦ ÇϱâÀ§ÇØ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ÀÀ´äÀ» »ý¼ºÇϱâ Àü¿¡ ´Ù¸¥ + ¸ðµâÀÌ ºÒ½Ã¿¡ Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿äû°æ·Î¿¡ ´ëÇÑ ¼³Á¤À» »ìÆ캸±â Àü¿¡ À̸¥ Áö½Ã¾î¸¦ + ó¸®Çϱ⶧¹®¿¡ À̸¥ Çì´õ Áö½Ã¾î´Â ÁÖ¼­¹öÀ̳ª °¡»óÈ£½ºÆ® + »ç¿ëÀå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. À̸¥ Áö½Ã¾î´Â ¿äû°æ·Î¿¡ + ÀÇÁ¸ÇÒ ¼ö ¾ø±â¶§¹®¿¡ <Directory>³ª + <Location>°°Àº »ç¿ëÀå¼Ò¿¡¼­ »ç¿ëÇÒ ¼ö + ¾ø´Ù.

    +
    top
    +
    +

    ¿¹Á¦

    + +
      +
    1. + "TS"·Î ½ÃÀÛÇÏ´Â ¸ðµç ¿äû Çì´õ¸¦ ÀÀ´ä Çì´õ·Î º¹»çÇÑ´Ù. + +

      + Header echo ^TS +

      +
    2. + +
    3. + ÀÀ´ä¿¡ ¿äûÀ» ¹ÞÀº ½Ã°£°ú ¿äûÀ» ¼­ºñ½ºÇϴµ¥ °É¸± ½Ã°£À» + ¾Ë·ÁÁÖ´Â MyHeader Çì´õ¸¦ Ãß°¡ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®´Â + ÀÌ Çì´õ¸¦ º¸°í ¼­¹öÀÇ ºÎÇϸ¦ ÃßÁ¤Çϰųª Ŭ¶óÀ̾ðÆ®¿Í + ¼­¹ö°£ÀÇ º´¸ñÁ¡À» ãÀ» ¼ö ÀÖ´Ù. + +

      + Header add MyHeader "%D %t" +

      + +

      ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + +

      + MyHeader: D=3775428 t=991424704447256 +

      +
    4. + +
    5. + Joe¿¡°Ô ¾È³ç + +

      + Header add MyHeader "Hello Joe. It took %D microseconds \
      + for Apache to serve this request." +

      + +

      ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + +

      + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache + to serve this request. +

      +
    6. + +
    7. + ¿äû¿¡ "MyRequestHeader" Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ ¼±ÅÃÀûÀ¸·Î + ÀÀ´ä¿¡ MyHeader¸¦ º¸³½´Ù. ƯÁ¤ Ŭ¶óÀ̾ðÆ®¿¡°Ô¸¸ + ÀÀ´ä¿¡ Çì´õ¸¦ Ãß°¡ÇÒ¶§ À¯¿ëÇÏ´Ù. ÀÌ ¿¹Á¦°¡ µ¿ÀÛÇÏ·Á¸é + mod_setenvif ¸ðµâÀÌ ÇÊ¿äÇÏ´Ù. + +

      + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader
      +

      + +

      HTTP ¿äû¿¡ MyRequestHeader: value Çì´õ°¡ + ÀÖ´Ù¸é, ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + +

      + MyHeader: D=3775428 t=991424704447256 mytext +

      +
    8. +
    +
    +
    top
    +

    Header Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:HTTP ÀÀ´ä Çì´õ¸¦ ±¸¼ºÇÑ´Ù
    ¹®¹ý:Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Extension
    ¸ðµâ:mod_headers
    +

    ÀÌ Áö½Ã¾î´Â HTTP ÀÀ´ä Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÑ´Ù. + ³»¿ë Çڵ鷯¿Í Ãâ·Â ÇÊÅÍ°¡ ½ÇÇàÇÑ Á÷ÈÄ¿¡ Çì´õ¸¦ ¼öÁ¤Çϱ⶧¹®¿¡ + º¸³¾ Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    conditionÀº ¼±ÅÃÀûÀ¸·Î »ç¿ëÇϸç, °ªÀ¸·Î + onsuccess ȤÀº always¸¦ »ç¿ëÇÑ´Ù. + ÀÌ´Â ¾î¶² ³»ºÎ Çì´õÇ¥¿¡ µ¿ÀÛÇÒÁö¸¦ °áÁ¤ÇÑ´Ù. + onsuccess´Â 2xx »óÅÂÄڵ带 + ¶æÇÏ°í, always´Â (2xx¸¦ + Æ÷ÇÔÇÑ) ¸ðµç »óÅÂÄڵ带 ¶æÇÑ´Ù. ƯÈ÷ ¾î¶² ¸ðµâÀÌ ¼³Á¤ÇÑ + Çì´õ¸¦ ÇØÁ¦ÇÏ°í ½Í´Ù¸é, µÑÁß ¾î¶² °ÍÀ» »ç¿ëÇÒÁö Àß »ìÆìºÁ¾ß + ÇÑ´Ù.

    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®¿¡ µû¶ó ±â´ÉÀÌ ´Ù¸£´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®·Î + ¾Æ·¡ °ªÁß Çϳª¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    set
    +
    ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÑ´Ù. °°Àº À̸§À¸·Î ÀÌ¹Ì Çì´õ°¡ ÀÖ´Ù¸é + ´ëüÇÑ´Ù. value¿¡ Çü½Ä¹®ÀÚ¿­À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    append
    +
    ÀÌ¹Ì Á¸ÀçÇÏ´Â °°Àº À̸§ÀÇ ÀÀ´ä Çì´õ¿¡ Ãß°¡ÇÑ´Ù. ±âÁ¸ + Çì´õ¿¡ »õ·Î¿î °ªÀ» ÇÕÄ¡¸é, ±âÁ¸ Çì´õ¿Í »õ·Î¿î °ª »çÀÌ¿¡ + ½°Ç¥¸¦ ºÙÀδÙ. ÀÌ´Â ¿©·¯ Çì´õ°ªÀ» ÁöÁ¤ÇÏ´Â HTTP Ç¥ÁØ ¹æ½ÄÀÌ´Ù.
    + +
    add
    +
    Çì´õ°¡ ÀÌ¹Ì ÀÖ´õ¶óµµ ÀÀ´ä Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ °°Àº + À̸§ÀÇ Çì´õ°¡ µÎ°³ (ȤÀº ¸¹ÀÌ) »ý±æ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀÇ¿ÜÀÇ + °á°ú°¡ ¹ß»ýÇÒ ¼ö Àֱ⶧¹®¿¡ º¸Åë ´ë½Å append¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    unset
    +
    ÀÌ·± À̸§ÀÇ ÀÀ´ä Çì´õ°¡ ÀÖ´Ù¸é »èÁ¦ÇÑ´Ù. °°Àº À̸§À» + °¡Áø Çì´õ°¡ ¿©·¯°³ ÀÖ´Ù¸é ¸ðµÎ Á¦°ÅÇÑ´Ù. value´Â + ÀûÁö ¾Ê´Â´Ù.
    + +
    echo
    +
    ÀÌ·± À̸§ÀÇ ¿äû Çì´õ¸¦ ±×´ë·Î ÀÀ´ä Çì´õ·Î º¸³½´Ù. + header¿¡ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + value´Â ÀûÁö ¾Ê´Â´Ù.
    +
    + +

    ¾Æ±Ô¸ÕÆ® µÚ¿¡ header À̸§ÀÌ ³ª¿Â´Ù. Çì´õ¸í + µÚ¿¡ ÄÝ·ÐÀ» ÀûÀ» ¼ö ÀÖÁö¸¸, ¾ø¾îµµ µÈ´Ù. set, + append, add, unset¿¡¼­ + ´ë¼Ò¹®ÀÚ´Â ¹«½ÃÇÑ´Ù. echoÀÇ header + À̸§Àº ´ë¼ö¹®ÀÚ¸¦ ±¸º°ÇÏ°í Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    add, append, setÀ» + »ç¿ëÇÒ¶§´Â ¼¼¹ø° ¾Æ±Ô¸ÕÆ® value°¡ ÇÊ¿äÇÏ´Ù. + value ¾È¿¡ °ø¹éÀÌ ÀÖ´Ù¸é ½Öµû¿ÈÇ¥·Î ¹­¾î¾ß ÇÑ´Ù. + value´Â ÀÏ¹Ý ¹®ÀÚ¿­À̳ª Çü½ÄÀ» ±â¼úÇÏ´Â ¹®ÀÚ¿­À̸ç, + µÎ°¡Áö¸¦ °°ÀÌ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. value¿¡¼­ Áö¿øÇÏ´Â + Çü½Ä±â¼úÀÚ´Â ´ÙÀ½°ú °°´Ù.

    + + + + + + + + + + + + +
    Çü½Ä¼³¸í
    %%ÆÛ¼¾Æ® ±âÈ£
    %t¿äûÀ» ¹ÞÀº ½Ã°£À» ±¹Á¦Ç¥Áؽ÷Πepoch (1970³â 1¿ù + 1ÀÏ) ÀÌÈÄ Áö³­ ¸¶ÀÌÅ©·ÎÃÊ ´ÜÀ§·Î. °ª ¾Õ¿¡ t=ÀÌ + ºÙ´Â´Ù.
    %D¿äûÀ» ¹ÞÀº ½Ã°£ºÎÅÍ Çì´õ¸¦ ³×Æ®¿÷¿¡ ¾µ¶§±îÁö °É¸° + ½Ã°£. ¿äûÀÇ ±â°£À» Àé´Ù. °ª ¾Õ¿¡ D=ÀÌ + ºÙ´Â´Ù.
    %{FOOBAR}eȯ°æº¯¼ö FOOBARÀÇ + ³»¿ë.
    %{FOOBAR}smod_sslÀÌ µ¿ÀÛÇÑ´Ù¸é, SSL ȯ°æº¯¼ö + FOOBARÀÇ ³»¿ë.
    + +

    ÁÖÀÇ

    +

    %s Çü½Ä Áö½ÃÀÚ´Â ¾ÆÆÄÄ¡ 2.1 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. + ÀÌ Áö½ÃÀÚ´Â SSLOptions +StdEnvVars¸¦ »ç¿ëÇÏ´Â + ºÎ´ãÀ» ´ú±âÀ§ÇØ %e ´ë½Å »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¾î¶² + ÀÌÀ¯¿¡¼­°Ç SSLOptions +StdEnvVars¸¦ »ç¿ëÇØ¾ß + ÇÑ´Ù¸é, %e´Â %s º¸´Ù ÈξÀ ´õ + È¿À²ÀûÀÌ´Ù.

    +
    + +

    Header Áö½Ã¾î µÚ¿¡ ÇൿÀÌ ÀϾ + Á¶°ÇÀ» Áö½ÃÇÏ´Â Ãß°¡ ¾Æ±Ô¸ÕÆ®³ª À̸¥ 󸮸¦ + ¶æÇÏ´Â Å°¿öµå early°¡ ³ª¿Ã ¼ö ÀÖ´Ù. + env=... ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÑ °æ¿ì ÇØ´ç + ȯ°æº¯¼ö°¡ Á¸ÀçÇÑ´Ù¸é (ȤÀº + env=!...¿¡ ³ª¿Â ȯ°æº¯¼ö°¡ Á¸ÀçÇÏÁö + ¾Ê´Ù¸é) Header Áö½Ã¾î°¡ µ¿ÀÛÇÑ´Ù. + ±×·¸Áö ¾ÊÀ¸¸é Áö½Ã¾î´Â ¿äû¿¡ ¾Æ¹« ¿µÇâÀ» ¹ÌÄ¡Áö ¾Ê´Â´Ù.

    + +

    À̸¥ ¹æ½ÄÀÌ ¾Æ´Ï¶ó¸é ÀÀ´äÀ» ³×Æ®¿÷À¸·Î + º¸³»±â Á÷Àü¿¡ Header Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. + ±×·¡¼­ Çì´õ ÇÊÅÍ°¡ Ãß°¡ÇÏ´Â Çì´õ¸¦ Á¦¿ÜÇÑ ´ëºÎºÐÀÇ Çì´õ¸¦ + ¼³Á¤Çϰųª µ¤¾î¾µ ¼ö ÀÖ´Ù.

    + +
    +
    top
    +

    RequestHeader Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:HTTP ¿äû Çì´õ¸¦ ±¸¼ºÇÑ´Ù
    ¹®¹ý:RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Extension
    ¸ðµâ:mod_headers
    +

    ÀÌ Áö½Ã¾î´Â HTTP ¿äû Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÑ´Ù. + ³»¿ë Çڵ鷯°¡ ½ÇÇàÇϱâ Á÷Àü¿¡ Çì´õ¸¦ ¼öÁ¤Çϱ⶧¹®¿¡ ¹ÞÀº + Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. ù¹ø° ¾Æ±Ô¸ÕÆ®¿¡ µû¶ó ±â´ÉÀÌ ´Ù¸£´Ù. + ù¹ø° ¾Æ±Ô¸ÕÆ®·Î ¾Æ·¡ °ªÁß Çϳª¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    set
    +
    ¿äû Çì´õ¸¦ ¼³Á¤ÇÑ´Ù. °°Àº À̸§À¸·Î ÀÌ¹Ì Çì´õ°¡ ÀÖ´Ù¸é + ´ëüÇÑ´Ù
    + +
    append
    +
    ÀÌ¹Ì Á¸ÀçÇÏ´Â °°Àº À̸§ÀÇ ¿äû Çì´õ¿¡ Ãß°¡ÇÑ´Ù. ±âÁ¸ + Çì´õ¿¡ »õ·Î¿î °ªÀ» ÇÕÄ¡¸é, ±âÁ¸ Çì´õ¿Í »õ·Î¿î °ª »çÀÌ¿¡ + ½°Ç¥¸¦ ºÙÀδÙ. ÀÌ´Â ¿©·¯ Çì´õ°ªÀ» ÁöÁ¤ÇÏ´Â HTTP Ç¥ÁØ ¹æ½ÄÀÌ´Ù.
    + +
    add
    +
    Çì´õ°¡ ÀÌ¹Ì ÀÖ´õ¶óµµ ¿äû Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ °°Àº + À̸§ÀÇ Çì´õ°¡ µÎ°³ (ȤÀº ¸¹ÀÌ) »ý±æ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀÇ¿ÜÀÇ + °á°ú°¡ ¹ß»ýÇÒ ¼ö Àֱ⶧¹®¿¡ º¸Åë ´ë½Å append¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    unset
    +
    ÀÌ·± À̸§ÀÇ ¿äû Çì´õ°¡ ÀÖ´Ù¸é »èÁ¦ÇÑ´Ù. °°Àº À̸§À» + °¡Áø Çì´õ°¡ ¿©·¯°³ ÀÖ´Ù¸é ¸ðµÎ Á¦°ÅÇÑ´Ù. value´Â + ÀûÁö ¾Ê´Â´Ù.
    +
    + +

    ¾Æ±Ô¸ÕÆ® µÚ¿¡ Çì´õ¸íÀÌ ³ª¿Â´Ù. Çì´õ¸í µÚ¿¡ ÄÝ·ÐÀ» ÀûÀ» + ¼ö ÀÖÁö¸¸, ¾ø¾îµµ µÈ´Ù. ´ë¼Ò¹®ÀÚ´Â ¹«½ÃÇÑ´Ù. add, + append, setÀ» »ç¿ëÇÒ¶§´Â ¼¼¹ø° + ¾Æ±Ô¸ÕÆ® value°¡ ÇÊ¿äÇÏ´Ù. value ¾È¿¡ + °ø¹éÀÌ ÀÖ´Ù¸é ½Öµû¿ÈÇ¥·Î ¹­¾î¾ß ÇÑ´Ù. unsetÀ» »ç¿ëÇÒ¶§´Â + value¸¦ ÀûÀ¸¸é ¾ÈµÈ´Ù. value´Â ÀÏ¹Ý + ¹®ÀÚ¿­À̳ª Çü½ÄÀ» ±â¼úÇÏ´Â ¹®ÀÚ¿­À̸ç, µÎ°¡Áö¸¦ °°ÀÌ »ç¿ëÇÒ + ¼öµµ ÀÖ´Ù. Áö¿øÇÏ´Â Çü½Ä±â¼úÀÚ´Â Header¿Í °°À¸¹Ç·Î ÀÚ¼¼ÇÑ + ³»¿ëÀº ±×°÷À» Âü°íÇ϶ó.

    + +

    RequestHeader Áö½Ã¾î µÚ¿¡ ÇൿÀÌ + ÀϾ Á¶°ÇÀ» Áö½ÃÇÏ´Â Ãß°¡ ¾Æ±Ô¸ÕÆ®³ª À̸¥ 󸮸¦ ¶æÇÏ´Â Å°¿öµå + early°¡ ³ª¿Ã ¼ö ÀÖ´Ù. env=... + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÑ °æ¿ì ÇØ´ç ȯ°æº¯¼ö°¡ + Á¸ÀçÇÑ´Ù¸é (ȤÀº env=!...¿¡ ³ª¿Â + ȯ°æº¯¼ö°¡ Á¸ÀçÇÏÁö ¾Ê´Ù¸é) RequestHeader + Áö½Ã¾î°¡ µ¿ÀÛÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é Áö½Ã¾î´Â ¿äû¿¡ ¾Æ¹« ¿µÇâÀ» + ¹ÌÄ¡Áö ¾Ê´Â´Ù.

    + +

    À̸¥ ¹æ½ÄÀÌ ¾Æ´Ï¶ó¸é fixup ´Ü°è¿¡¼­ + ¿äû¿¡ ÇØ´çÇÏ´Â Çڵ鷯¸¦ ½ÇÇàÇϱâ Á÷Àü¿¡ + RequestHeader Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. + ±×·¡¼­ ºê¶ó¿ìÀú¿¡ µû¶ó ȤÀº ¾ÆÆÄÄ¡ ÀÔ·ÂÇÊÅÍ°¡ Çì´õ¸¦ µ¤¾î¾²°Å³ª + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_headers.xml b/trunk/docs/manual/mod/mod_headers.xml new file mode 100644 index 0000000000..965a1d9c5d --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.xml @@ -0,0 +1,343 @@ + + + + + + + + + +mod_headers +Customization of HTTP request and response +headers +Extension +mod_headers.c +headers_module +RequestHeader +is available only in Apache 2.0 + + +

    This module provides directives to control and modify HTTP + request and response headers. Headers can be merged, replaced + or removed.

    +
    + +
    Order of Processing + +

    The directives provided by mod_headers can + occur almost anywhere within the server configuration, and can be + limited in scope by enclosing them in configuration sections.

    + +

    Order of processing is important and is affected both by the + order in the configuration file and by placement in configuration sections. These + two headers have a different effect if reversed:

    + + + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +
    + +

    This way round, the MirrorID header is not set. If + reversed, the MirrorID header is set to "mirror 12".

    +
    + +
    Early and Late Processing +

    mod_headers can be applied either early or late + in the request. The normal mode is late, when Request Headers are + set immediately before running the content generator and Response + Headers just as the response is sent down the wire. Always use + Late mode in an operational server.

    + +

    Early mode is designed as a test/debugging aid for developers. + Directives defined using the early keyword are set + right at the beginning of processing the request. This means + they can be used to simulate different requests and set up test + cases, but it also means that headers may be changed at any time + by other modules before generating a Response.

    + +

    Because early directives are processed before the request path's + configuration is traversed, early headers can only be set in a + main server or virtual host context. Early directives cannot depend + on a request path, so they will fail in contexts such as + <Directory> or <Location>.

    +
    + +
    Examples + +
      +
    1. + Copy all request headers that begin with "TS" to the + response headers: + + + Header echo ^TS + +
    2. + +
    3. + Add a header, MyHeader, to the response including a + timestamp for when the request was received and how long it + took to begin serving the request. This header can be used by + the client to intuit load on the server or in isolating + bottlenecks between the client and the server. + + + Header add MyHeader "%D %t" + + +

      results in this header being added to the response:

      + + + MyHeader: D=3775428 t=991424704447256 + +
    4. + +
    5. + Say hello to Joe + + + Header add MyHeader "Hello Joe. It took %D microseconds \
      + for Apache to serve this request." +
      + +

      results in this header being added to the response:

      + + + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache + to serve this request. + +
    6. + +
    7. + Conditionally send MyHeader on the response if and + only if header "MyRequestHeader" is present on the request. This + is useful for constructing headers in response to some client + stimulus. Note that this example requires the services of the + mod_setenvif module. + + + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader
      +
      + +

      If the header MyRequestHeader: value is present on + the HTTP request, the response will contain the following header:

      + + + MyHeader: D=3775428 t=991424704447256 mytext + +
    8. +
    +
    + + +RequestHeader +Configure HTTP request headers +RequestHeader set|append|add|unset header +[value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + + +

    This directive can replace, merge or remove HTTP request + headers. The header is modified just before the content handler + is run, allowing incoming headers to be modified. The action it + performs is determined by the first argument. This can be one + of the following values:

    + +
    +
    set
    +
    The request header is set, replacing any previous header + with this name
    + +
    append
    +
    The request header is appended to any existing header of the + same name. When a new value is merged onto an existing header + it is separated from the existing header with a comma. This + is the HTTP standard way of giving a header multiple + values.
    + +
    add
    +
    The request header is added to the existing set of headers, + even if this header already exists. This can result in two + (or more) headers having the same name. This can lead to + unforeseen consequences, and in general append should be + used instead.
    + +
    unset
    +
    The request header of this name is removed, if it exists. If + there are multiple headers of the same name, all will be removed. + value must be omitted.
    +
    + +

    This argument is followed by a header name, which can + include the final colon, but it is not required. Case is + ignored. For add, append and + set a value is given as the third argument. If + value contains spaces, it should be surrounded by double + quotes. For unset, no value should be given. + value may be a character string, a string containing format + specifiers or a combination of both. The supported format specifiers + are the same as for the Header, + please have a look there for details.

    + +

    The RequestHeader directive may be followed by + an additional argument, which may be used to specify conditions under + which the action will be taken, or may be the keyword early + to specify early processing. If the + environment + variable specified in the env=... argument + exists (or if the environment variable does not exist and + env=!... is specified) then the action specified + by the RequestHeader directive will take effect. + Otherwise, the directive will have no effect on the request.

    + +

    Except in early mode, the + RequestHeader directive is processed + just before the request is run by its handler in the fixup phase. + This should allow headers generated by the browser, or by Apache + input filters to be overridden or modified.

    +
    +
    + + +Header +Configure HTTP response headers +Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + + +

    This directive can replace, merge or remove HTTP response + headers. The header is modified just after the content handler + and output filters are run, allowing outgoing headers to be + modified.

    + +

    The optional condition can be either onsuccess + or always. It determines, which internal header table should be + operated on. onsuccess stands for 2xx + status codes and always for all status codes (including + 2xx). Especially if you want to unset headers + set by certain modules, you should try out, which table is affected.

    + +

    The action it performs is determined by the second + argument. This can be one of the following values:

    + +
    +
    set
    +
    The response header is set, replacing any previous header + with this name. The value may be a format string.
    + +
    append
    +
    The response header is appended to any existing header of + the same name. When a new value is merged onto an existing + header it is separated from the existing header with a comma. + This is the HTTP standard way of giving a header multiple values.
    + +
    add
    +
    The response header is added to the existing set of headers, + even if this header already exists. This can result in two + (or more) headers having the same name. This can lead to + unforeseen consequences, and in general "append" should be + used instead.
    + +
    unset
    +
    The response header of this name is removed, if it exists. + If there are multiple headers of the same name, all will be + removed. value must be omitted.
    + +
    echo
    +
    Request headers with this name are echoed back in the + response headers. header may be a regular expression. + value must be omitted.
    +
    + +

    This argument is followed by a header name, which + can include the final colon, but it is not required. Case is + ignored for set, append, add + and unset. The header name for echo + is case sensitive and may be a regular expression.

    + +

    For add, append and set a + value is specified as the third argument. If value + contains spaces, it should be surrounded by doublequotes. + value may be a character string, a string containing format + specifiers or a combination of both. The following format specifiers + are supported in value:

    + + + + + + + + + + + + + + + + + + + +
    FormatDescription
    %%The percent sign
    %tThe time the request was received in Universal Coordinated Time + since the epoch (Jan. 1, 1970) measured in microseconds. The value + is preceded by t=.
    %DThe time from when the request was received to the time the + headers are sent on the wire. This is a measure of the duration + of the request. The value is preceded by D=.
    %{FOOBAR}eThe contents of the environment + variable FOOBAR.
    %{FOOBAR}sThe contents of the SSL environment + variable FOOBAR, if mod_ssl is enabled.
    + + Note +

    The %s format specifier is only available in + Apache 2.1 and later; it can be used instead of %e + to avoid the overhead of enabling SSLOptions + +StdEnvVars. If SSLOptions +StdEnvVars must + be enabled anyway for some other reason, %e will be + more efficient than %s.

    +
    + +

    The Header directive may be followed by an + an additional argument, which may be used to specify conditions under + which the action will be taken, or may be the keyword early + to specify early processing. If the + environment variable specified in the + env=... argument exists (or if the environment + variable does not exist and env=!... is specified) + then the action specified by the Header directive + will take effect. Otherwise, the directive will have no effect + on the request.

    + +

    Except in early mode, the + Header directives are processed just + before the response is sent to the network. These means that it is + possible to set and/or override most headers, except for those headers + added by the header filter.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_headers.xml.ja b/trunk/docs/manual/mod/mod_headers.xml.ja new file mode 100644 index 0000000000..f9ca293409 --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.xml.ja @@ -0,0 +1,337 @@ + + + + + + + + + +mod_headers +HTTP $B%j%/%(%9%H$N%X%C%@$H1~Ez$N%X%C%@$N%+%9%?%^%$%:(B +Extension +mod_headers.c +headers_module +RequestHeader +$B$O(B Apache 2.0 $B0J9_$N$_$G;HMQ2DG=(B + + +

    $B$3$N%b%8%e!<%k$O(B HTTP $B$N%j%/%(%9%H%X%C%@$H1~Ez%X%C%@$r@)8f$7!"(B + $BJQ99$9$k$?$a$N%G%#%l%/%F%#%V$rDs6!$7$^$9!#%X%C%@$rDI2C$7$?$j!"(B + $BCV$-49$($?$j!":o=|$7$?$j$9$k$3$H$,$G$-$^$9!#(B

    +
    + +
    $B=hM}$N=gHV(B + +

    mod_header $B$N%G%#%l%/%F%#%V$O%5!<%P@_Dj$N$[$\$I$3$K$G$b(B + $B=q$/$3$H$,$G$-!"1F6A$9$kHO0O$r(B$B@_DjMQ%;%/%7%g%s(B$B$G0O$`$3$H$G8BDj$9$k(B + $B$3$H$,$G$-$^$9!#(B

    + +

    $B=hM}$N=gHV$O=EMW$G!"@_Dj%U%!%$%kCf$N=gHV$H!"(B$B@_DjMQ%;%/%7%g%s(B$BFb$N0LCV$H$NN>J}$K(B + $B1F6A$5$l$^$9!#0J2<$NFs$D$N%X%C%@$O=gHV$,5U$K$J$k$H(B + $B0c$&7k2L$K$J$j$^$9(B:

    + + + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +
    + +

    $B$3$N=gHV$N>l9g$O!"(BMirrorID $B%X%C%@$O@_Dj$5$l$^$;$s!#(B + $B5U$K$J$C$F$$$k$H!"(BMirrorID $B%X%C%@$O(B "mirror 12" $B$K@_Dj$5$l$^$9!#(B

    +
    + +
    $BAa4|=hM}!"8e4|=hM}(B +

    mod_headers $B$G$O!"%j%/%(%9%H$NAa4|$+8e4|$+$N(B + $B$I$A$i$GE,MQ$9$k$+$rA*$Y$^$9!#DL>o$O8e4|%b!<%I$G!"(B + $B%3%s%F%s%D@8@.$,A0$K%j%/%(%9%H%X%C%@$,%;%C%H$5$l!"(B + $B%l%9%]%s%9$H$7$FAw=P$5$l$kD>A0$K%l%9%]%s%9%X%C%@$,%;%C%H$5$l$^$9!#(B + $B1?MQCf$N%5!<%P$G$OI,$:8e4|%b!<%I$r;H$C$F$/$@$5$$!#(B

    + +

    $BAa4|%b!<%I$O3+H/early $B%-!<%o!<%I;XDj$5$l$?%G%#%l%/%F%#%V$K$h$C$F!"(B + $B%j%/%(%9%H=hM}$N3+;OCOE@$K$J$j$^$9!#(B + $B$D$^$j!"0[$J$k%j%/%(%9%H$r;n$7$?$j%F%9%H%1!<%9$r%;%C%H%"%C%W$9$k$N$K(B + $B3hMQ$G$-$k0lJ}$G!"%l%9%]%s%9$r@8@.$9$kA0$KB>$N%b%8%e!<%k$K$h$C$F(B + $B%X%C%@$,=q$-49$($i$l$F$7$^$&$+$b$7$l$J$$$H$$$&$3$H$r0UL#$7$^$9!#(B

    + +

    early $B%G%#%l%/%F%#%V$G$O%j%/%(%9%H%Q%9$N@_Dj$,2r7h$5$l$kA0$K(B + $B=hM}$5$l$k$N$G!"%a%$%s%5!<%P$+%P!<%A%c%k%[%9%H%3%s%F%-%9%H$G$N$_!"(B + $BAa4|%X%C%@$r%;%C%H$G$-$^$9!#(Bearly $B%G%#%l%/%F%#%V$O%j%/%(%9%H%Q%9$K(B + $B0MB8$9$k$3$H$O$G$-$^$;$s$N$G!"(B<Directory> $B$d(B + <Location> $B$H$$$C$?%3%s%F%-%9%HFb$G$O;HMQ(B + $B$G$-$^$;$s!#(B

    +
    + +
    $BNc(B + +
      +
    1. $B%j%/%(%9%H%X%C%@Cf$N(B "TS" $B$G;O$^$k%U%#!<%k%I$r$9$Y$F1~Ez%X%C%@$K(B + $B%3%T!<$7$^$9(B: + + Header echo ^TS + +
    2. + +
    3. + $B%j%/%(%9%H$rMyHeader $B$r1~Ez$KDI2C$7$^$9!#$3$N%X%C%@$O%/%i%$%"%s%H$,(B + $B%5!<%P$NIi2Y$rD>4QE*$KCN$k$?$a$d!"%/%i%$%"%s%H(B-$B%5!<%P4V$N(B + $B%\%H%k%M%C%/$rD4$Y$k$?$a$K;H$&$3$H$,$G$-$^$9!#(B + + + Header add MyHeader "%D %t" + + +

      $B>e5-$N@_Dj$G$O!"0J2<$N$h$&$J%X%C%@$,1~Ez$KDI2C$5$l$k$3$H$K$J$j$^$9(B:

      + + + MyHeader: D=3775428 t=991424704447256 + +
    4. + +
    5. + Joe $B$K$"$$$5$D$r$7$^$9(B: + + + Header add MyHeader "Hello Joe. It took %D microseconds for Apache to serve this request." + + +

      $B0J2<$N$h$&$J%X%C%@$,1~Ez$KDI2C$5$l$k$3$H$K$J$j$^$9(B

      + + + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache to serve this request. + +
    6. + +
    7. $B%j%/%(%9%H$K(B "MyRequestHeader" $B$,$"$k$H$-$K8B$j(B MyHeader $B$r1~Ez$K(B + $BIU$1$^$9!#$3$l$O!"%/%i%$%"%s%H$NMW5a$K1~$($F%X%C%@$r:n@.$9$k$H$-$K(B + $BLr$KN)$A$^$9!#$3$NNc$G$O(B mod_setenvif $B%b%8%e!<%k$,I,MW$J$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B + + + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader +
      + +

      $B$b$7(B HTTP $B%j%/%(%9%H$K(B MyRequestHeader: value $B%X%C%@$,(B + $B$"$k$H!"1~Ez$K$O0J2<$N$h$&$J%X%C%@$,IU2C$5$l$^$9!#(B

      + + + MyHeader: D=3775428 t=991424704447256 mytext + +
    8. +
    +
    + + +RequestHeader +HTTP $B%j%/%(%9%H%X%C%@$N@_Dj(B +RequestHeader set|append|add|unset header +[value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + + +

    $B$3$N%G%#%l%/%F%#%V$O(B HTTP $B%j%/%(%9%H%X%C%@$rCV49!"DI2C!":o=|$G$-$^$9!#(B + $B%X%C%@$O%3%s%F%s%H%O%s%I%i$,A0$K + +

    +
    set
    +
    $B%j%/%(%9%H%X%C%@$r@_Dj$7$^$9!#F1$8L>A0$N%X%C%@$,B8:_$7$F$$$k$H!"(B + $B$=$l$rCV$-49$($^$9!#(B
    + +
    append
    +
    $B%j%/%(%9%H%X%C%@$O!"4{$KB8:_$9$kF1$8L>A0$N%X%C%@$KDI2C$5$l$^$9!#(B + $B?7$7$$CM$,4{B8$N%X%C%@$KDI2C$5$l$k$H$-$K$O!"4{B8$N%X%C%@$N(B + $B8e$K%3%s%^$G6h@Z$i$l$FDI2C$5$l$^$9!#$3$l$O%X%C%@$KJ#?t$NCM$r(B + $B;XDj$9$k$H$-$N(B HTTP $B$NI8=`$NJ}K!$G$9!#(B
    + +
    add
    +
    $B%X%C%@$,4{$KB8:_$7$F$$$k$H$-$G$5$($b!"%j%/%(%9%H%X%C%@$r(B + $B4{B8$N%X%C%@$KDI2C$7$^$9!#$3$l$K$h$j!"Fs$D(B ($B$+$=$l0J>e(B) $B$N(B + $B%X%C%@$NL>A0$,F1$8$K$J$k$3$H$,$"$j$^$9!#$=$N7k2L!"A[Dj$G$-$J$$(B + $B$3$H$,5/$3$k2DG=@-$,$"$j$^$9$N$G!"0lHLE*$K$O(B append $B$NJ}$r(B + $B;H$&J}$,NI$$$G$7$g$&!#(B
    + +
    unset
    +
    $B$b$7;XDj$5$l$?L>A0$N%j%/%(%9%H%X%C%@$,B8:_$7$F$$$l$P!":o=|$5$l$^$9!#(B + $BF1$8L>A0$NJ#?t$N%X%C%@$,$"$k$H$-$O!"$9$Y$F:o=|$5$l$^$9!#(B + value $B$r$D$1$F$O$$$1$^$;$s!#(B
    +
    + +

    $B$3$N0z?t$N8e$K$O%X%C%@L>(B (header) $B$,B3$-$^$9!#(B + $B%X%C%@L>$K$O:G8e$K%3%m%s$r4^$a$k$3$H$b$G$-$^$9$,!"L5$/$F$b9=$$$^$;$s!#(B + $BBgJ8;z>.J8;z$O6hJL$5$l$^$;$s!#(Badd, + append, set $B$N>l9g$O!"(Bvalue $B$,;0$DL\$N(B + $B0z?t$H$7$F;XDj$5$l$^$9!#(Bvalue $B$K6uGr$,$"$k>l9g$OFs=E0zMQId$G(B + $B0O$`I,MW$,$"$j$^$9!#(Bunset $B$N>l9g$O!"(Bvalue $B$O;XDj$7$^$;$s!#(B + value $B$OJ8;zNs!"%U%)!<%^%C%H;XDj;R!"$"$k$$$O!"$=$N:.9g$G$9!#(B + $B;H$&$3$H$N$G$-$k%U%)!<%^%C%H;XDj;R$O!"(BHeader $B$HF1$8$G$9$N$G!"(B + $B>\:Y$O$=$A$i$r$4Mw$/$@$5$$!#(B

    + +

    RequestHeader $B%G%#%l%/%F%#%V$O!"(B + $B$I$&$$$C$?>r7o2<$G%"%/%7%g%s$r9T$&$+$r;XDj$9$kDI2C0z?t(B + $B$"$k$$$O!"(B$BAa4|=hM}(B $B$r;XDj$9$k(B early + $B%-!<%o!<%I$r@_Dj$9$k$3$H$,$G$-$^$9!#(B + env=... $B$N0z?t$G@_Dj$5$l$F$$$k(B + $B4D6-JQ?t(B $B$,B8:_$7$F$$$k(B + ($B$"$k$$$O(B env=!... $B$G;XDj$5$l$?4D6-JQ?t$,(B + $BB8:_$7$J$$(B) $B>l9g!"(BRequestHeader $B%G%#%l%/%F%#%V$O(B + $BM-8z$K$J$j$^$9!#$=$l0J30$N>l9g!"%G%#%l%/%F%#%V$O8zNO$r;}$A$^$;$s!#(B

    + +

    early $B%b!<%I$G$J$$>l9g$K8B$j!"(B + RequestHeader $B%G%#%l%/%F%#%V$O(B + fixup $B%U%'!<%:$G%j%/%(%9%H$,%O%s%I%i$K07$o$l$kD>A0$K(B + $B=hM}$5$l$^$9!#$3$l$K$h$j!"%V%i%&%6$d(B Apache $B$NF~NO%U%#%k%?$K$h$j(B + $B@8@.$5$l$?%X%C%@$r>e=q$-$7$?$j=$@5$7$?$j$G$-$k$h$&$K$J$C$F$$$^$9!#(B

    +
    +
    + + +Header +HTTP $B1~Ez%X%C%@$N@_Dj(B +Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + +

    $B$3$N%G%#%l%/%F%#%V$O(B HTTP $B1~Ez%X%C%@$rCV49!"DI2C!":o=|$G$-$^$9!#(B + $B%X%C%@$O%3%s%F%s%H%O%s%I%i$d=PNO%U%#%k%?$,8e$K + +

    $B%*%W%7%g%s$N(B condition $B$O(B onsuccess $B$+(B + always $B$N$I$A$i$+$r;XDj$G$-$^$9!#$3$l$OFbIt%X%C%@%F!<%V%k$N$I$l$r(B + $BA`:n$9$k$+$r7hDj$7$^$9!#(Bonsuccess $B$O(B 2xx + $B%9%F!<%?%9%3!<%I$N!"(Balways $B$OA4$F$N%9%F!<%?%9%3!<%I(B + (2xx $B$r4^$`(B) $B$N0UL#$K$J$j$^$9!#(B + $B$"$k%b%8%e!<%k$G%;%C%H$5$l$k%X%C%@$r%"%s%;%C%H$7$?$$>l9g$OFC$K!"(B + $B$I$N%F!<%V%k$,1F6A$r + +

    $B9T$J$&=hM}$OFsHVL\$N$N0z?t$G7h$^$j$^$9!#(B + $B$3$N0z?t$K$O + +

    +
    set
    +
    $B1~Ez%X%C%@$r@_Dj$7$^$9!#F1$8L>A0$N%X%C%@$,B8:_$9$k>l9g$O$=$l$r(B + $BCV$-49$($^$9!#(Bvalue $B$K$O%U%)!<%^%C%HJ8;zNs$r(B + $B;XDj$9$k$3$H$b$G$-$^$9!#(B
    + +
    append
    +
    $B1~Ez%X%C%@$r4{$KB8:_$9$kF1$8L>A0$N%X%C%@$KDI2C$7$^$9!#(B + $B?7$7$$CM$,4{B8$N%X%C%@$KDI2C$5$l$k$H$-$K$O!"4{B8$N%X%C%@$N(B + $B8e$K%3%s%^$G6h@Z$i$l$FDI2C$5$l$^$9!#$3$l$O%X%C%@$KJ#?t$NCM$r(B + $B;XDj$9$k$H$-$N(B HTTP $B$NI8=`$NJ}K!$G$9!#(B
    + +
    add
    +
    $B%X%C%@$,4{$KB8:_$7$F$$$k$H$-$G$5$($b!"1~Ez%X%C%@$r(B + $B4{B8$N%X%C%@$KDI2C$7$^$9!#$3$l$K$h$j!"Fs$D(B ($B$+$=$l0J>e(B) $B$N(B + $B%X%C%@$NL>A0$,F1$8$K$J$k$3$H$,$"$j$^$9!#$=$N7k2L!"A[Dj$G$-$J$$(B + $B$3$H$,5/$3$k2DG=@-$,$"$j$^$9$N$G!"0lHLE*$K$O(B append $B$NJ}$r(B + $B;H$&J}$,NI$$$G$7$g$&!#(B
    + +
    unset
    +
    $B$b$7;XDj$5$l$?L>A0$N1~Ez%X%C%@$,B8:_$7$F$$$l$P!":o=|$5$l$^$9!#(B + $BF1$8L>A0$N%X%C%@$,J#?t$"$k$H$-$O!"$9$Y$F:o=|$5$l$^$9!#(B + value $B$r$D$1$F$O$$$1$^$;$s!#(B
    + +
    echo
    +
    $B;XDj$5$l$?$b$N$HF1$8L>A0$N%j%/%(%9%H%X%C%@$r1~Ez%X%C%@$G(B + $B$=$N$^$^JV$7$^$9!#(Bheader $B$K$O@55,I=8=$b;XDj$G$-$^$9!#(B + value $B$r$D$1$F$O$$$1$^$;$s!#(B
    +
    + +

    $B$3$N0z?t$N8e$K$O%X%C%@L>(B (header) $B$,B3$-$^$9!#(B + $B%X%C%@L>$K$O:G8e$K%3%m%s$r4^$a$k$3$H$b$G$-$^$9$,!"L5$/$F$b9=$$$^$;$s!#(B + set, append, add, + unset $B$G$OBgJ8;z>.J8;z$O(B + $B6hJL$5$l$^$;$s!#(Becho $B$N(B header $BL>$OBgJ8;z>.J8;z$r6hJL$7!"(B + $B@55,I=8=$r;XDj$9$k$3$H$b$G$-$^$9!#(B

    + +

    add, append, + set $B$G$O(B value $B$r;0$DL\$N(B + $B0z?t$H$7$F;XDj$7$^$9!#(Bvalue $B$K6uGr$,$"$k>l9g$OFs=E0zMQId$G(B + $B0O$`I,MW$,$"$j$^$9!#(Bvalue $B$OJ8;z$N$_$+$i$J$kJ8;zNs!"(B + $B%U%)!<%^%C%H;X<(;R$r4^$`J8;zNs!"$b$7$/$ON>J}$+$i$J$kJ8;zNs$r;XDj$G$-$^$9!#(B + value $B$O0J2<$N%U%)!<%^%C%H;X<(;R$r%5%]!<%H$7$^$9(B:

    + + + + + + + + + + + + + + + + + + + +
    $B%U%)!<%^%C%H(B$B2r@b(B
    %%$B%Q!<%;%s%H5-9f(B
    %t$B%j%/%(%9%H$rt= $B$,IU2C$5$l$^$9!#(B
    %D$B%j%/%(%9%H$rD= $B$,IU2C$5$l$^$9!#(B
    %{FOOBAR}e$B4D6-JQ?t(B + FOOBAR $B$NCM$G$9!#(B
    %{FOOBAR}smod_ssl $B$,M-8z$J>l9g!"(B + SSL $B4D6-JQ?t(B FOOBAR + $B$NFbMF(B
    + + $BCm(B +

    %s $B%U%)!<%^%C%H;XDj;R$O(B 2.1 $B0J9_$G$N$_MxMQ$G$-$^$9!#(B + SSLOptions +StdEnvVars $B$rM-8z$K$9$k$3$H$K$h$k%*!<%P!<%X%C%I$r(B + $BHr$1$k$?$a!"(B%e $B$NBe$o$j$H$7$F;H$($^$9!#(B + $BB>$NM}M3$J$I$,$"$C$F!"$I$&$7$F$b(B SSLOptions +StdEnvVars + $B$rM-8z$K$7$J$1$l$P$J$i$J$$>l9g$O!"(B%e $B$N$[$&$,(B + %s $B$h$j$b=hM}8zN($ONI$$$G$9!#(B

    +
    + +

    Header $B%G%#%l%/%F%#%V$K$ODI2C$N0z?t$r;}$?$;$k$3$H$,(B + $B$G$-$F!"$I$&$$$C$?%"%/%7%g%s$,9T$o$l$?$+$N>r7o$r;XDj$7$?$j!"(B + $BAa4|=hM}(B $B$r;XDj$9$k(B early $B%-!<%o!<%I$r(B + $B;XDj$G$-$^$9!#(B + env=... $B0z?t$G;XDj$5$l$?(B $B4D6-JQ?t(B $B$,B8:_$9$k(B ($B$b$7$/$O(B env=!... + $B$,;XDj$5$l$F$$$F4D6-JQ?t$,B8:_$7$J$$(B) $B>l9g$O!"(BHeader + $B%G%#%l%/%F%#%V$G;XDj$5$l$?F0:n$,9T$J$o$l$^$9!#$=$&$G$J$$>l9g$O!"(B + $B%G%#%l%/%F%#%V$O$=$N%j%/%(%9%H$K$O2?$b$7$^$;$s!#(B

    + +

    $BAa4|=hM}(B$B%b!<%I$N>l9g0J30$G$O!"(B + Header + $B%G%#%l%/%F%#%V$O1~Ez$,%M%C%H%o!<%/$KAw$i$l$kD>A0$K(B + $B=hM}$5$l$^$9!#$3$l$O!"%X%C%@%U%#%k%?$K$h$jDI2C$5$l$k%X%C%@$r(B + $B=|$-!"$[$H$s$I$N%X%C%@$r@_Dj$7$?$j>e=q$-$7$?$j$9$k$3$H$,(B + $B2DG=!"$H$$$&$3$H$G$9!#(B

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_headers.xml.ko b/trunk/docs/manual/mod/mod_headers.xml.ko new file mode 100644 index 0000000000..f9e38f9524 --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.xml.ko @@ -0,0 +1,330 @@ + + + + + + + + + +mod_headers +HTTP ¿äû Çì´õ¿Í ÀÀ´ä Çì´õ ¼öÁ¤ +Extension +mod_headers.c +headers_module +RequestHeader´Â ¾ÆÆÄÄ¡ 2.0¿¡¸¸ +ÀÖ´Ù + + +

    ÀÌ ¸ðµâÀº HTTP ¿äû Çì´õ¿Í ÀÀ´ä Çì´õ¸¦ Á¶ÀýÇÏ°í ¼öÁ¤ÇÏ´Â + Áö½Ã¾îµéÀ» Á¦°øÇÑ´Ù. Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    ó¸® ¼ø¼­ + +

    mod_headers°¡ Á¦°øÇÏ´Â Áö½Ã¾î´Â ¼­¹ö¼³Á¤ÀÇ + °ÅÀÇ ¸ðµç Àå¼Ò¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, ¼³Á¤ ¼½¼ÇÀ¸·Î °¨½Î¼­ Áö½Ã¾îÀÇ + ¹üÀ§¸¦ Á¦ÇÑÇÒ ¼öµµ ÀÖ´Ù.

    + +

    󸮼ø¼­´Â Áß¿äÇϸç, ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â ¼ø¼­¿Í ¼³Á¤ ¼½¼ÇÀÇ ¿µÇâÀ» ¹Þ´Â´Ù. + ´ÙÀ½ µÎ Áö½Ã¾î¸¦ ¹Ý´ë·Î ÀûÀ¸¸é È¿°ú°¡ ´Þ¶óÁø´Ù.

    + + + RequestHeader append MirrorID "mirror 12"
    + RequestHeader unset MirrorID +
    + +

    À§¿Í °°ÀÌ ÀûÀ¸¸é MirrorID Çì´õ°¡ ³ª¿ÀÁö + ¾Ê´Â´Ù. ¹Ý´ë·Î ÀûÀ¸¸é MirrorID Çì´õ¸¦ "mirror 12"·Î ¼³Á¤ÇÑ´Ù.

    +
    + +
    À̸¥(early) ó¸®¿Í ´ÊÀº(late) ó¸® +

    mod_headers¸¦ ¿äû Ãʱ⳪ ³ªÁß¿¡ Àû¿ëÇÒ + ¼ö ÀÖ´Ù. º¸ÅëÀº ³»¿ë»ý¼ºÀÚ¸¦ ½ÇÇàÇϱâ Á÷Àü¿¡ ¿äû Çì´õ¸¦ + ¼³Á¤ÇÏ°í ÀÀ´äÀ» ³×Æ®¿÷¿¡ ¾µ¶§ ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÏ´Â ´ÊÀº(late) + ¹æ½ÄÀ» »ç¿ëÇÑ´Ù. ½ÇÁ¦ ¼­ºñ½ºÇÏ´Â ¼­¹ö¿¡¼­´Â Ç×»ó ´À¸° ¹æ½ÄÀ» + »ç¿ëÇ϶ó.

    + +

    À̸¥(early) ¹æ½ÄÀº °³¹ßÀÚ¸¦ À§ÇØ °Ë»ç/µð¹ö±ë¿ëÀ¸·Î ¸¸µé¾ú´Ù. + early Å°¿öµå¸¦ »ç¿ëÇÏ¿© Á¤ÀÇÇÑ Áö½Ã¾î´Â ¿äûÀ» + ó¸®Çϱ⠽ÃÀÛÇÒ¶§ ¼³Á¤ÇÑ´Ù. Áï, ´Ù¸¥ ¿äûÀ» ¸ðÀǽÇÇèÇϰųª + °Ë»ç¸¦ ÇϱâÀ§ÇØ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ÀÀ´äÀ» »ý¼ºÇϱâ Àü¿¡ ´Ù¸¥ + ¸ðµâÀÌ ºÒ½Ã¿¡ Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿äû°æ·Î¿¡ ´ëÇÑ ¼³Á¤À» »ìÆ캸±â Àü¿¡ À̸¥ Áö½Ã¾î¸¦ + ó¸®Çϱ⶧¹®¿¡ À̸¥ Çì´õ Áö½Ã¾î´Â ÁÖ¼­¹öÀ̳ª °¡»óÈ£½ºÆ® + »ç¿ëÀå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. À̸¥ Áö½Ã¾î´Â ¿äû°æ·Î¿¡ + ÀÇÁ¸ÇÒ ¼ö ¾ø±â¶§¹®¿¡ <Directory>³ª + <Location>°°Àº »ç¿ëÀå¼Ò¿¡¼­ »ç¿ëÇÒ ¼ö + ¾ø´Ù.

    +
    + +
    ¿¹Á¦ + +
      +
    1. + "TS"·Î ½ÃÀÛÇÏ´Â ¸ðµç ¿äû Çì´õ¸¦ ÀÀ´ä Çì´õ·Î º¹»çÇÑ´Ù. + + + Header echo ^TS + +
    2. + +
    3. + ÀÀ´ä¿¡ ¿äûÀ» ¹ÞÀº ½Ã°£°ú ¿äûÀ» ¼­ºñ½ºÇϴµ¥ °É¸± ½Ã°£À» + ¾Ë·ÁÁÖ´Â MyHeader Çì´õ¸¦ Ãß°¡ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®´Â + ÀÌ Çì´õ¸¦ º¸°í ¼­¹öÀÇ ºÎÇϸ¦ ÃßÁ¤Çϰųª Ŭ¶óÀ̾ðÆ®¿Í + ¼­¹ö°£ÀÇ º´¸ñÁ¡À» ãÀ» ¼ö ÀÖ´Ù. + + + Header add MyHeader "%D %t" + + +

      ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + + + MyHeader: D=3775428 t=991424704447256 + +
    4. + +
    5. + Joe¿¡°Ô ¾È³ç + + + Header add MyHeader "Hello Joe. It took %D microseconds \
      + for Apache to serve this request." +
      + +

      ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + + + MyHeader: Hello Joe. It took D=3775428 microseconds for Apache + to serve this request. + +
    6. + +
    7. + ¿äû¿¡ "MyRequestHeader" Çì´õ°¡ ÀÖ´Â °æ¿ì¿¡¸¸ ¼±ÅÃÀûÀ¸·Î + ÀÀ´ä¿¡ MyHeader¸¦ º¸³½´Ù. ƯÁ¤ Ŭ¶óÀ̾ðÆ®¿¡°Ô¸¸ + ÀÀ´ä¿¡ Çì´õ¸¦ Ãß°¡ÇÒ¶§ À¯¿ëÇÏ´Ù. ÀÌ ¿¹Á¦°¡ µ¿ÀÛÇÏ·Á¸é + mod_setenvif ¸ðµâÀÌ ÇÊ¿äÇÏ´Ù. + + + SetEnvIf MyRequestHeader value HAVE_MyRequestHeader
      + Header add MyHeader "%D %t mytext" env=HAVE_MyRequestHeader
      +
      + +

      HTTP ¿äû¿¡ MyRequestHeader: value Çì´õ°¡ + ÀÖ´Ù¸é, ÀÀ´ä¿¡ ´ÙÀ½°ú °°Àº Çì´õ°¡ »ý±ä´Ù.

      + + + MyHeader: D=3775428 t=991424704447256 mytext + +
    8. +
    +
    + + +RequestHeader +HTTP ¿äû Çì´õ¸¦ ±¸¼ºÇÑ´Ù +RequestHeader set|append|add|unset header +[value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + + +

    ÀÌ Áö½Ã¾î´Â HTTP ¿äû Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÑ´Ù. + ³»¿ë Çڵ鷯°¡ ½ÇÇàÇϱâ Á÷Àü¿¡ Çì´õ¸¦ ¼öÁ¤Çϱ⶧¹®¿¡ ¹ÞÀº + Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. ù¹ø° ¾Æ±Ô¸ÕÆ®¿¡ µû¶ó ±â´ÉÀÌ ´Ù¸£´Ù. + ù¹ø° ¾Æ±Ô¸ÕÆ®·Î ¾Æ·¡ °ªÁß Çϳª¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    set
    +
    ¿äû Çì´õ¸¦ ¼³Á¤ÇÑ´Ù. °°Àº À̸§À¸·Î ÀÌ¹Ì Çì´õ°¡ ÀÖ´Ù¸é + ´ëüÇÑ´Ù
    + +
    append
    +
    ÀÌ¹Ì Á¸ÀçÇÏ´Â °°Àº À̸§ÀÇ ¿äû Çì´õ¿¡ Ãß°¡ÇÑ´Ù. ±âÁ¸ + Çì´õ¿¡ »õ·Î¿î °ªÀ» ÇÕÄ¡¸é, ±âÁ¸ Çì´õ¿Í »õ·Î¿î °ª »çÀÌ¿¡ + ½°Ç¥¸¦ ºÙÀδÙ. ÀÌ´Â ¿©·¯ Çì´õ°ªÀ» ÁöÁ¤ÇÏ´Â HTTP Ç¥ÁØ ¹æ½ÄÀÌ´Ù.
    + +
    add
    +
    Çì´õ°¡ ÀÌ¹Ì ÀÖ´õ¶óµµ ¿äû Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ °°Àº + À̸§ÀÇ Çì´õ°¡ µÎ°³ (ȤÀº ¸¹ÀÌ) »ý±æ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀÇ¿ÜÀÇ + °á°ú°¡ ¹ß»ýÇÒ ¼ö Àֱ⶧¹®¿¡ º¸Åë ´ë½Å append¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    unset
    +
    ÀÌ·± À̸§ÀÇ ¿äû Çì´õ°¡ ÀÖ´Ù¸é »èÁ¦ÇÑ´Ù. °°Àº À̸§À» + °¡Áø Çì´õ°¡ ¿©·¯°³ ÀÖ´Ù¸é ¸ðµÎ Á¦°ÅÇÑ´Ù. value´Â + ÀûÁö ¾Ê´Â´Ù.
    +
    + +

    ¾Æ±Ô¸ÕÆ® µÚ¿¡ Çì´õ¸íÀÌ ³ª¿Â´Ù. Çì´õ¸í µÚ¿¡ ÄÝ·ÐÀ» ÀûÀ» + ¼ö ÀÖÁö¸¸, ¾ø¾îµµ µÈ´Ù. ´ë¼Ò¹®ÀÚ´Â ¹«½ÃÇÑ´Ù. add, + append, setÀ» »ç¿ëÇÒ¶§´Â ¼¼¹ø° + ¾Æ±Ô¸ÕÆ® value°¡ ÇÊ¿äÇÏ´Ù. value ¾È¿¡ + °ø¹éÀÌ ÀÖ´Ù¸é ½Öµû¿ÈÇ¥·Î ¹­¾î¾ß ÇÑ´Ù. unsetÀ» »ç¿ëÇÒ¶§´Â + value¸¦ ÀûÀ¸¸é ¾ÈµÈ´Ù. value´Â ÀÏ¹Ý + ¹®ÀÚ¿­À̳ª Çü½ÄÀ» ±â¼úÇÏ´Â ¹®ÀÚ¿­À̸ç, µÎ°¡Áö¸¦ °°ÀÌ »ç¿ëÇÒ + ¼öµµ ÀÖ´Ù. Áö¿øÇÏ´Â Çü½Ä±â¼úÀÚ´Â Header¿Í °°À¸¹Ç·Î ÀÚ¼¼ÇÑ + ³»¿ëÀº ±×°÷À» Âü°íÇ϶ó.

    + +

    RequestHeader Áö½Ã¾î µÚ¿¡ ÇൿÀÌ + ÀϾ Á¶°ÇÀ» Áö½ÃÇÏ´Â Ãß°¡ ¾Æ±Ô¸ÕÆ®³ª À̸¥ 󸮸¦ ¶æÇÏ´Â Å°¿öµå + early°¡ ³ª¿Ã ¼ö ÀÖ´Ù. env=... + ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÑ °æ¿ì ÇØ´ç ȯ°æº¯¼ö°¡ + Á¸ÀçÇÑ´Ù¸é (ȤÀº env=!...¿¡ ³ª¿Â + ȯ°æº¯¼ö°¡ Á¸ÀçÇÏÁö ¾Ê´Ù¸é) RequestHeader + Áö½Ã¾î°¡ µ¿ÀÛÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é Áö½Ã¾î´Â ¿äû¿¡ ¾Æ¹« ¿µÇâÀ» + ¹ÌÄ¡Áö ¾Ê´Â´Ù.

    + +

    À̸¥ ¹æ½ÄÀÌ ¾Æ´Ï¶ó¸é fixup ´Ü°è¿¡¼­ + ¿äû¿¡ ÇØ´çÇÏ´Â Çڵ鷯¸¦ ½ÇÇàÇϱâ Á÷Àü¿¡ + RequestHeader Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. + ±×·¡¼­ ºê¶ó¿ìÀú¿¡ µû¶ó ȤÀº ¾ÆÆÄÄ¡ ÀÔ·ÂÇÊÅÍ°¡ Çì´õ¸¦ µ¤¾î¾²°Å³ª + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + + +Header +HTTP ÀÀ´ä Çì´õ¸¦ ±¸¼ºÇÑ´Ù +Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable] +server configvirtual host +directory.htaccess +FileInfo + + +

    ÀÌ Áö½Ã¾î´Â HTTP ÀÀ´ä Çì´õ¸¦ ÇÕÄ¡°Å³ª ´ëü, Á¦°ÅÇÑ´Ù. + ³»¿ë Çڵ鷯¿Í Ãâ·Â ÇÊÅÍ°¡ ½ÇÇàÇÑ Á÷ÈÄ¿¡ Çì´õ¸¦ ¼öÁ¤Çϱ⶧¹®¿¡ + º¸³¾ Çì´õ¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    conditionÀº ¼±ÅÃÀûÀ¸·Î »ç¿ëÇϸç, °ªÀ¸·Î + onsuccess ȤÀº always¸¦ »ç¿ëÇÑ´Ù. + ÀÌ´Â ¾î¶² ³»ºÎ Çì´õÇ¥¿¡ µ¿ÀÛÇÒÁö¸¦ °áÁ¤ÇÑ´Ù. + onsuccess´Â 2xx »óÅÂÄڵ带 + ¶æÇÏ°í, always´Â (2xx¸¦ + Æ÷ÇÔÇÑ) ¸ðµç »óÅÂÄڵ带 ¶æÇÑ´Ù. ƯÈ÷ ¾î¶² ¸ðµâÀÌ ¼³Á¤ÇÑ + Çì´õ¸¦ ÇØÁ¦ÇÏ°í ½Í´Ù¸é, µÑÁß ¾î¶² °ÍÀ» »ç¿ëÇÒÁö Àß »ìÆìºÁ¾ß + ÇÑ´Ù.

    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®¿¡ µû¶ó ±â´ÉÀÌ ´Ù¸£´Ù. µÎ¹ø° ¾Æ±Ô¸ÕÆ®·Î + ¾Æ·¡ °ªÁß Çϳª¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    set
    +
    ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÑ´Ù. °°Àº À̸§À¸·Î ÀÌ¹Ì Çì´õ°¡ ÀÖ´Ù¸é + ´ëüÇÑ´Ù. value¿¡ Çü½Ä¹®ÀÚ¿­À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    append
    +
    ÀÌ¹Ì Á¸ÀçÇÏ´Â °°Àº À̸§ÀÇ ÀÀ´ä Çì´õ¿¡ Ãß°¡ÇÑ´Ù. ±âÁ¸ + Çì´õ¿¡ »õ·Î¿î °ªÀ» ÇÕÄ¡¸é, ±âÁ¸ Çì´õ¿Í »õ·Î¿î °ª »çÀÌ¿¡ + ½°Ç¥¸¦ ºÙÀδÙ. ÀÌ´Â ¿©·¯ Çì´õ°ªÀ» ÁöÁ¤ÇÏ´Â HTTP Ç¥ÁØ ¹æ½ÄÀÌ´Ù.
    + +
    add
    +
    Çì´õ°¡ ÀÌ¹Ì ÀÖ´õ¶óµµ ÀÀ´ä Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ±×·¡¼­ °°Àº + À̸§ÀÇ Çì´õ°¡ µÎ°³ (ȤÀº ¸¹ÀÌ) »ý±æ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ÀÇ¿ÜÀÇ + °á°ú°¡ ¹ß»ýÇÒ ¼ö Àֱ⶧¹®¿¡ º¸Åë ´ë½Å append¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    unset
    +
    ÀÌ·± À̸§ÀÇ ÀÀ´ä Çì´õ°¡ ÀÖ´Ù¸é »èÁ¦ÇÑ´Ù. °°Àº À̸§À» + °¡Áø Çì´õ°¡ ¿©·¯°³ ÀÖ´Ù¸é ¸ðµÎ Á¦°ÅÇÑ´Ù. value´Â + ÀûÁö ¾Ê´Â´Ù.
    + +
    echo
    +
    ÀÌ·± À̸§ÀÇ ¿äû Çì´õ¸¦ ±×´ë·Î ÀÀ´ä Çì´õ·Î º¸³½´Ù. + header¿¡ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + value´Â ÀûÁö ¾Ê´Â´Ù.
    +
    + +

    ¾Æ±Ô¸ÕÆ® µÚ¿¡ header À̸§ÀÌ ³ª¿Â´Ù. Çì´õ¸í + µÚ¿¡ ÄÝ·ÐÀ» ÀûÀ» ¼ö ÀÖÁö¸¸, ¾ø¾îµµ µÈ´Ù. set, + append, add, unset¿¡¼­ + ´ë¼Ò¹®ÀÚ´Â ¹«½ÃÇÑ´Ù. echoÀÇ header + À̸§Àº ´ë¼ö¹®ÀÚ¸¦ ±¸º°ÇÏ°í Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    add, append, setÀ» + »ç¿ëÇÒ¶§´Â ¼¼¹ø° ¾Æ±Ô¸ÕÆ® value°¡ ÇÊ¿äÇÏ´Ù. + value ¾È¿¡ °ø¹éÀÌ ÀÖ´Ù¸é ½Öµû¿ÈÇ¥·Î ¹­¾î¾ß ÇÑ´Ù. + value´Â ÀÏ¹Ý ¹®ÀÚ¿­À̳ª Çü½ÄÀ» ±â¼úÇÏ´Â ¹®ÀÚ¿­À̸ç, + µÎ°¡Áö¸¦ °°ÀÌ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. value¿¡¼­ Áö¿øÇÏ´Â + Çü½Ä±â¼úÀÚ´Â ´ÙÀ½°ú °°´Ù.

    + + + + + + + + + + + + + + + + + + + +
    Çü½Ä¼³¸í
    %%ÆÛ¼¾Æ® ±âÈ£
    %t¿äûÀ» ¹ÞÀº ½Ã°£À» ±¹Á¦Ç¥Áؽ÷Πepoch (1970³â 1¿ù + 1ÀÏ) ÀÌÈÄ Áö³­ ¸¶ÀÌÅ©·ÎÃÊ ´ÜÀ§·Î. °ª ¾Õ¿¡ t=ÀÌ + ºÙ´Â´Ù.
    %D¿äûÀ» ¹ÞÀº ½Ã°£ºÎÅÍ Çì´õ¸¦ ³×Æ®¿÷¿¡ ¾µ¶§±îÁö °É¸° + ½Ã°£. ¿äûÀÇ ±â°£À» Àé´Ù. °ª ¾Õ¿¡ D=ÀÌ + ºÙ´Â´Ù.
    %{FOOBAR}eȯ°æº¯¼ö FOOBARÀÇ + ³»¿ë.
    %{FOOBAR}smod_sslÀÌ µ¿ÀÛÇÑ´Ù¸é, SSL ȯ°æº¯¼ö + FOOBARÀÇ ³»¿ë.
    + + ÁÖÀÇ +

    %s Çü½Ä Áö½ÃÀÚ´Â ¾ÆÆÄÄ¡ 2.1 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. + ÀÌ Áö½ÃÀÚ´Â SSLOptions +StdEnvVars¸¦ »ç¿ëÇÏ´Â + ºÎ´ãÀ» ´ú±âÀ§ÇØ %e ´ë½Å »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¾î¶² + ÀÌÀ¯¿¡¼­°Ç SSLOptions +StdEnvVars¸¦ »ç¿ëÇØ¾ß + ÇÑ´Ù¸é, %e´Â %s º¸´Ù ÈξÀ ´õ + È¿À²ÀûÀÌ´Ù.

    +
    + +

    Header Áö½Ã¾î µÚ¿¡ ÇൿÀÌ ÀϾ + Á¶°ÇÀ» Áö½ÃÇÏ´Â Ãß°¡ ¾Æ±Ô¸ÕÆ®³ª À̸¥ 󸮸¦ + ¶æÇÏ´Â Å°¿öµå early°¡ ³ª¿Ã ¼ö ÀÖ´Ù. + env=... ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇÑ °æ¿ì ÇØ´ç + ȯ°æº¯¼ö°¡ Á¸ÀçÇÑ´Ù¸é (ȤÀº + env=!...¿¡ ³ª¿Â ȯ°æº¯¼ö°¡ Á¸ÀçÇÏÁö + ¾Ê´Ù¸é) Header Áö½Ã¾î°¡ µ¿ÀÛÇÑ´Ù. + ±×·¸Áö ¾ÊÀ¸¸é Áö½Ã¾î´Â ¿äû¿¡ ¾Æ¹« ¿µÇâÀ» ¹ÌÄ¡Áö ¾Ê´Â´Ù.

    + +

    À̸¥ ¹æ½ÄÀÌ ¾Æ´Ï¶ó¸é ÀÀ´äÀ» ³×Æ®¿÷À¸·Î + º¸³»±â Á÷Àü¿¡ Header Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. + ±×·¡¼­ Çì´õ ÇÊÅÍ°¡ Ãß°¡ÇÏ´Â Çì´õ¸¦ Á¦¿ÜÇÑ ´ëºÎºÐÀÇ Çì´õ¸¦ + ¼³Á¤Çϰųª µ¤¾î¾µ ¼ö ÀÖ´Ù.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_headers.xml.meta b/trunk/docs/manual/mod/mod_headers.xml.meta new file mode 100644 index 0000000000..4647b21b45 --- /dev/null +++ b/trunk/docs/manual/mod/mod_headers.xml.meta @@ -0,0 +1,13 @@ + + + + mod_headers + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_ident.html b/trunk/docs/manual/mod/mod_ident.html new file mode 100644 index 0000000000..35282bad10 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.html @@ -0,0 +1,7 @@ +URI: mod_ident.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_ident.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_ident.html.en b/trunk/docs/manual/mod/mod_ident.html.en new file mode 100644 index 0000000000..2daaa5f49e --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.html.en @@ -0,0 +1,101 @@ + + + +mod_ident - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_ident

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + + +
    Description:RFC 1413 ident lookups
    Status:Extension
    Module Identifier:ident_module
    Source File:mod_ident.c
    Compatibility:Available in Apache 2.1 and later
    +

    Summary

    + +

    This module queries an RFC 1413 compatible daemon on a remote host to look up the owner of + a connection.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    IdentityCheck Directive

    + + + + + + + + +
    Description:Enables logging of the RFC 1413 identity of the remote +user
    Syntax:IdentityCheck On|Off
    Default:IdentityCheck Off
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_ident
    Compatibility:Moved out of core in Apache 2.1
    +

    This directive enables RFC 1413-compliant logging of the remote user name for each + connection, where the client machine runs identd or something similar. + This information is logged in the access log using the %...l + format string.

    + +
    + The information should not be trusted in any way except for + rudimentary usage tracking. +
    + +

    Note that this can cause serious latency problems accessing + your server since every request requires one of these lookups + to be performed. When firewalls or proxy servers are involved, + each lookup might possibly fail and add a latency duration as + defined by the IdentityCheckTimeout directive to each hit. So in + general this is not very useful on public servers accessible from + the Internet.

    + +
    +
    top
    +

    IdentityCheckTimeout Directive

    + + + + + + + +
    Description:Determines the timeout duration for ident requests
    Syntax:IdentityCheckTimeout seconds
    Default:IdentityCheckTimeout 30
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_ident
    +

    This directive specifies the timeout duration of an ident + request. The default value of 30 seconds is recommended by RFC 1413, mainly because + of possible network latency. However, you may want to adjust the + timeout value according to your local network speed.

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ident.html.ko.euc-kr b/trunk/docs/manual/mod/mod_ident.html.ko.euc-kr new file mode 100644 index 0000000000..2f66be6b08 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.html.ko.euc-kr @@ -0,0 +1,98 @@ + + + +mod_ident - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_ident

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + + + +
    ¼³¸í:RFC 1413 ident °Ë»ö
    »óÅÂ:Extension
    ¸ðµâ¸í:ident_module
    ¼Ò½ºÆÄÀÏ:mod_ident.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº ¿¬°áÀÇ ¼ÒÀ¯ÀÚ¸¦ ã±âÀ§ÇØ ¿ø°Ý È£½ºÆ®¿¡ ÀÖ´Â + RFC 1413 + ȣȯ µ¥¸óÀ» °Ë»öÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    IdentityCheck Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:¿ø°Ý »ç¿ëÀÚÀÇ RFC 1413 ½Å¿øÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    ¹®¹ý:IdentityCheck On|Off
    ±âº»°ª:IdentityCheck Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory
    »óÅÂ:Extension
    ¸ðµâ:mod_ident
    Áö¿ø:¾ÆÆÄÄ¡ 2.1ºÎÅÍ core¿¡¼­ ºüÁ® ³ª¿Ô´Ù
    +

    ÀÌ Áö½Ã¾î´Â RFC + 1413À» ÀÌ¿ëÇÏ¿© Ŭ¶óÀ̾ðÆ® ¸Ó½®ÀÌ identd µîÀ» ½ÇÇàÇÑ´Ù¸é + ¿¬°á¿¡ ´ëÇÑ ¿ø°Ý »ç¿ëÀÚ¸íÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù. Çü½Ä¹®ÀÚ¿­·Î + %...lÀ» »ç¿ëÇÏ¿© Á¢±Ù ·Î±×¿¡ ÀÌ Á¤º¸¸¦ ±â·ÏÇÑ´Ù.

    + +
    + ±âº»ÀûÀÎ »ç¿ëÃßÀû ¿ÜÀÇ ¿ëµµ·Î ÀÌ Á¤º¸¸¦ ½Å·ÚÇÒ ¼ö ¾ø´Ù. +
    + +

    ¿äû¸¶´Ù °Ë»öÀ» ÇØ¾ß Çϱ⶧¹®¿¡ ¼­¹ö Á¢±ÙÀÌ »ó´çÈ÷ Áö¿¬µÇ´Â + ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖÀ½À» À¯ÀÇÇ϶ó. Áß°£¿¡ ¹æÈ­º®À̳ª ÇÁ·Ï½Ã¼­¹ö°¡ + ÀÖ´Ù¸é, ¾Æ¸¶µµ °Ë»öÀº ½ÇÆÐÇÒ °ÍÀÌ°í ¸Å ¿äû¿¡ IdentityCheckTimeout Áö½Ã¾î·Î + ÁöÁ¤ÇѸ¸Å­ Áö¿¬ÀÌ ¹ß»ýÇÑ´Ù. ±×·¡¼­ º¸Åë ÀÎÅͳÝÀÇ °ø°³µÈ + ¼­¹ö¿¡¼­´Â À¯¿ëÇÏÁö ¾Ê´Ù.

    + +
    +
    top
    +

    IdentityCheckTimeout Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ident ¿äûÀÇ ½Ã°£Á¦ÇÑÀ» ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:IdentityCheckTimeout seconds
    ±âº»°ª:IdentityCheckTimeout 30
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory
    »óÅÂ:Extension
    ¸ðµâ:mod_ident
    +

    ÀÌ Áö½Ã¾î´Â ident ¿äûÀÇ ½Ã°£Á¦ÇÑÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + ³×Æ®¿÷ Áö¿¬À» °í·ÁÇÏ¿© RFC 1413ÀÌ + ±ÇÇÏ´Â 30 ÃÊÀÌ´Ù. ±×·¯³ª ³×Æ®¿÷ ¼Óµµ »óȲ¿¡ µû¶ó ½Ã°£Á¦ÇÑ°ªÀ» + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ident.xml b/trunk/docs/manual/mod/mod_ident.xml new file mode 100644 index 0000000000..79fcef794f --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.xml @@ -0,0 +1,89 @@ + + + + + + + + + +mod_ident +RFC 1413 ident lookups +Extension +mod_ident.c +ident_module +Available in Apache 2.1 and later + + +

    This module queries an RFC 1413 compatible daemon on a remote host to look up the owner of + a connection.

    +
    +mod_log_config + + +IdentityCheck +Enables logging of the RFC 1413 identity of the remote +user +IdentityCheck On|Off +IdentityCheck Off +server configvirtual host +directory +Moved out of core in Apache 2.1 + + +

    This directive enables RFC 1413-compliant logging of the remote user name for each + connection, where the client machine runs identd or something similar. + This information is logged in the access log using the %...l + format string.

    + + + The information should not be trusted in any way except for + rudimentary usage tracking. + + +

    Note that this can cause serious latency problems accessing + your server since every request requires one of these lookups + to be performed. When firewalls or proxy servers are involved, + each lookup might possibly fail and add a latency duration as + defined by the IdentityCheckTimeout directive to each hit. So in + general this is not very useful on public servers accessible from + the Internet.

    +
    +
    + + +IdentityCheckTimeout +Determines the timeout duration for ident requests +IdentityCheckTimeout seconds +IdentityCheckTimeout 30 +server configvirtual host +directory + +

    This directive specifies the timeout duration of an ident + request. The default value of 30 seconds is recommended by RFC 1413, mainly because + of possible network latency. However, you may want to adjust the + timeout value according to your local network speed.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_ident.xml.ko b/trunk/docs/manual/mod/mod_ident.xml.ko new file mode 100644 index 0000000000..31453e965f --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.xml.ko @@ -0,0 +1,85 @@ + + + + + + + + + +mod_ident +RFC 1413 ident °Ë»ö +Extension +mod_ident.c +ident_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ÀÌ ¸ðµâÀº ¿¬°áÀÇ ¼ÒÀ¯ÀÚ¸¦ ã±âÀ§ÇØ ¿ø°Ý È£½ºÆ®¿¡ ÀÖ´Â + RFC 1413 + ȣȯ µ¥¸óÀ» °Ë»öÇÑ´Ù.

    +
    +mod_log_config + + +IdentityCheck +¿ø°Ý »ç¿ëÀÚÀÇ RFC 1413 ½Å¿øÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù +IdentityCheck On|Off +IdentityCheck Off +server configvirtual host +directory +¾ÆÆÄÄ¡ 2.1ºÎÅÍ core¿¡¼­ ºüÁ® ³ª¿Ô´Ù + + +

    ÀÌ Áö½Ã¾î´Â RFC + 1413À» ÀÌ¿ëÇÏ¿© Ŭ¶óÀ̾ðÆ® ¸Ó½®ÀÌ identd µîÀ» ½ÇÇàÇÑ´Ù¸é + ¿¬°á¿¡ ´ëÇÑ ¿ø°Ý »ç¿ëÀÚ¸íÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù. Çü½Ä¹®ÀÚ¿­·Î + %...lÀ» »ç¿ëÇÏ¿© Á¢±Ù ·Î±×¿¡ ÀÌ Á¤º¸¸¦ ±â·ÏÇÑ´Ù.

    + + + ±âº»ÀûÀÎ »ç¿ëÃßÀû ¿ÜÀÇ ¿ëµµ·Î ÀÌ Á¤º¸¸¦ ½Å·ÚÇÒ ¼ö ¾ø´Ù. + + +

    ¿äû¸¶´Ù °Ë»öÀ» ÇØ¾ß Çϱ⶧¹®¿¡ ¼­¹ö Á¢±ÙÀÌ »ó´çÈ÷ Áö¿¬µÇ´Â + ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖÀ½À» À¯ÀÇÇ϶ó. Áß°£¿¡ ¹æÈ­º®À̳ª ÇÁ·Ï½Ã¼­¹ö°¡ + ÀÖ´Ù¸é, ¾Æ¸¶µµ °Ë»öÀº ½ÇÆÐÇÒ °ÍÀÌ°í ¸Å ¿äû¿¡ IdentityCheckTimeout Áö½Ã¾î·Î + ÁöÁ¤ÇѸ¸Å­ Áö¿¬ÀÌ ¹ß»ýÇÑ´Ù. ±×·¡¼­ º¸Åë ÀÎÅͳÝÀÇ °ø°³µÈ + ¼­¹ö¿¡¼­´Â À¯¿ëÇÏÁö ¾Ê´Ù.

    +
    +
    + + +IdentityCheckTimeout +ident ¿äûÀÇ ½Ã°£Á¦ÇÑÀ» ÁöÁ¤ÇÑ´Ù +IdentityCheckTimeout seconds +IdentityCheckTimeout 30 +server configvirtual host +directory + +

    ÀÌ Áö½Ã¾î´Â ident ¿äûÀÇ ½Ã°£Á¦ÇÑÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + ³×Æ®¿÷ Áö¿¬À» °í·ÁÇÏ¿© RFC 1413ÀÌ + ±ÇÇÏ´Â 30 ÃÊÀÌ´Ù. ±×·¯³ª ³×Æ®¿÷ ¼Óµµ »óȲ¿¡ µû¶ó ½Ã°£Á¦ÇÑ°ªÀ» + ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_ident.xml.meta b/trunk/docs/manual/mod/mod_ident.xml.meta new file mode 100644 index 0000000000..195ef1a0d1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ident.xml.meta @@ -0,0 +1,12 @@ + + + + mod_ident + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_imagemap.html b/trunk/docs/manual/mod/mod_imagemap.html new file mode 100644 index 0000000000..b571be950b --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.html @@ -0,0 +1,7 @@ +URI: mod_imagemap.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_imagemap.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_imagemap.html.en b/trunk/docs/manual/mod/mod_imagemap.html.en new file mode 100644 index 0000000000..898e04d5ff --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.html.en @@ -0,0 +1,382 @@ + + + +mod_imagemap - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_imagemap

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + +
    Description:Server-side imagemap processing
    Status:Base
    Module Identifier:imap_module
    Source File:mod_imagemap.c
    +

    Summary

    + +

    This module processes .map files, thereby + replacing the functionality of the imagemap CGI + program. Any directory or document type configured to use the + handler imap-file (using either + AddHandler or + SetHandler) + will be processed by this module.

    + +

    The following directive will activate files ending with + .map as imagemap files:

    + +

    AddHandler imap-file map

    + +

    Note that the following is still supported:

    + +

    AddType application/x-httpd-imap map

    + +

    However, we are trying to phase out "magic MIME types" so we + are deprecating this method.

    +
    + +
    top
    +
    +

    New Features

    + +

    The imagemap module adds some new features that were not + possible with previously distributed imagemap programs.

    + +
      +
    • URL references relative to the Referer: information.
    • + +
    • Default <base> assignment through a new map + directive base.
    • + +
    • No need for imagemap.conf file.
    • + +
    • Point references.
    • + +
    • Configurable generation of imagemap menus.
    • +
    +
    top
    +
    +

    Imagemap File

    + +

    The lines in the imagemap files can have one of several + formats:

    + +

    + directive value [x,y ...]
    + directive value "Menu text" [x,y + ...]
    + directive value x,y ... "Menu text" +

    + +

    The directive is one of base, + default, poly, circle, + rect, or point. The value is an + absolute or relative URL, or one of the special values listed + below. The coordinates are x,y + pairs separated by whitespace. The quoted text is used as the text of + the link if a imagemap menu is generated. Lines beginning with '#' are + comments.

    + +

    Imagemap File Directives

    +

    There are six directives allowed in the imagemap file. The + directives can come in any order, but are processed in the + order they are found in the imagemap file.

    + +
    +
    base Directive
    + +

    Has the effect of <base href="value"> + . The non-absolute URLs of the map-file are taken relative + to this value. The base directive overrides + ImapBase as set in a + .htaccess file or in the server configuration files. + In the absence of an ImapBase configuration + directive, base defaults to + http://server_name/.

    +

    base_uri is synonymous with base. + Note that a trailing slash on the URL is significant.

    + +
    default Directive
    + +
    The action taken if the coordinates given do not fit any + of the poly, circle or + rect directives, and there are no + point directives. Defaults to nocontent + in the absence of an ImapDefault configuration setting, causing a status + code of 204 No Content to be returned. The client + should keep the same page displayed.
    + +
    poly Directive
    + +
    Takes three to one-hundred points, and is obeyed if the + user selected coordinates fall within the polygon defined by + these points.
    + +
    circle
    + +
    Takes the center coordinates of a circle and a point on + the circle. Is obeyed if the user selected point is with the + circle.
    + +
    rect Directive
    + +
    Takes the coordinates of two opposing corners of a + rectangle. Obeyed if the point selected is within this + rectangle.
    + +
    point Directive
    + +
    Takes a single point. The point directive closest to the + user selected point is obeyed if no other directives are + satisfied. Note that default will not be + followed if a point directive is present and + valid coordinates are given.
    +
    + + +

    Values

    + +

    The values for each of the directives can any of the following:

    + +
    +
    a URL
    + +

    The URL can be relative or absolute URL. Relative URLs + can contain '..' syntax and will be resolved relative to the + base value.

    +

    base itself will not resolved according to the + current value. A statement base mailto: will + work properly, though.

    + +
    map
    + +
    Equivalent to the URL of the imagemap file itself. No + coordinates are sent with this, so a menu will be generated + unless ImapMenu is set to + none.
    + +
    menu
    +
    Synonymous with map.
    + +
    referer
    + +
    Equivalent to the URL of the referring document. Defaults + to http://servername/ if no Referer: + header was present.
    + +
    nocontent
    + +
    Sends a status code of 204 No Content, + telling the client to keep the same page displayed. Valid for + all but base.
    + +
    error
    + +
    Fails with a 500 Server Error. Valid for all + but base, but sort of silly for anything but + default.
    +
    + + +

    Coordinates

    + +
    +
    0,0 200,200
    + +
    A coordinate consists of an x and a y + value separated by a comma. The coordinates are separated + from each other by whitespace. To accommodate the way Lynx + handles imagemaps, should a user select the coordinate + 0,0, it is as if no coordinate had been + selected.
    +
    + + + +

    Quoted Text

    + +
    +
    "Menu Text"
    + +

    After the value or after the coordinates, the line + optionally may contain text within double quotes. This string + is used as the text for the link if a menu is + generated:

    + +

    + <a href="http://foo.com/">Menu text</a> +

    + +

    If no quoted text is present, the name of the link will be + used as the text:

    + +

    + <a href="http://foo.com/">http://foo.com</a> +

    + +

    If you want to use double quotes within this text, you have to + write them as &quot;.

    +
    + + +
    top
    +
    +

    Example Mapfile

    + +

    + #Comments are printed in a 'formatted' or 'semiformatted' menu.
    + #And can contain html tags. <hr>
    + base referer
    + poly map "Could I have a menu, please?" 0,0 0,10 10,10 10,0
    + rect .. 0,0 77,27 "the directory of the referer"
    + circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27
    + rect another_file "in same directory as referer" 306,0 419,27
    + point http://www.zyzzyva.com/ 100,100
    + point http://www.tripod.com/ 200,200
    + rect mailto:nate@tripod.com 100,150 200,0 "Bugs?"
    +

    + +
    top
    +
    +

    Referencing your mapfile

    + +

    HTML example

    + <a href="/maps/imagemap1.map">
    + + <img ismap src="/images/imagemap1.gif">
    +
    + </a> +

    + +

    XHTML example

    + <a href="/maps/imagemap1.map">
    + + <img ismap="ismap" src="/images/imagemap1.gif" />
    +
    + </a> +

    + +
    +
    top
    +

    ImapBase Directive

    + + + + + + + + +
    Description:Default base for imagemap files
    Syntax:ImapBase map|referer|URL
    Default:ImapBase http://servername/
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_imagemap
    +

    The ImapBase directive sets the default + base used in the imagemap files. Its value is + overridden by a base directive within the imagemap + file. If not present, the base defaults to + http://servername/.

    + +

    See also

    + +
    +
    top
    +

    ImapDefault Directive

    + + + + + + + + +
    Description:Default action when an imagemap is called with coordinates +that are not explicitly mapped
    Syntax:ImapDefault error|nocontent|map|referer|URL
    Default:ImapDefault nocontent
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_imagemap
    +

    The ImapDefault directive sets the default + default used in the imagemap files. Its value is + overridden by a default directive within the + imagemap file. If not present, the default action + is nocontent, which means that a 204 No + Content is sent to the client. In this case, the client + should continue to display the original page.

    + +
    +
    top
    +

    ImapMenu Directive

    + + + + + + + +
    Description:Action if no coordinates are given when calling +an imagemap
    Syntax:ImapMenu none|formatted|semiformatted|unformatted
    Context:server config, virtual host, directory, .htaccess
    Override:Indexes
    Status:Base
    Module:mod_imagemap
    +

    The ImapMenu directive determines the + action taken if an imagemap file is called without valid + coordinates.

    + +
    +
    none
    +
    If ImapMenu is none, no menu is generated, + and the default action is performed.
    + +
    formatted
    +
    A formatted menu is the simplest menu. + Comments in the imagemap file are ignored. A level one header + is printed, then an hrule, then the links each on a separate + line. The menu has a consistent, plain look close to that of + a directory listing.
    + +
    semiformatted
    +
    In the semiformatted menu, comments are + printed where they occur in the imagemap file. Blank lines + are turned into HTML breaks. No header or hrule is printed, + but otherwise the menu is the same as a + formatted menu.
    + +
    unformatted
    +
    Comments are printed, blank lines are ignored. Nothing is + printed that does not appear in the imagemap file. All breaks + and headers must be included as comments in the imagemap + file. This gives you the most flexibility over the appearance + of your menus, but requires you to treat your map files as + HTML instead of plaintext.
    +
    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_imagemap.html.ko.euc-kr b/trunk/docs/manual/mod/mod_imagemap.html.ko.euc-kr new file mode 100644 index 0000000000..2f2b7a9a3c --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.html.ko.euc-kr @@ -0,0 +1,363 @@ + + + +mod_imap - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_imap

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:¼­¹öÃø À̹ÌÁö¸Ê(imagemap) ó¸®
    »óÅÂ:Base
    ¸ðµâ¸í:imap_module
    ¼Ò½ºÆÄÀÏ:mod_imap.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº imagemap CGI ÇÁ·Î±×·¥À» ´ë½ÅÇÏ¿© + .map ÆÄÀÏÀ» ó¸®ÇÑ´Ù. ÀÌ ¸ðµâÀº (AddHandler³ª SetHandler¸¦ »ç¿ëÇÏ¿©) + imap-file Çڵ鷯¸¦ »ç¿ëÇϵµ·Ï ¼³Á¤ÇÑ µð·ºÅ丮³ª + ¹®¼­¸¦ ó¸®ÇÑ´Ù.

    + +

    ¾Æ·¡ Áö½Ã¾î´Â .mapÀ¸·Î ³¡³ª´Â ÆÄÀÏÀ» À̹ÌÁö¸Ê + ÆÄÀÏ·Î ¼³Á¤ÇÑ´Ù.

    + +

    AddHandler imap-file map

    + +

    ¾ÆÁ÷µµ ¾Æ·¡¿Í °°Àº ¼³Á¤À» Áö¿øÇÑ´Ù.

    + +

    AddType application/x-httpd-imap map

    + +

    ±×·¯³ª ¿ì¸®´Â Á¡Â÷ "¼­¹ö¿¡°Ô Ưº°ÇÑ Àǹ̰¡ ÀÖ´Â MIME + type"À» Á¦°ÅÇÏ·Á°í Çϱ⶧¹®¿¡ ÀÌ ¹æ¹ýÀº ¾ø¾îÁú °ÍÀÌ´Ù.

    +
    + +
    top
    +
    +

    »õ·Î¿î ±â´É

    + +

    À̹ÌÁö¸Ê ¸ðµâ¿¡´Â ÀÌÀü À̹ÌÁö¸Ê ÇÁ·Î±×·¥¿¡´Â ¾ø´Â ¸î°¡Áö + »õ·Î¿î ±â´ÉÀÌ ÀÖ´Ù.

    + +
      +
    • Referer: Á¤º¸¿¡ »ó´ëÀûÀÎ URL ÂüÁ¶.
    • + +
    • »õ·Î¿î base ¸ÊÁö½Ã¾î¸¦ »ç¿ëÇÏ¿© ±âº» + <base> ÁöÁ¤.
    • + +
    • imagemap.conf ÆÄÀÏ ÇÊ¿ä¾øÀ½.
    • + +
    • Á¡(point) ÂüÁ¶.
    • + +
    • À̹ÌÁö¸Ê ¸Þ´º Á¶Á¤ °¡´É.
    • +
    +
    top
    +
    +

    À̹ÌÁö¸Ê ÆÄÀÏ

    + +

    À̹ÌÁö¸Ê ÆÄÀÏÀº ¾Æ·¡¿Í °°Àº Çü½ÄÀ¸·Î ÀÛ¼ºÇÑ´Ù.

    + +

    + directive value [x,y ...]
    + directive value "Menu text" [x,y + ...]
    + directive value x,y ... "Menu text" +

    + +

    directive´Â base, default, + poly, circle, rect, + point Áß Çϳª´Ù. value¿¡´Â Àý´ë URLÀ̳ª »ó´ë + URL ȤÀº ¾Æ·¡¿¡¼­ ¿­°ÅÇÒ Æ¯¼ö°ªÀ» »ç¿ëÇÑ´Ù. ÁÂÇ¥´Â °ø¹éÀ¸·Î + ±¸ºÐÇÑ x,y ½ÖÀÌ´Ù. µû¿ÈÇ¥·Î + ¹­Àº ¹®±¸´Â À̹ÌÁö¸Ê ¸Þ´º¸¦ ¸¸µé¶§ ¸µÅ© Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù. + '#'·Î ½ÃÀÛÇÏ´Â ÁÙÀº ÁÖ¼®ÀÌ´Ù.

    + +

    À̹ÌÁö¸Ê ÆÄÀÏ Áö½Ã¾î

    +

    À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ 6°¡Áö Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î´Â + Ưº°ÇÑ ¼ø¼­¾øÀÌ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, À̹ÌÁö¸Ê ÆÄÀÏ¿¡ ³ª¿Â + ¼ø¼­´ë·Î ó¸®ÇÑ´Ù.

    + +
    +
    base Áö½Ã¾î
    + +

    <base href="value"> + ±â´ÉÀ» ÇÑ´Ù. ¸ÊÆÄÀÏ¿¡¼­ ³ª¿À´Â URLÀº Àý´ë URLÀÌ ¾Æ´Ï¶ó¸é + ÀÌ °ª¿¡ »ó´ë URL·Î Ãë±ÞÇÑ´Ù. base Áö½Ã¾î´Â + .htaccess ÆÄÀÏÀ̳ª ¼­¹ö¼³Á¤ÆÄÀÏ¿¡¼­ ¼³Á¤ÇÑ + ImapBase °ªÀ» + ¹«½ÃÇÑ´Ù. ImapBase ¼³Á¤Áö½Ã¾î°¡ + ¾ø´Ù¸é ±âº» base °ªÀº + http://server_name/ÀÌ´Ù.

    +

    base_uri´Â base¿Í °°´Ù. URL¿¡¼­ + ¸¶Áö¸· ½½·¡½¬¸¦ ÀØÁö¸¶¶ó.

    + +
    default Áö½Ã¾î
    + +
    ÇØ´ç ÁÂÇ¥°¡ poly, circle, + rect Áö½Ã¾î¿¡ ÇØ´çÇÏÁö ¾Ê°í point + Áö½Ã¾î¸¦ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì ÇൿÀ» ÁöÁ¤ÇÑ´Ù. ImapDefault ¼³Á¤ÀÌ ¾ø´Ù¸é + ±âº»°ªÀº 204 No Content »óÅÂÄڵ带 ¹ÝȯÇÏ´Â + nocontentÀÌ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â µ¿ÀÏÇÑ + ÆäÀÌÁö¸¦ º¸¿©Áà¾ß ÇÑ´Ù.
    + +
    poly Áö½Ã¾î
    + +
    Á¡À» ¼¼°³¿¡¼­ ¹é°³±îÁö ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ ÀÌ + Á¡µé·Î ÀÌ·ç¾îÁø ´Ù°¢Çü ¾ÈÀÇ ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    circle
    + +
    ¿øÀÇ Á߽ɰú ¿øÀ§ÀÇ ÇÑ Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. »ç¿ëÀÚ°¡ + ¿ø ¾ÈÀÇ ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    rect Áö½Ã¾î
    + +
    »ç°¢ÇüÀÇ µÎ ¸ð¼­¸® Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. »ç°¢Çü ¾ÈÀÇ + ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    point Áö½Ã¾î
    + +
    ÇÑ Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. ´Ù¸¥ Áö½Ã¾îµéÀ» ¸¸Á·ÇÏÁö ¾ÊÀº + °æ¿ì »ç¿ëÀÚ°¡ ¼±ÅÃÇÑ ÁÂÇ¥¿¡ °¡Àå °¡±î¿î point Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù. point Áö½Ã¾î¸¦ »ç¿ëÇÏ°í À¯È¿ÇÑ + ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì default´Â Àý´ë·Î »ç¿ëµÇÁö + ¾Ê´Â´Ù.
    +
    + + +

    Áö½Ã¾î¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â °ªµé

    + +

    Áö½Ã¾î¿¡ ¾Æ·¡ value¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    URL
    + +

    »ó´ë URLÀ̳ª Àý´ë URLÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. »ó´ë URL¿¡ + '..'À» »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, base °ªÀ» ±âÁØÀ¸·Î + ã´Â´Ù.

    +

    base¸¦ ¼³Á¤ÇÒ¶§´Â ÇöÀç base°ªÀº ¹«½ÃÇÑ´Ù. + ±×·¯³ª, base mailto: ¹®Àº »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    map
    + +
    À̹ÌÁö¸Ê ÆÄÀÏ ÀÚü URL°ú °°´Ù. ÁÂÇ¥°¡ ¾ø°í ImapMenu°¡ noneÀÌ + ¾Æ´Ï¶ó¸é ¸Þ´º¸¦ ¸¸µç´Ù.
    + +
    menu
    +
    map°ú °°´Ù.
    + +
    referer
    + +
    ÂüÁ¶(¸µÅ©¸¦ µû¶ó¿À±â Àü) ¹®¼­ URL°ú °°´Ù. + Referer: Çì´õ°¡ ¾ø´Ù¸é ±âº»°ªÀº + http://servername/ÀÌ´Ù.
    + +
    nocontent
    + +
    Ŭ¶óÀ̾ðÆ®¿¡°Ô µ¿ÀÏÇÑ ÆäÀÌÁö¸¦ ±×´ë·Î º¸¿©ÁÖ¶ó´Â + 204 No Content »óÅÂÄڵ带 º¸³½´Ù. + base¸¦ Á¦¿ÜÇÑ ¸ðµç Áö½Ã¾î¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    error
    + +
    ½ÇÆи¦ ³ªÅ¸³»´Â 500 Server Error¸¦ º¸³½´Ù. + base¸¦ Á¦¿ÜÇÑ ¸ðµç Áö½Ã¾î¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, + default ¿Ü¿¡´Â »ç¿ëÇÒ ÀÏÀÌ ¾ø´Ù.
    +
    + + +

    ÁÂÇ¥

    + +
    +
    0,0 200,200
    + +
    ÁÂÇ¥´Â ½°Ç¥·Î ±¸ºÐÇÑ x¿Í y °ªÀÌ´Ù. + ÁÂÇ¥µéÀº ¼­·Î °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. À̹ÌÁö¸ÊÀ» ´Ù·ç´Â ¹æ½Ä»ó + LynxÀÇ ÆíÀǸ¦ À§ÇØ »ç¿ëÀÚ°¡ 0,0 ÁÂÇ¥¸¦ ¼±ÅÃÇÏ¿´´Ù¸é + ÁÂÇ¥¸¦ ¼±ÅÃÇÏÁö ¾ÊÀº °Íó·³ µ¿ÀÛÇÑ´Ù.
    +
    + + + +

    µû¿ÈÇ¥·Î ¹­Àº ¹®±¸

    + +
    +
    "Menu Text"
    + +

    value µÚ³ª ÁÂÇ¥ µÚ¿¡ ½Öµû¿ÈÇ¥·Î ¹­Àº ¹®±¸¸¦ ÀûÀ» + ¼öµµ ÀÖ´Ù. ÀÌ ¹®ÀÚ¿­Àº ¸Þ´º¸¦ ¸¸µé¶§ ¸µÅ© Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù.

    + +

    + <a href="http://foo.com/">Menu text</a> +

    + +

    µû¿ÈÇ¥·Î ¹­Àº ¹®±¸°¡ ¾ø´Ù¸é ´ÙÀ½°ú °°ÀÌ ¸µÅ©¸¦ ¸µÅ© + Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù.

    + +

    + <a href="http://foo.com/">http://foo.com</a> +

    + +

    ¹®±¸¿¡ ½Öµû¿ÈÇ¥¸¦ ¾²·Á¸é &quot;¿Í + °°ÀÌ Àû¾î¾ß ÇÑ´Ù.

    +
    + + +
    top
    +
    +

    ¸ÊÆÄÀÏ ¿¹Á¦

    + +

    + #'formatted'³ª 'semiformatted' ¸Þ´º´Â ÁÖ¼®À» Ãâ·ÂÇÑ´Ù.
    + #±×¸®°í ÁÖ¼®¿¡ html ű׸¦ ¾µ ¼ö ÀÖ´Ù. <hr>
    + base referer
    + poly map "¸Þ´º¸¦ º¸¿©ÁÖ¼¼¿ä." 0,0 0,10 10,10 10,0
    + rect .. 0,0 77,27 "ÂüÁ¶ ¹®¼­°¡ ÀÖ´Â µð·ºÅ丮"
    + circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27
    + rect another_file "ÂüÁ¶ ¹®¼­¿Í °°Àº µð·ºÅ丮¿¡ ÀÖ´Â" 306,0 419,27
    + point http://www.zyzzyva.com/ 100,100
    + point http://www.tripod.com/ 200,200
    + rect mailto:nate@tripod.com 100,150 200,0 "¹ö±×?"
    +

    + +
    top
    +
    +

    ¸ÊÆÄÀÏ »ç¿ëÇϱâ

    + +

    HTML ¿¡Á¦

    + <a href="/maps/imagemap1.map">
    + + <img ismap src="/images/imagemap1.gif">
    +
    + </a> +

    + +

    XHTML ¿¹Á¦

    + <a href="/maps/imagemap1.map">
    + + <img ismap="ismap" src="/images/imagemap1.gif" />
    +
    + </a> +

    + +
    +
    top
    +

    ImapBase Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ base ±âº»°ª
    ¹®¹ý:ImapBase map|referer|URL
    ±âº»°ª:ImapBase http://servername/
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_imap
    +

    ImapBase Áö½Ã¾î´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ + »ç¿ëÇÒ base ±âº»°ªÀ» ¼³Á¤ÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏ + ¾È¿¡¼­ base Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¿©±â¼­ ¼³Á¤ÇÑ + °ªÀº ¹«½ÃÇÑ´Ù. µÑ ¸ðµÎ ¾ø´Ù¸é, base ±âº»°ªÀº + http://servername/ÀÌ´Ù.

    + +

    Âü°í

    + +
    +
    top
    +

    ImapDefault Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:À̹ÌÁö¸Ê¿¡ ¾î´À ¿µ¿ª¿¡µµ ÇØ´çÇÏÁö ¾Ê´Â ÁÂÇ¥¸¦ ÁØ +°æ¿ì ±âº» Çൿ
    ¹®¹ý:ImapDefault error|nocontent|map|referer|URL
    ±âº»°ª:ImapDefault nocontent
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_imap
    +

    ImapDefault Áö½Ã¾î´Â À̹ÌÁö¸Ê + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ default ±âº»°ªÀ» ¼³Á¤ÇÑ´Ù. + À̹ÌÁö¸Ê ÆÄÀÏ ¾È¿¡¼­ default Áö½Ã¾î¸¦ »ç¿ëÇϸé + ¿©±â¼­ ¼³Á¤ÇÑ °ªÀº ¹«½ÃÇÑ´Ù. µÑ ¸ðµÎ ¾ø´Ù¸é, default + ÇൿÀº Ŭ¶óÀ̾ðÆ®¿¡°Ô 204 No Content¸¦ º¸³»´Â + nocontentÀÌ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â ¿ø·¡ ÆäÀÌÁö¸¦ + ±×´ë·Î º¸¿©Áà¾ß ÇÑ´Ù.

    + +
    +
    top
    +

    ImapMenu Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÁÂÇ¥¾øÀÌ À̹ÌÁö¸Ê ¿äû½Ã ÃëÇÒ Çൿ
    ¹®¹ý:ImapMenu none|formatted|semiformatted|unformatted
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Indexes
    »óÅÂ:Base
    ¸ðµâ:mod_imap
    +

    ImapMenu Áö½Ã¾î´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + À¯È¿ÇÑ ÁÂÇ¥¸¦ ÁÖÁö ¾ÊÀº °æ¿ì ÃëÇÒ ÇൿÀ» °áÁ¤ÇÑ´Ù.

    + +
    +
    none
    +
    ImapMenu°¡ noneÀ̸é, ¸Þ´º¸¦ ¸¸µéÁö¾Ê°í + default ÇൿÀ» ÃëÇÑ´Ù.
    + +
    formatted
    +
    formatted ¸Þ´º´Â °¡Àå °£´ÜÇÑ ¸Þ´º´Ù. + À̹ÌÁö¸Ê ÆÄÀÏÀÇ ÁÖ¼®Àº ¹«½ÃÇÑ´Ù. °¡Àå Å« Ç¥Á¦¿Í ¼öÁ÷¼±À» + Ãâ·ÂÇÏ°í, ¸µÅ©¸¦ ÇÑÁÙ¾¿ Ãâ·ÂÇÑ´Ù. ¸Þ´º´Â ÀÏ°üµÇ°í ÆòÀÌÇϸç, + µð·ºÅ丮 ¸ñ·Ï°ú Èí»çÇÏ´Ù.
    + +
    semiformatted
    +
    semiformatted ¸Þ´º´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + ³ª¿À´Â ÁÖ¼®À» Ãâ·ÂÇÑ´Ù. ºóÁÙÀº HTML Çà¹Ù²ÞÀ¸·Î º¯È¯ÇÑ´Ù. + Ç¥Á¦³ª ¼öÁ÷¼±À» ±×¸®Áö ¾ÊÁö¸¸, ³ª¸ÓÁö´Â formatted + ¸Þ´º¿Í °°´Ù.
    + +
    unformatted
    +
    ÁÖ¼®Àº Ãâ·ÂÇÏ°í, ºóÁÙÀº ¹«½ÃÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + ÀÖ´Â ³»¿ë¸¸ Ãâ·ÂÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏÀÇ ÁÖ¼®¿¡ ÇÊ¿äÇÑ ¸ðµç + Çà¹Ù²Þ°ú Ç¥Á¦¸¦ Àû¾î¾ß ÇÑ´Ù. ¸Þ´ºÀÇ ¿Ü°üÀ» °¡Àå ÀÚÀ¯ÀÚÁ¦·Î + ²Ù¹Ð ¼ö ÀÖÁö¸¸, À̹ÌÁö¸Ê ÆÄÀÏÀ» »ç½Ç»ó ÀÏ¹Ý ¹®ÀÚÆÄÀÏÀÌ + ¾Æ´Ñ HTML·Î ºÁ¾ß ÇÑ´Ù.
    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_imagemap.xml b/trunk/docs/manual/mod/mod_imagemap.xml new file mode 100644 index 0000000000..0aba85511c --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.xml @@ -0,0 +1,359 @@ + + + + + + + + + +mod_imagemap +Server-side imagemap processing +Base +mod_imagemap.c +imap_module + + +

    This module processes .map files, thereby + replacing the functionality of the imagemap CGI + program. Any directory or document type configured to use the + handler imap-file (using either + AddHandler or + SetHandler) + will be processed by this module.

    + +

    The following directive will activate files ending with + .map as imagemap files:

    + + AddHandler imap-file map + +

    Note that the following is still supported:

    + + AddType application/x-httpd-imap map + +

    However, we are trying to phase out "magic MIME types" so we + are deprecating this method.

    +
    + +
    New Features + +

    The imagemap module adds some new features that were not + possible with previously distributed imagemap programs.

    + +
      +
    • URL references relative to the Referer: information.
    • + +
    • Default <base> assignment through a new map + directive base.
    • + +
    • No need for imagemap.conf file.
    • + +
    • Point references.
    • + +
    • Configurable generation of imagemap menus.
    • +
    +
    + +
    Imagemap File + +

    The lines in the imagemap files can have one of several + formats:

    + + + directive value [x,y ...]
    + directive value "Menu text" [x,y + ...]
    + directive value x,y ... "Menu text" +
    + +

    The directive is one of base, + default, poly, circle, + rect, or point. The value is an + absolute or relative URL, or one of the special values listed + below. The coordinates are x,y + pairs separated by whitespace. The quoted text is used as the text of + the link if a imagemap menu is generated. Lines beginning with '#' are + comments.

    + +
    Imagemap File Directives +

    There are six directives allowed in the imagemap file. The + directives can come in any order, but are processed in the + order they are found in the imagemap file.

    + +
    +
    base Directive
    + +

    Has the effect of <base href="value"> + . The non-absolute URLs of the map-file are taken relative + to this value. The base directive overrides + ImapBase as set in a + .htaccess file or in the server configuration files. + In the absence of an ImapBase configuration + directive, base defaults to + http://server_name/.

    +

    base_uri is synonymous with base. + Note that a trailing slash on the URL is significant.

    + +
    default Directive
    + +
    The action taken if the coordinates given do not fit any + of the poly, circle or + rect directives, and there are no + point directives. Defaults to nocontent + in the absence of an ImapDefault configuration setting, causing a status + code of 204 No Content to be returned. The client + should keep the same page displayed.
    + +
    poly Directive
    + +
    Takes three to one-hundred points, and is obeyed if the + user selected coordinates fall within the polygon defined by + these points.
    + +
    circle
    + +
    Takes the center coordinates of a circle and a point on + the circle. Is obeyed if the user selected point is with the + circle.
    + +
    rect Directive
    + +
    Takes the coordinates of two opposing corners of a + rectangle. Obeyed if the point selected is within this + rectangle.
    + +
    point Directive
    + +
    Takes a single point. The point directive closest to the + user selected point is obeyed if no other directives are + satisfied. Note that default will not be + followed if a point directive is present and + valid coordinates are given.
    +
    +
    + +
    Values + +

    The values for each of the directives can any of the following:

    + +
    +
    a URL
    + +

    The URL can be relative or absolute URL. Relative URLs + can contain '..' syntax and will be resolved relative to the + base value.

    +

    base itself will not resolved according to the + current value. A statement base mailto: will + work properly, though.

    + +
    map
    + +
    Equivalent to the URL of the imagemap file itself. No + coordinates are sent with this, so a menu will be generated + unless ImapMenu is set to + none.
    + +
    menu
    +
    Synonymous with map.
    + +
    referer
    + +
    Equivalent to the URL of the referring document. Defaults + to http://servername/ if no Referer: + header was present.
    + +
    nocontent
    + +
    Sends a status code of 204 No Content, + telling the client to keep the same page displayed. Valid for + all but base.
    + +
    error
    + +
    Fails with a 500 Server Error. Valid for all + but base, but sort of silly for anything but + default.
    +
    +
    + +
    Coordinates + +
    +
    0,0 200,200
    + +
    A coordinate consists of an x and a y + value separated by a comma. The coordinates are separated + from each other by whitespace. To accommodate the way Lynx + handles imagemaps, should a user select the coordinate + 0,0, it is as if no coordinate had been + selected.
    +
    + +
    + +
    Quoted Text + +
    +
    "Menu Text"
    + +

    After the value or after the coordinates, the line + optionally may contain text within double quotes. This string + is used as the text for the link if a menu is + generated:

    + + + <a href="http://foo.com/">Menu text</a> + + +

    If no quoted text is present, the name of the link will be + used as the text:

    + + + <a href="http://foo.com/">http://foo.com</a> + + +

    If you want to use double quotes within this text, you have to + write them as &quot;.

    +
    + +
    +
    + +
    Example Mapfile + + + #Comments are printed in a 'formatted' or 'semiformatted' menu.
    + #And can contain html tags. <hr>
    + base referer
    + poly map "Could I have a menu, please?" 0,0 0,10 10,10 10,0
    + rect .. 0,0 77,27 "the directory of the referer"
    + circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27
    + rect another_file "in same directory as referer" 306,0 419,27
    + point http://www.zyzzyva.com/ 100,100
    + point http://www.tripod.com/ 200,200
    + rect mailto:nate@tripod.com 100,150 200,0 "Bugs?"
    +
    + +
    + +
    Referencing your mapfile + + HTML example + <a href="/maps/imagemap1.map">
    + + <img ismap src="/images/imagemap1.gif">
    +
    + </a> +
    + + XHTML example + <a href="/maps/imagemap1.map">
    + + <img ismap="ismap" src="/images/imagemap1.gif" />
    +
    + </a> +
    + +
    + + +ImapMenu +Action if no coordinates are given when calling +an imagemap +ImapMenu none|formatted|semiformatted|unformatted +server configvirtual host +directory.htaccess +Indexes + + +

    The ImapMenu directive determines the + action taken if an imagemap file is called without valid + coordinates.

    + +
    +
    none
    +
    If ImapMenu is none, no menu is generated, + and the default action is performed.
    + +
    formatted
    +
    A formatted menu is the simplest menu. + Comments in the imagemap file are ignored. A level one header + is printed, then an hrule, then the links each on a separate + line. The menu has a consistent, plain look close to that of + a directory listing.
    + +
    semiformatted
    +
    In the semiformatted menu, comments are + printed where they occur in the imagemap file. Blank lines + are turned into HTML breaks. No header or hrule is printed, + but otherwise the menu is the same as a + formatted menu.
    + +
    unformatted
    +
    Comments are printed, blank lines are ignored. Nothing is + printed that does not appear in the imagemap file. All breaks + and headers must be included as comments in the imagemap + file. This gives you the most flexibility over the appearance + of your menus, but requires you to treat your map files as + HTML instead of plaintext.
    +
    +
    +
    + + +ImapDefault +Default action when an imagemap is called with coordinates +that are not explicitly mapped +ImapDefault error|nocontent|map|referer|URL +ImapDefault nocontent +server configvirtual host +directory.htaccess +Indexes + + +

    The ImapDefault directive sets the default + default used in the imagemap files. Its value is + overridden by a default directive within the + imagemap file. If not present, the default action + is nocontent, which means that a 204 No + Content is sent to the client. In this case, the client + should continue to display the original page.

    +
    +
    + + +ImapBase +Default base for imagemap files +ImapBase map|referer|URL +ImapBase http://servername/ +server configvirtual host +directory.htaccess +Indexes + + +

    The ImapBase directive sets the default + base used in the imagemap files. Its value is + overridden by a base directive within the imagemap + file. If not present, the base defaults to + http://servername/.

    +
    +UseCanonicalName +
    + +
    diff --git a/trunk/docs/manual/mod/mod_imagemap.xml.ko b/trunk/docs/manual/mod/mod_imagemap.xml.ko new file mode 100644 index 0000000000..d9191ccefb --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.xml.ko @@ -0,0 +1,341 @@ + + + + + + + + + +mod_imap +¼­¹öÃø À̹ÌÁö¸Ê(imagemap) ó¸® +Base +mod_imap.c +imap_module + + +

    ÀÌ ¸ðµâÀº imagemap CGI ÇÁ·Î±×·¥À» ´ë½ÅÇÏ¿© + .map ÆÄÀÏÀ» ó¸®ÇÑ´Ù. ÀÌ ¸ðµâÀº (AddHandler³ª SetHandler¸¦ »ç¿ëÇÏ¿©) + imap-file Çڵ鷯¸¦ »ç¿ëÇϵµ·Ï ¼³Á¤ÇÑ µð·ºÅ丮³ª + ¹®¼­¸¦ ó¸®ÇÑ´Ù.

    + +

    ¾Æ·¡ Áö½Ã¾î´Â .mapÀ¸·Î ³¡³ª´Â ÆÄÀÏÀ» À̹ÌÁö¸Ê + ÆÄÀÏ·Î ¼³Á¤ÇÑ´Ù.

    + + AddHandler imap-file map + +

    ¾ÆÁ÷µµ ¾Æ·¡¿Í °°Àº ¼³Á¤À» Áö¿øÇÑ´Ù.

    + + AddType application/x-httpd-imap map + +

    ±×·¯³ª ¿ì¸®´Â Á¡Â÷ "¼­¹ö¿¡°Ô Ưº°ÇÑ Àǹ̰¡ ÀÖ´Â MIME + type"À» Á¦°ÅÇÏ·Á°í Çϱ⶧¹®¿¡ ÀÌ ¹æ¹ýÀº ¾ø¾îÁú °ÍÀÌ´Ù.

    +
    + +
    »õ·Î¿î ±â´É + +

    À̹ÌÁö¸Ê ¸ðµâ¿¡´Â ÀÌÀü À̹ÌÁö¸Ê ÇÁ·Î±×·¥¿¡´Â ¾ø´Â ¸î°¡Áö + »õ·Î¿î ±â´ÉÀÌ ÀÖ´Ù.

    + +
      +
    • Referer: Á¤º¸¿¡ »ó´ëÀûÀÎ URL ÂüÁ¶.
    • + +
    • »õ·Î¿î base ¸ÊÁö½Ã¾î¸¦ »ç¿ëÇÏ¿© ±âº» + <base> ÁöÁ¤.
    • + +
    • imagemap.conf ÆÄÀÏ ÇÊ¿ä¾øÀ½.
    • + +
    • Á¡(point) ÂüÁ¶.
    • + +
    • À̹ÌÁö¸Ê ¸Þ´º Á¶Á¤ °¡´É.
    • +
    +
    + +
    À̹ÌÁö¸Ê ÆÄÀÏ + +

    À̹ÌÁö¸Ê ÆÄÀÏÀº ¾Æ·¡¿Í °°Àº Çü½ÄÀ¸·Î ÀÛ¼ºÇÑ´Ù.

    + + + directive value [x,y ...]
    + directive value "Menu text" [x,y + ...]
    + directive value x,y ... "Menu text" +
    + +

    directive´Â base, default, + poly, circle, rect, + point Áß Çϳª´Ù. value¿¡´Â Àý´ë URLÀ̳ª »ó´ë + URL ȤÀº ¾Æ·¡¿¡¼­ ¿­°ÅÇÒ Æ¯¼ö°ªÀ» »ç¿ëÇÑ´Ù. ÁÂÇ¥´Â °ø¹éÀ¸·Î + ±¸ºÐÇÑ x,y ½ÖÀÌ´Ù. µû¿ÈÇ¥·Î + ¹­Àº ¹®±¸´Â À̹ÌÁö¸Ê ¸Þ´º¸¦ ¸¸µé¶§ ¸µÅ© Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù. + '#'·Î ½ÃÀÛÇÏ´Â ÁÙÀº ÁÖ¼®ÀÌ´Ù.

    + +
    À̹ÌÁö¸Ê ÆÄÀÏ Áö½Ã¾î +

    À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ 6°¡Áö Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î´Â + Ưº°ÇÑ ¼ø¼­¾øÀÌ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, À̹ÌÁö¸Ê ÆÄÀÏ¿¡ ³ª¿Â + ¼ø¼­´ë·Î ó¸®ÇÑ´Ù.

    + +
    +
    base Áö½Ã¾î
    + +

    <base href="value"> + ±â´ÉÀ» ÇÑ´Ù. ¸ÊÆÄÀÏ¿¡¼­ ³ª¿À´Â URLÀº Àý´ë URLÀÌ ¾Æ´Ï¶ó¸é + ÀÌ °ª¿¡ »ó´ë URL·Î Ãë±ÞÇÑ´Ù. base Áö½Ã¾î´Â + .htaccess ÆÄÀÏÀ̳ª ¼­¹ö¼³Á¤ÆÄÀÏ¿¡¼­ ¼³Á¤ÇÑ + ImapBase °ªÀ» + ¹«½ÃÇÑ´Ù. ImapBase ¼³Á¤Áö½Ã¾î°¡ + ¾ø´Ù¸é ±âº» base °ªÀº + http://server_name/ÀÌ´Ù.

    +

    base_uri´Â base¿Í °°´Ù. URL¿¡¼­ + ¸¶Áö¸· ½½·¡½¬¸¦ ÀØÁö¸¶¶ó.

    + +
    default Áö½Ã¾î
    + +
    ÇØ´ç ÁÂÇ¥°¡ poly, circle, + rect Áö½Ã¾î¿¡ ÇØ´çÇÏÁö ¾Ê°í point + Áö½Ã¾î¸¦ »ç¿ëÇÏÁö ¾ÊÀº °æ¿ì ÇൿÀ» ÁöÁ¤ÇÑ´Ù. ImapDefault ¼³Á¤ÀÌ ¾ø´Ù¸é + ±âº»°ªÀº 204 No Content »óÅÂÄڵ带 ¹ÝȯÇÏ´Â + nocontentÀÌ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â µ¿ÀÏÇÑ + ÆäÀÌÁö¸¦ º¸¿©Áà¾ß ÇÑ´Ù.
    + +
    poly Áö½Ã¾î
    + +
    Á¡À» ¼¼°³¿¡¼­ ¹é°³±îÁö ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ ÀÌ + Á¡µé·Î ÀÌ·ç¾îÁø ´Ù°¢Çü ¾ÈÀÇ ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    circle
    + +
    ¿øÀÇ Á߽ɰú ¿øÀ§ÀÇ ÇÑ Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. »ç¿ëÀÚ°¡ + ¿ø ¾ÈÀÇ ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    rect Áö½Ã¾î
    + +
    »ç°¢ÇüÀÇ µÎ ¸ð¼­¸® Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. »ç°¢Çü ¾ÈÀÇ + ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì¿¡ »ç¿ëÇÑ´Ù.
    + +
    point Áö½Ã¾î
    + +
    ÇÑ Á¡ÀÇ ÁÂÇ¥¸¦ ¹Þ´Â´Ù. ´Ù¸¥ Áö½Ã¾îµéÀ» ¸¸Á·ÇÏÁö ¾ÊÀº + °æ¿ì »ç¿ëÀÚ°¡ ¼±ÅÃÇÑ ÁÂÇ¥¿¡ °¡Àå °¡±î¿î point Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù. point Áö½Ã¾î¸¦ »ç¿ëÇÏ°í À¯È¿ÇÑ + ÁÂÇ¥¸¦ ¼±ÅÃÇÑ °æ¿ì default´Â Àý´ë·Î »ç¿ëµÇÁö + ¾Ê´Â´Ù.
    +
    +
    + +
    Áö½Ã¾î¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â °ªµé + +

    Áö½Ã¾î¿¡ ¾Æ·¡ value¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    URL
    + +

    »ó´ë URLÀ̳ª Àý´ë URLÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. »ó´ë URL¿¡ + '..'À» »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, base °ªÀ» ±âÁØÀ¸·Î + ã´Â´Ù.

    +

    base¸¦ ¼³Á¤ÇÒ¶§´Â ÇöÀç base°ªÀº ¹«½ÃÇÑ´Ù. + ±×·¯³ª, base mailto: ¹®Àº »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    map
    + +
    À̹ÌÁö¸Ê ÆÄÀÏ ÀÚü URL°ú °°´Ù. ÁÂÇ¥°¡ ¾ø°í ImapMenu°¡ noneÀÌ + ¾Æ´Ï¶ó¸é ¸Þ´º¸¦ ¸¸µç´Ù.
    + +
    menu
    +
    map°ú °°´Ù.
    + +
    referer
    + +
    ÂüÁ¶(¸µÅ©¸¦ µû¶ó¿À±â Àü) ¹®¼­ URL°ú °°´Ù. + Referer: Çì´õ°¡ ¾ø´Ù¸é ±âº»°ªÀº + http://servername/ÀÌ´Ù.
    + +
    nocontent
    + +
    Ŭ¶óÀ̾ðÆ®¿¡°Ô µ¿ÀÏÇÑ ÆäÀÌÁö¸¦ ±×´ë·Î º¸¿©ÁÖ¶ó´Â + 204 No Content »óÅÂÄڵ带 º¸³½´Ù. + base¸¦ Á¦¿ÜÇÑ ¸ðµç Áö½Ã¾î¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    error
    + +
    ½ÇÆи¦ ³ªÅ¸³»´Â 500 Server Error¸¦ º¸³½´Ù. + base¸¦ Á¦¿ÜÇÑ ¸ðµç Áö½Ã¾î¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, + default ¿Ü¿¡´Â »ç¿ëÇÒ ÀÏÀÌ ¾ø´Ù.
    +
    +
    + +
    ÁÂÇ¥ + +
    +
    0,0 200,200
    + +
    ÁÂÇ¥´Â ½°Ç¥·Î ±¸ºÐÇÑ x¿Í y °ªÀÌ´Ù. + ÁÂÇ¥µéÀº ¼­·Î °ø¹éÀ¸·Î ±¸ºÐÇÑ´Ù. À̹ÌÁö¸ÊÀ» ´Ù·ç´Â ¹æ½Ä»ó + LynxÀÇ ÆíÀǸ¦ À§ÇØ »ç¿ëÀÚ°¡ 0,0 ÁÂÇ¥¸¦ ¼±ÅÃÇÏ¿´´Ù¸é + ÁÂÇ¥¸¦ ¼±ÅÃÇÏÁö ¾ÊÀº °Íó·³ µ¿ÀÛÇÑ´Ù.
    +
    + +
    + +
    µû¿ÈÇ¥·Î ¹­Àº ¹®±¸ + +
    +
    "Menu Text"
    + +

    value µÚ³ª ÁÂÇ¥ µÚ¿¡ ½Öµû¿ÈÇ¥·Î ¹­Àº ¹®±¸¸¦ ÀûÀ» + ¼öµµ ÀÖ´Ù. ÀÌ ¹®ÀÚ¿­Àº ¸Þ´º¸¦ ¸¸µé¶§ ¸µÅ© Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù.

    + + + <a href="http://foo.com/">Menu text</a> + + +

    µû¿ÈÇ¥·Î ¹­Àº ¹®±¸°¡ ¾ø´Ù¸é ´ÙÀ½°ú °°ÀÌ ¸µÅ©¸¦ ¸µÅ© + Á¦¸ñÀ¸·Î »ç¿ëÇÑ´Ù.

    + + + <a href="http://foo.com/">http://foo.com</a> + + +

    ¹®±¸¿¡ ½Öµû¿ÈÇ¥¸¦ ¾²·Á¸é &quot;¿Í + °°ÀÌ Àû¾î¾ß ÇÑ´Ù.

    +
    + +
    +
    + +
    ¸ÊÆÄÀÏ ¿¹Á¦ + + + #'formatted'³ª 'semiformatted' ¸Þ´º´Â ÁÖ¼®À» Ãâ·ÂÇÑ´Ù.
    + #±×¸®°í ÁÖ¼®¿¡ html ű׸¦ ¾µ ¼ö ÀÖ´Ù. <hr>
    + base referer
    + poly map "¸Þ´º¸¦ º¸¿©ÁÖ¼¼¿ä." 0,0 0,10 10,10 10,0
    + rect .. 0,0 77,27 "ÂüÁ¶ ¹®¼­°¡ ÀÖ´Â µð·ºÅ丮"
    + circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27
    + rect another_file "ÂüÁ¶ ¹®¼­¿Í °°Àº µð·ºÅ丮¿¡ ÀÖ´Â" 306,0 419,27
    + point http://www.zyzzyva.com/ 100,100
    + point http://www.tripod.com/ 200,200
    + rect mailto:nate@tripod.com 100,150 200,0 "¹ö±×?"
    +
    + +
    + +
    ¸ÊÆÄÀÏ »ç¿ëÇϱâ + + HTML ¿¡Á¦ + <a href="/maps/imagemap1.map">
    + + <img ismap src="/images/imagemap1.gif">
    +
    + </a> +
    + + XHTML ¿¹Á¦ + <a href="/maps/imagemap1.map">
    + + <img ismap="ismap" src="/images/imagemap1.gif" />
    +
    + </a> +
    + +
    + + +ImapMenu +ÁÂÇ¥¾øÀÌ À̹ÌÁö¸Ê ¿äû½Ã ÃëÇÒ Çൿ +ImapMenu none|formatted|semiformatted|unformatted +server configvirtual host +directory.htaccess +Indexes + + +

    ImapMenu Áö½Ã¾î´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + À¯È¿ÇÑ ÁÂÇ¥¸¦ ÁÖÁö ¾ÊÀº °æ¿ì ÃëÇÒ ÇൿÀ» °áÁ¤ÇÑ´Ù.

    + +
    +
    none
    +
    ImapMenu°¡ noneÀ̸é, ¸Þ´º¸¦ ¸¸µéÁö¾Ê°í + default ÇൿÀ» ÃëÇÑ´Ù.
    + +
    formatted
    +
    formatted ¸Þ´º´Â °¡Àå °£´ÜÇÑ ¸Þ´º´Ù. + À̹ÌÁö¸Ê ÆÄÀÏÀÇ ÁÖ¼®Àº ¹«½ÃÇÑ´Ù. °¡Àå Å« Ç¥Á¦¿Í ¼öÁ÷¼±À» + Ãâ·ÂÇÏ°í, ¸µÅ©¸¦ ÇÑÁÙ¾¿ Ãâ·ÂÇÑ´Ù. ¸Þ´º´Â ÀÏ°üµÇ°í ÆòÀÌÇϸç, + µð·ºÅ丮 ¸ñ·Ï°ú Èí»çÇÏ´Ù.
    + +
    semiformatted
    +
    semiformatted ¸Þ´º´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + ³ª¿À´Â ÁÖ¼®À» Ãâ·ÂÇÑ´Ù. ºóÁÙÀº HTML Çà¹Ù²ÞÀ¸·Î º¯È¯ÇÑ´Ù. + Ç¥Á¦³ª ¼öÁ÷¼±À» ±×¸®Áö ¾ÊÁö¸¸, ³ª¸ÓÁö´Â formatted + ¸Þ´º¿Í °°´Ù.
    + +
    unformatted
    +
    ÁÖ¼®Àº Ãâ·ÂÇÏ°í, ºóÁÙÀº ¹«½ÃÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏ¿¡ + ÀÖ´Â ³»¿ë¸¸ Ãâ·ÂÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏÀÇ ÁÖ¼®¿¡ ÇÊ¿äÇÑ ¸ðµç + Çà¹Ù²Þ°ú Ç¥Á¦¸¦ Àû¾î¾ß ÇÑ´Ù. ¸Þ´ºÀÇ ¿Ü°üÀ» °¡Àå ÀÚÀ¯ÀÚÁ¦·Î + ²Ù¹Ð ¼ö ÀÖÁö¸¸, À̹ÌÁö¸Ê ÆÄÀÏÀ» »ç½Ç»ó ÀÏ¹Ý ¹®ÀÚÆÄÀÏÀÌ + ¾Æ´Ñ HTML·Î ºÁ¾ß ÇÑ´Ù.
    +
    +
    +
    + + +ImapDefault +À̹ÌÁö¸Ê¿¡ ¾î´À ¿µ¿ª¿¡µµ ÇØ´çÇÏÁö ¾Ê´Â ÁÂÇ¥¸¦ ÁØ +°æ¿ì ±âº» Çൿ +ImapDefault error|nocontent|map|referer|URL +ImapDefault nocontent +server configvirtual host +directory.htaccess +Indexes + + +

    ImapDefault Áö½Ã¾î´Â À̹ÌÁö¸Ê + ÆÄÀÏ¿¡¼­ »ç¿ëÇÒ default ±âº»°ªÀ» ¼³Á¤ÇÑ´Ù. + À̹ÌÁö¸Ê ÆÄÀÏ ¾È¿¡¼­ default Áö½Ã¾î¸¦ »ç¿ëÇϸé + ¿©±â¼­ ¼³Á¤ÇÑ °ªÀº ¹«½ÃÇÑ´Ù. µÑ ¸ðµÎ ¾ø´Ù¸é, default + ÇൿÀº Ŭ¶óÀ̾ðÆ®¿¡°Ô 204 No Content¸¦ º¸³»´Â + nocontentÀÌ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®´Â ¿ø·¡ ÆäÀÌÁö¸¦ + ±×´ë·Î º¸¿©Áà¾ß ÇÑ´Ù.

    +
    +
    + + +ImapBase +À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ base ±âº»°ª +ImapBase map|referer|URL +ImapBase http://servername/ +server configvirtual host +directory.htaccess +Indexes + + +

    ImapBase Áö½Ã¾î´Â À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ + »ç¿ëÇÒ base ±âº»°ªÀ» ¼³Á¤ÇÑ´Ù. À̹ÌÁö¸Ê ÆÄÀÏ + ¾È¿¡¼­ base Áö½Ã¾î¸¦ »ç¿ëÇÏ¸é ¿©±â¼­ ¼³Á¤ÇÑ + °ªÀº ¹«½ÃÇÑ´Ù. µÑ ¸ðµÎ ¾ø´Ù¸é, base ±âº»°ªÀº + http://servername/ÀÌ´Ù.

    +
    +UseCanonicalName +
    + +
    diff --git a/trunk/docs/manual/mod/mod_imagemap.xml.meta b/trunk/docs/manual/mod/mod_imagemap.xml.meta new file mode 100644 index 0000000000..77568ad9dd --- /dev/null +++ b/trunk/docs/manual/mod/mod_imagemap.xml.meta @@ -0,0 +1,12 @@ + + + + mod_imagemap + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_include.html b/trunk/docs/manual/mod/mod_include.html new file mode 100644 index 0000000000..b45a07fc56 --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.html @@ -0,0 +1,7 @@ +URI: mod_include.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_include.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_include.html.en b/trunk/docs/manual/mod/mod_include.html.en new file mode 100644 index 0000000000..b87074d1ee --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.html.en @@ -0,0 +1,806 @@ + + + +mod_include - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_include

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    Description:Server-parsed html documents (Server Side Includes)
    Status:Base
    Module Identifier:include_module
    Source File:mod_include.c
    Compatibility:Implemented as an output filter since Apache +2.0
    +

    Summary

    + +

    This module provides a filter which will process files + before they are sent to the client. The processing is + controlled by specially formatted SGML comments, referred to as + elements. These elements allow conditional text, the + inclusion of other files or programs, as well as the setting and + printing of environment variables.

    +
    + +
    top
    +
    +

    Enabling Server-Side Includes

    + + +

    Server Side Includes are implemented by the + INCLUDES filter. If + documents containing server-side include directives are given + the extension .shtml, the following directives will make Apache + parse them and assign the resulting document the mime type of + text/html:

    + +

    + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +

    + +

    The following directive must be given for the directories + containing the shtml files (typically in a + <Directory> section, + but this directive is also valid in .htaccess files if + AllowOverride Options + is set):

    + +

    + Options +Includes +

    + +

    For backwards compatibility, the server-parsed + handler also activates the + INCLUDES filter. As well, Apache will activate the INCLUDES + filter for any document with mime type + text/x-server-parsed-html or + text/x-server-parsed-html3 (and the resulting + output will have the mime type text/html).

    + +

    For more information, see our Tutorial on Server Side Includes.

    +
    top
    +
    +

    PATH_INFO with Server Side Includes

    + + +

    Files processed for server-side includes no longer accept + requests with PATH_INFO (trailing pathname information) + by default. You can use the AcceptPathInfo directive to + configure the server to accept requests with PATH_INFO.

    +
    top
    +
    +

    Basic Elements

    +

    The document is parsed as an HTML document, with special + commands embedded as SGML comments. A command has the syntax:

    + +

    + <!--#element attribute=value + attribute=value ... --> +

    + +

    The value will often be enclosed in double quotes, but single + quotes (') and backticks (`) are also + possible. Many commands only allow a single attribute-value pair. + Note that the comment terminator (-->) should be + preceded by whitespace to ensure that it isn't considered part of + an SSI token. Note that the leading <!--# is one + token and may not contain any whitespaces.

    + +

    The allowed elements are listed in the following table:

    + + + + + + + + + + + + + + + + + + + +
    ElementDescription
    configconfigure output formats
    echoprint variables
    execexecute external programs
    fsizeprint size of a file
    flastmodprint last modification time of a file
    includeinclude a file
    printenvprint all available variables
    setset a value of a variable
    + +

    SSI elements may be defined by modules other than + mod_include. In fact, the exec element is provided by + mod_cgi, and will only be available if this + module is loaded.

    + +

    The config Element

    +

    This command controls various aspects of the parsing. The + valid attributes are:

    + +
    +
    echomsg (Apache 2.1 and later)
    +
    The value is a message that is sent back to the + client if the echo element + attempts to echo an undefined variable. This overrides any SSIUndefinedEcho directives.
    + +
    errmsg
    +
    The value is a message that is sent back to the + client if an error occurs while parsing the + document. This overrides any SSIErrorMsg directives.
    + +
    sizefmt
    +
    The value sets the format to be used which displaying + the size of a file. Valid values are bytes + for a count in bytes, or abbrev for a count + in Kb or Mb as appropriate, for example a size of 1024 bytes + will be printed as "1K".
    + +
    timefmt
    +
    The value is a string to be used by the + strftime(3) library routine when printing + dates.
    +
    + + +

    The echo Element

    +

    This command prints one of the include + variables, defined below. If the variable is unset, the result is + determined by the SSIUndefinedEcho directive. Any dates printed are + subject to the currently configured timefmt.

    + +

    Attributes:

    + +
    +
    var
    +
    The value is the name of the variable to print.
    + +
    encoding
    +

    Specifies how Apache should encode special characters + contained in the variable before outputting them. If set + to none, no encoding will be done. If set to + url, then URL encoding (also known as %-encoding; + this is appropriate for use within URLs in links, etc.) will be + performed. At the start of an echo element, + the default is set to entity, resulting in entity + encoding (which is appropriate in the context of a block-level + HTML element, e.g. a paragraph of text). This can be + changed by adding an encoding attribute, which will + remain in effect until the next encoding attribute + is encountered or the element ends, whichever comes first.

    + +

    The encoding attribute must precede the + corresponding var attribute to be effective, and + only special characters as defined in the ISO-8859-1 character + encoding will be encoded. This encoding process may not have the + desired result if a different character encoding is in use.

    + +
    + In order to avoid cross-site scripting issues, you should + always encode user supplied data. +
    +
    +
    + + +

    The exec Element

    +

    The exec command executes a given shell command or + CGI script. It requires mod_cgi to be present + in the server. If Options + IncludesNOEXEC is set, this command is completely + disabled. The valid attributes are:

    + +
    +
    cgi
    +

    The value specifies a (%-encoded) URL-path to + the CGI script. If the path does not begin with a slash (/), + then it is taken to be relative to the current + document. The document referenced by this path is + invoked as a CGI script, even if the server would not + normally recognize it as such. However, the directory + containing the script must be enabled for CGI scripts + (with ScriptAlias + or Options + ExecCGI).

    + +

    The CGI script is given the PATH_INFO and query + string (QUERY_STRING) of the original request from the + client; these cannot be specified in the URL path. The + include variables will be available to the script in addition to + the standard CGI environment.

    + +

    Example

    + <!--#exec cgi="/cgi-bin/example.cgi" --> +

    + +

    If the script returns a Location: header instead of + output, then this will be translated into an HTML anchor.

    + +

    The include virtual + element should be used in preference to exec cgi. In + particular, if you need to pass additional arguments to a CGI program, + using the query string, this cannot be done with exec + cgi, but can be done with include virtual, as + shown here:

    + +

    + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> +

    +
    + +
    cmd
    +

    The server will execute the given string using + /bin/sh. The include variables are available to the command, in addition + to the usual set of CGI variables.

    + +

    The use of #include virtual is almost always prefered to using + either #exec cgi or #exec cmd. The former + (#include virtual) uses the standard Apache sub-request + mechanism to include files or scripts. It is much better tested and + maintained.

    + +

    In addition, on some platforms, like Win32, and on unix when + using suexec, you cannot pass arguments + to a command in an exec directive, or otherwise include + spaces in the command. Thus, while the following will work under a + non-suexec configuration on unix, it will not produce the desired + result under Win32, or when running suexec:

    + +

    + <!--#exec cmd="perl /path/to/perlscript arg1 arg2" --> +

    +
    +
    + + +

    The fsize Element

    +

    This command prints the size of the specified file, subject + to the sizefmt format specification. Attributes:

    + +
    +
    file
    +
    The value is a path relative to the directory + containing the current document being parsed.
    + +
    virtual
    +
    The value is a (%-encoded) URL-path. If it does not begin with + a slash (/) then it is taken to be relative to the current document. + Note, that this does not print the size of any CGI output, + but the size of the CGI script itself.
    +
    + + +

    The flastmod Element

    +

    This command prints the last modification date of the + specified file, subject to the timefmt format + specification. The attributes are the same as for the + fsize command.

    + + +

    The include Element

    +

    This command inserts the text of another document or file + into the parsed file. Any included file is subject to the + usual access control. If the directory containing the + parsed file has Options + IncludesNOEXEC set, then only documents with + a text MIME type (text/plain, text/html + etc.) will be included. Otherwise CGI scripts are invoked as normal + using the complete URL given in the command, including any query + string.

    + +

    An attribute defines the location of the document; the + inclusion is done for each attribute given to the include + command. The valid attributes are:

    + +
    +
    file
    +
    The value is a path relative to the directory + containing the current document being parsed. It cannot + contain ../, nor can it be an absolute path. + Therefore, you cannot include files that are outside of the + document root, or above the current document in the directory + structure. The virtual attribute should always be + used in preference to this one.
    + +
    virtual
    +

    The value is a (%-encoded) URL-path. The URL cannot contain a + scheme or hostname, only a path and an optional query string. If it + does not begin with a slash (/) then it is taken to be relative to the + current document.

    + +

    A URL is constructed from the attribute, and the output the + server would return if the URL were accessed by the client is + included in the parsed output. Thus included files can be nested.

    + +

    If the specified URL is a CGI program, the program will be + executed and its output inserted in place of the directive in the + parsed file. You may include a query string in a CGI url:

    + +

    + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> +

    + +

    include virtual should be used in preference + to exec cgi to include the output of CGI programs + into an HTML document.

    +
    +
    + + +

    The printenv Element

    +

    This prints out a listing of all existing variables and + their values. Special characters are entity encoded (see the echo element for details) + before being output. There are no attributes.

    + +

    Example

    + <!--#printenv --> +

    + + +

    The set Element

    +

    This sets the value of a variable. Attributes:

    + +
    +
    var
    +
    The name of the variable to set.
    + +
    value
    +
    The value to give a variable.
    +
    + +

    Example

    + <!--#set var="category" value="help" --> +

    + +
    top
    +
    +

    Include Variables

    + + +

    In addition to the variables in the standard CGI environment, + these are available for the echo command, for + if and elif, and to any program + invoked by the document.

    + +
    +
    DATE_GMT
    +
    The current date in Greenwich Mean Time.
    + +
    DATE_LOCAL
    +
    The current date in the local time zone.
    + +
    DOCUMENT_NAME
    +
    The filename (excluding directories) of the document + requested by the user.
    + +
    DOCUMENT_URI
    +
    The (%-decoded) URL path of the document requested by the + user. Note that in the case of nested include files, this is + not the URL for the current document.
    + +
    LAST_MODIFIED
    +
    The last modification date of the document requested by + the user.
    + +
    QUERY_STRING_UNESCAPED
    +
    If a query string is present, this variable contains the + (%-decoded) query string, which is escaped for shell + usage (special characters like & etc. are + preceded by backslashes).
    +
    +
    top
    +
    +

    Variable Substitution

    + +

    Variable substitution is done within quoted strings in most + cases where they may reasonably occur as an argument to an SSI + directive. This includes the config, + exec, flastmod, fsize, + include, echo, and set + directives, as well as the arguments to conditional operators. + You can insert a literal dollar sign into the string using backslash + quoting:

    + +

    + <!--#if expr="$a = \$test" --> +

    + +

    If a variable reference needs to be substituted in the + middle of a character sequence that might otherwise be + considered a valid identifier in its own right, it can be + disambiguated by enclosing the reference in braces, + a la shell substitution:

    + +

    + <!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" --> +

    + +

    This will result in the Zed variable being set + to "X_Y" if REMOTE_HOST is + "X" and REQUEST_METHOD is + "Y".

    + +

    The below example will print "in foo" if the + DOCUMENT_URI is /foo/file.html, "in bar" + if it is /bar/file.html and "in neither" otherwise:

    + +

    + <!--#if expr='"$DOCUMENT_URI" = "/foo/file.html"' -->
    + + in foo
    +
    + <!--#elif expr='"$DOCUMENT_URI" = "/bar/file.html"' -->
    + + in bar
    +
    + <!--#else -->
    + + in neither
    +
    + <!--#endif --> +

    +
    top
    +
    +

    Flow Control Elements

    + + +

    The basic flow control elements are:

    + +

    + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +

    + +

    The if element works like an if statement in a + programming language. The test condition is evaluated and if + the result is true, then the text until the next elif, + else or endif element is included in the + output stream.

    + +

    The elif or else statements are be used + to put text into the output stream if the original + test_condition was false. These elements are optional.

    + +

    The endif element ends the if element + and is required.

    + +

    test_condition is one of the following:

    + +
    +
    string
    +
    true if string is not empty
    + +
    string1 = string2
    + string1 == string2
    + string1 != string2
    + +

    Compare string1 with string2. If + string2 has the form /string2/ + then it is treated as a regular expression. Regular expressions are + implemented by the PCRE engine and + have the same syntax as those in perl + 5. Note that == is just an alias for = + and behaves exactly the same way.

    + +

    If you are matching positive (= or ==), you + can capture grouped parts of the regular expression. The captured parts + are stored in the special variables $1 .. + $9.

    + +

    Example

    + <!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
    + + <!--#set var="session" value="$1" -->
    +
    + <!--#endif --> +

    +
    + +
    string1 < string2
    + string1 <= string2
    + string1 > string2
    + string1 >= string2
    + +
    Compare string1 with string2. Note, that + strings are compared literally (using + strcmp(3)). Therefore the string "100" is less than + "20".
    + +
    ( test_condition )
    +
    true if test_condition is true
    + +
    ! test_condition
    +
    true if test_condition is false
    + +
    test_condition1 && + test_condition2
    +
    true if both test_condition1 and + test_condition2 are true
    + +
    test_condition1 || + test_condition2
    +
    true if either test_condition1 or + test_condition2 is true
    +
    + +

    "=" and "!=" bind more tightly than + "&&" and "||". "!" binds + most tightly. Thus, the following are equivalent:

    + +

    + <!--#if expr="$a = test1 && $b = test2" -->
    + <!--#if expr="($a = test1) && ($b = test2)" --> +

    + +

    The boolean operators && and || + share the same priority. So if you want to bind such an operator more + tightly, you should use parentheses.

    + +

    Anything that's not recognized as a variable or an operator + is treated as a string. Strings can also be quoted: + 'string'. Unquoted strings can't contain whitespace + (blanks and tabs) because it is used to separate tokens such as + variables. If multiple strings are found in a row, they are + concatenated using blanks. So,

    + +

    string1    string2 results in string1 string2
    +
    + and
    +
    + 'string1    string2' results in string1    string2.

    + +

    Optimization of Boolean Expressions

    +

    If the expressions become more complex and slow down processing + significantly, you can try to optimize them according to the + evaluation rules:

    +
      +
    • Expressions are evaluated from left to right
    • +
    • Binary boolean operators (&& and ||) + are short circuited wherever possible. In conclusion with the rule + above that means, mod_include evaluates at first + the left expression. If the left result is sufficient to determine + the end result, processing stops here. Otherwise it evaluates the + right side and computes the end result from both left and right + results.
    • +
    • Short circuit evaluation is turned off as long as there are regular + expressions to deal with. These must be evaluated to fill in the + backreference variables ($1 .. $9).
    • +
    +

    If you want to look how a particular expression is handled, you can + recompile mod_include using the + -DDEBUG_INCLUDE compiler option. This inserts for every + parsed expression tokenizer information, the parse tree and how it is + evaluated into the output sent to the client.

    +
    +
    +
    top
    +

    SSIEndTag Directive

    + + + + + + + + +
    Description:String that ends an include element
    Syntax:SSIEndTag tag
    Default:SSIEndTag "-->"
    Context:server config, virtual host
    Status:Base
    Module:mod_include
    Compatibility:Available in version 2.0.30 and later.
    +

    This directive changes the string that mod_include + looks for to mark the end of an include element.

    + +

    Example

    + SSIEndTag "%>" +

    + + +

    See also

    + +
    +
    top
    +

    SSIErrorMsg Directive

    + + + + + + + + + +
    Description:Error message displayed when there is an SSI +error
    Syntax:SSIErrorMsg message
    Default:SSIErrorMsg "[an error occurred while processing this +directive]"
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Base
    Module:mod_include
    Compatibility:Available in version 2.0.30 and later.
    +

    The SSIErrorMsg directive changes the error + message displayed when mod_include encounters an + error. For production servers you may consider changing the default + error message to "<!-- Error -->" so that + the message is not presented to the user.

    + +

    This directive has the same effect as the <!--#config + errmsg=message --> element.

    + +

    Example

    + SSIErrorMsg "<!-- Error -->" +

    + +
    +
    top
    +

    SSIStartTag Directive

    + + + + + + + + +
    Description:String that starts an include element
    Syntax:SSIStartTag tag
    Default:SSIStartTag "<!--#"
    Context:server config, virtual host
    Status:Base
    Module:mod_include
    Compatibility:Available in version 2.0.30 and later.
    +

    This directive changes the string that mod_include + looks for to mark an include element to process.

    + +

    You may want to use this option if you have 2 servers parsing the + output of a file each processing different commands (possibly at + different times).

    + +

    Example

    + SSIStartTag "<%"
    + SSIEndTag "%>" +

    + +

    The example given above, which also specifies a matching + SSIEndTag, will + allow you to use SSI directives as shown in the example + below:

    + +

    SSI directives with alternate start and end tags

    + <%printenv %> +

    + +

    See also

    + +
    +
    top
    +

    SSITimeFormat Directive

    + + + + + + + + + +
    Description:Configures the format in which date strings are +displayed
    Syntax:SSITimeFormat formatstring
    Default:SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z"
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Base
    Module:mod_include
    Compatibility:Available in version 2.0.30 and later.
    +

    This directive changes the format in which date strings are displayed + when echoing DATE environment variables. The + formatstring is as in strftime(3) from the + C standard library.

    + +

    This directive has the same effect as the <!--#config + timefmt=formatstring --> element.

    + +

    Example

    + SSITimeFormat "%R, %B %d, %Y" +

    + +

    The above directive would cause times to be displayed in the + format "22:26, June 14, 2002".

    + +
    +
    top
    +

    SSIUndefinedEcho Directive

    + + + + + + + + + +
    Description:String displayed when an unset variable is echoed
    Syntax:SSIUndefinedEcho string
    Default:SSIUndefinedEcho "(none)"
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Base
    Module:mod_include
    Compatibility:Available in version 2.0.34 and later.
    +

    This directive changes the string that mod_include + displays when a variable is not set and "echoed".

    + +

    Example

    + SSIUndefinedEcho "<!-- undef -->" +

    + +
    +
    top
    +

    XBitHack Directive

    + + + + + + + + +
    Description:Parse SSI directives in files with the execute bit +set
    Syntax:XBitHack on|off|full
    Default:XBitHack off
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Base
    Module:mod_include
    +

    The XBitHack directive controls the parsing + of ordinary html documents. This directive only affects files associated + with the MIME type text/html. XBitHack can take on the following values:

    + +
    +
    off
    +
    No special treatment of executable files.
    + +
    on
    +
    Any text/html file that has the user-execute bit + set will be treated as a server-parsed html document.
    + +
    full
    +
    As for on but also test the group-execute bit. + If it is set, then set the Last-modified date of the + returned file to be the last modified time of the file. If + it is not set, then no last-modified date is sent. Setting + this bit allows clients and proxies to cache the result of + the request. + +

    Note

    +

    You would not want to use the full option, unless you assure the + group-execute bit is unset for every SSI script which might #include a CGI or otherwise produces different output on + each hit (or could potentially change on subsequent requests).

    +
    +
    +
    + + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_include.html.ja.euc-jp b/trunk/docs/manual/mod/mod_include.html.ja.euc-jp new file mode 100644 index 0000000000..50dced9953 --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.html.ja.euc-jp @@ -0,0 +1,789 @@ + + + +mod_include - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_include

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬¥Ñ¡¼¥¹¤¹¤ë html ¥É¥­¥å¥á¥ó¥È (Server Side Includes)
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:include_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_include.c
    ¸ß´¹À­:Apache 2.0 ¤«¤é½ÐÎÏ¥Õ¥£¥ë¥¿¤È¤·¤Æ¼ÂÁõ¤µ¤ì¤Þ¤·¤¿¡£
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥Õ¥¡¥¤¥ë¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ëÁ°¤Ë½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤ò + Ä󶡤·¤Þ¤¹¡£½èÍý¤ÎÆâÍƤÏÍ×ÁǤȸƤФì¤ëÆÃÊ̤ʷÁ¼°¤Î SGML ¥³¥á¥ó¥È¤Ë¤è¤ê + À©¸æ¤µ¤ì¤Þ¤¹¡£¤³¤ì¤é¤ÎÍ×ÁǤϾò·ïʬ´ô¤ä¡¢Â¾¤Î¥Õ¥¡¥¤¥ë¤ä + ¥×¥í¥°¥é¥à¤Î½ÐÎϤμè¤ê¹þ¤ß¡¢´Ä¶­ÊÑ¿ô¤ÎÀßÄê¤äɽ¼¨¤ò¹Ô¤Ê¤¦¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    Server-Side Includes ¤òÍ­¸ú¤Ë¤¹¤ë

    + + +

    Server Side Includes ¤Ï INCLUDES + ¥Õ¥£¥ë¥¿ ¤Ë¤è¤ê¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + Server-side include ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò´Þ¤à¥É¥­¥å¥á¥ó¥È¤Î³ÈÄ¥»Ò¤¬ + .shtml ¤Î¾ì¹ç¡¢°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï Apache ¤¬¤½¤ì¤é¤ò + ¥Ñ¡¼¥¹¤·¤Æ¡¢¤½¤Î·ë²Ì¤Ç¤­¤ë¥É¥­¥å¥á¥ó¥È¤Ë text/html ¤Î + MIME ¥¿¥¤¥×¤ò³ä¤êÅö¤Æ¤Þ¤¹:

    + +

    + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +

    + +

    °Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï shtml ¥Õ¥¡¥¤¥ë¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹ (Ä̾ï¤Ï <Directory> ¥»¥¯¥·¥ç¥ó¤Ç»ØÄꤷ¤Þ¤¹¤¬¡¢ + AllowOverride Options + ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢.htaccess ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤â¤Ç¤­¤Þ¤¹):

    + +

    + Options +Includes +

    + +

    ¸ß´¹À­¤òÊݤĤ¿¤á¤Ë¡¢server-parsed + ¥Ï¥ó¥É¥é ¤â INCLUDES ¥Õ¥£¥ë¥¿¤ò + Í­¸ú¤Ë¤·¤Þ¤¹¡£MIME ¥¿¥¤¥× text/x-server-parsed-html ¤ä + text/x-server-parsed-html3 ¤Î¥É¥­¥å¥á¥ó¥È¤ËÂФ·¤Æ¤â + Apache ¤Ï INCLUDES ¥Õ¥£¥ë¥¿¤òÍ­¸ú¤Ë¤·¤Þ¤¹ (½ÐÎϤµ¤ì¤ë¤â¤Î¤Ï + MIME ¥¿¥¤¥× text/html ¤Ë¤Ê¤ê¤Þ¤¹)¡£

    + +

    ¾Ü¤·¤¤¾ðÊó¤Ï Tutorial on Server Side Includes.

    +
    top
    +
    +

    ¥µ¡¼¥Ð¥µ¥¤¥É¥¤¥ó¥¯¥ë¡¼¥É (SSI) ¤Ç¤Î PATH_INFO

    + + +

    SSI ¤Ç½èÍý¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï PATH_INFO + (¸å³¤Î¥Ñ¥¹Ì¾¾ðÊó) + ÉÕ¤­¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±Æþ¤ì¤Ê¤¯¤Ê¤ê¤Þ¤·¤¿¡£AcceptPathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + PATH_INFO ÉÕ¤­¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±Æþ¤ì¤ë¤è¤¦¤Ë¥µ¡¼¥Ð¤ò + ÀßÄê¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ´ðËÜÍ×ÁÇ

    +

    ¥É¥­¥å¥á¥ó¥È¤Ï¡¢SGML ¤Î¥³¥á¥ó¥È¤È¤·¤ÆÆÃÊ̤ʥ³¥Þ¥ó¥É¤¬Ëä¤á¹þ¤Þ¤ì¤¿ + HTML ¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ¥Ñ¡¼¥¹¤µ¤ì¤Þ¤¹¡£¥³¥Þ¥ó¥É¤Î¹½Ê¸¤Ï¼¡¤Î¤è¤¦¤Ë + ¤Ê¤Ã¤Æ¤¤¤Þ¤¹:

    + +

    + <!--#element attribute=value + attribute=value ... --> +

    + +

    ÃÍ (ÌõÃí: value) ¤ÏÆó½Å°úÍÑÉä¤Ç°Ï¤à¤Î¤¬°ìÈÌŪ¤Ç¤¹¤¬¡¢ + ¥·¥ó¥°¥ë¥¯¥ª¡¼¥È (') ¤È¥Ð¥Ã¥¯¥¯¥ª¡¼¥È (`) ¤â»ÈÍѤǤ­¤Þ¤¹¡£ + ¿¤¯¤Î¥³¥Þ¥ó¥É¤Ï°À­-ÃÍ (ÌõÃí: attribute-value) ¤ÎÁȤò°ì¤Ä¤À¤±»ØÄê¤Ç¤­¤Þ¤¹¡£ + ¥³¥á¥ó¥È¤Î½ª¤ï¤ê (-->) + ¤ÎÁ°¤Ë¤Ï¡¢SSI ¤Î¶ç¤Î°ìÉô¤À¤È²ò¼á¤µ¤ì¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¶õÇò¤ò + Æþ¤ì¤Æ¤¯¤À¤µ¤¤¡£ºÇ½é¤Î <!--# ¤Ï¤Þ¤È¤á¤Æ°ì¤Ä¤Î + ¶ç¤Ç¡¢¶õÇò¤ò¤Õ¤¯¤ó¤Ç¤Ï¤¤¤±¤Ê¤¤¤³¤ÈÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Í×ÁÇ (ÌõÃí: element) ¤ò°Ê²¼¤Îɽ¤Ë¼¨¤·¤Þ¤¹¡£

    + + + + + + + + + + + + + + + + + + + +
    Í×ÁÇÀâÌÀ
    configconfigure output formats
    echoprint variables
    execexecute external programs
    fsizeprint size of a file
    flastmodprint last modification time of a file
    includeinclude a file
    printenvprint all available variables
    setset a value of a variable
    + +

    SSI Í×ÁÇ¤Ï mod_include °Ê³°¤Î¥â¥¸¥å¡¼¥ë¤Ç + ÄêµÁ¤µ¤ì¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£¼ÂºÝ¡¢ + exec Í×ÁÇ¤Ï + mod_cgi ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Æ¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤¬ + ¥í¡¼¥É¤µ¤ì¤ë¾ì¹ç¤Ë¤Î¤ßÍøÍѲÄǽ¤È¤Ê¤ê¤Þ¤¹¡£

    + +

    config Í×ÁÇ

    +

    ¼¡¤Î¥³¥Þ¥ó¥É¤Ï²òÀϤÎÍÍ¡¹¤Ê¦Ì̤òÀ©¸æ¤·¤Þ¤¹¡£Â°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    echomsg (Apache 2.1 °Ê¹ß)
    +
    »ØÄꤵ¤ì¤ëÃͤϡ¢echo + Í×ÁǤ¬Ì¤ÄêµÁ¤ÎÊÑ¿ô¤ò¥¨¥³¡¼¤·¤è¤¦¤È¤·¤¿ºÝ¤Ë¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ë¥á¥Ã¥»¡¼¥¸¤Ë¤Ê¤ê¤Þ¤¹¡£ + SSIUndefinedEcho + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¾å½ñ¤­¤·¤Þ¤¹¡£
    + +
    errmsg
    +
    ¤³¤ÎÃͤ¬¡¢¥É¥­¥å¥á¥ó¥È¤Î²òÀÏÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿»þ¤Ë + ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¿®¤µ¤ì¤ë¥á¥Ã¥»¡¼¥¸¤Ë¤Ê¤ê¤Þ¤¹¡£ + SSIErrorMsg + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¾å½ñ¤­¤·¤Þ¤¹¡£
    + +
    sizefmt
    +
    ¤³¤ÎÃͤϡ¢¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤òɽ¼¨¤¹¤ëºÝ¤Ë»ÈÍѤ¹¤ë + ¥Õ¥©¡¼¥Þ¥Ã¥È¤òÀßÄꤷ¤Þ¤¹¡£ÃÍ¤Ï ¥Ð¥¤¥È¥«¥¦¥ó¥È¤Î + bytes¤«¡¢Kb ¤ä Mb ¤òÍ¥ÀèŪ¤Ë»ÈÍѤ¹¤ë + abbrec (Î㤨¤Ð 1024 ¥Ð¥¤¥È¤Ï "1K" ¤Èɽ¼¨¤µ¤ì¤Þ¤¹) + ¤Ç¤¹¡£
    + +
    timefmt
    +
    ¤³¤ÎÃÍ¤Ï strftime(3) ¥é¥¤¥Ö¥é¥ê¥ë¡¼¥Á¥ó¤¬ + Æü»þ¤ò¥×¥ê¥ó¥È¤¹¤ëºÝ¤ËÍѤ¤¤é¤ì¤Þ¤¹¡£
    +
    + + +

    echo Í×ÁÇ

    +

    ¤³¤Î¥³¥Þ¥ó¥É¤Ï°Ê²¼¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë include + ÊÑ¿ô ¤òɽ¼¨¤·¤Þ¤¹¡£ÊÑ¿ô¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï SSIUndefinedEcho ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + ·èÄꤵ¤ì¤ë·ë²Ì¤È¤Ê¤ê¤Þ¤¹¡£ÆüÉդϤ½¤Î»þÅÀ¤Ç¤Î timefmt ¤Ë½¾¤Ã¤Æ + ɽ¼¨¤µ¤ì¤Þ¤¹¡£Â°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    var
    +
    ÃͤÏɽ¼¨¤¹¤ëÊÑ¿ô¤Î̾Á°¤Ç¤¹¡£
    + +
    encoding
    +

    ÊÑ¿ô¤ò½ÐÎϤ¹¤ëÁ°¤Ë¡¢ÊÑ¿ôÃæ¤ÎÆÃÊÌʸ»ú¤ò¤É¤Î¤è¤¦¤Ë¥¨¥ó¥³¡¼¥É¤¹¤ë¤«¤ò + »ØÄꤷ¤Þ¤¹¡£none ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢¥¨¥ó¥³¡¼¥É¤Ï¹Ô¤Ê¤ï¤ì¤Þ¤»¤ó¡£ + url ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢URL ¥¨¥ó¥³¡¼¥É (%-¥¨¥ó¥³¡¼¥É¤È¤â + ¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¥ê¥ó¥¯Åù¤Î URL ¤Î»ÈÍѤËŬÀڤǤ¹) ¤¬ + ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£echo Í×ÁǤγ«»Ï»þ¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ï + entity ¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¥¨¥ó¥Æ¥£¥Æ¥£¥¨¥ó¥³¡¼¥É + (ÃÊÍî¤ä¥Æ¥­¥¹¥È¤Ê¤É¤Î¥Ö¥í¥Ã¥¯¥ì¥Ù¥ë¤Î HTML ¥¨¥ì¥á¥ó¥È¤Î¥³¥ó¥Æ¥­¥¹¥È¤Ë + Ŭ¤·¤Æ¤¤¤Þ¤¹) ¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£¤³¤ì¤Ï encoding °À­ + ¤ò²Ã¤¨¤ë¤³¤È¤ÇÊѹ¹¤Ç¤­¤Þ¤¹¡£Êѹ¹¤Ï¼¡¤Î encoding °À­¤«¡¢ + Í×ÁǤνªÎ»¤Þ¤Ç¸úÎϤò»ý¤Á¤Þ¤¹¡£

    + +

    encoding °À­¤Ï¥¨¥ó¥³¡¼¥É¤ÎÊѹ¹¤ò¤·¤¿¤¤ var + ¤ÎÁ°¤Ë ¤¢¤ëɬÍפ¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤Þ¤¿¡¢ISO-8859-1 ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ç + ÄêµÁ¤µ¤ì¤Æ¤¤¤ëÆÃÊ̤Êʸ»ú¤À¤±¤¬¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹¡£ + Ê̤Îʸ»ú¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î¾ì¹ç¤Ï¡¢¤³¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ï + ˾¤ß¤Î·ë²Ì¤Ë¤Ê¤é¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +
    + ¥¯¥í¥¹¥µ¥¤¥È¥¹¥¯¥ê¥×¥Æ¥£¥ó¥°¤ÎÌäÂê¤òÈò¤±¤ë¤¿¤á¤Ë¡¢ + ¾ï¤Ë¥æ¡¼¥¶¤«¤é¤Î¥Ç¡¼¥¿¤ò¥¨¥ó¥³¡¼¥É¤¹¤Ù¤­¤Ç¤¹¡£ +
    +
    +
    + + +

    exec Í×ÁÇ

    +

    exec ¥³¥Þ¥ó¥É¤Ï»ØÄꤵ¤ì¤¿¥·¥§¥ë¥³¥Þ¥ó¥É¤ä CGI ¥¹¥¯¥ê¥×¥È¤ò + ¼Â¹Ô¤·¤Þ¤¹¡£mod_cgi ¤¬¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤¤¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£Option + IncludesNOEXEC ¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£ + »ÈÍѲÄǽ¤Ê°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    cgi
    +

    ÃÍ¤Ï (%-¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿) URL ¤ò»ØÄꤷ¤Þ¤¹¡£¥Ñ¥¹¤¬ + ¥¹¥é¥Ã¥·¥å (/) ¤Ç»Ï¤Þ¤é¤Ê¤¤¤È¤­¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤«¤é¤Î + ÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£¤³¤Î¥Ñ¥¹¤Ç»²¾È¤µ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤Ï + ¥µ¡¼¥Ð¤¬ CGI ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤â CGI ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ + µ¯Æ°¤µ¤ì¤Þ¤¹¡£¤¿¤À¤·¡¢¥¹¥¯¥ê¥×¥È¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï + (ScriptAlias + ¤ä Option ExecCGI + ¤Ë¤è¤Ã¤Æ) CGI ¥¹¥¯¥ê¥×¥È¤Î»ÈÍѤ¬µö²Ä¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    CGI ¥¹¥¯¥ê¥×¥È¤Ë¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¸µ¡¹¤Î¥ê¥¯¥¨¥¹¥È¤Î + PATH_INFO ¤È¥¯¥¨¥ê¡¼Ê¸»úÎó (QUERY_STRING) ¤¬ÅϤµ¤ì¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï URL ¥Ñ¥¹¤È¤·¤ÆÆÃÄê¤Ç¤­¤Ê¤¤¤â¤Î¤Ç¤¹¡£ + ¥¹¥¯¥ê¥×¥È¤Ïɸ½à CGI ´Ä¶­¤Ë²Ã¤¨¤Æ¡¢include ÊÑ¿ô¤ò + »ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Îã

    + <!--#exec cgi="/cgi-bin/example.cgi" --> +

    + +

    ¥¹¥¯¥ê¥×¥È¤¬¡¢½ÐÎϤÎÂå¤ï¤ê¤Ë Location: ¥Ø¥Ã¥À¤òÊÖ¤¹¤È¡¢ + HTML ¤Î¥¢¥ó¥«¡¼ (ÌõÃí¡§¥ê¥ó¥¯) ¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£

    + +

    exec cgi ¤è¤ê¤â¡¢ + include virtual + ¤ÎÊý¤ò»È¤¦¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£Æäˡ¢CGI ¤Ø¤ÎÄɲäΰú¿ô¤ò + ¥¯¥¨¥ê¡¼Ê¸»úÎó¤ò»È¤Ã¤ÆÅϤ¹¤³¤È¤Ï exec cgi ¤Ï + ¤Ç¤­¤Þ¤»¤ó¤¬¡¢include virtual ¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ + ²Äǽ¤Ç¤¹¡£

    + +

    + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> +

    +
    + +
    cmd
    +

    ¥µ¡¼¥Ð¤Ï»ØÄꤵ¤ì¤¿Ê¸»úÎó¤ò /bin/sh ¤ò»È¤Ã¤Æ + ¼Â¹Ô¤·¤Þ¤¹¡£¥³¥Þ¥ó¥É¤ÏÄ̾ï¤Î CGI ÊÑ¿ô¤Ë²Ã¤¨¤Æ include ÊÑ¿ô¤â»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤Û¤È¤ó¤É¤Î¾ì¹ç¡¢#include + virtual ¤ò»È¤¦Êý¤¬ #exec cgi ¤ä #exec + cmd ¤ò»È¤¦¤è¤ê¤âÎɤ¤¤Ç¤¹¡£Á°¼Ô (#include virtual) + ¤Ïɸ½à¤Î Apache ¤Î¥µ¥Ö¥ê¥¯¥¨¥¹¥Èµ¡¹½¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¤ä¥¹¥¯¥ê¥×¥È¤Î + ½ÐÎϤò¼è¤ê¹þ¤ß¤Þ¤¹¡£ + ¤³¤Á¤é¤ÎÊý¤¬¤è¤¯¥Æ¥¹¥È¤µ¤ì¥á¥ó¥Æ¥Ê¥ó¥¹¤µ¤ì¤¿ÊýË¡¤Ç¤¹¡£

    + +

    ¤µ¤é¤Ë¡¢Win32 ¤Î¤è¤¦¤Ê¤¤¤¯¤Ä¤«¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤ä¡¢suexec ¤ò»È¤Ã¤Æ¤¤¤ë unix ¤Ç¤Ï¡¢ + exec ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥³¥Þ¥ó¥É¤Ë + °ú¿ô¤òÅϤ·¤¿¤ê¡¢¥³¥Þ¥ó¥É¤Ë¶õÇò¤òÆþ¤ì¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ¤Ç¤¹¤«¤é¡¢°Ê²¼¤Î¤â¤Î¤Ï unix ¤Î suexec ¤Ç¤Ê¤¤ÀßÄê¤Ç¤ÏÆ°ºî¤·¤Þ¤¹¤¬¡¢ + Win32 ¤ä suexec ¤ò»È¤Ã¤Æ¤¤¤ë unix ¤Ç¤Ï´üÂÔ¤·¤¿·ë²Ì¤Ë¤Ï¤Ê¤ê¤Þ¤»¤ó:

    + +

    + <!--#exec cmd="perl /path/to/perlscript arg1 arg2" --> +

    +
    +
    + + +

    fsize Í×ÁÇ

    +

    ¤³¤Î¥³¥Þ¥ó¥É¤Ï»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤ò sizefmt ¤Î + ½ñ¼°»ØÄê¤Ë´ð¤Å¤¤¤Æ½ÐÎϤ·¤Þ¤¹¡£Â°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    file
    +
    ÃͤϲòÀϤµ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤Î¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î + ÁêÂХѥ¹¤Ç¤¹¡£
    + +
    virtual
    +
    ÃÍ¤Ï (% ¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿) URL-path ¤Ç¤¹¡£¥¹¥é¥Ã¥·¥å (/) ¤Ç + »Ï¤Þ¤é¤Ê¤¤¤È¤­¤Ï¥É¥­¥å¥á¥ó¥È¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£ + CGI ¤Î½ÐÎϤΥµ¥¤¥º¤Ï¥×¥ê¥ó¥È¤µ¤ì¤Þ¤»¤ó¡£CGI + ¥¹¥¯¥ê¥×¥È¼«ÂΤΥµ¥¤¥º¤¬¥×¥ê¥ó¥È¤µ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
    +
    + + +

    flastmod Í×ÁÇ

    +

    ¤³¤Î¥³¥Þ¥ó¥É¤Ï»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤ò + timefmt ½ñ¼°»ØÄê¤Ë½¾¤Ã¤Æɽ¼¨¤·¤Þ¤¹¡£ + »ØÄê²Äǽ¤Ê°À­¤Ï fsize ¥³¥Þ¥ó¥É¤ÈƱ¤¸¤Ç¤¹¡£

    + + +

    include Í×ÁÇ

    +

    ¤³¤Î¥³¥Þ¥ó¥É¤ÏÊ̤Îʸ½ñ¤ä¥Õ¥¡¥¤¥ë¤Î¥Æ¥­¥¹¥È¤ò²òÀϤ·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Ë + ÁÞÆþ¤·¤Þ¤¹¡£ÁÞÆþ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Ï¥¢¥¯¥»¥¹À©¸æ¤Î´ÉÍý²¼¤Ë¤¢¤ê¤Þ¤¹¡£ + ²òÀϤ·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Î¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë + Option IncludesNOEXEC + ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢text MIME ¥¿¥¤¥× (text/plain, + text/html Åù) ¤Î¥É¥­¥å¥á¥ó¥È¤Î¤ß¥¤¥ó¥¯¥ë¡¼¥É¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + ¤½¤Î¾¤Î¾ì¹ç¤Ï¡¢¥¯¥¨¥ê¡¼Ê¸»úÎó¤â´Þ¤á¡¢¥³¥Þ¥ó¥É¤Ç»ØÄꤵ¤ì¤¿ + ´°Á´¤Ê URL ¤ò»È¤Ã¤ÆÉáÄÌ¤Ë CGI ¥¹¥¯¥ê¥×¥È¤¬¸Æ¤Ó½Ð¤µ¤ì¤Þ¤¹¡£

    + +

    °À­¤¬Ê¸½ñ¤Î°ÌÃÖ¤ò»ØÄꤷ¤Þ¤¹¡£include ¥³¥Þ¥ó¥É¤ËÍ¿¤¨¤é¤ì¤¿¤½¤ì¤¾¤ì¤Î + °À­¤ËÂФ·¤ÆÁÞÆþºî¶È¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£Í­¸ú¤Ê°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    file
    +
    ÃͤϲòÀϤµ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤Î¸ºß¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î + ÁêÂХѥ¹¤Ç¤¹¡£ + ../ ¤ò´Þ¤ó¤Ç¤¤¤¿¤ê¡¢ÀäÂХѥ¹¤ò»ØÄꤷ¤¿¤ê¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ¤Ç¤¹¤«¤é¡¢¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È¤Î³°¤Ë¤¢¤ë¥Õ¥¡¥¤¥ë¤ä¡¢¥Ç¥£¥ì¥¯¥È¥ê¹½Â¤¤Ç + ¾å°Ì¤Ë¤¢¤ë¥Õ¥¡¥¤¥ë¤òÁÞÆþ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ¾ï¤Ë¤³¤Î°À­¤è¤ê¤Ï¡¢virtual °À­¤ò»È¤¦¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    + +
    virtual
    +

    ÃͤϲòÀϤµ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤«¤é¤Î (% ¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿) URL + ¤Ç¤¹¡£URL ¤Ë¤Ï¥¹¥­¡¼¥à¤ä¥Û¥¹¥È̾¤ò´Þ¤á¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¥Ñ¥¹¤È¡¢ + ¤â¤·¤¢¤ì¤Ð¥¯¥¨¥ê¡¼Ê¸»úÎó¤ò»ØÄê¤Ç¤­¤ë¤À¤±¤Ç¤¹¡£¥¹¥é¥Ã¥·¥å (/) ¤«¤é + »Ï¤Þ¤é¤Ê¤¤¾ì¹ç¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    URL ¤Ï°À­¤«¤éºî¤é¤ì¡¢¤½¤Î URL ¤ò¥¯¥é¥¤¥¢¥ó¥È¤¬¥¢¥¯¥»¥¹¤·¤¿¤È¤­¤Ë + ½ÐÎϤµ¤ì¤ëÆâÍƤ¬²òÀϸå¤Î½ÐÎϤ˴ޤá¤é¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ÁÞÆþ¤µ¤ì¤ë + ¥Õ¥¡¥¤¥ë¤ÏÆþ¤ì»Ò¹½Â¤¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    »ØÄꤵ¤ì¤¿ URL ¤¬ CGI ¥×¥í¥°¥é¥à¤Ç¤¢¤Ã¤¿¾ì¹ç¤Ï¡¢ + ¥×¥í¥°¥é¥à¤¬¼Â¹Ô¤µ¤ì¡¢¤½¤Î½ÐÎϤ¬²òÀϤ·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ëÃæ¤Î + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¤¢¤Ã¤¿°ÌÃÖ¤ËÁÞÆþ¤µ¤ì¤Þ¤¹¡£CGI ¤Î url ¤Ë + ¥¯¥¨¥ê¡¼ URL ¤òÆþ¤ì¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> +

    + +

    HTML ¥É¥­¥å¥á¥ó¥È¤Ë CGI ¥×¥í¥°¥é¥à¤Î½ÐÎϤò´Þ¤á¤ëÊýË¡¤È¤·¤Æ¤Ï¡¢ + include virtual ¤ÎÊý¤¬ exec cgi ¤è¤ê¤â + ¹¥¤Þ¤·¤¤ÊýË¡¤Ç¤¹¡£

    +
    +
    + + +

    printenv Í×ÁÇ

    +

    ¤³¤ì¤Ï¡¢Â¸ºß¤¹¤ë¤¹¤Ù¤Æ¤ÎÊÑ¿ô¤È¤½¤ÎÃͤòɽ¼¨¤·¤Þ¤¹¡£Apache 1.3.12 ¤«¤é¡¢ + ÆÃÊ̤Êʸ»ú¤Ï½ÐÎϤµ¤ì¤ëÁ°¤Ë¥¨¥ó¥Æ¥£¥Æ¥£¥¨¥ó¥³¡¼¥É (¾ÜºÙ¤Ï echo Í×ÁǤò»²¾È) + ¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£Â°À­¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    Îã

    + <!--#printenv --> +

    + + +

    set Í×ÁÇ

    +

    ¤³¤ì¤ÏÊÑ¿ô¤ÎÃͤòÀßÄꤷ¤Þ¤¹¡£Â°À­¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +
    +
    var
    +
    ÀßÄꤹ¤ëÊÑ¿ô¤Î̾Á°¡£
    + +
    value
    +
    ÊÑ¿ô¤ËÀßÄꤹ¤ëÃÍ¡£
    +
    + +

    Îã

    + <!--#set var="category" value="help" --> +

    + +
    top
    +
    +

    Include ÊÑ¿ô

    + + +

    ɸ½à CGI ´Ä¶­¤ÎÊÑ¿ô¤Ë²Ã¤¨¤Æ¡¢echo ¥³¥Þ¥ó¥É¤ä¡¢ + if ¤ä elif, ¤½¤ì¤Ë¥É¥­¥å¥á¥ó¥È¤«¤é¸Æ¤Ó½Ð¤µ¤ì¤ë + ¤¹¤Ù¤Æ¤Î¥×¥í¥°¥é¥à¤«¤é»ÈÍѤǤ­¤ëÊÑ¿ô¤¬¤¢¤ê¤Þ¤¹¡£

    + +
    +
    DATE_GMT
    +
    ¥°¥ê¥Ë¥Ã¥¸É¸½à»þ¤Ë¤è¤ë¸½ºß»þ¹ï¡£
    + +
    DATE_LOCAL
    +
    ¥í¡¼¥«¥ë¤Îɸ½à»þ¤Ë¤è¤ë¸½ºß»þ¹ï¡£
    + +
    DOCUMENT_NAME
    +
    ¥æ¡¼¥¶¤¬¥ê¥¯¥¨¥¹¥È¤·¤¿ (¥Ç¥£¥ì¥¯¥È¥ê¤ò½ü¤¤¤¿) ¥Õ¥¡¥¤¥ë̾¡£
    + +
    DOCUMENT_URI
    +
    ¥æ¡¼¥¶¤¬¥ê¥¯¥¨¥¹¥È¤·¤¿ (% ¥¨¥ó¥³¡¼¥É¤µ¤ì¤¿) URL-path¡£ + ÁÞÆþ¥Õ¥¡¥¤¥ë¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢²òÀϤµ¤ì¤Æ¤¤¤ë + ¥É¥­¥å¥á¥ó¥È¤Î URL ¤Ç¤Ï¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
    + +
    LAST_MODIFIED
    +
    ¥æ¡¼¥¶¤¬¥ê¥¯¥¨¥¹¥È¤·¤¿¥É¥­¥å¥á¥ó¥È¤ÎºÇ½ª½¤Àµ»þ¹ï¡£
    + +
    QUERY_STRING_UNESCAPED
    +
    ¥¯¥¨¥ê¡¼Ê¸»úÎ󤬤¢¤ë¾ì¹ç¡¢¤³¤ÎÊÑ¿ô¤Ë¤Ï (%-¥Ç¥³¡¼¥É¤µ¤ì¤¿) + ¥¯¥¨¥ê¡¼Ê¸»úÎó¤¬ÂåÆþ¤µ¤ì¤Æ¤¤¤Æ¡¢shell ¤Ç»ÈÍѤǤ­¤ë¤è¤¦¤Ë + ¥¨¥¹¥±¡¼¥×¤µ¤ì¤Æ¤¤¤Þ¤¹ (& + ¤È¤¤¤Ã¤¿Æüìʸ»ú¤Ë¤Ï¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤¬Ä¾Á°¤ËÃÖ¤«¤ì¤Þ¤¹)¡£
    +
    +
    top
    +
    +

    ÊÑ¿ôÃÖ´¹

    + +

    ÊÑ¿ôÃÖ´¹¤Ï¤¿¤¤¤Æ¤¤¤Î¾ì¹ç SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤È¤·¤ÆÂÅÅö¤Ê¾ì½ê¤Ë¤¢¤ë + °úÍÑÉä¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎóÃæ¤Ç¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£¤³¤ì¤Ë³ºÅö¤¹¤ë¤â¤Î¤Ë¤Ï¡¢ + config, + exec, flastmod, fsize, + include, echo, set ¤Î + ³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¡¢¾ò·ïʬ´ôÍѤΥª¥Ú¥ì¡¼¥¿¤Ø¤Î°ú¿ô¤¬¤¢¤ê¤Þ¤¹¡£ + ¥É¥ëµ­¹æ¤Ï¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤ò»È¤¦¤³¤È¤Ç»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + <!--#if expr="$a = \$test" --> +

    + +

    ÊÑ¿ô̾¤È¤·¤Æ¤ß¤Ê¤µ¤ì¤ëʸ»úÎó¤ÎÃæ¤ÇÊÑ¿ô¤Ø¤Î»²¾È¤òÃÖ´¹¤¹¤ëɬÍפ¬¤¢¤ë¤È¤­¤Ï¡¢ + ¥·¥§¥ë¤Ç¤ÎÊÑ¿ôÃÖ´¹¤Î¤è¤¦¤Ë¡¢Ãæ³ç¸Ì¤Ç³ç¤ë¤³¤È¤Ç¶èÊ̤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + <!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" --> +

    + +

    ¤³¤ÎÎã¤Ç¤Ï¡¢REMOTE_HOST ¤¬ + "X" ¤Ç REQUEST_METHOD ¤¬ + "Y" ¤Î¤È¤­¤ËÊÑ¿ô Zed ¤ò "X_Y" + ¤ËÀßÄꤷ¤Þ¤¹¡£

    + +

    °Ê²¼¤ÎÎã¤Ç¤Ï¡¢DOCUMENT_URI ¤¬ /foo/file.html + ¤Î¤È¤­¤Ë "in foo" ¤ò¡¢/bar/file.html ¤Î¤È¤­¤Ë "in bar" ¤ò¡¢ + ¤É¤Á¤é¤Ç¤â¤Ê¤¤¤È¤­¤Ë¤Ï "in neither" ¤òɽ¼¨¤·¤Þ¤¹¡£

    + +

    + <!--#if expr='"$DOCUMENT_URI" = "/foo/file.html"' -->
    + + in foo
    +
    + <!--#elif expr='"$DOCUMENT_URI" = "/bar/file.html"' -->
    + + in bar
    +
    + <!--#else -->
    + + in neither
    +
    + <!--#endif --> +

    +
    top
    +
    +

    ¥Õ¥í¡¼À©¸æÍ×ÁÇ

    + + +

    ´ðËÜŪ¤Ê¥Õ¥í¡¼¥³¥ó¥È¥í¡¼¥ëÍ×ÁǤϼ¡¤ÎÄ̤ê¤Ç¤¹¡£

    + +

    + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +

    + +

    if Í×ÁÇ¤Ï¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Î + if ʸ¤ÈƱ¤¸¤è¤¦¤ËÆ°ºî¤·¤Þ¤¹¡£¾ò·ï¤¬É¾²Á¤µ¤ì¡¢·ë²Ì¤¬¿¿¤Ç¤¢¤ì¤Ð¼¡¤Î + elif ¤« else ¤« endif + Í×ÁǤޤǤÎʸ»úÎ󤬽ÐÎϤËÁÞÆþ¤µ¤ì¤Þ¤¹¡£

    + +

    elif ¤ä else ʸ¤Ï test_condition + ¤¬µ¶¤Î¤È¤­¤Ë¥Æ¥­¥¹¥È¤ò½ÐÎϤËÁÞÆþ¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¤³¤ì¤é¤ÎÍ×ÁǤϤ¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    endif Í×ÁÇ¤Ï if + Í×ÁǤò½ªÎ»¤µ¤»¤Þ¤¹¡£¤³¤ÎÍ×ÁǤÏɬ¿Ü¤Ç¤¹¡£

    + +

    test_condition ¤Ï°Ê²¼¤Î¤É¤ì¤«¤Ç¤¹:

    + +
    +
    string
    +
    string ¤¬¶õ¤Ç¤Ê¤¤¾ì¹ç¤Ë¿¿¤Ç¤¹
    + +
    string1 = string2
    + string1 == string2
    + string1 != string2
    + +

    string1 ¤È string2 ¤òÈæ³Ó¤·¤Þ¤¹¡£ + string2 ¤¬ /string/ + ¤È¤¤¤¦·Á¼°¤Ç¤¢¤ì¤Ð¡¢Àµµ¬É½¸½¤È¤·¤ÆÈæ³Ó¤µ¤ì¤Þ¤¹¡£Àµµ¬É½¸½¤Ï + PCRE ¥¨¥ó¥¸¥ó¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤Æ¡¢ + perl 5 ¤ÈƱ¤¸¹½Ê¸¤ò»ÈÍѤ·¤Þ¤¹¡£ + == ¤Ïñ¤Ë = ¤ÎÊÌ̾¤Ç¡¢¤Þ¤Ã¤¿¤¯Æ±¤¸Æ°ºî¤ò + ¤·¤Þ¤¹¡£

    + +

    Àµ¤Î¥Þ¥Ã¥Á¥ó¥° (= ¤Þ¤¿¤Ï ==) ¤Î¾ì¹ç¤Ï¡¢ + Àµµ¬É½¸½¤Ç¥°¥ë¡¼¥×ʬ¤±¤µ¤ì¤¿¥Ñ¡¼¥Ä¤ò¥­¥ã¥×¥Á¥ã¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥­¥ã¥×¥Á¥ã¤µ¤ì¤¿Éôʬ¤ÏÆüìÊÑ¿ô $1 .. $9 + ¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + <!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
    + + <!--#set var="session" value="$1" -->
    +
    + <!--#endif --> +

    +
    + +
    string1 < string2
    + string1 <= string2
    + string1 > string2
    + string1 >= string2
    + +
    string1 ¤È string2 ¤òÈæ³Ó¤·¤Þ¤¹¡£ + ʸ»úÎó¤È¤·¤ÆÈæ³Ó¤µ¤ì¤ë (strcmp(3) ¤ò»ÈÍÑ) + ¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Ç¤¹¤«¤é¡¢Ê¸»úÎó "100" ¤Ï "20" + ¤è¤ê¤â¾®¤µ¤¤¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
    + +
    ( test_condition )
    +
    test_condition ¤¬¿¿¤Î¤È¤­¡¢¿¿
    + +
    ! test_condition
    +
    test_condition ¤¬µ¶¤Î¤È¤­¡¢¿¿
    + +
    test_condition1 && + test_condition2
    +
    test_condition1 ¤«¤Ä + test_condition2 ¤¬¿¿¤Î¤È¤­¡¢¿¿
    + +
    test_condition1 || + test_condition2
    +
    test_condition1 ¤Þ¤¿¤Ï + test_condition2 ¤¬¿¿¤Î¤È¤­¡¢¿¿
    +
    + +

    "=" ¤È "!=" ¤ÎÊý¤¬ "&&" ¤è¤ê + ¤­¤Ä¤¯Â«Çû¤·¤Þ¤¹¡£"!" ¤Î«Çû¤¬°ìÈÖ¤­¤Ä¤¯¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é°Ê²¼¤ÎÆó¤Ä¤ÏÅù²Á¤Ç¤¹:

    + +

    + <!--#if expr="$a = test1 && $b = test2" -->
    + <!--#if expr="($a = test1) && ($b = test2)" --> +

    + +

    ¿¿µ¶ÃÍ¥ª¥Ú¥ì¡¼¥¿ && ¤È || + ¤ÏƱ¤¸Í¥ÀèÅ٤Ǥ¹¡£ + ¤³¤ì¤é¤Î¥ª¥Ú¥ì¡¼¥¿¤Ç°ìÊý¤Ë¤è¤ê¶¯¤¤Í¥ÀèÅÙ¤ò¤Ä¤±¤¿¤¤¾ì¹ç¤Ë¤Ï¡¢ + ³ç¸Ì¤ò»È¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ÊÑ¿ô¤ä¥ª¥Ú¥ì¡¼¥¿¤È¤·¤Æǧ¼±¤µ¤ì¤Ê¤¤¤â¤Î¤Ï¤¹¤Ù¤Æʸ»úÎó¤È¤·¤Æ + °·¤ï¤ì¤Þ¤¹¡£Ê¸»úÎó¤Ï°úÍÑÉä¤Ç°Ï¤à¤³¤È¤â¤Ç¤­¤Þ¤¹: 'string' + ¤Î¤è¤¦¤Ë¡£°úÍÑÉä¤Ç°Ï¤Þ¤ì¤Æ¤¤¤Ê¤¤Ê¸»úÎó¤Ë¤Ï¶õÇò (¥¹¥Ú¡¼¥¹¤È¥¿¥Ö) + ¤ò´Þ¤á¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤½¤ì¤é¤ÏÊÑ¿ô¤Ê¤É¤Î¶ç¤òʬΥ¤¹¤ë¤¿¤á¤Ë + »È¤ï¤ì¤Æ¤¤¤ë¤«¤é¤Ç¤¹¡£Ê£¿ô¤Îʸ»úÎó¤¬Â³¤¤¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + ¶õÇò¤ò´Ö¤ËÆþ¤ì¤Æ°ì¤Ä¤Ë¤¯¤Ã¤Ä¤±¤é¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢

    + +

    string1    string2 ¤Ï string1 string2 ¤Ë¤Ê¤ê¤Þ¤¹¡£
    +
    + ¤Þ¤¿¡¢
    +
    + 'string1    string2' ¤Ï string1    string2 + ¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¿¿µ¶ÃÍɽ¸½¤ÎºÇŬ²½

    +

    ¼°¤¬¤â¤Ã¤ÈÊ£»¨¤Ë¤Ê¤ê¡¢½èÍý¤Î®ÅÙÄã²¼¤¬¸²Ãø¤Ë¤Ê¤Ã¤¿¾ì¹ç¤Ï¡¢ + ɾ²Á¥ë¡¼¥ë¤Ë½¾¤Ã¤ÆºÇŬ²½¤·¤Æ¤ß¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡£

    +
      +
    • ɾ²Á¤Ïº¸¤«¤é±¦¤Ë¸þ¤«¤Ã¤Æ¹Ô¤ï¤ì¤Þ¤¹¡£
    • +
    • ÆóÃÍ¿¿µ¶ÃÍ¥ª¥Ú¥ì¡¼¥¿ (&& ¤È ||) + ¤Ï¡¢½ÐÍè¤ë¸Â¤êûÍíɾ²Á¤µ¤ì¤Þ¤¹¡£¤Ä¤Þ¤ê·ë²Ì¤È¤·¤Æ¾åµ­¤Î¥ë¡¼¥ë¤Ï¡¢ + mod_include ¤¬º¸¤Îɾ²Á¼°¤òɾ²Á¤·¤Þ¤¹¡£ + º¸Â¦¤Ç·ë²Ì¤ò½½Ê¬·èÄê¤Ç¤­¤ë¾ì¹ç¤Ï¡¢É¾²Á¤Ï¤½¤³¤ÇÄä»ß¤·¤Þ¤¹¡£ + ¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï±¦Â¦¤òɾ²Á¤·¤Æ¡¢º¸¤È±¦¤ÎξÊý¤«¤é·ë²Ì¤ò·×»»¤·¤Þ¤¹¡£
    • +
    • ûÍíɾ²Á¤Ïɾ²Á¤ÎÂоݤËÀµµ¬É½¸½¤¬´Þ¤Þ¤ì¤ë¾ì¹ç¡¢¥ª¥Õ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¸åÊý»²¾È¤¹¤ëÊÑ¿ô ($1 .. $9) + ¤òËä¤á¤ë¤¿¤á¤Ë¡¢¼ÂºÝ¤Ëɾ²Á¤¹¤ëɬÍפ¬¤¢¤ë¤«¤é¤Ç¤¹¡£
    • +
    +

    ÆÃÄê¤Î¼°¤¬¤É¤Î¤è¤¦¤Ë°·¤ï¤ì¤ë¤«¤òÃΤꤿ¤¤¾ì¹ç¤Ï¡¢ + -DDEBUG_INCLUDE ¥³¥ó¥Ñ¥¤¥é¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ + mod_include ¤ò¥ê¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡£ + ¤³¤ì¤Ë¤è¤ê¡¢Á´¤Æ¤Î¥Ñ¡¼¥¹¤µ¤ì¤¿¼°¤ËÂФ·¤Æ¡¢»ú¶ç²òÀϾðÊó¡¢ + ¥Ñ¡¼¥¹¥Ä¥ê¡¼¤È¡¢ + ¤½¤ì¤¬¤É¤Î¤è¤¦¤Ë¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤¿½ÐÎϤޤÇɾ²Á¤µ¤ì¤¿¤«¤ò + ÁÞÆþ¤·¤Þ¤¹¡£

    +
    +
    +
    top
    +

    SSIEndTag ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:include Í×ÁǤò½ªÎ»¤µ¤»¤ëʸ»úÎó
    ¹½Ê¸:SSIEndTag tag
    ¥Ç¥Õ¥©¥ë¥È:SSIEndTag "-->"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    ¸ß´¹À­:2.0.30 °Ê¹ß¤ÇÍøÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï mod_include ¤¬Ãµ¤¹¡¢ + include Í×ÁǤνªÎ»¤ò¼¨¤¹Ê¸»úÎó¤òÊѹ¹¤·¤Þ¤¹¡£

    + +

    Îã

    + SSIEndTag "%>" +

    + + +

    »²¾È

    + +
    +
    top
    +

    SSIErrorMsg ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:SSI ¤Î¥¨¥é¡¼¤¬¤¢¤Ã¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤ë¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
    ¹½Ê¸:SSIErrorMsg message
    ¥Ç¥Õ¥©¥ë¥È:SSIErrorMsg "[an error occurred while processing this +directive]"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0.30 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    SSIErrorMsg ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï mod_include + ¤¬¥¨¥é¡¼¤¬µ¯¤³¤Ã¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¥á¥Ã¥»¡¼¥¸¤òÊѹ¹¤·¤Þ¤¹¡£¥×¥í¥À¥¯¥·¥ç¥ó¥µ¡¼¥Ð¤Ç¤Ï + ¥á¥Ã¥»¡¼¥¸¤¬¥æ¡¼¥¶¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë + ¥Ç¥Õ¥©¥ë¥È¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò "<!-- Error -->" + ¤ËÊѤ¨¤ë¤È¤¤¤¦¤è¤¦¤Ê¤³¤È¤ò¹Í¤¨¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï <!--#config + errmsg=message --> Í×ÁǤÈƱ¤¸¸ú²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + SSIErrorMsg "<!-- Error -->" +

    + +
    +
    top
    +

    SSIStartTag ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:include Í×ÁǤò³«»Ï¤¹¤ëʸ»úÎó
    ¹½Ê¸:SSIStartTag tag
    ¥Ç¥Õ¥©¥ë¥È:SSIStartTag "<!--#"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0.30 °Ê¹ß¤Ç»ÈÍѲÄǽ
    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï mod_include ¤¬Ãµ¤¹¡¢include + Í×ÁǤγ«»Ï¤ò¼¨¤¹Ê¸»úÎó¤òÊѹ¹¤·¤Þ¤¹¡£

    + +

    Æó¤Ä¤Î¥µ¡¼¥Ð¤Ç (¤â¤·¤«¤¹¤ë¤ÈÊÌ¡¹¤ÎÃʳ¬¤Ç) ¥Õ¥¡¥¤¥ë¤Î½ÐÎϤò²òÀϤ·¤Æ¤¤¤Æ¡¢ + ¤½¤ì¤¾¤ì¤Ë°ã¤¦¥³¥Þ¥ó¥É¤ò½èÍý¤µ¤»¤¿¤¤¡¢ + ¤È¤¤¤¦¤è¤¦¤Ê¤È¤­¤Ë¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¤¤Þ¤¹¡£

    + +

    Îã

    + SSIStartTag "<%"
    + SSIEndTag "%>" +

    + +

    ¾å¤ÎÎã¤Î¤è¤¦¤ËÂбþ¤¹¤ë + SSIEndTag ¤òÊ»¤»¤Æ»È¤¦¤È¡¢ + ²¼¤Ë¼¨¤¹Îã¤Î¤è¤¦¤Ë SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¨¤Þ¤¹:

    + +

    °ã¤¦³«»Ï¤È½ªÎ»¤Î¥¿¥°¤ò»È¤Ã¤¿ SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + <%printenv %> +

    + +

    »²¾È

    + +
    +
    top
    +

    SSITimeFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:ÆüÉÕ¤±¤ò¸½¤¹Ê¸»úÎó¤Î½ñ¼°¤òÀßÄꤹ¤ë
    ¹½Ê¸:SSITimeFormat formatstring
    ¥Ç¥Õ¥©¥ë¥È:SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    ¸ß´¹À­:2.0.30 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï DATE ´Ä¶­ÊÑ¿ô¤ò echo ¤·¤ÆÆüÉÕ¤ò¸½¤¹Ê¸»úÎó¤¬ + ɽ¼¨¤µ¤ì¤ë¤È¤­¤Î½ñ¼°¤òÊѹ¹¤·¤Þ¤¹¡£formatstring ¤Ï + C ɸ½à¥é¥¤¥Ö¥é¥ê¤Î strftime(3) ¤ÈƱ¤¸·Á¼°¤Ç¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï <!--#config + timefmt=formatstring --> Í×ÁǤÈƱ¤¸¸ú²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + SSITimeFormat "%R, %B %d, %Y" +

    + +

    ¾å¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢ÆüÉÕ¤Ï "22:26, June 14, 2002" ¤È¤¤¤¦ + ·Á¼°¤Çɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    SSIUndefinedEcho ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:̤ÄêµÁ¤ÎÊÑ¿ô¤¬ echo ¤µ¤ì¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤ëʸ»úÎó
    ¹½Ê¸:SSIUndefinedEcho string
    ¥Ç¥Õ¥©¥ë¥È:SSIUndefinedEcho "(none)"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    ¸ß´¹À­:2.0.34 °Ê¹ß¤ÇÍøÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÊÑ¿ô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¤Ë¤â´Ø¤ï¤é¤º + "echo" ¤µ¤ì¤¿¤È¤­¤Ë mod_include + ¤¬É½¼¨¤¹¤ëʸ»úÎó¤òÊѹ¹¤·¤Þ¤¹¡£

    + +

    Îã

    + SSIUndefinedEcho "<!-- undef -->" +

    + +
    +
    top
    +

    XBitHack ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¼Â¹Ô¥Ó¥Ã¥È¤¬ÀßÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +²òÀϤ¹¤ë
    ¹½Ê¸:XBitHack on|off|full
    ¥Ç¥Õ¥©¥ë¥È:XBitHack off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Options
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_include
    +

    XBitHack ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÄ̾ï¤Î HTML + ¥É¥­¥å¥á¥ó¥È¤Î²òÀϤòÀ©¸æ¤·¤Þ¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï MIME ¥¿¥¤¥× + text/html ¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Ë¤Î¤ß±Æ¶Á¤·¤Þ¤¹¡£ + XBitHack ¤Ï°Ê²¼¤ÎÃͤò¤È¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +
    +
    off
    +
    ¼Â¹Ô²Äǽ¥Õ¥¡¥¤¥ë¤ËÂФ·¤ÆÆÃÊ̤ʰ·¤¤¤ò¤·¤Þ¤»¤ó¡£
    + +
    on
    +
    ¥æ¡¼¥¶¤Î¼Â¹Ô¥Ó¥Ã¥È¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë text/html + ¥Õ¥¡¥¤¥ë¤ÏÁ´¤Æ¥µ¡¼¥Ð¤Ç²òÀϤ¹¤ë html ¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£
    + +
    full
    +
    on ¤ÈƱÍͤǤ¹¤¬¡¢¥°¥ë¡¼¥×¼Â¹Ô¥Ó¥Ã¥È¤â¥Æ¥¹¥È¤·¤Þ¤¹¡£ + ¤â¤·¤½¤ì¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢ÊÖ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Î Last-modified ¤Î + ÆüÉÕ¤ò¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤Ë¤·¤Þ¤¹¡£¤½¤ì¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢ + last-modified ¤ÎÆüÉÕ¤ÏÁ÷¤é¤ì¤Þ¤»¤ó¡£¤³¤Î¥Ó¥Ã¥È¤òÀßÄꤹ¤ë¤È¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤ä¥×¥í¥­¥·¤¬¥ê¥¯¥¨¥¹¥È¤ò¥­¥ã¥Ã¥·¥å¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + +
    Ãí°Õ ¾¤Î CGI ¤ò #include + ¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¤â¤Î¤ä¡¢³Æ¥¢¥¯¥»¥¹¤ËÂФ·¤Æ°ã¤¦½ÐÎϤòÀ¸À®¤¹¤ë + (¤â¤·¤¯¤Ï¸å¤Î¥ê¥¯¥¨¥¹¥È¤ÇÊѤï¤ë¤«¤â¤·¤ì¤Ê¤¤¤â¤Î) + ¤¹¤Ù¤Æ¤Î SSI ¥¹¥¯¥ê¥×¥È¤ËÂФ·¤Æ¥°¥ë¡¼¥×¼Â¹Ô¥Ó¥Ã¥È¤¬ + ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò³Îǧ¤Ç¤­¤Ê¤¤¾ì¹ç¤Ï¡¢full ¤Ï»È¤ï¤Ê¤¤Êý¤¬Îɤ¤ + ¤Ç¤·¤ç¤¦¡£
    +
    +
    + + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_include.xml b/trunk/docs/manual/mod/mod_include.xml new file mode 100644 index 0000000000..435e2604d3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.xml @@ -0,0 +1,792 @@ + + + + + + + + + +mod_include +Server-parsed html documents (Server Side Includes) +Base +mod_include.c +include_module +Implemented as an output filter since Apache +2.0 + + +

    This module provides a filter which will process files + before they are sent to the client. The processing is + controlled by specially formatted SGML comments, referred to as + elements. These elements allow conditional text, the + inclusion of other files or programs, as well as the setting and + printing of environment variables.

    +
    +Options +AcceptPathInfo +Filters +SSI Tutorial + +
    + Enabling Server-Side Includes + +

    Server Side Includes are implemented by the + INCLUDES filter. If + documents containing server-side include directives are given + the extension .shtml, the following directives will make Apache + parse them and assign the resulting document the mime type of + text/html:

    + + + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +
    + +

    The following directive must be given for the directories + containing the shtml files (typically in a + Directory section, + but this directive is also valid in .htaccess files if + AllowOverride Options + is set):

    + + + Options +Includes + + +

    For backwards compatibility, the server-parsed + handler also activates the + INCLUDES filter. As well, Apache will activate the INCLUDES + filter for any document with mime type + text/x-server-parsed-html or + text/x-server-parsed-html3 (and the resulting + output will have the mime type text/html).

    + +

    For more information, see our Tutorial on Server Side Includes.

    +
    + +
    + PATH_INFO with Server Side Includes + +

    Files processed for server-side includes no longer accept + requests with PATH_INFO (trailing pathname information) + by default. You can use the AcceptPathInfo directive to + configure the server to accept requests with PATH_INFO.

    +
    + +
    Basic Elements +

    The document is parsed as an HTML document, with special + commands embedded as SGML comments. A command has the syntax:

    + + + <!--#element attribute=value + attribute=value ... --> + + +

    The value will often be enclosed in double quotes, but single + quotes (') and backticks (`) are also + possible. Many commands only allow a single attribute-value pair. + Note that the comment terminator (-->) should be + preceded by whitespace to ensure that it isn't considered part of + an SSI token. Note that the leading <!--# is one + token and may not contain any whitespaces.

    + +

    The allowed elements are listed in the following table:

    + + + + + + + + + + + + + + + + + + + +
    ElementDescription
    configconfigure output formats
    echoprint variables
    execexecute external programs
    fsizeprint size of a file
    flastmodprint last modification time of a file
    includeinclude a file
    printenvprint all available variables
    setset a value of a variable
    + +

    SSI elements may be defined by modules other than + mod_include. In fact, the exec element is provided by + mod_cgi, and will only be available if this + module is loaded.

    + +
    The config Element +

    This command controls various aspects of the parsing. The + valid attributes are:

    + +
    +
    echomsg (Apache 2.1 and later)
    +
    The value is a message that is sent back to the + client if the echo element + attempts to echo an undefined variable. This overrides any SSIUndefinedEcho directives.
    + +
    errmsg
    +
    The value is a message that is sent back to the + client if an error occurs while parsing the + document. This overrides any SSIErrorMsg directives.
    + +
    sizefmt
    +
    The value sets the format to be used which displaying + the size of a file. Valid values are bytes + for a count in bytes, or abbrev for a count + in Kb or Mb as appropriate, for example a size of 1024 bytes + will be printed as "1K".
    + +
    timefmt
    +
    The value is a string to be used by the + strftime(3) library routine when printing + dates.
    +
    +
    + +
    The echo Element +

    This command prints one of the include + variables, defined below. If the variable is unset, the result is + determined by the SSIUndefinedEcho directive. Any dates printed are + subject to the currently configured timefmt.

    + +

    Attributes:

    + +
    +
    var
    +
    The value is the name of the variable to print.
    + +
    encoding
    +

    Specifies how Apache should encode special characters + contained in the variable before outputting them. If set + to none, no encoding will be done. If set to + url, then URL encoding (also known as %-encoding; + this is appropriate for use within URLs in links, etc.) will be + performed. At the start of an echo element, + the default is set to entity, resulting in entity + encoding (which is appropriate in the context of a block-level + HTML element, e.g. a paragraph of text). This can be + changed by adding an encoding attribute, which will + remain in effect until the next encoding attribute + is encountered or the element ends, whichever comes first.

    + +

    The encoding attribute must precede the + corresponding var attribute to be effective, and + only special characters as defined in the ISO-8859-1 character + encoding will be encoded. This encoding process may not have the + desired result if a different character encoding is in use.

    + + + In order to avoid cross-site scripting issues, you should + always encode user supplied data. + +
    +
    +
    + +
    The exec Element +

    The exec command executes a given shell command or + CGI script. It requires mod_cgi to be present + in the server. If Options + IncludesNOEXEC is set, this command is completely + disabled. The valid attributes are:

    + +
    +
    cgi
    +

    The value specifies a (%-encoded) URL-path to + the CGI script. If the path does not begin with a slash (/), + then it is taken to be relative to the current + document. The document referenced by this path is + invoked as a CGI script, even if the server would not + normally recognize it as such. However, the directory + containing the script must be enabled for CGI scripts + (with ScriptAlias + or Options + ExecCGI).

    + +

    The CGI script is given the PATH_INFO and query + string (QUERY_STRING) of the original request from the + client; these cannot be specified in the URL path. The + include variables will be available to the script in addition to + the standard CGI environment.

    + + Example + <!--#exec cgi="/cgi-bin/example.cgi" --> + + +

    If the script returns a Location: header instead of + output, then this will be translated into an HTML anchor.

    + +

    The include virtual + element should be used in preference to exec cgi. In + particular, if you need to pass additional arguments to a CGI program, + using the query string, this cannot be done with exec + cgi, but can be done with include virtual, as + shown here:

    + + + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> + +
    + +
    cmd
    +

    The server will execute the given string using + /bin/sh. The include variables are available to the command, in addition + to the usual set of CGI variables.

    + +

    The use of #include virtual is almost always prefered to using + either #exec cgi or #exec cmd. The former + (#include virtual) uses the standard Apache sub-request + mechanism to include files or scripts. It is much better tested and + maintained.

    + +

    In addition, on some platforms, like Win32, and on unix when + using suexec, you cannot pass arguments + to a command in an exec directive, or otherwise include + spaces in the command. Thus, while the following will work under a + non-suexec configuration on unix, it will not produce the desired + result under Win32, or when running suexec:

    + + + <!--#exec cmd="perl /path/to/perlscript arg1 arg2" --> + +
    +
    +
    + +
    The fsize Element +

    This command prints the size of the specified file, subject + to the sizefmt format specification. Attributes:

    + +
    +
    file
    +
    The value is a path relative to the directory + containing the current document being parsed.
    + +
    virtual
    +
    The value is a (%-encoded) URL-path. If it does not begin with + a slash (/) then it is taken to be relative to the current document. + Note, that this does not print the size of any CGI output, + but the size of the CGI script itself.
    +
    +
    + +
    The flastmod Element +

    This command prints the last modification date of the + specified file, subject to the timefmt format + specification. The attributes are the same as for the + fsize command.

    +
    + +
    The include Element +

    This command inserts the text of another document or file + into the parsed file. Any included file is subject to the + usual access control. If the directory containing the + parsed file has Options + IncludesNOEXEC set, then only documents with + a text MIME type (text/plain, text/html + etc.) will be included. Otherwise CGI scripts are invoked as normal + using the complete URL given in the command, including any query + string.

    + +

    An attribute defines the location of the document; the + inclusion is done for each attribute given to the include + command. The valid attributes are:

    + +
    +
    file
    +
    The value is a path relative to the directory + containing the current document being parsed. It cannot + contain ../, nor can it be an absolute path. + Therefore, you cannot include files that are outside of the + document root, or above the current document in the directory + structure. The virtual attribute should always be + used in preference to this one.
    + +
    virtual
    +

    The value is a (%-encoded) URL-path. The URL cannot contain a + scheme or hostname, only a path and an optional query string. If it + does not begin with a slash (/) then it is taken to be relative to the + current document.

    + +

    A URL is constructed from the attribute, and the output the + server would return if the URL were accessed by the client is + included in the parsed output. Thus included files can be nested.

    + +

    If the specified URL is a CGI program, the program will be + executed and its output inserted in place of the directive in the + parsed file. You may include a query string in a CGI url:

    + + + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> + + +

    include virtual should be used in preference + to exec cgi to include the output of CGI programs + into an HTML document.

    +
    +
    +
    + +
    The printenv Element +

    This prints out a listing of all existing variables and + their values. Special characters are entity encoded (see the echo element for details) + before being output. There are no attributes.

    + + Example + <!--#printenv --> + +
    + +
    The set Element +

    This sets the value of a variable. Attributes:

    + +
    +
    var
    +
    The name of the variable to set.
    + +
    value
    +
    The value to give a variable.
    +
    + + Example + <!--#set var="category" value="help" --> + +
    +
    + +
    + Include Variables + +

    In addition to the variables in the standard CGI environment, + these are available for the echo command, for + if and elif, and to any program + invoked by the document.

    + +
    +
    DATE_GMT
    +
    The current date in Greenwich Mean Time.
    + +
    DATE_LOCAL
    +
    The current date in the local time zone.
    + +
    DOCUMENT_NAME
    +
    The filename (excluding directories) of the document + requested by the user.
    + +
    DOCUMENT_URI
    +
    The (%-decoded) URL path of the document requested by the + user. Note that in the case of nested include files, this is + not the URL for the current document.
    + +
    LAST_MODIFIED
    +
    The last modification date of the document requested by + the user.
    + +
    QUERY_STRING_UNESCAPED
    +
    If a query string is present, this variable contains the + (%-decoded) query string, which is escaped for shell + usage (special characters like & etc. are + preceded by backslashes).
    +
    +
    + +
    Variable Substitution + +

    Variable substitution is done within quoted strings in most + cases where they may reasonably occur as an argument to an SSI + directive. This includes the config, + exec, flastmod, fsize, + include, echo, and set + directives, as well as the arguments to conditional operators. + You can insert a literal dollar sign into the string using backslash + quoting:

    + + + <!--#if expr="$a = \$test" --> + + +

    If a variable reference needs to be substituted in the + middle of a character sequence that might otherwise be + considered a valid identifier in its own right, it can be + disambiguated by enclosing the reference in braces, + a la shell substitution:

    + + + <!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" --> + + +

    This will result in the Zed variable being set + to "X_Y" if REMOTE_HOST is + "X" and REQUEST_METHOD is + "Y".

    + +

    The below example will print "in foo" if the + DOCUMENT_URI is /foo/file.html, "in bar" + if it is /bar/file.html and "in neither" otherwise:

    + + + <!--#if expr='"$DOCUMENT_URI" = "/foo/file.html"' -->
    + + in foo
    +
    + <!--#elif expr='"$DOCUMENT_URI" = "/bar/file.html"' -->
    + + in bar
    +
    + <!--#else -->
    + + in neither
    +
    + <!--#endif --> +
    +
    + +
    + Flow Control Elements + +

    The basic flow control elements are:

    + + + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +
    + +

    The if element works like an if statement in a + programming language. The test condition is evaluated and if + the result is true, then the text until the next elif, + else or endif element is included in the + output stream.

    + +

    The elif or else statements are be used + to put text into the output stream if the original + test_condition was false. These elements are optional.

    + +

    The endif element ends the if element + and is required.

    + +

    test_condition is one of the following:

    + +
    +
    string
    +
    true if string is not empty
    + +
    string1 = string2
    + string1 == string2
    + string1 != string2
    + +

    Compare string1 with string2. If + string2 has the form /string2/ + then it is treated as a regular expression. Regular expressions are + implemented by the PCRE engine and + have the same syntax as those in perl + 5. Note that == is just an alias for = + and behaves exactly the same way.

    + +

    If you are matching positive (= or ==), you + can capture grouped parts of the regular expression. The captured parts + are stored in the special variables $1 .. + $9.

    + + Example + <!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
    + + <!--#set var="session" value="$1" -->
    +
    + <!--#endif --> +
    +
    + +
    string1 < string2
    + string1 <= string2
    + string1 > string2
    + string1 >= string2
    + +
    Compare string1 with string2. Note, that + strings are compared literally (using + strcmp(3)). Therefore the string "100" is less than + "20".
    + +
    ( test_condition )
    +
    true if test_condition is true
    + +
    ! test_condition
    +
    true if test_condition is false
    + +
    test_condition1 && + test_condition2
    +
    true if both test_condition1 and + test_condition2 are true
    + +
    test_condition1 || + test_condition2
    +
    true if either test_condition1 or + test_condition2 is true
    +
    + +

    "=" and "!=" bind more tightly than + "&&" and "||". "!" binds + most tightly. Thus, the following are equivalent:

    + + + <!--#if expr="$a = test1 && $b = test2" -->
    + <!--#if expr="($a = test1) && ($b = test2)" --> +
    + +

    The boolean operators && and || + share the same priority. So if you want to bind such an operator more + tightly, you should use parentheses.

    + +

    Anything that's not recognized as a variable or an operator + is treated as a string. Strings can also be quoted: + 'string'. Unquoted strings can't contain whitespace + (blanks and tabs) because it is used to separate tokens such as + variables. If multiple strings are found in a row, they are + concatenated using blanks. So,

    + + +

    string1    string2 results in string1 string2
    +
    + and
    +
    + 'string1    string2' results in string1    string2.

    +
    + + Optimization of Boolean Expressions +

    If the expressions become more complex and slow down processing + significantly, you can try to optimize them according to the + evaluation rules:

    +
      +
    • Expressions are evaluated from left to right
    • +
    • Binary boolean operators (&& and ||) + are short circuited wherever possible. In conclusion with the rule + above that means, mod_include evaluates at first + the left expression. If the left result is sufficient to determine + the end result, processing stops here. Otherwise it evaluates the + right side and computes the end result from both left and right + results.
    • +
    • Short circuit evaluation is turned off as long as there are regular + expressions to deal with. These must be evaluated to fill in the + backreference variables ($1 .. $9).
    • +
    +

    If you want to look how a particular expression is handled, you can + recompile mod_include using the + -DDEBUG_INCLUDE compiler option. This inserts for every + parsed expression tokenizer information, the parse tree and how it is + evaluated into the output sent to the client.

    +
    +
    + + +SSIEndTag +String that ends an include element +SSIEndTag tag +SSIEndTag "-->" +server configvirtual host + +Available in version 2.0.30 and later. + + +

    This directive changes the string that mod_include + looks for to mark the end of an include element.

    + + Example + SSIEndTag "%>" + + +
    +SSIStartTag +
    + + +SSIUndefinedEcho +String displayed when an unset variable is echoed +SSIUndefinedEcho string +SSIUndefinedEcho "(none)" +server configvirtual host +directory.htaccess +All +Available in version 2.0.34 and later. + + +

    This directive changes the string that mod_include + displays when a variable is not set and "echoed".

    + + Example + SSIUndefinedEcho "<!-- undef -->" + +
    +
    + + +SSIErrorMsg +Error message displayed when there is an SSI +error +SSIErrorMsg message +SSIErrorMsg "[an error occurred while processing this +directive]" +server configvirtual host +directory.htaccess +All +Available in version 2.0.30 and later. + + +

    The SSIErrorMsg directive changes the error + message displayed when mod_include encounters an + error. For production servers you may consider changing the default + error message to "<!-- Error -->" so that + the message is not presented to the user.

    + +

    This directive has the same effect as the <!--#config + errmsg=message --> element.

    + + Example + SSIErrorMsg "<!-- Error -->" + +
    +
    + + +SSIStartTag +String that starts an include element +SSIStartTag tag +SSIStartTag "<!--#" +server configvirtual host + +Available in version 2.0.30 and later. + + +

    This directive changes the string that mod_include + looks for to mark an include element to process.

    + +

    You may want to use this option if you have 2 servers parsing the + output of a file each processing different commands (possibly at + different times).

    + + Example + SSIStartTag "<%"
    + SSIEndTag "%>" +
    + +

    The example given above, which also specifies a matching + SSIEndTag, will + allow you to use SSI directives as shown in the example + below:

    + + SSI directives with alternate start and end tags + <%printenv %> + +
    +SSIEndTag +
    + + +SSITimeFormat +Configures the format in which date strings are +displayed +SSITimeFormat formatstring +SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z" + +server configvirtual host +directory.htaccess +All +Available in version 2.0.30 and later. + + +

    This directive changes the format in which date strings are displayed + when echoing DATE environment variables. The + formatstring is as in strftime(3) from the + C standard library.

    + +

    This directive has the same effect as the <!--#config + timefmt=formatstring --> element.

    + + Example + SSITimeFormat "%R, %B %d, %Y" + + +

    The above directive would cause times to be displayed in the + format "22:26, June 14, 2002".

    +
    +
    + + +XBitHack +Parse SSI directives in files with the execute bit +set +XBitHack on|off|full +XBitHack off +server configvirtual host +directory.htaccess +Options + + +

    The XBitHack directive controls the parsing + of ordinary html documents. This directive only affects files associated + with the MIME type text/html. XBitHack can take on the following values:

    + +
    +
    off
    +
    No special treatment of executable files.
    + +
    on
    +
    Any text/html file that has the user-execute bit + set will be treated as a server-parsed html document.
    + +
    full
    +
    As for on but also test the group-execute bit. + If it is set, then set the Last-modified date of the + returned file to be the last modified time of the file. If + it is not set, then no last-modified date is sent. Setting + this bit allows clients and proxies to cache the result of + the request. + + Note +

    You would not want to use the full option, unless you assure the + group-execute bit is unset for every SSI script which might #include a CGI or otherwise produces different output on + each hit (or could potentially change on subsequent requests).

    +
    +
    +
    + +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_include.xml.ja b/trunk/docs/manual/mod/mod_include.xml.ja new file mode 100644 index 0000000000..adbfd21d8f --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.xml.ja @@ -0,0 +1,771 @@ + + + + + + + + + +mod_include +$B%5!<%P$,%Q!<%9$9$k(B html $B%I%-%e%a%s%H(B (Server Side Includes) +Base +mod_include.c +include_module +Apache 2.0 $B$+$i=PNO%U%#%k%?$H$7$F + + +

    $B$3$N%b%8%e!<%k$O%U%!%$%k$,%/%i%$%"%s%H$KAw$i$l$kA0$K=hM}$9$k%U%#%k%?$r(B + $BDs6!$7$^$9!#=hM}$NFbMF$O(B$BMWAG(B$B$H8F$P$l$kFCJL$J7A<0$N(B SGML $B%3%a%s%H$K$h$j(B + $B@)8f$5$l$^$9!#$3$l$i$NMWAG$O>r7oJ,4t$d!"B>$N%U%!%$%k$d(B + $B%W%m%0%i%`$N=PNO$N +

    +Options +AcceptPathInfo +$B%U%#%k%?(B +SSI $B%A%e!<%H%j%"%k(B + +
    + Server-Side Includes $B$rM-8z$K$9$k(B + +

    Server Side Includes $B$O(B INCLUDES + $B%U%#%k%?(B $B$K$h$jl9g!"0J2<$N%G%#%l%/%F%#%V$G$O(B Apache $B$,$=$l$i$r(B + $B%Q!<%9$7$F!"$=$N7k2L$G$-$k%I%-%e%a%s%H$K(B text/html $B$N(B + MIME $B%?%$%W$r3d$jEv$F$^$9(B:

    + + + AddType text/html .shtml
    + AddOutputFilter INCLUDES .shtml +
    + +

    $B0J2<$N%G%#%l%/%F%#%V$O(B shtml $B%U%!%$%k$N$"$k%G%#%l%/%H%j$G;XDj$5$l$F$$$k(B + $BI,MW$,$"$j$^$9(B ($BDL>o$O(B Directory $B%;%/%7%g%s$G;XDj$7$^$9$,!"(B + AllowOverride Options + $B$,@_Dj$5$l$F$$$k$H!"(B.htaccess $B%U%!%$%k$K=q$/$3$H$b$G$-$^$9(B):

    + + + Options +Includes + + +

    $B8_49@-$rJ]$D$?$a$K!"(Bserver-parsed + $B%O%s%I%i(B $B$b(B INCLUDES $B%U%#%k%?$r(B + $BM-8z$K$7$^$9!#(BMIME $B%?%$%W(B text/x-server-parsed-html $B$d(B + text/x-server-parsed-html3 $B$N%I%-%e%a%s%H$KBP$7$F$b(B + Apache $B$O(B INCLUDES $B%U%#%k%?$rM-8z$K$7$^$9(B ($B=PNO$5$l$k$b$N$O(B + MIME $B%?%$%W(B text/html $B$K$J$j$^$9(B)$B!#(B

    + +

    $B>\$7$$>pJs$O(B Tutorial on Server Side Includes.

    +
    + +
    + $B%5!<%P%5%$%I%$%s%/%k!<%I(B (SSI) $B$G$N(B PATH_INFO + +

    SSI $B$G=hM}$5$l$k%U%!%$%k$O%G%U%)%k%H$G$O(B PATH_INFO + ($B8eB3$N%Q%9L>>pJs(B) + $BIU$-$N%j%/%(%9%H$rAcceptPathInfo $B%G%#%l%/%F%#%V$G(B + PATH_INFO $BIU$-$N%j%/%(%9%H$r +

    + +
    $B4pK\MWAG(B +

    $B%I%-%e%a%s%H$O!"(BSGML $B$N%3%a%s%H$H$7$FFCJL$J%3%^%s%I$,Kd$a9~$^$l$?(B + HTML $B%I%-%e%a%s%H$H$7$F%Q!<%9$5$l$^$9!#%3%^%s%I$N9=J8$O + + + <!--#element attribute=value + attribute=value ... --> + + +

    $BCM(B ($BLuCm(B: value) $B$OFs=E0zMQId$G0O$`$N$,0lHLE*$G$9$,!"(B + $B%7%s%0%k%/%*!<%H(B (') $B$H%P%C%/%/%*!<%H(B (`) $B$b;HMQ$G$-$^$9!#(B + $BB?$/$N%3%^%s%I$OB0@-(B-$BCM(B ($BLuCm(B: attribute-value) $B$NAH$r0l$D$@$1;XDj$G$-$^$9!#(B + $B%3%a%s%H$N=*$o$j(B (-->) + $B$NA0$K$O!"(BSSI $B$N6g$N0lIt$@$H2r<!--# $B$O$^$H$a$F(B$B0l$D(B$B$N(B + $B6g$G!"6uGr$r$U$/$s$G$O$$$1$J$$$3$HCm0U$7$F$/$@$5$$!#(B

    + +

    $BMWAG(B ($BLuCm(B: element) $B$r0J2<$NI=$K<($7$^$9!#(B

    + + + + + + + + + + + + + + + + + + + +
    $BMWAG(B$B@bL@(B
    configconfigure output formats
    echoprint variables
    execexecute external programs
    fsizeprint size of a file
    flastmodprint last modification time of a file
    includeinclude a file
    printenvprint all available variables
    setset a value of a variable
    + +

    SSI $BMWAG$O(B mod_include $B0J30$N%b%8%e!<%k$G(B + $BDj5A$5$l$k$3$H$b$"$j$^$9!#exec $BMWAG$O(B + mod_cgi $B$GDs6!$5$l$F$$$F!"$3$N%b%8%e!<%k$,(B + $B%m!<%I$5$l$k>l9g$K$N$_MxMQ2DG=$H$J$j$^$9!#(B

    + +
    config $BMWAG(B +

    $B + +

    +
    echomsg (Apache 2.1 $B0J9_(B)
    +
    $B;XDj$5$l$kCM$O!"(Becho + $BMWAG$,L$Dj5A$NJQ?t$r%(%3!<$7$h$&$H$7$?:]$K!"(B + $B%/%i%$%"%s%H$KAw$i$l$k%a%C%;!<%8$K$J$j$^$9!#(B + SSIUndefinedEcho + $B%G%#%l%/%F%#%V$r>e=q$-$7$^$9!#(B
    + +
    errmsg
    +
    $B$3$NCM$,!"%I%-%e%a%s%H$N2r@OCf$K%(%i!<$,H/@8$7$?;~$K(B + $B%/%i%$%"%s%H$KAw?.$5$l$k%a%C%;!<%8$K$J$j$^$9!#(B + SSIErrorMsg + $B%G%#%l%/%F%#%V$r>e=q$-$7$^$9!#(B
    + +
    sizefmt
    +
    $B$3$NCM$O!"%U%!%$%k$N%5%$%:$rI=<($9$k:]$K;HMQ$9$k(B + $B%U%)!<%^%C%H$r@_Dj$7$^$9!#CM$O(B $B%P%$%H%+%&%s%H$N(B + bytes$B$+!"(BKb $B$d(B Mb $B$rM%@hE*$K;HMQ$9$k(B + abbrec ($BNc$($P(B 1024 $B%P%$%H$O(B "1K" $B$HI=<($5$l$^$9(B) + $B$G$9!#(B
    + +
    timefmt
    +
    $B$3$NCM$O(B strftime(3) $B%i%$%V%i%j%k!<%A%s$,(B + $BF|;~$r%W%j%s%H$9$k:]$KMQ$$$i$l$^$9!#(B
    +
    +
    + +
    echo $BMWAG(B +

    $B$3$N%3%^%s%I$O0J2<$GDj5A$5$l$F$$$k(B include + $BJQ?t(B $B$rI=<($7$^$9!#JQ?t$,@_Dj$5$l$F$$$J$$>l9g$O(B SSIUndefinedEcho $B%G%#%l%/%F%#%V$G(B + $B7hDj$5$l$k7k2L$H$J$j$^$9!#F|IU$O$=$N;~E@$G$N(B timefmt $B$K=>$C$F(B + $BI=<($5$l$^$9!#B0@-$O + +

    +
    var
    +
    $BCM$OI=<($9$kJQ?t$NL>A0$G$9!#(B
    + +
    encoding
    +

    $BJQ?t$r=PNO$9$kA0$K!"JQ?tCf$NFCJLJ8;z$r$I$N$h$&$K%(%s%3!<%I$9$k$+$r(B + $B;XDj$7$^$9!#(Bnone $B$K@_Dj$5$l$F$$$k$H!"%(%s%3!<%I$O9T$J$o$l$^$;$s!#(B + url $B$K@_Dj$5$l$F$$$k$H!"(BURL $B%(%s%3!<%I(B (%-$B%(%s%3!<%I$H$b(B + $B8F$P$l$F$$$^$9!#$3$l$O%j%s%/Ey$N(B URL $B$N;HMQ$KE,@Z$G$9(B) $B$,(B + $B9T$J$o$l$^$9!#(Becho $BMWAG$N3+;O;~$O!"%G%U%)%k%H$O(B + entity $B$K@_Dj$5$l$F$$$^$9!#$3$l$O%(%s%F%#%F%#%(%s%3!<%I(B + ($BCJMn$d%F%-%9%H$J$I$N%V%m%C%/%l%Y%k$N(B HTML $B%(%l%a%s%H$N%3%s%F%-%9%H$K(B + $BE,$7$F$$$^$9(B) $B$r9T$J$$$^$9!#$3$l$O(B encoding $BB0@-(B + $B$r2C$($k$3$H$GJQ99$G$-$^$9!#JQ99$Oencoding $BB0@-$+!"(B + $BMWAG$N=*N;$^$G8zNO$r;}$A$^$9!#(B

    + +

    encoding $BB0@-$O%(%s%3!<%I$NJQ99$r$7$?$$(B var + $B$N(B$BA0$K(B $B$"$kI,MW$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$^$?!"(BISO-8859-1 $B%(%s%3!<%G%#%s%0$G(B + $BDj5A$5$l$F$$$kFCJL$JJ8;z$@$1$,%(%s%3!<%I$5$l$^$9!#(B + $BJL$NJ8;z$N%(%s%3!<%G%#%s%0$N>l9g$O!"$3$N%(%s%3!<%G%#%s%0$O(B + $BK>$_$N7k2L$K$J$i$J$$$+$b$7$l$^$;$s!#(B

    + + + $B%/%m%9%5%$%H%9%/%j%W%F%#%s%0$NLdBj$rHr$1$k$?$a$K!"(B + $B>o$K(B$B%f!<%6$+$i$N%G!<%?$r%(%s%3!<%I$9$Y$-$G$9!#(B + +
    +
    +
    + +
    exec $BMWAG(B +

    exec $B%3%^%s%I$O;XDj$5$l$?%7%'%k%3%^%s%I$d(B CGI $B%9%/%j%W%H$r(B + $Bmod_cgi $B$,%5!<%P$KAH$_9~$^$l$F$$$k$$$J$1$l$P(B + $B$J$j$^$;$s!#(BOption + IncludesNOEXEC $B$O$3$N%3%^%s%I$rL58z$K$7$^$9!#(B + $B;HMQ2DG=$JB0@-$O + +

    +
    cgi
    +

    $BCM$O(B (%-$B%(%s%3!<%I$5$l$?(B) URL $B$r;XDj$7$^$9!#%Q%9$,(B + $B%9%i%C%7%e(B (/) $B$G;O$^$i$J$$$H$-$O!"%I%-%e%a%s%H$+$i$N(B + $BAjBP%Q%9$H$7$F07$o$l$^$9!#$3$N%Q%9$G;2>H$5$l$F$$$k%I%-%e%a%s%H$O(B + $B%5!<%P$,(B CGI $B%9%/%j%W%H$H$7$F07$C$F$$$J$/$F$b(B CGI $B%9%/%j%W%H$H$7$F(B + $B5/F0$5$l$^$9!#$?$@$7!"%9%/%j%W%H$N$"$k%G%#%l%/%H%j$G$O(B + (ScriptAlias + $B$d(B Option ExecCGI + $B$K$h$C$F(B) CGI $B%9%/%j%W%H$N;HMQ$,5v2D$5$l$F$$$kI,MW$,$"$j$^$9!#(B

    + +

    CGI $B%9%/%j%W%H$K$O!"%/%i%$%"%s%H$+$i$N85!9$N%j%/%(%9%H$N(B + PATH_INFO $B$H%/%(%j!QUERY_STRING) $B$,EO$5$l$^$9!#(B + $B$3$l$i$O(B URL $B%Q%9$H$7$FFCDj(B$B$G$-$J$$(B$B$b$N$G$9!#(B + $B%9%/%j%W%H$OI8=`(B CGI $B4D6-$K2C$($F!"(Binclude $BJQ?t$r(B + $B;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + + $BNc(B + <!--#exec cgi="/cgi-bin/example.cgi" --> + + +

    $B%9%/%j%W%H$,!"=PNO$NBe$o$j$K(B Location: $B%X%C%@$rJV$9$H!"(B + HTML $B$N%"%s%+!<(B ($BLuCm!'%j%s%/(B) $B$KJQ49$5$l$^$9!#(B

    + +

    exec cgi $B$h$j$b!"(B + include virtual + $B$NJ}$r;H$&$h$&$K$7$F$/$@$5$$!#FC$K!"(BCGI $B$X$NDI2C$N0z?t$r(B + $B%/%(%j!exec cgi $B$O(B + $B$G$-$^$;$s$,!"(Binclude virtual $B$O0J2<$N$h$&$K$7$F(B + $B2DG=$G$9!#(B

    + + + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> + +
    + +
    cmd
    +

    $B%5!<%P$O;XDj$5$l$?J8;zNs$r(B /bin/sh $B$r;H$C$F(B + $Bo$N(B CGI $BJQ?t$K2C$($F(B include $BJQ?t(B$B$b;H$&$3$H$,$G$-$^$9!#(B

    + +

    $B$[$H$s$I$N>l9g!"(B#include + virtual $B$r;H$&J}$,(B #exec cgi $B$d(B #exec + cmd $B$r;H$&$h$j$bNI$$$G$9!#A0#include virtual) + $B$OI8=`$N(B Apache $B$N%5%V%j%/%(%9%H5!9=$r;H$C$F%U%!%$%k$d%9%/%j%W%H$N(B + $B=PNO$r + +

    $B$5$i$K!"(BWin32 $B$N$h$&$J$$$/$D$+$N%W%i%C%H%U%)!<%`$d!"(Bsuexec $B$r;H$C$F$$$k(B unix $B$G$O!"(B + exec $B%G%#%l%/%F%#%V$N%3%^%s%I$K(B + $B0z?t$rEO$7$?$j!"%3%^%s%I$K6uGr$rF~$l$k$3$H$O$G$-$^$;$s!#(B + $B$G$9$+$i!"0J2<$N$b$N$O(B unix $B$N(B suexec $B$G$J$$@_Dj$G$OF0:n$7$^$9$,!"(B + Win32 $B$d(B suexec $B$r;H$C$F$$$k(B unix $B$G$O4|BT$7$?7k2L$K$O$J$j$^$;$s(B:

    + + + <!--#exec cmd="perl /path/to/perlscript arg1 arg2" --> + +
    +
    +
    + +
    fsize $BMWAG(B +

    $B$3$N%3%^%s%I$O;XDj$5$l$?%U%!%$%k$NBg$-$5$r(B sizefmt $B$N(B + $B=q<0;XDj$K4p$E$$$F=PNO$7$^$9!#B0@-$O + +

    +
    file
    +
    $BCM$O2r@O$5$l$F$$$k%I%-%e%a%s%H$NB8:_$9$k%G%#%l%/%H%j$+$i$N(B + $BAjBP%Q%9$G$9!#(B
    + +
    virtual
    +
    $BCM$O(B (% $B%(%s%3!<%I$5$l$?(B) URL-path $B$G$9!#%9%i%C%7%e(B (/) $B$G(B + $B;O$^$i$J$$$H$-$O%I%-%e%a%s%H$+$i$NAjBP%Q%9$H$7$F07$o$l$^$9!#(B + CGI $B$N=PNO$N%5%$%:$O%W%j%s%H(B$B$5$l$^$;$s(B$B!#(BCGI + $B%9%/%j%W%H<+BN$N%5%$%:$,%W%j%s%H$5$l$k$3$H$KCm0U$7$F$/$@$5$$!#(B
    +
    +
    + +
    flastmod $BMWAG(B +

    $B$3$N%3%^%s%I$O;XDj$5$l$?%U%!%$%k$N:G=*=$@5;~9o$r(B + timefmt $B=q<0;XDj$K=>$C$FI=<($7$^$9!#(B + $B;XDj2DG=$JB0@-$O(B fsize $B%3%^%s%I$HF1$8$G$9!#(B

    +
    + +
    include $BMWAG(B +

    $B$3$N%3%^%s%I$OJL$NJ8=q$d%U%!%$%k$N%F%-%9%H$r2r@O$7$F$$$k%U%!%$%k$K(B + $BA^F~$7$^$9!#A^F~$5$l$k%U%!%$%k$O%"%/%;%9@)8f$N4IM}2<$K$"$j$^$9!#(B + $B2r@O$7$F$$$k%U%!%$%k$NB8:_$9$k%G%#%l%/%H%j$K(B + Option IncludesNOEXEC + $B$,@_Dj$5$l$F$$$k>l9g!"(Btext MIME $B%?%$%W(B (text/plain, + text/html $BEy(B) $B$N%I%-%e%a%s%H$N$_%$%s%/%k!<%I$,9T$J$o$l$^$9!#(B + $B$=$NB>$N>l9g$O!"%/%(%j! + +

    $BB0@-$,J8=q$N0LCV$r;XDj$7$^$9!#(Binclude $B%3%^%s%I$KM?$($i$l$?$=$l$>$l$N(B + $BB0@-$KBP$7$FA^F~:n6H$,9T$J$o$l$^$9!#M-8z$JB0@-$O + +

    +
    file
    +
    $BCM$O2r@O$5$l$F$$$k%I%-%e%a%s%H$NB8:_$9$k%G%#%l%/%H%j$+$i$N(B + $BAjBP%Q%9$G$9!#(B + ../ $B$r4^$s$G$$$?$j!"@dBP%Q%9$r;XDj$7$?$j$O$G$-$^$;$s!#(B + $B$G$9$+$i!"%I%-%e%a%s%H%k!<%H$N30$K$"$k%U%!%$%k$d!"%G%#%l%/%H%j9=B$$G(B + $B>e0L$K$"$k%U%!%$%k$rA^F~$9$k$3$H$O$G$-$^$;$s!#(B + $B>o$K$3$NB0@-$h$j$O!"(Bvirtual $BB0@-$r;H$&$h$&$K$7$F$/$@$5$$!#(B +
    + +
    virtual
    +

    $BCM$O2r@O$5$l$F$$$k%I%-%e%a%s%H$+$i$N(B (% $B%(%s%3!<%I$5$l$?(B) URL + $B$G$9!#(BURL $B$K$O%9%-!<%`$d%[%9%HL>$r4^$a$k$3$H$O$G$-$^$;$s!#%Q%9$H!"(B + $B$b$7$"$l$P%/%(%j!l9g$O!"%I%-%e%a%s%H$+$i$NAjBP%Q%9$H$7$F07$o$l$^$9!#(B

    + +

    URL $B$OB0@-$+$i:n$i$l!"$=$N(B URL $B$r%/%i%$%"%s%H$,%"%/%;%9$7$?$H$-$K(B + $B=PNO$5$l$kFbMF$,2r@O8e$N=PNO$K4^$a$i$l$^$9!#$G$9$+$i!"A^F~$5$l$k(B + $B%U%!%$%k$OF~$l;R9=B$$K$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B;XDj$5$l$?(B URL $B$,(B CGI $B%W%m%0%i%`$G$"$C$?>l9g$O!"(B + $B%W%m%0%i%`$, + + + <!--#include virtual="/cgi-bin/example.cgi?argument=value" --> + + +

    HTML $B%I%-%e%a%s%H$K(B CGI $B%W%m%0%i%`$N=PNO$r4^$a$kJ}K!$H$7$F$O!"(B + include virtual $B$NJ}$,(B exec cgi $B$h$j$b(B + $B9%$^$7$$J}K!$G$9!#(B

    +
    +
    +
    + +
    printenv $BMWAG(B +

    $B$3$l$O!"B8:_$9$k$9$Y$F$NJQ?t$H$=$NCM$rI=<($7$^$9!#(BApache 1.3.12 $B$+$i!"(B + $BFCJL$JJ8;z$O=PNO$5$l$kA0$K%(%s%F%#%F%#%(%s%3!<%I(B ($B>\:Y$O(B echo $BMWAG$r;2>H(B) + $B$5$l$k$h$&$K$J$j$^$7$?!#B0@-$O$"$j$^$;$s!#(B

    + + $BNc(B + <!--#printenv --> + +
    + +
    set $BMWAG(B +

    $B$3$l$OJQ?t$NCM$r@_Dj$7$^$9!#B0@-$O + +

    +
    var
    +
    $B@_Dj$9$kJQ?t$NL>A0!#(B
    + +
    value
    +
    $BJQ?t$K@_Dj$9$kCM!#(B
    +
    + + $BNc(B + <!--#set var="category" value="help" --> + +
    +
    + +
    + Include $BJQ?t(B + +

    $BI8=`(B CGI $B4D6-$NJQ?t$K2C$($F!"(Becho $B%3%^%s%I$d!"(B + if $B$d(B elif, $B$=$l$K%I%-%e%a%s%H$+$i8F$S=P$5$l$k(B + $B$9$Y$F$N%W%m%0%i%`$+$i;HMQ$G$-$kJQ?t$,$"$j$^$9!#(B

    + +
    +
    DATE_GMT
    +
    $B%0%j%K%C%8I8=`;~$K$h$k8=:_;~9o!#(B
    + +
    DATE_LOCAL
    +
    $B%m!<%+%k$NI8=`;~$K$h$k8=:_;~9o!#(B
    + +
    DOCUMENT_NAME
    +
    $B%f!<%6$,%j%/%(%9%H$7$?(B ($B%G%#%l%/%H%j$r=|$$$?(B) $B%U%!%$%kL>!#(B
    + +
    DOCUMENT_URI
    +
    $B%f!<%6$,%j%/%(%9%H$7$?(B (% $B%(%s%3!<%I$5$l$?(B) URL-path$B!#(B + $BA^F~%U%!%$%k$,F~$l;R$K$J$C$F$$$k>l9g$O!"2r@O$5$l$F$$$k(B + $B%I%-%e%a%s%H$N(B URL $B$G$O(B$B$J$$(B$B$3$H$KCm0U$7$F$/$@$5$$!#(B
    + +
    LAST_MODIFIED
    +
    $B%f!<%6$,%j%/%(%9%H$7$?%I%-%e%a%s%H$N:G=*=$@5;~9o!#(B
    + +
    QUERY_STRING_UNESCAPED
    +
    $B%/%(%j!l9g!"$3$NJQ?t$K$O(B (%-$B%G%3!<%I$5$l$?(B) + $B%/%(%j!$B%(%9%1!<%W(B$B$5$l$F$$$^$9(B (& + $B$H$$$C$?FCA0$KCV$+$l$^$9(B)$B!#(B
    +
    +
    + +
    $BJQ?tCV49(B + +

    $BJQ?tCV49$O$?$$$F$$$N>l9g(B SSI $B%G%#%l%/%F%#%V$N0z?t$H$7$FBEEv$J>l=j$K$"$k(B + $B0zMQId$G0O$^$l$?J8;zNsCf$G9T$J$o$l$^$9!#$3$l$K3:Ev$9$k$b$N$K$O!"(B + config, + exec, flastmod, fsize, + include, echo, set $B$N(B + $B3F%G%#%l%/%F%#%V$H!">r7oJ,4tMQ$N%*%Z%l!<%?$X$N0z?t$,$"$j$^$9!#(B + $B%I%k5-9f$O%P%C%/%9%i%C%7%e$r;H$&$3$H$G;H$&$3$H$,$G$-$^$9(B:

    + + + <!--#if expr="$a = \$test" --> + + +

    $BJQ?tL>$H$7$F$_$J$5$l$kJ8;zNs$NCf$GJQ?t$X$N;2>H$rCV49$9$kI,MW$,$"$k$H$-$O!"(B + $B%7%'%k$G$NJQ?tCV49$N$h$&$K!"Cf3g8L$G3g$k$3$H$G6hJL$9$k$3$H$,$G$-$^$9(B:

    + + + <!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" --> + + +

    $B$3$NNc$G$O!"(BREMOTE_HOST $B$,(B + "X" $B$G(B REQUEST_METHOD $B$,(B + "Y" $B$N$H$-$KJQ?t(B Zed $B$r(B "X_Y" + $B$K@_Dj$7$^$9!#(B

    + +

    $B0J2<$NNc$G$O!"(BDOCUMENT_URI $B$,(B /foo/file.html + $B$N$H$-$K(B "in foo" $B$r!"(B/bar/file.html $B$N$H$-$K(B "in bar" $B$r!"(B + $B$I$A$i$G$b$J$$$H$-$K$O(B "in neither" $B$rI=<($7$^$9!#(B

    + + + <!--#if expr='"$DOCUMENT_URI" = "/foo/file.html"' -->
    + + in foo
    +
    + <!--#elif expr='"$DOCUMENT_URI" = "/bar/file.html"' -->
    + + in bar
    +
    + <!--#else -->
    + + in neither
    +
    + <!--#endif --> +
    +
    + +
    + $B%U%m!<@)8fMWAG(B + +

    $B4pK\E*$J%U%m!<%3%s%H%m!<%kMWAG$O + + + <!--#if expr="test_condition" -->
    + <!--#elif expr="test_condition" -->
    + <!--#else -->
    + <!--#endif --> +
    + +

    if $BMWAG$O%W%m%0%i%_%s%08@8l$N(B + if $BJ8$HF1$8$h$&$KF0:n$7$^$9!#>r7o$,I>2A$5$l!"7k2L$,??$G$"$l$Pelif $B$+(B else $B$+(B endif + $BMWAG$^$G$NJ8;zNs$,=PNO$KA^F~$5$l$^$9!#(B

    + +

    elif $B$d(B else $BJ8$O(B test_condition + $B$,56$N$H$-$K%F%-%9%H$r=PNO$KA^F~$9$k$?$a$K;H$o$l$^$9!#(B + $B$3$l$i$NMWAG$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    + +

    endif $BMWAG$O(B if + $BMWAG$r=*N;$5$;$^$9!#$3$NMWAG$OI,?\$G$9!#(B

    + +

    test_condition $B$O0J2<$N$I$l$+$G$9(B:

    + +
    +
    string
    +
    string $B$,6u$G$J$$>l9g$K??$G$9(B
    + +
    string1 = string2
    + string1 == string2
    + string1 != string2
    + +

    string1 $B$H(B string2 $B$rHf3S$7$^$9!#(B + string2 $B$,(B /string/ + $B$H$$$&7A<0$G$"$l$P!"@55,I=8=$H$7$FHf3S$5$l$^$9!#@55,I=8=$O(B + PCRE $B%(%s%8%s$Gperl 5 $B$HF1$89=J8$r;HMQ$7$^$9!#(B + == $B$OC1$K(B = $B$NJLL>$G!"$^$C$?$/F1$8F0:n$r(B + $B$7$^$9!#(B

    + +

    $B@5$N%^%C%A%s%0(B (= $B$^$?$O(B ==) $B$N>l9g$O!"(B + $B@55,I=8=$G%0%k!<%WJ,$1$5$l$?%Q!<%D$r%-%c%W%A%c$9$k$3$H$,$G$-$^$9!#(B + $B%-%c%W%A%c$5$l$?ItJ,$OFC$1 .. $9 + $B$K3JG<$5$l$^$9!#(B

    + + $BNc(B + <!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
    + + <!--#set var="session" value="$1" -->
    +
    + <!--#endif --> +
    +
    + +
    string1 < string2
    + string1 <= string2
    + string1 > string2
    + string1 >= string2
    + +
    string1 $B$H(B string2 $B$rHf3S$7$^$9!#(B + $BJ8;zNs$H$7$F(B$BHf3S$5$l$k(B (strcmp(3) $B$r;HMQ(B) + $B$3$H$KCm0U$7$F$/$@$5$$!#$G$9$+$i!"J8;zNs(B "100" $B$O(B "20" + $B$h$j$b>.$5$$$3$H$K$J$j$^$9!#(B
    + +
    ( test_condition )
    +
    test_condition $B$,??$N$H$-!"??(B
    + +
    ! test_condition
    +
    test_condition $B$,56$N$H$-!"??(B
    + +
    test_condition1 && + test_condition2
    +
    test_condition1 $B$+$D(B + test_condition2 $B$,??$N$H$-!"??(B
    + +
    test_condition1 || + test_condition2
    +
    test_condition1 $B$^$?$O(B + test_condition2 $B$,??$N$H$-!"??(B
    +
    + +

    "=" $B$H(B "!=" $B$NJ}$,(B "&&" $B$h$j(B + $B$-$D$/B+G{$7$^$9!#(B"!" $B$NB+G{$,0lHV$-$D$/$J$C$F$$$^$9!#(B + $B$G$9$+$i0J2<$NFs$D$OEy2A$G$9(B:

    + + + <!--#if expr="$a = test1 && $b = test2" -->
    + <!--#if expr="($a = test1) && ($b = test2)" --> +
    + +

    $B??56CM%*%Z%l!<%?(B && $B$H(B || + $B$OF1$8M%@hEY$G$9!#(B + $B$3$l$i$N%*%Z%l!<%?$G0lJ}$K$h$j6/$$M%@hEY$r$D$1$?$$>l9g$K$O!"(B + $B3g8L$r;H$&I,MW$,$"$j$^$9!#(B

    + +

    $BJQ?t$d%*%Z%l!<%?$H$7$FG'<1$5$l$J$$$b$N$O$9$Y$FJ8;zNs$H$7$F(B + $B07$o$l$^$9!#J8;zNs$O0zMQId$G0O$`$3$H$b$G$-$^$9(B: 'string' + $B$N$h$&$K!#0zMQId$G0O$^$l$F$$$J$$J8;zNs$K$O6uGr(B ($B%9%Z!<%9$H%?%V(B) + $B$r4^$a$k$3$H$O$G$-$^$;$s!#$=$l$i$OJQ?t$J$I$N6g$rJ,N%$9$k$?$a$K(B + $B;H$o$l$F$$$k$+$i$G$9!#J#?t$NJ8;zNs$,B3$$$F$$$k$H$-$O!"(B + $B6uGr$r4V$KF~$l$F0l$D$K$/$C$D$1$i$l$^$9!#$G$9$+$i!"(B

    + + +

    string1    string2 $B$O(B string1 string2 $B$K$J$j$^$9!#(B
    +
    + $B$^$?!"(B
    +
    + 'string1    string2' $B$O(B string1    string2 + $B$K$J$j$^$9!#(B

    +
    + + $B??56CMI=8=$N:GE,2=(B +

    $B<0$,$b$C$HJ#;($K$J$j!"=hM}$NB.EYDc2<$,82Cx$K$J$C$?>l9g$O!"(B + $BI>2A%k!<%k$K=>$C$F:GE,2=$7$F$_$k$HNI$$$G$7$g$&!#(B

    +
      +
    • $BI>2A$O:8$+$i1&$K8~$+$C$F9T$o$l$^$9!#(B
    • +
    • $BFsCM??56CM%*%Z%l!<%?(B (&& $B$H(B ||) + $B$O!"=PMh$k8B$jC;MmI>2A$5$l$^$9!#$D$^$j7k2L$H$7$F>e5-$N%k!<%k$O!"(B + mod_include $B$,:8$NI>2A<0$rI>2A$7$^$9!#(B + $B:8B&$G7k2L$r==J,7hDj$G$-$k>l9g$O!"I>2A$O$=$3$GDd;_$7$^$9!#(B + $B$=$&$G$J$$>l9g$O1&B&$rI>2A$7$F!":8$H1&$NN>J}$+$i7k2L$r7W;;$7$^$9!#(B
    • +
    • $BC;MmI>2A$OI>2A$NBP>]$K@55,I=8=$,4^$^$l$k>l9g!"%*%U$K$J$j$^$9!#(B + $B8eJ};2>H$9$kJQ?t(B ($1 .. $9) + $B$rKd$a$k$?$a$K!"2A$9$kI,MW$,$"$k$+$i$G$9!#(B
    • +
    +

    $BFCDj$N<0$,$I$N$h$&$K07$o$l$k$+$rCN$j$?$$>l9g$O!"(B + -DDEBUG_INCLUDE $B%3%s%Q%$%i%*%W%7%g%s$rIU$1$F(B + mod_include $B$r%j%3%s%Q%$%k$9$k$HNI$$$G$7$g$&!#(B + $B$3$l$K$h$j!"A4$F$N%Q!<%9$5$l$?<0$KBP$7$F!";z6g2r@O>pJs!"(B + $B%Q!<%9%D%j!<$H!"(B + $B$=$l$,$I$N$h$&$K%/%i%$%"%s%H$KAw$i$l$?=PNO$^$GI>2A$5$l$?$+$r(B + $BA^F~$7$^$9!#(B

    +
    +
    + + +SSIEndTag +include $BMWAG$r=*N;$5$;$kJ8;zNs(B +SSIEndTag tag +SSIEndTag "-->" +server configvirtual host + +2.0.30 $B0J9_$GMxMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O(B mod_include $B$,C5$9!"(B + include $BMWAG$N=*N;$r<($9J8;zNs$rJQ99$7$^$9!#(B

    + + $BNc(B + SSIEndTag "%>" + + +
    +SSIStartTag +
    + + +SSIUndefinedEcho +$BL$Dj5A$NJQ?t$,(B echo $B$5$l$?$H$-$KI=<($5$l$kJ8;zNs(B +SSIUndefinedEcho string +SSIUndefinedEcho "(none)" +server configvirtual host +directory.htaccess +All +2.0.34 $B0J9_$GMxMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$OJQ?t$,Dj5A$5$l$F$$$J$$$K$b4X$o$i$:(B + "echo" $B$5$l$?$H$-$K(B mod_include + $B$,I=<($9$kJ8;zNs$rJQ99$7$^$9!#(B

    + + $BNc(B + SSIUndefinedEcho "<!-- undef -->" + +
    +
    + + +SSIErrorMsg +SSI $B$N%(%i!<$,$"$C$?$H$-$KI=<($5$l$k%(%i!<%a%C%;!<%8(B +SSIErrorMsg message +SSIErrorMsg "[an error occurred while processing this +directive]" +server configvirtual host +directory.htaccess +All +$B%P!<%8%g%s(B 2.0.30 $B0J9_$G;HMQ2DG=(B + + +

    SSIErrorMsg $B%G%#%l%/%F%#%V$O(B mod_include + $B$,%(%i!<$,5/$3$C$?$H$-$KI=<($9$k%a%C%;!<%8$rJQ99$7$^$9!#%W%m%@%/%7%g%s%5!<%P$G$O(B + $B%a%C%;!<%8$,%f!<%6$KI=<($5$l$J$$$h$&$K$9$k$?$a$K(B + $B%G%U%)%k%H%(%i!<%a%C%;!<%8$r(B "<!-- Error -->" + $B$KJQ$($k$H$$$&$h$&$J$3$H$r9M$($k$+$b$7$l$^$;$s!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O(B <!--#config + errmsg=message --> $BMWAG$HF1$88z2L$K$J$j$^$9!#(B

    + + $BNc(B + SSIErrorMsg "<!-- Error -->" + +
    +
    + + +SSIStartTag +include $BMWAG$r3+;O$9$kJ8;zNs(B +SSIStartTag tag +SSIStartTag "<!--#" +server configvirtual host + +$B%P!<%8%g%s(B 2.0.30 $B0J9_$G;HMQ2DG=(B + + + +

    $B$3$N%G%#%l%/%F%#%V$O(B mod_include $B$,C5$9!"(Binclude + $BMWAG$N3+;O$r<($9J8;zNs$rJQ99$7$^$9!#(B

    + +

    $BFs$D$N%5!<%P$G(B ($B$b$7$+$9$k$HJL!9$NCJ3,$G(B) $B%U%!%$%k$N=PNO$r2r@O$7$F$$$F!"(B + $B$=$l$>$l$K0c$&%3%^%s%I$r=hM}$5$;$?$$!"(B + $B$H$$$&$h$&$J$H$-$K$3$N%*%W%7%g%s$r;H$$$^$9!#(B

    + + $BNc(B + SSIStartTag "<%"
    + SSIEndTag "%>" +
    + +

    $B>e$NNc$N$h$&$KBP1~$9$k(B + SSIEndTag $B$rJ;$;$F;H$&$H!"(B + $B2<$K<($9Nc$N$h$&$K(B SSI $B%G%#%l%/%F%#%V$r;H$($^$9(B:

    + + $B0c$&3+;O$H=*N;$N%?%0$r;H$C$?(B SSI $B%G%#%l%/%F%#%V(B + <%printenv %> + +
    +SSIEndTag +
    + + +SSITimeFormat +$BF|IU$1$r8=$9J8;zNs$N=q<0$r@_Dj$9$k(B +SSITimeFormat formatstring +SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z" + +server configvirtual host +directory.htaccess +All +2.0.30 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O(B DATE $B4D6-JQ?t$r(B echo $B$7$FF|IU$r8=$9J8;zNs$,(B + $BI=<($5$l$k$H$-$N=q<0$rJQ99$7$^$9!#(Bformatstring $B$O(B + C $BI8=`%i%$%V%i%j$N(B strftime(3) $B$HF1$87A<0$G$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O(B <!--#config + timefmt=formatstring --> $BMWAG$HF1$88z2L$K$J$j$^$9!#(B

    + + $BNc(B + SSITimeFormat "%R, %B %d, %Y" + + +

    $B>e$N%G%#%l%/%F%#%V$G$O!"F|IU$O(B "22:26, June 14, 2002" $B$H$$$&(B + $B7A<0$GI=<($5$l$^$9!#(B

    +
    +
    + + +XBitHack +$B +XBitHack on|off|full +XBitHack off +server configvirtual host +directory.htaccess +Options + + +

    XBitHack $B%G%#%l%/%F%#%V$ODL>o$N(B HTML + $B%I%-%e%a%s%H$N2r@O$r@)8f$7$^$9!#$3$N%G%#%l%/%F%#%V$O(B MIME $B%?%$%W(B + text/html $B$H4XO"IU$1$i$l$F$$$k%U%!%$%k$K$N$_1F6A$7$^$9!#(B + XBitHack $B$O0J2<$NCM$r$H$k$3$H$,$G$-$^$9!#(B

    + +
    +
    off
    +
    $B + +
    on
    +
    $B%f!<%6$Ntext/html + $B%U%!%$%k$OA4$F%5!<%P$G2r@O$9$k(B html $B%I%-%e%a%s%H$H$7$F07$o$l$^$9!#(B
    + +
    full
    +
    on $B$HF1MM$G$9$,!"%0%k!<%WLast-modified $B$N(B + $BF|IU$r%U%!%$%k$N:G=*=$@5;~9o$K$7$^$9!#$=$l$,@_Dj$5$l$F$$$J$$$H$-$O!"(B + last-modified $B$NF|IU$OAw$i$l$^$;$s!#$3$N%S%C%H$r@_Dj$9$k$H!"(B + $B%/%i%$%"%s%H$d%W%m%-%7$,%j%/%(%9%H$r%-%c%C%7%e$G$-$k$h$&$K$J$j$^$9!#(B + + $BCm0U(B $BB>$N(B CGI $B$r(B #include + $B$9$k$+$b$7$l$J$$$b$N$d!"3F%"%/%;%9$KBP$7$F0c$&=PNO$r@8@.$9$k(B + ($B$b$7$/$O8e$N%j%/%(%9%H$GJQ$o$k$+$b$7$l$J$$$b$N(B) + $B$9$Y$F$N(B SSI $B%9%/%j%W%H$KBP$7$F%0%k!<%Wl9g$O!"(Bfull $B$O;H$o$J$$J}$,NI$$(B + $B$G$7$g$&!#(B +
    +
    + +
    +
    + + + diff --git a/trunk/docs/manual/mod/mod_include.xml.meta b/trunk/docs/manual/mod/mod_include.xml.meta new file mode 100644 index 0000000000..d3ac678b40 --- /dev/null +++ b/trunk/docs/manual/mod/mod_include.xml.meta @@ -0,0 +1,12 @@ + + + + mod_include + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_info.html b/trunk/docs/manual/mod/mod_info.html new file mode 100644 index 0000000000..849911036a --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.html @@ -0,0 +1,11 @@ +URI: mod_info.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_info.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_info.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_info.html.en b/trunk/docs/manual/mod/mod_info.html.en new file mode 100644 index 0000000000..299384dc14 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.html.en @@ -0,0 +1,194 @@ + + + +mod_info - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_info

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Provides a comprehensive overview of the server +configuration
    Status:Extension
    Module Identifier:info_module
    Source File:mod_info.c
    +

    Summary

    + +

    To configure mod_info, add the following to your + httpd.conf file.

    + +

    + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +

    + +

    You may wish to use mod_access inside the + <Location> + directive to limite access to your server configuration + information:

    + +

    + <Location /server-info>
    + + SetHandler server-info
    + Order deny,allow
    + Deny from all
    + Allow from yourcompany.com
    +
    + </Location> +

    + +

    Once configured, the server information is obtained by + accessing http://your.host.example.com/server-info

    +
    + +
    top
    +
    +

    Security Issues

    +

    Once mod_info is loaded into the server, its + handler capability is available in all configuration + files, including per-directory files (e.g., + .htaccess). This may have security-related + ramifications for your site.

    + +

    In particular, this module can leak sensitive information + from the configuration directives of other Apache modules such as + system paths, usernames/passwords, database names, etc. Therefore, + this module should only be + used in a controlled environment and always with caution.

    + +

    You will probably want to use mod_authz_host + to limit access to your server configuration information.

    + +

    Access control

    + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # Allow access from server itself
    + Allow from 127.0.0.1
    + # Additionally, allow access from local workstation
    + Allow from 192.168.1.17
    +
    + </Location> +

    +
    top
    +
    +

    Selecting the information shown

    +

    By default, the server information includes a list of + all enabled modules, and for each module, a description of + the directives understood by that module, the hooks implemented + by that module, and the relevant directives from the current + configuration.

    + +

    Other views of the configuration information are available by + appending a query to the server-info request. For + example, http://your.host.example.com/server-info?config + will show all configuration directives.

    + +
    +
    ?<module-name>
    +
    Only information relevant to the named module
    +
    ?config
    +
    Just the configuration directives, not sorted by module
    +
    ?hooks
    +
    Only the list of Hooks each module is attached to
    +
    ?list
    +
    Only a simple list of enabled modules
    +
    ?server
    +
    Only the basic server information
    +
    +
    top
    +
    +

    Known Limitations

    +

    mod_info provides its information by reading the + parsed configuration, rather than reading the original configuration + file. There are a few limitations as a result of the way the parsed + configuration tree is created:

    +
      +
    • Directives which are executed immediately rather than being + stored in the parsed configuration are not listed. These include + ServerRoot, + LoadModule, and + LoadFile.
    • +
    • Directives which control the configuration file itself, such as + Include, + <IfModule> and + <IfDefine> are not + listed, but the included configuration directives are.
    • +
    • Comments are not listed. (This may be considered a feature.)
    • +
    • Configuration directives from .htaccess files are + not listed (since they do not form part of the permanent server + configuration).
    • +
    • Container directives such as + <Directory> + are listed normally, but mod_info cannot figure + out the line number for the closing + </Directory>.
    • +
    • Directives generated by third party modules such as mod_perl + might not be listed.
    • +
    +
    +
    top
    +

    AddModuleInfo Directive

    + + + + + + + +
    Description:Adds additional information to the module +information displayed by the server-info handler
    Syntax:AddModuleInfo module-name string
    Context:server config, virtual host
    Status:Extension
    Module:mod_info
    Compatibility:Apache 1.3 and above
    +

    This allows the content of string to be shown as + HTML interpreted, Additional Information for + the module module-name. Example:

    + +

    + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_info.html.ja.euc-jp b/trunk/docs/manual/mod/mod_info.html.ja.euc-jp new file mode 100644 index 0000000000..e20fbae138 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.html.ja.euc-jp @@ -0,0 +1,188 @@ + + + +mod_info - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_info

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤ÎÀßÄê¤ÎÊñ³çŪ¤Ê³µ´Ñ¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:info_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_info.c
    +

    ³µÍ×

    + +

    mod_info ¤òÀßÄꤹ¤ë¤Ë¤Ï¡¢°Ê²¼¤ò httpd.conf + ¥Õ¥¡¥¤¥ë¤Ë²Ã¤¨¤Þ¤¹¡£

    + +

    + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +

    + +

    <Location> + ¤ÎÃæ¤Ç mod_access ¤ò»È¤Ã¤Æ¡¢¥µ¡¼¥ÐÀßÄê¾ðÊó¤Ø¤Î + ¥¢¥¯¥»¥¹¤òÀ©¸Â¤·¤¿¤¤¤È»×¤¦¤«¤â¤·¤ì¤Þ¤»¤ó :

    + +

    + <Location /server-info>
    + + SetHandler server-info
    + Order deny,allow
    + Deny from all
    + Allow from yourcompany.com
    +
    + </Location> +

    + +

    °ìöÀßÄꤹ¤ë¤È¡¢http://your.host.example.com/server-info + ¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤Ç¥µ¡¼¥Ð¤Î¾ðÊó¤òÆÀ¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    Security Issues

    +

    °ìö mod_info ¤¬¥µ¡¼¥Ð¤ËÆɤ߹þ¤Þ¤ì¤ë¤È¡¢ + Ä󶡤·¤Æ¤¤¤ë¥Ï¥ó¥É¥éµ¡Ç½¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤ÎÀßÄê¥Õ¥¡¥¤¥ë (Î㤨¤Ð + .htaccess) ¤ò´Þ¤à ¤¹¤Ù¤Æ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤òÍ­¸ú¤Ë¤¹¤ë¤È¤­¤Ï¥»¥­¥å¥ê¥Æ¥£¤ÎÌäÂê¤ò¹Íθ¤¹¤ëɬÍפ¬ + ¤¢¤ë¤Ç¤·¤ç¤¦¡£

    + +

    Æäˡ¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥·¥¹¥Æ¥à¥Ñ¥¹¡¢¥æ¡¼¥¶Ì¾/¥Ñ¥¹¥ï¡¼¥É¡¢ + ¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾¤Ê¤É¡¢Â¾¤Î Apache ¥â¥¸¥å¡¼¥ë¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤«¤é + ¥»¥­¥å¥ê¥Æ¥£¾åÈù̯¤Ê¾ðÊó¤òϳ¤é¤¹²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¤­¤Á¤ó¤È¥¢¥¯¥»¥¹À©¸æ¤µ¤ì¤¿´Ä¶­¤Ç¤Î¤ß¡¢ + Ãí°Õ¤·¤Æ»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ÀßÄê¾ðÊó¤Ø¤Î¥¢¥¯¥»¥¹¤òÀ©¸Â¤¹¤ë¤¿¤á¤Ë¡¢mod_authz_host ¤ò + »È¤¦¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    ¥¢¥¯¥»¥¹À©¸æ

    + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # Allow access from server itself
    + Allow from 127.0.0.1
    + # Additionally, allow access from local workstation
    + Allow from 192.168.1.17
    +
    + </Location> +

    +
    top
    +
    +

    ɽ¼¨¤µ¤ì¤ë¾ðÊó¤ÎÁªÂò

    +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥µ¡¼¥Ð¾ðÊó¤Ï¤¹¤Ù¤Æ¤ÎÍ­¸ú¤Ê¥â¥¸¥å¡¼¥ë¤È¡¢ + ³Æ¥â¥¸¥å¡¼¥ë¤Ë¤Ä¤¤¤Æ¡¢¥â¥¸¥å¡¼¥ë¤¬Íý²ò¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + ¼ÂÁõ¤·¤Æ¤¤¤ë¡¢¥Õ¥Ã¥¯¡¢¸½»þÅÀ¤Ç¤ÎÀßÄê¤Î´ØÏ¢¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë + ¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    server-info ¥ê¥¯¥¨¥¹¥È¤Ø¥¯¥¨¥ê¡¼¤òÄɲ乤뤳¤È¤Ç¡¢ + ÀßÄê¾ðÊó¤Î¾¤Îɽ¼¨·Á¼°¤òÁª¤Ö¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢ + http://your.host.example.com/server-info?config ¤Ï + ¤¹¤Ù¤Æ¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òɽ¼¨¤·¤Þ¤¹¡£

    + +
    +
    ?<module-name>
    +
    »ØÄꤵ¤ì¤¿¥â¥¸¥å¡¼¥ë¤Ë´ØÏ¢¤¹¤ë¾ðÊó¤Î¤ß
    +
    ?config
    +
    ¥â¥¸¥å¡¼¥ë¤Ç¥½¡¼¥È¤»¤º¤Ë¡¢ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤ß
    +
    ?hooks
    +
    ³Æ¥â¥¸¥å¡¼¥ë¤¬»ÈÍѤ¹¤ë¥Õ¥Ã¥¯¤Î¤ß
    +
    ?list
    +
    Í­¸ú¤Ê¥â¥¸¥å¡¼¥ë¤Î´Êñ¤Ê¥ê¥¹¥È¤Î¤ß
    +
    ?server
    +
    ´ðËÜ¥µ¡¼¥Ð¾ðÊó¤Î¤ß
    +
    +
    top
    +
    +

    ´ûÃΤÎÀ©¸Â

    +

    mod_info ¤Ï¡¢¸µ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤òÆɤà¤Î¤Ç¤Ï¤Ê¤¯¡¢ + ´û¤Ë¥Ñ¡¼¥¹¤µ¤ì¤¿ÀßÄê¤òÆɤ߹þ¤à¤³¤È¤Ç¾ðÊó¤òÄ󶡤·¤Þ¤¹¡£½¾¤Ã¤Æ¡¢ + ¥Ñ¡¼¥¹ºÑ¤ß¤ÎÀßÄê¾ðÊó¤ÎÌÚ¤¬À¸À®¤µ¤ì¤ëÊýË¡¤Ë¤è¤ëÀ©¸Â¤¬¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹:

    +
      +
    • ¥Ñ¡¼¥¹¤µ¤ì¤¿ÀßÄê¤ËÊݸ¤µ¤ì¤º¤Ë¡¢¤¹¤°¤Ë¼Â¹Ô¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + °ìÍ÷¤Ë¸½¤ì¤Þ¤»¤ó¡£¤³¤ì¤Ë¤Ï + ServerRoot, + LoadModule, + LoadFile ¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    • Include, + <IfModule>, + <IfDefine>, + ¤Î¤è¤¦¤ÊÀßÄê¥Õ¥¡¥¤¥ë¼«¿È¤òÀ©¸æ¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ë¤¢¤ê¡¢Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ɽ¼¨¤µ¤ì¤Þ¤¹¡£
    • +
    • ¥³¥á¥ó¥È¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó¡£(¤³¤ì¤Ï»ÅÍͤÀ¤È»×¤Ã¤Æ¤¯¤À¤µ¤¤¡£)
    • +
    • .htaccess ¥Õ¥¡¥¤¥ë¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïɽ¼¨¤µ¤ì¤Þ¤»¤ó + (±Êµ×Ū¤Ê¥µ¡¼¥ÐÀßÄê¤Î°ìÉô¤Ç¤Ï¤Ê¤¤¤«¤é¤Ç¤¹)¡£
    • +
    • <Directory> + ¤Î¤è¤¦¤Ê¥³¥ó¥Æ¥Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÉáÄ̤Ëɽ¼¨¤µ¤ì¤Þ¤¹¤¬¡¢ + mod_info ¤ÏÊĤ¸¥¿¥°¤Î </Directory> ¤Ê¤É¤Î¿ô¤òÃΤ뤳¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£
    • +
    • mod_perl ¤Î¤è¤¦¤Ê¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¥â¥¸¥å¡¼¥ë + ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïɽ¼¨¤µ¤ì¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    • +
    +
    +
    top
    +

    AddModuleInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:server-info ¥Ï¥ó¥É¥é¤Ë¤è¤êɽ¼¨¤µ¤ì¤ë¥â¥¸¥å¡¼¥ë¤Î¾ðÊó¤Ë +ÄɲäξðÊó¤òÉÕ¤±²Ã¤¨¤ë
    ¹½Ê¸:AddModuleInfo module-name string
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_info
    ¸ß´¹À­:Apache 1.3 °Ê¹ß
    +

    ¤³¤ì¤Ï¡¢string ¤ÎÆâÍƤ¬¥â¥¸¥å¡¼¥ë module-name + ¤ÎÄɲþðÊó ¤È¤·¤Æ HTML + ¤È¤·¤Æ²ò¼á¤µ¤ì¡¢É½¼¨¤µ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£Îã:

    + +

    + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_info.html.ko.euc-kr b/trunk/docs/manual/mod/mod_info.html.ko.euc-kr new file mode 100644 index 0000000000..1632e67c03 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.html.ko.euc-kr @@ -0,0 +1,169 @@ + + + +mod_info - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_info

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:¼­¹ö ¼³Á¤¿¡ ´ëÇÑ Á¾ÇÕÀûÀÎ Á¤º¸¸¦ º¸¿©ÁØ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:info_module
    ¼Ò½ºÆÄÀÏ:mod_info.c
    +

    ¿ä¾à

    + +

    mod_info¸¦ »ç¿ëÇÏ·Á¸é httpd.conf + ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    + +

    + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +

    + +

    ÀÌ·¸°Ô ¼³Á¤Çϸé + http://your.host.example.com/server-info¿¡ + Á¢±ÙÇÏ¿© ¼­¹ö¿¡ ´ëÇÑ Á¤º¸¸¦ º¼ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    º¸¾È ¹®Á¦

    +

    Çѹø ¼­¹ö°¡ mod_info¸¦ ÀоîµéÀ̸é, µð·ºÅ丮º° + ¼³Á¤ÆÄÀÏ(¿¹¸¦ µé¾î, .htaccess)À» Æ÷ÇÔÇÑ + ¸ðµç ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ Çڵ鷯 ±â´ÉÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ±×·¡¼­ »çÀÌÆ®¿¡ º¸¾È°ü·Ã ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    + +

    ƯÈ÷ ÀÌ ¸ðµâÀº ½Ã½ºÅÛ °æ·Î, »ç¿ëÀÚ¸í/¾ÏÈ£, µ¥ÀÌÅͺ£À̽º + À̸§°ú °°ÀÌ ¿©·¯ ¾ÆÆÄÄ¡ ¸ðµâÀÇ ¼³Á¤Áö½Ã¾î¿¡ ±â·ÏÇÑ ¹Î°¨ÇÑ + Á¤º¸¸¦ À¯ÃâÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ÀÌ ¸ðµâÀº Ç×»ó ÁÖÀÇÇØ¾ß Çϸç + ÅëÁ¦µÈ ȯ°æ¿¡¼­¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ mod_authz_host¸¦ »ç¿ëÇÏ¿© + ¼­¹ö ¼³Á¤ Á¤º¸¿¡ ´ëÇÑ Á¢±ÙÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    + +

    Á¢±Ù Á¦¾î

    + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # ÀÚ½ÅÀ¸·Î ºÎÅÍ Á¢±Ù Çã°¡
    + Allow from 127.0.0.1
    + # Ãß°¡·Î, ±Ùó¿¡ ÀÖ´Â ¿öÅ©½ºÅ×À̼ÇÀ¸·Î ºÎÅÍ Á¢±Ù Çã°¡
    + Allow from 192.168.1.17
    +
    + </Location> +

    +
    top
    +
    +

    º¸¿©ÁÖ´Â Á¤º¸ ¼±ÅÃÇϱâ

    +

    ±âº»ÀûÀ¸·Î ¼­¹ö Á¤º¸¿¡´Â »ç¿ëÇÏ´Â ¸ðµâ ¸ñ·Ï°ú ¸ðµâº°·Î + ¸ðµâÀÌ ÀÌÇØÇÏ´Â Áö½Ã¾î ¼³¸í, ¸ðµâÀÌ ±¸ÇöÇÑ ÈÅ(hook), ÇöÀç + ¼³Á¤¿¡¼­ »ç¿ëÇÑ Áö½Ã¾î Á¤º¸°¡ ÀÖ´Ù.

    + +

    server-info ¿äû¿¡ ÁúÀǹ®ÀÚ¿­À» ºÙ¿©¼­ ¼³Á¤ + Á¤º¸¸¦ ´Ù¸£°Ô º¼ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + http://your.host.example.com/server-info?config´Â + ¸ðµç ¼³Á¤Áö½Ã¾î¸¦ º¸¿© ÁØ´Ù.

    + +
    +
    ?<module-name>
    +
    ¸í½ÃÇÑ ¸ðµâ¿¡ ´ëÇÑ Á¤º¸¸¸
    +
    ?config
    +
    ¸ðµâº°·Î Á¤·ÄÇÏÁö ¾Ê°í, ¼³Á¤Áö½Ã¾î¸¸
    +
    ?hooks
    +
    ¸ðµâÀÌ µî·ÏÇÑ ÈÅ(hook) ¸ñ·Ï¸¸
    +
    ?list
    +
    »ç¿ëÇÏ´Â ¸ðµâ ¸ñ·Ï¸¸
    +
    ?server
    +
    ±âº» ¼­¹ö Á¤º¸¸¸
    +
    +
    top
    +
    +

    ¾Ë·ÁÁø ÇÑ°è

    +

    mod_info´Â ¿ø·¡ ¼³Á¤ÆÄÀÏÀ» ÀÐÁö ¾Ê°í + ÀÌ¹Ì ÀоîµéÀÎ ¼³Á¤ Á¤º¸¸¦ Âü°íÇÏ¿© Á¤º¸¸¦ º¸¿©ÁØ´Ù. ¼³Á¤À» + ÆĽÌÇÏ´Â ¹æ¹ý¶§¹®¿¡ ´ÙÀ½°ú °°Àº ¸î°¡Áö ÇÑ°è°¡ ÀÖ´Ù.

    +
      +
    • ÆĽÌÇÑ ¼³Á¤ Á¤º¸¿¡ ±â·ÏÇÏÁö ¾Ê°í Áï½Ã ½ÇÇàµÇ´Â Áö½Ã¾î¸¦ + º¸¿©ÁÖÁö ¸øÇÑ´Ù. ServerRoot, LoadModule, LoadFile°ú °°Àº Áö½Ã¾î°¡ + ¿©±â¿¡ ÇØ´çÇÑ´Ù.
    • +
    • Include, <IfModule>, <IfDefine>°ú °°ÀÌ + ¼³Á¤ÆÄÀÏ ÀÚü¸¦ Á¶Á¤ÇÏ´Â Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÑ´Ù. + ±×·¯³ª ¾È¿¡ ÀÖ´Â ¼³Á¤Áö½Ã¾î´Â º¸¿©ÁØ´Ù.
    • +
    • ÁÖ¼®À» º¸¿©ÁÖÁö ¸øÇÑ´Ù. (ÇÑ°è¶ó±â º¸´Ù´Â ±â´ÉÀ̶ó°í + »ý°¢ÇÒ ¼ö ÀÖ´Ù.)
    • +
    • (Áö¼ÓÀûÀÎ ¼­¹ö¼³Á¤ÀÌ ¾Æ´Ï±â ¶§¹®¿¡) .htaccess + ÆÄÀÏ¿¡ ÀÖ´Â ¼³Á¤Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÑ´Ù.
    • +
    • º¸Åë <Directory>¿Í + °°Àº ¹üÀ§Á¦ÇÑ Áö½Ã¾î´Â º¸¿©ÁÖÁö¸¸, + mod_info´Â ¸¶Ä¡´Â </Directory>ÀÇ ÁÙ¹øÈ£¸¦ + ¾Ë ¼ö ¾ø´Ù.
    • +
    • mod_perl°ú °°ÀÌ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀÇ + Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÒ ¼ö ÀÖ´Ù.
    • +
    +
    +
    top
    +

    AddModuleInfo Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¸ðµâ¿¡ ´ëÇÑ Ãß°¡ Á¤º¸¸¦ server-info Çڵ鷯°¡ º¸¿©ÁÖµµ·Ï +Ãß°¡ÇÑ´Ù
    ¹®¹ý:AddModuleInfo module-name string
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_info
    Áö¿ø:¾ÆÆÄÄ¡ 1.3 ÀÌÈÄ
    +

    module-name ¸ðµâ¿¡ ´ëÇÑ Ãß°¡ Á¤º¸·Î + stringÀÇ ³»¿ëÀ» HTML·Î º¸¿©ÁØ´Ù. ¿¹¸¦ µé¾î,

    + +

    + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_info.xml b/trunk/docs/manual/mod/mod_info.xml new file mode 100644 index 0000000000..24696f6ad2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.xml @@ -0,0 +1,174 @@ + + + + + + + + + +mod_info +Provides a comprehensive overview of the server +configuration +Extension +mod_info.c +info_module + + +

    To configure mod_info, add the following to your + httpd.conf file.

    + + + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +
    + +

    You may wish to use mod_access inside the + Location + directive to limite access to your server configuration + information:

    + + + <Location /server-info>
    + + SetHandler server-info
    + Order deny,allow
    + Deny from all
    + Allow from yourcompany.com
    +
    + </Location> +
    + +

    Once configured, the server information is obtained by + accessing http://your.host.example.com/server-info

    +
    + +
    Security Issues +

    Once mod_info is loaded into the server, its + handler capability is available in all configuration + files, including per-directory files (e.g., + .htaccess). This may have security-related + ramifications for your site.

    + +

    In particular, this module can leak sensitive information + from the configuration directives of other Apache modules such as + system paths, usernames/passwords, database names, etc. Therefore, + this module should only be + used in a controlled environment and always with caution.

    + +

    You will probably want to use mod_authz_host + to limit access to your server configuration information.

    + + Access control + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # Allow access from server itself
    + Allow from 127.0.0.1
    + # Additionally, allow access from local workstation
    + Allow from 192.168.1.17
    +
    + </Location> +
    +
    + +
    Selecting the information shown +

    By default, the server information includes a list of + all enabled modules, and for each module, a description of + the directives understood by that module, the hooks implemented + by that module, and the relevant directives from the current + configuration.

    + +

    Other views of the configuration information are available by + appending a query to the server-info request. For + example, http://your.host.example.com/server-info?config + will show all configuration directives.

    + +
    +
    ?<module-name>
    +
    Only information relevant to the named module
    +
    ?config
    +
    Just the configuration directives, not sorted by module
    +
    ?hooks
    +
    Only the list of Hooks each module is attached to
    +
    ?list
    +
    Only a simple list of enabled modules
    +
    ?server
    +
    Only the basic server information
    +
    +
    + +
    Known Limitations +

    mod_info provides its information by reading the + parsed configuration, rather than reading the original configuration + file. There are a few limitations as a result of the way the parsed + configuration tree is created:

    +
      +
    • Directives which are executed immediately rather than being + stored in the parsed configuration are not listed. These include + ServerRoot, + LoadModule, and + LoadFile.
    • +
    • Directives which control the configuration file itself, such as + Include, + <IfModule> and + <IfDefine> are not + listed, but the included configuration directives are.
    • +
    • Comments are not listed. (This may be considered a feature.)
    • +
    • Configuration directives from .htaccess files are + not listed (since they do not form part of the permanent server + configuration).
    • +
    • Container directives such as + <Directory> + are listed normally, but mod_info cannot figure + out the line number for the closing + </Directory>.
    • +
    • Directives generated by third party modules such as mod_perl + might not be listed.
    • +
    +
    + + +AddModuleInfo +Adds additional information to the module +information displayed by the server-info handler +AddModuleInfo module-name string +server configvirtual host + +Apache 1.3 and above + + +

    This allows the content of string to be shown as + HTML interpreted, Additional Information for + the module module-name. Example:

    + + + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +
    +
    + +
    +
    diff --git a/trunk/docs/manual/mod/mod_info.xml.ja b/trunk/docs/manual/mod/mod_info.xml.ja new file mode 100644 index 0000000000..bd2cabd360 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.xml.ja @@ -0,0 +1,169 @@ + + + + + + + + + +mod_info +$B%5!<%P$N@_Dj$NJq3gE*$J354Q$rDs6!$9$k(B +Extension +mod_info.c +info_module + + +

    mod_info $B$r@_Dj$9$k$K$O!"0J2<$r(B httpd.conf + $B%U%!%$%k$K2C$($^$9!#(B

    + + + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +
    + +

    Location + $B$NCf$G(B mod_access $B$r;H$C$F!"%5!<%P@_Dj>pJs$X$N(B + $B%"%/%;%9$r@)8B$7$?$$$H;W$&$+$b$7$l$^$;$s(B :

    + + + <Location /server-info>
    + + SetHandler server-info
    + Order deny,allow
    + Deny from all
    + Allow from yourcompany.com
    +
    + </Location> +
    + +

    $B0lC6@_Dj$9$k$H!"(Bhttp://your.host.example.com/server-info + $B$K%"%/%;%9$9$k$3$H$G%5!<%P$N>pJs$rF@$i$l$k$h$&$K$J$j$^$9!#(B

    +
    + +
    Security Issues +

    $B0lC6(B mod_info $B$,%5!<%P$KFI$_9~$^$l$k$H!"(B + $BDs6!$7$F$$$k%O%s%I%i5!G=$O%G%#%l%/%H%jKh$N@_Dj%U%!%$%k(B ($BNc$($P(B + .htaccess) $B$r4^$`(B $B$9$Y$F(B$B$N@_Dj%U%!%$%k$GM-8z$K$J$j$^$9!#(B + $B$3$N%b%8%e!<%k$rM-8z$K$9$k$H$-$O%;%-%e%j%F%#$NLdBj$r9MN8$9$kI,MW$,(B + $B$"$k$G$7$g$&!#(B

    + +

    $BFC$K!"$3$N%b%8%e!<%k$O%7%9%F%`%Q%9!"%f!<%6L>(B/$B%Q%9%o!<%I!"(B + $B%G!<%?%Y!<%9L>$J$I!"B>$N(B Apache $B%b%8%e!<%k$N@_Dj%G%#%l%/%F%#%V$+$i(B + $B%;%-%e%j%F%#>eHyL/$J>pJs$rO3$i$92DG=@-$,$"$j$^$9!#(B + $B$G$9$+$i!"$3$N%b%8%e!<%k$O$-$A$s$H%"%/%;%9@)8f$5$l$?4D6-$G(B$B$N$_(B$B!"(B + $BCm0U$7$F;H$C$F$/$@$5$$!#(B

    + +

    $B@_Dj>pJs$X$N%"%/%;%9$r@)8B$9$k$?$a$K!"(Bmod_authz_host $B$r(B + $B;H$&$N$,NI$$$G$7$g$&!#(B

    + + $B%"%/%;%9@)8f(B + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # Allow access from server itself
    + Allow from 127.0.0.1
    + # Additionally, allow access from local workstation
    + Allow from 192.168.1.17
    +
    + </Location> +
    +
    + +
    $BI=<($5$l$k>pJs$NA*Br(B +

    $B%G%U%)%k%H$G$O!"%5!<%P>pJs$O$9$Y$F$NM-8z$J%b%8%e!<%k$H!"(B + $B3F%b%8%e!<%k$K$D$$$F!"%b%8%e!<%k$,M}2r$9$k%G%#%l%/%F%#%V!"(B + $B + +

    server-info $B%j%/%(%9%H$X%/%(%j!<$rDI2C$9$k$3$H$G!"(B + $B@_Dj>pJs$NB>$NI=<(7A<0$rA*$V$3$H$,$G$-$^$9!#Nc$($P!"(B + http://your.host.example.com/server-info?config $B$O(B + $B$9$Y$F$N@_Dj%G%#%l%/%F%#%V$rI=<($7$^$9!#(B

    + +
    +
    ?<module-name>
    +
    $B;XDj$5$l$?%b%8%e!<%k$K4XO"$9$k>pJs$N$_(B
    +
    ?config
    +
    $B%b%8%e!<%k$G%=!<%H$;$:$K!"@_Dj%G%#%l%/%F%#%V$N$_(B
    +
    ?hooks
    +
    $B3F%b%8%e!<%k$,;HMQ$9$k%U%C%/$N$_(B
    +
    ?list
    +
    $BM-8z$J%b%8%e!<%k$N4JC1$J%j%9%H$N$_(B
    +
    ?server
    +
    $B4pK\%5!<%P>pJs$N$_(B
    +
    +
    + +
    $B4{CN$N@)8B(B +

    mod_info $B$O!"85$N@_Dj%U%!%$%k$rFI$`$N$G$O$J$/!"(B + $B4{$K%Q!<%9$5$l$?@_Dj$rFI$_9~$`$3$H$G>pJs$rDs6!$7$^$9!#=>$C$F!"(B + $B%Q!<%9:Q$_$N@_Dj>pJs$NLZ$,@8@.$5$l$kJ}K!$K$h$k@)8B$,$$$/$D$+$"$j$^$9(B:

    +
      +
    • $B%Q!<%9$5$l$?@_Dj$KJ]B8$5$l$:$K!"$9$0$KServerRoot, + LoadModule, + LoadFile $B$,$"$j$^$9!#(B
    • +
    • Include, + <IfModule>, + <IfDefine>, + $B$N$h$&$J@_Dj%U%!%$%k<+?H$r@)8f$9$k%G%#%l%/%F%#%V$OI=<($5$l$^$;$s!#(B + $B$=$N%G%#%l%/%F%#%V$NCf$K$"$j!"M-8z$K$J$C$F$$$k%G%#%l%/%F%#%V$O(B + $BI=<($5$l$^$9!#(B
    • +
    • $B%3%a%s%H$OI=<($5$l$^$;$s!#(B($B$3$l$O;EMM$@$H;W$C$F$/$@$5$$!#(B)
    • +
    • .htaccess $B%U%!%$%k$N@_Dj%G%#%l%/%F%#%V$OI=<($5$l$^$;$s(B + ($B1J5WE*$J%5!<%P@_Dj$N0lIt$G$O$J$$$+$i$G$9(B)$B!#(B
    • +
    • <Directory> + $B$N$h$&$J%3%s%F%J%G%#%l%/%F%#%V$OIaDL$KI=<($5$l$^$9$,!"(B + mod_info $B$OJD$8%?%0$N(B </Directory> $B$J$I$N?t$rCN$k$3$H$O$G$-$^$;$s!#(B
    • +
    • mod_perl $B$N$h$&$J%5!<%I%Q!<%F%#%b%8%e!<%k(B + $B$N%G%#%l%/%F%#%V$OI=<($5$l$J$$$+$b$7$l$^$;$s!#(B
    • +
    +
    + + +AddModuleInfo +server-info $B%O%s%I%i$K$h$jI=<($5$l$k%b%8%e!<%k$N>pJs$K(B +$BDI2C$N>pJs$rIU$12C$($k(B +AddModuleInfo module-name string +server configvirtual host + +Apache 1.3 $B0J9_(B + + +

    $B$3$l$O!"(Bstring $B$NFbMF$,%b%8%e!<%k(B module-name + $B$N(B$BDI2C>pJs(B $B$H$7$F(B HTML + $B$H$7$F2r + + + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +
    + + + + diff --git a/trunk/docs/manual/mod/mod_info.xml.ko b/trunk/docs/manual/mod/mod_info.xml.ko new file mode 100644 index 0000000000..6f7d193ed7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.xml.ko @@ -0,0 +1,153 @@ + + + + + + + + + +mod_info +¼­¹ö ¼³Á¤¿¡ ´ëÇÑ Á¾ÇÕÀûÀÎ Á¤º¸¸¦ º¸¿©ÁØ´Ù +Extension +mod_info.c +info_module + +

    +

    mod_info¸¦ »ç¿ëÇÏ·Á¸é httpd.conf + ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    + + + <Location /server-info>
    + + SetHandler server-info
    +
    + </Location> +
    + +

    ÀÌ·¸°Ô ¼³Á¤Çϸé + http://your.host.example.com/server-info¿¡ + Á¢±ÙÇÏ¿© ¼­¹ö¿¡ ´ëÇÑ Á¤º¸¸¦ º¼ ¼ö ÀÖ´Ù.

    +
    + +
    º¸¾È ¹®Á¦ +

    Çѹø ¼­¹ö°¡ mod_info¸¦ ÀоîµéÀ̸é, µð·ºÅ丮º° + ¼³Á¤ÆÄÀÏ(¿¹¸¦ µé¾î, .htaccess)À» Æ÷ÇÔÇÑ + ¸ðµç ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ Çڵ鷯 ±â´ÉÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ±×·¡¼­ »çÀÌÆ®¿¡ º¸¾È°ü·Ã ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù.

    + +

    ƯÈ÷ ÀÌ ¸ðµâÀº ½Ã½ºÅÛ °æ·Î, »ç¿ëÀÚ¸í/¾ÏÈ£, µ¥ÀÌÅͺ£À̽º + À̸§°ú °°ÀÌ ¿©·¯ ¾ÆÆÄÄ¡ ¸ðµâÀÇ ¼³Á¤Áö½Ã¾î¿¡ ±â·ÏÇÑ ¹Î°¨ÇÑ + Á¤º¸¸¦ À¯ÃâÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ÀÌ ¸ðµâÀº Ç×»ó ÁÖÀÇÇØ¾ß Çϸç + ÅëÁ¦µÈ ȯ°æ¿¡¼­¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ mod_authz_host¸¦ »ç¿ëÇÏ¿© + ¼­¹ö ¼³Á¤ Á¤º¸¿¡ ´ëÇÑ Á¢±ÙÀ» Á¦ÇÑÇÒ ¼ö ÀÖ´Ù.

    + + Á¢±Ù Á¦¾î + <Location /server-info>
    + + SetHandler server-info
    + Order allow,deny
    + # ÀÚ½ÅÀ¸·Î ºÎÅÍ Á¢±Ù Çã°¡
    + Allow from 127.0.0.1
    + # Ãß°¡·Î, ±Ùó¿¡ ÀÖ´Â ¿öÅ©½ºÅ×À̼ÇÀ¸·Î ºÎÅÍ Á¢±Ù Çã°¡
    + Allow from 192.168.1.17
    +
    + </Location> +
    +
    + +
    º¸¿©ÁÖ´Â Á¤º¸ ¼±ÅÃÇϱâ +

    ±âº»ÀûÀ¸·Î ¼­¹ö Á¤º¸¿¡´Â »ç¿ëÇÏ´Â ¸ðµâ ¸ñ·Ï°ú ¸ðµâº°·Î + ¸ðµâÀÌ ÀÌÇØÇÏ´Â Áö½Ã¾î ¼³¸í, ¸ðµâÀÌ ±¸ÇöÇÑ ÈÅ(hook), ÇöÀç + ¼³Á¤¿¡¼­ »ç¿ëÇÑ Áö½Ã¾î Á¤º¸°¡ ÀÖ´Ù.

    + +

    server-info ¿äû¿¡ ÁúÀǹ®ÀÚ¿­À» ºÙ¿©¼­ ¼³Á¤ + Á¤º¸¸¦ ´Ù¸£°Ô º¼ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, + http://your.host.example.com/server-info?config´Â + ¸ðµç ¼³Á¤Áö½Ã¾î¸¦ º¸¿© ÁØ´Ù.

    + +
    +
    ?<module-name>
    +
    ¸í½ÃÇÑ ¸ðµâ¿¡ ´ëÇÑ Á¤º¸¸¸
    +
    ?config
    +
    ¸ðµâº°·Î Á¤·ÄÇÏÁö ¾Ê°í, ¼³Á¤Áö½Ã¾î¸¸
    +
    ?hooks
    +
    ¸ðµâÀÌ µî·ÏÇÑ ÈÅ(hook) ¸ñ·Ï¸¸
    +
    ?list
    +
    »ç¿ëÇÏ´Â ¸ðµâ ¸ñ·Ï¸¸
    +
    ?server
    +
    ±âº» ¼­¹ö Á¤º¸¸¸
    +
    +
    + +
    ¾Ë·ÁÁø ÇÑ°è +

    mod_info´Â ¿ø·¡ ¼³Á¤ÆÄÀÏÀ» ÀÐÁö ¾Ê°í + ÀÌ¹Ì ÀоîµéÀÎ ¼³Á¤ Á¤º¸¸¦ Âü°íÇÏ¿© Á¤º¸¸¦ º¸¿©ÁØ´Ù. ¼³Á¤À» + ÆĽÌÇÏ´Â ¹æ¹ý¶§¹®¿¡ ´ÙÀ½°ú °°Àº ¸î°¡Áö ÇÑ°è°¡ ÀÖ´Ù.

    +
      +
    • ÆĽÌÇÑ ¼³Á¤ Á¤º¸¿¡ ±â·ÏÇÏÁö ¾Ê°í Áï½Ã ½ÇÇàµÇ´Â Áö½Ã¾î¸¦ + º¸¿©ÁÖÁö ¸øÇÑ´Ù. ServerRoot, LoadModule, LoadFile°ú °°Àº Áö½Ã¾î°¡ + ¿©±â¿¡ ÇØ´çÇÑ´Ù.
    • +
    • Include, <IfModule>, <IfDefine>°ú °°ÀÌ + ¼³Á¤ÆÄÀÏ ÀÚü¸¦ Á¶Á¤ÇÏ´Â Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÑ´Ù. + ±×·¯³ª ¾È¿¡ ÀÖ´Â ¼³Á¤Áö½Ã¾î´Â º¸¿©ÁØ´Ù.
    • +
    • ÁÖ¼®À» º¸¿©ÁÖÁö ¸øÇÑ´Ù. (ÇÑ°è¶ó±â º¸´Ù´Â ±â´ÉÀ̶ó°í + »ý°¢ÇÒ ¼ö ÀÖ´Ù.)
    • +
    • (Áö¼ÓÀûÀÎ ¼­¹ö¼³Á¤ÀÌ ¾Æ´Ï±â ¶§¹®¿¡) .htaccess + ÆÄÀÏ¿¡ ÀÖ´Â ¼³Á¤Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÑ´Ù.
    • +
    • º¸Åë <Directory>¿Í + °°Àº ¹üÀ§Á¦ÇÑ Áö½Ã¾î´Â º¸¿©ÁÖÁö¸¸, + mod_info´Â ¸¶Ä¡´Â </Directory>ÀÇ ÁÙ¹øÈ£¸¦ + ¾Ë ¼ö ¾ø´Ù.
    • +
    • mod_perl°ú °°ÀÌ Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀÇ + Áö½Ã¾î¸¦ º¸¿©ÁÖÁö ¸øÇÒ ¼ö ÀÖ´Ù.
    • +
    +
    + + +AddModuleInfo +¸ðµâ¿¡ ´ëÇÑ Ãß°¡ Á¤º¸¸¦ server-info Çڵ鷯°¡ º¸¿©ÁÖµµ·Ï +Ãß°¡ÇÑ´Ù +AddModuleInfo module-name string +server configvirtual host + +¾ÆÆÄÄ¡ 1.3 ÀÌÈÄ + + +

    module-name ¸ðµâ¿¡ ´ëÇÑ Ãß°¡ Á¤º¸·Î + stringÀÇ ³»¿ëÀ» HTML·Î º¸¿©ÁØ´Ù. ¿¹¸¦ µé¾î,

    + + + AddModuleInfo mod_deflate.c 'See <a \
    + + href="http://www.apache.org/docs-2.1/mod/mod_deflate.html">\
    + http://www.apache.org/docs-2.1/mod/mod_deflate.html</a>' +
    +
    +
    + +
    +
    diff --git a/trunk/docs/manual/mod/mod_info.xml.meta b/trunk/docs/manual/mod/mod_info.xml.meta new file mode 100644 index 0000000000..6394d97498 --- /dev/null +++ b/trunk/docs/manual/mod/mod_info.xml.meta @@ -0,0 +1,13 @@ + + + + mod_info + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_isapi.html b/trunk/docs/manual/mod/mod_isapi.html new file mode 100644 index 0000000000..6d92c77300 --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.html @@ -0,0 +1,7 @@ +URI: mod_isapi.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_isapi.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_isapi.html.en b/trunk/docs/manual/mod/mod_isapi.html.en new file mode 100644 index 0000000000..751ec3c5b1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.html.en @@ -0,0 +1,337 @@ + + + +mod_isapi - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_isapi

    +
    +

    Available Languages:  en  | + ko 

    +
    + + + + +
    Description:ISAPI Extensions within Apache for Windows
    Status:Base
    Module Identifier:isapi_module
    Source File:mod_isapi.c
    Compatibility:Win32 only
    +

    Summary

    + +

    This module implements the Internet Server extension API. It + allows Internet Server extensions (e.g. ISAPI .dll + modules) to be served by Apache for Windows, subject to the + noted restrictions.

    + +

    ISAPI extension modules (.dll files) are written by third + parties. The Apache Group does not author these modules, so we + provide no support for them. Please contact the ISAPI's author + directly if you are experiencing problems running their ISAPI + extension. Please do not post such problems to + Apache's lists or bug reporting pages.

    +
    + +
    top
    +
    +

    Usage

    + +

    In the server configuration file, use + the AddHandler directive to + associate ISAPI files with the isapi-isa handler, and map + it to them with their file extensions. To enable any .dll file to be + processed as an ISAPI extension, edit the httpd.conf file and add the + following line:

    +

    + AddHandler isapi-isa .dll +

    + +

    There is no capability within the Apache server to leave a + requested module loaded. However, you may preload and keep a + specific module loaded by using the following syntax in your + httpd.conf:

    +

    + ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll +

    + +

    Whether or not you have preloaded an ISAPI extension, all + ISAPI extensions are governed by the same permissions and + restrictions as CGI scripts. That is, Options ExecCGI must be set for the + directory that contains the ISAPI .dll file.

    + +

    Review the Additional Notes and the Programmer's Journal for additional details + and clarification of the specific ISAPI support offered by + mod_isapi.

    +
    top
    +
    +

    Additional Notes

    + +

    Apache's ISAPI implementation conforms to all of the ISAPI + 2.0 specification, except for some "Microsoft-specific" + extensions dealing with asynchronous I/O. Apache's I/O model + does not allow asynchronous reading and writing in a manner + that the ISAPI could access. If an ISA tries to access + unsupported features, including async I/O, a message is placed + in the error log to help with debugging. Since these messages + can become a flood, the directive ISAPILogNotSupported + Off exists to quiet this noise.

    + +

    Some servers, like Microsoft IIS, load the ISAPI extension + into the server and keep it loaded until memory usage is too + high, or unless configuration options are specified. Apache + currently loads and unloads the ISAPI extension each time it is + requested, unless the ISAPICacheFile directive is specified. + This is inefficient, but Apache's memory model makes this the + most effective method. Many ISAPI modules are subtly + incompatible with the Apache server, and unloading these + modules helps to ensure the stability of the server.

    + +

    Also, remember that while Apache supports ISAPI Extensions, + it does not support ISAPI Filters. Support for + filters may be added at a later date, but no support is planned + at this time.

    +
    top
    +
    +

    Programmer's Journal

    + +

    If you are programming Apache 2.0 mod_isapi + modules, you must limit your calls to ServerSupportFunction + to the following directives:

    + +
    +
    HSE_REQ_SEND_URL_REDIRECT_RESP
    +
    Redirect the user to another location.
    + This must be a fully qualified URL (e.g. + http://server/location).
    + +
    HSE_REQ_SEND_URL
    +
    Redirect the user to another location.
    + This cannot be a fully qualified URL, you are not allowed to + pass the protocol or a server name (e.g. simply + /location).
    + This redirection is handled by the server, not the + browser.
    +

    Warning

    +

    In their recent documentation, Microsoft appears to have + abandoned the distinction between the two + HSE_REQ_SEND_URL functions. Apache continues to treat + them as two distinct functions with different requirements + and behaviors.

    +
    + +
    HSE_REQ_SEND_RESPONSE_HEADER
    +
    Apache accepts a response body following the header if it + follows the blank line (two consecutive newlines) in the + headers string argument. This body cannot contain NULLs, + since the headers argument is NULL terminated.
    + +
    HSE_REQ_DONE_WITH_SESSION
    +
    Apache considers this a no-op, since the session will be + finished when the ISAPI returns from processing.
    + +
    HSE_REQ_MAP_URL_TO_PATH
    +
    Apache will translate a virtual name to a physical + name.
    + +
    HSE_APPEND_LOG_PARAMETER
    +
    + This logged message may be captured in any of the following + logs: + + + +

    The first option, the %{isapi-parameter}n component, + is always available and preferred.

    +
    + +
    HSE_REQ_IS_KEEP_CONN
    +
    Will return the negotiated Keep-Alive status.
    + +
    HSE_REQ_SEND_RESPONSE_HEADER_EX
    +
    Will behave as documented, although the fKeepConn + flag is ignored.
    + +
    HSE_REQ_IS_CONNECTED
    +
    Will report false if the request has been aborted.
    +
    + +

    Apache returns FALSE to any unsupported call to + ServerSupportFunction, and sets the + GetLastError value to + ERROR_INVALID_PARAMETER.

    + +

    ReadClient retrieves the request body exceeding the + initial buffer (defined by ISAPIReadAheadBuffer). Based on the + ISAPIReadAheadBuffer setting (number of bytes + to buffer prior to calling the ISAPI handler) shorter requests are sent + complete to the extension when it is invoked. If the request is + longer, the ISAPI extension must use ReadClient to + retrieve the remaining request body.

    + +

    WriteClient is supported, but only with the + HSE_IO_SYNC flag or no option flag (value of + 0). Any other WriteClient request + will be rejected with a return value of FALSE, and a + GetLastError value of + ERROR_INVALID_PARAMETER.

    + +

    GetServerVariable is supported, although extended server + variables do not exist (as defined by other servers.) All the + usual Apache CGI environment variables are available from + GetServerVariable, as well as the ALL_HTTP + and ALL_RAW values.

    + +

    Apache 2.0 mod_isapi supports additional + features introduced in later versions of the ISAPI specification, + as well as limited emulation of async I/O and the + TransmitFile semantics. Apache also supports preloading + ISAPI .dlls for performance, neither of which were not available under + Apache 1.3 mod_isapi.

    +
    +
    top
    +

    ISAPIAppendLogToErrors Directive

    + + + + + + + + +
    Description:Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log
    Syntax:ISAPIAppendLogToErrors on|off
    Default:ISAPIAppendLogToErrors off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_isapi
    +

    Record HSE_APPEND_LOG_PARAMETER requests from ISAPI + extensions to the server error log.

    + +
    +
    top
    +

    ISAPIAppendLogToQuery Directive

    + + + + + + + + +
    Description:Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field
    Syntax:ISAPIAppendLogToQuery on|off
    Default:ISAPIAppendLogToQuery on
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_isapi
    +

    Record HSE_APPEND_LOG_PARAMETER requests from ISAPI + extensions to the query field (appended to the CustomLog %q + component).

    + +
    +
    top
    +

    ISAPICacheFile Directive

    + + + + + + +
    Description:ISAPI .dll files to be loaded at startup
    Syntax:ISAPICacheFile file-path [file-path] +...
    Context:server config, virtual host
    Status:Base
    Module:mod_isapi
    +

    Specifies a space-separated list of file names to be loaded + when the Apache server is launched, and remain loaded until the + server is shut down. This directive may be repeated for every + ISAPI .dll file desired. The full path name of each file should + be specified. If the path name is not absolute, it will be treated + relative to ServerRoot.

    + +
    +
    top
    +

    ISAPIFakeAsync Directive

    + + + + + + + + +
    Description:Fake asynchronous support for ISAPI callbacks
    Syntax:ISAPIFakeAsync on|off
    Default:ISAPIFakeAsync off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_isapi
    +

    While set to on, asynchronous support for ISAPI callbacks is + simulated.

    + +
    +
    top
    +

    ISAPILogNotSupported Directive

    + + + + + + + + +
    Description:Log unsupported feature requests from ISAPI +extensions
    Syntax:ISAPILogNotSupported on|off
    Default:ISAPILogNotSupported off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_isapi
    +

    Logs all requests for unsupported features from ISAPI + extensions in the server error log. This may help administrators + to track down problems. Once set to on and all desired ISAPI modules + are functioning, it should be set back to off.

    + +
    +
    top
    +

    ISAPIReadAheadBuffer Directive

    + + + + + + + + +
    Description:Size of the Read Ahead Buffer sent to ISAPI +extensions
    Syntax:ISAPIReadAheadBuffer size
    Default:ISAPIReadAheadBuffer 49152
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_isapi
    +

    Defines the maximum size of the Read Ahead Buffer sent to + ISAPI extensions when they are initially invoked. All remaining + data must be retrieved using the ReadClient callback; some + ISAPI extensions may not support the ReadClient function. + Refer questions to the ISAPI extension's author.

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_isapi.html.ko.euc-kr b/trunk/docs/manual/mod/mod_isapi.html.ko.euc-kr new file mode 100644 index 0000000000..353a022f86 --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.html.ko.euc-kr @@ -0,0 +1,317 @@ + + + +mod_isapi - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_isapi

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + + + +
    ¼³¸í:Windows¿ë ¾ÆÆÄÄ¡¿¡¼­ ISAPI Extension »ç¿ë
    »óÅÂ:Base
    ¸ðµâ¸í:isapi_module
    ¼Ò½ºÆÄÀÏ:mod_isapi.c
    Áö¿ø:Win32 only
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº Internet Server extension API¸¦ ±¸ÇöÇÑ´Ù. ±×·¡¼­ + Á¦¾àÀº ÀÖÁö¸¸ Windows¿ë ¾ÆÆÄÄ¡¿¡¼­ Internet Server extensionÀ» + (Áï, ISAPI .dll ¸ðµâ) »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ISAPI extension ¸ðµâ(.dll ÆÄÀÏ)Àº Á¦»ïÀÚ°¡ ÀÛ¼ºÇÑ´Ù. + Apache GroupÀÌ ÀÌµé ¸ðµâÀ» ¸¸µéÁö ¾Ê¾ÒÀ¸¸ç, Áö¿øµµ ÇÏÁö + ¾Ê´Â´Ù. ISAPI extension »ç¿ë¿¡ °üÇÑ ¹®Á¦´Â ISAPI Á¦ÀÛÀÚ¿¡°Ô + Á÷Á¢ ¿¬¶ôÇÏ±æ ¹Ù¶õ´Ù. Á¦¹ß ÀÌ·± ¹®Á¦¸¦ ¾ÆÆÄÄ¡ + ¸ÞÀϸµ¸®½ºÆ®³ª ¹ö±×º¸°í ÆäÀÌÁö¿¡ ¿Ã¸®Áö ¸¶¶ó.

    +
    + +
    top
    +
    +

    »ç¿ë¹ý

    + +

    ¼­¹ö¼³Á¤ÆÄÀÏ¿¡¼­ AddHandler Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ISAPI ÆÄÀÏ È®ÀåÀÚ¿Í isapi-isa Çڵ鷯¸¦ ¿¬°áÇÑ´Ù. + .dll ÆÄÀÏÀ» ISAPI extensionÀ¸·Î ó¸®ÇÏ·Á¸é httpd.conf ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    +

    + AddHandler isapi-isa .dll +

    + +

    ¾ÆÆÄÄ¡ ¼­¹ö´Â ¿äûÇÑ ¸ðµâÀ» ¸Þ¸ð¸®¿¡ °è¼Ó µÑ ¼ö ¾ø´Ù. + ±×·¯³ª httpd.conf¿¡¼­ ´ÙÀ½°ú °°Àº ¼³Á¤À¸·Î ƯÁ¤ ¸ðµâÀ» ¹Ì¸® + ÀоîµéÀÏ ¼ö´Â ÀÖ´Ù.

    +

    + ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll +

    + +

    ISAPI extensionÀ» ¹Ì¸® ÀоîµéÀÌ´øÁö ¹Ì¸® ÀоîµéÀÌÁö ¾Ê´øÁö + °ü°è¾øÀÌ ISAPI extensionÀº CGI ½ºÅ©¸³Æ®¿Í µ¿ÀÏÇÑ ±ÇÇÑ°ú + Á¦¾àÀ» µû¸¥´Ù. Áï, ISAPI .dll ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿¡ Options ExecCGI°¡ + ÇÊ¿äÇÏ´Ù.

    + +

    mod_isapiÀÇ ISAPI Áö¿ø¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ + ³»¿ë°ú ¼³¸íÀº Ãß°¡ ¼³¸í°ú °³¹ßÀÚ Á¤º¸¸¦ Âü°íÇ϶ó.

    +
    top
    +
    +

    Ãß°¡ ¼³¸í

    + +

    ¾ÆÆÄÄ¡ ISAPI ±¸ÇöÀº ºñµ¿±â ÀÔÃâ·Â¿¡ ´ëÇÑ "¸¶ÀÌÅ©·Î¼ÒÇÁÆ® + ƯÀ¯ÀÇ" È®Àå±â´ÉÀ» Á¦¿ÜÇÑ ISAPI 2.0 ±Ô¾àÀ» ¸ðµÎ ¸¸Á·ÇÑ´Ù. + ¾ÆÆÄÄ¡ÀÇ ÀÔÃâ·Â ±¸Á¶·Î´Â ISAPI°¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ½ÄÀ¸·Î + ºñµ¿±â ÀÔÃâ·ÂÀ» ÇÒ ¼ö ¾ø´Ù. ISA°¡ ºñµ¿±â ÀÔÃâ·Â°ú °°ÀÌ Áö¿øÇÏÁö + ¾Ê´Â ±â´ÉÀ» »ç¿ëÇÏ·Á ÇÑ´Ù¸é, µð¹ö±ë¿¡ µµ¿òÀ» ÁÖ±âÀ§ÇØ ¿À·ù + ·Î±×¿¡ ±â·ÏÀ» ³²±ä´Ù. ·Î±×°¡ ¸Å¿ì Ä¿Áú ¼ö Àֱ⶧¹®¿¡ + ISAPILogNotSupported Off Áö½Ã¾î¸¦ »ç¿ëÇϸé + ·Î±×¿¡ ±â·ÏÇÏÁö ¾Ê´Â´Ù.

    + +

    Microsoft IIS¿Í °°Àº ¼­¹ö´Â ISAPI extensionÀ» ¸Þ¸ð¸®·Î + Àоîµé¿©¼­ ¸Þ¸ð¸® »ç¿ë·®ÀÌ ¸Å¿ì ¸¹Áö ¾Ê°Å³ª Ưº°È÷ ¼³Á¤ÇÏÁö + ¾Ê´ÂÇÑ ±×´ë·Î ¸Þ¸ð¸®¿¡ µÐ´Ù. ¾ÆÆÄÄ¡´Â ÇöÀç ISAPICacheFile Áö½Ã¾î¸¦ »ç¿ëÇÏÁö + ¾Ê´Â´Ù¸é ¿äûÀ» ¹ÞÀ»¶§¸¶´Ù ISAPI extensionÀ» ¸Þ¸ð¸®¿¡ ÀоîµéÀÌ°í + ¹ö¸°´Ù. ºñÈ¿À²ÀûÀÌÁö¸¸, ¾ÆÆÄÄ¡ÀÇ ¸Þ¸ð¸® ±¸Á¶»ó ÀÌ°ÍÀÌ °¡Àå + È¿À²ÀûÀÎ ¹æ¹ýÀÌ´Ù. ¿©·¯ ISAPI ¸ðµâÀÌ ¾ÆÆÄÄ¡ ¼­¹ö¿Í ¾à°£ + ȣȯÀÌ ¾È¸Â±â¶§¹®¿¡ ¼­¹öÀÇ ¾ÈÁ¤¼ºÀ» À§ÇØ ¸ðµâÀ» ¸Þ¸ð¸®¿¡¼­ + ¹ö¸°´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡´Â ISAPI ExtensionÀ» Áö¿øÇÏÁö¸¸, ISAPI + Filter¸¦ Áö¿øÇÏÁö ¾ÊÀ½À» ±â¾ïÇ϶ó. ³ªÁß¿¡ ÇÊÅ͸¦ + Áö¿øÇÒ ¼ö ÀÖÁö¸¸, ÇöÀç´Â °èȹÀÌ ¾ø´Ù.

    +
    top
    +
    +

    °³¹ßÀÚ Á¤º¸

    + +

    ¾ÆÆÄÄ¡ 2.0 mod_isapi ¸ðµâÀ» ÇÁ·Î±×·¡¹ÖÇÑ´Ù¸é, + ServerSupportFunction È£ÃâÀ» ´ÙÀ½ Áö½Ã¾î·Î + Á¦ÇÑÇØ¾ß ÇÑ´Ù.

    + +
    +
    HSE_REQ_SEND_URL_REDIRECT_RESP
    +
    »ç¿ëÀÚ¸¦ ´Ù¸¥ À§Ä¡·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    + ¿ÏÀüÇÑ URLÀ» »ç¿ëÇØ¾ß ÇÑ´Ù (¿¹¸¦ µé¾î, + http://server/location).
    + +
    HSE_REQ_SEND_URL
    +
    »ç¿ëÀÚ¸¦ ´Ù¸¥ À§Ä¡·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    + ¿ÏÀüÇÑ URLÀÌ ¾Æ´Ï¸ç, ÇÁ·ÎÅäÄÝ°ú ¼­¹ö¸íÀ» ³Ñ±æ ¼ö ¾ø´Ù + (¿¹¸¦ µé¾î, /location°°Àº °Í¸¸ °¡´É).
    + ºê¶ó¿ìÀú°¡ ¾Æ´Ï¶ó ¼­¹ö°¡ ¸®´ÙÀÌ·º¼ÇÀ» ó¸®ÇÑ´Ù.
    +

    °æ°í

    +

    ÃÖ±Ù ¹®¼­¸¦ º¸¸é Microsoft°¡ µÎ HSE_REQ_SEND_URL + ±â´É°£ÀÇ Â÷À̸¦ ¾ø¾Ø °Íó·³ º¸ÀδÙ. ¾ÆÆÄÄ¡´Â °è¼Ó ÀÌ + µÑÀÇ ¾Æ±Ô¸ÕÆ® Á¶°Ç°ú ÇൿÀ» ´Ù¸£°Ô ó¸®ÇÒ °ÍÀÌ´Ù.

    +
    + +
    HSE_REQ_SEND_RESPONSE_HEADER
    +
    headers ¹®ÀÚ¿­ ¾Æ±Ô¸ÕÆ®¿¡ ºóÁÙÀÌ (Áٹٲ޹®ÀÚ°¡ µÎ¹ø + ¿¬¼Ó) ÀÖ´Ù¸é ¾ÆÆÄÄ¡´Â Çì´õ ´ÙÀ½ ³»¿ëÀ» ÀÀ´ä ³»¿ëÀ¸·Î »ç¿ëÇÑ´Ù. + headers ¾Æ±Ô¸ÕÆ®°¡ NULL·Î ³¡³ª±â¶§¹®¿¡, ÀÀ´ä ³»¿ë¿¡ NULLÀ» + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    HSE_REQ_DONE_WITH_SESSION
    +
    ISAPI°¡ 󸮸¦ ¸¶Ä¡¸é ¼¼¼ÇÀÌ ³¡³ª±â¶§¹®¿¡ ¾ÆÆÄÄ¡´Â + ¾Æ¹« Àϵµ ÇÏÁö ¾Ê´Â´Ù.
    + +
    HSE_REQ_MAP_URL_TO_PATH
    +
    ¾ÆÆÄÄ¡´Â °¡»ó À̸§À» ¹°¸®Àû(½ÇÁ¦) À̸§À¸·Î º¯È¯ÇÑ´Ù.
    + +
    HSE_APPEND_LOG_PARAMETER
    +
    + ¹®±¸¸¦ ¾Æ·¡ ·Î±×Áß ÇÑ°÷¿¡ ³²±ä´Ù. + + + +

    ù¹ø°·Î ³ª¿Â %{isapi-parameter}n Ç׸ñÀº + ¾ðÁ¦³ª »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç ±ÇÀåÇÑ´Ù.

    +
    + +
    HSE_REQ_IS_KEEP_CONN
    +
    Çù»óµÈ Keep-Alive »óŸ¦ ¹ÝȯÇÑ´Ù.
    + +
    HSE_REQ_SEND_RESPONSE_HEADER_EX
    +
    fKeepConn ¿É¼ÇÀ» ¹«½ÃÇÏ´Â °ÍÀ» Á¦¿ÜÇÏ°í´Â + ¹®¼­¿¡ ³ª¿Âµ¥·Î µ¿ÀÛÇÑ´Ù.
    + +
    HSE_REQ_IS_CONNECTED
    +
    ¿äûÀÌ Áß°£¿¡ ²÷¾îÁ³´Ù¸é false¸¦ ¹ÝȯÇÑ´Ù.
    +
    + +

    Áö¿øÇÏÁö ¾Ê´Â ServerSupportFunction È£ÃâÀ» + ÇÏ¸é ¾ÆÆÄÄ¡´Â FALSE¸¦ ¹ÝȯÇÏ°í + GetLastError °ªÀ» + ERROR_INVALID_PARAMETER·Î ¼³Á¤ÇÑ´Ù.

    + +

    ReadClient´Â (ISAPIReadAheadBuffer·Î Á¤ÀÇÇÑ) + Ãʱâ¹öÆÛÅ©±â¸¦ ³Ñ¾î¼± ¿äû ³»¿ëÀ» °¡Á®¿Â´Ù. + ISAPIReadAheadBuffer ¼³Á¤ (ISAPI + Çڵ鷯¸¦ ºÎ¸£±âÀü ¹öÆÛÀÇ ¹ÙÀÌÆ®¼ö) º¸´Ù ªÀº ¿äûÀº extensionÀ» + ºÎ¸¦¶§ ÀüºÎ Àü´ÞµÈ´Ù. ¿äûÀÌ ±æ¸é, ISAPI extensionÀº + ReadClient·Î ³ª¸ÓÁö ¿äû ³»¿ëÀ» °¡Á®¿Í¾ß ÇÑ´Ù.

    + +

    WriteClient¸¦ Áö¿øÇÏÁö¸¸, + HSE_IO_SYNC ¿É¼Ç¸¸ »ç¿ëÇϰųª (0 + °ª) ¾Æ¹« ¿É¼Çµµ »ç¿ëÇÏÁö ¾Ê¾Æ¾ß ÇÑ´Ù. ´Ù¸¥ + WriteClient ¿äûÀº FALSE¸¦ ¹ÝȯÇϸç + ½ÇÆÐÇÏ°í, GetLastError °ªÀº + ERROR_INVALID_PARAMETER°¡ µÈ´Ù.

    + +

    GetServerVariableÀº Áö¿øÇÏÁö¸¸, (´Ù¸¥ ¼­¹ö¿¡¼­ + Á¤ÀÇÇÏ´Â) È®Àå ¼­¹öº¯¼ö´Â ¾ø´Ù. + GetServerVariable¿¡¼­ ¸ðµç ÀϹÝÀûÀÎ ¾ÆÆÄÄ¡ + CGI ȯ°æº¯¼ö¿Í ALL_HTTP, ALL_RAW + °ªÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0 mod_isapi´Â ÀÌÈÄ ISAPI ±Ô¾à¿¡ + ³ª¿Â Ãß°¡ ±â´ÉÀ» Áö¿øÇÏ°í, ºñµ¿±â ÀÔÃâ·Â°ú + TransmitFile ±â´ÉÀ» Á¶±Ý Èä³»³½´Ù. ¶Ç, ISAPI + .dllÀ» ¹Ì¸® Àоîµé¿©¼­ ¼º´ÉÀ» ³ôÀÌ´Â ¾ÆÆÄÄ¡ 1.3 + mod_isapi¿¡´Â ¾ø´Â ±â´ÉÀ» Áö¿øÇÑ´Ù.

    +
    +
    top
    +

    ISAPIAppendLogToErrors Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù
    ¹®¹ý:ISAPIAppendLogToErrors on|off
    ±âº»°ª:ISAPIAppendLogToErrors off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER + ¿äûÀ» ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù.

    + +
    +
    top
    +

    ISAPIAppendLogToQuery Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ÁúÀǹ®ÀÚ¿­¿¡ ±â·ÏÇÑ´Ù
    ¹®¹ý:ISAPIAppendLogToQuery on|off
    ±âº»°ª:ISAPIAppendLogToQuery on
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER + ¿äûÀ» ÁúÀǹ®ÀÚ¿­¿¡ ±â·ÏÇÑ´Ù (CustomLog %q + Ç׸ñ¿¡ µ¡ºÙÀδÙ).

    + +
    +
    top
    +

    ISAPICacheFile Áö½Ã¾î

    + + + + + + +
    ¼³¸í:¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ¸Þ¸ð¸®·Î ÀоîµéÀÏ ISAPI .dll ÆÄÀϵé
    ¹®¹ý:ISAPICacheFile file-path [file-path] +...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    ¾ÆÆÄÄ¡ ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ¸Þ¸ð¸®·Î Àоîµé¿©¼­ ¼­¹ö¸¦ Á¾·áÇÒ¶§±îÁö + ¸Þ¸ð¸®¿¡ ³²¾ÆÀÖÀ» ÆÄÀϸíÀ» °ø¹éÀ¸·Î ±¸ºÐÇÏ¿© ÁöÁ¤ÇÑ´Ù. ÀÌ + Áö½Ã¾î´Â ISAPI .dll ÆÄÀϺ°·Î ¿©·¯¹ø »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÆÄÀÏÀÇ + Àüü °æ·Î¸¦ Àû´Â´Ù. Àý´ë °æ·Î°¡ ¾Æ´Ï¸é ServerRoot¿¡ »ó´ë °æ·Î·Î ¹Þ¾ÆµéÀδÙ.

    + +
    +
    top
    +

    ISAPIFakeAsync Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ºñµ¿±â ISAPI ÄݹéÀ» Áö¿øÇϴ ôÇÑ´Ù
    ¹®¹ý:ISAPIFakeAsync on|off
    ±âº»°ª:ISAPIFakeAsync off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    onÀ¸·Î ¼³Á¤ÇÏ¸é ºñµ¿±â ISAPI Äݹé Áö¿øÀ» Èä³»³½´Ù.

    + +
    +
    top
    +

    ISAPILogNotSupported Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ISAPI extensionÀÌ Áö¿øÇÏÁö ¾Ê´Â ±â´ÉÀ» ¿äûÇϸé +·Î±×¿¡ ±â·ÏÇÑ´Ù
    ¹®¹ý:ISAPILogNotSupported on|off
    ±âº»°ª:ISAPILogNotSupported off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    ISAPI extensionÀÌ Áö¿øÇÏÁö ¾Ê´Â ±â´ÉÀ» ¿äûÇÏ¸é ¼­¹ö + ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù. ³ªÁß¿¡ °ü¸®ÀÚ°¡ ¹®Á¦¸¦ ÃßÀûÇϴµ¥ + µµ¿òÀÌ µÈ´Ù. ¿øÇÏ´Â ¸ðµç ISAPI ¸ðµâÀÌ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϸé + ´Ù½Ã off·Î µÇµ¹·Á¾ß ÇÑ´Ù.

    + +
    +
    top
    +

    ISAPIReadAheadBuffer Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:ISAPI extensionÀÇ ¹Ì¸®Àбâ¹öÆÛ(read ahead buffer) +Å©±â
    ¹®¹ý:ISAPIReadAheadBuffer size
    ±âº»°ª:ISAPIReadAheadBuffer 49152
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_isapi
    +

    ISAPI extensionÀ» óÀ½ È£ÃâÇÒ¶§ ¹Ì¸®Àбâ¹öÆÛÀÇ ÃÖ´ë Å©±â¸¦ + ÁöÁ¤ÇÑ´Ù. (ÀÌ Å©±âº¸´Ù Å«) ³ª¸ÓÁö ÀÚ·á´Â ReadClient + ÄݹéÀ» »ç¿ëÇÏ¿© Àоî¾ß ÇÑ´Ù. ¾î¶² ISAPI extensionÀº + ReadClient ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù. ÀÌ °æ¿ì + ISAPI extension Á¦ÀÛÀÚ¿¡°Ô ¹®ÀÇÇ϶ó.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_isapi.xml b/trunk/docs/manual/mod/mod_isapi.xml new file mode 100644 index 0000000000..348ac71520 --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.xml @@ -0,0 +1,321 @@ + + + + + + + + + +mod_isapi +ISAPI Extensions within Apache for Windows +Base +mod_isapi.c +isapi_module +Win32 only + + +

    This module implements the Internet Server extension API. It + allows Internet Server extensions (e.g. ISAPI .dll + modules) to be served by Apache for Windows, subject to the + noted restrictions.

    + +

    ISAPI extension modules (.dll files) are written by third + parties. The Apache Group does not author these modules, so we + provide no support for them. Please contact the ISAPI's author + directly if you are experiencing problems running their ISAPI + extension. Please do not post such problems to + Apache's lists or bug reporting pages.

    +
    + +
    Usage + +

    In the server configuration file, use + the AddHandler directive to + associate ISAPI files with the isapi-isa handler, and map + it to them with their file extensions. To enable any .dll file to be + processed as an ISAPI extension, edit the httpd.conf file and add the + following line:

    + + AddHandler isapi-isa .dll + + +

    There is no capability within the Apache server to leave a + requested module loaded. However, you may preload and keep a + specific module loaded by using the following syntax in your + httpd.conf:

    + + ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll + + +

    Whether or not you have preloaded an ISAPI extension, all + ISAPI extensions are governed by the same permissions and + restrictions as CGI scripts. That is, Options ExecCGI must be set for the + directory that contains the ISAPI .dll file.

    + +

    Review the Additional Notes and the Programmer's Journal for additional details + and clarification of the specific ISAPI support offered by + mod_isapi.

    +
    + +
    Additional Notes + +

    Apache's ISAPI implementation conforms to all of the ISAPI + 2.0 specification, except for some "Microsoft-specific" + extensions dealing with asynchronous I/O. Apache's I/O model + does not allow asynchronous reading and writing in a manner + that the ISAPI could access. If an ISA tries to access + unsupported features, including async I/O, a message is placed + in the error log to help with debugging. Since these messages + can become a flood, the directive ISAPILogNotSupported + Off exists to quiet this noise.

    + +

    Some servers, like Microsoft IIS, load the ISAPI extension + into the server and keep it loaded until memory usage is too + high, or unless configuration options are specified. Apache + currently loads and unloads the ISAPI extension each time it is + requested, unless the ISAPICacheFile directive is specified. + This is inefficient, but Apache's memory model makes this the + most effective method. Many ISAPI modules are subtly + incompatible with the Apache server, and unloading these + modules helps to ensure the stability of the server.

    + +

    Also, remember that while Apache supports ISAPI Extensions, + it does not support ISAPI Filters. Support for + filters may be added at a later date, but no support is planned + at this time.

    +
    + +
    Programmer's Journal + +

    If you are programming Apache 2.0 mod_isapi + modules, you must limit your calls to ServerSupportFunction + to the following directives:

    + +
    +
    HSE_REQ_SEND_URL_REDIRECT_RESP
    +
    Redirect the user to another location.
    + This must be a fully qualified URL (e.g. + http://server/location).
    + +
    HSE_REQ_SEND_URL
    +
    Redirect the user to another location.
    + This cannot be a fully qualified URL, you are not allowed to + pass the protocol or a server name (e.g. simply + /location).
    + This redirection is handled by the server, not the + browser.
    + Warning +

    In their recent documentation, Microsoft appears to have + abandoned the distinction between the two + HSE_REQ_SEND_URL functions. Apache continues to treat + them as two distinct functions with different requirements + and behaviors.

    +
    + +
    HSE_REQ_SEND_RESPONSE_HEADER
    +
    Apache accepts a response body following the header if it + follows the blank line (two consecutive newlines) in the + headers string argument. This body cannot contain NULLs, + since the headers argument is NULL terminated.
    + +
    HSE_REQ_DONE_WITH_SESSION
    +
    Apache considers this a no-op, since the session will be + finished when the ISAPI returns from processing.
    + +
    HSE_REQ_MAP_URL_TO_PATH
    +
    Apache will translate a virtual name to a physical + name.
    + +
    HSE_APPEND_LOG_PARAMETER
    +
    + This logged message may be captured in any of the following + logs: + +
      +
    • in the \"%{isapi-parameter}n\" component in a + CustomLog + directive
    • + +
    • in the %q log component with the + ISAPIAppendLogToQuery + On directive
    • + +
    • in the error log with the ISAPIAppendLogToErrors On directive
    • +
    + +

    The first option, the %{isapi-parameter}n component, + is always available and preferred.

    +
    + +
    HSE_REQ_IS_KEEP_CONN
    +
    Will return the negotiated Keep-Alive status.
    + +
    HSE_REQ_SEND_RESPONSE_HEADER_EX
    +
    Will behave as documented, although the fKeepConn + flag is ignored.
    + +
    HSE_REQ_IS_CONNECTED
    +
    Will report false if the request has been aborted.
    +
    + +

    Apache returns FALSE to any unsupported call to + ServerSupportFunction, and sets the + GetLastError value to + ERROR_INVALID_PARAMETER.

    + +

    ReadClient retrieves the request body exceeding the + initial buffer (defined by ISAPIReadAheadBuffer). Based on the + ISAPIReadAheadBuffer setting (number of bytes + to buffer prior to calling the ISAPI handler) shorter requests are sent + complete to the extension when it is invoked. If the request is + longer, the ISAPI extension must use ReadClient to + retrieve the remaining request body.

    + +

    WriteClient is supported, but only with the + HSE_IO_SYNC flag or no option flag (value of + 0). Any other WriteClient request + will be rejected with a return value of FALSE, and a + GetLastError value of + ERROR_INVALID_PARAMETER.

    + +

    GetServerVariable is supported, although extended server + variables do not exist (as defined by other servers.) All the + usual Apache CGI environment variables are available from + GetServerVariable, as well as the ALL_HTTP + and ALL_RAW values.

    + +

    Apache 2.0 mod_isapi supports additional + features introduced in later versions of the ISAPI specification, + as well as limited emulation of async I/O and the + TransmitFile semantics. Apache also supports preloading + ISAPI .dlls for performance, neither of which were not available under + Apache 1.3 mod_isapi.

    +
    + + +ISAPICacheFile +ISAPI .dll files to be loaded at startup +ISAPICacheFile file-path [file-path] +... +server configvirtual host + + + +

    Specifies a space-separated list of file names to be loaded + when the Apache server is launched, and remain loaded until the + server is shut down. This directive may be repeated for every + ISAPI .dll file desired. The full path name of each file should + be specified. If the path name is not absolute, it will be treated + relative to ServerRoot.

    +
    +
    + + +ISAPIReadAheadBuffer +Size of the Read Ahead Buffer sent to ISAPI +extensions +ISAPIReadAheadBuffer size +ISAPIReadAheadBuffer 49152 +server configvirtual host +directory.htaccess +FileInfo + + +

    Defines the maximum size of the Read Ahead Buffer sent to + ISAPI extensions when they are initially invoked. All remaining + data must be retrieved using the ReadClient callback; some + ISAPI extensions may not support the ReadClient function. + Refer questions to the ISAPI extension's author.

    +
    +
    + + +ISAPILogNotSupported +Log unsupported feature requests from ISAPI +extensions +ISAPILogNotSupported on|off +ISAPILogNotSupported off +server configvirtual host +directory.htaccess +FileInfo + + +

    Logs all requests for unsupported features from ISAPI + extensions in the server error log. This may help administrators + to track down problems. Once set to on and all desired ISAPI modules + are functioning, it should be set back to off.

    +
    +
    + + +ISAPIAppendLogToErrors +Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log +ISAPIAppendLogToErrors on|off +ISAPIAppendLogToErrors off +server configvirtual host +directory.htaccess +FileInfo + + +

    Record HSE_APPEND_LOG_PARAMETER requests from ISAPI + extensions to the server error log.

    +
    +
    + + +ISAPIAppendLogToQuery +Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field +ISAPIAppendLogToQuery on|off +ISAPIAppendLogToQuery on +server configvirtual host +directory.htaccess +FileInfo + + +

    Record HSE_APPEND_LOG_PARAMETER requests from ISAPI + extensions to the query field (appended to the CustomLog %q + component).

    +
    +
    + + +ISAPIFakeAsync +Fake asynchronous support for ISAPI callbacks +ISAPIFakeAsync on|off +ISAPIFakeAsync off +server configvirtual host +directory.htaccess +FileInfo + + +

    While set to on, asynchronous support for ISAPI callbacks is + simulated.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_isapi.xml.ko b/trunk/docs/manual/mod/mod_isapi.xml.ko new file mode 100644 index 0000000000..3d3de1434f --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.xml.ko @@ -0,0 +1,303 @@ + + + + + + + + + +mod_isapi +Windows¿ë ¾ÆÆÄÄ¡¿¡¼­ ISAPI Extension »ç¿ë +Base +mod_isapi.c +isapi_module +Win32 only + + +

    ÀÌ ¸ðµâÀº Internet Server extension API¸¦ ±¸ÇöÇÑ´Ù. ±×·¡¼­ + Á¦¾àÀº ÀÖÁö¸¸ Windows¿ë ¾ÆÆÄÄ¡¿¡¼­ Internet Server extensionÀ» + (Áï, ISAPI .dll ¸ðµâ) »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ISAPI extension ¸ðµâ(.dll ÆÄÀÏ)Àº Á¦»ïÀÚ°¡ ÀÛ¼ºÇÑ´Ù. + Apache GroupÀÌ ÀÌµé ¸ðµâÀ» ¸¸µéÁö ¾Ê¾ÒÀ¸¸ç, Áö¿øµµ ÇÏÁö + ¾Ê´Â´Ù. ISAPI extension »ç¿ë¿¡ °üÇÑ ¹®Á¦´Â ISAPI Á¦ÀÛÀÚ¿¡°Ô + Á÷Á¢ ¿¬¶ôÇÏ±æ ¹Ù¶õ´Ù. Á¦¹ß ÀÌ·± ¹®Á¦¸¦ ¾ÆÆÄÄ¡ + ¸ÞÀϸµ¸®½ºÆ®³ª ¹ö±×º¸°í ÆäÀÌÁö¿¡ ¿Ã¸®Áö ¸¶¶ó.

    +
    + +
    »ç¿ë¹ý + +

    ¼­¹ö¼³Á¤ÆÄÀÏ¿¡¼­ AddHandler Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ISAPI ÆÄÀÏ È®ÀåÀÚ¿Í isapi-isa Çڵ鷯¸¦ ¿¬°áÇÑ´Ù. + .dll ÆÄÀÏÀ» ISAPI extensionÀ¸·Î ó¸®ÇÏ·Á¸é httpd.conf ÆÄÀÏ¿¡ + ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù.

    + + AddHandler isapi-isa .dll + + +

    ¾ÆÆÄÄ¡ ¼­¹ö´Â ¿äûÇÑ ¸ðµâÀ» ¸Þ¸ð¸®¿¡ °è¼Ó µÑ ¼ö ¾ø´Ù. + ±×·¯³ª httpd.conf¿¡¼­ ´ÙÀ½°ú °°Àº ¼³Á¤À¸·Î ƯÁ¤ ¸ðµâÀ» ¹Ì¸® + ÀоîµéÀÏ ¼ö´Â ÀÖ´Ù.

    + + ISAPICacheFile c:/WebWork/Scripts/ISAPI/mytest.dll + + +

    ISAPI extensionÀ» ¹Ì¸® ÀоîµéÀÌ´øÁö ¹Ì¸® ÀоîµéÀÌÁö ¾Ê´øÁö + °ü°è¾øÀÌ ISAPI extensionÀº CGI ½ºÅ©¸³Æ®¿Í µ¿ÀÏÇÑ ±ÇÇÑ°ú + Á¦¾àÀ» µû¸¥´Ù. Áï, ISAPI .dll ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮¿¡ Options ExecCGI°¡ + ÇÊ¿äÇÏ´Ù.

    + +

    mod_isapiÀÇ ISAPI Áö¿ø¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ + ³»¿ë°ú ¼³¸íÀº Ãß°¡ ¼³¸í°ú °³¹ßÀÚ Á¤º¸¸¦ Âü°íÇ϶ó.

    +
    + +
    Ãß°¡ ¼³¸í + +

    ¾ÆÆÄÄ¡ ISAPI ±¸ÇöÀº ºñµ¿±â ÀÔÃâ·Â¿¡ ´ëÇÑ "¸¶ÀÌÅ©·Î¼ÒÇÁÆ® + ƯÀ¯ÀÇ" È®Àå±â´ÉÀ» Á¦¿ÜÇÑ ISAPI 2.0 ±Ô¾àÀ» ¸ðµÎ ¸¸Á·ÇÑ´Ù. + ¾ÆÆÄÄ¡ÀÇ ÀÔÃâ·Â ±¸Á¶·Î´Â ISAPI°¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¹æ½ÄÀ¸·Î + ºñµ¿±â ÀÔÃâ·ÂÀ» ÇÒ ¼ö ¾ø´Ù. ISA°¡ ºñµ¿±â ÀÔÃâ·Â°ú °°ÀÌ Áö¿øÇÏÁö + ¾Ê´Â ±â´ÉÀ» »ç¿ëÇÏ·Á ÇÑ´Ù¸é, µð¹ö±ë¿¡ µµ¿òÀ» ÁÖ±âÀ§ÇØ ¿À·ù + ·Î±×¿¡ ±â·ÏÀ» ³²±ä´Ù. ·Î±×°¡ ¸Å¿ì Ä¿Áú ¼ö Àֱ⶧¹®¿¡ + ISAPILogNotSupported Off Áö½Ã¾î¸¦ »ç¿ëÇϸé + ·Î±×¿¡ ±â·ÏÇÏÁö ¾Ê´Â´Ù.

    + +

    Microsoft IIS¿Í °°Àº ¼­¹ö´Â ISAPI extensionÀ» ¸Þ¸ð¸®·Î + Àоîµé¿©¼­ ¸Þ¸ð¸® »ç¿ë·®ÀÌ ¸Å¿ì ¸¹Áö ¾Ê°Å³ª Ưº°È÷ ¼³Á¤ÇÏÁö + ¾Ê´ÂÇÑ ±×´ë·Î ¸Þ¸ð¸®¿¡ µÐ´Ù. ¾ÆÆÄÄ¡´Â ÇöÀç ISAPICacheFile Áö½Ã¾î¸¦ »ç¿ëÇÏÁö + ¾Ê´Â´Ù¸é ¿äûÀ» ¹ÞÀ»¶§¸¶´Ù ISAPI extensionÀ» ¸Þ¸ð¸®¿¡ ÀоîµéÀÌ°í + ¹ö¸°´Ù. ºñÈ¿À²ÀûÀÌÁö¸¸, ¾ÆÆÄÄ¡ÀÇ ¸Þ¸ð¸® ±¸Á¶»ó ÀÌ°ÍÀÌ °¡Àå + È¿À²ÀûÀÎ ¹æ¹ýÀÌ´Ù. ¿©·¯ ISAPI ¸ðµâÀÌ ¾ÆÆÄÄ¡ ¼­¹ö¿Í ¾à°£ + ȣȯÀÌ ¾È¸Â±â¶§¹®¿¡ ¼­¹öÀÇ ¾ÈÁ¤¼ºÀ» À§ÇØ ¸ðµâÀ» ¸Þ¸ð¸®¿¡¼­ + ¹ö¸°´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡´Â ISAPI ExtensionÀ» Áö¿øÇÏÁö¸¸, ISAPI + Filter¸¦ Áö¿øÇÏÁö ¾ÊÀ½À» ±â¾ïÇ϶ó. ³ªÁß¿¡ ÇÊÅ͸¦ + Áö¿øÇÒ ¼ö ÀÖÁö¸¸, ÇöÀç´Â °èȹÀÌ ¾ø´Ù.

    +
    + +
    °³¹ßÀÚ Á¤º¸ + +

    ¾ÆÆÄÄ¡ 2.0 mod_isapi ¸ðµâÀ» ÇÁ·Î±×·¡¹ÖÇÑ´Ù¸é, + ServerSupportFunction È£ÃâÀ» ´ÙÀ½ Áö½Ã¾î·Î + Á¦ÇÑÇØ¾ß ÇÑ´Ù.

    + +
    +
    HSE_REQ_SEND_URL_REDIRECT_RESP
    +
    »ç¿ëÀÚ¸¦ ´Ù¸¥ À§Ä¡·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    + ¿ÏÀüÇÑ URLÀ» »ç¿ëÇØ¾ß ÇÑ´Ù (¿¹¸¦ µé¾î, + http://server/location).
    + +
    HSE_REQ_SEND_URL
    +
    »ç¿ëÀÚ¸¦ ´Ù¸¥ À§Ä¡·Î ¸®´ÙÀÌ·º¼ÇÇÑ´Ù.
    + ¿ÏÀüÇÑ URLÀÌ ¾Æ´Ï¸ç, ÇÁ·ÎÅäÄÝ°ú ¼­¹ö¸íÀ» ³Ñ±æ ¼ö ¾ø´Ù + (¿¹¸¦ µé¾î, /location°°Àº °Í¸¸ °¡´É).
    + ºê¶ó¿ìÀú°¡ ¾Æ´Ï¶ó ¼­¹ö°¡ ¸®´ÙÀÌ·º¼ÇÀ» ó¸®ÇÑ´Ù.
    + °æ°í +

    ÃÖ±Ù ¹®¼­¸¦ º¸¸é Microsoft°¡ µÎ HSE_REQ_SEND_URL + ±â´É°£ÀÇ Â÷À̸¦ ¾ø¾Ø °Íó·³ º¸ÀδÙ. ¾ÆÆÄÄ¡´Â °è¼Ó ÀÌ + µÑÀÇ ¾Æ±Ô¸ÕÆ® Á¶°Ç°ú ÇൿÀ» ´Ù¸£°Ô ó¸®ÇÒ °ÍÀÌ´Ù.

    +
    + +
    HSE_REQ_SEND_RESPONSE_HEADER
    +
    headers ¹®ÀÚ¿­ ¾Æ±Ô¸ÕÆ®¿¡ ºóÁÙÀÌ (Áٹٲ޹®ÀÚ°¡ µÎ¹ø + ¿¬¼Ó) ÀÖ´Ù¸é ¾ÆÆÄÄ¡´Â Çì´õ ´ÙÀ½ ³»¿ëÀ» ÀÀ´ä ³»¿ëÀ¸·Î »ç¿ëÇÑ´Ù. + headers ¾Æ±Ô¸ÕÆ®°¡ NULL·Î ³¡³ª±â¶§¹®¿¡, ÀÀ´ä ³»¿ë¿¡ NULLÀ» + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    HSE_REQ_DONE_WITH_SESSION
    +
    ISAPI°¡ 󸮸¦ ¸¶Ä¡¸é ¼¼¼ÇÀÌ ³¡³ª±â¶§¹®¿¡ ¾ÆÆÄÄ¡´Â + ¾Æ¹« Àϵµ ÇÏÁö ¾Ê´Â´Ù.
    + +
    HSE_REQ_MAP_URL_TO_PATH
    +
    ¾ÆÆÄÄ¡´Â °¡»ó À̸§À» ¹°¸®Àû(½ÇÁ¦) À̸§À¸·Î º¯È¯ÇÑ´Ù.
    + +
    HSE_APPEND_LOG_PARAMETER
    +
    + ¹®±¸¸¦ ¾Æ·¡ ·Î±×Áß ÇÑ°÷¿¡ ³²±ä´Ù. + +
      +
    • CustomLog + Áö½Ã¾îÀÇ \"%{isapi-parameter}n\" Ç׸ñ¿¡
    • + +
    • ISAPIAppendLogToQuery + On Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© %q + ·Î±× Ç׸ñ¿¡
    • + +
    • ISAPIAppendLogToErrors + On Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿À·ù ·Î±×¿¡
    • +
    + +

    ù¹ø°·Î ³ª¿Â %{isapi-parameter}n Ç׸ñÀº + ¾ðÁ¦³ª »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç ±ÇÀåÇÑ´Ù.

    +
    + +
    HSE_REQ_IS_KEEP_CONN
    +
    Çù»óµÈ Keep-Alive »óŸ¦ ¹ÝȯÇÑ´Ù.
    + +
    HSE_REQ_SEND_RESPONSE_HEADER_EX
    +
    fKeepConn ¿É¼ÇÀ» ¹«½ÃÇÏ´Â °ÍÀ» Á¦¿ÜÇÏ°í´Â + ¹®¼­¿¡ ³ª¿Âµ¥·Î µ¿ÀÛÇÑ´Ù.
    + +
    HSE_REQ_IS_CONNECTED
    +
    ¿äûÀÌ Áß°£¿¡ ²÷¾îÁ³´Ù¸é false¸¦ ¹ÝȯÇÑ´Ù.
    +
    + +

    Áö¿øÇÏÁö ¾Ê´Â ServerSupportFunction È£ÃâÀ» + ÇÏ¸é ¾ÆÆÄÄ¡´Â FALSE¸¦ ¹ÝȯÇÏ°í + GetLastError °ªÀ» + ERROR_INVALID_PARAMETER·Î ¼³Á¤ÇÑ´Ù.

    + +

    ReadClient´Â (ISAPIReadAheadBuffer·Î Á¤ÀÇÇÑ) + Ãʱâ¹öÆÛÅ©±â¸¦ ³Ñ¾î¼± ¿äû ³»¿ëÀ» °¡Á®¿Â´Ù. + ISAPIReadAheadBuffer ¼³Á¤ (ISAPI + Çڵ鷯¸¦ ºÎ¸£±âÀü ¹öÆÛÀÇ ¹ÙÀÌÆ®¼ö) º¸´Ù ªÀº ¿äûÀº extensionÀ» + ºÎ¸¦¶§ ÀüºÎ Àü´ÞµÈ´Ù. ¿äûÀÌ ±æ¸é, ISAPI extensionÀº + ReadClient·Î ³ª¸ÓÁö ¿äû ³»¿ëÀ» °¡Á®¿Í¾ß ÇÑ´Ù.

    + +

    WriteClient¸¦ Áö¿øÇÏÁö¸¸, + HSE_IO_SYNC ¿É¼Ç¸¸ »ç¿ëÇϰųª (0 + °ª) ¾Æ¹« ¿É¼Çµµ »ç¿ëÇÏÁö ¾Ê¾Æ¾ß ÇÑ´Ù. ´Ù¸¥ + WriteClient ¿äûÀº FALSE¸¦ ¹ÝȯÇϸç + ½ÇÆÐÇÏ°í, GetLastError °ªÀº + ERROR_INVALID_PARAMETER°¡ µÈ´Ù.

    + +

    GetServerVariableÀº Áö¿øÇÏÁö¸¸, (´Ù¸¥ ¼­¹ö¿¡¼­ + Á¤ÀÇÇÏ´Â) È®Àå ¼­¹öº¯¼ö´Â ¾ø´Ù. + GetServerVariable¿¡¼­ ¸ðµç ÀϹÝÀûÀÎ ¾ÆÆÄÄ¡ + CGI ȯ°æº¯¼ö¿Í ALL_HTTP, ALL_RAW + °ªÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡ 2.0 mod_isapi´Â ÀÌÈÄ ISAPI ±Ô¾à¿¡ + ³ª¿Â Ãß°¡ ±â´ÉÀ» Áö¿øÇÏ°í, ºñµ¿±â ÀÔÃâ·Â°ú + TransmitFile ±â´ÉÀ» Á¶±Ý Èä³»³½´Ù. ¶Ç, ISAPI + .dllÀ» ¹Ì¸® Àоîµé¿©¼­ ¼º´ÉÀ» ³ôÀÌ´Â ¾ÆÆÄÄ¡ 1.3 + mod_isapi¿¡´Â ¾ø´Â ±â´ÉÀ» Áö¿øÇÑ´Ù.

    +
    + + +ISAPICacheFile +¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ¸Þ¸ð¸®·Î ÀоîµéÀÏ ISAPI .dll ÆÄÀϵé +ISAPICacheFile file-path [file-path] +... +server configvirtual host + + + +

    ¾ÆÆÄÄ¡ ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ¸Þ¸ð¸®·Î Àоîµé¿©¼­ ¼­¹ö¸¦ Á¾·áÇÒ¶§±îÁö + ¸Þ¸ð¸®¿¡ ³²¾ÆÀÖÀ» ÆÄÀϸíÀ» °ø¹éÀ¸·Î ±¸ºÐÇÏ¿© ÁöÁ¤ÇÑ´Ù. ÀÌ + Áö½Ã¾î´Â ISAPI .dll ÆÄÀϺ°·Î ¿©·¯¹ø »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÆÄÀÏÀÇ + Àüü °æ·Î¸¦ Àû´Â´Ù. Àý´ë °æ·Î°¡ ¾Æ´Ï¸é ServerRoot¿¡ »ó´ë °æ·Î·Î ¹Þ¾ÆµéÀδÙ.

    +
    +
    + + +ISAPIReadAheadBuffer +ISAPI extensionÀÇ ¹Ì¸®Àбâ¹öÆÛ(read ahead buffer) +Å©±â +ISAPIReadAheadBuffer size +ISAPIReadAheadBuffer 49152 +server configvirtual host +directory.htaccess +FileInfo + + +

    ISAPI extensionÀ» óÀ½ È£ÃâÇÒ¶§ ¹Ì¸®Àбâ¹öÆÛÀÇ ÃÖ´ë Å©±â¸¦ + ÁöÁ¤ÇÑ´Ù. (ÀÌ Å©±âº¸´Ù Å«) ³ª¸ÓÁö ÀÚ·á´Â ReadClient + ÄݹéÀ» »ç¿ëÇÏ¿© Àоî¾ß ÇÑ´Ù. ¾î¶² ISAPI extensionÀº + ReadClient ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù. ÀÌ °æ¿ì + ISAPI extension Á¦ÀÛÀÚ¿¡°Ô ¹®ÀÇÇ϶ó.

    +
    +
    + + +ISAPILogNotSupported +ISAPI extensionÀÌ Áö¿øÇÏÁö ¾Ê´Â ±â´ÉÀ» ¿äûÇϸé +·Î±×¿¡ ±â·ÏÇÑ´Ù +ISAPILogNotSupported on|off +ISAPILogNotSupported off +server configvirtual host +directory.htaccess +FileInfo + + +

    ISAPI extensionÀÌ Áö¿øÇÏÁö ¾Ê´Â ±â´ÉÀ» ¿äûÇÏ¸é ¼­¹ö + ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù. ³ªÁß¿¡ °ü¸®ÀÚ°¡ ¹®Á¦¸¦ ÃßÀûÇϴµ¥ + µµ¿òÀÌ µÈ´Ù. ¿øÇÏ´Â ¸ðµç ISAPI ¸ðµâÀÌ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϸé + ´Ù½Ã off·Î µÇµ¹·Á¾ß ÇÑ´Ù.

    +
    +
    + + +ISAPIAppendLogToErrors +ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù +ISAPIAppendLogToErrors on|off +ISAPIAppendLogToErrors off +server configvirtual host +directory.htaccess +FileInfo + + +

    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER + ¿äûÀ» ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù.

    +
    +
    + + +ISAPIAppendLogToQuery +ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ÁúÀǹ®ÀÚ¿­¿¡ ±â·ÏÇÑ´Ù +ISAPIAppendLogToQuery on|off +ISAPIAppendLogToQuery on +server configvirtual host +directory.htaccess +FileInfo + + +

    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER + ¿äûÀ» ÁúÀǹ®ÀÚ¿­¿¡ ±â·ÏÇÑ´Ù (CustomLog %q + Ç׸ñ¿¡ µ¡ºÙÀδÙ).

    +
    +
    + + +ISAPIFakeAsync +ºñµ¿±â ISAPI ÄݹéÀ» Áö¿øÇϴ ôÇÑ´Ù +ISAPIFakeAsync on|off +ISAPIFakeAsync off +server configvirtual host +directory.htaccess +FileInfo + + +

    onÀ¸·Î ¼³Á¤ÇÏ¸é ºñµ¿±â ISAPI Äݹé Áö¿øÀ» Èä³»³½´Ù.

    +
    +
    + +
    + diff --git a/trunk/docs/manual/mod/mod_isapi.xml.meta b/trunk/docs/manual/mod/mod_isapi.xml.meta new file mode 100644 index 0000000000..893c0ffa9e --- /dev/null +++ b/trunk/docs/manual/mod/mod_isapi.xml.meta @@ -0,0 +1,12 @@ + + + + mod_isapi + /mod/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/mod/mod_ldap.html b/trunk/docs/manual/mod/mod_ldap.html new file mode 100644 index 0000000000..059ee1a961 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ldap.html @@ -0,0 +1,3 @@ +URI: mod_ldap.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_ldap.html.en b/trunk/docs/manual/mod/mod_ldap.html.en new file mode 100644 index 0000000000..f0fbc1e455 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ldap.html.en @@ -0,0 +1,633 @@ + + + +mod_ldap - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_ldap

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:LDAP connection pooling and result caching services for use +by other LDAP modules
    Status:Extension
    Module Identifier:ldap_module
    Source File:util_ldap.c
    Compatibility:Available in version 2.0.41 and later
    +

    Summary

    + +

    This module was created to improve the performance of + websites relying on backend connections to LDAP servers. In + addition to the functions provided by the standard LDAP + libraries, this module adds an LDAP connection pool and an LDAP + shared memory cache.

    + +

    To enable this module, LDAP support must be compiled into + apr-util. This is achieved by adding the --with-ldap + flag to the configure script when building + Apache.

    + +

    SSL/TLS support is dependant on which LDAP toolkit has been + linked to APR. As of this writing, APR-util supports: + OpenLDAP SDK (2.x or later), + Novell LDAP + SDK, + Mozilla LDAP SDK, native Solaris LDAP SDK (Mozilla based), + native Microsoft LDAP SDK, or the + iPlanet + (Netscape) SDK. See the APR + website for details.

    + +
    + +
    top
    +
    +

    Example Configuration

    +

    The following is an example configuration that uses + mod_ldap to increase the performance of HTTP Basic + authentication provided by mod_authnz_ldap.

    + +

    + # Enable the LDAP connection pool and shared
    + # memory cache. Enable the LDAP cache status
    + # handler. Requires that mod_ldap and mod_authnz_ldap
    + # be loaded. Change the "yourdomain.example.com" to
    + # match your domain.
    +
    + LDAPSharedCacheSize 200000
    + LDAPCacheEntries 1024
    + LDAPCacheTTL 600
    + LDAPOpCacheEntries 1024
    + LDAPOpCacheTTL 600
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + AuthLDAPURL ldap://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +

    +
    top
    +
    +

    LDAP Connection Pool

    + +

    LDAP connections are pooled from request to request. This + allows the LDAP server to remain connected and bound ready for + the next request, without the need to unbind/connect/rebind. + The performance advantages are similar to the effect of HTTP + keepalives.

    + +

    On a busy server it is possible that many requests will try + and access the same LDAP server connection simultaneously. + Where an LDAP connection is in use, Apache will create a new + connection alongside the original one. This ensures that the + connection pool does not become a bottleneck.

    + +

    There is no need to manually enable connection pooling in + the Apache configuration. Any module using this module for + access to LDAP services will share the connection pool.

    +
    top
    +
    +

    LDAP Cache

    + +

    For improved performance, mod_ldap uses an aggressive + caching strategy to minimize the number of times that the LDAP + server must be contacted. Caching can easily double or triple + the throughput of Apache when it is serving pages protected + with mod_authnz_ldap. In addition, the load on the LDAP server + will be significantly decreased.

    + +

    mod_ldap supports two types of LDAP caching during + the search/bind phase with a search/bind cache and + during the compare phase with two operation + caches. Each LDAP URL that is used by the server has + its own set of these three caches.

    + +

    The Search/Bind Cache

    +

    The process of doing a search and then a bind is the + most time-consuming aspect of LDAP operation, especially if + the directory is large. The search/bind cache is used to + cache all searches that resulted in successful binds. + Negative results (i.e., unsuccessful searches, or searches + that did not result in a successful bind) are not cached. + The rationale behind this decision is that connections with + invalid credentials are only a tiny percentage of the total + number of connections, so by not caching invalid + credentials, the size of the cache is reduced.

    + +

    mod_ldap stores the username, the DN + retrieved, the password used to bind, and the time of the bind + in the cache. Whenever a new connection is initiated with the + same username, mod_ldap compares the password + of the new connection with the password in the cache. If the + passwords match, and if the cached entry is not too old, + mod_ldap bypasses the search/bind phase.

    + +

    The search and bind cache is controlled with the LDAPCacheEntries and LDAPCacheTTL directives.

    + + +

    Operation Caches

    +

    During attribute and distinguished name comparison + functions, mod_ldap uses two operation caches + to cache the compare operations. The first compare cache is + used to cache the results of compares done to test for LDAP + group membership. The second compare cache is used to cache + the results of comparisons done between distinguished + names.

    + +

    The behavior of both of these caches is controlled with + the LDAPOpCacheEntries + and LDAPOpCacheTTL + directives.

    + + +

    Monitoring the Cache

    +

    mod_ldap has a content handler that allows + administrators to monitor the cache performance. The name of + the content handler is ldap-status, so the + following directives could be used to access the + mod_ldap cache information:

    + +

    + <Location /server/cache-info>
    + + SetHandler ldap-status
    +
    + </Location> +

    + +

    By fetching the URL http://servername/cache-info, + the administrator can get a status report of every cache that is used + by mod_ldap cache. Note that if Apache does not + support shared memory, then each httpd instance has its + own cache, so reloading the URL will result in different + information each time, depending on which httpd + instance processes the request.

    + +
    top
    +
    +

    Using SSL/TLS

    + +

    The ability to create an SSL and TLS connections to an LDAP server + is defined by the directives + LDAPTrustedGlobalCert, + LDAPTrustedClientCert and + LDAPTrustedMode. These directives specify the CA and + optional client certificates to be used, as well as the type of + encryption to be used on the connection (none, SSL or TLS/STARTTLS).

    + +

    + # Establish an SSL LDAP connection on port 636. Requires that
    + # mod_ldap and mod_authnz_ldap be loaded. Change the
    + # "yourdomain.example.com" to match your domain.
    +
    + LDAPTrustedGlobalCert CA_DER /certs/certfile.der
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +

    + +

    + # Establish a TLS LDAP connection on port 389. Requires that
    + # mod_ldap and mod_authnz_ldap be loaded. Change the
    + # "yourdomain.example.com" to match your domain.
    +
    + LDAPTrustedGlobalCert CA_DER /certs/certfile.der
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedMode TLS + AuthLDAPURL ldap://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +

    + +
    top
    +
    +

    SSL/TLS Certificates

    + +

    The different LDAP SDKs have widely different methods of setting + and handling both CA and client side certificates.

    + +

    If you intend to use SSL or TLS, read this section CAREFULLY so as to + understand the differences between configurations on the different LDAP + toolkits supported.

    + +

    Netscape/Mozilla/iPlanet SDK

    +

    CA certificates are specified within a file called cert7.db. + The SDK will not talk to any LDAP server whose certificate was + not signed by a CA specified in this file. If + client certificates are required, an optional key3.db file may + be specified with an optional password. The secmod file can be + specified if required. These files are in the same format as + used by the Netscape Communicator or Mozilla web browsers. The easiest + way to obtain these files is to grab them from your browser + installation.

    + +

    Client certificates are specified per connection using the + LDAPTrustedClientCert directive by referring + to the certificate "nickname". An optional password may be + specified to unlock the certificate's private key.

    + +

    The SDK supports SSL only. An attempt to use STARTTLS will cause + an error when an attempt is made to contact the LDAP server at + runtime.

    + +

    + # Specify a Netscape CA certificate file
    + LDAPTrustedGlobalCert CA_CERT7_DB /certs/cert7.db
    + # Specify an optional key3.db file for client certificate support
    + LDAPTrustedGlobalCert CERT_KEY3_DB /certs/key3.db
    + # Specify the secmod file if required
    + LDAPTrustedGlobalCert CA_SECMOD /certs/secmod
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedClientCert CERT_NICKNAME <nickname> [password]
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +

    + + + +

    Novell SDK

    + +

    One or more CA certificates must be specified for the Novell + SDK to work correctly. These certificates can be specified as + binary DER or Base64 (PEM) encoded files.

    + +

    Note: Client certificates are specified globally rather than per + connection, and so must be specified with the LDAPTrustedGlobalCert + directive as below. Trying to set client certificates via the + LDAPTrustedClientCert directive will cause an error to be logged + when an attempt is made to connect to the LDAP server..

    + +

    The SDK supports both SSL and STARTTLS, set using the + LDAPTrustedMode parameter. If an ldaps:// URL is specified, + SSL mode is forced, override this directive.

    + +

    + # Specify two CA certificate files
    + LDAPTrustedGlobalCert CA_DER /certs/cacert1.der
    + LDAPTrustedGlobalCert CA_BASE64 /certs/cacert2.pem
    + # Specify a client certificate file and key
    + LDAPTrustedGlobalCert CERT_BASE64 /certs/cert1.pem
    + LDAPTrustedGlobalCert KEY_BASE64 /certs/key1.pem [password]
    + # Do not use this directive, as it will throw an error
    + #LDAPTrustedClientCert CERT_BASE64 /certs/cert1.pem
    +

    + + + +

    OpenLDAP SDK

    + +

    One or more CA certificates must be specified for the OpenLDAP + SDK to work correctly. These certificates can be specified as + binary DER or Base64 (PEM) encoded files.

    + +

    Client certificates are specified per connection using the + LDAPTrustedClientCert directive.

    + +

    The documentation for the SDK claims to support both SSL and + STARTTLS, however STARTTLS does not seem to work on all versions + of the SDK. The SSL/TLS mode can be set using the + LDAPTrustedMode parameter. If an ldaps:// URL is specified, + SSL mode is forced. The OpenLDAP documentation notes that SSL + (ldaps://) support has been deprecated to be replaced with TLS, + although the SSL functionality still works.

    + +

    + # Specify two CA certificate files
    + LDAPTrustedGlobalCert CA_DER /certs/cacert1.der
    + LDAPTrustedGlobalCert CA_BASE64 /certs/cacert2.pem
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedClientCert CERT_BASE64 /certs/cert1.pem
    + LDAPTrustedClientCert KEY_BASE64 /certs/key1.pem
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +

    + + + +

    Solaris SDK

    + +

    SSL/TLS for the native Solaris LDAP libraries is not yet + supported. If required, install and use the OpenLDAP libraries + instead.

    + + + +

    Microsoft SDK

    + +

    SSL/TLS certificate configuration for the native Microsoft + LDAP libraries is done inside the system registry, and no + configuration directives are required.

    + +

    Both SSL and TLS are supported by using the ldaps:// URL + format, or by using the LDAPTrustedMode directive accordingly.

    + +

    Note: The status of support for client certificates is not yet known + for this toolkit.

    + + + +
    +
    top
    +

    LDAPCacheEntries Directive

    + + + + + + + +
    Description:Maximum number of entries in the primary LDAP cache
    Syntax:LDAPCacheEntries number
    Default:LDAPCacheEntries 1024
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the maximum size of the primary LDAP cache. This + cache contains successful search/binds. Set it to 0 to turn off + search/bind caching. The default size is 1024 cached + searches.

    + +
    +
    top
    +

    LDAPCacheTTL Directive

    + + + + + + + +
    Description:Time that cached items remain valid
    Syntax:LDAPCacheTTL seconds
    Default:LDAPCacheTTL 600
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the time (in seconds) that an item in the + search/bind cache remains valid. The default is 600 seconds (10 + minutes).

    + +
    +
    top
    +

    LDAPConnectionTimeout Directive

    + + + + + + +
    Description:Specifies the socket connection timeout in seconds
    Syntax:LDAPConnectionTimeout seconds
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the timeout value (in seconds) in which the module will + attempt to connect to the LDAP server. If a connection is not + successful with the timeout period, either an error will be + returned or the module will attempt to connect to a secondary LDAP + server if one is specified. The default is 10 seconds.

    + +
    +
    top
    +

    LDAPOpCacheEntries Directive

    + + + + + + + +
    Description:Number of entries used to cache LDAP compare +operations
    Syntax:LDAPOpCacheEntries number
    Default:LDAPOpCacheEntries 1024
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    This specifies the number of entries mod_ldap + will use to cache LDAP compare operations. The default is 1024 + entries. Setting it to 0 disables operation caching.

    + +
    +
    top
    +

    LDAPOpCacheTTL Directive

    + + + + + + + +
    Description:Time that entries in the operation cache remain +valid
    Syntax:LDAPOpCacheTTL seconds
    Default:LDAPOpCacheTTL 600
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the time (in seconds) that entries in the + operation cache remain valid. The default is 600 seconds.

    + +
    +
    top
    +

    LDAPSharedCacheFile Directive

    + + + + + + +
    Description:Sets the shared memory cache file
    Syntax:LDAPSharedCacheFile directory-path/filename
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the directory path and file name of the shared memory + cache file. If not set, anonymous shared memory will be used if the + platform supports it.

    + +
    +
    top
    +

    LDAPSharedCacheSize Directive

    + + + + + + + +
    Description:Size in bytes of the shared-memory cache
    Syntax:LDAPSharedCacheSize bytes
    Default:LDAPSharedCacheSize 102400
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies the number of bytes to allocate for the shared + memory cache. The default is 100kb. If set to 0, shared memory + caching will not be used.

    + +
    +
    top
    +

    LDAPTrustedClientCert Directive

    + + + + + + +
    Description:Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    Syntax:LDAPTrustedClientCert type directory-path/filename/nickname [password]
    Context:server config, virtual host, directory, .htaccess
    Status:Extension
    Module:mod_ldap
    +

    It specifies the directory path, file name or nickname of a + per connection client certificate used when establishing an SSL + or TLS connection to an LDAP server. Different locations or + directories may have their own independant client certificate + settings. Some LDAP toolkits (notably Novell) + do not support per connection client certificates, and will throw an + error on LDAP server connection if you try to use this directive + (Use the LDAPTrustedGlobalCert directive instead for Novell client + certificates - See the SSL/TLS certificate guide above for details). + The type specifies the kind of certificate parameter being + set, depending on the LDAP toolkit being used. Supported types are:

    +
      +
    • CERT_DER - binary DER encoded client certificate
    • +
    • CERT_BASE64 - PEM encoded client certificate
    • +
    • CERT_NICKNAME - Client certificate "nickname" (Netscape SDK)
    • +
    • KEY_DER - binary DER encoded private key
    • +
    • KEY_BASE64 - PEM encoded private key
    • +
    + +
    +
    top
    +

    LDAPTrustedGlobalCert Directive

    + + + + + + +
    Description:Sets the file or database containing global trusted +Certificate Authority or global client certificates
    Syntax:LDAPTrustedGlobalCert type directory-path/filename [password]
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    It specifies the directory path and file name of the trusted CA + certificates and/or system wide client certificates mod_ldap + should use when establishing an SSL or TLS connection to an LDAP + server. Note that all certificate information specified using this directive + is applied globally to the entire server installation. Some LDAP toolkits + (notably Novell) require all client certificates to be set globally using + this directive. Most other toolkits require clients certificates to be set + per Directory or per Location using LDAPTrustedClientCert. If you get this + wrong, an error may be logged when an attempt is made to contact the LDAP + server, or the connection may silently fail (See the SSL/TLS certificate + guide above for details). + The type specifies the kind of certificate parameter being + set, depending on the LDAP toolkit being used. Supported types are:

    +
      +
    • CA_DER - binary DER encoded CA certificate
    • +
    • CA_BASE64 - PEM encoded CA certificate
    • +
    • CA_CERT7_DB - Netscape cert7.db CA certificate database file
    • +
    • CA_SECMOD - Netscape secmod database file
    • +
    • CERT_DER - binary DER encoded client certificate
    • +
    • CERT_BASE64 - PEM encoded client certificate
    • +
    • CERT_KEY3_DB - Netscape key3.db client certificate database file
    • +
    • CERT_NICKNAME - Client certificate "nickname" (Netscape SDK)
    • +
    • CERT_PFX - PKCS#12 encoded client certificate (Novell SDK)
    • +
    • KEY_DER - binary DER encoded private key
    • +
    • KEY_BASE64 - PEM encoded private key
    • +
    • KEY_PFX - PKCS#12 encoded private key (Novell SDK)
    • +
    + +
    +
    top
    +

    LDAPTrustedMode Directive

    + + + + + + +
    Description:Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    Syntax:LDAPTrustedMode type
    Context:server config, virtual host, directory, .htaccess
    Status:Extension
    Module:mod_ldap
    +

    The following modes are supported:

    +
      +
    • NONE - no encryption
    • +
    • SSL - ldaps:// encryption on default port 636
    • +
    • TLS - STARTTLS encryption on default port 389
    • +
    + +

    Not all LDAP toolkits support all the above modes. An error message + will be logged at runtime if a mode is not supported, and the + connection to the LDAP server will fail. +

    + +

    If an ldaps:// URL is specified, the mode becomes SSL and the setting + of LDAPTrustedMode is ignored.

    + +
    +
    top
    +

    LDAPVerifyServerCert Directive

    + + + + + + + +
    Description:Force server certificate verification
    Syntax:LDAPVerifyServerCert On|Off
    Default:LDAPVerifyServerCert On
    Context:server config
    Status:Extension
    Module:mod_ldap
    +

    Specifies whether to force the verification of a + server certificate when establishing an SSL connection to the + LDAP server.

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ldap.xml b/trunk/docs/manual/mod/mod_ldap.xml new file mode 100644 index 0000000000..f0d3fde797 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ldap.xml @@ -0,0 +1,598 @@ + + + + + + + + + +mod_ldap +LDAP connection pooling and result caching services for use +by other LDAP modules +Extension +util_ldap.c +ldap_module +Available in version 2.0.41 and later + + +

    This module was created to improve the performance of + websites relying on backend connections to LDAP servers. In + addition to the functions provided by the standard LDAP + libraries, this module adds an LDAP connection pool and an LDAP + shared memory cache.

    + +

    To enable this module, LDAP support must be compiled into + apr-util. This is achieved by adding the --with-ldap + flag to the configure script when building + Apache.

    + +

    SSL/TLS support is dependant on which LDAP toolkit has been + linked to APR. As of this writing, APR-util supports: + OpenLDAP SDK (2.x or later), + Novell LDAP + SDK, + Mozilla LDAP SDK, native Solaris LDAP SDK (Mozilla based), + native Microsoft LDAP SDK, or the + iPlanet + (Netscape) SDK. See the APR + website for details.

    + +
    + +
    Example Configuration +

    The following is an example configuration that uses + mod_ldap to increase the performance of HTTP Basic + authentication provided by mod_authnz_ldap.

    + + + # Enable the LDAP connection pool and shared
    + # memory cache. Enable the LDAP cache status
    + # handler. Requires that mod_ldap and mod_authnz_ldap
    + # be loaded. Change the "yourdomain.example.com" to
    + # match your domain.
    +
    + LDAPSharedCacheSize 200000
    + LDAPCacheEntries 1024
    + LDAPCacheTTL 600
    + LDAPOpCacheEntries 1024
    + LDAPOpCacheTTL 600
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + AuthLDAPURL ldap://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +
    +
    + +
    LDAP Connection Pool + +

    LDAP connections are pooled from request to request. This + allows the LDAP server to remain connected and bound ready for + the next request, without the need to unbind/connect/rebind. + The performance advantages are similar to the effect of HTTP + keepalives.

    + +

    On a busy server it is possible that many requests will try + and access the same LDAP server connection simultaneously. + Where an LDAP connection is in use, Apache will create a new + connection alongside the original one. This ensures that the + connection pool does not become a bottleneck.

    + +

    There is no need to manually enable connection pooling in + the Apache configuration. Any module using this module for + access to LDAP services will share the connection pool.

    +
    + +
    LDAP Cache + +

    For improved performance, mod_ldap uses an aggressive + caching strategy to minimize the number of times that the LDAP + server must be contacted. Caching can easily double or triple + the throughput of Apache when it is serving pages protected + with mod_authnz_ldap. In addition, the load on the LDAP server + will be significantly decreased.

    + +

    mod_ldap supports two types of LDAP caching during + the search/bind phase with a search/bind cache and + during the compare phase with two operation + caches. Each LDAP URL that is used by the server has + its own set of these three caches.

    + +
    The Search/Bind Cache +

    The process of doing a search and then a bind is the + most time-consuming aspect of LDAP operation, especially if + the directory is large. The search/bind cache is used to + cache all searches that resulted in successful binds. + Negative results (i.e., unsuccessful searches, or searches + that did not result in a successful bind) are not cached. + The rationale behind this decision is that connections with + invalid credentials are only a tiny percentage of the total + number of connections, so by not caching invalid + credentials, the size of the cache is reduced.

    + +

    mod_ldap stores the username, the DN + retrieved, the password used to bind, and the time of the bind + in the cache. Whenever a new connection is initiated with the + same username, mod_ldap compares the password + of the new connection with the password in the cache. If the + passwords match, and if the cached entry is not too old, + mod_ldap bypasses the search/bind phase.

    + +

    The search and bind cache is controlled with the LDAPCacheEntries and LDAPCacheTTL directives.

    +
    + +
    Operation Caches +

    During attribute and distinguished name comparison + functions, mod_ldap uses two operation caches + to cache the compare operations. The first compare cache is + used to cache the results of compares done to test for LDAP + group membership. The second compare cache is used to cache + the results of comparisons done between distinguished + names.

    + +

    The behavior of both of these caches is controlled with + the LDAPOpCacheEntries + and LDAPOpCacheTTL + directives.

    +
    + +
    Monitoring the Cache +

    mod_ldap has a content handler that allows + administrators to monitor the cache performance. The name of + the content handler is ldap-status, so the + following directives could be used to access the + mod_ldap cache information:

    + + + <Location /server/cache-info>
    + + SetHandler ldap-status
    +
    + </Location> +
    + +

    By fetching the URL http://servername/cache-info, + the administrator can get a status report of every cache that is used + by mod_ldap cache. Note that if Apache does not + support shared memory, then each httpd instance has its + own cache, so reloading the URL will result in different + information each time, depending on which httpd + instance processes the request.

    +
    +
    + +
    Using SSL/TLS + +

    The ability to create an SSL and TLS connections to an LDAP server + is defined by the directives + LDAPTrustedGlobalCert, + LDAPTrustedClientCert and + LDAPTrustedMode. These directives specify the CA and + optional client certificates to be used, as well as the type of + encryption to be used on the connection (none, SSL or TLS/STARTTLS).

    + + + # Establish an SSL LDAP connection on port 636. Requires that
    + # mod_ldap and mod_authnz_ldap be loaded. Change the
    + # "yourdomain.example.com" to match your domain.
    +
    + LDAPTrustedGlobalCert CA_DER /certs/certfile.der
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +
    + + + # Establish a TLS LDAP connection on port 389. Requires that
    + # mod_ldap and mod_authnz_ldap be loaded. Change the
    + # "yourdomain.example.com" to match your domain.
    +
    + LDAPTrustedGlobalCert CA_DER /certs/certfile.der
    +
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedMode TLS + AuthLDAPURL ldap://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +
    + +
    + +
    SSL/TLS Certificates + +

    The different LDAP SDKs have widely different methods of setting + and handling both CA and client side certificates.

    + +

    If you intend to use SSL or TLS, read this section CAREFULLY so as to + understand the differences between configurations on the different LDAP + toolkits supported.

    + +
    Netscape/Mozilla/iPlanet SDK +

    CA certificates are specified within a file called cert7.db. + The SDK will not talk to any LDAP server whose certificate was + not signed by a CA specified in this file. If + client certificates are required, an optional key3.db file may + be specified with an optional password. The secmod file can be + specified if required. These files are in the same format as + used by the Netscape Communicator or Mozilla web browsers. The easiest + way to obtain these files is to grab them from your browser + installation.

    + +

    Client certificates are specified per connection using the + LDAPTrustedClientCert directive by referring + to the certificate "nickname". An optional password may be + specified to unlock the certificate's private key.

    + +

    The SDK supports SSL only. An attempt to use STARTTLS will cause + an error when an attempt is made to contact the LDAP server at + runtime.

    + + + # Specify a Netscape CA certificate file
    + LDAPTrustedGlobalCert CA_CERT7_DB /certs/cert7.db
    + # Specify an optional key3.db file for client certificate support
    + LDAPTrustedGlobalCert CERT_KEY3_DB /certs/key3.db
    + # Specify the secmod file if required
    + LDAPTrustedGlobalCert CA_SECMOD /certs/secmod
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedClientCert CERT_NICKNAME <nickname> [password]
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +
    + +
    + +
    Novell SDK + +

    One or more CA certificates must be specified for the Novell + SDK to work correctly. These certificates can be specified as + binary DER or Base64 (PEM) encoded files.

    + +

    Note: Client certificates are specified globally rather than per + connection, and so must be specified with the LDAPTrustedGlobalCert + directive as below. Trying to set client certificates via the + LDAPTrustedClientCert directive will cause an error to be logged + when an attempt is made to connect to the LDAP server..

    + +

    The SDK supports both SSL and STARTTLS, set using the + LDAPTrustedMode parameter. If an ldaps:// URL is specified, + SSL mode is forced, override this directive.

    + + + # Specify two CA certificate files
    + LDAPTrustedGlobalCert CA_DER /certs/cacert1.der
    + LDAPTrustedGlobalCert CA_BASE64 /certs/cacert2.pem
    + # Specify a client certificate file and key
    + LDAPTrustedGlobalCert CERT_BASE64 /certs/cert1.pem
    + LDAPTrustedGlobalCert KEY_BASE64 /certs/key1.pem [password]
    + # Do not use this directive, as it will throw an error
    + #LDAPTrustedClientCert CERT_BASE64 /certs/cert1.pem
    +
    + +
    + +
    OpenLDAP SDK + +

    One or more CA certificates must be specified for the OpenLDAP + SDK to work correctly. These certificates can be specified as + binary DER or Base64 (PEM) encoded files.

    + +

    Client certificates are specified per connection using the + LDAPTrustedClientCert directive.

    + +

    The documentation for the SDK claims to support both SSL and + STARTTLS, however STARTTLS does not seem to work on all versions + of the SDK. The SSL/TLS mode can be set using the + LDAPTrustedMode parameter. If an ldaps:// URL is specified, + SSL mode is forced. The OpenLDAP documentation notes that SSL + (ldaps://) support has been deprecated to be replaced with TLS, + although the SSL functionality still works.

    + + + # Specify two CA certificate files
    + LDAPTrustedGlobalCert CA_DER /certs/cacert1.der
    + LDAPTrustedGlobalCert CA_BASE64 /certs/cacert2.pem
    + <Location /ldap-status>
    + + SetHandler ldap-status
    + Order deny,allow
    + Deny from all
    + Allow from yourdomain.example.com
    + AuthLDAPEnabled on
    + LDAPTrustedClientCert CERT_BASE64 /certs/cert1.pem
    + LDAPTrustedClientCert KEY_BASE64 /certs/key1.pem
    + AuthLDAPURL ldaps://127.0.0.1/dc=example,dc=com?uid?one
    + AuthLDAPAuthoritative on
    + require valid-user
    +
    + </Location> +
    + +
    + +
    Solaris SDK + +

    SSL/TLS for the native Solaris LDAP libraries is not yet + supported. If required, install and use the OpenLDAP libraries + instead.

    + +
    + +
    Microsoft SDK + +

    SSL/TLS certificate configuration for the native Microsoft + LDAP libraries is done inside the system registry, and no + configuration directives are required.

    + +

    Both SSL and TLS are supported by using the ldaps:// URL + format, or by using the LDAPTrustedMode directive accordingly.

    + +

    Note: The status of support for client certificates is not yet known + for this toolkit.

    + +
    + +
    + + +LDAPSharedCacheSize +Size in bytes of the shared-memory cache +LDAPSharedCacheSize bytes +LDAPSharedCacheSize 102400 +server config + + +

    Specifies the number of bytes to allocate for the shared + memory cache. The default is 100kb. If set to 0, shared memory + caching will not be used.

    +
    +
    + + +LDAPSharedCacheFile +Sets the shared memory cache file +LDAPSharedCacheFile directory-path/filename +server config + + +

    Specifies the directory path and file name of the shared memory + cache file. If not set, anonymous shared memory will be used if the + platform supports it.

    +
    +
    + + +LDAPCacheEntries +Maximum number of entries in the primary LDAP cache +LDAPCacheEntries number +LDAPCacheEntries 1024 +server config + + +

    Specifies the maximum size of the primary LDAP cache. This + cache contains successful search/binds. Set it to 0 to turn off + search/bind caching. The default size is 1024 cached + searches.

    +
    +
    + + +LDAPCacheTTL +Time that cached items remain valid +LDAPCacheTTL seconds +LDAPCacheTTL 600 +server config + + +

    Specifies the time (in seconds) that an item in the + search/bind cache remains valid. The default is 600 seconds (10 + minutes).

    +
    +
    + + +LDAPOpCacheEntries +Number of entries used to cache LDAP compare +operations +LDAPOpCacheEntries number +LDAPOpCacheEntries 1024 +server config + + +

    This specifies the number of entries mod_ldap + will use to cache LDAP compare operations. The default is 1024 + entries. Setting it to 0 disables operation caching.

    +
    +
    + + +LDAPOpCacheTTL +Time that entries in the operation cache remain +valid +LDAPOpCacheTTL seconds +LDAPOpCacheTTL 600 +server config + + +

    Specifies the time (in seconds) that entries in the + operation cache remain valid. The default is 600 seconds.

    +
    +
    + + +LDAPTrustedGlobalCert +Sets the file or database containing global trusted +Certificate Authority or global client certificates +LDAPTrustedGlobalCert type directory-path/filename [password] +server config + + +

    It specifies the directory path and file name of the trusted CA + certificates and/or system wide client certificates mod_ldap + should use when establishing an SSL or TLS connection to an LDAP + server. Note that all certificate information specified using this directive + is applied globally to the entire server installation. Some LDAP toolkits + (notably Novell) require all client certificates to be set globally using + this directive. Most other toolkits require clients certificates to be set + per Directory or per Location using LDAPTrustedClientCert. If you get this + wrong, an error may be logged when an attempt is made to contact the LDAP + server, or the connection may silently fail (See the SSL/TLS certificate + guide above for details). + The type specifies the kind of certificate parameter being + set, depending on the LDAP toolkit being used. Supported types are:

    +
      +
    • CA_DER - binary DER encoded CA certificate
    • +
    • CA_BASE64 - PEM encoded CA certificate
    • +
    • CA_CERT7_DB - Netscape cert7.db CA certificate database file
    • +
    • CA_SECMOD - Netscape secmod database file
    • +
    • CERT_DER - binary DER encoded client certificate
    • +
    • CERT_BASE64 - PEM encoded client certificate
    • +
    • CERT_KEY3_DB - Netscape key3.db client certificate database file
    • +
    • CERT_NICKNAME - Client certificate "nickname" (Netscape SDK)
    • +
    • CERT_PFX - PKCS#12 encoded client certificate (Novell SDK)
    • +
    • KEY_DER - binary DER encoded private key
    • +
    • KEY_BASE64 - PEM encoded private key
    • +
    • KEY_PFX - PKCS#12 encoded private key (Novell SDK)
    • +
    +
    +
    + + +LDAPTrustedClientCert +Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates. +LDAPTrustedClientCert type directory-path/filename/nickname [password] +server configvirtual host +directory.htaccess + + +

    It specifies the directory path, file name or nickname of a + per connection client certificate used when establishing an SSL + or TLS connection to an LDAP server. Different locations or + directories may have their own independant client certificate + settings. Some LDAP toolkits (notably Novell) + do not support per connection client certificates, and will throw an + error on LDAP server connection if you try to use this directive + (Use the LDAPTrustedGlobalCert directive instead for Novell client + certificates - See the SSL/TLS certificate guide above for details). + The type specifies the kind of certificate parameter being + set, depending on the LDAP toolkit being used. Supported types are:

    +
      +
    • CERT_DER - binary DER encoded client certificate
    • +
    • CERT_BASE64 - PEM encoded client certificate
    • +
    • CERT_NICKNAME - Client certificate "nickname" (Netscape SDK)
    • +
    • KEY_DER - binary DER encoded private key
    • +
    • KEY_BASE64 - PEM encoded private key
    • +
    +
    +
    + + +LDAPTrustedMode +Specifies the SSL/TLS mode to be used when connecting to an LDAP server. +LDAPTrustedMode type +server configvirtual host +directory.htaccess + + +

    The following modes are supported:

    +
      +
    • NONE - no encryption
    • +
    • SSL - ldaps:// encryption on default port 636
    • +
    • TLS - STARTTLS encryption on default port 389
    • +
    + +

    Not all LDAP toolkits support all the above modes. An error message + will be logged at runtime if a mode is not supported, and the + connection to the LDAP server will fail. +

    + +

    If an ldaps:// URL is specified, the mode becomes SSL and the setting + of LDAPTrustedMode is ignored.

    +
    +
    + + +LDAPConnectionTimeout +Specifies the socket connection timeout in seconds +LDAPConnectionTimeout seconds +server config + + +

    Specifies the timeout value (in seconds) in which the module will + attempt to connect to the LDAP server. If a connection is not + successful with the timeout period, either an error will be + returned or the module will attempt to connect to a secondary LDAP + server if one is specified. The default is 10 seconds.

    +
    +
    + + +LDAPVerifyServerCert +Force server certificate verification +LDAPVerifyServerCert On|Off +LDAPVerifyServerCert On +server config + + +

    Specifies whether to force the verification of a + server certificate when establishing an SSL connection to the + LDAP server.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_ldap.xml.meta b/trunk/docs/manual/mod/mod_ldap.xml.meta new file mode 100644 index 0000000000..a66e24a5cb --- /dev/null +++ b/trunk/docs/manual/mod/mod_ldap.xml.meta @@ -0,0 +1,11 @@ + + + + mod_ldap + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_log_config.html b/trunk/docs/manual/mod/mod_log_config.html new file mode 100644 index 0000000000..342249126e --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.html @@ -0,0 +1,11 @@ +URI: mod_log_config.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_log_config.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_log_config.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_log_config.html.en b/trunk/docs/manual/mod/mod_log_config.html.en new file mode 100644 index 0000000000..53a4b8c60f --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.html.en @@ -0,0 +1,470 @@ + + + +mod_log_config - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_log_config

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Logging of the requests made to the server
    Status:Base
    Module Identifier:log_config_module
    Source File:mod_log_config.c
    +

    Summary

    + +

    This module provides for flexible logging of client + requests. Logs are written in a customizable format, and may be + written directly to a file, or to an external program. + Conditional logging is provided so that individual requests may + be included or excluded from the logs based on characteristics + of the request.

    + +

    Three directives are provided by this module: + TransferLog to create + a log file, LogFormat + to set a custom format, and CustomLog to define a log file and format in one + step. The TransferLog and CustomLog directives can be used multiple times in each + server to cause each request to be logged to multiple files.

    +
    + +
    top
    +
    +

    Custom Log Formats

    + +

    The format argument to the LogFormat and CustomLog directives is a string. This string is + used to log each request to the log file. It can contain literal + characters copied into the log files and the C-style control + characters "\n" and "\t" to represent new-lines and tabs. + Literal quotes and back-slashes should be escaped with + back-slashes.

    + +

    The characteristics of the request itself are logged by + placing "%" directives in the format string, which are + replaced in the log file by the values as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Format StringDescription
    %%The percent sign
    %aRemote IP-address
    %ALocal IP-address
    %BSize of response in bytes, excluding HTTP headers.
    %bSize of response in bytes, excluding HTTP headers. In CLF format, i.e. + a '-' rather than a 0 when no bytes are sent.
    %{Foobar}CThe contents of cookie Foobar in the request sent + to the server.
    %DThe time taken to serve the request, in microseconds.
    %{FOOBAR}eThe contents of the environment variable + FOOBAR
    %fFilename
    %hRemote host
    %HThe request protocol
    %{Foobar}iThe contents of Foobar: header line(s) + in the request sent to the server.
    %lRemote logname (from identd, if supplied). This will return a + dash unless mod_ident is present and IdentityCheck is set + On.
    %mThe request method
    %{Foobar}nThe contents of note Foobar from another + module.
    %{Foobar}oThe contents of Foobar: header line(s) + in the reply.
    %pThe canonical port of the server serving the request
    %PThe process ID of the child that serviced the request.
    %{format}PThe process ID or thread id of the child that serviced the + request. Valid formats are pid and tid. +
    %qThe query string (prepended with a ? if a query + string exists, otherwise an empty string)
    %rFirst line of request
    %sStatus. For requests that got internally redirected, this is + the status of the *original* request --- %>s + for the last.
    %tTime the request was received (standard english + format)
    %{format}tThe time, in the form given by format, which should be in + strftime(3) format. (potentially localized)
    %TThe time taken to serve the request, in seconds.
    %uRemote user (from auth; may be bogus if return status + (%s) is 401)
    %UThe URL path requested, not including any query string.
    %vThe canonical ServerName + of the server serving the request.
    %VThe server name according to the UseCanonicalName setting.
    %XConnection status when response is completed: + + + + + + + + + +
    X =connection aborted before the response completed.
    + =connection may be kept alive after the response is + sent.
    - = connection will be closed after the response is + sent.
    + +

    (This directive was %c in late versions of Apache + 1.3, but this conflicted with the historical ssl + %{var}c syntax.)

    %IBytes received, including request and headers, cannot be zero. + You need to enable mod_logio to use this.
    %OBytes sent, including headers, cannot be zero. You need to + enable mod_logio to use this.
    + +

    Modifiers

    + +

    Particular items can be restricted to print only for + responses with specific HTTP status codes by placing a + comma-separated list of status codes immediately following the + "%". For example, "%400,501{User-agent}i" logs + User-agent on 400 errors and 501 errors only. For + other status codes, the literal string "-" will be + logged. The status code list may be preceded by a + "!" to indicate negation: + "%!200,304,302{Referer}i" logs Referer + on all requests that do not return one of the three + specified codes.

    + +

    The modifiers "<" and ">" can be used for requests that + have been internally redirected to choose whether the original + or final (respectively) request should be consulted. By + default, the % directives %s, %U, %T, + %D, and %r look at the original request + while all others look at the final request. So for example, + %>s can be used to record the final status of + the request and %<u can be used to record the + original authenticated user on a request that is internally + redirected to an unauthenticated resource.

    + + + +

    Some Notes

    + +

    For security reasons, starting with version 2.0.46, + non-printable and other special characters in %r, + %i and %o are escaped using + \xhh sequences, where hh + stands for the hexadecimal representation of the raw + byte. Exceptions from this rule are " and + \, which are escaped by prepending a backslash, and + all whitespace characters, which are written in their C-style + notation (\n, \t, etc). In versions + prior to 2.0.46, no escaping was performed on these strings so + you had to be quite careful when dealing with raw log files.

    + +

    In httpd 2.0, unlike 1.3, the %b and + %B format strings do not represent the number of + bytes sent to the client, but simply the size in bytes of the + HTTP response (which will differ, for instance, if the + connection is aborted, or if SSL is used). The %O + format provided by mod_logio will log the + actual number of bytes sent over the network.

    + + + +

    Examples

    + +

    Some commonly used log format strings are:

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    Common Log Format with Virtual Host
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined log format
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer log format
    +
    "%{Referer}i -> %U"
    + +
    Agent (Browser) log format
    +
    "%{User-agent}i"
    +
    + +
    top
    +
    +

    Security Considerations

    +

    See the security tips + document for details on why your security could be compromised + if the directory where logfiles are stored is writable by + anyone other than the user that starts the server.

    +
    +
    top
    +

    BufferedLogs Directive

    + + + + + + + + +
    Description:Buffer log entries in memory before writing to disk
    Syntax:BufferedLogs On|Off
    Default:BufferedLogs Off
    Context:server config
    Status:Base
    Module:mod_log_config
    Compatibility:Available in versions 2.0.41 and later.
    +

    The BufferedLogs directive causes + mod_log_config to store several log entries in + memory and write them together to disk, rather than writing them + after each request. On some systems, this may result in more + efficient disk access and hence higher performance. It may be + set only once for the entire server; it cannot be configured + per virtual-host.

    + +
    This directive is experimental and should be used with + caution.
    + +
    +
    top
    +

    CookieLog Directive

    + + + + + + + +
    Description:Sets filename for the logging of cookies
    Syntax:CookieLog filename
    Context:server config, virtual host
    Status:Base
    Module:mod_log_config
    Compatibility:This directive is deprecated.
    +

    The CookieLog directive sets the + filename for logging of cookies. The filename is relative to the + ServerRoot. This directive is + included only for compatibility with mod_cookies, + and is deprecated.

    + +
    +
    top
    +

    CustomLog Directive

    + + + + + + +
    Description:Sets filename and format of log file
    Syntax:CustomLog file|pipe +format|nickname +[env=[!]environment-variable]
    Context:server config, virtual host
    Status:Base
    Module:mod_log_config
    +

    The CustomLog directive is used to + log requests to the server. A log format is specified, and the + logging can optionally be made conditional on request + characteristics using environment variables.

    + +

    The first argument, which specifies the location to which + the logs will be written, can take one of the following two + types of values:

    + +
    +
    file
    +
    A filename, relative to the ServerRoot.
    + +
    pipe
    +
    The pipe character "|", followed by the path + to a program to receive the log information on its standard + input. + +

    Security:

    +

    If a program is used, then it will be run as the user who + started httpd. This will be root if the server was + started by root; be sure that the program is secure.

    +
    +

    Note

    +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    +
    + +

    The second argument specifies what will be written to the + log file. It can specify either a nickname defined by + a previous LogFormat + directive, or it can be an explicit format string as + described in the log formats section.

    + +

    For example, the following two sets of directives have + exactly the same effect:

    + +

    + # CustomLog with format nickname
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # CustomLog with explicit format string
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +

    + +

    The third argument is optional and controls whether or + not to log a particular request based on the + presence or absence of a particular variable in the server + environment. If the specified environment + variable is set for the request (or is not set, in the case + of a 'env=!name' clause), then the + request will be logged.

    + +

    Environment variables can be set on a per-request + basis using the mod_setenvif + and/or mod_rewrite modules. For + example, if you want to record requests for all GIF + images on your server in a separate logfile but not in your main + log, you can use:

    + +

    + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +

    + +

    Or, to reproduce the behavior of the old RefererIgnore + directive, you might use the following:

    + +

    + SetEnvIf Referer example\.com localreferer
    + CustomLog referer.log referer env=!localreferer +

    + +
    +
    top
    +

    LogFormat Directive

    + + + + + + + +
    Description:Describes a format for use in a log file
    Syntax:LogFormat format|nickname +[nickname]
    Default:LogFormat "%h %l %u %t \"%r\" %>s %b"
    Context:server config, virtual host
    Status:Base
    Module:mod_log_config
    +

    This directive specifies the format of the access log + file.

    + +

    The LogFormat directive can take one of two + forms. In the first form, where only one argument is specified, + this directive sets the log format which will be used by logs + specified in subsequent TransferLog + directives. The single argument can specify an explicit + format as discussed in the custom log + formats section above. Alternatively, it can use a + nickname to refer to a log format defined in a + previous LogFormat directive as described + below.

    + +

    The second form of the LogFormat + directive associates an explicit format with a + nickname. This nickname can then be used in + subsequent LogFormat or + CustomLog directives + rather than repeating the entire format string. A + LogFormat directive that defines a nickname + does nothing else -- that is, it only + defines the nickname, it doesn't actually apply the format and make + it the default. Therefore, it will not affect subsequent + TransferLog directives. + In addition, LogFormat cannot use one nickname + to define another nickname. Note that the nickname should not contain + percent signs (%).

    + +

    Example

    + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common +

    + +
    +
    top
    +

    TransferLog Directive

    + + + + + + +
    Description:Specify location of a log file
    Syntax:TransferLog file|pipe
    Context:server config, virtual host
    Status:Base
    Module:mod_log_config
    +

    This directive has exactly the same arguments and effect as + the CustomLog + directive, with the exception that it does not allow the log format + to be specified explicitly or for conditional logging of requests. + Instead, the log format is determined by the most recently specified + LogFormat directive + which does not define a nickname. Common Log Format is used if no + other format has been specified.

    + +

    Example

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_log_config.html.ja.euc-jp b/trunk/docs/manual/mod/mod_log_config.html.ja.euc-jp new file mode 100644 index 0000000000..404ccd7c7e --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.html.ja.euc-jp @@ -0,0 +1,475 @@ + + + +mod_log_config - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_log_config

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    This translation may be out of date. Check the + English version for recent changes.
    + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Î¥í¥®¥ó¥°
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:log_config_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_log_config.c
    +

    ³µÍ×

    + +

    + ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò½ÀÆð¤Ë¥í¥°¼ý½¸¤¹¤ëµ¡Ç½¤ò + Ä󶡤·¤Þ¤¹¡£¥í¥°¤Ï¥«¥¹¥¿¥Þ¥¤¥º²Äǽ¤Ê½ñ¼°¤Ç½ñ¤«¤ì¡¢¥Õ¥¡¥¤¥ë¤ËľÀÜ + ½ñ¤¤¤¿¤ê¡¢³°Éô¥×¥í¥°¥é¥à¤ËÅϤ·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¸Ä¡¹¤Î¥ê¥¯¥¨¥¹¥È¤ò + ÆÃħ¤Ë±þ¤¸¤Æ¥í¥°¤Ë½ñ¤¤¤¿¤ê½ñ¤«¤Ê¤«¤Ã¤¿¤ê¤Ç¤­¤ë¤è¤¦¤Ë¡¢¾ò·ï¤Ë¤è¤ë + ¥í¥°¼ý½¸¤âÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï»°¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥ÖÄ󶡤·¤Þ¤¹: + ¥í¥°¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¤¿¤á¤Î TransferLog, + ¿·¤·¤¤½ñ¼°¤ò ÄêµÁ¤¹¤ë LogFormat, + ¥í¥°¥Õ¥¡¥¤¥ë¤È ½ñ¼°¤ò°ìÅÙ¤ËÄêµÁ¤¹¤ë CustomLog ¤Ç¤¹¡£ + ³Æ¥ê¥¯¥¨¥¹¥È¤¬Ê£¿ô²ó¥í¥°¼ý½¸¤µ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë + TransferLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÊ£¿ô²ó»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥«¥¹¥¿¥à¥í¥°½ñ¼°

    + +

    LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î½ñ¼°¤ò»ØÄꤹ¤ë°ú¿ô¤Ïʸ»úÎó¤Ç¤¹¡£¤³¤Îʸ»úÎó¤ò»È¤Ã¤Æ¤½¤ì¤¾¤ì¤Î + ¥ê¥¯¥¨¥¹¥È¤¬¥í¥°¥Õ¥¡¥¤¥ë¤Ë¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£¤½¤Îʸ»úÎó¤Ë¤Ï + ¥í¥°¥Õ¥¡¥¤¥ë¤Ë¤½¤Î¤Þ¤Þ + ½ñ¤«¤ì¤ëʸ»úÎó¤ä¡¢¤½¤ì¤¾¤ì²þ¹Ô¤È¥¿¥Ö¤ò¸½¤¹ C ¸À¸ì + ·Á¼°¤ÎÀ©¸æʸ»ú "\n" ¤È "\t" + ¤È¤ò´Þ¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤½¤Î¤Þ¤Þ½ÐÎϤµ¤»¤¿¤¤°úÍÑÉä¤È¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ï + ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ç¥¨¥¹¥±¡¼¥×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤½¤Î¤â¤Î¤Ï "%" + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¼°¤Îʸ»úÎó¤Ë½ñ¤¯¤³¤È¤Ç + ¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£"%" + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥í¥°¥Õ¥¡¥¤¥ëÃæ¤Ç¤Ï°Ê²¼¤Î¤è¤¦¤Ê + ÃͤÇÃÖ´¹¤µ¤ì¤Þ¤¹:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎóÀâÌÀ
    %%¥Ñ¡¼¥»¥ó¥Èµ­¹æ
    %...a¥ê¥â¡¼¥È IP ¥¢¥É¥ì¥¹
    %...A¥í¡¼¥«¥ë IP ¥¢¥É¥ì¥¹
    %...B¥ì¥¹¥Ý¥ó¥¹¤Î¥Ð¥¤¥È¿ô¡£HTTP ¥Ø¥Ã¥À¤Ï½ü¤¯¡£
    %...b¥ì¥¹¥Ý¥ó¥¹¤Î¥Ð¥¤¥È¿ô¡£HTTP ¥Ø¥Ã¥À¤Ï½ü¤¯¡£CLF ½ñ¼°¡£ + ¤¹¤Ê¤ï¤Á¡¢1 ¥Ð¥¤¥È¤âÁ÷¤é¤ì¤Ê¤«¤Ã¤¿¤È¤­¤Ï 0 ¤Ç¤Ï¤Ê¤¯¡¢ + '-' ¤Ë¤Ê¤ë
    %...{Foobar}C¥µ¡¼¥Ð¤ËÁ÷¤é¤ì¤¿¥ê¥¯¥¨¥¹¥ÈÃæ¤Î¥¯¥Ã¥­¡¼ Foobar ¤ÎÃÍ
    %...D¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë¤Î¤Ë¤«¤«¤Ã¤¿»þ´Ö¡¢¥ß¥êÉÃñ°Ì
    %...{FOOBAR}e´Ä¶­ÊÑ¿ô FOOBAR ¤ÎÆâÍÆ
    %...f¥Õ¥¡¥¤¥ë̾
    %...h¥ê¥â¡¼¥È¥Û¥¹¥È
    %...H¥ê¥¯¥¨¥¹¥È¥×¥í¥È¥³¥ë
    %...{Foobar}i¥µ¡¼¥Ð¤ËÁ÷¤é¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î Foobar: + ¥Ø¥Ã¥À¤ÎÆâÍÆ
    %...l(identd ¤«¤é¤â¤·Ä󶡤µ¤ì¤Æ¤¤¤ì¤Ð) ¥ê¥â¡¼¥È¥í¥°Ì¾¡£ + ¤³¤ì¤Ï mod_ident ¤¬¥µ¡¼¥Ð¤Ë¸ºß¤·¤Æ¡¢ + IdentityCheck + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ On ¤ËÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢ + - ¤Ë¤Ê¤ê¤Þ¤¹¡£
    %...m¥ê¥¯¥¨¥¹¥È¥á¥½¥Ã¥É
    %...{Foobar}n¾¤Î¥â¥¸¥å¡¼¥ë¤«¤é¤Î¥á¥â Foobar ¤ÎÆâÍÆ
    %...{Foobar}o±þÅú¤Î Foobar: ¥Ø¥Ã¥À¤ÎÆâÍÆ
    %...p¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤ë¥µ¡¼¥Ð¤ÎÀµ¼°¤Ê¥Ý¡¼¥È
    %...P¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤¿»Ò¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹ ID
    %...{format}P¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤¿¥ï¡¼¥«¡¼¤Î¥×¥í¥»¥¹ ID ¤«¥¹¥ì¥Ã¥É ID¡£ + format ¤È¤·¤ÆÍ­¸ú¤ÊÃÍ¤Ï pid ¤È tid +
    %...qÌ䤤¹ç¤»Ê¸»úÎó (¸ºß¤¹¤ë¾ì¹ç¤ÏÁ°¤Ë ? ¤¬Äɲ䵤ì¤ë¡£ + ¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï¶õʸ»úÎó)
    %...r¥ê¥¯¥¨¥¹¥È¤ÎºÇ½é¤Î¹Ô
    %...s¥¹¥Æ¡¼¥¿¥¹¡£ÆâÉô¤Ç¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Ï¡¢¸µ¡¹¤Î + ¥ê¥¯¥¨¥¹¥È¤Î¥¹¥Æ¡¼¥¿¥¹ --- ºÇ¸å¤Î¥¹¥Æ¡¼¥¿¥¹¤Ï %...>s +
    %...t¥ê¥¯¥¨¥¹¥È¤ò¼õÉÕ¤±¤¿»þ¹ï¡£ + CLF ¤Î»þ¹ï¤Î½ñ¼° (ɸ½à¤Î±Ñ¸ì¤Î½ñ¼°)
    %...{format}tformat ¤ÇÍ¿¤¨¤é¤ì¤¿½ñ¼°¤Ë¤è¤ë»þ¹ï¡£format ¤Ï + strftime (3) ¤Î + ½ñ¼°¤Ç¤¢¤ëɬÍפ¬¤¢¤ë¡£(ÃÏ°è²½¤µ¤ì¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ë)
    %...T¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤Î¤Ë¤«¤«¤Ã¤¿»þ´Ö¡¢ÉÃñ°Ì
    %...u¥ê¥â¡¼¥È¥æ¡¼¥¶ (ǧ¾Ú¤Ë¤è¤ë¤â¤Î¡£¥¹¥Æ¡¼¥¿¥¹ (%s) ¤¬ + 401 ¤Î¤È¤­¤Ï°ÕÌ£¤¬¤Ê¤¤¤â¤Î¤Ç¤¢¤ë²ÄǽÀ­¤¬¤¢¤ë) +
    %...U¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ URL ¥Ñ¥¹¡£¥¯¥¨¥êʸ»úÎó¤Ï´Þ¤Þ¤Ê¤¤
    %...v¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤ë¥µ¡¼¥Ð¤ÎÀµ¼°¤Ê ServerName
    %...VUseCanonicalName ¤ÎÀßÄê¤Ë¤è¤ë¥µ¡¼¥Ð̾
    %...X±þÅú¤¬´°Î»¤·¤¿¤È¤­¤ÎÀܳ¥¹¥Æ¡¼¥¿¥¹: + + + + + + + + + +
    X =±þÅú¤¬´°Î»¤¹¤ëÁ°¤ËÀܳ¤¬°Û¾ï½ªÎ»
    + =±þÅú¤¬Á÷¤é¤ì¤¿¸å¤ËÀܳ¤ò»ý³¤¹¤ë¤³¤È¤¬²Äǽ
    - = ±þÅú¤¬Á÷¤é¤ì¤¿¸å¤ËÀܳ¤¬ÀÚ¤é¤ì¤ë
    + +

    (¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache + 1.3 ¤Î¸å´ü¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï %...c ¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ + ¤¤¤Þ¤·¤¿¤¬¡¢¤³¤ì¤ÏÎò»ËŪ¤Ë ssl ¤¬»ÈÍѤ·¤Æ¤¤¤ë + %...{var}c + ¹½Ê¸¤È¾×Æͤ·¤Æ¤¤¤Þ¤·¤¿¡£)

    %...I¥ê¥¯¥¨¥¹¥È¤È¥Ø¥Ã¥À¤ò´Þ¤à¡¢¼õ¤±¼è¤Ã¤¿¥Ð¥¤¥È¿ô¡£ + 0 ¤Ë¤Ï¤Ê¤é¤Ê¤¤¡£ + ¤³¤ì¤ò»ÈÍѤ¹¤ë¤¿¤á¤Ë¤Ï mod_logio ¤¬É¬Í×
    %...O¥Ø¥Ã¥À¤ò´Þ¤à¡¢Á÷¿®¤·¤¿¥Ð¥¤¥È¿ô¡£0 ¤Ë¤Ï¤Ê¤é¤Ê¤¤¡£ + ¤³¤ì¤ò»ÈÍѤ¹¤ë¤¿¤á¤Ë¤Ï mod_logio ¤¬É¬Í×
    + +

    "..." ¤Ï²¿¤â¤Ê¤¤¤« (Î㤨¤Ð¡¢ + "%h %u %r %s %b" ¤Î¤è¤¦¤Ë)¡¢ + ¤½¤Î¹àÌܤò´Þ¤á¤ë¤«¤É¤¦¤«¤Î¾ò·ï (¤â¤·¾ò·ï¤Ë¹ç¤ï¤Ê¤«¤Ã¤¿¤È¤­¤Ï + ¤½¤Î¹àÌÜ¤Ï "-" ¤Ë¤Ê¤ê¤Þ¤¹) ¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¾ò·ï¤Î·Á¼°¤Ï + HTTP ¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤Î¥ê¥¹¥È¤Ç¡¢Á°¤Ë "!" ¤òÉÕ¤±¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢"%400,501{User-agent}i" ¤Ï 400 ¥¨¥é¡¼¤È 501 ¥¨¥é¡¼ + (Bad Request ¤È Not Implemented) ¤Î¤È¤­¤Î¤ß User-agent: + ¤ò¥í¥°¼ý½¸¤·¤Þ¤¹¡£ + "%!200,304,302{Referer}i" ¤ÏÉáÄ̤Υ¹¥Æ¡¼¥¿¥¹¤òÊÖ¤µ¤Ê¤«¤Ã¤¿ + ¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤Ç Referer: ¤ò¥í¥°¼ý½¸¤·¤Þ¤¹¡£

    + +

    ½¤¾þ»Ò "<" ¤È ">" ¤ÏÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¥í¥°¤Ë + ¸µ¤Î¥ê¥¯¥¨¥¹¥È¤«ºÇ½ªÅª¤Ê¥ê¥¯¥¨¥¹¥È¤Î¤É¤Á¤é¤ò»ÈÍѤ¹¤ë¤«¤ò + »ØÄꤹ¤ë¤¿¤á¤Ë»È¤¤¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢% ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + %s, %U, %T, %D, %r ¤Ï¸µ¤Î¥ê¥¯¥¨¥¹¥È¤ò¡¢Â¾¤ÏºÇ½ªÅª¤Ê¥ê¥¯¥¨¥¹¥È¤ò + »ÈÍѤ·¤Þ¤¹¡£Î㤨¤Ð¡¢¥ê¥¯¥¨¥¹¥È¤ÎºÇ½ª¥¹¥Æ¡¼¥¿¥¹¤òµ­Ï¿¤¹¤ë¤Ë¤Ï + %>s ¤ò¡¢ÆâÉôŪ¤Ëǧ¾Ú¤µ¤ì¤Æ¤¤¤Ê¤¤¥ê¥½¡¼¥¹¤Ø¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿ + ¥ê¥¯¥¨¥¹¥È¤Ç¸µ¤Î¥ê¥¯¥¨¥¹¥È¤Çǧ¾Ú¤µ¤ì¤¿¥æ¡¼¥¶¤òµ­Ï¿¤¹¤ë¤¿¤á¤Ë¤Ï + %<u ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    httpd 2.0 ¤Î 1.3.25 ¤è¤êÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢ + %...r, %...i, + %...o ¤Îʸ»úÎó¤Ï + ¥¨¥¹¥±¡¼¥×¤µ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤Ï¼ç¤Ë Common Log Format ¤«¤é¤ÎÍ×µá¤Ë¤è¤ë¤â¤Î¤Ç¤¹¡£ + ¤³¤ì¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬¥í¥°¤ËÀ©¸æʸ»ú¤òÁÞÆþ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤È¤¤¤¦¤³¤È¤Ç¡¢ + À¸¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò°·¤¦¤È¤­¤Ë¤ÏÈó¾ï¤ËÃí°Õ¤¬É¬ÍפǤ·¤¿¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤Ë¤è¤ê 2.0.46 ¤è¤ê°õ»úÉÔ²Äǽ¤Êʸ»ú¤È + ¾¤ÎÆÃÊ̤Êʸ»ú¤Ï¡¢¤Û¤È¤ó¤É \xhh ¤È¤¤¤¦ + ʸ»úÎó¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤³¤³¤Ç¡¢hh ¤Ï + ¤½¤Î¤Þ¤Þ¤Î¥Ð¥¤¥È¤ÎÃͤΠ16 ¿Ê¤Ç¤ÎÃͤǤ¹¡£¤³¤Îµ¬Â§¤ÎÎã³°¤Ë¤Ï¡¢ + ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤ò»È¤Ã¤Æ¥¨¥¹¥±¡¼¥×¤µ¤ì¤ë " ¤È \ ¤È¡¢ + C ·Á¼°¤Îɽµ­Ë¡¤¬»È¤ï¤ì¤ë¶õÇòʸ»ú (\n, \t ¤Ê¤É) ¤¬ + ¤¢¤ê¤Þ¤¹¡£

    + +

    httpd 2.0 ¤Ç¤Ï 1.3 ¤È¤Ï°Û¤Ê¤ê¡¢%b ¤È %B + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¿®¤µ¤ì¤¿¥Ð¥¤¥È¿ô¤½¤Î¤â¤Î¤Ç¤Ï¤Ê¤¯¡¢ + HTTP ¥ì¥¹¥Ý¥ó¥¹¤Î¥Ð¥¤¥È¿ô¤Ç¤¹ (¤³¤ì¤é¤Ï°Û¤Ê¤ë¤â¤Î¤Ç¡¢¤¿¤È¤¨¤Ð¡¢ + ¥³¥Í¥¯¥·¥ç¥ó¤¬ÅÓÃæ¤ÇÇË´þ¤µ¤ì¤¿¾ì¹ç¤ä¡¢SSL »ÈÍÑ»þ¤Ë°ìÃפ·¤Þ¤»¤ó) ¡£ + mod_logio ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë %O + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ç¡¢¥Í¥Ã¥È¥ï¡¼¥¯·Ðͳ¤Ç¼ÂºÝ¤ËžÁ÷¤µ¤ì¤¿¥Ð¥¤¥È¿ô¤ò + µ­Ï¿¤Ç¤­¤Þ¤¹¡£

    + +

    ¤è¤¯»È¤ï¤ì¤ë¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ï:

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈÉÕ¤­ Common Log Format
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined ¥í¥°½ñ¼°
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer ¥í¥°½ñ¼°
    +
    "%{Referer}i -> %U"
    + +
    Agent (¥Ö¥é¥¦¥¶) ¥í¥°½ñ¼°
    +
    "%{User-agent}i"
    +
    + +

    %v ¤È %p ¤Ë¤Ï¤½¤ì¤¾¤ì¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤ë¥µ¡¼¥Ð¤ÎÀµµ¬²½¤µ¤ì¤¿ + ServerName ¤È Listen ¤¬»È¤ï¤ì¤ë¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¤³¤ì¤Ï UseCanonicalName ¤Î + ÀßÄê¤Ë´Ø¤ï¤é¤º¡¢¾ï¤Ë¤½¤¦¤Ê¤ê¤Þ¤¹¡£¤½¤¦¤·¤Ê¤¤¤È¤É¤Î + ¥Û¥¹¥È¤¬¼ÂºÝ¤Ë¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤¿¤Î¤«¤òÃΤ뤿¤á¤Ë¡¢ + ¥í¥°²òÀÏ¥×¥í¥°¥é¥à¤¬¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥Þ¥Ã¥Á¥ó¥°¤ò¤È¤ë¥¢¥ë¥´¥ê¥º¥àÁ´ÂΤò + ºÆ¼ÂÁõ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¯¤Ê¤ë¤«¤é¤Ç¤¹¡£

    +
    top
    +
    +

    ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤·¤Æ

    +

    ¥í¥°¥Õ¥¡¥¤¥ë¤¬Êݸ¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤¬¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿°Ê³°¤Î¥æ¡¼¥¶¤Ç + ½ñ¤­¹þ¤ß²Äǽ¤Ê¤È¤­¤Ë¥»¥­¥å¥ê¥Æ¥£¤ÎÌäÂ꤬ȯÀ¸¤¹¤ëÍýͳ¤Î¾ÜºÙ¤Ï¥»¥­¥å¥ê¥Æ¥£¤Î¤³¤Ä + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    top
    +

    BufferedLogs ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Ç¥£¥¹¥¯¤Ë½ñ¤­½Ð¤¹Á°¤Ë¥á¥â¥ê¤Ë¥í¥°¥¨¥ó¥È¥ê¤ò¥Ð¥Ã¥Õ¥¡¤¹¤ë
    ¹½Ê¸:BufferedLogs On|Off
    ¥Ç¥Õ¥©¥ë¥È:BufferedLogs Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_log_config
    ¸ß´¹À­:2.0.41 °Ê¹ß
    +

    BufferedLogs ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È + mod_log_config ¤ÎµóÆ°¤¬ÊѲ½¤·¤Æ¡¢ + Ê£¿ô¤Î¥í¥°¤ò½ñ¤­½Ð¤¹ºÝ¤Ë¡¢¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È½èÍý¸åËè¤Ë + ½ñ¤­½Ð¤¹¤Î¤Ç¤Ï¤Ê¤¯¡¢¤¤¤Ã¤¿¤ó¥á¥â¥ê¤ËÃߤ¨¤Æ¤«¤é¡¢ + ¤Þ¤È¤á¤Æ¥Ç¥£¥¹¥¯¤Ë½ñ¤­½Ð¤¹¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î·ë²Ì¥Ç¥£¥¹¥¯¥¢¥¯¥»¥¹¤¬¤è¤ê¸úΨŪ¤Ë¤Ê¤ê¡¢ + ¹â¤¤¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤ÎÆÀ¤é¤ì¤ë¥·¥¹¥Æ¥à¤â¤¢¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥ÐÁ´ÂΤǰìÅÙ¤À¤±ÀßÄê¤Ç¤­¤Þ¤¹; + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤´¤È¤ËÀßÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£

    + +
    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¼Â¸³Åª¤Ê¤â¤Î¤Ç¤¹¤Î¤Ç¡¢ + »ÈÍѤ¹¤ëºÝ¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
    + +
    +
    top
    +

    CookieLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥Ã¥­¥ó¥°¤Î¥í¥®¥ó¥°¤Î¤¿¤á¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    ¹½Ê¸:CookieLog filename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_log_config
    ¸ß´¹À­:¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÈó¿ä¾©
    +

    CookieLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥Ã¥­¡¼¤Î¥í¥®¥ó¥°¤Î¤¿¤á¤Î¥Õ¥¡¥¤¥ë̾¤ò + ÀßÄꤷ¤Þ¤¹¡£filename ¤Ï ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï mod_cookies ¤È¤Î¸ß´¹À­¤Î¤¿¤á¤À¤±¤Ë + ¸ºß¤·¡¢»ÈÍѤϿ侩¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥í¥°¥Õ¥¡¥¤¥ë¤Î̾Á°¤È½ñ¼°¤òÀßÄꤹ¤ë
    ¹½Ê¸:CustomLog file|pipe +format|nickname +[env=[!]environment-variable]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_log_config
    +

    CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥µ¡¼¥Ð¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò + ¥í¥°¼ý½¸¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£¥í¥°¤Î½ñ¼°¤¬»ØÄꤵ¤ì¡¢ + ´Ä¶­ÊÑ¿ô¤ò»È¤Ã¤Æ¥í¥®¥ó¥°¤¬¾ò·ï¤Ë±þ¤¸¤Æ¹Ô¤Ê¤ï¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    ¥í¥°¤¬½ñ¤«¤ì¤ë¾ì½ê¤ò»ØÄꤹ¤ëºÇ½é¤Î°ú¿ô¤Ï°Ê²¼¤ÎÆó¤Ä¤Î·Á¼°¤ÎÃͤò + ¤È¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    file
    +
    ServerRoot + ¤«¤é¤ÎÁêÂХѥ¹¤Çɽ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë̾¡£
    + +
    pipe
    +
    ¥Ñ¥¤¥×ʸ»ú "|" ¤È¡¢¤½¤Î¸å¤Ëɸ½àÆþÎϤ«¤é¥í¥°¤Î + ¾ðÊó¤ò¼õ¤±¤È¤ë¥×¥í¥°¥é¥à¤Ø¤Î¥Ñ¥¹¤¬Â³¤¤¤¿¤â¤Î¡£ + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    ¤â¤·¥×¥í¥°¥é¥à¤¬»ÈÍѤµ¤ì¤¿¾ì¹ç¡¢ + httpd ¤¬µ¯Æ°¤µ¤ì¤¿¥æ¡¼¥¶¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¥µ¡¼¥Ð¤¬ + root ¤Ë¤è¤Ã¤Æµ¯Æ°¤µ¤ì¤¿¾ì¹ç¤Ï root ¤Ë¤Ê¤ê¤Þ¤¹¡£¥×¥í¥°¥é¥à¤¬ + °ÂÁ´¤Ç¤¢¤ë¤è¤¦¤Ëα°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +

    Ãí

    +

    Unix ¤Ç¤Ê¤¤¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÆþÎϤ·¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + »ÈÍѤ·¤Æ¤¤¤ë¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤¬¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Î»ÈÍѤòµö²Ä¤·¤Æ¤¤¤¿ + ¤È¤·¤Æ¡¢Ä̾ï¤Î¥¹¥é¥Ã¥·¥å¤À¤±¤ò»È¤¦¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£ + °ìÈÌŪ¤Ë¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ç¤Ï¾ï¤ËÉáÄ̤Υ¹¥é¥Ã¥·¥å¤Î¤ß¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë + Êý¤¬Îɤ¤¤Ç¤¹¡£

    +
    +
    + +

    Æó¤Ä¤á¤Î°ú¿ô¤Ï¥í¥°¥Õ¥¡¥¤¥ë¤Ë²¿¤¬½ñ¤«¤ì¤ë¤«¤ò»ØÄꤷ¤Þ¤¹¡£ + Á°¤Ë¤¢¤ë LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê + ÄêµÁ¤µ¤ì¤¿ nickname ¤«¡¢¥í¥°¤Î½ñ¼° + ¤Î¤È¤³¤í¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¡¢ÌÀ¼¨Åª¤Ê format ʸ»úÎó¤Î + ¤É¤Á¤é¤«¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢°Ê²¼¤ÎÆó¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö·²¤ÏÁ´¤¯Æ±¤¸¸ú²Ì¤ò¤â¤¿¤é¤·¤Þ¤¹:

    + +

    + # CustomLog with format nickname
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # CustomLog with explicit format string
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +

    + +

    »°¤ÄÌܤΰú¿ô¤Ï¾Êά²Äǽ¤Ç¡¢¥µ¡¼¥Ð¤Î´Ä¶­¤Ë¤¢¤ëÊÑ¿ô¤¬¤¢¤ë¤«¤Ê¤¤¤«¤Ë + ±þ¤¸¤Æ¥ê¥¯¥¨¥¹¥È¤ò¥í¥°¼ý½¸¤¹¤ë¤«¤É¤¦¤«¤òÀ©¸æ¤¹¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + »ØÄꤵ¤ì¤¿´Ä¶­ÊÑ¿ô¤¬¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + ÀßÄꤵ¤ì¤Æ¤¤¤¿¾ì¹ç ('env=!name' ʸ¤¬»È¤ï¤ì¤¿¤È¤­¤Ï + ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç)¡¢¥ê¥¯¥¨¥¹¥È¤¬¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£

    + +

    ´Ä¶­ÊÑ¿ô¤Ï mod_setenvif ¥â¥¸¥å¡¼¥ë¤È + mod_rewrite ¥â¥¸¥å¡¼¥ë¤ÎξÊý¤â¤·¤¯¤Ï + ÊÒÊý¤òÍѤ¤¤Æ¥ê¥¯¥¨¥¹¥È¤´¤È¤ËÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð¡¢¥µ¡¼¥Ð¤Ë¤¢¤ë¤¹¤Ù¤Æ¤Î GIF ²èÁü¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤òÊÌ¤Î¥í¥°¥Õ¥¡¥¤¥ë + ¤Ë¤Ïµ­Ï¿¤·¤¿¤¤¤±¤ì¤É¡¢¥á¥¤¥ó¥í¥°¤Ë¤Ïµ­Ï¿¤·¤¿¤¯¤Ê¤¤¡¢¤È¤¤¤¦¤È¤­¤Ï + °Ê²¼¤Î¤â¤Î¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +

    + +

    ¸Å¤¤ RefererIgnore ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱ¤¸µóÆ°¤ò¤µ¤»¤¿¤¤¾ì¹ç¤Ï¡¢ + ¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹:

    + +

    + SetEnvIf Referer example\.com localreferer
    + CustomLog referer.log referer env=!localreferer +

    + +
    +
    top
    +

    LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥í¥°¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤ¹¤ë½ñ¼°¤òÀßÄꤹ¤ë
    ¹½Ê¸:LogFormat format|nickname +[nickname]
    ¥Ç¥Õ¥©¥ë¥È:LogFormat "%h %l %u %t \"%r\" %>s %b"
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_log_config
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¢¥¯¥»¥¹¥í¥°¥Õ¥¡¥¤¥ë¤Î½ñ¼°¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÆó¤Ä¤Î·Á¼°¤Î¤É¤Á¤é¤«¤ò + ¤È¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ºÇ½é¤Î·Á¼°¤Ç¤Ï°ì¤Ä¤Î°ú¿ô¤Î¤ß¤¬»ØÄꤵ¤ì¡¢ + ³¤¯ TransferLog + ¤Ç»ØÄꤵ¤ì¤¿¥í¥°¤Ç»È¤ï¤ì¤ë¥í¥°¤Î½ñ¼°¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ÎñÆȤΰú¿ô¤Ç¤Ï + ¾å¤Î¥«¥¹¥¿¥à¥í¥°½ñ¼°¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë + format ¤òÌÀ¼¨Åª¤Ë»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤â¤·¤¯¤Ï¡¢²¼¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤ËÁ°¤Ë LogFormat + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÄêµÁ¤µ¤ì¤¿¥í¥°¤Î½ñ¼°¤ò nickname¤ò»È¤Ã¤Æ + »²¾È¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÆó¤Ä¤á¤Î·Á¼°¤Ï + format ¤Ë nickname ¤òÍ¿¤¨¤Þ¤¹¡£ + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎóÁ´ÂΤòºÆ¤Ó½ñ¤¯¤«¤ï¤ê¤Ë¡¢ + ¤³¤Î nickname ¤ò³¤­¤Î LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + CustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Nickname ¤òÄêµÁ¤¹¤ë LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¾¤Ë¤Ï²¿¤â¤·¤Þ¤»¤ó -- ¤¹¤Ê¤ï¤Á¡¢¥Ë¥Ã¥¯¥Í¡¼¥à¤òÄêµÁ + ¤¹¤ë¤À¤±¤Ç¡¢¼ÂºÝ¤Ë½ñ¼°¤òŬÍѤ·¤Æ¥Ç¥Õ¥©¥ë¥È¤Ë¤¹¤ë¤È¤¤¤¦¤³¤È¤Ï¹Ô¤Ê¤¤¤Þ¤»¤ó¡£ + ¤Ç¤¹¤«¤é¡¢¤³¤ì¤Ï³¤¯ TransferLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ï±Æ¶Á¤òÍ¿¤¨¤Þ¤»¤ó¡£ + ¤µ¤é¤Ë¡¢LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï´û¸¤Î nickname ¤ò + »È¤Ã¤ÆÊ̤Πnickname ¤òÄêµÁ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£Nickname ¤Ë¤Ï + ¥Ñ¡¼¥»¥ó¥Èµ­¹æ (%) ¤¬´Þ¤Þ¤ì¤Æ¤¤¤Æ¤Ï¤¤¤±¤Ê¤¤¤³¤È¤Ë¤âÃí°Õ + ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Îã

    + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common +

    + +
    +
    top
    +

    TransferLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥í¥°¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤ò»ØÄê
    ¹½Ê¸:TransferLog file|pipe
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_log_config
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥í¥°½ñ¼°¤òľÀÜ»ØÄê¤Ç¤­¤Ê¤¤¤³¤È¤È¡¢ + ¾ò·ïÉÕ¤­¥í¥®¥ó¥°¤¬Ìµ¤¤¤³¤È¤ò½ü¤¯¤È¡¢CustomLog ¤ÈÁ´¤¯Æ±¤¸°ú¿ô¤È¸ú²Ì¤¬¤¢¤ê¤Þ¤¹¡£ + ľÀÜ¥í¥°½ñ¼°¤ò»ØÄꤹ¤ëÂå¤ï¤ê¤Ë¡¢¥í¥°¤Î½ñ¼°¤Ï¤½¤³¤Þ¤Ç¤Ç°ìÈֺǸå¤Ë»ØÄꤵ¤ì¤¿ + ¥Ë¥Ã¥¯¥Í¡¼¥à¤òÄêµÁ¤·¤Ê¤¤ + LogFormat ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ÇÄêµÁ¤µ¤ì¤¿¤â¤Î¤ò»È¤¤¤Þ¤¹¡£ + ¤â¤·Â¾¤Î½ñ¼°¤¬Á´¤¯»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ï Common Log Format + ¤¬»È¤ï¤ì¤Þ¤¹¡£

    + +

    Îã

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_log_config.html.ko.euc-kr b/trunk/docs/manual/mod/mod_log_config.html.ko.euc-kr new file mode 100644 index 0000000000..944ef564c5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.html.ko.euc-kr @@ -0,0 +1,401 @@ + + + +mod_log_config - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_log_config

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:¼­¹ö·ÎÀÇ ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:log_config_module
    ¼Ò½ºÆÄÀÏ:mod_log_config.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ·Î±×¿¡ ÀÚÀ¯·Ó°Ô ±â·ÏÇÑ´Ù. + ÀÚ½ÅÀÌ ¿øÇÏ´Â Çü½ÄÀ¸·Î ·Î±×¸¦ ±â·ÏÇÒ ¼ö ÀÖ°í, ÆÄÀÏÀ̳ª ¿ÜºÎ + ÇÁ·Î±×·¥¿¡ Á÷Á¢ ·Î±×¸¦ º¸³¾ ¼öµµ ÀÖ´Ù. Á¶°ÇÀû ·Î±×¸¦ »ç¿ëÇϸé + ¿äûÀÇ ¼º°Ý¿¡ µû¶ó ¿äûÀ» ·Î±×¿¡ Ãß°¡Çϰųª Á¦¿ÜÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ¸ðµâÀº ¼¼°¡Áö Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù. TransferLog´Â ·Î±×ÆÄÀÏÀ» + ¸¸µé°í, LogFormatÀº + ¿øÇÏ´Â Çü½ÄÀ» Á¤ÇÏ°í, CustomLog´Â Çѹø¿¡ ·Î±×ÆÄÀÏ°ú + Çü½ÄÀ» ¸ðµÎ ÁöÁ¤ÇÑ´Ù. TransferLog¿Í + CustomLog Áö½Ã¾î¸¦ ¿©·¯¹ø »ç¿ëÇϸé + ¿äûÀ» ¿©·¯ ÆÄÀÏ¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    ·Î±× Çü½Ä ÁöÁ¤Çϱâ

    + +

    LogFormat°ú + CustomLog + Áö½Ã¾îÀÇ Çü½Ä ¾Æ±Ô¸ÕÆ®´Â ¹®ÀÚ¿­ÀÌ´Ù. ÀÌ ¹®ÀÚ¿­¿¡ µû¶ó ¿äûÀ» + ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. ¹®ÀÚ¿­¿¡´Â ·Î±×ÆÄÀÏ¿¡ ±×´ë·Î º¹»çµÇ´Â + ¹®ÀÚ¿Í Çà¹Ù²Þ°ú ÅÇÀ» ³ªÅ¸³»´Â CÀÇ "\n"°ú "\t" Á¦¾î¹®ÀÚ¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ·Î±×ÆÄÀÏ¿¡ µû¿ÈÇ¥³ª ¹é½½·¡½¬¸¦ ¾²·Á¸é ¾Õ¿¡ + ¹Ýµå½Ã ¹é½½·¡½¬¸¦ Àû¾îÁà¾ß ÇÑ´Ù.

    + +

    ¿äûÀÇ Æ¯Â¡Àº Çü½Ä ¹®ÀÚ¿­¿¡ "%" Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ±â·ÏÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ·Î±×ÆÄÀÏ¿¡¼­ ´ÙÀ½°ú °°ÀÌ + º¯°æµÈ´Ù.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Çü½Ä ¹®ÀÚ¿­¼³¸í
    %%ÆÛ¼¾Æ® ±âÈ£
    %...a¿ø°Ý IP-ÁÖ¼Ò
    %...A(¼­¹ö) IP-ÁÖ¼Ò
    %...BHTTP Çì´õ¸¦ Á¦¿ÜÇÑ Àü¼Û ¹ÙÀÌÆ®¼ö.
    %...bHTTP Çì´õ¸¦ Á¦¿ÜÇÑ Àü¼Û ¹ÙÀÌÆ®¼ö. CLF Çü½Ä°ú °°ÀÌ + Àü¼ÛÇÑ ³»¿ëÀÌ ¾ø´Â °æ¿ì 0 ´ë½Å '-'°¡ ³ª¿Â´Ù.
    %...{Foobar}C¼­¹ö°¡ ¼ö½ÅÇÑ ¿äû¿¡¼­ Foobar ÄíÅ°ÀÇ + ³»¿ë.
    %...D¿äûÀ» ó¸®Çϴµ¥ °É¸° ½Ã°£ (¸¶ÀÌÅ©·ÎÃÊ ´ÜÀ§).
    %...{FOOBAR}eȯ°æº¯¼ö FOOBARÀÇ ³»¿ë
    %...fÆÄÀϸí
    %...h¿ø°Ý È£½ºÆ®
    %...H¿äû ÇÁ·ÎÅäÄÝ
    %...{Foobar}i¼­¹ö°¡ ¼ö½ÅÇÑ ¿äû¿¡¼­ Foobar: + Çì´õÀÇ ³»¿ë.
    %...l(ÀÖ´Ù¸é identd°¡ Á¦°øÇÑ) ¿ø°Ý ·Î±×Àθí. + mod_ident°¡ ÀÖ°í IdentityCheck°¡ + OnÀÌ ¾Æ´Ï¸é »©±â±âÈ£¸¦ ±â·ÏÇÑ´Ù.
    %...m¿äû ¸Þ½áµå
    %...{Foobar}n´Ù¸¥ ¸ðµâÀÌ ±â·ÏÇÑ Foobar ³ëÆ®(note) + ³»¿ë.
    %...{Foobar}oÀÀ´äÀÇ Foobar: Çì´õ ³»¿ë.
    %...p¿äûÀ» ¼­ºñ½ºÇÏ´Â ¼­¹öÀÇ Á¤±Ô Æ÷Æ®
    %...P¿äûÀ» ¼­ºñ½ºÇÏ´Â ÀÚ½ÄÀÇ ÇÁ·Î¼¼½º ID.
    %...{format}P¿äûÀ» ¼­ºñ½ºÇÏ´Â ÀÚ½ÄÀÇ ÇÁ·Î¼¼½º ID ȤÀº ¾²·¹µå + ID. format¿¡´Â pid¿Í tid°¡ + °¡´ÉÇÏ´Ù. +
    %...qÁúÀǹ®ÀÚ¿­ (ÁúÀǹ®ÀÚ¿­ÀÌ ÀÖ´Ù¸é ¾Õ¿¡ ?¸¦ + ºÙÀÌ°í, ¾ø´Ù¸é ºó ¹®ÀÚ¿­)
    %...r¿äûÀÇ Ã¹¹ø° ÁÙ
    %...s»óÅÂ(status). ³»ºÎ ¸®´ÙÀÌ·º¼ÇµÈ ¿äûÀÇ °æ¿ì *¿ø·¡* + ¿äûÀÇ »óÅÂÀÌ´Ù. ÃÖÁ¾ ¿äûÀÇ »óÅ´ %...>s.
    %...tcommon log format ½Ã°£ Çü½Ä(Ç¥ÁØ ¿µ¾î Çü½Ä)ÀÇ ½Ã°£
    %...{format}tstrftime(3) Çü½Ä formatÀÇ ½Ã°£. (Áö¿ª½Ã°£ÀÏ + ¼ö ÀÖÀ½)
    %...T¿äûÀ» ó¸®Çϴµ¥ °É¸° ½Ã°£ (ÃÊ ´ÜÀ§).
    %...u¿ø°Ý »ç¿ëÀÚ (auth°¡ Á¦°øÇϸç, »óÅÂ(%s)°¡ + 401ÀÎ °æ¿ì ÀÌ»óÇÑ °ªÀ» ³ª¿Ã ¼ö ÀÖÀ½)
    %...UÁúÀǹ®ÀÚ¿­À» Á¦¿ÜÇÑ ¿äû URL °æ·Î.
    %...v¿äûÀ» ¼­ºñ½ºÇÑ ¼­¹öÀÇ Á¤±Ô ServerName.
    %...VUseCanonicalName + ¼³Á¤¿¡ µû¸¥ ¼­¹ö¸í.
    %...XÀÀ´äÀ» ¸¶ÃÆÀ»¶§ ¿¬°á »óÅÂ. + + + + + + + + + +
    X =ÀÀ´äÀ» ¸¶Ä¡±â Àü¿¡ ¿¬°áÀÌ ²÷¾îÁ³´Ù.
    + =ÀÀ´äÀ» º¸³½ÈÄ¿¡µµ ¿¬°áÀÌ »ì¾ÆÀÖ´Ù(keep alive).
    - = ÀÀ´äÀ» º¸³½ÈÄ ¿¬°áÀÌ ²÷¾îÁ³´Ù.
    + +

    (¾ÆÆÄÄ¡ 1.3 ÈÄ¹Ý ¹öÀü¿¡¼­ ÀÌ Áö½Ã¾î´Â + %...c¿´Áö¸¸, ÀüÅëÀûÀÎ ssl + %...{var}c ¹®¹ý°ú °ãÃļ­ + º¯°æÇß´Ù.)

    %...I¿äû°ú Çì´õ¸¦ Æ÷ÇÔÇÑ ¼ö½Å ¹ÙÀÌÆ®¼ö·Î 0ÀÏ ¼ö ¾ø´Ù. + À̸¦ »ç¿ëÇÏ·Á¸é mod_logio°¡ ÇÊ¿äÇÏ´Ù.
    %...OÇì´õ¸¦ Æ÷ÇÔÇÑ ¼Û½Å ¹ÙÀÌÆ®¼ö·Î 0ÀÏ ¼ö ¾ø´Ù. À̸¦ + »ç¿ëÇÏ·Á¸é mod_logio°¡ ÇÊ¿äÇÏ´Ù.
    + +

    "..."¿¡´Â (¿¹¸¦ µé¾î, + "%h %u %r %s %b") ¾Æ¹«°Íµµ ¾ø°Å³ª, Ç׸ñÀ» Æ÷ÇÔÇÒ + Á¶°ÇÀÌ ³ª¿Â´Ù (Á¶°ÇÀ» ¸¸Á·ÇÏÁö ¾ÊÀ¸¸é ÀÚ¸®¿¡ "-"¸¦ ±â·ÏÇÑ´Ù). + Á¶°ÇÀº ¾Õ¿¡ "!"¸¦ ºÙÀ̰ųª ¾ÈºÙÀÎ HTTP »óÅÂÄÚµå ¸ñ·ÏÀ¸·Î + ÀÛ¼ºÇÑ´Ù. ¿¹¸¦ µé¾î, "%400,501{User-agent}i"´Â 400 (Bad + Request) ¿À·ù¿Í 501 (Not Implemented) ¿À·ùÀ϶§¸¸ + User-agent:¸¦ ·Î±×¿¡ ³²±â°í, + "%!200,304,302{Referer}i"´Â Á¤»óÀûÀÎ »óÅ°¡ ¾Æ´Ñ + ¸ðµç ¿äû¿¡ ´ëÇØ Referer:¸¦ ·Î±×¿¡ ³²±ä´Ù.

    + +

    ¼öÁ¤ÀÚ "<"¿Í ">"´Â ³»ºÎ ¸®´ÙÀÌ·º¼ÇµÈ ¿äû¿¡¼­ °¢°¢ + óÀ½ ¿äûÀ» ¸»ÇÒÁö ¸¶Áö¸· ¿äûÀ» ¸»ÇÒÁö ¼±ÅÃÇÑ´Ù. ±âº»ÀûÀ¸·Î + %s, %U, %T, %D, %rÀº óÀ½ ¿äûÀ» º¸°í, ³ª¸ÓÁö + % Áö½Ã¾î´Â ¸¶Áö¸· ¿äûÀ» º»´Ù. ±×·¡¼­ + %>s´Â ¿äûÀÇ ¸¶Áö¸· »óÅÂ(status)¸¦ ±â·ÏÇÏ°í, + %<u´Â ÀÎÁõÀ¸·Î º¸È£ÇÏÁö ¾Ê´Â ÀÚ¿øÀ¸·Î ³»ºÎ + ¶ó´ÙÀÌ·º¼ÇµÈ °æ¿ì¿¡µµ óÀ½¿¡ ÀÎÁõÇÑ »ç¿ëÀÚ¸¦ ±â·ÏÇÑ´Ù.

    + +

    2.0.46 ÀÌÀüÀÇ httpd 2.0 ¹öÀüÀº %...r, + %...i, %...oÀÇ °á°ú ¹®ÀÚ¿­À» ±×´ë·Î + µÎ¾ú´Ù. ÀÌÀ¯´Â Common Log FormatÀÇ ¿ä±¸»çÇ×À» µû¸£±âÀ§Çؼ­¿´´Ù. + Áï, Ŭ¶óÀ̾ðÆ®°¡ Á¦¾î¹®ÀÚ¸¦ ·Î±×¿¡ Áý¾î³ÖÀ» ¼ö Àֱ⶧¹®¿¡ + ·Î±×ÆÄÀÏÀ» ±×´ë·Î ´Ù·ê ¶§´Â Á¶½ÉÇØ¾ß ÇÑ´Ù.

    + +

    º¸¾È»ó ÀÌÀ¯·Î 2.0.46ºÎÅÍ Ãâ·ÂÇÒ ¼ö ¾ø´Â ¹®ÀÚ³ª ´Ù¸¥ Ư¼ö¹®ÀÚ¸¦ + \xhh·Î Ç¥ÇöÇÑ´Ù. ¿©±â¼­ hh´Â + ÇØ´ç ¹ÙÀÌÆ®ÀÇ 16Áø¼ö Ç¥ÇöÀ» ³ªÅ¸³½´Ù. ÀÌ ±ÔÄ¢ÀÇ ¿¹¿Ü´Â ¹é½½·¡½¬¸¦ + ¾Õ¿¡ ºÙÀÌ´Â "¿Í \, ±×¸®°í C¾ð¾î + Çü½ÄÀÇ °ø¹é¹®ÀÚµé(\n, \t µî)ÀÌ´Ù.

    + +

    ÀϹÝÀûÀ¸·Î ¸¹ÀÌ »ç¿ëÇÏ´Â ·Î±× Çü½ÄÀº ´ÙÀ½°ú °°´Ù.

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    °¡»óÈ£½ºÆ® Á¤º¸¸¦ Æ÷ÇÔÇÑ Common Log Format
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined ·Î±× Çü½Ä
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer ·Î±× Çü½Ä
    +
    "%{Referer}i -> %U"
    + +
    Agent (ºê¶ó¿ìÀú) ·Î±× Çü½Ä
    +
    "%{User-agent}i"
    +
    + +

    ¿äûÀ» ¼­ºñ½ºÇÏ´Â ¼­¹öÀÇ Á¤±Ô ServerName°ú ListenÀº °¢°¢ %v¿Í + %p¸¦ »ç¿ëÇÑ´Ù. ·Î±×ºÐ¼® ÇÁ·Î±×·¥ÀÌ ½ÇÁ¦·Î ¿äûÀ» + ¼­ºñ½ºÇϴ ȣ½ºÆ®¸¦ ¾Ë±âÀ§ÇØ °¡»óÈ£½ºÆ® ã±â ¾Ë°í¸®ÁòÀ» + °¡Áú ÇÊ¿ä¾øµµ·Ï ÀÌµé °ªÀº UseCanonicalName ¼³Á¤°ú ¹«°üÇÏ´Ù.

    +
    top
    +
    +

    º¸¾È»ó °í·ÁÇÒ Á¡

    +

    ¼­¹ö¸¦ ½ÃÀÛÇÏ´Â »ç¿ëÀÚ¿Ü¿¡ ´Ù¸¥ »ç¿ëÀÚ°¡ ·Î±×ÆÄÀÏÀ» ÀúÀåÇÏ´Â + µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Áú¶§ ¿Ö º¸¾È¿¡ ¹®Á¦°¡ »ý±â´ÂÁö + º¸¾È ÆÁ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    +
    top
    +

    CookieLog Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÄíÅ°¸¦ ·Î±×¿¡ ³²±â±âÀ§ÇØ »ç¿ëÇÒ ÆÄÀϸíÀ» ¼³Á¤ÇÑ´Ù
    ¹®¹ý:CookieLog filename
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_log_config
    Áö¿ø:ÀÌ Áö½Ã¾î´Â »ç¿ëµÇÁö ¾Ê´Â´Ù.
    +

    CookieLog Áö½Ã¾î´Â ÄíÅ°¸¦ ·Î±×¿¡ + ³²±â±âÀ§ÇØ »ç¿ëÇÒ ÆÄÀϸíÀ» ¼³Á¤ÇÑ´Ù. ÆÄÀϸíÀº ServerRoot¿¡ »ó´ë°æ·ÎÀÌ´Ù. ÀÌ + Áö½Ã¾î´Â mod_cookies¿Í ȣȯÀ» À§ÇØ Æ÷ÇÔÇßÀ»»Ó, + ½ÇÁ¦ »ç¿ëµÇÁö ¾Ê´Â´Ù.

    + +
    +
    top
    +

    CustomLog Áö½Ã¾î

    + + + + + + +
    ¼³¸í:·Î±×ÆÄÀÏ À̸§°ú Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù
    ¹®¹ý:CustomLog file|pipe +format|nickname +[env=[!]environment-variable]
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_log_config
    +

    ¼­¹ö°¡ ¿äûÀ» ·Î±×¿¡ ³²±æ¶§ CustomLog + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ·Î±× Çü½ÄÀ» ÁöÁ¤ÇÏ°í, ȯ°æº¯¼ö¸¦ »ç¿ëÇÏ¿© + ¿äûÀÇ Æ¯Â¡¿¡ µû¶ó ¼±ÅÃÀûÀ¸·Î ·Î±×¸¦ ³²±æ ¼öµµ ÀÖ´Ù.

    + +

    ·Î±×¸¦ ±â·ÏÇÒ Àå¼Ò¸¦ ÁöÁ¤Çϴ ù¹ø° ¾Æ±Ô¸ÕÆ®¿¡´Â ´ÙÀ½ + µÑÁß Çϳª¸¦ »ç¿ëÇÑ´Ù.

    + +
    +
    file
    +
    ServerRoot¿¡ + »ó´ëÀûÀÎ ÆÄÀϸí.
    + +
    pipe
    +
    ÆÄÀÌÇÁ¹®ÀÚ "|"µÚ¿¡ ·Î±× Á¤º¸¸¦ Ç¥ÁØÀÔ·ÂÀ¸·Î + ¹ÞÀ» ÇÁ·Î±×·¥ °æ·Î¸¦ Àû´Â´Ù. + +

    º¸¾È:

    +

    ÇÁ·Î±×·¥À» »ç¿ëÇÑ´Ù¸é ÇÁ·Î±×·¥Àº À¥¼­¹ö¸¦ ½ÃÀÛÇÑ »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ½ÇÇàµÈ´Ù. ¼­¹ö¸¦ root·Î ½ÃÀÛÇÑ´Ù¸é ÇÁ·Î±×·¥µµ + root·Î ½ÇÇàÇϹǷΠÇÁ·Î±×·¥ÀÌ ¾ÈÀüÇÑÁö È®ÀÎÇ϶ó.

    +
    +

    ÁÖÀÇ

    +

    À¯´Ð½º°¡ ¾Æ´Ñ Ç÷¡Æû¿¡¼­ ÆÄÀÏ°æ·Î¸¦ ÀÔ·ÂÇÒ¶§ Ç÷¡ÆûÀÌ + ¹é½½·¡½¬¸¦ »ç¿ëÇÏ´õ¶óµµ ¹Ýµå½Ã ½½·¡½¬¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. + ÀϹÝÀûÀ¸·Î ¼³Á¤ÆÄÀÏ¿¡¼­´Â Ç×»ó ½½·¡½¬¸¦ »ç¿ëÇÏ´Â °ÍÀÌ + ÁÁ´Ù.

    +
    +
    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÒ ³»¿ëÀ» ÁöÁ¤ÇÑ´Ù. + Àü¿¡ LogFormatÀ¸·Î + Á¤ÀÇÇÑ nicknameÀ» »ç¿ëÇϰųª Á÷Á¢ ·Î±× Çü½Ä Àý¿¡¼­ ¼³¸íÇÑ format + ¹®ÀÚ¿­À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ´ÙÀ½ µÎ Áö½Ã¾î´Â ¶È°°Àº ÀÏÀ» ÇÑ´Ù.

    + +

    + # Çü½Ä º°ÄªÀ» »ç¿ëÇÑ CustomLog
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # Á÷Á¢ Çü½Ä ¹®ÀÚ¿­À» »ç¿ëÇÑ CustomLog
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +

    + +

    ¼¼¹ø° ¾Æ±Ô¸ÕÆ®´Â ¾ø¾îµµ µÇ¸ç, ƯÁ¤ ¼­¹ö ȯ°æº¯¼ö À¯¹«¿¡ + µû¶ó ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. ¿äû¿¡ ÁöÁ¤ÇÑ + ȯ°æº¯¼ö°¡ Á¤ÀǵÇÀÖ´Ù¸é (ȤÀº + 'env=!name'¸¦ »ç¿ëÇÑ °æ¿ì ¾ø´Ù¸é) + ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù.

    + +

    mod_setenvif³ª mod_rewrite + ¸ðµâÀ» »ç¿ëÇÏ¿© ¿äûº°·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ¼­¹ö°¡ GIF ±×¸²¿¡ ´ëÇÑ ¸ðµç ¿äûÀ» ÁÖ¼­¹ö ·Î±×°¡ ¾Æ´Ñ + ´Ù¸¥ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ·Á¸é,

    + +

    + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +

    + +
    +
    top
    +

    LogFormat Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:·Î±×ÆÄÀÏ¿¡ »ç¿ëÇÒ Çü½ÄÀ» ±â¼úÇÑ´Ù
    ¹®¹ý:LogFormat format|nickname +[nickname]
    ±âº»°ª:LogFormat "%h %l %u %t \"%r\" %>s %b"
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_log_config
    +

    ÀÌ Áö½Ã¾î´Â Á¢±Ù ·Î±×ÆÄÀÏÀÇ Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    LogFormat Áö½Ã¾î´Â µÎ°¡Áö Çü½ÄÀ¸·Î + »ç¿ëÇÑ´Ù. ù¹ø° Çü½ÄÀº ¾Æ±Ô¸ÕÆ®¸¦ ÇÑ°³¸¸ »ç¿ëÇÏ¿© ´ÙÀ½ + TransferLog Áö½Ã¾îµéÀÌ »ç¿ëÇÒ ·Î±× + Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù. ÀÌ ¾Æ±Ô¸ÕÆ®¿¡ À§ÀÇ ·Î±× + Çü½Ä ÁöÁ¤Çϱâ Àý¿¡¼­ ¼³¸íÇÑ formatÀ» Á÷Á¢ + »ç¿ëÇϰųª, ´ÙÀ½¿¡ ¼³¸íÇÒ LogFormat + Áö½Ã¾î·Î ¹Ì¸® Á¤ÀÇÇÑ (·Î±× Çü½ÄÀ» ÁöĪÇÏ´Â) nicknameÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    LogFormat Áö½Ã¾îÀÇ µÎ¹ø° Çü½ÄÀº + format°ú nicknameÀ» ¿¬°áÇÑ´Ù. ±×·¯¸é + µÚ¿¡¼­ »ç¿ëÇÏ´Â LogFormatÀ̳ª CustomLog Áö½Ã¾î¿¡ ¹Ýº¹Çؼ­ + Çü½Ä ¹®ÀÚ¿­À» ¸ðµÎ ÀÔ·ÂÇÏ´Â ´ë½Å nicknameÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù. º°ÄªÀ» Á¤ÀÇÇÏ´Â LogFormat + Áö½Ã¾î´Â ÀÌ ¿Ü¿¡´Â ¾Æ¹« ±â´ÉÀ» ÇÏÁö ¾Ê´Â´Ù. + Áï, º°Äª¸¸À» Á¤ÀÇÇϸç, ½ÇÁ¦·Î Çü½ÄÀ» Àû¿ëÇϰųª + Çü½ÄÀ» ±âº»°ªÀ¸·Î ¸¸µéÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î ´ÙÀ½¿¡ ³ª¿À´Â + TransferLog + Áö½Ã¾î¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù. ¶Ç, + LogFormatÀº º°ÄªÀ¸·Î ´Ù¸¥ º°ÄªÀ» + Á¤ÀÇÇÒ ¼ö ÀÖ´Ù. º°Äª À̸§¿¡´Â ÆÛ¼¾Æ® ±âÈ£(%)¸¦ + »ç¿ëÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    + +

    ¿¹Á¦

    + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common +

    + +
    +
    top
    +

    TransferLog Áö½Ã¾î

    + + + + + + +
    ¼³¸í:·Î±×ÆÄÀÏ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù
    ¹®¹ý:TransferLog file|pipe
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_log_config
    +

    ÀÌ Áö½Ã¾î´Â CustomLog Áö½Ã¾î¿Í ¾Æ±Ô¸ÕÆ®¿Í + ±â´ÉÀÌ ºñ½ÁÇÏÁö¸¸, ·Î±× Çü½ÄÀ» Á÷Á¢ ÁöÁ¤Çϰųª ¿äûÀ» Á¶°Ç¿¡ + µû¶ó ·Î±×¿¡ ³²±æ ¼ö ¾ø´Ù. ´ë½Å °¡Àå ÃÖ±Ù »ç¿ëÇÑ (º°ÄªÀ» + Á¤ÀÇÇÏÁö ¾ÊÀº) LogFormat Áö½Ã¾î°¡ ÁöÁ¤ÇÑ + ·Î±× Çü½ÄÀ» »ç¿ëÇÑ´Ù. ¹Ì¸® Çü½ÄÀ» ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é Common + Log FormatÀ» »ç¿ëÇÑ´Ù.

    + +

    ¿¹Á¦

    + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_log_config.xml b/trunk/docs/manual/mod/mod_log_config.xml new file mode 100644 index 0000000000..2f623ca386 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.xml @@ -0,0 +1,487 @@ + + + + + + + + + +mod_log_config +Logging of the requests made to the server +Base +mod_log_config.c +log_config_module + + +

    This module provides for flexible logging of client + requests. Logs are written in a customizable format, and may be + written directly to a file, or to an external program. + Conditional logging is provided so that individual requests may + be included or excluded from the logs based on characteristics + of the request.

    + +

    Three directives are provided by this module: + TransferLog to create + a log file, LogFormat + to set a custom format, and CustomLog to define a log file and format in one + step. The TransferLog and CustomLog directives can be used multiple times in each + server to cause each request to be logged to multiple files.

    +
    +Apache Log Files + +
    Custom Log Formats + +

    The format argument to the LogFormat and CustomLog directives is a string. This string is + used to log each request to the log file. It can contain literal + characters copied into the log files and the C-style control + characters "\n" and "\t" to represent new-lines and tabs. + Literal quotes and back-slashes should be escaped with + back-slashes.

    + +

    The characteristics of the request itself are logged by + placing "%" directives in the format string, which are + replaced in the log file by the values as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Format StringDescription
    %%The percent sign
    %aRemote IP-address
    %ALocal IP-address
    %BSize of response in bytes, excluding HTTP headers.
    %bSize of response in bytes, excluding HTTP headers. In CLF format, i.e. + a '-' rather than a 0 when no bytes are sent.
    %{Foobar}CThe contents of cookie Foobar in the request sent + to the server.
    %DThe time taken to serve the request, in microseconds.
    %{FOOBAR}eThe contents of the environment variable + FOOBAR
    %fFilename
    %hRemote host
    %HThe request protocol
    %{Foobar}iThe contents of Foobar: header line(s) + in the request sent to the server.
    %lRemote logname (from identd, if supplied). This will return a + dash unless mod_ident is present and IdentityCheck is set + On.
    %mThe request method
    %{Foobar}nThe contents of note Foobar from another + module.
    %{Foobar}oThe contents of Foobar: header line(s) + in the reply.
    %pThe canonical port of the server serving the request
    %PThe process ID of the child that serviced the request.
    %{format}PThe process ID or thread id of the child that serviced the + request. Valid formats are pid and tid. +
    %qThe query string (prepended with a ? if a query + string exists, otherwise an empty string)
    %rFirst line of request
    %sStatus. For requests that got internally redirected, this is + the status of the *original* request --- %>s + for the last.
    %tTime the request was received (standard english + format)
    %{format}tThe time, in the form given by format, which should be in + strftime(3) format. (potentially localized)
    %TThe time taken to serve the request, in seconds.
    %uRemote user (from auth; may be bogus if return status + (%s) is 401)
    %UThe URL path requested, not including any query string.
    %vThe canonical ServerName + of the server serving the request.
    %VThe server name according to the UseCanonicalName setting.
    %XConnection status when response is completed: + + + + + + + + + +
    X =connection aborted before the response completed.
    + =connection may be kept alive after the response is + sent.
    - = connection will be closed after the response is + sent.
    + +

    (This directive was %c in late versions of Apache + 1.3, but this conflicted with the historical ssl + %{var}c syntax.)

    %IBytes received, including request and headers, cannot be zero. + You need to enable mod_logio to use this.
    %OBytes sent, including headers, cannot be zero. You need to + enable mod_logio to use this.
    + +
    Modifiers + +

    Particular items can be restricted to print only for + responses with specific HTTP status codes by placing a + comma-separated list of status codes immediately following the + "%". For example, "%400,501{User-agent}i" logs + User-agent on 400 errors and 501 errors only. For + other status codes, the literal string "-" will be + logged. The status code list may be preceded by a + "!" to indicate negation: + "%!200,304,302{Referer}i" logs Referer + on all requests that do not return one of the three + specified codes.

    + +

    The modifiers "<" and ">" can be used for requests that + have been internally redirected to choose whether the original + or final (respectively) request should be consulted. By + default, the % directives %s, %U, %T, + %D, and %r look at the original request + while all others look at the final request. So for example, + %>s can be used to record the final status of + the request and %<u can be used to record the + original authenticated user on a request that is internally + redirected to an unauthenticated resource.

    + +
    + +
    Some Notes + +

    For security reasons, starting with version 2.0.46, + non-printable and other special characters in %r, + %i and %o are escaped using + \xhh sequences, where hh + stands for the hexadecimal representation of the raw + byte. Exceptions from this rule are " and + \, which are escaped by prepending a backslash, and + all whitespace characters, which are written in their C-style + notation (\n, \t, etc). In versions + prior to 2.0.46, no escaping was performed on these strings so + you had to be quite careful when dealing with raw log files.

    + +

    In httpd 2.0, unlike 1.3, the %b and + %B format strings do not represent the number of + bytes sent to the client, but simply the size in bytes of the + HTTP response (which will differ, for instance, if the + connection is aborted, or if SSL is used). The %O + format provided by mod_logio will log the + actual number of bytes sent over the network.

    + +
    + +
    Examples + +

    Some commonly used log format strings are:

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    Common Log Format with Virtual Host
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined log format
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer log format
    +
    "%{Referer}i -> %U"
    + +
    Agent (Browser) log format
    +
    "%{User-agent}i"
    +
    +
    +
    + +
    Security Considerations +

    See the security tips + document for details on why your security could be compromised + if the directory where logfiles are stored is writable by + anyone other than the user that starts the server.

    +
    + + +BufferedLogs +Buffer log entries in memory before writing to disk +BufferedLogs On|Off +BufferedLogs Off +server config +Experimental +Available in versions 2.0.41 and later. + + +

    The BufferedLogs directive causes + mod_log_config to store several log entries in + memory and write them together to disk, rather than writing them + after each request. On some systems, this may result in more + efficient disk access and hence higher performance. It may be + set only once for the entire server; it cannot be configured + per virtual-host.

    + + This directive is experimental and should be used with + caution. +
    +
    + + +CookieLog +Sets filename for the logging of cookies +CookieLog filename +server configvirtual host + +This directive is deprecated. + + +

    The CookieLog directive sets the + filename for logging of cookies. The filename is relative to the + ServerRoot. This directive is + included only for compatibility with mod_cookies, + and is deprecated.

    +
    +
    + + +CustomLog +Sets filename and format of log file +CustomLog file|pipe +format|nickname +[env=[!]environment-variable] +server configvirtual host + + + +

    The CustomLog directive is used to + log requests to the server. A log format is specified, and the + logging can optionally be made conditional on request + characteristics using environment variables.

    + +

    The first argument, which specifies the location to which + the logs will be written, can take one of the following two + types of values:

    + +
    +
    file
    +
    A filename, relative to the ServerRoot.
    + +
    pipe
    +
    The pipe character "|", followed by the path + to a program to receive the log information on its standard + input. + + Security: +

    If a program is used, then it will be run as the user who + started httpd. This will be root if the server was + started by root; be sure that the program is secure.

    +
    + Note +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    +
    + +

    The second argument specifies what will be written to the + log file. It can specify either a nickname defined by + a previous LogFormat + directive, or it can be an explicit format string as + described in the log formats section.

    + +

    For example, the following two sets of directives have + exactly the same effect:

    + + + # CustomLog with format nickname
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # CustomLog with explicit format string
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +
    + +

    The third argument is optional and controls whether or + not to log a particular request based on the + presence or absence of a particular variable in the server + environment. If the specified environment + variable is set for the request (or is not set, in the case + of a 'env=!name' clause), then the + request will be logged.

    + +

    Environment variables can be set on a per-request + basis using the mod_setenvif + and/or mod_rewrite modules. For + example, if you want to record requests for all GIF + images on your server in a separate logfile but not in your main + log, you can use:

    + + + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +
    + +

    Or, to reproduce the behavior of the old RefererIgnore + directive, you might use the following:

    + + + SetEnvIf Referer example\.com localreferer
    + CustomLog referer.log referer env=!localreferer +
    +
    +
    + + +LogFormat +Describes a format for use in a log file +LogFormat format|nickname +[nickname] +LogFormat "%h %l %u %t \"%r\" %>s %b" +server configvirtual host + + + +

    This directive specifies the format of the access log + file.

    + +

    The LogFormat directive can take one of two + forms. In the first form, where only one argument is specified, + this directive sets the log format which will be used by logs + specified in subsequent TransferLog + directives. The single argument can specify an explicit + format as discussed in the custom log + formats section above. Alternatively, it can use a + nickname to refer to a log format defined in a + previous LogFormat directive as described + below.

    + +

    The second form of the LogFormat + directive associates an explicit format with a + nickname. This nickname can then be used in + subsequent LogFormat or + CustomLog directives + rather than repeating the entire format string. A + LogFormat directive that defines a nickname + does nothing else -- that is, it only + defines the nickname, it doesn't actually apply the format and make + it the default. Therefore, it will not affect subsequent + TransferLog directives. + In addition, LogFormat cannot use one nickname + to define another nickname. Note that the nickname should not contain + percent signs (%).

    + + Example + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common + +
    +
    + + +TransferLog +Specify location of a log file +TransferLog file|pipe +server configvirtual host + + + +

    This directive has exactly the same arguments and effect as + the CustomLog + directive, with the exception that it does not allow the log format + to be specified explicitly or for conditional logging of requests. + Instead, the log format is determined by the most recently specified + LogFormat directive + which does not define a nickname. Common Log Format is used if no + other format has been specified.

    + + Example + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_log_config.xml.ja b/trunk/docs/manual/mod/mod_log_config.xml.ja new file mode 100644 index 0000000000..9fffdc15e8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.xml.ja @@ -0,0 +1,493 @@ + + + + + + + + + +mod_log_config +$B%5!<%P$X$N%j%/%(%9%H$N%m%.%s%0(B +Base +mod_log_config.c +log_config_module + + +

    + $B$3$N%b%8%e!<%k$O%/%i%$%"%s%H$N%j%/%(%9%H$r=@Fp$K%m%0<}=8$9$k5!G=$r(B + $BDs6!$7$^$9!#%m%0$O%+%9%?%^%$%:2DG=$J=q<0$G=q$+$l!"%U%!%$%k$KD>@\(B + $B=q$$$?$j!"30It%W%m%0%i%`$KEO$7$?$j$9$k$3$H$,$G$-$^$9!#8D!9$N%j%/%(%9%H$r(B + $BFCD'$K1~$8$F%m%0$K=q$$$?$j=q$+$J$+$C$?$j$G$-$k$h$&$K!">r7o$K$h$k(B + $B%m%0<}=8$bDs6!$5$l$F$$$^$9!#(B

    + +

    $B$3$N%b%8%e!<%k$O;0$D$N%G%#%l%/%F%#%VDs6!$7$^$9(B: + $B%m%0%U%!%$%k$r:n@.$9$k$?$a$N(B TransferLog, + $B?7$7$$=q<0$r(B $BDj5A$9$k(B LogFormat, + $B%m%0%U%!%$%k$H(B $B=q<0$r0lEY$KDj5A$9$k(B CustomLog $B$G$9!#(B + $B3F%j%/%(%9%H$,J#?t2s%m%0<}=8$5$l$k$h$&$K$9$k$?$a$K(B + TransferLog $B%G%#%l%/%F%#%V$H(B + CustomLog + $B%G%#%l%/%F%#%V$OJ#?t2s;HMQ$9$k$3$H$,$G$-$^$9!#(B

    +
    +Apache $B%m%0%U%!%$%k(B + +
    $B%+%9%?%`%m%0=q<0(B + +

    LogFormat $B%G%#%l%/%F%#%V$H(B + CustomLog + $B%G%#%l%/%F%#%V$N=q<0$r;XDj$9$k0z?t$OJ8;zNs$G$9!#$3$NJ8;zNs$r;H$C$F$=$l$>$l$N(B + $B%j%/%(%9%H$,%m%0%U%!%$%k$K%m%0<}=8$5$l$^$9!#$=$NJ8;zNs$K$O(B + $B%m%0%U%!%$%k$K$=$N$^$^(B + $B=q$+$l$kJ8;zNs$d!"$=$l$>$l2~9T$H%?%V$r8=$9(B C $B8@8l(B + $B7A<0$N@)8fJ8;z(B "\n" $B$H(B "\t" + $B$H$r4^$a$k$3$H$,$G$-$^$9!#$=$N$^$^=PNO$5$;$?$$0zMQId$H%P%C%/%9%i%C%7%e$O(B + $B%P%C%/%9%i%C%7%e$G%(%9%1!<%W$9$kI,MW$,$"$j$^$9!#(B

    + +

    $B%j%/%(%9%H$NFCD'$=$N$b$N$O(B "%" + $B%G%#%l%/%F%#%V$r=q<0$NJ8;zNs$K=q$/$3$H$G(B + $B%m%0<}=8$5$l$^$9!#(B"%" + $B%G%#%l%/%F%#%V$O%m%0%U%!%$%kCf$G$O0J2<$N$h$&$J(B + $BCM$GCV49$5$l$^$9(B:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%U%)!<%^%C%HJ8;zNs(B$B@bL@(B
    %%$B%Q!<%;%s%H5-9f(B
    %...a$B%j%b!<%H(B IP $B%"%I%l%9(B
    %...A$B%m!<%+%k(B IP $B%"%I%l%9(B
    %...B$B%l%9%]%s%9$N%P%$%H?t!#(BHTTP $B%X%C%@$O=|$/!#(B
    %...b$B%l%9%]%s%9$N%P%$%H?t!#(BHTTP $B%X%C%@$O=|$/!#(BCLF $B=q<0!#(B + $B$9$J$o$A(B$B!"(B1 $B%P%$%H$bAw$i$l$J$+$C$?$H$-$O(B 0 $B$G$O$J$/!"(B + '-' $B$K$J$k(B
    %...{Foobar}C$B%5!<%P$KAw$i$l$?%j%/%(%9%HCf$N%/%C%-!<(B Foobar $B$NCM(B
    %...D$B%j%/%(%9%H$r=hM}$9$k$N$K$+$+$C$?;~4V!"%_%jICC10L(B
    %...{FOOBAR}e$B4D6-JQ?t(B FOOBAR $B$NFbMF(B
    %...f$B%U%!%$%kL>(B
    %...h$B%j%b!<%H%[%9%H(B
    %...H$B%j%/%(%9%H%W%m%H%3%k(B
    %...{Foobar}i$B%5!<%P$KAw$i$l$?%j%/%(%9%H$N(B Foobar: + $B%X%C%@$NFbMF(B
    %...l(identd $B$+$i$b$7Ds6!$5$l$F$$$l$P(B) $B%j%b!<%H%m%0L>!#(B + $B$3$l$O(B mod_ident $B$,%5!<%P$KB8:_$7$F!"(B + IdentityCheck + $B%G%#%l%/%F%#%V$,(B On $B$K@_Dj$5$l$F$$$J$$8B$j!"(B + - $B$K$J$j$^$9!#(B
    %...m$B%j%/%(%9%H%a%=%C%I(B
    %...{Foobar}n$BB>$N%b%8%e!<%k$+$i$N%a%b(B Foobar $B$NFbMF(B
    %...{Foobar}o$B1~Ez$N(B Foobar: $B%X%C%@$NFbMF(B
    %...p$B%j%/%(%9%H$r07$C$F$$$k%5!<%P$N@5<0$J%]!<%H(B
    %...P$B%j%/%(%9%H$r07$C$?;R%W%m%;%9$N%W%m%;%9(B ID
    %...{format}P$B%j%/%(%9%H$r07$C$?%o!<%+!<$N%W%m%;%9(B ID $B$+%9%l%C%I(B ID$B!#(B + format $B$H$7$FM-8z$JCM$O(B pid $B$H(B tid +
    %...q$BLd$$9g$;J8;zNs(B ($BB8:_$9$k>l9g$OA0$K(B ? $B$,DI2C$5$l$k!#(B + $B$=$&$G$J$$>l9g$O6uJ8;zNs(B)
    %...r$B%j%/%(%9%H$N:G=i$N9T(B
    %...s$B%9%F!<%?%9!#FbIt$G%j%@%$%l%/%H$5$l$?%j%/%(%9%H$O!"85!9$N(B + $B%j%/%(%9%H$N%9%F!<%?%9(B --- $B:G8e$N%9%F!<%?%9$O(B %...>s +
    %...t$B%j%/%(%9%H$r
    %...{format}tformat $B$GM?$($i$l$?=q<0$K$h$k;~9o!#(Bformat $B$O(B + strftime (3) $B$N(B + $B=q<0$G$"$kI,MW$,$"$k!#(B($BCO0h2=$5$l$F$$$k2DG=@-$,$"$k(B)
    %...T$B%j%/%(%9%H$r07$&$N$K$+$+$C$?;~4V!"ICC10L(B
    %...u$B%j%b!<%H%f!<%6(B ($BG'>Z$K$h$k$b$N!#%9%F!<%?%9(B (%s) $B$,(B + 401 $B$N$H$-$O0UL#$,$J$$$b$N$G$"$k2DG=@-$,$"$k(B) +
    %...U$B%j%/%(%9%H$5$l$?(B URL $B%Q%9!#%/%(%jJ8;zNs$O4^$^$J$$(B
    %...v$B%j%/%(%9%H$r07$C$F$$$k%5!<%P$N@5<0$J(B ServerName
    %...VUseCanonicalName $B$N@_Dj$K$h$k%5!<%PL>(B
    %...X$B1~Ez$,40N;$7$?$H$-$N@\B3%9%F!<%?%9(B: + + + + + + + + + +
    X =$B1~Ez$,40N;$9$kA0$K@\B3$,0[>o=*N;(B
    + =$B1~Ez$,Aw$i$l$?8e$K@\B3$r;}B3$9$k$3$H$,2DG=(B
    - = $B1~Ez$,Aw$i$l$?8e$K@\B3$,@Z$i$l$k(B
    + +

    ($B$3$N%G%#%l%/%F%#%V$O(B Apache + 1.3 $B$N8e4|$N%P!<%8%g%s$G$O(B %...c $B$K3d$jEv$F$i$l$F(B + $B$$$^$7$?$,!"$3$l$ONr;KE*$K(B ssl $B$,;HMQ$7$F$$$k(B + %...{var}c + $B9=J8$H>WFM$7$F$$$^$7$?!#(B)

    %...I$B%j%/%(%9%H$H%X%C%@$r4^$`!"mod_logio $B$,I,MW(B
    %...O$B%X%C%@$r4^$`!"Aw?.$7$?%P%$%H?t!#(B0 $B$K$O$J$i$J$$!#(B + $B$3$l$r;HMQ$9$k$?$a$K$O(B mod_logio $B$,I,MW(B
    + +

    "..." $B$O2?$b$J$$$+(B ($BNc$($P(B$B!"(B + "%h %u %r %s %b" $B$N$h$&$K(B)$B!"(B + $B$=$N9`L\$r4^$a$k$+$I$&$+$N>r7o(B ($B$b$7>r7o$K9g$o$J$+$C$?$H$-$O(B + $B$=$N9`L\$O(B "-" $B$K$J$j$^$9(B) $B$K$9$k$3$H$,$G$-$^$9!#>r7o$N7A<0$O(B + HTTP $B%9%F!<%?%9%3!<%I$N%j%9%H$G!"A0$K(B "!" $B$rIU$1$k$3$H$b$G$-$^$9!#(B + $B$G$9$+$i!"(B"%400,501{User-agent}i" $B$O(B 400 $B%(%i!<$H(B 501 $B%(%i!<(B + (Bad Request $B$H(B Not Implemented) $B$N$H$-$N$_(B User-agent: + $B$r%m%0<}=8$7$^$9!#(B + "%!200,304,302{Referer}i" $B$OIaDL$N%9%F!<%?%9$r(B$BJV$5$J$+$C$?(B + $B$9$Y$F$N%j%/%(%9%H$G(B Referer: $B$r%m%0<}=8$7$^$9!#(B

    + +

    $B=$>~;R(B "<" $B$H(B ">" $B$OFbIt%j%@%$%l%/%H$5$l$?%j%/%(%9%H$N%m%0$K(B + $B85$N%j%/%(%9%H$+:G=*E*$J%j%/%(%9%H$N$I$A$i$r;HMQ$9$k$+$r(B + $B;XDj$9$k$?$a$K;H$$$^$9!#%G%U%)%k%H$G$O!"(B% $B%G%#%l%/%F%#%V$N(B + %s, %U, %T, %D, %r $B$O85$N%j%/%(%9%H$r!"B>$O:G=*E*$J%j%/%(%9%H$r(B + $B;HMQ$7$^$9!#Nc$($P!"%j%/%(%9%H$N:G=*%9%F!<%?%9$r5-O?$9$k$K$O(B + %>s $B$r!"FbItE*$KG'>Z$5$l$F$$$J$$%j%=!<%9$X%j%@%$%l%/%H$5$l$?(B + $B%j%/%(%9%H$G85$N%j%/%(%9%H$GG'>Z$5$l$?%f!<%6$r5-O?$9$k$?$a$K$O(B + %<u $B$r;H$&$3$H$,$G$-$^$9!#(B

    + +

    httpd 2.0 $B$N(B 1.3.25 $B$h$jA0$N%P!<%8%g%s$G$O!"(B + %...r, %...i, + %...o $B$NJ8;zNs$O(B + $B%(%9%1!<%W$5$l$F$$$J$+$C$?$3$H$K(B + $BCm0U$7$F$/$@$5$$!#$3$l$Oo$KCm0U$,I,MW$G$7$?!#(B

    + +

    $B%;%-%e%j%F%#>e$NM}M3$K$h$j(B 2.0.46 $B$h$j0u;zIT2DG=$JJ8;z$H(B + $BB>$NFCJL$JJ8;z$O!"$[$H$s$I(B \xhh $B$H$$$&(B + $BJ8;zNs$G%(%9%1!<%W$5$l$k$h$&$K$J$j$^$7$?!#$3$3$G!"(Bhh $B$O(B + $B$=$N$^$^$N%P%$%H$NCM$N(B 16 $B?J$G$NCM$G$9!#$3$N5,B'$NNc30$K$O!"(B + $B%P%C%/%9%i%C%7%e$r;H$C$F%(%9%1!<%W$5$l$k(B " $B$H(B \ $B$H!"(B + C $B7A<0$NI=5-K!$,;H$o$l$k6uGrJ8;z(B (\n, \t $B$J$I(B) $B$,(B + $B$"$j$^$9!#(B

    + +

    httpd 2.0 $B$G$O(B 1.3 $B$H$O0[$J$j!"(B%b $B$H(B %B + $B%U%)!<%^%C%HJ8;zNs$O%/%i%$%"%s%H$KAw?.$5$l$?%P%$%H?t$=$N$b$N$G$O$J$/!"(B + HTTP $B%l%9%]%s%9$N%P%$%H?t$G$9(B ($B$3$l$i$O0[$J$k$b$N$G!"$?$H$($P!"(B + $B%3%M%/%7%g%s$,ESCf$GGK4~$5$l$?>l9g$d!"(BSSL $B;HMQ;~$K0lCW$7$^$;$s(B) $B!#(B + mod_logio $B$GDs6!$5$l$F$$$k(B %O + $B%U%)!<%^%C%HJ8;zNs$G!"%M%C%H%o!<%/7PM3$GAw$5$l$?%P%$%H?t$r(B + $B5-O?$G$-$^$9!#(B

    + +

    $B$h$/;H$o$l$k%U%)!<%^%C%HJ8;zNs$O(B:

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    $B%P!<%A%c%k%[%9%HIU$-(B Common Log Format
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined $B%m%0=q<0(B
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer $B%m%0=q<0(B
    +
    "%{Referer}i -> %U"
    + +
    Agent ($B%V%i%&%6(B) $B%m%0=q<0(B
    +
    "%{User-agent}i"
    +
    + +

    %v $B$H(B %p $B$K$O$=$l$>$l!"(B + $B%j%/%(%9%H$r07$C$F$$$k%5!<%P$N@55,2=$5$l$?(B + ServerName $B$H(B Listen $B$,;H$o$l$k$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B + $B$3$l$O(B UseCanonicalName $B$N(B + $B@_Dj$K4X$o$i$:!">o$K$=$&$J$j$^$9!#$=$&$7$J$$$H$I$N(B + $B%[%9%H$, +

    + +
    $B%;%-%e%j%F%#$K4X$7$F(B +

    $B%m%0%U%!%$%k$,J]B8$5$l$F$$$k%G%#%l%/%H%j$,%5!<%P$r5/F0$7$?0J30$N%f!<%6$G(B + $B=q$-9~$_2DG=$J$H$-$K%;%-%e%j%F%#$NLdBj$,H/@8$9$kM}M3$N>\:Y$O(B$B%;%-%e%j%F%#$N$3$D(B + $B$r;2>H$7$F$/$@$5$$!#(B

    +
    + + +BufferedLogs +$B%G%#%9%/$K=q$-=P$9A0$K%a%b%j$K%m%0%(%s%H%j$r%P%C%U%!$9$k(B +BufferedLogs On|Off +BufferedLogs Off +server config +Experimental +2.0.41 $B0J9_(B + + +

    BufferedLogs $B%G%#%l%/%F%#%V$r;H$&$H(B + mod_log_config $B$N5sF0$,JQ2=$7$F!"(B + $BJ#?t$N%m%0$r=q$-=P$9:]$K!"$=$l$>$l$N%j%/%(%9%H=hM}8eKh$K(B + $B=q$-=P$9$N$G$O$J$/!"$$$C$?$s%a%b%j$KC_$($F$+$i!"(B + $B$^$H$a$F%G%#%9%/$K=q$-=P$9$h$&$K$J$j$^$9!#(B + $B$3$N7k2L%G%#%9%/%"%/%;%9$,$h$j8zN(E*$K$J$j!"(B + $B9b$$%Q%U%)!<%^%s%9$NF@$i$l$k%7%9%F%`$b$"$k$G$7$g$&!#(B + $B$3$N%G%#%l%/%F%#%V$O%5!<%PA4BN$G0lEY$@$1@_Dj$G$-$^$9(B; + $B%P!<%A%c%k%[%9%H$4$H$K@_Dj$9$k$3$H$O$G$-$^$;$s!#(B

    + + $B$3$N%G%#%l%/%F%#%V$O +
    +
    + + +CookieLog +$B%/%C%-%s%0$N%m%.%s%0$N$?$a$N%U%!%$%kL>$r@_Dj$9$k(B +CookieLog filename +server configvirtual host + +$B$3$N%G%#%l%/%F%#%V$OHs?d>)(B + + +

    CookieLog + $B%G%#%l%/%F%#%V$O%/%C%-!<$N%m%.%s%0$N$?$a$N%U%!%$%kL>$r(B + $B@_Dj$7$^$9!#(Bfilename $B$O(B ServerRoot + $B$+$i$NAjBP%Q%9$G$9!#$3$N%G%#%l%/%F%#%V$O(B mod_cookies $B$H$N8_49@-$N$?$a$@$1$K(B + $BB8:_$7!";HMQ$O?d>)$5$l$F$$$^$;$s!#(B

    +
    +
    + + +CustomLog +$B%m%0%U%!%$%k$NL>A0$H=q<0$r@_Dj$9$k(B +CustomLog file|pipe +format|nickname +[env=[!]environment-variable] +server configvirtual host + + + +

    CustomLog $B%G%#%l%/%F%#%V$O%5!<%P$X$N%j%/%(%9%H$r(B + $B%m%0<}=8$9$k$?$a$K;H$o$l$^$9!#%m%0$N=q<0$,;XDj$5$l!"(B + $B4D6-JQ?t$r;H$C$F%m%.%s%0$,>r7o$K1~$8$F9T$J$o$l$k$h$&$K$9$k$3$H$b$G$-$^$9!#(B

    + +

    $B%m%0$,=q$+$l$k>l=j$r;XDj$9$k:G=i$N0z?t$O0J2<$NFs$D$N7A<0$NCM$r(B + $B$H$k$3$H$,$G$-$^$9(B:

    + +
    +
    file
    +
    ServerRoot + $B$+$i$NAjBP%Q%9$GI=$5$l$k%U%!%$%kL>!#(B
    + +
    pipe
    +
    $B%Q%$%WJ8;z(B "|" $B$H!"$=$N8e$KI8=`F~NO$+$i%m%0$N(B + $B>pJs$r$B%;%-%e%j%F%#(B +

    $B$b$7%W%m%0%i%`$,;HMQ$5$l$?>l9g!"(B + httpd $B$,5/F0$5$l$?%f!<%6$H$7$Fl9g$O(B root $B$K$J$j$^$9!#%W%m%0%i%`$,(B + $B0BA4$G$"$k$h$&$KN10U$7$F$/$@$5$$!#(B

    + + $BCm(B +

    Unix $B$G$J$$%W%i%C%H%U%)!<%`$G%U%!%$%k$N%Q%9$rF~NO$7$F$$$k$H$-$O!"(B + $B;HMQ$7$F$$$k%W%i%C%H%U%)!<%`$,%P%C%/%9%i%C%7%e$N;HMQ$r5v2D$7$F$$$?(B + $B$H$7$F!"DL>o$N%9%i%C%7%e$@$1$r;H$&$h$&$K5$$r$D$1$F$/$@$5$$!#(B + $B0lHLE*$K!"@_Dj%U%!%$%kCf$G$O>o$KIaDL$N%9%i%C%7%e$N$_$r;H$&$h$&$K$9$k(B + $BJ}$,NI$$$G$9!#(B

    +
    +
    + +

    $BFs$D$a$N0z?t$O%m%0%U%!%$%k$K2?$,=q$+$l$k$+$r;XDj$7$^$9!#(B + $BA0$K$"$k(B LogFormat $B%G%#%l%/%F%#%V$K$h$j(B + $BDj5A$5$l$?(B nickname $B$+!"(B$B%m%0$N=q<0(B + $B$N$H$3$m$G@bL@$5$l$F$$$k!"L@<(E*$J(B format $BJ8;zNs$N(B + $B$I$A$i$+$r;XDj$9$k$3$H$,$G$-$^$9!#(B

    + +

    $BNc$($P!"0J2<$NFs$D$N%G%#%l%/%F%#%V72$OA4$/F1$88z2L$r$b$?$i$7$^$9(B:

    + + + # CustomLog with format nickname
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # CustomLog with explicit format string
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +
    + +

    $B;0$DL\$N0z?t$O>JN,2DG=$G!"%5!<%P$N4D6-$K$"$kJQ?t$,$"$k$+$J$$$+$K(B + $B1~$8$F%j%/%(%9%H$r%m%0<}=8$9$k$+$I$&$+$r@)8f$9$k$?$a$K;H$&$3$H$,$G$-$^$9!#(B + $B;XDj$5$l$?(B$B4D6-JQ?t(B$B$,%j%/%(%9%H$KBP$7$F(B + $B@_Dj$5$l$F$$$?>l9g(B ('env=!name' $BJ8$,;H$o$l$?$H$-$O(B + $B@_Dj$5$l$F$$$J$$>l9g(B)$B!"%j%/%(%9%H$,%m%0<}=8$5$l$^$9!#(B

    + +

    $B4D6-JQ?t$O(B mod_setenvif $B%b%8%e!<%k$H(B + mod_rewrite $B%b%8%e!<%k$NN>J}$b$7$/$O(B + $BJRJ}$rMQ$$$F%j%/%(%9%H$4$H$K@_Dj$9$k$3$H$,$G$-$^$9!#(B + $BNc$($P!"%5!<%P$K$"$k$9$Y$F$N(B GIF $B2hA|$X$N%j%/%(%9%H$rJL$N%m%0%U%!%$%k(B + $B$K$O5-O?$7$?$$$1$l$I!"%a%$%s%m%0$K$O5-O?$7$?$/$J$$!"$H$$$&$H$-$O(B + $B0J2<$N$b$N$r;H$&$3$H$,$G$-$^$9(B:

    + + + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +
    + +

    $B8E$$(B RefererIgnore $B%G%#%l%/%F%#%V$HF1$85sF0$r$5$;$?$$>l9g$O!"(B + $B + + + SetEnvIf Referer example\.com localreferer
    + CustomLog referer.log referer env=!localreferer +
    + + + + +LogFormat +$B%m%0%U%!%$%k$G;HMQ$9$k=q<0$r@_Dj$9$k(B +LogFormat format|nickname +[nickname] +LogFormat "%h %l %u %t \"%r\" %>s %b" +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O%"%/%;%9%m%0%U%!%$%k$N=q<0$r;XDj$7$^$9!#(B

    + +

    LogFormat $B%G%#%l%/%F%#%V$OFs$D$N7A<0$N$I$A$i$+$r(B + $B$H$k$3$H$,$G$-$^$9!#:G=i$N7A<0$G$O0l$D$N0z?t$N$_$,;XDj$5$l!"(B + $BB3$/(B TransferLog + $B$G;XDj$5$l$?%m%0$G;H$o$l$k%m%0$N=q<0$r@_Dj$7$^$9!#$3$NC1FH$N0z?t$G$O(B + $B>e$N(B$B%+%9%?%`%m%0=q<0(B$B$G@bL@$5$l$F$$$k$h$&$K(B + format $B$rL@<(E*$K;XDj$9$k$3$H$,$G$-$^$9!#(B + $B$b$7$/$O!"2<$G@bL@$5$l$F$$$k$h$&$KA0$K(B LogFormat + $B%G%#%l%/%F%#%V$GDj5A$5$l$?%m%0$N=q<0$r(B nickname$B$r;H$C$F(B + $B;2>H$9$k$3$H$b$G$-$^$9!#(B

    + +

    LogFormat $B%G%#%l%/%F%#%V$NFs$D$a$N7A<0$O(B + format $B$K(B nickname $B$rM?$($^$9!#(B + $B%U%)!<%^%C%HJ8;zNsA4BN$r:F$S=q$/$+$o$j$K!"(B + $B$3$N(B nickname $B$rB3$-$N(B LogFormat $B%G%#%l%/%F%#%V$d(B + CustomLog $B%G%#%l%/%F%#%V$G;H$&$3$H$,$G$-$^$9!#(B + Nickname $B$rDj5A$9$k(B LogFormat $B%G%#%l%/%F%#%V$O(B + $BB>$K$O2?$b$7$^$;$s(B -- $B$9$J$o$A!"%K%C%/%M!<%`$rDj5A(B + $B$9$k$@$1$G!"TransferLog + $B%G%#%l%/%F%#%V$K$O1F6A$rM?$($^$;$s!#(B + $B$5$i$K!"(BLogFormat $B%G%#%l%/%F%#%V$O4{B8$N(B nickname $B$r(B + $B;H$C$FJL$N(B nickname $B$rDj5A$9$k$3$H$O$G$-$^$;$s!#(BNickname $B$K$O(B + $B%Q!<%;%s%H5-9f(B (%) $B$,4^$^$l$F$$$F$O$$$1$J$$$3$H$K$bCm0U(B + $B$7$F$/$@$5$$!#(B

    + + $BNc(B + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common + +
    +
    + + +TransferLog +$B%m%0%U%!%$%k$N0LCV$r;XDj(B +TransferLog file|pipe +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O!"%m%0=q<0$rD>@\;XDj$G$-$J$$$3$H$H!"(B + $B>r7oIU$-%m%.%s%0$,L5$$$3$H$r=|$/$H!"(BCustomLog $B$HA4$/F1$80z?t$H8z2L$,$"$j$^$9!#(B + $BD>@\%m%0=q<0$r;XDj$9$kBe$o$j$K!"%m%0$N=q<0$O$=$3$^$G$G0lHV:G8e$K;XDj$5$l$?(B + $B%K%C%/%M!<%`$rDj5A$7$J$$(B + LogFormat $B%G%#%l%/%F%#%V(B + $B$GDj5A$5$l$?$b$N$r;H$$$^$9!#(B + $B$b$7B>$N=q<0$,A4$/;XDj$5$l$F$$$J$$$H$-$O(B Common Log Format + $B$,;H$o$l$^$9!#(B

    + + $BNc(B + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_log_config.xml.ko b/trunk/docs/manual/mod/mod_log_config.xml.ko new file mode 100644 index 0000000000..1a8e2c05c2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.xml.ko @@ -0,0 +1,421 @@ + + + + + + + + + +mod_log_config +¼­¹ö·ÎÀÇ ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù +Base +mod_log_config.c +log_config_module + + +

    ÀÌ ¸ðµâÀº Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ·Î±×¿¡ ÀÚÀ¯·Ó°Ô ±â·ÏÇÑ´Ù. + ÀÚ½ÅÀÌ ¿øÇÏ´Â Çü½ÄÀ¸·Î ·Î±×¸¦ ±â·ÏÇÒ ¼ö ÀÖ°í, ÆÄÀÏÀ̳ª ¿ÜºÎ + ÇÁ·Î±×·¥¿¡ Á÷Á¢ ·Î±×¸¦ º¸³¾ ¼öµµ ÀÖ´Ù. Á¶°ÇÀû ·Î±×¸¦ »ç¿ëÇϸé + ¿äûÀÇ ¼º°Ý¿¡ µû¶ó ¿äûÀ» ·Î±×¿¡ Ãß°¡Çϰųª Á¦¿ÜÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ¸ðµâÀº ¼¼°¡Áö Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù. TransferLog´Â ·Î±×ÆÄÀÏÀ» + ¸¸µé°í, LogFormatÀº + ¿øÇÏ´Â Çü½ÄÀ» Á¤ÇÏ°í, CustomLog´Â Çѹø¿¡ ·Î±×ÆÄÀÏ°ú + Çü½ÄÀ» ¸ðµÎ ÁöÁ¤ÇÑ´Ù. TransferLog¿Í + CustomLog Áö½Ã¾î¸¦ ¿©·¯¹ø »ç¿ëÇϸé + ¿äûÀ» ¿©·¯ ÆÄÀÏ¿¡ ±â·ÏÇÒ ¼ö ÀÖ´Ù.

    +
    +¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏ + +
    ·Î±× Çü½Ä ÁöÁ¤Çϱâ + +

    LogFormat°ú + CustomLog + Áö½Ã¾îÀÇ Çü½Ä ¾Æ±Ô¸ÕÆ®´Â ¹®ÀÚ¿­ÀÌ´Ù. ÀÌ ¹®ÀÚ¿­¿¡ µû¶ó ¿äûÀ» + ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. ¹®ÀÚ¿­¿¡´Â ·Î±×ÆÄÀÏ¿¡ ±×´ë·Î º¹»çµÇ´Â + ¹®ÀÚ¿Í Çà¹Ù²Þ°ú ÅÇÀ» ³ªÅ¸³»´Â CÀÇ "\n"°ú "\t" Á¦¾î¹®ÀÚ¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ·Î±×ÆÄÀÏ¿¡ µû¿ÈÇ¥³ª ¹é½½·¡½¬¸¦ ¾²·Á¸é ¾Õ¿¡ + ¹Ýµå½Ã ¹é½½·¡½¬¸¦ Àû¾îÁà¾ß ÇÑ´Ù.

    + +

    ¿äûÀÇ Æ¯Â¡Àº Çü½Ä ¹®ÀÚ¿­¿¡ "%" Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ±â·ÏÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ·Î±×ÆÄÀÏ¿¡¼­ ´ÙÀ½°ú °°ÀÌ + º¯°æµÈ´Ù.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Çü½Ä ¹®ÀÚ¿­¼³¸í
    %%ÆÛ¼¾Æ® ±âÈ£
    %...a¿ø°Ý IP-ÁÖ¼Ò
    %...A(¼­¹ö) IP-ÁÖ¼Ò
    %...BHTTP Çì´õ¸¦ Á¦¿ÜÇÑ Àü¼Û ¹ÙÀÌÆ®¼ö.
    %...bHTTP Çì´õ¸¦ Á¦¿ÜÇÑ Àü¼Û ¹ÙÀÌÆ®¼ö. CLF Çü½Ä°ú °°ÀÌ + Àü¼ÛÇÑ ³»¿ëÀÌ ¾ø´Â °æ¿ì 0 ´ë½Å '-'°¡ ³ª¿Â´Ù.
    %...{Foobar}C¼­¹ö°¡ ¼ö½ÅÇÑ ¿äû¿¡¼­ Foobar ÄíÅ°ÀÇ + ³»¿ë.
    %...D¿äûÀ» ó¸®Çϴµ¥ °É¸° ½Ã°£ (¸¶ÀÌÅ©·ÎÃÊ ´ÜÀ§).
    %...{FOOBAR}eȯ°æº¯¼ö FOOBARÀÇ ³»¿ë
    %...fÆÄÀϸí
    %...h¿ø°Ý È£½ºÆ®
    %...H¿äû ÇÁ·ÎÅäÄÝ
    %...{Foobar}i¼­¹ö°¡ ¼ö½ÅÇÑ ¿äû¿¡¼­ Foobar: + Çì´õÀÇ ³»¿ë.
    %...l(ÀÖ´Ù¸é identd°¡ Á¦°øÇÑ) ¿ø°Ý ·Î±×Àθí. + mod_ident°¡ ÀÖ°í IdentityCheck°¡ + OnÀÌ ¾Æ´Ï¸é »©±â±âÈ£¸¦ ±â·ÏÇÑ´Ù.
    %...m¿äû ¸Þ½áµå
    %...{Foobar}n´Ù¸¥ ¸ðµâÀÌ ±â·ÏÇÑ Foobar ³ëÆ®(note) + ³»¿ë.
    %...{Foobar}oÀÀ´äÀÇ Foobar: Çì´õ ³»¿ë.
    %...p¿äûÀ» ¼­ºñ½ºÇÏ´Â ¼­¹öÀÇ Á¤±Ô Æ÷Æ®
    %...P¿äûÀ» ¼­ºñ½ºÇÏ´Â ÀÚ½ÄÀÇ ÇÁ·Î¼¼½º ID.
    %...{format}P¿äûÀ» ¼­ºñ½ºÇÏ´Â ÀÚ½ÄÀÇ ÇÁ·Î¼¼½º ID ȤÀº ¾²·¹µå + ID. format¿¡´Â pid¿Í tid°¡ + °¡´ÉÇÏ´Ù. +
    %...qÁúÀǹ®ÀÚ¿­ (ÁúÀǹ®ÀÚ¿­ÀÌ ÀÖ´Ù¸é ¾Õ¿¡ ?¸¦ + ºÙÀÌ°í, ¾ø´Ù¸é ºó ¹®ÀÚ¿­)
    %...r¿äûÀÇ Ã¹¹ø° ÁÙ
    %...s»óÅÂ(status). ³»ºÎ ¸®´ÙÀÌ·º¼ÇµÈ ¿äûÀÇ °æ¿ì *¿ø·¡* + ¿äûÀÇ »óÅÂÀÌ´Ù. ÃÖÁ¾ ¿äûÀÇ »óÅ´ %...>s.
    %...tcommon log format ½Ã°£ Çü½Ä(Ç¥ÁØ ¿µ¾î Çü½Ä)ÀÇ ½Ã°£
    %...{format}tstrftime(3) Çü½Ä formatÀÇ ½Ã°£. (Áö¿ª½Ã°£ÀÏ + ¼ö ÀÖÀ½)
    %...T¿äûÀ» ó¸®Çϴµ¥ °É¸° ½Ã°£ (ÃÊ ´ÜÀ§).
    %...u¿ø°Ý »ç¿ëÀÚ (auth°¡ Á¦°øÇϸç, »óÅÂ(%s)°¡ + 401ÀÎ °æ¿ì ÀÌ»óÇÑ °ªÀ» ³ª¿Ã ¼ö ÀÖÀ½)
    %...UÁúÀǹ®ÀÚ¿­À» Á¦¿ÜÇÑ ¿äû URL °æ·Î.
    %...v¿äûÀ» ¼­ºñ½ºÇÑ ¼­¹öÀÇ Á¤±Ô ServerName.
    %...VUseCanonicalName + ¼³Á¤¿¡ µû¸¥ ¼­¹ö¸í.
    %...XÀÀ´äÀ» ¸¶ÃÆÀ»¶§ ¿¬°á »óÅÂ. + + + + + + + + + +
    X =ÀÀ´äÀ» ¸¶Ä¡±â Àü¿¡ ¿¬°áÀÌ ²÷¾îÁ³´Ù.
    + =ÀÀ´äÀ» º¸³½ÈÄ¿¡µµ ¿¬°áÀÌ »ì¾ÆÀÖ´Ù(keep alive).
    - = ÀÀ´äÀ» º¸³½ÈÄ ¿¬°áÀÌ ²÷¾îÁ³´Ù.
    + +

    (¾ÆÆÄÄ¡ 1.3 ÈÄ¹Ý ¹öÀü¿¡¼­ ÀÌ Áö½Ã¾î´Â + %...c¿´Áö¸¸, ÀüÅëÀûÀÎ ssl + %...{var}c ¹®¹ý°ú °ãÃļ­ + º¯°æÇß´Ù.)

    %...I¿äû°ú Çì´õ¸¦ Æ÷ÇÔÇÑ ¼ö½Å ¹ÙÀÌÆ®¼ö·Î 0ÀÏ ¼ö ¾ø´Ù. + À̸¦ »ç¿ëÇÏ·Á¸é mod_logio°¡ ÇÊ¿äÇÏ´Ù.
    %...OÇì´õ¸¦ Æ÷ÇÔÇÑ ¼Û½Å ¹ÙÀÌÆ®¼ö·Î 0ÀÏ ¼ö ¾ø´Ù. À̸¦ + »ç¿ëÇÏ·Á¸é mod_logio°¡ ÇÊ¿äÇÏ´Ù.
    + +

    "..."¿¡´Â (¿¹¸¦ µé¾î, + "%h %u %r %s %b") ¾Æ¹«°Íµµ ¾ø°Å³ª, Ç׸ñÀ» Æ÷ÇÔÇÒ + Á¶°ÇÀÌ ³ª¿Â´Ù (Á¶°ÇÀ» ¸¸Á·ÇÏÁö ¾ÊÀ¸¸é ÀÚ¸®¿¡ "-"¸¦ ±â·ÏÇÑ´Ù). + Á¶°ÇÀº ¾Õ¿¡ "!"¸¦ ºÙÀ̰ųª ¾ÈºÙÀÎ HTTP »óÅÂÄÚµå ¸ñ·ÏÀ¸·Î + ÀÛ¼ºÇÑ´Ù. ¿¹¸¦ µé¾î, "%400,501{User-agent}i"´Â 400 (Bad + Request) ¿À·ù¿Í 501 (Not Implemented) ¿À·ùÀ϶§¸¸ + User-agent:¸¦ ·Î±×¿¡ ³²±â°í, + "%!200,304,302{Referer}i"´Â Á¤»óÀûÀÎ »óÅ°¡ ¾Æ´Ñ + ¸ðµç ¿äû¿¡ ´ëÇØ Referer:¸¦ ·Î±×¿¡ ³²±ä´Ù.

    + +

    ¼öÁ¤ÀÚ "<"¿Í ">"´Â ³»ºÎ ¸®´ÙÀÌ·º¼ÇµÈ ¿äû¿¡¼­ °¢°¢ + óÀ½ ¿äûÀ» ¸»ÇÒÁö ¸¶Áö¸· ¿äûÀ» ¸»ÇÒÁö ¼±ÅÃÇÑ´Ù. ±âº»ÀûÀ¸·Î + %s, %U, %T, %D, %rÀº óÀ½ ¿äûÀ» º¸°í, ³ª¸ÓÁö + % Áö½Ã¾î´Â ¸¶Áö¸· ¿äûÀ» º»´Ù. ±×·¡¼­ + %>s´Â ¿äûÀÇ ¸¶Áö¸· »óÅÂ(status)¸¦ ±â·ÏÇÏ°í, + %<u´Â ÀÎÁõÀ¸·Î º¸È£ÇÏÁö ¾Ê´Â ÀÚ¿øÀ¸·Î ³»ºÎ + ¶ó´ÙÀÌ·º¼ÇµÈ °æ¿ì¿¡µµ óÀ½¿¡ ÀÎÁõÇÑ »ç¿ëÀÚ¸¦ ±â·ÏÇÑ´Ù.

    + +

    2.0.46 ÀÌÀüÀÇ httpd 2.0 ¹öÀüÀº %...r, + %...i, %...oÀÇ °á°ú ¹®ÀÚ¿­À» ±×´ë·Î + µÎ¾ú´Ù. ÀÌÀ¯´Â Common Log FormatÀÇ ¿ä±¸»çÇ×À» µû¸£±âÀ§Çؼ­¿´´Ù. + Áï, Ŭ¶óÀ̾ðÆ®°¡ Á¦¾î¹®ÀÚ¸¦ ·Î±×¿¡ Áý¾î³ÖÀ» ¼ö Àֱ⶧¹®¿¡ + ·Î±×ÆÄÀÏÀ» ±×´ë·Î ´Ù·ê ¶§´Â Á¶½ÉÇØ¾ß ÇÑ´Ù.

    + +

    º¸¾È»ó ÀÌÀ¯·Î 2.0.46ºÎÅÍ Ãâ·ÂÇÒ ¼ö ¾ø´Â ¹®ÀÚ³ª ´Ù¸¥ Ư¼ö¹®ÀÚ¸¦ + \xhh·Î Ç¥ÇöÇÑ´Ù. ¿©±â¼­ hh´Â + ÇØ´ç ¹ÙÀÌÆ®ÀÇ 16Áø¼ö Ç¥ÇöÀ» ³ªÅ¸³½´Ù. ÀÌ ±ÔÄ¢ÀÇ ¿¹¿Ü´Â ¹é½½·¡½¬¸¦ + ¾Õ¿¡ ºÙÀÌ´Â "¿Í \, ±×¸®°í C¾ð¾î + Çü½ÄÀÇ °ø¹é¹®ÀÚµé(\n, \t µî)ÀÌ´Ù.

    + +

    ÀϹÝÀûÀ¸·Î ¸¹ÀÌ »ç¿ëÇÏ´Â ·Î±× Çü½ÄÀº ´ÙÀ½°ú °°´Ù.

    + +
    +
    Common Log Format (CLF)
    +
    "%h %l %u %t \"%r\" %>s %b"
    + +
    °¡»óÈ£½ºÆ® Á¤º¸¸¦ Æ÷ÇÔÇÑ Common Log Format
    +
    "%v %h %l %u %t \"%r\" %>s %b"
    + +
    NCSA extended/combined ·Î±× Çü½Ä
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\""
    + +
    Referer ·Î±× Çü½Ä
    +
    "%{Referer}i -> %U"
    + +
    Agent (ºê¶ó¿ìÀú) ·Î±× Çü½Ä
    +
    "%{User-agent}i"
    +
    + +

    ¿äûÀ» ¼­ºñ½ºÇÏ´Â ¼­¹öÀÇ Á¤±Ô ServerName°ú ListenÀº °¢°¢ %v¿Í + %p¸¦ »ç¿ëÇÑ´Ù. ·Î±×ºÐ¼® ÇÁ·Î±×·¥ÀÌ ½ÇÁ¦·Î ¿äûÀ» + ¼­ºñ½ºÇϴ ȣ½ºÆ®¸¦ ¾Ë±âÀ§ÇØ °¡»óÈ£½ºÆ® ã±â ¾Ë°í¸®ÁòÀ» + °¡Áú ÇÊ¿ä¾øµµ·Ï ÀÌµé °ªÀº UseCanonicalName ¼³Á¤°ú ¹«°üÇÏ´Ù.

    +
    + +
    º¸¾È»ó °í·ÁÇÒ Á¡ +

    ¼­¹ö¸¦ ½ÃÀÛÇÏ´Â »ç¿ëÀÚ¿Ü¿¡ ´Ù¸¥ »ç¿ëÀÚ°¡ ·Î±×ÆÄÀÏÀ» ÀúÀåÇÏ´Â + µð·ºÅ丮¿¡ ¾²±â ±ÇÇÑÀ» °¡Áú¶§ ¿Ö º¸¾È¿¡ ¹®Á¦°¡ »ý±â´ÂÁö + º¸¾È ÆÁ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + + +CookieLog +ÄíÅ°¸¦ ·Î±×¿¡ ³²±â±âÀ§ÇØ »ç¿ëÇÒ ÆÄÀϸíÀ» ¼³Á¤ÇÑ´Ù +CookieLog filename +server configvirtual host + +ÀÌ Áö½Ã¾î´Â »ç¿ëµÇÁö ¾Ê´Â´Ù. + + +

    CookieLog Áö½Ã¾î´Â ÄíÅ°¸¦ ·Î±×¿¡ + ³²±â±âÀ§ÇØ »ç¿ëÇÒ ÆÄÀϸíÀ» ¼³Á¤ÇÑ´Ù. ÆÄÀϸíÀº ServerRoot¿¡ »ó´ë°æ·ÎÀÌ´Ù. ÀÌ + Áö½Ã¾î´Â mod_cookies¿Í ȣȯÀ» À§ÇØ Æ÷ÇÔÇßÀ»»Ó, + ½ÇÁ¦ »ç¿ëµÇÁö ¾Ê´Â´Ù.

    +
    +
    + + +CustomLog +·Î±×ÆÄÀÏ À̸§°ú Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù +CustomLog file|pipe +format|nickname +[env=[!]environment-variable] +server configvirtual host + + + +

    ¼­¹ö°¡ ¿äûÀ» ·Î±×¿¡ ³²±æ¶§ CustomLog + Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. ·Î±× Çü½ÄÀ» ÁöÁ¤ÇÏ°í, ȯ°æº¯¼ö¸¦ »ç¿ëÇÏ¿© + ¿äûÀÇ Æ¯Â¡¿¡ µû¶ó ¼±ÅÃÀûÀ¸·Î ·Î±×¸¦ ³²±æ ¼öµµ ÀÖ´Ù.

    + +

    ·Î±×¸¦ ±â·ÏÇÒ Àå¼Ò¸¦ ÁöÁ¤Çϴ ù¹ø° ¾Æ±Ô¸ÕÆ®¿¡´Â ´ÙÀ½ + µÑÁß Çϳª¸¦ »ç¿ëÇÑ´Ù.

    + +
    +
    file
    +
    ServerRoot¿¡ + »ó´ëÀûÀÎ ÆÄÀϸí.
    + +
    pipe
    +
    ÆÄÀÌÇÁ¹®ÀÚ "|"µÚ¿¡ ·Î±× Á¤º¸¸¦ Ç¥ÁØÀÔ·ÂÀ¸·Î + ¹ÞÀ» ÇÁ·Î±×·¥ °æ·Î¸¦ Àû´Â´Ù. + + º¸¾È: +

    ÇÁ·Î±×·¥À» »ç¿ëÇÑ´Ù¸é ÇÁ·Î±×·¥Àº À¥¼­¹ö¸¦ ½ÃÀÛÇÑ »ç¿ëÀÚ + ±ÇÇÑÀ¸·Î ½ÇÇàµÈ´Ù. ¼­¹ö¸¦ root·Î ½ÃÀÛÇÑ´Ù¸é ÇÁ·Î±×·¥µµ + root·Î ½ÇÇàÇϹǷΠÇÁ·Î±×·¥ÀÌ ¾ÈÀüÇÑÁö È®ÀÎÇ϶ó.

    +
    + ÁÖÀÇ +

    À¯´Ð½º°¡ ¾Æ´Ñ Ç÷¡Æû¿¡¼­ ÆÄÀÏ°æ·Î¸¦ ÀÔ·ÂÇÒ¶§ Ç÷¡ÆûÀÌ + ¹é½½·¡½¬¸¦ »ç¿ëÇÏ´õ¶óµµ ¹Ýµå½Ã ½½·¡½¬¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. + ÀϹÝÀûÀ¸·Î ¼³Á¤ÆÄÀÏ¿¡¼­´Â Ç×»ó ½½·¡½¬¸¦ »ç¿ëÇÏ´Â °ÍÀÌ + ÁÁ´Ù.

    +
    +
    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÒ ³»¿ëÀ» ÁöÁ¤ÇÑ´Ù. + Àü¿¡ LogFormatÀ¸·Î + Á¤ÀÇÇÑ nicknameÀ» »ç¿ëÇϰųª Á÷Á¢ ·Î±× Çü½Ä Àý¿¡¼­ ¼³¸íÇÑ format + ¹®ÀÚ¿­À» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¿¹¸¦ µé¾î, ´ÙÀ½ µÎ Áö½Ã¾î´Â ¶È°°Àº ÀÏÀ» ÇÑ´Ù.

    + + + # Çü½Ä º°ÄªÀ» »ç¿ëÇÑ CustomLog
    + LogFormat "%h %l %u %t \"%r\" %>s %b" common
    + CustomLog logs/access_log common
    +
    + # Á÷Á¢ Çü½Ä ¹®ÀÚ¿­À» »ç¿ëÇÑ CustomLog
    + CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b" +
    + +

    ¼¼¹ø° ¾Æ±Ô¸ÕÆ®´Â ¾ø¾îµµ µÇ¸ç, ƯÁ¤ ¼­¹ö ȯ°æº¯¼ö À¯¹«¿¡ + µû¶ó ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. ¿äû¿¡ ÁöÁ¤ÇÑ + ȯ°æº¯¼ö°¡ Á¤ÀǵÇÀÖ´Ù¸é (ȤÀº + 'env=!name'¸¦ »ç¿ëÇÑ °æ¿ì ¾ø´Ù¸é) + ¿äûÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù.

    + +

    mod_setenvif³ª mod_rewrite + ¸ðµâÀ» »ç¿ëÇÏ¿© ¿äûº°·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ + µé¾î, ¼­¹ö°¡ GIF ±×¸²¿¡ ´ëÇÑ ¸ðµç ¿äûÀ» ÁÖ¼­¹ö ·Î±×°¡ ¾Æ´Ñ + ´Ù¸¥ ·Î±×ÆÄÀÏ¿¡ ±â·ÏÇÏ·Á¸é,

    + + + SetEnvIf Request_URI \.gif$ gif-image
    + CustomLog gif-requests.log common env=gif-image
    + CustomLog nongif-requests.log common env=!gif-image +
    +
    +
    + + +LogFormat +·Î±×ÆÄÀÏ¿¡ »ç¿ëÇÒ Çü½ÄÀ» ±â¼úÇÑ´Ù +LogFormat format|nickname +[nickname] +LogFormat "%h %l %u %t \"%r\" %>s %b" +server configvirtual host + + + +

    ÀÌ Áö½Ã¾î´Â Á¢±Ù ·Î±×ÆÄÀÏÀÇ Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù.

    + +

    LogFormat Áö½Ã¾î´Â µÎ°¡Áö Çü½ÄÀ¸·Î + »ç¿ëÇÑ´Ù. ù¹ø° Çü½ÄÀº ¾Æ±Ô¸ÕÆ®¸¦ ÇÑ°³¸¸ »ç¿ëÇÏ¿© ´ÙÀ½ + TransferLog Áö½Ã¾îµéÀÌ »ç¿ëÇÒ ·Î±× + Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù. ÀÌ ¾Æ±Ô¸ÕÆ®¿¡ À§ÀÇ ·Î±× + Çü½Ä ÁöÁ¤Çϱâ Àý¿¡¼­ ¼³¸íÇÑ formatÀ» Á÷Á¢ + »ç¿ëÇϰųª, ´ÙÀ½¿¡ ¼³¸íÇÒ LogFormat + Áö½Ã¾î·Î ¹Ì¸® Á¤ÀÇÇÑ (·Î±× Çü½ÄÀ» ÁöĪÇÏ´Â) nicknameÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    LogFormat Áö½Ã¾îÀÇ µÎ¹ø° Çü½ÄÀº + format°ú nicknameÀ» ¿¬°áÇÑ´Ù. ±×·¯¸é + µÚ¿¡¼­ »ç¿ëÇÏ´Â LogFormatÀ̳ª CustomLog Áö½Ã¾î¿¡ ¹Ýº¹Çؼ­ + Çü½Ä ¹®ÀÚ¿­À» ¸ðµÎ ÀÔ·ÂÇÏ´Â ´ë½Å nicknameÀ» »ç¿ëÇÒ + ¼ö ÀÖ´Ù. º°ÄªÀ» Á¤ÀÇÇÏ´Â LogFormat + Áö½Ã¾î´Â ÀÌ ¿Ü¿¡´Â ¾Æ¹« ±â´ÉÀ» ÇÏÁö ¾Ê´Â´Ù. + Áï, º°Äª¸¸À» Á¤ÀÇÇϸç, ½ÇÁ¦·Î Çü½ÄÀ» Àû¿ëÇϰųª + Çü½ÄÀ» ±âº»°ªÀ¸·Î ¸¸µéÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î ´ÙÀ½¿¡ ³ª¿À´Â + TransferLog + Áö½Ã¾î¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù. ¶Ç, + LogFormatÀº º°ÄªÀ¸·Î ´Ù¸¥ º°ÄªÀ» + Á¤ÀÇÇÒ ¼ö ÀÖ´Ù. º°Äª À̸§¿¡´Â ÆÛ¼¾Æ® ±âÈ£(%)¸¦ + »ç¿ëÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó.

    + + ¿¹Á¦ + LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common + +
    +
    + + +TransferLog +·Î±×ÆÄÀÏ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù +TransferLog file|pipe +server configvirtual host + + + +

    ÀÌ Áö½Ã¾î´Â CustomLog Áö½Ã¾î¿Í ¾Æ±Ô¸ÕÆ®¿Í + ±â´ÉÀÌ ºñ½ÁÇÏÁö¸¸, ·Î±× Çü½ÄÀ» Á÷Á¢ ÁöÁ¤Çϰųª ¿äûÀ» Á¶°Ç¿¡ + µû¶ó ·Î±×¿¡ ³²±æ ¼ö ¾ø´Ù. ´ë½Å °¡Àå ÃÖ±Ù »ç¿ëÇÑ (º°ÄªÀ» + Á¤ÀÇÇÏÁö ¾ÊÀº) LogFormat Áö½Ã¾î°¡ ÁöÁ¤ÇÑ + ·Î±× Çü½ÄÀ» »ç¿ëÇÑ´Ù. ¹Ì¸® Çü½ÄÀ» ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é Common + Log FormatÀ» »ç¿ëÇÑ´Ù.

    + + ¿¹Á¦ + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
    + TransferLog logs/access_log +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_log_config.xml.meta b/trunk/docs/manual/mod/mod_log_config.xml.meta new file mode 100644 index 0000000000..f9817111e8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_config.xml.meta @@ -0,0 +1,13 @@ + + + + mod_log_config + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_log_forensic.html b/trunk/docs/manual/mod/mod_log_forensic.html new file mode 100644 index 0000000000..ede2670903 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.html @@ -0,0 +1,7 @@ +URI: mod_log_forensic.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_log_forensic.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_log_forensic.html.en b/trunk/docs/manual/mod/mod_log_forensic.html.en new file mode 100644 index 0000000000..6c7b635123 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.html.en @@ -0,0 +1,162 @@ + + + +mod_log_forensic - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_log_forensic

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    Description:Forensic Logging of the requests made to the server
    Status:Extension
    Module Identifier:log_forensic_module
    Source File:mod_log_forensic.c
    Compatibility:mod_unique_id is no longer required since +version 2.1
    +

    Summary

    + +

    This module provides for forensic logging of client + requests. Logging is done before and after processing a request, so the + forensic log contains two log lines for each request. + The forensic logger is very strict, which means:

    + +
      +
    • The format is fixed. You cannot modify the logging format at + runtime.
    • +
    • If it cannot write its data, the child process + exits immediately and may dump core (depending on your + CoreDumpDirectory + configuration).
    • +
    + +

    The check_forensic script, which can be found in the + distribution's support directory, may be helpful in evaluating the + forensic log output.

    +
    + +
    top
    +
    +

    Forensic Log Format

    +

    Each request is logged two times. The first time is before it's + processed further (that is, after receiving the headers). The second log + entry is written after the request processing at the same time + where normal logging occurs.

    + +

    In order to identify each request, a unique request ID is assigned. + This forensic ID can be cross logged in the normal transfer log using the + %{forensic-id}n format string. If you're using + mod_unique_id, its generated ID will be used.

    + +

    The first line logs the forensic ID, the request line and all received + headers, separated by pipe characters (|). A sample line + looks like the following (all on one line):

    + +

    + +yQtJf8CoAB4AAFNXBIEAAAAA|GET /manual/de/images/down.gif + HTTP/1.1|Host:localhost%3a8080|User-Agent:Mozilla/5.0 (X11; + U; Linux i686; en-US; rv%3a1.6) Gecko/20040216 + Firefox/0.8|Accept:image/png, etc... +

    + +

    The plus character at the beginning indicates that this is the first log + line of this request. The second line just contains a minus character and + the ID again:

    + +

    + -yQtJf8CoAB4AAFNXBIEAAAAA +

    + +

    The check_forensic script takes as its argument the name + of the logfile. It looks for those +/- ID pairs + and complains if a request was not completed.

    +
    top
    +
    +

    Security Considerations

    +

    See the security tips + document for details on why your security could be compromised + if the directory where logfiles are stored is writable by + anyone other than the user that starts the server.

    +
    +
    top
    +

    ForensicLog Directive

    + + + + + + +
    Description:Sets filename of the forensic log
    Syntax:ForensicLog filename|pipe
    Context:server config, virtual host
    Status:Extension
    Module:mod_log_forensic
    +

    The ForensicLog directive is used to + log requests to the server for forensic analysis. Each log entry + is assigned a unique ID which can be associated with the request + using the normal CustomLog + directive. mod_log_forensic creates a token called + forensic-id, which can be added to the transfer log + using the %{forensic-id}n format string.

    + +

    The argument, which specifies the location to which + the logs will be written, can take one of the following two + types of values:

    + +
    +
    filename
    +
    A filename, relative to the ServerRoot.
    + +
    pipe
    +
    The pipe character "|", followed by the path + to a program to receive the log information on its standard + input. The program name can be specified relative to the ServerRoot directive. + +

    Security:

    +

    If a program is used, then it will be run as the user who + started httpd. This will be root if the server was + started by root; be sure that the program is secure or switches to a + less privileged user.

    +
    + +

    Note

    +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_log_forensic.html.ja.euc-jp b/trunk/docs/manual/mod/mod_log_forensic.html.ja.euc-jp new file mode 100644 index 0000000000..f7b0060235 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.html.ja.euc-jp @@ -0,0 +1,163 @@ + + + +mod_log_forensic - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_log_forensic

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤ËÁ÷¤é¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î forensic ¥í¥®¥ó¥°
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:log_forensic_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_log_forensic.c
    ¸ß´¹À­:mod_unique_id ¤Ï¥Ð¡¼¥¸¥ç¥ó 2.1 ¤«¤é¤Ïɬ¿Ü¤Ç¤Ï +¤Ê¤¯¤Ê¤Ã¤¿
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¥ê¥¯¥¨¥¹¥È¤Î forensic ¥í¥®¥ó¥°¤ò + ¹Ô¤Ê¤¤¤Þ¤¹¡£¥í¥°¼ý½¸¤Ï¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤ÎÁ°¤È¸å¤Ë¹Ô¤Ê¤ï¤ì¤Þ¤¹¤Î¤Ç¡¢ + forensic ¥í¥°¤Ï³Æ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤ÆÆó¹Ô¥í¥°¼ý½¸¤·¤Þ¤¹¡£ + Forensic ¥í¥¬¡¼¤ÏÈó¾ï¤Ë¸·Ì©¤Ç¤¹¡£¤³¤ì¤Ï°Ê²¼¤Î¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹:

    + +
      +
    • ¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¸ÇÄê¤Ç¤¹¡£¼Â¹Ô»þ¤Ë¥í¥®¥ó¥°¥Õ¥©¡¼¥Þ¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤Ï + ¤Ç¤­¤Þ¤»¤ó¡£
    • +
    • ¥Ç¡¼¥¿¤ò½ñ¤±¤Ê¤¤¾ì¹ç¤Ï»Ò¥×¥í¥»¥¹¤Ï¤½¤Î¾ì¤Ç½ªÎ»¤·¡¢¤µ¤é¤Ë¥³¥¢¤ò + ¥À¥ó¥×¤¹¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (CoreDumpDirectory ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤Ë°Í¤ê¤Þ¤¹)¡£
    • +
    + +

    Forensic ¥í¥°¤Î½ÐÎϤò¸¡ºº¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ÇÛÉÛʪ¤Î support ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë check_forensic + ¥¹¥¯¥ê¥×¥È¤¬Ìò¤ËΩ¤Ä¤Ç¤·¤ç¤¦¡£

    +
    + +
    top
    +
    +

    Forensic ¥í¥°¥Õ¥©¡¼¥Þ¥Ã¥È

    +

    ³Æ¥ê¥¯¥¨¥¹¥È¤Ï2²ó¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹¡£ºÇ½é¤Ï¥ê¥¯¥¨¥¹¥È¤¬½èÍý¤µ¤ì¤ë + Á° (¤Ä¤Þ¤ê¡¢¥Ø¥Ã¥À¤ò¼õ¤±¼è¤Ã¤¿¸å) ¤Ç¤¹¡£2ÅÙÌÜ¤Î¥í¥°¤Ï + ¥ê¥¯¥¨¥¹¥È¤¬½èÍý¤µ¤ì¤¿¸å¡¢Ä̾ï¤Î¥í¥°¼ý½¸¤ÈƱ¤¸¤È¤­¤Ë + ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£

    + +

    ³Æ¥ê¥¯¥¨¥¹¥È¤ò¼±Ê̤¹¤ë¤¿¤á¤Ë¡¢¥ê¥¯¥¨¥¹¥È¤Ë¤Ï + °ì°Õ¤Ê¥ê¥¯¥¨¥¹¥È ID ¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£¤³¤Î forensic ID ¤Ï + ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó %{forensic-id}n ¤ò»È¤¦¤³¤È¤Ç + Ä̾ï¤Î transfer ¥í¥°¤Ë¥í¥°¼ý½¸¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + mod_unique_id ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤ì¤¬À¸À®¤¹¤ë + ID ¤¬»È¤ï¤ì¤Þ¤¹¡£

    + +

    ºÇ½é¤Î¹Ô¤Ï forensic ID¡¢¥ê¥¯¥¨¥¹¥È¹Ô¤È¼õ¤±¼è¤Ã¤¿¤¹¤Ù¤Æ¤Î¥Ø¥Ã¥À¤ò + ¥Ñ¥¤¥×ʸ»ú (|) ¤ÇʬΥ¤·¤Æ¥í¥°¼ý½¸¤·¤Þ¤¹¡£ + Î㤨¤Ð°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹ (¼ÂºÝ¤Ï¤¹¤Ù¤ÆƱ¤¸¹Ô¤Ë¤Ê¤ê¤Þ¤¹):

    + +

    + +yQtJf8CoAB4AAFNXBIEAAAAA|GET /manual/de/images/down.gif + HTTP/1.1|Host:localhost%3a8080|User-Agent:Mozilla/5.0 (X11; + U; Linux i686; en-US; rv%3a1.6) Gecko/20040216 + Firefox/0.8|Accept:image/png, etc... +

    + +

    ºÇ½é¤Î¥×¥é¥¹Ê¸»ú¤¬¤³¤Î¥í¥°¤ÏºÇ½é¤Î¥í¥°¤Ç¤¢¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + ÆóÈÖÌܤιԤϥޥ¤¥Ê¥¹Ê¸»ú¤È ID ¤Î¤ß¤Ç¤¹:

    + +

    + -yQtJf8CoAB4AAFNXBIEAAAAA +

    + +

    check_forensic ¥¹¥¯¥ê¥×¥È¤Ï°ú¿ô¤È¤·¤Æ¥í¥°¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò + ¼è¤ê¤Þ¤¹¡£+/- ¤Î ID ¤ÎÁȤòÄ´¤Ù¡¢´°Î»¤·¤Æ¤¤¤Ê¤¤ + ¥ê¥¯¥¨¥¹¥È¤¬¤¢¤ë¾ì¹ç¤Ï·Ù¹ð¤òȯ¤·¤Þ¤¹¡£

    +
    top
    +
    +

    ¥»¥­¥å¥ê¥Æ¥£¤ÎÌäÂê

    +

    ¥í¥°¥Õ¥¡¥¤¥ë¤¬Êݸ¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤¬¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿¥æ¡¼¥¶ + °Ê³°¤Ç½ñ¤­¹þ¤ß²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¥»¥­¥å¥ê¥Æ¥£¤¬Çˤé¤ì¤ë²ÄǽÀ­¤¬ + ¤¢¤ë¤³¤È¤Ë¤Ä¤¤¤Æ¤Î¾ÜºÙ¤Ï¥»¥­¥å¥ê¥Æ¥£¤Î¤³¤Ä¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    top
    +

    ForensicLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Forensic ¥í¥°¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    ¹½Ê¸:ForensicLog filename|pipe
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_log_forensic
    +

    ForensicLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï forensic ²òÀϤΤ¿¤á¤Î + ¥µ¡¼¥Ð¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¥í¥°¼ý½¸¤Ë»È¤¤¤Þ¤¹¡£ + ³Æ¥í¥°¥¨¥ó¥È¥ê¤Ë¤Ï¡¢ÉáÄ̤ΠCustomLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¥ê¥¯¥¨¥¹¥È¤È´ØÏ¢ÉÕ¤±¤ë¤³¤È¤Î + ¤Ç¤­¤ë + °ì°Õ¤Ê ID ¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£mod_log_forensic ¤Ï + forensic-id ¤È¤¤¤¦¥È¡¼¥¯¥ó¤òºîÀ®¤·¡¢¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó + %{forensic-id}n ¤ò»È¤¦¤³¤È¤Ç¤½¤Î¥È¡¼¥¯¥ó¤ò transfer ¥í¥°¤Ë + Äɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    °ú¿ô¤Ï¥í¥°¤¬½ñ¤­½Ð¤µ¤ì¤ë°ÌÃÖ¤ò»ØÄꤷ¡¢°Ê²¼¤Î 2¼ïÎà¤ÎÃͤΤɤÁ¤é¤«¤ò + ¼è¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    filename
    +
    ServerRoot ¤«¤é¤Î + ÁêÂÐ¥Õ¥¡¥¤¥ë̾
    + +
    pipe
    +
    ¥Ñ¥¤¥×ʸ»ú "|" ¤È¡¢¤½¤Î¸å¤Ë¥í¥°¾ðÊó¤òɸ½àÆþÎϤ«¤é + ¼õ¤±¼è¤ë¥×¥í¥°¥é¥à¡£¥×¥í¥°¥é¥à̾¤Ï ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ¤â + »ØÄê¤Ç¤­¤Þ¤¹¡£ + +

    ¥»¥­¥å¥ê¥Æ¥£:

    +

    ¥×¥í¥°¥é¥à¤ò»È¤¦¾ì¹ç¡¢¤½¤Î¥×¥í¥°¥é¥à¤Ï httpd ¤òµ¯Æ°¤·¤¿¥æ¡¼¥¶¤Ç + ¼Â¹Ô¤µ¤ì¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢¥µ¡¼¥Ð¤¬ root ¤Ç¼Â¹Ô¤µ¤ì¤¿¾ì¹ç¤Ï root ¤Ç + ¼Â¹Ô¤µ¤ì¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥×¥í¥°¥é¥à¤¬°ÂÁ´¤Ç¤¢¤ë¤«¡¢¤è¤ê¸¢¸Â¤Î¾¯¤Ê¤¤ + ¥æ¡¼¥¶¤ËÀÚ¤êÂؤ¨¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Î¤«¤á¤Æ¤¯¤À¤µ¤¤¡£

    +
    + +

    Ãí

    +

    Unix °Ê³°¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¥Õ¥¡¥¤¥ë̾¤òÆþÎϤ¹¤ë¤È¤­¤Ï¡¢ + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤¬¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Î»ÈÍѤòµö²Ä¤·¤Æ¤¤¤ë¾ì¹ç¤Ç¤â¡¢ + ¥¹¥é¥Ã¥·¥å¤Î¤ß¤¬»È¤ï¤ì¤ë¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£ + ÉáÄ̤ÏÀßÄê¥Õ¥¡¥¤¥ë¤¹¤Ù¤Æ¤Ë¤ª¤¤¤Æ¡¢¥¹¥é¥Ã¥·¥å¤ÎÊý¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë + ¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_log_forensic.xml b/trunk/docs/manual/mod/mod_log_forensic.xml new file mode 100644 index 0000000000..c7fb2e0d7d --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.xml @@ -0,0 +1,146 @@ + + + + + + + + + +mod_log_forensic +Forensic Logging of the requests made to the server +Extension +mod_log_forensic.c +log_forensic_module +mod_unique_id is no longer required since +version 2.1 + + +

    This module provides for forensic logging of client + requests. Logging is done before and after processing a request, so the + forensic log contains two log lines for each request. + The forensic logger is very strict, which means:

    + +
      +
    • The format is fixed. You cannot modify the logging format at + runtime.
    • +
    • If it cannot write its data, the child process + exits immediately and may dump core (depending on your + CoreDumpDirectory + configuration).
    • +
    + +

    The check_forensic script, which can be found in the + distribution's support directory, may be helpful in evaluating the + forensic log output.

    +
    +Apache Log Files +mod_log_config + +
    Forensic Log Format +

    Each request is logged two times. The first time is before it's + processed further (that is, after receiving the headers). The second log + entry is written after the request processing at the same time + where normal logging occurs.

    + +

    In order to identify each request, a unique request ID is assigned. + This forensic ID can be cross logged in the normal transfer log using the + %{forensic-id}n format string. If you're using + mod_unique_id, its generated ID will be used.

    + +

    The first line logs the forensic ID, the request line and all received + headers, separated by pipe characters (|). A sample line + looks like the following (all on one line):

    + + + +yQtJf8CoAB4AAFNXBIEAAAAA|GET /manual/de/images/down.gif + HTTP/1.1|Host:localhost%3a8080|User-Agent:Mozilla/5.0 (X11; + U; Linux i686; en-US; rv%3a1.6) Gecko/20040216 + Firefox/0.8|Accept:image/png, etc... + + +

    The plus character at the beginning indicates that this is the first log + line of this request. The second line just contains a minus character and + the ID again:

    + + + -yQtJf8CoAB4AAFNXBIEAAAAA + + +

    The check_forensic script takes as its argument the name + of the logfile. It looks for those +/- ID pairs + and complains if a request was not completed.

    +
    + +
    Security Considerations +

    See the security tips + document for details on why your security could be compromised + if the directory where logfiles are stored is writable by + anyone other than the user that starts the server.

    +
    + + +ForensicLog +Sets filename of the forensic log +ForensicLog filename|pipe +server configvirtual host + + + +

    The ForensicLog directive is used to + log requests to the server for forensic analysis. Each log entry + is assigned a unique ID which can be associated with the request + using the normal CustomLog + directive. mod_log_forensic creates a token called + forensic-id, which can be added to the transfer log + using the %{forensic-id}n format string.

    + +

    The argument, which specifies the location to which + the logs will be written, can take one of the following two + types of values:

    + +
    +
    filename
    +
    A filename, relative to the ServerRoot.
    + +
    pipe
    +
    The pipe character "|", followed by the path + to a program to receive the log information on its standard + input. The program name can be specified relative to the ServerRoot directive. + + Security: +

    If a program is used, then it will be run as the user who + started httpd. This will be root if the server was + started by root; be sure that the program is secure or switches to a + less privileged user.

    +
    + + Note +

    When entering a file path on non-Unix platforms, care should be taken + to make sure that only forward slashed are used even though the platform + may allow the use of back slashes. In general it is a good idea to always + use forward slashes throughout the configuration files.

    +
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_log_forensic.xml.ja b/trunk/docs/manual/mod/mod_log_forensic.xml.ja new file mode 100644 index 0000000000..acf0a59091 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.xml.ja @@ -0,0 +1,148 @@ + + + + + + + + + +mod_log_forensic +$B%5!<%P$KAw$i$l$?%j%/%(%9%H$N(B forensic $B%m%.%s%0(B +Extension +mod_log_forensic.c +log_forensic_module +mod_unique_id $B$O%P!<%8%g%s(B 2.1 $B$+$i$OI,?\$G$O(B +$B$J$/$J$C$?(B + + +

    $B$3$N%b%8%e!<%k$O%/%i%$%"%s%H%j%/%(%9%H$N(B forensic $B%m%.%s%0$r(B + $B9T$J$$$^$9!#%m%0<}=8$O%j%/%(%9%H$N=hM}$NA0$H8e$K9T$J$o$l$^$9$N$G!"(B + forensic $B%m%0$O3F%j%/%(%9%H$KBP$7$FFs9T%m%0<}=8$7$^$9!#(B + Forensic $B%m%,!<$OHs>o$K87L)$G$9!#$3$l$O0J2<$N$3$H$r0UL#$7$^$9(B:

    + +
      +
    • $B%U%)!<%^%C%H$O8GDj$G$9!# +
    • $B%G!<%?$r=q$1$J$$>l9g$O;R%W%m%;%9$O$=$N>l$G=*N;$7!"$5$i$K%3%"$r(B + $B%@%s%W$9$k$+$b$7$l$^$;$s(B (CoreDumpDirectory $B%G%#%l%/%F%#%V$N@_Dj$K0M$j$^$9(B)$B!#(B
    • +
    + +

    Forensic $B%m%0$N=PNO$r8!::$9$k$?$a$K$O!"(B + $BG[I[J*$N(B support $B%G%#%l%/%H%j$K$"$k(B check_forensic + $B%9%/%j%W%H$,Lr$KN)$D$G$7$g$&!#(B

    +
    +Apache $B%m%0%U%!%$%k(B +mod_log_config + +
    Forensic $B%m%0%U%)!<%^%C%H(B +

    $B3F%j%/%(%9%H$O(B2$B2s%m%0<}=8$5$l$^$9!#:G=i$O%j%/%(%9%H$,=hM}$5$l$k(B + $BA0(B ($B$D$^$j!"%X%C%@$r$B8e(B$B!"DL>o$N%m%0<}=8$HF1$8$H$-$K(B + $B9T$J$o$l$^$9!#(B

    + +

    $B3F%j%/%(%9%H$r<1JL$9$k$?$a$K!"%j%/%(%9%H$K$O(B + $B0l0U$J%j%/%(%9%H(B ID $B$,3d$jEv$F$i$l$^$9!#$3$N(B forensic ID $B$O(B + $B%U%)!<%^%C%HJ8;zNs(B %{forensic-id}n $B$r;H$&$3$H$G(B + $BDL>o$N(B transfer $B%m%0$K%m%0<}=8$9$k$3$H$b$G$-$^$9!#(B + mod_unique_id $B$r;H$C$F$$$k>l9g$O!"$=$l$,@8@.$9$k(B + ID $B$,;H$o$l$^$9!#(B

    + +

    $B:G=i$N9T$O(B forensic ID$B!"%j%/%(%9%H9T$H|) $B$GJ,N%$7$F%m%0<}=8$7$^$9!#(B + $BNc$($P0J2<$N$h$&$K$J$j$^$9(B ($B + + + +yQtJf8CoAB4AAFNXBIEAAAAA|GET /manual/de/images/down.gif + HTTP/1.1|Host:localhost%3a8080|User-Agent:Mozilla/5.0 (X11; + U; Linux i686; en-US; rv%3a1.6) Gecko/20040216 + Firefox/0.8|Accept:image/png, etc... + + +

    $B:G=i$N%W%i%9J8;z$,$3$N%m%0$O:G=i$N%m%0$G$"$k$3$H$r<($7$^$9!#(B + $BFsHVL\$N9T$O%^%$%J%9J8;z$H(B ID $B$N$_$G$9(B:

    + + + -yQtJf8CoAB4AAFNXBIEAAAAA + + +

    check_forensic $B%9%/%j%W%H$O0z?t$H$7$F%m%0%U%!%$%k$NL>A0$r(B + $B+/- $B$N(B ID $B$NAH$rD4$Y!"40N;$7$F$$$J$$(B + $B%j%/%(%9%H$,$"$k>l9g$O7Y9p$rH/$7$^$9!#(B

    +
    + +
    $B%;%-%e%j%F%#$NLdBj(B +

    $B%m%0%U%!%$%k$,J]B8$5$l$k%G%#%l%/%H%j$,%5!<%P$r5/F0$7$?%f!<%6(B + $B0J30$G=q$-9~$_2DG=$K$J$C$F$$$k$H$-$K%;%-%e%j%F%#$,GK$i$l$k2DG=@-$,(B + $B$"$k$3$H$K$D$$$F$N>\:Y$O(B$B%;%-%e%j%F%#$N$3$D(B$B$r(B + $B;2>H$7$F$/$@$5$$!#(B

    +
    + + +ForensicLog +Forensic $B%m%0$N%U%!%$%kL>$r@_Dj$9$k(B +ForensicLog filename|pipe +server configvirtual host + + + +

    ForensicLog $B%G%#%l%/%F%#%V$O(B forensic $B2r@O$N$?$a$N(B + $B%5!<%P$X$N%j%/%(%9%H$r%m%0<}=8$K;H$$$^$9!#(B + $B3F%m%0%(%s%H%j$K$O!"IaDL$N(B CustomLog $B%G%#%l%/%F%#%V$r;H$C$F%j%/%(%9%H$H4XO"IU$1$k$3$H$N(B + $B$G$-$k(B + $B0l0U$J(B ID $B$,3d$jEv$F$i$l$^$9!#(Bmod_log_forensic $B$O(B + forensic-id $B$H$$$&%H!<%/%s$r:n@.$7!"%U%)!<%^%C%HJ8;zNs(B + %{forensic-id}n $B$r;H$&$3$H$G$=$N%H!<%/%s$r(B transfer $B%m%0$K(B + $BDI2C$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B0z?t$O%m%0$,=q$-=P$5$l$k0LCV$r;XDj$7!"0J2<$N(B 2$B + +

    +
    filename
    +
    ServerRoot $B$+$i$N(B + $BAjBP%U%!%$%kL>(B
    + +
    pipe
    +
    $B%Q%$%WJ8;z(B "|" $B$H!"$=$N8e$K%m%0>pJs$rI8=`F~NO$+$i(B + $B$O(B ServerRoot $B$+$i$NAjBP%Q%9$H$7$F$b(B + $B;XDj$G$-$^$9!#(B + + $B%;%-%e%j%F%#(B: +

    $B%W%m%0%i%`$r;H$&>l9g!"$=$N%W%m%0%i%`$O(B httpd $B$r5/F0$7$?%f!<%6$G(B + $Bl9g$O(B root $B$G(B + $B/$J$$(B + $B%f!<%6$K@Z$jBX$($k$h$&$K$J$C$F$$$k$3$H$r3N$+$a$F$/$@$5$$!#(B

    +
    + + $BCm(B +

    Unix $B0J30$N%W%i%C%H%U%)!<%`$G%U%!%$%kL>$rF~NO$9$k$H$-$O!"(B + $B%W%i%C%H%U%)!<%`$,%P%C%/%9%i%C%7%e$N;HMQ$r5v2D$7$F$$$k>l9g$G$b!"(B + $B%9%i%C%7%e$N$_$,;H$o$l$k$h$&$K5$$r$D$1$F$/$@$5$$!#(B + $BIaDL$O@_Dj%U%!%$%k$9$Y$F$K$*$$$F!"%9%i%C%7%e$NJ}$r;HMQ$9$k$h$&$K(B + $B$7$F$/$@$5$$!#(B

    +
    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_log_forensic.xml.meta b/trunk/docs/manual/mod/mod_log_forensic.xml.meta new file mode 100644 index 0000000000..37fed313b3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_log_forensic.xml.meta @@ -0,0 +1,12 @@ + + + + mod_log_forensic + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_logio.html b/trunk/docs/manual/mod/mod_logio.html new file mode 100644 index 0000000000..225d49bf58 --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.html @@ -0,0 +1,11 @@ +URI: mod_logio.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_logio.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_logio.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_logio.html.en b/trunk/docs/manual/mod/mod_logio.html.en new file mode 100644 index 0000000000..d075f2b829 --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.html.en @@ -0,0 +1,91 @@ + + + +mod_logio - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_logio

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Logging of input and output bytes per request
    Status:Extension
    Module Identifier:logio_module
    Source File:mod_logio.c
    +

    Summary

    + + +

    This module provides the logging of input and output number of + bytes received/sent per request. The numbers reflect the actual bytes + as received on the network, which then takes into account the + headers and bodies of requests and responses. The counting is done + before SSL/TLS on input and after SSL/TLS on output, so the numbers + will correctly reflect any changes made by encryption.

    + +

    This module requires mod_log_config.

    + +
    +

    Directives

    +

    This module provides no + directives.

    +

    Topics

    +

    See also

    +
    +
    top
    +
    +

    Custom Log Formats

    + + +

    This modules adds two new logging directives. The characteristics of the + request itself are logged by placing "%" directives in + the format string, which are replaced in the log file by the values as + follows:

    + + + + + + + +
    Format StringDescription
    %...IBytes received, including request and headers, cannot be + zero.
    %...OBytes sent, including headers, cannot be zero.
    + +

    Usually, the functionality is used like this:

    + +
    +
    Combined I/O log format:
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    +
    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_logio.html.ja.euc-jp b/trunk/docs/manual/mod/mod_logio.html.ja.euc-jp new file mode 100644 index 0000000000..13ac519ff5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.html.ja.euc-jp @@ -0,0 +1,91 @@ + + + +mod_logio - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_logio

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥ÈËè¤ËÆþÎϥХ¤¥È¿ô¤È½ÐÎϥХ¤¥È¿ô¤È¤ò¥í¥®¥ó¥°
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:logio_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_logio.c
    +

    ³µÍ×

    + + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥ê¥¯¥¨¥¹¥È¤´¤È¤Ë¼õ¤±¼è¤Ã¤¿¥Ð¥¤¥È¿ô¤È + Á÷¿®¤·¤¿¥Ð¥¤¥È¿ô¤Î¥í¥®¥ó¥°¤ò¹Ô¤Ê¤¦µ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£ + µ­Ï¿¤µ¤ì¤ë¿ô»ú¤Ï¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤È¥ì¥¹¥Ý¥ó¥¹¤ÎËÜÂΤò + È¿±Ç¤·¤¿¡¢¼ÂºÝ¤Ë¥Í¥Ã¥È¥ï¡¼¥¯¤Ç¼õ¤±¼è¤Ã¤¿¥Ð¥¤¥ÈÃͤǤ¹¡£ + ÆþÎÏ¤Ç¤Ï SSL/TLS ¤ÎÁ°¤Ë¡¢½ÐÎÏ¤Ç¤Ï SSL/TLS ¤Î¸å¤Ë¿ô¤¨¤ë¤Î¤Ç¡¢ + ¿ô»ú¤Ï°Å¹æ¤Ë¤è¤ëÊѲ½¤âÀµ¤·¤¯È¿±Ç¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Î»ÈÍÑ¤Ë¤Ï mod_log_config ¥â¥¸¥å¡¼¥ë¤¬ + ɬÍפǤ¹¡£

    + +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    +

    ¥È¥Ô¥Ã¥¯

    +

    »²¾È

    +
    +
    top
    +
    +

    ¥«¥¹¥¿¥à¥í¥°½ñ¼°

    + + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¿·¤·¤¤¥í¥®¥ó¥°Íѥǥ£¥ì¥¯¥Æ¥£¥Ö¤ò²Ã¤¨¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¼«¿È¤ÎÆÃħ¤Ï¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë¡¢°Ê²¼¤ÎÍͤËÃÖ´¹¤µ¤ì¤ë + "%" ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + Æþ¤ì¤ë¤³¤È¤Ç¥í¥°¼ý½¸¤µ¤ì¤Þ¤¹:

    + + + + + + + +
    ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎóÀâÌÀ
    %...I¥ê¥¯¥¨¥¹¥È¤È¥Ø¥Ã¥À¤ò´Þ¤à¡¢¼õ¤±¼è¤Ã¤¿¥Ð¥¤¥È¿ô¡£ + 0 ¤Ë¤Ï¤Ê¤é¤Ê¤¤¡£
    %...O¥Ø¥Ã¥À¤ò´Þ¤à¡¢Á÷¿®¤·¤¿¥Ð¥¤¥È¿ô¡£0 ¤Ë¤Ï¤Ê¤é¤Ê¤¤¡£
    + +

    Ä̾¤³¤Îµ¡Ç½¤Ï°Ê²¼¤ÎÍͤ˻ÈÍѤµ¤ì¤Þ¤¹:

    + +
    +
    ·ë¹ç I/O ¥í¥°½ñ¼°:
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    +
    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_logio.html.ko.euc-kr b/trunk/docs/manual/mod/mod_logio.html.ko.euc-kr new file mode 100644 index 0000000000..1282ae7128 --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.html.ko.euc-kr @@ -0,0 +1,92 @@ + + + +mod_logio - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_logio

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:¿äû´ç ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·Ï
    »óÅÂ:Extension
    ¸ðµâ¸í:logio_module
    ¼Ò½ºÆÄÀÏ:mod_logio.c
    +

    ¿ä¾à

    + + +

    ÀÌ ¸ðµâÀº ¿äû´ç ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·ÏÇÑ´Ù. ¼ýÀÚ´Â + ³×Æ®¿÷¿¡¼­ ½ÇÁ¦·Î ÁÖ°í¹ÞÀº ¹ÙÀÌÆ®¼ö¸¦ ³ªÅ¸³»¸ç, ¿äû°ú ÀÀ´äÀÇ + Çì´õ¿Í ³»¿ëÀ» Æ÷ÇÔÇÑ´Ù. °³¼ö´Â ÀÔ·ÂÀÇ °æ¿ì SSL/TLS ÀÌÀü¿¡, + Ãâ·ÂÀÇ °æ¿ì SSL/TLS ÀÌÈÄ¿¡ ¼¼±â¶§¹®¿¡ ¾ÏȣȭÀÇ °á°úµµ + ¿Ã¹Ù·Î ¹Ý¿µµÈ´Ù.

    + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é mod_log_configÀÌ + ÇÊ¿äÇÏ´Ù.

    + +
    +

    Áö½Ã¾îµé

    +

    ÀÌ ¸ðµâ¿¡´Â Áö½Ã¾î°¡ ¾ø½À´Ï´Ù.

    +

    ÁÖÁ¦

    +

    Âü°í

    +
    +
    top
    +
    +

    »ç¿ëÀÚÁ¤ÀÇ ·Î±× Çü½Ä

    + + +

    ÀÌ ¸ðµâÀº µÎ°¡Áö »õ·Î¿î ·Î±×Áö½Ã¾î¸¦ Ãß°¡ÇÑ´Ù. ¿äûÀÚüÀÇ + Ư¼ºÀº Çü½Ä¹®ÀÚ¿­¿¡ "%" Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ±â·ÏÇÑ´Ù. + Áö½Ã¾î´Â ·Î±×ÆÄÀÏ¿¡ ´ÙÀ½°ú °°Àº °ªÀ» ±â·ÏÇÑ´Ù:

    + + + + + + + +
    Çü½Ä¹®ÀÚ¿­¼³¸í
    %...I¿äû°ú Çì´õ¸¦ Æ÷ÇÔÇÏ¿© ¹ÞÀº ¹ÙÀÌÆ®¼ö. 0ÀÏ ¼ö ¾ø´Ù.
    %...OÇì´õ¸¦ Æ÷ÇÔÇÏ¿© º¸³½ ¹ÙÀÌÆ®¼ö. 0ÀÏ ¼ö ¾ø´Ù.
    + +

    º¸Åë ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù:

    + +
    + +
    °áÇÕµÈ ÀÔÃâ·Â ·Î±× Çü½Ä:
    + +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    + +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_logio.xml b/trunk/docs/manual/mod/mod_logio.xml new file mode 100644 index 0000000000..17dee1da71 --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.xml @@ -0,0 +1,76 @@ + + + + + + + + + +mod_logio +Logging of input and output bytes per request +Extension +mod_logio.c +logio_module + + + +

    This module provides the logging of input and output number of + bytes received/sent per request. The numbers reflect the actual bytes + as received on the network, which then takes into account the + headers and bodies of requests and responses. The counting is done + before SSL/TLS on input and after SSL/TLS on output, so the numbers + will correctly reflect any changes made by encryption.

    + +

    This module requires mod_log_config.

    + +
    + +mod_log_config +Apache Log Files + +
    +Custom Log Formats + +

    This modules adds two new logging directives. The characteristics of the + request itself are logged by placing "%" directives in + the format string, which are replaced in the log file by the values as + follows:

    + + + + + + + + + + +
    Format StringDescription
    %...IBytes received, including request and headers, cannot be + zero.
    %...OBytes sent, including headers, cannot be zero.
    + +

    Usually, the functionality is used like this:

    + +
    +
    Combined I/O log format:
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_logio.xml.ja b/trunk/docs/manual/mod/mod_logio.xml.ja new file mode 100644 index 0000000000..2d4700e0ce --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.xml.ja @@ -0,0 +1,77 @@ + + + + + + + + + +mod_logio +$B%j%/%(%9%HKh$KF~NO%P%$%H?t$H=PNO%P%$%H?t$H$r%m%.%s%0(B +Extension +mod_logio.c +logio_module + + + +

    $B$3$N%b%8%e!<%k$O%j%/%(%9%H$4$H$K + +

    $B$3$N%b%8%e!<%k$N;HMQ$K$O(B mod_log_config $B%b%8%e!<%k$,(B + $BI,MW$G$9!#(B

    + +
    + +mod_log_config +Apache $B%m%0%U%!%$%k(B + +
    +$B%+%9%?%`%m%0=q<0(B + +

    $B$3$N%b%8%e!<%k$O?7$7$$%m%.%s%0MQ%G%#%l%/%F%#%V$r2C$($^$9!#(B + $B%j%/%(%9%H<+?H$NFCD'$O%U%)!<%^%C%HJ8;zNs$K!"0J2<$NMM$KCV49$5$l$k(B + "%" $B%G%#%l%/%F%#%V$r(B + $BF~$l$k$3$H$G%m%0<}=8$5$l$^$9(B:

    + + + + + + + + + + +
    $B%U%)!<%^%C%HJ8;zNs(B$B@bL@(B
    %...I$B%j%/%(%9%H$H%X%C%@$r4^$`!"
    %...O$B%X%C%@$r4^$`!"Aw?.$7$?%P%$%H?t!#(B0 $B$K$O$J$i$J$$!#(B
    + +

    $BDL>o!"$3$N5!G=$O0J2<$NMM$K;HMQ$5$l$^$9(B:

    + +
    +
    $B7k9g(B I/O $B%m%0=q<0(B:
    +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_logio.xml.ko b/trunk/docs/manual/mod/mod_logio.xml.ko new file mode 100644 index 0000000000..bd7842819e --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.xml.ko @@ -0,0 +1,78 @@ + + + + + + + + + +mod_logio +¿äû´ç ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·Ï +Extension +mod_logio.c +logio_module + + + +

    ÀÌ ¸ðµâÀº ¿äû´ç ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·ÏÇÑ´Ù. ¼ýÀÚ´Â + ³×Æ®¿÷¿¡¼­ ½ÇÁ¦·Î ÁÖ°í¹ÞÀº ¹ÙÀÌÆ®¼ö¸¦ ³ªÅ¸³»¸ç, ¿äû°ú ÀÀ´äÀÇ + Çì´õ¿Í ³»¿ëÀ» Æ÷ÇÔÇÑ´Ù. °³¼ö´Â ÀÔ·ÂÀÇ °æ¿ì SSL/TLS ÀÌÀü¿¡, + Ãâ·ÂÀÇ °æ¿ì SSL/TLS ÀÌÈÄ¿¡ ¼¼±â¶§¹®¿¡ ¾ÏȣȭÀÇ °á°úµµ + ¿Ã¹Ù·Î ¹Ý¿µµÈ´Ù.

    + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é mod_log_configÀÌ + ÇÊ¿äÇÏ´Ù.

    + +
    + +mod_log_config +¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏ + +
    +»ç¿ëÀÚÁ¤ÀÇ ·Î±× Çü½Ä + +

    ÀÌ ¸ðµâÀº µÎ°¡Áö »õ·Î¿î ·Î±×Áö½Ã¾î¸¦ Ãß°¡ÇÑ´Ù. ¿äûÀÚüÀÇ + Ư¼ºÀº Çü½Ä¹®ÀÚ¿­¿¡ "%" Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ±â·ÏÇÑ´Ù. + Áö½Ã¾î´Â ·Î±×ÆÄÀÏ¿¡ ´ÙÀ½°ú °°Àº °ªÀ» ±â·ÏÇÑ´Ù:

    + + + + + + + + + + +
    Çü½Ä¹®ÀÚ¿­¼³¸í
    %...I¿äû°ú Çì´õ¸¦ Æ÷ÇÔÇÏ¿© ¹ÞÀº ¹ÙÀÌÆ®¼ö. 0ÀÏ ¼ö ¾ø´Ù.
    %...OÇì´õ¸¦ Æ÷ÇÔÇÏ¿© º¸³½ ¹ÙÀÌÆ®¼ö. 0ÀÏ ¼ö ¾ø´Ù.
    + +

    º¸Åë ´ÙÀ½°ú °°ÀÌ »ç¿ëÇÑ´Ù:

    + +
    + +
    °áÇÕµÈ ÀÔÃâ·Â ·Î±× Çü½Ä:
    + +
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
    + +
    + +
    + +
    diff --git a/trunk/docs/manual/mod/mod_logio.xml.meta b/trunk/docs/manual/mod/mod_logio.xml.meta new file mode 100644 index 0000000000..ad1bd713ac --- /dev/null +++ b/trunk/docs/manual/mod/mod_logio.xml.meta @@ -0,0 +1,13 @@ + + + + mod_logio + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_mem_cache.html b/trunk/docs/manual/mod/mod_mem_cache.html new file mode 100644 index 0000000000..65ba497832 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.html @@ -0,0 +1,11 @@ +URI: mod_mem_cache.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_mem_cache.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_mem_cache.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_mem_cache.html.en b/trunk/docs/manual/mod/mod_mem_cache.html.en new file mode 100644 index 0000000000..12d5b36ec3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.html.en @@ -0,0 +1,236 @@ + + + +mod_mem_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_mem_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Content cache keyed to URIs
    Status:Extension
    Module Identifier:mem_cache_module
    Source File:mod_mem_cache.c
    +

    Summary

    + +

    This module requires the service of mod_cache. It acts as a support module for mod_cache and provides a memory based storage manager. + mod_mem_cache can be configured to operate in two + modes: caching open file descriptors or caching objects in heap storage. + mod_mem_cache is most useful when used to cache locally + generated content or to cache backend server content for mod_proxy configured for ProxyPass (aka reverse proxy).

    + +

    Content is stored in and retrieved from the cache using URI based + keys. Content with access protection is not cached.

    +
    + + +
    top
    +

    MCacheMaxObjectCount Directive

    + + + + + + + +
    Description:The maximum number of objects allowed to be placed in the +cache
    Syntax:MCacheMaxObjectCount value
    Default:MCacheMaxObjectCount 1009
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheMaxObjectCount directive sets the + maximum number of objects to be cached. The value is used to create the + open hash table. If a new object needs to be inserted in the cache and + the maximum number of objects has been reached, an object will be + removed to allow the new object to be cached. The object to be removed + is selected using the algorithm specified by MCacheRemovalAlgorithm.

    + +

    Example

    + MCacheMaxObjectCount 13001 +

    + +
    +
    top
    +

    MCacheMaxObjectSize Directive

    + + + + + + + +
    Description:The maximum size (in bytes) of a document allowed in the +cache
    Syntax:MCacheMaxObjectSize bytes
    Default:MCacheMaxObjectSize 10000
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheMaxObjectSize directive sets the + maximum allowable size, in bytes, of a document for it to be considered + cacheable.

    + +

    Example

    + MCacheMaxObjectSize 6400000 +

    + +

    Note

    +

    The value of MCacheMaxObjectSize must be + greater than the value specified by the MCacheMinObjectSize directive.

    +
    + +
    +
    top
    +

    MCacheMaxStreamingBuffer Directive

    + + + + + + + +
    Description:Maximum amount of a streamed response to buffer in memory +before declaring the response uncacheable
    Syntax:MCacheMaxStreamingBuffer size_in_bytes
    Default:MCacheMaxStreamingBuffer the smaller of 100000 or MCacheMaxObjectSize
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheMaxStreamingBuffer directive + specifies the maximum number of bytes of a streamed response to + buffer before deciding that the response is too big to cache. + A streamed response is one in which the entire content is not + immediately available and in which the Content-Length + may not be known. Sources of streaming responses include proxied + responses and the output of CGI scripts. By default, a streamed + response will not be cached unless it has a + Content-Length header. The reason for this is to + avoid using a large amount of memory to buffer a partial response + that might end up being too large to fit in the cache. + The MCacheMaxStreamingBuffer directive allows + buffering of streamed responses that don't contain a + Content-Length up to the specified maximum amount of + space. If the maximum buffer space is reached, the buffered + content is discarded and the attempt to cache is abandoned.

    + +

    Note:

    +

    Using a nonzero value for MCacheMaxStreamingBuffer + will not delay the transmission of the response to the client. + As soon as mod_mem_cache copies a block of streamed + content into a buffer, it sends the block on to the next output + filter for delivery to the client.

    +
    + +

    + # Enable caching of streamed responses up to 64KB:
    + MCacheMaxStreamingBuffer 65536 +

    + +
    +
    top
    +

    MCacheMinObjectSize Directive

    + + + + + + + +
    Description:The minimum size (in bytes) of a document to be allowed in the +cache
    Syntax:MCacheMinObjectSize bytes
    Default:MCacheMinObjectSize 0
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheMinObjectSize directive sets the + minimum size in bytes of a document for it to be considered + cacheable.

    + +

    Example

    + MCacheMinObjectSize 10000 +

    + +
    +
    top
    +

    MCacheRemovalAlgorithm Directive

    + + + + + + + +
    Description:The algorithm used to select documents for removal from the +cache
    Syntax:MCacheRemovalAlgorithm LRU|GDSF
    Default:MCacheRemovalAlgorithm GDSF
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheRemovalAlgorithm directive specifies + the algorithm used to select documents for removal from the cache. + Two choices are available:

    + +
    +
    LRU (Least Recently Used)
    +
    LRU removes the documents that have not been accessed + for the longest time.
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF assigns a priority to cached documents based + on the cost of a cache miss and the size of the document. Documents + with the lowest priority are removed first.
    +
    + +

    Example

    + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +

    + +
    +
    top
    +

    MCacheSize Directive

    + + + + + + + +
    Description:The maximum amount of memory used by the cache in +KBytes
    Syntax:MCacheSize KBytes
    Default:MCacheSize 100
    Context:server config
    Status:Extension
    Module:mod_mem_cache
    +

    The MCacheSize directive sets the maximum + amount of memory to be used by the cache, in KBytes (1024-byte units). + If a new object needs to be inserted in the cache and the size of the + object is greater than the remaining memory, objects will be removed + until the new object can be cached. The object to be removed is + selected using the algorithm specified by MCacheRemovalAlgorithm.

    + +

    Example

    + MCacheSize 700000 +

    + +

    Note

    +

    The MCacheSize value must be greater than + the value specified by the MCacheMaxObjectSize directive.

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mem_cache.html.ja.euc-jp b/trunk/docs/manual/mod/mod_mem_cache.html.ja.euc-jp new file mode 100644 index 0000000000..f07530fa02 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.html.ja.euc-jp @@ -0,0 +1,234 @@ + + + +mod_mem_cache - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_mem_cache

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:URI ¤ò¥­¡¼¤Ë¤·¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:mem_cache_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_mem_cache.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_cache ¤òɬÍפȤ·¤Þ¤¹¡£ + ¤³¤ì¤Ï mod_cache ¤Î¥µ¥Ý¡¼¥È¥â¥¸¥å¡¼¥ë¤È¤·¤Æ + Æ°ºî¤·¡¢¥á¥â¥ê¤ò»ÈÍѤ·¤¿¥¹¥È¥ì¡¼¥¸´ÉÍýµ¡¹½¤òÄ󶡤·¤Þ¤¹¡£ + mod_mem_cache ¤ÏÆó¤Ä¤Î¥â¡¼¥É¤Î¤É¤Á¤é¤«¤ÇÆ°ºî¤¹¤ë¤è¤¦¤Ë + ÀßÄê¤Ç¤­¤Þ¤¹: ¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¥­¥ã¥Ã¥·¥å¤«¥Ò¡¼¥×Ãæ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î + ¥­¥ã¥Ã¥·¥å¤Ç¤¹¡£¥í¡¼¥«¥ë¤ÇÀ¸À®¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥Ä¤ËÂФ·¤Æ¥­¥ã¥Ã¥·¥å¤¹¤ë¤È¤­¤ä¡¢ + mod_proxy ¤ò»È¤Ã¤Æ ProxyPass (¤Ä¤Þ¤ê¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¸þ¤±) ¤ËÀßÄꤷ¤¿¤È¤­¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤Î¥³¥ó¥Æ¥ó¥Ä¤ËÂФ·¤Æ + ¥­¥ã¥Ã¥·¥å¤ò¤¹¤ë¤È¤­¤Ë¡¢¤¿¤¤¤Ø¤ó¸ú²ÌŪ¤Ç¤¹¡£

    + +

    ¥³¥ó¥Æ¥ó¥Ä¤Î¥­¥ã¥Ã¥·¥å¤Ø¤ÎÊݸ¤È¼èÆÀ¤Ï URI ¤Ë´ð¤Å¤¤¤¿¥­¡¼¤¬»È¤ï¤ì¤Þ¤¹¡£ + ¥¢¥¯¥»¥¹Êݸî¤Î¤«¤±¤é¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥Ä¤Ï¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£

    +
    + + +
    top
    +

    MCacheMaxObjectCount ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ÎºÇÂç¿ô
    ¹½Ê¸:MCacheMaxObjectCount value
    ¥Ç¥Õ¥©¥ë¥È:MCacheMaxObjectCount 1009
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheMaxObjectCount ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥­¥ã¥Ã¥·¥å¤µ¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ÎºÇÂç¿ô¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤ÎÃͤϥϥå·¥å¥Æ¡¼¥Ö¥ë¤òºîÀ®¤¹¤ë¤È¤­¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¿·¤·¤¤¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¤È¤­¤Ë¡¢¥ª¥Ö¥¸¥§¥¯¥È¤ÎºÇÂç¿ô¤Ë + 㤷¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¤È¤­¡¢¿·¤·¤¤¥ª¥Ö¥¸¥§¥¯¥È¤ò¥­¥ã¥Ã¥·¥å¤Ç¤­¤ë¤è¤¦¤Ë¡¢ + ¥ª¥Ö¥¸¥§¥¯¥È¤ò°ì¤Ä¾Ãµî¤·¤Þ¤¹¡£¥ª¥Ö¥¸¥§¥¯¥È¤Ï + MCacheRemovalAlgorithm + ¤Ç»ØÄꤵ¤ì¤¿¥¢¥ë¥´¥ê¥º¥à¤Ë½¾¤Ã¤Æºï½ü¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + MCacheMaxObjectCount 13001 +

    + +
    +
    top
    +

    MCacheMaxObjectSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤ËÊݴɤǤ­¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇÂ祵¥¤¥º (¥Ð¥¤¥È)
    ¹½Ê¸:MCacheMaxObjectSize bytes
    ¥Ç¥Õ¥©¥ë¥È:MCacheMaxObjectSize 10000
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheMaxObjectSize ¤Ï¥É¥­¥å¥á¥ó¥È¤ò + ¥­¥ã¥Ã¥·¥å¤¹¤ë¤«¤É¤¦¤«¤òȽÄꤹ¤ë¡¢ºÇÂç¤Î¥µ¥¤¥º¤ò¥Ð¥¤¥È¿ô¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    Îã

    + MCacheMaxObjectSize 6400000 +

    + +

    Ãí

    +

    MCacheMaxObjectSize ¤ÎÃÍ¤Ï MCacheMinObjectSize + ¤Ç»ØÄꤷ¤¿Ãͤè¤ê¤âÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +
    +
    top
    +

    MCacheMaxStreamingBuffer ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¹¥È¥ê¡¼¥à¤µ¤ì¤Æ¤¤¤ë±þÅú¤ò¥­¥ã¥Ã¥·¥åÉÔǽ¤È·èÄꤹ¤ë¤Þ¤Ç¤Ë +¥á¥â¥ê¤Ë¥Ð¥Ã¥Õ¥¡¤¹¤ëºÇÂçÎÌ
    ¹½Ê¸:MCacheMaxStreamingBuffer size_in_bytes
    ¥Ç¥Õ¥©¥ë¥È:MCacheMaxStreamingBuffer of 100000 ¤« MCacheMaxObjectSize ¤Î¾¯¤¤Êý
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheMaxStreamingBuffer ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥µ¥¤¥º¤¬Â礭¤¹¤®¤Æ¥­¥ã¥Ã¥·¥å¤Ç¤­¤Ê¤¤¤ÈȽÃǤ¹¤ë¤Þ¤Ç¤Î¡¢ + ¥¹¥È¥ê¡¼¥à±þÅú¤Î¥Ð¥Ã¥Õ¥¡¤Î¤¿¤á¤ÎºÇÂç¥Ð¥¤¥È¿ô¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥¹¥È¥ê¡¼¥à±þÅú¤È¤Ï¡¢¥³¥ó¥Æ¥ó¥Ä¤ÎÁ´ÂΤ¬¤¹¤°¤Ë¤ÏÆÀ¤é¤ì¤º¡¢ + Content-Length ¤¬¤ï¤«¤é¤Ê¤¤±þÅú¤ò»Ø¤·¤Þ¤¹¡£ + ¥¹¥È¥ê¡¼¥à±þÅú¤ò¹Ô¤Ê¤¦¤è¤¦¤Ê¤â¤Î¤Ë¤Ï¥×¥í¥­¥·¤µ¤ì¤¿±þÅú¤ä¡¢ + CGI ¥¹¥¯¥ê¥×¥È¤Î½ÐÎϤʤɤ¬¤¢¤ê¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥¹¥È¥ê¡¼¥à¤Î±þÅú¤Ï + Content-Length ¤¬¤Ê¤¤¸Â¤ê¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤»¤ó¡£ + ¤³¤Î¤è¤¦¤ÊÆ°ºî¤Ë¤Ê¤Ã¤Æ¤¤¤ëÍýͳ¤Ï¡¢·ë¶É¥­¥ã¥Ã¥·¥å¤Ë¼ý¤Þ¤ê¤­¤é¤Ê¤¤¤È + ȽÃǤ¹¤ë¤³¤È¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤è¤¦¤Ê¡¢¥µ¥¤¥º¤ÎÂ礭¤Ê±þÅú¤Î¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤Ë¡¢ + ÂçÎ̤Υá¥â¥ê¤¬¾ÃÈñ¤µ¤ì¤ë¤Î¤òÈò¤±¤ë¤¿¤á¤Ç¤¹¡£ + MCacheMaxStreamingBuffer ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È¡¢ + Content-Length ¤ò´Þ¤Þ¤Ê¤¤±þÅú¤ËÂФ·¤Æ»ØÄꤵ¤ì¤¿ºÇÂçÎÌ¤Þ¤Ç + ¥Ð¥Ã¥Õ¥¡¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£¥Ð¥Ã¥Õ¥¡¤ò»È¤¤ÀÚ¤ë¤È¡¢¥Ð¥Ã¥Õ¥¡Ãæ¤Î + ¥³¥ó¥Æ¥ó¥Ä¤Ï¼Î¤Æ¤é¤ì¡¢¥­¥ã¥Ã¥·¥åÆ°ºî¤òÃæ»ß¤·¤Þ¤¹¡£

    + +

    Ãí:

    +

    MCacheMaxStreamingBuffer ¤ËÈóÎí¤ÎÃͤò + »È¤Ã¤Æ¤â¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ø¤Î±þÅú¤ÎžÁ÷¤ËÆäËÃÙ±ä¤ÏȯÀ¸¤·¤Þ¤»¤ó¡£ + mod_mem_cache ¤Ï¥¹¥È¥ê¡¼¥à¥³¥ó¥Æ¥ó¥Ä¤ÎÃÇÊÒ¤ò + ¥Ð¥Ã¥Õ¥¡¤Ë¥³¥Ô¡¼¤·¤¿¸å¡¢Â¨ºÂ¤Ë¡¢¤½¤ÎÉôʬ¤ò¥¯¥é¥¤¥¢¥ó¥È¤Ø¤ÎÇÛÁ÷¤Î + ¼¡ÃʤνÐÎÏ¥Õ¥£¥ë¥¿¤ËÁ÷¤ê¤Þ¤¹¡£

    +
    + +

    + # Enable caching of streamed responses up to 64KB:
    + MCacheMaxStreamingBuffer 65536 +

    + +
    +
    top
    +

    MCacheMinObjectSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇ¾®¥µ¥¤¥º (¥Ð¥¤¥È)
    ¹½Ê¸:MCacheMinObjectSize bytes
    ¥Ç¥Õ¥©¥ë¥È:MCacheMinObjectSize 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheMinObjectSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤ò + ¥­¥ã¥Ã¥·¥å¤¹¤ë¤«¤É¤¦¤«¤òȽÄꤹ¤ë¡¢ºÇ¾®¤Î¥µ¥¤¥º¤ò¥Ð¥¤¥È¿ô¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    Îã

    + MCacheMinObjectSize 10000 +

    + +
    +
    top
    +

    MCacheRemovalAlgorithm ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤«¤éºï½ü¤¹¤ë¥É¥­¥å¥á¥ó¥È¤òÁª¤Ö¤¿¤á¤Î¥¢¥ë¥´¥ê¥º¥à
    ¹½Ê¸:MCacheRemovalAlgorithm LRU|GDSF
    ¥Ç¥Õ¥©¥ë¥È:MCacheRemovalAlgorithm GDSF
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheRemovalAlgorithm ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥­¥ã¥Ã¥·¥å¤«¤éºï½ü¤¹¤ë¥É¥­¥å¥á¥ó¥È¤òÁªÂò¤¹¤ë¤¿¤á¤Î¥¢¥ë¥´¥ê¥º¥à¤ò + »ØÄꤷ¤Þ¤¹¡£ÁªÂò»è¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹:

    + +
    +
    LRU (Least Recently Used)
    +
    LRU °ìÈÖŤ¯¥¢¥¯¥»¥¹¤µ¤ì¤Æ¤¤¤Ê¤¤¥É¥­¥å¥á¥ó¥È¤òºï½ü¤·¤Þ¤¹¡£ +
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF ¤Ï¥­¥ã¥Ã¥·¥å¥ß¥¹¤Î¥³¥¹¥È¤È¥É¥­¥å¥á¥ó¥È¤Î¥µ¥¤¥º¤ò¤â¤È¤Ë¡¢ + ¥É¥­¥å¥á¥ó¥È¤Î¥­¥ã¥Ã¥·¥å¤ËÂФ·¤ÆÍ¥ÀèÅÙ¤ò¤Ä¤±¤Þ¤¹¡£ + Í¥ÀèÅ٤ΰìÈÖÄ㤤¥É¥­¥å¥á¥ó¥È¤¬ºÇ½é¤Ëºï½ü¤µ¤ì¤Þ¤¹¡£
    +
    + +

    Îã

    + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +

    + +
    +
    top
    +

    MCacheSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥­¥ã¥Ã¥·¥å¤Ë»È¤ï¤ì¤ë¥á¥â¥ê¤ÎºÇÂçÎ̤ò¥Ð¥¤¥Èñ°Ì¤Ç»ØÄê
    ¹½Ê¸:MCacheSize KBytes
    ¥Ç¥Õ¥©¥ë¥È:MCacheSize 100
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_mem_cache
    +

    MCacheSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥­¥ã¥Ã¥·¥å¤Ë + »È¤ï¤ì¤ë¥á¥â¥ê¤ÎÂ礭¤µ¤ò¥­¥í¥Ð¥¤¥È (1024 ¥Ð¥¤¥Èñ°Ì) ¤ÇÀßÄꤷ¤Þ¤¹¡£ + ¿·¤·¤¤¥ª¥Ö¥¸¥§¥¯¥È¤ò¥­¥ã¥Ã¥·¥å¤ËÁÞÆþ¤¹¤ë¤³¤È¤Ë¤Ê¤ê¡¢¥ª¥Ö¥¸¥§¥¯¥È¤Î + ¥µ¥¤¥º¤¬»Ä¤ê¤Î¥á¥â¥ê¤è¤êÂ礭¤¤¾ì¹ç¤Ï¡¢¤½¤Î¿·¤·¤¤¥ª¥Ö¥¸¥§¥¯¥È¤ÎÁÞÆþ¤¬ + ²Äǽ¤Ë¤Ê¤ë¤Þ¤Ç¡¢¸Å¤¤¥ª¥Ö¥¸¥§¥¯¥È¤¬ºï½ü¤µ¤ì¤Æ¤¤¤­¤Þ¤¹¡£ + ¥ª¥Ö¥¸¥§¥¯¥È¤Ï MCacheRemovalAlgorithm + ¤Ç»ØÄꤷ¤¿¥¢¥ë¥´¥ê¥º¥à¤Ë½¾¤Ã¤Æºï½ü¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + MCacheSize 700000 +

    + +

    Ãí

    +

    MCacheSize ¤ÎÃÍ¤Ï MCacheMaxObjectSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤷ¤¿Ãͤè¤ê + Â礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mem_cache.html.ko.euc-kr b/trunk/docs/manual/mod/mod_mem_cache.html.ko.euc-kr new file mode 100644 index 0000000000..467fc05ff1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.html.ko.euc-kr @@ -0,0 +1,237 @@ + + + +mod_mem_cache - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_mem_cache

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù.
    »óÅÂ:Experimental
    ¸ðµâ¸í:mem_cache_module
    ¼Ò½ºÆÄÀÏ:mod_mem_cache.c
    +

    ¿ä¾à

    + +
    + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... +
    + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é mod_cache°¡ + ÇÊ¿äÇÏ´Ù. ÀÌ ¸ðµâÀº mod_cache¸¦ + Áö¿øÇÏ¸ç ¸Þ¸ð¸®±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ Á¦°øÇÑ´Ù. + mod_mem_cache´Â ÆÄÀϱâ¼úÀÚ¸¦ ij½¬¿¡ ÀúÀåÇϰųª + °´Ã¼¸¦ Èü °ø°£¿¡ ij½¬ÇÏ´Â µÎ°¡Áö ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù. + mod_mem_cache´Â Á÷Á¢ ¼­¹ö°¡ »ý¼ºÇÑ ÆäÀÌÁö¸¦ + ij½¬Çϰųª ProxyPass·Î + ¼³Á¤ÇÑ (¿ªÇÁ·Ï½Ã(reverse proxy)) + mod_proxyÀÇ µÞ´Ü ¼­¹ö³»¿ëÀ» ij½¬ÇÒ¶§ ÁÖ·Î + »ç¿ëÇÑ´Ù.

    + +

    ³»¿ëÀº URI¸¦ Å°·Î »ç¿ëÇÏ¿© ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±ÙÀ» Á¦¾îÇÏ´Â ³»¿ëÀº ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù.

    +
    + + +
    top
    +

    MCacheMaxObjectCount Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÀúÀåÇÒ ¼ö ÀÖ´Â ÃÖ´ë °´Ã¼°³¼ö
    ¹®¹ý:MCacheMaxObjectCount value
    ±âº»°ª:MCacheMaxObjectCount 1009
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheMaxObjectCount Áö½Ã¾î´Â + ij½¬ÇÒ ¼ö ÀÖ´Â ÃÖ´ë °´Ã¼°³¼ö¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ °ªÀº Çؽ¬Å×À̺íÀ» + ¸¸µé¶§ »ç¿ëÇÑ´Ù. »õ·Î¿î °´Ã¼¸¦ ij½¬¿¡ Ãß°¡ÇØ¾ß Çϴµ¥ ÃÖ´ë + °´Ã¼°³¼ö¿¡ µµ´ÞÇÏ¿´´Ù¸é, »õ·Î¿î °´Ã¼¸¦ ij½¬ÇÒ ¼ö ÀÖµµ·Ï + ´Ù¸¥ °´Ã¼¸¦ Á¦°ÅÇÑ´Ù. MCacheRemovalAlgorithmÀ¸·Î + ÁöÁ¤ÇÑ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© Á¦°ÅÇÒ °´Ã¼¸¦ ¼±ÅÃÇÑ´Ù.

    + +

    ¿¹Á¦

    + MCacheMaxObjectCount 13001 +

    + +
    +
    top
    +

    MCacheMaxObjectSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ë Å©±â (¹ÙÀÌÆ® ´ÜÀ§)
    ¹®¹ý:MCacheMaxObjectSize bytes
    ±âº»°ª:MCacheMaxObjectSize 10000
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheMaxObjectSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ë Å©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + +

    ¿¹Á¦

    + MCacheMaxObjectSize 6400000 +

    + +

    Note

    +

    MCacheMaxObjectSize °ªÀº MCacheMinObjectSize + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªº¸´Ù Ä¿¾ß ÇÑ´Ù.

    +
    + +
    +
    top
    +

    MCacheMaxStreamingBuffer Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ÀÀ´äÀ» ij½¬¾ÈÇÑ´Ù°í °áÁ¤Çϱâ Àü±îÁö ¸Þ¸ð¸® ¹öÆÛ¿¡ +ÀúÀåÇÒ ½ºÆ®¸² ÀÀ´äÀÇ ÃÖ´ë Å©±â
    ¹®¹ý:MCacheMaxStreamingBuffer size_in_bytes
    ±âº»°ª:MCacheMaxStreamingBuffer 100000°ú MCacheMaxObjectSize +Áß¿¡ ÀÛÀº °ª
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheMaxStreamingBuffer Áö½Ã¾î´Â + ÀÀ´äÀÌ ³Ê¹« Ä¿¼­ ij½¬ÇÒ ¼ö ¾øÀ»¶§±îÁö ¹öÆÛ¿¡ ÀúÀåÇÒ ½ºÆ®¸² + ÀÀ´äÀÇ ÃÖ´ë ¹ÙÀÌÆ®¼ö¸¦ ¼³Á¤ÇÑ´Ù. ½ºÆ®¸² ÀÀ´ä(streamed response)Àº + Àüü ³»¿ëÀ» Áï½Ã ¾Ë ¼ö ¾ø°í Content-Lengthµµ + ¸ð¸£´Â ÀÀ´äÀÌ´Ù. ÇÁ·Ï½ÃµÈ ÀÀ´äÀ̳ª CGI ½ºÅ©¸³Æ®ÀÇ Ãâ·ÂÀÌ + ½ºÆ®¸² ÀÀ´ä¿¡ ¼ÓÇÑ´Ù. ±âº»ÀûÀ¸·Î Content-Length + Çì´õ°¡ ¾ø´Ù¸é ½ºÆ®¸² ÀÀ´äÀ» ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù. + ÀÌÀ¯´Â ij½¬¿¡ ÀúÀåÇϱ⿡ ³Ê¹« Å« ÀÀ´äÀÇ ÀϺθ¦ ¹öÆÛ¿¡ + ÀúÀåÇϱâÀ§ÇØ ¸¹Àº ¸Þ¸ð¸®¸¦ ³¶ºñÇÏÁö ¾Ê±âÀ§Çؼ­ÀÌ´Ù. + MCacheMaxStreamingBuffer Áö½Ã¾î¸¦ + »ç¿ëÇϸé Content-Length°¡ ¾ø´Â ½ºÆ®¸² ÀÀ´äÀ» + ÁöÁ¤ÇÑ Å©±â±îÁö¸¸ ¹öÆÛ¿¡ ÀúÀåÇÑ´Ù. ÃÖ´ë Å©±â¸¦ ³Ñ¾î¼­¸é + ¹öÆÛ ³»¿ëÀ» ¹ö¸®°í ij½¬ÇÏÁö ¾Ê´Â´Ù.

    + +

    ÁÖÀÇ:

    +

    MCacheMaxStreamingBuffer¿¡ 0ÀÌ + ¾Æ´Ñ °ªÀ» ¼³Á¤ÇÏ¿©µµ Ŭ¶óÀ̾ðÆ®·Î ÀÀ´äÀ» ´Ê°Ô º¸³»Áö ¾Ê´Â´Ù. + mod_mem_cache´Â ½ºÆ®¸² ÀÀ´äÀÇ ÀϺθ¦ + ¹öÆÛ¿¡ º¹»çÇÏÀÚ¸¶ÀÚ Å¬¶óÀ̾ðÆ®·Î º¸³»±âÀ§ÇØ ´ÙÀ½ Ãâ·ÂÇÊÅÍ·Î + º¸³½´Ù.

    +
    + +

    + # ½ºÆ®¸² ÀÀ´äÀ» 64KB±îÁö ij½¬ÇÑ´Ù:
    + MCacheMaxStreamingBuffer 65536 +

    + +
    +
    top
    +

    MCacheMinObjectSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼Ò Å©±â (¹ÙÀÌÆ® ´ÜÀ§)
    ¹®¹ý:MCacheMinObjectSize bytes
    ±âº»°ª:MCacheMinObjectSize 0
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheMinObjectSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼Ò Å©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + +

    ¿¹Á¦

    + MCacheMinObjectSize 10000 +

    + +
    +
    top
    +

    MCacheRemovalAlgorithm Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡¼­ Á¦°ÅÇÒ ¹®¼­¸¦ ã´Â ¾Ë°í¸®Áò
    ¹®¹ý:MCacheRemovalAlgorithm LRU|GDSF
    ±âº»°ª:MCacheRemovalAlgorithm GDSF
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheRemovalAlgorithm Áö½Ã¾î´Â + ij½¬¿¡¼­ Á¦°ÅÇÒ ¹®¼­¸¦ ã´Â ¾Ë°í¸®ÁòÀ» ÁöÁ¤ÇÑ´Ù.

    + +
    +
    LRU (Least Recently Used)
    +
    LRU´Â °¡Àå ¿À·¡µ¿¾È Á¢±ÙÇÏÁö ¾ÊÀº ¹®¼­¸¦ + ¸ÕÀú Á¦°ÅÇÑ´Ù.
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF´Â ij½¬ ½ÇÆÐ(cache miss) ºñ¿ë°ú ¹®¼­ÀÇ + Å©±â¸¦ °¡Áö°í ij½¬ÇÑ ¹®¼­¿¡ ¿ì¼±¼øÀ§¸¦ ºÎ¿©ÇÑ´Ù. °¡Àå + ¿ì¼±¼øÀ§°¡ ³·Àº ¹®¼­¸¦ ¸ÕÀú Á¦°ÅÇÑ´Ù.
    +
    + +

    ¿¹Á¦

    + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +

    + +
    +
    top
    +

    MCacheSize Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:ij½¬¿¡ »ç¿ëÇÒ ÃÖ´ë ¸Þ¸ð¸®·® (KByte ´ÜÀ§)
    ¹®¹ý:MCacheSize KBytes
    ±âº»°ª:MCacheSize 100
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Experimental
    ¸ðµâ:mod_mem_cache
    +

    MCacheSize Áö½Ã¾î´Â ij½¬¿¡ »ç¿ëÇÒ + ÃÖ´ë ¸Þ¸ð¸®·®À» KByte ´ÜÀ§·Î (1024 ¹ÙÀÌÆ® ´ÜÀ§) ¼³Á¤ÇÑ´Ù. + »õ·Î¿î °´Ã¼À» ij½¬¿¡ Ãß°¡ÇØ¾ß Çϴµ¥ °´Ã¼ÀÇ Å©±â°¡ ³²Àº + ¸Þ¸ð¸®º¸´Ù Å©´Ù¸é »õ·Î¿î °´Ã¼À» ij½¬ÇÒ ¼ö ÀÖÀ»¶§±îÁö ´Ù¸¥ + °´Ã¼¸¦ Á¦°ÅÇÑ´Ù. MCacheRemovalAlgorithmÀ¸·Î + ÁöÁ¤ÇÑ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© Á¦°ÅÇÒ °´Ã¼¸¦ ¼±ÅÃÇÑ´Ù.

    + +

    ¿¹Á¦

    + MCacheSize 700000 +

    + +

    ÁÖÀÇ

    +

    MCacheSize °ªÀº MCacheMaxObjectSize + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªº¸´Ù Ä¿¾ß ÇÑ´Ù.

    +
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mem_cache.xml b/trunk/docs/manual/mod/mod_mem_cache.xml new file mode 100644 index 0000000000..4007301eea --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.xml @@ -0,0 +1,217 @@ + + + + + + + + + +mod_mem_cache +Content cache keyed to URIs +Extension +mod_mem_cache.c +mem_cache_module + + +

    This module requires the service of mod_cache. It acts as a support module for mod_cache and provides a memory based storage manager. + mod_mem_cache can be configured to operate in two + modes: caching open file descriptors or caching objects in heap storage. + mod_mem_cache is most useful when used to cache locally + generated content or to cache backend server content for mod_proxy configured for ProxyPass (aka reverse proxy).

    + +

    Content is stored in and retrieved from the cache using URI based + keys. Content with access protection is not cached.

    +
    +mod_cache +mod_disk_cache + + +MCacheSize +The maximum amount of memory used by the cache in +KBytes +MCacheSize KBytes +MCacheSize 100 +server config + + +

    The MCacheSize directive sets the maximum + amount of memory to be used by the cache, in KBytes (1024-byte units). + If a new object needs to be inserted in the cache and the size of the + object is greater than the remaining memory, objects will be removed + until the new object can be cached. The object to be removed is + selected using the algorithm specified by MCacheRemovalAlgorithm.

    + + Example + MCacheSize 700000 + + + Note +

    The MCacheSize value must be greater than + the value specified by the MCacheMaxObjectSize directive.

    +
    +
    +
    + + +MCacheMaxObjectCount +The maximum number of objects allowed to be placed in the +cache +MCacheMaxObjectCount value +MCacheMaxObjectCount 1009 +server config + + +

    The MCacheMaxObjectCount directive sets the + maximum number of objects to be cached. The value is used to create the + open hash table. If a new object needs to be inserted in the cache and + the maximum number of objects has been reached, an object will be + removed to allow the new object to be cached. The object to be removed + is selected using the algorithm specified by MCacheRemovalAlgorithm.

    + + Example + MCacheMaxObjectCount 13001 + +
    +
    + + +MCacheMinObjectSize +The minimum size (in bytes) of a document to be allowed in the +cache +MCacheMinObjectSize bytes +MCacheMinObjectSize 0 +server config + + +

    The MCacheMinObjectSize directive sets the + minimum size in bytes of a document for it to be considered + cacheable.

    + + Example + MCacheMinObjectSize 10000 + +
    +
    + + +MCacheMaxObjectSize +The maximum size (in bytes) of a document allowed in the +cache +MCacheMaxObjectSize bytes +MCacheMaxObjectSize 10000 +server config + + +

    The MCacheMaxObjectSize directive sets the + maximum allowable size, in bytes, of a document for it to be considered + cacheable.

    + + Example + MCacheMaxObjectSize 6400000 + + + Note +

    The value of MCacheMaxObjectSize must be + greater than the value specified by the MCacheMinObjectSize directive.

    +
    +
    +
    + + +MCacheRemovalAlgorithm +The algorithm used to select documents for removal from the +cache +MCacheRemovalAlgorithm LRU|GDSF +MCacheRemovalAlgorithm GDSF +server config + + +

    The MCacheRemovalAlgorithm directive specifies + the algorithm used to select documents for removal from the cache. + Two choices are available:

    + +
    +
    LRU (Least Recently Used)
    +
    LRU removes the documents that have not been accessed + for the longest time.
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF assigns a priority to cached documents based + on the cost of a cache miss and the size of the document. Documents + with the lowest priority are removed first.
    +
    + + Example + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +
    +
    +
    + + +MCacheMaxStreamingBuffer +Maximum amount of a streamed response to buffer in memory +before declaring the response uncacheable +MCacheMaxStreamingBuffer size_in_bytes +MCacheMaxStreamingBuffer the smaller of 100000 or MCacheMaxObjectSize +server config + + + +

    The MCacheMaxStreamingBuffer directive + specifies the maximum number of bytes of a streamed response to + buffer before deciding that the response is too big to cache. + A streamed response is one in which the entire content is not + immediately available and in which the Content-Length + may not be known. Sources of streaming responses include proxied + responses and the output of CGI scripts. By default, a streamed + response will not be cached unless it has a + Content-Length header. The reason for this is to + avoid using a large amount of memory to buffer a partial response + that might end up being too large to fit in the cache. + The MCacheMaxStreamingBuffer directive allows + buffering of streamed responses that don't contain a + Content-Length up to the specified maximum amount of + space. If the maximum buffer space is reached, the buffered + content is discarded and the attempt to cache is abandoned.

    + + Note: +

    Using a nonzero value for MCacheMaxStreamingBuffer + will not delay the transmission of the response to the client. + As soon as mod_mem_cache copies a block of streamed + content into a buffer, it sends the block on to the next output + filter for delivery to the client.

    +
    + + + # Enable caching of streamed responses up to 64KB:
    + MCacheMaxStreamingBuffer 65536 +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_mem_cache.xml.ja b/trunk/docs/manual/mod/mod_mem_cache.xml.ja new file mode 100644 index 0000000000..1661a6483b --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.xml.ja @@ -0,0 +1,213 @@ + + + + + + + + + +mod_mem_cache +URI $B$r%-!<$K$7$?%3%s%F%s%D$N%-%c%C%7%e(B +Extension +mod_mem_cache.c +mem_cache_module + + +

    $B$3$N%b%8%e!<%k$O(B mod_cache $B$r(B$BI,MW$H$7$^$9(B$B!#(B + $B$3$l$O(B mod_cache $B$N%5%]!<%H%b%8%e!<%k$H$7$F(B + $BF0:n$7!"%a%b%j$r;HMQ$7$?%9%H%l!<%84IM}5!9=$rDs6!$7$^$9!#(B + mod_mem_cache $B$OFs$D$N%b!<%I$N$I$A$i$+$GF0:n$9$k$h$&$K(B + $B@_Dj$G$-$^$9(B: $B%U%!%$%k5-=R;R$N%-%c%C%7%e$+%R!<%WCf$N%*%V%8%'%/%H$N(B + $B%-%c%C%7%e$G$9!#%m!<%+%k$G@8@.$5$l$?%3%s%F%s%D$KBP$7$F%-%c%C%7%e$9$k$H$-$d!"(B + mod_proxy $B$r;H$C$F(B ProxyPass ($B$D$^$j(B$B%j%P!<%9%W%m%-%7(B$B8~$1(B) $B$K@_Dj$7$?$H$-$N%P%C%/%(%s%I%5!<%P$N%3%s%F%s%D$KBP$7$F(B + $B%-%c%C%7%e$r$9$k$H$-$K!"$?$$$X$s8z2LE*$G$9!#(B

    + +

    $B%3%s%F%s%D$N%-%c%C%7%e$X$NJ]B8$H +

    +mod_cache +mod_disk_cache + + +MCacheSize +$B%-%c%C%7%e$K;H$o$l$k%a%b%j$N:GBgNL$r%P%$%HC10L$G;XDj(B +MCacheSize KBytes +MCacheSize 100 +server config + + +

    MCacheSize $B%G%#%l%/%F%#%V$O%-%c%C%7%e$K(B + $B;H$o$l$k%a%b%j$NBg$-$5$r%-%m%P%$%H(B (1024 $B%P%$%HC10L(B) $B$G@_Dj$7$^$9!#(B + $B?7$7$$%*%V%8%'%/%H$r%-%c%C%7%e$KA^F~$9$k$3$H$K$J$j!"%*%V%8%'%/%H$N(B + $B%5%$%:$,;D$j$N%a%b%j$h$jBg$-$$>l9g$O!"$=$N?7$7$$%*%V%8%'%/%H$NA^F~$,(B + $B2DG=$K$J$k$^$G!"8E$$%*%V%8%'%/%H$,:o=|$5$l$F$$$-$^$9!#(B + $B%*%V%8%'%/%H$O(B MCacheRemovalAlgorithm + $B$G;XDj$7$?%"%k%4%j%:%`$K=>$C$F:o=|$5$l$^$9!#(B

    + + $BNc(B + MCacheSize 700000 + + + $BCm(B +

    MCacheSize $B$NCM$O(B MCacheMaxObjectSize $B%G%#%l%/%F%#%V$G;XDj$7$?CM$h$j(B + $BBg$-$/$J$1$l$P$J$j$^$;$s!#(B

    +
    +
    +
    + + +MCacheMaxObjectCount +$B%-%c%C%7%e$KJ]4I$5$l$k%*%V%8%'%/%H$N:GBg?t(B +MCacheMaxObjectCount value +MCacheMaxObjectCount 1009 +server config + + +

    MCacheMaxObjectCount $B%G%#%l%/%F%#%V$O(B + $B%-%c%C%7%e$5$l$k%*%V%8%'%/%H$N:GBg?t$r;XDj$7$^$9!#(B + $B$3$NCM$O%O%C%7%e%F!<%V%k$r:n@.$9$k$H$-$K;H$o$l$^$9!#(B + $B?7$7$$%*%V%8%'%/%H$rA^F~$9$k$H$-$K!"%*%V%8%'%/%H$N:GBg?t$K(B + $BC#$7$F$7$^$C$F$$$k$H$-!"?7$7$$%*%V%8%'%/%H$r%-%c%C%7%e$G$-$k$h$&$K!"(B + $B%*%V%8%'%/%H$r0l$D>C5n$7$^$9!#%*%V%8%'%/%H$O(B + MCacheRemovalAlgorithm + $B$G;XDj$5$l$?%"%k%4%j%:%`$K=>$C$F:o=|$5$l$^$9!#(B

    + + $BNc(B + MCacheMaxObjectCount 13001 + +
    +
    + + +MCacheMinObjectSize +$B%-%c%C%7%e$KJ]4I$5$l$k%I%-%e%a%s%H$N:G>.%5%$%:(B ($B%P%$%H(B) +MCacheMinObjectSize bytes +MCacheMinObjectSize 0 +server config + + +

    MCacheMinObjectSize $B%G%#%l%/%F%#%V$O!"%I%-%e%a%s%H$r(B + $B%-%c%C%7%e$9$k$+$I$&$+$rH=Dj$9$k!":G>.$N%5%$%:$r%P%$%H?t$G@_Dj$7$^$9!#(B

    + + $BNc(B + MCacheMinObjectSize 10000 + +
    +
    + + +MCacheMaxObjectSize +$B%-%c%C%7%e$KJ]4I$G$-$k%I%-%e%a%s%H$N:GBg%5%$%:(B ($B%P%$%H(B) +MCacheMaxObjectSize bytes +MCacheMaxObjectSize 10000 +server config + + +

    MCacheMaxObjectSize $B$O%I%-%e%a%s%H$r(B + $B%-%c%C%7%e$9$k$+$I$&$+$rH=Dj$9$k!":GBg$N%5%$%:$r%P%$%H?t$G@_Dj$7$^$9!#(B

    + + $BNc(B + MCacheMaxObjectSize 6400000 + + + $BCm(B +

    MCacheMaxObjectSize $B$NCM$O(B MCacheMinObjectSize + $B$G;XDj$7$?CM$h$j$bBg$-$/$J$1$l$P$J$j$^$;$s!#(B

    +
    +
    +
    + + +MCacheRemovalAlgorithm +$B%-%c%C%7%e$+$i:o=|$9$k%I%-%e%a%s%H$rA*$V$?$a$N%"%k%4%j%:%`(B +MCacheRemovalAlgorithm LRU|GDSF +MCacheRemovalAlgorithm GDSF +server config + + +

    MCacheRemovalAlgorithm $B%G%#%l%/%F%#%V$O!"(B + $B%-%c%C%7%e$+$i:o=|$9$k%I%-%e%a%s%H$rA*Br$9$k$?$a$N%"%k%4%j%:%`$r(B + $B;XDj$7$^$9!#A*Br;h$OFs$D$"$j$^$9(B:

    + +
    +
    LRU (Least Recently Used)
    +
    LRU $B0lHVD9$/%"%/%;%9$5$l$F$$$J$$%I%-%e%a%s%H$r:o=|$7$^$9!#(B +
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF $B$O%-%c%C%7%e%_%9$N%3%9%H$H%I%-%e%a%s%H$N%5%$%:$r$b$H$K!"(B + $B%I%-%e%a%s%H$N%-%c%C%7%e$KBP$7$FM%@hEY$r$D$1$^$9!#(B + $BM%@hEY$N0lHVDc$$%I%-%e%a%s%H$,:G=i$K:o=|$5$l$^$9!#(B
    +
    + + $BNc(B + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +
    +
    +
    + + +MCacheMaxStreamingBuffer +$B%9%H%j!<%`$5$l$F$$$k1~Ez$r%-%c%C%7%eITG=$H7hDj$9$k$^$G$K(B +$B%a%b%j$K%P%C%U%!$9$k:GBgNL(B +MCacheMaxStreamingBuffer size_in_bytes +MCacheMaxStreamingBuffer of 100000 $B$+(B MCacheMaxObjectSize $B$N>/$$J}(B +server config + + + +

    MCacheMaxStreamingBuffer $B%G%#%l%/%F%#%V$O!"(B + $B%5%$%:$,Bg$-$9$.$F%-%c%C%7%e$G$-$J$$$HH=CG$9$k$^$G$N!"(B + $B%9%H%j!<%`1~Ez$N%P%C%U%!$N$?$a$N:GBg%P%$%H?t$r;XDj$7$^$9!#(B + $B%9%H%j!<%`1~Ez$H$O!"%3%s%F%s%D$NA4BN$,$9$0$K$OF@$i$l$:!"(B + Content-Length $B$,$o$+$i$J$$1~Ez$r;X$7$^$9!#(B + $B%9%H%j!<%`1~Ez$r9T$J$&$h$&$J$b$N$K$O%W%m%-%7$5$l$?1~Ez$d!"(B + CGI $B%9%/%j%W%H$N=PNO$J$I$,$"$j$^$9!#%G%U%)%k%H$G$O%9%H%j!<%`$N1~Ez$O(B + Content-Length $B$,$J$$8B$j%-%c%C%7%e(B$B$5$l$^$;$s(B$B!#(B + $B$3$N$h$&$JF0:n$K$J$C$F$$$kM}M3$O!"7k6I%-%c%C%7%e$K<}$^$j$-$i$J$$$H(B + $BH=CG$9$k$3$H$K$J$C$F$7$^$&$h$&$J!"%5%$%:$NBg$-$J1~Ez$N%P%C%U%!%j%s%0$K!"(B + $BBgNL$N%a%b%j$,>CHq$5$l$k$N$rHr$1$k$?$a$G$9!#(B + MCacheMaxStreamingBuffer $B%G%#%l%/%F%#%V$r;H$&$H!"(B + Content-Length $B$r4^$^$J$$1~Ez$KBP$7$F;XDj$5$l$?:GBgNL$^$G(B + $B%P%C%U%!$9$k$h$&$K$G$-$^$9!#%P%C%U%!$r;H$$@Z$k$H!"%P%C%U%!Cf$N(B + $B%3%s%F%s%D$O + + $BCm(B: +

    MCacheMaxStreamingBuffer $B$KHsNm$NCM$r(B + $B;H$C$F$b!"%/%i%$%"%s%H$X$N1~Ez$NE>Aw$KFC$KCY1d$OH/@8$7$^$;$s!#(B + mod_mem_cache $B$O%9%H%j!<%`%3%s%F%s%D$NCGJR$r(B + $B%P%C%U%!$K%3%T!<$7$?8e!"B(:B$K!"$=$NItJ,$r%/%i%$%"%s%H$X$NG[Aw$N(B + $B + + + + # Enable caching of streamed responses up to 64KB:
    + MCacheMaxStreamingBuffer 65536 +
    + + + + diff --git a/trunk/docs/manual/mod/mod_mem_cache.xml.ko b/trunk/docs/manual/mod/mod_mem_cache.xml.ko new file mode 100644 index 0000000000..264693a3c6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.xml.ko @@ -0,0 +1,212 @@ + + + + + + + + + +mod_mem_cache +URI¸¦ Å°·Î »ç¿ëÇÏ¿© ³»¿ëÀ» ij½¬ÇÑ´Ù. +Experimental +mod_mem_cache.c +mem_cache_module + +

    + + ÀÌ ¸ðµâÀº ½ÇÇèÀûÀÎ »óÅÂÀÌ´Ù. ¹®¼­´Â ¾ÆÁ÷ ÀÛ¾÷ÁßÀÌ´Ù... + + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é mod_cache°¡ + ÇÊ¿äÇÏ´Ù. ÀÌ ¸ðµâÀº mod_cache¸¦ + Áö¿øÇÏ¸ç ¸Þ¸ð¸®±â¹Ý ÀúÀå°ü¸®ÀÚ¸¦ Á¦°øÇÑ´Ù. + mod_mem_cache´Â ÆÄÀϱâ¼úÀÚ¸¦ ij½¬¿¡ ÀúÀåÇϰųª + °´Ã¼¸¦ Èü °ø°£¿¡ ij½¬ÇÏ´Â µÎ°¡Áö ¹æ½ÄÀ¸·Î µ¿ÀÛÇÑ´Ù. + mod_mem_cache´Â Á÷Á¢ ¼­¹ö°¡ »ý¼ºÇÑ ÆäÀÌÁö¸¦ + ij½¬Çϰųª ProxyPass·Î + ¼³Á¤ÇÑ (¿ªÇÁ·Ï½Ã(reverse proxy)) + mod_proxyÀÇ µÞ´Ü ¼­¹ö³»¿ëÀ» ij½¬ÇÒ¶§ ÁÖ·Î + »ç¿ëÇÑ´Ù.

    + +

    ³»¿ëÀº URI¸¦ Å°·Î »ç¿ëÇÏ¿© ij½¬¿¡ ÀúÀåÇÏ°í °¡Á®¿Â´Ù. + Á¢±ÙÀ» Á¦¾îÇÏ´Â ³»¿ëÀº ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù.

    +
    +mod_cache +mod_disk_cache + + +MCacheSize +ij½¬¿¡ »ç¿ëÇÒ ÃÖ´ë ¸Þ¸ð¸®·® (KByte ´ÜÀ§) +MCacheSize KBytes +MCacheSize 100 +server config + + +

    MCacheSize Áö½Ã¾î´Â ij½¬¿¡ »ç¿ëÇÒ + ÃÖ´ë ¸Þ¸ð¸®·®À» KByte ´ÜÀ§·Î (1024 ¹ÙÀÌÆ® ´ÜÀ§) ¼³Á¤ÇÑ´Ù. + »õ·Î¿î °´Ã¼À» ij½¬¿¡ Ãß°¡ÇØ¾ß Çϴµ¥ °´Ã¼ÀÇ Å©±â°¡ ³²Àº + ¸Þ¸ð¸®º¸´Ù Å©´Ù¸é »õ·Î¿î °´Ã¼À» ij½¬ÇÒ ¼ö ÀÖÀ»¶§±îÁö ´Ù¸¥ + °´Ã¼¸¦ Á¦°ÅÇÑ´Ù. MCacheRemovalAlgorithmÀ¸·Î + ÁöÁ¤ÇÑ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© Á¦°ÅÇÒ °´Ã¼¸¦ ¼±ÅÃÇÑ´Ù.

    + + ¿¹Á¦ + MCacheSize 700000 + + + ÁÖÀÇ +

    MCacheSize °ªÀº MCacheMaxObjectSize + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªº¸´Ù Ä¿¾ß ÇÑ´Ù.

    +
    +
    +
    + + +MCacheMaxObjectCount +ij½¬¿¡ ÀúÀåÇÒ ¼ö ÀÖ´Â ÃÖ´ë °´Ã¼°³¼ö +MCacheMaxObjectCount value +MCacheMaxObjectCount 1009 +server config + + +

    MCacheMaxObjectCount Áö½Ã¾î´Â + ij½¬ÇÒ ¼ö ÀÖ´Â ÃÖ´ë °´Ã¼°³¼ö¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ °ªÀº Çؽ¬Å×À̺íÀ» + ¸¸µé¶§ »ç¿ëÇÑ´Ù. »õ·Î¿î °´Ã¼¸¦ ij½¬¿¡ Ãß°¡ÇØ¾ß Çϴµ¥ ÃÖ´ë + °´Ã¼°³¼ö¿¡ µµ´ÞÇÏ¿´´Ù¸é, »õ·Î¿î °´Ã¼¸¦ ij½¬ÇÒ ¼ö ÀÖµµ·Ï + ´Ù¸¥ °´Ã¼¸¦ Á¦°ÅÇÑ´Ù. MCacheRemovalAlgorithmÀ¸·Î + ÁöÁ¤ÇÑ ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© Á¦°ÅÇÒ °´Ã¼¸¦ ¼±ÅÃÇÑ´Ù.

    + + ¿¹Á¦ + MCacheMaxObjectCount 13001 + +
    +
    + + +MCacheMinObjectSize +ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼Ò Å©±â (¹ÙÀÌÆ® ´ÜÀ§) +MCacheMinObjectSize bytes +MCacheMinObjectSize 0 +server config + + +

    MCacheMinObjectSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼Ò Å©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + + ¿¹Á¦ + MCacheMinObjectSize 10000 + +
    +
    + + +MCacheMaxObjectSize +ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ë Å©±â (¹ÙÀÌÆ® ´ÜÀ§) +MCacheMaxObjectSize bytes +MCacheMaxObjectSize 10000 +server config + + +

    MCacheMaxObjectSize Áö½Ã¾î´Â ij½¬¿¡ + ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ë Å©±â¸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù.

    + + ¿¹Á¦ + MCacheMaxObjectSize 6400000 + + + Note +

    MCacheMaxObjectSize °ªÀº MCacheMinObjectSize + Áö½Ã¾î·Î ÁöÁ¤ÇÑ °ªº¸´Ù Ä¿¾ß ÇÑ´Ù.

    +
    +
    +
    + + +MCacheRemovalAlgorithm +ij½¬¿¡¼­ Á¦°ÅÇÒ ¹®¼­¸¦ ã´Â ¾Ë°í¸®Áò +MCacheRemovalAlgorithm LRU|GDSF +MCacheRemovalAlgorithm GDSF +server config + + +

    MCacheRemovalAlgorithm Áö½Ã¾î´Â + ij½¬¿¡¼­ Á¦°ÅÇÒ ¹®¼­¸¦ ã´Â ¾Ë°í¸®ÁòÀ» ÁöÁ¤ÇÑ´Ù.

    + +
    +
    LRU (Least Recently Used)
    +
    LRU´Â °¡Àå ¿À·¡µ¿¾È Á¢±ÙÇÏÁö ¾ÊÀº ¹®¼­¸¦ + ¸ÕÀú Á¦°ÅÇÑ´Ù.
    + +
    GDSF (GreadyDual-Size)
    +
    GDSF´Â ij½¬ ½ÇÆÐ(cache miss) ºñ¿ë°ú ¹®¼­ÀÇ + Å©±â¸¦ °¡Áö°í ij½¬ÇÑ ¹®¼­¿¡ ¿ì¼±¼øÀ§¸¦ ºÎ¿©ÇÑ´Ù. °¡Àå + ¿ì¼±¼øÀ§°¡ ³·Àº ¹®¼­¸¦ ¸ÕÀú Á¦°ÅÇÑ´Ù.
    +
    + + ¿¹Á¦ + MCacheRemovalAlgorithm GDSF
    + MCacheRemovalAlgorithm LRU +
    +
    +
    + + +MCacheMaxStreamingBuffer +ÀÀ´äÀ» ij½¬¾ÈÇÑ´Ù°í °áÁ¤Çϱâ Àü±îÁö ¸Þ¸ð¸® ¹öÆÛ¿¡ +ÀúÀåÇÒ ½ºÆ®¸² ÀÀ´äÀÇ ÃÖ´ë Å©±â +MCacheMaxStreamingBuffer size_in_bytes +MCacheMaxStreamingBuffer 100000°ú MCacheMaxObjectSize +Áß¿¡ ÀÛÀº °ª +server config + + + +

    MCacheMaxStreamingBuffer Áö½Ã¾î´Â + ÀÀ´äÀÌ ³Ê¹« Ä¿¼­ ij½¬ÇÒ ¼ö ¾øÀ»¶§±îÁö ¹öÆÛ¿¡ ÀúÀåÇÒ ½ºÆ®¸² + ÀÀ´äÀÇ ÃÖ´ë ¹ÙÀÌÆ®¼ö¸¦ ¼³Á¤ÇÑ´Ù. ½ºÆ®¸² ÀÀ´ä(streamed response)Àº + Àüü ³»¿ëÀ» Áï½Ã ¾Ë ¼ö ¾ø°í Content-Lengthµµ + ¸ð¸£´Â ÀÀ´äÀÌ´Ù. ÇÁ·Ï½ÃµÈ ÀÀ´äÀ̳ª CGI ½ºÅ©¸³Æ®ÀÇ Ãâ·ÂÀÌ + ½ºÆ®¸² ÀÀ´ä¿¡ ¼ÓÇÑ´Ù. ±âº»ÀûÀ¸·Î Content-Length + Çì´õ°¡ ¾ø´Ù¸é ½ºÆ®¸² ÀÀ´äÀ» ij½¬¿¡ ÀúÀåÇÏÁö ¾Ê´Â´Ù. + ÀÌÀ¯´Â ij½¬¿¡ ÀúÀåÇϱ⿡ ³Ê¹« Å« ÀÀ´äÀÇ ÀϺθ¦ ¹öÆÛ¿¡ + ÀúÀåÇϱâÀ§ÇØ ¸¹Àº ¸Þ¸ð¸®¸¦ ³¶ºñÇÏÁö ¾Ê±âÀ§Çؼ­ÀÌ´Ù. + MCacheMaxStreamingBuffer Áö½Ã¾î¸¦ + »ç¿ëÇϸé Content-Length°¡ ¾ø´Â ½ºÆ®¸² ÀÀ´äÀ» + ÁöÁ¤ÇÑ Å©±â±îÁö¸¸ ¹öÆÛ¿¡ ÀúÀåÇÑ´Ù. ÃÖ´ë Å©±â¸¦ ³Ñ¾î¼­¸é + ¹öÆÛ ³»¿ëÀ» ¹ö¸®°í ij½¬ÇÏÁö ¾Ê´Â´Ù.

    + + ÁÖÀÇ: +

    MCacheMaxStreamingBuffer¿¡ 0ÀÌ + ¾Æ´Ñ °ªÀ» ¼³Á¤ÇÏ¿©µµ Ŭ¶óÀ̾ðÆ®·Î ÀÀ´äÀ» ´Ê°Ô º¸³»Áö ¾Ê´Â´Ù. + mod_mem_cache´Â ½ºÆ®¸² ÀÀ´äÀÇ ÀϺθ¦ + ¹öÆÛ¿¡ º¹»çÇÏÀÚ¸¶ÀÚ Å¬¶óÀ̾ðÆ®·Î º¸³»±âÀ§ÇØ ´ÙÀ½ Ãâ·ÂÇÊÅÍ·Î + º¸³½´Ù.

    +
    + + + # ½ºÆ®¸² ÀÀ´äÀ» 64KB±îÁö ij½¬ÇÑ´Ù:
    + MCacheMaxStreamingBuffer 65536 +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_mem_cache.xml.meta b/trunk/docs/manual/mod/mod_mem_cache.xml.meta new file mode 100644 index 0000000000..c3315de313 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mem_cache.xml.meta @@ -0,0 +1,13 @@ + + + + mod_mem_cache + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_mime.html b/trunk/docs/manual/mod/mod_mime.html new file mode 100644 index 0000000000..09e9184ea0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.html @@ -0,0 +1,7 @@ +URI: mod_mime.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_mime.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_mime.html.en b/trunk/docs/manual/mod/mod_mime.html.en new file mode 100644 index 0000000000..00a963d067 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.html.en @@ -0,0 +1,938 @@ + + + +mod_mime - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_mime

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    Description:Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding)
    Status:Base
    Module Identifier:mime_module
    Source File:mod_mime.c
    +

    Summary

    + +

    This module is used to associate various bits of "meta + information" with files by their filename extensions. This + information relates the filename of the document to it's + mime-type, language, character set and encoding. This + information is sent to the browser, and participates in content + negotiation, so the user's preferences are respected when + choosing one of several possible files to serve. See + mod_negotiation for more information + about content negotiation.

    + +

    The directives AddCharset, AddEncoding, AddLanguage and AddType are all used to map file + extensions onto the meta-information for that file. Respectively + they set the character set, content-encoding, content-language, + and MIME-type (content-type) of documents. The directive TypesConfig is used to specify a + file which also maps extensions onto MIME types.

    + +

    In addition, mod_mime may define the handler and filters that originate and process + content. The directives AddHandler, AddOutputFilter, and AddInputFilter control the modules + or scripts that serve the document. The MultiviewsMatch directive allows + mod_negotiation to consider these file extensions + to be included when testing Multiviews matches.

    + +

    While mod_mime associates meta-information + with filename extensions, the core server + provides directives that are used to associate all the files in a + given container (e.g., <Location>, <Directory>, or <Files>) with particular + meta-information. These directives include ForceType, SetHandler, SetInputFilter, and SetOutputFilter. The core directives + override any filename extension mappings defined in + mod_mime.

    + +

    Note that changing the meta-information for a file does not + change the value of the Last-Modified header. + Thus, previously cached copies may still be used by a client or + proxy, with the previous headers. If you change the + meta-information (language, content type, character set or + encoding) you may need to 'touch' affected files (updating + their last modified date) to ensure that all visitors are + receive the corrected content headers.

    +
    + +
    top
    +
    +

    Files with Multiple Extensions

    +

    Files can have more than one extension, and the order of the + extensions is normally irrelevant. For example, if the + file welcome.html.fr maps onto content type + text/html and language French then the file + welcome.fr.html will map onto exactly the same information. + If more than one extension is given which maps onto the same + type of meta-information, then the one to the right will be + used, except for languages and content encodings. For example, if + .gif maps to the MIME-type image/gif and + .html maps to the MIME-type text/html, then the + file welcome.gif.html will be associated with the MIME-type + text/html.

    + +

    Languages and content encodings are treated accumulative, because one can assign + more than one language or encoding to a particular ressource. For example, + the file welcome.html.en.de will be delivered with + Content-Language: en, de and Content-Type: + text/html.

    + +

    Care should be taken when a file with multiple extensions + gets associated with both a MIME-type and a handler. This will + usually result in the request being by the module associated + with the handler. For example, if the .imap + extension is mapped to the handler imap-file (from + mod_imagemap) and the .html extension is + mapped to the MIME-type text/html, then the file + world.imap.html will be associated with both the + imap-file handler and text/html MIME-type. + When it is processed, the imap-file handler will be used, + and so it will be treated as a mod_imagemap imagemap + file.

    +
    top
    +
    +

    Content encoding

    +

    A file of a particular MIME type can additionally be encoded a + particular way to simplify transmission over the Internet. + While this usually will refer to compression, such as + gzip, it can also refer to encryption, such a + pgp or to an encoding such as UUencoding, which is + designed for transmitting a binary file in an ASCII (text) + format.

    + +

    The HTTP/1.1 + RFC, section 14.11 puts it this way:

    + +
    +

    The Content-Encoding entity-header field is used as a modifier to + the media-type. When present, its value indicates what additional + content codings have been applied to the entity-body, and thus what + decoding mechanisms must be applied in order to obtain the media-type + referenced by the Content-Type header field. Content-Encoding is + primarily used to allow a document to be compressed without losing + the identity of its underlying media type.

    +
    + +

    By using more than one file extension (see section above about multiple file + extensions), you can indicate that a file is of a + particular type, and also has a particular + encoding.

    + +

    For example, you may have a file which is a Microsoft Word + document, which is pkzipped to reduce its size. If the + .doc extension is associated with the Microsoft + Word file type, and the .zip extension is + associated with the pkzip file encoding, then the file + Resume.doc.zip would be known to be a pkzip'ed Word + document.

    + +

    Apache sends a Content-encoding header with the + resource, in order to tell the client browser about the + encoding method.

    + +

    Content-encoding: pkzip

    +
    top
    +
    +

    Character sets and languages

    +

    In addition to file type and the file encoding, + another important piece of information is what language a + particular document is in, and in what character set the file + should be displayed. For example, the document might be written + in the Vietnamese alphabet, or in Cyrillic, and should be + displayed as such. This information, also, is transmitted in + HTTP headers.

    + +

    The character set, language, encoding and mime type are all + used in the process of content negotiation (See + mod_negotiation) to determine + which document to give to the client, when there are + alternative documents in more than one character set, language, + encoding or mime type. All filename extensions associations + created with AddCharset, + AddEncoding, AddLanguage and AddType directives + (and extensions listed in the MimeMagicFile) participate in this select process. + Filename extensions that are only associated using the AddHandler, AddInputFilter or AddOutputFilter directives may be included or excluded + from matching by using the MultiviewsMatch directive.

    + +

    Charset

    +

    To convey this further information, Apache optionally sends + a Content-Language header, to specify the language + that the document is in, and can append additional information + onto the Content-Type header to indicate the + particular character set that should be used to correctly + render the information.

    + +

    + Content-Language: en, fr
    + Content-Type: text/plain; charset=ISO-8859-1 +

    + +

    The language specification is the two-letter abbreviation + for the language. The charset is the name of the + particular character set which should be used.

    + +
    +
    top
    +

    AddCharset Directive

    + + + + + + + +
    Description:Maps the given filename extensions to the specified content +charset
    Syntax:AddCharset charset extension +[extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The AddCharset directive maps the given + filename extensions to the specified content charset. charset + is the MIME + charset parameter of filenames containing + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + +

    Example

    + AddLanguage ja .ja
    + AddCharset EUC-JP .euc
    + AddCharset ISO-2022-JP .jis
    + AddCharset SHIFT_JIS .sjis +

    + +

    Then the document xxxx.ja.jis will be treated + as being a Japanese document whose charset is ISO-2022-JP + (as will the document xxxx.jis.ja). The + AddCharset directive is useful for both to + inform the client about the character encoding of the document so that + the document can be interpreted and displayed appropriately, and for content negotiation, + where the server returns one from several documents based on + the client's charset preference.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    AddEncoding Directive

    + + + + + + + +
    Description:Maps the given filename extensions to the specified encoding +type
    Syntax:AddEncoding MIME-enc extension +[extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The AddEncoding directive maps the given + filename extensions to the specified encoding type. MIME-enc + is the MIME encoding to use for documents containing the + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + +

    Example

    + AddEncoding x-gzip .gz
    + AddEncoding x-compress .Z +

    + +

    This will cause filenames containing the .gz extension + to be marked as encoded using the x-gzip encoding, and + filenames containing the .Z extension to be marked as + encoded with x-compress.

    + +

    Old clients expect x-gzip and x-compress, + however the standard dictates that they're equivalent to + gzip and compress respectively. Apache does + content encoding comparisons by ignoring any leading x-. + When responding with an encoding Apache will use whatever form + (i.e., x-foo or foo) the + client requested. If the client didn't specifically request a + particular form Apache will use the form given by the + AddEncoding directive. To make this long story + short, you should always use x-gzip and + x-compress for these two specific encodings. More + recent encodings, such as deflate should be + specified without the x-.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +
    +
    top
    +

    AddHandler Directive

    + + + + + + + +
    Description:Maps the filename extensions to the specified +handler
    Syntax:AddHandler handler-name extension +[extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    Files having the name extension will be served by the + specified handler-name. This + mapping is added to any already in force, overriding any mappings that + already exist for the same extension. For example, to + activate CGI scripts with the file extension .cgi, you + might use:

    + +

    + AddHandler cgi-script .cgi +

    + +

    Once that has been put into your httpd.conf file, any file containing + the .cgi extension will be treated as a CGI program.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    AddInputFilter Directive

    + + + + + + + + +
    Description:Maps filename extensions to the filters that will process +client requests
    Syntax:AddInputFilter filter[;filter...] +extension [extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:AddInputFilter is only available in Apache 2.0.26 and +later.
    +

    AddInputFilter maps the filename extension + extension to the filters which + will process client requests and POST input when they are received by + the server. This is in addition to any filters defined elsewhere, + including the SetInputFilter + directive. This mapping is merged over any already in force, overriding + any mappings that already exist for the same extension.

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content. Both the filter and extension arguments are + case-insensitive, and the extension may be specified with or + without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    AddLanguage Directive

    + + + + + + + +
    Description:Maps the given filename extension to the specified content +language
    Syntax:AddLanguage MIME-lang extension +[extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The AddLanguage directive maps the given + filename extension to the specified content language. + MIME-lang is the MIME language of filenames containing + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + +

    Example

    + AddEncoding x-compress .Z
    + AddLanguage en .en
    + AddLanguage fr .fr +

    + +

    Then the document xxxx.en.Z will be treated as + being a compressed English document (as will the document + xxxx.Z.en). Although the content language is + reported to the client, the browser is unlikely to use this + information. The AddLanguage directive is + more useful for content + negotiation, where the server returns one from several documents + based on the client's language preference.

    + +

    If multiple language assignments are made for the same + extension, the last one encountered is the one that is used. + That is, for the case of:

    + +

    + AddLanguage en .en
    + AddLanguage en-gb .en
    + AddLanguage en-us .en +

    + +

    documents with the extension .en would be treated as + being en-us.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    AddOutputFilter Directive

    + + + + + + + + +
    Description:Maps filename extensions to the filters that will process +responses from the server
    Syntax:AddOutputFilter filter[;filter...] +extension [extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:AddOutputFilter is only available in Apache 2.0.26 and +later.
    +

    The AddOutputFilter directive maps the + filename extension extension to the filters which will process responses + from the server before they are sent to the client. This is in + addition to any filters defined elsewhere, including SetOutputFilter and AddOutputFilterByType directive. This mapping is merged + over any already in force, overriding any mappings that already exist + for the same extension.

    + +

    For example, the following configuration will process all + .shtml files for server-side includes and will then + compress the output using mod_deflate.

    + +

    + AddOutputFilter INCLUDES;DEFLATE shtml +

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content. Both the filter and extension arguments + are case-insensitive, and the extension may be specified with or + without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    AddType Directive

    + + + + + + + +
    Description:Maps the given filename extensions onto the specified content +type
    Syntax:AddType MIME-type extension +[extension] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The AddType directive maps the given filename + extensions onto the specified content type. MIME-type is the + MIME type to use for filenames containing extension. This + mapping is added to any already in force, overriding any mappings that + already exist for the same extension. This directive can + be used to add mappings not listed in the MIME types file (see the + TypesConfig directive).

    + +

    Example

    + AddType image/gif .gif +

    + +
    + It is recommended that new MIME types be added using the + AddType directive rather than changing the + TypesConfig file. +
    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    DefaultLanguage Directive

    + + + + + + + +
    Description:Sets all files in the given scope to the specified +language
    Syntax:DefaultLanguage MIME-lang
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The DefaultLanguage directive tells Apache + that all files in the directive's scope (e.g., all files + covered by the current <Directory> container) that don't have an explicit language + extension (such as .fr or .de as configured + by AddLanguage) should be + considered to be in the specified MIME-lang language. This + allows entire directories to be marked as containing Dutch content, for + instance, without having to rename each file. Note that unlike using + extensions to specify languages, DefaultLanguage + can only specify a single language.

    + +

    If no DefaultLanguage directive is in force, + and a file does not have any language extensions as configured + by AddLanguage, then that file + will be considered to have no language attribute.

    + +

    Example

    + DefaultLanguage en +

    + +

    See also

    + +
    +
    top
    +

    ModMimeUsePathInfo Directive

    + + + + + + + + +
    Description:Tells mod_mime to treat path_info +components as part of the filename
    Syntax:ModMimeUsePathInfo On|Off
    Default:ModMimeUsePathInfo Off
    Context:directory
    Status:Base
    Module:mod_mime
    Compatibility:Available in Apache 2.0.41 and later
    +

    The ModMimeUsePathInfo directive is used to + combine the filename with the path_info URL component to + apply mod_mime's directives to the request. The default + value is Off - therefore, the path_info + component is ignored.

    + +

    This directive is recommended when you have a virtual filesystem.

    + +

    Example

    + ModMimeUsePathInfo On +

    + +

    If you have a request for /bar/foo.shtml where + /bar is a Location and ModMimeUsePathInfo is On, + mod_mime will treat the incoming request as + /bar/foo.shtml and directives like AddOutputFilter + INCLUDES .shtml will add the INCLUDES filter to the + request. If ModMimeUsePathInfo is not set, the + INCLUDES filter will not be added.

    + +

    See also

    + +
    +
    top
    +

    MultiviewsMatch Directive

    + + + + + + + + + +
    Description:The types of files that will be included when searching for +a matching file with MultiViews
    Syntax:MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters]
    Default:MultiviewsMatch NegotiatedOnly
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:Available in Apache 2.0.26 and later.
    +

    MultiviewsMatch permits three different + behaviors for mod_negotiation's + Multiviews feature. Multiviews allows a request for a file, + e.g. index.html, to match any negotiated + extensions following the base request, e.g. + index.html.en, index.html.fr, or + index.html.gz.

    + +

    The NegotiatedOnly option provides that every extension + following the base name must correlate to a recognized + mod_mime extension for content negotation, e.g. + Charset, Content-Type, Language, or Encoding. This is the strictest + implementation with the fewest unexpected side effects, and is the + default behavior.

    + +

    To include extensions associated with Handlers and/or Filters, + set the MultiviewsMatch directive to either + Handlers, Filters, or both option keywords. + If all other factors are equal, the smallest file will be served, + e.g. in deciding between index.html.cgi of 500 + bytes and index.html.pl of 1000 bytes, the .cgi + file would win in this example. Users of .asis files + might prefer to use the Handler option, if .asis files are + associated with the asis-handler.

    + +

    You may finally allow Any extensions to match, even if + mod_mime doesn't recognize the extension. This was the + behavior in Apache 1.3, and can cause unpredicatable results, such as + serving .old or .bak files the webmaster never expected to be served.

    + +

    For example, the following configuration will allow handlers + and filters to participate in Multviews, but will exclude unknown + files:

    + +

    + MultiviewsMatch Handlers Filters +

    + +

    See also

    + +
    +
    top
    +

    RemoveCharset Directive

    + + + + + + + + +
    Description:Removes any character set associations for a set of file +extensions
    Syntax:RemoveCharset extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:RemoveCharset is only available in Apache 2.0.24 and +later.
    +

    The RemoveCharset directive removes any + character set associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    Example

    + RemoveCharset .html .shtml +

    + +
    +
    top
    +

    RemoveEncoding Directive

    + + + + + + + +
    Description:Removes any content encoding associations for a set of file +extensions
    Syntax:RemoveEncoding extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The RemoveEncoding directive removes any + encoding associations for files with the given extensions. This + allows .htaccess files in subdirectories to undo + any associations inherited from parent directories or the + server config files. An example of its use might be:

    + +

    /foo/.htaccess:

    + AddEncoding x-gzip .gz
    + AddType text/plain .asc
    + <Files *.gz.asc>
    + + RemoveEncoding .gz
    +
    + </Files> +

    + +

    This will cause foo.gz to be marked as being + encoded with the gzip method, but foo.gz.asc as an + unencoded plaintext file.

    + +

    Note

    +

    RemoveEncoding directives are processed + after any AddEncoding + directives, so it is possible they may undo the effects of the latter + if both occur within the same directory configuration.

    +
    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +
    +
    top
    +

    RemoveHandler Directive

    + + + + + + + +
    Description:Removes any handler associations for a set of file +extensions
    Syntax:RemoveHandler extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The RemoveHandler directive removes any + handler associations for files with the given extensions. This allows + .htaccess files in subdirectories to undo any + associations inherited from parent directories or the server + config files. An example of its use might be:

    + +

    /foo/.htaccess:

    + AddHandler server-parsed .html +

    + +

    /foo/bar/.htaccess:

    + RemoveHandler .html +

    + +

    This has the effect of returning .html files in + the /foo/bar directory to being treated as normal + files, rather than as candidates for parsing (see the mod_include module).

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +
    +
    top
    +

    RemoveInputFilter Directive

    + + + + + + + + +
    Description:Removes any input filter associations for a set of file +extensions
    Syntax:RemoveInputFilter extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:RemoveInputFilter is only available in Apache 2.0.26 and +later.
    +

    The RemoveInputFilter directive removes any + input filter associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    See also

    + +
    +
    top
    +

    RemoveLanguage Directive

    + + + + + + + + +
    Description:Removes any language associations for a set of file +extensions
    Syntax:RemoveLanguage extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:RemoveLanguage is only available in Apache 2.0.24 and +later.
    +

    The RemoveLanguage directive removes any + language associations for files with the given extensions. This + allows .htaccess files in subdirectories to undo + any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +
    +
    top
    +

    RemoveOutputFilter Directive

    + + + + + + + + +
    Description:Removes any output filter associations for a set of file +extensions
    Syntax:RemoveOutputFilter extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    Compatibility:RemoveOutputFilter is only available in Apache 2.0.26 and +later.
    +

    The RemoveOutputFilter directive removes any + output filter associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +

    Example

    + RemoveOutputFilter shtml +

    + +

    See also

    + +
    +
    top
    +

    RemoveType Directive

    + + + + + + + +
    Description:Removes any content type associations for a set of file +extensions
    Syntax:RemoveType extension [extension] +...
    Context:virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_mime
    +

    The RemoveType directive removes any MIME + type associations for files with the given extensions. This allows + .htaccess files in subdirectories to undo any + associations inherited from parent directories or the server + config files. An example of its use might be:

    + +

    /foo/.htaccess:

    + RemoveType .cgi +

    + +

    This will remove any special handling of .cgi + files in the /foo/ directory and any beneath it, + causing the files to be treated as being of the DefaultType.

    + +

    Note

    +

    RemoveType directives are processed + after any AddType + directives, so it is possible they may undo the effects of the + latter if both occur within the same directory configuration.

    +
    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + +
    +
    top
    +

    TypesConfig Directive

    + + + + + + + +
    Description:The location of the mime.types file
    Syntax:TypesConfig file-path
    Default:TypesConfig conf/mime.types
    Context:server config
    Status:Base
    Module:mod_mime
    +

    The TypesConfig directive sets the location + of the MIME types configuration file. File-path is relative + to the ServerRoot. This file sets + the default list of mappings from filename extensions to content + types. Most administrators use the provided mime.types + file, which associates common filename extensions with IANA registered + content types. The current list is maintained at http://www.isi.edu/in-notes/iana/assignments/media-types/media-types. + This simplifies the httpd.conf file by providing the + majority of media-type definitions, and may be overridden by + AddType directives as + needed. You should not edit the mime.types file, because + it may be replaced when you upgrade your server.

    + +

    The file contains lines in the format of the arguments to + an AddType directive:

    + +

    + MIME-type [extension] ... +

    + +

    The case of the extension does not matter. Blank lines, and lines + beginning with a hash character (#) are ignored.

    + +
    + Please do not send requests to the Apache HTTP + Server Project to add any new entries in the distributed + mime.types file unless (1) they are already + registered with IANA, and (2) they use widely accepted, + non-conflicting filename extensions across platforms. + category/x-subtype requests will be automatically + rejected, as will any new two-letter extensions as they will + likely conflict later with the already crowded language and + character set namespace. +
    + +

    See also

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mime.html.ja.euc-jp b/trunk/docs/manual/mod/mod_mime.html.ja.euc-jp new file mode 100644 index 0000000000..cf71109e6a --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.html.ja.euc-jp @@ -0,0 +1,937 @@ + + + +mod_mime - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_mime

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤È¥Õ¥¡¥¤¥ë¤Î¿¶¤ëÉñ¤¤ + (¥Ï¥ó¥É¥é¤È¥Õ¥£¥ë¥¿)¡¢ÆâÍÆ (MIME ¥¿¥¤¥×¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°) + ¤È¤ò´ØÏ¢ÉÕ¤±¤ë
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:mime_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_mime.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï³ÈÄ¥»Ò¤ò»È¤Ã¤Æ¤¤¤í¤¤¤í¤Ê¡Ö¥á¥¿¾ðÊó¡×¤ò¥Õ¥¡¥¤¥ë¤Ë + ´ØÏ¢ÉÕ¤±¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£¤³¤Î¾ðÊó¤Ï¥É¥­¥å¥á¥ó¥È¤Î¥Õ¥¡¥¤¥ë̾¤È + MIME ¥¿¥¤¥×¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤È¤ò´ØÏ¢ÉÕ¤±¤Þ¤¹¡£ + ¤³¤Î¾ðÊó¤Ï¥Ö¥é¥¦¥¶¤ËÁ÷¤é¤ì¤Þ¤¹¤·¡¢Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¤ÎÃ椫¤é¥æ¡¼¥¶¤Î¹¥¤ß¤Î + ¤â¤Î¤¬Áª¤Ð¤ì¤ë¤è¤¦¤Ë¡¢¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ç¤â»È¤ï¤ì¤Þ¤¹¡£ + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + ¤Ë´Ø¤¹¤ë¾Ü¤·¤¤¾ðÊó¤Ï mod_negotiation + ¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    AddCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + AddEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + AddHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + AddLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + AddType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¹¤Ù¤Æ¡¢ + ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤ò¥á¥¿¾ðÊó¤Ë¥Þ¥Ã¥×¤¹¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£ + ¤½¤ì¤¾¤ì¡¢¥É¥­¥å¥á¥ó¥È¤Îʸ»ú¥»¥Ã¥È (ÌõÃí: charset)¡¢content-encoding, + content-language, MIME ¥¿¥¤¥× (content-type) ¤òÀßÄꤷ¤Þ¤¹¡£ + TypesConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï³ÈÄ¥»Ò¤ò + MIME ¥¿¥¤¥×¤Ë¥Þ¥Ã¥×¤¹¤ë¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£

    + +

    ¤µ¤é¤Ë¡¢mod_mime ¤Ï¥³¥ó¥Æ¥ó¥Ä¤òºîÀ®¡¢½èÍý¤¹¤ë + ¥Ï¥ó¥É¥é ¤È ¥Õ¥£¥ë¥¿ + ¤òÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£AddHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢AddOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢AddInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥É¥­¥å¥á¥ó¥È¤ò°·¤¦¥â¥¸¥å¡¼¥ë¤ä¥¹¥¯¥ê¥×¥È¤òÀ©¸æ¤·¤Þ¤¹¡£ + MultiviewsMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»ØÄꤷ¤¿¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤ò + mod_negotiation ¤¬ Multiviews ¤Î¥Þ¥Ã¥Á¤ò¤È¤ë¤È¤­¤Ë + ¹Íθ¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    mod_mime ¤Ï¥á¥¿¾ðÊó¤ò¥Õ¥¡¥¤¥ë̾¤È´ØÏ¢ÉÕ¤±¤Þ¤¹¤¬¡¢ + core ¥µ¡¼¥Ð¤Ë¤Ï¤¢¤ë¥³¥ó¥Æ¥Ê + (¤¿¤È¤¨¤Ð, <Location>, <Directory>, <Files>) ¤ÎÃæ¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤òÆÃÄê¤Î + ¥á¥¿¾ðÊó¤È´ØÏ¢ÉÕ¤±¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ï + ForceType, SetHandler, SetInputFilter, SetOutputFilter ¤¬¤¢¤ê¤Þ¤¹¡£ + ¥³¥¢¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï mod_mime ¤Ë¤è¤êÄêµÁ¤µ¤ì¤¿ + ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤Î¥Þ¥Ã¥Ô¥ó¥°¤¹¤Ù¤Æ¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    ¥Õ¥¡¥¤¥ë¤Î¥á¥¿¾ðÊó¤òÊѤ¨¤Æ¤â Last-Modified + ¥Ø¥Ã¥À¤ÎÃͤÏÊѤï¤é¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Ç¤¹¤«¤é¡¢ + ¤½¤ì¤é¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤ä¥×¥í¥­¥·¤Ç°ÊÁ°¤Ë¥­¥ã¥Ã¥·¥å¤µ¤ì¤¿ + ¥³¥Ô¡¼¤¬¤½¤Î¤È¤­¤Î¥Ø¥Ã¥À¤È¤È¤â¤Ë»È¤ï¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ + ¥á¥¿¾ðÊó (¸À¸ì¡¢¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¡¢Ê¸»ú¥»¥Ã¥È¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°) ¤ò + Êѹ¹¤·¤¿¤È¤­¤Ï¡¢¤¹¤Ù¤Æ¤ÎˬÌä¼Ô¤¬Àµ¤·¤¤¥³¥ó¥Æ¥ó¥È¥Ø¥Ã¥À¤ò + ¼õ¤±¼è¤ë¤è¤¦¤Ë¡¢±Æ¶Á¤ò¼õ¤±¤ë¥Õ¥¡¥¤¥ë¤Ë 'touch' ¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë + (ºÇ½ª¹¹¿·Æü¤ò¹¹¿·¤¹¤ë) ɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    Ê£¿ô¤Î³ÈÄ¥»Ò¤Î¤¢¤ë¥Õ¥¡¥¤¥ë

    +

    ¥Õ¥¡¥¤¥ë¤ÏÊ£¿ô¤Î³ÈÄ¥»Ò¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¡¢³ÈÄ¥»Ò¤Î½çÈÖ¤ÏÄ̾ï¤Ï´Ø·¸¤¢¤ê¤Þ¤»¤ó¡£Î㤨¤Ð¡¢¥Õ¥¡¥¤¥ë welcome.html.fr + ¤¬¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ï text/html + ¤Ë¡¢¸À¸ì¤Ï¥Õ¥é¥ó¥¹¸ì¤Ë¥Þ¥Ã¥×¤µ¤ì¤ë¾ì¹ç¡¢welcome.fr.html + ¤â¤Þ¤Ã¤¿¤¯Æ±¤¸¾ðÊó¤Ë¥Þ¥Ã¥×¤µ¤ì¤Þ¤¹¡£ + Ʊ¤¸¥á¥¿¾ðÊó¤Ë¥Þ¥Ã¥×¤µ¤ì¤ë³ÈÄ¥»Ò¤¬Ê£¿ô¤¢¤ë¤È¤­¤Ë¤Ï¡¢¸À¸ì¤È + ¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò½ü¤¤¤Æ¡¢ + ±¦Â¦¤Ë¤¢¤ë¤â¤Î¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢.gif ¤¬ MIME + ¥¿¥¤¥× image/gif ¤Ë¥Þ¥Ã¥×¤µ¤ì¡¢.html + ¤¬ MIME ¥¿¥¤¥× text/html + ¤Ë¥Þ¥Ã¥×¤µ¤ì¤ë¾ì¹ç¤Ï¡¢¥Õ¥¡¥¤¥ë welcome.gif.html ¤Ï + MIME ¥¿¥¤¥× text/html ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤Þ¤¹¡£

    + +

    ¥ê¥½¡¼¥¹¤ËÊ£¿ô¤Î¸À¸ì¤ä¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò´ØÏ¢ÉÕ¤±¤ë¤³¤È + ¤¬¤Ç¤­¤ë¤¿¤á¡¢ + ¸À¸ì¤È¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ÏÁ°¤Î¤â¤Î¤ËÄɲ䵤ì¤Æ¤¤¤­¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢¥Õ¥¡¥¤¥ë welcome.html.en.de ¤Ï + Content-Language: en, de ¤È Content-Type: + text/html ¤È¤·¤ÆÁ÷¿®¤µ¤ì¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î³ÈÄ¥»Ò¤Î¤¢¤ë¥Õ¥¡¥¤¥ë¤¬ MIME + ¥¿¥¤¥×¤È¥Ï¥ó¥É¥é¤ÎξÊý¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¤È¤­¤ÏÃí°Õ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤Î¾ì¹ç¡¢ÉáÄ̤ϥꥯ¥¨¥¹¥È¤¬¥Ï¥ó¥É¥é¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿ + ¥â¥¸¥å¡¼¥ë¤Ë¤è¤Ã¤Æ°·¤ï¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢³ÈÄ¥»Ò + .imap ¤¬ (mod_imagemap ¤Î) imap-file + ¤Ë¥Þ¥Ã¥×¤µ¤ì¤Æ¤¤¤Æ¡¢.html ¤¬ MIME ¥¿¥¤¥× text/html + ¤Ë¥Þ¥Ã¥×¤µ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢¥Õ¥¡¥¤¥ë world.imap.html ¤Ï + imap-file ¥Ï¥ó¥É¥é¤È text/html MIME + ¥¿¥¤¥×¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤¬½èÍý¤µ¤ì¤ë¤È¤­¤Ï imap-file + ¥Ï¥ó¥É¥é¤¬»ÈÍѤµ¤ì¤Þ¤¹¤Î¤Ç¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤Ï mod_imagemap + ¤Î¥¤¥á¡¼¥¸¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤È¤·¤Æ°·¤ï¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    ¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°

    +

    ÆÃÄê¤Î MIME ¥¿¥¤¥×¤Î¥Õ¥¡¥¤¥ë¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ç¤ÎžÁ÷¤ò´Êñ¤Ë¤¹¤ë¤¿¤á¤Ë¡¢ + ¤µ¤é¤ËÉä¹æ²½¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤ÏÄ̾ï¤Ï gzip ¤Î + ¤è¤¦¤Ê°µ½Ì¤Î¤³¤È¤ò»Ø¤·¤Þ¤¹¤¬¡¢pgp ¤Î¤è¤¦¤Ê°Å¹æ²½¤ä¡¢ + ¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤ò ASCII (¥Æ¥­¥¹¥È) ·Á¼°¤ÇÁ÷¤ë¤¿¤á¤Ë¹Í°Æ¤µ¤ì¤¿ + UUencoding ¤Î¤³¤È¤ò»Ø¤¹¤³¤È¤â¤¢¤ê¤Þ¤¹¡£

    + +

    HTTP/1.1 RFC + 14.11 Àá¤Ç¤Ï¼¡¤Î¤è¤¦¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +
    +

    Content-Encoding ¥¨¥ó¥Æ¥£¥Æ¥£¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Ï¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î + ½¤¾þ»Ò¤È¤·¤Æ»È¤ï¤ì¤Þ¤¹¡£¤½¤ì¤¬Â¸ºß¤·¤Æ¤¤¤ì¤Ð¡¢Ãͤϥ¨¥ó¥Æ¥£¥Æ¥£¥Ü¥Ç¥£¤Ë + ¤É¤ÎÄɲäÎÉä¹æ²½¤¬Å¬ÍѤµ¤ì¤¿¤«¤ò¼¨¤·¡¢Content-Type ¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Ë + ½ñ¤«¤ì¤Æ¤¤¤ë¥á¥Ç¥£¥¢¥¿¥¤¥×¤òÆÀ¤ë¤¿¤á¤Ë¤É¤ÎÉü¹æµ¡¹½¤òŬÍѤ¹¤Ù¤­¤«¡¢¤â + ¼¨¤·¤Æ¤¤¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£Content-Encoding ¤Ï¼ç¤Ë¡¢¸µ¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î + Ʊ°ìÀ­¤ò¼º¤¦¤³¤È¤Ê¤¯¥É¥­¥å¥á¥ó¥È¤ò°µ½Ì¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤¹¤ë¤¿¤á¤Ë + »ÈÍѤµ¤ì¤Þ¤¹¡£

    +
    + +

    Ê£¿ô¤Î¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò (Ê£¿ô¤Î³ÈÄ¥»Ò¤Ë¤Ä¤¤¤Æ¤Ï ¾å¤ÎÀá ¤ò»²¾È) »È¤¦¤³¤È¤Ç¡¢ + ¥Õ¥¡¥¤¥ë¤Î¥¿¥¤¥×¤ä¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ØÄꤹ¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +

    ¤¿¤È¤¨¤Ð¡¢Microsoft Word ¤Î¥É¥­¥å¥á¥ó¥È¤¬¤¢¤ê¡¢¥µ¥¤¥º¤ò¾®¤µ¤¯¤¹¤ë¤¿¤á¤Ë + pkzip ¤µ¤ì¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£.doc ³ÈÄ¥»Ò¤¬ Microsoft Word ¤Î + ¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤Æ¡¢.zip ³ÈÄ¥»Ò¤¬ + pkzip ¥Õ¥¡¥¤¥ë¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¤È¡¢¥Õ¥¡¥¤¥ë + Resume.doc.zip ¤Ï pkzip ¤µ¤ì¤¿ Word ¥É¥­¥å¥á¥ó¥È¤Ç¤¢¤ë + ¤È¤¤¤¦¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£

    + +

    ¥¯¥é¥¤¥¢¥ó¥È¤Î¥Ö¥é¥¦¥¶¤Ë¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°ÊýË¡¤òÃΤ餻¤ë¤¿¤á¤Ë¡¢ + Apache ¤Ï¥ê¥½¡¼¥¹¤È¶¦¤Ë Content-Encoding ¥Ø¥Ã¥À¤ò + Á÷¤ê¤Þ¤¹¡£

    + +

    Content-encoding: pkzip

    +
    top
    +
    +

    ʸ»ú¥»¥Ã¥È¤È¸À¸ì

    +

    ¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤È¥Õ¥¡¥¤¥ë¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î¾¤Ë½ÅÍפʾðÊó¤Ï + ¥É¥­¥å¥á¥ó¥È¤Î½ñ¤«¤ì¤Æ¤¤¤ë¸À¸ì¤È¡¢¤É¤Îʸ»ú¥»¥Ã¥È¤Ç¥Õ¥¡¥¤¥ë¤¬É½¼¨ + ¤µ¤ì¤ë¤Ù¤­¤«¡¢¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£¤¿¤È¤¨¤Ð¡¢¥É¥­¥å¥á¥ó¥È¤Ï¥Ù¥È¥Ê¥à¤Î + ¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤ä¥­¥ê¥ëʸ»ú¤Ç½ñ¤«¤ì¤Æ¤¤¤Æ¡¢¤½¤Î¤è¤¦¤Ëɽ¼¨¤µ¤ì¤ë + ɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤³¤Î¾ðÊó¤â¤Þ¤¿¡¢HTTP ¥Ø¥Ã¥À¤Ç + Á÷¿®¤µ¤ì¤Þ¤¹¡£

    + +

    ʸ»ú¥»¥Ã¥È¡¢¸À¸ì¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¡¢mime ¥¿¥¤¥×¤Ï¤¹¤Ù¤Æ + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó (mod_negotiation »²¾È) + ¤ÎºÇÃæ¤Ë¡¢Ê£¿ô¤Îʸ»ú¥»¥Ã¥È¡¢¸À¸ì¡¢¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¡¢MIME ¥¿¥¤¥×¤«¤é¤Ê¤ë + ÂåÂØʪ¤¬¤¢¤ë¤È¤­¤Ë¤É¤Î¥É¥­¥å¥á¥ó¥È¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¤Î¤«¤ò + ·èÄꤹ¤ë¤È¤­¤Ë»È¤ï¤ì¤Þ¤¹¡£AddCharset, + AddEncoding, AddLanguage, + AddType ¤Î³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇºîÀ®¤µ¤ì¤¿ + ³ÈÄ¥»Ò¤Î´ØÏ¢ÉÕ¤± (¤È MimeMagicFile ¤Ç¥ê¥¹¥È¤µ¤ì¤Æ¤¤¤ë + ³ÈÄ¥»Ò) ¤¬¤³¤ÎÁªÂò¤Ë»²²Ã¤·¤Þ¤¹¡£AddHandler, + AddInputFilter, + AddOutputFilter ¤Î + ³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Î¤ß´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë³ÈÄ¥»Ò¤Ï + MultiviewsMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤¦¤³¤È¤Ç¥Þ¥Ã¥Á¤Î + ½èÍý¤Ë´Þ¤á¤ë¤³¤È¤â³°¤¹¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    Charset

    +

    ¤µ¤é¤Ë¾ðÊó¤òÅÁ¤¨¤ë¤¿¤á¤Ë¡¢Apache ¤Ïʸ½ñ¤Î¸À¸ì¤ò + Content-Language ¥Ø¥Ã¥À¤ÇÁ÷¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£ + ¤Þ¤¿¡¢¾ðÊó¤òÀµ¤·¤¯É½¼¨¤¹¤ë¤¿¤á¤Ë»ÈÍѤ¹¤Ù¤­Ê¸»ú¥»¥Ã¥È¤ò¼¨¤¹¤¿¤á¤Ë + Conten-Type ¥Ø¥Ã¥À¤Ë¾ðÊó¤òÄɲ乤뤳¤È¤â¤¢¤ê¤Þ¤¹¡£

    + +

    + Content-Language: en, fr
    + Content-Type: text/plain; charset=ISO-8859-1 +

    + +

    ¸À¸ì¤Î»ØÄê¤ÏÆóʸ»ú¤Îû½Ì·Á¤Ç¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£charset ¤¬ + »ÈÍѤ¹¤Ù¤­Ê¸»ú¥»¥Ã¥È¤Î̾Á°¤Ç¤¹¡£

    + +
    +
    top
    +

    AddCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿Ê¸»ú¥»¥Ã¥È¤Ë¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:AddCharset charset extension +[extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    AddCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + Í¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿ charset ¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£charset + ¤Ï¡¢³ÈÄ¥»Ò extension ¤ò´Þ¤ó¤Ç¤¤¤ë¥Õ¥¡¥¤¥ë̾¤Î + MIME charset + ¥Ñ¥é¥á¡¼¥¿¤Ç¤¹¡£¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¾¤Î¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢Ʊ¤¸³ÈÄ¥»Ò + extension ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    Îã

    + AddLanguage ja .ja
    + AddCharset EUC-JP .euc
    + AddCharset ISO-2022-JP .jis
    + AddCharset SHIFT_JIS .sjis +

    + +

    ¤³¤Î¾ì¹ç¡¢¥É¥­¥å¥á¥ó¥È xxxx.ja.jis ¤Ï charset ¤¬ + ISO-2022-JP ¤ÎÆüËܸì¤Î¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹ + (xxxx.jis.ja ¤âƱÍÍ)¡£AddCharset + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤¬Å¬Àڤ˲ò¼á¤µ¤ìɽ¼¨¤µ¤ì¤ë¤è¤¦¤Ë¡¢ + ¥É¥­¥å¥á¥ó¥È¤Î charset ¤Î¾ðÊó¤ò¥¯¥é¥¤¥¢¥ó¥È¤Ë¶µ¤¨¤ë¤¿¤á¤ËÌò¤ËΩ¤Á¤Þ¤¹¡£ + ¤Þ¤¿¡¢¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤Î charset + ¤ÎÍ¥ÀèÅ٤˴ð¤Å¤¤¤ÆÊ£¿ô¤Î¥É¥­¥å¥á¥ó¥È¤ÎÃ椫¤é¥É¥­¥å¥á¥ó¥È¤òÁª¤Ö¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¤¿¤á¤Ë¤âÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +

    °ú¿ô extension¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥¨¥ó¥³¡¼¥Ç¥£¥ó¥° +¤Ë¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:AddEncoding MIME-enc extension +[extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    AddEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + Í¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£ + MIME-enc ¤Ï¡¢³ÈÄ¥»Ò extension + ¤ò´Þ¤ó¤À¥É¥­¥å¥á¥ó¥È¤Ë»ÈÍѤ¹¤ë MIME ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ç¤¹¡£ + ¤³¤Î¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¾¤Î¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢 + Ʊ¤¸³ÈÄ¥»Ò extension ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    Îã

    + AddEncoding x-gzip .gz
    + AddEncoding x-compress .Z
    +

    + +

    ¤³¤ì¤Ï¡¢³ÈÄ¥»Ò .gz ¤ò´Þ¤à¥Õ¥¡¥¤¥ë̾¤¬ x-gzip + ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»È¤Ã¤Æ¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ë¤³¤È¤È¡¢³ÈÄ¥»Ò .Z + ¤ò´Þ¤à¥Õ¥¡¥¤¥ë̾¤¬ x-compress + ¤Ç¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    ¸Å¤¤¥¯¥é¥¤¥¢¥ó¥È¤Ï x-zip ¤È x-compress + ¤¬Ê֤äƤ¯¤ë¤³¤È¤ò´üÂÔ¤·¤Þ¤¹¤¬¡¢É¸½àµ¬³Ê¤Ç¤Ï¤½¤ì¤¾¤ì + gzip ¤È compress + ¤ÈÅù²Á¤Ç¤¢¤ë¤³¤È¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£Apache + ¤Ï¡¢¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ÎÈæ³Ó¤ò¤¹¤ë¤È¤­¤Ë¤Ï¡¢ÀèƬ¤Ë¤¢¤ë + x- ¤ò̵»ë¤·¤Þ¤¹¡£Apache + ¤¬¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°ÉÕ¤­¤Ç±þÅú¤òÊÖ¤¹¤È¤­¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬Í׵ᤷ¤¿·Á¼° + (¤¹¤Ê¤ï¤Á¡¢x-foo ¤ä foo) + ¤ò»ÈÍѤ·¤Þ¤¹¡£Íפ¹¤ë¤Ë¡¢¤³¤ÎÆó¤Ä¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î¾ì¹ç¤Ï¾ï¤Ë + x-gzip ¤È x-compress + ¤ò»È¤¦¤Ù¤­¤Ç¤¢¤ë¡¢¤È¤¤¤¦¤³¤È¤Ç¤¹¡£deflate + ¤Î¤è¤¦¤Ê¤è¤ê¿·¤·¤¤¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ç¤Ï¡¢x- + ¤Ê¤·¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£ +

    + +

    °ú¿ô extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    AddHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥Ï¥ó¥É¥é¤Ë¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:AddHandler handler-name extension +[extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    ³ÈÄ¥»Ò extension ¤¬Ì¾Á°¤Ë¤¢¤ë¥Õ¥¡¥¤¥ë¤Ï»ØÄꤵ¤ì¤¿ handler-name ¤Ë°·¤ï¤ì¤Þ¤¹¡£ + ¤³¤Î¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¾¤Î¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢 + Ʊ¤¸³ÈÄ¥»Ò extension + ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢³ÈÄ¥»Ò + ".cgi" ¤Ç½ª¤ï¤ë¥Õ¥¡¥¤¥ë¤ò CGI + ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ°·¤¤¤¿¤¤¤È¤­¤Ï¡¢°Ê²¼¤ÎÀßÄê¤ò¤·¤Þ¤¹¡£

    + +

    + AddHandler cgi-script .cgi +

    + +

    ¤³¤ì¤ò httpd.conf ¥Õ¥¡¥¤¥ë¤Ëµ­½Ò¤¹¤ë¤³¤È¤Ç¡¢³ÈÄ¥»Ò + ".cgi" ¤Î¥Õ¥¡¥¤¥ë¤Ï CGI ¥×¥í¥°¥é¥à¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£ +

    + +

    °ú¿ô extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤ò¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë + ¥Õ¥£¥ë¥¿¤Ë¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:AddInputFilter filter[;filter...] +extension [extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.26 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    AddInputFilter ¤Ï¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò + extension ¤ò¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ä POST ¤¬¥µ¡¼¥Ð¤ËÍ褿¤È¤­¤Ë + ½èÍý¤ò¤¹¤ë¥Õ¥£¥ë¥¿¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢SetInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤â + ´Þ¤á¡¢Â¾¤Î¾ì½ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¥ë¥¿¤Ë²Ã¤¨¤é¤ì¤Þ¤¹¡£ + ¤³¤Î¥Þ¥Ã¥Ô¥ó¥°¤Ï¤¹¤Ç¤Ë¤¢¤ë¤â¤Î¤è¤êÍ¥À褵¤ì¤Æ¥Þ¡¼¥¸¤µ¤ì¡¢ + Ʊ¤¸ extension ¤ËÂФ¹¤ë´û¸¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤ò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥Ç¡¼¥¿¤ò½èÍý¤¹¤ë½çÈ֤˥»¥ß¥³¥í¥ó¤Ç + ·Ò¤¤¤Ç½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£¥Õ¥£¥ë¥¿¤È extension ¤È¤Î + ξÊý¤Î°ú¿ô¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢³ÈÄ¥»Ò¤ÎºÇ½é¤Î¥É¥Ã¥È¤Ï + ¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤ò»ØÄꤵ¤ì¤¿¸À¸ì¤Ë¥Þ¥Ã¥×
    ¹½Ê¸:AddLanguage MIME-lang extension +[extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    AddLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Í¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿ + content language ¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£MIME-lang ¤Ï¡¢³ÈÄ¥»Ò + extension ¤ò´Þ¤ó¤Ç¤¤¤ë¥Õ¥¡¥¤¥ë̾¤Î MIME ¤Ë¤ª¤±¤ë¸À¸ì¤Ç¤¹¡£ + ¤³¤Î¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢Ʊ¤¸³ÈÄ¥»Ò + extension ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    Îã

    + AddEncoding x-compress .Z
    + AddLanguage en .en
    + AddLanguage fr .fr +

    + +

    ¤³¤Î¾ì¹ç¡¢xxxx.en.Z ¥É¥­¥å¥á¥ó¥È¤Ï compress + ¤µ¤ì¤¿±Ñ¸ì¤Î¥É¥­¥å¥á¥ó¥È¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹ (xxxx.Z.en + ¤âƱÍÍ)¡£content language ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÄÌÃΤµ¤ì¤Þ¤¹¤¬¡¢ + ¥Ö¥é¥¦¥¶¤¬¤³¤Î¾ðÊó¤ò»È¤¦¤³¤È¤Ï¤ª¤½¤é¤¯¤¢¤ê¤Þ¤»¤ó¡£ + AddLanguage + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤Î¸À¸ì¤ÎÍ¥ÀèÅ٤˴ð¤Å¤¤¤ÆÊ£¿ô¤Î + ¥É¥­¥å¥á¥ó¥È¤ÎÃ椫¤é¥É¥­¥å¥á¥ó¥È¤òÁª¤Ö¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î¤¿¤á¤Ë¤è¤êÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î¸À¸ì¤¬Æ±¤¸³ÈÄ¥»Ò¤Ë³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢ + ºÇ¸å¤Î¤â¤Î¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£¤¹¤Ê¤ï¤Á¡¢¼¡¤Î¤è¤¦¤Ê¾ì¹ç¡¢

    + +

    + AddLanguage en .en
    + AddLanguage en-gb .en
    + AddLanguage en-us .en +

    + +

    ³ÈÄ¥»Ò .en ¤Î¤¢¤ë¥É¥­¥å¥á¥ó¥È¤Ï + en-us ¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    °ú¿ô extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò¥µ¡¼¥Ð¤«¤é¤Î±þÅú¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤Ë + ¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:AddOutputFilter filter[;filter...] +extension [extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.26 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    AddOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ³ÈÄ¥»Ò extension ¤ò¥µ¡¼¥Ð¤Î±þÅú¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤é¤ì¤ë + Á°¤Ë½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÄêµÁ¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï SetOutputFilter + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È AddOutputFilterByType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ò´Þ¤á¡¢Â¾¤Î¾ì½ê¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Õ¥£¥ë¥¿¤Ë²Ã¤¨¤é¤ì¤Þ¤¹¡£ + ¤³¤Î¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢Ʊ¤¸³ÈÄ¥»Ò + extension ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢°Ê²¼¤ÎÀßÄê¤Ï¤¹¤Ù¤Æ¤Î .shtml ¥Õ¥¡¥¤¥ë¤ò SSI ¤Ç½èÍý¤·¡¢ + ¤½¤Î½ÐÎϤò mod_deflate ¤ò»È¤Ã¤Æ°µ½Ì¤·¤Þ¤¹¡£

    + +

    + AddOutputFilter INCLUDES;DEFLATE shtml +

    + +

    Ê£¿ô¤Î¥Õ¥£¥ë¥¿¤ò»ØÄꤹ¤ë¤È¤­¤Ï¡¢¥Ç¡¼¥¿¤ò½èÍý¤¹¤ë½çÈ֤˥»¥ß¥³¥í¥ó¤Ç + ·Ò¤¤¤Ç½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£filter ¤È extension ¤Î + ξ°ú¿ô¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢³ÈÄ¥»Ò¤ÎºÇ½é¤Î¥É¥Ã¥È¤Ï + ¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    AddType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ë¥Þ¥Ã¥×
    ¹½Ê¸:AddType MIME-type extension +[extension] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    AddType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + Í¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ë¥Þ¥Ã¥×¤·¤Þ¤¹¡£ + MIME-type ¤Ï³ÈÄ¥»Ò extension + ¤ò´Þ¤ó¤À¥É¥­¥å¥á¥ó¥È¤Ë»ÈÍѤ¹¤ë MIME ¥¿¥¤¥×¤Ç¤¹¡£ + ¤³¤Î¿·¤·¤¤¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¤¢¤ë¥Þ¥Ã¥Ô¥ó¥°¤ËÄɲ䵤졢Ʊ¤¸³ÈÄ¥»Ò + extension ¤Î¤¿¤á¤Î¥Þ¥Ã¥Ô¥ó¥°¤ò¾å½ñ¤­¤·¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï MIME ¥¿¥¤¥×¥Õ¥¡¥¤¥ë (TypesConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»²¾È) + ¤Ë̵¤¤¥Þ¥Ã¥Ô¥ó¥°¤òÄɲ乤뤿¤á¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Îã

    + AddType image/gif .gif +

    + +
    + ¿·¤·¤¤ MIME ¥¿¥¤¥×¤Ï¡¢TypesConfig + ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢AddType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤ÆÄɲ乤뤳¤È¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ +
    + +

    °ú¿ô extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    DefaultLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¤¢¤ë¥¹¥³¡¼¥×¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò»ØÄꤵ¤ì¤¿¸À¸ì¤Ë +ÀßÄꤹ¤ë
    ¹½Ê¸:DefaultLanguage MIME-lang
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    DefaultLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Apache + ¤¬¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥¹¥³¡¼¥× (Î㤨¤Ð¡¢¤½¤Î»þÅÀ¤Î + <Directory> + ¤ÎÈÏ°Ï) ¤Ë¤¢¤ë¡¢ÌÀ¼¨Åª¤Ê¸À¸ì³ÈÄ¥»Ò + (AddLanguage ¤ÇÀßÄꤵ¤ì¤ë + .fr ¤ä .de) ¤Î¤Ê¤¤Á´¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò¡¢»ØÄꤵ¤ì¤¿ + MIME-lang ¸À¸ì¤Ç¤¢¤ë¤È¤ß¤Ê¤¹¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤òÊѤ¨¤ë¤³¤È¤Ê¤¯¡¢ + ¥Ç¥£¥ì¥¯¥È¥ê¤¬¥ª¥é¥ó¥À¸ì¤Î¥³¥ó¥Æ¥ó¥È¤ò´Þ¤ó¤Ç¤¤¤ë¡¢ + ¤È¤¤¤¦¤è¤¦¤Ê¤³¤È¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ³ÈÄ¥»Ò¤ò»ÈÍѤ·¤Æ¸À¸ì¤ò»ØÄꤹ¤ëÊýË¡¤È°ã¤¤¡¢ + DefaultLanguage + ¤Ï°ì¤Ä¤Î¸À¸ì¤·¤«»ØÄê¤Ç¤­¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    DefaultLanguage + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Í­¸ú¤Ç¤Ê¤¯¡¢¥Õ¥¡¥¤¥ë¤Ë + AddLanguage + ¤ÇÀßÄꤵ¤ì¤¿¸À¸ì¤Î³ÈÄ¥»Ò¤¬¤Ê¤¤¤È¤­¤Ï¡¢ + ¥Õ¥¡¥¤¥ë¤Ë¤Ï¸À¸ì°À­¤¬¤Ê¤¤¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + DefaultLanguage en +

    + +

    »²¾È

    + +
    +
    top
    +

    ModMimeUsePathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:path_info ¥³¥ó¥Ý¡¼¥Í¥ó¥È¤ò¥Õ¥¡¥¤¥ë̾¤Î°ìÉô¤È¤·¤Æ°·¤¦¤è¤¦¤Ë +mod_mime ¤ËÄÌÃΤ¹¤ë
    ¹½Ê¸:ModMimeUsePathInfo On|Off
    ¥Ç¥Õ¥©¥ë¥È:ModMimeUsePathInfo Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:Apache 2.0.41 °Ê¹ß
    +

    ModMimeUsePathInfo ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + mod_mime ¤Î»ý¤Ä¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ¥ê¥¯¥¨¥¹¥È¤ËŬÍѤµ¤»¤ë¤¿¤á¤Ë¡¢¥Õ¥¡¥¤¥ë̾¤È path_info URL + ¥³¥ó¥Ý¡¼¥Í¥ó¥È¤ò·ë¹ç¤µ¤»¤ë¤¿¤á¤Ë»ÈÍѤ·¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡Ö Off ¡×¤Ç¡¢path_info + ¥³¥ó¥Ý¡¼¥Í¥ó¥È¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥Ð¡¼¥Á¥ã¥ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ëºÝ¤Ë + ¿ä¾©¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤¹¡£

    + +

    Îã

    + ModMimeUsePathInfo On +

    + +

    /bar ¤¬Â¸ºß¤·¤Æ (foo.shtml ¤Ï¸ºß¤·¤Ê¤¤) + ModMimeUsePathInfo ¤¬ On ¤Ç¤¢¤ë¤È¤·¤Æ¡¢ + /bar/foo.shtml ¤ËÂФ¹¤ë¥ê¥¯¥¨¥¹¥È¤òȯ¹Ô¤·¤¿¾ì¹ç¡¢ + mod_mime ¤ÏÆþ¤Ã¤Æ¤­¤¿¥ê¥¯¥¨¥¹¥È¤ò + /bar/foo.shtml ¤È¤·¤Æ°·¤¤¡¢ + AddOutputFileter INCLUDES .shtml ¤Î¤è¤¦¤Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + INCLUDES ¥Õ¥£¥ë¥¿¤ò¥ê¥¯¥¨¥¹¥È¤ËÉղ䵤»¤Þ¤¹¡£ + ModMimeUsePathInfo ¤¬ÀßÄꤵ¤ì¤Ê¤±¤ì¤Ð¡¢ + INCLUDES ¥Õ¥£¥ë¥¿¤ÏÉղ䵤ì¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    MultiviewsMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:MultiViews ¤Ç¤Î¥Þ¥Ã¥Á¥ó¥°¤Î¸¡º÷¤Ë´Þ¤Þ¤»¤ë +¥Õ¥¡¥¤¥ë¤Î¥¿¥¤¥×¤ò»ØÄꤹ¤ë
    ¹½Ê¸:MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters]
    ¥Ç¥Õ¥©¥ë¥È:MultiviewsMatch NegotiatedOnly
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.26 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    MultiviewsMatch ¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢ + mod_negotiation ¤Î + Multiviews ¤Ë 3 ¼ïÎà¤Î°Û¤Ê¤ëµóÆ°¤ò¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Multiviews ¤ò»ÈÍѤ¹¤ë¤È¡¢¥Õ¥¡¥¤¥ë (Îã index.html) + ¤ËÂФ¹¤ë¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¡¢¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤¹¤ë³ÈÄ¥»Ò¤¬¥Ù¡¼¥¹¤ËÉÕ¤¤¤¿¤â¤Î + (index.html.en, index.html.fr ¤ä + index.html.gz) + ¤ò¥Þ¥Ã¥Á¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    NegotiatedOnly ¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢¥Ù¡¼¥¹Ì¾¤Ë³¤¯³ÈÄ¥»ÒÁ´¤Æ¤¬ + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Ç mod_mime + ¤¬Ç§¼±¤¹¤ë³ÈÄ¥»Ò (Îã ʸ»ú¥»¥Ã¥È¡¢¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¡¢¸À¸ì¤ä¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°) + ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤ì¤ÏÉûºîÍѤκǤ⾯¤Ê¤¤ + ºÇ¤âŪ³Î¤Ê¼ÂÁõ¤Ç¡¢¥Ç¥Õ¥©¥ë¥È¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥Ï¥ó¥É¥é¤È¥Õ¥£¥ë¥¿¤ÎξÊý¤â¤·¤¯¤ÏÊÒÊý¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿³ÈÄ¥»Ò¤ò´Þ¤á¤ë¤Ë¤Ï¡¢ + MultiviewsMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë Handlers, + Filters ¤Þ¤¿¤Ï¤½¤ÎξÊý¤Î¥ª¥×¥·¥ç¥ó¤ò¥»¥Ã¥È¤·¤Þ¤¹¡£ + ¤â¤·Â¾¤Î¾ò·ï¤¬Æ±¤¸¤Ç¤¢¤ì¤Ð¡¢ºÇ¤â¾®¤µ¤¤¥Õ¥¡¥¤¥ë¤¬Á÷¿®¤µ¤ì¤Þ¤¹¡£ + Î㤨¤Ð¡¢500 ʸ»ú¤Î index.html.cgi ¤È 1000 ¥Ð¥¤¥È¤Î + index.html.pl ¤Ç¤¢¤ì¤Ð¡¢.cgi + ¤Î¥Õ¥¡¥¤¥ë¤¬Í¥À褵¤ì¤Þ¤¹¡£.asis ¥Õ¥¡¥¤¥ë¤òÍøÍѤ·¤Æ¤¤¤ë¥æ¡¼¥¶¤Ï¡¢ + .asis ¥Õ¥¡¥¤¥ë¤¬ asis-handler ¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¤È¤­¤Ë¤Ï¡¢ + ¥Ï¥ó¥É¥é¥ª¥×¥·¥ç¥ó¤Î»ÈÍѤò¹¥¤à¤Ç¤·¤ç¤¦¡£

    + +

    ºÇ¸å¤Ë¡¢mod_mime ¤¬Ç§¼±¤·¤Ê¤¤³ÈÄ¥»Ò¤Ç¤¢¤í¤¦¤È¤â¡¢ + ¤É¤ó¤Ê³ÈÄ¥»Ò¤Ç¤â¥Þ¥Ã¥Á¤µ¤»¤ë Any ¤¬»ÈÍѤǤ­¤Þ¤¹¡£ + ¤³¤ÎµóÆ°¤Ï Apache 1.3 ¤Î¤È¤­¤ÈƱ¤¸¤â¤Î¤Ç¡¢Í½´ü¤·¤Ê¤¤Æ°ºî¡¢Î㤨¤Ð .old ¤ä + .bak ¥Õ¥¡¥¤¥ë¤È¤¤¤Ã¤¿¥¦¥§¥Ö¥Þ¥¹¥¿¤¬Á÷¿®¤ò°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤ + ¥Õ¥¡¥¤¥ë¤òÁ÷¿®¤¹¤ë¡¢¤È¤¤¤Ã¤¿Æ°ºî¤ò¹Ô¤Ê¤¦²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    Î㤨¤Ð¼¡¤ÎÀßÄê¤Ç¤Ï¡¢¥Ï¥ó¥É¥é¤ä¥Õ¥£¥ë¥¿¤¬ Multiviews ¤Ë»²²Ã¤¹¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¤·¡¢Ì¤ÃΤΥե¡¥¤¥ë¤Ï½ü³°¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    + MultiviewsMatch Handlers Filters +

    + + +

    »²¾È

    + +
    +
    top
    +

    RemoveCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Îʸ»ú¥»¥Ã¥È +¤ò²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveCharset extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.24 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    RemoveCharset ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ÏÍ¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿Ê¸»ú¥»¥Ã¥È¤ò¼è¤ê¾Ã¤·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë .htaccess + ¥Õ¥¡¥¤¥ë¤¬¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ë + ¤«¤é·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð:

    + +

    extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£ + ¤Þ¤¿¡¢ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    Îã

    + RemoveCharset .html .shtml +

    + +
    +
    top
    +

    RemoveEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥° +¤ò²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveEncoding extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    RemoveEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + Í¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò¼è¤ê¾Ã¤·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë .htaccess + ¥Õ¥¡¥¤¥ë¤¬¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤«¤é·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò + ¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    /foo/.htaccess:

    + AddEncoding x-gzip .gz
    + AddType text/plain .asc
    + <Files *.gz.asc>
    + + RemoveEncoding .gz
    +
    + </Files> +

    + +

    ¤³¤ì¤Ï¡¢foo.gz ¤Ï gzip + ¤Ç¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò»ØÄꤷ¤Þ¤¹¤¬¡¢foo.gz.asc + ¤Ï¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤Ê¤¤¥×¥ì¡¼¥ó¥Æ¥­¥¹¥È¤Î + ¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë¤È¤¤¤¦¤³¤È¤ò»ØÄꤷ¤Þ¤¹¡£

    + +

    Ãí°Õ

    +

    RemoveEncoding ¤Ï + AddEncoding + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸å¤Ç½èÍý¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + Ʊ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄêÃæ¤ËξÊý¤¬¸½¤ì¤ë¤È¡¢ + ¸å¼Ô¤Î¸ú²Ì¤¬ÂǤÁ¾Ã¤µ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    +
    + +

    extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£ + ¤Þ¤¿¡¢ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    RemoveHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Î¥Ï¥ó¥É¥é¤ò +²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveHandler extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    RemoveHandler ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ÏÍ¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Ï¥ó¥É¥é¤ò¼è¤ê¾Ã¤·¤Þ¤¹¡£ + ¤³¤ì¤Ë¤è¤ê¡¢¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë .htaccess + ¥Õ¥¡¥¤¥ë¤¬¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ë + ¤«¤é·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð:

    + +

    /foo/.htaccess:

    + AddHandler server-parsed .html +

    + +

    /foo/bar/.htaccess:

    + RemoveHandler .html +

    + +

    ¤³¤ì¤Ï¡¢/foo/bar ¥Ç¥£¥ì¥¯¥È¥ê¤Î .html + ¥Õ¥¡¥¤¥ë¤Ï SSI (mod_include ¥â¥¸¥å¡¼¥ë»²¾È) ¤Ç¤Ï¤Ê¤¯¡¢ + ÉáÄ̤Υե¡¥¤¥ë¤È¤·¤Æ°·¤ï¤ì¤ë¤è¤¦¤Ë¤¹¤ë¸ú²Ì¤¬¤¢¤ê¤Þ¤¹¡£ +

    + +

    extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£ + ¤Þ¤¿¡¢ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    RemoveInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿ÆþÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveInputFilter extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.26 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    RemoveInputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + »ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿ÆþÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤·¤Þ¤¹¡£ + ¤³¤ì¤òÍøÍѤ¹¤ë¤³¤È¤Ç¡¢¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤«¤é + ·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë¤ª¤¤¤Æ + .htaccess ¥Õ¥¡¥¤¥ë¤Ç¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    extension °ú¿ô¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£¤Þ¤¿¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    »²¾È

    + +
    +
    top
    +

    RemoveLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¸À¸ì¤ò²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveLanguage extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.24 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    RemoveLanguage ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + »ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¸À¸ì¤ò²ò½ü¤·¤Þ¤¹¡£ + ¤³¤ì¤òÍøÍѤ¹¤ë¤³¤È¤Ç¡¢¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤«¤é + ·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë¤ª¤¤¤Æ + .htaccess ¥Õ¥¡¥¤¥ë¤Ç¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    extension °ú¿ô¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£¤Þ¤¿¡¢ + ºÇ½é¤Î¥É¥Ã¥È¤Ï¤Ä¤¤¤Æ¤â¤Ä¤«¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    RemoveOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿½ÐÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveOutputFilter extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    ¸ß´¹À­:2.0.26 °Ê¹ß¤Ç¤Î¤ß»ÈÍѲÄǽ
    +

    RemoveOutputFilter ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + »ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿½ÐÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤·¤Þ¤¹¡£ + ¤³¤ì¤òÍøÍѤ¹¤ë¤³¤È¤Ç¡¢¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë¤«¤é + ·Ñ¾µ¤·¤¿´ØÏ¢ÉÕ¤±¤ò ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥êÆâ¤Ë¤ª¤¤¤Æ + .htaccess ¥Õ¥¡¥¤¥ë¤Ç¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£ + ¤Þ¤¿¡¢ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +

    Îã

    + RemoveOutputFilter shtml +

    + +

    »²¾È

    + +
    +
    top
    +

    RemoveType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò +²ò½ü¤¹¤ë
    ¹½Ê¸:RemoveType extension [extension] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    RemoveType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÍ¿¤¨¤é¤ì¤¿³ÈÄ¥»Ò¤Î + MIME ¥¿¥¤¥×¤Î´ØÏ¢ÉÕ¤±¤ò¼è¤ê¾Ã¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢ + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë .htaccess + ¥Õ¥¡¥¤¥ë¤¬¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤ä¥µ¡¼¥Ð¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤«¤é·Ñ¾µ¤·¤¿ + ´ØÏ¢ÉÕ¤±¤ò¼è¤ê¾Ã¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð:

    + +

    /foo/.htaccess:

    + RemoveType .cgi +

    + +

    ¤³¤ì¤Ï /foo/ ¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤Î .cgi + ¥Õ¥¡¥¤¥ë¤ÎÆÃÊ̤ʰ·¤¤¤ò¼è¤ê¾Ã¤·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤Ï DefaultType ¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    Ãí°Õ

    +

    RemoveType ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + AddType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¸å¤Ë½èÍý¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + ξÊý¤¬Æ±¤¸¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄêÃæ¤Ë¸½¤ì¤¿¾ì¹ç¡¢ + ¸å¼Ô¤Î¸ú²Ì¤¬ÂǤÁ¾Ã¤µ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    +
    + +

    extension ¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤»¤ó¡£ + ¤Þ¤¿¡¢ºÇ½é¤Î¥É¥Ã¥È¤Ï¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    TypesConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:mime.types ¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    ¹½Ê¸:TypesConfig file-path
    ¥Ç¥Õ¥©¥ë¥È:TypesConfig conf/mime.types
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:¥Ù¡¼¥¹
    ¥â¥¸¥å¡¼¥ë:mod_mime
    +

    TypesConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢MIME + ¥¿¥¤¥×ÀßÄê¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤òÀßÄꤷ¤Þ¤¹¡£filename ¤Ï + ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£ + ¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤«¤é¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ø¤Î + ¥Ç¥Õ¥©¥ë¥È¤Î¥Þ¥Ã¥Ô¥ó¥°¤òÀßÄꤷ¤Þ¤¹¡£ + ¤Û¤È¤ó¤É¤Î´ÉÍý¼Ô¤Ï¡¢¤è¤¯»È¤ï¤ì¤ë¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò + IANA ¤ËÅÐÏ¿¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ë´ØÏ¢ÉÕ¤±¤Æ¤¤¤ë¡¢ + Apache ¤Î mime.types ¥Õ¥¡¥¤¥ë¤ò»È¤¤¤Þ¤¹¡£ + ¸½ºß¤Î°ìÍ÷¤Ï http://www.isi.edu/in-notes/iana/assignments/media-types/media-types + ¤Ç´ÉÍý¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¡¢¼çÍפʥá¥Ç¥£¥¢¥¿¥¤¥×¤ÎÄêµÁ¤òÄ󶡤·¤Æ¡¢ + ɬÍפȤ³¤í¤ò AddType ¤Ç + ¾å½ñ¤­¤¹¤ë¡¢¤È¤¤¤¦ÊýË¡¤Ç httpd.conf ¤ò´Êά¤Ë¤·¤Þ¤¹¡£ + mime.types ¤Ï¥µ¡¼¥Ð¤ò¥¢¥Ã¥×¥°¥ì¡¼¥É¤·¤¿¤È¤­¤Ë + ÃÖ¤­´¹¤¨¤é¤ì¤ë¤«¤â¤·¤ì¤Ê¤¤¤Î¤Ç¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤òľÀÜ + ÊÔ½¸¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£

    + +

    ¥Õ¥¡¥¤¥ë¤Ï¡¢AddType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤ÈƱ¤¸·Á¼°¤Î¹Ô¤Ç¹½À®¤µ¤ì¤Þ¤¹¡£

    + +

    + MIME-type [extension] ... +

    + +

    ³ÈÄ¥»Ò¤ÎÂçʸ»ú¾®Ê¸»ú¤Ï¶èÊ̤µ¤ì¤Þ¤»¤ó¡£¶õ¹Ô¤ä¥Ï¥Ã¥·¥å (`#') + ¤Ç»Ï¤Þ¤ë¹Ô¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +
    + (1) IANA ¤Ë´û¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¡¢¤¢¤ë¤¤¤Ï (2) + ¹­¤¯¼õ¤±Æþ¤ì¤é¤ì¤Æ¤¤¤Æ¥×¥é¥Ã¥È¥Û¡¼¥à´Ö¤Ç¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë¾×Æͤ¬¤Ê¤¤¡¢ + ¤È¤¤¤¦¾ì¹ç¤Ç¤Ê¤±¤ì¤Ð¡¢ÇÛÉÛÃæ¤Î mime.types + ¥Õ¥¡¥¤¥ë¤Ë¿·¤¿¤Ê¤â¤Î¤òÅÐÏ¿¤¹¤ë¤è¤¦¤Ë + Apache HTTP Server Project ¤Ë¥ê¥¯¥¨¥¹¥È¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + category/x-subtype ¤Î¥ê¥¯¥¨¥¹¥È¤Ï¼«Æ°Åª¤ËµÑ²¼¤µ¤ì¤Þ¤¹¤·¡¢ + ¸À¸ì¤äʸ»ú¥»¥Ã¥È¤Î̾Á°¶õ´Ö¤Ç´û¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤Æ¡¢¾×ÆͤβÄǽÀ­¤Î¤¢¤ë + 2 ʸ»ú¤Î³ÈÄ¥»Ò¤âµÑ²¼¤µ¤ì¤Þ¤¹¡£ +
    + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mime.xml b/trunk/docs/manual/mod/mod_mime.xml new file mode 100644 index 0000000000..926e58ea3b --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.xml @@ -0,0 +1,901 @@ + + + + + + + + + +mod_mime +Associates the requested filename's extensions + with the file's behavior (handlers and filters) + and content (mime-type, language, character set and + encoding) +Base +mod_mime.c +mime_module + + +

    This module is used to associate various bits of "meta + information" with files by their filename extensions. This + information relates the filename of the document to it's + mime-type, language, character set and encoding. This + information is sent to the browser, and participates in content + negotiation, so the user's preferences are respected when + choosing one of several possible files to serve. See + mod_negotiation for more information + about content negotiation.

    + +

    The directives AddCharset, AddEncoding, AddLanguage and AddType are all used to map file + extensions onto the meta-information for that file. Respectively + they set the character set, content-encoding, content-language, + and MIME-type (content-type) of documents. The directive TypesConfig is used to specify a + file which also maps extensions onto MIME types.

    + +

    In addition, mod_mime may define the handler and filters that originate and process + content. The directives AddHandler, AddOutputFilter, and AddInputFilter control the modules + or scripts that serve the document. The MultiviewsMatch directive allows + mod_negotiation to consider these file extensions + to be included when testing Multiviews matches.

    + +

    While mod_mime associates meta-information + with filename extensions, the core server + provides directives that are used to associate all the files in a + given container (e.g., Location, Directory, or Files) with particular + meta-information. These directives include ForceType, SetHandler, SetInputFilter, and SetOutputFilter. The core directives + override any filename extension mappings defined in + mod_mime.

    + +

    Note that changing the meta-information for a file does not + change the value of the Last-Modified header. + Thus, previously cached copies may still be used by a client or + proxy, with the previous headers. If you change the + meta-information (language, content type, character set or + encoding) you may need to 'touch' affected files (updating + their last modified date) to ensure that all visitors are + receive the corrected content headers.

    +
    +MimeMagicFile +AddDefaultCharset +ForceType +DefaultType +SetHandler +SetInputFilter +SetOutputFilter + +
    Files with Multiple Extensions +

    Files can have more than one extension, and the order of the + extensions is normally irrelevant. For example, if the + file welcome.html.fr maps onto content type + text/html and language French then the file + welcome.fr.html will map onto exactly the same information. + If more than one extension is given which maps onto the same + type of meta-information, then the one to the right will be + used, except for languages and content encodings. For example, if + .gif maps to the MIME-type image/gif and + .html maps to the MIME-type text/html, then the + file welcome.gif.html will be associated with the MIME-type + text/html.

    + +

    Languages and content encodings are treated accumulative, because one can assign + more than one language or encoding to a particular ressource. For example, + the file welcome.html.en.de will be delivered with + Content-Language: en, de and Content-Type: + text/html.

    + +

    Care should be taken when a file with multiple extensions + gets associated with both a MIME-type and a handler. This will + usually result in the request being by the module associated + with the handler. For example, if the .imap + extension is mapped to the handler imap-file (from + mod_imagemap) and the .html extension is + mapped to the MIME-type text/html, then the file + world.imap.html will be associated with both the + imap-file handler and text/html MIME-type. + When it is processed, the imap-file handler will be used, + and so it will be treated as a mod_imagemap imagemap + file.

    +
    + +
    Content encoding +

    A file of a particular MIME type can additionally be encoded a + particular way to simplify transmission over the Internet. + While this usually will refer to compression, such as + gzip, it can also refer to encryption, such a + pgp or to an encoding such as UUencoding, which is + designed for transmitting a binary file in an ASCII (text) + format.

    + +

    The HTTP/1.1 + RFC, section 14.11 puts it this way:

    + +
    +

    The Content-Encoding entity-header field is used as a modifier to + the media-type. When present, its value indicates what additional + content codings have been applied to the entity-body, and thus what + decoding mechanisms must be applied in order to obtain the media-type + referenced by the Content-Type header field. Content-Encoding is + primarily used to allow a document to be compressed without losing + the identity of its underlying media type.

    +
    + +

    By using more than one file extension (see section above about multiple file + extensions), you can indicate that a file is of a + particular type, and also has a particular + encoding.

    + +

    For example, you may have a file which is a Microsoft Word + document, which is pkzipped to reduce its size. If the + .doc extension is associated with the Microsoft + Word file type, and the .zip extension is + associated with the pkzip file encoding, then the file + Resume.doc.zip would be known to be a pkzip'ed Word + document.

    + +

    Apache sends a Content-encoding header with the + resource, in order to tell the client browser about the + encoding method.

    + + Content-encoding: pkzip +
    + +
    Character sets and languages +

    In addition to file type and the file encoding, + another important piece of information is what language a + particular document is in, and in what character set the file + should be displayed. For example, the document might be written + in the Vietnamese alphabet, or in Cyrillic, and should be + displayed as such. This information, also, is transmitted in + HTTP headers.

    + +

    The character set, language, encoding and mime type are all + used in the process of content negotiation (See + mod_negotiation) to determine + which document to give to the client, when there are + alternative documents in more than one character set, language, + encoding or mime type. All filename extensions associations + created with AddCharset, + AddEncoding, AddLanguage and AddType directives + (and extensions listed in the MimeMagicFile) participate in this select process. + Filename extensions that are only associated using the AddHandler, AddInputFilter or AddOutputFilter directives may be included or excluded + from matching by using the MultiviewsMatch directive.

    + +
    Charset +

    To convey this further information, Apache optionally sends + a Content-Language header, to specify the language + that the document is in, and can append additional information + onto the Content-Type header to indicate the + particular character set that should be used to correctly + render the information.

    + + + Content-Language: en, fr
    + Content-Type: text/plain; charset=ISO-8859-1 +
    + +

    The language specification is the two-letter abbreviation + for the language. The charset is the name of the + particular character set which should be used.

    +
    +
    + + +AddCharset +Maps the given filename extensions to the specified content +charset +AddCharset charset extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    The AddCharset directive maps the given + filename extensions to the specified content charset. charset + is the MIME + charset parameter of filenames containing + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + + Example + AddLanguage ja .ja
    + AddCharset EUC-JP .euc
    + AddCharset ISO-2022-JP .jis
    + AddCharset SHIFT_JIS .sjis +
    + +

    Then the document xxxx.ja.jis will be treated + as being a Japanese document whose charset is ISO-2022-JP + (as will the document xxxx.jis.ja). The + AddCharset directive is useful for both to + inform the client about the character encoding of the document so that + the document can be interpreted and displayed appropriately, and for content negotiation, + where the server returns one from several documents based on + the client's charset preference.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +mod_negotiation +AddDefaultCharset +
    + + +AddEncoding +Maps the given filename extensions to the specified encoding +type +AddEncoding MIME-enc extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    The AddEncoding directive maps the given + filename extensions to the specified encoding type. MIME-enc + is the MIME encoding to use for documents containing the + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + + Example + AddEncoding x-gzip .gz
    + AddEncoding x-compress .Z +
    + +

    This will cause filenames containing the .gz extension + to be marked as encoded using the x-gzip encoding, and + filenames containing the .Z extension to be marked as + encoded with x-compress.

    + +

    Old clients expect x-gzip and x-compress, + however the standard dictates that they're equivalent to + gzip and compress respectively. Apache does + content encoding comparisons by ignoring any leading x-. + When responding with an encoding Apache will use whatever form + (i.e., x-foo or foo) the + client requested. If the client didn't specifically request a + particular form Apache will use the form given by the + AddEncoding directive. To make this long story + short, you should always use x-gzip and + x-compress for these two specific encodings. More + recent encodings, such as deflate should be + specified without the x-.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +
    + + +AddHandler +Maps the filename extensions to the specified +handler +AddHandler handler-name extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    Files having the name extension will be served by the + specified handler-name. This + mapping is added to any already in force, overriding any mappings that + already exist for the same extension. For example, to + activate CGI scripts with the file extension .cgi, you + might use:

    + + + AddHandler cgi-script .cgi + + +

    Once that has been put into your httpd.conf file, any file containing + the .cgi extension will be treated as a CGI program.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +SetHandler +
    + + +AddInputFilter +Maps filename extensions to the filters that will process +client requests +AddInputFilter filter[;filter...] +extension [extension] ... +server configvirtual host +directory.htaccess +FileInfo +AddInputFilter is only available in Apache 2.0.26 and +later. + + +

    AddInputFilter maps the filename extension + extension to the filters which + will process client requests and POST input when they are received by + the server. This is in addition to any filters defined elsewhere, + including the SetInputFilter + directive. This mapping is merged over any already in force, overriding + any mappings that already exist for the same extension.

    + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content. Both the filter and extension arguments are + case-insensitive, and the extension may be specified with or + without a leading dot.

    +
    +RemoveInputFilter +SetInputFilter +
    + + +AddLanguage +Maps the given filename extension to the specified content +language +AddLanguage MIME-lang extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    The AddLanguage directive maps the given + filename extension to the specified content language. + MIME-lang is the MIME language of filenames containing + extension. This mapping is added to any already in force, + overriding any mappings that already exist for the same + extension.

    + + Example + AddEncoding x-compress .Z
    + AddLanguage en .en
    + AddLanguage fr .fr +
    + +

    Then the document xxxx.en.Z will be treated as + being a compressed English document (as will the document + xxxx.Z.en). Although the content language is + reported to the client, the browser is unlikely to use this + information. The AddLanguage directive is + more useful for content + negotiation, where the server returns one from several documents + based on the client's language preference.

    + +

    If multiple language assignments are made for the same + extension, the last one encountered is the one that is used. + That is, for the case of:

    + + + AddLanguage en .en
    + AddLanguage en-gb .en
    + AddLanguage en-us .en +
    + +

    documents with the extension .en would be treated as + being en-us.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +mod_negotiation +
    + + +AddOutputFilter +Maps filename extensions to the filters that will process +responses from the server +AddOutputFilter filter[;filter...] +extension [extension] ... +server configvirtual host +directory.htaccess +FileInfo +AddOutputFilter is only available in Apache 2.0.26 and +later. + + +

    The AddOutputFilter directive maps the + filename extension extension to the filters which will process responses + from the server before they are sent to the client. This is in + addition to any filters defined elsewhere, including SetOutputFilter and AddOutputFilterByType directive. This mapping is merged + over any already in force, overriding any mappings that already exist + for the same extension.

    + +

    For example, the following configuration will process all + .shtml files for server-side includes and will then + compress the output using mod_deflate.

    + + + AddOutputFilter INCLUDES;DEFLATE shtml + + +

    If more than one filter is specified, they must be separated + by semicolons in the order in which they should process the + content. Both the filter and extension arguments + are case-insensitive, and the extension may be specified with or + without a leading dot.

    +
    +RemoveOutputFilter +SetOutputFilter +
    + + +AddType +Maps the given filename extensions onto the specified content +type +AddType MIME-type extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    The AddType directive maps the given filename + extensions onto the specified content type. MIME-type is the + MIME type to use for filenames containing extension. This + mapping is added to any already in force, overriding any mappings that + already exist for the same extension. This directive can + be used to add mappings not listed in the MIME types file (see the + TypesConfig directive).

    + + Example + AddType image/gif .gif + + + + It is recommended that new MIME types be added using the + AddType directive rather than changing the + TypesConfig file. + + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +DefaultType +ForceType +
    + + +MultiviewsMatch +The types of files that will be included when searching for +a matching file with MultiViews +MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] +MultiviewsMatch NegotiatedOnly +server configvirtual host +directory.htaccess +FileInfo +Available in Apache 2.0.26 and later. + + +

    MultiviewsMatch permits three different + behaviors for mod_negotiation's + Multiviews feature. Multiviews allows a request for a file, + e.g. index.html, to match any negotiated + extensions following the base request, e.g. + index.html.en, index.html.fr, or + index.html.gz.

    + +

    The NegotiatedOnly option provides that every extension + following the base name must correlate to a recognized + mod_mime extension for content negotation, e.g. + Charset, Content-Type, Language, or Encoding. This is the strictest + implementation with the fewest unexpected side effects, and is the + default behavior.

    + +

    To include extensions associated with Handlers and/or Filters, + set the MultiviewsMatch directive to either + Handlers, Filters, or both option keywords. + If all other factors are equal, the smallest file will be served, + e.g. in deciding between index.html.cgi of 500 + bytes and index.html.pl of 1000 bytes, the .cgi + file would win in this example. Users of .asis files + might prefer to use the Handler option, if .asis files are + associated with the asis-handler.

    + +

    You may finally allow Any extensions to match, even if + mod_mime doesn't recognize the extension. This was the + behavior in Apache 1.3, and can cause unpredicatable results, such as + serving .old or .bak files the webmaster never expected to be served.

    + +

    For example, the following configuration will allow handlers + and filters to participate in Multviews, but will exclude unknown + files:

    + + + MultiviewsMatch Handlers Filters + +
    +Options +mod_negotiation +
    + + +DefaultLanguage +Sets all files in the given scope to the specified +language +DefaultLanguage MIME-lang +server configvirtual host +directory.htaccess +FileInfo + + +

    The DefaultLanguage directive tells Apache + that all files in the directive's scope (e.g., all files + covered by the current Directory container) that don't have an explicit language + extension (such as .fr or .de as configured + by AddLanguage) should be + considered to be in the specified MIME-lang language. This + allows entire directories to be marked as containing Dutch content, for + instance, without having to rename each file. Note that unlike using + extensions to specify languages, DefaultLanguage + can only specify a single language.

    + +

    If no DefaultLanguage directive is in force, + and a file does not have any language extensions as configured + by AddLanguage, then that file + will be considered to have no language attribute.

    + + Example + DefaultLanguage en + +
    +mod_negotiation +
    + + +ModMimeUsePathInfo +Tells mod_mime to treat path_info +components as part of the filename +ModMimeUsePathInfo On|Off +ModMimeUsePathInfo Off +directory +Available in Apache 2.0.41 and later + + +

    The ModMimeUsePathInfo directive is used to + combine the filename with the path_info URL component to + apply mod_mime's directives to the request. The default + value is Off - therefore, the path_info + component is ignored.

    + +

    This directive is recommended when you have a virtual filesystem.

    + + Example + ModMimeUsePathInfo On + + +

    If you have a request for /bar/foo.shtml where + /bar is a Location and ModMimeUsePathInfo is On, + mod_mime will treat the incoming request as + /bar/foo.shtml and directives like AddOutputFilter + INCLUDES .shtml will add the INCLUDES filter to the + request. If ModMimeUsePathInfo is not set, the + INCLUDES filter will not be added.

    +
    +AcceptPathInfo +
    + + +RemoveCharset +Removes any character set associations for a set of file +extensions +RemoveCharset extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +RemoveCharset is only available in Apache 2.0.24 and +later. + + +

    The RemoveCharset directive removes any + character set associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + + Example + RemoveCharset .html .shtml + +
    +
    + + +RemoveEncoding +Removes any content encoding associations for a set of file +extensions +RemoveEncoding extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    The RemoveEncoding directive removes any + encoding associations for files with the given extensions. This + allows .htaccess files in subdirectories to undo + any associations inherited from parent directories or the + server config files. An example of its use might be:

    + + /foo/.htaccess: + AddEncoding x-gzip .gz
    + AddType text/plain .asc
    + <Files *.gz.asc>
    + + RemoveEncoding .gz
    +
    + </Files> +
    + +

    This will cause foo.gz to be marked as being + encoded with the gzip method, but foo.gz.asc as an + unencoded plaintext file.

    + + Note +

    RemoveEncoding directives are processed + after any AddEncoding + directives, so it is possible they may undo the effects of the latter + if both occur within the same directory configuration.

    +
    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +
    + + +RemoveHandler +Removes any handler associations for a set of file +extensions +RemoveHandler extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    The RemoveHandler directive removes any + handler associations for files with the given extensions. This allows + .htaccess files in subdirectories to undo any + associations inherited from parent directories or the server + config files. An example of its use might be:

    + + /foo/.htaccess: + AddHandler server-parsed .html + + + /foo/bar/.htaccess: + RemoveHandler .html + + +

    This has the effect of returning .html files in + the /foo/bar directory to being treated as normal + files, rather than as candidates for parsing (see the mod_include module).

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +
    + + +RemoveInputFilter +Removes any input filter associations for a set of file +extensions +RemoveInputFilter extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +RemoveInputFilter is only available in Apache 2.0.26 and +later. + + +

    The RemoveInputFilter directive removes any + input filter associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +AddInputFilter +SetInputFilter +
    + + +RemoveLanguage +Removes any language associations for a set of file +extensions +RemoveLanguage extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +RemoveLanguage is only available in Apache 2.0.24 and +later. + + +

    The RemoveLanguage directive removes any + language associations for files with the given extensions. This + allows .htaccess files in subdirectories to undo + any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +
    + + +RemoveOutputFilter +Removes any output filter associations for a set of file +extensions +RemoveOutputFilter extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +RemoveOutputFilter is only available in Apache 2.0.26 and +later. + + +

    The RemoveOutputFilter directive removes any + output filter associations for files with the given extensions. + This allows .htaccess files in subdirectories to + undo any associations inherited from parent directories or the + server config files.

    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    + + Example + RemoveOutputFilter shtml + +
    +AddOutputFilter +
    + + +RemoveType +Removes any content type associations for a set of file +extensions +RemoveType extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    The RemoveType directive removes any MIME + type associations for files with the given extensions. This allows + .htaccess files in subdirectories to undo any + associations inherited from parent directories or the server + config files. An example of its use might be:

    + + /foo/.htaccess: + RemoveType .cgi + + +

    This will remove any special handling of .cgi + files in the /foo/ directory and any beneath it, + causing the files to be treated as being of the DefaultType.

    + + Note +

    RemoveType directives are processed + after any AddType + directives, so it is possible they may undo the effects of the + latter if both occur within the same directory configuration.

    +
    + +

    The extension argument is case-insensitive, and can + be specified with or without a leading dot.

    +
    +
    + + +TypesConfig +The location of the mime.types file +TypesConfig file-path +TypesConfig conf/mime.types +server config + + +

    The TypesConfig directive sets the location + of the MIME types configuration file. File-path is relative + to the ServerRoot. This file sets + the default list of mappings from filename extensions to content + types. Most administrators use the provided mime.types + file, which associates common filename extensions with IANA registered + content types. The current list is maintained at http://www.isi.edu/in-notes/iana/assignments/media-types/media-types. + This simplifies the httpd.conf file by providing the + majority of media-type definitions, and may be overridden by + AddType directives as + needed. You should not edit the mime.types file, because + it may be replaced when you upgrade your server.

    + +

    The file contains lines in the format of the arguments to + an AddType directive:

    + + + MIME-type [extension] ... + + +

    The case of the extension does not matter. Blank lines, and lines + beginning with a hash character (#) are ignored.

    + + + Please do not send requests to the Apache HTTP + Server Project to add any new entries in the distributed + mime.types file unless (1) they are already + registered with IANA, and (2) they use widely accepted, + non-conflicting filename extensions across platforms. + category/x-subtype requests will be automatically + rejected, as will any new two-letter extensions as they will + likely conflict later with the already crowded language and + character set namespace. + +
    +mod_mime_magic +
    + +
    diff --git a/trunk/docs/manual/mod/mod_mime.xml.ja b/trunk/docs/manual/mod/mod_mime.xml.ja new file mode 100644 index 0000000000..ed3551b315 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.xml.ja @@ -0,0 +1,890 @@ + + + + + + + + + +mod_mime +$B%j%/%(%9%H$5$l$?%U%!%$%k$N3HD%;R$H%U%!%$%k$N?6$kIq$$(B + ($B%O%s%I%i$H%U%#%k%?(B)$B!"FbMF(B (MIME $B%?%$%W!"8@8l!"J8;z%;%C%H!"%(%s%3!<%G%#%s%0(B) + $B$H$r4XO"IU$1$k(B +$B%Y!<%9(B +mod_mime.c +mime_module + + +

    $B$3$N%b%8%e!<%k$O3HD%;R$r;H$C$F$$$m$$$m$J!V%a%?>pJs!W$r%U%!%$%k$K(B + $B4XO"IU$1$k$?$a$K;HMQ$5$l$^$9!#$3$N>pJs$O%I%-%e%a%s%H$N%U%!%$%kL>$H(B + MIME $B%?%$%W!"8@8l!"J8;z%;%C%H!"%(%s%3!<%G%#%s%0$H$r4XO"IU$1$^$9!#(B + $B$3$N>pJs$O%V%i%&%6$KAw$i$l$^$9$7!"J#?t$N%U%!%$%k$NCf$+$i%f!<%6$N9%$_$N(B + $B$b$N$,A*$P$l$k$h$&$K!"%3%s%F%s%H%M%4%7%(!<%7%g%s$G$b;H$o$l$^$9!#(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $B$K4X$9$k>\$7$$>pJs$O(B mod_negotiation + $B$r$4Mw2<$5$$!#(B

    + +

    AddCharset $B%G%#%l%/%F%#%V!"(B + AddEncoding $B%G%#%l%/%F%#%V!"(B + AddHandler $B%G%#%l%/%F%#%V!"(B + AddLanguage $B%G%#%l%/%F%#%V!"(B + AddType $B%G%#%l%/%F%#%V$O$9$Y$F!"(B + $B%U%!%$%k$N3HD%;R$r%a%?>pJs$K%^%C%W$9$k$?$a$K;HMQ$5$l$^$9!#(B + $B$=$l$>$l!"%I%-%e%a%s%H$NJ8;z%;%C%H(B ($BLuCm(B: charset)$B!"(Bcontent-encoding, + content-language, MIME $B%?%$%W(B (content-type) $B$r@_Dj$7$^$9!#(B + TypesConfig $B%G%#%l%/%F%#%V$O3HD%;R$r(B + MIME $B%?%$%W$K%^%C%W$9$k%U%!%$%k$r;XDj$9$k$?$a$K;HMQ$5$l$^$9!#(B

    + +

    $B$5$i$K!"(Bmod_mime $B$O%3%s%F%s%D$r:n@.!"=hM}$9$k(B + $B%O%s%I%i(B $B$H(B $B%U%#%k%?(B + $B$r@_Dj$9$k$3$H$,$G$-$^$9!#(BAddHandler $B%G%#%l%/%F%#%V!"(BAddOutputFilter $B%G%#%l%/%F%#%V!"(BAddInputFilter $B%G%#%l%/%F%#%V$O(B + $B%I%-%e%a%s%H$r07$&%b%8%e!<%k$d%9%/%j%W%H$r@)8f$7$^$9!#(B + MultiviewsMatch $B%G%#%l%/%F%#%V$O(B + $B$3$l$i$N%G%#%l%/%F%#%V$,;XDj$7$?%U%!%$%k$N3HD%;R$r(B + mod_negotiation $B$,(B Multiviews $B$N%^%C%A$r$H$k$H$-$K(B + $B9MN8$9$k$h$&$K$G$-$^$9!#(B

    + +

    mod_mime $B$O%a%?>pJs$r%U%!%$%kL>$H4XO"IU$1$^$9$,!"(B + core $B%5!<%P$K$O$"$k%3%s%F%J(B + ($B$?$H$($P(B, Location, Directory, Files) $B$NCf$N$9$Y$F$N%U%!%$%k$rFCDj$N(B + $B%a%?>pJs$H4XO"IU$1$k%G%#%l%/%F%#%V$,$"$j$^$9!#$3$l$i$N%G%#%l%/%F%#%V$K$O(B + ForceType, SetHandler, SetInputFilter, SetOutputFilter $B$,$"$j$^$9!#(B + $B%3%"$N%G%#%l%/%F%#%V$O(B mod_mime $B$K$h$jDj5A$5$l$?(B + $B%U%!%$%kL>$N3HD%;R$N%^%C%T%s%0$9$Y$F$r>e=q$-$7$^$9!#(B

    + +

    $B%U%!%$%k$N%a%?>pJs$rJQ$($F$b(B Last-Modified + $B%X%C%@$NCM$OJQ$o$i$J$$$3$H$KCm0U$7$F$/$@$5$$!#$G$9$+$i!"(B + $B$=$l$i$rJQ99$7$?>l9g$O!"%/%i%$%"%s%H$d%W%m%-%7$G0JA0$K%-%c%C%7%e$5$l$?(B + $B%3%T!<$,$=$N$H$-$N%X%C%@$H$H$b$K;H$o$l$k2DG=@-$,$"$j$^$9!#(B + $B%a%?>pJs(B ($B8@8l!"%3%s%F%s%H%?%$%W!"J8;z%;%C%H!"%(%s%3!<%G%#%s%0(B) $B$r(B + $BJQ99$7$?$H$-$O!"$9$Y$F$NK,Ld +

    + +MimeMagicFile +AddDefaultCharset +ForceType +DefaultType +SetHandler +SetInputFilter +SetOutputFilter + +
    $BJ#?t$N3HD%;R$N$"$k%U%!%$%k(B +

    $B%U%!%$%k$OJ#?t$N3HD%;R$r;}$D$3$H$,$G$-!"3HD%;R$N=gHV$O(B$BDL>o$O(B$B4X78$"$j$^$;$s!#Nc$($P!"%U%!%$%k(B welcome.html.fr + $B$,%3%s%F%s%H%?%$%W$O(B text/html + $B$K!"8@8l$O%U%i%s%98l$K%^%C%W$5$l$k>l9g!"(Bwelcome.fr.html + $B$b$^$C$?$/F1$8>pJs$K%^%C%W$5$l$^$9!#(B + $BF1$8%a%?>pJs$K%^%C%W$5$l$k3HD%;R$,J#?t$"$k$H$-$K$O!"8@8l$H(B + $B%3%s%F%s%H%(%s%3!<%G%#%s%0$r=|$$$F!"(B + $B1&B&$K$"$k$b$N$,;HMQ$5$l$^$9!#$?$H$($P!"(B.gif $B$,(B MIME + $B%?%$%W(B image/gif $B$K%^%C%W$5$l!"(B.html + $B$,(B MIME $B%?%$%W(B text/html + $B$K%^%C%W$5$l$k>l9g$O!"%U%!%$%k(B welcome.gif.html $B$O(B + MIME $B%?%$%W(B text/html $B$K4XO"IU$1$i$l$^$9!#(B

    + +

    $B%j%=!<%9$KJ#?t$N8@8l$d%(%s%3!<%G%#%s%0$r4XO"IU$1$k$3$H(B + $B$,$G$-$k$?$a!"(B + $B8@8l(B$B$H(B$B%3%s%F%s%H%(%s%3!<%G%#%s%0(B$B$OA0$N$b$N$KDI2C$5$l$F$$$-$^$9!#(B + $B$?$H$($P!"%U%!%$%k(B welcome.html.en.de $B$O(B + Content-Language: en, de $B$H(B Content-Type: + text/html $B$H$7$FAw?.$5$l$^$9!#(B

    + +

    $BJ#?t$N3HD%;R$N$"$k%U%!%$%k$,(B MIME + $B%?%$%W$H%O%s%I%i$NN>J}$K4XO"IU$1$i$l$F$$$k$H$-$OCm0U$9$kI,MW$,$"$j$^$9!#(B + $B$=$N>l9g!"IaDL$O%j%/%(%9%H$,%O%s%I%i$K4XO"IU$1$i$l$?(B + $B%b%8%e!<%k$K$h$C$F07$o$l$k$3$H$K$J$j$^$9!#$?$H$($P!"3HD%;R(B + .imap $B$,(B (mod_imagemap $B$N(B) imap-file + $B$K%^%C%W$5$l$F$$$F!"(B.html $B$,(B MIME $B%?%$%W(B text/html + $B$K%^%C%W$5$l$F$$$k$H$-$O!"%U%!%$%k(B world.imap.html $B$O(B + imap-file $B%O%s%I%i$H(B text/html MIME + $B%?%$%W$K4XO"IU$1$i$l$^$9!#%U%!%$%k$,=hM}$5$l$k$H$-$O(B imap-file + $B%O%s%I%i$,;HMQ$5$l$^$9$N$G!"$=$N%U%!%$%k$O(B mod_imagemap + $B$N%$%a!<%8%^%C%W%U%!%$%k$H$7$F07$o$l$k$3$H$K$J$j$^$9!#(B

    +
    + +
    $B%3%s%F%s%H%(%s%3!<%G%#%s%0(B +

    $BFCDj$N(B MIME $B%?%$%W$N%U%!%$%k$O%$%s%?!<%M%C%H$G$NE>Aw$r4JC1$K$9$k$?$a$K!"(B + $B$5$i$KId9f2=$9$k$3$H$,$G$-$^$9!#$3$l$ODL>o$O(B gzip $B$N(B + $B$h$&$J05=L$N$3$H$r;X$7$^$9$,!"(Bpgp $B$N$h$&$J0E9f2=$d!"(B + $B%P%$%J%j%U%!%$%k$r(B ASCII ($B%F%-%9%H(B) $B7A<0$GAw$k$?$a$K9M0F$5$l$?(B + UUencoding $B$N$3$H$r;X$9$3$H$b$"$j$^$9!#(B

    + +

    HTTP/1.1 RFC + 14.11 $B@a$G$O + +

    +

    Content-Encoding $B%(%s%F%#%F%#%X%C%@%U%#!<%k%I$O%a%G%#%"%?%$%W$N(B + $B=$>~;R$H$7$F;H$o$l$^$9!#$=$l$,B8:_$7$F$$$l$P!"CM$O%(%s%F%#%F%#%\%G%#$K(B + $B$I$NDI2C$NId9f2=$,E,MQ$5$l$?$+$r<($7!"(BContent-Type $B%X%C%@%U%#!<%k%I$K(B + $B=q$+$l$F$$$k%a%G%#%"%?%$%W$rF@$k$?$a$K$I$NI|9f5!9=$rE,MQ$9$Y$-$+!"$b(B + $B<($7$F$$$k$3$H$K$J$j$^$9!#(BContent-Encoding $B$O +

    + +

    $BJ#?t$N%U%!%$%k3HD%;R(B ($BJ#?t$N3HD%;R$K$D$$$F$O(B $B>e$N@a(B $B$r;2>H(B) $B;H$&$3$H$G!"(B + $B%U%!%$%k$N(B$B%?%$%W(B$B$d(B$B%(%s%3!<%G%#%s%0(B$B$r;XDj$9$k$3$H$,(B + $B$G$-$^$9!#(B

    + +

    $B$?$H$($P!"(BMicrosoft Word $B$N%I%-%e%a%s%H$,$"$j!"%5%$%:$r>.$5$/$9$k$?$a$K(B + pkzip $B$5$l$F$$$k$H$7$^$9!#(B.doc $B3HD%;R$,(B Microsoft Word $B$N(B + $B%U%!%$%k%?%$%W$H4XO"IU$1$i$l$F$$$F!"(B.zip $B3HD%;R$,(B + pkzip $B%U%!%$%k%(%s%3!<%G%#%s%0$H4XO"IU$1$i$l$F$$$k$H!"%U%!%$%k(B + Resume.doc.zip $B$O(B pkzip $B$5$l$?(B Word $B%I%-%e%a%s%H$G$"$k(B + $B$H$$$&$3$H$,$o$+$j$^$9!#(B

    + +

    $B%/%i%$%"%s%H$N%V%i%&%6$K%(%s%3!<%G%#%s%0J}K!$rCN$i$;$k$?$a$K!"(B + Apache $B$O%j%=!<%9$H6&$K(B Content-Encoding $B%X%C%@$r(B + $BAw$j$^$9!#(B

    + + Content-encoding: pkzip +
    + +
    $BJ8;z%;%C%H$H8@8l(B +

    $B%U%!%$%k%?%$%W$H%U%!%$%k%(%s%3!<%G%#%s%0$NB>$K=EMW$J>pJs$O(B + $B%I%-%e%a%s%H$N=q$+$l$F$$$k8@8l$H!"$I$NJ8;z%;%C%H$G%U%!%$%k$,I=<((B + $B$5$l$k$Y$-$+!"$H$$$&$b$N$G$9!#$?$H$($P!"%I%-%e%a%s%H$O%Y%H%J%`$N(B + $B%"%k%U%!%Y%C%H$d%-%j%kJ8;z$G=q$+$l$F$$$F!"$=$N$h$&$KI=<($5$l$k(B + $BI,MW$,$"$k$+$b$7$l$^$;$s!#$3$N>pJs$b$^$?!"(BHTTP $B%X%C%@$G(B + $BAw?.$5$l$^$9!#(B

    + +

    $BJ8;z%;%C%H!"8@8l!"%(%s%3!<%G%#%s%0!"(Bmime $B%?%$%W$O$9$Y$F(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s(B (mod_negotiation $B;2>H(B) + $B$N:GCf$K!"J#?t$NJ8;z%;%C%H!"8@8l!"%(%s%3!<%G%#%s%0!"(BMIME $B%?%$%W$+$i$J$k(B + $BBeBXJ*$,$"$k$H$-$K$I$N%I%-%e%a%s%H$r%/%i%$%"%s%H$KAw$k$N$+$r(B + $B7hDj$9$k$H$-$K;H$o$l$^$9!#(BAddCharset, + AddEncoding, AddLanguage, + AddType $B$N3F%G%#%l%/%F%#%V$G:n@.$5$l$?(B + $B3HD%;R$N4XO"IU$1(B ($B$H(B MimeMagicFile $B$G%j%9%H$5$l$F$$$k(B + $B3HD%;R(B) $B$,$3$NA*Br$K;22C$7$^$9!#(BAddHandler, + AddInputFilter, + AddOutputFilter $B$N(B + $B3F%G%#%l%/%F%#%V$G$N$_4XO"IU$1$i$l$F$$$k3HD%;R$O(B + MultiviewsMatch $B%G%#%l%/%F%#%V$r(B + $B;H$&$3$H$G%^%C%A$N(B + $B=hM}$K4^$a$k$3$H$b30$9$3$H$b$G$-$^$9!#(B

    + +
    Charset +

    $B$5$i$K>pJs$rEA$($k$?$a$K!"(BApache $B$OJ8=q$N8@8l$r(B + Content-Language $B%X%C%@$GAw$k$3$H$b$"$j$^$9!#(B + $B$^$?!">pJs$r@5$7$/I=<($9$k$?$a$K;HMQ$9$Y$-J8;z%;%C%H$r<($9$?$a$K(B + Conten-Type $B%X%C%@$K>pJs$rDI2C$9$k$3$H$b$"$j$^$9!#(B

    + + + Content-Language: en, fr
    + Content-Type: text/plain; charset=ISO-8859-1 +
    + +

    $B8@8l$N;XDj$OFsJ8;z$NC;=L7A$G9T$J$o$l$^$9!#(Bcharset $B$,(B + $B;HMQ$9$Y$-J8;z%;%C%H$NL>A0$G$9!#(B

    +
    +
    + + +AddCharset +$B%U%!%$%kL>$N3HD%;R$r;XDj$5$l$?J8;z%;%C%H$K%^%C%W$9$k(B +AddCharset charset extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    AddCharset $B%G%#%l%/%F%#%V$O!"(B + $BM?$($i$l$?3HD%;R$r;XDj$5$l$?(B charset $B$K%^%C%W$7$^$9!#(Bcharset + $B$O!"3HD%;R(B extension $B$r4^$s$G$$$k%U%!%$%kL>$N(B + MIME charset + $B%Q%i%a!<%?(B$B$G$9!#?7$7$$%^%C%T%s%0$O4{$K$"$kB>$N%^%C%T%s%0$KDI2C$5$l!"F1$83HD%;R(B + extension $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B

    + + $BNc(B + AddLanguage ja .ja
    + AddCharset EUC-JP .euc
    + AddCharset ISO-2022-JP .jis
    + AddCharset SHIFT_JIS .sjis +
    + +

    $B$3$N>l9g!"%I%-%e%a%s%H(B xxxx.ja.jis $B$O(B charset $B$,(B + ISO-2022-JP $B$NF|K\8l$N%I%-%e%a%s%H$H$7$F07$o$l$^$9(B + (xxxx.jis.ja $B$bF1MM(B)$B!#(BAddCharset + $B%G%#%l%/%F%#%V$O!"%I%-%e%a%s%H$,E,@Z$K2rpJs$r%/%i%$%"%s%H$K65$($k$?$a$KLr$KN)$A$^$9!#(B + $B$^$?!"%5!<%P$,%/%i%$%"%s%H$N(B charset + $B$NM%@hEY$K4p$E$$$FJ#?t$N%I%-%e%a%s%H$NCf$+$i%I%-%e%a%s%H$rA*$V(B$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B$B$N$?$a$K$bLr$KN)$A$^$9!#(B

    + +

    $B0z?t(B extension$B$OBgJ8;z>.J8;z$r6hJL$;$:!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +mod_negotiation +AddDefaultCharset +
    + + +AddEncoding +$B%U%!%$%kL>$N3HD%;R$r;XDj$5$l$?%(%s%3!<%G%#%s%0(B +$B$K%^%C%W$9$k(B +AddEncoding MIME-enc extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    AddEncoding $B%G%#%l%/%F%#%V$O!"(B + $BM?$($i$l$?3HD%;R$r;XDj$5$l$?%(%s%3!<%G%#%s%0$K%^%C%W$7$^$9!#(B + MIME-enc $B$O!"3HD%;R(B extension + $B$r4^$s$@%I%-%e%a%s%H$K;HMQ$9$k(B MIME $B%(%s%3!<%G%#%s%0$G$9!#(B + $B$3$N?7$7$$%^%C%T%s%0$O4{$K$"$kB>$N%^%C%T%s%0$KDI2C$5$l!"(B + $BF1$83HD%;R(B extension $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B

    + + $BNc(B + AddEncoding x-gzip .gz
    + AddEncoding x-compress .Z
    +
    + +

    $B$3$l$O!"3HD%;R(B .gz $B$r4^$`%U%!%$%kL>$,(B x-gzip + $B%(%s%3!<%G%#%s%0$r;H$C$F%(%s%3!<%I$5$l$F$$$k$3$H$H!"3HD%;R(B .Z + $B$r4^$`%U%!%$%kL>$,(B x-compress + $B$G%(%s%3!<%I$5$l$F$$$k$3$H$r;XDj$7$^$9!#(B

    + +

    $B8E$$%/%i%$%"%s%H$O(B x-zip $B$H(B x-compress + $B$,JV$C$F$/$k$3$H$r4|BT$7$^$9$,!"I8=`5,3J$G$O$=$l$>$l(B + gzip $B$H(B compress + $B$HEy2A$G$"$k$3$H$K$J$C$F$$$^$9!#(BApache + $B$O!"%3%s%F%s%H%(%s%3!<%G%#%s%0$NHf3S$r$9$k$H$-$K$O!"@hF,$K$"$k(B + x- $B$rL5;k$7$^$9!#(BApache + $B$,%(%s%3!<%G%#%s%0IU$-$G1~Ez$rJV$9$H$-$O!"%/%i%$%"%s%H$,MW5a$7$?7A<0(B + ($B$9$J$o$A(B$B!"(Bx-foo $B$d(B foo) + $B$r;HMQ$7$^$9!#MW$9$k$K!"$3$NFs$D$N%(%s%3!<%G%#%s%0$N>l9g$O>o$K(B + x-gzip $B$H(B x-compress + $B$r;H$&$Y$-$G$"$k!"$H$$$&$3$H$G$9!#(Bdeflate + $B$N$h$&$J$h$j?7$7$$%(%s%3!<%G%#%s%0$G$O!"(Bx- + $B$J$7$G;XDj$7$F$/$@$5$$!#(B +

    + +

    $B0z?t(B extension $B$OBgJ8;z>.J8;z$r6hJL$;$:!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +
    + + +AddHandler +$B%U%!%$%kL>$N3HD%;R$r;XDj$5$l$?%O%s%I%i$K%^%C%W$9$k(B +AddHandler handler-name extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    $B3HD%;R(B extension $B$,L>A0$K$"$k%U%!%$%k$O;XDj$5$l$?(B handler-name $B$K07$o$l$^$9!#(B + $B$3$N?7$7$$%^%C%T%s%0$O4{$K$"$kB>$N%^%C%T%s%0$KDI2C$5$l!"(B + $BF1$83HD%;R(B extension + $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#$?$H$($P!"3HD%;R(B + ".cgi" $B$G=*$o$k%U%!%$%k$r(B CGI + $B%9%/%j%W%H$H$7$F07$$$?$$$H$-$O!"0J2<$N@_Dj$r$7$^$9!#(B

    + + + AddHandler cgi-script .cgi + + +

    $B$3$l$r(B httpd.conf $B%U%!%$%k$K5-=R$9$k$3$H$G!"3HD%;R(B + ".cgi" $B$N%U%!%$%k$O(B CGI $B%W%m%0%i%`$H$7$F07$o$l$^$9!#(B +

    + +

    $B0z?t(B extension $B$OBgJ8;z>.J8;z$r6hJL$;$:!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +SetHandler +
    + + +AddInputFilter +$B%U%!%$%k$N3HD%;R$r%/%i%$%"%s%H$N%j%/%(%9%H$r=hM}$9$k(B + $B%U%#%k%?$K%^%C%W$9$k(B +AddInputFilter filter[;filter...] +extension [extension] ... +server configvirtual host +directory.htaccess +FileInfo +2.0.26 $B0J9_$G;HMQ2DG=(B + + +

    AddInputFilter $B$O%U%!%$%k$N3HD%;R(B + extension $B$r%/%i%$%"%s%H$N%j%/%(%9%H$d(B POST $B$,%5!<%P$KMh$?$H$-$K(B + $B=hM}$r$9$k(B$B%U%#%k%?(B$B$K%^%C%W$7$^$9!#(B + $B$3$l$O!"(BSetInputFilter $B%G%#%l%/%F%#%V$b(B + $B4^$a!"B>$N>l=j$GDj5A$5$l$F$$$k%U%#%k%?$K2C$($i$l$^$9!#(B + $B$3$N%^%C%T%s%0$O$9$G$K$"$k$b$N$h$jM%@h$5$l$F%^!<%8$5$l!"(B + $BF1$8(B extension $B$KBP$9$k4{B8$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B

    + +

    $BJ#?t$N%U%#%k%?$r;XDj$9$k$H$-$O!"%G!<%?$r=hM}$9$k=gHV$K%;%_%3%m%s$G(B + $B7R$$$G=q$/I,MW$,$"$j$^$9!#%U%#%k%?$H(B extension $B$H$N(B + $BN>J}$N0z?t$OBgJ8;z>.J8;z$r6hJL$;$:!"3HD%;R$N:G=i$N%I%C%H$O(B + $B$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +RemoveInputFilter +SetInputFilter +
    + + +AddLanguage +$B%U%!%$%kL>$r;XDj$5$l$?8@8l$K%^%C%W(B +AddLanguage MIME-lang extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    AddLanguage $B%G%#%l%/%F%#%V$O!"M?$($i$l$?3HD%;R$r;XDj$5$l$?(B + content language $B$K%^%C%W$7$^$9!#(BMIME-lang $B$O!"3HD%;R(B + extension $B$r4^$s$G$$$k%U%!%$%kL>$N(B MIME $B$K$*$1$k8@8l$G$9!#(B + $B$3$N?7$7$$%^%C%T%s%0$O4{$K$"$k%^%C%T%s%0$KDI2C$5$l!"F1$83HD%;R(B + extension $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B

    + + $BNc(B + AddEncoding x-compress .Z
    + AddLanguage en .en
    + AddLanguage fr .fr +
    + +

    $B$3$N>l9g!"(Bxxxx.en.Z $B%I%-%e%a%s%H$O(B compress + $B$5$l$?1Q8l$N%I%-%e%a%s%H$H$7$F07$o$l$^$9(B (xxxx.Z.en + $B$bF1MM(B)$B!#(Bcontent language $B$O%/%i%$%"%s%H$KDLCN$5$l$^$9$,!"(B + $B%V%i%&%6$,$3$N>pJs$r;H$&$3$H$O$*$=$i$/$"$j$^$;$s!#(B + AddLanguage + $B%G%#%l%/%F%#%V$O!"%5!<%P$,%/%i%$%"%s%H$N8@8l$NM%@hEY$K4p$E$$$FJ#?t$N(B + $B%I%-%e%a%s%H$NCf$+$i%I%-%e%a%s%H$rA*$V(B$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B$B$N$?$a$K$h$jLr$KN)$A$^$9!#(B

    + +

    $BJ#?t$N8@8l$,F1$83HD%;R$K3d$jEv$F$i$l$F$$$k$H$-$O!"(B + $B:G8e$N$b$N$,;HMQ$5$l$^$9!#$9$J$o$A!"l9g!"(B

    + + + AddLanguage en .en
    + AddLanguage en-gb .en
    + AddLanguage en-us .en +
    + +

    $B3HD%;R(B .en $B$N$"$k%I%-%e%a%s%H$O(B + en-us $B$H$7$F07$o$l$^$9!#(B

    + +

    $B0z?t(B extension $B$OBgJ8;z>.J8;z$r6hJL$;$:!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +mod_negotiation +
    + + +AddOutputFilter +$B%U%!%$%kL>$N3HD%;R$r%5!<%P$+$i$N1~Ez$r=hM}$9$k%U%#%k%?$K(B + $B%^%C%W$9$k(B +AddOutputFilter filter[;filter...] +extension [extension] ... +server configvirtual host +directory.htaccess +FileInfo +2.0.26 $B0J9_$G;HMQ2DG=(B + + +

    AddOutputFilter $B%G%#%l%/%F%#%V$O(B + $B3HD%;R(B extension $B$r%5!<%P$N1~Ez$,%/%i%$%"%s%H$KAw$i$l$k(B + $BA0$K=hM}$9$k(B$B%U%#%k%?(B$B$rDj5A$7$^$9!#(B + $B$3$l$O(B SetOutputFilter + $B%G%#%l%/%F%#%V$H(B AddOutputFilterByType $B%G%#%l%/%F%#%V(B + $B$r4^$a!"B>$N>l=j$GDj5A$5$l$F$$$k%U%#%k%?$K2C$($i$l$^$9!#(B + $B$3$N?7$7$$%^%C%T%s%0$O4{$K$"$k%^%C%T%s%0$KDI2C$5$l!"F1$83HD%;R(B + extension $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B

    + +

    $BNc$($P!"0J2<$N@_Dj$O$9$Y$F$N(B .shtml $B%U%!%$%k$r(B SSI $B$G=hM}$7!"(B + $B$=$N=PNO$r(B mod_deflate $B$r;H$C$F05=L$7$^$9!#(B

    + + + AddOutputFilter INCLUDES;DEFLATE shtml + + +

    $BJ#?t$N%U%#%k%?$r;XDj$9$k$H$-$O!"%G!<%?$r=hM}$9$k=gHV$K%;%_%3%m%s$G(B + $B7R$$$G=q$/I,MW$,$"$j$^$9!#(Bfilter $B$H(B extension $B$N(B + $BN>0z?t$OBgJ8;z>.J8;z$r6hJL$;$:!"3HD%;R$N:G=i$N%I%C%H$O(B + $B$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +RemoveOutputFilter +SetOutputFilter +
    + + +AddType +$B%U%!%$%kL>$N3HD%;R$r;XDj$5$l$?%3%s%F%s%H%?%$%W$K%^%C%W(B +AddType MIME-type extension +[extension] ... +server configvirtual host +directory.htaccess +FileInfo + + +

    AddType $B%G%#%l%/%F%#%V$O!"(B + $BM?$($i$l$?3HD%;R$r;XDj$5$l$?%3%s%F%s%H%?%$%W$K%^%C%W$7$^$9!#(B + MIME-type $B$O3HD%;R(B extension + $B$r4^$s$@%I%-%e%a%s%H$K;HMQ$9$k(B MIME $B%?%$%W$G$9!#(B + $B$3$N?7$7$$%^%C%T%s%0$O4{$K$"$k%^%C%T%s%0$KDI2C$5$l!"F1$83HD%;R(B + extension $B$N$?$a$N%^%C%T%s%0$r>e=q$-$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$O(B MIME $B%?%$%W%U%!%$%k(B (TypesConfig $B%G%#%l%/%F%#%V$r;2>H(B) + $B$KL5$$%^%C%T%s%0$rDI2C$9$k$?$a$K;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + + $BNc(B + AddType image/gif .gif + + + + $B?7$7$$(B MIME $B%?%$%W$O!"(BTypesConfig + $B%U%!%$%k$rJQ99$9$k$N$G$O$J$/!"(BAddType + $B%G%#%l%/%F%#%V$r;H$C$FDI2C$9$k$3$H$,?d>)$5$l$F$$$^$9!#(B + + +

    $B0z?t(B extension $B$OBgJ8;z>.J8;z$r6hJL$;$:!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +DefaultType +ForceType +
    + + +MultiviewsMatch +MultiViews $B$G$N%^%C%A%s%0$N8!:w$K4^$^$;$k(B +$B%U%!%$%k$N%?%$%W$r;XDj$9$k(B +MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] +MultiviewsMatch NegotiatedOnly +server configvirtual host +directory.htaccess +FileInfo +2.0.26 $B0J9_$G;HMQ2DG=(B + + +

    MultiviewsMatch $B$r;HMQ$9$k$3$H$G!"(B + mod_negotiation $B$N(B + Multiviews $B$K(B 3 $Bindex.html) + $B$KBP$9$k%j%/%(%9%H$KBP$7$F!"%M%4%7%(!<%7%g%s$9$k3HD%;R$,%Y!<%9$KIU$$$?$b$N(B + (index.html.en, index.html.fr $B$d(B + index.html.gz) + $B$r%^%C%A$5$;$k$3$H$,$G$-$^$9!#(B

    + +

    NegotiatedOnly $B%*%W%7%g%s$G$O!"%Y!<%9L>$KB3$/3HD%;RA4$F$,(B + $B%3%s%F%s%H%M%4%7%(!<%7%g%s$G(B mod_mime + $B$,G'<1$9$k3HD%;R(B ($BNc(B $BJ8;z%;%C%H!"%3%s%F%s%H%?%$%W!"8@8l$d%(%s%3!<%G%#%s%0(B) + $B$K4XO"IU$1$i$l$F$$$J$1$l$P$J$j$^$;$s!#$3$l$OI{:nMQ$N:G$b>/$J$$(B + $B:G$bE*3N$J + +

    $B%O%s%I%i$H%U%#%k%?$NN>J}$b$7$/$OJRJ}$H4XO"IU$1$i$l$?3HD%;R$r4^$a$k$K$O!"(B + MultiviewsMatch $B%G%#%l%/%F%#%V$K(B Handlers, + Filters $B$^$?$O$=$NN>J}$N%*%W%7%g%s$r%;%C%H$7$^$9!#(B + $B$b$7B>$N>r7o$,F1$8$G$"$l$P!":G$b>.$5$$%U%!%$%k$,Aw?.$5$l$^$9!#(B + $BNc$($P!"(B500 $BJ8;z$N(B index.html.cgi $B$H(B 1000 $B%P%$%H$N(B + index.html.pl $B$G$"$l$P!"(B.cgi + $B$N%U%!%$%k$,M%@h$5$l$^$9!#(B.asis $B%U%!%$%k$rMxMQ$7$F$$$k%f!<%6$O!"(B + .asis $B%U%!%$%k$,(B asis-handler $B$K4XO"IU$1$i$l$F$$$k$H$-$K$O!"(B + $B%O%s%I%i%*%W%7%g%s$N;HMQ$r9%$`$G$7$g$&!#(B

    + +

    $B:G8e$K!"(Bmod_mime $B$,G'<1$7$J$$3HD%;R$G$"$m$&$H$b!"(B + $B$I$s$J3HD%;R$G$b%^%C%A$5$;$k(B Any $B$,;HMQ$G$-$^$9!#(B + $B$3$N5sF0$O(B Apache 1.3 $B$N$H$-$HF1$8$b$N$G!"M=4|$7$J$$F0:n!"Nc$($P(B .old $B$d(B + .bak $B%U%!%$%k$H$$$C$?%&%'%V%^%9%?$,Aw?.$r0U?^$7$F$$$J$$(B + $B%U%!%$%k$rAw?.$9$k!"$H$$$C$?F0:n$r9T$J$&2DG=@-$,$"$j$^$9!#(B

    + +

    $BNc$($P + + + MultiviewsMatch Handlers Filters + + + +Options +mod_negotiation + + + +DefaultLanguage +$B$"$k%9%3!<%W$N$9$Y$F$N%U%!%$%k$r;XDj$5$l$?8@8l$K(B +$B@_Dj$9$k(B +DefaultLanguage MIME-lang +server configvirtual host +directory.htaccess +FileInfo + + +

    DefaultLanguage $B%G%#%l%/%F%#%V$O!"(BApache + $B$,%G%#%l%/%F%#%V$N%9%3!<%W(B ($BNc$($P(B$B!"$=$N;~E@$N(B + Directory + $B$NHO0O(B) $B$K$"$k!"L@<(E*$J8@8l3HD%;R(B + (AddLanguage $B$G@_Dj$5$l$k(B + .fr $B$d(B .de) $B$N$J$$A4$F$N%U%!%$%k$r!";XDj$5$l$?(B + MIME-lang $B8@8l$G$"$k$H$_$J$9$h$&$K$7$^$9!#(B + $B$3$l$K$h$j!"$9$Y$F$N%U%!%$%kL>$rJQ$($k$3$H$J$/!"(B + $B%G%#%l%/%H%j$,%*%i%s%@8l$N%3%s%F%s%H$r4^$s$G$$$k!"(B + $B$H$$$&$h$&$J$3$H$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $B3HD%;R$r;HMQ$7$F8@8l$r;XDj$9$kJ}K!$H0c$$!"(B + DefaultLanguage + $B$O0l$D$N8@8l$7$+;XDj$G$-$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B

    + +

    DefaultLanguage + $B%G%#%l%/%F%#%V$,M-8z$G$J$/!"%U%!%$%k$K(B + AddLanguage + $B$G@_Dj$5$l$?8@8l$N3HD%;R$,$J$$$H$-$O!"(B + $B%U%!%$%k$K$O8@8lB0@-$,$J$$$H$_$J$5$l$^$9!#(B

    + + $BNc(B + DefaultLanguage en + +
    +mod_negotiation +
    + + +ModMimeUsePathInfo +path_info $B%3%s%]!<%M%s%H$r%U%!%$%kL>$N0lIt$H$7$F07$&$h$&$K(B +mod_mime $B$KDLCN$9$k(B +ModMimeUsePathInfo On|Off +ModMimeUsePathInfo Off +directory +Apache 2.0.41 $B0J9_(B + + +

    ModMimeUsePathInfo $B%G%#%l%/%F%#%V$O!"(B + mod_mime $B$N;}$D%G%#%l%/%F%#%V$r(B + $B%j%/%(%9%H$KE,MQ$5$;$k$?$a$K!"%U%!%$%kL>$H(B path_info URL + $B%3%s%]!<%M%s%H$r7k9g$5$;$k$?$a$K;HMQ$7$^$9!#(B + $B%G%U%)%k%H$G$O!V(B Off $B!W$G!"(Bpath_info + $B%3%s%]!<%M%s%H$OL5;k$5$l$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O!"%P!<%A%c%k%U%!%$%k%7%9%F%`$r;HMQ$7$F$$$k:]$K(B + $B?d>)$5$l$k%G%#%l%/%F%#%V$G$9!#(B

    + + $BNc(B + ModMimeUsePathInfo On + + +

    /bar $B$,B8:_$7$F(B (foo.shtml $B$OB8:_$7$J$$(B) + ModMimeUsePathInfo $B$,(B On $B$G$"$k$H$7$F!"(B + /bar/foo.shtml $B$KBP$9$k%j%/%(%9%H$rH/9T$7$?>l9g!"(B + mod_mime $B$OF~$C$F$-$?%j%/%(%9%H$r(B + /bar/foo.shtml $B$H$7$F07$$!"(B + AddOutputFileter INCLUDES .shtml $B$N$h$&$J%G%#%l%/%F%#%V$O(B + INCLUDES $B%U%#%k%?$r%j%/%(%9%H$KIU2C$5$;$^$9!#(B + ModMimeUsePathInfo $B$,@_Dj$5$l$J$1$l$P!"(B + INCLUDES $B%U%#%k%?$OIU2C$5$l$^$;$s!#(B

    +
    +AcceptPathInfo +
    + + +RemoveCharset +$B%U%!%$%k$N3HD%;R$K4XO"IU$1$i$l$?$9$Y$F$NJ8;z%;%C%H(B +$B$r2r=|$9$k(B +RemoveCharset extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +2.0.24 $B0J9_$G;HMQ2DG=(B + + +

    RemoveCharset $B%G%#%l%/%F%#%V(B + $B$OM?$($i$l$?3HD%;R$K4XO"IU$1$i$l$?J8;z%;%C%H$rC$7$^$9!#(B + $B$3$l$K$h$j!"%5%V%G%#%l%/%H%j$K$"$k(B .htaccess + $B%U%!%$%k$,?F%G%#%l%/%H%j$d%5!<%P$N@_Dj%U%!%$%k(B + $B$+$i7Q>5$7$?4XO"IU$1$rC$9$3$H$,$G$-$^$9!#Nc$($P(B:

    + +

    extension $B$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B + $B$^$?!":G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    + + $BNc(B + RemoveCharset .html .shtml + +
    +
    + + +RemoveEncoding +$B%U%!%$%k$N3HD%;R$K4XO"IU$1$i$l$?$9$Y$F$N%3%s%F%s%H%(%s%3!<%G%#%s%0(B +$B$r2r=|$9$k(B +RemoveEncoding extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    RemoveEncoding $B%G%#%l%/%F%#%V$O!"(B + $BM?$($i$l$?3HD%;R$K4XO"IU$1$i$l$?%(%s%3!<%G%#%s%0$rC$7$^$9!#(B + $B$3$l$K$h$j!"%5%V%G%#%l%/%H%j$K$"$k(B .htaccess + $B%U%!%$%k$,?F%G%#%l%/%H%j$d%5!<%P$N@_Dj%U%!%$%k$+$i7Q>5$7$?4XO"IU$1$r(B + $BC$9$3$H$,$G$-$^$9!#(B

    + + /foo/.htaccess: + AddEncoding x-gzip .gz
    + AddType text/plain .asc
    + <Files *.gz.asc>
    + + RemoveEncoding .gz
    +
    + </Files> +
    + +

    $B$3$l$O!"(Bfoo.gz $B$O(B gzip + $B$G%(%s%3!<%I$5$l$F$$$k$3$H$r;XDj$7$^$9$,!"(Bfoo.gz.asc + $B$O%(%s%3!<%I$5$l$F$$$J$$%W%l!<%s%F%-%9%H$N(B + $B%U%!%$%k$G$"$k$H$$$&$3$H$r;XDj$7$^$9!#(B

    + + $BCm0U(B +

    RemoveEncoding $B$O(B + AddEncoding + $B%G%#%l%/%F%#%V$N(B$B8e(B$B$G=hM}$5$l$^$9$N$G!"(B + $BF1$8%G%#%l%/%H%j$N@_DjCf$KN>J}$,8=$l$k$H!"(B + $B8eC$5$l$k2DG=@-$,$"$j$^$9!#(B

    +
    + +

    extension $B$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B + $B$^$?!":G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +
    + + +RemoveHandler +$B%U%!%$%k$N3HD%;R$K4XO"IU$1$i$l$?$9$Y$F$N%O%s%I%i$r(B +$B2r=|$9$k(B +RemoveHandler extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    RemoveHandler $B%G%#%l%/%F%#%V(B + $B$OM?$($i$l$?3HD%;R$K4XO"IU$1$i$l$?%O%s%I%i$rC$7$^$9!#(B + $B$3$l$K$h$j!"%5%V%G%#%l%/%H%j$K$"$k(B .htaccess + $B%U%!%$%k$,?F%G%#%l%/%H%j$d%5!<%P$N@_Dj%U%!%$%k(B + $B$+$i7Q>5$7$?4XO"IU$1$rC$9$3$H$,$G$-$^$9!#$?$H$($P(B:

    + + /foo/.htaccess: + AddHandler server-parsed .html + + + /foo/bar/.htaccess: + RemoveHandler .html + + +

    $B$3$l$O!"(B/foo/bar $B%G%#%l%/%H%j$N(B .html + $B%U%!%$%k$O(B SSI (mod_include $B%b%8%e!<%k;2>H(B) $B$G$O$J$/!"(B + $BIaDL$N%U%!%$%k$H$7$F07$o$l$k$h$&$K$9$k8z2L$,$"$j$^$9!#(B +

    + +

    extension $B$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B + $B$^$?!":G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +
    + + +RemoveInputFilter +$B%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?F~NO%U%#%k%?$r2r=|$9$k(B +RemoveInputFilter extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +2.0.26 $B0J9_$G;HMQ2DG=(B + + +

    RemoveInputFilter $B%G%#%l%/%F%#%V$O(B + $B;XDj$5$l$?%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?F~NO%U%#%k%?$r2r=|$7$^$9!#(B + $B$3$l$rMxMQ$9$k$3$H$G!"?F%G%#%l%/%H%j$d%5!<%P@_Dj%U%!%$%k$+$i(B + $B7Q>5$7$?4XO"IU$1$r(B $B%5%V%G%#%l%/%H%jFb$K$*$$$F(B + .htaccess $B%U%!%$%k$GC$9$3$H$,$G$-$^$9!#(B

    + +

    extension $B0z?t$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#$^$?!"(B + $B:G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +AddInputFilter +SetInputFilter +
    + + +RemoveLanguage +$B%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?8@8l$r2r=|$9$k(B +RemoveLanguage extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +2.0.24 $B0J9_$G;HMQ2DG=(B + + +

    RemoveLanguage $B%G%#%l%/%F%#%V$O(B + $B;XDj$5$l$?%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?8@8l$r2r=|$7$^$9!#(B + $B$3$l$rMxMQ$9$k$3$H$G!"?F%G%#%l%/%H%j$d%5!<%P@_Dj%U%!%$%k$+$i(B + $B7Q>5$7$?4XO"IU$1$r(B $B%5%V%G%#%l%/%H%jFb$K$*$$$F(B + .htaccess $B%U%!%$%k$GC$9$3$H$,$G$-$^$9!#(B

    + +

    extension $B0z?t$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#$^$?!"(B + $B:G=i$N%I%C%H$O$D$$$F$b$D$+$J$/$F$b9=$$$^$;$s!#(B

    +
    +
    + + +RemoveOutputFilter +$B%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?=PNO%U%#%k%?$r2r=|$9$k(B +RemoveOutputFilter extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo +2.0.26 $B0J9_$G$N$_;HMQ2DG=(B + + +

    RemoveOutputFilter $B%G%#%l%/%F%#%V$O(B + $B;XDj$5$l$?%U%!%$%k3HD%;R$K4XO"IU$1$i$l$?=PNO%U%#%k%?$r2r=|$7$^$9!#(B + $B$3$l$rMxMQ$9$k$3$H$G!"?F%G%#%l%/%H%j$d%5!<%P@_Dj%U%!%$%k$+$i(B + $B7Q>5$7$?4XO"IU$1$r(B $B%5%V%G%#%l%/%H%jFb$K$*$$$F(B + .htaccess $B%U%!%$%k$GC$9$3$H$,$G$-$^$9!#(B

    + +

    extension $B$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B + $B$^$?!":G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    + + $BNc(B + RemoveOutputFilter shtml + +
    +AddOutputFilter +
    + + +RemoveType +$B%U%!%$%k$N3HD%;R$H4XO"IU$1$i$l$?%3%s%F%s%H%?%$%W$r(B +$B2r=|$9$k(B +RemoveType extension [extension] +... +virtual hostdirectory +.htaccess +FileInfo + + +

    RemoveType $B%G%#%l%/%F%#%V$OM?$($i$l$?3HD%;R$N(B + MIME $B%?%$%W$N4XO"IU$1$rC$7$^$9!#$3$l$K$h$j!"(B + $B%5%V%G%#%l%/%H%j$K$"$k(B .htaccess + $B%U%!%$%k$,?F%G%#%l%/%H%j$d%5!<%P$N@_Dj%U%!%$%k$+$i7Q>5$7$?(B + $B4XO"IU$1$rC$9$3$H$,$G$-$^$9!#$?$H$($P(B:

    + + /foo/.htaccess: + RemoveType .cgi + + +

    $B$3$l$O(B /foo/ $B%G%#%l%/%H%j0J2<$N(B .cgi + $B%U%!%$%k$NFCJL$J07$$$rC$7$^$9!#%U%!%$%k$O(B DefaultType $B$H$7$F07$o$l$^$9!#(B

    + + $BCm0U(B +

    RemoveType $B%G%#%l%/%F%#%V$O(B + AddType + $B%G%#%l%/%F%#%V$N(B$B8e(B$B$K=hM}$5$l$^$9$N$G!"(B + $BN>J}$,F1$8%G%#%l%/%H%j$N@_DjCf$K8=$l$?>l9g!"(B + $B8eC$5$l$k2DG=@-$,$"$j$^$9!#(B

    +
    + +

    extension $B$OBgJ8;z>.J8;z$r6hJL$7$^$;$s!#(B + $B$^$?!":G=i$N%I%C%H$O$"$C$F$b$J$/$F$b9=$$$^$;$s!#(B

    +
    +
    + + +TypesConfig +mime.types $B%U%!%$%k$N0LCV(B +TypesConfig file-path +TypesConfig conf/mime.types +server config + + +

    TypesConfig $B%G%#%l%/%F%#%V$O!"(BMIME + $B%?%$%W@_Dj%U%!%$%k$N0LCV$r@_Dj$7$^$9!#(Bfilename $B$O(B + ServerRoot $B$+$i$NAjBP%Q%9$G$9!#(B + $B$3$N%U%!%$%k$O%U%!%$%k$N3HD%;R$+$i%3%s%F%s%H%?%$%W$X$N(B + $B%G%U%)%k%H$N%^%C%T%s%0$r@_Dj$7$^$9!#(B + $B$[$H$s$I$N4IM}$N3HD%;R$r(B + IANA $B$KEPO?$5$l$?%3%s%F%s%H%?%$%W$K4XO"IU$1$F$$$k!"(B + Apache $B$N(B mime.types $B%U%!%$%k$r;H$$$^$9!#(B + $B8=:_$N0lMw$O(B http://www.isi.edu/in-notes/iana/assignments/media-types/media-types + $B$G4IM}$5$l$F$$$^$9!#$3$l$O!"AddType $B$G(B + $B>e=q$-$9$k!"$H$$$&J}K!$G(B httpd.conf $B$r4JN,$K$7$^$9!#(B + mime.types $B$O%5!<%P$r%"%C%W%0%l!<%I$7$?$H$-$K(B + $BCV$-49$($i$l$k$+$b$7$l$J$$$N$G!"$=$N%U%!%$%k$rD>@\(B + $BJT=8$7$J$$$G$/$@$5$$!#(B

    + +

    $B%U%!%$%k$O!"(BAddType + $B%G%#%l%/%F%#%V$N0z?t$HF1$87A<0$N9T$G9=@.$5$l$^$9!#(B

    + + + MIME-type [extension] ... + + +

    $B3HD%;R$NBgJ8;z>.J8;z$O6hJL$5$l$^$;$s!#6u9T$d%O%C%7%e(B (`#') + $B$G;O$^$k9T$OL5;k$5$l$^$9!#(B

    + + + (1) IANA $B$K4{$KEPO?$5$l$F$$$k!"$"$k$$$O(B (2) + $B9-$/WFM$,$J$$!"(B + $B$H$$$&>l9g$G$J$1$l$P!"G[I[Cf$N(B mime.types + $B%U%!%$%k$K?7$?$J$b$N$rEPO?$9$k$h$&$K(B + Apache HTTP Server Project $B$K%j%/%(%9%H$7$J$$$G$/$@$5$$!#(B + category/x-subtype $B$N%j%/%(%9%H$O<+F0E*$K5Q2<$5$l$^$9$7!"(B + $B8@8l$dJ8;z%;%C%H$NL>A06u4V$G4{$K;HMQ$5$l$F$$$F!">WFM$N2DG=@-$N$"$k(B + 2 $BJ8;z$N3HD%;R$b5Q2<$5$l$^$9!#(B + +
    +mod_mime_magic +
    + +
    diff --git a/trunk/docs/manual/mod/mod_mime.xml.meta b/trunk/docs/manual/mod/mod_mime.xml.meta new file mode 100644 index 0000000000..d1696cae58 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime.xml.meta @@ -0,0 +1,12 @@ + + + + mod_mime + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_mime_magic.html b/trunk/docs/manual/mod/mod_mime_magic.html new file mode 100644 index 0000000000..f413ffe981 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime_magic.html @@ -0,0 +1,3 @@ +URI: mod_mime_magic.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_mime_magic.html.en b/trunk/docs/manual/mod/mod_mime_magic.html.en new file mode 100644 index 0000000000..304badaa05 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime_magic.html.en @@ -0,0 +1,274 @@ + + + +mod_mime_magic - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_mime_magic

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Determines the MIME type of a file + by looking at a few bytes of its contents
    Status:Extension
    Module Identifier:mime_magic_module
    Source File:mod_mime_magic.c
    +

    Summary

    + +

    This module determines the MIME type of files in the same + way the Unix file(1) command works: it looks at the first + few bytes of the file. It is intended as a "second line of defense" + for cases that mod_mime can't resolve.

    + +

    This module is derived from a free version of the + file(1) command for Unix, which uses "magic + numbers" and other hints from a file's contents to figure out + what the contents are. This module is active only if the magic + file is specified by the MimeMagicFile directive.

    +
    + +
    top
    +
    +

    Format of the Magic File

    + +

    The contents of the file are plain ASCII text in 4-5 + columns. Blank lines are allowed but ignored. Commented lines + use a hash mark (#). The remaining lines are parsed for + the following columns:

    + + + + + + + + + + + + +
    ColumnDescription
    1byte number to begin checking from
    + ">" indicates a dependency upon the previous + non-">" line
    2

    type of data to match

    + + + + + + + + + + + + + + + + + + + + + + + + +
    bytesingle character
    shortmachine-order 16-bit integer
    longmachine-order 32-bit integer
    stringarbitrary-length string
    datelong integer date (seconds since Unix epoch/1970)
    beshortbig-endian 16-bit integer
    belongbig-endian 32-bit integer
    bedatebig-endian 32-bit integer date
    leshortlittle-endian 16-bit integer
    lelonglittle-endian 32-bit integer
    ledatelittle-endian 32-bit integer date
    3contents of data to match
    4MIME type if matched
    5MIME encoding if matched (optional)
    + +

    For example, the following magic file lines would recognize + some audio formats:

    + +
    # Sun/NeXT audio data
    +0      string      .snd
    +>12    belong      1       audio/basic
    +>12    belong      2       audio/basic
    +>12    belong      3       audio/basic
    +>12    belong      4       audio/basic
    +>12    belong      5       audio/basic
    +>12    belong      6       audio/basic
    +>12    belong      7       audio/basic
    +>12    belong     23       audio/x-adpcm
    + +

    Or these would recognize the difference between *.doc + files containing Microsoft Word or FrameMaker documents. (These are + incompatible file formats which use the same file suffix.)

    + +
    # Frame
    +0  string  \<MakerFile        application/x-frame
    +0  string  \<MIFFile          application/x-frame
    +0  string  \<MakerDictionary  application/x-frame
    +0  string  \<MakerScreenFon   application/x-frame
    +0  string  \<MML              application/x-frame
    +0  string  \<Book             application/x-frame
    +0  string  \<Maker            application/x-frame
    +
    +# MS-Word
    +0  string  \376\067\0\043            application/msword
    +0  string  \320\317\021\340\241\261  application/msword
    +0  string  \333\245-\0\0\0           application/msword
    + +

    An optional MIME encoding can be included as a fifth column. + For example, this can recognize gzipped files and set the + encoding for them.

    + +
    # gzip (GNU zip, not to be confused with
    +#       [Info-ZIP/PKWARE] zip archiver)
    +
    +0  string  \037\213  application/octet-stream  x-gzip
    +
    top
    +
    +

    Performance Issues

    +

    This module is not for every system. If your system is barely + keeping up with its load or if you're performing a web server + benchmark, you may not want to enable this because the + processing is not free.

    + +

    However, an effort was made to improve the performance of + the original file(1) code to make it fit in a busy web + server. It was designed for a server where there are thousands of users + who publish their own documents. This is probably very common + on intranets. Many times, it's helpful if the server can make + more intelligent decisions about a file's contents than the + file name allows ...even if just to reduce the "why doesn't my + page work" calls when users improperly name their own files. + You have to decide if the extra work suits your + environment.

    +
    top
    +
    +

    Notes

    +

    The following notes apply to the mod_mime_magic + module and are included here for compliance with contributors' + copyright restrictions that require their acknowledgment.

    + +
    +

    mod_mime_magic: MIME type lookup via file magic numbers
    + Copyright (c) 1996-1997 Cisco Systems, Inc.

    + +

    This software was submitted by Cisco Systems to the Apache Group + in July 1997. Future revisions and derivatives of this source code + must acknowledge Cisco Systems as the original contributor of this + module. All other licensing and usage conditions are those of the + Apache Group.

    + +

    Some of this code is derived from the free version of the file + command originally posted to comp.sources.unix. Copyright info for + that program is included below as required.

    +
    + +
    +

    - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.

    + +

    This software is not subject to any license of the American + Telephone and Telegraph Company or of the Regents of the University + of California.

    + +

    Permission is granted to anyone to use this software for any + purpose on any computer system, and to alter it and redistribute it + freely, subject to the following restrictions:

    + +
      +
    1. The author is not responsible for the consequences of use of + this software, no matter how awful, even if they arise from flaws + in it.
    2. + +
    3. The origin of this software must not be misrepresented, either + by explicit claim or by omission. Since few users ever read + sources, credits must appear in the documentation.
    4. + +
    5. Altered versions must be plainly marked as such, and must not + be misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation.
    6. + +
    7. This notice may not be removed or altered.
    8. +
    +
    + +
    +

    For compliance with Mr Darwin's terms: this has been very + significantly modified from the free "file" command.

    + +
      +
    • all-in-one file for compilation convenience when moving from + one version of Apache to the next.
    • + +
    • Memory allocation is done through the Apache API's pool + structure.
    • + +
    • All functions have had necessary Apache API request or server + structures passed to them where necessary to call other Apache API + routines. (i.e., usually for logging, files, or memory + allocation in itself or a called function.)
    • + +
    • struct magic has been converted from an array to a single-ended + linked list because it only grows one record at a time, it's only + accessed sequentially, and the Apache API has no equivalent of + realloc().
    • + +
    • Functions have been changed to get their parameters from the + server configuration instead of globals. (It should be reentrant + now but has not been tested in a threaded environment.)
    • + +
    • Places where it used to print results to stdout now saves them + in a list where they're used to set the MIME type in the Apache + request record.
    • + +
    • Command-line flags have been removed since they will never be + used here.
    • +
    +
    +
    +
    top
    +

    MimeMagicFile Directive

    + + + + + + +
    Description:Enable MIME-type determination based on file contents +using the specified magic file
    Syntax:MimeMagicFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_mime_magic
    +

    The MimeMagicFile directive can be used to + enable this module, the default file is distributed at + conf/magic. Non-rooted paths are relative to the + ServerRoot. Virtual hosts will use + the same file as the main server unless a more specific setting is + used, in which case the more specific setting overrides the main + server's file.

    + +

    Example

    + MimeMagicFile conf/magic +

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_mime_magic.xml b/trunk/docs/manual/mod/mod_mime_magic.xml new file mode 100644 index 0000000000..70d0068150 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime_magic.xml @@ -0,0 +1,271 @@ + + + + + + + + + +mod_mime_magic +Determines the MIME type of a file + by looking at a few bytes of its contents +Extension +mod_mime_magic.c +mime_magic_module + + +

    This module determines the MIME type of files in the same + way the Unix file(1) command works: it looks at the first + few bytes of the file. It is intended as a "second line of defense" + for cases that mod_mime can't resolve.

    + +

    This module is derived from a free version of the + file(1) command for Unix, which uses "magic + numbers" and other hints from a file's contents to figure out + what the contents are. This module is active only if the magic + file is specified by the MimeMagicFile directive.

    +
    + +
    Format of the Magic File + +

    The contents of the file are plain ASCII text in 4-5 + columns. Blank lines are allowed but ignored. Commented lines + use a hash mark (#). The remaining lines are parsed for + the following columns:

    + + + + + + + + + + + + + + + + + + +
    ColumnDescription
    1byte number to begin checking from
    + ">" indicates a dependency upon the previous + non-">" line
    2

    type of data to match

    + + + + + + + + + + + + + + + + + + + + + + + + +
    bytesingle character
    shortmachine-order 16-bit integer
    longmachine-order 32-bit integer
    stringarbitrary-length string
    datelong integer date (seconds since Unix epoch/1970)
    beshortbig-endian 16-bit integer
    belongbig-endian 32-bit integer
    bedatebig-endian 32-bit integer date
    leshortlittle-endian 16-bit integer
    lelonglittle-endian 32-bit integer
    ledatelittle-endian 32-bit integer date
    3contents of data to match
    4MIME type if matched
    5MIME encoding if matched (optional)
    + +

    For example, the following magic file lines would recognize + some audio formats:

    + + +
    # Sun/NeXT audio data
    +0      string      .snd
    +>12    belong      1       audio/basic
    +>12    belong      2       audio/basic
    +>12    belong      3       audio/basic
    +>12    belong      4       audio/basic
    +>12    belong      5       audio/basic
    +>12    belong      6       audio/basic
    +>12    belong      7       audio/basic
    +>12    belong     23       audio/x-adpcm
    +
    + +

    Or these would recognize the difference between *.doc + files containing Microsoft Word or FrameMaker documents. (These are + incompatible file formats which use the same file suffix.)

    + + +
    # Frame
    +0  string  \<MakerFile        application/x-frame
    +0  string  \<MIFFile          application/x-frame
    +0  string  \<MakerDictionary  application/x-frame
    +0  string  \<MakerScreenFon   application/x-frame
    +0  string  \<MML              application/x-frame
    +0  string  \<Book             application/x-frame
    +0  string  \<Maker            application/x-frame
    +
    +# MS-Word
    +0  string  \376\067\0\043            application/msword
    +0  string  \320\317\021\340\241\261  application/msword
    +0  string  \333\245-\0\0\0           application/msword
    +
    + +

    An optional MIME encoding can be included as a fifth column. + For example, this can recognize gzipped files and set the + encoding for them.

    + + +
    # gzip (GNU zip, not to be confused with
    +#       [Info-ZIP/PKWARE] zip archiver)
    +
    +0  string  \037\213  application/octet-stream  x-gzip
    +
    +
    + +
    Performance Issues +

    This module is not for every system. If your system is barely + keeping up with its load or if you're performing a web server + benchmark, you may not want to enable this because the + processing is not free.

    + +

    However, an effort was made to improve the performance of + the original file(1) code to make it fit in a busy web + server. It was designed for a server where there are thousands of users + who publish their own documents. This is probably very common + on intranets. Many times, it's helpful if the server can make + more intelligent decisions about a file's contents than the + file name allows ...even if just to reduce the "why doesn't my + page work" calls when users improperly name their own files. + You have to decide if the extra work suits your + environment.

    +
    + +
    Notes +

    The following notes apply to the mod_mime_magic + module and are included here for compliance with contributors' + copyright restrictions that require their acknowledgment.

    + + +

    mod_mime_magic: MIME type lookup via file magic numbers
    + Copyright (c) 1996-1997 Cisco Systems, Inc.

    + +

    This software was submitted by Cisco Systems to the Apache Group + in July 1997. Future revisions and derivatives of this source code + must acknowledge Cisco Systems as the original contributor of this + module. All other licensing and usage conditions are those of the + Apache Group.

    + +

    Some of this code is derived from the free version of the file + command originally posted to comp.sources.unix. Copyright info for + that program is included below as required.

    +
    + + +

    - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.

    + +

    This software is not subject to any license of the American + Telephone and Telegraph Company or of the Regents of the University + of California.

    + +

    Permission is granted to anyone to use this software for any + purpose on any computer system, and to alter it and redistribute it + freely, subject to the following restrictions:

    + +
      +
    1. The author is not responsible for the consequences of use of + this software, no matter how awful, even if they arise from flaws + in it.
    2. + +
    3. The origin of this software must not be misrepresented, either + by explicit claim or by omission. Since few users ever read + sources, credits must appear in the documentation.
    4. + +
    5. Altered versions must be plainly marked as such, and must not + be misrepresented as being the original software. Since few users + ever read sources, credits must appear in the documentation.
    6. + +
    7. This notice may not be removed or altered.
    8. +
    +
    + + +

    For compliance with Mr Darwin's terms: this has been very + significantly modified from the free "file" command.

    + +
      +
    • all-in-one file for compilation convenience when moving from + one version of Apache to the next.
    • + +
    • Memory allocation is done through the Apache API's pool + structure.
    • + +
    • All functions have had necessary Apache API request or server + structures passed to them where necessary to call other Apache API + routines. (i.e., usually for logging, files, or memory + allocation in itself or a called function.)
    • + +
    • struct magic has been converted from an array to a single-ended + linked list because it only grows one record at a time, it's only + accessed sequentially, and the Apache API has no equivalent of + realloc().
    • + +
    • Functions have been changed to get their parameters from the + server configuration instead of globals. (It should be reentrant + now but has not been tested in a threaded environment.)
    • + +
    • Places where it used to print results to stdout now saves them + in a list where they're used to set the MIME type in the Apache + request record.
    • + +
    • Command-line flags have been removed since they will never be + used here.
    • +
    +
    +
    + + +MimeMagicFile +Enable MIME-type determination based on file contents +using the specified magic file +MimeMagicFile file-path +server configvirtual host + + + +

    The MimeMagicFile directive can be used to + enable this module, the default file is distributed at + conf/magic. Non-rooted paths are relative to the + ServerRoot. Virtual hosts will use + the same file as the main server unless a more specific setting is + used, in which case the more specific setting overrides the main + server's file.

    + + Example + MimeMagicFile conf/magic + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_mime_magic.xml.meta b/trunk/docs/manual/mod/mod_mime_magic.xml.meta new file mode 100644 index 0000000000..4f0443ae75 --- /dev/null +++ b/trunk/docs/manual/mod/mod_mime_magic.xml.meta @@ -0,0 +1,11 @@ + + + + mod_mime_magic + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_negotiation.html b/trunk/docs/manual/mod/mod_negotiation.html new file mode 100644 index 0000000000..c4e86d3a49 --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.html @@ -0,0 +1,7 @@ +URI: mod_negotiation.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_negotiation.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_negotiation.html.en b/trunk/docs/manual/mod/mod_negotiation.html.en new file mode 100644 index 0000000000..226e47d570 --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.html.en @@ -0,0 +1,306 @@ + + + +mod_negotiation - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_negotiation

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    Description:Provides for content negotiation
    Status:Base
    Module Identifier:negotiation_module
    Source File:mod_negotiation.c
    +

    Summary

    + +

    Content negotiation, or more accurately content selection, is + the selection of the document that best matches the clients + capabilities, from one of several available documents. There + are two implementations of this.

    + +
      +
    • A type map (a file with the handler + type-map) which explicitly lists the files + containing the variants.
    • + +
    • A MultiViews search (enabled by the MultiViews + Options), where the server does + an implicit filename pattern match, and choose from amongst the + results.
    • +
    +
    + +
    top
    +
    +

    Type maps

    +

    A type map has a format similar to RFC822 mail headers. It + contains document descriptions separated by blank lines, with + lines beginning with a hash character ('#') treated as + comments. A document description consists of several header + records; records may be continued on multiple lines if the + continuation lines start with spaces. The leading space will be + deleted and the lines concatenated. A header record consists of + a keyword name, which always ends in a colon, followed by a + value. Whitespace is allowed between the header name and value, + and between the tokens of value. The headers allowed are:

    + +
    +
    Content-Encoding:
    +
    The encoding of the file. Apache only recognizes + encodings that are defined by an AddEncoding directive. + This normally includes the encodings x-compress + for compress'd files, and x-gzip for gzip'd + files. The x- prefix is ignored for encoding + comparisons.
    + +
    Content-Language:
    +
    The language(s) of the variant, as an Internet standard + language tag (RFC 1766). An example is en, + meaning English. If the variant contains more than one + language, they are separated by a comma.
    + +
    Content-Length:
    +
    The length of the file, in bytes. If this header is not + present, then the actual length of the file is used.
    + +
    Content-Type:
    + +
    + The MIME media type of the document, with optional + parameters. Parameters are separated from the media type + and from one another by a semi-colon, with a syntax of + name=value. Common parameters include: + +
    +
    level
    +
    an integer specifying the version of the media type. + For text/html this defaults to 2, otherwise + 0.
    + +
    qs
    +
    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.
    +
    + +

    Example

    + Content-Type: image/jpeg; qs=0.8 +

    +
    + +
    URI:
    +
    uri of the file containing the variant (of the given + media type, encoded with the given content encoding). These + are interpreted as URLs relative to the map file; they must + be on the same server (!), and they must refer to files to + which the client would be granted access if they were to be + requested directly.
    + +
    Body:
    +
    New in Apache 2.0, the actual content of the resource may + be included in the type-map file using the Body header. This + header must contain a string that designates a delimiter for + the body content. Then all following lines in the type map + file will be considered part of the resource body until the + delimiter string is found. + +

    Example:

    + Body:----xyz----
    + <html>
    + <body>
    + <p>Content of the page.</p>
    + </body>
    + </html>
    + ----xyz---- +

    +
    +
    +
    top
    +
    +

    MultiViews

    +

    A MultiViews search is enabled by the MultiViews + Options. If the server receives a + request for /some/dir/foo and + /some/dir/foo does not exist, then the + server reads the directory looking for all files named + foo.*, and effectively fakes up a 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 returns that document.

    + +

    The MultiViewsMatch + directive configures whether Apache will consider files + that do not have content negotiation meta-information assigned + to them when choosing files.

    +
    +
    top
    +

    CacheNegotiatedDocs Directive

    + + + + + + + + +
    Description:Allows content-negotiated documents to be +cached by proxy servers
    Syntax:CacheNegotiatedDocs On|Off
    Default:CacheNegotiatedDocs Off
    Context:server config, virtual host
    Status:Base
    Module:mod_negotiation
    Compatibility:The syntax changed in version 2.0.
    +

    If set, this directive allows content-negotiated documents + to be cached by proxy servers. This could mean that clients + behind those proxys could retrieve versions of the documents + that are not the best match for their abilities, but it will + make caching more efficient.

    + +

    This directive only applies to requests which come from + HTTP/1.0 browsers. HTTP/1.1 provides much better control over + the caching of negotiated documents, and this directive has no + effect in responses to HTTP/1.1 requests.

    + +

    Prior to version 2.0, + CacheNegotiatedDocs did not take an + argument; it was turned on by the presence of the directive by + itself.

    + +
    +
    top
    +

    ForceLanguagePriority Directive

    + + + + + + + + + +
    Description:Action to take if a single acceptable document is not +found
    Syntax:ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback]
    Default:ForceLanguagePriority Prefer
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_negotiation
    Compatibility:Available in version 2.0.30 and later
    +

    The ForceLanguagePriority directive uses + the given LanguagePriority to satisfy + negotation where the server could otherwise not return a single + matching document.

    + +

    ForceLanguagePriority Prefer uses + LanguagePriority to serve a one valid result, rather + than returning an HTTP result 300 (MULTIPLE CHOICES) when there + are several equally valid choices. If the directives below were + given, and the user's Accept-Language header assigned + en and de each as quality .500 + (equally acceptable) then the first matching variant, en, + will be served.

    + +

    + LanguagePriority en fr de
    + ForceLanguagePriority Prefer +

    + +

    ForceLanguagePriority Fallback uses + LanguagePriority to + serve a valid result, rather than returning an HTTP result 406 + (NOT ACCEPTABLE). If the directives below were given, and the user's + Accept-Language only permitted an es + language response, but such a variant isn't found, then the first + variant from the LanguagePriority list below will be served.

    + +

    + LanguagePriority en fr de
    + ForceLanguagePriority Fallback +

    + +

    Both options, Prefer and Fallback, may be + specified, so either the first matching variant from LanguagePriority will be served if + more than one variant is acceptable, or first available document will + be served if none of the variants matched the client's acceptable list + of languages.

    + +

    See also

    + +
    +
    top
    +

    LanguagePriority Directive

    + + + + + + + +
    Description:The precendence of language variants for cases where +the client does not express a preference
    Syntax:LanguagePriority MIME-lang [MIME-lang] +...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_negotiation
    +

    The LanguagePriority sets the precedence + of language variants for the case where the client does not + express a preference, when handling a MultiViews request. The list + of MIME-lang are in order of decreasing preference.

    + +

    Example:

    + LanguagePriority en fr de +

    + +

    For a request for foo.html, where + foo.html.fr and foo.html.de both + existed, but the browser did not express a language preference, + then foo.html.fr would be returned.

    + +

    Note that this directive only has an effect if a 'best' + language cannot be determined by any other means or the ForceLanguagePriority directive + is not None. In general, the client determines the + language preference, not the server.

    + +

    See also

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_negotiation.html.ja.euc-jp b/trunk/docs/manual/mod/mod_negotiation.html.ja.euc-jp new file mode 100644 index 0000000000..39c193d3bd --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.html.ja.euc-jp @@ -0,0 +1,300 @@ + + + +mod_negotiation - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_negotiation

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    ÀâÌÀ:¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + µ¡Ç½¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:negotiation_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_negotiation.c
    +

    ³µÍ×

    + +

    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¡¢¤è¤êÀµ³Î¤Ë¤Ï¥³¥ó¥Æ¥ó¥Ä¤ÎÁªÂòµ¡Ç½¤Ï¡¢ + Ê£¿ôÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¥É¥­¥å¥á¥ó¥È¤«¤é¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÎǽÎϤ˰ìÈÖ¹ç¤Ã¤¿ + ¥É¥­¥å¥á¥ó¥È¤òÁªÂò¤¹¤ëµ¡Ç½¤Ç¤¹¡£¤³¤Î¼ÂÁõ¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹¡£

    + +
      +
    • ¥¿¥¤¥×¥Þ¥Ã¥× (type-map + ¥Ï¥ó¥É¥é¤Ç°·¤ï¤ì¤ë¥Õ¥¡¥¤¥ë)¡£¤³¤ì¤Ï variants + ¤ò´Þ¤ó¤Ç¤¤¤ë¥Õ¥¡¥¤¥ë¤òÌÀ¼¨Åª¤Ë»ØÄꤷ¤Þ¤¹¡£
    • + +
    • MultiViews ¤Îõº÷ (MultiViews Option ¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹)¡£ + ¥µ¡¼¥Ð¤¬°ÅÌÛ¤ÎÆâ¤Ë¥Õ¥¡¥¤¥ë̾¤Î¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ò¹Ô¤Ê¤¤¡¢ + ¤½¤Î·ë²Ì¤«¤éÁªÂò¤·¤Þ¤¹¡£
    • +
    +
    + +
    top
    +
    +

    ¥¿¥¤¥×¥Þ¥Ã¥×

    +

    ¥¿¥¤¥×¥Þ¥Ã¥×¤Ï RFC 822 ¤Î¥á¡¼¥ë¥Ø¥Ã¥À¤ËÎà»÷¤·¤¿½ñ¼°¤Ç¤¹¡£ + ¥É¥­¥å¥á¥ó¥È¤Îµ­½Ò¤¬¶õ¹Ô¤ÇʬΥ¤µ¤ì¤Æ½ñ¤«¤ì¤Æ¤¤¤Æ¡¢¥Ï¥Ã¥·¥åʸ»ú + ('#') ¤Ç»Ï¤Þ¤ë¹Ô¤Ï¥³¥á¥ó¥È¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£ + ¥É¥­¥å¥á¥ó¥È¤ÎÀâÌÀ¤ÏÊ£¿ô¤Î¥Ø¥Ã¥À¥ì¥³¡¼¥É¤«¤é¹½À®¤µ¤ì¤Þ¤¹¡£ + ¥ì¥³¡¼¥É¤Ï¡¢Â³¤­¤Î¹Ô¤¬¶õÇò¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤ë¤ÈÊ£¿ô¤Î¹Ô¤Ë¤Þ¤¿¤¬¤ê¤Þ¤¹¡£ + ºÇ½é¤Î¶õÇò¤¬¾Ãµî¤µ¤ì¤Æ¡¢Á°¤Î¹Ô¤È¤Ä¤Ê¤²¤Æ 1 ¹Ô¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£ + ¥Ø¥Ã¥À¥ì¥³¡¼¥É¤Ï¥­¡¼¥ï¡¼¥É̾¤Î¸å¤ËÃͤ¬Â³¤¯¤È¤¤¤¦·Á¼°¤Ç¡¢ + ¥­¡¼¥ï¡¼¥É̾¤Ï¾ï¤Ë¥³¥í¥ó¤Ç½ª¤ï¤ê¤Þ¤¹¡£¶õÇò¤Ï¥Ø¥Ã¥À̾¤ÈÃͤδ֡¢ + ÃͤΥȡ¼¥¯¥ó¤Î´Ö¤ËÆþ¤ì¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + »ÈÍѲÄǽ¤Ê¥Ø¥Ã¥À¤Ï°Ê²¼¤Î¤È¤ª¤ê¤Ç¤¹:

    + +
    +
    Content-Encoding:
    +
    ¥Õ¥¡¥¤¥ë¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¡£Apache ¤Ï AddEncoding ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ÇÄêµÁ¤µ¤ì¤¿¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤À¤±¤òǧ¼±¤·¤Þ¤¹¡£Ä̾ï compress + ¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î¤¿¤á¤Î x-compress ¤È gzip + ¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î¤¿¤á¤Î x-gzip ¤ò´Þ¤ß¤Þ¤¹¡£ + ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ÎÈæ³Ó¤ò¤¹¤ë¤È¤­¤Ï¡¢ÀÜƬ¼­ x- + ¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£
    + +
    Content-Language:
    +
    ¥¤¥ó¥¿¡¼¥Í¥Ã¥Èɸ½à¤Î¸À¸ì¥¿¥° + (RFC 1766) + ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¸À¸ì¤Î¼ïÎà¡£Î㤨¤Ð¡¢en + ¤Ï±Ñ¸ì¤òɽ¤·¤Þ¤¹¡£ + Ê£¿ô¤Î¸À¸ì¤¬³ÊǼ¤µ¤ì¤ë¾ì¹ç¤Ï¥³¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤Þ¤¹¡£
    + +
    Content-Length:
    +
    ¥Õ¥¡¥¤¥ë¤ÎŤµ (¥Ð¥¤¥È¿ô)¡£ + ¤³¤Î¥Ø¥Ã¥À¤¬¤Ê¤¤¾ì¹ç¡¢¥Õ¥¡¥¤¥ë¤Î¼ÂºÝ¤ÎŤµ¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£
    + +
    Content-Type:
    +
    ¥É¥­¥å¥á¥ó¥È¤Î MIME + ¥á¥Ç¥£¥¢¥¿¥¤¥×¡¢¥ª¥×¥·¥ç¥Ê¥ë¤Ê¥Ñ¥é¥á¡¼¥¿ÉÕ¤­¡£¥Ñ¥é¥á¡¼¥¿¤Î¹½Ê¸¤Ï + name=value + ¤Ç¡¢¥á¥Ç¥£¥¢¥¿¥¤¥×¤ä¾¤Î¥Ñ¥é¥á¡¼¥¿¤È¤Ï¥»¥ß¥³¥í¥ó¤ÇʬΥ¤µ¤ì¤Þ¤¹¡£ + ¶¦Ä̤Υѥé¥á¡¼¥¿¤Ï°Ê²¼¤Î¤È¤ª¤ê: + +
    +
    level
    +
    ¥á¥Ç¥£¥¢¥¿¥¤¥×¤Î¥Ð¡¼¥¸¥ç¥ó¤ò¼¨¤¹À°¿ô¡£ + text/html ¤Ç¤Ï 2 ¤¬¥Ç¥Õ¥©¥ë¥È¤Ç¡¢¤½¤Î¾¤Î¾ì¹ç¤Ï + 0 ¤¬¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£
    + +
    qs
    +
    ¥¯¥é¥¤¥¢¥ó¥È¤ÎǽÎϤ˴ط¸¤Ê¤¯¡¢variant + ¤ò¾¤ÈÈæ³Ó¤·¤¿¤È¤­¤ÎÁêÂÐŪ¤Ê¡ÖÉʼÁ¡×¤Ç¡¢0.0 ¤«¤é 1.0 + ¤ÎÈϰϤÎÉâÆ°ÅÀ¾®¿ô¡£ + Î㤨¤Ð¡¢¼Ì¿¿¤òɽ¸½¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤ÏÉáÄÌ¤Ï JPEG + ¥Õ¥¡¥¤¥ë¤ÎÊý¤¬ ASCII ¥Õ¥¡¥¤¥ë¤è¤ê¤â¹â¤¤ÉʼÁ¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤·¤«¤·¡¢¥ê¥½¡¼¥¹¤¬ ASCII ¥¢¡¼¥È¤Çɽ¸½¤µ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢ASCII + ¥Õ¥¡¥¤¥ë¤ÎÊý¤¬ JPEG + ¥Õ¥¡¥¤¥ë¤è¤ê¤â¹â¤¤ÉʼÁ¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ë¡¢qs + ¤Ï¥ê¥½¡¼¥¹Ëè¤ËÆÃÍ­¤ÎÃͤò¼è¤ê¤Þ¤¹¡£ +
    +
    + +

    Îã

    + Content-Type: image/jpeg; qs=0.8 +

    +
    + +
    URI:
    +
    (»ØÄê¤Î¥á¥Ç¥£¥¢¥¿¥¤¥×¡¢¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Î) variant ¤Î + ¥Õ¥¡¥¤¥ë¤Î uri. ¤³¤ì¤Ï¡¢¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¤ÎÁêÂÐ URL ¤È¤·¤Æ + ²ò¼á¤µ¤ì¤Þ¤¹¡£Æ±¤¸¥µ¡¼¥Ð¤Ë¸ºß¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤º¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬ + ľÀܥꥯ¥¨¥¹¥È¤·¤¿¤È¤­¤Ë¥¢¥¯¥»¥¹¤òµö²Ä¤µ¤ì¤ë¤â¤Î¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
    + +
    Body:
    +
    Apache 2.0 ¤Ç¿·Àߤµ¤ì¤¿¤³¤Î Body ¥Ø¥Ã¥À¤ò»È¤Ã¤Æ¡¢ + ¥ê¥½¡¼¥¹¤Î¼ÂºÝ¤ÎÆâÍƤò¥¿¥¤¥×¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥Ø¥Ã¥À¤ÏËÜʸ¤ÎÆâÍƤζèÀÚ¤ê¤È¤Ê¤ëʸ»úÎó¤Ç»Ï¤Þ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¥¿¥¤¥×¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤Î³¤¯¹Ô¤Ï¡¢¶èÀÚ¤êʸ»úÎ󤬸«¤Ä¤«¤ë¤Þ¤Ç¡¢ + ¥ê¥½¡¼¥¹¤ÎËÜʸ¤Ë¤Ê¤ê¤Þ¤¹¡£ + +

    Example:

    + Body:----xyz----
    + <html>
    + <body>
    + <p>Content of the page.</p>
    + </body>
    + </html>
    + ----xyz---- +

    +
    +
    +
    top
    +
    +

    MultiViews

    +

    MultiViews õº÷¤Ï¡¢Multiviews Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤êÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤¬ /some/dir/foo + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤ê¡¢/some/dir/foo ¤¬Â¸ºß + ¤·¤Ê¤¤¾ì¹ç¡¢¥µ¡¼¥Ð¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤òÆɤó¤Ç¡¢ + foo.* ¤Ë¤¢¤Æ¤Ï¤Þ¤ëÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¤òõ¤·¡¢ + »ö¼Â¾å¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤ò¥Þ¥Ã¥×¤¹¤ë¥¿¥¤¥×¥Þ¥Ã¥×¤òºî¤ê¤Þ¤¹¡£ + ¤½¤Î¤È¤­¡¢¥á¥Ç¥£¥¢¥¿¥¤¥×¤È¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ï¡¢ + ¤½¤Î¥Õ¥¡¥¤¥ë̾¤òľÀÜ»ØÄꤷ¤¿¤È¤­¤ÈƱ¤¸¤â¤Î¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£ + ¤½¤ì¤«¤é¥¯¥é¥¤¥¢¥ó¥È¤ÎÍ×µá¤Ë°ìÈֹ礦¤â¤Î¤òÁª¤Ó¡¢ + ¤½¤Î¥É¥­¥å¥á¥ó¥È¤òÊÖ¤·¤Þ¤¹¡£

    + +

    ¥Õ¥¡¥¤¥ë¤òÁªÂò¤¹¤ëºÝ¤Ë¡¢´ØÏ¢¤¹¤ë¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î + ¥á¥¿¾ðÊó¤ò»ý¤¿¤Ê¤¤¥Õ¥¡¥¤¥ë¤Ë¤Ä¤¤¤Æ¡¢È½Äê¤ò¹Ô¤¦¤«¤É¤¦¤«¤ò + MultiViewsMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£

    +
    +
    top
    +

    CacheNegotiatedDocs ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤ò¥×¥í¥­¥·¥µ¡¼¥Ð¤¬ +¥­¥ã¥Ã¥·¥å¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë
    ¹½Ê¸:CacheNegotiatedDocs On|Off
    ¥Ç¥Õ¥©¥ë¥È:CacheNegotiatedDocs Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_negotiation
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0¤Ç¹½Ê¸¤¬ÊѤï¤ê¤Þ¤·¤¿
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó + ¤ò¤·¤¿·ë²Ì¤Î¥É¥­¥å¥á¥ó¥È¤Î¥­¥ã¥Ã¥·¥å¤òµö²Ä¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥×¥í¥­¥·¤Î¸å¤í¤Ë¤¤¤ë¥¯¥é¥¤¥¢¥ó¥È¤¬Ç½ÎϤ˰ìÈÖ¹ç¤Ã¤¿ + ¥É¥­¥å¥á¥ó¥È¤Ç¤Ï¤Ê¤¯¡¢ + ¥­¥ã¥Ã¥·¥å¤ò¤è¤ê¸ú²ÌŪ¤Ë¤¹¤ë¤â¤Î¤òÆÀ¤ë²ÄǽÀ­¤¬¤¢¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï HTTP/1.0 ¥Ö¥é¥¦¥¶¤«¤é¤Î¥ê¥¯¥¨¥¹¥È + ¤Î¤ß¤ËŬÍѤµ¤ì¤Þ¤¹¡£HTTP/1.1 ¤Ï¡¢ + ¸ò¾Ä¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Î¥­¥ã¥Ã¥·¥å¤ËÂФ·¤Æ¤º¤Ã¤È¤è¤¤À©¸æ¤¬²Äǽ¤Ê¤Î¤Ç¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï HTTP/1.1 ¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤Ï±Æ¶Á¤·¤Þ¤»¤ó¡£

    +

    2.0 ¤è¤êÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢ + CacheNegotiatedDocs ¤Ï°ú¿ô¤ò¼è¤é¤º¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Â¸ºß¤¹¤ë¤³¤È¤Ç on ¤ÎÆ°ºî¤ò¤·¤Æ¤¤¤Þ¤·¤¿¡£

    + +
    +
    top
    +

    ForceLanguagePriority ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:Í×µá¤Ë¹ç¤¦Ã±ÆȤΥɥ­¥å¥á¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¤È¤­¤Ë¹Ô¤Ê¤¦¤³¤È¤ò»ØÄê +
    ¹½Ê¸:ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback]
    ¥Ç¥Õ¥©¥ë¥È:ForceLanguagePriority Prefer
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_negotiation
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0.30 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ForceLanguagePriority ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Í×µá¤Ë¹ç¤¦¥É¥­¥å¥á¥ó¥È¤ò°ì¤Ä¤À¤±ÊÖ¤¹¤³¤È¤¬¤Ç¤­¤Ê¤¤¤È¤­¤Ë¡¢ + LanguagePriority + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î·ë²Ì¤òÊÖ¤·¤Þ¤¹¡£

    + +

    ForceLanguagePriority Prefer ¤Ï¡¢Æ±Åù¤ÎÁªÂò»è¤¬ + ¤¤¤¯¤Ä¤«¤¢¤ë¤È¤­¤Ë¡¢HTTP ¤Î 300 (MULTIPLE CHOICES) ¤òÊÖ¤¹Âå¤ï¤ê¤Ë¡¢ + LanguagePriority ¤ò»È¤Ã¤Æ°ì¤Ä¤À¤±¥É¥­¥å¥á¥ó¥È¤òÊÖ¤¹¤è¤¦¤Ë + ¤·¤Þ¤¹¡£°Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»ØÄꤵ¤ì¤Æ¤¤¤Æ¡¢¥æ¡¼¥¶¤Î Accept-Language + ¥Ø¥Ã¥À¤Ç¤Ï en ¤È de ¤ÎÉʼÁ¤¬¶¦¤Ë + .500 (Ʊ¤¸¤¯¤é¤¤µöÍÆ) ¤Ç¤¢¤ë¤È¤­¤Ï¡¢ + ºÇ½é¤Ë¥Þ¥Ã¥Á¤¹¤ë variant ¤Î en ¤¬Á÷¤é¤ì¤Þ¤¹¡£

    + +

    + LanguagePriority en fr de
    + ForceLanguagePriority Prefer +

    + +

    ForceLanguagePriority Fallback ¤Ç¤Ï¡¢HTTP 406 + (NOT ACCEPTABLE) ¤òÁ÷¿®¤¹¤ëÂå¤ï¤ê¤Ë¡¢ + LanguagePriority + ¤¬Àµ¤·¤¤·ë²Ì¤òÁ÷¤ê¤Þ¤¹¡£ + °Ê²¼¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»ØÄꤵ¤ì¤Æ¤¤¤Æ¡¢¥æ¡¼¥¶¤Î Accept-Language + ¤¬ es ¸À¸ì¤Î¤ß¤òµö²Ä¤·¤Æ¤¤¤Æ¡¢¤µ¤é¤Ë¤½¤Î¤è¤¦¤Ê variant ¤¬¤Ê¤¤¤È¤­¤Ë¤Ï¡¢ + °Ê²¼¤Î LanguagePriority + ¤Î¥ê¥¹¥È¤ÎºÇ½é¤Î variant ¤¬Á÷¤ì¤ì¤Þ¤¹¡£

    + +

    + LanguagePriority en fr de
    + ForceLanguagePriority Fallback +

    + +

    Prefer ¤È Fallback ¤ÎξÊý¤Î¥ª¥×¥·¥ç¥ó¤ò + Ʊ»þ¤Ë»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢Ê£¿ô¤Î variant ¤¬¤¢¤ë¤È¤­¤Ï + LanguagePriority ¤ÎºÇ½é¤Î + variant ¤¬Á÷¤é¤ì¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÎµöÍƸÀ¸ì¤Ë¹ç¤¦ vaiant ¤¬¤Ê¤¤¤È¤­¤Ï + ¸ºß¤¹¤ë¥É¥­¥å¥á¥ó¥È¤ÇºÇ½é¤Î¤â¤Î¤¬Á÷¤é¤ì¤ë¡¢¤È¤¤¤¦Íͤˤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    LanguagePriority ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤¬Í¥ÀèÅÙ¤ò¼¨¤µ¤Ê¤«¤Ã¤¿¤È¤­¤Î¸À¸ì¤Î variant ¤ÎÍ¥ÀèÅÙ¤ò +»ØÄê
    ¹½Ê¸:LanguagePriority MIME-lang [MIME-lang] +...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_negotiation
    +

    LanguagePriority ¤Ï¡¢MultiViews + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤È¤­¤Ë¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬Í¥Àè½ç°Ì¤òÄ󶡤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Î + ¸À¸ì¤ÎÍ¥Àè½ç°Ì¤òÀßÄꤷ¤Þ¤¹¡£MIME-lang + ¤Î¥ê¥¹¥È¤¬Í¥ÀèÅ٤ι߽ç¤ËʤӤޤ¹¡£

    + +

    Example:

    + LanguagePriority en fr de +

    + +

    foo.html ¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¡¢foo.html.fr + ¤È foo.html.de ¤¬Î¾Êý¸ºß¤·¡¢ + ¥Ö¥é¥¦¥¶¤¬¸À¸ì¤ÎÍ¥Àè½ç°Ì¤òÄ󶡤·¤Æ¤Ê¤¤¾ì¹ç¤Ï + foo.html.fr ¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¾¤ÎÊýË¡¤Ç¡ÖºÇÁ±¡× + ¤Î¸À¸ì¤¬·èÄê¤Ç¤­¤Ê¤¤¤È¤­¤«¡¢ForceLanguagePriority ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + None °Ê³°¤Î¤È¤­¤Ë¤Î¤ß¸ú²Ì¤¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + °ìÈÌŪ¤Ë¤Ï¡¢¥µ¡¼¥Ð¦¤Ç¤Ï¤Ê¤¯¥¯¥é¥¤¥¢¥ó¥È¦¤Ç¹¥¤ß¤Î¸À¸ì¤ò·èÄꤷ¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_negotiation.xml b/trunk/docs/manual/mod/mod_negotiation.xml new file mode 100644 index 0000000000..8a16763d97 --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.xml @@ -0,0 +1,286 @@ + + + + + + + + + +mod_negotiation +Provides for content negotiation +Base +mod_negotiation.c +negotiation_module + + +

    Content negotiation, or more accurately content selection, is + the selection of the document that best matches the clients + capabilities, from one of several available documents. There + are two implementations of this.

    + +
      +
    • A type map (a file with the handler + type-map) which explicitly lists the files + containing the variants.
    • + +
    • A MultiViews search (enabled by the MultiViews + Options), where the server does + an implicit filename pattern match, and choose from amongst the + results.
    • +
    +
    +Options +mod_mime +Content +Negotiation +Environment Variables + +
    Type maps +

    A type map has a format similar to RFC822 mail headers. It + contains document descriptions separated by blank lines, with + lines beginning with a hash character ('#') treated as + comments. A document description consists of several header + records; records may be continued on multiple lines if the + continuation lines start with spaces. The leading space will be + deleted and the lines concatenated. A header record consists of + a keyword name, which always ends in a colon, followed by a + value. Whitespace is allowed between the header name and value, + and between the tokens of value. The headers allowed are:

    + +
    +
    Content-Encoding:
    +
    The encoding of the file. Apache only recognizes + encodings that are defined by an AddEncoding directive. + This normally includes the encodings x-compress + for compress'd files, and x-gzip for gzip'd + files. The x- prefix is ignored for encoding + comparisons.
    + +
    Content-Language:
    +
    The language(s) of the variant, as an Internet standard + language tag (RFC 1766). An example is en, + meaning English. If the variant contains more than one + language, they are separated by a comma.
    + +
    Content-Length:
    +
    The length of the file, in bytes. If this header is not + present, then the actual length of the file is used.
    + +
    Content-Type:
    + +
    + The MIME media type of the document, with optional + parameters. Parameters are separated from the media type + and from one another by a semi-colon, with a syntax of + name=value. Common parameters include: + +
    +
    level
    +
    an integer specifying the version of the media type. + For text/html this defaults to 2, otherwise + 0.
    + +
    qs
    +
    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.
    +
    + + Example + Content-Type: image/jpeg; qs=0.8 + +
    + +
    URI:
    +
    uri of the file containing the variant (of the given + media type, encoded with the given content encoding). These + are interpreted as URLs relative to the map file; they must + be on the same server (!), and they must refer to files to + which the client would be granted access if they were to be + requested directly.
    + +
    Body:
    +
    New in Apache 2.0, the actual content of the resource may + be included in the type-map file using the Body header. This + header must contain a string that designates a delimiter for + the body content. Then all following lines in the type map + file will be considered part of the resource body until the + delimiter string is found. + + Example: + Body:----xyz----
    + <html>
    + <body>
    + <p>Content of the page.</p>
    + </body>
    + </html>
    + ----xyz---- +
    +
    +
    +
    + +
    MultiViews +

    A MultiViews search is enabled by the MultiViews + Options. If the server receives a + request for /some/dir/foo and + /some/dir/foo does not exist, then the + server reads the directory looking for all files named + foo.*, and effectively fakes up a 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 returns that document.

    + +

    The MultiViewsMatch + directive configures whether Apache will consider files + that do not have content negotiation meta-information assigned + to them when choosing files.

    +
    + + +CacheNegotiatedDocs +Allows content-negotiated documents to be +cached by proxy servers +CacheNegotiatedDocs On|Off +CacheNegotiatedDocs Off +server configvirtual host + +The syntax changed in version 2.0. + + +

    If set, this directive allows content-negotiated documents + to be cached by proxy servers. This could mean that clients + behind those proxys could retrieve versions of the documents + that are not the best match for their abilities, but it will + make caching more efficient.

    + +

    This directive only applies to requests which come from + HTTP/1.0 browsers. HTTP/1.1 provides much better control over + the caching of negotiated documents, and this directive has no + effect in responses to HTTP/1.1 requests.

    + +

    Prior to version 2.0, + CacheNegotiatedDocs did not take an + argument; it was turned on by the presence of the directive by + itself.

    +
    +
    + + +ForceLanguagePriority +Action to take if a single acceptable document is not +found +ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] +ForceLanguagePriority Prefer +server configvirtual host +directory.htaccess +FileInfo +Available in version 2.0.30 and later + + +

    The ForceLanguagePriority directive uses + the given LanguagePriority to satisfy + negotation where the server could otherwise not return a single + matching document.

    + +

    ForceLanguagePriority Prefer uses + LanguagePriority to serve a one valid result, rather + than returning an HTTP result 300 (MULTIPLE CHOICES) when there + are several equally valid choices. If the directives below were + given, and the user's Accept-Language header assigned + en and de each as quality .500 + (equally acceptable) then the first matching variant, en, + will be served.

    + + + LanguagePriority en fr de
    + ForceLanguagePriority Prefer +
    + +

    ForceLanguagePriority Fallback uses + LanguagePriority to + serve a valid result, rather than returning an HTTP result 406 + (NOT ACCEPTABLE). If the directives below were given, and the user's + Accept-Language only permitted an es + language response, but such a variant isn't found, then the first + variant from the LanguagePriority list below will be served.

    + + + LanguagePriority en fr de
    + ForceLanguagePriority Fallback +
    + +

    Both options, Prefer and Fallback, may be + specified, so either the first matching variant from LanguagePriority will be served if + more than one variant is acceptable, or first available document will + be served if none of the variants matched the client's acceptable list + of languages.

    +
    +AddLanguage +
    + + +LanguagePriority +The precendence of language variants for cases where +the client does not express a preference +LanguagePriority MIME-lang [MIME-lang] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    The LanguagePriority sets the precedence + of language variants for the case where the client does not + express a preference, when handling a MultiViews request. The list + of MIME-lang are in order of decreasing preference.

    + + Example: + LanguagePriority en fr de + + +

    For a request for foo.html, where + foo.html.fr and foo.html.de both + existed, but the browser did not express a language preference, + then foo.html.fr would be returned.

    + +

    Note that this directive only has an effect if a 'best' + language cannot be determined by any other means or the ForceLanguagePriority directive + is not None. In general, the client determines the + language preference, not the server.

    +
    +AddLanguage +
    + +
    diff --git a/trunk/docs/manual/mod/mod_negotiation.xml.ja b/trunk/docs/manual/mod/mod_negotiation.xml.ja new file mode 100644 index 0000000000..f7011f1f40 --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.xml.ja @@ -0,0 +1,278 @@ + + + + + + + + + +mod_negotiation +$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $B5!G=$rDs6!$9$k(B +Base +mod_negotiation.c +negotiation_module + + +

    $B%3%s%F%s%H%M%4%7%(!<%7%g%s!"$h$j@53N$K$O%3%s%F%s%D$NA*Br5!G=$O!"(B + $BJ#?tMQ0U$5$l$F$$$k%I%-%e%a%s%H$+$i!"%/%i%$%"%s%H$NG=NO$K0lHV9g$C$?(B + $B%I%-%e%a%s%H$rA*Br$9$k5!G=$G$9!#$3$N + +

      +
    • $B%?%$%W%^%C%W(B (type-map + $B%O%s%I%i$G07$o$l$k%U%!%$%k(B)$B!#$3$l$O(B variants + $B$r4^$s$G$$$k%U%!%$%k$rL@<(E*$K;XDj$7$^$9!#(B
    • + +
    • MultiViews $B$NC5:w(B (MultiViews Option $B$GM-8z$K$J$j$^$9(B)$B!#(B + $B%5!<%P$,0EL[$NFb$K%U%!%$%kL>$N%Q%?!<%s%^%C%A$r9T$J$$!"(B + $B$=$N7k2L$+$iA*Br$7$^$9!#(B
    • +
    +
    +Options +mod_mime +$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B +$B4D6-JQ?t(B + +
    $B%?%$%W%^%C%W(B +

    $B%?%$%W%^%C%W$O(B RFC 822 $B$N%a!<%k%X%C%@$KN`;w$7$?=q<0$G$9!#(B + $B%I%-%e%a%s%H$N5-=R$,6u9T$GJ,N%$5$l$F=q$+$l$F$$$F!"%O%C%7%eJ8;z(B + ('#') $B$G;O$^$k9T$O%3%a%s%H$H$7$F07$o$l$^$9!#(B + $B%I%-%e%a%s%H$N@bL@$OJ#?t$N%X%C%@%l%3!<%I$+$i9=@.$5$l$^$9!#(B + $B%l%3!<%I$O!"B3$-$N9T$,6uGr$G;O$^$C$F$$$k$HJ#?t$N9T$K$^$?$,$j$^$9!#(B + $B:G=i$N6uGr$,>C5n$5$l$F!"A0$N9T$H$D$J$2$F(B 1 $B9T$H$7$F07$o$l$^$9!#(B + $B%X%C%@%l%3!<%I$O%-!<%o!<%IL>$N8e$KCM$,B3$/$H$$$&7A<0$G!"(B + $B%-!<%o!<%IL>$O>o$K%3%m%s$G=*$o$j$^$9!#6uGr$O%X%C%@L>$HCM$N4V!"(B + $BCM$N%H!<%/%s$N4V$KF~$l$k$3$H$,$G$-$^$9!#(B + $B;HMQ2DG=$J%X%C%@$O0J2<$N$H$*$j$G$9(B:

    + +
    +
    Content-Encoding:
    +
    $B%U%!%$%k$N%(%s%3!<%G%#%s%0!#(BApache $B$O(B AddEncoding $B%G%#%l%/%F%#%V(B + $B$GDj5A$5$l$?%(%s%3!<%G%#%s%0$@$1$rG'<1$7$^$9!#DL>o(B compress + $B$5$l$?%U%!%$%k$N$?$a$N(B x-compress $B$H(B gzip + $B$5$l$?%U%!%$%k$N$?$a$N(B x-gzip $B$r4^$_$^$9!#(B + $B%(%s%3!<%G%#%s%0$NHf3S$r$9$k$H$-$O!"@\F,<-(B x- + $B$OL5;k$5$l$^$9!#(B
    + +
    Content-Language:
    +
    $B%$%s%?!<%M%C%HI8=`$N8@8l%?%0(B + (RFC 1766) + $B$GDj5A$5$l$F$$$k8@8l$Nen + $B$O1Q8l$rI=$7$^$9!#(B + $BJ#?t$N8@8l$,3JG<$5$l$k>l9g$O%3%s%^$G6h@Z$i$l$^$9!#(B
    + +
    Content-Length:
    +
    $B%U%!%$%k$ND9$5(B ($B%P%$%H?t(B)$B!#(B + $B$3$N%X%C%@$,$J$$>l9g!"%U%!%$%k$N + +
    Content-Type:
    +
    $B%I%-%e%a%s%H$N(B MIME + $B%a%G%#%"%?%$%W!"%*%W%7%g%J%k$J%Q%i%a!<%?IU$-!#%Q%i%a!<%?$N9=J8$O(B + name=value + $B$G!"%a%G%#%"%?%$%W$dB>$N%Q%i%a!<%?$H$O%;%_%3%m%s$GJ,N%$5$l$^$9!#(B + $B6&DL$N%Q%i%a!<%?$O0J2<$N$H$*$j(B: + +
    +
    level
    +
    $B%a%G%#%"%?%$%W$N%P!<%8%g%s$r<($9@0?t!#(B + text/html $B$G$O(B 2 $B$,%G%U%)%k%H$G!"$=$NB>$N>l9g$O(B + 0 $B$,%G%U%)%k%H$G$9!#(B
    + +
    qs
    +
    $B%/%i%$%"%s%H$NG=NO$K4X78$J$/!"(Bvariant + $B$rB>$HHf3S$7$?$H$-$NAjBPE*$J!VIJ.?t!#(B + $BNc$($P!"qs + $B$O%j%=!<%9Kh$KFCM-$NCM$r +
    + + $BNc(B + Content-Type: image/jpeg; qs=0.8 + +
    + +
    URI:
    +
    ($B;XDj$N%a%G%#%"%?%$%W!"%3%s%F%s%H%(%s%3!<%G%#%s%0$N(B) variant $B$N(B + $B%U%!%$%k$N(B uri. $B$3$l$O!"%^%C%W%U%!%$%k$+$i$NAjBP(B URL $B$H$7$F(B + $B2r@\%j%/%(%9%H$7$?$H$-$K%"%/%;%9$r5v2D$5$l$k$b$N$G$J$1$l$P$J$j$^$;$s!#(B
    + +
    Body:
    +
    Apache 2.0 $B$G?7@_$5$l$?$3$N(B Body $B%X%C%@$r;H$C$F!"(B + $B%j%=!<%9$NExample: + Body:----xyz----
    + <html>
    + <body>
    + <p>Content of the page.</p>
    + </body>
    + </html>
    + ----xyz---- + +
    +
    +
    + +
    MultiViews +

    MultiViews $BC5:w$O!"(BMultiviews Options $B%G%#%l%/%F%#%V$K$h$jM-8z$K$J$j$^$9!#(B + $B%5!<%P$,(B /some/dir/foo + $B$X$N%j%/%(%9%H$r/some/dir/foo $B$,B8:_(B + $B$7$J$$(B$B>l9g!"%5!<%P$O%G%#%l%/%H%j$rFI$s$G!"(B + foo.* $B$K$"$F$O$^$kA4$F$N%U%!%$%k$rC5$7!"(B + $B;ve$=$l$i$N%U%!%$%k$r%^%C%W$9$k%?%$%W%^%C%W$r:n$j$^$9!#(B + $B$=$N$H$-!"%a%G%#%"%?%$%W$H%3%s%F%s%H%(%s%3!<%G%#%s%0$O!"(B + $B$=$N%U%!%$%kL>$rD>@\;XDj$7$?$H$-$HF1$8$b$N$,3d$jEv$F$i$l$^$9!#(B + $B$=$l$+$i%/%i%$%"%s%H$NMW5a$K0lHV9g$&$b$N$rA*$S!"(B + $B$=$N%I%-%e%a%s%H$rJV$7$^$9!#(B

    + +

    $B%U%!%$%k$rA*Br$9$k:]$K!"4XO"$9$k%3%s%F%s%H%M%4%7%(!<%7%g%s$N(B + $B%a%?>pJs$r;}$?$J$$%U%!%$%k$K$D$$$F!"H=Dj$r9T$&$+$I$&$+$r(B + MultiViewsMatch + $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#(B

    +
    + + +CacheNegotiatedDocs +$B%3%s%F%s%H%M%4%7%(!<%7%g%s$5$l$?%I%-%e%a%s%H$r%W%m%-%7%5!<%P$,(B +$B%-%c%C%7%e$G$-$k$h$&$K$9$k(B +CacheNegotiatedDocs On|Off +CacheNegotiatedDocs Off +server config +virtual host + +$B%P!<%8%g%s(B 2.0$B$G9=J8$,JQ$o$j$^$7$?(B + + +

    $B$3$N%G%#%l%/%F%#%V$,@_Dj$5$l$F$$$k$H!"%3%s%F%s%H%M%4%7%(!<%7%g%s(B + $B$r$7$?7k2L$N%I%-%e%a%s%H$N%-%c%C%7%e$r5v2D$7$^$9!#(B + $B$3$l$O!"%W%m%-%7$N8e$m$K$$$k%/%i%$%"%s%H$,G=NO$K0lHV9g$C$?(B + $B%I%-%e%a%s%H$G$O$J$/!"(B + $B%-%c%C%7%e$r$h$j8z2LE*$K$9$k$b$N$rF@$k2DG=@-$,$"$k$H$$$&$3$H$G$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$O(B HTTP/1.0 $B%V%i%&%6$+$i$N%j%/%(%9%H(B + $B$N$_$KE,MQ$5$l$^$9!#(BHTTP/1.1 $B$O!"(B + $B8r>D$5$l$?%I%-%e%a%s%H$N%-%c%C%7%e$KBP$7$F$:$C$H$h$$@)8f$,2DG=$J$N$G!"(B + $B$3$N%G%#%l%/%F%#%V$O(B HTTP/1.1 $B$N%j%/%(%9%H$K$O1F6A$7$^$;$s!#(B

    +

    2.0 $B$h$jA0$N%P!<%8%g%s$G$O!"(B + CacheNegotiatedDocs $B$O0z?t$r + + + + +ForceLanguagePriority +$BMW5a$K9g$&C1FH$N%I%-%e%a%s%H$,8+$D$+$i$J$+$C$?$H$-$K9T$J$&$3$H$r;XDj(B + +ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] +ForceLanguagePriority Prefer +server configvirtual host +directory.htaccess +FileInfo +$B%P!<%8%g%s(B 2.0.30 $B0J9_$G;HMQ2DG=(B + + +

    ForceLanguagePriority $B%G%#%l%/%F%#%V$O(B + $BMW5a$K9g$&%I%-%e%a%s%H$r0l$D$@$1JV$9$3$H$,$G$-$J$$$H$-$K!"(B + LanguagePriority + $B%G%#%l%/%F%#%V$r;H$C$F%M%4%7%(!<%7%g%s$N7k2L$rJV$7$^$9!#(B

    + +

    ForceLanguagePriority Prefer $B$O!"F1Ey$NA*Br;h$,(B + $B$$$/$D$+$"$k$H$-$K!"(BHTTP $B$N(B 300 (MULTIPLE CHOICES) $B$rJV$9Be$o$j$K!"(B + LanguagePriority $B$r;H$C$F0l$D$@$1%I%-%e%a%s%H$rJV$9$h$&$K(B + $B$7$^$9!#0J2<$N%G%#%l%/%F%#%V$,;XDj$5$l$F$$$F!"%f!<%6$N(B Accept-Language + $B%X%C%@$G$O(B en $B$H(B de $B$NIJ.500 ($BF1$8$/$i$$5vMF(B) $B$G$"$k$H$-$O!"(B + $B:G=i$K%^%C%A$9$k(B variant $B$N(B en $B$,Aw$i$l$^$9!#(B

    + + + LanguagePriority en fr de
    + ForceLanguagePriority Prefer +
    + +

    ForceLanguagePriority Fallback $B$G$O!"(BHTTP 406 + (NOT ACCEPTABLE) $B$rAw?.$9$kBe$o$j$K!"(B + LanguagePriority + $B$,@5$7$$7k2L$rAw$j$^$9!#(B + $B0J2<$N%G%#%l%/%F%#%V$,;XDj$5$l$F$$$F!"%f!<%6$N(B Accept-Language + $B$,(B es $B8@8l$N$_$r5v2D$7$F$$$F!"$5$i$K$=$N$h$&$J(B variant $B$,$J$$$H$-$K$O!"(B + $B0J2<$N(B LanguagePriority + $B$N%j%9%H$N:G=i$N(B variant $B$,Aw$l$l$^$9!#(B

    + + + LanguagePriority en fr de
    + ForceLanguagePriority Fallback +
    + +

    Prefer $B$H(B Fallback $B$NN>J}$N%*%W%7%g%s$r(B + $BF1;~$K;XDj$9$k$3$H$,$G$-$^$9!#(B + $B$G$9$+$i!"J#?t$N(B variant $B$,$"$k$H$-$O(B + LanguagePriority $B$N:G=i$N(B + variant $B$,Aw$i$l!"%/%i%$%"%s%H$N5vMF8@8l$K9g$&(B vaiant $B$,$J$$$H$-$O(B + $BB8:_$9$k%I%-%e%a%s%H$G:G=i$N$b$N$,Aw$i$l$k!"$H$$$&MM$K$9$k$3$H$,$G$-$^$9!#(B

    +
    +AddLanguage +
    + + +LanguagePriority +$B%/%i%$%"%s%H$,M%@hEY$r<($5$J$+$C$?$H$-$N8@8l$N(B variant $B$NM%@hEY$r(B +$B;XDj(B +LanguagePriority MIME-lang [MIME-lang] +... +server configvirtual host +directory.htaccess +FileInfo + + +

    LanguagePriority $B$O!"(BMultiViews + $B%j%/%(%9%H$r07$&$H$-$K!"%/%i%$%"%s%H$,M%@h=g0L$rDs6!$7$F$$$J$$>l9g$N(B + $B8@8l$NM%@h=g0L$r@_Dj$7$^$9!#(BMIME-lang + $B$N%j%9%H$,M%@hEY$N9_=g$KJB$S$^$9!#(B

    + + Example: + LanguagePriority en fr de + + +

    foo.html $B$,%j%/%(%9%H$5$l!"(Bfoo.html.fr + $B$H(B foo.html.de $B$,N>J}B8:_$7!"(B + $B%V%i%&%6$,8@8l$NM%@h=g0L$rDs6!$7$F$J$$>l9g$O(B + foo.html.fr $B$,JV$5$l$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$OB>$NJ}K!$G!V:GA1!W(B + $B$N8@8l$,7hDj$G$-$J$$$H$-$+!"(BForceLanguagePriority $B%G%#%l%/%F%#%V$,(B + None $B0J30$N$H$-$K$N$_8z2L$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B0lHLE*$K$O!"%5!<%PB&$G$O$J$/%/%i%$%"%s%HB&$G9%$_$N8@8l$r7hDj$7$^$9!#(B

    +
    +AddLanguage +
    + +
    diff --git a/trunk/docs/manual/mod/mod_negotiation.xml.meta b/trunk/docs/manual/mod/mod_negotiation.xml.meta new file mode 100644 index 0000000000..0b53951696 --- /dev/null +++ b/trunk/docs/manual/mod/mod_negotiation.xml.meta @@ -0,0 +1,12 @@ + + + + mod_negotiation + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_nw_ssl.html b/trunk/docs/manual/mod/mod_nw_ssl.html new file mode 100644 index 0000000000..24adb0f8f0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_nw_ssl.html @@ -0,0 +1,3 @@ +URI: mod_nw_ssl.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_nw_ssl.html.en b/trunk/docs/manual/mod/mod_nw_ssl.html.en new file mode 100644 index 0000000000..a0e0e2f57b --- /dev/null +++ b/trunk/docs/manual/mod/mod_nw_ssl.html.en @@ -0,0 +1,97 @@ + + + +mod_nw_ssl - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_nw_ssl

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Enable SSL encryption for NetWare
    Status:Base
    Module Identifier:nwssl_module
    Source File:mod_nw_ssl.c
    Compatibility:NetWare only
    +

    Summary

    + +

    This module enables SSL encryption for a specified port. It + takes advantage of the SSL encryption functionality that is + built into the NetWare operating system.

    +
    + + +
    top
    +

    NWSSLTrustedCerts Directive

    + + + + + + +
    Description:List of additional client certificates
    Syntax:NWSSLTrustedCerts filename [filename] ...
    Context:server config
    Status:Base
    Module:mod_nw_ssl
    +

    Specifies a list of client certificate files (DER format) + that are used when creating a proxied SSL connection. Each + client certificate used by a server must be listed separately + in its own .der file.

    + +
    +
    top
    +

    NWSSLUpgradeable Directive

    + + + + + + +
    Description:Allows a connection to be upgraded to an SSL connection upon request
    Syntax:NWSSLUpgradeable [IP-address:]portnumber
    Context:server config
    Status:Base
    Module:mod_nw_ssl
    +

    Allow a connection that was created on the specified address + and/or port to be upgraded to an SSL connection upon request from + the client. The address and/or port must have already be defined + previously with a Listen + directive.

    + +
    +
    top
    +

    SecureListen Directive

    + + + + + + +
    Description:Enables SSL encryption for the specified port
    Syntax:SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]
    Context:server config
    Status:Base
    Module:mod_nw_ssl
    +

    Specifies the port and the eDirectory based certificate name + that will be used to enable SSL encryption. An optional third + parameter also enables mutual authentication.

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_nw_ssl.xml b/trunk/docs/manual/mod/mod_nw_ssl.xml new file mode 100644 index 0000000000..cf3f427671 --- /dev/null +++ b/trunk/docs/manual/mod/mod_nw_ssl.xml @@ -0,0 +1,81 @@ + + + + + + + + + +mod_nw_ssl +Enable SSL encryption for NetWare +Base +mod_nw_ssl.c +nwssl_module +NetWare only + + +

    This module enables SSL encryption for a specified port. It + takes advantage of the SSL encryption functionality that is + built into the NetWare operating system.

    +
    + + +SecureListen +Enables SSL encryption for the specified port +SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL] +server config + + +

    Specifies the port and the eDirectory based certificate name + that will be used to enable SSL encryption. An optional third + parameter also enables mutual authentication.

    +
    +
    + + +NWSSLTrustedCerts +List of additional client certificates +NWSSLTrustedCerts filename [filename] ... +server config + + +

    Specifies a list of client certificate files (DER format) + that are used when creating a proxied SSL connection. Each + client certificate used by a server must be listed separately + in its own .der file.

    +
    +
    + + +NWSSLUpgradeable +Allows a connection to be upgraded to an SSL connection upon request +NWSSLUpgradeable [IP-address:]portnumber +server config + + +

    Allow a connection that was created on the specified address + and/or port to be upgraded to an SSL connection upon request from + the client. The address and/or port must have already be defined + previously with a Listen + directive.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_nw_ssl.xml.meta b/trunk/docs/manual/mod/mod_nw_ssl.xml.meta new file mode 100644 index 0000000000..aee1060afb --- /dev/null +++ b/trunk/docs/manual/mod/mod_nw_ssl.xml.meta @@ -0,0 +1,11 @@ + + + + mod_nw_ssl + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_proxy.html b/trunk/docs/manual/mod/mod_proxy.html new file mode 100644 index 0000000000..2e413ab616 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.html @@ -0,0 +1,7 @@ +URI: mod_proxy.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_proxy.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_proxy.html.en b/trunk/docs/manual/mod/mod_proxy.html.en new file mode 100644 index 0000000000..2e50bda679 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.html.en @@ -0,0 +1,1203 @@ + + + +mod_proxy - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    Description:HTTP/1.1 proxy/gateway server
    Status:Extension
    Module Identifier:proxy_module
    Source File:mod_proxy.c
    +

    Summary

    + +

    Warning

    +

    Do not enable proxying with ProxyRequests until you have secured your server. Open proxy servers are dangerous both to your + network and to the Internet at large.

    +
    + +

    This module implements a proxy/gateway for Apache. It implements + proxying capability for AJP13 (Apache JServe Protocol + version 1.3), FTP, CONNECT (for SSL), + HTTP/0.9, HTTP/1.0, and HTTP/1.1. + The module can be configured to connect to other proxy modules for these + and other protocols.

    + +

    Apache's proxy features are divided into several modules in + addition to mod_proxy: + mod_proxy_http, mod_proxy_ftp, + mod_proxy_ajp, mod_proxy_balancer, + and mod_proxy_connect. Thus, if you want to use + one or more of the particular proxy functions, load + mod_proxy and the appropriate module(s) + into the server (either statically at compile-time or dynamically + via the LoadModule + directive).

    + +

    In addition, extended features are provided by other modules. + Caching is provided by mod_cache and related + modules. The ability to contact remote servers using the SSL/TLS + protocol is provided by the SSLProxy* directives of + mod_ssl. These additional modules will need + to be loaded and configured to take advantage of these features.

    +
    + +
    top
    +
    +

    Forward and Reverse Proxies

    +

    Apache can be configured in both a forward and + reverse proxy mode.

    + +

    An ordinary forward proxy is an intermediate + server that sits between the client and the origin + server. In order to get content from the origin server, + the client sends a request to the proxy naming the origin server + as the target and the proxy then requests the content from the + origin server and returns it to the client. The client must be + specially configured to use the forward proxy to access other + sites.

    + +

    A typical usage of a forward proxy is to provide Internet + access to internal clients that are otherwise restricted by a + firewall. The forward proxy can also use caching (as provided + by mod_cache) to reduce network usage.

    + +

    The forward proxy is activated using the ProxyRequests directive. Because + forward proxys allow clients to access arbitrary sites through + your server and to hide their true origin, it is essential that + you secure your server so that only + authorized clients can access the proxy before activating a + forward proxy.

    + +

    A reverse proxy, by contrast, appears to the + client just like an ordinary web server. No special + configuration on the client is necessary. The client makes + ordinary requests for content in the name-space of the reverse + proxy. The reverse proxy then decides where to send those + requests, and returns the content as if it was itself the + origin.

    + +

    A typical usage of a reverse proxy is to provide Internet + users access to a server that is behind a firewall. Reverse + proxies can also be used to balance load among several back-end + servers, or to provide caching for a slower back-end server. + In addition, reverse proxies can be used simply to bring + several servers into the same URL space.

    + +

    A reverse proxy is activated using the ProxyPass directive or the + [P] flag to the RewriteRule directive. It is + not necessary to turn ProxyRequests on in order to + configure a reverse proxy.

    +
    top
    +
    +

    Basic Examples

    + +

    The examples below are only a very basic idea to help you + get started. Please read the documentation on the individual + directives.

    + +

    In addition, if you wish to have caching enabled, consult + the documentation from mod_cache.

    + +

    Forward Proxy

    + ProxyRequests On
    + ProxyVia On
    +
    + <Proxy *>
    + + Order deny,allow
    + Deny from all
    + Allow from internal.example.com
    +
    + </Proxy> +

    + +

    Reverse Proxy

    + ProxyRequests Off
    +
    + <Proxy *>
    + + Order deny,allow
    + Allow from all
    +
    + </Proxy>
    +
    + ProxyPass /foo http://foo.example.com/bar
    + ProxyPassReverse /foo http://foo.example.com/bar +

    +
    top
    +
    +

    Controlling access to your proxy

    +

    You can control who can access your proxy via the <Proxy> control block as in + the following example:

    + +

    + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from 192.168.0
    +
    + </Proxy> +

    + +

    For more information on access control directives, see + mod_authz_host.

    + +

    Strictly limiting access is essential if you are using a + forward proxy (using the ProxyRequests directive). + Otherwise, your server can be used by any client to access + arbitrary hosts while hiding his or her true identity. This is + dangerous both for your network and for the Internet at large. + When using a reverse proxy (using the ProxyPass directive with + ProxyRequests Off), access control is less + critical because clients can only contact the hosts that you + have specifically configured.

    + +
    top
    +
    +

    FTP Proxy

    + + +

    Why doesn't file type xxx + download via FTP?

    +

    You probably don't have that particular file type defined as + application/octet-stream in your proxy's mime.types + configuration file. A useful line can be

    + +
    application/octet-stream   bin dms lha lzh exe class tgz taz
    +

    Alternatively you may prefer to default everything to binary:

    +
    DefaultType application/octet-stream
    + + +

    How can I force an FTP ASCII download of + File xxx?

    +

    In the rare situation where you must download a specific file using the + FTP ASCII transfer method (while the default transfer is in + binary mode), you can override mod_proxy's + default by suffixing the request with ;type=a to force an + ASCII transfer. (FTP Directory listings are always executed in ASCII mode, + however.)

    + + +

    How can I do FTP upload?

    +

    Currently, only GET is supported for FTP in mod_proxy. You can + of course use HTTP upload (POST or PUT) through an Apache proxy.

    + + +

    How can I access FTP files outside + of my home directory?

    +

    An FTP URI is interpreted relative to the home directory of the user + who is logging in. Alas, to reach higher directory levels you cannot + use /../, as the dots are interpreted by the browser and not actually + sent to the FTP server. To address this problem, the so called Squid + %2f hack was implemented in the Apache FTP proxy; it is a + solution which is also used by other popular proxy servers like the Squid Proxy Cache. By + prepending /%2f to the path of your request, you can make + such a proxy change the FTP starting directory to / (instead + of the home directory). For example, to retrieve the file + /etc/motd, you would use the URL:

    + +

    + ftp://user@host/%2f/etc/motd +

    + + +

    How can I hide the FTP cleartext password + in my browser's URL line?

    +

    To log in to an FTP server by username and password, Apache uses + different strategies. In absense of a user name and password in the URL + altogether, Apache sends an anonymous login to the FTP server, + i.e.,

    + +

    + user: anonymous
    + password: apache_proxy@ +

    + +

    This works for all popular FTP servers which are configured for + anonymous access.

    + +

    For a personal login with a specific username, you can embed the user + name into the URL, like in:

    + +

    + ftp://username@host/myfile +

    + +

    If the FTP server asks for a password when given this username (which + it should), then Apache will reply with a 401 (Authorization + required) response, which causes the Browser to pop up the + username/password dialog. Upon entering the password, the connection + attempt is retried, and if successful, the requested resource is + presented. The advantage of this procedure is that your browser does not + display the password in cleartext (which it would if you had used

    + +

    + ftp://username:password@host/myfile +

    + +

    in the first place).

    + +

    Note

    +

    The password which is transmitted in such a way is not encrypted on + its way. It travels between your browser and the Apache proxy server in + a base64-encoded cleartext string, and between the Apache proxy and the + FTP server as plaintext. You should therefore think twice before + accessing your FTP server via HTTP (or before accessing your personal + files via FTP at all!) When using unsecure channels, an eavesdropper + might intercept your password on its way.

    +
    + +
    top
    +
    +

    Slow Startup

    +

    If you're using the ProxyBlock directive, hostnames' IP addresses are looked up + and cached during startup for later match test. This may take a few + seconds (or more) depending on the speed with which the hostname lookups + occur.

    +
    top
    +
    +

    Intranet Proxy

    +

    An Apache proxy server situated in an intranet needs to forward + external requests through the company's firewall (for this, configure + the ProxyRemote directive + to forward the respective scheme to the firewall proxy). + However, when it has to + access resources within the intranet, it can bypass the firewall when + accessing hosts. The NoProxy + directive is useful for specifying which hosts belong to the intranet and + should be accessed directly.

    + +

    Users within an intranet tend to omit the local domain name from their + WWW requests, thus requesting "http://somehost/" instead of + http://somehost.example.com/. Some commercial proxy servers + let them get away with this and simply serve the request, implying a + configured local domain. When the ProxyDomain directive is used and the server is configured for proxy service, Apache can return + a redirect response and send the client to the correct, fully qualified, + server address. This is the preferred method since the user's bookmark + files will then contain fully qualified hosts.

    +
    top
    +
    +

    Protocol Adjustments

    +

    For circumstances where you have a application server which doesn't + implement keepalives or HTTP/1.1 properly, there are 2 environment + variables which when set send a HTTP/1.0 with no keepalive. These are set + via the SetEnv directive.

    + +

    These are the force-proxy-request-1.0 and + proxy-nokeepalive notes.

    + +

    + <Location /buggyappserver/>
    + + ProxyPass http://buggyappserver:7001/foo/
    + SetEnv force-proxy-request-1.0 1
    + SetEnv proxy-nokeepalive 1
    +
    + </Location> +

    +
    +
    top
    +

    AllowCONNECT Directive

    + + + + + + + +
    Description:Ports that are allowed to CONNECT through the +proxy
    Syntax:AllowCONNECT port [port] ...
    Default:AllowCONNECT 443 563
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The AllowCONNECT directive specifies a list + of port numbers to which the proxy CONNECT method may + connect. Today's browsers use this method when a https + connection is requested and proxy tunneling over HTTP is in effect.

    + +

    By default, only the default https port (443) and the + default snews port (563) are enabled. Use the + AllowCONNECT directive to override this default and + allow connections to the listed ports only.

    + +

    Note that you'll need to have mod_proxy_connect present + in the server in order to get the support for the CONNECT at + all.

    + +
    +
    top
    +

    NoProxy Directive

    + + + + + + +
    Description:Hosts, domains, or networks that will be connected to +directly
    Syntax:NoProxy host [host] ...
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    This directive is only useful for Apache proxy servers within + intranets. The NoProxy directive specifies a + list of subnets, IP addresses, hosts and/or domains, separated by + spaces. A request to a host which matches one or more of these is + always served directly, without forwarding to the configured + ProxyRemote proxy server(s).

    + +

    Example

    + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21 +

    + +

    The host arguments to the NoProxy + directive are one of the following type list:

    + +
    + +
    Domain
    +
    +

    A Domain is a partially qualified DNS domain name, preceded + by a period. It represents a list of hosts which logically belong to the + same DNS domain or zone (i.e., the suffixes of the hostnames are + all ending in Domain).

    + +

    Examples

    + .com .apache.org. +

    + +

    To distinguish Domains from Hostnames (both syntactically and semantically; a DNS domain can + have a DNS A record, too!), Domains are always written with a + leading period.

    + +

    Note

    +

    Domain name comparisons are done without regard to the case, and + Domains are always assumed to be anchored in the root of the + DNS tree, therefore two domains .MyDomain.com and + .mydomain.com. (note the trailing period) are considered + equal. Since a domain comparison does not involve a DNS lookup, it is much + more efficient than subnet comparison.

    +
    + + +
    SubNet
    +
    +

    A SubNet is a partially qualified internet address in + numeric (dotted quad) form, optionally followed by a slash and the netmask, + specified as the number of significant bits in the SubNet. It is + used to represent a subnet of hosts which can be reached over a common + network interface. In the absence of the explicit net mask it is assumed + that omitted (or zero valued) trailing digits specify the mask. (In this + case, the netmask can only be multiples of 8 bits wide.) Examples:

    + +
    +
    192.168 or 192.168.0.0
    +
    the subnet 192.168.0.0 with an implied netmask of 16 valid bits + (sometimes used in the netmask form 255.255.0.0)
    +
    192.168.112.0/21
    +
    the subnet 192.168.112.0/21 with a netmask of 21 + valid bits (also used in the form 255.255.248.0)
    +
    + +

    As a degenerate case, a SubNet with 32 valid bits is the + equivalent to an IPAddr, while a SubNet with zero + valid bits (e.g., 0.0.0.0/0) is the same as the constant + _Default_, matching any IP address.

    + + +
    IPAddr
    +
    +

    A IPAddr represents a fully qualified internet address in + numeric (dotted quad) form. Usually, this address represents a host, but + there need not necessarily be a DNS domain name connected with the + address.

    +

    Example

    + 192.168.123.7 +

    + +

    Note

    +

    An IPAddr does not need to be resolved by the DNS system, so + it can result in more effective apache performance.

    +
    + + +
    Hostname
    +
    +

    A Hostname is a fully qualified DNS domain name which can + be resolved to one or more IPAddrs via the + DNS domain name service. It represents a logical host (in contrast to + Domains, see above) and must be resolvable + to at least one IPAddr (or often to a list + of hosts with different IPAddrs).

    + +

    Examples

    + prep.ai.mit.edu
    + www.apache.org +

    + +

    Note

    +

    In many situations, it is more effective to specify an IPAddr in place of a Hostname since a + DNS lookup can be avoided. Name resolution in Apache can take a remarkable + deal of time when the connection to the name server uses a slow PPP + link.

    +

    Hostname comparisons are done without regard to the case, + and Hostnames are always assumed to be anchored in the root + of the DNS tree, therefore two hosts WWW.MyDomain.com + and www.mydomain.com. (note the trailing period) are + considered equal.

    +
    +
    + +

    See also

    + +
    +
    top
    +

    <Proxy> Directive

    + + + + + + +
    Description:Container for directives applied to proxied resources
    Syntax:<Proxy wildcard-url> ...</Proxy>
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    Directives placed in <Proxy> + sections apply only to matching proxied content. Shell-style wildcards are + allowed.

    + +

    For example, the following will allow only hosts in + yournetwork.example.com to access content via your proxy + server:

    + +

    + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from yournetwork.example.com
    +
    + </Proxy> +

    + +

    The following example will process all files in the foo + directory of example.com through the INCLUDES + filter when they are sent through the proxy server:

    + +

    + <Proxy http://example.com/foo/*>
    + + SetOutputFilter INCLUDES
    +
    + </Proxy> +

    + + +
    +
    top
    +

    ProxyBadHeader Directive

    + + + + + + + + +
    Description:Determines how to handle bad header lines in a +response
    Syntax:ProxyBadHeader IsError|Ignore|StartBody
    Default:ProxyBadHeader IsError
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    Compatibility:available in Apache 2.0.44 and later
    +

    The ProxyBadHeader directive determines the + behaviour of mod_proxy if it receives syntactically invalid + header lines (i.e. containing no colon). The following arguments + are possible:

    + +
    +
    IsError
    +
    Abort the request and end up with a 502 (Bad Gateway) response. This is + the default behaviour.
    + +
    Ignore
    +
    Treat bad header lines as if they weren't sent.
    + +
    StartBody
    +
    When receiving the first bad header line, finish reading the headers and + treat the remainder as body. This helps to work around buggy backend servers + which forget to insert an empty line between the headers and the body.
    +
    + +
    +
    top
    +

    ProxyBlock Directive

    + + + + + + +
    Description:Words, hosts, or domains that are banned from being +proxied
    Syntax:ProxyBlock *|word|host|domain +[word|host|domain] ...
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The ProxyBlock directive specifies a list of + words, hosts and/or domains, separated by spaces. HTTP, HTTPS, and + FTP document requests to sites whose names contain matched words, + hosts or domains are blocked by the proxy server. The proxy + module will also attempt to determine IP addresses of list items which + may be hostnames during startup, and cache them for match test as + well. That may slow down the startup time of the server.

    + +

    Example

    + ProxyBlock joes-garage.com some-host.co.uk rocky.wotsamattau.edu +

    + +

    rocky.wotsamattau.edu would also be matched if referenced by + IP address.

    + +

    Note that wotsamattau would also be sufficient to match + wotsamattau.edu.

    + +

    Note also that

    + +

    + ProxyBlock * +

    + +

    blocks connections to all sites.

    + +
    +
    top
    +

    ProxyDomain Directive

    + + + + + + +
    Description:Default domain name for proxied requests
    Syntax:ProxyDomain Domain
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    This directive is only useful for Apache proxy servers within + intranets. The ProxyDomain directive specifies + the default domain which the apache proxy server will belong to. If a + request to a host without a domain name is encountered, a redirection + response to the same host with the configured Domain appended + will be generated.

    + +

    Example

    + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21
    + ProxyDomain .mycompany.com +

    + +
    +
    top
    +

    ProxyErrorOverride Directive

    + + + + + + + + +
    Description:Override error pages for proxied content
    Syntax:ProxyErrorOverride On|Off
    Default:ProxyErrorOverride Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    Compatibility:Available in version 2.0 and later
    +

    This directive is useful for reverse-proxy setups, where you want to + have a common look and feel on the error pages seen by the end user. + This also allows for included files (via + mod_include's SSI) to get + the error code and act accordingly (default behavior would display + the error page of the proxied server, turning this on shows the SSI + Error message).

    + +
    +
    top
    +

    ProxyIOBufferSize Directive

    + + + + + + + +
    Description:Determine size of internal data throughput buffer
    Syntax:ProxyIOBufferSize bytes
    Default:ProxyIOBufferSize 8192
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The ProxyIOBufferSize directive adjusts the size + of the internal buffer, which is used as a scratchpad for the data between + input and output. The size must be less or equal 8192.

    + +

    In almost every case there's no reason to change that value.

    + +
    +
    top
    +

    <ProxyMatch> Directive

    + + + + + + +
    Description:Container for directives applied to regular-expression-matched +proxied resources
    Syntax:<ProxyMatch regex> ...</ProxyMatch>
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The <ProxyMatch> directive is + identical to the <Proxy> directive, except it matches URLs + using regular expressions.

    + +
    +
    top
    +

    ProxyMaxForwards Directive

    + + + + + + + + +
    Description:Maximium number of proxies that a request can be forwarded +through
    Syntax:ProxyMaxForwards number
    Default:ProxyMaxForwards 10
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    Compatibility:Available in Apache 2.0 and later
    +

    The ProxyMaxForwards directive specifies the + maximum number of proxies through which a request may pass, if there's no + Max-Forwards header supplied with the request. This is + set to prevent infinite proxy loops, or a DoS attack.

    + +

    Example

    + ProxyMaxForwards 15 +

    + +
    +
    top
    +

    ProxyPass Directive

    + + + + + + +
    Description:Maps remote servers into the local server URL-space
    Syntax:ProxyPass [path] !|url [key=value key=value ...]]
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_proxy
    +

    This directive allows remote servers to be mapped into the space of + the local server; the local server does not act as a proxy in the + conventional sense, but appears to be a mirror of the remote + server. path is the name of a local virtual path; url + is a partial URL for the remote server and cannot include a query + string.

    + +
    The ProxyRequests directive should + usually be set off when using + ProxyPass.
    + +

    Suppose the local server has address http://example.com/; + then

    + +

    + ProxyPass /mirror/foo/ http://backend.example.com/ +

    + +

    will cause a local request for + http://example.com/mirror/foo/bar to be internally converted + into a proxy request to http://backend.example.com/bar.

    + +

    The ! directive is useful in situations where you don't want + to reverse-proxy a subdirectory, e.g.

    + +

    + ProxyPass /mirror/foo/i !
    + ProxyPass /mirror/foo http://backend.example.com +

    + +

    will proxy all requests to /mirror/foo to + backend.example.com except requests made to + /mirror/foo/i.

    + +

    Note

    +

    Order is important. you need to put the exclusions before the + general ProxyPass directive.

    +
    + +

    New in Apache 2.1, is the ability to use pooled connections to a + backend server. Using the key=value parameters it is possible + to tune this connection pooling. The default for a Hard Maximum + for the number of connections is the number of threads per process in the + active MPM. In the Prefork MPM, this is always 1, while with the Worker MPM + it is controlled by the ThreadsPerChild.

    + +

    Setting min will determine how many connections will always + be open to the backend server. Upto the Soft Maximum or smax + number of connections will be created on demand. Any connections above + smax are subject to a time to live or ttl. Apache + will never create more than the Hard Maximum or max connections + to the backend server.

    + +

    + ProxyPass /example http://backend.example.com smax=5 max=20 ttl=120 retry=300 +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterDefaultDescription
    min0Minumum number of connections that will always + be open to the backend server.
    max1...nHard Maximum number of connections that will be + allowed to the backend server. The default for a Hard Maximum + for the number of connections is the number of threads per process in the + active MPM. In the Prefork MPM, this is always 1, while with the Worker MPM + it is controlled by the ThreadsPerChild. + Apache will never create more than the Hard Maximum connections + to the backend server.
    smaxmaxUpto the Soft Maximum + number of connections will be created on demand. Any connections above + smax are subject to a time to live or ttl. +
    ttl-Time To Live for the inactive connections above the + smax connections in seconds. Apache will close all + connections that has not been used inside that time period. +
    timeoutTimeoutConnection timeout in seconds. + If not set the Apache will wait until the free connection + is available. This directive is used for limiting the number + of connections to the backend server together with max + parameter. +
    acquire-If set this will be the maximum time to wait for a free + connection in the connection pool. If there are no free connections + in the pool the Apache will return SERVER_BUSY status to + the client. +
    keepaliveOffThis parameter should be used when you have a firewall between your + Apache and the backend server, who tend to drop inactive connections. + This flag will tell the Operating System to send KEEP_ALIVE + messages on inactive connections (interval depends on global OS settings, + generally 120ms), and thus prevent the firewall to drop the connection. + To enable keepalive set this property value to On. +
    retry60Connection pool worker retry timeout in seconds. + If the connection pool worker to the backend server is in the error state, + Apache will not forward any requests to that server until the timeout + expires. This enables to shut down the backend server for maintenance, + and bring it back online later. +
    loadfactor1Worker load factor. Used with BalancerMember. + It is a number between 1 and 100 and defines the normalized weighted + load applied to the worker. +
    route-Route of the worker when used inside load balancer. + The route is a value appended to seesion id. +
    redirect-Redirection Route of the worker. This value is usually + set dynamically to enable safe removal of the node from + the cluster. If set all requests without session id will be + redirected to the BalancerMember that has route parametar + equal as this value. +
    + +

    If the Proxy directive scheme starts with the + balancer:// then a virtual worker that does not really + communicate with the backend server will be created. Instead it is responsible + for the management of several "real" workers. In that case the special set of + parameters can be add to this virtual worker. +

    + + + + + + + + + + + + + + + + + + + + +
    ParameterDefaultDescription
    lbmethod-Balancer load-balance method. Select the load-balancing scheduler + method to use. Either requests, to perform weighted + request counting or traffic, to perform weighted + traffic byte count balancing. Default is requests. +
    stickysession-Balancer sticky session name. The value is usually set to something + like JSESSIONID or PHPSESSIONID, + and it depends on the backend application server that support sessions. +
    nofailoverOffIf set to On the session will break if the worker is in + error state or disabled. Set this value to On if backend servers do not + support session replication. +
    timeout0Balancer timeout in seconds. If set this will be the maximum time + to wait for a free worker. Default is not to wait. +
    maxattempts1Maximum number of failover attempts before giving up. +
    +

    + ProxyPass /special-area http://special.example.com/ smax=5 max=10
    + ProxyPass / balancer://mycluster stickysession=jsessionid nofailover=On
    + <Proxy balancer://mycluster>
    + + BalancerMember http://1.2.3.4:8009
    + BalancerMember http://1.2.3.5:8009 smax=10
    + # Less powerful server, don't send as many requests there
    + BalancerMember http://1.2.3.6:8009 smax=1 loadfactor=20
    +
    + </Proxy> +

    + +

    When used inside a <Location> section, the first argument is omitted and the local + directory is obtained from the <Location>.

    + +

    If you require a more flexible reverse-proxy configuration, see the + RewriteRule directive with the + [P] flag.

    + +
    +
    top
    +

    ProxyPassReverse Directive

    + + + + + + +
    Description:Adjusts the URL in HTTP response headers sent from a reverse +proxied server
    Syntax:ProxyPassReverse [path] url
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_proxy
    +

    This directive lets Apache adjust the URL in the Location, + Content-Location and URI headers on HTTP redirect + responses. This is essential when Apache is used as a reverse proxy to avoid + by-passing the reverse proxy because of HTTP redirects on the backend + servers which stay behind the reverse proxy.

    + +

    Only the HTTP response headers specifically mentioned above + will be rewritten. Apache will not rewrite other response + headers, nor will it rewrite URL references inside HTML pages. + This means that if the proxied content contains absolute URL + references, they will by-pass the proxy. A third-party module + that will look inside the HTML and rewrite URL references is Nick + Kew's mod_proxy_html.

    + +

    path is the name of a local virtual path. url is a + partial URL for the remote server - the same way they are used for the + ProxyPass directive.

    + +

    For example, suppose the local server has address + http://example.com/; then

    + +

    + ProxyPass /mirror/foo/ http://backend.example.com/
    + ProxyPassReverse /mirror/foo/ http://backend.example.com/
    + ProxyPassReverseCookieDomain backend.example.com public.example.com
    + ProxyPassReverseCookiePath / /mirror/foo/ +

    + +

    will not only cause a local request for the + http://example.com/mirror/foo/bar to be internally converted + into a proxy request to http://backend.example.com/bar + (the functionality ProxyPass provides here). It also takes care + of redirects the server backend.example.com sends: when + http://backend.example.com/bar is redirected by him to + http://backend.example.com/quux Apache adjusts this to + http://example.com/mirror/foo/quux before forwarding the HTTP + redirect response to the client. Note that the hostname used for + constructing the URL is chosen in respect to the setting of the UseCanonicalName directive.

    + +

    Note that this ProxyPassReverse directive can + also be used in conjunction with the proxy pass-through feature + (RewriteRule ... [P]) from mod_rewrite + because its doesn't depend on a corresponding ProxyPass directive.

    + +

    When used inside a <Location> section, the first argument is omitted and the local + directory is obtained from the <Location>.

    + +
    +
    top
    +

    ProxyPassReverseCookieDomain Directive

    + + + + + + +
    Description:Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server
    Syntax:ProxyPassReverseCookieDomain internal-domain public-domain
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_proxy
    +

    Usage is basically similar to +ProxyPassReverse, but instead of +rewriting headers that are a URL, this rewrites the domain +string in Set-Cookie headers.

    + +
    +
    top
    +

    ProxyPassReverseCookiePath Directive

    + + + + + + +
    Description:Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server
    Syntax:ProxyPassReverseCookiePath internal-path public-path
    Context:server config, virtual host, directory
    Status:Extension
    Module:mod_proxy
    +

    Usage is basically similar to +ProxyPassReverse, but instead of +rewriting headers that are a URL, this rewrites the path +string in Set-Cookie headers.

    + +
    +
    top
    +

    ProxyPreserveHost Directive

    + + + + + + + + +
    Description:Use incoming Host HTTP request header for proxy +request
    Syntax:ProxyPreserveHost On|Off
    Default:ProxyPreserveHost Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    Compatibility:Available in Apache 2.0.31 and later.
    +

    When enabled, this option will pass the Host: line from the incoming + request to the proxied host, instead of the hostname specified in the + ProxyPass line.

    + +

    This option should normally be turned Off. It is mostly + useful in special configurations like proxied mass name-based virtual + hosting, where the original Host header needs to be evaluated by the + backend server.

    + +
    +
    top
    +

    ProxyReceiveBufferSize Directive

    + + + + + + + +
    Description:Network buffer size for proxied HTTP and FTP +connections
    Syntax:ProxyReceiveBufferSize bytes
    Default:ProxyReceiveBufferSize 0
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The ProxyReceiveBufferSize directive specifies an + explicit (TCP/IP) network buffer size for proxied HTTP and FTP connections, + for increased throughput. It has to be greater than 512 or set + to 0 to indicate that the system's default buffer size should + be used.

    + +

    Example

    + ProxyReceiveBufferSize 2048 +

    + +
    +
    top
    +

    ProxyRemote Directive

    + + + + + + +
    Description:Remote proxy used to handle certain requests
    Syntax:ProxyRemote match remote-server
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    This defines remote proxies to this proxy. match is either the + name of a URL-scheme that the remote server supports, or a partial URL + for which the remote server should be used, or * to indicate + the server should be contacted for all requests. remote-server is + a partial URL for the remote server. Syntax:

    + +

    + remote-server = + scheme://hostname[:port] +

    + +

    scheme is effectively the protocol that should be used to + communicate with the remote server; only http is supported by + this module.

    + +

    Example

    + ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000
    + ProxyRemote * http://cleversite.com
    + ProxyRemote ftp http://ftpproxy.mydomain.com:8080 +

    + +

    In the last example, the proxy will forward FTP requests, encapsulated + as yet another HTTP proxy request, to another proxy which can handle + them.

    + +

    This option also supports reverse proxy configuration - a backend + webserver can be embedded within a virtualhost URL space even if that + server is hidden by another forward proxy.

    + +
    +
    top
    +

    ProxyRemoteMatch Directive

    + + + + + + +
    Description:Remote proxy used to handle requests matched by regular +expressions
    Syntax:ProxyRemoteMatch regex remote-server
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    The ProxyRemoteMatch is identical to the + ProxyRemote directive, except the + first argument is a regular expression match against the requested URL.

    + +
    +
    top
    +

    ProxyRequests Directive

    + + + + + + + +
    Description:Enables forward (standard) proxy requests
    Syntax:ProxyRequests On|Off
    Default:ProxyRequests Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    This allows or prevents Apache from functioning as a forward proxy + server. (Setting ProxyRequests to Off does not disable use of + the ProxyPass directive.)

    + +

    In a typical reverse proxy configuration, this option should be set to + Off.

    + +

    In order to get the functionality of proxying HTTP or FTP sites, you + need also mod_proxy_http or mod_proxy_ftp + (or both) present in the server.

    + +

    Warning

    +

    Do not enable proxying with ProxyRequests until you have secured your server. Open proxy servers are dangerous + both to your network and to the Internet at large.

    +
    + +
    +
    top
    +

    ProxyTimeout Directive

    + + + + + + + + +
    Description:Network timeout for proxied requests
    Syntax:ProxyTimeout seconds
    Default:ProxyTimeout 300
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    Compatibility:Available in Apache 2.0.31 and later
    +

    This directive allows a user to specifiy a timeout on proxy requests. + This is useful when you have a slow/buggy appserver which hangs, and you + would rather just return a timeout and fail gracefully instead of waiting + however long it takes the server to return.

    + +
    +
    top
    +

    ProxyVia Directive

    + + + + + + + +
    Description:Information provided in the Via HTTP response +header for proxied requests
    Syntax:ProxyVia On|Off|Full|Block
    Default:ProxyVia Off
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy
    +

    This directive controls the use of the Via: HTTP + header by the proxy. Its intended use is to control the flow of + proxy requests along a chain of proxy servers. See RFC 2616 (HTTP/1.1), section + 14.45 for an explanation of Via: header lines.

    + +
      +
    • If set to Off, which is the default, no special processing + is performed. If a request or reply contains a Via: header, + it is passed through unchanged.
    • + +
    • If set to On, each request and reply will get a + Via: header line added for the current host.
    • + +
    • If set to Full, each generated Via: header + line will additionally have the Apache server version shown as a + Via: comment field.
    • + +
    • If set to Block, every proxy request will have all its + Via: header lines removed. No new Via: header will + be generated.
    • +
    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy.html.ja.euc-jp b/trunk/docs/manual/mod/mod_proxy.html.ja.euc-jp new file mode 100644 index 0000000000..a7701b074a --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.html.ja.euc-jp @@ -0,0 +1,1202 @@ + + + +mod_proxy - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_proxy

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    ÀâÌÀ:HTTP/1.1 ¥×¥í¥­¥·/¥²¡¼¥È¥¦¥§¥¤¥µ¡¼¥Ð
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:proxy_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_proxy.c
    +

    ³µÍ×

    + +

    ·Ù¹ð

    +

    ¥µ¡¼¥Ð¤ò°ÂÁ´¤Ë¤¹¤ë¤Þ¤Ç ProxyRequests ¤ÏÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¥ª¡¼¥×¥ó¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï¤¢¤Ê¤¿¼«¿È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤È¤Ã¤Æ¤â¡¢ + ¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÁ´ÂΤˤȤäƤâ´í¸±¤Ç¤¹¡£

    +
    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï Apache ¤Î¥×¥í¥­¥·/¥²¡¼¥È¥¦¥§¥¤µ¡Ç½¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£ + AJP13 (Apache JServe Protocol version 1.3), + FTP, CONNECT (SSL ÍÑ), + HTTP/0.9, HTTP/1.0, HTTP/1.1 + ¤Î¥×¥í¥­¥·µ¡Ç½¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤Î¥×¥í¥È¥³¥ë¤ä¤½¤Î¾¤Î¥×¥í¥È¥³¥ëÍѤΠ+ ¥×¥í¥­¥·µ¡Ç½¤ò»ý¤Ã¤¿¡¢Â¾¤Î¥â¥¸¥å¡¼¥ë¤ËÀܳ¤¹¤ë¤è¤¦¤Ë¤âÀßÄê¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ¤Î¥×¥í¥­¥·µ¡Ç½¤Ï mod_proxy ¤Î¾¤Ë¡¢ + ¤¤¤¯¤Ä¤«¤Î¥â¥¸¥å¡¼¥ë¤Ëʬ³ä¤µ¤ì¤Æ¤¤¤Þ¤¹: + mod_proxy_http, mod_proxy_ftp, + mod_proxy_ajp, mod_proxy_balancer, + mod_proxy_connect ¤Ç¤¹¡£¤Ç¤¹¤«¤é¡¢ + ÆÃÄê¤Î¥×¥í¥­¥·¤Îµ¡Ç½¤ò»È¤¤¤¿¤¤¾ì¹ç¤Ï¡¢mod_proxy ¤È + ³ºÅö¤¹¤ë¥â¥¸¥å¡¼¥ë¤ò¥µ¡¼¥Ð¤Ë (¥³¥ó¥Ñ¥¤¥ë»þ¤ËÀÅŪ¤Ë¹Ô¤Ê¤¦¤« + LoadModule ¤ÇưŪ¤ËÆɤ߹þ¤à¤«¤·¤Æ) + ÁȤ߹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¤³¤ì¤Ë²Ã¤¨¤Æ¡¢Â¾¤Î¥â¥¸¥å¡¼¥ë¤Ë¤è¤Ã¤Æ³ÈÄ¥µ¡Ç½¤¬Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¥­¥ã¥Ã¥·¥å¤Ï mod_cache ¤È´ØÏ¢¥â¥¸¥å¡¼¥ë¤Ç + Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£SSL/TLS ¤Ç±ó³Ö¥µ¡¼¥Ð¤ËÀܳ¤¹¤ëµ¡Ç½¤Ï + mod_ssl ¤Î SSLProxy* ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤Îµ¡Ç½¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¢³ºÅö¤¹¤ë¥â¥¸¥å¡¼¥ë¤ò + ÁȤ߹þ¤ó¤ÇÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    ¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤È¥ê¥Ð¡¼¥¹¥×¥í¥­¥·

    +

    Apache ¤Ï¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤È¤·¤Æ¤â¡¢ + ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤È¤·¤Æ¤âÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Ä̾ï¤Î¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Ï¥¯¥é¥¤¥¢¥ó¥È¤È + ¥ª¥ê¥¸¥ó¥µ¡¼¥Ð (ÌõÃí: ¥³¥ó¥Æ¥ó¥ÄÀ¸À®¸µ¤Î¥µ¡¼¥Ð) + ¤Î´Ö¤Ë°ÌÃÖ¤¹¤ëÃæ´Ö¥µ¡¼¥Ð¤Ç¤¹¡£ + ¥ª¥ê¥¸¥ó¥µ¡¼¥Ð¤«¤é¥³¥ó¥Æ¥ó¥Ä¤ò¼èÆÀ¤¹¤ë²áÄø¤Ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï + ¹Ô¤­Àè¤È¤·¤Æ¥ª¥ê¥¸¥ó¥µ¡¼¥Ð¤ò»ØÄꤷ¤Ä¤Ä¥×¥í¥­¥·¤Ë¥ê¥¯¥¨¥¹¥È¤òÁ÷¤ê¡¢ + ¥×¥í¥­¥·¤Ï¥ª¥ê¥¸¥ó¥µ¡¼¥Ð¤«¤é¥³¥ó¥Æ¥ó¥Ä¼èÆÀ¤Î¥ê¥¯¥¨¥¹¥È¤òÁ÷¤ê¡¢ + ¥³¥ó¥Æ¥ó¥Ä¤¬¼èÆÀ¤Ç¤­¤ì¤Ð¤½¤ì¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤·¤Þ¤¹¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤¬Â¾¤Î¥µ¥¤¥È¤Ë¥Õ¥©¥ï¡¼¥É¥×¥í¥¯¥··Ðͳ¤Ç¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢ + ÆÃÊ̤ˤ½¤ìÍѤÎÀßÄê¤ò¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Î°ìÈÌŪ¤Ê»ÈÍÑÊýË¡¤Ï¡¢¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Ë¤è¤Ã¤Æ + À©¸Â¤µ¤ì¤Æ¤¤¤ëÆâÉô¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ë¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤Ø¤Î¥¢¥¯¥»¥¹¤ò + Ä󶡤¹¤ë¤â¤Î¤Ç¤¹¡£¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Ï¥Í¥Ã¥È¥ï¡¼¥¯¤Î»ÈÍÑÎ̤ò + ¸º¤é¤¹¤¿¤á¤Ë (mod_cache ¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë) + ¥­¥ã¥Ã¥·¥åµ¡Ç½¤òÍѤ¤¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    ¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Ï ProxyRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + Í­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÏËÜÅö¤Î¿È¸µ¤ò + ±£¤·¤ÆǤ°Õ¤Î¥µ¥¤¥È¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë¤¿¤á¡¢¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤ò + Í­¸ú¤Ë¤¹¤ëÁ°¤Ë¡¢¾µÇ§¤µ¤ì¤¿¥¯¥é¥¤¥¢¥ó¥È¤Î¤ß¤¬¥×¥í¥­¥·¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë + ¥µ¡¼¥Ð¤ò°ÂÁ´¤Ë¤¹¤ë¤³¤È¤¬½ÅÍפǤ¹¡£

    + +

    °ìÊý¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ë¤ÏÉáÄ̤Π+ ¥¦¥§¥Ö¥µ¡¼¥Ð¤Î¤è¤¦¤Ë¸«¤¨¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¦¤ËÆÃÊ̤ÊÀßÄê¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£ + ¥¯¥é¥¤¥¢¥ó¥È¤Ï¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤Î̾Á°¶õ´Ö¤ËÂФ·¤ÆÄ̾ï¤Î¥³¥ó¥Æ¥ó¥Ä¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£¥×¥í¥­¥·¤Ï¥ê¥¯¥¨¥¹¥È¤ò¤É¤³¤ËÁ÷¤ì¤ÐÎɤ¤¤«¤òȽÄꤷ¡¢ + ¤¢¤¿¤«¤â¼«Ê¬¼«¿È¤¬¥ª¥ê¥¸¥ó¥µ¡¼¥Ð¤Ç¤¢¤Ã¤¿¤«¤Î¤è¤¦¤Ë¥¯¥é¥¤¥¢¥ó¥È¤Ë + ¥³¥ó¥Æ¥ó¥Ä¤òÊÖ¤·¤Þ¤¹¡£

    + +

    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤Î¤è¤¯¤¢¤ëÍøÍÑÊýË¡¤Ï¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥æ¡¼¥¶¤Ë + ¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤ÎÃæ¤Ë¤¢¤ë¥µ¡¼¥Ð¤Ë¥¢¥¯¥»¥¹¤òÍ¿¤¨¤ë¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£ + ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ÏÊ£¿ô¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤ØÉé²Ùʬ»¶¤ò¤¹¤ë¤¿¤á¤Ë + »È¤Ã¤¿¤ê¡¢ÃÙ¤¤¥Ð¥Ã¥¯¥¨¥ó¥É¥¨¥ó¥É¥µ¡¼¥Ð¤Î¤¿¤á¤Ë¥­¥ã¥Ã¥·¥åµ¡Ç½¤òÄ󶡤·¤¿¤ê + ¤¹¤ë¤¿¤á¤Ë»È¤¨¤Þ¤¹¡£¤Þ¤¿¡¢¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ÏÊ£¿ô¤Î¥µ¡¼¥Ð¤ò + Ʊ¤¸ URL ¶õ´Ö¤Ë¤Þ¤È¤á¤ë¤¿¤á¤Ë»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + +

    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤Ï ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + RewriteRule ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + [P] ¥Õ¥é¥°¤ò»È¤¦¤³¤È¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤Î + ÀßÄê¤Î¤¿¤á¤Ë ProxyRequests ¤òÀßÄꤹ¤ëɬÍ×¤Ï + ¤¢¤ê¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ´ðËܤÎÎã

    + +

    °Ê²¼¤ÎÎã¤Ï¼ê»Ï¤á¤Î´Êñ¤ÊÎã¤Ç¤¹¡£¸Ä¡¹¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ÕÌ£¤Ï + ¤½¤ì¤¾¤ì¤ÎÀâÌÀ¤ò¤ªÆɤߤ¯¤À¤µ¤¤¡£

    + +

    ¤Þ¤¿¥­¥ã¥Ã¥·¥åµ¡Ç½¤òÍ­¸ú¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢mod_cache + ¤ÎÀâÌÀ¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£

    + +

    ¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·

    + ProxyRequests On
    + ProxyVia On
    +
    + <Proxy *>
    + + Order deny,allow
    + Deny from all
    + Allow from internal.example.com
    +
    + </Proxy> +

    + +

    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·

    + ProxyRequests Off
    +
    + <Proxy *>
    + + Order deny,allow
    + Allow from all
    +
    + </Proxy>
    +
    + ProxyPass /foo http://foo.example.com/bar
    + ProxyPassReverse /foo http://foo.example.com/bar +

    +
    top
    +
    +

    ¥×¥í¥­¥·¤Ø¤Î¥¢¥¯¥»¥¹À©¸æ

    +

    ¥×¥í¥­¥·¤Î¥¢¥¯¥»¥¹¤Ï°Ê²¼¤Î¤è¤¦¤Ë <Proxy> ¥³¥ó¥Æ¥Ê¤ÎÃæ¤Ë + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤ÇÀ©¸æ¤Ç¤­¤Þ¤¹:

    + +

    + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from 192.168.0
    +
    + </Proxy> +

    + +

    ¥¢¥¯¥»¥¹À©¸æ¤Î¤¿¤á¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤è¤ê¾Ü¤·¤¤¾ðÊó¤Ï + mod_authz_host ¤ò¤ªÆɤߤ¯¤À¤µ¤¤¡£

    + +

    (ProxyRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤Ã¤Æ) ¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤òÀßÄꤷ¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¸·¤·¤¯¥¢¥¯¥»¥¹ + À©¸Â¤ò¹Ô¤Ê¤¦¤³¤È¤¬Èó¾ï¤ËÂçÀڤǤ¹¡£¤½¤¦¤·¤Ê¤¤¤È¡¢Ç¤°Õ¤Î¥¯¥é¥¤¥¢¥ó¥È¤¬ + ¿È¸µ¤òÌÀ¤«¤¹¤³¤È¤Ê¤¯Ç¤°Õ¤Î¥Û¥¹¥È¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Ë¥µ¡¼¥Ð¤ò»È¤¦¤³¤È¤¬ + ¤Ç¤­¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¤¢¤Ê¤¿¼«¿È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤È¤Ã¤Æ¤â¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥È + Á´ÂΤˤȤäƤâ´í¸±¤Ê¤³¤È¤Ç¤¹¡£(ProxyRequests Off ¤Ë¤·¤Æ + ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ) + ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï¤¢¤Ê¤¿¤¬ÌÀ¼¨Åª¤Ë + ÀßÄꤷ¤¿¥Û¥¹¥È¤Ë¤·¤«¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¤¿¤á¡¢¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¤Î¤È¤­ + ¤Û¤É¥¢¥¯¥»¥¹À©¸æ¤ËÎϤòÃí¤¬¤Ê¤¯¤Æ¤âÂç¾æÉפǤ¹¡£

    + +
    top
    +
    +

    FTP ¥×¥í¥­¥·

    + + +

    ¤É¤¦¤·¤Æ¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤¬ xxx + ¤Î¥Õ¥¡¥¤¥ë¤ò FTP ¤Ç¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Ê¤¤¤Î?

    +

    ¤ª¤½¤é¤¯¡¢¥×¥í¥­¥·¤Î mime.types ÀßÄê¥Õ¥¡¥¤¥ë¤Ç¤½¤Î¥Õ¥¡¥¤¥ë¥¿¥¤¥×¤¬ + application/octet-stream ¤Ç¤¢¤ë¤ÈÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤Ç¤·¤ç¤¦¡£ + °Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤¬Ìò¤ËΩ¤Ä¤«¤â¤·¤ì¤Þ¤»¤ó:

    + +
    application/octet-stream   bin dms lha lzh exe class tgz taz
    +

    Ê̤ÎÊýË¡¤È¤·¤Æ¡¢¤¹¤Ù¤Æ¤Î¥Ç¥Õ¥©¥ë¥È¤ò¥Ð¥¤¥Ê¥ê¤Ë¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹:

    +
    DefaultType application/octet-stream
    + + +

    ¥Õ¥¡¥¤¥ë xxx ¤ò FTP ¤Î ASCII ¥À¥¦¥ó¥í¡¼¥É + ¤Ë¤µ¤»¤ë¤Î¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Î?

    +

    ¤Þ¤ì¤Ë¡¢(¥Ç¥Õ¥©¥ë¥È¤ÎžÁ÷¤Ï binary ¥â¡¼¥É¤Ç) ÆÃÄê¤Î + ¥Õ¥¡¥¤¥ë¤Î¤ß FTP ¤Î ASCII žÁ÷ÊýË¡¤ò»È¤ï¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤ + ¾ì¹ç¤Ë¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ÎºÇ¸å¤Ë ;type=a ¤òÉÕ¤±¤ë¤³¤È¤Ç + mod_proxy ¤Ë ASCII žÁ÷¤ò¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + (¤¿¤À¤·¡¢FTP ¤Î¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤Ï¾ï¤Ë ASCII ¥â¡¼¥É¤Ç¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£)

    + + +

    FTP ¤Î¥¢¥Ã¥×¥í¡¼¥É¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Î?

    +

    ¸½»þÅÀ¤Ç¤Ï¡¢mod_proxy ¤Î FTP ¥µ¥Ý¡¼¥È¤Ï GET ¤Î¤ß¤Ç¤¹¡£¤â¤Á¤í¤ó + Apache ¤Î ¥×¥í¥­¥·¤ò»È¤Ã¤Æ HTTP ¤Î¥¢¥Ã¥×¥í¡¼¥É (POST ¤ä PUT) ¤ò + ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤¹¡£

    + + +

    ¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î³°¤Î FTP ¥Õ¥¡¥¤¥ë¤Ë + ¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Î?

    +

    FTP URI ¤Ï¥í¥°¥¤¥ó¤·¤Æ¤¤¤ë¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¤Î + ÁêÂХѥ¹¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£»ÄÇ°¤Ê¤³¤È¤Ë¡¢/../ ¤Ï¥Ö¥é¥¦¥¶¤Ë¤è¤ê²ò¼á¤µ¤ì¡¢ + ¼ÂºÝ¤Ë FTP ¥µ¡¼¥Ð¤Ë¤ÏÁ÷¤é¤ì¤Ê¤¤¤¿¤á¡¢/../ ¤ò»È¤Ã¤Æ¾å°Ì¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë + Åþ㤹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤³¤ÎÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¡¢¤¤¤ï¤æ¤ë + Squid %2f ¥Ï¥Ã¥¯ ¤ò Apache ¤Î FTP ¥×¥í¥­¥·¤Ï¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤Ï Squid Proxy ¥­¥ã¥Ã¥·¥å ¤Î¤è¤¦¤Ê + ¾¤Î¤è¤¯»È¤ï¤ì¤Æ¤¤¤ë¥×¥í¥­¥·¥µ¡¼¥Ð¤Ç¤â¼è¤é¤ì¤Æ¤¤¤ëÊýË¡¤Ç¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¤Î¥Ñ¥¹¤ÎÀèƬ¤Ë /%2f ¤òÉÕ¤±¤ë¤³¤È¤Ç¡¢¥×¥í¥­¥·¤Ë + FTP ¤Î³«»Ï¥Ç¥£¥ì¥¯¥È¥ê¤ò (¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤ÎÂå¤ï¤ê¤Ë) / + ¤ËÊѤ¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢/etc/motd ¤ò¼èÆÀ¤¹¤ë¤¿¤á¤Ë¤Ï + ¼¡¤Î URL ¤ò»È¤¤¤Þ¤¹:

    + +

    + ftp://user@host/%2f/etc/motd +

    + + +

    ¥Ö¥é¥¦¥¶¤Î URL ɽ¼¨¤Ç FTP ¤Îʿʸ¥Ñ¥¹¥ï¡¼¥É¤ò + ±£¤¹¤Ë¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Î?

    +

    FTP ¥µ¡¼¥Ð¤Ë¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤ò»È¤Ã¤Æ¥í¥°¥¤¥ó¤¹¤ë¤¿¤á¤Ë¡¢ + Apache ¤Ï°Û¤Ê¤ëÊýË¡¤ò»È¤¤¤Þ¤¹¡£URL ¤Ë¥æ¡¼¥¶Ì¾¤È¥Ñ¥¹¥ï¡¼¥É¤¬¤Þ¤Ã¤¿¤¯ + ¤Ê¤¤¾ì¹ç¤Ï¡¢Apache ¤Ï FTP ¥µ¡¼¥Ð¤Ë anonymous ¥í¥°¥¤¥ó¤òÁ÷¤ê¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢

    + +

    + user: anonymous
    + password: apache_proxy@ +

    + +

    ¤³¤ì¤Ï anonymous ¥¢¥¯¥»¥¹¤¬ÀßÄꤵ¤ì¤¿ + ¤¹¤Ù¤Æ¤Î FTP ¥µ¡¼¥Ð¤ËÂФ·¤ÆÆ°ºî¤·¤Þ¤¹¡£

    + +

    ¥æ¡¼¥¶Ì¾¤ò»È¤Ã¤¿¸Ä¿ÍÊÌ¤Î¥í¥°¥¤¥ó¤Ë¤Ï¡¢URL ¤Ë¥æ¡¼¥¶Ì¾¤òÆþ¤ì¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹:

    + +

    + ftp://username@host/myfile +

    + +

    ¤³¤Î¥æ¡¼¥¶Ì¾¤¬Í¿¤¨¤é¤ì¤¿¤È¤­¤Ë¡¢FTP ¥µ¡¼¥Ð¤¬¥Ñ¥¹¥ï¡¼¥É¤òÍ׵᤹¤ì¤Ð + (¤â¤Á¤í¤ó¤½¤¦¤¹¤Ù¤­¤Ê¤Î¤Ç¤¹¤¬)¡¢Apache ¤Ï 401 + (Authorization required) ¤òÊÖ¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥Ö¥é¥¦¥¶¤Ï¥æ¡¼¥¶Ì¾ + ¥Ñ¥¹¥ï¡¼¥É¤ÎÆþÎÏ¥À¥¤¥¢¥í¥°¤òɽ¼¨¤·¤Þ¤¹¡£¥Ñ¥¹¥ï¡¼¥É¤¬ÆþÎϤµ¤ì¤¿¸å¡¢ + ºÆ¤ÓÀܳ¤ò»î¤ß¡¢À®¸ù¤¹¤ì¤Ð¥ê¥¯¥¨¥¹¥È¤·¤¿¥ê¥½¡¼¥¹¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£ + ¤³¤ÎÊýË¡¤ÎÍøÅÀ¤Ï¥Ö¥é¥¦¥¶¤¬¥Ñ¥¹¥ï¡¼¥É¤òʿʸ¤Çɽ¼¨¤·¤Ê¤¤¤³¤È¤Ç¤¹¡£ + (¤â¤·ºÇ½é¤«¤é

    + +

    + ftp://username:password@host/myfile +

    + +

    ¤ÈÆþÎϤ·¤¿¾ì¹ç¤Ë¤Ïɽ¼¨¤µ¤ì¤Æ¤·¤Þ¤¤¤Þ¤¹¡£)

    + +

    Ãí

    +

    Á÷¿®¤µ¤ì¤ë¥Ñ¥¹¥ï¡¼¥É¤Ï¡¢°Å¹æ²½¤µ¤ì¤ÆÁ÷¤é¤ì¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¥Ö¥é¥¦¥¶¤È Apache ¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï base64 ¤ÇÉä¹æ²½¤µ¤ì¤¿ + ʸ»úÎó¤È¤·¤Æ¡¢Apache ¥×¥í¥­¥·¤È FTP ¥µ¡¼¥Ð¤Î´Ö¤Ïʿʸ¤È¤·¤ÆÁ÷¤é¤ì¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢HTTP ¤ò»È¤Ã¤Æ HTTP ¤ò¥¢¥¯¥»¥¹¤¹¤ëÁ° (¤â¤·¤¯¤Ï¡¢¤½¤â¤½¤â + ¸Ä¿ÍŪ¤Ê¥Õ¥¡¥¤¥ë¤ò FTP ¤Ç¥¢¥¯¥»¥¹¤¹¤ëÁ°) ¤Ë¤è¤¯¹Í¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + °ÂÁ´¤Ç¤Ê¤¤ÄÌ¿®Ï©¤ò»È¤Ã¤¿¾ì¹ç¤Ï¡¢ÅðÄ°¼Ô¤ËÅÓÃæ¤Ç¥Ñ¥¹¥ï¡¼¥É¤òÅð¤Þ¤ì¤ë + ²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ÃÙ¤¤µ¯Æ°

    +

    ProxyBlock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢ + ¸å¤Î¥Æ¥¹¥È¤Î¤¿¤á¤Ëµ¯Æ°»þ¤Ë¥Û¥¹¥È¤Î + IP ¥¢¥É¥ì¥¹¤¬Ä´¤Ù¤é¤ì¤Æ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Þ¤¹¡£¥Û¥¹¥È̾¤Î¥ë¥Ã¥¯¥¢¥Ã¥×¤Î + ®¤µ¤Ë¤è¤Ã¤Æ¤Ï¡¢¿ôÉà (¤«¤½¤ì°Ê¾å) ¤«¤«¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ¥¤¥ó¥È¥é¥Í¥Ã¥È¥×¥í¥­¥·

    +

    ¥¤¥ó¥È¥é¥Í¥Ã¥È¤Ë¤¢¤ë Apache ¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï³°Éô¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò + ²ñ¼Ò¤Î¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤òÄ̤·¤ÆÁ÷¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£(¤³¤Î¤¿¤á¤Ë¤Ï + ¸Ä¡¹¤Î scheme ¤Ë¤Ä¤¤¤Æ¤½¤ì¤¾¤ì¡¢¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Î + ¥×¥í¥­¥·¤Ë¥Õ¥©¥ï¡¼¥É¤µ¤ì¤ë¤è¤¦¤Ë + ProxyRemote ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ÀßÄꤷ¤Æ¤¯¤À¤µ¤¤)¡£¤·¤«¤·¥¤¥ó¥È¥é¥Í¥Ã¥ÈÆâ¤Î¥ê¥½¡¼¥¹¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤È¤­¤Ï¡¢ + ¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤òÄ̤µ¤Ê¤¤¤Ç¤â¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹¡£ + ¤É¤Î¥Û¥¹¥È¤¬¥¤¥ó¥È¥é¥Í¥Ã¥È¤Ë°¤·¡¢Ä¾ÀÜ¥¢¥¯¥»¥¹¤¹¤Ù¤­¤«¤ò»ØÄꤹ¤ë¤Ë¤Ï¡¢ + NoProxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + Ìò¤ËΩ¤Á¤Þ¤¹¡£

    + +

    ¥¤¥ó¥È¥é¥Í¥Ã¥ÈÆâ¤Î¥æ¡¼¥¶¤Ï WWW ¤Î¥ê¥¯¥¨¥¹¥È¤Ç¥í¡¼¥«¥ë¥É¥á¥¤¥ó¤ò + ¾Êά¤¹¤ë¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£http://somehost.example.com/ + ¤È¤¤¤¦¥ê¥¯¥¨¥¹¥È¤ÎÂå¤ï¤ê¤Ë "http://somehost/" ¤ò¥ê¥¯¥¨¥¹¥È¤·¤¿¤ê¤·¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ê¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¡¢¥µ¡¼¥Ð¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¥í¡¼¥«¥ë¥É¥á¥¤¥ó¤¬ + °ÅÌۤΤ¦¤Á¤Ë»È¤ï¤ì¤Æ¤¤¤ë¤È²ò¼á¤·¤Æ¡¢Ã±½ã¤Ë¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë¤â¤Î¤â + ¾¦ÍÑ¥×¥í¥­¥·¥µ¡¼¥Ð¤ÎÃæ¤Ë¤Ï¤¢¤ê¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤¬ ¥×¥í¥­¥·¤Î¥µ¡¼¥Ó¥¹ÍѤËÀßÄꤵ¤ì¤Æ¤¤¤Æ + ProxyDomain ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + »ÈÍѤµ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢Apache ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë¥ê¥À¥¤¥ì¥¯¥È±þÅú¤òÁ÷¤Ã¤Æ¡¢ + Àµ¤·¤¤¡¢´°Á´¤Ê ((ÌõÃí: fully qualified)) + ¥µ¡¼¥Ð¤Î¥¢¥É¥ì¥¹¤ËÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ë + ¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤È¡¢¥æ¡¼¥¶¤Î¥Ö¥Ã¥¯¥Þ¡¼¥¯¤¬Àµ¤·¤¤´°Á´¤Ê¥Û¥¹¥È̾¤ò´Þ¤à + ¤³¤È¤Ë¤â¤Ê¤ë¤¿¤á¡¢¤è¤ê¹¥¤Þ¤·¤¤ÊýË¡¤È¸À¤¨¤ë¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    ¥×¥í¥È¥³¥ë¤ÎÄ´À°

    +

    Keepalive ¤ä HTTP/1.1 ¤òŬÀڤ˼ÂÁõ¤·¤Æ¤¤¤Ê¤¤¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥µ¡¼¥Ð¤¬ + ¤¢¤ë¾õ¶·¤Ç¡¢HTTP/1.0 ¤Ç keepalive ¤ò̵¤·¤Ë¤·¤Æ¥ê¥¯¥¨¥¹¥È¤òÁ÷¤ë¤¿¤á¤Î + ´Ä¶­ÊÑ¿ô¤¬Æó¤Ä¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Ï SetEnv ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£

    + +

    force-proxy-request-1.0 ¤È proxy-nokeepalive + ¤¬¤½¤Î´Ä¶­ÊÑ¿ô¤Ç¤¹¡£

    + +

    + <Location /buggyappserver/>
    + + ProxyPass http://buggyappserver:7001/foo/
    + SetEnv force-proxy-request-1.0 1
    + SetEnv proxy-nokeepalive 1
    +
    + </Location> +

    +
    +
    top
    +

    AllowCONNECT ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤ò·Ðͳ¤·¤Æ¡¢¤É¤Î¥Ý¡¼¥È¤Ë CONNECT +¤Ç¤­¤ë¤«¤ò»ØÄꤹ¤ë
    ¹½Ê¸:AllowCONNECT port [port] ...
    ¥Ç¥Õ¥©¥ë¥È:AllowCONNECT 443 563
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    AllowCONNECT ¤Ï¥×¥í¥­¥·¤Î CONNECT + ¥á¥½¥Ã¥É¤¬Àܳ¤òµö²Ä¤¹¤ë¥Ý¡¼¥ÈÈÖ¹æ¤Î¥ê¥¹¥È¤ò»ØÄꤷ¤Þ¤¹¡£ + º£Æü¤Î¥Ö¥é¥¦¥¶¤Ï¡¢https ¥³¥Í¥¯¥·¥ç¥ó¤¬Í׵ᤵ¤ì¤Æ¤¤¤Æ¡¢ + HTTP ¾å¤Ç¤Î¥×¥í¥­¥·¤Ë¤è¤ë¥È¥ó¥Í¥ê¥ó¥°¤¬¤Ç¤­¤ë¤È¤­¤Ë¡¢ + ¤³¤Î¥á¥½¥Ã¥É¤ò»È¤¤¤Þ¤¹¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤Ç¤Ï¡¢https ¤Î¥Ç¥Õ¥©¥ë¥È¥Ý¡¼¥È (443) ¤È + ¥Ç¥Õ¥©¥ë¥È¤Î snews ¥Ý¡¼¥È (563) ¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥Ç¥Õ¥©¥ë¥È¤ò¾å½ñ¤­¤·¤Æ¡¢¥ê¥¹¥È¤Ëµ­ºÜ¤·¤¿¥Ý¡¼¥È¤Ë¤Î¤ßÀܳ¤òµö²Ä¤·¤¿¤¤¾ì¹ç¡¢ + AllowCONNECT ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Þ¤¹¡£

    + +

    CONNECT ¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢mod_proxy_connect + ¤¬¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    top
    +

    NoProxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:ľÀÜÀܳ¤¹¤ë ¥Û¥¹¥È¡¢¥É¥á¥¤¥ó¡¢¥Í¥Ã¥È¥ï¡¼¥¯
    ¹½Ê¸:NoProxy host [host] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¤¥ó¥È¥é¥Í¥Ã¥ÈÃæ¤Î Apache ¥×¥í¥­¥·¥µ¡¼¥Ð¤Ë¤Î¤ß + Í­ÍѤǤ¹¡£NoProxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¶õÇò¶èÀÚ¤ê¤Ç¡¢ + ¥µ¥Ö¥Í¥Ã¥È¡¢IP ¥¢¥É¥ì¥¹¡¢¥Û¥¹¥È¡¢¥É¥á¥¤¥ó¤Î¥ê¥¹¥È¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤ì¤é¤Î¤É¤ì¤«¤Ë¥Þ¥Ã¥Á¤¹¤ë¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï ProxyRemote ¤ÇÀßÄꤵ¤ì¤¿¥×¥í¥­¥·¥µ¡¼¥Ð¤Ë + ¥Õ¥©¥ï¡¼¥É¤µ¤ì¤º¡¢Ä¾ÀܽèÍý¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21 +

    + +

    NoProxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î host °ú¿ô¤Ï + °Ê²¼¤Î¼ïÎà¤Î¤É¤ì¤«¤Ç¤¹:

    + +
    + +
    Domain
    +
    +

    Domain ¤ÏÀèƬ¤Ë¥Ô¥ê¥ª¥É¤ÎÃ夤¤¿Éôʬ DNS ¥É¥á¥¤¥ó̾¤Ç¤¹¡£ + Ʊ°ì DNS ¥É¥á¥¤¥óµÚ¤Ó¥¾¡¼¥ó (¤¹¤Ê¤ï¤Á¡¢¥Û¥¹¥È̾¤ÎËöÈø¤¬¤¹¤Ù¤Æ + Domain ¤Ç½ª¤ï¤Ã¤Æ¤¤¤ë¤È¤¤¤¦¤³¤È) ¤Ë°¤¹¤ë¥Û¥¹¥È¤Î¥ê¥¹¥È¤ò + ɽ¤·¤Þ¤¹)¡£

    + +

    Îã

    + .com .apache.org. +

    + +

    Domain ¤ò Hostname ¤È¶èÊ̤¹¤ë¤¿¤á¤Ë (°Ọ̃Ū¤Ë¤â¹½Ê¸Åª¤Ë¤â¡£DNS ¥É¥á¥¤¥ó¤â + DNS ¤Î A ¥ì¥³¡¼¥É¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¤Î¤Ç¤¹!)¡¢Domain ¤Ï + ¾ï¤Ë¥Ô¥ê¥ª¥É¤Ç»Ï¤Þ¤ê¤Þ¤¹¡£

    + +

    Ãí

    +

    ¥É¥á¥¤¥ó̾¤ÎÈæ³Ó¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë¹Ô¤Ê¤ï¤ì¡¢Domain + ¤Ï¾ï¤Ë DNS ¥Ä¥ê¡¼¤Î¥ë¡¼¥È¤«¤é»Ï¤Þ¤ë¤â¤Î¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ + ¼¡¤ÎÆó¤Ä¤Î¥É¥á¥¤¥ó .MyDomain.com ¤È + .mydomain.com. (ºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ËÃíÌÜ) ¤ÏƱ°ì¤Ç¤¢¤ë¤È + ¤ß¤Ê¤µ¤ì¤Þ¤¹¡£¥É¥á¥¤¥ó¤ÎÈæ³Ó¤Ï DNS ¥ë¥Ã¥¯¥¢¥Ã¥×¤Ê¤·¤Ç¹Ô¤Ê¤ï¤ì¤ë¤¿¤á¡¢ + ¥µ¥Ö¥Í¥Ã¥È¤ÎÈæ³Ó¤è¤ê¤â¤º¤Ã¤È¸úΨŪ¤Ç¤¹¡£

    +
    + + +
    SubNet
    +
    +

    SubNet ¤Ï¿ôÃÍ·Á¼° (¥É¥Ã¥È¤Ç¶èÀÚ¤é¤ì¤¿»Í¤Ä¤Î¿ô»ú) ¤Î + Éôʬ¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥¢¥É¥ì¥¹¤Ç¤¹¡£¸å¤Ë¥¹¥é¥Ã¥·¥å¤È Subnet + ¤Î°ÕÌ£¤Î¤¢¤ë¥Ó¥Ã¥È¿ô¤ò»ØÄꤹ¤ë¥Í¥Ã¥È¥Þ¥¹¥¯¤È¤ò³¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¶¦Ä̤Υͥåȥ¥¯¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò»È¤Ã¤ÆÅþ㤹¤ë¤³¤È¤Î¤Ç¤­¤ë¥µ¥Ö¥Í¥Ã¥È¤ò + ɽ¤¹¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ÌÀ¼¨Åª¤Ë¥Í¥Ã¥È¥Þ¥¹¥¯¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ï + ºÇ¸å¤Î¾Êά¤µ¤ì¤¿ (¤â¤·¤¯¤ÏÃͤ¬ 0 ¤Î) ¿ô»ú¤¬¥Þ¥¹¥¯¤ò»ØÄꤷ¤Þ¤¹¡£ + (¤³¤Î¾ì¹ç¤Ï¡¢¥Í¥Ã¥È¥Þ¥¹¥¯¤Ï 8 ¥Ó¥Ã¥Èñ°Ì¤Ç¤·¤«»ØÄê¤Ç¤­¤Þ¤»¤ó¡£) + Îã:

    + +
    +
    192.168 ¤â¤·¤¯¤Ï 192.168.0.0
    +
    ¥µ¥Ö¥Í¥Ã¥È 192.168.0.0 ¤È°ÅÌۤΠ16 ¥Ó¥Ã¥ÈÍ­¸ú¤Ê¥Í¥Ã¥È¥Þ¥¹¥¯ + (255.255.0.0 ¤È¤¤¤¦¥Í¥Ã¥È¥Þ¥¹¥¯¤Î·Á¼°¤Ç»È¤ï¤ì¤ë¤³¤È¤â + ¤¢¤ê¤Þ¤¹)
    +
    192.168.112.0/21
    +
    ¥µ¥Ö¥Í¥Ã¥È192.168.112.0/21 ¤È 21 ¥Ó¥Ã¥ÈÍ­¸ú¤Ê + ¥Í¥Ã¥È¥Þ¥¹¥¯ (255.255.248.0 ¤È¤¤¤¦·Á¼°¤Ç»È¤ï¤ì¤ë¤³¤È¤â + ¤¢¤ê¤Þ¤¹)
    +
    + +

    ÆÃÊ̤ʾì¹ç¤Ë¡¢32 ¥Ó¥Ã¥ÈÍ­¸ú¤Ê SubNet ¤Ï + IPAddr ¤ÈƱÅù¤Ç¡¢ + 0 ¥Ó¥Ã¥ÈÍ­¸ú¤Ê SubNet (Î㤨¤Ð¡¢0.0.0.0/0) ¤Ï + ¤¹¤Ù¤Æ¤Î IP ¥¢¥É¥ì¥¹¤Ë¥Þ¥Ã¥Á¤¹¤ëÄê¿ô _Default_ ¤ÈƱ¤¸¤Ç¤¹¡£

    +
    + + +
    IPAddr
    +
    +

    IPAddr ¤Ï¿ôÃÍ·Á¼° (¥É¥Ã¥È¤Ç¶èÀÚ¤é¤ì¤¿»Í¤Ä¤Î¿ô»ú) ¤Î + ´°Á´¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥¢¥É¥ì¥¹¤Ç¤¹¡£Ä̾ï¤Ï¤³¤Î¥¢¥É¥ì¥¹¤Ï¥Û¥¹¥È¤ò + ɽ¤·¤Þ¤¹¤¬¡¢É¬¤º¤·¤â¥¢¥É¥ì¥¹¤ËÂбþ¤¹¤ë DNS ¥É¥á¥¤¥ó̾¤¬¤¢¤ë¤ï¤±¤Ç¤Ï + ¤¢¤ê¤Þ¤»¤ó¡£

    + +

    Îã

    + 192.168.123.7 +

    + +

    Ãí

    +

    IPAddr ¤Ï DNS ¥·¥¹¥Æ¥à¤Ë¤è¤ê²ò·è¤µ¤ì¤ëɬÍפ¬¤Ê¤¤¤Î¤Ç¡¢ + apache ¤ÎÀ­Ç½¤¬¸þ¾å¤¹¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    +
    + + +
    Hostname
    +
    +

    Hostname ¤Ï DNS ¥É¥á¥¤¥ó¥µ¡¼¥Ó¥¹¤Ë¤è¤ê°ì¤Ä¤â¤·¤¯¤Ï + Ê£¿ô¤Î IPAddr ¤Ë²ò·è²Äǽ¤Ê + ´°Á´¤Ê DNS ¥É¥á¥¤¥ó̾¤Ç¤¹¡£¤³¤ì¤Ï (Domain + ¤È°ã¤Ã¤Æ¡¢ÀâÌÀ¤Ï¾åµ­¤ò»²¾È) ÏÀÍýŪ¤Ê¥Û¥¹¥È¤òɽ¤·¡¢¾¯¤¯¤È¤â°ì¤Ä¤Î + IPAddr (¤â¤·¤¯¤Ï°ã¤¦ + IPAddr ¤Î¥Û¥¹¥È¤Î¥ê¥¹¥È) ¤Ë²ò·è + ¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)¡£

    + +

    Îã

    + prep.ai.mit.edu
    + www.apache.org +

    + +

    Ãí

    +

    ¿¤¯¤Î¾ì¹ç¡¢Hostname ¤ÎÂå¤ï¤ê¤Ë IPAddr ¤ò»ØÄꤷ¤¿Êý¤¬¡¢DNS ¥ë¥Ã¥¯¥¢¥Ã¥×¤ò + Èò¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¤¿¤á¡¢¸úΨ¤¬Îɤ¯¤Ê¤ê¤Þ¤¹¡£Apache ¤Î̾Á°²ò·è¤Ï + ¥Í¡¼¥à¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤¬ÃÙ¤¤ PPP ¾å¤Î¾ì¹ç¤Ê¤É¤Ë¤«¤Ê¤ê»þ´Ö¤ò¼è¤é¤ì¤ë + ¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£

    +

    Hostname ¤ÎÈæ³Ó¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë¹Ô¤Ê¤ï¤ì¡¢ + Hostname ¤Ï¾ï¤Ë DNS ¥Ä¥ê¡¼¤Î¥ë¡¼¥È¤«¤é»Ï¤Þ¤ë¤â¤Î¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢Æó¤Ä¤Î¥É¥á¥¤¥ó WWW.MyDomain.com ¤È + www.mydomain.com. (ºÇ¸å¤Î¥Ô¥ê¥ª¥É¤ËÃíÌÜ) ¤ÏƱ°ì¤Ç¤¢¤ë¤È + ¤ß¤Ê¤µ¤ì¤Þ¤¹¡£

    +
    +
    + +

    »²¾È

    + +
    +
    top
    +

    <Proxy> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤ë¥ê¥½¡¼¥¹¤ËŬÍѤµ¤ì¤ë¥³¥ó¥Æ¥Ê
    ¹½Ê¸:<Proxy wildcard-url> ...</Proxy>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    <Proxy> ¥»¥¯¥·¥ç¥óÃæ¤Î + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Þ¥Ã¥Á¤¹¤ë¥×¥í¥­¥·¤µ¤ì¤ë¥³¥ó¥Æ¥ó¥Ä¤Ë¤Î¤ßŬÍѤµ¤ì¤Þ¤¹¡£ + ¥·¥§¥ë·Á¼°¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¤¬»È¤¨¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢¼¡¤ÎÀßÄê¤Ï yournetwork.example.com ¤Î + ¥Û¥¹¥È¤Ë¤Î¤ß¥×¥í¥­¥·¥µ¡¼¥Ð¤ò·Ðͳ¤·¤¿¥¢¥¯¥»¥¹¤òµö²Ä¤·¤Þ¤¹:

    + +

    + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from yournetwork.example.com
    +
    + </Proxy> +

    + +

    ¼¡¤ÎÎã¤Ï example.com ¤Î foo ¥Ç¥£¥ì¥¯¥È¥ê¤Î + ¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ¡¢¥×¥í¥­¥·¥µ¡¼¥Ð¤òÄ̤·¤ÆÁ÷¤é¤ì¤¿¤È¤­¤Ë¤Ï + INCLUDES ¥Õ¥£¥ë¥¿¤òÄ̤·¤ÆÁ÷¤ë¤è¤¦¤ËÀßÄꤷ¤Þ¤¹:

    + +

    + <Proxy http://example.com/foo/*>
    + + SetOutputFilter INCLUDES
    +
    + </Proxy> +

    + + + +
    +
    top
    +

    ProxyBadHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:±þÅú¤Ë¤ª¤«¤·¤Ê¥Ø¥Ã¥À¤¬¤¢¤ë¾ì¹ç¤Î°·¤¤Êý¤ò·è¤á¤ë
    ¹½Ê¸:ProxyBadHeader IsError|Ignore|StartBody
    ¥Ç¥Õ¥©¥ë¥È:ProxyBadHeader IsError
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    ¸ß´¹À­:2.0.44 °Ê¹ß
    +

    ProxyBadHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¹½Ê¸Åª¤Ë + ´Ö°ã¤Ã¤¿¥Ø¥Ã¥À (¤Ä¤Þ¤ê ¥³¥í¥ó¤ò´Þ¤Þ¤Ê¤¤¤â¤Î) ¤ò¼õ¤±¼è¤Ã¤¿¤È¤­¤Ë + mod_proxy ¤¬¤É¤¦¿¶¤ëÉñ¤¦¤«¤ò·è¤á¤Þ¤¹¡£°Ê²¼¤Î°ú¿ô¤ò + ¼è¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +
    +
    IsError
    +
    ¥ê¥¯¥¨¥¹¥È¤òÃæ»ß¤·¤Æ 502 (Bad Gateway) ±þÅú¤òÊÖ¤¹¡£ + ¤³¤ì¤¬¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ç¤¹¡£
    + +
    Ignore
    +
    ´Ö°ã¤Ã¤¿¥Ø¥Ã¥À¹Ô¤ò¤½¤â¤½¤â¸ºß¤·¤Ê¤«¤Ã¤¿¤â¤Î¤È¤·¤Æ°·¤¦¡£
    + +
    StartBody
    +
    ´Ö°ã¤Ã¤¿¥Ø¥Ã¥À¹Ô¤ò¼õ¤±¼è¤Ã¤¿¤é¡¢¥Ø¥Ã¥À¤ÎÆɤ߹þ¤ß¤ò½ªÎ»¤·¤Æ¡¢ + ¤½¤ì°Ê¹ß¤Î»Ä¤ê¤ò¥Ü¥Ç¥£¤È¤·¤Æ°·¤¦¡£¤³¤ì¤Ï¥Ø¥Ã¥À¤È¥Ü¥Ç¥£¤Î´Ö¤Ë¶õ¹Ô¤òÆþ¤ì˺¤ì¤Æ + ¤·¤Þ¤Ã¤Æ¤¤¤ë¤è¤¦¤Ê¡¢¤­¤Á¤ó¤ÈÆ°ºî¤·¤Æ¤¤¤Ê¤¤¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤¬¤¢¤ë¤È¤­¤Ë¡¢ + ÌäÂê¤ò²óÈò¤¹¤ë¤Î¤ËÌò¤ËΩ¤Á¤Þ¤¹¡£
    +
    + +
    +
    top
    +

    ProxyBlock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·Àܳ¤ò¶Ø»ß¤¹¤ë¸ì¶ç¡¢¥Û¥¹¥È̾¡¢¥É¥á¥¤¥ó¤ò»ØÄꤹ¤ë
    ¹½Ê¸:ProxyBlock *|word|host|domain +[word|host|domain] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ProxyBlock ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¶õÇò¤Ç¶èÀÚ¤é¤ì¤¿ + ¸ì¶ç¡¢¥Û¥¹¥È̾¡¢¥É¥á¥¤¥ó¤Î¥ê¥¹¥È¤ò»ØÄꤷ¤Þ¤¹¡£¥µ¥¤¥È̾¤Ë¤½¤Î¸ì¶ç¡¢¥Û¥¹¥È̾¡¢ + ¥É¥á¥¤¥ó¤ò´Þ¤à¥µ¥¤¥È¤Ø¤Î HTTP¡¢HTTPS¡¢FTP ¤Ë¤è¤ë¥É¥­¥å¥á¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤Ï + ¥×¥í¥­¥·¥µ¡¼¥Ð¤Ë¤è¤ê¥Ö¥í¥Ã¥¯¤µ¤ì¤Þ¤¹¡£¥×¥í¥­¥·¥â¥¸¥å¡¼¥ë¤Ï + µ¯Æ°»þ¤Ë¥Û¥¹¥È̾¤È»×¤·¤­¹àÌܤΠIP ¥¢¥É¥ì¥¹¤òÄ´¤Ù¡¢¸å¤Î¥Æ¥¹¥È¤Î¤¿¤á¤Ë + ¥­¥ã¥Ã¥·¥å¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¥µ¡¼¥Ð¤Îµ¯Æ°¤¬¾¯¤·ÃÙ¤¯¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    Example

    + ProxyBlock joes-garage.com some-host.co.uk rocky.wotsamattau.edu +

    + +

    rocky.wotsamattau.edu ¤¬ IP ¥¢¥É¥ì¥¹¤Ç»²¾È¤µ¤ì¤¿¤È¤­¤Ç¤â + ¥Þ¥Ã¥Á¤·¤Þ¤¹¡£

    + +

    wotsamattau.edu ¤Î¥Þ¥Ã¥Á¤Ë¤Ï wotsamattau + ¤À¤±¤Ç¤â½½Ê¬¤Ç¤¹¡£

    + +

    + ProxyBlock * +

    + +

    ¤Ï¤¹¤Ù¤Æ¤Î¥µ¥¤¥È¤Ø¤ÎÀܳ¤ò¥Ö¥í¥Ã¥¯¤¹¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    top
    +

    ProxyDomain ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¥Ç¥Õ¥©¥ë¥È¤Î¥É¥á¥¤¥ó̾
    ¹½Ê¸:ProxyDomain Domain
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¤¥ó¥È¥é¥Í¥Ã¥ÈÆâ¤Î Apache ¥×¥í¥­¥·¥µ¡¼¥Ð¤Ë¤Î¤ß + Í­ÍѤǤ¹¡£ProxyDomain ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + apache ¥×¥í¥­¥·¥µ¡¼¥Ð¤¬Â°¤¹¤ë¥Ç¥Õ¥©¥ë¥È¤Î¥É¥á¥¤¥ó¤ò»ØÄꤷ¤Þ¤¹¡£ + ¥É¥á¥¤¥ó̾¤Î̵¤¤¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¤¿¾ì¹ç¡¢ÀßÄꤵ¤ì¤¿ Domain + ¤¬Äɲ䵤줿Ʊ¤¸¥Û¥¹¥È¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È±þÅú¤¬ÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    Îã

    + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21
    + ProxyDomain .mycompany.com +

    + +
    +
    top
    +

    ProxyErrorOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥¨¥é¡¼¥Ú¡¼¥¸¤ò¾å½ñ¤­¤¹¤ë
    ¹½Ê¸:ProxyErrorOverride On|Off
    ¥Ç¥Õ¥©¥ë¥È:ProxyErrorOverride Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.0 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ò»ÈÍѤ·¤Æ¤¤¤Æ¡¢ + ¥¨¥ó¥É¥æ¡¼¥¶¤ËÁ÷¤é¤ì¤ë¥¨¥é¡¼¥Ú¡¼¥¸¤Î³°¸«¤ò¶¦Ä̤Τâ¤Î¤Ë¤·¤¿¤¤¤È¤­¤Ë + Í­ÍѤǤ¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï (mod_include ¤Î SSI ¤Ë¤è¤Ã¤Æ) + ¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤¬¥¨¥é¡¼¥³¡¼¥É¤ò¼èÆÀ¤·¤Æ¡¢Àµ¤·¤¯Æ°ºî¤ò + ¤¹¤ë¤è¤¦¤Ë¤â¤·¤Þ¤¹ (¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ï¡¢¥×¥í¥­¥·¤µ¤ì¤¿¥µ¡¼¥Ð¤Î + ¥¨¥é¡¼¥Ú¡¼¥¸¤Îɽ¼¨¤Ç¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÍ­¸ú¤Ë¤¹¤ë¤È SSI ¤Î¥¨¥é¡¼ + ¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Þ¤¹)¡£

    + +
    +
    top
    +

    ProxyIOBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ÆâÉô¥Ç¡¼¥¿¥¹¥ë¡¼¥×¥Ã¥È¥Ð¥Ã¥Õ¥¡¤Î¥µ¥¤¥º¤ò·èÄꤹ¤ë
    ¹½Ê¸:ProxyIOBufferSize bytes
    ¥Ç¥Õ¥©¥ë¥È:ProxyIOBufferSize 8192
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ProxyIOBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÆþÎÏ¤È + ½ÐÎÏÍѤΰì»þ¥á¥â¥ê¤È¤·¤Æ»È¤ï¤ì¤ëÆâÉô¥Ð¥Ã¥Õ¥¡¤Î¥µ¥¤¥º¤òÄ´À°¤·¤Þ¤¹¡£ + ¥µ¥¤¥º¤Ï 8192 °Ê²¼¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¤Û¤È¤ó¤É¤¹¤Ù¤Æ¤Î¾ì¹ç¡¢¤³¤ÎÃͤòÊѹ¹¤¹¤ëÍýͳ¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +
    +
    top
    +

    <ProxyMatch> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Àµµ¬É½¸½¤Ç¤Î¥Þ¥Ã¥Á¤Ë¤è¤ë¥×¥í¥­¥·¥ê¥½¡¼¥¹ÍѤΥǥ£¥ì¥¯¥Æ¥£¥Ö¥³¥ó¥Æ¥Ê
    ¹½Ê¸:<ProxyMatch regex> ...</ProxyMatch>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    <ProxyMatch> ¤Ï URL ¤Î¥Þ¥Ã¥Á¤Ë + Àµµ¬É½¸½¤òÍѤ¤¤ë¤³¤È¤ò½ü¤¤¤Æ <Proxy> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱ¤¸¤Ç¤¹¡£

    + +
    +
    top
    +

    ProxyMaxForwards ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤¬¥Õ¥©¥ï¡¼¥É¤µ¤ì¤ë¥×¥í¥­¥·¤ÎºÇÂç¿ô
    ¹½Ê¸:ProxyMaxForwards number
    ¥Ç¥Õ¥©¥ë¥È:ProxyMaxForwards 10
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    ¸ß´¹À­:Apache 2.0 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ProxyMaxForwards ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥ê¥¯¥¨¥¹¥È¤Ë Max-Forwards ¥Ø¥Ã¥À¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë + ¥ê¥¯¥¨¥¹¥È¤¬Ä̲á²Äǽ¤Ê¥×¥í¥­¥·¤ÎºÇÂç¿ô¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï + ¥×¥í¥­¥·¤Î̵¸Â¥ë¡¼¥×¤ä DoS ¹¶·â¤òËɤ°¤¿¤á¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    Îã

    + ProxyMaxForwards 15 +

    + +
    +
    top
    +

    ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ò¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î URL ¶õ´Ö¤Ë¥Þ¥Ã¥×¤¹¤ë
    ¹½Ê¸:ProxyPass [path] !|url [key=value key=value ...]]
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ò¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î̾Á°¶õ´Ö¤Ë + ¥Þ¥Ã¥×¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£¥í¡¼¥«¥ë¥µ¡¼¥Ð¤ÏÄ̾ï¤Î°ÕÌ£¤Ç¤Î¥×¥í¥­¥·¤È + ¤·¤Æ¤ÏÆ°ºî¤»¤º¡¢¥ê¥â¡¼¥È¥µ¡¼¥Ð¤Î¥ß¥é¡¼¤È¤·¤Æ¿¶¤ëÉñ¤¤¤Þ¤¹¡£ + path ¤Ï¥í¡¼¥«¥ë¤Î²¾Áۥѥ¹¤Î̾Á°¤Ç¤¹¡£url ¤Ï + ¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ÎÉôʬ URL ¤Ë¤Ê¤ê¡¢¥¯¥¨¥ê¡¼Ê¸»úÎó¤ò´Þ¤à¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£

    + +
    ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤Ã¤Æ¤¤¤ë¤È¤­¤Ï ProxyRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÄ̾ï¤Ï + off ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤Ù¤­¤Ç¤¹¡£
    + +

    ¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î¥¢¥É¥ì¥¹¤¬ http://example.com/ ¤Ç¤¢¤ë¤È + ¤·¤Þ¤¹¡£¤¹¤ë¤È¡¢

    + +

    + ProxyPass /mirror/foo/ http://backend.example.com/ +

    + +

    ¤ÈÀßÄꤹ¤ë¤È http://example.com/mirror/foo/bar ¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤¬ÆâÉôŪ¤Ë http://backend.example.com/bar ¤Ø¤Î + ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤ËÊÑ´¹¤µ¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤·¤¿¤¯¤Ê¤¤¤È¤­¤Ë ! ¤Ï + Ìò¤ËΩ¤Á¤Þ¤¹¡£Î㤨¤Ð¡¢

    + +

    + ProxyPass /mirror/foo/i !
    + ProxyPass /mirror/foo http://backend.example.com +

    + +

    ¤Ï /mirror/foo/i ¤ò½ü¤¯ + /mirror/foo ¤Ø¤Î¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ò + backend.example.com ¤Ë¥×¥í¥­¥·¤·¤Þ¤¹¡£

    + +

    Ãí

    +

    ½çÈ֤ϽÅÍפǤ¹¡£°ìÈÌŪ¤Ê ProxyPass + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÁ°¤Ë + ½ü³°¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÃÖ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    +
    + +

    2.1 ¤Î¿·µ¡Ç½¤Ç¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤ÎÀܳ¤Ë¥×¡¼¥ë¤µ¤ì¤¿¥³¥Í¥¯¥·¥ç¥ó¤ò + »È¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£key=value ·Á¼°¤Î¥Ñ¥é¥á¡¼¥¿¤Ç + ¤³¤Î¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ê¥ó¥°¤ÎÄ´À°¤¬¤Ç¤­¤Þ¤¹¡£Hard Maximum + ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë MPM ¤Ç¤Î¥×¥í¥»¥¹Åö¤¿¤ê¤Î¥¹¥ì¥Ã¥É¿ô¤È + Ʊ¤¸¿ô¤Î¥³¥Í¥¯¥·¥ç¥ó¿ô¤Ç¤¹¡£prefork MPM ¤Ç¤ÏÄ̾ï¤Ï 1 ¤Ç¡¢worker MPM ¤Ç¤Ï + ThreadsPerChild ¤ÇÄ´À°¤µ¤ì¤Þ¤¹¡£

    + +

    min ¤ÎÀßÄê¤Ç¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤Î´Ö¤Ë²¿ËܤΥ³¥Í¥¯¥·¥ç¥ó¤ò + ¾ï»þ³«¤¯¤«¤¬·è¤Þ¤ê¤Þ¤¹¡£Soft Maximum smax ¤Î¿ô¤Ë + 㤹¤ë¤Þ¤ÇɬÍפ˱þ¤¸¤Æ¥³¥Í¥¯¥·¥ç¥ó¤ÏÀ¸À®¤µ¤ì¤Þ¤¹¡£smax + ¤òĶ¤¨¤¿¿ô¤Î¥³¥Í¥¯¥·¥ç¥ó¤Ï¡¢À¸Â¸»þ´Ö ttl ¤ÇÀÚÃǤµ¤ì¤Þ¤¹¡£ + ¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È Hard Maximum max ¤Î¿ô°Ê¾å¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò + À¸À®¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    + ProxyPass /example http://backend.example.com smax=5 max=20 ttl=120 retry=300 +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥Ñ¥é¥á¡¼¥¿¥Ç¥Õ¥©¥ë¥ÈÃÍÀâÌÀ
    min0¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤ÎÀܳ¤Ç + ¾ï¤Ë³«¤¤¤Æ¤¤¤ë¥³¥Í¥¯¥·¥ç¥ó¿ô¤ÎºÇ¾®ÃÍ
    max1...n¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤ÎÀܳ¿ô¤Î Hard Maximum + (ÌõÃí: ¥Ï¡¼¥É¥ê¥ß¥Ã¥È)¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢»ÈÍѤ·¤Æ¤¤¤ë MPM ¤Î¥×¥í¥»¥¹¤¢¤¿¤ê¤Î¥¹¥ì¥Ã¥É¿ô¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + Prefork MPM ¤Ç¤Ï¾ï¤Ë 1 ¤Ç¡¢Worker MPM ¤Ç¤Ï ThreadsPerChild + ¤ÇÄ´Àá¤Ç¤­¤Þ¤¹¡£Hard Maximum °Ê¾å¤Ë¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò + À¸À®¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
    smaxmaxÀܳ¿ô¤Î Soft Maximum (ÌõÃí: ¥½¥Õ¥È¥ê¥ß¥Ã¥È)¤Þ¤Ç¡¢ + ¥³¥Í¥¯¥·¥ç¥ó¤ÏɬÍפ˱þ¤¸¤ÆÀ¸À®¤µ¤ì¤Þ¤¹¡£ + smax ¤òĶ¤¨¤¿¿ô¤Î¥³¥Í¥¯¥·¥ç¥ó¤ÏÀ¸Â¸»þ´Ö ttl + ¤ÇÀÚÃǤµ¤ì¤Þ¤¹¡£ +
    ttl-smax ¿ô¤òĶ¤¨¤¿Èó³èÆ°¾õÂ֤Υ³¥Í¥¯¥·¥ç¥ó¤ÎÀ¸Â¸»þ´Ö¤ò¡¢ + ÉäǻØÄꤷ¤Þ¤¹¡£¤³¤Î´ü´ÖÆâ¤Ë»ÈÍѤµ¤ì¤Ê¤«¤Ã¤¿¥³¥Í¥¯¥·¥ç¥ó¤Ï¡¢ + Á´¤ÆÊĤ¸¤é¤ì¤Þ¤¹¡£ +
    timeoutTimeout¥³¥Í¥¯¥·¥ç¥ó¥¿¥¤¥à¥¢¥¦¥È¤òÉäǻØÄꤷ¤Þ¤¹¡£Æä˻ØÄꤵ¤ì¤Ê¤±¤ì¤Ð¡¢ + ¥Õ¥ê¡¼¤Ê¥³¥Í¥¯¥·¥ç¥ó¤ò¼èÆÀ¤Ç¤­¤ë¤Þ¤ÇÂÔ¤Á¤Þ¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + max ¥Ñ¥é¥á¡¼¥¿¤È¹ç¤ï¤»¤Æ»È¤¦¤³¤È¤Ç¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¤Î + Àܳ¿ô¤òÀ©¸æ¤¹¤ë¤Î¤Ë»È¤¤¤Þ¤¹¡£ +
    acquire-ÀßÄꤹ¤ë¤È¡¢¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¤«¤é¥Õ¥ê¡¼¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¼èÆÀ¤¹¤ë¤¿¤á¤Ë + ÂÔµ¡¤¹¤ëÂÔ¤Á»þ´Ö¤ÎºÇÂçÃͤˤʤê¤Þ¤¹¡£¥Õ¥ê¡¼¤Î¥³¥Í¥¯¥·¥ç¥ó¤¬¥×¡¼¥ë¤Ë¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ + SERVER_BUSY ¥¹¥Æ¡¼¥¿¥¹¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¤Þ¤¹¡£ +
    keepaliveOff¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È Apache ¤Î´Ö¤Ë¥Õ¥¡¥¤¥¢¡¼¥¦¥©¡¼¥ë¤¬¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢ + ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Ï±ý¡¹¤Ë¤·¤Æ¡¢ + Èó³èÆ°¾õÂ֤Υ³¥Í¥¯¥·¥ç¥ó¤òÍî¤È¤½¤¦¤È¤·¤Þ¤¹¡£ + ¤³¤Î¥Õ¥é¥°¤Ï OS ¤Ë»Ø¼¨¤·¤Æ¡¢KEEP_ALIVE ¥á¥Ã¥»¡¼¥¸¤òÈó³èÆ°¾õÂ֤Π+ ¥³¥Í¥¯¥·¥ç¥ó¤Ç¤âÁ÷¤ë¤è¤¦¤Ë¤·¤Þ¤¹ (´Ö³Ö¤Ï OS ¤Î¥°¥í¡¼¥Ð¥ëÀßÄê¤Ë°Í¸¤·¡¢ + Ä̾ï¤Ï 120ms ´Ö³Ö) ¡£¤³¤ì¤Ë¤è¤Ã¤Æ¥Õ¥¡¥¤¥¢¥¦¥©¡¼¥ë¤Ë¤è¤Ã¤Æ¥³¥Í¥¯¥·¥ç¥ó¤¬ + Íî¤È¤µ¤ì¤ë¤³¤È¤òËɤ²¤Þ¤¹¡£keepalive ¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ò + On ¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    retry60¥³¥Í¥¯¥·¥ç¥ó¤ò¥×¡¼¥ê¥ó¥°¤¹¤ë¤¿¤á¤Î¡¢¥ê¥È¥é¥¤¤Î¥¿¥¤¥à¥¢¥¦¥È¤òÉÃ¤Ç + »ØÄꤷ¤Þ¤¹¡£¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ê¥ó¥°¤¬¼ºÇÔ¤·¤¿¾ì¹ç¤Ï¡¢ + ¥¿¥¤¥à¥¢¥¦¥È¤Î´ü´Ö¤¬²á¤®¤ë¤Þ¤Ç¡¢¤½¤Î¥µ¡¼¥Ð¤Ë¥ê¥¯¥¨¥¹¥È¤ò¥Õ¥©¥ï¡¼¥É¤·¤Þ¤»¤ó¡£ + ¤³¤Îµ¡Ç½¤ò»È¤¦¤È¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤ò¥á¥ó¥Æ¥Ê¥ó¥¹¤Î¤¿¤á¤Ë¥·¥ã¥Ã¥È¥À¥¦¥ó¤·¡¢ + ¸å¤Ç¥ª¥ó¥é¥¤¥ó¤ËÉüµ¢¤µ¤»¤ë¤È¤¤¤Ã¤¿¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +
    loadfactor1¥ï¡¼¥«¡¼¤¢¤¿¤ê¤ÎÉé²Ù·¸¿ô¤Ç¤¹¡£BalancerMember ¤Ç»È¤¤¤Þ¤¹¡£ + 1 ¤«¤é 100 ¤Þ¤Ç¤Î¿ô»ú¤Ç¤½¤Î¥ï¡¼¥«¡¼¤ËÂФ¹¤ëÀµµ¬²½¤µ¤ì¤¿Éé²ÙΨ¤ò»ØÄꤷ¤Þ¤¹¡£ +
    route-¥í¡¼¥É¥Ð¥é¥ó¥µ¤Ç»È¤Ã¤¿¾ì¹ç¡¢¥ï¡¼¥«¡¼¤Î¥ë¡¼¥Æ¥£¥ó¥°¤ò¤·¤Þ¤¹¡£ + ¥ë¡¼¥È¤Ï¥»¥Ã¥·¥ç¥ó ID ¤ËÉղ䵤줿Ãͤˤʤê¤Þ¤¹¡£ +
    redirect-¥ï¡¼¥«¡¼¤Î¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó·ÐÏ©¤Ç¤¹¡£¤³¤ÎÃͤÏÄ̾ï¤Ï¡¢ + °ÂÁ´¤Ë¥¯¥é¥¹¥¿¤«¤é¥Î¡¼¥É¤ò¼è¤êµî¤ëÀßÄê¤òưŪ¤ËÆþ¤ì¤ë¤¿¤á¤Ë»È¤¤¤Þ¤¹¡£ + ¥»¥Ã¥·¥ç¥ó ID ¤Î̵¤¤¥ê¥¯¥¨¥¹¥ÈÁ´¤Æ¤ò»ØÄꤷ¤¿¾ì¹ç¤Ï¡¢ + ¤³¤ÎÃͤÈƱ¤¸¥ë¡¼¥Æ¥£¥ó¥°¥Ñ¥é¥á¡¼¥¿¤ò»ý¤Ä + BalancerMember ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤Þ¤¹¡£ +
    + +

    Proxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥¹¥­¡¼¥à¤¬ balancer:// ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + ¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤È¼ÂºÝ¤Ë¤ÏÄÌ¿®¤·¤Ê¤¤²¾Áۥ¥«¡¼¤¬À¸À®¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î¥ï¡¼¥«¡¼¤Ï´ö¤Ä¤«¤Î "ËÜʪ¤Î" ¥ï¡¼¥«¡¼¤Î´ÉÍý¤ò¤Ä¤«¤µ¤É¤ê¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¥Ñ¥é¥á¡¼¥¿¤Ï¡¢¤³¤Î²¾Áۥ¥«¡¼¤ËÂФ·¤ÆÀßÄꤵ¤ì¤Þ¤¹¡£ +

    + + + + + + + + + + + + + + + + + + + + +
    ¥Ñ¥é¥á¡¼¥¿¥Ç¥Õ¥©¥ë¥ÈÃÍÀâÌÀ
    lbmethod-Balancer ¤Î¥í¡¼¥É¥Ð¥é¥ó¥¹ÊýË¡¡£»ÈÍѤ¹¤ë¥í¡¼¥É¥Ð¥é¥ó¥¹¤Î + ¥¹¥±¥¸¥å¡¼¥ê¥ó¥°ÊýË¡¤òÁª¤Ó¤Þ¤¹¡£½èÍý¤·¤¿¥ê¥¯¥¨¥¹¥È¤Î¿ô¤Ç½Å¤ßÉÕ¤±¤¹¤ë + requests ¤«¡¢Å¾Á÷Î̤ΥХ¤¥È¿ô¤Ç½Å¤ßÉÕ¤±¤¹¤ë + traffic ¤òÀßÄê¤Ç¤­¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Ï + requests ¤Ç¤¹¡£ +
    stickysession-¥Ð¥é¥ó¥µ¡¼¤Î¥¹¥Æ¥£¥Ã¥­¡¼¥»¥Ã¥·¥ç¥ó̾¤Ç¤¹¡£Ä̾ï¤Ï¤³¤ÎÃÍ¤Ï JSESSIONID + ¤ä PHPSESSIONID ¤È¤¤¤Ã¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÃÍ¤Ï + ¥Ð¥Ã¥¯¥¨¥ó¥É¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥µ¥Ý¡¼¥È¤¹¤ë¥»¥Ã¥·¥ç¥ó¤Ë°Í¸¤·¤Þ¤¹¡£ +
    nofailoverOffOn ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¡¢¥ï¡¼¥«¡¼¤¬¥¨¥é¡¼¤òµ¯¤³¤·¤¿¤ê + ̵¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¥»¥Ã¥·¥ç¥ó¤¬ÀÚ¤ì¤Þ¤¹¡£ + ¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤¬¥»¥Ã¥·¥ç¥ó¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢ + On ¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    timeout0¥Ð¥é¥ó¥µ¡¼¤Î¥¿¥¤¥à¥¢¥¦¥È¤òÉäǻØÄꤷ¤Þ¤¹¡£ + ¤³¤ÎÃͤòÀßÄꤹ¤ë¤È¡¢¥Õ¥ê¡¼¤Î¥ï¡¼¥«¡¼¤ò¼èÆÀ¤¹¤ë¤Þ¤Ç¤ÎºÇÂçÂÔµ¡»þ´Ö¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏÂÔµ¡¤·¤Þ¤»¤ó¡£ +
    maxattempts1¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼¤ò»î¤ß¤ëºÇÂç¤Î²ó¿ô¤ò»ØÄꤷ¤Þ¤¹¡£ +
    +

    + ProxyPass /special-area http://special.example.com/ smax=5 max=10
    + ProxyPass / balancer://mycluster stickysession=jsessionid nofailover=On
    + <Proxy balancer://mycluster>
    + + BalancerMember http://1.2.3.4:8009
    + BalancerMember http://1.2.3.5:8009 smax=10
    + # Less powerful server, don't send as many requests there
    + BalancerMember http://1.2.3.6:8009 smax=1 loadfactor=20
    +
    + </Proxy> +

    + +

    <Location> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ç»È¤ï¤ì¤¿¾ì¹ç¡¢ºÇ½é¤Î°ú¿ô¤Ï + ¾Êά¤µ¤ì¡¢¥í¡¼¥«¥ë¥Ç¥£¥ì¥¯¥È¥ê¤Ï <Location> ¤«¤é¼èÆÀ¤µ¤ì¤Þ¤¹¡£

    + +

    ¤è¤ê½ÀÆð¤Ê¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ÎÀßÄ꤬ɬÍפʾì¹ç¤Ï¡¢[P] + ¥Õ¥é¥°ÉÕ¤­¤Î RewriteRule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    top
    +

    ProxyPassReverse ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤µ¤ì¤¿¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤¿ HTTP ±þÅú¥Ø¥Ã¥À¤Î +URL ¤òÄ´À°¤¹¤ë
    ¹½Ê¸:ProxyPassReverse [path] url
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache ¤Ë HTTP ¥ê¥À¥¤¥ì¥¯¥È±þÅú¤Î + Location, Content-Location, URI + ¥Ø¥Ã¥À¤ÎÄ´À°¤ò¤µ¤»¤Þ¤¹¡£¤³¤ì¤Ï¡¢Apache ¤¬¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤È¤·¤Æ»È¤ï¤ì¤Æ¤¤¤ë + ¤È¤­¤Ë¡¢¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤òÄ̤µ¤Ê¤¤¤Ç¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤òËɤ°¤¿¤á¤Ë + ½ÅÍפǤ¹¡£¤³¤ì¤Ë¤è¤ê¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤Î HTTP ¥ê¥À¥¤¥ì¥¯¥È¤¬ + ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤È¥Ð¥Ã¥¯¥¨¥ó¥É¤Î´Ö¤Ç°·¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÌÀ¼¨¤µ¤ì¤Æ¤¤¤ë HTTP ±þÅú¥Ø¥Ã¥À¤Î¤ß¤¬½ñ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£ + Apache ¤Ï¾¤Î±þÅú¥Ø¥Ã¥À¤ò½ñ¤­´¹¤¨¤¿¤ê¡¢HTML ¥Ú¡¼¥¸¤ÎÃæ¤Î URL »²¾È¤ò + ½ñ¤­´¹¤¨¤¿¤ê¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£HTML ¤ÎÃæ¤ò¸«¤Æ¡¢URL »²¾È¤ò½ñ¤­´¹¤¨¤ë + ¥â¥¸¥å¡¼¥ë¤Ë Nick Kew ¤µ¤ó¤Î mod_proxy_html ¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    path ¤Ï¥í¡¼¥«¥ë²¾Áۥѥ¹¤Î̾Á°¤Ç¤¹¡£url ¤Ï + ¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ÎÉôʬ URL ¤Ç¤¹¡£¤³¤ì¤é¤Ï ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱÍͤǤ¹¡£

    + +

    Î㤨¤Ð¡¢¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î¥¢¥É¥ì¥¹¤¬ http://example.com/ + ¤À¤È¤·¤Þ¤¹¡£¤¹¤ë¤È

    + +

    + ProxyPass /mirror/foo/ http://backend.example.com/
    + ProxyPassReverse /mirror/foo/ http://backend.example.com/
    + ProxyPassReverseCookieDomain backend.example.com public.example.com
    + ProxyPassReverseCookiePath / /mirror/foo/ +

    + +

    ¤È¤¤¤¦ÀßÄê¤ò¤¹¤ë¤È¡¢http://example.com/mirror/foo/bar + ¤Ø¤Î¥í¡¼¥«¥ë¥ê¥¯¥¨¥¹¥È¤¬ http://backend.example.com/bar + ¤Ø¤Î¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤ËÆâÉô¤Ç¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤ë¤À¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó + (¤³¤ì¤Ï ProxyPass ¤Îµ¡Ç½¤Ç¤¹)¡£backend.example.com + ¤¬Á÷¤ë¥ê¥À¥¤¥ì¥¯¥È¤ÎÌÌÅݤâ¤ß¤Þ¤¹¡£http://backend.example.com/bar + ¤¬ http://backend.example.com/quux ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤¿¤È¤­¡¢ + Apache ¤Ï HTTP ¥ê¥À¥¤¥ì¥¯¥È±þÅú¤ò¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ëÁ°¤Ë¡¢ + http://example.com/mirror/foo/quux ¤ËÊѹ¹¤·¤Þ¤¹¡£ + URL ¤ò¹½À®¤¹¤ë¤Î¤Ë»È¤ï¤ì¤ë¥Û¥¹¥È̾¤Ï UseCanonicalName ¤ÎÀßÄê¤Ë±þ¤¸¤ÆÁªÂò¤µ¤ì¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ProxyPassReverse ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Âбþ¤¹¤ë ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ï°Í¸¤·¤Ê¤¤¤¿¤á¡¢ + mod_rewrite ¤Î¥×¥í¥­¥·Ä̲ᵡǽ + (RewriteRule ... [P]) ¤ÈÊ»¤»¤Æ»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    <Location> ¥»¥¯¥·¥ç¥ó¤ÎÃæ¤Ç»È¤ï¤ì¤¿¾ì¹ç¤Ï¡¢ + ºÇ½é¤Î°ú¿ô¤Ï¾Êά¤µ¤ì¡¢¥í¡¼¥«¥ë¥Ç¥£¥ì¥¯¥È¥ê¤Ï <Location> ¤«¤é¼èÆÀ¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    ProxyPassReverseCookieDomain ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¥µ¡¼¥Ð¤«¤é¤Î Set-Cookie ¥Ø¥Ã¥À¤Î Domain ʸ»úÎó¤ò +Ä´À°¤¹¤ë
    ¹½Ê¸:ProxyPassReverseCookieDomain internal-domain public-domain
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    »ÈÍÑË¡¤Ï´ðËÜŪ¤Ë +ProxyPassReverse ¤ÈƱ¤¸¤Ç¤¹¤¬¡¢ +¥Ø¥Ã¥À¤Î URL ¤ÎÂå¤ï¤ê¤Ë Set-Cookie ¥Ø¥Ã¥À¤Î +domain ʸ»úÎó¤ò½ñ¤­´¹¤¨¤Þ¤¹¡£

    + +
    +
    top
    +

    ProxyPassReverseCookiePath ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Reverse ¥×¥í¥­¥·¥µ¡¼¥Ð¤«¤é¤Î Set-Cookie ¥Ø¥Ã¥À¤Î Path ʸ»úÎó¤ò +Ä´À°¤¹¤ë
    ¹½Ê¸:ProxyPassReverseCookiePath internal-path public-path
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    »ÈÍÑË¡¤Ï´ðËÜŪ¤Ë +ProxyPassReverse ¤ÈƱ¤¸¤Ç¤¹¤¬¡¢ +¥Ø¥Ã¥À¤Î URL ¤ÎÂå¤ï¤ê¤Ë Set-Cookie ¥Ø¥Ã¥À¤Î +path ʸ»úÎó¤ò½ñ¤­´¹¤¨¤Þ¤¹¡£

    + +
    +
    top
    +

    ProxyPreserveHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Ë¡¢¼õ¤±ÉÕ¤±¤¿ Host HTTP ¥Ø¥Ã¥À¤ò»È¤¦
    ¹½Ê¸:ProxyPreserveHost On|Off
    ¥Ç¥Õ¥©¥ë¥È:ProxyPreserveHost Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    ¸ß´¹À­:Apache 2.0.31 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¡¢ProxyPass + ¤Ç»ØÄꤷ¤¿¥Û¥¹¥È̾¤ÎÂå¤ï¤ê¤Ë¡¢¼õ¤±ÉÕ¤±¤¿¥ê¥¯¥¨¥¹¥È¤Î Host: ¹Ô¤ò + ¥×¥í¥­¥·Àè¤Î¥Û¥¹¥È¤ËÁ÷¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¥ª¥×¥·¥ç¥ó¤ÏÄ̾ï¤Ï Off ¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£ + ¤Û¤È¤ó¤É¤Î¾ì¹ç¡¢¤³¤ì¤ÏÂçÎ̤Î̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥Æ¥£¥ó¥°¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤Æ¡¢ + ¸µ¡¹¤Î Host ¥Ø¥Ã¥À¤ò¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤¬²ò¼á¤¹¤ëɬÍפΤ¢¤ë¤È¤­¤Î¤è¤¦¤Ê¡¢ + ÆÃÊ̤ÊÀßÄ꤬ɬÍפʾì¹ç¤Ë¤Î¤ßÍ­ÍѤǤ¹¡£

    + +
    +
    top
    +

    ProxyReceiveBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤ë HTTP ¤È FTP Àܳ¤Î¤¿¤á¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º
    ¹½Ê¸:ProxyReceiveBufferSize bytes
    ¥Ç¥Õ¥©¥ë¥È:ProxyReceiveBufferSize 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ProxyReceiveBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥¹¥ë¡¼¥×¥Ã¥È¤ò¾å¤²¤ë¤¿¤á¤ËÌÀ¼¨Åª¤Ë (TCP/IP) ¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥Ã¥Õ¥¡¤Î¥µ¥¤¥º¤ò + ÀßÄꤷ¤Þ¤¹¡£ÃÍ¤Ï 512 °Ê¾å¤«¡¢¥·¥¹¥Æ¥à¤Î¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¥Ã¥Õ¥¡ + ¥µ¥¤¥º¤ò°ÕÌ£¤¹¤ë 0 ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    Îã

    + ProxyReceiveBufferSize 2048 +

    + +
    +
    top
    +

    ProxyRemote ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¦»þ¤Ë»È¤ï¤ì¤ë¥ê¥â¡¼¥È¥×¥í¥­¥·¤ò»ØÄꤹ¤ë
    ¹½Ê¸:ProxyRemote match remote-server
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤³¤Î¥×¥í¥­¥·¤ËÂФ¹¤ë¥ê¥â¡¼¥È¥×¥í¥­¥·¤òÄêµÁ¤·¤Þ¤¹¡£ + match ¤Ï¥ê¥â¡¼¥È¥µ¡¼¥Ð¤¬¥µ¥Ý¡¼¥È¤¹¤ë URL ¥¹¥­¡¼¥à¡¢ + ¥ê¥â¡¼¥È¥µ¡¼¥Ð¤¬»È¤¦¤Ï¤º¤Î URL ¤Î°ìÉôʬ¡¢¥µ¡¼¥Ð¤¬¤¹¤Ù¤Æ¤Î + ¥ê¥¯¥¨¥¹¥È¤Ë»È¤ï¤ì¤ë¤³¤È¤ò¼¨¤¹ * ¤Î¤É¤ì¤«¤Ë¤Ê¤ê¤Þ¤¹¡£ + remote-server ¤Ï¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ÎÉôʬ URL ¤Ç¤¹¡£¹½Ê¸:

    + +

    + remote-server = + scheme://hostname[:port] +

    + +

    scheme ¤Ï¼ÂºÝ¾å¥ê¥â¡¼¥È¥µ¡¼¥Ð¤È¤ÎÄÌ¿®¤Ë»È¤ï¤ì¤ë¥×¥í¥È¥³¥ë¤ò + ·èÄꤷ¤Þ¤¹¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ç¤Ï http ¤À¤±¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ + ¤¤¤Þ¤¹¡£

    + +

    Îã

    + ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000
    + ProxyRemote * http://cleversite.com
    + ProxyRemote ftp http://ftpproxy.mydomain.com:8080 +

    + +

    ¤³¤ÎÎã¤Ç¤Ï¡¢¥×¥í¥­¥·¤Ï FTP ¥ê¥¯¥¨¥¹¥È¤òÊ̤ΠHTTP ¥ê¥¯¥¨¥¹¥È¤ÇÊñ¤ó¤Ç + ¤½¤Î¤è¤¦¤Ê¥ê¥¯¥¨¥¹¥È¤ò°·¤¨¤ëÊÌ¤Î¥×¥í¥­¥·¤ËžÁ÷¤·¤Þ¤¹¡£

    + +

    ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ÎÀßÄê¤â¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤¬Ê̤Υե©¥ï¡¼¥É¥×¥í¥­¥·¤Î¸å¤í¤Ë±£¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ç¤â + ¥Ð¥Ã¥¯¥¨¥ó¥É¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î URL ¶õ´Ö¤ËÆþ¤ì¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +
    +
    top
    +

    ProxyRemoteMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:Àµµ¬É½¸½¤Ç¤Î¥Þ¥Ã¥Á¤Ë¤è¤ë¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¥ê¥â¡¼¥È¥×¥í¥­¥·¤Î»ØÄê
    ¹½Ê¸:ProxyRemoteMatch regex remote-server
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ProxyRemoteMatch ¤ÏºÇ½é¤Î°ú¿ô¤¬¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ + URL ¤Ë¥Þ¥Ã¥Á¤¹¤ëÀµµ¬É½¸½¤Ç¤¢¤ë¤³¤È¤ò½ü¤±¤Ð ProxyRemote ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈƱ¤¸¤Ç¤¹¡£

    + +
    +
    top
    +

    ProxyRequests ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Õ¥©¥ï¡¼¥É (ɸ½à¤Î) ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:ProxyRequests On|Off
    ¥Ç¥Õ¥©¥ë¥È:ProxyRequests Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤ì¤Ï Apache ¤Î¥Õ¥©¥ï¡¼¥É¥×¥í¥­¥·¥µ¡¼¥Ð¤È¤·¤Æ¤ÎÆ°ºî¤ò + Í­¸ú¤â¤·¤¯¤Ï̵¸ú¤Ë¤·¤Þ¤¹¡£(ProxyRequests ¤ò Off ¤Ë + ÀßÄꤷ¤Æ¤â¡¢ProxyPass + ¤ÎÀßÄê¤Ï̵¸ú¤Ë¤Ê¤ê¤Þ¤»¤ó¡£)

    + +

    Ä̾ï¤Î¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤ÎÀßÄê¤Ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï Off + ¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

    + +

    HTTP ¤ä FTP ¥µ¥¤¥È¤Ø¤Î¥×¥í¥­¥·¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + mod_proxy_http ¤ä mod_proxy_ftp ¤¬ + ¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ·Ù¹ð

    +

    ¥µ¡¼¥Ð¤ò°ÂÁ´¤Ë¤¹¤ë¤Þ¤Ç ProxyRequests ¤ÏÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¥ª¡¼¥×¥ó¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï¤¢¤Ê¤¿¼«¿È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤È¤Ã¤Æ¤â¡¢ + ¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÁ´ÂΤˤȤäƤâ´í¸±¤Ç¤¹¡£

    +
    + +
    +
    top
    +

    ProxyTimeout ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥¿¥¤¥à¥¢¥¦¥È
    ¹½Ê¸:ProxyTimeout seconds
    ¥Ç¥Õ¥©¥ë¥È:ProxyTimeout 300
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    ¸ß´¹À­:Apache 2.0.31 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥æ¡¼¥¶¤¬¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Î¥¿¥¤¥à¥¢¥¦¥È¤ò + »ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£¤³¤ì¤Ï¥Ï¥ó¥°¤·¤Æ¤·¤Þ¤¦ÃÙ¤¤¡¢¤â¤·¤¯¤ÏµóÆ°¤Î + ²ø¤·¤¤¥µ¡¼¥Ð¤¬¤¢¤ê¡¢¥µ¡¼¥Ð¤¬¥Ç¡¼¥¿¤òÊÖ¤¹¤Þ¤Ç¤Ò¤¿¤¹¤éÂÔ¤Á³¤±¤ë¤è¤ê¤â + ¥¿¥¤¥à¥¢¥¦¥È¤òÊÖ¤·¤Æ¤è¤ê´Ë¤ä¤«¤Ë(ÌõÃí: graceful ¤Ë) + ¼ºÇÔ¤µ¤»¤¿¤¤¾ì¹ç¤ËÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +
    +
    top
    +

    ProxyVia ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î Via HTTP ±þÅú¥Ø¥Ã¥À +¤Ë¤è¤êÄ󶡤µ¤ì¤ë¾ðÊó
    ¹½Ê¸:ProxyVia On|Off|Full|Block
    ¥Ç¥Õ¥©¥ë¥È:ProxyVia Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_proxy
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥×¥í¥­¥·¤Î Via: HTTP ¥Ø¥Ã¥À¤Î»ÈÍѤò + À©¸æ¤·¤Þ¤¹¡£ÁÛÄꤵ¤ì¤Æ¤¤¤ë»È¤¤Êý¤Ï¡¢¥×¥í¥­¥·¥µ¡¼¥Ð¤¬¤¤¤¯¤Ä¤â·Ò¤¬¤Ã¤Æ¤¤¤ë¤È¤­¤Ë + ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Îή¤ì¤òÀ©¸æ¤¹¤ë¤³¤È¤Ç¤¹¡£Via: ¥Ø¥Ã¥À¹Ô¤Î + ÀâÌÀ¤Ï RFC 2616 (HTTP/1.1) + ¤Î 14.45 Àá¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£

    + +
      +
    • ¥Ç¥Õ¥©¥ë¥È¤Î Off ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¡¢ÆÃÊ̤ʽèÍý¤Ï + ¹Ô¤Ê¤ï¤ì¤Þ¤»¤ó¡£¥ê¥¯¥¨¥¹¥È¤ä¥ê¥×¥é¥¤¤Ë Via: ¥Ø¥Ã¥À¤¬¤¢¤ì¤Ð¡¢ + Êѹ¹¤µ¤ì¤º¤Ë¤½¤Î¤Þ¤ÞÅϤ·¤Þ¤¹¡£
    • + +
    • On ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢³Æ¥ê¥¯¥¨¥¹¥È¤È¥ê¥×¥é¥¤¤Ë + Via: ¹Ô¤¬Äɲ䵤ì¤Þ¤¹¡£
    • + +
    • Full ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢Via: ¥Ø¥Ã¥À¤Ï + ¥³¥á¥ó¥ÈÉôʬ¤Ë Apache ¥µ¡¼¥Ð¤Î¥Ð¡¼¥¸¥ç¥ó¤â´Þ¤à¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
    • + +
    • Block ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤«¤é + Via: ¥Ø¥Ã¥À¤¬¼è¤ê½ü¤«¤ì¤Þ¤¹¡£¿·¤¿¤Ë Via: ¤¬ + À¸À®¤µ¤ì¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
    • +
    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy.xml b/trunk/docs/manual/mod/mod_proxy.xml new file mode 100644 index 0000000000..d3c81a57c9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.xml @@ -0,0 +1,1189 @@ + + + + + + + + + +mod_proxy +HTTP/1.1 proxy/gateway server +Extension +mod_proxy.c +proxy_module + + + Warning +

    Do not enable proxying with ProxyRequests until you have secured your server. Open proxy servers are dangerous both to your + network and to the Internet at large.

    +
    + +

    This module implements a proxy/gateway for Apache. It implements + proxying capability for AJP13 (Apache JServe Protocol + version 1.3), FTP, CONNECT (for SSL), + HTTP/0.9, HTTP/1.0, and HTTP/1.1. + The module can be configured to connect to other proxy modules for these + and other protocols.

    + +

    Apache's proxy features are divided into several modules in + addition to mod_proxy: + mod_proxy_http, mod_proxy_ftp, + mod_proxy_ajp, mod_proxy_balancer, + and mod_proxy_connect. Thus, if you want to use + one or more of the particular proxy functions, load + mod_proxy and the appropriate module(s) + into the server (either statically at compile-time or dynamically + via the LoadModule + directive).

    + +

    In addition, extended features are provided by other modules. + Caching is provided by mod_cache and related + modules. The ability to contact remote servers using the SSL/TLS + protocol is provided by the SSLProxy* directives of + mod_ssl. These additional modules will need + to be loaded and configured to take advantage of these features.

    +
    +mod_cache +mod_proxy_http +mod_proxy_ftp +mod_proxy_connect +mod_proxy_balancer +mod_ssl + +
    Forward and Reverse Proxies +

    Apache can be configured in both a forward and + reverse proxy mode.

    + +

    An ordinary forward proxy is an intermediate + server that sits between the client and the origin + server. In order to get content from the origin server, + the client sends a request to the proxy naming the origin server + as the target and the proxy then requests the content from the + origin server and returns it to the client. The client must be + specially configured to use the forward proxy to access other + sites.

    + +

    A typical usage of a forward proxy is to provide Internet + access to internal clients that are otherwise restricted by a + firewall. The forward proxy can also use caching (as provided + by mod_cache) to reduce network usage.

    + +

    The forward proxy is activated using the ProxyRequests directive. Because + forward proxys allow clients to access arbitrary sites through + your server and to hide their true origin, it is essential that + you secure your server so that only + authorized clients can access the proxy before activating a + forward proxy.

    + +

    A reverse proxy, by contrast, appears to the + client just like an ordinary web server. No special + configuration on the client is necessary. The client makes + ordinary requests for content in the name-space of the reverse + proxy. The reverse proxy then decides where to send those + requests, and returns the content as if it was itself the + origin.

    + +

    A typical usage of a reverse proxy is to provide Internet + users access to a server that is behind a firewall. Reverse + proxies can also be used to balance load among several back-end + servers, or to provide caching for a slower back-end server. + In addition, reverse proxies can be used simply to bring + several servers into the same URL space.

    + +

    A reverse proxy is activated using the ProxyPass directive or the + [P] flag to the RewriteRule directive. It is + not necessary to turn ProxyRequests on in order to + configure a reverse proxy.

    +
    + +
    Basic Examples + +

    The examples below are only a very basic idea to help you + get started. Please read the documentation on the individual + directives.

    + +

    In addition, if you wish to have caching enabled, consult + the documentation from mod_cache.

    + + Forward Proxy + ProxyRequests On
    + ProxyVia On
    +
    + <Proxy *>
    + + Order deny,allow
    + Deny from all
    + Allow from internal.example.com
    +
    + </Proxy> +
    + + Reverse Proxy + ProxyRequests Off
    +
    + <Proxy *>
    + + Order deny,allow
    + Allow from all
    +
    + </Proxy>
    +
    + ProxyPass /foo http://foo.example.com/bar
    + ProxyPassReverse /foo http://foo.example.com/bar +
    +
    + + +
    Controlling access to your proxy +

    You can control who can access your proxy via the Proxy control block as in + the following example:

    + + + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from 192.168.0
    +
    + </Proxy> +
    + +

    For more information on access control directives, see + mod_authz_host.

    + +

    Strictly limiting access is essential if you are using a + forward proxy (using the ProxyRequests directive). + Otherwise, your server can be used by any client to access + arbitrary hosts while hiding his or her true identity. This is + dangerous both for your network and for the Internet at large. + When using a reverse proxy (using the ProxyPass directive with + ProxyRequests Off), access control is less + critical because clients can only contact the hosts that you + have specifically configured.

    + +
    + +
    FTP Proxy + + +
    Why doesn't file type <var>xxx</var> + download via FTP? +

    You probably don't have that particular file type defined as + application/octet-stream in your proxy's mime.types + configuration file. A useful line can be

    + + +
    application/octet-stream   bin dms lha lzh exe class tgz taz
    +
    +

    Alternatively you may prefer to default everything to binary:

    + +
    DefaultType application/octet-stream
    +
    +
    + +
    How can I force an FTP ASCII download of + File <var>xxx</var>? +

    In the rare situation where you must download a specific file using the + FTP ASCII transfer method (while the default transfer is in + binary mode), you can override mod_proxy's + default by suffixing the request with ;type=a to force an + ASCII transfer. (FTP Directory listings are always executed in ASCII mode, + however.)

    +
    + +
    How can I do FTP upload? +

    Currently, only GET is supported for FTP in mod_proxy. You can + of course use HTTP upload (POST or PUT) through an Apache proxy.

    +
    + +
    How can I access FTP files outside + of my home directory? +

    An FTP URI is interpreted relative to the home directory of the user + who is logging in. Alas, to reach higher directory levels you cannot + use /../, as the dots are interpreted by the browser and not actually + sent to the FTP server. To address this problem, the so called Squid + %2f hack was implemented in the Apache FTP proxy; it is a + solution which is also used by other popular proxy servers like the Squid Proxy Cache. By + prepending /%2f to the path of your request, you can make + such a proxy change the FTP starting directory to / (instead + of the home directory). For example, to retrieve the file + /etc/motd, you would use the URL:

    + + + ftp://user@host/%2f/etc/motd + +
    + +
    How can I hide the FTP cleartext password + in my browser's URL line? +

    To log in to an FTP server by username and password, Apache uses + different strategies. In absense of a user name and password in the URL + altogether, Apache sends an anonymous login to the FTP server, + i.e.,

    + + + user: anonymous
    + password: apache_proxy@ +
    + +

    This works for all popular FTP servers which are configured for + anonymous access.

    + +

    For a personal login with a specific username, you can embed the user + name into the URL, like in:

    + + + ftp://username@host/myfile + + +

    If the FTP server asks for a password when given this username (which + it should), then Apache will reply with a 401 (Authorization + required) response, which causes the Browser to pop up the + username/password dialog. Upon entering the password, the connection + attempt is retried, and if successful, the requested resource is + presented. The advantage of this procedure is that your browser does not + display the password in cleartext (which it would if you had used

    + + + ftp://username:password@host/myfile + + +

    in the first place).

    + + Note +

    The password which is transmitted in such a way is not encrypted on + its way. It travels between your browser and the Apache proxy server in + a base64-encoded cleartext string, and between the Apache proxy and the + FTP server as plaintext. You should therefore think twice before + accessing your FTP server via HTTP (or before accessing your personal + files via FTP at all!) When using unsecure channels, an eavesdropper + might intercept your password on its way.

    +
    +
    +
    +
    Slow Startup +

    If you're using the ProxyBlock directive, hostnames' IP addresses are looked up + and cached during startup for later match test. This may take a few + seconds (or more) depending on the speed with which the hostname lookups + occur.

    +
    + +
    Intranet Proxy +

    An Apache proxy server situated in an intranet needs to forward + external requests through the company's firewall (for this, configure + the ProxyRemote directive + to forward the respective scheme to the firewall proxy). + However, when it has to + access resources within the intranet, it can bypass the firewall when + accessing hosts. The NoProxy + directive is useful for specifying which hosts belong to the intranet and + should be accessed directly.

    + +

    Users within an intranet tend to omit the local domain name from their + WWW requests, thus requesting "http://somehost/" instead of + http://somehost.example.com/. Some commercial proxy servers + let them get away with this and simply serve the request, implying a + configured local domain. When the ProxyDomain directive is used and the server is configured for proxy service, Apache can return + a redirect response and send the client to the correct, fully qualified, + server address. This is the preferred method since the user's bookmark + files will then contain fully qualified hosts.

    +
    + +
    Protocol Adjustments +

    For circumstances where you have a application server which doesn't + implement keepalives or HTTP/1.1 properly, there are 2 environment + variables which when set send a HTTP/1.0 with no keepalive. These are set + via the SetEnv directive.

    + +

    These are the force-proxy-request-1.0 and + proxy-nokeepalive notes.

    + + + <Location /buggyappserver/>
    + + ProxyPass http://buggyappserver:7001/foo/
    + SetEnv force-proxy-request-1.0 1
    + SetEnv proxy-nokeepalive 1
    +
    + </Location> +
    +
    + + +Proxy +Container for directives applied to proxied resources +<Proxy wildcard-url> ...</Proxy> +server configvirtual host + + + +

    Directives placed in Proxy + sections apply only to matching proxied content. Shell-style wildcards are + allowed.

    + +

    For example, the following will allow only hosts in + yournetwork.example.com to access content via your proxy + server:

    + + + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from yournetwork.example.com
    +
    + </Proxy> +
    + +

    The following example will process all files in the foo + directory of example.com through the INCLUDES + filter when they are sent through the proxy server:

    + + + <Proxy http://example.com/foo/*>
    + + SetOutputFilter INCLUDES
    +
    + </Proxy> +
    + +
    +
    + + +ProxyBadHeader +Determines how to handle bad header lines in a +response +ProxyBadHeader IsError|Ignore|StartBody +ProxyBadHeader IsError +server configvirtual host + +available in Apache 2.0.44 and later + + +

    The ProxyBadHeader directive determines the + behaviour of mod_proxy if it receives syntactically invalid + header lines (i.e. containing no colon). The following arguments + are possible:

    + +
    +
    IsError
    +
    Abort the request and end up with a 502 (Bad Gateway) response. This is + the default behaviour.
    + +
    Ignore
    +
    Treat bad header lines as if they weren't sent.
    + +
    StartBody
    +
    When receiving the first bad header line, finish reading the headers and + treat the remainder as body. This helps to work around buggy backend servers + which forget to insert an empty line between the headers and the body.
    +
    +
    +
    + + +ProxyMatch +Container for directives applied to regular-expression-matched +proxied resources +<ProxyMatch regex> ...</ProxyMatch> +server configvirtual host + + + +

    The ProxyMatch directive is + identical to the Proxy directive, except it matches URLs + using regular expressions.

    +
    +
    + + +ProxyPreserveHost +Use incoming Host HTTP request header for proxy +request +ProxyPreserveHost On|Off +ProxyPreserveHost Off +server configvirtual host + +Available in Apache 2.0.31 and later. + + +

    When enabled, this option will pass the Host: line from the incoming + request to the proxied host, instead of the hostname specified in the + ProxyPass line.

    + +

    This option should normally be turned Off. It is mostly + useful in special configurations like proxied mass name-based virtual + hosting, where the original Host header needs to be evaluated by the + backend server.

    +
    +
    + + +ProxyRequests +Enables forward (standard) proxy requests +ProxyRequests On|Off +ProxyRequests Off +server configvirtual host + + + +

    This allows or prevents Apache from functioning as a forward proxy + server. (Setting ProxyRequests to Off does not disable use of + the ProxyPass directive.)

    + +

    In a typical reverse proxy configuration, this option should be set to + Off.

    + +

    In order to get the functionality of proxying HTTP or FTP sites, you + need also mod_proxy_http or mod_proxy_ftp + (or both) present in the server.

    + + Warning +

    Do not enable proxying with ProxyRequests until you have secured your server. Open proxy servers are dangerous + both to your network and to the Internet at large.

    +
    +
    +
    + + +ProxyRemote +Remote proxy used to handle certain requests +ProxyRemote match remote-server +server configvirtual host + + + +

    This defines remote proxies to this proxy. match is either the + name of a URL-scheme that the remote server supports, or a partial URL + for which the remote server should be used, or * to indicate + the server should be contacted for all requests. remote-server is + a partial URL for the remote server. Syntax:

    + + + remote-server = + scheme://hostname[:port] + + +

    scheme is effectively the protocol that should be used to + communicate with the remote server; only http is supported by + this module.

    + + Example + ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000
    + ProxyRemote * http://cleversite.com
    + ProxyRemote ftp http://ftpproxy.mydomain.com:8080 +
    + +

    In the last example, the proxy will forward FTP requests, encapsulated + as yet another HTTP proxy request, to another proxy which can handle + them.

    + +

    This option also supports reverse proxy configuration - a backend + webserver can be embedded within a virtualhost URL space even if that + server is hidden by another forward proxy.

    +
    +
    + + +ProxyRemoteMatch +Remote proxy used to handle requests matched by regular +expressions +ProxyRemoteMatch regex remote-server +server configvirtual host + + + +

    The ProxyRemoteMatch is identical to the + ProxyRemote directive, except the + first argument is a regular expression match against the requested URL.

    +
    +
    + + +ProxyPass +Maps remote servers into the local server URL-space +ProxyPass [path] !|url [key=value key=value ...]] +server configvirtual host +directory + + + +

    This directive allows remote servers to be mapped into the space of + the local server; the local server does not act as a proxy in the + conventional sense, but appears to be a mirror of the remote + server. path is the name of a local virtual path; url + is a partial URL for the remote server and cannot include a query + string.

    + + The ProxyRequests directive should + usually be set off when using + ProxyPass. + +

    Suppose the local server has address http://example.com/; + then

    + + + ProxyPass /mirror/foo/ http://backend.example.com/ + + +

    will cause a local request for + http://example.com/mirror/foo/bar to be internally converted + into a proxy request to http://backend.example.com/bar.

    + +

    The ! directive is useful in situations where you don't want + to reverse-proxy a subdirectory, e.g.

    + + + ProxyPass /mirror/foo/i !
    + ProxyPass /mirror/foo http://backend.example.com +
    + +

    will proxy all requests to /mirror/foo to + backend.example.com except requests made to + /mirror/foo/i.

    + + Note +

    Order is important. you need to put the exclusions before the + general ProxyPass directive.

    +
    + +

    New in Apache 2.1, is the ability to use pooled connections to a + backend server. Using the key=value parameters it is possible + to tune this connection pooling. The default for a Hard Maximum + for the number of connections is the number of threads per process in the + active MPM. In the Prefork MPM, this is always 1, while with the Worker MPM + it is controlled by the ThreadsPerChild.

    + +

    Setting min will determine how many connections will always + be open to the backend server. Upto the Soft Maximum or smax + number of connections will be created on demand. Any connections above + smax are subject to a time to live or ttl. Apache + will never create more than the Hard Maximum or max connections + to the backend server.

    + + + ProxyPass /example http://backend.example.com smax=5 max=20 ttl=120 retry=300 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterDefaultDescription
    min0Minumum number of connections that will always + be open to the backend server.
    max1...nHard Maximum number of connections that will be + allowed to the backend server. The default for a Hard Maximum + for the number of connections is the number of threads per process in the + active MPM. In the Prefork MPM, this is always 1, while with the Worker MPM + it is controlled by the ThreadsPerChild. + Apache will never create more than the Hard Maximum connections + to the backend server.
    smaxmaxUpto the Soft Maximum + number of connections will be created on demand. Any connections above + smax are subject to a time to live or ttl. +
    ttl-Time To Live for the inactive connections above the + smax connections in seconds. Apache will close all + connections that has not been used inside that time period. +
    timeoutTimeoutConnection timeout in seconds. + If not set the Apache will wait until the free connection + is available. This directive is used for limiting the number + of connections to the backend server together with max + parameter. +
    acquire-If set this will be the maximum time to wait for a free + connection in the connection pool. If there are no free connections + in the pool the Apache will return SERVER_BUSY status to + the client. +
    keepaliveOffThis parameter should be used when you have a firewall between your + Apache and the backend server, who tend to drop inactive connections. + This flag will tell the Operating System to send KEEP_ALIVE + messages on inactive connections (interval depends on global OS settings, + generally 120ms), and thus prevent the firewall to drop the connection. + To enable keepalive set this property value to On. +
    retry60Connection pool worker retry timeout in seconds. + If the connection pool worker to the backend server is in the error state, + Apache will not forward any requests to that server until the timeout + expires. This enables to shut down the backend server for maintenance, + and bring it back online later. +
    loadfactor1Worker load factor. Used with BalancerMember. + It is a number between 1 and 100 and defines the normalized weighted + load applied to the worker. +
    route-Route of the worker when used inside load balancer. + The route is a value appended to seesion id. +
    redirect-Redirection Route of the worker. This value is usually + set dynamically to enable safe removal of the node from + the cluster. If set all requests without session id will be + redirected to the BalancerMember that has route parametar + equal as this value. +
    + +

    If the Proxy directive scheme starts with the + balancer:// then a virtual worker that does not really + communicate with the backend server will be created. Instead it is responsible + for the management of several "real" workers. In that case the special set of + parameters can be add to this virtual worker. +

    + + + + + + + + + + + + + + + + + + + + +
    ParameterDefaultDescription
    lbmethod-Balancer load-balance method. Select the load-balancing scheduler + method to use. Either requests, to perform weighted + request counting or traffic, to perform weighted + traffic byte count balancing. Default is requests. +
    stickysession-Balancer sticky session name. The value is usually set to something + like JSESSIONID or PHPSESSIONID, + and it depends on the backend application server that support sessions. +
    nofailoverOffIf set to On the session will break if the worker is in + error state or disabled. Set this value to On if backend servers do not + support session replication. +
    timeout0Balancer timeout in seconds. If set this will be the maximum time + to wait for a free worker. Default is not to wait. +
    maxattempts1Maximum number of failover attempts before giving up. +
    + + ProxyPass /special-area http://special.example.com/ smax=5 max=10
    + ProxyPass / balancer://mycluster stickysession=jsessionid nofailover=On
    + <Proxy balancer://mycluster>
    + + BalancerMember http://1.2.3.4:8009
    + BalancerMember http://1.2.3.5:8009 smax=10
    + # Less powerful server, don't send as many requests there
    + BalancerMember http://1.2.3.6:8009 smax=1 loadfactor=20
    +
    + </Proxy> +
    + +

    When used inside a Location section, the first argument is omitted and the local + directory is obtained from the Location.

    + +

    If you require a more flexible reverse-proxy configuration, see the + RewriteRule directive with the + [P] flag.

    +
    +
    + + +ProxyPassReverse +Adjusts the URL in HTTP response headers sent from a reverse +proxied server +ProxyPassReverse [path] url +server configvirtual host +directory + + + +

    This directive lets Apache adjust the URL in the Location, + Content-Location and URI headers on HTTP redirect + responses. This is essential when Apache is used as a reverse proxy to avoid + by-passing the reverse proxy because of HTTP redirects on the backend + servers which stay behind the reverse proxy.

    + +

    Only the HTTP response headers specifically mentioned above + will be rewritten. Apache will not rewrite other response + headers, nor will it rewrite URL references inside HTML pages. + This means that if the proxied content contains absolute URL + references, they will by-pass the proxy. A third-party module + that will look inside the HTML and rewrite URL references is Nick + Kew's mod_proxy_html.

    + +

    path is the name of a local virtual path. url is a + partial URL for the remote server - the same way they are used for the + ProxyPass directive.

    + +

    For example, suppose the local server has address + http://example.com/; then

    + + + ProxyPass /mirror/foo/ http://backend.example.com/
    + ProxyPassReverse /mirror/foo/ http://backend.example.com/
    + ProxyPassReverseCookieDomain backend.example.com public.example.com
    + ProxyPassReverseCookiePath / /mirror/foo/ +
    + +

    will not only cause a local request for the + http://example.com/mirror/foo/bar to be internally converted + into a proxy request to http://backend.example.com/bar + (the functionality ProxyPass provides here). It also takes care + of redirects the server backend.example.com sends: when + http://backend.example.com/bar is redirected by him to + http://backend.example.com/quux Apache adjusts this to + http://example.com/mirror/foo/quux before forwarding the HTTP + redirect response to the client. Note that the hostname used for + constructing the URL is chosen in respect to the setting of the UseCanonicalName directive.

    + +

    Note that this ProxyPassReverse directive can + also be used in conjunction with the proxy pass-through feature + (RewriteRule ... [P]) from mod_rewrite + because its doesn't depend on a corresponding ProxyPass directive.

    + +

    When used inside a Location section, the first argument is omitted and the local + directory is obtained from the Location.

    +
    +
    + + +ProxyPassReverseCookieDomain +Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server +ProxyPassReverseCookieDomain internal-domain public-domain +server configvirtual host +directory + + +

    Usage is basically similar to +ProxyPassReverse, but instead of +rewriting headers that are a URL, this rewrites the domain +string in Set-Cookie headers.

    +
    +
    + +ProxyPassReverseCookiePath +Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server +ProxyPassReverseCookiePath internal-path public-path +server configvirtual host +directory + + +

    Usage is basically similar to +ProxyPassReverse, but instead of +rewriting headers that are a URL, this rewrites the path +string in Set-Cookie headers.

    +
    +
    + + + +AllowCONNECT +Ports that are allowed to CONNECT through the +proxy +AllowCONNECT port [port] ... +AllowCONNECT 443 563 +server configvirtual host + + + +

    The AllowCONNECT directive specifies a list + of port numbers to which the proxy CONNECT method may + connect. Today's browsers use this method when a https + connection is requested and proxy tunneling over HTTP is in effect.

    + +

    By default, only the default https port (443) and the + default snews port (563) are enabled. Use the + AllowCONNECT directive to override this default and + allow connections to the listed ports only.

    + +

    Note that you'll need to have mod_proxy_connect present + in the server in order to get the support for the CONNECT at + all.

    +
    +
    + + +ProxyBlock +Words, hosts, or domains that are banned from being +proxied +ProxyBlock *|word|host|domain +[word|host|domain] ... +server configvirtual host + + + +

    The ProxyBlock directive specifies a list of + words, hosts and/or domains, separated by spaces. HTTP, HTTPS, and + FTP document requests to sites whose names contain matched words, + hosts or domains are blocked by the proxy server. The proxy + module will also attempt to determine IP addresses of list items which + may be hostnames during startup, and cache them for match test as + well. That may slow down the startup time of the server.

    + + Example + ProxyBlock joes-garage.com some-host.co.uk rocky.wotsamattau.edu + + +

    rocky.wotsamattau.edu would also be matched if referenced by + IP address.

    + +

    Note that wotsamattau would also be sufficient to match + wotsamattau.edu.

    + +

    Note also that

    + + + ProxyBlock * + + +

    blocks connections to all sites.

    +
    +
    + + +ProxyReceiveBufferSize +Network buffer size for proxied HTTP and FTP +connections +ProxyReceiveBufferSize bytes +ProxyReceiveBufferSize 0 +server configvirtual host + + + +

    The ProxyReceiveBufferSize directive specifies an + explicit (TCP/IP) network buffer size for proxied HTTP and FTP connections, + for increased throughput. It has to be greater than 512 or set + to 0 to indicate that the system's default buffer size should + be used.

    + + Example + ProxyReceiveBufferSize 2048 + +
    +
    + + +ProxyIOBufferSize +Determine size of internal data throughput buffer +ProxyIOBufferSize bytes +ProxyIOBufferSize 8192 +server configvirtual host + + + +

    The ProxyIOBufferSize directive adjusts the size + of the internal buffer, which is used as a scratchpad for the data between + input and output. The size must be less or equal 8192.

    + +

    In almost every case there's no reason to change that value.

    +
    +
    + + +ProxyMaxForwards +Maximium number of proxies that a request can be forwarded +through +ProxyMaxForwards number +ProxyMaxForwards 10 +server configvirtual host + +Available in Apache 2.0 and later + + +

    The ProxyMaxForwards directive specifies the + maximum number of proxies through which a request may pass, if there's no + Max-Forwards header supplied with the request. This is + set to prevent infinite proxy loops, or a DoS attack.

    + + Example + ProxyMaxForwards 15 + +
    +
    + + +NoProxy +Hosts, domains, or networks that will be connected to +directly +NoProxy host [host] ... +server configvirtual host + + + +

    This directive is only useful for Apache proxy servers within + intranets. The NoProxy directive specifies a + list of subnets, IP addresses, hosts and/or domains, separated by + spaces. A request to a host which matches one or more of these is + always served directly, without forwarding to the configured + ProxyRemote proxy server(s).

    + + Example + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21 +
    + +

    The host arguments to the NoProxy + directive are one of the following type list:

    + +
    + +
    Domain
    +
    +

    A Domain is a partially qualified DNS domain name, preceded + by a period. It represents a list of hosts which logically belong to the + same DNS domain or zone (i.e., the suffixes of the hostnames are + all ending in Domain).

    + + Examples + .com .apache.org. + + +

    To distinguish Domains from Hostnames (both syntactically and semantically; a DNS domain can + have a DNS A record, too!), Domains are always written with a + leading period.

    + + Note +

    Domain name comparisons are done without regard to the case, and + Domains are always assumed to be anchored in the root of the + DNS tree, therefore two domains .MyDomain.com and + .mydomain.com. (note the trailing period) are considered + equal. Since a domain comparison does not involve a DNS lookup, it is much + more efficient than subnet comparison.

    +
    + + +
    SubNet
    +
    +

    A SubNet is a partially qualified internet address in + numeric (dotted quad) form, optionally followed by a slash and the netmask, + specified as the number of significant bits in the SubNet. It is + used to represent a subnet of hosts which can be reached over a common + network interface. In the absence of the explicit net mask it is assumed + that omitted (or zero valued) trailing digits specify the mask. (In this + case, the netmask can only be multiples of 8 bits wide.) Examples:

    + +
    +
    192.168 or 192.168.0.0
    +
    the subnet 192.168.0.0 with an implied netmask of 16 valid bits + (sometimes used in the netmask form 255.255.0.0)
    +
    192.168.112.0/21
    +
    the subnet 192.168.112.0/21 with a netmask of 21 + valid bits (also used in the form 255.255.248.0)
    +
    + +

    As a degenerate case, a SubNet with 32 valid bits is the + equivalent to an IPAddr, while a SubNet with zero + valid bits (e.g., 0.0.0.0/0) is the same as the constant + _Default_, matching any IP address.

    + + +
    IPAddr
    +
    +

    A IPAddr represents a fully qualified internet address in + numeric (dotted quad) form. Usually, this address represents a host, but + there need not necessarily be a DNS domain name connected with the + address.

    + Example + 192.168.123.7 + + + Note +

    An IPAddr does not need to be resolved by the DNS system, so + it can result in more effective apache performance.

    +
    + + +
    Hostname
    +
    +

    A Hostname is a fully qualified DNS domain name which can + be resolved to one or more IPAddrs via the + DNS domain name service. It represents a logical host (in contrast to + Domains, see above) and must be resolvable + to at least one IPAddr (or often to a list + of hosts with different IPAddrs).

    + + Examples + prep.ai.mit.edu
    + www.apache.org +
    + + Note +

    In many situations, it is more effective to specify an IPAddr in place of a Hostname since a + DNS lookup can be avoided. Name resolution in Apache can take a remarkable + deal of time when the connection to the name server uses a slow PPP + link.

    +

    Hostname comparisons are done without regard to the case, + and Hostnames are always assumed to be anchored in the root + of the DNS tree, therefore two hosts WWW.MyDomain.com + and www.mydomain.com. (note the trailing period) are + considered equal.

    +
    +
    +
    +DNS Issues +
    + + +ProxyTimeout +Network timeout for proxied requests +ProxyTimeout seconds +ProxyTimeout 300 +server configvirtual host + +Available in Apache 2.0.31 and later + + +

    This directive allows a user to specifiy a timeout on proxy requests. + This is useful when you have a slow/buggy appserver which hangs, and you + would rather just return a timeout and fail gracefully instead of waiting + however long it takes the server to return.

    +
    +
    + + +ProxyDomain +Default domain name for proxied requests +ProxyDomain Domain +server configvirtual host + + + +

    This directive is only useful for Apache proxy servers within + intranets. The ProxyDomain directive specifies + the default domain which the apache proxy server will belong to. If a + request to a host without a domain name is encountered, a redirection + response to the same host with the configured Domain appended + will be generated.

    + + Example + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21
    + ProxyDomain .mycompany.com +
    +
    +
    + + +ProxyVia +Information provided in the Via HTTP response +header for proxied requests +ProxyVia On|Off|Full|Block +ProxyVia Off +server configvirtual host + + + +

    This directive controls the use of the Via: HTTP + header by the proxy. Its intended use is to control the flow of + proxy requests along a chain of proxy servers. See RFC 2616 (HTTP/1.1), section + 14.45 for an explanation of Via: header lines.

    + +
      +
    • If set to Off, which is the default, no special processing + is performed. If a request or reply contains a Via: header, + it is passed through unchanged.
    • + +
    • If set to On, each request and reply will get a + Via: header line added for the current host.
    • + +
    • If set to Full, each generated Via: header + line will additionally have the Apache server version shown as a + Via: comment field.
    • + +
    • If set to Block, every proxy request will have all its + Via: header lines removed. No new Via: header will + be generated.
    • +
    +
    +
    + + +ProxyErrorOverride +Override error pages for proxied content +ProxyErrorOverride On|Off +ProxyErrorOverride Off +server configvirtual host + +Available in version 2.0 and later + + +

    This directive is useful for reverse-proxy setups, where you want to + have a common look and feel on the error pages seen by the end user. + This also allows for included files (via + mod_include's SSI) to get + the error code and act accordingly (default behavior would display + the error page of the proxied server, turning this on shows the SSI + Error message).

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_proxy.xml.ja b/trunk/docs/manual/mod/mod_proxy.xml.ja new file mode 100644 index 0000000000..c584b3ad7b --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.xml.ja @@ -0,0 +1,1193 @@ + + + + + + + + + +mod_proxy +HTTP/1.1 $B%W%m%-%7(B/$B%2!<%H%&%'%$%5!<%P(B +Extension +mod_proxy.c +proxy_module + + + $B7Y9p(B +

    $B%5!<%P$r0BA4$K$9$k(B$B$^$G(B ProxyRequests $B$OM-8z$K$7$J$$$G$/$@$5$$!#(B + $B%*!<%W%s%W%m%-%7%5!<%P$O$"$J$?<+?H$N%M%C%H%o!<%/$K$H$C$F$b!"(B + $B%$%s%?!<%M%C%HA4BN$K$H$C$F$b4m81$G$9!#(B

    +
    + +

    $B$3$N%b%8%e!<%k$O(B Apache $B$N%W%m%-%7(B/$B%2!<%H%&%'%$5!G=$rAJP13 (Apache JServe Protocol version 1.3), + FTP, CONNECT (SSL $BMQ(B), + HTTP/0.9, HTTP/1.0, HTTP/1.1 + $B$N%W%m%-%75!G=$r$N%W%m%H%3%kMQ$N(B + $B%W%m%-%75!G=$r;}$C$?!"B>$N%b%8%e!<%k$K@\B3$9$k$h$&$K$b@_Dj$G$-$^$9!#(B

    + +

    Apache $B$N%W%m%-%75!G=$O(B mod_proxy $B$NB>$K!"(B + $B$$$/$D$+$N%b%8%e!<%k$KJ,3d$5$l$F$$$^$9(B: + mod_proxy_http, mod_proxy_ftp, + mod_proxy_ajp, mod_proxy_balancer, + mod_proxy_connect $B$G$9!#$G$9$+$i!"(B + $BFCDj$N%W%m%-%7$N5!G=$r;H$$$?$$>l9g$O!"(Bmod_proxy $B$H(B + $B3:Ev$9$k%b%8%e!<%k$r%5!<%P$K(B ($B%3%s%Q%$%k;~$K@EE*$K9T$J$&$+(B + LoadModule $B$GF0E*$KFI$_9~$`$+$7$F(B) + $BAH$_9~$`I,MW$,$"$j$^$9!#(B

    + +

    $B$3$l$K2C$($F!"B>$N%b%8%e!<%k$K$h$C$F3HD%5!G=$,Ds6!$5$l$F$$$^$9!#(B + $B%-%c%C%7%e$O(B mod_cache $B$H4XO"%b%8%e!<%k$G(B + $BDs6!$5$l$F$$$^$9!#(BSSL/TLS $B$G1s3V%5!<%P$K@\B3$9$k5!G=$O(B + mod_ssl $B$N(B SSLProxy* $B%G%#%l%/%F%#%V$G(B + $BDs6!$5$l$F$$$^$9!#$3$l$i$N5!G=$rMxMQ$9$k$?$a$K$O!"3:Ev$9$k%b%8%e!<%k$r(B + $BAH$_9~$s$G@_Dj$7$J$1$l$P$J$j$^$;$s!#(B

    +
    +mod_cache +mod_proxy_http +mod_proxy_ftp +mod_proxy_connect +mod_proxy_balancer +mod_ssl + +
    $B%U%)%o!<%I%W%m%-%7$H%j%P!<%9%W%m%-%7(B +

    Apache $B$O(B$B%U%)%o!<%I(B$B%W%m%-%7$H$7$F$b!"(B + $B%j%P!<%9(B$B%W%m%-%7$H$7$F$b@_Dj$9$k$3$H$,$G$-$^$9!#(B

    + +

    $BDL>o$N(B$B%U%)%o!<%I%W%m%-%7(B$B$O%/%i%$%"%s%H$H(B + $B%*%j%8%s%5!<%P(B $B%3%s%F%s%D@8@.85$N%5!<%P(B + $B$N4V$K0LCV$9$kCf4V%5!<%P$G$9!#(B + $B%*%j%8%s%5!<%P$+$i%3%s%F%s%D$r$N%5%$%H$K%U%)%o!<%I%W%m%/%77PM3$G%"%/%;%9$9$k$K$O!"(B + $BFCJL$K$=$lMQ$N@_Dj$r$7$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B%U%)%o!<%I%W%m%-%7$N0lHLE*$J;HMQJ}K!$O!"%U%!%$%"%&%)!<%k$K$h$C$F(B + $B@)8B$5$l$F$$$kFbIt$N%/%i%$%"%s%H$K%$%s%?!<%M%C%H$X$N%"%/%;%9$r(B + $BDs6!$9$k$b$N$G$9!#%U%)%o!<%I%W%m%-%7$O%M%C%H%o!<%/$N;HMQNL$r(B + $B8:$i$9$?$a$K(B (mod_cache $B$GDs6!$5$l$F$$$k(B) + $B%-%c%C%7%e5!G=$rMQ$$$k$3$H$b$G$-$^$9!#(B

    + +

    $B%U%)%o!<%I%W%m%-%7$O(B ProxyRequests $B%G%#%l%/%F%#%V$G(B + $BM-8z$K$J$j$^$9!#%U%)%o!<%I%W%m%-%7$G$O!"%/%i%$%"%s%H$OK\Ev$N?H85$r(B + $B1#$7$FG$0U$N%5%$%H$K%"%/%;%9$G$-$k$h$&$K$J$k$?$a!"%U%)%o!<%I%W%m%-%7$r(B + $BM-8z$K$9$kA0$K!">5G'$5$l$?%/%i%$%"%s%H$N$_$,%W%m%-%7$K%"%/%;%9$G$-$k$h$&$K(B + $B%5!<%P$r0BA4$K$9$k(B$B$3$H$,=EMW$G$9!#(B

    + +

    $B0lJ}(B$B%j%P!<%9%W%m%-%7(B$B$O!"%/%i%$%"%s%H$K$OIaDL$N(B + $B%&%'%V%5!<%P$N$h$&$K8+$($^$9!#%/%i%$%"%s%HB&$KFCJL$J@_Dj$OI,MW$"$j$^$;$s!#(B + $B%/%i%$%"%s%H$O%j%P!<%9%W%m%-%7$NL>A06u4V$KBP$7$FDL>o$N%3%s%F%s%D$X$N(B + $B%j%/%(%9%H$r9T$J$$$^$9!#%W%m%-%7$O%j%/%(%9%H$r$I$3$KAw$l$PNI$$$+$rH=Dj$7!"(B + $B$"$?$+$b<+J,<+?H$,%*%j%8%s%5!<%P$G$"$C$?$+$N$h$&$K%/%i%$%"%s%H$K(B + $B%3%s%F%s%D$rJV$7$^$9!#(B

    + +

    $B%j%P!<%9%W%m%-%7$N$h$/$"$kMxMQJ}K!$O!"%$%s%?!<%M%C%H%f!<%6$K(B + $B%U%!%$%"%&%)!<%k$NCf$K$"$k%5!<%P$K%"%/%;%9$rM?$($k$H$$$&$b$N$G$9!#(B + $B%j%P!<%9%W%m%-%7$OJ#?t$N%P%C%/%(%s%I%5!<%P$XIi2YJ,;6$r$9$k$?$a$K(B + $B;H$C$?$j!"CY$$%P%C%/%(%s%I%(%s%I%5!<%P$N$?$a$K%-%c%C%7%e5!G=$rDs6!$7$?$j(B + $B$9$k$?$a$K;H$($^$9!#$^$?!"%j%P!<%9%W%m%-%7$OJ#?t$N%5!<%P$r(B + $BF1$8(B URL $B6u4V$K$^$H$a$k$?$a$K;H$&$3$H$b$G$-$^$9!#(B

    + +

    $B%j%P!<%9%W%m%-%7$O(B ProxyPass $B%G%#%l%/%F%#%V$d(B + RewriteRule $B%G%#%l%/%F%#%V$N(B + [P] $B%U%i%0$r;H$&$3$H$GM-8z$K$J$j$^$9!#%j%P!<%9%W%m%-%7$N(B + $B@_Dj$N$?$a$K(B ProxyRequests $B$r@_Dj$9$kI,MW$O(B + $B$"$j$^$;$s(B$B!#(B

    +
    + +
    $B4pK\$NNc(B + +

    $B0J2<$NNc$O$l$N@bL@$r$*FI$_$/$@$5$$!#(B

    + +

    $B$^$?%-%c%C%7%e5!G=$rM-8z$K$7$?$$>l9g$O!"(Bmod_cache + $B$N@bL@$rFI$s$G$/$@$5$$!#(B

    + + $B%U%)%o!<%I%W%m%-%7(B + ProxyRequests On
    + ProxyVia On
    +
    + <Proxy *>
    + + Order deny,allow
    + Deny from all
    + Allow from internal.example.com
    +
    + </Proxy> +
    + + $B%j%P!<%9%W%m%-%7(B + ProxyRequests Off
    +
    + <Proxy *>
    + + Order deny,allow
    + Allow from all
    +
    + </Proxy>
    +
    + ProxyPass /foo http://foo.example.com/bar
    + ProxyPassReverse /foo http://foo.example.com/bar +
    +
    + + +
    $B%W%m%-%7$X$N%"%/%;%9@)8f(B +

    $B%W%m%-%7$N%"%/%;%9$O0J2<$N$h$&$K(B Proxy $B%3%s%F%J$NCf$K(B + $B%G%#%l%/%F%#%V$r=q$/$3$H$G@)8f$G$-$^$9(B:

    + + + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from 192.168.0
    +
    + </Proxy> +
    + +

    $B%"%/%;%9@)8f$N$?$a$N%G%#%l%/%F%#%V$N$h$j>\$7$$>pJs$O(B + mod_authz_host $B$r$*FI$_$/$@$5$$!#(B

    + +

    (ProxyRequests $B%G%#%l%/%F%#%V$r(B + $B;H$C$F(B) $B%U%)%o!<%I%W%m%-%7$r@_Dj$7$F$$$k>l9g$O!"87$7$/%"%/%;%9(B + $B@)8B$r9T$J$&$3$H$,Hs>o$KBg@Z$G$9!#$=$&$7$J$$$H!"G$0U$N%/%i%$%"%s%H$,(B + $B?H85$rL@$+$9$3$H$J$/G$0U$N%[%9%H$K%"%/%;%9$9$k$?$a$K%5!<%P$r;H$&$3$H$,(B + $B$G$-$F$7$^$$$^$9!#$3$l$O$"$J$?<+?H$N%M%C%H%o!<%/$K$H$C$F$b!"%$%s%?!<%M%C%H(B + $BA4BN$K$H$C$F$b4m81$J$3$H$G$9!#(B(ProxyRequests Off $B$K$7$F(B + ProxyPass $B%G%#%l%/%F%#%V$r;H$C$F(B) + $B%j%P!<%9%W%m%-%7$r;H$C$F$$$k>l9g$K$O!"%/%i%$%"%s%H$O$"$J$?$,L@<(E*$K(B + $B@_Dj$7$?%[%9%H$K$7$+%"%/%;%9$G$-$J$$$?$a!"%U%)%o!<%I%W%m%-%7$N$H$-(B + $B$[$I%"%/%;%9@)8f$KNO$rCm$,$J$/$F$bBg>fIW$G$9!#(B

    + +
    + +
    FTP $B%W%m%-%7(B + + +
    $B$I$&$7$F%U%!%$%k%?%$%W$,(B <var>xxx</var> + $B$N%U%!%$%k$r(B FTP $B$G%@%&%s%m!<%I$G$-$J$$$N(B? +

    $B$*$=$i$/!"%W%m%-%7$N(B mime.types $B@_Dj%U%!%$%k$G$=$N%U%!%$%k%?%$%W$,(B + application/octet-stream $B$G$"$k$HDj5A$5$l$F$$$J$$$N$G$7$g$&!#(B + $B0J2<$N$h$&$J$b$N$,Lr$KN)$D$+$b$7$l$^$;$s(B:

    + + +
    application/octet-stream   bin dms lha lzh exe class tgz taz
    +
    +

    $BJL$NJ}K!$H$7$F!"$9$Y$F$N%G%U%)%k%H$r%P%$%J%j$K$9$k$3$H$b$G$-$^$9(B:

    + +
    DefaultType application/octet-stream
    +
    +
    + +
    $B%U%!%$%k(B <var>xxx</var> $B$r(B FTP $B$N(B ASCII $B%@%&%s%m!<%I(B + $B$K$5$;$k$N$O$I$&$9$l$P$h$$$N(B? +

    $B$^$l$K!"(B($B%G%U%)%k%H$NE>Aw$O(B binary $B%b!<%I$G(B) $BFCDj$N(B + $B%U%!%$%k$N$_(B FTP $B$N(B ASCII $BE>AwJ}K!$r;H$o$J$1$l$P$J$i$J$$(B + $B>l9g$K$O!"%j%/%(%9%H$N:G8e$K(B ;type=a $B$rIU$1$k$3$H$G(B + mod_proxy $B$K(B ASCII $BE>Aw$r$5$;$k$3$H$,$G$-$^$9!#(B + ($B$?$@$7!"(BFTP $B$N%G%#%l%/%H%j0lMw$O>o$K(B ASCII $B%b!<%I$G9T$J$o$l$^$9!#(B)

    +
    + +
    FTP $B$N%"%C%W%m!<%I$O$I$&$9$l$P$h$$$N(B? +

    $B8=;~E@$G$O!"(Bmod_proxy $B$N(B FTP $B%5%]!<%H$O(B GET $B$N$_$G$9!#$b$A$m$s(B + Apache $B$N(B $B%W%m%-%7$r;H$C$F(B HTTP $B$N%"%C%W%m!<%I(B (POST $B$d(B PUT) $B$r(B + $B$9$k$3$H$O$G$-$^$9!#(B

    +
    + +
    $B%[!<%`%G%#%l%/%H%j$N30$N(B FTP $B%U%!%$%k$K(B + $B%"%/%;%9$9$k$K$O$I$&$9$l$P$h$$$N(B? +

    FTP URI $B$O%m%0%$%s$7$F$$$k%f!<%6$N%[!<%`%G%#%l%/%H%j$+$i$N(B + $BAjBP%Q%9$H$7$F07$o$l$^$9!#;DG0$J$3$H$K!"(B/../ $B$O%V%i%&%6$K$h$j2re0L$N%G%#%l%/%H%j$K(B + $BE~C#$9$k$3$H$O$G$-$^$;$s!#$3$NLdBj$r2r7h$9$k$?$a$K!"$$$o$f$k(B + Squid %2f $B%O%C%/(B $B$r(B Apache $B$N(B FTP $B%W%m%-%7$OSquid Proxy $B%-%c%C%7%e(B $B$N$h$&$J(B + $BB>$N$h$/;H$o$l$F$$$k%W%m%-%7%5!<%P$G$b/%2f $B$rIU$1$k$3$H$G!"%W%m%-%7$K(B + FTP $B$N3+;O%G%#%l%/%H%j$r(B ($B%[!<%`%G%#%l%/%H%j$NBe$o$j$K(B) / + $B$KJQ$($k$3$H$,$G$-$^$9!#Nc$($P!"(B/etc/motd $B$r + + + ftp://user@host/%2f/etc/motd + +

    + +
    $B%V%i%&%6$N(B URL $BI=<($G(B FTP $B$NJ?J8%Q%9%o!<%I$r(B + $B1#$9$K$O$I$&$9$l$P$h$$$N(B? +

    FTP $B%5!<%P$K%f!<%6L>$H%Q%9%o!<%I$r;H$C$F%m%0%$%s$9$k$?$a$K!"(B + Apache $B$O0[$J$kJ}K!$r;H$$$^$9!#(BURL $B$K%f!<%6L>$H%Q%9%o!<%I$,$^$C$?$/(B + $B$J$$>l9g$O!"(BApache $B$O(B FTP $B%5!<%P$K(B anonymous $B%m%0%$%s$rAw$j$^$9!#(B + $B$D$^$j(B$B!"(B

    + + + user: anonymous
    + password: apache_proxy@ +
    + +

    $B$3$l$O(B anonymous $B%"%/%;%9$,@_Dj$5$l$?(B + $B$9$Y$F$N(B FTP $B%5!<%P$KBP$7$FF0:n$7$^$9!#(B

    + +

    $B%f!<%6L>$r;H$C$?8D?MJL$N%m%0%$%s$K$O!"(BURL $B$K%f!<%6L>$rF~$l$k$3$H$,(B + $B$G$-$^$9(B:

    + + + ftp://username@host/myfile + + +

    $B$3$N%f!<%6L>$,M?$($i$l$?$H$-$K!"(BFTP $B%5!<%P$,%Q%9%o!<%I$rMW5a$9$l$P(B + ($B$b$A$m$s$=$&$9$Y$-$J$N$G$9$,(B)$B!"(BApache $B$O(B 401 + (Authorization required) $B$rJV$7$^$9!#$3$l$K$h$j!"%V%i%&%6$O%f!<%6L>(B + $B%Q%9%o!<%I$NF~NO%@%$%"%m%0$rI=<($7$^$9!#%Q%9%o!<%I$,F~NO$5$l$?8e!"(B + $B:F$S@\B3$r;n$_!"@.8y$9$l$P%j%/%(%9%H$7$?%j%=!<%9$,I=<($5$l$^$9!#(B + $B$3$NJ}K!$NMxE@$O%V%i%&%6$,%Q%9%o!<%I$rJ?J8$GI=<($7$J$$$3$H$G$9!#(B + ($B$b$7:G=i$+$i(B

    + + + ftp://username:password@host/myfile + + +

    $B$HF~NO$7$?>l9g$K$OI=<($5$l$F$7$^$$$^$9!#(B)

    + + $BCm(B +

    $BAw?.$5$l$k%Q%9%o!<%I$O!"0E9f2=$5$l$FAw$i$l$k$o$1$G$O$"$j$^$;$s!#(B + $B%V%i%&%6$H(B Apache $B%W%m%-%7%5!<%P$O(B base64 $B$GId9f2=$5$l$?(B + $BJ8;zNs$H$7$F!"(BApache $B%W%m%-%7$H(B FTP $B%5!<%P$N4V$OJ?J8$H$7$FAw$i$l$^$9!#(B + $B$G$9$+$i!"(BHTTP $B$r;H$C$F(B HTTP $B$r%"%/%;%9$9$kA0(B ($B$b$7$/$O!"$=$b$=$b(B + $B8D?ME*$J%U%!%$%k$r(B FTP $B$G%"%/%;%9$9$kA0(B) $B$K$h$/9M$($kI,MW$,$"$j$^$9!#(B + $B0BA4$G$J$$DL?.O)$r;H$C$?>l9g$O!"EpD0 + +

    +
    +
    $BCY$$5/F0(B +

    ProxyBlock $B%G%#%l%/%F%#%V$r;H$C$F$$$k>l9g!"(B + $B8e$N%F%9%H$N$?$a$K5/F0;~$K%[%9%H$N(B + IP $B%"%I%l%9$,D4$Y$i$l$F%-%c%C%7%e$5$l$^$9!#%[%9%HL>$N%k%C%/%"%C%W$N(B + $BB.$5$K$h$C$F$O!"?tIC(B ($B$+$=$l0J>e(B) $B$+$+$k$+$b$7$l$^$;$s!#(B

    +
    + +
    $B%$%s%H%i%M%C%H%W%m%-%7(B +

    $B%$%s%H%i%M%C%H$K$"$k(B Apache $B%W%m%-%7%5!<%P$O30It$X$N%j%/%(%9%H$r(B + $B2qscheme $B$K$D$$$F$=$l$>$l!"%U%!%$%"%&%)!<%k$N(B + $B%W%m%-%7$K%U%)%o!<%I$5$l$k$h$&$K(B + ProxyRemote $B%G%#%l%/%F%#%V$r(B + $B@_Dj$7$F$/$@$5$$(B)$B!#$7$+$7%$%s%H%i%M%C%HFb$N%j%=!<%9$K%"%/%;%9$9$k$H$-$O!"(B + $B%U%!%$%"%&%)!<%k$rDL$5$J$$$G$b%"%/%;%9$G$-$^$9!#(B + $B$I$N%[%9%H$,%$%s%H%i%M%C%H$KB0$7!"D>@\%"%/%;%9$9$Y$-$+$r;XDj$9$k$K$O!"(B + NoProxy $B%G%#%l%/%F%#%V$,(B + $BLr$KN)$A$^$9!#(B

    + +

    $B%$%s%H%i%M%C%HFb$N%f!<%6$O(B WWW $B$N%j%/%(%9%H$G%m!<%+%k%I%a%$%s$r(B + $B>JN,$9$k$3$H$,$h$/$"$j$^$9!#(Bhttp://somehost.example.com/ + $B$H$$$&%j%/%(%9%H$NBe$o$j$K(B "http://somehost/" $B$r%j%/%(%9%H$7$?$j$7$^$9!#(B + $B$3$N$h$&$J%j%/%(%9%H$r&MQ%W%m%-%7%5!<%P$NCf$K$O$"$j$^$9!#(B + $B%5!<%P$,(B $B%W%m%-%7$N%5!<%S%9MQ$K@_Dj$5$l$F$$$F(B + ProxyDomain $B%G%#%l%/%F%#%V$,(B + $B;HMQ$5$l$?>l9g$K$O!"(BApache $B$O%/%i%$%"%s%H$K%j%@%$%l%/%H1~Ez$rAw$C$F!"(B + $B@5$7$$!"40A4$J(B (fully qualified) + $B%5!<%P$N%"%I%l%9$KAw$k$3$H$,$G$-$^$9!#$3$N$h$&$K(B + $B%j%@%$%l%/%H$9$k$H!"%f!<%6$N%V%C%/%^!<%/$,@5$7$$40A4$J%[%9%HL>$r4^$`(B + $B$3$H$K$b$J$k$?$a!"$h$j9%$^$7$$J}K!$H8@$($k$G$7$g$&!#(B

    +
    + +
    $B%W%m%H%3%k$ND4@0(B +

    Keepalive $B$d(B HTTP/1.1 $B$rE,@Z$Ku67$G!"(BHTTP/1.0 $B$G(B keepalive $B$rL5$7$K$7$F%j%/%(%9%H$rAw$k$?$a$N(B + $B4D6-JQ?t$,Fs$D$"$j$^$9!#$3$l$i$O(B SetEnv $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#(B

    + +

    force-proxy-request-1.0 $B$H(B proxy-nokeepalive + $B$,$=$N4D6-JQ?t$G$9!#(B

    + + + <Location /buggyappserver/>
    + + ProxyPass http://buggyappserver:7001/foo/
    + SetEnv force-proxy-request-1.0 1
    + SetEnv proxy-nokeepalive 1
    +
    + </Location> +
    +
    + + +Proxy +$B%W%m%-%7$5$l$k%j%=!<%9$KE,MQ$5$l$k%3%s%F%J(B +<Proxy wildcard-url> ...</Proxy> +server configvirtual host + + + +

    Proxy $B%;%/%7%g%sCf$N(B + $B%G%#%l%/%F%#%V$O%^%C%A$9$k%W%m%-%7$5$l$k%3%s%F%s%D$K$N$_E,MQ$5$l$^$9!#(B + $B%7%'%k7A<0$N%o%$%k%I%+!<%I$,;H$($^$9!#(B

    + +

    $BNc$($P!"yournetwork.example.com $B$N(B + $B%[%9%H$K$N$_%W%m%-%7%5!<%P$r7PM3$7$?%"%/%;%9$r5v2D$7$^$9(B:

    + + + <Proxy *>
    + + Order Deny,Allow
    + Deny from all
    + Allow from yournetwork.example.com
    +
    + </Proxy> +
    + +

    $Bexample.com $B$N(B foo $B%G%#%l%/%H%j$N(B + $B$9$Y$F$N%U%!%$%k$KBP$7$F!"%W%m%-%7%5!<%P$rDL$7$FAw$i$l$?$H$-$K$O(B + INCLUDES $B%U%#%k%?$rDL$7$FAw$k$h$&$K@_Dj$7$^$9(B:

    + + + <Proxy http://example.com/foo/*>
    + + SetOutputFilter INCLUDES
    +
    + </Proxy> +
    + + +
    +
    + + +ProxyBadHeader +$B1~Ez$K$*$+$7$J%X%C%@$,$"$k>l9g$N07$$J}$r7h$a$k(B +ProxyBadHeader IsError|Ignore|StartBody +ProxyBadHeader IsError +server configvirtual host + +2.0.44 $B0J9_(B + + +

    ProxyBadHeader $B%G%#%l%/%F%#%V$O9=J8E*$K(B + $B4V0c$C$?%X%C%@(B ($B$D$^$j(B $B%3%m%s$r4^$^$J$$$b$N(B) $B$rmod_proxy $B$,$I$&?6$kIq$&$+$r7h$a$^$9!#0J2<$N0z?t$r(B + $B + +

    +
    IsError
    +
    $B%j%/%(%9%H$rCf;_$7$F(B 502 (Bad Gateway) $B1~Ez$rJV$9!#(B + $B$3$l$,%G%U%)%k%H$NF0:n$G$9!#(B
    + +
    Ignore
    +
    $B4V0c$C$?%X%C%@9T$r$=$b$=$bB8:_$7$J$+$C$?$b$N$H$7$F07$&!#(B
    + +
    StartBody
    +
    $B4V0c$C$?%X%C%@9T$r +
    +
    +
    + + +ProxyMatch +$B@55,I=8=$G$N%^%C%A$K$h$k%W%m%-%7%j%=!<%9MQ$N%G%#%l%/%F%#%V%3%s%F%J(B +<ProxyMatch regex> ...</ProxyMatch> +server configvirtual host + + + +

    ProxyMatch $B$O(B URL $B$N%^%C%A$K(B + $B@55,I=8=$rMQ$$$k$3$H$r=|$$$F(B Proxy $B%G%#%l%/%F%#%V$HF1$8$G$9!#(B

    +
    +
    + + +ProxyPreserveHost +$B%W%m%-%7%j%/%(%9%H$K!" +ProxyPreserveHost On|Off +ProxyPreserveHost Off +server configvirtual host + +Apache 2.0.31 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%*%W%7%g%s$,M-8z$K$J$C$F$$$k>l9g!"(BProxyPass + $B$G;XDj$7$?%[%9%HL>$NBe$o$j$K!" + +

    $B$3$N%*%W%7%g%s$ODL>o$O(B Off $B$K@_Dj$7$F$/$@$5$$!#(B + $B$[$H$s$I$N>l9g!"$3$l$OBgNL$NL>A0%Y!<%9$N%P!<%A%c%k%[%9%F%#%s%0$r9T$J$C$F$$$F!"(B + $B85!9$N(B Host $B%X%C%@$r%P%C%/%(%s%I%5!<%P$,2rl9g$K$N$_M-MQ$G$9!#(B

    +
    +
    + + +ProxyRequests +$B%U%)%o!<%I(B ($BI8=`$N(B) $B%W%m%-%7%j%/%(%9%H$rM-8z$K$9$k(B +ProxyRequests On|Off +ProxyRequests Off +server configvirtual host + + + +

    $B$3$l$O(B Apache $B$N%U%)%o!<%I%W%m%-%7%5!<%P$H$7$F$NF0:n$r(B + $BM-8z$b$7$/$OL58z$K$7$^$9!#(B(ProxyRequests $B$r(B Off $B$K(B + $B@_Dj$7$F$b!"(BProxyPass + $B$N@_Dj$OL58z$K$J$j$^$;$s!#(B)

    + +

    $BDL>o$N%j%P!<%9%W%m%-%7$N@_Dj$G$O!"$3$N%*%W%7%g%s$O(B Off + $B$K@_Dj$7$F$/$@$5$$!#(B

    + +

    HTTP $B$d(B FTP $B%5%$%H$X$N%W%m%-%7$N5!G=$rM-8z$K$7$?$$>l9g$O!"(B + mod_proxy_http $B$d(B mod_proxy_ftp $B$,(B + $B%5!<%P$KAH$_9~$^$l$F$$$J$1$l$P$J$j$^$;$s!#(B

    + + $B7Y9p(B +

    $B%5!<%P$r0BA4$K$9$k(B$B$^$G(B ProxyRequests $B$OM-8z$K$7$J$$$G$/$@$5$$!#(B + $B%*!<%W%s%W%m%-%7%5!<%P$O$"$J$?<+?H$N%M%C%H%o!<%/$K$H$C$F$b!"(B + $B%$%s%?!<%M%C%HA4BN$K$H$C$F$b4m81$G$9!#(B

    +
    +
    +
    + + +ProxyRemote +$BFCDj$N%j%/%(%9%H$r07$&;~$K;H$o$l$k%j%b!<%H%W%m%-%7$r;XDj$9$k(B +ProxyRemote match remote-server +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O$3$N%W%m%-%7$KBP$9$k%j%b!<%H%W%m%-%7$rDj5A$7$^$9!#(B + match $B$O%j%b!<%H%5!<%P$,%5%]!<%H$9$k(B URL $B%9%-!<%`!"(B + $B%j%b!<%H%5!<%P$,;H$&$O$:$N(B URL $B$N0lItJ,!"%5!<%P$,$9$Y$F$N(B + $B%j%/%(%9%H$K;H$o$l$k$3$H$r<($9(B * $B$N$I$l$+$K$J$j$^$9!#(B + remote-server $B$O%j%b!<%H%5!<%P$NItJ,(B URL $B$G$9!#9=J8(B:

    + + + remote-server = + scheme://hostname[:port] + + +

    scheme $B$Oe%j%b!<%H%5!<%P$H$NDL?.$K;H$o$l$k%W%m%H%3%k$r(B + $B7hDj$7$^$9!#$3$N%b%8%e!<%k$G$O(B http $B$@$1$,%5%]!<%H$5$l$F(B + $B$$$^$9!#(B

    + + $BNc(B + ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000
    + ProxyRemote * http://cleversite.com
    + ProxyRemote ftp http://ftpproxy.mydomain.com:8080 +
    + +

    $B$3$NNc$G$O!"%W%m%-%7$O(B FTP $B%j%/%(%9%H$rJL$N(B HTTP $B%j%/%(%9%H$GJq$s$G(B + $B$=$N$h$&$J%j%/%(%9%H$r07$($kJL$N%W%m%-%7$KE>Aw$7$^$9!#(B

    + +

    $B$3$N%*%W%7%g%s$O%j%P!<%9%W%m%-%7$N@_Dj$b%5%]!<%H$7$^$9!#(B + $B%5!<%P$,JL$N%U%)%o!<%I%W%m%-%7$N8e$m$K1#$5$l$F$$$k>l9g$G$b(B + $B%P%C%/%(%s%I%&%'%V%5!<%P$r%P!<%A%c%k%[%9%H$N(B URL $B6u4V$KF~$l$k$3$H$,(B + $B$G$-$^$9!#(B

    +
    +
    + + +ProxyRemoteMatch +$B@55,I=8=$G$N%^%C%A$K$h$k%j%/%(%9%H$r07$&%j%b!<%H%W%m%-%7$N;XDj(B +ProxyRemoteMatch regex remote-server +server configvirtual host + + + +

    ProxyRemoteMatch $B$O:G=i$N0z?t$,%j%/%(%9%H$5$l$?(B + URL $B$K%^%C%A$9$k@55,I=8=$G$"$k$3$H$r=|$1$P(B ProxyRemote $B%G%#%l%/%F%#%V$HF1$8$G$9!#(B

    +
    +
    + + +ProxyPass +$B%j%b!<%H%5!<%P$r%m!<%+%k%5!<%P$N(B URL $B6u4V$K%^%C%W$9$k(B +ProxyPass [path] !|url [key=value key=value ...]] +server configvirtual host +directory + + + +

    $B$3$N%G%#%l%/%F%#%V$O%j%b!<%H%5!<%P$r%m!<%+%k%5!<%P$NL>A06u4V$K(B + $B%^%C%W$G$-$k$h$&$K$7$^$9!#%m!<%+%k%5!<%P$ODL>o$N0UL#$G$N%W%m%-%7$H(B + $B$7$F$OF0:n$;$:!"%j%b!<%H%5!<%P$N%_%i!<$H$7$F?6$kIq$$$^$9!#(B + path $B$O%m!<%+%k$N2>A[%Q%9$NL>A0$G$9!#(Burl $B$O(B + $B%j%b!<%H%5!<%P$NItJ,(B URL $B$K$J$j!"%/%(%j! + + ProxyPass $B%G%#%l%/%F%#%V$r(B + $B;H$C$F$$$k$H$-$O(B ProxyRequests $B%G%#%l%/%F%#%V$ODL>o$O(B + off $B$K@_Dj$5$l$F$$$k$Y$-$G$9!#(B + +

    $B%m!<%+%k%5!<%P$N%"%I%l%9$,(B http://example.com/ $B$G$"$k$H(B + $B$7$^$9!#$9$k$H!"(B

    + + + ProxyPass /mirror/foo/ http://backend.example.com/ + + +

    $B$H@_Dj$9$k$H(B http://example.com/mirror/foo/bar $B$X$N(B + $B%j%/%(%9%H$,FbItE*$K(B http://backend.example.com/bar $B$X$N(B + $B%W%m%-%7%j%/%(%9%H$KJQ49$5$l$k$3$H$K$J$j$^$9!#(B

    + +

    $B%5%V%G%#%l%/%H%j$r%j%P!<%9%W%m%-%7$7$?$/$J$$$H$-$K(B ! $B$O(B + $BLr$KN)$A$^$9!#(B$BNc$($P(B$B!"(B

    + + + ProxyPass /mirror/foo/i !
    + ProxyPass /mirror/foo http://backend.example.com +
    + +

    $B$O(B /mirror/foo/i $B$r(B$B=|$/(B + /mirror/foo $B$X$N$9$Y$F$N%j%/%(%9%H$r(B + backend.example.com $B$K%W%m%-%7$7$^$9!#(B

    + + $BCm(B +

    $B=gHV$O=EMW$G$9!#0lHLE*$J(B ProxyPass + $B%G%#%l%/%F%#%V$N(B$BA0$K(B + $B=|30%G%#%l%/%F%#%V$rCV$/I,MW$,$"$j$^$9!#(B

    +
    + +

    2.1 $B$N?75!G=$G!"%P%C%/%(%s%I%5!<%P$H$N@\B3$K%W!<%k$5$l$?%3%M%/%7%g%s$r(B + $B;H$($k$h$&$K$J$j$^$7$?!#(Bkey=value $B7A<0$N%Q%i%a!<%?$G(B + $B$3$N%3%M%/%7%g%s%W!<%j%s%0$ND4@0$,$G$-$^$9!#(BHard Maximum + $B$N%G%U%)%k%HCM$O!"M-8z$K$J$C$F$$$k(B MPM $B$G$N%W%m%;%9Ev$?$j$N%9%l%C%I?t$H(B + $BF1$8?t$N%3%M%/%7%g%s?t$G$9!#(Bprefork MPM $B$G$ODL>o$O(B 1 $B$G!"(Bworker MPM $B$G$O(B + ThreadsPerChild $B$GD4@0$5$l$^$9!#(B

    + +

    min $B$N@_Dj$G!"%P%C%/%(%s%I%5!<%P$H$N4V$K2?K\$N%3%M%/%7%g%s$r(B + $B>o;~3+$/$+$,7h$^$j$^$9!#(BSoft Maximum smax $B$N?t$K(B + $BC#$9$k$^$GI,MW$K1~$8$F%3%M%/%7%g%s$O@8@.$5$l$^$9!#(Bsmax + $B$rD6$($??t$N%3%M%/%7%g%s$O!"@8B8;~4V(B ttl $B$G@ZCG$5$l$^$9!#(B + $B%P%C%/%(%s%I%5!<%P$H(B Hard Maximum max $B$N?t0J>e$N%3%M%/%7%g%s$r(B + $B@8@.$9$k$3$H$O$"$j$^$;$s!#(B

    + + + ProxyPass /example http://backend.example.com smax=5 max=20 ttl=120 retry=300 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%Q%i%a!<%?(B$B%G%U%)%k%HCM(B$B@bL@(B
    min0$B%P%C%/%(%s%I%5!<%P$H$N@\B3$G(B + $B>o$K3+$$$F$$$k%3%M%/%7%g%s?t$N:G>.CM(B
    max1...n$B%P%C%/%(%s%I%5!<%P$H$N@\B3?t$N(B Hard Maximum + $B%O!<%I%j%_%C%H(B$B!#(B + $B%G%U%)%k%HCM$O!";HMQ$7$F$$$k(B MPM $B$N%W%m%;%9$"$?$j$N%9%l%C%I?t$K$J$C$F$$$^$9!#(B + Prefork MPM $B$G$O>o$K(B 1 $B$G!"(BWorker MPM $B$G$O(B ThreadsPerChild + $B$GD4@a$G$-$^$9!#(BHard Maximum $B0J>e$K%P%C%/%(%s%I%5!<%P$H$N%3%M%/%7%g%s$r(B + $B@8@.$9$k$3$H$O$"$j$^$;$s!#(B
    smaxmax$B@\B3?t$N(B Soft Maximum $B%=%U%H%j%_%C%H(B$B$^$G!"(B + $B%3%M%/%7%g%s$OI,MW$K1~$8$F@8@.$5$l$^$9!#(B + smax $B$rD6$($??t$N%3%M%/%7%g%s$O@8B8;~4V(B ttl + $B$G@ZCG$5$l$^$9!#(B +
    ttl-smax $B?t$rD6$($?Hs3hF0>uBV$N%3%M%/%7%g%s$N@8B8;~4V$r!"(B + $BIC$G;XDj$7$^$9!#$3$N4|4VFb$K;HMQ$5$l$J$+$C$?%3%M%/%7%g%s$O!"(B + $BA4$FJD$8$i$l$^$9!#(B +
    timeoutTimeout$B%3%M%/%7%g%s%?%$%`%"%&%H$rIC$G;XDj$7$^$9!#FC$K;XDj$5$l$J$1$l$P!"(B + $B%U%j!<$J%3%M%/%7%g%s$rmax $B%Q%i%a!<%?$H9g$o$;$F;H$&$3$H$G!"%P%C%/%(%s%I%5!<%P$H$N(B + $B@\B3?t$r@)8f$9$k$N$K;H$$$^$9!#(B +
    acquire-$B@_Dj$9$k$H!"%3%M%/%7%g%s%W!<%k$+$i%U%j!<$N%3%M%/%7%g%s$rl9g$O!"(B + SERVER_BUSY $B%9%F!<%?%9$,%/%i%$%"%s%H$KJV$5$l$^$9!#(B +
    keepaliveOff$B%P%C%/%(%s%I%5!<%P$H(B Apache $B$N4V$K%U%!%$%"!<%&%)!<%k$,$"$k>l9g$K$O!"(B + $B$3$N%Q%i%a!<%?$r;H$C$F$/$@$5$$!#%U%!%$%"%&%)!<%k$O1}!9$K$7$F!"(B + $BHs3hF0>uBV$N%3%M%/%7%g%s$rMn$H$=$&$H$7$^$9!#(B + $B$3$N%U%i%0$O(B OS $B$K;X<($7$F!"(BKEEP_ALIVE $B%a%C%;!<%8$rHs3hF0>uBV$N(B + $B%3%M%/%7%g%s$G$bAw$k$h$&$K$7$^$9(B ($B4V3V$O(B OS $B$N%0%m!<%P%k@_Dj$K0MB8$7!"(B + $BDL>o$O(B 120ms $B4V3V(B) $B!#$3$l$K$h$C$F%U%!%$%"%&%)!<%k$K$h$C$F%3%M%/%7%g%s$,(B + $BMn$H$5$l$k$3$H$rKI$2$^$9!#(Bkeepalive $B$rM-8z$K$9$k$K$O!"$3$N%W%m%Q%F%#$r(B + On $B$K$7$F$/$@$5$$!#(B +
    retry60$B%3%M%/%7%g%s$r%W!<%j%s%0$9$k$?$a$N!"%j%H%i%$$N%?%$%`%"%&%H$rIC$G(B + $B;XDj$7$^$9!#%P%C%/%(%s%I%5!<%P$X$N%3%M%/%7%g%s%W!<%j%s%0$,<:GT$7$?>l9g$O!"(B + $B%?%$%`%"%&%H$N4|4V$,2a$.$k$^$G!"$=$N%5!<%P$K%j%/%(%9%H$r%U%)%o!<%I$7$^$;$s!#(B + $B$3$N5!G=$r;H$&$H!"%P%C%/%(%s%I%5!<%P$r%a%s%F%J%s%9$N$?$a$K%7%c%C%H%@%&%s$7!"(B + $B8e$G%*%s%i%$%s$KI|5"$5$;$k$H$$$C$?$3$H$,$G$-$^$9!#(B +
    loadfactor1$B%o!<%+!<$"$?$j$NIi2Y78?t$G$9!#(BBalancerMember $B$G;H$$$^$9!#(B + 1 $B$+$i(B 100 $B$^$G$N?t;z$G$=$N%o!<%+!<$KBP$9$k@55,2=$5$l$?Ii2YN($r;XDj$7$^$9!#(B +
    route-$B%m!<%I%P%i%s%5$G;H$C$?>l9g!"%o!<%+!<$N%k!<%F%#%s%0$r$7$^$9!#(B + $B%k!<%H$O%;%C%7%g%s(B ID $B$KIU2C$5$l$?CM$K$J$j$^$9!#(B +
    redirect-$B%o!<%+!<$N%j%@%$%l%/%7%g%s7PO)$G$9!#$3$NCM$ODL>o$O!"(B + $B0BA4$K%/%i%9%?$+$i%N!<%I$rl9g$O!"(B + $B$3$NCM$HF1$8%k!<%F%#%s%0%Q%i%a!<%?$r;}$D(B + BalancerMember $B$K%j%@%$%l%/%H$5$l$^$9!#(B +
    + +

    Proxy $B%G%#%l%/%F%#%V$N%9%-!<%`$,(B balancer:// $B$K$J$C$F$$$k>l9g$O!"(B + $B%P%C%/%(%s%I%5!<%P$HA[%o!<%+!<$,@8@.$5$l$^$9!#(B + $B$3$N%o!<%+!<$O4v$D$+$N(B "$BK\J*$N(B" $B%o!<%+!<$N4IM}$r$D$+$5$I$j$^$9!#(B + $B$3$N>l9g%Q%i%a!<%?$O!"$3$N2>A[%o!<%+!<$KBP$7$F@_Dj$5$l$^$9!#(B +

    + + + + + + + + + + + + + + + + + + + + +
    $B%Q%i%a!<%?(B$B%G%U%)%k%HCM(B$B@bL@(B
    lbmethod-Balancer $B$N%m!<%I%P%i%s%9J}K!!#;HMQ$9$k%m!<%I%P%i%s%9$N(B + $B%9%1%8%e!<%j%s%0J}K!$rA*$S$^$9!#=hM}$7$?%j%/%(%9%H$N?t$G=E$_IU$1$9$k(B + requests $B$+!"E>AwNL$N%P%$%H?t$G=E$_IU$1$9$k(B + traffic $B$r@_Dj$G$-$^$9!#%G%U%)%k%H$O(B + requests $B$G$9!#(B +
    stickysession-$B%P%i%s%5!<$N%9%F%#%C%-!<%;%C%7%g%sL>$G$9!#DL>o$O$3$NCM$O(B JSESSIONID + $B$d(B PHPSESSIONID $B$H$$$C$?$b$N$K$J$j$^$9$,!"$3$NCM$O(B + $B%P%C%/%(%s%I%"%W%j%1!<%7%g%s$N%5%]!<%H$9$k%;%C%7%g%s$K0MB8$7$^$9!#(B +
    nofailoverOffOn $B$K$J$C$F$$$k$H!"%o!<%+!<$,%(%i!<$r5/$3$7$?$j(B + $BL58z$K$J$C$F$$$k>l9g$K%;%C%7%g%s$,@Z$l$^$9!#(B + $B%P%C%/%(%s%I%5!<%P$,%;%C%7%g%s%l%W%j%1!<%7%g%s$r%5%]!<%H$7$F$$$J$$>l9g$O!"(B + On $B$K$7$F$/$@$5$$!#(B +
    timeout0$B%P%i%s%5!<$N%?%$%`%"%&%H$rIC$G;XDj$7$^$9!#(B + $B$3$NCM$r@_Dj$9$k$H!"%U%j!<$N%o!<%+!<$r
    maxattempts1$B%U%'%$%k%*!<%P!<$r;n$_$k:GBg$N2s?t$r;XDj$7$^$9!#(B +
    + + ProxyPass /special-area http://special.example.com/ smax=5 max=10
    + ProxyPass / balancer://mycluster stickysession=jsessionid nofailover=On
    + <Proxy balancer://mycluster>
    + + BalancerMember http://1.2.3.4:8009
    + BalancerMember http://1.2.3.5:8009 smax=10
    + # Less powerful server, don't send as many requests there
    + BalancerMember http://1.2.3.6:8009 smax=1 loadfactor=20
    +
    + </Proxy> +
    + +

    Location $B%;%/%7%g%s$NCf$G;H$o$l$?>l9g!":G=i$N0z?t$O(B + $B>JN,$5$l!"%m!<%+%k%G%#%l%/%H%j$O(B Location $B$+$i + +

    $B$h$j=@Fp$J%j%P!<%9%W%m%-%7$N@_Dj$,I,MW$J>l9g$O!"(B[P] + $B%U%i%0IU$-$N(B RewriteRule + $B%G%#%l%/%F%#%V$r;2>H$7$F$/$@$5$$!#(B

    +
    +
    + + +ProxyPassReverse +$B%j%P!<%9%W%m%-%7$5$l$?%5!<%P$+$iAw$i$l$?(B HTTP $B1~Ez%X%C%@$N(B +URL $B$rD4@0$9$k(B +ProxyPassReverse [path] url +server configvirtual host +directory + + + +

    $B$3$N%G%#%l%/%F%#%V$O(B Apache $B$K(B HTTP $B%j%@%$%l%/%H1~Ez$N(B + Location, Content-Location, URI + $B%X%C%@$ND4@0$r$5$;$^$9!#$3$l$O!"(BApache $B$,%j%P!<%9%W%m%-%7$H$7$F;H$o$l$F$$$k(B + $B$H$-$K!"%j%P!<%9%W%m%-%7$rDL$5$J$$$G%"%/%;%9$9$k$3$H$rKI$0$?$a$K(B + $B=EMW$G$9!#$3$l$K$h$j%P%C%/%(%s%I%5!<%P$N(B HTTP $B%j%@%$%l%/%H$,(B + $B%j%P!<%9%W%m%-%7$H%P%C%/%(%s%I$N4V$G07$o$l$k$h$&$K$J$j$^$9!#(B

    + +

    $B%G%#%l%/%F%#%V$GL@<($5$l$F$$$k(B HTTP $B1~Ez%X%C%@$N$_$,=q$-49$($i$l$^$9!#(B + Apache $B$OB>$N1~Ez%X%C%@$r=q$-49$($?$j!"(BHTML $B%Z!<%8$NCf$N(B URL $B;2>H$r(B + $B=q$-49$($?$j$9$k$3$H$O$"$j$^$;$s!#(BHTML $B$NCf$r8+$F!"(BURL $B;2>H$r=q$-49$($k(B + $B%b%8%e!<%k$K(B Nick Kew $B$5$s$N(B mod_proxy_html $B$,$"$j$^$9!#(B

    + +

    path $B$O%m!<%+%k2>A[%Q%9$NL>A0$G$9!#(Burl $B$O(B + $B%j%b!<%H%5!<%P$NItJ,(B URL $B$G$9!#$3$l$i$O(B ProxyPass $B%G%#%l%/%F%#%V$HF1MM$G$9!#(B

    + +

    $BNc$($P!"%m!<%+%k%5!<%P$N%"%I%l%9$,(B http://example.com/ + $B$@$H$7$^$9!#$9$k$H(B

    + + + ProxyPass /mirror/foo/ http://backend.example.com/
    + ProxyPassReverse /mirror/foo/ http://backend.example.com/
    + ProxyPassReverseCookieDomain backend.example.com public.example.com
    + ProxyPassReverseCookiePath / /mirror/foo/ +
    + +

    $B$H$$$&@_Dj$r$9$k$H!"(Bhttp://example.com/mirror/foo/bar + $B$X$N%m!<%+%k%j%/%(%9%H$,(B http://backend.example.com/bar + $B$X$N%W%m%-%7%j%/%(%9%H$KFbIt$G%j%@%$%l%/%H$5$l$k$@$1$G$O$"$j$^$;$s(B + ($B$3$l$O(B ProxyPass $B$N5!G=$G$9(B)$B!#(Bbackend.example.com + $B$,Aw$k%j%@%$%l%/%H$NLLE]$b$_$^$9!#(Bhttp://backend.example.com/bar + $B$,(B http://backend.example.com/quux $B$K%j%@%$%l%/%H$5$l$?$H$-!"(B + Apache $B$O(B HTTP $B%j%@%$%l%/%H1~Ez$r%/%i%$%"%s%H$KAw$kA0$K!"(B + http://example.com/mirror/foo/quux $B$KJQ99$7$^$9!#(B + URL $B$r9=@.$9$k$N$K;H$o$l$k%[%9%HL>$O(B UseCanonicalName $B$N@_Dj$K1~$8$FA*Br$5$l$k$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B

    + +

    ProxyPassReverse $B%G%#%l%/%F%#%V$O(B + $BBP1~$9$k(B ProxyPass $B%G%#%l%/%F%#%V$K$O0MB8$7$J$$$?$a!"(B + mod_rewrite $B$N%W%m%-%7DL2a5!G=(B + (RewriteRule ... [P]) $B$HJ;$;$F;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + +

    Location $B%;%/%7%g%s$NCf$G;H$o$l$?>l9g$O!"(B + $B:G=i$N0z?t$O>JN,$5$l!"%m!<%+%k%G%#%l%/%H%j$O(B Location $B$+$i + + + + +ProxyPassReverseCookieDomain +$B%j%P!<%9%W%m%-%7%5!<%P$+$i$N(B Set-Cookie $B%X%C%@$N(B Domain $BJ8;zNs$r(B +$BD4@0$9$k(B +ProxyPassReverseCookieDomain internal-domain public-domain +server configvirtual host +directory + + +

    $B;HMQK!$O4pK\E*$K(B +ProxyPassReverse $B$HF1$8$G$9$,!"(B +$B%X%C%@$N(B URL $B$NBe$o$j$K(B Set-Cookie $B%X%C%@$N(B +domain $BJ8;zNs$r=q$-49$($^$9!#(B

    +
    +
    + + +ProxyPassReverseCookiePath +Reverse $B%W%m%-%7%5!<%P$+$i$N(B Set-Cookie $B%X%C%@$N(B Path $BJ8;zNs$r(B +$BD4@0$9$k(B +ProxyPassReverseCookiePath internal-path public-path +server configvirtual host +directory + + +

    $B;HMQK!$O4pK\E*$K(B +ProxyPassReverse $B$HF1$8$G$9$,!"(B +$B%X%C%@$N(B URL $B$NBe$o$j$K(B Set-Cookie $B%X%C%@$N(B +path $BJ8;zNs$r=q$-49$($^$9!#(B

    +
    +
    + + + +AllowCONNECT +$B%W%m%-%7$r7PM3$7$F!"$I$N%]!<%H$K(B CONNECT +$B$G$-$k$+$r;XDj$9$k(B +AllowCONNECT port [port] ... +AllowCONNECT 443 563 +server configvirtual host + + + +

    AllowCONNECT $B$O%W%m%-%7$N(B CONNECT + $B%a%=%C%I$,@\B3$r5v2D$9$k%]!<%HHV9f$N%j%9%H$r;XDj$7$^$9!#(B + $B:#F|$N%V%i%&%6$O!"(Bhttps $B%3%M%/%7%g%s$,MW5a$5$l$F$$$F!"(B + HTTP $B>e$G$N%W%m%-%7$K$h$k%H%s%M%j%s%0$,$G$-$k$H$-$K!"(B + $B$3$N%a%=%C%I$r;H$$$^$9!#(B

    + +

    $B%G%U%)%k%H$N@_Dj$G$O!"(Bhttps $B$N%G%U%)%k%H%]!<%H(B (443) $B$H(B + $B%G%U%)%k%H$N(B snews $B%]!<%H(B (563) $B$,M-8z$K$J$C$F$$$^$9!#(B + $B$3$N%G%U%)%k%H$r>e=q$-$7$F!"%j%9%H$K5-:\$7$?%]!<%H$K$N$_@\B3$r5v2D$7$?$$>l9g!"(B + AllowCONNECT $B%G%#%l%/%F%#%V$r;HMQ$7$^$9!#(B

    + +

    CONNECT $B$r;HMQ$9$k$K$O!"(Bmod_proxy_connect + $B$,%5!<%P$KAH$_9~$^$l$F$$$J$1$l$P$J$i$J$$$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    +
    + + +ProxyBlock +$B%W%m%-%7@\B3$r6X;_$9$k8l6g!"%[%9%HL>!"%I%a%$%s$r;XDj$9$k(B +ProxyBlock *|word|host|domain +[word|host|domain] ... +server configvirtual host + + + +

    ProxyBlock $B%G%#%l%/%F%#%V$O6uGr$G6h@Z$i$l$?(B + $B8l6g!"%[%9%HL>!"%I%a%$%s$N%j%9%H$r;XDj$7$^$9!#%5%$%HL>$K$=$N8l6g!"%[%9%HL>!"(B + $B%I%a%$%s$r4^$`%5%$%H$X$N(B HTTP$B!"(BHTTPS$B!"(BFTP $B$K$h$k%I%-%e%a%s%H$N%j%/%(%9%H$O(B + $B%W%m%-%7%5!<%P$K$h$j(B$B%V%m%C%/$5$l$^$9(B$B!#%W%m%-%7%b%8%e!<%k$O(B + $B5/F0;~$K%[%9%HL>$H;W$7$-9`L\$N(B IP $B%"%I%l%9$rD4$Y!"8e$N%F%9%H$N$?$a$K(B + $B%-%c%C%7%e$7$^$9!#$3$l$K$h$j!"%5!<%P$N5/F0$,>/$7CY$/$J$k$+$b$7$l$^$;$s!#(B

    + + Example + ProxyBlock joes-garage.com some-host.co.uk rocky.wotsamattau.edu + + +

    rocky.wotsamattau.edu $B$,(B IP $B%"%I%l%9$G;2>H$5$l$?$H$-$G$b(B + $B%^%C%A$7$^$9!#(B

    + +

    wotsamattau.edu $B$N%^%C%A$K$O(B wotsamattau + $B$@$1$G$b==J,$G$9!#(B

    + + + ProxyBlock * + + +

    $B$O$9$Y$F$N%5%$%H$X$N@\B3$r%V%m%C%/$9$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    +
    + + +ProxyReceiveBufferSize +$B%W%m%-%7$5$l$k(B HTTP $B$H(B FTP $B@\B3$N$?$a$N%M%C%H%o!<%/%P%C%U%!%5%$%:(B +ProxyReceiveBufferSize bytes +ProxyReceiveBufferSize 0 +server configvirtual host + + + +

    ProxyReceiveBufferSize $B%G%#%l%/%F%#%V$O(B + $B%9%k!<%W%C%H$r>e$2$k$?$a$KL@<(E*$K(B (TCP/IP) $B%M%C%H%o!<%/%P%C%U%!$N%5%$%:$r(B + $B@_Dj$7$^$9!#CM$O(B 512 $B0J>e$+!"%7%9%F%`$N%G%U%)%k%H$N%P%C%U%!(B + $B%5%$%:$r0UL#$9$k(B 0 $B$G$J$1$l$P$J$j$^$;$s!#(B

    + + $BNc(B + ProxyReceiveBufferSize 2048 + +
    +
    + + +ProxyIOBufferSize +$BFbIt%G!<%?%9%k!<%W%C%H%P%C%U%!$N%5%$%:$r7hDj$9$k(B +ProxyIOBufferSize bytes +ProxyIOBufferSize 8192 +server configvirtual host + + + +

    ProxyIOBufferSize $B%G%#%l%/%F%#%V$OF~NO$H(B + $B=PNOMQ$N0l;~%a%b%j$H$7$F;H$o$l$kFbIt%P%C%U%!$N%5%$%:$rD4@0$7$^$9!#(B + $B%5%$%:$O(B 8192 $B0J2<$G$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B$[$H$s$I$9$Y$F$N>l9g!"$3$NCM$rJQ99$9$kM}M3$O$"$j$^$;$s!#(B

    +
    +
    + + +ProxyMaxForwards +$B%j%/%(%9%H$,%U%)%o!<%I$5$l$k%W%m%-%7$N:GBg?t(B +ProxyMaxForwards number +ProxyMaxForwards 10 +server configvirtual host + +Apache 2.0 $B0J9_$G;HMQ2DG=(B + + +

    ProxyMaxForwards $B%G%#%l%/%F%#%V$O(B + $B%j%/%(%9%H$K(B Max-Forwards $B%X%C%@$,;XDj$5$l$F$$$J$$>l9g$K(B + $B%j%/%(%9%H$,DL2a2DG=$J%W%m%-%7$N:GBg?t$r@_Dj$7$^$9!#$3$l$O(B + $B%W%m%-%7$NL58B%k!<%W$d(B DoS $B967b$rKI$0$?$a$K@_Dj$5$l$F$$$^$9!#(B

    + + $BNc(B + ProxyMaxForwards 15 + +
    +
    + + +NoProxy +$BD>@\@\B3$9$k(B $B%[%9%H!"%I%a%$%s!"%M%C%H%o!<%/(B +NoProxy host [host] ... +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O%$%s%H%i%M%C%HCf$N(B Apache $B%W%m%-%7%5!<%P$K$N$_(B + $BM-MQ$G$9!#(BNoProxy $B%G%#%l%/%F%#%V$O6uGr6h@Z$j$G!"(B + $B%5%V%M%C%H!"(BIP $B%"%I%l%9!"%[%9%H!"%I%a%$%s$N%j%9%H$r;XDj$7$^$9!#(B + $B$3$l$i$N$I$l$+$K%^%C%A$9$k%[%9%H$X$N%j%/%(%9%H$O(B ProxyRemote $B$G@_Dj$5$l$?%W%m%-%7%5!<%P$K(B + $B%U%)%o!<%I$5$l$:!"D>@\=hM}$5$l$^$9!#(B

    + + $BNc(B + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21 +
    + +

    NoProxy $B%G%#%l%/%F%#%V$N(B host $B0z?t$O(B + $B0J2<$N + +

    + +
    Domain
    +
    +

    Domain $B$O@hF,$K%T%j%*%I$NCe$$$?ItJ,(B DNS $B%I%a%$%sL>$G$9!#(B + $BF10l(B DNS $B%I%a%$%s5Z$S%>!<%s(B ($B$9$J$o$A(B$B!"%[%9%HL>$NKvHx$,$9$Y$F(B + Domain $B$G=*$o$C$F$$$k$H$$$&$3$H(B) $B$KB0$9$k%[%9%H$N%j%9%H$r(B + $BI=$7$^$9(B)$B!#(B

    + + $BNc(B + .com .apache.org. + + +

    Domain $B$r(B Hostname $B$H6hJL$9$k$?$a$K(B ($B0UL#E*$K$b9=J8E*$K$b!#(BDNS $B%I%a%$%s$b(B + DNS $B$N(B A $B%l%3!<%I$r;}$D$3$H$,$G$-$k$N$G$9(B!)$B!"(BDomain $B$O(B + $B>o$K%T%j%*%I$G;O$^$j$^$9!#(B

    + + $BCm(B +

    $B%I%a%$%sL>$NHf3S$OBgJ8;z>.J8;z$r6hJL$;$:$K9T$J$o$l!"(BDomain + $B$O>o$K(B DNS $B%D%j!<$N%k!<%H$+$i;O$^$k$b$N$H$_$J$5$l$^$9!#$G$9$+$i!"(B + $B.MyDomain.com $B$H(B + .mydomain.com. ($B:G8e$N%T%j%*%I$KCmL\(B) $B$OF10l$G$"$k$H(B + $B$_$J$5$l$^$9!#%I%a%$%s$NHf3S$O(B DNS $B%k%C%/%"%C%W$J$7$G9T$J$o$l$k$?$a!"(B + $B%5%V%M%C%H$NHf3S$h$j$b$:$C$H8zN(E*$G$9!#(B

    +
    + + +
    SubNet
    +
    +

    SubNet $B$O?tCM7A<0(B ($B%I%C%H$G6h@Z$i$l$?;M$D$N?t;z(B) $B$N(B + $BItJ,%$%s%?!<%M%C%H%"%I%l%9$G$9!#8e$K%9%i%C%7%e$H(B Subnet + $B$N0UL#$N$"$k%S%C%H?t$r;XDj$9$k%M%C%H%^%9%/$H$rB3$1$k$3$H$,$G$-$^$9!#(B + $B6&DL$N%M%C%H%o!<%/%$%s%?%U%'!<%9$r;H$C$FE~C#$9$k$3$H$N$G$-$k%5%V%M%C%H$r(B + $BI=$9$?$a$K;H$o$l$^$9!#L@<(E*$K%M%C%H%^%9%/$r;XDj$7$J$$>l9g$O(B + $B:G8e$N>JN,$5$l$?(B ($B$b$7$/$OCM$,(B 0 $B$N(B) $B?t;z$,%^%9%/$r;XDj$7$^$9!#(B + ($B$3$N>l9g$O!"%M%C%H%^%9%/$O(B 8 $B%S%C%HC10L$G$7$+;XDj$G$-$^$;$s!#(B) + $BNc(B:

    + +
    +
    192.168 $B$b$7$/$O(B 192.168.0.0
    +
    $B%5%V%M%C%H(B 192.168.0.0 $B$H0EL[$N(B 16 $B%S%C%HM-8z$J%M%C%H%^%9%/(B + (255.255.0.0 $B$H$$$&%M%C%H%^%9%/$N7A<0$G;H$o$l$k$3$H$b(B + $B$"$j$^$9(B)
    +
    192.168.112.0/21
    +
    $B%5%V%M%C%H(B192.168.112.0/21 $B$H(B 21 $B%S%C%HM-8z$J(B + $B%M%C%H%^%9%/(B (255.255.248.0 $B$H$$$&7A<0$G;H$o$l$k$3$H$b(B + $B$"$j$^$9(B)
    +
    + +

    $BFCJL$J>l9g$K!"(B32 $B%S%C%HM-8z$J(B SubNet $B$O(B + IPAddr $B$HF1Ey$G!"(B + 0 $B%S%C%HM-8z$J(B SubNet ($BNc$($P(B$B!"(B0.0.0.0/0) $B$O(B + $B$9$Y$F$N(B IP $B%"%I%l%9$K%^%C%A$9$kDj?t(B _Default_ $B$HF1$8$G$9!#(B

    +
    + + +
    IPAddr
    +
    +

    IPAddr $B$O?tCM7A<0(B ($B%I%C%H$G6h@Z$i$l$?;M$D$N?t;z(B) $B$N(B + $B40A4%$%s%?!<%M%C%H%"%I%l%9$G$9!#DL>o$O$3$N%"%I%l%9$O%[%9%H$r(B + $BI=$7$^$9$,!"I,$:$7$b%"%I%l%9$KBP1~$9$k(B DNS $B%I%a%$%sL>$,$"$k$o$1$G$O(B + $B$"$j$^$;$s!#(B

    + + $BNc(B + 192.168.123.7 + + + $BCm(B +

    IPAddr $B$O(B DNS $B%7%9%F%`$K$h$j2r7h$5$l$kI,MW$,$J$$$N$G!"(B + apache $B$N@-G=$,8~>e$9$k$+$b$7$l$^$;$s!#(B

    +
    + + +
    Hostname
    +
    +

    Hostname $B$O(B DNS $B%I%a%$%s%5!<%S%9$K$h$j0l$D$b$7$/$O(B + $BJ#?t$N(B IPAddr $B$K2r7h2DG=$J(B + $B40A4$J(B DNS $B%I%a%$%sL>$G$9!#$3$l$O(B (Domain + $B$H0c$C$F!"@bL@$O>e5-$r;2>H(B) $BO@M}E*$J%[%9%H$rI=$7!">/$/$H$b0l$D$N(B + IPAddr ($B$b$7$/$O0c$&(B + IPAddr $B$N%[%9%H$N%j%9%H(B) $B$K2r7h(B + $B$5$l$J$1$l$P$J$j$^$;$s(B)$B!#(B

    + + $BNc(B + prep.ai.mit.edu
    + www.apache.org +
    + + $BCm(B +

    $BB?$/$N>l9g!"(BHostname $B$NBe$o$j$K(B IPAddr $B$r;XDj$7$?J}$,!"(BDNS $B%k%C%/%"%C%W$r(B + $BHr$1$k$3$H$,$G$-$k$?$a!"8zN($,NI$/$J$j$^$9!#(BApache $B$NL>A02r7h$O(B + $B%M!<%`%5!<%P$X$N@\B3$,CY$$(B PPP $B>e$N>l9g$J$I$K$+$J$j;~4V$r +

    Hostname $B$NHf3S$OBgJ8;z>.J8;z$r6hJL$;$:$K9T$J$o$l!"(B + Hostname $B$O>o$K(B DNS $B%D%j!<$N%k!<%H$+$i;O$^$k$b$N$H$_$J$5$l$^$9!#(B + $B$G$9$+$i!"Fs$D$N%I%a%$%s(B WWW.MyDomain.com $B$H(B + www.mydomain.com. ($B:G8e$N%T%j%*%I$KCmL\(B) $B$OF10l$G$"$k$H(B + $B$_$J$5$l$^$9!#(B

    +
    +
    +
    +DNS $B$K4X$9$kLdBj(B +
    + + +ProxyTimeout +$B%W%m%-%7$5$l$?%j%/%(%9%H$N%M%C%H%o!<%/%?%$%`%"%&%H(B +ProxyTimeout seconds +ProxyTimeout 300 +server configvirtual host + +Apache 2.0.31 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O%f!<%6$,%W%m%-%7%j%/%(%9%H$N%?%$%`%"%&%H$r(B + $B;XDj$G$-$k$h$&$K$7$^$9!#$3$l$O%O%s%0$7$F$7$^$&CY$$!"$b$7$/$O5sF0$N(B + $B2x$7$$%5!<%P$,$"$j!"%5!<%P$,%G!<%?$rJV$9$^$G$R$?$9$iBT$AB3$1$k$h$j$b(B + $B%?%$%`%"%&%H$rJV$7$F$h$j4K$d$+$K(Bgraceful $B$K(B + $B<:GT$5$;$?$$>l9g$KLr$KN)$A$^$9!#(B

    +
    +
    + + +ProxyDomain +$B%W%m%-%7$5$l$?%j%/%(%9%H$N%G%U%)%k%H$N%I%a%$%sL>(B +ProxyDomain Domain +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O%$%s%H%i%M%C%HFb$N(B Apache $B%W%m%-%7%5!<%P$K$N$_(B + $BM-MQ$G$9!#(BProxyDomain $B%G%#%l%/%F%#%V$O(B + apache $B%W%m%-%7%5!<%P$,B0$9$k%G%U%)%k%H$N%I%a%$%s$r;XDj$7$^$9!#(B + $B%I%a%$%sL>$NL5$$%j%/%(%9%H$rl9g!"@_Dj$5$l$?(B Domain + $B$,DI2C$5$l$?F1$8%[%9%H$X$N%j%@%$%l%/%H1~Ez$,JV$5$l$^$9!#(B

    + + $BNc(B + ProxyRemote * http://firewall.mycompany.com:81
    + NoProxy .mycompany.com 192.168.112.0/21
    + ProxyDomain .mycompany.com +
    +
    +
    + + +ProxyVia +$B%W%m%-%7$5$l$?%j%/%(%9%H$N(B Via HTTP $B1~Ez%X%C%@(B +$B$K$h$jDs6!$5$l$k>pJs(B +ProxyVia On|Off|Full|Block +ProxyVia Off +server configvirtual host + + + +

    $B$3$N%G%#%l%/%F%#%V$O%W%m%-%7$N(B Via: HTTP $B%X%C%@$N;HMQ$r(B + $B@)8f$7$^$9!#A[Dj$5$l$F$$$k;H$$J}$O!"%W%m%-%7%5!<%P$,$$$/$D$b7R$,$C$F$$$k$H$-$K(B + $B%W%m%-%7%j%/%(%9%H$NN.$l$r@)8f$9$k$3$H$G$9!#(BVia: $B%X%C%@9T$N(B + $B@bL@$O(B RFC 2616 (HTTP/1.1) + $B$N(B 14.45 $B@a$rFI$s$G$/$@$5$$!#(B

    + +
      +
    • $B%G%U%)%k%H$N(B Off $B$K@_Dj$5$l$F$$$k$H!"FCJL$J=hM}$O(B + $B9T$J$o$l$^$;$s!#%j%/%(%9%H$d%j%W%i%$$K(B Via: $B%X%C%@$,$"$l$P!"(B + $BJQ99$5$l$:$K$=$N$^$^EO$7$^$9!#(B
    • + +
    • On $B$K@_Dj$5$l$F$$$l$P!"3F%j%/%(%9%H$H%j%W%i%$$K(B + Via: $B9T$,DI2C$5$l$^$9!#(B
    • + +
    • Full $B$K@_Dj$5$l$F$$$l$P!"(BVia: $B%X%C%@$O(B + $B%3%a%s%HItJ,$K(B Apache $B%5!<%P$N%P!<%8%g%s$b4^$`$h$&$K$J$j$^$9!#(B
    • + +
    • Block $B$K@_Dj$5$l$F$$$l$P!"$9$Y$F$N%W%m%-%7%j%/%(%9%H$+$i(B + Via: $B%X%C%@$,Via: $B$,(B + $B@8@.$5$l$k$3$H$O$"$j$^$;$s!#(B
    • +
    +
    +
    + + +ProxyErrorOverride +$B%W%m%-%7$5$l$?%3%s%F%s%D$N%(%i!<%Z!<%8$r>e=q$-$9$k(B +ProxyErrorOverride On|Off +ProxyErrorOverride Off +server configvirtual host + +$B%P!<%8%g%s(B 2.0 $B0J9_$G;HMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O%j%P!<%9%W%m%-%7$r;HMQ$7$F$$$F!"(B + $B%(%s%I%f!<%6$KAw$i$l$k%(%i!<%Z!<%8$N308+$r6&DL$N$b$N$K$7$?$$$H$-$K(B + $BM-MQ$G$9!#$3$N%G%#%l%/%F%#%V$O(B (mod_include $B$N(B SSI $B$K$h$C$F(B) + $B%$%s%/%k!<%I$5$l$?%U%!%$%k$,%(%i!<%3!<%I$r + + + + diff --git a/trunk/docs/manual/mod/mod_proxy.xml.meta b/trunk/docs/manual/mod/mod_proxy.xml.meta new file mode 100644 index 0000000000..7e1e4da813 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy.xml.meta @@ -0,0 +1,12 @@ + + + + mod_proxy + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.html b/trunk/docs/manual/mod/mod_proxy_ajp.html new file mode 100644 index 0000000000..2e2bf126e0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.html @@ -0,0 +1,7 @@ +URI: mod_proxy_ajp.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_proxy_ajp.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.html.en b/trunk/docs/manual/mod/mod_proxy_ajp.html.en new file mode 100644 index 0000000000..b42c63ac86 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.html.en @@ -0,0 +1,556 @@ + + + +mod_proxy_ajp - Apache HTTP Server + + + + + +

    +
    <-
    + +
    +

    Apache Module mod_proxy_ajp

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    Description:AJP support module for +mod_proxy
    Status:Extension
    Module Identifier:proxy_ajp_module
    Source File:proxy_ajp.c
    Compatibility:Available in version 2.1 and later
    +

    Summary

    + +

    This module requires the service of mod_proxy. It provides support for the + Apache JServ Protocol version 1.3 (hereafter + AJP13).

    + +

    Thus, in order to get the ability of handling AJP13 + protocol, mod_proxy and + mod_proxy_ajp have to be present in the server.

    + +

    Warning

    +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +

    Directives

    +

    This module provides no + directives.

    +

    Topics

    +

    See also

    +
    +
    top
    +
    +

    Overview of the protocol

    +

    The AJP13 protocol is packet-oriented. A binary format + was presumably chosen over the more readable plain text for reasons of + performance. The web server communicates with the servlet container over + TCP connections. To cut down on the expensive process of socket creation, + the web server will attempt to maintain persistent TCP connections to the + servlet container, and to reuse a connection for multiple request/response + cycles.

    +

    Once a connection is assigned to a particular request, it will not be + used for any others until the request-handling cycle has terminated. In + other words, requests are not multiplexed over connections. This makes + for much simpler code at either end of the connection, although it does + cause more connections to be open at once.

    +

    Once the web server has opened a connection to the servlet container, + the connection can be in one of the following states:

    +
      +
    • Idle
      No request is being handled over this connection.
    • +
    • Assigned
      The connecton is handling a specific request.
    • +
    +

    Once a connection is assigned to handle a particular request, the basic + request informaton (e.g. HTTP headers, etc) is sent over the connection in + a highly condensed form (e.g. common strings are encoded as integers). + Details of that format are below in Request Packet Structure. If there is a + body to the request (content-length > 0), that is sent in a + separate packet immediately after.

    +

    At this point, the servlet container is presumably ready to start + processing the request. As it does so, it can send the + following messages back to the web server:

    +
      +
    • SEND_HEADERS
      Send a set of headers back to the browser.
    • +
    • SEND_BODY_CHUNK
      Send a chunk of body data back to the browser. +
    • +
    • GET_BODY_CHUNK
      Get further data from the request if it hasn't all + been transferred yet. This is necessary because the packets have a fixed + maximum size and arbitrary amounts of data can be included the body of a + request (for uploaded files, for example). (Note: this is unrelated to + HTTP chunked tranfer).
    • +
    • END_RESPONSE
      Finish the request-handling cycle.
    • +
    +

    Each message is accompanied by a differently formatted packet of data. + See Response Packet Structures below for details.

    +
    top
    +
    +

    Basic Packet Structure

    +

    There is a bit of an XDR heritage to this protocol, but it differs + in lots of ways (no 4 byte alignment, for example).

    +

    Byte order: I am not clear about the endian-ness of the individual + bytes. I'm guessing the bytes are little-endian, because that's what + XDR specifies, and I'm guessing that sys/socket library is magically + making that so (on the C side). If anyone with a better knowledge of + socket calls can step in, that would be great.

    +

    There are four data types in the protocol: bytes, booleans, + integers and strings.

    +
    +
    Byte
    A single byte.
    +
    Boolean
    +
    A single byte, 1 = true, 0 = false. + Using other non-zero values as true (i.e. C-style) may work in some places, + but it won't in others.
    +
    Integer
    +
    A number in the range of 0 to 2^16 (32768). Stored in + 2 bytes with the high-order byte first.
    +
    String
    +
    A variable-sized string (length bounded by 2^16). Encoded with + the length packed into two bytes first, followed by the string + (including the terminating '\0'). Note that the encoded length does + not include the trailing '\0' -- it is like + strlen. This is a touch confusing on the Java side, which + is littered with odd autoincrement statements to skip over these + terminators. I believe the reason this was done was to allow the C + code to be extra efficient when reading strings which the servlet + container is sending back -- with the terminating \0 character, the + C code can pass around references into a single buffer, without copying. + if the \0 was missing, the C code would have to copy things out in order + to get its notion of a string.
    +
    + +

    Packet Size

    +

    According to much of the code, the max packet size is + 8 * 1024 bytes (8K). The actual length of the packet is encoded in + the header.

    + +

    Packet Headers

    +

    Packets sent from the server to the container begin with + 0x1234. Packets sent from the container to the server + begin with AB (that's the ASCII code for A followed by the + ASCII code for B). After those first two bytes, there is an integer + (encoded as above) with the length of the payload. Although this might + suggest that the maximum payload could be as large as 2^16, in fact, the + code sets the maximum to be 8K.

    + + + + + + + + + + + + + + + + + + + +
    Packet Format (Server->Container)
    Byte01234...(n+3)
    Contents0x120x34Data Length (n)Data
    + + + + + + + + + + + + + + + + + + + +
    Packet Format (Container->Server)
    Byte01234...(n+3)
    ContentsABData Length (n)Data
    +

    For most packets, the first byte of the payload encodes the type of + message. The exception is for request body packets sent from the server to + the container -- they are sent with a standard packet header ( + 0x1234 and then length of the packet), but without any prefix code + after that.

    +

    The web server can send the following messages to the servlet + container:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeType of PacketMeaning
    2Forward RequestBegin the request-processing cycle with the following data
    7ShutdownThe web server asks the container to shut itself down.
    8PingThe web server asks the container to take control + (secure login phase).
    10CPingThe web server asks the container to respond quickly with a CPong. +
    noneDataSize (2 bytes) and corresponding body data.
    +

    To ensure some basic security, the container will only actually do the + Shutdown if the request comes from the same machine on which + it's hosted.

    +

    The first Data packet is send immediatly after the + Forward Request by the web server.

    +

    The servlet container can send the following types of messages to the + webserver:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeType of PacketMeaning
    3Send Body ChunkSend a chunk of the body from the servlet container to the web + server (and presumably, onto the browser).
    4Send HeadersSend the response headers from the servlet container to the web + server (and presumably, onto the browser).
    5End ResponseMarks the end of the response (and thus the request-handling cycle). +
    6Get Body ChunkGet further data from the request if it hasn't all been + transferred yet.
    9CPong ReplyThe reply to a CPing request
    +

    Each of the above messages has a different internal structure, detailed + below.

    + +
    top
    +
    +

    Request Packet Structure

    +

    For messages from the server to the container of type + Forward Request:

    +
    +AJP13_FORWARD_REQUEST :=
    +    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    +    method           (byte)
    +    protocol         (string)
    +    req_uri          (string)
    +    remote_addr      (string)
    +    remote_host      (string)
    +    server_name      (string)
    +    server_port      (integer)
    +    is_ssl           (boolean)
    +    num_headers      (integer)
    +    request_headers *(req_header_name req_header_value)
    +    attributes      *(attribut_name attribute_value)
    +    request_terminator (byte) OxFF
    +    
    +

    The request_headers have the following structure: +

    +req_header_name := 
    +    sc_req_header_name | (string)  [see below for how this is parsed]
    +
    +sc_req_header_name := 0xA0xx (integer)
    +
    +req_header_value := (string)
    +
    +

    The attributes are optional and have the following + structure:

    +
    +attribute_name := sc_a_name | (sc_a_req_attribute string)
    +
    +attribute_value := (string)
    +
    +    
    +

    Not that the all-important header is content-length, + because it determines whether or not the container looks for another + packet immediately.

    +

    Detailed description of the elements of Forward Request +

    +

    Request prefix

    +

    For all requests, this will be 2. See above for details on other Prefix + codes.

    + +

    Method

    +

    The HTTP method, encoded as a single byte:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Command NameCode
    OPTIONS1
    GET2
    HEAD3
    POST4
    PUT5
    DELETE6
    TRACE7
    PROPFIND8
    PROPPATCH9
    MKCOL10
    COPY11
    MOVE12
    LOCK13
    UNLOCK14
    ACL15
    REPORT16
    VERSION-CONTROL17
    CHECKIN18
    CHECKOUT19
    UNCHECKOUT20
    SEARCH21
    MKWORKSPACE22
    UPDATE23
    LABEL24
    MERGE25
    BASELINE_CONTROL26
    MKACTIVITY27
    +

    Later version of ajp13, will transport + additional methods, even if they are not in this list.

    + +

    protocol, req_uri, remote_addr, remote_host, server_name, + server_port, is_ssl

    +

    These are all fairly self-explanatory. Each of these is required, and + will be sent for every request.

    + +

    Headers

    +

    The structure of request_headers is the following: + First, the number of headers num_headers is encoded. + Then, a series of header name req_header_name / value + req_header_value pairs follows. + Common header names are encoded as integers, + to save space. If the header name is not in the list of basic headers, + it is encoded normally (as a string, with prefixed length). The list of + common headers sc_req_header_nameand their codes + is as follows (all are case-sensitive):

    + + + + + + + + + + + + + + + + + + + +
    NameCode valueCode name
    accept0xA001SC_REQ_ACCEPT
    accept-charset0xA002SC_REQ_ACCEPT_CHARSET +
    accept-encoding0xA003SC_REQ_ACCEPT_ENCODING +
    accept-language0xA004SC_REQ_ACCEPT_LANGUAGE +
    authorization0xA005SC_REQ_AUTHORIZATION
    connection0xA006SC_REQ_CONNECTION
    content-type0xA007SC_REQ_CONTENT_TYPE
    content-length0xA008SC_REQ_CONTENT_LENGTH
    cookie0xA009SC_REQ_COOKIE
    cookie20xA00ASC_REQ_COOKIE2
    host0xA00BSC_REQ_HOST
    pragma0xA00CSC_REQ_PRAGMA
    referer0xA00DSC_REQ_REFERER
    user-agent0xA00ESC_REQ_USER_AGENT
    +

    The Java code that reads this grabs the first two-byte integer and if + it sees an '0xA0' in the most significant + byte, it uses the integer in the second byte as an index into an array of + header names. If the first byte is not 0xA0, it assumes that + the two-byte integer is the length of a string, which is then read in.

    +

    This works on the assumption that no header names will have length + greater than 0x9999 (==0xA000 - 1), which is perfectly + reasonable, though somewhat arbitrary.

    +

    Note:

    + The content-length header is extremely + important. If it is present and non-zero, the container assumes that + the request has a body (a POST request, for example), and immediately + reads a separate packet off the input stream to get that body. +
    + +

    Attributes

    +

    The attributes prefixed with a ? + (e.g. ?context) are all optional. For each, there is a + single byte code to indicate the type of attribute, and then a string to + give its value. They can be sent in any order (thogh the C code always + sends them in the order listed below). A special terminating code is + sent to signal the end of the list of optional attributes. The list of + byte codes is:

    + + + + + + + + + + + + + + +
    InformationCode ValueNote
    ?context0x01Not currently implemented +
    ?servlet_path0x02Not currently implemented +
    ?remote_user0x03
    ?auth_type0x04
    ?query_string0x05
    ?jvm_route0x06
    ?ssl_cert0x07
    ?ssl_cipher0x08
    ?ssl_session0x09
    ?req_attribute0x0AName (the name of the + attribute follows)
    ?ssl_key_size0x0B
    are_done0xFFrequest_terminator
    +

    The context and servlet_path are not + currently set by the C code, and most of the Java code completely ignores + whatever is sent over for those fields (and some of it will actually break + if a string is sent along after one of those codes). I don't know if this + is a bug or an unimplemented feature or just vestigial code, but it's + missing from both sides of the connection.

    +

    The remote_user and auth_type presumably + refer to HTTP-level authentication, and communicate the remote user's + username and the type of authentication used to establish their identity + (e.g. Basic, Digest).

    +

    The query_string, ssl_cert, + ssl_cipher, and ssl_session refer to the + corresponding pieces of HTTP and HTTPS.

    +

    The jvm_route, is used to support sticky + sessions -- associating a user's sesson with a particular Tomcat instance + in the presence of multiple, load-balancing servers.

    +

    Beyond this list of basic attributes, any number of other attributes + can be sent via the req_attribute code 0x0A. + A pair of strings to represent the attribute name and value are sent + immediately after each instance of that code. Environment values are passed + in via this method.

    +

    Finally, after all the attributes have been sent, the attribute + terminator, 0xFF, is sent. This signals both the end of the + list of attributes and also then end of the Request Packet.

    + +
    top
    +
    +

    Response Packet Structure

    +

    for messages which the container can send back to the server.

    +
    +AJP13_SEND_BODY_CHUNK :=
    +  prefix_code   3
    +  chunk_length  (integer)
    +  chunk        *(byte)
    +
    +
    +AJP13_SEND_HEADERS :=
    +  prefix_code       4
    +  http_status_code  (integer)
    +  http_status_msg   (string)
    +  num_headers       (integer)
    +  response_headers *(res_header_name header_value)
    +
    +res_header_name :=
    +    sc_res_header_name | (string)   [see below for how this is parsed]
    +
    +sc_res_header_name := 0xA0 (byte)
    +
    +header_value := (string)
    +
    +AJP13_END_RESPONSE :=
    +  prefix_code       5
    +  reuse             (boolean)
    +
    +
    +AJP13_GET_BODY_CHUNK :=
    +  prefix_code       6
    +  requested_length  (integer)
    +    
    +

    Details:

    +

    Send Body Chunk

    +

    The chunk is basically binary data, and is sent directly back to the + browser.

    + +

    Send Headers

    +

    The status code and message are the usual HTTP things + (e.g. 200 and OK). The response header names are + encoded the same way the request header names are. See header_encoding above + for details about how the the codes are distinguished from the strings.
    + The codes for common headers are:

    + + + + + + + + + + + + + +
    NameCode value
    Content-Type0xA001
    Content-Language0xA002
    Content-Length0xA003
    Date0xA004
    Last-Modified0xA005
    Location0xA006
    Set-Cookie0xA007
    Set-Cookie20xA008
    Servlet-Engine0xA009
    Status0xA00A
    WWW-Authenticate0xA00B
    +

    After the code or the string header name, the header value is + immediately encoded.

    + +

    End Response

    +

    Signals the end of this request-handling cycle. If the + reuse flag is true (==1), this TCP connection can + now be used to handle new incoming requests. If reuse is false + (anything other than 1 in the actual C code), the connection should + be closed.

    + +

    Get Body Chunk

    +

    The container asks for more data from the request (If the body was + too large to fit in the first packet sent over or when the request is + chuncked). The server will send a body packet back with an amount of data + which is the minimum of the request_length, the maximum send + body size (8186 (8 Kbytes - 6)), and the number of bytes + actually left to send from the request body.
    + If there is no more data in the body (i.e. the servlet container is + trying to read past the end of the body), the server will send back an + empty packet, which is a body packet with a payload length of 0. + (0x12,0x34,0x00,0x00)

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.html.ja.euc-jp b/trunk/docs/manual/mod/mod_proxy_ajp.html.ja.euc-jp new file mode 100644 index 0000000000..9a97d47358 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.html.ja.euc-jp @@ -0,0 +1,542 @@ + + + +mod_proxy_ajp - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_proxy_ajp

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + +
    ÀâÌÀ:mod_proxy ¤Ç AJP +¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¤Î¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:proxy_ajp_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:proxy_ajp.c
    +

    ³µÍ×

    + +

    Ëܥ⥸¥å¡¼¥ë¤Ë¤Ï mod_proxy ¤¬É¬ÍפǤ¹¡£ + Apache JServ Protocol version 1.3 (°Ê¹ß AJP13) + ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£

    + +

    AJP13 ¥×¥í¥È¥³¥ë¤ò°·¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï + mod_proxy ¤È mod_proxy_ajp + ¤ò¥µ¡¼¥Ð¤ËÁȤ߹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ·Ù¹ð

    +

    °ÂÁ´¤Ê¥µ¡¼¥Ð¤Ë¤¹¤ë¤Þ¤Ç¥×¥í¥¯¥·µ¡Ç½¤ÏÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¥ª¡¼¥×¥ó¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï¤¢¤Ê¤¿¼«¿È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤È¤Ã¤Æ¤â¡¢ + ¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÁ´ÂΤˤȤäƤâ´í¸±¤Ç¤¹¡£

    +
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    +

    ¥È¥Ô¥Ã¥¯

    +

    »²¾È

    +
    +
    top
    +
    +

    ¥×¥í¥È¥³¥ë¤Î³µÍ×

    +

    AJP13 ¥×¥í¥È¥³¥ë¤Ï¥Ñ¥±¥Ã¥È»Ø¸þ¤Ç¤¹¡£ + ²ÄÆɤʥץ졼¥ó¥Æ¥­¥¹¥È·Á¼°¤Ç¤Ï¤Ê¤¯¥Ð¥¤¥Ê¥ê·Á¼°¤Ë¤Ê¤Ã¤¿¤Î¤Ï¡¢ + ¤ª¤½¤é¤¯¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¾å¤ÎÍýͳ¤Ë¤è¤ê¤Þ¤¹¡£ + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ï¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤È TCP ¥³¥Í¥¯¥·¥ç¥ó¤ÇÄÌ¿®¤·¤Þ¤¹¡£ + ¥½¥±¥Ã¥ÈÀ¸À®¤Ï½Å¤¤½èÍý¤Ê¤Î¤Ç¡¢Éé²Ù¤ò¸º¤é¤¹¤¿¤á¤Ë¡¢¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤È¤Î + TCP Àܳ¤ò°Ý»ý¤·¡¢Ê£¿ô¤Î¥ê¥¯¥¨¥¹¥È¡¦¥ì¥¹¥Ý¥ó¥¹½èÍý¥µ¥¤¥¯¥ë¤ËÂФ·¤Æ°ì¤Ä¤Î + ¥³¥Í¥¯¥·¥ç¥ó¤ò»È¤¤¤Þ¤ï¤¹¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    +

    ¤¢¤ë¥ê¥¯¥¨¥¹¥È¤Ë¥³¥Í¥¯¥·¥ç¥ó¤¬³ä¤êÅö¤Æ¤é¤ì¤ë¤È¡¢¤½¤Î½èÍý¥µ¥¤¥¯¥ë¤¬ + ´°Î»¤¹¤ë¤Þ¤Ç¾¤Î¤â¤Î¤Ë»È¤ï¤ì¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤Ä¤Þ¤ê¥³¥Í¥¯¥·¥ç¥ó¾å¤Ç¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ÎƱ»þ½èÍý¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¡£ + ¤³¤Î¤¿¤á¡¢¥³¥Í¥¯¥·¥ç¥óξü¤Ç¤Î¼Â¹Ô¤¹¤ë¥³¡¼¥É¤ò´Ê·é¤Ë¤Ç¤­¤ë°ìÊý¤Ç¡¢ + Ʊ»þ¤Ë³«¤¯¥³¥Í¥¯¥·¥ç¥ó¤Ï¿¤¯¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    +

    ¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò³«¤¤¤¿¸å¤Ï¡¢¥³¥Í¥¯¥·¥ç¥ó¤Î¾õÂÖ¤Ï + ¼¡¤Î¤É¤ì¤«¤Ë¤Ê¤ê¤Þ¤¹:

    +
      +
    • Idle
      ¥³¥Í¥¯¥·¥ç¥ó¾å¤Ç½èÍý¤µ¤ì¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
    • +
    • Assigned
      ¥³¥Í¥¯¥·¥ç¥ó¤Ï¥ê¥¯¥¨¥¹¥È¤ò½èÍýÃæ¤Ç¤¹¡£
    • +
    +

    ¥³¥Í¥¯¥·¥ç¥ó¤¬ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¤Ë¥¢¥µ¥¤¥ó¤µ¤ì¤ë¤È¡¢´ðËÜŪ¤Ê¾ðÊó (Î㤨¤Ð + HTTP ¥Ø¥Ã¥ÀÅù) ¤¬°µ½Ì¤µ¤ì¤¿·Á (Î㤨¤ÐÄ̾ï¤Îʸ»úÎó¤ÏÀ°¿ô¤Ë¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹) + ¤ÇžÁ÷¤µ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï²¼µ­¤Î¡Ö¥ê¥¯¥¨¥¹¥È¥Ñ¥±¥Ã¥È¤Î¹½Â¤¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¥ê¥¯¥¨¥¹¥È¤Ë¥Ü¥Ç¥£¤¬Â¸ºß (content-length > 0) ¤¹¤ì¤Ð¡¢ + ´ðËÜŪ¤Ê¾ðÊó¤Îľ¸å¤ËÊ̥ѥ±¥Ã¥È¤ÇžÁ÷¤µ¤ì¤Þ¤¹¡£

    +

    ¤³¤Î»þÅÀ¤Ç¤ª¤½¤é¤¯¡¢¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤Ï½èÍý¤ò³«»Ï¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤Ç¤¹¤Î¤Ç¡¢¼¡¤Î¥á¥Ã¥»¡¼¥¸¤ò¥¦¥§¥Ö¥µ¡¼¥Ð¤ËÌᤷ¤ÆÃΤ餻¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
      +
    • SEND_HEADERS
      ¥Ö¥é¥¦¥¶¤Ë¥Ø¥Ã¥À¤òÁ÷¿®¤·¤Þ¤¹¡£
    • +
    • SEND_BODY_CHUNK
      ¥Ö¥é¥¦¥¶¤Ë¥Ü¥Ç¥£¥Ç¡¼¥¿¤Î¥Á¥ã¥ó¥¯¤òÁ÷¤ê¤Þ¤¹¡£ +
    • +
    • GET_BODY_CHUNK
      ¥ê¥¯¥¨¥¹¥È¤Î¥Ç¡¼¥¿¤òÁ´¤Æ¼õ¤±¼è¤ê½ª¤ï¤Ã¤Æ¤¤¤Ê¤¤¤È¤­¤Ë¡¢ + »Ä¤Ã¤Æ¤¤¤ë¥Ç¡¼¥¿¤ò¼õ¤±¼è¤ê¤Þ¤¹¡£¥Ñ¥±¥Ã¥È¤Ë¤¢¤ëÄê¤Þ¤Ã¤¿ºÇÂ獬¤¢¤ê¡¢Ç¤°Õ¤Î + Â礭¤µ¤Î¥Ç¡¼¥¿¤¬¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤È¤·¤Æ´Þ¤Þ¤ì¤¦¤ë¾ì¹ç + (Î㤨¤Ð¥Õ¥¡¥¤¥ë¤Î¥¢¥Ã¥×¥í¡¼¥É¤Î¾ì¹ç) ¤ËɬÍפȤʤê¤Þ¤¹¡£ + (Ãí: HTTP ¤Î¥Á¥ã¥ó¥¯Å¾Á÷¤È¤Ï´ØÏ¢¤¢¤ê¤Þ¤»¤ó¡£)
    • +
    • END_RESPONSE
      ¥ê¥¯¥¨¥¹¥È½èÍý¥µ¥¤¥¯¥ë¤ò½ªÎ»¤·¤Þ¤¹¡£
    • +
    +

    ¸Ä¡¹¤Î¥á¥Ã¥»¡¼¥¸¤Ï¤½¤ì¤¾¤ì°Û¤Ê¤ë¥Ç¡¼¥¿¥Ñ¥±¥Ã¥È·Á¼°¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¸å½Ò¤Î¡Ö¥ì¥¹¥Ý¥ó¥¹¥Ñ¥±¥Ã¥È¤Î¹½Â¤¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ´ðËܥѥ±¥Ã¥È¹½Â¤

    +

    ¤³¤Î¥×¥í¥È¥³¥ë¤Ë¤Ï XDR ¤«¤é¼õ¤±·Ñ¤¤¤ÀÉôʬ¤¬¾¯¤·¤¢¤ê¤Þ¤¹¤¬¡¢Â¿¤¯¤ÎÅÀ¤Ç + °Û¤Ê¤ê¤Þ¤¹ (Î㤨¤Ð 4 ¥Ð¥¤¥È¥¢¥é¥¤¥á¥ó¥È¤Ç¤Ê¤¤¤³¤È¤Ê¤É) ¡£

    +

    ¥Ð¥¤¥È¥ª¡¼¥À¡¼: ¸Ä¡¹¤Î¥Ð¥¤¥È¤Î¥¨¥ó¥Ç¥£¥¢¥ó¤¬¤É¤¦¤Ê¤Ã¤Æ¤¤¤ë¤«¤Ï¡¢ + »ä¤Ï¾Ü¤·¤¯¤Ê¤¤¤Î¤Ç¤¹¤¬¡¢¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È»×¤¤¤Þ¤¹¡£ + XDR »ÅÍͤǤ½¤¦¤Ê¤Ã¤Æ¤¤¤ë¤Î¤È¡¢ÁÇÀ²¤é¤·¤¤¤³¤È¤Ë sys/socket ¥é¥¤¥Ö¥é¥ê¤¬ + (C ¤Ç) ¤½¤¦¤¤¤¦É÷¤Ë¤Ç¤­¤Æ¤¤¤ë¤Î¤Ç¤½¤¦¤Ê¤Î¤À¤È»×¤¤¤Þ¤·¤¿¡£ + ¥½¥±¥Ã¥È¸Æ¤Ó½Ð¤·¤ÎÆâÉô¤Ë¤Ä¤¤¤Æ¤è¤ê¾Ü¤·¤¤Êý¤¬¤¤¤é¤Ã¤·¤ã¤¤¤Þ¤·¤¿¤é¡¢ + ¤´¶µ¼ø¤¯¤À¤µ¤¤¡£

    +

    ¥×¥í¥È¥³¥ë¤Ë¤Ï 4 ¤Ä¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤¬¤¢¤ê¤Þ¤¹: byte, boolean, + integer, string ¤Ç¤¹¡£

    +
    +
    Byte
    ¥Ð¥¤¥È°ì¤Ä¤Ç¤¹¡£
    +
    Boolean
    +
    ¥Ð¥¤¥È°ì¤Ä¤Ç¡¢1 = true, 0 = false ¤Ç¤¹¡£ + (C ¤Î¤è¤¦¤Ë) ÈóÎí¤ò¿¿¤È¤·¤Æ°·¤Ã¤Æ¤·¤Þ¤¦¤È¡¢¤¢¤ë¾ì¹ç¤ÏÆ°¤¯¤«¤â¤·¤ì¤Þ¤»¤ó¤·¡¢ + Æ°¤«¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    +
    Integer
    +
    0 ¤«¤é 2^16 (32768) ¤ÎÈϰϤοô»ú¡£¹â¼¡¤Î 2 ¥Ð¥¤¥È¤¬ + Àè¤Ë³ÊǼ¤µ¤ì¤Þ¤¹¡£
    +
    String
    +
    ²ÄÊÑŤÎʸ»úÎó (2^16 ¤¬Ä¹¤µ¤Î¾å¸Â) ¡£Ä¹¤µ¾ðÊó¤Î¥Ñ¥±¥Ã¥È 2 ¥Ð¥¤¥È¤Î¸å¤Ë + ʸ»úÎó (½ªÃ¼Ê¸»ú '\0' ¤ò´Þ¤à) ¤¬Â³¤¯·Á¼°¤Ç¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹¡£ + ¥¨¥ó¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ëŤµ¾ðÊó¤ÏºÇ¸å¤Î '\0' ¤ò¥«¥¦¥ó¥È¤·¤Ê¤¤ + ¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡½¡½¤³¤ì¤Ï strlen ¤ÈƱÍͤǤ¹¡£ + ¤³¤ì¤é¤Î½ªÃ¼Ê¸»ú¤ò¥¹¥­¥Ã¥×¤¹¤ë¤¿¤á¤Ë¡¢¤¢¤Þ¤ê°ÕÌ£¤Î̵¤¤¥¤¥ó¥¯¥ê¥á¥ó¥Èʸ + ¤ò¤¿¤¯¤µ¤ó½ñ¤«¤Ê¤¤¤È¤¤¤±¤Ê¤¤¤Î¤Ï¡¢ + Java ¤Î¦¤«¤é¸«¤ë¤È¾¯¤·Ê¶¤é¤ï¤·¤¯´¶¤¸¤é¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤³¤¦¤Ê¤Ã¤¿Íýͳ¤Ï¤ª¤½¤é¤¯¡¢Servlet ¥³¥ó¥Æ¥Ê¤«¤éÊÖ¤µ¤ì¤ëʸ»úÎó¤òÆɤ߽Ф¹»þ¤Ë¡¢ + ¸úΨ¤è¤¯ C ¤Î¥³¡¼¥É¤ò½ñ¤±¤ë¤è¤¦¤Ë¤¹¤ë¡½¡½¥µ¡¼¥Ö¥ì¥Ã¥È¤«¤éÊÖ¤µ¤ì¤ë + ʸ»úÎó¤Ï \0 ʸ»ú¤Ç½ªÃ¼¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢C ¤Î¥³¡¼¥É¤Ç¤Ï¤ï¤¶¤ï¤¶¥³¥Ô¡¼¤ò¤»¤º¤Ë¡¢ + °ì¤Ä¤Î¥Ð¥Ã¥Õ¥¡¤Ø¤Î¥ê¥Õ¥¡¥ì¥ó¥¹¤ò¼è¤ê²ó¤¹¤è¤¦¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¡½¡½ + ¤¿¤á¤À¤È»×¤ï¤ì¤Þ¤¹¡£ + '\0' ʸ»ú¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢C ¤Ç¤Ïʸ»úÎó¤Îµ¬Â§¤Ë¹ç¤¦¤è¤¦¤Ë¥³¥Ô¡¼¤·¤Ê¤±¤ì¤Ð + ¤¤¤±¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡£
    +
    + +

    ¥Ñ¥±¥Ã¥È¥µ¥¤¥º

    +

    ¿¤¯¤Î¥³¡¼¥É¤Ç¤½¤¦¤Ê¤Ã¤Æ¤¤¤ë¤Î¤Ç¤¹¤¬¡¢¥Ñ¥±¥Ã¥È¥µ¥¤¥º¤ÎºÇÂ祵¥¤¥º¤Ï + 8 * 1024 (8K) ¤Ç¤¹¡£¥Ñ¥±¥Ã¥È¤Î¼ÂºÝ¤ÎŤµ¤Ï¥Ø¥Ã¥À¤Ë + ¥¨¥ó¥³¡¼¥É¤µ¤ì¤ÆÆþ¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥Ñ¥±¥Ã¥È¥Ø¥Ã¥À

    +

    ¥µ¡¼¥Ð¤«¤é¥³¥ó¥Æ¥Ê¤ËÁ÷½Ð¤µ¤ì¤ë¥Ñ¥±¥Ã¥È¤Ï 0x1234 ¤Ç»Ï¤Þ¤ê¤Þ¤¹¡£ + ¥³¥ó¥Æ¥Ê¤«¤é¥µ¡¼¥Ð¤ËÁ÷¤é¤ì¤ë¥Ñ¥±¥Ã¥È¤Ï AB (ASCII ¥³¡¼¥É A ¤È + ASCII ¥³¡¼¥É B) ¤Ç»Ï¤Þ¤ê¤Þ¤¹¡£¤³¤ÎÆó¥Ð¥¤¥È¤Î¸å¤Ë¡¢¥Ú¥¤¥í¡¼¥ÉŤ¬ (¾åµ­¤Î·Á¼°¤Ç) + ³¤­¤Þ¤¹¡£¤³¤Î¤¿¤á¡¢¥Ú¥¤¥í¡¼¥ÉĹ¤ÎºÇÂçÃÍ¤Ï 2^16 ¤Ë¤Ç¤­¤ë¤è¤¦¤Ë»×¤¨¤Þ¤¹¤¬¡¢ + ¼ÂºÝ¤Ë¤Ï¥³¡¼¥É¤Ç¤ÏºÇÂçÃÍ¤Ï 8K ¤ËÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

    + + + + + + + + + + + + + + + + + + + +
    ¥Ñ¥±¥Ã¥È·Á¼° (Server->Container)
    Byte01234...(n+3)
    Contents0x120x34¥Ç¡¼¥¿Ä¹ (n)Data
    + + + + + + + + + + + + + + + + + + + +
    ¥Ñ¥±¥Ã¥È·Á¼° (Container->Server)
    Byte01234...(n+3)
    ContentsAB¥Ç¡¼¥¿Ä¹ (n)Data
    +

    ¤Û¤È¤ó¤É¤Î¥Ñ¥±¥Ã¥È¤Ç¡¢¥Ú¥¤¥í¡¼¥É¤ÎºÇ½é¤Î¥Ð¥¤¥È¤¬¥á¥Ã¥»¡¼¥¸¤Î·¿¤ò¥¨¥ó¥³¡¼¥É + ¤·¤Æ¤¤¤Þ¤¹¡£Îã³°¤Ï¥µ¡¼¥Ð¤«¤é¥³¥ó¥Æ¥Ê¤ËÁ÷¤é¤ì¤ë¥ê¥¯¥¨¥¹¥È¥Ü¥Ç¥£¥Ñ¥±¥Ã¥È¤Ç¤¹ + ¡½¡½¤³¤ì¤é¤Ïɸ½àŪ¤Ê¥Ñ¥±¥Ã¥È·Á¼° (0x1234 ¤È¥Ñ¥±¥Ã¥ÈĹ) + ¤Ç¤¹¤¬¡¢¤½¤Î¸å¤Ë³¤¯¥×¥ì¥Õ¥£¥Ã¥¯¥¹¥³¡¼¥É¤¬¤¢¤ê¤Þ¤»¤ó¡£

    +

    ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ï¼¡¤Î¥á¥Ã¥»¡¼¥¸¤ò¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤ËÁ÷½Ð¤Ç¤­¤Þ¤¹¡£

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥³¡¼¥É¥Ñ¥±¥Ã¥È¤Î·¿°ÕÌ£
    2Forward Request¥ê¥¯¥¨¥¹¥È½èÍý¥µ¥¤¥¯¥ë¤ò¸å³¤Î¥Ç¡¼¥¿¤È¤È¤â¤Ë³«»Ï¤¹¤ë¡£
    7Shutdown¥¦¥§¥Ö¥µ¡¼¥Ð¤¬¥³¥ó¥Æ¥Ê¤Ë¡¢¥³¥ó¥Æ¥Ê¤ò½ªÎ»¤¹¤ë¤è¤¦¤ËÅÁ¤¨¤ë¡£
    8Ping¥¦¥§¥Ö¥µ¡¼¥Ð¤¬¥³¥ó¥Æ¥Ê¤ËÀ©¸æ¤ò¼õ¤±»ý¤Ä¤è¤¦¤ËÅÁ¤¨¤ë + (¥»¥­¥å¥¢¥í¥°¥¤¥ó¥Õ¥§¡¼¥º) ¡£
    10CPing¥¦¥§¥Ö¥µ¡¼¥Ð¤¬¥³¥ó¥Æ¥Ê¤Ë CPong ¤Ç¨ºÂ¤Ë±þÅú¤¹¤ë¤è¤¦¤ËÅÁ¤¨¤ë¡£
    noneData¥µ¥¤¥º (2 ¥Ð¥¤¥È) ¤È¤½¤ì¤Ë³¤¯¥Ü¥Ç¥£¥Ç¡¼¥¿¡£
    +

    ´ðËÜŪ¤Ê¥»¥­¥å¥ê¥Æ¥£¤ò³ÎÊݤ¹¤ë¤¿¤á¡¢¥Û¥¹¥È¤µ¤ì¤Æ¤¤¤ë¥Þ¥·¥ó¤ÈƱ°ì¤Î + ¥Þ¥·¥ó¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤Î¤ß¡¢¥³¥ó¥Æ¥Ê¤Ï¼ÂºÝ¤Ë Shutdown + ¤ò¼Â¹Ô¤·¤Þ¤¹¡£

    +

    ºÇ½é¤Î Data ¥Ñ¥±¥Ã¥È¤Ï¡¢Forward Request + ¤Îľ¸å¤Ë¥¦¥§¥Ö¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤Þ¤¹¡£

    +

    ¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤Ï¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¡¢¼¡¤Î¥¿¥¤¥×¤Î¥á¥Ã¥»¡¼¥¸¤òÁ÷¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹ :

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¥³¡¼¥É¥Ñ¥±¥Ã¥È¤Î·¿°ÕÌ£
    3Send Body Chunk¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤«¤é¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë + (¤½¤·¤Æ¤ª¤½¤é¤¯¤½¤Î¤Þ¤Þ¥Ö¥é¥¦¥¶¤Ë)¡¢¥Ü¥Ç¥£¤Î¥Á¥ã¥ó¥¯¤òÁ÷¤ë¡£
    4Send Headers¥µ¡¼¥Ö¥ì¥Ã¥È¥³¥ó¥Æ¥Ê¤«¤é¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë (¤½¤·¤Æ¤ª¤½¤é¤¯¤½¤Î¤Þ¤Þ¥Ö¥é¥¦¥¶¤Ë) + ¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À¤òÁ÷¤ë¡£
    5End Response¥ì¥¹¥Ý¥ó¥¹ (¤Ä¤Þ¤ê¥ê¥¯¥¨¥¹¥È½èÍý¥µ¥¤¥¯¥ë) ½ªÎ»¤ÎÌÜ°õ¤òÁ÷¤ë¡£ +
    6Get Body Chunk¤Þ¤ÀÁ´¤ÆžÁ÷¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢»Ä¤Ã¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¤Î¥Ç¡¼¥¿¤ò¼õ¤±¼è¤ë¡£ +
    9CPong ±þÅúCPing ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¡£
    +

    ¾åµ­¥á¥Ã¥»¡¼¥¸¤Ï¡¢¤½¤ì¤¾¤ìÆâÉô¹½Â¤¤¬°Û¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¾ÜºÙ¤Ï²¼µ­¤ò¤´Í÷¤¯¤À¤µ¤¤¡£ +

    + +
    top
    +
    +

    ¥ê¥¯¥¨¥¹¥È¥Ñ¥±¥Ã¥È¹½Â¤

    +

    ¥µ¡¼¥Ð¤«¤é¥³¥ó¥Æ¥Ê¤ØÁ÷¤é¤ì¤ë¥á¥Ã¥»¡¼¥¸¤¬ + Forward Request ·¿¤Î¾ì¹ç :

    +
    +AJP13_FORWARD_REQUEST :=
    +    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    +    method           (byte)
    +    protocol         (string)
    +    req_uri          (string)
    +    remote_addr      (string)
    +    remote_host      (string)
    +    server_name      (string)
    +    server_port      (integer)
    +    is_ssl           (boolean)
    +    num_headers      (integer)
    +    request_headers *(req_header_name req_header_value)
    +    attributes      *(attribut_name attribute_value)
    +    request_terminator (byte) OxFF
    +    
    +

    request_headers ¤Ï¼¡¤Î¤è¤¦¤Ê¹½Â¤¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹ : +

    +req_header_name := 
    +    sc_req_header_name | (string)  [see below for how this is parsed]
    +
    +sc_req_header_name := 0xA0xx (integer)
    +
    +req_header_value := (string)
    +
    +

    °À­ ¤Ï¥ª¥×¥·¥ç¥ó¤Ç¡¢¼¡¤Î¤è¤¦¤Ê¹½Â¤¤ò¤·¤Æ¤¤¤Þ¤¹ :

    +
    +attribute_name := sc_a_name | (sc_a_req_attribute string)
    +
    +attribute_value := (string)
    +
    +    
    +

    ¤â¤Ã¤È¤â½ÅÍפʥإåÀ¤Ï content-length ¤À¤È¤¤¤¦¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥³¥ó¥Æ¥Ê¤Ï¼¡¤Î¥Ñ¥±¥Ã¥È¤òõ¤¹¤«¤É¤¦¤«¤ò¡¢ + ¤½¤ì¤ò¸«¤Æ·è¤á¤ë¤«¤é¤Ç¤¹¡£

    +

    Forward Request Í×ÁǤξܺ٤ÊÀâÌÀ +

    +

    Request prefix

    +

    ¥ê¥¯¥¨¥¹¥È¤Ë¤Ä¤¤¤Æ¤ÏÁ´¤Æ¡¢¤³¤ÎÃÍ¤Ï 2 ¤Ë¤Ê¤ê¤Þ¤¹¡£Â¾¤Î Prefix ¥³¡¼¥É¤Î¾ÜºÙ¤Ï + ¾åµ­¤ò¤´Í÷¤¯¤À¤µ¤¤¡£

    + +

    Method

    +

    HTTP ¥á¥½¥Ã¥É¤Ï 1 ¥Ð¥¤¥È¤Ë¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹ :

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Command NameCode
    OPTIONS1
    GET2
    HEAD3
    POST4
    PUT5
    DELETE6
    TRACE7
    PROPFIND8
    PROPPATCH9
    MKCOL10
    COPY11
    MOVE12
    LOCK13
    UNLOCK14
    ACL15
    REPORT16
    VERSION-CONTROL17
    CHECKIN18
    CHECKOUT19
    UNCHECKOUT20
    SEARCH21
    MKWORKSPACE22
    UPDATE23
    LABEL24
    MERGE25
    BASELINE_CONTROL26
    MKACTIVITY27
    +

    º£¸å¤Î ajp13 ¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢¤³¤Î°ìÍ÷¤Ë¤Ê¤¤¡¢º£¸åÄɲ䵤ì¤ë¥á¥½¥Ã¥É¤ò + Á÷¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    protocol, req_uri, remote_addr, remote_host, server_name, + server_port, is_ssl

    +

    ¤³¤ì¤é¤Ï¤Þ¤µ¤Ëʸ»úÄ̤ê¤Î¤â¤Î¤Ç¤¹¡£¤É¤ì¤âɬÍפǡ¢¥ê¥¯¥¨¥¹¥È¤ÎËè²ó¤Ë¤Ä¤­ + Á÷¤é¤ì¤Þ¤¹¡£

    + +

    Headers

    +

    request_headers ¤Î¹½Â¤¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤¹ : + ¤Þ¤º¥Ø¥Ã¥À¤Î¿ô num_headers ¤¬¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹¡£ + ¼¡¤Ë¥Ø¥Ã¥À̾ req_header_name / ÃÍ req_header_value + ¤ÎÁȤ¬Â³¤­¤Þ¤¹¡£¸úΨ¤Î¤¿¤á¡¢°ìÈÌŪ¤Ê¥Ø¥Ã¥À¤ÏÀ°¿ô¤Ç¥¨¥ó¥³¡¼¥É¤·¤ÆžÁ÷¤·¤Þ¤¹¡£ + ¥Ø¥Ã¥À̾¤¬´ðËܥإåÀ¤Î°ìÍ÷¤Ë̵¤¤¾ì¹ç¤Ï¡¢Ä̾ïÄ̤ê (ʸ»úÎó¤È¤·¤Æ¡¢Ä¹¤µ + ¥×¥ì¥Õ¥£¥Ã¥¯¥¹ÉÕ¤­¤Ç) žÁ÷¤µ¤ì¤Þ¤¹¡£°ìÈÌŪ¤Ê¥Ø¥Ã¥À + sc_req_header_name ¤Î°ìÍ÷¤È¤½¤Î¥³¡¼¥É¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹ + (¤É¤ì¤âÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Þ¤¹) :

    + + + + + + + + + + + + + + + + + + + +
    ̾Á°¥³¡¼¥É¤ÎÃÍ¥³¡¼¥É̾
    accept0xA001SC_REQ_ACCEPT
    accept-charset0xA002SC_REQ_ACCEPT_CHARSET +
    accept-encoding0xA003SC_REQ_ACCEPT_ENCODING +
    accept-language0xA004SC_REQ_ACCEPT_LANGUAGE +
    authorization0xA005SC_REQ_AUTHORIZATION
    connection0xA006SC_REQ_CONNECTION
    content-type0xA007SC_REQ_CONTENT_TYPE
    content-length0xA008SC_REQ_CONTENT_LENGTH
    cookie0xA009SC_REQ_COOKIE
    cookie20xA00ASC_REQ_COOKIE2
    host0xA00BSC_REQ_HOST
    pragma0xA00CSC_REQ_PRAGMA
    referer0xA00DSC_REQ_REFERER
    user-agent0xA00ESC_REQ_USER_AGENT
    +

    ¤³¤ì¤òÆɤ߹þ¤à Java ¤Î¥³¡¼¥É¤Ç¤Ï¡¢ºÇ½é¤Î 2 ¥Ð¥¤¥ÈÀ°¿ô¤ò¼è¤ê¹þ¤ß¡¢ + ÌÜ°õ¤Ë¤Ê¤ë¥Ð¥¤¥È '0xA0' ¤Ç¤¢¤ì¤Ð¡¢¥Ø¥Ã¥À̾¤ÎÇÛÎó¤Î + ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¤¤Þ¤¹¡£ÀèƬ¥Ð¥¤¥È¤¬ 0xA0 ¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢ + ÀèƬ 2 ¥Ð¥¤¥È¤Ïʸ»úÎóŤòɽ¤¹À°¿ô¤Ç¤¢¤ë¤È²ò¼á¤·¡¢Æɤ߹þ¤ß¤Ï¤¸¤á¤Þ¤¹¡£

    +

    ¥Ø¥Ã¥À̾¤ÎŤµ¤Ï 0x9999 (==0xA000 -1) °Ê¾å¤Ë¤Ê¤é¤Ê¤¤¤È¤¤¤¦ + ²¾Äê¤Î²¼¤ËÆ°¤¤¤Æ¤¤¤Æ¡¢¾¯¤·¤¢¤¤¤Þ¤¤¤Ç¤¹¤¬¹çÍýŪ¤ÊµóÆ°¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    +

    Ãí:

    + content-length ¥Ø¥Ã¥À¤Ï¤È¤Æ¤â½ÅÍפǤ¹¡£ + ¸ºß¤·¤Æ¤¤¤ÆÈó¥¼¥í¤Ç¤¢¤ì¤Ð¡¢¥ê¥¯¥¨¥¹¥È¤Ë¤Ï¥Ü¥Ç¥£¤¬¤¢¤ë (Î㤨¤Ð POST + ¥ê¥¯¥¨¥¹¥È) ¤È¿ä¬¤·¡¢¤½¤Î¥Ü¥Ç¥£¤ò¼è¤ê¹þ¤à¤¿¤á¤Ë + ľ¸å¤Î¥Ñ¥±¥Ã¥È¤òÆþÎÏ¥¹¥È¥ê¡¼¥à¤«¤éÆɤ߹þ¤ß¤Ï¤¸¤á¤Þ¤¹¡£ +
    + +

    °À­

    +

    ? ¥×¥ì¥Õ¥£¥Ã¥¯¥¹¤Ç»Ï¤Þ¤ë°À­ (Îã ?context) + ¤Ï¡£¾Êά²Äǽ¤Ç¤¹¡£¤½¤ì¤¾¤ì°À­¤Î·¿¤ò¼¨¤¹ 1 ¥Ð¥¤¥È¤Î¥³¡¼¥É¤È¡¢ + ÃͤÎʸ»úÎó¤¬Â³¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï½çÉÔƱ¤ÇÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹ (C ¤Î¥³¡¼¥É¤Ï¾ï¤Ë²¼¤Î°ìÍ÷½ç¤Ë + Á÷¤ë¤è¤¦¤Ç¤¹¤¬) ¡£ + ¥ª¥×¥·¥ç¥ó¤Î°À­¤Î¥ê¥¹¥È¤ÎºÇ¸å¤Ë¤Ï¡¢ÆÃÊ̤ʽªÎ»¥³¡¼¥É¤¬Á÷¤é¤ì¤Þ¤¹¡£ + ¥³¡¼¥É¤Î°ìÍ÷¤Ï :

    + + + + + + + + + + + + + + +
    InformationCode ValueNote
    ?context0x01̤¼ÂÁõ +
    ?servlet_path0x02̤¼ÂÁõ +
    ?remote_user0x03
    ?auth_type0x04
    ?query_string0x05
    ?jvm_route0x06
    ?ssl_cert0x07
    ?ssl_cipher0x08
    ?ssl_session0x09
    ?req_attribute0x0AName (the name of the + attribute follows)
    ?ssl_key_size0x0B
    are_done0xFFrequest_terminator
    +

    context ¤È servlet_path ¤Ï¸½ºß¤Î C ¤Î + ¥³¡¼¥É¤Ç¤Ï¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤Þ¤¿¡¢¤Û¤È¤ó¤É¤Î Java ¤Î¥³¡¼¥É¤Ç¤â¡¢ + ¤³¤Î¥Õ¥£¡¼¥ë¥É¤Ç²¿¤¬Á÷¤é¤ì¤Æ¤â̵»ë¤µ¤ì¤Þ¤¹ (¤³¤ì¤é¤Î¥³¡¼¥É¤Î¸å¤Ëʸ»úÎó¤¬ + Á÷¤é¤ì¤ë¤È²õ¤ì¤ë¤â¤Î¤â¤¢¤ê¤Þ¤¹)¡£ + ¤³¤ì¤¬¥Ð¥°¤Ê¤Î¤«¡¢Ã±¤Ë̤¼ÂÁõ¤Ê¤Î¤«¡¢Îò»ËŪ·Ð°Þ¤Ç»Ä¤Ã¤Æ¤¤¤ë¥³¡¼¥É¤Ê¤Î¤« + ʬ¤«¤ê¤Þ¤»¤ó¤¬¡¢¥³¥Í¥¯¥·¥ç¥ó¤Îξ¦¤È¤â¤Ç¸«Åö¤¿¤ê¤Þ¤»¤ó¡£

    +

    remote_user ¤È auth_type ¤Ï¤ª¤½¤é¤¯ + HTTP ¥ì¥Ù¥ë¤Îǧ¾Ú¤ò»²¾È¤·¤Æ¤¤¤Æ¡¢¥ê¥â¡¼¥È¥æ¡¼¥¶¤Î¥æ¡¼¥¶Ì¾¤Èǧ¾Ú¤Ë»ÈÍѤ·¤¿ + ¥¿¥¤¥× (Îã Basic, Digest) ¤Ë¤Ä¤¤¤Æ¤ä¤ê¼è¤ê¤·¤Þ¤¹¡£

    +

    query_string, ssl_cert, + ssl_cipher, ssl_session + ¤Ï HTTP ¤È HTTPS ¤ÎÂбþ¤¹¤ëÉôʬ¤ò»²¾È¤·¤Þ¤¹¡£

    +

    jvm_route ¤Ï¥¹¥Æ¥£¥Ã¥­¡¼¥»¥Ã¥·¥ç¥ó¤Î¥µ¥Ý¡¼¥È¡½¡½ + ¥í¡¼¥É¥Ð¥é¥ó¥¹¤·¤Æ¤¤¤ëÊ£¿ô¤Î¥µ¡¼¥ÐÃæ¤ÎÆÃÄê¤Î Tomcat ¥¤¥ó¥¹¥¿¥ó¥¹¤È¡¢ + ¥æ¡¼¥¶¤Î¥»¥Ã¥·¥ç¥ó¤È¤òɳÉÕ¤±¤ëµ¡Ç½¡½¡½¤Ë»È¤ï¤ì¤Þ¤¹¡£

    +

    ¤³¤Î´ðËÜ°À­°ìÍ÷¤Ë̵¤¤¤â¤Î¤Ë¤Ä¤¤¤Æ¤Ï¡¢req_attribute + ¥³¡¼¥É 0x0A ·Ðͳ¤Ç°À­¤ò²¿¸Ä¤Ç¤âÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + °À­¤Î̾Á°¤ÈÃͤÎʸ»úÎó¤ÎÁȤò¡¢¤½¤ì¤¾¤ì¤³¤Î¥³¡¼¥É¤Îľ¸å¤ËÁ÷¤ê¤Þ¤¹¡£ + ´Ä¶­ÊÑ¿ô¤Ï¤³¤ÎÊýË¡¤ÇÅÁ¤¨¤é¤ì¤Þ¤¹¡£

    +

    ºÇ¸å¤Ë°À­¤¬Á´¤ÆÁ÷¿®¤µ¤ì¤¿¸å¤Ë¡¢Â°À­¤Î½ªÃ¼¤ò¼¨¤¹ 0xFF + ¤¬Á÷½Ð¤µ¤ì¤Þ¤¹¡£¤³¤Î¿®¹æ¤Ï°À­¤Î°ìÍ÷¤Î½ª¤ï¤ê¤ò¼¨¤¹¤ÈƱ»þ¤Ë¡¢¥ê¥¯¥¨¥¹¥È + ¥Ñ¥±¥Ã¥È¤Î½ªÃ¼¤ò¤â¼¨¤·¤Æ¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥ì¥¹¥Ý¥ó¥¹¥Ñ¥±¥Ã¥È¹½Â¤

    +

    ¥³¥ó¥Æ¥Ê¤¬¥µ¡¼¥Ð¤ËÁ÷¤êÊÖ¤¹¤³¤È¤Î¤Ç¤­¤ë¥á¥Ã¥»¡¼¥¸:

    +
    +AJP13_SEND_BODY_CHUNK :=
    +  prefix_code   3
    +  chunk_length  (integer)
    +  chunk        *(byte)
    +
    +
    +AJP13_SEND_HEADERS :=
    +  prefix_code       4
    +  http_status_code  (integer)
    +  http_status_msg   (string)
    +  num_headers       (integer)
    +  response_headers *(res_header_name header_value)
    +
    +res_header_name :=
    +    sc_res_header_name | (string)   [see below for how this is parsed]
    +
    +sc_res_header_name := 0xA0 (byte)
    +
    +header_value := (string)
    +
    +AJP13_END_RESPONSE :=
    +  prefix_code       5
    +  reuse             (boolean)
    +
    +
    +AJP13_GET_BODY_CHUNK :=
    +  prefix_code       6
    +  requested_length  (integer)
    +    
    +

    ¾ÜºÙ :

    +

    Send Body Chunk

    +

    ¥Á¥ã¥ó¥¯¤Ï´ðËÜŪ¤Ë¤Ï¥Ð¥¤¥Ê¥ê¥Ç¡¼¥¿¤Ç¡¢¥Ö¥é¥¦¥¶¤ËľÀÜÁ÷¤é¤ì¤Þ¤¹¡£

    + +

    Send Headers

    +

    ¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É¤È¥á¥Ã¥»¡¼¥¸¤¬Ä̾ï¤Î HTTP ¤ÎÄÌ¿®¤Ë¤Ï¤¢¤ê¤Þ¤¹ (Îã + 200 ¤È OK)¡£¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À̾¤Ï¡¢ + ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À̾¤ÈƱÍͤÎÊýË¡¤Ç¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹¡£ + ¥³¡¼¥É¤Èʸ»úÎó¤ÎȽÊÌÊýË¡¤Î¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï¡¢¾åµ­¤Î header_encoding + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ + °ìÈÌŪ¤Ê¥Ø¥Ã¥À¤Î¥³¡¼¥É¤Ï :

    + + + + + + + + + + + + + +
    ̾Á°¥³¡¼¥É¤ÎÃÍ
    Content-Type0xA001
    Content-Language0xA002
    Content-Length0xA003
    Date0xA004
    Last-Modified0xA005
    Location0xA006
    Set-Cookie0xA007
    Set-Cookie20xA008
    Servlet-Engine0xA009
    Status0xA00A
    WWW-Authenticate0xA00B
    +

    ¥³¡¼¥É¤«¥Ø¥Ã¥Àʸ»úÎó¤Îľ¸å¤Ë¤Ï¡¢¥Ø¥Ã¥À¤ÎÃͤ¬¥¨¥ó¥³¡¼¥É¤µ¤ì¤Þ¤¹¡£

    + +

    End Response

    +

    ¥ê¥¯¥¨¥¹¥È½èÍý¥µ¥¤¥¯¥ë¤Î½ªÎ»¤òÃΤ餻¤Þ¤¹¡£reuse ¥Õ¥é¥°¤¬¿¿ + (==1) ¤Î¾ì¹ç¡¢¸½ºß»ÈÍѤ·¤Æ¤¤¤ë TCP ¥³¥Í¥¯¥·¥ç¥ó¤Ï¼¡¤Î¿·¤·¤¤ + ¥ê¥¯¥¨¥¹¥È¤Ë»È¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£reuse ¤¬µ¶ (C ¤Î¥³¡¼¥É¤Ç¤Ï + 1 °Ê³°¤ÎÁ´¤Æ) ¤Î¾ì¹ç¤Ï¡¢¥³¥Í¥¯¥·¥ç¥ó¤òÊĤ¸¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Get Body Chunk

    +

    (¥Ü¥Ç¥£¤Î¥µ¥¤¥º¤¬Â礭¤¹¤®¤ÆºÇ½é¤Î¥Ñ¥±¥Ã¥È¤Ë¼ý¤Þ¤é¤Ê¤¤¾ì¹ç¤ä¡¢ + ¥ê¥¯¥¨¥¹¥È¤¬¥Á¥ã¥ó¥¯Å¾Á÷¤µ¤ì¤¿¾ì¹ç¤Ê¤É¤Ë¤Ï¡¢) ¥³¥ó¥Æ¥Ê¤Ï¥ê¥¯¥¨¥¹¥È¤«¤é¤Î + ¥Ç¡¼¥¿Æɤ߹þ¤ßÍ×µá¤ò¤·¤Þ¤¹¡£¥µ¡¼¥Ð¦¤Ï¤½¤ì¤ËÂФ·¤Æ¡¢ºÇ¾® + request_length ºÇÂç (8186 (8 Kbytes - 6)) + ¤ÎÈϰϤǡ¢Ì¤Å¾Á÷¤Ç»Ä¤Ã¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È¥Ü¥Ç¥£¤ÎÂ礭¤µ¤Î¥Ç¡¼¥¿¤ò + Á÷¤êÊÖ¤·¤Þ¤¹¡£
    + ¥Ü¥Ç¥£¤Ë¤½¤ì°Ê¾å¥Ç¡¼¥¿¤¬»Ä¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç (¤Ä¤Þ¤ê¥µ¡¼¥Ö¥ì¥Ã¥È¤¬ + ¥Ü¥Ç¥£¤ÎºÇ¸å¤òĶ¤¨¤ÆÆɤ߹þ¤â¤¦¤È¤·¤¿¾ì¹ç) ¡¢¥µ¡¼¥Ð¤Ï + ¥Ú¥¤¥í¡¼¥ÉĹ 0 ¤Î¶õ¥Ñ¥±¥Ã¥È(0x12,0x34,0x00,0x00) + ¤òÁ÷¤êÊÖ¤·¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.xml b/trunk/docs/manual/mod/mod_proxy_ajp.xml new file mode 100644 index 0000000000..326b91d692 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.xml @@ -0,0 +1,539 @@ + + + + + + + + + +mod_proxy_ajp +AJP support module for +mod_proxy +Extension +proxy_ajp.c +proxy_ajp_module +Available in version 2.1 and later + + +

    This module requires the service of mod_proxy. It provides support for the + Apache JServ Protocol version 1.3 (hereafter + AJP13).

    + +

    Thus, in order to get the ability of handling AJP13 + protocol, mod_proxy and + mod_proxy_ajp have to be present in the server.

    + + Warning +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    + +mod_proxy + +
    Overview of the protocol +

    The AJP13 protocol is packet-oriented. A binary format + was presumably chosen over the more readable plain text for reasons of + performance. The web server communicates with the servlet container over + TCP connections. To cut down on the expensive process of socket creation, + the web server will attempt to maintain persistent TCP connections to the + servlet container, and to reuse a connection for multiple request/response + cycles.

    +

    Once a connection is assigned to a particular request, it will not be + used for any others until the request-handling cycle has terminated. In + other words, requests are not multiplexed over connections. This makes + for much simpler code at either end of the connection, although it does + cause more connections to be open at once.

    +

    Once the web server has opened a connection to the servlet container, + the connection can be in one of the following states:

    +
      +
    • Idle
      No request is being handled over this connection.
    • +
    • Assigned
      The connecton is handling a specific request.
    • +
    +

    Once a connection is assigned to handle a particular request, the basic + request informaton (e.g. HTTP headers, etc) is sent over the connection in + a highly condensed form (e.g. common strings are encoded as integers). + Details of that format are below in Request Packet Structure. If there is a + body to the request (content-length > 0), that is sent in a + separate packet immediately after.

    +

    At this point, the servlet container is presumably ready to start + processing the request. As it does so, it can send the + following messages back to the web server:

    +
      +
    • SEND_HEADERS
      Send a set of headers back to the browser.
    • +
    • SEND_BODY_CHUNK
      Send a chunk of body data back to the browser. +
    • +
    • GET_BODY_CHUNK
      Get further data from the request if it hasn't all + been transferred yet. This is necessary because the packets have a fixed + maximum size and arbitrary amounts of data can be included the body of a + request (for uploaded files, for example). (Note: this is unrelated to + HTTP chunked tranfer).
    • +
    • END_RESPONSE
      Finish the request-handling cycle.
    • +
    +

    Each message is accompanied by a differently formatted packet of data. + See Response Packet Structures below for details.

    +
    + +
    Basic Packet Structure +

    There is a bit of an XDR heritage to this protocol, but it differs + in lots of ways (no 4 byte alignment, for example).

    +

    Byte order: I am not clear about the endian-ness of the individual + bytes. I'm guessing the bytes are little-endian, because that's what + XDR specifies, and I'm guessing that sys/socket library is magically + making that so (on the C side). If anyone with a better knowledge of + socket calls can step in, that would be great.

    +

    There are four data types in the protocol: bytes, booleans, + integers and strings.

    +
    +
    Byte
    A single byte.
    +
    Boolean
    +
    A single byte, 1 = true, 0 = false. + Using other non-zero values as true (i.e. C-style) may work in some places, + but it won't in others.
    +
    Integer
    +
    A number in the range of 0 to 2^16 (32768). Stored in + 2 bytes with the high-order byte first.
    +
    String
    +
    A variable-sized string (length bounded by 2^16). Encoded with + the length packed into two bytes first, followed by the string + (including the terminating '\0'). Note that the encoded length does + not include the trailing '\0' -- it is like + strlen. This is a touch confusing on the Java side, which + is littered with odd autoincrement statements to skip over these + terminators. I believe the reason this was done was to allow the C + code to be extra efficient when reading strings which the servlet + container is sending back -- with the terminating \0 character, the + C code can pass around references into a single buffer, without copying. + if the \0 was missing, the C code would have to copy things out in order + to get its notion of a string.
    +
    + +
    Packet Size +

    According to much of the code, the max packet size is + 8 * 1024 bytes (8K). The actual length of the packet is encoded in + the header.

    +
    +
    Packet Headers +

    Packets sent from the server to the container begin with + 0x1234. Packets sent from the container to the server + begin with AB (that's the ASCII code for A followed by the + ASCII code for B). After those first two bytes, there is an integer + (encoded as above) with the length of the payload. Although this might + suggest that the maximum payload could be as large as 2^16, in fact, the + code sets the maximum to be 8K.

    + + + + + + + + + + + + + + + + + + + +
    Packet Format (Server->Container)
    Byte01234...(n+3)
    Contents0x120x34Data Length (n)Data
    + + + + + + + + + + + + + + + + + + + +
    Packet Format (Container->Server)
    Byte01234...(n+3)
    ContentsABData Length (n)Data
    +

    For most packets, the first byte of the payload encodes the type of + message. The exception is for request body packets sent from the server to + the container -- they are sent with a standard packet header ( + 0x1234 and then length of the packet), but without any prefix code + after that.

    +

    The web server can send the following messages to the servlet + container:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeType of PacketMeaning
    2Forward RequestBegin the request-processing cycle with the following data
    7ShutdownThe web server asks the container to shut itself down.
    8PingThe web server asks the container to take control + (secure login phase).
    10CPingThe web server asks the container to respond quickly with a CPong. +
    noneDataSize (2 bytes) and corresponding body data.
    +

    To ensure some basic security, the container will only actually do the + Shutdown if the request comes from the same machine on which + it's hosted.

    +

    The first Data packet is send immediatly after the + Forward Request by the web server.

    +

    The servlet container can send the following types of messages to the + webserver:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeType of PacketMeaning
    3Send Body ChunkSend a chunk of the body from the servlet container to the web + server (and presumably, onto the browser).
    4Send HeadersSend the response headers from the servlet container to the web + server (and presumably, onto the browser).
    5End ResponseMarks the end of the response (and thus the request-handling cycle). +
    6Get Body ChunkGet further data from the request if it hasn't all been + transferred yet.
    9CPong ReplyThe reply to a CPing request
    +

    Each of the above messages has a different internal structure, detailed + below.

    +
    +
    +
    Request Packet Structure +

    For messages from the server to the container of type + Forward Request:

    +
    +AJP13_FORWARD_REQUEST :=
    +    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    +    method           (byte)
    +    protocol         (string)
    +    req_uri          (string)
    +    remote_addr      (string)
    +    remote_host      (string)
    +    server_name      (string)
    +    server_port      (integer)
    +    is_ssl           (boolean)
    +    num_headers      (integer)
    +    request_headers *(req_header_name req_header_value)
    +    attributes      *(attribut_name attribute_value)
    +    request_terminator (byte) OxFF
    +    
    +

    The request_headers have the following structure: +

    +req_header_name := 
    +    sc_req_header_name | (string)  [see below for how this is parsed]
    +
    +sc_req_header_name := 0xA0xx (integer)
    +
    +req_header_value := (string)
    +
    +

    The attributes are optional and have the following + structure:

    +
    +attribute_name := sc_a_name | (sc_a_req_attribute string)
    +
    +attribute_value := (string)
    +
    +    
    +

    Not that the all-important header is content-length, + because it determines whether or not the container looks for another + packet immediately.

    +
    Detailed description of the elements of Forward Request +
    +
    Request prefix +

    For all requests, this will be 2. See above for details on other Prefix + codes.

    +
    +
    Method +

    The HTTP method, encoded as a single byte:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Command NameCode
    OPTIONS1
    GET2
    HEAD3
    POST4
    PUT5
    DELETE6
    TRACE7
    PROPFIND8
    PROPPATCH9
    MKCOL10
    COPY11
    MOVE12
    LOCK13
    UNLOCK14
    ACL15
    REPORT16
    VERSION-CONTROL17
    CHECKIN18
    CHECKOUT19
    UNCHECKOUT20
    SEARCH21
    MKWORKSPACE22
    UPDATE23
    LABEL24
    MERGE25
    BASELINE_CONTROL26
    MKACTIVITY27
    +

    Later version of ajp13, will transport + additional methods, even if they are not in this list.

    +
    +
    protocol, req_uri, remote_addr, remote_host, server_name, + server_port, is_ssl +

    These are all fairly self-explanatory. Each of these is required, and + will be sent for every request.

    +
    +
    Headers +

    The structure of request_headers is the following: + First, the number of headers num_headers is encoded. + Then, a series of header name req_header_name / value + req_header_value pairs follows. + Common header names are encoded as integers, + to save space. If the header name is not in the list of basic headers, + it is encoded normally (as a string, with prefixed length). The list of + common headers sc_req_header_nameand their codes + is as follows (all are case-sensitive):

    + + + + + + + + + + + + + + + + + + + +
    NameCode valueCode name
    accept0xA001SC_REQ_ACCEPT
    accept-charset0xA002SC_REQ_ACCEPT_CHARSET +
    accept-encoding0xA003SC_REQ_ACCEPT_ENCODING +
    accept-language0xA004SC_REQ_ACCEPT_LANGUAGE +
    authorization0xA005SC_REQ_AUTHORIZATION
    connection0xA006SC_REQ_CONNECTION
    content-type0xA007SC_REQ_CONTENT_TYPE
    content-length0xA008SC_REQ_CONTENT_LENGTH
    cookie0xA009SC_REQ_COOKIE
    cookie20xA00ASC_REQ_COOKIE2
    host0xA00BSC_REQ_HOST
    pragma0xA00CSC_REQ_PRAGMA
    referer0xA00DSC_REQ_REFERER
    user-agent0xA00ESC_REQ_USER_AGENT
    +

    The Java code that reads this grabs the first two-byte integer and if + it sees an '0xA0' in the most significant + byte, it uses the integer in the second byte as an index into an array of + header names. If the first byte is not 0xA0, it assumes that + the two-byte integer is the length of a string, which is then read in.

    +

    This works on the assumption that no header names will have length + greater than 0x9999 (==0xA000 - 1), which is perfectly + reasonable, though somewhat arbitrary.

    + Note: + The content-length header is extremely + important. If it is present and non-zero, the container assumes that + the request has a body (a POST request, for example), and immediately + reads a separate packet off the input stream to get that body. + +
    +
    Attributes +

    The attributes prefixed with a ? + (e.g. ?context) are all optional. For each, there is a + single byte code to indicate the type of attribute, and then a string to + give its value. They can be sent in any order (thogh the C code always + sends them in the order listed below). A special terminating code is + sent to signal the end of the list of optional attributes. The list of + byte codes is:

    + + + + + + + + + + + + + + +
    InformationCode ValueNote
    ?context0x01Not currently implemented +
    ?servlet_path0x02Not currently implemented +
    ?remote_user0x03
    ?auth_type0x04
    ?query_string0x05
    ?jvm_route0x06
    ?ssl_cert0x07
    ?ssl_cipher0x08
    ?ssl_session0x09
    ?req_attribute0x0AName (the name of the + attribute follows)
    ?ssl_key_size0x0B
    are_done0xFFrequest_terminator
    +

    The context and servlet_path are not + currently set by the C code, and most of the Java code completely ignores + whatever is sent over for those fields (and some of it will actually break + if a string is sent along after one of those codes). I don't know if this + is a bug or an unimplemented feature or just vestigial code, but it's + missing from both sides of the connection.

    +

    The remote_user and auth_type presumably + refer to HTTP-level authentication, and communicate the remote user's + username and the type of authentication used to establish their identity + (e.g. Basic, Digest).

    +

    The query_string, ssl_cert, + ssl_cipher, and ssl_session refer to the + corresponding pieces of HTTP and HTTPS.

    +

    The jvm_route, is used to support sticky + sessions -- associating a user's sesson with a particular Tomcat instance + in the presence of multiple, load-balancing servers.

    +

    Beyond this list of basic attributes, any number of other attributes + can be sent via the req_attribute code 0x0A. + A pair of strings to represent the attribute name and value are sent + immediately after each instance of that code. Environment values are passed + in via this method.

    +

    Finally, after all the attributes have been sent, the attribute + terminator, 0xFF, is sent. This signals both the end of the + list of attributes and also then end of the Request Packet.

    +
    +
    + +
    Response Packet Structure +

    for messages which the container can send back to the server.

    +
    +AJP13_SEND_BODY_CHUNK :=
    +  prefix_code   3
    +  chunk_length  (integer)
    +  chunk        *(byte)
    +
    +
    +AJP13_SEND_HEADERS :=
    +  prefix_code       4
    +  http_status_code  (integer)
    +  http_status_msg   (string)
    +  num_headers       (integer)
    +  response_headers *(res_header_name header_value)
    +
    +res_header_name :=
    +    sc_res_header_name | (string)   [see below for how this is parsed]
    +
    +sc_res_header_name := 0xA0 (byte)
    +
    +header_value := (string)
    +
    +AJP13_END_RESPONSE :=
    +  prefix_code       5
    +  reuse             (boolean)
    +
    +
    +AJP13_GET_BODY_CHUNK :=
    +  prefix_code       6
    +  requested_length  (integer)
    +    
    +
    Details:
    +
    Send Body Chunk +

    The chunk is basically binary data, and is sent directly back to the + browser.

    +
    +
    Send Headers +

    The status code and message are the usual HTTP things + (e.g. 200 and OK). The response header names are + encoded the same way the request header names are. See header_encoding above + for details about how the the codes are distinguished from the strings.
    + The codes for common headers are:

    + + + + + + + + + + + + + +
    NameCode value
    Content-Type0xA001
    Content-Language0xA002
    Content-Length0xA003
    Date0xA004
    Last-Modified0xA005
    Location0xA006
    Set-Cookie0xA007
    Set-Cookie20xA008
    Servlet-Engine0xA009
    Status0xA00A
    WWW-Authenticate0xA00B
    +

    After the code or the string header name, the header value is + immediately encoded.

    +
    +
    End Response +

    Signals the end of this request-handling cycle. If the + reuse flag is true (==1), this TCP connection can + now be used to handle new incoming requests. If reuse is false + (anything other than 1 in the actual C code), the connection should + be closed.

    +
    +
    Get Body Chunk +

    The container asks for more data from the request (If the body was + too large to fit in the first packet sent over or when the request is + chuncked). The server will send a body packet back with an amount of data + which is the minimum of the request_length, the maximum send + body size (8186 (8 Kbytes - 6)), and the number of bytes + actually left to send from the request body.
    + If there is no more data in the body (i.e. the servlet container is + trying to read past the end of the body), the server will send back an + empty packet, which is a body packet with a payload length of 0. + (0x12,0x34,0x00,0x00)

    +
    +
    + + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.xml.ja b/trunk/docs/manual/mod/mod_proxy_ajp.xml.ja new file mode 100644 index 0000000000..8dddbcb348 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.xml.ja @@ -0,0 +1,525 @@ + + + + + + + + + +mod_proxy_ajp +mod_proxy $B$G(B AJP +$B$r%5%]!<%H$9$k$?$a$N%b%8%e!<%k(B +Extension +proxy_ajp.c +proxy_ajp_module + + +

    $BK\%b%8%e!<%k$K$O(B mod_proxy $B$,(B$BI,MW$G$9(B$B!#(B + Apache JServ Protocol version 1.3 ($B0J9_(B AJP13) + $B$r%5%]!<%H$7$^$9!#(B

    + +

    AJP13 $B%W%m%H%3%k$r07$($k$h$&$K$9$k$K$O(B + mod_proxy $B$H(B mod_proxy_ajp + $B$r%5!<%P$KAH$_9~$`I,MW$,$"$j$^$9!#(B

    + + $B7Y9p(B +

    $B0BA4$J%5!<%P$K$9$k(B$B$^$G%W%m%/%75!G=$OM-8z$K$7$J$$$G$/$@$5$$!#(B + $B%*!<%W%s%W%m%-%7%5!<%P$O$"$J$?<+?H$N%M%C%H%o!<%/$K$H$C$F$b!"(B + $B%$%s%?!<%M%C%HA4BN$K$H$C$F$b4m81$G$9!#(B

    +
    +
    + +mod_proxy + +
    $B%W%m%H%3%k$N35MW(B +

    AJP13 $B%W%m%H%3%k$O%Q%1%C%H;X8~$G$9!#(B + $B2DFI$J%W%l!<%s%F%-%9%H7A<0$G$O$J$/%P%$%J%j7A<0$K$J$C$?$N$O!"(B + $B$*$=$i$/%Q%U%)!<%^%s%9>e$NM}M3$K$h$j$^$9!#(B + $B%&%'%V%5!<%P$O%5!<%V%l%C%H%3%s%F%J$H(B TCP $B%3%M%/%7%g%s$GDL?.$7$^$9!#(B + $B%=%1%C%H@8@.$O=E$$=hM}$J$N$G!"Ii2Y$r8:$i$9$?$a$K!"%5!<%V%l%C%H%3%s%F%J$H$N(B + TCP $B@\B3$r0];}$7!"J#?t$N%j%/%(%9%H!&%l%9%]%s%9=hM}%5%$%/%k$KBP$7$F0l$D$N(B + $B%3%M%/%7%g%s$r;H$$$^$o$9$h$&$K$J$C$F$$$^$9!#(B

    +

    $B$"$k%j%/%(%9%H$K%3%M%/%7%g%s$,3d$jEv$F$i$l$k$H!"$=$N=hM}%5%$%/%k$,(B + $B40N;$9$k$^$GB>$N$b$N$K;H$o$l$k$3$H$O$"$j$^$;$s!#(B + $B$D$^$j%3%M%/%7%g%s>e$G$O!"%j%/%(%9%H$NF1;~=hM}$O9T$o$l$^$;$s!#(B + $B$3$N$?$a!"%3%M%/%7%g%sN>C<$G$N +

    $B%5!<%V%l%C%H%3%s%F%J$X$N%3%M%/%7%g%s$r3+$$$?8e$O!"%3%M%/%7%g%s$N>uBV$O(B + $B +

      +
    • Idle
      $B%3%M%/%7%g%s>e$G=hM}$5$l$F$$$k%j%/%(%9%H$O$"$j$^$;$s!#(B
    • +
    • Assigned
      $B%3%M%/%7%g%s$O%j%/%(%9%H$r=hM}Cf$G$9!#(B
    • +
    +

    $B%3%M%/%7%g%s$,FCDj$N%j%/%(%9%H$K%"%5%$%s$5$l$k$H!"4pK\E*$J>pJs(B ($BNc$($P(B + HTTP $B%X%C%@Ey(B) $B$,05=L$5$l$?7A(B ($BNc$($PDL>o$NJ8;zNs$O@0?t$K%(%s%3!<%I$5$l$^$9(B) + $B$GE>Aw$5$l$^$9!#>\:Y$O2<5-$N!V%j%/%(%9%H%Q%1%C%H$N9=B$!W$r;2>H$7$F$/$@$5$$!#(B + $B%j%/%(%9%H$K%\%G%#$,B8:_(B (content-length > 0) $B$9$l$P!"(B + $B4pK\E*$J>pJs$ND>8e$KJL%Q%1%C%H$GE>Aw$5$l$^$9!#(B

    +

    $B$3$N;~E@$G$*$=$i$/!"%5!<%V%l%C%H%3%s%F%J$O=hM}$r3+;O$G$-$k$h$&$K$J$j$^$9!#(B + $B$G$9$N$G!" +

      +
    • SEND_HEADERS
      $B%V%i%&%6$K%X%C%@$rAw?.$7$^$9!#(B
    • +
    • SEND_BODY_CHUNK
      $B%V%i%&%6$K%\%G%#%G!<%?$N%A%c%s%/$rAw$j$^$9!#(B +
    • +
    • GET_BODY_CHUNK
      $B%j%/%(%9%H$N%G!<%?$rA4$Fl9g(B + ($BNc$($P%U%!%$%k$N%"%C%W%m!<%I$N>l9g(B) $B$KI,MW$H$J$j$^$9!#(B + ($BCm(B: HTTP $B$N%A%c%s%/E>Aw$H$O4XO"$"$j$^$;$s!#(B)
    • +
    • END_RESPONSE
      $B%j%/%(%9%H=hM}%5%$%/%k$r=*N;$7$^$9!#(B
    • +
    +

    $B8D!9$N%a%C%;!<%8$O$=$l$>$l0[$J$k%G!<%?%Q%1%C%H7A<0$K$J$C$F$$$^$9!#(B + $B8e=R$N!V%l%9%]%s%9%Q%1%C%H$N9=B$!W$r;2>H$7$F$/$@$5$$!#(B

    +
    + +
    $B4pK\%Q%1%C%H9=B$(B +

    $B$3$N%W%m%H%3%k$K$O(B XDR $B$+$i/$7$"$j$^$9$,!"B?$/$NE@$G(B + $B0[$J$j$^$9(B ($BNc$($P(B 4 $B%P%$%H%"%i%$%a%s%H$G$J$$$3$H$J$I(B) $B!#(B

    +

    $B%P%$%H%*!<%@!<(B: $B8D!9$N%P%$%H$N%(%s%G%#%"%s$,$I$&$J$C$F$$$k$+$O!"(B + $B;d$O>\$7$/$J$$$N$G$9$,!"%j%H%k%(%s%G%#%"%s$K$J$C$F$$$k$H;W$$$^$9!#(B + XDR $B;EMM$G$=$&$J$C$F$$$k$N$H!"AG@2$i$7$$$3$H$K(B sys/socket $B%i%$%V%i%j$,(B + (C $B$G(B) $B$=$&$$$&Iw$K$G$-$F$$$k$N$G$=$&$J$N$@$H;W$$$^$7$?!#(B + $B%=%1%C%H8F$S=P$7$NFbIt$K$D$$$F$h$j>\$7$$J}$,$$$i$C$7$c$$$^$7$?$i!"(B + $B$465 +

    $B%W%m%H%3%k$K$O(B 4 $B$D$N%G!<%?%?%$%W$,$"$j$^$9(B: byte, boolean, + integer, string $B$G$9!#(B

    +
    +
    Byte
    $B%P%$%H0l$D$G$9!#(B
    +
    Boolean
    +
    $B%P%$%H0l$D$G!"(B1 = true, 0 = false $B$G$9!#(B + (C $B$N$h$&$K(B) $BHsNm$r??$H$7$F07$C$F$7$^$&$H!"$"$k>l9g$OF0$/$+$b$7$l$^$;$s$7!"(B + $BF0$+$J$$$+$b$7$l$^$;$s!#(B
    +
    Integer
    +
    0 $B$+$i(B 2^16 (32768) $B$NHO0O$N?t;z!#9b +
    String
    +
    $B2DJQD9$NJ8;zNs(B (2^16 $B$,D9$5$N>e8B(B) $B!#D9$5>pJs$N%Q%1%C%H(B 2 $B%P%$%H$N8e$K(B + $BJ8;zNs(B ($B=*CpJs$O:G8e$N(B '\0' $B$r(B$B%+%&%s%H$7$J$$(B + $B$3$H$KCm0U$7$F$/$@$5$$!=!=$3$l$O(B strlen $B$HF1MM$G$9!#(B + $B$3$l$i$N=*C/$7J6$i$o$7$/46$8$i$l$k$+$b$7$l$^$;$s!#(B + $B$3$&$J$C$?M}M3$O$*$=$i$/!"(BServlet $B%3%s%F%J$+$iJV$5$l$kJ8;zNs$rFI$_=P$9;~$K!"(B + $B8zN($h$/(B C $B$N%3!<%I$r=q$1$k$h$&$K$9$k!=!=%5!<%V%l%C%H$+$iJV$5$l$k(B + $BJ8;zNs$O(B \0 $BJ8;z$G=*C<$5$l$F$$$k$N$G!"(BC $B$N%3!<%I$G$O$o$6$o$6%3%T!<$r$;$:$K!"(B + $B0l$D$N%P%C%U%!$X$N%j%U%!%l%s%9$rl9g$O!"(BC $B$G$OJ8;zNs$N5,B'$K9g$&$h$&$K%3%T!<$7$J$1$l$P(B + $B$$$1$J$/$J$C$F$7$^$$$^$9!#(B
    +
    + +
    $B%Q%1%C%H%5%$%:(B +

    $BB?$/$N%3!<%I$G$=$&$J$C$F$$$k$N$G$9$,!"%Q%1%C%H%5%$%:$N:GBg%5%$%:$O(B + 8 * 1024 (8K) $B$G$9!#%Q%1%C%H$N +

    +
    $B%Q%1%C%H%X%C%@(B +

    $B%5!<%P$+$i%3%s%F%J$KAw=P$5$l$k%Q%1%C%H$O(B 0x1234 $B$G;O$^$j$^$9!#(B + $B%3%s%F%J$+$i%5!<%P$KAw$i$l$k%Q%1%C%H$O(B AB (ASCII $B%3!<%I(B A $B$H(B + ASCII $B%3!<%I(B B) $B$G;O$^$j$^$9!#$3$NFs%P%$%H$N8e$K!"%Z%$%m!<%ID9$,(B ($B>e5-$N7A<0$G(B) + $BB3$-$^$9!#$3$N$?$a!"%Z%$%m!<%ID9$N:GBgCM$O(B 2^16 $B$K$G$-$k$h$&$K;W$($^$9$,!"(B + $B + + + + + + + + + + + + + + + + + + + +
    $B%Q%1%C%H7A<0(B (Server->Container)
    Byte01234...(n+3)
    Contents0x120x34$B%G!<%?D9(B (n)Data
    + + + + + + + + + + + + + + + + + + + +
    $B%Q%1%C%H7A<0(B (Container->Server)
    Byte01234...(n+3)
    ContentsAB$B%G!<%?D9(B (n)Data
    +

    $B$[$H$s$I$N%Q%1%C%H$G!"%Z%$%m!<%I$N:G=i$N%P%$%H$,%a%C%;!<%8$N7?$r%(%s%3!<%I(B + $B$7$F$$$^$9!#Nc30$O%5!<%P$+$i%3%s%F%J$KAw$i$l$k%j%/%(%9%H%\%G%#%Q%1%C%H$G$9(B + $B!=!=$3$l$i$OI8=`E*$J%Q%1%C%H7A<0(B (0x1234 $B$H%Q%1%C%HD9(B) + $B$G$9$,!"$=$N8e$KB3$/%W%l%U%#%C%/%9%3!<%I$,$"$j$^$;$s!#(B

    +

    $B%&%'%V%5!<%P$O + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%3!<%I(B$B%Q%1%C%H$N7?(B$B0UL#(B
    2Forward Request$B%j%/%(%9%H=hM}%5%$%/%k$r8eB3$N%G!<%?$H$H$b$K3+;O$9$k!#(B
    7Shutdown$B%&%'%V%5!<%P$,%3%s%F%J$K!"%3%s%F%J$r=*N;$9$k$h$&$KEA$($k!#(B
    8Ping$B%&%'%V%5!<%P$,%3%s%F%J$K@)8f$r +
    10CPing$B%&%'%V%5!<%P$,%3%s%F%J$K(B CPong $B$GB(:B$K1~Ez$9$k$h$&$KEA$($k!#(B
    noneData$B%5%$%:(B (2 $B%P%$%H(B) $B$H$=$l$KB3$/%\%G%#%G!<%?!#(B
    +

    $B4pK\E*$J%;%-%e%j%F%#$r3NJ]$9$k$?$a!"%[%9%H$5$l$F$$$k%^%7%s$HF10l$N(B + $B%^%7%s$+$i$N%j%/%(%9%H$KBP$7$F$N$_!"%3%s%F%J$OShutdown + $B$r +

    $B:G=i$N(B Data $B%Q%1%C%H$O!"(BForward Request + $B$ND>8e$K%&%'%V%5!<%P$+$iAw$i$l$^$9!#(B

    +

    $B%5!<%V%l%C%H%3%s%F%J$O%&%'%V%5!<%P$K!" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B%3!<%I(B$B%Q%1%C%H$N7?(B$B0UL#(B
    3Send Body Chunk$B%5!<%V%l%C%H%3%s%F%J$+$i%&%'%V%5!<%P$K(B + ($B$=$7$F$*$=$i$/$=$N$^$^%V%i%&%6$K(B)$B!"%\%G%#$N%A%c%s%/$rAw$k!#(B
    4Send Headers$B%5!<%V%l%C%H%3%s%F%J$+$i%&%'%V%5!<%P$K(B ($B$=$7$F$*$=$i$/$=$N$^$^%V%i%&%6$K(B) + $B%l%9%]%s%9%X%C%@$rAw$k!#(B
    5End Response$B%l%9%]%s%9(B ($B$D$^$j%j%/%(%9%H=hM}%5%$%/%k(B) $B=*N;$NL\0u$rAw$k!#(B +
    6Get Body Chunk$B$^$@A4$FE>Aw$5$l$F$$$J$$>l9g!";D$C$F$$$k%j%/%(%9%H$N%G!<%?$r +
    9CPong $B1~Ez(BCPing $B%j%/%(%9%H$K1~Ez$9$k!#(B
    +

    $B>e5-%a%C%;!<%8$O!"$=$l$>$lFbIt9=B$$,0[$J$C$F$$$^$9!#>\:Y$O2<5-$r$4Mw$/$@$5$$!#(B +

    +
    +
    +
    $B%j%/%(%9%H%Q%1%C%H9=B$(B +

    $B%5!<%P$+$i%3%s%F%J$XAw$i$l$k%a%C%;!<%8$,(B + Forward Request $B7?$N>l9g(B :

    +
    +AJP13_FORWARD_REQUEST :=
    +    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    +    method           (byte)
    +    protocol         (string)
    +    req_uri          (string)
    +    remote_addr      (string)
    +    remote_host      (string)
    +    server_name      (string)
    +    server_port      (integer)
    +    is_ssl           (boolean)
    +    num_headers      (integer)
    +    request_headers *(req_header_name req_header_value)
    +    attributes      *(attribut_name attribute_value)
    +    request_terminator (byte) OxFF
    +    
    +

    request_headers $B$O

    +req_header_name := 
    +    sc_req_header_name | (string)  [see below for how this is parsed]
    +
    +sc_req_header_name := 0xA0xx (integer)
    +
    +req_header_value := (string)
    +
    +

    $BB0@-(B $B$O%*%W%7%g%s$G!" +

    +attribute_name := sc_a_name | (sc_a_req_attribute string)
    +
    +attribute_value := (string)
    +
    +    
    +

    $B$b$C$H$b=EMW$J%X%C%@$O(B content-length $B$@$H$$$&$3$H$K(B + $BCm0U$7$F$/$@$5$$!#%3%s%F%J$O +

    Forward Request $BMWAG$N>\:Y$J@bL@(B +
    +
    Request prefix +

    $B%j%/%(%9%H$K$D$$$F$OA4$F!"$3$NCM$O(B 2 $B$K$J$j$^$9!#B>$N(B Prefix $B%3!<%I$N>\:Y$O(B + $B>e5-$r$4Mw$/$@$5$$!#(B

    +
    +
    Method +

    HTTP $B%a%=%C%I$O(B 1 $B%P%$%H$K%(%s%3!<%I$5$l$^$9(B :

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Command NameCode
    OPTIONS1
    GET2
    HEAD3
    POST4
    PUT5
    DELETE6
    TRACE7
    PROPFIND8
    PROPPATCH9
    MKCOL10
    COPY11
    MOVE12
    LOCK13
    UNLOCK14
    ACL15
    REPORT16
    VERSION-CONTROL17
    CHECKIN18
    CHECKOUT19
    UNCHECKOUT20
    SEARCH21
    MKWORKSPACE22
    UPDATE23
    LABEL24
    MERGE25
    BASELINE_CONTROL26
    MKACTIVITY27
    +

    $B:#8e$N(B ajp13 $B%P!<%8%g%s$G$O!"$3$N0lMw$K$J$$!":#8eDI2C$5$l$k%a%=%C%I$r(B + $BAw$k$+$b$7$l$^$;$s!#(B

    +
    +
    protocol, req_uri, remote_addr, remote_host, server_name, + server_port, is_ssl +

    $B$3$l$i$O$^$5$KJ8;zDL$j$N$b$N$G$9!#$I$l$bI,MW$G!"%j%/%(%9%H$NKh2s$K$D$-(B + $BAw$i$l$^$9!#(B

    +
    +
    Headers +

    request_headers $B$N9=B$$Onum_headers $B$,%(%s%3!<%I$5$l$^$9!#(B + $B(B req_header_name / $BCM(B req_header_value + $B$NAH$,B3$-$^$9!#8zN($N$?$a!"0lHLE*$J%X%C%@$O@0?t$G%(%s%3!<%I$7$FE>Aw$7$^$9!#(B + $B%X%C%@L>$,4pK\%X%C%@$N0lMw$KL5$$>l9g$O!"DL>oDL$j(B ($BJ8;zNs$H$7$F!"D9$5(B + $B%W%l%U%#%C%/%9IU$-$G(B) $BE>Aw$5$l$^$9!#0lHLE*$J%X%C%@(B + sc_req_header_name $B$N0lMw$H$=$N%3!<%I$O.J8;z$r6hJL$7$^$9(B) :

    + + + + + + + + + + + + + + + + + + + +
    $BL>A0(B$B%3!<%I$NCM(B$B%3!<%IL>(B
    accept0xA001SC_REQ_ACCEPT
    accept-charset0xA002SC_REQ_ACCEPT_CHARSET +
    accept-encoding0xA003SC_REQ_ACCEPT_ENCODING +
    accept-language0xA004SC_REQ_ACCEPT_LANGUAGE +
    authorization0xA005SC_REQ_AUTHORIZATION
    connection0xA006SC_REQ_CONNECTION
    content-type0xA007SC_REQ_CONTENT_TYPE
    content-length0xA008SC_REQ_CONTENT_LENGTH
    cookie0xA009SC_REQ_COOKIE
    cookie20xA00ASC_REQ_COOKIE2
    host0xA00BSC_REQ_HOST
    pragma0xA00CSC_REQ_PRAGMA
    referer0xA00DSC_REQ_REFERER
    user-agent0xA00ESC_REQ_USER_AGENT
    +

    $B$3$l$rFI$_9~$`(B Java $B$N%3!<%I$G$O!":G=i$N(B 2 $B%P%$%H@0?t$r'0xA0' $B$G$"$l$P!"%X%C%@L>$NG[Ns$N(B + $B%$%s%G%C%/%9$r;H$$$^$9!#@hF,%P%$%H$,(B 0xA0 $B$G$J$$>l9g$O!"(B + $B@hF,(B 2 $B%P%$%H$OJ8;zNsD9$rI=$9@0?t$G$"$k$H2r +

    $B%X%C%@L>$ND9$5$O(B 0x9999 (==0xA000 -1) $B0J>e$K$J$i$J$$$H$$$&(B + $B2>Dj$N2<$KF0$$$F$$$F!">/$7$"$$$^$$$G$9$,9gM}E*$J5sF0$K$J$C$F$$$^$9!#(B

    + $BCm(B: + content-length $B%X%C%@$O$H$F$b=EMW$G$9!#(B + $BB8:_$7$F$$$FHs%<%m$G$"$l$P!"%j%/%(%9%H$K$O%\%G%#$,$"$k(B ($BNc$($P(B POST + $B%j%/%(%9%H(B) $B$H?dB,$7!"$=$N%\%G%#$r8e$N%Q%1%C%H$rF~NO%9%H%j!<%`$+$iFI$_9~$_$O$8$a$^$9!#(B + +
    +
    $BB0@-(B +

    ? $B%W%l%U%#%C%/%9$G;O$^$kB0@-(B ($BNc(B ?context) + $B$O!#>JN,2DG=$G$9!#$=$l$>$lB0@-$N7?$r<($9(B 1 $B%P%$%H$N%3!<%I$H!"(B + $BCM$NJ8;zNs$,B3$-$^$9!#(B + $B$3$l$i$O=gITF1$GAw$k$3$H$,$G$-$^$9(B (C $B$N%3!<%I$O>o$K2<$N0lMw=g$K(B + $BAw$k$h$&$G$9$,(B) $B!#(B + $B%*%W%7%g%s$NB0@-$N%j%9%H$N:G8e$K$O!"FCJL$J=*N;%3!<%I$,Aw$i$l$^$9!#(B + $B%3!<%I$N0lMw$O(B :

    + + + + + + + + + + + + + + +
    InformationCode ValueNote
    ?context0x01$BL$
    ?servlet_path0x02$BL$
    ?remote_user0x03
    ?auth_type0x04
    ?query_string0x05
    ?jvm_route0x06
    ?ssl_cert0x07
    ?ssl_cipher0x08
    ?ssl_session0x09
    ?req_attribute0x0AName (the name of the + attribute follows)
    ?ssl_key_size0x0B
    are_done0xFFrequest_terminator
    +

    context $B$H(B servlet_path $B$O8=:_$N(B C $B$N(B + $B%3!<%I$G$O%;%C%H$5$l$F$$$^$;$s!#$^$?!"$[$H$s$I$N(B Java $B$N%3!<%I$G$b!"(B + $B$3$N%U%#!<%k%I$G2?$,Aw$i$l$F$bL5;k$5$l$^$9(B ($B$3$l$i$N%3!<%I$N8e$KJ8;zNs$,(B + $BAw$i$l$k$H2u$l$k$b$N$b$"$j$^$9(B)$B!#(B + $B$3$l$,%P%0$J$N$+!"C1$KL$B&$H$b$G8+Ev$?$j$^$;$s!#(B

    +

    remote_user $B$H(B auth_type $B$O$*$=$i$/(B + HTTP $B%l%Y%k$NG'>Z$r;2>H$7$F$$$F!"%j%b!<%H%f!<%6$N%f!<%6L>$HG'>Z$K;HMQ$7$?(B + $B%?%$%W(B ($BNc(B Basic, Digest) $B$K$D$$$F$d$j +

    query_string, ssl_cert, + ssl_cipher, ssl_session + $B$O(B HTTP $B$H(B HTTPS $B$NBP1~$9$kItJ,$r;2>H$7$^$9!#(B

    +

    jvm_route $B$O%9%F%#%C%-!<%;%C%7%g%s$N%5%]!<%H!=!=(B + $B%m!<%I%P%i%s%9$7$F$$$kJ#?t$N%5!<%PCf$NFCDj$N(B Tomcat $B%$%s%9%?%s%9$H!"(B + $B%f!<%6$N%;%C%7%g%s$H$rI3IU$1$k5!G=!=!=$K;H$o$l$^$9!#(B

    +

    $B$3$N4pK\B0@-0lMw$KL5$$$b$N$K$D$$$F$O!"(Breq_attribute + $B%3!<%I(B 0x0A $B7PM3$GB0@-$r2?8D$G$bAw$k$3$H$,$G$-$^$9!#(B + $BB0@-$NL>A0$HCM$NJ8;zNs$NAH$r!"$=$l$>$l$3$N%3!<%I$ND>8e$KAw$j$^$9!#(B + $B4D6-JQ?t$O$3$NJ}K!$GEA$($i$l$^$9!#(B

    +

    $B:G8e$KB0@-$,A4$FAw?.$5$l$?8e$K!"B0@-$N=*C<$r<($9(B 0xFF + $B$,Aw=P$5$l$^$9!#$3$N?.9f$OB0@-$N0lMw$N=*$o$j$r<($9$HF1;~$K!"%j%/%(%9%H(B + $B%Q%1%C%H$N=*C<$r$b<($7$F$$$^$9!#(B

    +
    +
    + +
    $B%l%9%]%s%9%Q%1%C%H9=B$(B +

    $B%3%s%F%J$,%5!<%P$KAw$jJV$9$3$H$N$G$-$k%a%C%;!<%8(B:

    +
    +AJP13_SEND_BODY_CHUNK :=
    +  prefix_code   3
    +  chunk_length  (integer)
    +  chunk        *(byte)
    +
    +
    +AJP13_SEND_HEADERS :=
    +  prefix_code       4
    +  http_status_code  (integer)
    +  http_status_msg   (string)
    +  num_headers       (integer)
    +  response_headers *(res_header_name header_value)
    +
    +res_header_name :=
    +    sc_res_header_name | (string)   [see below for how this is parsed]
    +
    +sc_res_header_name := 0xA0 (byte)
    +
    +header_value := (string)
    +
    +AJP13_END_RESPONSE :=
    +  prefix_code       5
    +  reuse             (boolean)
    +
    +
    +AJP13_GET_BODY_CHUNK :=
    +  prefix_code       6
    +  requested_length  (integer)
    +    
    +
    $B>\:Y(B :
    +
    Send Body Chunk +

    $B%A%c%s%/$O4pK\E*$K$O%P%$%J%j%G!<%?$G!"%V%i%&%6$KD>@\Aw$i$l$^$9!#(B

    +
    +
    Send Headers +

    $B%9%F!<%?%9%3!<%I$H%a%C%;!<%8$,DL>o$N(B HTTP $B$NDL?.$K$O$"$j$^$9(B ($BNc(B + 200 $B$H(B OK)$B!#%l%9%]%s%9%X%C%@L>$O!"(B + $B%j%/%(%9%H%X%C%@L>$HF1MM$NJ}K!$G%(%s%3!<%I$5$l$^$9!#(B + $B%3!<%I$HJ8;zNs$NH=JLJ}K!$N>\:Y$K4X$7$F$O!">e5-$N(B header_encoding + $B$r;2>H$7$F$/$@$5$$!#(B + $B0lHLE*$J%X%C%@$N%3!<%I$O(B :

    + + + + + + + + + + + + + +
    $BL>A0(B$B%3!<%I$NCM(B
    Content-Type0xA001
    Content-Language0xA002
    Content-Length0xA003
    Date0xA004
    Last-Modified0xA005
    Location0xA006
    Set-Cookie0xA007
    Set-Cookie20xA008
    Servlet-Engine0xA009
    Status0xA00A
    WWW-Authenticate0xA00B
    +

    $B%3!<%I$+%X%C%@J8;zNs$ND>8e$K$O!"%X%C%@$NCM$,%(%s%3!<%I$5$l$^$9!#(B

    +
    +
    End Response +

    $B%j%/%(%9%H=hM}%5%$%/%k$N=*N;$rCN$i$;$^$9!#(Breuse $B%U%i%0$,??(B + (==1) $B$N>l9g!"8=:_;HMQ$7$F$$$k(B TCP $B%3%M%/%7%g%s$Oreuse $B$,56(B (C $B$N%3!<%I$G$O(B + 1 $B0J30$NA4$F(B) $B$N>l9g$O!"%3%M%/%7%g%s$rJD$8$k$3$H$K$J$j$^$9!#(B

    +
    +
    Get Body Chunk +

    ($B%\%G%#$N%5%$%:$,Bg$-$9$.$F:G=i$N%Q%1%C%H$K<}$^$i$J$$>l9g$d!"(B + $B%j%/%(%9%H$,%A%c%s%/E>Aw$5$l$?>l9g$J$I$K$O!"(B) $B%3%s%F%J$O%j%/%(%9%H$+$i$N(B + $B%G!<%?FI$_9~$_MW5a$r$7$^$9!#%5!<%PB&$O$=$l$KBP$7$F!":G>.(B + request_length $B:GBg(B (8186 (8 Kbytes - 6)) + $B$NHO0O$G!"L$E>Aw$G;D$C$F$$$k%j%/%(%9%H%\%G%#$NBg$-$5$N%G!<%?$r(B + $BAw$jJV$7$^$9!#(B
    + $B%\%G%#$K$=$l0J>e%G!<%?$,;D$C$F$$$J$$>l9g(B ($B$D$^$j%5!<%V%l%C%H$,(B + $B%\%G%#$N:G8e$rD6$($FFI$_9~$b$&$H$7$?>l9g(B) $B!"%5!<%P$O(B + $B%Z%$%m!<%ID9(B 0 $B$N(B$B6u%Q%1%C%H(B(0x12,0x34,0x00,0x00) + $B$rAw$jJV$7$^$9!#(B

    +
    +
    + + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_ajp.xml.meta b/trunk/docs/manual/mod/mod_proxy_ajp.xml.meta new file mode 100644 index 0000000000..98ed6fc9fc --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ajp.xml.meta @@ -0,0 +1,12 @@ + + + + mod_proxy_ajp + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.html b/trunk/docs/manual/mod/mod_proxy_balancer.html new file mode 100644 index 0000000000..bca5d27445 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.html @@ -0,0 +1,7 @@ +URI: mod_proxy_balancer.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_proxy_balancer.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.html.en b/trunk/docs/manual/mod/mod_proxy_balancer.html.en new file mode 100644 index 0000000000..26821299ff --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.html.en @@ -0,0 +1,316 @@ + + + +mod_proxy_balancer - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy_balancer

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    Description:mod_proxy extension for load balancing
    Status:Extension
    Module Identifier:proxy_balancer_module
    Source File:proxy_balancer.c
    Compatibility:Available in version 2.1 and later
    +

    Summary

    + +

    This module requires the service of mod_proxy. It provides load balancing support for + HTTP, FTP and AJP13 protocols +

    + +

    Thus, in order to get the ability of load balancing, + mod_proxy and mod_proxy_balancer + have to be present in the server.

    + +

    Warning

    +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    + +
    top
    +
    +

    Load balancer scheduler algorithm

    + +

    At present, there are 2 load balancer scheduler algorithms available + for use: Request Counting and Weighted Traffic Counting. These are controlled + via the lbmethod value of the Balancer definition. See + the Proxy directive for + more information.

    + +
    top
    +
    +

    Request Counting Algorithm

    + +

    Enabled via lbmethod=requests, the idea behind this + scheduler is that we distribute the requests among the + various workers to ensure that each gets their configured share + of the number of requests. It works as follows:

    + +

    lbfactor is how much we expect this worker + to work, or the workers's work quota. This is + a normalized value representing their "share" of the amount of + work to be done.

    + +

    lbstatus is how urgent this worker has to work + to fulfill its quota of work.

    + +

    The worker is a member of the load balancer, + usually a remote host serving one of the supported protocols.

    + +

    We distribute each worker's work quota to the worker, and then look + which of them needs to work most urgently (biggest lbstatus). This + worker is then selected for work, and its lbstatus reduced by the + total work quota we distributed to all workers. Thus the sum of all + lbstatus does not change(*) and we distribute the requests + as desired.

    + +

    If some workers are disabled, the others will + still be scheduled correctly.

    + +
    for each worker in workers
    +    worker lbstatus += worker lbfactor
    +    total factor    += worker lbfactor
    +    if worker lbstatus > candidate lbstatus
    +        candidate = worker
    +
    +candidate lbstatus -= total factor
    + +

    If a balancer is configured as follows:

    + + + + + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    lbstatus0000
    + +

    And b gets disabled, the following schedule is produced:

    + + + + + + + + + + + + + + + + + + + + + + +
    workerabcd
    lbstatus-5002525
    lbstatus-250-2550
    lbstatus0000
    (repeat)
    + +

    That is it schedules: a c d + a c d a c + d ... Please note that:

    + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    + +

    Has the exact same behavior as:

    + + + + + + + + + + + +
    workerabcd
    lbfactor1111
    + +

    This is because all values of lbfactor are normalized + with respect to the others. For:

    + + + + + + + + + +
    workerabc
    lbfactor141
    + +

    worker b will, on average, get 4 times the requests + that a and c will.

    + +

    The following asymmetric configuration works as one would expect:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    workerab
    lbfactor7030
     
    lbstatus-3030
    lbstatus40-40
    lbstatus10-10
    lbstatus-2020
    lbstatus-5050
    lbstatus20-20
    lbstatus-1010
    lbstatus-4040
    lbstatus30-30
    lbstatus00
    (repeat)
    + +

    That is after 10 schedules, the schedule repeats and 7 a + are selected with 3 b interspersed.

    +
    top
    +
    +

    Weighted Traffic Counting Algorithm

    + +

    Enabled via lbmethod=traffic, the idea behind this + scheduler is very similar to the Request Counting method, with + the following changes:

    + +

    lbfactor is how much traffic, in bytes, we want + this worker to handle. This is also a normalized value + representing their "share" of the amount of work to be done, + but instead of simply counting the number of requests, we take + into account the amount of traffic this worker has seen.

    + +

    If a balancer is configured as follows:

    + + + + + + + + + +
    workerabc
    lbfactor121
    + +

    Then we mean that we want b to process twice the + amount of bytes than a or c should. It does + not necessarily mean that b would handle twice as + many requests, but it would process twice the I/O. Thus, the + size of the request and response are applied to the weighting + and selection algorithm.

    + +
    top
    +
    +

    Enabling Balancer Manager Support

    + +

    This module requires the service of + mod_status. + Balancer manager enables dynamic update of balancer + members. You can use balancer manager to change the balance + factor or a particular member, or put it in the off line + mode. +

    + +

    Thus, in order to get the ability of load balancer management, + mod_status and mod_proxy_balancer + have to be present in the server.

    + +

    To enable load balancer management for browsers from the foo.com + domain add this code to your httpd.conf + configuration file

    +

    + <Location /balancer-manager>
    + SetHandler balancer-manager
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +

    + +

    You can now access load balancer manager by using a Web browser + to access the page + http://your.server.name/balancer-manager

    +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.html.ja.euc-jp b/trunk/docs/manual/mod/mod_proxy_balancer.html.ja.euc-jp new file mode 100644 index 0000000000..a521cac37e --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.html.ja.euc-jp @@ -0,0 +1,317 @@ + + + +mod_proxy_balancer - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_proxy_balancer

    +
    +

    Available Languages:  en  | + ja 

    +
    + + + + +
    ÀâÌÀ:Éé²Ùʬ»¶¤Î¤¿¤á¤Î mod_proxy ³ÈÄ¥
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:proxy_balancer_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:proxy_balancer.c
    ¸ß´¹À­:2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    Ëܥ⥸¥å¡¼¥ë¤Ë¤Ï mod_proxy ¤¬É¬ÍפǤ¹¡£ + HTTP, FTP ¤È AJP13 + ¥×¥í¥È¥³¥ë¤Î¥í¡¼¥É¥Ð¥é¥ó¥¹µ¡Ç½¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤Ç¤¹¤«¤é¡¢ ¥í¡¼¥É¥Ð¥é¥ó¥¹¤òÍ­¸ú¤Ë¤¹¤ë¾ì¹ç mod_proxy + ¤È mod_proxy_balancer ¤¬¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ + ¤¤¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£

    + +

    ·Ù¹ð

    +

    °ÂÁ´¤Ê¥µ¡¼¥Ð¤Ë¤¹¤ë¤Þ¤Ç¥×¥í¥¯¥·µ¡Ç½¤ÏÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¥ª¡¼¥×¥ó¥×¥í¥­¥·¥µ¡¼¥Ð¤Ï¤¢¤Ê¤¿¼«¿È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Ë¤È¤Ã¤Æ¤â¡¢ + ¥¤¥ó¥¿¡¼¥Í¥Ã¥ÈÁ´ÂΤˤȤäƤâ´í¸±¤Ç¤¹¡£

    +
    +
    + +
    top
    +
    +

    ¥í¡¼¥É¥Ð¥é¥ó¥µ¤Î¥¹¥±¥¸¥å¡¼¥é¤Î¥¢¥ë¥´¥ê¥º¥à

    + +

    ¸½»þÅÀ¤Ç¤Ï 2 ¼ïÎà¤Î¥í¡¼¥É¥Ð¥é¥ó¥µ¥¹¥±¥¸¥å¡¼¥é¥¢¥ë¥´¥ê¥º¥à¤«¤éÁª¤Ù¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È²ó¿ô¤Ë¤è¤ë¤â¤Î (ÌõÃí: Request Counting) + ¤È¡¢¥È¥é¥Õ¥£¥Ã¥¯Î̤ˤè¤ë¤â¤Î (ÌõÃí: Weighted Traffic Counting) + ¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥é¥ó¥µ¤ÎÀßÄê lbmethod Ãͤǡ¢¤É¤Á¤é¤ò»È¤¦¤«»ØÄꤷ¤Þ¤¹¡£ + ¾ÜºÙ¤Ï Proxy ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    Request Counting ¥¢¥ë¥´¥ê¥º¥à

    + +

    lbmethod=requests ¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¥¹¥±¥¸¥å¡¼¥é¤ÎÇطʤˤ¢¤ë¹Í¤¨Êý¤Ï¡¢ÍÍ¡¹¤Ê¥ï¡¼¥«¡¼¤¬¤½¤ì¤¾¤ì¡¢ + ÀßÄꤵ¤ì¤Æ¤¤¤ëʬô¥ê¥¯¥¨¥¹¥È¿ô¤ò¤­¤Á¤ó¤È¼õ¤±¼è¤ì¤ë¤è¤¦¤Ë¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤È¤¤¤¦¹Í¤¨Êý¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÆ°ºî¤·¤Þ¤¹:

    + +

    lbfactor ¤Ï¡¢¤É¤ÎÄøÅ٥¥«¡¼¤Ë»Å»ö¤ò¿¶¤ë¤« + ¤Ä¤Þ¤ê¥ï¡¼¥«¡¼¤Î¥¯¥ª¡¼¥¿¤ò»Ø¤·¤Þ¤¹¡£¤³¤ÎÃÍ¤Ï "ʬô" + Î̤òɽ¤¹Àµµ¬²½¤µ¤ì¤¿ÃͤǤ¹¡£

    + +

    lbstatus ¤Ï¡¢¥ï¡¼¥«¡¼¤Î¥¯¥ª¡¼¥¿¤òËþ¤¿¤¹¤¿¤á¤Ë + ¤É¤Î¤°¤é¤¤µÞ¤®¤ÇƯ¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤ò»Ø¤·¤Þ¤¹¡£

    + +

    ¥ï¡¼¥«¡¼¤Ï¥í¡¼¥É¥Ð¥é¥ó¥µ¤Î¥á¥ó¥Ð¤Ç¡¢Ä̾ï¤Ï¡¢ + ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¥×¥í¥È¥³¥ë¤Î¤¦¤Á¤Î°ì¤Ä¤òÄ󶡤·¤Æ¤¤¤ë¥ê¥â¡¼¥È¥Û¥¹¥È¤Ç¤¹¡£ +

    + +

    ¤Þ¤º¸Ä¡¹¤Î¥ï¡¼¥«¡¼¤Ë¥ï¡¼¥«¡¼¥¯¥ª¡¼¥¿¤ò³ä¤ê¿¶¤ê¡¢¤É¤Î¥ï¡¼¥«¡¼¤¬ºÇ¤âµÞ¤®¤Ç + Ư¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤« (lbstatus ¤¬ºÇÂç¤Î¤â¤Î) ¤òÄ´¤Ù¤Þ¤¹¡£ + ¼¡¤Ë»Å»ö¤ò¤¹¤ë¤è¤¦¤Ë¤³¤Î¥ï¡¼¥«¡¼¤òÁªÂò¤·¡¢ÁªÂò¤·¤¿¥ï¡¼¥«¡¼¤Î lbstatus + ¤òÁ´ÂΤ˳ä¤ê¿¶¤Ã¤¿¤Ö¤ó¤À¤±º¹¤·°ú¤­¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢lbstatus ¤ÎÁíÎÌ¤Ï + ·ë²ÌŪ¤ËÊѲ½¤·¤Þ¤»¤ó(*)¤·¡¢¥ê¥¯¥¨¥¹¥È¤Ï´üÂÔÄ̤ê¤Ëʬ»¶¤µ¤ì¤Þ¤¹¡£

    + +

    ¤¢¤ë¥ï¡¼¥«¡¼¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤â¡¢Â¾¤Î¤â¤Î¤ÏÀµ¾ï¤Ë¥¹¥±¥¸¥å¡¼¥ë¤µ¤ì³¤±¤Þ¤¹¡£ +

    + +
    for each worker in workers
    +    worker lbstatus += worker lbfactor
    +    total factor    += worker lbfactor
    +    if worker lbstatus > candidate lbstatus
    +        candidate = worker
    +
    +candidate lbstatus -= total factor
    + +

    ¥Ð¥é¥ó¥µ¤ò¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤¿¾ì¹ç:

    + + + + + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    lbstatus0000
    + +

    ¤½¤·¤Æ b ¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤¿¾ì¹ç¡¢¼¡¤Î¤è¤¦¤Ê¥¹¥±¥¸¥å¡¼¥ë¤¬ + ¹Ô¤ï¤ì¤Þ¤¹¡£

    + + + + + + + + + + + + + + + + + + + + + + +
    workerabcd
    lbstatus-5002525
    lbstatus-250-2550
    lbstatus0000
    (repeat)
    + +

    ¤Ä¤Þ¤ê¤³¤Î¤è¤¦¤Ë¥¹¥±¥¸¥å¡¼¥ë¤µ¤ì¤Þ¤¹: a c + d a c d a + c d ... ¼¡¤ÎÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤:

    + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    + +

    ¤³¤ÎµóÆ°¤Ï¡¢¼¡¤ÎÀßÄê¤ÈÁ´¤¯Æ±¤¸¤Ë¤Ê¤ê¤Þ¤¹:

    + + + + + + + + + + + +
    workerabcd
    lbfactor1111
    + +

    This is because all values of lbfactor are normalized + with respect to the others. For:

    +

    lbfactor ¤ÏÁ´¤ÆÀµµ¬²½¤µ¤ì¤¿¤â¤Î¤Ç¡¢ + ¾¤È¤ÎÁêÂÐÃͤÀ¤«¤é¤Ç¤¹¡£¼¡¤ÎÀßÄê¤Ç¤Ï:

    + + + + + + + + + +
    workerabc
    lbfactor141
    + +

    ¥ï¡¼¥«¡¼ b ¤Ï¡¢Ê¿¶Ñ¤·¤Æ¡¢a ¤È c + ¤Î 4 Çܤοô¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±»ý¤Ä¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¼¡¤Î¤è¤¦¤ÊÈóÂоΤÊÀßÄê¤Ç¤Ï¡¢¤³¤¦¤Ê¤ë¤ÈͽÁÛ¤µ¤ì¤ë¤Ç¤·¤ç¤¦:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    workerab
    lbfactor7030
     
    lbstatus-3030
    lbstatus40-40
    lbstatus10-10
    lbstatus-2020
    lbstatus-5050
    lbstatus20-20
    lbstatus-1010
    lbstatus-4040
    lbstatus30-30
    lbstatus00
    (repeat)
    + +

    ¥¹¥±¥¸¥å¡¼¥ë¤Ï 10 ¥¹¥±¥¸¥å¡¼¥ë¸å¤Ë·«¤êÊÖ¤µ¤ì¡¢a 7 ²ó¤È + b 3 ²ó¤Ç¤Þ¤Ð¤é¤ËÁª¤Ð¤ì¤Þ¤¹¡£

    +
    top
    +
    +

    Weighted Traffic Counting ¥¢¥ë¥´¥ê¥º¥à

    + +

    lbmethod=traffic ¤ÇÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¥¹¥±¥¸¥å¡¼¥é¤ÎÇطʤˤ¢¤ë¹Í¤¨Êý¤Ï¡¢Request Counting + ¤ÈÈó¾ï¤Ë»÷¤Æ¤¤¤Þ¤¹¤¬¡¢¼¡¤Î°ã¤¤¤¬¤¢¤ê¤Þ¤¹:

    + +

    lbfactor ¤Ï ¤É¤ì¤À¤±¤Î¥Ð¥¤¥È¿ô¤Î¥È¥é¥Õ¥£¥Ã¥¯Î̤ò¡¢ + ¤³¤Î¥ï¡¼¥«¡¼¤Ë½èÍý¤·¤Æ¤â¤é¤¤¤¿¤¤¤« ¤òɽ¤·¤Þ¤¹¡£ + ¤³¤ÎÃͤâƱÍͤËÀµµ¬²½¤µ¤ì¤¿Ãͤǡ¢¥ï¡¼¥«¡¼Á´ÂΤΤ¦¤Á¤Ç¤Î "ʬô" + Î̤òɽ¸½¤·¤Æ¤¤¤Þ¤¹¡£¥ê¥¯¥¨¥¹¥È¿ô¤òñ½ã¤Ë¿ô¤¨¤ëÂå¤ï¤ê¤Ë¡¢ + ¤É¤ì¤À¤±¤ÎžÁ÷Î̤ò½èÍý¤·¤¿¤«¤ò¿ô¤¨¤Þ¤¹¡£

    + +

    ¼¡¤Î¤è¤¦¤Ë¥Ð¥é¥ó¥µ¤òÀßÄꤷ¤¿¾ì¹ç:

    + + + + + + + + + +
    workerabc
    lbfactor121
    + +

    b ¤Ë¤Ï a ¤ä c ¤Î 2 ÇÜ + ½èÍý¤·¤Æ¤Û¤·¤¤¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + b ¤Ï 2 ÇܤΠI/O ¤ò½èÍý¤¹¤ë¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¡¢ + 2 ÇܤΥꥯ¥¨¥¹¥È¿ô¤ò½èÍý¤¹¤ë¤È¤¤¤¦¤³¤È¤Ë¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ + ¤Ç¤¹¤«¤é¥ê¥¯¥¨¥¹¥È¤È¥ì¥¹¥Ý¥ó¥¹¤Î¥µ¥¤¥º¤¬¡¢ + ½Å¤ßÉÕ¤±¤È¿¶¤êʬ¤±¤Î¥¢¥ë¥´¥ê¥º¥à¤Ë¸ú¤¤¤Æ¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥Ð¥é¥ó¥µ¥Þ¥Í¡¼¥¸¥ã¤Î¥µ¥Ý¡¼¥È¤òÍ­¸ú¤Ë¤¹¤ë

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï mod_status ¤Î¥µ¡¼¥Ó¥¹¤ò + ɬÍפȤ·¤Þ¤¹¡£ + ¥Ð¥é¥ó¥µ¥Þ¥Í¡¼¥¸¥ã¤ò»È¤¦¤È¡¢¥Ð¥é¥ó¥µ¤Î¥á¥ó¥Ð¡¼¤ÎưŪ¤Ê¹¹¿·¤¬ + ¤Ç¤­¤Þ¤¹¡£¥Ð¥é¥ó¥µ¥Þ¥Í¡¼¥¸¥ã¤ò»È¤Ã¤Æ¡¢¥Ð¥é¥ó¥¹·¸¿ô (lbfactor) + ¤òÊѹ¹¤·¤¿¤ê¡¢¥á¥ó¥Ð¡¼¤òÊѹ¹¤·¤¿¤ê¡¢ÆÃÄê¤Î¥á¥ó¥Ð¡¼¤ò + ¥ª¥Õ¥é¥¤¥ó¥â¡¼¥É¤Ë¤·¤¿¤ê¤Ç¤­¤Þ¤¹¡£

    + +

    ¤Ç¤¹¤«¤é¡¢¥í¡¼¥É¥Ð¥é¥ó¥µ´ÉÍýµ¡Ç½¤ò»È¤¤¤¿¤±¤ì¤Ð¡¢ + mod_status ¤È mod_proxy_balancer + ¤ò¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    foo.com ¥É¥á¥¤¥ó¤Î¥Ö¥é¥¦¥¶¤«¤é¥í¡¼¥É¥Ð¥é¥ó¥µ´ÉÍýµ¡Ç½¤ò + »È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢¼¡¤Î¤è¤¦¤Ê¥³¡¼¥É¤ò httpd.conf + ¤ËÄɲä·¤Þ¤¹¡£

    +

    + <Location /balancer-manager>
    + SetHandler balancer-manager
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +

    + +

    ¤³¤¦¤¹¤ë¤È¡¢http://your.server.name/balancer-manager + ¤Î¥Ú¡¼¥¸·Ðͳ¤Ç¡¢¥¦¥§¥Ö¥Ö¥é¥¦¥¶¤«¤é¥í¡¼¥É¥Ð¥é¥ó¥µ¥Þ¥Í¡¼¥¸¥ã¤Ë + ¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.xml b/trunk/docs/manual/mod/mod_proxy_balancer.xml new file mode 100644 index 0000000000..ee1e8c757f --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.xml @@ -0,0 +1,306 @@ + + + + + + + + + +mod_proxy_balancer +mod_proxy extension for load balancing +Extension +proxy_balancer.c +proxy_balancer_module +Available in version 2.1 and later + + +

    This module requires the service of mod_proxy. It provides load balancing support for + HTTP, FTP and AJP13 protocols +

    + +

    Thus, in order to get the ability of load balancing, + mod_proxy and mod_proxy_balancer + have to be present in the server.

    + + Warning +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +mod_proxy + +
    + Load balancer scheduler algorithm +

    At present, there are 2 load balancer scheduler algorithms available + for use: Request Counting and Weighted Traffic Counting. These are controlled + via the lbmethod value of the Balancer definition. See + the Proxy directive for + more information.

    + +
    + +
    + Request Counting Algorithm +

    Enabled via lbmethod=requests, the idea behind this + scheduler is that we distribute the requests among the + various workers to ensure that each gets their configured share + of the number of requests. It works as follows:

    + +

    lbfactor is how much we expect this worker + to work, or the workers's work quota. This is + a normalized value representing their "share" of the amount of + work to be done.

    + +

    lbstatus is how urgent this worker has to work + to fulfill its quota of work.

    + +

    The worker is a member of the load balancer, + usually a remote host serving one of the supported protocols.

    + +

    We distribute each worker's work quota to the worker, and then look + which of them needs to work most urgently (biggest lbstatus). This + worker is then selected for work, and its lbstatus reduced by the + total work quota we distributed to all workers. Thus the sum of all + lbstatus does not change(*) and we distribute the requests + as desired.

    + +

    If some workers are disabled, the others will + still be scheduled correctly.

    + +
    for each worker in workers
    +    worker lbstatus += worker lbfactor
    +    total factor    += worker lbfactor
    +    if worker lbstatus > candidate lbstatus
    +        candidate = worker
    +
    +candidate lbstatus -= total factor
    +
    + +

    If a balancer is configured as follows:

    + + + + + + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    lbstatus0000
    + +

    And b gets disabled, the following schedule is produced:

    + + + + + + + + + + + + + + + + + + + + + + + +
    workerabcd
    lbstatus-5002525
    lbstatus-250-2550
    lbstatus0000
    (repeat)
    + +

    That is it schedules: a c d + a c d a c + d ... Please note that:

    + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    + +

    Has the exact same behavior as:

    + + + + + + + + + + + + +
    workerabcd
    lbfactor1111
    + +

    This is because all values of lbfactor are normalized + with respect to the others. For:

    + + + + + + + + + + +
    workerabc
    lbfactor141
    + +

    worker b will, on average, get 4 times the requests + that a and c will.

    + +

    The following asymmetric configuration works as one would expect:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    workerab
    lbfactor7030
     
    lbstatus-3030
    lbstatus40-40
    lbstatus10-10
    lbstatus-2020
    lbstatus-5050
    lbstatus20-20
    lbstatus-1010
    lbstatus-4040
    lbstatus30-30
    lbstatus00
    (repeat)
    + +

    That is after 10 schedules, the schedule repeats and 7 a + are selected with 3 b interspersed.

    +
    + +
    + Weighted Traffic Counting Algorithm +

    Enabled via lbmethod=traffic, the idea behind this + scheduler is very similar to the Request Counting method, with + the following changes:

    + +

    lbfactor is how much traffic, in bytes, we want + this worker to handle. This is also a normalized value + representing their "share" of the amount of work to be done, + but instead of simply counting the number of requests, we take + into account the amount of traffic this worker has seen.

    + +

    If a balancer is configured as follows:

    + + + + + + + + + + +
    workerabc
    lbfactor121
    + +

    Then we mean that we want b to process twice the + amount of bytes than a or c should. It does + not necessarily mean that b would handle twice as + many requests, but it would process twice the I/O. Thus, the + size of the request and response are applied to the weighting + and selection algorithm.

    + +
    + +
    + Enabling Balancer Manager Support +

    This module requires the service of + mod_status. + Balancer manager enables dynamic update of balancer + members. You can use balancer manager to change the balance + factor or a particular member, or put it in the off line + mode. +

    + +

    Thus, in order to get the ability of load balancer management, + mod_status and mod_proxy_balancer + have to be present in the server.

    + +

    To enable load balancer management for browsers from the foo.com + domain add this code to your httpd.conf + configuration file

    + + <Location /balancer-manager>
    + SetHandler balancer-manager
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +
    + +

    You can now access load balancer manager by using a Web browser + to access the page + http://your.server.name/balancer-manager

    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.xml.ja b/trunk/docs/manual/mod/mod_proxy_balancer.xml.ja new file mode 100644 index 0000000000..b53052872a --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.xml.ja @@ -0,0 +1,307 @@ + + + + + + + + + +mod_proxy_balancer +$BIi2YJ,;6$N$?$a$N(B mod_proxy $B3HD%(B +Extension +proxy_balancer.c +proxy_balancer_module +2.1 $B0J9_(B + + +

    $BK\%b%8%e!<%k$K$O(B mod_proxy $B$,(B$BI,MW$G$9(B$B!#(B + HTTP, FTP $B$H(B AJP13 + $B%W%m%H%3%k$N%m!<%I%P%i%s%95!G=$r;}$C$F$$$^$9!#(B

    + +

    $B$G$9$+$i!"(B $B%m!<%I%P%i%s%9$rM-8z$K$9$k>l9g(B mod_proxy + $B$H(B mod_proxy_balancer $B$,%5!<%P$KAH$_9~$^$l$F(B + $B$$$J$1$l$P$$$1$^$;$s!#(B

    + + $B7Y9p(B +

    $B0BA4$J%5!<%P$K$9$k(B$B$^$G%W%m%/%75!G=$OM-8z$K$7$J$$$G$/$@$5$$!#(B + $B%*!<%W%s%W%m%-%7%5!<%P$O$"$J$?<+?H$N%M%C%H%o!<%/$K$H$C$F$b!"(B + $B%$%s%?!<%M%C%HA4BN$K$H$C$F$b4m81$G$9!#(B

    +
    +
    +mod_proxy + +
    + $B%m!<%I%P%i%s%5$N%9%1%8%e!<%i$N%"%k%4%j%:%`(B +

    $B8=;~E@$G$O(B 2 $BRequest Counting + $B$H!"%H%i%U%#%C%/NL$K$h$k$b$N(B Weighted Traffic Counting + $B$,$"$j$^$9!#%P%i%s%5$N@_Dj(B lbmethod $BCM$G!"$I$A$i$r;H$&$+;XDj$7$^$9!#(B + $B>\:Y$O(B Proxy $B%G%#%l%/%F%#%V$r(B + $B;2>H$7$F$/$@$5$$!#(B

    + +
    + +
    + Request Counting $B%"%k%4%j%:%`(B +

    lbmethod=requests $B$GM-8z$K$J$j$^$9!#(B + $B$3$N%9%1%8%e!<%i$NGX7J$K$"$k9M$(J}$O!"MM!9$J%o!<%+!<$,$=$l$>$l!"(B + $B@_Dj$5$l$F$$$kJ,C4%j%/%(%9%H?t$r$-$A$s$H + +

    lbfactor $B$O!"(B$B$I$NDxEY%o!<%+!<$K;E;v$r?6$k$+(B + $B$D$^$j(B$B%o!<%+!<$N%/%*!<%?(B$B$r;X$7$^$9!#$3$NCM$O(B "$BJ,C4(B" + $BNL$rI=$9@55,2=$5$l$?CM$G$9!#(B

    + +

    lbstatus $B$O!"(B$B%o!<%+!<$N%/%*!<%?$rK~$?$9$?$a$K(B + $B$I$N$0$i$$5^$.$GF/$+$J$1$l$P$J$i$J$$$+(B$B$r;X$7$^$9!#(B

    + +

    $B%o!<%+!<(B$B$O%m!<%I%P%i%s%5$N%a%s%P$G!"DL>o$O!"(B + $B%5%]!<%H$5$l$k%W%m%H%3%k$N$&$A$N0l$D$rDs6!$7$F$$$k%j%b!<%H%[%9%H$G$9!#(B +

    + +

    $B$^$:8D!9$N%o!<%+!<$K%o!<%+!<%/%*!<%?$r3d$j?6$j!"$I$N%o!<%+!<$,:G$b5^$.$G(B + $BF/$+$J$1$l$P$J$i$J$$$+(B (lbstatus $B$,:GBg$N$b$N(B) $B$rD4$Y$^$9!#(B + $B + +

    $B$"$k%o!<%+!<$,L58z$K$J$C$F$b!"B>$N$b$N$O@5>o$K%9%1%8%e!<%k$5$lB3$1$^$9!#(B +

    + +
    for each worker in workers
    +    worker lbstatus += worker lbfactor
    +    total factor    += worker lbfactor
    +    if worker lbstatus > candidate lbstatus
    +        candidate = worker
    +
    +candidate lbstatus -= total factor
    +
    + +

    $B%P%i%s%5$rl9g(B:

    + + + + + + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    lbstatus0000
    + +

    $B$=$7$F(B b $B$,L58z$K$J$C$?>l9g!" + + + + + + + + + + + + + + + + + + + + + + + +
    workerabcd
    lbstatus-5002525
    lbstatus-250-2550
    lbstatus0000
    (repeat)
    + +

    $B$D$^$j$3$N$h$&$K%9%1%8%e!<%k$5$l$^$9(B: a c + d a c d a + c d ... $B + + + + + + + + + + + + +
    workerabcd
    lbfactor25252525
    + +

    $B$3$N5sF0$O!" + + + + + + + + + + + + +
    workerabcd
    lbfactor1111
    + +

    This is because all values of lbfactor are normalized + with respect to the others. For:

    +

    lbfactor $B$OA4$F@55,2=$5$l$?$b$N$G!"(B + $BB>$H$NAjBPCM$@$+$i$G$9!# + + + + + + + + + + +
    workerabc
    lbfactor141
    + +

    $B%o!<%+!<(B b $B$O!"J?6Q$7$F!"(Ba $B$H(B c + $B$N(B 4 $BG\$N?t$N%j%/%(%9%H$r + +

    $BN$J@_Dj$G$O!"$3$&$J$k$HM=A[$5$l$k$G$7$g$&(B:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    workerab
    lbfactor7030
     
    lbstatus-3030
    lbstatus40-40
    lbstatus10-10
    lbstatus-2020
    lbstatus-5050
    lbstatus20-20
    lbstatus-1010
    lbstatus-4040
    lbstatus30-30
    lbstatus00
    (repeat)
    + +

    $B%9%1%8%e!<%k$O(B 10 $B%9%1%8%e!<%k8e$K7+$jJV$5$l!"(Ba 7 $B2s$H(B + b 3 $B2s$G$^$P$i$KA*$P$l$^$9!#(B

    +
    + +
    + Weighted Traffic Counting $B%"%k%4%j%:%`(B +

    lbmethod=traffic $B$GM-8z$K$J$j$^$9!#(B + $B$3$N%9%1%8%e!<%i$NGX7J$K$"$k9M$(J}$O!"(BRequest Counting + $B$HHs>o$K;w$F$$$^$9$,!" + +

    lbfactor $B$O(B $B$I$l$@$1$N%P%$%H?t$N%H%i%U%#%C%/NL$r!"(B + $B$3$N%o!<%+!<$K=hM}$7$F$b$i$$$?$$$+(B $B$rI=$7$^$9!#(B + $B$3$NCM$bF1MM$K@55,2=$5$l$?CM$G!"%o!<%+!AwNL$r=hM}$7$?$+$r?t$($^$9!#(B

    + +

    $Bl9g(B:

    + + + + + + + + + + +
    workerabc
    lbfactor121
    + +

    b $B$K$O(B a $B$d(B c $B$N(B 2 $BG\(B + $B=hM}$7$F$[$7$$$H$$$&$3$H$K$J$j$^$9!#(B + b $B$O(B 2 $BG\$N(B I/O $B$r=hM}$9$k$H$$$&0UL#$K$J$j!"(B + 2 $BG\$N%j%/%(%9%H?t$r=hM}$9$k$H$$$&$3$H$K$O$J$j$^$;$s!#(B + $B$G$9$+$i%j%/%(%9%H$H%l%9%]%s%9$N%5%$%:$,!"(B + $B=E$_IU$1$H?6$jJ,$1$N%"%k%4%j%:%`$K8z$$$F$$$^$9!#(B

    + +
    + +
    + $B%P%i%s%5%^%M!<%8%c$N%5%]!<%H$rM-8z$K$9$k(B +

    $B$3$N%b%8%e!<%k$O(B mod_status $B$N%5!<%S%9$r(B + $BI,MW$H$7$^$9(B$B!#(B + $B%P%i%s%5%^%M!<%8%c$r;H$&$H!"%P%i%s%5$N%a%s%P!<$NF0E*$J99?7$,(B + $B$G$-$^$9!#%P%i%s%5%^%M!<%8%c$r;H$C$F!"%P%i%s%978?t(B (lbfactor) + $B$rJQ99$7$?$j!"%a%s%P!<$rJQ99$7$?$j!"FCDj$N%a%s%P!<$r(B + $B%*%U%i%$%s%b!<%I$K$7$?$j$G$-$^$9!#(B

    + +

    $B$G$9$+$i!"%m!<%I%P%i%s%54IM}5!G=$r;H$$$?$1$l$P!"(B + mod_status $B$H(B mod_proxy_balancer + $B$r%5!<%P$KAH$_9~$^$J$1$l$P$J$j$^$;$s!#(B

    + +

    foo.com $B%I%a%$%s$N%V%i%&%6$+$i%m!<%I%P%i%s%54IM}5!G=$r(B + $B;H$($k$h$&$K$9$k$K$O!"httpd.conf + $B$KDI2C$7$^$9!#(B

    + + <Location /balancer-manager>
    + SetHandler balancer-manager
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +
    + +

    $B$3$&$9$k$H!"(Bhttp://your.server.name/balancer-manager + $B$N%Z!<%87PM3$G!"%&%'%V%V%i%&%6$+$i%m!<%I%P%i%s%5%^%M!<%8%c$K(B + $B%"%/%;%9$G$-$k$h$&$K$J$j$^$9!#(B

    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_balancer.xml.meta b/trunk/docs/manual/mod/mod_proxy_balancer.xml.meta new file mode 100644 index 0000000000..086a80711d --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_balancer.xml.meta @@ -0,0 +1,12 @@ + + + + mod_proxy_balancer + /mod/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/mod/mod_proxy_connect.html b/trunk/docs/manual/mod/mod_proxy_connect.html new file mode 100644 index 0000000000..315f683c7f --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_connect.html @@ -0,0 +1,3 @@ +URI: mod_proxy_connect.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_proxy_connect.html.en b/trunk/docs/manual/mod/mod_proxy_connect.html.en new file mode 100644 index 0000000000..44765e8a48 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_connect.html.en @@ -0,0 +1,62 @@ + + + +mod_proxy_connect - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy_connect

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:mod_proxy extension for +CONNECT request handling
    Status:Extension
    Module Identifier:proxy_connect_module
    Source File:proxy_connect.c
    +

    Summary

    + +

    This module requires the service of mod_proxy. It provides support for the CONNECT + HTTP method. This method is mainly used to tunnel SSL requests + through proxy servers.

    + +

    Thus, in order to get the ability of handling CONNECT + requests, mod_proxy and + mod_proxy_connect have to be present in the server.

    + +

    Warning

    +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +

    Directives

    +

    This module provides no + directives.

    +

    See also

    +
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_connect.xml b/trunk/docs/manual/mod/mod_proxy_connect.xml new file mode 100644 index 0000000000..332ff27032 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_connect.xml @@ -0,0 +1,52 @@ + + + + + + + + + +mod_proxy_connect +mod_proxy extension for +CONNECT request handling +Extension +proxy_connect.c +proxy_connect_module + + +

    This module requires the service of mod_proxy. It provides support for the CONNECT + HTTP method. This method is mainly used to tunnel SSL requests + through proxy servers.

    + +

    Thus, in order to get the ability of handling CONNECT + requests, mod_proxy and + mod_proxy_connect have to be present in the server.

    + + Warning +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +AllowCONNECT +mod_proxy + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_connect.xml.meta b/trunk/docs/manual/mod/mod_proxy_connect.xml.meta new file mode 100644 index 0000000000..a5847ae1e8 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_connect.xml.meta @@ -0,0 +1,11 @@ + + + + mod_proxy_connect + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_proxy_ftp.html b/trunk/docs/manual/mod/mod_proxy_ftp.html new file mode 100644 index 0000000000..a0f912a252 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ftp.html @@ -0,0 +1,3 @@ +URI: mod_proxy_ftp.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_proxy_ftp.html.en b/trunk/docs/manual/mod/mod_proxy_ftp.html.en new file mode 100644 index 0000000000..25840d8b66 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ftp.html.en @@ -0,0 +1,61 @@ + + + +mod_proxy_ftp - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy_ftp

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:FTP support module for +mod_proxy
    Status:Extension
    Module Identifier:proxy_ftp_module
    Source File:proxy_ftp.c
    +

    Summary

    + +

    This module requires the service of mod_proxy. It provides support for the proxying + FTP sites. Note that FTP support is currently limited to + the GET method.

    + +

    Thus, in order to get the ability of handling FTP proxy requests, + mod_proxy and mod_proxy_ftp + have to be present in the server.

    + +

    Warning

    +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +

    Directives

    +

    This module provides no + directives.

    +

    See also

    +
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_ftp.xml b/trunk/docs/manual/mod/mod_proxy_ftp.xml new file mode 100644 index 0000000000..db6e09ebec --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ftp.xml @@ -0,0 +1,51 @@ + + + + + + + + + +mod_proxy_ftp +FTP support module for +mod_proxy +Extension +proxy_ftp.c +proxy_ftp_module + + +

    This module requires the service of mod_proxy. It provides support for the proxying + FTP sites. Note that FTP support is currently limited to + the GET method.

    + +

    Thus, in order to get the ability of handling FTP proxy requests, + mod_proxy and mod_proxy_ftp + have to be present in the server.

    + + Warning +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +mod_proxy + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_ftp.xml.meta b/trunk/docs/manual/mod/mod_proxy_ftp.xml.meta new file mode 100644 index 0000000000..2941afd362 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_ftp.xml.meta @@ -0,0 +1,11 @@ + + + + mod_proxy_ftp + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_proxy_http.html b/trunk/docs/manual/mod/mod_proxy_http.html new file mode 100644 index 0000000000..5be291027e --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_http.html @@ -0,0 +1,3 @@ +URI: mod_proxy_http.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_proxy_http.html.en b/trunk/docs/manual/mod/mod_proxy_http.html.en new file mode 100644 index 0000000000..95ba88fff5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_http.html.en @@ -0,0 +1,65 @@ + + + +mod_proxy_http - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_proxy_http

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:HTTP support module for +mod_proxy
    Status:Extension
    Module Identifier:proxy_http_module
    Source File:proxy_http.c
    +

    Summary

    + +

    This module requires the service of mod_proxy. It provides the features used for + proxying HTTP requests. mod_proxy_http + supports HTTP/0.9, HTTP/1.0 and HTTP/1.1. It does not + provide any caching abilities. If you want to set up a caching + proxy, you might want to use the additional service of the + mod_cache module.

    + +

    Thus, in order to get the ability of handling HTTP proxy requests, + mod_proxy and mod_proxy_http + have to be present in the server.

    + +

    Warning

    +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +

    Directives

    +

    This module provides no + directives.

    +

    See also

    +
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_proxy_http.xml b/trunk/docs/manual/mod/mod_proxy_http.xml new file mode 100644 index 0000000000..0d56fa1ad1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_http.xml @@ -0,0 +1,55 @@ + + + + + + + + + +mod_proxy_http +HTTP support module for +mod_proxy +Extension +proxy_http.c +proxy_http_module + + +

    This module requires the service of mod_proxy. It provides the features used for + proxying HTTP requests. mod_proxy_http + supports HTTP/0.9, HTTP/1.0 and HTTP/1.1. It does not + provide any caching abilities. If you want to set up a caching + proxy, you might want to use the additional service of the + mod_cache module.

    + +

    Thus, in order to get the ability of handling HTTP proxy requests, + mod_proxy and mod_proxy_http + have to be present in the server.

    + + Warning +

    Do not enable proxying until you have secured your server. Open proxy + servers are dangerous both to your network and to the Internet at + large.

    +
    +
    +mod_proxy +mod_proxy_connect + +
    diff --git a/trunk/docs/manual/mod/mod_proxy_http.xml.meta b/trunk/docs/manual/mod/mod_proxy_http.xml.meta new file mode 100644 index 0000000000..eb39f10cec --- /dev/null +++ b/trunk/docs/manual/mod/mod_proxy_http.xml.meta @@ -0,0 +1,11 @@ + + + + mod_proxy_http + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_rewrite.html b/trunk/docs/manual/mod/mod_rewrite.html new file mode 100644 index 0000000000..5b651b93ab --- /dev/null +++ b/trunk/docs/manual/mod/mod_rewrite.html @@ -0,0 +1,3 @@ +URI: mod_rewrite.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_rewrite.html.en b/trunk/docs/manual/mod/mod_rewrite.html.en new file mode 100644 index 0000000000..62054a9be9 --- /dev/null +++ b/trunk/docs/manual/mod/mod_rewrite.html.en @@ -0,0 +1,1608 @@ + + + +mod_rewrite - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_rewrite

    +
    +

    Available Languages:  en 

    +
    + + + + +
    Description:Provides a rule-based rewriting engine to rewrite requested +URLs on the fly
    Status:Extension
    Module Identifier:rewrite_module
    Source File:mod_rewrite.c
    Compatibility:Available in Apache 1.3 and later
    +

    Summary

    + +

    This module uses a rule-based rewriting engine (based on a + regular-expression parser) to rewrite requested URLs on the + fly. It supports an unlimited number of rules and an + unlimited number of attached rule conditions for each rule to + provide a really flexible and powerful URL manipulation + mechanism. The URL manipulations can depend on various tests, + for instance server variables, environment variables, HTTP + headers, time stamps and even external database lookups in + various formats can be used to achieve a really granular URL + matching.

    + +

    This module operates on the full URLs (including the + path-info part) both in per-server context + (httpd.conf) and per-directory context + (.htaccess) and can even generate query-string + parts on result. The rewritten result can lead to internal + sub-processing, external request redirection or even to an + internal proxy throughput.

    + +

    Further details, discussion, and examples, are provided in the + detailed mod_rewrite documentation.

    +
    + +
    top
    +
    +

    Quoting Special Characters

    + +

    As of Apache 1.3.20, special characters in + TestString and Substitution strings can be + escaped (that is, treated as normal characters without their + usual special meaning) by prefixing them with a slash ('\') + character. In other words, you can include an actual + dollar-sign character in a Substitution string by + using '\$'; this keeps mod_rewrite from trying + to treat it as a backreference.

    +
    top
    +
    +

    Environment Variables

    + +

    This module keeps track of two additional (non-standard) + CGI/SSI environment variables named SCRIPT_URL + and SCRIPT_URI. These contain the + logical Web-view to the current resource, while the + standard CGI/SSI variables SCRIPT_NAME and + SCRIPT_FILENAME contain the physical + System-view.

    + +

    Notice: These variables hold the URI/URL as they were + initially requested, i.e., before any + rewriting. This is important because the rewriting process is + primarily used to rewrite logical URLs to physical + pathnames.

    + +

    Example

    +SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
    +SCRIPT_FILENAME=/u/rse/.www/index.html
    +SCRIPT_URL=/u/rse/
    +SCRIPT_URI=http://en1.engelschall.com/u/rse/
    +
    + +
    top
    +
    +

    Practical Solutions

    + +

    For numerous examples of common, and not-so-common, uses for + mod_rewrite, see the Rewrite + Guide, and the Advanced Rewrite + Guide documents.

    + +
    +
    top
    +

    RewriteBase Directive

    + + + + + + + + +
    Description:Sets the base URL for per-directory rewrites
    Syntax:RewriteBase URL-path
    Default:See usage for information.
    Context:directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_rewrite
    +

    The RewriteBase directive explicitly + sets the base URL for per-directory rewrites. As you will see + below, RewriteRule + can be used in per-directory config files + (.htaccess). There it will act locally, + i.e., the local directory prefix is stripped at this + stage of processing and your rewriting rules act only on the + remainder. At the end it is automatically added back to the + path. The default setting is; RewriteBase physical-directory-path

    + +

    When a substitution occurs for a new URL, this module has + to re-inject the URL into the server processing. To be able + to do this it needs to know what the corresponding URL-prefix + or URL-base is. By default this prefix is the corresponding + filepath itself. But at most websites URLs are NOT + directly related to physical filename paths, so this + assumption will usually be wrong! There you have to + use the RewriteBase directive to specify the + correct URL-prefix.

    + +
    If your webserver's URLs are not directly +related to physical file paths, you have to use +RewriteBase in every .htaccess +files where you want to use RewriteRule directives. +
    + +

    For example, assume the following per-directory config file:

    + +
    +#
    +#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
    +#  Remember: /abc/def is the physical path of /xyz, i.e., the server
    +#            has a 'Alias /xyz /abc/def' directive e.g.
    +#
    +
    +RewriteEngine On
    +
    +#  let the server know that we were reached via /xyz and not
    +#  via the physical path prefix /abc/def
    +RewriteBase   /xyz
    +
    +#  now the rewriting rules
    +RewriteRule   ^oldstuff\.html$  newstuff.html
    +
    + +

    In the above example, a request to + /xyz/oldstuff.html gets correctly rewritten to + the physical file /abc/def/newstuff.html.

    + +

    For Apache Hackers

    +

    The following list gives detailed information about + the internal processing steps:

    +
    +Request:
    +  /xyz/oldstuff.html
    +
    +Internal Processing:
    +  /xyz/oldstuff.html     -> /abc/def/oldstuff.html  (per-server Alias)
    +  /abc/def/oldstuff.html -> /abc/def/newstuff.html  (per-dir    RewriteRule)
    +  /abc/def/newstuff.html -> /xyz/newstuff.html      (per-dir    RewriteBase)
    +  /xyz/newstuff.html     -> /abc/def/newstuff.html  (per-server Alias)
    +
    +Result:
    +  /abc/def/newstuff.html
    +
    +

    This seems very complicated but is + the correct Apache internal processing, because the + per-directory rewriting comes too late in the + process. So, when it occurs the (rewritten) request + has to be re-injected into the Apache kernel! BUT: + While this seems like a serious overhead, it really + isn't, because this re-injection happens fully + internally to the Apache server and the same + procedure is used by many other operations inside + Apache. So, you can be sure the design and + implementation is correct.

    +
    + + +
    +
    top
    +

    RewriteCond Directive

    + + + + + + + +
    Description:Defines a condition under which rewriting will take place +
    Syntax: RewriteCond + TestString CondPattern
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_rewrite
    +

    The RewriteCond directive defines a + rule condition. Precede a RewriteRule directive with one + or more RewriteCond directives. The following + rewriting rule is only used if its pattern matches the current + state of the URI and if these additional + conditions apply too.

    + +

    TestString is a string which can contains the + following expanded constructs in addition to plain text:

    + +
      +
    • + RewriteRule backreferences: These are + backreferences of the form + +

      + $N +

      + (0 <= N <= 9) which provide access to the grouped + parts (parenthesis!) of the pattern from the + corresponding RewriteRule directive (the one + following the current bunch of RewriteCond + directives). +
    • + +
    • + RewriteCond backreferences: These are + backreferences of the form + +

      + %N +

      + (1 <= N <= 9) which provide access to the grouped + parts (parentheses!) of the pattern from the last matched + RewriteCond directive in the current bunch + of conditions. +
    • + +
    • + RewriteMap expansions: These are + expansions of the form + +

      + ${mapname:key|default} +

      + See the documentation for + RewriteMap for more details. +
    • + +
    • + Server-Variables: These are variables of + the form + +

      + %{ NAME_OF_VARIABLE + } +

      + where NAME_OF_VARIABLE can be a string taken + from the following list: + + + + + + + + + + + + + + + + + + + + + + + + +
      HTTP headers: connection & request: +
      + HTTP_USER_AGENT
      + HTTP_REFERER
      + HTTP_COOKIE
      + HTTP_FORWARDED
      + HTTP_HOST
      + HTTP_PROXY_CONNECTION
      + HTTP_ACCEPT
      +
      + REMOTE_ADDR
      + REMOTE_HOST
      + REMOTE_PORT
      + REMOTE_USER
      + REMOTE_IDENT
      + REQUEST_METHOD
      + SCRIPT_FILENAME
      + PATH_INFO
      + QUERY_STRING
      + AUTH_TYPE
      +
      +
      server internals: date and time: specials:
      + DOCUMENT_ROOT
      + SERVER_ADMIN
      + SERVER_NAME
      + SERVER_ADDR
      + SERVER_PORT
      + SERVER_PROTOCOL
      + SERVER_SOFTWARE
      +
      + TIME_YEAR
      + TIME_MON
      + TIME_DAY
      + TIME_HOUR
      + TIME_MIN
      + TIME_SEC
      + TIME_WDAY
      + TIME
      +
      + API_VERSION
      + THE_REQUEST
      + REQUEST_URI
      + REQUEST_FILENAME
      + IS_SUBREQ
      + HTTPS
      +
      + +
      +

      These variables all + correspond to the similarly named HTTP + MIME-headers, C variables of the Apache server or + struct tm fields of the Unix system. + Most are documented elsewhere in the Manual or in + the CGI specification. Those that are special to + mod_rewrite include:

      + +
      +
      IS_SUBREQ
      + +
      Will contain the text "true" if the request + currently being processed is a sub-request, + "false" otherwise. Sub-requests may be generated + by modules that need to resolve additional files + or URIs in order to complete their tasks.
      + +
      API_VERSION
      + +
      This is the version of the Apache module API + (the internal interface between server and + module) in the current httpd build, as defined in + include/ap_mmn.h. The module API version + corresponds to the version of Apache in use (in + the release version of Apache 1.3.14, for + instance, it is 19990320:10), but is mainly of + interest to module authors.
      + +
      THE_REQUEST
      + +
      The full HTTP request line sent by the + browser to the server (e.g., "GET + /index.html HTTP/1.1"). This does not + include any additional headers sent by the + browser.
      + +
      REQUEST_URI
      + +
      The resource requested in the HTTP request + line. (In the example above, this would be + "/index.html".)
      + +
      REQUEST_FILENAME
      + +
      The full local filesystem path to the file or + script matching the request.
      + +
      HTTPS
      + +
      Will contain the text "on" if the connection is + using SSL/TLS, or "off" otherwise. (This variable + can be safely used regardless of whether + mod_ssl is loaded).
      + +
      +
      +
    • +
    + +

    Special Notes:

    + +
      +
    1. The variables SCRIPT_FILENAME and REQUEST_FILENAME + contain the same value, i.e., the value of the + filename field of the internal + request_rec structure of the Apache server. + The first name is just the commonly known CGI variable name + while the second is the consistent counterpart to + REQUEST_URI (which contains the value of the + uri field of request_rec).
    2. + +
    3. There is the special format: + %{ENV:variable} where variable can be + any environment variable. This is looked-up via internal + Apache structures and (if not found there) via + getenv() from the Apache server process.
    4. + +
    5. There is the special format: + %{SSL:variable} where variable is the + name of an SSL environment + variable; this can be used whether or not + mod_ssl is loaded, but will always expand to + the empty string if it is not. Example: + %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to + 128.
    6. + +
    7. There is the special format: + %{HTTP:header} where header can be + any HTTP MIME-header name. This is looked-up from the HTTP + request. Example: %{HTTP:Proxy-Connection} is + the value of the HTTP header + ``Proxy-Connection:''.
    8. + +
    9. There is the special format + %{LA-U:variable} for look-aheads which perform + an internal (URL-based) sub-request to determine the final + value of variable. Use this when you want to use a + variable for rewriting which is actually set later in an + API phase and thus is not available at the current stage. + For instance when you want to rewrite according to the + REMOTE_USER variable from within the + per-server context (httpd.conf file) you have + to use %{LA-U:REMOTE_USER} because this + variable is set by the authorization phases which come + after the URL translation phase where mod_rewrite + operates. On the other hand, because mod_rewrite implements + its per-directory context (.htaccess file) via + the Fixup phase of the API and because the authorization + phases come before this phase, you just can use + %{REMOTE_USER} there.
    10. + +
    11. There is the special format: + %{LA-F:variable} which performs an internal + (filename-based) sub-request to determine the final value + of variable. Most of the time this is the same as + LA-U above.
    12. +
    + +

    CondPattern is the condition pattern, + i.e., a regular expression which is applied to the + current instance of the TestString, i.e., + TestString is evaluated and then matched against + CondPattern.

    + +

    Remember: CondPattern is a + perl compatible regular expression with some + additions:

    + +
      +
    1. You can prefix the pattern string with a + '!' character (exclamation mark) to specify a + non-matching pattern.
    2. + +
    3. + There are some special variants of CondPatterns. + Instead of real regular expression strings you can also + use one of the following: + +
        +
      • '<CondPattern' (is lexically + lower)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically lower than + CondPattern.
      • + +
      • '>CondPattern' (is lexically + greater)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically greater than + CondPattern.
      • + +
      • '=CondPattern' (is lexically + equal)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically equal to + CondPattern, i.e the two strings are exactly + equal (character by character). If CondPattern + is just "" (two quotation marks) this + compares TestString to the empty string.
      • + +
      • '-d' (is + directory)
        + Treats the TestString as a pathname and tests + if it exists and is a directory.
      • + +
      • '-f' (is regular + file)
        + Treats the TestString as a pathname and tests + if it exists and is a regular file.
      • + +
      • '-s' (is regular file with + size)
        + Treats the TestString as a pathname and tests + if it exists and is a regular file with size greater + than zero.
      • + +
      • '-l' (is symbolic + link)
        + Treats the TestString as a pathname and tests + if it exists and is a symbolic link.
      • + +
      • '-x' (has executable + permissions)
        + Treats the TestString as a pathname and tests + if it exists and has execution permissions. These permissions + are determined depending on the underlying OS.
      • + +
      • '-F' (is existing file via + subrequest)
        + Checks if TestString is a valid file and + accessible via all the server's currently-configured + access controls for that path. This uses an internal + subrequest to determine the check, so use it with care + because it decreases your servers performance!
      • + +
      • '-U' (is existing URL via + subrequest)
        + Checks if TestString is a valid URL and + accessible via all the server's currently-configured + access controls for that path. This uses an internal + subrequest to determine the check, so use it with care + because it decreases your server's performance!
      • +
      + +

      Notice

      + All of these tests can + also be prefixed by an exclamation mark ('!') to + negate their meaning. +
      +
    4. +
    + +

    Additionally you can set special flags for + CondPattern by appending

    + +

    + [flags] +

    + +

    as the third argument to the RewriteCond + directive. Flags is a comma-separated list of the + following flags:

    + +
      +
    • 'nocase|NC' + (no case)
      + This makes the test case-insensitive, i.e., there + is no difference between 'A-Z' and 'a-z' both in the + expanded TestString and the CondPattern. + This flag is effective only for comparisons between + TestString and CondPattern. It has no + effect on filesystem and subrequest checks.
    • + +
    • + 'ornext|OR' + (or next condition)
      + Use this to combine rule conditions with a local OR + instead of the implicit AND. Typical example: + +
      +RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host2.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host3.*
      +RewriteRule ...some special stuff for any of these hosts...
      +
      + + Without this flag you would have to write the cond/rule + three times. +
    • +
    + +

    Example:

    + +

    To rewrite the Homepage of a site according to the + ``User-Agent:'' header of the request, you can + use the following:

    + +
    +RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
    +RewriteRule  ^/$                 /homepage.max.html  [L]
    +
    +RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
    +RewriteRule  ^/$                 /homepage.min.html  [L]
    +
    +RewriteRule  ^/$                 /homepage.std.html  [L]
    +
    + +

    Interpretation: If you use Netscape Navigator as your + browser (which identifies itself as 'Mozilla'), then you + get the max homepage, which includes Frames, etc. + If you use the Lynx browser (which is Terminal-based), then + you get the min homepage, which contains no images, no + tables, etc. If you use any other browser you get + the standard homepage.

    + + +
    +
    top
    +

    RewriteEngine Directive

    + + + + + + + + +
    Description:Enables or disables runtime rewriting engine
    Syntax:RewriteEngine on|off
    Default:RewriteEngine off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_rewrite
    + +

    The RewriteEngine directive enables or + disables the runtime rewriting engine. If it is set to + off this module does no runtime processing at + all. It does not even update the SCRIPT_URx + environment variables.

    + +

    Use this directive to disable the module instead of + commenting out all the RewriteRule directives!

    + +

    Note that, by default, rewrite configurations are not + inherited. This means that you need to have a + RewriteEngine on directive for each virtual host + in which you wish to use it.

    + +
    +
    top
    +

    RewriteLock Directive

    + + + + + + +
    Description:Sets the name of the lock file used for RewriteMap +synchronization
    Syntax:RewriteLock file-path
    Context:server config
    Status:Extension
    Module:mod_rewrite
    +

    This directive sets the filename for a synchronization + lockfile which mod_rewrite needs to communicate with RewriteMap + programs. Set this lockfile to a local path (not on a + NFS-mounted device) when you want to use a rewriting + map-program. It is not required for other types of rewriting + maps.

    + +
    +
    top
    +

    RewriteLog Directive

    + + + + + + +
    Description:Sets the name of the file used for logging rewrite engine +processing
    Syntax:RewriteLog file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_rewrite
    +

    The RewriteLog directive sets the name + of the file to which the server logs any rewriting actions it + performs. If the name does not begin with a slash + ('/') then it is assumed to be relative to the + Server Root. The directive should occur only once per + server config.

    + +
    To disable the logging of + rewriting actions it is not recommended to set + Filename to /dev/null, because + although the rewriting engine does not then output to a + logfile it still creates the logfile output internally. + This will slow down the server with no advantage + to the administrator! To disable logging either + remove or comment out the RewriteLog + directive or use RewriteLogLevel 0! +
    + +

    Security

    + +See the Apache Security Tips +document for details on why your security could be compromised if the +directory where logfiles are stored is writable by anyone other than +the user that starts the server. +
    + +

    Example

    +RewriteLog "/usr/local/var/apache/logs/rewrite.log" +

    + + +
    +
    top
    +

    RewriteLogLevel Directive

    + + + + + + + +
    Description:Sets the verbosity of the log file used by the rewrite +engine
    Syntax:RewriteLogLevel Level
    Default:RewriteLogLevel 0
    Context:server config, virtual host
    Status:Extension
    Module:mod_rewrite
    +

    The RewriteLogLevel directive sets the + verbosity level of the rewriting logfile. The default level 0 + means no logging, while 9 or more means that practically all + actions are logged.

    + +

    To disable the logging of rewriting actions simply set + Level to 0. This disables all rewrite action + logs.

    + +
    Using a high value for + Level will slow down your Apache server + dramatically! Use the rewriting logfile at a + Level greater than 2 only for debugging! +
    + +

    Example

    +RewriteLogLevel 3 +

    + + +
    +
    top
    +

    RewriteMap Directive

    + + + + + + + +
    Description:Defines a mapping function for key-lookup
    Syntax:RewriteMap MapName MapType:MapSource +
    Context:server config, virtual host
    Status:Extension
    Module:mod_rewrite
    Compatibility:The choice of different dbm types is available in +Apache 2.0.41 and later
    +

    The RewriteMap directive defines a + Rewriting Map which can be used inside rule + substitution strings by the mapping-functions to + insert/substitute fields through a key lookup. The source of + this lookup can be of various types.

    + +

    The MapName is + the name of the map and will be used to specify a + mapping-function for the substitution strings of a rewriting + rule via one of the following constructs:

    + +

    + ${ MapName : + LookupKey }
    + ${ MapName : + LookupKey | DefaultValue + }
    +

    + +

    When such a construct occurs the map MapName is + consulted and the key LookupKey is looked-up. If the + key is found, the map-function construct is substituted by + SubstValue. If the key is not found then it is + substituted by DefaultValue or by the empty string + if no DefaultValue was specified.

    + +

    The following combinations for MapType and + MapSource can be used:

    + +
      +
    • + Standard Plain Text
      + MapType: txt, MapSource: Unix filesystem + path to valid regular file + +

      This is the standard rewriting map feature where the + MapSource is a plain ASCII file containing + either blank lines, comment lines (starting with a '#' + character) or pairs like the following - one per + line.

      + +

      + MatchingKey + SubstValue +

      + +

      Example

      +##
      +##  map.txt -- rewriting map
      +##
      +
      +Ralf.S.Engelschall    rse   # Bastard Operator From Hell
      +Mr.Joe.Average        joe   # Mr. Average
      +
      + +

      +RewriteMap real-to-user txt:/path/to/file/map.txt +

      +
    • + +
    • + Randomized Plain Text
      + MapType: rnd, MapSource: Unix filesystem + path to valid regular file + +

      This is identical to the Standard Plain Text variant + above but with a special post-processing feature: After + looking up a value it is parsed according to contained + ``|'' characters which have the meaning of + ``or''. In other words they indicate a set of + alternatives from which the actual returned value is + chosen randomly. Although this sounds crazy and useless, + it was actually designed for load balancing in a reverse + proxy situation where the looked up values are server + names. Example:

      + +
      +##
      +##  map.txt -- rewriting map
      +##
      +
      +static   www1|www2|www3|www4
      +dynamic  www5|www6
      +
      + +

      +RewriteMap servers rnd:/path/to/file/map.txt +

      +
    • + +
    • + Hash File
      MapType: + dbm[=type], MapSource: Unix filesystem + path to valid regular file + +

      Here the source is a binary format DBM file containing + the same contents as a Plain Text format file, but + in a special representation which is optimized for really + fast lookups. The type can be sdbm, gdbm, ndbm, or + db depending on compile-time + settings. If the type is omitted, the + compile-time default will be chosen. You can create such a + file with any DBM tool or with the following Perl + script. Be sure to adjust it to create the appropriate + type of DBM. The example creates an NDBM file.

      + +
      +#!/path/to/bin/perl
      +##
      +##  txt2dbm -- convert txt map to dbm format
      +##
      +
      +use NDBM_File;
      +use Fcntl;
      +
      +($txtmap, $dbmmap) = @ARGV;
      +
      +open(TXT, "<$txtmap") or die "Couldn't open $txtmap!\n";
      +tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644)
      +  or die "Couldn't create $dbmmap!\n";
      +
      +while (<TXT>) {
      +  next if (/^\s*#/ or /^\s*$/);
      +  $DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/);
      +}
      +
      +untie %DB;
      +close(TXT);
      +
      + +

      +$ txt2dbm map.txt map.db +

      +
    • + +
    • + Internal Function
      + MapType: int, MapSource: Internal Apache + function + +

      Here the source is an internal Apache function. + Currently you cannot create your own, but the following + functions already exists:

      + +
        +
      • toupper:
        + Converts the looked up key to all upper case.
      • + +
      • tolower:
        + Converts the looked up key to all lower case.
      • + +
      • escape:
        + Translates special characters in the looked up key to + hex-encodings.
      • + +
      • unescape:
        + Translates hex-encodings in the looked up key back to + special characters.
      • +
      +
    • + +
    • + External Rewriting Program
      + MapType: prg, MapSource: Unix filesystem + path to valid regular file + +

      Here the source is a program, not a map file. To + create it you can use the language of your choice, but + the result has to be a executable (i.e., either + object-code or a script with the magic cookie trick + '#!/path/to/interpreter' as the first + line).

      + +

      This program is started once at startup of the Apache + servers and then communicates with the rewriting engine + over its stdin and stdout + file-handles. For each map-function lookup it will + receive the key to lookup as a newline-terminated string + on stdin. It then has to give back the + looked-up value as a newline-terminated string on + stdout or the four-character string + ``NULL'' if it fails (i.e., there + is no corresponding value for the given key). A trivial + program which will implement a 1:1 map (i.e., + key == value) could be:

      + +
      +#!/usr/bin/perl
      +$| = 1;
      +while (<STDIN>) {
      +    # ...put here any transformations or lookups...
      +    print $_;
      +}
      +
      + +

      But be very careful:

      + +
        +
      1. ``Keep it simple, stupid'' (KISS), because + if this program hangs it will hang the Apache server + when the rule occurs.
      2. + +
      3. Avoid one common mistake: never do buffered I/O on + stdout! This will cause a deadloop! Hence + the ``$|=1'' in the above example...
      4. + +
      5. Use the RewriteLock directive to + define a lockfile mod_rewrite can use to synchronize the + communication to the program. By default no such + synchronization takes place.
      6. +
      +
    • +
    +

    The RewriteMap directive can occur more than + once. For each mapping-function use one + RewriteMap directive to declare its rewriting + mapfile. While you cannot declare a map in + per-directory context it is of course possible to + use this map in per-directory context.

    + +

    Note

    For plain text and DBM format files the +looked-up keys are cached in-core until the mtime of the +mapfile changes or the server does a restart. This way you can have +map-functions in rules which are used for every +request. This is no problem, because the external lookup only happens +once! +
    + + +
    +
    top
    +

    RewriteOptions Directive

    + + + + + + + + +
    Description:Sets some special options for the rewrite engine
    Syntax:RewriteOptions Options
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_rewrite
    Compatibility:MaxRedirects is no longer available in version 2.1 and +later
    + +

    The RewriteOptions directive sets some + special options for the current per-server or per-directory + configuration. The Option string can be currently only one:

    + +
    +
    inherit
    +
    This forces the current configuration to inherit the + configuration of the parent. In per-virtual-server context + this means that the maps, conditions and rules of the main + server are inherited. In per-directory context this means + that conditions and rules of the parent directory's + .htaccess configuration are inherited.
    +
    + +
    +
    top
    +

    RewriteRule Directive

    + + + + + + + + +
    Description:Defines rules for the rewriting engine
    Syntax:RewriteRule + Pattern Substitution
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_rewrite
    Compatibility:The cookie-flag is available in Apache 2.0.40 and later.
    +

    The RewriteRule directive is the real + rewriting workhorse. The directive can occur more than once. + Each directive then defines one single rewriting rule. The + definition order of these rules is + important, because this order is used when + applying the rules at run-time.

    + +

    Pattern is + a perl compatible regular + expression which gets applied to the current URL. Here + ``current'' means the value of the URL when this rule gets + applied. This may not be the originally requested URL, + because any number of rules may already have matched and made + alterations to it.

    + +

    Some hints about the syntax of regular expressions:

    + +
    +Text:
    +  .           Any single character
    +  [chars]     Character class: One  of chars
    +  [^chars]    Character class: None of chars
    +  text1|text2 Alternative: text1 or text2
    +
    +Quantifiers:
    +  ?           0 or 1 of the preceding text
    +  *           0 or N of the preceding text (N > 0)
    +  +           1 or N of the preceding text (N > 1)
    +
    +Grouping:
    +  (text)      Grouping of text
    +              (either to set the borders of an alternative or
    +              for making backreferences where the Nth group can 
    +              be used on the RHS of a RewriteRule with $N)
    +
    +Anchors:
    +  ^           Start of line anchor
    +  $           End   of line anchor
    +
    +Escaping:
    +  \char       escape that particular char
    +              (for instance to specify the chars ".[]()" etc.)
    +
    + +

    For more information about regular expressions have a look at the + perl regular expression manpage ("perldoc + perlre"). If you are interested in more detailed + information about regular expressions and their variants + (POSIX regex etc.) have a look at the + following dedicated book on this topic:

    + +

    + Mastering Regular Expressions, 2nd Edition
    + Jeffrey E.F. Friedl
    + O'Reilly & Associates, Inc. 2002
    + ISBN 0-596-00289-0
    +

    + +

    Additionally in mod_rewrite the NOT character + ('!') is a possible pattern prefix. This gives + you the ability to negate a pattern; to say, for instance: + ``if the current URL does NOT match this + pattern''. This can be used for exceptional cases, where + it is easier to match the negative pattern, or as a last + default rule.

    + +

    Notice

    +When using the NOT character + to negate a pattern you cannot have grouped wildcard + parts in the pattern. This is impossible because when the + pattern does NOT match, there are no contents for the + groups. In consequence, if negated patterns are used, you + cannot use $N in the substitution + string! +
    + +

    Substitution of a + rewriting rule is the string which is substituted for (or + replaces) the original URL for which Pattern + matched. Beside plain text you can use

    + +
      +
    1. back-references $N to the RewriteRule + pattern
    2. + +
    3. back-references %N to the last matched + RewriteCond pattern
    4. + +
    5. server-variables as in rule condition test-strings + (%{VARNAME})
    6. + +
    7. mapping-function calls + (${mapname:key|default})
    8. +
    +

    Back-references are $N + (N=0..9) identifiers which will be replaced + by the contents of the Nth group of the + matched Pattern. The server-variables are the same + as for the TestString of a RewriteCond + directive. The mapping-functions come from the + RewriteMap directive and are explained there. + These three types of variables are expanded in the order of + the above list.

    + +

    As already mentioned above, all the rewriting rules are + applied to the Substitution (in the order of + definition in the config file). The URL is completely + replaced by the Substitution and the + rewriting process goes on until there are no more rules + unless explicitly terminated by a + L flag - see below.

    + +

    There is a special substitution string named + '-' which means: NO + substitution! Sounds silly? No, it is useful to + provide rewriting rules which only match + some URLs but do no substitution, e.g., in + conjunction with the C (chain) flag to be + able to have more than one pattern to be applied before a + substitution occurs.

    + +

    Query String

    +

    The Pattern will not match against the query string. + Instead, you must use a RewriteCond with the + %{QUERY_STRING} variable. You can, however, create + URLs in the substitution string containing a query string + part. Just use a question mark inside the substitution string to + indicate that the following stuff should be re-injected into the + query string. When you want to erase an existing query string, + end the substitution string with just the question mark. To + combine a new query string with an old one, use the + [QSA] flag (see below).

    +
    + +

    Substitution of Absolute URLs

    +

    There is a special feature: + When you prefix a substitution field with + http://thishost[:thisport] + then mod_rewrite automatically strips it + out. This auto-reduction on implicit external redirect + URLs is a useful and important feature when used in + combination with a mapping-function which generates the + hostname part. Have a look at the first example in the + example section below to understand this.

    + +

    Remember: An unconditional external + redirect to your own server will not work with the prefix + http://thishost because of this feature. To + achieve such a self-redirect, you have to use the + R-flag (see below).

    +
    + +

    Additionally you can set special flags for Substitution by + appending

    + +

    + [flags] +

    +

    + as the third argument to the RewriteRule + directive. Flags is a comma-separated list of the + following flags:

    + +
      +
    • 'chain|C' + (chained with next rule)
      + This flag chains the current rule with the next rule + (which itself can be chained with the following rule, + etc.). This has the following effect: if a rule + matches, then processing continues as usual, i.e., + the flag has no effect. If the rule does + not match, then all following chained + rules are skipped. For instance, use it to remove the + ``.www'' part inside a per-directory rule set + when you let an external redirect happen (where the + ``.www'' part should not to occur!).
    • + +
    • + 'cookie|CO=NAME:VAL:domain[:lifetime[:path]]' + (set cookie)
      + This sets a cookie on the client's browser. The cookie's name + is specified by NAME and the value is + VAL. The domain field is the domain of the + cookie, such as '.apache.org',the optional lifetime + is the lifetime of the cookie in minutes, and the optional + path is the path of the cookie
    • + +
    • + 'env|E=VAR:VAL' + (set environment variable)
      + This forces an environment variable named VAR to + be set to the value VAL, where VAL can + contain regexp backreferences $N and + %N which will be expanded. You can use this + flag more than once to set more than one variable. The + variables can be later dereferenced in many situations, but + usually from within XSSI (via <!--#echo + var="VAR"-->) or CGI (e.g. + $ENV{'VAR'}). Additionally you can dereference + it in a following RewriteCond pattern via + %{ENV:VAR}. Use this to strip but remember + information from URLs.
    • + +
    • 'forbidden|F' (force URL + to be forbidden)
      + This forces the current URL to be forbidden, + i.e., it immediately sends back a HTTP response of + 403 (FORBIDDEN). Use this flag in conjunction with + appropriate RewriteConds to conditionally block some + URLs.
    • + +
    • 'gone|G' (force URL to be + gone)
      + This forces the current URL to be gone, i.e., it + immediately sends back a HTTP response of 410 (GONE). Use + this flag to mark pages which no longer exist as gone.
    • + +
    • + 'handler|H=Content-handler' + (force Content handler)
      + Force the Content-handler of the target file to be + Content-handler. For instance, this can be used to + simulate the mod_alias directive + ScriptAlias which internally forces all files + inside the mapped directory to have a handler of + ``cgi-script''.
    • + +
    • 'last|L' + (last rule)
      + Stop the rewriting process here and don't apply any more + rewriting rules. This corresponds to the Perl + last command or the break command + from the C language. Use this flag to prevent the currently + rewritten URL from being rewritten further by following + rules. For example, use it to rewrite the root-path URL + ('/') to a real one, e.g., + '/e/www/'.
    • + +
    • 'next|N' + (next round)
      + Re-run the rewriting process (starting again with the + first rewriting rule). Here the URL to match is again not + the original URL but the URL from the last rewriting rule. + This corresponds to the Perl next command or + the continue command from the C language. Use + this flag to restart the rewriting process, i.e., + to immediately go to the top of the loop.
      + But be careful not to create an infinite + loop!
    • + +
    • 'nocase|NC' + (no case)
      + This makes the Pattern case-insensitive, + i.e., there is no difference between 'A-Z' and + 'a-z' when Pattern is matched against the current + URL.
    • + +
    • + 'noescape|NE' + (no URI escaping of + output)
      + This flag keeps mod_rewrite from applying the usual URI + escaping rules to the result of a rewrite. Ordinarily, + special characters (such as '%', '$', ';', and so on) + will be escaped into their hexcode equivalents ('%25', + '%24', and '%3B', respectively); this flag prevents this + from being done. This allows percent symbols to appear in + the output, as in +

      + RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] +

      + + which would turn '/foo/zed' into a safe + request for '/bar?arg=P1=zed'. +
    • + +
    • + 'nosubreq|NS' (used only if + no internal + sub-request)
      + This flag forces the rewriting engine to skip a + rewriting rule if the current request is an internal + sub-request. For instance, sub-requests occur internally + in Apache when mod_include tries to find out + information about possible directory default files + (index.xxx). On sub-requests it is not + always useful and even sometimes causes a failure to if + the complete set of rules are applied. Use this flag to + exclude some rules.
      + + +

      Use the following rule for your decision: whenever you + prefix some URLs with CGI-scripts to force them to be + processed by the CGI-script, the chance is high that you + will run into problems (or even overhead) on + sub-requests. In these cases, use this flag.

      +
    • + +
    • + 'proxy|P' (force + proxy)
      + This flag forces the substitution part to be internally + forced as a proxy request and immediately (i.e., + rewriting rule processing stops here) put through the proxy module. You have to make + sure that the substitution string is a valid URI + (e.g., typically starting with + http://hostname) which can be + handled by the Apache proxy module. If not you get an + error from the proxy module. Use this flag to achieve a + more powerful implementation of the ProxyPass directive, + to map some remote stuff into the namespace of the local + server. + +

      Notice: To use this functionality make sure you have + the proxy module compiled into your Apache server + program. If you don't know please check whether + mod_proxy.c is part of the ``httpd + -l'' output. If yes, this functionality is + available to mod_rewrite. If not, then you first have to + rebuild the httpd program with mod_proxy + enabled.

      +
    • + +
    • + 'passthrough|PT' + (pass through to next + handler)
      + This flag forces the rewriting engine to set the + uri field of the internal + request_rec structure to the value of the + filename field. This flag is just a hack to + be able to post-process the output of + RewriteRule directives by + Alias, ScriptAlias, + Redirect, etc. directives from + other URI-to-filename translators. A trivial example to + show the semantics: If you want to rewrite + /abc to /def via the rewriting + engine of mod_rewrite and then + /def to /ghi with + mod_alias: +

      + RewriteRule ^/abc(.*) /def$1 [PT]
      + Alias /def /ghi +

      + If you omit the PT flag then + mod_rewrite will do its job fine, + i.e., it rewrites uri=/abc/... to + filename=/def/... as a full API-compliant + URI-to-filename translator should do. Then + mod_alias comes and tries to do a + URI-to-filename transition which will not work. + +

      Note: You have to use this flag if you want to + intermix directives of different modules which contain + URL-to-filename translators. The typical example + is the use of mod_alias and + mod_rewrite..

      +
    • + +
    • 'qsappend|QSA' + (query string + append)
      + This flag forces the rewriting engine to append a query + string part in the substitution string to the existing one + instead of replacing it. Use this when you want to add more + data to the query string via a rewrite rule.
    • + +
    • 'redirect|R + [=code]' (force redirect)
      + Prefix Substitution with + http://thishost[:thisport]/ (which makes the + new URL a URI) to force a external redirection. If no + code is given a HTTP response of 302 (MOVED + TEMPORARILY) is used. If you want to use other response + codes in the range 300-400 just specify them as a number + or use one of the following symbolic names: + temp (default), permanent, + seeother. Use it for rules which should + canonicalize the URL and give it back to the client, + e.g., translate ``/~'' into + ``/u/'' or always append a slash to + /u/user, etc.
      + + +

      Note: When you use this flag, make + sure that the substitution field is a valid URL! If not, + you are redirecting to an invalid location! And remember + that this flag itself only prefixes the URL with + http://thishost[:thisport]/, rewriting + continues. Usually you also want to stop and do the + redirection immediately. To stop the rewriting you also + have to provide the 'L' flag.

      +
    • + +
    • 'skip|S=num' + (skip next rule(s))
      + This flag forces the rewriting engine to skip the next + num rules in sequence when the current rule + matches. Use this to make pseudo if-then-else constructs: + The last rule of the then-clause becomes + skip=N where N is the number of rules in the + else-clause. (This is not the same as the + 'chain|C' flag!)
    • + +
    • + 'type|T=MIME-type' + (force MIME type)
      + Force the MIME-type of the target file to be + MIME-type. For instance, this can be used to + setup the content-type based on some conditions. + For example, the following snippet allows .php files to + be displayed by mod_php if they are called with + the .phps extension: +

      + RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source] +

      +
    • + + +
    + +

    Note

    Never forget that Pattern is +applied to a complete URL in per-server configuration +files. But in per-directory configuration files, the +per-directory prefix (which always is the same for a specific +directory!) is automatically removed for the pattern matching +and automatically added after the substitution has been +done. This feature is essential for many sorts of rewriting, +because without this prefix stripping you have to match the parent +directory which is not always possible. + +

    There is one exception: If a substitution string + starts with ``http://'' then the directory + prefix will not be added and an + external redirect or proxy throughput (if flag + P is used!) is forced!

    +
    + +

    Note

    + To enable the rewriting engine + for per-directory configuration files you need to set + ``RewriteEngine On'' in these files + and ``Options + FollowSymLinks'' must be enabled. If your + administrator has disabled override of + FollowSymLinks for a user's directory, then + you cannot use the rewriting engine. This restriction is + needed for security reasons. +
    + +

    Here are all possible substitution combinations and their + meanings:

    + +

    Inside per-server configuration + (httpd.conf)
    + for request ``GET + /somepath/pathinfo'':

    +

    + +
    +Given Rule                                      Resulting Substitution
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) otherpath$1                      not supported, because invalid!
    +
    +^/somepath(.*) otherpath$1  [R]                 not supported, because invalid!
    +
    +^/somepath(.*) otherpath$1  [P]                 not supported, because invalid!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) /otherpath$1                     /otherpath/pathinfo
    +
    +^/somepath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) /otherpath$1 [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) http://thishost/otherpath$1      /otherpath/pathinfo
    +
    +^/somepath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) http://thishost/otherpath$1 [P]  not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +                                                (the [R] flag is redundant)
    +
    +^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    +                                                via internal proxy
    +
    + +

    Inside per-directory configuration for + /somepath
    + (i.e., file .htaccess in dir + /physical/path/to/somepath containing + RewriteBase /somepath)
    + for request ``GET + /somepath/localpath/pathinfo'':

    +

    + +
    +Given Rule                                      Resulting Substitution
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) otherpath$1                      /somepath/otherpath/pathinfo
    +
    +^localpath(.*) otherpath$1  [R]                 http://thishost/somepath/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) otherpath$1  [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) /otherpath$1                     /otherpath/pathinfo
    +
    +^localpath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) /otherpath$1 [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) http://thishost/otherpath$1      /otherpath/pathinfo
    +
    +^localpath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) http://thishost/otherpath$1 [P]  not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +                                                (the [R] flag is redundant)
    +
    +^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    +                                                via internal proxy
    +
    + +

    Example:

    + +

    We want to rewrite URLs of the form

    + +

    + / Language /~ + Realname /.../ File +

    + +

    into

    + +

    + /u/ Username /.../ + File . Language +

    + +

    We take the rewrite mapfile from above and save it under + /path/to/file/map.txt. Then we only have to + add the following lines to the Apache server configuration + file:

    + +
    +RewriteLog   /path/to/file/rewrite.log
    +RewriteMap   real-to-user               txt:/path/to/file/map.txt
    +RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1
    +
    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_rewrite.xml b/trunk/docs/manual/mod/mod_rewrite.xml new file mode 100644 index 0000000000..9bf42d7b61 --- /dev/null +++ b/trunk/docs/manual/mod/mod_rewrite.xml @@ -0,0 +1,1622 @@ + + + + + + + + + +mod_rewrite + +Provides a rule-based rewriting engine to rewrite requested +URLs on the fly + +Extension +mod_rewrite.c +rewrite_module +Available in Apache 1.3 and later + + +

    This module uses a rule-based rewriting engine (based on a + regular-expression parser) to rewrite requested URLs on the + fly. It supports an unlimited number of rules and an + unlimited number of attached rule conditions for each rule to + provide a really flexible and powerful URL manipulation + mechanism. The URL manipulations can depend on various tests, + for instance server variables, environment variables, HTTP + headers, time stamps and even external database lookups in + various formats can be used to achieve a really granular URL + matching.

    + +

    This module operates on the full URLs (including the + path-info part) both in per-server context + (httpd.conf) and per-directory context + (.htaccess) and can even generate query-string + parts on result. The rewritten result can lead to internal + sub-processing, external request redirection or even to an + internal proxy throughput.

    + +

    Further details, discussion, and examples, are provided in the + detailed mod_rewrite documentation.

    +
    + +
    Quoting Special Characters + +

    As of Apache 1.3.20, special characters in + TestString and Substitution strings can be + escaped (that is, treated as normal characters without their + usual special meaning) by prefixing them with a slash ('\') + character. In other words, you can include an actual + dollar-sign character in a Substitution string by + using '\$'; this keeps mod_rewrite from trying + to treat it as a backreference.

    +
    + +
    Environment Variables + +

    This module keeps track of two additional (non-standard) + CGI/SSI environment variables named SCRIPT_URL + and SCRIPT_URI. These contain the + logical Web-view to the current resource, while the + standard CGI/SSI variables SCRIPT_NAME and + SCRIPT_FILENAME contain the physical + System-view.

    + +

    Notice: These variables hold the URI/URL as they were + initially requested, i.e., before any + rewriting. This is important because the rewriting process is + primarily used to rewrite logical URLs to physical + pathnames.

    + +Example +
    +SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
    +SCRIPT_FILENAME=/u/rse/.www/index.html
    +SCRIPT_URL=/u/rse/
    +SCRIPT_URI=http://en1.engelschall.com/u/rse/
    +
    +
    + +
    + +
    Practical Solutions + +

    For numerous examples of common, and not-so-common, uses for + mod_rewrite, see the Rewrite + Guide, and the Advanced Rewrite + Guide documents.

    + +
    + + +RewriteEngine +Enables or disables runtime rewriting engine +RewriteEngine on|off +RewriteEngine off +server configvirtual host +directory.htaccess +FileInfo + + + +

    The RewriteEngine directive enables or + disables the runtime rewriting engine. If it is set to + off this module does no runtime processing at + all. It does not even update the SCRIPT_URx + environment variables.

    + +

    Use this directive to disable the module instead of + commenting out all the RewriteRule directives!

    + +

    Note that, by default, rewrite configurations are not + inherited. This means that you need to have a + RewriteEngine on directive for each virtual host + in which you wish to use it.

    +
    + +
    + + +RewriteOptions +Sets some special options for the rewrite engine +RewriteOptions Options +server configvirtual host +directory.htaccess +FileInfo +MaxRedirects is no longer available in version 2.1 and +later + + +

    The RewriteOptions directive sets some + special options for the current per-server or per-directory + configuration. The Option string can be currently only one:

    + +
    +
    inherit
    +
    This forces the current configuration to inherit the + configuration of the parent. In per-virtual-server context + this means that the maps, conditions and rules of the main + server are inherited. In per-directory context this means + that conditions and rules of the parent directory's + .htaccess configuration are inherited.
    +
    +
    + +
    + + +RewriteLog +Sets the name of the file used for logging rewrite engine +processing +RewriteLog file-path +server configvirtual host + + + +

    The RewriteLog directive sets the name + of the file to which the server logs any rewriting actions it + performs. If the name does not begin with a slash + ('/') then it is assumed to be relative to the + Server Root. The directive should occur only once per + server config.

    + + To disable the logging of + rewriting actions it is not recommended to set + Filename to /dev/null, because + although the rewriting engine does not then output to a + logfile it still creates the logfile output internally. + This will slow down the server with no advantage + to the administrator! To disable logging either + remove or comment out the RewriteLog + directive or use RewriteLogLevel 0! + + +Security + +See the Apache Security Tips +document for details on why your security could be compromised if the +directory where logfiles are stored is writable by anyone other than +the user that starts the server. + + +Example +RewriteLog "/usr/local/var/apache/logs/rewrite.log" + + +
    + +
    + + +RewriteLogLevel +Sets the verbosity of the log file used by the rewrite +engine +RewriteLogLevel Level +RewriteLogLevel 0 +server configvirtual host + + + +

    The RewriteLogLevel directive sets the + verbosity level of the rewriting logfile. The default level 0 + means no logging, while 9 or more means that practically all + actions are logged.

    + +

    To disable the logging of rewriting actions simply set + Level to 0. This disables all rewrite action + logs.

    + + Using a high value for + Level will slow down your Apache server + dramatically! Use the rewriting logfile at a + Level greater than 2 only for debugging! + + +Example +RewriteLogLevel 3 + + +
    + +
    + + +RewriteLock +Sets the name of the lock file used for RewriteMap +synchronization +RewriteLock file-path +server config + + +

    This directive sets the filename for a synchronization + lockfile which mod_rewrite needs to communicate with RewriteMap + programs. Set this lockfile to a local path (not on a + NFS-mounted device) when you want to use a rewriting + map-program. It is not required for other types of rewriting + maps.

    +
    + +
    + + +RewriteMap +Defines a mapping function for key-lookup +RewriteMap MapName MapType:MapSource + +server configvirtual host + +The choice of different dbm types is available in +Apache 2.0.41 and later + + +

    The RewriteMap directive defines a + Rewriting Map which can be used inside rule + substitution strings by the mapping-functions to + insert/substitute fields through a key lookup. The source of + this lookup can be of various types.

    + +

    The MapName is + the name of the map and will be used to specify a + mapping-function for the substitution strings of a rewriting + rule via one of the following constructs:

    + +

    + ${ MapName : + LookupKey }
    + ${ MapName : + LookupKey | DefaultValue + }
    +

    + +

    When such a construct occurs the map MapName is + consulted and the key LookupKey is looked-up. If the + key is found, the map-function construct is substituted by + SubstValue. If the key is not found then it is + substituted by DefaultValue or by the empty string + if no DefaultValue was specified.

    + +

    The following combinations for MapType and + MapSource can be used:

    + +
      +
    • + Standard Plain Text
      + MapType: txt, MapSource: Unix filesystem + path to valid regular file + +

      This is the standard rewriting map feature where the + MapSource is a plain ASCII file containing + either blank lines, comment lines (starting with a '#' + character) or pairs like the following - one per + line.

      + +

      + MatchingKey + SubstValue +

      + +Example +
      +##
      +##  map.txt -- rewriting map
      +##
      +
      +Ralf.S.Engelschall    rse   # Bastard Operator From Hell
      +Mr.Joe.Average        joe   # Mr. Average
      +
      +
      + + +RewriteMap real-to-user txt:/path/to/file/map.txt + +
    • + +
    • + Randomized Plain Text
      + MapType: rnd, MapSource: Unix filesystem + path to valid regular file + +

      This is identical to the Standard Plain Text variant + above but with a special post-processing feature: After + looking up a value it is parsed according to contained + ``|'' characters which have the meaning of + ``or''. In other words they indicate a set of + alternatives from which the actual returned value is + chosen randomly. Although this sounds crazy and useless, + it was actually designed for load balancing in a reverse + proxy situation where the looked up values are server + names. Example:

      + + +
      +##
      +##  map.txt -- rewriting map
      +##
      +
      +static   www1|www2|www3|www4
      +dynamic  www5|www6
      +
      +
      + + +RewriteMap servers rnd:/path/to/file/map.txt + +
    • + +
    • + Hash File
      MapType: + dbm[=type], MapSource: Unix filesystem + path to valid regular file + +

      Here the source is a binary format DBM file containing + the same contents as a Plain Text format file, but + in a special representation which is optimized for really + fast lookups. The type can be sdbm, gdbm, ndbm, or + db depending on compile-time + settings. If the type is omitted, the + compile-time default will be chosen. You can create such a + file with any DBM tool or with the following Perl + script. Be sure to adjust it to create the appropriate + type of DBM. The example creates an NDBM file.

      + + +
      +#!/path/to/bin/perl
      +##
      +##  txt2dbm -- convert txt map to dbm format
      +##
      +
      +use NDBM_File;
      +use Fcntl;
      +
      +($txtmap, $dbmmap) = @ARGV;
      +
      +open(TXT, "<$txtmap") or die "Couldn't open $txtmap!\n";
      +tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644)
      +  or die "Couldn't create $dbmmap!\n";
      +
      +while (<TXT>) {
      +  next if (/^\s*#/ or /^\s*$/);
      +  $DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/);
      +}
      +
      +untie %DB;
      +close(TXT);
      +
      +
      + + +$ txt2dbm map.txt map.db + +
    • + +
    • + Internal Function
      + MapType: int, MapSource: Internal Apache + function + +

      Here the source is an internal Apache function. + Currently you cannot create your own, but the following + functions already exists:

      + +
        +
      • toupper:
        + Converts the looked up key to all upper case.
      • + +
      • tolower:
        + Converts the looked up key to all lower case.
      • + +
      • escape:
        + Translates special characters in the looked up key to + hex-encodings.
      • + +
      • unescape:
        + Translates hex-encodings in the looked up key back to + special characters.
      • +
      +
    • + +
    • + External Rewriting Program
      + MapType: prg, MapSource: Unix filesystem + path to valid regular file + +

      Here the source is a program, not a map file. To + create it you can use the language of your choice, but + the result has to be a executable (i.e., either + object-code or a script with the magic cookie trick + '#!/path/to/interpreter' as the first + line).

      + +

      This program is started once at startup of the Apache + servers and then communicates with the rewriting engine + over its stdin and stdout + file-handles. For each map-function lookup it will + receive the key to lookup as a newline-terminated string + on stdin. It then has to give back the + looked-up value as a newline-terminated string on + stdout or the four-character string + ``NULL'' if it fails (i.e., there + is no corresponding value for the given key). A trivial + program which will implement a 1:1 map (i.e., + key == value) could be:

      + + +
      +#!/usr/bin/perl
      +$| = 1;
      +while (<STDIN>) {
      +    # ...put here any transformations or lookups...
      +    print $_;
      +}
      +
      +
      + +

      But be very careful:

      + +
        +
      1. ``Keep it simple, stupid'' (KISS), because + if this program hangs it will hang the Apache server + when the rule occurs.
      2. + +
      3. Avoid one common mistake: never do buffered I/O on + stdout! This will cause a deadloop! Hence + the ``$|=1'' in the above example...
      4. + +
      5. Use the RewriteLock directive to + define a lockfile mod_rewrite can use to synchronize the + communication to the program. By default no such + synchronization takes place.
      6. +
      +
    • +
    +

    The RewriteMap directive can occur more than + once. For each mapping-function use one + RewriteMap directive to declare its rewriting + mapfile. While you cannot declare a map in + per-directory context it is of course possible to + use this map in per-directory context.

    + +Note For plain text and DBM format files the +looked-up keys are cached in-core until the mtime of the +mapfile changes or the server does a restart. This way you can have +map-functions in rules which are used for every +request. This is no problem, because the external lookup only happens +once! + + +
    +
    + + +RewriteBase +Sets the base URL for per-directory rewrites +RewriteBase URL-path +See usage for information. +directory.htaccess + +FileInfo + + +

    The RewriteBase directive explicitly + sets the base URL for per-directory rewrites. As you will see + below, RewriteRule + can be used in per-directory config files + (.htaccess). There it will act locally, + i.e., the local directory prefix is stripped at this + stage of processing and your rewriting rules act only on the + remainder. At the end it is automatically added back to the + path. The default setting is; RewriteBase physical-directory-path

    + +

    When a substitution occurs for a new URL, this module has + to re-inject the URL into the server processing. To be able + to do this it needs to know what the corresponding URL-prefix + or URL-base is. By default this prefix is the corresponding + filepath itself. But at most websites URLs are NOT + directly related to physical filename paths, so this + assumption will usually be wrong! There you have to + use the RewriteBase directive to specify the + correct URL-prefix.

    + + If your webserver's URLs are not directly +related to physical file paths, you have to use +RewriteBase in every .htaccess +files where you want to use RewriteRule directives. + + +

    For example, assume the following per-directory config file:

    + + +
    +#
    +#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
    +#  Remember: /abc/def is the physical path of /xyz, i.e., the server
    +#            has a 'Alias /xyz /abc/def' directive e.g.
    +#
    +
    +RewriteEngine On
    +
    +#  let the server know that we were reached via /xyz and not
    +#  via the physical path prefix /abc/def
    +RewriteBase   /xyz
    +
    +#  now the rewriting rules
    +RewriteRule   ^oldstuff\.html$  newstuff.html
    +
    +
    + +

    In the above example, a request to + /xyz/oldstuff.html gets correctly rewritten to + the physical file /abc/def/newstuff.html.

    + +For Apache Hackers +

    The following list gives detailed information about + the internal processing steps:

    +
    +Request:
    +  /xyz/oldstuff.html
    +
    +Internal Processing:
    +  /xyz/oldstuff.html     -> /abc/def/oldstuff.html  (per-server Alias)
    +  /abc/def/oldstuff.html -> /abc/def/newstuff.html  (per-dir    RewriteRule)
    +  /abc/def/newstuff.html -> /xyz/newstuff.html      (per-dir    RewriteBase)
    +  /xyz/newstuff.html     -> /abc/def/newstuff.html  (per-server Alias)
    +
    +Result:
    +  /abc/def/newstuff.html
    +
    +

    This seems very complicated but is + the correct Apache internal processing, because the + per-directory rewriting comes too late in the + process. So, when it occurs the (rewritten) request + has to be re-injected into the Apache kernel! BUT: + While this seems like a serious overhead, it really + isn't, because this re-injection happens fully + internally to the Apache server and the same + procedure is used by many other operations inside + Apache. So, you can be sure the design and + implementation is correct.

    +
    + +
    + +
    + + +RewriteCond +Defines a condition under which rewriting will take place + + RewriteCond + TestString CondPattern +server configvirtual host +directory.htaccess +FileInfo + + +

    The RewriteCond directive defines a + rule condition. Precede a RewriteRule directive with one + or more RewriteCond directives. The following + rewriting rule is only used if its pattern matches the current + state of the URI and if these additional + conditions apply too.

    + +

    TestString is a string which can contains the + following expanded constructs in addition to plain text:

    + +
      +
    • + RewriteRule backreferences: These are + backreferences of the form + +

      + $N +

      + (0 <= N <= 9) which provide access to the grouped + parts (parenthesis!) of the pattern from the + corresponding RewriteRule directive (the one + following the current bunch of RewriteCond + directives). +
    • + +
    • + RewriteCond backreferences: These are + backreferences of the form + +

      + %N +

      + (1 <= N <= 9) which provide access to the grouped + parts (parentheses!) of the pattern from the last matched + RewriteCond directive in the current bunch + of conditions. +
    • + +
    • + RewriteMap expansions: These are + expansions of the form + +

      + ${mapname:key|default} +

      + See the documentation for + RewriteMap for more details. +
    • + +
    • + Server-Variables: These are variables of + the form + +

      + %{ NAME_OF_VARIABLE + } +

      + where NAME_OF_VARIABLE can be a string taken + from the following list: + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      HTTP headers: connection & request:
      + HTTP_USER_AGENT
      + HTTP_REFERER
      + HTTP_COOKIE
      + HTTP_FORWARDED
      + HTTP_HOST
      + HTTP_PROXY_CONNECTION
      + HTTP_ACCEPT
      +
      + REMOTE_ADDR
      + REMOTE_HOST
      + REMOTE_PORT
      + REMOTE_USER
      + REMOTE_IDENT
      + REQUEST_METHOD
      + SCRIPT_FILENAME
      + PATH_INFO
      + QUERY_STRING
      + AUTH_TYPE
      +
      server internals: date and time: specials:
      + DOCUMENT_ROOT
      + SERVER_ADMIN
      + SERVER_NAME
      + SERVER_ADDR
      + SERVER_PORT
      + SERVER_PROTOCOL
      + SERVER_SOFTWARE
      +
      + TIME_YEAR
      + TIME_MON
      + TIME_DAY
      + TIME_HOUR
      + TIME_MIN
      + TIME_SEC
      + TIME_WDAY
      + TIME
      +
      + API_VERSION
      + THE_REQUEST
      + REQUEST_URI
      + REQUEST_FILENAME
      + IS_SUBREQ
      + HTTPS
      +
      + + +

      These variables all + correspond to the similarly named HTTP + MIME-headers, C variables of the Apache server or + struct tm fields of the Unix system. + Most are documented elsewhere in the Manual or in + the CGI specification. Those that are special to + mod_rewrite include:

      + +
      +
      IS_SUBREQ
      + +
      Will contain the text "true" if the request + currently being processed is a sub-request, + "false" otherwise. Sub-requests may be generated + by modules that need to resolve additional files + or URIs in order to complete their tasks.
      + +
      API_VERSION
      + +
      This is the version of the Apache module API + (the internal interface between server and + module) in the current httpd build, as defined in + include/ap_mmn.h. The module API version + corresponds to the version of Apache in use (in + the release version of Apache 1.3.14, for + instance, it is 19990320:10), but is mainly of + interest to module authors.
      + +
      THE_REQUEST
      + +
      The full HTTP request line sent by the + browser to the server (e.g., "GET + /index.html HTTP/1.1"). This does not + include any additional headers sent by the + browser.
      + +
      REQUEST_URI
      + +
      The resource requested in the HTTP request + line. (In the example above, this would be + "/index.html".)
      + +
      REQUEST_FILENAME
      + +
      The full local filesystem path to the file or + script matching the request.
      + +
      HTTPS
      + +
      Will contain the text "on" if the connection is + using SSL/TLS, or "off" otherwise. (This variable + can be safely used regardless of whether + mod_ssl is loaded).
      + +
      +
      +
    • +
    + +

    Special Notes:

    + +
      +
    1. The variables SCRIPT_FILENAME and REQUEST_FILENAME + contain the same value, i.e., the value of the + filename field of the internal + request_rec structure of the Apache server. + The first name is just the commonly known CGI variable name + while the second is the consistent counterpart to + REQUEST_URI (which contains the value of the + uri field of request_rec).
    2. + +
    3. There is the special format: + %{ENV:variable} where variable can be + any environment variable. This is looked-up via internal + Apache structures and (if not found there) via + getenv() from the Apache server process.
    4. + +
    5. There is the special format: + %{SSL:variable} where variable is the + name of an SSL environment + variable; this can be used whether or not + mod_ssl is loaded, but will always expand to + the empty string if it is not. Example: + %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to + 128.
    6. + +
    7. There is the special format: + %{HTTP:header} where header can be + any HTTP MIME-header name. This is looked-up from the HTTP + request. Example: %{HTTP:Proxy-Connection} is + the value of the HTTP header + ``Proxy-Connection:''.
    8. + +
    9. There is the special format + %{LA-U:variable} for look-aheads which perform + an internal (URL-based) sub-request to determine the final + value of variable. Use this when you want to use a + variable for rewriting which is actually set later in an + API phase and thus is not available at the current stage. + For instance when you want to rewrite according to the + REMOTE_USER variable from within the + per-server context (httpd.conf file) you have + to use %{LA-U:REMOTE_USER} because this + variable is set by the authorization phases which come + after the URL translation phase where mod_rewrite + operates. On the other hand, because mod_rewrite implements + its per-directory context (.htaccess file) via + the Fixup phase of the API and because the authorization + phases come before this phase, you just can use + %{REMOTE_USER} there.
    10. + +
    11. There is the special format: + %{LA-F:variable} which performs an internal + (filename-based) sub-request to determine the final value + of variable. Most of the time this is the same as + LA-U above.
    12. +
    + +

    CondPattern is the condition pattern, + i.e., a regular expression which is applied to the + current instance of the TestString, i.e., + TestString is evaluated and then matched against + CondPattern.

    + +

    Remember: CondPattern is a + perl compatible regular expression with some + additions:

    + +
      +
    1. You can prefix the pattern string with a + '!' character (exclamation mark) to specify a + non-matching pattern.
    2. + +
    3. + There are some special variants of CondPatterns. + Instead of real regular expression strings you can also + use one of the following: + +
        +
      • '<CondPattern' (is lexically + lower)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically lower than + CondPattern.
      • + +
      • '>CondPattern' (is lexically + greater)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically greater than + CondPattern.
      • + +
      • '=CondPattern' (is lexically + equal)
        + Treats the CondPattern as a plain string and + compares it lexically to TestString. True if + TestString is lexically equal to + CondPattern, i.e the two strings are exactly + equal (character by character). If CondPattern + is just "" (two quotation marks) this + compares TestString to the empty string.
      • + +
      • '-d' (is + directory)
        + Treats the TestString as a pathname and tests + if it exists and is a directory.
      • + +
      • '-f' (is regular + file)
        + Treats the TestString as a pathname and tests + if it exists and is a regular file.
      • + +
      • '-s' (is regular file with + size)
        + Treats the TestString as a pathname and tests + if it exists and is a regular file with size greater + than zero.
      • + +
      • '-l' (is symbolic + link)
        + Treats the TestString as a pathname and tests + if it exists and is a symbolic link.
      • + +
      • '-x' (has executable + permissions)
        + Treats the TestString as a pathname and tests + if it exists and has execution permissions. These permissions + are determined depending on the underlying OS.
      • + +
      • '-F' (is existing file via + subrequest)
        + Checks if TestString is a valid file and + accessible via all the server's currently-configured + access controls for that path. This uses an internal + subrequest to determine the check, so use it with care + because it decreases your servers performance!
      • + +
      • '-U' (is existing URL via + subrequest)
        + Checks if TestString is a valid URL and + accessible via all the server's currently-configured + access controls for that path. This uses an internal + subrequest to determine the check, so use it with care + because it decreases your server's performance!
      • +
      + +Notice + All of these tests can + also be prefixed by an exclamation mark ('!') to + negate their meaning. + +
    4. +
    + +

    Additionally you can set special flags for + CondPattern by appending

    + +

    + [flags] +

    + +

    as the third argument to the RewriteCond + directive. Flags is a comma-separated list of the + following flags:

    + +
      +
    • 'nocase|NC' + (no case)
      + This makes the test case-insensitive, i.e., there + is no difference between 'A-Z' and 'a-z' both in the + expanded TestString and the CondPattern. + This flag is effective only for comparisons between + TestString and CondPattern. It has no + effect on filesystem and subrequest checks.
    • + +
    • + 'ornext|OR' + (or next condition)
      + Use this to combine rule conditions with a local OR + instead of the implicit AND. Typical example: + + +
      +RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host2.*  [OR]
      +RewriteCond %{REMOTE_HOST}  ^host3.*
      +RewriteRule ...some special stuff for any of these hosts...
      +
      +
      + + Without this flag you would have to write the cond/rule + three times. +
    • +
    + +

    Example:

    + +

    To rewrite the Homepage of a site according to the + ``User-Agent:'' header of the request, you can + use the following:

    + + +
    +RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
    +RewriteRule  ^/$                 /homepage.max.html  [L]
    +
    +RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
    +RewriteRule  ^/$                 /homepage.min.html  [L]
    +
    +RewriteRule  ^/$                 /homepage.std.html  [L]
    +
    +
    + +

    Interpretation: If you use Netscape Navigator as your + browser (which identifies itself as 'Mozilla'), then you + get the max homepage, which includes Frames, etc. + If you use the Lynx browser (which is Terminal-based), then + you get the min homepage, which contains no images, no + tables, etc. If you use any other browser you get + the standard homepage.

    + +
    + +
    + + +RewriteRule +Defines rules for the rewriting engine +RewriteRule + Pattern Substitution +server configvirtual host +directory.htaccess +FileInfo +The cookie-flag is available in Apache 2.0.40 and later. + + +

    The RewriteRule directive is the real + rewriting workhorse. The directive can occur more than once. + Each directive then defines one single rewriting rule. The + definition order of these rules is + important, because this order is used when + applying the rules at run-time.

    + +

    Pattern is + a perl compatible regular + expression which gets applied to the current URL. Here + ``current'' means the value of the URL when this rule gets + applied. This may not be the originally requested URL, + because any number of rules may already have matched and made + alterations to it.

    + +

    Some hints about the syntax of regular expressions:

    + +
    +Text:
    +  .           Any single character
    +  [chars]     Character class: One  of chars
    +  [^chars]    Character class: None of chars
    +  text1|text2 Alternative: text1 or text2
    +
    +Quantifiers:
    +  ?           0 or 1 of the preceding text
    +  *           0 or N of the preceding text (N > 0)
    +  +           1 or N of the preceding text (N > 1)
    +
    +Grouping:
    +  (text)      Grouping of text
    +              (either to set the borders of an alternative or
    +              for making backreferences where the Nth group can 
    +              be used on the RHS of a RewriteRule with $N)
    +
    +Anchors:
    +  ^           Start of line anchor
    +  $           End   of line anchor
    +
    +Escaping:
    +  \char       escape that particular char
    +              (for instance to specify the chars ".[]()" etc.)
    +
    + +

    For more information about regular expressions have a look at the + perl regular expression manpage ("perldoc + perlre"). If you are interested in more detailed + information about regular expressions and their variants + (POSIX regex etc.) have a look at the + following dedicated book on this topic:

    + +

    + Mastering Regular Expressions, 2nd Edition
    + Jeffrey E.F. Friedl
    + O'Reilly & Associates, Inc. 2002
    + ISBN 0-596-00289-0
    +

    + +

    Additionally in mod_rewrite the NOT character + ('!') is a possible pattern prefix. This gives + you the ability to negate a pattern; to say, for instance: + ``if the current URL does NOT match this + pattern''. This can be used for exceptional cases, where + it is easier to match the negative pattern, or as a last + default rule.

    + +Notice +When using the NOT character + to negate a pattern you cannot have grouped wildcard + parts in the pattern. This is impossible because when the + pattern does NOT match, there are no contents for the + groups. In consequence, if negated patterns are used, you + cannot use $N in the substitution + string! + + +

    Substitution of a + rewriting rule is the string which is substituted for (or + replaces) the original URL for which Pattern + matched. Beside plain text you can use

    + +
      +
    1. back-references $N to the RewriteRule + pattern
    2. + +
    3. back-references %N to the last matched + RewriteCond pattern
    4. + +
    5. server-variables as in rule condition test-strings + (%{VARNAME})
    6. + +
    7. mapping-function calls + (${mapname:key|default})
    8. +
    +

    Back-references are $N + (N=0..9) identifiers which will be replaced + by the contents of the Nth group of the + matched Pattern. The server-variables are the same + as for the TestString of a RewriteCond + directive. The mapping-functions come from the + RewriteMap directive and are explained there. + These three types of variables are expanded in the order of + the above list.

    + +

    As already mentioned above, all the rewriting rules are + applied to the Substitution (in the order of + definition in the config file). The URL is completely + replaced by the Substitution and the + rewriting process goes on until there are no more rules + unless explicitly terminated by a + L flag - see below.

    + +

    There is a special substitution string named + '-' which means: NO + substitution! Sounds silly? No, it is useful to + provide rewriting rules which only match + some URLs but do no substitution, e.g., in + conjunction with the C (chain) flag to be + able to have more than one pattern to be applied before a + substitution occurs.

    + +Query String +

    The Pattern will not match against the query string. + Instead, you must use a RewriteCond with the + %{QUERY_STRING} variable. You can, however, create + URLs in the substitution string containing a query string + part. Just use a question mark inside the substitution string to + indicate that the following stuff should be re-injected into the + query string. When you want to erase an existing query string, + end the substitution string with just the question mark. To + combine a new query string with an old one, use the + [QSA] flag (see below).

    +
    + +Substitution of Absolute URLs +

    There is a special feature: + When you prefix a substitution field with + http://thishost[:thisport] + then mod_rewrite automatically strips it + out. This auto-reduction on implicit external redirect + URLs is a useful and important feature when used in + combination with a mapping-function which generates the + hostname part. Have a look at the first example in the + example section below to understand this.

    + +

    Remember: An unconditional external + redirect to your own server will not work with the prefix + http://thishost because of this feature. To + achieve such a self-redirect, you have to use the + R-flag (see below).

    +
    + +

    Additionally you can set special flags for Substitution by + appending

    + +

    + [flags] +

    +

    + as the third argument to the RewriteRule + directive. Flags is a comma-separated list of the + following flags:

    + +
      +
    • 'chain|C' + (chained with next rule)
      + This flag chains the current rule with the next rule + (which itself can be chained with the following rule, + etc.). This has the following effect: if a rule + matches, then processing continues as usual, i.e., + the flag has no effect. If the rule does + not match, then all following chained + rules are skipped. For instance, use it to remove the + ``.www'' part inside a per-directory rule set + when you let an external redirect happen (where the + ``.www'' part should not to occur!).
    • + +
    • + 'cookie|CO=NAME:VAL:domain[:lifetime[:path]]' + (set cookie)
      + This sets a cookie on the client's browser. The cookie's name + is specified by NAME and the value is + VAL. The domain field is the domain of the + cookie, such as '.apache.org',the optional lifetime + is the lifetime of the cookie in minutes, and the optional + path is the path of the cookie
    • + +
    • + 'env|E=VAR:VAL' + (set environment variable)
      + This forces an environment variable named VAR to + be set to the value VAL, where VAL can + contain regexp backreferences $N and + %N which will be expanded. You can use this + flag more than once to set more than one variable. The + variables can be later dereferenced in many situations, but + usually from within XSSI (via <!--#echo + var="VAR"-->) or CGI (e.g. + $ENV{'VAR'}). Additionally you can dereference + it in a following RewriteCond pattern via + %{ENV:VAR}. Use this to strip but remember + information from URLs.
    • + +
    • 'forbidden|F' (force URL + to be forbidden)
      + This forces the current URL to be forbidden, + i.e., it immediately sends back a HTTP response of + 403 (FORBIDDEN). Use this flag in conjunction with + appropriate RewriteConds to conditionally block some + URLs.
    • + +
    • 'gone|G' (force URL to be + gone)
      + This forces the current URL to be gone, i.e., it + immediately sends back a HTTP response of 410 (GONE). Use + this flag to mark pages which no longer exist as gone.
    • + +
    • + 'handler|H=Content-handler' + (force Content handler)
      + Force the Content-handler of the target file to be + Content-handler. For instance, this can be used to + simulate the mod_alias directive + ScriptAlias which internally forces all files + inside the mapped directory to have a handler of + ``cgi-script''.
    • + +
    • 'last|L' + (last rule)
      + Stop the rewriting process here and don't apply any more + rewriting rules. This corresponds to the Perl + last command or the break command + from the C language. Use this flag to prevent the currently + rewritten URL from being rewritten further by following + rules. For example, use it to rewrite the root-path URL + ('/') to a real one, e.g., + '/e/www/'.
    • + +
    • 'next|N' + (next round)
      + Re-run the rewriting process (starting again with the + first rewriting rule). Here the URL to match is again not + the original URL but the URL from the last rewriting rule. + This corresponds to the Perl next command or + the continue command from the C language. Use + this flag to restart the rewriting process, i.e., + to immediately go to the top of the loop.
      + But be careful not to create an infinite + loop!
    • + +
    • 'nocase|NC' + (no case)
      + This makes the Pattern case-insensitive, + i.e., there is no difference between 'A-Z' and + 'a-z' when Pattern is matched against the current + URL.
    • + +
    • + 'noescape|NE' + (no URI escaping of + output)
      + This flag keeps mod_rewrite from applying the usual URI + escaping rules to the result of a rewrite. Ordinarily, + special characters (such as '%', '$', ';', and so on) + will be escaped into their hexcode equivalents ('%25', + '%24', and '%3B', respectively); this flag prevents this + from being done. This allows percent symbols to appear in + the output, as in + + RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] + + + which would turn '/foo/zed' into a safe + request for '/bar?arg=P1=zed'. +
    • + +
    • + 'nosubreq|NS' (used only if + no internal + sub-request)
      + This flag forces the rewriting engine to skip a + rewriting rule if the current request is an internal + sub-request. For instance, sub-requests occur internally + in Apache when mod_include tries to find out + information about possible directory default files + (index.xxx). On sub-requests it is not + always useful and even sometimes causes a failure to if + the complete set of rules are applied. Use this flag to + exclude some rules.
      + + +

      Use the following rule for your decision: whenever you + prefix some URLs with CGI-scripts to force them to be + processed by the CGI-script, the chance is high that you + will run into problems (or even overhead) on + sub-requests. In these cases, use this flag.

      +
    • + +
    • + 'proxy|P' (force + proxy)
      + This flag forces the substitution part to be internally + forced as a proxy request and immediately (i.e., + rewriting rule processing stops here) put through the proxy module. You have to make + sure that the substitution string is a valid URI + (e.g., typically starting with + http://hostname) which can be + handled by the Apache proxy module. If not you get an + error from the proxy module. Use this flag to achieve a + more powerful implementation of the ProxyPass directive, + to map some remote stuff into the namespace of the local + server. + +

      Notice: To use this functionality make sure you have + the proxy module compiled into your Apache server + program. If you don't know please check whether + mod_proxy.c is part of the ``httpd + -l'' output. If yes, this functionality is + available to mod_rewrite. If not, then you first have to + rebuild the httpd program with mod_proxy + enabled.

      +
    • + +
    • + 'passthrough|PT' + (pass through to next + handler)
      + This flag forces the rewriting engine to set the + uri field of the internal + request_rec structure to the value of the + filename field. This flag is just a hack to + be able to post-process the output of + RewriteRule directives by + Alias, ScriptAlias, + Redirect, etc. directives from + other URI-to-filename translators. A trivial example to + show the semantics: If you want to rewrite + /abc to /def via the rewriting + engine of mod_rewrite and then + /def to /ghi with + mod_alias: + + RewriteRule ^/abc(.*) /def$1 [PT]
      + Alias /def /ghi +
      + If you omit the PT flag then + mod_rewrite will do its job fine, + i.e., it rewrites uri=/abc/... to + filename=/def/... as a full API-compliant + URI-to-filename translator should do. Then + mod_alias comes and tries to do a + URI-to-filename transition which will not work. + +

      Note: You have to use this flag if you want to + intermix directives of different modules which contain + URL-to-filename translators. The typical example + is the use of mod_alias and + mod_rewrite..

      +
    • + +
    • 'qsappend|QSA' + (query string + append)
      + This flag forces the rewriting engine to append a query + string part in the substitution string to the existing one + instead of replacing it. Use this when you want to add more + data to the query string via a rewrite rule.
    • + +
    • 'redirect|R + [=code]' (force redirect)
      + Prefix Substitution with + http://thishost[:thisport]/ (which makes the + new URL a URI) to force a external redirection. If no + code is given a HTTP response of 302 (MOVED + TEMPORARILY) is used. If you want to use other response + codes in the range 300-400 just specify them as a number + or use one of the following symbolic names: + temp (default), permanent, + seeother. Use it for rules which should + canonicalize the URL and give it back to the client, + e.g., translate ``/~'' into + ``/u/'' or always append a slash to + /u/user, etc.
      + + +

      Note: When you use this flag, make + sure that the substitution field is a valid URL! If not, + you are redirecting to an invalid location! And remember + that this flag itself only prefixes the URL with + http://thishost[:thisport]/, rewriting + continues. Usually you also want to stop and do the + redirection immediately. To stop the rewriting you also + have to provide the 'L' flag.

      +
    • + +
    • 'skip|S=num' + (skip next rule(s))
      + This flag forces the rewriting engine to skip the next + num rules in sequence when the current rule + matches. Use this to make pseudo if-then-else constructs: + The last rule of the then-clause becomes + skip=N where N is the number of rules in the + else-clause. (This is not the same as the + 'chain|C' flag!)
    • + +
    • + 'type|T=MIME-type' + (force MIME type)
      + Force the MIME-type of the target file to be + MIME-type. For instance, this can be used to + setup the content-type based on some conditions. + For example, the following snippet allows .php files to + be displayed by mod_php if they are called with + the .phps extension: + + RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source] + +
    • + + +
    + +Note Never forget that Pattern is +applied to a complete URL in per-server configuration +files. But in per-directory configuration files, the +per-directory prefix (which always is the same for a specific +directory!) is automatically removed for the pattern matching +and automatically added after the substitution has been +done. This feature is essential for many sorts of rewriting, +because without this prefix stripping you have to match the parent +directory which is not always possible. + +

    There is one exception: If a substitution string + starts with ``http://'' then the directory + prefix will not be added and an + external redirect or proxy throughput (if flag + P is used!) is forced!

    +
    + +Note + To enable the rewriting engine + for per-directory configuration files you need to set + ``RewriteEngine On'' in these files + and ``Options + FollowSymLinks'' must be enabled. If your + administrator has disabled override of + FollowSymLinks for a user's directory, then + you cannot use the rewriting engine. This restriction is + needed for security reasons. + + +

    Here are all possible substitution combinations and their + meanings:

    + +

    Inside per-server configuration + (httpd.conf)
    + for request ``GET + /somepath/pathinfo'':

    +

    + +
    +Given Rule                                      Resulting Substitution
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) otherpath$1                      not supported, because invalid!
    +
    +^/somepath(.*) otherpath$1  [R]                 not supported, because invalid!
    +
    +^/somepath(.*) otherpath$1  [P]                 not supported, because invalid!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) /otherpath$1                     /otherpath/pathinfo
    +
    +^/somepath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) /otherpath$1 [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) http://thishost/otherpath$1      /otherpath/pathinfo
    +
    +^/somepath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) http://thishost/otherpath$1 [P]  not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^/somepath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +                                                (the [R] flag is redundant)
    +
    +^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    +                                                via internal proxy
    +
    + +

    Inside per-directory configuration for + /somepath
    + (i.e., file .htaccess in dir + /physical/path/to/somepath containing + RewriteBase /somepath)
    + for request ``GET + /somepath/localpath/pathinfo'':

    +

    + +
    +Given Rule                                      Resulting Substitution
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) otherpath$1                      /somepath/otherpath/pathinfo
    +
    +^localpath(.*) otherpath$1  [R]                 http://thishost/somepath/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) otherpath$1  [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) /otherpath$1                     /otherpath/pathinfo
    +
    +^localpath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) /otherpath$1 [P]                 not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) http://thishost/otherpath$1      /otherpath/pathinfo
    +
    +^localpath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) http://thishost/otherpath$1 [P]  not supported, because silly!
    +----------------------------------------------  ----------------------------------
    +^localpath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +
    +^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
    +                                                via external redirection
    +                                                (the [R] flag is redundant)
    +
    +^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
    +                                                via internal proxy
    +
    + +

    Example:

    + +

    We want to rewrite URLs of the form

    + +

    + / Language /~ + Realname /.../ File +

    + +

    into

    + +

    + /u/ Username /.../ + File . Language +

    + +

    We take the rewrite mapfile from above and save it under + /path/to/file/map.txt. Then we only have to + add the following lines to the Apache server configuration + file:

    + + +
    +RewriteLog   /path/to/file/rewrite.log
    +RewriteMap   real-to-user               txt:/path/to/file/map.txt
    +RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1
    +
    +
    +
    +
    +
    diff --git a/trunk/docs/manual/mod/mod_rewrite.xml.meta b/trunk/docs/manual/mod/mod_rewrite.xml.meta new file mode 100644 index 0000000000..bffdea71d6 --- /dev/null +++ b/trunk/docs/manual/mod/mod_rewrite.xml.meta @@ -0,0 +1,11 @@ + + + + mod_rewrite + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_setenvif.html b/trunk/docs/manual/mod/mod_setenvif.html new file mode 100644 index 0000000000..0a1cf29b65 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.html @@ -0,0 +1,11 @@ +URI: mod_setenvif.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_setenvif.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_setenvif.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_setenvif.html.en b/trunk/docs/manual/mod/mod_setenvif.html.en new file mode 100644 index 0000000000..05bda3b1f2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.html.en @@ -0,0 +1,286 @@ + + + +mod_setenvif - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_setenvif

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Allows the setting of environment variables based +on characteristics of the request
    Status:Base
    Module Identifier:setenvif_module
    Source File:mod_setenvif.c
    +

    Summary

    + + +

    The mod_setenvif module allows you to set + environment variables according to whether different aspects of + the request match regular expressions you specify. These + environment variables can be used by other parts of the server + to make decisions about actions to be taken.

    + +

    The directives are considered in the order they appear in + the configuration files. So more complex sequences can be used, + such as this example, which sets netscape if the + browser is mozilla but not MSIE.

    + +

    + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +

    +
    + + +
    top
    +

    BrowserMatch Directive

    + + + + + + + +
    Description:Sets environment variables conditional on HTTP User-Agent +
    Syntax:BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_setenvif
    +

    The BrowserMatch is a special cases of the + SetEnvIf directive that + sets environment variables conditional on the + User-Agent HTTP request header. The following two + lines have the same effect:

    +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +

    Some additional examples:

    +

    + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +

    + +
    +
    top
    +

    BrowserMatchNoCase Directive

    + + + + + + + + +
    Description:Sets environment variables conditional on User-Agent without +respect to case
    Syntax:BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_setenvif
    Compatibility:Apache 1.2 and + above (in Apache 1.2 this directive was found in the + now-obsolete mod_browser module)
    + +

    The BrowserMatchNoCase directive is + semantically identical to the BrowserMatch directive. + However, it provides for case-insensitive matching. For + example:

    +

    + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +

    + +

    The BrowserMatch and + BrowserMatchNoCase directives are special cases of + the SetEnvIf and SetEnvIfNoCase + directives. The following two lines have the same effect:

    +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +
    +
    top
    +

    SetEnvIf Directive

    + + + + + + + +
    Description:Sets environment variables based on attributes of the request +
    Syntax:SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_setenvif
    +

    The SetEnvIf directive defines + environment variables based on attributes of the request. The + attribute specified in the first argument can be one of three + things:

    + +
      +
    1. An HTTP request header field (see RFC2616 + for more information about these); for example: Host, + User-Agent, Referer, and + Accept-Language. A regular expression may be + used to specify a set of request headers.
    2. + +
    3. One of the following aspects of the request: +
        +
      • Remote_Host - the hostname (if available) of + the client making the request
      • + +
      • Remote_Addr - the IP address of the client + making the request
      • + +
      • Server_Addr - the IP address of the server + on which the request was received (only with versions later + than 2.0.43)
      • + +
      • Request_Method - the name of the method + being used (GET, POST, et + cetera)
      • + +
      • Request_Protocol - the name and version of + the protocol with which the request was made (e.g., + "HTTP/0.9", "HTTP/1.1", etc.)
      • + +
      • Request_URI - the resource requested on the HTTP + request line -- generally the portion of the URL + following the scheme and host portion without the query string
      • +
      +
    4. + +
    5. The name of an environment variable in the list of those +associated with the request. This allows +SetEnvIf directives to test against the result +of prior matches. Only those environment variables defined by earlier +SetEnvIf[NoCase] directives are available for testing in +this manner. 'Earlier' means that they were defined at a broader scope +(such as server-wide) or previously in the current directive's scope. +Environment variables will be considered only if there was no match +among request characteristics and a regular expression was not +used for the attribute.
    6. +
    + +

    The second argument (regex) is a Perl compatible regular expression. +This is similar to a POSIX.2 egrep-style regular expression. +If the regex matches against the attribute, +then the remainder of the arguments are evaluated.

    + +

    The rest of the arguments give the names of variables to set, and +optionally values to which they should be set. These take the form +of

    + +
      +
    1. varname, or
    2. + +
    3. !varname, or
    4. + +
    5. varname=value
    6. +
    + +

    In the first form, the value will be set to "1". The second + will remove the given variable if already defined, and the + third will set the variable to the literal value given by + value. Since version 2.0.51 Apache will + recognize occurrences of $1..$9 within + value and replace them by parenthesized subexpressions + of regex.

    + +

    Example:

    + + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +

    + +

    The first three will set the environment variable + object_is_image if the request was for an image + file, and the fourth sets intra_site_referral if + the referring page was somewhere on the + www.mydomain.com Web site.

    + +

    The last example will set environment variable + HAVE_TS if the request contains any headers that + begin with "TS" whose values begins with any character in the + set [a-z].

    + +

    See also

    + +
    +
    top
    +

    SetEnvIfNoCase Directive

    + + + + + + + + +
    Description:Sets environment variables based on attributes of the request +without respect to case
    Syntax:SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Base
    Module:mod_setenvif
    Compatibility:Apache 1.3 and above
    + +

    The SetEnvIfNoCase is semantically identical to + the SetEnvIf directive, + and differs only in that the regular expression matching is + performed in a case-insensitive manner. For example:

    +

    + SetEnvIfNoCase Host Apache\.Org site=apache +

    + +

    This will cause the site environment variable + to be set to "apache" if the HTTP request header + field Host: was included and contained + Apache.Org, apache.org, or any other + combination.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_setenvif.html.ja.euc-jp b/trunk/docs/manual/mod/mod_setenvif.html.ja.euc-jp new file mode 100644 index 0000000000..8725b3ba85 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.html.ja.euc-jp @@ -0,0 +1,280 @@ + + + +mod_setenvif - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_setenvif

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤Ë´ð¤Å¤¤¤¿´Ä¶­ÊÑ¿ô¤ÎÀßÄê¤ò²Äǽ¤Ë¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:setenvif_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_setenvif.c
    +

    ³µÍ×

    + + +

    mod_setenvif + ¥â¥¸¥å¡¼¥ë¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤Î¤¢¤ë¦Ì̤¬»ØÄꤵ¤ì¤¿Àµµ¬É½¸½ + ¤Ë¹ç¤¦¤«¤É¤¦¤«¤Ë¤è¤Ã¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£ + ¤³¤ì¤é¤Î´Ä¶­ÊÑ¿ô¤ò»ÈÍѤ·¤Æ¡¢¥µ¡¼¥Ð¤Î¾¤ÎÉôʬ¤¬¤É¤Î¤è¤¦¤ÊÆ°ºî¤ò¤¹¤ë¤«¤ò + ·èÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤¬Ä󶡤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤ë½çÈÖ¤ËŬÍѤµ¤ì¤Þ¤¹¡£ + ¤½¤ì¤ò»È¤Ã¤Æ¡¢¼¡¤ÎÎã¤Î¤è¤¦¤Ë¤è¤êÊ£»¨¤ÊÀßÄê¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥Ö¥é¥¦¥¶¤¬ mozilla ¤Ç¤Ï¤¢¤ë¤±¤ì¤É¡¢MSIE ¤Ç¤Ï¤Ê¤¤¤È¤­¤Ë + netscape ¤òÀßÄꤷ¤Þ¤¹¡£

    +

    + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    BrowserMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:HTTP User-Agent ¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë +
    ¹½Ê¸:BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_setenvif
    +

    BrowserMatch ¤Ï + SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÆÃÎã¤Ç¡¢User-Agent HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ë´ð¤Å¤¤¤Æ + ´Ä¶­ÊÑ¿ô¤òÀßÄꤷ¤Þ¤¹¡£°Ê²¼¤Î 2 ¹Ô¤Î¸ú²Ì¤ÏƱ¤¸¤Ë¤Ê¤ê¤Þ¤¹:

    + +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +

    ¤½¤Î¾¤ÎÎã:

    +

    + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +

    + +
    +
    top
    +

    BrowserMatchNoCase ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:HTTP User-Agent ¤Ë´ð¤Å¤¤¤ÆÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë +´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    ¹½Ê¸:BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_setenvif
    ¸ß´¹À­:Apache 1.2 °Ê¹ß + (Apache 1.2 ¤Ç¤Ï¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤â¤¦ÍѤ¤¤é¤ì¤Æ¤¤¤Ê¤¤ + mod_browser ¥â¥¸¥å¡¼¥ë¤Ë¤¢¤ê¤Þ¤·¤¿)
    + +

    BrowserMatchNoCase ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + °Ọ̃Ū¤Ë¤Ï BrowserMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Ʊ¤¸¤Ç¤¹¡£¤¿¤À¤·¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤ + ¥Þ¥Ã¥Á¥ó¥°¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£Î㤨¤Ð:

    + +

    + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +

    + +

    BrowserMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + BrowserMatchNoCase ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + SetEnvIfNoCase ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÆÃÎã¤Ç¤¹¡£°Ê²¼¤Î 2 ¹Ô¤Î¸ú²Ì¤ÏƱ¤¸¤Ç¤¹:

    + +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +
    +
    top
    +

    SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Î°À­¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë +
    ¹½Ê¸:SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_setenvif
    +

    SetEnvIf + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤Î°À­¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÄêµÁ¤·¤Þ¤¹¡£ + ºÇ½é¤Î°ú¿ô¤Ç»ØÄê¤Ç¤­¤ë attribute ¤Ï°Ê²¼¤Î»°¤Ä¤Î¤É¤ì¤«¤Ç¤¹:

    + +
      +
    1. HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É (¾Ü¤·¤¤¾ðÊó¤Ï RFC 2616 ¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤)¡£Î㤨¤Ð¡¢Host, + User-Agent, Referer, + Accept-Language ¤Ç¤¹¡£¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Î½¸¹ç¤ò¸½¤¹¤¿¤á¤Ë + Àµµ¬É½¸½¤ò»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
    2. + +
    3. °Ê²¼¤Î¥ê¥¯¥¨¥¹¥È¤Î°ìÉôʬ¤Î¤É¤ì¤«: + +
        +
      • Remote_Host - + ¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤ë¥¯¥é¥¤¥¢¥ó¥È¤Î¥Û¥¹¥È̾ (¤â¤·¤¢¤ì¤Ð)
      • + +
      • Remote_Addr - + ¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤ë¥¯¥é¥¤¥¢¥ó¥È¤Î IP ¥¢¥É¥ì¥¹
      • + +
      • Server_Addr - + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤Ã¤¿¥µ¡¼¥Ð¤Î IP ¥¢¥É¥ì¥¹ + (2.0.43 °Ê¹ß¤Î¤ß)
      • + +
      • Request_Method - + »ÈÍѤµ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É̾ (GET, POST + ¤Ê¤É)
      • + +
      • Request_Protocol - + ¥ê¥¯¥¨¥¹¥È¤¬¹Ô¤Ê¤ï¤ì¤¿¥×¥í¥È¥³¥ë¤Î̾Á°¤È¥Ð¡¼¥¸¥ç¥ó + (Î㤨¤Ð¡¢"HTTP/0.9", "HTTP/1.1" ¤Ê¤É¡£)
      • + +
      • Request_URI - + URL ¤Î¥¹¥­¡¼¥à¤È¥Û¥¹¥È¤Î¸å¤ÎÉôʬ
      • +
      +
    4. + +
    5. ¥ê¥¯¥¨¥¹¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë´Ä¶­ÊÑ¿ô¤Î¥ê¥¹¥È¡£¤³¤ì¤Ë¤è¤ê +SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬°ÊÁ°¤Î¥Þ¥Ã¥Á¤Î·ë²Ì¤ò +»È¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ÎÊýË¡¤Î¥Æ¥¹¥È¤Ç¤ÏÁ°¤ÎÉôʬ¤Ë¤¢¤ë +SetEnvIf[NoCase] ¤Î·ë²Ì¤Î¤ß¤ò»ÈÍѲÄǽ¤Ç¤¹¡£¡ÖÁ°¡×¤È¤Ï¡¢ +¤è¤ê¹­¤¤ÈϰϤËÂФ·¤ÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë (¥µ¡¼¥ÐÁ´ÂΤΤ褦¤Ë) ¤«¡¢¸½ºß¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î +ÈϰϤǤè¤êÁ°¤ÎÉôʬ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤«¡¢¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ +´Ä¶­ÊÑ¿ô¤Ç¤¢¤ë²ÄǽÀ­¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ÎÆÃÀ­¤ËÂФ¹¤ë¥Þ¥Ã¥Á¤¬Â¸ºß¤»¤º¡¢ +attribute ¤ËÀµµ¬É½¸½¤¬»È¤ï¤ì¤Ê¤«¤Ã¤¿¤È¤­¤Ë¤Î¤ß¹Í褵¤ì¤Þ¤¹¡£
    6. +
    + +

    Æó¤ÄÌܤΰú¿ô (regex) ¤Ï Perl ¸ß´¹¤ÎÀµµ¬É½¸½¤Ç¤¹¡£ +¤³¤ì¤Ï POSIX.2 ¤Î egrep ·Á¼°¤ÎÀµµ¬É½¸½¤È»÷¤Æ¤¤¤Þ¤¹¡£regex ¤¬ +attribute ¤Ë¥Þ¥Ã¥Á¤¹¤ë¾ì¹ç¤Ï¡¢»Ä¤ê¤Î°ú¿ô¤¬É¾²Á¤µ¤ì¤Þ¤¹¡£

    + +

    »Ä¤ê¤Î°ú¿ô¤ÏÀßÄꤹ¤ëÊÑ¿ô¤Î̾Á°¤Ç¡¢ÀßÄꤵ¤ì¤ëÃͤò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ +¤³¤ì¤Ï¡¢

    + +
      +
    1. varname
    2. + +
    3. !varname
    4. + +
    5. varname=value
    6. +
    + +

    ¤Î¤É¤ì¤«¤Î·Á¼°¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ºÇ½é¤Î·Á¼°¤Ç¤Ï¡¢ÃÍ¤Ï "1" ¤ËÀßÄꤵ¤ì¤Þ¤¹¡£ + Æó¤ÄÌܤϤ⤷Ãͤ¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ì¤Ð¤½¤ì¤ò¼è¤ê½ü¤­¤Þ¤¹¡£ + »°¤ÄÌܤÏÊÑ¿ô¤ò value ¤ÎÍ¿¤¨¤é¤ì¤¿ÃͤËÀßÄꤷ¤Þ¤¹¡£ + 2.0.51 °Ê¹ß¤Ç¤Ï¡¢regex Æâ¤Ë $1..$9 + ¤¬Â¸ºß¤¹¤ì¤Ð¤½¤ì¤òǧ¼±¤·¡¢regex ¤ÎÂбþ¤¹¤ë´Ý³ç¸Ì¤Ç°Ï¤Þ¤ì¤¿Éôʬ¤Ç + ÃÖ´¹¤·¤Þ¤¹¡£

    + +

    Îã:

    + + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +

    + +

    ½é¤á¤Î»°¤Ä¤Ï¥ê¥¯¥¨¥¹¥È¤¬²èÁü¤Ç¤¢¤ë¤È¤­¤Ë´Ä¶­ÊÑ¿ô + object_is_image ¤òÀßÄꤷ¤Þ¤¹¡£»Í¤ÄÌÜ¤Ï + »²¾È¸µ¤Î¥Ú¡¼¥¸¤¬¥¦¥§¥Ö¥µ¥¤¥È www.mydomain.com ¤Ë¤¢¤ë¤È¤­¤Ë + intra_site_referral ¤òÀßÄꤷ¤Þ¤¹¡£

    + +

    ºÇ¸å¤ÎÎã¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤Ë "TS" ¤Ç»Ï¤Þ¤ê¡¢Ãͤ¬½¸¹ç [a-z] ¤Î¤É¤ì¤«¤Ç + »Ï¤Þ¤ë¥Ø¥Ã¥À¤¬¤¢¤ë¤È¤­¤Ë HAVE_TS ¤òÀßÄꤷ¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    SetEnvIfNoCase ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Î°À­¤Ë´ð¤Å¤¤¤ÆÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    ¹½Ê¸:SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:FileInfo
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_setenvif
    ¸ß´¹À­:Apache 1.3 °Ê¹ß
    + +

    SetEnvIfNoCase ¤Ï°Ọ̃Ū¤Ë¤Ï + SetEnvIf ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Ʊ¤¸¤Ç¤¹¡£°ã¤¤¤Ï¡¢Àµµ¬É½¸½¤Î¥Þ¥Ã¥Á¥ó¥°¤¬Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤¤Ç + ¹Ô¤Ê¤ï¤ì¤ë¤³¤È¤Ç¤¹¡£Î㤨¤Ð:

    + +

    + SetEnvIfNoCase Host Apache\.Org site=apache +

    + +

    ¤³¤ì¤Ï HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤Ë¥Õ¥£¡¼¥ë¥É Host: ¤¬ + ¤¢¤ê¡¢¤½¤ÎÃͤ¬ Apache.Org ¤ä apache.org¡¢ + ¤½¤Î¾¤ÎÂçʸ»ú¾®Ê¸»ú¤ÎÁȤ߹ç¤ï¤»¤Ç¤¢¤Ã¤¿¤È¤­¤Ë site + ´Ä¶­ÊÑ¿ô¤ò "apache" ¤ËÀßÄꤷ¤Þ¤¹¡£

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_setenvif.html.ko.euc-kr b/trunk/docs/manual/mod/mod_setenvif.html.ko.euc-kr new file mode 100644 index 0000000000..7844be95a3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.html.ko.euc-kr @@ -0,0 +1,257 @@ + + + +mod_setenvif - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_setenvif

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:¿äûÀÇ ¼º°Ý¿¡ µû¶ó ȯ°æº¯¼ö ¼³Á¤À» º¯°æÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:setenvif_module
    ¼Ò½ºÆÄÀÏ:mod_setenvif.c
    +

    ¿ä¾à

    + + +

    mod_setenvif ¸ðµâÀº ¿äûÀÇ ¼º°ÝÀÌ + Á¤±ÔÇ¥Çö½Ä¿¡ ÇØ´çÇÏ´ÂÁö ¿©ºÎ·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ¼­¹öÀÇ + ´Ù¸¥ ºÎºÐÀÌ ÇൿÀ» °áÁ¤ÇÒ¶§ ÀÌ È¯°æº¯¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼³Á¤ÆÄÀÏ¿¡ ³ª¿À´Â ¼ø¼­´ë·Î Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ + ºê¶ó¿ìÀú°¡ MSIE°¡ ¾Æ´Ï¶ó mozillaÀÎ °æ¿ì netscape¸¦ + ¼³Á¤ÇÏ´Â ¾Æ·¡ ¿¹¿Í °°ÀÌ ¿©·¯ Áö½Ã¾î¸¦ ÇÔ²² »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +

    +
    + + +
    top
    +

    BrowserMatch Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:HTTP User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    ¹®¹ý:BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_setenvif
    +

    BrowserMatch´Â SetEnvIf Áö½Ã¾îÀÇ Æ¯º°ÇÑ + °æ¿ì·Î, HTTP ¿äû Çì´õ User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ + ¼³Á¤ÇÑ´Ù. ´ÙÀ½ µÎ ÁÙÀº °°´Ù:

    +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +

    Ãß°¡ ¿¹Á¦:

    +

    + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +

    + +
    +
    top
    +

    BrowserMatchNoCase Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù
    ¹®¹ý:BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_setenvif
    Áö¿ø:¾ÆÆÄÄ¡ 1.2 ÀÌ»ó (¾ÆÆÄÄ¡ 1.2¿¡¼­ ÀÌ Áö½Ã¾î´Â ÇöÀç + ¾ø¾îÁø mod_browser ¸ðµâ¿¡ ÀÖ¾ú´Ù)
    + +

    BrowserMatchNoCase Áö½Ã¾î´Â BrowserMatch Áö½Ã¾î¿Í + ÀÇ¹Ì»ó °°´Ù. ±×·¯³ª ÀÌ Áö½Ã¾î´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê´Â´Ù. + ¿¹¸¦ µé¾î:

    +

    + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +

    + +

    BrowserMatch¿Í + BrowserMatchNoCase Áö½Ã¾î´Â + SetEnvIf¿Í + SetEnvIfNoCase + Áö½Ã¾îÀÇ Æ¯º°ÇÑ °æ¿ì´Ù. ´ÙÀ½ ÁÖ ÁÙÀº °°´Ù:

    +

    + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +

    + +
    +
    top
    +

    SetEnvIf Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    ¹®¹ý:SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_setenvif
    +

    SetEnvIf Áö½Ã¾î´Â ¿äûÀÇ ¼ºÁú¿¡ + µû¶ó ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù. ù¹ø° ¾Æ±Ô¸ÕÆ® attribute´Â + ´ÙÀ½ ¼¼°¡ÁöÁß Çϳª´Ù:

    + +
      +
    1. HTTP ¿äû Çì´õ (´õ ÀÚ¼¼ÇÑ Á¤º¸´Â RFC2616 + Âü°í); ¿¹¸¦ µé¾î: Host, User-Agent, + Referer, Accept-Language. Á¤±ÔÇ¥Çö½ÄÀ» + »ç¿ëÇÏ¿© ¿©·¯ ¿äû Çì´õ¸¦ ÁöĪÇÒ ¼ö ÀÖ´Ù.
    2. + +
    3. ¿äûÀÇ ´ÙÀ½ ¼ºÁúÁß Çϳª: +
        +
      • Remote_Host - (ÀÖ´Ù¸é) ¿äûÇϴ Ŭ¶óÀ̾ðÆ®ÀÇ + È£½ºÆ®¸í
      • + +
      • Remote_Addr - ¿äûÇϴ Ŭ¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼Ò
      • + +
      • Server_Addr - ¿äûÀ» ¹Þ´Â ¼­¹öÀÇ IP ÁÖ¼Ò + (2.0.43 ¹öÀü ÀÌÈÄ¿¡¸¸)
      • + +
      • Request_Method - »ç¿ëÇÑ ¸Þ½áµå À̸§ + (GET, POST, µîµî)
      • + +
      • Request_Protocol - ¿äûÀÇ ÇÁ·ÎÅäÄÝ À̸§°ú + ¹öÀü (¿¹¸¦ µé¾î, "HTTP/0.9", "HTTP/1.1", µî.)
      • + +
      • Request_URI - HTTP ¿äû¿¡¼­ ¿äûÇÑ ÀÚ¿ø + -- ÀϹÝÀûÀ¸·Î URL¿¡¼­ ÁúÀǹ®ÀÚ¿­À» Á¦¿ÜÇÑ ½ºÅ´(scheme)°ú + È£½ºÆ® ÀÌÈÄ ºÎºÐ
      • +
      +
    4. + +
    5. ¿äû°ú ¿¬°üµÈ ȯ°æº¯¼ö À̸§. ±×·¡¼­ SetEnvIf +Áö½Ã¾î´Â ÀÌÀü Áö½Ã¾îÀÇ °á°ú¸¦ °Ë»çÇÒ ¼ö ÀÖ´Ù. ÀÌÀü¿¡ +SetEnvIf[NoCase] Áö½Ã¾î·Î Á¤ÀÇÇÑ È¯°æº¯¼ö¸¸À» +°Ë»çÇÒ ¼ö ÀÖ´Ù. 'ÀÌÀü'À̶õ (¼­¹öÀü¿ª°ú °°ÀÌ) ´õ ³ÐÀº ¿µ¿ª ȤÀº +Áö½Ã¾îÀÇ ÇöÀç ¿µ¿ª ÀÌÀüÀ» ¶æÇÑ´Ù. ¿äû ¼ºÁúÀÌ ¾Æ´Ï°í Á¤±ÔÇ¥Çö½ÄÀÌ +¾Æ´Ñ attribute´Â ȯ°æº¯¼ö·Î Ãë±ÞÇÑ´Ù.
    6. +
    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â (regex) Perl ȣȯ Á¤±ÔÇ¥Çö½ÄÀÌ´Ù. +ÀÌ´Â POSIX.2 egrepÀÇ Á¤±ÔÇ¥Çö½Ä°ú ºñ½ÁÇÏ´Ù. regex°¡ +attribute¿¡ ´ëÀÀÇÏ¸é ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®¸¦ ó¸®ÇÑ´Ù.

    + +

    ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®´Â ¼³Á¤ÇÒ º¯¼ö¸í°ú (¼±ÅÃÀûÀÎ) ¼³Á¤°ªµéÀÌ´Ù. +´ÙÀ½°ú °°Àº Çü½ÄÀÌ´Ù

    + +
      +
    1. varname, ȤÀº
    2. + +
    3. !varname, ȤÀº
    4. + +
    5. varname=value
    6. +
    + +

    ù¹ø° ÇüÅ´ °ªÀ¸·Î "1"À» »ç¿ëÇÑ´Ù. µÎ¹ø° ÇüÅ´ º¯¼ö°¡ + ÀÌ¹Ì Á¤ÀÇµÈ °æ¿ì º¯¼ö¸¦ Á¦°ÅÇÏ°í, ¼¼¹ø°´Â º¯¼öÀÇ °ªÀ¸·Î + value¸¦ ¼³Á¤ÇÑ´Ù. ¾ÆÆÄÄ¡ 2.0.51ºÎÅÍ + value¿¡ ÀÖ´Â $1..$9¸¦ + regexÀÇ °ýȣģ ÇÏÀ§Ç¥Çö½ÄÀ¸·Î ´ëüÇÑ´Ù.

    + +

    ¿¹Á¦:

    + + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +

    + +

    óÀ½ ¼¼ ÁÙÀº À̹ÌÁö ÆÄÀÏÀ» ¿äûÇÑ °æ¿ì ȯ°æº¯¼ö + object_is_image¸¦ ¼³Á¤ÇÑ´Ù. ³×¹ø° ÁÙÀº ÆäÀÌÁö¸¦ + www.mydomain.com À¥»çÀÌÆ®¿¡¼­ ÂüÁ¶ÇÑ °æ¿ì + intra_site_referralÀ» ¼³Á¤ÇÑ´Ù.

    + +

    ¸¶Áö¸· ¿¹´Â ¿äû¿¡ À̸§¿¡ "TS"·Î ½ÃÀÛÇÏ°í °ªÀÌ [a-z] + Áß Çϳª·Î ½ÃÀÛÇÏ´Â Çì´õ°¡ ÀÖ´Â °æ¿ì ȯ°æº¯¼ö + HAVE_TS¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    Âü°í

    + +
    +
    top
    +

    SetEnvIfNoCase Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í ¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù
    ¹®¹ý:SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:FileInfo
    »óÅÂ:Base
    ¸ðµâ:mod_setenvif
    Áö¿ø:¾ÆÆÄÄ¡ 1.3 ÀÌÈÄ
    + +

    SetEnvIfNoCase´Â Àǹ̻ó SetEnvIf Áö½Ã¾î¿Í °°Áö¸¸, + ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í Á¤±ÔÇ¥Çö½ÄÀ» ã´Â´Ù. ¿¹¸¦ µé¾î:

    +

    + SetEnvIfNoCase Host Apache\.Org site=apache +

    + +

    ÀÌ °æ¿ì HTTP ¿äû Çì´õ Host:°¡ + Apache.Org, apache.org µîÀ» Æ÷ÇÔÇϸé + site ȯ°æº¯¼ö¸¦ "apache"·Î ¼³Á¤ÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_setenvif.xml b/trunk/docs/manual/mod/mod_setenvif.xml new file mode 100644 index 0000000000..41d8ded11e --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.xml @@ -0,0 +1,273 @@ + + + + + + + + + +mod_setenvif +Allows the setting of environment variables based +on characteristics of the request +Base +mod_setenvif.c +setenvif_module + + + + +

    The mod_setenvif module allows you to set + environment variables according to whether different aspects of + the request match regular expressions you specify. These + environment variables can be used by other parts of the server + to make decisions about actions to be taken.

    + +

    The directives are considered in the order they appear in + the configuration files. So more complex sequences can be used, + such as this example, which sets netscape if the + browser is mozilla but not MSIE.

    + + + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +
    +
    + +Environment Variables in Apache + + +BrowserMatch +Sets environment variables conditional on HTTP User-Agent + +BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    The BrowserMatch is a special cases of the + SetEnvIf directive that + sets environment variables conditional on the + User-Agent HTTP request header. The following two + lines have the same effect:

    + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    + +

    Some additional examples:

    + + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +
    +
    +
    + + +BrowserMatchNoCase +Sets environment variables conditional on User-Agent without +respect to case +BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 1.2 and + above (in Apache 1.2 this directive was found in the + now-obsolete mod_browser module) + + + +

    The BrowserMatchNoCase directive is + semantically identical to the BrowserMatch directive. + However, it provides for case-insensitive matching. For + example:

    + + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +
    + +

    The BrowserMatch and + BrowserMatchNoCase directives are special cases of + the SetEnvIf and SetEnvIfNoCase + directives. The following two lines have the same effect:

    + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    +
    +
    + + +SetEnvIf +Sets environment variables based on attributes of the request + +SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    The SetEnvIf directive defines + environment variables based on attributes of the request. The + attribute specified in the first argument can be one of three + things:

    + +
      +
    1. An HTTP request header field (see RFC2616 + for more information about these); for example: Host, + User-Agent, Referer, and + Accept-Language. A regular expression may be + used to specify a set of request headers.
    2. + +
    3. One of the following aspects of the request: +
        +
      • Remote_Host - the hostname (if available) of + the client making the request
      • + +
      • Remote_Addr - the IP address of the client + making the request
      • + +
      • Server_Addr - the IP address of the server + on which the request was received (only with versions later + than 2.0.43)
      • + +
      • Request_Method - the name of the method + being used (GET, POST, et + cetera)
      • + +
      • Request_Protocol - the name and version of + the protocol with which the request was made (e.g., + "HTTP/0.9", "HTTP/1.1", etc.)
      • + +
      • Request_URI - the resource requested on the HTTP + request line -- generally the portion of the URL + following the scheme and host portion without the query string
      • +
      +
    4. + +
    5. The name of an environment variable in the list of those +associated with the request. This allows +SetEnvIf directives to test against the result +of prior matches. Only those environment variables defined by earlier +SetEnvIf[NoCase] directives are available for testing in +this manner. 'Earlier' means that they were defined at a broader scope +(such as server-wide) or previously in the current directive's scope. +Environment variables will be considered only if there was no match +among request characteristics and a regular expression was not +used for the attribute.
    6. +
    + +

    The second argument (regex) is a Perl compatible regular expression. +This is similar to a POSIX.2 egrep-style regular expression. +If the regex matches against the attribute, +then the remainder of the arguments are evaluated.

    + +

    The rest of the arguments give the names of variables to set, and +optionally values to which they should be set. These take the form +of

    + +
      +
    1. varname, or
    2. + +
    3. !varname, or
    4. + +
    5. varname=value
    6. +
    + +

    In the first form, the value will be set to "1". The second + will remove the given variable if already defined, and the + third will set the variable to the literal value given by + value. Since version 2.0.51 Apache will + recognize occurrences of $1..$9 within + value and replace them by parenthesized subexpressions + of regex.

    + + +Example: + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +
    + +

    The first three will set the environment variable + object_is_image if the request was for an image + file, and the fourth sets intra_site_referral if + the referring page was somewhere on the + www.mydomain.com Web site.

    + +

    The last example will set environment variable + HAVE_TS if the request contains any headers that + begin with "TS" whose values begins with any character in the + set [a-z].

    +
    + +Environment Variables in Apache, +for additional examples. + +
    + + +SetEnvIfNoCase +Sets environment variables based on attributes of the request +without respect to case +SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 1.3 and above + + + +

    The SetEnvIfNoCase is semantically identical to + the SetEnvIf directive, + and differs only in that the regular expression matching is + performed in a case-insensitive manner. For example:

    + + SetEnvIfNoCase Host Apache\.Org site=apache + + +

    This will cause the site environment variable + to be set to "apache" if the HTTP request header + field Host: was included and contained + Apache.Org, apache.org, or any other + combination.

    +
    +
    +
    diff --git a/trunk/docs/manual/mod/mod_setenvif.xml.ja b/trunk/docs/manual/mod/mod_setenvif.xml.ja new file mode 100644 index 0000000000..302b48d713 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.xml.ja @@ -0,0 +1,265 @@ + + + + + + + + + +mod_setenvif +$B%j%/%(%9%H$NFCD'$K4p$E$$$?4D6-JQ?t$N@_Dj$r2DG=$K$9$k(B +Base +mod_setenvif.c +setenvif_module + + +

    mod_setenvif + $B%b%8%e!<%k$O!"%j%/%(%9%H$N$"$kB&LL$,;XDj$5$l$?@55,I=8=(B + $B$K9g$&$+$I$&$+$K$h$C$F4D6-JQ?t$r@_Dj$9$k5!G=$rDs6!$7$^$9!#(B + $B$3$l$i$N4D6-JQ?t$r;HMQ$7$F!"%5!<%P$NB>$NItJ,$,$I$N$h$&$JF0:n$r$9$k$+$r(B + $B7hDj$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$N%b%8%e!<%k$,Ds6!$9$k%G%#%l%/%F%#%V$O!"(B + $B@_Dj%U%!%$%k$K8=$l$k=gHV$KE,MQ$5$l$^$9!#(B + $B$=$l$r;H$C$F!"netscape $B$r@_Dj$7$^$9!#(B

    + + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +
    +
    + +Apache $B$N4D6-JQ?t(B + + +BrowserMatch +HTTP User-Agent $B$K4p$E$$$F4D6-JQ?t$r@_Dj$9$k(B + +BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    BrowserMatch $B$O(B + SetEnvIf $B%G%#%l%/%F%#%V$N(B + $BFCNc$G!"(BUser-Agent HTTP $B%j%/%(%9%H%X%C%@$K4p$E$$$F(B + $B4D6-JQ?t$r@_Dj$7$^$9!#0J2<$N(B 2 $B9T$N8z2L$OF1$8$K$J$j$^$9(B:

    + + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    + +

    $B$=$NB>$NNc(B:

    + + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +
    +
    +
    + + +BrowserMatchNoCase +HTTP User-Agent $B$K4p$E$$$FBgJ8;z>.J8;z$r6hJL$;$:$K(B +$B4D6-JQ?t$r@_Dj$9$k(B +BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 1.2 $B0J9_(B + (Apache 1.2 $B$G$O$3$N%G%#%l%/%F%#%V$O$b$&MQ$$$i$l$F$$$J$$(B + mod_browser $B%b%8%e!<%k$K$"$j$^$7$?(B) + + + +

    BrowserMatchNoCase $B%G%#%l%/%F%#%V$O(B + $B0UL#E*$K$O(B BrowserMatch $B%G%#%l%/%F%#%V$H(B + $BF1$8$G$9!#$?$@$7!"$3$N%G%#%l%/%F%#%V$OBgJ8;z>.J8;z$r6hJL$7$J$$(B + $B%^%C%A%s%0$r9T$J$$$^$9!#Nc$($P(B:

    + + + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +
    + +

    BrowserMatch $B%G%#%l%/%F%#%V$H(B + BrowserMatchNoCase $B%G%#%l%/%F%#%V$O(B + SetEnvIf $B%G%#%l%/%F%#%V$H(B + SetEnvIfNoCase $B%G%#%l%/%F%#%V$N(B + $BFCNc$G$9!#0J2<$N(B 2 $B9T$N8z2L$OF1$8$G$9(B:

    + + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    +
    +
    + + +SetEnvIf +$B%j%/%(%9%H$NB0@-$K4p$E$$$F4D6-JQ?t$r@_Dj$9$k(B + +SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    SetEnvIf + $B%G%#%l%/%F%#%V$O!"%j%/%(%9%H$NB0@-$K4p$E$$$F4D6-JQ?t$rDj5A$7$^$9!#(B + $B:G=i$N0z?t$G;XDj$G$-$k(B attribute $B$O0J2<$N;0$D$N$I$l$+$G$9(B:

    + +
      +
    1. HTTP $B%j%/%(%9%H%X%C%@%U%#!<%k%I(B ($B>\$7$$>pJs$O(B RFC 2616 $B$r(B + $B;2>H$7$F$/$@$5$$(B)$B!#Nc$($P!"(BHost, + User-Agent, Referer, + Accept-Language $B$G$9!#%j%/%(%9%H%X%C%@$N=89g$r8=$9$?$a$K(B + $B@55,I=8=$r;H$&$3$H$b$G$-$^$9!#(B
    2. + +
    3. $B0J2<$N%j%/%(%9%H$N0lItJ,$N$I$l$+(B: + +
        +
      • Remote_Host - + $B%j%/%(%9%H$r9T$J$C$F$$$k%/%i%$%"%s%H$N%[%9%HL>(B ($B$b$7$"$l$P(B)
      • + +
      • Remote_Addr - + $B%j%/%(%9%H$r9T$J$C$F$$$k%/%i%$%"%s%H$N(B IP $B%"%I%l%9(B
      • + +
      • Server_Addr - + $B%j%/%(%9%H$r + +
      • Request_Method - + $B;HMQ$5$l$F$$$k%a%=%C%IL>(B (GET, POST + $B$J$I(B)
      • + +
      • Request_Protocol - + $B%j%/%(%9%H$,9T$J$o$l$?%W%m%H%3%k$NL>A0$H%P!<%8%g%s(B + ($BNc$($P(B$B!"(B"HTTP/0.9", "HTTP/1.1" $B$J$I!#(B)
      • + +
      • Request_URI - + URL $B$N%9%-!<%`$H%[%9%H$N8e$NItJ,(B
      • +
      +
    4. + +
    5. $B%j%/%(%9%H$H4XO"IU$1$i$l$k4D6-JQ?t$N%j%9%H!#$3$l$K$h$j(B +SetEnvIf $B%G%#%l%/%F%#%V$,0JA0$N%^%C%A$N7k2L$r(B +$B;H$&$3$H$,$G$-$k$h$&$K$J$j$^$9!#$3$NJ}K!$N%F%9%H$G$OA0$NItJ,$K$"$k(B +SetEnvIf[NoCase] $B$N7k2L$N$_$r;HMQ2DG=$G$9!#!VA0!W$H$O!"(B +$B$h$j9-$$HO0O$KBP$7$FDj5A$5$l$F$$$k(B ($B%5!<%PA4BN$N$h$&$K(B) $B$+!"8=:_$N%G%#%l%/%F%#%V$N(B +$BHO0O$G$h$jA0$NItJ,$GDj5A$5$l$F$$$k$+!"$H$$$&$3$H$G$9!#(B +$B4D6-JQ?t$G$"$k2DG=@-$O!"%j%/%(%9%H$NFC@-$KBP$9$k%^%C%A$,B8:_$;$:!"(B +attribute $B$K@55,I=8=$,;H$o$l$J$+$C$?$H$-$K$N$_9MN8$5$l$^$9!#(B
    6. +
    + +

    $BFs$DL\$N0z?t(B (regex) $B$O(B Perl $B8_49$N@55,I=8=(B$B$G$9!#(B +$B$3$l$O(B POSIX.2 $B$N(B egrep $B7A<0$N@55,I=8=$H;w$F$$$^$9!#(Bregex $B$,(B +attribute $B$K%^%C%A$9$k>l9g$O!";D$j$N0z?t$,I>2A$5$l$^$9!#(B

    + +

    $B;D$j$N0z?t$O@_Dj$9$kJQ?t$NL>A0$G!"@_Dj$5$l$kCM$r;XDj$9$k$3$H$b$G$-$^$9!#(B +$B$3$l$O!"(B

    + +
      +
    1. varname
    2. + +
    3. !varname
    4. + +
    5. varname=value
    6. +
    + +

    $B$N$I$l$+$N7A<0$K$J$j$^$9!#(B

    + +

    $B:G=i$N7A<0$G$O!"CM$O(B "1" $B$K@_Dj$5$l$^$9!#(B + $BFs$DL\$O$b$7CM$,Dj5A$5$l$F$$$l$P$=$l$rvalue $B$NM?$($i$l$?CM$K@_Dj$7$^$9!#(B + 2.0.51 $B0J9_$G$O!"(Bregex $BFb$K(B $1..$9 + $B$,B8:_$9$l$P$=$l$rG'<1$7!"(Bregex $B$NBP1~$9$k4]3g8L$G0O$^$l$?ItJ,$G(B + $BCV49$7$^$9!#(B

    + + +$BNc(B: + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +
    + +

    $B=i$a$N;0$D$O%j%/%(%9%H$,2hA|$G$"$k$H$-$K4D6-JQ?t(B + object_is_image $B$r@_Dj$7$^$9!#;M$DL\$O(B + $B;2>H85$N%Z!<%8$,%&%'%V%5%$%H(B www.mydomain.com $B$K$"$k$H$-$K(B + intra_site_referral $B$r@_Dj$7$^$9!#(B

    + +

    $B:G8e$NNc$O!"%j%/%(%9%H$K(B "TS" $B$G;O$^$j!"CM$,=89g(B [a-z] $B$N$I$l$+$G(B + $B;O$^$k%X%C%@$,$"$k$H$-$K(B HAVE_TS $B$r@_Dj$7$^$9!#(B

    +
    + +$BB>$NNc$O!"(BApache $B$N4D6-JQ?t(B + +
    + + +SetEnvIfNoCase +$B%j%/%(%9%H$NB0@-$K4p$E$$$FBgJ8;z>.J8;z$r6hJL$;$:$K4D6-JQ?t$r@_Dj$9$k(B +SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +Apache 1.3 $B0J9_(B + + + +

    SetEnvIfNoCase $B$O0UL#E*$K$O(B + SetEnvIf $B%G%#%l%/%F%#%V$H(B + $BF1$8$G$9!#0c$$$O!"@55,I=8=$N%^%C%A%s%0$,BgJ8;z>.J8;z$r6hJL$7$J$$$G(B + $B9T$J$o$l$k$3$H$G$9!#Nc$($P(B:

    + + + SetEnvIfNoCase Host Apache\.Org site=apache + + +

    $B$3$l$O(B HTTP $B%j%/%(%9%H%X%C%@$K%U%#!<%k%I(B Host: $B$,(B + $B$"$j!"$=$NCM$,(B Apache.Org $B$d(B apache.org$B!"(B + $B$=$NB>$NBgJ8;z>.J8;z$NAH$_9g$o$;$G$"$C$?$H$-$K(B site + $B4D6-JQ?t$r(B "apache" $B$K@_Dj$7$^$9!#(B

    + +
    +
    +
    diff --git a/trunk/docs/manual/mod/mod_setenvif.xml.ko b/trunk/docs/manual/mod/mod_setenvif.xml.ko new file mode 100644 index 0000000000..db0016452f --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.xml.ko @@ -0,0 +1,245 @@ + + + + + + + + + +mod_setenvif +¿äûÀÇ ¼º°Ý¿¡ µû¶ó ȯ°æº¯¼ö ¼³Á¤À» º¯°æÇÑ´Ù +Base +mod_setenvif.c +setenvif_module + + + + +

    mod_setenvif ¸ðµâÀº ¿äûÀÇ ¼º°ÝÀÌ + Á¤±ÔÇ¥Çö½Ä¿¡ ÇØ´çÇÏ´ÂÁö ¿©ºÎ·Î ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù. ¼­¹öÀÇ + ´Ù¸¥ ºÎºÐÀÌ ÇൿÀ» °áÁ¤ÇÒ¶§ ÀÌ È¯°æº¯¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼³Á¤ÆÄÀÏ¿¡ ³ª¿À´Â ¼ø¼­´ë·Î Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù. ±×·¡¼­ + ºê¶ó¿ìÀú°¡ MSIE°¡ ¾Æ´Ï¶ó mozillaÀÎ °æ¿ì netscape¸¦ + ¼³Á¤ÇÏ´Â ¾Æ·¡ ¿¹¿Í °°ÀÌ ¿©·¯ Áö½Ã¾î¸¦ ÇÔ²² »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + + + BrowserMatch ^Mozilla netscape
    + BrowserMatch MSIE !netscape
    +
    +
    + +¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö + + +BrowserMatch +HTTP User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù +BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    BrowserMatch´Â SetEnvIf Áö½Ã¾îÀÇ Æ¯º°ÇÑ + °æ¿ì·Î, HTTP ¿äû Çì´õ User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ + ¼³Á¤ÇÑ´Ù. ´ÙÀ½ µÎ ÁÙÀº °°´Ù:

    + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    + +

    Ãß°¡ ¿¹Á¦:

    + + BrowserMatch ^Mozilla forms jpeg=yes browser=netscape
    + BrowserMatch "^Mozilla/[2-3]" tables agif frames javascript
    + BrowserMatch MSIE !javascript
    +
    +
    +
    + + +BrowserMatchNoCase +´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù +BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +¾ÆÆÄÄ¡ 1.2 ÀÌ»ó (¾ÆÆÄÄ¡ 1.2¿¡¼­ ÀÌ Áö½Ã¾î´Â ÇöÀç + ¾ø¾îÁø mod_browser ¸ðµâ¿¡ ÀÖ¾ú´Ù) + + + +

    BrowserMatchNoCase Áö½Ã¾î´Â BrowserMatch Áö½Ã¾î¿Í + ÀÇ¹Ì»ó °°´Ù. ±×·¯³ª ÀÌ Áö½Ã¾î´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê´Â´Ù. + ¿¹¸¦ µé¾î:

    + + BrowserMatchNoCase mac platform=macintosh
    + BrowserMatchNoCase win platform=windows
    +
    + +

    BrowserMatch¿Í + BrowserMatchNoCase Áö½Ã¾î´Â + SetEnvIf¿Í + SetEnvIfNoCase + Áö½Ã¾îÀÇ Æ¯º°ÇÑ °æ¿ì´Ù. ´ÙÀ½ ÁÖ ÁÙÀº °°´Ù:

    + + BrowserMatchNoCase Robot is_a_robot
    + SetEnvIfNoCase User-Agent Robot is_a_robot
    +
    +
    +
    + + +SetEnvIf +¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù +SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo + + +

    SetEnvIf Áö½Ã¾î´Â ¿äûÀÇ ¼ºÁú¿¡ + µû¶ó ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù. ù¹ø° ¾Æ±Ô¸ÕÆ® attribute´Â + ´ÙÀ½ ¼¼°¡ÁöÁß Çϳª´Ù:

    + +
      +
    1. HTTP ¿äû Çì´õ (´õ ÀÚ¼¼ÇÑ Á¤º¸´Â RFC2616 + Âü°í); ¿¹¸¦ µé¾î: Host, User-Agent, + Referer, Accept-Language. Á¤±ÔÇ¥Çö½ÄÀ» + »ç¿ëÇÏ¿© ¿©·¯ ¿äû Çì´õ¸¦ ÁöĪÇÒ ¼ö ÀÖ´Ù.
    2. + +
    3. ¿äûÀÇ ´ÙÀ½ ¼ºÁúÁß Çϳª: +
        +
      • Remote_Host - (ÀÖ´Ù¸é) ¿äûÇϴ Ŭ¶óÀ̾ðÆ®ÀÇ + È£½ºÆ®¸í
      • + +
      • Remote_Addr - ¿äûÇϴ Ŭ¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼Ò
      • + +
      • Server_Addr - ¿äûÀ» ¹Þ´Â ¼­¹öÀÇ IP ÁÖ¼Ò + (2.0.43 ¹öÀü ÀÌÈÄ¿¡¸¸)
      • + +
      • Request_Method - »ç¿ëÇÑ ¸Þ½áµå À̸§ + (GET, POST, µîµî)
      • + +
      • Request_Protocol - ¿äûÀÇ ÇÁ·ÎÅäÄÝ À̸§°ú + ¹öÀü (¿¹¸¦ µé¾î, "HTTP/0.9", "HTTP/1.1", µî.)
      • + +
      • Request_URI - HTTP ¿äû¿¡¼­ ¿äûÇÑ ÀÚ¿ø + -- ÀϹÝÀûÀ¸·Î URL¿¡¼­ ÁúÀǹ®ÀÚ¿­À» Á¦¿ÜÇÑ ½ºÅ´(scheme)°ú + È£½ºÆ® ÀÌÈÄ ºÎºÐ
      • +
      +
    4. + +
    5. ¿äû°ú ¿¬°üµÈ ȯ°æº¯¼ö À̸§. ±×·¡¼­ SetEnvIf +Áö½Ã¾î´Â ÀÌÀü Áö½Ã¾îÀÇ °á°ú¸¦ °Ë»çÇÒ ¼ö ÀÖ´Ù. ÀÌÀü¿¡ +SetEnvIf[NoCase] Áö½Ã¾î·Î Á¤ÀÇÇÑ È¯°æº¯¼ö¸¸À» +°Ë»çÇÒ ¼ö ÀÖ´Ù. 'ÀÌÀü'À̶õ (¼­¹öÀü¿ª°ú °°ÀÌ) ´õ ³ÐÀº ¿µ¿ª ȤÀº +Áö½Ã¾îÀÇ ÇöÀç ¿µ¿ª ÀÌÀüÀ» ¶æÇÑ´Ù. ¿äû ¼ºÁúÀÌ ¾Æ´Ï°í Á¤±ÔÇ¥Çö½ÄÀÌ +¾Æ´Ñ attribute´Â ȯ°æº¯¼ö·Î Ãë±ÞÇÑ´Ù.
    6. +
    + +

    µÎ¹ø° ¾Æ±Ô¸ÕÆ®´Â (regex) Perl ȣȯ Á¤±ÔÇ¥Çö½ÄÀÌ´Ù. +ÀÌ´Â POSIX.2 egrepÀÇ Á¤±ÔÇ¥Çö½Ä°ú ºñ½ÁÇÏ´Ù. regex°¡ +attribute¿¡ ´ëÀÀÇÏ¸é ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®¸¦ ó¸®ÇÑ´Ù.

    + +

    ³ª¸ÓÁö ¾Æ±Ô¸ÕÆ®´Â ¼³Á¤ÇÒ º¯¼ö¸í°ú (¼±ÅÃÀûÀÎ) ¼³Á¤°ªµéÀÌ´Ù. +´ÙÀ½°ú °°Àº Çü½ÄÀÌ´Ù

    + +
      +
    1. varname, ȤÀº
    2. + +
    3. !varname, ȤÀº
    4. + +
    5. varname=value
    6. +
    + +

    ù¹ø° ÇüÅ´ °ªÀ¸·Î "1"À» »ç¿ëÇÑ´Ù. µÎ¹ø° ÇüÅ´ º¯¼ö°¡ + ÀÌ¹Ì Á¤ÀÇµÈ °æ¿ì º¯¼ö¸¦ Á¦°ÅÇÏ°í, ¼¼¹ø°´Â º¯¼öÀÇ °ªÀ¸·Î + value¸¦ ¼³Á¤ÇÑ´Ù. ¾ÆÆÄÄ¡ 2.0.51ºÎÅÍ + value¿¡ ÀÖ´Â $1..$9¸¦ + regexÀÇ °ýȣģ ÇÏÀ§Ç¥Çö½ÄÀ¸·Î ´ëüÇÑ´Ù.

    + + +¿¹Á¦: + SetEnvIf Request_URI "\.gif$" object_is_image=gif
    + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg
    + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm
    + :
    + SetEnvIf Referer www\.mydomain\.com intra_site_referral
    + :
    + SetEnvIf object_is_image xbm XBIT_PROCESSING=1
    + :
    + SetEnvIf ^TS* ^[a-z].* HAVE_TS
    +
    + +

    óÀ½ ¼¼ ÁÙÀº À̹ÌÁö ÆÄÀÏÀ» ¿äûÇÑ °æ¿ì ȯ°æº¯¼ö + object_is_image¸¦ ¼³Á¤ÇÑ´Ù. ³×¹ø° ÁÙÀº ÆäÀÌÁö¸¦ + www.mydomain.com À¥»çÀÌÆ®¿¡¼­ ÂüÁ¶ÇÑ °æ¿ì + intra_site_referralÀ» ¼³Á¤ÇÑ´Ù.

    + +

    ¸¶Áö¸· ¿¹´Â ¿äû¿¡ À̸§¿¡ "TS"·Î ½ÃÀÛÇÏ°í °ªÀÌ [a-z] + Áß Çϳª·Î ½ÃÀÛÇÏ´Â Çì´õ°¡ ÀÖ´Â °æ¿ì ȯ°æº¯¼ö + HAVE_TS¸¦ ¼³Á¤ÇÑ´Ù.

    +
    + +¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö¿¡ ´õ ¸¹Àº +¿¹Á¦°¡ ÀÖ´Ù. + +
    + + +SetEnvIfNoCase +´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í ¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù +SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ... +server config +virtual hostdirectory +.htaccess +FileInfo +¾ÆÆÄÄ¡ 1.3 ÀÌÈÄ + + + +

    SetEnvIfNoCase´Â Àǹ̻ó SetEnvIf Áö½Ã¾î¿Í °°Áö¸¸, + ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í Á¤±ÔÇ¥Çö½ÄÀ» ã´Â´Ù. ¿¹¸¦ µé¾î:

    + + SetEnvIfNoCase Host Apache\.Org site=apache + + +

    ÀÌ °æ¿ì HTTP ¿äû Çì´õ Host:°¡ + Apache.Org, apache.org µîÀ» Æ÷ÇÔÇϸé + site ȯ°æº¯¼ö¸¦ "apache"·Î ¼³Á¤ÇÑ´Ù.

    +
    +
    +
    diff --git a/trunk/docs/manual/mod/mod_setenvif.xml.meta b/trunk/docs/manual/mod/mod_setenvif.xml.meta new file mode 100644 index 0000000000..60e6547df3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_setenvif.xml.meta @@ -0,0 +1,13 @@ + + + + mod_setenvif + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_so.html b/trunk/docs/manual/mod/mod_so.html new file mode 100644 index 0000000000..1053634fd3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.html @@ -0,0 +1,11 @@ +URI: mod_so.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_so.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_so.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_so.html.en b/trunk/docs/manual/mod/mod_so.html.en new file mode 100644 index 0000000000..de971a8536 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.html.en @@ -0,0 +1,190 @@ + + + +mod_so - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_so

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Loading of executable code and +modules into the server at start-up or restart time
    Status:Extension
    Module Identifier:so_module
    Source File:mod_so.c
    Compatibility:This is a Base module (always included) on +Windows
    +

    Summary

    + + +

    On selected operating systems this module can be used to + load modules into Apache at runtime via the Dynamic Shared Object (DSO) mechanism, + rather than requiring a recompilation.

    + +

    On Unix, the loaded code typically comes from shared object + files (usually with .so extension), on Windows + this may either the .so or .dll + extension.

    + +

    Warning

    +

    Apache 1.3 modules cannot be directly used + with Apache 2.0 - the module must be modified to dynamically + load or compile into Apache 2.0.

    +
    +
    + +
    top
    +
    +

    Creating Loadable Modules for Windows

    + +

    Note

    +

    The module name format changed for Windows + with Apache 1.3.15 and 2.0 - the modules are now named as + mod_foo.so

    + +

    While mod_so still loads modules with + ApacheModuleFoo.dll names, the new naming convention is + preferred; if you are converting your loadable module for 2.0, + please fix the name to this 2.0 convention.

    + +

    The Apache module API is unchanged between the Unix and + Windows versions. Many modules will run on Windows with no or + little change from Unix, although others rely on aspects of the + Unix architecture which are not present in Windows, and will + not work.

    + +

    When a module does work, it can be added to the server in + one of two ways. As with Unix, it can be compiled into the + server. Because Apache for Windows does not have the + Configure program of Apache for Unix, the module's + source file must be added to the ApacheCore project file, and + its symbols must be added to the + os\win32\modules.c file.

    + +

    The second way is to compile the module as a DLL, a shared + library that can be loaded into the server at runtime, using + the LoadModule + directive. These module DLLs can be distributed and run on any + Apache for Windows installation, without recompilation of the + server.

    + +

    To create a module DLL, a small change is necessary to the + module's source file: The module record must be exported from + the DLL (which will be created later; see below). To do this, + add the AP_MODULE_DECLARE_DATA (defined in the + Apache header files) to your module's module record definition. + For example, if your module has:

    + +

    + module foo_module; +

    + +

    Replace the above with:

    +

    + module AP_MODULE_DECLARE_DATA foo_module; +

    + +

    Note that this will only be activated on Windows, so the + module can continue to be used, unchanged, with Unix if needed. + Also, if you are familiar with .DEF files, you can + export the module record with that method instead.

    + +

    Now, create a DLL containing your module. You will need to + link this against the libhttpd.lib export library that is + created when the libhttpd.dll shared library is compiled. You + may also have to change the compiler settings to ensure that + the Apache header files are correctly located. You can find + this library in your server root's modules directory. It is + best to grab an existing module .dsp file from the tree to + assure the build environment is configured correctly, or + alternately compare the compiler and link options to your + .dsp.

    + +

    This should create a DLL version of your module. Now simply + place it in the modules directory of your server + root, and use the LoadModule + directive to load it.

    + +
    +
    top
    +

    LoadFile Directive

    + + + + + + +
    Description:Link in the named object file or library
    Syntax:LoadFile filename [filename] ...
    Context:server config
    Status:Extension
    Module:mod_so
    + +

    The LoadFile directive links in the named object files or + libraries when the server is started or restarted; this is used + to load additional code which may be required for some module + to work. Filename is either an absolute path or + relative to ServerRoot.

    + +

    For example:

    + +

    LoadFile libexec/libxmlparse.so

    + + +
    +
    top
    +

    LoadModule Directive

    + + + + + + +
    Description:Links in the object file or library, and adds to the list +of active modules
    Syntax:LoadModule module filename
    Context:server config
    Status:Extension
    Module:mod_so
    +

    The LoadModule directive links in the object file or library + filename and adds the module structure named + module to the list of active modules. Module + is the name of the external variable of type + module in the file, and is listed as the Module Identifier + in the module documentation. Example:

    + +

    + LoadModule status_module modules/mod_status.so +

    + +

    loads the named module from the modules subdirectory of the + ServerRoot.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_so.html.ja.euc-jp b/trunk/docs/manual/mod/mod_so.html.ja.euc-jp new file mode 100644 index 0000000000..c89f3a1774 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.html.ja.euc-jp @@ -0,0 +1,190 @@ + + + +mod_so - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_so

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:µ¯Æ°»þ¤äºÆµ¯Æ°»þ¤Ë¼Â¹Ô¥³¡¼¥É¤È¥â¥¸¥å¡¼¥ë¤ò¥µ¡¼¥Ð¤Ë¥í¡¼¥É¤¹¤ë +
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:so_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_so.c
    ¸ß´¹À­:¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï Window ¤Ç¤Ï (¾ï¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë) Base +¥â¥¸¥å¡¼¥ë¤Ç¤¹
    +

    ³µÍ×

    + + +

    ¤¤¤¯¤Ä¤«¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¥µ¡¼¥Ð¤ÎºÆ¥³¥ó¥Ñ¥¤¥ë¤ò¤¹¤ëÂå¤ï¤ê¤Ë¡¢ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Æ + ưŪ¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È + (DSO) µ¡¹½¤Ë¤è¤ê¡¢¼Â¹Ô»þ¤Ë Apache ¤Ë¥â¥¸¥å¡¼¥ë¤òÆɤ߹þ¤Þ¤»¤ë¤³¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£

    + +

    Unix ¾å¤Ç¤Ï¡¢Æɤ߹þ¤Þ¤ì¤ë¥³¡¼¥É¤ÏÄ̾ï¤Ï¶¦Í­¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë + (ÉáÄÌ .so ¤È¤¤¤¦³ÈÄ¥»Ò¤¬ÉÕ¤¤¤Æ¤¤¤Þ¤¹) ¤«¤é¤Ç¤¹¡£ + Windows ¾å¤Ç¤Ï¤³¤Î¥â¥¸¥å¡¼¥ë¤Î³ÈÄ¥»Ò¤Ï .so ¤« .dll + ¤Ç¤¹¡£

    + +

    ·Ù¹ð

    +

    Apache 1.3 ¤Î¥â¥¸¥å¡¼¥ë¤òľÀÜ Apache 2.0 ¤Ç»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó + ¡½ ¥â¥¸¥å¡¼¥ë¤Ï Apache 2.0 ÍѤËưŪ¤Ë¥í¡¼¥É¤µ¤ì¤ë¤«¡¢ + ľÀÜÁȤ߹þ¤Þ¤ì¤ë¤¿¤á¤Ë½¤Àµ¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    +
    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    ¥È¥Ô¥Ã¥¯

    +
      +
    • Windows ÍÑ¤Î¥í¡¼¥É²Äǽ¤Ê¥â¥¸¥å¡¼¥ë¤òºîÀ®¤¹¤ë
    • +
    +
    top
    +
    +

    Windows ÍÑ¤Î¥í¡¼¥É²Äǽ¤Ê¥â¥¸¥å¡¼¥ë¤òºîÀ®¤¹¤ë

    + +

    Ãí

    +

    Apache 1.3.15 ¤È 2.0 ¤È¤Ç Windows ¤Î¥â¥¸¥å¡¼¥ë̾¤Î·Á¼°¤ÏÊѹ¹¤µ¤ì¤Þ¤·¤¿ + ¡½ ¥â¥¸¥å¡¼¥ë¤Ï mod_foo.so ¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤ê¤Þ¤·¤¿¡£

    + +

    ¤Þ¤À mod_so ¤Ç ApacheModuleFoo.dll ¤È¤¤¤¦Ì¾Á°¤Î¥â¥¸¥å¡¼¥ë¤â + ¥í¡¼¥É¤µ¤ì¤Þ¤¹¤¬¡¢¿·¤·¤¤Ì¾Á°¤ÎÉÕ¤±Êý¤ò»È¤¦Êý¤¬¹¥¤Þ¤ì¤Þ¤¹¡£¥â¥¸¥å¡¼¥ë¤ò + 2.0 ÍѤ˰ܿ¢¤·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢2.0 ¤Î½¬´·¤Ë¹ç¤¦¤è¤¦¤Ë̾Á°¤ò + ½¤Àµ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Apache ¤Î¥â¥¸¥å¡¼¥ë API ¤Ï UNIX ¤È Windows ´Ö¤Ç¤ÏÊѹ¹¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ + ¿¤¯¤Î¥â¥¸¥å¡¼¥ë¤ÏÁ´¤¯Êѹ¹¤Ê¤·¡¢¤â¤·¤¯¤Ï´Êñ¤ÊÊѹ¹¤Ë¤è¤ê Windows + ¤Ç¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤¿¤À¤·¡¢¤½¤ì°Ê³°¤Î Windows ¤Ë¤Ï̵¤¤ Unix + ¥¢¡¼¥­¥Æ¥¯¥Á¥ã¡¼¤Îµ¡Ç½¤Ë°Í¸¤·¤¿¥â¥¸¥å¡¼¥ë¤ÏÆ°ºî¤·¤Þ¤»¤ó¡£

    + +

    ¥â¥¸¥å¡¼¥ë¤¬¼ÂºÝ¤ËÆ°ºî¤¹¤ë¤È¤­¤Ï¡¢ + Æó¤Ä¤ÎÊýË¡¤Î¤É¤Á¤é¤«¤Ç¥µ¡¼¥Ð¤ËÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤º¡¢Unix + ¤ÈƱÍͤ˥µ¡¼¥Ð¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤ÆÁȤ߹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Windows + ÍѤΠApache ¤Ï Unix ÍѤΠApache ¤Ë¤¢¤ë Configure + ¥×¥í¥°¥é¥à¤¬¤¢¤ê¤Þ¤»¤ó¤Î¤Ç¡¢¥â¥¸¥å¡¼¥ë¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ò + ApacheCore ¥×¥í¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ËÄɲä·¡¢¥·¥ó¥Ü¥ë¤ò + os\win32\modules.c ¥Õ¥¡¥¤¥ë¤ËÄɲ乤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Æó¤ÄÌܤϥ⥸¥å¡¼¥ë¤ò DLL ¤È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëÊýË¡¤Ç¤¹¡£ + DLL ¤Ï¶¦Í­¥é¥¤¥Ö¥é¥ê¤Ç¡¢¼Â¹Ô»þ¤Ë + LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¥µ¡¼¥Ð¤ËÆɤ߹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤é¤Î¥â¥¸¥å¡¼¥ë + DLL ¤Ï¤½¤Î¤Þ¤ÞÇÛÉÛ¤¹¤ë¤³¤È¤¬²Äǽ¤Ç¡¢¥µ¡¼¥Ð¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤³¤È¤Ê¤¯¡¢Windows + ÍѤΠApache ¤Î¤¹¤Ù¤Æ¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Ç¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥â¥¸¥å¡¼¥ë DLL ¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ¥â¥¸¥å¡¼¥ë¤ÎºîÀ®¤Ë¾®¤µ¤ÊÊѹ¹¤ò¹Ô¤Ê¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢¥â¥¸¥å¡¼¥ë¤Î¥ì¥³¡¼¥É (¤³¤ì¤Ï¸å¤ÇºîÀ®¤µ¤ì¤Þ¤¹¡£ + °Ê²¼¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤) ¤¬ DLL ¤«¤é¥¨¥¯¥¹¥Ý¡¼¥È¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤ì¤ò¹Ô¤Ê¤¦¤Ë¤Ï¡¢AP_MODULE_DECLARE_DATA (Apache + ¤Î¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹) ¤ò¥â¥¸¥å¡¼¥ë¤Î¥â¥¸¥å¡¼¥ë¥ì¥³¡¼¥É + ÄêµÁ¤ÎÉôʬ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£¤¿¤È¤¨¤Ð¡¢¥â¥¸¥å¡¼¥ë¤Ë

    +

    + module foo_module; +

    + +

    ¤¬¤¢¤ë¤È¤¹¤ë¤È¡¢¤½¤ì¤ò¼¡¤Î¤â¤Î¤ÇÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£

    +

    + module AP_MODULE_DECLARE_DATA foo_module; +

    + +

    Unix ¾å¤Ç¤â¤³¤Î¥â¥¸¥å¡¼¥ë¤ò + Êѹ¹Ìµ¤·¤Ç»È¤¤Â³¤±¤é¤ì¤ë¤è¤¦¤Ë¡¢¤³¤Î¥Þ¥¯¥í¤Ï Windows + ¾å¤Ç¤Î¤ß¸úÎϤò»ý¤Á¤Þ¤¹¡£.DEF + ¥Õ¥¡¥¤¥ë¤ÎÊý¤òÎɤ¯ÃΤäƤ¤¤ë¤È¤¤¤¦¾ì¹ç¤Ï¡¢ + Âå¤ï¤ê¤Ë¤½¤ì¤ò»È¤Ã¤Æ¥â¥¸¥å¡¼¥ë¥ì¥³¡¼¥É¤ò + ¥¨¥¯¥¹¥Ý¡¼¥È¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    +

    ¤µ¤¢¡¢¤¢¤Ê¤¿¤Î¥â¥¸¥å¡¼¥ë¤Î DLL ¤òºîÀ®¤·¤Þ¤·¤ç¤¦¡£¤³¤ì¤ò¡¢ + libhttpd.lib ¶¦Í­¥é¥¤¥Ö¥é¥ê¤¬¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¤È¤­¤ËºîÀ®¤µ¤ì¤¿ + ibhttpd.lib ¥¨¥¯¥¹¥Ý¡¼¥È¥é¥¤¥Ö¥é¥ê¤È¥ê¥ó¥¯¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î»þ¤Ë¡¢ + Apache ¤Î¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤¬Àµ¤·¤¤°ÌÃ֤ˤ¢¤ë¤è¤¦¤Ë¡¢ + ¥³¥ó¥Ñ¥¤¥é¤ÎÀßÄê¤òÊѤ¨¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤³¤Î¥é¥¤¥Ö¥é¥ê¤Ï¥µ¡¼¥Ð¥ë¡¼¥È¤Î modules ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ê¤Þ¤¹¡£ + ¥Ó¥ë¥É´Ä¶­¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤ë¤è¤¦¤Ë¡¢´û¸¤Î¥â¥¸¥å¡¼¥ëÍѤΠ.dsp ¤ò + ¼è¤Ã¤Æ¤¯¤ë¤Î¤¬°ìÈÖÎɤ¤¤Ç¤·¤ç¤¦¡£¤â¤·¤¯¤Ï¡¢¤¢¤Ê¤¿¤Î .dsp ¤È + ¥³¥ó¥Ñ¥¤¥é¤È¥ê¥ó¥¯¤Î¥ª¥×¥·¥ç¥ó¤òÈæ³Ó¤¹¤ë¡¢¤È¤¤¤¦¤â¤Î¤Ç¤âÎɤ¤¤Ç¤¹¡£

    + +

    ¤³¤ì¤Ç DLL ÈǤΥ⥸¥å¡¼¥ë¤¬ºîÀ®¤µ¤ì¤Æ¤¤¤ë¤Ï¤º¤Ç¤¹¡£ + ¥µ¡¼¥Ð¥ë¡¼¥È¤Î modules + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥â¥¸¥å¡¼¥ë¤òÃÖ¤¤¤Æ¡¢ + LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤ÆÆɤ߹þ¤ó¤Ç¤¯¤À¤µ¤¤¡£

    +
    +
    top
    +

    LoadFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:»ØÄꤵ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ä¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤¹¤ë
    ¹½Ê¸:LoadFile filename [filename] ...
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_so
    + +

    LoadFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥µ¡¼¥Ð¤¬µ¯Æ°¤µ¤ì¤¿¤È¤­¤äºÆµ¯Æ°¤µ¤ì¤¿¤È¤­¤Ë¡¢ + »ØÄꤵ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ä¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï¥â¥¸¥å¡¼¥ë¤¬Æ°ºî¤¹¤ë¤¿¤á¤ËɬÍפˤʤ뤫¤â¤·¤ì¤Ê¤¤ÄɲäΠ+ ¥³¡¼¥É¤òÆɤ߹þ¤à¤¿¤á¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£Filename ¤ÏÀäÂХѥ¹¤«¡¢ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤Ç¤¹¡£

    + +

    Îã:

    + +

    LoadFile libexec/libxmlparse.so

    + + +
    +
    top
    +

    LoadModule ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ä¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤·¡¢»ÈÍѥ⥸¥å¡¼¥ë¤Î +¥ê¥¹¥È¤ËÄɲ乤ë
    ¹½Ê¸:LoadModule module filename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_so
    + +

    LoadModule ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï filename + ¤È¤¤¤¦¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ª¤è¤Ó¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤·¡¢module + ¤È¤¤¤¦Ì¾Á°¤Î¥â¥¸¥å¡¼¥ë¤Î¹½Â¤¤ò¥¢¥¯¥Æ¥£¥Ö¤Ê¥â¥¸¥å¡¼¥ë¤Î¥ê¥¹¥È¤ËÄɲä·¤Þ¤¹¡£ + Module ¤Ï¥Õ¥¡¥¤¥ëÃæ¤Î module + ·¿¤Î³°ÉôÊÑ¿ô¤Î̾Á°¤Ç¡¢¥â¥¸¥å¡¼¥ë¤Î¥É¥­¥å¥á¥ó¥È¤Ë + ¥â¥¸¥å¡¼¥ë¼±Ê̻ҤȤ·¤Æ½ñ¤«¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¹¡£Îã :

    + +

    + LoadModule status_module modules/mod_status.so +

    + +

    ¤³¤ì¤Ï ServerRoot ¤Î modules ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤«¤é»ØÄꤵ¤ì¤¿Ì¾Á°¤Î + ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤·¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_so.html.ko.euc-kr b/trunk/docs/manual/mod/mod_so.html.ko.euc-kr new file mode 100644 index 0000000000..65ee9c679b --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.html.ko.euc-kr @@ -0,0 +1,174 @@ + + + +mod_so - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_so

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + + +
    ¼³¸í:½ÃÀÛÇÒ¶§ ȤÀº Àç½ÃÀÛÇÒ¶§ ½ÇÇà°¡´ÉÇÑ ÄÚµå¿Í ¸ðµâÀ» +¼­¹ö·Î ÀоîµéÀδÙ
    »óÅÂ:Extension
    ¸ðµâ¸í:so_module
    ¼Ò½ºÆÄÀÏ:mod_so.c
    Áö¿ø:À©µµ¿ìÁî¿¡¼­ (Ç×»ó Æ÷ÇÔÇÏ´Â) Base ¸ðµâÀÌ´Ù.
    +

    ¿ä¾à

    + + +

    ¸î¸î ¿î¿µÃ¼Á¦¿¡¼­ ¾ÆÆÄÄ¡´Â µ¿Àû°øÀ¯°´Ã¼ + (DSO) ±â¼úÀ» »ç¿ëÇÏ¿© ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°íµµ ½ÇÇàÁß¿¡ + ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù.

    + +

    ÀоîµéÀÏ ÄÚµå´Â, À¯´Ð½º¿¡¼­´Â (.so È®ÀåÀÚ¸¦ + °¡Áø) ÀϹÝÀûÀÎ °øÀ¯°´Ã¼ÆÄÀÏÀÌ°í, À©µµ¿ìÁî¿¡¼­´Â .so + ȤÀº .dll È®ÀåÀÚ¸¦ °¡Áø´Ù.

    + +

    °æ°í

    +

    ¾ÆÆÄÄ¡ 1.3 ¸ðµâÀ» ¾ÆÆÄÄ¡ 2.0¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù. + ¾ÆÆÄÄ¡ 2.0ÀÌ µ¿ÀûÀ¸·Î ÀоîµéÀ̰ųª ¾ÆÆÄÄ¡¿Í °°ÀÌ ÄÄÆÄÀÏÇÏ·Á¸é + ¸ðµâÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    +
    +
    + +
    top
    +
    +

    À©µµ¿ìÁî¿¡¼­ ÀоîµéÀÏ ¸ðµâ ¸¸µé±â

    + +

    ÁÖÀÇ

    +

    À©µµ¿ìÁîÀÇ ¸ðµâ¸í Çü½ÄÀº ¾ÆÆÄÄ¡ 1.3.15¿Í 2.0¿¡¼­ º¯°æµÇ¾ú´Ù. + ¸ðµâ¸íÀº ÀÌÁ¦ mod_foo.so½ÄÀÌ´Ù.

    + +

    mod_so´Â ¾ÆÁ÷µµ ApacheModuleFoo.dll ½ÄÀÇ ¸ðµâÀ» ÀоîµéÀÏ + ¼ö ÀÖÁö¸¸, »õ·Î¿î À̸§ ±ÔÄ¢À» ¼±È£ÇÑ´Ù. ¸ðµâÀ» 2.0¿¡ ¸Â°Ô + ¼öÁ¤ÇÑ´Ù¸é À̸§À» 2.0 ±ÔÄ¢¿¡ ¾Ë¸Â°Ô °íÄ¡±æ ¹Ù¶õ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¸ðµâ API´Â À¯´Ð½º ¹öÀüÀ̰ųª À©µµ¿ìÁî ¹öÀüÀ̰ųª + °°´Ù. ¸î¸î API´Â À©µµ¿ìÁî¿¡ ¾ø´Â À¯´Ð½º ±¸Á¶¿¡ ÀÇÁ¸Çϱ⶧¹®¿¡ + »ç¿ëÇÒ ¼ö ¾øÁö¸¸, À¯´Ð½º¿¡¼­ ½ÇÇàµÇ´Â ¸¹Àº ¸ðµâÀ» ¼öÁ¤¾øÀÌ + ȤÀº Á¶±Ý ¼öÁ¤ÇÏ¿© À©µµ¿ìÁî¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ðµâÀº µÎ°¡Áö ¹æ¹ýÀ¸·Î ¼­¹ö¿¡ Ãß°¡ÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º¿¡¼­´Â + ¸ðµâÀ» ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡´Â + À¯´Ð½º¿Í ´Þ¸® Configure ÇÁ·Î±×·¥ÀÌ ¾ø±â¶§¹®¿¡ + ¸ðµâÀÇ ¼Ò½ºÆÄÀÏÀ» ApacheCore ÇÁ·ÎÁ§Æ® ÆÄÀÏ¿¡ Ãß°¡ÇÏ°í, ½Éº¼À» + os\win32\modules.c ÆÄÀÏ¿¡ Ãß°¡ÇØ¾ß ÇÑ´Ù.

    + +

    µÎ¹ø° ¹æ¹ýÀº ¸ðµâÀ» ¼­¹ö°¡ + LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ½ÃÀÛÇÒ¶§ ÀоîµéÀÏ ¼ö ÀÖ´Â °øÀ¯¶óÀ̺귯¸® DLL·Î + ¸¸µå´Â °ÍÀÌ´Ù. ÀÌ ¸ðµâ DLLÀ» ¹èÆ÷ÇÏ¸é ¼­¹ö¸¦ ÀçÄÄÆÄÀÏÇÏÁö + ¾Ê°í ¾î¶² À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡¿¡¼­µµ ¸ðµâÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ðµâ DLLÀ» ¸¸µé±âÀ§Çؼ­´Â ¸ðµâÀÇ ¼Ò½ºÆÄÀÏÀ» Á¶±Ý ¼öÁ¤ÇØ¾ß + ÇÑ´Ù. DLLÀº module record¸¦ exportÇØ¾ß ÇÑ´Ù. (¾Æ·¡ Âü°í) + À̸¦ À§ÇØ ¸ðµâÀÇ module record Á¤ÀÇ¿¡ (¾ÆÆÄÄ¡ Çì´õÆÄÀÏ¿¡ + Á¤ÀǵÈ) AP_MODULE_DECLARE_DATA¸¦ Ãß°¡ÇÑ´Ù. + ¿¹¸¦ µé¾î, ´ÙÀ½°ú °°Àº ¸ðµâÀÌ ÀÖ´Ù¸é:

    + +

    + module foo_module; +

    + +

    ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù:

    +

    + module AP_MODULE_DECLARE_DATA foo_module; +

    + +

    ÀÌ ºÎºÐÀº À©µµ¿ìÁî¿¡¼­¸¸ »ç¿ëÇϱ⶧¹®¿¡ º¯°æÇÏ¿©µµ À¯´Ð½º¿¡¼­ + ¼Ò½º¸¦ ±×´ë·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¶Ç, .DEF ÆÄÀÏ¿¡ + Àͼ÷ÇÏ´Ù¸é ´ë½Å ÀÌ ÆÄÀÏÀ» »ç¿ëÇÏ¿© module record¸¦ exportÇÒ + ¼öµµ ÀÖ´Ù.

    + +

    ÀÌÁ¦ ¸ðµâÀ» Æ÷ÇÔÇÑ DLLÀ» ¸¸µç´Ù. À̸¦ °øÀ¯¶óÀ̺귯¸® + libhttpd.dllÀ» ÄÄÆÄÀÏÇÒ¶§ ¸¸µç libhttpd.lib export ¶óÀ̺귯¸®¿Í + ¸µÅ©ÇÑ´Ù. ¾ÆÆÄÄ¡ Çì´õÆÄÀÏÀ» ¿Ã¹Ù·Î ãµµ·Ï ÄÄÆÄÀÏ·¯ ¼³Á¤À» + ¼öÁ¤ÇØ¾ß ÇÒÁöµµ ¸ð¸¥´Ù. ¼­¹öÀÇ modules µð·ºÅ丮¿¡¼­ ÀÌ + ¶óÀ̺귯¸®¸¦ ãÀ» ¼ö ÀÖ´Ù. ÄÄÆÄÀÏȯ°æÀ» ¿Ã¹Ù·Î ¼³Á¤ÇϱâÀ§ÇØ + ±âÁ¸ ¸ðµâÀÇ .dsp ÆÄÀÏÀ» °¡Á®´Ù ¾²°Å³ª Á÷Á¢ ¸¸µç .dsp¿Í + ÄÄÆÄÀÏ·¯/¸µÄ¿ ¿É¼ÇÀ» ºñ±³ÇÏ´Â °ÍÀÌ ÁÁ´Ù.

    + +

    ÀÌÁ¦ ¸ðµâÀ» DLL·Î ¸¸µç´Ù. ÀÌ°ÍÀ» ¼­¹öÀÇ + modules µð·ºÅ丮¿¡ µÎ°í, + LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀоîµéÀδÙ.

    + +
    +
    top
    +

    LoadFile Áö½Ã¾î

    + + + + + + +
    ¼³¸í:ÁöÁ¤ÇÑ ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀδÙ
    ¹®¹ý:LoadFile filename [filename] ...
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Extension
    ¸ðµâ:mod_so
    + +

    LoadFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇϰųª Àç½ÃÀÛÇÒ¶§ ÁöÁ¤ÇÑ + ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀδÙ(link in). ÀÌ Áö½Ã¾î´Â + ¾î¶² ¸ðµâÀÌ µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ Äڵ带 Ãß°¡·Î ÀоîµéÀ϶§ + »ç¿ëÇÑ´Ù. FilenameÀº Àý´ë°æ·ÎÀ̰ųª ServerRoot¿¡ ´ëÇÑ »ó´ë°æ·ÎÀÌ´Ù.

    + +

    ¿¹¸¦ µé¾î:

    + +

    LoadFile libexec/libxmlparse.so

    + + +
    +
    top
    +

    LoadModule Áö½Ã¾î

    + + + + + + +
    ¼³¸í:¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀÌ°í, »ç¿ë°¡´ÉÇÑ +¸ðµâ ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù
    ¹®¹ý:LoadModule module filename
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Extension
    ¸ðµâ:mod_so
    +

    LoadModule Áö½Ã¾î´Â ¸ñÀûÆÄÀÏ È¤Àº ¶óÀ̺귯¸® filenameÀ» + ÀоîµéÀÌ°í, »ç¿ë°¡´ÉÇÑ ¸ðµâ ¸ñ·Ï¿¡ moduleÀ̶ó´Â + ¸ðµâ ±¸Á¶Ã¼¸¦ Ãß°¡ÇÑ´Ù. ModuleÀº ÆÄÀÏÀÇ + module ÀÚ·áÇü ¿ÜºÎº¯¼ö¸íÀ̸ç, ¸ðµâ ¹®¼­ÀÇ ¸ðµâ¸í¿¡ + ³ª¿Â´Ù. ¿¹¸¦ µé¸é:

    + +

    + LoadModule status_module modules/mod_status.so +

    + +

    ServerRootÀÇ modules ÇÏÀ§µð·ºÅ丮¿¡¼­ ÁöÁ¤ÇÑ ¸ðµâÀ» ÀоîµéÀδÙ.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_so.xml b/trunk/docs/manual/mod/mod_so.xml new file mode 100644 index 0000000000..34e77d57fe --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.xml @@ -0,0 +1,176 @@ + + + + + + + + + +mod_so +Loading of executable code and +modules into the server at start-up or restart time +Extension +mod_so.c +so_module +This is a Base module (always included) on +Windows + + + +

    On selected operating systems this module can be used to + load modules into Apache at runtime via the Dynamic Shared Object (DSO) mechanism, + rather than requiring a recompilation.

    + +

    On Unix, the loaded code typically comes from shared object + files (usually with .so extension), on Windows + this may either the .so or .dll + extension.

    + + Warning +

    Apache 1.3 modules cannot be directly used + with Apache 2.0 - the module must be modified to dynamically + load or compile into Apache 2.0.

    +
    +
    + +
    Creating Loadable Modules for Windows + + Note +

    The module name format changed for Windows + with Apache 1.3.15 and 2.0 - the modules are now named as + mod_foo.so

    + +

    While mod_so still loads modules with + ApacheModuleFoo.dll names, the new naming convention is + preferred; if you are converting your loadable module for 2.0, + please fix the name to this 2.0 convention.

    + +

    The Apache module API is unchanged between the Unix and + Windows versions. Many modules will run on Windows with no or + little change from Unix, although others rely on aspects of the + Unix architecture which are not present in Windows, and will + not work.

    + +

    When a module does work, it can be added to the server in + one of two ways. As with Unix, it can be compiled into the + server. Because Apache for Windows does not have the + Configure program of Apache for Unix, the module's + source file must be added to the ApacheCore project file, and + its symbols must be added to the + os\win32\modules.c file.

    + +

    The second way is to compile the module as a DLL, a shared + library that can be loaded into the server at runtime, using + the LoadModule + directive. These module DLLs can be distributed and run on any + Apache for Windows installation, without recompilation of the + server.

    + +

    To create a module DLL, a small change is necessary to the + module's source file: The module record must be exported from + the DLL (which will be created later; see below). To do this, + add the AP_MODULE_DECLARE_DATA (defined in the + Apache header files) to your module's module record definition. + For example, if your module has:

    + + + module foo_module; + + +

    Replace the above with:

    + + module AP_MODULE_DECLARE_DATA foo_module; + + +

    Note that this will only be activated on Windows, so the + module can continue to be used, unchanged, with Unix if needed. + Also, if you are familiar with .DEF files, you can + export the module record with that method instead.

    + +

    Now, create a DLL containing your module. You will need to + link this against the libhttpd.lib export library that is + created when the libhttpd.dll shared library is compiled. You + may also have to change the compiler settings to ensure that + the Apache header files are correctly located. You can find + this library in your server root's modules directory. It is + best to grab an existing module .dsp file from the tree to + assure the build environment is configured correctly, or + alternately compare the compiler and link options to your + .dsp.

    + +

    This should create a DLL version of your module. Now simply + place it in the modules directory of your server + root, and use the LoadModule + directive to load it.

    + +
    + + +LoadFile +Link in the named object file or library +LoadFile filename [filename] ... + +server config + + + + +

    The LoadFile directive links in the named object files or + libraries when the server is started or restarted; this is used + to load additional code which may be required for some module + to work. Filename is either an absolute path or + relative to ServerRoot.

    + +

    For example:

    + + LoadFile libexec/libxmlparse.so + +
    +
    + + +LoadModule +Links in the object file or library, and adds to the list +of active modules +LoadModule module filename + +server config + + + +

    The LoadModule directive links in the object file or library + filename and adds the module structure named + module to the list of active modules. Module + is the name of the external variable of type + module in the file, and is listed as the Module Identifier + in the module documentation. Example:

    + + + LoadModule status_module modules/mod_status.so + + +

    loads the named module from the modules subdirectory of the + ServerRoot.

    +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_so.xml.ja b/trunk/docs/manual/mod/mod_so.xml.ja new file mode 100644 index 0000000000..4de13de0d1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.xml.ja @@ -0,0 +1,175 @@ + + + + + + + + + +mod_so +$B5/F0;~$d:F5/F0;~$K +Extension +mod_so.c +so_module +$B$3$N%b%8%e!<%k$O(B Window $B$G$O(B ($B>o$K4^$^$l$F$$$k(B) Base +$B%b%8%e!<%k$G$9(B + + + +

    $B$$$/$D$+$N%*%Z%l!<%F%#%s%0%7%9%F%`$G$O!"%5!<%P$N:F%3%s%Q%$%k$r$9$kBe$o$j$K!"(B + $B$3$N%b%8%e!<%k$r;HMQ$7$F(B + $BF0E*6&M-%*%V%8%'%/%H(B + (DSO) $B5!9=$K$h$j!" + +

    Unix $B>e$G$O!"FI$_9~$^$l$k%3!<%I$ODL>o$O6&M-%*%V%8%'%/%H%U%!%$%k(B + ($BIaDL(B .so $B$H$$$&3HD%;R$,IU$$$F$$$^$9(B) $B$+$i$G$9!#(B + Windows $B>e$G$O$3$N%b%8%e!<%k$N3HD%;R$O(B .so $B$+(B .dll + $B$G$9!#(B

    + + $B7Y9p(B +

    Apache 1.3 $B$N%b%8%e!<%k$rD>@\(B Apache 2.0 $B$G;H$&$3$H$O$G$-$^$;$s(B + $B!=(B $B%b%8%e!<%k$O(B Apache 2.0 $BMQ$KF0E*$K%m!<%I$5$l$k$+!"(B + $BD>@\AH$_9~$^$l$k$?$a$K=$@5$5$l$J$1$l$P$J$j$^$;$s!#(B

    +
    +
    + +
    Windows $BMQ$N%m!<%I2DG=$J%b%8%e!<%k$r:n@.$9$k(B + + $BCm(B +

    Apache 1.3.15 $B$H(B 2.0 $B$H$G(B Windows $B$N%b%8%e!<%kL>$N7A<0$OJQ99$5$l$^$7$?(B + $B!=(B $B%b%8%e!<%k$O(B mod_foo.so $B$H$$$&L>A0$K$J$j$^$7$?!#(B

    + +

    $B$^$@(B mod_so $B$G(B ApacheModuleFoo.dll $B$H$$$&L>A0$N%b%8%e!<%k$b(B + $B%m!<%I$5$l$^$9$,!"?7$7$$L>A0$NIU$1J}$r;H$&J}$,9%$^$l$^$9!#%b%8%e!<%k$r(B + 2.0 $BMQ$K0\?"$7$F$$$k$N$G$"$l$P!"(B2.0 $B$N=,47$K9g$&$h$&$KL>A0$r(B + $B=$@5$7$F$/$@$5$$!#(B

    + +

    Apache $B$N%b%8%e!<%k(B API $B$O(B UNIX $B$H(B Windows $B4V$G$OJQ99$5$l$F$$$^$;$s!#(B + $BB?$/$N%b%8%e!<%k$OA4$/JQ99$J$7!"$b$7$/$O4JC1$JJQ99$K$h$j(B Windows + $B$G + +

    $B%b%8%e!<%k$,Configure + $B%W%m%0%i%`$,$"$j$^$;$s$N$G!"%b%8%e!<%k$N%=!<%9%U%!%$%k$r(B + ApacheCore $B%W%m%8%'%/%H%U%!%$%k$KDI2C$7!"%7%s%\%k$r(B + os\win32\modules.c $B%U%!%$%k$KDI2C$9$kI,MW$,$"$j$^$9!#(B

    + +

    $BFs$DL\$O%b%8%e!<%k$r(B DLL $B$H$7$F%3%s%Q%$%k$9$kJ}K!$G$9!#(B + DLL $B$O6&M-%i%$%V%i%j$G!"LoadModule + $B%G%#%l%/%F%#%V$K$h$j%5!<%P$KFI$_9~$`$3$H$,$G$-$^$9!#$3$l$i$N%b%8%e!<%k(B + DLL $B$O$=$N$^$^G[I[$9$k$3$H$,2DG=$G!"%5!<%P$r:F%3%s%Q%$%k$9$k$3$H$J$/!"(BWindows + $BMQ$N(B Apache $B$N$9$Y$F$N%$%s%9%H!<%k$G + +

    $B%b%8%e!<%k(B DLL $B$r:n@.$9$k$?$a$K$O!"(B + $B%b%8%e!<%k$N:n@.$K>.$5$JJQ99$r9T$J$&I,MW$,$"$j$^$9!#(B + $B$D$^$j!"%b%8%e!<%k$N%l%3!<%I(B ($B$3$l$O8e$G:n@.$5$l$^$9!#(B + $B0J2<$r;2>H$7$F$/$@$5$$(B) $B$,(B DLL $B$+$i%(%/%9%]!<%H$5$l$J$1$l$P$J$j$^$;$s!#(B + $B$3$l$r9T$J$&$K$O!"(BAP_MODULE_DECLARE_DATA (Apache + $B$N%X%C%@%U%!%$%k$GDj5A$5$l$F$$$^$9(B) $B$r%b%8%e!<%k$N%b%8%e!<%k%l%3!<%I(B + $BDj5A$NItJ,$KDI2C$7$F$/$@$5$$!#$?$H$($P!"%b%8%e!<%k$K(B

    + + module foo_module; + + +

    $B$,$"$k$H$9$k$H!"$=$l$r + + module AP_MODULE_DECLARE_DATA foo_module; + + +

    Unix $B>e$G$b$3$N%b%8%e!<%k$r(B + $BJQ99L5$7$G;H$$B3$1$i$l$k$h$&$K!"$3$N%^%/%m$O(B Windows + $B>e$G$N$_8zNO$r;}$A$^$9!#(B.DEF + $B%U%!%$%k$NJ}$rNI$/CN$C$F$$$k$H$$$&>l9g$O!"(B + $BBe$o$j$K$=$l$r;H$C$F%b%8%e!<%k%l%3!<%I$r(B + $B%(%/%9%]!<%H$9$k$3$H$b$G$-$^$9!#(B

    +

    $B$5$"!"$"$J$?$N%b%8%e!<%k$N(B DLL $B$r:n@.$7$^$7$g$&!#$3$l$r!"(B + libhttpd.lib $B6&M-%i%$%V%i%j$,%3%s%Q%$%k$5$l$?$H$-$K:n@.$5$l$?(B + ibhttpd.lib $B%(%/%9%]!<%H%i%$%V%i%j$H%j%s%/$7$F$/$@$5$$!#$3$N;~$K!"(B + Apache $B$N%X%C%@%U%!%$%k$,@5$7$$0LCV$K$"$k$h$&$K!"(B + $B%3%s%Q%$%i$N@_Dj$rJQ$($kI,MW$,$"$k$+$b$7$l$^$;$s!#(B + $B$3$N%i%$%V%i%j$O%5!<%P%k!<%H$N(B modules $B%G%#%l%/%H%j$K$"$j$^$9!#(B + $B%S%k%I4D6-$,@5$7$/@_Dj$5$l$k$h$&$K!"4{B8$N%b%8%e!<%kMQ$N(B .dsp $B$r(B + $B + +

    $B$3$l$G(B DLL $BHG$N%b%8%e!<%k$,:n@.$5$l$F$$$k$O$:$G$9!#(B + $B%5!<%P%k!<%H$N(B modules + $B%G%#%l%/%H%j$K%b%8%e!<%k$rCV$$$F!"(B + LoadModule + $B%G%#%l%/%F%#%V$r;H$C$FFI$_9~$s$G$/$@$5$$!#(B

    +
    + + +LoadFile +$B;XDj$5$l$?%*%V%8%'%/%H%U%!%$%k$d%i%$%V%i%j$r%j%s%/$9$k(B +LoadFile filename [filename] ... + +server config + + + + +

    LoadFile $B%G%#%l%/%F%#%V$O!"%5!<%P$,5/F0$5$l$?$H$-$d:F5/F0$5$l$?$H$-$K!"(B + $B;XDj$5$l$?%*%V%8%'%/%H%U%!%$%k$d%i%$%V%i%j$r%j%s%/$7$^$9!#(B + $B$3$l$O%b%8%e!<%k$,F0:n$9$k$?$a$KI,MW$K$J$k$+$b$7$l$J$$DI2C$N(B + $B%3!<%I$rFI$_9~$`$?$a$K;HMQ$5$l$^$9!#(BFilename $B$O@dBP%Q%9$+!"(BServerRoot $B$+$i$NAjBP%Q%9$G$9!#(B

    + +

    $BNc(B:

    + + LoadFile libexec/libxmlparse.so + +
    +
    + + +LoadModule +$B%*%V%8%'%/%H%U%!%$%k$d%i%$%V%i%j$r%j%s%/$7!";HMQ%b%8%e!<%k$N(B +$B%j%9%H$KDI2C$9$k(B +LoadModule module filename + +server config + + + + +

    LoadModule $B%G%#%l%/%F%#%V$O(B filename + $B$H$$$&%*%V%8%'%/%H%U%!%$%k$*$h$S%i%$%V%i%j$r%j%s%/$7!"(Bmodule + $B$H$$$&L>A0$N%b%8%e!<%k$N9=B$$r%"%/%F%#%V$J%b%8%e!<%k$N%j%9%H$KDI2C$7$^$9!#(B + Module $B$O%U%!%$%kCf$N(B module + $B7?$N30ItJQ?t$NL>A0$G!"%b%8%e!<%k$N%I%-%e%a%s%H$K(B + $B%b%8%e!<%k<1JL;R(B$B$H$7$F=q$+$l$F$$$k$b$N$G$9!#Nc(B :

    + + + LoadModule status_module modules/mod_status.so + + +

    $B$3$l$O(B ServerRoot $B$N(B modules $B%5%V%G%#%l%/%H%j$+$i;XDj$5$l$?L>A0$N(B + $B%b%8%e!<%k$r%m!<%I$7$^$9!#(B

    +
    + +
    +
    diff --git a/trunk/docs/manual/mod/mod_so.xml.ko b/trunk/docs/manual/mod/mod_so.xml.ko new file mode 100644 index 0000000000..38749c9568 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.xml.ko @@ -0,0 +1,160 @@ + + + + + + + + + +mod_so +½ÃÀÛÇÒ¶§ ȤÀº Àç½ÃÀÛÇÒ¶§ ½ÇÇà°¡´ÉÇÑ ÄÚµå¿Í ¸ðµâÀ» +¼­¹ö·Î ÀоîµéÀδ٠+Extension +mod_so.c +so_module +À©µµ¿ìÁî¿¡¼­ (Ç×»ó Æ÷ÇÔÇÏ´Â) Base ¸ðµâÀÌ´Ù. + + + +

    ¸î¸î ¿î¿µÃ¼Á¦¿¡¼­ ¾ÆÆÄÄ¡´Â µ¿Àû°øÀ¯°´Ã¼ + (DSO) ±â¼úÀ» »ç¿ëÇÏ¿© ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°íµµ ½ÇÇàÁß¿¡ + ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù.

    + +

    ÀоîµéÀÏ ÄÚµå´Â, À¯´Ð½º¿¡¼­´Â (.so È®ÀåÀÚ¸¦ + °¡Áø) ÀϹÝÀûÀÎ °øÀ¯°´Ã¼ÆÄÀÏÀÌ°í, À©µµ¿ìÁî¿¡¼­´Â .so + ȤÀº .dll È®ÀåÀÚ¸¦ °¡Áø´Ù.

    + + °æ°í +

    ¾ÆÆÄÄ¡ 1.3 ¸ðµâÀ» ¾ÆÆÄÄ¡ 2.0¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù. + ¾ÆÆÄÄ¡ 2.0ÀÌ µ¿ÀûÀ¸·Î ÀоîµéÀ̰ųª ¾ÆÆÄÄ¡¿Í °°ÀÌ ÄÄÆÄÀÏÇÏ·Á¸é + ¸ðµâÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    +
    +
    + +
    À©µµ¿ìÁî¿¡¼­ ÀоîµéÀÏ ¸ðµâ ¸¸µé±â + + ÁÖÀÇ +

    À©µµ¿ìÁîÀÇ ¸ðµâ¸í Çü½ÄÀº ¾ÆÆÄÄ¡ 1.3.15¿Í 2.0¿¡¼­ º¯°æµÇ¾ú´Ù. + ¸ðµâ¸íÀº ÀÌÁ¦ mod_foo.so½ÄÀÌ´Ù.

    + +

    mod_so´Â ¾ÆÁ÷µµ ApacheModuleFoo.dll ½ÄÀÇ ¸ðµâÀ» ÀоîµéÀÏ + ¼ö ÀÖÁö¸¸, »õ·Î¿î À̸§ ±ÔÄ¢À» ¼±È£ÇÑ´Ù. ¸ðµâÀ» 2.0¿¡ ¸Â°Ô + ¼öÁ¤ÇÑ´Ù¸é À̸§À» 2.0 ±ÔÄ¢¿¡ ¾Ë¸Â°Ô °íÄ¡±æ ¹Ù¶õ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¸ðµâ API´Â À¯´Ð½º ¹öÀüÀ̰ųª À©µµ¿ìÁî ¹öÀüÀ̰ųª + °°´Ù. ¸î¸î API´Â À©µµ¿ìÁî¿¡ ¾ø´Â À¯´Ð½º ±¸Á¶¿¡ ÀÇÁ¸Çϱ⶧¹®¿¡ + »ç¿ëÇÒ ¼ö ¾øÁö¸¸, À¯´Ð½º¿¡¼­ ½ÇÇàµÇ´Â ¸¹Àº ¸ðµâÀ» ¼öÁ¤¾øÀÌ + ȤÀº Á¶±Ý ¼öÁ¤ÇÏ¿© À©µµ¿ìÁî¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ðµâÀº µÎ°¡Áö ¹æ¹ýÀ¸·Î ¼­¹ö¿¡ Ãß°¡ÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º¿¡¼­´Â + ¸ðµâÀ» ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡´Â + À¯´Ð½º¿Í ´Þ¸® Configure ÇÁ·Î±×·¥ÀÌ ¾ø±â¶§¹®¿¡ + ¸ðµâÀÇ ¼Ò½ºÆÄÀÏÀ» ApacheCore ÇÁ·ÎÁ§Æ® ÆÄÀÏ¿¡ Ãß°¡ÇÏ°í, ½Éº¼À» + os\win32\modules.c ÆÄÀÏ¿¡ Ãß°¡ÇØ¾ß ÇÑ´Ù.

    + +

    µÎ¹ø° ¹æ¹ýÀº ¸ðµâÀ» ¼­¹ö°¡ + LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ½ÃÀÛÇÒ¶§ ÀоîµéÀÏ ¼ö ÀÖ´Â °øÀ¯¶óÀ̺귯¸® DLL·Î + ¸¸µå´Â °ÍÀÌ´Ù. ÀÌ ¸ðµâ DLLÀ» ¹èÆ÷ÇÏ¸é ¼­¹ö¸¦ ÀçÄÄÆÄÀÏÇÏÁö + ¾Ê°í ¾î¶² À©µµ¿ìÁî¿ë ¾ÆÆÄÄ¡¿¡¼­µµ ¸ðµâÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ðµâ DLLÀ» ¸¸µé±âÀ§Çؼ­´Â ¸ðµâÀÇ ¼Ò½ºÆÄÀÏÀ» Á¶±Ý ¼öÁ¤ÇØ¾ß + ÇÑ´Ù. DLLÀº module record¸¦ exportÇØ¾ß ÇÑ´Ù. (¾Æ·¡ Âü°í) + À̸¦ À§ÇØ ¸ðµâÀÇ module record Á¤ÀÇ¿¡ (¾ÆÆÄÄ¡ Çì´õÆÄÀÏ¿¡ + Á¤ÀǵÈ) AP_MODULE_DECLARE_DATA¸¦ Ãß°¡ÇÑ´Ù. + ¿¹¸¦ µé¾î, ´ÙÀ½°ú °°Àº ¸ðµâÀÌ ÀÖ´Ù¸é:

    + + + module foo_module; + + +

    ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù:

    + + module AP_MODULE_DECLARE_DATA foo_module; + + +

    ÀÌ ºÎºÐÀº À©µµ¿ìÁî¿¡¼­¸¸ »ç¿ëÇϱ⶧¹®¿¡ º¯°æÇÏ¿©µµ À¯´Ð½º¿¡¼­ + ¼Ò½º¸¦ ±×´ë·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¶Ç, .DEF ÆÄÀÏ¿¡ + Àͼ÷ÇÏ´Ù¸é ´ë½Å ÀÌ ÆÄÀÏÀ» »ç¿ëÇÏ¿© module record¸¦ exportÇÒ + ¼öµµ ÀÖ´Ù.

    + +

    ÀÌÁ¦ ¸ðµâÀ» Æ÷ÇÔÇÑ DLLÀ» ¸¸µç´Ù. À̸¦ °øÀ¯¶óÀ̺귯¸® + libhttpd.dllÀ» ÄÄÆÄÀÏÇÒ¶§ ¸¸µç libhttpd.lib export ¶óÀ̺귯¸®¿Í + ¸µÅ©ÇÑ´Ù. ¾ÆÆÄÄ¡ Çì´õÆÄÀÏÀ» ¿Ã¹Ù·Î ãµµ·Ï ÄÄÆÄÀÏ·¯ ¼³Á¤À» + ¼öÁ¤ÇØ¾ß ÇÒÁöµµ ¸ð¸¥´Ù. ¼­¹öÀÇ modules µð·ºÅ丮¿¡¼­ ÀÌ + ¶óÀ̺귯¸®¸¦ ãÀ» ¼ö ÀÖ´Ù. ÄÄÆÄÀÏȯ°æÀ» ¿Ã¹Ù·Î ¼³Á¤ÇϱâÀ§ÇØ + ±âÁ¸ ¸ðµâÀÇ .dsp ÆÄÀÏÀ» °¡Á®´Ù ¾²°Å³ª Á÷Á¢ ¸¸µç .dsp¿Í + ÄÄÆÄÀÏ·¯/¸µÄ¿ ¿É¼ÇÀ» ºñ±³ÇÏ´Â °ÍÀÌ ÁÁ´Ù.

    + +

    ÀÌÁ¦ ¸ðµâÀ» DLL·Î ¸¸µç´Ù. ÀÌ°ÍÀ» ¼­¹öÀÇ + modules µð·ºÅ丮¿¡ µÎ°í, + LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀоîµéÀδÙ.

    + +
    + + +LoadFile +ÁöÁ¤ÇÑ ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀδ٠+LoadFile filename [filename] ... + +server config + + + + +

    LoadFile Áö½Ã¾î´Â ¼­¹ö°¡ ½ÃÀÛÇϰųª Àç½ÃÀÛÇÒ¶§ ÁöÁ¤ÇÑ + ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀδÙ(link in). ÀÌ Áö½Ã¾î´Â + ¾î¶² ¸ðµâÀÌ µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ Äڵ带 Ãß°¡·Î ÀоîµéÀ϶§ + »ç¿ëÇÑ´Ù. FilenameÀº Àý´ë°æ·ÎÀ̰ųª ServerRoot¿¡ ´ëÇÑ »ó´ë°æ·ÎÀÌ´Ù.

    + +

    ¿¹¸¦ µé¾î:

    + + LoadFile libexec/libxmlparse.so + +
    +
    + + +LoadModule +¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀÌ°í, »ç¿ë°¡´ÉÇÑ +¸ðµâ ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù +LoadModule module filename + +server config + + + +

    LoadModule Áö½Ã¾î´Â ¸ñÀûÆÄÀÏ È¤Àº ¶óÀ̺귯¸® filenameÀ» + ÀоîµéÀÌ°í, »ç¿ë°¡´ÉÇÑ ¸ðµâ ¸ñ·Ï¿¡ moduleÀ̶ó´Â + ¸ðµâ ±¸Á¶Ã¼¸¦ Ãß°¡ÇÑ´Ù. ModuleÀº ÆÄÀÏÀÇ + module ÀÚ·áÇü ¿ÜºÎº¯¼ö¸íÀ̸ç, ¸ðµâ ¹®¼­ÀÇ ¸ðµâ¸í¿¡ + ³ª¿Â´Ù. ¿¹¸¦ µé¸é:

    + + + LoadModule status_module modules/mod_status.so + + +

    ServerRootÀÇ modules ÇÏÀ§µð·ºÅ丮¿¡¼­ ÁöÁ¤ÇÑ ¸ðµâÀ» ÀоîµéÀδÙ.

    +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_so.xml.meta b/trunk/docs/manual/mod/mod_so.xml.meta new file mode 100644 index 0000000000..5c88b57de7 --- /dev/null +++ b/trunk/docs/manual/mod/mod_so.xml.meta @@ -0,0 +1,13 @@ + + + + mod_so + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_speling.html b/trunk/docs/manual/mod/mod_speling.html new file mode 100644 index 0000000000..bcda93f53c --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.html @@ -0,0 +1,11 @@ +URI: mod_speling.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_speling.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_speling.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_speling.html.en b/trunk/docs/manual/mod/mod_speling.html.en new file mode 100644 index 0000000000..7076bdec5e --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.html.en @@ -0,0 +1,128 @@ + + + +mod_speling - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_speling

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Attempts to correct mistaken URLs that +users might have entered by ignoring capitalization and by +allowing up to one misspelling
    Status:Extension
    Module Identifier:speling_module
    Source File:mod_speling.c
    +

    Summary

    + + +

    Requests to documents sometimes cannot be served by the core + apache server because the request was misspelled or + miscapitalized. This module addresses this problem by trying to + find a matching document, even after all other modules gave up. + It does its work by comparing each document name in the + requested directory against the requested document name + without regard to case, and allowing + up to one misspelling (character insertion / + omission / transposition or wrong character). A list is built + with all document names which were matched using this + strategy.

    + +

    If, after scanning the directory,

    + +
      +
    • no matching document was found, Apache will proceed as + usual and return a "document not found" error.
    • + +
    • only one document is found that "almost" matches the + request, then it is returned in the form of a redirection + response.
    • + +
    • more than one document with a close match was found, then + the list of the matches is returned to the client, and the + client can select the correct candidate.
    • +
    + +
    +

    Directives

    + +
    + +
    top
    +

    CheckSpelling Directive

    + + + + + + + + + +
    Description:Enables the spelling +module
    Syntax:CheckSpelling on|off
    Default:CheckSpelling Off
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Extension
    Module:mod_speling
    Compatibility:CheckSpelling was available as a separately available +module for Apache 1.1, but was limited to miscapitalizations. As +of Apache 1.3, it is part of the Apache distribution. Prior to Apache +1.3.2, the CheckSpelling directive was only available in the +"server" and "virtual host" contexts.
    +

    This directive enables or disables the spelling module. When + enabled, keep in mind that

    + +
      +
    • the directory scan which is necessary for the spelling + correction will have an impact on the server's performance + when many spelling corrections have to be performed at the + same time.
    • + +
    • the document trees should not contain sensitive files + which could be matched inadvertently by a spelling + "correction".
    • + +
    • the module is unable to correct misspelled user names (as + in http://my.host/~apahce/), just file names or + directory names.
    • + +
    • spelling corrections apply strictly to existing files, so + a request for the <Location /status> may + get incorrectly treated as the negotiated file + "/stats.html".
    • +
    + + +

    mod_speling should not be enabled in DAV + enabled directories, because it will try to "spell fix" newly created + resource names against existing filenames, e.g., when trying to upload + a new document doc43.html it might redirect to an existing + document doc34.html, which is not what was intended. +

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_speling.html.ja.euc-jp b/trunk/docs/manual/mod/mod_speling.html.ja.euc-jp new file mode 100644 index 0000000000..36edf05ec4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.html.ja.euc-jp @@ -0,0 +1,127 @@ + + + +mod_speling - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_speling

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥æ¡¼¥¶¤¬ÆþÎϤ·¤¿¤Ç¤¢¤í¤¦´Ö°ã¤Ã¤¿ URL ¤ò¡¢ +Âçʸ»ú¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤¹¤ë¤³¤È¤È°ì¤Ä°Ê²¼¤ÎÄÖ¤ê´Ö°ã¤¤¤òµöÍƤ¹¤ë¤³¤È¤Ç +½¤Àµ¤ò»î¤ß¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:speling_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_speling.c
    +

    ³µÍ×

    + + +

    ¥ê¥¯¥¨¥¹¥È¤ÎÄ֤꤬´Ö°ã¤Ã¤Æ¤¤¤¿¤ê¡¢ + Âçʸ»ú¾®Ê¸»ú¤¬°ã¤Ã¤Æ¤¤¤¿¤ê¤¹¤ë¤¿¤á¤Ë¡¢Apache ¤Î¥³¥¢¥µ¡¼¥Ð¤¬ + ¥É¥­¥å¥á¥ó¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ø¤Î±þÅú¤òÀµ¤·¤¯Ä󶡤Ǥ­¤Ê¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢Â¾¤Î¤¹¤Ù¤Æ¤Î¥â¥¸¥å¡¼¥ë¤¬¤¢¤­¤é¤á¤¿¸å¤Ç¤¢¤Ã¤¿¤È¤·¤Æ¤â¡¢ + ¥ê¥¯¥¨¥¹¥È¤Ë¹ç¤¦¥É¥­¥å¥á¥ó¥È¤ò¸«¤Ä¤±¤è¤¦¤È¤¹¤ë¤³¤È¤Ë¤è¤ê¤³¤ÎÌäÂê¤Î + ²ò·è¤ò»î¤ß¤Þ¤¹¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë + ¤½¤ì¤¾¤ì¤Î¥É¥­¥å¥á¥ó¥È¤Î̾Á°¤È¡¢¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤Î̾Á°¤È¤ò + Âçʸ»ú¾®Ê¸»ú¤Î¶èÊ̤ò̵»ë¤·¡¢°ìʸ»ú¤Þ¤Ç¤Î + ÄÖ¤ê¤Î´Ö°ã¤¤ (ʸ»ú¤ÎÁÞÆþ/¾Êά/Îٹ礦ʸ»ú¤ÎÃÖ´¹¡¢´Ö°ã¤Ã¤¿Ê¸»ú) + ¤òµö²Ä¤·¤ÆÈæ³Ó¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢ÌÜŪ¤òãÀ®¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + ¤³¤ÎÊýË¡¤Ç¥ê¥¯¥¨¥¹¥È¤Ë¹ç¤¦¥É¥­¥å¥á¥ó¥È¤Î°ìÍ÷¤¬ºîÀ®¤µ¤ì¤Þ¤¹¡£

    + +

    ¥Ç¥£¥ì¥¯¥È¥ê¤ò¥¹¥­¥ã¥ó¤·¤¿¸å¤Ë¡¢

    + +
      +
    • ŬÀڤʥɥ­¥å¥á¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¡¢ + Apache ¤Ï¤¤¤Ä¤â¤ÈƱ¤¸¤è¤¦¤Ë½èÍý¤ò¤·¡¢ + ¡Ö¥É¥­¥å¥á¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¡×¤È¤¤¤¦¥¨¥é¡¼¤òÊÖ¤·¤Þ¤¹¡£
    • + +
    • ¥ê¥¯¥¨¥¹¥È¤Ë¡Ö¤Û¤È¤ó¤É¡×¹ç¤¦¥É¥­¥å¥á¥ó¥È¤¬°ì¤Ä¤À¤±¸«¤Ä¤«¤Ã¤¿¾ì¹ç¡¢ + ¤½¤ì¤¬¥ê¥À¥¤¥ì¥¯¥È±þÅú¤È¤·¤ÆÊÖ¤µ¤ì¤Þ¤¹¡£
    • + +
    • ¤è¤¯»÷¤¿¥É¥­¥å¥á¥ó¥È¤¬Ê£¿ô¸«¤Ä¤«¤Ã¤¿¾ì¹ç¡¢ + ¤½¤Î¥ê¥¹¥È¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤µ¤ì¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤¬Àµ¤·¤¤¸õÊä¤òÁªÂò¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
    • +
    + +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    CheckSpelling ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + + +
    ÀâÌÀ:spelling ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤¹¤ë
    ¹½Ê¸:CheckSpelling on|off
    ¥Ç¥Õ¥©¥ë¥È:CheckSpelling Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:Options
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_speling
    ¸ß´¹À­:CheckSpelling ¤Ï Apache 1.1 ¤Ç¤ÏÊÌÇÛÉۤΥ⥸¥å¡¼¥ë¤Ç¡¢ +Âçʸ»ú¾®Ê¸»ú¤Î´Ö°ã¤¤¤Î¤ß¤Îµ¡Ç½¤Ç¤·¤¿¡£Apache 1.3 ¤Ç Apache ¤ÎÇÛÉÛ¤Ë +´Þ¤Þ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£Apache 1.3.2 ¤è¤êÁ°¤Ç¤Ï CheckSpelling +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡Ö¥µ¡¼¥Ð¡×¤È¡Ö¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¡×¥³¥ó¥Æ¥­¥¹¥È¤Ç¤Î¤ß +»ÈÍѲÄǽ¤Ç¤·¤¿
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÄÖ¤êÍѤΥ⥸¥å¡¼¥ë¤ò»ÈÍѤ¹¤ë¤«¤É¤¦¤«¤ò + ·è¤á¤Þ¤¹¡£»ÈÍÑ»þ¤Ë¤Ï¡¢°Ê²¼¤Î¤³¤È¤ò³Ð¤¨¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤

    + +
      +
    • Ʊ»þ¤Ë¤¿¤¯¤µ¤ó¤ÎÄÖ¤ê¤ÎÄûÀµ¤ò¹Ô¤Ê¤ï¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤È¤­¤Ï¡¢ + ¤½¤Î¤¿¤á¤Ë¹Ô¤Ê¤ï¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î¥¹¥­¥ã¥ó¤¬¥µ¡¼¥Ð¤ÎÀ­Ç½¤Ë + ±Æ¶Á¤òÍ¿¤¨¤Þ¤¹¡£
    • + +
    • ¥É¥­¥å¥á¥ó¥È¤ÎÃæ¤ËÄÖ¤ê¤Î¡ÖÄûÀµ¡×¤Ë¤è¤ê + °Õ¿Þ¤»¤º¹ç¤Ã¤Æ¤·¤Þ¤¦¤è¤¦¤Ê½ÅÍפʥե¡¥¤¥ë¤¬¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ +
    • + +
    • ¥â¥¸¥å¡¼¥ë¤Ï¥æ¡¼¥¶Ì¾¤ÎÄÖ¤ê¤Î´Ö°ã¤¤ + (http://my.host/~apahce/ ¤Î¤è¤¦¤Ë) + ¤òÄûÀµ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ÄûÀµ¤Ç¤­¤ë¤Î¤Ï¥Õ¥¡¥¤¥ë̾¤È¥Ç¥£¥ì¥¯¥È¥ê̾¤À¤±¤Ç¤¹¡£
    • + +
    • ÄÖ¤ê¤ÎÄûÀµ¤Ï¸ºß¤¹¤ë¥Õ¥¡¥¤¥ë¤Ë¸·Ì©¤ËŬÍѤµ¤ì¤Þ¤¹¤Î¤Ç¡¢ + <Location /status> + ¤Ï¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤Î·ë²Ì¤Î¥Õ¥¡¥¤¥ë "/stats.html" + ¤È¤·¤Æ´Ö°ã¤Ã¤Æ°·¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
    • +
    + + +

    DAV ¤¬Í­¸ú¤Ê¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï + mod_speling ¤ÏÍ­¸ú¤Ë¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ + ¿·¤·¤¯ºîÀ®¤·¤¿¥ê¥½¡¼¥¹Ì¾¤ò´û¤Ë¸ºß¤¹¤ë¥Õ¥¡¥¤¥ë̾¤Ë¡Ö½¤Àµ¡×¤·¤è¤¦¤È¤¹¤ë¡¢ + Î㤨¤Ð¡¢¿·µ¬¥É¥­¥å¥á¥ó¥È doc43.html ¤¬´û¤Ë¸ºß¤¹¤ë + doc34.html ¤Ë¥ê¥À¥¤¥ì¥¯¥È¤µ¤ì¤Æ¡¢ + ´üÂԤȤϰ㤦µóÆ°¤Ë¤Ê¤ë¤«¤é¤Ç¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_speling.html.ko.euc-kr b/trunk/docs/manual/mod/mod_speling.html.ko.euc-kr new file mode 100644 index 0000000000..14df147dde --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.html.ko.euc-kr @@ -0,0 +1,118 @@ + + + +mod_speling - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_speling

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:»ç¿ëÀÚ°¡ ´ë¼Ò¹®ÀÚ¸¦ À߸ø »ç¿ëÇϰųª ¸ÂÃã¹ýÀÌ Æ²¸®´Â +°ÍÀ» Çѹø±îÁö Çã¿ëÇÏ¿© À߸øµÈ URLÀ» °íÄ¡·Á°í ½ÃµµÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:speling_module
    ¼Ò½ºÆÄÀÏ:mod_speling.c
    +

    ¿ä¾à

    + + +

    Á¾Á¾ ¸ÂÃã¹ýÀÌ Æ²¸®°Å³ª ´ë¼Ò¹®ÀÚ¸¦ À߸ø »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ + ¹®¼­ ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ÀÖ´Ù. ÀÌ ¸ðµâÀº ´Ù¸¥ + ¸ðµç ¸ðµâµéÀÌ Æ÷±âÇÑ ¿äû¿¡ ÇØ´çÇÏ´Â ¹®¼­¸¦ ã´Â´Ù. ¸ðµâÀº + ¿äûÇÑ µð·ºÅ丮 ¾È¿¡ ÀÖ´Â ¸ðµç ¹®¼­¸¦ ¿äûÇÑ ¹®¼­À̸§°ú + ´ë¼Ò¹®ÀÚ ±¸º°¾øÀÌ (¹®ÀÚ Ã·°¡ / »ý·« / ±³Ã¼ + ȤÀº À߸øµÈ ¹®ÀÚ ) ¸ÂÃã¹ýÀÌ Çѹø±îÁö Ʋ·Áµµ + ºÁÁÖ¸ç ºñ±³ÇÑ´Ù. ÀÌ·± ¹æ¹ýÀ¸·Î ¹®¼­¸ñ·ÏÀ» ¸¸µç´Ù.

    + +

    µð·ºÅ丮¸¦ »ìÆ캻 ÈÄ¿¡,

    + +
      +
    • ¹®¼­¸¦ ãÁö¸øÇϸé, ¾ÆÆÄÄ¡´Â ÀϹÝÀûÀÎ "document not + found (¹®¼­¸¦ ãÀ» ¼ö ¾øÀ½)" ¿À·ù¸¦ ¹ÝȯÇÑ´Ù.
    • + +
    • ¿äû¿¡ "°ÅÀÇ" ÀÏÄ¡ÇÏ´Â ¹®¼­¸¦ Çϳª¸¸ ãÀº °æ¿ì, ±× + ¹®¼­·Î ¸®´ÙÀÌ·º¼Ç ÀÀ´äÀ» ÇÑ´Ù.
    • + +
    • ±ÙÁ¢ÇÑ ¹®¼­¸¦ ¿©·¯°³ ãÀº °æ¿ì, Ŭ¶óÀ̾ðÆ®°¡ ¿Ã¹Ù¸¥ + ¹®¼­¸¦ ¼±ÅÃÇÒ ¼ö ÀÖµµ·Ï ¹®¼­¸ñ·ÏÀ» º¸³½´Ù.
    • +
    + +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    CheckSpelling Áö½Ã¾î

    + + + + + + + + + +
    ¼³¸í:¸ÂÃã¹ý ¸ðµâÀ» »ç¿ëÇÑ´Ù
    ¹®¹ý:CheckSpelling on|off
    ±âº»°ª:CheckSpelling Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:Options
    »óÅÂ:Extension
    ¸ðµâ:mod_speling
    Áö¿ø:¾ÆÆÄÄ¡ 1.1Àº CheckSpellingÀ» º°µµ·Î Á¦°øÇÏ¿´Áö¸¸, +´ë¼Ò¹®ÀÚ°¡ ´Ù¸¥ °æ¿ì¸¸À» ó¸®ÇÒ ¼ö ÀÖ¾ú´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ¾ÆÆÄÄ¡ +¹èÆ÷º»ÀÇ ÀϺΰ¡ µÇ¾ú´Ù. ¾ÆÆÄÄ¡ 1.3.2 ÀÌÀü¿¡´Â +CheckSpelling Áö½Ã¾î¸¦ "ÁÖ¼­¹ö"¿Í "°¡»óÈ£½ºÆ®" +»ç¿ëÀå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ¾ú´Ù.
    +

    ÀÌ Áö½Ã¾î´Â ¸ÂÃã¹ý ¸ðµâÀÇ »ç¿ë¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. »ç¿ëÇÑ´Ù¸é + ´ÙÀ½À» ÁÖÀÇÇ϶ó

    + +
      +
    • ¸ÂÃã¹ý ±³Á¤À» À§ÇØ µð·ºÅ丮¸¦ »ìÆ캸´Â ÀÛ¾÷À» µ¿½Ã¿¡ + ¿©·¯¹ø ÇÒ °æ¿ì ¼­¹ö ¼º´É¿¡ ¿µÇâÀ» ÁØ´Ù.
    • + +
    • ¹®¼­Áß¿¡ ¸ÂÃã¹ý "±³Á¤"À¸·Î ¿ì¿¬È÷ º¸¿©Áú ¼ö ÀÖ´Â + ±â¹Ð¹®¼­°¡ ¾ø¾î¾ß ÇÑ´Ù.
    • + +
    • ¸ðµâÀº ÆÄÀϸí°ú µð·ºÅ丮¸í¸¸À» ±³Á¤ÇÒ ¼ö ÀÖÀ¸¸ç, + (http://my.host/~apahce/¿Í °°ÀÌ) ¸ÂÃã¹ýÀÌ + Ʋ¸° »ç¿ëÀÚ¸íÀ» ±³Á¤ÇÏÁö ¸øÇÑ´Ù.
    • + +
    • ¸ÂÃã¹ý ±³Á¤Àº Á¸ÀçÇÏ´Â ÆÄÀÏ¿¡¸¸ Àû¿ëµÈ´Ù. ±×·¡¼­ + <Location /status>¿¡ ´ëÇÑ ¿äûÀ» + ³»¿ëÇù»óÀ» °ÅÄ£ "/stats.html" ÆÄÀÏ·Î ¿ÀÀÎÇÒ + ¼ö ÀÖ´Ù.
    • +
    + + +

    DAV¸¦ »ç¿ëÇÏ´Â µð·ºÅ丮¿¡ + mod_spelingÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ÀÌÀ¯´Â »õ·Î ¾÷·ÎµåÇÏ·Á´Â + doc43.html ¹®¼­¸¦ ¾û¶×ÇÏ°Ô ±âÁ¸ÀÇ + doc34.html ÆÄÀÏ·Î ¸®´ÙÀÌ·ºÆ®ÇÏ´Â µî, DAV°¡ + »õ·Î ¸¸µå´Â ¸®¼Ò½º¸íÀ» ±âÁ¸ÀÇ ÆÄÀϸíÀ¸·Î "¸ÂÃã¹ý ±³Á¤"À» + ½ÃµµÇϱ⠶§¹®ÀÌ´Ù. +

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_speling.xml b/trunk/docs/manual/mod/mod_speling.xml new file mode 100644 index 0000000000..58af9d8974 --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.xml @@ -0,0 +1,120 @@ + + + + + + + + + +mod_speling +Attempts to correct mistaken URLs that +users might have entered by ignoring capitalization and by +allowing up to one misspelling +Extension +mod_speling.c +speling_module + + + + + +

    Requests to documents sometimes cannot be served by the core + apache server because the request was misspelled or + miscapitalized. This module addresses this problem by trying to + find a matching document, even after all other modules gave up. + It does its work by comparing each document name in the + requested directory against the requested document name + without regard to case, and allowing + up to one misspelling (character insertion / + omission / transposition or wrong character). A list is built + with all document names which were matched using this + strategy.

    + +

    If, after scanning the directory,

    + +
      +
    • no matching document was found, Apache will proceed as + usual and return a "document not found" error.
    • + +
    • only one document is found that "almost" matches the + request, then it is returned in the form of a redirection + response.
    • + +
    • more than one document with a close match was found, then + the list of the matches is returned to the client, and the + client can select the correct candidate.
    • +
    + +
    + + + +CheckSpelling +Enables the spelling +module +CheckSpelling on|off +CheckSpelling Off + +server config +virtual host +directory +.htaccess + +Options +CheckSpelling was available as a separately available +module for Apache 1.1, but was limited to miscapitalizations. As +of Apache 1.3, it is part of the Apache distribution. Prior to Apache +1.3.2, the CheckSpelling directive was only available in the +"server" and "virtual host" contexts. + + +

    This directive enables or disables the spelling module. When + enabled, keep in mind that

    + +
      +
    • the directory scan which is necessary for the spelling + correction will have an impact on the server's performance + when many spelling corrections have to be performed at the + same time.
    • + +
    • the document trees should not contain sensitive files + which could be matched inadvertently by a spelling + "correction".
    • + +
    • the module is unable to correct misspelled user names (as + in http://my.host/~apahce/), just file names or + directory names.
    • + +
    • spelling corrections apply strictly to existing files, so + a request for the <Location /status> may + get incorrectly treated as the negotiated file + "/stats.html".
    • +
    + + +

    mod_speling should not be enabled in DAV + enabled directories, because it will try to "spell fix" newly created + resource names against existing filenames, e.g., when trying to upload + a new document doc43.html it might redirect to an existing + document doc34.html, which is not what was intended. +

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_speling.xml.ja b/trunk/docs/manual/mod/mod_speling.xml.ja new file mode 100644 index 0000000000..dee8b56668 --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.xml.ja @@ -0,0 +1,118 @@ + + + + + + + + + +mod_speling +$B%f!<%6$,F~NO$7$?$G$"$m$&4V0c$C$?(B URL $B$r!"(B +$BBgJ8;z>.J8;z$N6hJL$rL5;k$9$k$3$H$H0l$D0J2<$NDV$j4V0c$$$r5vMF$9$k$3$H$G(B +$B=$@5$r;n$_$k(B +Extension +mod_speling.c +speling_module + + + + +

    $B%j%/%(%9%H$NDV$j$,4V0c$C$F$$$?$j!"(B + $BBgJ8;z>.J8;z$,0c$C$F$$$?$j$9$k$?$a$K!"(BApache $B$N%3%"%5!<%P$,(B + $B%I%-%e%a%s%H$X$N%j%/%(%9%H$X$N1~Ez$r@5$7$/Ds6!$G$-$J$$$3$H$,$"$j$^$9!#(B + $B$3$N%b%8%e!<%k$O!"B>$N$9$Y$F$N%b%8%e!<%k$,$"$-$i$a$?8e$G$"$C$?$H$7$F$b!"(B + $B%j%/%(%9%H$K9g$&%I%-%e%a%s%H$r8+$D$1$h$&$H$9$k$3$H$K$h$j$3$NLdBj$N(B + $B2r7h$r;n$_$^$9!#$3$N%b%8%e!<%k$O%j%/%(%9%H$5$l$?%G%#%l%/%H%j$K$"$k(B + $B$=$l$>$l$N%I%-%e%a%s%H$NL>A0$H!"%j%/%(%9%H$5$l$?%I%-%e%a%s%H$NL>A0$H$r(B + $BBgJ8;z>.J8;z$N6hJL$rL5;k$7(B$B!"(B$B0lJ8;z$^$G$N(B + $BDV$j$N4V0c$$(B ($BJ8;z$NA^F~(B/$B>JN,(B/$BNY9g$&J8;z$NCV49!"4V0c$C$?J8;z(B) + $B$r5v2D$7$FHf3S$9$k$3$H$K$h$j!"L\E*$rC#@.$7$h$&$H$7$^$9!#(B + $B$3$NJ}K!$G%j%/%(%9%H$K9g$&%I%-%e%a%s%H$N0lMw$,:n@.$5$l$^$9!#(B

    + +

    $B%G%#%l%/%H%j$r%9%-%c%s$7$?8e$K!"(B

    + +
      +
    • $BE,@Z$J%I%-%e%a%s%H$,8+$D$+$i$J$+$C$?>l9g!"(B + Apache $B$O$$$D$b$HF1$8$h$&$K=hM}$r$7!"(B + $B!V%I%-%e%a%s%H$,8+$D$+$i$J$$!W$H$$$&%(%i!<$rJV$7$^$9!#(B
    • + +
    • $B%j%/%(%9%H$K!V$[$H$s$I!W9g$&%I%-%e%a%s%H$,0l$D$@$18+$D$+$C$?>l9g!"(B + $B$=$l$,%j%@%$%l%/%H1~Ez$H$7$FJV$5$l$^$9!#(B
    • + +
    • $B$h$/;w$?%I%-%e%a%s%H$,J#?t8+$D$+$C$?>l9g!"(B + $B$=$N%j%9%H$,%/%i%$%"%s%H$KJV$5$l!"(B + $B%/%i%$%"%s%H$,@5$7$$8uJd$rA*Br$G$-$k$h$&$K$7$^$9!#(B
    • +
    + +
    + + +CheckSpelling +spelling $B%b%8%e!<%k$r;HMQ$9$k$h$&$K$9$k(B +CheckSpelling on|off +CheckSpelling Off + +server config +virtual host +directory +.htaccess + +Options +CheckSpelling $B$O(B Apache 1.1 $B$G$OJLG[I[$N%b%8%e!<%k$G!"(B +$BBgJ8;z>.J8;z$N4V0c$$$N$_$N5!G=$G$7$?!#(BApache 1.3 $B$G(B Apache $B$NG[I[$K(B +$B4^$^$l$k$h$&$K$J$j$^$7$?!#(BApache 1.3.2 $B$h$jA0$G$O(B CheckSpelling +$B%G%#%l%/%F%#%V$O!V%5!<%P!W$H!V%P!<%A%c%k%[%9%H!W%3%s%F%-%9%H$G$N$_(B +$B;HMQ2DG=$G$7$?(B + + +

    $B$3$N%G%#%l%/%F%#%V$ODV$jMQ$N%b%8%e!<%k$r;HMQ$9$k$+$I$&$+$r(B + $B7h$a$^$9!#;HMQ;~$K$O!"0J2<$N$3$H$r3P$($F$*$$$F$/$@$5$$(B

    + +
      +
    • $BF1;~$K$?$/$5$s$NDV$j$ND{@5$r9T$J$o$J$1$l$P$J$i$J$$$H$-$O!"(B + $B$=$N$?$a$K9T$J$o$l$k%G%#%l%/%H%j$N%9%-%c%s$,%5!<%P$N@-G=$K(B + $B1F6A$rM?$($^$9!#(B
    • + +
    • $B%I%-%e%a%s%H$NCf$KDV$j$N!VD{@5!W$K$h$j(B + $B0U?^$;$:9g$C$F$7$^$&$h$&$J=EMW$J%U%!%$%k$,$J$$$h$&$K$7$F$/$@$5$$!#(B +
    • + +
    • $B%b%8%e!<%k$O%f!<%6L>$NDV$j$N4V0c$$(B + (http://my.host/~apahce/ $B$N$h$&$K(B) + $B$rD{@5$9$k$3$H$O$G$-$^$;$s!#(B + $BD{@5$G$-$k$N$O%U%!%$%kL>$H%G%#%l%/%H%jL>$@$1$G$9!#(B
    • + +
    • $BDV$j$ND{@5$OB8:_$9$k%U%!%$%k$K87L)$KE,MQ$5$l$^$9$N$G!"(B + <Location /status> + $B$O%M%4%7%(!<%7%g%s$N7k2L$N%U%!%$%k(B "/stats.html" + $B$H$7$F4V0c$C$F07$o$l$k$+$b$7$l$^$;$s!#(B
    • +
    + + +

    DAV $B$,M-8z$J%G%#%l%/%H%j$G$O(B + mod_speling $B$OM-8z$K$7$J$$$G$/$@$5$$!#(B + $B?7$7$/:n@.$7$?%j%=!<%9L>$r4{$KB8:_$9$k%U%!%$%kL>$K!V=$@5!W$7$h$&$H$9$k!"(B + $BNc$($P!"?75,%I%-%e%a%s%H(B doc43.html $B$,4{$KB8:_$9$k(B + doc34.html $B$K%j%@%$%l%/%H$5$l$F!"(B + $B4|BT$H$O0c$&5sF0$K$J$k$+$i$G$9!#(B

    +
    + +
    + +
    diff --git a/trunk/docs/manual/mod/mod_speling.xml.ko b/trunk/docs/manual/mod/mod_speling.xml.ko new file mode 100644 index 0000000000..9b8da06933 --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.xml.ko @@ -0,0 +1,110 @@ + + + + + + + + + +mod_speling +»ç¿ëÀÚ°¡ ´ë¼Ò¹®ÀÚ¸¦ À߸ø »ç¿ëÇϰųª ¸ÂÃã¹ýÀÌ Æ²¸®´Â +°ÍÀ» Çѹø±îÁö Çã¿ëÇÏ¿© À߸øµÈ URLÀ» °íÄ¡·Á°í ½ÃµµÇÑ´Ù +Extension +mod_speling.c +speling_module + + + + + +

    Á¾Á¾ ¸ÂÃã¹ýÀÌ Æ²¸®°Å³ª ´ë¼Ò¹®ÀÚ¸¦ À߸ø »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ + ¹®¼­ ¿äûÀ» ¼­ºñ½ºÇÒ ¼ö ¾ø´Â °æ¿ì°¡ ÀÖ´Ù. ÀÌ ¸ðµâÀº ´Ù¸¥ + ¸ðµç ¸ðµâµéÀÌ Æ÷±âÇÑ ¿äû¿¡ ÇØ´çÇÏ´Â ¹®¼­¸¦ ã´Â´Ù. ¸ðµâÀº + ¿äûÇÑ µð·ºÅ丮 ¾È¿¡ ÀÖ´Â ¸ðµç ¹®¼­¸¦ ¿äûÇÑ ¹®¼­À̸§°ú + ´ë¼Ò¹®ÀÚ ±¸º°¾øÀÌ (¹®ÀÚ Ã·°¡ / »ý·« / ±³Ã¼ + ȤÀº À߸øµÈ ¹®ÀÚ ) ¸ÂÃã¹ýÀÌ Çѹø±îÁö Ʋ·Áµµ + ºÁÁÖ¸ç ºñ±³ÇÑ´Ù. ÀÌ·± ¹æ¹ýÀ¸·Î ¹®¼­¸ñ·ÏÀ» ¸¸µç´Ù.

    + +

    µð·ºÅ丮¸¦ »ìÆ캻 ÈÄ¿¡,

    + +
      +
    • ¹®¼­¸¦ ãÁö¸øÇϸé, ¾ÆÆÄÄ¡´Â ÀϹÝÀûÀÎ "document not + found (¹®¼­¸¦ ãÀ» ¼ö ¾øÀ½)" ¿À·ù¸¦ ¹ÝȯÇÑ´Ù.
    • + +
    • ¿äû¿¡ "°ÅÀÇ" ÀÏÄ¡ÇÏ´Â ¹®¼­¸¦ Çϳª¸¸ ãÀº °æ¿ì, ±× + ¹®¼­·Î ¸®´ÙÀÌ·º¼Ç ÀÀ´äÀ» ÇÑ´Ù.
    • + +
    • ±ÙÁ¢ÇÑ ¹®¼­¸¦ ¿©·¯°³ ãÀº °æ¿ì, Ŭ¶óÀ̾ðÆ®°¡ ¿Ã¹Ù¸¥ + ¹®¼­¸¦ ¼±ÅÃÇÒ ¼ö ÀÖµµ·Ï ¹®¼­¸ñ·ÏÀ» º¸³½´Ù.
    • +
    + +
    + + + +CheckSpelling +¸ÂÃã¹ý ¸ðµâÀ» »ç¿ëÇÑ´Ù +CheckSpelling on|off +CheckSpelling Off + +server config +virtual host +directory +.htaccess + +Options +¾ÆÆÄÄ¡ 1.1Àº CheckSpellingÀ» º°µµ·Î Á¦°øÇÏ¿´Áö¸¸, +´ë¼Ò¹®ÀÚ°¡ ´Ù¸¥ °æ¿ì¸¸À» ó¸®ÇÒ ¼ö ÀÖ¾ú´Ù. ¾ÆÆÄÄ¡ 1.3¿¡¼­ ¾ÆÆÄÄ¡ +¹èÆ÷º»ÀÇ ÀϺΰ¡ µÇ¾ú´Ù. ¾ÆÆÄÄ¡ 1.3.2 ÀÌÀü¿¡´Â +CheckSpelling Áö½Ã¾î¸¦ "ÁÖ¼­¹ö"¿Í "°¡»óÈ£½ºÆ®" +»ç¿ëÀå¼Ò¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ¾ú´Ù. + + +

    ÀÌ Áö½Ã¾î´Â ¸ÂÃã¹ý ¸ðµâÀÇ »ç¿ë¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. »ç¿ëÇÑ´Ù¸é + ´ÙÀ½À» ÁÖÀÇÇ϶ó

    + +
      +
    • ¸ÂÃã¹ý ±³Á¤À» À§ÇØ µð·ºÅ丮¸¦ »ìÆ캸´Â ÀÛ¾÷À» µ¿½Ã¿¡ + ¿©·¯¹ø ÇÒ °æ¿ì ¼­¹ö ¼º´É¿¡ ¿µÇâÀ» ÁØ´Ù.
    • + +
    • ¹®¼­Áß¿¡ ¸ÂÃã¹ý "±³Á¤"À¸·Î ¿ì¿¬È÷ º¸¿©Áú ¼ö ÀÖ´Â + ±â¹Ð¹®¼­°¡ ¾ø¾î¾ß ÇÑ´Ù.
    • + +
    • ¸ðµâÀº ÆÄÀϸí°ú µð·ºÅ丮¸í¸¸À» ±³Á¤ÇÒ ¼ö ÀÖÀ¸¸ç, + (http://my.host/~apahce/¿Í °°ÀÌ) ¸ÂÃã¹ýÀÌ + Ʋ¸° »ç¿ëÀÚ¸íÀ» ±³Á¤ÇÏÁö ¸øÇÑ´Ù.
    • + +
    • ¸ÂÃã¹ý ±³Á¤Àº Á¸ÀçÇÏ´Â ÆÄÀÏ¿¡¸¸ Àû¿ëµÈ´Ù. ±×·¡¼­ + <Location /status>¿¡ ´ëÇÑ ¿äûÀ» + ³»¿ëÇù»óÀ» °ÅÄ£ "/stats.html" ÆÄÀÏ·Î ¿ÀÀÎÇÒ + ¼ö ÀÖ´Ù.
    • +
    + + +

    DAV¸¦ »ç¿ëÇÏ´Â µð·ºÅ丮¿¡ + mod_spelingÀ» »ç¿ëÇÏ¸é ¾ÈµÈ´Ù. ÀÌÀ¯´Â »õ·Î ¾÷·ÎµåÇÏ·Á´Â + doc43.html ¹®¼­¸¦ ¾û¶×ÇÏ°Ô ±âÁ¸ÀÇ + doc34.html ÆÄÀÏ·Î ¸®´ÙÀÌ·ºÆ®ÇÏ´Â µî, DAV°¡ + »õ·Î ¸¸µå´Â ¸®¼Ò½º¸íÀ» ±âÁ¸ÀÇ ÆÄÀϸíÀ¸·Î "¸ÂÃã¹ý ±³Á¤"À» + ½ÃµµÇϱ⠶§¹®ÀÌ´Ù. +

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_speling.xml.meta b/trunk/docs/manual/mod/mod_speling.xml.meta new file mode 100644 index 0000000000..e17ad2e4d5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_speling.xml.meta @@ -0,0 +1,13 @@ + + + + mod_speling + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_ssl.html b/trunk/docs/manual/mod/mod_ssl.html new file mode 100644 index 0000000000..1b692ba64e --- /dev/null +++ b/trunk/docs/manual/mod/mod_ssl.html @@ -0,0 +1,3 @@ +URI: mod_ssl.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_ssl.html.en b/trunk/docs/manual/mod/mod_ssl.html.en new file mode 100644 index 0000000000..6e9f64b995 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ssl.html.en @@ -0,0 +1,1694 @@ + + + +mod_ssl - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_ssl

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols
    Status:Extension
    Module Identifier:ssl_module
    Source File:mod_ssl.c
    +

    Summary

    + +

    This module provides SSL v2/v3 and TLS v1 support for the Apache +HTTP Server. It was contributed by Ralf S. Engeschall based on his +mod_ssl project and originally derived from work by Ben Laurie.

    + +

    This module relies on OpenSSL +to provide the cryptography engine.

    + +

    Further details, discussion, and examples are provided in the +SSL documentation.

    +
    + +
    top
    +
    +

    Environment Variables

    + +

    This module provides a lot of SSL information as additional environment +variables to the SSI and CGI namespace. The generated variables are listed in +the table below. For backward compatibility the information can +be made available under different names, too. Look in the Compatibility chapter for details on the +compatibility variables.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Variable Name:Value Type:Description:
    HTTPS flag HTTPS is being used.
    SSL_PROTOCOL string The SSL protocol version (SSLv2, SSLv3, TLSv1)
    SSL_SESSION_ID string The hex-encoded SSL session id
    SSL_CIPHER string The cipher specification name
    SSL_CIPHER_EXPORT string true if cipher is an export cipher
    SSL_CIPHER_USEKEYSIZE number Number of cipher bits (actually used)
    SSL_CIPHER_ALGKEYSIZE number Number of cipher bits (possible)
    SSL_VERSION_INTERFACE string The mod_ssl program version
    SSL_VERSION_LIBRARY string The OpenSSL program version
    SSL_CLIENT_M_VERSION string The version of the client certificate
    SSL_CLIENT_M_SERIAL string The serial of the client certificate
    SSL_CLIENT_S_DN string Subject DN in client's certificate
    SSL_CLIENT_S_DN_x509 string Component of client's Subject DN
    SSL_CLIENT_I_DN string Issuer DN of client's certificate
    SSL_CLIENT_I_DN_x509 string Component of client's Issuer DN
    SSL_CLIENT_V_START string Validity of client's certificate (start time)
    SSL_CLIENT_V_END string Validity of client's certificate (end time)
    SSL_CLIENT_V_REMAIN string Number of days until client's certificate expires
    SSL_CLIENT_A_SIG string Algorithm used for the signature of client's certificate
    SSL_CLIENT_A_KEY string Algorithm used for the public key of client's certificate
    SSL_CLIENT_CERT string PEM-encoded client certificate
    SSL_CLIENT_CERT_CHAIN_n string PEM-encoded certificates in client certificate chain
    SSL_CLIENT_VERIFY string NONE, SUCCESS, GENEROUS or FAILED:reason
    SSL_SERVER_M_VERSION string The version of the server certificate
    SSL_SERVER_M_SERIAL string The serial of the server certificate
    SSL_SERVER_S_DN string Subject DN in server's certificate
    SSL_SERVER_S_DN_x509 string Component of server's Subject DN
    SSL_SERVER_I_DN string Issuer DN of server's certificate
    SSL_SERVER_I_DN_x509 string Component of server's Issuer DN
    SSL_SERVER_V_START string Validity of server's certificate (start time)
    SSL_SERVER_V_END string Validity of server's certificate (end time)
    SSL_SERVER_A_SIG string Algorithm used for the signature of server's certificate
    SSL_SERVER_A_KEY string Algorithm used for the public key of server's certificate
    SSL_SERVER_CERT string PEM-encoded server certificate
    + +

    x509 specifies a component of an X.509 DN; one of +C,ST,L,O,OU,CN,T,I,G,S,D,UID,Email. In Apache 2.1 and +later, x509 may also include a numeric _n +suffix. If the DN in question contains multiple attributes of the +same name, this suffix is used as an index to select a particular +attribute. For example, where the server certificate subject DN +included two OU fields, SSL_SERVER_S_DN_OU_0 and +SSL_SERVER_S_DN_OU_1 could be used to reference each.

    + +

    SSL_CLIENT_V_REMAIN is only available in version 2.1 +and later.

    + +
    top
    +
    +

    Custom Log Formats

    + +

    When mod_ssl is built into Apache or at least +loaded (under DSO situation) additional functions exist for the Custom Log Format of +mod_log_config. First there is an +additional ``%{varname}x'' +eXtension format function which can be used to expand any variables +provided by any module, especially those provided by mod_ssl which can +you find in the above table.

    +

    +For backward compatibility there is additionally a special +``%{name}c'' cryptography format function +provided. Information about this function is provided in the Compatibility chapter.

    +

    Example

    +CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" +

    +
    +
    top
    +

    SSLCACertificateFile Directive

    + + + + + + +
    Description:File of concatenated PEM-encoded CA Certificates +for Client Auth
    Syntax:SSLCACertificateFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the all-in-one file where you can assemble the +Certificates of Certification Authorities (CA) whose clients you deal +with. These are used for Client Authentication. Such a file is simply the +concatenation of the various PEM-encoded Certificate files, in order of +preference. This can be used alternatively and/or additionally to +SSLCACertificatePath.

    +

    Example

    +SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca-bundle-client.crt +

    + +
    +
    top
    +

    SSLCACertificatePath Directive

    + + + + + + +
    Description:Directory of PEM-encoded CA Certificates for +Client Auth
    Syntax:SSLCACertificatePath directory-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the directory where you keep the Certificates of +Certification Authorities (CAs) whose clients you deal with. These are used to +verify the client certificate on Client Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named +hash-value.N. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +

    Example

    +SSLCACertificatePath /usr/local/apache2/conf/ssl.crt/ +

    + +
    +
    top
    +

    SSLCADNRequestFile Directive

    + + + + + + +
    Description:File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    Syntax:SSLCADNRequestFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    When a client certificate is requested by mod_ssl, a list of +acceptable Certificate Authority names is sent to the client +in the SSL handshake. These CA names can be used by the client to +select an appropriate client certificate out of those it has +available.

    + +

    If neither of the directives SSLCADNRequestPath or SSLCADNRequestFile are given, then the +set of acceptable CA names sent to the client is the names of all the +CA certificates given by the SSLCACertificateFile and SSLCACertificatePath directives; in other +words, the names of the CAs which will actually be used to verify the +client certificate.

    + +

    In some circumstances, it is useful to be able to send a set of +acceptable CA names which differs from the actual CAs used to verify +the client certificate - for example, if the client certificates are +signed by intermediate CAs. In such cases, SSLCADNRequestPath and/or SSLCADNRequestFile can be used; the +acceptable CA names are then taken from the complete set of +certificates in the directory and/or file specified by this pair of +directives.

    + +

    SSLCADNRequestFile must +specify an all-in-one file containing a concatenation of +PEM-encoded CA certificates.

    + +

    Example

    +SSLCADNRequestFile /usr/local/apache2/conf/ca-names.crt +

    + +
    +
    top
    +

    SSLCADNRequestPath Directive

    + + + + + + +
    Description:Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    Syntax:SSLCADNRequestPath directory-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    + +

    This optional directive can be used to specify the set of +acceptable CA names which will be sent to the client when a +client certificate is requested. See the SSLCADNRequestFile directive for more +details.

    + +

    The files in this directory have to be PEM-encoded and are accessed +through hash filenames. So usually you can't just place the +Certificate files there: you also have to create symbolic links named +hash-value.N. And you should always make sure +this directory contains the appropriate symbolic links. Use the +Makefile which comes with mod_ssl to accomplish this +task.

    +

    Example

    +SSLCADNRequestPath /usr/local/apache2/conf/ca-names.crt/ +

    + +
    +
    top
    +

    SSLCARevocationFile Directive

    + + + + + + +
    Description:File of concatenated PEM-encoded CA CRLs for +Client Auth
    Syntax:SSLCARevocationFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the all-in-one file where you can +assemble the Certificate Revocation Lists (CRL) of Certification +Authorities (CA) whose clients you deal with. These are used +for Client Authentication. Such a file is simply the concatenation of +the various PEM-encoded CRL files, in order of preference. This can be +used alternatively and/or additionally to SSLCARevocationPath.

    +

    Example

    +SSLCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-client.crl +

    + +
    +
    top
    +

    SSLCARevocationPath Directive

    + + + + + + +
    Description:Directory of PEM-encoded CA CRLs for +Client Auth
    Syntax:SSLCARevocationPath directory-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose clients you deal with. +These are used to revoke the client certificate on Client Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +hash-value.rN. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +

    Example

    +SSLCARevocationPath /usr/local/apache2/conf/ssl.crl/ +

    + +
    +
    top
    +

    SSLCertificateChainFile Directive

    + + + + + + +
    Description:File of PEM-encoded Server CA Certificates
    Syntax:SSLCertificateChainFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the optional all-in-one file where you can +assemble the certificates of Certification Authorities (CA) which form the +certificate chain of the server certificate. This starts with the issuing CA +certificate of of the server certificate and can range up to the root CA +certificate. Such a file is simply the concatenation of the various +PEM-encoded CA Certificate files, usually in certificate chain order.

    +

    +This should be used alternatively and/or additionally to SSLCACertificatePath for explicitly +constructing the server certificate chain which is sent to the browser +in addition to the server certificate. It is especially useful to +avoid conflicts with CA certificates when using client +authentication. Because although placing a CA certificate of the +server certificate chain into SSLCACertificatePath has the same effect +for the certificate chain construction, it has the side-effect that +client certificates issued by this same CA certificate are also +accepted on client authentication. That's usually not one expect.

    +

    +But be careful: Providing the certificate chain works only if you are using a +single (either RSA or DSA) based server certificate. If you are +using a coupled RSA+DSA certificate pair, this will work only if actually both +certificates use the same certificate chain. Else the browsers will be +confused in this situation.

    +

    Example

    +SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt +

    + +
    +
    top
    +

    SSLCertificateFile Directive

    + + + + + + +
    Description:Server PEM-encoded X.509 Certificate file
    Syntax:SSLCertificateFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive points to the PEM-encoded Certificate file for the server and +optionally also to the corresponding RSA or DSA Private Key file for it +(contained in the same file). If the contained Private Key is encrypted the +Pass Phrase dialog is forced at startup time. This directive can be used up to +two times (referencing different filenames) when both a RSA and a DSA based +server certificate is used in parallel.

    +

    Example

    +SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt +

    + +
    +
    top
    +

    SSLCertificateKeyFile Directive

    + + + + + + +
    Description:Server PEM-encoded Private Key file
    Syntax:SSLCertificateKeyFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive points to the PEM-encoded Private Key file for the +server. If the Private Key is not combined with the Certificate in the +SSLCertificateFile, use this additional directive to +point to the file with the stand-alone Private Key. When +SSLCertificateFile is used and the file +contains both the Certificate and the Private Key this directive need +not be used. But we strongly discourage this practice. Instead we +recommend you to separate the Certificate and the Private Key. If the +contained Private Key is encrypted, the Pass Phrase dialog is forced +at startup time. This directive can be used up to two times +(referencing different filenames) when both a RSA and a DSA based +private key is used in parallel.

    +

    Example

    +SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key +

    + +
    +
    top
    +

    SSLCipherSuite Directive

    + + + + + + + + +
    Description:Cipher Suite available for negotiation in SSL +handshake
    Syntax:SSLCipherSuite cipher-spec
    Default:SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This complex directive uses a colon-separated cipher-spec string +consisting of OpenSSL cipher specifications to configure the Cipher Suite the +client is permitted to negotiate in the SSL handshake phase. Notice that this +directive can be used both in per-server and per-directory context. In +per-server context it applies to the standard SSL handshake when a connection +is established. In per-directory context it forces a SSL renegotation with the +reconfigured Cipher Suite after the HTTP request was read but before the HTTP +response is sent.

    +

    +An SSL cipher specification in cipher-spec is composed of 4 major +attributes plus a few extra minor ones:

    +
      +
    • Key Exchange Algorithm:
      + RSA or Diffie-Hellman variants. +
    • +
    • Authentication Algorithm:
      + RSA, Diffie-Hellman, DSS or none. +
    • +
    • Cipher/Encryption Algorithm:
      + DES, Triple-DES, RC4, RC2, IDEA or none. +
    • +
    • MAC Digest Algorithm:
      + MD5, SHA or SHA1. +
    • +
    +

    An SSL cipher can also be an export cipher and is either a SSLv2 or SSLv3/TLSv1 +cipher (here TLSv1 is equivalent to SSLv3). To specify which ciphers to use, +one can either specify all the Ciphers, one at a time, or use aliases to +specify the preference and order for the ciphers (see Table +1).

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Tag Description
    Key Exchange Algorithm:
    kRSA RSA key exchange
    kDHr Diffie-Hellman key exchange with RSA key
    kDHd Diffie-Hellman key exchange with DSA key
    kEDH Ephemeral (temp.key) Diffie-Hellman key exchange (no cert)
    Authentication Algorithm:
    aNULL No authentication
    aRSA RSA authentication
    aDSS DSS authentication
    aDH Diffie-Hellman authentication
    Cipher Encoding Algorithm:
    eNULL No encoding
    DES DES encoding
    3DES Triple-DES encoding
    RC4 RC4 encoding
    RC2 RC2 encoding
    IDEA IDEA encoding
    MAC Digest Algorithm:
    MD5 MD5 hash function
    SHA1 SHA1 hash function
    SHA SHA hash function
    Aliases:
    SSLv2 all SSL version 2.0 ciphers
    SSLv3 all SSL version 3.0 ciphers
    TLSv1 all TLS version 1.0 ciphers
    EXP all export ciphers
    EXPORT40 all 40-bit export ciphers only
    EXPORT56 all 56-bit export ciphers only
    LOW all low strength ciphers (no export, single DES)
    MEDIUM all ciphers with 128 bit encryption
    HIGH all ciphers using Triple-DES
    RSA all ciphers using RSA key exchange
    DH all ciphers using Diffie-Hellman key exchange
    EDH all ciphers using Ephemeral Diffie-Hellman key exchange
    ADH all ciphers using Anonymous Diffie-Hellman key exchange
    DSS all ciphers using DSS authentication
    NULL all ciphers using no encryption
    +

    +Now where this becomes interesting is that these can be put together +to specify the order and ciphers you wish to use. To speed this up +there are also aliases (SSLv2, SSLv3, TLSv1, EXP, LOW, MEDIUM, +HIGH) for certain groups of ciphers. These tags can be joined +together with prefixes to form the cipher-spec. Available +prefixes are:

    +
      +
    • none: add cipher to list
    • +
    • +: add ciphers to list and pull them to current location in list
    • +
    • -: remove cipher from list (can be added later again)
    • +
    • !: kill cipher from list completely (can not be added later again)
    • +
    +

    A simpler way to look at all of this is to use the ``openssl ciphers +-v'' command which provides a nice way to successively create the +correct cipher-spec string. The default cipher-spec string +is ``ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'' which +means the following: first, remove from consideration any ciphers that do not +authenticate, i.e. for SSL only the Anonymous Diffie-Hellman ciphers. Next, +use ciphers using RC4 and RSA. Next include the high, medium and then the low +security ciphers. Finally pull all SSLv2 and export ciphers to the +end of the list.

    +
    +$ openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'
    +NULL-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=SHA1
    +NULL-MD5                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=MD5
    +EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
    +...                     ...               ...     ...           ...
    +EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
    +EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
    +EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
    +
    +

    The complete list of particular RSA & DH ciphers for SSL is given in Table 2.

    +

    Example

    +SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cipher-Tag Protocol Key Ex. Auth. Enc. MAC Type
    RSA Ciphers:
    DES-CBC3-SHA SSLv3 RSA RSA 3DES(168) SHA1
    DES-CBC3-MD5 SSLv2 RSA RSA 3DES(168) MD5
    IDEA-CBC-SHA SSLv3 RSA RSA IDEA(128) SHA1
    RC4-SHA SSLv3 RSA RSA RC4(128) SHA1
    RC4-MD5 SSLv3 RSA RSA RC4(128) MD5
    IDEA-CBC-MD5 SSLv2 RSA RSA IDEA(128) MD5
    RC2-CBC-MD5 SSLv2 RSA RSA RC2(128) MD5
    RC4-MD5 SSLv2 RSA RSA RC4(128) MD5
    DES-CBC-SHA SSLv3 RSA RSA DES(56) SHA1
    RC4-64-MD5 SSLv2 RSA RSA RC4(64) MD5
    DES-CBC-MD5 SSLv2 RSA RSA DES(56) MD5
    EXP-DES-CBC-SHA SSLv3 RSA(512) RSA DES(40) SHA1 export
    EXP-RC2-CBC-MD5 SSLv3 RSA(512) RSA RC2(40) MD5 export
    EXP-RC4-MD5 SSLv3 RSA(512) RSA RC4(40) MD5 export
    EXP-RC2-CBC-MD5 SSLv2 RSA(512) RSA RC2(40) MD5 export
    EXP-RC4-MD5 SSLv2 RSA(512) RSA RC4(40) MD5 export
    NULL-SHA SSLv3 RSA RSA None SHA1
    NULL-MD5 SSLv3 RSA RSA None MD5
    Diffie-Hellman Ciphers:
    ADH-DES-CBC3-SHA SSLv3 DH None 3DES(168) SHA1
    ADH-DES-CBC-SHA SSLv3 DH None DES(56) SHA1
    ADH-RC4-MD5 SSLv3 DH None RC4(128) MD5
    EDH-RSA-DES-CBC3-SHA SSLv3 DH RSA 3DES(168) SHA1
    EDH-DSS-DES-CBC3-SHA SSLv3 DH DSS 3DES(168) SHA1
    EDH-RSA-DES-CBC-SHA SSLv3 DH RSA DES(56) SHA1
    EDH-DSS-DES-CBC-SHA SSLv3 DH DSS DES(56) SHA1
    EXP-EDH-RSA-DES-CBC-SHA SSLv3 DH(512) RSA DES(40) SHA1 export
    EXP-EDH-DSS-DES-CBC-SHA SSLv3 DH(512) DSS DES(40) SHA1 export
    EXP-ADH-DES-CBC-SHA SSLv3 DH(512) None DES(40) SHA1 export
    EXP-ADH-RC4-MD5 SSLv3 DH(512) None RC4(40) MD5 export
    + +
    +
    top
    +

    SSLCryptoDevice Directive

    + + + + + + + + +
    Description:Enable use of a cryptographic hardware accelerator
    Syntax:SSLCryptoDevice engine
    Default:SSLCryptoDevice builtin
    Context:server config
    Status:Extension
    Module:mod_ssl
    Compatibility:Available if mod_ssl is built using -DSSL_ENGINE_EXPERIMENTAL
    +

    +This directive enables use of a cryptographic hardware accelerator +board to offload some of the SSL processing overhead. This directive +can only be used if the SSL toolkit is built with "engine" support; +OpenSSL 0.9.7 and later releases have "engine" support by default, the +separate "-engine" releases of OpenSSL 0.9.6 must be used.

    + +

    To discover which engine names are supported, run the command +"openssl engine".

    + +

    Example

    +# For a Broadcom accelerator:
    +SSLCryptoDevice ubsec +

    + +
    +
    top
    +

    SSLEngine Directive

    + + + + + + + +
    Description:SSL Engine Operation Switch
    Syntax:SSLEngine on|off|optional
    Default:SSLEngine off
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive toggles the usage of the SSL/TLS Protocol Engine. This +is usually used inside a <VirtualHost> section to enable SSL/TLS for a +particular virtual host. By default the SSL/TLS Protocol Engine is +disabled for both the main server and all configured virtual hosts.

    +

    Example

    +<VirtualHost _default_:443>
    +SSLEngine on
    +...
    +</VirtualHost> +

    +

    New in Apache 2.1, SSLEngine can be set to +optional. This enables support for +RFC 2817, Upgrading to TLS +Within HTTP/1.1. At this time no web browsers support RFC 2817.

    + +
    +
    top
    +

    SSLHonorCipherOrder Directive

    + + + + + + + +
    Description:Option to prefer the server's cipher preference order
    Syntax:SSLHonorCiperOrder flag
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    Compatibility:Available in Apache 2.1 and later, if using OpenSSL 0.9.7 or later
    +

    When choosing a cipher during an SSLv3 or TLSv1 handshake, normally +the client's preference is used. If this directive is enabled, the +server's preference will be used instead.

    +

    Example

    +SSLHonorCipherOrder on +

    + +
    +
    top
    +

    SSLMutex Directive

    + + + + + + + +
    Description:Semaphore for internal mutual exclusion of +operations
    Syntax:SSLMutex type
    Default:SSLMutex none
    Context:server config
    Status:Extension
    Module:mod_ssl
    +

    +This configures the SSL engine's semaphore (aka. lock) which is used for mutual +exclusion of operations which have to be done in a synchronized way between the +pre-forked Apache server processes. This directive can only be used in the +global server context because it's only useful to have one global mutex. +This directive is designed to closely match the +AcceptMutex directive

    +

    +The following Mutex types are available:

    +
      +
    • none | no +

      + This is the default where no Mutex is used at all. Use it at your own + risk. But because currently the Mutex is mainly used for synchronizing + write access to the SSL Session Cache you can live without it as long + as you accept a sometimes garbled Session Cache. So it's not recommended + to leave this the default. Instead configure a real Mutex.

    • +
    • posixsem +

      + This is an elegant Mutex variant where a Posix Semaphore is used when possible. + It is only available when the underlying platform + and APR supports it.

    • +
    • sysvsem +

      + This is a somewhat elegant Mutex variant where a SystemV IPC Semaphore is used when + possible. It is possible to "leak" SysV semaphores if processes crash before + the semaphore is removed. It is only available when the underlying platform + and APR supports it.

    • +
    • sem +

      + This directive tells the SSL Module to pick the "best" semaphore implementation + available to it, choosing between Posix and SystemV IPC, in that order. It is only + available when the underlying platform and APR supports at least one of the 2.

    • +
    • pthread +

      + This directive tells the SSL Module to use Posix thread mutexes. It is only available + if the underlying platform and APR supports it.

    • +
    • fcntl:/path/to/mutex +

      + This is a portable Mutex variant where a physical (lock-)file and the fcntl() + fucntion are used as the Mutex. + Always use a local disk filesystem for /path/to/mutex and never a file + residing on a NFS- or AFS-filesystem. It is only available when the underlying platform + and APR supports it. Note: Internally, the Process ID (PID) of the + Apache parent process is automatically appended to + /path/to/mutex to make it unique, so you don't have to worry + about conflicts yourself. Notice that this type of mutex is not available + under the Win32 environment. There you have to use the semaphore + mutex.

    • +
    • flock:/path/to/mutex +

      + This is similar to the fcntl:/path/to/mutex method with the + exception that the flock() function is used to provide file + locking. It is only available when the underlying platform + and APR supports it.

    • +
    • file:/path/to/mutex +

      + This directive tells the SSL Module to pick the "best" file locking implementation + available to it, choosing between fcntl and flock, + in that order. It is only available when the underlying platform and APR supports + at least one of the 2.

    • +
    • default | yes +

      + This directive tells the SSL Module to pick the default locking implementation + as determined by the platform and APR.

    • +
    +

    Example

    +SSLMutex file:/usr/local/apache/logs/ssl_mutex +

    + +
    +
    top
    +

    SSLOptions Directive

    + + + + + + + +
    Description:Configure various SSL engine run-time options
    Syntax:SSLOptions [+|-]option ...
    Context:server config, virtual host, directory, .htaccess
    Override:Options
    Status:Extension
    Module:mod_ssl
    +

    +This directive can be used to control various run-time options on a +per-directory basis. Normally, if multiple SSLOptions +could apply to a directory, then the most specific one is taken +completely; the options are not merged. However if all the +options on the SSLOptions directive are preceded by a +plus (+) or minus (-) symbol, the options +are merged. Any options preceded by a + are added to the +options currently in force, and any options preceded by a +- are removed from the options currently in force.

    +

    +The available options are:

    +
      +
    • StdEnvVars +

      + When this option is enabled, the standard set of SSL related CGI/SSI + environment variables are created. This per default is disabled for + performance reasons, because the information extraction step is a + rather expensive operation. So one usually enables this option for + CGI and SSI requests only.

      +
    • +
    • CompatEnvVars +

      + When this option is enabled, additional CGI/SSI environment variables are + created for backward compatibility to other Apache SSL solutions. Look in + the Compatibility chapter for details + on the particular variables generated.

      +
    • +
    • ExportCertData +

      + When this option is enabled, additional CGI/SSI environment variables are + created: SSL_SERVER_CERT, SSL_CLIENT_CERT and + SSL_CLIENT_CERT_CHAIN_n (with n = 0,1,2,..). + These contain the PEM-encoded X.509 Certificates of server and client for + the current HTTPS connection and can be used by CGI scripts for deeper + Certificate checking. Additionally all other certificates of the client + certificate chain are provided, too. This bloats up the environment a + little bit which is why you have to use this option to enable it on + demand.

      +
    • +
    • FakeBasicAuth +

      + When this option is enabled, the Subject Distinguished Name (DN) of the + Client X509 Certificate is translated into a HTTP Basic Authorization + username. This means that the standard Apache authentication methods can + be used for access control. The user name is just the Subject of the + Client's X509 Certificate (can be determined by running OpenSSL's + openssl x509 command: openssl x509 -noout -subject -in + certificate.crt). Note that no password is + obtained from the user. Every entry in the user file needs this password: + ``xxj31ZMTZzkVA'', which is the DES-encrypted version of the + word `password''. Those who live under MD5-based encryption + (for instance under FreeBSD or BSD/OS, etc.) should use the following MD5 + hash of the same word: ``$1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/''.

      +
    • +
    • StrictRequire +

      + This forces forbidden access when SSLRequireSSL or + SSLRequire successfully decided that access should be + forbidden. Usually the default is that in the case where a ``Satisfy + any'' directive is used, and other access restrictions are passed, + denial of access due to SSLRequireSSL or + SSLRequire is overridden (because that's how the Apache + Satisfy mechanism should work.) But for strict access restriction + you can use SSLRequireSSL and/or SSLRequire in + combination with an ``SSLOptions +StrictRequire''. Then an + additional ``Satisfy Any'' has no chance once mod_ssl has + decided to deny access.

      +
    • +
    • OptRenegotiate +

      + This enables optimized SSL connection renegotiation handling when SSL + directives are used in per-directory context. By default a strict + scheme is enabled where every per-directory reconfiguration of + SSL parameters causes a full SSL renegotiation handshake. When this + option is used mod_ssl tries to avoid unnecessary handshakes by doing more + granular (but still safe) parameter checks. Nevertheless these granular + checks sometimes maybe not what the user expects, so enable this on a + per-directory basis only, please.

      +
    • +
    +

    Example

    +SSLOptions +FakeBasicAuth -StrictRequire
    +<Files ~ "\.(cgi|shtml)$">
    + SSLOptions +StdEnvVars +CompatEnvVars -ExportCertData
    +<Files> +

    + +
    +
    top
    +

    SSLPassPhraseDialog Directive

    + + + + + + + +
    Description:Type of pass phrase dialog for encrypted private +keys
    Syntax:SSLPassPhraseDialog type
    Default:SSLPassPhraseDialog builtin
    Context:server config
    Status:Extension
    Module:mod_ssl
    +

    +When Apache starts up it has to read the various Certificate (see +SSLCertificateFile) and +Private Key (see SSLCertificateKeyFile) files of the +SSL-enabled virtual servers. Because for security reasons the Private +Key files are usually encrypted, mod_ssl needs to query the +administrator for a Pass Phrase in order to decrypt those files. This +query can be done in two ways which can be configured by +type:

    +
      +
    • builtin +

      + This is the default where an interactive terminal dialog occurs at startup + time just before Apache detaches from the terminal. Here the administrator + has to manually enter the Pass Phrase for each encrypted Private Key file. + Because a lot of SSL-enabled virtual hosts can be configured, the + following reuse-scheme is used to minimize the dialog: When a Private Key + file is encrypted, all known Pass Phrases (at the beginning there are + none, of course) are tried. If one of those known Pass Phrases succeeds no + dialog pops up for this particular Private Key file. If none succeeded, + another Pass Phrase is queried on the terminal and remembered for the next + round (where it perhaps can be reused).

      +

      + This scheme allows mod_ssl to be maximally flexible (because for N encrypted + Private Key files you can use N different Pass Phrases - but then + you have to enter all of them, of course) while minimizing the terminal + dialog (i.e. when you use a single Pass Phrase for all N Private Key files + this Pass Phrase is queried only once).

    • + +
    • |/path/to/program [args...] + +

      This mode allows an external program to be used which acts as a + pipe to a particular input device; the program is sent the standard + prompt text used for the builtin mode on + stdin, and is expected to write password strings on + stdout. If several passwords are needed (or an + incorrect password is entered), additional prompt text will be + written subsequent to the first password being returned, and more + passwords must then be written back.

    • + +
    • exec:/path/to/program +

      + Here an external program is configured which is called at startup for each + encrypted Private Key file. It is called with two arguments (the first is + of the form ``servername:portnumber'', the second is either + ``RSA'' or ``DSA''), which indicate for which + server and algorithm it has to print the corresponding Pass Phrase to + stdout. The intent is that this external program first runs + security checks to make sure that the system is not compromised by an + attacker, and only when these checks were passed successfully it provides + the Pass Phrase.

      +

      + Both these security checks, and the way the Pass Phrase is determined, can + be as complex as you like. Mod_ssl just defines the interface: an + executable program which provides the Pass Phrase on stdout. + Nothing more or less! So, if you're really paranoid about security, here + is your interface. Anything else has to be left as an exercise to the + administrator, because local security requirements are so different.

      +

      + The reuse-algorithm above is used here, too. In other words: The external + program is called only once per unique Pass Phrase.

    • +
    +

    Example

    +SSLPassPhraseDialog exec:/usr/local/apache/sbin/pp-filter +

    + +
    +
    top
    +

    SSLProtocol Directive

    + + + + + + + + +
    Description:Configure usable SSL protocol flavors
    Syntax:SSLProtocol [+|-]protocol ...
    Default:SSLProtocol all
    Context:server config, virtual host
    Override:Options
    Status:Extension
    Module:mod_ssl
    +

    +This directive can be used to control the SSL protocol flavors mod_ssl should +use when establishing its server environment. Clients then can only connect +with one of the provided protocols.

    +

    +The available (case-insensitive) protocols are:

    +
      +
    • SSLv2 +

      + This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the + original SSL protocol as designed by Netscape Corporation.

    • + +
    • SSLv3 +

      + This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the + successor to SSLv2 and the currently (as of February 1999) de-facto + standardized SSL protocol from Netscape Corporation. It's supported by + almost all popular browsers.

    • + +
    • TLSv1 +

      + This is the Transport Layer Security (TLS) protocol, version 1.0. It is the + successor to SSLv3 and currently (as of February 1999) still under + construction by the Internet Engineering Task Force (IETF). It's still + not supported by any popular browsers.

    • + +
    • All +

      + This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1'' and a + convinient way for enabling all protocols except one when used in + combination with the minus sign on a protocol as the example above + shows.

    • +
    +

    Example

    +# enable SSLv3 and TLSv1, but not SSLv2
    +SSLProtocol all -SSLv2 +

    + +
    +
    top
    +

    SSLProxyCACertificateFile Directive

    + + + + + + +
    Description:File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    Syntax:SSLProxyCACertificateFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the all-in-one file where you can assemble the +Certificates of Certification Authorities (CA) whose remote servers you deal +with. These are used for Remote Server Authentication. Such a file is simply the +concatenation of the various PEM-encoded Certificate files, in order of +preference. This can be used alternatively and/or additionally to +SSLProxyCACertificatePath.

    +

    Example

    +SSLProxyCACertificateFile /usr/local/apache2/conf/ssl.crt/ca-bundle-remote-server.crt +

    + +
    +
    top
    +

    SSLProxyCACertificatePath Directive

    + + + + + + +
    Description:Directory of PEM-encoded CA Certificates for +Remote Server Auth
    Syntax:SSLProxyCACertificatePath directory-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the directory where you keep the Certificates of +Certification Authorities (CAs) whose remote servers you deal with. These are used to +verify the remote server certificate on Remote Server Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named +hash-value.N. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +

    Example

    +SSLProxyCACertificatePath /usr/local/apache2/conf/ssl.crt/ +

    + +
    +
    top
    +

    SSLProxyCARevocationFile Directive

    + + + + + + +
    Description:File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    Syntax:SSLProxyCARevocationFile file-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the all-in-one file where you can +assemble the Certificate Revocation Lists (CRL) of Certification +Authorities (CA) whose remote servers you deal with. These are used +for Remote Server Authentication. Such a file is simply the concatenation of +the various PEM-encoded CRL files, in order of preference. This can be +used alternatively and/or additionally to SSLProxyCARevocationPath.

    +

    Example

    +SSLProxyCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-remote-server.crl +

    + +
    +
    top
    +

    SSLProxyCARevocationPath Directive

    + + + + + + +
    Description:Directory of PEM-encoded CA CRLs for +Remote Server Auth
    Syntax:SSLProxyCARevocationPath directory-path
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose remote servers you deal with. +These are used to revoke the remote server certificate on Remote Server Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +hash-value.rN. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +

    Example

    +SSLProxyCARevocationPath /usr/local/apache2/conf/ssl.crl/ +

    + +
    +
    top
    +

    SSLProxyCipherSuite Directive

    + + + + + + + + +
    Description:Cipher Suite available for negotiation in SSL +proxy handshake
    Syntax:SSLProxyCipherSuite cipher-spec
    Default:SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    Equivalent to SSLCipherSuite, but for the proxy connection. +Please refer to SSLCipherSuite +for additional information.

    + +
    +
    top
    +

    SSLProxyEngine Directive

    + + + + + + + +
    Description:SSL Proxy Engine Operation Switch
    Syntax:SSLProxyEngine on|off
    Default:SSLProxyEngine off
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive toggles the usage of the SSL/TLS Protocol Engine for proxy. This +is usually used inside a <VirtualHost> section to enable SSL/TLS for proxy +usage in a particular virtual host. By default the SSL/TLS Protocol Engine is +disabled for proxy image both for the main server and all configured virtual hosts.

    +

    Example

    +<VirtualHost _default_:443>
    +SSLProxyEngine on
    +...
    +</VirtualHost> +

    + +
    +
    top
    +

    SSLProxyMachineCertificateFile Directive

    + + + + + + + +
    Description:File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    Syntax:SSLProxyMachineCertificateFile filename
    Context:server config
    Override:Not applicable
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the all-in-one file where you keep the certificates and +keys used for authentication of the proxy server to remote servers. +

    +

    +This referenced file is simply the concatenation of the various PEM-encoded +certificate files, in order of preference. Use this directive alternatively +or additionally to SSLProxyMachineCertificatePath. +

    +
    +

    Currently there is no support for encrypted private keys

    +
    +

    Example

    +SSLProxyMachineCertificateFile /usr/local/apache2/conf/ssl.crt/proxy.pem +

    + +
    +
    top
    +

    SSLProxyMachineCertificatePath Directive

    + + + + + + + +
    Description:Directory of PEM-encoded client certificates and keys to be used by the proxy
    Syntax:SSLProxyMachineCertificatePath directory
    Context:server config
    Override:Not applicable
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the directory where you keep the certificates and +keys used for authentication of the proxy server to remote servers. +

    +

    The files in this directory must be PEM-encoded and are accessed through +hash filenames. Additionally, you must create symbolic links named +hash-value.N. And you should always make sure this +directory contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task. +

    +
    +

    Currently there is no support for encrypted private keys

    +
    +

    Example

    +SSLProxyMachineCertificatePath /usr/local/apache2/conf/proxy.crt/ +

    + +
    +
    top
    +

    SSLProxyProtocol Directive

    + + + + + + + + +
    Description:Configure usable SSL protocol flavors for proxy usage
    Syntax:SSLProxyProtocol [+|-]protocol ...
    Default:SSLProxyProtocol all
    Context:server config, virtual host
    Override:Options
    Status:Extension
    Module:mod_ssl
    + +

    +This directive can be used to control the SSL protocol flavors mod_ssl should +use when establishing its server environment for proxy . It will only connect +to servers using one of the provided protocols.

    +

    Please refer to SSLProtocol +for additional information. +

    + +
    +
    top
    +

    SSLProxyVerify Directive

    + + + + + + + + +
    Description:Type of remote server Certificate verification
    Syntax:SSLProxyVerify level
    Default:SSLProxyVerify none
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the Certificate verification level for the remote server +Authentication. Notice that this directive can be used both in per-server and +per-directory context. In per-server context it applies to the remote server +authentication process used in the standard SSL handshake when a connection is +established. In per-directory context it forces a SSL renegotation with the +reconfigured remote server verification level after the HTTP request was read but +before the HTTP response is sent.

    +

    +The following levels are available for level:

    +
      +
    • none: + no remote server Certificate is required at all
    • +
    • optional: + the remote server may present a valid Certificate
    • +
    • require: + the remote server has to present a valid Certificate
    • +
    • optional_no_ca: + the remote server may present a valid Certificate
      + but it need not to be (successfully) verifiable.
    • +
    +

    In practice only levels none and +require are really interesting, because level +optional doesn't work with all servers and level +optional_no_ca is actually against the idea of +authentication (but can be used to establish SSL test pages, etc.)

    +

    Example

    +SSLProxyVerify require +

    + +
    +
    top
    +

    SSLProxyVerifyDepth Directive

    + + + + + + + + +
    Description:Maximum depth of CA Certificates in Remote Server +Certificate verification
    Syntax:SSLProxyVerifyDepth number
    Default:SSLProxyVerifyDepth 1
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets how deeply mod_ssl should verify before deciding that the +remote server does not have a valid certificate. Notice that this directive can be +used both in per-server and per-directory context. In per-server context it +applies to the client authentication process used in the standard SSL +handshake when a connection is established. In per-directory context it forces +a SSL renegotation with the reconfigured remote server verification depth after the +HTTP request was read but before the HTTP response is sent.

    +

    +The depth actually is the maximum number of intermediate certificate issuers, +i.e. the number of CA certificates which are max allowed to be followed while +verifying the remote server certificate. A depth of 0 means that self-signed +remote server certificates are accepted only, the default depth of 1 means +the remote server certificate can be self-signed or has to be signed by a CA +which is directly known to the server (i.e. the CA's certificate is under +SSLProxyCACertificatePath), etc.

    +

    Example

    +SSLProxyVerifyDepth 10 +

    + +
    +
    top
    +

    SSLRandomSeed Directive

    + + + + + + +
    Description:Pseudo Random Number Generator (PRNG) seeding +source
    Syntax:SSLRandomSeed context source +[bytes]
    Context:server config
    Status:Extension
    Module:mod_ssl
    +

    +This configures one or more sources for seeding the Pseudo Random Number +Generator (PRNG) in OpenSSL at startup time (context is +startup) and/or just before a new SSL connection is established +(context is connect). This directive can only be used +in the global server context because the PRNG is a global facility.

    +

    +The following source variants are available:

    +
      +
    • builtin +

      This is the always available builtin seeding source. It's usage + consumes minimum CPU cycles under runtime and hence can be always used + without drawbacks. The source used for seeding the PRNG contains of the + current time, the current process id and (when applicable) a randomly + choosen 1KB extract of the inter-process scoreboard structure of Apache. + The drawback is that this is not really a strong source and at startup + time (where the scoreboard is still not available) this source just + produces a few bytes of entropy. So you should always, at least for the + startup, use an additional seeding source.

    • +
    • file:/path/to/source +

      + This variant uses an external file /path/to/source as the + source for seeding the PRNG. When bytes is specified, only the + first bytes number of bytes of the file form the entropy (and + bytes is given to /path/to/source as the first + argument). When bytes is not specified the whole file forms the + entropy (and 0 is given to /path/to/source as + the first argument). Use this especially at startup time, for instance + with an available /dev/random and/or + /dev/urandom devices (which usually exist on modern Unix + derivates like FreeBSD and Linux).

      +

      + But be careful: Usually /dev/random provides only as + much entropy data as it actually has, i.e. when you request 512 bytes of + entropy, but the device currently has only 100 bytes available two things + can happen: On some platforms you receive only the 100 bytes while on + other platforms the read blocks until enough bytes are available (which + can take a long time). Here using an existing /dev/urandom is + better, because it never blocks and actually gives the amount of requested + data. The drawback is just that the quality of the received data may not + be the best.

      +

      + On some platforms like FreeBSD one can even control how the entropy is + actually generated, i.e. by which system interrupts. More details one can + find under rndcontrol(8) on those platforms. Alternatively, when + your system lacks such a random device, you can use tool + like EGD + (Entropy Gathering Daemon) and run it's client program with the + exec:/path/to/program/ variant (see below) or use + egd:/path/to/egd-socket (see below).

    • + +
    • exec:/path/to/program +

      + This variant uses an external executable + /path/to/program as the source for seeding the + PRNG. When bytes is specified, only the first + bytes number of bytes of its stdout contents + form the entropy. When bytes is not specified, the + entirety of the data produced on stdout form the + entropy. Use this only at startup time when you need a very strong + seeding with the help of an external program (for instance as in + the example above with the truerand utility you can + find in the mod_ssl distribution which is based on the AT&T + truerand library). Using this in the connection context + slows down the server too dramatically, of course. So usually you + should avoid using external programs in that context.

    • +
    • egd:/path/to/egd-socket (Unix only) +

      + This variant uses the Unix domain socket of the + external Entropy Gathering Daemon (EGD) (see http://www.lothar.com/tech + /crypto/) to seed the PRNG. Use this if no random device exists + on your platform.

    • +
    +

    Example

    +SSLRandomSeed startup builtin
    +SSLRandomSeed startup file:/dev/random
    +SSLRandomSeed startup file:/dev/urandom 1024
    +SSLRandomSeed startup exec:/usr/local/bin/truerand 16
    +SSLRandomSeed connect builtin
    +SSLRandomSeed connect file:/dev/random
    +SSLRandomSeed connect file:/dev/urandom 1024
    +

    + +
    +
    top
    +

    SSLRequire Directive

    + + + + + + + +
    Description:Allow access only when an arbitrarily complex +boolean expression is true
    Syntax:SSLRequire expression
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive specifies a general access requirement which has to be +fulfilled in order to allow access. It's a very powerful directive because the +requirement specification is an arbitrarily complex boolean expression +containing any number of access checks.

    +
    +

    The implementation of SSLRequire is not thread safe. + Using SSLRequire inside .htaccess files + on a threaded MPM may cause random crashes. +

    +
    +

    +The expression must match the following syntax (given as a BNF +grammar notation):

    +
    +
    +expr     ::= "true" | "false"
    +           | "!" expr
    +           | expr "&&" expr
    +           | expr "||" expr
    +           | "(" expr ")"
    +           | comp
    +
    +comp     ::= word "==" word | word "eq" word
    +           | word "!=" word | word "ne" word
    +           | word "<"  word | word "lt" word
    +           | word "<=" word | word "le" word
    +           | word ">"  word | word "gt" word
    +           | word ">=" word | word "ge" word
    +           | word "in" "{" wordlist "}"
    +           | word "=~" regex
    +           | word "!~" regex
    +
    +wordlist ::= word
    +           | wordlist "," word
    +
    +word     ::= digit
    +           | cstring
    +           | variable
    +           | function
    +
    +digit    ::= [0-9]+
    +cstring  ::= "..."
    +variable ::= "%{" varname "}"
    +function ::= funcname "(" funcargs ")"
    +
    +
    +

    while for varname any variable from Table 3 can be used. Finally for +funcname the following functions are available:

    +
      +
    • file(filename) +

      + This function takes one string argument and expands to the contents of the + file. This is especially useful for matching this contents against a + regular expression, etc.

      +
    • +
    +

    Notice that expression is first parsed into an internal machine +representation and then evaluated in a second step. Actually, in Global and +Per-Server Class context expression is parsed at startup time and +at runtime only the machine representation is executed. For Per-Directory +context this is different: here expression has to be parsed and +immediately executed for every request.

    +

    Example

    +SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
    + and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
    + and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
    + and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
    + and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
    + or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +

    + +

    Standard CGI/1.0 and Apache variables:

    +
    +HTTP_USER_AGENT        PATH_INFO             AUTH_TYPE
    +HTTP_REFERER           QUERY_STRING          SERVER_SOFTWARE
    +HTTP_COOKIE            REMOTE_HOST           API_VERSION
    +HTTP_FORWARDED         REMOTE_IDENT          TIME_YEAR
    +HTTP_HOST              IS_SUBREQ             TIME_MON
    +HTTP_PROXY_CONNECTION  DOCUMENT_ROOT         TIME_DAY
    +HTTP_ACCEPT            SERVER_ADMIN          TIME_HOUR
    +HTTP:headername        SERVER_NAME           TIME_MIN
    +THE_REQUEST            SERVER_PORT           TIME_SEC
    +REQUEST_METHOD         SERVER_PROTOCOL       TIME_WDAY
    +REQUEST_SCHEME         REMOTE_ADDR           TIME
    +REQUEST_URI            REMOTE_USER           ENV:variablename
    +REQUEST_FILENAME
    +
    +

    SSL-related variables:

    +
    +HTTPS                  SSL_CLIENT_M_VERSION   SSL_SERVER_M_VERSION
    +                       SSL_CLIENT_M_SERIAL    SSL_SERVER_M_SERIAL
    +SSL_PROTOCOL           SSL_CLIENT_V_START     SSL_SERVER_V_START
    +SSL_SESSION_ID         SSL_CLIENT_V_END       SSL_SERVER_V_END
    +SSL_CIPHER             SSL_CLIENT_S_DN        SSL_SERVER_S_DN
    +SSL_CIPHER_EXPORT      SSL_CLIENT_S_DN_C      SSL_SERVER_S_DN_C
    +SSL_CIPHER_ALGKEYSIZE  SSL_CLIENT_S_DN_ST     SSL_SERVER_S_DN_ST
    +SSL_CIPHER_USEKEYSIZE  SSL_CLIENT_S_DN_L      SSL_SERVER_S_DN_L
    +SSL_VERSION_LIBRARY    SSL_CLIENT_S_DN_O      SSL_SERVER_S_DN_O
    +SSL_VERSION_INTERFACE  SSL_CLIENT_S_DN_OU     SSL_SERVER_S_DN_OU
    +                       SSL_CLIENT_S_DN_CN     SSL_SERVER_S_DN_CN
    +                       SSL_CLIENT_S_DN_T      SSL_SERVER_S_DN_T
    +                       SSL_CLIENT_S_DN_I      SSL_SERVER_S_DN_I
    +                       SSL_CLIENT_S_DN_G      SSL_SERVER_S_DN_G
    +                       SSL_CLIENT_S_DN_S      SSL_SERVER_S_DN_S
    +                       SSL_CLIENT_S_DN_D      SSL_SERVER_S_DN_D
    +                       SSL_CLIENT_S_DN_UID    SSL_SERVER_S_DN_UID
    +                       SSL_CLIENT_S_DN_Email  SSL_SERVER_S_DN_Email
    +                       SSL_CLIENT_I_DN        SSL_SERVER_I_DN
    +                       SSL_CLIENT_I_DN_C      SSL_SERVER_I_DN_C
    +                       SSL_CLIENT_I_DN_ST     SSL_SERVER_I_DN_ST
    +                       SSL_CLIENT_I_DN_L      SSL_SERVER_I_DN_L
    +                       SSL_CLIENT_I_DN_O      SSL_SERVER_I_DN_O
    +                       SSL_CLIENT_I_DN_OU     SSL_SERVER_I_DN_OU
    +                       SSL_CLIENT_I_DN_CN     SSL_SERVER_I_DN_CN
    +                       SSL_CLIENT_I_DN_T      SSL_SERVER_I_DN_T
    +                       SSL_CLIENT_I_DN_I      SSL_SERVER_I_DN_I
    +                       SSL_CLIENT_I_DN_G      SSL_SERVER_I_DN_G
    +                       SSL_CLIENT_I_DN_S      SSL_SERVER_I_DN_S
    +                       SSL_CLIENT_I_DN_D      SSL_SERVER_I_DN_D
    +                       SSL_CLIENT_I_DN_UID    SSL_SERVER_I_DN_UID
    +                       SSL_CLIENT_I_DN_Email  SSL_SERVER_I_DN_Email
    +                       SSL_CLIENT_A_SIG       SSL_SERVER_A_SIG
    +                       SSL_CLIENT_A_KEY       SSL_SERVER_A_KEY
    +                       SSL_CLIENT_CERT        SSL_SERVER_CERT
    +                       SSL_CLIENT_CERT_CHAIN_n
    +                       SSL_CLIENT_VERIFY
    +
    + +
    +
    top
    +

    SSLRequireSSL Directive

    + + + + + + + +
    Description:Deny access when SSL is not used for the +HTTP request
    Syntax:SSLRequireSSL
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive forbids access unless HTTP over SSL (i.e. HTTPS) is enabled for +the current connection. This is very handy inside the SSL-enabled virtual +host or directories for defending against configuration errors that expose +stuff that should be protected. When this directive is present all requests +are denied which are not using SSL.

    +

    Example

    +SSLRequireSSL +

    + +
    +
    top
    +

    SSLSessionCache Directive

    + + + + + + + +
    Description:Type of the global/inter-process SSL Session +Cache
    Syntax:SSLSessionCache type
    Default:SSLSessionCache none
    Context:server config
    Status:Extension
    Module:mod_ssl
    +

    +This configures the storage type of the global/inter-process SSL Session +Cache. This cache is an optional facility which speeds up parallel request +processing. For requests to the same server process (via HTTP keep-alive), +OpenSSL already caches the SSL session information locally. But because modern +clients request inlined images and other data via parallel requests (usually +up to four parallel requests are common) those requests are served by +different pre-forked server processes. Here an inter-process cache +helps to avoid unneccessary session handshakes.

    +

    +The following four storage types are currently supported:

    +
      +
    • none + +

      This disables the global/inter-process Session Cache. This + will incur a noticeable speed penalty and may cause problems if + using certain browsers, particularly if client certificates are + enabled. This setting is not recommended.

    • + +
    • dbm:/path/to/datafile + +

      This makes use of a DBM hashfile on the local disk to + synchronize the local OpenSSL memory caches of the server + processes. This session cache may suffer reliability issues under + high load.

    • + +
    • shm:/path/to/datafile[(size)] + +

      This makes use of a high-performance cyclic buffer + (approx. size bytes in size) inside a shared memory + segment in RAM (established via /path/to/datafile) to + synchronize the local OpenSSL memory caches of the server + processes. This is the recommended session cache.

    • + +
    • dc:UNIX:/path/to/socket + +

      This makes use of the distcache distributed session + caching libraries. The argument should specify the location of + the server or proxy to be used using the distcache address syntax; + for example, UNIX:/path/to/socket specifies a UNIX + domain socket (typically a local dc_client proxy); + IP:server.example.com:9001 specifies an IP + address.

    • + +
    +

    Examples

    +SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data
    +SSLSessionCache shm:/usr/local/apache/logs/ssl_gcache_data(512000) +

    + +
    +
    top
    +

    SSLSessionCacheTimeout Directive

    + + + + + + + +
    Description:Number of seconds before an SSL session expires +in the Session Cache
    Syntax:SSLSessionCacheTimeout seconds
    Default:SSLSessionCacheTimeout 300
    Context:server config, virtual host
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the timeout in seconds for the information stored in the +global/inter-process SSL Session Cache and the OpenSSL internal memory cache. +It can be set as low as 15 for testing, but should be set to higher +values like 300 in real life.

    +

    Example

    +SSLSessionCacheTimeout 600 +

    + +
    +
    top
    +

    SSLUserName Directive

    + + + + + + + + +
    Description:Variable name to determine user name
    Syntax:SSLUserName varname
    Context:server config, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    Compatibility:Available in Apache 2.0.51 and later
    +

    +This directive sets the "user" field in the Apache request object. +This is used by lower modules to identify the user with a character +string. In particular, this may cause the environment variable +REMOTE_USER to be set. The varname can be +any of the SSL environment variables.

    + +

    Note that this directive has no effect if the +FakeBasic option is used (see SSLOptions).

    + +

    Example

    +SSLUserName SSL_CLIENT_S_DN_CN +

    + +
    +
    top
    +

    SSLVerifyClient Directive

    + + + + + + + + +
    Description:Type of Client Certificate verification
    Syntax:SSLVerifyClient level
    Default:SSLVerifyClient none
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets the Certificate verification level for the Client +Authentication. Notice that this directive can be used both in per-server and +per-directory context. In per-server context it applies to the client +authentication process used in the standard SSL handshake when a connection is +established. In per-directory context it forces a SSL renegotation with the +reconfigured client verification level after the HTTP request was read but +before the HTTP response is sent.

    +

    +The following levels are available for level:

    +
      +
    • none: + no client Certificate is required at all
    • +
    • optional: + the client may present a valid Certificate
    • +
    • require: + the client has to present a valid Certificate
    • +
    • optional_no_ca: + the client may present a valid Certificate
      + but it need not to be (successfully) verifiable.
    • +
    +

    In practice only levels none and +require are really interesting, because level +optional doesn't work with all browsers and level +optional_no_ca is actually against the idea of +authentication (but can be used to establish SSL test pages, etc.)

    +

    Example

    +SSLVerifyClient require +

    + +
    +
    top
    +

    SSLVerifyDepth Directive

    + + + + + + + + +
    Description:Maximum depth of CA Certificates in Client +Certificate verification
    Syntax:SSLVerifyDepth number
    Default:SSLVerifyDepth 1
    Context:server config, virtual host, directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    +

    +This directive sets how deeply mod_ssl should verify before deciding that the +clients don't have a valid certificate. Notice that this directive can be +used both in per-server and per-directory context. In per-server context it +applies to the client authentication process used in the standard SSL +handshake when a connection is established. In per-directory context it forces +a SSL renegotation with the reconfigured client verification depth after the +HTTP request was read but before the HTTP response is sent.

    +

    +The depth actually is the maximum number of intermediate certificate issuers, +i.e. the number of CA certificates which are max allowed to be followed while +verifying the client certificate. A depth of 0 means that self-signed client +certificates are accepted only, the default depth of 1 means the client +certificate can be self-signed or has to be signed by a CA which is directly +known to the server (i.e. the CA's certificate is under +SSLCACertificatePath), etc.

    +

    Example

    +SSLVerifyDepth 10 +

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_ssl.xml b/trunk/docs/manual/mod/mod_ssl.xml new file mode 100644 index 0000000000..5c807b28ed --- /dev/null +++ b/trunk/docs/manual/mod/mod_ssl.xml @@ -0,0 +1,1679 @@ + + + + + + + + + +mod_ssl +Strong cryptography using the Secure Sockets +Layer (SSL) and Transport Layer Security (TLS) protocols +Extension +mod_ssl.c +ssl_module + + +

    This module provides SSL v2/v3 and TLS v1 support for the Apache +HTTP Server. It was contributed by Ralf S. Engeschall based on his +mod_ssl project and originally derived from work by Ben Laurie.

    + +

    This module relies on OpenSSL +to provide the cryptography engine.

    + +

    Further details, discussion, and examples are provided in the +SSL documentation.

    +
    + +
    Environment Variables + +

    This module provides a lot of SSL information as additional environment +variables to the SSI and CGI namespace. The generated variables are listed in +the table below. For backward compatibility the information can +be made available under different names, too. Look in the Compatibility chapter for details on the +compatibility variables.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Variable Name:Value Type:Description:
    HTTPS flag HTTPS is being used.
    SSL_PROTOCOL string The SSL protocol version (SSLv2, SSLv3, TLSv1)
    SSL_SESSION_ID string The hex-encoded SSL session id
    SSL_CIPHER string The cipher specification name
    SSL_CIPHER_EXPORT string true if cipher is an export cipher
    SSL_CIPHER_USEKEYSIZE number Number of cipher bits (actually used)
    SSL_CIPHER_ALGKEYSIZE number Number of cipher bits (possible)
    SSL_VERSION_INTERFACE string The mod_ssl program version
    SSL_VERSION_LIBRARY string The OpenSSL program version
    SSL_CLIENT_M_VERSION string The version of the client certificate
    SSL_CLIENT_M_SERIAL string The serial of the client certificate
    SSL_CLIENT_S_DN string Subject DN in client's certificate
    SSL_CLIENT_S_DN_x509 string Component of client's Subject DN
    SSL_CLIENT_I_DN string Issuer DN of client's certificate
    SSL_CLIENT_I_DN_x509 string Component of client's Issuer DN
    SSL_CLIENT_V_START string Validity of client's certificate (start time)
    SSL_CLIENT_V_END string Validity of client's certificate (end time)
    SSL_CLIENT_V_REMAIN string Number of days until client's certificate expires
    SSL_CLIENT_A_SIG string Algorithm used for the signature of client's certificate
    SSL_CLIENT_A_KEY string Algorithm used for the public key of client's certificate
    SSL_CLIENT_CERT string PEM-encoded client certificate
    SSL_CLIENT_CERT_CHAIN_n string PEM-encoded certificates in client certificate chain
    SSL_CLIENT_VERIFY string NONE, SUCCESS, GENEROUS or FAILED:reason
    SSL_SERVER_M_VERSION string The version of the server certificate
    SSL_SERVER_M_SERIAL string The serial of the server certificate
    SSL_SERVER_S_DN string Subject DN in server's certificate
    SSL_SERVER_S_DN_x509 string Component of server's Subject DN
    SSL_SERVER_I_DN string Issuer DN of server's certificate
    SSL_SERVER_I_DN_x509 string Component of server's Issuer DN
    SSL_SERVER_V_START string Validity of server's certificate (start time)
    SSL_SERVER_V_END string Validity of server's certificate (end time)
    SSL_SERVER_A_SIG string Algorithm used for the signature of server's certificate
    SSL_SERVER_A_KEY string Algorithm used for the public key of server's certificate
    SSL_SERVER_CERT string PEM-encoded server certificate
    + +

    x509 specifies a component of an X.509 DN; one of +C,ST,L,O,OU,CN,T,I,G,S,D,UID,Email. In Apache 2.1 and +later, x509 may also include a numeric _n +suffix. If the DN in question contains multiple attributes of the +same name, this suffix is used as an index to select a particular +attribute. For example, where the server certificate subject DN +included two OU fields, SSL_SERVER_S_DN_OU_0 and +SSL_SERVER_S_DN_OU_1 could be used to reference each.

    + +

    SSL_CLIENT_V_REMAIN is only available in version 2.1 +and later.

    + +
    + +
    Custom Log Formats + +

    When mod_ssl is built into Apache or at least +loaded (under DSO situation) additional functions exist for the Custom Log Format of +mod_log_config. First there is an +additional ``%{varname}x'' +eXtension format function which can be used to expand any variables +provided by any module, especially those provided by mod_ssl which can +you find in the above table.

    +

    +For backward compatibility there is additionally a special +``%{name}c'' cryptography format function +provided. Information about this function is provided in the Compatibility chapter.

    +Example +CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + +
    + + +SSLPassPhraseDialog +Type of pass phrase dialog for encrypted private +keys +SSLPassPhraseDialog type +SSLPassPhraseDialog builtin +server config + + +

    +When Apache starts up it has to read the various Certificate (see +SSLCertificateFile) and +Private Key (see SSLCertificateKeyFile) files of the +SSL-enabled virtual servers. Because for security reasons the Private +Key files are usually encrypted, mod_ssl needs to query the +administrator for a Pass Phrase in order to decrypt those files. This +query can be done in two ways which can be configured by +type:

    +
      +
    • builtin +

      + This is the default where an interactive terminal dialog occurs at startup + time just before Apache detaches from the terminal. Here the administrator + has to manually enter the Pass Phrase for each encrypted Private Key file. + Because a lot of SSL-enabled virtual hosts can be configured, the + following reuse-scheme is used to minimize the dialog: When a Private Key + file is encrypted, all known Pass Phrases (at the beginning there are + none, of course) are tried. If one of those known Pass Phrases succeeds no + dialog pops up for this particular Private Key file. If none succeeded, + another Pass Phrase is queried on the terminal and remembered for the next + round (where it perhaps can be reused).

      +

      + This scheme allows mod_ssl to be maximally flexible (because for N encrypted + Private Key files you can use N different Pass Phrases - but then + you have to enter all of them, of course) while minimizing the terminal + dialog (i.e. when you use a single Pass Phrase for all N Private Key files + this Pass Phrase is queried only once).

    • + +
    • |/path/to/program [args...] + +

      This mode allows an external program to be used which acts as a + pipe to a particular input device; the program is sent the standard + prompt text used for the builtin mode on + stdin, and is expected to write password strings on + stdout. If several passwords are needed (or an + incorrect password is entered), additional prompt text will be + written subsequent to the first password being returned, and more + passwords must then be written back.

    • + +
    • exec:/path/to/program +

      + Here an external program is configured which is called at startup for each + encrypted Private Key file. It is called with two arguments (the first is + of the form ``servername:portnumber'', the second is either + ``RSA'' or ``DSA''), which indicate for which + server and algorithm it has to print the corresponding Pass Phrase to + stdout. The intent is that this external program first runs + security checks to make sure that the system is not compromised by an + attacker, and only when these checks were passed successfully it provides + the Pass Phrase.

      +

      + Both these security checks, and the way the Pass Phrase is determined, can + be as complex as you like. Mod_ssl just defines the interface: an + executable program which provides the Pass Phrase on stdout. + Nothing more or less! So, if you're really paranoid about security, here + is your interface. Anything else has to be left as an exercise to the + administrator, because local security requirements are so different.

      +

      + The reuse-algorithm above is used here, too. In other words: The external + program is called only once per unique Pass Phrase.

    • +
    +Example +SSLPassPhraseDialog exec:/usr/local/apache/sbin/pp-filter + +
    +
    + + +SSLMutex +Semaphore for internal mutual exclusion of +operations +SSLMutex type +SSLMutex none +server config + + +

    +This configures the SSL engine's semaphore (aka. lock) which is used for mutual +exclusion of operations which have to be done in a synchronized way between the +pre-forked Apache server processes. This directive can only be used in the +global server context because it's only useful to have one global mutex. +This directive is designed to closely match the +AcceptMutex directive

    +

    +The following Mutex types are available:

    +
      +
    • none | no +

      + This is the default where no Mutex is used at all. Use it at your own + risk. But because currently the Mutex is mainly used for synchronizing + write access to the SSL Session Cache you can live without it as long + as you accept a sometimes garbled Session Cache. So it's not recommended + to leave this the default. Instead configure a real Mutex.

    • +
    • posixsem +

      + This is an elegant Mutex variant where a Posix Semaphore is used when possible. + It is only available when the underlying platform + and APR supports it.

    • +
    • sysvsem +

      + This is a somewhat elegant Mutex variant where a SystemV IPC Semaphore is used when + possible. It is possible to "leak" SysV semaphores if processes crash before + the semaphore is removed. It is only available when the underlying platform + and APR supports it.

    • +
    • sem +

      + This directive tells the SSL Module to pick the "best" semaphore implementation + available to it, choosing between Posix and SystemV IPC, in that order. It is only + available when the underlying platform and APR supports at least one of the 2.

    • +
    • pthread +

      + This directive tells the SSL Module to use Posix thread mutexes. It is only available + if the underlying platform and APR supports it.

    • +
    • fcntl:/path/to/mutex +

      + This is a portable Mutex variant where a physical (lock-)file and the fcntl() + fucntion are used as the Mutex. + Always use a local disk filesystem for /path/to/mutex and never a file + residing on a NFS- or AFS-filesystem. It is only available when the underlying platform + and APR supports it. Note: Internally, the Process ID (PID) of the + Apache parent process is automatically appended to + /path/to/mutex to make it unique, so you don't have to worry + about conflicts yourself. Notice that this type of mutex is not available + under the Win32 environment. There you have to use the semaphore + mutex.

    • +
    • flock:/path/to/mutex +

      + This is similar to the fcntl:/path/to/mutex method with the + exception that the flock() function is used to provide file + locking. It is only available when the underlying platform + and APR supports it.

    • +
    • file:/path/to/mutex +

      + This directive tells the SSL Module to pick the "best" file locking implementation + available to it, choosing between fcntl and flock, + in that order. It is only available when the underlying platform and APR supports + at least one of the 2.

    • +
    • default | yes +

      + This directive tells the SSL Module to pick the default locking implementation + as determined by the platform and APR.

    • +
    +Example +SSLMutex file:/usr/local/apache/logs/ssl_mutex + +
    +
    + + +SSLRandomSeed +Pseudo Random Number Generator (PRNG) seeding +source +SSLRandomSeed context source +[bytes] +server config + + +

    +This configures one or more sources for seeding the Pseudo Random Number +Generator (PRNG) in OpenSSL at startup time (context is +startup) and/or just before a new SSL connection is established +(context is connect). This directive can only be used +in the global server context because the PRNG is a global facility.

    +

    +The following source variants are available:

    +
      +
    • builtin +

      This is the always available builtin seeding source. It's usage + consumes minimum CPU cycles under runtime and hence can be always used + without drawbacks. The source used for seeding the PRNG contains of the + current time, the current process id and (when applicable) a randomly + choosen 1KB extract of the inter-process scoreboard structure of Apache. + The drawback is that this is not really a strong source and at startup + time (where the scoreboard is still not available) this source just + produces a few bytes of entropy. So you should always, at least for the + startup, use an additional seeding source.

    • +
    • file:/path/to/source +

      + This variant uses an external file /path/to/source as the + source for seeding the PRNG. When bytes is specified, only the + first bytes number of bytes of the file form the entropy (and + bytes is given to /path/to/source as the first + argument). When bytes is not specified the whole file forms the + entropy (and 0 is given to /path/to/source as + the first argument). Use this especially at startup time, for instance + with an available /dev/random and/or + /dev/urandom devices (which usually exist on modern Unix + derivates like FreeBSD and Linux).

      +

      + But be careful: Usually /dev/random provides only as + much entropy data as it actually has, i.e. when you request 512 bytes of + entropy, but the device currently has only 100 bytes available two things + can happen: On some platforms you receive only the 100 bytes while on + other platforms the read blocks until enough bytes are available (which + can take a long time). Here using an existing /dev/urandom is + better, because it never blocks and actually gives the amount of requested + data. The drawback is just that the quality of the received data may not + be the best.

      +

      + On some platforms like FreeBSD one can even control how the entropy is + actually generated, i.e. by which system interrupts. More details one can + find under rndcontrol(8) on those platforms. Alternatively, when + your system lacks such a random device, you can use tool + like EGD + (Entropy Gathering Daemon) and run it's client program with the + exec:/path/to/program/ variant (see below) or use + egd:/path/to/egd-socket (see below).

    • + +
    • exec:/path/to/program +

      + This variant uses an external executable + /path/to/program as the source for seeding the + PRNG. When bytes is specified, only the first + bytes number of bytes of its stdout contents + form the entropy. When bytes is not specified, the + entirety of the data produced on stdout form the + entropy. Use this only at startup time when you need a very strong + seeding with the help of an external program (for instance as in + the example above with the truerand utility you can + find in the mod_ssl distribution which is based on the AT&T + truerand library). Using this in the connection context + slows down the server too dramatically, of course. So usually you + should avoid using external programs in that context.

    • +
    • egd:/path/to/egd-socket (Unix only) +

      + This variant uses the Unix domain socket of the + external Entropy Gathering Daemon (EGD) (see http://www.lothar.com/tech + /crypto/) to seed the PRNG. Use this if no random device exists + on your platform.

    • +
    +Example +SSLRandomSeed startup builtin
    +SSLRandomSeed startup file:/dev/random
    +SSLRandomSeed startup file:/dev/urandom 1024
    +SSLRandomSeed startup exec:/usr/local/bin/truerand 16
    +SSLRandomSeed connect builtin
    +SSLRandomSeed connect file:/dev/random
    +SSLRandomSeed connect file:/dev/urandom 1024
    +
    +
    +
    + + +SSLSessionCache +Type of the global/inter-process SSL Session +Cache +SSLSessionCache type +SSLSessionCache none +server config + + +

    +This configures the storage type of the global/inter-process SSL Session +Cache. This cache is an optional facility which speeds up parallel request +processing. For requests to the same server process (via HTTP keep-alive), +OpenSSL already caches the SSL session information locally. But because modern +clients request inlined images and other data via parallel requests (usually +up to four parallel requests are common) those requests are served by +different pre-forked server processes. Here an inter-process cache +helps to avoid unneccessary session handshakes.

    +

    +The following four storage types are currently supported:

    +
      +
    • none + +

      This disables the global/inter-process Session Cache. This + will incur a noticeable speed penalty and may cause problems if + using certain browsers, particularly if client certificates are + enabled. This setting is not recommended.

    • + +
    • dbm:/path/to/datafile + +

      This makes use of a DBM hashfile on the local disk to + synchronize the local OpenSSL memory caches of the server + processes. This session cache may suffer reliability issues under + high load.

    • + +
    • shm:/path/to/datafile[(size)] + +

      This makes use of a high-performance cyclic buffer + (approx. size bytes in size) inside a shared memory + segment in RAM (established via /path/to/datafile) to + synchronize the local OpenSSL memory caches of the server + processes. This is the recommended session cache.

    • + +
    • dc:UNIX:/path/to/socket + +

      This makes use of the distcache distributed session + caching libraries. The argument should specify the location of + the server or proxy to be used using the distcache address syntax; + for example, UNIX:/path/to/socket specifies a UNIX + domain socket (typically a local dc_client proxy); + IP:server.example.com:9001 specifies an IP + address.

    • + +
    +Examples +SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data
    +SSLSessionCache shm:/usr/local/apache/logs/ssl_gcache_data(512000) +
    +
    +
    + + +SSLSessionCacheTimeout +Number of seconds before an SSL session expires +in the Session Cache +SSLSessionCacheTimeout seconds +SSLSessionCacheTimeout 300 +server config +virtual host + + +

    +This directive sets the timeout in seconds for the information stored in the +global/inter-process SSL Session Cache and the OpenSSL internal memory cache. +It can be set as low as 15 for testing, but should be set to higher +values like 300 in real life.

    +Example +SSLSessionCacheTimeout 600 + +
    +
    + + +SSLEngine +SSL Engine Operation Switch +SSLEngine on|off|optional +SSLEngine off +server config +virtual host + + +

    +This directive toggles the usage of the SSL/TLS Protocol Engine. This +is usually used inside a VirtualHost section to enable SSL/TLS for a +particular virtual host. By default the SSL/TLS Protocol Engine is +disabled for both the main server and all configured virtual hosts.

    +Example +<VirtualHost _default_:443>
    +SSLEngine on
    +...
    +</VirtualHost> +
    +

    New in Apache 2.1, SSLEngine can be set to +optional. This enables support for +RFC 2817, Upgrading to TLS +Within HTTP/1.1. At this time no web browsers support RFC 2817.

    +
    +
    + + +SSLProtocol +Configure usable SSL protocol flavors +SSLProtocol [+|-]protocol ... +SSLProtocol all +server config +virtual host +Options + + +

    +This directive can be used to control the SSL protocol flavors mod_ssl should +use when establishing its server environment. Clients then can only connect +with one of the provided protocols.

    +

    +The available (case-insensitive) protocols are:

    +
      +
    • SSLv2 +

      + This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the + original SSL protocol as designed by Netscape Corporation.

    • + +
    • SSLv3 +

      + This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the + successor to SSLv2 and the currently (as of February 1999) de-facto + standardized SSL protocol from Netscape Corporation. It's supported by + almost all popular browsers.

    • + +
    • TLSv1 +

      + This is the Transport Layer Security (TLS) protocol, version 1.0. It is the + successor to SSLv3 and currently (as of February 1999) still under + construction by the Internet Engineering Task Force (IETF). It's still + not supported by any popular browsers.

    • + +
    • All +

      + This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1'' and a + convinient way for enabling all protocols except one when used in + combination with the minus sign on a protocol as the example above + shows.

    • +
    +Example +# enable SSLv3 and TLSv1, but not SSLv2
    +SSLProtocol all -SSLv2 +
    +
    +
    + + +SSLCipherSuite +Cipher Suite available for negotiation in SSL +handshake +SSLCipherSuite cipher-spec +SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +server config +virtual host +directory +.htaccess +AuthConfig + + +

    +This complex directive uses a colon-separated cipher-spec string +consisting of OpenSSL cipher specifications to configure the Cipher Suite the +client is permitted to negotiate in the SSL handshake phase. Notice that this +directive can be used both in per-server and per-directory context. In +per-server context it applies to the standard SSL handshake when a connection +is established. In per-directory context it forces a SSL renegotation with the +reconfigured Cipher Suite after the HTTP request was read but before the HTTP +response is sent.

    +

    +An SSL cipher specification in cipher-spec is composed of 4 major +attributes plus a few extra minor ones:

    +
      +
    • Key Exchange Algorithm:
      + RSA or Diffie-Hellman variants. +
    • +
    • Authentication Algorithm:
      + RSA, Diffie-Hellman, DSS or none. +
    • +
    • Cipher/Encryption Algorithm:
      + DES, Triple-DES, RC4, RC2, IDEA or none. +
    • +
    • MAC Digest Algorithm:
      + MD5, SHA or SHA1. +
    • +
    +

    An SSL cipher can also be an export cipher and is either a SSLv2 or SSLv3/TLSv1 +cipher (here TLSv1 is equivalent to SSLv3). To specify which ciphers to use, +one can either specify all the Ciphers, one at a time, or use aliases to +specify the preference and order for the ciphers (see Table +1).

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Tag Description
    Key Exchange Algorithm:
    kRSA RSA key exchange
    kDHr Diffie-Hellman key exchange with RSA key
    kDHd Diffie-Hellman key exchange with DSA key
    kEDH Ephemeral (temp.key) Diffie-Hellman key exchange (no cert)
    Authentication Algorithm:
    aNULL No authentication
    aRSA RSA authentication
    aDSS DSS authentication
    aDH Diffie-Hellman authentication
    Cipher Encoding Algorithm:
    eNULL No encoding
    DES DES encoding
    3DES Triple-DES encoding
    RC4 RC4 encoding
    RC2 RC2 encoding
    IDEA IDEA encoding
    MAC Digest Algorithm:
    MD5 MD5 hash function
    SHA1 SHA1 hash function
    SHA SHA hash function
    Aliases:
    SSLv2 all SSL version 2.0 ciphers
    SSLv3 all SSL version 3.0 ciphers
    TLSv1 all TLS version 1.0 ciphers
    EXP all export ciphers
    EXPORT40 all 40-bit export ciphers only
    EXPORT56 all 56-bit export ciphers only
    LOW all low strength ciphers (no export, single DES)
    MEDIUM all ciphers with 128 bit encryption
    HIGH all ciphers using Triple-DES
    RSA all ciphers using RSA key exchange
    DH all ciphers using Diffie-Hellman key exchange
    EDH all ciphers using Ephemeral Diffie-Hellman key exchange
    ADH all ciphers using Anonymous Diffie-Hellman key exchange
    DSS all ciphers using DSS authentication
    NULL all ciphers using no encryption
    +

    +Now where this becomes interesting is that these can be put together +to specify the order and ciphers you wish to use. To speed this up +there are also aliases (SSLv2, SSLv3, TLSv1, EXP, LOW, MEDIUM, +HIGH) for certain groups of ciphers. These tags can be joined +together with prefixes to form the cipher-spec. Available +prefixes are:

    +
      +
    • none: add cipher to list
    • +
    • +: add ciphers to list and pull them to current location in list
    • +
    • -: remove cipher from list (can be added later again)
    • +
    • !: kill cipher from list completely (can not be added later again)
    • +
    +

    A simpler way to look at all of this is to use the ``openssl ciphers +-v'' command which provides a nice way to successively create the +correct cipher-spec string. The default cipher-spec string +is ``ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'' which +means the following: first, remove from consideration any ciphers that do not +authenticate, i.e. for SSL only the Anonymous Diffie-Hellman ciphers. Next, +use ciphers using RC4 and RSA. Next include the high, medium and then the low +security ciphers. Finally pull all SSLv2 and export ciphers to the +end of the list.

    + +
    +$ openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'
    +NULL-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=SHA1
    +NULL-MD5                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=MD5
    +EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
    +...                     ...               ...     ...           ...
    +EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
    +EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
    +EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
    +
    +
    +

    The complete list of particular RSA & DH ciphers for SSL is given in Table 2.

    +Example +SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cipher-Tag Protocol Key Ex. Auth. Enc. MAC Type
    RSA Ciphers:
    DES-CBC3-SHA SSLv3 RSA RSA 3DES(168) SHA1
    DES-CBC3-MD5 SSLv2 RSA RSA 3DES(168) MD5
    IDEA-CBC-SHA SSLv3 RSA RSA IDEA(128) SHA1
    RC4-SHA SSLv3 RSA RSA RC4(128) SHA1
    RC4-MD5 SSLv3 RSA RSA RC4(128) MD5
    IDEA-CBC-MD5 SSLv2 RSA RSA IDEA(128) MD5
    RC2-CBC-MD5 SSLv2 RSA RSA RC2(128) MD5
    RC4-MD5 SSLv2 RSA RSA RC4(128) MD5
    DES-CBC-SHA SSLv3 RSA RSA DES(56) SHA1
    RC4-64-MD5 SSLv2 RSA RSA RC4(64) MD5
    DES-CBC-MD5 SSLv2 RSA RSA DES(56) MD5
    EXP-DES-CBC-SHA SSLv3 RSA(512) RSA DES(40) SHA1 export
    EXP-RC2-CBC-MD5 SSLv3 RSA(512) RSA RC2(40) MD5 export
    EXP-RC4-MD5 SSLv3 RSA(512) RSA RC4(40) MD5 export
    EXP-RC2-CBC-MD5 SSLv2 RSA(512) RSA RC2(40) MD5 export
    EXP-RC4-MD5 SSLv2 RSA(512) RSA RC4(40) MD5 export
    NULL-SHA SSLv3 RSA RSA None SHA1
    NULL-MD5 SSLv3 RSA RSA None MD5
    Diffie-Hellman Ciphers:
    ADH-DES-CBC3-SHA SSLv3 DH None 3DES(168) SHA1
    ADH-DES-CBC-SHA SSLv3 DH None DES(56) SHA1
    ADH-RC4-MD5 SSLv3 DH None RC4(128) MD5
    EDH-RSA-DES-CBC3-SHA SSLv3 DH RSA 3DES(168) SHA1
    EDH-DSS-DES-CBC3-SHA SSLv3 DH DSS 3DES(168) SHA1
    EDH-RSA-DES-CBC-SHA SSLv3 DH RSA DES(56) SHA1
    EDH-DSS-DES-CBC-SHA SSLv3 DH DSS DES(56) SHA1
    EXP-EDH-RSA-DES-CBC-SHA SSLv3 DH(512) RSA DES(40) SHA1 export
    EXP-EDH-DSS-DES-CBC-SHA SSLv3 DH(512) DSS DES(40) SHA1 export
    EXP-ADH-DES-CBC-SHA SSLv3 DH(512) None DES(40) SHA1 export
    EXP-ADH-RC4-MD5 SSLv3 DH(512) None RC4(40) MD5 export
    +
    +
    + + +SSLCertificateFile +Server PEM-encoded X.509 Certificate file +SSLCertificateFile file-path +server config +virtual host + + +

    +This directive points to the PEM-encoded Certificate file for the server and +optionally also to the corresponding RSA or DSA Private Key file for it +(contained in the same file). If the contained Private Key is encrypted the +Pass Phrase dialog is forced at startup time. This directive can be used up to +two times (referencing different filenames) when both a RSA and a DSA based +server certificate is used in parallel.

    +Example +SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt + +
    +
    + + +SSLCertificateKeyFile +Server PEM-encoded Private Key file +SSLCertificateKeyFile file-path +server config +virtual host + + +

    +This directive points to the PEM-encoded Private Key file for the +server. If the Private Key is not combined with the Certificate in the +SSLCertificateFile, use this additional directive to +point to the file with the stand-alone Private Key. When +SSLCertificateFile is used and the file +contains both the Certificate and the Private Key this directive need +not be used. But we strongly discourage this practice. Instead we +recommend you to separate the Certificate and the Private Key. If the +contained Private Key is encrypted, the Pass Phrase dialog is forced +at startup time. This directive can be used up to two times +(referencing different filenames) when both a RSA and a DSA based +private key is used in parallel.

    +Example +SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key + +
    +
    + + +SSLCertificateChainFile +File of PEM-encoded Server CA Certificates +SSLCertificateChainFile file-path +server config +virtual host + + +

    +This directive sets the optional all-in-one file where you can +assemble the certificates of Certification Authorities (CA) which form the +certificate chain of the server certificate. This starts with the issuing CA +certificate of of the server certificate and can range up to the root CA +certificate. Such a file is simply the concatenation of the various +PEM-encoded CA Certificate files, usually in certificate chain order.

    +

    +This should be used alternatively and/or additionally to SSLCACertificatePath for explicitly +constructing the server certificate chain which is sent to the browser +in addition to the server certificate. It is especially useful to +avoid conflicts with CA certificates when using client +authentication. Because although placing a CA certificate of the +server certificate chain into SSLCACertificatePath has the same effect +for the certificate chain construction, it has the side-effect that +client certificates issued by this same CA certificate are also +accepted on client authentication. That's usually not one expect.

    +

    +But be careful: Providing the certificate chain works only if you are using a +single (either RSA or DSA) based server certificate. If you are +using a coupled RSA+DSA certificate pair, this will work only if actually both +certificates use the same certificate chain. Else the browsers will be +confused in this situation.

    +Example +SSLCertificateChainFile /usr/local/apache2/conf/ssl.crt/ca.crt + +
    +
    + + +SSLCACertificatePath +Directory of PEM-encoded CA Certificates for +Client Auth +SSLCACertificatePath directory-path +server config +virtual host + + +

    +This directive sets the directory where you keep the Certificates of +Certification Authorities (CAs) whose clients you deal with. These are used to +verify the client certificate on Client Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named +hash-value.N. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +Example +SSLCACertificatePath /usr/local/apache2/conf/ssl.crt/ + +
    +
    + + +SSLCACertificateFile +File of concatenated PEM-encoded CA Certificates +for Client Auth +SSLCACertificateFile file-path +server config +virtual host + + +

    +This directive sets the all-in-one file where you can assemble the +Certificates of Certification Authorities (CA) whose clients you deal +with. These are used for Client Authentication. Such a file is simply the +concatenation of the various PEM-encoded Certificate files, in order of +preference. This can be used alternatively and/or additionally to +SSLCACertificatePath.

    +Example +SSLCACertificateFile /usr/local/apache2/conf/ssl.crt/ca-bundle-client.crt + +
    +
    + + +SSLCADNRequestFile +File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names +SSLCADNRequestFile file-path +server config +virtual host + + +

    When a client certificate is requested by mod_ssl, a list of +acceptable Certificate Authority names is sent to the client +in the SSL handshake. These CA names can be used by the client to +select an appropriate client certificate out of those it has +available.

    + +

    If neither of the directives SSLCADNRequestPath or SSLCADNRequestFile are given, then the +set of acceptable CA names sent to the client is the names of all the +CA certificates given by the SSLCACertificateFile and SSLCACertificatePath directives; in other +words, the names of the CAs which will actually be used to verify the +client certificate.

    + +

    In some circumstances, it is useful to be able to send a set of +acceptable CA names which differs from the actual CAs used to verify +the client certificate - for example, if the client certificates are +signed by intermediate CAs. In such cases, SSLCADNRequestPath and/or SSLCADNRequestFile can be used; the +acceptable CA names are then taken from the complete set of +certificates in the directory and/or file specified by this pair of +directives.

    + +

    SSLCADNRequestFile must +specify an all-in-one file containing a concatenation of +PEM-encoded CA certificates.

    + +Example +SSLCADNRequestFile /usr/local/apache2/conf/ca-names.crt + +
    +
    + + +SSLCADNRequestPath +Directory of PEM-encoded CA Certificates for +defining acceptable CA names +SSLCADNRequestPath directory-path +server config +virtual host + + + +

    This optional directive can be used to specify the set of +acceptable CA names which will be sent to the client when a +client certificate is requested. See the SSLCADNRequestFile directive for more +details.

    + +

    The files in this directory have to be PEM-encoded and are accessed +through hash filenames. So usually you can't just place the +Certificate files there: you also have to create symbolic links named +hash-value.N. And you should always make sure +this directory contains the appropriate symbolic links. Use the +Makefile which comes with mod_ssl to accomplish this +task.

    +Example +SSLCADNRequestPath /usr/local/apache2/conf/ca-names.crt/ + +
    +
    + + +SSLCARevocationPath +Directory of PEM-encoded CA CRLs for +Client Auth +SSLCARevocationPath directory-path +server config +virtual host + + +

    +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose clients you deal with. +These are used to revoke the client certificate on Client Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +hash-value.rN. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +Example +SSLCARevocationPath /usr/local/apache2/conf/ssl.crl/ + +
    +
    + + +SSLCARevocationFile +File of concatenated PEM-encoded CA CRLs for +Client Auth +SSLCARevocationFile file-path +server config +virtual host + + +

    +This directive sets the all-in-one file where you can +assemble the Certificate Revocation Lists (CRL) of Certification +Authorities (CA) whose clients you deal with. These are used +for Client Authentication. Such a file is simply the concatenation of +the various PEM-encoded CRL files, in order of preference. This can be +used alternatively and/or additionally to SSLCARevocationPath.

    +Example +SSLCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-client.crl + +
    +
    + + +SSLVerifyClient +Type of Client Certificate verification +SSLVerifyClient level +SSLVerifyClient none +server config +virtual host +directory +.htaccess +AuthConfig + + +

    +This directive sets the Certificate verification level for the Client +Authentication. Notice that this directive can be used both in per-server and +per-directory context. In per-server context it applies to the client +authentication process used in the standard SSL handshake when a connection is +established. In per-directory context it forces a SSL renegotation with the +reconfigured client verification level after the HTTP request was read but +before the HTTP response is sent.

    +

    +The following levels are available for level:

    +
      +
    • none: + no client Certificate is required at all
    • +
    • optional: + the client may present a valid Certificate
    • +
    • require: + the client has to present a valid Certificate
    • +
    • optional_no_ca: + the client may present a valid Certificate
      + but it need not to be (successfully) verifiable.
    • +
    +

    In practice only levels none and +require are really interesting, because level +optional doesn't work with all browsers and level +optional_no_ca is actually against the idea of +authentication (but can be used to establish SSL test pages, etc.)

    +Example +SSLVerifyClient require + +
    +
    + + +SSLVerifyDepth +Maximum depth of CA Certificates in Client +Certificate verification +SSLVerifyDepth number +SSLVerifyDepth 1 +server config +virtual host +directory +.htaccess +AuthConfig + + +

    +This directive sets how deeply mod_ssl should verify before deciding that the +clients don't have a valid certificate. Notice that this directive can be +used both in per-server and per-directory context. In per-server context it +applies to the client authentication process used in the standard SSL +handshake when a connection is established. In per-directory context it forces +a SSL renegotation with the reconfigured client verification depth after the +HTTP request was read but before the HTTP response is sent.

    +

    +The depth actually is the maximum number of intermediate certificate issuers, +i.e. the number of CA certificates which are max allowed to be followed while +verifying the client certificate. A depth of 0 means that self-signed client +certificates are accepted only, the default depth of 1 means the client +certificate can be self-signed or has to be signed by a CA which is directly +known to the server (i.e. the CA's certificate is under +SSLCACertificatePath), etc.

    +Example +SSLVerifyDepth 10 + +
    +
    + + +SSLOptions +Configure various SSL engine run-time options +SSLOptions [+|-]option ... +server config +virtual host +directory +.htaccess +Options + + +

    +This directive can be used to control various run-time options on a +per-directory basis. Normally, if multiple SSLOptions +could apply to a directory, then the most specific one is taken +completely; the options are not merged. However if all the +options on the SSLOptions directive are preceded by a +plus (+) or minus (-) symbol, the options +are merged. Any options preceded by a + are added to the +options currently in force, and any options preceded by a +- are removed from the options currently in force.

    +

    +The available options are:

    +
      +
    • StdEnvVars +

      + When this option is enabled, the standard set of SSL related CGI/SSI + environment variables are created. This per default is disabled for + performance reasons, because the information extraction step is a + rather expensive operation. So one usually enables this option for + CGI and SSI requests only.

      +
    • +
    • CompatEnvVars +

      + When this option is enabled, additional CGI/SSI environment variables are + created for backward compatibility to other Apache SSL solutions. Look in + the Compatibility chapter for details + on the particular variables generated.

      +
    • +
    • ExportCertData +

      + When this option is enabled, additional CGI/SSI environment variables are + created: SSL_SERVER_CERT, SSL_CLIENT_CERT and + SSL_CLIENT_CERT_CHAIN_n (with n = 0,1,2,..). + These contain the PEM-encoded X.509 Certificates of server and client for + the current HTTPS connection and can be used by CGI scripts for deeper + Certificate checking. Additionally all other certificates of the client + certificate chain are provided, too. This bloats up the environment a + little bit which is why you have to use this option to enable it on + demand.

      +
    • +
    • FakeBasicAuth +

      + When this option is enabled, the Subject Distinguished Name (DN) of the + Client X509 Certificate is translated into a HTTP Basic Authorization + username. This means that the standard Apache authentication methods can + be used for access control. The user name is just the Subject of the + Client's X509 Certificate (can be determined by running OpenSSL's + openssl x509 command: openssl x509 -noout -subject -in + certificate.crt). Note that no password is + obtained from the user. Every entry in the user file needs this password: + ``xxj31ZMTZzkVA'', which is the DES-encrypted version of the + word `password''. Those who live under MD5-based encryption + (for instance under FreeBSD or BSD/OS, etc.) should use the following MD5 + hash of the same word: ``$1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/''.

      +
    • +
    • StrictRequire +

      + This forces forbidden access when SSLRequireSSL or + SSLRequire successfully decided that access should be + forbidden. Usually the default is that in the case where a ``Satisfy + any'' directive is used, and other access restrictions are passed, + denial of access due to SSLRequireSSL or + SSLRequire is overridden (because that's how the Apache + Satisfy mechanism should work.) But for strict access restriction + you can use SSLRequireSSL and/or SSLRequire in + combination with an ``SSLOptions +StrictRequire''. Then an + additional ``Satisfy Any'' has no chance once mod_ssl has + decided to deny access.

      +
    • +
    • OptRenegotiate +

      + This enables optimized SSL connection renegotiation handling when SSL + directives are used in per-directory context. By default a strict + scheme is enabled where every per-directory reconfiguration of + SSL parameters causes a full SSL renegotiation handshake. When this + option is used mod_ssl tries to avoid unnecessary handshakes by doing more + granular (but still safe) parameter checks. Nevertheless these granular + checks sometimes maybe not what the user expects, so enable this on a + per-directory basis only, please.

      +
    • +
    +Example +SSLOptions +FakeBasicAuth -StrictRequire
    +<Files ~ "\.(cgi|shtml)$">
    + SSLOptions +StdEnvVars +CompatEnvVars -ExportCertData
    +<Files> +
    +
    +
    + + +SSLRequireSSL +Deny access when SSL is not used for the +HTTP request +SSLRequireSSL +directory +.htaccess +AuthConfig + + +

    +This directive forbids access unless HTTP over SSL (i.e. HTTPS) is enabled for +the current connection. This is very handy inside the SSL-enabled virtual +host or directories for defending against configuration errors that expose +stuff that should be protected. When this directive is present all requests +are denied which are not using SSL.

    +Example +SSLRequireSSL + +
    +
    + + +SSLRequire +Allow access only when an arbitrarily complex +boolean expression is true +SSLRequire expression +directory +.htaccess +AuthConfig + + +

    +This directive specifies a general access requirement which has to be +fulfilled in order to allow access. It's a very powerful directive because the +requirement specification is an arbitrarily complex boolean expression +containing any number of access checks.

    + +

    The implementation of SSLRequire is not thread safe. + Using SSLRequire inside .htaccess files + on a threaded MPM may cause random crashes. +

    +
    +

    +The expression must match the following syntax (given as a BNF +grammar notation):

    +
    +
    +expr     ::= "true" | "false"
    +           | "!" expr
    +           | expr "&&" expr
    +           | expr "||" expr
    +           | "(" expr ")"
    +           | comp
    +
    +comp     ::= word "==" word | word "eq" word
    +           | word "!=" word | word "ne" word
    +           | word "<"  word | word "lt" word
    +           | word "<=" word | word "le" word
    +           | word ">"  word | word "gt" word
    +           | word ">=" word | word "ge" word
    +           | word "in" "{" wordlist "}"
    +           | word "=~" regex
    +           | word "!~" regex
    +
    +wordlist ::= word
    +           | wordlist "," word
    +
    +word     ::= digit
    +           | cstring
    +           | variable
    +           | function
    +
    +digit    ::= [0-9]+
    +cstring  ::= "..."
    +variable ::= "%{" varname "}"
    +function ::= funcname "(" funcargs ")"
    +
    +
    +

    while for varname any variable from Table 3 can be used. Finally for +funcname the following functions are available:

    +
      +
    • file(filename) +

      + This function takes one string argument and expands to the contents of the + file. This is especially useful for matching this contents against a + regular expression, etc.

      +
    • +
    +

    Notice that expression is first parsed into an internal machine +representation and then evaluated in a second step. Actually, in Global and +Per-Server Class context expression is parsed at startup time and +at runtime only the machine representation is executed. For Per-Directory +context this is different: here expression has to be parsed and +immediately executed for every request.

    +Example +SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
    + and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
    + and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
    + and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
    + and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
    + or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +
    + +

    Standard CGI/1.0 and Apache variables:

    +
    +HTTP_USER_AGENT        PATH_INFO             AUTH_TYPE
    +HTTP_REFERER           QUERY_STRING          SERVER_SOFTWARE
    +HTTP_COOKIE            REMOTE_HOST           API_VERSION
    +HTTP_FORWARDED         REMOTE_IDENT          TIME_YEAR
    +HTTP_HOST              IS_SUBREQ             TIME_MON
    +HTTP_PROXY_CONNECTION  DOCUMENT_ROOT         TIME_DAY
    +HTTP_ACCEPT            SERVER_ADMIN          TIME_HOUR
    +HTTP:headername        SERVER_NAME           TIME_MIN
    +THE_REQUEST            SERVER_PORT           TIME_SEC
    +REQUEST_METHOD         SERVER_PROTOCOL       TIME_WDAY
    +REQUEST_SCHEME         REMOTE_ADDR           TIME
    +REQUEST_URI            REMOTE_USER           ENV:variablename
    +REQUEST_FILENAME
    +
    +

    SSL-related variables:

    +
    +HTTPS                  SSL_CLIENT_M_VERSION   SSL_SERVER_M_VERSION
    +                       SSL_CLIENT_M_SERIAL    SSL_SERVER_M_SERIAL
    +SSL_PROTOCOL           SSL_CLIENT_V_START     SSL_SERVER_V_START
    +SSL_SESSION_ID         SSL_CLIENT_V_END       SSL_SERVER_V_END
    +SSL_CIPHER             SSL_CLIENT_S_DN        SSL_SERVER_S_DN
    +SSL_CIPHER_EXPORT      SSL_CLIENT_S_DN_C      SSL_SERVER_S_DN_C
    +SSL_CIPHER_ALGKEYSIZE  SSL_CLIENT_S_DN_ST     SSL_SERVER_S_DN_ST
    +SSL_CIPHER_USEKEYSIZE  SSL_CLIENT_S_DN_L      SSL_SERVER_S_DN_L
    +SSL_VERSION_LIBRARY    SSL_CLIENT_S_DN_O      SSL_SERVER_S_DN_O
    +SSL_VERSION_INTERFACE  SSL_CLIENT_S_DN_OU     SSL_SERVER_S_DN_OU
    +                       SSL_CLIENT_S_DN_CN     SSL_SERVER_S_DN_CN
    +                       SSL_CLIENT_S_DN_T      SSL_SERVER_S_DN_T
    +                       SSL_CLIENT_S_DN_I      SSL_SERVER_S_DN_I
    +                       SSL_CLIENT_S_DN_G      SSL_SERVER_S_DN_G
    +                       SSL_CLIENT_S_DN_S      SSL_SERVER_S_DN_S
    +                       SSL_CLIENT_S_DN_D      SSL_SERVER_S_DN_D
    +                       SSL_CLIENT_S_DN_UID    SSL_SERVER_S_DN_UID
    +                       SSL_CLIENT_S_DN_Email  SSL_SERVER_S_DN_Email
    +                       SSL_CLIENT_I_DN        SSL_SERVER_I_DN
    +                       SSL_CLIENT_I_DN_C      SSL_SERVER_I_DN_C
    +                       SSL_CLIENT_I_DN_ST     SSL_SERVER_I_DN_ST
    +                       SSL_CLIENT_I_DN_L      SSL_SERVER_I_DN_L
    +                       SSL_CLIENT_I_DN_O      SSL_SERVER_I_DN_O
    +                       SSL_CLIENT_I_DN_OU     SSL_SERVER_I_DN_OU
    +                       SSL_CLIENT_I_DN_CN     SSL_SERVER_I_DN_CN
    +                       SSL_CLIENT_I_DN_T      SSL_SERVER_I_DN_T
    +                       SSL_CLIENT_I_DN_I      SSL_SERVER_I_DN_I
    +                       SSL_CLIENT_I_DN_G      SSL_SERVER_I_DN_G
    +                       SSL_CLIENT_I_DN_S      SSL_SERVER_I_DN_S
    +                       SSL_CLIENT_I_DN_D      SSL_SERVER_I_DN_D
    +                       SSL_CLIENT_I_DN_UID    SSL_SERVER_I_DN_UID
    +                       SSL_CLIENT_I_DN_Email  SSL_SERVER_I_DN_Email
    +                       SSL_CLIENT_A_SIG       SSL_SERVER_A_SIG
    +                       SSL_CLIENT_A_KEY       SSL_SERVER_A_KEY
    +                       SSL_CLIENT_CERT        SSL_SERVER_CERT
    +                       SSL_CLIENT_CERT_CHAIN_n
    +                       SSL_CLIENT_VERIFY
    +
    +
    +
    + + +SSLProxyMachineCertificatePath +Directory of PEM-encoded client certificates and keys to be used by the proxy +SSLProxyMachineCertificatePath directory +server config +Not applicable + + +

    +This directive sets the directory where you keep the certificates and +keys used for authentication of the proxy server to remote servers. +

    +

    The files in this directory must be PEM-encoded and are accessed through +hash filenames. Additionally, you must create symbolic links named +hash-value.N. And you should always make sure this +directory contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task. +

    + +

    Currently there is no support for encrypted private keys

    +
    +Example +SSLProxyMachineCertificatePath /usr/local/apache2/conf/proxy.crt/ + +
    +
    + + + +SSLProxyMachineCertificateFile +File of concatenated PEM-encoded client certificates and keys to be used by the proxy +SSLProxyMachineCertificateFile filename +server config +Not applicable + + +

    +This directive sets the all-in-one file where you keep the certificates and +keys used for authentication of the proxy server to remote servers. +

    +

    +This referenced file is simply the concatenation of the various PEM-encoded +certificate files, in order of preference. Use this directive alternatively +or additionally to SSLProxyMachineCertificatePath. +

    + +

    Currently there is no support for encrypted private keys

    +
    +Example +SSLProxyMachineCertificateFile /usr/local/apache2/conf/ssl.crt/proxy.pem + +
    +
    + + +SSLProxyVerify +Type of remote server Certificate verification +SSLProxyVerify level +SSLProxyVerify none +server config +virtual host +directory +.htaccess +AuthConfig + + +

    +This directive sets the Certificate verification level for the remote server +Authentication. Notice that this directive can be used both in per-server and +per-directory context. In per-server context it applies to the remote server +authentication process used in the standard SSL handshake when a connection is +established. In per-directory context it forces a SSL renegotation with the +reconfigured remote server verification level after the HTTP request was read but +before the HTTP response is sent.

    +

    +The following levels are available for level:

    +
      +
    • none: + no remote server Certificate is required at all
    • +
    • optional: + the remote server may present a valid Certificate
    • +
    • require: + the remote server has to present a valid Certificate
    • +
    • optional_no_ca: + the remote server may present a valid Certificate
      + but it need not to be (successfully) verifiable.
    • +
    +

    In practice only levels none and +require are really interesting, because level +optional doesn't work with all servers and level +optional_no_ca is actually against the idea of +authentication (but can be used to establish SSL test pages, etc.)

    +Example +SSLProxyVerify require + +
    +
    + + +SSLProxyVerifyDepth +Maximum depth of CA Certificates in Remote Server +Certificate verification +SSLProxyVerifyDepth number +SSLProxyVerifyDepth 1 +server config +virtual host +directory +.htaccess +AuthConfig + + +

    +This directive sets how deeply mod_ssl should verify before deciding that the +remote server does not have a valid certificate. Notice that this directive can be +used both in per-server and per-directory context. In per-server context it +applies to the client authentication process used in the standard SSL +handshake when a connection is established. In per-directory context it forces +a SSL renegotation with the reconfigured remote server verification depth after the +HTTP request was read but before the HTTP response is sent.

    +

    +The depth actually is the maximum number of intermediate certificate issuers, +i.e. the number of CA certificates which are max allowed to be followed while +verifying the remote server certificate. A depth of 0 means that self-signed +remote server certificates are accepted only, the default depth of 1 means +the remote server certificate can be self-signed or has to be signed by a CA +which is directly known to the server (i.e. the CA's certificate is under +SSLProxyCACertificatePath), etc.

    +Example +SSLProxyVerifyDepth 10 + +
    +
    + + +SSLProxyEngine +SSL Proxy Engine Operation Switch +SSLProxyEngine on|off +SSLProxyEngine off +server config +virtual host + + +

    +This directive toggles the usage of the SSL/TLS Protocol Engine for proxy. This +is usually used inside a VirtualHost section to enable SSL/TLS for proxy +usage in a particular virtual host. By default the SSL/TLS Protocol Engine is +disabled for proxy image both for the main server and all configured virtual hosts.

    +Example +<VirtualHost _default_:443>
    +SSLProxyEngine on
    +...
    +</VirtualHost> +
    +
    +
    + + +SSLProxyProtocol +Configure usable SSL protocol flavors for proxy usage +SSLProxyProtocol [+|-]protocol ... +SSLProxyProtocol all +server config +virtual host +Options + + + +

    +This directive can be used to control the SSL protocol flavors mod_ssl should +use when establishing its server environment for proxy . It will only connect +to servers using one of the provided protocols.

    +

    Please refer to SSLProtocol +for additional information. +

    +
    +
    + + +SSLProxyCipherSuite +Cipher Suite available for negotiation in SSL +proxy handshake +SSLProxyCipherSuite cipher-spec +SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +server config +virtual host +directory +.htaccess +AuthConfig + +

    Equivalent to SSLCipherSuite, but for the proxy connection. +Please refer to SSLCipherSuite +for additional information.

    +
    + +
    + +SSLProxyCACertificatePath +Directory of PEM-encoded CA Certificates for +Remote Server Auth +SSLProxyCACertificatePath directory-path +server config +virtual host + + +

    +This directive sets the directory where you keep the Certificates of +Certification Authorities (CAs) whose remote servers you deal with. These are used to +verify the remote server certificate on Remote Server Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named +hash-value.N. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +Example +SSLProxyCACertificatePath /usr/local/apache2/conf/ssl.crt/ + +
    +
    + + +SSLProxyCACertificateFile +File of concatenated PEM-encoded CA Certificates +for Remote Server Auth +SSLProxyCACertificateFile file-path +server config +virtual host + + +

    +This directive sets the all-in-one file where you can assemble the +Certificates of Certification Authorities (CA) whose remote servers you deal +with. These are used for Remote Server Authentication. Such a file is simply the +concatenation of the various PEM-encoded Certificate files, in order of +preference. This can be used alternatively and/or additionally to +SSLProxyCACertificatePath.

    +Example +SSLProxyCACertificateFile /usr/local/apache2/conf/ssl.crt/ca-bundle-remote-server.crt + +
    +
    + + +SSLProxyCARevocationPath +Directory of PEM-encoded CA CRLs for +Remote Server Auth +SSLProxyCARevocationPath directory-path +server config +virtual host + + +

    +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose remote servers you deal with. +These are used to revoke the remote server certificate on Remote Server Authentication.

    +

    +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +hash-value.rN. And you should always make sure this directory +contains the appropriate symbolic links. Use the Makefile which +comes with mod_ssl to accomplish this task.

    +Example +SSLProxyCARevocationPath /usr/local/apache2/conf/ssl.crl/ + +
    +
    + + +SSLProxyCARevocationFile +File of concatenated PEM-encoded CA CRLs for +Remote Server Auth +SSLProxyCARevocationFile file-path +server config +virtual host + + +

    +This directive sets the all-in-one file where you can +assemble the Certificate Revocation Lists (CRL) of Certification +Authorities (CA) whose remote servers you deal with. These are used +for Remote Server Authentication. Such a file is simply the concatenation of +the various PEM-encoded CRL files, in order of preference. This can be +used alternatively and/or additionally to SSLProxyCARevocationPath.

    +Example +SSLProxyCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-remote-server.crl + +
    +
    + + +SSLUserName +Variable name to determine user name +SSLUserName varname +server config +directory +.htaccess +AuthConfig +Available in Apache 2.0.51 and later + + +

    +This directive sets the "user" field in the Apache request object. +This is used by lower modules to identify the user with a character +string. In particular, this may cause the environment variable +REMOTE_USER to be set. The varname can be +any of the SSL environment variables.

    + +

    Note that this directive has no effect if the +FakeBasic option is used (see SSLOptions).

    + +Example +SSLUserName SSL_CLIENT_S_DN_CN + +
    +
    + + +SSLHonorCipherOrder +Option to prefer the server's cipher preference order +SSLHonorCiperOrder flag +server config +virtual host +Available in Apache 2.1 and later, if using OpenSSL 0.9.7 or later + + +

    When choosing a cipher during an SSLv3 or TLSv1 handshake, normally +the client's preference is used. If this directive is enabled, the +server's preference will be used instead.

    +Example +SSLHonorCipherOrder on + +
    +
    + + +SSLCryptoDevice +Enable use of a cryptographic hardware accelerator +SSLCryptoDevice engine +SSLCryptoDevice builtin +server config +Available if mod_ssl is built using -DSSL_ENGINE_EXPERIMENTAL + + +

    +This directive enables use of a cryptographic hardware accelerator +board to offload some of the SSL processing overhead. This directive +can only be used if the SSL toolkit is built with "engine" support; +OpenSSL 0.9.7 and later releases have "engine" support by default, the +separate "-engine" releases of OpenSSL 0.9.6 must be used.

    + +

    To discover which engine names are supported, run the command +"openssl engine".

    + +Example +# For a Broadcom accelerator:
    +SSLCryptoDevice ubsec +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_ssl.xml.meta b/trunk/docs/manual/mod/mod_ssl.xml.meta new file mode 100644 index 0000000000..a91b3f6ea0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_ssl.xml.meta @@ -0,0 +1,11 @@ + + + + mod_ssl + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_status.html b/trunk/docs/manual/mod/mod_status.html new file mode 100644 index 0000000000..64e6ac3d25 --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.html @@ -0,0 +1,11 @@ +URI: mod_status.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_status.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_status.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_status.html.en b/trunk/docs/manual/mod/mod_status.html.en new file mode 100644 index 0000000000..2bf745f297 --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.html.en @@ -0,0 +1,162 @@ + + + +mod_status - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_status

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Provides information on server activity and +performance
    Status:Base
    Module Identifier:status_module
    Source File:mod_status.c
    +

    Summary

    + +

    The Status module allows a server administrator to find out + how well their server is performing. A HTML page is presented + that gives the current server statistics in an easily readable + form. If required this page can be made to automatically + refresh (given a compatible browser). Another page gives a + simple machine-readable list of the current server state.

    + +

    The details given are:

    + +
      +
    • The number of worker serving requests
    • + +
    • The number of idle worker
    • + +
    • The status of each worker, the number of requests that + worker has performed and the total number of bytes served by + the worker (*)
    • + +
    • A total number of accesses and byte count served (*)
    • + +
    • The time the server was started/restarted and the time it + has been running for
    • + +
    • Averages giving the number of requests per second, the + number of bytes served per second and the average number of + bytes per request (*)
    • + +
    • The current percentage CPU used by each worker and in + total by Apache (*)
    • + +
    • The current hosts and requests being processed (*)
    • +
    + +

    A compile-time option must be used to display the details + marked "(*)" as the instrumentation required for obtaining + these statistics does not exist within standard Apache.

    +
    + +
    top
    +
    +

    Enabling Status Support

    + + +

    To enable status reports only for browsers from the foo.com + domain add this code to your httpd.conf + configuration file

    +

    + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +

    + +

    You can now access server statistics by using a Web browser + to access the page + http://your.server.name/server-status

    +
    top
    +
    +

    Automatic Updates

    + + +

    You can get the status page to update itself automatically if + you have a browser that supports "refresh". Access the page + http://your.server.name/server-status?refresh=N to + refresh the page every N seconds.

    + +
    top
    +
    +

    Machine Readable Status File

    + + +

    A machine-readable version of the status file is available by + accessing the page + http://your.server.name/server-status?auto. This + is useful when automatically run, see the Perl program in the + /support directory of Apache, + log_server_status.

    + +
    + It should be noted that if mod_status is + compiled into the server, its handler capability is available + in all configuration files, including + per-directory files (e.g., + .htaccess). This may have security-related + ramifications for your site. +
    + +
    +
    top
    +

    ExtendedStatus Directive

    + + + + + + + + +
    Description:Keep track of extended status information for each +request
    Syntax:ExtendedStatus On|Off
    Default:ExtendedStatus Off
    Context:server config
    Status:Base
    Module:mod_status
    Compatibility:ExtendedStatus is only available in Apache 1.3.2 and +later.
    +

    This setting applies to the entire server, and cannot be + enabled or disabled on a virtualhost-by-virtualhost basis. + The collection of extended status information can slow down + the server.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_status.html.ja.euc-jp b/trunk/docs/manual/mod/mod_status.html.ja.euc-jp new file mode 100644 index 0000000000..819cf36779 --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.html.ja.euc-jp @@ -0,0 +1,154 @@ + + + +mod_status - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_status

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤Î³èÆ°¾õ¶·¤ÈÀ­Ç½¤Ë´Ø¤¹¤ë¾ðÊó¤òÄ󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:status_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_status.c
    +

    ³µÍ×

    + +

    ¤³¤Î Status ¥â¥¸¥å¡¼¥ë¤Ë¤è¤ê¥µ¡¼¥Ð´ÉÍý¼Ô¤Ï¥µ¡¼¥Ð¤¬¤É¤Î¤¯¤é¤¤ + ¤ÎÀ­Ç½¤ÇÆ°ºî¤·¤Æ¤¤¤ë¤«¤òÃΤ뤳¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¸½»þÅÀ¤Ç¤Î¥µ¡¼¥Ð¤ÎÅý·×¾ðÊó¤òÆɤߤ䤹¤¤·Á¼°¤Ç¸½¤·¤¿ HTML ¥Ú¡¼¥¸¤¬ + ɽ¼¨¤µ¤ì¤Þ¤¹¡£É¬ÍפǤ¢¤ì¤Ð¡¢¤³¤Î¥Ú¡¼¥¸¤Ï¼«Æ°Åª¤Ë¥ê¥Õ¥ì¥Ã¥·¥å¤µ¤»¤ë + ¤³¤È¤â¤Ç¤­¤Þ¤¹ (¸ß´¹À­¤Î¤¢¤ë¥Ö¥é¥¦¥¶¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç)¡£ + Ê̤ˡ¢¸½»þÅÀ¤Ç¤Î¥µ¡¼¥Ð¤Î¾õÂÖ¤òñ½ã¤Êµ¡³£Æɤ߼è¤ê²Äǽ¤Ê¥ê¥¹¥È¤Ç + ¸½¤¹¥Ú¡¼¥¸¤â¤¢¤ê¤Þ¤¹¡£

    + +

    ɽ¼¨¤µ¤ì¤ë¾ðÊó¤Ï:

    + +
      +
    • ¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤ë¥ï¡¼¥«¡¼¤Î¿ô
    • + +
    • ¥¢¥¤¥É¥ë (ÌõÃí: ¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤Ê¤¤) ¥ï¡¼¥«¡¼¤Î¿ô
    • + +
    • ³Æ¥ï¡¼¥«¡¼¤Î¾õÂÖ¡¢¥ï¡¼¥«¡¼¤¬°·¤Ã¤¿¥ê¥¯¥¨¥¹¥È¤Î¿ô¡¢ + ¥ï¡¼¥«¡¼¤¬Á÷¤Ã¤¿Áí¥Ð¥¤¥È¿ô (*)
    • + +
    • Áí¥¢¥¯¥»¥¹¿ô¤ÈÁí¥Ð¥¤¥È¿ô (*)
    • + +
    • ¥µ¡¼¥Ð¤¬µ¯Æ°¤â¤·¤¯¤ÏºÆµ¯Æ°¤µ¤ì¤¿»þ¹ï¤ÈÆ°ºî¤·¤Æ¤¤¤ë»þ´Ö
    • + +
    • Ê¿¶Ñ¤Î 1 É䢤¿¤ê¤Î¥ê¥¯¥¨¥¹¥È¿ô¡¢1 É䢤¿¤ê¤ÎÁ÷¤é¤ì¤¿¥Ð¥¤¥È¿ô¡¢ + ¥ê¥¯¥¨¥¹¥È¤¢¤¿¤ê¤Î¥Ð¥¤¥È¿ô (*)
    • + +
    • ³Æ¥ï¡¼¥«¡¼¤È Apache Á´ÂΤǻÈÍѤµ¤ì¤Æ¤¤¤ë CPU ¤Î³ä¹ç (*)
    • + +
    • ¸½»þÅÀ¤Î¥Û¥¹¥È¤È½èÍý¤µ¤ì¤Æ¤¤¤ë¥ê¥¯¥¨¥¹¥È (*)
    • +
    + +

    "(*)" ¤ÎÉÕ¤¤¤Æ¤¤¤ë¾ðÊó¤òɽ¼¨¤¹¤ë¤¿¤á¤Ë¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Î¥ª¥×¥·¥ç¥ó + ¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤ÎÅý·×¾ðÊó¤òÆÀ¤ë¤¿¤á¤ËɬÍ×¤Ê + ¥³¡¼¥É¤Ïɸ½à¤Î Apache ¤Ë¤Ï´Þ¤Þ¤ì¤Æ¤¤¤Þ¤»¤ó¡£

    +
    + +
    top
    +
    +

    Status ¤ò»ÈÍѲÄǽ¤Ë¤¹¤ë

    + + +

    foo.com ¥É¥á¥¤¥ó¤«¤é¤Î¥Ö¥é¥¦¥¶¤Î¤ß¤ËÂФ·¤Æ + ¥¹¥Æ¡¼¥¿¥¹¤ÎÊó¹ð¤ò»ÈÍѲÄǽ¤Ë¤¹¤ë¤Ë¤Ï + °Ê²¼¤Î¥³¡¼¥É¤ò httpd.conf ÀßÄê¥Õ¥¡¥¤¥ë¤ËÄɲä·¤Þ¤¹

    +

    + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +

    + +

    ¤³¤ì¤Ç¡¢¥µ¡¼¥Ð¤ÎÅý·×¾ðÊó¤ò¥¦¥§¥Ö¥Ö¥é¥¦¥¶¤ò»È¤Ã¤Æ + http://your.server.name/server-status ¤ò¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤Ë¤è¤ê + ÃΤ뤳¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    ¼«Æ°¹¹¿·

    + + +

    ¥Ö¥é¥¦¥¶¤¬¡Ö¥ê¥Õ¥ì¥·¥å¡×µ¡Ç½¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ì¤Ð¡¢¥¹¥Æ¡¼¥¿¥¹¥Ú¡¼¥¸¤ò + ¼«Æ°Åª¤Ë¹¹¿·¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£N ÉÃËè¤Ë¹¹¿·¤µ¤»¤ë¤¿¤á¤Ë¤Ï + http://your.server.name/server-status?refresh=N + ¤È¤¤¤¦¥Ú¡¼¥¸¤ò¥¢¥¯¥»¥¹¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    µ¡³£Æɤ߼è¤ê²Äǽ¤Ê¥¹¥Æ¡¼¥¿¥¹¥Õ¥¡¥¤¥ë

    + + +

    http://your.server.name/server-status?auto ¤ò + ¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢¥¹¥Æ¡¼¥¿¥¹¥Õ¥¡¥¤¥ë¤Îµ¡³£Æɤ߼è¤ê²Äǽ¤Ê¥Ð¡¼¥¸¥ç¥ó¤ò + ÆÀ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¼«Æ°Åª¤Ë¼Â¹Ô¤µ¤ì¤ë¤È¤­¤ËÊØÍø¤Ç¤¹¡£ + Apache ¤Î /support ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë + Perl ¥×¥í¥°¥é¥à log_server_status ¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£

    + +
    + mod_status ¤¬¥µ¡¼¥Ð¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë + ¾ì¹ç¡¢¥Ï¥ó¥É¥é¤Îµ¡Ç½¤Ï¥Ç¥£¥ì¥¯¥È¥êËè¤Î¥Õ¥¡¥¤¥ë + (¤¹¤Ê¤ï¤Á¡¢.htaccess) ¤â´Þ¤à¤¹¤Ù¤Æ¤Î + ÀßÄê¥Õ¥¡¥¤¥ë¤Ç»ÈÍѲÄǽ¤Ë¤Ê¤ë¤³¤È¤Ë¤ÏÃí°Õ¤ò¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¥µ¥¤¥È¤Ë¤è¤Ã¤Æ¤Ï¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë˾¤Þ¤·¤¯¤Ê¤¤·ë²Ì¤ò + ¤â¤¿¤é¤¹¤³¤È¤¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ +
    + +
    +
    top
    +

    ExtendedStatus ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:³Æ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ³ÈÄ¥¥¹¥Æ¡¼¥¿¥¹¾ðÊó¤òÊݸ¤¹¤ë
    ¹½Ê¸:ExtendedStatus On|Off
    ¥Ç¥Õ¥©¥ë¥È:ExtendedStatus Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_status
    ¸ß´¹À­:ExtendedStatus ¤Ï Apache 1.3.2 °Ê¹ß¤Ç¤Î¤ß»ÈÍѲÄǽ
    +

    ¤³¤ÎÀßÄê¤Ï¥µ¡¼¥ÐÁ´ÂΤËÂФ·¤ÆŬÍѤµ¤ì¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Ë + Êѹ¹¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£³ÈÄ¥¥¹¥Æ¡¼¥¿¥¹¾ðÊó¤Î¼ý½¸¤Ï¥µ¡¼¥Ð¤Î + Æ°ºî¤òÃÙ¤¯¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_status.html.ko.euc-kr b/trunk/docs/manual/mod/mod_status.html.ko.euc-kr new file mode 100644 index 0000000000..4c11d758db --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.html.ko.euc-kr @@ -0,0 +1,148 @@ + + + +mod_status - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_status

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + + +
    ¼³¸í:¼­¹ö È°µ¿°ú ¼º´É¿¡ ´ëÇÑ Á¤º¸¸¦ Á¦°øÇÑ´Ù
    »óÅÂ:Base
    ¸ðµâ¸í:status_module
    ¼Ò½ºÆÄÀÏ:mod_status.c
    +

    ¿ä¾à

    + +

    Status ¸ðµâÀº ¼­¹ö °ü¸®ÀÚ¿¡°Ô ¼­¹öÀÇ »óŸ¦ º¸¿©ÁØ´Ù. + ½±°Ô ÀÐÀ» ¼ö ÀÖ´Â HTML ÆäÀÌÁö·Î ÇöÀç ¼­¹öÅë°è¸¦ º¸¿©ÁØ´Ù. + ÇÊ¿äÇÏ´Ù¸é (Ç¥ÁØÀ» µû¸£´Â ºê¶ó¿ìÀú¿¡¼­) ÆäÀÌÁö¸¦ ÀÚµ¿À¸·Î + °»½ÅÇÒ ¼ö ÀÖ´Ù. ÇöÀç ¼­¹ö »óŸ¦ ÄÄÇ»ÅÍ°¡ ÀÐÀ» ¼ö ÀÖ´Â + °£´ÜÇÑ ¸ñ·ÏÀ¸·Î º¸¿©ÁÙ ¼öµµ ÀÖ´Ù.

    + +

    ¾Ë·ÁÁÖ´Â Á¤º¸´Â:

    + +
      +
    • ¿äûÀ» ¼­ºñ½ºÇÏ´Â workerÀÇ °³¼ö
    • + +
    • ½¬°í ÀÖ´Â(idle) workerÀÇ °³¼ö
    • + +
    • °¢ workerµéÀÇ »óÅÂ, worker°¡ ó¸®ÇÑ ¿äûÀÇ °³¼ö¿Í + worker°¡ ¼­ºñ½ºÇÑ Àüü ¹ÙÀÌÆ®¼ö (*)
    • + +
    • ÃÑ Á¢±Ù Ƚ¼ö¿Í ¼­ºñ½ºÇÑ ¹ÙÀÌÆ®¼ö (*)
    • + +
    • ¼­¹ö°¡ ½ÃÀÛȤÀº Àç½ÃÀÛÇÑ ½Ã°£°ú µ¿ÀÛÇÑ ½Ã°£
    • + +
    • ÃÊ´ç ¿äû¼ö Æò±Õ, ÃÊ´ç ¼­ºñ½ºÇÑ ¹ÙÀÌÆ®¼ö¿Í ¿äû´ç + ¹ÙÀÌÆ®¼ö Æò±Õ (*)
    • + +
    • ÇöÀç ¾ÆÆÄÄ¡ Àüü¿Í °¢ workerµéÀÇ CPU ºñÀ² (*)
    • + +
    • ÇöÀç ó¸®ÇÏ°í Àִ ȣ½ºÆ®¿Í ¿äû (*)
    • +
    + +

    Ç¥ÁØ ¾ÆÆÄÄ¡¿¡´Â "(*)"·Î Ç¥½ÃÇÑ Åë°è¸¦ ¾òÀ» ¼ö ¾ø´Ù. + ÀÌ Á¤º¸¸¦ º¸·Á¸é ÄÄÆÄÀϽà ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    +
    + +
    top
    +
    +

    Status »ç¿ëÇϱâ

    + + +

    foo.com µµ¸ÞÀο¡¼­ Á¢±ÙÇÑ ºê¶ó¿ìÀú¿¡°Ô¸¸ »óŸ¦ º¸¿©ÁÖ·Á¸é + httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù

    +

    + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +

    + +

    ÀÌÁ¦ À¥ºê¶ó¿ìÀú·Î + http://your.server.name/server-status ÆäÀÌÁö¿¡ + Á¢±ÙÇÏ¸é ¼­¹ö Åë°è¸¦ º¼ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ÀÚµ¿ °»½Å

    + + +

    ºê¶ó¿ìÀú°¡ "Àç°»½Å"À» Áö¿øÇÑ´Ù¸é status ÆäÀÌÁö¸¦ ÀÚµ¿À¸·Î + °»½ÅÇÒ ¼ö ÀÖ´Ù. N Ãʸ¶´Ù °»½ÅÇÏ·Á¸é + http://your.server.name/server-status?refresh=N + ÆäÀÌÁö¸¦ »ç¿ëÇ϶ó.

    + +
    top
    +
    +

    ÄÄÇ»ÅÍ°¡ ÀÐÀ» ¼ö ÀÖ´Â Status ÆÄÀÏ

    + + +

    http://your.server.name/server-status?auto¿¡¼­ + ÄÄÇ»ÅÍ°¡ ½±°Ô ÀÐÀ» ¼ö ÀÖ´Â status ÆÄÀÏÀ» ¾òÀ» ¼ö ÀÖ´Ù. ÀÌ + Çü½ÄÀº ¾ÆÆÄÄ¡ /support µð·ºÅ丮¿¡ ÀÖ´Â + log_server_status Perl ÇÁ·Î±×·¥°ú °°ÀÌ ÀÚµ¿À¸·Î + ½ÇÇàÇÏ´Â ÇÁ·Î±×·¥¿¡ À¯¿ëÇÏ´Ù.

    + +
    + mod_status¸¦ ¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀÏÇÏ¿´´Ù¸é µð·ºÅ丮º° ¼³Á¤ÆÄÀÏÀ» (¿¹¸¦ + µé¾î, .htaccess) Æ÷ÇÔÇÏ¿© ¸ðµç + ¼³Á¤ÆÄÀÏ¿¡¼­ Çڵ鷯¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ »çÀÌÆ®¿¡ + º¸¾È ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. +
    + +
    +
    top
    +

    ExtendedStatus Áö½Ã¾î

    + + + + + + + + +
    ¼³¸í:°¢ ¿äû¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ »óÅ Á¤º¸¸¦ ±â·ÏÇÑ´Ù
    ¹®¹ý:ExtendedStatus On|Off
    ±âº»°ª:ExtendedStatus Off
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤
    »óÅÂ:Base
    ¸ðµâ:mod_status
    Áö¿ø:ExtendedStatus´Â ¾ÆÆÄÄ¡ 1.3.2 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù.
    +

    ÀÌ ¼³Á¤Àº ¼­¹ö Àüü¿¡ Àû¿ëµÇ¸ç, °¡»óÈ£½ºÆ®º°·Î Å°°í ²ø + ¼ö ¾ø´Ù. ÀÚ¼¼ÇÑ »óÅ Á¤º¸¸¦ ¸ðÀ¸¸é ¼­¹ö°¡ ´À·ÁÁú ¼ö ÀÖ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_status.xml b/trunk/docs/manual/mod/mod_status.xml new file mode 100644 index 0000000000..f1bcb330f0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.xml @@ -0,0 +1,144 @@ + + + + + + + + + +mod_status +Provides information on server activity and +performance +Base +mod_status.c +status_module + + + +

    The Status module allows a server administrator to find out + how well their server is performing. A HTML page is presented + that gives the current server statistics in an easily readable + form. If required this page can be made to automatically + refresh (given a compatible browser). Another page gives a + simple machine-readable list of the current server state.

    + +

    The details given are:

    + +
      +
    • The number of worker serving requests
    • + +
    • The number of idle worker
    • + +
    • The status of each worker, the number of requests that + worker has performed and the total number of bytes served by + the worker (*)
    • + +
    • A total number of accesses and byte count served (*)
    • + +
    • The time the server was started/restarted and the time it + has been running for
    • + +
    • Averages giving the number of requests per second, the + number of bytes served per second and the average number of + bytes per request (*)
    • + +
    • The current percentage CPU used by each worker and in + total by Apache (*)
    • + +
    • The current hosts and requests being processed (*)
    • +
    + +

    A compile-time option must be used to display the details + marked "(*)" as the instrumentation required for obtaining + these statistics does not exist within standard Apache.

    +
    + +
    + Enabling Status Support + +

    To enable status reports only for browsers from the foo.com + domain add this code to your httpd.conf + configuration file

    + + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +
    + +

    You can now access server statistics by using a Web browser + to access the page + http://your.server.name/server-status

    +
    + +
    + + Automatic Updates +

    You can get the status page to update itself automatically if + you have a browser that supports "refresh". Access the page + http://your.server.name/server-status?refresh=N to + refresh the page every N seconds.

    + +
    + +
    + + Machine Readable Status File +

    A machine-readable version of the status file is available by + accessing the page + http://your.server.name/server-status?auto. This + is useful when automatically run, see the Perl program in the + /support directory of Apache, + log_server_status.

    + + + It should be noted that if mod_status is + compiled into the server, its handler capability is available + in all configuration files, including + per-directory files (e.g., + .htaccess). This may have security-related + ramifications for your site. + + +
    + + + +ExtendedStatus +Keep track of extended status information for each +request +ExtendedStatus On|Off +ExtendedStatus Off +server config +ExtendedStatus is only available in Apache 1.3.2 and +later. + + +

    This setting applies to the entire server, and cannot be + enabled or disabled on a virtualhost-by-virtualhost basis. + The collection of extended status information can slow down + the server.

    +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_status.xml.ja b/trunk/docs/manual/mod/mod_status.xml.ja new file mode 100644 index 0000000000..5504d1678c --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.xml.ja @@ -0,0 +1,135 @@ + + + + + + + + +mod_status +$B%5!<%P$N3hF0>u67$H@-G=$K4X$9$k>pJs$rDs6!$9$k(B +Base +mod_status.c +status_module + + + +

    $B$3$N(B Status $B%b%8%e!<%k$K$h$j%5!<%P4IM}pJs$rFI$_$d$9$$7A<0$G8=$7$?(B HTML $B%Z!<%8$,(B + $BI=<($5$l$^$9!#I,MW$G$"$l$P!"$3$N%Z!<%8$O<+F0E*$K%j%U%l%C%7%e$5$;$k(B + $B$3$H$b$G$-$^$9(B ($B8_49@-$N$"$k%V%i%&%6$r;HMQ$7$F$$$k>l9g(B)$B!#(B + $BJL$K!"8=;~E@$G$N%5!<%P$N>uBV$rC1=c$J5!3#FI$_ + +

    $BI=<($5$l$k>pJs$O(B:

    + +
      +
    • $B%j%/%(%9%H$r07$C$F$$$k%o!<%+!<$N?t(B
    • + +
    • $B%"%$%I%k(B ($BLuCm(B: $B%j%/%(%9%H$r07$C$F$$$J$$(B) $B%o!<%+!<$N?t(B
    • + +
    • $B3F%o!<%+!<$N>uBV!"%o!<%+!<$,07$C$?%j%/%(%9%H$N?t!"(B + $B%o!<%+!<$,Aw$C$?Am%P%$%H?t(B (*)
    • + +
    • $BAm%"%/%;%9?t$HAm%P%$%H?t(B (*)
    • + +
    • $B%5!<%P$,5/F0$b$7$/$O:F5/F0$5$l$?;~9o$HF0:n$7$F$$$k;~4V(B
    • + +
    • $BJ?6Q$N(B 1 $BIC$"$?$j$N%j%/%(%9%H?t!"(B1 $BIC$"$?$j$NAw$i$l$?%P%$%H?t!"(B + $B%j%/%(%9%H$"$?$j$N%P%$%H?t(B (*)
    • + +
    • $B3F%o!<%+!<$H(B Apache $BA4BN$G;HMQ$5$l$F$$$k(B CPU $B$N3d9g(B (*)
    • + +
    • $B8=;~E@$N%[%9%H$H=hM}$5$l$F$$$k%j%/%(%9%H(B (*)
    • +
    + +

    "(*)" $B$NIU$$$F$$$k>pJs$rI=<($9$k$?$a$K$O%3%s%Q%$%k;~$N%*%W%7%g%s(B + $B$r;HMQ$9$kI,MW$,$"$j$^$9!#$3$l$i$NE}7W>pJs$rF@$k$?$a$KI,MW$J(B + $B%3!<%I$OI8=`$N(B Apache $B$K$O4^$^$l$F$$$^$;$s!#(B

    +
    + +
    + Status $B$r;HMQ2DG=$K$9$k(B + +

    foo.com $B%I%a%$%s$+$i$N%V%i%&%6$N$_$KBP$7$F(B + $B%9%F!<%?%9$NJs9p$r;HMQ2DG=$K$9$k$K$O(B + $B0J2<$N%3!<%I$r(B httpd.conf $B@_Dj%U%!%$%k$KDI2C$7$^$9(B

    + + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +
    + +

    $B$3$l$G!"%5!<%P$NE}7W>pJs$r%&%'%V%V%i%&%6$r;H$C$F(B + http://your.server.name/server-status $B$r%"%/%;%9$9$k$3$H$K$h$j(B + $BCN$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B

    +
    + +
    + + $B<+F099?7(B +

    $B%V%i%&%6$,!V%j%U%l%7%e!W5!G=$r%5%]!<%H$7$F$$$l$P!"%9%F!<%?%9%Z!<%8$r(B + $B<+F0E*$K99?7$9$k$h$&$K$G$-$^$9!#(BN $BICKh$K99?7$5$;$k$?$a$K$O(B + http://your.server.name/server-status?refresh=N + $B$H$$$&%Z!<%8$r%"%/%;%9$7$F$/$@$5$$!#(B

    + +
    + +
    + + $B5!3#FI$_<h$j2DG=$J%9%F!<%?%9%U%!%$%k(B +

    http://your.server.name/server-status?auto $B$r(B + $B%"%/%;%9$9$k$3$H$K$h$j!"%9%F!<%?%9%U%!%$%k$N5!3#FI$_/support $B%G%#%l%/%H%j$K$"$k(B + Perl $B%W%m%0%i%`(B log_server_status $B$r8+$F$/$@$5$$!#(B

    + + + mod_status $B$,%5!<%P$KAH$_9~$^$l$F$$$k(B + $B>l9g!"%O%s%I%i$N5!G=$O%G%#%l%/%H%j(B$BKh(B$B$N%U%!%$%k(B + ($B$9$J$o$A(B$B!"(B.htaccess) $B$b4^$`(B$B$9$Y$F(B$B$N(B + $B@_Dj%U%!%$%k$G;HMQ2DG=$K$J$k$3$H$K$OCm0U$r$7$F$*$/I,MW$,$"$j$^$9!#(B + $B$3$l$O!"%5%$%H$K$h$C$F$O%;%-%e%j%F%#$K4X$9$kK>$^$7$/$J$$7k2L$r(B + $B$b$?$i$9$3$H$,$"$k$+$b$7$l$^$;$s!#(B + + +
    + + + +ExtendedStatus +$B3F%j%/%(%9%H$KBP$7$F3HD%%9%F!<%?%9>pJs$rJ]B8$9$k(B +ExtendedStatus On|Off +ExtendedStatus Off +server config +ExtendedStatus $B$O(B Apache 1.3.2 $B0J9_$G$N$_;HMQ2DG=(B + + +

    $B$3$N@_Dj$O%5!<%PA4BN$KBP$7$FE,MQ$5$l!"%P!<%A%c%k%[%9%HKh$K(B + $BJQ99$9$k$3$H$O$G$-$^$;$s!#3HD%%9%F!<%?%9>pJs$N<}=8$O%5!<%P$N(B + $BF0:n$rCY$/$9$k$3$H$,$"$j$^$9!#(B

    +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_status.xml.ko b/trunk/docs/manual/mod/mod_status.xml.ko new file mode 100644 index 0000000000..08ba7e2cb1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.xml.ko @@ -0,0 +1,130 @@ + + + + + + + + + +mod_status +¼­¹ö È°µ¿°ú ¼º´É¿¡ ´ëÇÑ Á¤º¸¸¦ Á¦°øÇÑ´Ù +Base +mod_status.c +status_module + + + +

    Status ¸ðµâÀº ¼­¹ö °ü¸®ÀÚ¿¡°Ô ¼­¹öÀÇ »óŸ¦ º¸¿©ÁØ´Ù. + ½±°Ô ÀÐÀ» ¼ö ÀÖ´Â HTML ÆäÀÌÁö·Î ÇöÀç ¼­¹öÅë°è¸¦ º¸¿©ÁØ´Ù. + ÇÊ¿äÇÏ´Ù¸é (Ç¥ÁØÀ» µû¸£´Â ºê¶ó¿ìÀú¿¡¼­) ÆäÀÌÁö¸¦ ÀÚµ¿À¸·Î + °»½ÅÇÒ ¼ö ÀÖ´Ù. ÇöÀç ¼­¹ö »óŸ¦ ÄÄÇ»ÅÍ°¡ ÀÐÀ» ¼ö ÀÖ´Â + °£´ÜÇÑ ¸ñ·ÏÀ¸·Î º¸¿©ÁÙ ¼öµµ ÀÖ´Ù.

    + +

    ¾Ë·ÁÁÖ´Â Á¤º¸´Â:

    + +
      +
    • ¿äûÀ» ¼­ºñ½ºÇÏ´Â workerÀÇ °³¼ö
    • + +
    • ½¬°í ÀÖ´Â(idle) workerÀÇ °³¼ö
    • + +
    • °¢ workerµéÀÇ »óÅÂ, worker°¡ ó¸®ÇÑ ¿äûÀÇ °³¼ö¿Í + worker°¡ ¼­ºñ½ºÇÑ Àüü ¹ÙÀÌÆ®¼ö (*)
    • + +
    • ÃÑ Á¢±Ù Ƚ¼ö¿Í ¼­ºñ½ºÇÑ ¹ÙÀÌÆ®¼ö (*)
    • + +
    • ¼­¹ö°¡ ½ÃÀÛȤÀº Àç½ÃÀÛÇÑ ½Ã°£°ú µ¿ÀÛÇÑ ½Ã°£
    • + +
    • ÃÊ´ç ¿äû¼ö Æò±Õ, ÃÊ´ç ¼­ºñ½ºÇÑ ¹ÙÀÌÆ®¼ö¿Í ¿äû´ç + ¹ÙÀÌÆ®¼ö Æò±Õ (*)
    • + +
    • ÇöÀç ¾ÆÆÄÄ¡ Àüü¿Í °¢ workerµéÀÇ CPU ºñÀ² (*)
    • + +
    • ÇöÀç ó¸®ÇÏ°í Àִ ȣ½ºÆ®¿Í ¿äû (*)
    • +
    + +

    Ç¥ÁØ ¾ÆÆÄÄ¡¿¡´Â "(*)"·Î Ç¥½ÃÇÑ Åë°è¸¦ ¾òÀ» ¼ö ¾ø´Ù. + ÀÌ Á¤º¸¸¦ º¸·Á¸é ÄÄÆÄÀϽà ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    +
    + +
    + Status »ç¿ëÇϱâ + +

    foo.com µµ¸ÞÀο¡¼­ Á¢±ÙÇÑ ºê¶ó¿ìÀú¿¡°Ô¸¸ »óŸ¦ º¸¿©ÁÖ·Á¸é + httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ Ãß°¡ÇÑ´Ù

    + + <Location /server-status>
    + SetHandler server-status
    +
    + Order Deny,Allow
    + Deny from all
    + Allow from .foo.com
    + </Location> +
    + +

    ÀÌÁ¦ À¥ºê¶ó¿ìÀú·Î + http://your.server.name/server-status ÆäÀÌÁö¿¡ + Á¢±ÙÇÏ¸é ¼­¹ö Åë°è¸¦ º¼ ¼ö ÀÖ´Ù.

    +
    + +
    + + ÀÚµ¿ °»½Å +

    ºê¶ó¿ìÀú°¡ "Àç°»½Å"À» Áö¿øÇÑ´Ù¸é status ÆäÀÌÁö¸¦ ÀÚµ¿À¸·Î + °»½ÅÇÒ ¼ö ÀÖ´Ù. N Ãʸ¶´Ù °»½ÅÇÏ·Á¸é + http://your.server.name/server-status?refresh=N + ÆäÀÌÁö¸¦ »ç¿ëÇ϶ó.

    + +
    + +
    + + ÄÄÇ»ÅÍ°¡ ÀÐÀ» ¼ö ÀÖ´Â Status ÆÄÀÏ +

    http://your.server.name/server-status?auto¿¡¼­ + ÄÄÇ»ÅÍ°¡ ½±°Ô ÀÐÀ» ¼ö ÀÖ´Â status ÆÄÀÏÀ» ¾òÀ» ¼ö ÀÖ´Ù. ÀÌ + Çü½ÄÀº ¾ÆÆÄÄ¡ /support µð·ºÅ丮¿¡ ÀÖ´Â + log_server_status Perl ÇÁ·Î±×·¥°ú °°ÀÌ ÀÚµ¿À¸·Î + ½ÇÇàÇÏ´Â ÇÁ·Î±×·¥¿¡ À¯¿ëÇÏ´Ù.

    + + + mod_status¸¦ ¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀÏÇÏ¿´´Ù¸é µð·ºÅ丮º° ¼³Á¤ÆÄÀÏÀ» (¿¹¸¦ + µé¾î, .htaccess) Æ÷ÇÔÇÏ¿© ¸ðµç + ¼³Á¤ÆÄÀÏ¿¡¼­ Çڵ鷯¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ »çÀÌÆ®¿¡ + º¸¾È ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. + + +
    + + + +ExtendedStatus +°¢ ¿äû¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ »óÅ Á¤º¸¸¦ ±â·ÏÇÑ´Ù +ExtendedStatus On|Off +ExtendedStatus Off +server config +ExtendedStatus´Â ¾ÆÆÄÄ¡ 1.3.2 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. + + +

    ÀÌ ¼³Á¤Àº ¼­¹ö Àüü¿¡ Àû¿ëµÇ¸ç, °¡»óÈ£½ºÆ®º°·Î Å°°í ²ø + ¼ö ¾ø´Ù. ÀÚ¼¼ÇÑ »óÅ Á¤º¸¸¦ ¸ðÀ¸¸é ¼­¹ö°¡ ´À·ÁÁú ¼ö ÀÖ´Ù.

    +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_status.xml.meta b/trunk/docs/manual/mod/mod_status.xml.meta new file mode 100644 index 0000000000..ac1faf4d3d --- /dev/null +++ b/trunk/docs/manual/mod/mod_status.xml.meta @@ -0,0 +1,13 @@ + + + + mod_status + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_suexec.html b/trunk/docs/manual/mod/mod_suexec.html new file mode 100644 index 0000000000..4be81b750b --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.html @@ -0,0 +1,11 @@ +URI: mod_suexec.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_suexec.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_suexec.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_suexec.html.en b/trunk/docs/manual/mod/mod_suexec.html.en new file mode 100644 index 0000000000..0c009008fc --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.html.en @@ -0,0 +1,80 @@ + + + +mod_suexec - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_suexec

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Allows CGI scripts to run as a specified user +and Group
    Status:Extension
    Module Identifier:suexec_module
    Source File:mod_suexec.c
    Compatibility:Available in Apache 2.0 and later
    +

    Summary

    + +

    This module, in combination with the suexec support program allows + CGI scripts to run as a specified user and Group.

    +
    +

    Directives

    + +

    See also

    +
    + +
    top
    +

    SuexecUserGroup Directive

    + + + + + + + +
    Description:User and group permissions for CGI programs
    Syntax:SuexecUserGroup User Group
    Context:server config, virtual host
    Status:Extension
    Module:mod_suexec
    Compatibility:SuexecUserGroup is only available in 2.0 and +later.
    +

    The SuexecUserGroup directive allows you + to specify a user and group for CGI programs to run as. Non-CGI + requests are still processes with the user specified in the User + directive. This directive replaces the Apache 1.3 configuration of + using the User and Group directives inside of VirtualHosts.

    + +

    Example

    + + SuexecUserGroup nobody nogroup +

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_suexec.html.ja.euc-jp b/trunk/docs/manual/mod/mod_suexec.html.ja.euc-jp new file mode 100644 index 0000000000..0ca50b58c1 --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.html.ja.euc-jp @@ -0,0 +1,79 @@ + + + +mod_suexec - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_suexec

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:»ØÄꤵ¤ì¤¿¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤Ç CGI ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:³ÈÄ¥
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:suexec_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_suexec.c
    ¸ß´¹À­:Apache 2.0 °Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤È suexec ¥µ¥Ý¡¼¥È¥×¥í¥°¥é¥à + ¤Ë¤è¤ê¡¢CGI ¥¹¥¯¥ê¥×¥È¤¬»ØÄꤵ¤ì¤¿¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤Ç + ¼Â¹Ô¤µ¤ì¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +

    »²¾È

    +
    + +
    top
    +

    SuexecUserGroup ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:CGI ¥×¥í¥°¥é¥à¤Î¥æ¡¼¥¶¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¡¢¥°¥ë¡¼¥×¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó
    ¹½Ê¸:SuexecUserGroup User Group
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:³ÈÄ¥
    ¥â¥¸¥å¡¼¥ë:mod_suexec
    ¸ß´¹À­:SuexecUserGroup ¤Ï 2.0 °Ê¹ß¤Ç¤Î¤ß»ÈÍѲÄǽ¡£
    +

    SuexecUserGroup ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï CGI ¥×¥í¥°¥é¥à + ¤¬¼Â¹Ô¤µ¤ì¤ë¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£CGI °Ê³°¤Î + ¥ê¥¯¥¨¥¹¥È¤Ï User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿¥æ¡¼¥¶¤Î¤Þ¤Þ¤Ç½èÍý¤µ¤ì¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache 1.3 ¤Ë¤ª¤±¤ë VirtualHosts ¤ÎÃæ¤Ç + User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È Group ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦ÍÑË¡¤ÎÂå¤ï¤ê¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + + SuexecUserGroup nobody nogroup +

    + + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_suexec.html.ko.euc-kr b/trunk/docs/manual/mod/mod_suexec.html.ko.euc-kr new file mode 100644 index 0000000000..b16a6a7ce2 --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.html.ko.euc-kr @@ -0,0 +1,81 @@ + + + +mod_suexec - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_suexec

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:CGI ½ºÅ©¸³Æ®¸¦ ƯÁ¤ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑÀ¸·Î ½ÇÇàÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:suexec_module
    ¼Ò½ºÆÄÀÏ:mod_suexec.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.0 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀº suexec Áö¿ø + ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ƯÁ¤ »ç¿ëÀÚ¿Í ±×·ì + ±ÇÇÑÀ¸·Î ½ÇÇàÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +

    Âü°í

    +
    + +
    top
    +

    SuexecUserGroup Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:CGI ÇÁ·Î±×·¥ÀÌ »ç¿ëÇÒ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑ
    ¹®¹ý:SuexecUserGroup User Group
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Extension
    ¸ðµâ:mod_suexec
    Áö¿ø:SuexecUserGroupÀº 2.0 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù.
    +

    SuexecUserGroup Áö½Ã¾î´Â CGI ÇÁ·Î±×·¥ÀÌ + »ç¿ëÇÒ »ç¿ëÀÚ¿Í ±×·ìÀ» ¼³Á¤ÇÑ´Ù. CGI°¡ ¾Æ´Ñ ¿äûÀº °è¼Ó + User Áö½Ã¾î·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ ó¸®ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ¾ÆÆÄÄ¡ + 1.3¿¡¼­ VirtualHost ¾È¿¡ »ç¿ëÇÑ User¿Í Group Áö½Ã¾î¸¦ + ´ëüÇÑ´Ù.

    + +

    ¿¹Á¦

    + + SuexecUserGroup nobody nogroup +

    + + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_suexec.xml b/trunk/docs/manual/mod/mod_suexec.xml new file mode 100644 index 0000000000..6a911e145b --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.xml @@ -0,0 +1,68 @@ + + + + + + + + + +mod_suexec +Allows CGI scripts to run as a specified user +and Group +Extension +mod_suexec.c +suexec_module +Available in Apache 2.0 and later + + + +

    This module, in combination with the + suexec support program allows + CGI scripts to run as a specified user and Group.

    +
    + +SuEXEC support + + + +SuexecUserGroup +User and group permissions for CGI programs +SuexecUserGroup User Group +server config +virtual host +SuexecUserGroup is only available in 2.0 and +later. + + +

    The SuexecUserGroup directive allows you + to specify a user and group for CGI programs to run as. Non-CGI + requests are still processes with the user specified in the User + directive. This directive replaces the Apache 1.3 configuration of + using the User and Group directives inside of VirtualHosts.

    + + + Example + SuexecUserGroup nobody nogroup + + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_suexec.xml.ja b/trunk/docs/manual/mod/mod_suexec.xml.ja new file mode 100644 index 0000000000..6d69bb76d3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.xml.ja @@ -0,0 +1,66 @@ + + + + + + + + + +mod_suexec +$B;XDj$5$l$?%f!<%6$H%0%k!<%W$G(B CGI $B%9%/%j%W%H$r +$B3HD%(B +mod_suexec.c +suexec_module +Apache 2.0 $B0J9_$G;HMQ2DG=(B + + + +

    $B$3$N%b%8%e!<%k$H(B suexec $B%5%]!<%H%W%m%0%i%`(B + $B$K$h$j!"(BCGI $B%9%/%j%W%H$,;XDj$5$l$?%f!<%6$H%0%k!<%W$G(B + $B +

    + +SuEXEC $B%5%]!<%H(B + + + +SuexecUserGroup +CGI $B%W%m%0%i%`$N%f!<%6%Q!<%_%C%7%g%s!"%0%k!<%W%Q!<%_%C%7%g%s(B +SuexecUserGroup User Group +server config +virtual host +SuexecUserGroup $B$O(B 2.0 $B0J9_$G$N$_;HMQ2DG=!#(B + + +

    SuexecUserGroup $B%G%#%l%/%F%#%V$O(B CGI $B%W%m%0%i%`(B + $B$, + + + $BNc(B + SuexecUserGroup nobody nogroup + + + + + + + diff --git a/trunk/docs/manual/mod/mod_suexec.xml.ko b/trunk/docs/manual/mod/mod_suexec.xml.ko new file mode 100644 index 0000000000..806aab0afa --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.xml.ko @@ -0,0 +1,66 @@ + + + + + + + + + +mod_suexec +CGI ½ºÅ©¸³Æ®¸¦ ƯÁ¤ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑÀ¸·Î ½ÇÇàÇÑ´Ù +Extension +mod_suexec.c +suexec_module +¾ÆÆÄÄ¡ 2.0 ÀÌÈĺÎÅÍ + + +

    +

    ÀÌ ¸ðµâÀº suexec Áö¿ø + ÇÁ·Î±×·¥À» »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ®¸¦ ƯÁ¤ »ç¿ëÀÚ¿Í ±×·ì + ±ÇÇÑÀ¸·Î ½ÇÇàÇÑ´Ù.

    +
    + +SuEXEC Áö¿ø + + + +SuexecUserGroup +CGI ÇÁ·Î±×·¥ÀÌ »ç¿ëÇÒ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑ +SuexecUserGroup User Group +server config +virtual host +SuexecUserGroupÀº 2.0 ÀÌÈÄ¿¡¸¸ ÀÖ´Ù. + + +

    SuexecUserGroup Áö½Ã¾î´Â CGI ÇÁ·Î±×·¥ÀÌ + »ç¿ëÇÒ »ç¿ëÀÚ¿Í ±×·ìÀ» ¼³Á¤ÇÑ´Ù. CGI°¡ ¾Æ´Ñ ¿äûÀº °è¼Ó + User Áö½Ã¾î·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ ó¸®ÇÑ´Ù. ÀÌ Áö½Ã¾î´Â ¾ÆÆÄÄ¡ + 1.3¿¡¼­ VirtualHost ¾È¿¡ »ç¿ëÇÑ User¿Í Group Áö½Ã¾î¸¦ + ´ëüÇÑ´Ù.

    + + + ¿¹Á¦ + SuexecUserGroup nobody nogroup + + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_suexec.xml.meta b/trunk/docs/manual/mod/mod_suexec.xml.meta new file mode 100644 index 0000000000..2da62bb81e --- /dev/null +++ b/trunk/docs/manual/mod/mod_suexec.xml.meta @@ -0,0 +1,13 @@ + + + + mod_suexec + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_unique_id.html b/trunk/docs/manual/mod/mod_unique_id.html new file mode 100644 index 0000000000..1dae85cfd3 --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.html @@ -0,0 +1,11 @@ +URI: mod_unique_id.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_unique_id.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_unique_id.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_unique_id.html.en b/trunk/docs/manual/mod/mod_unique_id.html.en new file mode 100644 index 0000000000..8c8da6d930 --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.html.en @@ -0,0 +1,216 @@ + + + +mod_unique_id - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_unique_id

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:Provides an environment variable with a unique +identifier for each request
    Status:Extension
    Module Identifier:unique_id_module
    Source File:mod_unique_id.c
    +

    Summary

    + + +

    This module provides a magic token for each request which is + guaranteed to be unique across "all" requests under very + specific conditions. The unique identifier is even unique + across multiple machines in a properly configured cluster of + machines. The environment variable UNIQUE_ID is + set to the identifier for each request. Unique identifiers are + useful for various reasons which are beyond the scope of this + document.

    +
    +

    Directives

    +

    This module provides no + directives.

    +

    Topics

    +
    +
    top
    +
    +

    Theory

    + + +

    First a brief recap of how the Apache server works on Unix + machines. This feature currently isn't supported on Windows NT. + On Unix machines, Apache creates several children, the children + process requests one at a time. Each child can serve multiple + requests in its lifetime. For the purpose of this discussion, + the children don't share any data with each other. We'll refer + to the children as httpd processes.

    + +

    Your website has one or more machines under your + administrative control, together we'll call them a cluster of + machines. Each machine can possibly run multiple instances of + Apache. All of these collectively are considered "the + universe", and with certain assumptions we'll show that in this + universe we can generate unique identifiers for each request, + without extensive communication between machines in the + cluster.

    + +

    The machines in your cluster should satisfy these + requirements. (Even if you have only one machine you should + synchronize its clock with NTP.)

    + +
      +
    • The machines' times are synchronized via NTP or other + network time protocol.
    • + +
    • The machines' hostnames all differ, such that the module + can do a hostname lookup on the hostname and receive a + different IP address for each machine in the cluster.
    • +
    + +

    As far as operating system assumptions go, we assume that + pids (process ids) fit in 32-bits. If the operating system uses + more than 32-bits for a pid, the fix is trivial but must be + performed in the code.

    + +

    Given those assumptions, at a single point in time we can + identify any httpd process on any machine in the cluster from + all other httpd processes. The machine's IP address and the pid + of the httpd process are sufficient to do this. So in order to + generate unique identifiers for requests we need only + distinguish between different points in time.

    + +

    To distinguish time we will use a Unix timestamp (seconds + since January 1, 1970 UTC), and a 16-bit counter. The timestamp + has only one second granularity, so the counter is used to + represent up to 65536 values during a single second. The + quadruple ( ip_addr, pid, time_stamp, counter ) is + sufficient to enumerate 65536 requests per second per httpd + process. There are issues however with pid reuse over time, and + the counter is used to alleviate this issue.

    + +

    When an httpd child is created, the counter is initialized + with ( current microseconds divided by 10 ) modulo 65536 (this + formula was chosen to eliminate some variance problems with the + low order bits of the microsecond timers on some systems). When + a unique identifier is generated, the time stamp used is the + time the request arrived at the web server. The counter is + incremented every time an identifier is generated (and allowed + to roll over).

    + +

    The kernel generates a pid for each process as it forks the + process, and pids are allowed to roll over (they're 16-bits on + many Unixes, but newer systems have expanded to 32-bits). So + over time the same pid will be reused. However unless it is + reused within the same second, it does not destroy the + uniqueness of our quadruple. That is, we assume the system does + not spawn 65536 processes in a one second interval (it may even + be 32768 processes on some Unixes, but even this isn't likely + to happen).

    + +

    Suppose that time repeats itself for some reason. That is, + suppose that the system's clock is screwed up and it revisits a + past time (or it is too far forward, is reset correctly, and + then revisits the future time). In this case we can easily show + that we can get pid and time stamp reuse. The choice of + initializer for the counter is intended to help defeat this. + Note that we really want a random number to initialize the + counter, but there aren't any readily available numbers on most + systems (i.e., you can't use rand() because you need + to seed the generator, and can't seed it with the time because + time, at least at one second resolution, has repeated itself). + This is not a perfect defense.

    + +

    How good a defense is it? Suppose that one of your machines + serves at most 500 requests per second (which is a very + reasonable upper bound at this writing, because systems + generally do more than just shovel out static files). To do + that it will require a number of children which depends on how + many concurrent clients you have. But we'll be pessimistic and + suppose that a single child is able to serve 500 requests per + second. There are 1000 possible starting counter values such + that two sequences of 500 requests overlap. So there is a 1.5% + chance that if time (at one second resolution) repeats itself + this child will repeat a counter value, and uniqueness will be + broken. This was a very pessimistic example, and with real + world values it's even less likely to occur. If your system is + such that it's still likely to occur, then perhaps you should + make the counter 32 bits (by editing the code).

    + +

    You may be concerned about the clock being "set back" during + summer daylight savings. However this isn't an issue because + the times used here are UTC, which "always" go forward. Note + that x86 based Unixes may need proper configuration for this to + be true -- they should be configured to assume that the + motherboard clock is on UTC and compensate appropriately. But + even still, if you're running NTP then your UTC time will be + correct very shortly after reboot.

    + +

    The UNIQUE_ID environment variable is + constructed by encoding the 112-bit (32-bit IP address, 32 bit + pid, 32 bit time stamp, 16 bit counter) quadruple using the + alphabet [A-Za-z0-9@-] in a manner similar to MIME + base64 encoding, producing 19 characters. The MIME base64 + alphabet is actually [A-Za-z0-9+/] however + + and / need to be specially encoded + in URLs, which makes them less desirable. All values are + encoded in network byte ordering so that the encoding is + comparable across architectures of different byte ordering. The + actual ordering of the encoding is: time stamp, IP address, + pid, counter. This ordering has a purpose, but it should be + emphasized that applications should not dissect the encoding. + Applications should treat the entire encoded + UNIQUE_ID as an opaque token, which can be + compared against other UNIQUE_IDs for equality + only.

    + +

    The ordering was chosen such that it's possible to change + the encoding in the future without worrying about collision + with an existing database of UNIQUE_IDs. The new + encodings should also keep the time stamp as the first element, + and can otherwise use the same alphabet and bit length. Since + the time stamps are essentially an increasing sequence, it's + sufficient to have a flag second in which all machines + in the cluster stop serving and request, and stop using the old + encoding format. Afterwards they can resume requests and begin + issuing the new encodings.

    + +

    This we believe is a relatively portable solution to this + problem. It can be extended to multithreaded systems like + Windows NT, and can grow with future needs. The identifiers + generated have essentially an infinite life-time because future + identifiers can be made longer as required. Essentially no + communication is required between machines in the cluster (only + NTP synchronization is required, which is low overhead), and no + communication between httpd processes is required (the + communication is implicit in the pid value assigned by the + kernel). In very specific situations the identifier can be + shortened, but more information needs to be assumed (for + example the 32-bit IP address is overkill for any site, but + there is no portable shorter replacement for it).

    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_unique_id.html.ja.euc-jp b/trunk/docs/manual/mod/mod_unique_id.html.ja.euc-jp new file mode 100644 index 0000000000..c14b4e44ca --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.html.ja.euc-jp @@ -0,0 +1,214 @@ + + + +mod_unique_id - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_unique_id

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë°ì°Õ¤Ê¼±Ê̻ҤÎÆþ¤Ã¤¿´Ä¶­ÊÑ¿ô¤ò +Ä󶡤¹¤ë
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:unique_id_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_unique_id.c
    +

    ³µÍ×

    + + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤ÏÈó¾ï¤ËÀ©¸Â¤µ¤ì¤¿¾ò·ï²¼¤Ç¡¢ + ¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È¤Ë¡Ö¤¹¤Ù¤Æ¡×¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + °ì°Õ¤Ë·è¤Þ¤ë¤³¤È¤¬Êݾڤµ¤ì¤Æ¤¤¤ëËâË¡¤Î¥È¡¼¥¯¥ó¤òÄ󶡤·¤Þ¤¹¡£ + ¤³¤Î°ì°Õ¤Ê¼±Ê̻Ҥϡ¢Å¬ÀÚ¤ËÀßÄꤵ¤ì¤¿¥¯¥é¥¹¥¿¤Ç¤ÏÊ£¿ô¤Î + ¥Þ¥·¥ó¤Î´Ö¤Ç¤µ¤¨¤â°ì°Õ¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ´Ä¶­ÊÑ¿ô + UNIQUE_ID ¤Ë¼±Ê̻Ҥ¬ÀßÄꤵ¤ì¤Þ¤¹¡£ + °ì°Õ¤Ê¼±Ê̻Ҥ¬ÊØÍø¤ÊÍýͳ¤Ï¤¤¤í¤¤¤í¤¢¤ê¤Þ¤¹¤¬¡¢ + ¤³¤Î¥É¥­¥å¥á¥ó¥È¤ÎÌÜŪ¤«¤é¤Ï³°¤ì¤ë¤¿¤á¡¢¤³¤³¤Ç¤ÏÀâÌÀ¤·¤Þ¤»¤ó¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    +

    ¥È¥Ô¥Ã¥¯

    +
    +
    top
    +
    +

    ÍýÏÀ

    + + +

    ¤Þ¤º¤Ï¤¸¤á¤Ë¡¢Apache ¥µ¡¼¥Ð¤¬ Unix + ¥Þ¥·¥ó¤Ç¤É¤Î¤è¤¦¤ËÆ°ºî¤ò¤¹¤ë¤«¤ò´Êñ¤ËÀâÌÀ¤·¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤Ï¸½»þÅÀ¤Ç¤Ï Windows NT ¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ + Unix ¥Þ¥·¥ó¤Ç¤Ï Apache ¤Ï¤¤¤¯¤Ä¤«¤Î»Ò¥×¥í¥»¥¹¤òºîÀ®¤·¡¢ + ¤½¤Î»Ò¥×¥í¥»¥¹¤¬°ì¤Ä¤º¤Ä¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î»Ò¥×¥í¥»¥¹¤Ï¡¢ + À¸Â¸´ü´ÖÃæ¤ËÊ£¿ô¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ÎµÄÏÀ¤Ç¤Ï»Ò¥×¥í¥»¥¹´Ö¤Ç¤Ï°ìÀڥǡ¼¥¿¤ò¶¦Í­¤·¤Ê¤¤¤³¤È¤Ë¤·¤Þ¤¹¡£ + °Ê¸å¡¢¤³¤Î»Ò¥×¥í¥»¥¹¤Î¤³¤È¤ò httpd ¥×¥í¥»¥¹ ¤È¸Æ¤Ó¤Þ¤¹¡£

    + +

    ¤¢¤Ê¤¿¤Î¥¦¥§¥Ö¥µ¥¤¥È¤Ë¤Ï¤¢¤Ê¤¿¤¬´ÉÍý¤¹¤ë¤¤¤¯¤Ä¤«¤Î¥Þ¥·¥ó¤¬¤¢¤ë¤È¤·¤Þ¤¹¡£ + ¤½¤ì¤é¤ò¤Þ¤È¤á¤Æ¥¯¥é¥¹¥¿¤È¸Æ¤Ö¤³¤È¤Ë¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¥Þ¥·¥ó¤ÏÊ£¿ô¤Î + Apache ¤ò¼Â¹Ô¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤¹¤Ù¤Æ¤ò¤Þ¤È¤á¤¿¤â¤Î¤¬¡Ö±§Ãè¡×¤Ç¤¢¤ë¤È¹Í¤¨¤é¤ì¤Þ¤¹¡£ + ¤¤¤¯¤Ä¤«¤Î²¾Äê¤Î²¼¤Ç¡¢¥¯¥é¥¹¥¿¤Î¥Þ¥·¥ó´Ö¤¬¤¿¤¯¤µ¤óÄÌ¿®¤ò¤¹¤ë¤³¤È¤Ê¤¯¡¢ + ¤³¤Î±§Ãè¤ÎÃæ¤Ç¤½¤ì¤¾¤ì¤Î¥ê¥¯¥¨¥¹¥È¤Ë°ì°Õ¤Ê¼±Ê̻ҤòÀ¸À®¤Ç¤­¤ë¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ +

    + +

    ¥¯¥é¥¹¥¿¤Ë¤¢¤ë¥Þ¥·¥ó¤Ï°Ê²¼¤ÎÍ×µá¤ò¸«¤¿¤µ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + (¥Þ¥·¥ó¤¬°ì¤Ä¤À¤±¤À¤È¤·¤Æ¤â¡¢NTP ¤Ç»þ·×¤ò¹ç¤ï¤»¤ëÊý¤¬Îɤ¤¤Ç¤¹¡£)

    + +
      +
    • NTP ¤ä¾¤Î¥Í¥Ã¥È¥ï¡¼¥¯¾å¤Ç»þ´Ö¤ò¹ç¤ï¤»¤ë¥×¥í¥È¥³¥ë¤Ë¤è¤Ã¤Æ + ³Æ¥Þ¥·¥ó¤Î»þ´Ö¤ÎƱ´ü¤¬¼è¤é¤ì¤Æ¤¤¤ë¤³¤È¡£
    • + +
    • ¥â¥¸¥å¡¼¥ë¤¬¥Û¥¹¥È̾¤ò°ú¤¤¤Æ°ã¤¦ IP + ¥¢¥É¥ì¥¹¤ò¼õ¤±¼è¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¡¢ + ¥¯¥é¥¹¥¿¤Î¤½¤ì¤¾¤ì¤Î¥Þ¥·¥ó¤Î¥Û¥¹¥È̾¤¬°ã¤¦¤³¤È¡£
    • +
    + +

    ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ë¤ª¤¤¤Æ¤Ï¡¢pid (¥×¥í¥»¥¹ ID) ¤¬ + 32 ¥Ó¥Ã¥È¤ÎÈÏ°ÏÆâ¤Ç¤¢¤ë¤³¤È¤ò²¾Äꤷ¤Þ¤¹¡£¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î + pid ¤¬ 32 ¥Ó¥Ã¥È¤òĶ¤¨¤ë¾ì¹ç¤Ï¡¢´Êñ¤Ê½¤Àµ¤Ç¤Ï¤¢¤ê¤Þ¤¹¤¬¡¢ + ¥³¡¼¥É¤òÊѹ¹¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¤³¤ì¤é¤Î²¾Ä꤬Ëþ¤¿¤µ¤ì¤Æ¤¤¤ë¤È¡¢¤¢¤ë»þÅÀ¤Ë¤ª¤¤¤Æ¡¢ + ¥¯¥é¥¹¥¿Æâ¤Î¤É¤Î¥Þ¥·¥ó¤Î¤É¤Î httpd + ¥×¥í¥»¥¹¤Ç¤â¡¢°ì°Õ¤ËƱÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ï¥Þ¥·¥ó¤Î IP + ¥¢¥É¥ì¥¹¤È httpd ¥×¥í¥»¥¹¤Î pid ¤Ç½½Ê¬¤Ë¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢¥ê¥¯¥¨¥¹¥È¤Ë°ì°Õ¤Ê¼±Ê̻ҤòÀ¸À®¤¹¤ë¤¿¤á¤Ë¤Ï¡¢ + »þ¹ï¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¤À¤±¤Ç¤¹¡£

    + +

    »þ¹ï¤ò¶èÊ̤¹¤ë¤¿¤á¤Ë¡¢Unix ¤Î¥¿¥¤¥à¥¹¥¿¥ó¥× (UTC ¤Î 1970 ǯ + 1 ·î 1 Æü¤«¤é¤ÎÉÿô) ¤È¡¢16 ¥Ó¥Ã¥È¤Î¥«¥¦¥ó¥¿¤ò»È¤¤¤Þ¤¹¡£ + ¥¿¥¤¥à¥¹¥¿¥ó¥×¤ÎγÅ٤ϰìÉäǤ¹¤Î¤Ç¡¢°ìÉô֤Π65536 + ¤Þ¤Ç¤ÎÃͤòɽ¸½¤¹¤ë¤¿¤á¤Ë¥«¥¦¥ó¥¿¤ò»ÈÍѤ·¤Þ¤¹¡£»Í¤Ä¤ÎÃÍ + ( ip_addr, pid, time_stamp, counter ) ¤Ç³Æ httpd + ¥×¥í¥»¥¹¤Ç°ìÉÃ¤Î´Ö¤Ë 65536 ¥ê¥¯¥¨¥¹¥È¤ò¿ô¤¨¤¢¤²¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + »þ´Ö¤¬·Ð¤Ä¤È pid ¤¬ºÆÍøÍѤµ¤ì¤ë¤È¤¤¤¦ÌäÂ꤬¤¢¤ê¤Þ¤¹¤¬¡¢ + ¤³¤ÎÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¥«¥¦¥ó¥¿¤¬»ÈÍѤµ¤ì¤Þ¤¹¡£

    + +

    httpd ¤Î»Ò¥×¥í¥»¥¹¤¬ºîÀ®¤µ¤ì¤ë¤È¡¢¥«¥¦¥ó¥¿¤Ï + (¤½¤Î»þÅÀ¤Î¥Þ¥¤¥¯¥íÉà ¡à 10) modulo 65536 ¤Ç½é´ü²½¤µ¤ì¤Þ¤¹ + (¤³¤Î¼°¤Ï¤¤¤¯¤Ä¤«¤Î¥·¥¹¥Æ¥à¤Ë¤¢¤ë¡¢¥Þ¥¤¥¯¥íÉäΠ+ ¥¿¥¤¥Þ¤Î²¼°Ì¥Ó¥Ã¥È¤¬°Û¤Ê¤ë¤È¤¤¤¦ÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤ËÁª¤Ð¤ì¤Þ¤·¤¿)¡£ + °ì°Õ¤Ê¼±Ê̻Ҥ¬À¸À®¤µ¤ì¤¿¤È¤­¡¢»ÈÍѤµ¤ì¤ë¥¿¥¤¥à¥¹¥¿¥ó¥×¤Ï + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¥ê¥¯¥¨¥¹¥È¤¬ÅþÃ夷¤¿»þ¹ï¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥«¥¦¥ó¥¿¤Ï¼±Ê̻Ҥ¬À¸À®¤µ¤ì¤ë¤¿¤Ó¤ËÁý²Ã¤·¤Þ¤¹ + (¤¢¤Õ¤ì¤¿¾ì¹ç¤Ï 0 ¤ËÌá¤ê¤Þ¤¹)¡£

    + +

    ¥«¡¼¥Í¥ë¤Ï¥×¥í¥»¥¹¤ò¥Õ¥©¡¼¥¯¤¹¤ë¤È¡¢¤½¤ì¤¾¤ì¤Î¥×¥í¥»¥¹¤Î¤¿¤á¤Ë + pid ¤òÀ¸À®¤·¤Þ¤¹¡£pid ¤Ï·«¤êÊÖ¤µ¤ì¤ë¤³¤È¤¬µö²Ä¤µ¤ì¤Æ¤¤¤Þ¤¹ + (pid ¤ÎÃͤÏ¿¤¯¤Î Unix ¤Ç¤Ï 16 ¥Ó¥Ã¥È¤Ç¤¹¤¬¡¢¿·¤·¤¤¥·¥¹¥Æ¥à¤Ç¤Ï + 32 ¥Ó¥Ã¥È¤Ë³ÈÄ¥¤µ¤ì¤Æ¤¤¤Þ¤¹)¡£ + ¤Ç¤¹¤«¤é¡¢¤¢¤ëÄøÅ٤λþ´Ö¤¬·Ð²á¤¹¤ë¤ÈƱ¤¸ pid ¤¬ºÆ¤Ó»ÈÍѤµ¤ì¤Þ¤¹¡£ + ¤·¤«¤·¡¢°ìÉÃÆâ¤ËºÆ»ÈÍѤµ¤ì¤Ê¤±¤ì¤Ð¡¢ + »Í¤Ä¤ÎÃͤΰì°ÕÀ­¤ÏÊݤ¿¤ì¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢²æ¡¹¤Ï¥·¥¹¥Æ¥à¤¬°ìÉÃ´Ö + ¤Ë 65536 ¸Ä¤Î¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Ê¤¤¤È²¾Äꤷ¤Æ¤¤¤Þ¤¹ (¤¤¤¯¤Ä¤«¤Î Unix + ¤Ç¤Ï 32768 ¥×¥í¥»¥¹¤Ç¤¹¤¬¡¢¤½¤ì¤Ç¤¹¤é¤Û¤È¤ó¤É¤¢¤êÆÀ¤Ê¤¤¤Ç¤·¤ç¤¦)¡£

    + +

    ²¿¤é¤«¤ÎÍýͳ¤Ç¡¢Æ±¤¸»þ¹ï¤¬·«¤êÊÖ¤µ¤ì¤¿¤È¤·¤Þ¤·¤ç¤¦¡£ + ¤Ä¤Þ¤ê¡¢¥·¥¹¥Æ¥à¤Î»þ·×¤¬¶¸¤Ã¤Æ¤¤¤Æ¡¢¤â¤¦°ìÅÙ²áµî¤Î»þ¹ï¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿ + (¤â¤·¤¯¤Ï¿Ê¤ß¤¹¤®¤Æ¤¤¤¿¤È¤­¤Ë¡¢ + Àµ¤·¤¤»þ¹ï¤ËÌᤷ¤¿¤¿¤á¤ËºÆ¤Ó¾­Íè¤Î»þ¹ï¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿) ¤È¤·¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢pid ¤È¥¿¥¤¥à¥¹¥¿¥ó¥×¤¬ºÆ»ÈÍѤµ¤ì¤ë¤³¤È¤¬´Êñ¤Ë¼¨¤µ¤ì¤Þ¤¹¡£ + ¥«¥¦¥ó¥¿½é´ü²½ÍѤδؿô¤Ï¡¢¤³¤ÎÌäÂê¤Î²óÈò¤ò¼ê½õ¤±¤·¤è¤¦¤ÈÁªÂò¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ËÜÅö¤Ï¥«¥¦¥ó¥¿¤Î½é´ü²½¤ò¤¹¤ë¤¿¤á¤Ë¥é¥ó¥À¥à¤Ê¿ô»ú¤ò»È¤¤¤¿¤¤¤Î¤Ç¤¹¤¬¡¢ + ¤Û¤È¤ó¤É¤Î¥·¥¹¥Æ¥à¤Ç¤Ï´Êñ¤Ë»ÈÍѤǤ­¤ë¿ô¤Ï̵¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤ + (¤¹¤Ê¤ï¤Á¡¢rand ()¤Ï»È¤¨¤Þ¤»¤ó¡£rand () ¤Ë¤Ï seed + ¤òÍ¿¤¨¤ëɬÍפ¬¤¢¤ê¡¢seed ¤Ë¤Ï»þ¹ï¤ò»È¤¨¤Þ¤»¤ó¡£°ìÉÃñ°Ì¤Ç¤Ï¡¢ + ¤½¤Î»þ¹ï¤Ï¤¹¤Ç¤Ë·«¤êÊÖ¤µ¤ì¤Æ¤¤¤ë¤«¤é¤Ç¤¹)¡£ + ¤³¤ì¤Ï¡¢´°àú¤ÊÂкö¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    ¤³¤ÎÂкö¤Ï¤É¤Î¤¯¤é¤¤¸ú²Ì¤¬¤¢¤ë¤Ç¤·¤ç¤¦¤«? + ¤³¤³¤Ç¤Ï¡¢¥Þ¥·¥ó·²¤ÎÃæ¤Î°ì¤Ä¤ÏºÇÂç¤Ç°ìÉÃ¤Ë 500 + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤È²¾Äꤷ¤Þ¤¹ (¤³¤ì¤ò½ñ¤¤¤Æ¤¤¤ë»þÅÀ¤Ç¤ÏÂÅÅö¤Ê¾å¸Â¤Ç¤¹¡£ + Ä̾亮¥¹¥Æ¥à¤¬¤¹¤ë¤³¤È¤ÏÀÅŪ¤Ê¥Õ¥¡¥¤¥ë¤ò¼è¤ê¤À¤¹¤À¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤«¤é)¡£ + ¤½¤ì¤ò¹Ô¤Ê¤¦¤¿¤á¤Ë¡¢¤½¤Î¥Þ¥·¥ó¤ÏʹԤ·¤ÆÍè¤ë¥¯¥é¥¤¥¢¥ó¥È¤Î¿ô¤Ë + ±þ¤¸¤¿¿ô¤Î»Ò¥×¥í¥»¥¹¤òÍ׵ᤷ¤Þ¤¹¡£ + ¤·¤«¤·¤Ê¤¬¤é¡¢Èá´ÑŪ¤Ë¹Í¤¨¤Æ¡¢°ì¤Ä¤Î»Ò¥×¥í¥»¥¹¤¬°ìÉÃ¤Ë 500 + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¨¤ë¤È¤·¤Þ¤¹¡£¤½¤¦¤¹¤ë¤È¡¢(°ìÉäÎÀºÅ٤ˤª¤¤¤Æ) + »þ¹ï¤¬Æ±¤¸»þ¤ò·«¤êÊÖ¤¹¤È¡¢¤³¤Î»Ò¥×¥í¥»¥¹¤¬¥«¥¦¥ó¥¿¤ÎÃͤòºÆ¤Ó»È¤¤¡¢ + °ì°ÕÀ­¤¬²õ¤ì¤ë²ÄǽÀ­¤¬ 1.5% ¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤ÏÈó¾ï¤ËÈá´ÑŪ¤ÊÎã¤Ç¡¢¼ÂÀ¤³¦¤ÎÃͤǤϡ¢¤Û¤È¤ó¤Éµ¯¤³¤ê¤½¤¦¤Ë¤¢¤ê¤Þ¤»¤ó¡£ + ¤½¤ì¤Ç¤â¤³¤ì¤¬µ¯¤³¤ë²ÄǽÀ­¤Î¤¢¤ë¤è¤¦¤Ê¥·¥¹¥Æ¥à¤Ê¤é¡¢ + (¥×¥í¥°¥é¥à¥³¡¼¥É¤òÊÔ½¸¤·¤Æ) + ¥«¥¦¥ó¥¿¤ò 32 ¥Ó¥Ã¥È¤Ë¤¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ +

    + +

    ¥µ¥Þ¡¼¥¿¥¤¥à¤Ë¤è¤ê»þ·×¤¬¡ÖÌᤵ¤ì¤ë¡×¤³¤È¤òµ¤¤Ë¤·¤Æ¤¤¤ë¿Í¤¬ + ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤³¤³¤Ç»ÈÍѤµ¤ì¤ë»þ´Ö¤Ï UTC ¤Ç¤¢¤ê¡¢ + ¤½¤ì¤Ï¡Ö¾ï¤Ë¡×¿Ê¤à¤Î¤Ç¤³¤³¤Ç¤ÏÌäÂê¤Ë¤Ê¤ê¤Þ¤»¤ó¡£x86 ¾å¤Î Unix + ¤Ï¤³¤Î¾ò·ï¤òËþ¤¿¤¹¤¿¤á¤ËŬÀÚ¤ÊÀßÄ꤬ɬÍפ«¤â¤·¤ì¤Ê¤¤¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥Þ¥¶¡¼¥Ü¡¼¥É¤Î»þ·×¤Ï UTC ¤Ë¤Ê¤Ã¤Æ¤¤¤Æ¡¢ + ¾¤Î»þ´Ö¤Ï¤½¤³¤«¤éŬÀÚ¤ËÊäÀµ¤µ¤ì¤ë¤³¤È¤ò²¾Äê¤Ç¤­¤ë¤è¤¦¤Ë + ÀßÄꤵ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ç¤µ¤¨¡¢NTP + ¤ò»È¤Ã¤Æ¤¤¤ë¤Ê¤é¤Ð¥ê¥Ö¡¼¥È¸å¤Ë¤¹¤°Àµ¤·¤¤ UTC ¤Î»þ´Ö¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    + +

    UNIQUE_ID ´Ä¶­ÊÑ¿ô¤Ï 112 ¥Ó¥Ã¥È (32 ¥Ó¥Ã¥È IP + ¥¢¥É¥ì¥¹¡¢32 ¥Ó¥Ã¥È pid, 32 ¥Ó¥Ã¥È¥¿¥¤¥à¥¹¥¿¥ó¥×¡¢16 + ¥Ó¥Ã¥È¥«¥¦¥ó¥¿¤Î»Í¤Ä¤ÎÁÈ) ¤ò¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È [A-Za-z0-9@-] + ¤òÍѤ¤¤Æ MIME ¤Î base64 Éä¹æ²½¤ÈƱÍͤÎÊýË¡¤Ë¤è¤êÉä¹æ²½¤·¡¢19 + ¤Îʸ»ú¤òÀ¸À®¤¹¤ë¤³¤È¤Ë¤è¤êºîÀ®¤µ¤ì¤Þ¤¹¡£MIME ¤Î base64 + ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ï¼ÂºÝ¤Ï [A-Za-z0-9+/] ¤Ç¤¹¤¬¡¢ + + ¤È / ¤È¤Ï URL + ¤Ç¤ÏÆÃÊ̤ÊÉä¹æ²½¤¬É¬ÍפʤΤǡ¢¤¢¤Þ¤ê˾¤Þ¤·¤¯¤¢¤ê¤Þ¤»¤ó¡£ + Á´¤Æ¤ÎÃͤϥͥåȥ¥¯¥Ð¥¤¥È¥ª¡¼¥À¤ÇÉä¹æ²½¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + Éä¹æ¤Ï°ã¤Ã¤¿¥Ð¥¤¥È¥ª¡¼¥À¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã´Ö¤ÇÈæ³Ó²Äǽ¤Ç¤¹¡£ + ¼ÂºÝ¤ÎÉä¹æ²½¤Î½çÈÖ¤Ï: ¥¿¥¤¥à¥¹¥¿¥ó¥×¡¢IP ¥¢¥É¥ì¥¹¡¢pid, + ¥«¥¦¥ó¥¿¤Ç¤¹¡£¤³¤Î½ç¤Ë¤ÏÌÜŪ¤¬¤¢¤ê¤Þ¤¹¤¬¡¢ + ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÏÉä¹æ¤ò²òÀϤ¹¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤¤³¤È¤ò¶¯Ä´¤·¤Æ¤ª¤­¤Þ¤¹¡£ + ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÏÉä¹æ²½¤µ¤ì¤¿ UNIQUE_ID + Á´ÂΤòÆ©²áŪ¤Ê¥È¡¼¥¯¥ó¤È¤·¤Æ°·¤¦¤Ù¤­¤Ç¤¹¡£ + UNIQUE_ID ¤Ï¾¤Î UNIQUE_ID + ¤È¤ÎÅù²ÁÀ­¤òÄ´¤Ù¤ë¤¿¤á¤À¤±¤Ë¤Î¤ß»ÈÍѤǤ­¤Þ¤¹¡£

    + +

    ¤³¤Î½çÈ֤Ͼ­Íè¡¢´û¸¤Î UNIQUE_ID + ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤È¤Î¾×Æͤò¿´ÇÛ¤¹¤ë¤³¤È¤Ê¤¯Éä¹æ¤òÊѹ¹¤¹¤ë¤³¤È¤¬ + ²Äǽ¤Ë¤Ê¤ë¤è¤¦¤ËÁªÂò¤·¤Æ¤¤¤Þ¤¹¡£ + ¿·¤·¤¤Éä¹æ¤Ï¥¿¥¤¥à¥¹¥¿¥ó¥×¤òºÇ½é¤ÎÍ×ÁǤȤ·¤Æ»Ä¤¹¤Î¤¬Ë¾¤Þ¤·¤¯¡¢ + ¤½¤ì°Ê³°¤ÏƱ¤¸¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤È¥Ó¥Ã¥ÈŤò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¥¿¥¤¥à¥¹¥¿¥ó¥×¤ÏËܼÁŪ¤ËÁý²Ã·ÏÎó¤Ç¤¹¤Î¤Ç¡¢ + ¥¯¥é¥¹¥¿¤ÎÁ´¤Æ¤Î¥Þ¥·¥ó¤¬¥ê¥¯¥¨¥¹¥È¤È¥µ¡¼¥Ðµ¡Ç½¤òÄä»ß¤·¤Æ¡¢ + ¸Å¤¤Éä¹æ²½Êý¼°¤ò»ÈÍѤ¹¤ë¤Î¤ò¤ä¤á¤ë¥Õ¥é¥°É䬤¢¤ì¤Ð½½Ê¬¤Ç¤¹¡£ + ¤½¤Î¸å¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤òºÆ³«¤·¡¢ + ¿·¤·¤¤Éä¹æ¤òȯ¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ²æ¡¹¤Ï¤³¤ì¤¬¡¢ + ¤³¤ÎÌäÂê¤ËÂФ¹¤ëÈæ³ÓŪ°Ü¿¢À­¤Î¹â¤¤²ò·èË¡¤À¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£ + Windows NT ¤Î¤è¤¦¤Ê¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤Î¥·¥¹¥Æ¥à¤Ë³ÈÄ¥¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤·¡¢ + ¾­ÍèɬÍפˤʤì¤Ð¤µ¤é¤ËÁý¤ä¤¹¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ID ¤ÏɬÍפ˱þ¤¸¤ÆŤ¯¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤Î¤Ç¡¢À¸À®¤µ¤ì¤¿ ID + ¤Ï¼Â¼Á¾å¡¢Ìµ¸Â¤ËÍ­¸ú¤Ç¤¹¡£¤Þ¤¿¡¢¥¯¥é¥¹¥¿¤Î¥Þ¥·¥ó´Ö¤ÎÄÌ¿®¤â»ö¼Â¾åɬÍפʤ¯ + (NTP ¤Ë¤è¤ëƱ´ü¤Î¤ß¤¬É¬Íפǡ¢¤³¤ì¤Ï¥ª¡¼¥Ð¥Ø¥Ã¥É¤Ï¤¢¤Þ¤ê¤¢¤ê¤Þ¤»¤ó)¡¢httpd + ¥×¥í¥»¥¹´Ö¤ÎÄÌ¿®¤âɬÍפ¢¤ê¤Þ¤»¤ó (ÄÌ¿®¤Ï¥«¡¼¥Í¥ë¤Ë¤è¤ê³ä¤êÅö¤Æ¤é¤ì¤¿ + pid ¤ÎÃͤˤè¤ê°ÅÌÛ¤ÎÆâ¤Ë¹Ô¤Ê¤ï¤Æ¤¤¤Þ¤¹)¡£ + ¤µ¤é¤Ë¸Â¤é¤ì¤¿¾õ¶·²¼¤Ç¤Ï¡¢ID ¤Ï¤µ¤é¤Ëû¤¯¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ + ¤è¤ê¿¤¯¤Î¾ðÊó¤ò²¾Äꤹ¤ëɬÍפ¬¤Ç¤Æ¤­¤Þ¤¹ (Î㤨¤Ð¡¢32 ¥Ó¥Ã¥È + IP ¥¢¥É¥ì¥¹¤Ï¤É¤Î¥µ¥¤¥È¤Ë¤ª¤¤¤Æ¤â²á¾ê¤Ê¾ðÊó¤Ç¤¹¤¬¡¢ + ¤½¤ì¤ÎÂå¤ï¤ê¤Ë¤Ê¤ë°Ü¿¢À­¤Î¤¢¤ë¤â¤Î¤Ï¤¢¤ê¤Þ¤»¤ó)¡£

    +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_unique_id.html.ko.euc-kr b/trunk/docs/manual/mod/mod_unique_id.html.ko.euc-kr new file mode 100644 index 0000000000..cab790011c --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.html.ko.euc-kr @@ -0,0 +1,191 @@ + + + +mod_unique_id - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_unique_id

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:°¢ ¿äû¸¶´Ù À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ °¡Áö´Â ȯ°æº¯¼ö¸¦ +Á¦°øÇÑ´Ù
    »óÅÂ:Extension
    ¸ðµâ¸í:unique_id_module
    ¼Ò½ºÆÄÀÏ:mod_unique_id.c
    +

    ¿ä¾à

    + + +

    ÀÌ ¸ðµâÀº ¾î¶² Ưº°ÇÑ »óȲ¿¡¼­µµ "¸ðµç" ¿äûÁß¿¡¼­ + À¯ÀÏÇϵµ·Ï º¸ÀåµÈ ½Äº°ÀÚ(identifier)¸¦ ¸ðµç ¿äû¿¡ Á¦°øÇÑ´Ù. + ½ÉÁö¾î ÀÌ ½Äº°Àڴ Ưº°ÇÏ°Ô ±¸¼ºÇÑ Å¬·¯½ºÅÍÀÇ ¿©·¯ ÄÄÇ»Å͵é + Áß¿¡¼­µµ À¯ÀÏÇÏ´Ù. °¢ ¿äû¸¶´Ù ȯ°æº¯¼ö + UNIQUE_ID¸¦ ¼³Á¤ÇÑ´Ù. À¯ÀÏÇÑ ½Äº°ÀÚ´Â ¿©·¯°¡Áö + ¿ëµµ·Î »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ¼³¸íÀº ÀÌ ¹®¼­ÀÇ ¹üÀ§¸¦ ³Ñ¾î¼±´Ù.

    +
    +

    Áö½Ã¾îµé

    +

    ÀÌ ¸ðµâ¿¡´Â Áö½Ã¾î°¡ ¾ø½À´Ï´Ù.

    +

    ÁÖÁ¦

    +
    +
    top
    +
    +

    ÀÌ·Ð

    + + +

    ¸ÕÀú À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡ ¼­¹ö°¡ ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö + °£·«È÷ »ìÆ캸ÀÚ. Windows NT´Â ÇöÀç ÀÌ ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù. + À¯´Ð½º¿¡¼­ ¾ÆÆÄÄ¡´Â ¿©·¯ ÀÚ½ÄÀ» ¸¸µé°í, ÀÚ½Ä ÇÁ·Î¼¼½º´Â + Çѹø¿¡ ÇÑ ¿äû¾¿ ó¸®ÇÑ´Ù. ÀÚ½ÄÀº ½ÇÇàÁß¿¡ ¿©·¯ ¿äûÀ» + ó¸®ÇÑ´Ù. ¿©±â¼­ Áß¿äÇÑ °ÍÀº ÀڽĵéÀÌ ¼­·Î ÀڷḦ + °øÀ¯ÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù. ¾ÕÀ¸·Î ÀÚ½ÄÀ» httpd ÇÁ·Î¼¼½º¶ó°í + ÇÑ´Ù.

    + +

    ¿©·¯ ÄÄÇ»ÅÍ·Î À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇÑ´Ù¸é Ŭ·¯½ºÅÍ(cluster)¶ó°í + ºÎ¸¥´Ù. °¢ ÄÄÇ»ÅÍ´Â ¿©·¯ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÀÌµé ¸ðµÎ¸¦ + "¿ìÁÖ"·Î º¸¸é, Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ÄÄÇ»Å͵鰣¿¡ ¸¹Àº Åë½Å¾øÀÌ + °¢ ¿äû¸¶´Ù ¿ìÁÖ¿¡¼­ À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µé ¼ö ÀÖ´Ù.

    + +

    Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ÄÄÇ»ÅÍ´Â ´ÙÀ½ ¿ä±¸»çÇ×À» ¸¸Á·ÇØ¾ß ÇÑ´Ù. + (ÄÄÇ»Å͸¦ ÇѴ븸 »ç¿ëÇÏ´õ¶óµµ ÄÄÇ»ÅÍ ½Ã°£À» NTP¿Í µ¿±âÇØ¾ß + ÇÑ´Ù.)

    + +
      +
    • ÄÄÇ»ÅÍ ½Ã°£Àº NTP³ª ´Ù¸¥ ³×Æ®¿÷ ½Ã°£ ÇÁ·ÎÅäÄÝ°ú + µ¿±âÈ­µÈ´Ù.
    • + +
    • ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸íÀÌ ¸ðµÎ ´Ù¸£´Ù. ±×·¡¼­ ¸ðµâÀÌ + È£½ºÆ®¸íÀ¸·Î ãÀ¸¸é Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â °¢ ÄÄÇ»Å͸¶´Ù ´Ù¸¥ + IP ÁÖ¼Ò¸¦ ¾ò´Â´Ù.
    • +
    + +

    ¿î¿µÃ¼Á¦¿¡¼­ pid (ÇÁ·Î¼¼½º id)°¡ 32ºñÆ®¿¡ µé¾î°£´Ù°í + °¡Á¤ÇÑ´Ù. ¿î¿µÃ¼Á¦°¡ pid·Î 32ºñÆ® ÀÌ»óÀ» »ç¿ëÇÑ´Ù¸é °£´ÜÇÏÁö¸¸ + Äڵ带 ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ÀÌ·± °¡Á¤ÇÏ¿¡ ¿ì¸®´Â ¾î¶² ½ÃÁ¡¿¡¼­ Ŭ·¯½ºÅÍÀÇ ¾î¶² ÄÄÇ»ÅÍ¿¡ + ÀÖ´Â ¾î¶² httpd ÇÁ·Î¼¼½º¸¦ ´Ù¸¥ ¸ðµç httpd ÇÁ·Î¼¼½ºµé°ú + ±¸º°ÇÒ ¼ö ÀÖ´Ù. ÄÄÇ»ÅÍÀÇ IP ÁÖ¼Ò¿Í httpd ÇÁ·Î¼¼½ºÀÇ pid¸¸À¸·Îµµ + ÃæºÐÈ÷ ±¸º°ÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ¿äû¿¡ ´ëÇØ À¯ÀÏÇÑ ±¸º°ÀÚ¸¦ + ¸¸µå·Á¸é ½Ã°£Â÷¸¦ ±¸º°ÇÒ ¼ö¸¸ ÀÖÀ¸¸é µÈ´Ù.

    + +

    ½Ã°£À» ±¸º°ÇϱâÀ§ÇØ À¯´Ð½º ½Ã°£(timestamp, ¼¼°è Ç¥Áؽ÷Π+ 1970³â 1¿ù 1ÀÏ ÀÌÈÄ Áö³­ ÃÊ)°ú 16ºñÆ® Ä«¿îÅ͸¦ »ç¿ëÇÑ´Ù. + À¯´Ð½º ½Ã°£Àº ÃÊ´ÜÀ§ÀÌ°í, Ä«¿îÅÍ´Â ÀÏ Ãʵ¿¾È 65536±îÁö + Áõ°¡ÇÑ´Ù. ( ip_addr, pid, time_stamp, counter ) + ¹­À½Àº ¾î¶² httpd ÇÁ·Î¼¼½º¿¡¼­ ÀÏ Ãʵ¿¾È 65536 ¿äûÀ» ±¸º°ÇÒ + ¼ö ÀÖ´Ù. ±×·¯³ª Ä«¿îÅÍ´Â pid¸¦ Àç»ç¿ëÇÏ´Â ¹®Á¦¸¦ ÇØ°áÇØ¾ß + ÇÑ´Ù.

    + +

    httpd ÀÚ½ÄÀ» ¸¸µé¸é Ä«¿îÅÍ´Â ( ÇöÀç ¹Ð¸®ÃÊ ³ª´©±â 10 )À» + 65536À¸·Î ³ª´« ³ª¸ÓÁö°¡ µÈ´Ù. (¸î¸î ½Ã½ºÅÛÀÇ ¹Ð¸®ÃÊ ½Ã°£¿¡¼­ + ÇÏÀ§ ºñÆ®°¡ ÀÏÄ¡ÇÏÁö¾Ê´Â ¹®Á¦¶§¹®¿¡ ÀÌ °ø½ÄÀ» ¸¸µé¾ú´Ù.) + À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µé¶§ »ç¿ëÇÏ´Â ½Ã°£Àº À¥¼­¹ö°¡ ¿äûÀ» ¹ÞÀº + ½Ã°£ÀÌ´Ù. Ä«¿îÅÍ´Â ½Äº°ÀÚ¸¦ ¸¸µé¶§¸¶´Ù Áõ°¡ÇÑ´Ù (±×¸®°í + ´Ù½Ã ½ÃÀÛÇÑ´Ù).

    + +

    Ä¿³ÎÀº ÇÁ·Î¼¼½º¸¦ Æ÷Å©ÇÒ¶§(fork) °¢ ÇÁ·Î¼¼½º¿¡ pid¸¦ + ÇÒ´çÇÏ°í, pid´Â ´Ù½Ã ½ÃÀÛÇÒ ¼ö ÀÖ´Ù. (pid´Â ¸¹Àº À¯´Ð½º¿¡¼­ + 16ºñÆ®ÀÌÁö¸¸, ÃÖ±Ù ½Ã½ºÅÛÀº 32ºñÆ®·Î È®ÀåÇß´Ù.) ±×·¡¼­ ½Ã°£ÀÌ + Áö³ª¸é °°Àº pid¸¦ Àç»ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª °°Àº ½Ã°£¿¡ pid¸¦ + Àç»ç¿ëÇÏÁö ¾Ê´Â´Ù¸é À§ÀÇ ¹­À½Àº À¯ÀÏÇÏ´Ù. Áï, ¿ì¸®´Â ½Ã½ºÅÛÀÌ + ÀÏÃʵ¿¾È ÇÁ·Î¼¼½º¸¦ 65536°³ ÀÌ»ó ¸¸µéÁö ¾Ê´Â´Ù°í °¡Á¤ÇÑ´Ù. + (¾î¶² À¯´Ð½º¿¡¼­´Â 32768°³ ÀÌ»ó ÇÁ·Î¼¼½º¸¦ ¸¸µé¸é pid Àç»ç¿ë + ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖÁö¸¸, ÀÌ°ÍÁ¶Â÷µµ ÀϾ °Í°°Áö ¾Ê´Ù.)

    + +

    ½Ã°£ÀÌ ¾î¶² ÀÌÀ¯¿¡¼­°Ç ¹Ýº¹µÈ´Ù°í °¡Á¤Çغ¸ÀÚ. Áï, ½Ã½ºÅÛ + ½Ã°è°¡ ²¿¿©¼­ ½Ã°£ÀÌ °ú°Å·Î µ¹¾Æ°¡´Â (ȤÀº ½Ã°è°¡ ³Ê¹« ¾Õ¼­°¡¼­ + ¿Ã¹Ù·Î Àç¼³Á¤ÇÑÈÄ ¹Ì·¡¿¡ °°Àº ½Ã°£ÀÌ µÇ´Â) °æ¿ì´Ù. ÀÌ °æ¿ì + pid¿Í ½Ã°£À» ¸ðµÎ Àç»ç¿ëÇÒ ¼ö ÀÖ´Ù. Ä«¿îÅÍÀÇ ÃʱâÈ­ °ø½ÄÀº + ÀÌ ¹®Á¦¸¦ ÇØ°áÇÏ·Á°í °í¾ÈµÇ¾ú´Ù. ¿ì¸®´Â ½ÇÁ¦ ¹«ÀÛÀ§ ¼ýÀÚ·Î + Ä«¿îÅ͸¦ ÃʱâÈ­ÇÏ±æ ¿øÇÏÁö¸¸, ¸¹Àº ½Ã½ºÅÛ¿¡¼­ ÀÌ·± ¼ö¸¦ + ½±°Ô ¾òÀ» ¼ö ¾ø´Ù. (¿¹¸¦ µé¾î, seed°¡ ÇÊ¿äÇϱ⶧¹®¿¡ + rand()¸¦ »ç¿ëÇÒ ¼ö ¾ø°í, ½Ã°£Àº ÃÖ¼ÒÇÑ ÀÏÃÊ ´ÜÀ§À̱⶧¹®¿¡ + ½Ã°£À¸·Î seed·Î »ç¿ëÇÒ ¼ö ¾ø´Ù.) Áï ¿Ïº®ÇÑ ÇØ°áÃ¥ÀÌ ¾ø´Ù.

    + +

    ±×·³ ÀÌ ¹æ¹ýÀº ¾ó¸¶³ª ±¦ÂúÀ»±î? ÄÄÇ»ÅÍÁß Çϳª°¡ ¿äûÀ» + ÃÊ´ç ÃÖ´ë 500°³ (½Ã½ºÅÛÀº ÀϹÝÀûÀ¸·Î Á¤ÀûÀÎ ÆÄÀÏÀ» Àü¼ÛÇÏ´Â + °Í ÀÌ»óÀÇ ÀÛ¾÷À» ÇϹǷΠÀÌ ±ÛÀ» ¾²´Â ½ÃÁ¡¿¡¼­ »ó´çÈ÷ ³ôÀº + °ªÀÌ´Ù.) ¼­ºñ½ºÇÑ´Ù°í °¡Á¤ÇÏÀÚ. µ¿½Ã¿¡ ¾ó¸¶¸¸Å­ÀÇ Å¬¶óÀ̾ðÆ®¸¦ + ó¸®Çϴ°¡¿¡ µû¶ó ÀÚ½ÄÀÇ °³¼ö°¡ °áÁ¤µÈ´Ù. ±×·¯³ª ¿ì¸®´Â + ºñ°üÀûÀ¸·Î ÇÑ ÀÚ½ÄÀÌ ¿äûÀ» ÃÊ´ç 500°³ ó¸®ÇÒ ¼ö ÀÖ´Ù°í + °¡Á¤ÇÑ´Ù. Àç»ç¿ëÇÑ pid¸¦ °¡Áø ÀÚ½ÄÀÇ 500°³ ¿äû°ú ÀÌÀü ÀÚ½ÄÀÇ + 500°³ ¿äûÀÇ Ä«¿îÅÍ°ªÀÌ °ãÄ¥ ¼ö ÀÖ´Â Ä«¿îÅÍ ½ÃÀÛ°ª °æ¿ì¼ö´Â + 1000°³ÀÌ´Ù. ±×·¡¼­ (ÃÊ´ÜÀ§¿¡¼­) ÀÚ½ÄÀÌ Ä«¿îÅÍ°ªÀ» ¹Ýº¹ÇÏ¿© + À¯ÀϼºÀÌ ±úÁú È®·üÀº 1.5%ÀÌ´Ù. ÀÌ°ÍÀº ¸Å¿ì ºñ°üÀûÀÎ °¡Á¤À̸ç, + ½ÇÁ¦ ÀÌ·² °æ¿ì´Â »ó´çÈ÷ ´õ ³·´Ù. ±×·¡µµ ½Ã½ºÅÛ¿¡¼­ ÀÌ·± + ÀÏÀÌ ¹ß»ýÇÒ °Í °°´Ù¸é (¼Ò½º¸¦ ¼öÁ¤ÇÏ¿©) Ä«¿îÅ͸¦ 32ºñÆ®·Î + ¸¸µé¾î¶ó.

    + +

    ¼¶¸ÓŸÀÓ¶§¹®¿¡ ½Ã°è°¡ "µÚ·Î °¡´Â" °ÍÀ» °ÆÁ¤ÇÒÁöµµ ¸ð¸¥´Ù. + ±×·¯³ª ¿©±â¼­ »ç¿ëÇÏ´Â ½Ã°£Àº ±¹Á¦ Ç¥ÁؽÃ(UTC), Áï ½Ã°£ÀÌ + "Ç×»ó" ¾ÕÀ¸·Î °¡¹Ç·Î ¹®Á¦°¡ ¾ø´Ù. x86±â¹Ý À¯´Ð½º¿¡¼­´Â + ÀûÀýÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇÏ´Ù. ¸ÞÀκ¸µå ½Ã°è°¡ UTC¸¦ »ç¿ëÇϵµ·Ï + ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±×·¯³ª NTP¸¦ »ç¿ëÇÑ´Ù¸é Àç½ÃÀÛÈÄ Á¶±Ý Áö³ª¸é + UTC ½Ã°£¿¡ ¿Ã¹Ù·Î ¸ÂÃá´Ù.

    + +

    ȯ°æº¯¼ö UNIQUE_ID´Â MIME base64 ÀÎÄÚµù°ú + ºñ½ÁÇÑ ¹æ¹ýÀ¸·Î 112ºñÆ® (32ºñÆ® IP ÁÖ¼Ò, 32ºñÆ® pid, 32ºñÆ® + ½Ã°£, 16ºñÆ® Ä«¿îÅÍ) ¹­À½À» ¾ËÆĺª [A-Za-z0-9@-]·Î + Ç¥ÇöÇÑ´Ù. ½ÇÁ¦ MIME base64 ¾ËÆĺªÀº + [A-Za-z0-9+/]ÀÌÁö¸¸ +¿Í + /´Â URL¿¡¼­ Ưº°ÇÑ Àǹ̷Π»ç¿ëÇϹǷΠÁ¦¿ÜÇß´Ù. + ¸ðµç °ªÀ» ³×Æ®¿÷ ¹ÙÀÌÆ®¼ø¼­·Î ÀÎÄÚµùÇϱ⶧¹®¿¡ ´Ù¸¥ ¹ÙÀÌÆ®¼ø¼­¸¦ + »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃÄ°£¿¡ °ªÀÌ °°´Ù. ½ÇÁ¦ ÀÎÄÚµù ¼ø¼­´Â + ½Ã°£, IP ÁÖ¼Ò, pid, Ä«¿îÅÍ ¼ø¼­ÀÌ´Ù. ÀÌ ¼ø¼­¿¡´Â ¾î¶² ¸ñÀûÀÌ + ÀÖÁö¸¸, ÇÁ·Î±×·¥Àº ÀÎÄÚµù ¼ø¼­¿¡ ÀÇÁ¸ÇÏ¿© °ªµéÀ» ºÐ¼®Çϸé + ¾ÈµÊÀ» °­Á¶ÇÑ´Ù. ÇÁ·Î±×·¥Àº ÀÎÄÚµùµÈ UNIQUE_ID + Àüü¸¦ ÇÑ ´ÜÀ§·Î »ý°¢ÇÏ°í, ´Ù¸¥ UNIQUE_ID¿Í + µ¿ÀÏÇÑÁö¸¸ ºñ±³ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼ø¼­´Â ¾ÕÀ¸·Î ±âÁ¸ÀÇ UNIQUE_ID µ¥ÀÌÅͺ£À̽º¿Í + Ãæµ¹À» ¿°·ÁÇÏÁö¾Ê°í ÀÎÄÚµùÀ» º¯°æÇÒ ¼ö ÀÖµµ·Ï °í¾ÈÇß´Ù. + »õ·Î¿î ÀÎÄÚµùÀº ù Ç׸ñÀ¸·Î ½Ã°£À» »ç¿ëÇϰųª, °°Àº ¾ËÆĺª°ú + ºñÆ® ±æÀ̸¦ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. ½Ã°£ÀÌ ±âº»ÀûÀ¸·Î Áõ°¡ÇÏ´Â °ªÀ̹ǷΠ+ Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ¸ðµç ÄÄÇ»ÅÍ°¡ ¿äû ¼­ºñ½º¸¦ Áß´ÜÇÏ°í ÀÌÀü + ÀÎÄÚµù Çü½ÄÀ» ±×¸¸ »ç¿ëÇϱâÀ§ÇØ ±âÁØ ÃÊ(flag second)¸¸À¸·Î + ÃæºÐÇÏ´Ù. ÀÌÈÄ ¿äûÀ» Àç°ÔÇÏ°í »õ·Î¿î ÀÎÄÚµùÀ» ½ÃÀÛÇÒ ¼ö + ÀÖ´Ù.

    + +

    ¿ì¸®´Â ÀÌ ¹æ¹ýÀÌ ÀÌ ¹®Á¦¿¡ ´ëÇÏ¿© »ó´ëÀûÀ¸·Î Æ÷Æð¡´ÉÇÑ + ÇØ°áÃ¥À̶ó°í ¹Ï´Â´Ù. ÀÌ ¹æ¹ýÀº Windows NT¿Í °°Àº ¸ÖƼ¾²·¹µå + ½Ã½ºÅÛÀ¸·Î È®ÀåÇÒ ¼ö ÀÖ°í, ¾ÕÀ¸·Î ¿ëµµ¿¡ µû¶ó È®ÀåÇÒ ¼ö + ÀÖ´Ù. ¹Ì·¡¿¡ ÇÊ¿äÇѸ¸Å­ ´õ ±ä ½Äº°ÀÚ¸¦ ¸¸µé ¼ö Àֱ⶧¹®¿¡ + »ý¼ºÇÑ ½Äº°ÀÚ´Â ±âº»ÀûÀ¸·Î ¿µ¿øÇÑ ¼ö¸íÀ» °¡Áø´Ù. ±âº»ÀûÀ¸·Î + Ŭ·¯½ºÅÍÀÇ ÄÄÇ»ÅÍµé »çÀÌ¿¡ Åë½ÅÀÌ ÇÊ¿ä¾ø°í (ºÎÇÏ°¡ ÀÛÀº + NTP µ¿±â¸¸ ÇÊ¿äÇÏ´Ù), httpd ÇÁ·Î¼¼½º »çÀÌ¿¡ Åë½Åµµ ÇÊ¿ä¾ø´Ù + (Ä¿³ÎÀÌ ºÎ¿©ÇÏ´Â pid°ªÀÌ ¾Ï¹¬ÀûÀÎ Åë½ÅÀÌ´Ù). ¸Å¿ì ƯÀÌÇÑ + »óȲÀ̶ó¸é ÀνÄÀÚ Å©±â¸¦ ÁÙÀÏ ¼ö ÀÖÁö¸¸ ´õ ¸¹Àº Á¤º¸¸¦ + °¡Á¤ÇØ¾ß ÇÑ´Ù. (¿¹¸¦ µé¾î, ¾î¶² »çÀÌÆ®¿¡¼­ 32ºñÆ® IP ÁÖ¼Ò + ±¸ºÐÀº ºÒÇÊ¿äÇÏ°Ô Å©Áö¸¸, À̸¦ ÁÙÀÌ´Â ¹æ¹ýÀº »óȲ¿¡ µû¶ó + ´Ù¸£´Ù.)

    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_unique_id.xml b/trunk/docs/manual/mod/mod_unique_id.xml new file mode 100644 index 0000000000..47ece54a27 --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.xml @@ -0,0 +1,200 @@ + + + + + + + + + +mod_unique_id +Provides an environment variable with a unique +identifier for each request +Extension +mod_unique_id.c +unique_id_module + + + +

    This module provides a magic token for each request which is + guaranteed to be unique across "all" requests under very + specific conditions. The unique identifier is even unique + across multiple machines in a properly configured cluster of + machines. The environment variable UNIQUE_ID is + set to the identifier for each request. Unique identifiers are + useful for various reasons which are beyond the scope of this + document.

    +
    + +
    + Theory + +

    First a brief recap of how the Apache server works on Unix + machines. This feature currently isn't supported on Windows NT. + On Unix machines, Apache creates several children, the children + process requests one at a time. Each child can serve multiple + requests in its lifetime. For the purpose of this discussion, + the children don't share any data with each other. We'll refer + to the children as httpd processes.

    + +

    Your website has one or more machines under your + administrative control, together we'll call them a cluster of + machines. Each machine can possibly run multiple instances of + Apache. All of these collectively are considered "the + universe", and with certain assumptions we'll show that in this + universe we can generate unique identifiers for each request, + without extensive communication between machines in the + cluster.

    + +

    The machines in your cluster should satisfy these + requirements. (Even if you have only one machine you should + synchronize its clock with NTP.)

    + +
      +
    • The machines' times are synchronized via NTP or other + network time protocol.
    • + +
    • The machines' hostnames all differ, such that the module + can do a hostname lookup on the hostname and receive a + different IP address for each machine in the cluster.
    • +
    + +

    As far as operating system assumptions go, we assume that + pids (process ids) fit in 32-bits. If the operating system uses + more than 32-bits for a pid, the fix is trivial but must be + performed in the code.

    + +

    Given those assumptions, at a single point in time we can + identify any httpd process on any machine in the cluster from + all other httpd processes. The machine's IP address and the pid + of the httpd process are sufficient to do this. So in order to + generate unique identifiers for requests we need only + distinguish between different points in time.

    + +

    To distinguish time we will use a Unix timestamp (seconds + since January 1, 1970 UTC), and a 16-bit counter. The timestamp + has only one second granularity, so the counter is used to + represent up to 65536 values during a single second. The + quadruple ( ip_addr, pid, time_stamp, counter ) is + sufficient to enumerate 65536 requests per second per httpd + process. There are issues however with pid reuse over time, and + the counter is used to alleviate this issue.

    + +

    When an httpd child is created, the counter is initialized + with ( current microseconds divided by 10 ) modulo 65536 (this + formula was chosen to eliminate some variance problems with the + low order bits of the microsecond timers on some systems). When + a unique identifier is generated, the time stamp used is the + time the request arrived at the web server. The counter is + incremented every time an identifier is generated (and allowed + to roll over).

    + +

    The kernel generates a pid for each process as it forks the + process, and pids are allowed to roll over (they're 16-bits on + many Unixes, but newer systems have expanded to 32-bits). So + over time the same pid will be reused. However unless it is + reused within the same second, it does not destroy the + uniqueness of our quadruple. That is, we assume the system does + not spawn 65536 processes in a one second interval (it may even + be 32768 processes on some Unixes, but even this isn't likely + to happen).

    + +

    Suppose that time repeats itself for some reason. That is, + suppose that the system's clock is screwed up and it revisits a + past time (or it is too far forward, is reset correctly, and + then revisits the future time). In this case we can easily show + that we can get pid and time stamp reuse. The choice of + initializer for the counter is intended to help defeat this. + Note that we really want a random number to initialize the + counter, but there aren't any readily available numbers on most + systems (i.e., you can't use rand() because you need + to seed the generator, and can't seed it with the time because + time, at least at one second resolution, has repeated itself). + This is not a perfect defense.

    + +

    How good a defense is it? Suppose that one of your machines + serves at most 500 requests per second (which is a very + reasonable upper bound at this writing, because systems + generally do more than just shovel out static files). To do + that it will require a number of children which depends on how + many concurrent clients you have. But we'll be pessimistic and + suppose that a single child is able to serve 500 requests per + second. There are 1000 possible starting counter values such + that two sequences of 500 requests overlap. So there is a 1.5% + chance that if time (at one second resolution) repeats itself + this child will repeat a counter value, and uniqueness will be + broken. This was a very pessimistic example, and with real + world values it's even less likely to occur. If your system is + such that it's still likely to occur, then perhaps you should + make the counter 32 bits (by editing the code).

    + +

    You may be concerned about the clock being "set back" during + summer daylight savings. However this isn't an issue because + the times used here are UTC, which "always" go forward. Note + that x86 based Unixes may need proper configuration for this to + be true -- they should be configured to assume that the + motherboard clock is on UTC and compensate appropriately. But + even still, if you're running NTP then your UTC time will be + correct very shortly after reboot.

    + +

    The UNIQUE_ID environment variable is + constructed by encoding the 112-bit (32-bit IP address, 32 bit + pid, 32 bit time stamp, 16 bit counter) quadruple using the + alphabet [A-Za-z0-9@-] in a manner similar to MIME + base64 encoding, producing 19 characters. The MIME base64 + alphabet is actually [A-Za-z0-9+/] however + + and / need to be specially encoded + in URLs, which makes them less desirable. All values are + encoded in network byte ordering so that the encoding is + comparable across architectures of different byte ordering. The + actual ordering of the encoding is: time stamp, IP address, + pid, counter. This ordering has a purpose, but it should be + emphasized that applications should not dissect the encoding. + Applications should treat the entire encoded + UNIQUE_ID as an opaque token, which can be + compared against other UNIQUE_IDs for equality + only.

    + +

    The ordering was chosen such that it's possible to change + the encoding in the future without worrying about collision + with an existing database of UNIQUE_IDs. The new + encodings should also keep the time stamp as the first element, + and can otherwise use the same alphabet and bit length. Since + the time stamps are essentially an increasing sequence, it's + sufficient to have a flag second in which all machines + in the cluster stop serving and request, and stop using the old + encoding format. Afterwards they can resume requests and begin + issuing the new encodings.

    + +

    This we believe is a relatively portable solution to this + problem. It can be extended to multithreaded systems like + Windows NT, and can grow with future needs. The identifiers + generated have essentially an infinite life-time because future + identifiers can be made longer as required. Essentially no + communication is required between machines in the cluster (only + NTP synchronization is required, which is low overhead), and no + communication between httpd processes is required (the + communication is implicit in the pid value assigned by the + kernel). In very specific situations the identifier can be + shortened, but more information needs to be assumed (for + example the 32-bit IP address is overkill for any site, but + there is no portable shorter replacement for it).

    +
    + + +
    diff --git a/trunk/docs/manual/mod/mod_unique_id.xml.ja b/trunk/docs/manual/mod/mod_unique_id.xml.ja new file mode 100644 index 0000000000..6dda348623 --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.xml.ja @@ -0,0 +1,199 @@ + + + + + + + + + +mod_unique_id +$B$=$l$>$l$N%j%/%(%9%H$KBP$9$k0l0U$J<1JL;R$NF~$C$?4D6-JQ?t$r(B +$BDs6!$9$k(B +Extension +mod_unique_id.c +unique_id_module + + + +

    $B$3$N%b%8%e!<%k$OHs>o$K@)8B$5$l$?>r7o2<$G!"(B + $B$=$l$>$l$N%j%/%(%9%H$K!V$9$Y$F!W$N%j%/%(%9%H$KBP$7$F(B + $B0l0U$K7h$^$k$3$H$,J]>Z$5$l$F$$$kKbK!$N%H!<%/%s$rDs6!$7$^$9!#(B + $B$3$N0l0U$J<1JL;R$O!"E,@Z$K@_Dj$5$l$?%/%i%9%?$G$OJ#?t$N(B + $B%^%7%s$N4V$G$5$($b0l0U$K$J$j$^$9!#$=$l$>$l$N%j%/%(%9%H$KBP$7$F4D6-JQ?t(B + UNIQUE_ID $B$K<1JL;R$,@_Dj$5$l$^$9!#(B + $B0l0U$J<1JL;R$,JXMx$JM}M3$O$$$m$$$m$"$j$^$9$,!"(B + $B$3$N%I%-%e%a%s%H$NL\E*$+$i$O30$l$k$?$a!"$3$3$G$O@bL@$7$^$;$s!#(B

    +
    + +
    + $BM}O@(B + +

    $B$^$:$O$8$a$K!"(BApache $B%5!<%P$,(B Unix + $B%^%7%s$G$I$N$h$&$KF0:n$r$9$k$+$r4JC1$K@bL@$7$^$9!#(B + $B$3$N5!G=$O8=;~E@$G$O(B Windows NT $B$G$O%5%]!<%H$5$l$F$$$^$;$s!#(B + Unix $B%^%7%s$G$O(B Apache $B$O$$$/$D$+$N;R%W%m%;%9$r:n@.$7!"(B + $B$=$N;R%W%m%;%9$,0l$D$:$D%j%/%(%9%H$r=hM}$7$^$9!#$=$l$>$l$N;R%W%m%;%9$O!"(B + $B@8B84|4VCf$KJ#?t$N%j%/%(%9%H$r07$&$3$H$,$G$-$^$9!#(B + $B$3$N5DO@$G$O;R%W%m%;%94V$G$O0l@Z%G!<%?$r6&M-$7$J$$$3$H$K$7$^$9!#(B + $B0J8e!"$3$N;R%W%m%;%9$N$3$H$r(B httpd $B%W%m%;%9(B $B$H8F$S$^$9!#(B

    + +

    $B$"$J$?$N%&%'%V%5%$%H$K$O$"$J$?$,4IM}$9$k$$$/$D$+$N%^%7%s$,$"$k$H$7$^$9!#(B + $B$=$l$i$r$^$H$a$F%/%i%9%?$H8F$V$3$H$K$7$^$9!#$=$l$>$l$N%^%7%s$OJ#?t$N(B + Apache $B$rDj$N2<$G!"%/%i%9%?$N%^%7%s4V$,$?$/$5$sDL?.$r$9$k$3$H$J$/!"(B + $B$3$N1'Ch$NCf$G$=$l$>$l$N%j%/%(%9%H$K0l0U$J<1JL;R$r@8@.$G$-$k$3$H$r<($7$^$9!#(B +

    + +

    $B%/%i%9%?$K$"$k%^%7%s$O0J2<$NMW5a$r8+$?$5$J$1$l$P$J$j$^$;$s!#(B + ($B%^%7%s$,0l$D$@$1$@$H$7$F$b!"(BNTP $B$G;~7W$r9g$o$;$kJ}$,NI$$$G$9!#(B)

    + +
      +
    • NTP $B$dB>$N%M%C%H%o!<%/>e$G;~4V$r9g$o$;$k%W%m%H%3%k$K$h$C$F(B + $B3F%^%7%s$N;~4V$NF14|$, + +
    • $B%b%8%e!<%k$,%[%9%HL>$r0z$$$F0c$&(B IP + $B%"%I%l%9$r$l$N%^%7%s$N%[%9%HL>$,0c$&$3$H!#(B
    • +
    + +

    $B%*%Z%l!<%F%#%s%0%7%9%F%`$K$*$$$F$O!"(Bpid ($B%W%m%;%9(B ID) $B$,(B + 32 $B%S%C%H$NHO0OFb$G$"$k$3$H$r2>Dj$7$^$9!#%*%Z%l!<%F%#%s%0%7%9%F%`$N(B + pid $B$,(B 32 $B%S%C%H$rD6$($k>l9g$O!"4JC1$J=$@5$G$O$"$j$^$9$,!"(B + $B%3!<%I$rJQ99$9$kI,MW$,$"$j$^$9!#(B

    + +

    $B$3$l$i$N2>Dj$,K~$?$5$l$F$$$k$H!"$"$k;~E@$K$*$$$F!"(B + $B%/%i%9%?Fb$N$I$N%^%7%s$N$I$N(B httpd + $B%W%m%;%9$G$b!"0l0U$KF1Dj$9$k$3$H$,$G$-$^$9!#$3$l$O%^%7%s$N(B IP + $B%"%I%l%9$H(B httpd $B%W%m%;%9$N(B pid $B$G==J,$K9T$J$&$3$H$,$G$-$^$9!#(B + $B$G$9$+$i!"%j%/%(%9%H$K0l0U$J<1JL;R$r@8@.$9$k$?$a$K$O!"(B + $B;~9o$r6hJL$9$kI,MW$,$"$k$@$1$G$9!#(B

    + +

    $B;~9o$r6hJL$9$k$?$a$K!"(BUnix $B$N%?%$%`%9%?%s%W(B (UTC $B$N(B 1970 $BG/(B + 1 $B7n(B 1 $BF|$+$i$NIC?t(B) $B$H!"(B16 $B%S%C%H$N%+%&%s%?$r;H$$$^$9!#(B + $B%?%$%`%9%?%s%W$NN3EY$O0lIC$G$9$N$G!"0lIC4V$N(B 65536 + $B$^$G$NCM$rI=8=$9$k$?$a$K%+%&%s%?$r;HMQ$7$^$9!#;M$D$NCM(B + ( ip_addr, pid, time_stamp, counter ) $B$G3F(B httpd + $B%W%m%;%9$G0lIC$N4V$K(B 65536 $B%j%/%(%9%H$r?t$($"$2$k$3$H$,$G$-$^$9!#(B + $B;~4V$,7P$D$H(B pid $B$,:FMxMQ$5$l$k$H$$$&LdBj$,$"$j$^$9$,!"(B + $B$3$NLdBj$r2r7h$9$k$?$a$K%+%&%s%?$,;HMQ$5$l$^$9!#(B

    + +

    httpd $B$N;R%W%m%;%9$,:n@.$5$l$k$H!"%+%&%s%?$O(B + ($B$=$N;~E@$N%^%$%/%mIC(B $B!`(B 10) modulo 65536 $B$G=i4|2=$5$l$^$9(B + ($B$3$N<0$O$$$/$D$+$N%7%9%F%`$K$"$k!"%^%$%/%mIC$N(B + $B%?%$%^$N2<0L%S%C%H$,0[$J$k$H$$$&LdBj$r2r7h$9$k$?$a$KA*$P$l$^$7$?(B)$B!#(B + $B0l0U$J<1JL;R$,@8@.$5$l$?$H$-!";HMQ$5$l$k%?%$%`%9%?%s%W$O(B + $B%&%'%V%5!<%P$K%j%/%(%9%H$,E~Ce$7$?;~9o$K$J$j$^$9!#(B + $B%+%&%s%?$O<1JL;R$,@8@.$5$l$k$?$S$KA}2C$7$^$9(B + ($B$"$U$l$?>l9g$O(B 0 $B$KLa$j$^$9(B)$B!#(B

    + +

    $B%+!<%M%k$O%W%m%;%9$r%U%)!<%/$9$k$H!"$=$l$>$l$N%W%m%;%9$N$?$a$K(B + pid $B$r@8@.$7$^$9!#(Bpid $B$O7+$jJV$5$l$k$3$H$,5v2D$5$l$F$$$^$9(B + (pid $B$NCM$OB?$/$N(B Unix $B$G$O(B 16 $B%S%C%H$G$9$,!"?7$7$$%7%9%F%`$G$O(B + 32 $B%S%C%H$K3HD%$5$l$F$$$^$9(B)$B!#(B + $B$G$9$+$i!"$"$kDxEY$N;~4V$,7P2a$9$k$HF1$8(B pid $B$,:F$S;HMQ$5$l$^$9!#(B + $B$7$+$7!"0lICFb$K:F;HMQ$5$l$J$1$l$P!"(B + $B;M$D$NCM$N0l0U@-$OJ]$?$l$^$9!#$D$^$j!"2f!9$O%7%9%F%`$,0lIC4V(B + $B$K(B 65536 $B8D$N%W%m%;%9$r5/F0$7$J$$$H2>Dj$7$F$$$^$9(B ($B$$$/$D$+$N(B Unix + $B$G$O(B 32768 $B%W%m%;%9$G$9$,!"$=$l$G$9$i$[$H$s$I$"$jF@$J$$$G$7$g$&(B)$B!#(B

    + +

    $B2?$i$+$NM}M3$G!"F1$8;~9o$,7+$jJV$5$l$?$H$7$^$7$g$&!#(B + $B$D$^$j!"%7%9%F%`$N;~7W$,68$C$F$$$F!"$b$&0lEY2a5n$N;~9o$K$J$C$F$7$^$C$?(B + ($B$b$7$/$O?J$_$9$.$F$$$?$H$-$K!"(B + $B@5$7$$;~9o$KLa$7$?$?$a$K:F$S>-Mh$N;~9o$K$J$C$F$7$^$C$?(B) $B$H$7$^$9!#(B + $B$3$N>l9g!"(Bpid $B$H%?%$%`%9%?%s%W$,:F;HMQ$5$l$k$3$H$,4JC1$K<($5$l$^$9!#(B + $B%+%&%s%?=i4|2=MQ$N4X?t$O!"$3$NLdBj$N2sHr$r$B$9$J$o$A(B$B!"(Brand ()$B$O;H$($^$;$s!#(Brand () $B$K$O(B seed + $B$rM?$($kI,MW$,$"$j!"(Bseed $B$K$O;~9o$r;H$($^$;$s!#0lICC10L$G$O!"(B + $B$=$N;~9o$O$9$G$K7+$jJV$5$l$F$$$k$+$i$G$9(B)$B!#(B + $B$3$l$O!"40`z$JBP:v$G$O$"$j$^$;$s!#(B

    + +

    $B$3$NBP:v$O$I$N$/$i$$8z2L$,$"$k$G$7$g$&$+(B? + $B$3$3$G$O!"%^%7%s72$NCf$N0l$D$O:GBg$G0lIC$K(B 500 + $B%j%/%(%9%H$r07$&$H2>Dj$7$^$9(B ($B$3$l$r=q$$$F$$$k;~E@$G$OBEEv$J>e8B$G$9!#(B + $BDL>o%7%9%F%`$,$9$k$3$H$O@EE*$J%U%!%$%k$ro$KHa4QE*$JNc$G!" + +

    $B%5%^!<%?%$%`$K$h$j;~7W$,!VLa$5$l$k!W$3$H$r5$$K$7$F$$$k?M$,(B + $B$$$k$+$b$7$l$^$;$s!#$3$3$G;HMQ$5$l$k;~4V$O(B UTC $B$G$"$j!"(B + $B$=$l$O!V>o$K!W?J$`$N$G$3$3$G$OLdBj$K$J$j$^$;$s!#(Bx86 $B>e$N(B Unix + $B$O$3$N>r7o$rK~$?$9$?$a$KE,@Z$J@_Dj$,I,MW$+$b$7$l$J$$$3$H$K(B + $BCm0U$7$F$/$@$5$$!#%^%6!<%\!<%I$N;~7W$O(B UTC $B$K$J$C$F$$$F!"(B + $BB>$N;~4V$O$=$3$+$iE,@Z$KJd@5$5$l$k$3$H$r2>Dj$G$-$k$h$&$K(B + $B@_Dj$5$l$J$1$l$P$J$j$^$;$s!#$=$N$h$&$J>l9g$G$5$(!"(BNTP + $B$r;H$C$F$$$k$J$i$P%j%V!<%H8e$K$9$0@5$7$$(B UTC $B$N;~4V$K$J$k$G$7$g$&!#(B

    + +

    UNIQUE_ID $B4D6-JQ?t$O(B 112 $B%S%C%H(B (32 $B%S%C%H(B IP + $B%"%I%l%9!"(B32 $B%S%C%H(B pid, 32 $B%S%C%H%?%$%`%9%?%s%W!"(B16 + $B%S%C%H%+%&%s%?$N;M$D$NAH(B) $B$r%"%k%U%!%Y%C%H(B [A-Za-z0-9@-] + $B$rMQ$$$F(B MIME $B$N(B base64 $BId9f2=$HF1MM$NJ}K!$K$h$jId9f2=$7!"(B19 + $B$NJ8;z$r@8@.$9$k$3$H$K$h$j:n@.$5$l$^$9!#(BMIME $B$N(B base64 + $B$N%"%k%U%!%Y%C%H$O[A-Za-z0-9+/] $B$G$9$,!"(B + + $B$H(B / $B$H$O(B URL + $B$G$OFCJL$JId9f2=$,I,MW$J$N$G!"$"$^$jK>$^$7$/$"$j$^$;$s!#(B + $BA4$F$NCM$O%M%C%H%o!<%/%P%$%H%*!<%@$GId9f2=$5$l$^$9$N$G!"(B + $BId9f$O0c$C$?%P%$%H%*!<%@$N%"!<%-%F%/%A%c4V$GHf3S2DG=$G$9!#(B + $BUNIQUE_ID + $BA4BN$rF)2aE*$J%H!<%/%s$H$7$F07$&$Y$-$G$9!#(B + UNIQUE_ID $B$OB>$N(B UNIQUE_ID + $B$H$NEy2A@-$rD4$Y$k$?$a$@$1$K$N$_;HMQ$G$-$^$9!#(B

    + +

    $B$3$N=gHV$O>-Mh!"4{B8$N(B UNIQUE_ID + $B$N%G!<%?%Y!<%9$H$N>WFM$r?4G[$9$k$3$H$J$/Id9f$rJQ99$9$k$3$H$,(B + $B2DG=$K$J$k$h$&$KA*Br$7$F$$$^$9!#(B + $B?7$7$$Id9f$O%?%$%`%9%?%s%W$r:G=i$NMWAG$H$7$F;D$9$N$,K>$^$7$/!"(B + $B$=$l0J30$OF1$8%"%k%U%!%Y%C%H$H%S%C%HD9$r;H$&$3$H$,$G$-$^$9!#(B + $B%?%$%`%9%?%s%W$OK\$B%U%i%0IC(B$B$,$"$l$P==J,$G$9!#(B + $B$=$N8e$O!"%j%/%(%9%H$r:F3+$7!"(B + $B?7$7$$Id9f$rH/9T$9$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B

    + +

    $B2f!9$O$3$l$,!"(B + $B$3$NLdBj$KBP$9$kHf3SE*0\?"@-$N9b$$2r7hK!$@$H9M$($F$$$^$9!#(B + Windows NT $B$N$h$&$J%^%k%A%9%l%C%I$N%7%9%F%`$K3HD%$9$k$3$H$,$G$-$^$9$7!"(B + $B>-MhI,MW$K$J$l$P$5$i$KA}$d$9$3$H$b$G$-$^$9!#(B + ID $B$OI,MW$K1~$8$FD9$/$9$k$3$H$,$G$-$^$9$N$G!"@8@.$5$l$?(B ID + $B$Oe!"L58B$KM-8z$G$9!#$^$?!"%/%i%9%?$N%^%7%s4V$NDL?.$b;veI,MW$J$/(B + (NTP $B$K$h$kF14|$N$_$,I,MW$G!"$3$l$O%*!<%P%X%C%I$O$"$^$j$"$j$^$;$s(B)$B!"(Bhttpd + $B%W%m%;%94V$NDL?.$bI,MW$"$j$^$;$s(B ($BDL?.$O%+!<%M%k$K$h$j3d$jEv$F$i$l$?(B + pid $B$NCM$K$h$j0EL[$NFb$K9T$J$o$F$$$^$9(B)$B!#(B + $B$5$i$K8B$i$l$?>u672<$G$O!"(BID $B$O$5$i$KC;$/$9$k$3$H$,$G$-$^$9$,!"(B + $B$h$jB?$/$N>pJs$r2>Dj$9$kI,MW$,$G$F$-$^$9(B ($BNc$($P!"(B32 $B%S%C%H(B + IP $B%"%I%l%9$O$I$N%5%$%H$K$*$$$F$b2a>j$J>pJs$G$9$,!"(B + $B$=$l$NBe$o$j$K$J$k0\?"@-$N$"$k$b$N$O$"$j$^$;$s(B)$B!#(B

    +
    + + +
    diff --git a/trunk/docs/manual/mod/mod_unique_id.xml.ko b/trunk/docs/manual/mod/mod_unique_id.xml.ko new file mode 100644 index 0000000000..281c0be745 --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.xml.ko @@ -0,0 +1,174 @@ + + + + + + + + + +mod_unique_id +°¢ ¿äû¸¶´Ù À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ °¡Áö´Â ȯ°æº¯¼ö¸¦ +Á¦°øÇÑ´Ù +Extension +mod_unique_id.c +unique_id_module + + + +

    ÀÌ ¸ðµâÀº ¾î¶² Ưº°ÇÑ »óȲ¿¡¼­µµ "¸ðµç" ¿äûÁß¿¡¼­ + À¯ÀÏÇϵµ·Ï º¸ÀåµÈ ½Äº°ÀÚ(identifier)¸¦ ¸ðµç ¿äû¿¡ Á¦°øÇÑ´Ù. + ½ÉÁö¾î ÀÌ ½Äº°Àڴ Ưº°ÇÏ°Ô ±¸¼ºÇÑ Å¬·¯½ºÅÍÀÇ ¿©·¯ ÄÄÇ»Å͵é + Áß¿¡¼­µµ À¯ÀÏÇÏ´Ù. °¢ ¿äû¸¶´Ù ȯ°æº¯¼ö + UNIQUE_ID¸¦ ¼³Á¤ÇÑ´Ù. À¯ÀÏÇÑ ½Äº°ÀÚ´Â ¿©·¯°¡Áö + ¿ëµµ·Î »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ¼³¸íÀº ÀÌ ¹®¼­ÀÇ ¹üÀ§¸¦ ³Ñ¾î¼±´Ù.

    +
    + +
    + ÀÌ·Ð + +

    ¸ÕÀú À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡ ¼­¹ö°¡ ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö + °£·«È÷ »ìÆ캸ÀÚ. Windows NT´Â ÇöÀç ÀÌ ±â´ÉÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù. + À¯´Ð½º¿¡¼­ ¾ÆÆÄÄ¡´Â ¿©·¯ ÀÚ½ÄÀ» ¸¸µé°í, ÀÚ½Ä ÇÁ·Î¼¼½º´Â + Çѹø¿¡ ÇÑ ¿äû¾¿ ó¸®ÇÑ´Ù. ÀÚ½ÄÀº ½ÇÇàÁß¿¡ ¿©·¯ ¿äûÀ» + ó¸®ÇÑ´Ù. ¿©±â¼­ Áß¿äÇÑ °ÍÀº ÀڽĵéÀÌ ¼­·Î ÀڷḦ + °øÀ¯ÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù. ¾ÕÀ¸·Î ÀÚ½ÄÀ» httpd ÇÁ·Î¼¼½º¶ó°í + ÇÑ´Ù.

    + +

    ¿©·¯ ÄÄÇ»ÅÍ·Î À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇÑ´Ù¸é Ŭ·¯½ºÅÍ(cluster)¶ó°í + ºÎ¸¥´Ù. °¢ ÄÄÇ»ÅÍ´Â ¿©·¯ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÀÌµé ¸ðµÎ¸¦ + "¿ìÁÖ"·Î º¸¸é, Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ÄÄÇ»Å͵鰣¿¡ ¸¹Àº Åë½Å¾øÀÌ + °¢ ¿äû¸¶´Ù ¿ìÁÖ¿¡¼­ À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µé ¼ö ÀÖ´Ù.

    + +

    Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ÄÄÇ»ÅÍ´Â ´ÙÀ½ ¿ä±¸»çÇ×À» ¸¸Á·ÇØ¾ß ÇÑ´Ù. + (ÄÄÇ»Å͸¦ ÇѴ븸 »ç¿ëÇÏ´õ¶óµµ ÄÄÇ»ÅÍ ½Ã°£À» NTP¿Í µ¿±âÇØ¾ß + ÇÑ´Ù.)

    + +
      +
    • ÄÄÇ»ÅÍ ½Ã°£Àº NTP³ª ´Ù¸¥ ³×Æ®¿÷ ½Ã°£ ÇÁ·ÎÅäÄÝ°ú + µ¿±âÈ­µÈ´Ù.
    • + +
    • ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸íÀÌ ¸ðµÎ ´Ù¸£´Ù. ±×·¡¼­ ¸ðµâÀÌ + È£½ºÆ®¸íÀ¸·Î ãÀ¸¸é Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â °¢ ÄÄÇ»Å͸¶´Ù ´Ù¸¥ + IP ÁÖ¼Ò¸¦ ¾ò´Â´Ù.
    • +
    + +

    ¿î¿µÃ¼Á¦¿¡¼­ pid (ÇÁ·Î¼¼½º id)°¡ 32ºñÆ®¿¡ µé¾î°£´Ù°í + °¡Á¤ÇÑ´Ù. ¿î¿µÃ¼Á¦°¡ pid·Î 32ºñÆ® ÀÌ»óÀ» »ç¿ëÇÑ´Ù¸é °£´ÜÇÏÁö¸¸ + Äڵ带 ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ÀÌ·± °¡Á¤ÇÏ¿¡ ¿ì¸®´Â ¾î¶² ½ÃÁ¡¿¡¼­ Ŭ·¯½ºÅÍÀÇ ¾î¶² ÄÄÇ»ÅÍ¿¡ + ÀÖ´Â ¾î¶² httpd ÇÁ·Î¼¼½º¸¦ ´Ù¸¥ ¸ðµç httpd ÇÁ·Î¼¼½ºµé°ú + ±¸º°ÇÒ ¼ö ÀÖ´Ù. ÄÄÇ»ÅÍÀÇ IP ÁÖ¼Ò¿Í httpd ÇÁ·Î¼¼½ºÀÇ pid¸¸À¸·Îµµ + ÃæºÐÈ÷ ±¸º°ÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ¿äû¿¡ ´ëÇØ À¯ÀÏÇÑ ±¸º°ÀÚ¸¦ + ¸¸µå·Á¸é ½Ã°£Â÷¸¦ ±¸º°ÇÒ ¼ö¸¸ ÀÖÀ¸¸é µÈ´Ù.

    + +

    ½Ã°£À» ±¸º°ÇϱâÀ§ÇØ À¯´Ð½º ½Ã°£(timestamp, ¼¼°è Ç¥Áؽ÷Π+ 1970³â 1¿ù 1ÀÏ ÀÌÈÄ Áö³­ ÃÊ)°ú 16ºñÆ® Ä«¿îÅ͸¦ »ç¿ëÇÑ´Ù. + À¯´Ð½º ½Ã°£Àº ÃÊ´ÜÀ§ÀÌ°í, Ä«¿îÅÍ´Â ÀÏ Ãʵ¿¾È 65536±îÁö + Áõ°¡ÇÑ´Ù. ( ip_addr, pid, time_stamp, counter ) + ¹­À½Àº ¾î¶² httpd ÇÁ·Î¼¼½º¿¡¼­ ÀÏ Ãʵ¿¾È 65536 ¿äûÀ» ±¸º°ÇÒ + ¼ö ÀÖ´Ù. ±×·¯³ª Ä«¿îÅÍ´Â pid¸¦ Àç»ç¿ëÇÏ´Â ¹®Á¦¸¦ ÇØ°áÇØ¾ß + ÇÑ´Ù.

    + +

    httpd ÀÚ½ÄÀ» ¸¸µé¸é Ä«¿îÅÍ´Â ( ÇöÀç ¹Ð¸®ÃÊ ³ª´©±â 10 )À» + 65536À¸·Î ³ª´« ³ª¸ÓÁö°¡ µÈ´Ù. (¸î¸î ½Ã½ºÅÛÀÇ ¹Ð¸®ÃÊ ½Ã°£¿¡¼­ + ÇÏÀ§ ºñÆ®°¡ ÀÏÄ¡ÇÏÁö¾Ê´Â ¹®Á¦¶§¹®¿¡ ÀÌ °ø½ÄÀ» ¸¸µé¾ú´Ù.) + À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µé¶§ »ç¿ëÇÏ´Â ½Ã°£Àº À¥¼­¹ö°¡ ¿äûÀ» ¹ÞÀº + ½Ã°£ÀÌ´Ù. Ä«¿îÅÍ´Â ½Äº°ÀÚ¸¦ ¸¸µé¶§¸¶´Ù Áõ°¡ÇÑ´Ù (±×¸®°í + ´Ù½Ã ½ÃÀÛÇÑ´Ù).

    + +

    Ä¿³ÎÀº ÇÁ·Î¼¼½º¸¦ Æ÷Å©ÇÒ¶§(fork) °¢ ÇÁ·Î¼¼½º¿¡ pid¸¦ + ÇÒ´çÇÏ°í, pid´Â ´Ù½Ã ½ÃÀÛÇÒ ¼ö ÀÖ´Ù. (pid´Â ¸¹Àº À¯´Ð½º¿¡¼­ + 16ºñÆ®ÀÌÁö¸¸, ÃÖ±Ù ½Ã½ºÅÛÀº 32ºñÆ®·Î È®ÀåÇß´Ù.) ±×·¡¼­ ½Ã°£ÀÌ + Áö³ª¸é °°Àº pid¸¦ Àç»ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª °°Àº ½Ã°£¿¡ pid¸¦ + Àç»ç¿ëÇÏÁö ¾Ê´Â´Ù¸é À§ÀÇ ¹­À½Àº À¯ÀÏÇÏ´Ù. Áï, ¿ì¸®´Â ½Ã½ºÅÛÀÌ + ÀÏÃʵ¿¾È ÇÁ·Î¼¼½º¸¦ 65536°³ ÀÌ»ó ¸¸µéÁö ¾Ê´Â´Ù°í °¡Á¤ÇÑ´Ù. + (¾î¶² À¯´Ð½º¿¡¼­´Â 32768°³ ÀÌ»ó ÇÁ·Î¼¼½º¸¦ ¸¸µé¸é pid Àç»ç¿ë + ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖÁö¸¸, ÀÌ°ÍÁ¶Â÷µµ ÀϾ °Í°°Áö ¾Ê´Ù.)

    + +

    ½Ã°£ÀÌ ¾î¶² ÀÌÀ¯¿¡¼­°Ç ¹Ýº¹µÈ´Ù°í °¡Á¤Çغ¸ÀÚ. Áï, ½Ã½ºÅÛ + ½Ã°è°¡ ²¿¿©¼­ ½Ã°£ÀÌ °ú°Å·Î µ¹¾Æ°¡´Â (ȤÀº ½Ã°è°¡ ³Ê¹« ¾Õ¼­°¡¼­ + ¿Ã¹Ù·Î Àç¼³Á¤ÇÑÈÄ ¹Ì·¡¿¡ °°Àº ½Ã°£ÀÌ µÇ´Â) °æ¿ì´Ù. ÀÌ °æ¿ì + pid¿Í ½Ã°£À» ¸ðµÎ Àç»ç¿ëÇÒ ¼ö ÀÖ´Ù. Ä«¿îÅÍÀÇ ÃʱâÈ­ °ø½ÄÀº + ÀÌ ¹®Á¦¸¦ ÇØ°áÇÏ·Á°í °í¾ÈµÇ¾ú´Ù. ¿ì¸®´Â ½ÇÁ¦ ¹«ÀÛÀ§ ¼ýÀÚ·Î + Ä«¿îÅ͸¦ ÃʱâÈ­ÇÏ±æ ¿øÇÏÁö¸¸, ¸¹Àº ½Ã½ºÅÛ¿¡¼­ ÀÌ·± ¼ö¸¦ + ½±°Ô ¾òÀ» ¼ö ¾ø´Ù. (¿¹¸¦ µé¾î, seed°¡ ÇÊ¿äÇϱ⶧¹®¿¡ + rand()¸¦ »ç¿ëÇÒ ¼ö ¾ø°í, ½Ã°£Àº ÃÖ¼ÒÇÑ ÀÏÃÊ ´ÜÀ§À̱⶧¹®¿¡ + ½Ã°£À¸·Î seed·Î »ç¿ëÇÒ ¼ö ¾ø´Ù.) Áï ¿Ïº®ÇÑ ÇØ°áÃ¥ÀÌ ¾ø´Ù.

    + +

    ±×·³ ÀÌ ¹æ¹ýÀº ¾ó¸¶³ª ±¦ÂúÀ»±î? ÄÄÇ»ÅÍÁß Çϳª°¡ ¿äûÀ» + ÃÊ´ç ÃÖ´ë 500°³ (½Ã½ºÅÛÀº ÀϹÝÀûÀ¸·Î Á¤ÀûÀÎ ÆÄÀÏÀ» Àü¼ÛÇÏ´Â + °Í ÀÌ»óÀÇ ÀÛ¾÷À» ÇϹǷΠÀÌ ±ÛÀ» ¾²´Â ½ÃÁ¡¿¡¼­ »ó´çÈ÷ ³ôÀº + °ªÀÌ´Ù.) ¼­ºñ½ºÇÑ´Ù°í °¡Á¤ÇÏÀÚ. µ¿½Ã¿¡ ¾ó¸¶¸¸Å­ÀÇ Å¬¶óÀ̾ðÆ®¸¦ + ó¸®Çϴ°¡¿¡ µû¶ó ÀÚ½ÄÀÇ °³¼ö°¡ °áÁ¤µÈ´Ù. ±×·¯³ª ¿ì¸®´Â + ºñ°üÀûÀ¸·Î ÇÑ ÀÚ½ÄÀÌ ¿äûÀ» ÃÊ´ç 500°³ ó¸®ÇÒ ¼ö ÀÖ´Ù°í + °¡Á¤ÇÑ´Ù. Àç»ç¿ëÇÑ pid¸¦ °¡Áø ÀÚ½ÄÀÇ 500°³ ¿äû°ú ÀÌÀü ÀÚ½ÄÀÇ + 500°³ ¿äûÀÇ Ä«¿îÅÍ°ªÀÌ °ãÄ¥ ¼ö ÀÖ´Â Ä«¿îÅÍ ½ÃÀÛ°ª °æ¿ì¼ö´Â + 1000°³ÀÌ´Ù. ±×·¡¼­ (ÃÊ´ÜÀ§¿¡¼­) ÀÚ½ÄÀÌ Ä«¿îÅÍ°ªÀ» ¹Ýº¹ÇÏ¿© + À¯ÀϼºÀÌ ±úÁú È®·üÀº 1.5%ÀÌ´Ù. ÀÌ°ÍÀº ¸Å¿ì ºñ°üÀûÀÎ °¡Á¤À̸ç, + ½ÇÁ¦ ÀÌ·² °æ¿ì´Â »ó´çÈ÷ ´õ ³·´Ù. ±×·¡µµ ½Ã½ºÅÛ¿¡¼­ ÀÌ·± + ÀÏÀÌ ¹ß»ýÇÒ °Í °°´Ù¸é (¼Ò½º¸¦ ¼öÁ¤ÇÏ¿©) Ä«¿îÅ͸¦ 32ºñÆ®·Î + ¸¸µé¾î¶ó.

    + +

    ¼¶¸ÓŸÀÓ¶§¹®¿¡ ½Ã°è°¡ "µÚ·Î °¡´Â" °ÍÀ» °ÆÁ¤ÇÒÁöµµ ¸ð¸¥´Ù. + ±×·¯³ª ¿©±â¼­ »ç¿ëÇÏ´Â ½Ã°£Àº ±¹Á¦ Ç¥ÁؽÃ(UTC), Áï ½Ã°£ÀÌ + "Ç×»ó" ¾ÕÀ¸·Î °¡¹Ç·Î ¹®Á¦°¡ ¾ø´Ù. x86±â¹Ý À¯´Ð½º¿¡¼­´Â + ÀûÀýÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇÏ´Ù. ¸ÞÀκ¸µå ½Ã°è°¡ UTC¸¦ »ç¿ëÇϵµ·Ï + ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±×·¯³ª NTP¸¦ »ç¿ëÇÑ´Ù¸é Àç½ÃÀÛÈÄ Á¶±Ý Áö³ª¸é + UTC ½Ã°£¿¡ ¿Ã¹Ù·Î ¸ÂÃá´Ù.

    + +

    ȯ°æº¯¼ö UNIQUE_ID´Â MIME base64 ÀÎÄÚµù°ú + ºñ½ÁÇÑ ¹æ¹ýÀ¸·Î 112ºñÆ® (32ºñÆ® IP ÁÖ¼Ò, 32ºñÆ® pid, 32ºñÆ® + ½Ã°£, 16ºñÆ® Ä«¿îÅÍ) ¹­À½À» ¾ËÆĺª [A-Za-z0-9@-]·Î + Ç¥ÇöÇÑ´Ù. ½ÇÁ¦ MIME base64 ¾ËÆĺªÀº + [A-Za-z0-9+/]ÀÌÁö¸¸ +¿Í + /´Â URL¿¡¼­ Ưº°ÇÑ Àǹ̷Π»ç¿ëÇϹǷΠÁ¦¿ÜÇß´Ù. + ¸ðµç °ªÀ» ³×Æ®¿÷ ¹ÙÀÌÆ®¼ø¼­·Î ÀÎÄÚµùÇϱ⶧¹®¿¡ ´Ù¸¥ ¹ÙÀÌÆ®¼ø¼­¸¦ + »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃÄ°£¿¡ °ªÀÌ °°´Ù. ½ÇÁ¦ ÀÎÄÚµù ¼ø¼­´Â + ½Ã°£, IP ÁÖ¼Ò, pid, Ä«¿îÅÍ ¼ø¼­ÀÌ´Ù. ÀÌ ¼ø¼­¿¡´Â ¾î¶² ¸ñÀûÀÌ + ÀÖÁö¸¸, ÇÁ·Î±×·¥Àº ÀÎÄÚµù ¼ø¼­¿¡ ÀÇÁ¸ÇÏ¿© °ªµéÀ» ºÐ¼®Çϸé + ¾ÈµÊÀ» °­Á¶ÇÑ´Ù. ÇÁ·Î±×·¥Àº ÀÎÄÚµùµÈ UNIQUE_ID + Àüü¸¦ ÇÑ ´ÜÀ§·Î »ý°¢ÇÏ°í, ´Ù¸¥ UNIQUE_ID¿Í + µ¿ÀÏÇÑÁö¸¸ ºñ±³ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼ø¼­´Â ¾ÕÀ¸·Î ±âÁ¸ÀÇ UNIQUE_ID µ¥ÀÌÅͺ£À̽º¿Í + Ãæµ¹À» ¿°·ÁÇÏÁö¾Ê°í ÀÎÄÚµùÀ» º¯°æÇÒ ¼ö ÀÖµµ·Ï °í¾ÈÇß´Ù. + »õ·Î¿î ÀÎÄÚµùÀº ù Ç׸ñÀ¸·Î ½Ã°£À» »ç¿ëÇϰųª, °°Àº ¾ËÆĺª°ú + ºñÆ® ±æÀ̸¦ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. ½Ã°£ÀÌ ±âº»ÀûÀ¸·Î Áõ°¡ÇÏ´Â °ªÀ̹ǷΠ+ Ŭ·¯½ºÅÍ¿¡ ÀÖ´Â ¸ðµç ÄÄÇ»ÅÍ°¡ ¿äû ¼­ºñ½º¸¦ Áß´ÜÇÏ°í ÀÌÀü + ÀÎÄÚµù Çü½ÄÀ» ±×¸¸ »ç¿ëÇϱâÀ§ÇØ ±âÁØ ÃÊ(flag second)¸¸À¸·Î + ÃæºÐÇÏ´Ù. ÀÌÈÄ ¿äûÀ» Àç°ÔÇÏ°í »õ·Î¿î ÀÎÄÚµùÀ» ½ÃÀÛÇÒ ¼ö + ÀÖ´Ù.

    + +

    ¿ì¸®´Â ÀÌ ¹æ¹ýÀÌ ÀÌ ¹®Á¦¿¡ ´ëÇÏ¿© »ó´ëÀûÀ¸·Î Æ÷Æð¡´ÉÇÑ + ÇØ°áÃ¥À̶ó°í ¹Ï´Â´Ù. ÀÌ ¹æ¹ýÀº Windows NT¿Í °°Àº ¸ÖƼ¾²·¹µå + ½Ã½ºÅÛÀ¸·Î È®ÀåÇÒ ¼ö ÀÖ°í, ¾ÕÀ¸·Î ¿ëµµ¿¡ µû¶ó È®ÀåÇÒ ¼ö + ÀÖ´Ù. ¹Ì·¡¿¡ ÇÊ¿äÇѸ¸Å­ ´õ ±ä ½Äº°ÀÚ¸¦ ¸¸µé ¼ö Àֱ⶧¹®¿¡ + »ý¼ºÇÑ ½Äº°ÀÚ´Â ±âº»ÀûÀ¸·Î ¿µ¿øÇÑ ¼ö¸íÀ» °¡Áø´Ù. ±âº»ÀûÀ¸·Î + Ŭ·¯½ºÅÍÀÇ ÄÄÇ»ÅÍµé »çÀÌ¿¡ Åë½ÅÀÌ ÇÊ¿ä¾ø°í (ºÎÇÏ°¡ ÀÛÀº + NTP µ¿±â¸¸ ÇÊ¿äÇÏ´Ù), httpd ÇÁ·Î¼¼½º »çÀÌ¿¡ Åë½Åµµ ÇÊ¿ä¾ø´Ù + (Ä¿³ÎÀÌ ºÎ¿©ÇÏ´Â pid°ªÀÌ ¾Ï¹¬ÀûÀÎ Åë½ÅÀÌ´Ù). ¸Å¿ì ƯÀÌÇÑ + »óȲÀ̶ó¸é ÀνÄÀÚ Å©±â¸¦ ÁÙÀÏ ¼ö ÀÖÁö¸¸ ´õ ¸¹Àº Á¤º¸¸¦ + °¡Á¤ÇØ¾ß ÇÑ´Ù. (¿¹¸¦ µé¾î, ¾î¶² »çÀÌÆ®¿¡¼­ 32ºñÆ® IP ÁÖ¼Ò + ±¸ºÐÀº ºÒÇÊ¿äÇÏ°Ô Å©Áö¸¸, À̸¦ ÁÙÀÌ´Â ¹æ¹ýÀº »óȲ¿¡ µû¶ó + ´Ù¸£´Ù.)

    +
    + + +
    diff --git a/trunk/docs/manual/mod/mod_unique_id.xml.meta b/trunk/docs/manual/mod/mod_unique_id.xml.meta new file mode 100644 index 0000000000..6c6ba3413d --- /dev/null +++ b/trunk/docs/manual/mod/mod_unique_id.xml.meta @@ -0,0 +1,13 @@ + + + + mod_unique_id + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_userdir.html b/trunk/docs/manual/mod/mod_userdir.html new file mode 100644 index 0000000000..897ef83289 --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.html @@ -0,0 +1,11 @@ +URI: mod_userdir.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_userdir.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_userdir.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_userdir.html.en b/trunk/docs/manual/mod/mod_userdir.html.en new file mode 100644 index 0000000000..f9c836108d --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.html.en @@ -0,0 +1,175 @@ + + + +mod_userdir - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_userdir

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    Description:User-specific directories
    Status:Base
    Module Identifier:userdir_module
    Source File:mod_userdir.c
    +

    Summary

    + +

    This module allows user-specific directories to be accessed using the +http://example.com/~user/ syntax.

    +
    + + +
    top
    +

    UserDir Directive

    + + + + + + +
    Description:Location of the user-specific directories
    Syntax:UserDir directory-filename
    Context:server config, virtual host
    Status:Base
    Module:mod_userdir
    + +

    The UserDir directive sets the real + directory in a user's home directory to use when a request for a + document for a user is received. Directory-filename is + one of the following:

    + +
      +
    • The name of a directory or a pattern such as those shown + below.
    • + +
    • The keyword disabled. This turns off + all username-to-directory translations except those + explicitly named with the enabled keyword (see + below).
    • + +
    • The keyword disabled followed by a + space-delimited list of usernames. Usernames that appear in + such a list will never have directory translation + performed, even if they appear in an enabled + clause.
    • + +
    • The keyword enabled followed by a + space-delimited list of usernames. These usernames will have + directory translation performed even if a global disable is + in effect, but not if they also appear in a + disabled clause.
    • +
    + +

    If neither the enabled nor the + disabled keywords appear in the + Userdir directive, the argument is treated as a + filename pattern, and is used to turn the name into a directory + specification. A request for + http://www.foo.com/~bob/one/two.html will be + translated to:

    + + + + + + + +
    UserDir directive usedTranslated path
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    The following directives will send redirects to the client:

    + + + + + + + +
    UserDir directive usedTranslated path
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + +
    + Be careful when using this directive; for instance, + "UserDir ./" would map "/~root" to + "/" - which is probably undesirable. It is strongly + recommended that your configuration include a "UserDir + disabled root" declaration. See also the Directory directive and the Security Tips page for + more information. +
    + +

    Additional examples:

    + +

    To allow a few users to have UserDir directories, but +not anyone else, use the following:

    + +

    +UserDir disabled
    +UserDir enabled user1 user2 user3 +

    + +

    To allow most users to have UserDir directories, but +deny this to a few, use the following:

    + +

    +UserDir enabled
    +UserDir disabled user4 user5 user6 +

    + +

    It is also possible to specify alternative user directories. +If you use a command like:

    +

    +Userdir public_html /usr/web http://www.foo.com/ +

    +

    With a request for http://www.foo.com/~bob/one/two.html, will try to +find the page at ~bob/public_html/one/two.html first, then +/usr/web/bob/one/two.html, and finally it will send a redirect +to http://www.foo.com/bob/one/two.html.

    +

    If you add a redirect, it must be the last alternative in the list. +Apache cannot determine if the redirect succeeded or not, so if you have +the redirect earlier in the list, that will always be the alternative +that is used.

    + +

    User directory substitution is not active by default in versions +2.1.4 and later. In earlier versions, UserDir public_html +was assumed if no UserDir +directive was present.

    + + +

    See also

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_userdir.html.ja.euc-jp b/trunk/docs/manual/mod/mod_userdir.html.ja.euc-jp new file mode 100644 index 0000000000..bab775e9fa --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.html.ja.euc-jp @@ -0,0 +1,185 @@ + + + +mod_userdir - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_userdir

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + +
    ÀâÌÀ:¥æ¡¼¥¶ÀìÍѤΥǥ£¥ì¥¯¥È¥ê¤òÄó¶¡ +
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:userdir_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_userdir.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢ +http://example.com/~user/ +¹½Ê¸¤ò»È¤Ã¤Æ¥æ¡¼¥¶ÀìÍѥǥ£¥ì¥¯¥È¥ê¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    +
    + + +
    top
    +

    UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + +
    ÀâÌÀ:¥æ¡¼¥¶ÀìÍѥǥ£¥ì¥¯¥È¥ê¤Î°ÌÃÖ
    ¹½Ê¸:UserDir directory-filename
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    ¥¹¥Æ¡¼¥¿¥¹:Base
    ¥â¥¸¥å¡¼¥ë:mod_userdir
    + +

    UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥æ¡¼¥¶¤Î¥É¥­¥å¥á¥ó¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¤¿»þ¤Ë»È¤¦ + ¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥êÃæ¤Î¡¢¼ÂºÝ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò + ÀßÄꤷ¤Þ¤¹¡£ + directory-filename ¤Ë¤Ï¼¡¤Î¤É¤ì¤«¤ò»ØÄꤷ¤Þ¤¹:

    + +
      +
    • ¥Ç¥£¥ì¥¯¥È¥ê̾¤«²¼¤Ë¼¨¤¹¤è¤¦¤Ê¥Ñ¥¿¡¼¥ó¡£
    • + +
    • disabled ¥­¡¼¥ï¡¼¥É¡£ + enabled ¥­¡¼¥ï¡¼¥É (²¼µ­»²¾È) ¤ÇÌÀ¼¨Åª¤Ë + »ØÄꤵ¤ì¤¿¥æ¡¼¥¶°Ê³°¤Î + Á´¤Æ¤Î¥æ¡¼¥¶Ì¾-¥Ç¥£¥ì¥¯¥È¥êÊÑ´¹¤ò + ¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£
    • + +
    • disabled ¥­¡¼¥ï¡¼¥É¤È¡¢¥¹¥Ú¡¼¥¹¶èÀÚ¤ê¤Î¥æ¡¼¥¶Ì¾¥ê¥¹¥È¡£ + ¤³¤Î¥ê¥¹¥ÈÃæ¤Ë´Þ¤Þ¤ì¤ë¥æ¡¼¥¶Ì¾¤ËÂФ·¤Æ¤Ï¡¢¤¿¤È¤¨ + enabled Àá¤Ë¤¢¤Ã¤¿¤È¤·¤Æ¤â¡¢ + ·è¤·¤Æ¥Ç¥£¥ì¥¯¥È¥êÊÑ´¹¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¡£
    • + +
    • enebled ¥­¡¼¥ï¡¼¥É¤È¥¹¥Ú¡¼¥¹¶èÀÚ¤ê¤Î¥æ¡¼¥¶Ì¾¥ê¥¹¥È¡£ + Á´ÂΤǤÏÊÑ´¹¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤¿¤È¤¤¤¿¤È¤·¤Æ¤â¡¢ + ¤³¤ì¤é¤Î¥æ¡¼¥¶Ì¾¤Ë¤Ï¥Ç¥£¥ì¥¯¥È¥êÊÑ´¹¤¬¹Ô¤ï¤ì¤Þ¤¹¡£ + ¤¿¤À¤·¡¢disabled Àá¤Ë¤â¤¢¤ì¤ÐÊÑ´¹¤Ï¤µ¤ì¤Þ¤»¤ó¡£ +
    • +
    + +

    ¤â¤· enabled ¤â disabled + ¥­¡¼¥ï¡¼¥É¤â UserDir ¤Ë¸½¤ï¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢ + °ú¿ô¤Ï¥Õ¥¡¥¤¥ë̾¥Ñ¥¿¡¼¥ó¤È¤·¤Æ°·¤ï¤ì¡¢ + ̾Á°¤«¤é¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤ÎÊÑ´¹¤Î»ØÄê¤ò¹Ô¤Ê¤¦»þ¤Ë»È¤ï¤ì¤Þ¤¹¡£ + http://www.foo.com/~bob/one/two.html + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¼¡¤Î¤è¤¦¤ËÊÑ´¹¤µ¤ì¤Þ¤¹:

    + + + + + + + +
    UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥ÖÊÑ´¹¸å¤Î¥Ñ¥¹
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    ¼¡¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¥ê¥À¥¤¥ì¥¯¥È¤ò + Á÷¿®¤·¤Þ¤¹:

    + + + + + + + +
    UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥ÖÊÑ´¹¸å¤Î¥Ñ¥¹
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + +
    + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤È¤­¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤; + "UserDir ./" ¤Ï + "/~root" ¤«¤é "/" ¤Ø¥Þ¥Ã¥×¤·¤Þ¤¹¤¬¡¢ + ¤³¤ì¤Ï˾¤Þ¤·¤¤Æ°ºî¤Ç¤Ï¤Ê¤¤¤Ç¤·¤ç¤¦¡£ + "UserDir disabled root" Àë¸À¤ò + ÀßÄê¤ÎÃæ¤Ë´Þ¤á¤Æ¤ª¤¯¤³¤È¤ò¶¯¤¯¤ªÁ¦¤á¤·¤Þ¤¹¡£ + ÄɲþðÊó¤Ë Directory + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + ¥»¥­¥å¥ê¥Æ¥£ + Tips ¤Î¥Ú¡¼¥¸¤â¤´Í÷²¼¤µ¤¤¡£ +
    + +

    ÄɲäÎÎã:

    + +

    ¾¯¿ô¤Î¥æ¡¼¥¶¤Î¤ß¤¬ UserDir +¥Ç¥£¥ì¥¯¥È¥ê¤òÍøÍѤ·¡¢¤½¤ì°Ê³°¤Ë¤ÏÍøÍѤµ¤»¤¿¤¯¤Ê¤¤¾ì¹ç¤Ï +¼¡¤ò»È¤¤¤Þ¤·¤ç¤¦:

    + +

    +UserDir disabled
    +UserDir enabled user1 user2 user3 +

    + +

    ÂçÉôʬ¤Î¥æ¡¼¥¶¤Ï UserDir ¥Ç¥£¥ì¥¯¥È¥ê¤òÍøÍѤ¹¤ë¤±¤ì¤É¡¢ +¾¯¿ô¤Î¿Í¤ÏÉÔµö²Ä¤Ë¤·¤¿¤¤¾ì¹ç¤Ï¡¢¼¡¤ò»È¤¤¤Þ¤·¤ç¤¦:

    + +

    +UserDir enabled
    +UserDir disabled user4 user5 user6 +

    + +

    ¾¤Î¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤹ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ +¼¡¤Î¤è¤¦¤Ê¥³¥Þ¥ó¥É¤ò»È¤¦¤È:

    + +

    +Userdir public_html /usr/web http://www.foo.com/ +

    + +

    http://www.foo.com/~bob/one/two.html ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¤Þ¤º +~bob/public_html/one/two.html ¤Î¥Ú¡¼¥¸¤òÄ´¤Ù¡¢¤½¤Î¼¡¤Ë +/usr/web/bob/one/two.html ¤òÄ´¤Ù¡¢ºÇ¸å¤Ë http://www.foo.com/bob/one/two.html +¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ê¤Þ¤¹¡£

    + +

    ¥ê¥À¥¤¥ì¥¯¥È¤ò²Ã¤¨¤ë¾ì¹ç¤Ï¡¢¥ê¥¹¥È¤ÎºÇ¸å¤ÎÁªÂò»è¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ +Apache ¤Ï¥ê¥À¥¤¥ì¥¯¥È¤¬À®¸ù¤¹¤ë¤«¤É¤¦¤«¤ò·è¤á¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¤Î¤Ç¡¢ +¥ê¥¹¥È¤ÎÁ°¤ÎÊý¤Ë¥ê¥À¥¤¥ì¥¯¥È¤ò½ñ¤¯¤È¡¢¤½¤ì¤¬É¬¤º»ÈÍѤµ¤ì¤ëÁªÂò»è¤Ë +¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡£

    + +

    2.1.4 °Ê¹ß¤Ç¤Ï¡¢¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥êÃÖ´¹µ¡Ç½¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤Ïµ¯Æ°¤·¤Þ¤»¤ó¡£ +¤½¤ì°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¡¢UserDir +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð¡¢UserDir public_html +¤Ç¤¢¤ë¤È²¾Äꤵ¤ì¤Æ¤¤¤Þ¤·¤¿¡£

    + + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_userdir.html.ko.euc-kr b/trunk/docs/manual/mod/mod_userdir.html.ko.euc-kr new file mode 100644 index 0000000000..3df232c411 --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.html.ko.euc-kr @@ -0,0 +1,161 @@ + + + +mod_userdir - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_userdir

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + +
    ¼³¸í:»ç¿ëÀÚº° µð·ºÅ丮
    »óÅÂ:Base
    ¸ðµâ¸í:userdir_module
    ¼Ò½ºÆÄÀÏ:mod_userdir.c
    +

    ¿ä¾à

    + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇϸé http://example.com/~user/ ½ÄÀ¸·Î +»ç¿ëÀÚº° µð·ºÅ丮¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    +
    + + +
    top
    +

    UserDir Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:»ç¿ëÀÚº° µð·ºÅ丮 À§Ä¡
    ¹®¹ý:UserDir directory-filename
    ±âº»°ª:UserDir public_html
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®
    »óÅÂ:Base
    ¸ðµâ:mod_userdir
    + +

    UserDir Áö½Ã¾î´Â »ç¿ëÀÚÀÇ ¹®¼­¿¡ ´ëÇÑ +¿äûÀ» ¹ÞÀ»¶§ »ç¿ëÀÚ È¨µð·ºÅ丮 ¾È¿¡¼­ »ç¿ëÇÒ ½ÇÁ¦ µð·ºÅ丮¸¦ +ÁöÁ¤ÇÑ´Ù. Directory-filenameÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù:

    + +
      +
    • ¾Æ·¡¿Í °°Àº µð·ºÅ丮¸í ȤÀº ÆÐÅÏ.
    • + +
    • disabled Å°¿öµå. +enabled Å°¿öµå·Î (¾Æ·¡ Âü°í) Á÷Á¢ À̸§À» ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é +¸ðµç »ç¿ëÀÚ¸í-µð·ºÅ丮 º¯È¯À» ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • disabled Å°¿öµå µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í ¸ñ·Ï. +»ç¿ëÀÚ¸íÀÌ enabled ±¸¹®¿¡ ÀÖ´Ù°í ÇÏ´õ¶óµµ, ÀÌ ¸ñ·Ï¿¡ +ÀÖ´Â »ç¿ëÀÚ¸íÀº µð·ºÅ丮 º¯È¯À» ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • enabled Å°¿öµå µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í ¸ñ·Ï. +Àüü disableÀ» »ç¿ëÇÏ°í »ç¿ëÀÚ¸íÀÌ disabled ±¸¹®¿¡ +¾ø´õ¶óµµ, »ç¿ëÀÚ¸íÀ» µð·ºÅ丮 º¯È¯ÇÑ´Ù.
    • +
    + +

    Userdir Áö½Ã¾î¿¡ enabled³ª +disabled Å°¿öµå¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é, ¾Æ±Ô¸ÕÆ®¸¦ +ÆÄÀϸí ÆÐÅÏÀ¸·Î ó¸®ÇÏ¿© µð·ºÅ丮·Î º¯È¯ÇÑ´Ù. +http://www.foo.com/~bob/one/two.html¿¡ ´ëÇÑ ¿äûÀº +´ÙÀ½°ú °°ÀÌ º¯È¯µÈ´Ù:

    + + + + + + + +
    »ç¿ëÇÑ UserDir Áö½Ã¾îº¯È¯ÇÑ °æ·Î
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    ´ÙÀ½ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù:

    + + + + + + + +
    »ç¿ëÇÑ UserDir Áö½Ã¾îº¯È¯ÇÑ °æ·Î
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + +
    + ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÒ¶§ ÁÖÀÇÇ϶ó; ¿¹¸¦ µé¾î, +"UserDir ./"´Â "/~root"¸¦ ¾Æ¸¶µµ ¹Ù¶÷Á÷ÇÏÁö ¾Ê°Ô +"/"·Î º¯È¯ÇÑ´Ù. ¼³Á¤¿¡ "UserDir + disabled root"¸¦ Æ÷ÇÔÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù. ÀÚ¼¼ÇÑ Á¤º¸¸¦ ¾Ë·Á¸é +Directory Áö½Ã¾î¿Í º¸¾È ÆÁµµ Âü°íÇ϶ó. +
    + +

    Ãß°¡ ¿¹Á¦:

    + +

    ¸î¸î »ç¿ëÀÚ¿¡°Ô¸¸ UserDir µð·ºÅ丮¸¦ Çã¿ëÇÑ´Ù¸é, +´ÙÀ½°ú °°´Ù:

    + +

    +UserDir disabled
    +UserDir enabled user1 user2 user3 +

    + +

    ´ëºÎºÐÀÇ »ç¿ëÀÚ¿¡°Ô UserDir µð·ºÅ丮¸¦ Çã¿ëÇÏ°í +ÀϺθ¸ °ÅºÎÇÑ´Ù¸é, ´ÙÀ½°ú °°´Ù:

    + +

    +UserDir enabled
    +UserDir disabled user4 user5 user6 +

    + +

    ´Ù¸¥ »ç¿ëÀÚ µð·ºÅ丮¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù. +´ÙÀ½°ú °°Àº ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù¸é:

    +

    +Userdir public_html /usr/web http://www.foo.com/ +

    +

    http://www.foo.com/~bob/one/two.html ¿äûÀ» Çϸé, +¸ÕÀú ~bob/public_html/one/two.html ÆäÀÌÁö¸¦ ã°í, +/usr/web/bob/one/two.htmlÀ» ãÀº ÈÄ, ¸¶Áö¸·À¸·Î +http://www.foo.com/bob/one/two.htmlÀ¸·Î ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù.

    +

    ¸®´ÙÀÌ·º¼ÇÀ» »ç¿ëÇÑ´Ù¸é ¸ñ·ÏÀÇ ¸¶Áö¸·¿¡ µÎ¾î¾ß ÇÑ´Ù. +¾ÆÆÄÄ¡´Â ¸®´ÙÀÌ·º¼ÇÀÌ ¼º°øÇß´ÂÁö ¾Ë ¼ö ¾ø±â¶§¹®¿¡, ¸®´ÙÀÌ·º¼ÇÀ» +¸ñ·Ï ¾Õ¿¡ µÎ¸é Ç×»ó ¸®´ÙÀÌ·º¼ÇÀ» »ç¿ëÇÏ°Ô µÈ´Ù.

    + + +

    Âü°í

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_userdir.xml b/trunk/docs/manual/mod/mod_userdir.xml new file mode 100644 index 0000000000..5b479703e0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.xml @@ -0,0 +1,162 @@ + + + + + + + + + +mod_userdir +User-specific directories +Base +mod_userdir.c +userdir_module + + +

    This module allows user-specific directories to be accessed using the +http://example.com/~user/ syntax.

    +
    + +Mapping URLs to the +Filesystem +public_html +tutorial + + + +UserDir +Location of the user-specific directories +UserDir directory-filename +server config virtual +host + + + +

    The UserDir directive sets the real + directory in a user's home directory to use when a request for a + document for a user is received. Directory-filename is + one of the following:

    + +
      +
    • The name of a directory or a pattern such as those shown + below.
    • + +
    • The keyword disabled. This turns off + all username-to-directory translations except those + explicitly named with the enabled keyword (see + below).
    • + +
    • The keyword disabled followed by a + space-delimited list of usernames. Usernames that appear in + such a list will never have directory translation + performed, even if they appear in an enabled + clause.
    • + +
    • The keyword enabled followed by a + space-delimited list of usernames. These usernames will have + directory translation performed even if a global disable is + in effect, but not if they also appear in a + disabled clause.
    • +
    + +

    If neither the enabled nor the + disabled keywords appear in the + Userdir directive, the argument is treated as a + filename pattern, and is used to turn the name into a directory + specification. A request for + http://www.foo.com/~bob/one/two.html will be + translated to:

    + + + + + + + +
    UserDir directive usedTranslated path
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    The following directives will send redirects to the client:

    + + + + + + + +
    UserDir directive usedTranslated path
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + + + Be careful when using this directive; for instance, + "UserDir ./" would map "/~root" to + "/" - which is probably undesirable. It is strongly + recommended that your configuration include a "UserDir + disabled root" declaration. See also the Directory directive and the Security Tips page for + more information. + + +

    Additional examples:

    + +

    To allow a few users to have UserDir directories, but +not anyone else, use the following:

    + + +UserDir disabled
    +UserDir enabled user1 user2 user3 +
    + +

    To allow most users to have UserDir directories, but +deny this to a few, use the following:

    + + +UserDir enabled
    +UserDir disabled user4 user5 user6 +
    + +

    It is also possible to specify alternative user directories. +If you use a command like:

    + +Userdir public_html /usr/web http://www.foo.com/ + +

    With a request for http://www.foo.com/~bob/one/two.html, will try to +find the page at ~bob/public_html/one/two.html first, then +/usr/web/bob/one/two.html, and finally it will send a redirect +to http://www.foo.com/bob/one/two.html.

    +

    If you add a redirect, it must be the last alternative in the list. +Apache cannot determine if the redirect succeeded or not, so if you have +the redirect earlier in the list, that will always be the alternative +that is used.

    + +

    User directory substitution is not active by default in versions +2.1.4 and later. In earlier versions, UserDir public_html +was assumed if no UserDir +directive was present.

    + +
    + +public_html +tutorial + +
    +
    + + diff --git a/trunk/docs/manual/mod/mod_userdir.xml.ja b/trunk/docs/manual/mod/mod_userdir.xml.ja new file mode 100644 index 0000000000..f0cb23549e --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.xml.ja @@ -0,0 +1,170 @@ + + + + + + + + + +mod_userdir +$B%f!<%6@lMQ$N%G%#%l%/%H%j$rDs6!(B + +Base +mod_userdir.c +userdir_module + + +

    $B$3$N%b%8%e!<%k$O!"(B +http://example.com/~user/ +$B9=J8$r;H$C$F%f!<%6@lMQ%G%#%l%/%H%j$K%"%/%;%9$G$-$k$h$&$K$7$^$9!#(B

    +
    + +URL $B$+$i(B +$B%U%!%$%k%7%9%F%`$X$N%^%C%T%s%0(B +public_html +$B%A%e!<%H%j%"%k(B + + + +UserDir +$B%f!<%6@lMQ%G%#%l%/%H%j$N0LCV(B +UserDir directory-filename +server config +virtual host + + + +

    UserDir $B%G%#%l%/%F%#%V$O!"(B + $B%f!<%6$N%I%-%e%a%s%H$X$N%j%/%(%9%H$rdirectory-filename $B$K$O + +

      +
    • $B%G%#%l%/%H%jL>$+2<$K<($9$h$&$J%Q%?!<%s!#(B
    • + +
    • disabled $B%-!<%o!<%I!#(B + enabled $B%-!<%o!<%I(B ($B2<5-;2>H(B) $B$GL@<(E*$K(B + $B;XDj$5$l$?%f!<%60J30$N(B + $BA4$F$N(B$B%f!<%6L>(B-$B%G%#%l%/%H%jJQ49$r(B + $B$7$J$$$h$&$K$7$^$9!#(B
    • + +
    • disabled $B%-!<%o!<%I$H!"%9%Z!<%96h@Z$j$N%f!<%6L>%j%9%H!#(B + $B$3$N%j%9%HCf$K4^$^$l$k%f!<%6L>$KBP$7$F$O!"$?$H$((B + enabled $B@a$K$"$C$?$H$7$F$b!"(B + $B7h$7$F(B$B%G%#%l%/%H%jJQ49$O9T$o$l$^$;$s!#(B
    • + +
    • enebled $B%-!<%o!<%I$H%9%Z!<%96h@Z$j$N%f!<%6L>%j%9%H!#(B + $BA4BN$G$OJQ49$,L58z$K$J$C$F$$$?$H$$$?$H$7$F$b!"(B + $B$3$l$i$N%f!<%6L>$K$O%G%#%l%/%H%jJQ49$,9T$o$l$^$9!#(B + $B$?$@$7!"(Bdisabled $B@a$K$b$"$l$PJQ49$O$5$l$^$;$s!#(B +
    • +
    + +

    $B$b$7(B enabled $B$b(B disabled + $B%-!<%o!<%I$b(B UserDir $B$K8=$o$l$F$$$J$1$l$P!"(B + $B0z?t$O%U%!%$%kL>%Q%?!<%s$H$7$F07$o$l!"(B + $BL>A0$+$i%G%#%l%/%H%j$X$NJQ49$N;XDj$r9T$J$&;~$K;H$o$l$^$9!#(B + http://www.foo.com/~bob/one/two.html + $B$X$N%j%/%(%9%H$O + + + + + + + +
    UserDir $B%G%#%l%/%F%#%V(B$BJQ498e$N%Q%9(B
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    $B + + + + + + + +
    UserDir $B%G%#%l%/%F%#%V(B$BJQ498e$N%Q%9(B
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + + + $B$3$N%G%#%l%/%F%#%V$r;H$&$H$-$OCm0U$7$F$/$@$5$$(B; + "UserDir ./" $B$O(B + "/~root" $B$+$i(B "/" $B$X%^%C%W$7$^$9$,!"(B + $B$3$l$OK>$^$7$$F0:n$G$O$J$$$G$7$g$&!#(B + "UserDir disabled root" $B@k8@$r(B + $B@_Dj$NCf$K4^$a$F$*$/$3$H$r6/$/$*A&$a$7$^$9!#(B + $BDI2C>pJs$K(B Directory + $B%G%#%l%/%F%#%V$d(B + $B%;%-%e%j%F%#(B + Tips $B$N%Z!<%8$b$4Mw2<$5$$!#(B + + +

    $BDI2C$NNc(B:

    + +

    $B>/?t$N%f!<%6$N$_$,(B UserDir +$B%G%#%l%/%H%j$rMxMQ$7!"$=$l0J30$K$OMxMQ$5$;$?$/$J$$>l9g$O(B +$B + + +UserDir disabled
    +UserDir enabled user1 user2 user3 +
    + +

    $BBgItJ,$N%f!<%6$O(B UserDir $B%G%#%l%/%H%j$rMxMQ$9$k$1$l$I!"(B +$B>/?t$N?M$OIT5v2D$K$7$?$$>l9g$O!" + + +UserDir enabled
    +UserDir disabled user4 user5 user6 +
    + +

    $BB>$N%f!<%6%G%#%l%/%H%j$r;XDj$9$k$3$H$b$G$-$^$9!#(B +$B + + +Userdir public_html /usr/web http://www.foo.com/ + + +

    http://www.foo.com/~bob/one/two.html $B$X$N%j%/%(%9%H$O$^$:(B +~bob/public_html/one/two.html $B$N%Z!<%8$rD4$Y!"$=$N + +

    $B%j%@%$%l%/%H$r2C$($k>l9g$O!"%j%9%H$N:G8e$NA*Br;h$G$J$1$l$P$J$j$^$;$s!#(B +Apache $B$O%j%@%$%l%/%H$,@.8y$9$k$+$I$&$+$r7h$a$k$3$H$O$G$-$^$;$s$N$G!"(B +$B%j%9%H$NA0$NJ}$K%j%@%$%l%/%H$r=q$/$H!"$=$l$,I,$:;HMQ$5$l$kA*Br;h$K(B +$B$J$C$F$7$^$$$^$9!#(B

    + +

    2.1.4 $B0J9_$G$O!"%f!<%6%G%#%l%/%H%jCV495!G=$O%G%U%)%k%H$G$O5/F0$7$^$;$s!#(B +$B$=$l0JA0$N%P!<%8%g%s$G$O!"(BUserDir +$B%G%#%l%/%F%#%V$,B8:_$7$J$1$l$P!"(BUserDir public_html +$B$G$"$k$H2>Dj$5$l$F$$$^$7$?!#(B

    + +
    + +public_html +$B%A%e!<%H%j%"%k(B + +
    +
    + + diff --git a/trunk/docs/manual/mod/mod_userdir.xml.ko b/trunk/docs/manual/mod/mod_userdir.xml.ko new file mode 100644 index 0000000000..1d00d6542f --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.xml.ko @@ -0,0 +1,146 @@ + + + + + + + + + +mod_userdir +»ç¿ëÀÚº° µð·ºÅ丮 +Base +mod_userdir.c +userdir_module + + +

    ÀÌ ¸ðµâÀ» »ç¿ëÇϸé http://example.com/~user/ ½ÄÀ¸·Î +»ç¿ëÀÚº° µð·ºÅ丮¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    +
    + +URLÀ» ÆÄÀϽýºÅÛ¿¡ ´ëÀÀ +public_html +ÅõÅ丮¾ó + + + +UserDir +»ç¿ëÀÚº° µð·ºÅ丮 À§Ä¡ +UserDir directory-filename +UserDir public_html +server config virtual +host + + + +

    UserDir Áö½Ã¾î´Â »ç¿ëÀÚÀÇ ¹®¼­¿¡ ´ëÇÑ +¿äûÀ» ¹ÞÀ»¶§ »ç¿ëÀÚ È¨µð·ºÅ丮 ¾È¿¡¼­ »ç¿ëÇÒ ½ÇÁ¦ µð·ºÅ丮¸¦ +ÁöÁ¤ÇÑ´Ù. Directory-filenameÀº ´ÙÀ½ Áß ÇϳªÀÌ´Ù:

    + +
      +
    • ¾Æ·¡¿Í °°Àº µð·ºÅ丮¸í ȤÀº ÆÐÅÏ.
    • + +
    • disabled Å°¿öµå. +enabled Å°¿öµå·Î (¾Æ·¡ Âü°í) Á÷Á¢ À̸§À» ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é +¸ðµç »ç¿ëÀÚ¸í-µð·ºÅ丮 º¯È¯À» ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • disabled Å°¿öµå µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í ¸ñ·Ï. +»ç¿ëÀÚ¸íÀÌ enabled ±¸¹®¿¡ ÀÖ´Ù°í ÇÏ´õ¶óµµ, ÀÌ ¸ñ·Ï¿¡ +ÀÖ´Â »ç¿ëÀÚ¸íÀº µð·ºÅ丮 º¯È¯À» ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • enabled Å°¿öµå µÚ¿¡ °ø¹éÀ¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í ¸ñ·Ï. +Àüü disableÀ» »ç¿ëÇÏ°í »ç¿ëÀÚ¸íÀÌ disabled ±¸¹®¿¡ +¾ø´õ¶óµµ, »ç¿ëÀÚ¸íÀ» µð·ºÅ丮 º¯È¯ÇÑ´Ù.
    • +
    + +

    Userdir Áö½Ã¾î¿¡ enabled³ª +disabled Å°¿öµå¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¸é, ¾Æ±Ô¸ÕÆ®¸¦ +ÆÄÀϸí ÆÐÅÏÀ¸·Î ó¸®ÇÏ¿© µð·ºÅ丮·Î º¯È¯ÇÑ´Ù. +http://www.foo.com/~bob/one/two.html¿¡ ´ëÇÑ ¿äûÀº +´ÙÀ½°ú °°ÀÌ º¯È¯µÈ´Ù:

    + + + + + + + +
    »ç¿ëÇÑ UserDir Áö½Ã¾îº¯È¯ÇÑ °æ·Î
    UserDir public_html~bob/public_html/one/two.html
    UserDir /usr/web/usr/web/bob/one/two.html
    UserDir /home/*/www/home/bob/www/one/two.html
    + +

    ´ÙÀ½ Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù:

    + + + + + + + +
    »ç¿ëÇÑ UserDir Áö½Ã¾îº¯È¯ÇÑ °æ·Î
    UserDir http://www.foo.com/usershttp://www.foo.com/users/bob/one/two.html
    UserDir +http://www.foo.com/*/usrhttp://www.foo.com/bob/usr/one/two.html
    UserDir +http://www.foo.com/~*/http://www.foo.com/~bob/one/two.html
    + + + ÀÌ Áö½Ã¾î¸¦ »ç¿ëÇÒ¶§ ÁÖÀÇÇ϶ó; ¿¹¸¦ µé¾î, +"UserDir ./"´Â "/~root"¸¦ ¾Æ¸¶µµ ¹Ù¶÷Á÷ÇÏÁö ¾Ê°Ô +"/"·Î º¯È¯ÇÑ´Ù. ¼³Á¤¿¡ "UserDir + disabled root"¸¦ Æ÷ÇÔÇÏ±æ °­·ÂÈ÷ ±ÇÇÑ´Ù. ÀÚ¼¼ÇÑ Á¤º¸¸¦ ¾Ë·Á¸é +Directory Áö½Ã¾î¿Í º¸¾È ÆÁµµ Âü°íÇ϶ó. + + +

    Ãß°¡ ¿¹Á¦:

    + +

    ¸î¸î »ç¿ëÀÚ¿¡°Ô¸¸ UserDir µð·ºÅ丮¸¦ Çã¿ëÇÑ´Ù¸é, +´ÙÀ½°ú °°´Ù:

    + + +UserDir disabled
    +UserDir enabled user1 user2 user3 +
    + +

    ´ëºÎºÐÀÇ »ç¿ëÀÚ¿¡°Ô UserDir µð·ºÅ丮¸¦ Çã¿ëÇÏ°í +ÀϺθ¸ °ÅºÎÇÑ´Ù¸é, ´ÙÀ½°ú °°´Ù:

    + + +UserDir enabled
    +UserDir disabled user4 user5 user6 +
    + +

    ´Ù¸¥ »ç¿ëÀÚ µð·ºÅ丮¸¦ ÁöÁ¤ÇÒ ¼öµµ ÀÖ´Ù. +´ÙÀ½°ú °°Àº ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù¸é:

    + +Userdir public_html /usr/web http://www.foo.com/ + +

    http://www.foo.com/~bob/one/two.html ¿äûÀ» Çϸé, +¸ÕÀú ~bob/public_html/one/two.html ÆäÀÌÁö¸¦ ã°í, +/usr/web/bob/one/two.htmlÀ» ãÀº ÈÄ, ¸¶Áö¸·À¸·Î +http://www.foo.com/bob/one/two.htmlÀ¸·Î ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù.

    +

    ¸®´ÙÀÌ·º¼ÇÀ» »ç¿ëÇÑ´Ù¸é ¸ñ·ÏÀÇ ¸¶Áö¸·¿¡ µÎ¾î¾ß ÇÑ´Ù. +¾ÆÆÄÄ¡´Â ¸®´ÙÀÌ·º¼ÇÀÌ ¼º°øÇß´ÂÁö ¾Ë ¼ö ¾ø±â¶§¹®¿¡, ¸®´ÙÀÌ·º¼ÇÀ» +¸ñ·Ï ¾Õ¿¡ µÎ¸é Ç×»ó ¸®´ÙÀÌ·º¼ÇÀ» »ç¿ëÇÏ°Ô µÈ´Ù.

    + +
    + +public_html +ÅõÅ丮¾ó + +
    +
    + + diff --git a/trunk/docs/manual/mod/mod_userdir.xml.meta b/trunk/docs/manual/mod/mod_userdir.xml.meta new file mode 100644 index 0000000000..7a0b48158d --- /dev/null +++ b/trunk/docs/manual/mod/mod_userdir.xml.meta @@ -0,0 +1,13 @@ + + + + mod_userdir + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_usertrack.html b/trunk/docs/manual/mod/mod_usertrack.html new file mode 100644 index 0000000000..0d24c8e0df --- /dev/null +++ b/trunk/docs/manual/mod/mod_usertrack.html @@ -0,0 +1,3 @@ +URI: mod_usertrack.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_usertrack.html.en b/trunk/docs/manual/mod/mod_usertrack.html.en new file mode 100644 index 0000000000..f7b81ac63e --- /dev/null +++ b/trunk/docs/manual/mod/mod_usertrack.html.en @@ -0,0 +1,236 @@ + + + +mod_usertrack - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_usertrack

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description: +Clickstream logging of user activity on a site +
    Status:Extension
    Module Identifier:usertrack_module
    Source File:mod_usertrack.c
    +

    Summary

    + +

    Previous releases of Apache have included a module which + generates a 'clickstream' log of user activity on a site using + cookies. This was called the "cookies" module, mod_cookies. In + Apache 1.2 and later this module has been renamed the "user + tracking" module, mod_usertrack. This module has been + simplified and new directives added.

    +
    + +
    top
    +
    +

    Logging

    + + +

    Previously, the cookies module (now the user tracking + module) did its own logging, using the CookieLog + directive. In this release, this module does no logging at all. + Instead, a configurable log format file should be used to log + user click-streams. This is possible because the logging module + now allows multiple log files. The cookie itself is logged by + using the text %{cookie}n in the log file format. For + example:

    +

    +CustomLog logs/clickstream "%{cookie}n %r %t" +

    + +

    For backward compatibility the configurable log module + implements the old CookieLog directive, but this + should be upgraded to the above CustomLog directive.

    +
    top
    +
    +

    2-digit or 4-digit dates for cookies?

    + + +

    (the following is from message + <022701bda43d$9d32bbb0$1201a8c0@christian.office.sane.com> + in the new-httpd archives)

    +
    +From: "Christian Allen" <christian@sane.com>
    +Subject: Re: Apache Y2K bug in mod_usertrack.c
    +Date: Tue, 30 Jun 1998 11:41:56 -0400
    +
    +Did some work with cookies and dug up some info that might be useful.
    +
    +True, Netscape claims that the correct format NOW is four digit dates, and
    +four digit dates do in fact work... for Netscape 4.x (Communicator), that
    +is.  However, 3.x and below do NOT accept them.  It seems that Netscape
    +originally had a 2-digit standard, and then with all of the Y2K hype and
    +probably a few complaints, changed to a four digit date for Communicator.
    +Fortunately, 4.x also understands the 2-digit format, and so the best way to
    +ensure that your expiration date is legible to the client's browser is to
    +use 2-digit dates.
    +
    +However, this does not limit expiration dates to the year 2000; if you use
    +an expiration year of "13", for example, it is interpreted as 2013, NOT
    +1913!  In fact, you can use an expiration year of up to "37", and it will be
    +understood as "2037" by both MSIE and Netscape versions 3.x and up (not sure
    +about versions previous to those).  Not sure why Netscape used that
    +particular year as its cut-off point, but my guess is that it was in respect
    +to UNIX's 2038 problem.  Netscape/MSIE 4.x seem to be able to understand
    +2-digit years beyond that, at least until "50" for sure (I think they
    +understand up until about "70", but not for sure).
    +
    +Summary:  Mozilla 3.x and up understands two digit dates up until "37"
    +(2037).  Mozilla 4.x understands up until at least "50" (2050) in 2-digit
    +form, but also understands 4-digit years, which can probably reach up until
    +9999.  Your best bet for sending a long-life cookie is to send it for some
    +time late in the year "37".
    +
    + +
    +
    top
    +

    CookieDomain Directive

    + + + + + + + +
    Description:The domain to which the tracking cookie applies
    Syntax:CookieDomain domain
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    + +

    This directive controls the setting of the domain to which + the tracking cookie applies. If not present, no domain is + included in the cookie header field.

    + +

    The domain string must begin with a dot, and + must include at least one embedded dot. That is, + ".foo.com" is legal, but "foo.bar.com" and ".com" are not.

    + +
    +
    top
    +

    CookieExpires Directive

    + + + + + + + +
    Description:Expiry time for the tracking cookie
    Syntax:CookieExpires expiry-period
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    +

    When used, this directive sets an expiry time on the cookie + generated by the usertrack module. The expiry-period + can be given either as a number of seconds, or in the format + such as "2 weeks 3 days 7 hours". Valid denominations are: + years, months, weeks, days, hours, minutes and seconds. If the expiry + time is in any format other than one number indicating the + number of seconds, it must be enclosed by double quotes.

    + +

    If this directive is not used, cookies last only for the + current browser session.

    + +
    +
    top
    +

    CookieName Directive

    + + + + + + + + +
    Description:Name of the tracking cookie
    Syntax:CookieName token
    Default:CookieName Apache
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    +

    This directive allows you to change the name of the cookie + this module uses for its tracking purposes. By default the + cookie is named "Apache".

    + +

    You must specify a valid cookie name; results are + unpredictable if you use a name containing unusual characters. + Valid characters include A-Z, a-z, 0-9, "_", and "-".

    + +
    +
    top
    +

    CookieStyle Directive

    + + + + + + + + +
    Description:Format of the cookie header field
    Syntax:CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965
    Default:CookieStyle Netscape
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    +

    This directive controls the format of the cookie header + field. The three formats allowed are:

    + +
      +
    • Netscape, which is the original but now deprecated + syntax. This is the default, and the syntax Apache has + historically used.
    • + +
    • Cookie or RFC2109, which is the syntax that + superseded the Netscape syntax.
    • + +
    • Cookie2 or RFC2965, which is the most + current cookie syntax.
    • +
    + +

    Not all clients can understand all of these formats. but you + should use the newest one that is generally acceptable to your + users' browsers.

    + +
    +
    top
    +

    CookieTracking Directive

    + + + + + + + + +
    Description:Enables tracking cookie
    Syntax:CookieTracking on|off
    Default:CookieTracking off
    Context:server config, virtual host, directory, .htaccess
    Override:FileInfo
    Status:Extension
    Module:mod_usertrack
    +

    When the user track module is compiled in, and + "CookieTracking on" is set, Apache will start sending a + user-tracking cookie for all new requests. This directive can + be used to turn this behavior on or off on a per-server or + per-directory basis. By default, compiling mod_usertrack will + not activate cookies.

    + + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_usertrack.xml b/trunk/docs/manual/mod/mod_usertrack.xml new file mode 100644 index 0000000000..31eace6786 --- /dev/null +++ b/trunk/docs/manual/mod/mod_usertrack.xml @@ -0,0 +1,242 @@ + + + + + + + + +mod_usertrack + +Clickstream logging of user activity on a site + +Extension +mod_usertrack.c +usertrack_module + + +

    Previous releases of Apache have included a module which + generates a 'clickstream' log of user activity on a site using + cookies. This was called the "cookies" module, mod_cookies. In + Apache 1.2 and later this module has been renamed the "user + tracking" module, mod_usertrack. This module has been + simplified and new directives added.

    +
    + + +
    +Logging + +

    Previously, the cookies module (now the user tracking + module) did its own logging, using the CookieLog + directive. In this release, this module does no logging at all. + Instead, a configurable log format file should be used to log + user click-streams. This is possible because the logging module + now allows multiple log files. The cookie itself is logged by + using the text %{cookie}n in the log file format. For + example:

    + +CustomLog logs/clickstream "%{cookie}n %r %t" + + +

    For backward compatibility the configurable log module + implements the old CookieLog directive, but this + should be upgraded to the above CustomLog directive.

    +
    + +
    +2-digit or 4-digit dates for cookies? + +

    (the following is from message + <022701bda43d$9d32bbb0$1201a8c0@christian.office.sane.com> + in the new-httpd archives)

    +
    +From: "Christian Allen" <christian@sane.com>
    +Subject: Re: Apache Y2K bug in mod_usertrack.c
    +Date: Tue, 30 Jun 1998 11:41:56 -0400
    +
    +Did some work with cookies and dug up some info that might be useful.
    +
    +True, Netscape claims that the correct format NOW is four digit dates, and
    +four digit dates do in fact work... for Netscape 4.x (Communicator), that
    +is.  However, 3.x and below do NOT accept them.  It seems that Netscape
    +originally had a 2-digit standard, and then with all of the Y2K hype and
    +probably a few complaints, changed to a four digit date for Communicator.
    +Fortunately, 4.x also understands the 2-digit format, and so the best way to
    +ensure that your expiration date is legible to the client's browser is to
    +use 2-digit dates.
    +
    +However, this does not limit expiration dates to the year 2000; if you use
    +an expiration year of "13", for example, it is interpreted as 2013, NOT
    +1913!  In fact, you can use an expiration year of up to "37", and it will be
    +understood as "2037" by both MSIE and Netscape versions 3.x and up (not sure
    +about versions previous to those).  Not sure why Netscape used that
    +particular year as its cut-off point, but my guess is that it was in respect
    +to UNIX's 2038 problem.  Netscape/MSIE 4.x seem to be able to understand
    +2-digit years beyond that, at least until "50" for sure (I think they
    +understand up until about "70", but not for sure).
    +
    +Summary:  Mozilla 3.x and up understands two digit dates up until "37"
    +(2037).  Mozilla 4.x understands up until at least "50" (2050) in 2-digit
    +form, but also understands 4-digit years, which can probably reach up until
    +9999.  Your best bet for sending a long-life cookie is to send it for some
    +time late in the year "37".
    +
    + +
    + + +CookieDomain +The domain to which the tracking cookie applies +CookieDomain domain + +server config +virtual host +directory +.htaccess + +FileInfo + + + +

    This directive controls the setting of the domain to which + the tracking cookie applies. If not present, no domain is + included in the cookie header field.

    + +

    The domain string must begin with a dot, and + must include at least one embedded dot. That is, + ".foo.com" is legal, but "foo.bar.com" and ".com" are not.

    +
    +
    + + + +CookieExpires +Expiry time for the tracking cookie +CookieExpires expiry-period + +server config +virtual host +directory +.htaccess + +FileInfo + + +

    When used, this directive sets an expiry time on the cookie + generated by the usertrack module. The expiry-period + can be given either as a number of seconds, or in the format + such as "2 weeks 3 days 7 hours". Valid denominations are: + years, months, weeks, days, hours, minutes and seconds. If the expiry + time is in any format other than one number indicating the + number of seconds, it must be enclosed by double quotes.

    + +

    If this directive is not used, cookies last only for the + current browser session.

    +
    +
    + + +CookieName +Name of the tracking cookie +CookieName token +CookieName Apache + +server config +virtual host +directory +.htaccess + +FileInfo + + +

    This directive allows you to change the name of the cookie + this module uses for its tracking purposes. By default the + cookie is named "Apache".

    + +

    You must specify a valid cookie name; results are + unpredictable if you use a name containing unusual characters. + Valid characters include A-Z, a-z, 0-9, "_", and "-".

    +
    +
    + + +CookieStyle +Format of the cookie header field +CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 +CookieStyle Netscape + +server config +virtual host +directory +.htaccess + +FileInfo + + +

    This directive controls the format of the cookie header + field. The three formats allowed are:

    + +
      +
    • Netscape, which is the original but now deprecated + syntax. This is the default, and the syntax Apache has + historically used.
    • + +
    • Cookie or RFC2109, which is the syntax that + superseded the Netscape syntax.
    • + +
    • Cookie2 or RFC2965, which is the most + current cookie syntax.
    • +
    + +

    Not all clients can understand all of these formats. but you + should use the newest one that is generally acceptable to your + users' browsers.

    +
    +
    + + + + +CookieTracking +Enables tracking cookie +CookieTracking on|off +CookieTracking off + +server config +virtual host +directory +.htaccess + +FileInfo + + +

    When the user track module is compiled in, and + "CookieTracking on" is set, Apache will start sending a + user-tracking cookie for all new requests. This directive can + be used to turn this behavior on or off on a per-server or + per-directory basis. By default, compiling mod_usertrack will + not activate cookies.

    + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_usertrack.xml.meta b/trunk/docs/manual/mod/mod_usertrack.xml.meta new file mode 100644 index 0000000000..3a21b85d76 --- /dev/null +++ b/trunk/docs/manual/mod/mod_usertrack.xml.meta @@ -0,0 +1,11 @@ + + + + mod_usertrack + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mod_version.html b/trunk/docs/manual/mod/mod_version.html new file mode 100644 index 0000000000..ee3abd1556 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.html @@ -0,0 +1,11 @@ +URI: mod_version.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mod_version.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mod_version.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/mod_version.html.en b/trunk/docs/manual/mod/mod_version.html.en new file mode 100644 index 0000000000..ffa6e34e42 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.html.en @@ -0,0 +1,150 @@ + + + +mod_version - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_version

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    Description:Version dependent configuration
    Status:Extension
    Module Identifier:version_module
    Source File:mod_version.c
    Compatibility:Available in version 2.1 and later
    +

    Summary

    + +

    This module is designed for the use in test suites and large + networks which have to deal with different httpd versions and + different configurations. It provides a new container -- <IfVersion>, which + allows a flexible version checking including numeric comparisons and + regular expressions.

    + +

    Examples

    + <IfVersion 2.1.0>
    + + # current httpd version is exactly 2.1.0
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # use really new features :-)
    +
    + </IfVersion> +

    + +

    See below for further possibilities.

    +
    +

    Directives

    + +
    + +
    top
    +

    <IfVersion> Directive

    + + + + + + + +
    Description:contains version dependent configuration
    Syntax:<IfVersion [[!]operator] version> ... +</IfVersion>
    Context:server config, virtual host, directory, .htaccess
    Override:All
    Status:Extension
    Module:mod_version
    +

    The <IfVersion> section encloses + configuration directives which are executed only if the + httpd version + matches the desired criteria. For normal (numeric) comparisons the + version argument has the format + major[.minor[.patch]], e.g. + 2.1.0 or 2.2. minor and + patch are optional. If these numbers are omitted, they are + assumed to be zero. The following numerical operators are + possible:

    + + + + + + + + + + + + +
    operatordescription
    = or ==httpd version is equal
    >httpd version is greater than
    >=httpd version is greater or equal
    <httpd version is less than
    <=httpd version is less or equal
    + +

    Example

    + <IfVersion >= 2.1>
    + + # this happens only in versions greater or
    + # equal 2.1.0.
    +
    + </IfVersion> +

    + +

    Besides the numerical comparison it is possible to match a regular + expression against the httpd version. There are two ways to write it:

    + + + + + + +
    operatordescription
    = or ==version has the form + /regex/
    ~version has the form + regex
    + +

    Example

    + <IfVersion = /^2.1.[01234]$/>
    + + # e.g. workaround for buggy versions + + </IfVersion> +

    + +

    In order to reverse the meaning, all operators can be preceded by an + exclamation mark (!):

    + +

    + <IfVersion !~ ^2.1.[01234]$>
    + + # not for those versions
    +
    + </IfVersion> +

    + +

    If the operator is omitted, it is assumed to be + =.

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_version.html.ja.euc-jp b/trunk/docs/manual/mod/mod_version.html.ja.euc-jp new file mode 100644 index 0000000000..a9c33f7ff4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.html.ja.euc-jp @@ -0,0 +1,148 @@ + + + +mod_version - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache ¥â¥¸¥å¡¼¥ë mod_version

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + + + +
    ÀâÌÀ:¥Ð¡¼¥¸¥ç¥ó°Í¸¤ÎÀßÄê
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:version_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mod_version.c
    ¸ß´¹À­:¥Ð¡¼¥¸¥ç¥ó 2.1 °Ê¹ß
    +

    ³µÍ×

    + +

    ÍÍ¡¹¤Ê¥Ð¡¼¥¸¥ç¥ó¤Î httpd ¤Î°Û¤Ê¤ëÀßÄê¤ò°·¤¦¤³¤È¤Ë¤Ê¤ë¡¢ + ¥Æ¥¹¥È¥¹¥¤¡¼¥È¤äÂ絬Ìϥͥåȥ¥¯¤Ç¤Î»ÈÍѤΤ¿¤á¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¿·¤·¤¤¥³¥ó¥Æ¥Ê ¡½ <IfVersion> ¤ò + Ä󶡤·¤Þ¤¹¡£¤³¤ì¤ò»È¤¦¤È¡¢¿ô»ú¤ÎÈæ³Ó¤äÀµµ¬É½¸½¤Ë¤è¤ë½ÀÆð¤Ê + ¥Ð¡¼¥¸¥ç¥ó¥Á¥§¥Ã¥¯¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Îã

    + <IfVersion 2.1.0>
    + + # current httpd version is exactly 2.1.0
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # use really new features :-)
    +
    + </IfVersion> +

    + +

    ¾ÜºÙ¤Ï°Ê²¼¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£

    +
    +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + +
    + +
    top
    +

    <IfVersion> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ð¡¼¥¸¥ç¥ó°Í¸¤ÎÀßÄê¤òÆþ¤ì¤ë
    ¹½Ê¸:<IfVersion [[!]operator] version> ... +</IfVersion>
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë, ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È, ¥Ç¥£¥ì¥¯¥È¥ê, .htaccess
    ¾å½ñ¤­:All
    ¥¹¥Æ¡¼¥¿¥¹:Extension
    ¥â¥¸¥å¡¼¥ë:mod_version
    +

    <IfVersion> ¤Ï httpd ¤Î¥Ð¡¼¥¸¥ç¥ó + ¤¬´ð½à¤òËþ¤¿¤·¤¿¤È¤­¤Ë¤Î¤ß¼Â¹Ô¤µ¤»¤¿¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤ß¤Þ¤¹¡£ + Ä̾ï¤Î (¿ôÃÍ) Èæ³Ó¤Î¤È¤­¤Ï version °ú¿ô¤Ï + major[.minor[.patch]] ¤È¤¤¤¦ + ·Á¼°¡¢Î㤨¤Ð¡¢2.1.0 ¤ä 2.2 ¤È¤Ê¤ê¤Þ¤¹¡£ + minor ¤È patch ¤Ï¾Êά²Äǽ¤Ç¤¹¡£¾Êά¤µ¤ì¤¿¾ì¹ç¤Ï¡¢ + 0 ¤ò»ØÄꤷ¤¿¤â¤Î¤È¤ß¤Ê¤µ¤ì¤Þ¤¹¡£Èæ³Ó¤Ë¤Ï¼¡¤Î¿ôÃÍ operator ¤ò + »ØÄê¤Ç¤­¤Þ¤¹:

    + + + + + + + + + + + + +
    operatorÀâÌÀ
    = ¤È ==Ʊ¤¸ httpd ¥Ð¡¼¥¸¥ç¥ó
    >¤è¤êÂ礭¤¤ httpd ¥Ð¡¼¥¸¥ç¥ó
    >=»ØÄê°Ê¾å¤Î httpd ¥Ð¡¼¥¸¥ç¥ó
    <»ØÄê̤Ëþ¤Î httpd ¥Ð¡¼¥¸¥ç¥ó
    <=»ØÄê°Ê²¼¤Î httpd ¥Ð¡¼¥¸¥ç¥ó
    + +

    Îã

    + <IfVersion >= 2.1>
    + + # this happens only in versions greater or
    + # equal 2.1.0.
    +
    + </IfVersion> +

    + +

    ¿ôÃÍÈæ³Ó¤Ë²Ã¤¨¤Æ¡¢http ¤Î¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤ËÂФ·¤ÆÀµµ¬É½¸½¤Ë¤è¤ë + ¥Þ¥Ã¥Á¥ó¥°¤¬¤Ç¤­¤Þ¤¹¡£Æó¼ïÎà¤Î½ñ¤­Êý¤¬¤¢¤ê¤Þ¤¹:

    + + + + + + +
    operatorÀâÌÀ
    = or ==version ¤Ï + /regex/ ·Á¼°
    ~version ¤Ï + regex ·Á¼°
    + +

    Îã

    + <IfVersion = /^2.1.[01234]$/>
    + + # e.g. workaround for buggy versions + + </IfVersion> +

    + +

    ¥Þ¥Ã¥Á¥ó¥°¤ÎÈÝÄê¤òɽ¸½¤¹¤ë¤¿¤á¤Ë¡¢¤¹¤Ù¤Æ¤Î¥ª¥Ú¥ì¡¼¥¿¤ÏÁ°¤Ë + ´¶Ã²Éä (!)¤òÉÕ¤±¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    + <IfVersion !~ ^2.1.[01234]$>
    + + # not for those versions
    +
    + </IfVersion> +

    + +

    operator ¤¬¾Êά¤µ¤ì¤¿¤È¤­¤Ï = ¤È + ¤ß¤Ê¤µ¤ì¤Þ¤¹¡£

    + +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_version.html.ko.euc-kr b/trunk/docs/manual/mod/mod_version.html.ko.euc-kr new file mode 100644 index 0000000000..5e16b8f541 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.html.ko.euc-kr @@ -0,0 +1,150 @@ + + + +mod_version - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    ¾ÆÆÄÄ¡ ¸ðµâ mod_version

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + + + +
    ¼³¸í:¹öÀüº° ¼³Á¤
    »óÅÂ:Extension
    ¸ðµâ¸í:version_module
    ¼Ò½ºÆÄÀÏ:mod_version.c
    Áö¿ø:¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ
    +

    ¿ä¾à

    + +

    ¿©·¯ ´Ù¸¥ À¥¼­¹ö ¹öÀü°ú ±¸¼ºÀ» ´Ù·ç¾î¾ß ÇÒ Å« ³×Æ®¿÷°ú + Å×½ºÆ®¿ëÀ¸·Î »ç¿ëÇϱâÀ§ÇØ ÀÌ ¸ðµâÀ» ¸¸µé¾ú´Ù. ÀÌ ¸ðµâÀº + ¼ýÀÚ ºñ±³³ª Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© ÀÚÀ¯·Î¿î ¹öÀü °Ë»ç°¡ °¡´ÉÇÑ + <IfVersion>À» + Á¦°øÇÑ´Ù.

    + +

    ¿¹Á¦

    + <IfVersion 2.1.0>
    + + # ÇöÀç À¥¼­¹ö ¹öÀüÀº Á¤È®È÷ 2.1.0ÀÌ´Ù
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # ÁøÂ¥ »õ·Î¿î ±â´ÉÀ» »ç¿ëÇÑ´Ù :-)
    +
    + </IfVersion> +

    + +

    ´Ù¸¥ »ç¿ë¹ýÀº ¾Æ·¡¸¦ Âü°íÇÑ´Ù.

    +
    +

    Áö½Ã¾îµé

    + +
    + +
    top
    +

    <IfVersion> Áö½Ã¾î

    + + + + + + + +
    ¼³¸í:¹öÀüº° ¼³Á¤À» ¹­´Â´Ù
    ¹®¹ý:<IfVersion [[!]operator] version> ... +</IfVersion>
    »ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
    Override ¿É¼Ç:All
    »óÅÂ:Extension
    ¸ðµâ:mod_version
    +

    <IfVersion> ¼½¼ÇÀº + À¥¼­¹ö ¹öÀüÀÌ ¿øÇÏ´Â Á¶°ÇÀ» ¸¸Á·ÇÒ¶§¸¸ ½ÇÇàÇÒ ¼³Á¤ Áö½Ã¾î¸¦ + ¹­´Â´Ù. ÀϹÝÀûÀÎ (¼ýÀÚ) ºñ±³ÀÇ °æ¿ì version ¾Æ±Ô¸ÕÆ®´Â + 2.1.0À̳ª 2.2¿Í °°ÀÌ + major[.minor[.patch]] + Çü½ÄÀÌ´Ù. minor¿Í patch´Â ¾ø¾îµµ µÈ´Ù. + ÀÌµé ¼ýÀÚ°¡ ¾ø´Ù¸é 0À̶ó°í °¡Á¤ÇÑ´Ù. ´ÙÀ½°ú °°Àº ¼ýÀÚ + operator°¡ °¡´ÉÇÏ´Ù.

    + + + + + + + + + + + + +
    operator¼³¸í
    = ȤÀº ==µ¿ÀÏÇÑ À¥¼­¹ö ¹öÀü
    >º¸´Ù Å« À¥¼­¹ö ¹öÀü
    >=Å©°Å³ª °°Àº À¥¼­¹ö ¹öÀü
    <º¸´Ù ÀÛÀº À¥¼­¹ö ¹öÀü
    <=À۰ųª °°Àº À¥¼­¹ö ¹öÀü
    + +

    ¿¹Á¦

    + <IfVersion >= 2.1>
    + + # ¹öÀüÀÌ 2.1.0 º¸´Ù Å©°Å³ª °°À»¶§¸¸
    + # ½ÇÇàÇÑ´Ù.
    +
    + </IfVersion> +

    + +

    ¼ýÀÚ ºñ±³¿Ü¿¡µµ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© À¥¼­¹ö ¹öÀüÀ» ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. ¿©±â¿¡´Â µÎ°¡Áö ¹æ¹ýÀÌ ÀÖ´Ù.

    + + + + + + +
    operator¼³¸í
    = ȤÀº ==versionÀº + /regex/ Çü½ÄÀÌ´Ù
    ~versionÀº + regex Çü½ÄÀÌ´Ù
    + +

    ¿¹Á¦

    + <IfVersion = /^2.1.[01234]$/>
    + + # ¿¹¸¦ µé¾î, ¿©±â¿¡ ¹ö±×°¡ Àִ ƯÁ¤ ¹öÀü¿¡ ´ëÇÑ ÇØ°áÃ¥ÀÌ ³ª¿Â´Ù + + </IfVersion> +

    + +

    ¿¬»êÀÚ ¾Õ¿¡ ´À³¦Ç¥(!)¸¦ ¾²¸é Àǹ̸¦ ¹Ý´ë·Î + Çؼ®ÇÑ´Ù.

    + +

    + <IfVersion !~ ^2.1.[01234]$>
    + + # ÀÌ ¹öÀüÀÌ ¾Æ´Ï¸é
    +
    + </IfVersion> +

    + +

    operator¸¦ »ý·«Çϸé =À̶ó°í + »ý°¢ÇÑ´Ù.

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_version.xml b/trunk/docs/manual/mod/mod_version.xml new file mode 100644 index 0000000000..e96a2de3f0 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.xml @@ -0,0 +1,137 @@ + + + + + + + + +mod_version +Version dependent configuration +Extension +mod_version.c +version_module +Available in version 2.1 and later + + +

    This module is designed for the use in test suites and large + networks which have to deal with different httpd versions and + different configurations. It provides a new container -- IfVersion, which + allows a flexible version checking including numeric comparisons and + regular expressions.

    + + Examples + <IfVersion 2.1.0>
    + + # current httpd version is exactly 2.1.0
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # use really new features :-)
    +
    + </IfVersion> +
    + +

    See below for further possibilities.

    +
    + + +IfVersion +contains version dependent configuration +<IfVersion [[!]operator] version> ... +</IfVersion> +server configvirtual host +directory.htaccess +All + + +

    The IfVersion section encloses + configuration directives which are executed only if the + httpd version + matches the desired criteria. For normal (numeric) comparisons the + version argument has the format + major[.minor[.patch]], e.g. + 2.1.0 or 2.2. minor and + patch are optional. If these numbers are omitted, they are + assumed to be zero. The following numerical operators are + possible:

    + + + + + + + + + + + + + +
    operatordescription
    = or ==httpd version is equal
    >httpd version is greater than
    >=httpd version is greater or equal
    <httpd version is less than
    <=httpd version is less or equal
    + + Example + <IfVersion >= 2.1>
    + + # this happens only in versions greater or
    + # equal 2.1.0.
    +
    + </IfVersion> +
    + +

    Besides the numerical comparison it is possible to match a regular + expression against the httpd version. There are two ways to write it:

    + + + + + + + +
    operatordescription
    = or ==version has the form + /regex/
    ~version has the form + regex
    + + Example + <IfVersion = /^2.1.[01234]$/>
    + + # e.g. workaround for buggy versions + + </IfVersion> +
    + +

    In order to reverse the meaning, all operators can be preceded by an + exclamation mark (!):

    + + + <IfVersion !~ ^2.1.[01234]$>
    + + # not for those versions
    +
    + </IfVersion> +
    + +

    If the operator is omitted, it is assumed to be + =.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_version.xml.ja b/trunk/docs/manual/mod/mod_version.xml.ja new file mode 100644 index 0000000000..7b9802d7bf --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.xml.ja @@ -0,0 +1,135 @@ + + + + + + + + +mod_version +$B%P!<%8%g%s0MB8$N@_Dj(B +Extension +mod_version.c +version_module +$B%P!<%8%g%s(B 2.1 $B0J9_(B + + +

    $BMM!9$J%P!<%8%g%s$N(B httpd $B$N0[$J$k@_Dj$r07$&$3$H$K$J$k!"(B + $B%F%9%H%9%$!<%H$dBg5,LO%M%C%H%o!<%/$G$N;HMQ$N$?$a$K@_7W$5$l$F$$$^$9!#(B + $B$3$N%b%8%e!<%k$O?7$7$$%3%s%F%J(B $B!=(B IfVersion $B$r(B + $BDs6!$7$^$9!#$3$l$r;H$&$H!"?t;z$NHf3S$d@55,I=8=$K$h$k=@Fp$J(B + $B%P!<%8%g%s%A%'%C%/$,$G$-$k$h$&$K$J$j$^$9!#(B

    + + $BNc(B + <IfVersion 2.1.0>
    + + # current httpd version is exactly 2.1.0
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # use really new features :-)
    +
    + </IfVersion> +
    + +

    $B>\:Y$O0J2<$rFI$s$G$/$@$5$$!#(B

    +
    + + +IfVersion +$B%P!<%8%g%s0MB8$N@_Dj$rF~$l$k(B +<IfVersion [[!]operator] version> ... +</IfVersion> +server configvirtual host +directory.htaccess +All + + +

    IfVersion $B$O(B httpd $B$N%P!<%8%g%s(B + $B$,4p=`$rK~$?$7$?$H$-$K$N$_o$N(B ($B?tCM(B) $BHf3S$N$H$-$O(B version $B0z?t$O(B + major[.minor[.patch]] $B$H$$$&(B + $B7A<0!"Nc$($P!"(B2.1.0 $B$d(B 2.2 $B$H$J$j$^$9!#(B + minor $B$H(B patch $B$O>JN,2DG=$G$9!#>JN,$5$l$?>l9g$O!"(B + 0 $B$r;XDj$7$?$b$N$H$_$J$5$l$^$9!#Hf3S$K$Ooperator $B$r(B + $B;XDj$G$-$^$9(B:

    + + + + + + + + + + + + + +
    operator$B@bL@(B
    = $B$H(B ==$BF1$8(B httpd $B%P!<%8%g%s(B
    >$B$h$jBg$-$$(B httpd $B%P!<%8%g%s(B
    >=$B;XDj0J>e$N(B httpd $B%P!<%8%g%s(B
    <$B;XDjL$K~$N(B httpd $B%P!<%8%g%s(B
    <=$B;XDj0J2<$N(B httpd $B%P!<%8%g%s(B
    + + $BNc(B + <IfVersion >= 2.1>
    + + # this happens only in versions greater or
    + # equal 2.1.0.
    +
    + </IfVersion> +
    + +

    $B?tCMHf3S$K2C$($F!"(Bhttp $B$N%P!<%8%g%sHV9f$KBP$7$F@55,I=8=$K$h$k(B + $B%^%C%A%s%0$,$G$-$^$9!#Fs + + + + + + + +
    operator$B@bL@(B
    = or ==version $B$O(B + /regex/ $B7A<0(B
    ~version $B$O(B + regex $B7A<0(B
    + + $BNc(B + <IfVersion = /^2.1.[01234]$/>
    + + # e.g. workaround for buggy versions + + </IfVersion> +
    + +

    $B%^%C%A%s%0$NH]Dj$rI=8=$9$k$?$a$K!"$9$Y$F$N%*%Z%l!<%?$OA0$K(B + $B46C2Id(B (!)$B$rIU$1$k$3$H$,$G$-$^$9(B:

    + + + <IfVersion !~ ^2.1.[01234]$>
    + + # not for those versions
    +
    + </IfVersion> +
    + +

    operator $B$,>JN,$5$l$?$H$-$O(B = $B$H(B + $B$_$J$5$l$^$9!#(B

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_version.xml.ko b/trunk/docs/manual/mod/mod_version.xml.ko new file mode 100644 index 0000000000..ff42dfe699 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.xml.ko @@ -0,0 +1,134 @@ + + + + + + + + +mod_version +¹öÀüº° ¼³Á¤ +Extension +mod_version.c +version_module +¾ÆÆÄÄ¡ 2.1 ÀÌÈĺÎÅÍ + + +

    ¿©·¯ ´Ù¸¥ À¥¼­¹ö ¹öÀü°ú ±¸¼ºÀ» ´Ù·ç¾î¾ß ÇÒ Å« ³×Æ®¿÷°ú + Å×½ºÆ®¿ëÀ¸·Î »ç¿ëÇϱâÀ§ÇØ ÀÌ ¸ðµâÀ» ¸¸µé¾ú´Ù. ÀÌ ¸ðµâÀº + ¼ýÀÚ ºñ±³³ª Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© ÀÚÀ¯·Î¿î ¹öÀü °Ë»ç°¡ °¡´ÉÇÑ + IfVersionÀ» + Á¦°øÇÑ´Ù.

    + + ¿¹Á¦ + <IfVersion 2.1.0>
    + + # ÇöÀç À¥¼­¹ö ¹öÀüÀº Á¤È®È÷ 2.1.0ÀÌ´Ù
    +
    + </IfVersion>
    +
    + <IfVersion >= 2.2>
    + + # ÁøÂ¥ »õ·Î¿î ±â´ÉÀ» »ç¿ëÇÑ´Ù :-)
    +
    + </IfVersion> +
    + +

    ´Ù¸¥ »ç¿ë¹ýÀº ¾Æ·¡¸¦ Âü°íÇÑ´Ù.

    +
    + + +IfVersion +¹öÀüº° ¼³Á¤À» ¹­´Â´Ù +<IfVersion [[!]operator] version> ... +</IfVersion> +server configvirtual host +directory.htaccess +All + + +

    IfVersion ¼½¼ÇÀº + À¥¼­¹ö ¹öÀüÀÌ ¿øÇÏ´Â Á¶°ÇÀ» ¸¸Á·ÇÒ¶§¸¸ ½ÇÇàÇÒ ¼³Á¤ Áö½Ã¾î¸¦ + ¹­´Â´Ù. ÀϹÝÀûÀÎ (¼ýÀÚ) ºñ±³ÀÇ °æ¿ì version ¾Æ±Ô¸ÕÆ®´Â + 2.1.0À̳ª 2.2¿Í °°ÀÌ + major[.minor[.patch]] + Çü½ÄÀÌ´Ù. minor¿Í patch´Â ¾ø¾îµµ µÈ´Ù. + ÀÌµé ¼ýÀÚ°¡ ¾ø´Ù¸é 0À̶ó°í °¡Á¤ÇÑ´Ù. ´ÙÀ½°ú °°Àº ¼ýÀÚ + operator°¡ °¡´ÉÇÏ´Ù.

    + + + + + + + + + + + + + +
    operator¼³¸í
    = ȤÀº ==µ¿ÀÏÇÑ À¥¼­¹ö ¹öÀü
    >º¸´Ù Å« À¥¼­¹ö ¹öÀü
    >=Å©°Å³ª °°Àº À¥¼­¹ö ¹öÀü
    <º¸´Ù ÀÛÀº À¥¼­¹ö ¹öÀü
    <=À۰ųª °°Àº À¥¼­¹ö ¹öÀü
    + + ¿¹Á¦ + <IfVersion >= 2.1>
    + + # ¹öÀüÀÌ 2.1.0 º¸´Ù Å©°Å³ª °°À»¶§¸¸
    + # ½ÇÇàÇÑ´Ù.
    +
    + </IfVersion> +
    + +

    ¼ýÀÚ ºñ±³¿Ü¿¡µµ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© À¥¼­¹ö ¹öÀüÀ» ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. ¿©±â¿¡´Â µÎ°¡Áö ¹æ¹ýÀÌ ÀÖ´Ù.

    + + + + + + + +
    operator¼³¸í
    = ȤÀº ==versionÀº + /regex/ Çü½ÄÀÌ´Ù
    ~versionÀº + regex Çü½ÄÀÌ´Ù
    + + ¿¹Á¦ + <IfVersion = /^2.1.[01234]$/>
    + + # ¿¹¸¦ µé¾î, ¿©±â¿¡ ¹ö±×°¡ Àִ ƯÁ¤ ¹öÀü¿¡ ´ëÇÑ ÇØ°áÃ¥ÀÌ ³ª¿Â´Ù + + </IfVersion> +
    + +

    ¿¬»êÀÚ ¾Õ¿¡ ´À³¦Ç¥(!)¸¦ ¾²¸é Àǹ̸¦ ¹Ý´ë·Î + Çؼ®ÇÑ´Ù.

    + + + <IfVersion !~ ^2.1.[01234]$>
    + + # ÀÌ ¹öÀüÀÌ ¾Æ´Ï¸é
    +
    + </IfVersion> +
    + +

    operator¸¦ »ý·«Çϸé =À̶ó°í + »ý°¢ÇÑ´Ù.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mod_version.xml.meta b/trunk/docs/manual/mod/mod_version.xml.meta new file mode 100644 index 0000000000..f390ca3262 --- /dev/null +++ b/trunk/docs/manual/mod/mod_version.xml.meta @@ -0,0 +1,13 @@ + + + + mod_version + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mod_vhost_alias.html b/trunk/docs/manual/mod/mod_vhost_alias.html new file mode 100644 index 0000000000..75b549250c --- /dev/null +++ b/trunk/docs/manual/mod/mod_vhost_alias.html @@ -0,0 +1,3 @@ +URI: mod_vhost_alias.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mod_vhost_alias.html.en b/trunk/docs/manual/mod/mod_vhost_alias.html.en new file mode 100644 index 0000000000..4908ae64c5 --- /dev/null +++ b/trunk/docs/manual/mod/mod_vhost_alias.html.en @@ -0,0 +1,312 @@ + + + +mod_vhost_alias - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache Module mod_vhost_alias

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Provides for dynamically configured mass virtual +hosting
    Status:Extension
    Module Identifier:vhost_alias_module
    Source File:mod_vhost_alias.c
    +

    Summary

    + +

    This module creates dynamically configured virtual hosts, by + allowing the IP address and/or the Host: header of + the HTTP request to be used as part of the pathname to + determine what files to serve. This allows for easy use of a + huge number of virtual hosts with similar configurations.

    + +

    Note

    +

    If mod_alias or mod_userdir are + used for translating URIs to filenames, they will override the + directives of mod_vhost_alias described below. For + example, the following configuration will map + /cgi-bin/script.pl to + /usr/local/apache2/cgi-bin/script.pl in all cases:

    + +

    + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
    + VirtualScriptAlias /never/found/%0/cgi-bin/ +

    +
    +
    + +
    top
    +
    +

    Directory Name Interpolation

    + + +

    All the directives in this module interpolate a string into + a pathname. The interpolated string (henceforth called the + "name") may be either the server name (see the UseCanonicalName + directive for details on how this is determined) or the IP + address of the virtual host on the server in dotted-quad + format. The interpolation is controlled by specifiers inspired + by printf which have a number of formats:

    + + + + + + + + + + + + +
    %%insert a %
    %pinsert the port number of the virtual host
    %N.Minsert (part of) the name
    + +

    N and M are used to specify + substrings of the name. N selects from the + dot-separated components of the name, and M + selects characters within whatever N has selected. + M is optional and defaults to zero if it isn't + present; the dot must be present if and only if M + is present. The interpretation is as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    0the whole name
    1the first part
    2the second part
    -1the last part
    -2the penultimate part
    2+the second and all subsequent parts
    -2+the penultimate and all preceding parts
    1+ and -1+the same as 0
    + +

    If N or M is greater than the number + of parts available a single underscore is interpolated.

    + +
    top
    +
    +

    Examples

    + + +

    For simple name-based virtual hosts you might use the + following directives in your server configuration file:

    + +

    + UseCanonicalName Off
    + VirtualDocumentRoot /usr/local/apache/vhosts/%0 +

    + +

    A request for + http://www.example.com/directory/file.html will be + satisfied by the file + /usr/local/apache/vhosts/www.example.com/directory/file.html. +

    + +

    For a very large number of virtual hosts it is a good idea + to arrange the files to reduce the size of the + vhosts directory. To do this you might use the + following in your configuration file:

    + +

    + UseCanonicalName Off
    + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2 +

    + +

    A request for + http://www.domain.example.com/directory/file.html + will be satisfied by the file + /usr/local/apache/vhosts/example.com/d/o/m/domain/directory/file.html.

    + +

    A more even spread of files can be achieved by hashing from the + end of the name, for example:

    + +

    + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.-1/%2.-2/%2.-3/%2 +

    + +

    The example request would come from + /usr/local/apache/vhosts/example.com/n/i/a/domain/directory/file.html.

    + +

    Alternatively you might use:

    + +

    + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2.4+ +

    + +

    The example request would come from + /usr/local/apache/vhosts/example.com/d/o/m/ain/directory/file.html.

    + +

    For IP-based virtual hosting you might use the following in + your configuration file:

    + +

    + UseCanonicalName DNS
    + VirtualDocumentRootIP /usr/local/apache/vhosts/%1/%2/%3/%4/docs
    + VirtualScriptAliasIP /usr/local/apache/vhosts/%1/%2/%3/%4/cgi-bin +

    + +

    A request for + http://www.domain.example.com/directory/file.html + would be satisfied by the file + /usr/local/apache/vhosts/10/20/30/40/docs/directory/file.html + if the IP address of www.domain.example.com were + 10.20.30.40. A request for + http://www.domain.example.com/cgi-bin/script.pl would + be satisfied by executing the program + /usr/local/apache/vhosts/10/20/30/40/cgi-bin/script.pl.

    + +

    If you want to include the . character in a + VirtualDocumentRoot directive, but it clashes with + a % directive, you can work around the problem in + the following way:

    + +

    + VirtualDocumentRoot /usr/local/apache/vhosts/%2.0.%3.0 +

    + +

    A request for + http://www.domain.example.com/directory/file.html + will be satisfied by the file + /usr/local/apache/vhosts/domain.example/directory/file.html.

    + +

    The LogFormat + directives %V and %A are useful + in conjunction with this module.

    +
    +
    top
    +

    VirtualDocumentRoot Directive

    + + + + + + + +
    Description:Dynamically configure the location of the document root +for a given virtual host
    Syntax:VirtualDocumentRoot interpolated-directory|none
    Default:VirtualDocumentRoot none
    Context:server config, virtual host
    Status:Extension
    Module:mod_vhost_alias
    + +

    The VirtualDocumentRoot directive allows you to + determine where Apache will find your documents based on the + value of the server name. The result of expanding + interpolated-directory is used as the root of the + document tree in a similar manner to the DocumentRoot directive's argument. + If interpolated-directory is none then + VirtualDocumentRoot is turned off. This directive + cannot be used in the same context as VirtualDocumentRootIP.

    + + +
    +
    top
    +

    VirtualDocumentRootIP Directive

    + + + + + + + +
    Description:Dynamically configure the location of the document root +for a given virtual host
    Syntax:VirtualDocumentRootIP interpolated-directory|none
    Default:VirtualDocumentRootIP none
    Context:server config, virtual host
    Status:Extension
    Module:mod_vhost_alias
    + +

    The VirtualDocumentRootIP directive is like the + VirtualDocumentRoot + directive, except that it uses the IP address of the server end + of the connection for directory interpolation instead of the server + name.

    + +
    +
    top
    +

    VirtualScriptAlias Directive

    + + + + + + + +
    Description:Dynamically configure the location of the CGI directory for +a given virtual host
    Syntax:VirtualScriptAlias interpolated-directory|none
    Default:VirtualScriptAlias none
    Context:server config, virtual host
    Status:Extension
    Module:mod_vhost_alias
    + +

    The VirtualScriptAlias directive allows you to + determine where Apache will find CGI scripts in a similar + manner to VirtualDocumentRoot does for other documents. It matches + requests for URIs starting /cgi-bin/, much like ScriptAlias + /cgi-bin/ would.

    + + +
    +
    top
    +

    VirtualScriptAliasIP Directive

    + + + + + + + +
    Description:Dynamically configure the location of the cgi directory for +a given virtual host
    Syntax:VirtualScriptAliasIP interpolated-directory|none
    Default:VirtualScriptAliasIP none
    Context:server config, virtual host
    Status:Extension
    Module:mod_vhost_alias
    + +

    The VirtualScriptAliasIP directive is like the + VirtualScriptAlias + directive, except that it uses the IP address of the server end + of the connection for directory interpolation instead of the server + name.

    + + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mod_vhost_alias.xml b/trunk/docs/manual/mod/mod_vhost_alias.xml new file mode 100644 index 0000000000..a378e17fc4 --- /dev/null +++ b/trunk/docs/manual/mod/mod_vhost_alias.xml @@ -0,0 +1,307 @@ + + + + + + + + + +mod_vhost_alias +Provides for dynamically configured mass virtual +hosting +Extension +mod_vhost_alias.c +vhost_alias_module + + +

    This module creates dynamically configured virtual hosts, by + allowing the IP address and/or the Host: header of + the HTTP request to be used as part of the pathname to + determine what files to serve. This allows for easy use of a + huge number of virtual hosts with similar configurations.

    + + Note +

    If mod_alias or mod_userdir are + used for translating URIs to filenames, they will override the + directives of mod_vhost_alias described below. For + example, the following configuration will map + /cgi-bin/script.pl to + /usr/local/apache2/cgi-bin/script.pl in all cases:

    + + + ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
    + VirtualScriptAlias /never/found/%0/cgi-bin/ +
    +
    +
    + +UseCanonicalName +Dynamically configured mass + virtual hosting + +
    + Directory Name Interpolation + +

    All the directives in this module interpolate a string into + a pathname. The interpolated string (henceforth called the + "name") may be either the server name (see the UseCanonicalName + directive for details on how this is determined) or the IP + address of the virtual host on the server in dotted-quad + format. The interpolation is controlled by specifiers inspired + by printf which have a number of formats:

    + + + + + + + + + + + + +
    %%insert a %
    %pinsert the port number of the virtual host
    %N.Minsert (part of) the name
    + +

    N and M are used to specify + substrings of the name. N selects from the + dot-separated components of the name, and M + selects characters within whatever N has selected. + M is optional and defaults to zero if it isn't + present; the dot must be present if and only if M + is present. The interpretation is as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    0the whole name
    1the first part
    2the second part
    -1the last part
    -2the penultimate part
    2+the second and all subsequent parts
    -2+the penultimate and all preceding parts
    1+ and -1+the same as 0
    + +

    If N or M is greater than the number + of parts available a single underscore is interpolated.

    + +
    + +
    + Examples + +

    For simple name-based virtual hosts you might use the + following directives in your server configuration file:

    + + + UseCanonicalName Off
    + VirtualDocumentRoot /usr/local/apache/vhosts/%0 +
    + +

    A request for + http://www.example.com/directory/file.html will be + satisfied by the file + /usr/local/apache/vhosts/www.example.com/directory/file.html. +

    + +

    For a very large number of virtual hosts it is a good idea + to arrange the files to reduce the size of the + vhosts directory. To do this you might use the + following in your configuration file:

    + + + UseCanonicalName Off
    + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2 +
    + +

    A request for + http://www.domain.example.com/directory/file.html + will be satisfied by the file + /usr/local/apache/vhosts/example.com/d/o/m/domain/directory/file.html.

    + +

    A more even spread of files can be achieved by hashing from the + end of the name, for example:

    + + + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.-1/%2.-2/%2.-3/%2 + + +

    The example request would come from + /usr/local/apache/vhosts/example.com/n/i/a/domain/directory/file.html.

    + +

    Alternatively you might use:

    + + + VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2.4+ + + +

    The example request would come from + /usr/local/apache/vhosts/example.com/d/o/m/ain/directory/file.html.

    + +

    For IP-based virtual hosting you might use the following in + your configuration file:

    + + + UseCanonicalName DNS
    + VirtualDocumentRootIP /usr/local/apache/vhosts/%1/%2/%3/%4/docs
    + VirtualScriptAliasIP /usr/local/apache/vhosts/%1/%2/%3/%4/cgi-bin +
    + +

    A request for + http://www.domain.example.com/directory/file.html + would be satisfied by the file + /usr/local/apache/vhosts/10/20/30/40/docs/directory/file.html + if the IP address of www.domain.example.com were + 10.20.30.40. A request for + http://www.domain.example.com/cgi-bin/script.pl would + be satisfied by executing the program + /usr/local/apache/vhosts/10/20/30/40/cgi-bin/script.pl.

    + +

    If you want to include the . character in a + VirtualDocumentRoot directive, but it clashes with + a % directive, you can work around the problem in + the following way:

    + + + VirtualDocumentRoot /usr/local/apache/vhosts/%2.0.%3.0 + + +

    A request for + http://www.domain.example.com/directory/file.html + will be satisfied by the file + /usr/local/apache/vhosts/domain.example/directory/file.html.

    + +

    The LogFormat + directives %V and %A are useful + in conjunction with this module.

    +
    + + +VirtualDocumentRoot +Dynamically configure the location of the document root +for a given virtual host +VirtualDocumentRoot interpolated-directory|none +VirtualDocumentRoot none + +server config +virtual host + + + + +

    The VirtualDocumentRoot directive allows you to + determine where Apache will find your documents based on the + value of the server name. The result of expanding + interpolated-directory is used as the root of the + document tree in a similar manner to the DocumentRoot directive's argument. + If interpolated-directory is none then + VirtualDocumentRoot is turned off. This directive + cannot be used in the same context as VirtualDocumentRootIP.

    + +
    +
    + + +VirtualDocumentRootIP +Dynamically configure the location of the document root +for a given virtual host +VirtualDocumentRootIP interpolated-directory|none +VirtualDocumentRootIP none + +server config +virtual host + + + + +

    The VirtualDocumentRootIP directive is like the + VirtualDocumentRoot + directive, except that it uses the IP address of the server end + of the connection for directory interpolation instead of the server + name.

    +
    +
    + + +VirtualScriptAlias +Dynamically configure the location of the CGI directory for +a given virtual host +VirtualScriptAlias interpolated-directory|none +VirtualScriptAlias none + +server config +virtual host + + + + +

    The VirtualScriptAlias directive allows you to + determine where Apache will find CGI scripts in a similar + manner to VirtualDocumentRoot does for other documents. It matches + requests for URIs starting /cgi-bin/, much like ScriptAlias + /cgi-bin/ would.

    + +
    +
    + + +VirtualScriptAliasIP +Dynamically configure the location of the cgi directory for +a given virtual host +VirtualScriptAliasIP interpolated-directory|none +VirtualScriptAliasIP none + +server config +virtual host + + + + +

    The VirtualScriptAliasIP directive is like the + VirtualScriptAlias + directive, except that it uses the IP address of the server end + of the connection for directory interpolation instead of the server + name.

    + +
    + +
    +
    + diff --git a/trunk/docs/manual/mod/mod_vhost_alias.xml.meta b/trunk/docs/manual/mod/mod_vhost_alias.xml.meta new file mode 100644 index 0000000000..078861efcd --- /dev/null +++ b/trunk/docs/manual/mod/mod_vhost_alias.xml.meta @@ -0,0 +1,11 @@ + + + + mod_vhost_alias + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/module-dict.html b/trunk/docs/manual/mod/module-dict.html new file mode 100644 index 0000000000..61d6c0f953 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.html @@ -0,0 +1,11 @@ +URI: module-dict.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: module-dict.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: module-dict.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/module-dict.html.en b/trunk/docs/manual/mod/module-dict.html.en new file mode 100644 index 0000000000..1801086180 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.html.en @@ -0,0 +1,117 @@ + + + +Terms Used to Describe Modules - Apache HTTP Server + + + + + +
    <-
    +

    Terms Used to Describe Modules

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    This document describes the terms that are used to describe + each Apache module.

    +
    + +
    top
    +
    +

    Description

    + +

    A brief description of the purpose of the module.

    +
    top
    +
    +

    Status

    + +

    This indicates how tightly bound into the Apache Web server + the module is; in other words, you may need to recompile the + server in order to gain access to the module and its + functionality. Possible values for this attribute are:

    + +
    +
    MPM
    + +
    A module with status "MPM" is a Multi-Processing Module. Unlike the + other types of modules, Apache must have one and only one MPM + in use at any time. This type of module is responsible for + basic request handling and dispatching.
    + +
    Base
    + +
    A module labeled as having "Base" status is compiled and + loaded into the server by default, and is therefore normally + available unless you have taken steps to remove the module + from your configuration.
    + +
    Extension
    + +
    A module with "Extension" status is not normally compiled + and loaded into the server. To enable the module and its + functionality, you may need to change the server build + configuration files and re-compile Apache.
    + +
    Experimental
    + +
    "Experimental" status indicates that the module is + available as part of the Apache kit, but you are on your own + if you try to use it. The module is being documented for + completeness, and is not necessarily supported.
    + +
    External
    + +
    Modules which are not included with the base Apache + distribution ("third-party modules") may use the "External" + status. We are not responsible for, nor do we support such + modules.
    +
    +
    top
    +
    +

    Source File

    + +

    This quite simply lists the name of the source file which + contains the code for the module. This is also the name used by + the <IfModule> + directive.

    +
    top
    +
    +

    Module Identifier

    + +

    This is a string which identifies the module for use in the + LoadModule directive when + dynamically loading modules. In particular, it is the name of + the external variable of type module in the source file.

    +
    top
    +
    +

    Compatibility

    + +

    If the module was not part of the original Apache version 2 + distribution, the version in which it was introduced should be + listed here. In addition, if the module is limited to + particular platforms, the details will be listed here.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/module-dict.html.ja.euc-jp b/trunk/docs/manual/mod/module-dict.html.ja.euc-jp new file mode 100644 index 0000000000..11517298a0 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.html.ja.euc-jp @@ -0,0 +1,119 @@ + + + +Apache ¥â¥¸¥å¡¼¥ë¤Î²òÀâ¤Ç»ÈÍѤ¹¤ëÍѸì - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¥â¥¸¥å¡¼¥ë¤Î²òÀâ¤Ç»ÈÍѤ¹¤ëÍѸì

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ï Apache ¤Î³Æ ¥â¥¸¥å¡¼¥ë ¤òÀâÌÀ¤¹¤ë¤¿¤á¤Ë + »È¤ï¤ì¤Æ¤¤¤ëÍѸì¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ÀâÌÀ

    + +

    ¥â¥¸¥å¡¼¥ë¤ÎÌÜŪ¤Îû¤¤ÀâÌÀ¡£

    +
    top
    +
    +

    ¥¹¥Æ¡¼¥¿¥¹

    + +

    ¤³¤ì¤Ï¡¢¤½¤Î¥â¥¸¥å¡¼¥ë¤¬ Apache + ¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¤É¤ì¤¯¤é¤¤Ì©ÀܤËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¤ò¼¨¤·¤Þ¤¹¡£ + ¸À¤¤´¹¤¨¤ì¤Ð¡¢¥â¥¸¥å¡¼¥ë¤òÁȤ߹þ¤ß¡¢¤½¤Îµ¡Ç½¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¡¢ + ¥µ¡¼¥Ð¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Ê¤¤¤È¤¤¤¦¤³¤È¤ò¼¨¤·¤Þ¤¹¡£ + ¤³¤Î°À­¤¬¼è¤êÆÀ¤ëÃͤϰʲ¼¤Î¤â¤Î¤Ç¤¹:

    +
    +
    MPM
    + +
    ¥¹¥Æ¡¼¥¿¥¹¤¬ "MPM" ¤Î¥â¥¸¥å¡¼¥ë¤Ï¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë¤Ç¤¹¡£ + ¾¤Î¼ïÎà¤Î¥â¥¸¥å¡¼¥ë¤È¤Ï°ã¤Ã¤Æ¡¢Apache ¤Ï¾ï¤Ë MPM ¤ò°ì¤Ä¤À¤± + »ÈÍѤ·Â³¤±¤Þ¤¹¡£¤³¤Î¼ïÎà¤Î¥â¥¸¥å¡¼¥ë¤Ï´ðËÜŪ¤Ê¥ê¥¯¥¨¥¹¥È¤Î°·¤¤¤È + ¥Ç¥£¥¹¥Ñ¥Ã¥Á¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£
    + +
    Base
    + +
    ¥¹¥Æ¡¼¥¿¥¹¤¬ "Base" + ¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤ï¤¶¤ï¤¶ÀßÄ꤫¤é + ¥â¥¸¥å¡¼¥ë¤òºï½ü¤·¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢Ä̾ï¤ÏÍøÍѲÄǽ¤Ç¤¹¡£ +
    + +
    Extension
    + +
    ¥¹¥Æ¡¼¥¿¥¹¤¬ "Extension" ¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤º¡¢¥µ¡¼¥Ð¤Ë¤âÆɤ߹þ¤Þ¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¥â¥¸¥å¡¼¥ë¤È¤½¤Îµ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï¡¢ + ¥µ¡¼¥Ð¤ò¥Ó¥ë¥É¤¹¤ë¤¿¤á¤ÎÀßÄê¤òÊѹ¹¤·¤Æ¡¢Apache + ¤òºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
    +
    Experimental
    + +
    ¥¹¥Æ¡¼¥¿¥¹¤¬ "Experimental" ¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢ + Apache ÇÛÉÛʪ¤ËƱº­¤µ¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢ + »ÈÍѤ¹¤ë¾ì¹ç¤Ï¼«¸ÊÀÕǤ¤Ç¹Ô¤Ê¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ + ¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤â´°À®¤Ë¸þ¤±¤ÆºîÀ®Ãæ¤Ç¤¹¤·¡¢ + ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¤Æ¤¤¤ë¤È¤Ï¸Â¤ê¤Þ¤»¤ó¡£
    +
    External
    + +
    ¥¹¥Æ¡¼¥¿¥¹¤¬ "External" ¤Î¥â¥¸¥å¡¼¥ë¤Ï¡¢´ðËÜ Apache + ÇÛÉÛ¤ËƱº­¤µ¤ì¤Þ¤»¤ó ("¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¡¼¥â¥¸¥å¡¼¥ë")¡£ + ¤½¤Î¤¿¤á¡¢²æ¡¹¤ËÀÕǤ¤Ï¤¢¤ê¤Þ¤»¤ó¤·¡¢ + ¤½¤Î¥â¥¸¥å¡¼¥ë¤Î¥µ¥Ý¡¼¥È¤â¤·¤Æ¤¤¤Þ¤»¤ó¡£
    +
    +
    top
    +
    +

    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë

    + +

    ¤³¤ì¤Ïñ½ã¤Ë¡¢ + ¤½¤Î¥â¥¸¥å¡¼¥ë¤ËɬÍפʥ³¡¼¥É¤ò´Þ¤à¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÎóµó¤·¤¿¤â¤Î¤Ç¤¹¡£ + ¤³¤ì¤Ï¡¢<IfModule> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ÈÍѤµ¤ì¤ë̾Á°¤Ç¤â¤¢¤ê¤Þ¤¹¡£ +

    +
    top
    +
    +

    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò

    + +

    ¤³¤Îʸ»úÎó¤Ï¡¢¥â¥¸¥å¡¼¥ë¤ÎưŪÆɤ߹þ¤ß¤ò¹Ô¤Ê¤¦¤È¤­¤Ë»ÈÍѤ¹¤ë LoadModule + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤ª¤¤¤Æ»ÈÍѤµ¤ì¤ë¥â¥¸¥å¡¼¥ë¤Î¼±Ê̻ҤǤ¹¡£ + ¾Ü¤·¤¯½ñ¤¯¤È¡¢¥½¡¼¥¹¥Õ¥¡¥¤¥ëÆâ¤Î module ¥¿¥¤¥×¤Î³°ÉôÊÑ¿ô¤Î̾Á°¤Ç¤¹¡£ +

    +
    top
    +
    +

    ¸ß´¹À­

    + +

    ¤¢¤ë¥â¥¸¥å¡¼¥ë¤¬ Apache ¥Ð¡¼¥¸¥ç¥ó 2 + ¤ÎÇÛÉۤ˴ޤޤì¤Æ¤¤¤Ê¤«¤Ã¤¿¾ì¹ç¡¢ + ¤½¤Î¥â¥¸¥å¡¼¥ë¤¬Æ³Æþ¤µ¤ì¤¿¥Ð¡¼¥¸¥ç¥ó¤¬¤³¤³¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤Þ¤¿¡¢¥â¥¸¥å¡¼¥ë¤¬ÆÃÄê¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤Î¤ß¸ºß¤¹¤ë¤È¤­¤â + ¾ÜºÙ¤Ï¤³¤³¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/module-dict.html.ko.euc-kr b/trunk/docs/manual/mod/module-dict.html.ko.euc-kr new file mode 100644 index 0000000000..3a6bc48f66 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.html.ko.euc-kr @@ -0,0 +1,109 @@ + + + +¸ðµâÀ» ¼³¸íÇϱâÀ§ÇØ »ç¿ëÇÑ ¿ë¾îµé - Apache HTTP Server + + + + + +
    <-
    +

    ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇØ »ç¿ëÇÑ ¿ë¾îµé

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇØ + »ç¿ëÇÑ ¿ë¾î¸¦ ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¼³¸í

    + +

    ¸ðµâ ¸ñÀû¿¡ ´ëÇÑ °£´ÜÇÑ ¼³¸í.

    +
    top
    +
    +

    »óÅÂ

    + +

    ¸ðµâÀÌ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í ¾ó¸¶³ª ¹ÐÁ¢È÷ ¿¬°üµÇÀÖ´ÂÁö ³ªÅ¸³½´Ù. + Áï, ƯÁ¤ ¸ðµâ°ú ¸ðµâÀÇ ±â´ÉÀ» »ç¿ëÇϱâÀ§Çؼ­ ¼­¹ö¸¦ ´Ù½Ã + ÄÄÆÄÀÏÇØ¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ÀÌ ¼Ó¼ºÀÇ °ªÀº:

    + +
    +
    MPM
    + +
    »óÅ°¡ "MPM"ÀÎ ¸ðµâÀº ´ÙÁßó¸® + ¸ðµâÀÌ´Ù. ´Ù¸¥ Á¾·ùÀÇ ¸ðµâ°ú ´Þ¸® ¾ÆÆÄÄ¡´Â ¿ÀÁ÷ ÇÑ + MPM¸¸À» »ç¿ëÇÑ´Ù. ÀÌ·± Á¾·ùÀÇ ¸ðµâÀº ±âº»ÀûÀÎ ¿äû ó¸®¿Í + ºÐ¹è¸¦ ´ã´çÇÑ´Ù.
    + +
    Base
    + +
    »óÅ°¡ "Base"ÀÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵǹǷÎ, + ¼³Á¤¿¡¼­ ¸ðµâÀ» Á¦°ÅÇÏÁö ¾Ê´Â ÇÑ º¸Åë »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    Extension
    + +
    »óÅ°¡ "Extension"ÀÎ ¸ðµâÀº º¸Åë ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵÇÁö + ¾Ê´Â´Ù. ¸ðµâ°ú ¸ðµâÀÇ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é ¼­¹ö ÄÄÆÄÀÏ + ±¸¼ºÆÄÀÏÀ» º¯°æÇÏ°í ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù.
    + +
    Experimental
    + +
    "Experimental" »óÅ´ ¸ðµâÀÌ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖÁö¸¸, + »ç¿ëÇÏ·Á¸é À§ÇèÀ» °¨¼öÇØ¾ß ÇÑ´Ù. ¸ðµâ¿¡ ´ëÇÑ ¹®¼­°¡ ÀÖÁö¸¸, + ¸ðµâÀ» Áö¿øÇÑ´Ù´Â ¸»Àº ¾Æ´Ï´Ù.
    + +
    External
    + +
    "External" »óÅ´ ±âº» ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÁö ¾ÊÀº + ¸ðµâ("Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ")ÀÌ´Ù. ¿ì¸®´Â ÀÌ·± ¸ðµâ¿¡ Ã¥ÀÓÀÌ + ¾ø°í Áö¿øÇÏÁöµµ ¾Ê´Â´Ù.
    +
    +
    top
    +
    +

    ¼Ò½ºÆÄÀÏ

    + +

    °£´ÜÇÏ°Ô ¸»Çؼ­ ¸ðµâ ¼Ò½ºÄڵ尡 ÀÖ´Â ¼Ò½ºÆÄÀϸíÀÌ´Ù. + <IfModule> + Áö½Ã¾î¿¡¼­ »ç¿ëÇÏ´Â À̸§À̱⵵ ÇÏ´Ù.

    +
    top
    +
    +

    ¸ðµâ¸í

    + +

    ¸ðµâÀ» ÁöĪÇÏ´Â ¹®ÀÚ¿­·Î, ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â + LoadModule Áö½Ã¾î¿¡¼­ + »ç¿ëÇÑ´Ù. Á¤È®È÷ ¸»ÇÏ¸é ¼Ò½ºÆÄÀÏ¿¡¼­ module ÇüÀÇ ¿ÜºÎº¯¼ö + À̸§ÀÌ´Ù.

    +
    top
    +
    +

    Áö¿ø

    + +

    ¸ðµâÀÌ ¿ø·¡ ¾ÆÆÄÄ¡ ¹öÀü 2 ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÁö ¾Ê¾Ò´Ù¸é, + ¸ðµâÀ» óÀ½ ¼Ò°³ÇÑ ¹öÀüÀ» ¾Ë·ÁÁØ´Ù. ¶Ç, ¸ðµâÀÌ Æ¯Á¤ + Ç÷¡Æû¿ëÀ̶ó¸é »ó¼¼È÷ ¼³¸íÇÑ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/module-dict.xml b/trunk/docs/manual/mod/module-dict.xml new file mode 100644 index 0000000000..cec5db15fa --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.xml @@ -0,0 +1,107 @@ + + + + + + + + + + Terms Used to Describe Modules + + +

    This document describes the terms that are used to describe + each Apache module.

    +
    + +
    Description + +

    A brief description of the purpose of the module.

    +
    + +
    Status + +

    This indicates how tightly bound into the Apache Web server + the module is; in other words, you may need to recompile the + server in order to gain access to the module and its + functionality. Possible values for this attribute are:

    + +
    +
    MPM
    + +
    A module with status "MPM" is a Multi-Processing Module. Unlike the + other types of modules, Apache must have one and only one MPM + in use at any time. This type of module is responsible for + basic request handling and dispatching.
    + +
    Base
    + +
    A module labeled as having "Base" status is compiled and + loaded into the server by default, and is therefore normally + available unless you have taken steps to remove the module + from your configuration.
    + +
    Extension
    + +
    A module with "Extension" status is not normally compiled + and loaded into the server. To enable the module and its + functionality, you may need to change the server build + configuration files and re-compile Apache.
    + +
    Experimental
    + +
    "Experimental" status indicates that the module is + available as part of the Apache kit, but you are on your own + if you try to use it. The module is being documented for + completeness, and is not necessarily supported.
    + +
    External
    + +
    Modules which are not included with the base Apache + distribution ("third-party modules") may use the "External" + status. We are not responsible for, nor do we support such + modules.
    +
    +
    + +
    Source File + +

    This quite simply lists the name of the source file which + contains the code for the module. This is also the name used by + the IfModule + directive.

    +
    + +
    Module Identifier + +

    This is a string which identifies the module for use in the + LoadModule directive when + dynamically loading modules. In particular, it is the name of + the external variable of type module in the source file.

    +
    + +
    Compatibility + +

    If the module was not part of the original Apache version 2 + distribution, the version in which it was introduced should be + listed here. In addition, if the module is limited to + particular platforms, the details will be listed here.

    +
    + +
    diff --git a/trunk/docs/manual/mod/module-dict.xml.ja b/trunk/docs/manual/mod/module-dict.xml.ja new file mode 100644 index 0000000000..9ad2d73132 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.xml.ja @@ -0,0 +1,109 @@ + + + + + + + + + + Apache $B%b%8%e!<%k$N2r@b$G;HMQ$9$kMQ8l(B + + +

    $B$3$NJ8=q$O(B Apache $B$N3F(B $B%b%8%e!<%k(B $B$r@bL@$9$k$?$a$K(B + $B;H$o$l$F$$$kMQ8l$r@bL@$7$^$9!#(B

    +
    + +
    $B@bL@(B + +

    $B%b%8%e!<%k$NL\E*$NC;$$@bL@!#(B

    +
    + +
    $B%9%F!<%?%9(B + +

    $B$3$l$O!"$=$N%b%8%e!<%k$,(B Apache + $B%&%'%V%5!<%P$K$I$l$/$i$$L)@\$KAH$_9~$^$l$F$$$k$+$r<($7$^$9!#(B + $B8@$$49$($l$P!"%b%8%e!<%k$rAH$_9~$_!"$=$N5!G=$rMxMQ$9$k$?$a$K!"(B + $B%5!<%P$r:F%3%s%Q%$%k$9$kI,MW$,$"$k$+$b$7$l$J$$$H$$$&$3$H$r<($7$^$9!#(B + $B$3$NB0@-$, +

    +
    MPM
    + +
    $B%9%F!<%?%9$,(B "MPM" $B$N%b%8%e!<%k$O(B$B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B$B$G$9!#(B + $BB>$No$K(B MPM $B$r0l$D$@$1(B + $B;HMQ$7B3$1$^$9!#$3$N + +
    Base
    + +
    $B%9%F!<%?%9$,(B "Base" + $B$N%b%8%e!<%k$O!"%G%U%)%k%H$G%3%s%Q%$%k$5$l$F$o$6$o$6@_Dj$+$i(B + $B%b%8%e!<%k$r:o=|$7$F$$$J$$8B$j!"DL>o$OMxMQ2DG=$G$9!#(B +
    + +
    Extension
    + +
    $B%9%F!<%?%9$,(B "Extension" $B$N%b%8%e!<%k$O!"(B + $B%G%U%)%k%H$G$O%3%s%Q%$%k$5$l$:!"%5!<%P$K$bFI$_9~$^$l$^$;$s!#(B + $B$=$N%b%8%e!<%k$H$=$N5!G=$rM-8z$K$9$k$K$O!"(B + $B%5!<%P$r%S%k%I$9$k$?$a$N@_Dj$rJQ99$7$F!"(BApache + $B$r:F%3%s%Q%$%k$9$kI,MW$,$"$j$^$9!#(B
    +
    Experimental
    + +
    $B%9%F!<%?%9$,(B "Experimental" $B$N%b%8%e!<%k$O!"(B + Apache $BG[I[J*$KF1:-$5$l$F$$$^$9$,!"(B + $B;HMQ$9$k>l9g$O<+8J@UG$$G9T$J$&I,MW$,$"$j$^$9!#(B + $B$=$N%b%8%e!<%k$O!"%I%-%e%a%s%H$b40@.$K8~$1$F:n@.Cf$G$9$7!"(B + $B%5%]!<%H$5$l$k$F$$$k$H$O8B$j$^$;$s!#(B
    +
    External
    + +
    $B%9%F!<%?%9$,(B "External" $B$N%b%8%e!<%k$O!"4pK\(B Apache + $BG[I[$KF1:-$5$l$^$;$s(B ("$B%5!<%I%Q!<%F%#!<%b%8%e!<%k(B")$B!#(B + $B$=$N$?$a!"2f!9$K@UG$$O$"$j$^$;$s$7!"(B + $B$=$N%b%8%e!<%k$N%5%]!<%H$b$7$F$$$^$;$s!#(B
    +
    +
    + +
    $B%=!<%9%U%!%$%k(B + +

    $B$3$l$OC1=c$K!"(B + $B$=$N%b%8%e!<%k$KI,MW$J%3!<%I$r4^$`%=!<%9%U%!%$%k$NL>A0$rNs5s$7$?$b$N$G$9!#(B + $B$3$l$O!"(BIfModule + $B%G%#%l%/%F%#%V$G;HMQ$5$l$kL>A0$G$b$"$j$^$9!#(B +

    +
    + +
    $B%b%8%e!<%k<1JL;R(B + +

    $B$3$NJ8;zNs$O!"%b%8%e!<%k$NF0E*FI$_9~$_$r9T$J$&$H$-$K;HMQ$9$k(B LoadModule + $B%G%#%l%/%F%#%V$K$*$$$F;HMQ$5$l$k%b%8%e!<%k$N<1JL;R$G$9!#(B + $B>\$7$/=q$/$H!"%=!<%9%U%!%$%kFb$N(B module $B%?%$%W$N30ItJQ?t$NL>A0$G$9!#(B +

    +
    + +
    $B8_49@-(B + +

    $B$"$k%b%8%e!<%k$,(B Apache $B%P!<%8%g%s(B 2 + $B$NG[I[$K4^$^$l$F$$$J$+$C$?>l9g!"(B + $B$=$N%b%8%e!<%k$,F3F~$5$l$?%P!<%8%g%s$,$3$3$K=q$+$l$F$$$^$9!#(B + $B$^$?!"%b%8%e!<%k$,FCDj$N%W%i%C%H%U%)!<%`$K$N$_B8:_$9$k$H$-$b(B + $B>\:Y$O$3$3$K=q$+$l$F$$$^$9!#(B

    +
    +
    diff --git a/trunk/docs/manual/mod/module-dict.xml.ko b/trunk/docs/manual/mod/module-dict.xml.ko new file mode 100644 index 0000000000..45e1fbe8e0 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.xml.ko @@ -0,0 +1,98 @@ + + + + + + + + + + ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇØ »ç¿ëÇÑ ¿ë¾îµé + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¸ðµâÀ» ¼³¸íÇϱâÀ§ÇØ + »ç¿ëÇÑ ¿ë¾î¸¦ ¼³¸íÇÑ´Ù.

    +
    + +
    ¼³¸í + +

    ¸ðµâ ¸ñÀû¿¡ ´ëÇÑ °£´ÜÇÑ ¼³¸í.

    +
    + +
    »óÅÂ + +

    ¸ðµâÀÌ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í ¾ó¸¶³ª ¹ÐÁ¢È÷ ¿¬°üµÇÀÖ´ÂÁö ³ªÅ¸³½´Ù. + Áï, ƯÁ¤ ¸ðµâ°ú ¸ðµâÀÇ ±â´ÉÀ» »ç¿ëÇϱâÀ§Çؼ­ ¼­¹ö¸¦ ´Ù½Ã + ÄÄÆÄÀÏÇØ¾ß ÇÒ °æ¿ì°¡ ÀÖ´Ù. ÀÌ ¼Ó¼ºÀÇ °ªÀº:

    + +
    +
    MPM
    + +
    »óÅ°¡ "MPM"ÀÎ ¸ðµâÀº ´ÙÁßó¸® + ¸ðµâÀÌ´Ù. ´Ù¸¥ Á¾·ùÀÇ ¸ðµâ°ú ´Þ¸® ¾ÆÆÄÄ¡´Â ¿ÀÁ÷ ÇÑ + MPM¸¸À» »ç¿ëÇÑ´Ù. ÀÌ·± Á¾·ùÀÇ ¸ðµâÀº ±âº»ÀûÀÎ ¿äû ó¸®¿Í + ºÐ¹è¸¦ ´ã´çÇÑ´Ù.
    + +
    Base
    + +
    »óÅ°¡ "Base"ÀÎ ¸ðµâÀº ±âº»ÀûÀ¸·Î ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵǹǷÎ, + ¼³Á¤¿¡¼­ ¸ðµâÀ» Á¦°ÅÇÏÁö ¾Ê´Â ÇÑ º¸Åë »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    Extension
    + +
    »óÅ°¡ "Extension"ÀÎ ¸ðµâÀº º¸Åë ¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵÇÁö + ¾Ê´Â´Ù. ¸ðµâ°ú ¸ðµâÀÇ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é ¼­¹ö ÄÄÆÄÀÏ + ±¸¼ºÆÄÀÏÀ» º¯°æÇÏ°í ¾ÆÆÄÄ¡¸¦ ´Ù½Ã ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù.
    + +
    Experimental
    + +
    "Experimental" »óÅ´ ¸ðµâÀÌ ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖÁö¸¸, + »ç¿ëÇÏ·Á¸é À§ÇèÀ» °¨¼öÇØ¾ß ÇÑ´Ù. ¸ðµâ¿¡ ´ëÇÑ ¹®¼­°¡ ÀÖÁö¸¸, + ¸ðµâÀ» Áö¿øÇÑ´Ù´Â ¸»Àº ¾Æ´Ï´Ù.
    + +
    External
    + +
    "External" »óÅ´ ±âº» ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÁö ¾ÊÀº + ¸ðµâ("Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ")ÀÌ´Ù. ¿ì¸®´Â ÀÌ·± ¸ðµâ¿¡ Ã¥ÀÓÀÌ + ¾ø°í Áö¿øÇÏÁöµµ ¾Ê´Â´Ù.
    +
    +
    + +
    ¼Ò½ºÆÄÀÏ + +

    °£´ÜÇÏ°Ô ¸»Çؼ­ ¸ðµâ ¼Ò½ºÄڵ尡 ÀÖ´Â ¼Ò½ºÆÄÀϸíÀÌ´Ù. + IfModule + Áö½Ã¾î¿¡¼­ »ç¿ëÇÏ´Â À̸§À̱⵵ ÇÏ´Ù.

    +
    + +
    ¸ðµâ¸í + +

    ¸ðµâÀ» ÁöĪÇÏ´Â ¹®ÀÚ¿­·Î, ¸ðµâÀ» µ¿ÀûÀ¸·Î ÀоîµéÀÌ´Â + LoadModule Áö½Ã¾î¿¡¼­ + »ç¿ëÇÑ´Ù. Á¤È®È÷ ¸»ÇÏ¸é ¼Ò½ºÆÄÀÏ¿¡¼­ module ÇüÀÇ ¿ÜºÎº¯¼ö + À̸§ÀÌ´Ù.

    +
    + +
    Áö¿ø + +

    ¸ðµâÀÌ ¿ø·¡ ¾ÆÆÄÄ¡ ¹öÀü 2 ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÁö ¾Ê¾Ò´Ù¸é, + ¸ðµâÀ» óÀ½ ¼Ò°³ÇÑ ¹öÀüÀ» ¾Ë·ÁÁØ´Ù. ¶Ç, ¸ðµâÀÌ Æ¯Á¤ + Ç÷¡Æû¿ëÀ̶ó¸é »ó¼¼È÷ ¼³¸íÇÑ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/mod/module-dict.xml.meta b/trunk/docs/manual/mod/module-dict.xml.meta new file mode 100644 index 0000000000..dd3e109876 --- /dev/null +++ b/trunk/docs/manual/mod/module-dict.xml.meta @@ -0,0 +1,13 @@ + + + + module-dict + /mod/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/mod/mpm_common.html b/trunk/docs/manual/mod/mpm_common.html new file mode 100644 index 0000000000..f76c5828c5 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.html @@ -0,0 +1,11 @@ +URI: mpm_common.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm_common.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm_common.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mpm_common.html.de b/trunk/docs/manual/mod/mpm_common.html.de new file mode 100644 index 0000000000..785886743e --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.html.de @@ -0,0 +1,985 @@ + + + +mpm_common - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Allgemeine Direktiven der Apache-MPMs

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + +
    Beschreibung:Eine Sammlung von Direktiven, die in mehr als einem + Multi-Processing-Modul (MPM) implementiert sind.
    Status:MPM
    +
    + + +
    top
    +

    AcceptMutex-Direktive

    + + + + + + + +
    Beschreibung:Vom Apache verwendete Methode zur Serialisierung mehrerer + Kindprozesse, die Anfragen an Netzwerk-Sockets entgegennehmen.
    Syntax:AcceptMutex Default|Methode
    Voreinstellung:AcceptMutex Default
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, perchild, prefork, threadpool, worker
    +

    Die Direktive AcceptMutex bestimmt die + Methode, die der Apache zur Serialisierung mehrerer Kindprozesse + verwendet, welche Anfragen an Netzwerk-Sockets entgegennehmen. Vor + Apache 2.0 war diese Methode nur zur Kompilierungszeit einstellbar. + Die optimale Methode ist sehr stark von der Architektur und + Plattform abhängig. Lesen Sie bitte Perfomance-Hinweise für + weitere Details.

    + +

    Wenn die Direktive auf Default eingestellt ist, dann + wird die zur Kompilierungszeit gewählte Voreinstellung verwendet. + Weitere mögliche Methoden sind unten angegeben. Beachten Sie, dass + nicht alle Methoden auf allen Plattformen verfügbar sind. Wird + eine Methode angegeben, die nicht verfügbar ist, dann wird + eine Nachricht in das Fehlerprotokoll geschrieben, welche die + verfügbaren Methoden auflistet.

    + +
    +
    flock
    +
    verwendet die Systemfunktion flock(2), um die + durch die LockFile-Direktive definierte Datei zu sperren.
    + +
    fcntl
    +
    verwendet die Systemfunktion fcntl(2), um die + durch die LockFile-Direktive definierte Datei zu sperren.
    + +
    posixsem
    +
    verwendet POSIX-kompatible Semaphore, um den Mutex zu + implementieren.
    + +
    pthread
    +
    verwendet gemäß der POSIX-Thread-Spezifikation + implementierte POSIX-Mutexe.
    + +
    sysvsem
    +
    verwendet Semaphoren des SysV-Typs, um den Mutex zu + implementieren.
    +
    + +

    Um die bei der Kompilierung gewählte Voreinstellung für + Ihr System herauszufinden, können Sie Ihr LogLevel auf debug setzen. Dann wird der + voreingestellte AcceptMutex ins ErrorLog geschrieben.

    + +

    Warnung

    +

    Auf den meisten Systemen stoppt der Server mit der Beantwortung von + Anfragen, wenn die Option pthread ausgewählt wurde und + ein Kindprozess unkontrolliert endet während er den + AcceptCntl-Mutex hält. In diesem Fall muss der Server + manuell neu gestartet werden, um wieder weiter zu arbeiten.

    +

    Eine Ausnahme stellt Solaris dar, da es einen Mechanismus anbietet, den + der Apache verwendet und der üblicherweise die Freigabe des Mutex + erlaubt, nachdem ein Kindprozess, der gerade einen Mutex hält, + abgestürzt ist.

    +

    Wenn Ihr System die Funktion + pthread_mutexattr_setrobust_np() bereitstellt, können + Sie wahrscheinlich die Option pthread problemlos + verwenden.

    +
    + +
    +
    top
    +

    CoreDumpDirectory-Direktive

    + + + + + + + +
    Beschreibung:Verzeichnis, in das der Apache zu wechseln versucht, bevor er + einen Hauptspeicherauszug erstellt
    Syntax:CoreDumpDirectory Verzeichnis
    Voreinstellung:Für die Voreinstellung siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    Dies beeinflusst das Verzeichnis, in welches der Apache zu wechseln + versucht, bevor er einen Hauptspeicherauszug (Anm.d.Ü.: einen + so genannten Core-Dump) erstellt. Die Voreinstellung ist das + ServerRoot-Verzeichnis. Da dieses + jedoch nicht für den Benutzer beschreibbar sein soll, unter dem + der Server läuft, werden normalerweise keine + Hauptspeicherauszüge geschrieben. Wenn Sie zum Debuggen + einen Hauptspeicherauszug haben möchten, können Sie + ihn mit dieser Direktive an einem anderen Ort ablegen lassen.

    + +

    Hauptspeicherauszüge unter Linux

    +

    Wenn Apache als root startet und zu einem anderen Benutzer + wechselt, deaktiviert der Linux-Kernel Hauptspeicherauszüge + auch dann, wenn der Prozess in dem Verzeichnis schreiben darf. Ab Linux + 2.4 reaktiviert Apache (ab 2.0.46) Hauptspeicherauszüge wieder, + jedoch nur dann, wenn Sie explizit + CoreDumpDirectory konfigurieren.

    +
    + +
    +
    top
    +

    EnableExceptionHook-Direktive

    + + + + + + + + +
    Beschreibung:Aktiviert einen Hook, der nach einem Absturz noch +Ausnahmefehler behandeln lassen kann
    Syntax:EnableExceptionHook On|Off
    Voreinstellung:EnableExceptionHook Off
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, perchild, prefork, threadpool, worker
    Kompatibilität:Verfügbar seit Version 2.0.49
    +

    Diese Direktive ist aus Sicherheitsgründen nur verfügbar, + wenn der Server mit der Option --enable-exception-hook + konfiguriert wurde. Sie aktiviert einen Hook, der es externen Modulen + erlaubt, sich dort einzuhängen und nach dem Absturz eines + Kindprozesses noch Aktionen durchzuführen.

    + +

    Es existieren bereits zwei Module, mod_whatkilledus und + mod_backtrace, welche diesen Hook verwenden. Weitere + Informationen hierzu finden Sie auf Jeff Trawicks EnableExceptionHook-Seite.

    + +
    +
    top
    +

    Group-Direktive

    + + + + + + + + +
    Beschreibung:Benutzergruppe, unter welcher der Server Anfragen + beantwortet
    Syntax:Group Unix-Gruppe
    Voreinstellung:Group #-1
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpmt_os2, perchild, prefork, threadpool, worker
    Kompatibilität:Seit Apache 2.0 nur in der globalen Server-Konfiguration + gültig
    +

    Die Direktive Group bestimmt die + Benutzergruppe, unter welcher der Server Anfragen beantwortet. + Um diese Direktive zu verwenden, muss der Server als root gestartet + werden. Wenn Sie den Server unter einem nicht-root-Benutzer starten, + wird er nicht zur angegebenen Gruppe wechseln können und statt + dessen weiter mit der Gruppe des ursprünglichen Benutzers + laufen. Unix-Gruppe kann sein:

    + +
    +
    Ein Gruppenname
    +
    Verweist auf die durch den Namen angegebene Gruppe.
    + +
    # gefolgt von einer Gruppennummer.
    +
    Verweist auf die durch ihre Nummer angegebene Gruppe.
    +
    + +

    Beispiel

    + Group www-group +

    + +

    Es wird empfohlen, dass Sie eine neue Gruppe speziell zum Betrieb + des Servers erstellen. Einige Administratoren verwenden den Benutzer + nobody. Dies ist jedoch nicht immer möglich + oder gewünscht.

    + +

    Sicherheit

    +

    Setzen Sie Group (oder User) nicht auf root, + solange Sie nicht ganz genau wissen, was Sie tun und welche Gefahren + Sie eingehen.

    +
    + +

    Wichtiger Hinweis: Die Verwendung der Direktive innerhalb von + <VirtualHost> + wird nicht länger unterstützt. Benutzen Sie SuexecUserGroup um Ihren Server + für suexec einzurichten.

    + +

    Anmerkung

    +

    Obwohl die Direktive Group in den MPMs + beos und mpmt_os2 existiert, ist + sie dort tatsächlich eine Leeranweisung und exisitert nur + aus Kompatibilitätsgründen.

    +
    + +
    +
    top
    +

    Listen-Direktive

    + + + + + + + +
    Beschreibung:IP-Adressen und Ports, an denen der Server lauscht
    Syntax:Listen [IP-Addresse:]Port
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    Kompatibilität:Seit Apache 2.0 vorgeschrieben
    +

    Die Direktive Listen weist den Apache an, + nur an den angegebenen IP-Adressen oder Ports zu lauschen. + Standardmäßig antwortet er auf alle Anfragen an allen + IP-Interfaces. Listen ist nun eine notwendige + Anweisung. Wenn sie nicht in der Konfigurationsdatei enthalten ist, + wird der Server-Start fehlschlagen. Dies ist eine Änderung + gegenüber früheren Versionen des Apache.

    + +

    Die Direktive Listen weist den Server an, + ankommende Anfragen am angegebenen Port oder der + Kombination aus Adresse und Port entgegenzunehmen. Wenn nur eine Portnummer + angegeben ist, dann lauscht der Server am angegebenen Port an allen + Interfaces. Wenn sowohl eine IP-Adresse als auch ein Port angegeben + sind, dann lauscht der Server am angegeben Port und Interface.

    + +

    Es können mehrere Listen-Anweisungen + verwendet werden, um eine Reihe von Adressen und Port anzugeben, an + denen gelauscht werden soll. Der Server antwortet auf Anfragen von + jedem der aufgeführten Adressen und Ports.

    + +

    Um beispielsweise den Server Verbindungen an den beiden Ports 80 und + 8000 annehmen zu lassen, verwenden Sie:

    + +

    + Listen 80
    + Listen 8000 +

    + +

    Um den Server Verbindungen an zwei angegebenen Interfaces und Ports + annehmen zu lassen, verwenden Sie:

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6-Adressen müssen wie in dem folgenden Beispiel in eckige + Klammern eingeschlossen werden:

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    + +

    Fehlermöglichkeit

    + Mehrere Listen-Direktiven für gleiche + IP-Adresse und Port führen zur Fehlermeldung + Address already in use (Anm.d.Ü.: Adresse schon in + Benutzung). +
    + +

    Siehe auch

    + +
    +
    top
    +

    ListenBackLog-Direktive

    + + + + + + + +
    Beschreibung:Maximale Länge der Warteschlange schwebender + Verbindungen
    Syntax:ListenBacklog backlog
    Voreinstellung:ListenBacklog 511
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    Die maximale Länge der Warteschlange schwebender Verbindungen. + Üblicherweise ist keine Feineinstellung notwendig oder sinnvoll, + auf einigen System kann es jedoch gewünscht sein, diesen Wert bei + TCP-SYN-Angriffen zu erhöhen. Beachten Sie auch die Beschreibung des + backlog-Parameters der Systemfunktion listen(2).

    + +

    Der Wert wird vom Betriebssystem oft auf eine niedrigere + Einstellung begrenzt. Dies variiert von Betriebssystem zu Betriebssystem. + Beachten Sie auch, dass viele Betriebssyteme nicht genau beachten, + was für backlog angegeben ist, jedoch einen Wert basierend auf der + Angabe (normalerweiseweise jedoch größer als diese) verwenden.

    + +
    +
    top
    +

    LockFile-Direktive

    + + + + + + + +
    Beschreibung:Ablageort der Lock-Datei für die Serialisierung von +entgegengenommenen Anfragen
    Syntax:LockFile Dateiname
    Voreinstellung:LockFile logs/accept.lock
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, perchild, prefork, threadpool, worker
    +

    Die Direktive LockFile legt den Pfad zur + Lock-Datei fest, die verwendet wird, wenn der Apache mit einer der + AcceptMutex-Einstellungen + fcntl oder flock verwendet wird. Die Anweisung + sollte normalerweise bei der Voreinstellung belassen werden. + Der Hauptgrund, sie zu ändern, ist, wenn das + logs-Verzeichnis auf einem per NFS-eingebundenen Laufwerk + liegt, da die Lock-Datei auf einer lokalen Platte abgelegt sein + muss. Die PID (Anm.d.Ü.: Prozess-ID) des + Hauptserverprozesses wird automatisch an den Dateinamen angehängt.

    + +

    Sicherheit

    +

    Es ist am besten, die Ablage in einem allgemein (Anm.d.Ü.: für + jedermann) beschreibbaren + Verzeichnis wie /var/tmp zu vermeiden, da + ein Denial-of-Servide-Angriff gestartet werden könnte und der + Server am Start gehindert werden könnte, indem eine Lock-Datei + mit dem gleichen Namen erstellt wird, wie der Server sie zu erstellen + versuchen würde.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    MaxClients-Direktive

    + + + + + + + +
    Beschreibung:Maximale Anzahl der Kindprozesse, die zur Bedienung von Anfragen + gestartet wird
    Syntax:MaxClients Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, prefork, threadpool, worker
    +

    Die Direktive MaxClients setzt die Grenze + für die Anzahl gleichzeitig bedienter Anfragen. Jeder + Verbindungsversuch oberhalb der MaxClients-Begrenzung wird üblicherweise in eine + Warteschlange gestellt, bis zu einer Anzahl basierend auf der + ListenBacklog-Anweisung. + Sobald ein Kindprozess am Ende einer anderen Anfrage freigegeben wird, + wird die Verbindung bedient.

    + +

    Für Server ohne Thread-Unterstützung (z.B. + prefork) wird MaxClients als + maximale Anzahl der Kindprozesse verstanden, die zur Bedienung von + Anfragen gestartet werden. Die Voreinstellung ist 256. Um + diesen Wert zu erhöhen, muss auch ServerLimit angehoben werden.

    + +

    Bei Servern mit Thread-Unterstützung und bei Hybrid-Servern + (z.B. beos oder worker) + begrenzt MaxClients die Gesamtzahl der Threads, + die für die Bedienung von Anfragen verfügbar sind. + Die Voreinstellung für beos ist 50. + Bei Hybrid-MPMs ist die Voreinstellung 16 (ServerLimit) multipliziert mit + dem Wert 25 (ThreadsPerChild). Um MaxClients + auf einen Wert zu erhöhen, der mehr als 16 Prozesse erfordert, + müssen Sie daher auch ServerLimit anheben.

    + +
    +
    top
    +

    MaxMemFree-Direktive

    + + + + + + + +
    Beschreibung:Maximale Menge des Arbeitsspeichers, den die + Haupt-Zuteilungsroutine verwalten darf, ohne free() + aufzurufen
    Syntax:MaxMemFree KBytes
    Voreinstellung:MaxMemFree 0
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, prefork, threadpool, worker, mpm_winnt
    +

    Die Direktive MaxMemFree gibt die maximale + Menge freier Kilobytes an, welche die Haupt-Zuteilungsroutine verwalten + darf, ohne free() aufzurufen. Wenn keine Angabe gemacht wird, + oder Null angegeben ist, wird dieser Wert nicht eingeschränkt.

    + +
    +
    top
    +

    MaxRequestsPerChild-Direktive

    + + + + + + + +
    Beschreibung:Obergrenze für die Anzahl von Anfragen, die ein einzelner + Kindprozess während seines Lebens bearbeitet
    Syntax:MaxRequestsPerChild number
    Voreinstellung:MaxRequestsPerChild 10000
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    Die Direktive MaxRequestsPerChild legt die + Grenze für die Anzahl von Anfragen fest, die ein einzelner + Kinprozess während seines Lebens bearbeitet. Nach + MaxRequestsPerChild Anfragen stirbt der + Kindprozess. Wenn MaxRequestsPerChild + 0 ist, endet der Prozess niemals.

    + +

    Abweichende Voreinstellungen

    +

    Die Voreinstellung für mpm_netware und + mpm_winnt ist 0.

    +
    + +

    Die Begrenzung von MaxRequestsPerChild auf einen + Wert ungleich Null hat zwei vorteilhafte Auswirkungen:

    + +
      +
    • sie begrenzt die Menge an Arbeitsspeicher, die ein Prozess + durch (versehentliche) Speicherlecks verbrauchen kann.
    • + +
    • das Festlegen einer endlichen Lebensdauer von Prozessen hilft, die + Anzahl von Prozessen zu reduzieren, wenn die Serverlast + zurückgeht.
    • +
    + +

    Anmerkung

    +

    Bei KeepAlive-Anfragen + wird nur die erste Anfrage für diese begrenzung gezählt. + Eigentlich wird nur die Begrenzung für die Anzahl der + Verbindungen pro Kindprozess geändert.

    +
    + +
    +
    top
    +

    MaxSpareThreads-Direktive

    + + + + + + + +
    Beschreibung:Maximale Anzahl unbeschäftigter Threads
    Syntax:MaxSpareThreads Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    Maximale Anzahl unbeschäftigter Threads. Die verschiedenen MPMs + behandeln diese Anweisung unterschiedlich.

    + +

    Die Voreinstellung für perchild ist + MaxSpareThreads 10. Das MPM überwacht die Anzahl der + unbeschäftigten Threads auf der Basis einzelner Kindprozesse. Wenn + zu viele unbeschäftigte Threads in einem Kindprozess existieren, + beendet der Server Threads innerhalb dieses Kindprozesses.

    + +

    Die Voreinstellung für worker, + leader und threadpool ist + MaxSpareThreads 250. Diese MPMs behandeln Threads + auf einer serverweiten Basis. Wenn zu viele unbeschäftigte Threads + im Server existieren, dann werden solange Kindprozesse beendet, bis + die Anzahl der unbeschäftigten Threads kleiner als der + angegebene Wert ist.

    + +

    Die Voreinstellung für mpm_netware ist + MaxSpareThreads 100. Da dieses MPM nur einen einzigen + Prozess ausführt, ist die Zählung überschüssiger + Threads ebenfalls serverweit.

    + +

    beos and mpmt_os2 arbeiten + ähnlich wie mpm_netware. Die Voreinstellung + für beos ist MaxSpareThreads 50. + Die Voreinstellung für mpmt_os2 ist + 10.

    + +

    Restriktionen

    +

    Der Wertebereich von MaxSpareThreads + ist eingeschränkt. Apache korrigiert den angegebenen Wert + automatisch gemäß den folgenden Regeln:

    + +
    + +

    Siehe auch

    + +
    +
    top
    +

    MinSpareThreads-Direktive

    + + + + + + + +
    Beschreibung:Minimale Anzahl unbeschäftigter Threads, die zur + Bedienung von Anfragespitzen zur Verfügung stehen
    Syntax:MinSpareThreads Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    Minimale Anzahl unbeschäftigter Threads, um Anfragespitzen + zu bedienen. Die verschiedenen MPMs behandeln die Anweisung + unterschiedlich.

    + +

    perchild verwendet die Voreinstellung + MinSpareThreads 5 und überwacht die Anzahl der + unbeschäftigten Threads auf der Basis einzelner Kindprozesse. Wenn + in einem Kindprozess nicht genügend unbeschäftigte + Threads vorhanden sind, erstellt der Server neue Threads innerhalb + dieses Kindprozesses. Wenn Sie also NumServers auf 10 und MinSpareThreads auf einen Wert von 5 setzen, + haben Sie mindestens 50 unbeschäftigte Threads auf Ihrem + System.

    + +

    worker, leader und + threadpool verwenden eine Voreinstellung von + MinSpareThreads 75 und behandeln unbeschäftigte + Threads auf serverweiter Basis. Wenn nicht genügend + unbeschäftigte Threads im Server vorhanden sind, dann + werden solange Kindprozesse erzeugt, bis die Anzahl unbeschäftigter + Threads größer als der angegebene Wert ist.

    + +

    mpm_netware verwendet die Voreinstellung + MinSpareThreads 10 und verfolgt dies serverweit, da + es ein Einzelprozess-MPM ist.

    + +

    beos und mpmt_os2 arbeiten + ähnlich wie mpm_netware. Die Voreinstellung + für beos ist MinSpareThreads 1. + Die Voreinstellung für mpmt_os2 ist + 5.

    + + +

    Siehe auch

    + +
    +
    top
    +

    PidFile-Direktive

    + + + + + + + +
    Beschreibung:Datei, in welcher der Server die Prozess-ID des Daemons +ablegt
    Syntax:PidFile Dateiname
    Voreinstellung:PidFile logs/httpd.pid
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    Die Direktive PidFile bestimmt die Datei, + in welcher der Server die Prozess-ID des Daemons ablegt. Wenn der + Dateiname nicht absolut angegeben wird, wird er relativ zu + ServerRoot interpretiert.

    + +

    Beispiel

    + PidFile /var/run/apache.pid +

    + +

    Es ist oft hilfreich, dem Server ein Signal senden zu können, + damit er seine ErrorLogs und + TransferLogs + schließt und dann neu öffnet und seine + Konfigurationsdateien neu einliest. Dies kann durch Senden eines + SIGHUP-Signals (kill -1) an die Prozess-ID geschehen, die im + PidFile eingetragen ist.

    + +

    Die PidFile-Datei unterliegt den + gleichen Warnungen über die Ablage von Protokolldateien + und Sicherheit.

    + +

    Anmerkung

    +

    Ab Apache 2 wird empfohlen, nur das Skript apachectl zum (Neu-)Starten und Stoppen des Servers zu + verwenden.

    +
    + +
    +
    top
    +

    ScoreBoardFile-Direktive

    + + + + + + + +
    Beschreibung:Ablageort der Datei, die zur Speicherung von Daten zur + Koordinierung der Kindprozesse verwendet wird
    Syntax:ScoreBoardFile Dateipfad
    Voreinstellung:ScoreBoardFile logs/apache_status
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    Apache verwendet ein Scoreboard zur Kommunikation zwischen + seinen Eltern- und Kindprozessen. Einige Architekturen erfordern + eine Datei zur Unterstützung der Kommunikation. Wenn die Datei + undefiniert bleibt, versucht der Apache zuerst, das Scoreboard im + Arbeitsspeicher zu erstellen (Verwendung von anonymem Shared-Memory), + und versucht bei einem Fehlschlag anschließend die Datei auf + der Festplatte zu erstellen (Verwendung von Datei-basiertem + Shared-Memory). Die Angabe dieser Direktive veranlaßt den + Apache stets, die Datei auf der Festplatte zu erstellen.

    + +

    Beispiel

    + ScoreBoardFile /var/run/apache_status +

    + +

    Datei-basiertes Shared-Memory ist für Applikationen von + Drittanbietern hilfreich, die direkten Zugriff auf das Scoreboard + benötigen.

    + +

    Wenn Sie eine ScoreBoardFile-Anweisung + verwenden, erreichen Sie eventuell eine höhere Geschwindigkeit, wenn + Sie die Datei auf einer RAM-Disk ablegen. Achten Sie darauf, die + gleichen Warnungen wie über die Ablage von Protokolldateien und + Sicherheit zu beherzigen.

    + +

    Siehe auch

    + +
    +
    top
    +

    SendBufferSize-Direktive

    + + + + + + + +
    Beschreibung:Größe des TCP-Puffers
    Syntax:SendBufferSize Bytes
    Voreinstellung:SendBufferSize 0
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    Der Server setzt die Größe des TCP-Puffers auf die + angegebene Anzahl Bytes. Dies ist sehr hilfreich, um Voreinstellungen + alter Standardbetriebssysteme für Hochgeschwindigkeitsverbindungen + mit hoher Latenzzeit anzuheben (d.h. 100ms oder so, wie bei + Interkontinentalverbindungen).

    + +

    Wird der Wert auf 0 gesetzt, dann verwendet der Server + die Voreinstellung des Betriebssystems.

    + +
    +
    top
    +

    ServerLimit-Direktive

    + + + + + + + +
    Beschreibung:Obergrenze für die konfigurierbare Anzahl von + Prozessen
    Syntax:ServerLimit Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, perchild, prefork, threadpool, worker
    +

    Bei dem MPM prefork bestimmt die Direktive + den während der Lebensdauer des Apache-Prozesses maximal + einstellbaren Wert für MaxClients. Beim MPM + worker bestimmt die Direktive in Verbindung mit + ThreadLimit den Maximalwert + für MaxClients + für die Lebensdauer des Apache-Prozesses. Jeder Versuch, diese + Anweisung während eines Neustarts zu ändern, wird ignoriert. + MaxClients kann jedoch + während eines Neustarts geändert werden.

    + +

    Lassen Sie besondere Vorsicht bei der Verwendung dieser Direktive + walten. Wenn ServerLimit auf einen Wert deutlich + höher als notwendig gesetzt wird, wird zusätzliches, + unbenutztes Shared-Memory belegt. Wenn sowohl + ServerLimit als auch MaxClients auf Werte gesetzt werden, die + größer sind, als das System sie handhaben kann, dann kann + der Apache möglicherweise nicht starten, oder das System kann + instabil werden.

    + +

    Verwenden Sie die Direktive bei dem MPM prefork + nur, wenn Sie MaxClients + auf mehr als 256 (Voreinstellung) setzen müssen. Setzen Sie den + Wert nicht höher als den Wert, den Sie für MaxClients angeben möchten.

    + +

    Verwenden Sie die Direktive bei worker, + leader und threadpool nur, wenn Ihre + MaxClients- und + ThreadsPerChild-Einstellungen + mehr als 16 Serverprozesse (Voreinstellung) erfordern. Setzen Sie den + Wert dieser Direktive nicht höher, als die Anzahl der Serverprozesse, + die dafür erforderlich ist, was Sie bei MaxClients und + ThreadsPerChild angeben + möchten.

    + +

    Verwenden Sie die Direktive beim MPM perchild nur, + wenn Sie NumServers auf einen + Wert größer als 8 (Voreinstellung) setzen müssen.

    + +

    Anmerkung

    +

    Eine feste Begrenzung von ServerLimit 20000 ist in den + Server einkompiliert (bei dem MPM prefork 200000). + Dies soll unangenehme Effekte durch Tippfehler verhindern.

    +
    + +

    Siehe auch

    + +
    +
    top
    +

    StartServers-Direktive

    + + + + + + + +
    Beschreibung:Anzahl der Kindprozesse des Servers, die beim Start erstellt + werden
    Syntax:StartServers Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, mpmt_os2, prefork, threadpool, worker
    +

    Die Direktive StartServers bestimmt + die Anzahl der Kindprozesse des Servers, die beim Start erstellt + werden. Da die Anzahl der Prozesse abhängig von der Last + dynamisch kontrolliert wird, besteht normalerweise wenig + Grund für eine Änderung dieses Parameters.

    + +

    Die Voreinstellung unterscheidet sich von MPM zu MPM. Bei + leader, threadpool und + worker ist die Voreinstellung + StartServers 3. Die Voreinstellung bei + prefork ist 5 und bei + mpmt_os2 2.

    + +
    +
    top
    +

    StartThreads-Direktive

    + + + + + + + +
    Beschreibung:Anzahl der Threads, die beim Start erstellt werden
    Syntax:StartThreads Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:beos, mpm_netware, perchild
    +

    Anzahl der Threads, die beim Start erstellt werden. Da die Anzahl + der Threads abhängig von der Last dynamisch kontrolliert wird, + besteht normalerweise wenig Grund für eine Änderung + dieses Parameters.

    + +

    Die Voreinstellung für perchild ist + StartThreads 5. Die Direktive setzt während des + Starts die Anzahl der Threads pro Prozess.

    + +

    Die Voreinstellung bei mpm_netware ist + StartThreads 50. Da hier lediglich ein einzelner Prozess + existiert, ist dies die Gesamtzahl der Threads, die beim Start + erstellt wird, um Anfragen zu bedienen.

    + +

    Die Voreinstellung für beos ist StartThreads + 10. Die Einstellung reflektiert ebenfalls die Gesamtzahl der Threads, die + beim Start erstellt werden, um Anfragen zu bedienen.

    + +
    +
    top
    +

    ThreadLimit-Direktive

    + + + + + + + + +
    Beschreibung:Bestimmt die Obergrenze der konfigurierbaren Anzahl von Threads + pro Kindprozess
    Syntax:ThreadLimit Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, mpm_winnt, perchild, threadpool, worker
    Kompatibilität:Verfügbar für mpm_winnt ab + Apache 2.0.41
    +

    Die Direktive bestimmt den während der Lebensdauer des + Apache-Prozesses maximal einstellbaren Wert für + ThreadsPerChild. Jeder + Versuch, diese Direktive während eines Neustarts zu ändern, + wird ignoriert. ThreadsPerChild + kann jedoch während eines Neustarts modifiziert werden bis zu dem + Wert dieser Anweisung.

    + +

    Lassen Sie besondere Vorsicht bei der Verwendung dieser Direktive + walten. Wenn ThreadLimit auf einen Wert + deutlich höher als ThreadsPerChild gesetzt wird, wird + zusätzliches, ungenutztes Shared-Memory belegt. Wenn sowohl + ThreadLimit als auch ThreadsPerChild auf Werte gesetzt werden, + die größer sind, als das System sie handhaben kann, dann kann + der Apache möglicherweise nicht starten oder das System kann + instabil werden. Setzen Sie den Wert dieser Direktive nicht höher + als Ihre größte erwartete Einstellung für + ThreadsPerChild + während der aktuellen Ausführung des Apache.

    + +

    Die Voreinstellung für ThreadLimit ist + 1920 wenn sie zusammen mit mpm_winnt + verwendet wird, und 64 bei der Verwendung mit anderen + MPMs.

    + +

    Anmerkung

    +

    Eine feste Begrenzung von ThreadLimit 20000 + (oder ThreadLimit 15000 bei mpm_winnt) + ist in den Server einkompiliert. Dies soll unangenehme Effekte durch + Tippfehler verhindern.

    +
    + +
    +
    top
    +

    ThreadsPerChild-Direktive

    + + + + + + + +
    Beschreibung:Anzahl der Threads, die mit jedem Kindprozess gestartet + werden
    Syntax:ThreadsPerChild Anzahl
    Voreinstellung:Für Details siehe Beschreibung
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, mpm_winnt, threadpool, worker
    +

    Die Direktive legt die Anzahl der Threads fest, die mit jedem + Kindprozess gestartet werden. Der Kindprozess erstellt diese Threads + beim Start und erstellt später keine weiteren mehr. Wenn Sie ein + MPM wie mpm_winnt verwenden, wo nur ein + Kindprozess existiert, dann sollte diese Angabe hoch genug sein, + die gesamte Last des Servers zu bewältigen. Wenn Sie ein MPM + wie worker verwenden, wo mehrere Kindprozesse + existieren, dann sollte die Gesamtzahl der Thread groß + genug sein, die übliche Last auf dem Server zu bewältigen.

    + +

    Die Voreinstellung für ThreadsPerChild ist + 64, wenn mpm_winnt verwendet wird, und + 25 bei der Verwendung der anderen MPMs.

    + +
    +
    top
    +

    ThreadStackSize-Direktive

    + + + + + + + + +
    Beschreibung:Die Größe des Stacks in Bytes, der von Threads +verwendet wird, die Client-Verbindungen bearbeiten.
    Syntax:ThreadStackSize size
    Voreinstellung:65536 unter NetWare; variiert bei anderen Betriebssystemen.
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, mpm_netware, mpm_winnt, perchild, threadpool, worker
    Kompatibilität:Verfügbar seit Version 2.1
    +

    Die Direktive ThreadStackSize legt die + Größe des Stacks (für Autodaten) der Threads fest, die + Client-Verbindungen bearbeiten und Module aufrufen, welche bei der + Verarbeitung dieser Verbindungen helfen. In den meisten Fällen ist die + Voreinstellung des Betriebssystems angemessen, doch unter bestimmten + Umständen kann es sinnvoll sein, den Wert anzupassen:

    + +
      +
    • Auf Plattformen mit einer relativ kleinen Voreingestellung für + die Größe des Thread-Stacks (z.B. HP-UX) kann der Apache bei + der Verwendung einiger Drittanbietermodule, die einen relativ hohen Bedarf + an Speicherplatz haben, abstürzen. Ebendiese Module arbeiten + möglicherweise problemlos auf anderen Plattformen, wo der + voreingestellte Thread-Stack größer ist. Derartige + Abstürze können Sie vermeiden, indem Sie + ThreadStackSize auf einen höheren Wert als die + Betriebssystemvoreinstellung setzen. Eine solche Anpassung ist nur + notwendig, wenn es vom Anbieter des Moduls so spezifiziert wurde oder die + Diagnose eines Apache-Absturzes ergeben hat, das die + Thread-Stackgröße zu klein war.
    • + +
    • Auf Plattformen, wo die voreingestellte Thread-Stackgröße + für die Webserverkonfiguration deutlich größer als + notwendig ist, kann eine größere Anzahl von Threads pro + Kindprozess erreicht werden, wenn ThreadStackSize + auf einen Wert kleiner als die Betriebssystemvoreinstellung gesetzt wird. + Da es einzelne Anfragen geben kann, die mehr Stack zur Verarbeitung + benötigen, sollte eine derartige Korrektur ausschließlich in + Testumgebungen zum Einsatz kommen, auf denen die gesamte + Webserververarbeitung ausprobiert werden kann. Eine Änderung der + Webserverkonfiguration kann den aktuellen Wert der + ThreadStackSize ungültig machen.
    • +
    + +
    +
    top
    +

    User-Direktive

    + + + + + + + + +
    Beschreibung:Die Benutzerkennung, unter welcher der Server Anfragen + beantwortet
    Syntax:User Unix-User-ID
    Voreinstellung:User #-1
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:leader, perchild, prefork, threadpool, worker
    Kompatibilität:Seit Apache 2.0 nur in der globalen Server-Konfiguration +gültig
    +

    Die Direktive User legt die Benutzerkennung + fest, mit der der Server Anfragen beantwortet. Um diese Anweisung + zu verwenden, muss der Server als root gestartet werden. + Wenn Sie den Server unter einem nicht-root-Benutzer starten, kann + er nicht zu dem minder privilegierten Benutzer wechseln und wird statt + dessen weiter mit der ursprünglichen Benutzerkennung laufen. + Wenn Sie den Server als root starten, dann ist es normal, + dass der Elternprozess als root weiterläuft. + Unix-User-ID kann sein:

    + +
    +
    Ein Benutzername
    +
    Verweist auf den durch Namen angegebenen Benutzer.
    + +
    # gefolgt von einer Benutzernummer.
    +
    Verweist auf einen durch eine Nummer angegebenen Benutzer.
    +
    + +

    Der Benutzer sollte keine Rechte besitzen, die dazu führen, + dass er in der Lage ist, auf Dateien zuzugreifen, die nicht dafür + bestimmt sind, für die Außenwelt sichtbar zu sein. + Gleichermaßen sollte der Benutzer nicht in der Lage sein, + Code auszuführen, der nicht für HTTP-Anfragen bestimmt ist. + Es wird empfohlen, einen neuen Benutzer und eine neue Gruppe speziell + zur Ausführung des Servers zu erstellen. Einige Administratoren + verwenden den Benutzer nobody. Dies ist jedoch nicht + immer wünschenswert, da der Benuter nobody andere + Rechte auf dem System besitzen kann.

    + +

    Sicherheit

    +

    Setzen Sie User (oder Group) nicht auf root, + solange Sie nicht genau wissen, was Sie tun, und welches die Gefahren + sind.

    +
    + +

    Beim MPM perchild, das dafür gedacht ist, + virtuelle Hosts unter verschiedenen Benutzerkennungen auszuführen, + bestimmt die Direktive User die + Benutzerkennung für den Hauptserver und bildet den Rückfallwert + für <VirtualHost>-Abschnitte ohne eine + AssignUserID-Anweisung.

    + +

    Wichtiger Hinweis: Die Verwendung dieser Direktive innerhalb von + <VirtualHost> wird + nicht mehr unterstützt. Benutzen Sie SuexecUserGroup, um Ihren Server + für suexec einzurichten.

    + +

    Anmerkung

    +

    Obwohl die Direktive User in den MPMs + beos und mpmt_os2 existiert, ist + sie dort tatsächlich eine Leeranweisung und exisitert nur + aus Kompatibilitätsgründen.

    +
    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_common.html.en b/trunk/docs/manual/mod/mpm_common.html.en new file mode 100644 index 0000000000..b9ae5f2c52 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.html.en @@ -0,0 +1,912 @@ + + + +mpm_common - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM Common Directives

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + +
    Description:A collection of directives that are implemented by +more than one multi-processing module (MPM)
    Status:MPM
    +
    + + +
    top
    +

    AcceptMutex Directive

    + + + + + + + +
    Description:Method that Apache uses to serialize multiple children +accepting requests on network sockets
    Syntax:AcceptMutex Default|method
    Default:AcceptMutex Default
    Context:server config
    Status:MPM
    Module:leader, perchild, prefork, threadpool, worker
    +

    The AcceptMutex directives sets the + method that Apache uses to serialize multiple children accepting + requests on network sockets. Prior to Apache 2.0, the method was + selectable only at compile time. The optimal method to use is + highly architecture and platform dependent. For further details, + see the performance tuning + documentation.

    + +

    If this directive is set to Default, then the + compile-time selected default will be used. Other possible + methods are listed below. Note that not all methods are + available on all platforms. If a method is specified which is + not available, a message will be written to the error log + listing the available methods.

    + +
    +
    flock
    +
    uses the flock(2) system call to lock the + file defined by the LockFile directive.
    + +
    fcntl
    +
    uses the fcntl(2) system call to lock the + file defined by the LockFile directive.
    + +
    posixsem
    +
    uses POSIX compatible semaphores to implement the mutex.
    + +
    pthread
    +
    uses POSIX mutexes as implemented by the POSIX Threads + (PThreads) specification.
    + +
    sysvsem
    +
    uses SySV-style semaphores to implement the mutex.
    +
    + +

    If you want to find out the compile time chosen default + for your system, you may set your LogLevel to debug. Then the default AcceptMutex will be written into the ErrorLog.

    + +

    Warning

    +

    On most systems, when the pthread option + is selected, if a child process terminates abnormally + while holding the AcceptCntl mutex the + server will stop responding to requests. When this + occurs, the server will require a manual restart to + recover.

    +

    Solaris is a notable exception as it provides a + mechanism, used by Apache, which usually allows the + mutex to be recovered after a child process terminates + abnormally while holding a mutex.

    +

    If your system implements the + pthread_mutexattr_setrobust_np() function, + you may be able to use the pthread option safely.

    +
    + +
    +
    top
    +

    CoreDumpDirectory Directive

    + + + + + + + +
    Description:Directory where Apache attempts to +switch before dumping core
    Syntax:CoreDumpDirectory directory
    Default:See usage for the default setting
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    This controls the directory to which Apache attempts to + switch before dumping core. The default is in the + ServerRoot directory, however + since this should not be writable by the user the server runs + as, core dumps won't normally get written. If you want a core + dump for debugging, you can use this directive to place it in a + different location.

    + +

    Core Dumps on Linux

    +

    If Apache starts as root and switches to another user, the + Linux kernel disables core dumps even if the directory is + writable for the process. Apache (2.0.46 and later) reenables core dumps + on Linux 2.4 and beyond, but only if you explicitly configure a CoreDumpDirectory.

    +
    + +
    +
    top
    +

    EnableExceptionHook Directive

    + + + + + + + + +
    Description:Enables a hook that runs exception handlers +after a crash
    Syntax:EnableExceptionHook On|Off
    Default:EnableExceptionHook Off
    Context:server config
    Status:MPM
    Module:leader, perchild, prefork, threadpool, worker
    Compatibility:Available in version 2.0.49 and later
    +

    For safety reasons this directive is only available if the server was + configured with the --enable-exception-hook option. It + enables a hook that allows external modules to plug in and do something + after a child crashed.

    + +

    There are already two modules, mod_whatkilledus and + mod_backtrace that make use of this hook. Please have a + look at Jeff Trawick's EnableExceptionHook site for more information about these.

    + +
    +
    top
    +

    Group Directive

    + + + + + + + + +
    Description:Group under which the server will answer +requests
    Syntax:Group unix-group
    Default:Group #-1
    Context:server config
    Status:MPM
    Module:beos, leader, mpmt_os2, perchild, prefork, threadpool, worker
    Compatibility:Only valid in global server config since Apache +2.0
    +

    The Group directive sets the group under + which the server will answer requests. In order to use this + directive, the server must be run initially as root. If + you start the server as a non-root user, it will fail to change to the + specified group, and will instead continue to run as the group of the + original user. Unix-group is one of:

    + +
    +
    A group name
    +
    Refers to the given group by name.
    + +
    # followed by a group number.
    +
    Refers to a group by its number.
    +
    + +

    Example

    + Group www-group +

    + +

    It is recommended that you set up a new group specifically for + running the server. Some admins use user nobody, + but this is not always possible or desirable.

    + +

    Security

    +

    Don't set Group (or User) to root unless + you know exactly what you are doing, and what the dangers are.

    +
    + +

    Special note: Use of this directive in <VirtualHost> is no longer supported. To + configure your server for suexec use + SuexecUserGroup.

    + +

    Note

    +

    Although the Group directive is present + in the beos and mpmt_os2 MPMs, + it is actually a no-op there and only exists for compatibility + reasons.

    +
    + +
    +
    top
    +

    Listen Directive

    + + + + + + + +
    Description:IP addresses and ports that the server +listens to
    Syntax:Listen [IP-address:]portnumber
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    Compatibility:Required directive since Apache 2.0
    +

    The Listen directive instructs Apache to + listen to only specific IP addresses or ports; by default it + responds to requests on all IP interfaces. Listen + is now a required directive. If it is not in the config file, the + server will fail to start. This is a change from previous versions + of Apache.

    + +

    The Listen directive tells the server to + accept incoming requests on the specified port or address-and-port + combination. If only a port number is specified, the server listens to + the given port on all interfaces. If an IP address is given as well + as a port, the server will listen on the given port and + interface.

    + +

    Multiple Listen directives may be used to + specify a number of addresses and ports to listen to. The server will + respond to requests from any of the listed addresses and ports.

    + +

    For example, to make the server accept connections on both + port 80 and port 8000, use:

    + +

    + Listen 80
    + Listen 8000 +

    + +

    To make the server accept connections on two specified + interfaces and port numbers, use

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6 addresses must be surrounded in square brackets, as in the + following example:

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    + +

    Error condition

    + Multiple Listen directives for the same ip + address and port will result in an Address already in use + error message. +
    + +

    See also

    + +
    +
    top
    +

    ListenBackLog Directive

    + + + + + + + +
    Description:Maximum length of the queue of pending connections
    Syntax:ListenBacklog backlog
    Default:ListenBacklog 511
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    The maximum length of the queue of pending connections. + Generally no tuning is needed or desired, however on some + systems it is desirable to increase this when under a TCP SYN + flood attack. See the backlog parameter to the + listen(2) system call.

    + +

    This will often be limited to a smaller number by the + operating system. This varies from OS to OS. Also note that + many OSes do not use exactly what is specified as the backlog, + but use a number based on (but normally larger than) what is + set.

    + +
    +
    top
    +

    LockFile Directive

    + + + + + + + +
    Description:Location of the accept serialization lock file
    Syntax:LockFile filename
    Default:LockFile logs/accept.lock
    Context:server config
    Status:MPM
    Module:leader, perchild, prefork, threadpool, worker
    +

    The LockFile directive sets the path to + the lockfile used when Apache is used with an AcceptMutex value of either + fcntl or flock. This directive should + normally be left at its default value. The main reason for changing + it is if the logs directory is NFS mounted, since + the lockfile must be stored on a local disk. The PID + of the main server process is automatically appended to the + filename.

    + +

    Security

    +

    It is best to avoid putting this file in a world writable + directory such as /var/tmp because someone could create + a denial of service attack and prevent the server from starting by + creating a lockfile with the same name as the one the server will try + to create.

    +
    + +

    See also

    + +
    +
    top
    +

    MaxClients Directive

    + + + + + + + +
    Description:Maximum number of child processes that will be created +to serve requests
    Syntax:MaxClients number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:beos, leader, prefork, threadpool, worker
    +

    The MaxClients directive sets the limit + on the number of simultaneous requests that will be served. Any + connection attempts over the MaxClients + limit will normally be queued, up to a number based on the + ListenBacklog + directive. Once a child process is freed at the end of a different + request, the connection will then be serviced.

    + +

    For non-threaded servers (i.e., prefork), + MaxClients translates into the maximum + number of child processes that will be launched to serve requests. + The default value is 256; to increase it, you must also raise + ServerLimit.

    + +

    For threaded and hybrid servers (e.g. beos + or worker) MaxClients restricts + the total number of threads that will be available to serve clients. + The default value for beos is 50. For + hybrid MPMs the default value is 16 (ServerLimit) multiplied by the value of + 25 (ThreadsPerChild). Therefore, to increase MaxClients to a value that requires more than 16 processes, + you must also raise ServerLimit.

    + +
    +
    top
    +

    MaxMemFree Directive

    + + + + + + + +
    Description:Maximum amount of memory that the main allocator is allowed +to hold without calling free()
    Syntax:MaxMemFree KBytes
    Default:MaxMemFree 0
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, prefork, threadpool, worker, mpm_winnt
    +

    The MaxMemFree directive sets the + maximum number of free Kbytes that the main allocator is allowed + to hold without calling free(). When not set, or when set + to zero, the threshold will be set to unlimited.

    + +
    +
    top
    +

    MaxRequestsPerChild Directive

    + + + + + + + +
    Description:Limit on the number of requests that an individual child server +will handle during its life
    Syntax:MaxRequestsPerChild number
    Default:MaxRequestsPerChild 10000
    Context:server config
    Status:MPM
    Module:leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    The MaxRequestsPerChild directive sets + the limit on the number of requests that an individual child + server process will handle. After + MaxRequestsPerChild requests, the child + process will die. If MaxRequestsPerChild is + 0, then the process will never expire.

    + +

    Different default values

    +

    The default value for mpm_netware and + mpm_winnt is 0.

    +
    + +

    Setting MaxRequestsPerChild to a + non-zero limit has two beneficial effects:

    + +
      +
    • it limits the amount of memory that process can consume + by (accidental) memory leakage;
    • + +
    • by giving processes a finite lifetime, it helps reduce + the number of processes when the server load reduces.
    • +
    + +

    Note

    +

    For KeepAlive requests, only + the first request is counted towards this limit. In effect, it + changes the behavior to limit the number of connections per + child.

    +
    + +
    +
    top
    +

    MaxSpareThreads Directive

    + + + + + + + +
    Description:Maximum number of idle threads
    Syntax:MaxSpareThreads number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    Maximum number of idle threads. Different MPMs deal with this + directive differently.

    + +

    For perchild the default is + MaxSpareThreads 10. This MPM monitors the number of + idle threads on a per-child basis. If there are too many idle + threads in that child, the server will begin to kill threads + within that child.

    + +

    For worker, leader and threadpool the default is MaxSpareThreads 250. + These MPMs deal with idle threads on a server-wide basis. If there + are too many idle threads in the server then child processes are + killed until the number of idle threads is less than this number.

    + +

    For mpm_netware the default is + MaxSpareThreads 100. Since this MPM runs a + single-process, the spare thread count is also server-wide.

    + +

    beos and mpmt_os2 work + similar to mpm_netware. The default for + beos is MaxSpareThreads 50. For + mpmt_os2 the default value is 10.

    + +

    Restrictions

    +

    The range of the MaxSpareThreads value + is restricted. Apache will correct the given value automatically + according to the following rules:

    + +
    + +

    See also

    + +
    +
    top
    +

    MinSpareThreads Directive

    + + + + + + + +
    Description:Minimum number of idle threads available to handle request +spikes
    Syntax:MinSpareThreads number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    Minimum number of idle threads to handle request spikes. + Different MPMs deal with this directive + differently.

    + +

    perchild uses a default of + MinSpareThreads 5 and monitors the number of idle + threads on a per-child basis. If there aren't enough idle threads + in that child, the server will begin to create new threads within + that child. Thus, if you set NumServers to 10 and a MinSpareThreads value of 5, you'll have + at least 50 idle threads on your system.

    + +

    worker, leader and + threadpool use a default of MinSpareThreads + 75 and deal with idle threads on a server-wide basis. If + there aren't enough idle threads in the server then child + processes are created until the number of idle threads is greater + than number.

    + +

    mpm_netware uses a default of + MinSpareThreads 10 and, since it is a single-process + MPM, tracks this on a server-wide bases.

    + +

    beos and mpmt_os2 work + similar to mpm_netware. The default for + beos is MinSpareThreads 1. For + mpmt_os2 the default value is 5.

    + +

    See also

    + +
    +
    top
    +

    PidFile Directive

    + + + + + + + +
    Description:File where the server records the process ID +of the daemon
    Syntax:PidFile filename
    Default:PidFile logs/httpd.pid
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    The PidFile directive sets the file to + which the server records the process id of the daemon. If the + filename is not absolute then it is assumed to be relative to the + ServerRoot.

    + +

    Example

    + PidFile /var/run/apache.pid +

    + +

    It is often useful to be able to send the server a signal, + so that it closes and then re-opens its ErrorLog and TransferLog, and + re-reads its configuration files. This is done by sending a + SIGHUP (kill -1) signal to the process id listed in the + PidFile.

    + +

    The PidFile is subject to the same + warnings about log file placement and security.

    + +

    Note

    +

    As of Apache 2 it is recommended to use only the apachectl script for (re-)starting or stopping the server.

    +
    + +
    +
    top
    +

    ScoreBoardFile Directive

    + + + + + + + +
    Description:Location of the file used to store coordination data for +the child processes
    Syntax:ScoreBoardFile file-path
    Default:ScoreBoardFile logs/apache_status
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    Apache uses a scoreboard to communicate between its parent + and child processes. Some architectures require a file to facilitate + this communication. If the file is left unspecified, Apache first + attempts to create the scoreboard entirely in memory (using anonymous + shared memory) and, failing that, will attempt to create the file on + disk (using file-based shared memory). Specifying this directive causes + Apache to always create the file on the disk.

    + +

    Example

    + ScoreBoardFile /var/run/apache_status +

    + +

    File-based shared memory is useful for third-party applications + that require direct access to the scoreboard.

    + +

    If you use a ScoreBoardFile then + you may see improved speed by placing it on a RAM disk. But be + careful that you heed the same warnings about log file placement + and security.

    + +

    See also

    + +
    +
    top
    +

    SendBufferSize Directive

    + + + + + + + +
    Description:TCP buffer size
    Syntax:SendBufferSize bytes
    Default:SendBufferSize 0
    Context:server config
    Status:MPM
    Module:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    The server will set the TCP buffer size to the number of bytes + specified. Very useful to increase past standard OS defaults on + high speed high latency (i.e., 100ms or so, such as + transcontinental fast pipes).

    + +

    If set to the value of 0, the server will use the + OS deault.

    + +
    +
    top
    +

    ServerLimit Directive

    + + + + + + + +
    Description:Upper limit on configurable number of processes
    Syntax:ServerLimit number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:leader, perchild, prefork, threadpool, worker
    +

    For the prefork MPM, this directive sets the + maximum configured value for MaxClients for the lifetime of the + Apache process. For the worker MPM, this directive + in combination with ThreadLimit sets + the maximum configured value for MaxClients for the lifetime of the + Apache process. Any attempts to change this directive during a + restart will be ignored, but MaxClients can be modified during + a restart.

    + +

    Special care must be taken when using this directive. If + ServerLimit is set to a value much higher + than necessary, extra, unused shared memory will be allocated. If + both ServerLimit and MaxClients are set to values + higher than the system can handle, Apache may not start or the + system may become unstable.

    + +

    With the prefork MPM, use this directive only + if you need to set MaxClients higher than 256 (default). + Do not set the value of this directive any higher than what you + might want to set MaxClients to.

    + +

    With worker, leader and + threadpool use this directive only + if your MaxClients and + ThreadsPerChild + settings require more than 16 server processes (default). Do not set + the value of this directive any higher than the number of server + processes required by what you may want for MaxClients and ThreadsPerChild.

    + +

    With the perchild MPM, use this directive only + if you need to set NumServers higher than 8 (default).

    + +

    Note

    +

    There is a hard limit of ServerLimit 20000 compiled + into the server (for the prefork MPM 200000). This is + intended to avoid nasty effects caused by typos.

    +
    + +

    See also

    + +
    +
    top
    +

    StartServers Directive

    + + + + + + + +
    Description:Number of child server processes created at startup
    Syntax:StartServers number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:leader, mpmt_os2, prefork, threadpool, worker
    +

    The StartServers directive sets the + number of child server processes created on startup. As the number + of processes is dynamically controlled depending on the load, + there is usually little reason to adjust this parameter.

    + +

    The default value differs from MPM to MPM. For + leader, threadpool and + worker the default is StartServers 3. + For prefork defaults to 5 and for + mpmt_os2 to 2.

    + +
    +
    top
    +

    StartThreads Directive

    + + + + + + + +
    Description:Number of threads created on startup
    Syntax:StartThreads number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:beos, mpm_netware, perchild
    +

    Number of threads created on startup. As the + number of threads is dynamically controlled depending on the + load, there is usually little reason to adjust this + parameter.

    + +

    For perchild the default is StartThreads + 5 and this directive tracks the number of threads per + process at startup.

    + +

    For mpm_netware the default is + StartThreads 50 and, since there is only a single + process, this is the total number of threads created at startup to + serve requests.

    + +

    For beos the default is StartThreads + 10. It also reflects the total number of threads created + at startup to serve requests.

    + +
    +
    top
    +

    ThreadLimit Directive

    + + + + + + + + +
    Description:Sets the upper limit on the configurable number of threads +per child process
    Syntax:ThreadLimit number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:leader, mpm_winnt, perchild, threadpool, worker
    Compatibility:Available for mpm_winnt in Apache 2.0.41 +and later
    +

    This directive sets the maximum configured value for ThreadsPerChild for the lifetime + of the Apache process. Any attempts to change this directive + during a restart will be ignored, but ThreadsPerChild can be modified + during a restart up to the value of this directive.

    + +

    Special care must be taken when using this directive. If + ThreadLimit is set to a value much higher + than ThreadsPerChild, + extra unused shared memory will be allocated. If both + ThreadLimit and ThreadsPerChild are set to values + higher than the system can handle, Apache may not start or the + system may become unstable. Do not set the value of this directive + any higher than your greatest predicted setting of ThreadsPerChild for the + current run of Apache.

    + +

    The default value for ThreadLimit is + 1920 when used with mpm_winnt and + 64 when used with the others.

    + +

    Note

    +

    There is a hard limit of ThreadLimit 20000 (or + ThreadLimit 15000 with mpm_winnt) + compiled into the server. This is intended to avoid nasty effects + caused by typos.

    +
    + +
    +
    top
    +

    ThreadsPerChild Directive

    + + + + + + + +
    Description:Number of threads created by each child process
    Syntax:ThreadsPerChild number
    Default:See usage for details
    Context:server config
    Status:MPM
    Module:leader, mpm_winnt, threadpool, worker
    +

    This directive sets the number of threads created by each + child process. The child creates these threads at startup and + never creates more. If using an MPM like mpm_winnt, + where there is only one child process, this number should be high + enough to handle the entire load of the server. If using an MPM + like worker, where there are multiple child processes, + the total number of threads should be high enough to handle + the common load on the server.

    + +

    The default value for ThreadsPerChild is + 64 when used with mpm_winnt and + 25 when used with the others.

    + +
    +
    top
    +

    ThreadStackSize Directive

    + + + + + + + + +
    Description:The size in bytes of the stack used by threads handling +client connections
    Syntax:ThreadStackSize size
    Default:65536 on NetWare; varies on other operating systems
    Context:server config
    Status:MPM
    Module:leader, mpm_netware, mpm_winnt, perchild, threadpool, worker
    Compatibility:Available in Apache 2.1 and later
    +

    The ThreadStackSize directive sets the + size of the stack (for autodata) of threads which handle client + connections and call modules to help process those connections. + In most cases the operating system default for stack size is + reasonable, but there are some conditions where it may need to be + adjusted:

    + +
      +
    • On platforms with a relatively small default thread stack size + (e.g., HP-UX), Apache may crash when using some third-party modules + which use a relatively large amount of autodata storage. Those + same modules may have worked fine on other platforms where the + default thread stack size is larger. This type of crash is + resolved by setting ThreadStackSize to a + value higher than the operating system default. This type of + adjustment is necessary only if the provider of the third-party + module specifies that it is required, or if diagnosis of an Apache + crash indicates that the thread stack size was too small.
    • + +
    • On platforms where the default thread stack size is + significantly larger than necessary for the web server + configuration, a higher number of threads per child process + will be achievable if ThreadStackSize is + set to a value lower than the operating system default. This type + of adjustment should only be made in a test environment which allows + the full set of web server processing can be exercised, as there + may be infrequent requests which require more stack to process. + A change in the web server configuration can invalidate the + current ThreadStackSize setting.
    • +
    + +
    +
    top
    +

    User Directive

    + + + + + + + + +
    Description:The userid under which the server will answer +requests
    Syntax:User unix-userid
    Default:User #-1
    Context:server config
    Status:MPM
    Module:leader, perchild, prefork, threadpool, worker
    Compatibility:Only valid in global server config since Apache +2.0
    +

    The User directive sets the user ID as + which the server will answer requests. In order to use this + directive, the server must be run initially as root. + If you start the server as a non-root user, it will fail to change + to the lesser privileged user, and will instead continue to run as + that original user. If you do start the server as root, + then it is normal for the parent process to remain running as root. + Unix-userid is one of:

    + +
    +
    A username
    +
    Refers to the given user by name.
    + +
    # followed by a user number.
    +
    Refers to a user by its number.
    +
    + +

    The user should have no privileges that result in it being + able to access files that are not intended to be visible to the + outside world, and similarly, the user should not be able to + execute code that is not meant for HTTP requests. It is + recommended that you set up a new user and group specifically for + running the server. Some admins use user nobody, but + this is not always desirable, since the nobody user + can have other uses on the system.

    + +

    Security

    +

    Don't set User (or Group) to root unless + you know exactly what you are doing, and what the dangers are.

    +
    + +

    With the perchild MPM, which is intended to + server virtual hosts run under different user IDs, the + User directive defines the user ID for the + main server and the fallback for <VirtualHost> sections without an + AssignUserID directive.

    + +

    Special note: Use of this directive in <VirtualHost> is no longer supported. To + configure your server for suexec use + SuexecUserGroup.

    + +

    Note

    +

    Although the User directive is present + in the beos and mpmt_os2 MPMs, + it is actually a no-op there and only exists for compatibility + reasons.

    +
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_common.html.ja.euc-jp b/trunk/docs/manual/mod/mpm_common.html.ja.euc-jp new file mode 100644 index 0000000000..1cfed60208 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.html.ja.euc-jp @@ -0,0 +1,980 @@ + + + +mpm_common - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache MPM ¶¦Ḁ̈ǥ£¥ì¥¯¥Æ¥£¥Ö

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + +
    ÀâÌÀ:Æó¤Ä°Ê¾å¤Î¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) +¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥³¥ì¥¯¥·¥ç¥ó
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    +
    + + +
    top
    +

    AcceptMutex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Ê£¿ô¤Î»Ò¥×¥í¥»¥¹¤¬¥Í¥Ã¥È¥ï¡¼¥¯¥½¥±¥Ã¥È¤Ç¥ê¥¯¥¨¥¹¥È¤ò +accept ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤Ë¡¢Apache ¤¬¤½¤ì¤é¤Î»Ò¥×¥í¥»¥¹¤òľÎ󲽤¹¤ë¤¿¤á¤Ë +»È¤¦ÊýË¡
    ¹½Ê¸:AcceptMutex default|method
    ¥Ç¥Õ¥©¥ë¥È:AcceptMutex default
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, perchild, prefork, threadpool, worker
    +

    AcceptMutex ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥Í¥Ã¥È¥ï¡¼¥¯¥½¥±¥Ã¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò accept ¤·¤è¤¦¤È¤·¤Æ¤¤¤ëÊ£¿ô¤Î»Ò¥×¥í¥»¥¹¤ò + Apache ¤¬Ä¾Î󲽤¹¤ë¤¿¤á¤Ë»È¤¦ÊýË¡¤òÀßÄꤷ¤Þ¤¹¡£ + Apache 2.0 °ÊÁ°¤Ï¡¢¤³¤Î¥á¥½¥Ã¥É¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¤Î¤ßÁªÂò¤Ç¤­¤Þ¤·¤¿¡£ + ºÇŬ¤ÊÊýË¡¤Ï¡¢¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤ä¥×¥é¥Ã¥È¥Û¡¼¥à¤ËÂ礭¤¯°Í¸¤·¤Þ¤¹¡£ + ¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï¡¢À­Ç½¤Î¥Á¥å¡¼¥Ë¥ó¥° + ¥É¥­¥å¥á¥ó¥È¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ Default + ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¥³¥ó¥Ñ¥¤¥ë»þ¤ËÁªÂò¤µ¤ì¤¿¥Ç¥Õ¥©¥ë¥ÈÃͤ¬»È¤ï¤ì¤Þ¤¹¡£ + ¾¤Î»ÈÍѲÄǽ¤Ê¥á¥½¥Ã¥É¤Î°ìÍ÷¤Ï²¼¤Ë¤¢¤ê¤Þ¤¹¡£ + Á´¤Æ¤Î¥á¥½¥Ã¥É¤¬Á´¤Æ¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç»ÈÍѲÄǽ¤Ç¤¢¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¡¢ + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + »ÈÍѲÄǽ¤Ç¤Ê¤¤¥á¥½¥Ã¥É¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢ + »ÈÍѲÄǽ¤Ê¥á¥½¥Ã¥É¤Î°ìÍ÷¤ò´Þ¤ó¤À¥á¥Ã¥»¡¼¥¸¤¬ + ¥¨¥é¡¼¥í¥°¤Ë½ÐÎϤµ¤ì¤Þ¤¹¡£

    + +
    +
    flock
    +
    LockFile + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÄêµÁ¤·¤¿¥Õ¥¡¥¤¥ë¤Î¥í¥Ã¥¯¤Ë¡¢ + flock(2) ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò»È¤¤¤Þ¤¹¡£
    + +
    fcntl
    +
    LockFile + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÄêµÁ¤·¤¿¥Õ¥¡¥¤¥ë¤Î¥í¥Ã¥¯¤Ë¡¢ + fcntl(2) ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò»È¤¤¤Þ¤¹¡£
    + +
    posixsem
    +
    ÇÓ¾½èÍý¤Î¼ÂÁõ¤Ë POSIX ¸ß´¹¥»¥Þ¥Õ¥©¤ò»ÈÍѤ·¤Þ¤¹
    + +
    pthread
    +
    POSIX Threads (PThreads) µ¬³Ê¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ë + POSIX ÇÓ¾½èÍý¤ò»È¤¤¤Þ¤¹¡£
    + +
    sysvsem
    +
    ÇÓ¾½èÍý¤Î¼ÂÁõ¤Ë SySV ·Á¼°¤Î¥»¥Þ¥Õ¥©¤ò»È¤¤¤Þ¤¹¡£
    +
    + +

    ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥·¥¹¥Æ¥à¤Î¥Ç¥Õ¥©¥ë¥È¤ËÁª¤Ð¤ì¤¿¤â¤Î¤¬²¿¤«¤ò¸«¤¿¤¤¾ì¹ç¤Ï¡¢ + LogLevel ¤ò debug + ¤ËÀßÄꤹ¤ë¤È¤è¤¤¤Ç¤·¤ç¤¦¡£¥Ç¥Õ¥©¥ë¥È¤Î AcceptMutex + ¤¬ ErrorLog ¤Ë½ñ¤­¹þ¤Þ¤ì¤Þ¤¹¡£

    + +

    ·Ù¹ð

    +

    ¤Û¤È¤ó¤É¤Î¥·¥¹¥Æ¥à¤Ë¤ª¤¤¤Æ¤Ï¡¢pthread ¥ª¥×¥·¥ç¥ó¤¬ + Áª¤Ð¤ì¤Æ¤¤¤ë¤È¡¢»Ò¥×¥í¥»¥¹¤¬ ApacheCntl mutex ¤ò + ÊÝ»ý¤·¤Æ¤¤¤ë¤È¤­¤Ë°Û¾ï½ªÎ»¤·¤¿¾ì¹ç¡¢¥µ¡¼¥Ð¤Ï¥ê¥¯¥¨¥¹¥È¤Ø¤Î±þÅú¤ò + Ää»ß¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¤³¤ì¤¬È¯À¸¤·¤¿¾ì¹ç¤Ï¡¢¥µ¡¼¥Ð¤òÉüµì¤µ¤»¤ë¤¿¤á¤Ë¤Ï + ¼êÆ°¤ÇºÆµ¯Æ°¤µ¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    Solaris ¤ÏÎã³°¤Ç¡¢Apache ¤â»ÈÍѤ·¤Æ¤¤¤ë¡¢»Ò¥×¥í¥»¥¹¤¬ mutex ¤ò + ÊÝ»ý¤·¤Æ°Û¾ï½ªÎ»¤·¤¿¸å¤Ë mutex ¤òÉüµì¤µ¤»¤ë¤¿¤á¤Îµ¡¹½¤òÄ󶡤ò¤·¤Æ¤¤¤Þ¤¹¡£

    +

    ¸æ»ÈÍѤΥ·¥¹¥Æ¥à¤¬ pthread_mutexattr_setrobust_np() ´Ø¿ô¤ò + ¼ÂÁõ¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢pthread ¥ª¥×¥·¥ç¥ó¤ò°ÂÁ´¤Ë»ÈÍѤǤ­¤ë + ²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    CoreDumpDirectory ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:Apache ¤¬¥³¥¢¥À¥ó¥×¤¹¤ëÁ°¤Ë°ÜÆ°¤ò»î¤ß¤ë¥Ç¥£¥ì¥¯¥È¥ê +
    ¹½Ê¸:CoreDumpDirectory directory
    ¥Ç¥Õ¥©¥ë¥È:¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤ÏÀâÌÀʸ¤òÆɤó¤Ç¤¯¤À¤µ¤¤
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    Apache ¤¬¥³¥¢¥À¥ó¥×¤¹¤ëÁ°¤Ë°ÜÆ°¤ò»î¤ß¤ë¥Ç¥£¥ì¥¯¥È¥ê¤òÀ©¸æ¤·¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï ServerRoot + ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¤¬¡¢¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ï¥µ¡¼¥Ð¤Î¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¥æ¡¼¥¶¸¢¸Â¤Ç + ½ñ¤­¹þ¤ß²Äǽ¤Ç¤¢¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢Ä̾ï¤Ï¥³¥¢¥À¥ó¥×¤Ï½ñ¤­¹þ¤Þ¤ì¤Þ¤»¤ó¡£ + ¥Ç¥Ð¥Ã¥°¤Î¤¿¤á¤Ë¥³¥¢¥À¥ó¥×¤¬É¬ÍפǤ¢¤ì¤Ð¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¾¤Î°ÌÃ֤˥³¥¢¥À¥ó¥×¤ò½ñ¤­½Ð¤¹¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    Linux ¤Ç¤Î¥³¥¢¥À¥ó¥×

    +

    Apache ¤¬ root ¤È¤·¤Æµ¯Æ°¤µ¤ì¤Æ¡¢Ê̤Υ桼¥¶¤Î¸¢¸Â¤Ë°Ê¹ß¤·¤¿¾ì¹ç¤Ï + Linux ¤Î¥«¡¼¥Í¥ë¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤¬¥×¥í¥»¥¹¤Î¸¢¸Â¤Ç½ñ¤­¹þ¤ß²Äǽ¤Ê¾ì¹ç¤Ç¤µ¤¨¤â + ¥³¥¢¥À¥ó¥×¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£Apache (2.0.46 °Ê¹ß) ¤Ï + Linux 2.4 °Ê¹ß¤Ç¤Ï¥³¥¢¥À¥ó¥×¤ò¹Ô¤Ê¤¦¤è¤¦¤ËºÆ»ØÄꤷ¤Þ¤¹¤¬¡¢¤½¤ì¤Ï + CoreDumpDirectory ¤òÌÀ¼¨Åª¤ËÀßÄꤷ¤¿¤È¤­¤Ë + ¸Â¤ê¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    EnableExceptionHook ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¯¥é¥Ã¥·¥å¤Î¸å¤ËÎã³°¥Ï¥ó¥É¥é¤ò¼Â¹Ô¤¹¤ë¥Õ¥Ã¥¯¤òÍ­¸ú¤Ë¤¹¤ë
    ¹½Ê¸:EnableExceptionHook On|Off
    ¥Ç¥Õ¥©¥ë¥È:EnableExceptionHook Off
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, perchild, prefork, threadpool, worker
    ¸ß´¹À­:2.0.49 °Ê¹ß
    +

    °ÂÁ´¾å¤ÎÍýͳ¤«¤é¡¢--enable-exception-hook configure + ¥ª¥×¥·¥ç¥ó¤òÍ­¸ú¤Ë¤·¤¿¾ì¹ç¤Ë¤Î¤ß¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÍøÍѤǤ­¤Þ¤¹¡£ + ³°Éô¥â¥¸¥å¡¼¥ë¤ò¥×¥é¥°¥¤¥ó¤·¤Æ¡¢»Ò¤¬¥¯¥é¥Ã¥·¥å¤·¤¿¸å¤Ë²¿¤«¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ê + ¥Õ¥Ã¥¯¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£

    + +

    ¤³¤Î¤è¤¦¤Ê³°Éô¥â¥¸¥å¡¼¥ë¤Ï¡¢´û¤ËÆó¤Ä¸ºß¤·¤Æ¤¤¤Æ¡¢ + mod_whatkilledus ¤È mod_backtrace + ¤¬¤³¤Î¥Õ¥Ã¥¯¤ò³èÍѤ·¤Þ¤¹¡£¤³¤ì¤é¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï Jeff Trawick + ¤µ¤ó¤Î EnableExceptionHook site ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    top
    +

    Group ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤Ë½ê°¤¹¤ë¥°¥ë¡¼¥×
    ¹½Ê¸:Group unix-group
    ¥Ç¥Õ¥©¥ë¥È:Group #-1
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpmt_os2, perchild, prefork, threadpool, worker
    ¸ß´¹À­:Apache 2.0 °Ê¹ß¤Ç¡¢¥°¥í¡¼¥Ð¥ëÀßÄê¤Ç¤Î¤ßÍ­¸ú¤Ç¤¹¡£
    +

    Group ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ + ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤Ë½ê°¤·¤Æ¤ª¤¯¥°¥ë¡¼¥×¤òÀßÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¢ + ¥µ¡¼¥Ð¤ÏºÇ½é¤Ë root ¸¢¸Â¤Çµ¯Æ°¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + Èó root ¥æ¡¼¥¶¤Ç¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿¾ì¹ç¤Ï¡¢»ØÄꤷ¤¿¥°¥ë¡¼¥×¤ËÊѲ½¤Ç¤­¤º¤Ë¡¢ + ·ë²ÌŪ¤Ëµ¯Æ°¤·¤¿¥æ¡¼¥¶¤Î°¤¹¤ë¥°¥ë¡¼¥×¤Ç¼Â¹Ô¤µ¤ì¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + unix-group ¤Ï¼¡¤Î¤¦¤Á¤Î¤¤¤º¤ì¤«¤Ç¤¹:

    + +
    +
    ¥°¥ë¡¼¥×̾
    +
    ¥°¥ë¡¼¥×¤ò̾Á°¤Ç»²¾È¤·¤Þ¤¹
    + +
    # ¤Ë³¤¤¤Æ¥°¥ë¡¼¥×ÈÖ¹æ
    +
    ¥°¥ë¡¼¥×¤ò¤òÈÖ¹æ¤Ç»²¾È¤·¤Þ¤¹¡£
    +
    + +

    Îã

    + Group www-group +

    + +

    ¥µ¡¼¥Ð¤ò¼Â¹Ô¤¹¤ë¤¿¤á¤ËÆÃÄê¤Î¿·¤·¤¤¥°¥ë¡¼¥×¤òÀßÄꤹ¤ë¤³¤È¤ò + ¤ªÁ¦¤á¤·¤Þ¤¹¡£nobody ¤ò»ÈÍѤ¹¤ë´ÉÍý¼Ô¤â¤¤¤Þ¤¹¤¬¡¢ + ²Äǽ¤Ç¤¢¤Ã¤¿¤ê˾¤Þ¤·¤¤Ìõ¤Ç¤Ïɬ¤º¤·¤â¤¢¤ê¤Þ¤»¤ó¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    Àµ³Î¤Ë¤É¤ó¤Ê¤³¤È¤ò¤ä¤Ã¤Æ¤¤¤ë¤Î¤«¡¢¤½¤Î´í¸±À­¤òÃΤé¤Ê¤¤¤Ç¡¢ + Group (¤ä User) ¤ò + root ¤Ë ÀßÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£

    +
    + +

    Æõ­»ö¹à: ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + <VirtualHost> + ¤Ç»ÈÍѤ¹¤ë¤³¤È¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Ê¤¯¤Ê¤ê¤Þ¤·¤¿¡£Apache 2.0 ¤Ç + suexec ¤òÀßÄꤷ¤¿¤¤¾ì¹ç¤Ï¡¢ + SuexecUserGroup + ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãí°Õ

    +

    Group ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + beos ¤È mpmt_os2 MPM + ¤Ë¤â¸ºß¤·¤Þ¤¹¤¬¡¢¼Â¼ÁŪ¤Ë̵¸ú¤Ç¡¢¸ß´¹À­¤Î¤¿¤á¤À¤±¤Ë¸ºß¤·¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥µ¡¼¥Ð¤¬ listen ¤¹¤ëIP ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥ÈÈÖ¹æ
    ¹½Ê¸:Listen [IP-address:]portnumber
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    ¸ß´¹À­:Apache 2.0 ¤«¤éɬÍפʥǥ£¥ì¥¯¥Æ¥£¥Ö
    +

    Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache + ¤¬ÆÃÄê¤Î IP ¥¢¥É¥ì¥¹¤ä¥Ý¡¼¥ÈÈÖ¹æ¤À¤±¤ò listen ¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Ç¤ÏÁ´¤Æ¤Î IP ¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤·¤Þ¤¹¡£ + Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¸½ºß¤Ïɬ¿Ü¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤Ê¤ê¤Þ¤·¤¿¡£ + ¤â¤·ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¤Ê¤±¤ì¤Ð¡¢¥µ¡¼¥Ð¤Ïµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤¹¡£ + ¤³¤ì¤Ï°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Î Apache ¤«¤éÊѹ¹¤Î¤¢¤Ã¤¿Éôʬ¤Ç¤¹¡£

    + +

    Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢ÆÃÄê¤Î¥Ý¡¼¥È¤¢¤ë¤¤¤Ï + ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÎÁȤ߹ç¤ï¤»¤«¤éÆþ¤Ã¤Æ¤¯¤ë¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + ±þÅú¤¹¤ë¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£ + ¤â¤·¥Ý¡¼¥ÈÈÖ¹æ¤À¤±¤¬»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢¥µ¡¼¥Ð¤ÏÁ´¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Î + »ØÄꤵ¤ì¤¿¥Ý¡¼¥ÈÈÖ¹æ¤ËÂФ·¤Æ listen ¤·¤Þ¤¹¡£ + IP ¥¢¥É¥ì¥¹¤¬¥Ý¡¼¥È¤È¤È¤â¤Ë»ØÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï»ØÄꤵ¤ì¤¿¥Ý¡¼¥È¤È¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ËÂФ·¤Æ listen + ¤·¤Þ¤¹¡£

    + +

    Ê£¿ô¤Î¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ËÂФ·¤Æ listen ¤¹¤ë¤è¤¦¤Ë¡¢ + Ê£¿ô¤Î Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤ÏÎóµó¤µ¤ì¤¿¥¢¥É¥ì¥¹¤È¥Ý¡¼¥ÈÁ´¤Æ¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ + ±þÅú¤·¤Þ¤¹¡£

    + +

    Î㤨¤Ð¡¢¥µ¡¼¥Ð¤¬ 80 È֥ݡ¼¥È¤È 8000 È֥ݡ¼¥È¤ÎξÊý¤Î + ¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±Æþ¤ì¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    + Listen 80
    + Listen 8000 +

    + +

    Æó¤Ä¤ÎÆÃÄê¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È¥Ý¡¼¥ÈÈֹ椫¤é¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò + ¼õ¤±Æþ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +

    + +

    IPv6 ¥¢¥É¥ì¥¹¤Ï³Ñ³ç¸Ì¤Ç°Ï¤Þ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + Î㤨¤Ð¼¡¤ÎÎã¤Î¤è¤¦¤Ë¤Ç¤¹¡£

    + +

    + Listen [fe80::a00:20ff:fea7:ccea]:80 +

    + +

    ¥¨¥é¡¼¾ò·ï

    + Ʊ°ì IP ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÎÁȤˡ¢Ê£¿ô¤Î Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ØÄꤷ¤Æ¤·¤Þ¤¦¤È¡¢'Address already in use' + ¤È¤¤¤¦¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ +
    + + +

    »²¾È

    + +
    +
    top
    +

    ListenBackLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ÊÝα¾õÂ֤Υ³¥Í¥¯¥·¥ç¥ó¤Î¥­¥å¡¼¤ÎºÇÂçĹ
    ¹½Ê¸:ListenBacklog backlog
    ¥Ç¥Õ¥©¥ë¥È:ListenBacklog 511
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    ÊÝα¾õÂ֤Υ³¥Í¥¯¥·¥ç¥ó¤Î¥­¥å¡¼¤ÎºÇÂçŤǤ¹¡£ + °ìÈÌŪ¤Ë¤ÏÄ´À°¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤·¡¢Ä´À°¤Ï˾¤Þ¤·¤¯¤¢¤ê¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢TCP SYN ¥Õ¥é¥Ã¥É¥¢¥¿¥Ã¥¯¤Î¾õ¶·²¼¤Ë¤ª¤«¤ì¤ë¾ì¹ç¤Ë¡¢ + Áý¤ä¤·¤¿Êý¤¬Ë¾¤Þ¤·¤¤¥·¥¹¥Æ¥à¤â¤¢¤ê¤Þ¤¹¡£ + listen(2) ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Î¥Ð¥Ã¥¯¥í¥°¥Ñ¥é¥á¡¼¥¿¤ò + ¤´Í÷²¼¤µ¤¤¡£

    + +

    ¤³¤ÎÃÍ¤Ï OS ¤Ë¤è¤ê¡¢¾®¤µ¤Ê¿ô¤ËÍÞ¤¨¤é¤ì¤Þ¤¹¡£ + ÃÍ¤Ï OS Ëè¤Ë°Û¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿Â¿¤¯¤Î OS ¤Ç¤Ï¡¢ + ¥Ð¥Ã¥¯¥í¥°¤È¤·¤Æ»ØÄꤵ¤ì¤Æ¤¤¤ëÃͤÁ¤ç¤¦¤É¤Þ¤Ç»È¤Ã¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤Ê¤¯¡¢ + ÀßÄꤵ¤ì¤Æ¤¤¤ëÃͤ˴ð¤Å¤¤¤Æ (Ä̾ï¤ÏÀßÄêÃͤè¤ê¤âÂ礭¤ÊÃͤò) + »È¤Ã¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    top
    +

    LockFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¼õÉÕ¤òľÎ󲽤¹¤ë¤¿¤á¤Î¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    ¹½Ê¸:LockFile filename
    ¥Ç¥Õ¥©¥ë¥È:LockFile logs/accept.lock
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, perchild, prefork, threadpool, worker
    +

    AcceptMutex + ¤¬ fcntl ¤ä flock + ¤ËÀßÄꤵ¤ì¤Æ»ÈÍѤµ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ë¡¢»ÈÍѤµ¤ì¤ë¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤Ø¤Î¥Ñ¥¹¤ò + LockFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÄ̾ï¤Ï¤½¤Î¤Þ¤Þ¤Ë¤·¤Æ¤ª¤­¤Þ¤¹¡£ + ¼ç¤Ë logs ¥Ç¥£¥ì¥¯¥È¥ê¤¬ NFS + ¤Ç¥Þ¥¦¥ó¥È¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ê¤É¤ËÃͤòÊѤ¨¤Þ¤¹¡£ + ¤Ê¤¼¤Ê¤é¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤Ï¥í¡¼¥«¥ë¥Ç¥£¥¹¥¯¤Ë + Êݸ¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤é¤Ç¤¹¡£ + ¥á¥¤¥ó¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î PID ¤¬¥Õ¥¡¥¤¥ë̾¤Ë¼«Æ°Åª¤ËÉղ䵤ì¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    /var/tmp + ¤È¤¤¤Ã¤¿¡¢Ã¯¤Ç¤â½ñ¤­¹þ¤á¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥Õ¥¡¥¤¥ë¤ò + ÃÖ¤«¤Ê¤¤Êý¤¬¤è¤¤¤Ç¤¹¡£¤Ê¤¼¤Ê¤é¡¢¥µ¡¼¥Ð¤¬µ¯Æ°»þ¤ËºîÀ®¤¹¤ë + ¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤ÎºîÀ®¼«ÂΤò˸³²¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ï¤Ç¤â¥µ¡¼¥Ó¥¹µñÈÝ¥¢¥¿¥Ã¥¯¤ò°ú¤­µ¯¤³¤¹¤³¤È¤¬¤Ç¤­¤ë¤«¤é¤Ç¤¹¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    MaxClients ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤¿¤á¤ËºîÀ®¤µ¤ì¤ë +»Ò¥×¥í¥»¥¹¤ÎºÇÂç¸Ä¿ô
    ¹½Ê¸:MaxClients number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑË¡¤ò¤´Í÷²¼¤µ¤¤¡£
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, prefork, threadpool, worker
    +

    MaxClients ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ±þÅú¤¹¤ë¤³¤È¤Î¤Ç¤­¤ëƱ»þ¥ê¥¯¥¨¥¹¥È¿ô¤òÀßÄꤷ¤Þ¤¹¡£ + MaxClients À©¸Â¿ô¤ò±Û¤¨¤ë¥³¥Í¥¯¥·¥ç¥ó¤ÏÄ̾ + ListenBacklog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤¿¿ô¤Þ¤Ç¥­¥å¡¼¤ËÆþ¤ê¤Þ¤¹¡£ + ¾¤Î¥ê¥¯¥¨¥¹¥È¤ÎºÇ¸å¤Þ¤Ç㤷¤Æ»Ò¥×¥í¥»¥¹¤¬¶õ¤¯¤È¡¢ + ¼¡¤Î¥³¥Í¥¯¥·¥ç¥ó¤Ë±þÅú¤·¤Þ¤¹¡£

    + +

    ¥¹¥ì¥Ã¥É¤òÍѤ¤¤Ê¤¤¥µ¡¼¥Ð (¤¹¤Ê¤ï¤Á prefork) + ¤Ç¤Ï¡¢MaxClients + ¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤¿¤á¤Ëµ¯Æ°¤µ¤ì¤ë + »Ò¥×¥í¥»¥¹¤ÎºÇÂç¿ô¤È¤Ê¤ê¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 256 ¤Ç¡¢¤³¤ì¤òÁý²Ã¤µ¤»¤¿¤¤¾ì¹ç¤Ï¡¢ + ServerLimit + ¤ÎÃͤâÁý²Ã¤µ¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥¹¥ì¥Ã¥É¤òÍѤ¤¤ë¥µ¡¼¥Ð¤ä¡¢¥Ï¥¤¥Ö¥ê¥Ã¥É¥µ¡¼¥Ð (¤¹¤Ê¤ï¤Á + beos worker) + ¤Ç¤Ï¡¢MaxClients + ¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ë±þÅú¤Ç¤­¤ë¥¹¥ì¥Ã¥É¤ÎÁí¿ô¤òÀ©¸Â¤·¤Þ¤¹¡£ + beos ¤Ç¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 50 ¤Ç¤¹¡£ + ¥Ï¥¤¥Ö¥ê¥Ã¥É MPM ¤Ç¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 16 + ServerLimit + ¤Î 25 ÇÜ (ThreadsPerChild) ¤Ç¤¹¡£ + MaxClients + ¤ò 16 ¥×¥í¥»¥¹°Ê¾åɬÍפÊÃͤޤÇÁý²Ã¤µ¤»¤¿¤¤¾ì¹ç¤Ï¡¢ + ServerLimit + ¤âÁý²Ã¤µ¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    MaxMemFree ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:free() ¤¬¸Æ¤Ð¤ì¤Ê¤¤¸Â¤ê¡¢ +¼ç¥á¥â¥ê¥¢¥í¥±¡¼¥¿¤¬ÊÝ»ý¤·Â³¤±¤é¤ì¤ë¥á¥â¥ê¤ÎºÇÂçÎÌ
    ¹½Ê¸:MaxMemFree KBytes
    ¥Ç¥Õ¥©¥ë¥È:MaxMemFree 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, prefork, threadpool, worker, mpm_winnt
    +

    MaxMemFree ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + free() ¤¬¸Æ¤Ð¤ì¤Ê¤¤¸Â¤ê¡¢ + ¼ç¥¢¥í¥±¡¼¥¿¤¬ÊÝ»ý¤Ç¤­¤ë¶õ¤Î¥á¥â¥ê¤ÎºÇÂçÃͤò¥­¥í¥Ð¥¤¥Èñ°Ì¤ÇÀßÄꤷ¤Þ¤¹¡£ + ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤«¡¢Îí¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢ÌµÀ©¸Â¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    top
    +

    MaxRequestsPerChild ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¸Ä¡¹¤Î»Ò¥µ¡¼¥Ð¤¬²ÔƯÃæ¤Ë°·¤¦¥ê¥¯¥¨¥¹¥È¿ô¤Î¾å¸Â
    ¹½Ê¸:MaxRequestsPerChild number
    ¥Ç¥Õ¥©¥ë¥È:MaxRequestsPerChild 10000
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    MaxRequestsPerChild ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¸Ä¡¹¤Î»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤¬°·¤¦¤³¤È¤Î¤Ç¤­¤ë¥ê¥¯¥¨¥¹¥È¤ÎÀ©¸Â¿ô¤ò + ÀßÄꤷ¤Þ¤¹¡£MaxRequestsPerChild + ¸Ä¤Î¥ê¥¯¥¨¥¹¥È¤Î¸å¤Ë¡¢»Ò¥×¥í¥»¥¹¤Ï½ªÎ»¤·¤Þ¤¹¡£ + MaxRequestsPerChild ¤¬ 0 + ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¥×¥í¥»¥¹¤Ï´ü¸ÂÀÚ¤ì¤Ë¤è¤ê½ªÎ»¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    ¤½¤Î¾¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ

    +

    mpm_netware ¤È mpm_winnt + ¤Ç¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 0 ¤Ç¤¹¡£

    +
    + +

    MaxRequestsPerChild + ¤òÈó¥¼¥í¤ËÀ©¸Â¤¹¤ë¤³¤È¤Ë¤Ï¡¢Æó¤Ä¤ÎÍøÅÀ¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • (¶öȯŪ¤Ê) ¥á¥â¥ê¡¼¥ê¡¼¥¯¤¬µ¯¤³¤Ã¤¿¾ì¹ç¤Ë + ¥×¥í¥»¥¹¤¬¾ÃÈñ¤¹¤ë¥á¥â¥ê¤ÎÁíÎ̤òÀ©¸Â¤Ç¤­¤ë
    • + +
    • ¥×¥í¥»¥¹¤ËÍ­¸Â¤Î¥é¥¤¥Õ¥¿¥¤¥à¤òÀßÄꤹ¤ë¤³¤È¤Ç¡¢ + ¥µ¡¼¥ÐÉé²Ù¤¬²¼¤¬¤Ã¤¿»þ¤Ë¥×¥í¥»¥¹¿ô¤ò¾¯¤Ê¤¯¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë
    • +
    + +

    Ãí

    +

    KeepAlive ¥ê¥¯¥¨¥¹¥È¤Î¾ì¹ç¤Ï¡¢ + °ì¤ÄÌܤΥꥯ¥¨¥¹¥È¤À¤±¤¬¤³¤ÎÀ©¸Â¤Ë³ºÅö¤·¤Þ¤¹¡£ + ¼Â¸úŪ¤Ë¤Ï¡¢°ì¤Ä¤Î»Ò¥×¥í¥»¥¹¤¢¤¿¤ê¤Î¥³¥Í¥¯¥·¥ç¥ó¿ô¤ò + À©¸Â¤¹¤ë¤è¤¦¤ËµóÆ°¤¬ÊѲ½¤·¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    MaxSpareThreads ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤ÎºÇÂç¿ô
    ¹½Ê¸:MaxSpareThreads number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑË¡¤ò¤´Í÷²¼¤µ¤¤¡£
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    ¥¢¥¤¥É¥ë¤Ê¥¹¥ì¥Ã¥É¤ÎºÇÂç¿ô¤Ç¤¹¡£°Û¤Ê¤ë MPM ¤Ç¤Ï¤½¤ì¤¾¤ì¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï°Û¤Ê¤ë¼è¤ê°·¤ï¤ìÊý¤ò¤µ¤ì¤Þ¤¹¡£

    + +

    perchild ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MaxSpareThreads 10 ¤Ç¤¹¡£ + ¤³¤Î MPM ¤Ï¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ò¡¢¤½¤ì¤¾¤ì¤Î»Ò¥×¥í¥»¥¹¤´¤È¤Ë´Æ»ë¤·¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤Ë¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤¬Â¿¤¹¤®¤ë¾ì¹ç¤Ï¡¢ + ¥µ¡¼¥Ð¤Ï¤½¤Î»Ò¥×¥í¥»¥¹¤Ë´Þ¤Þ¤ì¤ë¥¹¥ì¥Ã¥É¤ò½ªÎ»¤·»Ï¤á¤Þ¤¹¡£

    + +

    worker, leader, + threadpool ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MaxSpareThreads 250 ¤Ç¤¹¡£ + ¤³¤Î MPM ¤Ï¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ò¥µ¡¼¥ÐÁ´ÂΤǴƻ뤷¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ç¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤¬Â¿¤¹¤®¤ë¾ì¹ç¤Ï¡¢ + ¤³¤Î¿ô»ú¤è¤ê¤â¾¯¤Ê¤¤¿ô¤Ë¤Ê¤ë¤Þ¤Ç»Ò¥×¥í¥»¥¹¤ò½ªÎ»¤·¤Þ¤¹¡£

    + +

    mpm_netware ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MaxSpareThreads 100 ¤Ç¤¹¡£ + ¤³¤Î MPM ¤Ï¥·¥ó¥°¥ë¥×¥í¥»¥¹¤Ç¼Â¹Ô¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + ¥¹¥Ú¥¢¥¹¥ì¥Ã¥É¿ô¤â¥µ¡¼¥ÐÁ´ÂΤǴªÄꤷ¤Þ¤¹¡£

    + +

    beos ¤È mpmt_os2 ¤Ï + mpm_netware ¤È»÷¤¿µóÆ°¤ò¤·¤Þ¤¹¡£ + beos ¤Ç¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï MaxSpareThreads 50 + ¤Ç¤¹¡£mpmt_os2 ¤Ç¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 10 + ¤Ç¤¹¡£

    + +

    À©¸Â»ö¹à

    +

    MaxSpareThreads ¤Î¼è¤ëÃͤˤÏÀ©¸Â¤¬¤¢¤ê¤Þ¤¹¡£ + Apache ¤Ï¼¡¤Îµ¬Â§¤Ë½¾¤Ã¤Æ¼«Æ°Åª¤ËÊäÀµ¤·¤Þ¤¹¡£

    + +
    + +

    »²¾È

    + +
    +
    top
    +

    MinSpareThreads ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤³¤È¤Î¤Ç¤­¤ë +¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ÎºÇ¾®¿ô
    ¹½Ê¸:MinSpareThreads number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑÊýË¡¤ò¤´Í÷²¼¤µ¤¤¡£
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, mpmt_os2, perchild, threadpool, worker
    +

    ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¥¹¥ì¥Ã¥É¿ô¤ÎºÇ¾®ÃͤǤ¹¡£ + °Û¤Ê¤ë MPM ¤Ç¤Ï¤½¤ì¤¾¤ì¡¢ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï°Û¤Ê¤ë¼è¤ê°·¤ï¤ìÊý¤ò¤·¤Þ¤¹¡£

    + +

    perchild ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MinSpareThreads 5 ¤Ç¡¢ + ¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ò»Ò¥×¥í¥»¥¹Ëè¤Ë´Æ»ë¤·¤Þ¤¹¡£ + ¤â¤·»Ò¥×¥í¥»¥¹¤Ë½½Ê¬¤Ê¿ô¤Î¥¹¥ì¥Ã¥É¤¬¤Ê¤±¤ì¤Ð¡¢ + ¥µ¡¼¥Ð¤Ï¤½¤Î»Ò¥×¥í¥»¥¹¤Ë¿·¤·¤¤¥¹¥ì¥Ã¥É¤òºî¤ê»Ï¤á¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢NumServers + ¤ò 10 ¤Ë¡¢MinSpareThreads ¤ò + 5 ¤Ë¤·¤¿¾ì¹ç¤Ï¡¢ºÇ¾®¤Ç¤â 50 ¤Î¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤¬ + ¥·¥¹¥Æ¥à¾å¤Ë¤¢¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    worker, leader, + threadpool ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MinSpareThreads 75 ¤Ç¡¢ + ¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ò¥µ¡¼¥ÐÁ´ÂΤǴƻ뤷¤Þ¤¹¡£ + ¤â¤·¥µ¡¼¥Ð¤Ë½½Ê¬¤Ê¿ô¤Î¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤¬¤Ê¤±¤ì¤Ð¡¢ + ¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤¬¤³¤Î¿ô¤è¤ê¤âÂ礭¤¯¤Ê¤ë¤Þ¤Ç + ¿·¤·¤¤»Ò¥×¥í¥»¥¹¤¬À¸À®¤µ¤ì¤Þ¤¹¡£

    + +

    mpm_netware ¤Ç¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Ï MinSpareThreads 10 ¤Ç¡¢ + ¥·¥ó¥°¥ë¥×¥í¥»¥¹ MPM ¤Ç¤¹¤Î¤Ç¡¢¥µ¡¼¥ÐÁ´ÂΤǴÉÍý¤µ¤ì¤Þ¤¹¡£

    + +

    beos ¤È mpmt_os2 ¤Ï¡¢ + mpm_netware¤Ë¤è¤¯»÷¤Æ¤¤¤Þ¤¹¡£ + beos ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï MinSpareThreads 1 + ¤Ç¤¹¡£mpmt_os2 ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï + 5 ¤Ç¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    PidFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥Ç¡¼¥â¥ó¤Î¥×¥í¥»¥¹ ID +¤ò¥µ¡¼¥Ð¤¬µ­Ï¿¤¹¤ë¤¿¤á¤Î¥Õ¥¡¥¤¥ë
    ¹½Ê¸:PidFile filename
    ¥Ç¥Õ¥©¥ë¥È:PidFile logs/httpd.pid
    ¥³¥ó¥Æ¥­¥¹¥È:
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    PidFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¡¢ + ¥Ç¡¼¥â¥ó¤Î¥×¥í¥»¥¹ ID ¤ò¥µ¡¼¥Ð¤¬µ­Ï¿¤¹¤ë¥Õ¥¡¥¤¥ë¤òÀßÄꤷ¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë̾¤¬ÀäÂХѥ¹¤Ç¤Ê¤¤¾ì¹ç¤Ï¡¢ + ServerRoot + ¤«¤é¤ÎÁêÂÐŪ¤Ê¤â¤Î¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£

    + +

    Îã

    + PidFile /var/run/apache.pid +

    + +

    ¥µ¡¼¥Ð¤¬ ErrorLog + ¤ä TransferLog + ¤òÊĤ¸¤Æ³«¤­Ä¾¤·¤¿¤ê¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤ò + ºÆÆɹþ¤·¤¿¤ê¤µ¤»¤ë¤¿¤á¤Ë¡¢¥µ¡¼¥Ð¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤ë¤È + ÊØÍø¤Ê¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï SIGHUP (kill -1) ¥·¥°¥Ê¥ë¤ò PidFile + ¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¥×¥í¥»¥¹ ID ¤ËÁ÷¤ë¤³¤È¤Ç¤Ç¤­¤Þ¤¹¡£

    + +

    PidFile ¤Ë¤Ï¡¢¥í¥°¥Õ¥¡¥¤¥ë¤ÎÀßÃÖ°ÌÃÖ¤ä + ¥»¥­¥å¥ê¥Æ¥£ + ¤ÈÁ´¤¯Æ±¤¸Ãí°ÕÅÀ¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    Ãí°Õ

    +

    Apache 2 ¤Ç¤Ï¡¢ + apachectl + ¥¹¥¯¥ê¥×¥È¤Î¤ß¤ò»ÈÍѤ·¤Æ¥µ¡¼¥Ð¤Î (ºÆ) µ¯Æ°¤äÄä»ß¤ò + ¹Ô¤Ê¤¦¤³¤È¤ò¿ä¾©¤·¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    +
    top
    +

    ScoreBoardFile ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»Ò¥×¥í¥»¥¹¤ÈÏ¢·È¤¹¤ë¤¿¤á¤Î¥Ç¡¼¥¿¤òÊݸ¤¹¤ë +¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    ¹½Ê¸:ScoreBoardFile file-path
    ¥Ç¥Õ¥©¥ë¥È:ScoreBoardFile logs/apache_status
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_winnt, perchild, prefork, threadpool, worker
    +

    Apache ¤Ï¿Æ¥×¥í¥»¥¹¤È»Ò¥×¥í¥»¥¹´Ö¤ÎÄÌ¿®¤Ë¥¹¥³¥¢¥Ü¡¼¥É¤òÍѤ¤¤Þ¤¹¡£ + ¤³¤ÎÄÌ¿®µ¡Ç½¤Ë¥Õ¥¡¥¤¥ë¤òɬÍפȤ¹¤ë¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤â¤¢¤ê¤Þ¤¹¡£ + ¥Õ¥¡¥¤¥ë¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢Apache ¤Ï¤Þ¤º¥á¥â¥ê¾å + (ƿ̾¶¦Í­¥á¥â¥ê) ¤Ë¥¹¥³¥¢¥Ü¡¼¥É¤òºî¤í¤¦¤È¤·¡¢¤½¤ì¤¬¼ºÇÔ¤¹¤ë¤È + ¥Ç¥£¥¹¥¯¾å¤Ë¥Õ¥¡¥¤¥ë (¥Õ¥¡¥¤¥ë¥Ù¡¼¥¹¤Î¶¦Í­¥á¥â¥ê) ¤òºî¤í¤¦¤È¤·¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ØÄꤹ¤ë¤È¡¢Apache + ¤Ïɬ¤º¥Ç¥£¥¹¥¯¤Ë¥Õ¥¡¥¤¥ë¤òÀ¸À®¤·¤Þ¤¹¡£

    + +

    Îã

    + ScoreBoardFile /var/run/apache_status +

    + +

    ¥Õ¥¡¥¤¥ë¥Ù¡¼¥¹¤Î¶¦Í­¥á¥â¥ê¤Ï¡¢¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¡¼À½¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç + ¥¹¥³¥¢¥Ü¡¼¥É¤ËľÀÜ¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤ËÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +

    ScoreBoardFile ¤ò»È¤¦¾ì¹ç¡¢ + RAM ¥Ç¥£¥¹¥¯¾å¤ËÃÖ¤¯¤È¥¹¥Ô¡¼¥É¤¬¸þ¾å¤¹¤ë¤Ç¤·¤ç¤¦¡£ + ¤·¤«¤·¡¢¥í¥°¥Õ¥¡¥¤¥ë¤ÎÀßÃÖ°ÌÃÖ¤ä + ¥»¥­¥å¥ê¥Æ¥£ + ¤ÈƱÍͤÎÃí°ÕÅÀ¤¬¤¢¤ë¤Î¤Ç¡¢Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    »²¾È

    + +
    +
    top
    +

    SendBufferSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:TCP ¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º
    ¹½Ê¸:SendBufferSize bytes
    ¥Ç¥Õ¥©¥ë¥È:SendBufferSize 0
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, leader, mpm_netware, mpm_winnt, mpmt_os2, perchild, prefork, threadpool, worker
    +

    ¥µ¡¼¥Ð¤Ï TCP ¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º¤ò»ØÄꤵ¤ì¤¿¥Ð¥¤¥È¿ô¤ËÀßÄꤷ¤Þ¤¹¡£ + ¹â®¤Ç¹â¥ì¥¤¥Æ¥ó¥·¤Ê´Ä¶­¤Ç + (Îã 100ms ÄøÅÙ¡¢ÂçΦ²£Ãǹâ®ÄÌ¿®Ï©¤Ê¤É) + ¸Å¤¤°ìÈÌŪ¤Ê OS ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòÁý¤ä¤¹¤Î¤ËÈó¾ï¤ËÊØÍø¤Ç¤¹¡£

    + +

    0¤Ë¤·¤¿¾ì¹ç¡¢OS ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤ¬»ÈÍѤµ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    ServerLimit ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:ÀßÄê²Äǽ¤Ê¥µ¡¼¥Ð¥×¥í¥»¥¹¿ô¤Î¾å¸Â
    ¹½Ê¸:ServerLimit number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑË¡¤ò»²¾È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, perchild, prefork, threadpool, worker
    +

    prefork MPM ¤Î¾ì¹ç¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Apache ¥×¥í¥»¥¹²ÔƯÃæ¤Ë¤ª¤±¤ë + MaxClients + ¤ËÀßÄê²Äǽ¤Ê¾å¸ÂÃͤòÀßÄꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹ + (ÌõÃí: prefork ¤Î¾ì¹ç¤ÏƱ»þ¥¯¥é¥¤¥¢¥ó¥È¿ô = ¥µ¡¼¥Ð¥×¥í¥»¥¹¿ô¤Ê¤Î¤Ç) ¡£ + worker MPM ¤Î¾ì¹ç¤Ë¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ThreadLimit + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÈÁȤ߹ç¤ï¤»¤Æ¡¢ + Apache ¥×¥í¥»¥¹²ÔƯÃæ¤Ë¤ª¤±¤ë + MaxClients + ¤ËÀßÄê²Äǽ¤Ê¾å¸ÂÃͤòÀßÄꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ºÆµ¯Æ°Ãæ¤Ë¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÊѹ¹¤·¤Æ¤â̵»ë¤µ¤ì¤Þ¤¹¤¬¡¢ + MaxClients + ¤ÏºÆµ¯Æ°Ãæ¤Ë½¤Àµ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ëºÝ¤ÏÆäËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ServerLimit ¤¬É¬Íװʾå¤ËÂ礭¤ÊÃÍ¤Ë + ÀßÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢Í¾·×¤Ê̤»ÈÍѶ¦Í­¥á¥â¥ê¤¬³ä¤êÅö¤Æ¤é¤ì¤Þ¤¹¡£ + ServerLimit ¤È + MaxClients + ¤¬¥·¥¹¥Æ¥à¤Î°·¤¨¤ëÈϰϤò±Û¤¨¤¿ÀßÄêÃͤˤʤäƤ¤¤ë¤È¡¢ + Apache ¤Ïµ¯Æ°¤·¤Ê¤¤¤«¡¢µ¯Æ°¤·¤Æ¤âÉÔ°ÂÄê¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    + +

    prefork MPM ¤Ç¤Ï¡¢ + MaxClients + ¤ò 256 (¥Ç¥Õ¥©¥ë¥È) ¤è¤ê¤âÂ礭¤ÊÃͤËÀßÄꤹ¤ëɬÍפ¬¤¢¤ë»þ¤Ë¤À¤±»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£ + ´õ˾¤Î MaxClients + ¿ô¤È¤¯¤é¤Ù¤Æ¡¢É¬Íװʾå¤ËÂ礭¤ÊÃͤò»ØÄꤹ¤ë¤³¤È¤ÏÈò¤±¤Æ¤¯¤À¤µ¤¤¡£

    + +

    worker, leader, + threadpool MPM ¤Ç¤Ï¡¢ + MaxClients ¤È + ThreadsPerChild + ¤ÎÀßÄê¤Ç 16 ¥µ¡¼¥Ð¥×¥í¥»¥¹ (¥Ç¥Õ¥©¥ë¥È) + °Ê¾åɬÍפˤʤë¾ì¹ç¤Ë¤Î¤ß»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£´õ˾¤Î + MaxClients ¤È + ThreadsPerChild + ¤È¤¯¤é¤Ù¤Æ¡¢É¬ÍפȤʤ륵¡¼¥Ð¥×¥í¥»¥¹¿ô°Ê¾å¤ËÂ礭¤ÊÃͤò + ÀßÄꤹ¤ë¤³¤È¤ÏÈò¤±¤Æ¤¯¤À¤µ¤¤¡£

    + +

    perchild MPM ¤Ç¤Ï¡¢ + NumServers ¤ò 8 (¥Ç¥Õ¥©¥ë¥È) + ¤è¤í¤¤¤âÂ礭¤ÊÃͤËÀßÄꤹ¤ëɬÍפ¬¤¢¤ë¤È¤­¤Ë¤Î¤ß»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãí°Õ

    +

    ServerLimit 20000 ¤È¤¤¤¦À©¸ÂÉÕ¤­¤Ç¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤Þ¤¹ + (prefork MPM ¤Ç¤Ï 200000) ¡£ + ¤³¤ì¤Ï¥¹¥Ú¥ë¥ß¥¹¤Ë¤è¤Ã¤Æ¸í¤Ã¤Æ¹ó¤¤¾õ¶·¤Ë¤Ê¤ë¤Î¤ò¡¢ + ²óÈò¤¹¤ë¤¿¤á¤Î½èÃ֤Ǥ¹¡£

    +
    + +

    »²¾È

    + +
    +
    top
    +

    StartServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î¿ô
    ¹½Ê¸:StartServers number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑÊýË¡¤ò»²¾È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, mpmt_os2, prefork, threadpool, worker
    +

    StartServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î¿ô¤òÀßÄꤷ¤Þ¤¹¡£ + ¥×¥í¥»¥¹¿ô¤ÏÉé²Ù¤Ë±þ¤¸¤ÆưŪ¤ËÀ©¸æ¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + Ä̾ï¤Ï¤³¤ÎÃͤòÄ´À°¤¹¤ëÍýͳ¤Ï¤¢¤Þ¤ê¤Ê¤¤¤Ç¤·¤ç¤¦¡£

    + +

    ¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï MPM ¤´¤È¤Ë°Û¤Ê¤ê¤Þ¤¹¡£ + leader, threadpool, + worker ¤Ï StartServers 3 ¤Ç¤¹¡£ + prefork ¤Ï 5 ¤Ç¡¢ + mpmt_os2 ¤Ï 2 ¤Ç¤¹¡£

    + +
    +
    top
    +

    StartThreads ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¤Î¿ô
    ¹½Ê¸:StartThreads number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑÊýË¡¤ò»²¾È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:beos, mpm_netware, perchild
    +

    µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¤Î¿ô¤Ç¤¹¡£ + ¥¹¥ì¥Ã¥É¿ô¤ÏÉé²Ù¤Ë±þ¤¸¤ÆưŪ¤ËÀ©¸æ¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ + Ä̾ï¤Ï¤³¤ÎÃͤòÄ´À°¤¹¤ëÍýͳ¤Ï¤¢¤Þ¤ê¤Ê¤¤¤Ç¤·¤ç¤¦¡£

    + +

    perchild ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï + StartThreads 5 ¤Ç¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïµ¯Æ°»þ¤Ë + ¥×¥í¥»¥¹Ëè¤Î¥¹¥ì¥Ã¥É¿ô¤òÄÉÀפ·¤Þ¤¹¡£

    + +

    mpm_netware ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï + StartThreads 50 ¤Ç¡¢ + ¤³¤Î¾ì¹ç¥×¥í¥»¥¹¤Ï°ì¤Ä¤·¤«¤Ê¤¤¤Î¤Ç¡¢ + µ¯Æ°»þ¤Ë¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¥¹¥ì¥Ã¥É¤ÎÁí¿ô¤È¤Ê¤ê¤Þ¤¹¡£

    + +

    beos ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï StartThreads + 10 ¤Ç¤¹¡£ + ¤Þ¤¿¡¢µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¤ÎÁí¿ô¤Ë¤âÈ¿±Ç¤µ¤ì¤Þ¤¹¡£

    + +
    +
    top
    +

    ThreadLimit ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:ÀßÄê²Äǽ¤Ê»Ò¥×¥í¥»¥¹Ëè¤Î¥¹¥ì¥Ã¥É¿ô¤Î¾å¸Â¤ò +ÀßÄꤷ¤Þ¤¹
    ¹½Ê¸:ThreadLimit number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑÊýË¡¤ò»²¾È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, mpm_winnt, perchild, threadpool, worker
    ¸ß´¹À­:Apache 2.0.41 ¤È¤½¤ì°Ê¹ß¤Î mpm_winnt +¤ÇÍøÍѲÄǽ
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Apache ¥×¥í¥»¥¹²ÔƯÃæ¤Ë¤ª¤±¤ë + ThreadsPerChild + ¤ËÀßÄê²Äǽ¤Ê¾å¸ÂÃͤòÀßÄꤷ¤Þ¤¹¡£ºÆµ¯Æ°»þ¤Ë¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤò + Êѹ¹¤·¤Æ¤â̵»ë¤µ¤ì¤Þ¤¹¤¬¡¢ + ThreadsPerChild + ¤ÏºÆµ¯Æ°Ãæ¤Ë¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿¾å¸ÂÃÍ¤Þ¤Ç + Êѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ëºÝ¤ÏÆäËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ThreadLimit ¤¬ + ThreadsPerChild + ¤è¤ê¤â¤º¤Ã¤ÈÂ礭¤ÊÃͤËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ï¡¢ + ;·×¤Ê̤»ÈÍѶ¦Í­¥á¥â¥ê¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤·¤Þ¤¤¤Þ¤¹¡£ + ThreadLimit ¤¬ + ThreadsPerChild + ¤ÎξÊý¤¬¥·¥¹¥Æ¥à¤Î°·¤¨¤ëÈϰϤòĶ¤¨¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + Apache ¤Ïµ¯Æ°¤·¤Ê¤¤¤«¡¢µ¯Æ°¤·¤¿¤È¤·¤Æ¤âÉÔ°ÂÄê¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤϺ£»ÈÍѤ·¤Æ¤¤¤ë Apache ¤Î ThreadsPerChild ¤ÎͽÁÛ¾å¸ÂÃͤò + Ķ¤¨¤¿ÃͤˤÏÀßÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£ +

    + +

    ThreadLimit ¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï + mpm_winnt ¤Î¤È¤­¤Ï 1920 ¤Ç¡¢ + ¾¤Î¾ì¹ç¤Ï 64 ¤Ç¤¹¡£

    + +

    Ãí°Õ

    +

    ThreadLimit 20000 (mpm_winnt + ¤Î¾ì¹ç¤Ï ThreadLimit 15000 ) + ¤È¤¤¤¦À©¸ÂÉÕ¤­¤Ç¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤Ï¥¹¥Ú¥ë¥ß¥¹¤Ë¤è¤Ã¤Æ¸í¤Ã¤Æ¹ó¤¤¾õ¶·¤Ë¤Ê¤ë¤Î¤ò¡¢ + ²óÈò¤¹¤ë¤¿¤á¤Î½èÃ֤Ǥ¹¡£

    +
    + +
    +
    top
    +

    ThreadsPerChild ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:»Ò¥×¥í¥»¥¹¤½¤ì¤¾¤ì¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¿ô
    ¹½Ê¸:ThreadsPerChild number
    ¥Ç¥Õ¥©¥ë¥È:¾ÜºÙ¤Ï»ÈÍÑÊýË¡¤ò»²¾È
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, mpm_winnt, threadpool, worker
    +

    ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¤½¤ì¤¾¤ì¤Î»Ò¥×¥í¥»¥¹¤ÇÀ¸À®¤µ¤ì¤ë + ¥¹¥ì¥Ã¥É¿ô¤òÀßÄꤷ¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤Ï³«»Ï»þ¤Ë¤³¤ì¤é¤Î¥¹¥ì¥Ã¥É¤òÀ¸À®¤·¤Æ¡¢ + ¤½¤Î¸å¤ÏÀ¸À®¤·¤Þ¤»¤ó¡£mpm_winnt ¤Î¤è¤¦¤Ê¡¢ + »Ò¥×¥í¥»¥¹¤¬°ì¤Ä¤·¤«¤Ê¤¤¤è¤¦¤Ê MPM ¤òÍøÍѤ·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¤³¤ÎÃͤϥµ¡¼¥Ð¤ÎÉé²ÙÁ´ÂΤò½½Ê¬¼è¤ê°·¤¨¤ëÄøÅ٤ˡ¢ + Â礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£worker ¤Î¤è¤¦¤Ê¡¢ + »Ò¥×¥í¥»¥¹¤¬Ê£¿ô¤¢¤ë¤è¤¦¤Ê MPM ¤òÍøÍѤ·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¥µ¡¼¥Ð¤ÎÄ̾ïÉé²Ù¤ò½½Ê¬°·¤¨¤ëÄøÅ٤ˡ¢ + ¥¹¥ì¥Ã¥ÉÁí¿ô¤¬Â¿¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    mpm_winnt¤Ç¤Î ThreadsPerChild + ¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 64 ¤Ç¡¢Â¾¤Î¾ì¹ç¤Ï + 25 ¤Ç¤¹¡£

    + +
    +
    top
    +

    ThreadStackSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥¯¥é¥¤¥¢¥ó¥È¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±»ý¤Ä¥¹¥ì¥Ã¥É¤¬»ÈÍѤ¹¤ë +¥¹¥¿¥Ã¥¯¤Î¥Ð¥¤¥È¿ô
    ¹½Ê¸:ThreadStackSize size
    ¥Ç¥Õ¥©¥ë¥È:NetWare ¤Ç¤Ï 65536¡£Â¾¤Î OS ¤Ç¤Ï°ã¤Ã¤¿ÃÍ
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, mpm_netware, mpm_winnt, perchild, threadpool, worker
    ¸ß´¹À­:2.1 °Ê¹ß
    +

    ¥¯¥é¥¤¥¢¥ó¥È¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±»ý¤Á¡¢¥³¥Í¥¯¥·¥ç¥ó½èÍý¤ËɬÍפʥ⥸¥å¡¼¥ë¤Î + ¸Æ¤Ó½Ð¤·¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤ë¥¹¥ì¥Ã¥É¤Î¡¢(¼«Æ°ÊÑ¿ôÍѤÎ) ¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤Ï + ThreadStackSize ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤷ¤Þ¤¹¡£ + ÂçÄñ¤Î¾ì¹ç OS ¤Î»ØÄꤷ¤Æ¤¤¤ë¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï + ŬÀڤʤâ¤Î¤Ç¤¹¤¬¡¢Ä´À°¤¬É¬Íפˤʤë¾ì¹ç¤â¤¢¤ê¤Þ¤¹:

    + +
      +
    • ¥¹¥ì¥Ã¥É¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤ¬Èæ³ÓŪ¾®¤µ¤¯ÀßÄꤵ¤ì¤Æ¤¤¤ë + ¥×¥é¥Ã¥È¥Û¡¼¥à (Î㤨¤Ð HP-UX) ¤Ç¤Ï¡¢¼«Æ°ÊÑ¿ôÍѤÎÎΰè¤ÇÂ礭¤ÊÍÆÎ̤ò + »ÈÍѤ¹¤ë¥µ¡¼¥É¥Ñ¡¼¥Æ¥£À½¥â¥¸¥å¡¼¥ë¤Î¤¿¤á¤Ë Apache ¤¬¥¯¥é¥Ã¥·¥å¤¹¤ë + ¾ì¹ç¤â¤¢¤ê¤Þ¤¹¡£¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¾¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Ï + ¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤¬Â礭¤¤¤¿¤á¤Ë¡¢²÷Ä´¤ËÆ°ºî¤¹¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤³¤Î¥¿¥¤¥×¤Î¥¯¥é¥Ã¥·¥å¤Ï¡¢ThreadStackSize + ¤Ç OS ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤè¤êÂ礭¤ÊÃͤò»ØÄꤹ¤ë¤³¤È¤Ç²ò·è¤·¤Þ¤¹¡£ + ¥µ¡¼¥É¥Ñ¡¼¥Æ¥£À½¥â¥¸¥å¡¼¥ë¤Ç¤³¤Î½èÃÖ¤¬É¬ÍפǤ¢¤ë¤Èµ­ºÜ¤µ¤ì¤Æ¤¤¤ë + ¾ì¹ç¤«¡¢Apache ¤Î½ÐÎϤ¹¤ë¥á¥Ã¥»¡¼¥¸¤Ç¥¹¥ì¥Ã¥É¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤¬ + ¾®¤µ¤¹¤®¤ë¤È»ØŦ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ë¤Î¤ß¡¢¤³¤ÎÄ´À°¤ò¤·¤Æ¤¯¤À¤µ¤¤¡£
    • + +
    • ¥Ç¥Õ¥©¥ë¥È¥¹¥ì¥Ã¥É¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤¬¡¢Web ¥µ¡¼¥ÐÍÑÅÓ¤ËɬÍפÊÎ̤è¤ê¤â + ÌÀ¤é¤«¤ËÂ礭¤¹¤®¤ë¾ì¹ç¡¢ThreadStackSize + ¤ò OS ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤè¤ê¤â¾®¤µ¤ÊÃͤˤ¹¤ë¤³¤È¤Ç¡¢»Ò¥×¥í¥»¥¹¤¢¤¿¤ê¤Î + ¥¹¥ì¥Ã¥É¿ô¤ò¤è¤ê¿¤¯»ý¤¿¤»¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤³¤Î¥¿¥¤¥×¤ÎÄ´À°¤Ï¡¢¥Æ¥¹¥È´Ä¶­¤Ç¥¦¥§¥Ö¥µ¡¼¥Ð¤ò´°Á´¤Ë + ¥Æ¥¹¥È¤Ç¤­¤ë¾ì¹ç¤Ë¸Â¤Ã¤Æ¹Ô¤Ê¤¦¤Ù¤­¤Ç¤¹¡£ + ¤Þ¤ì¤Ë¿¿ô¤Î¥¹¥¿¥Ã¥¯¤¬Í׵ᤵ¤ì¤ë¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¤ë¤³¤È¤¬¤¢¤ë¤«¤â + ¤·¤ì¤Ê¤¤¤«¤é¤Ç¤¹¡£ + Web ¥µ¡¼¥Ð¤ÎÀßÄê¤òÊѹ¹¤¹¤ë¤È¡¢¸½ºß¤Î ThreadStackSize + ¤ÎÀßÄ꤬¼è¤ê¾Ã¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    + +
    +
    top
    +

    User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤ËÍѤ¤¤ë¥æ¡¼¥¶ ID
    ¹½Ê¸:User unix-userid
    ¥Ç¥Õ¥©¥ë¥È:User #-1
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:leader, perchild, prefork, threadpool, worker
    ¸ß´¹À­:Apache 2.0 °Ê¹ß¤Ç¡¢¥°¥í¡¼¥Ð¥ëÀßÄê¤Ç¤Î¤ßÍ­¸ú¤Ç¤¹¡£ +
    +

    User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥µ¡¼¥Ð¤¬¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤ËÍѤ¤¤ë¥æ¡¼¥¶ ID ¤òÀßÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¢¥¹¥¿¥ó¥É¥¢¥í¥ó·¿¤Î + ¥µ¡¼¥Ð¤ÏºÇ½é¤Ë root ¸¢¸Â¤Çµ¯Æ°¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + Èó root ¥æ¡¼¥¶¤Ç¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿¾ì¹ç¤Ï¡¢ + ¸¢¸Â¤ÎÄ㤤¥æ¡¼¥¶¤Ø¤ÈÊѤï¤ë¤³¤È¤¬¤Ç¤­¤º¡¢ + ·ë¶É¸µ¤Î¥æ¡¼¥¶¤Î¥×¥í¥»¥¹¤È¤·¤Æ¼Â¹Ô¤µ¤ì³¤±¤Þ¤¹¡£ + root ¤Çµ¯Æ°¤·¤¿¾ì¹ç¤Ë¿Æ¥×¥í¥»¥¹¤¬ root + ¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¤Î¤ÏÀµ¾ï¤ÊÆ°ºî¤Ç¤¹¡£ + Unix-userid ¤Ï¼¡¤Î¤É¤ì¤«¤Ç¤¹¡£

    + +
    +
    ¥æ¡¼¥¶Ì¾
    +
    ¥æ¡¼¥¶¤ò̾Á°¤Ç»²¾È¤·¤Þ¤¹¡£
    + +
    # ¤Ë³¤¤¤Æ¥æ¡¼¥¶ÈÖ¹æ
    +
    ¥æ¡¼¥¶¤òÈÖ¹æ¤Ç»²¾È¤·¤Þ¤¹¡£
    +
    + +

    ¤³¤Î¥æ¡¼¥¶¤Ï¡¢³°Éô¤Ë¸«¤»¤ë¤è¤¦¤Ë°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤¥Õ¥¡¥¤¥ë¤Ë¡¢ + ¥¢¥¯¥»¥¹²Äǽ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤è¤¦¤Ê¸¢¸Â¤ò»ý¤Ä¤Ù¤­¤Ç¤Ï¤Ê¤¤¤Ç¤¹¤·¡¢ + ƱÍÍ¤Ë HTTP ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ±þÅú¤¹¤ë¤è¤¦¤Ë°Õ¿Þ¤·¤Æ¤¤¤Ê¤¤ + ¼Â¹Ô¥³¡¼¥É¤ò¡¢¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ê¸¢¸Â¤ò»ý¤Ä¤Ù¤­¤Ç¤Ï¤Ê¤¤¤Ç¤¹¡£ + ¥µ¡¼¥Ð¤ò¼Â¹Ô¤¹¤ë¤¿¤á¤ËÆÃÄê¤Î¿·¤·¤¤¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤ò + ÀßÄꤹ¤ë¤³¤È¤ò¤ªÁ¦¤á¤¤¤¿¤·¤Þ¤¹¡£ + nobody ¥æ¡¼¥¶¤ò»ÈÍѤ¹¤ë´ÉÍý¼Ô¤â¤¤¤Þ¤¹¤¬¡¢ + ¤³¤ì¤¬¾ï¤Ë˾¤Þ¤·¤¤¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤Ê¤¼¤Ê¤é nobody ¥æ¡¼¥¶¤Ï¡¢¥·¥¹¥Æ¥à¤Ç + ¾¤ÎÌò³ä¤òô¤Ã¤Æ¤¤¤ë¤«¤âÃΤì¤Ê¤¤¤«¤é¤Ç¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£

    +

    Àµ³Î¤Ë¤É¤ó¤Ê¤³¤È¤ò¤ä¤Ã¤Æ¤¤¤ë¤Î¤«¡¢¤½¤Î´í¸±À­¤òÃΤé¤Ê¤¤¤Ç¡¢ + User (¤ä Group) ¤ò root ¤Ë + ÀßÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£

    +
    + +

    perchild MPM ¤Ç¤Ï¡¢°Û¤Ê¤ë¥æ¡¼¥¶ ID + ¤ÇÊ£¿ô¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÆ°¤«¤¹¤³¤È¤òÌÜŪ¤È¤·¤Æ¤¤¤Þ¤¹¤¬¡¢ + User ¤Ï¡¢¼ç¥µ¡¼¥Ð¤Î¥æ¡¼¥¶ ID + ¤È¡¢AssignUserID + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ý¤¿¤Ê¤¤ <VirtualHost> ¥»¥¯¥·¥ç¥ó¤Ø¤Î + ¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¤È¤òÄêµÁ¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Æõ­»ö¹à: ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + <VirtualHost> + ¤Ç»ÈÍѤ¹¤ë¤³¤È¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Ê¤¯¤Ê¤ê¤Þ¤·¤¿¡£ + suexec ¸þ¤±¤Ë¥µ¡¼¥Ð¤òÀßÄꤹ¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + SuexecUserGroup + ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãí°Õ

    +

    User ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + beos ¤È mpmt_os2 MPM + ¤Ë¤â¸ºß¤·¤Þ¤¹¤¬¡¢¼Â¼ÁŪ¤Ë̵¸ú¤Ç¡¢¸ß´¹À­¤Î¤¿¤á¤À¤±¤Ë¸ºß¤·¤Þ¤¹¡£

    +
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_common.xml b/trunk/docs/manual/mod/mpm_common.xml new file mode 100644 index 0000000000..8bca7bbf10 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.xml @@ -0,0 +1,949 @@ + + + + + + + + + +mpm_common +A collection of directives that are implemented by +more than one multi-processing module (MPM) +MPM + + +AcceptMutex +Method that Apache uses to serialize multiple children +accepting requests on network sockets +AcceptMutex Default|method +AcceptMutex Default +server config +leaderperchild +preforkthreadpoolworker + + + +

    The AcceptMutex directives sets the + method that Apache uses to serialize multiple children accepting + requests on network sockets. Prior to Apache 2.0, the method was + selectable only at compile time. The optimal method to use is + highly architecture and platform dependent. For further details, + see the performance tuning + documentation.

    + +

    If this directive is set to Default, then the + compile-time selected default will be used. Other possible + methods are listed below. Note that not all methods are + available on all platforms. If a method is specified which is + not available, a message will be written to the error log + listing the available methods.

    + +
    +
    flock
    +
    uses the flock(2) system call to lock the + file defined by the LockFile directive.
    + +
    fcntl
    +
    uses the fcntl(2) system call to lock the + file defined by the LockFile directive.
    + +
    posixsem
    +
    uses POSIX compatible semaphores to implement the mutex.
    + +
    pthread
    +
    uses POSIX mutexes as implemented by the POSIX Threads + (PThreads) specification.
    + +
    sysvsem
    +
    uses SySV-style semaphores to implement the mutex.
    +
    + +

    If you want to find out the compile time chosen default + for your system, you may set your LogLevel to debug. Then the default AcceptMutex will be written into the ErrorLog.

    + + Warning +

    On most systems, when the pthread option + is selected, if a child process terminates abnormally + while holding the AcceptCntl mutex the + server will stop responding to requests. When this + occurs, the server will require a manual restart to + recover.

    +

    Solaris is a notable exception as it provides a + mechanism, used by Apache, which usually allows the + mutex to be recovered after a child process terminates + abnormally while holding a mutex.

    +

    If your system implements the + pthread_mutexattr_setrobust_np() function, + you may be able to use the pthread option safely.

    +
    +
    +
    + + +CoreDumpDirectory +Directory where Apache attempts to +switch before dumping core +CoreDumpDirectory directory +See usage for the default setting +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    This controls the directory to which Apache attempts to + switch before dumping core. The default is in the + ServerRoot directory, however + since this should not be writable by the user the server runs + as, core dumps won't normally get written. If you want a core + dump for debugging, you can use this directive to place it in a + different location.

    + + Core Dumps on Linux +

    If Apache starts as root and switches to another user, the + Linux kernel disables core dumps even if the directory is + writable for the process. Apache (2.0.46 and later) reenables core dumps + on Linux 2.4 and beyond, but only if you explicitly configure a CoreDumpDirectory.

    +
    +
    +
    + + +EnableExceptionHook +Enables a hook that runs exception handlers +after a crash +EnableExceptionHook On|Off +EnableExceptionHook Off +server config +leaderperchild +preforkthreadpool +worker +Available in version 2.0.49 and later + + +

    For safety reasons this directive is only available if the server was + configured with the --enable-exception-hook option. It + enables a hook that allows external modules to plug in and do something + after a child crashed.

    + +

    There are already two modules, mod_whatkilledus and + mod_backtrace that make use of this hook. Please have a + look at Jeff Trawick's EnableExceptionHook site for more information about these.

    +
    +
    + + +Group +Group under which the server will answer +requests +Group unix-group +Group #-1 +server config +beosleader +mpmt_os2perchildprefork +threadpoolworker +Only valid in global server config since Apache +2.0 + + +

    The Group directive sets the group under + which the server will answer requests. In order to use this + directive, the server must be run initially as root. If + you start the server as a non-root user, it will fail to change to the + specified group, and will instead continue to run as the group of the + original user. Unix-group is one of:

    + +
    +
    A group name
    +
    Refers to the given group by name.
    + +
    # followed by a group number.
    +
    Refers to a group by its number.
    +
    + + Example + Group www-group + + +

    It is recommended that you set up a new group specifically for + running the server. Some admins use user nobody, + but this is not always possible or desirable.

    + + Security +

    Don't set Group (or User) to root unless + you know exactly what you are doing, and what the dangers are.

    +
    + +

    Special note: Use of this directive in VirtualHost is no longer supported. To + configure your server for suexec use + SuexecUserGroup.

    + + Note +

    Although the Group directive is present + in the beos and mpmt_os2 MPMs, + it is actually a no-op there and only exists for compatibility + reasons.

    +
    +
    +
    + + +PidFile +File where the server records the process ID +of the daemon +PidFile filename +PidFile logs/httpd.pid +server config +beosleader +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    The PidFile directive sets the file to + which the server records the process id of the daemon. If the + filename is not absolute then it is assumed to be relative to the + ServerRoot.

    + + Example + PidFile /var/run/apache.pid + + +

    It is often useful to be able to send the server a signal, + so that it closes and then re-opens its ErrorLog and TransferLog, and + re-reads its configuration files. This is done by sending a + SIGHUP (kill -1) signal to the process id listed in the + PidFile.

    + +

    The PidFile is subject to the same + warnings about log file placement and security.

    + + Note +

    As of Apache 2 it is recommended to use only the + apachectl script for (re-)starting or stopping the server.

    +
    +
    +
    + + +Listen +IP addresses and ports that the server +listens to +Listen [IP-address:]portnumber +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchild +preforkthreadpoolworker + +Required directive since Apache 2.0 + + +

    The Listen directive instructs Apache to + listen to only specific IP addresses or ports; by default it + responds to requests on all IP interfaces. Listen + is now a required directive. If it is not in the config file, the + server will fail to start. This is a change from previous versions + of Apache.

    + +

    The Listen directive tells the server to + accept incoming requests on the specified port or address-and-port + combination. If only a port number is specified, the server listens to + the given port on all interfaces. If an IP address is given as well + as a port, the server will listen on the given port and + interface.

    + +

    Multiple Listen directives may be used to + specify a number of addresses and ports to listen to. The server will + respond to requests from any of the listed addresses and ports.

    + +

    For example, to make the server accept connections on both + port 80 and port 8000, use:

    + + + Listen 80
    + Listen 8000 +
    + +

    To make the server accept connections on two specified + interfaces and port numbers, use

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6 addresses must be surrounded in square brackets, as in the + following example:

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + + + Error condition + Multiple Listen directives for the same ip + address and port will result in an Address already in use + error message. + +
    +DNS Issues +Setting which addresses and ports Apache + uses +
    + + +ListenBackLog +Maximum length of the queue of pending connections +ListenBacklog backlog +ListenBacklog 511 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    The maximum length of the queue of pending connections. + Generally no tuning is needed or desired, however on some + systems it is desirable to increase this when under a TCP SYN + flood attack. See the backlog parameter to the + listen(2) system call.

    + +

    This will often be limited to a smaller number by the + operating system. This varies from OS to OS. Also note that + many OSes do not use exactly what is specified as the backlog, + but use a number based on (but normally larger than) what is + set.

    +
    +
    + + +LockFile +Location of the accept serialization lock file +LockFile filename +LockFile logs/accept.lock +server config +leaderperchild +preforkthreadpoolworker + + + +

    The LockFile directive sets the path to + the lockfile used when Apache is used with an AcceptMutex value of either + fcntl or flock. This directive should + normally be left at its default value. The main reason for changing + it is if the logs directory is NFS mounted, since + the lockfile must be stored on a local disk. The PID + of the main server process is automatically appended to the + filename.

    + + Security +

    It is best to avoid putting this file in a world writable + directory such as /var/tmp because someone could create + a denial of service attack and prevent the server from starting by + creating a lockfile with the same name as the one the server will try + to create.

    +
    +
    +AcceptMutex +
    + + +MaxClients +Maximum number of child processes that will be created +to serve requests +MaxClients number +See usage for details +server config +beosleader +preforkthreadpoolworker + + + +

    The MaxClients directive sets the limit + on the number of simultaneous requests that will be served. Any + connection attempts over the MaxClients + limit will normally be queued, up to a number based on the + ListenBacklog + directive. Once a child process is freed at the end of a different + request, the connection will then be serviced.

    + +

    For non-threaded servers (i.e., prefork), + MaxClients translates into the maximum + number of child processes that will be launched to serve requests. + The default value is 256; to increase it, you must also raise + ServerLimit.

    + +

    For threaded and hybrid servers (e.g. beos + or worker) MaxClients restricts + the total number of threads that will be available to serve clients. + The default value for beos is 50. For + hybrid MPMs the default value is 16 (ServerLimit) multiplied by the value of + 25 (ThreadsPerChild). Therefore, to increase MaxClients to a value that requires more than 16 processes, + you must also raise ServerLimit.

    +
    +
    + + +MaxMemFree +Maximum amount of memory that the main allocator is allowed +to hold without calling free() +MaxMemFree KBytes +MaxMemFree 0 +server config +beosleader +mpm_netwareprefork +threadpoolworkermpm_winnt + + +

    The MaxMemFree directive sets the + maximum number of free Kbytes that the main allocator is allowed + to hold without calling free(). When not set, or when set + to zero, the threshold will be set to unlimited.

    +
    +
    + + +MaxRequestsPerChild +Limit on the number of requests that an individual child server +will handle during its life +MaxRequestsPerChild number +MaxRequestsPerChild 10000 +server config +leadermpm_netware +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    The MaxRequestsPerChild directive sets + the limit on the number of requests that an individual child + server process will handle. After + MaxRequestsPerChild requests, the child + process will die. If MaxRequestsPerChild is + 0, then the process will never expire.

    + + Different default values +

    The default value for mpm_netware and + mpm_winnt is 0.

    +
    + +

    Setting MaxRequestsPerChild to a + non-zero limit has two beneficial effects:

    + +
      +
    • it limits the amount of memory that process can consume + by (accidental) memory leakage;
    • + +
    • by giving processes a finite lifetime, it helps reduce + the number of processes when the server load reduces.
    • +
    + + Note +

    For KeepAlive requests, only + the first request is counted towards this limit. In effect, it + changes the behavior to limit the number of connections per + child.

    +
    +
    +
    + + +MaxSpareThreads +Maximum number of idle threads +MaxSpareThreads number +See usage for details +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    Maximum number of idle threads. Different MPMs deal with this + directive differently.

    + +

    For perchild the default is + MaxSpareThreads 10. This MPM monitors the number of + idle threads on a per-child basis. If there are too many idle + threads in that child, the server will begin to kill threads + within that child.

    + +

    For worker, leader and threadpool the default is MaxSpareThreads 250. + These MPMs deal with idle threads on a server-wide basis. If there + are too many idle threads in the server then child processes are + killed until the number of idle threads is less than this number.

    + +

    For mpm_netware the default is + MaxSpareThreads 100. Since this MPM runs a + single-process, the spare thread count is also server-wide.

    + +

    beos and mpmt_os2 work + similar to mpm_netware. The default for + beos is MaxSpareThreads 50. For + mpmt_os2 the default value is 10.

    + + Restrictions +

    The range of the MaxSpareThreads value + is restricted. Apache will correct the given value automatically + according to the following rules:

    +
      +
    • perchild requires MaxSpareThreads to be less or equal than ThreadLimit.
    • + +
    • mpm_netware wants the value to be greater than + MinSpareThreads.
    • + +
    • For leader, threadpool and + worker the value must be greater or equal than + the sum of MinSpareThreads + and ThreadsPerChild.
    • +
    +
    +
    +MinSpareThreads +StartServers +
    + + +MinSpareThreads +Minimum number of idle threads available to handle request +spikes +MinSpareThreads number +See usage for details +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    Minimum number of idle threads to handle request spikes. + Different MPMs deal with this directive + differently.

    + +

    perchild uses a default of + MinSpareThreads 5 and monitors the number of idle + threads on a per-child basis. If there aren't enough idle threads + in that child, the server will begin to create new threads within + that child. Thus, if you set NumServers to 10 and a MinSpareThreads value of 5, you'll have + at least 50 idle threads on your system.

    + +

    worker, leader and + threadpool use a default of MinSpareThreads + 75 and deal with idle threads on a server-wide basis. If + there aren't enough idle threads in the server then child + processes are created until the number of idle threads is greater + than number.

    + +

    mpm_netware uses a default of + MinSpareThreads 10 and, since it is a single-process + MPM, tracks this on a server-wide bases.

    + +

    beos and mpmt_os2 work + similar to mpm_netware. The default for + beos is MinSpareThreads 1. For + mpmt_os2 the default value is 5.

    +
    +MaxSpareThreads +StartServers +
    + + +ScoreBoardFile +Location of the file used to store coordination data for +the child processes +ScoreBoardFile file-path +ScoreBoardFile logs/apache_status +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    Apache uses a scoreboard to communicate between its parent + and child processes. Some architectures require a file to facilitate + this communication. If the file is left unspecified, Apache first + attempts to create the scoreboard entirely in memory (using anonymous + shared memory) and, failing that, will attempt to create the file on + disk (using file-based shared memory). Specifying this directive causes + Apache to always create the file on the disk.

    + + Example + ScoreBoardFile /var/run/apache_status + + +

    File-based shared memory is useful for third-party applications + that require direct access to the scoreboard.

    + +

    If you use a ScoreBoardFile then + you may see improved speed by placing it on a RAM disk. But be + careful that you heed the same warnings about log file placement + and security.

    +
    +Stopping and Restarting +Apache +
    + + +SendBufferSize +TCP buffer size +SendBufferSize bytes +SendBufferSize 0 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    The server will set the TCP buffer size to the number of bytes + specified. Very useful to increase past standard OS defaults on + high speed high latency (i.e., 100ms or so, such as + transcontinental fast pipes).

    + +

    If set to the value of 0, the server will use the + OS deault.

    +
    +
    + + +ServerLimit +Upper limit on configurable number of processes +ServerLimit number +See usage for details +server config +leaderperchild +preforkthreadpoolworker + + + +

    For the prefork MPM, this directive sets the + maximum configured value for MaxClients for the lifetime of the + Apache process. For the worker MPM, this directive + in combination with ThreadLimit sets + the maximum configured value for MaxClients for the lifetime of the + Apache process. Any attempts to change this directive during a + restart will be ignored, but MaxClients can be modified during + a restart.

    + +

    Special care must be taken when using this directive. If + ServerLimit is set to a value much higher + than necessary, extra, unused shared memory will be allocated. If + both ServerLimit and MaxClients are set to values + higher than the system can handle, Apache may not start or the + system may become unstable.

    + +

    With the prefork MPM, use this directive only + if you need to set MaxClients higher than 256 (default). + Do not set the value of this directive any higher than what you + might want to set MaxClients to.

    + +

    With worker, leader and + threadpool use this directive only + if your MaxClients and + ThreadsPerChild + settings require more than 16 server processes (default). Do not set + the value of this directive any higher than the number of server + processes required by what you may want for MaxClients and ThreadsPerChild.

    + +

    With the perchild MPM, use this directive only + if you need to set NumServers higher than 8 (default).

    + + Note +

    There is a hard limit of ServerLimit 20000 compiled + into the server (for the prefork MPM 200000). This is + intended to avoid nasty effects caused by typos.

    +
    +
    +Stopping and Restarting Apache +
    + + +StartServers +Number of child server processes created at startup +StartServers number +See usage for details +server config +leadermpmt_os2 +preforkthreadpoolworker + + + +

    The StartServers directive sets the + number of child server processes created on startup. As the number + of processes is dynamically controlled depending on the load, + there is usually little reason to adjust this parameter.

    + +

    The default value differs from MPM to MPM. For + leader, threadpool and + worker the default is StartServers 3. + For prefork defaults to 5 and for + mpmt_os2 to 2.

    +
    +
    + + +StartThreads +Number of threads created on startup +StartThreads number +See usage for details +server config +beosmpm_netware +perchild + + +

    Number of threads created on startup. As the + number of threads is dynamically controlled depending on the + load, there is usually little reason to adjust this + parameter.

    + +

    For perchild the default is StartThreads + 5 and this directive tracks the number of threads per + process at startup.

    + +

    For mpm_netware the default is + StartThreads 50 and, since there is only a single + process, this is the total number of threads created at startup to + serve requests.

    + +

    For beos the default is StartThreads + 10. It also reflects the total number of threads created + at startup to serve requests.

    +
    +
    + + +ThreadLimit +Sets the upper limit on the configurable number of threads +per child process +ThreadLimit number +See usage for details +server config +leadermpm_winnt +perchildthreadpoolworker + +Available for mpm_winnt in Apache 2.0.41 +and later + + +

    This directive sets the maximum configured value for ThreadsPerChild for the lifetime + of the Apache process. Any attempts to change this directive + during a restart will be ignored, but ThreadsPerChild can be modified + during a restart up to the value of this directive.

    + +

    Special care must be taken when using this directive. If + ThreadLimit is set to a value much higher + than ThreadsPerChild, + extra unused shared memory will be allocated. If both + ThreadLimit and ThreadsPerChild are set to values + higher than the system can handle, Apache may not start or the + system may become unstable. Do not set the value of this directive + any higher than your greatest predicted setting of ThreadsPerChild for the + current run of Apache.

    + +

    The default value for ThreadLimit is + 1920 when used with mpm_winnt and + 64 when used with the others.

    + + Note +

    There is a hard limit of ThreadLimit 20000 (or + ThreadLimit 15000 with mpm_winnt) + compiled into the server. This is intended to avoid nasty effects + caused by typos.

    +
    +
    +
    + + +ThreadsPerChild +Number of threads created by each child process +ThreadsPerChild number +See usage for details +server config +leadermpm_winnt +threadpoolworker + + +

    This directive sets the number of threads created by each + child process. The child creates these threads at startup and + never creates more. If using an MPM like mpm_winnt, + where there is only one child process, this number should be high + enough to handle the entire load of the server. If using an MPM + like worker, where there are multiple child processes, + the total number of threads should be high enough to handle + the common load on the server.

    + +

    The default value for ThreadsPerChild is + 64 when used with mpm_winnt and + 25 when used with the others.

    +
    +
    + + +ThreadStackSize +The size in bytes of the stack used by threads handling +client connections +ThreadStackSize size +65536 on NetWare; varies on other operating systems +server config +leadermpm_netware +mpm_winntperchild +threadpoolworker + +Available in Apache 2.1 and later + + +

    The ThreadStackSize directive sets the + size of the stack (for autodata) of threads which handle client + connections and call modules to help process those connections. + In most cases the operating system default for stack size is + reasonable, but there are some conditions where it may need to be + adjusted:

    + +
      +
    • On platforms with a relatively small default thread stack size + (e.g., HP-UX), Apache may crash when using some third-party modules + which use a relatively large amount of autodata storage. Those + same modules may have worked fine on other platforms where the + default thread stack size is larger. This type of crash is + resolved by setting ThreadStackSize to a + value higher than the operating system default. This type of + adjustment is necessary only if the provider of the third-party + module specifies that it is required, or if diagnosis of an Apache + crash indicates that the thread stack size was too small.
    • + +
    • On platforms where the default thread stack size is + significantly larger than necessary for the web server + configuration, a higher number of threads per child process + will be achievable if ThreadStackSize is + set to a value lower than the operating system default. This type + of adjustment should only be made in a test environment which allows + the full set of web server processing can be exercised, as there + may be infrequent requests which require more stack to process. + A change in the web server configuration can invalidate the + current ThreadStackSize setting.
    • +
    +
    +
    + + +User +The userid under which the server will answer +requests +User unix-userid +User #-1 +server config +leaderperchild +preforkthreadpoolworker + +Only valid in global server config since Apache +2.0 + + +

    The User directive sets the user ID as + which the server will answer requests. In order to use this + directive, the server must be run initially as root. + If you start the server as a non-root user, it will fail to change + to the lesser privileged user, and will instead continue to run as + that original user. If you do start the server as root, + then it is normal for the parent process to remain running as root. + Unix-userid is one of:

    + +
    +
    A username
    +
    Refers to the given user by name.
    + +
    # followed by a user number.
    +
    Refers to a user by its number.
    +
    + +

    The user should have no privileges that result in it being + able to access files that are not intended to be visible to the + outside world, and similarly, the user should not be able to + execute code that is not meant for HTTP requests. It is + recommended that you set up a new user and group specifically for + running the server. Some admins use user nobody, but + this is not always desirable, since the nobody user + can have other uses on the system.

    + + Security +

    Don't set User (or Group) to root unless + you know exactly what you are doing, and what the dangers are.

    +
    + +

    With the perchild MPM, which is intended to + server virtual hosts run under different user IDs, the + User directive defines the user ID for the + main server and the fallback for VirtualHost sections without an + AssignUserID directive.

    + +

    Special note: Use of this directive in VirtualHost is no longer supported. To + configure your server for suexec use + SuexecUserGroup.

    + + Note +

    Although the User directive is present + in the beos and mpmt_os2 MPMs, + it is actually a no-op there and only exists for compatibility + reasons.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_common.xml.de b/trunk/docs/manual/mod/mpm_common.xml.de new file mode 100644 index 0000000000..a596870ac4 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.xml.de @@ -0,0 +1,1010 @@ + + + + + + + + + +mpm_common +Eine Sammlung von Direktiven, die in mehr als einem + Multi-Processing-Modul (MPM) implementiert sind. +MPM + + +AcceptMutex +Vom Apache verwendete Methode zur Serialisierung mehrerer + Kindprozesse, die Anfragen an Netzwerk-Sockets entgegennehmen. +AcceptMutex Default|Methode +AcceptMutex Default +server config +leaderperchild +preforkthreadpoolworker + + + +

    Die Direktive AcceptMutex bestimmt die + Methode, die der Apache zur Serialisierung mehrerer Kindprozesse + verwendet, welche Anfragen an Netzwerk-Sockets entgegennehmen. Vor + Apache 2.0 war diese Methode nur zur Kompilierungszeit einstellbar. + Die optimale Methode ist sehr stark von der Architektur und + Plattform abhängig. Lesen Sie bitte Perfomance-Hinweise für + weitere Details.

    + +

    Wenn die Direktive auf Default eingestellt ist, dann + wird die zur Kompilierungszeit gewählte Voreinstellung verwendet. + Weitere mögliche Methoden sind unten angegeben. Beachten Sie, dass + nicht alle Methoden auf allen Plattformen verfügbar sind. Wird + eine Methode angegeben, die nicht verfügbar ist, dann wird + eine Nachricht in das Fehlerprotokoll geschrieben, welche die + verfügbaren Methoden auflistet.

    + +
    +
    flock
    +
    verwendet die Systemfunktion flock(2), um die + durch die LockFile-Direktive definierte Datei zu sperren.
    + +
    fcntl
    +
    verwendet die Systemfunktion fcntl(2), um die + durch die LockFile-Direktive definierte Datei zu sperren.
    + +
    posixsem
    +
    verwendet POSIX-kompatible Semaphore, um den Mutex zu + implementieren.
    + +
    pthread
    +
    verwendet gemäß der POSIX-Thread-Spezifikation + implementierte POSIX-Mutexe.
    + +
    sysvsem
    +
    verwendet Semaphoren des SysV-Typs, um den Mutex zu + implementieren.
    +
    + +

    Um die bei der Kompilierung gewählte Voreinstellung für + Ihr System herauszufinden, können Sie Ihr LogLevel auf debug setzen. Dann wird der + voreingestellte AcceptMutex ins ErrorLog geschrieben.

    + + Warnung +

    Auf den meisten Systemen stoppt der Server mit der Beantwortung von + Anfragen, wenn die Option pthread ausgewählt wurde und + ein Kindprozess unkontrolliert endet während er den + AcceptCntl-Mutex hält. In diesem Fall muss der Server + manuell neu gestartet werden, um wieder weiter zu arbeiten.

    +

    Eine Ausnahme stellt Solaris dar, da es einen Mechanismus anbietet, den + der Apache verwendet und der üblicherweise die Freigabe des Mutex + erlaubt, nachdem ein Kindprozess, der gerade einen Mutex hält, + abgestürzt ist.

    +

    Wenn Ihr System die Funktion + pthread_mutexattr_setrobust_np() bereitstellt, können + Sie wahrscheinlich die Option pthread problemlos + verwenden.

    +
    +
    +
    + + +CoreDumpDirectory +Verzeichnis, in das der Apache zu wechseln versucht, bevor er + einen Hauptspeicherauszug erstellt +CoreDumpDirectory Verzeichnis +Für die Voreinstellung siehe Beschreibung +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    Dies beeinflusst das Verzeichnis, in welches der Apache zu wechseln + versucht, bevor er einen Hauptspeicherauszug einen + so genannten Core-Dump erstellt. Die Voreinstellung ist das + ServerRoot-Verzeichnis. Da dieses + jedoch nicht für den Benutzer beschreibbar sein soll, unter dem + der Server läuft, werden normalerweise keine + Hauptspeicherauszüge geschrieben. Wenn Sie zum Debuggen + einen Hauptspeicherauszug haben möchten, können Sie + ihn mit dieser Direktive an einem anderen Ort ablegen lassen.

    + + Hauptspeicherauszüge unter Linux +

    Wenn Apache als root startet und zu einem anderen Benutzer + wechselt, deaktiviert der Linux-Kernel Hauptspeicherauszüge + auch dann, wenn der Prozess in dem Verzeichnis schreiben darf. Ab Linux + 2.4 reaktiviert Apache (ab 2.0.46) Hauptspeicherauszüge wieder, + jedoch nur dann, wenn Sie explizit + CoreDumpDirectory konfigurieren.

    +
    +
    +
    + + +EnableExceptionHook +Aktiviert einen Hook, der nach einem Absturz noch +Ausnahmefehler behandeln lassen kann +EnableExceptionHook On|Off +EnableExceptionHook Off +server config +leaderperchild +preforkthreadpool +worker +Verfügbar seit Version 2.0.49 + + +

    Diese Direktive ist aus Sicherheitsgründen nur verfügbar, + wenn der Server mit der Option --enable-exception-hook + konfiguriert wurde. Sie aktiviert einen Hook, der es externen Modulen + erlaubt, sich dort einzuhängen und nach dem Absturz eines + Kindprozesses noch Aktionen durchzuführen.

    + +

    Es existieren bereits zwei Module, mod_whatkilledus und + mod_backtrace, welche diesen Hook verwenden. Weitere + Informationen hierzu finden Sie auf Jeff Trawicks EnableExceptionHook-Seite.

    +
    +
    + + +Group +Benutzergruppe, unter welcher der Server Anfragen + beantwortet +Group Unix-Gruppe +Group #-1 +server config +beosleader +mpmt_os2perchildprefork +threadpoolworker +Seit Apache 2.0 nur in der globalen Server-Konfiguration + gültig + + +

    Die Direktive Group bestimmt die + Benutzergruppe, unter welcher der Server Anfragen beantwortet. + Um diese Direktive zu verwenden, muss der Server als root gestartet + werden. Wenn Sie den Server unter einem nicht-root-Benutzer starten, + wird er nicht zur angegebenen Gruppe wechseln können und statt + dessen weiter mit der Gruppe des ursprünglichen Benutzers + laufen. Unix-Gruppe kann sein:

    + +
    +
    Ein Gruppenname
    +
    Verweist auf die durch den Namen angegebene Gruppe.
    + +
    # gefolgt von einer Gruppennummer.
    +
    Verweist auf die durch ihre Nummer angegebene Gruppe.
    +
    + + Beispiel + Group www-group + + +

    Es wird empfohlen, dass Sie eine neue Gruppe speziell zum Betrieb + des Servers erstellen. Einige Administratoren verwenden den Benutzer + nobody. Dies ist jedoch nicht immer möglich + oder gewünscht.

    + + Sicherheit +

    Setzen Sie Group (oder User) nicht auf root, + solange Sie nicht ganz genau wissen, was Sie tun und welche Gefahren + Sie eingehen.

    +
    + +

    Wichtiger Hinweis: Die Verwendung der Direktive innerhalb von + VirtualHost + wird nicht länger unterstützt. Benutzen Sie SuexecUserGroup um Ihren Server + für suexec einzurichten.

    + + Anmerkung +

    Obwohl die Direktive Group in den MPMs + beos und mpmt_os2 existiert, ist + sie dort tatsächlich eine Leeranweisung und exisitert nur + aus Kompatibilitätsgründen.

    +
    +
    +
    + + +PidFile +Datei, in welcher der Server die Prozess-ID des Daemons +ablegt +PidFile Dateiname +PidFile logs/httpd.pid +server config +beosleader +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    Die Direktive PidFile bestimmt die Datei, + in welcher der Server die Prozess-ID des Daemons ablegt. Wenn der + Dateiname nicht absolut angegeben wird, wird er relativ zu + ServerRoot interpretiert.

    + + Beispiel + PidFile /var/run/apache.pid + + +

    Es ist oft hilfreich, dem Server ein Signal senden zu können, + damit er seine ErrorLogs und + TransferLogs + schließt und dann neu öffnet und seine + Konfigurationsdateien neu einliest. Dies kann durch Senden eines + SIGHUP-Signals (kill -1) an die Prozess-ID geschehen, die im + PidFile eingetragen ist.

    + +

    Die PidFile-Datei unterliegt den + gleichen Warnungen über die Ablage von Protokolldateien + und Sicherheit.

    + + Anmerkung +

    Ab Apache 2 wird empfohlen, nur das Skript + apachectl zum (Neu-)Starten und Stoppen des Servers zu + verwenden.

    +
    +
    +
    + + +Listen +IP-Adressen und Ports, an denen der Server lauscht +Listen [IP-Addresse:]Port +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchild +preforkthreadpoolworker + +Seit Apache 2.0 vorgeschrieben + + +

    Die Direktive Listen weist den Apache an, + nur an den angegebenen IP-Adressen oder Ports zu lauschen. + Standardmäßig antwortet er auf alle Anfragen an allen + IP-Interfaces. Listen ist nun eine notwendige + Anweisung. Wenn sie nicht in der Konfigurationsdatei enthalten ist, + wird der Server-Start fehlschlagen. Dies ist eine Änderung + gegenüber früheren Versionen des Apache.

    + +

    Die Direktive Listen weist den Server an, + ankommende Anfragen am angegebenen Port oder der + Kombination aus Adresse und Port entgegenzunehmen. Wenn nur eine Portnummer + angegeben ist, dann lauscht der Server am angegebenen Port an allen + Interfaces. Wenn sowohl eine IP-Adresse als auch ein Port angegeben + sind, dann lauscht der Server am angegeben Port und Interface.

    + +

    Es können mehrere Listen-Anweisungen + verwendet werden, um eine Reihe von Adressen und Port anzugeben, an + denen gelauscht werden soll. Der Server antwortet auf Anfragen von + jedem der aufgeführten Adressen und Ports.

    + +

    Um beispielsweise den Server Verbindungen an den beiden Ports 80 und + 8000 annehmen zu lassen, verwenden Sie:

    + + + Listen 80
    + Listen 8000 +
    + +

    Um den Server Verbindungen an zwei angegebenen Interfaces und Ports + annehmen zu lassen, verwenden Sie:

    + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6-Adressen müssen wie in dem folgenden Beispiel in eckige + Klammern eingeschlossen werden:

    + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + + + Fehlermöglichkeit + Mehrere Listen-Direktiven für gleiche + IP-Adresse und Port führen zur Fehlermeldung + Address already in use Adresse schon in + Benutzung. + +
    +DNS-Probleme +Bestimmen, welche Adressen und Ports der + Apache verwendet +
    + + +ListenBackLog +Maximale Länge der Warteschlange schwebender + Verbindungen +ListenBacklog backlog +ListenBacklog 511 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    Die maximale Länge der Warteschlange schwebender Verbindungen. + Üblicherweise ist keine Feineinstellung notwendig oder sinnvoll, + auf einigen System kann es jedoch gewünscht sein, diesen Wert bei + TCP-SYN-Angriffen zu erhöhen. Beachten Sie auch die Beschreibung des + backlog-Parameters der Systemfunktion listen(2).

    + +

    Der Wert wird vom Betriebssystem oft auf eine niedrigere + Einstellung begrenzt. Dies variiert von Betriebssystem zu Betriebssystem. + Beachten Sie auch, dass viele Betriebssyteme nicht genau beachten, + was für backlog angegeben ist, jedoch einen Wert basierend auf der + Angabe (normalerweiseweise jedoch größer als diese) verwenden.

    +
    +
    + + +LockFile +Ablageort der Lock-Datei für die Serialisierung von +entgegengenommenen Anfragen +LockFile Dateiname +LockFile logs/accept.lock +server config +leaderperchild +preforkthreadpoolworker + + + +

    Die Direktive LockFile legt den Pfad zur + Lock-Datei fest, die verwendet wird, wenn der Apache mit einer der + AcceptMutex-Einstellungen + fcntl oder flock verwendet wird. Die Anweisung + sollte normalerweise bei der Voreinstellung belassen werden. + Der Hauptgrund, sie zu ändern, ist, wenn das + logs-Verzeichnis auf einem per NFS-eingebundenen Laufwerk + liegt, da die Lock-Datei auf einer lokalen Platte abgelegt sein + muss. Die PID Prozess-ID des + Hauptserverprozesses wird automatisch an den Dateinamen angehängt.

    + + Sicherheit +

    Es ist am besten, die Ablage in einem allgemein für + jedermann beschreibbaren + Verzeichnis wie /var/tmp zu vermeiden, da + ein Denial-of-Servide-Angriff gestartet werden könnte und der + Server am Start gehindert werden könnte, indem eine Lock-Datei + mit dem gleichen Namen erstellt wird, wie der Server sie zu erstellen + versuchen würde.

    +
    +
    +AcceptMutex +
    + + +MaxClients +Maximale Anzahl der Kindprozesse, die zur Bedienung von Anfragen + gestartet wird +MaxClients Anzahl +Für Details siehe Beschreibung +server config +beosleader +preforkthreadpoolworker + + + +

    Die Direktive MaxClients setzt die Grenze + für die Anzahl gleichzeitig bedienter Anfragen. Jeder + Verbindungsversuch oberhalb der MaxClients-Begrenzung wird üblicherweise in eine + Warteschlange gestellt, bis zu einer Anzahl basierend auf der + ListenBacklog-Anweisung. + Sobald ein Kindprozess am Ende einer anderen Anfrage freigegeben wird, + wird die Verbindung bedient.

    + +

    Für Server ohne Thread-Unterstützung (z.B. + prefork) wird MaxClients als + maximale Anzahl der Kindprozesse verstanden, die zur Bedienung von + Anfragen gestartet werden. Die Voreinstellung ist 256. Um + diesen Wert zu erhöhen, muss auch ServerLimit angehoben werden.

    + +

    Bei Servern mit Thread-Unterstützung und bei Hybrid-Servern + (z.B. beos oder worker) + begrenzt MaxClients die Gesamtzahl der Threads, + die für die Bedienung von Anfragen verfügbar sind. + Die Voreinstellung für beos ist 50. + Bei Hybrid-MPMs ist die Voreinstellung 16 (ServerLimit) multipliziert mit + dem Wert 25 (ThreadsPerChild). Um MaxClients + auf einen Wert zu erhöhen, der mehr als 16 Prozesse erfordert, + müssen Sie daher auch ServerLimit anheben.

    +
    +
    + + +MaxMemFree +Maximale Menge des Arbeitsspeichers, den die + Haupt-Zuteilungsroutine verwalten darf, ohne free() + aufzurufen +MaxMemFree KBytes +MaxMemFree 0 +server config +beosleader +mpm_netwareprefork +threadpoolworkermpm_winnt + + +

    Die Direktive MaxMemFree gibt die maximale + Menge freier Kilobytes an, welche die Haupt-Zuteilungsroutine verwalten + darf, ohne free() aufzurufen. Wenn keine Angabe gemacht wird, + oder Null angegeben ist, wird dieser Wert nicht eingeschränkt.

    +
    +
    + + +MaxRequestsPerChild +Obergrenze für die Anzahl von Anfragen, die ein einzelner + Kindprozess während seines Lebens bearbeitet +MaxRequestsPerChild number +MaxRequestsPerChild 10000 +server config +leadermpm_netware +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    Die Direktive MaxRequestsPerChild legt die + Grenze für die Anzahl von Anfragen fest, die ein einzelner + Kinprozess während seines Lebens bearbeitet. Nach + MaxRequestsPerChild Anfragen stirbt der + Kindprozess. Wenn MaxRequestsPerChild + 0 ist, endet der Prozess niemals.

    + + Abweichende Voreinstellungen +

    Die Voreinstellung für mpm_netware und + mpm_winnt ist 0.

    +
    + +

    Die Begrenzung von MaxRequestsPerChild auf einen + Wert ungleich Null hat zwei vorteilhafte Auswirkungen:

    + +
      +
    • sie begrenzt die Menge an Arbeitsspeicher, die ein Prozess + durch (versehentliche) Speicherlecks verbrauchen kann.
    • + +
    • das Festlegen einer endlichen Lebensdauer von Prozessen hilft, die + Anzahl von Prozessen zu reduzieren, wenn die Serverlast + zurückgeht.
    • +
    + + Anmerkung +

    Bei KeepAlive-Anfragen + wird nur die erste Anfrage für diese begrenzung gezählt. + Eigentlich wird nur die Begrenzung für die Anzahl der + Verbindungen pro Kindprozess geändert.

    +
    +
    +
    + + +MaxSpareThreads +Maximale Anzahl unbeschäftigter Threads +MaxSpareThreads Anzahl +Für Details siehe Beschreibung +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    Maximale Anzahl unbeschäftigter Threads. Die verschiedenen MPMs + behandeln diese Anweisung unterschiedlich.

    + +

    Die Voreinstellung für perchild ist + MaxSpareThreads 10. Das MPM überwacht die Anzahl der + unbeschäftigten Threads auf der Basis einzelner Kindprozesse. Wenn + zu viele unbeschäftigte Threads in einem Kindprozess existieren, + beendet der Server Threads innerhalb dieses Kindprozesses.

    + +

    Die Voreinstellung für worker, + leader und threadpool ist + MaxSpareThreads 250. Diese MPMs behandeln Threads + auf einer serverweiten Basis. Wenn zu viele unbeschäftigte Threads + im Server existieren, dann werden solange Kindprozesse beendet, bis + die Anzahl der unbeschäftigten Threads kleiner als der + angegebene Wert ist.

    + +

    Die Voreinstellung für mpm_netware ist + MaxSpareThreads 100. Da dieses MPM nur einen einzigen + Prozess ausführt, ist die Zählung überschüssiger + Threads ebenfalls serverweit.

    + +

    beos and mpmt_os2 arbeiten + ähnlich wie mpm_netware. Die Voreinstellung + für beos ist MaxSpareThreads 50. + Die Voreinstellung für mpmt_os2 ist + 10.

    + + Restriktionen +

    Der Wertebereich von MaxSpareThreads + ist eingeschränkt. Apache korrigiert den angegebenen Wert + automatisch gemäß den folgenden Regeln:

    +
      +
    • perchild verlangt, dass MaxSpareThreads kleiner oder gleich ThreadLimit ist.
    • + +
    • mpm_netware verlangt einen Wert größer + als MinSpareThreads.
    • + +
    • Bei leader, threadpool und + worker muss der Wert größer oder gleich + der Summe aus MinSpareThreads und + ThreadsPerChild sein.
    • +
    +
    +
    +MinSpareThreads +StartServers +
    + + +MinSpareThreads +Minimale Anzahl unbeschäftigter Threads, die zur + Bedienung von Anfragespitzen zur Verfügung stehen +MinSpareThreads Anzahl +Für Details siehe Beschreibung +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    Minimale Anzahl unbeschäftigter Threads, um Anfragespitzen + zu bedienen. Die verschiedenen MPMs behandeln die Anweisung + unterschiedlich.

    + +

    perchild verwendet die Voreinstellung + MinSpareThreads 5 und überwacht die Anzahl der + unbeschäftigten Threads auf der Basis einzelner Kindprozesse. Wenn + in einem Kindprozess nicht genügend unbeschäftigte + Threads vorhanden sind, erstellt der Server neue Threads innerhalb + dieses Kindprozesses. Wenn Sie also NumServers auf 10 und MinSpareThreads auf einen Wert von 5 setzen, + haben Sie mindestens 50 unbeschäftigte Threads auf Ihrem + System.

    + +

    worker, leader und + threadpool verwenden eine Voreinstellung von + MinSpareThreads 75 und behandeln unbeschäftigte + Threads auf serverweiter Basis. Wenn nicht genügend + unbeschäftigte Threads im Server vorhanden sind, dann + werden solange Kindprozesse erzeugt, bis die Anzahl unbeschäftigter + Threads größer als der angegebene Wert ist.

    + +

    mpm_netware verwendet die Voreinstellung + MinSpareThreads 10 und verfolgt dies serverweit, da + es ein Einzelprozess-MPM ist.

    + +

    beos und mpmt_os2 arbeiten + ähnlich wie mpm_netware. Die Voreinstellung + für beos ist MinSpareThreads 1. + Die Voreinstellung für mpmt_os2 ist + 5.

    + +
    +MaxSpareThreads +StartServers +
    + + +ScoreBoardFile +Ablageort der Datei, die zur Speicherung von Daten zur + Koordinierung der Kindprozesse verwendet wird +ScoreBoardFile Dateipfad +ScoreBoardFile logs/apache_status +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    Apache verwendet ein Scoreboard zur Kommunikation zwischen + seinen Eltern- und Kindprozessen. Einige Architekturen erfordern + eine Datei zur Unterstützung der Kommunikation. Wenn die Datei + undefiniert bleibt, versucht der Apache zuerst, das Scoreboard im + Arbeitsspeicher zu erstellen (Verwendung von anonymem Shared-Memory), + und versucht bei einem Fehlschlag anschließend die Datei auf + der Festplatte zu erstellen (Verwendung von Datei-basiertem + Shared-Memory). Die Angabe dieser Direktive veranlaßt den + Apache stets, die Datei auf der Festplatte zu erstellen.

    + + Beispiel + ScoreBoardFile /var/run/apache_status + + +

    Datei-basiertes Shared-Memory ist für Applikationen von + Drittanbietern hilfreich, die direkten Zugriff auf das Scoreboard + benötigen.

    + +

    Wenn Sie eine ScoreBoardFile-Anweisung + verwenden, erreichen Sie eventuell eine höhere Geschwindigkeit, wenn + Sie die Datei auf einer RAM-Disk ablegen. Achten Sie darauf, die + gleichen Warnungen wie über die Ablage von Protokolldateien und + Sicherheit zu beherzigen.

    +
    +Apache beenden und neu + starten +
    + + +SendBufferSize +Größe des TCP-Puffers +SendBufferSize Bytes +SendBufferSize 0 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    Der Server setzt die Größe des TCP-Puffers auf die + angegebene Anzahl Bytes. Dies ist sehr hilfreich, um Voreinstellungen + alter Standardbetriebssysteme für Hochgeschwindigkeitsverbindungen + mit hoher Latenzzeit anzuheben (d.h. 100ms oder so, wie bei + Interkontinentalverbindungen).

    + +

    Wird der Wert auf 0 gesetzt, dann verwendet der Server + die Voreinstellung des Betriebssystems.

    +
    +
    + + +ServerLimit +Obergrenze für die konfigurierbare Anzahl von + Prozessen +ServerLimit Anzahl +Für Details siehe Beschreibung +server config +leaderperchild +preforkthreadpoolworker + + + +

    Bei dem MPM prefork bestimmt die Direktive + den während der Lebensdauer des Apache-Prozesses maximal + einstellbaren Wert für MaxClients. Beim MPM + worker bestimmt die Direktive in Verbindung mit + ThreadLimit den Maximalwert + für MaxClients + für die Lebensdauer des Apache-Prozesses. Jeder Versuch, diese + Anweisung während eines Neustarts zu ändern, wird ignoriert. + MaxClients kann jedoch + während eines Neustarts geändert werden.

    + +

    Lassen Sie besondere Vorsicht bei der Verwendung dieser Direktive + walten. Wenn ServerLimit auf einen Wert deutlich + höher als notwendig gesetzt wird, wird zusätzliches, + unbenutztes Shared-Memory belegt. Wenn sowohl + ServerLimit als auch MaxClients auf Werte gesetzt werden, die + größer sind, als das System sie handhaben kann, dann kann + der Apache möglicherweise nicht starten, oder das System kann + instabil werden.

    + +

    Verwenden Sie die Direktive bei dem MPM prefork + nur, wenn Sie MaxClients + auf mehr als 256 (Voreinstellung) setzen müssen. Setzen Sie den + Wert nicht höher als den Wert, den Sie für MaxClients angeben möchten.

    + +

    Verwenden Sie die Direktive bei worker, + leader und threadpool nur, wenn Ihre + MaxClients- und + ThreadsPerChild-Einstellungen + mehr als 16 Serverprozesse (Voreinstellung) erfordern. Setzen Sie den + Wert dieser Direktive nicht höher, als die Anzahl der Serverprozesse, + die dafür erforderlich ist, was Sie bei MaxClients und + ThreadsPerChild angeben + möchten.

    + +

    Verwenden Sie die Direktive beim MPM perchild nur, + wenn Sie NumServers auf einen + Wert größer als 8 (Voreinstellung) setzen müssen.

    + + Anmerkung +

    Eine feste Begrenzung von ServerLimit 20000 ist in den + Server einkompiliert (bei dem MPM prefork 200000). + Dies soll unangenehme Effekte durch Tippfehler verhindern.

    +
    +
    +Apache beenden und neu + starten +
    + + +StartServers +Anzahl der Kindprozesse des Servers, die beim Start erstellt + werden +StartServers Anzahl +Für Details siehe Beschreibung +server config +leadermpmt_os2 +preforkthreadpoolworker + + + +

    Die Direktive StartServers bestimmt + die Anzahl der Kindprozesse des Servers, die beim Start erstellt + werden. Da die Anzahl der Prozesse abhängig von der Last + dynamisch kontrolliert wird, besteht normalerweise wenig + Grund für eine Änderung dieses Parameters.

    + +

    Die Voreinstellung unterscheidet sich von MPM zu MPM. Bei + leader, threadpool und + worker ist die Voreinstellung + StartServers 3. Die Voreinstellung bei + prefork ist 5 und bei + mpmt_os2 2.

    +
    +
    + + +StartThreads +Anzahl der Threads, die beim Start erstellt werden +StartThreads Anzahl +Für Details siehe Beschreibung +server config +beosmpm_netware +perchild + + +

    Anzahl der Threads, die beim Start erstellt werden. Da die Anzahl + der Threads abhängig von der Last dynamisch kontrolliert wird, + besteht normalerweise wenig Grund für eine Änderung + dieses Parameters.

    + +

    Die Voreinstellung für perchild ist + StartThreads 5. Die Direktive setzt während des + Starts die Anzahl der Threads pro Prozess.

    + +

    Die Voreinstellung bei mpm_netware ist + StartThreads 50. Da hier lediglich ein einzelner Prozess + existiert, ist dies die Gesamtzahl der Threads, die beim Start + erstellt wird, um Anfragen zu bedienen.

    + +

    Die Voreinstellung für beos ist StartThreads + 10. Die Einstellung reflektiert ebenfalls die Gesamtzahl der Threads, die + beim Start erstellt werden, um Anfragen zu bedienen.

    +
    +
    + + +ThreadLimit +Bestimmt die Obergrenze der konfigurierbaren Anzahl von Threads + pro Kindprozess +ThreadLimit Anzahl +Für Details siehe Beschreibung +server config +leadermpm_winnt +perchildthreadpoolworker + +Verfügbar für mpm_winnt ab + Apache 2.0.41 + + +

    Die Direktive bestimmt den während der Lebensdauer des + Apache-Prozesses maximal einstellbaren Wert für + ThreadsPerChild. Jeder + Versuch, diese Direktive während eines Neustarts zu ändern, + wird ignoriert. ThreadsPerChild + kann jedoch während eines Neustarts modifiziert werden bis zu dem + Wert dieser Anweisung.

    + +

    Lassen Sie besondere Vorsicht bei der Verwendung dieser Direktive + walten. Wenn ThreadLimit auf einen Wert + deutlich höher als ThreadsPerChild gesetzt wird, wird + zusätzliches, ungenutztes Shared-Memory belegt. Wenn sowohl + ThreadLimit als auch ThreadsPerChild auf Werte gesetzt werden, + die größer sind, als das System sie handhaben kann, dann kann + der Apache möglicherweise nicht starten oder das System kann + instabil werden. Setzen Sie den Wert dieser Direktive nicht höher + als Ihre größte erwartete Einstellung für + ThreadsPerChild + während der aktuellen Ausführung des Apache.

    + +

    Die Voreinstellung für ThreadLimit ist + 1920 wenn sie zusammen mit mpm_winnt + verwendet wird, und 64 bei der Verwendung mit anderen + MPMs.

    + + Anmerkung +

    Eine feste Begrenzung von ThreadLimit 20000 + (oder ThreadLimit 15000 bei mpm_winnt) + ist in den Server einkompiliert. Dies soll unangenehme Effekte durch + Tippfehler verhindern.

    +
    +
    +
    + + +ThreadsPerChild +Anzahl der Threads, die mit jedem Kindprozess gestartet + werden +ThreadsPerChild Anzahl +Für Details siehe Beschreibung +server config +leadermpm_winnt +threadpoolworker + + +

    Die Direktive legt die Anzahl der Threads fest, die mit jedem + Kindprozess gestartet werden. Der Kindprozess erstellt diese Threads + beim Start und erstellt später keine weiteren mehr. Wenn Sie ein + MPM wie mpm_winnt verwenden, wo nur ein + Kindprozess existiert, dann sollte diese Angabe hoch genug sein, + die gesamte Last des Servers zu bewältigen. Wenn Sie ein MPM + wie worker verwenden, wo mehrere Kindprozesse + existieren, dann sollte die Gesamtzahl der Thread groß + genug sein, die übliche Last auf dem Server zu bewältigen.

    + +

    Die Voreinstellung für ThreadsPerChild ist + 64, wenn mpm_winnt verwendet wird, und + 25 bei der Verwendung der anderen MPMs.

    +
    +
    + + +ThreadStackSize +Die Größe des Stacks in Bytes, der von Threads +verwendet wird, die Client-Verbindungen bearbeiten. +ThreadStackSize size +65536 unter NetWare; variiert bei anderen Betriebssystemen. +server config +leadermpm_netware +mpm_winntperchild +threadpoolworker + +Verfügbar seit Version 2.1 + + +

    Die Direktive ThreadStackSize legt die + Größe des Stacks (für Autodaten) der Threads fest, die + Client-Verbindungen bearbeiten und Module aufrufen, welche bei der + Verarbeitung dieser Verbindungen helfen. In den meisten Fällen ist die + Voreinstellung des Betriebssystems angemessen, doch unter bestimmten + Umständen kann es sinnvoll sein, den Wert anzupassen:

    + +
      +
    • Auf Plattformen mit einer relativ kleinen Voreingestellung für + die Größe des Thread-Stacks (z.B. HP-UX) kann der Apache bei + der Verwendung einiger Drittanbietermodule, die einen relativ hohen Bedarf + an Speicherplatz haben, abstürzen. Ebendiese Module arbeiten + möglicherweise problemlos auf anderen Plattformen, wo der + voreingestellte Thread-Stack größer ist. Derartige + Abstürze können Sie vermeiden, indem Sie + ThreadStackSize auf einen höheren Wert als die + Betriebssystemvoreinstellung setzen. Eine solche Anpassung ist nur + notwendig, wenn es vom Anbieter des Moduls so spezifiziert wurde oder die + Diagnose eines Apache-Absturzes ergeben hat, das die + Thread-Stackgröße zu klein war.
    • + +
    • Auf Plattformen, wo die voreingestellte Thread-Stackgröße + für die Webserverkonfiguration deutlich größer als + notwendig ist, kann eine größere Anzahl von Threads pro + Kindprozess erreicht werden, wenn ThreadStackSize + auf einen Wert kleiner als die Betriebssystemvoreinstellung gesetzt wird. + Da es einzelne Anfragen geben kann, die mehr Stack zur Verarbeitung + benötigen, sollte eine derartige Korrektur ausschließlich in + Testumgebungen zum Einsatz kommen, auf denen die gesamte + Webserververarbeitung ausprobiert werden kann. Eine Änderung der + Webserverkonfiguration kann den aktuellen Wert der + ThreadStackSize ungültig machen.
    • +
    +
    +
    + + +User +Die Benutzerkennung, unter welcher der Server Anfragen + beantwortet +User Unix-User-ID +User #-1 +server config +leaderperchild +preforkthreadpoolworker + +Seit Apache 2.0 nur in der globalen Server-Konfiguration +gültig + + +

    Die Direktive User legt die Benutzerkennung + fest, mit der der Server Anfragen beantwortet. Um diese Anweisung + zu verwenden, muss der Server als root gestartet werden. + Wenn Sie den Server unter einem nicht-root-Benutzer starten, kann + er nicht zu dem minder privilegierten Benutzer wechseln und wird statt + dessen weiter mit der ursprünglichen Benutzerkennung laufen. + Wenn Sie den Server als root starten, dann ist es normal, + dass der Elternprozess als root weiterläuft. + Unix-User-ID kann sein:

    + +
    +
    Ein Benutzername
    +
    Verweist auf den durch Namen angegebenen Benutzer.
    + +
    # gefolgt von einer Benutzernummer.
    +
    Verweist auf einen durch eine Nummer angegebenen Benutzer.
    +
    + +

    Der Benutzer sollte keine Rechte besitzen, die dazu führen, + dass er in der Lage ist, auf Dateien zuzugreifen, die nicht dafür + bestimmt sind, für die Außenwelt sichtbar zu sein. + Gleichermaßen sollte der Benutzer nicht in der Lage sein, + Code auszuführen, der nicht für HTTP-Anfragen bestimmt ist. + Es wird empfohlen, einen neuen Benutzer und eine neue Gruppe speziell + zur Ausführung des Servers zu erstellen. Einige Administratoren + verwenden den Benutzer nobody. Dies ist jedoch nicht + immer wünschenswert, da der Benuter nobody andere + Rechte auf dem System besitzen kann.

    + + Sicherheit +

    Setzen Sie User (oder Group) nicht auf root, + solange Sie nicht genau wissen, was Sie tun, und welches die Gefahren + sind.

    +
    + +

    Beim MPM perchild, das dafür gedacht ist, + virtuelle Hosts unter verschiedenen Benutzerkennungen auszuführen, + bestimmt die Direktive User die + Benutzerkennung für den Hauptserver und bildet den Rückfallwert + für VirtualHost-Abschnitte ohne eine + AssignUserID-Anweisung.

    + +

    Wichtiger Hinweis: Die Verwendung dieser Direktive innerhalb von + VirtualHost wird + nicht mehr unterstützt. Benutzen Sie SuexecUserGroup, um Ihren Server + für suexec einzurichten.

    + + Anmerkung +

    Obwohl die Direktive User in den MPMs + beos und mpmt_os2 existiert, ist + sie dort tatsächlich eine Leeranweisung und exisitert nur + aus Kompatibilitätsgründen.

    +
    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_common.xml.ja b/trunk/docs/manual/mod/mpm_common.xml.ja new file mode 100644 index 0000000000..09bdd3e63a --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.xml.ja @@ -0,0 +1,983 @@ + + + + + + + + + +mpm_common +$BFs$D0J>e$N%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) +$B$G +MPM + + +AcceptMutex +$BJ#?t$N;R%W%m%;%9$,%M%C%H%o!<%/%=%1%C%H$G%j%/%(%9%H$r(B +accept $B$7$h$&$H$7$F$$$k$H$-$K!"(BApache $B$,$=$l$i$N;R%W%m%;%9$rD>Ns2=$9$k$?$a$K(B +$B;H$&J}K!(B +AcceptMutex default|method +AcceptMutex default +server config +leaderperchild +preforkthreadpoolworker + + + +

    AcceptMutex $B%G%#%l%/%F%#%V$O!"(B + $B%M%C%H%o!<%/%=%1%C%H$N%j%/%(%9%H$r(B accept $B$7$h$&$H$7$F$$$kJ#?t$N;R%W%m%;%9$r(B + Apache $B$,D>Ns2=$9$k$?$a$K;H$&J}K!$r@_Dj$7$^$9!#(B + Apache 2.0 $B0JA0$O!"$3$N%a%=%C%I$O%3%s%Q%$%k;~$K$N$_A*Br$G$-$^$7$?!#(B + $B:GE,$JJ}K!$O!"%"!<%-%F%/%A%c$d%W%i%C%H%[!<%`$KBg$-$/0MB8$7$^$9!#(B + $B>\:Y$K4X$7$F$O!"(B$B@-G=$N%A%e!<%K%s%0(B + $B%I%-%e%a%s%H$r$4Mw2<$5$$!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$,(B Default + $B$K@_Dj$5$l$F$$$l$P!"%3%s%Q%$%k;~$KA*Br$5$l$?%G%U%)%k%HCM$,;H$o$l$^$9!#(B + $BB>$N;HMQ2DG=$J%a%=%C%I$N0lMw$O2<$K$"$j$^$9!#(B + $BA4$F$N%a%=%C%I$,A4$F$N%W%i%C%H%[!<%`$G;HMQ2DG=$G$"$k$o$1$G$O$J$$!"(B + $B$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B + $B;HMQ2DG=$G$J$$%a%=%C%I$,;XDj$5$l$?>l9g$O!"(B + $B;HMQ2DG=$J%a%=%C%I$N0lMw$r4^$s$@%a%C%;!<%8$,(B + $B%(%i!<%m%0$K=PNO$5$l$^$9!#(B

    + +
    +
    flock
    +
    LockFile + $B%G%#%l%/%F%#%V$GDj5A$7$?%U%!%$%k$N%m%C%/$K!"(B + flock(2) $B%7%9%F%`%3!<%k$r;H$$$^$9!#(B
    + +
    fcntl
    +
    LockFile + $B%G%#%l%/%F%#%V$GDj5A$7$?%U%!%$%k$N%m%C%/$K!"(B + fcntl(2) $B%7%9%F%`%3!<%k$r;H$$$^$9!#(B
    + +
    posixsem
    +
    $BGSB>=hM}$N + +
    pthread
    +
    POSIX Threads (PThreads) $B5,3J$G=hM}$r;H$$$^$9!#(B
    + +
    sysvsem
    +
    $BGSB>=hM}$N +
    + +

    $B%3%s%Q%$%k;~$K%7%9%F%`$N%G%U%)%k%H$KA*$P$l$?$b$N$,2?$+$r8+$?$$>l9g$O!"(B + LogLevel $B$r(B debug + $B$K@_Dj$9$k$H$h$$$G$7$g$&!#%G%U%)%k%H$N(B AcceptMutex + $B$,(B ErrorLog $B$K=q$-9~$^$l$^$9!#(B

    + + $B7Y9p(B +

    $B$[$H$s$I$N%7%9%F%`$K$*$$$F$O!"(Bpthread $B%*%W%7%g%s$,(B + $BA*$P$l$F$$$k$H!";R%W%m%;%9$,(B ApacheCntl mutex $B$r(B + $BJ];}$7$F$$$k$H$-$K0[>o=*N;$7$?>l9g!"%5!<%P$O%j%/%(%9%H$X$N1~Ez$r(B + $BDd;_$7$F$7$^$$$^$9!#$3$l$,H/@8$7$?>l9g$O!"%5!<%P$rI|5l$5$;$k$?$a$K$O(B + $B + +

    Solaris $B$ONc30$G!"(BApache $B$b;HMQ$7$F$$$k!";R%W%m%;%9$,(B mutex $B$r(B + $BJ];}$7$F0[>o=*N;$7$?8e$K(B mutex $B$rI|5l$5$;$k$?$a$N5!9=$rDs6!$r$7$F$$$^$9!#(B

    +

    $B8f;HMQ$N%7%9%F%`$,(B pthread_mutexattr_setrobust_np() $B4X?t$r(B + $Bl9g$O!"(Bpthread $B%*%W%7%g%s$r0BA4$K;HMQ$G$-$k(B + $B2DG=@-$,$"$j$^$9!#(B

    +
    +
    +
    + + +CoreDumpDirectory +Apache $B$,%3%"%@%s%W$9$kA0$K0\F0$r;n$_$k%G%#%l%/%H%j(B + +CoreDumpDirectory directory +$B%G%U%)%k%H$N@_Dj$O@bL@J8$rFI$s$G$/$@$5$$(B +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    Apache $B$,%3%"%@%s%W$9$kA0$K0\F0$r;n$_$k%G%#%l%/%H%j$r@)8f$7$^$9!#(B + $B%G%U%)%k%HCM$O(B ServerRoot + $B%G%#%l%/%H%j$G$9$,!"$3$N%G%#%l%/%H%j$O%5!<%P$No$O%3%"%@%s%W$O=q$-9~$^$l$^$;$s!#(B + $B%G%P%C%0$N$?$a$K%3%"%@%s%W$,I,MW$G$"$l$P!"(B + $B$3$N%G%#%l%/%F%#%V$r;H$C$FB>$N0LCV$K%3%"%@%s%W$r=q$-=P$9$h$&$K$G$-$^$9!#(B

    + + Linux $B$G$N%3%"%@%s%W(B +

    Apache $B$,(B root $B$H$7$F5/F0$5$l$F!"JL$N%f!<%6$N8"8B$K0J9_$7$?>l9g$O(B + Linux $B$N%+!<%M%k$O%G%#%l%/%H%j$,%W%m%;%9$N8"8B$G=q$-9~$_2DG=$J>l9g$G$5$($b(B + $B%3%"%@%s%W$r(B$BL58z(B$B$K$7$^$9!#(BApache (2.0.46 $B0J9_(B) $B$O(B + Linux 2.4 $B0J9_$G$O%3%"%@%s%W$r9T$J$&$h$&$K:F;XDj$7$^$9$,!"$=$l$O(B + CoreDumpDirectory $B$rL@<(E*$K@_Dj$7$?$H$-$K(B + $B8B$j$^$9!#(B

    +
    +
    +
    + + +EnableExceptionHook +$B%/%i%C%7%e$N8e$KNc30%O%s%I%i$r +EnableExceptionHook On|Off +EnableExceptionHook Off +server config +leaderperchild +preforkthreadpool +worker +2.0.49 $B0J9_(B + + +

    $B0BA4>e$NM}M3$+$i!"(B--enable-exception-hook configure + $B%*%W%7%g%s$rM-8z$K$7$?>l9g$K$N$_!"$3$N%G%#%l%/%F%#%V$rMxMQ$G$-$^$9!#(B + $B30It%b%8%e!<%k$r%W%i%0%$%s$7$F!";R$,%/%i%C%7%e$7$?8e$K2?$+ + +

    $B$3$N$h$&$J30It%b%8%e!<%k$O!"4{$KFs$DB8:_$7$F$$$F!"(B + mod_whatkilledus $B$H(B mod_backtrace + $B$,$3$N%U%C%/$r3hMQ$7$^$9!#$3$l$i$N>\:Y$K$D$$$F$O(B Jeff Trawick + $B$5$s$N(B EnableExceptionHook site $B$r;2>H$7$F$/$@$5$$!#(B

    +
    +
    + + +Group +$B%j%/%(%9%H$K1~Ez$9$k:]$K=jB0$9$k%0%k!<%W(B +Group unix-group +Group #-1 +server config +beosleader +mpmt_os2perchildprefork +threadpoolworker +Apache 2.0 $B0J9_$G!"%0%m!<%P%k@_Dj$G$N$_M-8z$G$9!#(B + + +

    Group $B%G%#%l%/%F%#%V$G!"(B + $B%j%/%(%9%H$K1~Ez$9$k:]$K=jB0$7$F$*$/%0%k!<%W$r@_Dj$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$r;HMQ$9$k$?$a$K$O!"(B + $B%5!<%P$O:G=i$K(B root $B8"8B$G5/F0$5$l$F$$$kI,MW$,$"$j$^$9!#(B + $BHs(B root $B%f!<%6$G%5!<%P$r5/F0$7$?>l9g$O!";XDj$7$?%0%k!<%W$KJQ2=$G$-$:$K!"(B + $B7k2LE*$K5/F0$7$?%f!<%6$NB0$9$k%0%k!<%W$Gunix-group $B$O + +

    +
    $B%0%k!<%WL>(B
    +
    $B%0%k!<%W$rL>A0$G;2>H$7$^$9(B
    + +
    # $B$KB3$$$F%0%k!<%WHV9f(B
    +
    $B%0%k!<%W$r$rHV9f$G;2>H$7$^$9!#(B
    +
    + + $BNc(B + Group www-group + + +

    $B%5!<%P$rnobody $B$r;HMQ$9$k4IM}$^$7$$Lu$G$OI,$:$7$b$"$j$^$;$s!#(B

    + + $B%;%-%e%j%F%#(B +

    $B@53N$K$I$s$J$3$H$r$d$C$F$$$k$N$+!"$=$N4m81@-$rCN$i$J$$$G!"(B + Group ($B$d(B User) $B$r(B + root $B$K(B $B@_Dj$7$J$$$G$/$@$5$$!#(B

    +
    + +

    $BFC5-;v9`(B: $B$3$N%G%#%l%/%F%#%V$r(B + VirtualHost + $B$G;HMQ$9$k$3$H$O%5%]!<%H$5$l$J$/$J$j$^$7$?!#(BApache 2.0 $B$G(B + suexec $B$r@_Dj$7$?$$>l9g$O!"(B + SuexecUserGroup + $B$r;HMQ$7$F$/$@$5$$!#(B

    + + $BCm0U(B +

    Group $B%G%#%l%/%F%#%V$O(B + beos $B$H(B mpmt_os2 MPM + $B$K$bB8:_$7$^$9$,!" + + + + + +PidFile +$B%G!<%b%s$N%W%m%;%9(B ID +$B$r%5!<%P$,5-O?$9$k$?$a$N%U%!%$%k(B +PidFile filename +PidFile logs/httpd.pid +beosleader +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    PidFile $B%G%#%l%/%F%#%V$G!"(B + $B%G!<%b%s$N%W%m%;%9(B ID $B$r%5!<%P$,5-O?$9$k%U%!%$%k$r@_Dj$7$^$9!#(B + $B%U%!%$%kL>$,@dBP%Q%9$G$J$$>l9g$O!"(B + ServerRoot + $B$+$i$NAjBPE*$J$b$N$H$7$F07$o$l$^$9!#(B

    + + $BNc(B + PidFile /var/run/apache.pid + + +

    $B%5!<%P$,(B ErrorLog + $B$d(B TransferLog + $B$rJD$8$F3+$-D>$7$?$j!"@_Dj%U%!%$%k$r(B + $B:FFI9~$7$?$j$5$;$k$?$a$K!"%5!<%P$K%7%0%J%k$rAw$k$3$H$,$G$-$k$H(B + $BJXMx$J$3$H$,$"$j$^$9!#(B + $B$3$l$O(B SIGHUP (kill -1) $B%7%0%J%k$r(B PidFile + $B$K=q$+$l$F$$$k%W%m%;%9(B ID $B$KAw$k$3$H$G$G$-$^$9!#(B

    + +

    PidFile $B$K$O!"%m%0%U%!%$%k$N@_CV0LCV$d(B + $B%;%-%e%j%F%#(B + $B$HA4$/F1$8Cm0UE@$,$"$j$^$9!#(B

    + + $BCm0U(B +

    Apache 2 $B$G$O!"(B + apachectl + $B%9%/%j%W%H$N$_$r;HMQ$7$F%5!<%P$N(B ($B:F(B) $B5/F0$dDd;_$r(B + $B9T$J$&$3$H$r?d>)$7$F$$$^$9!#(B

    +
    +
    +
    + + +Listen +$B%5!<%P$,(B listen $B$9$k(BIP $B%"%I%l%9$H%]!<%HHV9f(B +Listen [IP-address:]portnumber +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchild +preforkthreadpoolworker + +Apache 2.0 $B$+$iI,MW$J%G%#%l%/%F%#%V(B + + +

    Listen $B%G%#%l%/%F%#%V$O(B Apache + $B$,FCDj$N(B IP $B%"%I%l%9$d%]!<%HHV9f$@$1$r(B listen $B$9$k$h$&$K;XDj$7$^$9!#(B + $B%G%U%)%k%H$G$OA4$F$N(B IP $B%$%s%?!<%U%'!<%9$N%j%/%(%9%H$K1~Ez$7$^$9!#(B + Listen $B%G%#%l%/%F%#%V$O(B + $B8=:_$OI,?\$N%G%#%l%/%F%#%V$H$J$j$^$7$?!#(B + $B$b$7@_Dj%U%!%$%k$K$J$1$l$P!"%5!<%P$O5/F0$K<:GT$7$^$9!#(B + $B$3$l$O0JA0$N%P!<%8%g%s$N(B Apache $B$+$iJQ99$N$"$C$?ItJ,$G$9!#(B

    + +

    Listen $B%G%#%l%/%F%#%V$G$O!"FCDj$N%]!<%H$"$k$$$O(B + $B%"%I%l%9$H%]!<%H$NAH$_9g$o$;$+$iF~$C$F$/$k%j%/%(%9%H$KBP$7$F(B + $B1~Ez$9$k$h$&$K;XDj$7$^$9!#(B + $B$b$7%]!<%HHV9f$@$1$,;XDj$5$l$?>l9g$O!"%5!<%P$OA4%$%s%?!<%U%'!<%9$N(B + $B;XDj$5$l$?%]!<%HHV9f$KBP$7$F(B listen $B$7$^$9!#(B + IP $B%"%I%l%9$,%]!<%H$H$H$b$K;XDj$5$l$?>l9g$O!"(B + $B%5!<%P$O;XDj$5$l$?%]!<%H$H%$%s%?!<%U%'!<%9$KBP$7$F(B listen + $B$7$^$9!#(B

    + +

    $BJ#?t$N%"%I%l%9$H%]!<%H$KBP$7$F(B listen $B$9$k$h$&$K!"(B + $BJ#?t$N(B Listen $B%G%#%l%/%F%#%V$r;H$&$3$H$b$G$-$^$9!#(B + $B%5!<%P$ONs5s$5$l$?%"%I%l%9$H%]!<%HA4$F$+$i$N%j%/%(%9%H$KBP$7$F(B + $B1~Ez$7$^$9!#(B

    + +

    $BNc$($P!"%5!<%P$,(B 80 $BHV%]!<%H$H(B 8000 $BHV%]!<%H$NN>J}$N(B + $B%3%M%/%7%g%s$rl9g$O!" + + + Listen 80
    + Listen 8000 +
    + +

    $BFs$D$NFCDj$N%$%s%?!<%U%'!<%9$H%]!<%HHV9f$+$i$N%3%M%/%7%g%s$r(B + $B + + + Listen 192.170.2.1:80
    + Listen 192.170.2.5:8000 +
    + +

    IPv6 $B%"%I%l%9$O3Q3g8L$G0O$^$J$1$l$P$J$j$^$;$s!#(B + $BNc$($P + + + Listen [fe80::a00:20ff:fea7:ccea]:80 + + + $B%(%i!<>r7o(B + $BF10l(B IP $B%"%I%l%9$H%]!<%H$NAH$K!"J#?t$N(B Listen + $B%G%#%l%/%F%#%V$r;XDj$7$F$7$^$&$H!"(B'Address already in use' + $B$H$$$&%(%i!<%a%C%;!<%8$r + + + +DNS $B$NLdBj(B +Apache +$B$,;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj(B + + + +ListenBackLog +$BJ]N1>uBV$N%3%M%/%7%g%s$N%-%e!<$N:GBgD9(B +ListenBacklog backlog +ListenBacklog 511 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    $BJ]N1>uBV$N%3%M%/%7%g%s$N%-%e!<$N:GBgD9$G$9!#(B + $B0lHLE*$K$OD4@0$9$kI,MW$O$"$j$^$;$s$7!"D4@0$OK>$^$7$/$"$j$^$;$s!#(B + $B$7$+$7!"(BTCP SYN $B%U%i%C%I%"%?%C%/$N>u672<$K$*$+$l$k>l9g$K!"(B + $BA}$d$7$?J}$,K>$^$7$$%7%9%F%`$b$"$j$^$9!#(B + listen(2) $B%7%9%F%`%3!<%k$N%P%C%/%m%0%Q%i%a!<%?$r(B + $B$4Mw2<$5$$!#(B

    + +

    $B$3$NCM$O(B OS $B$K$h$j!">.$5$J?t$KM^$($i$l$^$9!#(B + $BCM$O(B OS $BKh$K0[$J$C$F$$$^$9!#$^$?B?$/$N(B OS $B$G$O!"(B + $B%P%C%/%m%0$H$7$F;XDj$5$l$F$$$kCM$A$g$&$I$^$G;H$C$F$$$k$o$1$G$O$J$/!"(B + $B@_Dj$5$l$F$$$kCM$K4p$E$$$F(B ($BDL>o$O@_DjCM$h$j$bBg$-$JCM$r(B) + $B;H$C$F$$$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    +
    +
    + + +LockFile +$BNs2=$9$k$?$a$N%m%C%/%U%!%$%k$N0LCV(B +LockFile filename +LockFile logs/accept.lock +server config +leaderperchild +preforkthreadpoolworker + + + +

    AcceptMutex + $B$,(B fcntl $B$d(B flock + $B$K@_Dj$5$l$F;HMQ$5$l$F$$$k>l9g$K!";HMQ$5$l$k%m%C%/%U%!%$%k$X$N%Q%9$r(B + LockFile $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$ODL>o$O$=$N$^$^$K$7$F$*$-$^$9!#(B + $Blogs $B%G%#%l%/%H%j$,(B NFS + $B$G%^%&%s%H$5$l$F$$$k>l9g$J$I$KCM$rJQ$($^$9!#(B + $B$J$<$J$i(B$B%m%C%/%U%!%$%k$O%m!<%+%k%G%#%9%/$K(B + $BJ]B8$5$l$J$1$l$P$J$i$J$$(B$B$+$i$G$9!#(B + $B%a%$%s%5!<%P%W%m%;%9$N(B PID $B$,%U%!%$%kL>$K<+F0E*$KIU2C$5$l$^$9!#(B

    + + $B%;%-%e%j%F%#(B +

    /var/tmp + $B$H$$$C$?!"C/$G$b=q$-9~$a$k%G%#%l%/%H%j$K%U%!%$%k$r(B + $BCV$+$J$$(B$BJ}$,$h$$$G$9!#$J$<$J$i!"%5!<%P$,5/F0;~$K:n@.$9$k(B + $B%m%C%/%U%!%$%k$N:n@.<+BN$rK832$9$k$3$H$K$h$C$F!"(B + $BC/$G$b%5!<%S%95qH]%"%?%C%/$r0z$-5/$3$9$3$H$,$G$-$k$+$i$G$9!#(B

    +
    +
    +AcceptMutex +
    + + +MaxClients +$B%j%/%(%9%H$K1~Ez$9$k$?$a$K:n@.$5$l$k(B +$B;R%W%m%;%9$N:GBg8D?t(B +MaxClients number +$B>\:Y$O;HMQK!$r$4Mw2<$5$$!#(B +server config +beosleader +preforkthreadpoolworker + + + +

    MaxClients $B%G%#%l%/%F%#%V$O!"(B + $B1~Ez$9$k$3$H$N$G$-$kF1;~%j%/%(%9%H?t$r@_Dj$7$^$9!#(B + MaxClients $B@)8B?t$r1[$($k%3%M%/%7%g%s$ODL>o!"(B + ListenBacklog + $B%G%#%l%/%F%#%V$G@_Dj$7$??t$^$G%-%e!<$KF~$j$^$9!#(B + $BB>$N%j%/%(%9%H$N:G8e$^$GC#$7$F;R%W%m%;%9$,6u$/$H!"(B + $B + +

    $B%9%l%C%I$rMQ$$$J$$%5!<%P(B ($B$9$J$o$A(B prefork) + $B$G$O!"(BMaxClients + $B$O!"%j%/%(%9%H$K1~Ez$9$k$?$a$K5/F0$5$l$k(B + $B;R%W%m%;%9$N:GBg?t$H$J$j$^$9!#(B + $B%G%U%)%k%HCM$O(B 256 $B$G!"$3$l$rA}2C$5$;$?$$>l9g$O!"(B + ServerLimit + $B$NCM$bA}2C$5$;$kI,MW$,$"$j$^$9!#(B

    + +

    $B%9%l%C%I$rMQ$$$k%5!<%P$d!"%O%$%V%j%C%I%5!<%P(B ($B$9$J$o$A(B + beos worker) + $B$G$O!"(BMaxClients + $B$O!"%/%i%$%"%s%H$K1~Ez$G$-$k%9%l%C%I$NAm?t$r@)8B$7$^$9!#(B + beos $B$G$N%G%U%)%k%HCM$O(B 50 $B$G$9!#(B + $B%O%$%V%j%C%I(B MPM $B$G$N%G%U%)%k%HCM$O(B 16 + ServerLimit + $B$N(B 25 $BG\(B (ThreadsPerChild) $B$G$9!#(B + MaxClients + $B$r(B 16 $B%W%m%;%90J>eI,MW$JCM$^$GA}2C$5$;$?$$>l9g$O!"(B + ServerLimit + $B$bA}2C$5$;$kI,MW$,$"$j$^$9!#(B

    +
    +
    + + +MaxMemFree +free() $B$,8F$P$l$J$$8B$j!"(B +$B +MaxMemFree KBytes +MaxMemFree 0 +server config +beosleader +mpm_netwareprefork +threadpoolworkermpm_winnt + + +

    MaxMemFree $B%G%#%l%/%F%#%V$O(B + free() $B$,8F$P$l$J$$8B$j!"(B + $B + + + + +MaxRequestsPerChild +$B8D!9$N;R%5!<%P$,2TF/Cf$K07$&%j%/%(%9%H?t$N>e8B(B +MaxRequestsPerChild number +MaxRequestsPerChild 10000 +server config +leadermpm_netware +mpm_winntmpmt_os2 +perchildprefork +threadpoolworker + + +

    MaxRequestsPerChild $B%G%#%l%/%F%#%V$O!"(B + $B8D!9$N;R%5!<%P%W%m%;%9$,07$&$3$H$N$G$-$k%j%/%(%9%H$N@)8B?t$r(B + $B@_Dj$7$^$9!#(BMaxRequestsPerChild + $B8D$N%j%/%(%9%H$N8e$K!";R%W%m%;%9$O=*N;$7$^$9!#(B + MaxRequestsPerChild $B$,(B 0 + $B$K@_Dj$5$l$F$$$k>l9g$O!"%W%m%;%9$O4|8B@Z$l$K$h$j=*N;$9$k$3$H$O$"$j$^$;$s!#(B

    + + $B$=$NB>$N%G%U%)%k%HCM(B +

    mpm_netware $B$H(B mpm_winnt + $B$G$N%G%U%)%k%HCM$O(B 0 $B$G$9!#(B

    +
    + +

    MaxRequestsPerChild + $B$rHs%<%m$K@)8B$9$k$3$H$K$O!"Fs$D$NMxE@$,$"$j$^$9(B:

    + +
      +
    • ($B6vH/E*$J(B) $B%a%b%j!<%j!<%/$,5/$3$C$?>l9g$K(B + $B%W%m%;%9$,>CHq$9$k%a%b%j$NAmNL$r@)8B$G$-$k(B
    • + +
    • $B%W%m%;%9$KM-8B$N%i%$%U%?%$%`$r@_Dj$9$k$3$H$G!"(B + $B%5!<%PIi2Y$,2<$,$C$?;~$K%W%m%;%9?t$r>/$J$/$9$k$3$H$,$G$-$k(B
    • +
    + + $BCm(B +

    KeepAlive $B%j%/%(%9%H$N>l9g$O!"(B + $B0l$DL\$N%j%/%(%9%H$@$1$,$3$N@)8B$K3:Ev$7$^$9!#(B + $B$B%3%M%/%7%g%s(B$B?t$r(B + $B@)8B$9$k$h$&$K5sF0$,JQ2=$7$^$9!#(B

    +
    +
    +
    + + +MaxSpareThreads +$B%"%$%I%k%9%l%C%I$N:GBg?t(B +MaxSpareThreads number +$B>\:Y$O;HMQK!$r$4Mw2<$5$$!#(B +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    $B%"%$%I%k$J%9%l%C%I$N:GBg?t$G$9!#0[$J$k(B MPM $B$G$O$=$l$>$l!"(B + $B$3$N%G%#%l%/%F%#%V$O0[$J$k + +

    perchild $B$G$O!"(B + $B%G%U%)%k%H$O(B MaxSpareThreads 10 $B$G$9!#(B + $B$3$N(B MPM $B$O%"%$%I%k%9%l%C%I?t$r!"$=$l$>$l$N;R%W%m%;%9$4$H$K4F;k$7$^$9!#(B + $B;R%W%m%;%9$K%"%$%I%k%9%l%C%I$,B?$9$.$k>l9g$O!"(B + $B%5!<%P$O$=$N;R%W%m%;%9$K4^$^$l$k%9%l%C%I$r=*N;$7;O$a$^$9!#(B

    + +

    worker, leader, + threadpool $B$G$O!"(B + $B%G%U%)%k%H$O(B MaxSpareThreads 250 $B$G$9!#(B + $B$3$N(B MPM $B$O%"%$%I%k%9%l%C%I?t$r%5!<%PA4BN$G4F;k$7$^$9!#(B + $B%5!<%P$G%"%$%I%k%9%l%C%I?t$,B?$9$.$k>l9g$O!"(B + $B$3$N?t;z$h$j$b>/$J$$?t$K$J$k$^$G;R%W%m%;%9$r=*N;$7$^$9!#(B

    + +

    mpm_netware $B$G$O!"(B + $B%G%U%)%k%H$O(B MaxSpareThreads 100 $B$G$9!#(B + $B$3$N(B MPM $B$O%7%s%0%k%W%m%;%9$G + +

    beos $B$H(B mpmt_os2 $B$O(B + mpm_netware $B$H;w$?5sF0$r$7$^$9!#(B + beos $B$G$N%G%U%)%k%HCM$O(B MaxSpareThreads 50 + $B$G$9!#(Bmpmt_os2 $B$G$N%G%U%)%k%HCM$O(B 10 + $B$G$9!#(B

    + + $B@)8B;v9`(B +

    MaxSpareThreads $B$N$C$F<+F0E*$KJd@5$7$^$9!#(B

    +
      +
    • perchild $B$G$O!"(B + MaxSpareThreads $B$,(B + ThreadLimit + $B$HEy$7$$$+$=$l0J2<$G$"$kI,MW$,$"$j$^$9!#(B
    • + +
    • mpm_netware $B$O(B + MinSpareThreads + $B$h$j$bBg$-$$I,MW$,$"$j$^$9!#(B
    • + +
    • leader, threadpool, + worker $B$G$O!"(B + MinSpareThreads $B$H(B + ThreadsPerChild + $B$G7h$^$kAmOB$HEy$7$$$+Bg$-$$I,MW$,$"$j$^$9!#(B
    • +
    +
    +
    +MinSpareThreads +StartServers +
    + + +MinSpareThreads +$B%j%/%(%9%H$K1~Ez$9$k$3$H$N$G$-$k(B +$B%"%$%I%k%9%l%C%I?t$N:G>.?t(B +MinSpareThreads number +$B>\:Y$O;HMQJ}K!$r$4Mw2<$5$$!#(B +server config +beosleader +mpm_netwarempmt_os2 +perchildthreadpoolworker + + + +

    $B%j%/%(%9%H$K1~Ez$9$k%9%l%C%I?t$N:G>.CM$G$9!#(B + $B0[$J$k(B MPM $B$G$O$=$l$>$l!"(B + $B$3$N%G%#%l%/%F%#%V$O0[$J$k + +

    perchild $B$G$O!"(B + $B%G%U%)%k%H$O(B MinSpareThreads 5 $B$G!"(B + $B%"%$%I%k%9%l%C%I?t$r;R%W%m%;%9Kh$K4F;k$7$^$9!#(B + $B$b$7;R%W%m%;%9$K==J,$J?t$N%9%l%C%I$,$J$1$l$P!"(B + $B%5!<%P$O$=$N;R%W%m%;%9$K?7$7$$%9%l%C%I$r:n$j;O$a$^$9!#(B + $B$G$9$+$i!"(BNumServers + $B$r(B 10 $B$K!"(BMinSpareThreads $B$r(B + 5 $B$K$7$?>l9g$O!":G>.$G$b(B 50 $B$N%"%$%I%k%9%l%C%I$,(B + $B%7%9%F%`>e$K$"$k$3$H$K$J$j$^$9!#(B

    + +

    worker, leader, + threadpool $B$G$O!"(B + $B%G%U%)%k%H$O(B MinSpareThreads 75 $B$G!"(B + $B%"%$%I%k%9%l%C%I?t$r%5!<%PA4BN$G4F;k$7$^$9!#(B + $B$b$7%5!<%P$K==J,$J?t$N%"%$%I%k%9%l%C%I$,$J$1$l$P!"(B + $B%"%$%I%k%9%l%C%I?t$,$3$N?t$h$j$bBg$-$/$J$k$^$G(B + $B?7$7$$;R%W%m%;%9$,@8@.$5$l$^$9!#(B

    + +

    mpm_netware $B$G$O!"(B + $B%G%U%)%k%H$O(B MinSpareThreads 10 $B$G!"(B + $B%7%s%0%k%W%m%;%9(B MPM $B$G$9$N$G!"%5!<%PA4BN$G4IM}$5$l$^$9!#(B

    + +

    beos $B$H(B mpmt_os2 $B$O!"(B + mpm_netware$B$K$h$/;w$F$$$^$9!#(B + beos $B$G$N%G%U%)%k%H$O(B MinSpareThreads 1 + $B$G$9!#(Bmpmt_os2 $B$G$N%G%U%)%k%H$O(B + 5 $B$G$9!#(B

    +
    +MaxSpareThreads +StartServers +
    + + +ScoreBoardFile +$B;R%W%m%;%9$HO"7H$9$k$?$a$N%G!<%?$rJ]B8$9$k(B +$B%U%!%$%k$N0LCV(B +ScoreBoardFile file-path +ScoreBoardFile logs/apache_status +server config +beosleader +mpm_winntperchildprefork +threadpoolworker + + +

    Apache $B$O?F%W%m%;%9$H;R%W%m%;%94V$NDL?.$K%9%3%"%\!<%I$rMQ$$$^$9!#(B + $B$3$NDL?.5!G=$K%U%!%$%k$rI,MW$H$9$k%"!<%-%F%/%A%c$b$"$j$^$9!#(B + $B%U%!%$%k$,;XDj$5$l$F$$$J$1$l$P!"(BApache $B$O$^$:%a%b%j>e(B + ($BF?L>6&M-%a%b%j(B) $B$K%9%3%"%\!<%I$r:n$m$&$H$7!"$=$l$,<:GT$9$k$H(B + $B%G%#%9%/>e$K%U%!%$%k(B ($B%U%!%$%k%Y!<%9$N6&M-%a%b%j(B) $B$r:n$m$&$H$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$r;XDj$9$k$H!"(BApache + $B$OI,$:%G%#%9%/$K%U%!%$%k$r@8@.$7$^$9!#(B

    + + $BNc(B + ScoreBoardFile /var/run/apache_status + + +

    $B%U%!%$%k%Y!<%9$N6&M-%a%b%j$O!"%5!<%I%Q!<%F%#!<@=$N%"%W%j%1!<%7%g%s$G(B + $B%9%3%"%\!<%I$KD>@\%"%/%;%9$9$kI,MW$,$"$k>l9g$KLr$KN)$A$^$9!#(B

    + +

    ScoreBoardFile $B$r;H$&>l9g!"(B + RAM $B%G%#%9%/>e$KCV$/$H%9%T!<%I$,8~>e$9$k$G$7$g$&!#(B + $B$7$+$7!"%m%0%U%!%$%k$N@_CV0LCV$d(B + $B%;%-%e%j%F%#(B + $B$HF1MM$NCm0UE@$,$"$k$N$G!"Cm0U$7$F$/$@$5$$!#(B

    +
    +Apache $B$NDd;_$H:F5/F0(B +
    + + +SendBufferSize +TCP $B%P%C%U%!%5%$%:(B +SendBufferSize bytes +SendBufferSize 0 +server config +beosleader +mpm_netwarempm_winnt +mpmt_os2perchildprefork +threadpoolworker + + +

    $B%5!<%P$O(B TCP $B%P%C%U%!%5%$%:$r;XDj$5$l$?%P%$%H?t$K@_Dj$7$^$9!#(B + $B9bB.$G9b%l%$%F%s%7$J4D6-$G(B + ($BNc(B 100ms $BDxEY!"BgN&2#CG9bB.DL?.O)$J$I(B) + $B8E$$0lHLE*$J(B OS $B$N%G%U%)%k%HCM$rA}$d$9$N$KHs>o$KJXMx$G$9!#(B

    + +

    0$B$K$7$?>l9g!"(BOS $B$N%G%U%)%k%HCM$,;HMQ$5$l$^$9!#(B

    +
    +
    + + +ServerLimit +$B@_Dj2DG=$J%5!<%P%W%m%;%9?t$N>e8B(B +ServerLimit number +$B>\:Y$O;HMQK!$r;2>H(B +server config +leaderperchild +preforkthreadpoolworker + + + +

    prefork MPM $B$N>l9g$O!"$3$N%G%#%l%/%F%#%V$O(B + Apache $B%W%m%;%92TF/Cf$K$*$1$k(B + MaxClients + $B$K@_Dj2DG=$J>e8BCM$r@_Dj$9$k$3$H$K$J$j$^$9(B + ($BLuCm(B: prefork $B$N>l9g$OF1;~%/%i%$%"%s%H?t(B = $B%5!<%P%W%m%;%9?t$J$N$G(B) $B!#(B + worker MPM $B$N>l9g$K$O!"$3$N%G%#%l%/%F%#%V$O(B + ThreadLimit + $B%G%#%l%/%F%#%V$HAH$_9g$o$;$F!"(B + Apache $B%W%m%;%92TF/Cf$K$*$1$k(B + MaxClients + $B$K@_Dj2DG=$J>e8BCM$r@_Dj$9$k$3$H$K$J$j$^$9!#(B + $B:F5/F0Cf$K$3$N%G%#%l%/%F%#%V$rJQ99$7$F$bL5;k$5$l$^$9$,!"(B + MaxClients + $B$O:F5/F0Cf$K=$@5$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$r;HMQ$9$k:]$OFC$KCm0U$7$F$/$@$5$$!#(B + ServerLimit $B$,I,MW0J>e$KBg$-$JCM$K(B + $B@_Dj$5$l$?>l9g$O!"M>7W$JL$;HMQ6&M-%a%b%j$,3d$jEv$F$i$l$^$9!#(B + ServerLimit $B$H(B + MaxClients + $B$,%7%9%F%`$N07$($kHO0O$r1[$($?@_DjCM$K$J$C$F$$$k$H!"(B + Apache $B$O5/F0$7$J$$$+!"5/F0$7$F$bIT0BDj$K$J$k$G$7$g$&!#(B

    + +

    prefork MPM $B$G$O!"(B + MaxClients + $B$r(B 256 ($B%G%U%)%k%H(B) $B$h$j$bBg$-$JCM$K@_Dj$9$kI,MW$,$"$k;~$K$@$1;HMQ$7$F$/$@$5$$!#(B + $B4uK>$N(B MaxClients + $B?t$H$/$i$Y$F!"I,MW0J>e$KBg$-$JCM$r;XDj$9$k$3$H$OHr$1$F$/$@$5$$!#(B

    + +

    worker, leader, + threadpool MPM $B$G$O!"(B + MaxClients $B$H(B + ThreadsPerChild + $B$N@_Dj$G(B 16 $B%5!<%P%W%m%;%9(B ($B%G%U%)%k%H(B) + $B0J>eI,MW$K$J$k>l9g$K$N$_;HMQ$7$F$/$@$5$$!#4uK>$N(B + MaxClients $B$H(B + ThreadsPerChild + $B$H$/$i$Y$F!"I,MW$H$J$k%5!<%P%W%m%;%9?t0J>e$KBg$-$JCM$r(B + $B@_Dj$9$k$3$H$OHr$1$F$/$@$5$$!#(B

    + +

    perchild MPM $B$G$O!"(B + NumServers $B$r(B 8 ($B%G%U%)%k%H(B) + $B$h$m$$$bBg$-$JCM$K@_Dj$9$kI,MW$,$"$k$H$-$K$N$_;HMQ$7$F$/$@$5$$!#(B

    + + $BCm0U(B +

    ServerLimit 20000 $B$H$$$&@)8BIU$-$G%3%s%Q%$%k$5$l$F$$$^$9(B + (prefork MPM $B$G$O(B 200000) $B!#(B + $B$3$l$O%9%Z%k%_%9$K$h$C$F8m$C$F9s$$>u67$K$J$k$N$r!"(B + $B2sHr$9$k$?$a$N=hCV$G$9!#(B

    +
    +
    +Apache $B$NDd;_$H:F5/F0(B +
    + + +StartServers +$B5/F0;~$K@8@.$5$l$k;R%5!<%P%W%m%;%9$N?t(B +StartServers number +$B>\:Y$O;HMQJ}K!$r;2>H(B +server config +leadermpmt_os2 +preforkthreadpoolworker + + + +

    StartServers $B%G%#%l%/%F%#%V$O!"(B + $B5/F0;~$K@8@.$5$l$k;R%5!<%P%W%m%;%9$N?t$r@_Dj$7$^$9!#(B + $B%W%m%;%9?t$OIi2Y$K1~$8$FF0E*$K@)8f$5$l$^$9$N$G!"(B + $BDL>o$O$3$NCM$rD4@0$9$kM}M3$O$"$^$j$J$$$G$7$g$&!#(B

    + +

    $B%G%U%)%k%HCM$O(B MPM $B$4$H$K0[$J$j$^$9!#(B + leader, threadpool, + worker $B$O(B StartServers 3 $B$G$9!#(B + prefork $B$O(B 5 $B$G!"(B + mpmt_os2 $B$O(B 2 $B$G$9!#(B

    +
    +
    + + +StartThreads +$B5/F0;~$K@8@.$5$l$k%9%l%C%I$N?t(B +StartThreads number +$B>\:Y$O;HMQJ}K!$r;2>H(B +server config +beosmpm_netware +perchild + + +

    $B5/F0;~$K@8@.$5$l$k%9%l%C%I$N?t$G$9!#(B + $B%9%l%C%I?t$OIi2Y$K1~$8$FF0E*$K@)8f$5$l$^$9$N$G!"(B + $BDL>o$O$3$NCM$rD4@0$9$kM}M3$O$"$^$j$J$$$G$7$g$&!#(B

    + +

    perchild $B$G$N%G%U%)%k%H$O(B + StartThreads 5 $B$G!"$3$N%G%#%l%/%F%#%V$O5/F0;~$K(B + $B%W%m%;%9Kh$N%9%l%C%I?t$rDI@W$7$^$9!#(B

    + +

    mpm_netware $B$G$N%G%U%)%k%H$O(B + StartThreads 50 $B$G!"(B + $B$3$N>l9g%W%m%;%9$O0l$D$7$+$J$$$N$G!"(B + $B5/F0;~$K%j%/%(%9%H$K1~Ez$9$k%9%l%C%I$NAm?t$H$J$j$^$9!#(B

    + +

    beos $B$G$N%G%U%)%k%H$O(B StartThreads + 10 $B$G$9!#(B + $B$^$?!"5/F0;~$K@8@.$5$l$k%9%l%C%I$NAm?t$K$bH?1G$5$l$^$9!#(B

    +
    +
    + + +ThreadLimit +$B@_Dj2DG=$J;R%W%m%;%9Kh$N%9%l%C%I?t$N>e8B$r(B +$B@_Dj$7$^$9(B +ThreadLimit number +$B>\:Y$O;HMQJ}K!$r;2>H(B +server config +leadermpm_winnt +perchildthreadpoolworker + +Apache 2.0.41 $B$H$=$l0J9_$N(B mpm_winnt +$B$GMxMQ2DG=(B + + +

    $B$3$N%G%#%l%/%F%#%V$O(B + Apache $B%W%m%;%92TF/Cf$K$*$1$k(B + ThreadsPerChild + $B$K@_Dj2DG=$J>e8BCM$r@_Dj$7$^$9!#:F5/F0;~$K$3$N%G%#%l%/%F%#%V$NCM$r(B + $BJQ99$7$F$bL5;k$5$l$^$9$,!"(B + ThreadsPerChild + $B$O:F5/F0Cf$K!"$3$N%G%#%l%/%F%#%V$G;XDj$5$l$?>e8BCM$^$G(B + $BJQ99$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B$3$N%G%#%l%/%F%#%V$r;HMQ$9$k:]$OFC$KCm0U$7$F$/$@$5$$!#(B + ThreadLimit $B$,(B + ThreadsPerChild + $B$h$j$b$:$C$HBg$-$JCM$K@_Dj$5$l$?>l9g$O!"(B + $BM>7W$JL$;HMQ6&M-%a%b%j$,3d$jEv$F$i$l$F$7$^$$$^$9!#(B + ThreadLimit $B$,(B + ThreadsPerChild + $B$NN>J}$,%7%9%F%`$N07$($kHO0O$rD6$($F$$$k>l9g$O!"(B + Apache $B$O5/F0$7$J$$$+!"5/F0$7$?$H$7$F$bIT0BDj$K$J$k$G$7$g$&!#(B + $B$3$N%G%#%l%/%F%#%V$NCM$O:#;HMQ$7$F$$$k(B Apache $B$N(B ThreadsPerChild $B$NM=A[>e8BCM$r(B + $BD6$($?CM$K$O@_Dj$7$J$$$G$/$@$5$$!#(B +

    + +

    ThreadLimit $B$N%G%U%)%k%HCM$O(B + mpm_winnt $B$N$H$-$O(B 1920 $B$G!"(B + $BB>$N>l9g$O(B 64 $B$G$9!#(B

    + + $BCm0U(B +

    ThreadLimit 20000 (mpm_winnt + $B$N>l9g$O(B ThreadLimit 15000 ) + $B$H$$$&@)8BIU$-$G%3%s%Q%$%k$5$l$F$$$^$9!#(B + $B$3$l$O%9%Z%k%_%9$K$h$C$F8m$C$F9s$$>u67$K$J$k$N$r!"(B + $B2sHr$9$k$?$a$N=hCV$G$9!#(B

    +
    +
    +
    + + +ThreadsPerChild +$B;R%W%m%;%9$=$l$>$l$K@8@.$5$l$k%9%l%C%I?t(B +ThreadsPerChild number +$B>\:Y$O;HMQJ}K!$r;2>H(B +server config +leadermpm_winnt +threadpoolworker + + +

    $B$3$N%G%#%l%/%F%#%V$O!"$=$l$>$l$N;R%W%m%;%9$G@8@.$5$l$k(B + $B%9%l%C%I?t$r@_Dj$7$^$9!#(B + $B;R%W%m%;%9$O3+;O;~$K$3$l$i$N%9%l%C%I$r@8@.$7$F!"(B + $B$=$N8e$O@8@.$7$^$;$s!#(Bmpm_winnt $B$N$h$&$J!"(B + $B;R%W%m%;%9$,0l$D$7$+$J$$$h$&$J(B MPM $B$rMxMQ$7$F$$$k$N$G$"$l$P!"(B + $B$3$NCM$O%5!<%P$NIi2YA4BN$r==J,worker $B$N$h$&$J!"(B + $B;R%W%m%;%9$,J#?t$"$k$h$&$J(B MPM $B$rMxMQ$7$F$$$k$N$G$"$l$P!"(B + $B%5!<%P$NDL>oIi2Y$r==J,07$($kDxEY$K!"(B + $B%9%l%C%IAm?t(B$B$,B?$/$J$1$l$P$J$j$^$;$s!#(B

    + +

    mpm_winnt$B$G$N(B ThreadsPerChild + $B$N%G%U%)%k%HCM$O(B 64 $B$G!"B>$N>l9g$O(B + 25 $B$G$9!#(B

    +
    +
    + + +ThreadStackSize +$B%/%i%$%"%s%H$N%3%M%/%7%g%s$r +ThreadStackSize size +NetWare $B$G$O(B 65536$B!#B>$N(B OS $B$G$O0c$C$?CM(B +server config +leadermpm_netware +mpm_winntperchild +threadpoolworker + +2.1 $B0J9_(B + + +

    $B%/%i%$%"%s%H%3%M%/%7%g%s$rThreadStackSize $B%G%#%l%/%F%#%V$G;XDj$7$^$9!#(B + $BBgDq$N>l9g(B OS $B$N;XDj$7$F$$$k%9%?%C%/%5%$%:$N%G%U%)%k%HCM$O(B + $BE,@Z$J$b$N$G$9$,!"D4@0$,I,MW$K$J$k>l9g$b$"$j$^$9(B:

    + +
      +
    • $B%9%l%C%I%9%?%C%/%5%$%:$N%G%U%)%k%HCM$,Hf3SE*>.$5$/@_Dj$5$l$F$$$k(B + $B%W%i%C%H%[!<%`(B ($BNc$($P(B HP-UX) $B$G$O!"<+F0JQ?tMQ$NNN0h$GBg$-$JMFNL$r(B + $B;HMQ$9$k%5!<%I%Q!<%F%#@=%b%8%e!<%k$N$?$a$K(B Apache $B$,%/%i%C%7%e$9$k(B + $B>l9g$b$"$j$^$9!#$=$N%b%8%e!<%k$OB>$N%W%i%C%H%[!<%`$G$O(B + $B%9%?%C%/%5%$%:$,Bg$-$$$?$a$K!"2wD4$KF0:n$9$k$+$b$7$l$^$;$s!#(B + $B$3$N%?%$%W$N%/%i%C%7%e$O!"(BThreadStackSize + $B$G(B OS $B$N%G%U%)%k%HCM$h$jBg$-$JCM$r;XDj$9$k$3$H$G2r7h$7$^$9!#(B + $B%5!<%I%Q!<%F%#@=%b%8%e!<%k$G$3$N=hCV$,I,MW$G$"$k$H5-:\$5$l$F$$$k(B + $B>l9g$+!"(BApache $B$N=PNO$9$k%a%C%;!<%8$G%9%l%C%I%9%?%C%/%5%$%:$,(B + $B>.$5$9$.$k$H;XE&$5$l$F$$$k>l9g$K$N$_!"$3$ND4@0$r$7$F$/$@$5$$!#(B
    • + +
    • $B%G%U%)%k%H%9%l%C%I%9%?%C%/%5%$%:$,!"(BWeb $B%5!<%PMQES$KI,MW$JNL$h$j$b(B + $BL@$i$+$KBg$-$9$.$k>l9g!"(BThreadStackSize + $B$r(B OS $B$N%G%U%)%k%HCM$h$j$b>.$5$JCM$K$9$k$3$H$G!";R%W%m%;%9$"$?$j$N(B + $B%9%l%C%I?t$r$h$jB?$/;}$?$;$i$l$k$h$&$K$J$j$^$9!#(B + $B$3$N%?%$%W$ND4@0$O!"%F%9%H4D6-$G%&%'%V%5!<%P$r40A4$K(B + $B%F%9%H$G$-$k>l9g$K8B$C$F9T$J$&$Y$-$G$9!#(B + $B$^$l$KB??t$N%9%?%C%/$,MW5a$5$l$k%j%/%(%9%H$rThreadStackSize + $B$N@_Dj$,C$5$l$k>l9g$,$"$j$^$9!#(B
    • +
    +
    +
    + + +User +$B%j%/%(%9%H$K1~Ez$9$k:]$KMQ$$$k%f!<%6(B ID +User unix-userid +User #-1 +server config +leaderperchild +preforkthreadpoolworker + +Apache 2.0 $B0J9_$G!"%0%m!<%P%k@_Dj$G$N$_M-8z$G$9!#(B + + + +

    User $B%G%#%l%/%F%#%V$O(B + $B%5!<%P$,%j%/%(%9%H$K1~Ez$9$k:]$KMQ$$$k%f!<%6(B ID $B$r@_Dj$7$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$r;HMQ$9$k$?$a$K$O!"%9%?%s%I%"%m%s7?$N(B + $B%5!<%P$O:G=i$K(B root $B8"8B$G5/F0$5$l$F$$$kI,MW$,$"$j$^$9!#(B + $BHs(B root $B%f!<%6$G%5!<%P$r5/F0$7$?>l9g$O!"(B + $B8"8B$NDc$$%f!<%6$X$HJQ$o$k$3$H$,$G$-$:!"(B + $B7k6I85$N%f!<%6$N%W%m%;%9$H$7$Froot $B$G5/F0$7$?>l9g$K?F%W%m%;%9$,(B root + $B$H$7$Fo$JF0:n$G$9!#(B + Unix-userid $B$O + +

    +
    $B%f!<%6L>(B
    +
    $B%f!<%6$rL>A0$G;2>H$7$^$9!#(B
    + +
    # $B$KB3$$$F%f!<%6HV9f(B
    +
    $B%f!<%6$rHV9f$G;2>H$7$^$9!#(B
    +
    + +

    $B$3$N%f!<%6$O!"30It$K8+$;$k$h$&$K0U?^$7$F$$$J$$%U%!%$%k$K!"(B + $B%"%/%;%92DG=$K$J$C$F$7$^$&$h$&$J8"8B$r;}$D$Y$-$G$O$J$$$G$9$7!"(B + $BF1MM$K(B HTTP $B%j%/%(%9%H$KBP$7$F1~Ez$9$k$h$&$K0U?^$7$F$$$J$$(B + $Bnobody $B%f!<%6$r;HMQ$9$k4IM}o$KK>$^$7$$$o$1$G$O$"$j$^$;$s!#(B + $B$J$<$J$i(B nobody $B%f!<%6$O!"%7%9%F%`$G(B + $BB>$NLr3d$rC4$C$F$$$k$+$bCN$l$J$$$+$i$G$9!#(B

    + + $B%;%-%e%j%F%#(B +

    $B@53N$K$I$s$J$3$H$r$d$C$F$$$k$N$+!"$=$N4m81@-$rCN$i$J$$$G!"(B + User ($B$d(B Group) $B$r(B root $B$K(B + $B@_Dj$7$J$$$G$/$@$5$$!#(B

    +
    + +

    perchild MPM $B$G$O!"0[$J$k%f!<%6(B ID + $B$GJ#?t$N%P!<%A%c%k%[%9%H$rF0$+$9$3$H$rL\E*$H$7$F$$$^$9$,!"(B + User $B$O!"AssignUserID + $B%G%#%l%/%F%#%V$r;}$?$J$$(B VirtualHost $B%;%/%7%g%s$X$N(B + $B%U%)!<%k%P%C%/$H$rDj5A$9$k$3$H$K$J$j$^$9!#(B

    + +

    $BFC5-;v9`(B: $B$3$N%G%#%l%/%F%#%V$r(B + VirtualHost + $B$G;HMQ$9$k$3$H$O%5%]!<%H$5$l$J$/$J$j$^$7$?!#(B + suexec $B8~$1$K%5!<%P$r@_Dj$9$k$N$G$"$l$P!"(B + SuexecUserGroup + $B$r;HMQ$7$F$/$@$5$$!#(B

    + + $BCm0U(B +

    User $B%G%#%l%/%F%#%V$O(B + beos $B$H(B mpmt_os2 MPM + $B$K$bB8:_$7$^$9$,!" + + + + + diff --git a/trunk/docs/manual/mod/mpm_common.xml.meta b/trunk/docs/manual/mod/mpm_common.xml.meta new file mode 100644 index 0000000000..ae1fa4b41f --- /dev/null +++ b/trunk/docs/manual/mod/mpm_common.xml.meta @@ -0,0 +1,13 @@ + + + + mpm_common + /mod/ + .. + + + de + en + ja + + diff --git a/trunk/docs/manual/mod/mpm_netware.html b/trunk/docs/manual/mod/mpm_netware.html new file mode 100644 index 0000000000..03b1ca93bb --- /dev/null +++ b/trunk/docs/manual/mod/mpm_netware.html @@ -0,0 +1,3 @@ +URI: mpm_netware.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mpm_netware.html.en b/trunk/docs/manual/mod/mpm_netware.html.en new file mode 100644 index 0000000000..fe5e0d31e3 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_netware.html.en @@ -0,0 +1,109 @@ + + + +mpm_netware - Apache HTTP Server + + + + + +

    +
    <-
    + +
    +

    Apache MPM netware

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare
    Status:MPM
    Module Identifier:mpm_netware_module
    Source File:mpm_netware.c
    +

    Summary

    + +

    This Multi-Processing Module (MPM) implements an exclusively + threaded web server that has been optimized for Novell + NetWare.

    + +

    The main thread is responsible for launching child + worker threads which listen for connections and serve them when they + arrive. Apache always tries to maintain several spare + or idle worker threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + child threads to be spawned before their requests can be + served.

    + +

    The StartThreads, + MinSpareThreads, + MaxSpareThreads, and + MaxThreads + regulate how the main thread creates worker threads to serve + requests. In general, Apache is very self-regulating, so most + sites do not need to adjust these directives from their default + values. Sites with limited memory may need to decrease MaxThreads to keep the server from + thrashing (spawning and terminating idle threads). More information + about tuning process creation is provided in the performance hints + documentation.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing old + ones and launching new ones. On the NetWare OS it is highly + recommended that this directive remain set to 0. This allows worker + threads to continue servicing requests indefinitely.

    +
    + + +
    top
    +

    MaxThreads Directive

    + + + + + + + +
    Description:Set the maximum number of worker threads
    Syntax:MaxThreads number
    Default:MaxThreads 2048
    Context:server config
    Status:MPM
    Module:mpm_netware
    +

    The MaxThreads directive sets the desired + maximum number worker threads allowable. The default value is + also the compiled in hard limit. Therefore it can only be lowered, + for example:

    + +

    + MaxThreads 512 +

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_netware.xml b/trunk/docs/manual/mod/mpm_netware.xml new file mode 100644 index 0000000000..7985902c64 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_netware.xml @@ -0,0 +1,106 @@ + + + + + + + + +mpm_netware +Multi-Processing Module implementing an exclusively threaded web + server optimized for Novell NetWare +MPM +mpm_netware.c +mpm_netware_module + + +

    This Multi-Processing Module (MPM) implements an exclusively + threaded web server that has been optimized for Novell + NetWare.

    + +

    The main thread is responsible for launching child + worker threads which listen for connections and serve them when they + arrive. Apache always tries to maintain several spare + or idle worker threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + child threads to be spawned before their requests can be + served.

    + +

    The StartThreads, + MinSpareThreads, + MaxSpareThreads, and + MaxThreads + regulate how the main thread creates worker threads to serve + requests. In general, Apache is very self-regulating, so most + sites do not need to adjust these directives from their default + values. Sites with limited memory may need to decrease MaxThreads to keep the server from + thrashing (spawning and terminating idle threads). More information + about tuning process creation is provided in the performance hints + documentation.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing old + ones and launching new ones. On the NetWare OS it is highly + recommended that this directive remain set to 0. This allows worker + threads to continue servicing requests indefinitely.

    +
    +Setting which addresses and + ports Apache uses + + +Listen + +ListenBacklog + +MaxMemFree + +MaxRequestsPerChild + +SendBufferSize + +MaxSpareThreads + +MinSpareThreads + +StartThreads + +ThreadStackSize + + + +MaxThreads +Set the maximum number of worker threads +MaxThreads number +MaxThreads 2048 +server config + + +

    The MaxThreads directive sets the desired + maximum number worker threads allowable. The default value is + also the compiled in hard limit. Therefore it can only be lowered, + for example:

    + + + MaxThreads 512 + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_netware.xml.meta b/trunk/docs/manual/mod/mpm_netware.xml.meta new file mode 100644 index 0000000000..9cc16991d7 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_netware.xml.meta @@ -0,0 +1,11 @@ + + + + mpm_netware + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/mpm_winnt.html b/trunk/docs/manual/mod/mpm_winnt.html new file mode 100644 index 0000000000..c5d89ac935 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.html @@ -0,0 +1,11 @@ +URI: mpm_winnt.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm_winnt.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm_winnt.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/mpm_winnt.html.de b/trunk/docs/manual/mod/mpm_winnt.html.de new file mode 100644 index 0000000000..f0ac85451f --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.html.de @@ -0,0 +1,93 @@ + + + +mpm_winnt - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-MPM winnt

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + + + +
    Beschreibung: Das Multi-Processing-Modul ist optimiert für + Windows NT.
    Status:MPM
    Modulbezeichner:mpm_winnt_module
    Quelltext-Datei:mpm_winnt.c
    +

    Zusammenfassung

    + +

    Dieses Multi-Processing-Modul (MPM) ist die Voreinstellung + für das Betriebssystem Windows NT. Es verwendet einen einzelnen + Steuerprozess, der einen einzelnen Kindprozess startet, welcher + wiederum Threads zur Bedienung von Anfragen erstellt.

    +
    + + +
    top
    +

    Win32DisableAcceptEx-Direktive

    + + + + + + + + +
    Beschreibung:Für die Annahme von Netzwerkverbindungen wird accept() anstelle von AcceptEx() verwendet
    Syntax:Win32DisableAcceptEx
    Voreinstellung:AcceptEx() ist standardmäßig aktiviert. Verwenden Sie diese +Direktive, um den Gebrauch von AcceptEx() zu deaktivieren.
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:mpm_winnt
    Kompatibilität:Verfügbar ab Version 2.0.49
    +

    AcceptEx() ist eine Schnittstelle zu Microsoft Winsock v2, + die unter bestimmten Umständen einige Leistungsverbesserungen + gegenüber der accept()-API von BSD bietet. Einige beliebte + Windows-Produkte, typischerweise Virenscanner oder VPN-Pakete, besitzen + jedoch Fehler, welche den einwandfreien Betrieb von AcceptEx() + stören. Wenn Sie einen Fehler wie:

    + +

    + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. +

    + +

    erhalten, sollten Sie diese Direktive verwenden, um den Gebrauch von + AcceptEx() zu unterbinden.

    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_winnt.html.en b/trunk/docs/manual/mod/mpm_winnt.html.en new file mode 100644 index 0000000000..5359171bc4 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.html.en @@ -0,0 +1,93 @@ + + + +mpm_winnt - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM winnt

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    Description:This Multi-Processing Module is optimized for Windows +NT.
    Status:MPM
    Module Identifier:mpm_winnt_module
    Source File:mpm_winnt.c
    +

    Summary

    + +

    This Multi-Processing Module (MPM) is the default for the + Windows NT operating systems. It uses a single control process + which launches a single child process which in turn creates + threads to handle requests

    +
    + + +
    top
    +

    Win32DisableAcceptEx Directive

    + + + + + + + + +
    Description:Use accept() rather than AcceptEx() to accept network connections
    Syntax:Win32DisableAcceptEx
    Default:AcceptEx() is enabled by default. Use this directive to disable use of + AcceptEx()
    Context:server config
    Status:MPM
    Module:mpm_winnt
    Compatibility:Available in Version 2.0.49 and later
    +

    AcceptEx() is a Microsoft WinSock v2 API that provides + some performance improvements over the use of the BSD style + accept() API in certain circumstances. Some popular Windows + products, typically virus scanning or virtual private network + packages, have bugs that interfere with the proper operation of + AcceptEx(). If you encounter an error condition like:

    + +

    + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. +

    + +

    you should use this directive to disable the use of + AcceptEx().

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_winnt.html.ja.euc-jp b/trunk/docs/manual/mod/mpm_winnt.html.ja.euc-jp new file mode 100644 index 0000000000..6e286a1c6f --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.html.ja.euc-jp @@ -0,0 +1,91 @@ + + + +mpm_winnt - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache MPM winnt

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    ÀâÌÀ:Windows NT +¸þ¤±¤ËºÇŬ²½¤µ¤ì¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:mpm_winnt_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:mpm_winnt.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) + ¤Ï Windows NT ¤Ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ë¤Ê¤ê¤Þ¤¹¡£ + °ì¤Ä¤ÎÀ©¸æÍÑ¥×¥í¥»¥¹¤òÍѤ¤¡¢¤³¤ì¤¬°ì¤Ä¤Î»Ò¥×¥í¥»¥¹¤òµ¯Æ°¤·¡¢ + ¤½¤·¤Æ»Ò¥×¥í¥»¥¹¤¬¥ê¥¯¥¨¥¹¥È¤ò¼è¤ê°·¤¦¤¿¤á¤Ë¥¹¥ì¥Ã¥É¤ò + µ¯Æ°¤·¤Þ¤¹¡£

    +
    + + +
    top
    +

    Win32DisableAcceptEx ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + + +
    ÀâÌÀ:¥Í¥Ã¥È¥ï¡¼¥¯Àܳ¤Î¼õ¤±ÉÕ¤±¤Ë accept() ¤òAcceptEx ¤ÎÂå¤ï¤ê¤Ë»È¤¦
    ¹½Ê¸:Win32DisableAcceptEx
    ¥Ç¥Õ¥©¥ë¥È:AcceptEx() ¤Ï¥Ç¥Õ¥©¥ë¥È¤ÇÍ­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£AcceptEx() ¤ò̵¸ú¤Ë¤¹¤ë +¤¿¤á¤Ë¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¡£
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:mpm_winnt
    ¸ß´¹À­:2.0.49 ¥Ð¡¼¥¸¥ç¥ó°Ê¹ß¤Ç»ÈÍѲÄǽ
    +

    AcceptEx() ¤Ï Microsoft WinSock v2 API ¤Ç¡¢¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï + BSD ·Á¼°¤Î accept() API ¤è¤ê¤â¤è¤¤À­Ç½¤òȯ´ø¤·¤Þ¤¹¡£ + ¤è¤¯»È¤ï¤ì¤Æ¤¤¤ë Windows À½ÉʤÎÃæ¤Ç¡¢Æä˥¦¥£¥ë¥¹¥¹¥­¥ã¥Ê¤ä VPN ¥Ñ¥Ã¥±¡¼¥¸ + ¤ÎÃæ¤Ë¤Ï¡¢¥Ð¥°¤¬¸¶°ø¤Ç AcceptEx() ¤ÎŬÀÚ¤ÊÆ°ºî¤ò˸¤²¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + °Ê²¼¤Î¤è¤¦¤Ê¥¨¥é¡¼¤ËÁø¶ø¤·¤¿¾ì¹ç¤Ï¡¢¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ + AcceptEx() ¤ò»ÈÍѤ·¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. +

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpm_winnt.xml b/trunk/docs/manual/mod/mpm_winnt.xml new file mode 100644 index 0000000000..93f2ff88d3 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.xml @@ -0,0 +1,89 @@ + + + + + + + + + +mpm_winnt +This Multi-Processing Module is optimized for Windows +NT. +MPM +mpm_winnt.c +mpm_winnt_module + + +

    This Multi-Processing Module (MPM) is the default for the + Windows NT operating systems. It uses a single control process + which launches a single child process which in turn creates + threads to handle requests

    +
    + +CoreDumpDirectory + +PidFile + +Listen + +ListenBacklog + +MaxRequestsPerChild + +MaxMemFree + +ScoreBoardFile + +SendBufferSize + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + + + +Win32DisableAcceptEx +Use accept() rather than AcceptEx() to accept network connections +Win32DisableAcceptEx +AcceptEx() is enabled by default. Use this directive to disable use of + AcceptEx() +server config +Available in Version 2.0.49 and later + + +

    AcceptEx() is a Microsoft WinSock v2 API that provides + some performance improvements over the use of the BSD style + accept() API in certain circumstances. Some popular Windows + products, typically virus scanning or virtual private network + packages, have bugs that interfere with the proper operation of + AcceptEx(). If you encounter an error condition like:

    + + + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. + + +

    you should use this directive to disable the use of + AcceptEx().

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_winnt.xml.de b/trunk/docs/manual/mod/mpm_winnt.xml.de new file mode 100644 index 0000000000..9db752503a --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.xml.de @@ -0,0 +1,89 @@ + + + + + + + + + +mpm_winnt + Das Multi-Processing-Modul ist optimiert für + Windows NT. +MPM +mpm_winnt.c +mpm_winnt_module + + +

    Dieses Multi-Processing-Modul (MPM) ist die Voreinstellung + für das Betriebssystem Windows NT. Es verwendet einen einzelnen + Steuerprozess, der einen einzelnen Kindprozess startet, welcher + wiederum Threads zur Bedienung von Anfragen erstellt.

    +
    + +CoreDumpDirectory + +PidFile + +Listen + +ListenBacklog + +MaxMemFree + +MaxRequestsPerChild + +ScoreBoardFile + +SendBufferSize + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + + + +Win32DisableAcceptEx +Für die Annahme von Netzwerkverbindungen wird accept() anstelle von AcceptEx() verwendet +Win32DisableAcceptEx +AcceptEx() ist standardmäßig aktiviert. Verwenden Sie diese +Direktive, um den Gebrauch von AcceptEx() zu deaktivieren. +server config +Verfügbar ab Version 2.0.49 + + +

    AcceptEx() ist eine Schnittstelle zu Microsoft Winsock v2, + die unter bestimmten Umständen einige Leistungsverbesserungen + gegenüber der accept()-API von BSD bietet. Einige beliebte + Windows-Produkte, typischerweise Virenscanner oder VPN-Pakete, besitzen + jedoch Fehler, welche den einwandfreien Betrieb von AcceptEx() + stören. Wenn Sie einen Fehler wie:

    + + + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. + + +

    erhalten, sollten Sie diese Direktive verwenden, um den Gebrauch von + AcceptEx() zu unterbinden.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_winnt.xml.ja b/trunk/docs/manual/mod/mpm_winnt.xml.ja new file mode 100644 index 0000000000..f88da85dfc --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.xml.ja @@ -0,0 +1,87 @@ + + + + + + + + + +mpm_winnt +Windows NT +$B8~$1$K:GE,2=$5$l$?%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B +MPM +mpm_winnt.c +mpm_winnt_module + + +

    $B$3$N%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) + $B$O(B Windows NT $B$G$N%G%U%)%k%H$K$J$j$^$9!#(B + $B0l$D$N@)8fMQ%W%m%;%9$rMQ$$!"$3$l$,0l$D$N;R%W%m%;%9$r5/F0$7!"(B + $B$=$7$F;R%W%m%;%9$,%j%/%(%9%H$r +

    + +CoreDumpDirectory + +PidFile + +Listen + +ListenBacklog + +MaxRequestsPerChild + +MaxMemFree + +ScoreBoardFile + +SendBufferSize + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + + + +Win32DisableAcceptEx +$B%M%C%H%o!<%/@\B3$N +Win32DisableAcceptEx +AcceptEx() $B$O%G%U%)%k%H$GM-8z$K$J$C$F$$$^$9!#(BAcceptEx() $B$rL58z$K$9$k(B +$B$?$a$K$3$N%G%#%l%/%F%#%V$r;H$$$^$9!#(B +server config +2.0.49 $B%P!<%8%g%s0J9_$G;HMQ2DG=(B + + +

    AcceptEx() $B$O(B Microsoft WinSock v2 API $B$G!">l9g$K$h$C$F$O(B + BSD $B7A<0$N(B accept() API $B$h$j$b$h$$@-G=$rH/4x$7$^$9!#(B + $B$h$/;H$o$l$F$$$k(B Windows $B@=IJ$NCf$G!"FC$K%&%#%k%9%9%-%c%J$d(B VPN $B%Q%C%1!<%8(B + $B$NCf$K$O!"%P%0$,860x$G(B AcceptEx() $B$NE,@Z$JF0:n$rK8$2$k$b$N$,$"$j$^$9!#(B + $B0J2<$N$h$&$J%(%i!<$KAx6x$7$?>l9g$O!"$3$N%G%#%l%/%F%#%V$r;HMQ$7$F(B + AcceptEx() $B$r;HMQ$7$J$$$h$&$K$7$F$/$@$5$$!#(B

    + + + [error] (730038)An operation was attempted on something that is + not a socket.: winnt_accept: AcceptEx failed. Attempting to recover. + +
    +
    + +
    diff --git a/trunk/docs/manual/mod/mpm_winnt.xml.meta b/trunk/docs/manual/mod/mpm_winnt.xml.meta new file mode 100644 index 0000000000..3bc778eb44 --- /dev/null +++ b/trunk/docs/manual/mod/mpm_winnt.xml.meta @@ -0,0 +1,13 @@ + + + + mpm_winnt + /mod/ + .. + + + de + en + ja + + diff --git a/trunk/docs/manual/mod/mpmt_os2.html b/trunk/docs/manual/mod/mpmt_os2.html new file mode 100644 index 0000000000..df2b37dfd3 --- /dev/null +++ b/trunk/docs/manual/mod/mpmt_os2.html @@ -0,0 +1,3 @@ +URI: mpmt_os2.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/mpmt_os2.html.en b/trunk/docs/manual/mod/mpmt_os2.html.en new file mode 100644 index 0000000000..ff8c4de1e5 --- /dev/null +++ b/trunk/docs/manual/mod/mpmt_os2.html.en @@ -0,0 +1,72 @@ + + + +mpmt_os2 - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM os2

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Hybrid multi-process, multi-threaded MPM for OS/2
    Status:MPM
    Module Identifier:mpm_mpmt_os2_module
    Source File:mpmt_os2.c
    +

    Summary

    + +

    The Server consists of a main, parent process and a small, static + number of child processes.

    + +

    The parent process's job is to manage the child processes. This + involves spawning children as required to ensure there are always + StartServers processes + accepting connections.

    + +

    Each child process consists of a a pool of worker threads and a + main thread that accepts connections and passes them to the workers via + a work queue. The worker thread pool is dynamic, managed by a + maintenance thread so that the number of idle threads is kept between + MinSpareThreads and + MaxSpareThreads.

    +
    + + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/mpmt_os2.xml b/trunk/docs/manual/mod/mpmt_os2.xml new file mode 100644 index 0000000000..479c43990f --- /dev/null +++ b/trunk/docs/manual/mod/mpmt_os2.xml @@ -0,0 +1,71 @@ + + + + + + + + + +mpmt_os2 +Hybrid multi-process, multi-threaded MPM for OS/2 +MPM +mpmt_os2.c +mpm_mpmt_os2_module + + +

    The Server consists of a main, parent process and a small, static + number of child processes.

    + +

    The parent process's job is to manage the child processes. This + involves spawning children as required to ensure there are always + StartServers processes + accepting connections.

    + +

    Each child process consists of a a pool of worker threads and a + main thread that accepts connections and passes them to the workers via + a work queue. The worker thread pool is dynamic, managed by a + maintenance thread so that the number of idle threads is kept between + MinSpareThreads and + MaxSpareThreads.

    +
    +Setting which addresses and ports Apache +uses + +User + +Group + +Listen + +ListenBacklog + +SendBufferSize + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +StartServers + + +
    diff --git a/trunk/docs/manual/mod/mpmt_os2.xml.meta b/trunk/docs/manual/mod/mpmt_os2.xml.meta new file mode 100644 index 0000000000..5ffd92955e --- /dev/null +++ b/trunk/docs/manual/mod/mpmt_os2.xml.meta @@ -0,0 +1,11 @@ + + + + mpmt_os2 + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/perchild.html b/trunk/docs/manual/mod/perchild.html new file mode 100644 index 0000000000..6659fb364e --- /dev/null +++ b/trunk/docs/manual/mod/perchild.html @@ -0,0 +1,3 @@ +URI: perchild.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/perchild.html.en b/trunk/docs/manual/mod/perchild.html.en new file mode 100644 index 0000000000..d20f5f99ee --- /dev/null +++ b/trunk/docs/manual/mod/perchild.html.en @@ -0,0 +1,265 @@ + + + +perchild - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM perchild

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids
    Status:MPM
    Module Identifier:mpm_perchild_module
    Source File:perchild.c
    +

    Summary

    + +
    + This module is not functional. Development of this module is not + complete and is not currently active. Do not use + perchild unless you are a programmer willing to + help fix it. +
    + +

    This Multi-Processing Module (MPM) implements a hybrid + multi-process, multi-threaded web server. A fixed number of + processes create threads to handle requests. Fluctuations in + load are handled by increasing or decreasing the number of + threads in each process.

    +
    + +
    top
    +
    +

    How it works

    +

    A single control process launches the number of child processes + indicated by the NumServers + directive at server startup. Each child process creates threads as + specified in the StartThreads directive. + The individual threads then + listen for connections and serve them when they arrive.

    + +

    Apache always tries to maintain a pool of spare or + idle server threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for new + threads to be created. For each child process, Apache assesses + the number of idle threads and creates or destroys threads to + keep this number within the boundaries specified by + MinSpareThreads + and MaxSpareThreads. + Since this process is very self-regulating, it is rarely + necessary to modify these directives from their default values. + The maximum number of clients that may be served simultaneously + is determined by multiplying the number of server processes + that will be created (NumServers) by the maximum + number of threads created in each process + (MaxThreadsPerChild).

    + +

    While the parent process is usually started as root under + Unix in order to bind to port 80, the child processes and + threads are launched by Apache as a less-privileged user. The + User and Group directives are used to + set the privileges of the Apache child processes. The child + processes must be able to read all the content that will be + served, but should have as few privileges beyond that as + possible. In addition, unless suexec is used, + these directives also set the privileges which will be inherited + by CGI scripts.

    + +

    MaxRequestsPerChild + controls how frequently the + server recycles processes by killing old ones and launching new + ones.

    + +

    Working with different user-IDs

    +

    The perchild MPM adds the extra ability to + specify that particular processes should serve requests under + different user-IDs. These user-IDs can then be associated with + specific virtual hosts. You have to use one ChildPerUserID directive for + every user/group combination you want to be run. Then you can tie + particular virtual hosts to that user and group IDs.

    + +

    The following example runs 7 child processes. Two of them are run + under user1/group1. The next four are run + under user2/group2 and the remaining + process uses the User and Group + of the main server:

    + +

    Global config

    + NumServers 7
    + ChildPerUserID user1 group1 2
    + ChildPerUserID user2 group2 4 +

    + +

    Using unbalanced numbers of processes as above is useful, if the + particular virtual hosts produce different load. The assignment to + the virtual hosts is easily done as in the example below. In + conclusion with the example above the following assumes, that + server2 has to serve about twice of the hits of + server1.

    + +

    Example

    + NameVirtualHost *
    +
    + <VirtualHost *>
    + + ServerName fallbackhost
    + # no assignment; use fallback
    +
    + </VirtualHost>
    +
    + <VirtualHost *>
    + + ServerName server1
    + AssignUserID user1 group1
    +
    + </VirtualHost>
    +
    + <VirtualHost *>
    + + ServerName server2
    + AssignUserID user2 group2
    +
    + </VirtualHost> +

    + +
    +
    top
    +

    AssignUserID Directive

    + + + + + + +
    Description:Tie a virtual host to a user and group ID
    Syntax:AssignUserID user-id group-id
    Context:virtual host
    Status:MPM
    Module:perchild
    +

    Tie a virtual host to a specific user/group combination. Requests + addressed to the virtual host where this directive appears will be + served by a process running with the specified user and group ID.

    + +

    The user and group ID has to be assigned to a number of children + in the global server config using the ChildPerUserID directive. See the section above for a + configuration example.

    + +
    +
    top
    +

    ChildPerUserID Directive

    + + + + + + +
    Description:Specify user ID and group ID for a number of child +processes
    Syntax:ChildPerUserID user-id group-id +num-children
    Context:server config
    Status:MPM
    Module:perchild
    +

    Specify a user ID and group ID for a number of child processes. + The third argument, num-children, is the number of child + processes to start with the specified user and group. It does + not represent a specific child number. In order to use this + directive, the server must be run initially as root. + If you start the server as a non-root user, it will fail to change + to the lesser privileged user.

    + +

    If the total number of child processes, found by totaling all of the + third arguments to all ChildPerUserID directives + in the config file, is less than NumServers, then all remaining children will inherit the + User and Group settings from the main server. + See the section above for a configuration + example.

    + +

    Security

    +

    Don't set user-id (or group-id) to + root unless you know exactly what you are doing, and + what the dangers are.

    +
    + +
    +
    top
    +

    MaxThreadsPerChild Directive

    + + + + + + + +
    Description:Maximum number of threads per child process
    Syntax:MaxThreadsPerChild number
    Default:MaxThreadsPerChild 64
    Context:server config
    Status:MPM
    Module:perchild
    +

    This directive sets the maximum number of threads that will be + created in each child process. To increase this value beyond its + default, it is necessary to change the value of the ThreadLimit directive and stop and + re-start the server.

    + +
    +
    top
    +

    NumServers Directive

    + + + + + + + +
    Description:Total number of children alive at the same time
    Syntax:NumServers number
    Default:NumServers 2
    Context:server config
    Status:MPM
    Module:perchild
    +

    The NumServers directive determines the number + of children alive at the same time. This number should be large enough to + handle the requests for the entire site. To increase this value beyond the + value of 8, it is necessary to change the value of the + ServerLimit directive and stop + and re-start the server. See the section above for a configuration example.

    + +
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/perchild.xml b/trunk/docs/manual/mod/perchild.xml new file mode 100644 index 0000000000..f386849b15 --- /dev/null +++ b/trunk/docs/manual/mod/perchild.xml @@ -0,0 +1,270 @@ + + + + + + + + + +perchild +Multi-Processing Module allowing for daemon processes serving +requests to be assigned a variety of different userids +MPM +perchild.c +mpm_perchild_module + + + + This module is not functional. Development of this module is not + complete and is not currently active. Do not use + perchild unless you are a programmer willing to + help fix it. + + +

    This Multi-Processing Module (MPM) implements a hybrid + multi-process, multi-threaded web server. A fixed number of + processes create threads to handle requests. Fluctuations in + load are handled by increasing or decreasing the number of + threads in each process.

    +
    +Setting which addresses and ports Apache +uses + +
    How it works +

    A single control process launches the number of child processes + indicated by the NumServers + directive at server startup. Each child process creates threads as + specified in the StartThreads directive. + The individual threads then + listen for connections and serve them when they arrive.

    + +

    Apache always tries to maintain a pool of spare or + idle server threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for new + threads to be created. For each child process, Apache assesses + the number of idle threads and creates or destroys threads to + keep this number within the boundaries specified by + MinSpareThreads + and MaxSpareThreads. + Since this process is very self-regulating, it is rarely + necessary to modify these directives from their default values. + The maximum number of clients that may be served simultaneously + is determined by multiplying the number of server processes + that will be created (NumServers) by the maximum + number of threads created in each process + (MaxThreadsPerChild).

    + +

    While the parent process is usually started as root under + Unix in order to bind to port 80, the child processes and + threads are launched by Apache as a less-privileged user. The + User and Group directives are used to + set the privileges of the Apache child processes. The child + processes must be able to read all the content that will be + served, but should have as few privileges beyond that as + possible. In addition, unless suexec is used, + these directives also set the privileges which will be inherited + by CGI scripts.

    + +

    MaxRequestsPerChild + controls how frequently the + server recycles processes by killing old ones and launching new + ones.

    + +
    Working with different user-IDs +

    The perchild MPM adds the extra ability to + specify that particular processes should serve requests under + different user-IDs. These user-IDs can then be associated with + specific virtual hosts. You have to use one ChildPerUserID directive for + every user/group combination you want to be run. Then you can tie + particular virtual hosts to that user and group IDs.

    + +

    The following example runs 7 child processes. Two of them are run + under user1/group1. The next four are run + under user2/group2 and the remaining + process uses the User and Group + of the main server:

    + + Global config + NumServers 7
    + ChildPerUserID user1 group1 2
    + ChildPerUserID user2 group2 4 +
    + +

    Using unbalanced numbers of processes as above is useful, if the + particular virtual hosts produce different load. The assignment to + the virtual hosts is easily done as in the example below. In + conclusion with the example above the following assumes, that + server2 has to serve about twice of the hits of + server1.

    + + Example + NameVirtualHost *
    +
    + <VirtualHost *>
    + + ServerName fallbackhost
    + # no assignment; use fallback
    +
    + </VirtualHost>
    +
    + <VirtualHost *>
    + + ServerName server1
    + AssignUserID user1 group1
    +
    + </VirtualHost>
    +
    + <VirtualHost *>
    + + ServerName server2
    + AssignUserID user2 group2
    +
    + </VirtualHost> +
    +
    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartThreads + +ThreadLimit + +ThreadStackSize + +User + + + +AssignUserID +Tie a virtual host to a user and group ID +AssignUserID user-id group-id +virtual host + + +

    Tie a virtual host to a specific user/group combination. Requests + addressed to the virtual host where this directive appears will be + served by a process running with the specified user and group ID.

    + +

    The user and group ID has to be assigned to a number of children + in the global server config using the ChildPerUserID directive. See the section above for a + configuration example.

    +
    +
    + + +ChildPerUserID +Specify user ID and group ID for a number of child +processes +ChildPerUserID user-id group-id +num-children +server config + + +

    Specify a user ID and group ID for a number of child processes. + The third argument, num-children, is the number of child + processes to start with the specified user and group. It does + not represent a specific child number. In order to use this + directive, the server must be run initially as root. + If you start the server as a non-root user, it will fail to change + to the lesser privileged user.

    + +

    If the total number of child processes, found by totaling all of the + third arguments to all ChildPerUserID directives + in the config file, is less than NumServers, then all remaining children will inherit the + User and Group settings from the main server. + See the section above for a configuration + example.

    + + Security +

    Don't set user-id (or group-id) to + root unless you know exactly what you are doing, and + what the dangers are.

    +
    +
    +
    + + +MaxThreadsPerChild +Maximum number of threads per child process +MaxThreadsPerChild number +MaxThreadsPerChild 64 +server config + + +

    This directive sets the maximum number of threads that will be + created in each child process. To increase this value beyond its + default, it is necessary to change the value of the ThreadLimit directive and stop and + re-start the server.

    +
    +
    + + +NumServers +Total number of children alive at the same time +NumServers number +NumServers 2 +server config + + +

    The NumServers directive determines the number + of children alive at the same time. This number should be large enough to + handle the requests for the entire site. To increase this value beyond the + value of 8, it is necessary to change the value of the + ServerLimit directive and stop + and re-start the server. See the section above for a configuration example.

    +
    +
    + +
    diff --git a/trunk/docs/manual/mod/perchild.xml.meta b/trunk/docs/manual/mod/perchild.xml.meta new file mode 100644 index 0000000000..0f5b87f6fa --- /dev/null +++ b/trunk/docs/manual/mod/perchild.xml.meta @@ -0,0 +1,11 @@ + + + + perchild + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/prefork.html b/trunk/docs/manual/mod/prefork.html new file mode 100644 index 0000000000..4676cc4ff3 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.html @@ -0,0 +1,11 @@ +URI: prefork.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: prefork.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: prefork.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/prefork.html.de b/trunk/docs/manual/mod/prefork.html.de new file mode 100644 index 0000000000..3d779ac8e0 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.html.de @@ -0,0 +1,190 @@ + + + +prefork - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-MPM prefork

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + + + +
    Beschreibung:Implementiert einen im Voraus forkenden Webserver ohne + Thread-Unterstützung
    Status:MPM
    Modulbezeichner:mpm_prefork_module
    Quelltext-Datei:prefork.c
    +

    Zusammenfassung

    + +

    Dieses Multi-Processing-Modul (MPM) implementiert einen + im Voraus forkenden Webserver ohne Thread-Unterstützung, der Anfragen + auf ähnliche Weise behandelt wie der Apache 1.3. Es ist für + Angebote geeignet, die aus Kompatibilitätsgründen mit + nicht-Thread-sicheren Bibliotheken Threading vermeiden müssen. + Es ist außerdem das geeignetste MPM, um jede Anfrage isoliert + zu bearbeiten, so dass Probleme mit einem einzelnen Prozess keinen + anderen beeinflussen.

    + +

    Das MPM ist stark selbstregulierend, so dass es selten + notwendig ist, seine Konfigurationseinstellungen zu justieren. Das + Wichtigste ist, dass MaxClients + gross genug ist, so viele gleichzeitige Anfragen zu bedienen, wie Sie + erwarten, aber klein genug, um sicherzustellen, dass genug physischer + Arbeitsspeicher für alle Prozesse vorhanden ist.

    +
    + +
    top
    +
    +

    Arbeitsweise

    +

    Ein einzelner Steuerprozess ist für den Start von + Kindprozessen verantwortlich, die auf Verbindungen warten und diese + bedienen, sobald sie eintreffen. Der Apache versucht immer, mehrere + freie oder unbeschäftigte Serverprozesse vorzuhalten, + die zur Bedienung eingehender Anfragen bereit stehen. Auf diese Weise + müssen Clients nicht darauf warten, dass neue Kindprozesse + geforkt werden, bevor ihre Anfrage bearbeitet werden kann.

    + +

    StartServers, + MinSpareServers, + MaxSpareServers und + MaxClients regulieren, + wie der Elternprozess Kindprozesse zur Bedienung von Anfragen erstellt. + Im Allgemeinen ist der Apache sehr selbstregulierend, so dass die meisten + Angebote die Voreinstellung dieser Direktiven nicht verändern + müssen. Systeme, die mehr als 256 gleichzeitige Anfragen bedienen + müssen, können MaxClients erhöhen, während + Systeme mit begrenztem Arbeitsspeicher möglicherweise + MaxClients heruntersetzen + müssen, um den Server vor Flatterverhalten (Arbeitsspeicherinhalte auf + Platte auslagern - und zurück) zu schützen. Weitere + Informationen zur Feinabstimmung der Prozesserstellung sind in den + Performance-Hinweisen zu + finden.

    + +

    Währen der Elternprozess unter Unix normalerweise als + root gestartet wird, um sich an Port 80 binden zu können, + werden die Kindprozesse unter einem weniger privilegierten Benutzer + gestartet. Die Direktiven User + und Group werden dazu + verwendet, die Privilegien der Apache-Kindprozesse festzulegen. Die + Kindprozesse müssen in der Lage sein, alle Inhalte zu lesen, die + sie ausliefern sollen, sollten darüber hinaus jedoch so wenig wie + möglich Rechte besitzen.

    + +

    MaxRequestsPerChild + bestimmt, wie häufig der Server Prozesse erneuert, indem er alte + beendet und neue startet.

    +
    +
    top
    +

    MaxSpareServers-Direktive

    + + + + + + + +
    Beschreibung:Maximale Anzahl der unbeschäftigten Kindprozesse des + Servers
    Syntax:MaxSpareServers Anzahl
    Voreinstellung:MaxSpareServers 10
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:prefork
    +

    Die Direktive MaxSpareServers bestimmt das + gewünschte Maximum an unbeschäftigten + Kindprozessen des Servers. Ein unbeschäftiger Prozess ist einer, der + keine Anfrage bedient. Wenn mehr als MaxSpareServers + Prozesse unbeschäftigt sind, wird der Elternprozess die + überschüssigen Prozesse beenden.

    + +

    Eine Feineinstellung dieses Parameters sollte nur bei sehr + beschäftigten Angeboten notwendig sein. Es ist nahezu immer eine + schlechte Idee, den Parameter auf einen hohen Wert zu setzen. Wenn Sie + versuchen, den Wert kleiner oder gleich MinSpareServers zu setzen, wird der Apache + ihn automatisch auf MinSpareServers + 1 + korrigieren.

    + +

    Siehe auch

    + +
    +
    top
    +

    MinSpareServers-Direktive

    + + + + + + + +
    Beschreibung:Minimale Anzahl der unbeschäftigten Kindprozesse des + Servers
    Syntax:MinSpareServers Anzahl
    Voreinstellung:MinSpareServers 5
    Kontext:Serverkonfiguration
    Status:MPM
    Modul:prefork
    +

    Die Direktive MinSpareServers bestimmt das + gewünschte Minimum der unbeschäftigten + Kindprozesse des Servers. Ein unbeschäftigter Prozess ist einer, der + keine Anfrage bedient. Wenn weniger als + MinSpareServers Prozesse unbeschäftigt sind, + dann erstellt der Elternprozess neue mit einer maximalen Rate von 1 + pro Sekunde.

    + +

    Die Feineinstellung des Parameters sollte nur bei sehr + beschäftigten Angeboten notwendig sein. Es ist nahezu immer eine + schlechte ide, den Parameter auf einen hohen Wert zu setzen.

    + +

    Siehe auch

    + +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/prefork.html.en b/trunk/docs/manual/mod/prefork.html.en new file mode 100644 index 0000000000..09a5b5586a --- /dev/null +++ b/trunk/docs/manual/mod/prefork.html.en @@ -0,0 +1,175 @@ + + + +prefork - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM prefork

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    Description:Implements a non-threaded, pre-forking web server
    Status:MPM
    Module Identifier:mpm_prefork_module
    Source File:prefork.c
    +

    Summary

    + +

    This Multi-Processing Module (MPM) implements a non-threaded, + pre-forking web server that handles requests in a manner similar + to Apache 1.3. It is appropriate for sites that need to avoid + threading for compatibility with non-thread-safe libraries. It + is also the best MPM for isolating each request, so that a problem + with a single request will not affect any other.

    + +

    This MPM is very self-regulating, so it is rarely necessary to + adjust its configuration directives. Most important is that + MaxClients be big enough to + handle as many simultaneous requests as you expect to receive, but + small enough to assure that there is enough physical RAM for all + processes.

    +
    + +
    top
    +
    +

    How it Works

    +

    A single control process is responsible for launching child + processes which listen for connections and serve them when they + arrive. Apache always tries to maintain several spare + or idle server processes, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + child processes to be forked before their requests can be + served.

    + +

    The StartServers, + MinSpareServers, + MaxSpareServers, and + MaxClients regulate how + the parent process creates children to serve requests. In general, + Apache is very self-regulating, so most sites do not need to + adjust these directives from their default values. Sites which + need to serve more than 256 simultaneous requests may need to + increase MaxClients, + while sites with limited memory may need to decrease MaxClients to keep the server from + thrashing (swapping memory to disk and back). More information + about tuning process creation is provided in the performance hints + documentation.

    + +

    While the parent process is usually started as root + under Unix in order to bind to port 80, the child processes are + launched by Apache as a less-privileged user. The User and Group directives are used to set + the privileges of the Apache child processes. The child processes + must be able to read all the content that will be served, but + should have as few privileges beyond that as possible.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing + old ones and launching new ones.

    +
    +
    top
    +

    MaxSpareServers Directive

    + + + + + + + +
    Description:Maximum number of idle child server processes
    Syntax:MaxSpareServers number
    Default:MaxSpareServers 10
    Context:server config
    Status:MPM
    Module:prefork
    +

    The MaxSpareServers directive sets the + desired maximum number of idle child server processes. An + idle process is one which is not handling a request. If there are + more than MaxSpareServers idle, then the + parent process will kill off the excess processes.

    + +

    Tuning of this parameter should only be necessary on very + busy sites. Setting this parameter to a large number is almost + always a bad idea. If you are trying to set the value equal to or lower than + MinSpareServers, Apache + will automatically adjust it to MinSpareServers + 1.

    + +

    See also

    + +
    +
    top
    +

    MinSpareServers Directive

    + + + + + + + +
    Description:Minimum number of idle child server processes
    Syntax:MinSpareServers number
    Default:MinSpareServers 5
    Context:server config
    Status:MPM
    Module:prefork
    +

    The MinSpareServers directive sets the + desired minimum number of idle child server processes. An + idle process is one which is not handling a request. If there are + fewer than MinSpareServers idle, then the parent + process creates new children at a maximum rate of 1 per second.

    + +

    Tuning of this parameter should only be necessary on very + busy sites. Setting this parameter to a large number is almost + always a bad idea.

    + +

    See also

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/prefork.html.ja.euc-jp b/trunk/docs/manual/mod/prefork.html.ja.euc-jp new file mode 100644 index 0000000000..9505c67f86 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.html.ja.euc-jp @@ -0,0 +1,187 @@ + + + +prefork - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache MPM prefork

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    ÀâÌÀ:¥¹¥ì¥Ã¥É¤ò»È¤ï¤º¡¢Àè¹Ô¤·¤Æ fork ¤ò¹Ô¤Ê¤¦¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼ÂÁõ +
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:mpm_prefork_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:prefork.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) ¤Ï¡¢ + Unix ¾å¤Ç¤Î Apache 1.3 ¤Î¥Ç¥Õ¥©¥ë¥È¤ÎµóÆ°¤ÈÈó¾ï¤Ë¤è¤¯»÷¤¿ÊýË¡¤Ç + ¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë¡¢¥¹¥ì¥Ã¥É¤ò»È¤ï¤º¡¢Àè¹Ô¤·¤Æ fork ¤ò¹Ô¤Ê¤¦ + ¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£ + ¥¹¥ì¥Ã¥É¥»¡¼¥Õ¤Ç¤Ê¤¤¥é¥¤¥Ö¥é¥ê¤È¤Î¸ß´¹À­¤ò¤È¤ë¤¿¤á¤Ë¡¢ + ¥¹¥ì¥Ã¥É¤òÈò¤±¤ëɬÍפΤ¢¤ë¥µ¥¤¥È¤Ç¤Ï¡¢¤³¤Î¥â¥¸¥å¡¼¥ë¤Î»ÈÍѤ¬Å¬ÀڤǤ·¤ç¤¦¡£ + ¤¢¤ë¥ê¥¯¥¨¥¹¥È¤ÇȯÀ¸¤·¤¿ÌäÂ꤬¾¤Î¥ê¥¯¥¨¥¹¥È¤Ë±Æ¶Á¤·¤Ê¤¤¤è¤¦¤Ë¡¢ + ¸Ä¡¹¤Î¥ê¥¯¥¨¥¹¥È¤òñΥ¤¹¤ë¤Î¤Ë¤â¡¢ºÇŬ¤Ê MPM ¤Ç¤¹¡£

    + +

    ¤³¤Î MPM ¤ÏÈó¾ï¤Ë¼«Î§Åª¤Ê¤Î¤Ç¡¢¤³¤Î MPM ¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + Ä´À°¤¹¤ëɬÍפϤۤȤó¤É¤Ê¤¤¤Ç¤·¤ç¤¦¡£¤â¤Ã¤È¤â½ÅÍפʤ³¤È¤Ï¡¢ + MaxClients + ¤¬¡¢Í½ÁÛ¤µ¤ì¤ëƱ»þ¥ê¥¯¥¨¥¹¥È¿ô¤ò½½Ê¬°·¤¨¤ë¤°¤é¤¤¤ÏÂ礭¤¤¤±¤ì¤É¤â¡¢ + Á´¥×¥í¥»¥¹¤Ë½½Ê¬¤ÊʪÍý¥á¥â¥ê¤¬³Î¼Â¤Ë¹Ô¤­ÅϤëÄøÅ٤ˤϾ®¤µ¤¤Ãͤˤ¹¤ë¡¢ + ¤È¤¤¤¦¤³¤È¤Ç¤¹¡£

    + +
    + +
    top
    +
    +

    Æ°ºîÊýË¡

    +

    °ì¤Ä¤Î¥³¥ó¥È¥í¡¼¥ë¥×¥í¥»¥¹¤¬¡¢ + ¥³¥Í¥¯¥·¥ç¥ó¤ËÂФ·¤Æ listen ¤·¤Æ¡¢¤·¤«¤ë¤Ù¤­»þ¤Ë±þÅú¤¹¤ë + »Ò¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Þ¤¹¡£Apache ¤Ï¾ï¤Ë´ö¤Ä¤«¤Î¥¹¥Ú¥¢ + ¤«¥¢¥¤¥É¥ë¤Ê¥µ¡¼¥Ð¥×¥í¥»¥¹¤ò°Ý»ý¤·¤Æ¤¤¤Æ¡¢¤½¤ì¤é¤ÏÆþ¤Ã¤Æ¤­¤¿ + ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤Ç¤­¤ë¤è¤¦¤ËÂÔµ¡¤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤¬±þÅú¤µ¤ì¤ëÁ°¤Ë¡¢ + ¿·¤·¤¤»Ò¥×¥í¥»¥¹¤¬ fork ¤µ¤ì¤ë¤Î¤òÂÔ¤¿¤Ê¤¯¤Æ¤â¤è¤¤¤è¤¦¤Ë + ¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£

    + +

    ¿Æ¥×¥í¥»¥¹¤¬¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤Î»Ò¥×¥í¥»¥¹¤ò + ¤É¤Î¤è¤¦¤ËÀ¸À®¤¹¤ë¤«¤Ï¡¢ + StartServers, + MinSpareServers, + MaxSpareServers, + MaxClients + ¤ÇÄ´À°¤·¤Þ¤¹¡£°ìÈÌŪ¤Ë¡¢Apache ¤ÏÈó¾ï¤Ë¼«Î§Åª¤Ê¤Î¤Ç¡¢ + ÂçÄñ¤Î¥µ¥¤¥È¤Ç¤Ï¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Ç¥Õ¥©¥ë¥ÈÃͤ«¤éÄ´À°¤¹¤ë + ɬÍפϤʤ¤¤Ç¤·¤ç¤¦¡£ + Ʊ»þ¤Ë 256 ¤òĶ¤¨¤ë¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤·¤Ê¤¤¤È¤¤¤±¤Ê¤¤¥µ¥¤¥È¤Ç¤Ï¡¢ + MaxClients + ¤òÁý¤ä¤¹É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£ + °ìÊý¡¢¥á¥â¥ê¤Î¸Â¤é¤ì¤Æ¤¤¤ë¥µ¥¤¥È¤Ç¤Ï¡¢¥¹¥é¥Ã¥·¥ó¥° + (¥á¥â¥ê¤È¥Ç¥£¥¹¥¯´Ö¤Ç²¿Å٤⥹¥ï¥Ã¥×) ¤¬µ¯¤³¤ë¤Î¤òËɤ°¤¿¤á¤Ë + MaxClients + ¤ò¸º¤é¤¹É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£¥×¥í¥»¥¹À¸À®¤Î¥Á¥å¡¼¥Ë¥ó¥°¤Ë´Ø¤¹¤ë + ¾Ü¤·¤¤¾ðÊó¤Ï¡¢À­Ç½¤Ë´Ø¤¹¤ë¥Ò¥ó¥È + ¤Ë¤¢¤ê¤Þ¤¹¡£

    + +

    Ä̾ï Unix ¤Ç¤Ï¿Æ¥×¥í¥»¥¹¤Ï 80 È֥ݡ¼¥È¤Ë¥Ð¥¤¥ó¥É¤¹¤ë¤¿¤á¤Ë + root ¤Çµ¯Æ°¤µ¤ì¤Þ¤¹¤¬¡¢»Ò¥×¥í¥»¥¹¤ä¥¹¥ì¥Ã¥É¤Ï + ¤â¤Ã¤ÈÄ㤤¸¢¸Â¤Î¥æ¡¼¥¶¤Ç Apache ¤Ë¤è¤Ã¤Æµ¯Æ°¤µ¤ì¤Þ¤¹¡£ + User ¤È + Group + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Apache ¤Î»Ò¥×¥í¥»¥¹¤Î¸¢¸Â¤òÀßÄꤹ¤ë¤Î¤ËÍѤ¤¤é¤ì¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¥³¥ó¥Æ¥ó¥ÄÁ´¤Æ¤òÆɤá¤Ê¤¤¤È¤¤¤±¤Þ¤»¤ó¤¬¡¢ + ²Äǽ¤Ê¸Â¤êɬÍ׺Ǿ®¸Â¤Î¸¢¸Â¤Î¤ß¤ò»ý¤Ã¤Æ¤¤¤ë¤è¤¦¤Ë¤¹¤ë¤Ù¤­¤Ç¤¹¡£

    + +

    MaxRequestsPerChild + ¤Ï¡¢¸Å¤¤¥×¥í¥»¥¹¤òÄä»ß¤·¤Æ¿·¤·¤¤¥×¥í¥»¥¹¤òµ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ¤É¤ÎÄøÅÙ¤ÎÉÑÅ٤ǥµ¡¼¥Ð¤¬¥×¥í¥»¥¹¤ò¥ê¥µ¥¤¥¯¥ë¤¹¤ë¤«¤òÀ©¸æ¤·¤Þ¤¹¡£

    +
    +
    top
    +

    MaxSpareServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤ÎºÇÂç¸Ä¿ô
    ¹½Ê¸:MaxSpareServers number
    ¥Ç¥Õ¥©¥ë¥È:MaxSpareServers 10
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:prefork
    +

    MaxSpareServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î´õ˾ºÇÂç¸Ä¿ô¤òÀßÄꤷ¤Þ¤¹¡£ + ¥¢¥¤¥É¥ë¥×¥í¥»¥¹¤È¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤Ê¤¤¥×¥í¥»¥¹¤Ç¤¹¡£ + MaxSpareServers ¤è¤ê¤â¿¤¤¿ô¤¬¥¢¥¤¥É¥ë¤Ç¤¢¤ì¤Ð¡¢ + ¿Æ¥×¥í¥»¥¹¤ÏĶ²á¥×¥í¥»¥¹¤ò kill ¤·¤Þ¤¹¡£

    + +

    Èó¾ï¤Ëº®¤ó¤Ç¤¤¤ë¥µ¥¤¥È¤Ç¤Î¤ß¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤ò¥Á¥å¡¼¥Ë¥ó¥°¤¹¤ë¤Ù¤­¤Ç¤¹¡£ + ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤òÂ礭¤¯¤¹¤ë¤È¤¤¤¦¤³¤È¤Ï¡¢ÂçÄñ¤Î¾ì¹ç¤Ï°­¤¤È¯ÁۤǤ¹¡£ + MinSpareServers + °Ê²¼¤ËÀßÄꤷ¤¿¾ì¹ç¡¢MinSpareServers + +1 ¤Ë¼«Æ°Ä´À°¤µ¤ì¤Þ¤¹¡£

    + +

    »²¾È

    + +
    +
    top
    +

    MinSpareServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + + + + + +
    ÀâÌÀ:¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤ÎºÇ¾®¸Ä¿ô
    ¹½Ê¸:MinSpareServers number
    ¥Ç¥Õ¥©¥ë¥È:MinSpareServers 5
    ¥³¥ó¥Æ¥­¥¹¥È:¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë:prefork
    +

    MaxSpareServers ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î´õ˾ºÇ¾®¸Ä¿ô¤òÀßÄꤷ¤Þ¤¹¡£ + ¥¢¥¤¥É¥ë¥×¥í¥»¥¹¤È¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤ò°·¤Ã¤Æ¤¤¤Ê¤¤¥×¥í¥»¥¹¤Ç¤¹¡£ + MinSpareServers ¤è¤ê¤â¾¯¤Ê¤¤¿ô¤¬¥¢¥¤¥É¥ë¤Ç¤¢¤ì¤Ð¡¢ + ¿Æ¥×¥í¥»¥¹¤ÏºÇ¹â¤Ç 1 ÉäˤĤ­ 1 ¸Ä¤Î³ä¹ç¤Ç¿·¤·¤¤»Ò¥×¥í¥»¥¹¤òÀ¸À®¤·¤Þ¤¹¡£

    + +

    Èó¾ï¤Ëº®¤ó¤Ç¤¤¤ë¥µ¥¤¥È¤Ç¤Î¤ß¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤ò¥Á¥å¡¼¥Ë¥ó¥°¤¹¤ë¤Ù¤­¤Ç¤¹¡£ + ¤³¤Î¥Ñ¥é¥á¡¼¥¿¤òÂ礭¤¯¤¹¤ë¤È¤¤¤¦¤³¤È¤Ï¡¢ÂçÄñ¤Î¾ì¹ç¤Ï°­¤¤È¯ÁۤǤ¹¡£

    + +

    »²¾È

    + +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/prefork.xml b/trunk/docs/manual/mod/prefork.xml new file mode 100644 index 0000000000..10b9af1a20 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.xml @@ -0,0 +1,169 @@ + + + + + + + + + +prefork +Implements a non-threaded, pre-forking web server +MPM +prefork.c +mpm_prefork_module + + +

    This Multi-Processing Module (MPM) implements a non-threaded, + pre-forking web server that handles requests in a manner similar + to Apache 1.3. It is appropriate for sites that need to avoid + threading for compatibility with non-thread-safe libraries. It + is also the best MPM for isolating each request, so that a problem + with a single request will not affect any other.

    + +

    This MPM is very self-regulating, so it is rarely necessary to + adjust its configuration directives. Most important is that + MaxClients be big enough to + handle as many simultaneous requests as you expect to receive, but + small enough to assure that there is enough physical RAM for all + processes.

    +
    +Setting which addresses and ports Apache +uses + +
    How it Works +

    A single control process is responsible for launching child + processes which listen for connections and serve them when they + arrive. Apache always tries to maintain several spare + or idle server processes, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + child processes to be forked before their requests can be + served.

    + +

    The StartServers, + MinSpareServers, + MaxSpareServers, and + MaxClients regulate how + the parent process creates children to serve requests. In general, + Apache is very self-regulating, so most sites do not need to + adjust these directives from their default values. Sites which + need to serve more than 256 simultaneous requests may need to + increase MaxClients, + while sites with limited memory may need to decrease MaxClients to keep the server from + thrashing (swapping memory to disk and back). More information + about tuning process creation is provided in the performance hints + documentation.

    + +

    While the parent process is usually started as root + under Unix in order to bind to port 80, the child processes are + launched by Apache as a less-privileged user. The User and Group directives are used to set + the privileges of the Apache child processes. The child processes + must be able to read all the content that will be served, but + should have as few privileges beyond that as possible.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing + old ones and launching new ones.

    +
    + +CoreDumpDirectory + +EnableExceptionHook + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +User + +Group + +AcceptMutex + + + +MaxSpareServers +Maximum number of idle child server processes +MaxSpareServers number +MaxSpareServers 10 +server config + + +

    The MaxSpareServers directive sets the + desired maximum number of idle child server processes. An + idle process is one which is not handling a request. If there are + more than MaxSpareServers idle, then the + parent process will kill off the excess processes.

    + +

    Tuning of this parameter should only be necessary on very + busy sites. Setting this parameter to a large number is almost + always a bad idea. If you are trying to set the value equal to or lower than + MinSpareServers, Apache + will automatically adjust it to MinSpareServers + 1.

    +
    +MinSpareServers +StartServers +
    + + +MinSpareServers +Minimum number of idle child server processes +MinSpareServers number +MinSpareServers 5 +server config + + +

    The MinSpareServers directive sets the + desired minimum number of idle child server processes. An + idle process is one which is not handling a request. If there are + fewer than MinSpareServers idle, then the parent + process creates new children at a maximum rate of 1 per second.

    + +

    Tuning of this parameter should only be necessary on very + busy sites. Setting this parameter to a large number is almost + always a bad idea.

    +
    +MaxSpareServers +StartServers +
    + +
    + diff --git a/trunk/docs/manual/mod/prefork.xml.de b/trunk/docs/manual/mod/prefork.xml.de new file mode 100644 index 0000000000..0471887b7c --- /dev/null +++ b/trunk/docs/manual/mod/prefork.xml.de @@ -0,0 +1,181 @@ + + + + + + + + + +prefork +Implementiert einen im Voraus forkenden Webserver ohne + Thread-Unterstützung +MPM +prefork.c +mpm_prefork_module + + +

    Dieses Multi-Processing-Modul (MPM) implementiert einen + im Voraus forkenden Webserver ohne Thread-Unterstützung, der Anfragen + auf ähnliche Weise behandelt wie der Apache 1.3. Es ist für + Angebote geeignet, die aus Kompatibilitätsgründen mit + nicht-Thread-sicheren Bibliotheken Threading vermeiden müssen. + Es ist außerdem das geeignetste MPM, um jede Anfrage isoliert + zu bearbeiten, so dass Probleme mit einem einzelnen Prozess keinen + anderen beeinflussen.

    + +

    Das MPM ist stark selbstregulierend, so dass es selten + notwendig ist, seine Konfigurationseinstellungen zu justieren. Das + Wichtigste ist, dass MaxClients + gross genug ist, so viele gleichzeitige Anfragen zu bedienen, wie Sie + erwarten, aber klein genug, um sicherzustellen, dass genug physischer + Arbeitsspeicher für alle Prozesse vorhanden ist.

    +
    +Bestimmen der vom Apache verwendeten Adressen + und Ports + +
    Arbeitsweise +

    Ein einzelner Steuerprozess ist für den Start von + Kindprozessen verantwortlich, die auf Verbindungen warten und diese + bedienen, sobald sie eintreffen. Der Apache versucht immer, mehrere + freie oder unbeschäftigte Serverprozesse vorzuhalten, + die zur Bedienung eingehender Anfragen bereit stehen. Auf diese Weise + müssen Clients nicht darauf warten, dass neue Kindprozesse + geforkt werden, bevor ihre Anfrage bearbeitet werden kann.

    + +

    StartServers, + MinSpareServers, + MaxSpareServers und + MaxClients regulieren, + wie der Elternprozess Kindprozesse zur Bedienung von Anfragen erstellt. + Im Allgemeinen ist der Apache sehr selbstregulierend, so dass die meisten + Angebote die Voreinstellung dieser Direktiven nicht verändern + müssen. Systeme, die mehr als 256 gleichzeitige Anfragen bedienen + müssen, können MaxClients erhöhen, während + Systeme mit begrenztem Arbeitsspeicher möglicherweise + MaxClients heruntersetzen + müssen, um den Server vor Flatterverhalten (Arbeitsspeicherinhalte auf + Platte auslagern - und zurück) zu schützen. Weitere + Informationen zur Feinabstimmung der Prozesserstellung sind in den + Performance-Hinweisen zu + finden.

    + +

    Währen der Elternprozess unter Unix normalerweise als + root gestartet wird, um sich an Port 80 binden zu können, + werden die Kindprozesse unter einem weniger privilegierten Benutzer + gestartet. Die Direktiven User + und Group werden dazu + verwendet, die Privilegien der Apache-Kindprozesse festzulegen. Die + Kindprozesse müssen in der Lage sein, alle Inhalte zu lesen, die + sie ausliefern sollen, sollten darüber hinaus jedoch so wenig wie + möglich Rechte besitzen.

    + +

    MaxRequestsPerChild + bestimmt, wie häufig der Server Prozesse erneuert, indem er alte + beendet und neue startet.

    +
    + +CoreDumpDirectory + +EnableExceptionHook + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +User + +Group + +AcceptMutex + + + +MaxSpareServers +Maximale Anzahl der unbeschäftigten Kindprozesse des + Servers +MaxSpareServers Anzahl +MaxSpareServers 10 +server config + + +

    Die Direktive MaxSpareServers bestimmt das + gewünschte Maximum an unbeschäftigten + Kindprozessen des Servers. Ein unbeschäftiger Prozess ist einer, der + keine Anfrage bedient. Wenn mehr als MaxSpareServers + Prozesse unbeschäftigt sind, wird der Elternprozess die + überschüssigen Prozesse beenden.

    + +

    Eine Feineinstellung dieses Parameters sollte nur bei sehr + beschäftigten Angeboten notwendig sein. Es ist nahezu immer eine + schlechte Idee, den Parameter auf einen hohen Wert zu setzen. Wenn Sie + versuchen, den Wert kleiner oder gleich MinSpareServers zu setzen, wird der Apache + ihn automatisch auf MinSpareServers + 1 + korrigieren.

    +
    +MinSpareServers +StartServers +
    + + +MinSpareServers +Minimale Anzahl der unbeschäftigten Kindprozesse des + Servers +MinSpareServers Anzahl +MinSpareServers 5 +server config + + +

    Die Direktive MinSpareServers bestimmt das + gewünschte Minimum der unbeschäftigten + Kindprozesse des Servers. Ein unbeschäftigter Prozess ist einer, der + keine Anfrage bedient. Wenn weniger als + MinSpareServers Prozesse unbeschäftigt sind, + dann erstellt der Elternprozess neue mit einer maximalen Rate von 1 + pro Sekunde.

    + +

    Die Feineinstellung des Parameters sollte nur bei sehr + beschäftigten Angeboten notwendig sein. Es ist nahezu immer eine + schlechte ide, den Parameter auf einen hohen Wert zu setzen.

    +
    +MaxSpareServers +StartServers +
    + +
    diff --git a/trunk/docs/manual/mod/prefork.xml.ja b/trunk/docs/manual/mod/prefork.xml.ja new file mode 100644 index 0000000000..b1d9a6e179 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.xml.ja @@ -0,0 +1,177 @@ + + + + + + + + + +prefork +$B%9%l%C%I$r;H$o$:!"@h9T$7$F(B fork $B$r9T$J$&%&%'%V%5!<%P$r +MPM +prefork.c +mpm_prefork_module + + +

    $B$3$N%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) $B$O!"(B + Unix $B>e$G$N(B Apache 1.3 $B$N%G%U%)%k%H$N5sF0$HHs>o$K$h$/;w$?J}K!$G(B + $B%j%/%(%9%H$r=hM}$9$k!"%9%l%C%I$r;H$o$:!"@h9T$7$F(B fork $B$r9T$J$&(B + $B%&%'%V%5!<%P$r$N%j%/%(%9%H$K1F6A$7$J$$$h$&$K!"(B + $B8D!9$N%j%/%(%9%H$rC1N%$9$k$N$K$b!":GE,$J(B MPM $B$G$9!#(B

    + +

    $B$3$N(B MPM $B$OHs>o$K<+N'E*$J$N$G!"$3$N(B MPM $B$N@_Dj%G%#%l%/%F%#%V$r(B + $BD4@0$9$kI,MW$O$[$H$s$I$J$$$G$7$g$&!#$b$C$H$b=EMW$J$3$H$O!"(B + MaxClients + $B$,!"M=A[$5$l$kF1;~%j%/%(%9%H?t$r==J,07$($k$0$i$$$OBg$-$$$1$l$I$b!"(B + $BA4%W%m%;%9$K==J,$JJ*M}%a%b%j$,3N.$5$$CM$K$9$k!"(B + $B$H$$$&$3$H$G$9!#(B

    + +
    +Apache +$B$,;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj(B + +
    $BF0:nJ}K!(B +

    $B0l$D$N%3%s%H%m!<%k%W%m%;%9$,!"(B + $B%3%M%/%7%g%s$KBP$7$F(B listen $B$7$F!"$7$+$k$Y$-;~$K1~Ez$9$k(B + $B;R%W%m%;%9$r5/F0$7$^$9!#(BApache $B$O>o$K4v$D$+$N(B$B%9%Z%"(B + $B$+%"%$%I%k$J%5!<%P%W%m%;%9$r0];}$7$F$$$F!"$=$l$i$OF~$C$F$-$?(B + $B%j%/%(%9%H$K1~Ez$G$-$k$h$&$KBT5!$7$F$$$^$9!#(B + $B$3$N$h$&$K$7$F%/%i%$%"%s%H$O!"%j%/%(%9%H$,1~Ez$5$l$kA0$K!"(B + $B?7$7$$;R%W%m%;%9$,(B fork $B$5$l$k$N$rBT$?$J$/$F$b$h$$$h$&$K(B + $B$J$C$F$$$^$9!#(B

    + +

    $B?F%W%m%;%9$,%j%/%(%9%H$K1~Ez$9$k$N;R%W%m%;%9$r(B + $B$I$N$h$&$K@8@.$9$k$+$O!"(B + StartServers, + MinSpareServers, + MaxSpareServers, + MaxClients + $B$GD4@0$7$^$9!#0lHLE*$K!"(BApache $B$OHs>o$K<+N'E*$J$N$G!"(B + $BBgDq$N%5%$%H$G$O$3$l$i$N%G%#%l%/%F%#%V$r%G%U%)%k%HCM$+$iD4@0$9$k(B + $BI,MW$O$J$$$G$7$g$&!#(B + $BF1;~$K(B 256 $B$rD6$($k%j%/%(%9%H$K1~Ez$7$J$$$H$$$1$J$$%5%$%H$G$O!"(B + MaxClients + $B$rA}$d$9I,MW$,$"$k$G$7$g$&!#(B + $B0lJ}!"%a%b%j$N8B$i$l$F$$$k%5%$%H$G$O!"%9%i%C%7%s%0(B + ($B%a%b%j$H%G%#%9%/4V$G2?EY$b%9%o%C%W(B) $B$,5/$3$k$N$rKI$0$?$a$K(B + MaxClients + $B$r8:$i$9I,MW$,$"$k$G$7$g$&!#%W%m%;%9@8@.$N%A%e!<%K%s%0$K4X$9$k(B + $B>\$7$$>pJs$O!"(B$B@-G=$K4X$9$k%R%s%H(B + $B$K$"$j$^$9!#(B

    + +

    $BDL>o(B Unix $B$G$O?F%W%m%;%9$O(B 80 $BHV%]!<%H$K%P%$%s%I$9$k$?$a$K(B + root $B$G5/F0$5$l$^$9$,!";R%W%m%;%9$d%9%l%C%I$O(B + $B$b$C$HDc$$8"8B$N%f!<%6$G(B Apache $B$K$h$C$F5/F0$5$l$^$9!#(B + User $B$H(B + Group + $B%G%#%l%/%F%#%V$O(B + Apache $B$N;R%W%m%;%9$N8"8B$r@_Dj$9$k$N$KMQ$$$i$l$^$9!#(B + $B;R%W%m%;%9$O%/%i%$%"%s%H$KAw$k%3%s%F%s%DA4$F$rFI$a$J$$$H$$$1$^$;$s$,!"(B + $B2DG=$J8B$jI,MW:G>.8B$N8"8B$N$_$r;}$C$F$$$k$h$&$K$9$k$Y$-$G$9!#(B

    + +

    MaxRequestsPerChild + $B$O!"8E$$%W%m%;%9$rDd;_$7$F?7$7$$%W%m%;%9$r5/F0$9$k$3$H$K$h$C$F!"(B + $B$I$NDxEY$NIQEY$G%5!<%P$,%W%m%;%9$r%j%5%$%/%k$9$k$+$r@)8f$7$^$9!#(B

    +
    + +CoreDumpDirectory + +EnableExceptionHook + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +User + +Group + +AcceptMutex + + + +MaxSpareServers +$B%"%$%I%k$J;R%5!<%P%W%m%;%9$N:GBg8D?t(B +MaxSpareServers number +MaxSpareServers 10 +server config + + +

    MaxSpareServers $B%G%#%l%/%F%#%V$O!"(B + $B%"%$%I%k$J(B$B;R%5!<%P%W%m%;%9$N4uK>:GBg8D?t$r@_Dj$7$^$9!#(B + $B%"%$%I%k%W%m%;%9$H$O!"%j%/%(%9%H$r07$C$F$$$J$$%W%m%;%9$G$9!#(B + MaxSpareServers $B$h$j$bB?$$?t$,%"%$%I%k$G$"$l$P!"(B + $B?F%W%m%;%9$OD62a%W%m%;%9$r(B kill $B$7$^$9!#(B

    + +

    $BHs>o$K:.$s$G$$$k%5%$%H$G$N$_!"$3$N%Q%i%a!<%?$r%A%e!<%K%s%0$9$k$Y$-$G$9!#(B + $B$3$N%Q%i%a!<%?$rBg$-$/$9$k$H$$$&$3$H$O!"BgDq$N>l9g$O0-$$H/A[$G$9!#(B + MinSpareServers + $B0J2<$K@_Dj$7$?>l9g!"(BMinSpareServers + +1 $B$K<+F0D4@0$5$l$^$9!#(B

    +
    +MinSpareServers +StartServers +
    + + +MinSpareServers +$B%"%$%I%k$J;R%5!<%P%W%m%;%9$N:G>.8D?t(B +MinSpareServers number +MinSpareServers 5 +server config + + +

    MaxSpareServers $B%G%#%l%/%F%#%V$O!"(B + $B%"%$%I%k$J(B$B;R%5!<%P%W%m%;%9$N4uK>:G>.8D?t$r@_Dj$7$^$9!#(B + $B%"%$%I%k%W%m%;%9$H$O!"%j%/%(%9%H$r07$C$F$$$J$$%W%m%;%9$G$9!#(B + MinSpareServers $B$h$j$b>/$J$$?t$,%"%$%I%k$G$"$l$P!"(B + $B?F%W%m%;%9$O:G9b$G(B 1 $BIC$K$D$-(B 1 $B8D$N3d9g$G?7$7$$;R%W%m%;%9$r@8@.$7$^$9!#(B

    + +

    $BHs>o$K:.$s$G$$$k%5%$%H$G$N$_!"$3$N%Q%i%a!<%?$r%A%e!<%K%s%0$9$k$Y$-$G$9!#(B + $B$3$N%Q%i%a!<%?$rBg$-$/$9$k$H$$$&$3$H$O!"BgDq$N>l9g$O0-$$H/A[$G$9!#(B

    +
    +MaxSpareServers +StartServers +
    + +
    + diff --git a/trunk/docs/manual/mod/prefork.xml.meta b/trunk/docs/manual/mod/prefork.xml.meta new file mode 100644 index 0000000000..ae83abfd34 --- /dev/null +++ b/trunk/docs/manual/mod/prefork.xml.meta @@ -0,0 +1,13 @@ + + + + prefork + /mod/ + .. + + + de + en + ja + + diff --git a/trunk/docs/manual/mod/quickreference.html b/trunk/docs/manual/mod/quickreference.html new file mode 100644 index 0000000000..c2795e8fcf --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html @@ -0,0 +1,19 @@ +URI: quickreference.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: quickreference.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: quickreference.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: quickreference.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: quickreference.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mod/quickreference.html.de b/trunk/docs/manual/mod/quickreference.html.de new file mode 100644 index 0000000000..c7574e196c --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html.de @@ -0,0 +1,765 @@ + + + +Kurzreferenz der Direktiven - Apache HTTP Server + + + + + + +
    <-
    + +

    Kurzreferenz der Direktiven

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Die Kurzreferenz der Direktiven zeigt die Verwendung, + Voreinstellung, den Status und den Kontext aller + Apache-Konfigurationsanweisungen. Für weitergehende Informationen + schauen Sie bitte im Verzeichnis der Direktiven.

    + +

    Die erste Spalte enthält den Namen und die Verwendung. + Die zweite Spalte zeigt die Voreinstellung der Direktive, sofern + eine Voreinstellung existiert. Wenn die Voreinstellung zu breit + für die Anzeige ist, werden die ersten Buchstaben angegeben, + gefolgt von einem "+".

    + +

    Die dritte und vierte Spalte geben den Kontext an, in dem die + Direktive erlaubt ist, sowie den Status der Direktive entsprechend + der Legende.

    +
    +
    + + + +
     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X  + + + + + +
    sServerkonfiguration
    vVirtual Host
    dVerzeichnis
    h.htaccess
    + + + + + + +
    CCore
    MMPM
    BBasis
    EErweiterung
    Xexperimentell
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AcceptMutex Default|Methode Default sM
    Vom Apache verwendete Methode zur Serialisierung mehrerer + Kindprozesse, die Anfragen an Netzwerk-Sockets entgegennehmen.
    AcceptPathInfo On|Off|Default Default svdhC
    Ressourcen lassen angehängte Pfadangaben zu
    AccessFileName Dateiname [Dateiname] ... .htaccess svC
    Name der dezentralen Konfigurationsdateien
    Action Aktionsart CGI-Skript [virtual]svdhB
    Aktiviert ein CGI-Skript für einen bestimmten Handler oder + Content-Type
    AddAlt string file [file] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by filename
    AddAltByEncoding string MIME-encoding +[MIME-encoding] ...svdhB
    Alternate text to display for a file instead of an icon +selected by MIME-encoding
    AddAltByType string MIME-type +[MIME-type] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by MIME content-type
    AddCharset charset extension +[extension] ...svdhB
    Maps the given filename extensions to the specified content +charset
    AddDefaultCharset On|Off|Zeichenkodierung Off svdhC
    Standard-Charset-Parameter, der bei Antworten vom Content-Type + text/plain oder text/html hinzugefügt wird +
    AddDescription string file [file] ...svdhB
    Description to display for a file
    AddEncoding MIME-enc extension +[extension] ...svdhB
    Maps the given filename extensions to the specified encoding +type
    AddHandler handler-name extension +[extension] ...svdhB
    Maps the filename extensions to the specified +handler
    AddIcon icon name [name] +...svdhB
    Icon to display for a file selected by name
    AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...svdhB
    Icon to display next to files selected by MIME +content-encoding
    AddIconByType icon MIME-type +[MIME-type] ...svdhB
    Icon to display next to files selected by MIME +content-type
    AddInputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +client requests
    AddLanguage MIME-lang extension +[extension] ...svdhB
    Maps the given filename extension to the specified content +language
    AddModuleInfo module-name stringsvE
    Adds additional information to the module +information displayed by the server-info handler
    AddOutputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +responses from the server
    AddOutputFilterByType Filter[;Filter...] +MIME-Type [MIME-Type] ...svdhC
    einen Ausgabefilter einem bestimmten MIME-Type +zuordnen
    AddType MIME-type extension +[extension] ...svdhB
    Maps the given filename extensions onto the specified content +type
    Alias URL-path +file-path|directory-pathsvB
    Maps URLs to filesystem locations
    AliasMatch regex +file-path|directory-pathsvB
    Maps URLs to filesystem locations using regular +expressions
    Allow from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts can access an area of the +server
    AllowCONNECT port [port] ... 443 563 svE
    Ports that are allowed to CONNECT through the +proxy
    AllowEncodedSlashes On|Off Off svC
    Legt fest, ob kodierte Pfadtrennzeichen in URLs durchgereicht +werden dürfen
    AllowOverride All|None|Direktiven-Typ +[Direktiven-Typ] ... All dC
    Direktiven-Typen, die in .htaccess-Dateien +erlaubt sind.
    Anonymous user [user] ...dhE
    Specifies userIDs that are allowed access without +password verification
    Anonymous_LogEmail On|Off On dhE
    Sets whether the password entered will be logged in the +error log
    Anonymous_MustGiveEmail On|Off On dhE
    Specifies whether blank passwords are allowed
    Anonymous_NoUserID On|Off Off dhE
    Sets whether the userID field may be empty
    Anonymous_VerifyEmail On|Off Off dhE
    Sets whether to check the password field for a correctly +formatted email address
    AssignUserID user-id group-idvM
    Tie a virtual host to a user and group ID
    AuthBasicAuthoritative On|Off On dhB
    Sets whether authorization and authentication are passed to +lower level modules
    AuthBasicProvider On|Off|provider-name +[provider-name] ... On dhB
    Sets the authentication provider(s) for this location
    AuthDBMGroupFile file-pathdhE
    Sets the name of the database file containing the list +of user groups for authorization
    AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store passwords
    AuthDBMUserFile file-pathdhE
    Sets the name of a database file containing the list of users and +passwords for authentication
    AuthDefaultAuthoritative On|Off On dhB
    Sets whether authentication is passed to lower level +modules
    AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
    Selects the algorithm used to calculate the challenge and +response hashes in digest authentication
    AuthDigestDomain URI [URI] ...dhX
    URIs that are in the same protection space for digest +authentication
    AuthDigestNcCheck On|Off Off sX
    Enables or disables checking of the nonce-count sent by the +server
    AuthDigestNonceFormat formatdhX
    Determines how the nonce is generated
    AuthDigestNonceLifetime seconds 300 dhX
    How long the server nonce is valid
    AuthDigestProvider On|Off|provider-name +[provider-name] ... On dhX
    Sets the authentication provider(s) for this location
    AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhX
    Determines the quality-of-protection to use in digest +authentication
    AuthDigestShmemSize size 1000 sX
    The amount of shared memory to allocate for keeping track +of clients
    AuthGroupFile file-pathdhB
    Sets the name of a text file containing the list +of user groups for authorization
    AuthLDAPBindDN distinguished-namedhE
    Optional DN to use in binding to the LDAP server
    AuthLDAPBindPassword passworddhE
    Password used in conjuction with the bind DN
    AuthLDAPCharsetConfig file-pathsE
    Language to charset conversion configuration file
    AuthLDAPCompareDNOnServer on|off on dhE
    Use the LDAP server to compare the DNs
    AuthLDAPDereferenceAliases never|searching|finding|always Always dhE
    When will the module de-reference aliases
    AuthLDAPGroupAttribute attributedhE
    LDAP attributes used to check for group membership
    AuthLDAPGroupAttributeIsDN on|off on dhE
    Use the DN of the client username when checking for +group membership
    AuthLDAPRemoteUserIsDN on|off off dhE
    Use the DN of the client username to set the REMOTE_USER +environment variable
    AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]dhE
    URL specifying the LDAP search parameters
    AuthName auth-BereichdhC
    Autorisierungsbereich zur Verwendung in der +HTTP-Authentisierung
    <AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>svE
    Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    AuthType Basic|DigestdhC
    Art der Authentisierung
    AuthUserFile file-pathdhB
    Sets the name of a text file containing the list of users and +passwords for authentication
    AuthzDBMAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store list of user groups
    AuthzDefaultAuthoritative On|Off On dhB
    Sets whether authorization is passed to lower level +modules
    AuthzGroupFileAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    AuthzLDAPAuthoritative on|off on dhE
    Prevent other authentication modules from +authenticating the user if this one fails
    AuthzOwnerAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzUserAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on HTTP User-Agent +
    BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on User-Agent without +respect to case
    BufferedLogs On|Off Off sB
    Buffer log entries in memory before writing to disk
    CacheDefaultExpire seconds 3600 (one hour) svE
    The default duration to cache a document when no expiry date is specified.
    CacheDirLength length 2 svE
    The number of characters in subdirectory names
    CacheDirLevels levels 3 svE
    The number of levels of subdirectories in the +cache.
    CacheDisable url-stringsvE
    Disable caching of specified URLs
    CacheEnable cache_type url-stringsvE
    Enable caching of specified URLs using a specified storage +manager
    CacheFile file-path [file-path] ...sX
    Cache a list of file handles at startup time
    CacheIgnoreCacheControl On|Off Off svE
    Ignore request to not serve cached content to client
    CacheIgnoreHeaders header-string [header-string] ... None svE
    Do not store the given HTTP header(s) in the cache. +
    CacheIgnoreNoLastMod On|Off Off svE
    Ignore the fact that a response has no Last Modified +header.
    CacheLastModifiedFactor float 0.1 svE
    The factor used to compute an expiry date based on the +LastModified date.
    CacheMaxExpire seconds 86400 (one day) svE
    The maximum time in seconds to cache a document
    CacheMaxFileSize bytes 1000000 svE
    The maximum size (in bytes) of a document to be placed in the +cache
    CacheMinFileSize bytes 1 svE
    The minimum size (in bytes) of a document to be placed in the +cache
    CacheNegotiatedDocs On|Off Off svB
    Allows content-negotiated documents to be +cached by proxy servers
    CacheRoot directorysvE
    The directory root under which cache files are +stored
    CacheStoreNoStore On|Off Off svE
    Attempt to cache requests or responses that have been marked as no-store.
    CacheStorePrivate On|Off Off svE
    Attempt to cache responses that the server has marked as private
    CGIMapExtension CGI-Pfad .EndungdhC
    Technik zur Bestimmung des Interpreters für +CGI-Skripte
    CharsetDefault charsetsvdhX
    Charset to translate into
    CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
    Configures charset translation behavior
    CharsetSourceEnc charsetsvdhX
    Source charset of files
    CheckSpelling on|off Off svdhE
    Enables the spelling +module
    ChildPerUserID user-id group-id +num-childrensM
    Specify user ID and group ID for a number of child +processes
    ContentDigest On|Off Off svdhC
    Aktiviert die Generierung von Content-MD5 +HTTP-Response-Headern
    CookieDomain domainsvdhE
    The domain to which the tracking cookie applies
    CookieExpires expiry-periodsvdhE
    Expiry time for the tracking cookie
    CookieLog filenamesvB
    Sets filename for the logging of cookies
    CookieName token Apache svdhE
    Name of the tracking cookie
    CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
    Format of the cookie header field
    CookieTracking on|off off svdhE
    Enables tracking cookie
    CoreDumpDirectory VerzeichnissM
    Verzeichnis, in das der Apache zu wechseln versucht, bevor er + einen Hauptspeicherauszug erstellt
    CustomLog file|pipe +format|nickname +[env=[!]environment-variable]svB
    Sets filename and format of log file
    Dav On|Off|provider-name Off dE
    Enable WebDAV HTTP methods
    DavDepthInfinity on|off off svdE
    Allow PROPFIND, Depth: Infinity requests
    DavGenericLockDB file-pathsvdE
    Location of the DAV lock database
    DavLockDB file-pathsvE
    Location of the DAV lock database
    DavMinTimeout seconds 0 svdE
    Minimum amount of time the server holds a lock on +a DAV resource
    DBDExptime time-in-secondssvX
    Keepalive time for idle connections
    DBDKeep numbersvX
    Maximum sustainednumber of connections
    DBDMax numbersvX
    Maximum number of connections
    DBDMin numbersvX
    Minimum number of connections
    DBDParams +param1=value1[,param2=value2]svX
    Parameters for database connection
    DBDPersist 0|1svX
    Whether to use persistent connections
    DBDPrepareSQL "SQL statement" labelsvX
    Define an SQL prepared statement
    DBDriver namesvX
    Specify an SQL driver
    DefaultIcon url-pathsvdhB
    Icon to display for files when no specific icon is +configured
    DefaultLanguage MIME-langsvdhB
    Sets all files in the given scope to the specified +language
    DefaultType MIME-Type text/plain svdhC
    MIME-Content-Type, der gesendet wird, wenn der Server den Typ +nicht auf andere Weise ermitteln kann.
    DeflateBufferSize value 8096 svE
    Fragment size to be compressed at one time by zlib
    DeflateCompressionLevel valuesvE
    How much compression do we apply to the output
    DeflateFilterNote [type] notenamesvE
    Places the compression ratio in a note for logging
    DeflateMemLevel value 9 svE
    How much memory should be used by zlib for compression
    DeflateWindowSize value 15 svE
    Zlib compression window size
    Deny from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts are denied access to the +server
    <Directory Verzeichnispfad> +... </Directory>svC
    Umschließt eine Gruppe von Direktiven, die nur auf +das genannte Verzeichnis des Dateisystems und Unterverzeichnisse angewendet +werden
    DirectoryIndex + local-url [local-url] ... index.html svdhB
    List of resources to look for when the client requests +a directory
    <DirectoryMatch regex> +... </DirectoryMatch>svC
    Umschließt eine Gruppe von Direktiven, die auf + Verzeichnisse des Dateisystems und ihre Unterverzeichnisse abgebildet + werden, welche auf einen regulären Ausdruck passen
    DirectorySlash On|Off On svdhB
    Toggle trailing slash redirects on or off
    DocumentRoot Verzeichnis /usr/local/apache/h +svC
    Verzeichnis, welches den Haupt-Dokumentenbaum bildet, der im +Web sichtbar ist.
    DumpIOInput On|Off Off sE
    Dump all input data to the error log
    DumpIOOutput On|Off Off sE
    Dump all output data to the error log
    EnableExceptionHook On|Off Off sM
    Aktiviert einen Hook, der nach einem Absturz noch +Ausnahmefehler behandeln lassen kann
    EnableMMAP On|Off On svdhC
    Verwende Memory-Mapping, um Dateien während der +Auslieferung zu lesen
    EnableSendfile On|Off On svdhC
    Verwende die sendfile-Unterstützung des Kernels, um +Dateien an den Client auszuliefern
    ErrorDocument Fehlercode DokumentsvdhC
    Das, was der Server im Fehlerfall an den Client +zurückgibt
    ErrorLog Dateiname|syslog[:facility] logs/error_log (Uni +svC
    Ablageort, an dem der Server Fehler protokolliert
    ExamplesvdhX
    Demonstration directive to illustrate the Apache module +API
    ExpiresActive On|OffsvdhE
    Enables generation of Expires +headers
    ExpiresByType MIME-type +<code>secondssvdhE
    Value of the Expires header configured +by MIME type
    ExpiresDefault <code>secondssvdhE
    Default algorithm for calculating expiration time
    ExtendedStatus On|Off Off sB
    Keep track of extended status information for each +request
    ExtFilterDefine filtername parameterssE
    Define an external filter
    ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
    Configure mod_ext_filter options
    FileETag Komponente ... INode MTime Size svdhC
    Dateiattribute, die zur Erstellung des HTTP-Response-Headers +ETag verwendet werden
    <Files Dateiname> ... </Files>svdhC
    Enthält Direktiven, die sich nur auf passende Dateinamen +beziehen
    <FilesMatch regex> ... </FilesMatch>svdhC
    Enthält Direktiven, die für Dateinamen gelten, die + auf einen regulären Ausdruck passen
    FilterChain [+=-@!]filter-name ...svdhX
    Configure the filter chain
    FilterDeclare filter-name [type]svdhX
    Declare a smart filter
    FilterProtocol filter-name [provider-name] + proto-flagssvdhX
    Deal with correct HTTP protocol handling
    FilterProvider filter-name provider-name + [req|resp|env]=dispatch matchsvdhX
    Register a content filter
    FilterTrace filter-name levelsvdX
    Get debug/diagnostic information from + mod_filter
    ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
    Action to take if a single acceptable document is not +found
    ForceType MIME-Type|NonedhC
    Erzwingt die Auslieferung aller passendenden Dateien mit dem +angegebenen MIME-Content-Type
    ForensicLog filename|pipesvE
    Sets filename of the forensic log
    Group Unix-Gruppe #-1 sM
    Benutzergruppe, unter welcher der Server Anfragen + beantwortet
    Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]svdhE
    Configure HTTP response headers
    HeaderName filenamesvdhB
    Name of the file that will be inserted at the top +of the index listing
    HostnameLookups On|Off|Double Off svdC
    Aktiviert DNS-Lookups auf Client-IP-Adressen
    IdentityCheck On|Off Off svdE
    Enables logging of the RFC 1413 identity of the remote +user
    IdentityCheckTimeout seconds 30 svdE
    Determines the timeout duration for ident requests
    <IfDefine [!]Parametername> ... + </IfDefine>svdhC
    Schließt Direktiven ein, die nur ausgeführt werden, +wenn eine Testbedingung beim Start wahr ist
    <IfModule [!]Modulname|Modulbezeichner> + ... </IfModule>svdhC
    Schließt Direktiven ein, die abhängig vom +Vorhandensein oder Fehlen eines speziellen Moduls ausgeführt +werden
    <IfVersion [[!]operator] version> ... +</IfVersion>svdhE
    contains version dependent configuration
    ImapBase map|referer|URL http://servername/ svdhB
    Default base for imagemap files
    ImapDefault error|nocontent|map|referer|URL nocontent svdhB
    Default action when an imagemap is called with coordinates +that are not explicitly mapped
    ImapMenu none|formatted|semiformatted|unformattedsvdhB
    Action if no coordinates are given when calling +an imagemap
    Include Dateiname|VerzeichnissvdC
    Fügt andere Konfigurationsdateien innerhalb der +Server-Konfigurationsdatei ein
    IndexIgnore file [file] ...svdhB
    Adds to the list of files to hide when listing +a directory
    IndexOptions [+|-]option [[+|-]option] +...svdhB
    Various configuration settings for directory +indexing
    IndexOrderDefault Ascending|Descending +Name|Date|Size|Description Ascending Name svdhB
    Sets the default ordering of the directory index
    IndexStyleSheet url-pathsvdhB
    Adds a CSS stylesheet to the directory index
    ISAPIAppendLogToErrors on|off off svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log
    ISAPIAppendLogToQuery on|off on svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field
    ISAPICacheFile file-path [file-path] +...svB
    ISAPI .dll files to be loaded at startup
    ISAPIFakeAsync on|off off svdhB
    Fake asynchronous support for ISAPI callbacks
    ISAPILogNotSupported on|off off svdhB
    Log unsupported feature requests from ISAPI +extensions
    ISAPIReadAheadBuffer size 49152 svdhB
    Size of the Read Ahead Buffer sent to ISAPI +extensions
    KeepAlive On|Off On svC
    Aktiviert persistente HTTP-Verbindungen
    KeepAliveTimeout Sekunden 5 svC
    Zeitspanne, die der Server während persistenter Verbindungen +auf nachfolgende Anfragen wartet
    LanguagePriority MIME-lang [MIME-lang] +...svdhB
    The precendence of language variants for cases where +the client does not express a preference
    LDAPCacheEntries number 1024 sE
    Maximum number of entries in the primary LDAP cache
    LDAPCacheTTL seconds 600 sE
    Time that cached items remain valid
    LDAPConnectionTimeout secondssE
    Specifies the socket connection timeout in seconds
    LDAPOpCacheEntries number 1024 sE
    Number of entries used to cache LDAP compare +operations
    LDAPOpCacheTTL seconds 600 sE
    Time that entries in the operation cache remain +valid
    LDAPSharedCacheFile directory-path/filenamesE
    Sets the shared memory cache file
    LDAPSharedCacheSize bytes 102400 sE
    Size in bytes of the shared-memory cache
    LDAPTrustedClientCert type directory-path/filename/nickname [password]svdhE
    Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    LDAPTrustedGlobalCert type directory-path/filename [password]sE
    Sets the file or database containing global trusted +Certificate Authority or global client certificates
    LDAPTrustedMode typesvdhE
    Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    LDAPVerifyServerCert On|Off On sE
    Force server certificate verification
    <Limit Methode [Methode] ... > ... + </Limit>svdhC
    Beschränkt die eingeschlossenen Zugriffskontrollen auf +bestimmte HTTP-Methoden
    <LimitExcept Methode [Methode] ... > ... + </LimitExcept>svdhC
    Beschränkt Zugriffskontrollen auf alle HTTP-Methoden +außer den genannten
    LimitInternalRecursion Zahl [Zahl] 10 svC
    Bestimmt die maximale Anzahl interner Umleitungen und + verschachtelter Unteranfragen
    LimitRequestBody Bytes 0 svdhC
    Begrenzt die Gesamtgröße des vom Client gesendeten +HTTP-Request-Body
    LimitRequestFields Anzahl 100 sC
    Begrenzt die Anzahl der HTTP-Request-Header, die vom Client +entgegengenommen werden
    LimitRequestFieldsize BytessC
    Begrenzt die Länge des vom Client gesendeten +HTTP-Request-Headers
    LimitRequestLine Bytes 8190 sC
    Begrenzt die Länge der vom Client entgegengenommenen +HTTP-Anfragezeile
    LimitXMLRequestBody Bytes 1000000 svdhC
    Begrenzt die Größe eines XML-basierten +Request-Bodys
    Listen [IP-Addresse:]PortsM
    IP-Adressen und Ports, an denen der Server lauscht
    ListenBacklog backlogsM
    Maximale Länge der Warteschlange schwebender + Verbindungen
    LoadFile filename [filename] ...sE
    Link in the named object file or library
    LoadModule module filenamesE
    Links in the object file or library, and adds to the list +of active modules
    <Location + URL-Pfad|URL> ... </Location>svC
    Wendet die enthaltenen Direktiven nur auf die entsprechenden +URLs an
    <LocationMatch + regex> ... </LocationMatch>svC
    Wendet die enthaltenen Direktiven nur auf URLs an, die auf +reguläre Ausdrücke passen
    LockFile Dateiname logs/accept.lock sM
    Ablageort der Lock-Datei für die Serialisierung von +entgegengenommenen Anfragen
    LogFormat format|nickname +[nickname] "%h %l %u %t \"%r\" +svB
    Describes a format for use in a log file
    LogLevel Level warn svC
    Steuert die Ausführlichkeit des Fehlerprotokolls
    MaxClients AnzahlsM
    Maximale Anzahl der Kindprozesse, die zur Bedienung von Anfragen + gestartet wird
    MaxKeepAliveRequests Anzahl 100 svC
    Anzahl der Anfragen, die bei einer persistenten Verbindung +zulässig sind
    MaxMemFree KBytes 0 sM
    Maximale Menge des Arbeitsspeichers, den die + Haupt-Zuteilungsroutine verwalten darf, ohne free() + aufzurufen
    MaxRequestsPerChild number 10000 sM
    Obergrenze für die Anzahl von Anfragen, die ein einzelner + Kindprozess während seines Lebens bearbeitet
    MaxRequestsPerThread Anzahl 0 sM
    Die maximale Anzahl von Anfragen, die ein einzelner Thread + während seiner Lebensdauer bedient.
    MaxSpareServers Anzahl 10 sM
    Maximale Anzahl der unbeschäftigten Kindprozesse des + Servers
    MaxSpareThreads AnzahlsM
    Maximale Anzahl unbeschäftigter Threads
    MaxThreads number 2048 sM
    Set the maximum number of worker threads
    MaxThreadsPerChild number 64 sM
    Maximum number of threads per child process
    MCacheMaxObjectCount value 1009 sE
    The maximum number of objects allowed to be placed in the +cache
    MCacheMaxObjectSize bytes 10000 sE
    The maximum size (in bytes) of a document allowed in the +cache
    MCacheMaxStreamingBuffer size_in_bytes the smaller of 1000 +sE
    Maximum amount of a streamed response to buffer in memory +before declaring the response uncacheable
    MCacheMinObjectSize bytes 0 sE
    The minimum size (in bytes) of a document to be allowed in the +cache
    MCacheRemovalAlgorithm LRU|GDSF GDSF sE
    The algorithm used to select documents for removal from the +cache
    MCacheSize KBytes 100 sE
    The maximum amount of memory used by the cache in +KBytes
    MetaDir directory .web svdhE
    Name of the directory to find CERN-style meta information +files
    MetaFiles on|off off svdhE
    Activates CERN meta-file processing
    MetaSuffix suffix .meta svdhE
    File name suffix for the file containg CERN-style +meta information
    MimeMagicFile file-pathsvE
    Enable MIME-type determination based on file contents +using the specified magic file
    MinSpareServers Anzahl 5 sM
    Minimale Anzahl der unbeschäftigten Kindprozesse des + Servers
    MinSpareThreads AnzahlsM
    Minimale Anzahl unbeschäftigter Threads, die zur + Bedienung von Anfragespitzen zur Verfügung stehen
    MMapFile file-path [file-path] ...sX
    Map a list of files into memory at startup time
    ModMimeUsePathInfo On|Off Off dB
    Tells mod_mime to treat path_info +components as part of the filename
    MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] NegotiatedOnly svdhB
    The types of files that will be included when searching for +a matching file with MultiViews
    NameVirtualHost Adresse[:Port]sC
    Bestimmt eine IP-Adresse für den Betrieb namensbasierter +virtueller Hosts
    NoProxy host [host] ...svE
    Hosts, domains, or networks that will be connected to +directly
    NumServers number 2 sM
    Total number of children alive at the same time
    NWSSLTrustedCerts filename [filename] ...sB
    List of additional client certificates
    NWSSLUpgradeable [IP-address:]portnumbersB
    Allows a connection to be upgraded to an SSL connection upon request
    Options + [+|-]Option [[+|-]Option] ... All svdhC
    Definiert, welche Eigenschaften oder Funktionen in einem +bestimmten Verzeichnis verfügbar sind
    Order ordering Deny,Allow dhB
    Controls the default access state and the order in which +Allow and Deny are +evaluated.
    PassEnv env-variable [env-variable] +...svdhB
    Passes environment variables from the shell
    PidFile Dateiname logs/httpd.pid sM
    Datei, in welcher der Server die Prozess-ID des Daemons +ablegt
    ProtocolEcho On|OffsvX
    Turn the echo server on or off
    <Proxy wildcard-url> ...</Proxy>svE
    Container for directives applied to proxied resources
    ProxyBadHeader IsError|Ignore|StartBody IsError svE
    Determines how to handle bad header lines in a +response
    ProxyBlock *|word|host|domain +[word|host|domain] ...svE
    Words, hosts, or domains that are banned from being +proxied
    ProxyDomain DomainsvE
    Default domain name for proxied requests
    ProxyErrorOverride On|Off Off svE
    Override error pages for proxied content
    ProxyIOBufferSize bytes 8192 svE
    Determine size of internal data throughput buffer
    <ProxyMatch regex> ...</ProxyMatch>svE
    Container for directives applied to regular-expression-matched +proxied resources
    ProxyMaxForwards number 10 svE
    Maximium number of proxies that a request can be forwarded +through
    ProxyPass [path] !|url [key=value key=value ...]]svdE
    Maps remote servers into the local server URL-space
    ProxyPassReverse [path] urlsvdE
    Adjusts the URL in HTTP response headers sent from a reverse +proxied server
    ProxyPassReverseCookieDomain internal-domain public-domainsvdE
    Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server
    ProxyPassReverseCookiePath internal-path public-pathsvdE
    Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server
    ProxyPreserveHost On|Off Off svE
    Use incoming Host HTTP request header for proxy +request
    ProxyReceiveBufferSize bytes 0 svE
    Network buffer size for proxied HTTP and FTP +connections
    ProxyRemote match remote-serversvE
    Remote proxy used to handle certain requests
    ProxyRemoteMatch regex remote-serversvE
    Remote proxy used to handle requests matched by regular +expressions
    ProxyRequests On|Off Off svE
    Enables forward (standard) proxy requests
    ProxyTimeout seconds 300 svE
    Network timeout for proxied requests
    ProxyVia On|Off|Full|Block Off svE
    Information provided in the Via HTTP response +header for proxied requests
    ReadmeName filenamesvdhB
    Name of the file that will be inserted at the end +of the index listing
    Redirect [status] URL-path +URLsvdhB
    Sends an external redirect asking the client to fetch +a different URL
    RedirectMatch [status] regex +URLsvdhB
    Sends an external redirect based on a regular expression match +of the current URL
    RedirectPermanent URL-path URLsvdhB
    Sends an external permanent redirect asking the client to fetch +a different URL
    RedirectTemp URL-path URLsvdhB
    Sends an external temporary redirect asking the client to fetch +a different URL
    RemoveCharset extension [extension] +...vdhB
    Removes any character set associations for a set of file +extensions
    RemoveEncoding extension [extension] +...vdhB
    Removes any content encoding associations for a set of file +extensions
    RemoveHandler extension [extension] +...vdhB
    Removes any handler associations for a set of file +extensions
    RemoveInputFilter extension [extension] +...vdhB
    Removes any input filter associations for a set of file +extensions
    RemoveLanguage extension [extension] +...vdhB
    Removes any language associations for a set of file +extensions
    RemoveOutputFilter extension [extension] +...vdhB
    Removes any output filter associations for a set of file +extensions
    RemoveType extension [extension] +...vdhB
    Removes any content type associations for a set of file +extensions
    RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]svdhE
    Configure HTTP request headers
    Require Name [Name] ...dhC
    Wählt die authentisierten Benutzer aus, die auf eine +Ressource zugreifen können
    RewriteBase URL-pathdhE
    Sets the base URL for per-directory rewrites
    RewriteCond + TestString CondPatternsvdhE
    Defines a condition under which rewriting will take place +
    RewriteEngine on|off off svdhE
    Enables or disables runtime rewriting engine
    RewriteLock file-pathsE
    Sets the name of the lock file used for RewriteMap +synchronization
    RewriteLog file-pathsvE
    Sets the name of the file used for logging rewrite engine +processing
    RewriteLogLevel Level 0 svE
    Sets the verbosity of the log file used by the rewrite +engine
    RewriteMap MapName MapType:MapSource +svE
    Defines a mapping function for key-lookup
    RewriteOptions OptionssvdhE
    Sets some special options for the rewrite engine
    RewriteRule + Pattern SubstitutionsvdhE
    Defines rules for the rewriting engine
    RLimitCPU Sekunden|max [Sekunden|max]svdhC
    Begrenzt den CPU-Verbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden
    RLimitMEM Bytes|max [Bytes|max]svdhC
    Begrenzt den Speicherverbrauch von Prozessen, die von +Apache-Kindprozessen gestartet wurden
    RLimitNPROC Zahl|max [Zahl|max]svdhC
    Begrenzt die Anzahl der Prozesse, die von Prozessen gestartet +werden können, der ihrerseits von Apache-Kinprozessen gestartet +wurden
    Satisfy Any|All All dhC
    Zusammenspiel von rechnerbasierter Zugriffskontrolle und +Benutzerauthentisierung
    ScoreBoardFile Dateipfad logs/apache_status sM
    Ablageort der Datei, die zur Speicherung von Daten zur + Koordinierung der Kindprozesse verwendet wird
    Script Methode CGI-SkriptsvdB
    Aktiviert ein CGI-Skript für eine bestimmte + Anfragemethode.
    ScriptAlias URL-path +file-path|directory-pathsvB
    Maps a URL to a filesystem location and designates the +target as a CGI script
    ScriptAliasMatch regex +file-path|directory-pathsvB
    Maps a URL to a filesystem location using a regular expression +and designates the target as a CGI script
    ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
    Methode zur Ermittlung des Interpreters von +CGI-Skripten
    ScriptLog file-pathsvB
    Location of the CGI script error logfile
    ScriptLogBuffer bytes 1024 svB
    Maximum amount of PUT or POST requests that will be recorded +in the scriptlog
    ScriptLogLength bytes 10385760 svB
    Size limit of the CGI script logfile
    ScriptSock file-path logs/cgisock svB
    The name of the socket to use for communication with +the cgi daemon
    SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]sB
    Enables SSL encryption for the specified port
    SendBufferSize Bytes 0 sM
    Größe des TCP-Puffers
    ServerAdmin E-Mail-Adresse|URLsvC
    E-Mail-Adresse, die der Server in Fehlermeldungen einfügt, +welche an den Client gesendet werden
    ServerAlias Hostname [Hostname] ...vC
    Alternativer Name für einen Host, der verwendet wird, wenn +Anfragen einem namensbasierten virtuellen Host zugeordnet werden
    ServerLimit AnzahlsM
    Obergrenze für die konfigurierbare Anzahl von + Prozessen
    ServerName +voll-qualifizierter-Domainname[:port]svC
    Rechnername und Port, die der Server dazu verwendet, sich +selbst zu identifizieren
    ServerPath URL-PfadvC
    Veralteter URL-Pfad für einen namensbasierten +virtuellen Host, auf den von einem inkompatiblen Browser zugegriffen +wird
    ServerRoot Verzeichnis /usr/local/apache sC
    Basisverzeichnis der Serverinstallation
    ServerSignature On|Off|EMail Off svdhC
    Konfiguriert die Fußzeile von servergenerierten +Dokumenten
    ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
    Konfiguriert den HTTP-Response-Header +Server
    SetEnv env-variable valuesvdhB
    Sets environment variables
    SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +
    SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +without respect to case
    SetHandler Handlername|NonesvdhC
    Erzwingt die Verarbeitung aller passenden Dateien durch +einen Handler
    SetInputFilter Filter[;Filter...]svdhC
    Bestimmt die Filter, die Client-Anfragen und POST-Eingaben +verarbeiten
    SetOutputFilter Filter[;Filter...]svdhC
    Bestimmt die Filter, die Antworten des Servers verarbeiten
    SSIEndTag tag "-->" svB
    String that ends an include element
    SSIErrorMsg message "[an error occurred +svdhB
    Error message displayed when there is an SSI +error
    SSIStartTag tag "<!--#" svB
    String that starts an include element
    SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +svdhB
    Configures the format in which date strings are +displayed
    SSIUndefinedEcho string "(none)" svdhB
    String displayed when an unset variable is echoed
    SSLCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Client Auth
    SSLCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Client Auth
    SSLCADNRequestFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    SSLCADNRequestPath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    SSLCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Client Auth
    SSLCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Client Auth
    SSLCertificateChainFile file-pathsvE
    File of PEM-encoded Server CA Certificates
    SSLCertificateFile file-pathsvE
    Server PEM-encoded X.509 Certificate file
    SSLCertificateKeyFile file-pathsvE
    Server PEM-encoded Private Key file
    SSLCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +handshake
    SSLCryptoDevice engine builtin sE
    Enable use of a cryptographic hardware accelerator
    SSLEngine on|off|optional off svE
    SSL Engine Operation Switch
    SSLHonorCiperOrder flagsvE
    Option to prefer the server's cipher preference order
    SSLMutex type none sE
    Semaphore for internal mutual exclusion of +operations
    SSLOptions [+|-]option ...svdhE
    Configure various SSL engine run-time options
    SSLPassPhraseDialog type builtin sE
    Type of pass phrase dialog for encrypted private +keys
    SSLProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors
    SSLProxyCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    SSLProxyCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Remote Server Auth
    SSLProxyCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +proxy handshake
    SSLProxyEngine on|off off svE
    SSL Proxy Engine Operation Switch
    SSLProxyMachineCertificateFile filenamesE
    File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyMachineCertificatePath directorysE
    Directory of PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors for proxy usage
    SSLProxyVerify level none svdhE
    Type of remote server Certificate verification
    SSLProxyVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Remote Server +Certificate verification
    SSLRandomSeed context source +[bytes]sE
    Pseudo Random Number Generator (PRNG) seeding +source
    SSLRequire expressiondhE
    Allow access only when an arbitrarily complex +boolean expression is true
    SSLRequireSSLdhE
    Deny access when SSL is not used for the +HTTP request
    SSLSessionCache type none sE
    Type of the global/inter-process SSL Session +Cache
    SSLSessionCacheTimeout seconds 300 svE
    Number of seconds before an SSL session expires +in the Session Cache
    SSLUserName varnamesdhE
    Variable name to determine user name
    SSLVerifyClient level none svdhE
    Type of Client Certificate verification
    SSLVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Client +Certificate verification
    StartServers AnzahlsM
    Anzahl der Kindprozesse des Servers, die beim Start erstellt + werden
    StartThreads AnzahlsM
    Anzahl der Threads, die beim Start erstellt werden
    SuexecUserGroup User GroupsvE
    User and group permissions for CGI programs
    ThreadLimit AnzahlsM
    Bestimmt die Obergrenze der konfigurierbaren Anzahl von Threads + pro Kindprozess
    ThreadsPerChild AnzahlsM
    Anzahl der Threads, die mit jedem Kindprozess gestartet + werden
    ThreadStackSize sizesM
    Die Größe des Stacks in Bytes, der von Threads +verwendet wird, die Client-Verbindungen bearbeiten.
    TimeOut Sekunden 300 sC
    Zeitspanne, die der Server auf verschiedene Ereignisse wartet, +bevor er die Anfrage abbricht
    TransferLog file|pipesvB
    Specify location of a log file
    TypesConfig file-path conf/mime.types sB
    The location of the mime.types file
    UnsetEnv env-variable [env-variable] +...svdhB
    Removes variables from the environment
    UseCanonicalName On|Off|DNS Off svdC
    Bestimmt, wie der Server seinen eigenen Namen und Port +ermittelt
    User Unix-User-ID #-1 sM
    Die Benutzerkennung, unter welcher der Server Anfragen + beantwortet
    UserDir directory-filenamesvB
    Location of the user-specific directories
    VirtualDocumentRoot interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    VirtualDocumentRootIP interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    <VirtualHost + Adresse[:Port] [Adresse[:Port]] + ...> ... </VirtualHost>sC
    Enthält Direktiven, die nur auf bestimmte Hostnamen oder +IP-Adressen angewendet werden
    VirtualScriptAlias interpolated-directory|none none svE
    Dynamically configure the location of the CGI directory for +a given virtual host
    VirtualScriptAliasIP interpolated-directory|none none svE
    Dynamically configure the location of the cgi directory for +a given virtual host
    Win32DisableAcceptExsM
    Für die Annahme von Netzwerkverbindungen wird accept() anstelle von AcceptEx() verwendet
    XBitHack on|off|full off svdhB
    Parse SSI directives in files with the execute bit +set
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/quickreference.html.en b/trunk/docs/manual/mod/quickreference.html.en new file mode 100644 index 0000000000..b24c97aac1 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html.en @@ -0,0 +1,746 @@ + + + +Directive Quick Reference - Apache HTTP Server + + + + + + +
    <-
    + +

    Directive Quick Reference

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    The directive quick reference shows the usage, default, status, + and context of each Apache configuration directive. For more + information about each of these, see the Directive Dictionary.

    + +

    The first column gives the directive name and usage. The second + columns shows the default value of the directive, if a default exists. + If the default is too large to display, the first characters will be + followed by "+".

    + +

    The third and fourth columns list the contexts where the directive + is allowed and the status of the directive according to the legend + tables below.

    +
    +
    + + + +
     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X  + + + + + +
    sserver config
    vvirtual host
    ddirectory
    h.htaccess
    + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AcceptMutex Default|method Default sM
    Method that Apache uses to serialize multiple children +accepting requests on network sockets
    AcceptPathInfo On|Off|Default Default svdhC
    Resources accept trailing pathname information
    AccessFileName filename [filename] ... .htaccess svC
    Name of the distributed configuration file
    Action action-type cgi-script [virtual]svdhB
    Activates a CGI script for a particular handler or +content-type
    AddAlt string file [file] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by filename
    AddAltByEncoding string MIME-encoding +[MIME-encoding] ...svdhB
    Alternate text to display for a file instead of an icon +selected by MIME-encoding
    AddAltByType string MIME-type +[MIME-type] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by MIME content-type
    AddCharset charset extension +[extension] ...svdhB
    Maps the given filename extensions to the specified content +charset
    AddDefaultCharset On|Off|charset Off svdhC
    Default charset parameter to be added when a response +content-type is text/plain or text/html
    AddDescription string file [file] ...svdhB
    Description to display for a file
    AddEncoding MIME-enc extension +[extension] ...svdhB
    Maps the given filename extensions to the specified encoding +type
    AddHandler handler-name extension +[extension] ...svdhB
    Maps the filename extensions to the specified +handler
    AddIcon icon name [name] +...svdhB
    Icon to display for a file selected by name
    AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...svdhB
    Icon to display next to files selected by MIME +content-encoding
    AddIconByType icon MIME-type +[MIME-type] ...svdhB
    Icon to display next to files selected by MIME +content-type
    AddInputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +client requests
    AddLanguage MIME-lang extension +[extension] ...svdhB
    Maps the given filename extension to the specified content +language
    AddModuleInfo module-name stringsvE
    Adds additional information to the module +information displayed by the server-info handler
    AddOutputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +responses from the server
    AddOutputFilterByType filter[;filter...] +MIME-type [MIME-type] ...svdhC
    assigns an output filter to a particular MIME-type
    AddType MIME-type extension +[extension] ...svdhB
    Maps the given filename extensions onto the specified content +type
    Alias URL-path +file-path|directory-pathsvB
    Maps URLs to filesystem locations
    AliasMatch regex +file-path|directory-pathsvB
    Maps URLs to filesystem locations using regular +expressions
    Allow from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts can access an area of the +server
    AllowCONNECT port [port] ... 443 563 svE
    Ports that are allowed to CONNECT through the +proxy
    AllowEncodedSlashes On|Off Off svC
    Determines whether encoded path separators in URLs are allowed to +be passed through
    AllowOverride All|None|directive-type +[directive-type] ... All dC
    Types of directives that are allowed in +.htaccess files
    Anonymous user [user] ...dhE
    Specifies userIDs that are allowed access without +password verification
    Anonymous_LogEmail On|Off On dhE
    Sets whether the password entered will be logged in the +error log
    Anonymous_MustGiveEmail On|Off On dhE
    Specifies whether blank passwords are allowed
    Anonymous_NoUserID On|Off Off dhE
    Sets whether the userID field may be empty
    Anonymous_VerifyEmail On|Off Off dhE
    Sets whether to check the password field for a correctly +formatted email address
    AssignUserID user-id group-idvM
    Tie a virtual host to a user and group ID
    AuthBasicAuthoritative On|Off On dhB
    Sets whether authorization and authentication are passed to +lower level modules
    AuthBasicProvider On|Off|provider-name +[provider-name] ... On dhB
    Sets the authentication provider(s) for this location
    AuthDBMGroupFile file-pathdhE
    Sets the name of the database file containing the list +of user groups for authorization
    AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store passwords
    AuthDBMUserFile file-pathdhE
    Sets the name of a database file containing the list of users and +passwords for authentication
    AuthDefaultAuthoritative On|Off On dhB
    Sets whether authentication is passed to lower level +modules
    AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
    Selects the algorithm used to calculate the challenge and +response hashes in digest authentication
    AuthDigestDomain URI [URI] ...dhX
    URIs that are in the same protection space for digest +authentication
    AuthDigestNcCheck On|Off Off sX
    Enables or disables checking of the nonce-count sent by the +server
    AuthDigestNonceFormat formatdhX
    Determines how the nonce is generated
    AuthDigestNonceLifetime seconds 300 dhX
    How long the server nonce is valid
    AuthDigestProvider On|Off|provider-name +[provider-name] ... On dhX
    Sets the authentication provider(s) for this location
    AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhX
    Determines the quality-of-protection to use in digest +authentication
    AuthDigestShmemSize size 1000 sX
    The amount of shared memory to allocate for keeping track +of clients
    AuthGroupFile file-pathdhB
    Sets the name of a text file containing the list +of user groups for authorization
    AuthLDAPBindDN distinguished-namedhE
    Optional DN to use in binding to the LDAP server
    AuthLDAPBindPassword passworddhE
    Password used in conjuction with the bind DN
    AuthLDAPCharsetConfig file-pathsE
    Language to charset conversion configuration file
    AuthLDAPCompareDNOnServer on|off on dhE
    Use the LDAP server to compare the DNs
    AuthLDAPDereferenceAliases never|searching|finding|always Always dhE
    When will the module de-reference aliases
    AuthLDAPGroupAttribute attributedhE
    LDAP attributes used to check for group membership
    AuthLDAPGroupAttributeIsDN on|off on dhE
    Use the DN of the client username when checking for +group membership
    AuthLDAPRemoteUserIsDN on|off off dhE
    Use the DN of the client username to set the REMOTE_USER +environment variable
    AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]dhE
    URL specifying the LDAP search parameters
    AuthName auth-domaindhC
    Authorization realm for use in HTTP +authentication
    <AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>svE
    Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    AuthType Basic|DigestdhC
    Type of user authentication
    AuthUserFile file-pathdhB
    Sets the name of a text file containing the list of users and +passwords for authentication
    AuthzDBMAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store list of user groups
    AuthzDefaultAuthoritative On|Off On dhB
    Sets whether authorization is passed to lower level +modules
    AuthzGroupFileAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    AuthzLDAPAuthoritative on|off on dhE
    Prevent other authentication modules from +authenticating the user if this one fails
    AuthzOwnerAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzUserAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on HTTP User-Agent +
    BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on User-Agent without +respect to case
    BufferedLogs On|Off Off sB
    Buffer log entries in memory before writing to disk
    CacheDefaultExpire seconds 3600 (one hour) svE
    The default duration to cache a document when no expiry date is specified.
    CacheDirLength length 2 svE
    The number of characters in subdirectory names
    CacheDirLevels levels 3 svE
    The number of levels of subdirectories in the +cache.
    CacheDisable url-stringsvE
    Disable caching of specified URLs
    CacheEnable cache_type url-stringsvE
    Enable caching of specified URLs using a specified storage +manager
    CacheFile file-path [file-path] ...sX
    Cache a list of file handles at startup time
    CacheIgnoreCacheControl On|Off Off svE
    Ignore request to not serve cached content to client
    CacheIgnoreHeaders header-string [header-string] ... None svE
    Do not store the given HTTP header(s) in the cache. +
    CacheIgnoreNoLastMod On|Off Off svE
    Ignore the fact that a response has no Last Modified +header.
    CacheLastModifiedFactor float 0.1 svE
    The factor used to compute an expiry date based on the +LastModified date.
    CacheMaxExpire seconds 86400 (one day) svE
    The maximum time in seconds to cache a document
    CacheMaxFileSize bytes 1000000 svE
    The maximum size (in bytes) of a document to be placed in the +cache
    CacheMinFileSize bytes 1 svE
    The minimum size (in bytes) of a document to be placed in the +cache
    CacheNegotiatedDocs On|Off Off svB
    Allows content-negotiated documents to be +cached by proxy servers
    CacheRoot directorysvE
    The directory root under which cache files are +stored
    CacheStoreNoStore On|Off Off svE
    Attempt to cache requests or responses that have been marked as no-store.
    CacheStorePrivate On|Off Off svE
    Attempt to cache responses that the server has marked as private
    CGIMapExtension cgi-path .extensiondhC
    Technique for locating the interpreter for CGI +scripts
    CharsetDefault charsetsvdhX
    Charset to translate into
    CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
    Configures charset translation behavior
    CharsetSourceEnc charsetsvdhX
    Source charset of files
    CheckSpelling on|off Off svdhE
    Enables the spelling +module
    ChildPerUserID user-id group-id +num-childrensM
    Specify user ID and group ID for a number of child +processes
    ContentDigest On|Off Off svdhC
    Enables the generation of Content-MD5 HTTP Response +headers
    CookieDomain domainsvdhE
    The domain to which the tracking cookie applies
    CookieExpires expiry-periodsvdhE
    Expiry time for the tracking cookie
    CookieLog filenamesvB
    Sets filename for the logging of cookies
    CookieName token Apache svdhE
    Name of the tracking cookie
    CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
    Format of the cookie header field
    CookieTracking on|off off svdhE
    Enables tracking cookie
    CoreDumpDirectory directorysM
    Directory where Apache attempts to +switch before dumping core
    CustomLog file|pipe +format|nickname +[env=[!]environment-variable]svB
    Sets filename and format of log file
    Dav On|Off|provider-name Off dE
    Enable WebDAV HTTP methods
    DavDepthInfinity on|off off svdE
    Allow PROPFIND, Depth: Infinity requests
    DavGenericLockDB file-pathsvdE
    Location of the DAV lock database
    DavLockDB file-pathsvE
    Location of the DAV lock database
    DavMinTimeout seconds 0 svdE
    Minimum amount of time the server holds a lock on +a DAV resource
    DBDExptime time-in-secondssvX
    Keepalive time for idle connections
    DBDKeep numbersvX
    Maximum sustainednumber of connections
    DBDMax numbersvX
    Maximum number of connections
    DBDMin numbersvX
    Minimum number of connections
    DBDParams +param1=value1[,param2=value2]svX
    Parameters for database connection
    DBDPersist 0|1svX
    Whether to use persistent connections
    DBDPrepareSQL "SQL statement" labelsvX
    Define an SQL prepared statement
    DBDriver namesvX
    Specify an SQL driver
    DefaultIcon url-pathsvdhB
    Icon to display for files when no specific icon is +configured
    DefaultLanguage MIME-langsvdhB
    Sets all files in the given scope to the specified +language
    DefaultType MIME-type text/plain svdhC
    MIME content-type that will be sent if the +server cannot determine a type in any other way
    DeflateBufferSize value 8096 svE
    Fragment size to be compressed at one time by zlib
    DeflateCompressionLevel valuesvE
    How much compression do we apply to the output
    DeflateFilterNote [type] notenamesvE
    Places the compression ratio in a note for logging
    DeflateMemLevel value 9 svE
    How much memory should be used by zlib for compression
    DeflateWindowSize value 15 svE
    Zlib compression window size
    Deny from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts are denied access to the +server
    <Directory directory-path> +... </Directory>svC
    Enclose a group of directives that apply only to the +named file-system directory and sub-directories
    DirectoryIndex + local-url [local-url] ... index.html svdhB
    List of resources to look for when the client requests +a directory
    <DirectoryMatch regex> +... </DirectoryMatch>svC
    Enclose directives that apply to +file-system directories matching a regular expression and their +subdirectories
    DirectorySlash On|Off On svdhB
    Toggle trailing slash redirects on or off
    DocumentRoot directory-path /usr/local/apache/h +svC
    Directory that forms the main document tree visible +from the web
    DumpIOInput On|Off Off sE
    Dump all input data to the error log
    DumpIOOutput On|Off Off sE
    Dump all output data to the error log
    EnableExceptionHook On|Off Off sM
    Enables a hook that runs exception handlers +after a crash
    EnableMMAP On|Off On svdhC
    Use memory-mapping to read files during delivery
    EnableSendfile On|Off On svdhC
    Use the kernel sendfile support to deliver files to the client
    ErrorDocument error-code documentsvdhC
    What the server will return to the client +in case of an error
    ErrorLog file-path|syslog[:facility] logs/error_log (Uni +svC
    Location where the server will log errors
    ExamplesvdhX
    Demonstration directive to illustrate the Apache module +API
    ExpiresActive On|OffsvdhE
    Enables generation of Expires +headers
    ExpiresByType MIME-type +<code>secondssvdhE
    Value of the Expires header configured +by MIME type
    ExpiresDefault <code>secondssvdhE
    Default algorithm for calculating expiration time
    ExtendedStatus On|Off Off sB
    Keep track of extended status information for each +request
    ExtFilterDefine filtername parameterssE
    Define an external filter
    ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
    Configure mod_ext_filter options
    FileETag component ... INode MTime Size svdhC
    File attributes used to create the ETag +HTTP response header
    <Files filename> ... </Files>svdhC
    Contains directives that apply to matched +filenames
    <FilesMatch regex> ... </FilesMatch>svdhC
    Contains directives that apply to regular-expression matched +filenames
    FilterChain [+=-@!]filter-name ...svdhX
    Configure the filter chain
    FilterDeclare filter-name [type]svdhX
    Declare a smart filter
    FilterProtocol filter-name [provider-name] + proto-flagssvdhX
    Deal with correct HTTP protocol handling
    FilterProvider filter-name provider-name + [req|resp|env]=dispatch matchsvdhX
    Register a content filter
    FilterTrace filter-name levelsvdX
    Get debug/diagnostic information from + mod_filter
    ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
    Action to take if a single acceptable document is not +found
    ForceType MIME-type|NonedhC
    Forces all matching files to be served with the specified +MIME content-type
    ForensicLog filename|pipesvE
    Sets filename of the forensic log
    Group unix-group #-1 sM
    Group under which the server will answer +requests
    Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]svdhE
    Configure HTTP response headers
    HeaderName filenamesvdhB
    Name of the file that will be inserted at the top +of the index listing
    HostnameLookups On|Off|Double Off svdC
    Enables DNS lookups on client IP addresses
    IdentityCheck On|Off Off svdE
    Enables logging of the RFC 1413 identity of the remote +user
    IdentityCheckTimeout seconds 30 svdE
    Determines the timeout duration for ident requests
    <IfDefine [!]parameter-name> ... + </IfDefine>svdhC
    Encloses directives that will be processed only +if a test is true at startup
    <IfModule [!]module-file|module-identifier> ... + </IfModule>svdhC
    Encloses directives that are processed conditional on the +presence or absence of a specific module
    <IfVersion [[!]operator] version> ... +</IfVersion>svdhE
    contains version dependent configuration
    ImapBase map|referer|URL http://servername/ svdhB
    Default base for imagemap files
    ImapDefault error|nocontent|map|referer|URL nocontent svdhB
    Default action when an imagemap is called with coordinates +that are not explicitly mapped
    ImapMenu none|formatted|semiformatted|unformattedsvdhB
    Action if no coordinates are given when calling +an imagemap
    Include file-path|directory-pathsvdC
    Includes other configuration files from within +the server configuration files
    IndexIgnore file [file] ...svdhB
    Adds to the list of files to hide when listing +a directory
    IndexOptions [+|-]option [[+|-]option] +...svdhB
    Various configuration settings for directory +indexing
    IndexOrderDefault Ascending|Descending +Name|Date|Size|Description Ascending Name svdhB
    Sets the default ordering of the directory index
    IndexStyleSheet url-pathsvdhB
    Adds a CSS stylesheet to the directory index
    ISAPIAppendLogToErrors on|off off svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log
    ISAPIAppendLogToQuery on|off on svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field
    ISAPICacheFile file-path [file-path] +...svB
    ISAPI .dll files to be loaded at startup
    ISAPIFakeAsync on|off off svdhB
    Fake asynchronous support for ISAPI callbacks
    ISAPILogNotSupported on|off off svdhB
    Log unsupported feature requests from ISAPI +extensions
    ISAPIReadAheadBuffer size 49152 svdhB
    Size of the Read Ahead Buffer sent to ISAPI +extensions
    KeepAlive On|Off On svC
    Enables HTTP persistent connections
    KeepAliveTimeout seconds 5 svC
    Amount of time the server will wait for subsequent +requests on a persistent connection
    LanguagePriority MIME-lang [MIME-lang] +...svdhB
    The precendence of language variants for cases where +the client does not express a preference
    LDAPCacheEntries number 1024 sE
    Maximum number of entries in the primary LDAP cache
    LDAPCacheTTL seconds 600 sE
    Time that cached items remain valid
    LDAPConnectionTimeout secondssE
    Specifies the socket connection timeout in seconds
    LDAPOpCacheEntries number 1024 sE
    Number of entries used to cache LDAP compare +operations
    LDAPOpCacheTTL seconds 600 sE
    Time that entries in the operation cache remain +valid
    LDAPSharedCacheFile directory-path/filenamesE
    Sets the shared memory cache file
    LDAPSharedCacheSize bytes 102400 sE
    Size in bytes of the shared-memory cache
    LDAPTrustedClientCert type directory-path/filename/nickname [password]svdhE
    Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    LDAPTrustedGlobalCert type directory-path/filename [password]sE
    Sets the file or database containing global trusted +Certificate Authority or global client certificates
    LDAPTrustedMode typesvdhE
    Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    LDAPVerifyServerCert On|Off On sE
    Force server certificate verification
    <Limit method [method] ... > ... + </Limit>svdhC
    Restrict enclosed access controls to only certain HTTP +methods
    <LimitExcept method [method] ... > ... + </LimitExcept>svdhC
    Restrict access controls to all HTTP methods +except the named ones
    LimitInternalRecursion number [number] 10 svC
    Determine maximum number of internal redirects and nested +subrequests
    LimitRequestBody bytes 0 svdhC
    Restricts the total size of the HTTP request body sent +from the client
    LimitRequestFields number 100 sC
    Limits the number of HTTP request header fields that +will be accepted from the client
    LimitRequestFieldsize bytessC
    Limits the size of the HTTP request header allowed from the +client
    LimitRequestLine bytes 8190 sC
    Limit the size of the HTTP request line that will be accepted +from the client
    LimitXMLRequestBody bytes 1000000 svdhC
    Limits the size of an XML-based request body
    Listen [IP-address:]portnumbersM
    IP addresses and ports that the server +listens to
    ListenBacklog backlogsM
    Maximum length of the queue of pending connections
    LoadFile filename [filename] ...sE
    Link in the named object file or library
    LoadModule module filenamesE
    Links in the object file or library, and adds to the list +of active modules
    <Location + URL-path|URL> ... </Location>svC
    Applies the enclosed directives only to matching +URLs
    <LocationMatch + regex> ... </LocationMatch>svC
    Applies the enclosed directives only to regular-expression +matching URLs
    LockFile filename logs/accept.lock sM
    Location of the accept serialization lock file
    LogFormat format|nickname +[nickname] "%h %l %u %t \"%r\" +svB
    Describes a format for use in a log file
    LogLevel level warn svC
    Controls the verbosity of the ErrorLog
    MaxClients numbersM
    Maximum number of child processes that will be created +to serve requests
    MaxKeepAliveRequests number 100 svC
    Number of requests allowed on a persistent +connection
    MaxMemFree KBytes 0 sM
    Maximum amount of memory that the main allocator is allowed +to hold without calling free()
    MaxRequestsPerChild number 10000 sM
    Limit on the number of requests that an individual child server +will handle during its life
    MaxRequestsPerThread number 0 sM
    Limit on the number of requests that an individual thread +will handle during its life
    MaxSpareServers number 10 sM
    Maximum number of idle child server processes
    MaxSpareThreads numbersM
    Maximum number of idle threads
    MaxThreads number 2048 sM
    Set the maximum number of worker threads
    MaxThreadsPerChild number 64 sM
    Maximum number of threads per child process
    MCacheMaxObjectCount value 1009 sE
    The maximum number of objects allowed to be placed in the +cache
    MCacheMaxObjectSize bytes 10000 sE
    The maximum size (in bytes) of a document allowed in the +cache
    MCacheMaxStreamingBuffer size_in_bytes the smaller of 1000 +sE
    Maximum amount of a streamed response to buffer in memory +before declaring the response uncacheable
    MCacheMinObjectSize bytes 0 sE
    The minimum size (in bytes) of a document to be allowed in the +cache
    MCacheRemovalAlgorithm LRU|GDSF GDSF sE
    The algorithm used to select documents for removal from the +cache
    MCacheSize KBytes 100 sE
    The maximum amount of memory used by the cache in +KBytes
    MetaDir directory .web svdhE
    Name of the directory to find CERN-style meta information +files
    MetaFiles on|off off svdhE
    Activates CERN meta-file processing
    MetaSuffix suffix .meta svdhE
    File name suffix for the file containg CERN-style +meta information
    MimeMagicFile file-pathsvE
    Enable MIME-type determination based on file contents +using the specified magic file
    MinSpareServers number 5 sM
    Minimum number of idle child server processes
    MinSpareThreads numbersM
    Minimum number of idle threads available to handle request +spikes
    MMapFile file-path [file-path] ...sX
    Map a list of files into memory at startup time
    ModMimeUsePathInfo On|Off Off dB
    Tells mod_mime to treat path_info +components as part of the filename
    MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] NegotiatedOnly svdhB
    The types of files that will be included when searching for +a matching file with MultiViews
    NameVirtualHost addr[:port]sC
    Designates an IP address for name-virtual +hosting
    NoProxy host [host] ...svE
    Hosts, domains, or networks that will be connected to +directly
    NumServers number 2 sM
    Total number of children alive at the same time
    NWSSLTrustedCerts filename [filename] ...sB
    List of additional client certificates
    NWSSLUpgradeable [IP-address:]portnumbersB
    Allows a connection to be upgraded to an SSL connection upon request
    Options + [+|-]option [[+|-]option] ... All svdhC
    Configures what features are available in a particular +directory
    Order ordering Deny,Allow dhB
    Controls the default access state and the order in which +Allow and Deny are +evaluated.
    PassEnv env-variable [env-variable] +...svdhB
    Passes environment variables from the shell
    PidFile filename logs/httpd.pid sM
    File where the server records the process ID +of the daemon
    ProtocolEcho On|OffsvX
    Turn the echo server on or off
    <Proxy wildcard-url> ...</Proxy>svE
    Container for directives applied to proxied resources
    ProxyBadHeader IsError|Ignore|StartBody IsError svE
    Determines how to handle bad header lines in a +response
    ProxyBlock *|word|host|domain +[word|host|domain] ...svE
    Words, hosts, or domains that are banned from being +proxied
    ProxyDomain DomainsvE
    Default domain name for proxied requests
    ProxyErrorOverride On|Off Off svE
    Override error pages for proxied content
    ProxyIOBufferSize bytes 8192 svE
    Determine size of internal data throughput buffer
    <ProxyMatch regex> ...</ProxyMatch>svE
    Container for directives applied to regular-expression-matched +proxied resources
    ProxyMaxForwards number 10 svE
    Maximium number of proxies that a request can be forwarded +through
    ProxyPass [path] !|url [key=value key=value ...]]svdE
    Maps remote servers into the local server URL-space
    ProxyPassReverse [path] urlsvdE
    Adjusts the URL in HTTP response headers sent from a reverse +proxied server
    ProxyPassReverseCookieDomain internal-domain public-domainsvdE
    Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server
    ProxyPassReverseCookiePath internal-path public-pathsvdE
    Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server
    ProxyPreserveHost On|Off Off svE
    Use incoming Host HTTP request header for proxy +request
    ProxyReceiveBufferSize bytes 0 svE
    Network buffer size for proxied HTTP and FTP +connections
    ProxyRemote match remote-serversvE
    Remote proxy used to handle certain requests
    ProxyRemoteMatch regex remote-serversvE
    Remote proxy used to handle requests matched by regular +expressions
    ProxyRequests On|Off Off svE
    Enables forward (standard) proxy requests
    ProxyTimeout seconds 300 svE
    Network timeout for proxied requests
    ProxyVia On|Off|Full|Block Off svE
    Information provided in the Via HTTP response +header for proxied requests
    ReadmeName filenamesvdhB
    Name of the file that will be inserted at the end +of the index listing
    Redirect [status] URL-path +URLsvdhB
    Sends an external redirect asking the client to fetch +a different URL
    RedirectMatch [status] regex +URLsvdhB
    Sends an external redirect based on a regular expression match +of the current URL
    RedirectPermanent URL-path URLsvdhB
    Sends an external permanent redirect asking the client to fetch +a different URL
    RedirectTemp URL-path URLsvdhB
    Sends an external temporary redirect asking the client to fetch +a different URL
    RemoveCharset extension [extension] +...vdhB
    Removes any character set associations for a set of file +extensions
    RemoveEncoding extension [extension] +...vdhB
    Removes any content encoding associations for a set of file +extensions
    RemoveHandler extension [extension] +...vdhB
    Removes any handler associations for a set of file +extensions
    RemoveInputFilter extension [extension] +...vdhB
    Removes any input filter associations for a set of file +extensions
    RemoveLanguage extension [extension] +...vdhB
    Removes any language associations for a set of file +extensions
    RemoveOutputFilter extension [extension] +...vdhB
    Removes any output filter associations for a set of file +extensions
    RemoveType extension [extension] +...vdhB
    Removes any content type associations for a set of file +extensions
    RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]svdhE
    Configure HTTP request headers
    Require entity-name [entity-name] ...dhC
    Selects which authenticated users can access +a resource
    RewriteBase URL-pathdhE
    Sets the base URL for per-directory rewrites
    RewriteCond + TestString CondPatternsvdhE
    Defines a condition under which rewriting will take place +
    RewriteEngine on|off off svdhE
    Enables or disables runtime rewriting engine
    RewriteLock file-pathsE
    Sets the name of the lock file used for RewriteMap +synchronization
    RewriteLog file-pathsvE
    Sets the name of the file used for logging rewrite engine +processing
    RewriteLogLevel Level 0 svE
    Sets the verbosity of the log file used by the rewrite +engine
    RewriteMap MapName MapType:MapSource +svE
    Defines a mapping function for key-lookup
    RewriteOptions OptionssvdhE
    Sets some special options for the rewrite engine
    RewriteRule + Pattern SubstitutionsvdhE
    Defines rules for the rewriting engine
    RLimitCPU seconds|max [seconds|max]svdhC
    Limits the CPU consumption of processes launched +by Apache children
    RLimitMEM bytes|max [bytes|max]svdhC
    Limits the memory consumption of processes launched +by Apache children
    RLimitNPROC number|max [number|max]svdhC
    Limits the number of processes that can be launched by +processes launched by Apache children
    Satisfy Any|All All dhC
    Interaction between host-level access control and +user authentication
    ScoreBoardFile file-path logs/apache_status sM
    Location of the file used to store coordination data for +the child processes
    Script method cgi-scriptsvdB
    Activates a CGI script for a particular request +method.
    ScriptAlias URL-path +file-path|directory-pathsvB
    Maps a URL to a filesystem location and designates the +target as a CGI script
    ScriptAliasMatch regex +file-path|directory-pathsvB
    Maps a URL to a filesystem location using a regular expression +and designates the target as a CGI script
    ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
    Technique for locating the interpreter for CGI +scripts
    ScriptLog file-pathsvB
    Location of the CGI script error logfile
    ScriptLogBuffer bytes 1024 svB
    Maximum amount of PUT or POST requests that will be recorded +in the scriptlog
    ScriptLogLength bytes 10385760 svB
    Size limit of the CGI script logfile
    ScriptSock file-path logs/cgisock svB
    The name of the socket to use for communication with +the cgi daemon
    SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]sB
    Enables SSL encryption for the specified port
    SendBufferSize bytes 0 sM
    TCP buffer size
    ServerAdmin email-address|URLsvC
    Email address that the server includes in error +messages sent to the client
    ServerAlias hostname [hostname] ...vC
    Alternate names for a host used when matching requests +to name-virtual hosts
    ServerLimit numbersM
    Upper limit on configurable number of processes
    ServerName fully-qualified-domain-name[:port]svC
    Hostname and port that the server uses to identify +itself
    ServerPath URL-pathvC
    Legacy URL pathname for a name-based virtual host that +is accessed by an incompatible browser
    ServerRoot directory-path /usr/local/apache sC
    Base directory for the server installation
    ServerSignature On|Off|EMail Off svdhC
    Configures the footer on server-generated documents
    ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
    Configures the Server HTTP response +header
    SetEnv env-variable valuesvdhB
    Sets environment variables
    SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +
    SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +without respect to case
    SetHandler handler-name|NonesvdhC
    Forces all matching files to be processed by a +handler
    SetInputFilter filter[;filter...]svdhC
    Sets the filters that will process client requests and POST +input
    SetOutputFilter filter[;filter...]svdhC
    Sets the filters that will process responses from the +server
    SSIEndTag tag "-->" svB
    String that ends an include element
    SSIErrorMsg message "[an error occurred +svdhB
    Error message displayed when there is an SSI +error
    SSIStartTag tag "<!--#" svB
    String that starts an include element
    SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +svdhB
    Configures the format in which date strings are +displayed
    SSIUndefinedEcho string "(none)" svdhB
    String displayed when an unset variable is echoed
    SSLCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Client Auth
    SSLCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Client Auth
    SSLCADNRequestFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    SSLCADNRequestPath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    SSLCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Client Auth
    SSLCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Client Auth
    SSLCertificateChainFile file-pathsvE
    File of PEM-encoded Server CA Certificates
    SSLCertificateFile file-pathsvE
    Server PEM-encoded X.509 Certificate file
    SSLCertificateKeyFile file-pathsvE
    Server PEM-encoded Private Key file
    SSLCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +handshake
    SSLCryptoDevice engine builtin sE
    Enable use of a cryptographic hardware accelerator
    SSLEngine on|off|optional off svE
    SSL Engine Operation Switch
    SSLHonorCiperOrder flagsvE
    Option to prefer the server's cipher preference order
    SSLMutex type none sE
    Semaphore for internal mutual exclusion of +operations
    SSLOptions [+|-]option ...svdhE
    Configure various SSL engine run-time options
    SSLPassPhraseDialog type builtin sE
    Type of pass phrase dialog for encrypted private +keys
    SSLProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors
    SSLProxyCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    SSLProxyCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Remote Server Auth
    SSLProxyCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +proxy handshake
    SSLProxyEngine on|off off svE
    SSL Proxy Engine Operation Switch
    SSLProxyMachineCertificateFile filenamesE
    File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyMachineCertificatePath directorysE
    Directory of PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors for proxy usage
    SSLProxyVerify level none svdhE
    Type of remote server Certificate verification
    SSLProxyVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Remote Server +Certificate verification
    SSLRandomSeed context source +[bytes]sE
    Pseudo Random Number Generator (PRNG) seeding +source
    SSLRequire expressiondhE
    Allow access only when an arbitrarily complex +boolean expression is true
    SSLRequireSSLdhE
    Deny access when SSL is not used for the +HTTP request
    SSLSessionCache type none sE
    Type of the global/inter-process SSL Session +Cache
    SSLSessionCacheTimeout seconds 300 svE
    Number of seconds before an SSL session expires +in the Session Cache
    SSLUserName varnamesdhE
    Variable name to determine user name
    SSLVerifyClient level none svdhE
    Type of Client Certificate verification
    SSLVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Client +Certificate verification
    StartServers numbersM
    Number of child server processes created at startup
    StartThreads numbersM
    Number of threads created on startup
    SuexecUserGroup User GroupsvE
    User and group permissions for CGI programs
    ThreadLimit numbersM
    Sets the upper limit on the configurable number of threads +per child process
    ThreadsPerChild numbersM
    Number of threads created by each child process
    ThreadStackSize sizesM
    The size in bytes of the stack used by threads handling +client connections
    TimeOut seconds 300 sC
    Amount of time the server will wait for +certain events before failing a request
    TransferLog file|pipesvB
    Specify location of a log file
    TypesConfig file-path conf/mime.types sB
    The location of the mime.types file
    UnsetEnv env-variable [env-variable] +...svdhB
    Removes variables from the environment
    UseCanonicalName On|Off|DNS Off svdC
    Configures how the server determines its own name and +port
    User unix-userid #-1 sM
    The userid under which the server will answer +requests
    UserDir directory-filenamesvB
    Location of the user-specific directories
    VirtualDocumentRoot interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    VirtualDocumentRootIP interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    <VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>sC
    Contains directives that apply only to a specific +hostname or IP address
    VirtualScriptAlias interpolated-directory|none none svE
    Dynamically configure the location of the CGI directory for +a given virtual host
    VirtualScriptAliasIP interpolated-directory|none none svE
    Dynamically configure the location of the cgi directory for +a given virtual host
    Win32DisableAcceptExsM
    Use accept() rather than AcceptEx() to accept network connections
    XBitHack on|off|full off svdhB
    Parse SSI directives in files with the execute bit +set
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/quickreference.html.es b/trunk/docs/manual/mod/quickreference.html.es new file mode 100644 index 0000000000..4a25c24607 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html.es @@ -0,0 +1,749 @@ + + + +Guía Rápida de Referencia de Directivas - Servidor HTTP Apache + + + + + + +
    <-
    + +

    Guía Rápida de Referencia de Directivas

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    La Guía Rápida de Referencia de Directivas muestra el uso, las + opciones por defecto, el estado y el contexto de cada directiva de + configuración de Apache. Para más información sobre cada + directiva, consulte el Diccionario + de Directivas.

    + +

    La primera columna muestra el nombre y el uso de la directiva. + La segunda columna muestra el valor por defecto de la directiva, + si existe ese valor por defecto. Si el valor por defecto es + demasiado largo para mostrarlo, el primer caracter va seguido de + un signo "+".

    + +

    La tercera y la cuarta columna listan los contextos en los que + la directiva puede funcionar y el estado de la directiva de + acuerdo con las notas que detallan más abajo.

    +
    +
    + + + +
     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X  + + + + + +
    sserver config
    vvirtual host
    ddirectory
    h.htaccess
    + + + + + + +
    CCore
    MMPM
    BBase
    EExtensión
    XExperimental
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AcceptMutex Default|method Default sM
    Method that Apache uses to serialize multiple children +accepting requests on network sockets
    AcceptPathInfo On|Off|Default Default svdhC
    Resources accept trailing pathname information
    AccessFileName filename [filename] ... .htaccess svC
    Name of the distributed configuration file
    Action action-type cgi-script [virtual]svdhB
    Activates a CGI script for a particular handler or +content-type
    AddAlt string file [file] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by filename
    AddAltByEncoding string MIME-encoding +[MIME-encoding] ...svdhB
    Alternate text to display for a file instead of an icon +selected by MIME-encoding
    AddAltByType string MIME-type +[MIME-type] ...svdhB
    Alternate text to display for a file, instead of an +icon selected by MIME content-type
    AddCharset charset extension +[extension] ...svdhB
    Maps the given filename extensions to the specified content +charset
    AddDefaultCharset On|Off|charset Off svdhC
    Default charset parameter to be added when a response +content-type is text/plain or text/html
    AddDescription string file [file] ...svdhB
    Description to display for a file
    AddEncoding MIME-enc extension +[extension] ...svdhB
    Maps the given filename extensions to the specified encoding +type
    AddHandler handler-name extension +[extension] ...svdhB
    Maps the filename extensions to the specified +handler
    AddIcon icon name [name] +...svdhB
    Icon to display for a file selected by name
    AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...svdhB
    Icon to display next to files selected by MIME +content-encoding
    AddIconByType icon MIME-type +[MIME-type] ...svdhB
    Icon to display next to files selected by MIME +content-type
    AddInputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +client requests
    AddLanguage MIME-lang extension +[extension] ...svdhB
    Maps the given filename extension to the specified content +language
    AddModuleInfo module-name stringsvE
    Adds additional information to the module +information displayed by the server-info handler
    AddOutputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +responses from the server
    AddOutputFilterByType filter[;filter...] +MIME-type [MIME-type] ...svdhC
    assigns an output filter to a particular MIME-type
    AddType MIME-type extension +[extension] ...svdhB
    Maps the given filename extensions onto the specified content +type
    Alias URL-path +file-path|directory-pathsvB
    Maps URLs to filesystem locations
    AliasMatch regex +file-path|directory-pathsvB
    Maps URLs to filesystem locations using regular +expressions
    Allow from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts can access an area of the +server
    AllowCONNECT port [port] ... 443 563 svE
    Ports that are allowed to CONNECT through the +proxy
    AllowEncodedSlashes On|Off Off svC
    Determines whether encoded path separators in URLs are allowed to +be passed through
    AllowOverride All|None|directive-type +[directive-type] ... All dC
    Types of directives that are allowed in +.htaccess files
    Anonymous user [user] ...dhE
    Specifies userIDs that are allowed access without +password verification
    Anonymous_LogEmail On|Off On dhE
    Sets whether the password entered will be logged in the +error log
    Anonymous_MustGiveEmail On|Off On dhE
    Specifies whether blank passwords are allowed
    Anonymous_NoUserID On|Off Off dhE
    Sets whether the userID field may be empty
    Anonymous_VerifyEmail On|Off Off dhE
    Sets whether to check the password field for a correctly +formatted email address
    AssignUserID user-id group-idvM
    Tie a virtual host to a user and group ID
    AuthBasicAuthoritative On|Off On dhB
    Sets whether authorization and authentication are passed to +lower level modules
    AuthBasicProvider On|Off|provider-name +[provider-name] ... On dhB
    Sets the authentication provider(s) for this location
    AuthDBMGroupFile file-pathdhE
    Sets the name of the database file containing the list +of user groups for authorization
    AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store passwords
    AuthDBMUserFile file-pathdhE
    Sets the name of a database file containing the list of users and +passwords for authentication
    AuthDefaultAuthoritative On|Off On dhB
    Sets whether authentication is passed to lower level +modules
    AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
    Selects the algorithm used to calculate the challenge and +response hashes in digest authentication
    AuthDigestDomain URI [URI] ...dhX
    URIs that are in the same protection space for digest +authentication
    AuthDigestNcCheck On|Off Off sX
    Enables or disables checking of the nonce-count sent by the +server
    AuthDigestNonceFormat formatdhX
    Determines how the nonce is generated
    AuthDigestNonceLifetime seconds 300 dhX
    How long the server nonce is valid
    AuthDigestProvider On|Off|provider-name +[provider-name] ... On dhX
    Sets the authentication provider(s) for this location
    AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhX
    Determines the quality-of-protection to use in digest +authentication
    AuthDigestShmemSize size 1000 sX
    The amount of shared memory to allocate for keeping track +of clients
    AuthGroupFile file-pathdhB
    Sets the name of a text file containing the list +of user groups for authorization
    AuthLDAPBindDN distinguished-namedhE
    Optional DN to use in binding to the LDAP server
    AuthLDAPBindPassword passworddhE
    Password used in conjuction with the bind DN
    AuthLDAPCharsetConfig file-pathsE
    Language to charset conversion configuration file
    AuthLDAPCompareDNOnServer on|off on dhE
    Use the LDAP server to compare the DNs
    AuthLDAPDereferenceAliases never|searching|finding|always Always dhE
    When will the module de-reference aliases
    AuthLDAPGroupAttribute attributedhE
    LDAP attributes used to check for group membership
    AuthLDAPGroupAttributeIsDN on|off on dhE
    Use the DN of the client username when checking for +group membership
    AuthLDAPRemoteUserIsDN on|off off dhE
    Use the DN of the client username to set the REMOTE_USER +environment variable
    AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]dhE
    URL specifying the LDAP search parameters
    AuthName auth-domaindhC
    Authorization realm for use in HTTP +authentication
    <AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>svE
    Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    AuthType Basic|DigestdhC
    Type of user authentication
    AuthUserFile file-pathdhB
    Sets the name of a text file containing the list of users and +passwords for authentication
    AuthzDBMAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store list of user groups
    AuthzDefaultAuthoritative On|Off On dhB
    Sets whether authorization is passed to lower level +modules
    AuthzGroupFileAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    AuthzLDAPAuthoritative on|off on dhE
    Prevent other authentication modules from +authenticating the user if this one fails
    AuthzOwnerAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzUserAuthoritative On|Off On dhB
    Sets whether authorization will be passed on to lower level +modules
    BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on HTTP User-Agent +
    BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables conditional on User-Agent without +respect to case
    BufferedLogs On|Off Off sB
    Buffer log entries in memory before writing to disk
    CacheDefaultExpire seconds 3600 (one hour) svE
    The default duration to cache a document when no expiry date is specified.
    CacheDirLength length 2 svE
    The number of characters in subdirectory names
    CacheDirLevels levels 3 svE
    The number of levels of subdirectories in the +cache.
    CacheDisable url-stringsvE
    Disable caching of specified URLs
    CacheEnable cache_type url-stringsvE
    Enable caching of specified URLs using a specified storage +manager
    CacheFile file-path [file-path] ...sX
    Cache a list of file handles at startup time
    CacheIgnoreCacheControl On|Off Off svE
    Ignore request to not serve cached content to client
    CacheIgnoreHeaders header-string [header-string] ... None svE
    Do not store the given HTTP header(s) in the cache. +
    CacheIgnoreNoLastMod On|Off Off svE
    Ignore the fact that a response has no Last Modified +header.
    CacheLastModifiedFactor float 0.1 svE
    The factor used to compute an expiry date based on the +LastModified date.
    CacheMaxExpire seconds 86400 (one day) svE
    The maximum time in seconds to cache a document
    CacheMaxFileSize bytes 1000000 svE
    The maximum size (in bytes) of a document to be placed in the +cache
    CacheMinFileSize bytes 1 svE
    The minimum size (in bytes) of a document to be placed in the +cache
    CacheNegotiatedDocs On|Off Off svB
    Allows content-negotiated documents to be +cached by proxy servers
    CacheRoot directorysvE
    The directory root under which cache files are +stored
    CacheStoreNoStore On|Off Off svE
    Attempt to cache requests or responses that have been marked as no-store.
    CacheStorePrivate On|Off Off svE
    Attempt to cache responses that the server has marked as private
    CGIMapExtension cgi-path .extensiondhC
    Technique for locating the interpreter for CGI +scripts
    CharsetDefault charsetsvdhX
    Charset to translate into
    CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
    Configures charset translation behavior
    CharsetSourceEnc charsetsvdhX
    Source charset of files
    CheckSpelling on|off Off svdhE
    Enables the spelling +module
    ChildPerUserID user-id group-id +num-childrensM
    Specify user ID and group ID for a number of child +processes
    ContentDigest On|Off Off svdhC
    Enables the generation of Content-MD5 HTTP Response +headers
    CookieDomain domainsvdhE
    The domain to which the tracking cookie applies
    CookieExpires expiry-periodsvdhE
    Expiry time for the tracking cookie
    CookieLog filenamesvB
    Sets filename for the logging of cookies
    CookieName token Apache svdhE
    Name of the tracking cookie
    CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
    Format of the cookie header field
    CookieTracking on|off off svdhE
    Enables tracking cookie
    CoreDumpDirectory directorysM
    Directory where Apache attempts to +switch before dumping core
    CustomLog file|pipe +format|nickname +[env=[!]environment-variable]svB
    Sets filename and format of log file
    Dav On|Off|provider-name Off dE
    Enable WebDAV HTTP methods
    DavDepthInfinity on|off off svdE
    Allow PROPFIND, Depth: Infinity requests
    DavGenericLockDB file-pathsvdE
    Location of the DAV lock database
    DavLockDB file-pathsvE
    Location of the DAV lock database
    DavMinTimeout seconds 0 svdE
    Minimum amount of time the server holds a lock on +a DAV resource
    DBDExptime time-in-secondssvX
    Keepalive time for idle connections
    DBDKeep numbersvX
    Maximum sustainednumber of connections
    DBDMax numbersvX
    Maximum number of connections
    DBDMin numbersvX
    Minimum number of connections
    DBDParams +param1=value1[,param2=value2]svX
    Parameters for database connection
    DBDPersist 0|1svX
    Whether to use persistent connections
    DBDPrepareSQL "SQL statement" labelsvX
    Define an SQL prepared statement
    DBDriver namesvX
    Specify an SQL driver
    DefaultIcon url-pathsvdhB
    Icon to display for files when no specific icon is +configured
    DefaultLanguage MIME-langsvdhB
    Sets all files in the given scope to the specified +language
    DefaultType MIME-type text/plain svdhC
    MIME content-type that will be sent if the +server cannot determine a type in any other way
    DeflateBufferSize value 8096 svE
    Fragment size to be compressed at one time by zlib
    DeflateCompressionLevel valuesvE
    How much compression do we apply to the output
    DeflateFilterNote [type] notenamesvE
    Places the compression ratio in a note for logging
    DeflateMemLevel value 9 svE
    How much memory should be used by zlib for compression
    DeflateWindowSize value 15 svE
    Zlib compression window size
    Deny from all|host|env=env-variable +[host|env=env-variable] ...dhB
    Controls which hosts are denied access to the +server
    <Directory directory-path> +... </Directory>svC
    Enclose a group of directives that apply only to the +named file-system directory and sub-directories
    DirectoryIndex + local-url [local-url] ... index.html svdhB
    List of resources to look for when the client requests +a directory
    <DirectoryMatch regex> +... </DirectoryMatch>svC
    Enclose directives that apply to +file-system directories matching a regular expression and their +subdirectories
    DirectorySlash On|Off On svdhB
    Toggle trailing slash redirects on or off
    DocumentRoot directory-path /usr/local/apache/h +svC
    Directory that forms the main document tree visible +from the web
    DumpIOInput On|Off Off sE
    Dump all input data to the error log
    DumpIOOutput On|Off Off sE
    Dump all output data to the error log
    EnableExceptionHook On|Off Off sM
    Enables a hook that runs exception handlers +after a crash
    EnableMMAP On|Off On svdhC
    Use memory-mapping to read files during delivery
    EnableSendfile On|Off On svdhC
    Use the kernel sendfile support to deliver files to the client
    ErrorDocument error-code documentsvdhC
    What the server will return to the client +in case of an error
    ErrorLog file-path|syslog[:facility] logs/error_log (Uni +svC
    Location where the server will log errors
    ExamplesvdhX
    Demonstration directive to illustrate the Apache module +API
    ExpiresActive On|OffsvdhE
    Enables generation of Expires +headers
    ExpiresByType MIME-type +<code>secondssvdhE
    Value of the Expires header configured +by MIME type
    ExpiresDefault <code>secondssvdhE
    Default algorithm for calculating expiration time
    ExtendedStatus On|Off Off sB
    Keep track of extended status information for each +request
    ExtFilterDefine filtername parameterssE
    Define an external filter
    ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
    Configure mod_ext_filter options
    FileETag component ... INode MTime Size svdhC
    File attributes used to create the ETag +HTTP response header
    <Files filename> ... </Files>svdhC
    Contains directives that apply to matched +filenames
    <FilesMatch regex> ... </FilesMatch>svdhC
    Contains directives that apply to regular-expression matched +filenames
    FilterChain [+=-@!]filter-name ...svdhX
    Configure the filter chain
    FilterDeclare filter-name [type]svdhX
    Declare a smart filter
    FilterProtocol filter-name [provider-name] + proto-flagssvdhX
    Deal with correct HTTP protocol handling
    FilterProvider filter-name provider-name + [req|resp|env]=dispatch matchsvdhX
    Register a content filter
    FilterTrace filter-name levelsvdX
    Get debug/diagnostic information from + mod_filter
    ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
    Action to take if a single acceptable document is not +found
    ForceType MIME-type|NonedhC
    Forces all matching files to be served with the specified +MIME content-type
    ForensicLog filename|pipesvE
    Sets filename of the forensic log
    Group unix-group #-1 sM
    Group under which the server will answer +requests
    Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]svdhE
    Configure HTTP response headers
    HeaderName filenamesvdhB
    Name of the file that will be inserted at the top +of the index listing
    HostnameLookups On|Off|Double Off svdC
    Enables DNS lookups on client IP addresses
    IdentityCheck On|Off Off svdE
    Enables logging of the RFC 1413 identity of the remote +user
    IdentityCheckTimeout seconds 30 svdE
    Determines the timeout duration for ident requests
    <IfDefine [!]parameter-name> ... + </IfDefine>svdhC
    Encloses directives that will be processed only +if a test is true at startup
    <IfModule [!]module-file|module-identifier> ... + </IfModule>svdhC
    Encloses directives that are processed conditional on the +presence or absence of a specific module
    <IfVersion [[!]operator] version> ... +</IfVersion>svdhE
    contains version dependent configuration
    ImapBase map|referer|URL http://servername/ svdhB
    Default base for imagemap files
    ImapDefault error|nocontent|map|referer|URL nocontent svdhB
    Default action when an imagemap is called with coordinates +that are not explicitly mapped
    ImapMenu none|formatted|semiformatted|unformattedsvdhB
    Action if no coordinates are given when calling +an imagemap
    Include file-path|directory-pathsvdC
    Includes other configuration files from within +the server configuration files
    IndexIgnore file [file] ...svdhB
    Adds to the list of files to hide when listing +a directory
    IndexOptions [+|-]option [[+|-]option] +...svdhB
    Various configuration settings for directory +indexing
    IndexOrderDefault Ascending|Descending +Name|Date|Size|Description Ascending Name svdhB
    Sets the default ordering of the directory index
    IndexStyleSheet url-pathsvdhB
    Adds a CSS stylesheet to the directory index
    ISAPIAppendLogToErrors on|off off svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log
    ISAPIAppendLogToQuery on|off on svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field
    ISAPICacheFile file-path [file-path] +...svB
    ISAPI .dll files to be loaded at startup
    ISAPIFakeAsync on|off off svdhB
    Fake asynchronous support for ISAPI callbacks
    ISAPILogNotSupported on|off off svdhB
    Log unsupported feature requests from ISAPI +extensions
    ISAPIReadAheadBuffer size 49152 svdhB
    Size of the Read Ahead Buffer sent to ISAPI +extensions
    KeepAlive On|Off On svC
    Enables HTTP persistent connections
    KeepAliveTimeout seconds 5 svC
    Amount of time the server will wait for subsequent +requests on a persistent connection
    LanguagePriority MIME-lang [MIME-lang] +...svdhB
    The precendence of language variants for cases where +the client does not express a preference
    LDAPCacheEntries number 1024 sE
    Maximum number of entries in the primary LDAP cache
    LDAPCacheTTL seconds 600 sE
    Time that cached items remain valid
    LDAPConnectionTimeout secondssE
    Specifies the socket connection timeout in seconds
    LDAPOpCacheEntries number 1024 sE
    Number of entries used to cache LDAP compare +operations
    LDAPOpCacheTTL seconds 600 sE
    Time that entries in the operation cache remain +valid
    LDAPSharedCacheFile directory-path/filenamesE
    Sets the shared memory cache file
    LDAPSharedCacheSize bytes 102400 sE
    Size in bytes of the shared-memory cache
    LDAPTrustedClientCert type directory-path/filename/nickname [password]svdhE
    Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    LDAPTrustedGlobalCert type directory-path/filename [password]sE
    Sets the file or database containing global trusted +Certificate Authority or global client certificates
    LDAPTrustedMode typesvdhE
    Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    LDAPVerifyServerCert On|Off On sE
    Force server certificate verification
    <Limit method [method] ... > ... + </Limit>svdhC
    Restrict enclosed access controls to only certain HTTP +methods
    <LimitExcept method [method] ... > ... + </LimitExcept>svdhC
    Restrict access controls to all HTTP methods +except the named ones
    LimitInternalRecursion number [number] 10 svC
    Determine maximum number of internal redirects and nested +subrequests
    LimitRequestBody bytes 0 svdhC
    Restricts the total size of the HTTP request body sent +from the client
    LimitRequestFields number 100 sC
    Limits the number of HTTP request header fields that +will be accepted from the client
    LimitRequestFieldsize bytessC
    Limits the size of the HTTP request header allowed from the +client
    LimitRequestLine bytes 8190 sC
    Limit the size of the HTTP request line that will be accepted +from the client
    LimitXMLRequestBody bytes 1000000 svdhC
    Limits the size of an XML-based request body
    Listen [IP-address:]portnumbersM
    IP addresses and ports that the server +listens to
    ListenBacklog backlogsM
    Maximum length of the queue of pending connections
    LoadFile filename [filename] ...sE
    Link in the named object file or library
    LoadModule module filenamesE
    Links in the object file or library, and adds to the list +of active modules
    <Location + URL-path|URL> ... </Location>svC
    Applies the enclosed directives only to matching +URLs
    <LocationMatch + regex> ... </LocationMatch>svC
    Applies the enclosed directives only to regular-expression +matching URLs
    LockFile filename logs/accept.lock sM
    Location of the accept serialization lock file
    LogFormat format|nickname +[nickname] "%h %l %u %t \"%r\" +svB
    Describes a format for use in a log file
    LogLevel level warn svC
    Controls the verbosity of the ErrorLog
    MaxClients numbersM
    Maximum number of child processes that will be created +to serve requests
    MaxKeepAliveRequests number 100 svC
    Number of requests allowed on a persistent +connection
    MaxMemFree KBytes 0 sM
    Maximum amount of memory that the main allocator is allowed +to hold without calling free()
    MaxRequestsPerChild number 10000 sM
    Limit on the number of requests that an individual child server +will handle during its life
    MaxRequestsPerThread number 0 sM
    Limita el número de peticiones que una hebra (thread) puede +atender durante su vida
    MaxSpareServers number 10 sM
    Maximum number of idle child server processes
    MaxSpareThreads numbersM
    Maximum number of idle threads
    MaxThreads number 2048 sM
    Set the maximum number of worker threads
    MaxThreadsPerChild number 64 sM
    Maximum number of threads per child process
    MCacheMaxObjectCount value 1009 sE
    The maximum number of objects allowed to be placed in the +cache
    MCacheMaxObjectSize bytes 10000 sE
    The maximum size (in bytes) of a document allowed in the +cache
    MCacheMaxStreamingBuffer size_in_bytes the smaller of 1000 +sE
    Maximum amount of a streamed response to buffer in memory +before declaring the response uncacheable
    MCacheMinObjectSize bytes 0 sE
    The minimum size (in bytes) of a document to be allowed in the +cache
    MCacheRemovalAlgorithm LRU|GDSF GDSF sE
    The algorithm used to select documents for removal from the +cache
    MCacheSize KBytes 100 sE
    The maximum amount of memory used by the cache in +KBytes
    MetaDir directory .web svdhE
    Name of the directory to find CERN-style meta information +files
    MetaFiles on|off off svdhE
    Activates CERN meta-file processing
    MetaSuffix suffix .meta svdhE
    File name suffix for the file containg CERN-style +meta information
    MimeMagicFile file-pathsvE
    Enable MIME-type determination based on file contents +using the specified magic file
    MinSpareServers number 5 sM
    Minimum number of idle child server processes
    MinSpareThreads numbersM
    Minimum number of idle threads available to handle request +spikes
    MMapFile file-path [file-path] ...sX
    Map a list of files into memory at startup time
    ModMimeUsePathInfo On|Off Off dB
    Tells mod_mime to treat path_info +components as part of the filename
    MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] NegotiatedOnly svdhB
    The types of files that will be included when searching for +a matching file with MultiViews
    NameVirtualHost addr[:port]sC
    Designates an IP address for name-virtual +hosting
    NoProxy host [host] ...svE
    Hosts, domains, or networks that will be connected to +directly
    NumServers number 2 sM
    Total number of children alive at the same time
    NWSSLTrustedCerts filename [filename] ...sB
    List of additional client certificates
    NWSSLUpgradeable [IP-address:]portnumbersB
    Allows a connection to be upgraded to an SSL connection upon request
    Options + [+|-]option [[+|-]option] ... All svdhC
    Configures what features are available in a particular +directory
    Order ordering Deny,Allow dhB
    Controls the default access state and the order in which +Allow and Deny are +evaluated.
    PassEnv env-variable [env-variable] +...svdhB
    Passes environment variables from the shell
    PidFile filename logs/httpd.pid sM
    File where the server records the process ID +of the daemon
    ProtocolEcho On|OffsvX
    Turn the echo server on or off
    <Proxy wildcard-url> ...</Proxy>svE
    Container for directives applied to proxied resources
    ProxyBadHeader IsError|Ignore|StartBody IsError svE
    Determines how to handle bad header lines in a +response
    ProxyBlock *|word|host|domain +[word|host|domain] ...svE
    Words, hosts, or domains that are banned from being +proxied
    ProxyDomain DomainsvE
    Default domain name for proxied requests
    ProxyErrorOverride On|Off Off svE
    Override error pages for proxied content
    ProxyIOBufferSize bytes 8192 svE
    Determine size of internal data throughput buffer
    <ProxyMatch regex> ...</ProxyMatch>svE
    Container for directives applied to regular-expression-matched +proxied resources
    ProxyMaxForwards number 10 svE
    Maximium number of proxies that a request can be forwarded +through
    ProxyPass [path] !|url [key=value key=value ...]]svdE
    Maps remote servers into the local server URL-space
    ProxyPassReverse [path] urlsvdE
    Adjusts the URL in HTTP response headers sent from a reverse +proxied server
    ProxyPassReverseCookieDomain internal-domain public-domainsvdE
    Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server
    ProxyPassReverseCookiePath internal-path public-pathsvdE
    Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server
    ProxyPreserveHost On|Off Off svE
    Use incoming Host HTTP request header for proxy +request
    ProxyReceiveBufferSize bytes 0 svE
    Network buffer size for proxied HTTP and FTP +connections
    ProxyRemote match remote-serversvE
    Remote proxy used to handle certain requests
    ProxyRemoteMatch regex remote-serversvE
    Remote proxy used to handle requests matched by regular +expressions
    ProxyRequests On|Off Off svE
    Enables forward (standard) proxy requests
    ProxyTimeout seconds 300 svE
    Network timeout for proxied requests
    ProxyVia On|Off|Full|Block Off svE
    Information provided in the Via HTTP response +header for proxied requests
    ReadmeName filenamesvdhB
    Name of the file that will be inserted at the end +of the index listing
    Redirect [status] URL-path +URLsvdhB
    Sends an external redirect asking the client to fetch +a different URL
    RedirectMatch [status] regex +URLsvdhB
    Sends an external redirect based on a regular expression match +of the current URL
    RedirectPermanent URL-path URLsvdhB
    Sends an external permanent redirect asking the client to fetch +a different URL
    RedirectTemp URL-path URLsvdhB
    Sends an external temporary redirect asking the client to fetch +a different URL
    RemoveCharset extension [extension] +...vdhB
    Removes any character set associations for a set of file +extensions
    RemoveEncoding extension [extension] +...vdhB
    Removes any content encoding associations for a set of file +extensions
    RemoveHandler extension [extension] +...vdhB
    Removes any handler associations for a set of file +extensions
    RemoveInputFilter extension [extension] +...vdhB
    Removes any input filter associations for a set of file +extensions
    RemoveLanguage extension [extension] +...vdhB
    Removes any language associations for a set of file +extensions
    RemoveOutputFilter extension [extension] +...vdhB
    Removes any output filter associations for a set of file +extensions
    RemoveType extension [extension] +...vdhB
    Removes any content type associations for a set of file +extensions
    RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]svdhE
    Configure HTTP request headers
    Require entity-name [entity-name] ...dhC
    Selects which authenticated users can access +a resource
    RewriteBase URL-pathdhE
    Sets the base URL for per-directory rewrites
    RewriteCond + TestString CondPatternsvdhE
    Defines a condition under which rewriting will take place +
    RewriteEngine on|off off svdhE
    Enables or disables runtime rewriting engine
    RewriteLock file-pathsE
    Sets the name of the lock file used for RewriteMap +synchronization
    RewriteLog file-pathsvE
    Sets the name of the file used for logging rewrite engine +processing
    RewriteLogLevel Level 0 svE
    Sets the verbosity of the log file used by the rewrite +engine
    RewriteMap MapName MapType:MapSource +svE
    Defines a mapping function for key-lookup
    RewriteOptions OptionssvdhE
    Sets some special options for the rewrite engine
    RewriteRule + Pattern SubstitutionsvdhE
    Defines rules for the rewriting engine
    RLimitCPU seconds|max [seconds|max]svdhC
    Limits the CPU consumption of processes launched +by Apache children
    RLimitMEM bytes|max [bytes|max]svdhC
    Limits the memory consumption of processes launched +by Apache children
    RLimitNPROC number|max [number|max]svdhC
    Limits the number of processes that can be launched by +processes launched by Apache children
    Satisfy Any|All All dhC
    Interaction between host-level access control and +user authentication
    ScoreBoardFile file-path logs/apache_status sM
    Location of the file used to store coordination data for +the child processes
    Script method cgi-scriptsvdB
    Activates a CGI script for a particular request +method.
    ScriptAlias URL-path +file-path|directory-pathsvB
    Maps a URL to a filesystem location and designates the +target as a CGI script
    ScriptAliasMatch regex +file-path|directory-pathsvB
    Maps a URL to a filesystem location using a regular expression +and designates the target as a CGI script
    ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
    Technique for locating the interpreter for CGI +scripts
    ScriptLog file-pathsvB
    Location of the CGI script error logfile
    ScriptLogBuffer bytes 1024 svB
    Maximum amount of PUT or POST requests that will be recorded +in the scriptlog
    ScriptLogLength bytes 10385760 svB
    Size limit of the CGI script logfile
    ScriptSock file-path logs/cgisock svB
    The name of the socket to use for communication with +the cgi daemon
    SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]sB
    Enables SSL encryption for the specified port
    SendBufferSize bytes 0 sM
    TCP buffer size
    ServerAdmin email-address|URLsvC
    Email address that the server includes in error +messages sent to the client
    ServerAlias hostname [hostname] ...vC
    Alternate names for a host used when matching requests +to name-virtual hosts
    ServerLimit numbersM
    Upper limit on configurable number of processes
    ServerName fully-qualified-domain-name[:port]svC
    Hostname and port that the server uses to identify +itself
    ServerPath URL-pathvC
    Legacy URL pathname for a name-based virtual host that +is accessed by an incompatible browser
    ServerRoot directory-path /usr/local/apache sC
    Base directory for the server installation
    ServerSignature On|Off|EMail Off svdhC
    Configures the footer on server-generated documents
    ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
    Configures the Server HTTP response +header
    SetEnv env-variable valuesvdhB
    Sets environment variables
    SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +
    SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    Sets environment variables based on attributes of the request +without respect to case
    SetHandler handler-name|NonesvdhC
    Forces all matching files to be processed by a +handler
    SetInputFilter filter[;filter...]svdhC
    Sets the filters that will process client requests and POST +input
    SetOutputFilter filter[;filter...]svdhC
    Sets the filters that will process responses from the +server
    SSIEndTag tag "-->" svB
    String that ends an include element
    SSIErrorMsg message "[an error occurred +svdhB
    Error message displayed when there is an SSI +error
    SSIStartTag tag "<!--#" svB
    String that starts an include element
    SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +svdhB
    Configures the format in which date strings are +displayed
    SSIUndefinedEcho string "(none)" svdhB
    String displayed when an unset variable is echoed
    SSLCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Client Auth
    SSLCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Client Auth
    SSLCADNRequestFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    SSLCADNRequestPath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    SSLCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Client Auth
    SSLCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Client Auth
    SSLCertificateChainFile file-pathsvE
    File of PEM-encoded Server CA Certificates
    SSLCertificateFile file-pathsvE
    Server PEM-encoded X.509 Certificate file
    SSLCertificateKeyFile file-pathsvE
    Server PEM-encoded Private Key file
    SSLCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +handshake
    SSLCryptoDevice engine builtin sE
    Enable use of a cryptographic hardware accelerator
    SSLEngine on|off|optional off svE
    SSL Engine Operation Switch
    SSLHonorCiperOrder flagsvE
    Option to prefer the server's cipher preference order
    SSLMutex type none sE
    Semaphore for internal mutual exclusion of +operations
    SSLOptions [+|-]option ...svdhE
    Configure various SSL engine run-time options
    SSLPassPhraseDialog type builtin sE
    Type of pass phrase dialog for encrypted private +keys
    SSLProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors
    SSLProxyCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    SSLProxyCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Remote Server Auth
    SSLProxyCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +proxy handshake
    SSLProxyEngine on|off off svE
    SSL Proxy Engine Operation Switch
    SSLProxyMachineCertificateFile filenamesE
    File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyMachineCertificatePath directorysE
    Directory of PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors for proxy usage
    SSLProxyVerify level none svdhE
    Type of remote server Certificate verification
    SSLProxyVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Remote Server +Certificate verification
    SSLRandomSeed context source +[bytes]sE
    Pseudo Random Number Generator (PRNG) seeding +source
    SSLRequire expressiondhE
    Allow access only when an arbitrarily complex +boolean expression is true
    SSLRequireSSLdhE
    Deny access when SSL is not used for the +HTTP request
    SSLSessionCache type none sE
    Type of the global/inter-process SSL Session +Cache
    SSLSessionCacheTimeout seconds 300 svE
    Number of seconds before an SSL session expires +in the Session Cache
    SSLUserName varnamesdhE
    Variable name to determine user name
    SSLVerifyClient level none svdhE
    Type of Client Certificate verification
    SSLVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Client +Certificate verification
    StartServers numbersM
    Number of child server processes created at startup
    StartThreads numbersM
    Number of threads created on startup
    SuexecUserGroup User GroupsvE
    User and group permissions for CGI programs
    ThreadLimit numbersM
    Sets the upper limit on the configurable number of threads +per child process
    ThreadsPerChild numbersM
    Number of threads created by each child process
    ThreadStackSize sizesM
    The size in bytes of the stack used by threads handling +client connections
    TimeOut seconds 300 sC
    Amount of time the server will wait for +certain events before failing a request
    TransferLog file|pipesvB
    Specify location of a log file
    TypesConfig file-path conf/mime.types sB
    The location of the mime.types file
    UnsetEnv env-variable [env-variable] +...svdhB
    Removes variables from the environment
    UseCanonicalName On|Off|DNS Off svdC
    Configures how the server determines its own name and +port
    User unix-userid #-1 sM
    The userid under which the server will answer +requests
    UserDir directory-filenamesvB
    Location of the user-specific directories
    VirtualDocumentRoot interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    VirtualDocumentRootIP interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    <VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>sC
    Contains directives that apply only to a specific +hostname or IP address
    VirtualScriptAlias interpolated-directory|none none svE
    Dynamically configure the location of the CGI directory for +a given virtual host
    VirtualScriptAliasIP interpolated-directory|none none svE
    Dynamically configure the location of the cgi directory for +a given virtual host
    Win32DisableAcceptExsM
    Use accept() rather than AcceptEx() to accept network connections
    XBitHack on|off|full off svdhB
    Parse SSI directives in files with the execute bit +set
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/quickreference.html.ja.euc-jp b/trunk/docs/manual/mod/quickreference.html.ja.euc-jp new file mode 100644 index 0000000000..83c855e5c8 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html.ja.euc-jp @@ -0,0 +1,681 @@ + + + +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö ¥¯¥¤¥Ã¥¯¥ê¥Õ¥¡¥ì¥ó¥¹ - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö ¥¯¥¤¥Ã¥¯¥ê¥Õ¥¡¥ì¥ó¥¹

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö ¥¯¥¤¥Ã¥¯¥ê¥Õ¥¡¥ì¥ó¥¹¤Ç¤Ï¡¢³Æ Apache ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + »ÈÍÑÊýË¡¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¡¢¥¹¥Æ¡¼¥¿¥¹¤È¥³¥ó¥Æ¥­¥¹¥È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£ + ³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¡¢¤è¤ê¾Ü¤·¤¤¾ðÊó¤Ë´Ø¤·¤Æ¤Ï + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¼­½ñ¤ò + ¤´Í÷²¼¤µ¤¤¡£

    + +

    Âè 1 ÎóÌܤϥǥ£¥ì¥¯¥Æ¥£¥Ö¤Î̾Á°¤È»ÈÍÑÊýË¡¤Ç¤¹¡£ + Âè 2 ÎóÌÜ¤Ï (¤â¤·¤¢¤ì¤Ð) ¥Ç¥Õ¥©¥ë¥ÈÃͤȤʤäƤ¤¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃͤ¬Ä¹¤¹¤®¤Æɽ¼¨¤·¤­¤ì¤Ê¤¤¾ì¹ç¤Ï¡¢ºÇ½é¤Îʸ»úÎó¤Î¸å¤í¤Ë + ¡Ö + ¡×¤¬Â³¤­¤Þ¤¹¡£

    + +

    Âè 3, 4 Îó¤Ï¡¢²¼¤Îɽ¤ÎÃí¼á¤Ë½¾¤Ã¤Æ¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î»ÈÍѤǤ­¤ë¥³¥ó¥Æ¥­¥¹¥È¤È¡¢ + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥¹¥Æ¡¼¥¿¥¹¤¬¼¨¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    +
    + + + +
     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X  + + + + + +
    s¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ë
    v¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È
    d¥Ç¥£¥ì¥¯¥È¥ê
    h.htaccess
    + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AcceptMutex default|method default sM
    Ê£¿ô¤Î»Ò¥×¥í¥»¥¹¤¬¥Í¥Ã¥È¥ï¡¼¥¯¥½¥±¥Ã¥È¤Ç¥ê¥¯¥¨¥¹¥È¤ò +accept ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤Ë¡¢Apache ¤¬¤½¤ì¤é¤Î»Ò¥×¥í¥»¥¹¤òľÎ󲽤¹¤ë¤¿¤á¤Ë +»È¤¦ÊýË¡
    AcceptPathInfo On|Off|Default Default svdhC
    ¸å¤Ë³¤¯¥Ñ¥¹Ì¾¾ðÊó¤ò¼õ¤±ÉÕ¤±¤ë¥ê¥½¡¼¥¹¤Î»ØÄê
    AccessFileName filename [filename] ... .htaccess svC
    ʬ»¶ÀßÄê¥Õ¥¡¥¤¥ë¤Î̾Á°
    Action action-type cgi-script [virtual]svdhB
    ÆÃÄê¤Î¥Ï¥ó¥É¥é¤ä¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ËÂФ·¤Æ CGI ¤ò¼Â¹Ô¤¹¤ë¤è¤¦¤Ë +ÀßÄê
    AddAlt string file [file] ...svdhB
    ¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ë +ɽ¼¨¤µ¤ì¤ë¡¢¥Õ¥¡¥¤¥ë̾¤ÇÁªÂò¤µ¤ì¤¿ÂåÂإƥ­¥¹¥È
    AddAltByEncoding string MIME-encoding +[MIME-encoding] ...svdhB
    ¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ëɽ¼¨¤µ¤ì¤ë¡¢MIME Éä¹æ²½ÊýË¡¤ÇÁªÂò¤µ¤ì¤¿ +ÂåÂإƥ­¥¹¥È
    AddAltByType string MIME-type +[MIME-type] ...svdhB
    ¥¢¥¤¥³¥ó¤ÎÂå¤ï¤ê¤Ë +ɽ¼¨¤µ¤ì¤ë¡¢MIME ¥¿¥¤¥×¤ÇÁªÂò¤µ¤ì¤¿ÂåÂإƥ­¥¹¥È
    AddCharset charset extension +[extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿Ê¸»ú¥»¥Ã¥È¤Ë¥Þ¥Ã¥×¤¹¤ë
    AddDefaultCharset On|Off|charset Off svdhC
    ¥ì¥¹¥Ý¥ó¥¹¤Î¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤¬ text/plain ¤¢¤ë¤¤¤Ï +text/html ¤Î¾ì¹ç¤ËÄɲ乤ë¥Ç¥Õ¥©¥ë¥È¤Î charset ¥Ñ¥é¥á¡¼¥¿
    AddDescription string file [file] ...svdhB
    ¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æɽ¼¨¤¹¤ëÀâÌÀ
    AddEncoding MIME-enc extension +[extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥¨¥ó¥³¡¼¥Ç¥£¥ó¥° +¤Ë¥Þ¥Ã¥×¤¹¤ë
    AddHandler handler-name extension +[extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥Ï¥ó¥É¥é¤Ë¥Þ¥Ã¥×¤¹¤ë
    AddIcon icon name +[name] ...svdhB
    ¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò̾Á°¤ÇÁªÂò
    AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...svdhB
    ¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò MIME +Éä¹æ²½ÊýË¡¤ÇÁªÂò
    AddIconByType icon MIME-type +[MIME-type] ...svdhB
    ¥Õ¥¡¥¤¥ë¤ÎÎÙ¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó¤ò +MIME ¥¿¥¤¥×¤Ë¤è¤Ã¤ÆÁªÂò
    AddInputFilter filter[;filter...] +extension [extension] ...svdh
    ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤ò¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤¹¤ë + ¥Õ¥£¥ë¥¿¤Ë¥Þ¥Ã¥×¤¹¤ë
    AddLanguage MIME-lang extension +[extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤ò»ØÄꤵ¤ì¤¿¸À¸ì¤Ë¥Þ¥Ã¥×
    AddModuleInfo module-name stringsvE
    server-info ¥Ï¥ó¥É¥é¤Ë¤è¤êɽ¼¨¤µ¤ì¤ë¥â¥¸¥å¡¼¥ë¤Î¾ðÊó¤Ë +ÄɲäξðÊó¤òÉÕ¤±²Ã¤¨¤ë
    AddOutputFilter filter[;filter...] +extension [extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò¥µ¡¼¥Ð¤«¤é¤Î±þÅú¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤Ë + ¥Þ¥Ã¥×¤¹¤ë
    AddOutputFilterByType filter[;filter...] MIME-type +[MIME-type] ...svdhC
    MIME-type ¤Ë½ÐÎÏ¥Õ¥£¥ë¥¿¤ò³ä¤êÅö¤Æ¤ë
    AddType MIME-type extension +[extension] ...svdh
    ¥Õ¥¡¥¤¥ë̾¤Î³ÈÄ¥»Ò¤ò»ØÄꤵ¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ë¥Þ¥Ã¥×
    Alias URL-path +file-path|directory-pathsvB
    URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤˥ޥåפ¹¤ë
    AliasMatch regex +file-path|directory-pathsvB
    Àµµ¬É½¸½¤ò»È¤Ã¤Æ URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤˥ޥåפ¹¤ë
    Allow from all|host|env=env-variable +[host|env=env-variable] ...dhB
    ¥µ¡¼¥Ð¤Î¤¢¤ëÎΰè¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¥Û¥¹¥È¤òÀ©¸æ¤¹¤ë
    AllowCONNECT port [port] ... 443 563 svE
    ¥×¥í¥­¥·¤ò·Ðͳ¤·¤Æ¡¢¤É¤Î¥Ý¡¼¥È¤Ë CONNECT +¤Ç¤­¤ë¤«¤ò»ØÄꤹ¤ë
    AllowEncodedSlashes On|Off Off svC
    URL Ãæ¤ÎÉä¹æ²½¤µ¤ì¤¿¥Ñ¥¹Ê¬Î¥Ê¸»ú¤¬Àè¤ËÅÁ¤¨¤é¤ì¤ë¤Î¤òµö²Ä¤¹¤ë¤«¤É¤¦¤«¤ò +·èÄꤹ¤ë
    AllowOverride All|None|directive-type +[directive-type] ... All dC
    .htaccess ¤Çµö²Ä¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¼ïÎà
    Anonymous user [user] ...dhE
    ¥Ñ¥¹¥ï¡¼¥É¤Î¸¡ººÌµ¤·¤Ç¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ë userID ¤ò»ØÄꤹ¤ë +
    Anonymous_LogEmail On|Off On dhE
    ÆþÎϤµ¤ì¤¿¥Ñ¥¹¥ï¡¼¥É¤¬¥¨¥é¡¼¥í¥°¤Ë¥í¥®¥ó¥°¤µ¤ì¤ë¤«¤É¤¦¤«¤ò +ÀßÄꤹ¤ë
    Anonymous_MustGiveEmail On|Off On dhE
    ¶õ¥Ñ¥¹¥ï¡¼¥É¤òµö²Ä¤¹¤ë¤«¤É¤¦¤«¤ò»ØÄꤹ¤ë
    Anonymous_NoUserID On|Off Off dhE
    ¶õ userID ¤òµö²Ä¤¹¤ë¤«¤ò»ØÄꤹ¤ë
    Anonymous_VerifyEmail On|Off Off dhE
    ¥Ñ¥¹¥ï¡¼¥ÉÍó¤¬Àµ¤·¤¤·Á¼°¤ÎÅŻҥ᡼¥ë¥¢¥É¥ì¥¹¤Ç¤¢¤ë¤³¤È¤ò +Ä´¤Ù¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    AssignUserID user-id group-idvM
    Tie a virtual host to a user and group ID
    AuthBasicAuthoritative On|Off On dhB
    ǧ¾Ú¤È¾µÇ§¤ò¡¢¤è¤êÄ㤤¥ì¥Ù¥ë¤Î¥â¥¸¥å¡¼¥ë¤Ë°Ü¹Ô¤µ¤»¤ë¤«¤ò +ÀßÄꤷ¤Þ¤¹¡£
    AuthBasicProvider On|Off|provider-name +[provider-name] ... On dhB
    ¤³¤Î°ÌÃÖ¤ËÂФ¹¤ëǧ¾Ú¥×¥í¥Ð¥¤¥À¤òÀßÄꤷ¤Þ¤¹¡£
    AuthDBMGroupFile file-pathdhE
    Sets the name of the database file containing the list +of user groups for authorization
    AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
    ¥Ñ¥¹¥ï¡¼¥É¤òÊݸ¤¹¤ë¤¿¤á¤ËɬÍפʥǡ¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤Î¼ïÎà¤ò +ÀßÄꤹ¤ë
    AuthDBMUserFile file-pathdhE
    ǧ¾ÚÍѤΥ桼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î¥ê¥¹¥È¤òÊÝ»ý¤·¤Æ¤¤¤ë +¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    AuthDefaultAuthoritative On|Off On dhB
    ¼¡¤ÎÄ㼡¥ì¥Ù¥ë¤Îǧ¾Ú¥â¥¸¥å¡¼¥ë¤ËÀ©¸æ¤òÅϤ¹¤«¤É¤¦¤«¤ò +ÀßÄꤷ¤Þ¤¹
    AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
    Selects the algorithm used to calculate the challenge and +response hashes in digest authentication
    AuthDigestDomain URI [URI] ...dhX
    URIs that are in the same protection space for digest +authentication
    AuthDigestNcCheck On|Off Off sX
    Enables or disables checking of the nonce-count sent by the +server
    AuthDigestNonceFormat formatdhX
    Determines how the nonce is generated
    AuthDigestNonceLifetime seconds 300 dhX
    How long the server nonce is valid
    AuthDigestProvider On|Off|provider-name +[provider-name] ... On dhX
    Sets the authentication provider(s) for this location
    AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhX
    Determines the quality-of-protection to use in digest +authentication
    AuthDigestShmemSize size 1000 sX
    The amount of shared memory to allocate for keeping track +of clients
    AuthGroupFile file-pathdhB
    ¾Úǧ¤Ë»ÈÍѤ¹¤ë¥æ¡¼¥¶¥°¥ë¡¼¥×¤Î°ìÍ÷¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ë¡¢ +¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤹ¤ë
    AuthLDAPBindDN distinguished-namedhE
    Optional DN to use in binding to the LDAP server
    AuthLDAPBindPassword passworddhE
    Password used in conjuction with the bind DN
    AuthLDAPCharsetConfig file-pathsE
    Language to charset conversion configuration file
    AuthLDAPCompareDNOnServer on|off on dhE
    Use the LDAP server to compare the DNs
    AuthLDAPDereferenceAliases never|searching|finding|always Always dhE
    When will the module de-reference aliases
    AuthLDAPGroupAttribute attributedhE
    LDAP attributes used to check for group membership
    AuthLDAPGroupAttributeIsDN on|off on dhE
    Use the DN of the client username when checking for +group membership
    AuthLDAPRemoteUserIsDN on|off off dhE
    Use the DN of the client username to set the REMOTE_USER +environment variable
    AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]dhE
    URL specifying the LDAP search parameters
    AuthName auth-domaindhC
    HTTP ǧ¾Ú¤Îǧ²ÄÎΰè (ÌõÃí: realm)
    <AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>svE
    Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    AuthType Basic|DigestdhC
    ¥æ¡¼¥¶Ç§¾Ú¤Î¼ïÎà
    AuthUserFile file-pathdhB
    ǧ¾Ú¤Ë»ÈÍѤ¹¤ë¥æ¡¼¥¶¤È¥Ñ¥¹¥ï¡¼¥É¤Î°ìÍ÷¤¬³ÊǼ¤µ¤ì¤Æ¤¤¤ë¡¢ +¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÀßÄꤹ¤ë
    AuthzDBMAuthoritative On|Off On dhE
    Sets whether authorization will be passed on to lower level +modules
    AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
    Sets the type of database file that is used to +store list of user groups
    AuthzDefaultAuthoritative On|Off On dhB
    ¾µÇ§¤¬Äã°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    AuthzGroupFileAuthoritative On|Off On dhB
    ¾µÇ§¤¬²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    AuthzLDAPAuthoritative on|off on dhE
    Prevent other authentication modules from +authenticating the user if this one fails
    AuthzOwnerAuthoritative On|Off On dhE
    ¾µÇ§¤¬²¼°Ì¾µÇ§¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    AuthzUserAuthoritative On|Off On dhB
    ¾µÇ§¤¬²¼°Ì¤Î¥â¥¸¥å¡¼¥ë¤ËÅϤµ¤ì¤ë¤«¤É¤¦¤«¤òÀßÄꤹ¤ë
    BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...svdhB
    HTTP User-Agent ¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë +
    BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    HTTP User-Agent ¤Ë´ð¤Å¤¤¤ÆÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë +´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    BufferedLogs On|Off Off sB
    ¥Ç¥£¥¹¥¯¤Ë½ñ¤­½Ð¤¹Á°¤Ë¥á¥â¥ê¤Ë¥í¥°¥¨¥ó¥È¥ê¤ò¥Ð¥Ã¥Õ¥¡¤¹¤ë
    CacheDefaultExpire seconds 3600 (1»þ´Ö) svE
    ´üÆü¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¤­¤Ë¥É¥­¥å¥á¥ó¥È¤ò¥­¥ã¥Ã¥·¥å¤¹¤ë¥Ç¥Õ¥©¥ë¥È¤Î´ü´Ö
    CacheDirLength length 2 svE
    ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê̾¤Îʸ»ú¿ô
    CacheDirLevels levels 3 svE
    ¥­¥ã¥Ã¥·¥å¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Î¿¼¤µ¤Î¿ô
    CacheDisable url-stringsvE
    ÆÃÄê¤Î URL ¤ò¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤
    CacheEnable cache_type url-stringsvE
    »ØÄꤷ¤¿¥¹¥È¥ì¡¼¥¸´ÉÍýÊý¼°¤ò»È¤Ã¤Æ¤Î¥­¥ã¥Ã¥·¥å¤òÍ­¸ú¤Ë¤¹¤ë
    CacheFile file-path [file-path] ...sX
    Cache a list of file handles at startup time
    CacheIgnoreCacheControl On|Off Off svE
    ¥­¥ã¥Ã¥·¥å¤µ¤ì¤Æ¤¤¤ë¥³¥ó¥Æ¥ó¥Ä¤òÊÖ¤µ¤Ê¤¤¤è¤¦¤Ë¥¯¥é¥¤¥¢¥ó¥È¤«¤é +¥ê¥¯¥¨¥¹¥È¤µ¤ì¤Æ¤â̵»ë¤¹¤ë
    CacheIgnoreHeaders header-string [header-string] ... None svE
    »ØÄꤵ¤ì¤¿ HTTP ¥Ø¥Ã¥À¤ò¥­¥ã¥Ã¥·¥å¤ËÊݸ¤·¤Ê¤¤¡£ +
    CacheIgnoreNoLastMod On|Off Off svE
    ±þÅú¤Ë Last Modified ¤¬Ìµ¤¯¤Æ¤âµ¤¤Ë¤·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë
    CacheLastModifiedFactor float 0.1 svE
    LastModified ¤ÎÆüÉդ˴ð¤Å¤¤¤ÆÍ­¸ú´ü¸Â (expiry) +¤ò·×»»¤¹¤ë¤¿¤á¤Î½Å¤ß¤ò»ØÄꤹ¤ë +
    CacheMaxExpire seconds 86400 (°ìÆü) svE
    ¥É¥­¥å¥á¥ó¥È¤ò¥­¥ã¥Ã¥·¥å¤¹¤ëºÇÂç»þ´Ö¤òÉÿô¤Ç¸½¤·¤¿¤â¤Î
    CacheMaxFileSize bytes 1000000 svE
    ¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇÂç¤Î (¥Ð¥¤¥È¤Ç¤Î) ¥µ¥¤¥º
    CacheMinFileSize bytes 1 svE
    ¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇ¾®¸Â¤Î (¥Ð¥¤¥È¤Ç¤Î) Â礭¤µ
    CacheNegotiatedDocs On|Off Off svB
    ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤µ¤ì¤¿¥É¥­¥å¥á¥ó¥È¤ò¥×¥í¥­¥·¥µ¡¼¥Ð¤¬ +¥­¥ã¥Ã¥·¥å¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë
    CacheRoot directorysvE
    ¥­¥ã¥Ã¥·¥å¥Õ¥¡¥¤¥ë¤¬Êݴɤµ¤ì¤ë¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê
    CacheStoreNoStore On|Off Off svE
    no-store ¤È»ØÄꤵ¤ì¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Î¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¡£
    CacheStorePrivate On|Off Off svE
    private ¤È»ØÄꤵ¤ì¤Æ¤¤¤ë¥ì¥¹¥Ý¥ó¥¹¤Î¥­¥ã¥Ã¥·¥å¤ò»î¤ß¤ë¡£
    CGIMapExtension cgi-path .extensiondhC
    CGI ¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Î°ÌÃÖ¤òÄ´¤Ù¤ë¤¿¤á¤Î¼êË¡
    CharsetDefault charsetsvdhX
    Charset to translate into
    CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
    Configures charset translation behavior
    CharsetSourceEnc charsetsvdhX
    Source charset of files
    CheckSpelling on|off Off svdhE
    spelling ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤¹¤ë
    ChildPerUserID user-id group-id +num-childrensM
    Specify user ID and group ID for a number of child +processes
    ContentDigest On|Off Off svdhC
    Content-MD5 HTTP ±þÅú¥Ø¥Ã¥À¤ÎÀ¸À®¤òÍ­¸ú¤Ë¤¹¤ë
    CookieDomain domainsvdhE
    The domain to which the tracking cookie applies
    CookieExpires expiry-periodsvdhE
    Expiry time for the tracking cookie
    CookieLog filenamesvB
    ¥¯¥Ã¥­¥ó¥°¤Î¥í¥®¥ó¥°¤Î¤¿¤á¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    CookieName token Apache svdhE
    Name of the tracking cookie
    CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
    Format of the cookie header field
    CookieTracking on|off off svdhE
    Enables tracking cookie
    CoreDumpDirectory directorysM
    Apache ¤¬¥³¥¢¥À¥ó¥×¤¹¤ëÁ°¤Ë°ÜÆ°¤ò»î¤ß¤ë¥Ç¥£¥ì¥¯¥È¥ê +
    CustomLog file|pipe +format|nickname +[env=[!]environment-variable]svB
    ¥í¥°¥Õ¥¡¥¤¥ë¤Î̾Á°¤È½ñ¼°¤òÀßÄꤹ¤ë
    Dav On|Off|provider-name Off dE
    WebDAV HTTP ¥á¥½¥Ã¥É¤òÍ­¸ú¤Ë¤·¤Þ¤¹
    DavDepthInfinity on|off off svdE
    PROPFIND, Depth: Infinity ¥ê¥¯¥¨¥¹¥È¤òµö²Ä¤·¤Þ¤¹
    DavGenericLockDB file-pathsvdE
    DAV ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ì½ê
    DavLockDB file-pathsvE
    DAV ¥í¥Ã¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î°ÌÃÖ
    DavMinTimeout seconds 0 svdE
    ¥µ¡¼¥Ð¤¬ DAV ¥ê¥½¡¼¥¹¤Î¥í¥Ã¥¯¤ò°Ý»ý¤¹¤ëºÇ¾®»þ´Ö¤Ç¤¹¡£ +
    DBDExptime time-in-secondssvX
    Keepalive time for idle connections
    DBDKeep numbersvX
    Maximum sustainednumber of connections
    DBDMax numbersvX
    Maximum number of connections
    DBDMin numbersvX
    Minimum number of connections
    DBDParams +param1=value1[,param2=value2]svX
    Parameters for database connection
    DBDPersist 0|1svX
    Whether to use persistent connections
    DBDPrepareSQL "SQL statement" labelsvX
    Define an SQL prepared statement
    DBDriver namesvX
    Specify an SQL driver
    DefaultIcon url-pathsvdhB
    ÆÃÄê¤Î¥¢¥¤¥³¥ó¤¬²¿¤âÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤»þ¤Ë +¥Õ¥¡¥¤¥ë¤Ëɽ¼¨¤¹¤ë¥¢¥¤¥³¥ó
    DefaultLanguage MIME-langsvdh
    ¤¢¤ë¥¹¥³¡¼¥×¤Î¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò»ØÄꤵ¤ì¤¿¸À¸ì¤Ë +ÀßÄꤹ¤ë
    DefaultType MIME-type text/plain svdhC
    ¥µ¡¼¥Ð¤¬¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò·èÄê¤Ç¤­¤Ê¤¤¤È¤­¤Ë +Á÷¤é¤ì¤ë MIME ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×
    DeflateBufferSize value 8096 svE
    zlib ¤¬°ìÅ٤˰µ½Ì¤¹¤ë²ô¤ÎÂ礭¤µ
    DeflateCompressionLevel valuesvE
    ½ÐÎϤËÂФ·¤Æ¹Ô¤Ê¤¦°µ½Ì¤ÎÄøÅÙ
    DeflateFilterNote [type] notenamesvE
    ¥í¥®¥ó¥°ÍѤ˰µ½ÌÈæ¤ò¥á¥â¤ËÄɲÃ
    DeflateMemLevel value 9 svE
    zlib ¤¬°µ½Ì¤Ë»È¤¦¥á¥â¥ê¤Î¥ì¥Ù¥ë¤ò»ØÄê
    DeflateWindowSize value 15 svE
    Zlib ¤Î°µ½ÌÍÑ¥¦¥£¥ó¥É¥¦¤ÎÂ礭¤µ
    Deny from all|host|env=env-variable +[host|env=env-variable] ...dhB
    ¥µ¡¼¥Ð¤¬¥¢¥¯¥»¥¹¤òµñÈݤ¹¤ë¥Û¥¹¥È¤òÀ©¸æ¤¹¤ë
    <Directory directory-path> +... </Directory>svC
    »ØÄê¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤È¤Î¤ß¤Ë +ŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    DirectoryIndex + local-url [local-url] ... index.html svdhB
    ¥¯¥é¥¤¥¢¥ó¥È¤¬¥Ç¥£¥ì¥¯¥È¥ê¤ò¥ê¥¯¥¨¥¹¥È¤·¤¿¤È¤­¤ËÄ´¤Ù¤ë +¥ê¥½¡¼¥¹¤Î¥ê¥¹¥È
    <DirectoryMatch regex> +... </DirectoryMatch>svC
    Àµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È +¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤È¤Î¤ß¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    DirectorySlash On|Off On svdhB
    ¥Ñ¥¹ËöÈø¤Î¥¹¥é¥Ã¥·¥å¤Ç¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤«¤É¤¦¤«¤Î¥ª¥ó¥ª¥Õ¤ò¥È¥°¥ë¤µ¤»¤ë
    DocumentRoot directory-path /usr/local/apache/h +svC
    ¥¦¥§¥Ö¤«¤é¸«¤¨¤ë¥á¥¤¥ó¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼¤Ë¤Ê¤ë +¥Ç¥£¥ì¥¯¥È¥ê
    DumpIOInput On|Off Off sE
    ¥¨¥é¡¼¥í¥°¤Ë¤¹¤Ù¤Æ¤ÎÆþÎϥǡ¼¥¿¤ò¥À¥ó¥×
    DumpIOOutput On|Off Off sE
    ¥¨¥é¡¼¥í¥°¤Ë¤¹¤Ù¤Æ¤Î½ÐÎϥǡ¼¥¿¤ò¥À¥ó¥×
    EnableExceptionHook On|Off Off sM
    ¥¯¥é¥Ã¥·¥å¤Î¸å¤ËÎã³°¥Ï¥ó¥É¥é¤ò¼Â¹Ô¤¹¤ë¥Õ¥Ã¥¯¤òÍ­¸ú¤Ë¤¹¤ë
    EnableMMAP On|Off On svdhC
    ÇÛÁ÷Ãæ¤Ë¥Õ¥¡¥¤¥ë¤òÆɤ߹þ¤à¤¿¤á¤Ë¥á¥â¥ê¥Þ¥Ã¥Ô¥ó¥°¤ò +»È¤¦¤«¤É¤¦¤«
    EnableSendfile On|Off On svdhC
    ¥Õ¥¡¥¤¥ë¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ø¤ÎÇÛÁ÷»þ¤Ë¥«¡¼¥Í¥ë¤Î sendfile ¥µ¥Ý¡¼¥È¤ò +»È¤¦¤«¤É¤¦¤«
    ErrorDocument error-code documentsvdhC
    ¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤Ë¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¤â¤Î
    ErrorLog file-path|syslog[:facility] logs/error_log (Uni +svC
    ¥µ¡¼¥Ð¤¬¥¨¥é¡¼¤ò¥í¥°¼ý½¸¤¹¤ë¾ì½ê
    ExamplesvdhX
    Demonstration directive to illustrate the Apache module +API
    ExpiresActive On|OffsvdhE
    Expires ¥Ø¥Ã¥À¤ÎÀ¸À®¤òÍ­¸ú¤Ë¤¹¤ë
    ExpiresByType MIME-type +<code>secondssvdhE
    MIME ¥¿¥¤¥×¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤ë Expires ¥Ø¥Ã¥À¤ÎÃÍ
    ExpiresDefault <code>secondssvdhE
    ´ü¸ÂÀÚ¤ì´üÆü¤ò·×»»¤¹¤ë¥Ç¥Õ¥©¥ë¥È¥¢¥ë¥´¥ê¥º¥à
    ExtendedStatus On|Off Off sB
    ³Æ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ³ÈÄ¥¥¹¥Æ¡¼¥¿¥¹¾ðÊó¤òÊݸ¤¹¤ë
    ExtFilterDefine filtername parameterssE
    ³°Éô¥Õ¥£¥ë¥¿¤òÄêµÁ
    ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
    mod_ext_filter ¤Î¥ª¥×¥·¥ç¥ó¤òÀßÄê
    FileETag component ... INode MTime Size svdhC
    ETag HTTP ±þÅú¥Ø¥Ã¥À¤òºîÀ®¤¹¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤ë +¥Õ¥¡¥¤¥ë¤Î°À­
    <Files filename> ... </Files>svdhC
    ¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë̾¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    <FilesMatch regex> ... </FilesMatch>svdhC
    Àµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë̾¤ËŬÍѤµ¤ì¤ë +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    FilterChain [+=-@!]filter-name ...svdhX
    Configure the filter chain
    FilterDeclare filter-name [type]svdhX
    Declare a smart filter
    FilterProtocol filter-name [provider-name] + proto-flagssvdhX
    Deal with correct HTTP protocol handling
    FilterProvider filter-name provider-name + [req|resp|env]=dispatch matchsvdhX
    Register a content filter
    FilterTrace filter-name levelsvdX
    Get debug/diagnostic information from + mod_filter
    ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
    Í×µá¤Ë¹ç¤¦Ã±ÆȤΥɥ­¥å¥á¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¤È¤­¤Ë¹Ô¤Ê¤¦¤³¤È¤ò»ØÄê +
    ForceType MIME-type|NonedhC
    ¤¹¤Ù¤Æ¤Î¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¤¬»ØÄê¤Î MIME ¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤Ç +Á÷¤é¤ì¤ë¤è¤¦¤Ë¤¹¤ë
    ForensicLog filename|pipesvE
    Forensic ¥í¥°¤Î¥Õ¥¡¥¤¥ë̾¤òÀßÄꤹ¤ë
    Group unix-group #-1 sM
    ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤Ë½ê°¤¹¤ë¥°¥ë¡¼¥×
    Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]svdhE
    HTTP ±þÅú¥Ø¥Ã¥À¤ÎÀßÄê
    HeaderName filenamesvdhB
    +¥¤¥ó¥Ç¥Ã¥¯¥¹°ìÍ÷¤ÎÀèƬ¤ËÁÞÆþ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°
    HostnameLookups On|Off|Double Off svdC
    ¥¯¥é¥¤¥¢¥ó¥È¤Î IP ¥¢¥É¥ì¥¹¤Î DNS ¥ë¥Ã¥¯¥¢¥Ã¥×¤ò +Í­¸ú¤Ë¤¹¤ë
    IdentityCheck On|Off Off svdE
    Enables logging of the RFC 1413 identity of the remote +user
    IdentityCheckTimeout seconds 30 svdE
    Determines the timeout duration for ident requests
    <IfDefine [!]parameter-name> ... + </IfDefine>svdhC
    µ¯Æ°»þ¤Ë¥Æ¥¹¥È¤¬¿¿¤Ç¤¢¤ë¤È¤­¤Î¤ß¤Ë½èÍý¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +°Ï¤à
    <IfModule [!]module-file|module-identifier> ... + </IfModule>svdhC
    ¥â¥¸¥å¡¼¥ë¤Î¸ºß¤¹¤ë¤«¤·¤Ê¤¤¤«¤Ë±þ¤¸¤Æ½èÍý¤µ¤ì¤ë +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à
    <IfVersion [[!]operator] version> ... +</IfVersion>svdhE
    ¥Ð¡¼¥¸¥ç¥ó°Í¸¤ÎÀßÄê¤òÆþ¤ì¤ë
    ImapBase map|referer|URL http://servername/ svdhB
    Default base for imagemap files
    ImapDefault error|nocontent|map|referer|URL nocontent svdhB
    Default action when an imagemap is called with coordinates +that are not explicitly mapped
    ImapMenu none|formatted|semiformatted|unformattedsvdhB
    Action if no coordinates are given when calling +an imagemap
    Include file-path|directory-pathsvdC
    ¥µ¡¼¥ÐÀßÄê¥Õ¥¡¥¤¥ëÃ椫¤é¾¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ò¼è¤ê¹þ¤à
    IndexIgnore file [file] ...svdhB
    ¥Ç¥£¥ì¥¯¥È¥ê°ìÍ÷¤ò¹Ô¤Ê¤¦ºÝ¤Ë̵»ë¤¹¤Ù¤­ +¥Õ¥¡¥¤¥ë¥ê¥¹¥È¤ËÄɲÃ
    IndexOptions [+|-]option [[+|-]option] ...svdhB
    ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÎÍÍ¡¹¤ÊÀßÄê¹àÌÜ +
    IndexOrderDefault Ascending|Descending +Name|Date|Size|Description Ascending Name svdhB
    +¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤Îɸ½à¤Î½çÈÖÉÕ¤±¤òÀßÄê
    IndexStyleSheet url-pathsvdhB
    ¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ë CSS ¥¹¥¿¥¤¥ë¥·¡¼¥È¤òÄɲ乤ë
    ISAPIAppendLogToErrors on|off off svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the error log
    ISAPIAppendLogToQuery on|off on svdhB
    Record HSE_APPEND_LOG_PARAMETER requests from +ISAPI extensions to the query field
    ISAPICacheFile file-path [file-path] +...svB
    ISAPI .dll files to be loaded at startup
    ISAPIFakeAsync on|off off svdhB
    Fake asynchronous support for ISAPI callbacks
    ISAPILogNotSupported on|off off svdhB
    Log unsupported feature requests from ISAPI +extensions
    ISAPIReadAheadBuffer size 49152 svdhB
    Size of the Read Ahead Buffer sent to ISAPI +extensions
    KeepAlive On|Off On svC
    HTTP ¤Î»ý³Ū¤ÊÀܳ¤òÍ­¸ú¤Ë¤¹¤ë
    KeepAliveTimeout seconds 5 svC
    »ý³Ū¤ÊÀܳ¤Ç¼¡¤Î¥ê¥¯¥¨¥¹¥È¤¬Íè¤ë¤Þ¤Ç¥µ¡¼¥Ð¤¬ÂԤĻþ´Ö
    LanguagePriority MIME-lang [MIME-lang] +...svdhB
    ¥¯¥é¥¤¥¢¥ó¥È¤¬Í¥ÀèÅÙ¤ò¼¨¤µ¤Ê¤«¤Ã¤¿¤È¤­¤Î¸À¸ì¤Î variant ¤ÎÍ¥ÀèÅÙ¤ò +»ØÄê
    LDAPCacheEntries number 1024 sE
    Maximum number of entries in the primary LDAP cache
    LDAPCacheTTL seconds 600 sE
    Time that cached items remain valid
    LDAPConnectionTimeout secondssE
    Specifies the socket connection timeout in seconds
    LDAPOpCacheEntries number 1024 sE
    Number of entries used to cache LDAP compare +operations
    LDAPOpCacheTTL seconds 600 sE
    Time that entries in the operation cache remain +valid
    LDAPSharedCacheFile directory-path/filenamesE
    Sets the shared memory cache file
    LDAPSharedCacheSize bytes 102400 sE
    Size in bytes of the shared-memory cache
    LDAPTrustedClientCert type directory-path/filename/nickname [password]svdhE
    Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    LDAPTrustedGlobalCert type directory-path/filename [password]sE
    Sets the file or database containing global trusted +Certificate Authority or global client certificates
    LDAPTrustedMode typesvdhE
    Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    LDAPVerifyServerCert On|Off On sE
    Force server certificate verification
    <Limit method [method] ... > ... + </Limit>svdhC
    °Ï¤¤¤ÎÃæ¤Ë¤¢¤ë¥¢¥¯¥»¥¹À©¸æ¤ÎŬÍѤòÆÃÄê¤Î HTTP ¥á¥½¥Ã¥É¤Î¤ß¤Ë +À©¸Â¤¹¤ë
    <LimitExcept method [method] ... > ... + </LimitExcept>svdhC
    »ØÄꤵ¤ì¤¿¤â¤Î°Ê³°¤Î HTTP ¥á¥½¥Ã¥É¤Ë¥¢¥¯¥»¥¹À©¸æ¤ò +À©¸Â¤¹¤ë
    LimitInternalRecursion number [number] 10 svC
    ÆâÉô¥ê¥À¥¤¥ì¥¯¥È¤ÈÆþ¤ì»Ò¤Ë¤Ê¤Ã¤¿¥µ¥Ö¥ê¥¯¥¨¥¹¥È¤ÎºÇÂç¿ô¤ò·èÄꤹ¤ë
    LimitRequestBody bytes 0 svdhC
    ¥¯¥é¥¤¥¢¥ó¥È¤«¤éÁ÷¤é¤ì¤ë HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤Î +ÁíÎ̤òÀ©¸Â¤¹¤ë
    LimitRequestFields number 100 sC
    ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤Î¿ô¤ò +À©¸Â¤¹¤ë
    LimitRequestFieldsize bytessC
    ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤Î +¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    LimitRequestLine bytes 8190 sC
    ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î HTTP ¥ê¥¯¥¨¥¹¥È¹Ô¤Î¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    LimitXMLRequestBody bytes 1000000 svdhC
    XML ·Á¼°¤Î¥ê¥¯¥¨¥¹¥È¤Î¥Ü¥Ç¥£¤Î¥µ¥¤¥º¤òÀ©¸Â¤¹¤ë
    Listen [IP-address:]portnumbersM
    ¥µ¡¼¥Ð¤¬ listen ¤¹¤ëIP ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥ÈÈÖ¹æ
    ListenBacklog backlogsM
    ÊÝα¾õÂ֤Υ³¥Í¥¯¥·¥ç¥ó¤Î¥­¥å¡¼¤ÎºÇÂçĹ
    LoadFile filename [filename] ...sE
    »ØÄꤵ¤ì¤¿¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ä¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤¹¤ë
    LoadModule module filenamesE
    ¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤ä¥é¥¤¥Ö¥é¥ê¤ò¥ê¥ó¥¯¤·¡¢»ÈÍѥ⥸¥å¡¼¥ë¤Î +¥ê¥¹¥È¤ËÄɲ乤ë
    <Location + URL-path|URL> ... </Location>svC
    °Ï¤ó¤À¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Þ¥Ã¥Á¤¹¤ë URL ¤Î¤ß¤ËŬÍÑ
    <LocationMatch + regex> ... </LocationMatch>svC
    °Ï¤ó¤À¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÀµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ë URL ¤Î¤ß¤Ë +ŬÍÑ
    LockFile filename logs/accept.lock sM
    ¼õÉÕ¤òľÎ󲽤¹¤ë¤¿¤á¤Î¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    LogFormat format|nickname +[nickname] "%h %l %u %t \"%r\" +svB
    ¥í¥°¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤ¹¤ë½ñ¼°¤òÀßÄꤹ¤ë
    LogLevel level warn svC
    ErrorLog ¤Î¾éĹÀ­¤òÀ©¸æ¤¹¤ë
    MaxClients numbersM
    ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤¿¤á¤ËºîÀ®¤µ¤ì¤ë +»Ò¥×¥í¥»¥¹¤ÎºÇÂç¸Ä¿ô
    MaxKeepAliveRequests number 100 svC
    »ý³Ū¤ÊÀܳ¾å¤Çµö²Ä¤µ¤ì¤ë¥ê¥¯¥¨¥¹¥È¤Î¿ô
    MaxMemFree KBytes 0 sM
    free() ¤¬¸Æ¤Ð¤ì¤Ê¤¤¸Â¤ê¡¢ +¼ç¥á¥â¥ê¥¢¥í¥±¡¼¥¿¤¬ÊÝ»ý¤·Â³¤±¤é¤ì¤ë¥á¥â¥ê¤ÎºÇÂçÎÌ
    MaxRequestsPerChild number 10000 sM
    ¸Ä¡¹¤Î»Ò¥µ¡¼¥Ð¤¬²ÔƯÃæ¤Ë°·¤¦¥ê¥¯¥¨¥¹¥È¿ô¤Î¾å¸Â
    MaxRequestsPerThread number 0 sM
    Limit on the number of requests that an individual thread +will handle during its life
    MaxSpareServers number 10 sM
    ¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤ÎºÇÂç¸Ä¿ô
    MaxSpareThreads numbersM
    ¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤ÎºÇÂç¿ô
    MaxThreads number 2048 sM
    Set the maximum number of worker threads
    MaxThreadsPerChild number 64 sM
    Maximum number of threads per child process
    MCacheMaxObjectCount value 1009 sE
    ¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ÎºÇÂç¿ô
    MCacheMaxObjectSize bytes 10000 sE
    ¥­¥ã¥Ã¥·¥å¤ËÊݴɤǤ­¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇÂ祵¥¤¥º (¥Ð¥¤¥È)
    MCacheMaxStreamingBuffer size_in_bytes of 100000 ¤« MCacheM +sE
    ¥¹¥È¥ê¡¼¥à¤µ¤ì¤Æ¤¤¤ë±þÅú¤ò¥­¥ã¥Ã¥·¥åÉÔǽ¤È·èÄꤹ¤ë¤Þ¤Ç¤Ë +¥á¥â¥ê¤Ë¥Ð¥Ã¥Õ¥¡¤¹¤ëºÇÂçÎÌ
    MCacheMinObjectSize bytes 0 sE
    ¥­¥ã¥Ã¥·¥å¤ËÊݴɤµ¤ì¤ë¥É¥­¥å¥á¥ó¥È¤ÎºÇ¾®¥µ¥¤¥º (¥Ð¥¤¥È)
    MCacheRemovalAlgorithm LRU|GDSF GDSF sE
    ¥­¥ã¥Ã¥·¥å¤«¤éºï½ü¤¹¤ë¥É¥­¥å¥á¥ó¥È¤òÁª¤Ö¤¿¤á¤Î¥¢¥ë¥´¥ê¥º¥à
    MCacheSize KBytes 100 sE
    ¥­¥ã¥Ã¥·¥å¤Ë»È¤ï¤ì¤ë¥á¥â¥ê¤ÎºÇÂçÎ̤ò¥Ð¥¤¥Èñ°Ì¤Ç»ØÄê
    MetaDir directory .web svdhE
    Name of the directory to find CERN-style meta information +files
    MetaFiles on|off off svdhE
    Activates CERN meta-file processing
    MetaSuffix suffix .meta svdhE
    File name suffix for the file containg CERN-style +meta information
    MimeMagicFile file-pathsvE
    Enable MIME-type determination based on file contents +using the specified magic file
    MinSpareServers number 5 sM
    ¥¢¥¤¥É¥ë¤Ê»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤ÎºÇ¾®¸Ä¿ô
    MinSpareThreads numbersM
    ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤³¤È¤Î¤Ç¤­¤ë +¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¿ô¤ÎºÇ¾®¿ô
    MMapFile file-path [file-path] ...sX
    Map a list of files into memory at startup time
    ModMimeUsePathInfo On|Off Off d
    path_info ¥³¥ó¥Ý¡¼¥Í¥ó¥È¤ò¥Õ¥¡¥¤¥ë̾¤Î°ìÉô¤È¤·¤Æ°·¤¦¤è¤¦¤Ë +mod_mime ¤ËÄÌÃΤ¹¤ë
    MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] NegotiatedOnly svdh
    MultiViews ¤Ç¤Î¥Þ¥Ã¥Á¥ó¥°¤Î¸¡º÷¤Ë´Þ¤Þ¤»¤ë +¥Õ¥¡¥¤¥ë¤Î¥¿¥¤¥×¤ò»ØÄꤹ¤ë
    NameVirtualHost addr[:port]sC
    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¤¿¤á¤Î IP ¥¢¥É¥ì¥¹¤ò»ØÄê
    NoProxy host [host] ...svE
    ľÀÜÀܳ¤¹¤ë ¥Û¥¹¥È¡¢¥É¥á¥¤¥ó¡¢¥Í¥Ã¥È¥ï¡¼¥¯
    NumServers number 2 sM
    Total number of children alive at the same time
    NWSSLTrustedCerts filename [filename] ...sB
    List of additional client certificates
    NWSSLUpgradeable [IP-address:]portnumbersB
    Allows a connection to be upgraded to an SSL connection upon request
    Options + [+|-]option [[+|-]option] ... All svdhC
    ¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ»ÈÍѲÄǽ¤Êµ¡Ç½¤òÀßÄꤹ¤ë
    Order ordering Deny,Allow dhB
    ¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹²Äǽ¤Ê¾õÂ֤ȡ¢Allow ¤È +Deny ¤¬É¾²Á¤µ¤ì¤ë½çÈÖ¤òÀ©¸æ¤¹¤ë
    PassEnv env-variable [env-variable] +...svdhB
    ¥·¥§¥ë¤«¤é¤Î´Ä¶­ÊÑ¿ô¤òÅϤ¹
    PidFile filename logs/httpd.pid M
    ¥Ç¡¼¥â¥ó¤Î¥×¥í¥»¥¹ ID +¤ò¥µ¡¼¥Ð¤¬µ­Ï¿¤¹¤ë¤¿¤á¤Î¥Õ¥¡¥¤¥ë
    ProtocolEcho On|OffsvX
    ¥¨¥³¡¼¥µ¡¼¥Ð¤ÎÍ­¸ú̵¸ú¤òÀßÄꤷ¤Þ¤¹¡£
    <Proxy wildcard-url> ...</Proxy>svE
    ¥×¥í¥­¥·¤µ¤ì¤ë¥ê¥½¡¼¥¹¤ËŬÍѤµ¤ì¤ë¥³¥ó¥Æ¥Ê
    ProxyBadHeader IsError|Ignore|StartBody IsError svE
    ±þÅú¤Ë¤ª¤«¤·¤Ê¥Ø¥Ã¥À¤¬¤¢¤ë¾ì¹ç¤Î°·¤¤Êý¤ò·è¤á¤ë
    ProxyBlock *|word|host|domain +[word|host|domain] ...svE
    ¥×¥í¥­¥·Àܳ¤ò¶Ø»ß¤¹¤ë¸ì¶ç¡¢¥Û¥¹¥È̾¡¢¥É¥á¥¤¥ó¤ò»ØÄꤹ¤ë
    ProxyDomain DomainsvE
    ¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¥Ç¥Õ¥©¥ë¥È¤Î¥É¥á¥¤¥ó̾
    ProxyErrorOverride On|Off Off svE
    ¥×¥í¥­¥·¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥Ä¤Î¥¨¥é¡¼¥Ú¡¼¥¸¤ò¾å½ñ¤­¤¹¤ë
    ProxyIOBufferSize bytes 8192 svE
    ÆâÉô¥Ç¡¼¥¿¥¹¥ë¡¼¥×¥Ã¥È¥Ð¥Ã¥Õ¥¡¤Î¥µ¥¤¥º¤ò·èÄꤹ¤ë
    <ProxyMatch regex> ...</ProxyMatch>svE
    Àµµ¬É½¸½¤Ç¤Î¥Þ¥Ã¥Á¤Ë¤è¤ë¥×¥í¥­¥·¥ê¥½¡¼¥¹ÍѤΥǥ£¥ì¥¯¥Æ¥£¥Ö¥³¥ó¥Æ¥Ê
    ProxyMaxForwards number 10 svE
    ¥ê¥¯¥¨¥¹¥È¤¬¥Õ¥©¥ï¡¼¥É¤µ¤ì¤ë¥×¥í¥­¥·¤ÎºÇÂç¿ô
    ProxyPass [path] !|url [key=value key=value ...]]svdE
    ¥ê¥â¡¼¥È¥µ¡¼¥Ð¤ò¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î URL ¶õ´Ö¤Ë¥Þ¥Ã¥×¤¹¤ë
    ProxyPassReverse [path] urlsvdE
    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤µ¤ì¤¿¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤¿ HTTP ±þÅú¥Ø¥Ã¥À¤Î +URL ¤òÄ´À°¤¹¤ë
    ProxyPassReverseCookieDomain internal-domain public-domainsvdE
    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¥µ¡¼¥Ð¤«¤é¤Î Set-Cookie ¥Ø¥Ã¥À¤Î Domain ʸ»úÎó¤ò +Ä´À°¤¹¤ë
    ProxyPassReverseCookiePath internal-path public-pathsvdE
    Reverse ¥×¥í¥­¥·¥µ¡¼¥Ð¤«¤é¤Î Set-Cookie ¥Ø¥Ã¥À¤Î Path ʸ»úÎó¤ò +Ä´À°¤¹¤ë
    ProxyPreserveHost On|Off Off svE
    ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤Ë¡¢¼õ¤±ÉÕ¤±¤¿ Host HTTP ¥Ø¥Ã¥À¤ò»È¤¦
    ProxyReceiveBufferSize bytes 0 svE
    ¥×¥í¥­¥·¤µ¤ì¤ë HTTP ¤È FTP Àܳ¤Î¤¿¤á¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º
    ProxyRemote match remote-serversvE
    ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¦»þ¤Ë»È¤ï¤ì¤ë¥ê¥â¡¼¥È¥×¥í¥­¥·¤ò»ØÄꤹ¤ë
    ProxyRemoteMatch regex remote-serversvE
    Àµµ¬É½¸½¤Ç¤Î¥Þ¥Ã¥Á¤Ë¤è¤ë¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¥ê¥â¡¼¥È¥×¥í¥­¥·¤Î»ØÄê
    ProxyRequests On|Off Off svE
    ¥Õ¥©¥ï¡¼¥É (ɸ½à¤Î) ¥×¥í¥­¥·¥ê¥¯¥¨¥¹¥È¤òÍ­¸ú¤Ë¤¹¤ë
    ProxyTimeout seconds 300 svE
    ¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥¿¥¤¥à¥¢¥¦¥È
    ProxyVia On|Off|Full|Block Off svE
    ¥×¥í¥­¥·¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î Via HTTP ±þÅú¥Ø¥Ã¥À +¤Ë¤è¤êÄ󶡤µ¤ì¤ë¾ðÊó
    ReadmeName filenamesvdhB
    ¥¤¥ó¥Ç¥Ã¥¯¥¹°ìÍ÷¤ÎºÇ¸å¤ËÁÞÆþ¤µ¤ì¤ë¥Õ¥¡¥¤¥ë¤Î̾Á°
    Redirect [status] URL-path +URLsvdhB
    ¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤ò +Á÷¤ë
    RedirectMatch [status] regex +URLsvdhB
    ¸½ºß¤Î URL ¤Ø¤ÎÀµµ¬É½¸½¤Î¥Þ¥Ã¥Á¤Ë¤è¤ê +³°Éô¤Ø¤Î¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    RedirectPermanent URL-path URLsvdhB
    ¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î±Êµ×Ū¤Ê +¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    RedirectTemp URL-path URLsvdhB
    ¥¯¥é¥¤¥¢¥ó¥È¤¬°ã¤¦ URL ¤ò¼èÆÀ¤¹¤ë¤è¤¦¤Ë³°Éô¤Ø¤Î°ì»þŪ¤Ê +¥ê¥À¥¤¥ì¥¯¥È¤òÁ÷¤ë
    RemoveCharset extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Îʸ»ú¥»¥Ã¥È +¤ò²ò½ü¤¹¤ë
    RemoveEncoding extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Î¥³¥ó¥Æ¥ó¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥° +¤ò²ò½ü¤¹¤ë
    RemoveHandler extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤¹¤Ù¤Æ¤Î¥Ï¥ó¥É¥é¤ò +²ò½ü¤¹¤ë
    RemoveInputFilter extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿ÆþÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤¹¤ë
    RemoveLanguage extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿¸À¸ì¤ò²ò½ü¤¹¤ë
    RemoveOutputFilter extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë³ÈÄ¥»Ò¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤¿½ÐÎÏ¥Õ¥£¥ë¥¿¤ò²ò½ü¤¹¤ë
    RemoveType extension [extension] +...vdh
    ¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥³¥ó¥Æ¥ó¥È¥¿¥¤¥×¤ò +²ò½ü¤¹¤ë
    RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]svdhE
    HTTP ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤ÎÀßÄê
    Require entity-name [entity-name] ...dhC
    ¤É¤Îǧ¾ÚºÑ¤ß¥æ¡¼¥¶¤¬¥ê¥½¡¼¥¹¤ò¥¢¥¯¥»¥¹¤Ç¤­¤ë¤«¤òÁªÂò¤¹¤ë
    RewriteBase URL-pathdhE
    Sets the base URL for per-directory rewrites
    RewriteCond + TestString CondPatternsvdhE
    Defines a condition under which rewriting will take place +
    RewriteEngine on|off off svdhE
    Enables or disables runtime rewriting engine
    RewriteLock file-pathsE
    Sets the name of the lock file used for RewriteMap +synchronization
    RewriteLog file-pathsvE
    Sets the name of the file used for logging rewrite engine +processing
    RewriteLogLevel Level 0 svE
    Sets the verbosity of the log file used by the rewrite +engine
    RewriteMap MapName MapType:MapSource +svE
    Defines a mapping function for key-lookup
    RewriteOptions OptionssvdhE
    Sets some special options for the rewrite engine
    RewriteRule + Pattern SubstitutionsvdhE
    Defines rules for the rewriting engine
    RLimitCPU seconds|max [seconds|max]svdhC
    Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤Î CPU ¾ÃÈñÎ̤ò +À©¸Â¤¹¤ë
    RLimitMEM bytes|max [bytes|max]svdhC
    Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤Î¥á¥â¥ê¾ÃÈñÎ̤ò +À©¸Â¤¹¤ë
    RLimitNPROC number|max [number|max]svdhC
    Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤éµ¯Æ°¤µ¤ì¤¿¥×¥í¥»¥¹¤¬µ¯Æ°¤¹¤ë¥×¥í¥»¥¹¤Î +¿ô¤òÀ©¸Â¤¹¤ë
    Satisfy Any|All All dhC
    ¥Û¥¹¥È¥ì¥Ù¥ë¤Î¥¢¥¯¥»¥¹À©¸æ¤È¥æ¡¼¥¶Ç§¾Ú¤È¤ÎÁê¸ßºîÍѤò»ØÄê
    ScoreBoardFile file-path logs/apache_status sM
    »Ò¥×¥í¥»¥¹¤ÈÏ¢·È¤¹¤ë¤¿¤á¤Î¥Ç¡¼¥¿¤òÊݸ¤¹¤ë +¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    Script method cgi-scriptsvdB
    ÆÃÄê¤Î¥ê¥¯¥¨¥¹¥È¥á¥½¥Ã¥É¤ËÂФ·¤Æ CGI ¥¹¥¯¥ê¥×¥È¤ò +¼Â¹Ô¤¹¤ë¤è¤¦¤ËÀßÄê
    ScriptAlias URL-path +file-path|directory-pathsvB
    URL ¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤إޥåפ·¡¢¥Þ¥Ã¥×Àè¤ò +CGI ¥¹¥¯¥ê¥×¥È¤Ë»ØÄê
    ScriptAliasMatch regex +file-path|directory-pathsvB
    URL ¤òÀµµ¬É½¸½¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ÌÃ֤إޥåפ·¡¢¥Þ¥Ã¥×Àè¤ò +CGI ¥¹¥¯¥ê¥×¥È¤Ë»ØÄê
    ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
    CGI ¥¹¥¯¥ê¥×¥È¤Î¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Î°ÌÃÖ¤òÄ´¤Ù¤ë¤¿¤á¤Î¼êË¡
    ScriptLog file-pathsvB
    CGI ¥¹¥¯¥ê¥×¥È¤Î¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤Î¾ì½ê
    ScriptLogBuffer bytes 1024 svB
    ¥¹¥¯¥ê¥×¥È¥í¥°¤Ëµ­Ï¿¤µ¤ì¤ë PUT ¤ä POST ¥ê¥¯¥¨¥¹¥È¤ÎÆâÍƤξå¸Â
    ScriptLogLength bytes 10385760 svB
    CGI ¥¹¥¯¥ê¥×¥È¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤Î¾å¸Â
    ScriptSock file-path logs/cgisock svB
    CGI ¥Ç¡¼¥â¥ó¤È¤ÎÄÌ¿®¤Ë»È¤ï¤ì¤ë¥½¥±¥Ã¥È¤Î̾Á°
    SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]sB
    Enables SSL encryption for the specified port
    SendBufferSize bytes 0 sM
    TCP ¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º
    ServerAdmin email-address|URLsvC
    ¥µ¡¼¥Ð¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ë´Þ¤á¤ëÅŻҥ᡼¥ë¤Î +¥¢¥É¥ì¥¹
    ServerAlias hostname [hostname] ...vC
    ¥ê¥¯¥¨¥¹¥È¤ò̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥Þ¥Ã¥Á¤µ¤»¤Æ¤¤¤ë¤È¤­¤Ë +»ÈÍѤµ¤ì¤ë¥Û¥¹¥È¤ÎÊÌ̾
    ServerLimit numbersM
    ÀßÄê²Äǽ¤Ê¥µ¡¼¥Ð¥×¥í¥»¥¹¿ô¤Î¾å¸Â
    ServerName fully-qualified-domain-name[:port]svC
    ¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤ò¼¨¤¹¤È¤­¤Ë»È¤¦¥Û¥¹¥È̾¤È¥Ý¡¼¥È
    ServerPath URL-pathvC
    Èó¸ß´¹¤Î¥Ö¥é¥¦¥¶¤¬Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¥¢¥¯¥»¥¹¤·¤¿¤È¤­¤Î +¤¿¤á¤Î¸ß´¹ÍÑ URL ¥Ñ¥¹Ì¾
    ServerRoot directory-path /usr/local/apache sC
    ¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤¿¥µ¡¼¥Ð¤Î¥Ù¡¼¥¹¥Ç¥£¥ì¥¯¥È¥ê
    ServerSignature On|Off|EMail Off svdhC
    ¥µ¡¼¥Ð¤¬À¸À®¤¹¤ë¥É¥­¥å¥á¥ó¥È¤Î¥Õ¥Ã¥¿¤òÀßÄê
    ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
    Server HTTP ±þÅú¥Ø¥Ã¥À¤òÀßÄꤹ¤ë
    SetEnv env-variable valuesvdhB
    ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    ¥ê¥¯¥¨¥¹¥È¤Î°À­¤Ë´ð¤Å¤¤¤Æ´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë +
    SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    ¥ê¥¯¥¨¥¹¥È¤Î°À­¤Ë´ð¤Å¤¤¤ÆÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë´Ä¶­ÊÑ¿ô¤òÀßÄꤹ¤ë
    SetHandler handler-name|NonesvdhC
    ¥Þ¥Ã¥Á¤¹¤ë¥Õ¥¡¥¤¥ë¤¬¥Ï¥ó¥É¥é¤Ç½èÍý¤µ¤ì¤ë¤è¤¦¤Ë¤¹¤ë
    SetInputFilter filter[;filter...]svdhC
    ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ä POST ¤ÎÆþÎϤò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÀßÄꤹ¤ë
    SetOutputFilter filter[;filter...]svdhC
    ¥µ¡¼¥Ð¤Î±þÅú¤ò½èÍý¤¹¤ë¥Õ¥£¥ë¥¿¤òÀßÄꤹ¤ë
    SSIEndTag tag "-->" svB
    include Í×ÁǤò½ªÎ»¤µ¤»¤ëʸ»úÎó
    SSIErrorMsg message "[an error occurred +svdhB
    SSI ¤Î¥¨¥é¡¼¤¬¤¢¤Ã¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤ë¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸
    SSIStartTag tag "<!--#" svB
    include Í×ÁǤò³«»Ï¤¹¤ëʸ»úÎó
    SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +svdhB
    ÆüÉÕ¤±¤ò¸½¤¹Ê¸»úÎó¤Î½ñ¼°¤òÀßÄꤹ¤ë
    SSIUndefinedEcho string "(none)" svdhB
    ̤ÄêµÁ¤ÎÊÑ¿ô¤¬ echo ¤µ¤ì¤¿¤È¤­¤Ëɽ¼¨¤µ¤ì¤ëʸ»úÎó
    SSLCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Client Auth
    SSLCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Client Auth
    SSLCADNRequestFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    SSLCADNRequestPath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    SSLCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Client Auth
    SSLCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Client Auth
    SSLCertificateChainFile file-pathsvE
    File of PEM-encoded Server CA Certificates
    SSLCertificateFile file-pathsvE
    Server PEM-encoded X.509 Certificate file
    SSLCertificateKeyFile file-pathsvE
    Server PEM-encoded Private Key file
    SSLCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +handshake
    SSLCryptoDevice engine builtin sE
    Enable use of a cryptographic hardware accelerator
    SSLEngine on|off|optional off svE
    SSL Engine Operation Switch
    SSLHonorCiperOrder flagsvE
    Option to prefer the server's cipher preference order
    SSLMutex type none sE
    Semaphore for internal mutual exclusion of +operations
    SSLOptions [+|-]option ...svdhE
    Configure various SSL engine run-time options
    SSLPassPhraseDialog type builtin sE
    Type of pass phrase dialog for encrypted private +keys
    SSLProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors
    SSLProxyCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    SSLProxyCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Remote Server Auth
    SSLProxyCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +proxy handshake
    SSLProxyEngine on|off off svE
    SSL Proxy Engine Operation Switch
    SSLProxyMachineCertificateFile filenamesE
    File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyMachineCertificatePath directorysE
    Directory of PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors for proxy usage
    SSLProxyVerify level none svdhE
    Type of remote server Certificate verification
    SSLProxyVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Remote Server +Certificate verification
    SSLRandomSeed context source +[bytes]sE
    Pseudo Random Number Generator (PRNG) seeding +source
    SSLRequire expressiondhE
    Allow access only when an arbitrarily complex +boolean expression is true
    SSLRequireSSLdhE
    Deny access when SSL is not used for the +HTTP request
    SSLSessionCache type none sE
    Type of the global/inter-process SSL Session +Cache
    SSLSessionCacheTimeout seconds 300 svE
    Number of seconds before an SSL session expires +in the Session Cache
    SSLUserName varnamesdhE
    Variable name to determine user name
    SSLVerifyClient level none svdhE
    Type of Client Certificate verification
    SSLVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Client +Certificate verification
    StartServers numbersM
    µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë»Ò¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î¿ô
    StartThreads numbersM
    µ¯Æ°»þ¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¤Î¿ô
    SuexecUserGroup User Groupsv
    CGI ¥×¥í¥°¥é¥à¤Î¥æ¡¼¥¶¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¡¢¥°¥ë¡¼¥×¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó
    ThreadLimit numbersM
    ÀßÄê²Äǽ¤Ê»Ò¥×¥í¥»¥¹Ëè¤Î¥¹¥ì¥Ã¥É¿ô¤Î¾å¸Â¤ò +ÀßÄꤷ¤Þ¤¹
    ThreadsPerChild numbersM
    »Ò¥×¥í¥»¥¹¤½¤ì¤¾¤ì¤ËÀ¸À®¤µ¤ì¤ë¥¹¥ì¥Ã¥É¿ô
    ThreadStackSize sizesM
    ¥¯¥é¥¤¥¢¥ó¥È¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±»ý¤Ä¥¹¥ì¥Ã¥É¤¬»ÈÍѤ¹¤ë +¥¹¥¿¥Ã¥¯¤Î¥Ð¥¤¥È¿ô
    TimeOut seconds 300 sC
    ³Æ¥¤¥Ù¥ó¥È¤Ë¤Ä¤¤¤Æ¡¢¥ê¥¯¥¨¥¹¥È¤ò¼ºÇÔ¤µ¤»¤ë¤Þ¤Ç¤Ë¥µ¡¼¥Ð¤¬ +ÂԤĻþ´Ö¤òÀßÄê
    TransferLog file|pipesvB
    ¥í¥°¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤ò»ØÄê
    TypesConfig file-path conf/mime.types s
    mime.types ¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ
    UnsetEnv env-variable [env-variable] +...svdhB
    ´Ä¶­¤«¤éÊÑ¿ô¤ò¼è¤ê½ü¤¯
    UseCanonicalName On|Off|Dns Off svdC
    ¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤Î̾Á°¤È¥Ý¡¼¥È¤ò·èÄꤹ¤ëÊýË¡¤òÀßÄꤹ¤ë
    User unix-userid #-1 sM
    ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ëºÝ¤ËÍѤ¤¤ë¥æ¡¼¥¶ ID
    UserDir directory-filenamesvB
    ¥æ¡¼¥¶ÀìÍѥǥ£¥ì¥¯¥È¥ê¤Î°ÌÃÖ
    VirtualDocumentRoot interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    VirtualDocumentRootIP interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    <VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>sC
    ÆÃÄê¤Î¥Û¥¹¥È̾¤ä IP ¥¢¥É¥ì¥¹¤Î¤ß¤ËŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +°Ï¤à
    VirtualScriptAlias interpolated-directory|none none svE
    Dynamically configure the location of the CGI directory for +a given virtual host
    VirtualScriptAliasIP interpolated-directory|none none svE
    Dynamically configure the location of the cgi directory for +a given virtual host
    Win32DisableAcceptExsM
    ¥Í¥Ã¥È¥ï¡¼¥¯Àܳ¤Î¼õ¤±ÉÕ¤±¤Ë accept() ¤òAcceptEx ¤ÎÂå¤ï¤ê¤Ë»È¤¦
    XBitHack on|off|full off svdhB
    ¼Â¹Ô¥Ó¥Ã¥È¤¬ÀßÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î SSI ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò +²òÀϤ¹¤ë
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/quickreference.html.ko.euc-kr b/trunk/docs/manual/mod/quickreference.html.ko.euc-kr new file mode 100644 index 0000000000..723bfa1760 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.html.ko.euc-kr @@ -0,0 +1,692 @@ + + + +Áö½Ã¾î ºü¸¥ÂüÁ¶ - Apache HTTP Server + + + + + + +
    <-
    + +

    Áö½Ã¾î ºü¸¥ÂüÁ¶

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤Áö½Ã¾î °¢°¢ÀÇ ¿ëµµ, ±âº»°ª, »óÅÂ, + »ç¿ëÀå¼Ò¸¦ º¸¿©ÁØ´Ù. À̵éÀº Áö½Ã¾î »çÀü¿¡¼­ ¼³¸íÇÑ´Ù.

    + +

    ù¹ø° ¿­Àº Áö½Ã¾î À̸§°ú ¿ëµµ¸¦ ¾Ë·ÁÁØ´Ù. µÎ¹ø° ¿­Àº + Áö½Ã¾î¿¡ ±âº»°ªÀÌ ÀÖ´Ù¸é ±âº»°ªÀ» º¸¿©ÁØ´Ù. ¸¸¾à ±âº»°ªÀÌ + ³Ê¹« ±æ´Ù¸é, "+" ±âÈ£·Î »ý·«ÇßÀ½À» ¾Ë¸°´Ù.

    + +

    ¼¼¹ø°¿Í ³×¹ø° ¿­Àº °¢°¢ ¾Æ·¡ Ç¥¿¡ µû¶ó Áö½Ã¾î¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Â Àå¼Ò¿Í Áö½Ã¾îÀÇ »óŸ¦ ³ªÅ¸³½´Ù.

    +
    +
    + + + +
     A  |  B  |  C  |  D  |  E  |  F  |  G  |  H  |  I  |  K  |  L  |  M  |  N  |  O  |  P  |  R  |  S  |  T  |  U  |  V  |  W  |  X  + + + + + +
    sÁÖ¼­¹ö¼³Á¤
    v°¡»óÈ£½ºÆ®
    ddirectory
    h.htaccess
    + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AcceptMutex Default|method Default sM
    Method that Apache uses to serialize multiple children +accepting requests on network sockets
    AcceptPathInfo On|Off|Default Default svdhC
    Resources accept trailing pathname information
    AccessFileName filename [filename] ... .htaccess svC
    Name of the distributed configuration file
    Action action-type cgi-script [virtual]svdhB
    ƯÁ¤ Çڵ鷯³ª content-type¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù
    AddAlt string file [file] ...svdhB
    ÆÄÀϸíÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ ¼³¸í±Û
    AddAltByEncoding string MIME-encoding +[MIME-encoding] ...svdhB
    MIME-encodingÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û
    AddAltByType string MIME-type +[MIME-type] ...svdhB
    MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ¾ÆÀÌÄÜ´ë½Å »ç¿ëÇÒ ÆÄÀÏ +¼³¸í±Û
    AddCharset charset extension +[extension] ...svdhB
    Maps the given filename extensions to the specified content +charset
    AddDefaultCharset On|Off|charset Off svdhC
    Default charset parameter to be added when a response +content-type is text/plain or text/html
    AddDescription string file [file] ...svdhB
    ÆÄÀÏ¿¡ ´ëÇÑ ¼³¸í
    AddEncoding MIME-enc extension +[extension] ...svdhB
    Maps the given filename extensions to the specified encoding +type
    AddHandler handler-name extension +[extension] ...svdhB
    Maps the filename extensions to the specified +handler
    AddIcon icon name [name] +...svdhB
    À̸§À¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    AddIconByEncoding icon MIME-encoding +[MIME-encoding] ...svdhB
    MIME content-encodingÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    AddIconByType icon MIME-type +[MIME-type] ...svdhB
    MIME content-typeÀ¸·Î ¼±ÅÃÇÑ ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    AddInputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +client requests
    AddLanguage MIME-lang extension +[extension] ...svdhB
    Maps the given filename extension to the specified content +language
    AddModuleInfo module-name stringsvE
    ¸ðµâ¿¡ ´ëÇÑ Ãß°¡ Á¤º¸¸¦ server-info Çڵ鷯°¡ º¸¿©ÁÖµµ·Ï +Ãß°¡ÇÑ´Ù
    AddOutputFilter filter[;filter...] +extension [extension] ...svdhB
    Maps filename extensions to the filters that will process +responses from the server
    AddOutputFilterByType filter[;filter...] +MIME-type [MIME-type] ...svdhC
    assigns an output filter to a particular MIME-type
    AddType MIME-type extension +[extension] ...svdhB
    Maps the given filename extensions onto the specified content +type
    Alias URL-path +file-path|directory-pathsvB
    URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÑ´Ù
    AliasMatch regex +file-path|directory-pathsvB
    Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÑ´Ù
    Allow from all|host|env=env-variable +[host|env=env-variable] ...dhB
    ¼­¹öÀÇ ÀϺο¡ Á¢±ÙÇÒ ¼ö Àִ ȣ½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù
    AllowCONNECT port [port] ... 443 563 svE
    Ports that are allowed to CONNECT through the +proxy
    AllowEncodedSlashes On|Off Off svC
    Determines whether encoded path separators in URLs are allowed to +be passed through
    AllowOverride All|None|directive-type +[directive-type] ... All dC
    Types of directives that are allowed in +.htaccess files
    Anonymous user [user] ...dhE
    ¾ÏÈ£°Ë»ç¾øÀÌ Á¢±ÙÀ» Çã¿ëÇÒ »ç¿ëÀÚ ¾ÆÀ̵ðµéÀ» +ÁöÁ¤ÇÑ´Ù
    Anonymous_LogEmail On|Off On dhE
    ÀÔ·ÂÇÑ ¾ÏÈ£¸¦ ¿À·ù·Î±×¿¡ ±â·ÏÇÒÁö ¿©ºÎ
    Anonymous_MustGiveEmail On|Off On dhE
    ¾ÏÈ£°¡ ¾ø¾îµµ °¡´ÉÇÑÁö ¿©ºÎ
    Anonymous_NoUserID On|Off Off dhE
    »ç¿ëÀÚ ¾ÆÀ̵𰡠¾ø¾îµµ °¡´ÉÇÏÁö ¿©ºÎ
    Anonymous_VerifyEmail On|Off Off dhE
    ¾ÏÈ£°¡ ¿Ã¹Ù¸¥ Çü½ÄÀÇ ÀüÀÚ¿ìÆí ÁÖ¼ÒÀÎÁö °Ë»ç +¿©ºÎ
    AssignUserID user-id group-idvM
    Tie a virtual host to a user and group ID
    AuthBasicAuthoritative On|Off On dhB
    ÀÎÁõ°ú ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ¿¡ ³Ñ°ÜÁÙÁö °áÁ¤ÇÑ´Ù
    AuthBasicProvider On|Off|provider-name +[provider-name] ... On dhB
    ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù
    AuthDBMGroupFile file-pathdhE
    ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù
    AuthDBMType default|SDBM|GDBM|NDBM|DB default dhE
    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ +ÁöÁ¤ÇÑ´Ù
    AuthDBMUserFile file-pathdhE
    ÀÎÁõÇÒ »ç¿ëÀÚ¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º +ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù
    AuthDefaultAuthoritative On|Off On dhB
    ÀÎÁõÀ» Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    AuthDigestAlgorithm MD5|MD5-sess MD5 dhX
    digest authentication¿¡¼­ challenge¿Í response +hash¸¦ °è»êÇÏ´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÑ´Ù
    AuthDigestDomain URI [URI] ...dhX
    digest authentication¿¡¼­ °°Àº º¸È£¿µ¿ª¿¡ ¼ÓÇÏ´Â +URIµé
    AuthDigestNcCheck On|Off Off sX
    ¼­¹ö°¡ º¸³»´Â nonce-count¸¦ °Ë»çÇÒÁö ¿©ºÎ
    AuthDigestNonceFormat formatdhX
    nonce¸¦ ¸¸µå´Â ¹æ¹ýÀ» °áÁ¤ÇÑ´Ù
    AuthDigestNonceLifetime seconds 300 dhX
    ¼­¹ö nonce°¡ À¯È¿ÇÑ ±â°£
    AuthDigestProvider On|Off|provider-name +[provider-name] ... On dhX
    ÀÌ À§Ä¡¿¡ ´ëÇÑ ÀÎÁõÁ¦°øÀÚ¸¦ ÁöÁ¤ÇÑ´Ù
    AuthDigestQop none|auth|auth-int [auth|auth-int] auth dhX
    digest authentication°¡ »ç¿ëÇÒ +º¸È£¼öÁØ(quality-of-protection)À» ÁöÁ¤ÇÑ´Ù.
    AuthDigestShmemSize size 1000 sX
    Ŭ¶óÀ̾ðÆ®¸¦ ÃßÀûÇϱâÀ§ÇØ ÇÒ´çÇÏ´Â °øÀ¯¸Þ¸ð¸®·®
    AuthGroupFile file-pathdhB
    ÀÎÁõ¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ±×·ì ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù
    AuthLDAPBindDN distinguished-namedhE
    Optional DN to use in binding to the LDAP server
    AuthLDAPBindPassword passworddhE
    Password used in conjuction with the bind DN
    AuthLDAPCharsetConfig file-pathsE
    Language to charset conversion configuration file
    AuthLDAPCompareDNOnServer on|off on dhE
    Use the LDAP server to compare the DNs
    AuthLDAPDereferenceAliases never|searching|finding|always Always dhE
    When will the module de-reference aliases
    AuthLDAPGroupAttribute attributedhE
    LDAP attributes used to check for group membership
    AuthLDAPGroupAttributeIsDN on|off on dhE
    Use the DN of the client username when checking for +group membership
    AuthLDAPRemoteUserIsDN on|off off dhE
    Use the DN of the client username to set the REMOTE_USER +environment variable
    AuthLDAPUrl url [NONE|SSL|TLS|STARTTLS]dhE
    URL specifying the LDAP search parameters
    AuthName auth-domaindhC
    Authorization realm for use in HTTP +authentication
    <AuthnProviderAlias baseProvider Alias> +... </AuthnProviderAlias>svE
    Enclose a group of directives that represent an +extension of a base authentication provider and referenced by +the specified alias
    AuthType Basic|DigestdhC
    Type of user authentication
    AuthUserFile file-pathdhB
    ÀÎÁõÇÒ »ç¿ëÀÚ¸í¿Í ¾ÏÈ£ ¸ñ·ÏÀ» ÀúÀåÇÏ´Â ¹®ÀÚÆÄÀϸíÀ» +ÁöÁ¤ÇÑ´Ù
    AuthzDBMAuthoritative On|Off On dhE
    ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    AuthzDBMType default|SDBM|GDBM|NDBM|DB default dhE
    ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â µ¥ÀÌÅͺ£À̽º ÆÄÀÏ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù
    AuthzDefaultAuthoritative On|Off On dhB
    ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    AuthzGroupFileAuthoritative On|Off On dhB
    ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    AuthzLDAPAuthoritative on|off on dhE
    Prevent other authentication modules from +authenticating the user if this one fails
    AuthzOwnerAuthoritative On|Off On dhE
    ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    AuthzUserAuthoritative On|Off On dhB
    ±ÇÇѺο©¸¦ Àú¼öÁØ ¸ðµâ·Î ³Ñ°ÜÁÙÁö ¿©ºÎ
    BrowserMatch regex [!]env-variable[=value] +[[!]env-variable[=value]] ...svdhB
    HTTP User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    BrowserMatchNoCase regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í User-Agent¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù
    CacheDefaultExpire seconds 3600 (one hour) svX
    ¸¸±â½Ã°£À» ÁöÁ¤ÇÏÁö¾ÊÀº ¹®¼­¸¦ ij½¬ÇÒ ±âº» ±â°£.
    CacheDirLength length 2 svX
    ÇÏÀ§µð·ºÅ丮¸íÀÇ ¹®ÀÚ°³¼ö
    CacheDirLevels levels 3 svX
    ij½¬ÀÇ ÇÏÀ§µð·ºÅ丮 ±íÀÌ.
    CacheDisable url-stringsvX
    ƯÁ¤ URLÀ» ij½¬ÇÏÁö ¾Ê´Â´Ù
    CacheEnable cache_type url-stringsvX
    ÁöÁ¤ÇÑ ÀúÀå°ü¸®ÀÚ¸¦ »ç¿ëÇÏ¿© ÁöÁ¤ÇÑ URLÀ» ij½¬ÇÑ´Ù
    CacheFile file-path [file-path] ...sX
    ½ÃÀ۽à ¿©·¯ ÆÄÀÏ ÇÚµéÀ» ij½¬ÇÑ´Ù
    CacheIgnoreCacheControl On|Off Off svX
    Ŭ¶óÀ̾ðÆ®°¡ ij½¬ÇÏÁö¾Ê´Â ³»¿ëÀ» ¿äûÇÔÀ» ¹«½ÃÇÑ´Ù.
    CacheIgnoreHeaders header-string [header-string] ... None svX
    ij½¬¿¡ ÁöÁ¤ÇÑ HTTP Çì´õ(µé)¸¦ ÀúÀåÇÏÁö ¾Ê´Â´Ù +
    CacheIgnoreNoLastMod On|Off Off svX
    ÀÀ´ä¿¡ Last Modified Çì´õ°¡ ¾ø´Ù´Â »ç½ÇÀ» ¹«½ÃÇÑ´Ù.
    CacheLastModifiedFactor float 0.1 svX
    LastModified ½Ã°£À¸·Î ¸¸±â½Ã°£À» °è»êÇϴµ¥ »ç¿ëÇÏ´Â +°è¼ö.
    CacheMaxExpire seconds 86400 (ÇÏ·ç) svX
    ¹®¼­¸¦ ij½¬ÇÏ´Â ÃÊ´ÜÀ§ ÃÖ´ë½Ã°£
    CacheMaxFileSize bytes 1000000 svX
    ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ëÅ©±â (¹ÙÀÌÆ® ´ÜÀ§)
    CacheMinFileSize bytes 1 svX
    ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼ÒÅ©±â (¹ÙÀÌÆ® ´ÜÀ§)
    CacheNegotiatedDocs On|Off Off svB
    Allows content-negotiated documents to be +cached by proxy servers
    CacheRoot directorysvX
    ij½¬ ÆÄÀÏÀ» ÀúÀåÇÒ µð·ºÅ丮 root
    CGIMapExtension cgi-path .extensiondhC
    Technique for locating the interpreter for CGI +scripts
    CharsetDefault charsetsvdhX
    º¯È¯ÇÒ ¹®ÀÚÁýÇÕ
    CharsetOptions option [option] ... DebugLevel=0 NoImpl +svdhX
    ¹®ÀÚÁýÇÕ º¯È¯ ±â´ÉÀ» ¼³Á¤
    CharsetSourceEnc charsetsvdhX
    ÆÄÀÏ ¿øº»ÀÇ ¹®ÀÚÁýÇÕ
    CheckSpelling on|off Off svdhE
    ¸ÂÃã¹ý ¸ðµâÀ» »ç¿ëÇÑ´Ù
    ChildPerUserID user-id group-id +num-childrensM
    Specify user ID and group ID for a number of child +processes
    ContentDigest On|Off Off svdhC
    Enables the generation of Content-MD5 HTTP Response +headers
    CookieDomain domainsvdhE
    The domain to which the tracking cookie applies
    CookieExpires expiry-periodsvdhE
    Expiry time for the tracking cookie
    CookieLog filenamesvB
    ÄíÅ°¸¦ ·Î±×¿¡ ³²±â±âÀ§ÇØ »ç¿ëÇÒ ÆÄÀϸíÀ» ¼³Á¤ÇÑ´Ù
    CookieName token Apache svdhE
    Name of the tracking cookie
    CookieStyle + Netscape|Cookie|Cookie2|RFC2109|RFC2965 Netscape svdhE
    Format of the cookie header field
    CookieTracking on|off off svdhE
    Enables tracking cookie
    CoreDumpDirectory directorysM
    Directory where Apache attempts to +switch before dumping core
    CustomLog file|pipe +format|nickname +[env=[!]environment-variable]svB
    ·Î±×ÆÄÀÏ À̸§°ú Çü½ÄÀ» ÁöÁ¤ÇÑ´Ù
    Dav On|Off|provider-name Off dE
    WebDAV HTTP ¸Þ½áµå¸¦ ½ÃÀÛÇÑ´Ù
    DavDepthInfinity on|off off svdE
    PROPFINDÀÇ Depth: Infinity ¿äûÀ» Çã°¡ÇÑ´Ù
    DavGenericLockDB file-pathsvdE
    Location of the DAV lock database
    DavLockDB file-pathsvE
    DAV Àá±Ý µ¥ÀÌÅͺ£À̽º À§Ä¡
    DavMinTimeout seconds 0 svdE
    ¼­¹ö°¡ DAV ÀÚ¿ø¿¡ ´ëÇØ À¯ÁöÇÒ Àá±ÝÀÇ Ãּҽð£
    DBDExptime time-in-secondssvX
    Keepalive time for idle connections
    DBDKeep numbersvX
    Maximum sustainednumber of connections
    DBDMax numbersvX
    Maximum number of connections
    DBDMin numbersvX
    Minimum number of connections
    DBDParams +param1=value1[,param2=value2]svX
    Parameters for database connection
    DBDPersist 0|1svX
    Whether to use persistent connections
    DBDPrepareSQL "SQL statement" labelsvX
    Define an SQL prepared statement
    DBDriver namesvX
    Specify an SQL driver
    DefaultIcon url-pathsvdhB
    ƯÁ¤ ¾ÆÀÌÄÜÀ» ¼³Á¤ÇÏÁö¾ÊÀº ÆÄÀÏ¿¡ »ç¿ëÇÒ ¾ÆÀÌÄÜ
    DefaultLanguage MIME-langsvdhB
    Sets all files in the given scope to the specified +language
    DefaultType MIME-type text/plain svdhC
    MIME content-type that will be sent if the +server cannot determine a type in any other way
    DeflateBufferSize value 8096 svE
    zlibÀÌ Çѹø¿¡ ¾ÐÃàÇÒ Å©±â
    DeflateCompressionLevel valuesvE
    Ãâ·ÂÀ» ¾î´ÀÁ¤µµ ¾ÐÃàÇϴ°¡
    DeflateFilterNote [type] notenamesvE
    ¾ÐÃà·üÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    DeflateMemLevel value 9 svE
    zlibÀÌ ¾ÐÃàÇÒ¶§ »ç¿ëÇÏ´Â ¸Þ¸ð¸®·®
    DeflateWindowSize value 15 svE
    Zlib ¾ÐÃà window size
    Deny from all|host|env=env-variable +[host|env=env-variable] ...dhB
    ¼­¹ö Á¢±ÙÀ» °ÅºÎÇÒ È£½ºÆ®¸¦ ÁöÁ¤ÇÑ´Ù
    <Directory directory-path> +... </Directory>svC
    Enclose a group of directives that apply only to the +named file-system directory and sub-directories
    DirectoryIndex + local-url [local-url] ... index.html svdhB
    Ŭ¶óÀ̾ðÆ®°¡ µð·ºÅ丮¸¦ ¿äûÇÒ¶§ ã¾Æº¼ ÀÚ¿ø ¸ñ·Ï
    <DirectoryMatch regex> +... </DirectoryMatch>svC
    Enclose directives that apply to +file-system directories matching a regular expression and their +subdirectories
    DirectorySlash On|Off On svdhB
    ¸¶Áö¸· ½½·¡½¬ ¸®´ÙÀÌ·º¼ÇÀ» Å°°í ²ö´Ù
    DocumentRoot directory-path /usr/local/apache/h +svC
    Directory that forms the main document tree visible +from the web
    DumpIOInput On|Off Off sE
    Dump all input data to the error log
    DumpIOOutput On|Off Off sE
    Dump all output data to the error log
    EnableExceptionHook On|Off Off sM
    Enables a hook that runs exception handlers +after a crash
    EnableMMAP On|Off On svdhC
    Use memory-mapping to read files during delivery
    EnableSendfile On|Off On svdhC
    Use the kernel sendfile support to deliver files to the client
    ErrorDocument error-code documentsvdhC
    What the server will return to the client +in case of an error
    ErrorLog file-path|syslog[:facility] logs/error_log (Uni +svC
    Location where the server will log errors
    ExamplesvdhX
    ¾ÆÆÄÄ¡ ¸ðµâ API¸¦ ¼³¸íÇϱâÀ§ÇÑ ¿¹Á¦ Áö½Ã¾î
    ExpiresActive On|OffsvdhE
    Expires Çì´õ¸¦ »ý¼ºÇÑ´Ù
    ExpiresByType MIME-type +<code>secondssvdhE
    MIME typeÀ¸·Î Expires Çì´õ°ªÀ» ¼³Á¤ÇÑ´Ù
    ExpiresDefault <code>secondssvdhE
    ¸¸±â½Ã°£À» °è»êÇÏ´Â ±âº» ¾Ë°í¸®Áò
    ExtendedStatus On|Off Off sB
    °¢ ¿äû¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ »óÅ Á¤º¸¸¦ ±â·ÏÇÑ´Ù
    ExtFilterDefine filtername parameterssE
    ¿ÜºÎ ÇÊÅ͸¦ Á¤ÀÇÇÑ´Ù
    ExtFilterOptions option [option] ... DebugLevel=0 NoLogS +dE
    mod_ext_filter ¿É¼ÇÀ» ¼³Á¤ÇÑ´Ù
    FileETag component ... INode MTime Size svdhC
    File attributes used to create the ETag +HTTP response header
    <Files filename> ... </Files>svdhC
    Contains directives that apply to matched +filenames
    <FilesMatch regex> ... </FilesMatch>svdhC
    Contains directives that apply to regular-expression matched +filenames
    FilterChain [+=-@!]filter-name ...svdhX
    Configure the filter chain
    FilterDeclare filter-name [type]svdhX
    Declare a smart filter
    FilterProtocol filter-name [provider-name] + proto-flagssvdhX
    Deal with correct HTTP protocol handling
    FilterProvider filter-name provider-name + [req|resp|env]=dispatch matchsvdhX
    Register a content filter
    FilterTrace filter-name levelsvdX
    Get debug/diagnostic information from + mod_filter
    ForceLanguagePriority None|Prefer|Fallback [Prefer|Fallback] Prefer svdhB
    Action to take if a single acceptable document is not +found
    ForceType MIME-type|NonedhC
    Forces all matching files to be served with the specified +MIME content-type
    ForensicLog filename|pipesvE
    Sets filename of the forensic log
    Group unix-group #-1 sM
    Group under which the server will answer +requests
    Header [condition] set|append|add|unset|echo +header [value] [early|env=[!]variable]svdhE
    HTTP ÀÀ´ä Çì´õ¸¦ ±¸¼ºÇÑ´Ù
    HeaderName filenamesvdhB
    ÆÄÀϸñ·Ï À§¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§
    HostnameLookups On|Off|Double Off svdC
    Enables DNS lookups on client IP addresses
    IdentityCheck On|Off Off svdE
    ¿ø°Ý »ç¿ëÀÚÀÇ RFC 1413 ½Å¿øÀ» ·Î±×¿¡ ±â·ÏÇÑ´Ù
    IdentityCheckTimeout seconds 30 svdE
    ident ¿äûÀÇ ½Ã°£Á¦ÇÑÀ» ÁöÁ¤ÇÑ´Ù
    <IfDefine [!]parameter-name> ... + </IfDefine>svdhC
    Encloses directives that will be processed only +if a test is true at startup
    <IfModule [!]module-file|module-identifier> ... + </IfModule>svdhC
    Encloses directives that are processed conditional on the +presence or absence of a specific module
    <IfVersion [[!]operator] version> ... +</IfVersion>svdhE
    ¹öÀüº° ¼³Á¤À» ¹­´Â´Ù
    ImapBase map|referer|URL http://servername/ svdhB
    À̹ÌÁö¸Ê ÆÄÀÏ¿¡¼­ base ±âº»°ª
    ImapDefault error|nocontent|map|referer|URL nocontent svdhB
    À̹ÌÁö¸Ê¿¡ ¾î´À ¿µ¿ª¿¡µµ ÇØ´çÇÏÁö ¾Ê´Â ÁÂÇ¥¸¦ ÁØ +°æ¿ì ±âº» Çൿ
    ImapMenu none|formatted|semiformatted|unformattedsvdhB
    ÁÂÇ¥¾øÀÌ À̹ÌÁö¸Ê ¿äû½Ã ÃëÇÒ Çൿ
    Include file-path|directory-pathsvdC
    Includes other configuration files from within +the server configuration files
    IndexIgnore file [file] ...svdhB
    µð·ºÅ丮 ¸ñ·Ï¿¡¼­ ¼û±æ ÆÄÀϸñ·ÏÀ» Ãß°¡ÇÑ´Ù
    IndexOptions [+|-]option [[+|-]option] +...svdhB
    µð·ºÅ丮 ¸ñ·ÏÀÇ ¿©·¯ ¼³Á¤µé
    IndexOrderDefault Ascending|Descending +Name|Date|Size|Description Ascending Name svdhB
    µð·ºÅ丮 ¸ñ·ÏÀÇ ±âº» ¼ø¼­¸¦ ¼³Á¤ÇÑ´Ù
    IndexStyleSheet url-pathsvdhB
    µð·ºÅ丮 ¸ñ·Ï¿¡ CSS ½ºÅ¸ÀϽ¬Æ®¸¦ Ãß°¡ÇÑ´Ù
    ISAPIAppendLogToErrors on|off off svdhB
    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ¿À·ù ·Î±×¿¡ ±â·ÏÇÑ´Ù
    ISAPIAppendLogToQuery on|off on svdhB
    ISAPI exntensionÀÇ HSE_APPEND_LOG_PARAMETER +¿äûÀ» ÁúÀǹ®ÀÚ¿­¿¡ ±â·ÏÇÑ´Ù
    ISAPICacheFile file-path [file-path] +...svB
    ¼­¹ö°¡ ½ÃÀÛÇÒ¶§ ¸Þ¸ð¸®·Î ÀоîµéÀÏ ISAPI .dll ÆÄÀϵé
    ISAPIFakeAsync on|off off svdhB
    ºñµ¿±â ISAPI ÄݹéÀ» Áö¿øÇϴ ôÇÑ´Ù
    ISAPILogNotSupported on|off off svdhB
    ISAPI extensionÀÌ Áö¿øÇÏÁö ¾Ê´Â ±â´ÉÀ» ¿äûÇϸé +·Î±×¿¡ ±â·ÏÇÑ´Ù
    ISAPIReadAheadBuffer size 49152 svdhB
    ISAPI extensionÀÇ ¹Ì¸®Àбâ¹öÆÛ(read ahead buffer) +Å©±â
    KeepAlive On|Off On svC
    Enables HTTP persistent connections
    KeepAliveTimeout seconds 5 svC
    Amount of time the server will wait for subsequent +requests on a persistent connection
    LanguagePriority MIME-lang [MIME-lang] +...svdhB
    The precendence of language variants for cases where +the client does not express a preference
    LDAPCacheEntries number 1024 sE
    Maximum number of entries in the primary LDAP cache
    LDAPCacheTTL seconds 600 sE
    Time that cached items remain valid
    LDAPConnectionTimeout secondssE
    Specifies the socket connection timeout in seconds
    LDAPOpCacheEntries number 1024 sE
    Number of entries used to cache LDAP compare +operations
    LDAPOpCacheTTL seconds 600 sE
    Time that entries in the operation cache remain +valid
    LDAPSharedCacheFile directory-path/filenamesE
    Sets the shared memory cache file
    LDAPSharedCacheSize bytes 102400 sE
    Size in bytes of the shared-memory cache
    LDAPTrustedClientCert type directory-path/filename/nickname [password]svdhE
    Sets the file containing or nickname referring to a per +connection client certificate. Not all LDAP toolkits support per +connection client certificates.
    LDAPTrustedGlobalCert type directory-path/filename [password]sE
    Sets the file or database containing global trusted +Certificate Authority or global client certificates
    LDAPTrustedMode typesvdhE
    Specifies the SSL/TLS mode to be used when connecting to an LDAP server.
    LDAPVerifyServerCert On|Off On sE
    Force server certificate verification
    <Limit method [method] ... > ... + </Limit>svdhC
    Restrict enclosed access controls to only certain HTTP +methods
    <LimitExcept method [method] ... > ... + </LimitExcept>svdhC
    Restrict access controls to all HTTP methods +except the named ones
    LimitInternalRecursion number [number] 10 svC
    Determine maximum number of internal redirects and nested +subrequests
    LimitRequestBody bytes 0 svdhC
    Restricts the total size of the HTTP request body sent +from the client
    LimitRequestFields number 100 sC
    Limits the number of HTTP request header fields that +will be accepted from the client
    LimitRequestFieldsize bytessC
    Limits the size of the HTTP request header allowed from the +client
    LimitRequestLine bytes 8190 sC
    Limit the size of the HTTP request line that will be accepted +from the client
    LimitXMLRequestBody bytes 1000000 svdhC
    Limits the size of an XML-based request body
    Listen [IP-address:]portnumbersM
    IP addresses and ports that the server +listens to
    ListenBacklog backlogsM
    Maximum length of the queue of pending connections
    LoadFile filename [filename] ...sE
    ÁöÁ¤ÇÑ ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀδÙ
    LoadModule module filenamesE
    ¸ñÀûÆÄÀÏÀ̳ª ¶óÀ̺귯¸®¸¦ ÀоîµéÀÌ°í, »ç¿ë°¡´ÉÇÑ +¸ðµâ ¸ñ·Ï¿¡ Ãß°¡ÇÑ´Ù
    <Location + URL-path|URL> ... </Location>svC
    Applies the enclosed directives only to matching +URLs
    <LocationMatch + regex> ... </LocationMatch>svC
    Applies the enclosed directives only to regular-expression +matching URLs
    LockFile filename logs/accept.lock sM
    Location of the accept serialization lock file
    LogFormat format|nickname +[nickname] "%h %l %u %t \"%r\" +svB
    ·Î±×ÆÄÀÏ¿¡ »ç¿ëÇÒ Çü½ÄÀ» ±â¼úÇÑ´Ù
    LogLevel level warn svC
    Controls the verbosity of the ErrorLog
    MaxClients numbersM
    Maximum number of child processes that will be created +to serve requests
    MaxKeepAliveRequests number 100 svC
    Number of requests allowed on a persistent +connection
    MaxMemFree KBytes 0 sM
    Maximum amount of memory that the main allocator is allowed +to hold without calling free()
    MaxRequestsPerChild number 10000 sM
    Limit on the number of requests that an individual child server +will handle during its life
    MaxRequestsPerThread number 0 sM
    ÇÑ ¾²·¹µå°¡ ½ÇÇàÇÏ´Â µ¿¾È ó¸®ÇÒ ¿äû°³¼ö ÇÑ°è
    MaxSpareServers number 10 sM
    Maximum number of idle child server processes
    MaxSpareThreads numbersM
    Maximum number of idle threads
    MaxThreads number 2048 sM
    Set the maximum number of worker threads
    MaxThreadsPerChild number 64 sM
    Maximum number of threads per child process
    MCacheMaxObjectCount value 1009 sX
    ij½¬¿¡ ÀúÀåÇÒ ¼ö ÀÖ´Â ÃÖ´ë °´Ã¼°³¼ö
    MCacheMaxObjectSize bytes 10000 sX
    ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ´ë Å©±â (¹ÙÀÌÆ® ´ÜÀ§)
    MCacheMaxStreamingBuffer size_in_bytes 100000°ú MCacheMaxOb +sX
    ÀÀ´äÀ» ij½¬¾ÈÇÑ´Ù°í °áÁ¤Çϱâ Àü±îÁö ¸Þ¸ð¸® ¹öÆÛ¿¡ +ÀúÀåÇÒ ½ºÆ®¸² ÀÀ´äÀÇ ÃÖ´ë Å©±â
    MCacheMinObjectSize bytes 0 sX
    ij½¬¿¡ ÀúÀåÇÒ ¹®¼­ÀÇ ÃÖ¼Ò Å©±â (¹ÙÀÌÆ® ´ÜÀ§)
    MCacheRemovalAlgorithm LRU|GDSF GDSF sX
    ij½¬¿¡¼­ Á¦°ÅÇÒ ¹®¼­¸¦ ã´Â ¾Ë°í¸®Áò
    MCacheSize KBytes 100 sX
    ij½¬¿¡ »ç¿ëÇÒ ÃÖ´ë ¸Þ¸ð¸®·® (KByte ´ÜÀ§)
    MetaDir directory .web svdhE
    CERN ¸ÞŸÁ¤º¸¸¦ ãÀ» µð·ºÅ丮 À̸§
    MetaFiles on|off off svdhE
    CERN ¸ÞŸÆÄÀÏÀ» ó¸®ÇÑ´Ù
    MetaSuffix suffix .meta svdhE
    CERN ¸ÞŸÁ¤º¸¸¦ ÀúÀåÇÏ´Â ÆÄÀÏÀÇ Á¢¹Ì»ç
    MimeMagicFile file-pathsvE
    Enable MIME-type determination based on file contents +using the specified magic file
    MinSpareServers number 5 sM
    Minimum number of idle child server processes
    MinSpareThreads numbersM
    Minimum number of idle threads available to handle request +spikes
    MMapFile file-path [file-path] ...sX
    ½ÃÀ۽à ¿©·¯ ÆÄÀÏÀ» ¸Þ¸ð¸®¿¡ ´ëÀÀÇÑ´Ù
    ModMimeUsePathInfo On|Off Off dB
    Tells mod_mime to treat path_info +components as part of the filename
    MultiviewsMatch Any|NegotiatedOnly|Filters|Handlers +[Handlers|Filters] NegotiatedOnly svdhB
    The types of files that will be included when searching for +a matching file with MultiViews
    NameVirtualHost addr[:port]sC
    Designates an IP address for name-virtual +hosting
    NoProxy host [host] ...svE
    Hosts, domains, or networks that will be connected to +directly
    NumServers number 2 sM
    Total number of children alive at the same time
    NWSSLTrustedCerts filename [filename] ...sB
    List of additional client certificates
    NWSSLUpgradeable [IP-address:]portnumbersB
    Allows a connection to be upgraded to an SSL connection upon request
    Options + [+|-]option [[+|-]option] ... All svdhC
    Configures what features are available in a particular +directory
    Order ordering Deny,Allow dhB
    ±âº»ÀûÀ¸·Î Á¢±ÙÀ» Çã¿ëÇÒÁö °ÅºÎÇÒÁö ¿©ºÎ¿Í +Allow¿Í Deny +󸮼ø¼­¸¦ Á¤ÇÑ´Ù.
    PassEnv env-variable [env-variable] +...svdhB
    ½©¿¡¼­ ȯ°æº¯¼ö¸¦ °¡Á®¿Â´Ù
    PidFile filename logs/httpd.pid sM
    File where the server records the process ID +of the daemon
    ProtocolEcho On|OffsvX
    echo ¼­¹ö¸¦ Å°°í ²ö´Ù
    <Proxy wildcard-url> ...</Proxy>svE
    Container for directives applied to proxied resources
    ProxyBadHeader IsError|Ignore|StartBody IsError svE
    Determines how to handle bad header lines in a +response
    ProxyBlock *|word|host|domain +[word|host|domain] ...svE
    Words, hosts, or domains that are banned from being +proxied
    ProxyDomain DomainsvE
    Default domain name for proxied requests
    ProxyErrorOverride On|Off Off svE
    Override error pages for proxied content
    ProxyIOBufferSize bytes 8192 svE
    Determine size of internal data throughput buffer
    <ProxyMatch regex> ...</ProxyMatch>svE
    Container for directives applied to regular-expression-matched +proxied resources
    ProxyMaxForwards number 10 svE
    Maximium number of proxies that a request can be forwarded +through
    ProxyPass [path] !|url [key=value key=value ...]]svdE
    Maps remote servers into the local server URL-space
    ProxyPassReverse [path] urlsvdE
    Adjusts the URL in HTTP response headers sent from a reverse +proxied server
    ProxyPassReverseCookieDomain internal-domain public-domainsvdE
    Adjusts the Domain string in Set-Cookie headers from a reverse- +proxied server
    ProxyPassReverseCookiePath internal-path public-pathsvdE
    Adjusts the Path string in Set-Cookie headers from a reverse- +proxied server
    ProxyPreserveHost On|Off Off svE
    Use incoming Host HTTP request header for proxy +request
    ProxyReceiveBufferSize bytes 0 svE
    Network buffer size for proxied HTTP and FTP +connections
    ProxyRemote match remote-serversvE
    Remote proxy used to handle certain requests
    ProxyRemoteMatch regex remote-serversvE
    Remote proxy used to handle requests matched by regular +expressions
    ProxyRequests On|Off Off svE
    Enables forward (standard) proxy requests
    ProxyTimeout seconds 300 svE
    Network timeout for proxied requests
    ProxyVia On|Off|Full|Block Off svE
    Information provided in the Via HTTP response +header for proxied requests
    ReadmeName filenamesvdhB
    ÆÄÀϸñ·Ï ¸¶Áö¸·¿¡ »ðÀÔÇÒ ÆÄÀÏÀÇ À̸§
    Redirect [status] URL-path +URLsvdhB
    Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    RedirectMatch [status] regex +URLsvdhB
    ÇöÀç URLÀÌ Á¤±ÔÇ¥Çö½Ä¿¡ ÇØ´çÇÏ¸é ¿ÜºÎ ¸®´ÙÀÌ·º¼ÇÀ» +º¸³½´Ù
    RedirectPermanent URL-path URLsvdhB
    Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +¿µ±¸ ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    RedirectTemp URL-path URLsvdhB
    Ŭ¶óÀ̾ðÆ®°¡ ´Ù¸¥ URL¿¡ Á¢¼ÓÇϵµ·Ï ¿äûÇÏ´Â ¿ÜºÎ +Àӽà ¸®´ÙÀÌ·º¼ÇÀ» º¸³½´Ù
    RemoveCharset extension [extension] +...vdhB
    Removes any character set associations for a set of file +extensions
    RemoveEncoding extension [extension] +...vdhB
    Removes any content encoding associations for a set of file +extensions
    RemoveHandler extension [extension] +...vdhB
    Removes any handler associations for a set of file +extensions
    RemoveInputFilter extension [extension] +...vdhB
    Removes any input filter associations for a set of file +extensions
    RemoveLanguage extension [extension] +...vdhB
    Removes any language associations for a set of file +extensions
    RemoveOutputFilter extension [extension] +...vdhB
    Removes any output filter associations for a set of file +extensions
    RemoveType extension [extension] +...vdhB
    Removes any content type associations for a set of file +extensions
    RequestHeader set|append|add|unset header +[value] [early|env=[!]variable]svdhE
    HTTP ¿äû Çì´õ¸¦ ±¸¼ºÇÑ´Ù
    Require entity-name [entity-name] ...dhC
    Selects which authenticated users can access +a resource
    RewriteBase URL-pathdhE
    Sets the base URL for per-directory rewrites
    RewriteCond + TestString CondPatternsvdhE
    Defines a condition under which rewriting will take place +
    RewriteEngine on|off off svdhE
    Enables or disables runtime rewriting engine
    RewriteLock file-pathsE
    Sets the name of the lock file used for RewriteMap +synchronization
    RewriteLog file-pathsvE
    Sets the name of the file used for logging rewrite engine +processing
    RewriteLogLevel Level 0 svE
    Sets the verbosity of the log file used by the rewrite +engine
    RewriteMap MapName MapType:MapSource +svE
    Defines a mapping function for key-lookup
    RewriteOptions OptionssvdhE
    Sets some special options for the rewrite engine
    RewriteRule + Pattern SubstitutionsvdhE
    Defines rules for the rewriting engine
    RLimitCPU seconds|max [seconds|max]svdhC
    Limits the CPU consumption of processes launched +by Apache children
    RLimitMEM bytes|max [bytes|max]svdhC
    Limits the memory consumption of processes launched +by Apache children
    RLimitNPROC number|max [number|max]svdhC
    Limits the number of processes that can be launched by +processes launched by Apache children
    Satisfy Any|All All dhC
    Interaction between host-level access control and +user authentication
    ScoreBoardFile file-path logs/apache_status sM
    Location of the file used to store coordination data for +the child processes
    Script method cgi-scriptsvdB
    ƯÁ¤ ¿äû¸Þ¼­µå¿¡ ´ëÇØ CGI ½ºÅ©¸³Æ®¸¦ +»ç¿ëÇÑ´Ù.
    ScriptAlias URL-path +file-path|directory-pathsvB
    URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î ´ëÀÀÇÏ°í ´ë»óÀÌ CGI +½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù
    ScriptAliasMatch regex +file-path|directory-pathsvB
    Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ¿© URLÀ» ƯÁ¤ ÆÄÀϽýºÅÛ Àå¼Ò·Î +´ëÀÀÇÏ°í ´ë»óÀÌ CGI ½ºÅ©¸³Æ®¶ó°í ¾Ë¸°´Ù
    ScriptInterpreterSource Registry|Registry-Strict|Script Script svdhC
    Technique for locating the interpreter for CGI +scripts
    ScriptLog file-pathsvB
    CGI ½ºÅ©¸³Æ® ¿À·ù·Î±×ÆÄÀÏÀÇ À§Ä¡
    ScriptLogBuffer bytes 1024 svB
    ½ºÅ©¸³Æ® ·Î±×¿¡ ±â·ÏÇÒ PUT ȤÀº POST ¿äûÀÇ ÃÖ´ë·®
    ScriptLogLength bytes 10385760 svB
    CGI ½ºÅ©¸³Æ® ·Î±×ÆÄÀÏÀÇ Å©±â Á¦ÇÑ
    ScriptSock file-path logs/cgisock svB
    cgi µ¥¸ó°ú Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ¼ÒÄÏÀÇ À̸§
    SecureListen [IP-address:]portnumber +Certificate-Name [MUTUAL]sB
    Enables SSL encryption for the specified port
    SendBufferSize bytes 0 sM
    TCP buffer size
    ServerAdmin email-address|URLsvC
    Email address that the server includes in error +messages sent to the client
    ServerAlias hostname [hostname] ...vC
    Alternate names for a host used when matching requests +to name-virtual hosts
    ServerLimit numbersM
    Upper limit on configurable number of processes
    ServerName fully-qualified-domain-name[:port]svC
    Hostname and port that the server uses to identify +itself
    ServerPath URL-pathvC
    Legacy URL pathname for a name-based virtual host that +is accessed by an incompatible browser
    ServerRoot directory-path /usr/local/apache sC
    Base directory for the server installation
    ServerSignature On|Off|EMail Off svdhC
    Configures the footer on server-generated documents
    ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full Full sC
    Configures the Server HTTP response +header
    SetEnv env-variable valuesvdhB
    ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    SetEnvIf attribute + regex [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    ¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÑ´Ù
    SetEnvIfNoCase attribute regex + [!]env-variable[=value] + [[!]env-variable[=value]] ...svdhB
    ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í ¿äûÀÇ ¼ºÁú¿¡ µû¶ó ȯ°æº¯¼ö¸¦ +¼³Á¤ÇÑ´Ù
    SetHandler handler-name|NonesvdhC
    Forces all matching files to be processed by a +handler
    SetInputFilter filter[;filter...]svdhC
    Sets the filters that will process client requests and POST +input
    SetOutputFilter filter[;filter...]svdhC
    Sets the filters that will process responses from the +server
    SSIEndTag tag "-->" svB
    String that ends an include element
    SSIErrorMsg message "[an error occurred +svdhB
    Error message displayed when there is an SSI +error
    SSIStartTag tag "<!--#" svB
    String that starts an include element
    SSITimeFormat formatstring "%A, %d-%b-%Y %H:%M +svdhB
    Configures the format in which date strings are +displayed
    SSIUndefinedEcho string "(none)" svdhB
    String displayed when an unset variable is echoed
    SSLCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Client Auth
    SSLCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Client Auth
    SSLCADNRequestFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for defining acceptable CA names
    SSLCADNRequestPath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +defining acceptable CA names
    SSLCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Client Auth
    SSLCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Client Auth
    SSLCertificateChainFile file-pathsvE
    File of PEM-encoded Server CA Certificates
    SSLCertificateFile file-pathsvE
    Server PEM-encoded X.509 Certificate file
    SSLCertificateKeyFile file-pathsvE
    Server PEM-encoded Private Key file
    SSLCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +handshake
    SSLCryptoDevice engine builtin sE
    Enable use of a cryptographic hardware accelerator
    SSLEngine on|off|optional off svE
    SSL Engine Operation Switch
    SSLHonorCiperOrder flagsvE
    Option to prefer the server's cipher preference order
    SSLMutex type none sE
    Semaphore for internal mutual exclusion of +operations
    SSLOptions [+|-]option ...svdhE
    Configure various SSL engine run-time options
    SSLPassPhraseDialog type builtin sE
    Type of pass phrase dialog for encrypted private +keys
    SSLProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors
    SSLProxyCACertificateFile file-pathsvE
    File of concatenated PEM-encoded CA Certificates +for Remote Server Auth
    SSLProxyCACertificatePath directory-pathsvE
    Directory of PEM-encoded CA Certificates for +Remote Server Auth
    SSLProxyCARevocationFile file-pathsvE
    File of concatenated PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCARevocationPath directory-pathsvE
    Directory of PEM-encoded CA CRLs for +Remote Server Auth
    SSLProxyCipherSuite cipher-spec ALL:!ADH:RC4+RSA:+H +svdhE
    Cipher Suite available for negotiation in SSL +proxy handshake
    SSLProxyEngine on|off off svE
    SSL Proxy Engine Operation Switch
    SSLProxyMachineCertificateFile filenamesE
    File of concatenated PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyMachineCertificatePath directorysE
    Directory of PEM-encoded client certificates and keys to be used by the proxy
    SSLProxyProtocol [+|-]protocol ... all svE
    Configure usable SSL protocol flavors for proxy usage
    SSLProxyVerify level none svdhE
    Type of remote server Certificate verification
    SSLProxyVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Remote Server +Certificate verification
    SSLRandomSeed context source +[bytes]sE
    Pseudo Random Number Generator (PRNG) seeding +source
    SSLRequire expressiondhE
    Allow access only when an arbitrarily complex +boolean expression is true
    SSLRequireSSLdhE
    Deny access when SSL is not used for the +HTTP request
    SSLSessionCache type none sE
    Type of the global/inter-process SSL Session +Cache
    SSLSessionCacheTimeout seconds 300 svE
    Number of seconds before an SSL session expires +in the Session Cache
    SSLUserName varnamesdhE
    Variable name to determine user name
    SSLVerifyClient level none svdhE
    Type of Client Certificate verification
    SSLVerifyDepth number 1 svdhE
    Maximum depth of CA Certificates in Client +Certificate verification
    StartServers numbersM
    Number of child server processes created at startup
    StartThreads numbersM
    Number of threads created on startup
    SuexecUserGroup User GroupsvE
    CGI ÇÁ·Î±×·¥ÀÌ »ç¿ëÇÒ »ç¿ëÀÚ¿Í ±×·ì ±ÇÇÑ
    ThreadLimit numbersM
    Sets the upper limit on the configurable number of threads +per child process
    ThreadsPerChild numbersM
    Number of threads created by each child process
    ThreadStackSize sizesM
    The size in bytes of the stack used by threads handling +client connections
    TimeOut seconds 300 sC
    Amount of time the server will wait for +certain events before failing a request
    TransferLog file|pipesvB
    ·Î±×ÆÄÀÏ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù
    TypesConfig file-path conf/mime.types sB
    The location of the mime.types file
    UnsetEnv env-variable [env-variable] +...svdhB
    ȯ°æº¯¼ö¸¦ Á¦°ÅÇÑ´Ù
    UseCanonicalName On|Off|DNS Off svdC
    Configures how the server determines its own name and +port
    User unix-userid #-1 sM
    The userid under which the server will answer +requests
    UserDir directory-filename public_html svB
    »ç¿ëÀÚº° µð·ºÅ丮 À§Ä¡
    VirtualDocumentRoot interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    VirtualDocumentRootIP interpolated-directory|none none svE
    Dynamically configure the location of the document root +for a given virtual host
    <VirtualHost + addr[:port] [addr[:port]] + ...> ... </VirtualHost>sC
    Contains directives that apply only to a specific +hostname or IP address
    VirtualScriptAlias interpolated-directory|none none svE
    Dynamically configure the location of the CGI directory for +a given virtual host
    VirtualScriptAliasIP interpolated-directory|none none svE
    Dynamically configure the location of the cgi directory for +a given virtual host
    Win32DisableAcceptExsM
    Use accept() rather than AcceptEx() to accept network connections
    XBitHack on|off|full off svdhB
    Parse SSI directives in files with the execute bit +set
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/quickreference.xml b/trunk/docs/manual/mod/quickreference.xml new file mode 100644 index 0000000000..f3f02002cc --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml @@ -0,0 +1,59 @@ + + + + + + + + + Directive Quick Reference + +

    The directive quick reference shows the usage, default, status, + and context of each Apache configuration directive. For more + information about each of these, see the Directive Dictionary.

    + +

    The first column gives the directive name and usage. The second + columns shows the default value of the directive, if a default exists. + If the default is too large to display, the first characters will be + followed by "+".

    + +

    The third and fourth columns list the contexts where the directive + is allowed and the status of the directive according to the legend + tables below.

    +
    + + + + + + + + +
    sserver config
    vvirtual host
    ddirectory
    h.htaccess
    + + + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    +
    +
    diff --git a/trunk/docs/manual/mod/quickreference.xml.de b/trunk/docs/manual/mod/quickreference.xml.de new file mode 100644 index 0000000000..11a4c0658b --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml.de @@ -0,0 +1,61 @@ + + + + + + + + + Kurzreferenz der Direktiven + +

    Die Kurzreferenz der Direktiven zeigt die Verwendung, + Voreinstellung, den Status und den Kontext aller + Apache-Konfigurationsanweisungen. Für weitergehende Informationen + schauen Sie bitte im Verzeichnis der Direktiven.

    + +

    Die erste Spalte enthält den Namen und die Verwendung. + Die zweite Spalte zeigt die Voreinstellung der Direktive, sofern + eine Voreinstellung existiert. Wenn die Voreinstellung zu breit + für die Anzeige ist, werden die ersten Buchstaben angegeben, + gefolgt von einem "+".

    + +

    Die dritte und vierte Spalte geben den Kontext an, in dem die + Direktive erlaubt ist, sowie den Status der Direktive entsprechend + der Legende.

    +
    + + + + + + + + +
    sServerkonfiguration
    vVirtual Host
    dVerzeichnis
    h.htaccess
    + + + + + + + + +
    CCore
    MMPM
    BBasis
    EErweiterung
    Xexperimentell
    +
    +
    diff --git a/trunk/docs/manual/mod/quickreference.xml.es b/trunk/docs/manual/mod/quickreference.xml.es new file mode 100644 index 0000000000..b7b492a49f --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml.es @@ -0,0 +1,62 @@ + + + + + + + + + Guía Rápida de Referencia de Directivas + +

    La Guía Rápida de Referencia de Directivas muestra el uso, las + opciones por defecto, el estado y el contexto de cada directiva de + configuración de Apache. Para más información sobre cada + directiva, consulte el Diccionario + de Directivas.

    + +

    La primera columna muestra el nombre y el uso de la directiva. + La segunda columna muestra el valor por defecto de la directiva, + si existe ese valor por defecto. Si el valor por defecto es + demasiado largo para mostrarlo, el primer caracter va seguido de + un signo "+".

    + +

    La tercera y la cuarta columna listan los contextos en los que + la directiva puede funcionar y el estado de la directiva de + acuerdo con las notas que detallan más abajo.

    +
    + + + + + + + + +
    sserver config
    vvirtual host
    ddirectory
    h.htaccess
    + + + + + + + + +
    CCore
    MMPM
    BBase
    EExtensión
    XExperimental
    +
    +
    + diff --git a/trunk/docs/manual/mod/quickreference.xml.ja b/trunk/docs/manual/mod/quickreference.xml.ja new file mode 100644 index 0000000000..5bffb3df86 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml.ja @@ -0,0 +1,60 @@ + + + + + + + + + $B%G%#%l%/%F%#%V(B $B%/%$%C%/%j%U%!%l%s%9(B + +

    $B%G%#%l%/%F%#%V(B $B%/%$%C%/%j%U%!%l%s%9$G$O!"3F(B Apache $B@_Dj%G%#%l%/%F%#%V$N(B + $B;HMQJ}K!!"%G%U%)%k%HCM!"%9%F!<%?%9$H%3%s%F%-%9%H$r<($7$F$$$^$9!#(B + $B3F%G%#%l%/%F%#%V$N!"$h$j>\$7$$>pJs$K4X$7$F$O(B + $B%G%#%l%/%F%#%V<-=q(B$B$r(B + $B$4Mw2<$5$$!#(B

    + +

    $BBh(B 1 $BNsL\$O%G%#%l%/%F%#%V$NL>A0$H;HMQJ}K!$G$9!#(B + $BBh(B 2 $BNsL\$O(B ($B$b$7$"$l$P(B) $B%G%U%)%k%HCM$H$J$C$F$$$^$9!#(B + $B%G%U%)%k%HCM$,D9$9$.$FI=<($7$-$l$J$$>l9g$O!":G=i$NJ8;zNs$N8e$m$K(B + $B!V(B + $B!W$,B3$-$^$9!#(B

    + +

    $BBh(B 3, 4 $BNs$O!"2<$NI=$NCm$C$F!"(B + $B%G%#%l%/%F%#%V$N;HMQ$G$-$k%3%s%F%-%9%H$H!"(B + $B%G%#%l%/%F%#%V$N%9%F!<%?%9$,<($5$l$F$$$^$9!#(B

    +
    + + + + + + + + +
    s$B%5!<%P@_Dj%U%!%$%k(B
    v$B%P!<%A%c%k%[%9%H(B
    d$B%G%#%l%/%H%j(B
    h.htaccess
    + + + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    +
    +
    diff --git a/trunk/docs/manual/mod/quickreference.xml.ko b/trunk/docs/manual/mod/quickreference.xml.ko new file mode 100644 index 0000000000..e049936070 --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml.ko @@ -0,0 +1,56 @@ + + + + + + + + + Áö½Ã¾î ºü¸¥ÂüÁ¶ + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¼³Á¤Áö½Ã¾î °¢°¢ÀÇ ¿ëµµ, ±âº»°ª, »óÅÂ, + »ç¿ëÀå¼Ò¸¦ º¸¿©ÁØ´Ù. À̵éÀº Áö½Ã¾î »çÀü¿¡¼­ ¼³¸íÇÑ´Ù.

    + +

    ù¹ø° ¿­Àº Áö½Ã¾î À̸§°ú ¿ëµµ¸¦ ¾Ë·ÁÁØ´Ù. µÎ¹ø° ¿­Àº + Áö½Ã¾î¿¡ ±âº»°ªÀÌ ÀÖ´Ù¸é ±âº»°ªÀ» º¸¿©ÁØ´Ù. ¸¸¾à ±âº»°ªÀÌ + ³Ê¹« ±æ´Ù¸é, "+" ±âÈ£·Î »ý·«ÇßÀ½À» ¾Ë¸°´Ù.

    + +

    ¼¼¹ø°¿Í ³×¹ø° ¿­Àº °¢°¢ ¾Æ·¡ Ç¥¿¡ µû¶ó Áö½Ã¾î¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Â Àå¼Ò¿Í Áö½Ã¾îÀÇ »óŸ¦ ³ªÅ¸³½´Ù.

    +
    + + + + + + + + +
    sÁÖ¼­¹ö¼³Á¤
    v°¡»óÈ£½ºÆ®
    ddirectory
    h.htaccess
    + + + + + + + + +
    CCore
    MMPM
    BBase
    EExtension
    XExperimental
    +
    +
    diff --git a/trunk/docs/manual/mod/quickreference.xml.meta b/trunk/docs/manual/mod/quickreference.xml.meta new file mode 100644 index 0000000000..394fdfe0ed --- /dev/null +++ b/trunk/docs/manual/mod/quickreference.xml.meta @@ -0,0 +1,15 @@ + + + + quickreference + /mod/ + .. + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/mod/threadpool.html b/trunk/docs/manual/mod/threadpool.html new file mode 100644 index 0000000000..1e9bcdac9f --- /dev/null +++ b/trunk/docs/manual/mod/threadpool.html @@ -0,0 +1,3 @@ +URI: threadpool.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/mod/threadpool.html.en b/trunk/docs/manual/mod/threadpool.html.en new file mode 100644 index 0000000000..10cf7db7a0 --- /dev/null +++ b/trunk/docs/manual/mod/threadpool.html.en @@ -0,0 +1,81 @@ + + + +threadpool - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM threadpool

    +
    +

    Available Languages:  en 

    +
    + + + +
    Description:Yet another experimental variant of the standard +worker MPM
    Status:MPM
    Module Identifier:mpm_threadpool_module
    Source File:threadpool.c
    +

    Summary

    + +

    Warning

    +

    This MPM is a developer playground and highly experimental, so it + may or may not work as expected.

    +
    + +

    This is an experimental variant of the standard worker MPM. + Rather than queuing connections like the worker MPM, the + threadpool MPM queues idle worker threads and + hands each accepted connection to the next available worker.

    + +

    The threadpool MPM can't match the performance of + the worker MPM in benchmark testing. As of 2.0.39, + some of the key load-throtting concepts from the threadpool MPM have been incorporated into the worker MPM. The threadpool code is useful + primarily as a research platform. For general-purpose use and for any + production environments, use worker instead.

    +
    + + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/threadpool.xml b/trunk/docs/manual/mod/threadpool.xml new file mode 100644 index 0000000000..2c4b6f7015 --- /dev/null +++ b/trunk/docs/manual/mod/threadpool.xml @@ -0,0 +1,94 @@ + + + + + + + + +threadpool +Yet another experimental variant of the standard +worker MPM +MPM +threadpool.c +mpm_threadpool_module + + + Warning +

    This MPM is a developer playground and highly experimental, so it + may or may not work as expected.

    +
    + +

    This is an experimental variant of the standard worker MPM. + Rather than queuing connections like the worker MPM, the + threadpool MPM queues idle worker threads and + hands each accepted connection to the next available worker.

    + +

    The threadpool MPM can't match the performance of + the worker MPM in benchmark testing. As of 2.0.39, + some of the key load-throtting concepts from the threadpool MPM have been incorporated into the worker MPM. The threadpool code is useful + primarily as a research platform. For general-purpose use and for any + production environments, use worker instead.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +Listen + +ListenBacklog + +SendBufferSize + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +PidFile + +ScoreBoardFile + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/threadpool.xml.meta b/trunk/docs/manual/mod/threadpool.xml.meta new file mode 100644 index 0000000000..195dbfab50 --- /dev/null +++ b/trunk/docs/manual/mod/threadpool.xml.meta @@ -0,0 +1,11 @@ + + + + threadpool + /mod/ + .. + + + en + + diff --git a/trunk/docs/manual/mod/worker.html b/trunk/docs/manual/mod/worker.html new file mode 100644 index 0000000000..1d429299de --- /dev/null +++ b/trunk/docs/manual/mod/worker.html @@ -0,0 +1,11 @@ +URI: worker.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: worker.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: worker.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/mod/worker.html.de b/trunk/docs/manual/mod/worker.html.de new file mode 100644 index 0000000000..a75a2da1e2 --- /dev/null +++ b/trunk/docs/manual/mod/worker.html.de @@ -0,0 +1,169 @@ + + + +worker - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache-MPM worker

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + + + +
    Beschreibung:Multi-Processing-Modul, das einen Hybrid-Webserver mit + Multi-Thread und Multi-Prozess-Unterstützung implementiert
    Status:MPM
    Modulbezeichner:mpm_worker_module
    Quelltext-Datei:worker.c
    +

    Zusammenfassung

    + +

    Dieses Multi-Processing-Modul (MPM) implementiert einen Hybrid-Server + mit Multi-Thread und Multi-Prozess-Unterstützung. Durch die Verwendung + von Threads für die Bedienung von Anfragen ist er in der Lage, + eine große Anzahl von Anfragen mit weniger Systemressourcen als + ein Prozess-basierter Server zu bedienen. Er behält jedoch viel von + der Stabilität eines Prozess-basierten Servers bei, indem er + mehrere Prozesse verfügbar hält, jeden mit etlichen Threads.

    + +

    Die wichtigsten Direktiven zur Steuerung des MPMs sind ThreadsPerChild, welche die Anzahl + der Threads beeinflusst, die von jedem Kindprozess verwendet werden, und + MaxClients, welche die + maximale Gesamtzahl an Threads regelt, die gestartet werden + können.

    +
    + +
    top
    +
    +

    Arbeitsweise

    +

    Ein einzelner Steuerprozess (der Elternprozess) ist für den + Start der Kindprozesse verantwortlich. Jeder Kindprozess erstellt eine + feste Anzahl von Server-Threads, wie durch die ThreadsPerChild-Direktive + angegeben, sowie einen "Listener-Thread", der auf Verbindungen wartet und + diese an einen Server-Thread zur Bearbeitung weiterreicht, sobald sie + eintreffen.

    + +

    Der Apache versucht immer, einen Vorrat von freien oder + unbeschäftigten Threads zu verwalten, die zur Bedienung + hereinkommender Anfragen bereit stehen. Auf diese Weise brauchen + Clients nicht auf die Erstellung eines neuen Threads oder Prozesses + zu warten, bevor ihre Anfrage bedient werden kann. Die Anzahl der + Prozesse, die anfangs gestartet wird, wird mit der Direktive + StartServers festgelegt. + Dann, während des Betriebes, berechnet der Apache die Gesamtzahl + der unbeschäftigten Threads und forkt oder beendet Prozesse, um diese + Anzahl innerhalb der durch MinSpareThreads und MaxSpareThreads angegebenen Grenzen + zu halten. Da dieser Prozess sehr selbstregulierend ist, ist es nur selten + notwendig, die Voreinstellung dieser Direktiven zu ändern. Die + maximale Anzahl Clients, die gleichzeitig bedient werden kann (d.h. + die maximale Gesamtzahl der Threads in allen Prozessen), wird mit der + Direktive MaxClients + festgelegt. Die maximale Anzahl der aktiven Kindprozesse ergibt sich aus + MaxClients dividiert durch + ThreadsPerChild.

    + +

    Zwei Direktiven legen harte Limits für die Anzahl der aktiven + Kindprozesse fest und können nur geändert werden, indem der Server + komplett gestoppt und dann wieder neu gestartet wird. ServerLimit stellt die obere Grenze für + die Anzahl der aktiven Kindprozesse dar und muss größer oder + gleich dem Quotienten aus MaxClients und ThreadsPerChild sein. ThreadLimit ist die obere Grenze für + die Anzahl der Server-Threads und muss größer oder gleich + ThreadsPerChild sein. Sofern für + diese Direktiven keine Voreinstellungen verwendet werden, sollten sie vor + allen anderen worker-Direktiven platziert werden.

    + +

    Neben den normalen aktiven Kindprozessen gibt es möglicherweise noch + zusätzliche Kindprozesse, welche gerade beendet werden, wo allerdings + zumindest noch ein Server-Thread eine existierende Verbindung bearbeitet. + Obwohl die tatsächlich zu erwartende Anzahl deutlich kleiner ist, + können bis zu MaxClients + solcher Prozesse auftreten. Dieses Verhalten können Sie vermeiden, + indem Sie die Terminierung einzelner Kindprozesse wie folgt abschalten:

    + + + +

    Eine typische Konfiguration der Prozess-Thread-Steuerung für + das MPM worker könnte wie folgt aussehen:

    + +

    + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +

    + +

    Während der Elternprozess unter Unix normalerweise als + root gestartet wird, um sich an Port 80 binden zu können, + werden die Kindprozesse und Threads unter einem weniger privilegierten + Benutzer gestartet. Die Direktiven User und Group werden dazu verwendet, die + Privilegien der Apache-Kindprozesse festzulegen. Die Kindprozesse + müssen in der Lage sein, alle Inhalte zu lesen, die sie ausliefern + sollen, sollten darüber hinaus jedoch so wenig wie möglich Rechte + besitzen. Zusätzlich, solange nicht suexec verwendet wird, legen diese + Direktiven auch die Privilegien fest, die von CGI-Skripts + geerbt werden.

    + +

    MaxRequestsPerChild + bestimmt, wie häufig der Server Prozesse erneuert, indem er alte + beendet und neue startet.

    +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/worker.html.en b/trunk/docs/manual/mod/worker.html.en new file mode 100644 index 0000000000..5374e966ec --- /dev/null +++ b/trunk/docs/manual/mod/worker.html.en @@ -0,0 +1,176 @@ + + + +worker - Apache HTTP Server + + + + + + +
    <-
    + +
    +

    Apache MPM worker

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    Description:Multi-Processing Module implementing a hybrid + multi-threaded multi-process web server
    Status:MPM
    Module Identifier:mpm_worker_module
    Source File:worker.c
    +

    Summary

    + +

    This Multi-Processing Module (MPM) implements a hybrid + multi-process multi-threaded server. By using threads to serve + requests, it is able to serve a large number of requests with + less system resources than a process-based server. Yet it + retains much of the stability of a process-based server by + keeping multiple processes available, each with many threads.

    + +

    The most important directives used to control this MPM are + ThreadsPerChild, which + controls the number of threads deployed by each child process and + MaxClients, which + controls the maximum total number of threads that may be + launched.

    +
    + +
    top
    +
    +

    How it Works

    +

    A single control process (the parent) is responsible for launching + child processes. Each child process creates a fixed number of server + threads as specified in the ThreadsPerChild directive, as well + as a listener thread which listens for connections and passes them + to a server thread for processing when they arrive.

    + +

    Apache always tries to maintain a pool of spare or + idle server threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + threads or processes to be created before their requests can be + served. The number of processes that will initially launched is + set by the StartServers + directive. Then during operation, Apache assesses the total number + of idle threads in all processes, and forks or kills processes to + keep this number within the boundaries specified by MinSpareThreads and MaxSpareThreads. Since this + process is very self-regulating, it is rarely necessary to modify + these directives from their default values. The maximum number of + clients that may be served simultaneously (i.e., the maximum total + number of threads in all processes) is determined by the + MaxClients directive. + The maximum number of active child processes is determined by + the MaxClients + directive divided by the + ThreadsPerChild directive.

    + +

    Two directives set hard limits on the number of active child + processes and the number of server threads in a child process, + and can only be changed by fully stopping the server and then + starting it again. ServerLimit + is a hard limit on the number of active child + processes, and must be greater than or equal to the + MaxClients + directive divided by the + ThreadsPerChild directive. + ThreadLimit is a hard + limit of the number of server threads, and must be greater than + or equal to the ThreadsPerChild directive. If + non-default values are specified for these directives, they + should appear before other worker directives.

    + +

    In addition to a the set of active child processes, there may + be additional child processes which are terminating but where at + least one server thread is still handling an existing client + connection. Up to MaxClients terminating processes + may be present, though the actual number can be expected to be + much smaller. This behavior can be avoided by disabling the + termination of individual child processes, which is achieved by + the following:

    + + + +

    A typical configuration of the process-thread controls in + the worker MPM could look as follows:

    + +

    + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +

    + +

    While the parent process is usually started as root + under Unix in order to bind to port 80, the child processes and threads + are launched by Apache as a less-privileged user. The User and Group directives are used to set + the privileges of the Apache child processes. The child processes + must be able to read all the content that will be served, but + should have as few privileges beyond that as possible. In + addition, unless suexec is used, + these directives also set the privileges which will be inherited + by CGI scripts.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing + old ones and launching new ones.

    +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/worker.html.ja.euc-jp b/trunk/docs/manual/mod/worker.html.ja.euc-jp new file mode 100644 index 0000000000..d68b8d7f21 --- /dev/null +++ b/trunk/docs/manual/mod/worker.html.ja.euc-jp @@ -0,0 +1,185 @@ + + + +worker - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +
    +

    Apache MPM worker

    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + + + +
    ÀâÌÀ:¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤È¥Þ¥ë¥Á¥×¥í¥»¥¹¤Î¥Ï¥¤¥Ö¥ê¥Ã¥É·¿ +¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼ÂÁõ¤·¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë
    ¥¹¥Æ¡¼¥¿¥¹:MPM
    ¥â¥¸¥å¡¼¥ë¼±ÊÌ»Ò:mpm_worker_module
    ¥½¡¼¥¹¥Õ¥¡¥¤¥ë:worker.c
    +

    ³µÍ×

    + +

    ¤³¤Î¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) + ¤Ï¡¢¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤È¥Þ¥ë¥Á¥×¥í¥»¥¹¤Î¥Ï¥¤¥Ö¥ê¥Ã¥É·¿¥µ¡¼¥Ð¤ò + ¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£¥ê¥¯¥¨¥¹¥È¤Î±þÅú¤Ë¥¹¥ì¥Ã¥É¤ò»È¤¦¤È¡¢ + ¥×¥í¥»¥¹¥Ù¡¼¥¹¤Î¥µ¡¼¥Ð¤è¤ê¤â¾¯¤Ê¤¤¥·¥¹¥Æ¥à»ñ¸»¤Ç¡¢ + ¿¤¯¤Î¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤µ¤é¤Ë¡¢Â¿¤¯¤Î¥¹¥ì¥Ã¥É¤ò»ý¤Ã¤¿Ê£¿ô¤Î¥×¥í¥»¥¹¤ò°Ý»ý¤¹¤ë¤³¤È¤Ç¡¢ + ¥×¥í¥»¥¹¥Ù¡¼¥¹¤Î¥µ¡¼¥Ð¤Î»ý¤Ä°ÂÄêÀ­¤òÊÝ»ý¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤³¤Î MPM ¤òÀ©¸æ¤¹¤ë¤Î¤Ë»È¤ï¤ì¤ëºÇ¤â½ÅÍפʥǥ£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ThreadsPerChild ¤È + MaxClients ¤Ç¤¹¡£ + ThreadsPerChild ¤Ï + ³Æ»Ò¥×¥í¥»¥¹¤ÇÍÑ°Õ¤µ¤ì¤ë¥¹¥ì¥Ã¥É¿ô¤òÀ©¸æ¤·¤Æ¡¢ + MaxClients ¤Ï + µ¯Æ°¤µ¤ì¤ë¥¹¥ì¥Ã¥É¤ÎÁí¿ô¤ÎºÇÂçÃͤòÀ©¸Â¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    Æ°ºîÊýË¡

    +

    °ì¤Ä¤ÎÀ©¸æÍÑ¥×¥í¥»¥¹ (¿Æ) ¤¬»Ò¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤Ï + ThreadsPerChild + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄꤵ¤ì¤¿°ìÄê¿ô¤Î¥µ¡¼¥Ð¥¹¥ì¥Ã¥É¤ÈÀܳ¤ò + listen ¤¹¤ë¥¹¥ì¥Ã¥É¤ò°ì¤Äºî¤ê¤Þ¤¹¡£ + Listener ¥¹¥ì¥Ã¥É¤ÏÀܳ¤¬Í褿¤È¤­¤Ë¥µ¡¼¥Ð¥×¥í¥»¥¹¤ËÅϤ·¤Þ¤¹¡£

    + +

    Apache ¤Ï¥¹¥Ú¥¢¤Î¡¢¤Ä¤Þ¤ê¥¢¥¤¥É¥ë¤Ê¥µ¡¼¥Ð¥¹¥ì¥Ã¥É¤Î + ¥×¡¼¥ë¤ò¾ï¤Ë°Ý»ý¤·¤Æ¤¤¤Æ¡¢¤½¤ì¤é¤ÏÆþ¤Ã¤Æ¤¯¤ë¥ê¥¯¥¨¥¹¥È¤Ë + Åú¤¨¤é¤ì¤ë¤è¤¦¤ËÂÔµ¡¤·¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë¤·¤Æ¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï¥ê¥¯¥¨¥¹¥È¤Î±þÅú¤¬ÆÀ¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¤¿¤á¤Ë + ¿·¤·¤¤¥¹¥ì¥Ã¥É¤ä¥×¥í¥»¥¹¤¬À¸À®¤µ¤ì¤ë¤Î¤ò + ÂÔ¤¿¤Ê¤¯¤Æ¤â¤è¤¤¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + µ¯Æ°½é´ü»þ¤Î¥×¥í¥»¥¹Áí¿ô¤Ï¡¢ + StartServers + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤵ¤ì¤Þ¤¹¡£¤½¤Î¸å¤Î²ÔƯÃæ¤Ë¡¢ + Apache ¤ÏÁ´¥×¥í¥»¥¹¤Î¥¢¥¤¥É¥ë¥¹¥ì¥Ã¥É¤Î¹ç·×¿ô¤ò¸«ÀѤâ¤Ã¤Æ¡¢ + MinSpareThreads ¤È + MaxSpareThreads + ¤Ç»ØÄꤵ¤ì¤¿ÈϰϤÎÃæ¤Ë¤³¤Î¿ô¤¬¼ý¤Þ¤ë¤è¤¦¤Ë fork ¤·¤¿¤ê + kill ¤·¤¿¤ê¤·¤Þ¤¹¡£¤³¤ÎÁàºî¤ÏÈó¾ï¤Ë¼«Î§Åª¤Ê¤Î¤Ç¡¢ + ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥Ç¥Õ¥©¥ë¥ÈÃͤ«¤éÊѹ¹¤¹¤ëɬÍ×¤Ï + ¤á¤Ã¤¿¤Ë¤Ê¤¤¤Ç¤·¤ç¤¦¡£ + Ʊ»þ¤Ë±þÅú¤¹¤ë¤³¤È¤Î¤Ç¤­¤ë¥¯¥é¥¤¥¢¥ó¥È¿ô¤ÎºÇÂç¿ô + (¤Ä¤Þ¤êÁ´¥×¥í¥»¥¹Ãæ¤ÎÁí¥¹¥ì¥Ã¥É¿ô¤ÎºÇÂçÃÍ) ¤Ï + MaxClients + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç·èÄꤵ¤ì¤Þ¤¹¡£ + ³èÆ°Ãæ¤Î»Ò¥×¥í¥»¥¹¿ô¤ÎºÇÂçÃÍ¤Ï + MaxClients ¤ò + ThreadsPerChild ¤Ç³ä¤Ã¤¿ + ¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ³èÆ°Ãæ¤Î»Ò¥×¥í¥»¥¹¤Î¿ô¤È»Ò¥×¥í¥»¥¹Ãæ¤Î¥µ¡¼¥Ð¥¹¥ì¥Ã¥É¤Î¿ô¤Î±Û¤¨¤é¤ì¤Ê¤¤ + ¾å¸Â¤òÀßÄꤹ¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Æó¤Ä¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Ï¥µ¡¼¥Ð¤ò + ´°Á´¤ËÄä»ß¤·¤Æ¡¢ºÆµ¯Æ°¤¹¤ë¤³¤È¤Ç¤·¤«Êѹ¹¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ServerLimit + ¤Ï³èÆ°Ãæ¤Î»Ò¥×¥í¥»¥¹¤Î±Û¤¨¤é¤ì¤Ê¤¤¾å¸Â¤òÀßÄꤷ¡¢ + MaxClients ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ÎÃͤò + ThreadsPerChild ¤ÎÃͤdzä¤Ã¤¿ÃͰʾå¤Ç¤¢¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£ThreadLimit ¤Ï + ¥µ¡¼¥Ð¥¹¥ì¥Ã¥É¤Î±Û¤¨¤é¤ì¤Ê¤¤¾å¸Â¤Ç¡¢ThreadsPerChild ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î + ÃͰʾå¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È°Ê³°¤ÎÃͤò»ØÄꤹ¤ë¾ì¹ç¤Ï + ¾¤Î worker ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤è¤ê¤âÁ°¤Ë½ñ¤«¤ì¤Æ¤¤¤ë + ɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ³èÆ°Ãæ¤Î»Ò¥×¥í¥»¥¹·²¤Ë²Ã¤¨¤Æ¡¢¾¯¤Ê¤¯¤È¤â°ì¤Ä¤Î¥µ¡¼¥Ð¥¹¥ì¥Ã¥É¤¬ + ´û¸¤Î¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤ÎÀܳ¤ò°·¤Ã¤Æ¤¤¤ë½ªÎ»¤·¤è¤¦¤È¤·¤Æ¤¤¤ë + »Ò¥×¥í¥»¥¹¤¬¤¢¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£½ªÎ»Ãæ¤Î¥×¥í¥»¥¹¤Ï MaxClients ¤Ç»ØÄꤵ¤ì¤¿¿ô¤Þ¤Ç + ¸ºß¤Ç¤­¤Þ¤¹¤¬¡¢¼ÂºÝ¤Ë´üÂÔ¤µ¤ì¤ë¿ô¤Ï¤º¤Ã¤È¾¯¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£¤³¤Î + ¿¶Éñ¤¤¤Ï³Æ»Ò¥×¥í¥»¥¹¤ò½ªÎ»¤µ¤»¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤³¤È¤Ç²óÈò¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï°Ê²¼¤ÎÍͤˤ·¤Æ¼Â¸½¤Ç¤­¤Þ¤¹¡£

    + + + +

    worker MPM ¤Îŵ·¿Åª¤Ê¥×¥í¥»¥¹¡¦¥¹¥ì¥Ã¥ÉÀ©¸æ¤Î + ÀßÄê¤Ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +

    + +

    Ä̾ï Unix ¤Ç¤Ï¿Æ¥×¥í¥»¥¹¤Ï 80 È֥ݡ¼¥È¤Ë¥Ð¥¤¥ó¥É¤¹¤ë¤¿¤á¤Ë + root ¤Çµ¯Æ°¤µ¤ì¤Þ¤¹¤¬¡¢»Ò¥×¥í¥»¥¹¤ä¥¹¥ì¥Ã¥É¤Ï + ¤â¤Ã¤ÈÄ㤤¸¢¸Â¤Î¥æ¡¼¥¶¤Ç Apache ¤Ë¤è¤Ã¤Æµ¯Æ°¤µ¤ì¤Þ¤¹¡£ + User ¤È + Group ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + Apache ¤Î»Ò¥×¥í¥»¥¹¤Î¸¢¸Â¤òÀßÄꤹ¤ë¤Î¤ËÍѤ¤¤é¤ì¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤ë¥³¥ó¥Æ¥ó¥ÄÁ´¤Æ¤òÆɤá¤Ê¤¤¤È¤¤¤±¤Þ¤»¤ó¤¬¡¢ + ²Äǽ¤Ê¸Â¤êɬÍ׺Ǿ®¸Â¤Î¸¢¸Â¤Î¤ß¤ò»ý¤Ã¤Æ¤¤¤ë¤è¤¦¤Ë¤¹¤ë¤Ù¤­¤Ç¤¹¡£ + ¤µ¤é¤Ë¡¢suexec + ¤¬»ÈÍѤµ¤ì¤Æ¤¤¤Ê¤¤¸Â¤ê¡¢¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + CGI ¥¹¥¯¥ê¥×¥È¤Ç·Ñ¾µ¤µ¤ì¤ë¸¢¸Â¤âÀßÄꤷ¤Þ¤¹¡£

    + +

    MaxRequestsPerChild + ¤Ï¡¢¸Å¤¤¥×¥í¥»¥¹¤òÄä»ß¤·¤Æ¿·¤·¤¤¥×¥í¥»¥¹¤òµ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ¤É¤ÎÄøÅÙ¤ÎÉÑÅ٤ǥµ¡¼¥Ð¤¬¥×¥í¥»¥¹¤ò¥ê¥µ¥¤¥¯¥ë¤¹¤ë¤«¤òÀ©¸æ¤·¤Þ¤¹¡£

    +
    +
    +
    +

    Available Languages:  de  | + en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mod/worker.xml b/trunk/docs/manual/mod/worker.xml new file mode 100644 index 0000000000..f68520fdac --- /dev/null +++ b/trunk/docs/manual/mod/worker.xml @@ -0,0 +1,185 @@ + + + + + + + + +worker +Multi-Processing Module implementing a hybrid + multi-threaded multi-process web server +MPM +worker.c +mpm_worker_module + + +

    This Multi-Processing Module (MPM) implements a hybrid + multi-process multi-threaded server. By using threads to serve + requests, it is able to serve a large number of requests with + less system resources than a process-based server. Yet it + retains much of the stability of a process-based server by + keeping multiple processes available, each with many threads.

    + +

    The most important directives used to control this MPM are + ThreadsPerChild, which + controls the number of threads deployed by each child process and + MaxClients, which + controls the maximum total number of threads that may be + launched.

    +
    +Setting which addresses and ports Apache +uses + +
    How it Works +

    A single control process (the parent) is responsible for launching + child processes. Each child process creates a fixed number of server + threads as specified in the ThreadsPerChild directive, as well + as a listener thread which listens for connections and passes them + to a server thread for processing when they arrive.

    + +

    Apache always tries to maintain a pool of spare or + idle server threads, which stand ready to serve incoming + requests. In this way, clients do not need to wait for a new + threads or processes to be created before their requests can be + served. The number of processes that will initially launched is + set by the StartServers + directive. Then during operation, Apache assesses the total number + of idle threads in all processes, and forks or kills processes to + keep this number within the boundaries specified by MinSpareThreads and MaxSpareThreads. Since this + process is very self-regulating, it is rarely necessary to modify + these directives from their default values. The maximum number of + clients that may be served simultaneously (i.e., the maximum total + number of threads in all processes) is determined by the + MaxClients directive. + The maximum number of active child processes is determined by + the MaxClients + directive divided by the + ThreadsPerChild directive.

    + +

    Two directives set hard limits on the number of active child + processes and the number of server threads in a child process, + and can only be changed by fully stopping the server and then + starting it again. ServerLimit + is a hard limit on the number of active child + processes, and must be greater than or equal to the + MaxClients + directive divided by the + ThreadsPerChild directive. + ThreadLimit is a hard + limit of the number of server threads, and must be greater than + or equal to the ThreadsPerChild directive. If + non-default values are specified for these directives, they + should appear before other worker directives.

    + +

    In addition to a the set of active child processes, there may + be additional child processes which are terminating but where at + least one server thread is still handling an existing client + connection. Up to MaxClients terminating processes + may be present, though the actual number can be expected to be + much smaller. This behavior can be avoided by disabling the + termination of individual child processes, which is achieved by + the following:

    + +
      +
    • set the value of + MaxRequestsPerChild to zero
    • + +
    • set the value of + MaxSpareThreads to the same value as + MaxClients
    • +
    + +

    A typical configuration of the process-thread controls in + the worker MPM could look as follows:

    + + + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +
    + +

    While the parent process is usually started as root + under Unix in order to bind to port 80, the child processes and threads + are launched by Apache as a less-privileged user. The User and Group directives are used to set + the privileges of the Apache child processes. The child processes + must be able to read all the content that will be served, but + should have as few privileges beyond that as possible. In + addition, unless suexec is used, + these directives also set the privileges which will be inherited + by CGI scripts.

    + +

    MaxRequestsPerChild + controls how frequently the server recycles processes by killing + old ones and launching new ones.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/worker.xml.de b/trunk/docs/manual/mod/worker.xml.de new file mode 100644 index 0000000000..1fbf0da722 --- /dev/null +++ b/trunk/docs/manual/mod/worker.xml.de @@ -0,0 +1,185 @@ + + + + + + + + +worker +Multi-Processing-Modul, das einen Hybrid-Webserver mit + Multi-Thread und Multi-Prozess-Unterstützung implementiert +MPM +worker.c +mpm_worker_module + + +

    Dieses Multi-Processing-Modul (MPM) implementiert einen Hybrid-Server + mit Multi-Thread und Multi-Prozess-Unterstützung. Durch die Verwendung + von Threads für die Bedienung von Anfragen ist er in der Lage, + eine große Anzahl von Anfragen mit weniger Systemressourcen als + ein Prozess-basierter Server zu bedienen. Er behält jedoch viel von + der Stabilität eines Prozess-basierten Servers bei, indem er + mehrere Prozesse verfügbar hält, jeden mit etlichen Threads.

    + +

    Die wichtigsten Direktiven zur Steuerung des MPMs sind ThreadsPerChild, welche die Anzahl + der Threads beeinflusst, die von jedem Kindprozess verwendet werden, und + MaxClients, welche die + maximale Gesamtzahl an Threads regelt, die gestartet werden + können.

    +
    +Bestimmen der vom Apache verwendeten Adressen + und Ports + +
    Arbeitsweise +

    Ein einzelner Steuerprozess (der Elternprozess) ist für den + Start der Kindprozesse verantwortlich. Jeder Kindprozess erstellt eine + feste Anzahl von Server-Threads, wie durch die ThreadsPerChild-Direktive + angegeben, sowie einen "Listener-Thread", der auf Verbindungen wartet und + diese an einen Server-Thread zur Bearbeitung weiterreicht, sobald sie + eintreffen.

    + +

    Der Apache versucht immer, einen Vorrat von freien oder + unbeschäftigten Threads zu verwalten, die zur Bedienung + hereinkommender Anfragen bereit stehen. Auf diese Weise brauchen + Clients nicht auf die Erstellung eines neuen Threads oder Prozesses + zu warten, bevor ihre Anfrage bedient werden kann. Die Anzahl der + Prozesse, die anfangs gestartet wird, wird mit der Direktive + StartServers festgelegt. + Dann, während des Betriebes, berechnet der Apache die Gesamtzahl + der unbeschäftigten Threads und forkt oder beendet Prozesse, um diese + Anzahl innerhalb der durch MinSpareThreads und MaxSpareThreads angegebenen Grenzen + zu halten. Da dieser Prozess sehr selbstregulierend ist, ist es nur selten + notwendig, die Voreinstellung dieser Direktiven zu ändern. Die + maximale Anzahl Clients, die gleichzeitig bedient werden kann (d.h. + die maximale Gesamtzahl der Threads in allen Prozessen), wird mit der + Direktive MaxClients + festgelegt. Die maximale Anzahl der aktiven Kindprozesse ergibt sich aus + MaxClients dividiert durch + ThreadsPerChild.

    + +

    Zwei Direktiven legen harte Limits für die Anzahl der aktiven + Kindprozesse fest und können nur geändert werden, indem der Server + komplett gestoppt und dann wieder neu gestartet wird. ServerLimit stellt die obere Grenze für + die Anzahl der aktiven Kindprozesse dar und muss größer oder + gleich dem Quotienten aus MaxClients und ThreadsPerChild sein. ThreadLimit ist die obere Grenze für + die Anzahl der Server-Threads und muss größer oder gleich + ThreadsPerChild sein. Sofern für + diese Direktiven keine Voreinstellungen verwendet werden, sollten sie vor + allen anderen worker-Direktiven platziert werden.

    + +

    Neben den normalen aktiven Kindprozessen gibt es möglicherweise noch + zusätzliche Kindprozesse, welche gerade beendet werden, wo allerdings + zumindest noch ein Server-Thread eine existierende Verbindung bearbeitet. + Obwohl die tatsächlich zu erwartende Anzahl deutlich kleiner ist, + können bis zu MaxClients + solcher Prozesse auftreten. Dieses Verhalten können Sie vermeiden, + indem Sie die Terminierung einzelner Kindprozesse wie folgt abschalten:

    + +
      +
    • setzen Sie den Wert von MaxRequestsPerChild auf Null
    • + +
    • setzen Sie den Wert von MaxSpareThreads auf den gleichen Wert wie MaxClients
    • +
    + +

    Eine typische Konfiguration der Prozess-Thread-Steuerung für + das MPM worker könnte wie folgt aussehen:

    + + + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +
    + +

    Während der Elternprozess unter Unix normalerweise als + root gestartet wird, um sich an Port 80 binden zu können, + werden die Kindprozesse und Threads unter einem weniger privilegierten + Benutzer gestartet. Die Direktiven User und Group werden dazu verwendet, die + Privilegien der Apache-Kindprozesse festzulegen. Die Kindprozesse + müssen in der Lage sein, alle Inhalte zu lesen, die sie ausliefern + sollen, sollten darüber hinaus jedoch so wenig wie möglich Rechte + besitzen. Zusätzlich, solange nicht + suexec verwendet wird, legen diese + Direktiven auch die Privilegien fest, die von CGI-Skripts + geerbt werden.

    + +

    MaxRequestsPerChild + bestimmt, wie häufig der Server Prozesse erneuert, indem er alte + beendet und neue startet.

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/worker.xml.ja b/trunk/docs/manual/mod/worker.xml.ja new file mode 100644 index 0000000000..678b4980d9 --- /dev/null +++ b/trunk/docs/manual/mod/worker.xml.ja @@ -0,0 +1,190 @@ + + + + + + + + + +worker +$B%^%k%A%9%l%C%I$H%^%k%A%W%m%;%9$N%O%$%V%j%C%I7?(B +$B%&%'%V%5!<%P$r +MPM +worker.c +mpm_worker_module + + +

    $B$3$N%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) + $B$O!"%^%k%A%9%l%C%I$H%^%k%A%W%m%;%9$N%O%$%V%j%C%I7?%5!<%P$r(B + $B/$J$$%7%9%F%`;q8;$G!"(B + $BB?$/$N%j%/%(%9%H$K1~Ez$9$k$3$H$,$G$-$^$9!#(B + $B$5$i$K!"B?$/$N%9%l%C%I$r;}$C$?J#?t$N%W%m%;%9$r0];}$9$k$3$H$G!"(B + $B%W%m%;%9%Y!<%9$N%5!<%P$N;}$D0BDj@-$rJ];}$7$F$$$^$9!#(B

    + +

    $B$3$N(B MPM $B$r@)8f$9$k$N$K;H$o$l$k:G$b=EMW$J%G%#%l%/%F%#%V$O!"(B + ThreadsPerChild $B$H(B + MaxClients $B$G$9!#(B + ThreadsPerChild $B$O(B + $B3F;R%W%m%;%9$GMQ0U$5$l$k%9%l%C%I?t$r@)8f$7$F!"(B + MaxClients $B$O(B + $B5/F0$5$l$k%9%l%C%I$NAm?t$N:GBgCM$r@)8B$7$^$9!#(B

    +
    +Apache +$B$N;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj(B + +
    $BF0:nJ}K!(B +

    $B0l$D$N@)8fMQ%W%m%;%9(B ($B?F(B) $B$,;R%W%m%;%9$r5/F0$7$^$9!#(B + $B;R%W%m%;%9$O(B + ThreadsPerChild + $B%G%#%l%/%F%#%V$G;XDj$5$l$?0lDj?t$N%5!<%P%9%l%C%I$H@\B3$r(B + listen $B$9$k%9%l%C%I$r0l$D:n$j$^$9!#(B + Listener $B%9%l%C%I$O@\B3$,Mh$?$H$-$K%5!<%P%W%m%;%9$KEO$7$^$9!#(B

    + +

    Apache $B$O(B$B%9%Z%"$N(B$B!"$D$^$j%"%$%I%k$J%5!<%P%9%l%C%I$N(B + $B%W!<%k$r>o$K0];}$7$F$$$F!"$=$l$i$OF~$C$F$/$k%j%/%(%9%H$K(B + $BEz$($i$l$k$h$&$KBT5!$7$F$$$^$9!#(B + $B$3$N$h$&$K$7$F!"%/%i%$%"%s%H$O%j%/%(%9%H$N1~Ez$,F@$i$l$k$h$&$K$J$k$?$a$K(B + $B?7$7$$%9%l%C%I$d%W%m%;%9$,@8@.$5$l$k$N$r(B + $BBT$?$J$/$F$b$h$$$h$&$K$J$C$F$$$^$9!#(B + $B5/F0=i4|;~$N%W%m%;%9Am?t$O!"(B + StartServers + $B%G%#%l%/%F%#%V$G@_Dj$5$l$^$9!#$=$N8e$N2TF/Cf$K!"(B + Apache $B$OA4%W%m%;%9$N%"%$%I%k%9%l%C%I$N9g7W?t$r8+@Q$b$C$F!"(B + MinSpareThreads $B$H(B + MaxSpareThreads + $B$G;XDj$5$l$?HO0O$NCf$K$3$N?t$,<}$^$k$h$&$K(B fork $B$7$?$j(B + kill $B$7$?$j$7$^$9!#$3$NA`:n$OHs>o$K<+N'E*$J$N$G!"(B + $B$3$l$i$N%G%#%l%/%F%#%V$r%G%U%)%k%HCM$+$iJQ99$9$kI,MW$O(B + $B$a$C$?$K$J$$$G$7$g$&!#(B + $BF1;~$K1~Ez$9$k$3$H$N$G$-$k%/%i%$%"%s%H?t$N:GBg?t(B + ($B$D$^$jA4%W%m%;%9Cf$NAm%9%l%C%I?t$N:GBgCM(B) $B$O(B + MaxClients + $B%G%#%l%/%F%#%V$G7hDj$5$l$^$9!#(B + $B3hF0Cf$N;R%W%m%;%9?t$N:GBgCM$O(B + MaxClients $B$r(B + ThreadsPerChild $B$G3d$C$?(B + $B$b$N$K$J$j$^$9!#(B

    + +

    $B3hF0Cf$N;R%W%m%;%9$N?t$H;R%W%m%;%9Cf$N%5!<%P%9%l%C%I$N?t$N1[$($i$l$J$$(B + $B>e8B$r@_Dj$9$k%G%#%l%/%F%#%V$,Fs$D$"$j$^$9!#$3$l$i$O%5!<%P$r(B + $B40A4$KDd;_$7$F!":F5/F0$9$k$3$H$G$7$+JQ99$9$k$3$H$O$G$-$^$;$s!#(B + ServerLimit + $B$O3hF0Cf$N;R%W%m%;%9$N1[$($i$l$J$$>e8B$r@_Dj$7!"(B + MaxClients $B%G%#%l%/%F%#%V(B + $B$NCM$r(B + ThreadsPerChild $B$NCM$G3d$C$?CM0J>e$G$"$k(B + $BI,MW$,$"$j$^$9!#(BThreadLimit $B$O(B + $B%5!<%P%9%l%C%I$N1[$($i$l$J$$>e8B$G!"(BThreadsPerChild $B%G%#%l%/%F%#%V$N(B + $BCM0J>e$G$"$kI,MW$,$"$j$^$9!#%G%U%)%k%H0J30$NCM$r;XDj$9$k>l9g$O(B + $BB>$N(B worker $B%G%#%l%/%F%#%V$h$j$bA0$K=q$+$l$F$$$k(B + $BI,MW$,$"$j$^$9!#(B

    + +

    $B3hF0Cf$N;R%W%m%;%972$K2C$($F!">/$J$/$H$b0l$D$N%5!<%P%9%l%C%I$,(B + $B4{B8$N%/%i%$%"%s%H$+$i$N@\B3$r07$C$F$$$k=*N;$7$h$&$H$7$F$$$k(B + $B;R%W%m%;%9$,$"$k2DG=@-$,$"$j$^$9!#=*N;Cf$N%W%m%;%9$O(B MaxClients $B$G;XDj$5$l$??t$^$G(B + $BB8:_$G$-$^$9$,!"/$J$/$J$j$^$9!#$3$N(B + $B?6Iq$$$O3F;R%W%m%;%9$r=*N;$5$;$J$$$h$&$K$9$k$3$H$G2sHr$G$-$^$9!#(B + $B$3$l$O0J2<$NMM$K$7$F + +

      +
    • + MaxRequestsPerChild $B$NCM$r(B 0 $B$K@_Dj$9$k(B
    • + +
    • + MaxSpareThreads $B$NCM$r(B + MaxClients + $B$HF1$8CM$K$9$k(B
    • +
    + +

    worker MPM $B$NE57?E*$J%W%m%;%9!&%9%l%C%I@)8f$N(B + $B@_Dj$G$O!" + + + ServerLimit 16
    + StartServers 2
    + MaxClients 150
    + MinSpareThreads 25
    + MaxSpareThreads 75
    + ThreadsPerChild 25 +
    + +

    $BDL>o(B Unix $B$G$O?F%W%m%;%9$O(B 80 $BHV%]!<%H$K%P%$%s%I$9$k$?$a$K(B + root $B$G5/F0$5$l$^$9$,!";R%W%m%;%9$d%9%l%C%I$O(B + $B$b$C$HDc$$8"8B$N%f!<%6$G(B Apache $B$K$h$C$F5/F0$5$l$^$9!#(B + User $B$H(B + Group $B%G%#%l%/%F%#%V$O(B + Apache $B$N;R%W%m%;%9$N8"8B$r@_Dj$9$k$N$KMQ$$$i$l$^$9!#(B + $B;R%W%m%;%9$O%/%i%$%"%s%H$KAw$k%3%s%F%s%DA4$F$rFI$a$J$$$H$$$1$^$;$s$,!"(B + $B2DG=$J8B$jI,MW:G>.8B$N8"8B$N$_$r;}$C$F$$$k$h$&$K$9$k$Y$-$G$9!#(B + $B$5$i$K!"(Bsuexec + $B$,;HMQ$5$l$F$$$J$$8B$j!"$3$l$i$N%G%#%l%/%F%#%V$O(B + CGI $B%9%/%j%W%H$G7Q>5$5$l$k8"8B$b@_Dj$7$^$9!#(B

    + +

    MaxRequestsPerChild + $B$O!"8E$$%W%m%;%9$rDd;_$7$F?7$7$$%W%m%;%9$r5/F0$9$k$3$H$K$h$C$F!"(B + $B$I$NDxEY$NIQEY$G%5!<%P$,%W%m%;%9$r%j%5%$%/%k$9$k$+$r@)8f$7$^$9!#(B

    +
    + +AcceptMutex + +CoreDumpDirectory + +EnableExceptionHook + +Group + +PidFile + +Listen + +ListenBacklog + +LockFile + +MaxClients + +MaxMemFree + +MaxRequestsPerChild + +MaxSpareThreads + +MinSpareThreads + +ScoreBoardFile + +SendBufferSize + +ServerLimit + +StartServers + +ThreadLimit + +ThreadsPerChild + +ThreadStackSize + +User + + +
    diff --git a/trunk/docs/manual/mod/worker.xml.meta b/trunk/docs/manual/mod/worker.xml.meta new file mode 100644 index 0000000000..0fda0aee7f --- /dev/null +++ b/trunk/docs/manual/mod/worker.xml.meta @@ -0,0 +1,13 @@ + + + + worker + /mod/ + .. + + + de + en + ja + + diff --git a/trunk/docs/manual/mpm.html b/trunk/docs/manual/mpm.html new file mode 100644 index 0000000000..c34f5f0445 --- /dev/null +++ b/trunk/docs/manual/mpm.html @@ -0,0 +1,19 @@ +URI: mpm.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: mpm.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: mpm.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/mpm.html.de b/trunk/docs/manual/mpm.html.de new file mode 100644 index 0000000000..8538a1c20b --- /dev/null +++ b/trunk/docs/manual/mpm.html.de @@ -0,0 +1,127 @@ + + + +Multi-Processing-Module (MPMs) - Apache HTTP Server + + + + + +
    <-
    +

    Multi-Processing-Module (MPMs)

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Das Dokument beschreibt, was ein Multi-Processing-Modul ist und wie solche + Module beim Apache HTTP Server verwendet werden.

    +
    + +
    top
    +
    +

    Einführung

    + +

    Der Apache HTTP Server wurde als leistungsfähiger und flexibler Webserver + konzipiert, der auf einer Vielzahl von Plattformen in einer + Reihe unterschiedlicher Umgebungen arbeiten kann. Unterschiedliche + Plattformen und unterschiedliche Umgebungen verlangen oftmals verschiedene + Fähigkeiten oder kennen verschiedene Wege, die gleiche + Funktionaltät sehr effizient zu implementieren. Der Apache hat durch + seinen modularen Aufbau schon immer eine breite Auswahl von Umgebungen + unterstützt. Dieses Design erlaubt es dem Webmaster, durch Auswahl der + Module, die zur Kompilierungszeit oder zur Laufzeit geladen werden, die + Features auszuwählen, die in den Server intregiert werden.

    + +

    Der Apache 2.0 erweitert dieses modulare Design auf die grundlegenden + Funktionen eines Webservers. Der Server wird mit einer Auswahl von + Multi-Processing-Modulen (MPMs) ausgeliefert, die für die Bindung an + Netzwerkports der Maschine, die Annahme von Anfragen und die Abfertigung von + Kindprozessen zur Behandlung der Anfragen zuständig sind.

    + +

    Die Erweiterung des modularen Aufbaus auf diese Ebene des Servers + bringt zwei wesentliche Vorteile:

    + +
      +
    • Der Apache kann nun eine Vielfalt von Betriebssystemen sauberer und + effizienter unterstützen. Insbesondere die Windows-Version des Apache + ist jetzt deutlich effizienter, da mpm_winnt native + Netzwerkfähigkeiten anstelle der im Apache 1.3 verwendeten + POSIX-Schicht benutzen kann. Dieser Vorteil gilt auch für andere + Betriebssysteme, für die spezielle MPMs implementiert sind.
    • + +
    • Der Server läßt sich besser auf die Bedürfnisse der + jeweiligen Website anpassen. Sites beispielsweise, die eine hohe + Skalierbarkeit benötigen, können ein Threaded-MPM wie + worker oder event wählen, + während Sites, die Stabilität oder Kompatibilität mit + älterer Software erfordern, prefork wählen + können. Darüber hinaus können Spezialfähigkeiten wie + die Bedienung verschiedener Hosts unter unterschiedlichen User-IDs + (perchild) angeboten werden.
    • +
    + +

    Auf Anwenderebene erscheinen MPMs fast wie andere Apache-Module. Der + Hauptunterschied ist, dass jeweils nur ein einziges MPM in den Server + geladen werden kann. Die Liste der verfügbaren MPMs finden Sie im Modul-Index.

    + +
    top
    +
    +

    Auswahl eines MPMs

    + +

    MPMs müssen während der + (Anm.d.Ü.: Quelltext-)Konfiguration ausgewählt und in den + Server einkompiliert werden. Compiler sind in der Lage eine Reihe von + Funktionen zu optimieren, wenn Threads verwendet werden. Sie können + dies allerdings nur, wenn sie wissen, dass Threads benutzt werden.

    + +

    Um das gewünschte MPM tatsächlich auszuwählen, verwenden Sie + beim configure-Skript das Argument + --with-mpm=NAME. NAME ist der Name des + gewünschten MPMs.

    + +

    Ist der Server kompiliert, so ist es mittels ./httpd -l + möglich, das ausgewählte MPM zu ermitteln. Dieser Befehl listet + alle in den Server einkompilierten Module auf, einschließlich des + MPM.

    +
    top
    +
    +

    MPM-Voreinstellungen

    + +

    Die folgende Tabelle gibt die voreingestellten MPMs für verschiedene + Betriebssysteme an. Wenn Sie während der Kompilierung keine andere + Auswahl treffen, wird dieses MPM gewählt.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mpm.html.en b/trunk/docs/manual/mpm.html.en new file mode 100644 index 0000000000..6f7434f7f1 --- /dev/null +++ b/trunk/docs/manual/mpm.html.en @@ -0,0 +1,128 @@ + + + +Multi-Processing Modules (MPMs) - Apache HTTP Server + + + + + +
    <-
    +

    Multi-Processing Modules (MPMs)

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    This document describes what a Multi-Processing Module is and +how they are used by the Apache HTTP Server.

    +
    + +
    top
    +
    +

    Introduction

    + +

    The Apache HTTP Server is designed to be a powerful and + flexible web server that can work on a very wide variety of + platforms in a range of different environments. Different + platforms and different environments often require different + features, or may have different ways of implementing the same + feature most efficiently. Apache has always accommodated a wide + variety of environments through its modular design. This design + allows the webmaster to choose which features will be included + in the server by selecting which modules to load either at + compile-time or at run-time.

    + +

    Apache 2.0 extends this modular design to the most basic + functions of a web server. The server ships with a selection of + Multi-Processing Modules (MPMs) which are responsible for + binding to network ports on the machine, accepting requests, + and dispatching children to handle the requests.

    + +

    Extending the modular design to this level of the server + allows two important benefits:

    + +
      +
    • Apache can more cleanly and efficiently support a wide + variety of operating systems. In particular, the Windows + version of Apache is now much more efficient, since + mpm_winnt can use native + networking features in place of the POSIX layer used in + Apache 1.3. This benefit also extends to other operating + systems that implement specialized MPMs.
    • + +
    • The server can be better customized for the needs of the + particular site. For example, sites that need a great deal of + scalability can choose to use a threaded MPM like + worker or event, while sites requiring + stability or compatibility with older software can use a + prefork. In addition, + special features like serving different hosts under different + userids (perchild) can be + provided.
    • +
    + +

    At the user level, MPMs appear much like other Apache + modules. The main difference is that one and only one MPM must + be loaded into the server at any time. The list of available + MPMs appears on the module index page.

    + +
    top
    +
    +

    Choosing an MPM

    + +

    MPMs must be chosen during configuration, and compiled into + the server. Compilers are capable of optimizing a lot of + functions if threads are used, but only if they know that + threads are being used.

    + +

    To actually choose the desired MPM, use the argument + --with-mpm=NAME with the + configure script. NAME is the name of the + desired MPM.

    + +

    Once the server has been compiled, it is possible to + determine which MPM was chosen by using ./httpd + -l. This command will list every module that is compiled + into the server, including the MPM.

    +
    top
    +
    +

    MPM Defaults

    + +

    The following table lists the default MPMs for various operating +systems. This will be the MPM selected if you do not make another +choice at compile-time.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mpm.html.es b/trunk/docs/manual/mpm.html.es new file mode 100644 index 0000000000..57dd1a5985 --- /dev/null +++ b/trunk/docs/manual/mpm.html.es @@ -0,0 +1,139 @@ + + + +Módulos de MultiProcesamiento (MPMs) - Servidor HTTP Apache + + + + + +
    <-
    +

    Módulos de MultiProcesamiento (MPMs)

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Este documento describe que es un Módulo de Multiprocesamiento y +como los usa Apache.

    +
    + +
    top
    +
    +

    Introducción

    + +

    Apache está diseñado para ser un servidor web potente + y flexible que pueda funcionar en la más amplia variedad de + plataformas y entornos. Las diferentes plataformas y los + diferentes entornos, hacen que a menudo sean necesarias diferentes + características o funcionalidades, o que una misma + característica o funcionalidad sea implementada de diferente + manera para obtener una mayor eficiencia. Apache se ha adaptado + siempre a una gran variedad de entornos a través de su + diseño modular. Este diseño permite a los + administradores de sitios web elegir que características van + a ser incluidas en el servidor seleccionando que módulos se + van a cargar, ya sea al compilar o al ejecutar el servidor.

    + +

    Apache 2.0 extiende este diseño modular hasta las + funciones más básicas de un servidor web. El servidor + viene con una serie de Módulos de MultiProcesamiento que son + responsables de conectar con los puertos de red de la + máquina, acceptar las peticiones, y generar los procesos hijo + que se encargan de servirlas.

    + +

    La extensión del diseño modular a este nivel del + servidor ofrece dos beneficios importantes:

    + +
      +
    • Apache puede soportar de una forma más fácil y + eficiente una amplia variedad de sistemas operativos. En + concreto, la versión de Windows de Apache es mucho más + eficiente, porque el módulo mpm_winnt + puede usar funcionalidades nativas de red en lugar de usar la + capa POSIX como hace Apache 1.3. Este beneficio se extiende + también a otros sistemas operativos que implementan sus + respectivos MPMs.
    • + +
    • El servidor puede personalizarse mejor para las necesidades + de cada sitio web. Por ejemplo, los sitios web que necesitan + más que nada escalibildad pueden usar un MPM hebrado como + worker, mientras que los sitios web que + requieran por encima de otras cosas estabilidad o compatibilidad + con software antiguo pueden usar + prefork. Además, se pueden configurar + funcionalidades especiales como servir diferentes hosts con + diferentes identificadores de usuario + (perchild).
    • +
    + +

    A nivel de usuario, los MPMs son como cualquier otro + módulo de Apache. La diferencia más importante es que + solo un MPM puede estar cargado en el servidor en un determinado + momento. La lista de MPMs disponibles está en la sección índice de Módulos.

    + +
    top
    +
    +

    Cómo Elegir un MPM

    + +

    Los MPMs deben elegirse durante el proceso de + configuración, y deben ser compilados en el servidor. Los + compiladores son capaces de optimizar muchas funciones si se usan + hebras, pero solo si se sabe que se están usando hebras. Como + algunos MPM usan hebras en Unix y otros no, Apache tendrá un + mejor rendimiento si el MPM es elegido en el momento de compilar y + está incorporado en el servidor.

    + +

    Para elegir el MPM deseado, use el argumento --with-mpm= + NAME con el script ./configure. NAME es el + nombre del MPM deseado.

    + +

    Una vez que el servidor ha sido compilado, es posible + determinar que MPM ha sido elegido usando ./httpd + -l. Este comando lista todos los módulos compilados en + el servidor, incluido en MPM.

    +
    top
    +
    +

    MPM por defecto

    + +

    En la siguiente tabla se muestran los MPMs por defecto para varios +sistemas operativos. Estos serán los MPM seleccionados si no se +especifica lo contrario al compilar.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mpm.html.ja.euc-jp b/trunk/docs/manual/mpm.html.ja.euc-jp new file mode 100644 index 0000000000..030e16d734 --- /dev/null +++ b/trunk/docs/manual/mpm.html.ja.euc-jp @@ -0,0 +1,133 @@ + + + +¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM)

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë¤¬¤É¤Î¤è¤¦¤Ê¤â¤Î¤Ç¡¢ +Apache HTTP ¥µ¡¼¥Ð¤Ç¤É¤Î¤è¤¦¤Ë»ÈÍѤµ¤ì¤ë¤«¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¤Ï¤¸¤á¤Ë

    + +

    Apache HTTP ¥µ¡¼¥Ð¤Ï°Û¤Ê¤ëÉý¹­¤¤´Ä¶­¡¢Â¿¼ï¿Íͤʥץé¥Ã¥È¥Û¡¼¥à¤Ç + Æ°ºî¤¹¤ë¤è¤¦¤Ë¡¢¥Ñ¥ï¥Õ¥ë¤Ç½ÀÆðÀ­¤ËÉÙ¤ó¤ÀÀ߷פˤʤäƤ¤¤Þ¤¹¡£ + °Û¤Ê¤ë¥×¥é¥Ã¥È¥Û¡¼¥à¡¦°Û¤Ê¤ë´Ä¶­¤Ç¤Ï¤·¤Ð¤·¤Ð¡¢ + °Û¤Ê¤ëµ¡Ç½¤¬É¬Íפˤʤ俤ꡢ + Ʊ¤¸µ¡Ç½¤Ç¤â¸úΨ¤Î¤¿¤á¤Ë°Û¤Ê¤ë¼ÂÁõ¤¬É¬Íפˤʤ俤ꤷ¤Þ¤¹¡£ + Apache ¤Ç¤Ï¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤¿À߷פˤè¤êÉý¹­¤¤´Ä¶­¤ËŬ±þ¤·¤Æ¤­¤Þ¤·¤¿¡£ + ¤³¤ÎÀ߷פΤª¤«¤²¤Ç¡¢´ÉÍý¼Ô¤Ï + ¥³¥ó¥Ñ¥¤¥ë»þ¤Þ¤¿¤Ï¼Â¹Ô»þ¤Ë¤É¤Î¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë¤«Áª¤Ö¤³¤È¤Ë¤è¤Ã¤Æ¡¢ + ¤É¤Îµ¡Ç½¤ò¥µ¡¼¥Ð¤Ë¼è¤ê¹þ¤à¤«ÁªÂò¤¹¤ë¤³¤È¤¬¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Apache 2.0 ¤Ç¤Ï¡¢ + ¤³¤Î¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤¿À߷פò¥µ¡¼¥Ð¤Î´ðËܵ¡Ç½¤Ë¤Þ¤Ç³ÈÄ¥¤·¤Þ¤·¤¿¡£ + ¥µ¡¼¥Ð¤Ë¤ÏÀºÁª¤µ¤ì¤¿¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) + ¤¬ÉÕ¤¤¤Æ¤­¤Æ¡¢¤³¤ì¤é¤Ï¥Þ¥·¥ó¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥Ý¡¼¥È¤ò¥Ð¥¤¥ó¥É¤·¤¿¤ê¡¢ + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤¿¤ê¡¢¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤è¤¦»Ò¥×¥í¥»¥¹¤Ë³ä¤êÅö¤Æ¤¿¤ê¡¢ + ¤È¤¤¤Ã¤¿Ìò³ä¤ò»ý¤Á¤Þ¤¹¡£

    + +

    ¥â¥¸¥å¡¼¥ë²½¤µ¤ì¤¿À߷פò¥µ¡¼¥Ð¤Î¤³¤Î¥ì¥Ù¥ë¤Þ¤Ç³ÈÄ¥¤¹¤ë¤³¤È¤Ç + Æó¤Ä¤Î½ÅÍפÊÍøÅÀ¤¬À¸¤Þ¤ì¤Þ¤¹:

    + +
      +
    • Apache ¤ÏÉý¹­¤¤¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ò + ¤è¤êÈþ¤·¤¯¸úΨŪ¤Ë¥µ¥Ý¡¼¥È¤Ç¤­¤Þ¤¹¡£ + ÆÃ¤Ë Windows ÈǤΠApache ¤Ï¿ïʬ¸úΨŪ¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¤Ê¤¼¤Ê¤é mpm_winnt + ¤Ë¤è¤Ã¤Æ¡¢Apache 1.3 ¤ÇÍѤ¤¤é¤ì¤Æ¤¤¤¿ POSIX + ¥ì¥¤¥ä¤ÎÂå¤ï¤ê¤Ë¥Í¥¤¥Æ¥£¥Ö¤Î¥Í¥Ã¥È¥ï¡¼¥¯µ¡Ç½¤ò + ÍøÍѤǤ­¤ë¤«¤é¤Ç¤¹¡£ + ÆÃÊ̲½¤µ¤ì¤¿ MPM + ¤ò¼ÂÁõ¤·¤¿Â¾¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ç¤â¡¢ + ƱÍͤˤ³¤ÎÍøÅÀ¤ÏÀ¸¤Þ¤ì¤Þ¤¹¡£
    • + +
    • ¥µ¡¼¥Ð¤ÏÆÃÄê¤Î¥µ¥¤¥È¸þ¤±¤Ë¡¢¤è¤ê¾å¼ê¤Ë¥«¥¹¥¿¥Þ¥¤¥º¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð¡¢Èó¾ï¤ËÂ礭¤Ê¥¹¥±¡¼¥é¥Ó¥ê¥Æ¥£¤òɬÍפȤ¹¤ë¥µ¥¤¥È¤Ç¤Ï¡¢ + worker ¤ä event ¤È¤¤¤Ã¤¿¥¹¥ì¥Ã¥É²½¤µ¤ì¤¿ + MPM ¤òÍøÍѤǤ­¤ë°ìÊý¤Ç¡¢°ÂÄêÀ­¤ä¸Å¤¤¥½¥Õ¥È¥¦¥§¥¢¤È¤Î¸ß´¹À­¤ò + ɬÍפȤ¹¤ë¥µ¥¤¥È¤Ç¤Ï prefork + ¤¬ÍøÍѤǤ­¤Þ¤¹¡£¤Þ¤¿¡¢ + °Û¤Ê¤ë¥Û¥¹¥È¤ò°Û¤Ê¤ë¥æ¡¼¥¶ ID ¤ÇÆ°ºî¤µ¤»¤ë + (perchild) ¤È¤¤¤Ã¤¿ + ÆÃÊ̤ʵ¡Ç½¤âÄ󶡤Ǥ­¤Þ¤¹¡£
    • +
    + +

    ¥æ¡¼¥¶¥ì¥Ù¥ë¤Ç¤Ï¡¢MPM ¤Ï¾¤Î Apache + ¥â¥¸¥å¡¼¥ë¤ÈƱÅù¤Ë¸«¤¨¤Þ¤¹¡£ + ¼ç¤Ê°ã¤¤¤Ï¡¢¤¤¤Ä¤Ç¤âÍ£°ì¤Î MPM + ¤¬¥í¡¼¥É¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤È¤¤¤¦ÅÀ¤Ç¤¹¡£ + ÍøÍѲÄǽ¤Ê MPM ¤Ï + module ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ë¤¢¤ê¤Þ¤¹¡£

    + +
    top
    +
    +

    MPM ¤òÁª¤Ö

    + +

    MPM ¤ÏÀßÄêÃæ¤ËÁªÂò¤·¤Æ¡¢¥µ¡¼¥ÐÆâÉô¤Ë¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤±¤ì¤Ð + ¤Ê¤ê¤Þ¤»¤ó¡£ + ¥³¥ó¥Ñ¥¤¥é¤Ï¡¢¥¹¥ì¥Ã¥É¤¬»ÈÍѤµ¤ì¤Æ¤¤¤ë¾ì¹ç¤ËÍÍ¡¹¤Êµ¡Ç½¤òºÇŬ²½¤Ç¤­¤Þ¤¹¤¬¡¢ + ¤½¤Î¤¿¤á¤Ë¤Ï¤½¤â¤½¤â¥¹¥ì¥Ã¥É¤¬»È¤ï¤ì¤Æ¤¤¤ë¤È¤¤¤¦¤³¤È¤òÃΤëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ˾¤ß¤Î MPM ¤ò¼ÂºÝ¤ËÁª¤Ö¤¿¤á¤Ë¤Ï¡¢configure ¥¹¥¯¥ê¥×¥È¤Ç + --with-mpm=NAME °ú¿ô¤òÍѤ¤¤Æ¤¯¤À¤µ¤¤¡£ + NAME ¤Ï˾¤ß¤Î MPM ¤Î̾Á°¤Ç¤¹¡£

    + +

    ¥µ¡¼¥Ð¥³¥ó¥Ñ¥¤¥ë¸å¤Ï¡¢¤É¤Î MPM ¤¬ÁªÂò¤µ¤ì¤¿¤«¤ò + ./httpd -l ¤Ç³Î¤«¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤Î¥³¥Þ¥ó¥É¤Ï¡¢MPM + ¤ò´Þ¤á¡¢¥µ¡¼¥Ð¤Ë¥³¥ó¥Ñ¥¤¥ë¤ÇÁȤ߹þ¤Þ¤ì¤¿¥â¥¸¥å¡¼¥ëÁ´¤Æ¤ò + Îóµó¤·¤Þ¤¹¡£

    +
    top
    +
    +

    MPM ¥Ç¥Õ¥©¥ë¥ÈÃÍ

    + +

    ¼¡É½¤ËÍÍ¡¹¤Ê OS ¸þ¤±¤Î¥Ç¥Õ¥©¥ë¥È¤Î MPM °ìÍ÷¤ò·ÇºÜ¤·¤Æ¤¤¤Þ¤¹¡£ +¥³¥ó¥Ñ¥¤¥ë»þ¤Ë°Õ¿ÞŪ¤Ë¾¤òÁªÂò¤·¤Ê¤±¤ì¤Ð¡¢¼«Æ°Åª¤Ë¤³¤ì¤é¤Î MPM +¤¬ÁªÂò¤µ¤ì¤Þ¤¹¡£

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mpm.html.ko.euc-kr b/trunk/docs/manual/mpm.html.ko.euc-kr new file mode 100644 index 0000000000..a6e17a98bd --- /dev/null +++ b/trunk/docs/manual/mpm.html.ko.euc-kr @@ -0,0 +1,122 @@ + + + +´ÙÁßó¸® ¸ðµâ (MPM) - Apache HTTP Server + + + + + +
    <-
    +

    ´ÙÁßó¸® ¸ðµâ (MPM)

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­´Â ´ÙÁßó¸® ¸ðµâ (Multi-Processing Module)ÀÌ ¹«¾ùÀ̸ç, +¾ÆÆÄÄ¡ À¥¼­¹ö°¡ À̸¦ ¾î¶»°Ô »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¼Ò°³

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ´Ù¾çÇÑ È¯°æÀÇ ´Ù¾çÇÑ Ç÷¡Æû¿¡¼­ µ¿ÀÛÇÒ + ¼ö ÀÖµµ·Ï °­·ÂÇÏ°í À¯¿¬ÇÏ°Ô ¼³°èµÇ¾ú´Ù. ´Ù¸¥ Ç÷¡Æû°ú ´Ù¸¥ + ȯ°æÀº º¸Åë ´Ù¸¥ ±â´ÉÀ» ¿ä±¸Çϸç, ¾î¶² ±â´ÉÀ» °¡Àå È¿À²ÀûÀ¸·Î + ±¸ÇöÇÏ´Â ¹æ¹ýÀÌ ´Ù¸¦ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¸ðµâÈ­µÈ ¼³°è·Î ÀÌ·± + ´Ù¾çÇÑ È¯°æ¿¡ Ç×»ó ÀûÀÀÇØ¿Ô´Ù. ±×·¡¼­ À¥¸¶½ºÅÍ´Â ÄÄÆÄÀϽà + ȤÀº ½ÇÇà½Ã ¾î¶² ¸ðµâÀ» ÀоîµéÀÏÁö ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» °áÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    Apache 2.0Àº ÀÌ·± ¸ðµâÈ­µÈ ¼³°è¸¦ À¥¼­¹öÀÇ °¡Àå ±âº»ÀûÀÎ + ºÎºÐ¿¡±îÁö È®ÀåÇß´Ù. ¼­¹ö´Â ½Ã½ºÅÛÀÇ ³×Æ®¿÷ Æ÷Æ®¿¡ ¿¬°áÇÏ°í, + ¿äûÀ» ¹Þ¾ÆµéÀ̸ç, ¹Þ¾ÆµéÀÎ ¿äûÀ» ó¸®ÇϱâÀ§ÇØ Àڽĵ鿡°Ô + ºÐ¹èÇÏ´Â ´ÙÁßó¸® ¸ðµâ (Multi-Processing Modules, MPMs)À» + ¼±ÅÃÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼­¹ö¸¦ ÀÌ Á¤µµ·Î ¸ðµâÈ­ÇÏ¸é µÎ°¡Áö Áß¿äÇÑ ÀåÁ¡ÀÌ + ÀÖ´Ù:

    + +
      +
    • mpm_winnt°¡ Apache 1.3¿¡¼­ »ç¿ëÇÑ + POSIXÃþ ´ë½Å ÀÚü ³×Æ®¿÷ ±â´ÉÀ» »ç¿ëÇÒ ¼ö ÀÖ´Â µî, + ¾ÆÆÄÄ¡´Â ¿©·¯ ´Ù¾çÇÑ ¿î¿µÃ¼Á¦¸¦ ´õ ±ò²ûÇÏ°í È¿À²ÀûÀ¸·Î + Áö¿øÇÒ ¼ö ÀÖ´Ù. ÀÌ ÀåÁ¡Àº ƯȭµÈ MPMÀ» ±¸ÇöÇÑ ´Ù¸¥ + ¿î¿µÃ¼Á¦¿¡µµ Àû¿ëµÈ´Ù.
    • + +
    • ¼­¹ö´Â ƯÁ¤ »çÀÌÆ®ÀÇ ¿ä±¸Á¶°Ç¿¡ ´õ ƯȭµÉ ¼ö ÀÖ´Ù. + ¿¹¸¦ µé¾î ³ôÀº È®Àå°¡´É¼º(scalability)ÀÌ ÇÊ¿äÇÑ »çÀÌÆ®´Â + worker¿Í °°Àº ¾²·¹µå MPMÀ» »ç¿ëÇÏ°í, + ¾ÈÁ¤¼º°ú ¿À·¡µÈ ¼ÒÇÁÆ®¿þ¾î¿ÍÀÇ È£È¯¼ºÀÌ ÇÊ¿äÇÑ »çÀÌÆ®´Â + preforking MPMÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + Ãß°¡·Î ´Ù¸¥ »ç¿ëÀÚ¾ÆÀ̵ð·Î ¿©·¯ È£½ºÆ®¸¦ ¼­ºñ½ºÇÏ´Â + °Í(perchild)°ú °°Àº Ưº°ÇÑ ±â´Éµµ + Á¦°øµÈ´Ù.
    • +
    + +

    »ç¿ëÀÚ°¡ º¸±â¿¡ MPMÀº ´Ù¸¥ ¾ÆÆÄÄ¡ ¸ðµâ°ú °ÅÀÇ ºñ½ÁÇØ + º¸ÀδÙ. ÁÖµÈ Â÷ÀÌ´Â ¼­¹ö´Â Çѹø¿¡ ¿ÀÁ÷ ÇÑ MPM¸¸À» »ç¿ëÇØ¾ß + ÇÑ´Ù´Â Á¡ÀÌ´Ù. »ç¿ë°¡´ÉÇÑ MPM ¸ñ·ÏÀº ¸ðµâ + ¸ñ·Ï ÆäÀÌÁö¿¡ ÀÖ´Ù.

    + +
    top
    +
    +

    MPM ¼±ÅÃÇϱâ

    + +

    MPMs´Â ±¸¼ºÁß¿¡ ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ ÄÄÆÄÀÏµÇ¾ß ÇÑ´Ù. + ¾²·¹µå¸¦ »ç¿ëÇÏ´Â °ÍÀ» ÄÄÆÄÀÏ·¯°¡ ¾Ë¸é ¸¹Àº ÇÔ¼ö¸¦ + ÃÖÀûÈ­ÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º¿¡¼­ ¸î¸î MPMÀº ¾²·¹µå¸¦ ¾²°í + ³ª¸ÓÁö´Â ¾Æ´Ï¹Ç·Î, MPMÀÌ ±¸¼ºÁß¿¡ ¼±ÅÃµÇ¾î ¾ÆÆÄÄ¡¿¡ + ÄÄÆÄÀϵɶ§ ¾ÆÆÄÄ¡´Â ´õ ºü¸¥ ¼Óµµ¸¦ ³½´Ù.

    + +

    ¿øÇÏ´Â MPMÀ» ¼±ÅÃÇÏ·Á¸é ./configure ½ºÅ©¸³Æ®¿¡ + with-mpm= NAME ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇ϶ó. NAMEÀº + ¿øÇÏ´Â MPM À̸§ÀÌ´Ù.

    + +

    ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑÈÄ ./httpd -l ¸í·É¾î·Î ¼±ÅÃÇÑ + MPMÀ» ¾Ë ¼ö ÀÖ´Ù. ÀÌ ¸í·É¾î´Â MPMÀ» Æ÷ÇÔÇÏ¿© ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ + ¸ðµç ¸ðµâÀ» ¾Ë·ÁÁØ´Ù.

    +
    top
    +
    +

    MPM ±âº»°ª

    + +

    ´ÙÀ½ Ç¥´Â ¿©·¯ ¿î¿µÃ¼Á¦ÀÇ ±âº» MPMÀ» º¸¿©ÁØ´Ù. ÄÄÆÄÀϽà +´Ù¸£°Ô ¼±ÅÃÇÏÁö ¾ÊÀ¸¸é ÀÌ MPMÀÌ ¼±ÅõȴÙ.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    À¯´Ð½ºprefork
    À©µµ¿ìÁîmpm_winnt
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/mpm.xml b/trunk/docs/manual/mpm.xml new file mode 100644 index 0000000000..30ec624582 --- /dev/null +++ b/trunk/docs/manual/mpm.xml @@ -0,0 +1,115 @@ + + + + + + + + + + Multi-Processing Modules (MPMs) + + +

    This document describes what a Multi-Processing Module is and +how they are used by the Apache HTTP Server.

    +
    + +
    Introduction + +

    The Apache HTTP Server is designed to be a powerful and + flexible web server that can work on a very wide variety of + platforms in a range of different environments. Different + platforms and different environments often require different + features, or may have different ways of implementing the same + feature most efficiently. Apache has always accommodated a wide + variety of environments through its modular design. This design + allows the webmaster to choose which features will be included + in the server by selecting which modules to load either at + compile-time or at run-time.

    + +

    Apache 2.0 extends this modular design to the most basic + functions of a web server. The server ships with a selection of + Multi-Processing Modules (MPMs) which are responsible for + binding to network ports on the machine, accepting requests, + and dispatching children to handle the requests.

    + +

    Extending the modular design to this level of the server + allows two important benefits:

    + +
      +
    • Apache can more cleanly and efficiently support a wide + variety of operating systems. In particular, the Windows + version of Apache is now much more efficient, since + mpm_winnt can use native + networking features in place of the POSIX layer used in + Apache 1.3. This benefit also extends to other operating + systems that implement specialized MPMs.
    • + +
    • The server can be better customized for the needs of the + particular site. For example, sites that need a great deal of + scalability can choose to use a threaded MPM like + worker or event, while sites requiring + stability or compatibility with older software can use a + prefork. In addition, + special features like serving different hosts under different + userids (perchild) can be + provided.
    • +
    + +

    At the user level, MPMs appear much like other Apache + modules. The main difference is that one and only one MPM must + be loaded into the server at any time. The list of available + MPMs appears on the module index page.

    + +
    + +
    Choosing an MPM + +

    MPMs must be chosen during configuration, and compiled into + the server. Compilers are capable of optimizing a lot of + functions if threads are used, but only if they know that + threads are being used.

    + +

    To actually choose the desired MPM, use the argument + --with-mpm=NAME with the + configure script. NAME is the name of the + desired MPM.

    + +

    Once the server has been compiled, it is possible to + determine which MPM was chosen by using ./httpd + -l. This command will list every module that is compiled + into the server, including the MPM.

    +
    + +
    MPM Defaults + +

    The following table lists the default MPMs for various operating +systems. This will be the MPM selected if you do not make another +choice at compile-time.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    + +
    diff --git a/trunk/docs/manual/mpm.xml.de b/trunk/docs/manual/mpm.xml.de new file mode 100644 index 0000000000..1d2341914d --- /dev/null +++ b/trunk/docs/manual/mpm.xml.de @@ -0,0 +1,115 @@ + + + + + + + + + + Multi-Processing-Module (MPMs) + + +

    Das Dokument beschreibt, was ein Multi-Processing-Modul ist und wie solche + Module beim Apache HTTP Server verwendet werden.

    +
    + +
    Einführung + +

    Der Apache HTTP Server wurde als leistungsfähiger und flexibler Webserver + konzipiert, der auf einer Vielzahl von Plattformen in einer + Reihe unterschiedlicher Umgebungen arbeiten kann. Unterschiedliche + Plattformen und unterschiedliche Umgebungen verlangen oftmals verschiedene + Fähigkeiten oder kennen verschiedene Wege, die gleiche + Funktionaltät sehr effizient zu implementieren. Der Apache hat durch + seinen modularen Aufbau schon immer eine breite Auswahl von Umgebungen + unterstützt. Dieses Design erlaubt es dem Webmaster, durch Auswahl der + Module, die zur Kompilierungszeit oder zur Laufzeit geladen werden, die + Features auszuwählen, die in den Server intregiert werden.

    + +

    Der Apache 2.0 erweitert dieses modulare Design auf die grundlegenden + Funktionen eines Webservers. Der Server wird mit einer Auswahl von + Multi-Processing-Modulen (MPMs) ausgeliefert, die für die Bindung an + Netzwerkports der Maschine, die Annahme von Anfragen und die Abfertigung von + Kindprozessen zur Behandlung der Anfragen zuständig sind.

    + +

    Die Erweiterung des modularen Aufbaus auf diese Ebene des Servers + bringt zwei wesentliche Vorteile:

    + +
      +
    • Der Apache kann nun eine Vielfalt von Betriebssystemen sauberer und + effizienter unterstützen. Insbesondere die Windows-Version des Apache + ist jetzt deutlich effizienter, da mpm_winnt native + Netzwerkfähigkeiten anstelle der im Apache 1.3 verwendeten + POSIX-Schicht benutzen kann. Dieser Vorteil gilt auch für andere + Betriebssysteme, für die spezielle MPMs implementiert sind.
    • + +
    • Der Server läßt sich besser auf die Bedürfnisse der + jeweiligen Website anpassen. Sites beispielsweise, die eine hohe + Skalierbarkeit benötigen, können ein Threaded-MPM wie + worker oder event wählen, + während Sites, die Stabilität oder Kompatibilität mit + älterer Software erfordern, prefork wählen + können. Darüber hinaus können Spezialfähigkeiten wie + die Bedienung verschiedener Hosts unter unterschiedlichen User-IDs + (perchild) angeboten werden.
    • +
    + +

    Auf Anwenderebene erscheinen MPMs fast wie andere Apache-Module. Der + Hauptunterschied ist, dass jeweils nur ein einziges MPM in den Server + geladen werden kann. Die Liste der verfügbaren MPMs finden Sie im Modul-Index.

    + +
    + +
    Auswahl eines MPMs + +

    MPMs müssen während der + Quelltext-Konfiguration ausgewählt und in den + Server einkompiliert werden. Compiler sind in der Lage eine Reihe von + Funktionen zu optimieren, wenn Threads verwendet werden. Sie können + dies allerdings nur, wenn sie wissen, dass Threads benutzt werden.

    + +

    Um das gewünschte MPM tatsächlich auszuwählen, verwenden Sie + beim configure-Skript das Argument + --with-mpm=NAME. NAME ist der Name des + gewünschten MPMs.

    + +

    Ist der Server kompiliert, so ist es mittels ./httpd -l + möglich, das ausgewählte MPM zu ermitteln. Dieser Befehl listet + alle in den Server einkompilierten Module auf, einschließlich des + MPM.

    +
    + +
    MPM-Voreinstellungen + +

    Die folgende Tabelle gibt die voreingestellten MPMs für verschiedene + Betriebssysteme an. Wenn Sie während der Kompilierung keine andere + Auswahl treffen, wird dieses MPM gewählt.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    + +
    diff --git a/trunk/docs/manual/mpm.xml.es b/trunk/docs/manual/mpm.xml.es new file mode 100644 index 0000000000..d5fde4cc28 --- /dev/null +++ b/trunk/docs/manual/mpm.xml.es @@ -0,0 +1,124 @@ + + + + + + + + + + Módulos de MultiProcesamiento (MPMs) + + +

    Este documento describe que es un Módulo de Multiprocesamiento y +como los usa Apache.

    +
    + +
    Introducción + +

    Apache está diseñado para ser un servidor web potente + y flexible que pueda funcionar en la más amplia variedad de + plataformas y entornos. Las diferentes plataformas y los + diferentes entornos, hacen que a menudo sean necesarias diferentes + características o funcionalidades, o que una misma + característica o funcionalidad sea implementada de diferente + manera para obtener una mayor eficiencia. Apache se ha adaptado + siempre a una gran variedad de entornos a través de su + diseño modular. Este diseño permite a los + administradores de sitios web elegir que características van + a ser incluidas en el servidor seleccionando que módulos se + van a cargar, ya sea al compilar o al ejecutar el servidor.

    + +

    Apache 2.0 extiende este diseño modular hasta las + funciones más básicas de un servidor web. El servidor + viene con una serie de Módulos de MultiProcesamiento que son + responsables de conectar con los puertos de red de la + máquina, acceptar las peticiones, y generar los procesos hijo + que se encargan de servirlas.

    + +

    La extensión del diseño modular a este nivel del + servidor ofrece dos beneficios importantes:

    + +
      +
    • Apache puede soportar de una forma más fácil y + eficiente una amplia variedad de sistemas operativos. En + concreto, la versión de Windows de Apache es mucho más + eficiente, porque el módulo mpm_winnt + puede usar funcionalidades nativas de red en lugar de usar la + capa POSIX como hace Apache 1.3. Este beneficio se extiende + también a otros sistemas operativos que implementan sus + respectivos MPMs.
    • + +
    • El servidor puede personalizarse mejor para las necesidades + de cada sitio web. Por ejemplo, los sitios web que necesitan + más que nada escalibildad pueden usar un MPM hebrado como + worker, mientras que los sitios web que + requieran por encima de otras cosas estabilidad o compatibilidad + con software antiguo pueden usar + prefork. Además, se pueden configurar + funcionalidades especiales como servir diferentes hosts con + diferentes identificadores de usuario + (perchild).
    • +
    + +

    A nivel de usuario, los MPMs son como cualquier otro + módulo de Apache. La diferencia más importante es que + solo un MPM puede estar cargado en el servidor en un determinado + momento. La lista de MPMs disponibles está en la sección índice de Módulos.

    + +
    + +
    Cómo Elegir un MPM + +

    Los MPMs deben elegirse durante el proceso de + configuración, y deben ser compilados en el servidor. Los + compiladores son capaces de optimizar muchas funciones si se usan + hebras, pero solo si se sabe que se están usando hebras. Como + algunos MPM usan hebras en Unix y otros no, Apache tendrá un + mejor rendimiento si el MPM es elegido en el momento de compilar y + está incorporado en el servidor.

    + +

    Para elegir el MPM deseado, use el argumento --with-mpm= + NAME con el script ./configure. NAME es el + nombre del MPM deseado.

    + +

    Una vez que el servidor ha sido compilado, es posible + determinar que MPM ha sido elegido usando ./httpd + -l. Este comando lista todos los módulos compilados en + el servidor, incluido en MPM.

    +
    + +
    MPM por defecto + +

    En la siguiente tabla se muestran los MPMs por defecto para varios +sistemas operativos. Estos serán los MPM seleccionados si no se +especifica lo contrario al compilar.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    + +
    + diff --git a/trunk/docs/manual/mpm.xml.ja b/trunk/docs/manual/mpm.xml.ja new file mode 100644 index 0000000000..1efb9f4612 --- /dev/null +++ b/trunk/docs/manual/mpm.xml.ja @@ -0,0 +1,120 @@ + + + + + + + + + + $B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) + + +

    $B$3$NJ8=q$G$O%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k$,$I$N$h$&$J$b$N$G!"(B +Apache HTTP $B%5!<%P$G$I$N$h$&$K;HMQ$5$l$k$+$K$D$$$F2r@b$7$F$$$^$9!#(B

    +
    + +
    $B$O$8$a$K(B + +

    Apache HTTP $B%5!<%P$O0[$J$kI}9-$$4D6-!"B? + +

    Apache 2.0 $B$G$O!"(B + $B$3$N%b%8%e!<%k2=$5$l$?@_7W$r%5!<%P$N4pK\5!G=$K$^$G3HD%$7$^$7$?!#(B + $B%5!<%P$K$O@:A*$5$l$?%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) + $B$,IU$$$F$-$F!"$3$l$i$O%^%7%s$N%M%C%H%o!<%/%]!<%H$r%P%$%s%I$7$?$j!"(B + $B%j%/%(%9%H$r + +

    $B%b%8%e!<%k2=$5$l$?@_7W$r%5!<%P$N$3$N%l%Y%k$^$G3HD%$9$k$3$H$G(B + $BFs$D$N=EMW$JMxE@$,@8$^$l$^$9(B:

    + +
      +
    • Apache $B$OI}9-$$%*%Z%l!<%F%#%s%0%7%9%F%`$r(B + $B$h$jH~$7$/8zN(E*$K%5%]!<%H$G$-$^$9!#(B + $BFC$K(B Windows $BHG$N(B Apache $B$O?oJ,8zN(E*$K$J$j$^$7$?!#(B + $B$J$<$J$i(B mpm_winnt + $B$K$h$C$F!"(BApache 1.3 $B$GMQ$$$i$l$F$$$?(B POSIX + $B%l%$%d$NBe$o$j$K%M%$%F%#%V$N%M%C%H%o!<%/5!G=$r(B + $BMxMQ$G$-$k$+$i$G$9!#(B + $BFCJL2=$5$l$?(B MPM + $B$r$N%*%Z%l!<%F%#%s%0%7%9%F%`$G$b!"(B + $BF1MM$K$3$NMxE@$O@8$^$l$^$9!#(B
    • + +
    • $B%5!<%P$OFCDj$N%5%$%H8~$1$K!"$h$j>eo$KBg$-$J%9%1!<%i%S%j%F%#$rI,MW$H$9$k%5%$%H$G$O!"(B + worker $B$d(B event $B$H$$$C$?%9%l%C%I2=$5$l$?(B + MPM $B$rMxMQ$G$-$k0lJ}$G!"0BDj@-$d8E$$%=%U%H%&%'%"$H$N8_49@-$r(B + $BI,MW$H$9$k%5%$%H$G$O(B prefork + $B$,MxMQ$G$-$^$9!#$^$?!"(B + $B0[$J$k%[%9%H$r0[$J$k%f!<%6(B ID $B$GF0:n$5$;$k(B + (perchild) $B$H$$$C$?(B + $BFCJL$J5!G=$bDs6!$G$-$^$9!#(B
    • +
    + +

    $B%f!<%6%l%Y%k$G$O!"(BMPM $B$OB>$N(B Apache + $B%b%8%e!<%k$HF1Ey$K8+$($^$9!#(B + $Bmodule $B%$%s%G%C%/%9(B$B$K$"$j$^$9!#(B

    + +
    + +
    MPM $B$rA*$V(B + +

    MPM $B$O@_DjCf$KA*Br$7$F!"%5!<%PFbIt$K%3%s%Q%$%k$5$l$J$1$l$P(B + $B$J$j$^$;$s!#(B + $B%3%s%Q%$%i$O!"%9%l%C%I$,;HMQ$5$l$F$$$k>l9g$KMM!9$J5!G=$r:GE,2=$G$-$^$9$,!"(B + $B$=$N$?$a$K$O$=$b$=$b%9%l%C%I$,;H$o$l$F$$$k$H$$$&$3$H$rCN$kI,MW$,$"$j$^$9!#(B

    + +

    $BK>$_$N(B MPM $B$rconfigure $B%9%/%j%W%H$G(B + --with-mpm=NAME $B0z?t$rMQ$$$F$/$@$5$$!#(B + NAME $B$OK>$_$N(B MPM $B$NL>A0$G$9!#(B

    + +

    $B%5!<%P%3%s%Q%$%k8e$O!"$I$N(B MPM $B$,A*Br$5$l$?$+$r(B + ./httpd -l $B$G3N$+$a$k$3$H$,$G$-$^$9!#(B + $B$3$N%3%^%s%I$O!"(BMPM + $B$r4^$a!"%5!<%P$K%3%s%Q%$%k$GAH$_9~$^$l$?%b%8%e!<%kA4$F$r(B + $BNs5s$7$^$9!#(B

    +
    + +
    MPM $B%G%U%)%k%HCM(B + +

    $B$rA*Br$7$J$1$l$P!"<+F0E*$K$3$l$i$N(B MPM +$B$,A*Br$5$l$^$9!#(B

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    Unixprefork
    Windowsmpm_winnt
    +
    + +
    diff --git a/trunk/docs/manual/mpm.xml.ko b/trunk/docs/manual/mpm.xml.ko new file mode 100644 index 0000000000..3db7ca8154 --- /dev/null +++ b/trunk/docs/manual/mpm.xml.ko @@ -0,0 +1,107 @@ + + + + + + + + + + ´ÙÁßó¸® ¸ðµâ (MPM) + + +

    ÀÌ ¹®¼­´Â ´ÙÁßó¸® ¸ðµâ (Multi-Processing Module)ÀÌ ¹«¾ùÀ̸ç, +¾ÆÆÄÄ¡ À¥¼­¹ö°¡ À̸¦ ¾î¶»°Ô »ç¿ëÇÏ´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + +
    ¼Ò°³ + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ´Ù¾çÇÑ È¯°æÀÇ ´Ù¾çÇÑ Ç÷¡Æû¿¡¼­ µ¿ÀÛÇÒ + ¼ö ÀÖµµ·Ï °­·ÂÇÏ°í À¯¿¬ÇÏ°Ô ¼³°èµÇ¾ú´Ù. ´Ù¸¥ Ç÷¡Æû°ú ´Ù¸¥ + ȯ°æÀº º¸Åë ´Ù¸¥ ±â´ÉÀ» ¿ä±¸Çϸç, ¾î¶² ±â´ÉÀ» °¡Àå È¿À²ÀûÀ¸·Î + ±¸ÇöÇÏ´Â ¹æ¹ýÀÌ ´Ù¸¦ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¸ðµâÈ­µÈ ¼³°è·Î ÀÌ·± + ´Ù¾çÇÑ È¯°æ¿¡ Ç×»ó ÀûÀÀÇØ¿Ô´Ù. ±×·¡¼­ À¥¸¶½ºÅÍ´Â ÄÄÆÄÀϽà + ȤÀº ½ÇÇà½Ã ¾î¶² ¸ðµâÀ» ÀоîµéÀÏÁö ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ Æ÷ÇÔÇÒ + ±â´ÉÀ» °áÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    Apache 2.0Àº ÀÌ·± ¸ðµâÈ­µÈ ¼³°è¸¦ À¥¼­¹öÀÇ °¡Àå ±âº»ÀûÀÎ + ºÎºÐ¿¡±îÁö È®ÀåÇß´Ù. ¼­¹ö´Â ½Ã½ºÅÛÀÇ ³×Æ®¿÷ Æ÷Æ®¿¡ ¿¬°áÇÏ°í, + ¿äûÀ» ¹Þ¾ÆµéÀ̸ç, ¹Þ¾ÆµéÀÎ ¿äûÀ» ó¸®ÇϱâÀ§ÇØ Àڽĵ鿡°Ô + ºÐ¹èÇÏ´Â ´ÙÁßó¸® ¸ðµâ (Multi-Processing Modules, MPMs)À» + ¼±ÅÃÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼­¹ö¸¦ ÀÌ Á¤µµ·Î ¸ðµâÈ­ÇÏ¸é µÎ°¡Áö Áß¿äÇÑ ÀåÁ¡ÀÌ + ÀÖ´Ù:

    + +
      +
    • mpm_winnt°¡ Apache 1.3¿¡¼­ »ç¿ëÇÑ + POSIXÃþ ´ë½Å ÀÚü ³×Æ®¿÷ ±â´ÉÀ» »ç¿ëÇÒ ¼ö ÀÖ´Â µî, + ¾ÆÆÄÄ¡´Â ¿©·¯ ´Ù¾çÇÑ ¿î¿µÃ¼Á¦¸¦ ´õ ±ò²ûÇÏ°í È¿À²ÀûÀ¸·Î + Áö¿øÇÒ ¼ö ÀÖ´Ù. ÀÌ ÀåÁ¡Àº ƯȭµÈ MPMÀ» ±¸ÇöÇÑ ´Ù¸¥ + ¿î¿µÃ¼Á¦¿¡µµ Àû¿ëµÈ´Ù.
    • + +
    • ¼­¹ö´Â ƯÁ¤ »çÀÌÆ®ÀÇ ¿ä±¸Á¶°Ç¿¡ ´õ ƯȭµÉ ¼ö ÀÖ´Ù. + ¿¹¸¦ µé¾î ³ôÀº È®Àå°¡´É¼º(scalability)ÀÌ ÇÊ¿äÇÑ »çÀÌÆ®´Â + worker¿Í °°Àº ¾²·¹µå MPMÀ» »ç¿ëÇÏ°í, + ¾ÈÁ¤¼º°ú ¿À·¡µÈ ¼ÒÇÁÆ®¿þ¾î¿ÍÀÇ È£È¯¼ºÀÌ ÇÊ¿äÇÑ »çÀÌÆ®´Â + preforking MPMÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + Ãß°¡·Î ´Ù¸¥ »ç¿ëÀÚ¾ÆÀ̵ð·Î ¿©·¯ È£½ºÆ®¸¦ ¼­ºñ½ºÇÏ´Â + °Í(perchild)°ú °°Àº Ưº°ÇÑ ±â´Éµµ + Á¦°øµÈ´Ù.
    • +
    + +

    »ç¿ëÀÚ°¡ º¸±â¿¡ MPMÀº ´Ù¸¥ ¾ÆÆÄÄ¡ ¸ðµâ°ú °ÅÀÇ ºñ½ÁÇØ + º¸ÀδÙ. ÁÖµÈ Â÷ÀÌ´Â ¼­¹ö´Â Çѹø¿¡ ¿ÀÁ÷ ÇÑ MPM¸¸À» »ç¿ëÇØ¾ß + ÇÑ´Ù´Â Á¡ÀÌ´Ù. »ç¿ë°¡´ÉÇÑ MPM ¸ñ·ÏÀº ¸ðµâ + ¸ñ·Ï ÆäÀÌÁö¿¡ ÀÖ´Ù.

    + +
    + +
    MPM ¼±ÅÃÇϱâ + +

    MPMs´Â ±¸¼ºÁß¿¡ ¼±ÅÃÇÏ¿© ¼­¹ö¿¡ ÄÄÆÄÀÏµÇ¾ß ÇÑ´Ù. + ¾²·¹µå¸¦ »ç¿ëÇÏ´Â °ÍÀ» ÄÄÆÄÀÏ·¯°¡ ¾Ë¸é ¸¹Àº ÇÔ¼ö¸¦ + ÃÖÀûÈ­ÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º¿¡¼­ ¸î¸î MPMÀº ¾²·¹µå¸¦ ¾²°í + ³ª¸ÓÁö´Â ¾Æ´Ï¹Ç·Î, MPMÀÌ ±¸¼ºÁß¿¡ ¼±ÅÃµÇ¾î ¾ÆÆÄÄ¡¿¡ + ÄÄÆÄÀϵɶ§ ¾ÆÆÄÄ¡´Â ´õ ºü¸¥ ¼Óµµ¸¦ ³½´Ù.

    + +

    ¿øÇÏ´Â MPMÀ» ¼±ÅÃÇÏ·Á¸é ./configure ½ºÅ©¸³Æ®¿¡ + with-mpm= NAME ¾Æ±Ô¸ÕÆ®¸¦ »ç¿ëÇ϶ó. NAMEÀº + ¿øÇÏ´Â MPM À̸§ÀÌ´Ù.

    + +

    ¼­¹ö¸¦ ÄÄÆÄÀÏÇÑÈÄ ./httpd -l ¸í·É¾î·Î ¼±ÅÃÇÑ + MPMÀ» ¾Ë ¼ö ÀÖ´Ù. ÀÌ ¸í·É¾î´Â MPMÀ» Æ÷ÇÔÇÏ¿© ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ + ¸ðµç ¸ðµâÀ» ¾Ë·ÁÁØ´Ù.

    +
    + +
    MPM ±âº»°ª + +

    ´ÙÀ½ Ç¥´Â ¿©·¯ ¿î¿µÃ¼Á¦ÀÇ ±âº» MPMÀ» º¸¿©ÁØ´Ù. ÄÄÆÄÀϽà +´Ù¸£°Ô ¼±ÅÃÇÏÁö ¾ÊÀ¸¸é ÀÌ MPMÀÌ ¼±ÅõȴÙ.

    + + + + + + + + +
    BeOSbeos
    Netwarempm_netware
    OS/2mpmt_os2
    À¯´Ð½ºprefork
    À©µµ¿ìÁîmpm_winnt
    +
    + +
    diff --git a/trunk/docs/manual/mpm.xml.meta b/trunk/docs/manual/mpm.xml.meta new file mode 100644 index 0000000000..ddd57d214b --- /dev/null +++ b/trunk/docs/manual/mpm.xml.meta @@ -0,0 +1,15 @@ + + + + mpm + / + . + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/new_features_2_0.html b/trunk/docs/manual/new_features_2_0.html new file mode 100644 index 0000000000..798ba8a591 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html @@ -0,0 +1,27 @@ +URI: new_features_2_0.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: new_features_2_0.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: new_features_2_0.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: new_features_2_0.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: new_features_2_0.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR + +URI: new_features_2_0.html.pt-br +Content-Language: pt-br +Content-type: text/html; charset=ISO-8859-1 + +URI: new_features_2_0.html.ru.koi8-r +Content-Language: ru +Content-type: text/html; charset=KOI8-R diff --git a/trunk/docs/manual/new_features_2_0.html.de b/trunk/docs/manual/new_features_2_0.html.de new file mode 100644 index 0000000000..4614a5acf8 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.de @@ -0,0 +1,263 @@ + + + +Übersicht der neuen Funktionen in Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Übersicht der neuen Funktionen in Apache 2.0

    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    Dieses Dokument beschreibt einige der wichtigsten Änderungen + des Apache HTTP Servers 2.0 gegenüber der Version 1.3.

    +
    + +
    top
    +
    +

    Core-Erweiterungen

    + + +
    +
    Unix-Threading
    + +
    Auf Unix-Systemen mit Unterstützung für POSIX-Threads, + kann Apache jetzt in einem Multi-Process, Multi-Threaded Hybrid-Mode + gestartet werden. Dies verbessert die Skalierfähigkeit für + viele, jedoch nicht unbedingt alle Konfigurationen.
    + +
    Neues Build-System
    + +
    Das Build-System wurde komplett auf der Basis von + autoconf und libtool neu geschrieben. Dadurch + wird das Apache-Konfigurationssystem dem vieler anderer Packages + ähnlicher.
    + +
    Multi-Protokoll-Unterstützung
    + +
    Apache stellt jetzt die notwendigen Grundfunktionalitäten + bereit, um mehrere Protokolle unterstützen und verarbeiten zu + können. mod_echo wurde hierfür als + Beispiel geschrieben.
    + +
    Bessere Unterstützung von + Nicht-Unix-Plattformen
    + +
    Apache 2.0 ist schneller und stabiler auf Nicht-Unix-Plattformen + wie BeOS, OS/2 und Windows. Mit der Einführung von + Plattform-spezifischen Multi-Processing Modulen + (MPMs) und der Apache Portable Runtime (APR), sind diese Plattformen + jetzt in ihrem nativen API implementiert, wodurch die Verwendung der + häufig fehlerbehafteten und schlecht funktionierenden + POSIX-Emulation-Layer vermieden wird.
    + +
    Neues Apache API
    + +
    Das API für Module hat sich in 2.0 stark verändert. + Die meisten der Sortierungs-/Prioritätsprobleme von Modulen bei + 1.3 sollten nun verschwunden sein. In 2.0 wird hiervon vieles + automatisch durchgeführt. Die Modulsortierung wird jetzt + über einen pre-hook vorgenommen, um mehr Flexibilität + zu bieten. Außerdem wurden neue API-Calls hinzugefügt, + die zusätzliche Modulfähigkeiten zur Verfügung stellen, + ohne den Apache-Kern anpassen zu müssen.
    + +
    IPv6-Unterstützung
    + +
    Auf Systemen, bei denen die zugrundeliegende Apache Portable + Runtime-Bibliothek IPv6 unterstützt, bekommt Apache + standarmäßig IPv6 Listening Sockets. Zusätzlich + unterstützen die Konfigurationsanweisungen Listen, NameVirtualHost und VirtualHost numerische IPv6-Adressangaben + (z.B., "Listen [fe80::1]:8080").
    + +
    Filterung
    + +
    Apache-Module können jetzt als Filter entwickelt und zur + Filterung des rein- und rausgehenden Datenstroms des Servers + eingesetzt werden. Hierdurch kann beispielsweise die Ausgabe von + CGI-Skripten durch den INCLUDES-Filter von + mod_include bearbeitet werden und so Server-Side + Include-Anweisungen ausgeführt werden. Das Modul + mod_ext_filter erlaubt externen Programmen + als Filter zu agieren, in der gleichen Weise wie CGI-Programme als + Eingabe dienen können.
    + +
    Mehrsprachige Fehlermeldungen
    + +
    Fehlermeldungen die an den Browser rausgehen, stehen jetzt als + SSI-Dokumente in verschiedenen Sprachen zur Verfügung. Sie + können bei Bedarf durch den Administrator angepasst werden, + um ein einheitliches Design zu erreichen.
    + +
    Vereinfachte Konfiguration
    + +
    Viele der verwirrenden Konfigurationsanweisungen wurden vereinfacht. + Die oft für Verwirrung sorgenden Port- und + BindAddress-Anweisungen wurden entfernt. + Ausschließlich die Listen-Anweisung wird nun zum + Setzen von IP-Addressen und Portnummern benutzt. + Der Servername und die Portnummer, die für Weiterleitungen und + zur Erkennung virtueller Server verwendet werden, werden über + die ServerName-Anweisung + konfiguriert.
    + +
    Native Windows NT Unicode-Unterstützung
    + +
    Apache 2.0 auf Windows NT benutzt jetzt utf-8 für alle + Dateinamen-Kodierungen. Diese werden direkt auf das zugrundeliegende + Unicode-Dateisystem abgebildet, wodurch Mehrsprach-Unterstützung + für alle Windows NT-basierten Installationen, inklusive Windows + 2000 und Windows XP, zur Verfügung gestellt wird. + Diese Unterstützung ist nicht auf Windows 95, 98 oder ME + verfügbar. Hier wird weiterhin die jeweils lokale Codepage des + Rechners für den Zugriff auf das Dateisystem verwendet.
    + +
    Bibliothek für reguläre Ausdrücke aktualisiert
    + +
    Apache 2.0 enthält die "Perl Compatible + Regular Expression Library" (PCRE). + Bei der Auswertung aller regulären Ausdrücke wird nun + die leistungsfähigere Syntax von Perl 5 verwendet.
    + +
    +
    top
    +
    +

    Modul-Erweiterungen

    + + +
    +
    mod_ssl
    + +
    Neues Modul in Apache 2.0. Dieses Modul ist ein Interface + zu den von OpenSSL bereitgestellten SSL/TLS + Verschlüsselungs-Protokollen.
    + +
    mod_dav
    + +
    Neues Modul in Apache 2.0. Dieses Modul implementiert die HTTP + Distributed Authoring and Versioning (DAV) Spezifikation zur + Erzeugung und Pflege von Web-Inhalten.
    + +
    mod_deflate
    + +
    Neues Modul in Apache 2.0. Dieses Modul erlaubt es Browsern, die + dies unterstützen, eine Komprimierung des Inhaltes vor der + Auslieferung anzufordern, um so Netzwerk-Bandbreite zu sparen.
    + +
    mod_auth_ldap
    + +
    Neues Modul in Apache 2.0.41. Diese Modul ermöglicht + die Verwendung einer LDAP-Datenbank zur Speicherung von + Berechtigungsdaten für die HTTP-Basic-Authentication. + Ein Begleitmodul, mod_ldap, stellt einen + Verbindungs-Pool und die Pufferung von Abfrageergebnissen zur + Verfügung. +
    + +
    mod_auth_digest
    + +
    Zusätzliche Unterstützung für + prozessübergreifendes Session-Caching mittels Shared-Memory. +
    + +
    mod_charset_lite
    + +
    Neues Modul in Apache 2.0. + Dieses experimentelle Modul erlaubt Zeichensatz-Übersetzungen oder + -Umschlüsselung.
    + +
    mod_file_cache
    + +
    Neues Modul in Apache 2.0. Dieses Modul beinhaltet die + Funktionalität von mod_mmap_static aus Apache 1.3, + plus einige weitere Caching-Funktionen.
    + +
    mod_headers
    + +
    Dieses Modul ist in Apache 2.0 deutlich flexibler geworden. Es + kann jetzt die von mod_proxy genutzten Request-Header + manipulieren und es ist möglich Response-Header auf Basis von + definierten Bedingungen zu verändern.
    + +
    mod_proxy
    + +
    Das Proxy Modul wurde komplett neu geschrieben um die + Möglichkeiten der neuen Filter-Funktionalität + auszuschöpfen und um einen zuverlässigen Proxy zu haben, der + den HTTP/1.1-Spezifikationen entspricht. Neue <Proxy> + -Konfigurationsabschnitte bieten eine besser lesbare (und intern + schnellere) Kontrolle der vermittelten Seiten. + Die überladenen <Directory + "proxy:...">-Konfigurationen werden nicht + mehr unterstützt. Das Modul ist nun in mehrere Module + unterteilt, die jeweils ein bestimmtes Übertragungsprotokoll + unterstützen, wie proxy_connect, + proxy_ftp und proxy_http.
    + +
    mod_negotiation
    + +
    Die neue Konfigurationsanweisung ForceLanguagePriority + kann benutzt werden, um sicherzustellen, dass ein Client auf jeden + Fall ein einzelnes Dokument, anstatt einer NOT ACCEPTABLE- oder + MULTIPLE CHOICES-Antwort, bekommt. Zusätzlich wurden die + Negotiation- und Multiview-Algorithmen angepasst um einheitlichere + Ergebnisse zu liefern. Außerdem wird ein neues + Type-Map-Format bereitgestellt, das Dokumenteninhalte direkt + enthalten kann.
    + +
    mod_autoindex
    + +
    Automatisch erzeugte Verzeichnisindizes können zur besseren + Übersichtlichkeit durch HTML-Tabellen dargestellt werden. + Genauere Sortierungen, wie Sortierung nach Versionsnummer und + Wildcard-Filterung des Verzeichnisindizes werden unterstützt.
    + +
    mod_include
    + +
    Neue Anweisungen erlauben es, die Standard Start- und Endtags von + SSI-Elementen zu ändern. Zudem können die Default-Formate + für Fehlermeldungen und Zeitangaben nun ebenfalls in der + Serverkonfiguration vorgenommen werden. Auf die Ergebnisse der + Auswertung und Gruppierung von regulären Ausdrücken (jetzt + auf Basis der Perl-Syntax für reguläre Ausdrücke) kann + über die mod_include Variablen $0 + bis $9 zugegriffen werden.
    + +
    mod_auth_dbm
    + +
    DBM-ähnliche Datenbanken werden jetzt durch die + Konfigurationsaweisung AuthDBMType unterstützt.
    +
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.en b/trunk/docs/manual/new_features_2_0.html.en new file mode 100644 index 0000000000..8470b22e35 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.en @@ -0,0 +1,243 @@ + + + +Overview of new features in Apache 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Overview of new features in Apache 2.0

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    This document describes some of the major changes between the + 1.3 and 2.0 versions of the Apache HTTP Server.

    +
    + +
    top
    +
    +

    Core Enhancements

    + + +
    +
    Unix Threading
    + +
    On Unix systems with POSIX threads support, Apache can + now run in a hybrid multiprocess, multithreaded mode. This + improves scalability for many, but not all configurations.
    + +
    New Build System
    + +
    The build system has been rewritten from scratch to be + based on autoconf and libtool. + This makes Apache's configuration system more similar to + that of other packages.
    + +
    Multiprotocol Support
    + +
    Apache now has some of the infrastructure in place to + support serving multiple protocols. mod_echo has + been written as an example.
    + +
    Better support for non-Unix + platforms
    + +
    Apache 2.0 is faster and more stable on non-Unix + platforms such as BeOS, OS/2, and Windows. With the + introduction of platform-specific multi-processing modules (MPMs) and the + Apache Portable Runtime (APR), these platforms are now + implemented in their native API, avoiding the often buggy and + poorly performing POSIX-emulation layers.
    + +
    New Apache API
    + +
    The API for modules has changed significantly for 2.0. + Many of the module-ordering/-priority problems from 1.3 should + be gone. 2.0 does much of this automatically, and module ordering + is now done per-hook to allow more flexibility. Also, new calls + have been added that provide additional module capabilities + without patching the core Apache server.
    + +
    IPv6 Support
    + +
    On systems where IPv6 is supported by the underlying + Apache Portable Runtime library, Apache gets IPv6 listening + sockets by default. Additionally, the Listen, NameVirtualHost, and VirtualHost directives support + IPv6 numeric address strings (e.g., "Listen + [fe80::1]:8080").
    + +
    Filtering
    + +
    Apache modules may now be written as filters which act on + the stream of content as it is delivered to or from the + server. This allows, for example, the output of CGI scripts to + be parsed for Server Side Include directives using the + INCLUDES filter in mod_include. The + module mod_ext_filter allows external programs to + act as filters in much the same way that CGI programs can act as + handlers.
    + +
    Multilanguage Error Responses
    + +
    Error response messages to the browser are now provided in + several languages, using SSI documents. They may be customized + by the administrator to achieve a consistent look and feel.
    + +
    Simplified configuration
    + +
    Many confusing directives have been simplified. The often + confusing Port and BindAddress directives + are gone; only the Listen + directive is used for IP address binding; the ServerName directive specifies the + server name and port number only for redirection and vhost + recognition.
    + +
    Native Windows NT Unicode Support
    + +
    Apache 2.0 on Windows NT now uses utf-8 for all filename + encodings. These directly translate to the underlying Unicode + file system, providing multilanguage support for all Windows + NT-based installations, including Windows 2000 and Windows XP. + This support does not extend to Windows 95, 98 or ME, which + continue to use the machine's local codepage for filesystem + access.
    + +
    Regular Expression Library Updated
    + +
    Apache 2.0 includes the Perl + Compatible Regular Expression Library (PCRE). All regular + expression evaluation now uses the more powerful Perl 5 + syntax.
    + +
    +
    top
    +
    +

    Module Enhancements

    + + +
    +
    mod_ssl
    + +
    New module in Apache 2.0. This module is an interface + to the SSL/TLS encryption protocols provided by + OpenSSL.
    + +
    mod_dav
    + +
    New module in Apache 2.0. This module implements the HTTP + Distributed Authoring and Versioning (DAV) specification for + posting and maintaining web content.
    + +
    mod_deflate
    + +
    New module in Apache 2.0. This module allows supporting + browsers to request that content be compressed before delivery, + saving network bandwidth.
    + +
    mod_auth_ldap
    + +
    New module in Apache 2.0.41. This module allows an LDAP + database to be used to store credentials for HTTP Basic + Authentication. A companion module, mod_ldap + provides connection pooling and results caching.
    + +
    mod_auth_digest
    + +
    Includes additional support for session caching across + processes using shared memory.
    + +
    mod_charset_lite
    + +
    New module in Apache 2.0. This experimental module allows + for character set translation or recoding.
    + +
    mod_file_cache
    + +
    New module in Apache 2.0. This module includes the + functionality of mod_mmap_static in Apache 1.3, + plus adds further caching abilities.
    + +
    mod_headers
    + +
    This module is much more flexible in Apache 2.0. It can now + modify request headers used by mod_proxy, and + it can conditionally set response headers.
    + +
    mod_proxy
    + +
    The proxy module has been completely rewritten to take + advantage of the new filter infrastructure and to implement a + more reliable, HTTP/1.1 compliant proxy. In addition, new + <Proxy> + configuration sections provide more readable (and internally + faster) control of proxied sites; overloaded <Directory + "proxy:..."> configuration are not supported. The module + is now divided into specific protocol support modules including + proxy_connect, proxy_ftp and + proxy_http.
    + +
    mod_negotiation
    + +
    A new ForceLanguagePriority directive can be used to assure that + the client receives a single document in all cases, rather than + NOT ACCEPTABLE or MULTIPLE CHOICES responses. In addition, the + negotiation and MultiViews algorithms have been cleaned up to + provide more consistent results and a new form of type map that + can include document content is provided.
    + +
    mod_autoindex
    + +
    Autoindex'ed directory listings can now be configured to + use HTML tables for cleaner formatting, and allow finer-grained + control of sorting, including version-sorting, and wildcard + filtering of the directory listing.
    + +
    mod_include
    + +
    New directives allow the default start and end tags for SSI elements + to be changed and allow for error and time format configuration + to take place in the main configuration file rather than in the + SSI document. Results from regular expression parsing and grouping + (now based on Perl's regular expression syntax) can be retrieved + using mod_include's variables $0 + .. $9.
    + +
    mod_auth_dbm
    + +
    Now supports multiple types of DBM-like databases using the + AuthDBMType + directive.
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.fr b/trunk/docs/manual/new_features_2_0.html.fr new file mode 100644 index 0000000000..3996750f45 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.fr @@ -0,0 +1,251 @@ + + + +Vue d'ensemble des nouvelles fonctionnalités d'Apache 2.0 - Serveur Apache HTTP + + + + + +
    <-
    +

    Vue d'ensemble des nouvelles fonctionnalités d'Apache 2.0

    +
    +

    Langues Disponibles:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    Ce document décrit les changements majeurs apportés entre les + versions 1.3 et 2.0 du serveur HTTP Apache.

    +
    + +
    top
    +
    +

    Améliorations du Système de Base

    + + +
    +
    Threading Unix
    + +
    Sur les systèmes Unix qui supportent les threads POSIX, Apache + peut à présent tourner en mode hybride multi-processus et + multi-threadé, ce qui augmente l'extensibilité et la performance + du serveur pour la plupart des configurations.
    + +
    Nouveau Système de Compilation
    + +
    Le processus de compilation a été refait de A à Z; + il utilise à présent autoconf et libtool, + ce qui rend la compilation d'Apache plus familière aux utilisateurs + d'autre logiciels de mème type.
    + +
    Support Multiprotocole
    + +
    Apache dispose désormais de l'infrastructure nécessaire pour supporter + d'autres protocoles. Le module mod_echo illustre ces + possibilités.
    + +
    Support amélioré des Plate-formes non-Unix
    + +
    Apache 2.0 se montre plus rapide et plus stable sur les plate-formes + non Unix, telles BeOS, OS/2, NetWare et Windows. L'apparition des + Modules Multi-Processus (MPMs), ainsi que de + la bibliothèque "Apache Portable Runtime" (APR) permet a Apache de + tirer parti des API natives de ces plate-formes, sans s'appuyer sur leurs + couches POSIX souvent boguées et peu optimisées.
    + +
    Nouvelle API Apache
    + +
    L'Interface de Programmation (API) des modules a beaucoup changé + avec le passage à la version 2.0. + Les problèmes d'ordre et de priorité des modules, rencontrés + avec la version 1.3, devraient maintenant être résolus. Apache 2.0 + gère ces problèmes de façon automatique. L'ordre des modules + est géré au moyen de "crochets" (hooks), ce qui rend la gestion + flexible. De nouveaux appels ont été également créés + afin de permettre l'implémentation d'autres fonctions dans les modules, + sans devoir corriger le noyau du serveur Apache.
    + +
    Support IPv6
    + +
    Sur les systèmes où la bibliothèque Apache Portable Runtime + supporte IPv6, Apache peut par défaut écouter sur des interfaces + de connexions IPv6. Les directives Listen, + NameVirtualHost et + VirtualHost supportent également + les adresses IPv6 (comme par exemple, dans "Listen[fe80::1]:8080").
    + +
    Filtering
    + +
    Il est maintenant possible d'écrire des modules Apache pour filtrer + les flux de données entrant ou sortant du serveur. A titre d'exemple, + il est possible de filtrer des directives Server Side Include de la sortie + standard d'un script CGI, au moyen du filtre INCLUDES fourni + par le module mod_include. Le module + mod_ext_filter permet quant à lui l'utilisation comme + filtres de programmes externes à Apache, de la même manière + qu'on peut utiliser des programmes CGI comme Handlers.
    + +
    Réponses d'Erreurs Multilangues
    + +
    Les messages d'erreur envoyés au navigateur existent à présent en + plusieurs langues avec des documents SSI. Ces messages peuvent être + personnalisés par l'administrateur afin de s'intégrer avec le site web.
    + +
    Simplification de la Configuration
    + +
    Beaucoup de directives, auparavant peu claires, ont été simplifiées. + Les directives Port et BindAddress, souvent + sources d'incompréhension, ont disparus. Désormais seule la directive + Listen sert de liaison pour les + adresses IP; la directive ServerName ne + précise le nom du serveur et son port que pour les redirections et la + gestion des hôtes virtuels.
    + +
    Support natif de l'Unicode sous Windows NT
    + +
    Apache 2.0 sur Windows NT utilise à présent l'utf-8 pour tous les + noms de fichiers. Ces noms de fichiers sont directement traduits vers + l'encodage Unicode du système de fichiers, ce qui permet le support + multilangue pour toutes les installations sur la famille NT de Windows, y + compris Windows 2000 et Windows XP.Ce support n'est pas fonctionnel + pour Windows 95, 98 ni ME, qui utilisent les pages de code locales pour + les accès au système de fichiers, comme auparavant.
    + +
    Mise à jour de la Bibliothèque d'Expressions Rationnelles
    + +
    Apache 2.0 contient la bibliothèque + d'expressions rationnelles compatible Perl (Perl Compatible Regular + Expression Library - PCRE). Toutes les expressions rationnelles sont dont + gérées avec la syntaxe de Perl 5, plus puissante.
    + +
    +
    top
    +
    +

    Amélioration des Modules

    + + +
    +
    mod_ssl
    + +
    Apparu dans Apache 2.0, ce module est une interface aux protocoles de + criffrement SSL/TLS fournis par OpenSSL.
    + +
    mod_dav
    + +
    Apparu dans Apache 2.0, ce module implémente les spécifications HTTP de + gestion distribuée de versions et de rédaction (Distributed Authoring and + Versioning - DAV), destinées à la mise en ligne et à la maintenance des + contenus Web.
    + +
    mod_deflate
    + +
    Module apparu dans Apachge 2.0, mod_deflate permet aux navigateurs qui + le supportent de demander la compression des contenus envoyés par le serveur. + Cela à l'avantage de réduite l'occupation de la bande passante.
    + +
    mod_auth_ldap
    + +
    Apparu dans Apache 2.0.41, ce module permet aux administrateurs + d'utiliser un arbre LDAP pour gérer la base d'utilisateurs pour les + Authentifications Basiques HTTP. Un module voisin, + mod_ldap, permet de globaliser les connexions à l'arbre LDAP + et de garder en mémoire cache ces accès.
    + +
    mod_auth_digest
    + +
    Améliore les fonctions de cache sur une session entre les différents + processus, en utilisant de la mémoire partagée.
    + +
    mod_charset_lite
    + +
    Apparu dans Apache 2.0, ce module expérimental permet la conversion + et l'enregistrement entre jeux de caractères.
    + +
    mod_file_cache
    + +
    Apparu dans Apache 2.0, ce module implémente les fonctionnalités du + module mod_mmap_static présent dans Apache 1.3, et offre des + fonctions plus avancées pour la gestion de la cache.
    + +
    mod_headers
    + +
    Ce module gagne beaucoup de flexibilité avec Apache 2.0 : on peut + désormais l'utiliser pour modifier les en-têtes des requêtes + utilisés par mod_proxy, et peut aussi positionner les + en-têtes des réponses de manière conditionnelle.
    + +
    mod_proxy
    + +
    Le module proxy a été réécrit de A à Z. Il tire + maintenant avantage de la nouvelle infrastructure de filtrage, et implémente + un mandataire plus fiable, et conforme aux normes HTTP/1.1. De nouvelles + sections de configuration ajoutées à + <Proxy> + donnent un contrôle plus lisible et un traitement plus rapide des requêtes + proxifiés; les configurations surcharchées <Directory + "proxy:..."> ne sont pas supportées. Le module a aussi été + fragmenté en plusieurs modules qui gérent chacun leur protocole : + proxy_connect, proxy_ftp et + proxy_http.
    + +
    mod_negotiation
    + +
    Une nouvelles directive, ForceLanguagePriority a été ajoutée, + elle permet de garantir que le client reçoit un seul document dans tous les + cas, au lieu de réponses NOT ACCEPTABLE ou MULTIPLE CHOICES. Les + algorithmes gérant la négociation et les vues multiples (MultiViews) ont + été nettoyés et donnent des réponses plus logiques. Un nouveau format de + carte de types (map type) qui peut aussi gérer le contenu de documents a + aussi été ajouté.
    + +
    mod_autoindex
    + +
    Les listes auto-générés par Autoindex sont à présent + configurables, et peuvent utiliser des tables HTML pour une mise en forme plus propre. + L'ordre d'affichage des fichiers est également finement paramètrable, + comme pour le tri par version, et le filtrage par caractères jokers du + listage du répertoire.
    + +
    mod_include
    + +
    De nouvelles directives permettent de modifier la valeur par défaut + des drapeaux start et end des éléments SSI. Ces directives + permettent à la configuration d'affichage de dates et heures d'être + effectuée dans le fichier de configuration principal, plutôt que dans le + document SSI. Les réponses données par des recherches par expressions + rationnelles (qui gèrent à présent les regex Perl) sont + recupérés au moyen des variables $0 à $9.
    + +
    mod_auth_dbm
    + +
    Plusieurs bases de données DBM sont supportées, et sélectionnables + au moyen de la directive AuthDBMType.
    +
    +
    +
    +

    Langues Disponibles:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.ja.euc-jp b/trunk/docs/manual/new_features_2_0.html.ja.euc-jp new file mode 100644 index 0000000000..0c37b7af4e --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.ja.euc-jp @@ -0,0 +1,253 @@ + + + +Apache 2.0 ¤Î¿·µ¡Ç½¤Î³µÍ× - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache 2.0 ¤Î¿·µ¡Ç½¤Î³µÍ×

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï¡¢Apache HTTP ¥µ¡¼¥Ð¥Ð¡¼¥¸¥ç¥ó 1.3 ¤È 2.0 + ¤Î¼ç¤Ê°ã¤¤¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥³¥¢µ¡Ç½¤Î³ÈÄ¥

    + + +
    +
    Unix ¤Î¥¹¥ì¥Ã¥É
    + +
    POSIX ¥¹¥ì¥Ã¥É¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë Unix ¥·¥¹¥Æ¥à¾å¤Ç¤Ï¡¢ + Apache ¤Ï¥Þ¥ë¥Á¥×¥í¥»¥¹¡¢¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤Î¥Ï¥¤¥Ö¥ê¥Ã¥É¥â¡¼¥É¤Ç + ¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤³¤ì¤Ë¤è¤ê + ¿¤¯¤ÎÀßÄê¤Ë¤ª¤¤¤Æ¥¹¥±¡¼¥é¥Ó¥ê¥Æ¥£¤¬¸þ¾å¤·¤Þ¤¹¡£
    + +
    ¿·¤·¤¤¥Ó¥ë¥É¥·¥¹¥Æ¥à
    + +
    ¥Ó¥ë¥É¥·¥¹¥Æ¥à¤Ï autoconf ¤È libtool + ¤Ë´ð¤Å¤¤¤¿¤â¤Î¤Ë¤Ê¤ë¤è¤¦¤Ë¡¢ + ¿·¤·¤¯½ñ¤­Ä¾¤µ¤ì¤Þ¤·¤¿¡£¤³¤ì¤Ë¤è¤ê¡¢Apache ¤Î configure ¤Î¥·¥¹¥Æ¥à¤Ï + ¾¤Î¥Ñ¥Ã¥±¡¼¥¸¤È»÷¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    ¥Þ¥ë¥Á¥×¥í¥È¥³¥ë¥µ¥Ý¡¼¥È
    + +
    Apache ¤ËÊ£¿ô¤Î¥×¥í¥È¥³¥ë¤ò°·¤¦¤¿¤á¤Îµ¡¹½¤¬È÷¤ï¤ê¤Þ¤·¤¿¡£ + Îã¤È¤·¤Æ mod_echo ¤¬½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£
    + +
    Unix °Ê³°¤Î¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Î¥µ¥Ý¡¼¥È¤Î²þÁ±
    + +
    Apache 2.0 ¤Ï BeOS¡¢OS/2¡¢Windows ¤Ê¤É¤Î Unix °Ê³°¤Î + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ç¡¢¤è¤ê®¤¯¡¢¤è¤ê°ÂÄꤷ¤ÆÆ°ºî¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¥×¥é¥Ã¥È¥Õ¥©¡¼¥àÆÃÍ­¤Î ¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥°¥â¥¸¥å¡¼¥ë (MPM) ¤È + Apache Portable Runtime (APR) ¤ÎƳÆþ¤Ë¤è¤ê¡¢ + ¥Í¥¤¥Æ¥£¥ô¤Î API ¤Ç¼ÂÁõ¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¡¢ + ¥Ð¥°¤¬Â¿¤¯¡¢À­Ç½¤Î°­¤¤¤³¤È¤¬Â¿¤¤ POSIX ¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó¥ì¥¤¥ä¤Î»ÈÍѤò + ²óÈò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤·¤¿¡£
    + +
    ¿·¤·¤¤ Apache API
    + +
    2.0 ¤Ç¤Ï¥â¥¸¥å¡¼¥ë¤Î API ¤¬Â礭¤¯ÊѤï¤ê¤Þ¤·¤¿¡£ + 1.3 ¤Ë¤¢¤Ã¤¿¥â¥¸¥å¡¼¥ë¤Î½çÈÖ/Í¥ÀèÅÙ¤ÎÌäÂê¤Î¿¤¯¤Ï + ¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤ë¤Ï¤º¤Ç¤¹¡£2.0 ¤ÏÍ¥ÀèÅÙ¤ÎÁªÂò¤ò¤Û¤È¤ó¤É¤ò¼«Æ°Åª¤Ë¹Ô¤Ê¤¤¡¢ + ¥â¥¸¥å¡¼¥ë¤Î½çÈ֤Ϥè¤ê½ÀÆðÀ­¤ò¹â¤á¤ë¤¿¤á¤Ë¥Õ¥Ã¥¯Ëè¤Ë¹Ô¤Ê¤ï¤ì¤ë¤è¤¦¤Ë + ¤Ê¤ê¤Þ¤·¤¿¡£¤Þ¤¿¡¢¥³¥¢ Apache ¥µ¡¼¥Ð¤Ë¥Ñ¥Ã¥Á¤ò¤¢¤Æ¤ë¤³¤È¤Ê¤¯ + ÄɲäΥ⥸¥å¡¼¥ëµ¡Ç½¤òÄ󶡤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¿·¤·¤¤´Ø¿ô¤¬ + Äɲ䵤ì¤Þ¤·¤¿¡£
    + +
    IPv6 ¥µ¥Ý¡¼¥È
    + +
    Apache ¤¬»ÈÍѤ·¤Æ¤¤¤ë Apache Portable Runtime library ¤¬ + IPv6 ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç¤Ï Apache ¤Ï ¥Ç¥Õ¥©¥ë¥È¤Ç + IPv6 ¤Î¥½¥±¥Ã¥È¤ò listen ¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢ + Listen, + NameVirtualHost, + VirtualHost + ¤Î³Æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ IPv6 ¤Î¥¢¥É¥ì¥¹¤ò + ¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿ (Î㤨¤Ð¡¢ + "Listen [fe80::1]:8080")¡£
    + +
    ¥Õ¥£¥ë¥¿
    + +
    Apache ¤Î¥â¥¸¥å¡¼¥ë¤Ï¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤Æ¤­¤¿¤ê¡¢¥µ¡¼¥Ð¤Ø + Á÷¤ë¥¹¥È¥ê¡¼¥à¤ËÂФ·¤ÆÆ°ºî¤¹¤ë¥Õ¥£¥ë¥¿¤È¤·¤Æ½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë + ¤Ê¤ê¤Þ¤·¤¿¡£¤³¤ì¤Ë¤è¤ê¡¢Î㤨¤Ð CGI ¥¹¥¯¥ê¥×¥È¤Î½ÐÎϤò + mod_include ¤Î INCLUDES ¥Õ¥£¥ë¥¿¤ò»È¤Ã¤Æ + Server Side Include ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò²òÀϤ¹¤ë¡¢ + ¤È¤¤¤¦¤è¤¦¤Ê¤³¤È¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤·¤¿¡£mod_ext_filter + ¤Ç³°Éô¥×¥í¥°¥é¥à¤ò¥Õ¥£¥ë¥¿¤È¤·¤ÆÆ°ºî¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤Ï CGI ¥×¥í¥°¥é¥à¤ò¥Ï¥ó¥É¥é¤È¤·¤ÆÆ°ºî¤µ¤»¤ë¤Î¤È + ¤è¤¯»÷¤¿ÊýË¡¤Ç¤Ç¤­¤Þ¤¹¡£
    + +
    ¿¸À¸ì¥¨¥é¡¼±þÅú
    + +
    ¥Ö¥é¥¦¥¶¤Ø¤Î¥¨¥é¡¼±þÅú¤Î¥á¥Ã¥»¡¼¥¸¤¬¡¢SSI ¤Îʸ½ñ¤ò»È¤Ã¤Æ + Ê£¿ô¤Î¸À¸ì¤ÇÄ󶡤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¸«¤¿¤á¤Î°ì´ÓÀ­¤òÊݤĤ¿¤á¤Ë + ´ÉÍý¼Ô¤¬¥«¥¹¥¿¥Þ¥¤¥º¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
    + +
    ÀßÄê¤Î´ÊÁDz½
    + +
    ¿¤¯¤Îº®Íð¤ò¾·¤­¤¬¤Á¤Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬´ÊÁDz½¤µ¤ì¤Þ¤·¤¿¡£ + ¤è¤¯º®Íð¤ò°ú¤­µ¯¤³¤·¤Æ¤¤¤¿ Port ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + Bind ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¤Ê¤¯¤Ê¤ê¤Þ¤·¤¿¡£Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤ß¤¬ IP ¥¢¥É¥ì¥¹¤Î¥Ð¥¤¥ó¥É¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï + ¥ê¥À¥¤¥ì¥¯¥È¤È vhost ¤Îǧ¼±¤Î¤¿¤á¤À¤±¤Ë¥µ¡¼¥Ð¤Î̾Á°¤È¥Ý¡¼¥ÈÈÖ¹æ¤ò + »ØÄꤷ¤Þ¤¹¡£
    + +
    Windows NT ¤Î¥Í¥¤¥Æ¥£¥ô Unicode ¥µ¥Ý¡¼¥È
    + +
    Windows NT ¾å¤Î Apache 2.0 ¤Ï¥Õ¥¡¥¤¥ë̾¤Îʸ»ú¥¨¥ó¥³¡¼¥ÉÁ´¤Æ¤Ë + utf-8 ¤ò»È¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤³¤ì¤é¤Ï Unicode ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë + ľÀÜÊÑ´¹¤µ¤ì¤ë¤Î¤Ç¡¢Windows 2000 ¤È Windows XP ¤ò´Þ¤à¡¢Á´¤Æ¤Î + Windows NT ·Ï¤Ç¿¸À¸ì¥µ¥Ý¡¼¥È¤¬Ä󶡤µ¤ì¤Þ¤¹¡£ + ¤³¤Î¥µ¥Ý¡¼¥È¤Ï¡¢¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥¢¥¯¥»¥¹»þ¤Ë¥í¡¼¥«¥ë¤Î + ¥³¡¼¥É¥Ú¡¼¥¸¤ò»È¤¦ Windows 95, 98, ME ¤Ë¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡£
    + +
    Àµµ¬É½¸½¥é¥¤¥Ö¥é¥ê¤Î¥¢¥Ã¥×¥Ç¡¼¥È
    + +
    Apache 2.0 ¤Ï Perl + ¸ß´¹Àµµ¬É½¸½¥é¥¤¥Ö¥é¥ê (PCRE) ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£ + Àµµ¬É½¸½¤Îɾ²Á¤Ë¤Ï¡¢¤è¤ê¶¯ÎϤˤʤä¿ Perl 5 + ¹½Ê¸¤ò»ÈÍѤ·¤Þ¤¹¡£
    + +
    +
    top
    +
    +

    ¥â¥¸¥å¡¼¥ë¤Î³ÈÄ¥

    + + +
    +
    mod_ssl
    + +
    Apache 2.0 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï OpenSSL ¤¬ + Ä󶡤¹¤ë SSL/TLS °Å¹æ¥×¥í¥È¥³¥ë¤Ø¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ç¤¹¡£
    + +
    mod_dav
    + +
    Apache 2.0 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¥¦¥§¥Ö¥³¥ó¥Æ¥ó¥Ä¤ò + Á÷¤ê¡¢°Ý»ý¤¹¤ë¤¿¤á¤Îµ¬³Ê + HTTP Distributed Authoring and Versioning (DAV) ¤ò¼ÂÁõ¤·¤Æ¤¤¤Þ¤¹¡£
    + +
    mod_deflate
    + +
    Apache 2.0 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£Á÷¿®Á°¤ËÁ÷¿®ÆâÍƤò°µ½Ì¤·¤Æ + ¥Í¥Ã¥È¥ï¡¼¥¯ÂÓ°è¤òÀáÌ󤹤롢¤È¤¤¤¦¥ê¥¯¥¨¥¹¥È¤ò¥Ö¥é¥¦¥¶¤¬ + Í×µá¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
    + +
    mod_auth_ldap
    + +
    Apache 2.0.41 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£HTTP ´ðËÜǧ¾Ú¤Î¾ÚÌÀ½ñ¤òÊݸ¤¹¤ë¤Î¤Ë¡¢ + LDAP ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò»ÈÍѤǤ­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ + ´ØÏ¢¥â¥¸¥å¡¼¥ë¤Î mod_ldap ¤Ç¡¢ + ¥³¥Í¥¯¥·¥ç¥ó¤Î¥×¡¼¥ëµ¡Ç½¤È·ë²Ì¤Î¥­¥ã¥Ã¥·¥åµ¡Ç½¤¬Ä󶡤µ¤ì¤Þ¤¹¡£
    + +
    mod_auth_digest
    + +
    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï¶¦Í­¥á¥â¥ê¤ò»È¤¦¤³¤È¤Ë¤è¤ê¡¢¥×¥í¥»¥¹¤ò¤Þ¤¿¤¤¤À + ¥»¥Ã¥·¥ç¥ó¤Î¥­¥ã¥Ã¥·¥å¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_charset_lite
    + +
    Apache 2.0 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£¤³¤Î¼Â¸³Åª¤Ê¥â¥¸¥å¡¼¥ë¤Ï + ¥­¥ã¥é¥¯¥¿¥»¥Ã¥È¤ÎÊÑ´¹¤äºÆÉä¹æ²½¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£
    + +
    mod_file_cache
    + +
    Apache 2.0 ¤Î¿·¥â¥¸¥å¡¼¥ë¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¤Ï¡¢ + Apache 1.3 ¤Ë¤ª¤±¤ë mod_mmap_static µ¡Ç½¤¬´Þ¤Þ¤ì¡¢ + ¤Þ¤¿¡¢ÄɲäΥ­¥ã¥Ã¥·¥åµ¡Ç½¤¬²Ã¤ï¤Ã¤Æ¤¤¤Þ¤¹¡£
    + +
    mod_headers
    + +
    ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï Apache 2.0 ¤ÇÈó¾ï¤Ë½ÀÆðÀ­¤¬ + ¹â¤¯¤Ê¤ê¤Þ¤·¤¿¡£mod_proxy + ¤Ç»È¤ï¤ì¤ë¥ê¥¯¥¨¥¹¥È¤Î¥Ø¥Ã¥À¤òÊѹ¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¤·¡¢ + ±þÅú¥Ø¥Ã¥À¤ò¾ò·ï¤Ë±þ¤¸¤ÆÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_proxy
    + +
    proxy ¥â¥¸¥å¡¼¥ë¤Ï¿·¤·¤¤¥Õ¥£¥ë¥¿¤Îµ¡¹½¤òÍøÍѤ¹¤ë¤¿¤á¤È¡¢ + ¤è¤ê¿®Íê¤Ç¤­¤ë¡¢HTTP/1.1 ¤Ë½àµò¤·¤¿ proxy ¤ò¼ÂÁõ¤¹¤ë¤¿¤á¤Ë + ´°Á´¤Ë½ñ¤­Ä¾¤µ¤ì¤Þ¤·¤¿¡£¤µ¤é¤Ë¡¢¿·¤·¤¤ + <Proxy> + ÀßÄꥻ¥¯¥·¥ç¥ó¤¬proxy ¤µ¤ì¤ë¥µ¥¤¥È¤Î¤è¤êÆɤߤ䤹¤¯ (ÆâÉôŪ¤Ë¤â¤è¤ê®¤¤) + ÀßÄê¤òÄ󶡤·¤Þ¤¹¡£¥ª¡¼¥Ð¡¼¥í¡¼¥É¤µ¤ì¤¿ + <Directory "proxy:... > + ÀßÄê¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤Ï proxy_connect, + proxy_ftp, proxy_http + ¤È¤¤¤Ã¤¿¡¢ÆÃÄê¤Î¥×¥í¥È¥³¥ë¤ò¥µ¥Ý¡¼¥È¤¹¤ë + ¥â¥¸¥å¡¼¥ë¤Ëʬ³ä¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_negotiation
    + +
    ¥¯¥é¥¤¥¢¥ó¥È¤¬ NOT ACCEPTABLE ¤ä MULTIPLE CHOICES ±þÅú¤Î + Âå¤ï¤ê¤Ë¾ï¤ËñÆȤÎʸ½ñ¤ò¼õ¤±¤È¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢¿·¤·¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ForceLanguagePriority + ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¤µ¤é¤Ë¡¢¤è¤ê°ì´ÓÀ­¤Î¤¢¤ë·ë²Ì¤òÄ󶡤¹¤ë¤¿¤á¤Ë + ¥Í¥´¥·¥¨¡¼¥·¥ç¥ó¤È MultiViews ¤Î¥¢¥ë¥´¥ê¥º¥à¤¬²þÁ±¤µ¤ì¡¢ + ʸ½ñ¤ÎÆâÍƤò´Þ¤á¤ë¤³¤È¤Î¤Ç¤­¤ë¡¢¿·¤·¤¤·Á¼°¤Î¥¿¥¤¥×¥Þ¥Ã¥×¤¬ + Ä󶡤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_autoindex
    + +
    Autoindex ¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ÎÆâÍÆ°ìÍ÷¤¬¡¢ + ¤­¤ì¤¤¤Ëɽ¼¨¤µ¤ì¤ë¤¿¤á¤Ë HTML ¤Î¥Æ¡¼¥Ö¥ë¤ò»È¤¦¤è¤¦¤Ë + ÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤Þ¤¿¡¢¥Ð¡¼¥¸¥ç¥ó¤Ë¤è¤ë¥½¡¼¥Æ¥£¥ó¥°¤Ê¤É¡¢ + ¤è¤êºÙ¤«¤¤¥½¡¼¥Æ¥£¥ó¥°¤ÎÀ©¸æ¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¡¢¥Ç¥£¥ì¥¯¥È¥ê + ¤ÎÆâÍÆ°ìÍ÷¤ò¥ï¥¤¥ë¥É¥«¡¼¥É¤Ë¤è¤êÁªÊ̤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤â¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_include
    + +
    ¿·¤·¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢SSI ¤Î¥Ç¥Õ¥©¥ë¥È¤Î³«»Ï¥¿¥°¤È½ªÎ»¥¿¥°¤ò + Êѹ¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤Þ¤¿¡¢¥¨¥é¡¼¤È»þ¹ï¤Î·Á¼°¤ÎÀßÄ꤬ SSI ¤Î + ʸ½ñÃæ¤Ç¤Ï¤Ê¤¯¡¢¼çÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ç¹Ô¤Ê¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + Àµµ¬É½¸½¤Î²òÀϤȥ°¥ë¡¼¥×²½¤Î·ë²Ì (Perl ¤ÎÀµµ¬É½¸½¤Î¹½Ê¸¤Ë + ´ð¤Å¤¤¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤·¤¿) ¤ò mod_include + ¤ÎÊÑ¿ô $0 .. $9 ¤Ë¤è¤ê¼èÆÀ¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    mod_auth_dbm
    + +
    AuthDBMType + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¡¢Ê£¿ô¤Î DBM ·¿¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥µ¥Ý¡¼¥È¤¹¤ë + ¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.ko.euc-kr b/trunk/docs/manual/new_features_2_0.html.ko.euc-kr new file mode 100644 index 0000000000..268baeadbf --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.ko.euc-kr @@ -0,0 +1,233 @@ + + + +Apache 2.0ÀÇ »õ·Î¿î ±â´É °³¿ä - Apache HTTP Server + + + + + +
    <-
    +

    Apache 2.0ÀÇ »õ·Î¿î ±â´É °³¿ä

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 1.3 ¹öÀü°ú 2.0 ¹öÀü°£ÀÇ ÁÖµÈ Â÷ÀÌÁ¡À» + ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ÇÙ½É ºÎºÐ¿¡¼­ ³ª¾ÆÁø Á¡

    + + +
    +
    À¯´Ð½º ¾²·¹µå
    + +
    POSIX ¾²·¹µå¸¦ Áö¿øÇÏ´Â À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ¿©·¯ ÇÁ·Î¼¼½º¿Í ¿©·¯ ¾²·¹µå·Î È¥ÇÕÇؼ­ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + ÀüºÎ´Â ¾Æ´ÏÁö¸¸ ¸¹Àº °æ¿ì È®Àå°¡´É¼º(scalability)À» ³ôÀδÙ.
    + +
    »õ·Î¿î ÄÄÆÄÀÏ ½Ã½ºÅÛ
    + +
    ÄÄÆÄÀÏ ½Ã½ºÅÛÀÌ autoconf¿Í libtoolÀ» + »ç¿ëÇϵµ·Ï ÀçÀÛ¼ºµÇ¾ú´Ù. ±×·¡¼­ ¾ÆÆÄÄ¡ ±¸¼º ½Ã½ºÅÛÀÌ ´Ù¸¥ + ÆÐÅ°Áöµé°ú Á»´õ ºñ½ÁÇØÁ³´Ù.
    + +
    ¿©·¯ ÇÁ·ÎÅäÄÝ Áö¿ø
    + +
    ÀÌÁ¦ ¾ÆÆÄÄ¡´Â ¿©·¯ ÇÁ·ÎÅäÄÝÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖ´Â ±¸Á¶¸¦ + °®Ãè´Ù. mod_echo°¡ ±× ¿¹·Î ÀÛ¼ºµÇ¾ú´Ù.
    + +
    ºñÀ¯´Ð½º Ç÷¡Æû¿¡ ´ëÇÑ ´õ ³ªÀº Áö¿ø
    + +
    Apache 2.0´Â BeOS, OS/2, À©µµ¿ìÁî¿Í °°Àº ºñÀ¯´Ð½º + Ç÷¡Æû¿¡¼­ ´õ ºü¸£°í ¾ÈÁ¤È­µÇ¾ú´Ù. ÀÌÁ¦ ¾ÆÆÄÄ¡´Â À̵é + Ç÷¡Æû¿¡¼­ ¹ö±×°¡ ¸¹°í ¼º´ÉÀÌ ´À·È´ø POSIX ȣȯÃþ ´ë½Å + ÀÚü API·Î ±¸ÇöµÈ Ç÷¡Æû ƯÀ¯ÀÇ ´ÙÁßó¸® ¸ðµâ + (MPM)°ú Apache Portable Runtime (APR)À» »ç¿ëÇÏ¿© ±¸ÇöµÈ´Ù.
    + +
    »õ·Î¿î ¾ÆÆÄÄ¡ API
    + +
    ¸ðµâ API°¡ 2.0¿¡¼­ »ó´çÈ÷ º¯Çß´Ù. 1.3ÀÇ ¿©·¯ ¸ðµâ + ¼ø¼­¿Í ¿ì¼±¼øÀ§ ¹®Á¦°¡ »ç¶óÁ³´Ù. 2.0Àº À̸¦ ´ëºÎºÐ ÀÚµ¿À¸·Î + ó¸®Çϸç, ¸ðµâ ¼ø¼­´Â ÀÌÁ¦ ´õ À¯¿¬ÇÑ ÈÅ(hook) ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù. + ¶Ç, ¾ÆÆÄÄ¡ ¼­¹ö ÇÙ½É ºÎºÐÀ» ¼öÁ¤ÇÏÁö ¾Ê°í »õ·Î¿î ¸ðµâ ±â´ÉÀ» + Á¦°øÇÏ´Â ÇÔ¼ö°¡ Ãß°¡µÇ¾ú´Ù.
    + +
    IPv6 Áö¿ø
    + +
    ÇÏÀ§ Apache Portable Runtine ¶óÀ̺귯¸®°¡ IPv6¸¦ Áö¿øÇÏ´Â + ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î IPv6 ¼ÒÄÏÀ» ±â´Ù¸°´Ù. ¶Ç, + Listen, + NameVirtualHost, + VirtualHost Áö½Ã¾î°¡ + IPv6 ¼ýÀÚ ÁÖ¼Ò¸¦ Áö¿øÇÑ´Ù. (¿¹, + "Listen [fe80::1]:8080").
    + +
    ÇÊÅ͸µ
    + +
    ÀÌÁ¦ ¾ÆÆÄÄ¡ ¸ðµâÀ» ¼­¹ö·Î ¿À°í°¡´Â È帧¿¡ ´ëÇÑ + ÇÊÅÍ·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î mod_includeÀÇ + INCLUDES ÇÊÅ͸¦ »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ® Ãâ·Â¿¡¼­ + Server Side Include Áö½Ã¾î¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. + mod_ext_filter ¸ðµâÀº CGI ÇÁ·Î±×·¥À» + Çڵ鷯·Î »ç¿ëÇÏ´Â °Í°ú °°ÀÌ ¿ÜºÎ ÇÁ·Î±×·¥À» ÇÊÅÍ·Î + »ç¿ëÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.
    + +
    ´Ù±¹¾î ¿À·ù ÀÀ´ä
    + +
    ºê¶ó¿ìÀú·Î º¸³»´Â ¿À·ù ÀÀ´ä¹®ÀÌ ÀÌÁ¦ SSI ¹®¼­¸¦ + »ç¿ëÇÏ¿© ´Ù±¹¾î·Î Á¦°øµÈ´Ù. °ü¸®ÀÚ´Â ÅëÀÏµÈ ¿Ü°üÀ» À§ÇØ + ÀÌ ¹®¼­¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    °£´ÜÇØÁø ¼³Á¤
    + +
    È¥¶õÀ» ÁÖ´ø ¸¹Àº Áö½Ã¾îµéÀÌ °£´ÜÇØÁ³´Ù. ÀÚÁÖ È¥¶õÀ» + ÁÖ´ø Port¿Í BindAddress Áö½Ã¾î´Â + ¾ø¾îÁö°í IP ÁÖ¼Ò ¿¬°á¿¡ + Listen Áö½Ã¾î¸¸À» + »ç¿ëÇÑ´Ù. ServerName + Áö½Ã¾î´Â ¸®´ÙÀÌ·º¼Ç°ú °¡»óÈ£½ºÆ® ÀνĿ¡¸¸ »ç¿ëµÉ ¼­¹ö¸í°ú + Æ÷Æ®¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    Windows NT À¯´ÏÄÚµå ÀÚü Áö¿ø
    + +
    Windows NT¿¡¼­ Apache 2.0Àº ÀÌÁ¦ ¸ðµç ÆÄÀϸí ÀÎÄÚµù¿¡ + utf-8À» »ç¿ëÇÑ´Ù. ÆÄÀϸíÀº ÇÏÀ§ À¯´ÏÄÚµå ÆÄÀϽýºÅÛÀ¸·Î Á÷Á¢ + º¯¿ªµÇ¾î, Windows 2000°ú Windows XP¸¦ Æ÷ÇÔÇÑ ¸ðµç Windows NT±â¹Ý + ½Ã½ºÅÛ¿¡ ´Ù±¹¾î Áö¿øÀ» Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀº Windows 95, + 98, ME¿¡´Â Áö¿øµÇÁö¾Ê°í, ÆÄÀϽýºÅÛ Á¢±Ù¿¡ Àü°ú °°ÀÌ ½Ã½ºÅÛÀÇ + Áö¿ª ÄÚµåÆäÀÌÁö¸¦ »ç¿ëÇÑ´Ù.
    + +
    Á¤±ÔÇ¥Çö½Ä ¶óÀ̺귯¸® Updated
    + +
    Apache 2.0Àº Perlȣȯ + Á¤±ÔÇ¥Çö½Ä ¶óÀ̺귯¸® (Perl Compatible Regular Expression + Library) (PCRE)¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌÁ¦ ¸ðµç Á¤±ÔÇ¥Çö½Ä¿¡ + ´õ °­·ÂÇÑ Perl 5 ¹®¹ýÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    +
    top
    +
    +

    ¸ðµâ¿¡¼­ ³ª¾ÆÁø Á¡

    + + +
    +
    mod_ssl
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº OpenSSLÀÌ + Á¦°øÇÏ´Â SSL/TLS ¾Ïȣȭ ÇÁ·ÎÅäÄÝÀÇ ÀÎÅ×ÆäÀ̽º´Ù.
    + +
    mod_dav
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº À¥ÄÁÅÙÃ÷¸¦ + ¿Ã¸®°í °ü¸®ÇϱâÀ§ÇÑ HTTP Distributed Authoring and Versioning + (DAV) Ç¥ÁØÀ» ±¸ÇöÇÑ´Ù.
    + +
    mod_deflate
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ³×Æ®¿÷ »ç¿ë·®À» + ÁÙÀ̱âÀ§ÇØ ºê¶ó¿ìÀú¿¡°Ô ÄÁÅÙÃ÷¸¦ ¾ÐÃàÇؼ­ º¸³»¶ó°í ¿äûÇÒ + ¼ö ÀÖ´Ù.
    + +
    mod_auth_ldap
    + +
    Apache 2.0.41¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº HTTP + Basic Authentication¿¡ »ç¿ëÇÏ´Â Á¤º¸¸¦ LDAP µ¥ÀÌÅͺ£À̽º¿¡ + ÀúÀåÇÑ´Ù. °ü·ÃµÈ mod_ldap ¸ðµâÀº + ¿¬°áÇ®(connection pool)À» Á¦°øÇÏ°í, °á°ú¸¦ ij½ÌÇÑ´Ù.
    + +
    mod_auth_digest
    + +
    °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º°£ ¼¼¼Ç ij½ÌÀ» Áö¿øÇÑ´Ù.
    + +
    mod_charset_lite
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ½ÇÇèÀûÀÎ ¸ðµâÀº + ¹®ÀÚÁýÇÕ º¯È¯°ú ¹®ÀÚÁýÇÕ ÀçÀÛ¼º ±â´ÉÀ» Á¦°øÇÑ´Ù.
    + +
    mod_file_cache
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº Apache 1.3ÀÇ + mod_mmap_static ±â´É¿¡ ´õ ³ªÀº ij½¬ ±â´ÉÀ» + Ãß°¡Çß´Ù.
    + +
    mod_headers
    + +
    ÀÌ ¸ðµâÀº Apache 2.0¿¡¼­ ´õ À¯¿¬ÇØÁ³´Ù. ÀÌÁ¦ + mod_proxy°¡ »ç¿ëÇÏ´Â ¿äû Çì´õ¸¦ ¼öÁ¤ÇÒ + ¼ö ÀÖ°í, °æ¿ì¿¡ µû¶ó¼­ ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù.
    + +
    mod_proxy
    + +
    ÀÌ ÇÁ·Ï½Ã ¸ðµâÀº »õ·Î¿î ÇÊÅÍ ±¸Á¶¸¦ ÀÌ¿ëÇÏ°í ´õ ¹ÏÀ»¸¸ÇÑ + HTTP/1.1 ÇÁ·Ï½Ã¸¦ ±¸ÇöÇϱâÀ§ÇØ ¿ÏÀüÈ÷ ÀçÀÛ¼ºµÇ¾ú´Ù. Ãß°¡·Î + »õ·Î¿î <Proxy> + ¼³Á¤ ¼½¼ÇÀº ÇÁ·Ï½Ã ¼³Á¤À» ´õ ½±°Ô (±×¸®°í ³»ºÎÀûÀ¸·Î ´õ + ºü¸£°Ô) ¸¸µç´Ù. °ú°Å <Directory "proxy:..."> + ¼³Á¤Àº ÀÌÁ¦ Áö¿øÇÏÁö ¾Ê´Â´Ù. ¸ðµâÀº proxy_connect, + proxy_ftp, proxy_http¿Í °°ÀÌ + Áö¿øÇÏ´Â ÇÁ·ÎÅäÄÝ º°·Î ³ª´²Á³´Ù.
    + +
    mod_negotiation
    + +
    »õ·Î¿î ForceLanguagePriority + Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®°¡ NOT ACCEPTABLEÀ̳ª MULTIPLE CHOICES + ÀÀ´ä ´ë½Å ¸ðµç °æ¿ì ÇÑ ¹®¼­¸¦ ¹ÞÀ½À» º¸ÀåÇÑ´Ù. Ãß°¡·Î + Çù»ó ¾Ë°í¸®Áò°ú MultiViews ¾Ë°í¸®ÁòÀÌ ´õ ÀÏ°üµÈ °á°ú¸¦ + ³»µµ·Ï ¼öÁ¤µÇ¾ú°í, ¹®¼­ ³»¿ëÀ» Æ÷ÇÔÇÒ ¼ö ÀÖ´Â »õ·Î¿î Çü½ÄÀÇ + type mapÀÌ Ãß°¡µÇ¾ú´Ù.
    + +
    mod_autoindex
    + +
    ÀÚµ¿À¸·Î »ý¼ºµÈ µð·ºÅ丮 ¸ñ·ÏÀÌ ÀÌÁ¦ ´õ ±ò²ûÇÑ Çü½ÄÀ» + À§ÇØ HTML Ç¥¸¦ »ç¿ëÇÒ ¼ö ÀÖ°Ô µÇ¾ú°í, ¹öÀü Á¤·ÄÀ» Æ÷ÇÔÇÏ¿© + Á¤·Ä¼ø¼­¸¦ ÀÚ¼¼È÷ Á¶ÀýÇÒ ¼ö ÀÖÀ¸¸ç, µð·ºÅ丮 ¸ñ·ÏÀ» ¿ÍÀϵåÄ«µå·Î + °É·¯³¾ ¼ö ÀÖ´Ù.
    + +
    mod_include
    + +
    »õ·Î¿î Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© SSI ¿ä¼ÒÀÇ ±âº» ½ÃÀÛ ÅÂ±×¿Í + ¸¶Ä§ ű׸¦ º¯°æÇÒ ¼ö ÀÖ°í, ¿À·ù¿Í ½Ã°£Çü½ÄÀ» SSI ¹®¼­¿Ü¿¡ + ÁÖ ¼³Á¤ÆÄÀÏ¿¡¼­µµ ¼³Á¤ÇÒ ¼ö ÀÖ°Ô µÇ¾ú´Ù. mod_include¿¡¼­ (ÀÌÁ¦ + Perl Á¤±ÔÇ¥Çö½Ä ¹®¹ýÀ¸·Î) Á¤±ÔÇ¥Çö½Ä ÆĽ̰ú ±×·ìÀÇ + °á°ú¸¦ mod_includeÀÇ $0 + ... $9 º¯¼ö·Î ¾òÀ» ¼ö ÀÖ´Ù.
    + +
    mod_auth_dbm
    + +
    ÀÌÁ¦ AuthDBMType + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿©·¯ DBM·ù µ¥ÀÌÅͺ£À̽º¸¦ Áö¿øÇÑ´Ù.
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.pt-br b/trunk/docs/manual/new_features_2_0.html.pt-br new file mode 100644 index 0000000000..7aa074d9df --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.pt-br @@ -0,0 +1,242 @@ + + + +Descrição das novas funcionalidades do Apache 2.0 - Servidor HTTP Apache + + + + + +
    <-
    +

    Descrição das novas funcionalidades do Apache 2.0

    +
    +

    Línguas Disponíveis:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    Esse documento descreve algumas das mudanças principais + entre as versões 1.3 e 2.0 do Servidor HTTP Apache.

    +
    + +
    top
    +
    +

    Principais Melhorias

    + + +
    +
    Threading Unix
    + +
    Em sistemas Unix com suporte a threads POSIX, o Apache pode + funcionar em modo híbrido multiprocesso e multithread. Não funciona + em todas configurações, mas melhora a escalabilidade em muitas.
    + +
    Novo Sistema de Compilação
    + +
    O sistema de compilação foi reescrito do zero para utilizar o + autoconf e o libtool, tornando a + configuração do sistema Apache mais similar a de outros + pacotes.
    + +
    Suporte Multi-protocolo
    + +
    O Apache possui agora uma infraestrutura feita para suportar + múltiplos protocolos. O módulo mod_echo é um + exemplo ilustrativo de sua utilização.
    + +
    Suporte Aperfeiçoado para Plataformas Não-Unix
    + +
    O Apache 2.0 está mais rápido e mais estável em plataformas + Não-Unix como BeOS, OS/2 e Windows. Com a introdução de módulos + multi-processamento (MPMs) específicos e a + Apache Portable Runtime (APR), essas plataformas estão implementando + as suas APIs nativas, evitando as camadas de emulação POSIX que se + mostravam lentas e defeituosas.
    + +
    Nova API Apache
    + +
    A API para módulos mudou significativamente na versão 2.0. + Muitos dos problemas de ordenamento/prioridade da versão + 1.3 foram resolvidos. A versão 2.0 faz o ordenamento automático + "per-hook" para permitir mais flexibilidade. Novas chamadas foram + adicionadas para fornecer capacidades adicionais sem a necessidade + de se aplicar nenhum patch ao servidor Apache principal.
    + +
    Suporte IPv6
    + +
    Em sistemas onde o IPv6 é suportado pela biblioteca de base + Apache Portable Runtime, o Apache monitora por padrão + as interfaces IPv6. Em adição as diretrizes Listen, NameVirtualHost e VirtualHost, suportam correntes (strings) de + endereços numéricos do tipo IPv6. (ex. "Listen + [fe80::1]:8080").
    + +
    Filtrando
    + +
    Os módulos do Apache agora são feito filtros que + agem na corrente do conteúdo na medida que este é entregue, tanto + na entrada quando na saída de dados do servidor. É possível então, + por exemplo, que o retorno de dados de scripts CGI sejam analisados + pelas diretrizes do "Server Side Include" usando o filtro INCLUDES do mod_include. O módulo mod_ext_filter, permite que programas externos trabalhem + como filtros do mesmo modo que aplicações CGI funcionam como + manipuladores.
    + +
    Respostas de Erro Multi-linguais
    + +
    Mensagens de erro para o navegador agora são fornecidas em + diversas línguas, usando documentos SSI. Podem ser personalizadas + pelo administrador que desejar definir seus próprios + padrões.
    + +
    Configuração Simplificada
    + +
    Muitas diretrizes confusas foram simplificadas. Entre elas, + Port e BindAddress não existem + mais; apenas a diretriz Listen + é usada para direcionar endereços IP; a diretriz ServerName especifica o nome do servidor + e o número da porta apenas para redirecionamento e reconhecimento + de hospedeiros virtuais.
    + +
    Suporte Nativo ao Unicode do Windows NT
    + +
    O Apache 2.0 para Windows NT agora usa utf-8 para codificação + de todos os nomes de arquivos. A tradução para o sistema + base Unicode, torna possível o suporte multi-lingual para todas + as instalações da família NT, incluindo o Windows 2000 e Windows XP. + Esse suporte não se estende ao Windows 95, 98 ou ME, que + continuam usando o código de páginas da máquina local para o + acesso ao sistema de arquivos.
    + +
    Biblioteca de Expressões Regulares Atualizada
    + +
    O Apache 2.0 inclui a Biblioteca + de Expressões Regulares Compatíveis Perl (PCRE). Todas as + avaliações de expressões regulares usam a mais poderosa sintaxe + do Perl 5.
    + +
    +
    top
    +
    +

    Melhorias nos Módulos

    + + +
    +
    mod_ssl
    + +
    Novo módulo no Apache 2.0. Esse módulo é uma interface + para os protocolos de codificação SSL/TLS fornecidos pela + OpenSSL.
    + +
    mod_dav
    + +
    Novo módulo no Apache 2.0. Este módulo implementa as + especificações de Autoria Distribuída e Versões (Distributed + Authoring and Versioning - DAV) para HTTP, para a publicação + e a manutenção de conteúdo da web.
    + +
    mod_deflate
    + +
    Novo módulo no Apache 2.0. Esse módulo permite o suporte + a navegadores que solicitam que o conteúdo seja comprimido antes + da entrega, economizando banda da rede.
    + +
    mod_auth_ldap
    + +
    Novo módulo no Apache 2.0.41. Este módulo permite que + bancos de dados LDAP sejam usados para armazenar credenciais + para Autenticação Básica HTTP. Um módulo que o acompanha mod_ldap, fornece a conciliação de conexões e armazenamento + de resultados.
    + +
    mod_auth_digest
    + +
    Inclui suporte adicional para armazenamento de sessões + através de processos que usam memória compartilhada.
    + +
    mod_charset_lite
    + +
    Novo módulo no Apache 2.0. Este modo experimental permite a + tradução de tabelas de caracteres ou re-codificação.
    + +
    mod_file_cache
    + +
    Novo módulo no Apache 2.0. Esse módulo inclui a funcionalidade + do mod_mmap_static do Apache 1.3, além de disponibilizar + outras possibilidades de armazenamento.
    + +
    mod_headers
    + +
    Este módulo está muito mais flexível no Apache 2.0. Pode + modificar pedidos de cabeçalhos usados pelo mod_proxy, e incondicionalmente pode ajustar cabeçalhos de respostas.
    + +
    mod_proxy
    + +
    O módulo proxy foi totalmente reescrito para levar vantagem + da nova infraestrutura de filtro e implementar um proxy mais fiel e + de acordo com o padrão HTTP/1.1. Além disso, uma nova seção + de configuração <Proxy> fornece controles mais legíveis (e internamente + mais rápidos) para sites com proxies; configurações + sobrecarregadas <Directory "proxy:...">, não + são suportadas. O módulo agora é dividido em suporte + de protocolos específicos incluindo proxy_connect, + proxy_ftp e proxy_http.
    + +
    mod_negotiation
    + +
    A nova diretriz ForceLanguagePriority pode ser usada para assegurar que + o cliente receba um único documento em todos os casos, ao invés de + respostas "NOT ACCEPTABLE" ou "MULTIPLE CHOICES". Novos algoritmos + de negociação e visões múltiplas (MultiViews) foram organizados para + obter resultados mais consistentes e uma nova forma de tipo de mapa + (map type) que podem incluir o conteúdo de documentos é fornecido.
    + +
    mod_autoindex
    + +
    As listagens de diretórios automáticas podem ser + configuradas para usar tabelas HTML para formatações mais limpas + e permitir controles mais acurados de classificação, incluindo + ordenação por versão e filtro da lista de + diretórios através de caracteres-coringa.
    + +
    mod_include
    + +
    Novas diretrizes permitem que as tags padrões start e + end para elementos SSI, possam ser alteradas e permitir que + as configurações de formatos de erro e hora sejam incluídos no + arquivo de configuração principal, ao invés de serem adicionadas + ao documento SSI. Resultados de análises de expressões regulares + e agrupamento (baseadas na sintaxe de expressões regulares do Perl) + podem ser obtidas usando as variáveis do módulo mod_include, de $0 a $9.
    + +
    mod_auth_dbm
    + +
    Agora suporta múltiplos tipos de banco de dados similares ao DBM, + usando a diretriz AuthDBMType + .
    + +
    +
    +
    +

    Línguas Disponíveis:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.html.ru.koi8-r b/trunk/docs/manual/new_features_2_0.html.ru.koi8-r new file mode 100644 index 0000000000..e7c4466c23 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.html.ru.koi8-r @@ -0,0 +1,252 @@ + + + +ïÂÚÏÒ ÎÏ×ÙÈ ×ÏÚÍÏÖÎÏÓÔÅÊ × Apache 2.0 - HTTP ÓÅÒ×ÅÒ Apache + + + + + +
    <-
    +

    ïÂÚÏÒ ÎÏ×ÙÈ ×ÏÚÍÏÖÎÏÓÔÅÊ × Apache 2.0

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    +
    This translation may be out of date. Check the + English version for recent changes.
    + +

    üÔÏÔ ÄÏËÕÍÅÎÔ ÏÐÉÓÙ×ÁÅÔ ÏÓÎÏ×ÎÙÅ ÒÁÚÌÉÞÉÑ ÍÅÖÄÕ ×ÅÒÓÉÑÍÉ 1.3 É 2.0 HTTP ÓÅÒ×ÅÒÁ Apache

    +
    + +
    top
    +
    +

    õÌÕÞÛÅÎÉÑ × ÑÄÒÅ ÓÅÒ×ÅÒÁ

    + + +
    +
    íÎÏÇÏÐÏÔÏÞÎÏÓÔØ × UNIX
    + +
    îÁ UNIX ÓÉÓÔÅÍÁÈ, ËÏÔÏÒÙÅ ÐÏÄÄÅÒÖÉ×ÁÀÔ ÐÏÔÏËÉ (ÎÉÔÉ) ÓÔÁÎÄÁÒÔÁ POSIX, + Apache ÔÅÐÅÒØ ÍÏÖÅÔ ×ÙÐÏÌÎÑÔØÓÑ × ÇÉÂÒÉÄÎÏÍ ÍÎÏÇÏÐÒÏÃÅÓÓÏ×Ï - + ÍÎÏÇÏÐÏÔÏÞÎÏÍ ÒÅÖÉÍÅ. üÔÏ ÓÐÏÓÏÂÓÔ×ÕÅÔ ÒÁÓÛÉÒÑÅÍÏÓÔÉ + ÓÉÓÔÅÍÙ ÄÌÑ ÍÎÏÇÉÈ, ÎÏ ÎÅ ÄÌÑ ×ÓÅÈ ÓÐÏÓÏÂÏ× ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ.
    + +
    îÏ×ÁÑ ÓÉÓÔÅÍÁ ÓÂÏÒËÉ
    + +
    óÉÓÔÅÍÁ ÓÂÏÒËÉ ÂÙÌÁ ÐÏÌÎÏÓÔØÀ ÉÚÍÅÎÅÎÁ, É ÔÅÐÅÒØ ÏÓÎÏ×Ù×ÁÅÔÓÑ ÎÁ autoconf É libtool. + üÔÏ ÄÅÌÁÅÔ ÐÒÏÃÅÓÓ ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ Apache ÂÏÌÅÅ ÐÏÈÏÖÉÍ ÎÁ ÐÏÄÏÂÎÙÊ ÐÒÏÃÅÓÓ × ÄÒÕÇÉÈ ÐÒÏÇÒÁÍÍÎÙÈ + ÐÒÏÄÕËÔÁÈ.
    + +
    ðÏÄÄÅÒÖËÁ ÒÁÚÌÉÞÎÙÈ ÐÒÏÔÏËÏÌÏ×
    + +
    Apache ÔÅÐÅÒØ ÉÍÅÅÔ ÓÐÅÃÉÁÌØÎÕÀ ÉÎÆÒÁÓÔÒÕËÔÕÒÕ, + ÓÐÏÓÏÂÎÕÀ ÏÂÓÌÕÖÉ×ÁÔØ ÒÁÚÌÉÞÎÙÅ ÐÒÏÔÏËÏÌÙ. + íÏÄÕÌØ mod_echo ÂÙÌ ÎÁÐÉÓÁÎ × ËÁÞÅÓÔ×Å + ÐÒÉÍÅÒÁ ÜÔÏÍÕ.
    + +
    õÌÕÞÛÅÎÎÁÑ ÐÏÄÄÅÒÖËÁ ÏÔÌÉÞÎÙÈ ÏÔ UNIX + ÐÌÁÔÆÏÒÍ
    + +
    Apache 2.0 ÓÔÁÌ ÒÁÂÏÔÁÔØ ÂÙÓÔÒÅÅ É ÎÁÄÅÖÎÅÅ + ÎÁ ÏÔÌÉÞÎÙÈ ÏÔ UNIX ÐÌÁÔÆÏÒÍÁÈ, ÔÁËÉÈ ËÁË: BeOS, + OS/2 É Windows. ó ××ÅÄÅÎÉÅÍ ÎÏ×ÙÈ ÓÐÅÃÉÆÉÞÎÙÈ + ÄÌÑ ËÁÖÄÏÊ ÐÌÁÔÆÏÒÍÙ ÍÕÌØÔÉ-ÐÒÏÃÅÓÓÎÙÈ ÍÏÄÕÌÅÊ (MPMs) É + ÂÉÂÌÉÏÔÅËÉ Apache Portable Runtime (APR), ÜÔÉ ÐÌÁÔÆÏÒÍÙ + ÔÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÀÔÓÑ Ó ÐÏÍÏÝØÀ ÉÈ ÓÏÂÓÔ×ÅÎÎÙÈ API, ÞÔÏ + ÐÏÚ×ÏÌÑÅÔÓÑ ÉÚÂÅÖÁÔØ ××ÅÄÅÎÉÑ ÚÁÞÁÓÔÕÀ ÎÅÐÒÁ×ÉÌØÎÏ ÒÁÂÏÔÁÀÝÉÈ + ÉÚ-ÚÁ ÂÏÌØÛÏÇÏ ËÏÌÉÞÅÓÔ×Á ÏÛÉÂÏË POSIX - ÜÍÕÌÉÒÕÀÝÉÈ ÓÌÏÅ×.
    + +
    îÏ×ÙÊ API ÄÌÑ Apache
    + +
    API ÄÌÑ ÎÁÐÉÓÁÎÉÑ ÍÏÄÕÌÅÊ ÚÎÁÞÉÔÅÌØÎÏ ÉÚÍÅÎÉÌÓÑ × ×ÅÒÓÉÉ 2.0 + íÎÏÇÉÅ ÉÚ ÐÒÏÂÌÅÍ ×ÅÒÓÉÉ 1.3, Ó×ÑÚÁÎÎÙÅ Ó ÐÏÒÑÄËÏÍ ÓÌÅÄÏ×ÁÎÉÑ + ÍÏÄÕÌÅÊ É ÉÈ ÐÒÉÏÒÉÔÅÔÁÍÉ, ÄÏÌÖÎÙ ÉÓÞÅÚÎÕÔØ. ÷ ×ÅÒÓÉÉ 2.0 + ÍÎÏÇÉÅ ÉÚ ÐÏÄÏÂÎÙÈ ×ÅÝÅÊ ÄÅÌÁÀÔÓÑ Á×ÔÏÍÁÔÉÞÅÓËÉ, É ÔÅÐÅÒØ + ÐÏÒÑÄÏË ÓÌÅÄÏ×ÁÎÉÑ ÍÏÄÕÌÅÊ ÏÐÒÅÄÅÌÑÅÔÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ ÓÐÅÃÉÁÌØÎÙÈ + ÐÒÏÇÒÁÍÍÎÙÈ ËÒÀÞËÏ× (hooks), ÏÔÞÅÇÏ ÎÁÓÔÒÏÊËÁ ÓÅÒ×ÅÒÁ ÓÔÁÎÏ×ÉÔÓÑ + ÂÏÌÅÅ ÇÉÂËÏÊ. ôÁËÖÅ ÂÙÌÉ ÄÏÂÁ×ÌÅÎÙ ÎÏ×ÙÅ ÆÕÎËÃÉÉ, ËÏÔÏÒÙÅ + ÐÒÅÄÏÓÔÁ×ÌÑÀÔ ÄÏÐÏÌÎÉÔÅÌØÎÙÅ ×ÏÚÍÏÖÎÏÓÔÉ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ÍÏÄÕÌÅÊ, + ÉÚÂÁ×ÌÑÑ ÏÔ ÎÅÏÂÈÏÄÉÍÏÓÔÉ ×ÎÅÓÅÎÉÑ ËÁËÉÈ - ÌÉÂÏ ÉÚÍÅÎÅÎÉÊ × ÑÄÒÏ + ÓÅÒ×ÅÒÁ.
    + +
    ðÏÄÄÅÒÖËÁ ÐÒÏÔÏËÏÌÁ IPv6
    + +
    îÁ ÓÉÓÔÅÍÁÈ, ÇÄÅ ÐÒÏÔÏËÏÌ IPv6 ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ + ÂÁÚÏ×ÏÊ ÂÉÂÌÉÏÔÅËÏÊ Apache Portable Runtime, Apache + ÐÏ ÕÍÏÌÞÁÎÉÀ ÐÏÌÕÞÁÅÔ ×ÏÚÍÏÖÎÏÓÔØ ÓÌÕÛÁÔØ IPv6 ÓÏËÅÔÙ + (sockets). ÷ ÄÏÂÁ×ÏË Ë ÜÔÏÍÕ ÄÉÒÅËÔÉ×Ù Listen, NameVirtualHost É VirtualHost ÍÏÇÕÔ ÒÁÂÏÔÁÔØ Ó ÁÄÒÅÓÎÙÍÉ ÓÔÒÏËÁÍÉ, + ÚÁÄÁÎÎÙÍÉ × ÆÏÒÍÁÔÅ IPv6 (Ô.Å. ÎÁÐÒÉÍÅÒ "Listen [fe80::1]:8080").
    + +
    éÓÐÏÌØÚÏ×ÁÎÉÅ ÆÉÌØÔÒÏ×
    + +
    íÏÄÕÌÉ Apache ÔÅÐÅÒØ ÍÏÇÕÔ ÂÙÔØ ÎÁÐÉÓÁÎÙ ËÁË ÆÉÌØÔÒÙ, + ÏÂÒÁÂÁÔÙ×ÁÀÝÉÅ ÐÏÔÏËÉ ÄÁÎÎÙÈ, ËÏÔÏÒÙÅ ÐÒÉÈÏÄÑÔ ÉÌÉ ÕÈÏÄÑÔ + ÉÚ ÓÅÒ×ÅÒÁ. üÔÏ ÐÏÚ×ÏÌÑÅÔ, Ë ÐÒÉÍÅÒÕ, ÄÁÎÎÙÍ, Ñ×ÌÑÀÝÉÍÓÑ + ÒÅÚÕÌØÔÁÔÏÍ ÒÁÂÏÔÙ CGI-ÓËÒÉÐÔÁ, ÂÙÔØ ÏÂÒÁÂÏÔÁÎÎÙÍÉ SSI + ÆÉÌØÔÒÏÍ INCLUDES, ÐÒÅÄÏÓÔÁ×ÌÑÅÍÙÍ ÍÏÄÕÌÅÍ + mod_include. íÏÄÕÌØ mod_ext_filter + ÐÏÚ×ÏÌÑÅÔ ×ÎÅÛÎÉÍ ÐÒÏÇÒÁÍÍÁÍ ÉÓÐÏÌÎÑÔØ ÒÏÌØ ÆÉÌØÔÒÏ× ÔÏÞÎÏ ÔÁË ÖÅ + ËÁË É CGI ÐÒÏÇÒÁÍÍÁÍ ÐÏÚ×ÏÌÑÅÔÓÑ ÄÅÊÓÔ×Ï×ÁÔØ × ËÁÞÅÓÔ×Å + ÏÂÒÁÂÏÔÞÉËÏ× (handlers).
    + +
    óÏÏÂÝÅÎÉÑ ÏÂ ÏÛÉÂËÁÈ ÎÁ ÒÁÚÎÙÈ ÑÚÙËÁÈ
    + +
    óÏÏÂÝÅÎÉÑ Ï ÏÛÉÂËÁÈ, ÐÏÓÙÌÁÅÍÙÅ ÂÒÁÕÚÅÒÕ, ÔÅÐÅÒØ + ÐÒÅÄÓÔÁ×ÌÅÎÙ ÎÁ ÎÅÓËÏÌØËÉÈ ÑÚÙËÁÈ É ÉÓÐÏÌØÚÕÀÔ SSI + ÔÅÈÎÏÌÏÇÉÀ. ïÎÉ ÍÏÇÕÔ ÂÙÔØ ÌÅÇËÏ ÏÔÒÅÄÁËÔÉÒÏ×ÁÎÙ + ÁÄÍÉÎÉÓÔÒÁÔÏÒÏÍ ÐÏÄ Ó×ÏÉ ÎÕÖÄÙ.
    + +
    õÐÒÏÝÅÎÎÁÑ ËÏÎÆÉÇÕÒÁÃÉÑ
    + +
    íÎÏÇÉÅ ÚÁÐÕÔÁÎÎÙÅ ÄÉÒÅËÔÉ×Ù ÂÙÌÉ ÕÐÒÏÝÅÎÙ. îÁÉÂÏÌÅÅ + ÓÂÉ×ÁÀÝÉÅ Ó ÔÏÌËÕ Port É BindAddress ÂÙÌÉ ÕÂÒÁÎÙ; + ÄÌÑ ÐÒÉ×ÑÚËÉ Ë IP ÁÄÒÅÓÕ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ ÄÉÒÅËÔÉ×Á + Listen; ÄÉÒÅËÔÉ×Á + ServerName ÏÐÒÅÄÅÌÑÅÔ ÉÍÑ ÓÅÒ×ÅÒÁ É ÎÏÍÅÒ ÐÏÒÔÁ + ÔÅÐÅÒØ ÔÏÌØËÏ ÄÌÑ ÐÅÒÅÎÁÐÒÁ×ÌÅÎÉÊ É ÒÁÂÏÔÙ Ó ×ÉÒÔÕÁÌØÎÙÍÉ ÈÏÓÔÁÍÉ.
    + +
    ðÏÄÄÅÒÖËÁ ÀÎÉËÏÄÁ Windows NT
    + +
    Apache 2.0 ÎÁ Windows NT ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÅÔ ËÏÄÉÒÏ×ËÕ utf-8 + ÄÌÑ ÒÁÂÏÔÙ Ó ÉÍÅÎÁÍÉ ÆÁÊÌÏ×. üÔÏ ÐÏÚ×ÏÌÑÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ + ÎÉÖÅÌÅÖÁÝÕÀ ÆÁÊÌÏ×ÕÀ ÓÉÓÔÅÍÕ, ÒÁÂÏÔÁÀÝÕÀ × ÆÏÒÍÁÔÅ Unicode, + ÞÔÏ ÐÒÅÄÏÓÔÁ×ÌÑÅÔ ÐÏÄÄÅÒÖËÕ ÓÅÒ×ÅÒÏÍ ÍÎÏÇÏÑÚÙÞÎÏÓÔÉ ÄÌÑ ×ÓÅÈ NT- + ÓÉÓÔÅÍ, ×ËÌÀÞÁÑ Windows 2000 É Windows XP. + üÔÏ ÎÅ ÒÁÓÐÒÏÓÔÒÁÎÑÅÔÓÑ ÎÁ ÔÁËÉÅ ÏÐÅÒÁÃÉÏÎÎÙÅ ÓÉÓÔÅÍÙ, ËÁË + Windows 95, 98 ÉÌÉ ME, ËÏÔÏÒÙÅ ÄÌÑ ÏÂÒÁÝÅÎÉÑ Ë ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÅ + ÉÓÐÏÌØÚÕÀÔ ÌÏËÁÌØÎÙÅ ÍÁÛÉÎÎÙÅ ËÏÄÏ×ÙÅ ÓÔÒÁÎÉÃÙ.
    + +
    îÏ×ÁÑ ÂÉÂÌÉÏÔÅËÁ ÄÌÑ ÒÁÂÏÔÙ Ó ÒÅÇÕÌÑÒÎÙÍÉ ×ÙÒÁÖÅÎÑÍÉ
    + +
    ÷ ÓÏÓÔÁ× Apache 2.0 ÂÙÌÁ ×ËÌÀÞÅÎÁ + ÂÉÂÌÉÏÔÅËÁ ÄÌÑ ÒÁÂÏÔÙ Ó Perl-ÓÏ×ÍÅÓÔÉÍÙÍÉ ÒÅÇÕÌÑÒÎÙÍÉ ×ÙÒÁÖÅÎÑÍÉ (PCRE). + ÷ÓÅ ÒÅÇÕÌÑÒÎÙÅ ×ÙÒÁÖÅÎÉÑ ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÀÔ ÂÏÌÅÅ ÍÏÝÎÙÊ ÓÉÎÔÁËÓÉÓ Perl 5.
    + +
    +
    top
    +
    +

    õÌÕÞÛÅÎÉÑ × ÍÏÄÕÌÑÈ ÓÅÒ×ÅÒÁ

    + + +
    +
    mod_ssl
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ Ñ×ÌÑÅÔÓÑ ÉÎÔÅÒÆÅÊÓÏÍ + Ë ÐÒÏÔÏËÏÌÁÍ ÛÉÆÒÏ×ÁÎÉÑ SSL/TLS, ÐÒÅÄÏÓÔÁ×ÌÑÅÍÙÍÉ OpenSSL.
    + +
    mod_dav
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ×ÎÅÄÒÑÅÔ ÓÐÅÃÉÆÉËÁÃÉÀ + Distributed Authoring and Versioning (DAV), ÐÏÚ×ÏÌÑÀÝÕÀ ÕÐÒÁ×ÌÑÔØ + ÓÏÄÅÒÖÉÍÙÍ ÓÁÊÔÁ ÐÏÓÒÅÄÓÔ×ÏÍ ÒÁÓÛÉÒÅÎÎÏÇÏ ÐÒÏÔÏËÏÌÁ HTTP.
    + +
    mod_deflate
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ ÂÒÁÕÚÅÒÁÍ, ÐÏÄÄÅÒÖÉ×ÁÀÝÉÍ + ÄÁÎÎÕÀ ÔÅÈÎÏÌÏÇÉÀ, ÚÁÐÒÁÛÉ×ÁÔØ ÄÁÎÎÙÅ × ÓÖÁÔÏÍ ×ÉÄÅ, ÞÔÏ ÓÏËÒÁÝÁÅÔ ÎÁÇÒÕÚËÕ ÎÁ + ÓÅÔØ.
    + +
    mod_auth_ldap
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0.41. üÔÏÔ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÂÁÚÕ ÄÁÎÎÙÈ LDAP + ÄÌÑ ÈÒÁÎÅÎÉÑ ÉÍÅÎ É ÐÁÒÏÌÅÊ ÐÏÌØÚÏ×ÁÔÅÌÅÊ, ÎÅÏÂÈÏÄÉÍÙÈ ÐÒÉ ÁÕÔÅÎÔÉÆÉËÁÃÉÉ ÐÏ ÍÅÔÏÄÕ + Basic. óÏÐÕÔÓÔ×ÕÀÝÉÊ ÅÍÕ ÍÏÄÕÌØ mod_ldap ÏÂÅÓÐÅÞÉ×ÁÅÔ ×ÏÚÍÏÖÎÏÓÔØ + ÓÏÚÄÁÎÉÑ ÏÞÅÒÅÄÅÊ ÐÏÄËÌÀÞÅÎÉÊ (connection pools) É ËÜÛÉÒÏ×ÁÎÉÑ ÒÅÚÕÌØÔÁÔÏ×.
    + +
    mod_auth_digest
    + +
    ÷ËÌÀÞÁÅÔ ÄÏÐÏÌÎÉÔÅÌØÎÕÀ ÐÏÄÄÅÒÖËÕ ËÜÛÉÒÏ×ÁÎÉÑ ÓÅÓÓÉÊ + ÐÒÏÃÅÓÓÁÍÉ, ÂÌÁÇÏÄÁÒÑ ÉÓÐÏÌØÚÏ×ÁÎÉÀ ÏÂÝÅÊ ÏÂÌÁÓÔÉ ÐÁÍÑÔÉ (ÒÁÚÄÅÌÅÎÉÀ + ÐÁÍÑÔÉ).
    + +
    mod_charset_lite
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ + ÏÓÕÝÅÓÔ×ÌÑÔØ ÐÅÒÅ×ÏÄ ÉÚ ÏÄÎÏÇÏ ÎÁÂÏÒÁ ÓÉÍ×ÏÌÏ× (character set) × ÄÒÕÇÏÊ É ÉÚ ÏÄÎÏÊ + ËÏÄÉÒÏ×ËÉ × ÄÒÕÇÕÀ.
    + +
    mod_file_cache
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ×ËÌÀÞÁÅÔ × ÓÅÂÑ + ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ ÍÏÄÕÌÑ mod_mmap_static ÉÚ Apache 1.3 + ÐÌÀÓ ÎÏ×ÙÅ ×ÏÚÍÏÖÎÏÓÔÉ ËÜÛÉÒÏ×ÁÎÉÑ.
    + +
    mod_headers
    + +
    üÔÏÔ ÍÏÄÕÌØ ÓÔÁÌ ÂÏÌÅÅ ÇÉÂËÉÍ × Apache 2.0. ïÎ ÐÏÚ×ÏÌÑÅÔ + ÍÏÄÉÆÉÃÉÒÏ×ÁÔØ ÚÁÇÏÌÏ×ËÉ ÚÁÐÒÏÓÏ×, ÉÓÐÏÌØÚÕÅÍÙÈ ÍÏÄÕÌÅÍ + mod_proxy, É ÍÏÖÅÔ ×ËÌÀÞÁÔØ × ÏÔ×ÅÔ ÓÅÒ×ÅÒÁ ÚÁÇÏÌÏ×ËÉ × + ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ÒÁÚÌÉÞÎÙÈ ÕÓÌÏ×ÉÊ.
    + +
    mod_proxy
    + +
    ðÒÏËÓÉ ÍÏÄÕÌØ ÂÙÌ ÐÏÌÎÏÓÔØÀ ÐÅÒÅÐÉÓÁÎ, É ÔÅÐÅÒØ ×ËÌÀÞÁÅÔ + × ÓÅÂÑ ÐÒÅÉÍÕÝÅÓÔ×Á ÎÏ×ÏÊ ÆÉÌØÔÒÏ×ÏÊ ÉÎÆÒÁÓÔÒÕËÔÕÒÙ É ÉÓÐÏÌØÚÕÅÔ + ÂÏÌÅÅ ÎÁÄÅÖÎÕÀ, ÓÏ×ÍÅÓÔÉÍÕÀ Ó HTTP/1.1 ÐÒÏËÓÉ-ÔÅÈÎÏÌÏÇÉÀ. ÷ ÄÏÂÁ×ÏË + Ë ÜÔÏÍÕ ÂÙÌÁ ××ÅÄÅÎÁ ÎÏ×ÁÑ ÓÅËÃÉÑ <Proxy>, ËÏÔÏÒÕÀ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÈ ÆÁÊÌÁÈ, ÞÔÏ + ÏÂÅÓÐÅÞÉ×ÁÅÔ ÂÏÌÅÅ ÕÄÏÂÎÙÊ (É ÂÏÌÅÅ ÂÙÓÔÒÙÊ ÄÌÑ ÑÄÒÁ ÓÅÒ×ÅÒÁ) ËÏÎÔÒÏÌØ ÎÁÄ ÓÁÊÔÁÍÉ, + ÉÓÐÏÌØÚÕÀÝÉÍÉ proxy-ÔÅÈÎÏÌÏÇÉÀ. ðÅÒÅÇÒÕÖÅÎÎÁÑ ËÏÎÆÉÇÕÒÁÃÉÑ <Directory "proxy:..."> + ÂÏÌÅÅ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ. íÏÄÕÌØ ÔÅÐÅÒØ ÒÁÚÄÅÌÅÎ ÎÁ ÏÔÄÅÌØÎÙÅ ÓÐÅÃÉÆÉÞÎÙÅ ÍÏÄÕÌÉ, + ÐÏÄÄÅÒÖÉ×ÁÀÝÉÅ ÒÁÚÌÉÞÎÙÅ ÐÒÏÔÏËÏÌÙ. üÔÉ ÍÏÄÕÌÉ ×ËÌÀÞÁÀÔ × ÓÅÂÑ proxy_connect, proxy_ftp + É proxy_http.
    + +
    mod_negotiation
    + +
    äÏÂÁ×ÌÅÎÁ ÎÏ×ÁÑ ÄÉÒÅËÔÉ×Á ForceLanguagePriority, ÄÌÑ ÔÏÇÏ ÞÔÏÂÙ ×ÍÅÓÔÏ ÏÔ×ÅÔÏ× ÓÅÒ×ÅÒÁ + NOT ACCEPTABLE ÉÌÉ MULTIPLE CHOICES ×ÓÅÇÄÁ ÐÒÅÄÏÓÔÁ×ÌÑÔØ ÐÏÌØÚÏ×ÁÔÅÌÀ + ÏÐÒÅÄÅÌÅÎÎÙÊ ÄÏËÕÍÅÎÔ. ÷ ÄÏÐÏÌÎÅÎÉÅ Ë ÜÔÏÍÕ ÁÌÇÏÒÉÔÍÙ + ÎÅÇÏÃÉÁÃÉÉ (negotiation) É MultiViews ÂÙÌÉ ×ÙÞÉÝÅÎÙ É ÉÓÐÒÁ×ÌÅÎÙ, ÄÌÑ + ÏÂÅÓÐÅÞÅÎÉÑ ÂÏÌÅÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÒÅÚÕÌØÔÁÔÁ, Á ÔÁËÖÅ ÐÏÑ×ÉÌÁÓØ ×ÏÚÍÏÖÎÏÓÔØ + ×ËÌÀÞÅÎÉÑ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏÇÏ ÓÏÄÅÒÖÉÍÏÇÏ ÄÏËÕÍÅÎÔÏ× × ËÁÒÔÕ ÔÉÐÏ× (type map).
    + +
    mod_autoindex
    + +
    ìÉÓÔÉÎÇÉ Á×ÔÏÉÎÄÅËÓÉÒÕÅÍÙÈ ËÁÔÁÌÏÇÏ× ÔÅÐÅÒØ ÍÏÇÕÔ ×ÙÄÁ×ÁÔØÓÑ × ×ÉÄÅ + HTML-ÔÁÂÌÉÃ. ðÏÑ×ÉÌÁÓØ ×ÏÚÍÏÖÎÏÓÔØ ÂÏÌÅÅ ÇÉÂËÏÊ ÓÏÒÔÉÒÏ×ËÉ, ×ËÌÀÞÁÑ ÓÏÒÔÉÒÏ×ËÕ ÐÏ ×ÅÒÓÉÑÍ É + ÓÏÒÔÉÒÏ×ËÕ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ ÕÎÉ×ÅÒÓÁÌØÎÙÈ ÓÉÍ×ÏÌÏ× (wildcard).
    + +
    mod_include
    + +
    ÷×ÅÄÅÎÙ ÎÏ×ÙÅ ÄÉÒÅËÔÉ×Ù, ËÏÔÏÒÙÅ ÐÏÚ×ÏÌÑÀÔ ÉÚÍÅÎÉÔØ ÎÁÞÁÌØÎÙÊ É ËÏÎÅÞÎÙÊ + ÔÅÇÉ SSI ÜÌÅÍÅÎÔÏ×, ÚÁÄÁ×ÁÅÍÙÅ ÐÏ ÕÍÏÌÞÁÎÉÀ, Á ÔÁËÖÅ ÐÒÅÄÏÓÔÁ×ÌÑÀÔ ×ÏÚÍÏÖÎÏÓÔØ + ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ ÆÏÒÍÁÔÁ ÓÏÏÂÝÅÎÉÊ Ï ÏÛÉÂËÁÈ É ×ÒÅÍÅÎÉ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ + × ÇÌÁ×ÎÏÍ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÍ ÆÁÊÌÅ, Á ÎÅ × SSI ÄÏËÕÍÅÎÔÅ. òÅÚÕÌØÔÁÔÙ + ÏÂÒÁÂÏÔËÉ ÒÅÇÕÌÑÒÎÙÈ ×ÙÒÁÖÅÎÉÊ (ÔÅÐÅÒØ ÏÓÎÏ×Ù×ÁÀÝÉÈÓÑ ÎÁ ÓÉÎÔÁËÓÉÓÅ + ÒÅÇÕÌÑÒÎÙÈ ×ÙÒÁÖÅÎÉÊ ÑÚÙËÁ Perl) ÍÏÇÕÔ ÂÙÔØ ÐÏÌÕÞÅÎÙ ÐÒÉ ÐÏÍÏÝÉ ÐÅÒÅÍÅÎÎÙÈ + $0 .. $9 ÍÏÄÕÌÑ mod_include.
    + +
    mod_auth_dbm
    + +
    ôÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÍÎÏÇÏÞÉÓÌÅÎÎÙÅ ÔÉÐÙ DBM-ÐÏÄÏÂÎÙÈ ÂÁÚ ÄÁÎÎÙÈ ÐÏÓÒÅÄÓÔ×ÏÍ + ÄÉÒÅËÔÉ×Ù AuthDBMType.
    + +
    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.xml b/trunk/docs/manual/new_features_2_0.xml new file mode 100644 index 0000000000..a9598506d0 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml @@ -0,0 +1,234 @@ + + + + + + + + + +Overview of new features in Apache 2.0 + + +

    This document describes some of the major changes between the + 1.3 and 2.0 versions of the Apache HTTP Server.

    +
    + +Upgrading to 2.0 from 1.3 + +
    + Core Enhancements + +
    +
    Unix Threading
    + +
    On Unix systems with POSIX threads support, Apache can + now run in a hybrid multiprocess, multithreaded mode. This + improves scalability for many, but not all configurations.
    + +
    New Build System
    + +
    The build system has been rewritten from scratch to be + based on autoconf and libtool. + This makes Apache's configuration system more similar to + that of other packages.
    + +
    Multiprotocol Support
    + +
    Apache now has some of the infrastructure in place to + support serving multiple protocols. mod_echo has + been written as an example.
    + +
    Better support for non-Unix + platforms
    + +
    Apache 2.0 is faster and more stable on non-Unix + platforms such as BeOS, OS/2, and Windows. With the + introduction of platform-specific multi-processing modules (MPMs) and the + Apache Portable Runtime (APR), these platforms are now + implemented in their native API, avoiding the often buggy and + poorly performing POSIX-emulation layers.
    + +
    New Apache API
    + +
    The API for modules has changed significantly for 2.0. + Many of the module-ordering/-priority problems from 1.3 should + be gone. 2.0 does much of this automatically, and module ordering + is now done per-hook to allow more flexibility. Also, new calls + have been added that provide additional module capabilities + without patching the core Apache server.
    + +
    IPv6 Support
    + +
    On systems where IPv6 is supported by the underlying + Apache Portable Runtime library, Apache gets IPv6 listening + sockets by default. Additionally, the Listen, NameVirtualHost, and VirtualHost directives support + IPv6 numeric address strings (e.g., "Listen + [fe80::1]:8080").
    + +
    Filtering
    + +
    Apache modules may now be written as filters which act on + the stream of content as it is delivered to or from the + server. This allows, for example, the output of CGI scripts to + be parsed for Server Side Include directives using the + INCLUDES filter in mod_include. The + module mod_ext_filter allows external programs to + act as filters in much the same way that CGI programs can act as + handlers.
    + +
    Multilanguage Error Responses
    + +
    Error response messages to the browser are now provided in + several languages, using SSI documents. They may be customized + by the administrator to achieve a consistent look and feel.
    + +
    Simplified configuration
    + +
    Many confusing directives have been simplified. The often + confusing Port and BindAddress directives + are gone; only the Listen + directive is used for IP address binding; the ServerName directive specifies the + server name and port number only for redirection and vhost + recognition.
    + +
    Native Windows NT Unicode Support
    + +
    Apache 2.0 on Windows NT now uses utf-8 for all filename + encodings. These directly translate to the underlying Unicode + file system, providing multilanguage support for all Windows + NT-based installations, including Windows 2000 and Windows XP. + This support does not extend to Windows 95, 98 or ME, which + continue to use the machine's local codepage for filesystem + access.
    + +
    Regular Expression Library Updated
    + +
    Apache 2.0 includes the Perl + Compatible Regular Expression Library (PCRE). All regular + expression evaluation now uses the more powerful Perl 5 + syntax.
    + +
    +
    + +
    + Module Enhancements + +
    +
    mod_ssl
    + +
    New module in Apache 2.0. This module is an interface + to the SSL/TLS encryption protocols provided by + OpenSSL.
    + +
    mod_dav
    + +
    New module in Apache 2.0. This module implements the HTTP + Distributed Authoring and Versioning (DAV) specification for + posting and maintaining web content.
    + +
    mod_deflate
    + +
    New module in Apache 2.0. This module allows supporting + browsers to request that content be compressed before delivery, + saving network bandwidth.
    + +
    mod_auth_ldap
    + +
    New module in Apache 2.0.41. This module allows an LDAP + database to be used to store credentials for HTTP Basic + Authentication. A companion module, mod_ldap + provides connection pooling and results caching.
    + +
    mod_auth_digest
    + +
    Includes additional support for session caching across + processes using shared memory.
    + +
    mod_charset_lite
    + +
    New module in Apache 2.0. This experimental module allows + for character set translation or recoding.
    + +
    mod_file_cache
    + +
    New module in Apache 2.0. This module includes the + functionality of mod_mmap_static in Apache 1.3, + plus adds further caching abilities.
    + +
    mod_headers
    + +
    This module is much more flexible in Apache 2.0. It can now + modify request headers used by mod_proxy, and + it can conditionally set response headers.
    + +
    mod_proxy
    + +
    The proxy module has been completely rewritten to take + advantage of the new filter infrastructure and to implement a + more reliable, HTTP/1.1 compliant proxy. In addition, new + Proxy + configuration sections provide more readable (and internally + faster) control of proxied sites; overloaded <Directory + "proxy:..."> configuration are not supported. The module + is now divided into specific protocol support modules including + proxy_connect, proxy_ftp and + proxy_http.
    + +
    mod_negotiation
    + +
    A new ForceLanguagePriority directive can be used to assure that + the client receives a single document in all cases, rather than + NOT ACCEPTABLE or MULTIPLE CHOICES responses. In addition, the + negotiation and MultiViews algorithms have been cleaned up to + provide more consistent results and a new form of type map that + can include document content is provided.
    + +
    mod_autoindex
    + +
    Autoindex'ed directory listings can now be configured to + use HTML tables for cleaner formatting, and allow finer-grained + control of sorting, including version-sorting, and wildcard + filtering of the directory listing.
    + +
    mod_include
    + +
    New directives allow the default start and end tags for SSI elements + to be changed and allow for error and time format configuration + to take place in the main configuration file rather than in the + SSI document. Results from regular expression parsing and grouping + (now based on Perl's regular expression syntax) can be retrieved + using mod_include's variables $0 + .. $9.
    + +
    mod_auth_dbm
    + +
    Now supports multiple types of DBM-like databases using the + AuthDBMType + directive.
    + +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_0.xml.de b/trunk/docs/manual/new_features_2_0.xml.de new file mode 100644 index 0000000000..e95a0201d7 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.de @@ -0,0 +1,256 @@ + + + + + + + + + +Übersicht der neuen Funktionen in Apache 2.0 + + +

    Dieses Dokument beschreibt einige der wichtigsten Änderungen + des Apache HTTP Servers 2.0 gegenüber der Version 1.3.

    +
    + +Upgrade von 1.3 auf 2.0 + +
    + Core-Erweiterungen + +
    +
    Unix-Threading
    + +
    Auf Unix-Systemen mit Unterstützung für POSIX-Threads, + kann Apache jetzt in einem Multi-Process, Multi-Threaded Hybrid-Mode + gestartet werden. Dies verbessert die Skalierfähigkeit für + viele, jedoch nicht unbedingt alle Konfigurationen.
    + +
    Neues Build-System
    + +
    Das Build-System wurde komplett auf der Basis von + autoconf und libtool neu geschrieben. Dadurch + wird das Apache-Konfigurationssystem dem vieler anderer Packages + ähnlicher.
    + +
    Multi-Protokoll-Unterstützung
    + +
    Apache stellt jetzt die notwendigen Grundfunktionalitäten + bereit, um mehrere Protokolle unterstützen und verarbeiten zu + können. mod_echo wurde hierfür als + Beispiel geschrieben.
    + +
    Bessere Unterstützung von + Nicht-Unix-Plattformen
    + +
    Apache 2.0 ist schneller und stabiler auf Nicht-Unix-Plattformen + wie BeOS, OS/2 und Windows. Mit der Einführung von + Plattform-spezifischen Multi-Processing Modulen + (MPMs) und der Apache Portable Runtime (APR), sind diese Plattformen + jetzt in ihrem nativen API implementiert, wodurch die Verwendung der + häufig fehlerbehafteten und schlecht funktionierenden + POSIX-Emulation-Layer vermieden wird.
    + +
    Neues Apache API
    + +
    Das API für Module hat sich in 2.0 stark verändert. + Die meisten der Sortierungs-/Prioritätsprobleme von Modulen bei + 1.3 sollten nun verschwunden sein. In 2.0 wird hiervon vieles + automatisch durchgeführt. Die Modulsortierung wird jetzt + über einen pre-hook vorgenommen, um mehr Flexibilität + zu bieten. Außerdem wurden neue API-Calls hinzugefügt, + die zusätzliche Modulfähigkeiten zur Verfügung stellen, + ohne den Apache-Kern anpassen zu müssen.
    + +
    IPv6-Unterstützung
    + +
    Auf Systemen, bei denen die zugrundeliegende Apache Portable + Runtime-Bibliothek IPv6 unterstützt, bekommt Apache + standarmäßig IPv6 Listening Sockets. Zusätzlich + unterstützen die Konfigurationsanweisungen Listen, NameVirtualHost und VirtualHost numerische IPv6-Adressangaben + (z.B., "Listen [fe80::1]:8080").
    + +
    Filterung
    + +
    Apache-Module können jetzt als Filter entwickelt und zur + Filterung des rein- und rausgehenden Datenstroms des Servers + eingesetzt werden. Hierdurch kann beispielsweise die Ausgabe von + CGI-Skripten durch den INCLUDES-Filter von + mod_include bearbeitet werden und so Server-Side + Include-Anweisungen ausgeführt werden. Das Modul + mod_ext_filter erlaubt externen Programmen + als Filter zu agieren, in der gleichen Weise wie CGI-Programme als + Eingabe dienen können.
    + +
    Mehrsprachige Fehlermeldungen
    + +
    Fehlermeldungen die an den Browser rausgehen, stehen jetzt als + SSI-Dokumente in verschiedenen Sprachen zur Verfügung. Sie + können bei Bedarf durch den Administrator angepasst werden, + um ein einheitliches Design zu erreichen.
    + +
    Vereinfachte Konfiguration
    + +
    Viele der verwirrenden Konfigurationsanweisungen wurden vereinfacht. + Die oft für Verwirrung sorgenden Port- und + BindAddress-Anweisungen wurden entfernt. + Ausschließlich die Listen-Anweisung wird nun zum + Setzen von IP-Addressen und Portnummern benutzt. + Der Servername und die Portnummer, die für Weiterleitungen und + zur Erkennung virtueller Server verwendet werden, werden über + die ServerName-Anweisung + konfiguriert.
    + +
    Native Windows NT Unicode-Unterstützung
    + +
    Apache 2.0 auf Windows NT benutzt jetzt utf-8 für alle + Dateinamen-Kodierungen. Diese werden direkt auf das zugrundeliegende + Unicode-Dateisystem abgebildet, wodurch Mehrsprach-Unterstützung + für alle Windows NT-basierten Installationen, inklusive Windows + 2000 und Windows XP, zur Verfügung gestellt wird. + Diese Unterstützung ist nicht auf Windows 95, 98 oder ME + verfügbar. Hier wird weiterhin die jeweils lokale Codepage des + Rechners für den Zugriff auf das Dateisystem verwendet.
    + +
    Bibliothek für reguläre Ausdrücke aktualisiert
    + +
    Apache 2.0 enthält die "Perl Compatible + Regular Expression Library" (PCRE). + Bei der Auswertung aller regulären Ausdrücke wird nun + die leistungsfähigere Syntax von Perl 5 verwendet.
    + +
    +
    + +
    + Modul-Erweiterungen + +
    +
    mod_ssl
    + +
    Neues Modul in Apache 2.0. Dieses Modul ist ein Interface + zu den von OpenSSL bereitgestellten SSL/TLS + Verschlüsselungs-Protokollen.
    + +
    mod_dav
    + +
    Neues Modul in Apache 2.0. Dieses Modul implementiert die HTTP + Distributed Authoring and Versioning (DAV) Spezifikation zur + Erzeugung und Pflege von Web-Inhalten.
    + +
    mod_deflate
    + +
    Neues Modul in Apache 2.0. Dieses Modul erlaubt es Browsern, die + dies unterstützen, eine Komprimierung des Inhaltes vor der + Auslieferung anzufordern, um so Netzwerk-Bandbreite zu sparen.
    + +
    mod_auth_ldap
    + +
    Neues Modul in Apache 2.0.41. Diese Modul ermöglicht + die Verwendung einer LDAP-Datenbank zur Speicherung von + Berechtigungsdaten für die HTTP-Basic-Authentication. + Ein Begleitmodul, mod_ldap, stellt einen + Verbindungs-Pool und die Pufferung von Abfrageergebnissen zur + Verfügung. +
    + +
    mod_auth_digest
    + +
    Zusätzliche Unterstützung für + prozessübergreifendes Session-Caching mittels Shared-Memory. +
    + +
    mod_charset_lite
    + +
    Neues Modul in Apache 2.0. + Dieses experimentelle Modul erlaubt Zeichensatz-Übersetzungen oder + -Umschlüsselung.
    + +
    mod_file_cache
    + +
    Neues Modul in Apache 2.0. Dieses Modul beinhaltet die + Funktionalität von mod_mmap_static aus Apache 1.3, + plus einige weitere Caching-Funktionen.
    + +
    mod_headers
    + +
    Dieses Modul ist in Apache 2.0 deutlich flexibler geworden. Es + kann jetzt die von mod_proxy genutzten Request-Header + manipulieren und es ist möglich Response-Header auf Basis von + definierten Bedingungen zu verändern.
    + +
    mod_proxy
    + +
    Das Proxy Modul wurde komplett neu geschrieben um die + Möglichkeiten der neuen Filter-Funktionalität + auszuschöpfen und um einen zuverlässigen Proxy zu haben, der + den HTTP/1.1-Spezifikationen entspricht. Neue Proxy + -Konfigurationsabschnitte bieten eine besser lesbare (und intern + schnellere) Kontrolle der vermittelten Seiten. + Die überladenen <Directory + "proxy:...">-Konfigurationen werden nicht + mehr unterstützt. Das Modul ist nun in mehrere Module + unterteilt, die jeweils ein bestimmtes Übertragungsprotokoll + unterstützen, wie proxy_connect, + proxy_ftp und proxy_http.
    + +
    mod_negotiation
    + +
    Die neue Konfigurationsanweisung ForceLanguagePriority + kann benutzt werden, um sicherzustellen, dass ein Client auf jeden + Fall ein einzelnes Dokument, anstatt einer NOT ACCEPTABLE- oder + MULTIPLE CHOICES-Antwort, bekommt. Zusätzlich wurden die + Negotiation- und Multiview-Algorithmen angepasst um einheitlichere + Ergebnisse zu liefern. Außerdem wird ein neues + Type-Map-Format bereitgestellt, das Dokumenteninhalte direkt + enthalten kann.
    + +
    mod_autoindex
    + +
    Automatisch erzeugte Verzeichnisindizes können zur besseren + Übersichtlichkeit durch HTML-Tabellen dargestellt werden. + Genauere Sortierungen, wie Sortierung nach Versionsnummer und + Wildcard-Filterung des Verzeichnisindizes werden unterstützt.
    + +
    mod_include
    + +
    Neue Anweisungen erlauben es, die Standard Start- und Endtags von + SSI-Elementen zu ändern. Zudem können die Default-Formate + für Fehlermeldungen und Zeitangaben nun ebenfalls in der + Serverkonfiguration vorgenommen werden. Auf die Ergebnisse der + Auswertung und Gruppierung von regulären Ausdrücken (jetzt + auf Basis der Perl-Syntax für reguläre Ausdrücke) kann + über die mod_include Variablen $0 + bis $9 zugegriffen werden.
    + +
    mod_auth_dbm
    + +
    DBM-ähnliche Datenbanken werden jetzt durch die + Konfigurationsaweisung AuthDBMType unterstützt.
    +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_0.xml.fr b/trunk/docs/manual/new_features_2_0.xml.fr new file mode 100644 index 0000000000..5c869e2532 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.fr @@ -0,0 +1,238 @@ + + + + + + + + + + Vue d'ensemble des nouvelles fonctionnalités d'Apache 2.0 + + +

    Ce document décrit les changements majeurs apportés entre les + versions 1.3 et 2.0 du serveur HTTP Apache.

    +
    + + Migrer à 2.0 depuis la version 1.3 + +
    + Améliorations du Système de Base + +
    +
    Threading Unix
    + +
    Sur les systèmes Unix qui supportent les threads POSIX, Apache + peut à présent tourner en mode hybride multi-processus et + multi-threadé, ce qui augmente l'extensibilité et la performance + du serveur pour la plupart des configurations.
    + +
    Nouveau Système de Compilation
    + +
    Le processus de compilation a été refait de A à Z; + il utilise à présent autoconf et libtool, + ce qui rend la compilation d'Apache plus familière aux utilisateurs + d'autre logiciels de mème type.
    + +
    Support Multiprotocole
    + +
    Apache dispose désormais de l'infrastructure nécessaire pour supporter + d'autres protocoles. Le module mod_echo illustre ces + possibilités.
    + +
    Support amélioré des Plate-formes non-Unix
    + +
    Apache 2.0 se montre plus rapide et plus stable sur les plate-formes + non Unix, telles BeOS, OS/2, NetWare et Windows. L'apparition des + Modules Multi-Processus (MPMs), ainsi que de + la bibliothèque "Apache Portable Runtime" (APR) permet a Apache de + tirer parti des API natives de ces plate-formes, sans s'appuyer sur leurs + couches POSIX souvent boguées et peu optimisées.
    + +
    Nouvelle API Apache
    + +
    L'Interface de Programmation (API) des modules a beaucoup changé + avec le passage à la version 2.0. + Les problèmes d'ordre et de priorité des modules, rencontrés + avec la version 1.3, devraient maintenant être résolus. Apache 2.0 + gère ces problèmes de façon automatique. L'ordre des modules + est géré au moyen de "crochets" (hooks), ce qui rend la gestion + flexible. De nouveaux appels ont été également créés + afin de permettre l'implémentation d'autres fonctions dans les modules, + sans devoir corriger le noyau du serveur Apache.
    + +
    Support IPv6
    + +
    Sur les systèmes où la bibliothèque Apache Portable Runtime + supporte IPv6, Apache peut par défaut écouter sur des interfaces + de connexions IPv6. Les directives Listen, + NameVirtualHost et + VirtualHost supportent également + les adresses IPv6 (comme par exemple, dans "Listen[fe80::1]:8080").
    + +
    Filtering
    + +
    Il est maintenant possible d'écrire des modules Apache pour filtrer + les flux de données entrant ou sortant du serveur. A titre d'exemple, + il est possible de filtrer des directives Server Side Include de la sortie + standard d'un script CGI, au moyen du filtre INCLUDES fourni + par le module mod_include. Le module + mod_ext_filter permet quant à lui l'utilisation comme + filtres de programmes externes à Apache, de la même manière + qu'on peut utiliser des programmes CGI comme Handlers.
    + +
    Réponses d'Erreurs Multilangues
    + +
    Les messages d'erreur envoyés au navigateur existent à présent en + plusieurs langues avec des documents SSI. Ces messages peuvent être + personnalisés par l'administrateur afin de s'intégrer avec le site web.
    + +
    Simplification de la Configuration
    + +
    Beaucoup de directives, auparavant peu claires, ont été simplifiées. + Les directives Port et BindAddress, souvent + sources d'incompréhension, ont disparus. Désormais seule la directive + Listen sert de liaison pour les + adresses IP; la directive ServerName ne + précise le nom du serveur et son port que pour les redirections et la + gestion des hôtes virtuels.
    + +
    Support natif de l'Unicode sous Windows NT
    + +
    Apache 2.0 sur Windows NT utilise à présent l'utf-8 pour tous les + noms de fichiers. Ces noms de fichiers sont directement traduits vers + l'encodage Unicode du système de fichiers, ce qui permet le support + multilangue pour toutes les installations sur la famille NT de Windows, y + compris Windows 2000 et Windows XP.Ce support n'est pas fonctionnel + pour Windows 95, 98 ni ME, qui utilisent les pages de code locales pour + les accès au système de fichiers, comme auparavant.
    + +
    Mise à jour de la Bibliothèque d'Expressions Rationnelles
    + +
    Apache 2.0 contient la bibliothèque + d'expressions rationnelles compatible Perl (Perl Compatible Regular + Expression Library - PCRE). Toutes les expressions rationnelles sont dont + gérées avec la syntaxe de Perl 5, plus puissante.
    + +
    +
    + +
    + Amélioration des Modules + +
    +
    mod_ssl
    + +
    Apparu dans Apache 2.0, ce module est une interface aux protocoles de + criffrement SSL/TLS fournis par OpenSSL.
    + +
    mod_dav
    + +
    Apparu dans Apache 2.0, ce module implémente les spécifications HTTP de + gestion distribuée de versions et de rédaction (Distributed Authoring and + Versioning - DAV), destinées à la mise en ligne et à la maintenance des + contenus Web.
    + +
    mod_deflate
    + +
    Module apparu dans Apachge 2.0, mod_deflate permet aux navigateurs qui + le supportent de demander la compression des contenus envoyés par le serveur. + Cela à l'avantage de réduite l'occupation de la bande passante.
    + +
    mod_auth_ldap
    + +
    Apparu dans Apache 2.0.41, ce module permet aux administrateurs + d'utiliser un arbre LDAP pour gérer la base d'utilisateurs pour les + Authentifications Basiques HTTP. Un module voisin, + mod_ldap, permet de globaliser les connexions à l'arbre LDAP + et de garder en mémoire cache ces accès.
    + +
    mod_auth_digest
    + +
    Améliore les fonctions de cache sur une session entre les différents + processus, en utilisant de la mémoire partagée.
    + +
    mod_charset_lite
    + +
    Apparu dans Apache 2.0, ce module expérimental permet la conversion + et l'enregistrement entre jeux de caractères.
    + +
    mod_file_cache
    + +
    Apparu dans Apache 2.0, ce module implémente les fonctionnalités du + module mod_mmap_static présent dans Apache 1.3, et offre des + fonctions plus avancées pour la gestion de la cache.
    + +
    mod_headers
    + +
    Ce module gagne beaucoup de flexibilité avec Apache 2.0 : on peut + désormais l'utiliser pour modifier les en-têtes des requêtes + utilisés par mod_proxy, et peut aussi positionner les + en-têtes des réponses de manière conditionnelle.
    + +
    mod_proxy
    + +
    Le module proxy a été réécrit de A à Z. Il tire + maintenant avantage de la nouvelle infrastructure de filtrage, et implémente + un mandataire plus fiable, et conforme aux normes HTTP/1.1. De nouvelles + sections de configuration ajoutées à + Proxy + donnent un contrôle plus lisible et un traitement plus rapide des requêtes + proxifiés; les configurations surcharchées <Directory + "proxy:..."> ne sont pas supportées. Le module a aussi été + fragmenté en plusieurs modules qui gérent chacun leur protocole : + proxy_connect, proxy_ftp et + proxy_http.
    + +
    mod_negotiation
    + +
    Une nouvelles directive, ForceLanguagePriority a été ajoutée, + elle permet de garantir que le client reçoit un seul document dans tous les + cas, au lieu de réponses NOT ACCEPTABLE ou MULTIPLE CHOICES. Les + algorithmes gérant la négociation et les vues multiples (MultiViews) ont + été nettoyés et donnent des réponses plus logiques. Un nouveau format de + carte de types (map type) qui peut aussi gérer le contenu de documents a + aussi été ajouté.
    + +
    mod_autoindex
    + +
    Les listes auto-générés par Autoindex sont à présent + configurables, et peuvent utiliser des tables HTML pour une mise en forme plus propre. + L'ordre d'affichage des fichiers est également finement paramètrable, + comme pour le tri par version, et le filtrage par caractères jokers du + listage du répertoire.
    + +
    mod_include
    + +
    De nouvelles directives permettent de modifier la valeur par défaut + des drapeaux start et end des éléments SSI. Ces directives + permettent à la configuration d'affichage de dates et heures d'être + effectuée dans le fichier de configuration principal, plutôt que dans le + document SSI. Les réponses données par des recherches par expressions + rationnelles (qui gèrent à présent les regex Perl) sont + recupérés au moyen des variables $0 à $9.
    + +
    mod_auth_dbm
    + +
    Plusieurs bases de données DBM sont supportées, et sélectionnables + au moyen de la directive AuthDBMType.
    +
    +
    +
    \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_0.xml.ja b/trunk/docs/manual/new_features_2_0.xml.ja new file mode 100644 index 0000000000..babdaf5e57 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.ja @@ -0,0 +1,239 @@ + + + + + + + + + +Apache 2.0 $B$N?75!G=$N35MW(B + + +

    $B$3$NJ8=q$G$O!"(BApache HTTP $B%5!<%P%P!<%8%g%s(B 1.3 $B$H(B 2.0 + $B$N +

    + +1.3 $B$+$i(B 2.0 $B$X$N%"%C%W%0%l!<%I(B + +
    + $B%3%"5!G=$N3HD%(B + +
    +
    Unix $B$N%9%l%C%I(B
    + +
    POSIX $B%9%l%C%I$r%5%]!<%H$7$F$$$k(B Unix $B%7%9%F%`>e$G$O!"(B + Apache $B$O%^%k%A%W%m%;%9!"%^%k%A%9%l%C%I$N%O%$%V%j%C%I%b!<%I$G(B + $Be$7$^$9!#(B
    + +
    $B?7$7$$%S%k%I%7%9%F%`(B
    + +
    $B%S%k%I%7%9%F%`$O(B autoconf $B$H(B libtool + $B$K4p$E$$$?$b$N$K$J$k$h$&$K!"(B + $B?7$7$/=q$-D>$5$l$^$7$?!#$3$l$K$h$j!"(BApache $B$N(B configure $B$N%7%9%F%`$O(B + $BB>$N%Q%C%1!<%8$H;w$?$b$N$K$J$j$^$7$?!#(B
    + +
    $B%^%k%A%W%m%H%3%k%5%]!<%H(B
    + +
    Apache $B$KJ#?t$N%W%m%H%3%k$r07$&$?$a$N5!9=$,Hw$o$j$^$7$?!#(B + $BNc$H$7$F(B mod_echo $B$,=q$+$l$F$$$^$9!#(B
    + +
    Unix $B0J30$N%W%i%C%H%U%)!<%`$N%5%]!<%H$N2~A1(B
    + +
    Apache 2.0 $B$O(B BeOS$B!"(BOS/2$B!"(BWindows $B$J$I$N(B Unix $B0J30$N(B + $B%W%i%C%H%U%)!<%`$G!"$h$jB.$/!"$h$j0BDj$7$FF0:n$9$k$h$&$K$J$j$^$7$?!#(B + $B%W%i%C%H%U%)!<%`FCM-$N(B $B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) $B$H(B + Apache Portable Runtime (APR) $B$NF3F~$K$h$j!"(B + $B%M%$%F%#%t$N(B API $B$G + +
    $B?7$7$$(B Apache API
    + +
    2.0 $B$G$O%b%8%e!<%k$N(B API $B$,Bg$-$/JQ$o$j$^$7$?!#(B + 1.3 $B$K$"$C$?%b%8%e!<%k$N=gHV(B/$BM%@hEY$NLdBj$NB?$/$O(B + $B$J$/$J$C$F$$$k$O$:$G$9!#(B2.0 $B$OM%@hEY$NA*Br$r$[$H$s$I$r<+F0E*$K9T$J$$!"(B + $B%b%8%e!<%k$N=gHV$O$h$j=@Fp@-$r9b$a$k$?$a$K%U%C%/Kh$K9T$J$o$l$k$h$&$K(B + $B$J$j$^$7$?!#$^$?!"%3%"(B Apache $B%5!<%P$K%Q%C%A$r$"$F$k$3$H$J$/(B + $BDI2C$N%b%8%e!<%k5!G=$rDs6!$9$k$3$H$,$G$-$k$h$&$K?7$7$$4X?t$,(B + $BDI2C$5$l$^$7$?!#(B
    + +
    IPv6 $B%5%]!<%H(B
    + +
    Apache $B$,;HMQ$7$F$$$k(B Apache Portable Runtime library $B$,(B + IPv6 $B$r%5%]!<%H$7$F$$$k%7%9%F%`$G$O(B Apache $B$O(B $B%G%U%)%k%H$G(B + IPv6 $B$N%=%1%C%H$r(B listen $B$7$^$9!#$5$i$K!"(B + Listen, + NameVirtualHost, + VirtualHost + $B$N3F%G%#%l%/%F%#%V$,(B IPv6 $B$N%"%I%l%9$r(B + $B%5%]!<%H$9$k$h$&$K$J$j$^$7$?(B ($BNc$($P!"(B + "Listen [fe80::1]:8080")$B!#(B
    + +
    $B%U%#%k%?(B
    + +
    Apache $B$N%b%8%e!<%k$O%5!<%P$+$iAw$i$l$F$-$?$j!"%5!<%P$X(B + $BAw$k%9%H%j!<%`$KBP$7$FF0:n$9$k%U%#%k%?$H$7$F=q$/$3$H$,$G$-$k$h$&$K(B + $B$J$j$^$7$?!#$3$l$K$h$j!"Nc$($P(B CGI $B%9%/%j%W%H$N=PNO$r(B + mod_include $B$N(B INCLUDES $B%U%#%k%?$r;H$C$F(B + Server Side Include $B$N%G%#%l%/%F%#%V$r2r@O$9$k!"(B + $B$H$$$&$h$&$J$3$H$,2DG=$K$J$j$^$7$?!#(Bmod_ext_filter + $B$G30It%W%m%0%i%`$r%U%#%k%?$H$7$FF0:n$5$;$k$3$H$,$G$-$^$9!#(B + $B$3$l$O(B CGI $B%W%m%0%i%`$r%O%s%I%i$H$7$FF0:n$5$;$k$N$H(B + $B$h$/;w$?J}K!$G$G$-$^$9!#(B
    + +
    $BB?8@8l%(%i!<1~Ez(B
    + +
    $B%V%i%&%6$X$N%(%i!<1~Ez$N%a%C%;!<%8$,!"(BSSI $B$NJ8=q$r;H$C$F(B + $BJ#?t$N8@8l$GDs6!$5$l$k$h$&$K$J$j$^$7$?!#8+$?$a$N0l4S@-$rJ]$D$?$a$K(B + $B4IM} + +
    $B@_Dj$N4JAG2=(B
    + +
    $BB?$/$N:.Mp$r>7$-$,$A$J%G%#%l%/%F%#%V$,4JAG2=$5$l$^$7$?!#(B + $B$h$/:.Mp$r0z$-5/$3$7$F$$$?(B Port $B%G%#%l%/%F%#%V$H(B + Bind $B%G%#%l%/%F%#%V$O(B + $B$J$/$J$j$^$7$?!#(BListen + $B%G%#%l%/%F%#%V$N$_$,(B IP $B%"%I%l%9$N%P%$%s%I$K;H$o$l$^$9!#(B + ServerName $B%G%#%l%/%F%#%V$G$O(B + $B%j%@%$%l%/%H$H(B vhost $B$NG'<1$N$?$a$@$1$K%5!<%P$NL>A0$H%]!<%HHV9f$r(B + $B;XDj$7$^$9!#(B
    + +
    Windows NT $B$N%M%$%F%#%t(B Unicode $B%5%]!<%H(B
    + +
    Windows NT $B>e$N(B Apache 2.0 $B$O%U%!%$%kL>$NJ8;z%(%s%3!<%IA4$F$K(B + utf-8 $B$r;H$&$h$&$K$J$j$^$7$?!#$3$l$i$O(B Unicode $B%U%!%$%k%7%9%F%`$K(B + $BD>@\JQ49$5$l$k$N$G!"(BWindows 2000 $B$H(B Windows XP $B$r4^$`!"A4$F$N(B + Windows NT $B7O$GB?8@8l%5%]!<%H$,Ds6!$5$l$^$9!#(B + $B$3$N%5%]!<%H$O!"%U%!%$%k%7%9%F%`$N%"%/%;%9;~$K%m!<%+%k$N(B + $B%3!<%I%Z!<%8$r;H$&(B Windows 95, 98, ME $B$K$OE,MQ$5$l$^$;$s!#(B
    + +
    $B@55,I=8=%i%$%V%i%j$N%"%C%W%G!<%H(B
    + +
    Apache 2.0 $B$O(B Perl + $B8_49@55,I=8=%i%$%V%i%j(B (PCRE) $B$r4^$s$G$$$^$9!#(B + $B@55,I=8=$NI>2A$K$O!"$h$j6/NO$K$J$C$?(B Perl 5 + $B9=J8$r;HMQ$7$^$9!#(B
    + +
    +
    + +
    + $B%b%8%e!<%k$N3HD%(B + +
    +
    mod_ssl
    + +
    Apache 2.0 $B$N?7%b%8%e!<%k!#$3$N%b%8%e!<%k$O(B OpenSSL $B$,(B + $BDs6!$9$k(B SSL/TLS $B0E9f%W%m%H%3%k$X$N%$%s%?%U%'!<%9$G$9!#(B
    + +
    mod_dav
    + +
    Apache 2.0 $B$N?7%b%8%e!<%k!#$3$N%b%8%e!<%k$O%&%'%V%3%s%F%s%D$r(B + $BAw$j!"0];}$9$k$?$a$N5,3J(B + HTTP Distributed Authoring and Versioning (DAV) $B$r + +
    mod_deflate
    + +
    Apache 2.0 $B$N?7%b%8%e!<%k!#Aw?.A0$KAw?.FbMF$r05=L$7$F(B + $B%M%C%H%o!<%/BS0h$r@aLs$9$k!"$H$$$&%j%/%(%9%H$r%V%i%&%6$,(B + $BMW5a$G$-$k$h$&$K$7$^$9!#(B
    + +
    mod_auth_ldap
    + +
    Apache 2.0.41 $B$N?7%b%8%e!<%k!#(BHTTP $B4pK\G'>Z$N>ZL@=q$rJ]B8$9$k$N$K!"(B + LDAP $B%G!<%?%Y!<%9$r;HMQ$G$-$k$h$&$K$J$j$^$9!#(B + $B4XO"%b%8%e!<%k$N(B mod_ldap $B$G!"(B + $B%3%M%/%7%g%s$N%W!<%k5!G=$H7k2L$N%-%c%C%7%e5!G=$,Ds6!$5$l$^$9!#(B
    + +
    mod_auth_digest
    + +
    $B$3$N%b%8%e!<%k$O6&M-%a%b%j$r;H$&$3$H$K$h$j!"%W%m%;%9$r$^$?$$$@(B + $B%;%C%7%g%s$N%-%c%C%7%e$r%5%]!<%H$9$k$h$&$K$J$j$^$7$?!#(B
    + +
    mod_charset_lite
    + +
    Apache 2.0 $B$N?7%b%8%e!<%k!#$3$N + +
    mod_file_cache
    + +
    Apache 2.0 $B$N?7%b%8%e!<%k!#$3$N%b%8%e!<%k$K$O!"(B + Apache 1.3 $B$K$*$1$k(B mod_mmap_static $B5!G=$,4^$^$l!"(B + $B$^$?!"DI2C$N%-%c%C%7%e5!G=$,2C$o$C$F$$$^$9!#(B
    + +
    mod_headers
    + +
    $B$3$N%b%8%e!<%k$O(B Apache 2.0 $B$GHs>o$K=@Fp@-$,(B + $B9b$/$J$j$^$7$?!#(Bmod_proxy + $B$G;H$o$l$k%j%/%(%9%H$N%X%C%@$rJQ99$G$-$k$h$&$K$J$j$^$7$?$7!"(B + $B1~Ez%X%C%@$r>r7o$K1~$8$F@_Dj$G$-$k$h$&$K$J$j$^$7$?!#(B
    + +
    mod_proxy
    + +
    proxy $B%b%8%e!<%k$O?7$7$$%U%#%k%?$N5!9=$rMxMQ$9$k$?$a$H!"(B + $B$h$j?.Mj$G$-$k!"(BHTTP/1.1 $B$K=`5r$7$?(B proxy $B$r$5$l$^$7$?!#$5$i$K!"?7$7$$(B + Proxy + $B@_Dj%;%/%7%g%s$,(Bproxy $B$5$l$k%5%$%H$N$h$jFI$_$d$9$/(B ($BFbItE*$K$b$h$jB.$$(B) + $B@_Dj$rDs6!$7$^$9!#%*!<%P!<%m!<%I$5$l$?(B + <Directory "proxy:... > + $B@_Dj$O%5%]!<%H$5$l$F$$$^$;$s!#$3$N%b%8%e!<%k$O(B proxy_connect, + proxy_ftp, proxy_http + $B$H$$$C$?!"FCDj$N%W%m%H%3%k$r%5%]!<%H$9$k(B + $B%b%8%e!<%k$KJ,3d$5$l$k$h$&$K$J$j$^$7$?!#(B
    + +
    mod_negotiation
    + +
    $B%/%i%$%"%s%H$,(B NOT ACCEPTABLE $B$d(B MULTIPLE CHOICES $B1~Ez$N(B + $BBe$o$j$K>o$KC1FH$NJ8=q$rForceLanguagePriority + $B$r;H$&$3$H$,$G$-$k$h$&$K$J$j$^$7$?!#(B + $B$5$i$K!"$h$j0l4S@-$N$"$k7k2L$rDs6!$9$k$?$a$K(B + $B%M%4%7%(!<%7%g%s$H(B MultiViews $B$N%"%k%4%j%:%`$,2~A1$5$l!"(B + $BJ8=q$NFbMF$r4^$a$k$3$H$N$G$-$k!"?7$7$$7A<0$N%?%$%W%^%C%W$,(B + $BDs6!$5$l$k$h$&$K$J$j$^$7$?!#(B
    + +
    mod_autoindex
    + +
    Autoindex $B$5$l$k%G%#%l%/%H%j$NFbMF0lMw$,!"(B + $B$-$l$$$KI=<($5$l$k$?$a$K(B HTML $B$N%F!<%V%k$r;H$&$h$&$K(B + $B@_Dj$G$-$k$h$&$K$J$j$^$7$?!#$^$?!"%P!<%8%g%s$K$h$k%=!<%F%#%s%0$J$I!"(B + $B$h$j:Y$+$$%=!<%F%#%s%0$N@)8f$,$G$-$k$h$&$K$J$j!"%G%#%l%/%H%j(B + $B$NFbMF0lMw$r%o%$%k%I%+!<%I$K$h$jA*JL$9$k$3$H$,$G$-$k$h$&$K$b$J$j$^$7$?!#(B
    + +
    mod_include
    + +
    $B?7$7$$%G%#%l%/%F%#%V$K$h$j!"(BSSI $B$N%G%U%)%k%H$N3+;O%?%0$H=*N;%?%0$r(B + $BJQ99$G$-$k$h$&$K$J$j$^$7$?!#$^$?!"%(%i!<$H;~9o$N7A<0$N@_Dj$,(B SSI $B$N(B + $BJ8=qCf$G$O$J$/!"mod_include + $B$NJQ?t(B $0 .. $9 $B$K$h$j + +
    mod_auth_dbm
    + +
    AuthDBMType + $B%G%#%l%/%F%#%V$K$h$j!"J#?t$N(B DBM $B7?$N%G!<%?%Y!<%9$r%5%]!<%H$9$k(B + $B$h$&$K$J$j$^$7$?!#(B
    + +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_0.xml.ko b/trunk/docs/manual/new_features_2_0.xml.ko new file mode 100644 index 0000000000..1e6135c54e --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.ko @@ -0,0 +1,219 @@ + + + + + + + + + +Apache 2.0ÀÇ »õ·Î¿î ±â´É °³¿ä + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 1.3 ¹öÀü°ú 2.0 ¹öÀü°£ÀÇ ÁÖµÈ Â÷ÀÌÁ¡À» + ¼³¸íÇÑ´Ù.

    +
    + +1.3¿¡¼­ 2.0À¸·Î ¾÷±×·¹À̵å + +
    + ÇÙ½É ºÎºÐ¿¡¼­ ³ª¾ÆÁø Á¡ + +
    +
    À¯´Ð½º ¾²·¹µå
    + +
    POSIX ¾²·¹µå¸¦ Áö¿øÇÏ´Â À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ¿©·¯ ÇÁ·Î¼¼½º¿Í ¿©·¯ ¾²·¹µå·Î È¥ÇÕÇؼ­ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + ÀüºÎ´Â ¾Æ´ÏÁö¸¸ ¸¹Àº °æ¿ì È®Àå°¡´É¼º(scalability)À» ³ôÀδÙ.
    + +
    »õ·Î¿î ÄÄÆÄÀÏ ½Ã½ºÅÛ
    + +
    ÄÄÆÄÀÏ ½Ã½ºÅÛÀÌ autoconf¿Í libtoolÀ» + »ç¿ëÇϵµ·Ï ÀçÀÛ¼ºµÇ¾ú´Ù. ±×·¡¼­ ¾ÆÆÄÄ¡ ±¸¼º ½Ã½ºÅÛÀÌ ´Ù¸¥ + ÆÐÅ°Áöµé°ú Á»´õ ºñ½ÁÇØÁ³´Ù.
    + +
    ¿©·¯ ÇÁ·ÎÅäÄÝ Áö¿ø
    + +
    ÀÌÁ¦ ¾ÆÆÄÄ¡´Â ¿©·¯ ÇÁ·ÎÅäÄÝÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖ´Â ±¸Á¶¸¦ + °®Ãè´Ù. mod_echo°¡ ±× ¿¹·Î ÀÛ¼ºµÇ¾ú´Ù.
    + +
    ºñÀ¯´Ð½º Ç÷¡Æû¿¡ ´ëÇÑ ´õ ³ªÀº Áö¿ø
    + +
    Apache 2.0´Â BeOS, OS/2, À©µµ¿ìÁî¿Í °°Àº ºñÀ¯´Ð½º + Ç÷¡Æû¿¡¼­ ´õ ºü¸£°í ¾ÈÁ¤È­µÇ¾ú´Ù. ÀÌÁ¦ ¾ÆÆÄÄ¡´Â À̵é + Ç÷¡Æû¿¡¼­ ¹ö±×°¡ ¸¹°í ¼º´ÉÀÌ ´À·È´ø POSIX ȣȯÃþ ´ë½Å + ÀÚü API·Î ±¸ÇöµÈ Ç÷¡Æû ƯÀ¯ÀÇ ´ÙÁßó¸® ¸ðµâ + (MPM)°ú Apache Portable Runtime (APR)À» »ç¿ëÇÏ¿© ±¸ÇöµÈ´Ù.
    + +
    »õ·Î¿î ¾ÆÆÄÄ¡ API
    + +
    ¸ðµâ API°¡ 2.0¿¡¼­ »ó´çÈ÷ º¯Çß´Ù. 1.3ÀÇ ¿©·¯ ¸ðµâ + ¼ø¼­¿Í ¿ì¼±¼øÀ§ ¹®Á¦°¡ »ç¶óÁ³´Ù. 2.0Àº À̸¦ ´ëºÎºÐ ÀÚµ¿À¸·Î + ó¸®Çϸç, ¸ðµâ ¼ø¼­´Â ÀÌÁ¦ ´õ À¯¿¬ÇÑ ÈÅ(hook) ´ÜÀ§·Î ÁöÁ¤ÇÑ´Ù. + ¶Ç, ¾ÆÆÄÄ¡ ¼­¹ö ÇÙ½É ºÎºÐÀ» ¼öÁ¤ÇÏÁö ¾Ê°í »õ·Î¿î ¸ðµâ ±â´ÉÀ» + Á¦°øÇÏ´Â ÇÔ¼ö°¡ Ãß°¡µÇ¾ú´Ù.
    + +
    IPv6 Áö¿ø
    + +
    ÇÏÀ§ Apache Portable Runtine ¶óÀ̺귯¸®°¡ IPv6¸¦ Áö¿øÇÏ´Â + ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡´Â ±âº»ÀûÀ¸·Î IPv6 ¼ÒÄÏÀ» ±â´Ù¸°´Ù. ¶Ç, + Listen, + NameVirtualHost, + VirtualHost Áö½Ã¾î°¡ + IPv6 ¼ýÀÚ ÁÖ¼Ò¸¦ Áö¿øÇÑ´Ù. (¿¹, + "Listen [fe80::1]:8080").
    + +
    ÇÊÅ͸µ
    + +
    ÀÌÁ¦ ¾ÆÆÄÄ¡ ¸ðµâÀ» ¼­¹ö·Î ¿À°í°¡´Â È帧¿¡ ´ëÇÑ + ÇÊÅÍ·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î mod_includeÀÇ + INCLUDES ÇÊÅ͸¦ »ç¿ëÇÏ¿© CGI ½ºÅ©¸³Æ® Ãâ·Â¿¡¼­ + Server Side Include Áö½Ã¾î¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. + mod_ext_filter ¸ðµâÀº CGI ÇÁ·Î±×·¥À» + Çڵ鷯·Î »ç¿ëÇÏ´Â °Í°ú °°ÀÌ ¿ÜºÎ ÇÁ·Î±×·¥À» ÇÊÅÍ·Î + »ç¿ëÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù.
    + +
    ´Ù±¹¾î ¿À·ù ÀÀ´ä
    + +
    ºê¶ó¿ìÀú·Î º¸³»´Â ¿À·ù ÀÀ´ä¹®ÀÌ ÀÌÁ¦ SSI ¹®¼­¸¦ + »ç¿ëÇÏ¿© ´Ù±¹¾î·Î Á¦°øµÈ´Ù. °ü¸®ÀÚ´Â ÅëÀÏµÈ ¿Ü°üÀ» À§ÇØ + ÀÌ ¹®¼­¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    °£´ÜÇØÁø ¼³Á¤
    + +
    È¥¶õÀ» ÁÖ´ø ¸¹Àº Áö½Ã¾îµéÀÌ °£´ÜÇØÁ³´Ù. ÀÚÁÖ È¥¶õÀ» + ÁÖ´ø Port¿Í BindAddress Áö½Ã¾î´Â + ¾ø¾îÁö°í IP ÁÖ¼Ò ¿¬°á¿¡ + Listen Áö½Ã¾î¸¸À» + »ç¿ëÇÑ´Ù. ServerName + Áö½Ã¾î´Â ¸®´ÙÀÌ·º¼Ç°ú °¡»óÈ£½ºÆ® ÀνĿ¡¸¸ »ç¿ëµÉ ¼­¹ö¸í°ú + Æ÷Æ®¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    Windows NT À¯´ÏÄÚµå ÀÚü Áö¿ø
    + +
    Windows NT¿¡¼­ Apache 2.0Àº ÀÌÁ¦ ¸ðµç ÆÄÀϸí ÀÎÄÚµù¿¡ + utf-8À» »ç¿ëÇÑ´Ù. ÆÄÀϸíÀº ÇÏÀ§ À¯´ÏÄÚµå ÆÄÀϽýºÅÛÀ¸·Î Á÷Á¢ + º¯¿ªµÇ¾î, Windows 2000°ú Windows XP¸¦ Æ÷ÇÔÇÑ ¸ðµç Windows NT±â¹Ý + ½Ã½ºÅÛ¿¡ ´Ù±¹¾î Áö¿øÀ» Á¦°øÇÑ´Ù. ÀÌ ±â´ÉÀº Windows 95, + 98, ME¿¡´Â Áö¿øµÇÁö¾Ê°í, ÆÄÀϽýºÅÛ Á¢±Ù¿¡ Àü°ú °°ÀÌ ½Ã½ºÅÛÀÇ + Áö¿ª ÄÚµåÆäÀÌÁö¸¦ »ç¿ëÇÑ´Ù.
    + +
    Á¤±ÔÇ¥Çö½Ä ¶óÀ̺귯¸® Updated
    + +
    Apache 2.0Àº Perlȣȯ + Á¤±ÔÇ¥Çö½Ä ¶óÀ̺귯¸® (Perl Compatible Regular Expression + Library) (PCRE)¸¦ Æ÷ÇÔÇÑ´Ù. ÀÌÁ¦ ¸ðµç Á¤±ÔÇ¥Çö½Ä¿¡ + ´õ °­·ÂÇÑ Perl 5 ¹®¹ýÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    +
    + +
    + ¸ðµâ¿¡¼­ ³ª¾ÆÁø Á¡ + +
    +
    mod_ssl
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº OpenSSLÀÌ + Á¦°øÇÏ´Â SSL/TLS ¾Ïȣȭ ÇÁ·ÎÅäÄÝÀÇ ÀÎÅ×ÆäÀ̽º´Ù.
    + +
    mod_dav
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº À¥ÄÁÅÙÃ÷¸¦ + ¿Ã¸®°í °ü¸®ÇϱâÀ§ÇÑ HTTP Distributed Authoring and Versioning + (DAV) Ç¥ÁØÀ» ±¸ÇöÇÑ´Ù.
    + +
    mod_deflate
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ³×Æ®¿÷ »ç¿ë·®À» + ÁÙÀ̱âÀ§ÇØ ºê¶ó¿ìÀú¿¡°Ô ÄÁÅÙÃ÷¸¦ ¾ÐÃàÇؼ­ º¸³»¶ó°í ¿äûÇÒ + ¼ö ÀÖ´Ù.
    + +
    mod_auth_ldap
    + +
    Apache 2.0.41¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº HTTP + Basic Authentication¿¡ »ç¿ëÇÏ´Â Á¤º¸¸¦ LDAP µ¥ÀÌÅͺ£À̽º¿¡ + ÀúÀåÇÑ´Ù. °ü·ÃµÈ mod_ldap ¸ðµâÀº + ¿¬°áÇ®(connection pool)À» Á¦°øÇÏ°í, °á°ú¸¦ ij½ÌÇÑ´Ù.
    + +
    mod_auth_digest
    + +
    °øÀ¯¸Þ¸ð¸®¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º°£ ¼¼¼Ç ij½ÌÀ» Áö¿øÇÑ´Ù.
    + +
    mod_charset_lite
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ½ÇÇèÀûÀÎ ¸ðµâÀº + ¹®ÀÚÁýÇÕ º¯È¯°ú ¹®ÀÚÁýÇÕ ÀçÀÛ¼º ±â´ÉÀ» Á¦°øÇÑ´Ù.
    + +
    mod_file_cache
    + +
    Apache 2.0¿¡¼­ »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ ¸ðµâÀº Apache 1.3ÀÇ + mod_mmap_static ±â´É¿¡ ´õ ³ªÀº ij½¬ ±â´ÉÀ» + Ãß°¡Çß´Ù.
    + +
    mod_headers
    + +
    ÀÌ ¸ðµâÀº Apache 2.0¿¡¼­ ´õ À¯¿¬ÇØÁ³´Ù. ÀÌÁ¦ + mod_proxy°¡ »ç¿ëÇÏ´Â ¿äû Çì´õ¸¦ ¼öÁ¤ÇÒ + ¼ö ÀÖ°í, °æ¿ì¿¡ µû¶ó¼­ ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÒ ¼öµµ ÀÖ´Ù.
    + +
    mod_proxy
    + +
    ÀÌ ÇÁ·Ï½Ã ¸ðµâÀº »õ·Î¿î ÇÊÅÍ ±¸Á¶¸¦ ÀÌ¿ëÇÏ°í ´õ ¹ÏÀ»¸¸ÇÑ + HTTP/1.1 ÇÁ·Ï½Ã¸¦ ±¸ÇöÇϱâÀ§ÇØ ¿ÏÀüÈ÷ ÀçÀÛ¼ºµÇ¾ú´Ù. Ãß°¡·Î + »õ·Î¿î Proxy + ¼³Á¤ ¼½¼ÇÀº ÇÁ·Ï½Ã ¼³Á¤À» ´õ ½±°Ô (±×¸®°í ³»ºÎÀûÀ¸·Î ´õ + ºü¸£°Ô) ¸¸µç´Ù. °ú°Å <Directory "proxy:..."> + ¼³Á¤Àº ÀÌÁ¦ Áö¿øÇÏÁö ¾Ê´Â´Ù. ¸ðµâÀº proxy_connect, + proxy_ftp, proxy_http¿Í °°ÀÌ + Áö¿øÇÏ´Â ÇÁ·ÎÅäÄÝ º°·Î ³ª´²Á³´Ù.
    + +
    mod_negotiation
    + +
    »õ·Î¿î ForceLanguagePriority + Áö½Ã¾î´Â Ŭ¶óÀ̾ðÆ®°¡ NOT ACCEPTABLEÀ̳ª MULTIPLE CHOICES + ÀÀ´ä ´ë½Å ¸ðµç °æ¿ì ÇÑ ¹®¼­¸¦ ¹ÞÀ½À» º¸ÀåÇÑ´Ù. Ãß°¡·Î + Çù»ó ¾Ë°í¸®Áò°ú MultiViews ¾Ë°í¸®ÁòÀÌ ´õ ÀÏ°üµÈ °á°ú¸¦ + ³»µµ·Ï ¼öÁ¤µÇ¾ú°í, ¹®¼­ ³»¿ëÀ» Æ÷ÇÔÇÒ ¼ö ÀÖ´Â »õ·Î¿î Çü½ÄÀÇ + type mapÀÌ Ãß°¡µÇ¾ú´Ù.
    + +
    mod_autoindex
    + +
    ÀÚµ¿À¸·Î »ý¼ºµÈ µð·ºÅ丮 ¸ñ·ÏÀÌ ÀÌÁ¦ ´õ ±ò²ûÇÑ Çü½ÄÀ» + À§ÇØ HTML Ç¥¸¦ »ç¿ëÇÒ ¼ö ÀÖ°Ô µÇ¾ú°í, ¹öÀü Á¤·ÄÀ» Æ÷ÇÔÇÏ¿© + Á¤·Ä¼ø¼­¸¦ ÀÚ¼¼È÷ Á¶ÀýÇÒ ¼ö ÀÖÀ¸¸ç, µð·ºÅ丮 ¸ñ·ÏÀ» ¿ÍÀϵåÄ«µå·Î + °É·¯³¾ ¼ö ÀÖ´Ù.
    + +
    mod_include
    + +
    »õ·Î¿î Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© SSI ¿ä¼ÒÀÇ ±âº» ½ÃÀÛ ÅÂ±×¿Í + ¸¶Ä§ ű׸¦ º¯°æÇÒ ¼ö ÀÖ°í, ¿À·ù¿Í ½Ã°£Çü½ÄÀ» SSI ¹®¼­¿Ü¿¡ + ÁÖ ¼³Á¤ÆÄÀÏ¿¡¼­µµ ¼³Á¤ÇÒ ¼ö ÀÖ°Ô µÇ¾ú´Ù. mod_include¿¡¼­ (ÀÌÁ¦ + Perl Á¤±ÔÇ¥Çö½Ä ¹®¹ýÀ¸·Î) Á¤±ÔÇ¥Çö½Ä ÆĽ̰ú ±×·ìÀÇ + °á°ú¸¦ mod_includeÀÇ $0 + ... $9 º¯¼ö·Î ¾òÀ» ¼ö ÀÖ´Ù.
    + +
    mod_auth_dbm
    + +
    ÀÌÁ¦ AuthDBMType + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿©·¯ DBM·ù µ¥ÀÌÅͺ£À̽º¸¦ Áö¿øÇÑ´Ù.
    + +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_0.xml.meta b/trunk/docs/manual/new_features_2_0.xml.meta new file mode 100644 index 0000000000..430fb33b27 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.meta @@ -0,0 +1,17 @@ + + + + new_features_2_0 + / + . + + + de + en + fr + ja + ko + pt-br + ru + + diff --git a/trunk/docs/manual/new_features_2_0.xml.pt-br b/trunk/docs/manual/new_features_2_0.xml.pt-br new file mode 100644 index 0000000000..94a15caf6e --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.pt-br @@ -0,0 +1,238 @@ + + + + + + + + + +Descrição das novas funcionalidades do Apache 2.0 + + +

    Esse documento descreve algumas das mudanças principais + entre as versões 1.3 e 2.0 do Servidor HTTP Apache.

    +
    + +Atualizando da versão 1.3 para 2.0 + +
    + Principais Melhorias + +
    +
    Threading Unix
    + +
    Em sistemas Unix com suporte a threads POSIX, o Apache pode + funcionar em modo híbrido multiprocesso e multithread. Não funciona + em todas configurações, mas melhora a escalabilidade em muitas.
    + +
    Novo Sistema de Compilação
    + +
    O sistema de compilação foi reescrito do zero para utilizar o + autoconf e o libtool, tornando a + configuração do sistema Apache mais similar a de outros + pacotes.
    + +
    Suporte Multi-protocolo
    + +
    O Apache possui agora uma infraestrutura feita para suportar + múltiplos protocolos. O módulo mod_echo é um + exemplo ilustrativo de sua utilização.
    + +
    Suporte Aperfeiçoado para Plataformas Não-Unix
    + +
    O Apache 2.0 está mais rápido e mais estável em plataformas + Não-Unix como BeOS, OS/2 e Windows. Com a introdução de módulos + multi-processamento (MPMs) específicos e a + Apache Portable Runtime (APR), essas plataformas estão implementando + as suas APIs nativas, evitando as camadas de emulação POSIX que se + mostravam lentas e defeituosas.
    + +
    Nova API Apache
    + +
    A API para módulos mudou significativamente na versão 2.0. + Muitos dos problemas de ordenamento/prioridade da versão + 1.3 foram resolvidos. A versão 2.0 faz o ordenamento automático + "per-hook" para permitir mais flexibilidade. Novas chamadas foram + adicionadas para fornecer capacidades adicionais sem a necessidade + de se aplicar nenhum patch ao servidor Apache principal.
    + +
    Suporte IPv6
    + +
    Em sistemas onde o IPv6 é suportado pela biblioteca de base + Apache Portable Runtime, o Apache monitora por padrão + as interfaces IPv6. Em adição as diretrizes Listen, NameVirtualHost e VirtualHost, suportam correntes (strings) de + endereços numéricos do tipo IPv6. (ex. "Listen + [fe80::1]:8080").
    + +
    Filtrando
    + +
    Os módulos do Apache agora são feito filtros que + agem na corrente do conteúdo na medida que este é entregue, tanto + na entrada quando na saída de dados do servidor. É possível então, + por exemplo, que o retorno de dados de scripts CGI sejam analisados + pelas diretrizes do "Server Side Include" usando o filtro INCLUDES do mod_include. O módulo mod_ext_filter, permite que programas externos trabalhem + como filtros do mesmo modo que aplicações CGI funcionam como + manipuladores.
    + +
    Respostas de Erro Multi-linguais
    + +
    Mensagens de erro para o navegador agora são fornecidas em + diversas línguas, usando documentos SSI. Podem ser personalizadas + pelo administrador que desejar definir seus próprios + padrões.
    + +
    Configuração Simplificada
    + +
    Muitas diretrizes confusas foram simplificadas. Entre elas, + Port e BindAddress não existem + mais; apenas a diretriz Listen + é usada para direcionar endereços IP; a diretriz ServerName especifica o nome do servidor + e o número da porta apenas para redirecionamento e reconhecimento + de hospedeiros virtuais.
    + +
    Suporte Nativo ao Unicode do Windows NT
    + +
    O Apache 2.0 para Windows NT agora usa utf-8 para codificação + de todos os nomes de arquivos. A tradução para o sistema + base Unicode, torna possível o suporte multi-lingual para todas + as instalações da família NT, incluindo o Windows 2000 e Windows XP. + Esse suporte não se estende ao Windows 95, 98 ou ME, que + continuam usando o código de páginas da máquina local para o + acesso ao sistema de arquivos.
    + +
    Biblioteca de Expressões Regulares Atualizada
    + +
    O Apache 2.0 inclui a Biblioteca + de Expressões Regulares Compatíveis Perl (PCRE). Todas as + avaliações de expressões regulares usam a mais poderosa sintaxe + do Perl 5.
    + +
    +
    + +
    + Melhorias nos Módulos + +
    +
    mod_ssl
    + +
    Novo módulo no Apache 2.0. Esse módulo é uma interface + para os protocolos de codificação SSL/TLS fornecidos pela + OpenSSL.
    + +
    mod_dav
    + +
    Novo módulo no Apache 2.0. Este módulo implementa as + especificações de Autoria Distribuída e Versões (Distributed + Authoring and Versioning - DAV) para HTTP, para a publicação + e a manutenção de conteúdo da web.
    + +
    mod_deflate
    + +
    Novo módulo no Apache 2.0. Esse módulo permite o suporte + a navegadores que solicitam que o conteúdo seja comprimido antes + da entrega, economizando banda da rede.
    + +
    mod_auth_ldap
    + +
    Novo módulo no Apache 2.0.41. Este módulo permite que + bancos de dados LDAP sejam usados para armazenar credenciais + para Autenticação Básica HTTP. Um módulo que o acompanha mod_ldap, fornece a conciliação de conexões e armazenamento + de resultados.
    + +
    mod_auth_digest
    + +
    Inclui suporte adicional para armazenamento de sessões + através de processos que usam memória compartilhada.
    + +
    mod_charset_lite
    + +
    Novo módulo no Apache 2.0. Este modo experimental permite a + tradução de tabelas de caracteres ou re-codificação.
    + +
    mod_file_cache
    + +
    Novo módulo no Apache 2.0. Esse módulo inclui a funcionalidade + do mod_mmap_static do Apache 1.3, além de disponibilizar + outras possibilidades de armazenamento.
    + +
    mod_headers
    + +
    Este módulo está muito mais flexível no Apache 2.0. Pode + modificar pedidos de cabeçalhos usados pelo mod_proxy, e incondicionalmente pode ajustar cabeçalhos de respostas.
    + +
    mod_proxy
    + +
    O módulo proxy foi totalmente reescrito para levar vantagem + da nova infraestrutura de filtro e implementar um proxy mais fiel e + de acordo com o padrão HTTP/1.1. Além disso, uma nova seção + de configuração Proxy fornece controles mais legíveis (e internamente + mais rápidos) para sites com proxies; configurações + sobrecarregadas <Directory "proxy:...">, não + são suportadas. O módulo agora é dividido em suporte + de protocolos específicos incluindo proxy_connect, + proxy_ftp e proxy_http.
    + +
    mod_negotiation
    + +
    A nova diretriz ForceLanguagePriority pode ser usada para assegurar que + o cliente receba um único documento em todos os casos, ao invés de + respostas "NOT ACCEPTABLE" ou "MULTIPLE CHOICES". Novos algoritmos + de negociação e visões múltiplas (MultiViews) foram organizados para + obter resultados mais consistentes e uma nova forma de tipo de mapa + (map type) que podem incluir o conteúdo de documentos é fornecido.
    + +
    mod_autoindex
    + +
    As listagens de diretórios automáticas podem ser + configuradas para usar tabelas HTML para formatações mais limpas + e permitir controles mais acurados de classificação, incluindo + ordenação por versão e filtro da lista de + diretórios através de caracteres-coringa.
    + +
    mod_include
    + +
    Novas diretrizes permitem que as tags padrões start e + end para elementos SSI, possam ser alteradas e permitir que + as configurações de formatos de erro e hora sejam incluídos no + arquivo de configuração principal, ao invés de serem adicionadas + ao documento SSI. Resultados de análises de expressões regulares + e agrupamento (baseadas na sintaxe de expressões regulares do Perl) + podem ser obtidas usando as variáveis do módulo mod_include, de $0 a $9.
    + +
    mod_auth_dbm
    + +
    Agora suporta múltiplos tipos de banco de dados similares ao DBM, + usando a diretriz AuthDBMType + .
    + +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_0.xml.ru b/trunk/docs/manual/new_features_2_0.xml.ru new file mode 100644 index 0000000000..39308f1d39 --- /dev/null +++ b/trunk/docs/manual/new_features_2_0.xml.ru @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + +ïÂÚÏÒ ÎÏ×ÙÈ ×ÏÚÍÏÖÎÏÓÔÅÊ × Apache 2.0 + + +

    üÔÏÔ ÄÏËÕÍÅÎÔ ÏÐÉÓÙ×ÁÅÔ ÏÓÎÏ×ÎÙÅ ÒÁÚÌÉÞÉÑ ÍÅÖÄÕ ×ÅÒÓÉÑÍÉ 1.3 É 2.0 HTTP ÓÅÒ×ÅÒÁ Apache

    +
    + +ðÅÒÅÈÏÄ ÏÔ ×ÅÒÓÉÉ 1.3 Ë ×ÅÒÓÉÉ 2.0 + +
    + õÌÕÞÛÅÎÉÑ × ÑÄÒÅ ÓÅÒ×ÅÒÁ + +
    +
    íÎÏÇÏÐÏÔÏÞÎÏÓÔØ × UNIX
    + +
    îÁ UNIX ÓÉÓÔÅÍÁÈ, ËÏÔÏÒÙÅ ÐÏÄÄÅÒÖÉ×ÁÀÔ ÐÏÔÏËÉ (ÎÉÔÉ) ÓÔÁÎÄÁÒÔÁ POSIX, + Apache ÔÅÐÅÒØ ÍÏÖÅÔ ×ÙÐÏÌÎÑÔØÓÑ × ÇÉÂÒÉÄÎÏÍ ÍÎÏÇÏÐÒÏÃÅÓÓÏ×Ï - + ÍÎÏÇÏÐÏÔÏÞÎÏÍ ÒÅÖÉÍÅ. üÔÏ ÓÐÏÓÏÂÓÔ×ÕÅÔ ÒÁÓÛÉÒÑÅÍÏÓÔÉ + ÓÉÓÔÅÍÙ ÄÌÑ ÍÎÏÇÉÈ, ÎÏ ÎÅ ÄÌÑ ×ÓÅÈ ÓÐÏÓÏÂÏ× ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ.
    + +
    îÏ×ÁÑ ÓÉÓÔÅÍÁ ÓÂÏÒËÉ
    + +
    óÉÓÔÅÍÁ ÓÂÏÒËÉ ÂÙÌÁ ÐÏÌÎÏÓÔØÀ ÉÚÍÅÎÅÎÁ, É ÔÅÐÅÒØ ÏÓÎÏ×Ù×ÁÅÔÓÑ ÎÁ autoconf É libtool. + üÔÏ ÄÅÌÁÅÔ ÐÒÏÃÅÓÓ ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ Apache ÂÏÌÅÅ ÐÏÈÏÖÉÍ ÎÁ ÐÏÄÏÂÎÙÊ ÐÒÏÃÅÓÓ × ÄÒÕÇÉÈ ÐÒÏÇÒÁÍÍÎÙÈ + ÐÒÏÄÕËÔÁÈ.
    + +
    ðÏÄÄÅÒÖËÁ ÒÁÚÌÉÞÎÙÈ ÐÒÏÔÏËÏÌÏ×
    + +
    Apache ÔÅÐÅÒØ ÉÍÅÅÔ ÓÐÅÃÉÁÌØÎÕÀ ÉÎÆÒÁÓÔÒÕËÔÕÒÕ, + ÓÐÏÓÏÂÎÕÀ ÏÂÓÌÕÖÉ×ÁÔØ ÒÁÚÌÉÞÎÙÅ ÐÒÏÔÏËÏÌÙ. + íÏÄÕÌØ mod_echo ÂÙÌ ÎÁÐÉÓÁÎ × ËÁÞÅÓÔ×Å + ÐÒÉÍÅÒÁ ÜÔÏÍÕ.
    + +
    õÌÕÞÛÅÎÎÁÑ ÐÏÄÄÅÒÖËÁ ÏÔÌÉÞÎÙÈ ÏÔ UNIX + ÐÌÁÔÆÏÒÍ
    + +
    Apache 2.0 ÓÔÁÌ ÒÁÂÏÔÁÔØ ÂÙÓÔÒÅÅ É ÎÁÄÅÖÎÅÅ + ÎÁ ÏÔÌÉÞÎÙÈ ÏÔ UNIX ÐÌÁÔÆÏÒÍÁÈ, ÔÁËÉÈ ËÁË: BeOS, + OS/2 É Windows. ó ××ÅÄÅÎÉÅÍ ÎÏ×ÙÈ ÓÐÅÃÉÆÉÞÎÙÈ + ÄÌÑ ËÁÖÄÏÊ ÐÌÁÔÆÏÒÍÙ ÍÕÌØÔÉ-ÐÒÏÃÅÓÓÎÙÈ ÍÏÄÕÌÅÊ (MPMs) É + ÂÉÂÌÉÏÔÅËÉ Apache Portable Runtime (APR), ÜÔÉ ÐÌÁÔÆÏÒÍÙ + ÔÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÀÔÓÑ Ó ÐÏÍÏÝØÀ ÉÈ ÓÏÂÓÔ×ÅÎÎÙÈ API, ÞÔÏ + ÐÏÚ×ÏÌÑÅÔÓÑ ÉÚÂÅÖÁÔØ ××ÅÄÅÎÉÑ ÚÁÞÁÓÔÕÀ ÎÅÐÒÁ×ÉÌØÎÏ ÒÁÂÏÔÁÀÝÉÈ + ÉÚ-ÚÁ ÂÏÌØÛÏÇÏ ËÏÌÉÞÅÓÔ×Á ÏÛÉÂÏË POSIX - ÜÍÕÌÉÒÕÀÝÉÈ ÓÌÏÅ×.
    + +
    îÏ×ÙÊ API ÄÌÑ Apache
    + +
    API ÄÌÑ ÎÁÐÉÓÁÎÉÑ ÍÏÄÕÌÅÊ ÚÎÁÞÉÔÅÌØÎÏ ÉÚÍÅÎÉÌÓÑ × ×ÅÒÓÉÉ 2.0 + íÎÏÇÉÅ ÉÚ ÐÒÏÂÌÅÍ ×ÅÒÓÉÉ 1.3, Ó×ÑÚÁÎÎÙÅ Ó ÐÏÒÑÄËÏÍ ÓÌÅÄÏ×ÁÎÉÑ + ÍÏÄÕÌÅÊ É ÉÈ ÐÒÉÏÒÉÔÅÔÁÍÉ, ÄÏÌÖÎÙ ÉÓÞÅÚÎÕÔØ. ÷ ×ÅÒÓÉÉ 2.0 + ÍÎÏÇÉÅ ÉÚ ÐÏÄÏÂÎÙÈ ×ÅÝÅÊ ÄÅÌÁÀÔÓÑ Á×ÔÏÍÁÔÉÞÅÓËÉ, É ÔÅÐÅÒØ + ÐÏÒÑÄÏË ÓÌÅÄÏ×ÁÎÉÑ ÍÏÄÕÌÅÊ ÏÐÒÅÄÅÌÑÅÔÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ ÓÐÅÃÉÁÌØÎÙÈ + ÐÒÏÇÒÁÍÍÎÙÈ ËÒÀÞËÏ× (hooks), ÏÔÞÅÇÏ ÎÁÓÔÒÏÊËÁ ÓÅÒ×ÅÒÁ ÓÔÁÎÏ×ÉÔÓÑ + ÂÏÌÅÅ ÇÉÂËÏÊ. ôÁËÖÅ ÂÙÌÉ ÄÏÂÁ×ÌÅÎÙ ÎÏ×ÙÅ ÆÕÎËÃÉÉ, ËÏÔÏÒÙÅ + ÐÒÅÄÏÓÔÁ×ÌÑÀÔ ÄÏÐÏÌÎÉÔÅÌØÎÙÅ ×ÏÚÍÏÖÎÏÓÔÉ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ÍÏÄÕÌÅÊ, + ÉÚÂÁ×ÌÑÑ ÏÔ ÎÅÏÂÈÏÄÉÍÏÓÔÉ ×ÎÅÓÅÎÉÑ ËÁËÉÈ - ÌÉÂÏ ÉÚÍÅÎÅÎÉÊ × ÑÄÒÏ + ÓÅÒ×ÅÒÁ.
    + +
    ðÏÄÄÅÒÖËÁ ÐÒÏÔÏËÏÌÁ IPv6
    + +
    îÁ ÓÉÓÔÅÍÁÈ, ÇÄÅ ÐÒÏÔÏËÏÌ IPv6 ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ + ÂÁÚÏ×ÏÊ ÂÉÂÌÉÏÔÅËÏÊ Apache Portable Runtime, Apache + ÐÏ ÕÍÏÌÞÁÎÉÀ ÐÏÌÕÞÁÅÔ ×ÏÚÍÏÖÎÏÓÔØ ÓÌÕÛÁÔØ IPv6 ÓÏËÅÔÙ + (sockets). ÷ ÄÏÂÁ×ÏË Ë ÜÔÏÍÕ ÄÉÒÅËÔÉ×Ù Listen, NameVirtualHost É VirtualHost ÍÏÇÕÔ ÒÁÂÏÔÁÔØ Ó ÁÄÒÅÓÎÙÍÉ ÓÔÒÏËÁÍÉ, + ÚÁÄÁÎÎÙÍÉ × ÆÏÒÍÁÔÅ IPv6 (Ô.Å. ÎÁÐÒÉÍÅÒ "Listen [fe80::1]:8080").
    + +
    éÓÐÏÌØÚÏ×ÁÎÉÅ ÆÉÌØÔÒÏ×
    + +
    íÏÄÕÌÉ Apache ÔÅÐÅÒØ ÍÏÇÕÔ ÂÙÔØ ÎÁÐÉÓÁÎÙ ËÁË ÆÉÌØÔÒÙ, + ÏÂÒÁÂÁÔÙ×ÁÀÝÉÅ ÐÏÔÏËÉ ÄÁÎÎÙÈ, ËÏÔÏÒÙÅ ÐÒÉÈÏÄÑÔ ÉÌÉ ÕÈÏÄÑÔ + ÉÚ ÓÅÒ×ÅÒÁ. üÔÏ ÐÏÚ×ÏÌÑÅÔ, Ë ÐÒÉÍÅÒÕ, ÄÁÎÎÙÍ, Ñ×ÌÑÀÝÉÍÓÑ + ÒÅÚÕÌØÔÁÔÏÍ ÒÁÂÏÔÙ CGI-ÓËÒÉÐÔÁ, ÂÙÔØ ÏÂÒÁÂÏÔÁÎÎÙÍÉ SSI + ÆÉÌØÔÒÏÍ INCLUDES, ÐÒÅÄÏÓÔÁ×ÌÑÅÍÙÍ ÍÏÄÕÌÅÍ + mod_include. íÏÄÕÌØ mod_ext_filter + ÐÏÚ×ÏÌÑÅÔ ×ÎÅÛÎÉÍ ÐÒÏÇÒÁÍÍÁÍ ÉÓÐÏÌÎÑÔØ ÒÏÌØ ÆÉÌØÔÒÏ× ÔÏÞÎÏ ÔÁË ÖÅ + ËÁË É CGI ÐÒÏÇÒÁÍÍÁÍ ÐÏÚ×ÏÌÑÅÔÓÑ ÄÅÊÓÔ×Ï×ÁÔØ × ËÁÞÅÓÔ×Å + ÏÂÒÁÂÏÔÞÉËÏ× (handlers).
    + +
    óÏÏÂÝÅÎÉÑ ÏÂ ÏÛÉÂËÁÈ ÎÁ ÒÁÚÎÙÈ ÑÚÙËÁÈ
    + +
    óÏÏÂÝÅÎÉÑ Ï ÏÛÉÂËÁÈ, ÐÏÓÙÌÁÅÍÙÅ ÂÒÁÕÚÅÒÕ, ÔÅÐÅÒØ + ÐÒÅÄÓÔÁ×ÌÅÎÙ ÎÁ ÎÅÓËÏÌØËÉÈ ÑÚÙËÁÈ É ÉÓÐÏÌØÚÕÀÔ SSI + ÔÅÈÎÏÌÏÇÉÀ. ïÎÉ ÍÏÇÕÔ ÂÙÔØ ÌÅÇËÏ ÏÔÒÅÄÁËÔÉÒÏ×ÁÎÙ + ÁÄÍÉÎÉÓÔÒÁÔÏÒÏÍ ÐÏÄ Ó×ÏÉ ÎÕÖÄÙ.
    + +
    õÐÒÏÝÅÎÎÁÑ ËÏÎÆÉÇÕÒÁÃÉÑ
    + +
    íÎÏÇÉÅ ÚÁÐÕÔÁÎÎÙÅ ÄÉÒÅËÔÉ×Ù ÂÙÌÉ ÕÐÒÏÝÅÎÙ. îÁÉÂÏÌÅÅ + ÓÂÉ×ÁÀÝÉÅ Ó ÔÏÌËÕ Port É BindAddress ÂÙÌÉ ÕÂÒÁÎÙ; + ÄÌÑ ÐÒÉ×ÑÚËÉ Ë IP ÁÄÒÅÓÕ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ ÄÉÒÅËÔÉ×Á + Listen; ÄÉÒÅËÔÉ×Á + ServerName ÏÐÒÅÄÅÌÑÅÔ ÉÍÑ ÓÅÒ×ÅÒÁ É ÎÏÍÅÒ ÐÏÒÔÁ + ÔÅÐÅÒØ ÔÏÌØËÏ ÄÌÑ ÐÅÒÅÎÁÐÒÁ×ÌÅÎÉÊ É ÒÁÂÏÔÙ Ó ×ÉÒÔÕÁÌØÎÙÍÉ ÈÏÓÔÁÍÉ.
    + +
    ðÏÄÄÅÒÖËÁ ÀÎÉËÏÄÁ Windows NT
    + +
    Apache 2.0 ÎÁ Windows NT ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÅÔ ËÏÄÉÒÏ×ËÕ utf-8 + ÄÌÑ ÒÁÂÏÔÙ Ó ÉÍÅÎÁÍÉ ÆÁÊÌÏ×. üÔÏ ÐÏÚ×ÏÌÑÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ + ÎÉÖÅÌÅÖÁÝÕÀ ÆÁÊÌÏ×ÕÀ ÓÉÓÔÅÍÕ, ÒÁÂÏÔÁÀÝÕÀ × ÆÏÒÍÁÔÅ Unicode, + ÞÔÏ ÐÒÅÄÏÓÔÁ×ÌÑÅÔ ÐÏÄÄÅÒÖËÕ ÓÅÒ×ÅÒÏÍ ÍÎÏÇÏÑÚÙÞÎÏÓÔÉ ÄÌÑ ×ÓÅÈ NT- + ÓÉÓÔÅÍ, ×ËÌÀÞÁÑ Windows 2000 É Windows XP. + üÔÏ ÎÅ ÒÁÓÐÒÏÓÔÒÁÎÑÅÔÓÑ ÎÁ ÔÁËÉÅ ÏÐÅÒÁÃÉÏÎÎÙÅ ÓÉÓÔÅÍÙ, ËÁË + Windows 95, 98 ÉÌÉ ME, ËÏÔÏÒÙÅ ÄÌÑ ÏÂÒÁÝÅÎÉÑ Ë ÆÁÊÌÏ×ÏÊ ÓÉÓÔÅÍÅ + ÉÓÐÏÌØÚÕÀÔ ÌÏËÁÌØÎÙÅ ÍÁÛÉÎÎÙÅ ËÏÄÏ×ÙÅ ÓÔÒÁÎÉÃÙ.
    + +
    îÏ×ÁÑ ÂÉÂÌÉÏÔÅËÁ ÄÌÑ ÒÁÂÏÔÙ Ó ÒÅÇÕÌÑÒÎÙÍÉ ×ÙÒÁÖÅÎÑÍÉ
    + +
    ÷ ÓÏÓÔÁ× Apache 2.0 ÂÙÌÁ ×ËÌÀÞÅÎÁ + ÂÉÂÌÉÏÔÅËÁ ÄÌÑ ÒÁÂÏÔÙ Ó Perl-ÓÏ×ÍÅÓÔÉÍÙÍÉ ÒÅÇÕÌÑÒÎÙÍÉ ×ÙÒÁÖÅÎÑÍÉ (PCRE). + ÷ÓÅ ÒÅÇÕÌÑÒÎÙÅ ×ÙÒÁÖÅÎÉÑ ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÀÔ ÂÏÌÅÅ ÍÏÝÎÙÊ ÓÉÎÔÁËÓÉÓ Perl 5.
    + +
    +
    + +
    + õÌÕÞÛÅÎÉÑ × ÍÏÄÕÌÑÈ ÓÅÒ×ÅÒÁ + +
    +
    mod_ssl
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ Ñ×ÌÑÅÔÓÑ ÉÎÔÅÒÆÅÊÓÏÍ + Ë ÐÒÏÔÏËÏÌÁÍ ÛÉÆÒÏ×ÁÎÉÑ SSL/TLS, ÐÒÅÄÏÓÔÁ×ÌÑÅÍÙÍÉ OpenSSL.
    + +
    mod_dav
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ×ÎÅÄÒÑÅÔ ÓÐÅÃÉÆÉËÁÃÉÀ + Distributed Authoring and Versioning (DAV), ÐÏÚ×ÏÌÑÀÝÕÀ ÕÐÒÁ×ÌÑÔØ + ÓÏÄÅÒÖÉÍÙÍ ÓÁÊÔÁ ÐÏÓÒÅÄÓÔ×ÏÍ ÒÁÓÛÉÒÅÎÎÏÇÏ ÐÒÏÔÏËÏÌÁ HTTP.
    + +
    mod_deflate
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ ÂÒÁÕÚÅÒÁÍ, ÐÏÄÄÅÒÖÉ×ÁÀÝÉÍ + ÄÁÎÎÕÀ ÔÅÈÎÏÌÏÇÉÀ, ÚÁÐÒÁÛÉ×ÁÔØ ÄÁÎÎÙÅ × ÓÖÁÔÏÍ ×ÉÄÅ, ÞÔÏ ÓÏËÒÁÝÁÅÔ ÎÁÇÒÕÚËÕ ÎÁ + ÓÅÔØ.
    + +
    mod_auth_ldap
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0.41. üÔÏÔ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÂÁÚÕ ÄÁÎÎÙÈ LDAP + ÄÌÑ ÈÒÁÎÅÎÉÑ ÉÍÅÎ É ÐÁÒÏÌÅÊ ÐÏÌØÚÏ×ÁÔÅÌÅÊ, ÎÅÏÂÈÏÄÉÍÙÈ ÐÒÉ ÁÕÔÅÎÔÉÆÉËÁÃÉÉ ÐÏ ÍÅÔÏÄÕ + Basic. óÏÐÕÔÓÔ×ÕÀÝÉÊ ÅÍÕ ÍÏÄÕÌØ mod_ldap ÏÂÅÓÐÅÞÉ×ÁÅÔ ×ÏÚÍÏÖÎÏÓÔØ + ÓÏÚÄÁÎÉÑ ÏÞÅÒÅÄÅÊ ÐÏÄËÌÀÞÅÎÉÊ (connection pools) É ËÜÛÉÒÏ×ÁÎÉÑ ÒÅÚÕÌØÔÁÔÏ×.
    + +
    mod_auth_digest
    + +
    ÷ËÌÀÞÁÅÔ ÄÏÐÏÌÎÉÔÅÌØÎÕÀ ÐÏÄÄÅÒÖËÕ ËÜÛÉÒÏ×ÁÎÉÑ ÓÅÓÓÉÊ + ÐÒÏÃÅÓÓÁÍÉ, ÂÌÁÇÏÄÁÒÑ ÉÓÐÏÌØÚÏ×ÁÎÉÀ ÏÂÝÅÊ ÏÂÌÁÓÔÉ ÐÁÍÑÔÉ (ÒÁÚÄÅÌÅÎÉÀ + ÐÁÍÑÔÉ).
    + +
    mod_charset_lite
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÍÏÄÕÌØ ÐÏÚ×ÏÌÑÅÔ + ÏÓÕÝÅÓÔ×ÌÑÔØ ÐÅÒÅ×ÏÄ ÉÚ ÏÄÎÏÇÏ ÎÁÂÏÒÁ ÓÉÍ×ÏÌÏ× (character set) × ÄÒÕÇÏÊ É ÉÚ ÏÄÎÏÊ + ËÏÄÉÒÏ×ËÉ × ÄÒÕÇÕÀ.
    + +
    mod_file_cache
    + +
    îÏ×ÙÊ ÍÏÄÕÌØ × Apache 2.0. üÔÏÔ ÍÏÄÕÌØ ×ËÌÀÞÁÅÔ × ÓÅÂÑ + ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ ÍÏÄÕÌÑ mod_mmap_static ÉÚ Apache 1.3 + ÐÌÀÓ ÎÏ×ÙÅ ×ÏÚÍÏÖÎÏÓÔÉ ËÜÛÉÒÏ×ÁÎÉÑ.
    + +
    mod_headers
    + +
    üÔÏÔ ÍÏÄÕÌØ ÓÔÁÌ ÂÏÌÅÅ ÇÉÂËÉÍ × Apache 2.0. ïÎ ÐÏÚ×ÏÌÑÅÔ + ÍÏÄÉÆÉÃÉÒÏ×ÁÔØ ÚÁÇÏÌÏ×ËÉ ÚÁÐÒÏÓÏ×, ÉÓÐÏÌØÚÕÅÍÙÈ ÍÏÄÕÌÅÍ + mod_proxy, É ÍÏÖÅÔ ×ËÌÀÞÁÔØ × ÏÔ×ÅÔ ÓÅÒ×ÅÒÁ ÚÁÇÏÌÏ×ËÉ × + ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ÒÁÚÌÉÞÎÙÈ ÕÓÌÏ×ÉÊ.
    + +
    mod_proxy
    + +
    ðÒÏËÓÉ ÍÏÄÕÌØ ÂÙÌ ÐÏÌÎÏÓÔØÀ ÐÅÒÅÐÉÓÁÎ, É ÔÅÐÅÒØ ×ËÌÀÞÁÅÔ + × ÓÅÂÑ ÐÒÅÉÍÕÝÅÓÔ×Á ÎÏ×ÏÊ ÆÉÌØÔÒÏ×ÏÊ ÉÎÆÒÁÓÔÒÕËÔÕÒÙ É ÉÓÐÏÌØÚÕÅÔ + ÂÏÌÅÅ ÎÁÄÅÖÎÕÀ, ÓÏ×ÍÅÓÔÉÍÕÀ Ó HTTP/1.1 ÐÒÏËÓÉ-ÔÅÈÎÏÌÏÇÉÀ. ÷ ÄÏÂÁ×ÏË + Ë ÜÔÏÍÕ ÂÙÌÁ ××ÅÄÅÎÁ ÎÏ×ÁÑ ÓÅËÃÉÑ Proxy, ËÏÔÏÒÕÀ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÈ ÆÁÊÌÁÈ, ÞÔÏ + ÏÂÅÓÐÅÞÉ×ÁÅÔ ÂÏÌÅÅ ÕÄÏÂÎÙÊ (É ÂÏÌÅÅ ÂÙÓÔÒÙÊ ÄÌÑ ÑÄÒÁ ÓÅÒ×ÅÒÁ) ËÏÎÔÒÏÌØ ÎÁÄ ÓÁÊÔÁÍÉ, + ÉÓÐÏÌØÚÕÀÝÉÍÉ proxy-ÔÅÈÎÏÌÏÇÉÀ. ðÅÒÅÇÒÕÖÅÎÎÁÑ ËÏÎÆÉÇÕÒÁÃÉÑ <Directory "proxy:..."> + ÂÏÌÅÅ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ. íÏÄÕÌØ ÔÅÐÅÒØ ÒÁÚÄÅÌÅÎ ÎÁ ÏÔÄÅÌØÎÙÅ ÓÐÅÃÉÆÉÞÎÙÅ ÍÏÄÕÌÉ, + ÐÏÄÄÅÒÖÉ×ÁÀÝÉÅ ÒÁÚÌÉÞÎÙÅ ÐÒÏÔÏËÏÌÙ. üÔÉ ÍÏÄÕÌÉ ×ËÌÀÞÁÀÔ × ÓÅÂÑ proxy_connect, proxy_ftp + É proxy_http.
    + +
    mod_negotiation
    + +
    äÏÂÁ×ÌÅÎÁ ÎÏ×ÁÑ ÄÉÒÅËÔÉ×Á ForceLanguagePriority, ÄÌÑ ÔÏÇÏ ÞÔÏÂÙ ×ÍÅÓÔÏ ÏÔ×ÅÔÏ× ÓÅÒ×ÅÒÁ + NOT ACCEPTABLE ÉÌÉ MULTIPLE CHOICES ×ÓÅÇÄÁ ÐÒÅÄÏÓÔÁ×ÌÑÔØ ÐÏÌØÚÏ×ÁÔÅÌÀ + ÏÐÒÅÄÅÌÅÎÎÙÊ ÄÏËÕÍÅÎÔ. ÷ ÄÏÐÏÌÎÅÎÉÅ Ë ÜÔÏÍÕ ÁÌÇÏÒÉÔÍÙ + ÎÅÇÏÃÉÁÃÉÉ (negotiation) É MultiViews ÂÙÌÉ ×ÙÞÉÝÅÎÙ É ÉÓÐÒÁ×ÌÅÎÙ, ÄÌÑ + ÏÂÅÓÐÅÞÅÎÉÑ ÂÏÌÅÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÒÅÚÕÌØÔÁÔÁ, Á ÔÁËÖÅ ÐÏÑ×ÉÌÁÓØ ×ÏÚÍÏÖÎÏÓÔØ + ×ËÌÀÞÅÎÉÑ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏÇÏ ÓÏÄÅÒÖÉÍÏÇÏ ÄÏËÕÍÅÎÔÏ× × ËÁÒÔÕ ÔÉÐÏ× (type map).
    + +
    mod_autoindex
    + +
    ìÉÓÔÉÎÇÉ Á×ÔÏÉÎÄÅËÓÉÒÕÅÍÙÈ ËÁÔÁÌÏÇÏ× ÔÅÐÅÒØ ÍÏÇÕÔ ×ÙÄÁ×ÁÔØÓÑ × ×ÉÄÅ + HTML-ÔÁÂÌÉÃ. ðÏÑ×ÉÌÁÓØ ×ÏÚÍÏÖÎÏÓÔØ ÂÏÌÅÅ ÇÉÂËÏÊ ÓÏÒÔÉÒÏ×ËÉ, ×ËÌÀÞÁÑ ÓÏÒÔÉÒÏ×ËÕ ÐÏ ×ÅÒÓÉÑÍ É + ÓÏÒÔÉÒÏ×ËÕ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ ÕÎÉ×ÅÒÓÁÌØÎÙÈ ÓÉÍ×ÏÌÏ× (wildcard).
    + +
    mod_include
    + +
    ÷×ÅÄÅÎÙ ÎÏ×ÙÅ ÄÉÒÅËÔÉ×Ù, ËÏÔÏÒÙÅ ÐÏÚ×ÏÌÑÀÔ ÉÚÍÅÎÉÔØ ÎÁÞÁÌØÎÙÊ É ËÏÎÅÞÎÙÊ + ÔÅÇÉ SSI ÜÌÅÍÅÎÔÏ×, ÚÁÄÁ×ÁÅÍÙÅ ÐÏ ÕÍÏÌÞÁÎÉÀ, Á ÔÁËÖÅ ÐÒÅÄÏÓÔÁ×ÌÑÀÔ ×ÏÚÍÏÖÎÏÓÔØ + ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ ÆÏÒÍÁÔÁ ÓÏÏÂÝÅÎÉÊ Ï ÏÛÉÂËÁÈ É ×ÒÅÍÅÎÉ ÎÅÐÏÓÒÅÄÓÔ×ÅÎÎÏ + × ÇÌÁ×ÎÏÍ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÍ ÆÁÊÌÅ, Á ÎÅ × SSI ÄÏËÕÍÅÎÔÅ. òÅÚÕÌØÔÁÔÙ + ÏÂÒÁÂÏÔËÉ ÒÅÇÕÌÑÒÎÙÈ ×ÙÒÁÖÅÎÉÊ (ÔÅÐÅÒØ ÏÓÎÏ×Ù×ÁÀÝÉÈÓÑ ÎÁ ÓÉÎÔÁËÓÉÓÅ + ÒÅÇÕÌÑÒÎÙÈ ×ÙÒÁÖÅÎÉÊ ÑÚÙËÁ Perl) ÍÏÇÕÔ ÂÙÔØ ÐÏÌÕÞÅÎÙ ÐÒÉ ÐÏÍÏÝÉ ÐÅÒÅÍÅÎÎÙÈ + $0 .. $9 ÍÏÄÕÌÑ mod_include.
    + +
    mod_auth_dbm
    + +
    ôÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÍÎÏÇÏÞÉÓÌÅÎÎÙÅ ÔÉÐÙ DBM-ÐÏÄÏÂÎÙÈ ÂÁÚ ÄÁÎÎÙÈ ÐÏÓÒÅÄÓÔ×ÏÍ + ÄÉÒÅËÔÉ×Ù AuthDBMType.
    + +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_2.html b/trunk/docs/manual/new_features_2_2.html new file mode 100644 index 0000000000..b79e2041d9 --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.html @@ -0,0 +1,11 @@ +URI: new_features_2_2.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: new_features_2_2.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR + +URI: new_features_2_2.html.pt-br +Content-Language: pt-br +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/new_features_2_2.html.en b/trunk/docs/manual/new_features_2_2.html.en new file mode 100644 index 0000000000..522baf7a7f --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.html.en @@ -0,0 +1,172 @@ + + + +Overview of new features in Apache 2.2 - Apache HTTP Server + + + + + +
    <-
    +

    Overview of new features in Apache 2.2

    +
    +

    Available Languages:  en  | + ko  | + pt-br 

    +
    + +

    This document describes some of the major changes between the + 2.0 and 2.2 versions of the Apache HTTP Server. For new features since + version 1.3, see the 2.0 new features + document.

    +
    + +
    top
    +
    +

    Core Enhancements

    + +
    + +
    Authn/Authz
    +
    The bundled authentication and authorization modules have + been refactored. There is a new authentication backend provider + scheme which greatly eases the construction of new authentication + backends.
    + +
    Caching
    +
    mod_cache, mod_disk_cache, and + mod_mem_cache have undergone a lot of changes + are now considered production-quality. htcacheclean + has been introduced to cleanup mod_disk_cache + setups.
    + +
    Proxying
    +
    The new mod_proxy_balancer module provides + load balancing services for mod_proxy. + The new mod_proxy_ajp module adds support for the + Apache JServ Protocol version 1.3 used by + Apache Tomcat.
    + +
    Regular Expression Library Updated
    +
    Version 5.0 of the + Perl Compatible Regular Expression + Library (PCRE) is now included.
    + +
    Smart Filtering
    +
    mod_filter introduces dynamic configuration + to the output filter chain. It enables filters to be conditionally + inserted, based on any Request or Response header or environment + variable, and dispenses with the more problematic dependencies and + ordering problems in the 2.0 architecture.
    + +
    Large File Support
    + +
    httpd is now built with support for files larger than 2Gb on + modern 32-bit Unix systems. Support for handling >2Gb request + bodies has also been added.
    + +
    Event MPM
    +
    The event MPM uses a seperate thread to handle + Keep Alive requests and accepting connections. Keep Alive requests + have traditionally required httpd to dedicate a worker to handle it. + This dedicated worker could not be used again until the Keep Alive + timeout was reached.
    + +
    +
    top
    +
    +

    Module Enhancements

    + +
    +
    mod_authnz_ldap
    +
    This module is a port of the 2.0 + mod_auth_ldap module to the 2.2 Authn/Authz + framework. New features include using LDAP attribute values and + complicated search filters in the + Require directive.
    + +
    mod_info
    +
    Added a new ?config argument which will show + the configuration directives as parsed by Apache, including + their file name and line number. The module also + shows the order of all request hooks and additional + build information, similar to httpd -V.
    + +
    mod_ssl
    + +
    Added a support for + RFC 2817, which + allows connections to upgrade from clear text to TLS encryption.
    +
    +
    top
    +
    +

    Program Enhancements

    + +
    +
    httpd
    +
    A new command line option -M has been added that + lists all modules that are loaded based on the current + configuration. Unlike the -l option, this list + includes DSOs loaded via mod_so.
    +
    +
    top
    +
    +

    Module Developer Changes

    + +
    +
    APR 1.0 API
    + +
    Apache 2.2 uses the APR 1.0 API. All deprecated functions and + symbols have been removed from APR and + APR-Util. For details, see the + APR Website.
    + +
    Connection Error Logging
    + +
    A new function, ap_log_cerror has been added to log + errors that occure with the client's connection. When logged, + the message includes the client IP address.
    + +
    Test Configuration Hook Added
    + +
    A new hook, test_config has been added to aid + modules that want to execute special code only when the user passes + -t to httpd.
    + +
    Set Threaded MPM's Stacksize
    + +
    A new directive, ThreadStackSize has been added to + set the stack size on all threaded MPMs. This is required + for some third-party modules on platforms with small default + thread stack size.
    + +
    Protocol handling for output filters
    + +
    In the past, every filter has been responsible for ensuring + that it generates the correct response headers where it affects + them. Filters can now delegate common protocol management to + mod_filter, using the + ap_register_output_filter_protocol or + ap_filter_protocol calls.
    +
    +
    +
    +

    Available Languages:  en  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_2.html.ko.euc-kr b/trunk/docs/manual/new_features_2_2.html.ko.euc-kr new file mode 100644 index 0000000000..e94f58448d --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.html.ko.euc-kr @@ -0,0 +1,126 @@ + + + +¾ÆÆÄÄ¡ 2.2ÀÇ »õ·Î¿î ±â´É °³¿ä - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ 2.2ÀÇ »õ·Î¿î ±â´É °³¿ä

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko  | + pt-br 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü°ú 2.2 ¹öÀü°£ÀÇ ÁÖµÈ Â÷ÀÌÁ¡À» + ¼³¸íÇÑ´Ù. 1.3 ¹öÀü ÀÌÈÄÀÇ »õ·Î¿î ±â´ÉÀº 2.0 »õ·Î¿î ±â´É ¹®¼­¸¦ + Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    ÇÙ½É ºÎºÐ¿¡¼­ ³ª¾ÆÁø Á¡

    + +
    + +
    Authn/Authz
    +
    ...
    + +
    ij½¬
    +
    ...
    + +
    ÇÁ·Ï½Ã
    +
    »õ·Î¿î mod_proxy_balancer ¸ðµâÀÌ + mod_proxy¸¦ À§ÇÑ ºÎÇÏºÐ»ê ¼­ºñ½º¸¦ Á¦°øÇÑ´Ù. + »õ·Î¿î mod_proxy_ajp ¸ðµâÀº ¾ÆÆÄÄ¡ ÅèĹÀÌ + »ç¿ëÇÏ´Â Apache JServ Protocol 1.3 ¹öÀüÀ» + Áö¿øÇÑ´Ù.
    + +
    ¶È¶ÈÇÑ ÇÊÅÍ
    +
    mod_filter´Â Ãâ·ÂÇÊÅͼø¼­¸¦ µ¿ÀûÀ¸·Î + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ¿äû Çì´õ, ÀÀ´ä Çì´õ, ȯ°æº¯¼ö¿¡ + µû¶ó ¼±ÅÃÀûÀ¸·Î ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ°í, 2.0 ±¸Á¶ÀÇ Àǽɽº·¯¿î + ÀÇÁ¸°ü°è¿Í ¼ø¼­ ¹®Á¦¸¦ ´ú¾îÁØ´Ù.
    + +
    +
    top
    +
    +

    ¸ðµâ¿¡¼­ ³ª¾ÆÁø Á¡

    + +
    +
    mod_authnz_ldap
    +
    ÀÌ ¸ðµâÀº 2.0ÀÇ mod_auth_ldap ¸ðµâÀ» + 2.2ÀÇ Authn/Authz ±¸Á¶·Î ¿Å±ä °ÍÀÌ´Ù. Require Áö½Ã¾î¿¡¼­ LDAP + ¼Ó¼º(attribute) °ª°ú º¹ÀâÇÑ °Ë»ö ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â + ±â´ÉÀÌ Ãß°¡µÇ¾ú´Ù.
    + +
    mod_info
    +
    ¾ÆÆÄÄ¡°¡ ÀоîµéÀÎ ¼³Á¤Áö½Ã¾î¸¦ ÆÄÀϸí°ú ÁÙ¹øÈ£¿Í °°ÀÌ + º¸¿©ÁÖ´Â ?config ¾Æ±Ô¸ÕÆ®°¡ Ãß°¡µÇ¾ú´Ù. ¸ðµâÀº + ¸ðµç ¿äû ÈÅ(hook)ÀÇ ¼ø¼­¿Í httpd -V¿Í ºñ½ÁÇÑ + ÄÄÆÄÀÏ Á¤º¸µµ º¸¿©ÁØ´Ù.
    +
    +
    top
    +
    +

    ¸ðµâ °³¹ßÀÚ¿¡°Ô ´Þ¶óÁø Á¡

    + +
    +
    APR 1.0 API
    + +
    ¾ÆÆÄÄ¡ 2.2´Â APR 1.0 API¸¦ »ç¿ëÇÑ´Ù. APR°ú + APR-Util¿¡¼­ ¾ø¾îÁö±â·Î ¿¹Á¤µÇ¾ú´ø ÇÔ¼ö¿Í + ½Éº¼ÀÌ ¸ðµÎ ¾ø¾îÁ³´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº APR À¥»çÀÌÆ®¸¦ Âü°íÇ϶ó.
    + +
    ¿¬°á ¿À·ù ·Î±× ±â·Ï
    + +
    Ŭ¶óÀ̾ðÆ®¿Í ¿¬°á¿¡ ¹ß»ýÇÑ ¿À·ù¸¦ ·Î±×¿¡ ±â·ÏÇϱâÀ§ÇØ + ÇÔ¼ö ap_log_cerror¸¦ »õ·Î Ãß°¡Çß´Ù. ·Î±×¿¡ + ±â·ÏÇÏ¸é ¹®±¸¿¡ Ŭ¶óÀ̾ðÆ® IP ÁÖ¼Ò°¡ ³ª¿Â´Ù.
    + +
    ¼³Á¤ Å×½ºÆ®¿ë ÈÅ Ãß°¡
    + +
    »ç¿ëÀÚ°¡ httpd¿¡ -t ¿É¼ÇÀ» »ç¿ëÇÑ °æ¿ì¿¡¸¸ + ¸ðµâÀÌ Æ¯º°ÇÑ Äڵ带 ½ÇÇàÇϵµ·Ï ÈÅ test_config¸¦ + »õ·Î Ãß°¡Çß´Ù.
    + +
    ¾²·¹µå±â¹Ý MPMÀÇ ½ºÅÃÅ©±â ÁöÁ¤
    + +
    ¸ðµç ¾²·¹µå±â¹Ý MPMÀÇ ½ºÅÃÅ©±â¸¦ ÁöÁ¤ÇϱâÀ§ÇØ + ThreadStackSize Áö½Ã¾î¸¦ »õ·Î Ãß°¡Çß´Ù. ¾²·¹µå + ½ºÅÃÅ©±â ±âº»°ªÀÌ ÀÛÀº Ç÷¹Æû¿¡¼­ ÀϺΠÁ¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» + »ç¿ëÇÒ °æ¿ì¿¡ ÇÊ¿äÇÏ´Ù.
    + +
    Ãâ·ÂÇÊÅ͸¦ À§ÇÑ ÇÁ·ÎÅäÄÝ Ã³¸®
    + +
    Àü¿¡´Â ¸ðµç ÇÊÅÍ¿¡°Ô ÀÚ½ÅÀÌ Ã³¸®ÇÑ ÀÀ´ä¿¡ ¿Ã¹Ù¸¥ ÀÀ´ä + Çì´õ¸¦ »ý¼ºÇÏ´ÂÁö È®ÀÎÇÒ Ã¥ÀÓÀÌ ÀÖ¾ú´Ù. ÀÌÁ¦ ÇÊÅÍ´Â + ap_register_output_filter_protocol ȤÀº + ap_filter_protocol È£ÃâÀ» »ç¿ëÇÏ¿© ÀÏ»óÀûÀÎ + ÇÁ·ÎÅäÄÝ °ü¸®¸¦ mod_filter¿¡°Ô ¶°³Ñ±æ + ¼ö ÀÖ´Ù.
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_2.html.pt-br b/trunk/docs/manual/new_features_2_2.html.pt-br new file mode 100644 index 0000000000..661b0d4419 --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.html.pt-br @@ -0,0 +1,135 @@ + + + +Descrição das novas funcionalidades do Apache 2.2 - Servidor HTTP Apache + + + + + +
    <-
    +

    Descrição das novas funcionalidades do Apache 2.2

    +
    +

    Línguas Disponíveis:  en  | + ko  | + pt-br 

    +
    +
    Esta tradução pode estar desatualizada. + Verifique a versão em Inglês para mudanças recentes.
    + +

    Esse documento descreve algumas das principais mudanças + entre as versões 2.0 e 2.2 do Servidor HTTP Apache. + Para a lista de mudanças desde a versão 1.3, veja a página + de documentação novas funcionalidades + do Apache 2.0.

    +
    + +
    top
    +
    +

    Principais Melhorias

    + +
    + +
    Authn/Authz
    +
    ...
    + +
    Caching
    +
    ...
    + +
    Proxying
    +
    O novo módulo mod_proxy_balancer fornece + serviços de carregamento de balenceamento para mod_proxy. O novo módulo mod_proxy_ajp oferece suporte para o Protocolo Apache JServ + versão 1.3, usado pelo Apache Tomcat.
    + +
    Filtragem Inteligente (Smart Filtering)
    +
    O mod_filter introduz configuração dinâmica para + o filtro de saída de dados. Permitindo que os filtros sejam + condicionalmente inseridos, baseando-se nos cabeçalhos Request ou Response ou em variáveis do + ambiente, ele acaba com os problemas de dependências e pedidos + da arquitetura 2.0.
    + +
    +
    top
    +
    +

    Melhorias nos Módulos

    + +
    +
    mod_authnz_ldap
    +
    Este módulo é uma migração do mod_auth_ldap, + da versão 2.0 para a estrutura 2.2 de Authn/Authz. + As novas funcionalidades incluem o uso de atributos LDAP e + filtros de procura complexos na diretriz Require.
    + +
    mod_info
    +
    Adicionado um novo argumento ?config que + mostra a configuração das diretrizes analisadas pelo + Apache, incluindo o nome do arquivo e o número da linha. + Esse módulo também mostra a ordem de todos os ganchos de + pedidos (request hooks) e informações adicionais sobre + a compilação, similar ao comando httpd -V.
    +
    +
    top
    +
    +

    Mudanças ao Desenvolvedor de Módulos

    + +
    +
    API do APR 1.0
    + +
    O Apache 2.2 utiliza a API do APR 1.0. Todas as funções e + símbolos antigos foram removidos do APR e + APR-Util. Para mais detalhes, visite o + Website do APR.
    + +
    Registros de Erros de Conexão (logs)
    + +
    Uma nova função ap_log_cerror, foi adicionada + para registrar erros que ocorrem na conexão do cliente. + Quando documentado no diário de log, a mensagem inclui o + endereço IP do cliente.
    + +
    Adicionado Gancho de Teste de Configuração
    + +
    Um novo gancho (hook), test_config foi + adicionado para auxiliar módulos que querem executar + códigos especiais apenas quando o usuário passa o + parâmetro -t para o httpd.
    + +
    Ajustar o Stacksize dos "Threaded MPM's"
    + +
    Uma nova diretriz chamada ThreadStackSize, + foi adicionada para ajustar o tamanho das stacks em todos + os threadeds MPMs. Essa é uma prática necessário para alguns + módulos de terceiros em plataformas com tamanhos de stacks + pequenos por padrão.
    + +
    Negociação de Protocolo para filtros de saída
    + +
    No passado, todo filtro era responsável por garantir + a geração de cabeçalhos de resposta correto que os afetava. + Os filtros agora podem delegar o gerenciamento de protocolos + comuns para mod_filter, usando chamadas + de ap_register_output_filter_protocol ou + ap_filter_protocol.
    + +
    + +
    +
    +

    Línguas Disponíveis:  en  | + ko  | + pt-br 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/new_features_2_2.xml b/trunk/docs/manual/new_features_2_2.xml new file mode 100644 index 0000000000..ccf035510b --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.xml @@ -0,0 +1,161 @@ + + + + + + + + + +Overview of new features in Apache 2.2 + + +

    This document describes some of the major changes between the + 2.0 and 2.2 versions of the Apache HTTP Server. For new features since + version 1.3, see the 2.0 new features + document.

    +
    + +
    + Core Enhancements +
    + +
    Authn/Authz
    +
    The bundled authentication and authorization modules have + been refactored. There is a new authentication backend provider + scheme which greatly eases the construction of new authentication + backends.
    + +
    Caching
    +
    mod_cache, mod_disk_cache, and + mod_mem_cache have undergone a lot of changes + are now considered production-quality. htcacheclean + has been introduced to cleanup mod_disk_cache + setups.
    + +
    Proxying
    +
    The new mod_proxy_balancer module provides + load balancing services for mod_proxy. + The new mod_proxy_ajp module adds support for the + Apache JServ Protocol version 1.3 used by + Apache Tomcat.
    + +
    Regular Expression Library Updated
    +
    Version 5.0 of the + Perl Compatible Regular Expression + Library (PCRE) is now included.
    + +
    Smart Filtering
    +
    mod_filter introduces dynamic configuration + to the output filter chain. It enables filters to be conditionally + inserted, based on any Request or Response header or environment + variable, and dispenses with the more problematic dependencies and + ordering problems in the 2.0 architecture.
    + +
    Large File Support
    + +
    httpd is now built with support for files larger than 2Gb on + modern 32-bit Unix systems. Support for handling >2Gb request + bodies has also been added.
    + +
    Event MPM
    +
    The event MPM uses a seperate thread to handle + Keep Alive requests and accepting connections. Keep Alive requests + have traditionally required httpd to dedicate a worker to handle it. + This dedicated worker could not be used again until the Keep Alive + timeout was reached.
    + +
    +
    + +
    + Module Enhancements +
    +
    mod_authnz_ldap
    +
    This module is a port of the 2.0 + mod_auth_ldap module to the 2.2 Authn/Authz + framework. New features include using LDAP attribute values and + complicated search filters in the + Require directive.
    + +
    mod_info
    +
    Added a new ?config argument which will show + the configuration directives as parsed by Apache, including + their file name and line number. The module also + shows the order of all request hooks and additional + build information, similar to httpd -V.
    + +
    mod_ssl
    + +
    Added a support for + RFC 2817, which + allows connections to upgrade from clear text to TLS encryption.
    +
    +
    + +
    + Program Enhancements +
    +
    httpd
    +
    A new command line option -M has been added that + lists all modules that are loaded based on the current + configuration. Unlike the -l option, this list + includes DSOs loaded via mod_so.
    +
    +
    + +
    + Module Developer Changes +
    +
    APR 1.0 API
    + +
    Apache 2.2 uses the APR 1.0 API. All deprecated functions and + symbols have been removed from APR and + APR-Util. For details, see the + APR Website.
    + +
    Connection Error Logging
    + +
    A new function, ap_log_cerror has been added to log + errors that occure with the client's connection. When logged, + the message includes the client IP address.
    + +
    Test Configuration Hook Added
    + +
    A new hook, test_config has been added to aid + modules that want to execute special code only when the user passes + -t to httpd.
    + +
    Set Threaded MPM's Stacksize
    + +
    A new directive, ThreadStackSize has been added to + set the stack size on all threaded MPMs. This is required + for some third-party modules on platforms with small default + thread stack size.
    + +
    Protocol handling for output filters
    + +
    In the past, every filter has been responsible for ensuring + that it generates the correct response headers where it affects + them. Filters can now delegate common protocol management to + mod_filter, using the + ap_register_output_filter_protocol or + ap_filter_protocol calls.
    +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_2.xml.ko b/trunk/docs/manual/new_features_2_2.xml.ko new file mode 100644 index 0000000000..1427d25e11 --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.xml.ko @@ -0,0 +1,118 @@ + + + + + + + + + +¾ÆÆÄÄ¡ 2.2ÀÇ »õ·Î¿î ±â´É °³¿ä + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü°ú 2.2 ¹öÀü°£ÀÇ ÁÖµÈ Â÷ÀÌÁ¡À» + ¼³¸íÇÑ´Ù. 1.3 ¹öÀü ÀÌÈÄÀÇ »õ·Î¿î ±â´ÉÀº 2.0 »õ·Î¿î ±â´É ¹®¼­¸¦ + Âü°íÇ϶ó.

    +
    + +
    + ÇÙ½É ºÎºÐ¿¡¼­ ³ª¾ÆÁø Á¡ +
    + +
    Authn/Authz
    +
    ...
    + +
    ij½¬
    +
    ...
    + +
    ÇÁ·Ï½Ã
    +
    »õ·Î¿î mod_proxy_balancer ¸ðµâÀÌ + mod_proxy¸¦ À§ÇÑ ºÎÇÏºÐ»ê ¼­ºñ½º¸¦ Á¦°øÇÑ´Ù. + »õ·Î¿î mod_proxy_ajp ¸ðµâÀº ¾ÆÆÄÄ¡ ÅèĹÀÌ + »ç¿ëÇÏ´Â Apache JServ Protocol 1.3 ¹öÀüÀ» + Áö¿øÇÑ´Ù.
    + +
    ¶È¶ÈÇÑ ÇÊÅÍ
    +
    mod_filter´Â Ãâ·ÂÇÊÅͼø¼­¸¦ µ¿ÀûÀ¸·Î + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ¿äû Çì´õ, ÀÀ´ä Çì´õ, ȯ°æº¯¼ö¿¡ + µû¶ó ¼±ÅÃÀûÀ¸·Î ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ°í, 2.0 ±¸Á¶ÀÇ Àǽɽº·¯¿î + ÀÇÁ¸°ü°è¿Í ¼ø¼­ ¹®Á¦¸¦ ´ú¾îÁØ´Ù.
    + +
    +
    + +
    + ¸ðµâ¿¡¼­ ³ª¾ÆÁø Á¡ +
    +
    mod_authnz_ldap
    +
    ÀÌ ¸ðµâÀº 2.0ÀÇ mod_auth_ldap ¸ðµâÀ» + 2.2ÀÇ Authn/Authz ±¸Á¶·Î ¿Å±ä °ÍÀÌ´Ù. Require Áö½Ã¾î¿¡¼­ LDAP + ¼Ó¼º(attribute) °ª°ú º¹ÀâÇÑ °Ë»ö ÇÊÅ͸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â + ±â´ÉÀÌ Ãß°¡µÇ¾ú´Ù.
    + +
    mod_info
    +
    ¾ÆÆÄÄ¡°¡ ÀоîµéÀÎ ¼³Á¤Áö½Ã¾î¸¦ ÆÄÀϸí°ú ÁÙ¹øÈ£¿Í °°ÀÌ + º¸¿©ÁÖ´Â ?config ¾Æ±Ô¸ÕÆ®°¡ Ãß°¡µÇ¾ú´Ù. ¸ðµâÀº + ¸ðµç ¿äû ÈÅ(hook)ÀÇ ¼ø¼­¿Í httpd -V¿Í ºñ½ÁÇÑ + ÄÄÆÄÀÏ Á¤º¸µµ º¸¿©ÁØ´Ù.
    +
    +
    + +
    + ¸ðµâ °³¹ßÀÚ¿¡°Ô ´Þ¶óÁø Á¡ +
    +
    APR 1.0 API
    + +
    ¾ÆÆÄÄ¡ 2.2´Â APR 1.0 API¸¦ »ç¿ëÇÑ´Ù. APR°ú + APR-Util¿¡¼­ ¾ø¾îÁö±â·Î ¿¹Á¤µÇ¾ú´ø ÇÔ¼ö¿Í + ½Éº¼ÀÌ ¸ðµÎ ¾ø¾îÁ³´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº APR À¥»çÀÌÆ®¸¦ Âü°íÇ϶ó.
    + +
    ¿¬°á ¿À·ù ·Î±× ±â·Ï
    + +
    Ŭ¶óÀ̾ðÆ®¿Í ¿¬°á¿¡ ¹ß»ýÇÑ ¿À·ù¸¦ ·Î±×¿¡ ±â·ÏÇϱâÀ§ÇØ + ÇÔ¼ö ap_log_cerror¸¦ »õ·Î Ãß°¡Çß´Ù. ·Î±×¿¡ + ±â·ÏÇÏ¸é ¹®±¸¿¡ Ŭ¶óÀ̾ðÆ® IP ÁÖ¼Ò°¡ ³ª¿Â´Ù.
    + +
    ¼³Á¤ Å×½ºÆ®¿ë ÈÅ Ãß°¡
    + +
    »ç¿ëÀÚ°¡ httpd¿¡ -t ¿É¼ÇÀ» »ç¿ëÇÑ °æ¿ì¿¡¸¸ + ¸ðµâÀÌ Æ¯º°ÇÑ Äڵ带 ½ÇÇàÇϵµ·Ï ÈÅ test_config¸¦ + »õ·Î Ãß°¡Çß´Ù.
    + +
    ¾²·¹µå±â¹Ý MPMÀÇ ½ºÅÃÅ©±â ÁöÁ¤
    + +
    ¸ðµç ¾²·¹µå±â¹Ý MPMÀÇ ½ºÅÃÅ©±â¸¦ ÁöÁ¤ÇϱâÀ§ÇØ + ThreadStackSize Áö½Ã¾î¸¦ »õ·Î Ãß°¡Çß´Ù. ¾²·¹µå + ½ºÅÃÅ©±â ±âº»°ªÀÌ ÀÛÀº Ç÷¹Æû¿¡¼­ ÀϺΠÁ¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» + »ç¿ëÇÒ °æ¿ì¿¡ ÇÊ¿äÇÏ´Ù.
    + +
    Ãâ·ÂÇÊÅ͸¦ À§ÇÑ ÇÁ·ÎÅäÄÝ Ã³¸®
    + +
    Àü¿¡´Â ¸ðµç ÇÊÅÍ¿¡°Ô ÀÚ½ÅÀÌ Ã³¸®ÇÑ ÀÀ´ä¿¡ ¿Ã¹Ù¸¥ ÀÀ´ä + Çì´õ¸¦ »ý¼ºÇÏ´ÂÁö È®ÀÎÇÒ Ã¥ÀÓÀÌ ÀÖ¾ú´Ù. ÀÌÁ¦ ÇÊÅÍ´Â + ap_register_output_filter_protocol ȤÀº + ap_filter_protocol È£ÃâÀ» »ç¿ëÇÏ¿© ÀÏ»óÀûÀÎ + ÇÁ·ÎÅäÄÝ °ü¸®¸¦ mod_filter¿¡°Ô ¶°³Ñ±æ + ¼ö ÀÖ´Ù.
    +
    +
    +
    diff --git a/trunk/docs/manual/new_features_2_2.xml.meta b/trunk/docs/manual/new_features_2_2.xml.meta new file mode 100644 index 0000000000..f34a8fb56e --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.xml.meta @@ -0,0 +1,13 @@ + + + + new_features_2_2 + / + . + + + en + ko + pt-br + + diff --git a/trunk/docs/manual/new_features_2_2.xml.pt-br b/trunk/docs/manual/new_features_2_2.xml.pt-br new file mode 100644 index 0000000000..27ed101528 --- /dev/null +++ b/trunk/docs/manual/new_features_2_2.xml.pt-br @@ -0,0 +1,128 @@ + + + + + + + + + +Descrição das novas funcionalidades do Apache 2.2 + + +

    Esse documento descreve algumas das principais mudanças + entre as versões 2.0 e 2.2 do Servidor HTTP Apache. + Para a lista de mudanças desde a versão 1.3, veja a página + de documentação novas funcionalidades + do Apache 2.0.

    +
    + +
    + Principais Melhorias +
    + +
    Authn/Authz
    +
    ...
    + +
    Caching
    +
    ...
    + +
    Proxying
    +
    O novo módulo mod_proxy_balancer fornece + serviços de carregamento de balenceamento para mod_proxy. O novo módulo mod_proxy_ajp oferece suporte para o Protocolo Apache JServ + versão 1.3, usado pelo Apache Tomcat.
    + +
    Filtragem Inteligente (Smart Filtering)
    +
    O mod_filter introduz configuração dinâmica para + o filtro de saída de dados. Permitindo que os filtros sejam + condicionalmente inseridos, baseando-se nos cabeçalhos Request ou Response ou em variáveis do + ambiente, ele acaba com os problemas de dependências e pedidos + da arquitetura 2.0.
    + +
    +
    + +
    + Melhorias nos Módulos +
    +
    mod_authnz_ldap
    +
    Este módulo é uma migração do mod_auth_ldap, + da versão 2.0 para a estrutura 2.2 de Authn/Authz. + As novas funcionalidades incluem o uso de atributos LDAP e + filtros de procura complexos na diretriz Require.
    + +
    mod_info
    +
    Adicionado um novo argumento ?config que + mostra a configuração das diretrizes analisadas pelo + Apache, incluindo o nome do arquivo e o número da linha. + Esse módulo também mostra a ordem de todos os ganchos de + pedidos (request hooks) e informações adicionais sobre + a compilação, similar ao comando httpd -V.
    +
    +
    + +
    + Mudanças ao Desenvolvedor de Módulos +
    +
    API do APR 1.0
    + +
    O Apache 2.2 utiliza a API do APR 1.0. Todas as funções e + símbolos antigos foram removidos do APR e + APR-Util. Para mais detalhes, visite o + Website do APR.
    + +
    Registros de Erros de Conexão (logs)
    + +
    Uma nova função ap_log_cerror, foi adicionada + para registrar erros que ocorrem na conexão do cliente. + Quando documentado no diário de log, a mensagem inclui o + endereço IP do cliente.
    + +
    Adicionado Gancho de Teste de Configuração
    + +
    Um novo gancho (hook), test_config foi + adicionado para auxiliar módulos que querem executar + códigos especiais apenas quando o usuário passa o + parâmetro -t para o httpd.
    + +
    Ajustar o Stacksize dos "Threaded MPM's"
    + +
    Uma nova diretriz chamada ThreadStackSize, + foi adicionada para ajustar o tamanho das stacks em todos + os threadeds MPMs. Essa é uma prática necessário para alguns + módulos de terceiros em plataformas com tamanhos de stacks + pequenos por padrão.
    + +
    Negociação de Protocolo para filtros de saída
    + +
    No passado, todo filtro era responsável por garantir + a geração de cabeçalhos de resposta correto que os afetava. + Os filtros agora podem delegar o gerenciamento de protocolos + comuns para mod_filter, usando chamadas + de ap_register_output_filter_protocol ou + ap_filter_protocol.
    + +
    + +
    +
    diff --git a/trunk/docs/manual/platform/ebcdic.html b/trunk/docs/manual/platform/ebcdic.html new file mode 100644 index 0000000000..f9b208e49c --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.html @@ -0,0 +1,7 @@ +URI: ebcdic.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: ebcdic.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/ebcdic.html.en b/trunk/docs/manual/platform/ebcdic.html.en new file mode 100644 index 0000000000..e2c2d8ce79 --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.html.en @@ -0,0 +1,584 @@ + + + +The Apache EBCDIC Port - Apache HTTP Server + + + + + +
    <-
    +

    The Apache EBCDIC Port

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +
    Warning: This document + has not been updated to take into account changes made in + the 2.0 version of the Apache HTTP Server. Some of the + information may still be relevant, but please use it with care. +
    + +
    + +
    top
    +
    +

    Overview of the Apache EBCDIC Port

    + + + +

    Version 1.3 of the Apache HTTP Server is the first version + which includes a port to a (non-ASCII) mainframe machine which + uses the EBCDIC character set as its native codeset.

    + +

    (It is the SIEMENS family of mainframes running the BS2000/OSD + operating system. This mainframe OS nowadays features a + SVR4-derived POSIX subsystem).

    + +

    The port was started initially to

    + +
      +
    • prove the feasibility of porting the Apache HTTP server to + this platform
    • + +
    • find a "worthy and capable" successor for the venerable + CERN-3.0 daemon + (which was ported a couple of years ago), and to
    • + +
    • prove that Apache's preforking process model can on this + platform easily outperform the accept-fork-serve model used + by CERN by a factor of 5 or more.
    • +
    + +

    This document serves as a rationale to describe some of the + design decisions of the port to this machine.

    + +
    top
    +
    +

    Design Goals

    + + + +

    One objective of the EBCDIC port was to maintain enough + backwards compatibility with the (EBCDIC) CERN server to make + the transition to the new server attractive and easy. This + required the addition of a configurable method to define + whether a HTML document was stored in ASCII (the only format + accepted by the old server) or in EBCDIC (the native document + format in the POSIX subsystem, and therefore the only realistic + format in which the other POSIX tools like grep or + sed could operate on the documents). The current + solution to this is a "pseudo-MIME-format" which is intercepted + and interpreted by the Apache server (see below). Future versions + might solve the problem by defining an "ebcdic-handler" for all + documents which must be converted.

    + +
    top
    +
    +

    Technical Solution

    + + + +

    Since all Apache input and output is based upon the BUFF + data type and its methods, the easiest solution was to add the + conversion to the BUFF handling routines. The conversion must + be settable at any time, so a BUFF flag was added which defines + whether a BUFF object has currently enabled conversion or not. + This flag is modified at several points in the HTTP + protocol:

    + +
      +
    • set before a request is received + (because the request and the request header lines are always + in ASCII format)
    • + +
    • set/unset when the request body is + received - depending on the content type of the request body + (because the request body may contain ASCII text or a binary + file)
    • + +
    • set before a reply header is sent + (because the response header lines are always in ASCII + format)
    • + +
    • set/unset when the response body is sent + - depending on the content type of the response body (because + the response body may contain text or a binary file)
    • +
    + +
    top
    +
    +

    Porting Notes

    + + + +
      +
    1. +

      The relevant changes in the source are #ifdef'ed + into two categories:

      + +
      +
      #ifdef + CHARSET_EBCDIC
      + +
      +

      Code which is needed for any EBCDIC based machine. + This includes character translations, differences in + contiguity of the two character sets, flags which + indicate which part of the HTTP protocol has to be + converted and which part doesn't etc.

      +
      + +
      #ifdef _OSD_POSIX
      + +
      +

      Code which is needed for the SIEMENS BS2000/OSD + mainframe platform only. This deals with include file + differences and socket implementation topics which are + only required on the BS2000/OSD platform.

      +
      +
      +
    2. + +
    3. +

      The possibility to translate between ASCII and EBCDIC at + the socket level (on BS2000 POSIX, there is a socket option + which supports this) was intentionally not chosen, + because the byte stream at the HTTP protocol level consists + of a mixture of protocol related strings and non-protocol + related raw file data. HTTP protocol strings are always + encoded in ASCII (the GET request, any Header: lines, + the chunking information etc.) whereas the file transfer + parts (i.e., GIF images, CGI output etc.) + should usually be just "passed through" by the server. This + separation between "protocol string" and "raw data" is + reflected in the server code by functions like bgets() + or rvputs() for strings, and functions like + bwrite() for binary data. A global translation + of everything would therefore be inadequate.

      + +

      (In the case of text files of course, provisions must be + made so that EBCDIC documents are always served in + ASCII)

      +
    4. + +
    5. +

      This port therefore features a built-in protocol level + conversion for the server-internal strings (which the + compiler translated to EBCDIC strings) and thus for all + server-generated documents. The hard coded ASCII escapes + \012 and \015 which are ubiquitous + in the server code are an exception: they are already the binary + encoding of the ASCII \n and \r and + must not be converted to ASCII a second time. + This exception is only relevant for server-generated strings; + and external EBCDIC documents are not expected to + contain ASCII newline characters.

      +
    6. + +
    7. +

      By examining the call hierarchy for the BUFF management + routines, I added an "ebcdic/ascii conversion layer" which + would be crossed on every puts/write/get/gets, and a + conversion flag which allowed enabling/disabling the + conversions on-the-fly. Usually, a document crosses this + layer twice from its origin source (a file or CGI output) to + its destination (the requesting client): file -> + Apache, and Apache -> client.

      + +

      The server can now read the header lines of a CGI-script + output in EBCDIC format, and then find out that the remainder + of the script's output is in ASCII (like in the case of the + output of a WWW Counter program: the document body contains a + GIF image). All header processing is done in the native + EBCDIC format; the server then determines, based on the type + of document being served, whether the document body (except + for the chunking information, of course) is in ASCII already + or must be converted from EBCDIC.

      +
    8. + +
    9. +

      For Text documents (MIME types text/plain, text/html + etc.), an implicit translation to ASCII can be + used, or (if the users prefer to store some documents in + raw ASCII form for faster serving, or because the files + reside on a NFS-mounted directory tree) can be served + without conversion.

      + +

      Example:

      + +

      to serve files with the suffix .ahtml as a + raw ASCII text/html document without implicit + conversion (and suffix .ascii as ASCII + text/plain), use the directives:

      + +

      + AddType text/x-ascii-html .ahtml
      + AddType text/x-ascii-plain .ascii +

      + +

      Similarly, any text/foo MIME type can be + served as "raw ASCII" by configuring a MIME type + "text/x-ascii-foo" for it using + AddType.

      +
    10. + +
    11. +

      Non-text documents are always served "binary" without + conversion. This seems to be the most sensible choice for, + .e.g., GIF/ZIP/AU file types. This of course + requires the user to copy them to the mainframe host using + the "rcp -b" binary switch.

      +
    12. + +
    13. +

      Server parsed files are always assumed to be in native + (i.e., EBCDIC) format as used on the machine, and + are converted after processing.

      +
    14. + +
    15. +

      For CGI output, the CGI script determines whether a + conversion is needed or not: by setting the appropriate + Content-Type, text files can be converted, or GIF output can + be passed through unmodified. An example for the latter case + is the wwwcount program which we ported as well.

      +
    16. + +
    + +
    top
    +
    +

    Document Storage Notes

    + + + +

    Binary Files

    + + + +

    All files with a Content-Type: which does not + start with text/ are regarded as binary + files by the server and are not subject to any conversion. + Examples for binary files are GIF images, gzip-compressed files + and the like.

    + +

    When exchanging binary files between the mainframe host and + a Unix machine or Windows PC, be sure to use the ftp "binary" + (TYPE I) command, or use the + rcp -b command from the mainframe host (the + -b switch is not supported in unix + rcp's).

    + + + +

    Text Documents

    + + + +

    The default assumption of the server is that Text Files + (i.e., all files whose Content-Type: + starts with text/) are stored in the native + character set of the host, EBCDIC.

    + + + +

    Server Side Included Documents

    + + + +

    SSI documents must currently be stored in EBCDIC only. + No provision is made to convert it from ASCII before + processing.

    + + + +
    top
    +
    +

    Apache Modules' Status

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ModuleStatusNotes
    core+ +
    mod_access+ +
    mod_actions+ +
    mod_alias+ +
    mod_asis+ +
    mod_auth+ +
    mod_auth_anon+ +
    mod_auth_dbm?with own libdb.a
    mod_autoindex+ +
    mod_cern_meta? +
    mod_cgi+ +
    mod_digest+ +
    mod_dir+ +
    mod_so-no shared libs
    mod_env+ +
    mod_example-(test bed only)
    mod_expires+ +
    mod_headers+ +
    mod_imagemap+ +
    mod_include+ +
    mod_info+ +
    mod_log_agent+ +
    mod_log_config+ +
    mod_log_referer+ +
    mod_mime+ +
    mod_mime_magic?not ported yet
    mod_negotiation+ +
    mod_proxy+ +
    mod_rewrite+untested
    mod_setenvif+ +
    mod_speling+ +
    mod_status+ +
    mod_unique_id+ +
    mod_userdir+ +
    mod_usertrack?untested
    + +
    top
    +
    +

    Third Party Modules' Status

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ModuleStatusNotes
    mod_jserv + -JAVA still being ported.
    mod_php3+mod_php3 runs fine, with LDAP and GD + and FreeType libraries.
    mod_put?untested
    mod_session-untested
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/ebcdic.html.ko.euc-kr b/trunk/docs/manual/platform/ebcdic.html.ko.euc-kr new file mode 100644 index 0000000000..1816f3125b --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.html.ko.euc-kr @@ -0,0 +1,559 @@ + + + +¾ÆÆÄÄ¡ EBCDIC Æ÷Æà - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ EBCDIC Æ÷ÆÃ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +
    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ + º¯°æµÈ ³»¿ëÀ» ´ã°íÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, + ÁÖÀÇÇؼ­ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. +
    + +
    + +
    top
    +
    +

    ¾ÆÆÄÄ¡ EBCDIC Æ÷Æà °³¿ä

    + + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â 1.3 ¹öÀü¶§ óÀ½À¸·Î EBCDIC ¹®ÀÚÁýÇÕÀ» + ±âº» ¹®ÀÚÁýÇÕÀ¸·Î »ç¿ëÇÏ´Â (ºñ-ASCII) ¸ÞÀÎÇ÷¹ÀÓ ÄÄÇ»ÅÍ·Î + Æ÷ÆõǾú´Ù.

    + +

    (BS2000/OSD + ¿î¿µÃ¼Á¦¸¦ »ç¿ëÇÏ´Â SIEMENS °è¿­ ¸ÞÀÎÇ÷¹ÀÓÀ» ¸»ÇÑ´Ù. + ÀÌ ¸ÞÀÎÇ÷¹ÀÓ ¿î¿µÃ¼Á¦¿¡´Â ÇöÀç SVR4°è¿­ÀÇ POSIX ÇÏÀ§½Ã½ºÅÛÀÌ + ÀÖ´Ù).

    + +

    Æ÷ÆÃÀº óÀ½¿¡ ´ÙÀ½°ú °°Àº ¸ñÀû¿¡¼­ ½ÃÀ۵Ǿú´Ù

    + +
      +
    • ÀÌ Ç÷¹ÆûÀ¸·Îµµ ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ Æ÷ÆÃÇÒ ¼ö ÀÖ´Ù´Â °¡´É¼ºÀ» º¸À̱âÀ§Çؼ­
    • + +
    • (¸î³â Àü¿¡ Æ÷ÆõÈ) ¿À·¡µÈ CERN-3.0 ¼­¹ö¸¦ ´ëüÇÒ + "¾µ¸¸ÇÏ°í À¯´ÉÇÑ" ÈÄ°èÀÚ¸¦ ã±âÀ§ÇØ
    • + +
    • ÀÌ Ç÷¹Æû¿¡¼­ ¾ÆÆÄÄ¡ÀÇ prefork ÇÁ·Î¼¼½º ¹æ½ÄÀÌ CERNÀÇ + accept-fork-serve ¹æ½Ä º¸´Ù 5¹è ÀÌ»ó ¼º´ÉÀÌ ÁÁÀ½À» + º¸À̱âÀ§Çؼ­.
    • +
    + +

    ÀÌ ¹®¼­´Â Æ÷Æýà ¿©·¯ ¼³°è»ó °áÁ¤ÀÇ ÀÌÀ¯¸¦ ¼³¸íÇÑ´Ù.

    + +
    top
    +
    +

    ¼³°è ¸ñÇ¥

    + + + +

    EBCDIC Æ÷ÆÃÀÇ ¸ñÀûÁß Çϳª´Â »õ·Î¿î ¼­¹ö·Î ÀüȯÀ» À¯µµÇÏ°í + ½±°Ô ÀüȯÇÒ ¼ö ÀÖµµ·Ï °¡´ÉÇÑ (EBCDIC) CERN ¼­¹ö¿Í ȣȯ¼ºÀ» + À¯ÁöÇÏ´Â °ÍÀÌ´Ù. ±×·¡¼­ HTML ¹®¼­°¡ (ÀÌÀü CERN ¼­¹ö°¡ ÀνÄÇÏ´Â + À¯ÀÏÇÑ Çü½ÄÀÎ) ASCII¿Í (POSIX ÇÏÀ§½Ã½ºÅÛÀÇ ±âº» ¹®¼­ Çü½Ä. + ±×·¯¹Ç·Î grepÀ̳ª sed °°Àº POSIX + µµ±¸¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â Çö½ÇÀûÀÎ Çü½ÄÀÎ) EBCDIC Áß ¾î´À Çü½ÄÀÎÁö + ¼³Á¤ÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ÇöÀç ÇØ°áÃ¥Àº ¾ÆÆÄÄ¡ ¼­¹ö°¡ Áß°£¿¡¼­ + ¹®¼­¸¦ °¡·Îä¼­ ¹®¼­ÀÇ Çü½ÄÀ» ÆľÇÇÏ´Â "°¡»ó MIME Çü½Ä"ÀÌ´Ù + (¾Æ·¡ Âü°í). ´ÙÀ½ ¹öÀü¿¡¼­´Â º¯È¯ÇؾßÇÒ ¸ðµç ¹®¼­¿¡ + "ebcdic-handler"¸¦ Á¤ÀÇÇÏ´Â ¹æ¹ýÀ¸·Î ¹®Á¦¸¦ ÇØ°áÇÒ °ÍÀÌ´Ù.

    + +
    top
    +
    +

    ±â¼úÀû ÇØ°áÃ¥

    + + + +

    ¾ÆÆÄÄ¡°¡ BUFF ÀÚ·áÇü°ú ¸Þ½áµå¸¦ »ç¿ëÇÏ¿© ¸ðµç ÀÔÃâ·ÂÀ» + ÇϹǷΠ°¡Àå ½¬¿î ¹æ¹ýÀº BUFF ó¸® ÇÔ¼ö¿¡ º¯È¯±â´ÉÀ» Ãß°¡ÇÏ´Â + °ÍÀÌ´Ù. ¾ðÁ¦µçÁö º¯È¯ÇÒ ¼ö ÀÖ¾î¾ß Çϱ⶧¹®¿¡ BUFF °´Ã¼¸¦ + º¯È¯ÇØ¾ß ÇÏ´ÂÁö ¾Ë·ÁÁÖ´Â BUFF Ç¥½Ã¸¦ Ãß°¡Çß´Ù. ÀÌ Ç¥½Ã´Â + HTTP ÇÁ·ÎÅäÄÝÀÇ ¿©·¯ ´Ü°è¿¡¼­ º¯°æµÉ ¼ö ÀÖ´Ù:

    + +
      +
    • ¿äûÀ» ¹Þ±â Àü¿¡ º¯È¯ (¿äû°ú ¿äûÇì´õ°¡ + Ç×»ó ASCII Çü½ÄÀ̱⠶§¹®¿¡)
    • + +
    • ¿äû ³»¿ëÀ» ¹Þ¾ÒÀ»¶§ content type¿¡ µû¶ó + º¯È¯/º¯È¯¾ÈÇÔ (¿äû ³»¿ëÀÌ ASCII ¹®ÀÚ³ª + ¹ÙÀ̳ʸ® ÆÄÀÏÀÎ °æ¿ì º¯È¯ÇØ¾ß Çϱ⶧¹®¿¡)
    • + +
    • ÀÀ´äÇì´õ¸¦ º¸³»±â Àü¿¡ º¯È¯ (ÀÀ´äÇì´õ´Â + Ç×»ó ASCII Çü½ÄÀ̱⶧¹®¿¡)
    • + +
    • ÀÀ´ä ³»¿ëÀ» º¸³¾¶§ content type¿¡ µû¶ó + º¯È¯/º¯È¯¾ÈÇÔ (ÀÀ´ä ³»¿ëÀÌ ¹®ÀÚ ÆÄÀÏÀ̰ųª + ¹ÙÀ̳ʸ® ÆÄÀÏÀ̱⶧¹®¿¡)
    • +
    + +
    top
    +
    +

    Æ÷Æÿ¡ ´ëÇؼ­

    + + + +
      +
    1. +

      ¼Ò½ºÀÇ º¯È­´Â µÎ°¡Áö #ifdef·Î ±¸ºÐÇÒ + ¼ö ÀÖ´Ù:

      + +
      +
      #ifdef + CHARSET_EBCDIC
      + +
      +

      ¸ðµç EBCDIC±â¹Ý ÄÄÇ»ÅÍ¿¡ ÇÊ¿äÇÑ ÄÚµå. ¹®ÀÚº¯È¯, + µÎ ¹®ÀÚÁýÇÕ°£ÀÇ ¿¬¼ÓµÈ ¹®ÀÚ°ª Â÷ÀÌ, ¾î¶² HTTP ÇÁ·ÎÅäÄÝ + ºÎºÐÀÌ º¯È¯µÇ¾ß ÇÏ´ÂÁö¸¦ ¾Ë·ÁÁִ ǥ½Ã µî.

      +
      + +
      #ifdef _OSD_POSIX
      + +
      +

      SIEMENS BS2000/OSD ¸ÞÀÎÇ÷¹ÀÓ Ç÷¹Æû¿¡¸¸ ÇÊ¿äÇÑ + ÄÚµå. BS2000/OSD Ç÷¹Æû¿¡¸¸ ÇÊ¿äÇÑ Çì´õÆÄÀÏ Â÷ÀÌ¿Í + ¼ÒÄÏ ±¸Çö ¹®Á¦¸¦ ´Ù·é´Ù.

      +
      +
      +
    2. + +
    3. +

      ¼ÒÄÏ ¼öÁØ¿¡¼­ ASCII¿Í EBCDIC°£ º¯È­´Â (BS2000 POSIX¿¡´Â + ÀÌ ±â´ÉÀ» Áö¿øÇÏ´Â ¼ÒÄÏ ¿É¼ÇÀÌ ÀÖ´Ù) HTTP ÇÁ·ÎÅäÄÝ ¼öÁØ¿¡¼­ + Àü¼ÛµÇ´Â ÀÚ·á¿¡ ÇÁ·ÎÅäÄÝ°ü·Ã ¹®ÀÚ¿­°ú ÇÁ·ÎÅäÄÝ°ú ¹«°üÇÑ + ÀϹÝÆÄÀÏÀÌ ¼¯¿©Àֱ⶧¹®¿¡ ÀǵµÀûÀ¸·Î »ç¿ëÇÏÁö + ¾Ê¾Ò´Ù. HTTP ÇÁ·ÎÅäÄÝ ¹®ÀÚ¿­Àº (GET + ¿äû, Header: ÁÙ, ±âŸ Á¤º¸ µî.) Ç×»ó ASCII + Çü½ÄÀÌ°í, ÆÄÀÏÀü¼Û ºÎºÐÀº (Áï, GIF ±×¸², CGI + Ãâ·Â µî.) ¼­¹ö°¡ Ç×»ó "º¯È¯ÇÏÁö¾Ê°í ±×³É" º¸³»¾ß + ÇÑ´Ù. ¼­¹ö ÄÚµå´Â "ÇÁ·ÎÅäÄÝ ¹®ÀÚ¿­"°ú "ÀÏ¹Ý ÀÚ·á"¸¦, + ¹®ÀÚ¿­¿¡´Â bgets()³ª rvputs(), + ¹ÙÀ̳ʸ® ÀÚ·á¿¡´Â bgets()³ª + rvputs() ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ±¸º°ÇÑ´Ù. ±×·¯¹Ç·Î + ¹«Á¶°Ç ¸ðµç °ÍÀ» º¯È¯ÇÏ´Â °ÍÀº ÀûÀýÇÏÁö ¾Ê´Ù.

      + +

      (¹°·Ð ¹®ÀÚÆÄÀÏÀÇ °æ¿ì EBCDIC ¹®¼­¸¦ Ç×»ó ASCII·Î + ¼­ºñ½ºÇϵµ·Ï ÁغñÇØ¾ß ÇÑ´Ù)

      +
    4. + +
    5. +

      ±×·¡¼­ Æ÷Æÿ¡´Â (ÄÄÆÄÀÏ·¯°¡ EBCDIC ¹®ÀÚ¿­·Î º¯È¯ÇÑ) + ¼­¹ö ³»ºÎ ¹®ÀÚ¿­°ú ¼­¹ö°¡ »ý¼ºÇÑ ¹®¼­¸¦ ±âº» ÇÁ·ÎÅäÄÝ + ¼öÁØ¿¡¼­ º¯È¯ÇÏ´Â ±â´ÉÀÌ ÀÖ´Ù. ¼­¹ö Äڵ忡 »êÀçµÈ ASCII + escape¹®ÀÚ \012¿Í \015´Â ¿¹¿Ü´Ù: + À̵éÀÌ ÀÌ¹Ì ASCII \n°ú \rÀÇ + ¹ÙÀ̳ʸ® °ªÀ̱⶧¹®¿¡ ASCII·Î µÎ¹ø º¯È¯ÇÏ¸é ¾ÈµÈ´Ù. + ÀÌ ¿¹¿Ü´Â ¼­¹ö°¡ »ý¼ºÇÑ ¹®ÀÚ¿­¿¡¸¸ Àû¿ëµÈ´Ù; ¿ÜºÎ + EBCDIC ¹®¼­´Â ASCII Áٹٲ޹®ÀÚ¸¦ Æ÷ÇÔÇÏ¸é ¾ÈµÈ´Ù.

      +
    6. + +
    7. +

      BUFF °ü¸®ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» »ìÆ캻 ÈÄ ³ª´Â ¸ðµç + puts/write/get/gets°¡ °ÅÄ¡°ÔµÇ´Â "ebcdic/ascii º¯È¯ + °èÃþ"À» Ãß°¡ÇÏ°í, µ¿ÀûÀ¸·Î º¯È¯À¯¹«¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Â + º¯È¯ Ç¥½Ã¸¦ Ãß°¡Çß´Ù. ¹®¼­°¡ ¿øº»(ÆÄÀÏÀ̳ª CGI Ãâ·Â)¿¡¼­ + ´ë»ó(¿äûÇÑ Å¬¶óÀ̾ðÆ®)À¸·Î À̵¿ÇÒ¶§ Ç×»ó ÀÌ °èÃþÀ» + µÎ¹ø Áö³­´Ù: ÆÄÀÏ -> ¾ÆÆÄÄ¡, ¾ÆÆÄÄ¡ + -> Ŭ¶óÀ̾ðÆ®.

      + +

      ¼­¹ö´Â ÀÌÁ¦ EBCDIC Çü½ÄÀ¸·Î µÈ CGI ½ºÅ©¸³Æ® Ãâ·ÂÀÇ + Çì´õÁÙÀ» Àаí, ³ª¸ÓÁö ½ºÅ©¸³Æ® Ãâ·ÂÀÌ ASCIIÀÓÀ» ¾Ë¾Æ³¾ + ¼ö ÀÖ´Ù (WWW ¹æ¹®ÀÚ¼ö¸¦ ¼¼´Â ÇÁ·Î±×·¥°ú °°Àº °æ¿ì: ¹®¼­ + ³»¿ëÀº GIF ±×¸²ÀÌ´Ù). ±âº» EBCDIC Çü½ÄÀ¸·Î ¸ðµç Çì´õ¸¦ + ó¸®ÇÑ´Ù; ±×·± ´ÙÀ½ ¼­ºñ½ºÇÒ ¹®¼­ÀÇ type¿¡ µû¶ó ¼­¹ö´Â + ¹®¼­ ³»¿ëÀÌ ÀÌ¹Ì ASCIIÀÎÁö ȤÀº EBCDIC¿¡¼­ º¯È¯À» ÇØ¾ß + ÇÏ´ÂÁö °áÁ¤ÇÑ´Ù.

      +
    8. + +
    9. +

      (MIME typeÀÌ text/plain, text/html µî) ³»¿ëÀÌ + ÀÏ¹Ý ¹®ÀÚÀÎ ¹®¼­¸¦ ¾Ï¹¬ÀûÀ¸·Î ASCII·Î º¯È¯Çϰųª, (»ç¿ëÀÚ¿¡°Ô + ºü¸£°Ô ¼­ºñ½ºÇϱâÀ§ÇØ ¹Ì¸® ¹®¼­¸¦ ASCII Çü½ÄÀ¸·Î ÀúÀåÇÏ¿´°Å³ª + NFS·Î ¸¶¿îÆ®ÇÑ µð·ºÅ丮¿¡ ÆÄÀÏÀÌ ÀÖ´Â °æ¿ì) º¯È¯¾øÀÌ + ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

      + +

      ¿¹:

      + +

      À̸§ÀÌ .ahtml·Î ³¡³ª´Â ÆÄÀÏÀ» ¾Ï¹¬ÀûÀÎ + º¯È¯¾øÀÌ ASCII text/html ¹®¼­·Î (±×¸®°í + .ascii È®ÀåÀÚ´Â ASCII + text/plainÀ¸·Î) ¼­ºñ½ºÇÏ·Á¸é ´ÙÀ½ Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù:

      + +

      + AddType text/x-ascii-html .ahtml
      + AddType text/x-ascii-plain .ascii +

      + +

      ¶Ç, text/foo ½ÄÀÇ MIME typeÀ» + AddType "text/x-ascii-foo" + ¼³Á¤ÇÏ¿© "ÀÏ¹Ý ASCII"·Î ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

      +
    10. + +
    11. +

      ³»¿ëÀÌ ÀÏ¹Ý ¹®ÀÚ°¡ ¾Æ´Ñ ¹®¼­´Â º¯È¯¾øÀÌ Ç×»ó "¹ÙÀ̳ʸ®"·Î + ¼­ºñ½ºÇÑ´Ù. ¿¹¸¦ µé¾î, GIF/ZIP/AU ÆÄÀÏÇü½Ä¿¡ + °¡Àå ÀûÇÕÇÑ ¼±ÅÃÀÌ´Ù. ¹°·Ð »ç¿ëÀÚ´Â "rcp -b" + ¹ÙÀ̳ʸ® ¿É¼ÇÀ» »ç¿ëÇÏ¿© ÆÄÀÏÀ» ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®·Î + º¹»çÇß¾î¾ß ÇÑ´Ù.

      +
    12. + +
    13. +

      ¼­¹öÆÄ½Ì ÆÄÀÏÀº Ç×»ó ÄÄÇ»ÅÍ°¡ »ç¿ëÇÏ´Â ±âº» Çü½ÄÀ¸·Î + (Áï, EBCDIC) ÀúÀåµÇ¾ú´Ù°í °¡Á¤ÇÏ°í, ó¸®ÈÄ¿¡ + º¯È¯ÇÑ´Ù.

      +
    14. + +
    15. +

      CGI Ãâ·ÂÀÇ °æ¿ì CGI ½ºÅ©¸³Æ®°¡ º¯È¯ÀÌ ÇÊ¿äÇÑÁö °áÁ¤ÇÑ´Ù: + ÀûÀýÇÑ Content-TypeÀ» ¼³Á¤ÇÏ¿©, ¹®ÀÚÆÄÀÏÀº º¯È¯ÇÏ°í, + GIF Ãâ·ÂÀº º¯È¯¾øÀÌ º¸³¾ ¼ö ÀÖ´Ù. ¿ì¸®°¡ Æ÷ÆÃÇÑ wwwcount + ÇÁ·Î±×·¥ÀÌ ÈÄÀÚÀÇ °æ¿ì´Ù.

      +
    16. + +
    + +
    top
    +
    +

    ¹®¼­ ÀúÀå¿¡ ´ëÇؼ­

    + + + +

    ¹ÙÀ̳ʸ® ÆÄÀÏ

    + + + +

    ¼­¹ö´Â Content-Type:ÀÌ text/·Î + ½ÃÀÛÇÏ´Â ¾Ê´Â ÆÄÀÏÀ» ¹ÙÀ̳ʸ® ÆÄÀÏ·Î °£ÁÖÇÏ¿© + ¾î¶² º¯È¯µµ ÇÏÁö ¾Ê´Â´Ù. ¹ÙÀ̳ʸ® ÆÄÀÏ¿¡´Â GIF ±×¸², gzipÀ¸·Î + ¾ÐÃàÇÑ ÆÄÀÏ µîÀÌ ÀÖ´Ù.

    + +

    ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®¿Í À¯´Ð½º ȤÀº À©µµ¿ìÁî PC°£¿¡ ¹ÙÀ̳ʸ® + ÆÄÀÏÀ» Àü¼ÛÇÒ ¶§´Â ftp "binary" (TYPE I) ¸í·É¾î³ª + ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®¿¡¼­ (À¯´Ð½º rcp´Â + -b ¿É¼ÇÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù) rcp -b + ¸í·É¾î¸¦ ¹Ýµå½Ã »ç¿ëÇ϶ó.

    + + + +

    ¹®ÀÚ ¹®¼­

    + + + +

    ±âº»ÀûÀ¸·Î ¼­¹ö´Â ¹®ÀÚÆÄÀÏÀÌ (Áï, + Content-Type:ÀÌ text/·Î ½ÃÀÛÇÏ´Â + ¸ðµç ÆÄÀÏ) È£½ºÆ®ÀÇ ±âº» ¹®ÀÚÁýÇÕÀÎ EBCDICÀ¸·Î ÀúÀåµÇ¾ú´Ù°í + °¡Á¤ÇÑ´Ù.

    + + + +

    Server Side Include ¹®¼­

    + + + +

    SSI ¹®¼­´Â ÇöÀç EBCDIC Çü½ÄÀ¸·Î¸¸ ÀúÀåÇØ¾ß ÇÑ´Ù. ó¸®Çϱâ + Àü¿¡ ASCII¸¦ º¯È¯ÇÏÁö ¾Ê´Â´Ù.

    + + + +
    top
    +
    +

    ¾ÆÆÄÄ¡ ¸ðµâÀÇ »óÅÂ

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¸ðµâ»óźñ°í
    core+ +
    mod_access+ +
    mod_actions+ +
    mod_alias+ +
    mod_asis+ +
    mod_auth+ +
    mod_auth_anon+ +
    mod_auth_dbm?ÀÚü libdb.a¸¦ »ç¿ëÇÏ¿©
    mod_autoindex+ +
    mod_cern_meta? +
    mod_cgi+ +
    mod_digest+ +
    mod_dir+ +
    mod_so-°øÀ¯¶óÀ̺귯¸®°¡ ¾øÀ½
    mod_env+ +
    mod_example-(½ÃÇè ´Ü°è)
    mod_expires+ +
    mod_headers+ +
    mod_imap+ +
    mod_include+ +
    mod_info+ +
    mod_log_agent+ +
    mod_log_config+ +
    mod_log_referer+ +
    mod_mime+ +
    mod_mime_magic?¾ÆÁ÷ Æ÷ÆþȵÊ
    mod_negotiation+ +
    mod_proxy+ +
    mod_rewrite+Å×½ºÆ®¾ÈµÊ
    mod_setenvif+ +
    mod_speling+ +
    mod_status+ +
    mod_unique_id+ +
    mod_userdir+ +
    mod_usertrack?Å×½ºÆ®¾ÈµÊ
    + +
    top
    +
    +

    Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀÇ »óÅÂ

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¸ðµâ»óźñ°í
    mod_jserv + -JAVA´Â Æ÷ÆÃÁßÀÌ´Ù.
    mod_php3+mod_php3´Â LDAP, GD, FreeType ¶óÀ̺귯¸®¿Í + ÇÔ²² Àß µ¿ÀÛÇÑ´Ù.
    mod_put?Å×½ºÆ®¾ÈµÊ
    mod_session-Å×½ºÆ®¾ÈµÊ
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/ebcdic.xml b/trunk/docs/manual/platform/ebcdic.xml new file mode 100644 index 0000000000..40aef0634b --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.xml @@ -0,0 +1,579 @@ + + + + + + + + + Platform Specific Notes + + The Apache EBCDIC Port + + + + Warning: This document + has not been updated to take into account changes made in + the 2.0 version of the Apache HTTP Server. Some of the + information may still be relevant, but please use it with care. + + + + +
    + + Overview of the Apache EBCDIC Port + +

    Version 1.3 of the Apache HTTP Server is the first version + which includes a port to a (non-ASCII) mainframe machine which + uses the EBCDIC character set as its native codeset.

    + +

    (It is the SIEMENS family of mainframes running the BS2000/OSD + operating system. This mainframe OS nowadays features a + SVR4-derived POSIX subsystem).

    + +

    The port was started initially to

    + +
      +
    • prove the feasibility of porting the Apache HTTP server to + this platform
    • + +
    • find a "worthy and capable" successor for the venerable + CERN-3.0 daemon + (which was ported a couple of years ago), and to
    • + +
    • prove that Apache's preforking process model can on this + platform easily outperform the accept-fork-serve model used + by CERN by a factor of 5 or more.
    • +
    + +

    This document serves as a rationale to describe some of the + design decisions of the port to this machine.

    + +
    + +
    + + Design Goals + +

    One objective of the EBCDIC port was to maintain enough + backwards compatibility with the (EBCDIC) CERN server to make + the transition to the new server attractive and easy. This + required the addition of a configurable method to define + whether a HTML document was stored in ASCII (the only format + accepted by the old server) or in EBCDIC (the native document + format in the POSIX subsystem, and therefore the only realistic + format in which the other POSIX tools like grep or + sed could operate on the documents). The current + solution to this is a "pseudo-MIME-format" which is intercepted + and interpreted by the Apache server (see below). Future versions + might solve the problem by defining an "ebcdic-handler" for all + documents which must be converted.

    + +
    + +
    + + Technical Solution + +

    Since all Apache input and output is based upon the BUFF + data type and its methods, the easiest solution was to add the + conversion to the BUFF handling routines. The conversion must + be settable at any time, so a BUFF flag was added which defines + whether a BUFF object has currently enabled conversion or not. + This flag is modified at several points in the HTTP + protocol:

    + +
      +
    • set before a request is received + (because the request and the request header lines are always + in ASCII format)
    • + +
    • set/unset when the request body is + received - depending on the content type of the request body + (because the request body may contain ASCII text or a binary + file)
    • + +
    • set before a reply header is sent + (because the response header lines are always in ASCII + format)
    • + +
    • set/unset when the response body is sent + - depending on the content type of the response body (because + the response body may contain text or a binary file)
    • +
    + +
    + +
    + + Porting Notes + +
      +
    1. +

      The relevant changes in the source are #ifdef'ed + into two categories:

      + +
      +
      #ifdef + CHARSET_EBCDIC
      + +
      +

      Code which is needed for any EBCDIC based machine. + This includes character translations, differences in + contiguity of the two character sets, flags which + indicate which part of the HTTP protocol has to be + converted and which part doesn't etc.

      +
      + +
      #ifdef _OSD_POSIX
      + +
      +

      Code which is needed for the SIEMENS BS2000/OSD + mainframe platform only. This deals with include file + differences and socket implementation topics which are + only required on the BS2000/OSD platform.

      +
      +
      +
    2. + +
    3. +

      The possibility to translate between ASCII and EBCDIC at + the socket level (on BS2000 POSIX, there is a socket option + which supports this) was intentionally not chosen, + because the byte stream at the HTTP protocol level consists + of a mixture of protocol related strings and non-protocol + related raw file data. HTTP protocol strings are always + encoded in ASCII (the GET request, any Header: lines, + the chunking information etc.) whereas the file transfer + parts (i.e., GIF images, CGI output etc.) + should usually be just "passed through" by the server. This + separation between "protocol string" and "raw data" is + reflected in the server code by functions like bgets() + or rvputs() for strings, and functions like + bwrite() for binary data. A global translation + of everything would therefore be inadequate.

      + +

      (In the case of text files of course, provisions must be + made so that EBCDIC documents are always served in + ASCII)

      +
    4. + +
    5. +

      This port therefore features a built-in protocol level + conversion for the server-internal strings (which the + compiler translated to EBCDIC strings) and thus for all + server-generated documents. The hard coded ASCII escapes + \012 and \015 which are ubiquitous + in the server code are an exception: they are already the binary + encoding of the ASCII \n and \r and + must not be converted to ASCII a second time. + This exception is only relevant for server-generated strings; + and external EBCDIC documents are not expected to + contain ASCII newline characters.

      +
    6. + +
    7. +

      By examining the call hierarchy for the BUFF management + routines, I added an "ebcdic/ascii conversion layer" which + would be crossed on every puts/write/get/gets, and a + conversion flag which allowed enabling/disabling the + conversions on-the-fly. Usually, a document crosses this + layer twice from its origin source (a file or CGI output) to + its destination (the requesting client): file -> + Apache, and Apache -> client.

      + +

      The server can now read the header lines of a CGI-script + output in EBCDIC format, and then find out that the remainder + of the script's output is in ASCII (like in the case of the + output of a WWW Counter program: the document body contains a + GIF image). All header processing is done in the native + EBCDIC format; the server then determines, based on the type + of document being served, whether the document body (except + for the chunking information, of course) is in ASCII already + or must be converted from EBCDIC.

      +
    8. + +
    9. +

      For Text documents (MIME types text/plain, text/html + etc.), an implicit translation to ASCII can be + used, or (if the users prefer to store some documents in + raw ASCII form for faster serving, or because the files + reside on a NFS-mounted directory tree) can be served + without conversion.

      + +

      Example:

      + +

      to serve files with the suffix .ahtml as a + raw ASCII text/html document without implicit + conversion (and suffix .ascii as ASCII + text/plain), use the directives:

      + + + AddType text/x-ascii-html .ahtml
      + AddType text/x-ascii-plain .ascii +
      + +

      Similarly, any text/foo MIME type can be + served as "raw ASCII" by configuring a MIME type + "text/x-ascii-foo" for it using + AddType.

      +
    10. + +
    11. +

      Non-text documents are always served "binary" without + conversion. This seems to be the most sensible choice for, + .e.g., GIF/ZIP/AU file types. This of course + requires the user to copy them to the mainframe host using + the "rcp -b" binary switch.

      +
    12. + +
    13. +

      Server parsed files are always assumed to be in native + (i.e., EBCDIC) format as used on the machine, and + are converted after processing.

      +
    14. + +
    15. +

      For CGI output, the CGI script determines whether a + conversion is needed or not: by setting the appropriate + Content-Type, text files can be converted, or GIF output can + be passed through unmodified. An example for the latter case + is the wwwcount program which we ported as well.

      +
    16. + +
    + +
    + +
    + + Document Storage Notes + +
    + + Binary Files + +

    All files with a Content-Type: which does not + start with text/ are regarded as binary + files by the server and are not subject to any conversion. + Examples for binary files are GIF images, gzip-compressed files + and the like.

    + +

    When exchanging binary files between the mainframe host and + a Unix machine or Windows PC, be sure to use the ftp "binary" + (TYPE I) command, or use the + rcp -b command from the mainframe host (the + -b switch is not supported in unix + rcp's).

    + +
    + +
    + + Text Documents + +

    The default assumption of the server is that Text Files + (i.e., all files whose Content-Type: + starts with text/) are stored in the native + character set of the host, EBCDIC.

    + +
    + +
    + + Server Side Included Documents + +

    SSI documents must currently be stored in EBCDIC only. + No provision is made to convert it from ASCII before + processing.

    + +
    + +
    + +
    + + Apache Modules' Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ModuleStatusNotes
    core+
    mod_access+
    mod_actions+
    mod_alias+
    mod_asis+
    mod_auth+
    mod_auth_anon+
    mod_auth_dbm?with own libdb.a
    mod_autoindex+
    mod_cern_meta?
    mod_cgi+
    mod_digest+
    mod_dir+
    mod_so-no shared libs
    mod_env+
    mod_example-(test bed only)
    mod_expires+
    mod_headers+
    mod_imagemap+
    mod_include+
    mod_info+
    mod_log_agent+
    mod_log_config+
    mod_log_referer+
    mod_mime+
    mod_mime_magic?not ported yet
    mod_negotiation+
    mod_proxy+
    mod_rewrite+untested
    mod_setenvif+
    mod_speling+
    mod_status+
    mod_unique_id+
    mod_userdir+
    mod_usertrack?untested
    + +
    + +
    + + Third Party Modules' Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ModuleStatusNotes
    mod_jserv + -JAVA still being ported.
    mod_php3+mod_php3 runs fine, with LDAP and GD + and FreeType libraries.
    mod_put?untested
    mod_session-untested
    + +
    + +
    diff --git a/trunk/docs/manual/platform/ebcdic.xml.ko b/trunk/docs/manual/platform/ebcdic.xml.ko new file mode 100644 index 0000000000..076b89394c --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.xml.ko @@ -0,0 +1,552 @@ + + + + + + + + + Platform Specific Notes + + ¾ÆÆÄÄ¡ EBCDIC Æ÷Æà + + + + ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ + º¯°æµÈ ³»¿ëÀ» ´ã°íÀÖÁö ¾Ê´Ù. ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, + ÁÖÀÇÇؼ­ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + + + + +
    + + ¾ÆÆÄÄ¡ EBCDIC Æ÷Æà °³¿ä + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â 1.3 ¹öÀü¶§ óÀ½À¸·Î EBCDIC ¹®ÀÚÁýÇÕÀ» + ±âº» ¹®ÀÚÁýÇÕÀ¸·Î »ç¿ëÇÏ´Â (ºñ-ASCII) ¸ÞÀÎÇ÷¹ÀÓ ÄÄÇ»ÅÍ·Î + Æ÷ÆõǾú´Ù.

    + +

    (BS2000/OSD + ¿î¿µÃ¼Á¦¸¦ »ç¿ëÇÏ´Â SIEMENS °è¿­ ¸ÞÀÎÇ÷¹ÀÓÀ» ¸»ÇÑ´Ù. + ÀÌ ¸ÞÀÎÇ÷¹ÀÓ ¿î¿µÃ¼Á¦¿¡´Â ÇöÀç SVR4°è¿­ÀÇ POSIX ÇÏÀ§½Ã½ºÅÛÀÌ + ÀÖ´Ù).

    + +

    Æ÷ÆÃÀº óÀ½¿¡ ´ÙÀ½°ú °°Àº ¸ñÀû¿¡¼­ ½ÃÀ۵Ǿú´Ù

    + +
      +
    • ÀÌ Ç÷¹ÆûÀ¸·Îµµ ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ Æ÷ÆÃÇÒ ¼ö ÀÖ´Ù´Â °¡´É¼ºÀ» º¸À̱âÀ§Çؼ­
    • + +
    • (¸î³â Àü¿¡ Æ÷ÆõÈ) ¿À·¡µÈ CERN-3.0 ¼­¹ö¸¦ ´ëüÇÒ + "¾µ¸¸ÇÏ°í À¯´ÉÇÑ" ÈÄ°èÀÚ¸¦ ã±âÀ§ÇØ
    • + +
    • ÀÌ Ç÷¹Æû¿¡¼­ ¾ÆÆÄÄ¡ÀÇ prefork ÇÁ·Î¼¼½º ¹æ½ÄÀÌ CERNÀÇ + accept-fork-serve ¹æ½Ä º¸´Ù 5¹è ÀÌ»ó ¼º´ÉÀÌ ÁÁÀ½À» + º¸À̱âÀ§Çؼ­.
    • +
    + +

    ÀÌ ¹®¼­´Â Æ÷Æýà ¿©·¯ ¼³°è»ó °áÁ¤ÀÇ ÀÌÀ¯¸¦ ¼³¸íÇÑ´Ù.

    + +
    + +
    + + ¼³°è ¸ñÇ¥ + +

    EBCDIC Æ÷ÆÃÀÇ ¸ñÀûÁß Çϳª´Â »õ·Î¿î ¼­¹ö·Î ÀüȯÀ» À¯µµÇÏ°í + ½±°Ô ÀüȯÇÒ ¼ö ÀÖµµ·Ï °¡´ÉÇÑ (EBCDIC) CERN ¼­¹ö¿Í ȣȯ¼ºÀ» + À¯ÁöÇÏ´Â °ÍÀÌ´Ù. ±×·¡¼­ HTML ¹®¼­°¡ (ÀÌÀü CERN ¼­¹ö°¡ ÀνÄÇÏ´Â + À¯ÀÏÇÑ Çü½ÄÀÎ) ASCII¿Í (POSIX ÇÏÀ§½Ã½ºÅÛÀÇ ±âº» ¹®¼­ Çü½Ä. + ±×·¯¹Ç·Î grepÀ̳ª sed °°Àº POSIX + µµ±¸¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â Çö½ÇÀûÀÎ Çü½ÄÀÎ) EBCDIC Áß ¾î´À Çü½ÄÀÎÁö + ¼³Á¤ÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ÇöÀç ÇØ°áÃ¥Àº ¾ÆÆÄÄ¡ ¼­¹ö°¡ Áß°£¿¡¼­ + ¹®¼­¸¦ °¡·Îä¼­ ¹®¼­ÀÇ Çü½ÄÀ» ÆľÇÇÏ´Â "°¡»ó MIME Çü½Ä"ÀÌ´Ù + (¾Æ·¡ Âü°í). ´ÙÀ½ ¹öÀü¿¡¼­´Â º¯È¯ÇؾßÇÒ ¸ðµç ¹®¼­¿¡ + "ebcdic-handler"¸¦ Á¤ÀÇÇÏ´Â ¹æ¹ýÀ¸·Î ¹®Á¦¸¦ ÇØ°áÇÒ °ÍÀÌ´Ù.

    + +
    + +
    + + ±â¼úÀû ÇØ°áÃ¥ + +

    ¾ÆÆÄÄ¡°¡ BUFF ÀÚ·áÇü°ú ¸Þ½áµå¸¦ »ç¿ëÇÏ¿© ¸ðµç ÀÔÃâ·ÂÀ» + ÇϹǷΠ°¡Àå ½¬¿î ¹æ¹ýÀº BUFF ó¸® ÇÔ¼ö¿¡ º¯È¯±â´ÉÀ» Ãß°¡ÇÏ´Â + °ÍÀÌ´Ù. ¾ðÁ¦µçÁö º¯È¯ÇÒ ¼ö ÀÖ¾î¾ß Çϱ⶧¹®¿¡ BUFF °´Ã¼¸¦ + º¯È¯ÇØ¾ß ÇÏ´ÂÁö ¾Ë·ÁÁÖ´Â BUFF Ç¥½Ã¸¦ Ãß°¡Çß´Ù. ÀÌ Ç¥½Ã´Â + HTTP ÇÁ·ÎÅäÄÝÀÇ ¿©·¯ ´Ü°è¿¡¼­ º¯°æµÉ ¼ö ÀÖ´Ù:

    + +
      +
    • ¿äûÀ» ¹Þ±â Àü¿¡ º¯È¯ (¿äû°ú ¿äûÇì´õ°¡ + Ç×»ó ASCII Çü½ÄÀ̱⠶§¹®¿¡)
    • + +
    • ¿äû ³»¿ëÀ» ¹Þ¾ÒÀ»¶§ content type¿¡ µû¶ó + º¯È¯/º¯È¯¾ÈÇÔ (¿äû ³»¿ëÀÌ ASCII ¹®ÀÚ³ª + ¹ÙÀ̳ʸ® ÆÄÀÏÀÎ °æ¿ì º¯È¯ÇØ¾ß Çϱ⶧¹®¿¡)
    • + +
    • ÀÀ´äÇì´õ¸¦ º¸³»±â Àü¿¡ º¯È¯ (ÀÀ´äÇì´õ´Â + Ç×»ó ASCII Çü½ÄÀ̱⶧¹®¿¡)
    • + +
    • ÀÀ´ä ³»¿ëÀ» º¸³¾¶§ content type¿¡ µû¶ó + º¯È¯/º¯È¯¾ÈÇÔ (ÀÀ´ä ³»¿ëÀÌ ¹®ÀÚ ÆÄÀÏÀ̰ųª + ¹ÙÀ̳ʸ® ÆÄÀÏÀ̱⶧¹®¿¡)
    • +
    + +
    + +
    + + Æ÷Æÿ¡ ´ëÇؼ­ + +
      +
    1. +

      ¼Ò½ºÀÇ º¯È­´Â µÎ°¡Áö #ifdef·Î ±¸ºÐÇÒ + ¼ö ÀÖ´Ù:

      + +
      +
      #ifdef + CHARSET_EBCDIC
      + +
      +

      ¸ðµç EBCDIC±â¹Ý ÄÄÇ»ÅÍ¿¡ ÇÊ¿äÇÑ ÄÚµå. ¹®ÀÚº¯È¯, + µÎ ¹®ÀÚÁýÇÕ°£ÀÇ ¿¬¼ÓµÈ ¹®ÀÚ°ª Â÷ÀÌ, ¾î¶² HTTP ÇÁ·ÎÅäÄÝ + ºÎºÐÀÌ º¯È¯µÇ¾ß ÇÏ´ÂÁö¸¦ ¾Ë·ÁÁִ ǥ½Ã µî.

      +
      + +
      #ifdef _OSD_POSIX
      + +
      +

      SIEMENS BS2000/OSD ¸ÞÀÎÇ÷¹ÀÓ Ç÷¹Æû¿¡¸¸ ÇÊ¿äÇÑ + ÄÚµå. BS2000/OSD Ç÷¹Æû¿¡¸¸ ÇÊ¿äÇÑ Çì´õÆÄÀÏ Â÷ÀÌ¿Í + ¼ÒÄÏ ±¸Çö ¹®Á¦¸¦ ´Ù·é´Ù.

      +
      +
      +
    2. + +
    3. +

      ¼ÒÄÏ ¼öÁØ¿¡¼­ ASCII¿Í EBCDIC°£ º¯È­´Â (BS2000 POSIX¿¡´Â + ÀÌ ±â´ÉÀ» Áö¿øÇÏ´Â ¼ÒÄÏ ¿É¼ÇÀÌ ÀÖ´Ù) HTTP ÇÁ·ÎÅäÄÝ ¼öÁØ¿¡¼­ + Àü¼ÛµÇ´Â ÀÚ·á¿¡ ÇÁ·ÎÅäÄÝ°ü·Ã ¹®ÀÚ¿­°ú ÇÁ·ÎÅäÄÝ°ú ¹«°üÇÑ + ÀϹÝÆÄÀÏÀÌ ¼¯¿©Àֱ⶧¹®¿¡ ÀǵµÀûÀ¸·Î »ç¿ëÇÏÁö + ¾Ê¾Ò´Ù. HTTP ÇÁ·ÎÅäÄÝ ¹®ÀÚ¿­Àº (GET + ¿äû, Header: ÁÙ, ±âŸ Á¤º¸ µî.) Ç×»ó ASCII + Çü½ÄÀÌ°í, ÆÄÀÏÀü¼Û ºÎºÐÀº (Áï, GIF ±×¸², CGI + Ãâ·Â µî.) ¼­¹ö°¡ Ç×»ó "º¯È¯ÇÏÁö¾Ê°í ±×³É" º¸³»¾ß + ÇÑ´Ù. ¼­¹ö ÄÚµå´Â "ÇÁ·ÎÅäÄÝ ¹®ÀÚ¿­"°ú "ÀÏ¹Ý ÀÚ·á"¸¦, + ¹®ÀÚ¿­¿¡´Â bgets()³ª rvputs(), + ¹ÙÀ̳ʸ® ÀÚ·á¿¡´Â bgets()³ª + rvputs() ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ±¸º°ÇÑ´Ù. ±×·¯¹Ç·Î + ¹«Á¶°Ç ¸ðµç °ÍÀ» º¯È¯ÇÏ´Â °ÍÀº ÀûÀýÇÏÁö ¾Ê´Ù.

      + +

      (¹°·Ð ¹®ÀÚÆÄÀÏÀÇ °æ¿ì EBCDIC ¹®¼­¸¦ Ç×»ó ASCII·Î + ¼­ºñ½ºÇϵµ·Ï ÁغñÇØ¾ß ÇÑ´Ù)

      +
    4. + +
    5. +

      ±×·¡¼­ Æ÷Æÿ¡´Â (ÄÄÆÄÀÏ·¯°¡ EBCDIC ¹®ÀÚ¿­·Î º¯È¯ÇÑ) + ¼­¹ö ³»ºÎ ¹®ÀÚ¿­°ú ¼­¹ö°¡ »ý¼ºÇÑ ¹®¼­¸¦ ±âº» ÇÁ·ÎÅäÄÝ + ¼öÁØ¿¡¼­ º¯È¯ÇÏ´Â ±â´ÉÀÌ ÀÖ´Ù. ¼­¹ö Äڵ忡 »êÀçµÈ ASCII + escape¹®ÀÚ \012¿Í \015´Â ¿¹¿Ü´Ù: + À̵éÀÌ ÀÌ¹Ì ASCII \n°ú \rÀÇ + ¹ÙÀ̳ʸ® °ªÀ̱⶧¹®¿¡ ASCII·Î µÎ¹ø º¯È¯ÇÏ¸é ¾ÈµÈ´Ù. + ÀÌ ¿¹¿Ü´Â ¼­¹ö°¡ »ý¼ºÇÑ ¹®ÀÚ¿­¿¡¸¸ Àû¿ëµÈ´Ù; ¿ÜºÎ + EBCDIC ¹®¼­´Â ASCII Áٹٲ޹®ÀÚ¸¦ Æ÷ÇÔÇÏ¸é ¾ÈµÈ´Ù.

      +
    6. + +
    7. +

      BUFF °ü¸®ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀ» »ìÆ캻 ÈÄ ³ª´Â ¸ðµç + puts/write/get/gets°¡ °ÅÄ¡°ÔµÇ´Â "ebcdic/ascii º¯È¯ + °èÃþ"À» Ãß°¡ÇÏ°í, µ¿ÀûÀ¸·Î º¯È¯À¯¹«¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Â + º¯È¯ Ç¥½Ã¸¦ Ãß°¡Çß´Ù. ¹®¼­°¡ ¿øº»(ÆÄÀÏÀ̳ª CGI Ãâ·Â)¿¡¼­ + ´ë»ó(¿äûÇÑ Å¬¶óÀ̾ðÆ®)À¸·Î À̵¿ÇÒ¶§ Ç×»ó ÀÌ °èÃþÀ» + µÎ¹ø Áö³­´Ù: ÆÄÀÏ -> ¾ÆÆÄÄ¡, ¾ÆÆÄÄ¡ + -> Ŭ¶óÀ̾ðÆ®.

      + +

      ¼­¹ö´Â ÀÌÁ¦ EBCDIC Çü½ÄÀ¸·Î µÈ CGI ½ºÅ©¸³Æ® Ãâ·ÂÀÇ + Çì´õÁÙÀ» Àаí, ³ª¸ÓÁö ½ºÅ©¸³Æ® Ãâ·ÂÀÌ ASCIIÀÓÀ» ¾Ë¾Æ³¾ + ¼ö ÀÖ´Ù (WWW ¹æ¹®ÀÚ¼ö¸¦ ¼¼´Â ÇÁ·Î±×·¥°ú °°Àº °æ¿ì: ¹®¼­ + ³»¿ëÀº GIF ±×¸²ÀÌ´Ù). ±âº» EBCDIC Çü½ÄÀ¸·Î ¸ðµç Çì´õ¸¦ + ó¸®ÇÑ´Ù; ±×·± ´ÙÀ½ ¼­ºñ½ºÇÒ ¹®¼­ÀÇ type¿¡ µû¶ó ¼­¹ö´Â + ¹®¼­ ³»¿ëÀÌ ÀÌ¹Ì ASCIIÀÎÁö ȤÀº EBCDIC¿¡¼­ º¯È¯À» ÇØ¾ß + ÇÏ´ÂÁö °áÁ¤ÇÑ´Ù.

      +
    8. + +
    9. +

      (MIME typeÀÌ text/plain, text/html µî) ³»¿ëÀÌ + ÀÏ¹Ý ¹®ÀÚÀÎ ¹®¼­¸¦ ¾Ï¹¬ÀûÀ¸·Î ASCII·Î º¯È¯Çϰųª, (»ç¿ëÀÚ¿¡°Ô + ºü¸£°Ô ¼­ºñ½ºÇϱâÀ§ÇØ ¹Ì¸® ¹®¼­¸¦ ASCII Çü½ÄÀ¸·Î ÀúÀåÇÏ¿´°Å³ª + NFS·Î ¸¶¿îÆ®ÇÑ µð·ºÅ丮¿¡ ÆÄÀÏÀÌ ÀÖ´Â °æ¿ì) º¯È¯¾øÀÌ + ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

      + +

      ¿¹:

      + +

      À̸§ÀÌ .ahtml·Î ³¡³ª´Â ÆÄÀÏÀ» ¾Ï¹¬ÀûÀÎ + º¯È¯¾øÀÌ ASCII text/html ¹®¼­·Î (±×¸®°í + .ascii È®ÀåÀÚ´Â ASCII + text/plainÀ¸·Î) ¼­ºñ½ºÇÏ·Á¸é ´ÙÀ½ Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù:

      + + + AddType text/x-ascii-html .ahtml
      + AddType text/x-ascii-plain .ascii +
      + +

      ¶Ç, text/foo ½ÄÀÇ MIME typeÀ» + AddType "text/x-ascii-foo" + ¼³Á¤ÇÏ¿© "ÀÏ¹Ý ASCII"·Î ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

      +
    10. + +
    11. +

      ³»¿ëÀÌ ÀÏ¹Ý ¹®ÀÚ°¡ ¾Æ´Ñ ¹®¼­´Â º¯È¯¾øÀÌ Ç×»ó "¹ÙÀ̳ʸ®"·Î + ¼­ºñ½ºÇÑ´Ù. ¿¹¸¦ µé¾î, GIF/ZIP/AU ÆÄÀÏÇü½Ä¿¡ + °¡Àå ÀûÇÕÇÑ ¼±ÅÃÀÌ´Ù. ¹°·Ð »ç¿ëÀÚ´Â "rcp -b" + ¹ÙÀ̳ʸ® ¿É¼ÇÀ» »ç¿ëÇÏ¿© ÆÄÀÏÀ» ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®·Î + º¹»çÇß¾î¾ß ÇÑ´Ù.

      +
    12. + +
    13. +

      ¼­¹öÆÄ½Ì ÆÄÀÏÀº Ç×»ó ÄÄÇ»ÅÍ°¡ »ç¿ëÇÏ´Â ±âº» Çü½ÄÀ¸·Î + (Áï, EBCDIC) ÀúÀåµÇ¾ú´Ù°í °¡Á¤ÇÏ°í, ó¸®ÈÄ¿¡ + º¯È¯ÇÑ´Ù.

      +
    14. + +
    15. +

      CGI Ãâ·ÂÀÇ °æ¿ì CGI ½ºÅ©¸³Æ®°¡ º¯È¯ÀÌ ÇÊ¿äÇÑÁö °áÁ¤ÇÑ´Ù: + ÀûÀýÇÑ Content-TypeÀ» ¼³Á¤ÇÏ¿©, ¹®ÀÚÆÄÀÏÀº º¯È¯ÇÏ°í, + GIF Ãâ·ÂÀº º¯È¯¾øÀÌ º¸³¾ ¼ö ÀÖ´Ù. ¿ì¸®°¡ Æ÷ÆÃÇÑ wwwcount + ÇÁ·Î±×·¥ÀÌ ÈÄÀÚÀÇ °æ¿ì´Ù.

      +
    16. + +
    + +
    + +
    + + ¹®¼­ ÀúÀå¿¡ ´ëÇؼ­ + +
    + + ¹ÙÀ̳ʸ® ÆÄÀÏ + +

    ¼­¹ö´Â Content-Type:ÀÌ text/·Î + ½ÃÀÛÇÏ´Â ¾Ê´Â ÆÄÀÏÀ» ¹ÙÀ̳ʸ® ÆÄÀÏ·Î °£ÁÖÇÏ¿© + ¾î¶² º¯È¯µµ ÇÏÁö ¾Ê´Â´Ù. ¹ÙÀ̳ʸ® ÆÄÀÏ¿¡´Â GIF ±×¸², gzipÀ¸·Î + ¾ÐÃàÇÑ ÆÄÀÏ µîÀÌ ÀÖ´Ù.

    + +

    ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®¿Í À¯´Ð½º ȤÀº À©µµ¿ìÁî PC°£¿¡ ¹ÙÀ̳ʸ® + ÆÄÀÏÀ» Àü¼ÛÇÒ ¶§´Â ftp "binary" (TYPE I) ¸í·É¾î³ª + ¸ÞÀÎÇ÷¹ÀÓ È£½ºÆ®¿¡¼­ (À¯´Ð½º rcp´Â + -b ¿É¼ÇÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù) rcp -b + ¸í·É¾î¸¦ ¹Ýµå½Ã »ç¿ëÇ϶ó.

    + +
    + +
    + + ¹®ÀÚ ¹®¼­ + +

    ±âº»ÀûÀ¸·Î ¼­¹ö´Â ¹®ÀÚÆÄÀÏÀÌ (Áï, + Content-Type:ÀÌ text/·Î ½ÃÀÛÇÏ´Â + ¸ðµç ÆÄÀÏ) È£½ºÆ®ÀÇ ±âº» ¹®ÀÚÁýÇÕÀÎ EBCDICÀ¸·Î ÀúÀåµÇ¾ú´Ù°í + °¡Á¤ÇÑ´Ù.

    + +
    + +
    + + Server Side Include ¹®¼­ + +

    SSI ¹®¼­´Â ÇöÀç EBCDIC Çü½ÄÀ¸·Î¸¸ ÀúÀåÇØ¾ß ÇÑ´Ù. ó¸®Çϱâ + Àü¿¡ ASCII¸¦ º¯È¯ÇÏÁö ¾Ê´Â´Ù.

    + +
    + +
    + +
    + + ¾ÆÆÄÄ¡ ¸ðµâÀÇ »óÅ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¸ðµâ»óźñ°í
    core+
    mod_access+
    mod_actions+
    mod_alias+
    mod_asis+
    mod_auth+
    mod_auth_anon+
    mod_auth_dbm?ÀÚü libdb.a¸¦ »ç¿ëÇÏ¿©
    mod_autoindex+
    mod_cern_meta?
    mod_cgi+
    mod_digest+
    mod_dir+
    mod_so-°øÀ¯¶óÀ̺귯¸®°¡ ¾øÀ½
    mod_env+
    mod_example-(½ÃÇè ´Ü°è)
    mod_expires+
    mod_headers+
    mod_imap+
    mod_include+
    mod_info+
    mod_log_agent+
    mod_log_config+
    mod_log_referer+
    mod_mime+
    mod_mime_magic?¾ÆÁ÷ Æ÷ÆþȵÊ
    mod_negotiation+
    mod_proxy+
    mod_rewrite+Å×½ºÆ®¾ÈµÊ
    mod_setenvif+
    mod_speling+
    mod_status+
    mod_unique_id+
    mod_userdir+
    mod_usertrack?Å×½ºÆ®¾ÈµÊ
    + +
    + +
    + + Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀÇ »óÅ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¸ðµâ»óźñ°í
    mod_jserv + -JAVA´Â Æ÷ÆÃÁßÀÌ´Ù.
    mod_php3+mod_php3´Â LDAP, GD, FreeType ¶óÀ̺귯¸®¿Í + ÇÔ²² Àß µ¿ÀÛÇÑ´Ù.
    mod_put?Å×½ºÆ®¾ÈµÊ
    mod_session-Å×½ºÆ®¾ÈµÊ
    + +
    + +
    diff --git a/trunk/docs/manual/platform/ebcdic.xml.meta b/trunk/docs/manual/platform/ebcdic.xml.meta new file mode 100644 index 0000000000..267e2f7a9f --- /dev/null +++ b/trunk/docs/manual/platform/ebcdic.xml.meta @@ -0,0 +1,12 @@ + + + + ebcdic + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/platform/index.html b/trunk/docs/manual/platform/index.html new file mode 100644 index 0000000000..5b7bb86fb2 --- /dev/null +++ b/trunk/docs/manual/platform/index.html @@ -0,0 +1,7 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/index.html.en b/trunk/docs/manual/platform/index.html.en new file mode 100644 index 0000000000..589c69dd87 --- /dev/null +++ b/trunk/docs/manual/platform/index.html.en @@ -0,0 +1,94 @@ + + + +Platform Specific Notes - Apache HTTP Server + + + + + +
    <-
    +

    Platform Specific Notes

    +
    +

    Available Languages:  en  | + ko 

    +
    +
    + +
    top
    +
    +

    Microsoft Windows

    + + + +
    +
    Using Apache
    +
    +

    This document explains how to install, configure and run Apache 2.0 + under Microsoft Windows.

    + +

    See: Using Apache with Microsoft Windows

    +
    +
    + +
    +
    Compiling Apache
    +
    +

    There are many important points before you begin compiling Apache. + This document explain them.

    + +

    See: Compiling Apache for Microsoft Windows

    +
    +
    + +
    top
    +
    +

    Other Platforms

    + + + +
    +
    Novell NetWare
    +
    +

    This document explains how to install, configure and run Apache 2.0 + under Novell NetWare 5.1 and above.

    + +

    See: Using Apache With Novell NetWare

    +
    +
    + +
    +
    EBCDIC
    +
    +

    Version 1.3 of the Apache HTTP Server is the first version which + includes a port to a (non-ASCII) mainframe machine which uses the + EBCDIC character set as its native codeset.

    + +
    Warning: This document + has not been updated to take into account changes made in + the 2.0 version of the Apache HTTP Server. Some of the + information may still be relevant, but please use it + with care.
    + +

    See: The Apache EBCDIC Port

    +
    +
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/index.html.ko.euc-kr b/trunk/docs/manual/platform/index.html.ko.euc-kr new file mode 100644 index 0000000000..28a7aaf367 --- /dev/null +++ b/trunk/docs/manual/platform/index.html.ko.euc-kr @@ -0,0 +1,94 @@ + + + +Ç÷¡Æûº° ¼³¸í - Apache HTTP Server + + + + + +
    <-
    +

    Ç÷¡Æûº° ¼³¸í

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    + +
    top
    +
    +

    Microsoft Windows

    + + + +
    +
    ¾ÆÆÄÄ¡ »ç¿ë¹ý
    +
    +

    ÀÌ ¹®¼­´Â Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, + ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Microsoft Windows¿¡¼­ + ¾ÆÆÄÄ¡ »ç¿ë¹ý

    +
    +
    + +
    +
    ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ
    +
    +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ÁÖÀÇÇÒ Á¡ÀÌ ¸¹´Ù. ÀÌ ¹®¼­´Â + ÀÌÁ¡À» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Microsoft Windows¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ

    +
    +
    + +
    top
    +
    +

    ±âŸ Ç÷¡Æû

    + + + +
    +
    Novell NetWare
    +
    +

    ÀÌ ¹®¼­´Â Novell NetWare 5.1 À̻󿡼­ ¾ÆÆÄÄ¡ 2.0À» + ¼³Ä¡, ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ + »ç¿ëÇϱâ

    +
    +
    + +
    +
    EBCDIC
    +
    +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â 1.3 ¹öÀü¶§ óÀ½À¸·Î EBCDIC ¹®ÀÚÁýÇÕÀ» + ±âº» ¹®ÀÚÁýÇÕÀ¸·Î »ç¿ëÇÏ´Â (ºñ-ASCII) ¸ÞÀÎÇ÷¹ÀÓ ÄÄÇ»ÅÍ·Î + Æ÷ÆõǾú´Ù.

    + +
    °æ°í: ÀÌ ¹®¼­´Â + ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» ´ã°íÀÖÁö ¾Ê´Ù. + ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.
    + +

    ¹®¼­: ¾ÆÆÄÄ¡ EBCDIC Æ÷ÆÃ

    +
    +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/index.xml b/trunk/docs/manual/platform/index.xml new file mode 100644 index 0000000000..c8cf35f3d4 --- /dev/null +++ b/trunk/docs/manual/platform/index.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + Platform Specific Notes + +
    + + Microsoft Windows + +
    +
    Using Apache
    +
    +

    This document explains how to install, configure and run Apache 2.0 + under Microsoft Windows.

    + +

    See: Using Apache with Microsoft Windows

    +
    +
    + +
    +
    Compiling Apache
    +
    +

    There are many important points before you begin compiling Apache. + This document explain them.

    + +

    See: Compiling Apache for Microsoft Windows

    +
    +
    + +
    + +
    + + Other Platforms + +
    +
    Novell NetWare
    +
    +

    This document explains how to install, configure and run Apache 2.0 + under Novell NetWare 5.1 and above.

    + +

    See: Using Apache With Novell NetWare

    +
    +
    + +
    +
    EBCDIC
    +
    +

    Version 1.3 of the Apache HTTP Server is the first version which + includes a port to a (non-ASCII) mainframe machine which uses the + EBCDIC character set as its native codeset.

    + + Warning: This document + has not been updated to take into account changes made in + the 2.0 version of the Apache HTTP Server. Some of the + information may still be relevant, but please use it + with care. + +

    See: The Apache EBCDIC Port

    +
    +
    + +
    + +
    diff --git a/trunk/docs/manual/platform/index.xml.ko b/trunk/docs/manual/platform/index.xml.ko new file mode 100644 index 0000000000..2661de1a8e --- /dev/null +++ b/trunk/docs/manual/platform/index.xml.ko @@ -0,0 +1,88 @@ + + + + + + + + + + + Ç÷¡Æûº° ¼³¸í + +
    + + Microsoft Windows + +
    +
    ¾ÆÆÄÄ¡ »ç¿ë¹ý
    +
    +

    ÀÌ ¹®¼­´Â Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, + ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Microsoft Windows¿¡¼­ + ¾ÆÆÄÄ¡ »ç¿ë¹ý

    +
    +
    + +
    +
    ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ
    +
    +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ÁÖÀÇÇÒ Á¡ÀÌ ¸¹´Ù. ÀÌ ¹®¼­´Â + ÀÌÁ¡À» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Microsoft Windows¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ

    +
    +
    + +
    + +
    + + ±âŸ Ç÷¡Æû + +
    +
    Novell NetWare
    +
    +

    ÀÌ ¹®¼­´Â Novell NetWare 5.1 À̻󿡼­ ¾ÆÆÄÄ¡ 2.0À» + ¼³Ä¡, ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    + +

    ¹®¼­: Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ + »ç¿ëÇϱâ

    +
    +
    + +
    +
    EBCDIC
    +
    +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â 1.3 ¹öÀü¶§ óÀ½À¸·Î EBCDIC ¹®ÀÚÁýÇÕÀ» + ±âº» ¹®ÀÚÁýÇÕÀ¸·Î »ç¿ëÇÏ´Â (ºñ-ASCII) ¸ÞÀÎÇ÷¹ÀÓ ÄÄÇ»ÅÍ·Î + Æ÷ÆõǾú´Ù.

    + + °æ°í: ÀÌ ¹®¼­´Â + ¾ÆÆÄÄ¡ À¥¼­¹ö 2.0 ¹öÀü¿¡¼­ º¯°æµÈ ³»¿ëÀ» ´ã°íÀÖÁö ¾Ê´Ù. + ¾ÆÁ÷µµ À¯È¿ÇÑ Á¤º¸°¡ ÀÖÁö¸¸, ÁÖÀÇÇؼ­ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + +

    ¹®¼­: ¾ÆÆÄÄ¡ EBCDIC Æ÷ÆÃ

    +
    +
    + +
    + +
    diff --git a/trunk/docs/manual/platform/index.xml.meta b/trunk/docs/manual/platform/index.xml.meta new file mode 100644 index 0000000000..3f98921b2b --- /dev/null +++ b/trunk/docs/manual/platform/index.xml.meta @@ -0,0 +1,12 @@ + + + + index + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/platform/netware.html b/trunk/docs/manual/platform/netware.html new file mode 100644 index 0000000000..cb2d4221d7 --- /dev/null +++ b/trunk/docs/manual/platform/netware.html @@ -0,0 +1,7 @@ +URI: netware.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: netware.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/netware.html.en b/trunk/docs/manual/platform/netware.html.en new file mode 100644 index 0000000000..57a519f6da --- /dev/null +++ b/trunk/docs/manual/platform/netware.html.en @@ -0,0 +1,655 @@ + + + +Using Apache With Novell NetWare - Apache HTTP Server + + + + + +
    <-
    +

    Using Apache With Novell NetWare

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    This document explains how to install, configure and run + Apache 2.0 under Novell NetWare 6.0 and above. If you find any bugs, + or wish to contribute in other ways, please use our + bug reporting + page.

    + +

    The bug reporting page and dev-httpd mailing list are not + provided to answer questions about configuration or running Apache. + Before you submit a bug report or request, first consult this document, the + Frequently Asked Questions page and the other + relevant documentation topics. If you still have a question or problem, + post it to the + novell.devsup.webserver newsgroup, where many Apache users are more than + willing to answer new and obscure questions about using Apache on NetWare.

    + +

    Most of this document assumes that you are installing Apache + from a binary distribution. If you want to compile Apache + yourself (possibly to help with development, or to track down + bugs), see the section on Compiling Apache for + NetWare below.

    + +
    + +
    top
    +
    +

    Requirements

    + + + +

    Apache 2.0 is designed to run on NetWare 6.0 service pack 3 + and above. If you are running a service pack less + than SP3, you must install the latest + NetWare Libraries + for C (LibC).

    + +

    NetWare service packs are available here.

    + +

    Apache 2.0 for NetWare can also be run in a NetWare 5.1 environment + as long as the latest service pack or the latest version + of the NetWare Libraries + for C (LibC) has been installed . WARNING: Apache 2.0 + for NetWare has not been targeted for or tested in this environment.

    + +
    top
    +
    +

    Downloading Apache for NetWare

    + + + +

    Information on the latest version of Apache can be found on + the Apache web server at http://www.apache.org/. This + will list the current release, any more recent alpha or + beta-test releases, together with details of mirror web and + anonymous ftp sites. Binary builds of the latest releases of + Apache 2.0 for NetWare can be downloaded from + here.

    + +
    top
    +
    +

    Installing Apache for NetWare

    + + + +

    There is no Apache install program for NetWare currently. If you + are building Apache 2.0 for NetWare from source, you will need to + copy the files over to the server manually.

    + +

    Follow these steps to install Apache on NetWare from the + binary download (assuming you will install to + sys:/apache2):

    + +
      +
    • Unzip the binary download file to the root of the SYS: + volume (may be installed to any volume)
    • + +
    • Edit the httpd.conf file setting ServerRoot and ServerName along with any file path values + to reflect your correct server settings
    • + +
    • Add SYS:/APACHE2 to the search path, for example: +

      SEARCH ADD SYS:\APACHE2

      +
    • + +
    + +

    Follow these steps to install Apache on NetWare manually + from your own build source (assuming you will install to + sys:/apache2):

    + +
      +
    • Create a directory called Apache2 on a + NetWare volume
    • + +
    • Copy APACHE2.NLM, APRLIB.NLM + to SYS:/APACHE2
    • + +
    • Create a directory under SYS:/APACHE2 + called BIN
    • + +
    • Copy HTDIGEST.NLM, HTPASSWD.NLM, + HTDBM.NLM, LOGRES.NLM, ROTLOGS.NLM + to SYS:/APACHE2/BIN
    • + +
    • Create a directory under SYS:/APACHE2 + called CONF
    • + +
    • Copy the HTTPD-STD.CONF file to the + SYS:/APACHE2/CONF directory and rename to + HTTPD.CONF
    • + +
    • Copy the MIME.TYPES, CHARSET.CONV and + MAGIC files to SYS:/APACHE2/CONF directory
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\ICONS + to SYS:/APACHE2/ICONS
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\MANUAL + to SYS:/APACHE2/MANUAL
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\ERROR + to SYS:/APACHE2/ERROR
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\DOCROOT + to SYS:/APACHE2/HTDOCS
    • + +
    • Create the directory SYS:/APACHE2/LOGS + on the server
    • + +
    • Create the directory SYS:/APACHE2/CGI-BIN + on the server
    • + +
    • Create the directory SYS:/APACHE2/MODULES + and copy all nlm modules into the modules directory
    • + +
    • Edit the HTTPD.CONF file searching for all + @@Value@@ markers and replacing them with the + appropriate setting
    • + +
    • Add SYS:/APACHE2 to the search path, for example: +

      SEARCH ADD SYS:\APACHE2

      +
    • +
    + +

    Apache may be installed to other volumes besides the default SYS volume.

    + +

    During the build process, adding the keyword "install" to the makefile command line + will automatically produce a complete distribution package under the subdirectory + DIST. Install Apache by simply copying the distribution that was produced + by the makfiles to the root of a NetWare volume (see: Compiling Apache for + NetWare below).

    + +
    top
    +
    +

    Running Apache for NetWare

    + + + +

    To start Apache just type apache at the + console. This will load apache in the OS address space. If you + prefer to load Apache in a protected address space you may + specify the address space with the load statement as follows:

    + +

    + load address space = apache2 apache2 +

    + +

    This will load Apache into an address space called apache2. + Running multiple instances of Apache concurrently on NetWare is + possible by loading each instance into its own protected + address space.

    + +

    After starting Apache, it will be listening to port 80 + (unless you changed the Listen + directive in the configuration files). + To connect to the server and access the default page, + launch a browser and enter the server's name or address. This + should respond with a welcome page, and a link to the Apache + manual. If nothing happens or you get an error, look in the + error_log file in the logs + directory.

    + +

    Once your basic installation is working, you should + configure it properly by editing the files in the + conf directory.

    + +

    To unload Apache running in the OS address space just type + the following at the console:

    + +

    + unload apache2 +

    + +

    or

    + +

    + apache2 shutdown +

    + +

    If apache is running in a protected address space specify the + address space in the unload statement:

    + +

    + unload address space = apache2 apache2 +

    + +

    When working with Apache it is important to know how it will + find the configuration files. You can specify a configuration + file on the command line in two ways:

    + +
      +
    • -f specifies a path to a particular + configuration file
    • +
    + +

    + apache2 -f "vol:/my server/conf/my.conf" +

    + +

    + apache -f test/test.conf +

    + +

    In these cases, the proper ServerRoot + should be set in the configuration file.

    + +

    If you don't specify a configuration file name with -f, + Apache will use the file name compiled into the server, usually + conf/httpd.conf. Invoking Apache with the -V + switch will display this value labeled as SERVER_CONFIG_FILE. + Apache will then determine its ServerRoot + by trying the following, in this order:

    + +
      +
    • A ServerRoot directive via a + -C switch.
    • + +
    • The -d switch on the command line.
    • + +
    • Current working directory
    • + +
    • The server root compiled into the server.
    • +
    + +

    The server root compiled into the server is usually sys:/apache2. + invoking apache with the -V switch will display this value labeled as + HTTPD_ROOT.

    + +

    Apache 2.0 for NetWare includes a set of command line directives that can + be used to modify or display information about the running instance of the + web server. These directives are only available while Apache is running. Each + of these directives must be preceded by the keyword APACHE2.

    + +
    +
    RESTART
    +
    Instructs Apache to terminate all running worker + threads as they become idle, reread the configuration file and restart each + worker thread based on the new configuration.
    + +
    VERSION
    +
    Displays version information about the currently + running instance of Apache.
    + +
    MODULES
    +
    Displays a list of loaded modules both built-in + and external.
    + +
    DIRECTIVES
    +
    Displays a list of all available directives.
    + +
    SETTINGS
    +
    Enables or disables the thread status display + on the console. When enabled, the state of each running threads is displayed + on the Apache console screen.
    + +
    SHUTDOWN
    +
    Terminates the running instance of the Apache + web server.
    + +
    HELP
    +
    Describes each of the runtime directives.
    +
    + +

    By default these directives are issued against the instance of Apache running + in the OS address space. To issue a directive against a specific instance running + in a protected address space, include the -p parameter along with the name of the + address space. For more information type "apache2 Help" on the command line.

    + +
    top
    +
    +

    Configuring Apache for NetWare

    + + + +

    Apache is configured by reading configuration files usually stored + in the conf directory. These are the same as files used + to configure the Unix version, but there are a few different directives for + Apache on NetWare. See the Apache + documentation for all the available directives.

    + +

    The main differences in Apache for NetWare are:

    + +
      +
    • +

      Because Apache for NetWare is multithreaded, it does not + use a separate process for each request, as Apache does on some Unix + implementations. Instead there are only threads running: a parent + thread, and multiple child or worker threads which handle the requests.

      + +

      Therefore the "process"-management directives are different:

      + +

      MaxRequestsPerChild - + Like the Unix directive, this controls how many requests + a worker thread will serve before exiting. The recommended default, + MaxRequestsPerChild 0, causes the thread to continue servicing + request indefinitely. It is recommended on NetWare, unless there is some + specific reason, that this directive always remain set to 0.

      + +

      StartThreads - + This directive tells the server how many threads it should start initially. + The recommended default is StartThreads 50.

      + +

      MinSpareThreads - + This directive instructs the server to spawn additional worker threads + if the number of idle threads ever falls below this value. The recommended + default is MinSpareThreads 10.

      + +

      MaxSpareThreads - + This directive instructs the server to begin terminating worker threads + if the number of idle threads ever exceeds this value. The recommended + default is MaxSpareThreads 100.

      + +

      MaxThreads - + This directive limits the total number of work threads to a maximum + value. The recommended default is ThreadsPerChild 250.

      + +

      ThreadStackSize - + This directive tells the server what size of stack to use + for the individual worker thread. The recommended default + is ThreadStackSize 65536.

      +
    • + +
    • +

      The directives that accept filenames as arguments must use + NetWare filenames instead of Unix names. However, because Apache + uses Unix-style names internally, forward slashes must be used + rather than backslashes. It is recommended that all rooted file paths + begin with a volume name. If omitted, Apache will assume the + SYS: volume which may not be correct.

      +
    • + +
    • +

      Apache for NetWare has the ability to load modules at + runtime, without recompiling the server. If Apache is + compiled normally, it will install a number of optional + modules in the \Apache2\modules directory. + To activate these, or other modules, the LoadModule directive + must be used. For example, to active the status module, use + the following:

      + +

      + LoadModule status_module modules/status.nlm +

      + +

      Information on creating loadable + modules is also available.

      +
    • +
    + +

    Additional NetWare specific directives:

    + + + +
      +
    • CGIMapExtension - + This directive maps a CGI file extension to a script interpreter.
    • +
    +
      +
    • SecureListen - + Enables SSL encryption for a specified port.
    • +
    +
      +
    • NWSSLTrustedCerts - + Adds trusted certificates that are used to create secure connections to proxied servers.
    • +
    +
      +
    • NWSSLUpgradeable - + Allow a connection created on the specified address/port to be upgraded to an SSL connection.
    • +
    + + + +
    top
    +
    +

    Compiling Apache for NetWare

    + + + +

    Compiling Apache requires MetroWerks CodeWarrior 6.x or higher. Once + Apache has been built, it can be installed to the root of any NetWare + volume. The default is the sys:/Apache2 directory.

    + +

    Before running the server you must fill out the conf + directory. Copy the file HTTPD-STD.CONF from the distribution + conf directory and rename it to HTTPD.CONF. + Edit the HTTPD.CONF file searching for all @@Value@@ + markers and replacing them with the appropriate setting. Copy over + the conf/magic and conf/mime.types files as well. + Alternatively, a complete distribution can be built by including the keyword + install when invoking the makefiles.

    + +

    Requirements:

    + + + +

    The following development tools are required to build + Apache 2.0 for NetWare:

    + + + + + +

    Building Apache using the NetWare makefiles:

    + + + +
      +
    • Set the environment variable NOVELLLIBC to the + location of the NetWare Libraries for C SDK, for example: +

      Set NOVELLLIBC=c:\novell\ndk\libc

      +
    • + +
    • Set the environment variable METROWERKS to the + location where you installed the Metrowerks CodeWarrior compiler, + for example: +

      Set METROWERKS=C:\Program Files\Metrowerks\CodeWarrior

      + If you installed to the default location C:\Program + Files\Metrowerks\CodeWarrior, you don't need to set this.
    • + +
    • Set the environment variable LDAPSDK to the + location where you installed the LDAP Libraries for C, for example: +

      Set LDAPSDK=c:\Novell\NDK\cldapsdk\NetWare\libc

      +
    • + +
    • Set the environment variable ZLIBSDK to the + location where you installed the source code for the ZLib Library, + for example: +

      Set ZLIBSDK=D:\NOVELL\zlib

      +
    • + +
    • Set the environment variable AP_WORK to the full path of + the httpd source code directory. +

      Set AP_WORK=D:\httpd-2.0.x

      +
    • + +
    • Set the environment variable APR_WORK to the full path of + the apr source code directory. Typically \httpd\srclib\apr + but the APR project can be outside of the httpd directory structure. +

      Set APR_WORK=D:\apr-1.x.x

      +
    • + +
    • Set the environment variable APU_WORK to the full path of + the apr-util source code directory. Typically \httpd\srclib\apr-util + but the APR-UTIL project can be outside of the httpd directory structure. +

      Set APU_WORK=D:\apr-util-1.x.x

      +
    • + +
    • Make sure that the path to the AWK utility and the GNU make utility + (gmake.exe) have been included in the system's + PATH environment variable.
    • + +
    • Download the source code and unzip to an appropriate directory on + your workstation.
    • + +
    • Change directory to \httpd-2.0 and build the prebuild utilities + by running "gmake -f nwgnumakefile prebuild". This target will create + the directory \httpd-2.0\nwprebuild and copy each of the utilities + to this location that are necessary to complete the following build steps. +
    • + +
    • Copy the files \httpd-2.0\nwprebuild\GENCHARS.nlm and + \httpd-2.0\nwprebuild\DFTABLES.nlm to the SYS: volume of a + NetWare server and run them using the following commands: +

      + SYS:\genchars > sys:\test_char.h
      + SYS:\dftables sys:\chartables.c
      +

      +
    • + +
    • Copy the files test_char.h and chartables.c + to the directory \httpd-2.0\os\netware on the build machine.
    • + +
    • Change directory to \httpd-2.0 and build Apache by running + "gmake -f nwgnumakefile". You can create a distribution directory by + adding an install parameter to the command, for example: +

      gmake -f nwgnumakefile install

      +
    • +
    + + + +

    Additional make options

    + + + +
      +
    • gmake -f nwgnumakefile

      Builds release versions of all of the + binaries and copies them to a \release destination directory.

    • + +
    • gmake -f nwgnumakefile DEBUG=1

      Builds debug versions of all of the + binaries and copies them to a \debug destination directory.

    • + +
    • gmake -f nwgnumakefile install

      Creates a complete Apache + distribution with binaries, docs and additional support files in a + \dist\Apache2 directory.

    • + +
    • gmake -f nwgnumakefile prebuild

      Builds all of the prebuild utilities + and copies them to the \nwprebuild directory.

    • + +
    • gmake -f nwgnumakefile installdev

      Same as install but also creates a + \lib and \include directory in the destination directory + and copies headers and import files.

    • + +
    • gmake -f nwgnumakefile clean

      Cleans all object files and binaries + from the \release.o or \debug.o build areas depending on whether + DEBUG has been defined.

    • + +
    • gmake -f nwgnumakefile clobber_all

      Same as clean and also deletes + the distribution directory if it exists.

    • +
    + + + +

    Additional environment variable options

    + + + +
      +
    • To build all of the experimental modules, set the environment + variable EXPERIMENTAL: +

      Set EXPERIMENTAL=1

      +
    • + +
    • To build Apache using standard BSD style sockets rather than + Winsock, set the environment variable USE_STDSOCKETS: +

      Set USE_STDSOCKETS=1

      +
    • + +
    + + + +

    Building mod_ssl for the NetWare platform

    + + + +

    By default Apache for NetWare uses the built-in module + mod_nw_ssl to provide SSL services. This module + simply enables the native SSL services implemented in NetWare OS + to handle all encryption for a given port. Alternatively, mod_ssl + can also be used in the same manner as on other platforms.

    + +

    Before mod_ssl can be built for the NetWare platform, the OpenSSL + libraries must be provided. This can be done through the following + steps:

    + +
      +
    • Download the latest NetWare patch for OpenSSL from the + OpenSSL Contribution + page.
    • + +
    • Download the corresponding OpenSSL source code from the + OpenSSL Source + page.
    • + +
    • At the root of the OpenSSL source directory, apply the NetWare + patch using the "patch" utility, for example: +

      patch -p 1 -i netwarepatch-0.9.7g.diff

    • + +
    • Edit the file NetWare/set_env.bat and modify any + tools and utilities paths so that they correspond to your build + environment.
    • + +
    • From the root of the OpenSSL source directory, run the following + scripts: +

      + Netware/set_env netware-libc
      + Netware/build netware-libc +

    • + +
    • Before building Apache, set the environment variable + OSSLSDK to the full path to the root of the openssl + source code directory. +

      Set OSSLSDK=d:\openssl-0.9.7x

    • + +
    + + + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/netware.html.ko.euc-kr b/trunk/docs/manual/platform/netware.html.ko.euc-kr new file mode 100644 index 0000000000..373abd3b0e --- /dev/null +++ b/trunk/docs/manual/platform/netware.html.ko.euc-kr @@ -0,0 +1,581 @@ + + + +Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ëÇϱâ - Apache HTTP Server + + + + + +
    <-
    +

    Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ëÇϱâ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ÀÌ ¹®¼­´Â Novell NetWare 6.0 À̻󿡼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, + ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. ¹ö±×¸¦ ã¾Ò°Å³ª ´Ù¸¥ ¹æ¹ýÀ¸·Î + µ½°í½Í´Ù¸é, ¹ö±× + º¸°í ÆäÀÌÁö¸¦ ÀÌ¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    ¹ö±× º¸°í ÆäÀÌÁö³ª dev-httpd ¸ÞÀϸµ¸®½ºÆ®´Â ¾ÆÆÄÄ¡ ¼³Á¤°ú + ½ÇÇà¿¡ ´ëÇÑ Áú¹®À» ´äÇÏÁö ¾Ê´Â´Ù. ¹ö±×¸¦ º¸°íÇϱâ + Àü¿¡ ¸ÕÀú ÀÌ ¹®¼­¿Í ÀÚÁÖ ¹°¾îº¸´Â Áú¹® + (FAQ) ÆäÀÌÁö, ´Ù¸¥ °ü·Ã¹®¼­¸¦ »ìÆìºÁ¶ó. ±×·¡µµ ±Ã±ÝÇÑ + Á¡À̳ª ¹®Á¦°¡ ÀÖ´Ù¸é, NetWare¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¿¡ ´ëÇÑ ¾î·Æ°í + »õ·Î¿î Áú¹®À» ´äÇØÁÙ ¸¹Àº ¾ÆÆÄÄ¡ »ç¿ëÀÚ°¡ ÀÖ´Â + novell.devsup.webserver ´º½º±×·ì¿¡ ±ÛÀ» ¿Ã¸®±æ ¹Ù¶õ´Ù.

    + +

    ÀÌ ¹®¼­´Â ¹ÙÀ̳ʸ® ¹èÆ÷º»À¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡Çß´Ù°í °¡Á¤ÇÑ´Ù. + (¾Æ¸¶µµ °³¹ß¿¡ µµ¿òÀ» Áְųª ¹ö±×¸¦ ã±âÀ§ÇØ) Á÷Á¢ ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÏ·Á¸é ¾Æ·¡ NetWare¿¡¼­ ¾ÆÆÄÄ¡ + ÄÄÆÄÀÏÇϱâ ÀýÀ» Âü°íÇ϶ó.

    + +
    + +
    top
    +
    +

    ¿ä±¸Á¶°Ç

    + + + +

    ¾ÆÆÄÄ¡ 2.0Àº NetWare 6.0 service pack 3 À̻󿡼­ µ¿ÀÛÇϵµ·Ï + ¼³°èµÇ¾ú´Ù. SP3º¸´Ù ³·Àº service packÀ» »ç¿ëÇÑ´Ù¸é ÃֽŠ+ NetWare + Libraries for C (LibC)¸¦ ¼³Ä¡ÇØ¾ß ÇÑ´Ù.

    + +

    NetWare service packÀº ¿©±â¿¡ + ÀÖ´Ù.

    + +

    ÃֽŠservice packÀ̳ª ÃֽŠ¹öÀü NetWare + Libraries for C (LibC)¸¦ ¼³Ä¡Çß´Ù¸é NetWare 5.1 ȯ°æ¿¡¼­µµ + NetWare¿ë ¾ÆÆÄÄ¡ 2.0À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. °æ°í: + NetWare¿ë ¾ÆÆÄÄ¡ 2.0Àº ÀÌ È¯°æÀ» °í·ÁÇÏÁö ¾Ê¾Ò°í Å×½ºÆ®ÇÏÁö + ¾Ê¾Ò´Ù.

    + +
    top
    +
    +

    NetWare¿ë ¾ÆÆÄÄ¡ ´Ù¿î¹Þ±â

    + + + +

    ¾ÆÆÄÄ¡ ÃֽŠ¹öÀü¿¡ ´ëÇÑ Á¤º¸´Â http://www.apache.org/¿¡¼­ + (¾ÆÆÄÄ¡ À¥¼­¹ö) ãÀ» ¼ö ÀÖ´Ù. ¿©±â¿¡´Â ÇöÀç ¹öÀü°ú ÃÖ±Ù + ¾ËÆÄ/º£Å¸Å×½ºÆ® ¹öÀü, ¹Ì·¯ À¥»çÀÌÆ®¿Í ftp »çÀÌÆ® Á¤º¸°¡ + ÀÖ´Ù. NetWare¿ë ¾ÆÆÄÄ¡ 2.0ÀÇ ÃֽŠ¹ÙÀ̳ʸ® ¹èÆ÷º»Àº ¿©±â¿¡¼­ + ´Ù¿î¹ÞÀ» ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    NetWare¿ë ¾ÆÆÄÄ¡ ¼³Ä¡Çϱâ

    + + + +

    ÇöÀç NetWare¿ë ¾ÆÆÄÄ¡ ¼³Ä¡ÇÁ·Î±×·¥Àº ¾ø´Ù. NetWare¿ë + ¾ÆÆÄÄ¡ 2.0 ¼Ò½º¸¦ Á÷Á¢ ÄÄÆÄÀÏÇÑ´Ù¸é ÆÄÀÏÀ» ¼­¹ö·Î Á÷Á¢ + º¹»çÇØÁà¾ß ÇÑ´Ù.

    + +

    ¹ÙÀ̳ʸ®·Î ´Ù¿î¹ÞÀº NetWare¿ë ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ´Â °úÁ¤Àº + ´ÙÀ½°ú °°´Ù (sys:/apache2¿¡ ¼³Ä¡ÇÑ´Ù°í °¡Á¤ÇÑ´Ù):

    + +
      +
    • ¹ÙÀ̳ʸ®·Î ´Ù¿î¹ÞÀº ¾ÐÃàÆÄÀÏÀ» SYS: º¼·ý + ÃÖ»óÀ§ µð·ºÅ丮¿¡ Ǭ´Ù (´Ù¸¥ º¼·ý¿¡ ¼³Ä¡Çصµ µÈ´Ù)
    • + +
    • httpd.conf ÆÄÀÏÀ» ¼öÁ¤ÇÏ¿© ServerRoot¿Í ServerName°ú ÆÄÀÏ°æ·Î °ªÀ» ¼­¹ö¿¡ + ¾Ë¸Â°Ô ÁöÁ¤ÇÑ´Ù
    • + +
    • ¿¹¸¦ µé¾î

      SEARCH ADD SYS:\APACHE2

      ¿Í + °°ÀÌ °Ë»ö°æ·Î¿¡ SYS:/APACHE2¸¦ Ãß°¡ÇÑ´Ù +
    • + +
    + +

    Á÷Á¢ ¼Ò½º¸¦ ÄÄÆÄÀÏÇÑ °æ¿ì NetWare¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ´Â + ¹æ¹ýÀº ´ÙÀ½°ú °°´Ù (sys:/apache2¿¡ ¼³Ä¡ÇÑ´Ù°í + °¡Á¤ÇÑ´Ù):

    + +
      +
    • NetWare º¼·ý¿¡ Apache2¶ó´Â µð·ºÅ丮¸¦ + ¸¸µç´Ù
    • + +
    • APACHE2.NLM°ú APRLIB.NLMÀ» + SYS:/APACHE2¿¡ º¹»çÇÑ´Ù
    • + +
    • SYS:/APACHE2 ¾Æ·¡¿¡ BINÀ̶ó´Â + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • HTDIGEST.NLM, HTPASSWD.NLM, + HTDBM.NLM, LOGRES.NLM, + ROTLOGS.NLMÀ» SYS:/APACHE2/BIN¿¡ + º¹»çÇÑ´Ù
    • + +
    • SYS:/APACHE2 ¾Æ·¡¿¡ CONF¶ó´Â + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • HTTPD-STD.CONF ÆÄÀÏÀ» + SYS:/APACHE2/CONF¿¡ º¹»çÇÏ°í ÆÄÀϸíÀ» + HTTPD.CONF·Î º¯°æÇÑ´Ù
    • + +
    • MIME.TYPES, CHARSET.CONV, + MAGIC ÆÄÀÏÀ» SYS:/APACHE2/CONF + µð·ºÅ丮¿¡ º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\ICONS¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/ICONS·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\MANUAL¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/MANUAL·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\ERROR¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/ERROR·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\DICROOT¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/HTDOCS·Î º¹»çÇÑ´Ù
    • + +
    • ¼­¹ö¿¡ SYS:/APACHE2/LOGS µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • ¼­¹ö¿¡ SYS:/APACHE2/APACHE2/CGI-BINÀ̶õ + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • SYS:/APACHE2/MODULES µð·ºÅ丮¸¦ ¸¸µé°í + ¸ðµç nlm ¸ðµâÀ» modules µð·ºÅ丮·Î º¹»çÇÑ´Ù
    • + +
    • HTTPD.CONF ÆÄÀÏÀÇ ¸ðµç @@Value@@ + Ç¥½Ã¸¦ ÀûÀýÇÑ ¼³Á¤À¸·Î ´ëüÇÑ´Ù
    • + +
    • SEARCH ADD SYS:\APACHE2

      °°ÀÌ °Ë»ö°æ·Î¿¡ + SYS:/APACHE2¸¦ Ãß°¡ÇÑ´Ù +
    • +
    + +

    ±âº» SYS º¼·ýÀÌ ¾Æ´Ñ ´Ù¸¥ º¼·ý¿¡µµ ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    makefile ¸í·É¾î¿¡ "install" Å°¿öµå¸¦ »ç¿ëÇϸé ÄÄÆÄÀϽà + ÀÚµ¿À¸·Î DIST ÇÏÀ§µð·ºÅ丮¿¡ ¿ÏÀüÇÑ ¹èÆ÷º»À» + ¸¸µç´Ù. makefile·Î ¸¸µç ¹èÆ÷º»À» NetWare º¼·ý ÃÖ»óÀ§ µð·ºÅ丮·Î + º¹»çÇÏ¸é ¾ÆÆÄÄ¡°¡ ¼³Ä¡µÈ´Ù (¾Æ·¡ NetWare¿ë + ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ Âü°í).

    + +
    top
    +
    +

    NetWare¿ë ¾ÆÆÄÄ¡ ½ÇÇàÇϱâ

    + + + +

    ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ·Á¸é Äֿܼ¡¼­ apache¸¦ ÀÔ·ÂÇϸé + µÈ´Ù. ±×·¯¸é ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡ ¾ÆÆÄÄ¡¸¦ ÀоîµéÀδÙ. + º¸È£ÁÖ¼Ò¿µ¿ª¿¡ ¾ÆÆÄÄ¡¸¦ ÀоîµéÀÌ·Á¸é ´ÙÀ½°ú °°ÀÌ load ¸í·É¾î·Î + ÁÖ¼Ò¿µ¿ªÀ» ÁöÁ¤ÇÑ´Ù:

    + +

    + load address space = apache2 apache2 +

    + +

    ±×·¯¸é ¾ÆÆÄÄ¡¸¦ apache2¶ó´Â ÁÖ¼Ò¿µ¿ª¿¡ ÀоîµéÀδÙ. + NetWare´Â ¿©·¯ ¾ÆÆÄÄ¡¸¦ °¢°¢ ´Ù¸¥ º¸È£ÁÖ¼Ò¿µ¿ª¿¡ Àоîµé¿©¼­ + ¿©·¯ ¾ÆÆÄÄ¡¸¦ µ¿½Ã¿¡ ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇϸé (¼³Á¤ÆÄÀÏ¿¡¼­ Listen Áö½Ã¾î¸¦ ¼öÁ¤ÇÏÁö + ¾Ê´ÂÇÑ) Æ÷Æ® 80¹øÀ» ±â´Ù¸°´Ù. ºê¶ó¿ìÀú¸¦ ½ÃÀÛÇÏ¿© ¼­¹ö¸í + ȤÀº ¼­¹ö ÁÖ¼Ò¸¦ ÀÔ·ÂÇÏ¸é ¼­¹ö¿¡ Á¢¼ÓÇÏ¿© ±âº»ÆäÀÌÁö¿¡ + Á¢±ÙÇÑ´Ù. ¾ÆÆÄÄ¡ ¼³¸í¼­ ¸µÅ©°¡ Àִ ȯ¿µÆäÀÌÁö°¡ ³ª¿Í¾ß + ÇÑ´Ù. ¾Æ¹« Àϵµ ¾ø°Å³ª ¿À·ù°¡ ¹ß»ýÇϸé logs + µð·ºÅ丮¿¡ ÀÖ´Â error_log ÆÄÀÏÀ» »ìÆìºÁ¶ó.

    + +

    ±âº» ¼³Ä¡°¡ µ¿ÀÛÇϸé conf µð·ºÅ丮¿¡ ÀÖ´Â + ÆÄÀÏÀ» ÀûÀýÈ÷ ¼³Á¤ÇÑ´Ù.

    + +

    ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡¸¦ ³»¸±·Á¸é Äֿܼ¡ + ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù:

    + +

    + unload apache2 +

    + +

    ȤÀº

    + +

    + apache2 shutdown +

    + +

    º¸È£ÁÖ¼Ò¿µ¿ª¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇß´Ù¸é unload ¸í·É¾î¿¡ + ÁÖ¼Ò¿µ¿ªÀ» ÁöÁ¤ÇÑ´Ù:

    + +

    + unload address space = apache2 apache2 +

    + +

    ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏ À§Ä¡¸¦ ã´Â ¹æ¹ýÀ» ¾Ë¾ÆµÎ¾î¾ß ÇÑ´Ù. + ¸í·ÉÇà¿¡¼­ ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÏ´Â ¹æ¹ýÀº µÎ°¡Áö´Ù:

    + +
      +
    • -f´Â ƯÁ¤ ¼³Á¤ÆÄÀÏ °æ·Î¸¦ ÁöÁ¤ÇÑ´Ù
    • +
    + +

    + apache2 -f "vol:/my server/conf/my.conf" +

    + +

    + apache -f test/test.conf +

    + +

    ÀÌ °æ¿ì ¼³Á¤ÆÄÀÏÀº ¿Ã¹Ù¸¥ ServerRoot¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +

    -f·Î ¼³Á¤ÆÄÀϸíÀ» ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é, ¾ÆÆÄÄ¡´Â + ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ ÆÄÀϸíÀ» (º¸Åë conf/httpd.conf) + »ç¿ëÇÑ´Ù. -V ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé + SERVER_CONFIG_FILEÀ̶ó´Â Ç׸ñÀ» º¸¿©ÁØ´Ù. + ¾ÆÆÄÄ¡´Â ´ÙÀ½ ¼ø¼­´ë·Î ServerRoot¸¦ ã´Â´Ù:

    + +
      +
    • -C ¿É¼ÇÀÇ ServerRoot Áö½Ã¾î.
    • + +
    • ¸í·ÉÇàÀÇ -d ¿É¼Ç.
    • + +
    • ÇöÀç µð·ºÅ丮
    • + +
    • ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root.
    • +
    + +

    ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root´Â º¸Åë + sys:/apache2ÀÌ´Ù. -V ¿É¼ÇÀ¸·Î + ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé HTTPD_ROOT¶ó´Â Ç׸ñÀ» º¸¿©ÁØ´Ù.

    + +

    NetWare¿ë ¾ÆÆÄÄ¡ 2.0¿¡´Â ½ÇÇàÁßÀÎ À¥¼­¹ö¸¦ Á×À̰ųª Á¤º¸¸¦ + ¾Ë·ÁÁÖ´Â ¸í·ÉÇà Áö½Ã¾î°¡ ÀÖ´Ù. À̵é Áö½Ã¾î´Â ¾ÆÆÄÄ¡ µ¿ÀÛÁß¿¡¸¸ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î ¾Õ¿¡´Â APACHE2 Å°¿öµå¸¦ + ºÙ¿©¾ß ÇÑ´Ù.

    + +
    +
    RESTART
    +
    ¸ðµç ¾²·¹µå°¡ ½¬´Â »óÅÂÀ϶§ ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í, ¼³Á¤ÆÄÀÏÀ» + ´Ù½Ã ÀÐÀºÈÄ »õ·Î¿î ¼³Á¤¿¡ µû¶ó worker ¾²·¹µåµéÀ» Àç½ÃÀÛÇÑ´Ù.
    + +
    VERSION
    +
    ÇöÀç ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ ¹öÀü Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù.
    + +
    MODULES
    +
    ±âº» ¸ðµâ°ú ¿ÜºÎ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    DIRECTIVES
    +
    ¸ðµç Áö½Ã¾î ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    SETTINGS
    +
    Äֿܼ¡ ¾²·¹µå »óÅ ǥ½Ã¸¦ º¸À̰ųª ¾ø¾Ø´Ù. »óŸ¦ + º¸À̸é, ¾ÆÆÄÄ¡ ÄܼÖâ¿¡ µ¿ÀÛÇÏ´Â ¾²·¹µåµéÀÇ »óÅ°¡ ³ª¿Â´Ù.
    + +
    SHUTDOWN
    +
    ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ Á×ÀδÙ.
    + +
    HELP
    +
    ½ÇÇà ¿É¼ÇµéÀ» ¼³¸íÇÑ´Ù.
    +
    + +

    ±âº»ÀûÀ¸·Î ÀÌ Áö½Ã¾îµéÀº ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀÎ + ¾ÆÆÄÄ¡¸¦ ´ë»óÀ¸·Î ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ º¸È£ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀ̶ó¸é, + -p¿Í ÁÖ¼Ò¿µ¿ª À̸§À» Ãß°¡ÇÑ´Ù. ´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é ¸í·ÉÇà¿¡ + "apache2 Help"¸¦ ÀÔ·ÂÇÑ´Ù.

    + +
    top
    +
    +

    NetWare¿ë ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ

    + + + +

    ¾ÆÆÄÄ¡´Â º¸Åë conf µð·ºÅ丮¿¡ ÀÖ´Â ¼³Á¤ÆÄÀÏ·Î + ¼³Á¤ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¯´Ð½º¿ë°ú °°Áö¸¸, NetWare¿ë ¾ÆÆÄÄ¡¿¡´Â + Á¶±Ý ´Ù¸¥ Áö½Ã¾îµéÀÌ ÀÖ´Ù. »ç¿ë°¡´ÉÇÑ ¸ðµç Áö½Ã¾î¿¡ ´ëÇؼ­´Â + ¾ÆÆÄÄ¡ ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    NetWare¿ë ¾ÆÆÄÄ¡ÀÇ ÁÖµÈ Â÷ÀÌÁ¡Àº:

    + +
      +
    • +

      NetWare¿ë ¾ÆÆÄÄ¡´Â ´ÙÁß¾²·¹µå ¹æ½ÄÀ» »ç¿ëÇϱ⶧¹®¿¡, + À¯´Ð½º¿Í °°ÀÌ ¿äû¸¶´Ù ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + ´ë½Å ¿©·¯ ¾²·¹µå¸¦ ½ÇÇàÇÑ´Ù: ºÎ¸ð ¾²·¹µå¿Í ¿äûÀ» ó¸®ÇÏ´Â + ¿©·¯ ÀÚ½Ä È¤Àº worker ¾²·¹µåµé.

      + +

      ±×·¯¹Ç·Î "ÇÁ·Î¼¼½º"-°ü¸® Áö½Ã¾î°¡ ´Ù¸£´Ù:

      + +

      MaxRequestsPerChild - + À¯´Ð½º¿Í °°ÀÌ worker ¾²·¹µå°¡ ¿äûÀ» ¾ó¸¶¸¸Å­ ó¸®ÇÏ°í + Á×À»Áö¸¦ Á¶Á¤ÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ª + MaxRequestsPerChild 0À» »ç¿ëÇÏ¸é ¾²·¹µå´Â + Á×Áö¾Ê°í ¿µ¿øÈ÷ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. Ưº°ÇÑ ÀÌÀ¯°¡ ¾ø´Ù¸é + NetWare¿¡¼­´Â ÀÌ Áö½Ã¾î¸¦ 0À¸·Î ¼³Á¤Çϱæ + ±ÇÇÑ´Ù.

      + +

      StartThreads - + ÀÌ Áö½Ã¾î´Â ¼­¹ö°¡ óÀ½¿¡ ½ÃÀÛÇÒ ¾²·¹µå °³¼ö¸¦ °áÁ¤ÇÑ´Ù. + ±ÇÀåÇÏ´Â ±âº»°ªÀº StartThreads 50ÀÌ´Ù.

      + +

      MinSpareThreads - + ¼­¹ö´Â ½¬´Â(idle) ¾²·¹µå °³¼ö°¡ ÀÌ °ªº¸´Ù ÀûÀ¸¸é worker + ¾²·¹µå¸¦ ´õ ¸¸µç´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + MinSpareThreads 10ÀÌ´Ù.

      + +

      MaxSpareThreads - + ¼­¹ö´Â ½¬´Â ¾²·¹µå °³¼ö°¡ ÀÌ °ªº¸´Ù ¸¹À¸¸é worker ¾²·¹µå¸¦ + Á×À̱⠽ÃÀÛÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + MaxSpareThreads 100ÀÌ´Ù.

      + +

      MaxThreads - + ÀÌ Áö½Ã¾î´Â worker ¾²·¹µåÀÇ ÃÖ´ë °³¼ö¸¦ Á¦ÇÑÇÑ´Ù. ±ÇÀåÇÏ´Â + ±âº»°ªÀº ThreadsPerChild 250ÀÌ´Ù.

      + +

      ThreadStackSize - + ÇÑ worker ¾²·¹µå°¡ »ç¿ëÇÒ ½ºÅà ũ±â¸¦ Áö½ÃÇÑ´Ù. ±ÇÀåÇÏ´Â + ±âº»°ªÀº ThreadStackSize 65536ÀÌ´Ù.

      +
    • + +
    • +

      ¾Æ±Ô¸ÕÆ®·Î ÆÄÀϸíÀ» ¹Þ´Â Áö½Ã¾î¿¡´Â À¯´Ð½º ÆÄÀϸíÀÌ + ¾Æ´Ñ NetWare ÆÄÀϸíÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ + ³»ºÎÀûÀ¸·Î À¯´Ð½º½Ä ÆÄÀϸíÀ» »ç¿ëÇϱ⶧¹®¿¡ ¹é½½·¡½¬ + ´ë½Å ½½·¡½¬¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ðµç Àý´ë°æ·Î¿¡ º¼·ý¸íÀ» + Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù. º¼·ý¸íÀ» »ý·«ÇÏ¸é ¾ÆÆÄÄ¡´Â + SYS: º¼·ýÀ̶ó°í À߸ø °¡Á¤ÇÒ ¼ö ÀÖ´Ù.

      +
    • + +
    • +

      NetWare¿ë ¾ÆÆÄÄ¡´Â ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°í ½ÇÇàÇÒ¶§ + ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù. º¸Åë ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϸé + \Apache2\modules µð·ºÅ丮¿¡ ¿©·¯ Ãß°¡ ¸ðµâÀ» + ¼³Ä¡ÇÑ´Ù. À̵é ȤÀº ´Ù¸¥ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î status ¸ðµâÀ» »ç¿ëÇÑ´Ù¸é:

      + +

      + LoadModule status_module modules/status.nlm +

      + +

      ÀоîµéÀÏ ¼ö + ÀÖ´Â ¸ðµâ ¸¸µé±â¿¡ ´ëÇÑ Á¤º¸µµ ÀÖ´Ù.

      +
    • +
    + +

    ÀÌ¿ÜÀÇ NetWare Àü¿ë Áö½Ã¾îµé:

    + + + +
      +
    • CGIMapExtension - + CGI ÆÄÀÏ È®ÀåÀÚ¸¦ ½ºÅ©¸³Æ® ÀÎÅÍÇÁ¸®ÅÍ¿Í ¿¬°áÇÑ´Ù.
    • +
    +
      +
    • SecureListen - + ƯÁ¤ Æ÷Æ®¸¦ SSL ¾ÏȣȭÇÑ´Ù.
    • +
    +
      +
    • NWSSLTrustedCerts - + ÇÁ·Ï½ÃÇÏ´Â ¼­¹ö¿¡ º¸¾È¿¬°áÇÒ¶§ »ç¿ëÇÒ ½Å·ÚÇÏ´Â + ÀÎÁõ¼­(certificate)¸¦ Ãß°¡ÇÑ´Ù.
    • +
    +
      +
    • NWSSLUpgradeable - + ƯÁ¤ ÁÖ¼Ò/Æ÷Æ®·Î ¸Î¾îÁø ¿¬°áÀ» SSL ¿¬°á·Î º¯°æÇÒ ¼ö + ÀÖ´Ù.
    • +
    + + + +
    top
    +
    +

    Netware¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ

    + + + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é MetroWerks CodeWarrior 6.x ÀÌ»óÀÌ + ÇÊ¿äÇÏ´Ù. ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ¸é ¾î¶² Netware º¼·ý¿¡¶óµµ ¼³Ä¡ÇÒ + ¼ö ÀÖ´Ù. ±âº»°ªÀº sys:/Apache2 µð·ºÅ丮´Ù.

    + +

    ¼­¹ö¸¦ ½ÇÇàÇϱâ Àü¿¡ conf µð·ºÅ丮¸¦ ÀÛ¼ºÇØ¾ß + ÇÑ´Ù. ¹èÆ÷º»ÀÇ conf µð·ºÅ丮¿¡ ÀÖ´Â + HTTPD-STD.CONF ÆÄÀϸíÀ» HTTPD.CONF·Î + º¯°æÇÑ´Ù. HTTPD.CONF ÆÄÀÏ¿¡¼­ @@Value@@ + Ç¥½Ã¸¦ ã¾Æ¼­ ÀûÀýÇÑ ¼³Á¤À¸·Î ´ëüÇÑ´Ù. conf/magic°ú + conf/mime.types ÆÄÀϵµ º¹»çÇÑ´Ù. ¾Æ´Ï¸é makefileÀ» + ½ÇÇàÇÒ¶§ install Å°¿öµå¸¦ »ç¿ëÇÏ¸é ¿ÏÀüÇÑ ¹èÆ÷º»À» + ¸¸µç´Ù.

    + +

    ¿ä±¸»çÇ×:

    + + + +

    NetWare¿ë ¾ÆÆÄÄ¡ 2.0À» ÄÄÆÄÀÏÇÏ·Á¸é ´ÙÀ½ °³¹ßµµ±¸°¡ + ÇÊ¿äÇÏ´Ù:

    + + + + + +

    NetWare makefileÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ:

    + + + +
      +
    • NOVELLLIBC ȯ°æº¯¼ö¸¦ +

      Set NOVELLLIBC=c:\novell\ndk\libc

      ¿Í + °°ÀÌ NetWare Libraries for C SDK À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • METROWERKS ȯ°æº¯¼ö¸¦ +

      Set METROWERKS=C:\Program Files\Metrowerks\CodeWarrior

      ¿Í + °°ÀÌ Metrowerks CodeWarrior ÄÄÆÄÀÏ·¯¸¦ ¼³Ä¡ÇÑ À§Ä¡·Î + ¼³Á¤ÇÑ´Ù. ±âº» À§Ä¡ÀÎ + C:\Program Files\Metrowerks\CodeWarrior¿¡ + ¼³Ä¡ÇÏ¿´´Ù¸é, ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ÇÊ¿ä´Â ¾ø´Ù.
    • + +
    • LDAPSDK ȯ°æº¯¼ö¸¦ +

      Set LDAPSDK=c:\Novell\NDK\cldapsdk\NetWare\libc

      ¿Í + °°ÀÌ LDAP Libraries for C¸¦ ¼³Ä¡ÇÑ À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • ZLIBSDK ȯ°æº¯¼ö¸¦ +

      Set ZLIBSDK=D:\NOVELL\zlib

      °ú °°ÀÌ + ZLib ¶óÀ̺귯¸® ¼Ò½ºÄÚµå À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • AP_WORK ȯ°æº¯¼ö¸¦ \httpd-2.0 + µð·ºÅ丮ÀÇ Àüü °æ·Î·Î ¼³Á¤ÇÑ´Ù.
    • + +
    • APR_WORK ȯ°æº¯¼ö¸¦ + \httpd-2.0\srclib\apr µð·ºÅ丮ÀÇ Àüü °æ·Î·Î + ¼³Á¤ÇÑ´Ù.
    • + +
    • AWK µµ±¸¿Í GNU make (gmake.exe) µµ±¸°¡ + ½Ã½ºÅÛÀÇ PATH ȯ°æº¯¼ö¿¡ Æ÷ÇÔµÇÀÖ´ÂÁö + È®ÀÎÇÑ´Ù.
    • + +
    • ¼Ò½ºÄڵ带 ´Ù¿î¹Þ¾Æ Àû´çÇÑ µð·ºÅ丮¿¡ ¾ÐÃàÀ» Ǭ´Ù.
    • + +
    • \httpd-2.0\srclib\apr-util\uri µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + GENURI.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • GENURI.nlm ÆÄÀÏÀ» NetWare ¼­¹öÀÇ + SYS: º¼·ýÀ¸·Î º¹»çÇÏ°í +

      SYS:\genuri > sys:\uri_delims.h

      + ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. +
    • + +
    • uri_delims.h ÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ´Â ÄÄÇ»ÅÍÀÇ + \httpd-2.0\srclib\apr-util\uri µð·ºÅ丮·Î + º¹»çÇÑ´Ù.
    • + +
    • \httpd-2.0\srclib\apr µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© APRÀ» + ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • \httpd-2.0\srclib\pcre µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + DFTABLES.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • \httpd-2.0\server µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + GENCHARS.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • °¢ µð·ºÅ丮ÀÇ GENCHARS.nlm°ú + DFTABLES.nlm ÆÄÀÏÀ» NetWare ¼­¹öÀÇ + SYS: º¼·ýÀ¸·Î º¹»çÇÏ°í ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù: +

      + SYS:\genchars > sys:\test_char.h
      + SYS:\dftables > sys:\chartables.c
      +

      +
    • + +
    • test_char.h¿Í chartables.c + ÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ´Â ÄÄÇ»ÅÍÀÇ \httpd-2.0\os\netware + µð·ºÅ丮·Î º¹»çÇÑ´Ù.
    • + +
    • \httpd-2.0 µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÑ´Ù. +

      gmake -f nwgnumakefile install

      °ú + °°ÀÌ install ÆĶó¹ÌÅ͸¦ Ãß°¡ÇÏ¸é ¹èÆ÷¿ë µð·ºÅ丮¸¦ ¸¸µé + ¼ö ÀÖ´Ù. +
    • +
    + + + +

    Ãß°¡ make ¿É¼Ç

    + + + +
      +
    • gmake -f nwgnumakefile

      ÀÏ¹Ý ½ÇÇàÆÄÀÏÀ» + ÄÄÆÄÀÏÇÏ¿© \release µð·ºÅ丮·Î º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile DEBUG=1

      µð¹ö±×¿ë + ½ÇÇàÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ¿© \debug µð·ºÅ丮·Î + º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile install +

      \dist\Apache2 µð·ºÅ丮¿¡ ½ÇÇàÆÄÀÏ, ¹®¼­, + Ãß°¡ Áö¿øÆÄÀÏÀ» Æ÷ÇÔÇÑ ¿ÏÀüÇÑ ¾ÆÆÄÄ¡ ¹èÆ÷º»À» ¸¸µç´Ù.

    • + +
    • gmake -f nwgnumakefile installdev +

      install°ú ºñ½ÁÇÏÁö¸¸, \lib°ú + \include µð·ºÅ丮¸¦ ¸¸µé°í Çì´õÆÄÀÏ°ú import + ÆÄÀÏÀ» º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile clean +

      DEBUG Á¤ÀÇ À¯¹«¿¡ µû¶ó \release³ª + \debug¿¡ ÀÖ´Â ¿ÀºêÁ§Æ®ÆÄÀÏ°ú ½ÇÇàÆÄÀÏÀ» + ¸ðµÎ Áö¿î´Ù.

    • + +
    • gmake -f nwgnumakefile clobber_all

      clean°ú + ºñ½ÁÇÏÁö¸¸ µð·ºÅ丮µµ Áö¿î´Ù.

    • +
    + + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/netware.xml b/trunk/docs/manual/platform/netware.xml new file mode 100644 index 0000000000..c9edbe4773 --- /dev/null +++ b/trunk/docs/manual/platform/netware.xml @@ -0,0 +1,653 @@ + + + + + + + + + Platform Specific Notes + + Using Apache With Novell NetWare + + + +

    This document explains how to install, configure and run + Apache 2.0 under Novell NetWare 6.0 and above. If you find any bugs, + or wish to contribute in other ways, please use our + bug reporting + page.

    + +

    The bug reporting page and dev-httpd mailing list are not + provided to answer questions about configuration or running Apache. + Before you submit a bug report or request, first consult this document, the + Frequently Asked Questions page and the other + relevant documentation topics. If you still have a question or problem, + post it to the + novell.devsup.webserver newsgroup, where many Apache users are more than + willing to answer new and obscure questions about using Apache on NetWare.

    + +

    Most of this document assumes that you are installing Apache + from a binary distribution. If you want to compile Apache + yourself (possibly to help with development, or to track down + bugs), see the section on Compiling Apache for + NetWare below.

    + +
    + +
    + + Requirements + +

    Apache 2.0 is designed to run on NetWare 6.0 service pack 3 + and above. If you are running a service pack less + than SP3, you must install the latest + NetWare Libraries + for C (LibC).

    + +

    NetWare service packs are available here.

    + +

    Apache 2.0 for NetWare can also be run in a NetWare 5.1 environment + as long as the latest service pack or the latest version + of the NetWare Libraries + for C (LibC) has been installed . WARNING: Apache 2.0 + for NetWare has not been targeted for or tested in this environment.

    + +
    + +
    + + Downloading Apache for NetWare + +

    Information on the latest version of Apache can be found on + the Apache web server at http://www.apache.org/. This + will list the current release, any more recent alpha or + beta-test releases, together with details of mirror web and + anonymous ftp sites. Binary builds of the latest releases of + Apache 2.0 for NetWare can be downloaded from + here.

    + +
    + +
    + + Installing Apache for NetWare + +

    There is no Apache install program for NetWare currently. If you + are building Apache 2.0 for NetWare from source, you will need to + copy the files over to the server manually.

    + +

    Follow these steps to install Apache on NetWare from the + binary download (assuming you will install to + sys:/apache2):

    + +
      +
    • Unzip the binary download file to the root of the SYS: + volume (may be installed to any volume)
    • + +
    • Edit the httpd.conf file setting ServerRoot and ServerName along with any file path values + to reflect your correct server settings
    • + +
    • Add SYS:/APACHE2 to the search path, for example: + SEARCH ADD SYS:\APACHE2 +
    • + +
    + +

    Follow these steps to install Apache on NetWare manually + from your own build source (assuming you will install to + sys:/apache2):

    + +
      +
    • Create a directory called Apache2 on a + NetWare volume
    • + +
    • Copy APACHE2.NLM, APRLIB.NLM + to SYS:/APACHE2
    • + +
    • Create a directory under SYS:/APACHE2 + called BIN
    • + +
    • Copy HTDIGEST.NLM, HTPASSWD.NLM, + HTDBM.NLM, LOGRES.NLM, ROTLOGS.NLM + to SYS:/APACHE2/BIN
    • + +
    • Create a directory under SYS:/APACHE2 + called CONF
    • + +
    • Copy the HTTPD-STD.CONF file to the + SYS:/APACHE2/CONF directory and rename to + HTTPD.CONF
    • + +
    • Copy the MIME.TYPES, CHARSET.CONV and + MAGIC files to SYS:/APACHE2/CONF directory
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\ICONS + to SYS:/APACHE2/ICONS
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\MANUAL + to SYS:/APACHE2/MANUAL
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\ERROR + to SYS:/APACHE2/ERROR
    • + +
    • Copy all files and subdirectories in \HTTPD-2.0\DOCS\DOCROOT + to SYS:/APACHE2/HTDOCS
    • + +
    • Create the directory SYS:/APACHE2/LOGS + on the server
    • + +
    • Create the directory SYS:/APACHE2/CGI-BIN + on the server
    • + +
    • Create the directory SYS:/APACHE2/MODULES + and copy all nlm modules into the modules directory
    • + +
    • Edit the HTTPD.CONF file searching for all + @@Value@@ markers and replacing them with the + appropriate setting
    • + +
    • Add SYS:/APACHE2 to the search path, for example: + SEARCH ADD SYS:\APACHE2 +
    • +
    + +

    Apache may be installed to other volumes besides the default SYS volume.

    + +

    During the build process, adding the keyword "install" to the makefile command line + will automatically produce a complete distribution package under the subdirectory + DIST. Install Apache by simply copying the distribution that was produced + by the makfiles to the root of a NetWare volume (see: Compiling Apache for + NetWare below).

    + +
    + +
    + + Running Apache for NetWare + +

    To start Apache just type apache at the + console. This will load apache in the OS address space. If you + prefer to load Apache in a protected address space you may + specify the address space with the load statement as follows:

    + + + load address space = apache2 apache2 + + +

    This will load Apache into an address space called apache2. + Running multiple instances of Apache concurrently on NetWare is + possible by loading each instance into its own protected + address space.

    + +

    After starting Apache, it will be listening to port 80 + (unless you changed the Listen + directive in the configuration files). + To connect to the server and access the default page, + launch a browser and enter the server's name or address. This + should respond with a welcome page, and a link to the Apache + manual. If nothing happens or you get an error, look in the + error_log file in the logs + directory.

    + +

    Once your basic installation is working, you should + configure it properly by editing the files in the + conf directory.

    + +

    To unload Apache running in the OS address space just type + the following at the console:

    + + + unload apache2 + + +

    or

    + + + apache2 shutdown + + +

    If apache is running in a protected address space specify the + address space in the unload statement:

    + + + unload address space = apache2 apache2 + + +

    When working with Apache it is important to know how it will + find the configuration files. You can specify a configuration + file on the command line in two ways:

    + +
      +
    • -f specifies a path to a particular + configuration file
    • +
    + + + apache2 -f "vol:/my server/conf/my.conf" + + + + apache -f test/test.conf + + +

    In these cases, the proper ServerRoot + should be set in the configuration file.

    + +

    If you don't specify a configuration file name with -f, + Apache will use the file name compiled into the server, usually + conf/httpd.conf. Invoking Apache with the -V + switch will display this value labeled as SERVER_CONFIG_FILE. + Apache will then determine its ServerRoot + by trying the following, in this order:

    + +
      +
    • A ServerRoot directive via a + -C switch.
    • + +
    • The -d switch on the command line.
    • + +
    • Current working directory
    • + +
    • The server root compiled into the server.
    • +
    + +

    The server root compiled into the server is usually sys:/apache2. + invoking apache with the -V switch will display this value labeled as + HTTPD_ROOT.

    + +

    Apache 2.0 for NetWare includes a set of command line directives that can + be used to modify or display information about the running instance of the + web server. These directives are only available while Apache is running. Each + of these directives must be preceded by the keyword APACHE2.

    + +
    +
    RESTART
    +
    Instructs Apache to terminate all running worker + threads as they become idle, reread the configuration file and restart each + worker thread based on the new configuration.
    + +
    VERSION
    +
    Displays version information about the currently + running instance of Apache.
    + +
    MODULES
    +
    Displays a list of loaded modules both built-in + and external.
    + +
    DIRECTIVES
    +
    Displays a list of all available directives.
    + +
    SETTINGS
    +
    Enables or disables the thread status display + on the console. When enabled, the state of each running threads is displayed + on the Apache console screen.
    + +
    SHUTDOWN
    +
    Terminates the running instance of the Apache + web server.
    + +
    HELP
    +
    Describes each of the runtime directives.
    +
    + +

    By default these directives are issued against the instance of Apache running + in the OS address space. To issue a directive against a specific instance running + in a protected address space, include the -p parameter along with the name of the + address space. For more information type "apache2 Help" on the command line.

    + +
    + +
    + + Configuring Apache for NetWare + +

    Apache is configured by reading configuration files usually stored + in the conf directory. These are the same as files used + to configure the Unix version, but there are a few different directives for + Apache on NetWare. See the Apache + documentation for all the available directives.

    + +

    The main differences in Apache for NetWare are:

    + +
      +
    • +

      Because Apache for NetWare is multithreaded, it does not + use a separate process for each request, as Apache does on some Unix + implementations. Instead there are only threads running: a parent + thread, and multiple child or worker threads which handle the requests.

      + +

      Therefore the "process"-management directives are different:

      + +

      MaxRequestsPerChild - + Like the Unix directive, this controls how many requests + a worker thread will serve before exiting. The recommended default, + MaxRequestsPerChild 0, causes the thread to continue servicing + request indefinitely. It is recommended on NetWare, unless there is some + specific reason, that this directive always remain set to 0.

      + +

      StartThreads - + This directive tells the server how many threads it should start initially. + The recommended default is StartThreads 50.

      + +

      MinSpareThreads - + This directive instructs the server to spawn additional worker threads + if the number of idle threads ever falls below this value. The recommended + default is MinSpareThreads 10.

      + +

      MaxSpareThreads - + This directive instructs the server to begin terminating worker threads + if the number of idle threads ever exceeds this value. The recommended + default is MaxSpareThreads 100.

      + +

      MaxThreads - + This directive limits the total number of work threads to a maximum + value. The recommended default is ThreadsPerChild 250.

      + +

      ThreadStackSize - + This directive tells the server what size of stack to use + for the individual worker thread. The recommended default + is ThreadStackSize 65536.

      +
    • + +
    • +

      The directives that accept filenames as arguments must use + NetWare filenames instead of Unix names. However, because Apache + uses Unix-style names internally, forward slashes must be used + rather than backslashes. It is recommended that all rooted file paths + begin with a volume name. If omitted, Apache will assume the + SYS: volume which may not be correct.

      +
    • + +
    • +

      Apache for NetWare has the ability to load modules at + runtime, without recompiling the server. If Apache is + compiled normally, it will install a number of optional + modules in the \Apache2\modules directory. + To activate these, or other modules, the LoadModule directive + must be used. For example, to active the status module, use + the following:

      + + + LoadModule status_module modules/status.nlm + + +

      Information on creating loadable + modules is also available.

      +
    • +
    + +
    + + Additional NetWare specific directives: + +
      +
    • CGIMapExtension - + This directive maps a CGI file extension to a script interpreter.
    • +
    +
      +
    • SecureListen - + Enables SSL encryption for a specified port.
    • +
    +
      +
    • NWSSLTrustedCerts - + Adds trusted certificates that are used to create secure connections to proxied servers.
    • +
    +
      +
    • NWSSLUpgradeable - + Allow a connection created on the specified address/port to be upgraded to an SSL connection.
    • +
    + +
    + +
    + +
    + + Compiling Apache for NetWare + +

    Compiling Apache requires MetroWerks CodeWarrior 6.x or higher. Once + Apache has been built, it can be installed to the root of any NetWare + volume. The default is the sys:/Apache2 directory.

    + +

    Before running the server you must fill out the conf + directory. Copy the file HTTPD-STD.CONF from the distribution + conf directory and rename it to HTTPD.CONF. + Edit the HTTPD.CONF file searching for all @@Value@@ + markers and replacing them with the appropriate setting. Copy over + the conf/magic and conf/mime.types files as well. + Alternatively, a complete distribution can be built by including the keyword + install when invoking the makefiles.

    + +
    + + Requirements: + +

    The following development tools are required to build + Apache 2.0 for NetWare:

    + + + +
    + +
    + + Building Apache using the NetWare makefiles: + +
      +
    • Set the environment variable NOVELLLIBC to the + location of the NetWare Libraries for C SDK, for example: + Set NOVELLLIBC=c:\novell\ndk\libc +
    • + +
    • Set the environment variable METROWERKS to the + location where you installed the Metrowerks CodeWarrior compiler, + for example: + Set METROWERKS=C:\Program Files\Metrowerks\CodeWarrior + If you installed to the default location C:\Program + Files\Metrowerks\CodeWarrior, you don't need to set this.
    • + +
    • Set the environment variable LDAPSDK to the + location where you installed the LDAP Libraries for C, for example: + Set LDAPSDK=c:\Novell\NDK\cldapsdk\NetWare\libc +
    • + +
    • Set the environment variable ZLIBSDK to the + location where you installed the source code for the ZLib Library, + for example: + Set ZLIBSDK=D:\NOVELL\zlib +
    • + +
    • Set the environment variable AP_WORK to the full path of + the httpd source code directory. + Set AP_WORK=D:\httpd-2.0.x +
    • + +
    • Set the environment variable APR_WORK to the full path of + the apr source code directory. Typically \httpd\srclib\apr + but the APR project can be outside of the httpd directory structure. + Set APR_WORK=D:\apr-1.x.x +
    • + +
    • Set the environment variable APU_WORK to the full path of + the apr-util source code directory. Typically \httpd\srclib\apr-util + but the APR-UTIL project can be outside of the httpd directory structure. + Set APU_WORK=D:\apr-util-1.x.x +
    • + +
    • Make sure that the path to the AWK utility and the GNU make utility + (gmake.exe) have been included in the system's + PATH environment variable.
    • + +
    • Download the source code and unzip to an appropriate directory on + your workstation.
    • + +
    • Change directory to \httpd-2.0 and build the prebuild utilities + by running "gmake -f nwgnumakefile prebuild". This target will create + the directory \httpd-2.0\nwprebuild and copy each of the utilities + to this location that are necessary to complete the following build steps. +
    • + +
    • Copy the files \httpd-2.0\nwprebuild\GENCHARS.nlm and + \httpd-2.0\nwprebuild\DFTABLES.nlm to the SYS: volume of a + NetWare server and run them using the following commands: + + SYS:\genchars > sys:\test_char.h
      + SYS:\dftables sys:\chartables.c
      +
      +
    • + +
    • Copy the files test_char.h and chartables.c + to the directory \httpd-2.0\os\netware on the build machine.
    • + +
    • Change directory to \httpd-2.0 and build Apache by running + "gmake -f nwgnumakefile". You can create a distribution directory by + adding an install parameter to the command, for example: + gmake -f nwgnumakefile install +
    • +
    + +
    + +
    + + Additional make options + +
      +
    • gmake -f nwgnumakefile

      Builds release versions of all of the + binaries and copies them to a \release destination directory.

    • + +
    • gmake -f nwgnumakefile DEBUG=1

      Builds debug versions of all of the + binaries and copies them to a \debug destination directory.

    • + +
    • gmake -f nwgnumakefile install

      Creates a complete Apache + distribution with binaries, docs and additional support files in a + \dist\Apache2 directory.

    • + +
    • gmake -f nwgnumakefile prebuild

      Builds all of the prebuild utilities + and copies them to the \nwprebuild directory.

    • + +
    • gmake -f nwgnumakefile installdev

      Same as install but also creates a + \lib and \include directory in the destination directory + and copies headers and import files.

    • + +
    • gmake -f nwgnumakefile clean

      Cleans all object files and binaries + from the \release.o or \debug.o build areas depending on whether + DEBUG has been defined.

    • + +
    • gmake -f nwgnumakefile clobber_all

      Same as clean and also deletes + the distribution directory if it exists.

    • +
    + +
    + +
    + + Additional environment variable options + +
      +
    • To build all of the experimental modules, set the environment + variable EXPERIMENTAL: + Set EXPERIMENTAL=1 +
    • + +
    • To build Apache using standard BSD style sockets rather than + Winsock, set the environment variable USE_STDSOCKETS: + Set USE_STDSOCKETS=1 +
    • + +
    + +
    + +
    + + Building mod_ssl for the NetWare platform + +

    By default Apache for NetWare uses the built-in module + mod_nw_ssl to provide SSL services. This module + simply enables the native SSL services implemented in NetWare OS + to handle all encryption for a given port. Alternatively, mod_ssl + can also be used in the same manner as on other platforms.

    + +

    Before mod_ssl can be built for the NetWare platform, the OpenSSL + libraries must be provided. This can be done through the following + steps:

    + +
      +
    • Download the latest NetWare patch for OpenSSL from the + OpenSSL Contribution + page.
    • + +
    • Download the corresponding OpenSSL source code from the + OpenSSL Source + page.
    • + +
    • At the root of the OpenSSL source directory, apply the NetWare + patch using the "patch" utility, for example: + patch -p 1 -i netwarepatch-0.9.7g.diff
    • + +
    • Edit the file NetWare/set_env.bat and modify any + tools and utilities paths so that they correspond to your build + environment.
    • + +
    • From the root of the OpenSSL source directory, run the following + scripts: + + Netware/set_env netware-libc
      + Netware/build netware-libc +
    • + +
    • Before building Apache, set the environment variable + OSSLSDK to the full path to the root of the openssl + source code directory. + Set OSSLSDK=d:\openssl-0.9.7x
    • + +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/platform/netware.xml.ko b/trunk/docs/manual/platform/netware.xml.ko new file mode 100644 index 0000000000..4e7070e51b --- /dev/null +++ b/trunk/docs/manual/platform/netware.xml.ko @@ -0,0 +1,592 @@ + + + + + + + + + Platform Specific Notes + + Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ëÇϱâ + + + +

    ÀÌ ¹®¼­´Â Novell NetWare 6.0 À̻󿡼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, + ¼³Á¤, ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. ¹ö±×¸¦ ã¾Ò°Å³ª ´Ù¸¥ ¹æ¹ýÀ¸·Î + µ½°í½Í´Ù¸é, ¹ö±× + º¸°í ÆäÀÌÁö¸¦ ÀÌ¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    ¹ö±× º¸°í ÆäÀÌÁö³ª dev-httpd ¸ÞÀϸµ¸®½ºÆ®´Â ¾ÆÆÄÄ¡ ¼³Á¤°ú + ½ÇÇà¿¡ ´ëÇÑ Áú¹®À» ´äÇÏÁö ¾Ê´Â´Ù. ¹ö±×¸¦ º¸°íÇϱâ + Àü¿¡ ¸ÕÀú ÀÌ ¹®¼­¿Í ÀÚÁÖ ¹°¾îº¸´Â Áú¹® + (FAQ) ÆäÀÌÁö, ´Ù¸¥ °ü·Ã¹®¼­¸¦ »ìÆìºÁ¶ó. ±×·¡µµ ±Ã±ÝÇÑ + Á¡À̳ª ¹®Á¦°¡ ÀÖ´Ù¸é, NetWare¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¿¡ ´ëÇÑ ¾î·Æ°í + »õ·Î¿î Áú¹®À» ´äÇØÁÙ ¸¹Àº ¾ÆÆÄÄ¡ »ç¿ëÀÚ°¡ ÀÖ´Â + novell.devsup.webserver ´º½º±×·ì¿¡ ±ÛÀ» ¿Ã¸®±æ ¹Ù¶õ´Ù.

    + +

    ÀÌ ¹®¼­´Â ¹ÙÀ̳ʸ® ¹èÆ÷º»À¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡Çß´Ù°í °¡Á¤ÇÑ´Ù. + (¾Æ¸¶µµ °³¹ß¿¡ µµ¿òÀ» Áְųª ¹ö±×¸¦ ã±âÀ§ÇØ) Á÷Á¢ ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÏ·Á¸é ¾Æ·¡ NetWare¿¡¼­ ¾ÆÆÄÄ¡ + ÄÄÆÄÀÏÇϱâ ÀýÀ» Âü°íÇ϶ó.

    + +
    + +
    + + ¿ä±¸Á¶°Ç + +

    ¾ÆÆÄÄ¡ 2.0Àº NetWare 6.0 service pack 3 À̻󿡼­ µ¿ÀÛÇϵµ·Ï + ¼³°èµÇ¾ú´Ù. SP3º¸´Ù ³·Àº service packÀ» »ç¿ëÇÑ´Ù¸é ÃֽŠ+ NetWare + Libraries for C (LibC)¸¦ ¼³Ä¡ÇØ¾ß ÇÑ´Ù.

    + +

    NetWare service packÀº ¿©±â¿¡ + ÀÖ´Ù.

    + +

    ÃֽŠservice packÀ̳ª ÃֽŠ¹öÀü NetWare + Libraries for C (LibC)¸¦ ¼³Ä¡Çß´Ù¸é NetWare 5.1 ȯ°æ¿¡¼­µµ + NetWare¿ë ¾ÆÆÄÄ¡ 2.0À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. °æ°í: + NetWare¿ë ¾ÆÆÄÄ¡ 2.0Àº ÀÌ È¯°æÀ» °í·ÁÇÏÁö ¾Ê¾Ò°í Å×½ºÆ®ÇÏÁö + ¾Ê¾Ò´Ù.

    + +
    + +
    + + NetWare¿ë ¾ÆÆÄÄ¡ ´Ù¿î¹Þ±â + +

    ¾ÆÆÄÄ¡ ÃֽŠ¹öÀü¿¡ ´ëÇÑ Á¤º¸´Â http://www.apache.org/¿¡¼­ + (¾ÆÆÄÄ¡ À¥¼­¹ö) ãÀ» ¼ö ÀÖ´Ù. ¿©±â¿¡´Â ÇöÀç ¹öÀü°ú ÃÖ±Ù + ¾ËÆÄ/º£Å¸Å×½ºÆ® ¹öÀü, ¹Ì·¯ À¥»çÀÌÆ®¿Í ftp »çÀÌÆ® Á¤º¸°¡ + ÀÖ´Ù. NetWare¿ë ¾ÆÆÄÄ¡ 2.0ÀÇ ÃֽŠ¹ÙÀ̳ʸ® ¹èÆ÷º»Àº ¿©±â¿¡¼­ + ´Ù¿î¹ÞÀ» ¼ö ÀÖ´Ù.

    + +
    + +
    + + NetWare¿ë ¾ÆÆÄÄ¡ ¼³Ä¡Çϱâ + +

    ÇöÀç NetWare¿ë ¾ÆÆÄÄ¡ ¼³Ä¡ÇÁ·Î±×·¥Àº ¾ø´Ù. NetWare¿ë + ¾ÆÆÄÄ¡ 2.0 ¼Ò½º¸¦ Á÷Á¢ ÄÄÆÄÀÏÇÑ´Ù¸é ÆÄÀÏÀ» ¼­¹ö·Î Á÷Á¢ + º¹»çÇØÁà¾ß ÇÑ´Ù.

    + +

    ¹ÙÀ̳ʸ®·Î ´Ù¿î¹ÞÀº NetWare¿ë ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ´Â °úÁ¤Àº + ´ÙÀ½°ú °°´Ù (sys:/apache2¿¡ ¼³Ä¡ÇÑ´Ù°í °¡Á¤ÇÑ´Ù):

    + +
      +
    • ¹ÙÀ̳ʸ®·Î ´Ù¿î¹ÞÀº ¾ÐÃàÆÄÀÏÀ» SYS: º¼·ý + ÃÖ»óÀ§ µð·ºÅ丮¿¡ Ǭ´Ù (´Ù¸¥ º¼·ý¿¡ ¼³Ä¡Çصµ µÈ´Ù)
    • + +
    • httpd.conf ÆÄÀÏÀ» ¼öÁ¤ÇÏ¿© ServerRoot¿Í ServerName°ú ÆÄÀÏ°æ·Î °ªÀ» ¼­¹ö¿¡ + ¾Ë¸Â°Ô ÁöÁ¤ÇÑ´Ù
    • + +
    • ¿¹¸¦ µé¾î SEARCH ADD SYS:\APACHE2¿Í + °°ÀÌ °Ë»ö°æ·Î¿¡ SYS:/APACHE2¸¦ Ãß°¡ÇÑ´Ù +
    • + +
    + +

    Á÷Á¢ ¼Ò½º¸¦ ÄÄÆÄÀÏÇÑ °æ¿ì NetWare¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ´Â + ¹æ¹ýÀº ´ÙÀ½°ú °°´Ù (sys:/apache2¿¡ ¼³Ä¡ÇÑ´Ù°í + °¡Á¤ÇÑ´Ù):

    + +
      +
    • NetWare º¼·ý¿¡ Apache2¶ó´Â µð·ºÅ丮¸¦ + ¸¸µç´Ù
    • + +
    • APACHE2.NLM°ú APRLIB.NLMÀ» + SYS:/APACHE2¿¡ º¹»çÇÑ´Ù
    • + +
    • SYS:/APACHE2 ¾Æ·¡¿¡ BINÀ̶ó´Â + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • HTDIGEST.NLM, HTPASSWD.NLM, + HTDBM.NLM, LOGRES.NLM, + ROTLOGS.NLMÀ» SYS:/APACHE2/BIN¿¡ + º¹»çÇÑ´Ù
    • + +
    • SYS:/APACHE2 ¾Æ·¡¿¡ CONF¶ó´Â + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • HTTPD-STD.CONF ÆÄÀÏÀ» + SYS:/APACHE2/CONF¿¡ º¹»çÇÏ°í ÆÄÀϸíÀ» + HTTPD.CONF·Î º¯°æÇÑ´Ù
    • + +
    • MIME.TYPES, CHARSET.CONV, + MAGIC ÆÄÀÏÀ» SYS:/APACHE2/CONF + µð·ºÅ丮¿¡ º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\ICONS¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/ICONS·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\MANUAL¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/MANUAL·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\ERROR¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/ERROR·Î º¹»çÇÑ´Ù
    • + +
    • \HTTPD-2.0\DOCS\DICROOT¿¡ ÀÖ´Â ¸ðµç ÆÄÀÏ°ú + ÇÏÀ§µð·ºÅ丮¸¦ SYS:/APACHE2/HTDOCS·Î º¹»çÇÑ´Ù
    • + +
    • ¼­¹ö¿¡ SYS:/APACHE2/LOGS µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • ¼­¹ö¿¡ SYS:/APACHE2/APACHE2/CGI-BINÀ̶õ + µð·ºÅ丮¸¦ ¸¸µç´Ù
    • + +
    • SYS:/APACHE2/MODULES µð·ºÅ丮¸¦ ¸¸µé°í + ¸ðµç nlm ¸ðµâÀ» modules µð·ºÅ丮·Î º¹»çÇÑ´Ù
    • + +
    • HTTPD.CONF ÆÄÀÏÀÇ ¸ðµç @@Value@@ + Ç¥½Ã¸¦ ÀûÀýÇÑ ¼³Á¤À¸·Î ´ëüÇÑ´Ù
    • + +
    • SEARCH ADD SYS:\APACHE2 °°ÀÌ °Ë»ö°æ·Î¿¡ + SYS:/APACHE2¸¦ Ãß°¡ÇÑ´Ù +
    • +
    + +

    ±âº» SYS º¼·ýÀÌ ¾Æ´Ñ ´Ù¸¥ º¼·ý¿¡µµ ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù.

    + +

    makefile ¸í·É¾î¿¡ "install" Å°¿öµå¸¦ »ç¿ëÇϸé ÄÄÆÄÀϽà + ÀÚµ¿À¸·Î DIST ÇÏÀ§µð·ºÅ丮¿¡ ¿ÏÀüÇÑ ¹èÆ÷º»À» + ¸¸µç´Ù. makefile·Î ¸¸µç ¹èÆ÷º»À» NetWare º¼·ý ÃÖ»óÀ§ µð·ºÅ丮·Î + º¹»çÇÏ¸é ¾ÆÆÄÄ¡°¡ ¼³Ä¡µÈ´Ù (¾Æ·¡ NetWare¿ë + ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ Âü°í).

    + +
    + +
    + + NetWare¿ë ¾ÆÆÄÄ¡ ½ÇÇàÇϱâ + +

    ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ·Á¸é Äֿܼ¡¼­ apache¸¦ ÀÔ·ÂÇϸé + µÈ´Ù. ±×·¯¸é ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡ ¾ÆÆÄÄ¡¸¦ ÀоîµéÀδÙ. + º¸È£ÁÖ¼Ò¿µ¿ª¿¡ ¾ÆÆÄÄ¡¸¦ ÀоîµéÀÌ·Á¸é ´ÙÀ½°ú °°ÀÌ load ¸í·É¾î·Î + ÁÖ¼Ò¿µ¿ªÀ» ÁöÁ¤ÇÑ´Ù:

    + + + load address space = apache2 apache2 + + +

    ±×·¯¸é ¾ÆÆÄÄ¡¸¦ apache2¶ó´Â ÁÖ¼Ò¿µ¿ª¿¡ ÀоîµéÀδÙ. + NetWare´Â ¿©·¯ ¾ÆÆÄÄ¡¸¦ °¢°¢ ´Ù¸¥ º¸È£ÁÖ¼Ò¿µ¿ª¿¡ Àоîµé¿©¼­ + ¿©·¯ ¾ÆÆÄÄ¡¸¦ µ¿½Ã¿¡ ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡°¡ ½ÃÀÛÇϸé (¼³Á¤ÆÄÀÏ¿¡¼­ Listen Áö½Ã¾î¸¦ ¼öÁ¤ÇÏÁö + ¾Ê´ÂÇÑ) Æ÷Æ® 80¹øÀ» ±â´Ù¸°´Ù. ºê¶ó¿ìÀú¸¦ ½ÃÀÛÇÏ¿© ¼­¹ö¸í + ȤÀº ¼­¹ö ÁÖ¼Ò¸¦ ÀÔ·ÂÇÏ¸é ¼­¹ö¿¡ Á¢¼ÓÇÏ¿© ±âº»ÆäÀÌÁö¿¡ + Á¢±ÙÇÑ´Ù. ¾ÆÆÄÄ¡ ¼³¸í¼­ ¸µÅ©°¡ Àִ ȯ¿µÆäÀÌÁö°¡ ³ª¿Í¾ß + ÇÑ´Ù. ¾Æ¹« Àϵµ ¾ø°Å³ª ¿À·ù°¡ ¹ß»ýÇϸé logs + µð·ºÅ丮¿¡ ÀÖ´Â error_log ÆÄÀÏÀ» »ìÆìºÁ¶ó.

    + +

    ±âº» ¼³Ä¡°¡ µ¿ÀÛÇϸé conf µð·ºÅ丮¿¡ ÀÖ´Â + ÆÄÀÏÀ» ÀûÀýÈ÷ ¼³Á¤ÇÑ´Ù.

    + +

    ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡¸¦ ³»¸±·Á¸é Äֿܼ¡ + ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù:

    + + + unload apache2 + + +

    ȤÀº

    + + + apache2 shutdown + + +

    º¸È£ÁÖ¼Ò¿µ¿ª¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇß´Ù¸é unload ¸í·É¾î¿¡ + ÁÖ¼Ò¿µ¿ªÀ» ÁöÁ¤ÇÑ´Ù:

    + + + unload address space = apache2 apache2 + + +

    ¾ÆÆÄÄ¡°¡ ¼³Á¤ÆÄÀÏ À§Ä¡¸¦ ã´Â ¹æ¹ýÀ» ¾Ë¾ÆµÎ¾î¾ß ÇÑ´Ù. + ¸í·ÉÇà¿¡¼­ ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÏ´Â ¹æ¹ýÀº µÎ°¡Áö´Ù:

    + +
      +
    • -f´Â ƯÁ¤ ¼³Á¤ÆÄÀÏ °æ·Î¸¦ ÁöÁ¤ÇÑ´Ù
    • +
    + + + apache2 -f "vol:/my server/conf/my.conf" + + + + apache -f test/test.conf + + +

    ÀÌ °æ¿ì ¼³Á¤ÆÄÀÏÀº ¿Ã¹Ù¸¥ ServerRoot¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +

    -f·Î ¼³Á¤ÆÄÀϸíÀ» ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é, ¾ÆÆÄÄ¡´Â + ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ ÆÄÀϸíÀ» (º¸Åë conf/httpd.conf) + »ç¿ëÇÑ´Ù. -V ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé + SERVER_CONFIG_FILEÀ̶ó´Â Ç׸ñÀ» º¸¿©ÁØ´Ù. + ¾ÆÆÄÄ¡´Â ´ÙÀ½ ¼ø¼­´ë·Î ServerRoot¸¦ ã´Â´Ù:

    + +
      +
    • -C ¿É¼ÇÀÇ ServerRoot Áö½Ã¾î.
    • + +
    • ¸í·ÉÇàÀÇ -d ¿É¼Ç.
    • + +
    • ÇöÀç µð·ºÅ丮
    • + +
    • ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root.
    • +
    + +

    ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root´Â º¸Åë + sys:/apache2ÀÌ´Ù. -V ¿É¼ÇÀ¸·Î + ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé HTTPD_ROOT¶ó´Â Ç׸ñÀ» º¸¿©ÁØ´Ù.

    + +

    NetWare¿ë ¾ÆÆÄÄ¡ 2.0¿¡´Â ½ÇÇàÁßÀÎ À¥¼­¹ö¸¦ Á×À̰ųª Á¤º¸¸¦ + ¾Ë·ÁÁÖ´Â ¸í·ÉÇà Áö½Ã¾î°¡ ÀÖ´Ù. À̵é Áö½Ã¾î´Â ¾ÆÆÄÄ¡ µ¿ÀÛÁß¿¡¸¸ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. Áö½Ã¾î ¾Õ¿¡´Â APACHE2 Å°¿öµå¸¦ + ºÙ¿©¾ß ÇÑ´Ù.

    + +
    +
    RESTART
    +
    ¸ðµç ¾²·¹µå°¡ ½¬´Â »óÅÂÀ϶§ ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í, ¼³Á¤ÆÄÀÏÀ» + ´Ù½Ã ÀÐÀºÈÄ »õ·Î¿î ¼³Á¤¿¡ µû¶ó worker ¾²·¹µåµéÀ» Àç½ÃÀÛÇÑ´Ù.
    + +
    VERSION
    +
    ÇöÀç ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ ¹öÀü Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù.
    + +
    MODULES
    +
    ±âº» ¸ðµâ°ú ¿ÜºÎ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    DIRECTIVES
    +
    ¸ðµç Áö½Ã¾î ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    SETTINGS
    +
    Äֿܼ¡ ¾²·¹µå »óÅ ǥ½Ã¸¦ º¸À̰ųª ¾ø¾Ø´Ù. »óŸ¦ + º¸À̸é, ¾ÆÆÄÄ¡ ÄܼÖâ¿¡ µ¿ÀÛÇÏ´Â ¾²·¹µåµéÀÇ »óÅ°¡ ³ª¿Â´Ù.
    + +
    SHUTDOWN
    +
    ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ Á×ÀδÙ.
    + +
    HELP
    +
    ½ÇÇà ¿É¼ÇµéÀ» ¼³¸íÇÑ´Ù.
    +
    + +

    ±âº»ÀûÀ¸·Î ÀÌ Áö½Ã¾îµéÀº ¿î¿µÃ¼Á¦ ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀÎ + ¾ÆÆÄÄ¡¸¦ ´ë»óÀ¸·Î ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ º¸È£ÁÖ¼Ò¿µ¿ª¿¡¼­ ½ÇÇàÁßÀ̶ó¸é, + -p¿Í ÁÖ¼Ò¿µ¿ª À̸§À» Ãß°¡ÇÑ´Ù. ´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é ¸í·ÉÇà¿¡ + "apache2 Help"¸¦ ÀÔ·ÂÇÑ´Ù.

    + +
    + +
    + + NetWare¿ë ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ + +

    ¾ÆÆÄÄ¡´Â º¸Åë conf µð·ºÅ丮¿¡ ÀÖ´Â ¼³Á¤ÆÄÀÏ·Î + ¼³Á¤ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¯´Ð½º¿ë°ú °°Áö¸¸, NetWare¿ë ¾ÆÆÄÄ¡¿¡´Â + Á¶±Ý ´Ù¸¥ Áö½Ã¾îµéÀÌ ÀÖ´Ù. »ç¿ë°¡´ÉÇÑ ¸ðµç Áö½Ã¾î¿¡ ´ëÇؼ­´Â + ¾ÆÆÄÄ¡ ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    NetWare¿ë ¾ÆÆÄÄ¡ÀÇ ÁÖµÈ Â÷ÀÌÁ¡Àº:

    + +
      +
    • +

      NetWare¿ë ¾ÆÆÄÄ¡´Â ´ÙÁß¾²·¹µå ¹æ½ÄÀ» »ç¿ëÇϱ⶧¹®¿¡, + À¯´Ð½º¿Í °°ÀÌ ¿äû¸¶´Ù ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + ´ë½Å ¿©·¯ ¾²·¹µå¸¦ ½ÇÇàÇÑ´Ù: ºÎ¸ð ¾²·¹µå¿Í ¿äûÀ» ó¸®ÇÏ´Â + ¿©·¯ ÀÚ½Ä È¤Àº worker ¾²·¹µåµé.

      + +

      ±×·¯¹Ç·Î "ÇÁ·Î¼¼½º"-°ü¸® Áö½Ã¾î°¡ ´Ù¸£´Ù:

      + +

      MaxRequestsPerChild - + À¯´Ð½º¿Í °°ÀÌ worker ¾²·¹µå°¡ ¿äûÀ» ¾ó¸¶¸¸Å­ ó¸®ÇÏ°í + Á×À»Áö¸¦ Á¶Á¤ÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ª + MaxRequestsPerChild 0À» »ç¿ëÇÏ¸é ¾²·¹µå´Â + Á×Áö¾Ê°í ¿µ¿øÈ÷ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. Ưº°ÇÑ ÀÌÀ¯°¡ ¾ø´Ù¸é + NetWare¿¡¼­´Â ÀÌ Áö½Ã¾î¸¦ 0À¸·Î ¼³Á¤Çϱæ + ±ÇÇÑ´Ù.

      + +

      StartThreads - + ÀÌ Áö½Ã¾î´Â ¼­¹ö°¡ óÀ½¿¡ ½ÃÀÛÇÒ ¾²·¹µå °³¼ö¸¦ °áÁ¤ÇÑ´Ù. + ±ÇÀåÇÏ´Â ±âº»°ªÀº StartThreads 50ÀÌ´Ù.

      + +

      MinSpareThreads - + ¼­¹ö´Â ½¬´Â(idle) ¾²·¹µå °³¼ö°¡ ÀÌ °ªº¸´Ù ÀûÀ¸¸é worker + ¾²·¹µå¸¦ ´õ ¸¸µç´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + MinSpareThreads 10ÀÌ´Ù.

      + +

      MaxSpareThreads - + ¼­¹ö´Â ½¬´Â ¾²·¹µå °³¼ö°¡ ÀÌ °ªº¸´Ù ¸¹À¸¸é worker ¾²·¹µå¸¦ + Á×À̱⠽ÃÀÛÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + MaxSpareThreads 100ÀÌ´Ù.

      + +

      MaxThreads - + ÀÌ Áö½Ã¾î´Â worker ¾²·¹µåÀÇ ÃÖ´ë °³¼ö¸¦ Á¦ÇÑÇÑ´Ù. ±ÇÀåÇÏ´Â + ±âº»°ªÀº ThreadsPerChild 250ÀÌ´Ù.

      + +

      ThreadStackSize - + ÇÑ worker ¾²·¹µå°¡ »ç¿ëÇÒ ½ºÅà ũ±â¸¦ Áö½ÃÇÑ´Ù. ±ÇÀåÇÏ´Â + ±âº»°ªÀº ThreadStackSize 65536ÀÌ´Ù.

      +
    • + +
    • +

      ¾Æ±Ô¸ÕÆ®·Î ÆÄÀϸíÀ» ¹Þ´Â Áö½Ã¾î¿¡´Â À¯´Ð½º ÆÄÀϸíÀÌ + ¾Æ´Ñ NetWare ÆÄÀϸíÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡°¡ + ³»ºÎÀûÀ¸·Î À¯´Ð½º½Ä ÆÄÀϸíÀ» »ç¿ëÇϱ⶧¹®¿¡ ¹é½½·¡½¬ + ´ë½Å ½½·¡½¬¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ðµç Àý´ë°æ·Î¿¡ º¼·ý¸íÀ» + Æ÷ÇÔÇÏ±æ ¹Ù¶õ´Ù. º¼·ý¸íÀ» »ý·«ÇÏ¸é ¾ÆÆÄÄ¡´Â + SYS: º¼·ýÀ̶ó°í À߸ø °¡Á¤ÇÒ ¼ö ÀÖ´Ù.

      +
    • + +
    • +

      NetWare¿ë ¾ÆÆÄÄ¡´Â ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°í ½ÇÇàÇÒ¶§ + ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù. º¸Åë ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϸé + \Apache2\modules µð·ºÅ丮¿¡ ¿©·¯ Ãß°¡ ¸ðµâÀ» + ¼³Ä¡ÇÑ´Ù. À̵é ȤÀº ´Ù¸¥ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î status ¸ðµâÀ» »ç¿ëÇÑ´Ù¸é:

      + + + LoadModule status_module modules/status.nlm + + +

      ÀоîµéÀÏ ¼ö + ÀÖ´Â ¸ðµâ ¸¸µé±â¿¡ ´ëÇÑ Á¤º¸µµ ÀÖ´Ù.

      +
    • +
    + +
    + + ÀÌ¿ÜÀÇ NetWare Àü¿ë Áö½Ã¾îµé: + +
      +
    • CGIMapExtension - + CGI ÆÄÀÏ È®ÀåÀÚ¸¦ ½ºÅ©¸³Æ® ÀÎÅÍÇÁ¸®ÅÍ¿Í ¿¬°áÇÑ´Ù.
    • +
    +
      +
    • SecureListen - + ƯÁ¤ Æ÷Æ®¸¦ SSL ¾ÏȣȭÇÑ´Ù.
    • +
    +
      +
    • NWSSLTrustedCerts - + ÇÁ·Ï½ÃÇÏ´Â ¼­¹ö¿¡ º¸¾È¿¬°áÇÒ¶§ »ç¿ëÇÒ ½Å·ÚÇÏ´Â + ÀÎÁõ¼­(certificate)¸¦ Ãß°¡ÇÑ´Ù.
    • +
    +
      +
    • NWSSLUpgradeable - + ƯÁ¤ ÁÖ¼Ò/Æ÷Æ®·Î ¸Î¾îÁø ¿¬°áÀ» SSL ¿¬°á·Î º¯°æÇÒ ¼ö + ÀÖ´Ù.
    • +
    + +
    + +
    + +
    + + Netware¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é MetroWerks CodeWarrior 6.x ÀÌ»óÀÌ + ÇÊ¿äÇÏ´Ù. ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ¸é ¾î¶² Netware º¼·ý¿¡¶óµµ ¼³Ä¡ÇÒ + ¼ö ÀÖ´Ù. ±âº»°ªÀº sys:/Apache2 µð·ºÅ丮´Ù.

    + +

    ¼­¹ö¸¦ ½ÇÇàÇϱâ Àü¿¡ conf µð·ºÅ丮¸¦ ÀÛ¼ºÇØ¾ß + ÇÑ´Ù. ¹èÆ÷º»ÀÇ conf µð·ºÅ丮¿¡ ÀÖ´Â + HTTPD-STD.CONF ÆÄÀϸíÀ» HTTPD.CONF·Î + º¯°æÇÑ´Ù. HTTPD.CONF ÆÄÀÏ¿¡¼­ @@Value@@ + Ç¥½Ã¸¦ ã¾Æ¼­ ÀûÀýÇÑ ¼³Á¤À¸·Î ´ëüÇÑ´Ù. conf/magic°ú + conf/mime.types ÆÄÀϵµ º¹»çÇÑ´Ù. ¾Æ´Ï¸é makefileÀ» + ½ÇÇàÇÒ¶§ install Å°¿öµå¸¦ »ç¿ëÇÏ¸é ¿ÏÀüÇÑ ¹èÆ÷º»À» + ¸¸µç´Ù.

    + +
    + + ¿ä±¸»çÇ×: + +

    NetWare¿ë ¾ÆÆÄÄ¡ 2.0À» ÄÄÆÄÀÏÇÏ·Á¸é ´ÙÀ½ °³¹ßµµ±¸°¡ + ÇÊ¿äÇÏ´Ù:

    + + + +
    + +
    + + NetWare makefileÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ: + +
      +
    • NOVELLLIBC ȯ°æº¯¼ö¸¦ + Set NOVELLLIBC=c:\novell\ndk\libc¿Í + °°ÀÌ NetWare Libraries for C SDK À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • METROWERKS ȯ°æº¯¼ö¸¦ + Set METROWERKS=C:\Program Files\Metrowerks\CodeWarrior¿Í + °°ÀÌ Metrowerks CodeWarrior ÄÄÆÄÀÏ·¯¸¦ ¼³Ä¡ÇÑ À§Ä¡·Î + ¼³Á¤ÇÑ´Ù. ±âº» À§Ä¡ÀÎ + C:\Program Files\Metrowerks\CodeWarrior¿¡ + ¼³Ä¡ÇÏ¿´´Ù¸é, ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÒ ÇÊ¿ä´Â ¾ø´Ù.
    • + +
    • LDAPSDK ȯ°æº¯¼ö¸¦ + Set LDAPSDK=c:\Novell\NDK\cldapsdk\NetWare\libc¿Í + °°ÀÌ LDAP Libraries for C¸¦ ¼³Ä¡ÇÑ À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • ZLIBSDK ȯ°æº¯¼ö¸¦ + Set ZLIBSDK=D:\NOVELL\zlib°ú °°ÀÌ + ZLib ¶óÀ̺귯¸® ¼Ò½ºÄÚµå À§Ä¡·Î ¼³Á¤ÇÑ´Ù. +
    • + +
    • AP_WORK ȯ°æº¯¼ö¸¦ \httpd-2.0 + µð·ºÅ丮ÀÇ Àüü °æ·Î·Î ¼³Á¤ÇÑ´Ù.
    • + +
    • APR_WORK ȯ°æº¯¼ö¸¦ + \httpd-2.0\srclib\apr µð·ºÅ丮ÀÇ Àüü °æ·Î·Î + ¼³Á¤ÇÑ´Ù.
    • + +
    • AWK µµ±¸¿Í GNU make (gmake.exe) µµ±¸°¡ + ½Ã½ºÅÛÀÇ PATH ȯ°æº¯¼ö¿¡ Æ÷ÇÔµÇÀÖ´ÂÁö + È®ÀÎÇÑ´Ù.
    • + +
    • ¼Ò½ºÄڵ带 ´Ù¿î¹Þ¾Æ Àû´çÇÑ µð·ºÅ丮¿¡ ¾ÐÃàÀ» Ǭ´Ù.
    • + +
    • \httpd-2.0\srclib\apr-util\uri µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + GENURI.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • GENURI.nlm ÆÄÀÏÀ» NetWare ¼­¹öÀÇ + SYS: º¼·ýÀ¸·Î º¹»çÇÏ°í + SYS:\genuri > sys:\uri_delims.h + ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. +
    • + +
    • uri_delims.h ÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ´Â ÄÄÇ»ÅÍÀÇ + \httpd-2.0\srclib\apr-util\uri µð·ºÅ丮·Î + º¹»çÇÑ´Ù.
    • + +
    • \httpd-2.0\srclib\apr µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© APRÀ» + ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • \httpd-2.0\srclib\pcre µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + DFTABLES.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • \httpd-2.0\server µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© + GENCHARS.nlmÀ» ÄÄÆÄÀÏÇÑ´Ù.
    • + +
    • °¢ µð·ºÅ丮ÀÇ GENCHARS.nlm°ú + DFTABLES.nlm ÆÄÀÏÀ» NetWare ¼­¹öÀÇ + SYS: º¼·ýÀ¸·Î º¹»çÇÏ°í ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù: + + SYS:\genchars > sys:\test_char.h
      + SYS:\dftables > sys:\chartables.c
      +
      +
    • + +
    • test_char.h¿Í chartables.c + ÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ´Â ÄÄÇ»ÅÍÀÇ \httpd-2.0\os\netware + µð·ºÅ丮·Î º¹»çÇÑ´Ù.
    • + +
    • \httpd-2.0 µð·ºÅ丮¿¡¼­ + "gmake -f nwgnumakefile"À» ½ÇÇàÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇÑ´Ù. + gmake -f nwgnumakefile install°ú + °°ÀÌ install ÆĶó¹ÌÅ͸¦ Ãß°¡ÇÏ¸é ¹èÆ÷¿ë µð·ºÅ丮¸¦ ¸¸µé + ¼ö ÀÖ´Ù. +
    • +
    + +
    + +
    + + Ãß°¡ make ¿É¼Ç + +
      +
    • gmake -f nwgnumakefile

      ÀÏ¹Ý ½ÇÇàÆÄÀÏÀ» + ÄÄÆÄÀÏÇÏ¿© \release µð·ºÅ丮·Î º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile DEBUG=1

      µð¹ö±×¿ë + ½ÇÇàÆÄÀÏÀ» ÄÄÆÄÀÏÇÏ¿© \debug µð·ºÅ丮·Î + º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile install +

      \dist\Apache2 µð·ºÅ丮¿¡ ½ÇÇàÆÄÀÏ, ¹®¼­, + Ãß°¡ Áö¿øÆÄÀÏÀ» Æ÷ÇÔÇÑ ¿ÏÀüÇÑ ¾ÆÆÄÄ¡ ¹èÆ÷º»À» ¸¸µç´Ù.

    • + +
    • gmake -f nwgnumakefile installdev +

      install°ú ºñ½ÁÇÏÁö¸¸, \lib°ú + \include µð·ºÅ丮¸¦ ¸¸µé°í Çì´õÆÄÀÏ°ú import + ÆÄÀÏÀ» º¹»çÇÑ´Ù.

    • + +
    • gmake -f nwgnumakefile clean +

      DEBUG Á¤ÀÇ À¯¹«¿¡ µû¶ó \release³ª + \debug¿¡ ÀÖ´Â ¿ÀºêÁ§Æ®ÆÄÀÏ°ú ½ÇÇàÆÄÀÏÀ» + ¸ðµÎ Áö¿î´Ù.

    • + +
    • gmake -f nwgnumakefile clobber_all

      clean°ú + ºñ½ÁÇÏÁö¸¸ µð·ºÅ丮µµ Áö¿î´Ù.

    • +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/platform/netware.xml.meta b/trunk/docs/manual/platform/netware.xml.meta new file mode 100644 index 0000000000..0acefe5cc7 --- /dev/null +++ b/trunk/docs/manual/platform/netware.xml.meta @@ -0,0 +1,12 @@ + + + + netware + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/platform/perf-hp.html b/trunk/docs/manual/platform/perf-hp.html new file mode 100644 index 0000000000..23995ca460 --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.html @@ -0,0 +1,7 @@ +URI: perf-hp.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: perf-hp.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/perf-hp.html.en b/trunk/docs/manual/platform/perf-hp.html.en new file mode 100644 index 0000000000..76731557b6 --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.html.en @@ -0,0 +1,105 @@ + + + +Running a High-Performance Web Server on HPUX - Apache HTTP Server + + + + + +
    <-
    +

    Running a High-Performance Web Server on HPUX

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +
    +Date: Wed, 05 Nov 1997 16:59:34 -0800
    +From: Rick Jones <raj@cup.hp.com>
    +Reply-To: raj@cup.hp.com
    +Organization: Network Performance
    +Subject: HP-UX tuning tips
    +
    + +

    Here are some tuning tips for HP-UX to add to the tuning page.

    + +

    For HP-UX 9.X: Upgrade to 10.20
    + For HP-UX 10.[00|01|10]: Upgrade to 10.20

    + +

    For HP-UX 10.20:

    + +

    Install the latest cumulative ARPA Transport Patch. This + will allow you to configure the size of the TCP connection + lookup hash table. The default is 256 buckets and must be set + to a power of two. This is accomplished with adb against the + *disc* image of the kernel. The variable name is tcp_hash_size. + Notice that it's critically important that you use "W" + to write a 32 bit quantity, not "w" to write a 16 bit + value when patching the disc image because the tcp_hash_size + variable is a 32 bit quantity.

    + +

    How to pick the value? Examine the output of ftp://ftp.cup.hp.com/dist/networking/tools/connhist + and see how many total TCP connections exist on the system. You + probably want that number divided by the hash table size to be + reasonably small, say less than 10. Folks can look at HP's + SPECweb96 disclosures for some common settings. These can be + found at http://www.specbench.org/. + If an HP-UX system was performing at 1000 SPECweb96 connections + per second, the TIME_WAIT time of 60 seconds would mean + 60,000 TCP "connections" being tracked.

    + +

    Folks can check their listen queue depths with ftp://ftp.cup.hp.com/dist/networking/misc/listenq.

    + +

    If folks are running Apache on a PA-8000 based system, they + should consider "chatr'ing" the Apache executable to have a + large page size. This would be "chatr +pi L <BINARY>". + The GID of the running executable must have MLOCK privileges. + Setprivgrp(1m) should be consulted for assigning + MLOCK. The change can be validated by running Glance + and examining the memory regions of the server(s) to make sure that + they show a non-trivial fraction of the text segment being locked.

    + +

    If folks are running Apache on MP systems, they might + consider writing a small program that uses mpctl() + to bind processes to processors. A simple pid % numcpu + algorithm is probably sufficient. This might even go into the + source code.

    + +

    If folks are concerned about the number of FIN_WAIT_2 + connections, they can use nettune to shrink the value of + tcp_keepstart. However, they should be careful there - + certainly do not make it less than oh two to four minutes. If + tcp_hash_size has been set well, it is probably OK to + let the FIN_WAIT_2's take longer to timeout (perhaps + even the default two hours) - they will not on average have a big + impact on performance.

    + +

    There are other things that could go into the code base, but + that might be left for another email. Feel free to drop me a + message if you or others are interested.

    + +

    sincerely,

    + +

    rick jones

    + +

    http://www.cup.hp.com/netperf/NetperfPage.html

    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/perf-hp.html.ko.euc-kr b/trunk/docs/manual/platform/perf-hp.html.ko.euc-kr new file mode 100644 index 0000000000..150a823cb9 --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.html.ko.euc-kr @@ -0,0 +1,100 @@ + + + +HPUX¿¡¼­ °í¼º´É À¥¼­¹ö ½ÇÇàÇϱâ - Apache HTTP Server + + + + + +
    <-
    +

    HPUX¿¡¼­ °í¼º´É À¥¼­¹ö ½ÇÇàÇϱâ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + + +
    +Date: Wed, 05 Nov 1997 16:59:34 -0800
    +From: Rick Jones <raj@cup.hp.com>
    +Reply-To: raj@cup.hp.com
    +Organization: Network Performance
    +Subject: HP-UX tuning tips
    +
    + +

    ÀÌ ±ÛÀº ¼º´ÉÇâ»ó ÆäÀÌÁö¿¡ Ãß°¡ÇÒ HP-UX ¼º´ÉÇâ»ó ÆÁÀÌ´Ù.

    + +

    HP-UX 9.X´Â: 10.20À¸·Î ¾÷±×·¹À̵åÇ϶ó
    + HP-UX 10.[00|01|10]Àº: 10.20À¸·Î ¾÷±×·¹À̵åÇ϶ó

    + +

    HP-UX 10.20˼:

    + +

    ÃÖ±Ù ARPA Transport ÆÐÄ¡ ¸ðÀ½À» ¼³Ä¡ÇÑ´Ù. ±×·¯¸é TCP + ¿¬°áã±â Çؽ¬Å×À̺í Å©±â¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº + 256 °³ÀÌ°í, 2ÀÇ °ÅµìÁ¦°ö°ªÀ¸·Î ÁöÁ¤ÇØ¾ß ÇÑ´Ù. adb·Î Ä¿³ÎÀÇ + *disc* À̹ÌÁö¸¦ ¼öÁ¤ÇÏ¿© ¼³Á¤ÇÑ´Ù. º¯¼ö¸íÀº + tcp_hash_sizeÀÌ´Ù. tcp_hash_size + º¯¼ö°ªÀÌ 32ºñÆ®À̹ǷΠdisc À̹ÌÁö¸¦ ¼öÁ¤ÇÒ¶§ ¹Ýµå½Ã 16ºñÆ® + °ªÀ» ±â·ÏÇÏ´Â "w" ´ë½Å 32ºñÆ® °ªÀ» ±â·ÏÇÏ´Â + "W"¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ¾î¶² °ªÀ» °í¸¦±î? ftp://ftp.cup.hp.com/dist/networking/tools/connhistÀÇ + °á°ú¸¦ º¸°í, ½Ã½ºÅÛ¿¡ Á¸ÀçÇÏ´Â TCP ¿¬°á ÃÑ°³¼ö¸¦ »ìÆìºÁ¶ó. + ÀÌ ¼ýÀÚ¸¦ Çؽ¬Å×À̺í Å©±â·Î ³ª´« °ªÀÌ »ó´çÈ÷ (10 ÀÌÇÏ) ÀÛÀ¸¸é + ÁÁ´Ù. HPÀÇ SPECweb96 °á°ú¿¡¼­ ÀϹÝÀûÀÎ ¼³Á¤À» º¼ ¼ö ÀÖ´Ù. + °á°ú´Â http://www.specbench.org/¿¡ + ÀÖ´Ù. HP-UX ½Ã½ºÅÛÀÌ ÃÊ´ç 1000¹ø SPECweb96 ¿¬°áÀ» ÇÏ´Â °æ¿ì + TIME_WAIT°¡ 60Ãʶó¸é 60,000°³ÀÇ TCP "¿¬°á"À» + ÃßÀûÇÑ´Ù´Â ¶æÀÌ´Ù.

    + +

    ftp://ftp.cup.hp.com/dist/networking/misc/listenq¸¦ + ½ÇÇàÇÏ¿© ½Ã½ºÅÛÀÇ ¿¬°á´ë±âÇà·Ä ±íÀ̸¦ ¾Ë ¼ö ÀÖ´Ù.

    + +

    PA-8000±â¹Ý ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù¸é, ¾ÆÆÄÄ¡ + ½ÇÇàÆÄÀÏÀÌ Å« ÆäÀÌÁöÅ©±â¸¦ »ç¿ëÇϵµ·Ï "chatr"ÇÑ´Ù. ¸í·ÉÀº + "chatr +pi L <½ÇÇàÆÄÀÏ>"ÀÌ´Ù. ½ÇÇàÆÄÀÏÀ» + ½ÇÇàÇÏ´Â GID¿¡ MLOCK ±ÇÇÑÀÌ ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. + MLOCK ºÎ¿©¿¡ ´ëÇؼ­´Â Setprivgrp(1m)¸¦ + Âü°íÇ϶ó. ¼öÁ¤ÈÄ Glance¸¦ ½ÇÇàÇÏ¿© ¼­¹öÀÇ ¸Þ¸ð¸®¿µ¿ªÀ» »ìÆ캸¸é + »ó´çÇÑ text ¼¼±×¸ÕÆ®°¡ Àá°ÜÀÖÀ½À» È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    + +

    ´ÙÁßÇÁ·Î¼¼½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù¸é, ÇÁ·Î¼¼½º¸¦ + ÇÁ·Î¼¼½º¿¡ ¹èÁ¤ÇÏ´Â mpctl()¸¦ »ç¿ëÇÑ ÀÛÀº + ÇÁ·Î±×·¥À» ÀÛ¼ºÇغÁ¶ó. ´Ü¼øÇÑ pid % numcpu + ¾Ë°í¸®ÁòÀ¸·Îµµ ÃæºÐÇÒ °ÍÀÌ´Ù. ÀÌ ºÎºÐÀº ¾ÕÀ¸·Î ¼Ò½ºÄڵ忡 + Æ÷Ç﵃ ¼ö ÀÖ´Ù.

    + +

    FIN_WAIT_2 ¿¬°áÀÇ °³¼ö°¡ °ÆÁ¤½º·´´Ù¸é, + nettuneÀ» »ç¿ëÇÏ¿© tcp_keepstart °ªÀ» ÁÙÀÏ + ¼ö ÀÖ´Ù. ±×·¯³ª Á¶½ÉÇØ¾ß ÇÑ´Ù - 4ºÐ º¸´Ù ÀÛ°Ô ¼³Á¤ÇÏÁö ¸¶¶ó. + tcp_hash_size¸¦ Àß ¼³Á¤ÇÏ¿´´Ù¸é, + FIN_WAIT_2 °ªÀÌ Ä¿µµ (½ÉÁö¾î ±âº»°ªÀÎ 2½Ã°£µµ) + ¹®Á¦¾ø´Ù - º¸Åë ¼º´É¿¡ Å« ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù.

    + +

    ¾ÕÀ¸·Î ¼Ò½ºÄڵ忡 Æ÷Ç﵃ ºÎºÐÀÌ ´õ ÀÖÁö¸¸, ¿©±â¼­ ÁÙÀδÙ. + °ü½ÉÀÌ ÀÖ´Ù¸é ¸ÞÀÏÀ» ÁÖ±æ ¹Ù¶õ´Ù.

    + +

    ±×·³ À̸¸,

    + +

    rick jones

    + +

    http://www.cup.hp.com/netperf/NetperfPage.html

    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/perf-hp.xml b/trunk/docs/manual/platform/perf-hp.xml new file mode 100644 index 0000000000..1554acc9dd --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.xml @@ -0,0 +1,113 @@ + + + + + + + + + Platform Specific Notes + + Running a High-Performance Web Server on HPUX + + + +
    +Date: Wed, 05 Nov 1997 16:59:34 -0800
    +From: Rick Jones <raj@cup.hp.com>
    +Reply-To: raj@cup.hp.com
    +Organization: Network Performance
    +Subject: HP-UX tuning tips
    +
    + +

    Here are some tuning tips for HP-UX to add to the tuning page.

    + +

    For HP-UX 9.X: Upgrade to 10.20
    + For HP-UX 10.[00|01|10]: Upgrade to 10.20

    + +

    For HP-UX 10.20:

    + +

    Install the latest cumulative ARPA Transport Patch. This + will allow you to configure the size of the TCP connection + lookup hash table. The default is 256 buckets and must be set + to a power of two. This is accomplished with adb against the + *disc* image of the kernel. The variable name is tcp_hash_size. + Notice that it's critically important that you use "W" + to write a 32 bit quantity, not "w" to write a 16 bit + value when patching the disc image because the tcp_hash_size + variable is a 32 bit quantity.

    + +

    How to pick the value? Examine the output of ftp://ftp.cup.hp.com/dist/networking/tools/connhist + and see how many total TCP connections exist on the system. You + probably want that number divided by the hash table size to be + reasonably small, say less than 10. Folks can look at HP's + SPECweb96 disclosures for some common settings. These can be + found at http://www.specbench.org/. + If an HP-UX system was performing at 1000 SPECweb96 connections + per second, the TIME_WAIT time of 60 seconds would mean + 60,000 TCP "connections" being tracked.

    + +

    Folks can check their listen queue depths with ftp://ftp.cup.hp.com/dist/networking/misc/listenq.

    + +

    If folks are running Apache on a PA-8000 based system, they + should consider "chatr'ing" the Apache executable to have a + large page size. This would be "chatr +pi L <BINARY>". + The GID of the running executable must have MLOCK privileges. + Setprivgrp(1m) should be consulted for assigning + MLOCK. The change can be validated by running Glance + and examining the memory regions of the server(s) to make sure that + they show a non-trivial fraction of the text segment being locked.

    + +

    If folks are running Apache on MP systems, they might + consider writing a small program that uses mpctl() + to bind processes to processors. A simple pid % numcpu + algorithm is probably sufficient. This might even go into the + source code.

    + +

    If folks are concerned about the number of FIN_WAIT_2 + connections, they can use nettune to shrink the value of + tcp_keepstart. However, they should be careful there - + certainly do not make it less than oh two to four minutes. If + tcp_hash_size has been set well, it is probably OK to + let the FIN_WAIT_2's take longer to timeout (perhaps + even the default two hours) - they will not on average have a big + impact on performance.

    + +

    There are other things that could go into the code base, but + that might be left for another email. Feel free to drop me a + message if you or others are interested.

    + +

    sincerely,

    + +

    rick jones

    + +

    http://www.cup.hp.com/netperf/NetperfPage.html

    + +
    + +
    + + diff --git a/trunk/docs/manual/platform/perf-hp.xml.ko b/trunk/docs/manual/platform/perf-hp.xml.ko new file mode 100644 index 0000000000..88434ad476 --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.xml.ko @@ -0,0 +1,107 @@ + + + + + + + + + Platform Specific Notes + + HPUX¿¡¼­ °í¼º´É À¥¼­¹ö ½ÇÇàÇϱâ + + + +
    +Date: Wed, 05 Nov 1997 16:59:34 -0800
    +From: Rick Jones <raj@cup.hp.com>
    +Reply-To: raj@cup.hp.com
    +Organization: Network Performance
    +Subject: HP-UX tuning tips
    +
    + +

    ÀÌ ±ÛÀº ¼º´ÉÇâ»ó ÆäÀÌÁö¿¡ Ãß°¡ÇÒ HP-UX ¼º´ÉÇâ»ó ÆÁÀÌ´Ù.

    + +

    HP-UX 9.X´Â: 10.20À¸·Î ¾÷±×·¹À̵åÇ϶ó
    + HP-UX 10.[00|01|10]Àº: 10.20À¸·Î ¾÷±×·¹À̵åÇ϶ó

    + +

    HP-UX 10.20˼:

    + +

    ÃÖ±Ù ARPA Transport ÆÐÄ¡ ¸ðÀ½À» ¼³Ä¡ÇÑ´Ù. ±×·¯¸é TCP + ¿¬°áã±â Çؽ¬Å×À̺í Å©±â¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº + 256 °³ÀÌ°í, 2ÀÇ °ÅµìÁ¦°ö°ªÀ¸·Î ÁöÁ¤ÇØ¾ß ÇÑ´Ù. adb·Î Ä¿³ÎÀÇ + *disc* À̹ÌÁö¸¦ ¼öÁ¤ÇÏ¿© ¼³Á¤ÇÑ´Ù. º¯¼ö¸íÀº + tcp_hash_sizeÀÌ´Ù. tcp_hash_size + º¯¼ö°ªÀÌ 32ºñÆ®À̹ǷΠdisc À̹ÌÁö¸¦ ¼öÁ¤ÇÒ¶§ ¹Ýµå½Ã 16ºñÆ® + °ªÀ» ±â·ÏÇÏ´Â "w" ´ë½Å 32ºñÆ® °ªÀ» ±â·ÏÇÏ´Â + "W"¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ¾î¶² °ªÀ» °í¸¦±î? ftp://ftp.cup.hp.com/dist/networking/tools/connhistÀÇ + °á°ú¸¦ º¸°í, ½Ã½ºÅÛ¿¡ Á¸ÀçÇÏ´Â TCP ¿¬°á ÃÑ°³¼ö¸¦ »ìÆìºÁ¶ó. + ÀÌ ¼ýÀÚ¸¦ Çؽ¬Å×À̺í Å©±â·Î ³ª´« °ªÀÌ »ó´çÈ÷ (10 ÀÌÇÏ) ÀÛÀ¸¸é + ÁÁ´Ù. HPÀÇ SPECweb96 °á°ú¿¡¼­ ÀϹÝÀûÀÎ ¼³Á¤À» º¼ ¼ö ÀÖ´Ù. + °á°ú´Â http://www.specbench.org/¿¡ + ÀÖ´Ù. HP-UX ½Ã½ºÅÛÀÌ ÃÊ´ç 1000¹ø SPECweb96 ¿¬°áÀ» ÇÏ´Â °æ¿ì + TIME_WAIT°¡ 60Ãʶó¸é 60,000°³ÀÇ TCP "¿¬°á"À» + ÃßÀûÇÑ´Ù´Â ¶æÀÌ´Ù.

    + +

    ftp://ftp.cup.hp.com/dist/networking/misc/listenq¸¦ + ½ÇÇàÇÏ¿© ½Ã½ºÅÛÀÇ ¿¬°á´ë±âÇà·Ä ±íÀ̸¦ ¾Ë ¼ö ÀÖ´Ù.

    + +

    PA-8000±â¹Ý ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù¸é, ¾ÆÆÄÄ¡ + ½ÇÇàÆÄÀÏÀÌ Å« ÆäÀÌÁöÅ©±â¸¦ »ç¿ëÇϵµ·Ï "chatr"ÇÑ´Ù. ¸í·ÉÀº + "chatr +pi L <½ÇÇàÆÄÀÏ>"ÀÌ´Ù. ½ÇÇàÆÄÀÏÀ» + ½ÇÇàÇÏ´Â GID¿¡ MLOCK ±ÇÇÑÀÌ ¹Ýµå½Ã ÇÊ¿äÇÏ´Ù. + MLOCK ºÎ¿©¿¡ ´ëÇؼ­´Â Setprivgrp(1m)¸¦ + Âü°íÇ϶ó. ¼öÁ¤ÈÄ Glance¸¦ ½ÇÇàÇÏ¿© ¼­¹öÀÇ ¸Þ¸ð¸®¿µ¿ªÀ» »ìÆ캸¸é + »ó´çÇÑ text ¼¼±×¸ÕÆ®°¡ Àá°ÜÀÖÀ½À» È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    + +

    ´ÙÁßÇÁ·Î¼¼½º ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù¸é, ÇÁ·Î¼¼½º¸¦ + ÇÁ·Î¼¼½º¿¡ ¹èÁ¤ÇÏ´Â mpctl()¸¦ »ç¿ëÇÑ ÀÛÀº + ÇÁ·Î±×·¥À» ÀÛ¼ºÇغÁ¶ó. ´Ü¼øÇÑ pid % numcpu + ¾Ë°í¸®ÁòÀ¸·Îµµ ÃæºÐÇÒ °ÍÀÌ´Ù. ÀÌ ºÎºÐÀº ¾ÕÀ¸·Î ¼Ò½ºÄڵ忡 + Æ÷Ç﵃ ¼ö ÀÖ´Ù.

    + +

    FIN_WAIT_2 ¿¬°áÀÇ °³¼ö°¡ °ÆÁ¤½º·´´Ù¸é, + nettuneÀ» »ç¿ëÇÏ¿© tcp_keepstart °ªÀ» ÁÙÀÏ + ¼ö ÀÖ´Ù. ±×·¯³ª Á¶½ÉÇØ¾ß ÇÑ´Ù - 4ºÐ º¸´Ù ÀÛ°Ô ¼³Á¤ÇÏÁö ¸¶¶ó. + tcp_hash_size¸¦ Àß ¼³Á¤ÇÏ¿´´Ù¸é, + FIN_WAIT_2 °ªÀÌ Ä¿µµ (½ÉÁö¾î ±âº»°ªÀÎ 2½Ã°£µµ) + ¹®Á¦¾ø´Ù - º¸Åë ¼º´É¿¡ Å« ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù.

    + +

    ¾ÕÀ¸·Î ¼Ò½ºÄڵ忡 Æ÷Ç﵃ ºÎºÐÀÌ ´õ ÀÖÁö¸¸, ¿©±â¼­ ÁÙÀδÙ. + °ü½ÉÀÌ ÀÖ´Ù¸é ¸ÞÀÏÀ» ÁÖ±æ ¹Ù¶õ´Ù.

    + +

    ±×·³ À̸¸,

    + +

    rick jones

    + +

    http://www.cup.hp.com/netperf/NetperfPage.html

    + +
    + +
    + + diff --git a/trunk/docs/manual/platform/perf-hp.xml.meta b/trunk/docs/manual/platform/perf-hp.xml.meta new file mode 100644 index 0000000000..235aa32801 --- /dev/null +++ b/trunk/docs/manual/platform/perf-hp.xml.meta @@ -0,0 +1,12 @@ + + + + perf-hp + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/platform/win_compiling.html b/trunk/docs/manual/platform/win_compiling.html new file mode 100644 index 0000000000..6f9885da14 --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.html @@ -0,0 +1,7 @@ +URI: win_compiling.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: win_compiling.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/win_compiling.html.en b/trunk/docs/manual/platform/win_compiling.html.en new file mode 100644 index 0000000000..38418cbf4e --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.html.en @@ -0,0 +1,426 @@ + + + +Compiling Apache for Microsoft Windows - Apache HTTP Server + + + + + +
    <-
    +

    Compiling Apache for Microsoft Windows

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    There are many important points before you begin compiling + Apache. See Using Apache with Microsoft + Windows before you begin.

    + +
    + +
    top
    +
    +

    Requirements

    + + + +

    Compiling Apache requires the following environment to be + properly installed:

    + +
      +
    • +

      Disk Space

      +

      Make sure you have at least 50 MB of free disk space + available. After installation Apache requires approximately + 10 MB of disk space, plus space for log and cache files, + which can grow rapidly. The actual disk space requirements + will vary considerably based on your chosen configuration and + any third-party modules or libraries.

      +
    • + +
    • +

      Microsoft Visual C++ 5.0 or higher.

      +

      Apache can be built using the command line tools, or from + within the Visual Studio IDE Workbench. The command line + build requires the environment to reflect the PATH, + INCLUDE, LIB and other variables + that can be configured with the vcvars32 batch file:

      + +

      + "c:\Program Files\DevStudio\VC\Bin\vcvars32.bat" +

      +
    • + +
    • +

      The Windows Platform SDK.

      +

      Visual C++ 5.0 builds require an updated Microsoft Windows + Platform SDK to enable some Apache features. For command line + builds, the Platform SDK environment is prepared by the + setenv batch file:

      + +

      + "c:\Program Files\Platform SDK\setenv.bat" +

      + +

      The Platform SDK files distributed with Visual C++ 6.0 and + later are sufficient, so users of later version may skip + this requirement.

      + +
      Note that the Windows Platform SDK update is required + to enable all supported mod_isapi features. + Without a recent update, Apache will issue warnings under + MSVC++ 5.0 that some mod_isapi features + will be disabled. Look for the update at http://msdn.microsoft.com/downloads/sdks/platform/platform.asp.
      +
    • + +
    • +

      The awk utility (awk, gawk or similar).

      +

      To install Apache within the build system, several files are + modified using the awk.exe utility. awk was chosen since it + is a very small download (compared with Perl or WSH/VB) and + accomplishes the task of generating files. Brian Kernighan's + http://cm.bell-labs.com/cm/cs/who/bwk/ + site has a compiled native Win32 binary, + http://cm.bell-labs.com/cm/cs/who/bwk/awk95.exe which + you must save with the name awk.exe rather than + awk95.exe.

      + +
      Note that Developer Studio IDE will only find + awk.exe from the Tools menu Options... Directories + tab (the Projects - VC++ Directories pane in Developer Studio 7.0) + listing Executable file paths. Add the path for awk.exe + to this list, and your system PATH environment variable, + as needed.
      + +
      Also note that if you are using Cygwin (http://www.cygwin.com/) the awk utility is named gawk.exe and + that the file awk.exe is really a symlink to the gawk.exe + file. The Windows command shell does not recognize symlinks, and because of that + building InstallBin will fail. A workaround is to delete awk.exe from + the cygwin installation and rename gawk.exe to awk.exe.
      +
    • + +
    • +

      [Optional] OpenSSL libraries (for mod_ssl + and ab.exe with ssl support)

      +

      Caution: there are significant restrictions and + prohibitions on the use and distribution of strong cryptography + and patented intellectual property throughout the world. + OpenSSL includes strong cryptography controlled by both export + regulations and domestic law, as well as intellectual property + protected by patent, in the United States and elsewhere. Neither + the Apache Software Foundation nor the OpenSSL project can provide + legal advise regarding possession, use, or distribution of the code + provided by the OpenSSL project. Consult your own legal + counsel, you are responsible for your own actions.

      + +

      OpenSSL must be installed into a srclib subdirectory named + openssl, obtained from http://www.openssl.org/source/, in order to compile mod_ssl + or the abs project (ab.exe with SSL support.) To prepare OpenSSL + for both release and debug builds of Apache, and + disable the patent protected features in 0.9.7, you might use the following + build commands:

      + +

      + perl Configure VC-WIN32
      + perl util\mkfiles.pl >MINFO
      + perl util\mk1mf.pl dll no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile
      + perl util\mk1mf.pl dll debug no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile.dbg
      + perl util\mkdef.pl 32 libeay no-asm no-mdc2 no-rc5 no-idea >ms\libeay32.def
      + perl util\mkdef.pl 32 ssleay no-asm no-mdc2 no-rc5 no-idea >ms\ssleay32.def
      + nmake
      + nmake -f makefile.dbg +

      + +
    • + +
    • +

      [Optional] zlib sources (for mod_deflate)

      +

      Zlib must be installed into a srclib subdirectory named + zlib, however those sources need not be compiled. The build system + will compile the compression sources directly into the mod_deflate + module. Zlib can be obtained from http://www.gzip.org/zlib/ -- mod_deflate is + confirmed to build correctly with version 1.1.4.

      +
    • + +
    + +
    top
    +
    +

    Command-Line Build

    + + + +

    First, unpack the Apache distribution into an appropriate + directory. Open a command-line prompt and cd to that + directory.

    + +

    The master Apache makefile instructions are contained in the + Makefile.win file. To compile Apache on Windows + NT, simply use one of the following commands to compiled the + release or debug build, respectively:

    + +
    +nmake /f Makefile.win _apacher
    +
    +nmake /f Makefile.win _apached
    +    
    + +

    Either command will compile Apache. The latter will include + debugging information in the resulting files, making it easier + to find bugs and track down problems.

    + +
    top
    +
    +

    Developer Studio Workspace IDE Build

    + + + +

    Apache can also be compiled using VC++'s Visual Studio + development environment. To simplify this process, a + Visual Studio workspace, Apache.dsw, is provided. + This workspace exposes the entire list of working .dsp + projects that are required for the complete Apache binary release. + It includes dependencies between the projects to assure that they + are built in the appropriate order.

    + +

    Open the Apache.dsw workspace, and select + InstallBin (Release or Debug build, + as desired) as the Active Project. InstallBin causes all + related project to be built, and then invokes Makefile.win to + move the compiled executables and dlls. You may personalize the + INSTDIR= choice by changing InstallBin's Settings, + General tab, Build command line entry. INSTDIR defaults to the + /Apache2 directory. If you only want a test compile (without + installing) you may build the BuildBin project instead.

    + +

    The .dsp project files are distributed in Visual + C++ 6.0 format. Visual C++ 5.0 (97) will recognize them. Visual C++ + 7.0 (.net) must convert Apache.dsw plus the .dsp + files into an Apache.sln plus .msproj files, + be sure you reconvert the .msproj file if any of the source + .dsp files change! This is really trivial, just open + Apache.dsw in the VC++ 7.0 IDE once again.

    + +

    Visual C++ 7.0 (.net) users should also use the Build + menu, Configuration Manager dialog to uncheck both the Debug + and Release Solution modules abs, mod_ssl + and mod_deflate. + These modules are built by invoking nmake or the IDE directly + with the BinBuild target to build those modules explicitly, + only if the srclib directories openssl + and/or zlib exist.

    + +

    Exported .mak files pose a greater hassle, but they are + required for Visual C++ 5.0 users to build mod_ssl, + abs (ab with SSL support) and/or + mod_deflate. + VC++ 7.0 (.net) users also benefit, nmake builds + are faster than binenv builds. + Build the entire project from within the VC++ 5.0 or 6.0 IDE, + then use the Project Menu Export for all makefiles. + You must build the projects first in order to create all dynamic + auto-generated targets, so that dependencies can be parsed + correctly. Run the following command to fix the paths so they + will build anywhere:

    + +

    + perl srclib\apr\build\fixwin32mak.pl +

    + +

    You must type this command from the top level + directory of the httpd source tree. Every + .mak and .dep project file within + the current directory and below will be corrected, and the + timestamps adjusted to reflect the .dsp.

    + +

    If you contribute back a patch that revises project files, we + must commit project files in Visual Studio 6.0 format. Changes + should be simple, with minimal compilation and linkage flags that + will be recognized by all VC++ 5.0 through 7.0 environments.

    + +
    top
    +
    +

    Project Components

    + + + +

    The Apache.dsw workspace and makefile.win + nmake script both build the .dsp projects + of the Apache server in the following sequence:

    + +
      +
    1. srclib\apr\apr.dsp
    2. + +
    3. srclib\apr\libapr.dsp
    4. + +
    5. srclib\apr-util\uri\gen_uri_delims.dsp
    6. + +
    7. srclib\apr-util\xml\expat\lib\xml.dsp
    8. + +
    9. srclib\apr-util\aprutil.dsp
    10. + +
    11. srclib\apr-util\libaprutil.dsp
    12. + +
    13. srclib\pcre\dftables.dsp
    14. + +
    15. srclib\pcre\pcre.dsp
    16. + +
    17. srclib\pcre\pcreposix.dsp
    18. + +
    19. server\gen_test_char.dsp
    20. + +
    21. libhttpd.dsp
    22. + +
    23. Apache.dsp
    24. +
    + +

    In addition, the modules\ subdirectory tree contains + project files for the majority of the modules.

    + +

    The support\ directory contains project files for + additional programs that are not part of the Apache runtime, + but are used by the administrator to test Apache and maintain + password and log files. Windows-specific support projects are + broken out in the support\win32\ directory.

    + +
      +
    1. support\ab.dsp
    2. + +
    3. support\htdigest.dsp
    4. + +
    5. support\htpasswd.dsp
    6. + +
    7. support\logresolve.dsp
    8. + +
    9. support\rotatelogs.dsp
    10. + +
    11. support\win32\ApacheMonitor.dsp
    12. + +
    13. support\win32\wintty.dsp
    14. +
    + +

    Once Apache has been compiled, it needs to be installed in + its server root directory. The default is the + \Apache2 directory, of the same drive.

    + +

    To build and install all the files into the desired folder + dir automatically, use one of the following + nmake commands:

    + +
    +nmake /f Makefile.win installr INSTDIR=dir
    +
    +nmake /f Makefile.win installd INSTDIR=dir
    +    
    + +

    The dir argument to INSTDIR gives + the installation directory; it can be omitted if Apache is + to be installed into \Apache2.

    + +

    This will install the following:

    + +
      +
    • dir\bin\Apache.exe - Apache + executable
    • + +
    • dir\bin\ApacheMonitor.exe - Service + monitor taskbar icon utility
    • + +
    • dir\bin\htdigest.exe - Digest auth + password file utility
    • + +
    • dir\bin\htdbm.exe - SDBM auth + database password file utility
    • + +
    • dir\bin\htpasswd.exe - Basic auth + password file utility
    • + +
    • dir\bin\logresolve.exe - Log file + dns name lookup utility
    • + +
    • dir\bin\rotatelogs.exe - Log file + cycling utility
    • + +
    • dir\bin\wintty.exe - Console window + utility
    • + +
    • dir\bin\libapr.dll - Apache + Portable Runtime shared library
    • + +
    • dir\bin\libaprutil.dll - Apache + Utility Runtime shared library
    • + +
    • dir\bin\libhttpd.dll - Apache Core + library
    • + +
    • dir\modules\mod_*.so - Loadable + Apache modules
    • + +
    • dir\conf - Configuration + directory
    • + +
    • dir\logs - Empty logging + directory
    • + +
    • dir\include - C language header + files
    • + +
    • dir\lib - Link library files
    • +
    + +

    Warning about building Apache from the development tree

    + + + +
    Note only the .dsp files are maintained between release + builds. The .mak files are NOT regenerated, due to the tremendous + waste of reviewer's time. Therefore, you cannot rely on the NMAKE + commands above to build revised .dsp project files unless you + then export all .mak files yourself from the project. This is + unnecessary if you build from within the Microsoft + Developer Studio environment.
    + +
    Also note it is very worthwhile to build the BuildBin + target project (or the command line _apacher or + _apached target) prior to exporting the make files. + Many files are autogenerated in the build process. Only a full + build provides all of the dependent files required to build proper + dependency trees for correct build behavior.
    + +

    In order to create distribution .mak files, always review + the generated .mak (or .dep) dependencies for + Platform SDK or other garbage includes. The DevStudio\SharedIDE\bin\ + (VC5) or DevStudio\Common\MSDev98\bin\ (VC6) directory contains + the sysincl.dat file, which must list all exceptions. Update this + file (including both forward and backslashed paths, such as both + sys/time.h and sys\time.h) to include such dependencies. + Including local-install paths in a distributed .mak file will + cause the build to fail completely. And don't forget to run + srclib/apr/build/fixwin32mak.pl in order to fix absolute + paths within the .mak files.

    + + + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/win_compiling.html.ko.euc-kr b/trunk/docs/manual/platform/win_compiling.html.ko.euc-kr new file mode 100644 index 0000000000..746879c045 --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.html.ko.euc-kr @@ -0,0 +1,423 @@ + + + +Microsoft Windows¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ - Apache HTTP Server + + + + + +
    <-
    +

    Microsoft Windows¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ÁÖÀÇÇÒ Á¡ÀÌ ¸¹´Ù. ¹Ì¸® Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¹ýÀ» + Âü°íÇ϶ó.

    + +
    + +
    top
    +
    +

    ¿ä±¸»çÇ×

    + + + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é ´ÙÀ½ÀÌ Á¤»óÀûÀ¸·Î ¼³Ä¡µÇ¾ß ÇÑ´Ù:

    + +
      +
    • +

      µð½ºÅ© °ø°£

      +

      ³²Àº µð½ºÅ© °ø°£ÀÌ ÃÖ¼ÒÇÑ 50 MB´Â µÇ¾ß ÇÑ´Ù. ¾ÆÆÄÄ¡ + ¼³Ä¡ÈÄ¿¡´Â »¡¸® Áõ°¡ÇÏ´Â ·Î±×¿Í ij½¬ÆÄÀÏÀ» Á¦¿ÜÇÏ°í + ¾à 10 MB Á¤µµ°¡ ÇÊ¿äÇÏ´Ù. ½ÇÁ¦ µð½ºÅ© »ç¿ë·®Àº ¼±ÅÃÇÑ + ±¸¼º°ú Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ ȤÀº ¶óÀ̺귯¸®¿¡ µû¶ó Å©°Ô + ´Ù¸£´Ù.

      +
    • + +
    • +

      Microsoft Visual C++ 5.0 ÀÌ»ó.

      +

      ¾ÆÆÄÄ¡´Â ¸í·ÉÇà µµ±¸¸¦ »ç¿ëÇϰųª Visual Studio IDE + Workbench ¾È¿¡¼­ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. ¸í·ÉÇà¿¡¼­ ÄÄÆÄÀÏÇÑ´Ù¸é + vcvars32 ¹èÄ¡ÆÄÀÏÀÌ ¼³Á¤ÇÏ´Â PATH, + INCLUDE, LIB µî ȯ°æº¯¼ö°¡ + ÇÊ¿äÇÏ´Ù:

      + +

      + "c:\Program Files\DevStudio\VC\Bin\vcvars32.bat" +

      +
    • + +
    • +

      Windows Platform SDK.

      +

      ¾î¶² ¾ÆÆÄÄ¡ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é Visual C++ 5.0¿¡ Ãß°¡·Î + ÃֽŠMicrosoft Windows Platform SDK°¡ ÇÊ¿äÇÏ´Ù. ¸í·ÉÇà¿¡¼­ + ÄÄÆÄÀÏÇÑ´Ù¸é setenv ¹èÄ¡ÆÄÀÏÀÌ Platform + SDK ȯ°æÀ» ¸¸µç´Ù:

      + +

      + "c:\Program Files\Platform SDK\setenv.bat" +

      + +

      Visual C++ 6.0 ÀÌ»ó¿¡ Æ÷ÇÔµÈ Platform SDK ÆÄÀÏÀº + ÃæºÐÇÏ´Ù. ÀÌ ¹öÀüÀ» »ç¿ëÇÏ´Â »ç¿ëÀÚ´Â ÀÌ °úÁ¤À» »ý·«Çصµ + µÈ´Ù.

      + +
      ¸ðµç mod_isapi ±â´ÉÀ» »ç¿ëÇÏ·Á¸é + ÃֽŠWindows Platform SDK°¡ ÇÊ¿äÇÏ´Ù. ÃֽŠ¹öÀüÀÌ ¾Æ´Ï¸é + MSVC++ 5.0Àº mod_isapi ±â´ÉÀÇ ÀϺθ¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù°í °æ°íÇÑ´Ù. http://msdn.microsoft.com/downloads/sdks/platform/platform.asp¿¡ + ÃֽŠ¹öÀüÀÌ ÀÖ´Ù.
      +
    • + +
    • +

      awk µµ±¸ (awk, gawk µî).

      +

      ÄÄÆÄÀÏÇÑ ½Ã½ºÅÛ¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ·Á¸é + awk.exe µµ±¸¸¦ »ç¿ëÇÏ¿© ¿©·¯ ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß + ÇÑ´Ù. (PerlÀ̳ª WSH/VB°ú ºñ±³ÇÏ¿©) ´Ù¿î¹Þ±â¿¡ ¸Å¿ì ÀÛ°í + ÆÄÀÏ »ý¼º ÀÛ¾÷ÀÌ °¡´ÉÇÏ¿© awk¸¦ ¼±ÅÃÇß´Ù. Brian KernighanÀÇ + http://cm.bell-labs.com/cm/cs/who/bwk/ »çÀÌÆ®¿¡ + ÄÄÆÄÀÏµÈ Win32 ½ÇÇàÆÄÀÏ http://cm.bell-labs.com/cm/cs/who/bwk/awk95.exeÀÌ + ÀÖ´Ù. À̸§À» awk95.exe ´ë½Å + awk.exe·Î º¯°æÇØ¾ß ÇÑ´Ù.

      + +
      Developer Studio IDE´Â Tools ¸Þ´º Options... + Directories ÅÇÀÇ (Developer Studio 7.0À̶ó¸é Projects + - VC++ Directories pane) Executable files °æ·Î ¸ñ·Ï¿¡¼­¸¸ + awk.exe¸¦ ã´Â´Ù. ÀÌ ¸ñ·Ï¿¡ awk.exe + °æ·Î¸¦ Ãß°¡ÇÏ°í, ÇÊ¿äÇÏ´Ù¸é PATH ȯ°æº¯¼ö¿¡µµ + Ãß°¡ÇÑ´Ù.
      + +
      CygwinÀ» (http://www.cygwin.com/) »ç¿ëÇÑ´Ù¸é + gawk.exe¶ó´Â À̸§À¸·Î awk µµ±¸°¡ ÀÖÀ¸¸ç, + awk.exe ÆÄÀÏÀº gawk.exe ÆÄÀÏÀÇ + ½Éº¼¸µÅ©ÀÓÀ» ÁÖÀÇÇ϶ó. Windows ¸í·É ÇÁ·ÒÇÁÆ®°¡ ½Éº¼¸µÅ©¸¦ + ÀνÄÇÏÁö ¸øÇϱ⶧¹®¿¡ InstallBinÀ» ÄÄÆÄÀÏÇÒ¶§ ½ÇÆÐÇÑ´Ù. + ÇØ°áÃ¥Àº cygwin¿¡¼­ awk.exe¸¦ »èÁ¦ÇÏ°í + gawk.exe À̸§À» awk.exe·Î + ¹Ù²Û´Ù.
      +
    • + +
    • +

      [¼±ÅÃÀûÀÎ] OpenSSL ¶óÀ̺귯¸® (mod_ssl°ú + ab.exeÀÇ ssl Áö¿ø¿¡ »ç¿ë)

      +

      ÁÖÀÇ: °­·ÂÇÑ ¾Ïȣȭ¿Í ƯÇã°¡ °É¸° ÁöÀûÀç»ê±ÇÀ» + Àü¼¼°è¿¡ ¹èÆ÷Çϴµ¥´Â »ó´çÇÑ Á¦¾àÀÌ ÀÖ´Ù. + OpenSSLÀº ¹Ì±¹ ¼öÃâ±ÔÁ¦¹ýÀÌ ±ÔÁ¦ÇÏ¸ç ¹Ì±¹°ú ±âŸ Áö¿ª¿¡¼­ + ƯÇã·Î º¸È£µÇ´Â ÁöÀûÀç»ê±ÇÀÎ °­·ÂÇÑ ¾Ïȣȭ¸¦ Æ÷ÇÔÇÑ´Ù. + Apache Software Foundation°ú OpenSSL ÇÁ·ÎÁ§Æ®´Â OpenSSL + ÇÁ·ÎÁ§Æ®°¡ Á¦°øÇÏ´Â Äڵ带 ¼ÒÀ¯, »ç¿ë, ¹èÆ÷Çϴµ¥ µû¸¥ + ¹ýÀû ÀÚ¹®À» Á¦°øÇÏÁö ¾Ê´Â´Ù. Á÷Á¢ ¹ý·ü »ó´ãÀ» + ¹Þ±æ ¹Ù¶õ´Ù. ´ç½Å ÇൿÀÇ Ã¥ÀÓÀº ´ç½Å¿¡°Ô ÀÖ´Ù.

      + +

      mod_sslÀ̳ª (SSLÀ» Áö¿øÇÏ´Â + ab.exe) abs ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ·Á¸é, OpenSSLÀ» + http://www.openssl.org/source/¿¡¼­ ´Ù¿î¹Þ¾Æ¼­ + srclibÀÇ opensslÀ̶ó´Â + ÇÏÀ§µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÑ´Ù. release¿Í + debug·Î ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇϸç 0.9.7 + ¹öÀü¿¡ Àִ ƯÇã°¡ °É¸° ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é, ¾Æ·¡ + ÄÄÆÄÀÏ ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù:

      + +

      + perl Configure VC-WIN32
      + perl util\mkfiles.pl >MINFO
      + perl util\mk1mf.pl dll no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile
      + perl util\mk1mf.pl dll debug no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile.dbg
      + perl util\mkdef.pl 32 libeay no-asm no-mdc2 no-rc5 no-idea >ms\libeay32.def
      + perl util\mkdef.pl 32 ssleay no-asm no-mdc2 no-rc5 no-idea >ms\ssleay32.def
      + nmake
      + nmake -f makefile.dbg +

      + +
    • + +
    • +

      [¼±ÅÃÀûÀÎ] zlib ¼Ò½º (mod_deflate¿¡ + »ç¿ë)

      +

      ZlibÀ» srclibÀÇ zlib¶ó´Â + ÇÏÀ§µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÏÁö¸¸, ¼Ò½º¸¦ ¹Ì¸® ÄÄÆÄÀÏÇÒ + ÇÊ¿ä´Â ¾ø´Ù. ÄÄÆÄÀÏ ½Ã½ºÅÛÀº ÀÌ ¾ÐÃà¼Ò½º¸¦ + mod_deflate ¸ðµâ°ú °°ÀÌ ÄÄÆÄÀÏÇÑ´Ù. + ZlibÀº http://www.gzip.org/zlib/¿¡¼­ ±¸ÇÒ ¼ö ÀÖ´Ù -- + mod_deflate´Â 1.1.4 ¹öÀü°ú Á¤»óÀûÀ¸·Î + ÄÄÆÄÀϵǾú´Ù.

      +
    • + +
    + +
    top
    +
    +

    ¸í·ÉÇà¿¡¼­ ÄÄÆÄÀÏÇϱâ

    + + + +

    ¸ÕÀú Àû´çÇÑ µð·ºÅ丮¿¡ ¾ÆÆÄÄ¡ ¹èÆ÷º» ¾ÐÃàÀ» Ǭ´Ù. ¸í·ÉÇà + ÇÁ·ÒÇÁÆ®¸¦ ¿­°í ±× µð·ºÅ丮·Î cdÇÑ´Ù.

    + +

    Makefile.win ÆÄÀÏ¿¡ ¾ÆÆÄÄ¡ makefile ¸í·ÉÀÌ + ÀÖ´Ù. Windows NT¿¡¼­ release¿Í debug + ÄÄÆÄÀÏÇÏ´Â ¸í·É¾î´Â °¢°¢ ´ÙÀ½°ú °°´Ù:

    + +
    +nmake /f Makefile.win _apacher
    +
    +nmake /f Makefile.win _apached
    +    
    + +

    µÎ ¸í·É¾î ¸ðµÎ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÑ´Ù. ÈÄÀÚ´Â °á°úÆÄÀÏ¿¡ + µð¹ö±ë Á¤º¸¸¦ Æ÷ÇÔÇÏ¿© ¹ö±×¸¦ ã°í ¹®Á¦¸¦ ÃßÀûÇϱ⠽±°Ô + ÇÑ´Ù.

    + +
    top
    +
    +

    Developer Studio Workspace IDE¿¡¼­ ÄÄÆÄÀÏÇϱâ

    + + + +

    VC++ÀÇ Visual Studio °³¹ß ȯ°æÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ + ¼öµµ ÀÖ´Ù. °úÁ¤À» ½±°Ô ÇÏ·Á°í Visual Studio workspace + Apache.dsw¸¦ Á¦°øÇÑ´Ù. ÀÌ workspace´Â ¿ÏÀüÇÑ + ¾ÆÆÄÄ¡ ¹ÙÀ̳ʸ® ¹èÆ÷º»¿¡ ÇÊ¿äÇÑ .dsp ÇÁ·ÎÁ§Æ® + ¸ñ·ÏÀ» ´ã°íÀÖ´Ù. ¶Ç, ¾Ë¸ÂÀº ¼ø¼­·Î ÄÄÆÄÀÏÇϱâÀ§ÇÑ ÇÁ·ÎÁ§Æ®°£ + ÀÇÁ¸¼º Á¤º¸µµ Æ÷ÇÔÇÑ´Ù.

    + +

    Apache.dsw workspace¸¦ ¿­°í + InstallBinÀ» (Release³ª + Debug Áß ¿øÇÏ´Â °ÍÀ») Active Project·Î ¼±ÅÃÇÑ´Ù. + InstallBinÀº °ü·ÃµÈ ¸ðµç ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ°í, + ÄÄÆÄÀÏµÈ ½ÇÇàÆÄÀÏ°ú dllÀ» ¿Å±â´Â Makefile.winÀ» + È£ÃâÇÑ´Ù. InstallBinÀÇ Settings, General ÅÇ, + Build command line Ç׸ñÀ» ¼öÁ¤ÇÏ¿© INSTDIR=À» + º¯°æÇÒ ¼ö ÀÖ´Ù. INSTDIR= ±âº»°ªÀº + /Apache2 µð·ºÅ丮ÀÌ´Ù. (¼³Ä¡ÇÏÁö¾Ê°í) Å×½ºÆ®·Î + ÄÄÆÄÀϸ¸ Çغ¸·Á¸é ´ë½Å BuildBin ÇÁ·ÎÁ§Æ®¸¦ + »ç¿ëÇÑ´Ù.

    + +

    .dsp ÇÁ·ÎÁ§Æ® ÆÄÀÏÀº Visual C++ 6.0 Çü½ÄÀÌ´Ù. + Visual C++ 5.0 (97)¿¡¼­µµ ÀÌ ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. Visual + C++ 7.0 (.net)Àº Apache.dsw¿Í .dsp + ÆÄÀϵéÀ» Apache.sln°ú .msproj + ÆÄÀϵé·Î º¯È¯ÇÑ´Ù. .dsp ¼Ò½ºÆÄÀÏÀ» ¼öÁ¤Çϸé + ¹Ýµå½Ã .msproj ÆÄÀÏ·Î ´Ù½Ã º¯È¯Ç϶ó! ±×³É VC++ + 7.0 IDE¿¡¼­ Apache.dsw¸¦ ´Ù½Ã ¿­±â¸¸ ÇÏ¸é µÈ´Ù.

    + +

    ¶Ç, Visual C++ 7.0 (.net) »ç¿ëÀÚ´Â Build ¸Þ´º, Configuration + Manager ´ëȭâ¿¡¼­ Debug¿Í ReleaseÀÇ + abs, mod_ssl, mod_deflate + Solution modules ¼±ÅÃÀ» ÇØÁ¦ÇØ¾ß ÇÑ´Ù. srclib¿¡ + opensslÀ̳ª zlib µð·ºÅ丮°¡ ÀÖ´Â + °æ¿ì¿¡¸¸ nmake¸¦ ½ÇÇàÇϰųª (ÀÌ ¸ðµâÀ» ¸í½ÃÀûÀ¸·Î + ÄÄÆÄÀÏÇÏ´Â) IDE BinBuild ´ë»óÀ» »ç¿ëÇÏ¿© ¸ðµâÀ» + ÄÄÆÄÀÏ ÇÒ ¼ö ÀÖ´Ù.

    + +

    ExportÇÑ .mak ÆÄÀϵéÀÌ È¥¶õ½º·´Áö¸¸, Visual + C++ 5.0 »ç¿ëÀÚ°¡ mod_ssl, abs (SSLÀ» Áö¿øÇÏ´Â + ab), mod_deflate¸¦ ÄÄÆÄÀÏÇÒ¶§ ÇÊ¿äÇÏ´Ù. + VC++ 7.0 (.net) »ç¿ëÀÚ¿¡°Ôµµ binenv º¸´Ù + nmake¸¦ »ç¿ëÇϸé ÄÄÆÄÀÏÀÌ ´õ ºü¸£´Ù. VC++ 5.0À̳ª + 6.0 IDE¿¡¼­ Àüü ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ°í, Project ¸Þ´ºÀÇ Export + for all makefiles¸¦ »ç¿ëÇ϶ó. µ¿ÀûÀ¸·Î ÀÚµ¿ »ý¼ºÇÏ´Â ´ë»óÀ» + ¸ðµÎ ÄÄÆÄÀÏÇÏ°í ¿Ã¹Ù¸¥ ÀÇÁ¸¼º Á¤º¸¸¦ ¾ò±âÀ§Çؼ­´Â ¸ÕÀú + ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© °æ·Î¸¦ + ¼öÁ¤ÇÏ¸é ¾î¶² °æ·Î¿¡¼­µµ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù:

    + +

    + perl srclib\apr\build\fixwin32mak.pl +

    + +

    httpd ¼Ò½º ÃÖ»óÀ§ µð·ºÅ丮¿¡¼­ + ¸í·É¾î¸¦ ½ÇÇàÇØ¾ß ÇÑ´Ù. ÇöÀç µð·ºÅ丮¿Í ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â + ¸ðµç .mak¿Í .dep ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» + ¼öÁ¤ÇÏ°í, .dsp¸¦ °í·ÁÇÏ¿© ÆÄÀϽð£À» ¼öÁ¤ÇÑ´Ù.

    + +

    ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» ´Ùµë¾î¼­ ÆÐÄ¡¸¦ º¸³½´Ù¸é, ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» + Visual Studio 6.0 Çü½ÄÀ¸·Î ¸¸µé¾î¾ß ÇÑ´Ù. º¯°æÀº °£´ÜÇÏ°í, + VC++ 5.0¿¡¼­ 7.0±îÁö ¸ðµç ȯ°æ¿¡¼­ ÀνÄÇÏ´Â ÃÖ¼ÒÇÑÀÇ ÄÄÆÄÀÏ + ¿É¼Ç°ú ¸µÄ¿ ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +
    top
    +
    +

    ÇÁ·ÎÁ§Æ® ±¸¼º¿ä¼Ò

    + + + +

    Apache.dsw workspace¿Í makefile.win + nmake ½ºÅ©¸³Æ®´Â ´ÙÀ½ ¼ø¼­´ë·Î ¾ÆÆÄÄ¡ ¼­¹ö + .dsp ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÑ´Ù:

    + +
      +
    1. srclib\apr\apr.dsp
    2. + +
    3. srclib\apr\libapr.dsp
    4. + +
    5. srclib\apr-util\uri\gen_uri_delims.dsp
    6. + +
    7. srclib\apr-util\xml\expat\lib\xml.dsp
    8. + +
    9. srclib\apr-util\aprutil.dsp
    10. + +
    11. srclib\apr-util\libaprutil.dsp
    12. + +
    13. srclib\pcre\dftables.dsp
    14. + +
    15. srclib\pcre\pcre.dsp
    16. + +
    17. srclib\pcre\pcreposix.dsp
    18. + +
    19. server\gen_test_char.dsp
    20. + +
    21. libhttpd.dsp
    22. + +
    23. Apache.dsp
    24. +
    + +

    ¶Ç, modules\ ÇÏÀ§µð·ºÅ丮 ¾Æ·¡ ´ëºÎºÐÀÇ + ¸ðµâ¿¡´Â ÇÁ·ÎÁ§Æ®ÆÄÀÏÀÌ ÀÖ´Ù.

    + +

    support\ µð·ºÅ丮¿¡´Â ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϴµ¥ + ÇÊ¿äÇÏÁö´Â ¾ÊÁö¸¸, °ü¸®ÀÚ°¡ ¾ÆÆÄÄ¡¸¦ °Ë»çÇϰųª ¾ÏÈ£ÆÄÀÏ°ú + ·Î±×ÆÄÀÏÀ» °ü¸®Çϴµ¥ »ç¿ëÇÒ Ãß°¡ ÇÁ·Î±×·¥µéÀÇ ÇÁ·ÎÁ§Æ®ÆÄÀÏÀÌ + ÀÖ´Ù. Windows Àü¿ë Áö¿ø ÇÁ·Î±×·¥Àº support\win32\ + µð·ºÅ丮¿¡ µû·Î ÀÖ´Ù.

    + +
      +
    1. support\ab.dsp
    2. + +
    3. support\htdigest.dsp
    4. + +
    5. support\htpasswd.dsp
    6. + +
    7. support\logresolve.dsp
    8. + +
    9. support\rotatelogs.dsp
    10. + +
    11. support\win32\ApacheMonitor.dsp
    12. + +
    13. support\win32\wintty.dsp
    14. +
    + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϸé server root µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÑ´Ù. + ±âº»°ªÀº °°Àº µð½ºÅ©ÀÇ \Apache2 µð·ºÅ丮ÀÌ´Ù.

    + +

    ÄÄÆÄÀÏÇÏ°í ¸ðµç ÆÄÀÏÀ» ¿øÇÏ´Â Æú´õ dir¿¡ ÀÚµ¿À¸·Î + ¼³Ä¡ÇÏ·Á¸é ´ÙÀ½ nmake ¸í·É¾îÁß Çϳª¸¦ »ç¿ëÇÑ´Ù:

    + +
    +nmake /f Makefile.win installr INSTDIR=dir
    +
    +nmake /f Makefile.win installd INSTDIR=dir
    +    
    + +

    INSTDIRÀÇ dir ¾Æ±Ô¸ÕÆ®´Â ¼³Ä¡µð·ºÅ丮¸¦ + ¶æÇÑ´Ù. »ý¶ôÇϸé \Apache2¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ¼³Ä¡ÇÑ´Ù:

    + +
      +
    • dir\bin\Apache.exe - ¾ÆÆÄÄ¡ + ½ÇÇàÆÄÀÏ
    • + +
    • dir\bin\ApacheMonitor.exe - + ¼­ºñ½º °¨½Ã¿ë ÀÛ¾÷Ç¥½ÃÁÙ ¾ÆÀÌÄÜ µµ±¸
    • + +
    • dir\bin\htdigest.exe - Digest + auth ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\htdbm.exe - SDBM auth + µ¥ÀÌÅͺ£À̽º ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\htpasswd.exe - Basic + auth ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\logresolve.exe - ·Î±×ÆÄÀÏ¿¡¼­ + dns À̸§À» ã´Â µµ±¸
    • + +
    • dir\bin\rotatelogs.exe - ·Î±×ÆÄÀÏ + ¼øȯ µµ±¸
    • + +
    • dir\bin\wintty.exe - ÄܼÖâ + µµ±¸
    • + +
    • dir\bin\libapr.dll - Apache + Portable Runtime °øÀ¯ ¶óÀ̺귯¸®
    • + +
    • dir\bin\libaprutil.dll - Apache + Utility Runtime °øÀ¯ ¶óÀ̺귯¸®
    • + +
    • dir\bin\libhttpd.dll - Apache + Core ¶óÀ̺귯¸®
    • + +
    • dir\modules\mod_*.so - ÀоîµéÀÏ + ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¸ðµâ
    • + +
    • dir\conf - ¼³Á¤ µð·ºÅ丮
    • + +
    • dir\logs - ºñ¾îÀÖ´Â ·Î±× + µð·ºÅ丮
    • + +
    • dir\include - C ¾ð¾î Çì´õÆÄÀÏ
    • + +
    • dir\lib - ¸µÅ© ¶óÀ̺귯¸®ÆÄÀÏ
    • +
    + +

    °³¹ßÁßÀÎ ¾ÆÆÄÄ¡ ¹öÀüÀ» ÄÄÆÄÀÏÇÒ¶§ °æ°í

    + + + +
    .dsp ÆÄÀÏÀº release¸¶´Ù + »õ·Î ¸¸µé¾îÁø´Ù. °³¹ßÀÚÀÇ ½Ã°£³¶ºñ¸¦ ¸·±âÀ§ÇØ + .mak ÆÄÀÏÀº »õ·Î ¸¸µéÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î + NMAKE ¸í·É¾î¸¦ »ç¿ëÇÏ¿© »õ·Î¿î .dsp + ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» ÄÄÆÄÀÏÇÒ ¼ö ¾ø´Ù. ÇÁ·ÎÁ§Æ®¿¡¼­ Á÷Á¢ ¸ðµç + .mak ÆÄÀÏÀ» exportÇØ¾ß ÇÑ´Ù. Microsoft Developer + Studio ȯ°æ¿¡¼­ ÄÄÆÄÀÏÇÑ´Ù¸é ÀÌ ÀÛ¾÷ÀÌ ÇÊ¿ä¾ø´Ù.
    + +
    ¶Ç, makefileÀ» exportÇϱâ Àü¿¡ BuildBin + ÇÁ·ÎÁ§Æ®¸¦ (ȤÀº _apacher³ª _apached + ¸í·ÉÇà ´ë»ó) ÄÄÆÄÀÏÇÏ¸é ¸Å¿ì µµ¿òÀÌ µÈ´Ù. ÄÄÆÄÀÏÁß¿¡ ¸¹Àº + ÆÄÀÏÀÌ ÀÚµ¿À¸·Î ¸¸µé¾îÁø´Ù. Àüü¸¦ ÄÄÆÄÀÏÇؾ߸¸ Á¤»óÀûÀ¸·Î + ÄÄÆÄÀÏÇÒ¶§ ÇÊ¿äÇÑ ÀÇÁ¸ÆÄÀÏÀ» ¸ðµÎ ¸¸µç´Ù.
    + +

    ¹èÆ÷¿ë .mak ÆÄÀÏÀ» ¸¸µå·Á¸é Ç×»ó + .mak (ȤÀº .dep)¿¡¼­ Platform + SDK µîÀÇ ÀÇÁ¸¼ºÀ» Á¡°ËÇ϶ó. + DevStudio\SharedIDE\bin\ (VC5)³ª + DevStudio\Common\MSDev98\bin\ (VC6) µð·ºÅ丮¿¡´Â + ¸ðµç ¿¹¿Ü ¸ñ·ÏÀÌ ´ã±ä sysincl.dat ÆÄÀÏÀÌ + ÀÖ´Ù. ÀÌ ÆÄÀÏ¿¡ ÀÇÁ¸¼º Á¤º¸¸¦ Ãß°¡ÇÑ´Ù + (sys/time.h¿Í sys\time.h¿Í °°ÀÌ, + °æ·Î´Â ½½·¡½¬¸¦ »ç¿ëÇÑ °Í°ú ¹é½½·¡½¬¸¦ »ç¿ëÇÑ °Í ¸ðµÎ¸¦ + Ãß°¡ÇÑ´Ù). ¹èÆ÷ÇÒ .mak ÆÄÀÏ¿¡ ÇöÀç ÄÄÇ»ÅÍ¿¡¸¸ + ÇØ´çÇÏ´Â ¼³Ä¡°æ·Î°¡ ÀÖ´Ù¸é ÄÄÆÄÀÏÀÌ ¿ÏÀüÈ÷ ½ÇÆÐÇÑ´Ù. + ±×·¯¹Ç·Î srclib/apr/build/fixwin32mak.plÀ» + ½ÇÇàÇØÇÏ¿© .mak ÆÄÀÏ¿¡ ÀÖ´Â Àý´ë°æ·Î¸¦ ¾ø¾Ö¾ß + ÇÑ´Ù.

    + + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/win_compiling.xml b/trunk/docs/manual/platform/win_compiling.xml new file mode 100644 index 0000000000..8b069606f9 --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.xml @@ -0,0 +1,427 @@ + + + + + + + + + Platform Specific Notes + + Compiling Apache for Microsoft Windows + + + +

    There are many important points before you begin compiling + Apache. See Using Apache with Microsoft + Windows before you begin.

    + +
    + +
    + + Requirements + +

    Compiling Apache requires the following environment to be + properly installed:

    + +
      +
    • +

      Disk Space

      +

      Make sure you have at least 50 MB of free disk space + available. After installation Apache requires approximately + 10 MB of disk space, plus space for log and cache files, + which can grow rapidly. The actual disk space requirements + will vary considerably based on your chosen configuration and + any third-party modules or libraries.

      +
    • + +
    • +

      Microsoft Visual C++ 5.0 or higher.

      +

      Apache can be built using the command line tools, or from + within the Visual Studio IDE Workbench. The command line + build requires the environment to reflect the PATH, + INCLUDE, LIB and other variables + that can be configured with the vcvars32 batch file:

      + + + "c:\Program Files\DevStudio\VC\Bin\vcvars32.bat" + +
    • + +
    • +

      The Windows Platform SDK.

      +

      Visual C++ 5.0 builds require an updated Microsoft Windows + Platform SDK to enable some Apache features. For command line + builds, the Platform SDK environment is prepared by the + setenv batch file:

      + + + "c:\Program Files\Platform SDK\setenv.bat" + + +

      The Platform SDK files distributed with Visual C++ 6.0 and + later are sufficient, so users of later version may skip + this requirement.

      + + Note that the Windows Platform SDK update is required + to enable all supported mod_isapi features. + Without a recent update, Apache will issue warnings under + MSVC++ 5.0 that some mod_isapi features + will be disabled. Look for the update at http://msdn.microsoft.com/downloads/sdks/platform/platform.asp. +
    • + +
    • +

      The awk utility (awk, gawk or similar).

      +

      To install Apache within the build system, several files are + modified using the awk.exe utility. awk was chosen since it + is a very small download (compared with Perl or WSH/VB) and + accomplishes the task of generating files. Brian Kernighan's + http://cm.bell-labs.com/cm/cs/who/bwk/ + site has a compiled native Win32 binary, + http://cm.bell-labs.com/cm/cs/who/bwk/awk95.exe which + you must save with the name awk.exe rather than + awk95.exe.

      + + Note that Developer Studio IDE will only find + awk.exe from the Tools menu Options... Directories + tab (the Projects - VC++ Directories pane in Developer Studio 7.0) + listing Executable file paths. Add the path for awk.exe + to this list, and your system PATH environment variable, + as needed. + + Also note that if you are using Cygwin (http://www.cygwin.com/) the awk utility is named gawk.exe and + that the file awk.exe is really a symlink to the gawk.exe + file. The Windows command shell does not recognize symlinks, and because of that + building InstallBin will fail. A workaround is to delete awk.exe from + the cygwin installation and rename gawk.exe to awk.exe. +
    • + +
    • +

      [Optional] OpenSSL libraries (for mod_ssl + and ab.exe with ssl support)

      +

      Caution: there are significant restrictions and + prohibitions on the use and distribution of strong cryptography + and patented intellectual property throughout the world. + OpenSSL includes strong cryptography controlled by both export + regulations and domestic law, as well as intellectual property + protected by patent, in the United States and elsewhere. Neither + the Apache Software Foundation nor the OpenSSL project can provide + legal advise regarding possession, use, or distribution of the code + provided by the OpenSSL project. Consult your own legal + counsel, you are responsible for your own actions.

      + +

      OpenSSL must be installed into a srclib subdirectory named + openssl, obtained from http://www.openssl.org/source/, in order to compile mod_ssl + or the abs project (ab.exe with SSL support.) To prepare OpenSSL + for both release and debug builds of Apache, and + disable the patent protected features in 0.9.7, you might use the following + build commands:

      + + + perl Configure VC-WIN32
      + perl util\mkfiles.pl >MINFO
      + perl util\mk1mf.pl dll no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile
      + perl util\mk1mf.pl dll debug no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile.dbg
      + perl util\mkdef.pl 32 libeay no-asm no-mdc2 no-rc5 no-idea >ms\libeay32.def
      + perl util\mkdef.pl 32 ssleay no-asm no-mdc2 no-rc5 no-idea >ms\ssleay32.def
      + nmake
      + nmake -f makefile.dbg +
      + +
    • + +
    • +

      [Optional] zlib sources (for mod_deflate)

      +

      Zlib must be installed into a srclib subdirectory named + zlib, however those sources need not be compiled. The build system + will compile the compression sources directly into the mod_deflate + module. Zlib can be obtained from http://www.gzip.org/zlib/ -- mod_deflate is + confirmed to build correctly with version 1.1.4.

      +
    • + +
    + +
    + +
    + + Command-Line Build + +

    First, unpack the Apache distribution into an appropriate + directory. Open a command-line prompt and cd to that + directory.

    + +

    The master Apache makefile instructions are contained in the + Makefile.win file. To compile Apache on Windows + NT, simply use one of the following commands to compiled the + release or debug build, respectively:

    + +
    +nmake /f Makefile.win _apacher
    +
    +nmake /f Makefile.win _apached
    +    
    + +

    Either command will compile Apache. The latter will include + debugging information in the resulting files, making it easier + to find bugs and track down problems.

    + +
    + +
    + + Developer Studio Workspace IDE Build + +

    Apache can also be compiled using VC++'s Visual Studio + development environment. To simplify this process, a + Visual Studio workspace, Apache.dsw, is provided. + This workspace exposes the entire list of working .dsp + projects that are required for the complete Apache binary release. + It includes dependencies between the projects to assure that they + are built in the appropriate order.

    + +

    Open the Apache.dsw workspace, and select + InstallBin (Release or Debug build, + as desired) as the Active Project. InstallBin causes all + related project to be built, and then invokes Makefile.win to + move the compiled executables and dlls. You may personalize the + INSTDIR= choice by changing InstallBin's Settings, + General tab, Build command line entry. INSTDIR defaults to the + /Apache2 directory. If you only want a test compile (without + installing) you may build the BuildBin project instead.

    + +

    The .dsp project files are distributed in Visual + C++ 6.0 format. Visual C++ 5.0 (97) will recognize them. Visual C++ + 7.0 (.net) must convert Apache.dsw plus the .dsp + files into an Apache.sln plus .msproj files, + be sure you reconvert the .msproj file if any of the source + .dsp files change! This is really trivial, just open + Apache.dsw in the VC++ 7.0 IDE once again.

    + +

    Visual C++ 7.0 (.net) users should also use the Build + menu, Configuration Manager dialog to uncheck both the Debug + and Release Solution modules abs, mod_ssl + and mod_deflate. + These modules are built by invoking nmake or the IDE directly + with the BinBuild target to build those modules explicitly, + only if the srclib directories openssl + and/or zlib exist.

    + +

    Exported .mak files pose a greater hassle, but they are + required for Visual C++ 5.0 users to build mod_ssl, + abs (ab with SSL support) and/or + mod_deflate. + VC++ 7.0 (.net) users also benefit, nmake builds + are faster than binenv builds. + Build the entire project from within the VC++ 5.0 or 6.0 IDE, + then use the Project Menu Export for all makefiles. + You must build the projects first in order to create all dynamic + auto-generated targets, so that dependencies can be parsed + correctly. Run the following command to fix the paths so they + will build anywhere:

    + + + perl srclib\apr\build\fixwin32mak.pl + + +

    You must type this command from the top level + directory of the httpd source tree. Every + .mak and .dep project file within + the current directory and below will be corrected, and the + timestamps adjusted to reflect the .dsp.

    + +

    If you contribute back a patch that revises project files, we + must commit project files in Visual Studio 6.0 format. Changes + should be simple, with minimal compilation and linkage flags that + will be recognized by all VC++ 5.0 through 7.0 environments.

    + +
    + +
    + + Project Components + +

    The Apache.dsw workspace and makefile.win + nmake script both build the .dsp projects + of the Apache server in the following sequence:

    + +
      +
    1. srclib\apr\apr.dsp
    2. + +
    3. srclib\apr\libapr.dsp
    4. + +
    5. srclib\apr-util\uri\gen_uri_delims.dsp
    6. + +
    7. srclib\apr-util\xml\expat\lib\xml.dsp
    8. + +
    9. srclib\apr-util\aprutil.dsp
    10. + +
    11. srclib\apr-util\libaprutil.dsp
    12. + +
    13. srclib\pcre\dftables.dsp
    14. + +
    15. srclib\pcre\pcre.dsp
    16. + +
    17. srclib\pcre\pcreposix.dsp
    18. + +
    19. server\gen_test_char.dsp
    20. + +
    21. libhttpd.dsp
    22. + +
    23. Apache.dsp
    24. +
    + +

    In addition, the modules\ subdirectory tree contains + project files for the majority of the modules.

    + +

    The support\ directory contains project files for + additional programs that are not part of the Apache runtime, + but are used by the administrator to test Apache and maintain + password and log files. Windows-specific support projects are + broken out in the support\win32\ directory.

    + +
      +
    1. support\ab.dsp
    2. + +
    3. support\htdigest.dsp
    4. + +
    5. support\htpasswd.dsp
    6. + +
    7. support\logresolve.dsp
    8. + +
    9. support\rotatelogs.dsp
    10. + +
    11. support\win32\ApacheMonitor.dsp
    12. + +
    13. support\win32\wintty.dsp
    14. +
    + +

    Once Apache has been compiled, it needs to be installed in + its server root directory. The default is the + \Apache2 directory, of the same drive.

    + +

    To build and install all the files into the desired folder + dir automatically, use one of the following + nmake commands:

    + +
    +nmake /f Makefile.win installr INSTDIR=dir
    +
    +nmake /f Makefile.win installd INSTDIR=dir
    +    
    + +

    The dir argument to INSTDIR gives + the installation directory; it can be omitted if Apache is + to be installed into \Apache2.

    + +

    This will install the following:

    + +
      +
    • dir\bin\Apache.exe - Apache + executable
    • + +
    • dir\bin\ApacheMonitor.exe - Service + monitor taskbar icon utility
    • + +
    • dir\bin\htdigest.exe - Digest auth + password file utility
    • + +
    • dir\bin\htdbm.exe - SDBM auth + database password file utility
    • + +
    • dir\bin\htpasswd.exe - Basic auth + password file utility
    • + +
    • dir\bin\logresolve.exe - Log file + dns name lookup utility
    • + +
    • dir\bin\rotatelogs.exe - Log file + cycling utility
    • + +
    • dir\bin\wintty.exe - Console window + utility
    • + +
    • dir\bin\libapr.dll - Apache + Portable Runtime shared library
    • + +
    • dir\bin\libaprutil.dll - Apache + Utility Runtime shared library
    • + +
    • dir\bin\libhttpd.dll - Apache Core + library
    • + +
    • dir\modules\mod_*.so - Loadable + Apache modules
    • + +
    • dir\conf - Configuration + directory
    • + +
    • dir\logs - Empty logging + directory
    • + +
    • dir\include - C language header + files
    • + +
    • dir\lib - Link library files
    • +
    + +
    + + Warning about building Apache from the development tree + + Note only the .dsp files are maintained between release + builds. The .mak files are NOT regenerated, due to the tremendous + waste of reviewer's time. Therefore, you cannot rely on the NMAKE + commands above to build revised .dsp project files unless you + then export all .mak files yourself from the project. This is + unnecessary if you build from within the Microsoft + Developer Studio environment. + + Also note it is very worthwhile to build the BuildBin + target project (or the command line _apacher or + _apached target) prior to exporting the make files. + Many files are autogenerated in the build process. Only a full + build provides all of the dependent files required to build proper + dependency trees for correct build behavior. + +

    In order to create distribution .mak files, always review + the generated .mak (or .dep) dependencies for + Platform SDK or other garbage includes. The DevStudio\SharedIDE\bin\ + (VC5) or DevStudio\Common\MSDev98\bin\ (VC6) directory contains + the sysincl.dat file, which must list all exceptions. Update this + file (including both forward and backslashed paths, such as both + sys/time.h and sys\time.h) to include such dependencies. + Including local-install paths in a distributed .mak file will + cause the build to fail completely. And don't forget to run + srclib/apr/build/fixwin32mak.pl in order to fix absolute + paths within the .mak files.

    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/platform/win_compiling.xml.ko b/trunk/docs/manual/platform/win_compiling.xml.ko new file mode 100644 index 0000000000..6e8a18cf6f --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.xml.ko @@ -0,0 +1,424 @@ + + + + + + + + + Platform Specific Notes + + Microsoft Windows¿ë ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ + + + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϱâ Àü¿¡ ÁÖÀÇÇÒ Á¡ÀÌ ¸¹´Ù. ¹Ì¸® Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¹ýÀ» + Âü°íÇ϶ó.

    + +
    + +
    + + ¿ä±¸»çÇ× + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é ´ÙÀ½ÀÌ Á¤»óÀûÀ¸·Î ¼³Ä¡µÇ¾ß ÇÑ´Ù:

    + +
      +
    • +

      µð½ºÅ© °ø°£

      +

      ³²Àº µð½ºÅ© °ø°£ÀÌ ÃÖ¼ÒÇÑ 50 MB´Â µÇ¾ß ÇÑ´Ù. ¾ÆÆÄÄ¡ + ¼³Ä¡ÈÄ¿¡´Â »¡¸® Áõ°¡ÇÏ´Â ·Î±×¿Í ij½¬ÆÄÀÏÀ» Á¦¿ÜÇÏ°í + ¾à 10 MB Á¤µµ°¡ ÇÊ¿äÇÏ´Ù. ½ÇÁ¦ µð½ºÅ© »ç¿ë·®Àº ¼±ÅÃÇÑ + ±¸¼º°ú Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ ȤÀº ¶óÀ̺귯¸®¿¡ µû¶ó Å©°Ô + ´Ù¸£´Ù.

      +
    • + +
    • +

      Microsoft Visual C++ 5.0 ÀÌ»ó.

      +

      ¾ÆÆÄÄ¡´Â ¸í·ÉÇà µµ±¸¸¦ »ç¿ëÇϰųª Visual Studio IDE + Workbench ¾È¿¡¼­ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù. ¸í·ÉÇà¿¡¼­ ÄÄÆÄÀÏÇÑ´Ù¸é + vcvars32 ¹èÄ¡ÆÄÀÏÀÌ ¼³Á¤ÇÏ´Â PATH, + INCLUDE, LIB µî ȯ°æº¯¼ö°¡ + ÇÊ¿äÇÏ´Ù:

      + + + "c:\Program Files\DevStudio\VC\Bin\vcvars32.bat" + +
    • + +
    • +

      Windows Platform SDK.

      +

      ¾î¶² ¾ÆÆÄÄ¡ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é Visual C++ 5.0¿¡ Ãß°¡·Î + ÃֽŠMicrosoft Windows Platform SDK°¡ ÇÊ¿äÇÏ´Ù. ¸í·ÉÇà¿¡¼­ + ÄÄÆÄÀÏÇÑ´Ù¸é setenv ¹èÄ¡ÆÄÀÏÀÌ Platform + SDK ȯ°æÀ» ¸¸µç´Ù:

      + + + "c:\Program Files\Platform SDK\setenv.bat" + + +

      Visual C++ 6.0 ÀÌ»ó¿¡ Æ÷ÇÔµÈ Platform SDK ÆÄÀÏÀº + ÃæºÐÇÏ´Ù. ÀÌ ¹öÀüÀ» »ç¿ëÇÏ´Â »ç¿ëÀÚ´Â ÀÌ °úÁ¤À» »ý·«Çصµ + µÈ´Ù.

      + + ¸ðµç mod_isapi ±â´ÉÀ» »ç¿ëÇÏ·Á¸é + ÃֽŠWindows Platform SDK°¡ ÇÊ¿äÇÏ´Ù. ÃֽŠ¹öÀüÀÌ ¾Æ´Ï¸é + MSVC++ 5.0Àº mod_isapi ±â´ÉÀÇ ÀϺθ¦ + »ç¿ëÇÒ ¼ö ¾ø´Ù°í °æ°íÇÑ´Ù. http://msdn.microsoft.com/downloads/sdks/platform/platform.asp¿¡ + ÃֽŠ¹öÀüÀÌ ÀÖ´Ù. +
    • + +
    • +

      awk µµ±¸ (awk, gawk µî).

      +

      ÄÄÆÄÀÏÇÑ ½Ã½ºÅÛ¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ·Á¸é + awk.exe µµ±¸¸¦ »ç¿ëÇÏ¿© ¿©·¯ ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß + ÇÑ´Ù. (PerlÀ̳ª WSH/VB°ú ºñ±³ÇÏ¿©) ´Ù¿î¹Þ±â¿¡ ¸Å¿ì ÀÛ°í + ÆÄÀÏ »ý¼º ÀÛ¾÷ÀÌ °¡´ÉÇÏ¿© awk¸¦ ¼±ÅÃÇß´Ù. Brian KernighanÀÇ + http://cm.bell-labs.com/cm/cs/who/bwk/ »çÀÌÆ®¿¡ + ÄÄÆÄÀÏµÈ Win32 ½ÇÇàÆÄÀÏ http://cm.bell-labs.com/cm/cs/who/bwk/awk95.exeÀÌ + ÀÖ´Ù. À̸§À» awk95.exe ´ë½Å + awk.exe·Î º¯°æÇØ¾ß ÇÑ´Ù.

      + + Developer Studio IDE´Â Tools ¸Þ´º Options... + Directories ÅÇÀÇ (Developer Studio 7.0À̶ó¸é Projects + - VC++ Directories pane) Executable files °æ·Î ¸ñ·Ï¿¡¼­¸¸ + awk.exe¸¦ ã´Â´Ù. ÀÌ ¸ñ·Ï¿¡ awk.exe + °æ·Î¸¦ Ãß°¡ÇÏ°í, ÇÊ¿äÇÏ´Ù¸é PATH ȯ°æº¯¼ö¿¡µµ + Ãß°¡ÇÑ´Ù. + + CygwinÀ» (http://www.cygwin.com/) »ç¿ëÇÑ´Ù¸é + gawk.exe¶ó´Â À̸§À¸·Î awk µµ±¸°¡ ÀÖÀ¸¸ç, + awk.exe ÆÄÀÏÀº gawk.exe ÆÄÀÏÀÇ + ½Éº¼¸µÅ©ÀÓÀ» ÁÖÀÇÇ϶ó. Windows ¸í·É ÇÁ·ÒÇÁÆ®°¡ ½Éº¼¸µÅ©¸¦ + ÀνÄÇÏÁö ¸øÇϱ⶧¹®¿¡ InstallBinÀ» ÄÄÆÄÀÏÇÒ¶§ ½ÇÆÐÇÑ´Ù. + ÇØ°áÃ¥Àº cygwin¿¡¼­ awk.exe¸¦ »èÁ¦ÇÏ°í + gawk.exe À̸§À» awk.exe·Î + ¹Ù²Û´Ù. +
    • + +
    • +

      [¼±ÅÃÀûÀÎ] OpenSSL ¶óÀ̺귯¸® (mod_ssl°ú + ab.exeÀÇ ssl Áö¿ø¿¡ »ç¿ë)

      +

      ÁÖÀÇ: °­·ÂÇÑ ¾Ïȣȭ¿Í ƯÇã°¡ °É¸° ÁöÀûÀç»ê±ÇÀ» + Àü¼¼°è¿¡ ¹èÆ÷Çϴµ¥´Â »ó´çÇÑ Á¦¾àÀÌ ÀÖ´Ù. + OpenSSLÀº ¹Ì±¹ ¼öÃâ±ÔÁ¦¹ýÀÌ ±ÔÁ¦ÇÏ¸ç ¹Ì±¹°ú ±âŸ Áö¿ª¿¡¼­ + ƯÇã·Î º¸È£µÇ´Â ÁöÀûÀç»ê±ÇÀÎ °­·ÂÇÑ ¾Ïȣȭ¸¦ Æ÷ÇÔÇÑ´Ù. + Apache Software Foundation°ú OpenSSL ÇÁ·ÎÁ§Æ®´Â OpenSSL + ÇÁ·ÎÁ§Æ®°¡ Á¦°øÇÏ´Â Äڵ带 ¼ÒÀ¯, »ç¿ë, ¹èÆ÷Çϴµ¥ µû¸¥ + ¹ýÀû ÀÚ¹®À» Á¦°øÇÏÁö ¾Ê´Â´Ù. Á÷Á¢ ¹ý·ü »ó´ãÀ» + ¹Þ±æ ¹Ù¶õ´Ù. ´ç½Å ÇൿÀÇ Ã¥ÀÓÀº ´ç½Å¿¡°Ô ÀÖ´Ù.

      + +

      mod_sslÀ̳ª (SSLÀ» Áö¿øÇÏ´Â + ab.exe) abs ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ·Á¸é, OpenSSLÀ» + http://www.openssl.org/source/¿¡¼­ ´Ù¿î¹Þ¾Æ¼­ + srclibÀÇ opensslÀ̶ó´Â + ÇÏÀ§µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÑ´Ù. release¿Í + debug·Î ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ¶§ »ç¿ëÇϸç 0.9.7 + ¹öÀü¿¡ Àִ ƯÇã°¡ °É¸° ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é, ¾Æ·¡ + ÄÄÆÄÀÏ ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù:

      + + + perl Configure VC-WIN32
      + perl util\mkfiles.pl >MINFO
      + perl util\mk1mf.pl dll no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile
      + perl util\mk1mf.pl dll debug no-asm no-mdc2 no-rc5 no-idea VC-WIN32 >makefile.dbg
      + perl util\mkdef.pl 32 libeay no-asm no-mdc2 no-rc5 no-idea >ms\libeay32.def
      + perl util\mkdef.pl 32 ssleay no-asm no-mdc2 no-rc5 no-idea >ms\ssleay32.def
      + nmake
      + nmake -f makefile.dbg +
      + +
    • + +
    • +

      [¼±ÅÃÀûÀÎ] zlib ¼Ò½º (mod_deflate¿¡ + »ç¿ë)

      +

      ZlibÀ» srclibÀÇ zlib¶ó´Â + ÇÏÀ§µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÏÁö¸¸, ¼Ò½º¸¦ ¹Ì¸® ÄÄÆÄÀÏÇÒ + ÇÊ¿ä´Â ¾ø´Ù. ÄÄÆÄÀÏ ½Ã½ºÅÛÀº ÀÌ ¾ÐÃà¼Ò½º¸¦ + mod_deflate ¸ðµâ°ú °°ÀÌ ÄÄÆÄÀÏÇÑ´Ù. + ZlibÀº http://www.gzip.org/zlib/¿¡¼­ ±¸ÇÒ ¼ö ÀÖ´Ù -- + mod_deflate´Â 1.1.4 ¹öÀü°ú Á¤»óÀûÀ¸·Î + ÄÄÆÄÀϵǾú´Ù.

      +
    • + +
    + +
    + +
    + + ¸í·ÉÇà¿¡¼­ ÄÄÆÄÀÏÇϱâ + +

    ¸ÕÀú Àû´çÇÑ µð·ºÅ丮¿¡ ¾ÆÆÄÄ¡ ¹èÆ÷º» ¾ÐÃàÀ» Ǭ´Ù. ¸í·ÉÇà + ÇÁ·ÒÇÁÆ®¸¦ ¿­°í ±× µð·ºÅ丮·Î cdÇÑ´Ù.

    + +

    Makefile.win ÆÄÀÏ¿¡ ¾ÆÆÄÄ¡ makefile ¸í·ÉÀÌ + ÀÖ´Ù. Windows NT¿¡¼­ release¿Í debug + ÄÄÆÄÀÏÇÏ´Â ¸í·É¾î´Â °¢°¢ ´ÙÀ½°ú °°´Ù:

    + +
    +nmake /f Makefile.win _apacher
    +
    +nmake /f Makefile.win _apached
    +    
    + +

    µÎ ¸í·É¾î ¸ðµÎ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÑ´Ù. ÈÄÀÚ´Â °á°úÆÄÀÏ¿¡ + µð¹ö±ë Á¤º¸¸¦ Æ÷ÇÔÇÏ¿© ¹ö±×¸¦ ã°í ¹®Á¦¸¦ ÃßÀûÇϱ⠽±°Ô + ÇÑ´Ù.

    + +
    + +
    + + Developer Studio Workspace IDE¿¡¼­ ÄÄÆÄÀÏÇϱâ + +

    VC++ÀÇ Visual Studio °³¹ß ȯ°æÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ + ¼öµµ ÀÖ´Ù. °úÁ¤À» ½±°Ô ÇÏ·Á°í Visual Studio workspace + Apache.dsw¸¦ Á¦°øÇÑ´Ù. ÀÌ workspace´Â ¿ÏÀüÇÑ + ¾ÆÆÄÄ¡ ¹ÙÀ̳ʸ® ¹èÆ÷º»¿¡ ÇÊ¿äÇÑ .dsp ÇÁ·ÎÁ§Æ® + ¸ñ·ÏÀ» ´ã°íÀÖ´Ù. ¶Ç, ¾Ë¸ÂÀº ¼ø¼­·Î ÄÄÆÄÀÏÇϱâÀ§ÇÑ ÇÁ·ÎÁ§Æ®°£ + ÀÇÁ¸¼º Á¤º¸µµ Æ÷ÇÔÇÑ´Ù.

    + +

    Apache.dsw workspace¸¦ ¿­°í + InstallBinÀ» (Release³ª + Debug Áß ¿øÇÏ´Â °ÍÀ») Active Project·Î ¼±ÅÃÇÑ´Ù. + InstallBinÀº °ü·ÃµÈ ¸ðµç ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ°í, + ÄÄÆÄÀÏµÈ ½ÇÇàÆÄÀÏ°ú dllÀ» ¿Å±â´Â Makefile.winÀ» + È£ÃâÇÑ´Ù. InstallBinÀÇ Settings, General ÅÇ, + Build command line Ç׸ñÀ» ¼öÁ¤ÇÏ¿© INSTDIR=À» + º¯°æÇÒ ¼ö ÀÖ´Ù. INSTDIR= ±âº»°ªÀº + /Apache2 µð·ºÅ丮ÀÌ´Ù. (¼³Ä¡ÇÏÁö¾Ê°í) Å×½ºÆ®·Î + ÄÄÆÄÀϸ¸ Çغ¸·Á¸é ´ë½Å BuildBin ÇÁ·ÎÁ§Æ®¸¦ + »ç¿ëÇÑ´Ù.

    + +

    .dsp ÇÁ·ÎÁ§Æ® ÆÄÀÏÀº Visual C++ 6.0 Çü½ÄÀÌ´Ù. + Visual C++ 5.0 (97)¿¡¼­µµ ÀÌ ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. Visual + C++ 7.0 (.net)Àº Apache.dsw¿Í .dsp + ÆÄÀϵéÀ» Apache.sln°ú .msproj + ÆÄÀϵé·Î º¯È¯ÇÑ´Ù. .dsp ¼Ò½ºÆÄÀÏÀ» ¼öÁ¤Çϸé + ¹Ýµå½Ã .msproj ÆÄÀÏ·Î ´Ù½Ã º¯È¯Ç϶ó! ±×³É VC++ + 7.0 IDE¿¡¼­ Apache.dsw¸¦ ´Ù½Ã ¿­±â¸¸ ÇÏ¸é µÈ´Ù.

    + +

    ¶Ç, Visual C++ 7.0 (.net) »ç¿ëÀÚ´Â Build ¸Þ´º, Configuration + Manager ´ëȭâ¿¡¼­ Debug¿Í ReleaseÀÇ + abs, mod_ssl, mod_deflate + Solution modules ¼±ÅÃÀ» ÇØÁ¦ÇØ¾ß ÇÑ´Ù. srclib¿¡ + opensslÀ̳ª zlib µð·ºÅ丮°¡ ÀÖ´Â + °æ¿ì¿¡¸¸ nmake¸¦ ½ÇÇàÇϰųª (ÀÌ ¸ðµâÀ» ¸í½ÃÀûÀ¸·Î + ÄÄÆÄÀÏÇÏ´Â) IDE BinBuild ´ë»óÀ» »ç¿ëÇÏ¿© ¸ðµâÀ» + ÄÄÆÄÀÏ ÇÒ ¼ö ÀÖ´Ù.

    + +

    ExportÇÑ .mak ÆÄÀϵéÀÌ È¥¶õ½º·´Áö¸¸, Visual + C++ 5.0 »ç¿ëÀÚ°¡ mod_ssl, abs (SSLÀ» Áö¿øÇÏ´Â + ab), mod_deflate¸¦ ÄÄÆÄÀÏÇÒ¶§ ÇÊ¿äÇÏ´Ù. + VC++ 7.0 (.net) »ç¿ëÀÚ¿¡°Ôµµ binenv º¸´Ù + nmake¸¦ »ç¿ëÇϸé ÄÄÆÄÀÏÀÌ ´õ ºü¸£´Ù. VC++ 5.0À̳ª + 6.0 IDE¿¡¼­ Àüü ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÏ°í, Project ¸Þ´ºÀÇ Export + for all makefiles¸¦ »ç¿ëÇ϶ó. µ¿ÀûÀ¸·Î ÀÚµ¿ »ý¼ºÇÏ´Â ´ë»óÀ» + ¸ðµÎ ÄÄÆÄÀÏÇÏ°í ¿Ã¹Ù¸¥ ÀÇÁ¸¼º Á¤º¸¸¦ ¾ò±âÀ§Çؼ­´Â ¸ÕÀú + ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© °æ·Î¸¦ + ¼öÁ¤ÇÏ¸é ¾î¶² °æ·Î¿¡¼­µµ ÄÄÆÄÀÏÇÒ ¼ö ÀÖ´Ù:

    + + + perl srclib\apr\build\fixwin32mak.pl + + +

    httpd ¼Ò½º ÃÖ»óÀ§ µð·ºÅ丮¿¡¼­ + ¸í·É¾î¸¦ ½ÇÇàÇØ¾ß ÇÑ´Ù. ÇöÀç µð·ºÅ丮¿Í ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â + ¸ðµç .mak¿Í .dep ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» + ¼öÁ¤ÇÏ°í, .dsp¸¦ °í·ÁÇÏ¿© ÆÄÀϽð£À» ¼öÁ¤ÇÑ´Ù.

    + +

    ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» ´Ùµë¾î¼­ ÆÐÄ¡¸¦ º¸³½´Ù¸é, ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» + Visual Studio 6.0 Çü½ÄÀ¸·Î ¸¸µé¾î¾ß ÇÑ´Ù. º¯°æÀº °£´ÜÇÏ°í, + VC++ 5.0¿¡¼­ 7.0±îÁö ¸ðµç ȯ°æ¿¡¼­ ÀνÄÇÏ´Â ÃÖ¼ÒÇÑÀÇ ÄÄÆÄÀÏ + ¿É¼Ç°ú ¸µÄ¿ ¿É¼ÇÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +
    + +
    + + ÇÁ·ÎÁ§Æ® ±¸¼º¿ä¼Ò + +

    Apache.dsw workspace¿Í makefile.win + nmake ½ºÅ©¸³Æ®´Â ´ÙÀ½ ¼ø¼­´ë·Î ¾ÆÆÄÄ¡ ¼­¹ö + .dsp ÇÁ·ÎÁ§Æ®¸¦ ÄÄÆÄÀÏÇÑ´Ù:

    + +
      +
    1. srclib\apr\apr.dsp
    2. + +
    3. srclib\apr\libapr.dsp
    4. + +
    5. srclib\apr-util\uri\gen_uri_delims.dsp
    6. + +
    7. srclib\apr-util\xml\expat\lib\xml.dsp
    8. + +
    9. srclib\apr-util\aprutil.dsp
    10. + +
    11. srclib\apr-util\libaprutil.dsp
    12. + +
    13. srclib\pcre\dftables.dsp
    14. + +
    15. srclib\pcre\pcre.dsp
    16. + +
    17. srclib\pcre\pcreposix.dsp
    18. + +
    19. server\gen_test_char.dsp
    20. + +
    21. libhttpd.dsp
    22. + +
    23. Apache.dsp
    24. +
    + +

    ¶Ç, modules\ ÇÏÀ§µð·ºÅ丮 ¾Æ·¡ ´ëºÎºÐÀÇ + ¸ðµâ¿¡´Â ÇÁ·ÎÁ§Æ®ÆÄÀÏÀÌ ÀÖ´Ù.

    + +

    support\ µð·ºÅ丮¿¡´Â ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇϴµ¥ + ÇÊ¿äÇÏÁö´Â ¾ÊÁö¸¸, °ü¸®ÀÚ°¡ ¾ÆÆÄÄ¡¸¦ °Ë»çÇϰųª ¾ÏÈ£ÆÄÀÏ°ú + ·Î±×ÆÄÀÏÀ» °ü¸®Çϴµ¥ »ç¿ëÇÒ Ãß°¡ ÇÁ·Î±×·¥µéÀÇ ÇÁ·ÎÁ§Æ®ÆÄÀÏÀÌ + ÀÖ´Ù. Windows Àü¿ë Áö¿ø ÇÁ·Î±×·¥Àº support\win32\ + µð·ºÅ丮¿¡ µû·Î ÀÖ´Ù.

    + +
      +
    1. support\ab.dsp
    2. + +
    3. support\htdigest.dsp
    4. + +
    5. support\htpasswd.dsp
    6. + +
    7. support\logresolve.dsp
    8. + +
    9. support\rotatelogs.dsp
    10. + +
    11. support\win32\ApacheMonitor.dsp
    12. + +
    13. support\win32\wintty.dsp
    14. +
    + +

    ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇϸé server root µð·ºÅ丮¿¡ ¼³Ä¡ÇØ¾ß ÇÑ´Ù. + ±âº»°ªÀº °°Àº µð½ºÅ©ÀÇ \Apache2 µð·ºÅ丮ÀÌ´Ù.

    + +

    ÄÄÆÄÀÏÇÏ°í ¸ðµç ÆÄÀÏÀ» ¿øÇÏ´Â Æú´õ dir¿¡ ÀÚµ¿À¸·Î + ¼³Ä¡ÇÏ·Á¸é ´ÙÀ½ nmake ¸í·É¾îÁß Çϳª¸¦ »ç¿ëÇÑ´Ù:

    + +
    +nmake /f Makefile.win installr INSTDIR=dir
    +
    +nmake /f Makefile.win installd INSTDIR=dir
    +    
    + +

    INSTDIRÀÇ dir ¾Æ±Ô¸ÕÆ®´Â ¼³Ä¡µð·ºÅ丮¸¦ + ¶æÇÑ´Ù. »ý¶ôÇϸé \Apache2¿¡ ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ¼³Ä¡ÇÑ´Ù:

    + +
      +
    • dir\bin\Apache.exe - ¾ÆÆÄÄ¡ + ½ÇÇàÆÄÀÏ
    • + +
    • dir\bin\ApacheMonitor.exe - + ¼­ºñ½º °¨½Ã¿ë ÀÛ¾÷Ç¥½ÃÁÙ ¾ÆÀÌÄÜ µµ±¸
    • + +
    • dir\bin\htdigest.exe - Digest + auth ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\htdbm.exe - SDBM auth + µ¥ÀÌÅͺ£À̽º ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\htpasswd.exe - Basic + auth ¾ÏÈ£ÆÄÀÏ µµ±¸
    • + +
    • dir\bin\logresolve.exe - ·Î±×ÆÄÀÏ¿¡¼­ + dns À̸§À» ã´Â µµ±¸
    • + +
    • dir\bin\rotatelogs.exe - ·Î±×ÆÄÀÏ + ¼øȯ µµ±¸
    • + +
    • dir\bin\wintty.exe - ÄܼÖâ + µµ±¸
    • + +
    • dir\bin\libapr.dll - Apache + Portable Runtime °øÀ¯ ¶óÀ̺귯¸®
    • + +
    • dir\bin\libaprutil.dll - Apache + Utility Runtime °øÀ¯ ¶óÀ̺귯¸®
    • + +
    • dir\bin\libhttpd.dll - Apache + Core ¶óÀ̺귯¸®
    • + +
    • dir\modules\mod_*.so - ÀоîµéÀÏ + ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¸ðµâ
    • + +
    • dir\conf - ¼³Á¤ µð·ºÅ丮
    • + +
    • dir\logs - ºñ¾îÀÖ´Â ·Î±× + µð·ºÅ丮
    • + +
    • dir\include - C ¾ð¾î Çì´õÆÄÀÏ
    • + +
    • dir\lib - ¸µÅ© ¶óÀ̺귯¸®ÆÄÀÏ
    • +
    + +
    + + °³¹ßÁßÀÎ ¾ÆÆÄÄ¡ ¹öÀüÀ» ÄÄÆÄÀÏÇÒ¶§ °æ°í + + .dsp ÆÄÀÏÀº release¸¶´Ù + »õ·Î ¸¸µé¾îÁø´Ù. °³¹ßÀÚÀÇ ½Ã°£³¶ºñ¸¦ ¸·±âÀ§ÇØ + .mak ÆÄÀÏÀº »õ·Î ¸¸µéÁö ¾Ê´Â´Ù. ±×·¯¹Ç·Î + NMAKE ¸í·É¾î¸¦ »ç¿ëÇÏ¿© »õ·Î¿î .dsp + ÇÁ·ÎÁ§Æ®ÆÄÀÏÀ» ÄÄÆÄÀÏÇÒ ¼ö ¾ø´Ù. ÇÁ·ÎÁ§Æ®¿¡¼­ Á÷Á¢ ¸ðµç + .mak ÆÄÀÏÀ» exportÇØ¾ß ÇÑ´Ù. Microsoft Developer + Studio ȯ°æ¿¡¼­ ÄÄÆÄÀÏÇÑ´Ù¸é ÀÌ ÀÛ¾÷ÀÌ ÇÊ¿ä¾ø´Ù. + + ¶Ç, makefileÀ» exportÇϱâ Àü¿¡ BuildBin + ÇÁ·ÎÁ§Æ®¸¦ (ȤÀº _apacher³ª _apached + ¸í·ÉÇà ´ë»ó) ÄÄÆÄÀÏÇÏ¸é ¸Å¿ì µµ¿òÀÌ µÈ´Ù. ÄÄÆÄÀÏÁß¿¡ ¸¹Àº + ÆÄÀÏÀÌ ÀÚµ¿À¸·Î ¸¸µé¾îÁø´Ù. Àüü¸¦ ÄÄÆÄÀÏÇؾ߸¸ Á¤»óÀûÀ¸·Î + ÄÄÆÄÀÏÇÒ¶§ ÇÊ¿äÇÑ ÀÇÁ¸ÆÄÀÏÀ» ¸ðµÎ ¸¸µç´Ù. + +

    ¹èÆ÷¿ë .mak ÆÄÀÏÀ» ¸¸µå·Á¸é Ç×»ó + .mak (ȤÀº .dep)¿¡¼­ Platform + SDK µîÀÇ ÀÇÁ¸¼ºÀ» Á¡°ËÇ϶ó. + DevStudio\SharedIDE\bin\ (VC5)³ª + DevStudio\Common\MSDev98\bin\ (VC6) µð·ºÅ丮¿¡´Â + ¸ðµç ¿¹¿Ü ¸ñ·ÏÀÌ ´ã±ä sysincl.dat ÆÄÀÏÀÌ + ÀÖ´Ù. ÀÌ ÆÄÀÏ¿¡ ÀÇÁ¸¼º Á¤º¸¸¦ Ãß°¡ÇÑ´Ù + (sys/time.h¿Í sys\time.h¿Í °°ÀÌ, + °æ·Î´Â ½½·¡½¬¸¦ »ç¿ëÇÑ °Í°ú ¹é½½·¡½¬¸¦ »ç¿ëÇÑ °Í ¸ðµÎ¸¦ + Ãß°¡ÇÑ´Ù). ¹èÆ÷ÇÒ .mak ÆÄÀÏ¿¡ ÇöÀç ÄÄÇ»ÅÍ¿¡¸¸ + ÇØ´çÇÏ´Â ¼³Ä¡°æ·Î°¡ ÀÖ´Ù¸é ÄÄÆÄÀÏÀÌ ¿ÏÀüÈ÷ ½ÇÆÐÇÑ´Ù. + ±×·¯¹Ç·Î srclib/apr/build/fixwin32mak.plÀ» + ½ÇÇàÇØÇÏ¿© .mak ÆÄÀÏ¿¡ ÀÖ´Â Àý´ë°æ·Î¸¦ ¾ø¾Ö¾ß + ÇÑ´Ù.

    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/platform/win_compiling.xml.meta b/trunk/docs/manual/platform/win_compiling.xml.meta new file mode 100644 index 0000000000..3135ce95a4 --- /dev/null +++ b/trunk/docs/manual/platform/win_compiling.xml.meta @@ -0,0 +1,12 @@ + + + + win_compiling + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/platform/windows.html b/trunk/docs/manual/platform/windows.html new file mode 100644 index 0000000000..dbcab1c655 --- /dev/null +++ b/trunk/docs/manual/platform/windows.html @@ -0,0 +1,7 @@ +URI: windows.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: windows.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/platform/windows.html.en b/trunk/docs/manual/platform/windows.html.en new file mode 100644 index 0000000000..05ab8970ba --- /dev/null +++ b/trunk/docs/manual/platform/windows.html.en @@ -0,0 +1,736 @@ + + + +Using Apache with Microsoft Windows - Apache HTTP Server + + + + + +
    <-
    +

    Using Apache with Microsoft Windows

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    This document explains how to install, configure and run + Apache 2.0 under Microsoft Windows. If you find any bugs, or + wish to contribute in other ways, please use our bug reporting + page.

    + +

    This document assumes that you are installing a binary + distribution of Apache. If you want to compile Apache yourself + (possibly to help with development or tracking down bugs), + see Compiling Apache for Microsoft + Windows.

    + +

    Because of the current versioning policies on Microsoft + Windows operating system families, this document assumes the + following:

    +
      +
    • Windows NT: This means all versions of + Windows that are based on the Windows NT kernel. Includes Windows + NT, Windows 2000, Windows XP and Windows .Net Server 2003.
    • +
    • Windows 9x: This means older, + consumer-oriented versions of Windows. Includes Windows 95 (also + OSR2), Windows 98 and Windows ME.
    • +
    + +
    + +
    top
    +
    +

    Operating System Requirements

    + + +

    The primary Windows platform for running Apache 2.0 is Windows + NT. The binary installer only works with the x86 family of + processors, such as Intel and AMD processors. Running Apache on + Windows 9x is not thoroughly tested, and it is never recommended on + production systems. +

    + +

    On all operating systems, TCP/IP networking must be installed + and working. If running on Windows 95, the Winsock 2 upgrade must + be installed. Winsock 2 for Windows 95 can be downloaded from here. +

    + +

    On Windows NT 4.0, installing Service Pack 6 is strongly + recommended, as Service Pack 4 created known issues with TCP/IP + and Winsock integrity that were resolved in later Service Packs.

    +
    top
    +
    +

    Downloading Apache for Windows

    + + +

    Information on the latest versions of Apache can be found on the + web site of the Apache web server at + http://httpd.apache.org/download.cgi. + There you will find the current release, as well as more recent alpha + or beta test versions, and a list of HTTP and FTP mirrors from which + you can download the Apache web server. Please use a mirror near to + you for a fast and reliable download.

    + +

    For Windows installations you should download the version of + Apache for Windows with the .msi extension. This is a + single Microsoft Installer file, which contains a ready-to-run + version of Apache. There is a separate .zip file, + which contains only the source code. You can compile Apache + yourself with the Microsoft Visual C++ (Visual Studio) tools.

    +
    top
    +
    +

    Installing Apache for Windows

    + + +

    You need Microsoft Installer 1.2 or above for the installation + to work. On Windows 9x you can update your Microsoft Installer to + version 2.0 here + and on Windows NT 4.0 and 2000 the version 2.0 update can be found + here. + Windows XP does not need this update.

    + +

    Note that you cannot install two versions of Apache 2.0 on the + same computer with the binary installer. You can, however, install + a version of the 1.3 series and a version of the + 2.0 series on the same computer without problems. If you need to + have two different 2.0 versions on the same computer, you have to + compile and install Apache from the + source.

    + +

    Run the Apache .msi file you downloaded above. The + installation will ask you for these things:

    + +
      +
    1. Network Domain. Enter the DNS domain in which + your server is or will be registered in. For example, if your + server's full DNS name is server.mydomain.net, you would + type mydomain.net here.

    2. + +
    3. Server Name. Your server's full DNS name. + From the example above, you would type server.mydomain.net + here.

    4. + +
    5. Administrator's Email Address. Enter the + server administrator's or webmaster's email address here. This + address will be displayed along with error messages to the client + by default.

    6. + +
    7. For whom to install Apache Select for + All Users, on Port 80, as a Service - Recommended if you'd + like your new Apache to listen at port 80 for incoming traffic. + It will run as a service (that is, Apache will run even if no one + is logged in on the server at the moment) Select only for + the Current User, on Port 8080, when started Manually if + you'd like to install Apache for your personal experimenting or + if you already have another WWW server running on port 80.

    8. + +
    9. The installation type. Select Typical + for everything except the source code and libraries for module + development. With Custom you can specify what to + install. A full install will require about 13 megabytes of free + disk space. This does not include the size of your web + site(s).

    10. + +
    11. Where to install. The default path is + C:\Program Files\Apache Group under which a directory + called Apache2 will be created by default.

    12. +
    + +

    During the installation, Apache will configure the files in the + conf subdirectory to reflect the chosen installation + directory. However, if any of the configuration files in this + directory already exist, they will not be overwritten. Instead, the + new copy of the corresponding file will be left with the extension + .default. So, for example, if conf\httpd.conf + already exists, it will be renamed as conf\httpd.conf.default. + After the installation you should manually check to see what new + settings are in the .default file, and if necessary, + update your existing configuration file.

    + +

    Also, if you already have a file called htdocs\index.html, + it will not be overwritten (and no index.html.default + will be installed either). This means it should be safe to install + Apache over an existing installation, although you would have to + stop the existing running server before doing the installation, and + then start the new one after the installation is finished.

    + +

    After installing Apache, you must edit the configuration files + in the conf subdirectory as required. These files + will be configured during the installation so that Apache is ready + to be run from the directory it was installed into, with the + documents server from the subdirectory htdocs. There + are lots of other options which you should set before you really + start using Apache. However, to get started quickly, the files + should work as installed.

    +
    top
    +
    +

    Customizing Apache for Windows

    + + +

    Apache is configured by the files in the conf + subdirectory. These are the same files used to configure the Unix + version, but there are a few different directives for Apache on + Windows. See the directive index + for all the available directives.

    + +

    The main differences in Apache for Windows are:

    +
      +
    • Because Apache for Windows is multithreaded, it does not + use a separate process for each request, as Apache does on Unix. + Instead there are usually only two Apache processes running: a + parent process, and a child which handles the requests. Within + the child process each request is handled by a separate thread. +

      + +

      The process management directives are also different:

      + +

      MaxRequestsPerChild: + Like the Unix directive, this controls how many requests a single + child process will serve before exiting. However, unlike on Unix, + a single process serves all the requests at once, not just one. + If this is set, it is recommended that a very high number is + used. The recommended default, MaxRequestsPerChild 0, + causes the child process to never exit.

      + +
      Warning: The server configuration + file is reread when a new child process is started. If you have + modified httpd.conf, the new child may not start or + you may receive unexpected results.
      + +

      ThreadsPerChild: + This directive is new. It tells the server how many threads it + should use. This is the maximum number of connections the server + can handle at once, so be sure to set this number high enough for + your site if you get a lot of hits. The recommended default is + ThreadsPerChild 50.

    • + +
    • The directives that accept filenames as arguments must use + Windows filenames instead of Unix ones. However, because Apache + uses Unix-style names internally, you must use forward slashes, + not backslashes. Drive letters can be used; if omitted, the drive + with the Apache executable will be assumed.

    • + +
    • Apache for Windows contains the ability to load modules at + runtime, without recompiling the server. If Apache is compiled + normally, it will install a number of optional modules in the + \Apache2\modules directory. To activate these or + other modules, the new LoadModule + directive must be used. For example, to activate the status + module, use the following (in addition to the status-activating + directives in access.conf):

      + +

      + LoadModule status_module modules/mod_status.so +

      + +

      Information on creating + loadable modules is also available.

    • + +
    • Apache can also load ISAPI (Internet Server Application + Programming Interface) extensions (i.e. internet server + applications), such as those used by Microsoft IIS and other + Windows servers. More information + is available. Note that Apache cannot load + ISAPI Filters.

    • + +
    • When running CGI scripts, the method Apache uses to find + the interpreter for the script is configurable using the + ScriptInterpreterSource + directive.

    • + +
    • Since it is often difficult to manage files with names + like .htaccess in Windows, you may find it useful to + change the name of this per-directory configuration file using + the AccessFilename + directive.

    • + +
    • Any errors during Apache startup are logged into the + Windows event log when running on Windows NT. This mechanism + acts as a backup for those situations where Apache cannot even + access the normally used error.log file. You can + view the Windows event log by using the Event Viewer application + on Windows NT 4.0, and the Event Viewer MMC snap-in on newer + versions of Windows.

      + +
      Note that there is no startup error logging on + Windows 9x because no Windows event log exists on those operating + systems.
    • +
    + +
    top
    +
    +

    Running Apache as a Service

    + + +

    Apache can be run as a service on Windows NT. There is some + highly experimental support for similar behavior on Windows 9x.

    + +

    You can install Apache as a service automatically during the + installation. If you chose to install for all users, the + installation will create an Apache service for you. If you specify + to install for yourself only, you can manually register Apache as a + service after the installation. You have to be a member of the + Administrators group for the service installation to succeed.

    + +

    Apache comes with a utility called the Apache Service Monitor. + With it you can see and manage the state of all installed Apache + services on any machine on your network. To be able to manage an + Apache service with the monitor, you have to first install the + service (either automatically via the installation or manually). +

    + +

    You can install Apache as a Windows NT service as follows from + the command prompt at the Apache bin subdirectory:

    + +

    + apache -k install +

    + +

    If you need to specify the name of the service you want to + install, use the following command. You have to do this if you + have several different service installations of Apache on your + computer.

    + +

    + apache -k install -n "MyServiceName" +

    + +

    If you need to have specifically named configuration files for + different services, you must use this:

    + +

    + apache -k install -n "MyServiceName" -f "c:\files\my.conf" +

    + +

    If you use the first command without any special parameters except + -k install, the service will be called Apache2 + and the configuration will be assumed to be conf\httpd.conf. +

    + +

    Removing an Apache service is easy. Just use:

    + +

    + apache -k uninstall +

    + +

    The specific Apache service to be uninstalled can be specified by using:

    + +

    + apache -k uninstall -n "MyServiceName" +

    + +

    Normal starting, restarting and shutting down of an Apache + service is usually done via the Apache Service Monitor, by using + commands like NET START Apache2 and NET STOP + Apache2 or via normal Windows service management. Before + starting Apache as a service by any means, you should test the + service's configuration file by using:

    + +

    + apache -n "MyServiceName" -t +

    + +

    You can control an Apache service by its command line switches, + too. To start an installed Apache service you'll use this:

    + +

    + apache -k start +

    + +

    To stop an Apache service via the command line switches, use + this:

    + +

    + apache -k stop +

    + +

    or

    + +

    + apache -k shutdown +

    + +

    You can also restart a running service and force it to reread + its configuration file by using:

    + +

    + apache -k restart +

    + +

    By default, all Apache services are registered to run as the + system user (the LocalSystem account). The + LocalSystem account has no privileges to your network + via any Windows-secured mechanism, including the file system, named + pipes, DCOM, or secure RPC. It has, however, wide privileges locally. +

    + +
    Never grant any network privileges to + the LocalSystem account! If you need Apache to be able + to access network resources, create a separate account for Apache as + noted below.
    + +

    You may want to create a separate account for running Apache + service(s). Especially, if you have to access network resources + via Apache, this is strongly recommended.

    + +
      +
    1. Create a normal domain user account, and be sure to + memorize its password.
    2. + +
    3. Grant the newly-created user a privilege of Log on + as a service and Act as part of the operating + system. On Windows NT 4.0 these privileges are granted via + User Manager for Domains, but on Windows 2000 and XP you probably + want to use Group Policy for propagating these settings. You can + also manually set these via the Local Security Policy MMC snap-in. +
    4. + +
    5. Confirm that the created account is a member of the Users + group.
    6. + +
    7. Grant the account read and execute (RX) rights to all document + and script folders (htdocs and cgi-bin + for example).
    8. + +
    9. Grant the account change (RWXD) rights to the + Apache logs directory.
    10. + +
    11. Grant the account read and execute (RX) rights to the + Apache.exe binary executable.
    12. +
    + +
    It is usually a good practice to grant the user the Apache + service runs as read and execute (RX) access to the whole Apache2 + directory, except the logs subdirectory, where the + user has to have at least change (RWXD) rights.
    + +

    If you allow the account to log in as a user and as a service, + then you can log on with that account and test that the account has the + privileges to execute the scripts, read the web pages, and that + you can start Apache in a console window. If this works, and you + have followed the steps above, Apache should execute as a service + with no problems.

    + +
    Error code 2186 is a good indication that + you need to review the "Log On As" configuration for the service, + since Apache cannot access a required network resource. Also, pay + close attention to the privileges of the user Apache is + configured to run as.
    + +

    When starting Apache as a service you may encounter an error + message from the Windows Service Control Manager. For example, + if you try to start Apache by using the Services applet in the + Windows Control Panel, you may get the following message:

    + +

    + Could not start the Apache2 service on \\COMPUTER
    + Error 1067; The process terminated unexpectedly. +

    + +

    You will get this generic error if there is any problem with + starting the Apache service. In order to see what is really causing + the problem you should follow the instructions for Running Apache + for Windows from the Command Prompt.

    + +

    There is some support for Apache on Windows 9x to behave in a + similar manner as a service on Windows NT. It is highly + experimental. It is not of production-class reliability, + and its future is not guaranteed. It can be mostly regarded as + a risky thing to play with - proceed with caution!

    + +

    There are some differences between the two kinds of services + you should be aware of:

    + +
      +
    • Apache will attempt to start and if successful it will run + in the background. If you run the command

      + +

      + apache -n "MyServiceName" -k start +

      + +

      via a shortcut on your desktop, for example, then if the + service starts successfully, a console window will flash up but + it immediately disappears. If Apache detects any errors on startup + such as incorrect entries in the httpd.conf configuration file, + the console window will remain visible. This will display an error + message which will be useful in tracking down the cause of the + problem.

    • + +
    • Windows 9x does not support NET START or + NET STOP commands. You must control the Apache + service on the command prompt via the -k switches. +

    • + +
    • Apache and Windows 9x offer no support for running Apache + as a specific user with network privileges. In fact, Windows 9x + offers no security on the local machine, either. This is the + simple reason because of which the Apache Software Foundation + never endorses use of a Windows 9x -based system as a public + Apache server. The primitive support for Windows 9x exists only + to assist the user in developing web content and learning the + Apache server, and perhaps as an intranet server on a secured, + private network.

    • + +
    + +

    Once you have confirmed that Apache runs correctly as a + console application you can install, control and uninstall the + pseudo-service with the same commands as on Windows NT. You can + also use the Apache Service Monitor to manage Windows 9x + pseudo-services.

    + +
    top
    +
    +

    Running Apache as a Console Application

    + + +

    Running Apache as a service is usually the recommended way to + use it, but it is sometimes easier to work from the command line + (on Windows 9x running Apache from the command line is the + recommended way due to the lack of reliable service support.)

    + +

    To run Apache from the command line as a console application, + use the following command:

    + +

    + apache +

    + +

    Apache will execute, and will remain running until it is stopped + by pressing Control-C.

    + +

    You can also run Apache via the shortcut Start Apache in Console + placed to Start Menu --> Programs --> Apache HTTP Server + 2.0.xx --> Control Apache Server during the installation. + This will open a console window and start Apache inside it. If you + don't have Apache installed as a service, the window will remain + visible until you stop Apache by pressing Control-C in the console + window where Apache is running in. The server will exit in a few + seconds. However, if you do have Apache installed as a service, the + shortcut starts the service. If the Apache service is running + already, the shortcut doesn't do anything.

    + +

    You can tell a running Apache to stop by opening another console + window and entering:

    + +

    + apache -k shutdown +

    + +

    This should be preferred over pressing Control-C because this + lets Apache end any current operations and clean up gracefully.

    + +

    You can also tell Apache to restart. This forces it to reread + the configuration file. Any operations in progress are allowed to + complete without interruption. To restart Apache, use:

    + +

    + apache -k restart +

    + +
    Note for people familiar with the Unix version of Apache: + these commands provide a Windows equivalent to kill -TERM + pid and kill -USR1 pid. The + command line option used, -k, was chosen as a reminder + of the kill command used on Unix.
    + +

    If the Apache console window closes immediately or unexpectedly + after startup, open the Command Prompt from the Start Menu --> + Programs. Change to the folder to which you installed Apache, type + the command apache, and read the error message. Then + change to the logs folder, and review the error.log + file for configuration mistakes. If you accepted the defaults when + you installed Apache, the commands would be:

    + +

    + c:
    + cd "\Program Files\Apache Group\Apache2\bin"
    + apache +

    + +

    Then wait for Apache to stop, or press Control-C. Then enter the + following:

    + +

    + cd ..\logs
    + more < error.log +

    + +

    When working with Apache it is important to know how it will + find the configuration file. You can specify a configuration file + on the command line in two ways:

    + +
      +
    • -f specifies an absolute or relative path to + a particular configuration file:

      + +

      + apache -f "c:\my server files\anotherconfig.conf" +

      + +

      or

      + +

      + apache -f files\anotherconfig.conf +

    • + +
    • -n specifies the installed Apache service + whose configuration file is to be used:

      + +

      + apache -n "MyServiceName" +

      +
    • +
    + +

    In both of these cases, the proper + ServerRoot should be set in + the configuration file.

    + +

    If you don't specify a configuration file with -f + or -n, Apache will use the file name compiled into the + server, such as conf\httpd.conf. This built-in path + is relative to the installation directory. You can verify the compiled + file name from a value labelled as SERVER_CONFIG_FILE when + invoking Apache with the -V switch, like this:

    + +

    + apache -V +

    + +

    Apache will then try to determine its + ServerRoot by trying the following, in this order:

    + +
      +
    1. A ServerRoot directive + via the -C command line switch.
    2. + +
    3. The -d switch on the command line.
    4. + +
    5. Current working directory.
    6. + +
    7. A registry entry which was created if you did a binary + installation.
    8. + +
    9. The server root compiled into the server. This is + /apache by default, you can verify it by using + apache -V and looking for a value labelled as + HTTPD_ROOT.
    10. +
    + +

    During the installation, a version-specific registry key is + created in the Windows registry. The location of this key depends + on the type of the installation. If you chose to install Apache + for all users, the key is located under the + HKEY_LOCAL_MACHINE hive, like this (the version + numbers will of course vary between different versions of Apache: +

    + +

    + HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\2.0.43 +

    + +

    Correspondingly, if you chose to install Apache for the current + user only, the key is located under the HKEY_CURRENT_USER + hive, the contents of which are dependent of the user currently + logged on:

    + +

    + HKEY_CURRENT_USER\SOFTWARE\Apache Group\Apache\2.0.43 +

    + +

    This key is compiled into the server and can enable you to test + new versions without affecting the current version. Of course, you + must take care not to install the new version in the same + directory as another version.

    + +

    If you did not do a binary install, Apache will in some + scenarios complain about the missing registry key. This warning can + be ignored if the server was otherwise able to find its + configuration file.

    + +

    The value of this key is the + ServerRoot directory which + contains the conf subdirectory. When Apache starts it + reads the httpd.conf file from that directory. If + this file contains a ServerRoot + directive which contains a different directory from the one + obtained from the registry key above, Apache will forget the + registry key and use the directory from the configuration file. If + you copy the Apache directory or configuration files to a new + location it is vital that you update the + ServerRoot directive in the + httpd.conf file to reflect the new location.

    + +
    top
    +
    +

    Testing the Installation

    + + +

    After starting Apache (either in a console window or as a + service) it will be listening on port 80 (unless you changed the + Listen directive in the + configuration files or installed Apache only for the current user). + To connect to the server and access the default page, launch a + browser and enter this URL:

    + +

    + http://localhost/ +

    + +

    Apache should respond with a welcome page and a link to the + Apache manual. If nothing happens or you get an error, look in the + error.log file in the logs subdirectory. + If your host is not connected to the net, or if you have serious + problems with your DNS (Domain Name Service) configuration, you + may have to use this URL:

    + +

    + http://127.0.0.1/ +

    + +

    If you happen to be running Apache on an alternate port, you + need to explicitly put that in the URL:

    + +

    + http://127.0.0.1:8080/ +

    + +

    Once your basic installation is working, you should configure it + properly by editing the files in the conf subdirectory. + Again, if you change the configuration of the Windows NT service + for Apache, first attempt to start it from the command line to + make sure that the service starts with no errors.

    + +

    Because Apache cannot share the same port with + another TCP/IP application, you may need to stop, uninstall or reconfigure + certain other services before running Apache. These conflicting + services include other WWW servers and some firewall implementations. +

    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/windows.html.ko.euc-kr b/trunk/docs/manual/platform/windows.html.ko.euc-kr new file mode 100644 index 0000000000..18ccd033aa --- /dev/null +++ b/trunk/docs/manual/platform/windows.html.ko.euc-kr @@ -0,0 +1,688 @@ + + + +Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¹ý - Apache HTTP Server + + + + + +
    <-
    +

    Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¹ý

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ÀÌ ¹®¼­´Â Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, ¼³Á¤, + ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. À߸øµÈ ºÎºÐÀÌ Àְųª ´Ù¸¥ ¹æ¹ýÀ¸·Î + µµ¿òÀ» ÁÖ·Á¸é, ¹ö±× º¸°í + ÆäÀÌÁö¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¹ÙÀ̳ʸ® ¹èÆ÷º»À» ¼³Ä¡ÇÑ´Ù°í °¡Á¤ÇÑ´Ù. + (¾Æ¸¶µµ °³¹ß ȤÀº ¹ö±×¸¦ ã±âÀ§ÇØ) Á÷Á¢ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é + Microsoft Windows¿ë ¾ÆÆÄÄ¡ + ÄÄÆÄÀÏÀ» Âü°íÇ϶ó.

    + +

    ÇöÀç Microsoft Windows ¿î¿µÃ¼Á¦±ºÀÇ ¹öÀü Á¤Ã¥»ó + ÀÌ ¹®¼­´Â ´ÙÀ½°ú °°ÀÌ ±¸ºÐÇÑ´Ù:

    +
      +
    • Windows NT: Windows NT Ä¿³ÎÀ» ±â¹ÝÀ¸·Î + ÇÏ´Â ¸ðµç Windows ¹öÀüÀ» ÀǹÌÇÑ´Ù. Windows NT, Windows + 2000, Windows XP, Windows .Net Server 2003À» ÁöĪÇÑ´Ù.
    • +
    • Windows 9x: ¼ÒºñÀÚ Áß½ÉÀÇ ¿À·¡µÈ + Windows ¹öÀüÀ» ¶æÇÑ´Ù. Windows 95 (OSR2 Æ÷ÇÔ), Windows + 98, Windows ME¸¦ ÁöĪÇÑ´Ù.
    • +
    + +
    + +
    top
    +
    +

    ¿î¿µÃ¼Á¦ ¿ä±¸Á¶°Ç

    + + +

    ¾ÆÆÄÄ¡ 2.0À» ½ÇÇàÇϱâÀ§ÇÑ ±âº» Windows Ç÷¡ÆûÀº Windows + NTÀÌ´Ù. ¹ÙÀ̳ʸ® ¼³Ä¡ÇÁ·Î±×·¥Àº Intel°ú AMD¿Í °°Àº x86 °³¿­ + ÇÁ·Î¼¼¼­¿¡¼­¸¸ µ¿ÀÛÇÑ´Ù. ¾ÆÆÄÄ¡´Â Windows 9x¿¡¼­ ÃæºÐÈ÷ + °Ë»çÇÏÁö ¾Ê¾Ò±â¶§¹®¿¡ Àý´ë·Î ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÏÁö ¾Ê±æ + ¹Ù¶õ´Ù. +

    + +

    ¿î¿µÃ¼Á¦¿¡ ¼³Ä¡ÇÑ TCP/IP ³×Æ®¿öÅ©°¡ µ¿ÀÛÇØ¾ß ÇÑ´Ù. Windows + 95¿¡¼­ ½ÇÇàÇÑ´Ù¸é, Winsock 2 ¾÷±×·¹À̵带 ¼³Ä¡ÇØ¾ß ÇÑ´Ù. + Windows 95¿ë Winsock 2´Â ¿©±â¿¡¼­ + ´Ù¿î¹ÞÀ» ¼ö ÀÖ´Ù. +

    + +

    Windows NT 4.0À» »ç¿ëÇÑ´Ù¸é ¼­ºñ½ºÆÑ 4ÀÇ TCP/IP ¹®Á¦¿Í + Winsock ¹®Á¦°¡ ´ÙÀ½ ¼­ºñ½ºÆÑ¿¡¼­ ÇØ°áµÇ¾ú±â¶§¹®¿¡, ¼­ºñ½ºÆÑ + 6À» ¼³Ä¡Çϱæ Àû±Ø ±ÇÇÑ´Ù.

    +
    top
    +
    +

    Windows¿ë ¾ÆÆÄÄ¡ ´Ù¿î·Îµå

    + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö http://httpd.apache.org/download.cgi¿¡¼­ + ¾ÆÆÄÄ¡ ÃֽŠ¹öÀü¿¡ ´ëÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù. ¿©±â¿¡´Â ÃֽŠ+ ¹ßÇ¥ÆÇ°ú ¾ËÆÄ È¤Àº º£Å¸ Å×½ºÆ®¹öÀü°ú, ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ´Ù¿î·ÎµåÇÒ + ¼ö ÀÖ´Â HTTP ¹Ì·¯¿Í FTP ¹Ì·¯ ¸ñ·ÏÀÌ ÀÖ´Ù. ºü¸£°í ¾ÈÁ¤ÇÏ°Ô + ´Ù¿î¹ÞÀ¸·Á¸é °¡±î¿î ¹Ì·¯¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    Windows¿¡ ¼³Ä¡ÇÏ·Á¸é È®ÀåÀÚ°¡ .msiÀÎ Windows¿ë + ¾ÆÆÄÄ¡ ¹öÀüÀ» ´Ù¿î¹Þ¾Æ¾ß ÇÑ´Ù. ÀÌ ÆÄÀÏÀº ¸·¹Ù·Î ½ÇÇàÇÒ ¼ö + ÀÖ´Â ¾ÆÆÄÄ¡¸¦ ÀúÀåÇÑ Microsoft ¼³Ä¡ÆÄÀÏÀÌ´Ù. µû·Î ¼Ò½ºÄڵ常 + ¹­¾îµÐ .zip ÆÄÀÏÀÌ ÀÖ´Ù. Microsoft Visual C++ + (Visual Studio)À» »ç¿ëÇÏ¿© Á÷Á¢ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ ¼öµµ ÀÖ´Ù.

    +
    top
    +
    +

    Windows¿ë ¾ÆÆÄÄ¡ ¼³Ä¡Çϱâ

    + + +

    ¼³Ä¡ÇÏ·Á¸é Microsoft Installer 1.2 ÀÌ»ó ¹öÀüÀÌ ÇÊ¿äÇÏ´Ù. + Windows 9x¸¦ »ç¿ëÇÑ´Ù¸é ¿©±â¿¡¼­ + Microsoft Installer¸¦ 2.0 ¹öÀüÀ¸·Î ¾÷±×·¹À̵åÇÒ ¼ö ÀÖ°í, + Windows NT 4.0°ú 2000À» »ç¿ëÇÑ´Ù¸é ¿©±â¿¡¼­ + 2.0 ¹öÀü ¾÷µ¥ÀÌÆ®¸¦ ±¸ÇÒ ¼ö ÀÖ´Ù. Windows XP´Â ¾÷µ¥ÀÌÆ®ÇÒ + ÇÊ¿ä°¡ ¾ø´Ù.

    + +

    ¹ÙÀ̳ʸ® ¼³Ä¡ÆÄÀϷδ °°Àº ÄÄÇ»ÅÍ¿¡ ¼­·Î ´Ù¸¥ ¾ÆÆÄÄ¡ + 2.0 ¹öÀüÀ» ¼³Ä¡ÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó. ±×·¯³ª 1.3 + ¹öÀü°ú 2.0 ¹öÀüÀº °°Àº ÄÄÇ»ÅÍ¿¡ ¾Æ¹« ¹®Á¦¾øÀÌ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. °°Àº ÄÄÇ»ÅÍ¿¡ µÎ°¡Áö ´Ù¸¥ 2.0 ¹öÀüÀ» ¼³Ä¡ÇÏ·Á¸é + ¼Ò½º¸¦ ÄÄÆÄÀÏÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇØ¾ß ÇÑ´Ù.

    + +

    À§¿¡¼­ ´Ù¿î¹ÞÀº ¾ÆÆÄÄ¡ .msi ÆÄÀÏÀ» ½ÇÇàÇÑ´Ù. + ¼³Ä¡ÇÒ¶§ ´ÙÀ½°ú °°Àº °ÍÀ» ¹°¾îº»´Ù:

    + +
      +
    1. ³×Æ®¿öÅ© µµ¸ÞÀÎ (Network Domain). + µî·ÏµÈ ¼­¹öÀÇ DNS µµ¸ÞÀÎÀ» ÀÔ·ÂÇÑ´Ù. ¿¹¸¦ µé¾î, ¼­¹öÀÇ + Àüü DNS À̸§ÀÌ server.mydomain.netÀ̶ó¸é + ¿©±â¿¡ mydomain.netÀ» ÀÔ·ÂÇÑ´Ù.

    2. + +
    3. ¼­¹ö¸í (Server Name). ¼­¹öÀÇ Àüü + DNS À̸§. À§ÀÇ °æ¿ì ¿©±â¿¡ server.mydomain.netÀ» + ÀÔ·ÂÇÑ´Ù.

    4. + +
    5. °ü¸®ÀÚ ÀüÀÚ¿ìÆí ÁÖ¼Ò (Administrator's Email + Address). ¿©±â¿¡ ¼­¹ö °ü¸®ÀÚ³ª À¥¸¶½ºÅÍÀÇ ÀüÀÚ¿ìÆí + ÁÖ¼Ò¸¦ ÀÔ·ÂÇÑ´Ù. ±âº»ÀûÀ¸·Î Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â ¿À·ù¹®¿¡ + ÀÌ ÁÖ¼Ò¸¦ ±â·ÏÇÑ´Ù.

    6. + +
    7. »ç¿ëÀÚ ´ë»ó (For whom to install + Apache) »õ·Î ¼³Ä¡ÇÏ´Â ¾ÆÆÄÄ¡°¡ 80¹ø Æ÷Æ®¿¡¼­ + ¿äûÀ» ±â´Ù¸®°Ô ÇÏ·Á¸é for All Users, on Port 80, + as a Service - Recommended (¸ðµç »ç¿ëÀÚ, 80¹ø Æ÷Æ®, + service·Î - Ãßõ)¸¦ ¼±ÅÃÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÑ´Ù + (Áï, ¾ÆÆÄÄ¡´Â ¼­¹ö¿¡ ·Î±×ÀÎÇÑ »ç¶÷ÀÌ ¾ø¾îµµ ½ÇÇàµÈ´Ù). + °³ÀÎÀûÀ¸·Î Å×½ºÆ®Çغ¸°Å³ª ÀÌ¹Ì 80¹ø Æ÷Æ®¸¦ »ç¿ëÇÏ´Â ´Ù¸¥ + À¥¼­¹ö°¡ ÀÖ´Ù¸é only for the Current User, on Port + 8080, when started Manually (ÇöÀç »ç¿ëÀÚ¸¸, 8080¹ø + Æ÷Æ®, Á÷Á¢ ½ÃÀÛ)¸¦ ¼±ÅÃÇÑ´Ù.

    8. + +
    9. ¼³Ä¡ Á¾·ù (The installation type). + ¸ðµâ °³¹ß¿¡ ÇÊ¿äÇÑ ¼Ò½ºÄÚµå¿Í ¶óÀ̺귯¸®¸¦ Á¦¿ÜÇÑ ¸ðµç + °ÍÀ» ¼³Ä¡ÇÏ·Á¸é TypicalÀ» ¼±ÅÃÇÑ´Ù. + CustomÀ» ¼±ÅÃÇÏ¸é ¼³Ä¡ÇÒ ³»¿ëÀ» ÁöÁ¤ÇÒ ¼ö + ÀÖ´Ù. Àüü ¼³Ä¡½Ã µð½ºÅ©¿¡ ºó °ø°£ÀÌ ¾à 13 ¸Þ°¡¹ÙÀÌÆ® + Á¤µµ ÇÊ¿äÇÏ´Ù. ÀÌ ¼öÄ¡´Â À¥»çÀÌÆ® Å©±â¸¦ Á¦¿ÜÇÑ + °ÍÀÌ´Ù.

    10. + +
    11. ¼³Ä¡ Àå¼Ò (Where to install). + ±âº» °æ·Î´Â C:\Program Files\Apache GroupÀÌ°í, + ÀÌ°÷¿¡ Apache2¶ó´Â µð·ºÅ丮¸¦ ¸¸µç´Ù.

    12. +
    + +

    ¼³Ä¡ÇÒ µ¿¾È ¾ÆÆÄÄ¡´Â conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϵéÀ» ¼±ÅÃÇÑ ¼³Ä¡ µð·ºÅ丮¿¡ ¸Â°Ô ±¸¼ºÇÑ´Ù. ±×·¯³ª + ÀÌ µð·ºÅ丮¿¡ ¼³Á¤ÆÄÀÏÀÌ ÀÌ¹Ì ÀÖ´Ù¸é ±×´ë·Î µÐ´Ù. ´ë½Å, + ÇØ´ç ÆÄÀÏÀÇ »õ·Î¿î º¹»çº»¿¡ È®ÀåÀÚ .default¸¦ + ºÙÀδÙ. ¿¹¸¦ µé¾î, conf\httpd.conf°¡ ÀÌ¹Ì ÀÖ´Ù¸é + conf\httpd.conf.default·Î À̸§À» º¯°æÇÑ´Ù. + ¼³Ä¡ÈÄ .default ÆÄÀÏÀÇ ¼³Á¤À» Á÷Á¢ »ìÆ캸°í, + ÇÊ¿äÇÏ´Ù¸é ±âÁ¸ ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¶Ç, ÀÌ¹Ì htdocs\index.htmlÀ̶ó´Â ÆÄÀÏÀÌ + ÀÖ´Ù¸é ±×´ë·Î µÐ´Ù (index.html.default¶ó°í + º¹»çÇÏÁöµµ ¾Ê´Â´Ù). Áï, ±âÁ¸¿¡ ¾ÆÆÄÄ¡°¡ ¼³Ä¡µÇÀÖ´õ¶óµµ ¾ÈÀüÇÏ°Ô + ¾ÆÆÄÄ¡¸¦ »õ·Î ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ¹°·Ð ¼³Ä¡Çϱâ Àü¿¡ ¼­¹ö¸¦ + Áß´ÜÇÏ°í, ¼³Ä¡ÈÄ »õ·Î¿î ¼­¹ö¸¦ ½ÃÀÛÇØ¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¼³Ä¡ÈÄ ÇÊ¿äÇÏ´Ù¸é conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. ÆÄÀÏÀº ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ µð·ºÅ丮ÀÇ + htdocs ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ¹®¼­¸¦ ¼­ºñ½ºÇϵµ·Ï + ¼³Á¤µÇÀÖ´Ù. ½ÇÁ¦·Î ¾ÆÆÄÄ¡¸¦ »ç¿ëÇϱâ Àü¿¡ ¼³Á¤ÇØ¾ß ÇÒ ¿É¼ÇÀÌ + ¸¹´Ù. ±×·¯³ª »¡¸® ½ÇÇàÇغ¼ ¼ö ÀÖµµ·Ï ±âº» ¼³Á¤ÆÄÀϷεµ µ¿ÀÛÇÑ´Ù.

    +
    top
    +
    +

    Windows¿ë ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ

    + + +

    ¾ÆÆÄÄ¡´Â conf ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏ·Î + ¼³Á¤ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¯´Ð½º¿ë°ú °°Áö¸¸, Windows¿ë ¾ÆÆÄÄ¡ + ƯÀ¯ÀÇ Áö½Ã¾î°¡ ¸î°³ ÀÖ´Ù. »ç¿ë°¡´ÉÇÑ ¸ðµç Áö½Ã¾î¸¦ º¸·Á¸é + Áö½Ã¾î ¸ñ·ÏÀ» Âü°íÇ϶ó.

    + +

    Windows¿ë ¾ÆÆÄÄ¡ÀÇ ÁÖµÈ Â÷ÀÌÁ¡Àº:

    +
      +
    • Windows¿ë ¾ÆÆÄÄ¡´Â ´ÙÁß¾²·¹µå ¹æ½ÄÀ» »ç¿ëÇϱ⶧¹®¿¡, + À¯´Ð½º¿Í ´Þ¸® ¿äû¸¶´Ù ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + ´ë½Å ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½º´Â Ç×»ó, ºÎ¸ð ÇÁ·Î¼¼½º¿Í ¿äûÀ» ó¸®ÇÏ´Â + ÀÚ½Ä ÇÁ·Î¼¼½º, 2°³ÀÌ´Ù. ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ ÀÖ´Â ¿©·¯ ¾²·¹µåµéÀÌ + ¿äûµéÀ» ó¸®ÇÑ´Ù. +

      + +

      ÇÁ·Î¼¼½º °ü¸® Áö½Ã¾îµµ ´Ù¸£´Ù:

      + +

      MaxRequestsPerChild: À¯´Ð½º¿Í + °°ÀÌ, ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¿äûÀ» ¾ó¸¶¸¸Å­ ó¸®ÇÏ°í Á×À»Áö¸¦ + Á¶Á¤ÇÑ´Ù. ±×·¯³ª À¯´Ð½º¿Í ´Þ¸® ÇÁ·Î¼¼½º°¡ Çѹø¿¡ ÇÑ ¿äû¸¸À» + ó¸®ÇÏÁö¾Ê°í Çѹø¿¡ ¸ðµç ¿äûÀ» ¼­ºñ½ºÇϱ⶧¹®¿¡, ¼³Á¤ÇÑ´Ù¸é + ¸Å¿ì Å« °ªÀ» ¼³Á¤ÇÏ±æ ±ÇÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ª + MaxRequestsPerChild 0À» »ç¿ëÇϸé ÀÚ½Ä ÇÁ·Î¼¼½º´Â + Á×Áö¾Ê°í ¿µ¿øÈ÷ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

      + +
      °æ°í: ÀÚ½Ä ÇÁ·Î¼¼½º´Â »õ·Î + ½ÃÀÛÇÒ ¶§¸¶´Ù ¼­¹ö¼³Á¤ÆÄÀÏÀ» »õ·Î Àд´Ù. + httpd.conf¸¦ ¼öÁ¤Çß´Ù¸é, ÀÚ½Ä ÇÁ·Î¼¼½º°¡ + ½ÃÀÛÇÏÁö ¾Ê°Å³ª ¿¹±âÄ¡¾ÊÀº °á°ú°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù.
      + +

      ThreadsPerChild: + ÀÌ Áö½Ã¾î´Â »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ Áö½Ã¾î´Â ¼­¹ö°¡ »ç¿ëÇÒ + ¾²·¹µå °³¼ö¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ °ªÀÌ ¼­¹ö°¡ Çѹø¿¡ ó¸®ÇÒ ¼ö + ÀÖ´Â ÃÖ´ë ¿¬°á°³¼öÀ̱⶧¹®¿¡, »çÀÌÆ®¿¡ Á¢¼Ó·®ÀÌ ¸¹´Ù¸é + ÃæºÐÈ÷ Å« °ªÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + ThreadsPerChild 50ÀÌ´Ù.

    • + +
    • ÆÄÀϸíÀ» ¾Æ±Ô¸ÕÆ®·Î ¹Þ´Â Áö½Ã¾î´Â À¯´Ð½º ÆÄÀϸíÀÌ + ¾Æ´Ñ Windows ÆÄÀϸíÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡ ³»ºÎ¿¡¼­ + À¯´Ð½º½Ä À̸§À» »ç¿ëÇϱ⶧¹®¿¡ ¹é½½·¡½¬°¡ ¾Æ´Ñ ½½·¡½¬¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. µå¶óÀÌºê ¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. µå¶óÀ̺긦 + ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ¾ÆÆÄÄ¡ ½ÇÇàÆÄÀÏÀÌ ÀÖ´Â µå¶óÀ̺긦 + »ç¿ëÇÑ´Ù.

    • + +
    • Windows¿ë ¾ÆÆÄÄ¡´Â ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°í + ½ÇÇàÁß¿¡ ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù. ±âº»°ªÀ¸·Î ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇϸé \Apache2\modules µð·ºÅ丮¿¡ ¿©·¯ + ¼±Åð¡´ÉÇÑ ¸ðµâÀ» ¼³Ä¡ÇÑ´Ù. ÀÌ ¸ðµâ ȤÀº ´Ù¸¥ ¸ðµâÀ» + »ç¿ëÇÏ·Á¸é »õ·Î »ý±ä LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î, status ¸ðµâÀ» »ç¿ëÇÑ´Ù¸é + (access.conf¿¡ status°ü·Ã Áö½Ã¾î¿Í ÇÔ²²) + ¾Æ·¡¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù:

      + +

      + LoadModule status_module modules/mod_status.so +

      + +

      ÀоîµéÀÏ ¼ö ÀÖ´Â + ¸ðµâ ¸¸µé±â¿¡ ´ëÇÑ Á¤º¸µµ ÀÖ´Ù.

    • + +
    • ¾ÆÆÄÄ¡´Â Microsoft IIS¿Í ´Ù¸¥ Windows ¼­¹ö°¡ »ç¿ëÇÏ´Â + ISAPI (Internet Server Application Programming Interface) + È®ÀåÀ» (Áï, ÀÎÅÍ³Ý ¼­¹ö ÇÁ·Î±×·¥) ÀоîµéÀÏ ¼öµµ ÀÖ´Ù. + ´õ ÀÚ¼¼ÇÑ Á¤º¸°¡ ÀÖ´Ù. + ¾ÆÆÄÄ¡´Â ISAPI ÇÊÅ͸¦ ÀоîµéÀÏ ¼ö ¾øÀ½À» + ÁÖÀÇÇ϶ó.

    • + +
    • CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ´Ù¸é ScriptInterpreterSource Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ ½ºÅ©¸³Æ®ÀÇ ÀÎÅÍÇÁ¸®Å͸¦ ã´Â ¹æ¹ýÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    • + +
    • Windows¿¡¼­ .htaccess¿Í °°Àº ÆÄÀϸíÀ» + ´Ù·ç±â Èûµå¹Ç·Î, AccessFilename Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ À̸§À» º¯°æÇϸé ÆíÇÏ´Ù.

    • + +
    • Windows NT¶ó¸é ¾ÆÆÄÄ¡ ½ÃÀ۽à ¹ß»ýÇÑ ¿À·ù¸¦ Windows + À̺¥Æ® ·Î±×¿¡ ±â·ÏÇÑ´Ù. ±×·¡¼­ ¾ÆÆÄÄ¡°¡ º¸Åë »ç¿ëÇÏ´Â + error.log ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Â °æ¿ì¿¡ ´ëºñÇÑ´Ù. + Windows À̺¥Æ® ·Î±×´Â Windows NT 4.0¿¡¼­´Â À̺¥Æ® ºä¾î + ÇÁ·Î±×·¥À¸·Î, ÃֽŠWindows ¹öÀü¿¡¼­´Â À̺¥Æ® ºä¾î MMC + ½º³ÀÀο¡¼­ º¼ ¼ö ÀÖ´Ù.

      + +
      Windows 9x¿¡´Â Windows À̺¥Æ® ·Î±×°¡ ¾ø±â¶§¹®¿¡ + ½ÃÀ۽à ¹ß»ýÇÑ ¿À·ù¸¦ ±â·ÏÇÏÁö ¾Ê´Â´Ù.
    • +
    + +
    top
    +
    +

    ¾ÆÆÄÄ¡¸¦ Service·Î ½ÇÇàÇϱâ

    + + +

    Windows NT¿¡¼­´Â ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. Windows + 9x¿¡´Â ¸Å¿ì ½ÇÇèÀûÀÎ ¹æ¹ýÀ¸·Î ºñ½ÁÇÑ ±â´ÉÀ» Áö¿øÇÑ´Ù.

    + +

    ¼³Ä¡½Ã ÀÚµ¿À¸·Î ¾ÆÆÄÄ¡¸¦ service·Î ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. "¸ðµç + »ç¿ëÀÚ"¸¦ ¼±ÅÃÇϸé, ¾ÆÆÄÄ¡ service°¡ ¸¸µé¾îÁø´Ù. "ÇöÀç + »ç¿ëÀÚ¸¸"À» ¼±ÅÃÇÏ´õ¶óµµ ¼³Ä¡ÈÄ Á÷Á¢ ¾ÆÆÄÄ¡¸¦ service·Î + µî·ÏÇÒ ¼ö ÀÖ´Ù. service¸¦ ¼³Ä¡ÇÏ·Á¸é Administrators ±×·ìÀÇ + ±¸¼º¿øÀ̾î¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡´Â Apache Service Monitor¶ó´Â µµ±¸°¡ ÀÖ´Ù. ÀÌ + µµ±¸¸¦ »ç¿ëÇÏ¸é ³×Æ®¿÷¿¡ ÀÖ´Â ´Ù¸¥ ÄÄÇ»ÅÍ¿¡ ¼³Ä¡µÈ ¾ÆÆÄÄ¡ + »óŵµ È®ÀÎÇÏ°í °ü¸®ÇÒ ¼ö ÀÖ´Ù. monitor·Î ¾ÆÆÄÄ¡ service¸¦ + °ü¸®ÇÏ·Á¸é ¸ÕÀú service¸¦ (¼³Ä¡½Ã ÀÚµ¿À¸·Î ȤÀº Á÷Á¢) ¼³Ä¡ÇØ¾ß + ÇÑ´Ù. +

    + +

    ¾ÆÆÄÄ¡ bin ÇÏÀ§µð·ºÅ丮¿¡¼­ ¸í·ÉÇà ÇÁ·ÒÇÁÆ®¿¡ + ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÏ¸é ¾ÆÆÄÄ¡¸¦ Windows NT service·Î ¼³Ä¡ÇÑ´Ù:

    + +

    + apache -k install +

    + +

    ¼³Ä¡ÇÒ service À̸§À» ÁöÁ¤ÇÏ°í ½Í´Ù¸é ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. + ÄÄÇ»ÅÍ¿¡ ¾ÆÆÄÄ¡°¡ ¿©·¯°³ ¼³Ä¡µÇÀÖ´Ù¸é À̸§À» ´Ù¸£°Ô ÁÖ¾î¾ß + ÇÑ´Ù.

    + +

    + apache -k install -n "MyServiceName" +

    + +

    service°¡ »ç¿ëÇÒ ¼³Á¤ÆÄÀÏÀ» Á÷Á¢ ÁöÁ¤ÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ + ÇÑ´Ù:

    + +

    + apache -k install -n "MyServiceName" -f "c:\files\my.conf" +

    + +

    -k install ¿Ü¿¡ ´Ù¸¥ ÆĶó¹ÌÅ͸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é, service À̸§Àº Apache2°¡ µÇ°í ¼³Á¤ÆÄÀÏÀº + conf\httpd.conf°¡ µÈ´Ù. +

    + +

    ¾ÆÆÄÄ¡ service¸¦ Á¦°ÅÇϱ⠽±´Ù. °£´ÜÈ÷:

    + +

    + apache -k uninstall +

    + +

    ´ÙÀ½°ú °°ÀÌ Á¦°ÅÇÒ ¾ÆÆÄÄ¡ service¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù:

    + +

    + apache -k uninstall -n "MyServiceName" +

    + +

    º¸Åë ¾ÆÆÄÄ¡ service ½ÃÀÛ, Àç½ÃÀÛ, Á¾·á´Â Apache Service + Monitor³ª NET START Apache2, NET STOP + Apache2 °°Àº ¸í·É¾î ȤÀº Windows ¼­ºñ½º °ü¸®Ã¢¿¡¼­ + ÇÑ´Ù. ¾î¶² ¹æ¹ýÀ» »ç¿ëÇϵçÁö ¾ÆÆÄÄ¡ service¸¦ ½ÃÀÛÇϱâ Àü¿¡ + ¼³Á¤ÆÄÀÏÀ» °Ë»çÇغÁ¾ß ÇÑ´Ù:

    + +

    + apache -n "MyServiceName" -t +

    + +

    ¸í·ÉÇà ¿É¼ÇÀ¸·Îµµ ¾ÆÆÄÄ¡ service¸¦ Á¶Á¤ÇÒ ¼ö ÀÖ´Ù. ¼³Ä¡ÇÑ + ¾ÆÆÄÄ¡ serivce¸¦ ½ÃÀÛÇÏ·Á¸é:

    + +

    + apache -k start +

    + +

    ¸í·ÉÇà ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡ service¸¦ Á¾·áÇÏ·Á¸é:

    + +

    + apache -k stop +

    + +

    ȤÀº

    + +

    + apache -k shutdown +

    + +

    ½ÇÇàÁßÀÎ service¸¦ Àç½ÃÀÛÇÏ¿© ¼³Á¤ÆÄÀÏÀ» ´Ù½Ã Àеµ·Ï + ÇÒ ¼ö ÀÖ´Ù:

    + +

    + apache -k restart +

    + +

    ±âº»ÀûÀ¸·Î ¸ðµç ¾ÆÆÄÄ¡ service´Â ½Ã½ºÅÛ »ç¿ëÀÚ + (LocalSystem °èÁ¤) ±ÇÇÑÀ¸·Î ½ÇÇàÇϵµ·Ï µî·ÏµÈ´Ù. + Windows º¸¾È±¸Á¶»ó LocalSystem °èÁ¤Àº ÆÄÀϽýºÅÛ, + named pipes, DCOM, secure RPC µî ¾î¶² ¹æ¹ýÀ» »ç¿ëÇϵçÁö + ³×Æ®¿÷¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ÇØ´ç ÄÄÇ»ÅÍ¿¡¼­´Â ¸¹Àº ±ÇÇÑÀ» + °¡Áø´Ù. +

    + +
    LocalSystem °èÁ¤¿¡°Ô + ³×Æ®¿÷ ±ÇÇÑÀ» Àý´ë·Î ÁÖÁö ¸¶¶ó! ¾ÆÆÄÄ¡°¡ ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇØ¾ß + ÇÑ´Ù¸é, ¾Æ·¡¿¡¼­ ¼³¸íÇÏ´Â ¹æ¹ýÀ¸·Î ¾ÆÆÄÄ¡¸¦ À§ÇÑ º°µµÀÇ + °èÁ¤À» ¸¸µé¾î¶ó.
    + +

    ¾ÆÆÄÄ¡ service¸¦ ½ÇÇàÇϱâÀ§ÇÑ º°µµÀÇ °èÁ¤À» ¸¸µé ¼öµµ + ÀÖ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡°¡ ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇØ¾ß ÇÑ´Ù¸é ÀÌ ¹æ¹ýÀ» + °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + +
      +
    1. ÀÏ¹Ý µµ¸ÞÀÎ »ç¿ëÀÚ °èÁ¤À» ¸¸µé°í ¾ÏÈ£¸¦ ±â¾ïÇ϶ó.
    2. + +
    3. »õ·Î ¸¸µç °èÁ¤¿¡ ¼­ºñ½º·Î ·Î±×¿Â¿Í + ¿î¿µ üÁ¦ÀÇ ÀϺηΠȰµ¿ ±ÇÇÑÀ» + ºÎ¿©ÇÑ´Ù. Windows NT 4.0¿¡¼­´Â User Manager for Domains¿¡¼­ + ±ÇÇÑÀ» ºÎ¿©ÇÒ ¼ö ÀÖ°í, Windows 2000°ú XP¿¡¼­´Â ¾Æ¸¶µµ + "±×·ì Á¤Ã¥"À» »ç¿ëÇØ¾ß ÇÑ´Ù. "·ÎÄà º¸¾È ¼³Á¤" MMC + ½º³ÀÀο¡¼­ Á÷Á¢ ¼³Á¤ÇØÁÙ ¼öµµ ÀÖ´Ù. +
    4. + +
    5. »õ·Î ¸¸µç °èÁ¤ÀÌ Users ±×·ì¿¡ ¼ÓÇÏ´ÂÁö È®ÀÎÇÑ´Ù.
    6. + +
    7. ¸ðµç ¹®¼­¿Í ½ºÅ©¸³Æ® Æú´õ¿¡ (¿¹¸¦ µé¾î + htdocs¿Í cgi-bin) ´ëÇØ ÀÐ±â ¹× + ½ÇÇà (RX) ±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù.
    8. + +
    9. ¾ÆÆÄÄ¡ logs µð·ºÅ丮¿¡ ¼öÁ¤ (RWXD) ±ÇÇÑÀ» + ºÎ¿©ÇÑ´Ù.
    10. + +
    11. Apache.exe ½ÇÇàÆÄÀÏ¿¡ ÀÐ±â ¹× ½ÇÇà (RX) + ±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù.
    12. +
    + +
    ¾ÆÆÄÄ¡ service¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿¡°Ô ÃÖ¼ÒÇÑ ¼öÁ¤ (RWXD) + ±ÇÇÑÀÌ ÇÊ¿äÇÑ logs ÇÏÀ§µð·ºÅ丮¸¦ Á¦¿ÜÇÏ°í + Apache2 µð·ºÅ丮 Àüü¿¡ ÀÐ±â ¹× ½ÇÇà (RX) ±ÇÇÑÀ» ºÎ¿©ÇÏ´Â + °ÍÀÌ ÁÁ´Ù.
    + +

    °èÁ¤¿¡ "·ÎÄà ·Î±×¿Â"°ú "¼­ºñ½º·Î ·Î±×¿Â" ±ÇÇÑÀÌ ÀÖ´Ù¸é, + ±× °èÁ¤À¸·Î ·Î±×¿ÂÇÏ¿© °èÁ¤ÀÌ ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ°í À¥ÆäÀÌÁö¸¦ + ÀÐÀ¸¸ç ÄܼÖâ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÒ ¼ö ÀÖ´ÂÁö °Ë»çÇغ¼ ¼ö + ÀÖ´Ù. ¿©±â¼­ ¹®Á¦°¡ ¾ø´Ù¸é ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇصµ ¹®Á¦°¡ + ¾ø´Ù.

    + +
    Error code 2186Àº ¾ÆÆÄÄ¡°¡ ÇÊ¿äÇÑ + ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù´Â ¸»·Î serviceÀÇ "·Î±×¿Â" + ¼³Á¤À» È®ÀÎÇ϶ó. ¶Ç, ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â °èÁ¤ÀÇ ±ÇÇÑÀ» + »ìÆìºÁ¶ó.
    + +

    ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇϸé Windows Service Control + Manager¿¡¼­ ¿À·ù¹®À» º¼ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, Á¦¾îÆÇ¿¡¼­ + "¼­ºñ½º"¸¦ »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ´Â °æ¿ì ´ÙÀ½°ú °°Àº ¹®±¸°¡ + ³ª¿Ã ¼ö ÀÖ´Ù:

    + +

    + Could not start the Apache2 service on \\COMPUTER
    + Error 1067; The process terminated unexpectedly. +

    + +

    ¾ÆÆÄÄ¡ service¸¦ ½ÃÀÛÇÒ¶§ ¹®Á¦°¡ ÀÖÀ¸¸é ÀϹÝÀûÀÎ ÀÌ·± + ¿À·ù°¡ ³ª¿Â´Ù. ½ÇÁ¦ ¾îµð°¡ ¹®Á¦ÀÎÁö ¾Ë·Á¸é ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö + ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇغ¸¶ó.

    + +

    Windows 9x¿¡¼­ ¾ÆÆÄÄ¡´Â Windows NTÀÇ service¿Í ºñ½ÁÇÑ + ¹æ¹ýÀ» Áö¿øÇÑ´Ù. ±×·¯³ª ¸Å¿ì ½ÇÇèÀûÀÎ ±â´ÉÀÌ´Ù. + ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÒ¸¸Å­ ¾ÈÁ¤ÀûÀÌÁö ¾Ê°í ¾ÕÀ¸·Î °³¼±µÉÁö + º¸ÀåÇÒ ¼öµµ ¾ø´Ù. À§ÇèÇϹǷΠȤ½Ã³ª »ç¿ëÇÑ´Ù¸é ÁÖÀÇÇؼ­ + »ç¿ëÇØ¾ß ÇÑ´Ù!

    + +

    µÎ°¡Áö serviceÀÇ Áß¿äÇÑ Â÷ÀÌÁ¡Àº ´ÙÀ½°ú °°´Ù:

    + +
      +
    • ¾ÆÆÄÄ¡°¡ ¼º°øÀûÀ¸·Î ½ÃÀÛÇÏ¸é ¹è°æ¿¡¼­ ½ÇÇàÇÑ´Ù. + ¿¹¸¦ µé¾î, µ¥½ºÅ©Å¾¿¡ ¹Ù·Î°¡±â¸¦ ¸¸µé¾î¼­ ´ÙÀ½ ¸í·ÉÀ» + ½ÇÇàÇÏ´Â °æ¿ì,

      + +

      + apache -n "MyServiceName" -k start +

      + +

      service°¡ ¼º°øÀûÀ¸·Î ½ÃÀÛÇϸé ÄܼÖâÀÌ »ý°å´Ù°¡ ±Ý¹æ + »ç¶óÁø´Ù. httpd.conf ¼³Á¤ÆÄÀÏ¿¡ À߸øµÈ ³»¿ëÀÌ ÀÖ´Â µî + ¾ÆÆÄÄ¡ ½ÃÀ۽à ¿À·ù°¡ ¹ß»ýÇϸé ÄܼÖâÀ» °è¼Ó º¸ÀδÙ. ÄܼÖâÀº + ¹®Á¦ÀÇ ¿øÀÎÀ» ÆľÇÇϴµ¥ µµ¿òÀ» ÁÖ´Â ¿À·ù¹®À» º¸¿©ÁØ´Ù.

    • + +
    • Windows 9x´Â NET START¿Í NET + STOP ¸í·É¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù. ¸í·ÉÇÁ·ÒÇÁÆ®¿¡¼­ + -k ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡ service¸¦ Á¶Á¤ÇØ¾ß + ÇÑ´Ù. +

    • + +
    • + ¾ÆÆÄÄ¡¿Í Windows 9x´Â ³×Æ®¿÷ ±ÇÇÑÀ» °¡Áø ƯÁ¤ »ç¿ëÀÚ·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏÁö ¸øÇÑ´Ù. »ç½Ç Windows 9x´Â º¸¾ÈÀ» Á¦°øÇÏÁöµµ + ¾Ê´Â´Ù. ÀÌ°ÍÀÌ ¹Ù·Î Apache Software FoundationÀÌ Windows + 9x ½Ã½ºÅÛÀ» °ø°³ À¥¼­¹ö·Î »ç¿ëÇÏ±æ ±ÇÇÏÁö ¾Ê´Â ÀÌÀ¯´Ù. + »ç¿ëÀÚ°¡ À¥ ÄÁÅÙÃ÷¸¦ °³¹ßÇÏ°í ¾ÆÆÄÄ¡ ¼­¹ö ÇнÀÀ» µ½±âÀ§ÇØ, + ¾Æ´Ï¸é ¾ÈÀüÇÑ »ç¼³ ³×Æ®¿÷¿¡ À§Ä¡ÇÒ ÀÎÆ®¶ó³Ý ¼­¹ö¸¦ À§ÇØ, + Windows 9x¸¦ Áö¿øÇÒ »ÓÀÌ´Ù.

    • + +
    + +

    ¾ÆÆÄÄ¡°¡ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î µ¿ÀÛÇÔÀ» È®ÀÎÇÏ¿´´Ù¸é Windows + NT¿¡¼­¿Í °°Àº ¸í·É¾î·Î °¡»ó service¸¦ ¼³Ä¡, Á¶Àý, Á¦°ÅÇÒ + ¼ö ÀÖ´Ù. ¶Ç, Apache Service Monitor¸¦ »ç¿ëÇÏ¿© Windows 9x + °¡»ó service¸¦ °ü¸®ÇÒ ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇϱâ

    + + +

    ÀϹÝÀûÀ¸·Î ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÏ±æ ±ÇÇÑ´Ù. ±×·¯³ª + ¸í·ÉÇà¿¡¼­ ½ÇÇàÇÏ´Â°Ô ÆíÇÑ °æ¿ì°¡ ÀÖ´Ù (Windows 9x¿¡¼­´Â + service¸¦ ¾ÈÁ¤ÀûÀ¸·Î Áö¿øÇÏÁö ¾Ê±â¶§¹®¿¡ ¸í·ÉÇà¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ±ÇÇÑ´Ù).

    + +

    ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÏ·Á¸é, ¸í·ÉÇà¿¡¼­ ´ÙÀ½ + ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù:

    + +

    + apache +

    + +

    ¾ÆÆÄÄ¡´Â Control-C¸¦ ´­·¯¼­ Á¤ÁöÇÒ ¶§±îÁö ½ÇÇàµÈ´Ù.

    + +

    ¶Ç, ½ÃÀÛ ¸Þ´º --> ÇÁ·Î±×·¥ --> Apache HTTP + Server 2.0.xx --> Control Apache Server¿¡ ¼³Ä¡µÈ + Start Apache in Console ¹Ù·Î°¡±â·Î ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + ¹Ù·Î°¡±â¸¦ ½ÇÇàÇϸé ÄܼÖâÀ» ¿­°í ±× ¾È¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù. + ¾ÆÆÄÄ¡¸¦ service·Î ¼³Ä¡ÇÏÁö ¾Ê¾Ò´Ù¸é, ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â + ÄܼÖâ¿¡¼­ Control-C¸¦ ´­·¯ ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÒ¶§±îÁö âÀÌ ¶°ÀÖ´Ù. + ÀÌ °æ¿ì ¼­¹ö´Â ¸îÃʾȿ¡ Á¾·áÇÑ´Ù. ±×·¯³ª, ¾ÆÆÄÄ¡¸¦ service·Î + ¼³Ä¡ÇÏ¿´´Ù¸é ¹Ù·Î°¡±â´Â service¸¦ ½ÃÀÛÇÑ´Ù. ¾ÆÆÄÄ¡ service°¡ + ÀÌ¹Ì ½ÇÇàÁßÀ̶ó¸é ¹Ù·Î°¡±â´Â ¾Æ¹«Àϵµ ÇÏÁö ¾Ê´Â´Ù.

    + +

    ´Ù¸¥ ÄܼÖâÀ» ¿­°í ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÏ¿© ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡¸¦ + Á¾·áÇÒ ¼ö ÀÖ´Ù:

    + +

    + apache -k shutdown +

    + +

    ÀÌ ¹æ¹ýÀº ¾ÆÆÄÄ¡°¡ ÇöÀç ÀÛ¾÷À» ¸¶Ä¡°í Á¡ÀÝ°Ô Á¾·áÇÒ ¼ö + Àֱ⶧¹®¿¡ Control-C º¸´Ù ³´´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡¸¦ Àç½ÃÀÛÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ¼³Á¤ÆÄÀÏÀ» ´Ù½Ã + Àд´Ù. ÁøÇàÁßÀÎ ÀÛ¾÷À» Áß°£¿¡ ²÷Áö¾Ê°í ¿Ï·áÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ + Àç½ÃÀÛÇÏ·Á¸é:

    + +

    + apache -k restart +

    + +
    À¯´Ð½º¿ë ¾ÆÆÄÄ¡¿¡ Àͼ÷ÇÑ »ç¶÷À» À§ÇØ: ÀÌ ¸í·É¾î´Â + kill -TERM pid³ª kill -USR1 + pidÀÇ WindowsÆÇÀÌ´Ù. ¸í·ÉÇà ¿É¼Ç + -k´Â À¯´Ð½º kill ¸í·É¾î À̸§À» + º»µû Áö¾ú´Ù.
    + +

    ¾ÆÆÄÄ¡ ÄܼÖâÀÌ Áï½Ã ȤÀº ½ÃÀÛÈÄ °©Àڱ⠴ÝÄ¡¸é ½ÃÀÛ ¸Þ´º + --> ÇÁ·Î±×·¥ÀÇ ¸í·É ÇÁ·ÒÇÁÆ®¸¦ ½ÇÇàÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ + Æú´õ·Î °¡¼­ apache ¸í·É¾î¸¦ ½ÇÇàÇغ¸°í ¹ß»ýÇÑ + ¿À·ù¹®À» »ìÆ캻´Ù. ±×¸®°í logs Æú´õ·Î °¡¼­, ¼³Á¤ÆÄÀÏÀÌ + À߸øµÇ¾ú´ÂÁö error.log ÆÄÀÏÀ» »ìÆ캻´Ù. ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇÒ¶§ ±âº»°ªÀ» »ç¿ëÇß´Ù¸é ´ÙÀ½°ú °°´Ù:

    + +

    + c:
    + cd "\Program Files\Apache Group\Apache2\bin"
    + apache +

    + +

    ¾ÆÆÄÄ¡°¡ Á¤ÁöÇÒ ¶§±îÁö ±â´Ù¸®°Å³ª Control-C¸¦ ´©¸¥´Ù. + ±×¸®°í ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù:

    + +

    + cd ..\logs
    + more < error.log +

    + +

    ¾ÆÆÄÄ¡¸¦ ´Ù·ê¶§ ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ¼³Á¤ÆÄÀÏÀ» ã´ÂÁö ¾Æ´Â + °ÍÀÌ Áß¿äÇÏ´Ù. µÎ°¡Áö ¹æ¹ýÀ¸·Î ¸í·ÉÇà¿¡¼­ ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù:

    + +
      +
    • -f´Â ¼³Á¤ÆÄÀÏÀÇ Àý´ë°æ·Î ȤÀº »ó´ë°æ·Î¸¦ + ÁöÁ¤ÇÑ´Ù:

      + +

      + apache -f "c:\my server files\anotherconfig.conf" +

      + +

      ȤÀº

      + +

      + apache -f files\anotherconfig.conf +

    • + +
    • -nÀº ¾ÆÆÄÄ¡ service¸¦ ¼±ÅÃÇÏ°í, ÇØ´ç + serviceÀÇ ¼³Á¤ÆÄÀÏÀ» »ç¿ëÇÑ´Ù:

      + +

      + apache -n "MyServiceName" +

      +
    • +
    + +

    µÎ °æ¿ì ¸ðµÎ ¼³Á¤ÆÄÀÏÀÌ ÀûÀýÇÑ ServerRoot¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    -f³ª -nÀ¸·Î ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÏÁö + ¾ÊÀ¸¸é, ¾ÆÆÄÄ¡´Â conf\httpd.conf¿Í °°ÀÌ ¼­¹ö¿¡ + ÄÄÆÄÀÏµÈ ÆÄÀϸíÀ» »ç¿ëÇÑ´Ù. ÀÌ ±âº» °æ·Î´Â ¼³Ä¡ µð·ºÅ丮¿¡ + »ó´ëÀûÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ -V ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇϸé SERVER_CONFIG_FILEÀ̶õ Ç׸ñ¿¡¼­ ¼­¹ö°¡ + »ç¿ëÇÒ ¼³Á¤ÆÄÀÏÀ» ¾Ë ¼ö ÀÖ´Ù:

    + +

    + apache -V +

    + +

    ¾ÆÆÄÄ¡´Â ´ÙÀ½ ¼ø¼­´ë·Î ServerRoot¸¦ ã´Â´Ù:

    + +
      +
    1. -C ¸í·ÉÇà ¿É¼Ç¿¡ »ç¿ëÇÑ ServerRoot Áö½Ã¾î.
    2. + +
    3. -d ¸í·ÉÇà ¿É¼Ç.
    4. + +
    5. ÇöÀç ÀÛ¾÷ µð·ºÅ丮.
    6. + +
    7. ¹ÙÀ̳ʸ® ¼³Ä¡¸¦ Çß´Ù¸é ¼³Ä¡ÇÒ¶§ ¸¸µç registry Ç׸ñ.
    8. + +
    9. ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root. ±âº»°ªÀº + /apacheÀÌ°í, apache -V¸¦ ½ÇÇàÇϸé + HTTPD_ROOT¶ó´Â Ç׸ñ¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ´Ù.
    10. +
    + +

    ¼³Ä¡ÇÒ¶§ À©µµ¿ìÁî ·¹Áö½ºÆ®¸®¿¡ ¹öÀü ƯÀ¯ÀÇ ·¹Áö½ºÆ®¸® + Å°¸¦ ¸¸µç´Ù. Å°ÀÇ À§Ä¡´Â ¼³Ä¡ Á¾·ù¿¡ µû¶ó ´Ù¸£´Ù. install + Apache for all users¸¦ ¼±ÅÃÇÏ¿´´Ù¸é + HKEY_LOCAL_MACHINE ¾Æ·¡¿¡ ´ÙÀ½°ú °°Àº Å°¸¦ + ¸¸µç´Ù (¹°·Ð ¹öÀü¹øÈ£´Â ¾ÆÆÄÄ¡ ¹öÀü¸¶´Ù ´Ù¸£´Ù): +

    + +

    + HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\2.0.43 +

    + +

    "¸ðµç »ç¿ëÀÚ"¸¦ ´ë»óÀ¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ¿´´Ù¸é + HKEY_CURRENT_USER ¾Æ·¡ Å°°¡ »ý±ä´Ù. ³»¿ëÀº + ÇöÀç ·Î±×¿ÂÇÑ »ç¿ëÀÚ¿¡ µû¶ó ´Ù¸£´Ù:

    + +

    + HKEY_CURRENT_USER\SOFTWARE\Apache Group\Apache\2.0.43 +

    + +

    Å° À̸§ÀÌ ¼­¹ö¿¡ ÄÄÆÄÀϵDZ⶧¹®¿¡ ÇöÀç ¹öÀüÀ» °Çµå¸®Áö¾Ê°í + »õ·Î¿î ¹öÀüÀ» ¼³Ä¡ÇÏ¿© Å×½ºÆ®Çغ¼ ¼ö ÀÖ´Ù. ¹°·Ð »õ ¹öÀüÀ» + ´Ù¸¥ ¹öÀü°ú °°Àº µð·ºÅ丮¿¡ ¼³Ä¡ÇÏÁö¾Êµµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù.

    + +

    ¹ÙÀ̳ʸ® ¼³Ä¡¸¦ ÇÏÁö ¾ÊÀº °æ¿ì ¾ÆÆÄÄ¡´Â ·¹Áö½ºÆ®¸® Å°°¡ + ¾ø´Ù°í ºÒÆòÇÒ ¼ö ÀÖ´Ù. ¼­¹ö°¡ ´Ù¸¥ ¹æ¹ýÀ¸·Î ¼³Á¤ÆÄÀÏÀ» ãÀ» + ¼ö ÀÖ´Ù¸é ÀÌ °æ°í¸¦ ¹«½ÃÇصµ µÈ´Ù.

    + +

    Å°ÀÇ °ªÀº ServerRoot + µð·ºÅ丮À̸ç, ÀÌ µð·ºÅ丮¿¡ conf¶ó´Â ÇÏÀ§µð·ºÅ丮°¡ + ÀÖ´Ù. ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé ÀÌ ÇÏÀ§µð·ºÅ丮¿¡¼­ + httpd.conf ÆÄÀÏÀ» Àд´Ù. ÀÌ ÆÄÀÏ¿¡ ³ª¿À´Â + ServerRoot Áö½Ã¾î°¡ + ·¹Áö½ºÆ®¸® Å°¿¡ ³ª¿Â µð·ºÅ丮¿Í ´Ù¸£´Ù¸é, ¾ÆÆÄÄ¡´Â ·¹Áö½ºÆ®¸®¿¡¼­ + ¾òÀº °ªÀ» ¹«½ÃÇÏ°í ¾ÕÀ¸·Î ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â µð·ºÅ丮¸¦ »ç¿ëÇÑ´Ù. + ¾ÆÆÄÄ¡ µð·ºÅ丮³ª ¼³Á¤ÆÄÀÏÀ» ´Ù¸¥ Àå¼Ò·Î º¹»çÇÏ¸é ¹Ýµå½Ã + httpd.conf ÆÄÀÏ¿¡ ÀÖ´Â ServerRoot Áö½Ã¾î¸¦ ±× À§Ä¡·Î + ¼öÁ¤Ç϶ó.

    + +
    top
    +
    +

    Á¤»óÀûÀ¸·Î ¼³Ä¡µÇ¾ú´ÂÁö °Ë»çÇϱâ

    + + +

    (ÄܼÖâÀ̳ª service¸¦ ÅëÇØ) ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé (¼³Á¤ÆÄÀÏÀÇ + Listen Áö½Ã¾î¸¦ + ¼öÁ¤Çϰųª ¾ÆÆÄÄ¡¸¦ "ÇöÀç »ç¿ëÀÚ¸¸" ´ë»óÀ¸·Î ¼³Ä¡ÇÏÁö ¾Ê´Â + °æ¿ì) 80¹ø Æ÷Æ®¸¦ ±â´Ù¸°´Ù. ºê¶ó¿ìÀú¸¦ ½ÃÀÛÇÏ°í URLÀ» ÀÔ·ÂÇÏ¿© + ¼­¹öÀÇ ±âº» ÆäÀÌÁö¿¡ Á¢±ÙÇÏ´Ù:

    + +

    + http://localhost/ +

    + +

    ¾ÆÆÄÄ¡´Â ¾ÆÆÄÄ¡ ¼³¸í¼­ ¸µÅ©°¡ Àִ ȯ¿µÆäÀÌÁö¸¦ º¸¿©Áà¾ß + ÇÑ´Ù. ¾Æ¹« Àϵµ ÀϾÁö ¾Ê°Å³ª ¿À·ù°¡ ³ª¿À¸é, logs + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â error.log ÆÄÀÏÀ» »ìÆìºÁ¶ó. + È£½ºÆ®°¡ ³×Æ®¿÷¿¡ ¿¬°áµÇÀÖÁö ¾Ê°Å³ª DNS (Domain Name Service) + ¼³Á¤¿¡ ¹®Á¦°¡ ÀÖ´Ù¸é ´ÙÀ½ URLÀ» »ç¿ëÇØ¾ß ÇÑ´Ù:

    + +

    + http://127.0.0.1/ +

    + +

    ±âº» ¼³Ä¡°¡ µ¿ÀÛÇϸé conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀÏÀ» ÀûÀýÈ÷ ¼³Á¤ÇÑ´Ù. ¶Ç, Windows NT ¾ÆÆÄÄ¡ service + ¼³Á¤À» ¼öÁ¤ÇÑ °æ¿ì ¸ÕÀú ¸í·ÉÇà¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ¿© ¿À·ù°¡ + ¹ß»ýÇÏÁö¾Ê´ÂÁö È®ÀÎÇØ¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡°¡ ´Ù¸¥ TCP/IP ÇÁ·Î±×·¥°ú °°Àº Æ÷Æ®¸¦ °øÀ¯ÇÒ ¼ö + ¾ø±â¶§¹®¿¡ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϱâ Àü¿¡ ´Ù¸¥ + ¼­ºñ½º¸¦ Áß´Ü, Á¦°Å, Àç¼³Á¤ÇØ¾ß ÇÒÁöµµ ¸ð¸¥´Ù. ´Ù¸¥ À¥¼­¹ö³ª + ƯÁ¤ ¹æÈ­º® ¼­¹ö½º¿Í Ãæµ¹ÇÒ ¼ö ÀÖ´Ù. +

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/platform/windows.xml b/trunk/docs/manual/platform/windows.xml new file mode 100644 index 0000000000..0872cbe87c --- /dev/null +++ b/trunk/docs/manual/platform/windows.xml @@ -0,0 +1,729 @@ + + + + + + + + + Platform Specific Notes + + Using Apache with Microsoft Windows + + + +

    This document explains how to install, configure and run + Apache 2.0 under Microsoft Windows. If you find any bugs, or + wish to contribute in other ways, please use our bug reporting + page.

    + +

    This document assumes that you are installing a binary + distribution of Apache. If you want to compile Apache yourself + (possibly to help with development or tracking down bugs), + see Compiling Apache for Microsoft + Windows.

    + +

    Because of the current versioning policies on Microsoft + Windows operating system families, this document assumes the + following:

    +
      +
    • Windows NT: This means all versions of + Windows that are based on the Windows NT kernel. Includes Windows + NT, Windows 2000, Windows XP and Windows .Net Server 2003.
    • +
    • Windows 9x: This means older, + consumer-oriented versions of Windows. Includes Windows 95 (also + OSR2), Windows 98 and Windows ME.
    • +
    + +
    + +
    + Operating System Requirements + +

    The primary Windows platform for running Apache 2.0 is Windows + NT. The binary installer only works with the x86 family of + processors, such as Intel and AMD processors. Running Apache on + Windows 9x is not thoroughly tested, and it is never recommended on + production systems. +

    + +

    On all operating systems, TCP/IP networking must be installed + and working. If running on Windows 95, the Winsock 2 upgrade must + be installed. Winsock 2 for Windows 95 can be downloaded from here. +

    + +

    On Windows NT 4.0, installing Service Pack 6 is strongly + recommended, as Service Pack 4 created known issues with TCP/IP + and Winsock integrity that were resolved in later Service Packs.

    +
    + +
    + Downloading Apache for Windows + +

    Information on the latest versions of Apache can be found on the + web site of the Apache web server at + http://httpd.apache.org/download.cgi. + There you will find the current release, as well as more recent alpha + or beta test versions, and a list of HTTP and FTP mirrors from which + you can download the Apache web server. Please use a mirror near to + you for a fast and reliable download.

    + +

    For Windows installations you should download the version of + Apache for Windows with the .msi extension. This is a + single Microsoft Installer file, which contains a ready-to-run + version of Apache. There is a separate .zip file, + which contains only the source code. You can compile Apache + yourself with the Microsoft Visual C++ (Visual Studio) tools.

    +
    + +
    + Installing Apache for Windows + +

    You need Microsoft Installer 1.2 or above for the installation + to work. On Windows 9x you can update your Microsoft Installer to + version 2.0 here + and on Windows NT 4.0 and 2000 the version 2.0 update can be found + here. + Windows XP does not need this update.

    + +

    Note that you cannot install two versions of Apache 2.0 on the + same computer with the binary installer. You can, however, install + a version of the 1.3 series and a version of the + 2.0 series on the same computer without problems. If you need to + have two different 2.0 versions on the same computer, you have to + compile and install Apache from the + source.

    + +

    Run the Apache .msi file you downloaded above. The + installation will ask you for these things:

    + +
      +
    1. Network Domain. Enter the DNS domain in which + your server is or will be registered in. For example, if your + server's full DNS name is server.mydomain.net, you would + type mydomain.net here.

    2. + +
    3. Server Name. Your server's full DNS name. + From the example above, you would type server.mydomain.net + here.

    4. + +
    5. Administrator's Email Address. Enter the + server administrator's or webmaster's email address here. This + address will be displayed along with error messages to the client + by default.

    6. + +
    7. For whom to install Apache Select for + All Users, on Port 80, as a Service - Recommended if you'd + like your new Apache to listen at port 80 for incoming traffic. + It will run as a service (that is, Apache will run even if no one + is logged in on the server at the moment) Select only for + the Current User, on Port 8080, when started Manually if + you'd like to install Apache for your personal experimenting or + if you already have another WWW server running on port 80.

    8. + +
    9. The installation type. Select Typical + for everything except the source code and libraries for module + development. With Custom you can specify what to + install. A full install will require about 13 megabytes of free + disk space. This does not include the size of your web + site(s).

    10. + +
    11. Where to install. The default path is + C:\Program Files\Apache Group under which a directory + called Apache2 will be created by default.

    12. +
    + +

    During the installation, Apache will configure the files in the + conf subdirectory to reflect the chosen installation + directory. However, if any of the configuration files in this + directory already exist, they will not be overwritten. Instead, the + new copy of the corresponding file will be left with the extension + .default. So, for example, if conf\httpd.conf + already exists, it will be renamed as conf\httpd.conf.default. + After the installation you should manually check to see what new + settings are in the .default file, and if necessary, + update your existing configuration file.

    + +

    Also, if you already have a file called htdocs\index.html, + it will not be overwritten (and no index.html.default + will be installed either). This means it should be safe to install + Apache over an existing installation, although you would have to + stop the existing running server before doing the installation, and + then start the new one after the installation is finished.

    + +

    After installing Apache, you must edit the configuration files + in the conf subdirectory as required. These files + will be configured during the installation so that Apache is ready + to be run from the directory it was installed into, with the + documents server from the subdirectory htdocs. There + are lots of other options which you should set before you really + start using Apache. However, to get started quickly, the files + should work as installed.

    +
    + +
    + Customizing Apache for Windows + +

    Apache is configured by the files in the conf + subdirectory. These are the same files used to configure the Unix + version, but there are a few different directives for Apache on + Windows. See the directive index + for all the available directives.

    + +

    The main differences in Apache for Windows are:

    +
      +
    • Because Apache for Windows is multithreaded, it does not + use a separate process for each request, as Apache does on Unix. + Instead there are usually only two Apache processes running: a + parent process, and a child which handles the requests. Within + the child process each request is handled by a separate thread. +

      + +

      The process management directives are also different:

      + +

      MaxRequestsPerChild: + Like the Unix directive, this controls how many requests a single + child process will serve before exiting. However, unlike on Unix, + a single process serves all the requests at once, not just one. + If this is set, it is recommended that a very high number is + used. The recommended default, MaxRequestsPerChild 0, + causes the child process to never exit.

      + + Warning: The server configuration + file is reread when a new child process is started. If you have + modified httpd.conf, the new child may not start or + you may receive unexpected results. + +

      ThreadsPerChild: + This directive is new. It tells the server how many threads it + should use. This is the maximum number of connections the server + can handle at once, so be sure to set this number high enough for + your site if you get a lot of hits. The recommended default is + ThreadsPerChild 50.

    • + +
    • The directives that accept filenames as arguments must use + Windows filenames instead of Unix ones. However, because Apache + uses Unix-style names internally, you must use forward slashes, + not backslashes. Drive letters can be used; if omitted, the drive + with the Apache executable will be assumed.

    • + +
    • Apache for Windows contains the ability to load modules at + runtime, without recompiling the server. If Apache is compiled + normally, it will install a number of optional modules in the + \Apache2\modules directory. To activate these or + other modules, the new LoadModule + directive must be used. For example, to activate the status + module, use the following (in addition to the status-activating + directives in access.conf):

      + + + LoadModule status_module modules/mod_status.so + + +

      Information on creating + loadable modules is also available.

    • + +
    • Apache can also load ISAPI (Internet Server Application + Programming Interface) extensions (i.e. internet server + applications), such as those used by Microsoft IIS and other + Windows servers. More information + is available. Note that Apache cannot load + ISAPI Filters.

    • + +
    • When running CGI scripts, the method Apache uses to find + the interpreter for the script is configurable using the + ScriptInterpreterSource + directive.

    • + +
    • Since it is often difficult to manage files with names + like .htaccess in Windows, you may find it useful to + change the name of this per-directory configuration file using + the AccessFilename + directive.

    • + +
    • Any errors during Apache startup are logged into the + Windows event log when running on Windows NT. This mechanism + acts as a backup for those situations where Apache cannot even + access the normally used error.log file. You can + view the Windows event log by using the Event Viewer application + on Windows NT 4.0, and the Event Viewer MMC snap-in on newer + versions of Windows.

      + + Note that there is no startup error logging on + Windows 9x because no Windows event log exists on those operating + systems.
    • +
    + +
    + +
    + Running Apache as a Service + +

    Apache can be run as a service on Windows NT. There is some + highly experimental support for similar behavior on Windows 9x.

    + +

    You can install Apache as a service automatically during the + installation. If you chose to install for all users, the + installation will create an Apache service for you. If you specify + to install for yourself only, you can manually register Apache as a + service after the installation. You have to be a member of the + Administrators group for the service installation to succeed.

    + +

    Apache comes with a utility called the Apache Service Monitor. + With it you can see and manage the state of all installed Apache + services on any machine on your network. To be able to manage an + Apache service with the monitor, you have to first install the + service (either automatically via the installation or manually). +

    + +

    You can install Apache as a Windows NT service as follows from + the command prompt at the Apache bin subdirectory:

    + + + apache -k install + + +

    If you need to specify the name of the service you want to + install, use the following command. You have to do this if you + have several different service installations of Apache on your + computer.

    + + + apache -k install -n "MyServiceName" + + +

    If you need to have specifically named configuration files for + different services, you must use this:

    + + + apache -k install -n "MyServiceName" -f "c:\files\my.conf" + + +

    If you use the first command without any special parameters except + -k install, the service will be called Apache2 + and the configuration will be assumed to be conf\httpd.conf. +

    + +

    Removing an Apache service is easy. Just use:

    + + + apache -k uninstall + + +

    The specific Apache service to be uninstalled can be specified by using:

    + + + apache -k uninstall -n "MyServiceName" + + +

    Normal starting, restarting and shutting down of an Apache + service is usually done via the Apache Service Monitor, by using + commands like NET START Apache2 and NET STOP + Apache2 or via normal Windows service management. Before + starting Apache as a service by any means, you should test the + service's configuration file by using:

    + + + apache -n "MyServiceName" -t + + +

    You can control an Apache service by its command line switches, + too. To start an installed Apache service you'll use this:

    + + + apache -k start + + +

    To stop an Apache service via the command line switches, use + this:

    + + + apache -k stop + + +

    or

    + + + apache -k shutdown + + +

    You can also restart a running service and force it to reread + its configuration file by using:

    + + + apache -k restart + + +

    By default, all Apache services are registered to run as the + system user (the LocalSystem account). The + LocalSystem account has no privileges to your network + via any Windows-secured mechanism, including the file system, named + pipes, DCOM, or secure RPC. It has, however, wide privileges locally. +

    + + Never grant any network privileges to + the LocalSystem account! If you need Apache to be able + to access network resources, create a separate account for Apache as + noted below. + +

    You may want to create a separate account for running Apache + service(s). Especially, if you have to access network resources + via Apache, this is strongly recommended.

    + +
      +
    1. Create a normal domain user account, and be sure to + memorize its password.
    2. + +
    3. Grant the newly-created user a privilege of Log on + as a service and Act as part of the operating + system. On Windows NT 4.0 these privileges are granted via + User Manager for Domains, but on Windows 2000 and XP you probably + want to use Group Policy for propagating these settings. You can + also manually set these via the Local Security Policy MMC snap-in. +
    4. + +
    5. Confirm that the created account is a member of the Users + group.
    6. + +
    7. Grant the account read and execute (RX) rights to all document + and script folders (htdocs and cgi-bin + for example).
    8. + +
    9. Grant the account change (RWXD) rights to the + Apache logs directory.
    10. + +
    11. Grant the account read and execute (RX) rights to the + Apache.exe binary executable.
    12. +
    + + It is usually a good practice to grant the user the Apache + service runs as read and execute (RX) access to the whole Apache2 + directory, except the logs subdirectory, where the + user has to have at least change (RWXD) rights. + +

    If you allow the account to log in as a user and as a service, + then you can log on with that account and test that the account has the + privileges to execute the scripts, read the web pages, and that + you can start Apache in a console window. If this works, and you + have followed the steps above, Apache should execute as a service + with no problems.

    + + Error code 2186 is a good indication that + you need to review the "Log On As" configuration for the service, + since Apache cannot access a required network resource. Also, pay + close attention to the privileges of the user Apache is + configured to run as. + +

    When starting Apache as a service you may encounter an error + message from the Windows Service Control Manager. For example, + if you try to start Apache by using the Services applet in the + Windows Control Panel, you may get the following message:

    + + + Could not start the Apache2 service on \\COMPUTER
    + Error 1067; The process terminated unexpectedly. +
    + +

    You will get this generic error if there is any problem with + starting the Apache service. In order to see what is really causing + the problem you should follow the instructions for Running Apache + for Windows from the Command Prompt.

    + +

    There is some support for Apache on Windows 9x to behave in a + similar manner as a service on Windows NT. It is highly + experimental. It is not of production-class reliability, + and its future is not guaranteed. It can be mostly regarded as + a risky thing to play with - proceed with caution!

    + +

    There are some differences between the two kinds of services + you should be aware of:

    + +
      +
    • Apache will attempt to start and if successful it will run + in the background. If you run the command

      + + + apache -n "MyServiceName" -k start + + +

      via a shortcut on your desktop, for example, then if the + service starts successfully, a console window will flash up but + it immediately disappears. If Apache detects any errors on startup + such as incorrect entries in the httpd.conf configuration file, + the console window will remain visible. This will display an error + message which will be useful in tracking down the cause of the + problem.

    • + +
    • Windows 9x does not support NET START or + NET STOP commands. You must control the Apache + service on the command prompt via the -k switches. +

    • + +
    • Apache and Windows 9x offer no support for running Apache + as a specific user with network privileges. In fact, Windows 9x + offers no security on the local machine, either. This is the + simple reason because of which the Apache Software Foundation + never endorses use of a Windows 9x -based system as a public + Apache server. The primitive support for Windows 9x exists only + to assist the user in developing web content and learning the + Apache server, and perhaps as an intranet server on a secured, + private network.

    • + +
    + +

    Once you have confirmed that Apache runs correctly as a + console application you can install, control and uninstall the + pseudo-service with the same commands as on Windows NT. You can + also use the Apache Service Monitor to manage Windows 9x + pseudo-services.

    + +
    + +
    + Running Apache as a Console Application + +

    Running Apache as a service is usually the recommended way to + use it, but it is sometimes easier to work from the command line + (on Windows 9x running Apache from the command line is the + recommended way due to the lack of reliable service support.)

    + +

    To run Apache from the command line as a console application, + use the following command:

    + + + apache + + +

    Apache will execute, and will remain running until it is stopped + by pressing Control-C.

    + +

    You can also run Apache via the shortcut Start Apache in Console + placed to Start Menu --> Programs --> Apache HTTP Server + 2.0.xx --> Control Apache Server during the installation. + This will open a console window and start Apache inside it. If you + don't have Apache installed as a service, the window will remain + visible until you stop Apache by pressing Control-C in the console + window where Apache is running in. The server will exit in a few + seconds. However, if you do have Apache installed as a service, the + shortcut starts the service. If the Apache service is running + already, the shortcut doesn't do anything.

    + +

    You can tell a running Apache to stop by opening another console + window and entering:

    + + + apache -k shutdown + + +

    This should be preferred over pressing Control-C because this + lets Apache end any current operations and clean up gracefully.

    + +

    You can also tell Apache to restart. This forces it to reread + the configuration file. Any operations in progress are allowed to + complete without interruption. To restart Apache, use:

    + + + apache -k restart + + + Note for people familiar with the Unix version of Apache: + these commands provide a Windows equivalent to kill -TERM + pid and kill -USR1 pid. The + command line option used, -k, was chosen as a reminder + of the kill command used on Unix. + +

    If the Apache console window closes immediately or unexpectedly + after startup, open the Command Prompt from the Start Menu --> + Programs. Change to the folder to which you installed Apache, type + the command apache, and read the error message. Then + change to the logs folder, and review the error.log + file for configuration mistakes. If you accepted the defaults when + you installed Apache, the commands would be:

    + + + c:
    + cd "\Program Files\Apache Group\Apache2\bin"
    + apache +
    + +

    Then wait for Apache to stop, or press Control-C. Then enter the + following:

    + + + cd ..\logs
    + more < error.log +
    + +

    When working with Apache it is important to know how it will + find the configuration file. You can specify a configuration file + on the command line in two ways:

    + +
      +
    • -f specifies an absolute or relative path to + a particular configuration file:

      + + + apache -f "c:\my server files\anotherconfig.conf" + + +

      or

      + + + apache -f files\anotherconfig.conf +
    • + +
    • -n specifies the installed Apache service + whose configuration file is to be used:

      + + + apache -n "MyServiceName" + +
    • +
    + +

    In both of these cases, the proper + ServerRoot should be set in + the configuration file.

    + +

    If you don't specify a configuration file with -f + or -n, Apache will use the file name compiled into the + server, such as conf\httpd.conf. This built-in path + is relative to the installation directory. You can verify the compiled + file name from a value labelled as SERVER_CONFIG_FILE when + invoking Apache with the -V switch, like this:

    + + + apache -V + + +

    Apache will then try to determine its + ServerRoot by trying the following, in this order:

    + +
      +
    1. A ServerRoot directive + via the -C command line switch.
    2. + +
    3. The -d switch on the command line.
    4. + +
    5. Current working directory.
    6. + +
    7. A registry entry which was created if you did a binary + installation.
    8. + +
    9. The server root compiled into the server. This is + /apache by default, you can verify it by using + apache -V and looking for a value labelled as + HTTPD_ROOT.
    10. +
    + +

    During the installation, a version-specific registry key is + created in the Windows registry. The location of this key depends + on the type of the installation. If you chose to install Apache + for all users, the key is located under the + HKEY_LOCAL_MACHINE hive, like this (the version + numbers will of course vary between different versions of Apache: +

    + + + HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\2.0.43 + + +

    Correspondingly, if you chose to install Apache for the current + user only, the key is located under the HKEY_CURRENT_USER + hive, the contents of which are dependent of the user currently + logged on:

    + + + HKEY_CURRENT_USER\SOFTWARE\Apache Group\Apache\2.0.43 + + +

    This key is compiled into the server and can enable you to test + new versions without affecting the current version. Of course, you + must take care not to install the new version in the same + directory as another version.

    + +

    If you did not do a binary install, Apache will in some + scenarios complain about the missing registry key. This warning can + be ignored if the server was otherwise able to find its + configuration file.

    + +

    The value of this key is the + ServerRoot directory which + contains the conf subdirectory. When Apache starts it + reads the httpd.conf file from that directory. If + this file contains a ServerRoot + directive which contains a different directory from the one + obtained from the registry key above, Apache will forget the + registry key and use the directory from the configuration file. If + you copy the Apache directory or configuration files to a new + location it is vital that you update the + ServerRoot directive in the + httpd.conf file to reflect the new location.

    + +
    + +
    + Testing the Installation + +

    After starting Apache (either in a console window or as a + service) it will be listening on port 80 (unless you changed the + Listen directive in the + configuration files or installed Apache only for the current user). + To connect to the server and access the default page, launch a + browser and enter this URL:

    + + + http://localhost/ + + +

    Apache should respond with a welcome page and a link to the + Apache manual. If nothing happens or you get an error, look in the + error.log file in the logs subdirectory. + If your host is not connected to the net, or if you have serious + problems with your DNS (Domain Name Service) configuration, you + may have to use this URL:

    + + + http://127.0.0.1/ + + +

    If you happen to be running Apache on an alternate port, you + need to explicitly put that in the URL:

    + + + http://127.0.0.1:8080/ + + +

    Once your basic installation is working, you should configure it + properly by editing the files in the conf subdirectory. + Again, if you change the configuration of the Windows NT service + for Apache, first attempt to start it from the command line to + make sure that the service starts with no errors.

    + +

    Because Apache cannot share the same port with + another TCP/IP application, you may need to stop, uninstall or reconfigure + certain other services before running Apache. These conflicting + services include other WWW servers and some firewall implementations. +

    + +
    + +
    diff --git a/trunk/docs/manual/platform/windows.xml.ko b/trunk/docs/manual/platform/windows.xml.ko new file mode 100644 index 0000000000..b1855fda58 --- /dev/null +++ b/trunk/docs/manual/platform/windows.xml.ko @@ -0,0 +1,689 @@ + + + + + + + + + Platform Specific Notes + + Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ »ç¿ë¹ý + + + +

    ÀÌ ¹®¼­´Â Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ 2.0À» ¼³Ä¡, ¼³Á¤, + ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. À߸øµÈ ºÎºÐÀÌ Àְųª ´Ù¸¥ ¹æ¹ýÀ¸·Î + µµ¿òÀ» ÁÖ·Á¸é, ¹ö±× º¸°í + ÆäÀÌÁö¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ ¹ÙÀ̳ʸ® ¹èÆ÷º»À» ¼³Ä¡ÇÑ´Ù°í °¡Á¤ÇÑ´Ù. + (¾Æ¸¶µµ °³¹ß ȤÀº ¹ö±×¸¦ ã±âÀ§ÇØ) Á÷Á¢ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÏ·Á¸é + Microsoft Windows¿ë ¾ÆÆÄÄ¡ + ÄÄÆÄÀÏÀ» Âü°íÇ϶ó.

    + +

    ÇöÀç Microsoft Windows ¿î¿µÃ¼Á¦±ºÀÇ ¹öÀü Á¤Ã¥»ó + ÀÌ ¹®¼­´Â ´ÙÀ½°ú °°ÀÌ ±¸ºÐÇÑ´Ù:

    +
      +
    • Windows NT: Windows NT Ä¿³ÎÀ» ±â¹ÝÀ¸·Î + ÇÏ´Â ¸ðµç Windows ¹öÀüÀ» ÀǹÌÇÑ´Ù. Windows NT, Windows + 2000, Windows XP, Windows .Net Server 2003À» ÁöĪÇÑ´Ù.
    • +
    • Windows 9x: ¼ÒºñÀÚ Áß½ÉÀÇ ¿À·¡µÈ + Windows ¹öÀüÀ» ¶æÇÑ´Ù. Windows 95 (OSR2 Æ÷ÇÔ), Windows + 98, Windows ME¸¦ ÁöĪÇÑ´Ù.
    • +
    + +
    + +
    + ¿î¿µÃ¼Á¦ ¿ä±¸Á¶°Ç + +

    ¾ÆÆÄÄ¡ 2.0À» ½ÇÇàÇϱâÀ§ÇÑ ±âº» Windows Ç÷¡ÆûÀº Windows + NTÀÌ´Ù. ¹ÙÀ̳ʸ® ¼³Ä¡ÇÁ·Î±×·¥Àº Intel°ú AMD¿Í °°Àº x86 °³¿­ + ÇÁ·Î¼¼¼­¿¡¼­¸¸ µ¿ÀÛÇÑ´Ù. ¾ÆÆÄÄ¡´Â Windows 9x¿¡¼­ ÃæºÐÈ÷ + °Ë»çÇÏÁö ¾Ê¾Ò±â¶§¹®¿¡ Àý´ë·Î ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÏÁö ¾Ê±æ + ¹Ù¶õ´Ù. +

    + +

    ¿î¿µÃ¼Á¦¿¡ ¼³Ä¡ÇÑ TCP/IP ³×Æ®¿öÅ©°¡ µ¿ÀÛÇØ¾ß ÇÑ´Ù. Windows + 95¿¡¼­ ½ÇÇàÇÑ´Ù¸é, Winsock 2 ¾÷±×·¹À̵带 ¼³Ä¡ÇØ¾ß ÇÑ´Ù. + Windows 95¿ë Winsock 2´Â ¿©±â¿¡¼­ + ´Ù¿î¹ÞÀ» ¼ö ÀÖ´Ù. +

    + +

    Windows NT 4.0À» »ç¿ëÇÑ´Ù¸é ¼­ºñ½ºÆÑ 4ÀÇ TCP/IP ¹®Á¦¿Í + Winsock ¹®Á¦°¡ ´ÙÀ½ ¼­ºñ½ºÆÑ¿¡¼­ ÇØ°áµÇ¾ú±â¶§¹®¿¡, ¼­ºñ½ºÆÑ + 6À» ¼³Ä¡Çϱæ Àû±Ø ±ÇÇÑ´Ù.

    +
    + +
    + Windows¿ë ¾ÆÆÄÄ¡ ´Ù¿î·Îµå + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö http://httpd.apache.org/download.cgi¿¡¼­ + ¾ÆÆÄÄ¡ ÃֽŠ¹öÀü¿¡ ´ëÇÑ Á¤º¸¸¦ ¾òÀ» ¼ö ÀÖ´Ù. ¿©±â¿¡´Â ÃֽŠ+ ¹ßÇ¥ÆÇ°ú ¾ËÆÄ È¤Àº º£Å¸ Å×½ºÆ®¹öÀü°ú, ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ´Ù¿î·ÎµåÇÒ + ¼ö ÀÖ´Â HTTP ¹Ì·¯¿Í FTP ¹Ì·¯ ¸ñ·ÏÀÌ ÀÖ´Ù. ºü¸£°í ¾ÈÁ¤ÇÏ°Ô + ´Ù¿î¹ÞÀ¸·Á¸é °¡±î¿î ¹Ì·¯¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù.

    + +

    Windows¿¡ ¼³Ä¡ÇÏ·Á¸é È®ÀåÀÚ°¡ .msiÀÎ Windows¿ë + ¾ÆÆÄÄ¡ ¹öÀüÀ» ´Ù¿î¹Þ¾Æ¾ß ÇÑ´Ù. ÀÌ ÆÄÀÏÀº ¸·¹Ù·Î ½ÇÇàÇÒ ¼ö + ÀÖ´Â ¾ÆÆÄÄ¡¸¦ ÀúÀåÇÑ Microsoft ¼³Ä¡ÆÄÀÏÀÌ´Ù. µû·Î ¼Ò½ºÄڵ常 + ¹­¾îµÐ .zip ÆÄÀÏÀÌ ÀÖ´Ù. Microsoft Visual C++ + (Visual Studio)À» »ç¿ëÇÏ¿© Á÷Á¢ ¾ÆÆÄÄ¡¸¦ ÄÄÆÄÀÏÇÒ ¼öµµ ÀÖ´Ù.

    +
    + +
    + Windows¿ë ¾ÆÆÄÄ¡ ¼³Ä¡Çϱâ + +

    ¼³Ä¡ÇÏ·Á¸é Microsoft Installer 1.2 ÀÌ»ó ¹öÀüÀÌ ÇÊ¿äÇÏ´Ù. + Windows 9x¸¦ »ç¿ëÇÑ´Ù¸é ¿©±â¿¡¼­ + Microsoft Installer¸¦ 2.0 ¹öÀüÀ¸·Î ¾÷±×·¹À̵åÇÒ ¼ö ÀÖ°í, + Windows NT 4.0°ú 2000À» »ç¿ëÇÑ´Ù¸é ¿©±â¿¡¼­ + 2.0 ¹öÀü ¾÷µ¥ÀÌÆ®¸¦ ±¸ÇÒ ¼ö ÀÖ´Ù. Windows XP´Â ¾÷µ¥ÀÌÆ®ÇÒ + ÇÊ¿ä°¡ ¾ø´Ù.

    + +

    ¹ÙÀ̳ʸ® ¼³Ä¡ÆÄÀϷδ °°Àº ÄÄÇ»ÅÍ¿¡ ¼­·Î ´Ù¸¥ ¾ÆÆÄÄ¡ + 2.0 ¹öÀüÀ» ¼³Ä¡ÇÒ ¼ö ¾øÀ½À» ÁÖÀÇÇ϶ó. ±×·¯³ª 1.3 + ¹öÀü°ú 2.0 ¹öÀüÀº °°Àº ÄÄÇ»ÅÍ¿¡ ¾Æ¹« ¹®Á¦¾øÀÌ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. °°Àº ÄÄÇ»ÅÍ¿¡ µÎ°¡Áö ´Ù¸¥ 2.0 ¹öÀüÀ» ¼³Ä¡ÇÏ·Á¸é + ¼Ò½º¸¦ ÄÄÆÄÀÏÇÏ¿© ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇØ¾ß ÇÑ´Ù.

    + +

    À§¿¡¼­ ´Ù¿î¹ÞÀº ¾ÆÆÄÄ¡ .msi ÆÄÀÏÀ» ½ÇÇàÇÑ´Ù. + ¼³Ä¡ÇÒ¶§ ´ÙÀ½°ú °°Àº °ÍÀ» ¹°¾îº»´Ù:

    + +
      +
    1. ³×Æ®¿öÅ© µµ¸ÞÀÎ (Network Domain). + µî·ÏµÈ ¼­¹öÀÇ DNS µµ¸ÞÀÎÀ» ÀÔ·ÂÇÑ´Ù. ¿¹¸¦ µé¾î, ¼­¹öÀÇ + Àüü DNS À̸§ÀÌ server.mydomain.netÀ̶ó¸é + ¿©±â¿¡ mydomain.netÀ» ÀÔ·ÂÇÑ´Ù.

    2. + +
    3. ¼­¹ö¸í (Server Name). ¼­¹öÀÇ Àüü + DNS À̸§. À§ÀÇ °æ¿ì ¿©±â¿¡ server.mydomain.netÀ» + ÀÔ·ÂÇÑ´Ù.

    4. + +
    5. °ü¸®ÀÚ ÀüÀÚ¿ìÆí ÁÖ¼Ò (Administrator's Email + Address). ¿©±â¿¡ ¼­¹ö °ü¸®ÀÚ³ª À¥¸¶½ºÅÍÀÇ ÀüÀÚ¿ìÆí + ÁÖ¼Ò¸¦ ÀÔ·ÂÇÑ´Ù. ±âº»ÀûÀ¸·Î Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»´Â ¿À·ù¹®¿¡ + ÀÌ ÁÖ¼Ò¸¦ ±â·ÏÇÑ´Ù.

    6. + +
    7. »ç¿ëÀÚ ´ë»ó (For whom to install + Apache) »õ·Î ¼³Ä¡ÇÏ´Â ¾ÆÆÄÄ¡°¡ 80¹ø Æ÷Æ®¿¡¼­ + ¿äûÀ» ±â´Ù¸®°Ô ÇÏ·Á¸é for All Users, on Port 80, + as a Service - Recommended (¸ðµç »ç¿ëÀÚ, 80¹ø Æ÷Æ®, + service·Î - Ãßõ)¸¦ ¼±ÅÃÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÑ´Ù + (Áï, ¾ÆÆÄÄ¡´Â ¼­¹ö¿¡ ·Î±×ÀÎÇÑ »ç¶÷ÀÌ ¾ø¾îµµ ½ÇÇàµÈ´Ù). + °³ÀÎÀûÀ¸·Î Å×½ºÆ®Çغ¸°Å³ª ÀÌ¹Ì 80¹ø Æ÷Æ®¸¦ »ç¿ëÇÏ´Â ´Ù¸¥ + À¥¼­¹ö°¡ ÀÖ´Ù¸é only for the Current User, on Port + 8080, when started Manually (ÇöÀç »ç¿ëÀÚ¸¸, 8080¹ø + Æ÷Æ®, Á÷Á¢ ½ÃÀÛ)¸¦ ¼±ÅÃÇÑ´Ù.

    8. + +
    9. ¼³Ä¡ Á¾·ù (The installation type). + ¸ðµâ °³¹ß¿¡ ÇÊ¿äÇÑ ¼Ò½ºÄÚµå¿Í ¶óÀ̺귯¸®¸¦ Á¦¿ÜÇÑ ¸ðµç + °ÍÀ» ¼³Ä¡ÇÏ·Á¸é TypicalÀ» ¼±ÅÃÇÑ´Ù. + CustomÀ» ¼±ÅÃÇÏ¸é ¼³Ä¡ÇÒ ³»¿ëÀ» ÁöÁ¤ÇÒ ¼ö + ÀÖ´Ù. Àüü ¼³Ä¡½Ã µð½ºÅ©¿¡ ºó °ø°£ÀÌ ¾à 13 ¸Þ°¡¹ÙÀÌÆ® + Á¤µµ ÇÊ¿äÇÏ´Ù. ÀÌ ¼öÄ¡´Â À¥»çÀÌÆ® Å©±â¸¦ Á¦¿ÜÇÑ + °ÍÀÌ´Ù.

    10. + +
    11. ¼³Ä¡ Àå¼Ò (Where to install). + ±âº» °æ·Î´Â C:\Program Files\Apache GroupÀÌ°í, + ÀÌ°÷¿¡ Apache2¶ó´Â µð·ºÅ丮¸¦ ¸¸µç´Ù.

    12. +
    + +

    ¼³Ä¡ÇÒ µ¿¾È ¾ÆÆÄÄ¡´Â conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀϵéÀ» ¼±ÅÃÇÑ ¼³Ä¡ µð·ºÅ丮¿¡ ¸Â°Ô ±¸¼ºÇÑ´Ù. ±×·¯³ª + ÀÌ µð·ºÅ丮¿¡ ¼³Á¤ÆÄÀÏÀÌ ÀÌ¹Ì ÀÖ´Ù¸é ±×´ë·Î µÐ´Ù. ´ë½Å, + ÇØ´ç ÆÄÀÏÀÇ »õ·Î¿î º¹»çº»¿¡ È®ÀåÀÚ .default¸¦ + ºÙÀδÙ. ¿¹¸¦ µé¾î, conf\httpd.conf°¡ ÀÌ¹Ì ÀÖ´Ù¸é + conf\httpd.conf.default·Î À̸§À» º¯°æÇÑ´Ù. + ¼³Ä¡ÈÄ .default ÆÄÀÏÀÇ ¼³Á¤À» Á÷Á¢ »ìÆ캸°í, + ÇÊ¿äÇÏ´Ù¸é ±âÁ¸ ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¶Ç, ÀÌ¹Ì htdocs\index.htmlÀ̶ó´Â ÆÄÀÏÀÌ + ÀÖ´Ù¸é ±×´ë·Î µÐ´Ù (index.html.default¶ó°í + º¹»çÇÏÁöµµ ¾Ê´Â´Ù). Áï, ±âÁ¸¿¡ ¾ÆÆÄÄ¡°¡ ¼³Ä¡µÇÀÖ´õ¶óµµ ¾ÈÀüÇÏ°Ô + ¾ÆÆÄÄ¡¸¦ »õ·Î ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ¹°·Ð ¼³Ä¡Çϱâ Àü¿¡ ¼­¹ö¸¦ + Áß´ÜÇÏ°í, ¼³Ä¡ÈÄ »õ·Î¿î ¼­¹ö¸¦ ½ÃÀÛÇØ¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡ ¼³Ä¡ÈÄ ÇÊ¿äÇÏ´Ù¸é conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ¼³Á¤ÆÄÀÏÀ» ¼öÁ¤ÇØ¾ß ÇÑ´Ù. ÆÄÀÏÀº ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ µð·ºÅ丮ÀÇ + htdocs ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ¹®¼­¸¦ ¼­ºñ½ºÇϵµ·Ï + ¼³Á¤µÇÀÖ´Ù. ½ÇÁ¦·Î ¾ÆÆÄÄ¡¸¦ »ç¿ëÇϱâ Àü¿¡ ¼³Á¤ÇØ¾ß ÇÒ ¿É¼ÇÀÌ + ¸¹´Ù. ±×·¯³ª »¡¸® ½ÇÇàÇغ¼ ¼ö ÀÖµµ·Ï ±âº» ¼³Á¤ÆÄÀϷεµ µ¿ÀÛÇÑ´Ù.

    +
    + +
    + Windows¿ë ¾ÆÆÄÄ¡ ¼³Á¤Çϱâ + +

    ¾ÆÆÄÄ¡´Â conf ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â ÆÄÀÏ·Î + ¼³Á¤ÇÑ´Ù. ÀÌ ÆÄÀÏÀº À¯´Ð½º¿ë°ú °°Áö¸¸, Windows¿ë ¾ÆÆÄÄ¡ + ƯÀ¯ÀÇ Áö½Ã¾î°¡ ¸î°³ ÀÖ´Ù. »ç¿ë°¡´ÉÇÑ ¸ðµç Áö½Ã¾î¸¦ º¸·Á¸é + Áö½Ã¾î ¸ñ·ÏÀ» Âü°íÇ϶ó.

    + +

    Windows¿ë ¾ÆÆÄÄ¡ÀÇ ÁÖµÈ Â÷ÀÌÁ¡Àº:

    +
      +
    • Windows¿ë ¾ÆÆÄÄ¡´Â ´ÙÁß¾²·¹µå ¹æ½ÄÀ» »ç¿ëÇϱ⶧¹®¿¡, + À¯´Ð½º¿Í ´Þ¸® ¿äû¸¶´Ù ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + ´ë½Å ¾ÆÆÄÄ¡ ÇÁ·Î¼¼½º´Â Ç×»ó, ºÎ¸ð ÇÁ·Î¼¼½º¿Í ¿äûÀ» ó¸®ÇÏ´Â + ÀÚ½Ä ÇÁ·Î¼¼½º, 2°³ÀÌ´Ù. ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ ÀÖ´Â ¿©·¯ ¾²·¹µåµéÀÌ + ¿äûµéÀ» ó¸®ÇÑ´Ù. +

      + +

      ÇÁ·Î¼¼½º °ü¸® Áö½Ã¾îµµ ´Ù¸£´Ù:

      + +

      MaxRequestsPerChild: À¯´Ð½º¿Í + °°ÀÌ, ÀÚ½Ä ÇÁ·Î¼¼½º°¡ ¿äûÀ» ¾ó¸¶¸¸Å­ ó¸®ÇÏ°í Á×À»Áö¸¦ + Á¶Á¤ÇÑ´Ù. ±×·¯³ª À¯´Ð½º¿Í ´Þ¸® ÇÁ·Î¼¼½º°¡ Çѹø¿¡ ÇÑ ¿äû¸¸À» + ó¸®ÇÏÁö¾Ê°í Çѹø¿¡ ¸ðµç ¿äûÀ» ¼­ºñ½ºÇϱ⶧¹®¿¡, ¼³Á¤ÇÑ´Ù¸é + ¸Å¿ì Å« °ªÀ» ¼³Á¤ÇÏ±æ ±ÇÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ª + MaxRequestsPerChild 0À» »ç¿ëÇϸé ÀÚ½Ä ÇÁ·Î¼¼½º´Â + Á×Áö¾Ê°í ¿µ¿øÈ÷ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

      + + °æ°í: ÀÚ½Ä ÇÁ·Î¼¼½º´Â »õ·Î + ½ÃÀÛÇÒ ¶§¸¶´Ù ¼­¹ö¼³Á¤ÆÄÀÏÀ» »õ·Î Àд´Ù. + httpd.conf¸¦ ¼öÁ¤Çß´Ù¸é, ÀÚ½Ä ÇÁ·Î¼¼½º°¡ + ½ÃÀÛÇÏÁö ¾Ê°Å³ª ¿¹±âÄ¡¾ÊÀº °á°ú°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. + +

      ThreadsPerChild: + ÀÌ Áö½Ã¾î´Â »õ·Î Ãß°¡µÇ¾ú´Ù. ÀÌ Áö½Ã¾î´Â ¼­¹ö°¡ »ç¿ëÇÒ + ¾²·¹µå °³¼ö¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ °ªÀÌ ¼­¹ö°¡ Çѹø¿¡ ó¸®ÇÒ ¼ö + ÀÖ´Â ÃÖ´ë ¿¬°á°³¼öÀ̱⶧¹®¿¡, »çÀÌÆ®¿¡ Á¢¼Ó·®ÀÌ ¸¹´Ù¸é + ÃæºÐÈ÷ Å« °ªÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù. ±ÇÀåÇÏ´Â ±âº»°ªÀº + ThreadsPerChild 50ÀÌ´Ù.

    • + +
    • ÆÄÀϸíÀ» ¾Æ±Ô¸ÕÆ®·Î ¹Þ´Â Áö½Ã¾î´Â À¯´Ð½º ÆÄÀϸíÀÌ + ¾Æ´Ñ Windows ÆÄÀϸíÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ±×·¯³ª ¾ÆÆÄÄ¡ ³»ºÎ¿¡¼­ + À¯´Ð½º½Ä À̸§À» »ç¿ëÇϱ⶧¹®¿¡ ¹é½½·¡½¬°¡ ¾Æ´Ñ ½½·¡½¬¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. µå¶óÀÌºê ¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. µå¶óÀ̺긦 + ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é ¾ÆÆÄÄ¡ ½ÇÇàÆÄÀÏÀÌ ÀÖ´Â µå¶óÀ̺긦 + »ç¿ëÇÑ´Ù.

    • + +
    • Windows¿ë ¾ÆÆÄÄ¡´Â ¼­¹ö¸¦ ´Ù½Ã ÄÄÆÄÀÏÇÏÁö ¾Ê°í + ½ÇÇàÁß¿¡ ¸ðµâÀ» ÀоîµéÀÏ ¼ö ÀÖ´Ù. ±âº»°ªÀ¸·Î ¾ÆÆÄÄ¡¸¦ + ÄÄÆÄÀÏÇϸé \Apache2\modules µð·ºÅ丮¿¡ ¿©·¯ + ¼±Åð¡´ÉÇÑ ¸ðµâÀ» ¼³Ä¡ÇÑ´Ù. ÀÌ ¸ðµâ ȤÀº ´Ù¸¥ ¸ðµâÀ» + »ç¿ëÇÏ·Á¸é »õ·Î »ý±ä LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. + ¿¹¸¦ µé¾î, status ¸ðµâÀ» »ç¿ëÇÑ´Ù¸é + (access.conf¿¡ status°ü·Ã Áö½Ã¾î¿Í ÇÔ²²) + ¾Æ·¡¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù:

      + + + LoadModule status_module modules/mod_status.so + + +

      ÀоîµéÀÏ ¼ö ÀÖ´Â + ¸ðµâ ¸¸µé±â¿¡ ´ëÇÑ Á¤º¸µµ ÀÖ´Ù.

    • + +
    • ¾ÆÆÄÄ¡´Â Microsoft IIS¿Í ´Ù¸¥ Windows ¼­¹ö°¡ »ç¿ëÇÏ´Â + ISAPI (Internet Server Application Programming Interface) + È®ÀåÀ» (Áï, ÀÎÅÍ³Ý ¼­¹ö ÇÁ·Î±×·¥) ÀоîµéÀÏ ¼öµµ ÀÖ´Ù. + ´õ ÀÚ¼¼ÇÑ Á¤º¸°¡ ÀÖ´Ù. + ¾ÆÆÄÄ¡´Â ISAPI ÇÊÅ͸¦ ÀоîµéÀÏ ¼ö ¾øÀ½À» + ÁÖÀÇÇ϶ó.

    • + +
    • CGI ½ºÅ©¸³Æ®¸¦ »ç¿ëÇÑ´Ù¸é ScriptInterpreterSource Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡°¡ ½ºÅ©¸³Æ®ÀÇ ÀÎÅÍÇÁ¸®Å͸¦ ã´Â ¹æ¹ýÀ» + ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    • + +
    • Windows¿¡¼­ .htaccess¿Í °°Àº ÆÄÀϸíÀ» + ´Ù·ç±â Èûµå¹Ç·Î, AccessFilename Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + µð·ºÅ丮º° ¼³Á¤ÆÄÀÏ À̸§À» º¯°æÇϸé ÆíÇÏ´Ù.

    • + +
    • Windows NT¶ó¸é ¾ÆÆÄÄ¡ ½ÃÀ۽à ¹ß»ýÇÑ ¿À·ù¸¦ Windows + À̺¥Æ® ·Î±×¿¡ ±â·ÏÇÑ´Ù. ±×·¡¼­ ¾ÆÆÄÄ¡°¡ º¸Åë »ç¿ëÇÏ´Â + error.log ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Â °æ¿ì¿¡ ´ëºñÇÑ´Ù. + Windows À̺¥Æ® ·Î±×´Â Windows NT 4.0¿¡¼­´Â À̺¥Æ® ºä¾î + ÇÁ·Î±×·¥À¸·Î, ÃֽŠWindows ¹öÀü¿¡¼­´Â À̺¥Æ® ºä¾î MMC + ½º³ÀÀο¡¼­ º¼ ¼ö ÀÖ´Ù.

      + + Windows 9x¿¡´Â Windows À̺¥Æ® ·Î±×°¡ ¾ø±â¶§¹®¿¡ + ½ÃÀ۽à ¹ß»ýÇÑ ¿À·ù¸¦ ±â·ÏÇÏÁö ¾Ê´Â´Ù.
    • +
    + +
    + +
    + ¾ÆÆÄÄ¡¸¦ Service·Î ½ÇÇàÇϱâ + +

    Windows NT¿¡¼­´Â ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. Windows + 9x¿¡´Â ¸Å¿ì ½ÇÇèÀûÀÎ ¹æ¹ýÀ¸·Î ºñ½ÁÇÑ ±â´ÉÀ» Áö¿øÇÑ´Ù.

    + +

    ¼³Ä¡½Ã ÀÚµ¿À¸·Î ¾ÆÆÄÄ¡¸¦ service·Î ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. "¸ðµç + »ç¿ëÀÚ"¸¦ ¼±ÅÃÇϸé, ¾ÆÆÄÄ¡ service°¡ ¸¸µé¾îÁø´Ù. "ÇöÀç + »ç¿ëÀÚ¸¸"À» ¼±ÅÃÇÏ´õ¶óµµ ¼³Ä¡ÈÄ Á÷Á¢ ¾ÆÆÄÄ¡¸¦ service·Î + µî·ÏÇÒ ¼ö ÀÖ´Ù. service¸¦ ¼³Ä¡ÇÏ·Á¸é Administrators ±×·ìÀÇ + ±¸¼º¿øÀ̾î¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡¿¡´Â Apache Service Monitor¶ó´Â µµ±¸°¡ ÀÖ´Ù. ÀÌ + µµ±¸¸¦ »ç¿ëÇÏ¸é ³×Æ®¿÷¿¡ ÀÖ´Â ´Ù¸¥ ÄÄÇ»ÅÍ¿¡ ¼³Ä¡µÈ ¾ÆÆÄÄ¡ + »óŵµ È®ÀÎÇÏ°í °ü¸®ÇÒ ¼ö ÀÖ´Ù. monitor·Î ¾ÆÆÄÄ¡ service¸¦ + °ü¸®ÇÏ·Á¸é ¸ÕÀú service¸¦ (¼³Ä¡½Ã ÀÚµ¿À¸·Î ȤÀº Á÷Á¢) ¼³Ä¡ÇØ¾ß + ÇÑ´Ù. +

    + +

    ¾ÆÆÄÄ¡ bin ÇÏÀ§µð·ºÅ丮¿¡¼­ ¸í·ÉÇà ÇÁ·ÒÇÁÆ®¿¡ + ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÏ¸é ¾ÆÆÄÄ¡¸¦ Windows NT service·Î ¼³Ä¡ÇÑ´Ù:

    + + + apache -k install + + +

    ¼³Ä¡ÇÒ service À̸§À» ÁöÁ¤ÇÏ°í ½Í´Ù¸é ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. + ÄÄÇ»ÅÍ¿¡ ¾ÆÆÄÄ¡°¡ ¿©·¯°³ ¼³Ä¡µÇÀÖ´Ù¸é À̸§À» ´Ù¸£°Ô ÁÖ¾î¾ß + ÇÑ´Ù.

    + + + apache -k install -n "MyServiceName" + + +

    service°¡ »ç¿ëÇÒ ¼³Á¤ÆÄÀÏÀ» Á÷Á¢ ÁöÁ¤ÇÏ·Á¸é ´ÙÀ½°ú °°ÀÌ + ÇÑ´Ù:

    + + + apache -k install -n "MyServiceName" -f "c:\files\my.conf" + + +

    -k install ¿Ü¿¡ ´Ù¸¥ ÆĶó¹ÌÅ͸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é, service À̸§Àº Apache2°¡ µÇ°í ¼³Á¤ÆÄÀÏÀº + conf\httpd.conf°¡ µÈ´Ù. +

    + +

    ¾ÆÆÄÄ¡ service¸¦ Á¦°ÅÇϱ⠽±´Ù. °£´ÜÈ÷:

    + + + apache -k uninstall + + +

    ´ÙÀ½°ú °°ÀÌ Á¦°ÅÇÒ ¾ÆÆÄÄ¡ service¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù:

    + + + apache -k uninstall -n "MyServiceName" + + +

    º¸Åë ¾ÆÆÄÄ¡ service ½ÃÀÛ, Àç½ÃÀÛ, Á¾·á´Â Apache Service + Monitor³ª NET START Apache2, NET STOP + Apache2 °°Àº ¸í·É¾î ȤÀº Windows ¼­ºñ½º °ü¸®Ã¢¿¡¼­ + ÇÑ´Ù. ¾î¶² ¹æ¹ýÀ» »ç¿ëÇϵçÁö ¾ÆÆÄÄ¡ service¸¦ ½ÃÀÛÇϱâ Àü¿¡ + ¼³Á¤ÆÄÀÏÀ» °Ë»çÇغÁ¾ß ÇÑ´Ù:

    + + + apache -n "MyServiceName" -t + + +

    ¸í·ÉÇà ¿É¼ÇÀ¸·Îµµ ¾ÆÆÄÄ¡ service¸¦ Á¶Á¤ÇÒ ¼ö ÀÖ´Ù. ¼³Ä¡ÇÑ + ¾ÆÆÄÄ¡ serivce¸¦ ½ÃÀÛÇÏ·Á¸é:

    + + + apache -k start + + +

    ¸í·ÉÇà ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡ service¸¦ Á¾·áÇÏ·Á¸é:

    + + + apache -k stop + + +

    ȤÀº

    + + + apache -k shutdown + + +

    ½ÇÇàÁßÀÎ service¸¦ Àç½ÃÀÛÇÏ¿© ¼³Á¤ÆÄÀÏÀ» ´Ù½Ã Àеµ·Ï + ÇÒ ¼ö ÀÖ´Ù:

    + + + apache -k restart + + +

    ±âº»ÀûÀ¸·Î ¸ðµç ¾ÆÆÄÄ¡ service´Â ½Ã½ºÅÛ »ç¿ëÀÚ + (LocalSystem °èÁ¤) ±ÇÇÑÀ¸·Î ½ÇÇàÇϵµ·Ï µî·ÏµÈ´Ù. + Windows º¸¾È±¸Á¶»ó LocalSystem °èÁ¤Àº ÆÄÀϽýºÅÛ, + named pipes, DCOM, secure RPC µî ¾î¶² ¹æ¹ýÀ» »ç¿ëÇϵçÁö + ³×Æ®¿÷¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù. ±×·¯³ª ÇØ´ç ÄÄÇ»ÅÍ¿¡¼­´Â ¸¹Àº ±ÇÇÑÀ» + °¡Áø´Ù. +

    + + LocalSystem °èÁ¤¿¡°Ô + ³×Æ®¿÷ ±ÇÇÑÀ» Àý´ë·Î ÁÖÁö ¸¶¶ó! ¾ÆÆÄÄ¡°¡ ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇØ¾ß + ÇÑ´Ù¸é, ¾Æ·¡¿¡¼­ ¼³¸íÇÏ´Â ¹æ¹ýÀ¸·Î ¾ÆÆÄÄ¡¸¦ À§ÇÑ º°µµÀÇ + °èÁ¤À» ¸¸µé¾î¶ó. + +

    ¾ÆÆÄÄ¡ service¸¦ ½ÇÇàÇϱâÀ§ÇÑ º°µµÀÇ °èÁ¤À» ¸¸µé ¼öµµ + ÀÖ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡°¡ ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇØ¾ß ÇÑ´Ù¸é ÀÌ ¹æ¹ýÀ» + °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + +
      +
    1. ÀÏ¹Ý µµ¸ÞÀÎ »ç¿ëÀÚ °èÁ¤À» ¸¸µé°í ¾ÏÈ£¸¦ ±â¾ïÇ϶ó.
    2. + +
    3. »õ·Î ¸¸µç °èÁ¤¿¡ ¼­ºñ½º·Î ·Î±×¿Â¿Í + ¿î¿µ üÁ¦ÀÇ ÀϺηΠȰµ¿ ±ÇÇÑÀ» + ºÎ¿©ÇÑ´Ù. Windows NT 4.0¿¡¼­´Â User Manager for Domains¿¡¼­ + ±ÇÇÑÀ» ºÎ¿©ÇÒ ¼ö ÀÖ°í, Windows 2000°ú XP¿¡¼­´Â ¾Æ¸¶µµ + "±×·ì Á¤Ã¥"À» »ç¿ëÇØ¾ß ÇÑ´Ù. "·ÎÄà º¸¾È ¼³Á¤" MMC + ½º³ÀÀο¡¼­ Á÷Á¢ ¼³Á¤ÇØÁÙ ¼öµµ ÀÖ´Ù. +
    4. + +
    5. »õ·Î ¸¸µç °èÁ¤ÀÌ Users ±×·ì¿¡ ¼ÓÇÏ´ÂÁö È®ÀÎÇÑ´Ù.
    6. + +
    7. ¸ðµç ¹®¼­¿Í ½ºÅ©¸³Æ® Æú´õ¿¡ (¿¹¸¦ µé¾î + htdocs¿Í cgi-bin) ´ëÇØ ÀÐ±â ¹× + ½ÇÇà (RX) ±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù.
    8. + +
    9. ¾ÆÆÄÄ¡ logs µð·ºÅ丮¿¡ ¼öÁ¤ (RWXD) ±ÇÇÑÀ» + ºÎ¿©ÇÑ´Ù.
    10. + +
    11. Apache.exe ½ÇÇàÆÄÀÏ¿¡ ÀÐ±â ¹× ½ÇÇà (RX) + ±ÇÇÑÀ» ºÎ¿©ÇÑ´Ù.
    12. +
    + + ¾ÆÆÄÄ¡ service¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿¡°Ô ÃÖ¼ÒÇÑ ¼öÁ¤ (RWXD) + ±ÇÇÑÀÌ ÇÊ¿äÇÑ logs ÇÏÀ§µð·ºÅ丮¸¦ Á¦¿ÜÇÏ°í + Apache2 µð·ºÅ丮 Àüü¿¡ ÀÐ±â ¹× ½ÇÇà (RX) ±ÇÇÑÀ» ºÎ¿©ÇÏ´Â + °ÍÀÌ ÁÁ´Ù. + +

    °èÁ¤¿¡ "·ÎÄà ·Î±×¿Â"°ú "¼­ºñ½º·Î ·Î±×¿Â" ±ÇÇÑÀÌ ÀÖ´Ù¸é, + ±× °èÁ¤À¸·Î ·Î±×¿ÂÇÏ¿© °èÁ¤ÀÌ ½ºÅ©¸³Æ®¸¦ ½ÇÇàÇÏ°í À¥ÆäÀÌÁö¸¦ + ÀÐÀ¸¸ç ÄܼÖâ¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÒ ¼ö ÀÖ´ÂÁö °Ë»çÇغ¼ ¼ö + ÀÖ´Ù. ¿©±â¼­ ¹®Á¦°¡ ¾ø´Ù¸é ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇصµ ¹®Á¦°¡ + ¾ø´Ù.

    + + Error code 2186Àº ¾ÆÆÄÄ¡°¡ ÇÊ¿äÇÑ + ³×Æ®¿÷ ÀÚ¿ø¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù´Â ¸»·Î serviceÀÇ "·Î±×¿Â" + ¼³Á¤À» È®ÀÎÇ϶ó. ¶Ç, ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â °èÁ¤ÀÇ ±ÇÇÑÀ» + »ìÆìºÁ¶ó. + +

    ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇϸé Windows Service Control + Manager¿¡¼­ ¿À·ù¹®À» º¼ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, Á¦¾îÆÇ¿¡¼­ + "¼­ºñ½º"¸¦ »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ´Â °æ¿ì ´ÙÀ½°ú °°Àº ¹®±¸°¡ + ³ª¿Ã ¼ö ÀÖ´Ù:

    + + + Could not start the Apache2 service on \\COMPUTER
    + Error 1067; The process terminated unexpectedly. +
    + +

    ¾ÆÆÄÄ¡ service¸¦ ½ÃÀÛÇÒ¶§ ¹®Á¦°¡ ÀÖÀ¸¸é ÀϹÝÀûÀÎ ÀÌ·± + ¿À·ù°¡ ³ª¿Â´Ù. ½ÇÁ¦ ¾îµð°¡ ¹®Á¦ÀÎÁö ¾Ë·Á¸é ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö + ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇغ¸¶ó.

    + +

    Windows 9x¿¡¼­ ¾ÆÆÄÄ¡´Â Windows NTÀÇ service¿Í ºñ½ÁÇÑ + ¹æ¹ýÀ» Áö¿øÇÑ´Ù. ±×·¯³ª ¸Å¿ì ½ÇÇèÀûÀÎ ±â´ÉÀÌ´Ù. + ½ÇÁ¦ ¼­ºñ½º¿¡ »ç¿ëÇÒ¸¸Å­ ¾ÈÁ¤ÀûÀÌÁö ¾Ê°í ¾ÕÀ¸·Î °³¼±µÉÁö + º¸ÀåÇÒ ¼öµµ ¾ø´Ù. À§ÇèÇϹǷΠȤ½Ã³ª »ç¿ëÇÑ´Ù¸é ÁÖÀÇÇؼ­ + »ç¿ëÇØ¾ß ÇÑ´Ù!

    + +

    µÎ°¡Áö serviceÀÇ Áß¿äÇÑ Â÷ÀÌÁ¡Àº ´ÙÀ½°ú °°´Ù:

    + +
      +
    • ¾ÆÆÄÄ¡°¡ ¼º°øÀûÀ¸·Î ½ÃÀÛÇÏ¸é ¹è°æ¿¡¼­ ½ÇÇàÇÑ´Ù. + ¿¹¸¦ µé¾î, µ¥½ºÅ©Å¾¿¡ ¹Ù·Î°¡±â¸¦ ¸¸µé¾î¼­ ´ÙÀ½ ¸í·ÉÀ» + ½ÇÇàÇÏ´Â °æ¿ì,

      + + + apache -n "MyServiceName" -k start + + +

      service°¡ ¼º°øÀûÀ¸·Î ½ÃÀÛÇϸé ÄܼÖâÀÌ »ý°å´Ù°¡ ±Ý¹æ + »ç¶óÁø´Ù. httpd.conf ¼³Á¤ÆÄÀÏ¿¡ À߸øµÈ ³»¿ëÀÌ ÀÖ´Â µî + ¾ÆÆÄÄ¡ ½ÃÀ۽à ¿À·ù°¡ ¹ß»ýÇϸé ÄܼÖâÀ» °è¼Ó º¸ÀδÙ. ÄܼÖâÀº + ¹®Á¦ÀÇ ¿øÀÎÀ» ÆľÇÇϴµ¥ µµ¿òÀ» ÁÖ´Â ¿À·ù¹®À» º¸¿©ÁØ´Ù.

    • + +
    • Windows 9x´Â NET START¿Í NET + STOP ¸í·É¾î¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù. ¸í·ÉÇÁ·ÒÇÁÆ®¿¡¼­ + -k ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÆÆÄÄ¡ service¸¦ Á¶Á¤ÇØ¾ß + ÇÑ´Ù. +

    • + +
    • + ¾ÆÆÄÄ¡¿Í Windows 9x´Â ³×Æ®¿÷ ±ÇÇÑÀ» °¡Áø ƯÁ¤ »ç¿ëÀÚ·Î + ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏÁö ¸øÇÑ´Ù. »ç½Ç Windows 9x´Â º¸¾ÈÀ» Á¦°øÇÏÁöµµ + ¾Ê´Â´Ù. ÀÌ°ÍÀÌ ¹Ù·Î Apache Software FoundationÀÌ Windows + 9x ½Ã½ºÅÛÀ» °ø°³ À¥¼­¹ö·Î »ç¿ëÇÏ±æ ±ÇÇÏÁö ¾Ê´Â ÀÌÀ¯´Ù. + »ç¿ëÀÚ°¡ À¥ ÄÁÅÙÃ÷¸¦ °³¹ßÇÏ°í ¾ÆÆÄÄ¡ ¼­¹ö ÇнÀÀ» µ½±âÀ§ÇØ, + ¾Æ´Ï¸é ¾ÈÀüÇÑ »ç¼³ ³×Æ®¿÷¿¡ À§Ä¡ÇÒ ÀÎÆ®¶ó³Ý ¼­¹ö¸¦ À§ÇØ, + Windows 9x¸¦ Áö¿øÇÒ »ÓÀÌ´Ù.

    • + +
    + +

    ¾ÆÆÄÄ¡°¡ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î µ¿ÀÛÇÔÀ» È®ÀÎÇÏ¿´´Ù¸é Windows + NT¿¡¼­¿Í °°Àº ¸í·É¾î·Î °¡»ó service¸¦ ¼³Ä¡, Á¶Àý, Á¦°ÅÇÒ + ¼ö ÀÖ´Ù. ¶Ç, Apache Service Monitor¸¦ »ç¿ëÇÏ¿© Windows 9x + °¡»ó service¸¦ °ü¸®ÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    + ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇϱâ + +

    ÀϹÝÀûÀ¸·Î ¾ÆÆÄÄ¡¸¦ service·Î ½ÇÇàÇÏ±æ ±ÇÇÑ´Ù. ±×·¯³ª + ¸í·ÉÇà¿¡¼­ ½ÇÇàÇÏ´Â°Ô ÆíÇÑ °æ¿ì°¡ ÀÖ´Ù (Windows 9x¿¡¼­´Â + service¸¦ ¾ÈÁ¤ÀûÀ¸·Î Áö¿øÇÏÁö ¾Ê±â¶§¹®¿¡ ¸í·ÉÇà¿¡¼­ ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇÏ´Â ¹æ¹ýÀ» ±ÇÇÑ´Ù).

    + +

    ¾ÆÆÄÄ¡¸¦ ÄÜ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇÏ·Á¸é, ¸í·ÉÇà¿¡¼­ ´ÙÀ½ + ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù:

    + + + apache + + +

    ¾ÆÆÄÄ¡´Â Control-C¸¦ ´­·¯¼­ Á¤ÁöÇÒ ¶§±îÁö ½ÇÇàµÈ´Ù.

    + +

    ¶Ç, ½ÃÀÛ ¸Þ´º --> ÇÁ·Î±×·¥ --> Apache HTTP + Server 2.0.xx --> Control Apache Server¿¡ ¼³Ä¡µÈ + Start Apache in Console ¹Ù·Î°¡±â·Î ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Ù. + ¹Ù·Î°¡±â¸¦ ½ÇÇàÇϸé ÄܼÖâÀ» ¿­°í ±× ¾È¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÑ´Ù. + ¾ÆÆÄÄ¡¸¦ service·Î ¼³Ä¡ÇÏÁö ¾Ê¾Ò´Ù¸é, ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â + ÄܼÖâ¿¡¼­ Control-C¸¦ ´­·¯ ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÒ¶§±îÁö âÀÌ ¶°ÀÖ´Ù. + ÀÌ °æ¿ì ¼­¹ö´Â ¸îÃʾȿ¡ Á¾·áÇÑ´Ù. ±×·¯³ª, ¾ÆÆÄÄ¡¸¦ service·Î + ¼³Ä¡ÇÏ¿´´Ù¸é ¹Ù·Î°¡±â´Â service¸¦ ½ÃÀÛÇÑ´Ù. ¾ÆÆÄÄ¡ service°¡ + ÀÌ¹Ì ½ÇÇàÁßÀ̶ó¸é ¹Ù·Î°¡±â´Â ¾Æ¹«Àϵµ ÇÏÁö ¾Ê´Â´Ù.

    + +

    ´Ù¸¥ ÄܼÖâÀ» ¿­°í ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÏ¿© ½ÇÇàÁßÀÎ ¾ÆÆÄÄ¡¸¦ + Á¾·áÇÒ ¼ö ÀÖ´Ù:

    + + + apache -k shutdown + + +

    ÀÌ ¹æ¹ýÀº ¾ÆÆÄÄ¡°¡ ÇöÀç ÀÛ¾÷À» ¸¶Ä¡°í Á¡ÀÝ°Ô Á¾·áÇÒ ¼ö + Àֱ⶧¹®¿¡ Control-C º¸´Ù ³´´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡¸¦ Àç½ÃÀÛÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì ¼³Á¤ÆÄÀÏÀ» ´Ù½Ã + Àд´Ù. ÁøÇàÁßÀÎ ÀÛ¾÷À» Áß°£¿¡ ²÷Áö¾Ê°í ¿Ï·áÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ + Àç½ÃÀÛÇÏ·Á¸é:

    + + + apache -k restart + + + À¯´Ð½º¿ë ¾ÆÆÄÄ¡¿¡ Àͼ÷ÇÑ »ç¶÷À» À§ÇØ: ÀÌ ¸í·É¾î´Â + kill -TERM pid³ª kill -USR1 + pidÀÇ WindowsÆÇÀÌ´Ù. ¸í·ÉÇà ¿É¼Ç + -k´Â À¯´Ð½º kill ¸í·É¾î À̸§À» + º»µû Áö¾ú´Ù. + +

    ¾ÆÆÄÄ¡ ÄܼÖâÀÌ Áï½Ã ȤÀº ½ÃÀÛÈÄ °©Àڱ⠴ÝÄ¡¸é ½ÃÀÛ ¸Þ´º + --> ÇÁ·Î±×·¥ÀÇ ¸í·É ÇÁ·ÒÇÁÆ®¸¦ ½ÇÇàÇÑ´Ù. ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÑ + Æú´õ·Î °¡¼­ apache ¸í·É¾î¸¦ ½ÇÇàÇغ¸°í ¹ß»ýÇÑ + ¿À·ù¹®À» »ìÆ캻´Ù. ±×¸®°í logs Æú´õ·Î °¡¼­, ¼³Á¤ÆÄÀÏÀÌ + À߸øµÇ¾ú´ÂÁö error.log ÆÄÀÏÀ» »ìÆ캻´Ù. ¾ÆÆÄÄ¡¸¦ + ¼³Ä¡ÇÒ¶§ ±âº»°ªÀ» »ç¿ëÇß´Ù¸é ´ÙÀ½°ú °°´Ù:

    + + + c:
    + cd "\Program Files\Apache Group\Apache2\bin"
    + apache +
    + +

    ¾ÆÆÄÄ¡°¡ Á¤ÁöÇÒ ¶§±îÁö ±â´Ù¸®°Å³ª Control-C¸¦ ´©¸¥´Ù. + ±×¸®°í ´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇÑ´Ù:

    + + + cd ..\logs
    + more < error.log +
    + +

    ¾ÆÆÄÄ¡¸¦ ´Ù·ê¶§ ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ¼³Á¤ÆÄÀÏÀ» ã´ÂÁö ¾Æ´Â + °ÍÀÌ Áß¿äÇÏ´Ù. µÎ°¡Áö ¹æ¹ýÀ¸·Î ¸í·ÉÇà¿¡¼­ ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù:

    + +
      +
    • -f´Â ¼³Á¤ÆÄÀÏÀÇ Àý´ë°æ·Î ȤÀº »ó´ë°æ·Î¸¦ + ÁöÁ¤ÇÑ´Ù:

      + + + apache -f "c:\my server files\anotherconfig.conf" + + +

      ȤÀº

      + + + apache -f files\anotherconfig.conf +
    • + +
    • -nÀº ¾ÆÆÄÄ¡ service¸¦ ¼±ÅÃÇÏ°í, ÇØ´ç + serviceÀÇ ¼³Á¤ÆÄÀÏÀ» »ç¿ëÇÑ´Ù:

      + + + apache -n "MyServiceName" + +
    • +
    + +

    µÎ °æ¿ì ¸ðµÎ ¼³Á¤ÆÄÀÏÀÌ ÀûÀýÇÑ ServerRoot¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    -f³ª -nÀ¸·Î ¼³Á¤ÆÄÀÏÀ» ÁöÁ¤ÇÏÁö + ¾ÊÀ¸¸é, ¾ÆÆÄÄ¡´Â conf\httpd.conf¿Í °°ÀÌ ¼­¹ö¿¡ + ÄÄÆÄÀÏµÈ ÆÄÀϸíÀ» »ç¿ëÇÑ´Ù. ÀÌ ±âº» °æ·Î´Â ¼³Ä¡ µð·ºÅ丮¿¡ + »ó´ëÀûÀÌ´Ù. ´ÙÀ½°ú °°ÀÌ -V ¿É¼ÇÀ¸·Î ¾ÆÆÄÄ¡¸¦ + ½ÇÇàÇϸé SERVER_CONFIG_FILEÀ̶õ Ç׸ñ¿¡¼­ ¼­¹ö°¡ + »ç¿ëÇÒ ¼³Á¤ÆÄÀÏÀ» ¾Ë ¼ö ÀÖ´Ù:

    + + + apache -V + + +

    ¾ÆÆÄÄ¡´Â ´ÙÀ½ ¼ø¼­´ë·Î ServerRoot¸¦ ã´Â´Ù:

    + +
      +
    1. -C ¸í·ÉÇà ¿É¼Ç¿¡ »ç¿ëÇÑ ServerRoot Áö½Ã¾î.
    2. + +
    3. -d ¸í·ÉÇà ¿É¼Ç.
    4. + +
    5. ÇöÀç ÀÛ¾÷ µð·ºÅ丮.
    6. + +
    7. ¹ÙÀ̳ʸ® ¼³Ä¡¸¦ Çß´Ù¸é ¼³Ä¡ÇÒ¶§ ¸¸µç registry Ç׸ñ.
    8. + +
    9. ¼­¹ö¿¡ ÄÄÆÄÀÏµÈ server root. ±âº»°ªÀº + /apacheÀÌ°í, apache -V¸¦ ½ÇÇàÇϸé + HTTPD_ROOT¶ó´Â Ç׸ñ¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ´Ù.
    10. +
    + +

    ¼³Ä¡ÇÒ¶§ À©µµ¿ìÁî ·¹Áö½ºÆ®¸®¿¡ ¹öÀü ƯÀ¯ÀÇ ·¹Áö½ºÆ®¸® + Å°¸¦ ¸¸µç´Ù. Å°ÀÇ À§Ä¡´Â ¼³Ä¡ Á¾·ù¿¡ µû¶ó ´Ù¸£´Ù. install + Apache for all users¸¦ ¼±ÅÃÇÏ¿´´Ù¸é + HKEY_LOCAL_MACHINE ¾Æ·¡¿¡ ´ÙÀ½°ú °°Àº Å°¸¦ + ¸¸µç´Ù (¹°·Ð ¹öÀü¹øÈ£´Â ¾ÆÆÄÄ¡ ¹öÀü¸¶´Ù ´Ù¸£´Ù): +

    + + + HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\2.0.43 + + +

    "¸ðµç »ç¿ëÀÚ"¸¦ ´ë»óÀ¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡ÇÏ¿´´Ù¸é + HKEY_CURRENT_USER ¾Æ·¡ Å°°¡ »ý±ä´Ù. ³»¿ëÀº + ÇöÀç ·Î±×¿ÂÇÑ »ç¿ëÀÚ¿¡ µû¶ó ´Ù¸£´Ù:

    + + + HKEY_CURRENT_USER\SOFTWARE\Apache Group\Apache\2.0.43 + + +

    Å° À̸§ÀÌ ¼­¹ö¿¡ ÄÄÆÄÀϵDZ⶧¹®¿¡ ÇöÀç ¹öÀüÀ» °Çµå¸®Áö¾Ê°í + »õ·Î¿î ¹öÀüÀ» ¼³Ä¡ÇÏ¿© Å×½ºÆ®Çغ¼ ¼ö ÀÖ´Ù. ¹°·Ð »õ ¹öÀüÀ» + ´Ù¸¥ ¹öÀü°ú °°Àº µð·ºÅ丮¿¡ ¼³Ä¡ÇÏÁö¾Êµµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù.

    + +

    ¹ÙÀ̳ʸ® ¼³Ä¡¸¦ ÇÏÁö ¾ÊÀº °æ¿ì ¾ÆÆÄÄ¡´Â ·¹Áö½ºÆ®¸® Å°°¡ + ¾ø´Ù°í ºÒÆòÇÒ ¼ö ÀÖ´Ù. ¼­¹ö°¡ ´Ù¸¥ ¹æ¹ýÀ¸·Î ¼³Á¤ÆÄÀÏÀ» ãÀ» + ¼ö ÀÖ´Ù¸é ÀÌ °æ°í¸¦ ¹«½ÃÇصµ µÈ´Ù.

    + +

    Å°ÀÇ °ªÀº ServerRoot + µð·ºÅ丮À̸ç, ÀÌ µð·ºÅ丮¿¡ conf¶ó´Â ÇÏÀ§µð·ºÅ丮°¡ + ÀÖ´Ù. ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé ÀÌ ÇÏÀ§µð·ºÅ丮¿¡¼­ + httpd.conf ÆÄÀÏÀ» Àд´Ù. ÀÌ ÆÄÀÏ¿¡ ³ª¿À´Â + ServerRoot Áö½Ã¾î°¡ + ·¹Áö½ºÆ®¸® Å°¿¡ ³ª¿Â µð·ºÅ丮¿Í ´Ù¸£´Ù¸é, ¾ÆÆÄÄ¡´Â ·¹Áö½ºÆ®¸®¿¡¼­ + ¾òÀº °ªÀ» ¹«½ÃÇÏ°í ¾ÕÀ¸·Î ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â µð·ºÅ丮¸¦ »ç¿ëÇÑ´Ù. + ¾ÆÆÄÄ¡ µð·ºÅ丮³ª ¼³Á¤ÆÄÀÏÀ» ´Ù¸¥ Àå¼Ò·Î º¹»çÇÏ¸é ¹Ýµå½Ã + httpd.conf ÆÄÀÏ¿¡ ÀÖ´Â ServerRoot Áö½Ã¾î¸¦ ±× À§Ä¡·Î + ¼öÁ¤Ç϶ó.

    + +
    + +
    + Á¤»óÀûÀ¸·Î ¼³Ä¡µÇ¾ú´ÂÁö °Ë»çÇϱâ + +

    (ÄܼÖâÀ̳ª service¸¦ ÅëÇØ) ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϸé (¼³Á¤ÆÄÀÏÀÇ + Listen Áö½Ã¾î¸¦ + ¼öÁ¤Çϰųª ¾ÆÆÄÄ¡¸¦ "ÇöÀç »ç¿ëÀÚ¸¸" ´ë»óÀ¸·Î ¼³Ä¡ÇÏÁö ¾Ê´Â + °æ¿ì) 80¹ø Æ÷Æ®¸¦ ±â´Ù¸°´Ù. ºê¶ó¿ìÀú¸¦ ½ÃÀÛÇÏ°í URLÀ» ÀÔ·ÂÇÏ¿© + ¼­¹öÀÇ ±âº» ÆäÀÌÁö¿¡ Á¢±ÙÇÏ´Ù:

    + + + http://localhost/ + + +

    ¾ÆÆÄÄ¡´Â ¾ÆÆÄÄ¡ ¼³¸í¼­ ¸µÅ©°¡ Àִ ȯ¿µÆäÀÌÁö¸¦ º¸¿©Áà¾ß + ÇÑ´Ù. ¾Æ¹« Àϵµ ÀϾÁö ¾Ê°Å³ª ¿À·ù°¡ ³ª¿À¸é, logs + ÇÏÀ§µð·ºÅ丮¿¡ ÀÖ´Â error.log ÆÄÀÏÀ» »ìÆìºÁ¶ó. + È£½ºÆ®°¡ ³×Æ®¿÷¿¡ ¿¬°áµÇÀÖÁö ¾Ê°Å³ª DNS (Domain Name Service) + ¼³Á¤¿¡ ¹®Á¦°¡ ÀÖ´Ù¸é ´ÙÀ½ URLÀ» »ç¿ëÇØ¾ß ÇÑ´Ù:

    + + + http://127.0.0.1/ + + +

    ±âº» ¼³Ä¡°¡ µ¿ÀÛÇϸé conf ÇÏÀ§µð·ºÅ丮¿¡ + ÀÖ´Â ÆÄÀÏÀ» ÀûÀýÈ÷ ¼³Á¤ÇÑ´Ù. ¶Ç, Windows NT ¾ÆÆÄÄ¡ service + ¼³Á¤À» ¼öÁ¤ÇÑ °æ¿ì ¸ÕÀú ¸í·ÉÇà¿¡¼­ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇÏ¿© ¿À·ù°¡ + ¹ß»ýÇÏÁö¾Ê´ÂÁö È®ÀÎÇØ¾ß ÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡°¡ ´Ù¸¥ TCP/IP ÇÁ·Î±×·¥°ú °°Àº Æ÷Æ®¸¦ °øÀ¯ÇÒ ¼ö + ¾ø±â¶§¹®¿¡ ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϱâ Àü¿¡ ´Ù¸¥ + ¼­ºñ½º¸¦ Áß´Ü, Á¦°Å, Àç¼³Á¤ÇØ¾ß ÇÒÁöµµ ¸ð¸¥´Ù. ´Ù¸¥ À¥¼­¹ö³ª + ƯÁ¤ ¹æÈ­º® ¼­¹ö½º¿Í Ãæµ¹ÇÒ ¼ö ÀÖ´Ù. +

    + +
    + +
    diff --git a/trunk/docs/manual/platform/windows.xml.meta b/trunk/docs/manual/platform/windows.xml.meta new file mode 100644 index 0000000000..391c0b6d28 --- /dev/null +++ b/trunk/docs/manual/platform/windows.xml.meta @@ -0,0 +1,12 @@ + + + + windows + /platform/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/ab.html b/trunk/docs/manual/programs/ab.html new file mode 100644 index 0000000000..3ba123c454 --- /dev/null +++ b/trunk/docs/manual/programs/ab.html @@ -0,0 +1,7 @@ +URI: ab.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: ab.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/ab.html.en b/trunk/docs/manual/programs/ab.html.en new file mode 100644 index 0000000000..c87b10b5a4 --- /dev/null +++ b/trunk/docs/manual/programs/ab.html.en @@ -0,0 +1,198 @@ + + + +ab - Apache HTTP server benchmarking tool - Apache HTTP Server + + + + + +
    <-
    +

    ab - Apache HTTP server benchmarking tool

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    ab is a tool for benchmarking your Apache Hypertext + Transfer Protocol (HTTP) server. It is designed to give you an impression + of how your current Apache installation performs. This especially shows + you how many requests per second your Apache installation is capable of + serving.

    +
    +

    See also

    +
    top
    +
    +

    Synopsis

    +

    ab + [ -A auth-username:password ] + [ -c concurrency ] + [ -C cookie-name=value ] + [ -d ] + [ -e csv-file ] + [ -g gnuplot-file ] + [ -h ] + [ -H custom-header ] + [ -i ] + [ -k ] + [ -n requests ] + [ -p POST-file ] + [ -P proxy-auth-username:password ] + [ -q ] + [ -s ] + [ -S ] + [ -t timelimit ] + [ -T content-type ] + [ -v verbosity] + [ -V ] + [ -w ] + [ -x <table>-attributes ] + [ -X proxy[:port] ] + [ -y <tr>-attributes ] + [ -z <td>-attributes ] + [http://]hostname[:port]/path

    +
    top
    +
    +

    Options

    +
    +
    -A auth-username:password
    +
    Supply BASIC Authentication credentials to the server. The username and + password are separated by a single : and sent on the wire + base64 encoded. The string is sent regardless of whether the server needs + it (i.e., has sent an 401 authentication needed).
    + +
    -c concurrency
    +
    Number of multiple requests to perform at a time. Default is one + request at a time.
    + +
    -C cookie-name=value
    +
    Add a Cookie: line to the request. The argument is + typically in the form of a name=value + pair. This field is repeatable.
    + +
    -d
    +
    Do not display the "percentage served within XX [ms] table". (legacy + support).
    + +
    -e csv-file
    +
    Write a Comma separated value (CSV) file which contains for each + percentage (from 1% to 100%) the time (in milliseconds) it took to serve + that percentage of the requests. This is usually more useful than the + 'gnuplot' file; as the results are already 'binned'.
    + +
    -g gnuplot-file
    +
    Write all measured values out as a 'gnuplot' or TSV (Tab separate + values) file. This file can easily be imported into packages like Gnuplot, + IDL, Mathematica, Igor or even Excel. The labels are on the first line of + the file.
    + +
    -h
    +
    Display usage information.
    + +
    -H custom-header
    +
    Append extra headers to the request. The argument is typically in + the form of a valid header line, containing a colon-separated field-value + pair (i.e., "Accept-Encoding: zip/zop;8bit").
    + +
    -i
    +
    Do HEAD requests instead of GET.
    + +
    -k
    +
    Enable the HTTP KeepAlive feature, i.e., perform multiple + requests within one HTTP session. Default is no KeepAlive.
    + +
    -n requests
    +
    Number of requests to perform for the benchmarking session. The default + is to just perform a single request which usually leads to + non-representative benchmarking results.
    + +
    -p POST-file
    +
    File containing data to POST.
    + +
    -P proxy-auth-username:password
    +
    Supply BASIC Authentication credentials to a proxy en-route. The + username and password are separated by a single : and sent on + the wire base64 encoded. The string is sent regardless of whether the + proxy needs it (i.e., has sent an 407 proxy authentication + needed).
    + +
    -q
    +
    When processing more than 150 requests, ab outputs a + progress count on stderr every 10% or 100 requests or so. The + -q flag will suppress these messages.
    + +
    -s
    +
    When compiled in (ab -h will show you) use the SSL + protected https rather than the http protocol. + This feature is experimental and very rudimentary. You probably + do not want to use it.
    + +
    -S
    +
    Do not display the median and standard deviation values, nor display + the warning/error messages when the average and median are more than + one or two times the standard deviation apart. And default to the + min/avg/max values. (legacy support).
    + +
    -t timelimit
    +
    Maximum number of seconds to spend for benchmarking. This implies a + -n 50000 internally. Use this to benchmark the server within a + fixed total amount of time. Per default there is no timelimit.
    + +
    -T content-type
    +
    Content-type header to use for POST data.
    + +
    -v verbosity
    +
    Set verbosity level - 4 and above prints information on + headers, 3 and above prints response codes (404, 200, etc.), + 2 and above prints warnings and info.
    + +
    -V
    +
    Display version number and exit.
    + +
    -w
    +
    Print out results in HTML tables. Default table is two columns wide, + with a white background.
    + +
    -x <table>-attributes
    +
    String to use as attributes for <table>. Attributes + are inserted <table here >.
    + +
    -X proxy[:port]
    +
    Use a proxy server for the requests.
    + +
    -y <tr>-attributes
    +
    String to use as attributes for <tr>.
    + +
    -z <td>-attributes
    +
    String to use as attributes for <td>.
    +
    +
    top
    +
    +

    Bugs

    +

    There are various statically declared buffers of fixed length. Combined + with the lazy parsing of the command line arguments, the response headers + from the server and other external inputs, this might bite you.

    + +

    It does not implement HTTP/1.x fully; only accepts some 'expected' forms + of responses. The rather heavy use of strstr(3) shows up top + in profile, which might indicate a performance problem; i.e., you + would measure the ab performance rather than the server's.

    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/ab.html.ko.euc-kr b/trunk/docs/manual/programs/ab.html.ko.euc-kr new file mode 100644 index 0000000000..c2d4a4cf41 --- /dev/null +++ b/trunk/docs/manual/programs/ab.html.ko.euc-kr @@ -0,0 +1,201 @@ + + + +ab - ¾ÆÆÄÄ¡ À¥¼­¹ö ¼º´É°Ë»ç µµ±¸ - Apache HTTP Server + + + + + +
    <-
    +

    ab - ¾ÆÆÄÄ¡ À¥¼­¹ö ¼º´É°Ë»ç µµ±¸

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ab´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (HTTP) + ¼­¹öÀÇ ¼º´ÉÀ» °Ë»çÇÏ´Â(benchmarking) µµ±¸ÀÌ´Ù. ÇöÀç ¾ÆÆÄÄ¡°¡ + ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö ¾Ë·ÁÁØ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡°¡ ÇöÀç ÃÊ´ç ¸î°³ÀÇ + ¿äûÀ» ¼­ºñ½ºÇÏ´ÂÁö ¾Ë·ÁÁØ´Ù.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    ab + [ -A auth-username:password ] + [ -c concurrency ] + [ -C cookie-name=value ] + [ -d ] + [ -e csv-file ] + [ -g gnuplot-file ] + [ -h ] + [ -H custom-header ] + [ -i ] + [ -k ] + [ -n requests ] + [ -p POST-file ] + [ -P proxy-auth-username:password ] + [ -q ] + [ -s ] + [ -S ] + [ -t timelimit ] + [ -T content-type ] + [ -v verbosity] + [ -V ] + [ -w ] + [ -x <table>-attributes ] + [ -X proxy[:port] ] + [ -y <tr>-attributes ] + [ -z <td>-attributes ] + [http://]hostname[:port]/path

    +
    top
    +
    +

    ¿É¼Ç

    +
    +
    -A auth-username:password
    +
    ¼­¹ö¿¡°Ô BASIC Authentication Á¤º¸¸¦ Á¦°øÇÑ´Ù. + :À¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ base64 ÀÎÄÚµùÇÏ¿© + Àü¼ÛÇÑ´Ù. ¼­¹ö°¡ Á¤º¸¸¦ ¿ä±¸ÇÏ´ÂÁö (¿¹¸¦ µé¾î, + 401 ÀÎÁõ Çʿ並 º¸³»´ÂÁö) °ü°è¾øÀÌ ¹®ÀÚ¿­À» Àü¼ÛÇÑ´Ù.
    + +
    -c concurrency
    +
    µ¿½Ã¿¡ ¿äûÇÏ´Â ¿äû¼ö. ±âº»ÀûÀ¸·Î Çѹø¿¡ ÇÑ ¿äû¸¸À» + º¸³½´Ù.
    + +
    -C cookie-name=value
    +
    ¿äû¿¡ Cookie: Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ¾Æ±Ô¸ÕÆ®´Â + º¸Åë name=value¿Í °°Àº + ½ÖÀÌ´Ù. ÀÌ ¿É¼ÇÀº ¿©·¯¹ø »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    -d
    +
    "percentage served within XX [ms] table"À» Ãâ·ÂÇÏÁö + ¾Ê´Â´Ù. (ȣȯ¼ºÀ» À§ÇØ).
    + +
    -e csv-file
    +
    ¿äûÀ» ó¸®Çϴµ¥ °É¸° (¹Ð¸®ÃÊ ´ÜÀ§) ½Ã°£µéÀÇ (1%¿¡¼­ + 100%) ´©Àû¹éºÐÀ²À» ½°Ç¥·Î ±¸ºÐÇÑ Çü½Ä(CSV)À¸·Î Ãâ·ÂÇÑ´Ù. + °á°ú¸¦ ÀÌ¹Ì 'Á¤¸®'ÇÏ¿´±â¶§¹®¿¡ 'gnuplot' ÆÄÀϺ¸´Ù º¸Åë ´õ + À¯¿ëÇÏ´Ù.
    + +
    -g gnuplot-file
    +
    ÃøÁ¤ÇÑ ¸ðµç °ªÀ» 'gnuplot' ȤÀº TSV (Tab separate values, + ÅÇÀ¸·Î ±¸ºÐÇÑ °ª) ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. Gnuplot, IDL, Mathematica, + Igor, ½ÉÁö¾î Excel °°Àº ÇÁ·Î±×·¥¿¡¼­µµ ÀÌ·± ÆÄÀÏÀ» ½±°Ô + ÀÐÀ» ¼ö ÀÖ´Ù. ÆÄÀÏÀÇ Ã¹¹ø° ÁÙ¿¡ Ç׸ñÀ̸§ÀÌ ³ª¿Â´Ù.
    + +
    -h
    +
    »ç¿ë¹ýÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -H custom-header
    +
    ¿äû¿¡ Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ¾Æ±Ô¸ÕÆ®´Â º¸Åë ÄÝ·ÐÀ¸·Î ±¸ºÐÇÑ + ½ÖÀÎ (¿¹¸¦ µé¾î, + "Accept-Encoding: zip/zop;8bit") À¯È¿ÇÑ + Çì´õÁÙÀÌ´Ù.
    + +
    -i
    +
    GET ´ë½Å HEAD ¿äûÀ» ÇÑ´Ù.
    + +
    -k
    +
    HTTP KeepAlive ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, + ÇÑ HTTP ¼¼¼Ç¿¡¼­ ¿©·¯ ¿äûÀ» ÇÑ´Ù. ±âº»ÀûÀ¸·Î KeepAlive¸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    -n requests
    +
    ¼º´ÉÀ» °Ë»çÇϱâÀ§ÇØ º¸³»´Â ¿äû¼ö. ±âº»°ªÀ¸·Î ¿äûÀ» + Çѹø¸¸ º¸³»±â¶§¹®¿¡ ÀϹÝÀûÀÎ ¼º´É°Ë»ç °á°ú¸¦ ¾òÀ» ¼ö ¾ø´Ù.
    + +
    -p POST-file
    +
    POST ÀÚ·á ÆÄÀÏ.
    + +
    -P proxy-auth-username:password
    +
    ÇÁ·Ï½Ã¸¦ ÅëÇØ BASIC Authentication Á¤º¸¸¦ Á¦°øÇÑ´Ù. + :·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ base64 ÀÎÄÚµùÇÏ¿© + Àü¼ÛÇÑ´Ù. ÇÁ·Ï½Ã°¡ Á¤º¸¸¦ ¿ä±¸ÇÏ´ÂÁö (¿¹¸¦ µé¾î, + 401 ÀÎÁõ Çʿ並 º¸³»´ÂÁö) °ü°è¾øÀÌ ¹®ÀÚ¿­À» Àü¼ÛÇÑ´Ù.
    + +
    -q
    +
    150°³ ÀÌ»ó ¿äûÀ» º¸³¾¶§ ab´Â 10% ȤÀº + ¸Å 100 ¿äû´ç Ç¥ÁØ¿À·ù¿¡ ÁøÇà»óȲÀ» Ãâ·ÂÇÑ´Ù. + -q ¿É¼ÇÀº ÀÌ ¹®±¸¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    -s
    +
    ±â´ÉÀ» Ãß°¡ÇÏ¿© ÄÄÆÄÀÏÇÏ¿´´Ù¸é (ab -h·Î + È®ÀÎÇÒ ¼ö ÀÖ´Ù) http ÇÁ·ÎÅäÄÝ ´ë½Å SSLÀ» »ç¿ëÇÑ + https ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÑ´Ù. ÀÌ ±â´ÉÀº ½ÇÇèÀûÀÌ°í + ¸Å¿ì ±âÃÊÀûÀÌ´Ù. ¾Æ¸¶µµ »ç¿ëÀ» ²¨·ÁÇÒ °ÍÀÌ´Ù.
    + +
    -S
    +
    Áß°£°ª°ú Ç¥ÁØÆíÂ÷¸¦ Ãâ·ÂÇÏÁö ¾Ê°í, Æò±Õ°ú Áß°£°ªÀÇ Â÷ÀÌ°¡ + Ç¥ÁØÆíÂ÷º¸´Ù Å©´õ¶óµµ °æ°í/¿À·ù¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù. + ÃÖ¼Ò/Æò±Õ/ÃÖ´ë °ªÀ» Ãâ·ÂÇÑ´Ù. (ȣȯ¼ºÀ» À§ÇØ).
    + +
    -t timelimit
    +
    ¼º´ÉÀ» °Ë»çÇÏ´Â ÃÖ´ë ÃÊ´ÜÀ§ ½Ã°£. ³»ºÎÀûÀ¸·Î + -n 50000À» °¡Á¤ÇÑ´Ù. Á¤ÇØÁø ½Ã°£µ¿¾È ¼­¹ö ¼º´ÉÀ» + °Ë»çÇÒ¶§ »ç¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î ½Ã°£Á¦ÇÑ ¾øÀÌ °Ë»çÇÑ´Ù.
    + +
    -T content-type
    +
    POST ÀÚ·áÀÇ Content-type Çì´õ.
    + +
    -v verbosity
    +
    Ãâ·ÂÀÇ ÀÚ¼¼ÇÔ ¼öÁØÀ» ÁöÁ¤ÇÑ´Ù. 4 ÀÌ»óÀ̸é + Çì´õ¿¡ ´ëÇÑ Á¤º¸¸¦, 3 ÀÌ»óÀ̸é (404, 202, µî) + ÀÀ´äÄڵ带, 2 ÀÌ»óÀÌ¸é °æ°í(warning)¿Í + Á¤º¸(info)¸¦ Ãâ·ÂÇÑ´Ù.
    + +
    -V
    +
    ¹öÀüÀ» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    + +
    -w
    +
    °á°ú¸¦ HTML Ç¥·Î Ãâ·ÂÇÑ´Ù. ±âº»ÀûÀ¸·Î Ç¥¸¦ Èò ¹è°æ¿¡ + µÎ ¿­·Î ÀÛ¼ºÇÑ´Ù.
    + +
    -x <table>-attributes
    +
    <table>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­. + ¼Ó¼ºÀ» <table ¿©±â¿¡ > + Ãß°¡ÇÑ´Ù.
    + +
    -X proxy[:port]
    +
    ÇÁ·Ï½Ã ¼­¹ö¸¦ »ç¿ëÇÏ¿© ¿äûÇÑ´Ù.
    + +
    -y <tr>-attributes
    +
    <tr>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­.
    + +
    -z <td>-attributes
    +
    <td>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­.
    +
    +
    top
    +
    +

    ¹ö±×

    +

    Á¤ÀûÀ¸·Î ±æÀÌ°¡ °íÁ¤µÈ ¹öÆÛ¸¦ ¸¹ÀÌ »ç¿ëÇÑ´Ù. ¸í·ÉÇà + ¾Æ±Ô¸ÕÆ®, ¼­¹öÀÇ ÀÀ´ä Çì´õ, ´Ù¸¥ ¿ÜºÎ ÀԷµéÀ» °°ÀÌ + ÀоîµéÀ̸鼭 ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ÇÁ·Î±×·¥Àº HTTP/1.x¸¦ ¿ÏÀüÈ÷ ±¸ÇöÇÏÁö ¾Ê´Â´Ù; ´ÜÁö + '±â´ëÇÏ´Â' Çü½ÄÀÇ ÀÀ´ä¸¸À» ¹Þ´Â´Ù. strstr(3)À» + ¸Å¿ì ¸¹ÀÌ »ç¿ë±â¶§¹®¿¡ ¼Óµµ°¡ ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù; Áï, + ¼­¹ö ¼º´Éº¸´Ù´Â ab ¼º´ÉÀ» ÃøÁ¤ÇÏ°Ô µÉ ¼öµµ + ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/ab.xml b/trunk/docs/manual/programs/ab.xml new file mode 100644 index 0000000000..1aeec1b43a --- /dev/null +++ b/trunk/docs/manual/programs/ab.xml @@ -0,0 +1,193 @@ + + + + + + + + +Programs + +ab - Apache HTTP server benchmarking tool + + +

    ab is a tool for benchmarking your Apache Hypertext + Transfer Protocol (HTTP) server. It is designed to give you an impression + of how your current Apache installation performs. This especially shows + you how many requests per second your Apache installation is capable of + serving.

    +
    +httpd + +
    Synopsis +

    ab + [ -A auth-username:password ] + [ -c concurrency ] + [ -C cookie-name=value ] + [ -d ] + [ -e csv-file ] + [ -g gnuplot-file ] + [ -h ] + [ -H custom-header ] + [ -i ] + [ -k ] + [ -n requests ] + [ -p POST-file ] + [ -P proxy-auth-username:password ] + [ -q ] + [ -s ] + [ -S ] + [ -t timelimit ] + [ -T content-type ] + [ -v verbosity] + [ -V ] + [ -w ] + [ -x <table>-attributes ] + [ -X proxy[:port] ] + [ -y <tr>-attributes ] + [ -z <td>-attributes ] + [http://]hostname[:port]/path

    +
    + +
    Options +
    +
    -A auth-username:password
    +
    Supply BASIC Authentication credentials to the server. The username and + password are separated by a single : and sent on the wire + base64 encoded. The string is sent regardless of whether the server needs + it (i.e., has sent an 401 authentication needed).
    + +
    -c concurrency
    +
    Number of multiple requests to perform at a time. Default is one + request at a time.
    + +
    -C cookie-name=value
    +
    Add a Cookie: line to the request. The argument is + typically in the form of a name=value + pair. This field is repeatable.
    + +
    -d
    +
    Do not display the "percentage served within XX [ms] table". (legacy + support).
    + +
    -e csv-file
    +
    Write a Comma separated value (CSV) file which contains for each + percentage (from 1% to 100%) the time (in milliseconds) it took to serve + that percentage of the requests. This is usually more useful than the + 'gnuplot' file; as the results are already 'binned'.
    + +
    -g gnuplot-file
    +
    Write all measured values out as a 'gnuplot' or TSV (Tab separate + values) file. This file can easily be imported into packages like Gnuplot, + IDL, Mathematica, Igor or even Excel. The labels are on the first line of + the file.
    + +
    -h
    +
    Display usage information.
    + +
    -H custom-header
    +
    Append extra headers to the request. The argument is typically in + the form of a valid header line, containing a colon-separated field-value + pair (i.e., "Accept-Encoding: zip/zop;8bit").
    + +
    -i
    +
    Do HEAD requests instead of GET.
    + +
    -k
    +
    Enable the HTTP KeepAlive feature, i.e., perform multiple + requests within one HTTP session. Default is no KeepAlive.
    + +
    -n requests
    +
    Number of requests to perform for the benchmarking session. The default + is to just perform a single request which usually leads to + non-representative benchmarking results.
    + +
    -p POST-file
    +
    File containing data to POST.
    + +
    -P proxy-auth-username:password
    +
    Supply BASIC Authentication credentials to a proxy en-route. The + username and password are separated by a single : and sent on + the wire base64 encoded. The string is sent regardless of whether the + proxy needs it (i.e., has sent an 407 proxy authentication + needed).
    + +
    -q
    +
    When processing more than 150 requests, ab outputs a + progress count on stderr every 10% or 100 requests or so. The + -q flag will suppress these messages.
    + +
    -s
    +
    When compiled in (ab -h will show you) use the SSL + protected https rather than the http protocol. + This feature is experimental and very rudimentary. You probably + do not want to use it.
    + +
    -S
    +
    Do not display the median and standard deviation values, nor display + the warning/error messages when the average and median are more than + one or two times the standard deviation apart. And default to the + min/avg/max values. (legacy support).
    + +
    -t timelimit
    +
    Maximum number of seconds to spend for benchmarking. This implies a + -n 50000 internally. Use this to benchmark the server within a + fixed total amount of time. Per default there is no timelimit.
    + +
    -T content-type
    +
    Content-type header to use for POST data.
    + +
    -v verbosity
    +
    Set verbosity level - 4 and above prints information on + headers, 3 and above prints response codes (404, 200, etc.), + 2 and above prints warnings and info.
    + +
    -V
    +
    Display version number and exit.
    + +
    -w
    +
    Print out results in HTML tables. Default table is two columns wide, + with a white background.
    + +
    -x <table>-attributes
    +
    String to use as attributes for <table>. Attributes + are inserted <table here >.
    + +
    -X proxy[:port]
    +
    Use a proxy server for the requests.
    + +
    -y <tr>-attributes
    +
    String to use as attributes for <tr>.
    + +
    -z <td>-attributes
    +
    String to use as attributes for <td>.
    +
    +
    + +
    Bugs +

    There are various statically declared buffers of fixed length. Combined + with the lazy parsing of the command line arguments, the response headers + from the server and other external inputs, this might bite you.

    + +

    It does not implement HTTP/1.x fully; only accepts some 'expected' forms + of responses. The rather heavy use of strstr(3) shows up top + in profile, which might indicate a performance problem; i.e., you + would measure the ab performance rather than the server's.

    +
    + +
    diff --git a/trunk/docs/manual/programs/ab.xml.ko b/trunk/docs/manual/programs/ab.xml.ko new file mode 100644 index 0000000000..3db250fc5b --- /dev/null +++ b/trunk/docs/manual/programs/ab.xml.ko @@ -0,0 +1,194 @@ + + + + + + + + +Programs + +ab - ¾ÆÆÄÄ¡ À¥¼­¹ö ¼º´É°Ë»ç µµ±¸ + + +

    ab´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ (HTTP) + ¼­¹öÀÇ ¼º´ÉÀ» °Ë»çÇÏ´Â(benchmarking) µµ±¸ÀÌ´Ù. ÇöÀç ¾ÆÆÄÄ¡°¡ + ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö ¾Ë·ÁÁØ´Ù. ƯÈ÷ ¾ÆÆÄÄ¡°¡ ÇöÀç ÃÊ´ç ¸î°³ÀÇ + ¿äûÀ» ¼­ºñ½ºÇÏ´ÂÁö ¾Ë·ÁÁØ´Ù.

    +
    +httpd + +
    °³¿ä +

    ab + [ -A auth-username:password ] + [ -c concurrency ] + [ -C cookie-name=value ] + [ -d ] + [ -e csv-file ] + [ -g gnuplot-file ] + [ -h ] + [ -H custom-header ] + [ -i ] + [ -k ] + [ -n requests ] + [ -p POST-file ] + [ -P proxy-auth-username:password ] + [ -q ] + [ -s ] + [ -S ] + [ -t timelimit ] + [ -T content-type ] + [ -v verbosity] + [ -V ] + [ -w ] + [ -x <table>-attributes ] + [ -X proxy[:port] ] + [ -y <tr>-attributes ] + [ -z <td>-attributes ] + [http://]hostname[:port]/path

    +
    + +
    ¿É¼Ç +
    +
    -A auth-username:password
    +
    ¼­¹ö¿¡°Ô BASIC Authentication Á¤º¸¸¦ Á¦°øÇÑ´Ù. + :À¸·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ base64 ÀÎÄÚµùÇÏ¿© + Àü¼ÛÇÑ´Ù. ¼­¹ö°¡ Á¤º¸¸¦ ¿ä±¸ÇÏ´ÂÁö (¿¹¸¦ µé¾î, + 401 ÀÎÁõ Çʿ並 º¸³»´ÂÁö) °ü°è¾øÀÌ ¹®ÀÚ¿­À» Àü¼ÛÇÑ´Ù.
    + +
    -c concurrency
    +
    µ¿½Ã¿¡ ¿äûÇÏ´Â ¿äû¼ö. ±âº»ÀûÀ¸·Î Çѹø¿¡ ÇÑ ¿äû¸¸À» + º¸³½´Ù.
    + +
    -C cookie-name=value
    +
    ¿äû¿¡ Cookie: Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ¾Æ±Ô¸ÕÆ®´Â + º¸Åë name=value¿Í °°Àº + ½ÖÀÌ´Ù. ÀÌ ¿É¼ÇÀº ¿©·¯¹ø »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    + +
    -d
    +
    "percentage served within XX [ms] table"À» Ãâ·ÂÇÏÁö + ¾Ê´Â´Ù. (ȣȯ¼ºÀ» À§ÇØ).
    + +
    -e csv-file
    +
    ¿äûÀ» ó¸®Çϴµ¥ °É¸° (¹Ð¸®ÃÊ ´ÜÀ§) ½Ã°£µéÀÇ (1%¿¡¼­ + 100%) ´©Àû¹éºÐÀ²À» ½°Ç¥·Î ±¸ºÐÇÑ Çü½Ä(CSV)À¸·Î Ãâ·ÂÇÑ´Ù. + °á°ú¸¦ ÀÌ¹Ì 'Á¤¸®'ÇÏ¿´±â¶§¹®¿¡ 'gnuplot' ÆÄÀϺ¸´Ù º¸Åë ´õ + À¯¿ëÇÏ´Ù.
    + +
    -g gnuplot-file
    +
    ÃøÁ¤ÇÑ ¸ðµç °ªÀ» 'gnuplot' ȤÀº TSV (Tab separate values, + ÅÇÀ¸·Î ±¸ºÐÇÑ °ª) ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. Gnuplot, IDL, Mathematica, + Igor, ½ÉÁö¾î Excel °°Àº ÇÁ·Î±×·¥¿¡¼­µµ ÀÌ·± ÆÄÀÏÀ» ½±°Ô + ÀÐÀ» ¼ö ÀÖ´Ù. ÆÄÀÏÀÇ Ã¹¹ø° ÁÙ¿¡ Ç׸ñÀ̸§ÀÌ ³ª¿Â´Ù.
    + +
    -h
    +
    »ç¿ë¹ýÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -H custom-header
    +
    ¿äû¿¡ Çì´õ¸¦ Ãß°¡ÇÑ´Ù. ¾Æ±Ô¸ÕÆ®´Â º¸Åë ÄÝ·ÐÀ¸·Î ±¸ºÐÇÑ + ½ÖÀÎ (¿¹¸¦ µé¾î, + "Accept-Encoding: zip/zop;8bit") À¯È¿ÇÑ + Çì´õÁÙÀÌ´Ù.
    + +
    -i
    +
    GET ´ë½Å HEAD ¿äûÀ» ÇÑ´Ù.
    + +
    -k
    +
    HTTP KeepAlive ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, + ÇÑ HTTP ¼¼¼Ç¿¡¼­ ¿©·¯ ¿äûÀ» ÇÑ´Ù. ±âº»ÀûÀ¸·Î KeepAlive¸¦ + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    -n requests
    +
    ¼º´ÉÀ» °Ë»çÇϱâÀ§ÇØ º¸³»´Â ¿äû¼ö. ±âº»°ªÀ¸·Î ¿äûÀ» + Çѹø¸¸ º¸³»±â¶§¹®¿¡ ÀϹÝÀûÀÎ ¼º´É°Ë»ç °á°ú¸¦ ¾òÀ» ¼ö ¾ø´Ù.
    + +
    -p POST-file
    +
    POST ÀÚ·á ÆÄÀÏ.
    + +
    -P proxy-auth-username:password
    +
    ÇÁ·Ï½Ã¸¦ ÅëÇØ BASIC Authentication Á¤º¸¸¦ Á¦°øÇÑ´Ù. + :·Î ±¸ºÐÇÑ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ base64 ÀÎÄÚµùÇÏ¿© + Àü¼ÛÇÑ´Ù. ÇÁ·Ï½Ã°¡ Á¤º¸¸¦ ¿ä±¸ÇÏ´ÂÁö (¿¹¸¦ µé¾î, + 401 ÀÎÁõ Çʿ並 º¸³»´ÂÁö) °ü°è¾øÀÌ ¹®ÀÚ¿­À» Àü¼ÛÇÑ´Ù.
    + +
    -q
    +
    150°³ ÀÌ»ó ¿äûÀ» º¸³¾¶§ ab´Â 10% ȤÀº + ¸Å 100 ¿äû´ç Ç¥ÁØ¿À·ù¿¡ ÁøÇà»óȲÀ» Ãâ·ÂÇÑ´Ù. + -q ¿É¼ÇÀº ÀÌ ¹®±¸¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    -s
    +
    ±â´ÉÀ» Ãß°¡ÇÏ¿© ÄÄÆÄÀÏÇÏ¿´´Ù¸é (ab -h·Î + È®ÀÎÇÒ ¼ö ÀÖ´Ù) http ÇÁ·ÎÅäÄÝ ´ë½Å SSLÀ» »ç¿ëÇÑ + https ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÑ´Ù. ÀÌ ±â´ÉÀº ½ÇÇèÀûÀÌ°í + ¸Å¿ì ±âÃÊÀûÀÌ´Ù. ¾Æ¸¶µµ »ç¿ëÀ» ²¨·ÁÇÒ °ÍÀÌ´Ù.
    + +
    -S
    +
    Áß°£°ª°ú Ç¥ÁØÆíÂ÷¸¦ Ãâ·ÂÇÏÁö ¾Ê°í, Æò±Õ°ú Áß°£°ªÀÇ Â÷ÀÌ°¡ + Ç¥ÁØÆíÂ÷º¸´Ù Å©´õ¶óµµ °æ°í/¿À·ù¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù. + ÃÖ¼Ò/Æò±Õ/ÃÖ´ë °ªÀ» Ãâ·ÂÇÑ´Ù. (ȣȯ¼ºÀ» À§ÇØ).
    + +
    -t timelimit
    +
    ¼º´ÉÀ» °Ë»çÇÏ´Â ÃÖ´ë ÃÊ´ÜÀ§ ½Ã°£. ³»ºÎÀûÀ¸·Î + -n 50000À» °¡Á¤ÇÑ´Ù. Á¤ÇØÁø ½Ã°£µ¿¾È ¼­¹ö ¼º´ÉÀ» + °Ë»çÇÒ¶§ »ç¿ëÇÑ´Ù. ±âº»ÀûÀ¸·Î ½Ã°£Á¦ÇÑ ¾øÀÌ °Ë»çÇÑ´Ù.
    + +
    -T content-type
    +
    POST ÀÚ·áÀÇ Content-type Çì´õ.
    + +
    -v verbosity
    +
    Ãâ·ÂÀÇ ÀÚ¼¼ÇÔ ¼öÁØÀ» ÁöÁ¤ÇÑ´Ù. 4 ÀÌ»óÀ̸é + Çì´õ¿¡ ´ëÇÑ Á¤º¸¸¦, 3 ÀÌ»óÀ̸é (404, 202, µî) + ÀÀ´äÄڵ带, 2 ÀÌ»óÀÌ¸é °æ°í(warning)¿Í + Á¤º¸(info)¸¦ Ãâ·ÂÇÑ´Ù.
    + +
    -V
    +
    ¹öÀüÀ» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    + +
    -w
    +
    °á°ú¸¦ HTML Ç¥·Î Ãâ·ÂÇÑ´Ù. ±âº»ÀûÀ¸·Î Ç¥¸¦ Èò ¹è°æ¿¡ + µÎ ¿­·Î ÀÛ¼ºÇÑ´Ù.
    + +
    -x <table>-attributes
    +
    <table>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­. + ¼Ó¼ºÀ» <table ¿©±â¿¡ > + Ãß°¡ÇÑ´Ù.
    + +
    -X proxy[:port]
    +
    ÇÁ·Ï½Ã ¼­¹ö¸¦ »ç¿ëÇÏ¿© ¿äûÇÑ´Ù.
    + +
    -y <tr>-attributes
    +
    <tr>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­.
    + +
    -z <td>-attributes
    +
    <td>ÀÇ ¼Ó¼ºÀ¸·Î »ç¿ëÇÒ ¹®ÀÚ¿­.
    +
    +
    + +
    ¹ö±× +

    Á¤ÀûÀ¸·Î ±æÀÌ°¡ °íÁ¤µÈ ¹öÆÛ¸¦ ¸¹ÀÌ »ç¿ëÇÑ´Ù. ¸í·ÉÇà + ¾Æ±Ô¸ÕÆ®, ¼­¹öÀÇ ÀÀ´ä Çì´õ, ´Ù¸¥ ¿ÜºÎ ÀԷµéÀ» °°ÀÌ + ÀоîµéÀ̸鼭 ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù.

    + +

    ÀÌ ÇÁ·Î±×·¥Àº HTTP/1.x¸¦ ¿ÏÀüÈ÷ ±¸ÇöÇÏÁö ¾Ê´Â´Ù; ´ÜÁö + '±â´ëÇÏ´Â' Çü½ÄÀÇ ÀÀ´ä¸¸À» ¹Þ´Â´Ù. strstr(3)À» + ¸Å¿ì ¸¹ÀÌ »ç¿ë±â¶§¹®¿¡ ¼Óµµ°¡ ¹®Á¦°¡ µÉ ¼ö ÀÖ´Ù; Áï, + ¼­¹ö ¼º´Éº¸´Ù´Â ab ¼º´ÉÀ» ÃøÁ¤ÇÏ°Ô µÉ ¼öµµ + ÀÖ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/programs/ab.xml.meta b/trunk/docs/manual/programs/ab.xml.meta new file mode 100644 index 0000000000..0b388dfb5f --- /dev/null +++ b/trunk/docs/manual/programs/ab.xml.meta @@ -0,0 +1,12 @@ + + + + ab + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/apachectl.html b/trunk/docs/manual/programs/apachectl.html new file mode 100644 index 0000000000..b3966d8d90 --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.html @@ -0,0 +1,7 @@ +URI: apachectl.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: apachectl.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/apachectl.html.en b/trunk/docs/manual/programs/apachectl.html.en new file mode 100644 index 0000000000..dac194ed9c --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.html.en @@ -0,0 +1,151 @@ + + + +apachectl - Apache HTTP Server Control Interface - Apache HTTP Server + + + + + +
    <-
    +

    apachectl - Apache HTTP Server Control Interface

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    apachectl is a front end to the Apache HyperText + Transfer Protocol (HTTP) server. It is designed to help the + administrator control the functioning of the Apache + httpd daemon.

    + +

    The apachectl script can operate in two modes. + First, it can act as a simple front-end to the httpd + command that simply sets any necessary environment variables and + then invokes httpd, passing through any command line + arguments. Second, apachectl can act as a SysV init + script, taking simple one-word arguments like start, + restart, and stop, and translating them + into appropriate signals to httpd.

    + +

    If your Apache installation uses non-standard paths, you will + need to edit the apachectl script to set the + appropriate paths to the httpd binary. You can also + specify any necessary httpd command line arguments. + See the comments in the script for details.

    + +

    The apachectl script returns a 0 exit value on + success, and >0 if an error occurs. For more details, view + the comments in the script.

    +
    + +
    top
    +
    +

    Synopsis

    + +

    When acting in pass-through mode, apachectl can take +all the arguments available for the httpd +binary.

    + +

    apachectl [ httpd-argument ]

    + +

    When acting in SysV init mode, apachectl takes simple, +one-word commands, defined below.

    + +

    apachectl command

    + +
    top
    +
    +

    Options

    + +

    Only the SysV init-style options are defined here. Other arguments +are defined on the httpd manual page.

    + +
    + +
    start
    + +
    Start the Apache httpd daemon. Gives an error if it +is already running. This is equivalent to apachectl -k +start.
    + +
    stop
    + +
    Stops the Apache httpd daemon. This is equivalent to +apachectl -k stop.
    + +
    restart
    + +
    Restarts the Apache httpd daemon. If the daemon is +not running, it is started. This command automatically checks the +configuration files as in configtest before initiating +the restart to make sure the daemon doesn't die. This is equivalent +to apachectl -k restart.
    + +
    fullstatus
    + +
    Displays a full status report from mod_status. +For this to work, you need to have mod_status enabled +on your server and a text-based browser such as lynx +available on your system. The URL used to access the status report +can be set by editing the STATUSURL variable in the +script.
    + +
    status
    + +
    Displays a brief status report. Similar to the +fullstatus option, except that the list of requests +currently being served is omitted.
    + +
    graceful
    + +
    Gracefully restarts the Apache httpd daemon. If the +daemon is not running, it is started. This differs from a normal +restart in that currently open connections are not aborted. A side +effect is that old log files will not be closed immediately. This +means that if used in a log rotation script, a substantial delay may +be necessary to ensure that the old log files are closed before +processing them. This command automatically checks the configuration +files as in configtest before initiating the +restart to make sure Apache doesn't die. This is equivalent to +apachectl -k graceful.
    + +
    configtest
    + +
    Run a configuration file syntax test. It parses the configuration +files and either reports Syntax Ok +or detailed information about the particular syntax error. This is +equivalent to apachectl -t.
    + +
    + +

    The following option was available in earlier versions but has been removed.

    + +
    + +
    startssl
    + +
    To start httpd with SSL support, you should edit +your configuration file to include the relevant directives and then +use the normal apachectl start.
    + +
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/apachectl.html.ko.euc-kr b/trunk/docs/manual/programs/apachectl.html.ko.euc-kr new file mode 100644 index 0000000000..f569eea464 --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.html.ko.euc-kr @@ -0,0 +1,144 @@ + + + +apachectl - ¾ÆÆÄÄ¡ À¥¼­¹ö Á¶Àý ÀÎÅÍÆäÀ̽º - Apache HTTP Server + + + + + +
    <-
    +

    apachectl - ¾ÆÆÄÄ¡ À¥¼­¹ö Á¶Àý ÀÎÅÍÆäÀ̽º

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    apachectlÀº ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û + ÇÁ·ÎÅäÄÝ (HTTP) ¼­¹öÀÇ ¾Õ´ÜÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥Àº °ü¸®ÀÚ°¡ + ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Á¶Á¤Çϵµ·Ï + µ½´Â´Ù.

    + +

    apachectl ½ºÅ©¸³Æ®´Â µÎ°¡Áö ¹æ¹ýÀ¸·Î ½ÇÇàÇÑ´Ù. + ù¹ø° ¹æ¹ýÀº httpdÀ» ºÎ¸£´Â °£´ÜÇÑ ½ºÅ©¸³Æ® + ¿ªÇÒÀ» ÇÏ¿©, ÇÊ¿äÇÑ È¯°æº¯¼ö¸¦ ¼³Á¤ÇÏ°í ¹ÞÀº ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ + °¡Áö°í httpd¸¦ ½ÇÇàÇÑ´Ù. µÎ¹ø° ¹æ¹ýÀº + apachectl¸¦ SysV init ½ºÅ©¸³Æ®·Î »ç¿ëÇÏ¿©, + start, restart, stop + °°Àº ÇÑ´Ü¾î ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ¾Æ¼­ httpd¿¡°Ô + ÀûÀýÇÑ ½ÅÈ£¸¦ º¸³½´Ù.

    + +

    ¾ÆÆÄÄ¡¸¦ ÀϹÝÀûÀÎ °æ·Î¿¡ ¼³Ä¡ÇÏÁö ¾Ê¾Ò´Ù¸é, ÀûÀýÇÑ + httpd °æ·Î·Î apachectl ½ºÅ©¸³Æ®¸¦ + ¼öÁ¤ÇØ¾ß ÇÑ´Ù. ¶Ç, httpd ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ + Ãß°¡·Î ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ½ºÅ©¸³Æ®ÀÇ ÁÖ¼®À» + Âü°íÇ϶ó.

    + +

    apachectl ½ºÅ©¸³Æ®´Â ¼º°ø½Ã Á¾·áÄÚµå 0À», + ¿À·ù½Ã >0À» ¹ÝȯÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ½ºÅ©¸³Æ®ÀÇ ÁÖ¼®À» + Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    + +

    °£´ÜÇÑ ½ÇÇà ½ºÅ©¸³Æ®·Î µ¿ÀÛÇϸé, apachectlÀº +httpd ½ÇÇàÆÄÀÏÀÇ ¸ðµç ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ´Â´Ù.

    + +

    apachectl [ httpd-argument ]

    + +

    SysV init ¹æ½ÄÀ¸·Î µ¿ÀÛÇϸé, apachectlÀº ¾Æ·¡¼­ +¼³¸íÇÒ °£´ÜÇÑ ÇÑ´Ü¾î ¸í·É¾î¸¦ ¹Þ´Â´Ù.

    + +

    apachectl command

    + +
    top
    +
    +

    ¿É¼Ç

    + +

    ¿©±â¼­´Â SysV init-½Ä ¿É¼Ç¸¸ ¼³¸íÇÑ´Ù. ´Ù¸¥ ¿É¼ÇÀº httpd manpage¿¡¼­ ¼³¸íÇÑ´Ù.

    + +
    + +
    start
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» ½ÃÀÛÇÑ´Ù. ÀÌ¹Ì ½ÇÇàÁßÀ̶ó¸é +¿À·ù¸¦ ³½´Ù. apachectl -k start¿Í °°´Ù.
    + +
    stop
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Áß´ÜÇÑ´Ù. apachectl +-k stop°ú °°´Ù.
    + +
    restart
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Àç½ÃÀÛÇÑ´Ù. µ¥¸óÀÌ ½ÇÇàÁßÀÌ +¾Æ´Ï¶ó¸é, ½ÃÀÛÇÑ´Ù. µ¥¸óÀÌ Àç½ÃÀ۽à ½ÇÆÐÇÏÁö ¾ÊÀ½À» È®ÀÎÇϱâÀ§ÇØ +Àç½ÃÀÛ Àü¿¡ ÀÚµ¿À¸·Î configtest ¸í·É°ú °°ÀÌ ¼³Á¤ÆÄÀÏÀ» +°Ë»çÇÑ´Ù. apachectl -k restart¿Í °°´Ù.
    + +
    fullstatus
    + +
    mod_statusÀÇ ¸ðµç »óÅ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. +ÀÌ ¸í·ÉÀ» »ç¿ëÇϱâÀ§Çؼ­´Â ¼­¹ö°¡ mod_status¸¦ +»ç¿ëÇÏ°í, ½Ã½ºÅÛ¿¡ lynx °°Àº ¹®ÀÚ±â¹Ý ºê¶ó¿ìÀú°¡ +ÇÊ¿äÇÏ´Ù. »óÅ Á¤º¸¿¡ Á¢±ÙÇÏ´Â URLÀº ½ºÅ©¸³Æ®ÀÇ +STATUSURL º¯¼ö¸¦ ¼öÁ¤ÇÏ¿© ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    status
    + +
    °£´ÜÇÑ »óÅ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. fullstatus ¿É¼Ç°ú +ºñ½ÁÇÏÁö¸¸, ÇöÀç ¼­ºñ½ºÁßÀÎ ¿äû ¸ñ·ÏÀ» Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    graceful
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Á¡ÀÝ°Ô(gracefully) Àç½ÃÀÛÇÑ´Ù. +µ¥¸óÀÌ ½ÇÇàÁßÀÌ ¾Æ´Ï¶ó¸é, ½ÃÀÛÇÑ´Ù. ÀϹÝÀûÀÎ Àç½ÃÀÛ°ú ´Þ¸® ÇöÀç +¿­·ÁÀÖ´Â ¿¬°áÀ» ²÷Áö¾Ê´Â´Ù. ¶Ç, ÀÌÀü ·Î±×ÆÄÀÏÀ» Áï½Ã ´ÝÁö ¾Ê´Â´Ù. +Áï, ·Î±×¼øȯ ½ºÅ©¸³Æ®¿¡¼­ ÀÌ ¸í·ÉÀ» »ç¿ëÇÑ´Ù¸é, ÀÌÀü ·Î±×ÆÄÀÏÀ» +ó¸®ÇϱâÀü¿¡ ·Î±×ÆÄÀÏÀ» ´ÝÇûÀ½À» º¸ÀåÇϱâÀ§ÇØ »ó´çÈ÷ ±â´Ù·Á¾ß +ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ Àç½ÃÀ۽à ½ÇÆÐÇÏÁö ¾ÊÀ½À» È®ÀÎÇϱâÀ§ÇØ Àç½ÃÀÛ +Àü¿¡ ÀÚµ¿À¸·Î configtest ¸í·É°ú °°ÀÌ ¼³Á¤ÆÄÀÏÀ» +°Ë»çÇÑ´Ù. apachectl -k graceful°ú °°´Ù.
    + +
    configtest
    + +
    ¼³Á¤ÆÄÀÏÀÇ ¹®¹ýÀ» °Ë»çÇÑ´Ù. ¼³Á¤ÆÄÀÏÀ» Àаí Syntax +Ok ȤÀº ƯÁ¤ ¼³Á¤¿À·ù¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸¸¦ ¾Ë·ÁÁØ´Ù. +apachectl -t¿Í °°´Ù.
    + +
    + +

    ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ¾ÕÀ¸·Î »ç¶óÁú °ÍÀÌ´Ù.

    + +
    + +
    startssl
    + +
    apachectl -k start -DSSL°ú °°´Ù. ¿ì¸®´Â Á÷Á¢ +¾ÕÀÇ ¸í·É¾î¸¦ »ç¿ëÇϰųª Ç×»ó SSLÀ» »ç¿ëÇϵµ·Ï +httpd.conf¿¡¼­ <IfDefine> ¼½¼ÇÀ» Á¦°ÅÇÏ±æ ±ÇÇÑ´Ù.
    + +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/apachectl.xml b/trunk/docs/manual/programs/apachectl.xml new file mode 100644 index 0000000000..8307ea73e3 --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.xml @@ -0,0 +1,151 @@ + + + + + + + + +Programs + + apachectl - Apache HTTP Server Control Interface + + +

    apachectl is a front end to the Apache HyperText + Transfer Protocol (HTTP) server. It is designed to help the + administrator control the functioning of the Apache + httpd daemon.

    + +

    The apachectl script can operate in two modes. + First, it can act as a simple front-end to the httpd + command that simply sets any necessary environment variables and + then invokes httpd, passing through any command line + arguments. Second, apachectl can act as a SysV init + script, taking simple one-word arguments like start, + restart, and stop, and translating them + into appropriate signals to httpd.

    + +

    If your Apache installation uses non-standard paths, you will + need to edit the apachectl script to set the + appropriate paths to the httpd binary. You can also + specify any necessary httpd command line arguments. + See the comments in the script for details.

    + +

    The apachectl script returns a 0 exit value on + success, and >0 if an error occurs. For more details, view + the comments in the script.

    +
    +Starting Apache +Stopping Apache +Configuration Files +Platform Docs +httpd + +
    Synopsis + +

    When acting in pass-through mode, apachectl can take +all the arguments available for the httpd +binary.

    + +

    apachectl [ httpd-argument ]

    + +

    When acting in SysV init mode, apachectl takes simple, +one-word commands, defined below.

    + +

    apachectl command

    + +
    + +
    Options + +

    Only the SysV init-style options are defined here. Other arguments +are defined on the httpd manual page.

    + +
    + +
    start
    + +
    Start the Apache httpd daemon. Gives an error if it +is already running. This is equivalent to apachectl -k +start.
    + +
    stop
    + +
    Stops the Apache httpd daemon. This is equivalent to +apachectl -k stop.
    + +
    restart
    + +
    Restarts the Apache httpd daemon. If the daemon is +not running, it is started. This command automatically checks the +configuration files as in configtest before initiating +the restart to make sure the daemon doesn't die. This is equivalent +to apachectl -k restart.
    + +
    fullstatus
    + +
    Displays a full status report from mod_status. +For this to work, you need to have mod_status enabled +on your server and a text-based browser such as lynx +available on your system. The URL used to access the status report +can be set by editing the STATUSURL variable in the +script.
    + +
    status
    + +
    Displays a brief status report. Similar to the +fullstatus option, except that the list of requests +currently being served is omitted.
    + +
    graceful
    + +
    Gracefully restarts the Apache httpd daemon. If the +daemon is not running, it is started. This differs from a normal +restart in that currently open connections are not aborted. A side +effect is that old log files will not be closed immediately. This +means that if used in a log rotation script, a substantial delay may +be necessary to ensure that the old log files are closed before +processing them. This command automatically checks the configuration +files as in configtest before initiating the +restart to make sure Apache doesn't die. This is equivalent to +apachectl -k graceful.
    + +
    configtest
    + +
    Run a configuration file syntax test. It parses the configuration +files and either reports Syntax Ok +or detailed information about the particular syntax error. This is +equivalent to apachectl -t.
    + +
    + +

    The following option was available in earlier versions but has been removed.

    + +
    + +
    startssl
    + +
    To start httpd with SSL support, you should edit +your configuration file to include the relevant directives and then +use the normal apachectl start.
    + +
    + +
    + +
    diff --git a/trunk/docs/manual/programs/apachectl.xml.ko b/trunk/docs/manual/programs/apachectl.xml.ko new file mode 100644 index 0000000000..30ee0a789a --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.xml.ko @@ -0,0 +1,144 @@ + + + + + + + + +Programs + + apachectl - ¾ÆÆÄÄ¡ À¥¼­¹ö Á¶Àý ÀÎÅÍÆäÀ̽º + + +

    apachectlÀº ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û + ÇÁ·ÎÅäÄÝ (HTTP) ¼­¹öÀÇ ¾Õ´ÜÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥Àº °ü¸®ÀÚ°¡ + ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Á¶Á¤Çϵµ·Ï + µ½´Â´Ù.

    + +

    apachectl ½ºÅ©¸³Æ®´Â µÎ°¡Áö ¹æ¹ýÀ¸·Î ½ÇÇàÇÑ´Ù. + ù¹ø° ¹æ¹ýÀº httpdÀ» ºÎ¸£´Â °£´ÜÇÑ ½ºÅ©¸³Æ® + ¿ªÇÒÀ» ÇÏ¿©, ÇÊ¿äÇÑ È¯°æº¯¼ö¸¦ ¼³Á¤ÇÏ°í ¹ÞÀº ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ + °¡Áö°í httpd¸¦ ½ÇÇàÇÑ´Ù. µÎ¹ø° ¹æ¹ýÀº + apachectl¸¦ SysV init ½ºÅ©¸³Æ®·Î »ç¿ëÇÏ¿©, + start, restart, stop + °°Àº ÇÑ´Ü¾î ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ¾Æ¼­ httpd¿¡°Ô + ÀûÀýÇÑ ½ÅÈ£¸¦ º¸³½´Ù.

    + +

    ¾ÆÆÄÄ¡¸¦ ÀϹÝÀûÀÎ °æ·Î¿¡ ¼³Ä¡ÇÏÁö ¾Ê¾Ò´Ù¸é, ÀûÀýÇÑ + httpd °æ·Î·Î apachectl ½ºÅ©¸³Æ®¸¦ + ¼öÁ¤ÇØ¾ß ÇÑ´Ù. ¶Ç, httpd ¸í·ÉÇà ¾Æ±Ô¸ÕÆ®¸¦ + Ãß°¡·Î ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ½ºÅ©¸³Æ®ÀÇ ÁÖ¼®À» + Âü°íÇ϶ó.

    + +

    apachectl ½ºÅ©¸³Æ®´Â ¼º°ø½Ã Á¾·áÄÚµå 0À», + ¿À·ù½Ã >0À» ¹ÝȯÇÑ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ½ºÅ©¸³Æ®ÀÇ ÁÖ¼®À» + Âü°íÇ϶ó.

    +
    +¾ÆÆÄÄ¡ ½ÃÀÛ +¾ÆÆÄÄ¡ Áß´Ü +¼³Á¤ÆÄÀÏ +Ç÷¡Æû ¹®¼­ +httpd + +
    °³¿ä + +

    °£´ÜÇÑ ½ÇÇà ½ºÅ©¸³Æ®·Î µ¿ÀÛÇϸé, apachectlÀº +httpd ½ÇÇàÆÄÀÏÀÇ ¸ðµç ¾Æ±Ô¸ÕÆ®¸¦ ¹Þ´Â´Ù.

    + +

    apachectl [ httpd-argument ]

    + +

    SysV init ¹æ½ÄÀ¸·Î µ¿ÀÛÇϸé, apachectlÀº ¾Æ·¡¼­ +¼³¸íÇÒ °£´ÜÇÑ ÇÑ´Ü¾î ¸í·É¾î¸¦ ¹Þ´Â´Ù.

    + +

    apachectl command

    + +
    + +
    ¿É¼Ç + +

    ¿©±â¼­´Â SysV init-½Ä ¿É¼Ç¸¸ ¼³¸íÇÑ´Ù. ´Ù¸¥ ¿É¼ÇÀº httpd manpage¿¡¼­ ¼³¸íÇÑ´Ù.

    + +
    + +
    start
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» ½ÃÀÛÇÑ´Ù. ÀÌ¹Ì ½ÇÇàÁßÀ̶ó¸é +¿À·ù¸¦ ³½´Ù. apachectl -k start¿Í °°´Ù.
    + +
    stop
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Áß´ÜÇÑ´Ù. apachectl +-k stop°ú °°´Ù.
    + +
    restart
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Àç½ÃÀÛÇÑ´Ù. µ¥¸óÀÌ ½ÇÇàÁßÀÌ +¾Æ´Ï¶ó¸é, ½ÃÀÛÇÑ´Ù. µ¥¸óÀÌ Àç½ÃÀ۽à ½ÇÆÐÇÏÁö ¾ÊÀ½À» È®ÀÎÇϱâÀ§ÇØ +Àç½ÃÀÛ Àü¿¡ ÀÚµ¿À¸·Î configtest ¸í·É°ú °°ÀÌ ¼³Á¤ÆÄÀÏÀ» +°Ë»çÇÑ´Ù. apachectl -k restart¿Í °°´Ù.
    + +
    fullstatus
    + +
    mod_statusÀÇ ¸ðµç »óÅ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. +ÀÌ ¸í·ÉÀ» »ç¿ëÇϱâÀ§Çؼ­´Â ¼­¹ö°¡ mod_status¸¦ +»ç¿ëÇÏ°í, ½Ã½ºÅÛ¿¡ lynx °°Àº ¹®ÀÚ±â¹Ý ºê¶ó¿ìÀú°¡ +ÇÊ¿äÇÏ´Ù. »óÅ Á¤º¸¿¡ Á¢±ÙÇÏ´Â URLÀº ½ºÅ©¸³Æ®ÀÇ +STATUSURL º¯¼ö¸¦ ¼öÁ¤ÇÏ¿© ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    status
    + +
    °£´ÜÇÑ »óÅ Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. fullstatus ¿É¼Ç°ú +ºñ½ÁÇÏÁö¸¸, ÇöÀç ¼­ºñ½ºÁßÀÎ ¿äû ¸ñ·ÏÀ» Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    graceful
    + +
    ¾ÆÆÄÄ¡ httpd µ¥¸óÀ» Á¡ÀÝ°Ô(gracefully) Àç½ÃÀÛÇÑ´Ù. +µ¥¸óÀÌ ½ÇÇàÁßÀÌ ¾Æ´Ï¶ó¸é, ½ÃÀÛÇÑ´Ù. ÀϹÝÀûÀÎ Àç½ÃÀÛ°ú ´Þ¸® ÇöÀç +¿­·ÁÀÖ´Â ¿¬°áÀ» ²÷Áö¾Ê´Â´Ù. ¶Ç, ÀÌÀü ·Î±×ÆÄÀÏÀ» Áï½Ã ´ÝÁö ¾Ê´Â´Ù. +Áï, ·Î±×¼øȯ ½ºÅ©¸³Æ®¿¡¼­ ÀÌ ¸í·ÉÀ» »ç¿ëÇÑ´Ù¸é, ÀÌÀü ·Î±×ÆÄÀÏÀ» +ó¸®ÇϱâÀü¿¡ ·Î±×ÆÄÀÏÀ» ´ÝÇûÀ½À» º¸ÀåÇϱâÀ§ÇØ »ó´çÈ÷ ±â´Ù·Á¾ß +ÇÑ´Ù. ¾ÆÆÄÄ¡°¡ Àç½ÃÀ۽à ½ÇÆÐÇÏÁö ¾ÊÀ½À» È®ÀÎÇϱâÀ§ÇØ Àç½ÃÀÛ +Àü¿¡ ÀÚµ¿À¸·Î configtest ¸í·É°ú °°ÀÌ ¼³Á¤ÆÄÀÏÀ» +°Ë»çÇÑ´Ù. apachectl -k graceful°ú °°´Ù.
    + +
    configtest
    + +
    ¼³Á¤ÆÄÀÏÀÇ ¹®¹ýÀ» °Ë»çÇÑ´Ù. ¼³Á¤ÆÄÀÏÀ» Àаí Syntax +Ok ȤÀº ƯÁ¤ ¼³Á¤¿À·ù¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ Á¤º¸¸¦ ¾Ë·ÁÁØ´Ù. +apachectl -t¿Í °°´Ù.
    + +
    + +

    ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÒ ¼ö ÀÖÁö¸¸, ¾ÕÀ¸·Î »ç¶óÁú °ÍÀÌ´Ù.

    + +
    + +
    startssl
    + +
    apachectl -k start -DSSL°ú °°´Ù. ¿ì¸®´Â Á÷Á¢ +¾ÕÀÇ ¸í·É¾î¸¦ »ç¿ëÇϰųª Ç×»ó SSLÀ» »ç¿ëÇϵµ·Ï +httpd.conf¿¡¼­ IfDefine ¼½¼ÇÀ» Á¦°ÅÇÏ±æ ±ÇÇÑ´Ù.
    + +
    + +
    + +
    diff --git a/trunk/docs/manual/programs/apachectl.xml.meta b/trunk/docs/manual/programs/apachectl.xml.meta new file mode 100644 index 0000000000..9c3879e018 --- /dev/null +++ b/trunk/docs/manual/programs/apachectl.xml.meta @@ -0,0 +1,12 @@ + + + + apachectl + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/apxs.html b/trunk/docs/manual/programs/apxs.html new file mode 100644 index 0000000000..b6d6d1deba --- /dev/null +++ b/trunk/docs/manual/programs/apxs.html @@ -0,0 +1,7 @@ +URI: apxs.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: apxs.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/apxs.html.en b/trunk/docs/manual/programs/apxs.html.en new file mode 100644 index 0000000000..6054cac678 --- /dev/null +++ b/trunk/docs/manual/programs/apxs.html.en @@ -0,0 +1,330 @@ + + + +apxs - APache eXtenSion tool - Apache HTTP Server + + + + + +
    <-
    +

    apxs - APache eXtenSion tool

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    apxs is a tool for building and installing extension + modules for the Apache HyperText Transfer Protocol (HTTP) server. This is + achieved by building a dynamic shared object (DSO) from one or more source + or object files which then can be loaded into the Apache server + under runtime via the LoadModule + directive from mod_so.

    + +

    So to use this extension mechanism your platform has to support the DSO + feature and your Apache httpd binary has to be built with the + mod_so module. The apxs tool automatically + complains if this is not the case. You can check this yourself by manually + running the command

    + +

    + $ httpd -l +

    + +

    The module mod_so should be part of the displayed list. + If these requirements are fulfilled you can easily extend your Apache + server's functionality by installing your own modules with the DSO mechanism + by the help of this apxs tool:

    + +

    + $ apxs -i -a -c mod_foo.c
    + gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    + ld -Bshareable -o mod_foo.so mod_foo.o
    + cp mod_foo.so /path/to/apache/modules/mod_foo.so
    + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/etc/httpd.conf]
    + $ apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +

    + +

    The arguments files can be any C source file (.c), a object + file (.o) or even a library archive (.a). The apxs tool + automatically recognizes these extensions and automatically used the C + source files for compilation while just using the object and archive files + for the linking phase. But when using such pre-compiled objects make sure + they are compiled for position independent code (PIC) to be able to use them + for a dynamically loaded shared object. For instance with GCC you always + just have to use -fpic. For other C compilers consult its + manual page or at watch for the flags apxs uses to compile the + object files.

    + +

    For more details about DSO support in Apache read the documentation of + mod_so or perhaps even read the + src/modules/standard/mod_so.c source file.

    +
    + +
    top
    +
    +

    Synopsis

    +

    apxs -g + [ -S name=value ] + -n modname

    + +

    apxs -q + [ -S name=value ] + query ...

    + +

    apxs -c + [ -S name=value ] + [ -o dsofile ] + [ -I incdir ] + [ -D name=value ] + [ -L libdir ] + [ -l libname ] + [ -Wc,compiler-flags ] + [ -Wl,linker-flags ] + files ...

    + +

    apxs -i + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    + +

    apxs -e + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    +
    top
    +
    +

    Options

    +

    Common Options

    +
    +
    -n modname
    +
    This explicitly sets the module name for the -i (install) + and -g (template generation) option. Use this to explicitly + specify the module name. For option -g this is required, for + option -i the apxs tool tries to determine the + name from the source or (as a fallback) at least by guessing it from the + filename.
    +
    + + +

    Query Options

    +
    +
    -q
    +
    Performs a query for apxs's knowledge about certain + settings. The query parameters can be one or more of the + following strings: CC, CFLAGS, + CFLAGS_SHLIB, INCLUDEDIR, LD_SHLIB, + LDFLAGS_SHLIB, LIBEXECDIR, + LIBS_SHLIB, SBINDIR, SYSCONFDIR, + TARGET. + +

    Use this for manually determining settings. For instance use

    +

    + INC=-I`apxs -q INCLUDEDIR` +

    + +

    inside your own Makefiles if you need manual access to Apache's C + header files.

    +
    + + +

    Configuration Options

    +
    +
    -S name=value
    +
    This option changes the apxs settings described above.
    +
    + + +

    Template Generation Options

    +
    +
    -g
    +
    This generates a subdirectory name (see option + -n) and there two files: A sample module source file named + mod_name.c which can be used as a template for + creating your own modules or as a quick start for playing with the + apxs mechanism. And a corresponding Makefile for even easier + build and installing of this module.
    +
    + + +

    DSO Compilation Options

    +
    +
    -c
    +
    This indicates the compilation operation. It first compiles the C + source files (.c) of files into corresponding object files (.o) + and then builds a dynamically shared object in dsofile by + linking these object files plus the remaining object files (.o and .a) of + files. If no -o option is specified the output + file is guessed from the first filename in files and thus + usually defaults to mod_name.so.
    + +
    -o dsofile
    +
    Explicitly specifies the filename of the created dynamically shared + object. If not specified and the name cannot be guessed from the + files list, the fallback name mod_unknown.so is + used.
    + +
    -D name=value
    +
    This option is directly passed through to the compilation command(s). + Use this to add your own defines to the build process.
    + +
    -I incdir
    +
    This option is directly passed through to the compilation command(s). + Use this to add your own include directories to search to the build + process.
    + +
    -L libdir
    +
    This option is directly passed through to the linker command. Use this + to add your own library directories to search to the build process.
    + +
    -l libname
    +
    This option is directly passed through to the linker command. Use this + to add your own libraries to search to the build process.
    + +
    -Wc,compiler-flags
    +
    This option passes compiler-flags as additional flags to + the libtool --mode=compile command. Use this to add local + compiler-specific options.
    + +
    -Wl,linker-flags
    +
    This option passes linker-flags as additional + flags to the libtool --mode=link command. Use this + to add local linker-specific options.
    +
    + + +

    DSO Installation and Configuration Options

    + +
    +
    -i
    +
    This indicates the installation operation and installs one or more + dynamically shared objects into the server's modules + directory.
    + +
    -a
    +
    This activates the module by automatically adding a corresponding + LoadModule line to Apache's + httpd.conf configuration file, or by enabling it if it + already exists.
    + +
    -A
    +
    Same as option -a but the created LoadModule directive is prefixed with a hash + sign (#), i.e., the module is just prepared for + later activation but initially disabled.
    + +
    -e
    +
    This indicates the editing operation, which can be used with the + -a and -A options similarly to the + -i operation to edit Apache's httpd.conf + configuration file without attempting to install the module.
    +
    + +
    top
    +
    +

    Examples

    +

    Assume you have an Apache module named mod_foo.c available + which should extend Apache's server functionality. To accomplish this you + first have to compile the C source into a shared object suitable for loading + into the Apache server under runtime via the following command:

    + +

    + $ apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + $ _ +

    + +

    Then you have to update the Apache configuration by making sure a + LoadModule directive is present to + load this shared object. To simplify this step apxs provides + an automatic way to install the shared object in its "modules" directory + and updating the httpd.conf file accordingly. This can be + achieved by running:

    + +

    + $ apxs -i -a mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/conf/httpd.conf]
    + $ _ +

    + +

    This way a line named

    + +

    + LoadModule foo_module modules/mod_foo.so +

    + +

    is added to the configuration file if still not present. If you want to + have this disabled per default use the -A option, + i.e.

    + +

    + $ apxs -i -A mod_foo.c +

    + +

    For a quick test of the apxs mechanism you can create a sample Apache + module template plus a corresponding Makefile via:

    + +

    + $ apxs -g -n foo
    + Creating [DIR] foo
    + Creating [FILE] foo/Makefile
    + Creating [FILE] foo/modules.mk
    + Creating [FILE] foo/mod_foo.c
    + Creating [FILE] foo/.deps
    + $ _ +

    + +

    Then you can immediately compile this sample module into a shared object + and load it into the Apache server:

    + +

    + $ cd foo
    + $ make all reload
    + apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + apxs -i -a -n "foo" mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/conf/httpd.conf]
    + apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +

    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/apxs.html.ko.euc-kr b/trunk/docs/manual/programs/apxs.html.ko.euc-kr new file mode 100644 index 0000000000..e667e65a9f --- /dev/null +++ b/trunk/docs/manual/programs/apxs.html.ko.euc-kr @@ -0,0 +1,324 @@ + + + +apxs - APache eXtenSion µµ±¸ - Apache HTTP Server + + + + + +
    <-
    +

    apxs - APache eXtenSion µµ±¸

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    apxs´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ + (HTTP) ¼­¹öÀÇ È®Àå¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â µµ±¸ÀÌ´Ù. ÀÌ + µµ±¸´Â ¿©·¯ ¼Ò½º¿Í ¿ÀºêÁ§Æ®ÆÄÀÏÀ» °¡Áö°í, + mod_soÀÇ LoadModule Áö½Ã¾î·Î ½ÇÇàÁß¿¡ + ¾ÆÆÄÄ¡ ¼­¹ö·Î ÀоîµéÀÏ ¼ö ÀÖ´Â µ¿Àû°øÀ¯°´Ã¼(DSO)¸¦ ¸¸µç´Ù.

    + +

    ±×·¡¼­ ÀÌ·± È®Àå¹æ½ÄÀ» »ç¿ëÇÏ·Á¸é Ç÷¡ÆûÀÌ DSO ±â´ÉÀ» + Áö¿øÇÏ°í ¾ÆÆÄÄ¡ httpd ½ÇÇàÆÄÀÏÀ» + mod_so ¸ðµâ°ú °°ÀÌ ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. + apxs µµ±¸´Â ÀÌ Á¶°ÇÀÌ ¸¸Á·ÇÏÁö¾ÊÀ¸¸é ½ÇÇàÇÏÁö + ¾Ê´Â´Ù. Á÷Á¢ ¸í·É¾î¸¦ ½ÇÇàÇÏ¿© Á¶°ÇÀÌ ¸¸Á·ÇÏ´ÂÁö ¾Ë¾Æº¼ + ¼ö ÀÖ´Ù

    + +

    + $ httpd -l +

    + +

    ¸ñ·Ï¿¡ mod_so ¸ðµâÀÌ ³ª¿Í¾ß ÇÑ´Ù. Á¶°ÇÀ» + ¸¸Á·Çϸé apxs µµ±¸·Î DSO ¸ðµâÀ» ¼³Ä¡ÇÏ¿© + ¾ÆÆÄÄ¡¼­¹öÀÇ ±â´ÉÀ» ½±°Ô È®ÀåÇÒ ¼ö ÀÖ´Ù:

    + +

    + $ apxs -i -a -c mod_foo.c
    + gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    + ld -Bshareable -o mod_foo.so mod_foo.o
    + cp mod_foo.so /path/to/apache/modules/mod_foo.so
    + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/etc/httpd.conf]
    + $ apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +

    + +

    ¾Æ±Ô¸ÕÆ® files¿¡´Â C ¼Ò½ºÆÄÀÏ (.c) À̳ª + ¿ÀºêÁ§Æ®ÆÄÀÏ (.o), ¶óÀ̺귯¸®¸ðÀ½ (.a)À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + apxs µµ±¸´Â È®ÀåÀÚ¸¦ º¸°í ÀÚµ¿À¸·Î C ¼Ò½ºÆÄÀÏÀº + ÄÄÆÄÀÏÇÏ°í, ¿ÀºêÁ§Æ®¿Í ¸ðÀ½ÆÄÀÏÀº ¸µÅ©¿¡¸¸ »ç¿ëÇÑ´Ù. ±×·¯³ª + ÄÄÆÄÀÏÇÑ ¿ÀºêÁ§Æ®¸¦ »ç¿ëÇÏ·Á¸é µ¿ÀûÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Â + °øÀ¯°´Ã¼·Î »ç¿ëÇϱâÀ§ÇØ ¹Ýµå½Ã ¿ÀºêÁ§Æ®¸¦ À§Ä¡µ¶¸³ÄÚµå(PIC, + position independent code)·Î ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. GCCÀÇ °æ¿ì + -fpicÀ» »ç¿ëÇÏ¸é µÈ´Ù. ´Ù¸¥ C ÄÄÆÄÀÏ·¯´Â ¼³¸í¼­¸¦ + Âü°íÇϰųª apxs°¡ ¿ÀºêÁ§Æ®ÆÄÀÏÀ» ÄÄÆÄÀÏÇÒ¶§ + »ç¿ëÇÏ´Â ¿É¼ÇÀ» Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ÀÇ DSO Áö¿ø¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº + mod_so ¹®¼­¸¦ Âü°íÇϰųª + src/modules/standard/mod_so.c ¼Ò½ºÆÄÀÏÀ» ÀоîºÁ¶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    apxs -g + [ -S name=value ] + -n modname

    + +

    apxs -q + [ -S name=value ] + query ...

    + +

    apxs -c + [ -S name=value ] + [ -o dsofile ] + [ -I incdir ] + [ -D name=value ] + [ -L libdir ] + [ -l libname ] + [ -Wc,compiler-flags ] + [ -Wl,linker-flags ] + files ...

    + +

    apxs -i + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    + +

    apxs -e + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    +
    top
    +
    +

    ¿É¼Ç

    +

    °øÅë ¿É¼Ç

    +
    +
    -n modname
    +
    -i (install)°ú -g (template + generation) ¿É¼ÇÀ» »ç¿ëÇÒ¶§ Á÷Á¢ ¸ðµâ¸íÀ» ÁöÁ¤ÇÑ´Ù. ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¸ðµâ¸íÀ» Á÷Á¢ ÁöÁ¤ÇÑ´Ù. -g + ¿É¼ÇÀ» »ç¿ëÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» ¹Ýµå½Ã »ç¿ëÇؾßÇÏ°í, + -i ¿É¼ÇÀ» »ç¿ëÇÑ´Ù¸é apxs µµ±¸´Â + ¼Ò½º³ª (¸¶Áö¸· ½Ãµµ·Î) ÆÄÀϸíÀ» °¡Áö°í À̸§À» ÃßÃøÇÑ´Ù.
    +
    + + +

    ÁúÀÇ ¿É¼Ç

    +
    +
    -q
    +
    apxsÀÇ ¼³Á¤°ªÀ» ¾Ë¾Æ³½´Ù. query¿¡´Â + ´ÙÀ½À» »ç¿ëÇÒ ¼ö ÀÖ´Ù: CC, CFLAGS, + CFLAGS_SHLIB, INCLUDEDIR, + LD_SHLIB, LDFLAGS_SHLIB, + LIBEXECDIR, LIBS_SHLIB, + SBINDIR, SYSCONFDIR, TARGET. + +

    ¼³Á¤À» Á÷Á¢ ¾Ë¾Æ³¾¶§ »ç¿ëÇÑ´Ù.

    +

    + INC=-I`apxs -q INCLUDEDIR` +

    + +

    ¿¹¸¦ µé¾î, ¾ÆÆÄÄ¡ C Çì´õÆÄÀÏÀ» Á÷Á¢ Á¢±ÙÇÑ´Ù¸é + Makefile¿¡¼­ À§¿Í °°ÀÌ »ç¿ëÇÑ´Ù.

    +
    + + +

    ¼³Á¤ ¿É¼Ç

    +
    +
    -S name=value
    +
    ÀÌ ¿É¼ÇÀº À§¿¡¼­ ¼³¸íÇÑ apxs ¼³Á¤À» º¯°æÇÑ´Ù.
    +
    + + +

    °ßº»(template) »ý¼º ¿É¼Ç

    +
    +
    -g
    +
    ÇÏÀ§µð·ºÅ丮 nameÀ» ¸¸µé°í (-n + ¿É¼Ç Âü°í) ±×°÷¿¡ ÆÄÀÏ µÎ°³¸¦ ¸¸µç´Ù: ÇÑ ÆÄÀÏÀº + mod_name.c¶ó´Â °ßº» ¸ðµâ¼Ò½ºÆÄÀÏ·Î, + ÀÚ½ÅÀÇ ¸ðµâÀ» ¸¸µé¶§ °ßº»À¸·Î »ç¿ëÇϰųª apxs ±â´ÉÀ» + ½ÃÇèÇغ¼¶§ »ç¿ëÇÑ´Ù. ´Ù¸¥ ÆÄÀÏÀº ÀÌ ¸ðµâÀ» ½±°Ô ÄÄÆÄÀÏÇÏ°í + ¼³Ä¡ÇϱâÀ§ÇÑ MakefileÀÌ´Ù.
    +
    + + +

    DSO ÄÄÆÄÀÏ ¿É¼Ç

    +
    +
    -c
    +
    ÄÄÆÄÀÏÀ» Áö½ÃÇÑ´Ù. ¸ÕÀú files¿¡¼­ C + ¼Ò½ºÆÄÀϵé(.c)À» ¿ÀºêÁ§Æ®ÆÄÀÏ(.o)·Î ÄÄÆÄÀÏÇÏ°í, + filesÀÇ ³ª¸ÓÁö ¿ÀºêÁ§Æ®ÆÄÀϵé(.o°ú .a)°ú + ¸µÅ©ÇÏ¿© µ¿Àû°øÀ¯°´Ã¼ dsofileÀ» ¸¸µç´Ù. + -o ¿É¼ÇÀ» »ç¿ëÇÏÁö¾ÊÀ¸¸é filesÀÇ + ù¹ø° ÆÄÀÏ¸í¿¡¼­ À̸§À» ÃßÃøÇÏ¿© º¸Åë + mod_name.so¸¦ »ç¿ëÇÑ´Ù.
    + +
    -o dsofile
    +
    »ý¼ºÇÒ µ¿Àû°øÀ¯°´Ã¼ ÆÄÀϸíÀ» Á÷Á¢ ÁöÁ¤ÇÑ´Ù. À̸§À» + ÁöÁ¤ÇÏÁö¾Ê°í files ¸ñ·Ï¿¡¼­ À̸§À» ÃßÃøÇÏÁö + ¸øÇÏ¸é ¸¶Áö¸·À¸·Î mod_unknown.so¸¦ À̸§À¸·Î + »ç¿ëÇÑ´Ù.
    + +
    -D name=value
    +
    ÀÌ ¿É¼ÇÀ» ÄÄÆÄÀÏ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ ÀÚ½ÅÀÇ defineÀ» Ãß°¡ÇÑ´Ù.
    + +
    -I incdir
    +
    ÀÌ ¿É¼ÇÀ» ÄÄÆÄÀÏ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ include¸¦ ãÀ» µð·ºÅ丮¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -L libdir
    +
    ÀÌ ¿É¼ÇÀ» ¸µÄ¿ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ ¶óÀ̺귯¸®¸¦ ãÀ» µð·ºÅ丮¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -l libname
    +
    ÀÌ ¿É¼ÇÀ» ¸µÄ¿ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ »ç¿ëÇÒ ¶óÀ̺귯¸®¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -Wc,compiler-flags
    +
    ÀÌ ¿É¼ÇÀº Ãß°¡ ¿É¼Ç compiler-flags¸¦ + libtool --mode=compile ¸í·É¾î·Î Àü´ÞÇÑ´Ù. + ÄÄÆÄÀÏ·¯ ƯÀ¯ÀÇ ¿É¼ÇÀ» Ãß°¡ÇÒ¶§ »ç¿ëÇÑ´Ù.
    + +
    -Wl,linker-flags
    +
    ÀÌ ¿É¼ÇÀº Ãß°¡ ¿É¼Ç linker-flags¸¦ + libtool --mode=link ¸í·É¾î·Î Àü´ÞÇÑ´Ù. ¸µÄ¿ + ƯÀ¯ÀÇ ¿É¼ÇÀ» Ãß°¡ÇÒ¶§ »ç¿ëÇÑ´Ù.
    +
    + + +

    DSO ¼³Ä¡°ú ¼³Á¤ ¿É¼Ç

    + +
    +
    -i
    +
    ¼³Ä¡¸¦ Áö½ÃÇÑ´Ù. ¿©·¯ µ¿Àû°øÀ¯°´Ã¼¸¦ ¼­¹öÀÇ + modules µð·ºÅ丮¿¡ ¼³Ä¡ÇÑ´Ù.
    + +
    -a
    +
    ¾ÆÆÄÄ¡ httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ÀûÀýÇÑ + LoadModule ÁÙÀ» + Ãß°¡Çϰųª ÀÌ¹Ì ÀÖ´Ù¸é È°¼ºÈ­ÇÏ¿© ¸ðµâÀ» »ç¿ëÇϵµ·Ï + ¸¸µç´Ù.
    + +
    -A
    +
    -a¿Í ºñ½ÁÇÏÁö¸¸, LoadModule Áö½Ã¾î ¾Õ¿¡ + ¿ì¹°Á¤ÀÚ(#)¸¦ ºÙÀδÙ. Áï, ÇöÀç´Â + »ç¿ëÇÏÁö¾ÊÁö¸¸ ³ªÁß¿¡ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ¸ðµâÀ» ÁغñÇÑ´Ù.
    + +
    -e
    +
    ÆíÁýÀ» Áö½ÃÇÑ´Ù. -a ȤÀº -A + ¿É¼Ç°ú °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, -i ¸í·É°ú + ºñ½ÁÇÏÁö¸¸ ¸ðµâÀ» ¼³Ä¡ÇÏÁö¾Ê°í ¾ÆÆÄÄ¡ + httpd.conf ¼³Á¤ÆÄÀϸ¸ ÆíÁýÇÑ´Ù.
    +
    + +
    top
    +
    +

    ¿¹Á¦

    +

    ¾ÆÆÄÄ¡¼­¹öÀÇ ±â´ÉÀ» È®ÀåÇÏ´Â mod_foo.c¶ó´Â + ¾ÆÆÄÄ¡ ¸ðµâÀÌ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. ¸ÕÀú ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© + C ¼Ò½º¸¦ ¾ÆÆÄÄ¡ ¼­¹ö°¡ ÀоîµéÀÏ °øÀ¯°´Ã¼·Î ÄÄÆÄÀÏÇÑ´Ù:

    + +

    + $ apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + $ _ +

    + +

    ±×¸®°í ÀÌ °øÀ¯°´Ã¼¸¦ ÀоîµéÀÌ´Â LoadModule Áö½Ã¾î¸¦ ¾ÆÆÄÄ¡ + ¼³Á¤¿¡ Ãß°¡ÇÑ´Ù. apxs´Â ÀÚµ¿À¸·Î °øÀ¯°´Ã¼¸¦ + "modules" µð·ºÅ丮¿¡ ¼³Ä¡ÇÏ°í httpd.conf ÆÄÀÏÀ» + ¾Ë¸Â°Ô ¼öÁ¤ÇÏ¿© °£´ÜÈ÷ ÀÛ¾÷À» ¸¶Ä£´Ù. ´ÙÀ½ °°ÀÌ ½ÇÇàÇÑ´Ù:

    + +

    + $ apxs -i -a mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [/path/to/apache/conf/httpd.conf¿¡¼­ `foo' ¸ðµâÀ» È°¼ºÈ­ÇÑ´Ù]
    + $ _ +

    + +

    ±×·¯¸é ´ÙÀ½°ú °°Àº ÁÙÀ»

    + +

    + LoadModule foo_module modules/mod_foo.so +

    + +

    ¼³Á¤ÆÄÀÏ¿¡ ¾ø´Ù¸é Ãß°¡ÇÑ´Ù. ÀÌ ¼³Á¤À» ±âº»ÀûÀ¸·Î »ç¿ëÇÏÁö + ¾Ê´Â´Ù¸é -A ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. Áï

    + +

    + $ apxs -i -A mod_foo.c +

    + +

    apxs¸¦ ½±°Ô »ç¿ëÇÏ·Á°í ´ÙÀ½°ú °°ÀÌ ¾ÆÆÄÄ¡ ¸ðµâ °ßº»°ú + MakefileÀ» ¸¸µé ¼ö ÀÖ´Ù:

    + +

    + $ apxs -g -n foo
    + Creating [DIR] foo
    + Creating [FILE] foo/Makefile
    + Creating [FILE] foo/modules.mk
    + Creating [FILE] foo/mod_foo.c
    + Creating [FILE] foo/.deps
    + $ _ +

    + +

    ±×·±ÈÄ ¹Ù·Î °ßº» ¸ðµâÀ» °øÀ¯°´Ã¼·Î ÄÄÆÄÀÏÇÏ¿© ¾ÆÆÄÄ¡ + ¼­¹ö°¡ Àеµ·ÏÇÑ´Ù:

    + +

    + $ cd foo
    + $ make all reload
    + apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + apxs -i -a -n "foo" mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [/path/to/apache/conf/httpd.conf¿¡¼­ `foo' ¸ðµâÀ» È°¼ºÈ­ÇÑ´Ù]
    + apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/apxs.xml b/trunk/docs/manual/programs/apxs.xml new file mode 100644 index 0000000000..ba0e36afe5 --- /dev/null +++ b/trunk/docs/manual/programs/apxs.xml @@ -0,0 +1,326 @@ + + + + + + + + +Programs + +apxs - APache eXtenSion tool + + +

    apxs is a tool for building and installing extension + modules for the Apache HyperText Transfer Protocol (HTTP) server. This is + achieved by building a dynamic shared object (DSO) from one or more source + or object files which then can be loaded into the Apache server + under runtime via the LoadModule + directive from mod_so.

    + +

    So to use this extension mechanism your platform has to support the DSO + feature and your Apache httpd binary has to be built with the + mod_so module. The apxs tool automatically + complains if this is not the case. You can check this yourself by manually + running the command

    + + + $ httpd -l + + +

    The module mod_so should be part of the displayed list. + If these requirements are fulfilled you can easily extend your Apache + server's functionality by installing your own modules with the DSO mechanism + by the help of this apxs tool:

    + + + $ apxs -i -a -c mod_foo.c
    + gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    + ld -Bshareable -o mod_foo.so mod_foo.o
    + cp mod_foo.so /path/to/apache/modules/mod_foo.so
    + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/etc/httpd.conf]
    + $ apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +
    + +

    The arguments files can be any C source file (.c), a object + file (.o) or even a library archive (.a). The apxs tool + automatically recognizes these extensions and automatically used the C + source files for compilation while just using the object and archive files + for the linking phase. But when using such pre-compiled objects make sure + they are compiled for position independent code (PIC) to be able to use them + for a dynamically loaded shared object. For instance with GCC you always + just have to use -fpic. For other C compilers consult its + manual page or at watch for the flags apxs uses to compile the + object files.

    + +

    For more details about DSO support in Apache read the documentation of + mod_so or perhaps even read the + src/modules/standard/mod_so.c source file.

    +
    +apachectl +httpd + +
    Synopsis +

    apxs -g + [ -S name=value ] + -n modname

    + +

    apxs -q + [ -S name=value ] + query ...

    + +

    apxs -c + [ -S name=value ] + [ -o dsofile ] + [ -I incdir ] + [ -D name=value ] + [ -L libdir ] + [ -l libname ] + [ -Wc,compiler-flags ] + [ -Wl,linker-flags ] + files ...

    + +

    apxs -i + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    + +

    apxs -e + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    +
    + +
    Options +
    Common Options +
    +
    -n modname
    +
    This explicitly sets the module name for the -i (install) + and -g (template generation) option. Use this to explicitly + specify the module name. For option -g this is required, for + option -i the apxs tool tries to determine the + name from the source or (as a fallback) at least by guessing it from the + filename.
    +
    +
    + +
    Query Options +
    +
    -q
    +
    Performs a query for apxs's knowledge about certain + settings. The query parameters can be one or more of the + following strings: CC, CFLAGS, + CFLAGS_SHLIB, INCLUDEDIR, LD_SHLIB, + LDFLAGS_SHLIB, LIBEXECDIR, + LIBS_SHLIB, SBINDIR, SYSCONFDIR, + TARGET. + +

    Use this for manually determining settings. For instance use

    + + INC=-I`apxs -q INCLUDEDIR` + + +

    inside your own Makefiles if you need manual access to Apache's C + header files.

    +
    +
    + +
    Configuration Options +
    +
    -S name=value
    +
    This option changes the apxs settings described above.
    +
    +
    + +
    Template Generation Options +
    +
    -g
    +
    This generates a subdirectory name (see option + -n) and there two files: A sample module source file named + mod_name.c which can be used as a template for + creating your own modules or as a quick start for playing with the + apxs mechanism. And a corresponding Makefile for even easier + build and installing of this module.
    +
    +
    + +
    DSO Compilation Options +
    +
    -c
    +
    This indicates the compilation operation. It first compiles the C + source files (.c) of files into corresponding object files (.o) + and then builds a dynamically shared object in dsofile by + linking these object files plus the remaining object files (.o and .a) of + files. If no -o option is specified the output + file is guessed from the first filename in files and thus + usually defaults to mod_name.so.
    + +
    -o dsofile
    +
    Explicitly specifies the filename of the created dynamically shared + object. If not specified and the name cannot be guessed from the + files list, the fallback name mod_unknown.so is + used.
    + +
    -D name=value
    +
    This option is directly passed through to the compilation command(s). + Use this to add your own defines to the build process.
    + +
    -I incdir
    +
    This option is directly passed through to the compilation command(s). + Use this to add your own include directories to search to the build + process.
    + +
    -L libdir
    +
    This option is directly passed through to the linker command. Use this + to add your own library directories to search to the build process.
    + +
    -l libname
    +
    This option is directly passed through to the linker command. Use this + to add your own libraries to search to the build process.
    + +
    -Wc,compiler-flags
    +
    This option passes compiler-flags as additional flags to + the libtool --mode=compile command. Use this to add local + compiler-specific options.
    + +
    -Wl,linker-flags
    +
    This option passes linker-flags as additional + flags to the libtool --mode=link command. Use this + to add local linker-specific options.
    +
    +
    + +
    + DSO Installation and Configuration Options +
    +
    -i
    +
    This indicates the installation operation and installs one or more + dynamically shared objects into the server's modules + directory.
    + +
    -a
    +
    This activates the module by automatically adding a corresponding + LoadModule line to Apache's + httpd.conf configuration file, or by enabling it if it + already exists.
    + +
    -A
    +
    Same as option -a but the created LoadModule directive is prefixed with a hash + sign (#), i.e., the module is just prepared for + later activation but initially disabled.
    + +
    -e
    +
    This indicates the editing operation, which can be used with the + -a and -A options similarly to the + -i operation to edit Apache's httpd.conf + configuration file without attempting to install the module.
    +
    +
    +
    + +
    Examples +

    Assume you have an Apache module named mod_foo.c available + which should extend Apache's server functionality. To accomplish this you + first have to compile the C source into a shared object suitable for loading + into the Apache server under runtime via the following command:

    + + + $ apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + $ _ +
    + +

    Then you have to update the Apache configuration by making sure a + LoadModule directive is present to + load this shared object. To simplify this step apxs provides + an automatic way to install the shared object in its "modules" directory + and updating the httpd.conf file accordingly. This can be + achieved by running:

    + + + $ apxs -i -a mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/conf/httpd.conf]
    + $ _ +
    + +

    This way a line named

    + + + LoadModule foo_module modules/mod_foo.so + + +

    is added to the configuration file if still not present. If you want to + have this disabled per default use the -A option, + i.e.

    + + + $ apxs -i -A mod_foo.c + + +

    For a quick test of the apxs mechanism you can create a sample Apache + module template plus a corresponding Makefile via:

    + + + $ apxs -g -n foo
    + Creating [DIR] foo
    + Creating [FILE] foo/Makefile
    + Creating [FILE] foo/modules.mk
    + Creating [FILE] foo/mod_foo.c
    + Creating [FILE] foo/.deps
    + $ _ +
    + +

    Then you can immediately compile this sample module into a shared object + and load it into the Apache server:

    + + + $ cd foo
    + $ make all reload
    + apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + apxs -i -a -n "foo" mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/conf/httpd.conf]
    + apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +
    + +
    +
    diff --git a/trunk/docs/manual/programs/apxs.xml.ko b/trunk/docs/manual/programs/apxs.xml.ko new file mode 100644 index 0000000000..a479d90e66 --- /dev/null +++ b/trunk/docs/manual/programs/apxs.xml.ko @@ -0,0 +1,320 @@ + + + + + + + + +Programs + +apxs - APache eXtenSion µµ±¸ + + +

    apxs´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ + (HTTP) ¼­¹öÀÇ È®Àå¸ðµâÀ» ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇÏ´Â µµ±¸ÀÌ´Ù. ÀÌ + µµ±¸´Â ¿©·¯ ¼Ò½º¿Í ¿ÀºêÁ§Æ®ÆÄÀÏÀ» °¡Áö°í, + mod_soÀÇ LoadModule Áö½Ã¾î·Î ½ÇÇàÁß¿¡ + ¾ÆÆÄÄ¡ ¼­¹ö·Î ÀоîµéÀÏ ¼ö ÀÖ´Â µ¿Àû°øÀ¯°´Ã¼(DSO)¸¦ ¸¸µç´Ù.

    + +

    ±×·¡¼­ ÀÌ·± È®Àå¹æ½ÄÀ» »ç¿ëÇÏ·Á¸é Ç÷¡ÆûÀÌ DSO ±â´ÉÀ» + Áö¿øÇÏ°í ¾ÆÆÄÄ¡ httpd ½ÇÇàÆÄÀÏÀ» + mod_so ¸ðµâ°ú °°ÀÌ ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. + apxs µµ±¸´Â ÀÌ Á¶°ÇÀÌ ¸¸Á·ÇÏÁö¾ÊÀ¸¸é ½ÇÇàÇÏÁö + ¾Ê´Â´Ù. Á÷Á¢ ¸í·É¾î¸¦ ½ÇÇàÇÏ¿© Á¶°ÇÀÌ ¸¸Á·ÇÏ´ÂÁö ¾Ë¾Æº¼ + ¼ö ÀÖ´Ù

    + + + $ httpd -l + + +

    ¸ñ·Ï¿¡ mod_so ¸ðµâÀÌ ³ª¿Í¾ß ÇÑ´Ù. Á¶°ÇÀ» + ¸¸Á·Çϸé apxs µµ±¸·Î DSO ¸ðµâÀ» ¼³Ä¡ÇÏ¿© + ¾ÆÆÄÄ¡¼­¹öÀÇ ±â´ÉÀ» ½±°Ô È®ÀåÇÒ ¼ö ÀÖ´Ù:

    + + + $ apxs -i -a -c mod_foo.c
    + gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    + ld -Bshareable -o mod_foo.so mod_foo.o
    + cp mod_foo.so /path/to/apache/modules/mod_foo.so
    + chmod 755 /path/to/apache/modules/mod_foo.so
    + [activating module `foo' in /path/to/apache/etc/httpd.conf]
    + $ apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +
    + +

    ¾Æ±Ô¸ÕÆ® files¿¡´Â C ¼Ò½ºÆÄÀÏ (.c) À̳ª + ¿ÀºêÁ§Æ®ÆÄÀÏ (.o), ¶óÀ̺귯¸®¸ðÀ½ (.a)À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + apxs µµ±¸´Â È®ÀåÀÚ¸¦ º¸°í ÀÚµ¿À¸·Î C ¼Ò½ºÆÄÀÏÀº + ÄÄÆÄÀÏÇÏ°í, ¿ÀºêÁ§Æ®¿Í ¸ðÀ½ÆÄÀÏÀº ¸µÅ©¿¡¸¸ »ç¿ëÇÑ´Ù. ±×·¯³ª + ÄÄÆÄÀÏÇÑ ¿ÀºêÁ§Æ®¸¦ »ç¿ëÇÏ·Á¸é µ¿ÀûÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Â + °øÀ¯°´Ã¼·Î »ç¿ëÇϱâÀ§ÇØ ¹Ýµå½Ã ¿ÀºêÁ§Æ®¸¦ À§Ä¡µ¶¸³ÄÚµå(PIC, + position independent code)·Î ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù. GCCÀÇ °æ¿ì + -fpicÀ» »ç¿ëÇÏ¸é µÈ´Ù. ´Ù¸¥ C ÄÄÆÄÀÏ·¯´Â ¼³¸í¼­¸¦ + Âü°íÇϰųª apxs°¡ ¿ÀºêÁ§Æ®ÆÄÀÏÀ» ÄÄÆÄÀÏÇÒ¶§ + »ç¿ëÇÏ´Â ¿É¼ÇÀ» Âü°íÇ϶ó.

    + +

    ¾ÆÆÄÄ¡ÀÇ DSO Áö¿ø¿¡ ´ëÇÑ ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº + mod_so ¹®¼­¸¦ Âü°íÇϰųª + src/modules/standard/mod_so.c ¼Ò½ºÆÄÀÏÀ» ÀоîºÁ¶ó.

    +
    +apachectl +httpd + +
    °³¿ä +

    apxs -g + [ -S name=value ] + -n modname

    + +

    apxs -q + [ -S name=value ] + query ...

    + +

    apxs -c + [ -S name=value ] + [ -o dsofile ] + [ -I incdir ] + [ -D name=value ] + [ -L libdir ] + [ -l libname ] + [ -Wc,compiler-flags ] + [ -Wl,linker-flags ] + files ...

    + +

    apxs -i + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    + +

    apxs -e + [ -S name=value ] + [ -n modname ] + [ -a ] + [ -A ] + dso-file ...

    +
    + +
    ¿É¼Ç +
    °øÅë ¿É¼Ç +
    +
    -n modname
    +
    -i (install)°ú -g (template + generation) ¿É¼ÇÀ» »ç¿ëÇÒ¶§ Á÷Á¢ ¸ðµâ¸íÀ» ÁöÁ¤ÇÑ´Ù. ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¸ðµâ¸íÀ» Á÷Á¢ ÁöÁ¤ÇÑ´Ù. -g + ¿É¼ÇÀ» »ç¿ëÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» ¹Ýµå½Ã »ç¿ëÇؾßÇÏ°í, + -i ¿É¼ÇÀ» »ç¿ëÇÑ´Ù¸é apxs µµ±¸´Â + ¼Ò½º³ª (¸¶Áö¸· ½Ãµµ·Î) ÆÄÀϸíÀ» °¡Áö°í À̸§À» ÃßÃøÇÑ´Ù.
    +
    +
    + +
    ÁúÀÇ ¿É¼Ç +
    +
    -q
    +
    apxsÀÇ ¼³Á¤°ªÀ» ¾Ë¾Æ³½´Ù. query¿¡´Â + ´ÙÀ½À» »ç¿ëÇÒ ¼ö ÀÖ´Ù: CC, CFLAGS, + CFLAGS_SHLIB, INCLUDEDIR, + LD_SHLIB, LDFLAGS_SHLIB, + LIBEXECDIR, LIBS_SHLIB, + SBINDIR, SYSCONFDIR, TARGET. + +

    ¼³Á¤À» Á÷Á¢ ¾Ë¾Æ³¾¶§ »ç¿ëÇÑ´Ù.

    + + INC=-I`apxs -q INCLUDEDIR` + + +

    ¿¹¸¦ µé¾î, ¾ÆÆÄÄ¡ C Çì´õÆÄÀÏÀ» Á÷Á¢ Á¢±ÙÇÑ´Ù¸é + Makefile¿¡¼­ À§¿Í °°ÀÌ »ç¿ëÇÑ´Ù.

    +
    +
    + +
    ¼³Á¤ ¿É¼Ç +
    +
    -S name=value
    +
    ÀÌ ¿É¼ÇÀº À§¿¡¼­ ¼³¸íÇÑ apxs ¼³Á¤À» º¯°æÇÑ´Ù.
    +
    +
    + +
    °ßº»(template) »ý¼º ¿É¼Ç +
    +
    -g
    +
    ÇÏÀ§µð·ºÅ丮 nameÀ» ¸¸µé°í (-n + ¿É¼Ç Âü°í) ±×°÷¿¡ ÆÄÀÏ µÎ°³¸¦ ¸¸µç´Ù: ÇÑ ÆÄÀÏÀº + mod_name.c¶ó´Â °ßº» ¸ðµâ¼Ò½ºÆÄÀÏ·Î, + ÀÚ½ÅÀÇ ¸ðµâÀ» ¸¸µé¶§ °ßº»À¸·Î »ç¿ëÇϰųª apxs ±â´ÉÀ» + ½ÃÇèÇغ¼¶§ »ç¿ëÇÑ´Ù. ´Ù¸¥ ÆÄÀÏÀº ÀÌ ¸ðµâÀ» ½±°Ô ÄÄÆÄÀÏÇÏ°í + ¼³Ä¡ÇϱâÀ§ÇÑ MakefileÀÌ´Ù.
    +
    +
    + +
    DSO ÄÄÆÄÀÏ ¿É¼Ç +
    +
    -c
    +
    ÄÄÆÄÀÏÀ» Áö½ÃÇÑ´Ù. ¸ÕÀú files¿¡¼­ C + ¼Ò½ºÆÄÀϵé(.c)À» ¿ÀºêÁ§Æ®ÆÄÀÏ(.o)·Î ÄÄÆÄÀÏÇÏ°í, + filesÀÇ ³ª¸ÓÁö ¿ÀºêÁ§Æ®ÆÄÀϵé(.o°ú .a)°ú + ¸µÅ©ÇÏ¿© µ¿Àû°øÀ¯°´Ã¼ dsofileÀ» ¸¸µç´Ù. + -o ¿É¼ÇÀ» »ç¿ëÇÏÁö¾ÊÀ¸¸é filesÀÇ + ù¹ø° ÆÄÀÏ¸í¿¡¼­ À̸§À» ÃßÃøÇÏ¿© º¸Åë + mod_name.so¸¦ »ç¿ëÇÑ´Ù.
    + +
    -o dsofile
    +
    »ý¼ºÇÒ µ¿Àû°øÀ¯°´Ã¼ ÆÄÀϸíÀ» Á÷Á¢ ÁöÁ¤ÇÑ´Ù. À̸§À» + ÁöÁ¤ÇÏÁö¾Ê°í files ¸ñ·Ï¿¡¼­ À̸§À» ÃßÃøÇÏÁö + ¸øÇÏ¸é ¸¶Áö¸·À¸·Î mod_unknown.so¸¦ À̸§À¸·Î + »ç¿ëÇÑ´Ù.
    + +
    -D name=value
    +
    ÀÌ ¿É¼ÇÀ» ÄÄÆÄÀÏ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ ÀÚ½ÅÀÇ defineÀ» Ãß°¡ÇÑ´Ù.
    + +
    -I incdir
    +
    ÀÌ ¿É¼ÇÀ» ÄÄÆÄÀÏ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ include¸¦ ãÀ» µð·ºÅ丮¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -L libdir
    +
    ÀÌ ¿É¼ÇÀ» ¸µÄ¿ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ ¶óÀ̺귯¸®¸¦ ãÀ» µð·ºÅ丮¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -l libname
    +
    ÀÌ ¿É¼ÇÀ» ¸µÄ¿ ¸í·É¾î·Î Á÷Á¢ Àü´ÞÇÑ´Ù. + ÄÄÆÄÀ϶§ »ç¿ëÇÒ ¶óÀ̺귯¸®¸¦ Ãß°¡ÇÑ´Ù.
    + +
    -Wc,compiler-flags
    +
    ÀÌ ¿É¼ÇÀº Ãß°¡ ¿É¼Ç compiler-flags¸¦ + libtool --mode=compile ¸í·É¾î·Î Àü´ÞÇÑ´Ù. + ÄÄÆÄÀÏ·¯ ƯÀ¯ÀÇ ¿É¼ÇÀ» Ãß°¡ÇÒ¶§ »ç¿ëÇÑ´Ù.
    + +
    -Wl,linker-flags
    +
    ÀÌ ¿É¼ÇÀº Ãß°¡ ¿É¼Ç linker-flags¸¦ + libtool --mode=link ¸í·É¾î·Î Àü´ÞÇÑ´Ù. ¸µÄ¿ + ƯÀ¯ÀÇ ¿É¼ÇÀ» Ãß°¡ÇÒ¶§ »ç¿ëÇÑ´Ù.
    +
    +
    + +
    + DSO ¼³Ä¡°ú ¼³Á¤ ¿É¼Ç +
    +
    -i
    +
    ¼³Ä¡¸¦ Áö½ÃÇÑ´Ù. ¿©·¯ µ¿Àû°øÀ¯°´Ã¼¸¦ ¼­¹öÀÇ + modules µð·ºÅ丮¿¡ ¼³Ä¡ÇÑ´Ù.
    + +
    -a
    +
    ¾ÆÆÄÄ¡ httpd.conf ¼³Á¤ÆÄÀÏ¿¡ ÀûÀýÇÑ + LoadModule ÁÙÀ» + Ãß°¡Çϰųª ÀÌ¹Ì ÀÖ´Ù¸é È°¼ºÈ­ÇÏ¿© ¸ðµâÀ» »ç¿ëÇϵµ·Ï + ¸¸µç´Ù.
    + +
    -A
    +
    -a¿Í ºñ½ÁÇÏÁö¸¸, LoadModule Áö½Ã¾î ¾Õ¿¡ + ¿ì¹°Á¤ÀÚ(#)¸¦ ºÙÀδÙ. Áï, ÇöÀç´Â + »ç¿ëÇÏÁö¾ÊÁö¸¸ ³ªÁß¿¡ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ¸ðµâÀ» ÁغñÇÑ´Ù.
    + +
    -e
    +
    ÆíÁýÀ» Áö½ÃÇÑ´Ù. -a ȤÀº -A + ¿É¼Ç°ú °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, -i ¸í·É°ú + ºñ½ÁÇÏÁö¸¸ ¸ðµâÀ» ¼³Ä¡ÇÏÁö¾Ê°í ¾ÆÆÄÄ¡ + httpd.conf ¼³Á¤ÆÄÀϸ¸ ÆíÁýÇÑ´Ù.
    +
    +
    +
    + +
    ¿¹Á¦ +

    ¾ÆÆÄÄ¡¼­¹öÀÇ ±â´ÉÀ» È®ÀåÇÏ´Â mod_foo.c¶ó´Â + ¾ÆÆÄÄ¡ ¸ðµâÀÌ ÀÖ´Ù°í °¡Á¤ÇÏÀÚ. ¸ÕÀú ´ÙÀ½ ¸í·É¾î¸¦ »ç¿ëÇÏ¿© + C ¼Ò½º¸¦ ¾ÆÆÄÄ¡ ¼­¹ö°¡ ÀоîµéÀÏ °øÀ¯°´Ã¼·Î ÄÄÆÄÀÏÇÑ´Ù:

    + + + $ apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + $ _ +
    + +

    ±×¸®°í ÀÌ °øÀ¯°´Ã¼¸¦ ÀоîµéÀÌ´Â LoadModule Áö½Ã¾î¸¦ ¾ÆÆÄÄ¡ + ¼³Á¤¿¡ Ãß°¡ÇÑ´Ù. apxs´Â ÀÚµ¿À¸·Î °øÀ¯°´Ã¼¸¦ + "modules" µð·ºÅ丮¿¡ ¼³Ä¡ÇÏ°í httpd.conf ÆÄÀÏÀ» + ¾Ë¸Â°Ô ¼öÁ¤ÇÏ¿© °£´ÜÈ÷ ÀÛ¾÷À» ¸¶Ä£´Ù. ´ÙÀ½ °°ÀÌ ½ÇÇàÇÑ´Ù:

    + + + $ apxs -i -a mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [/path/to/apache/conf/httpd.conf¿¡¼­ `foo' ¸ðµâÀ» È°¼ºÈ­ÇÑ´Ù]
    + $ _ +
    + +

    ±×·¯¸é ´ÙÀ½°ú °°Àº ÁÙÀ»

    + + + LoadModule foo_module modules/mod_foo.so + + +

    ¼³Á¤ÆÄÀÏ¿¡ ¾ø´Ù¸é Ãß°¡ÇÑ´Ù. ÀÌ ¼³Á¤À» ±âº»ÀûÀ¸·Î »ç¿ëÇÏÁö + ¾Ê´Â´Ù¸é -A ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. Áï

    + + + $ apxs -i -A mod_foo.c + + +

    apxs¸¦ ½±°Ô »ç¿ëÇÏ·Á°í ´ÙÀ½°ú °°ÀÌ ¾ÆÆÄÄ¡ ¸ðµâ °ßº»°ú + MakefileÀ» ¸¸µé ¼ö ÀÖ´Ù:

    + + + $ apxs -g -n foo
    + Creating [DIR] foo
    + Creating [FILE] foo/Makefile
    + Creating [FILE] foo/modules.mk
    + Creating [FILE] foo/mod_foo.c
    + Creating [FILE] foo/.deps
    + $ _ +
    + +

    ±×·±ÈÄ ¹Ù·Î °ßº» ¸ðµâÀ» °øÀ¯°´Ã¼·Î ÄÄÆÄÀÏÇÏ¿© ¾ÆÆÄÄ¡ + ¼­¹ö°¡ Àеµ·ÏÇÑ´Ù:

    + + + $ cd foo
    + $ make all reload
    + apxs -c mod_foo.c
    + /path/to/libtool --mode=compile gcc ... -c mod_foo.c
    + /path/to/libtool --mode=link gcc ... -o mod_foo.la mod_foo.slo
    + apxs -i -a -n "foo" mod_foo.la
    + /path/to/instdso.sh mod_foo.la /path/to/apache/modules
    + /path/to/libtool --mode=install cp mod_foo.la /path/to/apache/modules + ... + chmod 755 /path/to/apache/modules/mod_foo.so
    + [/path/to/apache/conf/httpd.conf¿¡¼­ `foo' ¸ðµâÀ» È°¼ºÈ­ÇÑ´Ù]
    + apachectl restart
    + /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    + [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    + /path/to/apache/sbin/apachectl restart: httpd started
    + $ _ +
    + +
    +
    diff --git a/trunk/docs/manual/programs/apxs.xml.meta b/trunk/docs/manual/programs/apxs.xml.meta new file mode 100644 index 0000000000..886c2b4f1f --- /dev/null +++ b/trunk/docs/manual/programs/apxs.xml.meta @@ -0,0 +1,12 @@ + + + + apxs + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/configure.html b/trunk/docs/manual/programs/configure.html new file mode 100644 index 0000000000..9f569079b8 --- /dev/null +++ b/trunk/docs/manual/programs/configure.html @@ -0,0 +1,7 @@ +URI: configure.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: configure.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/configure.html.en b/trunk/docs/manual/programs/configure.html.en new file mode 100644 index 0000000000..6b5d9c9d2a --- /dev/null +++ b/trunk/docs/manual/programs/configure.html.en @@ -0,0 +1,934 @@ + + + +configure - Configure the source tree - Apache HTTP Server + + + + + +
    <-
    +

    configure - Configure the source tree

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    The configure script configures the source tree + for compiling and installing the Apache HTTP Server on your + particular platform. Various options allow the compilation of a + server corresponding to your personal requirements.

    + +

    This script, included in the root directory of the source + distribution, is for compilation on Unix and Unix-like systems + only. For other platforms, see the platform documentation.

    +
    + +
    top
    +
    +

    Synopsis

    +

    You should call the configure script from within the + root directory of the distribution.

    + +

    ./configure [OPTION]... + [VAR=VALUE]...

    + +

    To assign environment variables (e.g. CC, + CFLAGS ...), specify them as + VAR=VALUE. See below + for descriptions of some of the useful variables.

    +
    top
    +
    +

    Options

    + + +

    Configuration options

    + +

    The following options influence the behavior of + configure itself.

    + +
    +
    -C
    +
    --config-cache
    +
    This is an alias for --cache-file=config.cache
    + +
    --cache-file=FILE
    +
    The test results will be cached in file FILE. + This option is disabled by default.
    + +
    -h
    +
    --help [short|recursive]
    +
    Output the help and exit. With the argument short only + options specific to this package will displayed. The argument + recursive displays the short help of all the included + packages.
    + +
    -n
    +
    --no-create
    +
    The configure script is run normally but does + not create output files. This is useful to check the test results + before generating makefiles for compilation.
    + +
    -q
    +
    --quiet
    +
    Do not print checking ... messages during the + configure process.
    + +
    --srcdir=DIR
    +
    Defines directory DIR to be the source file directory. + Default is the directory, where configure is located, or the parent + directory ...
    + +
    --silent
    +
    Same as --quiet
    + +
    -V
    +
    --version
    +
    Display copyright information and exit.
    +
    + + +

    Installation + directories

    + +

    These options define the installation directory. The installation + tree depends on the selected layout.

    + +
    +
    --prefix=PREFIX
    +
    Install architecture-independent files in PREFIX. + By default the installation directory is set to + /usr/local/apache2.
    + +
    --exec-prefix=EPREFIX
    +
    Install architecture-dependent files in EPREFIX. + By default the installation directory is set to the + PREFIX directory.
    +
    + +

    By default, make install will install all the files in + /usr/local/apache2/bin, /usr/local/apache2/lib + etc. You can specify an installation prefix other than + /usr/local/apache2 using --prefix, + for instance --prefix=$HOME.

    + +

    Define a directory layout

    +
    +
    --enable-layout=LAYOUT
    +
    Configure the source code and build scripts to assume an + installation tree based on the layout LAYOUT. This allows + you to separately specify the locations for each type of file within + the Apache HTTP Server installation. The config.layout + file contains several example configurations, and you can also create + your own custom configuration following the examples. The different + layouts in this file are grouped into <Layout + FOO>...</Layout> sections and referred to by name as + in FOO. The default layout is Apache.
    +
    + + +

    Fine tuning of the installation + directories

    + +

    For better control of the installation directories, use the options + below. Please note that the directory defaults are set by + autoconf and be overwritten by the corresponding layout + setting.

    + +
    + +
    --bindir=DIR
    +
    Install user executables in DIR. The user executables + are supporting programs like htpasswd, + dbmmanage, etc. which are useful for site + administrators. By default DIR is set to + EPREFIX/bin.
    + +
    --datadir=DIR
    +
    Install read-only architecture-independent data in DIR. + By default datadir is set to + PREFIX/share. This option is offered by + autoconf and currently unused.
    + +
    --includedir=DIR
    +
    Install C header files in DIR. By default + includedir is set to + EPREFIX/include.
    + +
    --infodir=DIR
    +
    Install info documentation in DIR. + By default infodir is set to + PREFIX/info. This option is currently + unused.
    + +
    --libdir=DIR
    +
    Install object code libraries in DIR. By default + libdir is set to + EPREFIX/lib.
    + +
    --libexecdir=DIR
    +
    Install the program executables (i.e., shared modules) in + DIR. By default libexecdir is set to + EPREFIX/libexec.
    + +
    --localstatedir=DIR
    +
    Install modifiable single-machine data in DIR. + By default localstatedir is set to + PREFIX/var. This option is offered by + autoconf and currently unused.
    + +
    --mandir=DIR
    +
    Install the man documentation in DIR. By default + mandir is set to + EPREFIX/man.
    + +
    --oldincludedir=DIR
    +
    Install C header files for non-gcc in DIR. + By default oldincludedir is set to + /usr/include. This option is offered by + autoconf and currently unused.
    + +
    --sbindir=DIR
    +
    Install the system administrator executables in DIR. + Those are server programs like httpd, + apachectl, suexec, etc. which + are neccessary to run the Apache HTTP Server. By default + sbindir is set to + EPREFIX/sbin.
    + +
    --sharedstatedir=DIR
    +
    Install modifiable architecture-independent data in DIR. + By default sharedstatedir is set to + PREFIX/com. This option is offered by + autoconf and currently unused.
    + +
    --sysconfdir=DIR
    +
    Install read-only single-machine data like the server configuration + files httpd.conf, mime.types, etc. in + DIR. By default sysconfdir is set to + PREFIX/etc.
    +
    + + + +

    System types

    + +

    These options are used to cross-compile the Apache HTTP Server to run on + another system. In normal cases, when building and running the server on + the same system, these options are not used.

    + +
    +
    --build=BUILD
    +
    Defines the system type of the system on which the tools are being + built. It defaults to the result of the script + config.guess.
    + +
    --host=HOST
    +
    Defines the system type of the system on which the server will run. + HOST defaults to BUILD.
    + +
    --target=TARGET
    +
    Configure for building compilers for the system type + TARGET. It defaults to HOST. This option is + offered by autoconf and not necessary for the Apache HTTP + Server.
    +
    + + +

    Optional Features

    + +

    These options are used to fine tune the features your HTTP server will + have.

    + +

    General syntax

    +

    Generally you can use the following syntax to enable or disable a + feature:

    + +
    +
    --disable-FEATURE
    +
    Do not include FEATURE. This is the same as + --enable-FEATURE=no.
    + +
    --enable-FEATURE[=ARG]
    +
    Include FEATURE. The default value for ARG + is yes.
    + +
    --enable-MODULE=shared
    +
    The corresponding module will be build as DSO module.
    + +
    --enable-MODULE=static
    +
    By default enabled modules are linked statically. You can force + this explicitly.
    +
    + +

    Note

    + configure will not complain about + --enable-foo even if foo doesn't + exist, so you need to type carefully. +
    + + + +

    Modules enabled by default

    +

    Some modules are compiled by default and have to be disabled + explicitly. Use the following options to remove discrete modules from + the compilation process.

    + +
    +
    --disable-actions
    +
    Disable action triggering on requests, which is provided by + mod_actions.
    + +
    --disable-alias
    +
    Disable the mapping of requests to different parts of the + filesystem, which is provided by mod_alias.
    + +
    --disable-asis
    +
    Disable support for as-is filetypes, which is provided by + mod_asis.
    + +
    --disable-auth
    +
    Disable user-based access control provided by + mod_auth. This module provides for HTTP Basic + Authentication, where the usernames and passwords are stored in + plain text files.
    + +
    --disable-autoindex
    +
    Disable the directory listing functionality provided by + mod_autoindex.
    + +
    --disable-access
    +
    Disable host-based access control provided by + mod_access.
    + +
    --disable-cgi
    +
    mod_cgi, which provides support for CGI scripts, + is enabled by default when using a non-threaded MPM. Use this + option to disable CGI support.
    + +
    --disable-cgid
    +
    When using the threaded MPMs worker or + perchild support for CGI scripts is provided by + mod_cgid by default. To disable CGI support use + this option.
    + +
    --disable-charset-lite
    +
    Disable character set translation provided by + mod_charset_lite. This module will be installed by + default only on EBCDIC systems.
    + +
    --disable-dir
    +
    Disable directory request handling provided by + mod_dir.
    + +
    --disable-env
    +
    Enable setting and clearing of environment variables, which is + provided by mod_env.
    + + +
    --disable-http
    +
    Disable the HTTP protocol handling. The http + module is a basic one, enabling the server to function as an + HTTP server. It is only useful to disable it if you want to use + another protocol module instead. Don't disable this + module unless you are really sure what you are doing. +
    + Note: This module will always be linked statically.
    + +
    --disable-imagemap
    +
    Disable support for server based imagemaps, which provided by + mod_imagemap.
    + +
    --disable-include
    +
    Disable Server Side Includes provided by + mod_include.
    + +
    --disable-log-config
    +
    Disable the logging configuration provided by + mod_log_config. You won't be able to log requests + to the server without this module.
    + +
    --disable-mime
    +
    mod_mime associates the requested filename's + extensions with the file's behavior and content (mime-type, + language, character set and encoding). Disabling the mapping of + file-extensions to MIME is normally not recommended.
    + +
    --disable-negotiation
    +
    Disable content negotiation provided by + mod_negotiation.
    + +
    --disable-setenvif
    +
    Disable support for basing environment variables on headers, + which is provided by mod_setenvif.
    + +
    --disable-status
    +
    Enable the process/thread monitoring, which is provided by + mod_status.
    + +
    --disable-userdir
    +
    Disable the mapping of requests to user-specific directories, + which is provided by mod_userdir.
    +
    + + +

    Modules, disabled by default

    +

    Some modules are compiled by default and have to be enabled + explicitly or by using the keywords most or + all (see --enable-mods-shared below for + further explanation) to be available. Therefore use the options + below.

    + +
    +
    --enable-auth-anon
    +
    Enable anonymous user access provided by + mod_auth_anon.
    + +
    --enable-auth-dbm
    +
    mod_auth_dbm provides for HTTP Basic + Authentication, where the usernames and passwords are stored in DBM + type database files. Use this option to enable the module.
    + +
    --enable-auth-digest
    +
    Enable RFC2617 Digest authentication provided by + mod_auth_digest. This module uses plain text files + to store the credentials.
    + +
    --enable-authnz-ldap
    +
    Enable LDAP based authentication provided by + mod_authnz_ldap.
    + +
    --enable-cache
    +
    Enable dynamic file caching provided by + mod_cache. This experimental module may be + interesting for servers with high load or caching proxy servers. At + least one storage management module (e.g. + mod_disk_cache or mod_mem_cache) + is also necessary.
    + +
    --enable-cern-meta
    +
    Enable the CERN-type meta files support provided by + mod_cern_meta.
    + +
    --enable-charset-lite
    +
    Enable character set translation provided by + mod_charset_lite. This module will be installed by + default only on EBCDIC systems. On other systems, you have to enable + it.
    + +
    --enable-dav
    +
    Enable the WebDAV protocol handling provided by + mod_dav. Support for filesystem resources is + provided by the seperate module mod_dav_fs. This + module is also automatically enabled with + --enable-dav.
    + Note: mod_dav can only be used together with the + http protocol module.
    + +
    --enable-dav-fs
    +
    Enable DAV support for filesystem resources, which is provided by + mod_dav_fs. This module is a provider for the + mod_dav module, so you should also use + --enable-dav.
    + +
    --enable-dav-lock
    +
    Enable mod_dav_lock which provides generic DAV + locking support for backend modules. This module needs at least + mod_dav to function, so you should also use + --enable-dav.
    + +
    --enable-deflate
    +
    Enable deflate transfer encoding provided by + mod_deflate.
    + +
    --enable-disk-cache
    +
    Enable disk caching provided by + mod_disk_cache.
    + +
    --enable-expires
    +
    Enable Expires header control provided by + mod_expires.
    + +
    --enable-ext-filter
    +
    Enable the external filter support provided by + mod_ext_filter.
    + +
    --enable-file-cache
    +
    Enable the file cache provided by + mod_file_cache.
    + +
    --enable-headers
    +
    Enable control of HTTP headers provided by + mod_headers.
    + +
    --enable-info
    +
    Enable the server information provided by + mod_info.
    + +
    --enable-ldap
    +
    Enable LDAP caching and connection pooling services provided by + mod_ldap.
    + +
    --enable-logio
    +
    Enable logging of input and output bytes including headers provided + by mod_logio.
    + +
    --enable-mem-cache
    +
    Enable memory caching provided by + mod_mem_cache.
    + +
    --enable-mime-magic
    +
    Enable automatical determining of MIME types, which is provided by + mod_mime_magic.
    + +
    --enable-isapi
    +
    Enable the isapi extension support provided by + mod_isapi.
    + +
    --enable-proxy
    +
    Enable the proxy/gateway functionality provided by + mod_proxy. The proxying capabilities for + AJP13, CONNECT, FTP, + HTTP and the balancer are provided by the seperate + modules mod_proxy_ajp, + mod_proxy_connect, mod_proxy_ftp, + mod_proxy_http and + mod_proxy_balancer. + These five modules are also automatically enabled with + --enable-proxy.
    + +
    --enable-proxy-ajp
    +
    Enable proxy support for AJP13 (Apache JServ Protocol 1.3) + request handling, which is provided by mod_proxy_ajp. + This module is an extension for the mod_proxy module, + so you should also use --enable-proxy.
    + +
    --enable-proxy-balancer
    +
    Enable load balancing support for the AJP13, + FTP and HTTP protocols, which is provided by + mod_proxy_balancer. This module is an extension for the + mod_proxy module, so you should also use + --enable-proxy.
    + +
    --enable-proxy-connect
    +
    Enable proxy support for CONNECT request handling, + which is provided by mod_proxy_connect. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-proxy-ftp
    +
    Enable proxy support for FTP requests, which is + provided by mod_proxy_ftp. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-proxy-http
    +
    Enable proxy support for HTTP requests, which is + provided by mod_proxy_http. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-rewrite
    +
    Enable rule based URL manipulation provided by + mod_rewrite.
    + +
    --enable-so
    +
    Enable DSO capability provided by mod_so. This + module will be automatically enabled if you use the + --enable-mods-shared option.
    + +
    --enable-speling
    +
    Enable the functionality to correct common URL misspellings, which + is provided by mod_speling.
    + +
    --enable-ssl
    +
    Enable support for SSL/TLS provided by + mod_ssl.
    + +
    --enable-unique-id
    +
    Enable the generation of per-request unique ids, which is provided + by mod_unique_id.
    + +
    --enable-usertrack
    +
    Enable user-session tracking provided by + mod_usertrack.
    + +
    --enable-vhost-alias
    +
    Enable mass virtual hosting provided by + mod_vhost_alias.
    +
    + + +

    Modules for developers

    +

    The following modules are useful only for developers and testing + purposes and are disabled by default. Use the following options to + enable them. If you are not sure whether you need one of these + modules, omit them.

    + +
    + +
    --enable-bucketeer
    +
    Enable the manipulation filter for buckets, which is provided by + mod_bucketeer.
    + + +
    --enable-case-filter
    +
    Enable the example uppercase conversion output filter support of + mod_case_filter.
    + + +
    --enable-case-filter-in
    +
    Enable the example uppercase conversion input filter support of + mod_case_filter_in.
    + +
    --enable-echo
    +
    Enable the ECHO server provided by + mod_echo.
    + +
    --enable-example
    +
    Enable the example and demo module + mod_example.
    + + +
    --enable-optional-fn-export
    +
    Enable the example for an optional function exporter, which is + provided by mod_optional_fn_export.
    + + +
    --enable-optional-fn-import
    +
    Enable the example for an optional function importer, which is + provided by mod_optional_fn_import.
    + + +
    --enable-optional-hook-export
    +
    Enable the example for an optional hook exporter, which is provided + by mod_optional_hook_export.
    + + +
    --enable-optional-hook-import
    +
    Enable the example optional hook importer, which is provided by + mod_optional_hook_import.
    +
    + + +

    MPMs and third-party modules

    +

    To add the necessary Multi Processing Module and additional third-party + modules use the following options:

    + +
    +
    --with-module=module-type:module-file[, + module-type:module-file]
    +

    Add one or more third-party modules to the list of statically linked + modules. The module source file module-file + will be searched in the modules/module-type + subdirectory of your Apache HTTP server source tree. If it is not found + there configure is considering module-file to be + an absolute file path and tries to copy the source file into the + module-type subdirectory. If the subdirectory doesn't + exist it will be created and populated with a standard + Makefile.in.

    +

    This option is useful to add small external modules consisting of + one source file. For more complex modules you should read the + vendor's documentation.

    +

    Note

    + If you want to build a DSO module instead of a statically linked + use apxs.
    +
    + +
    --with-mpm=MPM
    +
    Choose the process model for your server. You have to select + exactly one Multi-Processing Module. + Otherwise the default MPM for + your operating system will be taken. Possible MPMs are + beos, leader, + mpmt_os2, perchild, + prefork, threadpool and + worker.
    +
    + + +

    Cumulative and other options

    +
    +
    --enable-maintainer-mode
    +
    Turn on debugging and compile time warnings.
    + +
    --enable-mods-shared=MODULE-LIST
    +
    +

    Defines a list of modules to be enabled and build as dynamic + shared modules. This mean, these module have to be loaded + dynamically by using the LoadModule directive.

    +

    MODULE-LIST is a space separated list of modulenames + enclosed by quotation marks. The module names are given without the + preceding mod_. For example:

    +

    + --enable-mods-shared='headers rewrite dav' +

    +

    Additionally you can use the special keywords all and + most. For example,

    +

    + --enable-mods-shared=most +

    +

    will compile most modules and build them as DSO modules. +

    +
    + +
    --enable-modules=MODULE-LIST
    +
    This option behaves similar to --enable-mods-shared, + but will link the given modules statically. This mean, these modules + will always be present while running httpd. They need + not be loaded with LoadModule.
    + +
    --enable-v4-mapped
    +
    Allow IPv6 sockets to handle IPv4 connections.
    + +
    --with-port=PORT
    +
    This defines the port on which httpd will listen. + This port number is used when generating the configuration file + httpd.conf. The default is 80.
    + +
    --with-program-name
    +
    Define an alternative executable name. The default is + httpd.
    +
    + + + +

    Optional packages

    +

    These options are used to define optional packages.

    + +

    General syntax

    +

    Generally you can use the following syntax to define an optional + package:

    + +
    +
    --with-PACKAGE[=ARG]
    +
    Use the package PACKAGE. The default value for + ARG isyes.
    + +
    --without-PACKAGE
    +
    Do not use the package PACKAGE. This is the same as + --with-PACKAGE=no. This option is provided by + autoconf but not very useful for the Apache HTTP + Server.
    +
    + + + + +

    Specific packages

    +
    +
    --with-apr=DIR|FILE
    +
    The Apache Portable Runtime (APR) is part of the httpd + source distribution and will automatically be build together with the + HTTP server. If you want to use an already installed APR instead you + have to tell configure the path to the + apr-config script. You may set the absolute path and name + or the directory to the installed APR. apr-config must + exists within this directory or the subdirectory + bin.
    + +
    --with-apr-util=DIR|FILE
    +
    The Apache Portable Runtime Utilities (APU) are part of the + httpd source distribution and will automatically be build + together with the HTTP server. If you want to use an already installed + APU instead you have to tell configure the path to the + apu-config script. You may set the absolute path and name + or the directory to the installed APU. apu-config must + exists within this directory or the subdirectory + bin.
    + +
    --with-ssl=DIR
    +
    If mod_ssl has been enabled configure + searches for an installed OpenSSL. You can set the directory path + to the SSL/TLS toolkit instead.
    + +
    --with-z=DIR
    +
    configure searches automatically for an installed + zlib library if your source configuration requires one + (e.g., when mod_deflate is enabled). You can set the + directory path to the compression library instead.
    +
    + +

    Several features of the Apache HTTP Server, including + mod_authn_dbm and mod_rewrite's DBM + RewriteMap use simple + key/value databases for quick lookups of information. SDBM is included + in the APU, so this database is always available. If you would like to + use other database types, use the following options to enable + them:

    + +
    +
    --with-gdbm[=path]
    +
    If no path is specified, configure will + search for the include files and libraries of a GNU DBM + installation in the usual search paths. An explicit + path will cause configure to look in + path/lib and + path/include for the relevant files. + Finally, the path may specify specific include and + library paths separated by a colon.
    + +
    --with-ndbm[=path]
    +
    Like --with-gdbm, bur searches for a New DBM + installation.
    + +
    --with-berkeley-db[=path]
    +
    Like --with-gdbm, but searches for a Berkeley DB + installation.
    +
    + +

    Note

    +

    The DBM options are provided by the APU and passed through to its + configuration script. They are useless when using an already + installed APU defined by --with-apr-util.

    +

    You may use more then one DBM implementation together with your + HTTP server. The appropriated DBM type will be configured within + the runtime configuration at each time.

    +
    + + + +

    Options for support programs

    +
    +
    --enable-static-support
    +
    Build a statically linked version of the support binaries. This + means, a stand-alone executable will be built with all the necessary + libraries integrated. Otherwise the support binaries are linked + dynamically by default.
    + +
    --enable-suexec
    +
    Use this option to enable suexec, which allows you to set + uid and gid for spawned processes. Do not use this + option unless you understand all the security implications of + running a suid binary on your server. Further options + to configure suexec are described below.
    + +

    It is possible to create a statically linked binary of a single + support program by using the following options:

    + +
    +
    --enable-static-ab
    +
    Build a statically linked version of ab.
    + + +
    --enable-static-checkgid
    +
    Build a statically linked version of checkgid.
    + +
    --enable-static-htdbm
    +
    Build a statically linked version of htdbm.
    + +
    --enable-static-htdigest
    +
    Build a statically linked version of htdigest.
    + +
    --enable-static-htpasswd
    +
    Build a statically linked version of htpasswd.
    + +
    --enable-static-logresolve
    +
    Build a statically linked version of logresolve.
    + +
    --enable-static-rotatelogs
    +
    Build a statically linked version of rotatelogs.
    +
    + +

    suexec configuration options

    +

    The following options are used to fine tune the behavior of suexec. See Configuring and installing suEXEC + for further information.

    + +
    +
    --with-suexec-bin
    +
    This defines the path to suexec binary. Default is + --sbindir (see Fine + tuning of installation directories).
    + +
    --with-suexec-caller
    +
    This defines the user allowed to call suexec. + It should be the same as the user under which httpd + normally runs.
    + +
    --with-suexec-docroot
    +
    This defines the directory tree under which suexec access is allowed for executables. Default value is + --datadir/htdocs.
    + +
    --with-suexec-gidmin
    +
    Define this as the lowest GID allowed to be a target user for + suexec. The default value is 100.
    + +
    --with-suexec-logfile
    +
    This defines the filename of the suexec logfile. + By default the logfile is named suexec_log and located in + --logfiledir.
    + +
    --with-suexec-safepath
    +
    Define the value of the environment variable PATH to + be set for processes started by suexec. Default + value is /usr/local/bin:/usr/bin:/bin.
    + +
    --with-suexec-userdir
    +
    This defines the subdirectory under the user's directory that + contains all executables for which suexec access + is allowed. This setting is necessary when you want to use + suexec together with user-specific directories (as + provided by mod_userdir). The default is + public_html.
    + +
    --with-suexec-uidmin
    +
    Define this as the lowest UID allowed to be a target user for + suexec. The default value is 100.
    + +
    --with-suexec-umask
    +
    Set umask for processes started by + suexec. It defaults to your system settings.
    +
    + + +
    top
    +
    +

    Environment variables

    +

    There are some useful environment variables to override the choices made by + configure or to help it to find libraries and programs with + nonstandard names or locations.

    + + +
    +
    CC
    +
    Define the C compiler command to be used for compilation.
    + +
    CFLAGS
    +
    Set C compiler flags you want to use for compilation.
    + +
    CPP
    +
    Define the C preprocessor command to be used.
    + +
    CPPFLAGS
    +
    Set C/C++ preprocessor flags, e.g. -Iincludedir + if you have headers in a nonstandard directory includedir.
    + +
    LDFLAGS
    +
    Set linker flags, e.g. -Llibdir if you have + libraries in a nonstandard directory libdir.
    +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/configure.html.ko.euc-kr b/trunk/docs/manual/programs/configure.html.ko.euc-kr new file mode 100644 index 0000000000..f6156ac540 --- /dev/null +++ b/trunk/docs/manual/programs/configure.html.ko.euc-kr @@ -0,0 +1,930 @@ + + + +configure - ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    configure - ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    configure ½ºÅ©¸³Æ®´Â ƯÁ¤ Ç÷¡Æû¿¡¼­ ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇϱâÀ§ÇØ ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù. ¿©·¯ + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¿øÇÏ´Â ¿ä±¸Á¶°Ç¿¡ ¸Â°Ô ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ ¼ö + ÀÖ´Ù.

    + +

    ¼Ò½º ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ µð·ºÅ丮¿¡ ÀÖ´Â ÀÌ ½ºÅ©¸³Æ®´Â À¯´Ð½º¿Í + À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­¸¸ »ç¿ëÇÑ´Ù. ´Ù¸¥ Ç÷¡ÆûÀ» »ç¿ëÇÑ´Ù¸é + Ç÷¡Æû ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    configure ½ºÅ©¸³Æ®´Â ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ + µð·ºÅ丮¿¡¼­ ½ÇÇàÇØ¾ß ÇÑ´Ù.

    + +

    ./configure [OPTION]... + [VAR=VALUE]...

    + +

    ȯ°æº¯¼ö¸¦ (¿¹¸¦ µé¾î, CC, CFLAGS, + ...) ÁöÁ¤ÇÏ·Á¸é, VAR=VALUE¿Í + °°ÀÌ Áö½ÃÇÑ´Ù. ¾Æ·¡¿¡¼­ À¯¿ëÇÑ È¯°æº¯¼öµéÀ» + ¼³¸íÇÑ´Ù.

    +
    top
    +
    +

    ¿É¼Ç

    + + +

    ±¸¼º ¿É¼Ç

    + +

    ÀÌ ¿É¼ÇµéÀº configure ÀÚü Çൿ¿¡ ¿µÇâÀ» + ÁØ´Ù.

    + +
    +
    -C
    +
    --config-cache
    +
    --cache-file=config.cache¿Í °°´Ù.
    + +
    --cache-file=FILE
    +
    °Ë»ç °á°ú¸¦ FILE ÆÄÀÏ¿¡ ij½ÌÇÑ´Ù. + ±âº»°ªÀº °Ë»ç °á°ú¸¦ ±â·ÏÇÏÁö ¾Ê´Â´Ù.
    + +
    -h
    +
    --help [short|recursive]
    +
    µµ¿ò¸»À» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù. short ¾Æ±Ô¸ÕÆ®´Â + ÀÌ ÆÐÅ°Áö ƯÀ¯ÀÇ ¿É¼Ç¸¸À» Ãâ·ÂÇÑ´Ù. recursive + ¾Æ±Ô¸ÕÆ®´Â Æ÷ÇÔµÈ ¸ðµç ÆÐÅ°Áö¿¡ ´ëÇÑ ÂªÀº µµ¿ò¸»À» + º¸¿©ÁØ´Ù.
    + +
    -n
    +
    --no-create
    +
    configure ½ºÅ©¸³Æ®¸¦ Á¤»óÀûÀ¸·Î ½ÇÇàÇÏÁö¸¸, + Ãâ·ÂÆÄÀÏÀ» ¸¸µéÁö ¾Ê´Â´Ù. ÀÌ ¿É¼ÇÀº ÄÄÆÄÀÏÀ» À§ÇÑ makefileÀ» + ¸¸µé±â ÀÌÀü¿¡ °Ë»ç °á°ú¸¦ È®ÀÎÇغ¼¶§ À¯¿ëÇÏ´Ù.
    + +
    -q
    +
    --quiet
    +
    ½ÇÇàÁß¿¡ checking ... ¹®±¸¸¦ Ãâ·ÂÇÏÁö + ¾Ê´Â´Ù.
    + +
    --srcdir=DIR
    +
    DIR µð·ºÅ丮¸¦ ¼Ò½ºÆÄÀÏ µð·ºÅ丮·Î ÁöÁ¤ÇÑ´Ù. + ±âº»°ªÀº configure°¡ ÀÖ´Â µð·ºÅ丮 ȤÀº »óÀ§µð·ºÅ丮 + ..ÀÌ´Ù.
    + +
    --silent
    +
    --quiet¿Í °°´Ù.
    + +
    -V
    +
    --version
    +
    ÀúÀÛ±Ç Á¤º¸¸¦ Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    +
    + + +

    ¼³Ä¡ µð·ºÅ丮

    + +

    ÀÌ ¿É¼ÇµéÀº ¼³Ä¡ µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. ¼³Ä¡ À§Ä¡´Â + ¼±ÅÃÇÑ ±¸Á¶(layout)¿¡ µû¶ó ´Ù¸£´Ù.

    + +
    +
    --prefix=PREFIX
    +
    ¾ÆÅ°ÅØÃÄ¿¡ µ¶¸³ÀûÀÎ ÆÄÀÏÀ» PREFIX¿¡ ¼³Ä¡ÇÑ´Ù. + ±âº»°ªÀº /usr/local/apache2ÀÌ´Ù.
    + +
    --exec-prefix=EPREFIX
    +
    ¾ÆÅ°ÅØÃÄ¿¡ ÀÇÁ¸ÀûÀÎ ÆÄÀÏÀ» EPREFIX¿¡ ¼³Ä¡ÇÑ´Ù. + ±âº»°ªÀº PREFIX µð·ºÅ丮ÀÌ´Ù.
    +
    + +

    ±âº»ÀûÀ¸·Î make installÀº + /usr/local/apache2/bin, + /usr/local/apache2/lib¿Í °°Àº À§Ä¡¿¡ ¸ðµç + ÆÄÀÏÀ» ¼³Ä¡ÇÑ´Ù. --prefix=$HOME°ú °°ÀÌ + --prefix ¿É¼ÇÀ» »ç¿ëÇÏ¿© + /usr/local/apache2 ÀÌ¿ÜÀÇ ¼³Ä¡ »óÀ§µð·ºÅ丮¸¦ + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    µð·ºÅ丮 ±¸Á¶ ÁöÁ¤

    +
    +
    --enable-layout=LAYOUT
    +
    ¼³Ä¡ À§Ä¡¸¦ LAYOUT ±¸Á¶¿¡ µû¸£µµ·Ï + ¼Ò½ºÄÚµå¿Í ÄÄÆÄÀÏ ½ºÅ©¸³Æ®¸¦ ±¸¼ºÇÑ´Ù. ±¸Á¶¸¦ »ç¿ëÇϸé + ÆÄÀÏ Á¾·ù¿¡ µû¶ó ¼³Ä¡ À§Ä¡¸¦ µû·Î ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. + config.layout ÆÄÀÏ¿¡ ¿©·¯ ¼³Á¤ ¿¹°¡ ÀÖ°í, + À̸¦ Âü°íÇÏ¿© Á÷Á¢ ¼³Á¤À» ¸¸µé ¼öµµ ÀÖ´Ù. ÆÄÀÏ¿¡¼­ + °¢ ±¸Á¶´Â <Layout + FOO>...</Layout>·Î ±¸ºÐµÇ¸ç, ÀÌ + ºÎºÐÀº FOO¶ó´Â À̸§ÀÇ ±¸Á¶¸¦ ³ªÅ¸³½´Ù. + ±¸Á¶ÀÇ ±âº»°ªÀº ApacheÀÌ´Ù.
    +
    + + +

    ¼³Ä¡ µð·ºÅ丮ÀÇ + ÀÚ¼¼ÇÑ Á¶Á¤

    + +

    ¼³Ä¡ µð·ºÅ丮¸¦ ´õ ¼öÁ¤ÇÑ´Ù¸é ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. + °¢ µð·ºÅ丮ÀÇ ±âº»°ªÀº autoconf°¡ ÁöÁ¤Çϸç, + ¼±ÅÃÇÑ ±¸Á¶¿¡ µû¶ó ´Ù¸§À» ÁÖÀÇÇ϶ó.

    + +
    + +
    --bindir=DIR
    +
    »ç¿ëÀÚ ½ÇÇàÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. »ç¿ëÀÚ + ½ÇÇàÆÄÀÏ¿¡´Â »çÀÌÆ® °ü¸®ÀÚ¿¡°Ô À¯¿ëÇÑ + htpasswd¿Í dbmmanage °°Àº + Áö¿ø ÇÁ·Î±×·¥µµ Æ÷ÇԵȴÙ. DIRÀÇ ±âº»°ªÀº + EPREFIX/binÀÌ´Ù.
    + +
    --datadir=DIR
    +
    ¾ÆÅ°ÅØÃÄ µ¶¸³ÀûÀÎ ÀбâÀü¿ë ÀڷḦ DIR¿¡ + ¼³Ä¡ÇÑ´Ù. datadirÀÇ ±âº»°ªÀº + PREFIX/shareÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --includedir=DIR
    +
    C Çì´õÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. + includedirÀÇ ±âº»°ªÀº + EPREFIX/includeÀÌ´Ù.
    + +
    --infodir=DIR
    +
    info ¹®¼­¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + infodirÀÇ ±âº»°ªÀº + PREFIX/infoÀÌ´Ù. ÇöÀç ÀÌ ¿É¼ÇÀº + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --libdir=DIR
    +
    ¿ÀºêÁ§Æ®ÄÚµå ¶óÀ̺귯¸®¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + libdirÀÇ ±âº»°ªÀº + EPREFIX/libÀÌ´Ù.
    + +
    --libexecdir=DIR
    +
    ÇÁ·Î±×·¥ ½ÇÇàÆÄÀÏÀ» (Áï, °øÀ¯¸ðµâ) DIR¿¡ + ¼³Ä¡ÇÑ´Ù. libexecdirÀÇ ±âº»°ªÀº + EPREFIX/libexecÀÌ´Ù.
    + +
    --localstatedir=DIR
    +
    º¯°æµÇ´Â ¸Ó½®º° Á¤º¸¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + localstatedirÀÇ ±âº»°ªÀº + PREFIX/varÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --mandir=DIR
    +
    man ¹®¼­¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + mandirÀÇ ±âº»°ªÀº + EPREFIX/manÀÌ´Ù.
    + +
    --oldincludedir=DIR
    +
    gcc°¡ ¾Æ´Ñ ÄÄÆÄÀÏ·¯¸¦ À§ÇÑ C Çì´õÆÄÀÏÀ» DIR¿¡ + ¼³Ä¡ÇÑ´Ù. oldincludedirÀÇ ±âº»°ªÀº + /usr/includeÀÌ´Ù. autoconf¿¡ + ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --sbindir=DIR
    +
    ½Ã½ºÅÛ °ü¸®ÀÚ¿ë ½ÇÇàÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. + ½Ã½ºÅÛ °ü¸®ÀÚ¿ë ½ÇÇàÆÄÀÏÀ̶õ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ½ÇÇàÇϴµ¥ + ÇÊ¿äÇÑ httpd, apachectl, + suexec µî ¼­¹ö ÇÁ·Î±×·¥À» ¸»ÇÑ´Ù. + sbindirÀÇ ±âº»°ªÀº + EPREFIX/sbinÀÌ´Ù.
    + +
    --sharedstatedir=DIR
    +
    º¯°æµÇ´Â ¾ÆÅ°ÅØÃÄ µ¶¸³ÀûÀÎ ÀڷḦ DIR¿¡ + ¼³Ä¡ÇÑ´Ù. sharedstatedirÀÇ ±âº»°ªÀº + PREFIX/comÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --sysconfdir=DIR
    +
    ¼­¹ö ¼³Á¤ÆÄÀÏ httpd.conf, + mime.types¿Í °°Àº ÀбâÀü¿ë ¸Ó½®º° ÀڷḦ + DIR¿¡ ¼³Ä¡ÇÑ´Ù. sysconfdirÀÇ + ±âº»°ªÀº PREFIX/etcÀÌ´Ù.
    +
    + + + +

    ½Ã½ºÅÛ Á¾·ù

    + +

    ´Ù¸¥ ½Ã½ºÅÛ¿¡¼­ ½ÇÇàÇÒ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ + ±³Â÷ÄÄÆÄÀÏÇϱâ(cross-compile)Çϱâ À§ÇÑ ¿É¼ÇµéÀÌ´Ù. ¼­¹ö¸¦ + ÄÄÆÄÀÏÇÑ ½Ã½ºÅÛ¿¡¼­ ¼­¹ö¸¦ ½ÇÇàÇÏ´Â ÀϹÝÀûÀÎ °æ¿ì, ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.

    + +
    +
    --build=BUILD
    +
    µµ±¸¸¦ ÄÄÆÄÀÏÇÏ´Â ½Ã½ºÅÛÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + config.guess ½ºÅ©¸³Æ®ÀÇ °á°úÀÌ´Ù.
    + +
    --host=HOST
    +
    ¼­¹ö¸¦ ½ÇÇàÇÒ ½Ã½ºÅÛÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. HOSTÀÇ + ±âº»°ªÀº BUILDÀÌ´Ù.
    + +
    --target=TARGET
    +
    TARGET ½Ã½ºÅÛ Á¾·ù¸¦ À§ÇÑ ÄÄÆÄÀÏ·¯¸¦ ¸¸µé¶§ + »ç¿ëÇÑ´Ù. ±âº»°ªÀº HOSTÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í´Â + °ü·ÃÀÌ ¾ø´Ù.
    +
    + + +

    ±â´É ¼±ÅÃ

    + +

    ÀÌ ¿É¼ÇÀº À¥¼­¹öÀÇ ¼¼ºÎ ±â´ÉÀ» Á¶ÀýÇÑ´Ù.

    + +

    ÀϹÝÀûÀÎ ¹®¹ý

    +

    ÀϹÝÀûÀ¸·Î ´ÙÀ½ ¹®¹ýÀ» »ç¿ëÇÏ¿© ±â´ÉÀ» Æ÷ÇÔÇÏ°í »«´Ù:

    + +
    +
    --disable-FEATURE
    +
    FEATURE ±â´ÉÀ» »«´Ù. + --enable-FEATURE=no¿Í °°´Ù.
    + +
    --enable-FEATURE[=ARG]
    +
    FEATURE ±â´ÉÀ» Æ÷ÇÔÇÑ´Ù. ARGÀÇ + ±âº»°ªÀº yesÀÌ´Ù.
    + +
    --enable-MODULE=shared
    +
    ÇØ´ç ¸ðµâÀ» DSO ¸ðµâ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-MODULE=static
    +
    Æ÷ÇÔÇÏ´Â ¸ðµâÀº ±âº»ÀûÀ¸·Î Á¤ÀûÀ¸·Î ¸µÅ©µÈ´Ù. ÀÌ + ¿É¼ÇÀº ¸í½ÃÀûÀ¸·Î Á¤Àû ¸µÅ©¸¦ °­Á¦ÇÑ´Ù.
    +
    + +

    ÁÖÀÇ

    + configure´Â foo°¡ ¾ø´Â °æ¿ì + --enable-foo¸¦ »ç¿ëÇصµ ÀÌ »ç½ÇÀ» + ¾Ë·ÁÁÖÁö ¾ÊÀ¸¹Ç·Î ÁÖÀÇÇؼ­ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. +
    + + + +

    ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏ´Â ¸ðµâ

    +

    ¾î¶² ¸ðµâÀº ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵDZ⶧¹®¿¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é + ¸í½ÃÀûÀ¸·Î »©Áà¾ß ÇÑ´Ù. ´ÙÀ½ ¿É¼ÇÀº ƯÁ¤ ¸ðµâÀ» ÄÄÆÄÀÏ + °úÁ¤¿¡¼­ Á¦¿ÜÇÑ´Ù.

    + +
    +
    --disable-actions
    +
    mod_actions°¡ Á¦°øÇÏ´Â ¿äû¿¡ ´ëÇÑ + Çൿ ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-alias
    +
    mod_alias°¡ Á¦°øÇÏ´Â ¿äûÀ» + ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐÀ¸·Î ´ëÀÀÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --disable-asis
    +
    mod_asis°¡ Á¦°øÇÏ´Â as-is ÆÄÀÏÇüÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-auth
    +
    mod_auth°¡ Á¦°øÇÏ´Â »ç¿ëÀÚº° Á¢±ÙÁ¦¾î + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀº »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ + ÀÏ¹Ý ¹®ÀÚÆÄÀÏ¿¡ ÀúÀåÇÏ´Â HTTP Basic Authentication¿¡¼­ + »ç¿ëÇÑ´Ù.
    + +
    --disable-autoindex
    +
    mod_autoindex°¡ Á¦°øÇÏ´Â µð·ºÅ丮 + ¸ñ·Ï ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-access
    +
    mod_access°¡ Á¦°øÇϴ ȣ½ºÆ®º° + Á¢±ÙÁ¦¾î ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-cgi
    +
    ºñ¾²·¹µå MPMÀ» »ç¿ëÇÏ´Â °æ¿ì CGI ½ºÅ©¸³Æ®¸¦ Áö¿øÇÏ´Â + mod_cgi¸¦ ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÑ´Ù. ÀÌ + ¿É¼ÇÀ» »ç¿ëÇϸé CGI¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-cgid
    +
    ¾²·¹µå MPMÀÎ worker³ª + perchild¸¦ »ç¿ëÇÏ´Â °æ¿ì ±âº»ÀûÀ¸·Î + mod_cgid°¡ CGI ½ºÅ©¸³Æ®¸¦ Áö¿øÇÑ´Ù. + ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé CGI¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-charset-lite
    +
    mod_charset_lite°¡ Á¦°øÇÏ´Â ¹®ÀÚÁýÇÕ + º¯È¯ ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀº EBCDIC ½Ã½ºÅÛ¿¡¼­¸¸ + ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÑ´Ù.
    + +
    --disable-dir
    +
    mod_dirÀÌ Á¦°øÇÏ´Â µð·ºÅ丮 ¿äû + ó¸® ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-env
    +
    mod_env°¡ Á¦°øÇϴ ȯ°æº¯¼ö ¼³Á¤/ÇØÁ¦ + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + + +
    --disable-http
    +
    HTTP ÇÁ·ÎÅäÄÝÀ» ó¸®ÇÏÁö ¾Ê´Â´Ù. http + ¸ðµâÀº ¼­¹ö°¡ À¥¼­¹ö·Î µ¿ÀÛÇϴµ¥ ±âº»ÀûÀÎ ¸ðµâÀÌ´Ù. + ´ë½Å ´Ù¸¥ ÇÁ·ÎÅäÄÝ ¸ðµâÀ» »ç¿ëÇÒ °æ¿ì¿¡¸¸ ÀÌ ¸ðµâÀÌ + À¯¿ëÇÏ´Ù. ÀÚ½ÅÀÌ ¹«¾ùÀ» ÇÏ´ÂÁö È®½ÇÈ÷ ¾ËÁö + ¸øÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» »©Áö ¸¶¶ó +
    + ÁÖÀÇ: ÀÌ ¸ðµâÀº Ç×»ó Á¤ÀûÀ¸·Î ¸µÅ©µÈ´Ù.
    + +
    --disable-imap
    +
    mod_imapÀÌ Á¦°øÇÏ´Â ¼­¹ö±â¹Ý imagemap + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-include
    +
    mod_include°¡ Á¦°øÇÏ´Â Server Side + Includes ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-log-config
    +
    mod_log_config°¡ Á¦°øÇÏ´Â ·Î±× + ¼³Á¤À» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀÌ ¾øÀ¸¸é ¼­¹öÀÇ ¿äûÀ» + ·Î±×¿¡ ±â·ÏÇÒ ¼ö ¾ø´Ù.
    + +
    --disable-mime
    +
    mod_mimeÀº ¿äûÇÑ ÆÄÀϸíÀÇ È®ÀåÀÚ¿¡ + µû¶ó ÆÄÀÏÀÇ Çൿ°ú ³»¿ë(mime-type, ¾ð¾î, ¹®ÀÚÁýÇÕ, + ÀÎÄÚµù)À» °áÁ¤ÇÑ´Ù. (ÀÌ ¸ðµâÀ» Á¦°ÅÇÏ¿©) ÆÄÀÏ È®ÀåÀÚ¸¦ + MIME°ú ¿¬°üÇÏÁö ¾Ê´Â °ÍÀ» ÀϹÝÀûÀ¸·Î ÃßõÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-negotiation
    +
    mod_negotiationÀÌ Á¦°øÇÏ´Â ³»¿ëÇù»ó + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-setenvif
    +
    mod_setenvif°¡ Á¦°øÇÏ´Â Çì´õ¿¡ + µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-status
    +
    mod_status°¡ Á¦°øÇÏ´Â ÇÁ·Î¼¼½º/¾²·¹µå + °¨½Ã ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-userdir
    +
    mod_userdirÀÌ Á¦°øÇÏ´Â ¿äûÀ» »ç¿ëÀÚº° + µð·ºÅ丮¿¡ ´ëÀÀÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    +
    + + +

    ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏÁö ¾Ê´Â ¸ðµâ

    +

    ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵǴ ¸ðµâµµ ÀÖÁö¸¸, ¸ðµâÀ» »ç¿ëÇÏ·Á¸é + Á÷Á¢ ȤÀº most³ª all Å°¿öµå¸¦ + »ç¿ëÇÏ¿© ¸í½ÃÀûÀ¸·Î Æ÷ÇÔÇØ¾ß ÇÏ´Â ¸ðµâÀÌ ÀÖ´Ù. ±×·¡¼­ + ¾Æ·¡ ¿É¼ÇµéÀ» »ç¿ëÇÑ´Ù.

    + +
    +
    --enable-auth-anon
    +
    mod_auth_anonÀÌ Á¦°øÇÏ´Â À͸í»ç¿ëÀÚ + Á¢±Ù ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-auth-dbm
    +
    mod_auth_dbmÀº »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ + DBMÇü½ÄÀÇ µ¥ÀÌÅͺ£À̽º ÆÄÀÏ¿¡ ÀúÀåÇÏ´Â HTTP Basic + Authentication¿¡¼­ »ç¿ëÇÑ´Ù. ¸ðµâÀ» »ç¿ëÇÏ·Á¸é ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-auth-digest
    +
    mod_auth_digest°¡ Á¦°øÇÏ´Â RFC2617 + Digest authenticationÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº Á¤º¸¸¦ + ÀÏ¹Ý ¹®ÀÚÆÄÀÏ¿¡ ÀúÀåÇÑ´Ù.
    + +
    --enable-authnz-ldap
    +
    mod_authnz_ldapÀÌ Á¦°øÇÏ´Â LDAP±â¹Ý + ÀÎÁõ ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-cache
    +
    mod_cache°¡ Á¦°øÇÏ´Â µ¿ÀûÀ¸·Î »ý¼ºÇÏ´Â + ÆÄÀÏÀÇ Ä³½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¸Å¿ì ºÎÇÏ°¡ ¸¹°Å³ª ÇÁ·Ï½Ã + ¼­¹ö¸¦ ij½ÌÇÏ´Â ¼­¹ö¿¡°Ô ÀÌ ½ÇÇèÀûÀÎ ¸ðµâÀÌ À¯¿ëÇÒ + ¼ö ÀÖ´Ù. ÃÖ¼ÒÇÑ ÇÑ°¡Áö ÀúÀå°ü¸®¸ðµâ(storage management + module)À» (¿¹¸¦ µé¾î, mod_disk_cache³ª + mod_mem_cache) °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-cern-meta
    +
    mod_cern_meta°¡ Á¦°øÇÏ´Â CERN ¸ÞŸÆÄÀÏ + Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-charset-lite
    +
    mod_charset_lite°¡ Á¦°øÇÏ´Â ¹®ÀÚÁýÇÕ + º¯È¯ ±â´ÉÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº EBCDIC ½Ã½ºÅÛ¿¡¼­¸¸ + ±âº»ÀûÀ¸·Î Æ÷ÇԵȴÙ. ´Ù¸¥ ½Ã½ºÅÛ¿¡¼­´Â Á÷Á¢ Æ÷ÇÔ½ÃÄÑÁà¾ß + ÇÑ´Ù.
    + +
    --enable-dav
    +
    mod_dav°¡ Á¦°øÇÏ´Â WebDAV ÇÁ·ÎÅäÄÝ + ó¸® ±â´ÉÀ» »ç¿ëÇÑ´Ù. µ¶¸³µÈ mod_dav_fs + ¸ðµâÀÌ ÆÄÀϽýºÅÛ ÀÚ¿øÀ» Áö¿øÇÑ´Ù. ÀÌ ¸ðµâÀº + --enable-dav¸¦ »ç¿ëÇϸé ÀÚµ¿À¸·Î Æ÷ÇÔÇÑ´Ù.
    + ÁÖÀÇ: mod_dav´Â http + ÇÁ·ÎÅäÄÝ ¸ðµâ°ú °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-dav-fs
    +
    mod_dav_fs°¡ Á¦°øÇÏ´Â DAVÀÇ ÆÄÀϽýºÅÛ + ÀÚ¿ø Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº + mod_dav ¸ðµâÀ» À§ÇÑ Á¦°øÀÚÀ̱⠶§¹®¿¡ + --enable-davµµ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-deflate
    +
    mod_deflate°¡ Á¦°øÇÏ´Â ¾ÐÃàÀü¼Û + ÀÎÄÚµù ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-disk-cache
    +
    mod_disk_cache°¡ Á¦°øÇÏ´Â µð½ºÅ© + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-expires
    +
    mod_expires°¡ Á¦°øÇÏ´Â Expires + Çì´õ Á¶Àý ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-ext-filter
    +
    mod_ext_filter°¡ Á¦°øÇÏ´Â ¿ÜºÎ + ÇÊÅÍ Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-file-cache
    +
    mod_file_cache°¡ Á¦°øÇÏ´Â ÆÄÀÏ + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-headers
    +
    mod_headers°¡ Á¦°øÇÏ´Â HTTP Çì´õ + Á¶Àý ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-info
    +
    mod_info°¡ Á¦°øÇÏ´Â ¼­¹öÁ¤º¸ ±â´ÉÀ» + »ç¿ëÇÑ´Ù.
    + +
    --enable-ldap
    +
    mod_ldapÀÌ Á¦°øÇÏ´Â LDAP ij½Ì°ú + ¿¬°áÇ® ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-logio
    +
    mod_logio°¡ Á¦°øÇÏ´Â ·Î±×¿¡ Çì´õ¿Í + ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·ÏÇÏ´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-mem-cache
    +
    mod_mem_cache°¡ Á¦°øÇÏ´Â ¸Þ¸ð¸® + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-mime-magic
    +
    mod_mime_magicÀÌ Á¦°øÇÏ´Â MIME + type ÀÚµ¿ ÀÎ½Ä ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-isapi
    +
    mod_isapi°¡ Á¦°øÇÏ´Â isapi È®ÀåÀ» + Áö¿øÇÑ´Ù.
    + +
    --enable-proxy
    +
    mod_proxy°¡ Á¦°øÇÏ´Â ÇÁ·Ï½Ã/°ÔÀÌÆ®¿þÀÌ + ±â´ÉÀ» »ç¿ëÇÑ´Ù. CONNECT, FTP, + HTTP¿¡ ´ëÇÑ ÇÁ·Ï½Ã ±â´ÉÀ» °¢°¢ + mod_proxy_connect, + mod_proxy_ftp, + mod_proxy_http + ¸ðµâÀÌ Á¦°øÇÑ´Ù. --enable-proxy¸¦ »ç¿ëÇϸé + ÀÌ ¼¼ ¸ðµâÀ» ÀÚµ¿À¸·Î Æ÷ÇÔÇÑ´Ù.
    + +
    --enable-proxy-connect
    +
    mod_proxy_connect°¡ Á¦°øÇÏ´Â + CONNECT ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» + »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ + È®ÀåÀ̹ǷÎ, --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    + +
    --enable-proxy-ftp
    +
    mod_proxy_ftp°¡ Á¦°øÇÏ´Â + FTP ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ È®ÀåÀ̹ǷÎ, + --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-proxy-http
    +
    mod_proxy_http°¡ Á¦°øÇÏ´Â + HTTP ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ È®ÀåÀ̹ǷÎ, + --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-rewrite
    +
    mod_rewrite°¡ Á¦°øÇÏ´Â ±ÔÄ¢±â¹Ý + URL Á¶ÀÛ ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-so
    +
    mod_so°¡ Á¦°øÇÏ´Â DSO ±â´ÉÀ» »ç¿ëÇÑ´Ù. + --enable-mods-shared ¿É¼ÇÀ» »ç¿ëÇϸé + ÀÚµ¿À¸·Î ÀÌ ¸ðµâÀ» Æ÷ÇÔÇÑ´Ù.
    + +
    --enable-speling
    +
    mod_spellingÀÌ Á¦°øÇÏ´Â URL¿¡¼­ + ÀϹÝÀûÀÎ ¸ÂÃã¹ý ½Ç¼ö¸¦ °íÄ¡´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-ssl
    +
    mod_sslÀÌ Á¦°øÇÏ´Â SSL/TLS ±â´ÉÀ» + »ç¿ëÇÑ´Ù.
    + +
    --enable-unique-id
    +
    mod_unique_id°¡ Á¦°øÇÏ´Â ¿äû¸¶´Ù + À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µå´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-usertrack
    +
    mod_usertrackÀÌ Á¦°øÇÏ´Â »ç¿ëÀÚ¼¼¼Ç + ÃßÀû ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-vhost-alias
    +
    mod_vhost_alias°¡ Á¦°øÇÏ´Â ´ë·® + °¡»óÈ£½ºÆ® ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    +
    + + +

    °³¹ßÀÚ¸¦ À§ÇÑ ¸ðµâ

    +

    ´ÙÀ½ ¸ðµâÀº Å×½ºÆ®¿ëÀ¸·Î °³¹ßÀÚ¿¡°Ô¸¸ À¯¿ëÇϸç, ±âº»ÀûÀ¸·Î + Æ÷ÇÔÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀÌ ÇÊ¿äÇÑÁö È®½ÇÄ¡¾Ê´Ù¸é »ç¿ëÇÏÁö ¸¶¶ó.

    + +
    + +
    --enable-bucketeer
    +
    mod_bucketeer°¡ Á¦°øÇÏ´Â ¹öŶ(bucket) + Á¶ÀÛ ÇÊÅ͸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-case-filter
    +
    mod_case_filterÀÇ ´ë¹®ÀÚº¯È¯ Ãâ·ÂÇÊÅÍ + °ßº»À» »ç¿ëÇÑ´Ù.
    + + +
    --enable-case-filter-in
    +
    mod_case_filter_inÀÇ ´ë¹®ÀÚº¯È¯ ÀÔ·ÂÇÊÅÍ + °ßº»À» »ç¿ëÇÑ´Ù.
    + +
    --enable-echo
    +
    mod_echo°¡ Á¦°øÇÏ´Â ECHO ¼­¹ö¸¦ + »ç¿ëÇÑ´Ù.
    + +
    --enable-example
    +
    °ßº» ¿¹Á¦¸ðµâÀÎ mod_exampleÀ» + »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-fn-export
    +
    mod_optional_fn_export°¡ Á¦°øÇÏ´Â ¼±ÅÃÀûÀÎ + ÇÔ¼ö ¿¢½ºÆ÷Æ®(exporter)ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-fn-import
    +
    mod_optional_fn_import°¡ Á¦°øÇÏ´Â ¼±ÅÃÀûÀÎ + ÇÔ¼ö ÀÓÆ÷Æ®(importer)ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-hook-export
    +
    mod_optional_hook_export°¡ Á¦°øÇÏ´Â + ¼±ÅÃÀûÀÎ ÈÅ(hook) ¿¢½ºÆ÷Æ®ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-hook-import
    +
    mod_optional_hook_import°¡ Á¦°øÇÏ´Â + ¼±ÅÃÀûÀÎ ÈÅ ÀÓÆ÷Æ®ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    +
    + + +

    MPM°ú Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ

    +

    ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÏ¿© ÇÊ¿äÇÑ ´ÙÁß󸮸ðµâ°ú Á¦»ïÀÚ°¡ + ¸¸µç ¸ðµâÀ» Ãß°¡ÇÑ´Ù:

    + +
    +
    --with-module=module-type:module-file +
    +

    Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» Á¤ÀûÀ¸·Î ¸µÅ©ÇÒ ¸ðµâ ¸ñ·Ï¿¡ + Ãß°¡ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö ¼Ò½º Æ®¸®ÀÇ + modules/module-type¿¡¼­ ¸ðµâÀÇ + ¼Ò½ºÆÄÀÏ module-fileÀ» ã±â¶§¹®¿¡ + ±×°÷¿¡ ¼Ò½ºÆÄÀÏÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ±×°÷¿¡ ÆÄÀÏÀÌ ¾ø´Ù¸é + configure´Â module-fileÀÌ + Àý´ëÆÄÀÏ°æ·Î¶ó°í °¡Á¤ÇÏ°í ¼Ò½ºÆÄÀÏÀ» + module-type ÇÏÀ§µð·ºÅ丮¿¡ º¹»çÇÏ·Á°í + ½ÃµµÇÑ´Ù.

    +

    ÀÌ ¿É¼ÇÀº ¼Ò½ºÆÄÀÏÀÌ ÇÑ°³ÀÎ ÀÛÀº ¿ÜºÎ ¸ðµâÀ» Ãß°¡Çϴµ¥ + À¯¿ëÇÏ´Ù. ´õ º¹ÀâÇÑ ¸ðµâÀº °³¹ß»ç°¡ Á¦°øÇÑ ¹®¼­¸¦ + Âü°íÇØ¾ß ÇÑ´Ù.

    +

    ÁÖÀÇ

    + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ¸ðµâÀÌ ¾Æ´Ñ DSO ¸ðµâÀ» ¿øÇÑ´Ù¸é + apxs¸¦ »ç¿ëÇ϶ó.
    +
    + +
    --with-mpm=MPM
    +
    ¼­¹öÀÇ µ¿ÀÛ¹æ½ÄÀ» ¼±ÅÃÇÑ´Ù. Á¤È®È÷ ÇÑ°¡Áö ´ÙÁß󸮸ðµâ¸¸À» ¼±ÅÃÇØ¾ß ÇÑ´Ù. + ¼±ÅÃÇÏÁö ¾ÊÀ¸¸é »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦ÀÇ ±âº» MPMÀ» »ç¿ëÇÑ´Ù. + »ç¿ëÇÒ ¼ö ÀÖ´Â MPM¿¡´Â beos, + leader, mpmt_os2, + perchild, prefork, + threadpool, worker°¡ + ÀÖ´Ù.
    +
    + + +

    ±âŸ ¿É¼Ç

    +
    +
    --enable-maintainer-mode
    +
    µð¹ö±ë ¸ðµå¿Í ÄÄÆÄÀϽà °æ°í¸¦ ÀÛµ¿ÇÑ´Ù.
    + +
    --enable-mods-shared=MODULE-LIST
    +
    +

    µ¿Àû°øÀ¯¸ðµâ·Î ÄÄÆÄÀÏÇÒ ¸ðµâ ¸ñ·ÏÀ» ÁöÁ¤ÇÑ´Ù. Áï, + ÀÌ ¸ðµâµéÀº LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© µ¿ÀûÀ¸·Î Àоîµé¿©¾ß ÇÑ´Ù.

    +

    MODULE-LIST´Â °ø¹éÀ¸·Î ±¸ºÐÇÑ ¸ðµâ¸íµéÀ» + µû¿ÈÇ¥·Î ¹­Àº ¸ñ·ÏÀÌ´Ù. ¸ðµâ¸í¿¡¼­ ¾Õ¿¡ + mod_´Â »«´Ù. ¿¹¸¦ µé¾î:

    +

    + --enable-mods-shared='headers rewrite dav' +

    +

    ¶Ç, Ưº°ÇÑ Å°¿öµå all°ú most¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î,

    +

    + --enable-mods-shared=most +

    +

    ´Â ´ëºÎºÐÀÇ ¸ðµâÀ» DSO ¸ðµâ·Î ÄÄÆÄÀÏÇÑ´Ù. +

    +
    + +
    --enable-modules=MODULE-LIST
    +
    --enable-mods-shared¿Í ºñ½ÁÇÏÁö¸¸, + ÀÌ ¿É¼ÇÀº ¿­°ÅÇÑ ¸ðµâµéÀ» Á¤ÀûÀ¸·Î ¸µÅ©ÇÑ´Ù. Áï, ÀÌ + ¸ðµâµéÀº httpd ½ÇÇàÇÏ¸é ¾ðÁ¦³ª »ç¿ëÇÒ + ¼ö ÀÖ´Ù. LoadModule·Î ÀоîµéÀÏ + ÇÊ¿ä°¡ ¾ø´Ù.
    + +
    --enable-v4-mapped
    +
    IPv6 ¼ÒÄÏÀÌ IPv4 ¿¬°áÀ» ó¸®ÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù.
    + +
    --with-port=PORT
    +
    httpd°¡ ±â´Ù¸± Æ÷Æ®¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ + Æ÷Æ®¹øÈ£´Â ¼³Á¤ÆÄÀÏ httpd.conf¸¦ ¸¸µé¶§ + ¾²ÀδÙ. ±âº»°ªÀº 80ÀÌ´Ù.
    + +
    --with-program-name
    +
    ´Ù¸¥ ½ÇÇàÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + httpdÀÌ´Ù.
    +
    + + + +

    Ãß°¡ ÆÐÅ°Áö ¼±ÅÃ

    +

    ´ÙÀ½ ¿É¼ÇÀº Ãß°¡ ÆÐÅ°Áö¸¦ ¼±ÅÃÇÑ´Ù.

    + +

    ÀϹÝÀûÀÎ ¹®¹ý

    +

    ÀϹÝÀûÀ¸·Î ´ÙÀ½°ú °°Àº ¹®¹ýÀ» »ç¿ëÇÏ¿© Ãß°¡ ÆÐÅ°Áö¸¦ + ´Ù·é´Ù:

    + +
    +
    --with-PACKAGE[=ARG]
    +
    ÆÐÅ°Áö PACKAGE¸¦ »ç¿ëÇÑ´Ù. + ARGÀÇ ±âº»°ªÀº yesÀÌ´Ù.
    + +
    --without-PACKAGE
    +
    ÆÐÅ°Áö PACKAGE¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + --with-PACKAGE=no¿Í °°´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í´Â + °ü°è°¡ ¾ø´Ù.
    +
    + + + + +

    ƯÁ¤ ÆÐÅ°Áö

    +
    +
    --with-apr=DIR|FILE
    +
    httpd ¼Ò½º ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ Apache Portable + Runtime (APR)Àº ÀÚµ¿À¸·Î À¥¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵȴÙ. + ¸¸¾à ÀÌ¹Ì ¼³Ä¡µÈ APRÀ» ´ë½Å »ç¿ëÇÏ°í ½Í´Ù¸é + configure¿¡°Ô apr-config + ½ºÅ©¸³Æ®ÀÇ °æ·Î¸¦ ¾Ë·ÁÁÖ¾î¾ß ÇÑ´Ù. APR°¡ ¼³Ä¡µÈ Àý´ë°æ·Î, + ÆÄÀϸí, µð·ºÅ丮¸íÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ µð·ºÅ丮³ª + ±× µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 bin¿¡ + apr-config°¡ ÀÖ¾î¾ß ÇÑ´Ù.
    + +
    --with-apr-util=DIR|FILE
    +
    httpd ¼Ò½º ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ Apache Portable + Runtime Utilities (APU)´Â ÀÚµ¿À¸·Î À¥¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀϵȴÙ. ¸¸¾à ÀÌ¹Ì ¼³Ä¡µÈ APUÀ» ´ë½Å »ç¿ëÇÏ°í ½Í´Ù¸é + configure¿¡°Ô apu-config + ½ºÅ©¸³Æ®ÀÇ °æ·Î¸¦ ¾Ë·ÁÁÖ¾î¾ß ÇÑ´Ù. APU°¡ ¼³Ä¡µÈ Àý´ë°æ·Î, + ÆÄÀϸí, µð·ºÅ丮¸íÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ µð·ºÅ丮³ª + ±× µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 bin¿¡ + apu-config°¡ ÀÖ¾î¾ß ÇÑ´Ù.
    + +
    --with-ssl=DIR
    +
    mod_sslÀ» »ç¿ëÇÏ´Â °æ¿ì + configure´Â ¼³Ä¡µÈ OpenSSLÀ» ã´Â´Ù. + ´ë½Å ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¿© SSL/TLS µµ±¸ÀÇ µð·ºÅ丮°æ·Î¸¦ + ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.
    + +
    --with-z=DIR
    +
    (mod_deflate¸¦ »ç¿ëÇÏ´Â °æ¿ì¿Í + °°ÀÌ) ±¸¼º¿¡ ÇÊ¿äÇÏ´Ù¸é ÀÚµ¿À¸·Î configure´Â + ¼³Ä¡µÈ zlib ¶óÀ̺귯¸®¸¦ ã´Â´Ù. ´ë½Å + ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÐÃà ¶óÀ̺귯¸®ÀÇ µð·ºÅ丮°æ·Î¸¦ + ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.
    +
    + +

    mod_authn_dbm°ú + mod_rewriteÀÇ DBM RewriteMap °°Àº ¾ÆÆÄÄ¡ + À¥¼­¹öÀÇ ÀϺΠ±â´ÉÀº Á¤º¸¸¦ »¡¸® ã±âÀ§ÇØ °£´ÜÇÑ Å°/°ª + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÑ´Ù. APU¿¡ SDBMÀÌ µé¾îÀ־ ¾ðÁ¦³ª + ÃÖ¼ÒÇÑ ÀÌ µ¥ÀÌÅͺ£À̽º´Â »ç¿ëÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ Á¾·ùÀÇ + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÏ°í ½Í´Ù¸é ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù:

    + +
    +
    --with-gdbm[=path]
    +
    path¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é, + configure´Â ÀϹÝÀûÀÎ °Ë»ö°æ·Î¿¡¼­ ¼³Ä¡µÈ + GNU DBM Çì´õÆÄÀÏ°ú ¶óÀ̺귯¸®¸¦ ã´Â´Ù. Á÷Á¢ + path¸¦ ÁöÁ¤Çϸé configure´Â + path/lib°ú + path/include¿¡¼­ ÇÊ¿äÇÑ ÆÄÀÏÀ» + ã´Â´Ù. ¸¶Áö¸·À¸·Î path¿¡ Çì´õÆÄÀÏ °æ·Î¿Í + ¶óÀ̺귯¸® °æ·Î¸¦ ÄÝ·ÐÀ» »çÀÌ¿¡ µÎ°í °°ÀÌ ÀûÀ» ¼ö + ÀÖ´Ù.
    + +
    --with-ndbm[=path]
    +
    --with-gdbm°ú °°Áö¸¸ ¼³Ä¡µÈ New DBMÀ» + ã´Â´Ù.
    + +
    --with-berkeley-db[=path]
    +
    --with-gdbm°ú °°Áö¸¸ ¼³Ä¡µÈ Berkeley + DB¸¦ ã´Â´Ù.
    +
    + +

    ÁÖÀÇ

    +

    DBM ¿É¼ÇÀº APU°¡ Á¦°øÇϸç APU ±¸¼º½ºÅ©¸³Æ®·Î Á÷Á¢ + Àü´ÞµÈ´Ù. ±×·¡¼­ --with-apr-utilÀ» »ç¿ëÇÏ¿© + ÀÌ¹Ì ¼³Ä¡µÈ APU¸¦ »ç¿ëÇÑ´Ù¸é DBM ¿É¼ÇÀº ¼Ò¿ëÀÌ ¾ø´Ù.

    +

    À¥¼­¹ö´Â ¿©·¯ DBM ±¸ÇöÀ» °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ½ÇÇà½Ã + ÀûÀýÇÑ DBM Á¾·ù¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    +
    + + + +

    Áö¿ø ÇÁ·Î±×·¥À» À§ÇÑ ¿É¼Ç

    +
    +
    --enable-static-support
    +
    Áö¿ø ÇÁ·Î±×·¥À» Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ¸¸µç´Ù. + Áï, ÇÊ¿äÇÑ ¶óÀ̺귯¸®¸¦ ¸ðµÎ Æ÷ÇÔÇϵµ·Ï ½ÇÇàÆÄÀÏÀ» + ÄÄÆÄÀÏÇÑ´Ù. ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏÁö ¾ÊÀ¸¸é ±âº»°ªÀ¸·Î Áö¿ø + ÇÁ·Î±×·¥À» µ¿ÀûÀ¸·Î ¸µÅ©ÇÑ´Ù.
    + +
    --enable-suexec
    +
    À¥¼­¹ö°¡ ½ÇÇàÇÏ´Â ÇÁ·Î¼¼½ºÀÇ uid¿Í gid¸¦ ¼³Á¤ÇÏ´Â + suexec¸¦ »ç¿ëÇÏ·Á¸é + ÀÌ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. suid ½ÇÇàÆÄÀÏÀÇ º¸¾È»ó À§ÇèÀ» + ¸ðµÎ ¾ËÁö ¸øÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏÁö ¸¶¶ó. + suexec¸¦ ±¸¼ºÇÏ´Â ¿É¼ÇÀº + ¾Æ·¡¿¡¼­ ¼³¸íÇÑ´Ù.
    +
    + +

    ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÏ¿© Áö¿ø ÇÁ·Î±×·¥º°·Î Á¤ÀûÀ¸·Î ¸µÅ©µÈ + ½ÇÇàÆÄÀÏÀ» ¸¸µé ¼ö ÀÖ´Ù:

    + +
    +
    --enable-static-ab
    +
    ab¸¦ Á¤ÀûÀ¸·Î ¸µÅ©µÈ + ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + + +
    --enable-static-checkgid
    +
    checkgid¸¦ Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î + ÄÄÆÄÀÏÇÑ´Ù.
    + + +
    --enable-static-htdbm
    +
    htdbmÀ» Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î + ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-htdigest
    +
    htdigest¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-htpasswd
    +
    htpasswd¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-logresolve
    +
    logresolve¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-rotatelogs
    +
    rotatelogs¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    +
    + +

    suexec ¼³Á¤ ¿É¼Ç

    +

    ¾Æ·¡ ¿É¼ÇÀº suexec¸¦ ÀÚ¼¼È÷ ¼³Á¤ÇÑ´Ù. + ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â suEXEC + ±¸¼º°ú ¼³Ä¡¸¦ Âü°íÇ϶ó.

    + +
    +
    --with-suexec-bin
    +
    suexec ½ÇÇàÆÄÀÏÀÇ °æ·Î¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + --sbindirÀÌ´Ù (¼³Ä¡ µð·ºÅ丮ÀÇ ÀÚ¼¼ÇÑ + Á¶Á¤ Âü°í).
    + +
    --with-suexec-caller
    +
    suexec¸¦ ½ÇÇàÇÒ »ç¿ëÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. + ÀÌ »ç¿ëÀÚ´Â º¸Åë httpd¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿Í + °°¾Æ¾ß ÇÑ´Ù.
    + +
    --with-suexec-docroot
    +
    suexec´Â ÀÌ ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ µð·ºÅ丮 + ¾Æ·¡¿¡ ÀÖ´Â ½ÇÇàÆÄÀϸ¸À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº + --datadir/htdocs´Ù.
    + +
    --with-suexec-gidmin
    +
    suexec¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ÃÖ¼Ò GID¸¦ ¼³Á¤ÇÑ´Ù. + ±âº»°ªÀº 100ÀÌ´Ù.
    + +
    --with-suexec-logfile
    +
    suexec ·Î±×ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ·Î±×ÆÄÀϸíÀÇ + ±âº»°ªÀº suexec_logÀÌ°í, + --logfiledir¿¡ À§Ä¡ÇÑ´Ù.
    + +
    --with-suexec-safepath
    +
    suexec°¡ ½ÃÀÛÇÏ´Â ÇÁ·Î¼¼½ºÀÇ + PATH ȯ°æº¯¼ö°ªÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + /usr/local/bin:/usr/bin:/binÀÌ´Ù.
    + +
    --with-suexec-userdir
    +
    »ç¿ëÀÚ µð·ºÅ丮¿¡¼­ suexec°¡ Á¢±ÙÇÒ + ¼ö ÀÖ´Â (½ÇÇàÆÄÀÏÀÌ ÀÖ´Â) ÇÏÀ§µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. + ÀÌ ¼³Á¤Àº suexec¿Í + (mod_userdirÀÌ Á¦°øÇÏ´Â) »ç¿ëÀÚº° + µð·ºÅ丮¸¦ °°ÀÌ »ç¿ëÇÒ¶§ ÇÊ¿äÇÏ´Ù. ±âº»°ªÀº + public_htmlÀÌ´Ù.
    + +
    --with-suexec-uidmin
    +
    suexec¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ÃÖ¼Ò UID¸¦ ¼³Á¤ÇÑ´Ù. + ±âº»°ªÀº 100ÀÌ´Ù.
    + +
    --with-suexec-umask
    +
    suexec°¡ ½ÇÇàÇÏ´Â ÇÁ·Î¼¼½ºÀÇ + umask¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ + ±âº» ¼³Á¤°ú °°´Ù.
    +
    + + +
    top
    +
    +

    ȯ°æº¯¼ö

    +

    configureÀÇ ¼±ÅÃÀ» ¹«½ÃÇϰųª °ü·Ê¿Í ´Ù¸¥ + À̸§À̳ª À§Ä¡¿¡ ÀÖ´Â ¶óÀ̺귯¸®¿Í ÇÁ·Î±×·¥À» ãµµ·Ï µµ¿ÍÁÖ´Â + À¯¿ëÇÑ È¯°æº¯¼öµéÀÌ ÀÖ´Ù.

    + + +
    +
    CC
    +
    ÄÄÆÄÀÏ¿¡ »ç¿ëÇÒ C ÄÄÆÄÀÏ·¯ ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    CFLAGS
    +
    ÄÄÆÄÀ϶§ »ç¿ëÇÏ±æ ¹Ù¶ó´Â C ÄÄÆÄÀÏ·¯ ¿É¼ÇÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    CPP
    +
    »ç¿ëÇÒ C ¼±Ã³¸®±â ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    CPPFLAGS
    +
    C/C++ ¼±Ã³¸®±â ¿É¼Ç. ¿¹¸¦ µé¾î, Çì´õÆÄÀÏÀÌ °ü·Ê¿Í ´Þ¸® + includedir µð·ºÅ丮¿¡ ÀÖ´Ù¸é + -IincludedirÀ» »ç¿ëÇÑ´Ù.
    + +
    LDFLAGS
    +
    ¸µÄ¿ ¿É¼Ç. ¿¹¸¦ µé¾î, ¶óÀ̺귯¸®°¡ °ü·Ê¿Í ´Þ¸® + libdir µð·ºÅ丮¿¡ ÀÖ´Ù¸é + -LlibdirÀ» »ç¿ëÇÑ´Ù.
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/configure.xml b/trunk/docs/manual/programs/configure.xml new file mode 100644 index 0000000000..4fbda1a72e --- /dev/null +++ b/trunk/docs/manual/programs/configure.xml @@ -0,0 +1,947 @@ + + + + + + + + +Programs + + configure - Configure the source tree + + +

    The configure script configures the source tree + for compiling and installing the Apache HTTP Server on your + particular platform. Various options allow the compilation of a + server corresponding to your personal requirements.

    + +

    This script, included in the root directory of the source + distribution, is for compilation on Unix and Unix-like systems + only. For other platforms, see the platform documentation.

    +
    + +Compiling and Installing + +
    Synopsis +

    You should call the configure script from within the + root directory of the distribution.

    + +

    ./configure [OPTION]... + [VAR=VALUE]...

    + +

    To assign environment variables (e.g. CC, + CFLAGS ...), specify them as + VAR=VALUE. See below + for descriptions of some of the useful variables.

    +
    + +
    Options + + +
    Configuration options + +

    The following options influence the behavior of + configure itself.

    + +
    +
    -C
    +
    --config-cache
    +
    This is an alias for --cache-file=config.cache
    + +
    --cache-file=FILE
    +
    The test results will be cached in file FILE. + This option is disabled by default.
    + +
    -h
    +
    --help [short|recursive]
    +
    Output the help and exit. With the argument short only + options specific to this package will displayed. The argument + recursive displays the short help of all the included + packages.
    + +
    -n
    +
    --no-create
    +
    The configure script is run normally but does + not create output files. This is useful to check the test results + before generating makefiles for compilation.
    + +
    -q
    +
    --quiet
    +
    Do not print checking ... messages during the + configure process.
    + +
    --srcdir=DIR
    +
    Defines directory DIR to be the source file directory. + Default is the directory, where configure is located, or the parent + directory ...
    + +
    --silent
    +
    Same as --quiet
    + +
    -V
    +
    --version
    +
    Display copyright information and exit.
    +
    +
    + +
    Installation + directories + +

    These options define the installation directory. The installation + tree depends on the selected layout.

    + +
    +
    --prefix=PREFIX
    +
    Install architecture-independent files in PREFIX. + By default the installation directory is set to + /usr/local/apache2.
    + +
    --exec-prefix=EPREFIX
    +
    Install architecture-dependent files in EPREFIX. + By default the installation directory is set to the + PREFIX directory.
    +
    + +

    By default, make install will install all the files in + /usr/local/apache2/bin, /usr/local/apache2/lib + etc. You can specify an installation prefix other than + /usr/local/apache2 using --prefix, + for instance --prefix=$HOME.

    + +
    Define a directory layout +
    +
    --enable-layout=LAYOUT
    +
    Configure the source code and build scripts to assume an + installation tree based on the layout LAYOUT. This allows + you to separately specify the locations for each type of file within + the Apache HTTP Server installation. The config.layout + file contains several example configurations, and you can also create + your own custom configuration following the examples. The different + layouts in this file are grouped into <Layout + FOO>...</Layout> sections and referred to by name as + in FOO. The default layout is Apache.
    +
    +
    + +
    Fine tuning of the installation + directories + +

    For better control of the installation directories, use the options + below. Please note that the directory defaults are set by + autoconf and be overwritten by the corresponding layout + setting.

    + +
    + +
    --bindir=DIR
    +
    Install user executables in DIR. The user executables + are supporting programs like htpasswd, + dbmmanage, etc. which are useful for site + administrators. By default DIR is set to + EPREFIX/bin.
    + +
    --datadir=DIR
    +
    Install read-only architecture-independent data in DIR. + By default datadir is set to + PREFIX/share. This option is offered by + autoconf and currently unused.
    + +
    --includedir=DIR
    +
    Install C header files in DIR. By default + includedir is set to + EPREFIX/include.
    + +
    --infodir=DIR
    +
    Install info documentation in DIR. + By default infodir is set to + PREFIX/info. This option is currently + unused.
    + +
    --libdir=DIR
    +
    Install object code libraries in DIR. By default + libdir is set to + EPREFIX/lib.
    + +
    --libexecdir=DIR
    +
    Install the program executables (i.e., shared modules) in + DIR. By default libexecdir is set to + EPREFIX/libexec.
    + +
    --localstatedir=DIR
    +
    Install modifiable single-machine data in DIR. + By default localstatedir is set to + PREFIX/var. This option is offered by + autoconf and currently unused.
    + +
    --mandir=DIR
    +
    Install the man documentation in DIR. By default + mandir is set to + EPREFIX/man.
    + +
    --oldincludedir=DIR
    +
    Install C header files for non-gcc in DIR. + By default oldincludedir is set to + /usr/include. This option is offered by + autoconf and currently unused.
    + +
    --sbindir=DIR
    +
    Install the system administrator executables in DIR. + Those are server programs like httpd, + apachectl, suexec, etc. which + are neccessary to run the Apache HTTP Server. By default + sbindir is set to + EPREFIX/sbin.
    + +
    --sharedstatedir=DIR
    +
    Install modifiable architecture-independent data in DIR. + By default sharedstatedir is set to + PREFIX/com. This option is offered by + autoconf and currently unused.
    + +
    --sysconfdir=DIR
    +
    Install read-only single-machine data like the server configuration + files httpd.conf, mime.types, etc. in + DIR. By default sysconfdir is set to + PREFIX/etc.
    +
    +
    +
    + +
    System types + +

    These options are used to cross-compile the Apache HTTP Server to run on + another system. In normal cases, when building and running the server on + the same system, these options are not used.

    + +
    +
    --build=BUILD
    +
    Defines the system type of the system on which the tools are being + built. It defaults to the result of the script + config.guess.
    + +
    --host=HOST
    +
    Defines the system type of the system on which the server will run. + HOST defaults to BUILD.
    + +
    --target=TARGET
    +
    Configure for building compilers for the system type + TARGET. It defaults to HOST. This option is + offered by autoconf and not necessary for the Apache HTTP + Server.
    +
    +
    + +
    Optional Features + +

    These options are used to fine tune the features your HTTP server will + have.

    + +
    General syntax +

    Generally you can use the following syntax to enable or disable a + feature:

    + +
    +
    --disable-FEATURE
    +
    Do not include FEATURE. This is the same as + --enable-FEATURE=no.
    + +
    --enable-FEATURE[=ARG]
    +
    Include FEATURE. The default value for ARG + is yes.
    + +
    --enable-MODULE=shared
    +
    The corresponding module will be build as DSO module.
    + +
    --enable-MODULE=static
    +
    By default enabled modules are linked statically. You can force + this explicitly.
    +
    + + Note + configure will not complain about + --enable-foo even if foo doesn't + exist, so you need to type carefully. + +
    + + +
    Modules enabled by default +

    Some modules are compiled by default and have to be disabled + explicitly. Use the following options to remove discrete modules from + the compilation process.

    + +
    +
    --disable-actions
    +
    Disable action triggering on requests, which is provided by + mod_actions.
    + +
    --disable-alias
    +
    Disable the mapping of requests to different parts of the + filesystem, which is provided by mod_alias.
    + +
    --disable-asis
    +
    Disable support for as-is filetypes, which is provided by + mod_asis.
    + +
    --disable-auth
    +
    Disable user-based access control provided by + mod_auth. This module provides for HTTP Basic + Authentication, where the usernames and passwords are stored in + plain text files.
    + +
    --disable-autoindex
    +
    Disable the directory listing functionality provided by + mod_autoindex.
    + +
    --disable-access
    +
    Disable host-based access control provided by + mod_access.
    + +
    --disable-cgi
    +
    mod_cgi, which provides support for CGI scripts, + is enabled by default when using a non-threaded MPM. Use this + option to disable CGI support.
    + +
    --disable-cgid
    +
    When using the threaded MPMs worker or + perchild support for CGI scripts is provided by + mod_cgid by default. To disable CGI support use + this option.
    + +
    --disable-charset-lite
    +
    Disable character set translation provided by + mod_charset_lite. This module will be installed by + default only on EBCDIC systems.
    + +
    --disable-dir
    +
    Disable directory request handling provided by + mod_dir.
    + +
    --disable-env
    +
    Enable setting and clearing of environment variables, which is + provided by mod_env.
    + + +
    --disable-http
    +
    Disable the HTTP protocol handling. The http + module is a basic one, enabling the server to function as an + HTTP server. It is only useful to disable it if you want to use + another protocol module instead. Don't disable this + module unless you are really sure what you are doing. +
    + Note: This module will always be linked statically.
    + +
    --disable-imagemap
    +
    Disable support for server based imagemaps, which provided by + mod_imagemap.
    + +
    --disable-include
    +
    Disable Server Side Includes provided by + mod_include.
    + +
    --disable-log-config
    +
    Disable the logging configuration provided by + mod_log_config. You won't be able to log requests + to the server without this module.
    + +
    --disable-mime
    +
    mod_mime associates the requested filename's + extensions with the file's behavior and content (mime-type, + language, character set and encoding). Disabling the mapping of + file-extensions to MIME is normally not recommended.
    + +
    --disable-negotiation
    +
    Disable content negotiation provided by + mod_negotiation.
    + +
    --disable-setenvif
    +
    Disable support for basing environment variables on headers, + which is provided by mod_setenvif.
    + +
    --disable-status
    +
    Enable the process/thread monitoring, which is provided by + mod_status.
    + +
    --disable-userdir
    +
    Disable the mapping of requests to user-specific directories, + which is provided by mod_userdir.
    +
    +
    + +
    Modules, disabled by default +

    Some modules are compiled by default and have to be enabled + explicitly or by using the keywords most or + all (see --enable-mods-shared below for + further explanation) to be available. Therefore use the options + below.

    + +
    +
    --enable-auth-anon
    +
    Enable anonymous user access provided by + mod_auth_anon.
    + +
    --enable-auth-dbm
    +
    mod_auth_dbm provides for HTTP Basic + Authentication, where the usernames and passwords are stored in DBM + type database files. Use this option to enable the module.
    + +
    --enable-auth-digest
    +
    Enable RFC2617 Digest authentication provided by + mod_auth_digest. This module uses plain text files + to store the credentials.
    + +
    --enable-authnz-ldap
    +
    Enable LDAP based authentication provided by + mod_authnz_ldap.
    + +
    --enable-cache
    +
    Enable dynamic file caching provided by + mod_cache. This experimental module may be + interesting for servers with high load or caching proxy servers. At + least one storage management module (e.g. + mod_disk_cache or mod_mem_cache) + is also necessary.
    + +
    --enable-cern-meta
    +
    Enable the CERN-type meta files support provided by + mod_cern_meta.
    + +
    --enable-charset-lite
    +
    Enable character set translation provided by + mod_charset_lite. This module will be installed by + default only on EBCDIC systems. On other systems, you have to enable + it.
    + +
    --enable-dav
    +
    Enable the WebDAV protocol handling provided by + mod_dav. Support for filesystem resources is + provided by the seperate module mod_dav_fs. This + module is also automatically enabled with + --enable-dav.
    + Note: mod_dav can only be used together with the + http protocol module.
    + +
    --enable-dav-fs
    +
    Enable DAV support for filesystem resources, which is provided by + mod_dav_fs. This module is a provider for the + mod_dav module, so you should also use + --enable-dav.
    + +
    --enable-dav-lock
    +
    Enable mod_dav_lock which provides generic DAV + locking support for backend modules. This module needs at least + mod_dav to function, so you should also use + --enable-dav.
    + +
    --enable-deflate
    +
    Enable deflate transfer encoding provided by + mod_deflate.
    + +
    --enable-disk-cache
    +
    Enable disk caching provided by + mod_disk_cache.
    + +
    --enable-expires
    +
    Enable Expires header control provided by + mod_expires.
    + +
    --enable-ext-filter
    +
    Enable the external filter support provided by + mod_ext_filter.
    + +
    --enable-file-cache
    +
    Enable the file cache provided by + mod_file_cache.
    + +
    --enable-headers
    +
    Enable control of HTTP headers provided by + mod_headers.
    + +
    --enable-info
    +
    Enable the server information provided by + mod_info.
    + +
    --enable-ldap
    +
    Enable LDAP caching and connection pooling services provided by + mod_ldap.
    + +
    --enable-logio
    +
    Enable logging of input and output bytes including headers provided + by mod_logio.
    + +
    --enable-mem-cache
    +
    Enable memory caching provided by + mod_mem_cache.
    + +
    --enable-mime-magic
    +
    Enable automatical determining of MIME types, which is provided by + mod_mime_magic.
    + +
    --enable-isapi
    +
    Enable the isapi extension support provided by + mod_isapi.
    + +
    --enable-proxy
    +
    Enable the proxy/gateway functionality provided by + mod_proxy. The proxying capabilities for + AJP13, CONNECT, FTP, + HTTP and the balancer are provided by the seperate + modules mod_proxy_ajp, + mod_proxy_connect, mod_proxy_ftp, + mod_proxy_http and + mod_proxy_balancer. + These five modules are also automatically enabled with + --enable-proxy.
    + +
    --enable-proxy-ajp
    +
    Enable proxy support for AJP13 (Apache JServ Protocol 1.3) + request handling, which is provided by mod_proxy_ajp. + This module is an extension for the mod_proxy module, + so you should also use --enable-proxy.
    + +
    --enable-proxy-balancer
    +
    Enable load balancing support for the AJP13, + FTP and HTTP protocols, which is provided by + mod_proxy_balancer. This module is an extension for the + mod_proxy module, so you should also use + --enable-proxy.
    + +
    --enable-proxy-connect
    +
    Enable proxy support for CONNECT request handling, + which is provided by mod_proxy_connect. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-proxy-ftp
    +
    Enable proxy support for FTP requests, which is + provided by mod_proxy_ftp. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-proxy-http
    +
    Enable proxy support for HTTP requests, which is + provided by mod_proxy_http. This module + is an extension for the mod_proxy module, so you + should also use --enable-proxy.
    + +
    --enable-rewrite
    +
    Enable rule based URL manipulation provided by + mod_rewrite.
    + +
    --enable-so
    +
    Enable DSO capability provided by mod_so. This + module will be automatically enabled if you use the + --enable-mods-shared option.
    + +
    --enable-speling
    +
    Enable the functionality to correct common URL misspellings, which + is provided by mod_speling.
    + +
    --enable-ssl
    +
    Enable support for SSL/TLS provided by + mod_ssl.
    + +
    --enable-unique-id
    +
    Enable the generation of per-request unique ids, which is provided + by mod_unique_id.
    + +
    --enable-usertrack
    +
    Enable user-session tracking provided by + mod_usertrack.
    + +
    --enable-vhost-alias
    +
    Enable mass virtual hosting provided by + mod_vhost_alias.
    +
    +
    + +
    Modules for developers +

    The following modules are useful only for developers and testing + purposes and are disabled by default. Use the following options to + enable them. If you are not sure whether you need one of these + modules, omit them.

    + +
    + +
    --enable-bucketeer
    +
    Enable the manipulation filter for buckets, which is provided by + mod_bucketeer.
    + + +
    --enable-case-filter
    +
    Enable the example uppercase conversion output filter support of + mod_case_filter.
    + + +
    --enable-case-filter-in
    +
    Enable the example uppercase conversion input filter support of + mod_case_filter_in.
    + +
    --enable-echo
    +
    Enable the ECHO server provided by + mod_echo.
    + +
    --enable-example
    +
    Enable the example and demo module + mod_example.
    + + +
    --enable-optional-fn-export
    +
    Enable the example for an optional function exporter, which is + provided by mod_optional_fn_export.
    + + +
    --enable-optional-fn-import
    +
    Enable the example for an optional function importer, which is + provided by mod_optional_fn_import.
    + + +
    --enable-optional-hook-export
    +
    Enable the example for an optional hook exporter, which is provided + by mod_optional_hook_export.
    + + +
    --enable-optional-hook-import
    +
    Enable the example optional hook importer, which is provided by + mod_optional_hook_import.
    +
    +
    + +
    MPMs and third-party modules +

    To add the necessary Multi Processing Module and additional third-party + modules use the following options:

    + +
    +
    --with-module=module-type:module-file[, + module-type:module-file]
    +

    Add one or more third-party modules to the list of statically linked + modules. The module source file module-file + will be searched in the modules/module-type + subdirectory of your Apache HTTP server source tree. If it is not found + there configure is considering module-file to be + an absolute file path and tries to copy the source file into the + module-type subdirectory. If the subdirectory doesn't + exist it will be created and populated with a standard + Makefile.in.

    +

    This option is useful to add small external modules consisting of + one source file. For more complex modules you should read the + vendor's documentation.

    + Note + If you want to build a DSO module instead of a statically linked + use apxs. +
    + +
    --with-mpm=MPM
    +
    Choose the process model for your server. You have to select + exactly one Multi-Processing Module. + Otherwise the default MPM for + your operating system will be taken. Possible MPMs are + beos, leader, + mpmt_os2, perchild, + prefork, threadpool and + worker.
    +
    +
    + +
    Cumulative and other options +
    +
    --enable-maintainer-mode
    +
    Turn on debugging and compile time warnings.
    + +
    --enable-mods-shared=MODULE-LIST
    +
    +

    Defines a list of modules to be enabled and build as dynamic + shared modules. This mean, these module have to be loaded + dynamically by using the LoadModule directive.

    +

    MODULE-LIST is a space separated list of modulenames + enclosed by quotation marks. The module names are given without the + preceding mod_. For example:

    + + --enable-mods-shared='headers rewrite dav' + +

    Additionally you can use the special keywords all and + most. For example,

    + + --enable-mods-shared=most + +

    will compile most modules and build them as DSO modules. +

    +
    + +
    --enable-modules=MODULE-LIST
    +
    This option behaves similar to --enable-mods-shared, + but will link the given modules statically. This mean, these modules + will always be present while running httpd. They need + not be loaded with LoadModule.
    + +
    --enable-v4-mapped
    +
    Allow IPv6 sockets to handle IPv4 connections.
    + +
    --with-port=PORT
    +
    This defines the port on which httpd will listen. + This port number is used when generating the configuration file + httpd.conf. The default is 80.
    + +
    --with-program-name
    +
    Define an alternative executable name. The default is + httpd.
    +
    +
    +
    + +
    Optional packages +

    These options are used to define optional packages.

    + +
    General syntax +

    Generally you can use the following syntax to define an optional + package:

    + +
    +
    --with-PACKAGE[=ARG]
    +
    Use the package PACKAGE. The default value for + ARG isyes.
    + +
    --without-PACKAGE
    +
    Do not use the package PACKAGE. This is the same as + --with-PACKAGE=no. This option is provided by + autoconf but not very useful for the Apache HTTP + Server.
    +
    +
    + + + +
    Specific packages +
    +
    --with-apr=DIR|FILE
    +
    The Apache Portable Runtime (APR) is part of the httpd + source distribution and will automatically be build together with the + HTTP server. If you want to use an already installed APR instead you + have to tell configure the path to the + apr-config script. You may set the absolute path and name + or the directory to the installed APR. apr-config must + exists within this directory or the subdirectory + bin.
    + +
    --with-apr-util=DIR|FILE
    +
    The Apache Portable Runtime Utilities (APU) are part of the + httpd source distribution and will automatically be build + together with the HTTP server. If you want to use an already installed + APU instead you have to tell configure the path to the + apu-config script. You may set the absolute path and name + or the directory to the installed APU. apu-config must + exists within this directory or the subdirectory + bin.
    + +
    --with-ssl=DIR
    +
    If mod_ssl has been enabled configure + searches for an installed OpenSSL. You can set the directory path + to the SSL/TLS toolkit instead.
    + +
    --with-z=DIR
    +
    configure searches automatically for an installed + zlib library if your source configuration requires one + (e.g., when mod_deflate is enabled). You can set the + directory path to the compression library instead.
    +
    + +

    Several features of the Apache HTTP Server, including + mod_authn_dbm and mod_rewrite's DBM + RewriteMap use simple + key/value databases for quick lookups of information. SDBM is included + in the APU, so this database is always available. If you would like to + use other database types, use the following options to enable + them:

    + +
    +
    --with-gdbm[=path]
    +
    If no path is specified, configure will + search for the include files and libraries of a GNU DBM + installation in the usual search paths. An explicit + path will cause configure to look in + path/lib and + path/include for the relevant files. + Finally, the path may specify specific include and + library paths separated by a colon.
    + +
    --with-ndbm[=path]
    +
    Like --with-gdbm, bur searches for a New DBM + installation.
    + +
    --with-berkeley-db[=path]
    +
    Like --with-gdbm, but searches for a Berkeley DB + installation.
    +
    + + Note +

    The DBM options are provided by the APU and passed through to its + configuration script. They are useless when using an already + installed APU defined by --with-apr-util.

    +

    You may use more then one DBM implementation together with your + HTTP server. The appropriated DBM type will be configured within + the runtime configuration at each time.

    +
    +
    +
    + +
    Options for support programs +
    +
    --enable-static-support
    +
    Build a statically linked version of the support binaries. This + means, a stand-alone executable will be built with all the necessary + libraries integrated. Otherwise the support binaries are linked + dynamically by default.
    + +
    --enable-suexec
    +
    Use this option to enable + suexec, which allows you to set + uid and gid for spawned processes. Do not use this + option unless you understand all the security implications of + running a suid binary on your server. Further options + to configure suexec are described below.
    + +

    It is possible to create a statically linked binary of a single + support program by using the following options:

    + +
    +
    --enable-static-ab
    +
    Build a statically linked version of + ab.
    + + +
    --enable-static-checkgid
    +
    Build a statically linked version of checkgid.
    + +
    --enable-static-htdbm
    +
    Build a statically linked version of + htdbm.
    + +
    --enable-static-htdigest
    +
    Build a statically linked version of + htdigest.
    + +
    --enable-static-htpasswd
    +
    Build a statically linked version of + htpasswd.
    + +
    --enable-static-logresolve
    +
    Build a statically linked version of + logresolve.
    + +
    --enable-static-rotatelogs
    +
    Build a statically linked version of + rotatelogs.
    +
    + +
    suexec configuration options +

    The following options are used to fine tune the behavior of + suexec. See Configuring and installing suEXEC + for further information.

    + +
    +
    --with-suexec-bin
    +
    This defines the path to suexec binary. Default is + --sbindir (see Fine + tuning of installation directories).
    + +
    --with-suexec-caller
    +
    This defines the user allowed to call suexec. + It should be the same as the user under which httpd + normally runs.
    + +
    --with-suexec-docroot
    +
    This defines the directory tree under which + suexec access is allowed for executables. Default value is + --datadir/htdocs.
    + +
    --with-suexec-gidmin
    +
    Define this as the lowest GID allowed to be a target user for + suexec. The default value is 100.
    + +
    --with-suexec-logfile
    +
    This defines the filename of the suexec logfile. + By default the logfile is named suexec_log and located in + --logfiledir.
    + +
    --with-suexec-safepath
    +
    Define the value of the environment variable PATH to + be set for processes started by suexec. Default + value is /usr/local/bin:/usr/bin:/bin.
    + +
    --with-suexec-userdir
    +
    This defines the subdirectory under the user's directory that + contains all executables for which suexec access + is allowed. This setting is necessary when you want to use + suexec together with user-specific directories (as + provided by mod_userdir). The default is + public_html.
    + +
    --with-suexec-uidmin
    +
    Define this as the lowest UID allowed to be a target user for + suexec. The default value is 100.
    + +
    --with-suexec-umask
    +
    Set umask for processes started by + suexec. It defaults to your system settings.
    +
    +
    +
    +
    + +
    Environment variables +

    There are some useful environment variables to override the choices made by + configure or to help it to find libraries and programs with + nonstandard names or locations.

    + + +
    +
    CC
    +
    Define the C compiler command to be used for compilation.
    + +
    CFLAGS
    +
    Set C compiler flags you want to use for compilation.
    + +
    CPP
    +
    Define the C preprocessor command to be used.
    + +
    CPPFLAGS
    +
    Set C/C++ preprocessor flags, e.g. -Iincludedir + if you have headers in a nonstandard directory includedir.
    + +
    LDFLAGS
    +
    Set linker flags, e.g. -Llibdir if you have + libraries in a nonstandard directory libdir.
    +
    +
    +
    diff --git a/trunk/docs/manual/programs/configure.xml.ko b/trunk/docs/manual/programs/configure.xml.ko new file mode 100644 index 0000000000..2d18f899ec --- /dev/null +++ b/trunk/docs/manual/programs/configure.xml.ko @@ -0,0 +1,934 @@ + + + + + + + + +Programs + + configure - ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù + + +

    configure ½ºÅ©¸³Æ®´Â ƯÁ¤ Ç÷¡Æû¿¡¼­ ¾ÆÆÄÄ¡ + À¥¼­¹ö¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡ÇϱâÀ§ÇØ ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù. ¿©·¯ + ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¿øÇÏ´Â ¿ä±¸Á¶°Ç¿¡ ¸Â°Ô ¼­¹ö¸¦ ÄÄÆÄÀÏÇÒ ¼ö + ÀÖ´Ù.

    + +

    ¼Ò½º ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ µð·ºÅ丮¿¡ ÀÖ´Â ÀÌ ½ºÅ©¸³Æ®´Â À¯´Ð½º¿Í + À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­¸¸ »ç¿ëÇÑ´Ù. ´Ù¸¥ Ç÷¡ÆûÀ» »ç¿ëÇÑ´Ù¸é + Ç÷¡Æû ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + +ÄÄÆÄÀÏ°ú ¼³Ä¡ + +
    °³¿ä +

    configure ½ºÅ©¸³Æ®´Â ¹èÆ÷º»ÀÇ ÃÖ»óÀ§ + µð·ºÅ丮¿¡¼­ ½ÇÇàÇØ¾ß ÇÑ´Ù.

    + +

    ./configure [OPTION]... + [VAR=VALUE]...

    + +

    ȯ°æº¯¼ö¸¦ (¿¹¸¦ µé¾î, CC, CFLAGS, + ...) ÁöÁ¤ÇÏ·Á¸é, VAR=VALUE¿Í + °°ÀÌ Áö½ÃÇÑ´Ù. ¾Æ·¡¿¡¼­ À¯¿ëÇÑ È¯°æº¯¼öµéÀ» + ¼³¸íÇÑ´Ù.

    +
    + +
    ¿É¼Ç + + +
    ±¸¼º ¿É¼Ç + +

    ÀÌ ¿É¼ÇµéÀº configure ÀÚü Çൿ¿¡ ¿µÇâÀ» + ÁØ´Ù.

    + +
    +
    -C
    +
    --config-cache
    +
    --cache-file=config.cache¿Í °°´Ù.
    + +
    --cache-file=FILE
    +
    °Ë»ç °á°ú¸¦ FILE ÆÄÀÏ¿¡ ij½ÌÇÑ´Ù. + ±âº»°ªÀº °Ë»ç °á°ú¸¦ ±â·ÏÇÏÁö ¾Ê´Â´Ù.
    + +
    -h
    +
    --help [short|recursive]
    +
    µµ¿ò¸»À» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù. short ¾Æ±Ô¸ÕÆ®´Â + ÀÌ ÆÐÅ°Áö ƯÀ¯ÀÇ ¿É¼Ç¸¸À» Ãâ·ÂÇÑ´Ù. recursive + ¾Æ±Ô¸ÕÆ®´Â Æ÷ÇÔµÈ ¸ðµç ÆÐÅ°Áö¿¡ ´ëÇÑ ÂªÀº µµ¿ò¸»À» + º¸¿©ÁØ´Ù.
    + +
    -n
    +
    --no-create
    +
    configure ½ºÅ©¸³Æ®¸¦ Á¤»óÀûÀ¸·Î ½ÇÇàÇÏÁö¸¸, + Ãâ·ÂÆÄÀÏÀ» ¸¸µéÁö ¾Ê´Â´Ù. ÀÌ ¿É¼ÇÀº ÄÄÆÄÀÏÀ» À§ÇÑ makefileÀ» + ¸¸µé±â ÀÌÀü¿¡ °Ë»ç °á°ú¸¦ È®ÀÎÇغ¼¶§ À¯¿ëÇÏ´Ù.
    + +
    -q
    +
    --quiet
    +
    ½ÇÇàÁß¿¡ checking ... ¹®±¸¸¦ Ãâ·ÂÇÏÁö + ¾Ê´Â´Ù.
    + +
    --srcdir=DIR
    +
    DIR µð·ºÅ丮¸¦ ¼Ò½ºÆÄÀÏ µð·ºÅ丮·Î ÁöÁ¤ÇÑ´Ù. + ±âº»°ªÀº configure°¡ ÀÖ´Â µð·ºÅ丮 ȤÀº »óÀ§µð·ºÅ丮 + ..ÀÌ´Ù.
    + +
    --silent
    +
    --quiet¿Í °°´Ù.
    + +
    -V
    +
    --version
    +
    ÀúÀÛ±Ç Á¤º¸¸¦ Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    +
    +
    + +
    ¼³Ä¡ µð·ºÅ丮 + +

    ÀÌ ¿É¼ÇµéÀº ¼³Ä¡ µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. ¼³Ä¡ À§Ä¡´Â + ¼±ÅÃÇÑ ±¸Á¶(layout)¿¡ µû¶ó ´Ù¸£´Ù.

    + +
    +
    --prefix=PREFIX
    +
    ¾ÆÅ°ÅØÃÄ¿¡ µ¶¸³ÀûÀÎ ÆÄÀÏÀ» PREFIX¿¡ ¼³Ä¡ÇÑ´Ù. + ±âº»°ªÀº /usr/local/apache2ÀÌ´Ù.
    + +
    --exec-prefix=EPREFIX
    +
    ¾ÆÅ°ÅØÃÄ¿¡ ÀÇÁ¸ÀûÀÎ ÆÄÀÏÀ» EPREFIX¿¡ ¼³Ä¡ÇÑ´Ù. + ±âº»°ªÀº PREFIX µð·ºÅ丮ÀÌ´Ù.
    +
    + +

    ±âº»ÀûÀ¸·Î make installÀº + /usr/local/apache2/bin, + /usr/local/apache2/lib¿Í °°Àº À§Ä¡¿¡ ¸ðµç + ÆÄÀÏÀ» ¼³Ä¡ÇÑ´Ù. --prefix=$HOME°ú °°ÀÌ + --prefix ¿É¼ÇÀ» »ç¿ëÇÏ¿© + /usr/local/apache2 ÀÌ¿ÜÀÇ ¼³Ä¡ »óÀ§µð·ºÅ丮¸¦ + ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +
    µð·ºÅ丮 ±¸Á¶ ÁöÁ¤ +
    +
    --enable-layout=LAYOUT
    +
    ¼³Ä¡ À§Ä¡¸¦ LAYOUT ±¸Á¶¿¡ µû¸£µµ·Ï + ¼Ò½ºÄÚµå¿Í ÄÄÆÄÀÏ ½ºÅ©¸³Æ®¸¦ ±¸¼ºÇÑ´Ù. ±¸Á¶¸¦ »ç¿ëÇϸé + ÆÄÀÏ Á¾·ù¿¡ µû¶ó ¼³Ä¡ À§Ä¡¸¦ µû·Î ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. + config.layout ÆÄÀÏ¿¡ ¿©·¯ ¼³Á¤ ¿¹°¡ ÀÖ°í, + À̸¦ Âü°íÇÏ¿© Á÷Á¢ ¼³Á¤À» ¸¸µé ¼öµµ ÀÖ´Ù. ÆÄÀÏ¿¡¼­ + °¢ ±¸Á¶´Â <Layout + FOO>...</Layout>·Î ±¸ºÐµÇ¸ç, ÀÌ + ºÎºÐÀº FOO¶ó´Â À̸§ÀÇ ±¸Á¶¸¦ ³ªÅ¸³½´Ù. + ±¸Á¶ÀÇ ±âº»°ªÀº ApacheÀÌ´Ù.
    +
    +
    + +
    ¼³Ä¡ µð·ºÅ丮ÀÇ + ÀÚ¼¼ÇÑ Á¶Á¤ + +

    ¼³Ä¡ µð·ºÅ丮¸¦ ´õ ¼öÁ¤ÇÑ´Ù¸é ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. + °¢ µð·ºÅ丮ÀÇ ±âº»°ªÀº autoconf°¡ ÁöÁ¤Çϸç, + ¼±ÅÃÇÑ ±¸Á¶¿¡ µû¶ó ´Ù¸§À» ÁÖÀÇÇ϶ó.

    + +
    + +
    --bindir=DIR
    +
    »ç¿ëÀÚ ½ÇÇàÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. »ç¿ëÀÚ + ½ÇÇàÆÄÀÏ¿¡´Â »çÀÌÆ® °ü¸®ÀÚ¿¡°Ô À¯¿ëÇÑ + htpasswd¿Í dbmmanage °°Àº + Áö¿ø ÇÁ·Î±×·¥µµ Æ÷ÇԵȴÙ. DIRÀÇ ±âº»°ªÀº + EPREFIX/binÀÌ´Ù.
    + +
    --datadir=DIR
    +
    ¾ÆÅ°ÅØÃÄ µ¶¸³ÀûÀÎ ÀбâÀü¿ë ÀڷḦ DIR¿¡ + ¼³Ä¡ÇÑ´Ù. datadirÀÇ ±âº»°ªÀº + PREFIX/shareÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --includedir=DIR
    +
    C Çì´õÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. + includedirÀÇ ±âº»°ªÀº + EPREFIX/includeÀÌ´Ù.
    + +
    --infodir=DIR
    +
    info ¹®¼­¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + infodirÀÇ ±âº»°ªÀº + PREFIX/infoÀÌ´Ù. ÇöÀç ÀÌ ¿É¼ÇÀº + »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --libdir=DIR
    +
    ¿ÀºêÁ§Æ®ÄÚµå ¶óÀ̺귯¸®¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + libdirÀÇ ±âº»°ªÀº + EPREFIX/libÀÌ´Ù.
    + +
    --libexecdir=DIR
    +
    ÇÁ·Î±×·¥ ½ÇÇàÆÄÀÏÀ» (Áï, °øÀ¯¸ðµâ) DIR¿¡ + ¼³Ä¡ÇÑ´Ù. libexecdirÀÇ ±âº»°ªÀº + EPREFIX/libexecÀÌ´Ù.
    + +
    --localstatedir=DIR
    +
    º¯°æµÇ´Â ¸Ó½®º° Á¤º¸¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + localstatedirÀÇ ±âº»°ªÀº + PREFIX/varÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --mandir=DIR
    +
    man ¹®¼­¸¦ DIR¿¡ ¼³Ä¡ÇÑ´Ù. + mandirÀÇ ±âº»°ªÀº + EPREFIX/manÀÌ´Ù.
    + +
    --oldincludedir=DIR
    +
    gcc°¡ ¾Æ´Ñ ÄÄÆÄÀÏ·¯¸¦ À§ÇÑ C Çì´õÆÄÀÏÀ» DIR¿¡ + ¼³Ä¡ÇÑ´Ù. oldincludedirÀÇ ±âº»°ªÀº + /usr/includeÀÌ´Ù. autoconf¿¡ + ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --sbindir=DIR
    +
    ½Ã½ºÅÛ °ü¸®ÀÚ¿ë ½ÇÇàÆÄÀÏÀ» DIR¿¡ ¼³Ä¡ÇÑ´Ù. + ½Ã½ºÅÛ °ü¸®ÀÚ¿ë ½ÇÇàÆÄÀÏÀ̶õ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ½ÇÇàÇϴµ¥ + ÇÊ¿äÇÑ httpd, apachectl, + suexec µî ¼­¹ö ÇÁ·Î±×·¥À» ¸»ÇÑ´Ù. + sbindirÀÇ ±âº»°ªÀº + EPREFIX/sbinÀÌ´Ù.
    + +
    --sharedstatedir=DIR
    +
    º¯°æµÇ´Â ¾ÆÅ°ÅØÃÄ µ¶¸³ÀûÀÎ ÀڷḦ DIR¿¡ + ¼³Ä¡ÇÑ´Ù. sharedstatedirÀÇ ±âº»°ªÀº + PREFIX/comÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ÇöÀç »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --sysconfdir=DIR
    +
    ¼­¹ö ¼³Á¤ÆÄÀÏ httpd.conf, + mime.types¿Í °°Àº ÀбâÀü¿ë ¸Ó½®º° ÀڷḦ + DIR¿¡ ¼³Ä¡ÇÑ´Ù. sysconfdirÀÇ + ±âº»°ªÀº PREFIX/etcÀÌ´Ù.
    +
    +
    +
    + +
    ½Ã½ºÅÛ Á¾·ù + +

    ´Ù¸¥ ½Ã½ºÅÛ¿¡¼­ ½ÇÇàÇÒ ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ + ±³Â÷ÄÄÆÄÀÏÇϱâ(cross-compile)Çϱâ À§ÇÑ ¿É¼ÇµéÀÌ´Ù. ¼­¹ö¸¦ + ÄÄÆÄÀÏÇÑ ½Ã½ºÅÛ¿¡¼­ ¼­¹ö¸¦ ½ÇÇàÇÏ´Â ÀϹÝÀûÀÎ °æ¿ì, ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.

    + +
    +
    --build=BUILD
    +
    µµ±¸¸¦ ÄÄÆÄÀÏÇÏ´Â ½Ã½ºÅÛÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + config.guess ½ºÅ©¸³Æ®ÀÇ °á°úÀÌ´Ù.
    + +
    --host=HOST
    +
    ¼­¹ö¸¦ ½ÇÇàÇÒ ½Ã½ºÅÛÀÇ Á¾·ù¸¦ ÁöÁ¤ÇÑ´Ù. HOSTÀÇ + ±âº»°ªÀº BUILDÀÌ´Ù.
    + +
    --target=TARGET
    +
    TARGET ½Ã½ºÅÛ Á¾·ù¸¦ À§ÇÑ ÄÄÆÄÀÏ·¯¸¦ ¸¸µé¶§ + »ç¿ëÇÑ´Ù. ±âº»°ªÀº HOSTÀÌ´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í´Â + °ü·ÃÀÌ ¾ø´Ù.
    +
    +
    + +
    ±â´É ¼±Åà + +

    ÀÌ ¿É¼ÇÀº À¥¼­¹öÀÇ ¼¼ºÎ ±â´ÉÀ» Á¶ÀýÇÑ´Ù.

    + +
    ÀϹÝÀûÀÎ ¹®¹ý +

    ÀϹÝÀûÀ¸·Î ´ÙÀ½ ¹®¹ýÀ» »ç¿ëÇÏ¿© ±â´ÉÀ» Æ÷ÇÔÇÏ°í »«´Ù:

    + +
    +
    --disable-FEATURE
    +
    FEATURE ±â´ÉÀ» »«´Ù. + --enable-FEATURE=no¿Í °°´Ù.
    + +
    --enable-FEATURE[=ARG]
    +
    FEATURE ±â´ÉÀ» Æ÷ÇÔÇÑ´Ù. ARGÀÇ + ±âº»°ªÀº yesÀÌ´Ù.
    + +
    --enable-MODULE=shared
    +
    ÇØ´ç ¸ðµâÀ» DSO ¸ðµâ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-MODULE=static
    +
    Æ÷ÇÔÇÏ´Â ¸ðµâÀº ±âº»ÀûÀ¸·Î Á¤ÀûÀ¸·Î ¸µÅ©µÈ´Ù. ÀÌ + ¿É¼ÇÀº ¸í½ÃÀûÀ¸·Î Á¤Àû ¸µÅ©¸¦ °­Á¦ÇÑ´Ù.
    +
    + + ÁÖÀÇ + configure´Â foo°¡ ¾ø´Â °æ¿ì + --enable-foo¸¦ »ç¿ëÇصµ ÀÌ »ç½ÇÀ» + ¾Ë·ÁÁÖÁö ¾ÊÀ¸¹Ç·Î ÁÖÀÇÇؼ­ ÀÔ·ÂÇØ¾ß ÇÑ´Ù. + +
    + + +
    ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏ´Â ¸ðµâ +

    ¾î¶² ¸ðµâÀº ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵDZ⶧¹®¿¡ »ç¿ëÇÏÁö ¾Ê´Â´Ù¸é + ¸í½ÃÀûÀ¸·Î »©Áà¾ß ÇÑ´Ù. ´ÙÀ½ ¿É¼ÇÀº ƯÁ¤ ¸ðµâÀ» ÄÄÆÄÀÏ + °úÁ¤¿¡¼­ Á¦¿ÜÇÑ´Ù.

    + +
    +
    --disable-actions
    +
    mod_actions°¡ Á¦°øÇÏ´Â ¿äû¿¡ ´ëÇÑ + Çൿ ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-alias
    +
    mod_alias°¡ Á¦°øÇÏ´Â ¿äûÀ» + ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐÀ¸·Î ´ëÀÀÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö + ¾Ê´Â´Ù.
    + +
    --disable-asis
    +
    mod_asis°¡ Á¦°øÇÏ´Â as-is ÆÄÀÏÇüÀ» + Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-auth
    +
    mod_auth°¡ Á¦°øÇÏ´Â »ç¿ëÀÚº° Á¢±ÙÁ¦¾î + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀº »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ + ÀÏ¹Ý ¹®ÀÚÆÄÀÏ¿¡ ÀúÀåÇÏ´Â HTTP Basic Authentication¿¡¼­ + »ç¿ëÇÑ´Ù.
    + +
    --disable-autoindex
    +
    mod_autoindex°¡ Á¦°øÇÏ´Â µð·ºÅ丮 + ¸ñ·Ï ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-access
    +
    mod_access°¡ Á¦°øÇϴ ȣ½ºÆ®º° + Á¢±ÙÁ¦¾î ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-cgi
    +
    ºñ¾²·¹µå MPMÀ» »ç¿ëÇÏ´Â °æ¿ì CGI ½ºÅ©¸³Æ®¸¦ Áö¿øÇÏ´Â + mod_cgi¸¦ ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÑ´Ù. ÀÌ + ¿É¼ÇÀ» »ç¿ëÇϸé CGI¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-cgid
    +
    ¾²·¹µå MPMÀÎ worker³ª + perchild¸¦ »ç¿ëÇÏ´Â °æ¿ì ±âº»ÀûÀ¸·Î + mod_cgid°¡ CGI ½ºÅ©¸³Æ®¸¦ Áö¿øÇÑ´Ù. + ÀÌ ¿É¼ÇÀ» »ç¿ëÇϸé CGI¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-charset-lite
    +
    mod_charset_lite°¡ Á¦°øÇÏ´Â ¹®ÀÚÁýÇÕ + º¯È¯ ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀº EBCDIC ½Ã½ºÅÛ¿¡¼­¸¸ + ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÑ´Ù.
    + +
    --disable-dir
    +
    mod_dirÀÌ Á¦°øÇÏ´Â µð·ºÅ丮 ¿äû + ó¸® ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-env
    +
    mod_env°¡ Á¦°øÇϴ ȯ°æº¯¼ö ¼³Á¤/ÇØÁ¦ + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + + +
    --disable-http
    +
    HTTP ÇÁ·ÎÅäÄÝÀ» ó¸®ÇÏÁö ¾Ê´Â´Ù. http + ¸ðµâÀº ¼­¹ö°¡ À¥¼­¹ö·Î µ¿ÀÛÇϴµ¥ ±âº»ÀûÀÎ ¸ðµâÀÌ´Ù. + ´ë½Å ´Ù¸¥ ÇÁ·ÎÅäÄÝ ¸ðµâÀ» »ç¿ëÇÒ °æ¿ì¿¡¸¸ ÀÌ ¸ðµâÀÌ + À¯¿ëÇÏ´Ù. ÀÚ½ÅÀÌ ¹«¾ùÀ» ÇÏ´ÂÁö È®½ÇÈ÷ ¾ËÁö + ¸øÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» »©Áö ¸¶¶ó +
    + ÁÖÀÇ: ÀÌ ¸ðµâÀº Ç×»ó Á¤ÀûÀ¸·Î ¸µÅ©µÈ´Ù.
    + +
    --disable-imap
    +
    mod_imapÀÌ Á¦°øÇÏ´Â ¼­¹ö±â¹Ý imagemap + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-include
    +
    mod_include°¡ Á¦°øÇÏ´Â Server Side + Includes ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-log-config
    +
    mod_log_config°¡ Á¦°øÇÏ´Â ·Î±× + ¼³Á¤À» »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀÌ ¾øÀ¸¸é ¼­¹öÀÇ ¿äûÀ» + ·Î±×¿¡ ±â·ÏÇÒ ¼ö ¾ø´Ù.
    + +
    --disable-mime
    +
    mod_mimeÀº ¿äûÇÑ ÆÄÀϸíÀÇ È®ÀåÀÚ¿¡ + µû¶ó ÆÄÀÏÀÇ Çൿ°ú ³»¿ë(mime-type, ¾ð¾î, ¹®ÀÚÁýÇÕ, + ÀÎÄÚµù)À» °áÁ¤ÇÑ´Ù. (ÀÌ ¸ðµâÀ» Á¦°ÅÇÏ¿©) ÆÄÀÏ È®ÀåÀÚ¸¦ + MIME°ú ¿¬°üÇÏÁö ¾Ê´Â °ÍÀ» ÀϹÝÀûÀ¸·Î ÃßõÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-negotiation
    +
    mod_negotiationÀÌ Á¦°øÇÏ´Â ³»¿ëÇù»ó + ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-setenvif
    +
    mod_setenvif°¡ Á¦°øÇÏ´Â Çì´õ¿¡ + µû¶ó ȯ°æº¯¼ö¸¦ ¼³Á¤ÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-status
    +
    mod_status°¡ Á¦°øÇÏ´Â ÇÁ·Î¼¼½º/¾²·¹µå + °¨½Ã ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    + +
    --disable-userdir
    +
    mod_userdirÀÌ Á¦°øÇÏ´Â ¿äûÀ» »ç¿ëÀÚº° + µð·ºÅ丮¿¡ ´ëÀÀÇÏ´Â ±â´ÉÀ» »ç¿ëÇÏÁö ¾Ê´Â´Ù.
    +
    +
    + +
    ±âº»ÀûÀ¸·Î Æ÷ÇÔÇÏÁö ¾Ê´Â ¸ðµâ +

    ±âº»ÀûÀ¸·Î ÄÄÆÄÀϵǴ ¸ðµâµµ ÀÖÁö¸¸, ¸ðµâÀ» »ç¿ëÇÏ·Á¸é + Á÷Á¢ ȤÀº most³ª all Å°¿öµå¸¦ + »ç¿ëÇÏ¿© ¸í½ÃÀûÀ¸·Î Æ÷ÇÔÇØ¾ß ÇÏ´Â ¸ðµâÀÌ ÀÖ´Ù. ±×·¡¼­ + ¾Æ·¡ ¿É¼ÇµéÀ» »ç¿ëÇÑ´Ù.

    + +
    +
    --enable-auth-anon
    +
    mod_auth_anonÀÌ Á¦°øÇÏ´Â À͸í»ç¿ëÀÚ + Á¢±Ù ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-auth-dbm
    +
    mod_auth_dbmÀº »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ + DBMÇü½ÄÀÇ µ¥ÀÌÅͺ£À̽º ÆÄÀÏ¿¡ ÀúÀåÇÏ´Â HTTP Basic + Authentication¿¡¼­ »ç¿ëÇÑ´Ù. ¸ðµâÀ» »ç¿ëÇÏ·Á¸é ÀÌ + ¿É¼ÇÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-auth-digest
    +
    mod_auth_digest°¡ Á¦°øÇÏ´Â RFC2617 + Digest authenticationÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº Á¤º¸¸¦ + ÀÏ¹Ý ¹®ÀÚÆÄÀÏ¿¡ ÀúÀåÇÑ´Ù.
    + +
    --enable-authnz-ldap
    +
    mod_authnz_ldapÀÌ Á¦°øÇÏ´Â LDAP±â¹Ý + ÀÎÁõ ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-cache
    +
    mod_cache°¡ Á¦°øÇÏ´Â µ¿ÀûÀ¸·Î »ý¼ºÇÏ´Â + ÆÄÀÏÀÇ Ä³½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù. ¸Å¿ì ºÎÇÏ°¡ ¸¹°Å³ª ÇÁ·Ï½Ã + ¼­¹ö¸¦ ij½ÌÇÏ´Â ¼­¹ö¿¡°Ô ÀÌ ½ÇÇèÀûÀÎ ¸ðµâÀÌ À¯¿ëÇÒ + ¼ö ÀÖ´Ù. ÃÖ¼ÒÇÑ ÇÑ°¡Áö ÀúÀå°ü¸®¸ðµâ(storage management + module)À» (¿¹¸¦ µé¾î, mod_disk_cache³ª + mod_mem_cache) °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-cern-meta
    +
    mod_cern_meta°¡ Á¦°øÇÏ´Â CERN ¸ÞŸÆÄÀÏ + Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-charset-lite
    +
    mod_charset_lite°¡ Á¦°øÇÏ´Â ¹®ÀÚÁýÇÕ + º¯È¯ ±â´ÉÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº EBCDIC ½Ã½ºÅÛ¿¡¼­¸¸ + ±âº»ÀûÀ¸·Î Æ÷ÇԵȴÙ. ´Ù¸¥ ½Ã½ºÅÛ¿¡¼­´Â Á÷Á¢ Æ÷ÇÔ½ÃÄÑÁà¾ß + ÇÑ´Ù.
    + +
    --enable-dav
    +
    mod_dav°¡ Á¦°øÇÏ´Â WebDAV ÇÁ·ÎÅäÄÝ + ó¸® ±â´ÉÀ» »ç¿ëÇÑ´Ù. µ¶¸³µÈ mod_dav_fs + ¸ðµâÀÌ ÆÄÀϽýºÅÛ ÀÚ¿øÀ» Áö¿øÇÑ´Ù. ÀÌ ¸ðµâÀº + --enable-dav¸¦ »ç¿ëÇϸé ÀÚµ¿À¸·Î Æ÷ÇÔÇÑ´Ù.
    + ÁÖÀÇ: mod_dav´Â http + ÇÁ·ÎÅäÄÝ ¸ðµâ°ú °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-dav-fs
    +
    mod_dav_fs°¡ Á¦°øÇÏ´Â DAVÀÇ ÆÄÀϽýºÅÛ + ÀÚ¿ø Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº + mod_dav ¸ðµâÀ» À§ÇÑ Á¦°øÀÚÀ̱⠶§¹®¿¡ + --enable-davµµ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-deflate
    +
    mod_deflate°¡ Á¦°øÇÏ´Â ¾ÐÃàÀü¼Û + ÀÎÄÚµù ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-disk-cache
    +
    mod_disk_cache°¡ Á¦°øÇÏ´Â µð½ºÅ© + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-expires
    +
    mod_expires°¡ Á¦°øÇÏ´Â Expires + Çì´õ Á¶Àý ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-ext-filter
    +
    mod_ext_filter°¡ Á¦°øÇÏ´Â ¿ÜºÎ + ÇÊÅÍ Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-file-cache
    +
    mod_file_cache°¡ Á¦°øÇÏ´Â ÆÄÀÏ + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-headers
    +
    mod_headers°¡ Á¦°øÇÏ´Â HTTP Çì´õ + Á¶Àý ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-info
    +
    mod_info°¡ Á¦°øÇÏ´Â ¼­¹öÁ¤º¸ ±â´ÉÀ» + »ç¿ëÇÑ´Ù.
    + +
    --enable-ldap
    +
    mod_ldapÀÌ Á¦°øÇÏ´Â LDAP ij½Ì°ú + ¿¬°áÇ® ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-logio
    +
    mod_logio°¡ Á¦°øÇÏ´Â ·Î±×¿¡ Çì´õ¿Í + ÀÔÃâ·Â ¹ÙÀÌÆ®¼ö¸¦ ±â·ÏÇÏ´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-mem-cache
    +
    mod_mem_cache°¡ Á¦°øÇÏ´Â ¸Þ¸ð¸® + ij½Ì ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-mime-magic
    +
    mod_mime_magicÀÌ Á¦°øÇÏ´Â MIME + type ÀÚµ¿ ÀÎ½Ä ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-isapi
    +
    mod_isapi°¡ Á¦°øÇÏ´Â isapi È®ÀåÀ» + Áö¿øÇÑ´Ù.
    + +
    --enable-proxy
    +
    mod_proxy°¡ Á¦°øÇÏ´Â ÇÁ·Ï½Ã/°ÔÀÌÆ®¿þÀÌ + ±â´ÉÀ» »ç¿ëÇÑ´Ù. CONNECT, FTP, + HTTP¿¡ ´ëÇÑ ÇÁ·Ï½Ã ±â´ÉÀ» °¢°¢ + mod_proxy_connect, + mod_proxy_ftp, + mod_proxy_http + ¸ðµâÀÌ Á¦°øÇÑ´Ù. --enable-proxy¸¦ »ç¿ëÇϸé + ÀÌ ¼¼ ¸ðµâÀ» ÀÚµ¿À¸·Î Æ÷ÇÔÇÑ´Ù.
    + +
    --enable-proxy-connect
    +
    mod_proxy_connect°¡ Á¦°øÇÏ´Â + CONNECT ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» + »ç¿ëÇÑ´Ù. ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ + È®ÀåÀ̹ǷÎ, --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    + +
    --enable-proxy-ftp
    +
    mod_proxy_ftp°¡ Á¦°øÇÏ´Â + FTP ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ È®ÀåÀ̹ǷÎ, + --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-proxy-http
    +
    mod_proxy_http°¡ Á¦°øÇÏ´Â + HTTP ¿äû¿¡ ´ëÇÑ ÇÁ·Ï½Ã Áö¿ø ±â´ÉÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀº mod_proxy ¸ðµâÀÇ È®ÀåÀ̹ǷÎ, + --enable-proxyµµ °°ÀÌ »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    --enable-rewrite
    +
    mod_rewrite°¡ Á¦°øÇÏ´Â ±ÔÄ¢±â¹Ý + URL Á¶ÀÛ ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-so
    +
    mod_so°¡ Á¦°øÇÏ´Â DSO ±â´ÉÀ» »ç¿ëÇÑ´Ù. + --enable-mods-shared ¿É¼ÇÀ» »ç¿ëÇϸé + ÀÚµ¿À¸·Î ÀÌ ¸ðµâÀ» Æ÷ÇÔÇÑ´Ù.
    + +
    --enable-speling
    +
    mod_spellingÀÌ Á¦°øÇÏ´Â URL¿¡¼­ + ÀϹÝÀûÀÎ ¸ÂÃã¹ý ½Ç¼ö¸¦ °íÄ¡´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-ssl
    +
    mod_sslÀÌ Á¦°øÇÏ´Â SSL/TLS ±â´ÉÀ» + »ç¿ëÇÑ´Ù.
    + +
    --enable-unique-id
    +
    mod_unique_id°¡ Á¦°øÇÏ´Â ¿äû¸¶´Ù + À¯ÀÏÇÑ ½Äº°ÀÚ¸¦ ¸¸µå´Â ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-usertrack
    +
    mod_usertrackÀÌ Á¦°øÇÏ´Â »ç¿ëÀÚ¼¼¼Ç + ÃßÀû ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    + +
    --enable-vhost-alias
    +
    mod_vhost_alias°¡ Á¦°øÇÏ´Â ´ë·® + °¡»óÈ£½ºÆ® ±â´ÉÀ» »ç¿ëÇÑ´Ù.
    +
    +
    + +
    °³¹ßÀÚ¸¦ À§ÇÑ ¸ðµâ +

    ´ÙÀ½ ¸ðµâÀº Å×½ºÆ®¿ëÀ¸·Î °³¹ßÀÚ¿¡°Ô¸¸ À¯¿ëÇϸç, ±âº»ÀûÀ¸·Î + Æ÷ÇÔÇÏÁö ¾Ê´Â´Ù. ÀÌ ¸ðµâÀ» »ç¿ëÇÏ·Á¸é ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. + ÀÌ ¸ðµâÀÌ ÇÊ¿äÇÑÁö È®½ÇÄ¡¾Ê´Ù¸é »ç¿ëÇÏÁö ¸¶¶ó.

    + +
    + +
    --enable-bucketeer
    +
    mod_bucketeer°¡ Á¦°øÇÏ´Â ¹öŶ(bucket) + Á¶ÀÛ ÇÊÅ͸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-case-filter
    +
    mod_case_filterÀÇ ´ë¹®ÀÚº¯È¯ Ãâ·ÂÇÊÅÍ + °ßº»À» »ç¿ëÇÑ´Ù.
    + + +
    --enable-case-filter-in
    +
    mod_case_filter_inÀÇ ´ë¹®ÀÚº¯È¯ ÀÔ·ÂÇÊÅÍ + °ßº»À» »ç¿ëÇÑ´Ù.
    + +
    --enable-echo
    +
    mod_echo°¡ Á¦°øÇÏ´Â ECHO ¼­¹ö¸¦ + »ç¿ëÇÑ´Ù.
    + +
    --enable-example
    +
    °ßº» ¿¹Á¦¸ðµâÀÎ mod_exampleÀ» + »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-fn-export
    +
    mod_optional_fn_export°¡ Á¦°øÇÏ´Â ¼±ÅÃÀûÀÎ + ÇÔ¼ö ¿¢½ºÆ÷Æ®(exporter)ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-fn-import
    +
    mod_optional_fn_import°¡ Á¦°øÇÏ´Â ¼±ÅÃÀûÀÎ + ÇÔ¼ö ÀÓÆ÷Æ®(importer)ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-hook-export
    +
    mod_optional_hook_export°¡ Á¦°øÇÏ´Â + ¼±ÅÃÀûÀÎ ÈÅ(hook) ¿¢½ºÆ÷Æ®ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    + + +
    --enable-optional-hook-import
    +
    mod_optional_hook_import°¡ Á¦°øÇÏ´Â + ¼±ÅÃÀûÀÎ ÈÅ ÀÓÆ÷Æ®ÀÇ ¿¹¸¦ »ç¿ëÇÑ´Ù.
    +
    +
    + +
    MPM°ú Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ +

    ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÏ¿© ÇÊ¿äÇÑ ´ÙÁß󸮸ðµâ°ú Á¦»ïÀÚ°¡ + ¸¸µç ¸ðµâÀ» Ãß°¡ÇÑ´Ù:

    + +
    +
    --with-module=module-type:module-file +
    +

    Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâÀ» Á¤ÀûÀ¸·Î ¸µÅ©ÇÒ ¸ðµâ ¸ñ·Ï¿¡ + Ãß°¡ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö ¼Ò½º Æ®¸®ÀÇ + modules/module-type¿¡¼­ ¸ðµâÀÇ + ¼Ò½ºÆÄÀÏ module-fileÀ» ã±â¶§¹®¿¡ + ±×°÷¿¡ ¼Ò½ºÆÄÀÏÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ±×°÷¿¡ ÆÄÀÏÀÌ ¾ø´Ù¸é + configure´Â module-fileÀÌ + Àý´ëÆÄÀÏ°æ·Î¶ó°í °¡Á¤ÇÏ°í ¼Ò½ºÆÄÀÏÀ» + module-type ÇÏÀ§µð·ºÅ丮¿¡ º¹»çÇÏ·Á°í + ½ÃµµÇÑ´Ù.

    +

    ÀÌ ¿É¼ÇÀº ¼Ò½ºÆÄÀÏÀÌ ÇÑ°³ÀÎ ÀÛÀº ¿ÜºÎ ¸ðµâÀ» Ãß°¡Çϴµ¥ + À¯¿ëÇÏ´Ù. ´õ º¹ÀâÇÑ ¸ðµâÀº °³¹ß»ç°¡ Á¦°øÇÑ ¹®¼­¸¦ + Âü°íÇØ¾ß ÇÑ´Ù.

    + ÁÖÀÇ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ¸ðµâÀÌ ¾Æ´Ñ DSO ¸ðµâÀ» ¿øÇÑ´Ù¸é + apxs¸¦ »ç¿ëÇ϶ó. +
    + +
    --with-mpm=MPM
    +
    ¼­¹öÀÇ µ¿ÀÛ¹æ½ÄÀ» ¼±ÅÃÇÑ´Ù. Á¤È®È÷ ÇÑ°¡Áö ´ÙÁß󸮸ðµâ¸¸À» ¼±ÅÃÇØ¾ß ÇÑ´Ù. + ¼±ÅÃÇÏÁö ¾ÊÀ¸¸é »ç¿ëÇÏ´Â ¿î¿µÃ¼Á¦ÀÇ ±âº» MPMÀ» »ç¿ëÇÑ´Ù. + »ç¿ëÇÒ ¼ö ÀÖ´Â MPM¿¡´Â beos, + leader, mpmt_os2, + perchild, prefork, + threadpool, worker°¡ + ÀÖ´Ù.
    +
    +
    + +
    ±âŸ ¿É¼Ç +
    +
    --enable-maintainer-mode
    +
    µð¹ö±ë ¸ðµå¿Í ÄÄÆÄÀϽà °æ°í¸¦ ÀÛµ¿ÇÑ´Ù.
    + +
    --enable-mods-shared=MODULE-LIST
    +
    +

    µ¿Àû°øÀ¯¸ðµâ·Î ÄÄÆÄÀÏÇÒ ¸ðµâ ¸ñ·ÏÀ» ÁöÁ¤ÇÑ´Ù. Áï, + ÀÌ ¸ðµâµéÀº LoadModule Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© µ¿ÀûÀ¸·Î Àоîµé¿©¾ß ÇÑ´Ù.

    +

    MODULE-LIST´Â °ø¹éÀ¸·Î ±¸ºÐÇÑ ¸ðµâ¸íµéÀ» + µû¿ÈÇ¥·Î ¹­Àº ¸ñ·ÏÀÌ´Ù. ¸ðµâ¸í¿¡¼­ ¾Õ¿¡ + mod_´Â »«´Ù. ¿¹¸¦ µé¾î:

    + + --enable-mods-shared='headers rewrite dav' + +

    ¶Ç, Ưº°ÇÑ Å°¿öµå all°ú most¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î,

    + + --enable-mods-shared=most + +

    ´Â ´ëºÎºÐÀÇ ¸ðµâÀ» DSO ¸ðµâ·Î ÄÄÆÄÀÏÇÑ´Ù. +

    +
    + +
    --enable-modules=MODULE-LIST
    +
    --enable-mods-shared¿Í ºñ½ÁÇÏÁö¸¸, + ÀÌ ¿É¼ÇÀº ¿­°ÅÇÑ ¸ðµâµéÀ» Á¤ÀûÀ¸·Î ¸µÅ©ÇÑ´Ù. Áï, ÀÌ + ¸ðµâµéÀº httpd ½ÇÇàÇÏ¸é ¾ðÁ¦³ª »ç¿ëÇÒ + ¼ö ÀÖ´Ù. LoadModule·Î ÀоîµéÀÏ + ÇÊ¿ä°¡ ¾ø´Ù.
    + +
    --enable-v4-mapped
    +
    IPv6 ¼ÒÄÏÀÌ IPv4 ¿¬°áÀ» ó¸®ÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù.
    + +
    --with-port=PORT
    +
    httpd°¡ ±â´Ù¸± Æ÷Æ®¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ + Æ÷Æ®¹øÈ£´Â ¼³Á¤ÆÄÀÏ httpd.conf¸¦ ¸¸µé¶§ + ¾²ÀδÙ. ±âº»°ªÀº 80ÀÌ´Ù.
    + +
    --with-program-name
    +
    ´Ù¸¥ ½ÇÇàÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + httpdÀÌ´Ù.
    +
    +
    +
    + +
    Ãß°¡ ÆÐÅ°Áö ¼±Åà +

    ´ÙÀ½ ¿É¼ÇÀº Ãß°¡ ÆÐÅ°Áö¸¦ ¼±ÅÃÇÑ´Ù.

    + +
    ÀϹÝÀûÀÎ ¹®¹ý +

    ÀϹÝÀûÀ¸·Î ´ÙÀ½°ú °°Àº ¹®¹ýÀ» »ç¿ëÇÏ¿© Ãß°¡ ÆÐÅ°Áö¸¦ + ´Ù·é´Ù:

    + +
    +
    --with-PACKAGE[=ARG]
    +
    ÆÐÅ°Áö PACKAGE¸¦ »ç¿ëÇÑ´Ù. + ARGÀÇ ±âº»°ªÀº yesÀÌ´Ù.
    + +
    --without-PACKAGE
    +
    ÆÐÅ°Áö PACKAGE¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. + --with-PACKAGE=no¿Í °°´Ù. + autoconf¿¡ ÀÌ ¿É¼ÇÀÌ ÀÖÁö¸¸ ¾ÆÆÄÄ¡ À¥¼­¹ö¿Í´Â + °ü°è°¡ ¾ø´Ù.
    +
    +
    + + + +
    ƯÁ¤ ÆÐÅ°Áö +
    +
    --with-apr=DIR|FILE
    +
    httpd ¼Ò½º ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ Apache Portable + Runtime (APR)Àº ÀÚµ¿À¸·Î À¥¼­¹ö¿Í °°ÀÌ ÄÄÆÄÀϵȴÙ. + ¸¸¾à ÀÌ¹Ì ¼³Ä¡µÈ APRÀ» ´ë½Å »ç¿ëÇÏ°í ½Í´Ù¸é + configure¿¡°Ô apr-config + ½ºÅ©¸³Æ®ÀÇ °æ·Î¸¦ ¾Ë·ÁÁÖ¾î¾ß ÇÑ´Ù. APR°¡ ¼³Ä¡µÈ Àý´ë°æ·Î, + ÆÄÀϸí, µð·ºÅ丮¸íÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ µð·ºÅ丮³ª + ±× µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 bin¿¡ + apr-config°¡ ÀÖ¾î¾ß ÇÑ´Ù.
    + +
    --with-apr-util=DIR|FILE
    +
    httpd ¼Ò½º ¹èÆ÷º»¿¡ Æ÷ÇÔµÈ Apache Portable + Runtime Utilities (APU)´Â ÀÚµ¿À¸·Î À¥¼­¹ö¿Í °°ÀÌ + ÄÄÆÄÀϵȴÙ. ¸¸¾à ÀÌ¹Ì ¼³Ä¡µÈ APUÀ» ´ë½Å »ç¿ëÇÏ°í ½Í´Ù¸é + configure¿¡°Ô apu-config + ½ºÅ©¸³Æ®ÀÇ °æ·Î¸¦ ¾Ë·ÁÁÖ¾î¾ß ÇÑ´Ù. APU°¡ ¼³Ä¡µÈ Àý´ë°æ·Î, + ÆÄÀϸí, µð·ºÅ丮¸íÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÁöÁ¤ÇÑ µð·ºÅ丮³ª + ±× µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮 bin¿¡ + apu-config°¡ ÀÖ¾î¾ß ÇÑ´Ù.
    + +
    --with-ssl=DIR
    +
    mod_sslÀ» »ç¿ëÇÏ´Â °æ¿ì + configure´Â ¼³Ä¡µÈ OpenSSLÀ» ã´Â´Ù. + ´ë½Å ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¿© SSL/TLS µµ±¸ÀÇ µð·ºÅ丮°æ·Î¸¦ + ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.
    + +
    --with-z=DIR
    +
    (mod_deflate¸¦ »ç¿ëÇÏ´Â °æ¿ì¿Í + °°ÀÌ) ±¸¼º¿¡ ÇÊ¿äÇÏ´Ù¸é ÀÚµ¿À¸·Î configure´Â + ¼³Ä¡µÈ zlib ¶óÀ̺귯¸®¸¦ ã´Â´Ù. ´ë½Å + ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏ¿© ¾ÐÃà ¶óÀ̺귯¸®ÀÇ µð·ºÅ丮°æ·Î¸¦ + ¾Ë·ÁÁÙ ¼ö ÀÖ´Ù.
    +
    + +

    mod_authn_dbm°ú + mod_rewriteÀÇ DBM RewriteMap °°Àº ¾ÆÆÄÄ¡ + À¥¼­¹öÀÇ ÀϺΠ±â´ÉÀº Á¤º¸¸¦ »¡¸® ã±âÀ§ÇØ °£´ÜÇÑ Å°/°ª + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÑ´Ù. APU¿¡ SDBMÀÌ µé¾îÀ־ ¾ðÁ¦³ª + ÃÖ¼ÒÇÑ ÀÌ µ¥ÀÌÅͺ£À̽º´Â »ç¿ëÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ Á¾·ùÀÇ + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÏ°í ½Í´Ù¸é ¾Æ·¡ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù:

    + +
    +
    --with-gdbm[=path]
    +
    path¸¦ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é, + configure´Â ÀϹÝÀûÀÎ °Ë»ö°æ·Î¿¡¼­ ¼³Ä¡µÈ + GNU DBM Çì´õÆÄÀÏ°ú ¶óÀ̺귯¸®¸¦ ã´Â´Ù. Á÷Á¢ + path¸¦ ÁöÁ¤Çϸé configure´Â + path/lib°ú + path/include¿¡¼­ ÇÊ¿äÇÑ ÆÄÀÏÀ» + ã´Â´Ù. ¸¶Áö¸·À¸·Î path¿¡ Çì´õÆÄÀÏ °æ·Î¿Í + ¶óÀ̺귯¸® °æ·Î¸¦ ÄÝ·ÐÀ» »çÀÌ¿¡ µÎ°í °°ÀÌ ÀûÀ» ¼ö + ÀÖ´Ù.
    + +
    --with-ndbm[=path]
    +
    --with-gdbm°ú °°Áö¸¸ ¼³Ä¡µÈ New DBMÀ» + ã´Â´Ù.
    + +
    --with-berkeley-db[=path]
    +
    --with-gdbm°ú °°Áö¸¸ ¼³Ä¡µÈ Berkeley + DB¸¦ ã´Â´Ù.
    +
    + + ÁÖÀÇ +

    DBM ¿É¼ÇÀº APU°¡ Á¦°øÇϸç APU ±¸¼º½ºÅ©¸³Æ®·Î Á÷Á¢ + Àü´ÞµÈ´Ù. ±×·¡¼­ --with-apr-utilÀ» »ç¿ëÇÏ¿© + ÀÌ¹Ì ¼³Ä¡µÈ APU¸¦ »ç¿ëÇÑ´Ù¸é DBM ¿É¼ÇÀº ¼Ò¿ëÀÌ ¾ø´Ù.

    +

    À¥¼­¹ö´Â ¿©·¯ DBM ±¸ÇöÀ» °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ½ÇÇà½Ã + ÀûÀýÇÑ DBM Á¾·ù¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.

    +
    +
    +
    + +
    Áö¿ø ÇÁ·Î±×·¥À» À§ÇÑ ¿É¼Ç +
    +
    --enable-static-support
    +
    Áö¿ø ÇÁ·Î±×·¥À» Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ¸¸µç´Ù. + Áï, ÇÊ¿äÇÑ ¶óÀ̺귯¸®¸¦ ¸ðµÎ Æ÷ÇÔÇϵµ·Ï ½ÇÇàÆÄÀÏÀ» + ÄÄÆÄÀÏÇÑ´Ù. ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏÁö ¾ÊÀ¸¸é ±âº»°ªÀ¸·Î Áö¿ø + ÇÁ·Î±×·¥À» µ¿ÀûÀ¸·Î ¸µÅ©ÇÑ´Ù.
    + +
    --enable-suexec
    +
    À¥¼­¹ö°¡ ½ÇÇàÇÏ´Â ÇÁ·Î¼¼½ºÀÇ uid¿Í gid¸¦ ¼³Á¤ÇÏ´Â + suexec¸¦ »ç¿ëÇÏ·Á¸é + ÀÌ ¿É¼ÇÀ» »ç¿ëÇÑ´Ù. suid ½ÇÇàÆÄÀÏÀÇ º¸¾È»ó À§ÇèÀ» + ¸ðµÎ ¾ËÁö ¸øÇÑ´Ù¸é ÀÌ ¿É¼ÇÀ» »ç¿ëÇÏÁö ¸¶¶ó. + suexec¸¦ ±¸¼ºÇÏ´Â ¿É¼ÇÀº + ¾Æ·¡¿¡¼­ ¼³¸íÇÑ´Ù.
    +
    + +

    ´ÙÀ½ ¿É¼ÇÀ» »ç¿ëÇÏ¿© Áö¿ø ÇÁ·Î±×·¥º°·Î Á¤ÀûÀ¸·Î ¸µÅ©µÈ + ½ÇÇàÆÄÀÏÀ» ¸¸µé ¼ö ÀÖ´Ù:

    + +
    +
    --enable-static-ab
    +
    ab¸¦ Á¤ÀûÀ¸·Î ¸µÅ©µÈ + ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + + +
    --enable-static-checkgid
    +
    checkgid¸¦ Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î + ÄÄÆÄÀÏÇÑ´Ù.
    + + +
    --enable-static-htdbm
    +
    htdbmÀ» Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î + ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-htdigest
    +
    htdigest¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-htpasswd
    +
    htpasswd¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-logresolve
    +
    logresolve¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    + +
    --enable-static-rotatelogs
    +
    rotatelogs¸¦ + Á¤ÀûÀ¸·Î ¸µÅ©µÈ ½ÇÇàÆÄÀÏ·Î ÄÄÆÄÀÏÇÑ´Ù.
    +
    + +
    suexec ¼³Á¤ ¿É¼Ç +

    ¾Æ·¡ ¿É¼ÇÀº suexec¸¦ ÀÚ¼¼È÷ ¼³Á¤ÇÑ´Ù. + ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â suEXEC + ±¸¼º°ú ¼³Ä¡¸¦ Âü°íÇ϶ó.

    + +
    +
    --with-suexec-bin
    +
    suexec ½ÇÇàÆÄÀÏÀÇ °æ·Î¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + --sbindirÀÌ´Ù (¼³Ä¡ µð·ºÅ丮ÀÇ ÀÚ¼¼ÇÑ + Á¶Á¤ Âü°í).
    + +
    --with-suexec-caller
    +
    suexec¸¦ ½ÇÇàÇÒ »ç¿ëÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. + ÀÌ »ç¿ëÀÚ´Â º¸Åë httpd¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿Í + °°¾Æ¾ß ÇÑ´Ù.
    + +
    --with-suexec-docroot
    +
    suexec´Â ÀÌ ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ µð·ºÅ丮 + ¾Æ·¡¿¡ ÀÖ´Â ½ÇÇàÆÄÀϸ¸À» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº + --datadir/htdocs´Ù.
    + +
    --with-suexec-gidmin
    +
    suexec¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ÃÖ¼Ò GID¸¦ ¼³Á¤ÇÑ´Ù. + ±âº»°ªÀº 100ÀÌ´Ù.
    + +
    --with-suexec-logfile
    +
    suexec ·Î±×ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ·Î±×ÆÄÀϸíÀÇ + ±âº»°ªÀº suexec_logÀÌ°í, + --logfiledir¿¡ À§Ä¡ÇÑ´Ù.
    + +
    --with-suexec-safepath
    +
    suexec°¡ ½ÃÀÛÇÏ´Â ÇÁ·Î¼¼½ºÀÇ + PATH ȯ°æº¯¼ö°ªÀ» ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº + /usr/local/bin:/usr/bin:/binÀÌ´Ù.
    + +
    --with-suexec-userdir
    +
    »ç¿ëÀÚ µð·ºÅ丮¿¡¼­ suexec°¡ Á¢±ÙÇÒ + ¼ö ÀÖ´Â (½ÇÇàÆÄÀÏÀÌ ÀÖ´Â) ÇÏÀ§µð·ºÅ丮¸¦ ÁöÁ¤ÇÑ´Ù. + ÀÌ ¼³Á¤Àº suexec¿Í + (mod_userdirÀÌ Á¦°øÇÏ´Â) »ç¿ëÀÚº° + µð·ºÅ丮¸¦ °°ÀÌ »ç¿ëÇÒ¶§ ÇÊ¿äÇÏ´Ù. ±âº»°ªÀº + public_htmlÀÌ´Ù.
    + +
    --with-suexec-uidmin
    +
    suexec¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ÃÖ¼Ò UID¸¦ ¼³Á¤ÇÑ´Ù. + ±âº»°ªÀº 100ÀÌ´Ù.
    + +
    --with-suexec-umask
    +
    suexec°¡ ½ÇÇàÇÏ´Â ÇÁ·Î¼¼½ºÀÇ + umask¸¦ ÁöÁ¤ÇÑ´Ù. ±âº»°ªÀº »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ + ±âº» ¼³Á¤°ú °°´Ù.
    +
    +
    +
    +
    + +
    ȯ°æº¯¼ö +

    configureÀÇ ¼±ÅÃÀ» ¹«½ÃÇϰųª °ü·Ê¿Í ´Ù¸¥ + À̸§À̳ª À§Ä¡¿¡ ÀÖ´Â ¶óÀ̺귯¸®¿Í ÇÁ·Î±×·¥À» ãµµ·Ï µµ¿ÍÁÖ´Â + À¯¿ëÇÑ È¯°æº¯¼öµéÀÌ ÀÖ´Ù.

    + + +
    +
    CC
    +
    ÄÄÆÄÀÏ¿¡ »ç¿ëÇÒ C ÄÄÆÄÀÏ·¯ ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    CFLAGS
    +
    ÄÄÆÄÀ϶§ »ç¿ëÇÏ±æ ¹Ù¶ó´Â C ÄÄÆÄÀÏ·¯ ¿É¼ÇÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    CPP
    +
    »ç¿ëÇÒ C ¼±Ã³¸®±â ¸í·É¾î¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    CPPFLAGS
    +
    C/C++ ¼±Ã³¸®±â ¿É¼Ç. ¿¹¸¦ µé¾î, Çì´õÆÄÀÏÀÌ °ü·Ê¿Í ´Þ¸® + includedir µð·ºÅ丮¿¡ ÀÖ´Ù¸é + -IincludedirÀ» »ç¿ëÇÑ´Ù.
    + +
    LDFLAGS
    +
    ¸µÄ¿ ¿É¼Ç. ¿¹¸¦ µé¾î, ¶óÀ̺귯¸®°¡ °ü·Ê¿Í ´Þ¸® + libdir µð·ºÅ丮¿¡ ÀÖ´Ù¸é + -LlibdirÀ» »ç¿ëÇÑ´Ù.
    +
    +
    +
    diff --git a/trunk/docs/manual/programs/configure.xml.meta b/trunk/docs/manual/programs/configure.xml.meta new file mode 100644 index 0000000000..7a520cd68d --- /dev/null +++ b/trunk/docs/manual/programs/configure.xml.meta @@ -0,0 +1,12 @@ + + + + configure + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/dbmmanage.html b/trunk/docs/manual/programs/dbmmanage.html new file mode 100644 index 0000000000..443de47d70 --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.html @@ -0,0 +1,7 @@ +URI: dbmmanage.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: dbmmanage.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/dbmmanage.html.en b/trunk/docs/manual/programs/dbmmanage.html.en new file mode 100644 index 0000000000..0e24e05680 --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.html.en @@ -0,0 +1,191 @@ + + + +dbmmanage - Manage user authentication files in DBM format - Apache HTTP Server + + + + + +
    <-
    +

    dbmmanage - Manage user authentication files in DBM format

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    dbmmanage is used to create and update the DBM format files + used to store usernames and password for basic authentication of HTTP users + via mod_authn_dbm. + Resources available from the Apache HTTP server can be restricted to just + the users listed in the files created by dbmmanage. This + program can only be used when the usernames are stored in a DBM file. To + use a flat-file database see htpasswd.

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure user authentication in + httpd see the httpd manual, which is part of + the Apache distribution or can be found at http://httpd.apache.org/.

    +
    + +
    top
    +
    +

    Synopsis

    +

    dbmmanage [ encoding ] + filename add|adduser|check|delete|update + username + [ encpasswd + [ group[,group...] + [ comment ] ] ]

    + +

    dbmmanage filename + view [ username ]

    + +

    dbmmanage filename import

    +
    top
    +
    +

    Options

    +
    +
    filename
    +
    The filename of the DBM format file. Usually without the extension + .db, .pag, or .dir.
    + +
    username
    +
    The user for which the operations are performed. The username + may not contain a colon (:).
    + +
    encpasswd
    +
    This is the already encrypted password to use for the + update and add commands. You may use a hyphen + (-) if you want to get prompted for the password, but fill + in the fields afterwards. Additionally when using the update + command, a period (.) keeps the original password + untouched.
    + +
    group
    +
    A group, which the user is member of. A groupname may not contain a + colon (:). You may use a hyphen (-) if you don't + want to assign the user to a group, but fill in the comment field. + Additionally when using the update command, a period + (.) keeps the original groups untouched.
    + +
    comment
    +
    This is the place for your opaque comments about the user, like + realname, mailaddress or such things. The server will ignore this + field.
    +
    + +

    Encodings

    +
    +
    -d
    +
    crypt encryption (default, except on Win32, Netware)
    + +
    -m
    +
    MD5 encryption (default on Win32, Netware)
    + +
    -s
    +
    SHA1 encryption
    + +
    -p
    +
    plaintext (not recommended)
    +
    + + +

    Commands

    +
    +
    add
    +
    Adds an entry for username to filename using the + encrypted password encpasswd. + +

    dbmmanage passwords.dat add rbowen foKntnEF3KSXA

    +
    + +
    adduser
    +
    Asks for a password and then adds an entry for username to + filename. + +

    dbmmanage passwords.dat adduser krietz

    +
    + +
    check
    +
    Asks for a password and then checks if username is in + filename and if it's password matches the specified one. + +

    dbmmanage passwords.dat check rbowen

    +
    + +
    delete
    +
    Deletes the username entry from filename. + +

    dbmmanage passwords.dat delete rbowen

    +
    + +
    import
    +
    Reads username:password entries + (one per line) from STDIN and adds them to + filename. The passwords already have to be crypted.
    + +
    update
    +
    Same as the adduser command, except that it makes + sure username already exists in filename. + +

    dbmmanage passwords.dat update rbowen

    +
    + +
    view
    +
    Just displays the contents of the DBM file. If you specify a + username, it displays the particular record only. + +

    dbmmanage passwords.dat view

    +
    +
    + +
    top
    +
    +

    Bugs

    +

    One should be aware that there are a number of different DBM file formats + in existence, and with all likelihood, libraries for more than one format + may exist on your system. The three primary examples are SDBM, 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 filename is the same format that dbmmanage + expects to see. dbmmanage currently has no way of determining + what type of DBM file it is looking at. If used against the wrong format, + 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.

    + +

    dbmmanage has a list of DBM format preferences, defined by + the @AnyDBM::ISA array near the beginning of the program. Since + we prefer the Berkeley DB 2 file format, the order in which + dbmmanage will look for system libraries is Berkeley DB 2, + then NDBM, then GDBM and then SDBM. The first library found will be the + library dbmmanage will attempt to use for all DBM file + transactions. This ordering is slightly different than the standard + @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.

    + +

    One can usually use the file program supplied with most + Unix systems to see what format a DBM file is in.

    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/dbmmanage.html.ko.euc-kr b/trunk/docs/manual/programs/dbmmanage.html.ko.euc-kr new file mode 100644 index 0000000000..6db76b4499 --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.html.ko.euc-kr @@ -0,0 +1,172 @@ + + + +dbmmanage - DBM Çü½ÄÀÇ »ç¿ëÀÚÀÎÁõ ÆÄÀÏÀ» °ü¸®ÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    dbmmanage - DBM Çü½ÄÀÇ »ç¿ëÀÚÀÎÁõ ÆÄÀÏÀ» °ü¸®ÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    dbmmanage´Â HTTP basic authentication¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â DBMÇü½ÄÀÇ ÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» dbmmanage·Î + ¸¸µç ÆÄÀÏ¿¡ ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù. »ç¿ëÀÚ¸íÀÌ + DBM ÆÄÀÏ¿¡ ±â·ÏµÇÀÖÀ»¶§¸¸ ÀÌ ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ÀϹÝÆÄÀÏÀ» µ¥ÀÌÅͺ£À̽º·Î »ç¿ëÇÏ·Á¸é htpasswd¸¦ Âü°íÇ϶ó.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ »ç¿ëÀÚÀÎÁõÀ» ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    dbmmanage [ encoding ] + filename add|adduser|check|delete|update + username + [ encpasswd + [ group[,group...] + [ comment ] ] ]

    + +

    dbmmanage filename + view [ username ]

    + +

    dbmmanage filename import

    +
    top
    +
    +

    ¿É¼Ç

    +
    +
    filename
    +
    DBMÇü½Ä ÆÄÀÏÀÇ ÆÄÀϸí. º¸Åë .db, + .pag, .dir È®ÀåÀÚ¸¦ »«´Ù.
    + +
    username
    +
    ÀÛ¾÷ÇÒ »ç¿ëÀÚ¸í. username¿¡ ÄÝ·Ð(:)À» + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    encpasswd
    +
    update³ª add ¸í·É¿¡ »ç¿ëÇÒ + ÀÌ¹Ì ¾ÏȣȭµÈ ¾ÏÈ£ÀÌ´Ù. ¾ÏÈ£¸¦ ³ªÁß¿¡ ÁöÁ¤ÇÏ°í ½ÍÀº °æ¿ì + »©±â±âÈ£(-)¸¦ »ç¿ëÇÑ´Ù. ¶Ç, update + ¸í·ÉÀ» »ç¿ëÇÒ¶§ ¸¶Ä§Ç¥(.)¸¦ »ç¿ëÇÏ¸é ¿ø·¡ + ¾ÏÈ£¸¦ ±×´ë·Î µÐ´Ù.
    + +
    group
    +
    »ç¿ëÀÚ°¡ ¼ÓÇÑ ±×·ì. ±×·ì¸í¿¡ ÄÝ·Ð(:)À» + »ç¿ëÇÒ ¼ö ¾ø´Ù. »ç¿ëÀÚ¸¦ ±×·ì¿¡ Ãß°¡ÇÏÁö´Â ¾ÊÁö¸¸ ¼³¸í¶õÀ» + ä¿ì°í ½Í´Ù¸é »©±â±âÈ£(-)¸¦ »ç¿ëÇÑ´Ù. ¶Ç, + update ¸í·ÉÀ» »ç¿ëÇÒ¶§ ¸¶Ä§Ç¥(.)¸¦ + »ç¿ëÇÑ´Ù¸é ¿ø·¡ ±×·ìÀ» ±×´ë·Î µÐ´Ù.
    + +
    comment
    +
    ½ÇÁ¦ À̸§, ¸ÞÀÏ ÁÖ¼Ò µî »ç¿ëÀÚ¿¡ ´ëÇÑ ¼³¸íÀ» Àû´Â ¶õÀÌ´Ù. + ¼­¹ö´Â ÀÌ Ç׸ñÀ» ¹«½ÃÇÑ´Ù.
    +
    + +

    ÀÎÄÚµù

    +
    +
    -d
    +
    crypt ¾Ïȣȭ (Win32³ª Netware°¡ ¾Æ´Ï¶ó¸é ±âº»°ª)
    + +
    -m
    +
    MD5 ¾Ïȣȭ (Win32°ú Netware¿¡¼­ ±âº»°ª)
    + +
    -s
    +
    SHA1 ¾Ïȣȭ
    + +
    -p
    +
    ¾ÏÈ£¸¦ ±×´ë·Î ±â·Ï (ÃßõÇÏÁö ¾ÊÀ½)
    +
    + + +

    ¸í·É

    +
    +
    add
    +
    ¾ÏȣȭµÈ ¾ÏÈ£ encpasswd¸¦ »ç¿ëÇÏ¿© + filename¿¡ username Ç׸ñÀ» Ãß°¡ÇÑ´Ù.
    + +
    adduser
    +
    ¾ÏÈ£¸¦ ¹°¾îº¸°í filename¿¡ + username Ç׸ñÀ» Ãß°¡ÇÑ´Ù.
    + +
    check
    +
    ¾ÏÈ£¸¦ ¹°¾îº»ÈÄ filename¿¡ + usernameÀÌ ÀÖ°í ¾ÏÈ£°¡ ÀÏÄ¡ÇÏ´ÂÁö °Ë»çÇÑ´Ù.
    + +
    delete
    +
    filename¿¡¼­ username Ç׸ñÀ» + »èÁ¦ÇÑ´Ù.
    + +
    import
    +
    STDIN¿¡¼­ + username:password Ç׸ñÀ» + (ÇÑÁÙ¿¡ Çϳª¾¿) Àо filename¿¡ Ãß°¡ÇÑ´Ù. + ¾ÏÈ£´Â ÀÌ¹Ì ¾ÏȣȭµÇÀÖ¾î¾ß ÇÑ´Ù.
    + +
    update
    +
    adduser ¸í·É°ú ºñ½ÁÇÏÁö¸¸, + filename¿¡ ÀÌ¹Ì usernameÀÌ ÀÖ´ÂÁö + È®ÀÎÇÑ´Ù.
    + +
    view
    +
    DBM ÆÄÀÏ ³»¿ëÀ» Ãâ·ÂÇÑ´Ù. usernameÀ» + ÁöÁ¤Çϸé ƯÁ¤ Ç׸ñ¸¸À» Ãâ·ÂÇÑ´Ù.
    +
    + +
    top
    +
    +

    ¹ö±×

    +

    ¿©·¯ ´Ù¸¥ DBM ÆÄÀÏÇü½ÄµéÀÌ ÀÖ°í ´ç½ÅÀÇ ½Ã½ºÅÛ¿¡ ¿©·¯ + Çü½Ä¿¡ ´ëÇÑ ºñ½ÁÇÑ ¶óÀ̺귯¸®µéÀÌ ÀÖÀ½À» ÁÖÀÇÇØ¾ß ÇÑ´Ù. + °¡Àå ´ëÇ¥ÀûÀÎ ³×°¡Áö°¡ SDBM, NDBM, GNU ÇÁ·ÎÁ§Æ®ÀÇ GDBM, + Berkeley DB 2ÀÌ´Ù. ºÒÇàÈ÷µµ ÀÌ ¶óÀ̺귯¸®µéÀº ¸ðµÎ ´Ù¸¥ + ÆÄÀÏÇü½ÄÀ» »ç¿ëÇÑ´Ù. ±×·¡¼­ filenameÀÌ »ç¿ëÇÏ´Â + ÆÄÀÏÇü½ÄÀÌ dbmmanage°¡ ¿øÇÏ´Â Çü½Ä°ú °°ÀºÁö + È®ÀÎÇØ¾ß ÇÑ´Ù. dbmmanage´Â DBM ÆÄÀÏÀÇ Çü½ÄÀ» + ¾Ë¾Æ³»Áö ¸øÇÑ´Ù. ´Ù¸¥ Çü½ÄÀ» »ç¿ëÇÏ¸é ¾Æ¹«Àϵµ ÇÏÁö ¾Ê°Å³ª, + ´Ù¸§ À̸§ÀÇ DBM ÆÄÀÏÀ» ¸¸µé°Å³ª, ÃÖ¾ÇÀÇ °æ¿ì ÆÄÀÏÀ» ±â·ÏÇÏ¿© + DBM ÆÄÀÏÀ» ¸ÁÄ¥ ¼ö ÀÖ´Ù.

    + +

    dbmmanage ÇÁ·Î±×·¥ ¾ÕºÎºÐ¿¡ ÀÖ´Â + @AnyDBM::ISA ¹è¿­ÀÌ DBMÇü½Ä ¼±È£¼ø¼­ÀÌ´Ù. + ¿ì¸®´Â Berkeley DB 2 ÆÄÀÏÇü½ÄÀ» ¼±È£ÇϹǷΠ+ dbmmanage°¡ ½Ã½ºÅÛ ¶óÀ̺귯¸®¸¦ ã´Â ¼ø¼­´Â + Berkeley DB 2, NDBM, GDBM, SDBM ¼øÀÌ´Ù. dbmmanage´Â + Á¦ÀÏ ¸ÕÀú ãÀº ¶óÀ̺귯¸®¸¦ »ç¿ëÇÏ¿© ¸ðµç DBM ÆÄÀÏ ÀÛ¾÷À» + ÇÑ´Ù. ÀÌ ¼ø¼­´Â PerlÀÇ °£´ÜÇÑ dbmopen() È£ÃâÀÌ + »ç¿ëÇÏ´Â ¼ø¼­³ª PerlÀÇ Ç¥ÁØ @AnyDBM::ISA ¼ø¼­¿Í + Á¶±Ý ´Ù¸£´Ù. ±×·¡¼­ ´Ù¸¥ µµ±¸¸¦ »ç¿ëÇÏ¿© DBM ÆÄÀÏÀ» °ü¸®ÇÑ´Ù¸é + ÀÌ ¼ø¼­¸¦ µû¶ó¾ß ÇÑ´Ù. C¿Í °°ÀÌ ´Ù¸¥ ¾ð¾î·Î ÀÛ¼ºÇÑ ÇÁ·Î±×·¥À» + »ç¿ëÇÏ¿© ÆÄÀÏÀ» ´Ù·ç´Â °æ¿ì¿¡µµ ¸¶Âù°¡Áö´Ù.

    + +

    ´ëºÎºÐÀÇ À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ file ÇÁ·Î±×·¥À¸·Î + DBM ÆÄÀÏÇü½ÄÀ» È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/dbmmanage.xml b/trunk/docs/manual/programs/dbmmanage.xml new file mode 100644 index 0000000000..14dd69820e --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.xml @@ -0,0 +1,189 @@ + + + + + + + + +Programs + +dbmmanage - Manage user authentication files in DBM format + + +

    dbmmanage is used to create and update the DBM format files + used to store usernames and password for basic authentication of HTTP users + via mod_authn_dbm. + Resources available from the Apache HTTP server can be restricted to just + the users listed in the files created by dbmmanage. This + program can only be used when the usernames are stored in a DBM file. To + use a flat-file database see htpasswd.

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure user authentication in + httpd see the httpd manual, which is part of + the Apache distribution or can be found at http://httpd.apache.org/.

    +
    +httpd +mod_authn_dbm +mod_authz_dbm + +
    Synopsis +

    dbmmanage [ encoding ] + filename add|adduser|check|delete|update + username + [ encpasswd + [ group[,group...] + [ comment ] ] ]

    + +

    dbmmanage filename + view [ username ]

    + +

    dbmmanage filename import

    +
    + +
    Options +
    +
    filename
    +
    The filename of the DBM format file. Usually without the extension + .db, .pag, or .dir.
    + +
    username
    +
    The user for which the operations are performed. The username + may not contain a colon (:).
    + +
    encpasswd
    +
    This is the already encrypted password to use for the + update and add commands. You may use a hyphen + (-) if you want to get prompted for the password, but fill + in the fields afterwards. Additionally when using the update + command, a period (.) keeps the original password + untouched.
    + +
    group
    +
    A group, which the user is member of. A groupname may not contain a + colon (:). You may use a hyphen (-) if you don't + want to assign the user to a group, but fill in the comment field. + Additionally when using the update command, a period + (.) keeps the original groups untouched.
    + +
    comment
    +
    This is the place for your opaque comments about the user, like + realname, mailaddress or such things. The server will ignore this + field.
    +
    + +
    Encodings +
    +
    -d
    +
    crypt encryption (default, except on Win32, Netware)
    + +
    -m
    +
    MD5 encryption (default on Win32, Netware)
    + +
    -s
    +
    SHA1 encryption
    + +
    -p
    +
    plaintext (not recommended)
    +
    +
    + +
    Commands +
    +
    add
    +
    Adds an entry for username to filename using the + encrypted password encpasswd. + + dbmmanage passwords.dat add rbowen foKntnEF3KSXA +
    + +
    adduser
    +
    Asks for a password and then adds an entry for username to + filename. + + dbmmanage passwords.dat adduser krietz +
    + +
    check
    +
    Asks for a password and then checks if username is in + filename and if it's password matches the specified one. + + dbmmanage passwords.dat check rbowen +
    + +
    delete
    +
    Deletes the username entry from filename. + + dbmmanage passwords.dat delete rbowen +
    + +
    import
    +
    Reads username:password entries + (one per line) from STDIN and adds them to + filename. The passwords already have to be crypted.
    + +
    update
    +
    Same as the adduser command, except that it makes + sure username already exists in filename. + + dbmmanage passwords.dat update rbowen +
    + +
    view
    +
    Just displays the contents of the DBM file. If you specify a + username, it displays the particular record only. + + dbmmanage passwords.dat view +
    +
    +
    +
    + +
    Bugs +

    One should be aware that there are a number of different DBM file formats + in existence, and with all likelihood, libraries for more than one format + may exist on your system. The three primary examples are SDBM, 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 filename is the same format that dbmmanage + expects to see. dbmmanage currently has no way of determining + what type of DBM file it is looking at. If used against the wrong format, + 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.

    + +

    dbmmanage has a list of DBM format preferences, defined by + the @AnyDBM::ISA array near the beginning of the program. Since + we prefer the Berkeley DB 2 file format, the order in which + dbmmanage will look for system libraries is Berkeley DB 2, + then NDBM, then GDBM and then SDBM. The first library found will be the + library dbmmanage will attempt to use for all DBM file + transactions. This ordering is slightly different than the standard + @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.

    + +

    One can usually use the file program supplied with most + Unix systems to see what format a DBM file is in.

    +
    + +
    diff --git a/trunk/docs/manual/programs/dbmmanage.xml.ko b/trunk/docs/manual/programs/dbmmanage.xml.ko new file mode 100644 index 0000000000..cda5dbd7c1 --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.xml.ko @@ -0,0 +1,170 @@ + + + + + + + + +Programs + +dbmmanage - DBM Çü½ÄÀÇ »ç¿ëÀÚÀÎÁõ ÆÄÀÏÀ» °ü¸®ÇÑ´Ù + + +

    dbmmanage´Â HTTP basic authentication¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â DBMÇü½ÄÀÇ ÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» dbmmanage·Î + ¸¸µç ÆÄÀÏ¿¡ ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù. »ç¿ëÀÚ¸íÀÌ + DBM ÆÄÀÏ¿¡ ±â·ÏµÇÀÖÀ»¶§¸¸ ÀÌ ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. + ÀϹÝÆÄÀÏÀ» µ¥ÀÌÅͺ£À̽º·Î »ç¿ëÇÏ·Á¸é htpasswd¸¦ Âü°íÇ϶ó.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ »ç¿ëÀÚÀÎÁõÀ» ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    +httpd +mod_authn_dbm +mod_authz_dbm + +
    °³¿ä +

    dbmmanage [ encoding ] + filename add|adduser|check|delete|update + username + [ encpasswd + [ group[,group...] + [ comment ] ] ]

    + +

    dbmmanage filename + view [ username ]

    + +

    dbmmanage filename import

    +
    + +
    ¿É¼Ç +
    +
    filename
    +
    DBMÇü½Ä ÆÄÀÏÀÇ ÆÄÀϸí. º¸Åë .db, + .pag, .dir È®ÀåÀÚ¸¦ »«´Ù.
    + +
    username
    +
    ÀÛ¾÷ÇÒ »ç¿ëÀÚ¸í. username¿¡ ÄÝ·Ð(:)À» + »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    encpasswd
    +
    update³ª add ¸í·É¿¡ »ç¿ëÇÒ + ÀÌ¹Ì ¾ÏȣȭµÈ ¾ÏÈ£ÀÌ´Ù. ¾ÏÈ£¸¦ ³ªÁß¿¡ ÁöÁ¤ÇÏ°í ½ÍÀº °æ¿ì + »©±â±âÈ£(-)¸¦ »ç¿ëÇÑ´Ù. ¶Ç, update + ¸í·ÉÀ» »ç¿ëÇÒ¶§ ¸¶Ä§Ç¥(.)¸¦ »ç¿ëÇÏ¸é ¿ø·¡ + ¾ÏÈ£¸¦ ±×´ë·Î µÐ´Ù.
    + +
    group
    +
    »ç¿ëÀÚ°¡ ¼ÓÇÑ ±×·ì. ±×·ì¸í¿¡ ÄÝ·Ð(:)À» + »ç¿ëÇÒ ¼ö ¾ø´Ù. »ç¿ëÀÚ¸¦ ±×·ì¿¡ Ãß°¡ÇÏÁö´Â ¾ÊÁö¸¸ ¼³¸í¶õÀ» + ä¿ì°í ½Í´Ù¸é »©±â±âÈ£(-)¸¦ »ç¿ëÇÑ´Ù. ¶Ç, + update ¸í·ÉÀ» »ç¿ëÇÒ¶§ ¸¶Ä§Ç¥(.)¸¦ + »ç¿ëÇÑ´Ù¸é ¿ø·¡ ±×·ìÀ» ±×´ë·Î µÐ´Ù.
    + +
    comment
    +
    ½ÇÁ¦ À̸§, ¸ÞÀÏ ÁÖ¼Ò µî »ç¿ëÀÚ¿¡ ´ëÇÑ ¼³¸íÀ» Àû´Â ¶õÀÌ´Ù. + ¼­¹ö´Â ÀÌ Ç׸ñÀ» ¹«½ÃÇÑ´Ù.
    +
    + +
    ÀÎÄÚµù +
    +
    -d
    +
    crypt ¾Ïȣȭ (Win32³ª Netware°¡ ¾Æ´Ï¶ó¸é ±âº»°ª)
    + +
    -m
    +
    MD5 ¾Ïȣȭ (Win32°ú Netware¿¡¼­ ±âº»°ª)
    + +
    -s
    +
    SHA1 ¾Ïȣȭ
    + +
    -p
    +
    ¾ÏÈ£¸¦ ±×´ë·Î ±â·Ï (ÃßõÇÏÁö ¾ÊÀ½)
    +
    +
    + +
    ¸í·É +
    +
    add
    +
    ¾ÏȣȭµÈ ¾ÏÈ£ encpasswd¸¦ »ç¿ëÇÏ¿© + filename¿¡ username Ç׸ñÀ» Ãß°¡ÇÑ´Ù.
    + +
    adduser
    +
    ¾ÏÈ£¸¦ ¹°¾îº¸°í filename¿¡ + username Ç׸ñÀ» Ãß°¡ÇÑ´Ù.
    + +
    check
    +
    ¾ÏÈ£¸¦ ¹°¾îº»ÈÄ filename¿¡ + usernameÀÌ ÀÖ°í ¾ÏÈ£°¡ ÀÏÄ¡ÇÏ´ÂÁö °Ë»çÇÑ´Ù.
    + +
    delete
    +
    filename¿¡¼­ username Ç׸ñÀ» + »èÁ¦ÇÑ´Ù.
    + +
    import
    +
    STDIN¿¡¼­ + username:password Ç׸ñÀ» + (ÇÑÁÙ¿¡ Çϳª¾¿) Àо filename¿¡ Ãß°¡ÇÑ´Ù. + ¾ÏÈ£´Â ÀÌ¹Ì ¾ÏȣȭµÇÀÖ¾î¾ß ÇÑ´Ù.
    + +
    update
    +
    adduser ¸í·É°ú ºñ½ÁÇÏÁö¸¸, + filename¿¡ ÀÌ¹Ì usernameÀÌ ÀÖ´ÂÁö + È®ÀÎÇÑ´Ù.
    + +
    view
    +
    DBM ÆÄÀÏ ³»¿ëÀ» Ãâ·ÂÇÑ´Ù. usernameÀ» + ÁöÁ¤Çϸé ƯÁ¤ Ç׸ñ¸¸À» Ãâ·ÂÇÑ´Ù.
    +
    +
    +
    + +
    ¹ö±× +

    ¿©·¯ ´Ù¸¥ DBM ÆÄÀÏÇü½ÄµéÀÌ ÀÖ°í ´ç½ÅÀÇ ½Ã½ºÅÛ¿¡ ¿©·¯ + Çü½Ä¿¡ ´ëÇÑ ºñ½ÁÇÑ ¶óÀ̺귯¸®µéÀÌ ÀÖÀ½À» ÁÖÀÇÇØ¾ß ÇÑ´Ù. + °¡Àå ´ëÇ¥ÀûÀÎ ³×°¡Áö°¡ SDBM, NDBM, GNU ÇÁ·ÎÁ§Æ®ÀÇ GDBM, + Berkeley DB 2ÀÌ´Ù. ºÒÇàÈ÷µµ ÀÌ ¶óÀ̺귯¸®µéÀº ¸ðµÎ ´Ù¸¥ + ÆÄÀÏÇü½ÄÀ» »ç¿ëÇÑ´Ù. ±×·¡¼­ filenameÀÌ »ç¿ëÇÏ´Â + ÆÄÀÏÇü½ÄÀÌ dbmmanage°¡ ¿øÇÏ´Â Çü½Ä°ú °°ÀºÁö + È®ÀÎÇØ¾ß ÇÑ´Ù. dbmmanage´Â DBM ÆÄÀÏÀÇ Çü½ÄÀ» + ¾Ë¾Æ³»Áö ¸øÇÑ´Ù. ´Ù¸¥ Çü½ÄÀ» »ç¿ëÇÏ¸é ¾Æ¹«Àϵµ ÇÏÁö ¾Ê°Å³ª, + ´Ù¸§ À̸§ÀÇ DBM ÆÄÀÏÀ» ¸¸µé°Å³ª, ÃÖ¾ÇÀÇ °æ¿ì ÆÄÀÏÀ» ±â·ÏÇÏ¿© + DBM ÆÄÀÏÀ» ¸ÁÄ¥ ¼ö ÀÖ´Ù.

    + +

    dbmmanage ÇÁ·Î±×·¥ ¾ÕºÎºÐ¿¡ ÀÖ´Â + @AnyDBM::ISA ¹è¿­ÀÌ DBMÇü½Ä ¼±È£¼ø¼­ÀÌ´Ù. + ¿ì¸®´Â Berkeley DB 2 ÆÄÀÏÇü½ÄÀ» ¼±È£ÇϹǷΠ+ dbmmanage°¡ ½Ã½ºÅÛ ¶óÀ̺귯¸®¸¦ ã´Â ¼ø¼­´Â + Berkeley DB 2, NDBM, GDBM, SDBM ¼øÀÌ´Ù. dbmmanage´Â + Á¦ÀÏ ¸ÕÀú ãÀº ¶óÀ̺귯¸®¸¦ »ç¿ëÇÏ¿© ¸ðµç DBM ÆÄÀÏ ÀÛ¾÷À» + ÇÑ´Ù. ÀÌ ¼ø¼­´Â PerlÀÇ °£´ÜÇÑ dbmopen() È£ÃâÀÌ + »ç¿ëÇÏ´Â ¼ø¼­³ª PerlÀÇ Ç¥ÁØ @AnyDBM::ISA ¼ø¼­¿Í + Á¶±Ý ´Ù¸£´Ù. ±×·¡¼­ ´Ù¸¥ µµ±¸¸¦ »ç¿ëÇÏ¿© DBM ÆÄÀÏÀ» °ü¸®ÇÑ´Ù¸é + ÀÌ ¼ø¼­¸¦ µû¶ó¾ß ÇÑ´Ù. C¿Í °°ÀÌ ´Ù¸¥ ¾ð¾î·Î ÀÛ¼ºÇÑ ÇÁ·Î±×·¥À» + »ç¿ëÇÏ¿© ÆÄÀÏÀ» ´Ù·ç´Â °æ¿ì¿¡µµ ¸¶Âù°¡Áö´Ù.

    + +

    ´ëºÎºÐÀÇ À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ file ÇÁ·Î±×·¥À¸·Î + DBM ÆÄÀÏÇü½ÄÀ» È®ÀÎÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/programs/dbmmanage.xml.meta b/trunk/docs/manual/programs/dbmmanage.xml.meta new file mode 100644 index 0000000000..b5cd0d7f31 --- /dev/null +++ b/trunk/docs/manual/programs/dbmmanage.xml.meta @@ -0,0 +1,12 @@ + + + + dbmmanage + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/htcacheclean.html b/trunk/docs/manual/programs/htcacheclean.html new file mode 100644 index 0000000000..454c00465f --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.html @@ -0,0 +1,7 @@ +URI: htcacheclean.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: htcacheclean.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/htcacheclean.html.en b/trunk/docs/manual/programs/htcacheclean.html.en new file mode 100644 index 0000000000..fbaaa64b79 --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.html.en @@ -0,0 +1,109 @@ + + + +htcacheclean - Clean up the disk cache - Apache HTTP Server + + + + + +
    <-
    +

    htcacheclean - Clean up the disk cache

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    htcacheclean is used to keep the size of + mod_disk_cache's storage within a certain limit. This + tool can run either manually or in daemon mode. When running in + daemon mode, it sleeps in the background and checks the cache directories + at regular intervals for cached content to be removed. You can stop the daemon + cleanly by sending it a TERM or INT signal.

    +
    + +
    top
    +
    +

    Synopsis

    +

    htcacheclean + [ -D ] + [ -v ] + [ -r ] + [ -n ] + -ppath + -llimit

    + +

    htcacheclean -b + [ -n ] + [ -i ] + -dinterval + -ppath + -llimit

    +
    top
    +
    +

    Options

    +
    +
    -dinterval
    +
    Daemonize and repeat cache cleaning every interval minutes. + This option is mutually exclusive with the -D, -v + and -r options. To shutdown the daemon cleanly, just send it + a SIGTERM or SIGINT.
    + +
    -D
    +
    Do a dry run and don't delete anything. This option is mutually + exclusive with the -d option.
    + +
    -v
    +
    Be verbose and print statistics. This option is mutually exclusive + with the -d option.
    + +
    -r
    +
    Clean thoroughly. This assumes that the Apache web server is + not running (otherwise you may get garbage in the cache). This option + is mutually exclusive with the -d option.
    + +
    -n
    +
    Be nice. This causes slower processing in favour of other + processes. htcacheclean will sleep from time to time + so that (a) the disk IO will be delayed and (b) the kernel can schedule + other processes in the meantime.
    + +
    -ppath
    +
    Specify path as the root directory of the disk cache. This + should be the same value as specified with the CacheRoot directive.
    + +
    -llimit
    +
    Specify limit as the total disk cache size limit. The value + is expressed in bytes by default (or attaching B to the + number). Attach K for Kbytes or M for + MBytes.
    + +
    -i
    +
    Be intelligent and run only when there was a modification of the disk + cache. This option is only possible together with the -d + option.
    +
    +
    top
    +
    +

    Exit Status

    +

    htcacheclean returns a zero status ("true") if all + operations were successful, 1 otherwise.

    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htcacheclean.html.ko.euc-kr b/trunk/docs/manual/programs/htcacheclean.html.ko.euc-kr new file mode 100644 index 0000000000..eedcdb76e8 --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.html.ko.euc-kr @@ -0,0 +1,113 @@ + + + +htcacheclean - µð½ºÅ© ij½¬¸¦ û¼ÒÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    htcacheclean - µð½ºÅ© ij½¬¸¦ û¼ÒÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    htcachecleanÀº mod_disk_cache°¡ + »ç¿ëÇÏ´Â ÀúÀå¼Ò ¿ë·®À» ÀÏÁ¤ Çѵµ·Î À¯ÁöÇÑ´Ù. ÀÌ µµ±¸´Â Á÷Á¢ + ½ÇÇàÇϰųª µ¥¸ó(daemon)À¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÇÁ·Î±×·¥À» µ¥¸óÀ¸·Î + ½ÇÇàÇÏ¸é ¹é±×¶ó¿îµå¿¡¼­ ÀáÀÚ°í ÀÖ´Ù°¡ ÀÏÁ¤ ÁÖ±â·Î ij½¬ + µð·ºÅ丮¿¡¼­ Áö¿ï °ÍÀÌ ÀÖ´ÂÁö °Ë»çÇÑ´Ù. µ¥¸ó¿¡°Ô TERMÀ̳ª + INT ½Ã±×³ÎÀ» º¸³»¸é ¾ÈÀüÇÏ°Ô Á¾·áÇÑ´Ù.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    htcacheclean + [ -D ] + [ -v ] + [ -r ] + [ -n ] + -ppath + -llimit

    + +

    htcacheclean -b + [ -n ] + [ -i ] + -dinterval + -ppath + -llimit

    +
    top
    +
    +

    ¿É¼Ç

    +
    +
    -dinterval
    +
    µ¥¸óÀ¸·Î ½ÇÇàÇÏ¿© interval ºÐ¸¶´Ù ij½¬¸¦ + û¼ÒÇÑ´Ù. ÀÌ ¿É¼ÇÀº -D, -v, + -r ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù. µ¥¸óÀ» ¾ÈÀüÇÏ°Ô + Á¾·áÇÏ·Á¸é µ¥¸ó¿¡°Ô SIGTERM ȤÀº + SIGINT ½Ã±×³ÎÀ» º¸³»¸é µÈ´Ù.
    + +
    -D
    +
    °Ë»ç¸¸ ÇÏ°í ½ÇÁ¦ ¾Æ¹«°Íµµ Áö¿ìÁö ¾Ê´Â´Ù. ÀÌ ¿É¼ÇÀº + -d ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -v
    +
    ÀÚ¼¼ÇÑ Åë°è¸¦ Ãâ·ÂÇÑ´Ù. ÀÌ ¿É¼ÇÀº -d ¿É¼Ç°ú + ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -r
    +
    ¿ÏÀüÈ÷ û¼ÒÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ µ¿ÀÛÇÏÁö ¾Ê´Â´Ù°í °¡Á¤ÇÑ´Ù + (¸¸¾à µ¿ÀÛÇÑ´Ù¸é ij½¬¿¡ ÀÌ»óÇÑ °ªÀÌ ÀúÀåµÈ´Ù). ÀÌ ¿É¼ÇÀº + -d ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -n
    +
    Ä£ÀýÇÏ°Ô(nice) µ¿ÀÛÇÑ´Ù. ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ À§ÇØ ´À¸®°Ô + µ¿ÀÛÇÑ´Ù. htcacheclean°¡ ÀÚÁÖ ÀáÀ» ÀڰԵǿ© + (1) µð½ºÅ© ÀÔÃâ·ÂÀÌ Áö¿¬µÇ°í (2) ±×µ¿¾È Ä¿³ÎÀº ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ + ½ºÄÉÁÙÇÒ ¼ö ÀÖ´Ù.
    + +
    -ppath
    +
    path¸¦ µð½ºÅ© ij½¬ÀÇ ÃÖ»óÀ§ µð·ºÅ丮·Î ÁöÁ¤ÇÑ´Ù. + CacheRoot + Áö½Ã¾î¿¡ »ç¿ëÇÑ °ª°ú µ¿ÀÏÇÑ °ªÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    -llimit
    +
    Àüü µð½ºÅ© ij½¬ ¿ë·® Á¦ÇÑÀ» limit·Î Á¦ÇÑÇÑ´Ù. + °ªÀº ±âº»ÀûÀ¸·Î (ȤÀº ¼ýÀÚ¿¡ B¸¦ ºÙÀ̸é) ¹ÙÀÌÆ® + ´ÜÀ§ÀÌ´Ù. ų·Î¹ÙÀÌÆ®´Â K¸¦, ¸Þ°¡¹ÙÀÌÆ®´Â + MÀ» µÚ¿¡ ºÙÀδÙ.
    + +
    -i
    +
    Áö´ÉÀûÀ¸·Î µð½ºÅ© ij½¬°¡ º¯°æµÈ °æ¿ì¿¡¸¸ µ¿ÀÛÇÑ´Ù. ÀÌ + ¿É¼ÇÀº -d ¿É¼Ç°ú ÇÔ²²¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +
    +
    top
    +
    +

    Á¾·áÄÚµå

    +

    htcacheclean´Â ¸ðµç ÀÛ¾÷ÀÌ ¼º°øÇÑ °æ¿ì¿¡ + ("Âü") Á¾·áÄÚµå 0À» ¹ÝȯÇÏ°í, ½ÇÆÐÇÑ °æ¿ì¿¡´Â 1À» + ¹ÝȯÇÑ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htcacheclean.xml b/trunk/docs/manual/programs/htcacheclean.xml new file mode 100644 index 0000000000..19b835c87f --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.xml @@ -0,0 +1,105 @@ + + + + + + + + +Programs + +htcacheclean - Clean up the disk cache + + +

    htcacheclean is used to keep the size of + mod_disk_cache's storage within a certain limit. This + tool can run either manually or in daemon mode. When running in + daemon mode, it sleeps in the background and checks the cache directories + at regular intervals for cached content to be removed. You can stop the daemon + cleanly by sending it a TERM or INT signal.

    +
    +mod_disk_cache + +
    Synopsis +

    htcacheclean + [ -D ] + [ -v ] + [ -r ] + [ -n ] + -ppath + -llimit

    + +

    htcacheclean -b + [ -n ] + [ -i ] + -dinterval + -ppath + -llimit

    +
    + +
    Options +
    +
    -dinterval
    +
    Daemonize and repeat cache cleaning every interval minutes. + This option is mutually exclusive with the -D, -v + and -r options. To shutdown the daemon cleanly, just send it + a SIGTERM or SIGINT.
    + +
    -D
    +
    Do a dry run and don't delete anything. This option is mutually + exclusive with the -d option.
    + +
    -v
    +
    Be verbose and print statistics. This option is mutually exclusive + with the -d option.
    + +
    -r
    +
    Clean thoroughly. This assumes that the Apache web server is + not running (otherwise you may get garbage in the cache). This option + is mutually exclusive with the -d option.
    + +
    -n
    +
    Be nice. This causes slower processing in favour of other + processes. htcacheclean will sleep from time to time + so that (a) the disk IO will be delayed and (b) the kernel can schedule + other processes in the meantime.
    + +
    -ppath
    +
    Specify path as the root directory of the disk cache. This + should be the same value as specified with the CacheRoot directive.
    + +
    -llimit
    +
    Specify limit as the total disk cache size limit. The value + is expressed in bytes by default (or attaching B to the + number). Attach K for Kbytes or M for + MBytes.
    + +
    -i
    +
    Be intelligent and run only when there was a modification of the disk + cache. This option is only possible together with the -d + option.
    +
    +
    + +
    Exit Status +

    htcacheclean returns a zero status ("true") if all + operations were successful, 1 otherwise.

    +
    + +
    diff --git a/trunk/docs/manual/programs/htcacheclean.xml.ko b/trunk/docs/manual/programs/htcacheclean.xml.ko new file mode 100644 index 0000000000..f98c7aeb43 --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.xml.ko @@ -0,0 +1,106 @@ + + + + + + + + +Programs + +htcacheclean - µð½ºÅ© ij½¬¸¦ û¼ÒÇÑ´Ù + + +

    htcachecleanÀº mod_disk_cache°¡ + »ç¿ëÇÏ´Â ÀúÀå¼Ò ¿ë·®À» ÀÏÁ¤ Çѵµ·Î À¯ÁöÇÑ´Ù. ÀÌ µµ±¸´Â Á÷Á¢ + ½ÇÇàÇϰųª µ¥¸ó(daemon)À¸·Î ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ÇÁ·Î±×·¥À» µ¥¸óÀ¸·Î + ½ÇÇàÇÏ¸é ¹é±×¶ó¿îµå¿¡¼­ ÀáÀÚ°í ÀÖ´Ù°¡ ÀÏÁ¤ ÁÖ±â·Î ij½¬ + µð·ºÅ丮¿¡¼­ Áö¿ï °ÍÀÌ ÀÖ´ÂÁö °Ë»çÇÑ´Ù. µ¥¸ó¿¡°Ô TERMÀ̳ª + INT ½Ã±×³ÎÀ» º¸³»¸é ¾ÈÀüÇÏ°Ô Á¾·áÇÑ´Ù.

    +
    +mod_disk_cache + +
    °³¿ä +

    htcacheclean + [ -D ] + [ -v ] + [ -r ] + [ -n ] + -ppath + -llimit

    + +

    htcacheclean -b + [ -n ] + [ -i ] + -dinterval + -ppath + -llimit

    +
    + +
    ¿É¼Ç +
    +
    -dinterval
    +
    µ¥¸óÀ¸·Î ½ÇÇàÇÏ¿© interval ºÐ¸¶´Ù ij½¬¸¦ + û¼ÒÇÑ´Ù. ÀÌ ¿É¼ÇÀº -D, -v, + -r ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù. µ¥¸óÀ» ¾ÈÀüÇÏ°Ô + Á¾·áÇÏ·Á¸é µ¥¸ó¿¡°Ô SIGTERM ȤÀº + SIGINT ½Ã±×³ÎÀ» º¸³»¸é µÈ´Ù.
    + +
    -D
    +
    °Ë»ç¸¸ ÇÏ°í ½ÇÁ¦ ¾Æ¹«°Íµµ Áö¿ìÁö ¾Ê´Â´Ù. ÀÌ ¿É¼ÇÀº + -d ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -v
    +
    ÀÚ¼¼ÇÑ Åë°è¸¦ Ãâ·ÂÇÑ´Ù. ÀÌ ¿É¼ÇÀº -d ¿É¼Ç°ú + ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -r
    +
    ¿ÏÀüÈ÷ û¼ÒÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ µ¿ÀÛÇÏÁö ¾Ê´Â´Ù°í °¡Á¤ÇÑ´Ù + (¸¸¾à µ¿ÀÛÇÑ´Ù¸é ij½¬¿¡ ÀÌ»óÇÑ °ªÀÌ ÀúÀåµÈ´Ù). ÀÌ ¿É¼ÇÀº + -d ¿É¼Ç°ú ÇÔ²² »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -n
    +
    Ä£ÀýÇÏ°Ô(nice) µ¿ÀÛÇÑ´Ù. ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ À§ÇØ ´À¸®°Ô + µ¿ÀÛÇÑ´Ù. htcacheclean°¡ ÀÚÁÖ ÀáÀ» ÀڰԵǿ© + (1) µð½ºÅ© ÀÔÃâ·ÂÀÌ Áö¿¬µÇ°í (2) ±×µ¿¾È Ä¿³ÎÀº ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ + ½ºÄÉÁÙÇÒ ¼ö ÀÖ´Ù.
    + +
    -ppath
    +
    path¸¦ µð½ºÅ© ij½¬ÀÇ ÃÖ»óÀ§ µð·ºÅ丮·Î ÁöÁ¤ÇÑ´Ù. + CacheRoot + Áö½Ã¾î¿¡ »ç¿ëÇÑ °ª°ú µ¿ÀÏÇÑ °ªÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.
    + +
    -llimit
    +
    Àüü µð½ºÅ© ij½¬ ¿ë·® Á¦ÇÑÀ» limit·Î Á¦ÇÑÇÑ´Ù. + °ªÀº ±âº»ÀûÀ¸·Î (ȤÀº ¼ýÀÚ¿¡ B¸¦ ºÙÀ̸é) ¹ÙÀÌÆ® + ´ÜÀ§ÀÌ´Ù. ų·Î¹ÙÀÌÆ®´Â K¸¦, ¸Þ°¡¹ÙÀÌÆ®´Â + MÀ» µÚ¿¡ ºÙÀδÙ.
    + +
    -i
    +
    Áö´ÉÀûÀ¸·Î µð½ºÅ© ij½¬°¡ º¯°æµÈ °æ¿ì¿¡¸¸ µ¿ÀÛÇÑ´Ù. ÀÌ + ¿É¼ÇÀº -d ¿É¼Ç°ú ÇÔ²²¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +
    +
    + +
    Á¾·áÄÚµå +

    htcacheclean´Â ¸ðµç ÀÛ¾÷ÀÌ ¼º°øÇÑ °æ¿ì¿¡ + ("Âü") Á¾·áÄÚµå 0À» ¹ÝȯÇÏ°í, ½ÇÆÐÇÑ °æ¿ì¿¡´Â 1À» + ¹ÝȯÇÑ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/programs/htcacheclean.xml.meta b/trunk/docs/manual/programs/htcacheclean.xml.meta new file mode 100644 index 0000000000..43637e3ea8 --- /dev/null +++ b/trunk/docs/manual/programs/htcacheclean.xml.meta @@ -0,0 +1,12 @@ + + + + htcacheclean + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/htdbm.html b/trunk/docs/manual/programs/htdbm.html new file mode 100644 index 0000000000..ad1f2a2867 --- /dev/null +++ b/trunk/docs/manual/programs/htdbm.html @@ -0,0 +1,3 @@ +URI: htdbm.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/programs/htdbm.html.en b/trunk/docs/manual/programs/htdbm.html.en new file mode 100644 index 0000000000..e6a935abb5 --- /dev/null +++ b/trunk/docs/manual/programs/htdbm.html.en @@ -0,0 +1,281 @@ + + + +htdbm - Manipulate DBM password databases - Apache HTTP Server + + + + + +
    <-
    +

    htdbm - Manipulate DBM password databases

    +
    +

    Available Languages:  en 

    +
    + +

    htdbm is used to manipulate the DBM format files used to + store usernames and password for basic authentication of HTTP users via + mod_auth_dbm. See the dbmmanage + documentation for more information about these DBM files.

    +
    + +
    top
    +
    +

    Synopsis

    +

    htdbm + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + [ -x ] + filename username

    + +

    htdbm -b + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username password

    + +

    htdbm -n + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + username

    + +

    htdbm -nb + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + username password

    + +

    htdbm -v + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username

    + +

    htdbm -vb + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username password

    + +

    htdbm -x + [ -TDBTYPE ] + [ -m | + -d | + -p | + -s ] + filename username

    + +

    htdbm -l + [ -TDBTYPE ] +

    +
    top
    +
    +

    Options

    +
    +
    -b
    +
    Use batch mode; i.e., get the password from the command line + rather than prompting for it. This option should be used with extreme care, + since the password is clearly visible on the command + line.
    + +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is rewritten and truncated. This option cannot be combined with + the -n option.
    + +
    -n
    +
    Display the results on standard output rather than updating a + database. This option changes the syntax of the command line, since the + passwdfile argument (usually the first one) is omitted. It + cannot be combined with the -c option.
    + +
    -m
    +
    Use MD5 encryption for passwords. On Windows, Netware and TPF, this is + the default.
    + +
    -d
    +
    Use crypt() encryption for passwords. The default on all + platforms but Windows, Netware and TPF. Though possibly supported by + htdbm on all platforms, it is not supported by the + httpd server on Windows, Netware and TPF.
    + +
    -s
    +
    Use SHA encryption for passwords. Facilitates migration from/to Netscape + servers using the LDAP Directory Interchange Format (ldif).
    + +
    -p
    +
    Use plaintext passwords. Though htdbm will support + creation on all platforms, the httpd daemon will + only accept plain text passwords on Windows, Netware and TPF.
    + +
    -l
    +
    Print each of the usernames and comments from the database on + stdout.
    + +
    -t
    +
    Interpret the final parameter as a comment. When this option is + specified, an additional string can be appended to the command line; this + string will be stored in the "Comment" field of the database, associated + with the specified username.
    + +
    -v
    +
    Verify the username and password. The program will print a message + indicating whether the supplied password is valid. If the password is + invalid, the program exits with error code 3.
    + +
    -x
    +
    Delete user. If the username exists in the specified DBM file, it + will be deleted.
    + +
    filename
    +
    The filename of the DBM format file. Usually without the extension + .db, .pag, or .dir. If + -c is given, the DBM file is created if it does not already + exist, or updated if it does exist.
    + +
    username
    +
    The username to create or update in passwdfile. If + username does not exist in this file, an entry is added. If it + does exist, the password is changed.
    + +
    password
    +
    The plaintext password to be encrypted and stored in the DBM file. + Used only with the -b flag.
    + +
    -TDBTYPE
    +
    Type of DBM file (SDBM, GDBM, DB, or "default").
    +
    +
    top
    +
    +

    Bugs

    +

    One should be aware that there are a number of different DBM file + formats in existence, and with all likelihood, libraries for more than + one format may exist on your system. The three primary examples are + SDBM, NDBM, GNU GDBM, and Berkeley/Sleepycat DB 2/3/4. Unfortunately, + all these libraries use different file formats, and you must make sure + that the file format used by filename is the same format that + htdbm expects to see. htdbm currently has + no way of determining what type of DBM file it is looking at. If used + against the wrong format, 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.

    + +

    One can usually use the file program supplied with most + Unix systems to see what format a DBM file is in.

    +
    top
    +
    +

    Exit Status

    +

    htdbm returns a zero status ("true") if the username and + password have been successfully added or updated in the DBM File. + htdbm returns 1 if it encounters some problem + accessing files, 2 if there was a syntax problem with the + command line, 3 if the password was entered interactively and + the verification entry didn't match, 4 if its operation was + interrupted, 5 if a value is too long (username, filename, + password, or final computed record), 6 if the username + contains illegal characters (see the Restrictions + section), and 7 if the file is not a valid DBM password + file.

    +
    top
    +
    +

    Examples

    +

    + htdbm /usr/local/etc/apache/.htdbm-users jsmith +

    + +

    Adds or modifies the password for user jsmith. The user + is prompted for the password. If executed on a Windows system, the password + will be encrypted using the modified Apache MD5 algorithm; otherwise, the + system's crypt() routine will be used. If the file does not + exist, htdbm will do nothing except return an error.

    + +

    + htdbm -c /home/doe/public_html/.htdbm jane +

    + +

    Creates a new file and stores a record in it for user jane. + The user is prompted for the password. If the file exists and cannot be + read, or cannot be written, it is not altered and htdbm + will display a message and return an error status.

    + +

    + htdbm -mb /usr/web/.htdbm-all jones Pwd4Steve +

    + +

    Encrypts the password from the command line (Pwd4Steve) + using the MD5 algorithm, and stores it in the specified file.

    +
    top
    +
    +

    Security Considerations

    +

    Web password files such as those managed by htdbm should + not be within the Web server's URI space -- that is, they should + not be fetchable with a browser.

    + +

    The use of the -b option is discouraged, since when it is + used the unencrypted password appears on the command line.

    +
    top
    +
    +

    Restrictions

    +

    On the Windows and MPE platforms, passwords encrypted with + htdbm are limited to no more than 255 + characters in length. Longer passwords will be truncated to 255 + characters.

    + +

    The MD5 algorithm used by htdbm is specific to the Apache + software; passwords encrypted using it will not be usable with other Web + servers.

    + +

    Usernames are limited to 255 bytes and may not include the + character :.

    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htdbm.xml b/trunk/docs/manual/programs/htdbm.xml new file mode 100644 index 0000000000..de888d8aa0 --- /dev/null +++ b/trunk/docs/manual/programs/htdbm.xml @@ -0,0 +1,276 @@ + + + + + + + + +Programs + +htdbm - Manipulate DBM password databases + + +

    htdbm is used to manipulate the DBM format files used to + store usernames and password for basic authentication of HTTP users via + mod_auth_dbm. See the dbmmanage + documentation for more information about these DBM files.

    +
    +httpd +dbmmanage +mod_auth_dbm + +
    Synopsis +

    htdbm + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + [ -x ] + filename username

    + +

    htdbm -b + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username password

    + +

    htdbm -n + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + username

    + +

    htdbm -nb + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + username password

    + +

    htdbm -v + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username

    + +

    htdbm -vb + [ -TDBTYPE ] + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -t ] + [ -v ] + filename username password

    + +

    htdbm -x + [ -TDBTYPE ] + [ -m | + -d | + -p | + -s ] + filename username

    + +

    htdbm -l + [ -TDBTYPE ] +

    +
    + +
    Options +
    +
    -b
    +
    Use batch mode; i.e., get the password from the command line + rather than prompting for it. This option should be used with extreme care, + since the password is clearly visible on the command + line.
    + +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is rewritten and truncated. This option cannot be combined with + the -n option.
    + +
    -n
    +
    Display the results on standard output rather than updating a + database. This option changes the syntax of the command line, since the + passwdfile argument (usually the first one) is omitted. It + cannot be combined with the -c option.
    + +
    -m
    +
    Use MD5 encryption for passwords. On Windows, Netware and TPF, this is + the default.
    + +
    -d
    +
    Use crypt() encryption for passwords. The default on all + platforms but Windows, Netware and TPF. Though possibly supported by + htdbm on all platforms, it is not supported by the + httpd server on Windows, Netware and TPF.
    + +
    -s
    +
    Use SHA encryption for passwords. Facilitates migration from/to Netscape + servers using the LDAP Directory Interchange Format (ldif).
    + +
    -p
    +
    Use plaintext passwords. Though htdbm will support + creation on all platforms, the httpd daemon will + only accept plain text passwords on Windows, Netware and TPF.
    + +
    -l
    +
    Print each of the usernames and comments from the database on + stdout.
    + +
    -t
    +
    Interpret the final parameter as a comment. When this option is + specified, an additional string can be appended to the command line; this + string will be stored in the "Comment" field of the database, associated + with the specified username.
    + +
    -v
    +
    Verify the username and password. The program will print a message + indicating whether the supplied password is valid. If the password is + invalid, the program exits with error code 3.
    + +
    -x
    +
    Delete user. If the username exists in the specified DBM file, it + will be deleted.
    + +
    filename
    +
    The filename of the DBM format file. Usually without the extension + .db, .pag, or .dir. If + -c is given, the DBM file is created if it does not already + exist, or updated if it does exist.
    + +
    username
    +
    The username to create or update in passwdfile. If + username does not exist in this file, an entry is added. If it + does exist, the password is changed.
    + +
    password
    +
    The plaintext password to be encrypted and stored in the DBM file. + Used only with the -b flag.
    + +
    -TDBTYPE
    +
    Type of DBM file (SDBM, GDBM, DB, or "default").
    +
    +
    + +
    Bugs +

    One should be aware that there are a number of different DBM file + formats in existence, and with all likelihood, libraries for more than + one format may exist on your system. The three primary examples are + SDBM, NDBM, GNU GDBM, and Berkeley/Sleepycat DB 2/3/4. Unfortunately, + all these libraries use different file formats, and you must make sure + that the file format used by filename is the same format that + htdbm expects to see. htdbm currently has + no way of determining what type of DBM file it is looking at. If used + against the wrong format, 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.

    + +

    One can usually use the file program supplied with most + Unix systems to see what format a DBM file is in.

    +
    + +
    Exit Status +

    htdbm returns a zero status ("true") if the username and + password have been successfully added or updated in the DBM File. + htdbm returns 1 if it encounters some problem + accessing files, 2 if there was a syntax problem with the + command line, 3 if the password was entered interactively and + the verification entry didn't match, 4 if its operation was + interrupted, 5 if a value is too long (username, filename, + password, or final computed record), 6 if the username + contains illegal characters (see the Restrictions + section), and 7 if the file is not a valid DBM password + file.

    +
    + +
    Examples + + htdbm /usr/local/etc/apache/.htdbm-users jsmith + + +

    Adds or modifies the password for user jsmith. The user + is prompted for the password. If executed on a Windows system, the password + will be encrypted using the modified Apache MD5 algorithm; otherwise, the + system's crypt() routine will be used. If the file does not + exist, htdbm will do nothing except return an error.

    + + + htdbm -c /home/doe/public_html/.htdbm jane + + +

    Creates a new file and stores a record in it for user jane. + The user is prompted for the password. If the file exists and cannot be + read, or cannot be written, it is not altered and htdbm + will display a message and return an error status.

    + + + htdbm -mb /usr/web/.htdbm-all jones Pwd4Steve + + +

    Encrypts the password from the command line (Pwd4Steve) + using the MD5 algorithm, and stores it in the specified file.

    +
    + +
    Security Considerations +

    Web password files such as those managed by htdbm should + not be within the Web server's URI space -- that is, they should + not be fetchable with a browser.

    + +

    The use of the -b option is discouraged, since when it is + used the unencrypted password appears on the command line.

    +
    + +
    Restrictions +

    On the Windows and MPE platforms, passwords encrypted with + htdbm are limited to no more than 255 + characters in length. Longer passwords will be truncated to 255 + characters.

    + +

    The MD5 algorithm used by htdbm is specific to the Apache + software; passwords encrypted using it will not be usable with other Web + servers.

    + +

    Usernames are limited to 255 bytes and may not include the + character :.

    +
    + +
    diff --git a/trunk/docs/manual/programs/htdbm.xml.meta b/trunk/docs/manual/programs/htdbm.xml.meta new file mode 100644 index 0000000000..459f367544 --- /dev/null +++ b/trunk/docs/manual/programs/htdbm.xml.meta @@ -0,0 +1,11 @@ + + + + htdbm + /programs/ + .. + + + en + + diff --git a/trunk/docs/manual/programs/htdigest.html b/trunk/docs/manual/programs/htdigest.html new file mode 100644 index 0000000000..bb29be39ca --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.html @@ -0,0 +1,7 @@ +URI: htdigest.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: htdigest.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/htdigest.html.en b/trunk/docs/manual/programs/htdigest.html.en new file mode 100644 index 0000000000..0ada2731fb --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.html.en @@ -0,0 +1,72 @@ + + + +htdigest - manage user files for digest authentication - Apache HTTP Server + + + + + +
    <-
    +

    htdigest - manage user files for digest authentication

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    htdigest is used to create and update the flat-files used + to store usernames, realm and password for digest authentication of HTTP + users. Resources available from the Apache HTTP server can be restricted + to just the users listed in the files created by htdigest.

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure digest authentication in + httpd see the Apache manual, which is part + of the Apache distribution or can be found at + http://httpd.apache.org/.

    +
    + +
    top
    +
    +

    Synopsis

    +

    htdigest [ -c ] + passwdfile realm username

    +
    top
    +
    +

    Options

    +
    +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is deleted first.
    + +
    passwdfile
    +
    Name of the file to contain the username, realm and password. If + -c is given, this file is created if it does not already + exist, or deleted and recreated if it does exist.
    + +
    realm
    +
    The realm name to which the user name belongs.
    + +
    username
    +
    The user name to create or update in passwdfile. If + username does not exist is this file, an entry is added. If it + does exist, the password is changed.
    +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htdigest.html.ko.euc-kr b/trunk/docs/manual/programs/htdigest.html.ko.euc-kr new file mode 100644 index 0000000000..a4942f025c --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.html.ko.euc-kr @@ -0,0 +1,75 @@ + + + +htdigest - digest authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» +°ü¸®ÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    htdigest - digest authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» +°ü¸®ÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    htdigest´Â HTTP »ç¿ëÀÚÀÇ digest authentication¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í, ¿µ¿ª, ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀϹÝÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» htdigest·Î + ¸¸µç ÆÄÀÏ¿¡ ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ digest authenticationÀ» + ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í + http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    htdigest [ -c ] + passwdfile realm username

    +
    top
    +
    +

    ¿É¼Ç

    +
    +
    -c
    +
    passwdfileÀ» ¸¸µç´Ù. passwdfileÀÌ + ÀÌ¹Ì ÀÖ´Ù¸é ¸ÕÀú Áö¿ì°í ¸¸µç´Ù.
    + +
    passwdfile
    +
    »ç¿ëÀÚ¸í, ¿µ¿ª, ¾ÏÈ£¸¦ ÀúÀåÇÒ ÆÄÀϸí. -c¸¦ + °°ÀÌ »ç¿ëÇÑ °æ¿ì ÆÄÀÏÀÌ ¾ø´Ù¸é ¸¸µé°í, ÀÖ´Ù¸é ÆÄÀÏÀ» Áö¿ì°í + ´Ù½Ã ¸¸µç´Ù.
    + +
    realm
    +
    »ç¿ëÀÚ¸íÀÌ ¼ÓÇÑ ¿µ¿ªÀ̸§.
    + +
    username
    +
    passwdfile¿¡ ¸¸µé°Å³ª ¼öÁ¤ÇÒ »ç¿ëÀÚ¸í. ÆÄÀÏ¿¡ + usernameÀÌ ¾ø´Ù¸é Ç׸ñÀ» Ãß°¡ÇÑ´Ù. ÀÖ´Ù¸é ¾ÏÈ£¸¦ + ¼öÁ¤ÇÑ´Ù.
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htdigest.xml b/trunk/docs/manual/programs/htdigest.xml new file mode 100644 index 0000000000..74cc97dc64 --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.xml @@ -0,0 +1,69 @@ + + + + + + + + +Programs + +htdigest - manage user files for digest authentication + + +

    htdigest is used to create and update the flat-files used + to store usernames, realm and password for digest authentication of HTTP + users. Resources available from the Apache HTTP server can be restricted + to just the users listed in the files created by htdigest.

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure digest authentication in + httpd see the Apache manual, which is part + of the Apache distribution or can be found at + http://httpd.apache.org/.

    +
    +httpd +mod_auth_digest + +
    Synopsis +

    htdigest [ -c ] + passwdfile realm username

    +
    + +
    Options +
    +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is deleted first.
    + +
    passwdfile
    +
    Name of the file to contain the username, realm and password. If + -c is given, this file is created if it does not already + exist, or deleted and recreated if it does exist.
    + +
    realm
    +
    The realm name to which the user name belongs.
    + +
    username
    +
    The user name to create or update in passwdfile. If + username does not exist is this file, an entry is added. If it + does exist, the password is changed.
    +
    +
    + +
    diff --git a/trunk/docs/manual/programs/htdigest.xml.ko b/trunk/docs/manual/programs/htdigest.xml.ko new file mode 100644 index 0000000000..09c1b39b10 --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.xml.ko @@ -0,0 +1,70 @@ + + + + + + + + +Programs + +htdigest - digest authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» +°ü¸®ÇÑ´Ù + + +

    htdigest´Â HTTP »ç¿ëÀÚÀÇ digest authentication¿¡ + »ç¿ëÇÒ »ç¿ëÀÚ¸í, ¿µ¿ª, ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀϹÝÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù. ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» htdigest·Î + ¸¸µç ÆÄÀÏ¿¡ ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ digest authenticationÀ» + ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í + http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    +httpd +mod_auth_digest + +
    °³¿ä +

    htdigest [ -c ] + passwdfile realm username

    +
    + +
    ¿É¼Ç +
    +
    -c
    +
    passwdfileÀ» ¸¸µç´Ù. passwdfileÀÌ + ÀÌ¹Ì ÀÖ´Ù¸é ¸ÕÀú Áö¿ì°í ¸¸µç´Ù.
    + +
    passwdfile
    +
    »ç¿ëÀÚ¸í, ¿µ¿ª, ¾ÏÈ£¸¦ ÀúÀåÇÒ ÆÄÀϸí. -c¸¦ + °°ÀÌ »ç¿ëÇÑ °æ¿ì ÆÄÀÏÀÌ ¾ø´Ù¸é ¸¸µé°í, ÀÖ´Ù¸é ÆÄÀÏÀ» Áö¿ì°í + ´Ù½Ã ¸¸µç´Ù.
    + +
    realm
    +
    »ç¿ëÀÚ¸íÀÌ ¼ÓÇÑ ¿µ¿ªÀ̸§.
    + +
    username
    +
    passwdfile¿¡ ¸¸µé°Å³ª ¼öÁ¤ÇÒ »ç¿ëÀÚ¸í. ÆÄÀÏ¿¡ + usernameÀÌ ¾ø´Ù¸é Ç׸ñÀ» Ãß°¡ÇÑ´Ù. ÀÖ´Ù¸é ¾ÏÈ£¸¦ + ¼öÁ¤ÇÑ´Ù.
    +
    +
    + +
    diff --git a/trunk/docs/manual/programs/htdigest.xml.meta b/trunk/docs/manual/programs/htdigest.xml.meta new file mode 100644 index 0000000000..bda55bf8ee --- /dev/null +++ b/trunk/docs/manual/programs/htdigest.xml.meta @@ -0,0 +1,12 @@ + + + + htdigest + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/htpasswd.html b/trunk/docs/manual/programs/htpasswd.html new file mode 100644 index 0000000000..5462afe3c6 --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.html @@ -0,0 +1,7 @@ +URI: htpasswd.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: htpasswd.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/htpasswd.html.en b/trunk/docs/manual/programs/htpasswd.html.en new file mode 100644 index 0000000000..5c655b88e7 --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.html.en @@ -0,0 +1,215 @@ + + + +htpasswd - Manage user files for basic authentication - Apache HTTP Server + + + + + +
    <-
    +

    htpasswd - Manage user files for basic authentication

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    htpasswd is used to create and update the flat-files used to + store usernames and password for basic authentication of HTTP users. If + htpasswd cannot access a file, such as not being able to write + to the output file or not being able to read the file in order to update it, + it returns an error status and makes no changes.

    + +

    Resources available from the Apache HTTP server can be restricted to + just the users listed in the files created by htpasswd. This + program can only manage usernames and passwords stored in a flat-file. It + can encrypt and display password information for use in other types of data + stores, though. To use a DBM database see dbmmanage.

    + +

    htpasswd encrypts passwords using either a version of MD5 + modified for Apache, or the system's crypt() routine. Files + managed by htpasswd may contain both types of passwords; some + user records may have MD5-encrypted passwords while others in the same file + may have passwords encrypted with crypt().

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure user authentication in + httpd see the Apache manual, which is part of the + Apache distribution or can be found at http://httpd.apache.org/.

    +
    +

    See also

    • httpd
    • The scripts in support/SHA1 which come with the +distribution.
    +
    top
    +
    +

    Synopsis

    +

    htpasswd + [ -c ] + [ -m ] + [ -D ] passwdfile username

    + +

    htpasswd -b + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -D ] passwdfile username + password

    + +

    htpasswd -n + [ -m | + -d | + -s | + -p ] username

    + +

    htpasswd -nb + [ -m | + -d | + -s | + -p ] username password

    +
    top
    +
    +

    Options

    +
    +
    -b
    +
    Use batch mode; i.e., get the password from the command line + rather than prompting for it. This option should be used with extreme care, + since the password is clearly visible on the command + line.
    + +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is rewritten and truncated. This option cannot be combined with + the -n option.
    + +
    -n
    +
    Display the results on standard output rather than updating a file. + This is useful for generating password records acceptable to Apache for + inclusion in non-text data stores. This option changes the syntax of the + command line, since the passwdfile argument (usually the first + one) is omitted. It cannot be combined with the -c option.
    + +
    -m
    +
    Use MD5 encryption for passwords. On Windows, Netware and TPF, this is + the default.
    + +
    -d
    +
    Use crypt() encryption for passwords. The default on all + platforms but Windows, Netware and TPF. Though possibly supported by + htpasswd on all platforms, it is not supported by the + httpd server on Windows, Netware and TPF.
    + +
    -s
    +
    Use SHA encryption for passwords. Facilitates migration from/to Netscape + servers using the LDAP Directory Interchange Format (ldif).
    + +
    -p
    +
    Use plaintext passwords. Though htpasswd will support + creation on all platforms, the httpd daemon will + only accept plain text passwords on Windows, Netware and TPF.
    + +
    -D
    +
    Delete user. If the username exists in the specified htpasswd file, it + will be deleted.
    + +
    passwdfile
    +
    Name of the file to contain the user name and password. If + -c is given, this file is created if it does not already exist, + or rewritten and truncated if it does exist.
    + +
    username
    +
    The username to create or update in passwdfile. If + username does not exist in this file, an entry is added. If it + does exist, the password is changed.
    + +
    password
    +
    The plaintext password to be encrypted and stored in the file. Only + used with the -b flag.
    +
    +
    top
    +
    +

    Exit Status

    +

    htpasswd returns a zero status ("true") if the username and + password have been successfully added or updated in the + passwdfile. htpasswd returns 1 if it + encounters some problem accessing files, 2 if there was a + syntax problem with the command line, 3 if the password was + entered interactively and the verification entry didn't match, + 4 if its operation was interrupted, 5 if a value + is too long (username, filename, password, or final computed record), + 6 if the username contains illegal characters (see the + Restrictions section), and 7 + if the file is not a valid password file.

    +
    top
    +
    +

    Examples

    +

    + htpasswd /usr/local/etc/apache/.htpasswd-users jsmith +

    + +

    Adds or modifies the password for user jsmith. The user + is prompted for the password. If executed on a Windows system, the password + will be encrypted using the modified Apache MD5 algorithm; otherwise, the + system's crypt() routine will be used. If the file does not + exist, htpasswd will do nothing except return an error.

    + +

    + htpasswd -c /home/doe/public_html/.htpasswd jane +

    + +

    Creates a new file and stores a record in it for user jane. + The user is prompted for the password. If the file exists and cannot be + read, or cannot be written, it is not altered and htpasswd + will display a message and return an error status.

    + +

    + htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve +

    + +

    Encrypts the password from the command line (Pwd4Steve) + using the MD5 algorithm, and stores it in the specified file.

    +
    top
    +
    +

    Security Considerations

    +

    Web password files such as those managed by htpasswd should + not be within the Web server's URI space -- that is, they should + not be fetchable with a browser.

    + +

    The use of the -b option is discouraged, since when it is + used the unencrypted password appears on the command line.

    +
    top
    +
    +

    Restrictions

    +

    On the Windows and MPE platforms, passwords encrypted with + htpasswd are limited to no more than 255 + characters in length. Longer passwords will be truncated to 255 + characters.

    + +

    The MD5 algorithm used by htpasswd is specific to the Apache + software; passwords encrypted using it will not be usable with other Web + servers.

    + +

    Usernames are limited to 255 bytes and may not include the + character :.

    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htpasswd.html.ko.euc-kr b/trunk/docs/manual/programs/htpasswd.html.ko.euc-kr new file mode 100644 index 0000000000..cba6c7ea3d --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.html.ko.euc-kr @@ -0,0 +1,217 @@ + + + +htpasswd - basic authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» + °ü¸®ÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    htpasswd - basic authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» + °ü¸®ÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    htpasswd´Â HTTP basic authentication¿¡ »ç¿ëÇÒ + »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀϹÝÆÄÀÏÀ» »ý¼ºÇÏ°í ¼öÁ¤ÇÑ´Ù. + htpasswd°¡ ÆÄÀÏÀ» ¾²°Å³ª ÀÐÀ» ¼ö ¾ø´Ù¸é, + ¿À·ù»óŸ¦ ¹ÝȯÇÏ°í ¾Æ¹«°Íµµ ¼öÁ¤ÇÏÁö ¾Ê´Â´Ù.

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» htpasswd·Î ¸¸µç ÆÄÀÏ¿¡ + ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀÏ¹Ý ÆÄÀÏÀ» °ü¸®ÇÑ´Ù. ±×·¯³ª ´Ù¸¥ ÀÚ·áÀúÀå + ¹æ½ÄÀ» À§ÇØ ¾ÏÈ£ Á¤º¸¸¦ ¾ÏȣȭÇÏ¿© ÀúÀåÇÒ ¼ö ÀÖ´Ù. DBM + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÏ·Á¸é dbmmanage¸¦ Âü°íÇ϶ó.

    + +

    htpasswd´Â ¾ÆÆÄÄ¡ ƯÀ¯ÀÇ MD5 ȤÀº ½Ã½ºÅÛÀÇ + crypt()¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. + htpasswd°¡ °ü¸®ÇÏ´Â ÆÄÀÏÀº µÎ Á¾·ùÀÇ ¾ÏÈ£¸¦ + ¸ðµÎ ÀúÀåÇÒ ¼ö ÀÖ´Ù. Áï, °°Àº ÆÄÀÏ¿¡ MD5·Î ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + »ç¿ëÇÏ´Â »ç¿ëÀÚ¿Í crypt()·Î ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + »ç¿ëÇÏ´Â »ç¿ëÀÚ Á¤º¸ ¸ðµÎ ³ª¿Ã ¼ö ÀÖ´Ù.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ »ç¿ëÀÚÀÎÁõÀ» ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    +

    Âü°í

    • httpd
    • ¹èÆ÷º»¿¡´Â SHA1À» Áö¿øÇÏ´Â ½ºÅ©¸³Æ®µµ ÀÖ´Ù.
    +
    top
    +
    +

    °³¿ä

    +

    htpasswd + [ -c ] + [ -m ] + [ -D ] passwdfile username

    + +

    htpasswd -b + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -D ] passwdfile username + password

    + +

    htpasswd -n + [ -m | + -d | + -s | + -p ] username

    + +

    htpasswd -nb + [ -m | + -d | + -s | + -p ] username password

    +
    top
    +
    +

    ¿É¼Ç

    +
    +
    -b
    +
    ¹èÄ¡(batch) ¸ðµå¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾ÏÈ£¸¦ + ¹°¾îº¸Áö¾Ê°í ¸í·ÉÇà¿¡¼­ ¹Þ´Â´Ù. ¸í·ÉÇà¿¡ ¾ÏÈ£°¡ + Á÷Á¢ µå·¯³ª¹Ç·Î, ÀÌ ¿É¼ÇÀº ¸Å¿ì Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    + +
    -c
    +
    passwdfileÀ» ¸¸µç´Ù. passwdfileÀÌ + ÀÌ¹Ì Á¸ÀçÇÑ´Ù¸é, µ¤¾î¾´´Ù. ÀÌ ¿É¼ÇÀ» -n ¿É¼Ç°ú + °°ÀÌ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -n
    +
    ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö¾Ê°í °á°ú¸¦ Ç¥ÁØÃâ·ÂÀ¸·Î Ãâ·ÂÇÑ´Ù. + ¾ÆÆÄÄ¡°¡ ¹®¼­ÀÌ¿ÜÀÇ °÷¿¡ »ý¼ºÇÑ ¾ÏÈ£¸¦ ÀúÀåÇÒ¶§ À¯¿ëÇÏ´Ù. + (Ç×»ó ù¹ø° ¾Æ±Ô¸ÕÆ®ÀÎ) passwdfile ¾Æ±Ô¸ÕÆ®°¡ + ¾ø±â¶§¹®¿¡ ¸í·ÉÇà ¹®¹ýÀÌ ´Ù¸£´Ù. -c ¿É¼Ç°ú + °°ÀÌ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -m
    +
    MD5¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. Windows, Netware, + TPF¿¡¼­ ±âº»°ªÀÌ´Ù.
    + +
    -d
    +
    crypt()¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. + Windows, Netware, TPF¸¦ Á¦¿ÜÇÑ ¸ðµç Ç÷¡Æû¿¡¼­ ±âº»°ªÀÌ´Ù. + ¸ðµç Ç÷¡ÆûÀÇ htpasswd°¡ ÀÌ Çü½ÄÀ» Áö¿øÇÒ ¼ö´Â + ÀÖÁö¸¸, Windows, Netware, TPFÀÇ httpd + ¼­¹ö´Â ÀÌ Çü½ÄÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    -s
    +
    ¾ÏÈ£¸¦ SHA ¾ÏȣȭÇÑ´Ù. LDAP µð·ºÅ丮±³È¯Çü½Ä(ldif)À» + »ç¿ëÇÏ¿© Netscape ¼­¹ö·Î Á¤º¸¸¦ º¸³»°Å³ª °ÅÁ®¿Ã¶§ À¯¿ëÇÏ´Ù.
    + +
    -p
    +
    ¾ÏÈ£¸¦ ±×´ë·Î »ç¿ëÇÑ´Ù. ¸ðµç Ç÷¡ÆûÀÇ htpasswd°¡ + Áö¿øÇÏÁö¸¸, Windows, Netware, TPFÀÇ httpd + µ¥¸ó¸¸ÀÌ ÀÏ¹Ý ¾ÏÈ£¸¦ ¹Þ´Â´Ù.
    + +
    -D
    +
    »ç¿ëÀÚ¸¦ »èÁ¦ÇÑ´Ù. htpasswd ÆÄÀÏ¿¡ »ç¿ëÀÚ¸íÀÌ ÀÖ´Ù¸é + »èÁ¦ÇÑ´Ù.
    + +
    passwdfile
    +
    »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÆÄÀϸí. -c¸¦ + »ç¿ëÇÑ °æ¿ì ÆÄÀÏÀÌ ¾ø´Ù¸é »õ·Î ¸¸µé°í, ÀÖ´Ù¸é µ¤¾î¾´´Ù.
    + +
    username
    +
    passwdfile¿¡ ¸¸µé°Å³ª ¼öÁ¤ÇÒ »ç¿ëÀÚ¸í. + usernameÀÌ ÀÌ ÆÄÀÏ¿¡ ¾ø´Ù¸é Ç׸ñÀ» Ãß°¡ÇÑ´Ù. + ÀÖ´Ù¸é ¾ÏÈ£¸¦ ¼öÁ¤ÇÑ´Ù.
    + +
    password
    +
    ¾ÏȣȭÇÏ¿© ÆÄÀÏ¿¡ ÀúÀåÇÒ ¾ÏÈ£. ¿ÀÁ÷ -b + ¿É¼Ç°ú °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +
    +
    top
    +
    +

    Á¾·áÄÚµå

    +

    htpasswd´Â passwdfile¿¡ »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ ¼º°øÀûÀ¸·Î Ãß°¡Çϰųª ¼öÁ¤ÇÑ °æ¿ì ("Âü") Á¾·áÄÚµå + 0À» ¹ÝȯÇÑ´Ù. htpasswd´Â ÆÄÀÏ¿¡ Á¢±ÙÇÒ¶§ ¹®Á¦°¡ + ¹ß»ýÇÑ °æ¿ì 1À», ¸í·ÉÇà Çü½ÄÀÌ À߸øµÈ °æ¿ì + 2¸¦, ÀÔ·ÂÇÑ ¾ÏÈ£¿Í È®ÀÎÂ÷ ´Ù½Ã ÀÔ·ÂÇÑ °ªÀÌ + ÀÏÄ¡ÇÏÁö ¾ÊÀº °æ¿ì 3À», ¸í·ÉÀÌ Áß´ÜµÈ °æ¿ì + 4¸¦, (»ç¿ëÀÚ¸í, ÆÄÀϸí, ¾ÏÈ£, ÃÖÁ¾ °è»ê°á°ú) + °ªÀÌ ³Ê¹« ±ä °æ¿ì 5¸¦, »ç¿ëÀÚ¸í¿¡ Çã¿ëÇÏÁö¾Ê´Â + ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì Á¦ÇÑ Àý Âü°í) + 6¸¦, ÆÄÀÏÀÌ ¿Ã¹Ù¸¥ ¾ÏÈ£ÆÄÀÏÀÌ ¾Æ´Ñ °æ¿ì + 7À» ¹ÝȯÇÑ´Ù.

    +
    top
    +
    +

    ¿¹Á¦

    +

    + htpasswd /usr/local/etc/apache/.htpasswd-users jsmith +

    + +

    »ç¿ëÀÚ jsmithÀÇ ¾ÏÈ£¸¦ Ãß°¡Çϰųª ¼öÁ¤ÇÑ´Ù. + »ç¿ëÀÚ¿¡°Ô ¾ÏÈ£¸¦ ¹°¾îº»´Ù. Windows ½Ã½ºÅÛ¿¡¼­ ½ÇÇàÇϸé + ¾ÏÈ£¸¦ ¾ÆÆÄÄ¡ ƯÀ¯ÀÇ MD5 ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© ¾ÏȣȭÇÏ°í, + ¾Æ´Ï¸é ½Ã½ºÅÛÀÇ crypt() ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÆÄÀÏÀÌ + ¾ø´Ù¸é htpasswd´Â ¾Æ¹« Àϵµ ÇÏÁö¾Ê°í ¿À·ù¸¦ + ³½´Ù.

    + +

    + htpasswd -c /home/doe/public_html/.htpasswd jane +

    + +

    »õ·Î ÆÄÀÏÀ» ¸¸µé°í ±× ÆÄÀÏ¿¡ »ç¿ëÀÚ janeÀ» + Ãß°¡ÇÑ´Ù. »ç¿ëÀÚ¿¡°Ô ¾ÏÈ£¸¦ ¹°¾îº»´Ù. ÆÄÀÏÀÌ ÀÖÁö¸¸ Àаųª + ¾µ ¼ö ¾ø´Ù¸é, htpasswd´Â ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö¾Ê°í + ¹®±¸¸¦ Ãâ·ÂÇÑÈÄ ¿À·ù»óŸ¦ ¹ÝȯÇÑ´Ù.

    + +

    + htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve +

    + +

    ¸í·ÉÇàÀÇ ¾ÏÈ£(Pwd4Steve)¸¦ MD5 ¾Ë°í¸®ÁòÀ¸·Î + ¾ÏȣȭÇÏ¿© ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ ÀúÀåÇÑ´Ù.

    +
    top
    +
    +

    º¸¾È»ó °í·ÁÇÒ Á¡

    +

    htpasswd µîÀÌ °ü¸®ÇÏ´Â À¥ ¾ÏÈ£ÆÄÀÏÀÌ À¥¼­¹öÀÇ + URI °ø°£¿¡ ÀÖÀ¸¸é ¾ÈµÈ´Ù. Áï, ºê¶ó¿ìÀú°¡ ÀÌ ÆÄÀÏÀ» + º¼ ¼ö ¾ø¾î¾ß ÇÑ´Ù.

    + +

    ¸í·ÉÇà¿¡ ¾ÏȣȭÇÏÁö¾ÊÀº ¾ÏÈ£¸¦ »ç¿ëÇϱ⶧¹®¿¡ -b + ¿É¼ÇÀ» ÃßõÇÏÁö ¾Ê´Â´Ù.

    +
    top
    +
    +

    Á¦ÇÑ

    +

    Windows¿Í MPE Ç÷¡ÆûÀº htpasswd°¡ ¾ÏȣȭÇÏ´Â + ¾ÏÈ£ÀÇ ±æÀ̸¦ 255 ¹®ÀÚ·Î Á¦ÇÑÇÑ´Ù. ´õ ±ä ¾ÏÈ£´Â + 255ÀÚ¿¡¼­ ©¸°´Ù.

    + +

    htpasswd°¡ »ç¿ëÇÏ´Â MD5 ¾Ë°í¸®ÁòÀº ¾ÆÆÄÄ¡ + ¼ÒÇÁÆ®¿þ¾î ƯÀ¯ÀÇ °ÍÀÌ´Ù. À̸¦ »ç¿ëÇÏ¿© ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + ´Ù¸¥ À¥¼­¹ö¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    »ç¿ëÀÚ¸íÀº 255 ¹ÙÀÌÆ®·Î Á¦Çѵǰí : + ¹®ÀÚ¸¦ Æ÷ÇÔÇÒ ¼ö ¾ø´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/htpasswd.xml b/trunk/docs/manual/programs/htpasswd.xml new file mode 100644 index 0000000000..294a1a02df --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.xml @@ -0,0 +1,209 @@ + + + + + + + + +Programs + +htpasswd - Manage user files for basic authentication + + +

    htpasswd is used to create and update the flat-files used to + store usernames and password for basic authentication of HTTP users. If + htpasswd cannot access a file, such as not being able to write + to the output file or not being able to read the file in order to update it, + it returns an error status and makes no changes.

    + +

    Resources available from the Apache HTTP server can be restricted to + just the users listed in the files created by htpasswd. This + program can only manage usernames and passwords stored in a flat-file. It + can encrypt and display password information for use in other types of data + stores, though. To use a DBM database see dbmmanage.

    + +

    htpasswd encrypts passwords using either a version of MD5 + modified for Apache, or the system's crypt() routine. Files + managed by htpasswd may contain both types of passwords; some + user records may have MD5-encrypted passwords while others in the same file + may have passwords encrypted with crypt().

    + +

    This manual page only lists the command line arguments. For details of + the directives necessary to configure user authentication in + httpd see the Apache manual, which is part of the + Apache distribution or can be found at http://httpd.apache.org/.

    +
    +httpd +The scripts in support/SHA1 which come with the +distribution. + +
    Synopsis +

    htpasswd + [ -c ] + [ -m ] + [ -D ] passwdfile username

    + +

    htpasswd -b + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -D ] passwdfile username + password

    + +

    htpasswd -n + [ -m | + -d | + -s | + -p ] username

    + +

    htpasswd -nb + [ -m | + -d | + -s | + -p ] username password

    +
    + +
    Options +
    +
    -b
    +
    Use batch mode; i.e., get the password from the command line + rather than prompting for it. This option should be used with extreme care, + since the password is clearly visible on the command + line.
    + +
    -c
    +
    Create the passwdfile. If passwdfile already + exists, it is rewritten and truncated. This option cannot be combined with + the -n option.
    + +
    -n
    +
    Display the results on standard output rather than updating a file. + This is useful for generating password records acceptable to Apache for + inclusion in non-text data stores. This option changes the syntax of the + command line, since the passwdfile argument (usually the first + one) is omitted. It cannot be combined with the -c option.
    + +
    -m
    +
    Use MD5 encryption for passwords. On Windows, Netware and TPF, this is + the default.
    + +
    -d
    +
    Use crypt() encryption for passwords. The default on all + platforms but Windows, Netware and TPF. Though possibly supported by + htpasswd on all platforms, it is not supported by the + httpd server on Windows, Netware and TPF.
    + +
    -s
    +
    Use SHA encryption for passwords. Facilitates migration from/to Netscape + servers using the LDAP Directory Interchange Format (ldif).
    + +
    -p
    +
    Use plaintext passwords. Though htpasswd will support + creation on all platforms, the httpd daemon will + only accept plain text passwords on Windows, Netware and TPF.
    + +
    -D
    +
    Delete user. If the username exists in the specified htpasswd file, it + will be deleted.
    + +
    passwdfile
    +
    Name of the file to contain the user name and password. If + -c is given, this file is created if it does not already exist, + or rewritten and truncated if it does exist.
    + +
    username
    +
    The username to create or update in passwdfile. If + username does not exist in this file, an entry is added. If it + does exist, the password is changed.
    + +
    password
    +
    The plaintext password to be encrypted and stored in the file. Only + used with the -b flag.
    +
    +
    + +
    Exit Status +

    htpasswd returns a zero status ("true") if the username and + password have been successfully added or updated in the + passwdfile. htpasswd returns 1 if it + encounters some problem accessing files, 2 if there was a + syntax problem with the command line, 3 if the password was + entered interactively and the verification entry didn't match, + 4 if its operation was interrupted, 5 if a value + is too long (username, filename, password, or final computed record), + 6 if the username contains illegal characters (see the + Restrictions section), and 7 + if the file is not a valid password file.

    +
    + +
    Examples + + htpasswd /usr/local/etc/apache/.htpasswd-users jsmith + + +

    Adds or modifies the password for user jsmith. The user + is prompted for the password. If executed on a Windows system, the password + will be encrypted using the modified Apache MD5 algorithm; otherwise, the + system's crypt() routine will be used. If the file does not + exist, htpasswd will do nothing except return an error.

    + + + htpasswd -c /home/doe/public_html/.htpasswd jane + + +

    Creates a new file and stores a record in it for user jane. + The user is prompted for the password. If the file exists and cannot be + read, or cannot be written, it is not altered and htpasswd + will display a message and return an error status.

    + + + htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve + + +

    Encrypts the password from the command line (Pwd4Steve) + using the MD5 algorithm, and stores it in the specified file.

    +
    + +
    Security Considerations +

    Web password files such as those managed by htpasswd should + not be within the Web server's URI space -- that is, they should + not be fetchable with a browser.

    + +

    The use of the -b option is discouraged, since when it is + used the unencrypted password appears on the command line.

    +
    + +
    Restrictions +

    On the Windows and MPE platforms, passwords encrypted with + htpasswd are limited to no more than 255 + characters in length. Longer passwords will be truncated to 255 + characters.

    + +

    The MD5 algorithm used by htpasswd is specific to the Apache + software; passwords encrypted using it will not be usable with other Web + servers.

    + +

    Usernames are limited to 255 bytes and may not include the + character :.

    +
    + +
    diff --git a/trunk/docs/manual/programs/htpasswd.xml.ko b/trunk/docs/manual/programs/htpasswd.xml.ko new file mode 100644 index 0000000000..8ea2ee6428 --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.xml.ko @@ -0,0 +1,210 @@ + + + + + + + + +Programs + +htpasswd - basic authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚÆÄÀÏÀ» + °ü¸®ÇÑ´Ù + + +

    htpasswd´Â HTTP basic authentication¿¡ »ç¿ëÇÒ + »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀϹÝÆÄÀÏÀ» »ý¼ºÇÏ°í ¼öÁ¤ÇÑ´Ù. + htpasswd°¡ ÆÄÀÏÀ» ¾²°Å³ª ÀÐÀ» ¼ö ¾ø´Ù¸é, + ¿À·ù»óŸ¦ ¹ÝȯÇÏ°í ¾Æ¹«°Íµµ ¼öÁ¤ÇÏÁö ¾Ê´Â´Ù.

    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â ÀÚ¿øÀ» htpasswd·Î ¸¸µç ÆÄÀÏ¿¡ + ±â·ÏÇÑ »ç¿ëÀÚ¿¡°Ô¸¸ º¸¿©ÁÙ ¼ö ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÀÏ¹Ý ÆÄÀÏÀ» °ü¸®ÇÑ´Ù. ±×·¯³ª ´Ù¸¥ ÀÚ·áÀúÀå + ¹æ½ÄÀ» À§ÇØ ¾ÏÈ£ Á¤º¸¸¦ ¾ÏȣȭÇÏ¿© ÀúÀåÇÒ ¼ö ÀÖ´Ù. DBM + µ¥ÀÌÅͺ£À̽º¸¦ »ç¿ëÇÏ·Á¸é dbmmanage¸¦ Âü°íÇ϶ó.

    + +

    htpasswd´Â ¾ÆÆÄÄ¡ ƯÀ¯ÀÇ MD5 ȤÀº ½Ã½ºÅÛÀÇ + crypt()¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. + htpasswd°¡ °ü¸®ÇÏ´Â ÆÄÀÏÀº µÎ Á¾·ùÀÇ ¾ÏÈ£¸¦ + ¸ðµÎ ÀúÀåÇÒ ¼ö ÀÖ´Ù. Áï, °°Àº ÆÄÀÏ¿¡ MD5·Î ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + »ç¿ëÇÏ´Â »ç¿ëÀÚ¿Í crypt()·Î ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + »ç¿ëÇÏ´Â »ç¿ëÀÚ Á¤º¸ ¸ðµÎ ³ª¿Ã ¼ö ÀÖ´Ù.

    + +

    ÀÌ manpage´Â ¸í·ÉÇà ¿É¼Ç¸¸À» ¼³¸íÇÑ´Ù. httpd¿¡¼­ »ç¿ëÀÚÀÎÁõÀ» ¼³Á¤ÇÏ´Â Áö½Ã¾î¿¡ + ´ëÇÑ ¼³¸íÀº ¾ÆÆÄÄ¡ ¹èÆ÷º»¿¡ Æ÷ÇÔµÇÀÖ°í http://httpd.apache.org/¿¡¼­µµ + º¼ ¼ö ÀÖ´Â ¾ÆÆÄÄ¡ ¼³¸í¼­¸¦ Âü°íÇ϶ó.

    +
    +httpd +¹èÆ÷º»¿¡´Â SHA1À» Áö¿øÇÏ´Â ½ºÅ©¸³Æ®µµ ÀÖ´Ù. + +
    °³¿ä +

    htpasswd + [ -c ] + [ -m ] + [ -D ] passwdfile username

    + +

    htpasswd -b + [ -c ] + [ -m | + -d | + -p | + -s ] + [ -D ] passwdfile username + password

    + +

    htpasswd -n + [ -m | + -d | + -s | + -p ] username

    + +

    htpasswd -nb + [ -m | + -d | + -s | + -p ] username password

    +
    + +
    ¿É¼Ç +
    +
    -b
    +
    ¹èÄ¡(batch) ¸ðµå¸¦ »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, ¾ÏÈ£¸¦ + ¹°¾îº¸Áö¾Ê°í ¸í·ÉÇà¿¡¼­ ¹Þ´Â´Ù. ¸í·ÉÇà¿¡ ¾ÏÈ£°¡ + Á÷Á¢ µå·¯³ª¹Ç·Î, ÀÌ ¿É¼ÇÀº ¸Å¿ì Á¶½ÉÇؼ­ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    + +
    -c
    +
    passwdfileÀ» ¸¸µç´Ù. passwdfileÀÌ + ÀÌ¹Ì Á¸ÀçÇÑ´Ù¸é, µ¤¾î¾´´Ù. ÀÌ ¿É¼ÇÀ» -n ¿É¼Ç°ú + °°ÀÌ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -n
    +
    ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö¾Ê°í °á°ú¸¦ Ç¥ÁØÃâ·ÂÀ¸·Î Ãâ·ÂÇÑ´Ù. + ¾ÆÆÄÄ¡°¡ ¹®¼­ÀÌ¿ÜÀÇ °÷¿¡ »ý¼ºÇÑ ¾ÏÈ£¸¦ ÀúÀåÇÒ¶§ À¯¿ëÇÏ´Ù. + (Ç×»ó ù¹ø° ¾Æ±Ô¸ÕÆ®ÀÎ) passwdfile ¾Æ±Ô¸ÕÆ®°¡ + ¾ø±â¶§¹®¿¡ ¸í·ÉÇà ¹®¹ýÀÌ ´Ù¸£´Ù. -c ¿É¼Ç°ú + °°ÀÌ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    + +
    -m
    +
    MD5¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. Windows, Netware, + TPF¿¡¼­ ±âº»°ªÀÌ´Ù.
    + +
    -d
    +
    crypt()¸¦ »ç¿ëÇÏ¿© ¾ÏÈ£¸¦ ¾ÏȣȭÇÑ´Ù. + Windows, Netware, TPF¸¦ Á¦¿ÜÇÑ ¸ðµç Ç÷¡Æû¿¡¼­ ±âº»°ªÀÌ´Ù. + ¸ðµç Ç÷¡ÆûÀÇ htpasswd°¡ ÀÌ Çü½ÄÀ» Áö¿øÇÒ ¼ö´Â + ÀÖÁö¸¸, Windows, Netware, TPFÀÇ httpd + ¼­¹ö´Â ÀÌ Çü½ÄÀ» Áö¿øÇÏÁö ¾Ê´Â´Ù.
    + +
    -s
    +
    ¾ÏÈ£¸¦ SHA ¾ÏȣȭÇÑ´Ù. LDAP µð·ºÅ丮±³È¯Çü½Ä(ldif)À» + »ç¿ëÇÏ¿© Netscape ¼­¹ö·Î Á¤º¸¸¦ º¸³»°Å³ª °ÅÁ®¿Ã¶§ À¯¿ëÇÏ´Ù.
    + +
    -p
    +
    ¾ÏÈ£¸¦ ±×´ë·Î »ç¿ëÇÑ´Ù. ¸ðµç Ç÷¡ÆûÀÇ htpasswd°¡ + Áö¿øÇÏÁö¸¸, Windows, Netware, TPFÀÇ httpd + µ¥¸ó¸¸ÀÌ ÀÏ¹Ý ¾ÏÈ£¸¦ ¹Þ´Â´Ù.
    + +
    -D
    +
    »ç¿ëÀÚ¸¦ »èÁ¦ÇÑ´Ù. htpasswd ÆÄÀÏ¿¡ »ç¿ëÀÚ¸íÀÌ ÀÖ´Ù¸é + »èÁ¦ÇÑ´Ù.
    + +
    passwdfile
    +
    »ç¿ëÀÚ¸í°ú ¾ÏÈ£¸¦ ÀúÀåÇÏ´Â ÆÄÀϸí. -c¸¦ + »ç¿ëÇÑ °æ¿ì ÆÄÀÏÀÌ ¾ø´Ù¸é »õ·Î ¸¸µé°í, ÀÖ´Ù¸é µ¤¾î¾´´Ù.
    + +
    username
    +
    passwdfile¿¡ ¸¸µé°Å³ª ¼öÁ¤ÇÒ »ç¿ëÀÚ¸í. + usernameÀÌ ÀÌ ÆÄÀÏ¿¡ ¾ø´Ù¸é Ç׸ñÀ» Ãß°¡ÇÑ´Ù. + ÀÖ´Ù¸é ¾ÏÈ£¸¦ ¼öÁ¤ÇÑ´Ù.
    + +
    password
    +
    ¾ÏȣȭÇÏ¿© ÆÄÀÏ¿¡ ÀúÀåÇÒ ¾ÏÈ£. ¿ÀÁ÷ -b + ¿É¼Ç°ú °°ÀÌ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    +
    +
    + +
    Á¾·áÄÚµå +

    htpasswd´Â passwdfile¿¡ »ç¿ëÀÚ¸í°ú + ¾ÏÈ£¸¦ ¼º°øÀûÀ¸·Î Ãß°¡Çϰųª ¼öÁ¤ÇÑ °æ¿ì ("Âü") Á¾·áÄÚµå + 0À» ¹ÝȯÇÑ´Ù. htpasswd´Â ÆÄÀÏ¿¡ Á¢±ÙÇÒ¶§ ¹®Á¦°¡ + ¹ß»ýÇÑ °æ¿ì 1À», ¸í·ÉÇà Çü½ÄÀÌ À߸øµÈ °æ¿ì + 2¸¦, ÀÔ·ÂÇÑ ¾ÏÈ£¿Í È®ÀÎÂ÷ ´Ù½Ã ÀÔ·ÂÇÑ °ªÀÌ + ÀÏÄ¡ÇÏÁö ¾ÊÀº °æ¿ì 3À», ¸í·ÉÀÌ Áß´ÜµÈ °æ¿ì + 4¸¦, (»ç¿ëÀÚ¸í, ÆÄÀϸí, ¾ÏÈ£, ÃÖÁ¾ °è»ê°á°ú) + °ªÀÌ ³Ê¹« ±ä °æ¿ì 5¸¦, »ç¿ëÀÚ¸í¿¡ Çã¿ëÇÏÁö¾Ê´Â + ¹®ÀÚ°¡ Æ÷ÇÔµÈ °æ¿ì Á¦ÇÑ Àý Âü°í) + 6¸¦, ÆÄÀÏÀÌ ¿Ã¹Ù¸¥ ¾ÏÈ£ÆÄÀÏÀÌ ¾Æ´Ñ °æ¿ì + 7À» ¹ÝȯÇÑ´Ù.

    +
    + +
    ¿¹Á¦ + + htpasswd /usr/local/etc/apache/.htpasswd-users jsmith + + +

    »ç¿ëÀÚ jsmithÀÇ ¾ÏÈ£¸¦ Ãß°¡Çϰųª ¼öÁ¤ÇÑ´Ù. + »ç¿ëÀÚ¿¡°Ô ¾ÏÈ£¸¦ ¹°¾îº»´Ù. Windows ½Ã½ºÅÛ¿¡¼­ ½ÇÇàÇϸé + ¾ÏÈ£¸¦ ¾ÆÆÄÄ¡ ƯÀ¯ÀÇ MD5 ¾Ë°í¸®ÁòÀ» »ç¿ëÇÏ¿© ¾ÏȣȭÇÏ°í, + ¾Æ´Ï¸é ½Ã½ºÅÛÀÇ crypt() ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ÆÄÀÏÀÌ + ¾ø´Ù¸é htpasswd´Â ¾Æ¹« Àϵµ ÇÏÁö¾Ê°í ¿À·ù¸¦ + ³½´Ù.

    + + + htpasswd -c /home/doe/public_html/.htpasswd jane + + +

    »õ·Î ÆÄÀÏÀ» ¸¸µé°í ±× ÆÄÀÏ¿¡ »ç¿ëÀÚ janeÀ» + Ãß°¡ÇÑ´Ù. »ç¿ëÀÚ¿¡°Ô ¾ÏÈ£¸¦ ¹°¾îº»´Ù. ÆÄÀÏÀÌ ÀÖÁö¸¸ Àаųª + ¾µ ¼ö ¾ø´Ù¸é, htpasswd´Â ÆÄÀÏÀ» ¼öÁ¤ÇÏÁö¾Ê°í + ¹®±¸¸¦ Ãâ·ÂÇÑÈÄ ¿À·ù»óŸ¦ ¹ÝȯÇÑ´Ù.

    + + + htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve + + +

    ¸í·ÉÇàÀÇ ¾ÏÈ£(Pwd4Steve)¸¦ MD5 ¾Ë°í¸®ÁòÀ¸·Î + ¾ÏȣȭÇÏ¿© ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ ÀúÀåÇÑ´Ù.

    +
    + +
    º¸¾È»ó °í·ÁÇÒ Á¡ +

    htpasswd µîÀÌ °ü¸®ÇÏ´Â À¥ ¾ÏÈ£ÆÄÀÏÀÌ À¥¼­¹öÀÇ + URI °ø°£¿¡ ÀÖÀ¸¸é ¾ÈµÈ´Ù. Áï, ºê¶ó¿ìÀú°¡ ÀÌ ÆÄÀÏÀ» + º¼ ¼ö ¾ø¾î¾ß ÇÑ´Ù.

    + +

    ¸í·ÉÇà¿¡ ¾ÏȣȭÇÏÁö¾ÊÀº ¾ÏÈ£¸¦ »ç¿ëÇϱ⶧¹®¿¡ -b + ¿É¼ÇÀ» ÃßõÇÏÁö ¾Ê´Â´Ù.

    +
    + +
    Á¦ÇÑ +

    Windows¿Í MPE Ç÷¡ÆûÀº htpasswd°¡ ¾ÏȣȭÇÏ´Â + ¾ÏÈ£ÀÇ ±æÀ̸¦ 255 ¹®ÀÚ·Î Á¦ÇÑÇÑ´Ù. ´õ ±ä ¾ÏÈ£´Â + 255ÀÚ¿¡¼­ ©¸°´Ù.

    + +

    htpasswd°¡ »ç¿ëÇÏ´Â MD5 ¾Ë°í¸®ÁòÀº ¾ÆÆÄÄ¡ + ¼ÒÇÁÆ®¿þ¾î ƯÀ¯ÀÇ °ÍÀÌ´Ù. À̸¦ »ç¿ëÇÏ¿© ¾ÏȣȭÇÑ ¾ÏÈ£¸¦ + ´Ù¸¥ À¥¼­¹ö¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù.

    + +

    »ç¿ëÀÚ¸íÀº 255 ¹ÙÀÌÆ®·Î Á¦Çѵǰí : + ¹®ÀÚ¸¦ Æ÷ÇÔÇÒ ¼ö ¾ø´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/programs/htpasswd.xml.meta b/trunk/docs/manual/programs/htpasswd.xml.meta new file mode 100644 index 0000000000..72455343e3 --- /dev/null +++ b/trunk/docs/manual/programs/htpasswd.xml.meta @@ -0,0 +1,12 @@ + + + + htpasswd + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/httpd.html b/trunk/docs/manual/programs/httpd.html new file mode 100644 index 0000000000..7d7ff916d3 --- /dev/null +++ b/trunk/docs/manual/programs/httpd.html @@ -0,0 +1,7 @@ +URI: httpd.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: httpd.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/httpd.html.en b/trunk/docs/manual/programs/httpd.html.en new file mode 100644 index 0000000000..5bf7675083 --- /dev/null +++ b/trunk/docs/manual/programs/httpd.html.en @@ -0,0 +1,192 @@ + + + +httpd - Apache Hypertext Transfer Protocol Server - Apache HTTP Server + + + + + +
    <-
    +

    httpd - Apache Hypertext Transfer Protocol Server

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    httpd is the Apache HyperText Transfer Protocol + (HTTP) server program. It is designed to be run as a standalone + daemon process. When used like this it will create a pool of + child processes or threads to handle requests.

    + +

    In general, httpd should not be invoked directly, + but rather should be invoked via apachectl on Unix-based systems or as a service on Windows NT, + 2000 and XP and as + a console application on Windows 9x and ME.

    +
    + +
    top
    +
    +

    Synopsis

    +

    httpd [ -d + serverroot ] [ -f config ] + [ -C directive ] [ -c + directive ] [ -D parameter ] + [ -e level ] [ -E + file ] [ -k start|restart|graceful|stop ] + [ -R directory ] [ -h ] + [ -l ] [ -L ] [ -S ] + [ -t ] [ -v ] [ -V ] + [ -X ] [ -M ]

    + +

    On Windows systems, the + following additional arguments are available:

    + +

    httpd [ -k + install|config|uninstall ] [ -n name ] + [ -w ]

    +
    top
    +
    +

    Options

    + +
    +
    -d serverroot
    + +
    Set the initial value for the ServerRoot directive to +serverroot. This can be overridden by the ServerRoot +directive in the configuration file. The default is +/usr/local/apache2.
    + +
    -f config
    + +
    Uses the directives in the file config on startup. If +config does not begin with a /, then it is taken to be a +path relative to the ServerRoot. The default is +conf/httpd.conf.
    + +
    -k start|restart|graceful|stop
    + +
    Signals httpd to start, restart, or stop. See Stopping Apache for more information.
    + +
    -C directive
    + +
    Process the configuration directive before reading +config files.
    + +
    -c directive
    + +
    Process the configuration directive after reading config +files.
    + + +
    -D parameter
    + +
    Sets a configuration parameter which can be used with +<IfDefine> sections +in the configuration files to conditionally skip or process +commands at server startup and restart.
    + +
    -e level
    + +
    Sets the LogLevel to +level during server startup. This is useful for +temporarily increasing the verbosity of the error messages to find +problems during startup.
    + +
    -E file
    + +
    Send error messages during server startup to file.
    + +
    -R directory
    + +
    When the server is compiled using the SHARED_CORE +rule, this specifies the directory for the shared +object files.
    + +
    -h
    + +
    Output a short summary of available command line options.
    + +
    -l
    + +
    Output a list of modules compiled into the server. This will +not list dynamically loaded modules included using +the LoadModule directive.
    + +
    -L
    + +
    Output a list of directives together with expected arguments and +places where the directive is valid.
    + +
    -M
    + +
    Dump a list of loaded Static and Shared Modules.
    + +
    -S
    + +
    Show the settings as parsed from the config file (currently only +shows the virtualhost settings).
    + +
    -t
    + +
    Run syntax tests for configuration files only. The program +immediately exits after these syntax parsing tests with either a return code +of 0 (Syntax OK) or return code not equal to 0 (Syntax Error). If -D +DUMP_VHOSTS is also set, details of the virtual host +configuration will be printed. If -D DUMP_MODULES is +set, all loaded modules will be printed.
    + +
    -v
    + +
    Print the version of httpd, and then exit.
    + +
    -V
    + +
    Print the version and build parameters of httpd, and +then exit.
    + +
    -X
    + +
    Run httpd in debug mode. Only one worker will be started and the +server will not detach from the console.
    + +
    + +

    The following arguments are available only on the Windows platform:

    + +
    + +
    -k install|config|uninstall
    + +
    Install Apache as a Windows NT service; change startup options for +the Apache service; and uninstall the Apache service.
    + +
    -n name
    + +
    The name of the Apache service to signal.
    + +
    -w
    + +
    Keep the console window open on error so that the error message can +be read.
    + +
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/httpd.html.ko.euc-kr b/trunk/docs/manual/programs/httpd.html.ko.euc-kr new file mode 100644 index 0000000000..374924cbc8 --- /dev/null +++ b/trunk/docs/manual/programs/httpd.html.ko.euc-kr @@ -0,0 +1,188 @@ + + + +httpd - ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ ¼­¹ö - Apache HTTP Server + + + + + +
    <-
    +

    httpd - ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ ¼­¹ö

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    httpd´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ + (HTTP) ¼­¹ö ÇÁ·Î±×·¥ÀÌ´Ù. ÀÚü(standalone) µ¥¸ó ÇÁ·Î¼¼½º·Î + ½ÇÇàÇϵµ·Ï ¼³°èµÇ¾ú´Ù. ¿øÇÑ´Ù¸é ¿äûÀ» ó¸®ÇϱâÀ§ÇØ ÀÚ½Ä + ÇÁ·Î¼¼½º¿Í ¾²·¹µåµéÀ» ¸¸µç´Ù.

    + +

    ÀϹÝÀûÀ¸·Î httpd¸¦ Á÷Á¢ ½ÇÇàÇϱ⺸´Ù´Â + À¯´Ð½º±â¹Ý ½Ã½ºÅÛ¿¡¼­´Â apachectlÀ» ÅëÇØ, 2000, XP¿¡¼­´Â + ¼­ºñ½º·Î, Windows + 9x¿Í ME¿¡¼­´Â ÄÝ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    httpd [ -d + serverroot ] [ -f config ] + [ -C directive ] [ -c + directive ] [ -D parameter ] + [ -e level ] [ -E + file ] [ -k start|restart|graceful|stop ] + [ -R directory ] [ -h ] + [ -l ] [ -L ] [ -S ] + [ -t ] [ -v ] [ -V ] + [ -X ] [ -M ]

    + +

    Windows ½Ã½ºÅÛ¿¡¼­´Â + ´ÙÀ½ ¾Æ±Ô¸ÕÆ®¸¦ Ãß°¡·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + +

    httpd [ -k + install|config|uninstall ] [ -n name ] + [ -w ]

    +
    top
    +
    +

    ¿É¼Ç

    + +
    +
    -d serverroot
    + +
    ServerRoot Áö½Ã¾îÀÇ +±âº»°ªÀ» serverroot·Î ¼³Á¤ÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ ServerRoot +Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀÌ °ªÀ» ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº +/usr/local/apache2ÀÌ´Ù.
    + +
    -f config
    + +
    ½ÃÀÛÇÒ¶§ config ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. +config°¡ /·Î ½ÃÀÛÇÏÁö ¾ÊÀ¸¸é ServerRoot¿¡ »ó´ë°æ·ÎÀÌ´Ù. ±âº»°ªÀº +conf/httpd.confÀÌ´Ù.
    + +
    -k start|restart|graceful|stop
    + +
    httpd¸¦ ½ÃÀÛ, Àç½ÃÀÛ, Áß´ÜÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â +¾ÆÆÄÄ¡ Áß´ÜÇϱ⸦ Âü°íÇ϶ó.
    + +
    -C directive
    + +
    ¼³Á¤ÆÄÀÏÀ» ÀбâÀü¿¡ directive Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù.
    + +
    -c directive
    + +
    ¼³Á¤ÆÄÀÏÀ» ÀбâÀü¿¡ directive Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù.
    + + +
    -D parameter
    + +
    ¼­¹ö ½ÃÀÛ È¤Àº Àç½ÃÀ۽à ¼±ÅÃÀûÀ¸·Î ¸í·É¾î¸¦ ó¸®ÇϱâÀ§ÇØ +¼³Á¤ÆÄÀÏÀÇ <IfDefine> +¼½¼Ç¿¡ »ç¿ëÇÒ parameter¸¦ ¼³Á¤ÇÑ´Ù.
    + +
    -e level
    + +
    ¼­¹ö°¡ ½ÃÀÛÇϴµ¿¾È LogLevelÀ» +level·Î ¼³Á¤ÇÑ´Ù. ÀÌ´Â ½ÃÀÛÁß ¹®Á¦¸¦ ã±âÀ§ÇØ Àá½Ã +´õ ÀÚ¼¼ÇÑ ¿À·ù¹®À» ¾òÀ»¶§ À¯¿ëÇÏ´Ù.
    + +
    -E file
    + +
    ¼­¹ö°¡ ½ÃÀÛÇϴµ¿¾È file·Î ¿À·ù¹®À» º¸³½´Ù.
    + +
    -R directory
    + +
    ¼­¹ö¸¦ SHARED_CORE ±ÔÄ¢À» »ç¿ëÇÏ¿© ÄÄÆÄÀÏÇÑ +°æ¿ì °øÀ¯¿ÀºêÁ§Æ®ÆÄÀÏ directory¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    -h
    + +
    »ç¿ëÇÒ ¼ö ÀÖ´Â ¸í·ÉÇà ¿É¼ÇµéÀÇ ÂªÀº ¿ä¾àÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -l
    + +
    ¼­¹ö¿¡ °°ÀÌ ÄÄÆÄÀÏÇÑ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù. LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© µ¿ÀûÀ¸·Î +ÀоîµéÀÌ´Â ¸ðµâÀº Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    -L
    + +
    Áö½Ã¾î ¸ñ·ÏÀ» Áö½Ã¾î°¡ ¹Þ´Â ¾Æ±Ô¸ÕÆ®¿Í Áö½Ã¾î »ç¿ëÀå¼Ò¿Í +°°ÀÌ Ãâ·ÂÇÑ´Ù.
    + +
    -M
    + +
    ÀоîµéÀÎ Á¤Àû ¸ðµâ°ú °øÀ¯ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -S
    + +
    ¼³Á¤ÆÄÀÏ¿¡¼­ ÀоîµéÀÎ ¼³Á¤À» º¸¿©ÁØ´Ù (ÇöÀç´Â °¡»óÈ£½ºÆ® +¼³Á¤¸¸À» º¸¿©ÁØ´Ù).
    + +
    -t
    + +
    ¼³Á¤ÆÄÀÏÀÇ ¹®¹ý°Ë»ç¸¸ ÇÑ´Ù. ÇÁ·Î±×·¥Àº ¹®¹ýÀ» °Ë»çÇÑÈÄ +(¹®¹ýÀÌ ¿Ã¹Ù¸¥ °æ¿ì) 0À̳ª (¹®¹ý¿¡ ¹®Á¦°¡ ÀÖ´Â °æ¿ì) 0ÀÌ ¾Æ´Ñ +Á¾·áÄÚµå·Î Áï½Ã Á¾·áÇÑ´Ù. -D DUMP_VHOSTSÀ» +»ç¿ëÇÏ¸é °¡»óÈ£½ºÆ® ¼³Á¤À» ÀÚ¼¼È÷ Ãâ·ÂÇÑ´Ù. -D +DUMP_MODULES¸¦ »ç¿ëÇϸé ÀоîµéÀÎ ¸ðµâ +¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -v
    + +
    httpdÀÇ ¹öÀüÀ» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    + +
    -V
    + +
    httpdÀÇ ¹öÀü°ú ÄÄÆÄÀÏ ÆĶó¹ÌÅ͸¦ Ãâ·ÂÇÏ°í +Á¾·áÇÑ´Ù.
    + +
    -X
    + +
    µð¹ö±× »óÅ·ΠÀ¥¼­¹ö¸¦ ½ÇÇàÇÑ´Ù. ¿ÀÁ÷ ÇÑ ÇÁ·Î¼¼½º³ª ¾²·¹µå·Î¸¸ +¼­ºñ½ºÇÏ°í, ¼­¹ö´Â Äֿܼ¡¼­ ¶³¾îÁöÁö ¾Ê´Â´Ù.
    + +
    + +

    ´ÙÀ½ ¾Æ±Ô¸ÕÆ®´Â Windows +Ç÷¡Æû¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + +
    + +
    -k install|config|uninstall
    + +
    ¾ÆÆÄÄ¡¸¦ Windows NT ¼­ºñ½º·Î ¼³Ä¡ÇÑ´Ù; ¾ÆÆÄÄ¡ ¼­ºñ½ºÀÇ ½ÃÀÛ +¿É¼ÇÀ» ¼öÁ¤ÇÑ´Ù; ¾ÆÆÄÄ¡ ¼­ºñ½º ¼³Ä¡¸¦ Áö¿î´Ù.
    + +
    -n name
    + +
    ¾ÆÆÄÄ¡ ¼­ºñ½ºÀÇ name.
    + +
    -w
    + +
    ¿À·ù°¡ ¹ß»ýÇϸé ÄܼÖâÀ» ¿­¾î¼­ ¿À·ù¹®À» º¸¿©ÁØ´Ù.
    + +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/httpd.xml b/trunk/docs/manual/programs/httpd.xml new file mode 100644 index 0000000000..4710eaf19b --- /dev/null +++ b/trunk/docs/manual/programs/httpd.xml @@ -0,0 +1,199 @@ + + + + + + + + +Programs + + httpd - Apache Hypertext Transfer Protocol Server + + +

    httpd is the Apache HyperText Transfer Protocol + (HTTP) server program. It is designed to be run as a standalone + daemon process. When used like this it will create a pool of + child processes or threads to handle requests.

    + +

    In general, httpd should not be invoked directly, + but rather should be invoked via + apachectl on Unix-based systems or as a service on Windows NT, + 2000 and XP and as + a console application on Windows 9x and ME.

    +
    + +Starting Apache +Stopping Apache +Configuration Files +Platform-specific Documentation +apachectl + +
    Synopsis +

    httpd [ -d + serverroot ] [ -f config ] + [ -C directive ] [ -c + directive ] [ -D parameter ] + [ -e level ] [ -E + file ] [ -k start|restart|graceful|stop ] + [ -R directory ] [ -h ] + [ -l ] [ -L ] [ -S ] + [ -t ] [ -v ] [ -V ] + [ -X ] [ -M ]

    + +

    On Windows systems, the + following additional arguments are available:

    + +

    httpd [ -k + install|config|uninstall ] [ -n name ] + [ -w ]

    +
    + +
    Options + +
    +
    -d serverroot
    + +
    Set the initial value for the ServerRoot directive to +serverroot. This can be overridden by the ServerRoot +directive in the configuration file. The default is +/usr/local/apache2.
    + +
    -f config
    + +
    Uses the directives in the file config on startup. If +config does not begin with a /, then it is taken to be a +path relative to the ServerRoot. The default is +conf/httpd.conf.
    + +
    -k start|restart|graceful|stop
    + +
    Signals httpd to start, restart, or stop. See Stopping Apache for more information.
    + +
    -C directive
    + +
    Process the configuration directive before reading +config files.
    + +
    -c directive
    + +
    Process the configuration directive after reading config +files.
    + + +
    -D parameter
    + +
    Sets a configuration parameter which can be used with +IfDefine sections +in the configuration files to conditionally skip or process +commands at server startup and restart.
    + +
    -e level
    + +
    Sets the LogLevel to +level during server startup. This is useful for +temporarily increasing the verbosity of the error messages to find +problems during startup.
    + +
    -E file
    + +
    Send error messages during server startup to file.
    + +
    -R directory
    + +
    When the server is compiled using the SHARED_CORE +rule, this specifies the directory for the shared +object files.
    + +
    -h
    + +
    Output a short summary of available command line options.
    + +
    -l
    + +
    Output a list of modules compiled into the server. This will +not list dynamically loaded modules included using +the LoadModule directive.
    + +
    -L
    + +
    Output a list of directives together with expected arguments and +places where the directive is valid.
    + +
    -M
    + +
    Dump a list of loaded Static and Shared Modules.
    + +
    -S
    + +
    Show the settings as parsed from the config file (currently only +shows the virtualhost settings).
    + +
    -t
    + +
    Run syntax tests for configuration files only. The program +immediately exits after these syntax parsing tests with either a return code +of 0 (Syntax OK) or return code not equal to 0 (Syntax Error). If -D +DUMP_VHOSTS is also set, details of the virtual host +configuration will be printed. If -D DUMP_MODULES is +set, all loaded modules will be printed.
    + +
    -v
    + +
    Print the version of httpd, and then exit.
    + +
    -V
    + +
    Print the version and build parameters of httpd, and +then exit.
    + +
    -X
    + +
    Run httpd in debug mode. Only one worker will be started and the +server will not detach from the console.
    + +
    + +

    The following arguments are available only on the Windows platform:

    + +
    + +
    -k install|config|uninstall
    + +
    Install Apache as a Windows NT service; change startup options for +the Apache service; and uninstall the Apache service.
    + +
    -n name
    + +
    The name of the Apache service to signal.
    + +
    -w
    + +
    Keep the console window open on error so that the error message can +be read.
    + +
    + +
    + +
    diff --git a/trunk/docs/manual/programs/httpd.xml.ko b/trunk/docs/manual/programs/httpd.xml.ko new file mode 100644 index 0000000000..0f54a5ad0f --- /dev/null +++ b/trunk/docs/manual/programs/httpd.xml.ko @@ -0,0 +1,191 @@ + + + + + + + + +Programs + + httpd - ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ ¼­¹ö + + +

    httpd´Â ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ + (HTTP) ¼­¹ö ÇÁ·Î±×·¥ÀÌ´Ù. ÀÚü(standalone) µ¥¸ó ÇÁ·Î¼¼½º·Î + ½ÇÇàÇϵµ·Ï ¼³°èµÇ¾ú´Ù. ¿øÇÑ´Ù¸é ¿äûÀ» ó¸®ÇϱâÀ§ÇØ ÀÚ½Ä + ÇÁ·Î¼¼½º¿Í ¾²·¹µåµéÀ» ¸¸µç´Ù.

    + +

    ÀϹÝÀûÀ¸·Î httpd¸¦ Á÷Á¢ ½ÇÇàÇϱ⺸´Ù´Â + À¯´Ð½º±â¹Ý ½Ã½ºÅÛ¿¡¼­´Â apachectlÀ» ÅëÇØ, 2000, XP¿¡¼­´Â + ¼­ºñ½º·Î, Windows + 9x¿Í ME¿¡¼­´Â ÄÝ¼Ö ÇÁ·Î±×·¥À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù.

    +
    + +¾ÆÆÄÄ¡ ½ÃÀÛ +¾ÆÆÄÄ¡ Áß´Ü +¼³Á¤ÆÄÀÏ +Ç÷¡Æûº° ¹®¼­ +apachectl + +
    °³¿ä +

    httpd [ -d + serverroot ] [ -f config ] + [ -C directive ] [ -c + directive ] [ -D parameter ] + [ -e level ] [ -E + file ] [ -k start|restart|graceful|stop ] + [ -R directory ] [ -h ] + [ -l ] [ -L ] [ -S ] + [ -t ] [ -v ] [ -V ] + [ -X ] [ -M ]

    + +

    Windows ½Ã½ºÅÛ¿¡¼­´Â + ´ÙÀ½ ¾Æ±Ô¸ÕÆ®¸¦ Ãß°¡·Î »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + +

    httpd [ -k + install|config|uninstall ] [ -n name ] + [ -w ]

    +
    + +
    ¿É¼Ç + +
    +
    -d serverroot
    + +
    ServerRoot Áö½Ã¾îÀÇ +±âº»°ªÀ» serverroot·Î ¼³Á¤ÇÑ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ ServerRoot +Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀÌ °ªÀ» ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. ±âº»°ªÀº +/usr/local/apache2ÀÌ´Ù.
    + +
    -f config
    + +
    ½ÃÀÛÇÒ¶§ config ÆÄÀÏ¿¡ ÀÖ´Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù. +config°¡ /·Î ½ÃÀÛÇÏÁö ¾ÊÀ¸¸é ServerRoot¿¡ »ó´ë°æ·ÎÀÌ´Ù. ±âº»°ªÀº +conf/httpd.confÀÌ´Ù.
    + +
    -k start|restart|graceful|stop
    + +
    httpd¸¦ ½ÃÀÛ, Àç½ÃÀÛ, Áß´ÜÇÑ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â +¾ÆÆÄÄ¡ Áß´ÜÇϱ⸦ Âü°íÇ϶ó.
    + +
    -C directive
    + +
    ¼³Á¤ÆÄÀÏÀ» ÀбâÀü¿¡ directive Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù.
    + +
    -c directive
    + +
    ¼³Á¤ÆÄÀÏÀ» ÀбâÀü¿¡ directive Áö½Ã¾î¸¦ ó¸®ÇÑ´Ù.
    + + +
    -D parameter
    + +
    ¼­¹ö ½ÃÀÛ È¤Àº Àç½ÃÀ۽à ¼±ÅÃÀûÀ¸·Î ¸í·É¾î¸¦ ó¸®ÇϱâÀ§ÇØ +¼³Á¤ÆÄÀÏÀÇ IfDefine +¼½¼Ç¿¡ »ç¿ëÇÒ parameter¸¦ ¼³Á¤ÇÑ´Ù.
    + +
    -e level
    + +
    ¼­¹ö°¡ ½ÃÀÛÇϴµ¿¾È LogLevelÀ» +level·Î ¼³Á¤ÇÑ´Ù. ÀÌ´Â ½ÃÀÛÁß ¹®Á¦¸¦ ã±âÀ§ÇØ Àá½Ã +´õ ÀÚ¼¼ÇÑ ¿À·ù¹®À» ¾òÀ»¶§ À¯¿ëÇÏ´Ù.
    + +
    -E file
    + +
    ¼­¹ö°¡ ½ÃÀÛÇϴµ¿¾È file·Î ¿À·ù¹®À» º¸³½´Ù.
    + +
    -R directory
    + +
    ¼­¹ö¸¦ SHARED_CORE ±ÔÄ¢À» »ç¿ëÇÏ¿© ÄÄÆÄÀÏÇÑ +°æ¿ì °øÀ¯¿ÀºêÁ§Æ®ÆÄÀÏ directory¸¦ ÁöÁ¤ÇÑ´Ù.
    + +
    -h
    + +
    »ç¿ëÇÒ ¼ö ÀÖ´Â ¸í·ÉÇà ¿É¼ÇµéÀÇ ÂªÀº ¿ä¾àÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -l
    + +
    ¼­¹ö¿¡ °°ÀÌ ÄÄÆÄÀÏÇÑ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù. LoadModule Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© µ¿ÀûÀ¸·Î +ÀоîµéÀÌ´Â ¸ðµâÀº Ãâ·ÂÇÏÁö ¾Ê´Â´Ù.
    + +
    -L
    + +
    Áö½Ã¾î ¸ñ·ÏÀ» Áö½Ã¾î°¡ ¹Þ´Â ¾Æ±Ô¸ÕÆ®¿Í Áö½Ã¾î »ç¿ëÀå¼Ò¿Í +°°ÀÌ Ãâ·ÂÇÑ´Ù.
    + +
    -M
    + +
    ÀоîµéÀÎ Á¤Àû ¸ðµâ°ú °øÀ¯ ¸ðµâ ¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -S
    + +
    ¼³Á¤ÆÄÀÏ¿¡¼­ ÀоîµéÀÎ ¼³Á¤À» º¸¿©ÁØ´Ù (ÇöÀç´Â °¡»óÈ£½ºÆ® +¼³Á¤¸¸À» º¸¿©ÁØ´Ù).
    + +
    -t
    + +
    ¼³Á¤ÆÄÀÏÀÇ ¹®¹ý°Ë»ç¸¸ ÇÑ´Ù. ÇÁ·Î±×·¥Àº ¹®¹ýÀ» °Ë»çÇÑÈÄ +(¹®¹ýÀÌ ¿Ã¹Ù¸¥ °æ¿ì) 0À̳ª (¹®¹ý¿¡ ¹®Á¦°¡ ÀÖ´Â °æ¿ì) 0ÀÌ ¾Æ´Ñ +Á¾·áÄÚµå·Î Áï½Ã Á¾·áÇÑ´Ù. -D DUMP_VHOSTSÀ» +»ç¿ëÇÏ¸é °¡»óÈ£½ºÆ® ¼³Á¤À» ÀÚ¼¼È÷ Ãâ·ÂÇÑ´Ù. -D +DUMP_MODULES¸¦ »ç¿ëÇϸé ÀоîµéÀÎ ¸ðµâ +¸ñ·ÏÀ» Ãâ·ÂÇÑ´Ù.
    + +
    -v
    + +
    httpdÀÇ ¹öÀüÀ» Ãâ·ÂÇÏ°í Á¾·áÇÑ´Ù.
    + +
    -V
    + +
    httpdÀÇ ¹öÀü°ú ÄÄÆÄÀÏ ÆĶó¹ÌÅ͸¦ Ãâ·ÂÇÏ°í +Á¾·áÇÑ´Ù.
    + +
    -X
    + +
    µð¹ö±× »óÅ·ΠÀ¥¼­¹ö¸¦ ½ÇÇàÇÑ´Ù. ¿ÀÁ÷ ÇÑ ÇÁ·Î¼¼½º³ª ¾²·¹µå·Î¸¸ +¼­ºñ½ºÇÏ°í, ¼­¹ö´Â Äֿܼ¡¼­ ¶³¾îÁöÁö ¾Ê´Â´Ù.
    + +
    + +

    ´ÙÀ½ ¾Æ±Ô¸ÕÆ®´Â Windows +Ç÷¡Æû¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù:

    + +
    + +
    -k install|config|uninstall
    + +
    ¾ÆÆÄÄ¡¸¦ Windows NT ¼­ºñ½º·Î ¼³Ä¡ÇÑ´Ù; ¾ÆÆÄÄ¡ ¼­ºñ½ºÀÇ ½ÃÀÛ +¿É¼ÇÀ» ¼öÁ¤ÇÑ´Ù; ¾ÆÆÄÄ¡ ¼­ºñ½º ¼³Ä¡¸¦ Áö¿î´Ù.
    + +
    -n name
    + +
    ¾ÆÆÄÄ¡ ¼­ºñ½ºÀÇ name.
    + +
    -w
    + +
    ¿À·ù°¡ ¹ß»ýÇϸé ÄܼÖâÀ» ¿­¾î¼­ ¿À·ù¹®À» º¸¿©ÁØ´Ù.
    + +
    + +
    + +
    diff --git a/trunk/docs/manual/programs/httpd.xml.meta b/trunk/docs/manual/programs/httpd.xml.meta new file mode 100644 index 0000000000..13e18e8c38 --- /dev/null +++ b/trunk/docs/manual/programs/httpd.xml.meta @@ -0,0 +1,12 @@ + + + + httpd + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/index.html b/trunk/docs/manual/programs/index.html new file mode 100644 index 0000000000..37d824cf97 --- /dev/null +++ b/trunk/docs/manual/programs/index.html @@ -0,0 +1,11 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/index.html.en b/trunk/docs/manual/programs/index.html.en new file mode 100644 index 0000000000..e7192bd197 --- /dev/null +++ b/trunk/docs/manual/programs/index.html.en @@ -0,0 +1,100 @@ + + + +Server and Supporting Programs - Apache HTTP Server + + + + + +
    <-
    +

    Server and Supporting Programs

    +
    +

    Available Languages:  en  | + es  | + ko 

    +
    + +

    This page documents all the executable programs included + with the Apache HTTP Server.

    +
    +
    top
    +
    +

    Index

    + +
    +
    httpd
    + +
    Apache hypertext transfer protocol server
    + +
    apachectl
    + +
    Apache HTTP server control interface
    + +
    ab
    + +
    Apache HTTP server benchmarking tool
    + +
    apxs
    + +
    APache eXtenSion tool
    + +
    configure
    + +
    Configure the source tree
    + +
    dbmmanage
    + +
    Create and update user authentication files in DBM format + for basic authentication
    + +
    htcacheclean
    +
    Clean up the disk cache
    + +
    htdigest
    + +
    Create and update user authentication files for digest + authentication
    + +
    htdbm
    + +
    Manipulate DBM password databases.
    + +
    htpasswd
    + +
    Create and update user authentication files for basic + authentication
    + +
    logresolve
    + +
    Resolve hostnames for IP-addresses in Apache + logfiles
    + +
    rotatelogs
    + +
    Rotate Apache logs without having to kill the server
    + +
    suexec
    + +
    Switch User For Exec
    + +
    Other Programs
    +
    Support tools with no own manual page.
    +
    +
    +
    +

    Available Languages:  en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/index.html.es b/trunk/docs/manual/programs/index.html.es new file mode 100644 index 0000000000..c088b63bfa --- /dev/null +++ b/trunk/docs/manual/programs/index.html.es @@ -0,0 +1,100 @@ + + + +El Servidor Apache y Programas de Soporte - Servidor HTTP Apache + + + + + +
    <-
    +

    El Servidor Apache y Programas de Soporte

    +
    +

    Idiomas disponibles:  en  | + es  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Esta página contiene toda la documentación sobre los programas + ejecutables incluidos en el servidor Apache.

    +
    +
    top
    +
    +

    Índice

    + +
    +
    httpd
    + +
    Servidor Apache del Protocolo de Transmisión de + Hipertexto (HTTP)
    + +
    apachectl
    + +
    Interfaz de control del servidor HTTP Apache
    + +
    ab
    + +
    Herramienta de benchmarking del Servidor HTTP Apache
    + +
    apxs
    + +
    Herramienta de Extensión de Apache
    + +
    configure
    + +
    Configuración de la estructura de directorios de Apache
    + +
    dbmmanage
    + +
    Crea y actualiza los archivos de autentificación de usuarios + en formato DBM para autentificación básica
    + +
    htdigest
    + +
    Crea y actualiza los ficheros de autentificación de usuarios + para autentificación tipo digest
    + +
    htpasswd
    + +
    Crea y actualiza los ficheros de autentificación de usuarios + para autentificación básica
    + +
    logresolve
    + +
    Resuelve los nombres de host para direcciones IP que estén + en los ficheros log de Apache
    + +
    rotatelogs
    + +
    Renueva los logs de Apache sin parar el servidor
    + +
    suexec
    + +
    Switch User For Exec. Programa para cambiar la identidad de + usuario con la que se ejecuta un CGI
    + +
    Otros Programas
    +
    Herramientas de soporte sin sección propia en la + documentación.
    +
    +
    +
    +

    Idiomas disponibles:  en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/index.html.ko.euc-kr b/trunk/docs/manual/programs/index.html.ko.euc-kr new file mode 100644 index 0000000000..d6a1fe7b90 --- /dev/null +++ b/trunk/docs/manual/programs/index.html.ko.euc-kr @@ -0,0 +1,96 @@ + + + +¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ - Apache HTTP Server + + + + + +
    <-
    +

    ¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ Æ÷ÇÔµÈ ÇÁ·Î±×·¥µéÀÌ´Ù.

    +
    +
    top
    +
    +

    ¸ñ·Ï

    + +
    +
    httpd
    + +
    ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ ¼­¹ö
    + +
    apachectl
    + +
    ¾ÆÆÄÄ¡ À¥¼­¹ö Á¶Àý ÀÎÅÍÆäÀ̽º
    + +
    ab
    + +
    ¾ÆÆÄÄ¡ À¥¼­¹ö ¼º´É°Ë»ç µµ±¸
    + +
    apxs
    + +
    ¾ÆÆÄÄ¡ È®Àå µµ±¸ (APache eXtenSion tool)
    + +
    configure
    + +
    ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù
    + +
    dbmmanage
    + +
    basic authentication¿¡ »ç¿ëÇÒ DBM Çü½ÄÀÇ »ç¿ëÀÚ + ÀÎÁõÆÄÀÏÀ» ¸¸µé°í ¼öÁ¤ÇÑ´Ù
    + +
    htcacheclean
    +
    µð½ºÅ© ij½¬¸¦ û¼ÒÇÑ´Ù
    + +
    htdigest
    + +
    digest authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ÀÎÁõÆÄÀÏÀ» + ¸¸µé°í ¼öÁ¤ÇÑ´Ù
    + +
    htpasswd
    + +
    basic authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ÀÎÁõÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù
    + +
    logresolve
    + +
    ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀÇ IP-ÁÖ¼Ò¸¦ È£½ºÆ®¸íÀ¸·Î º¯È¯ÇÑ´Ù
    + +
    rotatelogs
    + +
    ¼­¹ö¸¦ Á×ÀÌÁö¾Ê°í ¾ÆÆÄÄ¡ ·Î±×¸¦ ¼øȯÇÑ´Ù
    + +
    suexec
    + +
    ½ÇÇàÀ» À§ÇØ »ç¿ëÀÚ¸¦ º¯°æÇÑ´Ù (Switch User For Exec)
    + +
    ´Ù¸¥ ÇÁ·Î±×·¥µé
    +
    manpage°¡ ¾ø´Â Áö¿ø µµ±¸µé.
    +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + es  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/index.xml b/trunk/docs/manual/programs/index.xml new file mode 100644 index 0000000000..18c3dfb8d2 --- /dev/null +++ b/trunk/docs/manual/programs/index.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + Server and Supporting Programs + + +

    This page documents all the executable programs included + with the Apache HTTP Server.

    +
    + +
    Index + +
    +
    httpd
    + +
    Apache hypertext transfer protocol server
    + +
    apachectl
    + +
    Apache HTTP server control interface
    + +
    ab
    + +
    Apache HTTP server benchmarking tool
    + +
    apxs
    + +
    APache eXtenSion tool
    + +
    configure
    + +
    Configure the source tree
    + +
    dbmmanage
    + +
    Create and update user authentication files in DBM format + for basic authentication
    + +
    htcacheclean
    +
    Clean up the disk cache
    + +
    htdigest
    + +
    Create and update user authentication files for digest + authentication
    + +
    htdbm
    + +
    Manipulate DBM password databases.
    + +
    htpasswd
    + +
    Create and update user authentication files for basic + authentication
    + +
    logresolve
    + +
    Resolve hostnames for IP-addresses in Apache + logfiles
    + +
    rotatelogs
    + +
    Rotate Apache logs without having to kill the server
    + +
    suexec
    + +
    Switch User For Exec
    + +
    Other Programs
    +
    Support tools with no own manual page.
    +
    +
    + +
    diff --git a/trunk/docs/manual/programs/index.xml.es b/trunk/docs/manual/programs/index.xml.es new file mode 100644 index 0000000000..d6de0fba05 --- /dev/null +++ b/trunk/docs/manual/programs/index.xml.es @@ -0,0 +1,94 @@ + + + + + + + + + + + El Servidor Apache y Programas de Soporte + + +

    Esta página contiene toda la documentación sobre los programas + ejecutables incluidos en el servidor Apache.

    +
    + +
    Índice + +
    +
    httpd
    + +
    Servidor Apache del Protocolo de Transmisión de + Hipertexto (HTTP)
    + +
    apachectl
    + +
    Interfaz de control del servidor HTTP Apache
    + +
    ab
    + +
    Herramienta de benchmarking del Servidor HTTP Apache
    + +
    apxs
    + +
    Herramienta de Extensión de Apache
    + +
    configure
    + +
    Configuración de la estructura de directorios de Apache
    + +
    dbmmanage
    + +
    Crea y actualiza los archivos de autentificación de usuarios + en formato DBM para autentificación básica
    + +
    htdigest
    + +
    Crea y actualiza los ficheros de autentificación de usuarios + para autentificación tipo digest
    + +
    htpasswd
    + +
    Crea y actualiza los ficheros de autentificación de usuarios + para autentificación básica
    + +
    logresolve
    + +
    Resuelve los nombres de host para direcciones IP que estén + en los ficheros log de Apache
    + +
    rotatelogs
    + +
    Renueva los logs de Apache sin parar el servidor
    + +
    suexec
    + +
    Switch User For Exec. Programa para cambiar la identidad de + usuario con la que se ejecuta un CGI
    + +
    Otros Programas
    +
    Herramientas de soporte sin sección propia en la + documentación.
    +
    +
    + +
    + + diff --git a/trunk/docs/manual/programs/index.xml.ko b/trunk/docs/manual/programs/index.xml.ko new file mode 100644 index 0000000000..949e066b28 --- /dev/null +++ b/trunk/docs/manual/programs/index.xml.ko @@ -0,0 +1,90 @@ + + + + + + + + + + + ¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ Æ÷ÇÔµÈ ÇÁ·Î±×·¥µéÀÌ´Ù.

    +
    + +
    ¸ñ·Ï + +
    +
    httpd
    + +
    ¾ÆÆÄÄ¡ ÇÏÀÌÆÛÅؽºÆ® Àü¼Û ÇÁ·ÎÅäÄÝ ¼­¹ö
    + +
    apachectl
    + +
    ¾ÆÆÄÄ¡ À¥¼­¹ö Á¶Àý ÀÎÅÍÆäÀ̽º
    + +
    ab
    + +
    ¾ÆÆÄÄ¡ À¥¼­¹ö ¼º´É°Ë»ç µµ±¸
    + +
    apxs
    + +
    ¾ÆÆÄÄ¡ È®Àå µµ±¸ (APache eXtenSion tool)
    + +
    configure
    + +
    ¼Ò½º Æ®¸®¸¦ ±¸¼ºÇÑ´Ù
    + +
    dbmmanage
    + +
    basic authentication¿¡ »ç¿ëÇÒ DBM Çü½ÄÀÇ »ç¿ëÀÚ + ÀÎÁõÆÄÀÏÀ» ¸¸µé°í ¼öÁ¤ÇÑ´Ù
    + +
    htcacheclean
    +
    µð½ºÅ© ij½¬¸¦ û¼ÒÇÑ´Ù
    + +
    htdigest
    + +
    digest authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ÀÎÁõÆÄÀÏÀ» + ¸¸µé°í ¼öÁ¤ÇÑ´Ù
    + +
    htpasswd
    + +
    basic authentication¿¡ »ç¿ëÇÒ »ç¿ëÀÚ ÀÎÁõÆÄÀÏÀ» ¸¸µé°í + ¼öÁ¤ÇÑ´Ù
    + +
    logresolve
    + +
    ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀÇ IP-ÁÖ¼Ò¸¦ È£½ºÆ®¸íÀ¸·Î º¯È¯ÇÑ´Ù
    + +
    rotatelogs
    + +
    ¼­¹ö¸¦ Á×ÀÌÁö¾Ê°í ¾ÆÆÄÄ¡ ·Î±×¸¦ ¼øȯÇÑ´Ù
    + +
    suexec
    + +
    ½ÇÇàÀ» À§ÇØ »ç¿ëÀÚ¸¦ º¯°æÇÑ´Ù (Switch User For Exec)
    + +
    ´Ù¸¥ ÇÁ·Î±×·¥µé
    +
    manpage°¡ ¾ø´Â Áö¿ø µµ±¸µé.
    +
    +
    + +
    diff --git a/trunk/docs/manual/programs/index.xml.meta b/trunk/docs/manual/programs/index.xml.meta new file mode 100644 index 0000000000..d82564162b --- /dev/null +++ b/trunk/docs/manual/programs/index.xml.meta @@ -0,0 +1,13 @@ + + + + index + /programs/ + .. + + + en + es + ko + + diff --git a/trunk/docs/manual/programs/logresolve.html b/trunk/docs/manual/programs/logresolve.html new file mode 100644 index 0000000000..6c1b8a70bb --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.html @@ -0,0 +1,7 @@ +URI: logresolve.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: logresolve.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/logresolve.html.en b/trunk/docs/manual/programs/logresolve.html.en new file mode 100644 index 0000000000..e6ee748e60 --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.html.en @@ -0,0 +1,72 @@ + + + +logresolve - Resolve IP-addresses to hostnames in Apache + log files - Apache HTTP Server + + + + + +
    <-
    +

    logresolve - Resolve IP-addresses to hostnames in Apache + log files

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    logresolve is a post-processing program to + resolve IP-addresses in Apache's access logfiles. To minimize + impact on your nameserver, logresolve has its very own internal + hash-table cache. This means that each IP number will only be + looked up the first time it is found in the log file.

    + +

    Takes an Apache log file on standard input. The IP addresses + must be the first thing on each line and must be seperated from + the remainder of the line by a space.

    +
    + +
    top
    +
    +

    Synopsis

    + +

    logresolve [ -s + filename ] [ -c ] < + access_log > access_log.new

    +
    top
    +
    +

    Options

    + +
    + +
    -s filename
    + +
    Specifies a filename to record statistics.
    + +
    -c
    + +
    This causes logresolve to apply some DNS checks: +after finding the hostname from the IP address, it looks up the IP +addresses for the hostname and checks that one of these matches the +original address.
    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/logresolve.html.ko.euc-kr b/trunk/docs/manual/programs/logresolve.html.ko.euc-kr new file mode 100644 index 0000000000..ce7b4f5ad1 --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.html.ko.euc-kr @@ -0,0 +1,69 @@ + + + +logresolve - ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀÇ IP-ÁÖ¼Ò¸¦ È£½ºÆ®¸íÀ¸·Î + º¯È¯ÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    logresolve - ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀÇ IP-ÁÖ¼Ò¸¦ È£½ºÆ®¸íÀ¸·Î + º¯È¯ÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + +

    logresolve´Â ¾ÆÆÄÄ¡ Á¢±Ù·Î±×ÆÄÀÏ¿¡ ÀÖ´Â + IP-ÁÖ¼Ò¸¦ ã´Â ÈÄó¸® ÇÁ·Î±×·¥ÀÌ´Ù. ³×ÀÓ¼­¹öÀÇ ºÎÇϸ¦ + ÃÖ¼ÒÈ­ÇϱâÀ§ÇØ logresolve´Â ³»ºÎÀûÀ¸·Î Çؽ¬Å×À̺í ij½¬¸¦ + »ç¿ëÇÑ´Ù. Áï, IP ÁÖ¼Ò°¡ ·Î±×ÆÄÀÏ¿¡ óÀ½ ³ª¿Ã¶§¸¸ ã´Â´Ù.

    + +

    Ç¥ÁØÀÔ·ÂÀ¸·Î ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀ» Àд´Ù. °¢ ÁÙÀÇ Ã¹¹ø° + Ç׸ñÀÌ IP ÁÖ¼ÒÀÌ°í, ³ª¸ÓÁö ºÎºÐ°ú °ø¹éÀ¸·Î ±¸ºÐµÇ¾ß ÇÑ´Ù.

    +
    + +
    top
    +
    +

    °³¿ä

    + +

    logresolve [ -s + filename ] [ -c ] < + access_log > access_log.new

    +
    top
    +
    +

    ¿É¼Ç

    + +
    + +
    -s filename
    + +
    Åë°è¸¦ ±â·ÏÇÒ ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    -c
    + +
    logresolve°¡ ¸î°¡Áö DNS °Ë»ç¸¦ Çϵµ·Ï ÇÑ´Ù: +IP ÁּҷΠȣ½ºÆ®¸íÀ» ãÀºÈÄ ±× È£½ºÆ®¸íÀ¸·Î ´Ù½Ã IP ÁÖ¼ÒµéÀ» +ã¾Æ¼­ ±×Áß Çϳª°¡ ¿ø·¡ ÁÖ¼Ò¿Í ÀÏÄ¡ÇÏ´ÂÁö °Ë»çÇÑ´Ù.
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/logresolve.xml b/trunk/docs/manual/programs/logresolve.xml new file mode 100644 index 0000000000..bf226962a9 --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.xml @@ -0,0 +1,67 @@ + + + + + + + + +Programs + + logresolve - Resolve IP-addresses to hostnames in Apache + log files + + +

    logresolve is a post-processing program to + resolve IP-addresses in Apache's access logfiles. To minimize + impact on your nameserver, logresolve has its very own internal + hash-table cache. This means that each IP number will only be + looked up the first time it is found in the log file.

    + +

    Takes an Apache log file on standard input. The IP addresses + must be the first thing on each line and must be seperated from + the remainder of the line by a space.

    +
    + +
    Synopsis + +

    logresolve [ -s + filename ] [ -c ] < + access_log > access_log.new

    +
    + + +
    Options + +
    + +
    -s filename
    + +
    Specifies a filename to record statistics.
    + +
    -c
    + +
    This causes logresolve to apply some DNS checks: +after finding the hostname from the IP address, it looks up the IP +addresses for the hostname and checks that one of these matches the +original address.
    + +
    +
    + +
    diff --git a/trunk/docs/manual/programs/logresolve.xml.ko b/trunk/docs/manual/programs/logresolve.xml.ko new file mode 100644 index 0000000000..a8e2ec918e --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.xml.ko @@ -0,0 +1,64 @@ + + + + + + + + +Programs + + logresolve - ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀÇ IP-ÁÖ¼Ò¸¦ È£½ºÆ®¸íÀ¸·Î + º¯È¯ÇÑ´Ù + + +

    logresolve´Â ¾ÆÆÄÄ¡ Á¢±Ù·Î±×ÆÄÀÏ¿¡ ÀÖ´Â + IP-ÁÖ¼Ò¸¦ ã´Â ÈÄó¸® ÇÁ·Î±×·¥ÀÌ´Ù. ³×ÀÓ¼­¹öÀÇ ºÎÇϸ¦ + ÃÖ¼ÒÈ­ÇϱâÀ§ÇØ logresolve´Â ³»ºÎÀûÀ¸·Î Çؽ¬Å×À̺í ij½¬¸¦ + »ç¿ëÇÑ´Ù. Áï, IP ÁÖ¼Ò°¡ ·Î±×ÆÄÀÏ¿¡ óÀ½ ³ª¿Ã¶§¸¸ ã´Â´Ù.

    + +

    Ç¥ÁØÀÔ·ÂÀ¸·Î ¾ÆÆÄÄ¡ ·Î±×ÆÄÀÏÀ» Àд´Ù. °¢ ÁÙÀÇ Ã¹¹ø° + Ç׸ñÀÌ IP ÁÖ¼ÒÀÌ°í, ³ª¸ÓÁö ºÎºÐ°ú °ø¹éÀ¸·Î ±¸ºÐµÇ¾ß ÇÑ´Ù.

    +
    + +
    °³¿ä + +

    logresolve [ -s + filename ] [ -c ] < + access_log > access_log.new

    +
    + + +
    ¿É¼Ç + +
    + +
    -s filename
    + +
    Åë°è¸¦ ±â·ÏÇÒ ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù.
    + +
    -c
    + +
    logresolve°¡ ¸î°¡Áö DNS °Ë»ç¸¦ Çϵµ·Ï ÇÑ´Ù: +IP ÁּҷΠȣ½ºÆ®¸íÀ» ãÀºÈÄ ±× È£½ºÆ®¸íÀ¸·Î ´Ù½Ã IP ÁÖ¼ÒµéÀ» +ã¾Æ¼­ ±×Áß Çϳª°¡ ¿ø·¡ ÁÖ¼Ò¿Í ÀÏÄ¡ÇÏ´ÂÁö °Ë»çÇÑ´Ù.
    + +
    +
    + +
    diff --git a/trunk/docs/manual/programs/logresolve.xml.meta b/trunk/docs/manual/programs/logresolve.xml.meta new file mode 100644 index 0000000000..7e0922e7db --- /dev/null +++ b/trunk/docs/manual/programs/logresolve.xml.meta @@ -0,0 +1,12 @@ + + + + logresolve + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/other.html b/trunk/docs/manual/programs/other.html new file mode 100644 index 0000000000..2f9477404b --- /dev/null +++ b/trunk/docs/manual/programs/other.html @@ -0,0 +1,7 @@ +URI: other.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: other.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/other.html.en b/trunk/docs/manual/programs/other.html.en new file mode 100644 index 0000000000..a41a76331d --- /dev/null +++ b/trunk/docs/manual/programs/other.html.en @@ -0,0 +1,59 @@ + + + +Other Programs - Apache HTTP Server + + + + + +
    <-
    +

    Other Programs

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    The following programs are simple support programs included with the + Apache HTTP Server which do not have their own manual pages. They are not + installed automatically. You can find them after the configuration process + in the support/ directory.

    +
    + +
    top
    +
    +

    log_server_status

    +

    This perl script is designed to be run at a frequent interval by + something like cron. It connects to the server and downloads the status + information. It reformats the information to a single line and logs it to + a file. Adjust the variables at the top of the script to specify the + location of the resulting logfile.

    +
    top
    +
    +

    split-logfile

    +

    This perl script will take a combined Web server access log file and + break its contents into separate files. It assumes that the first field of + each line is the virtual host identity (put there by "%v"), and + that the logfiles should be named that + ".log" in the current + directory.

    + +

    The combined log file is read from stdin. Records read will be appended + to any existing log files.

    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/other.html.ko.euc-kr b/trunk/docs/manual/programs/other.html.ko.euc-kr new file mode 100644 index 0000000000..b8d5bbc4e7 --- /dev/null +++ b/trunk/docs/manual/programs/other.html.ko.euc-kr @@ -0,0 +1,57 @@ + + + +Other Programs - Apache HTTP Server + + + + + +
    <-
    +

    Other Programs

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + +

    ´ÙÀ½Àº °£´ÜÇÏ¿© manpage°¡ ¾ø´Â, ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ Æ÷ÇÔµÈ + Áö¿ø ÇÁ·Î±×·¥µéÀÌ´Ù. ÀÚµ¿À¸·Î À̵éÀ» ¼³Ä¡ÇÏÁö ¾Ê´Â´Ù. + ±¸¼º°úÁ¤ÈÄ support/ µð·ºÅ丮¿¡¼­ ÀÌ ÇÁ·Î±×·¥µéÀ» + ãÀ» ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    log_server_status

    +

    ÀÌ perl ½ºÅ©¸³Æ®´Â cron µî¿¡¼­ ÀÚÁÖ ½ÇÇàÇϵµ·Ï ¼³°èµÇ¾ú´Ù. + ÀÌ ½ºÅ©¸³Æ®¸¦ ¼­¹ö¿¡ ¿¬°áÇÏ¿© »óÅ Á¤º¸¸¦ ´Ù¿î·ÎµåÇÑ´Ù. + ±×·±ÈÄ ÀÌ Á¤º¸¸¦ ÇÑÁÙ·Î Á¤¸®ÇÏ¿© ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. ·Î±×ÆÄÀÏÀÇ + À§Ä¡¸¦ ÁöÁ¤ÇÏ·Á¸é ½ºÅ©¸³Æ® ¾ÕºÎºÐÀÇ º¯¼ö¸¦ ¼öÁ¤ÇÑ´Ù.

    +
    top
    +
    +

    split-logfile

    +

    ÀÌ perl ½ºÅ©¸³Æ®´Â °áÇÕµÈ À¥¼­¹ö Á¢±Ù·Î±×ÆÄÀÏÀÇ ³»¿ëÀ» + ¿©·¯ ÆÄÀÏ·Î ³ª´«´Ù. °¢ ÁÙÀÇ Ã¹¹ø° Ç׸ñÀÌ ("%v"·Î + Ãß°¡ÇÑ) °¡»óÈ£½ºÆ® Á¤º¸ÀÌ°í, ·Î±×ÆÄÀϸíÀº ÇöÀç µð·ºÅ丮¿¡ + °¡»óÈ£½ºÆ®¸í + ".log"¶ó°í °¡Á¤ÇÑ´Ù.

    + +

    °áÇÕµÈ ·Î±×ÆÄÀÏÀ» Ç¥ÁØÀÔ·ÂÀ¸·Î Àд´Ù. ÀÐÀº ³»¿ëÀ» ±âÁ¸ÀÇ + ·Î±×ÆÄÀϵ鿡 Ãß°¡ÇÑ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/other.xml b/trunk/docs/manual/programs/other.xml new file mode 100644 index 0000000000..8939827f36 --- /dev/null +++ b/trunk/docs/manual/programs/other.xml @@ -0,0 +1,54 @@ + + + + + + + + +Programs + +Other Programs + + +

    The following programs are simple support programs included with the + Apache HTTP Server which do not have their own manual pages. They are not + installed automatically. You can find them after the configuration process + in the support/ directory.

    +
    + +
    log_server_status +

    This perl script is designed to be run at a frequent interval by + something like cron. It connects to the server and downloads the status + information. It reformats the information to a single line and logs it to + a file. Adjust the variables at the top of the script to specify the + location of the resulting logfile.

    +
    + +
    split-logfile +

    This perl script will take a combined Web server access log file and + break its contents into separate files. It assumes that the first field of + each line is the virtual host identity (put there by "%v"), and + that the logfiles should be named that + ".log" in the current + directory.

    + +

    The combined log file is read from stdin. Records read will be appended + to any existing log files.

    +
    + +
    diff --git a/trunk/docs/manual/programs/other.xml.ko b/trunk/docs/manual/programs/other.xml.ko new file mode 100644 index 0000000000..1946f9e9be --- /dev/null +++ b/trunk/docs/manual/programs/other.xml.ko @@ -0,0 +1,52 @@ + + + + + + + + +Programs + +Other Programs + + +

    ´ÙÀ½Àº °£´ÜÇÏ¿© manpage°¡ ¾ø´Â, ¾ÆÆÄÄ¡ À¥¼­¹ö¿¡ Æ÷ÇÔµÈ + Áö¿ø ÇÁ·Î±×·¥µéÀÌ´Ù. ÀÚµ¿À¸·Î À̵éÀ» ¼³Ä¡ÇÏÁö ¾Ê´Â´Ù. + ±¸¼º°úÁ¤ÈÄ support/ µð·ºÅ丮¿¡¼­ ÀÌ ÇÁ·Î±×·¥µéÀ» + ãÀ» ¼ö ÀÖ´Ù.

    +
    + +
    log_server_status +

    ÀÌ perl ½ºÅ©¸³Æ®´Â cron µî¿¡¼­ ÀÚÁÖ ½ÇÇàÇϵµ·Ï ¼³°èµÇ¾ú´Ù. + ÀÌ ½ºÅ©¸³Æ®¸¦ ¼­¹ö¿¡ ¿¬°áÇÏ¿© »óÅ Á¤º¸¸¦ ´Ù¿î·ÎµåÇÑ´Ù. + ±×·±ÈÄ ÀÌ Á¤º¸¸¦ ÇÑÁÙ·Î Á¤¸®ÇÏ¿© ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. ·Î±×ÆÄÀÏÀÇ + À§Ä¡¸¦ ÁöÁ¤ÇÏ·Á¸é ½ºÅ©¸³Æ® ¾ÕºÎºÐÀÇ º¯¼ö¸¦ ¼öÁ¤ÇÑ´Ù.

    +
    + +
    split-logfile +

    ÀÌ perl ½ºÅ©¸³Æ®´Â °áÇÕµÈ À¥¼­¹ö Á¢±Ù·Î±×ÆÄÀÏÀÇ ³»¿ëÀ» + ¿©·¯ ÆÄÀÏ·Î ³ª´«´Ù. °¢ ÁÙÀÇ Ã¹¹ø° Ç׸ñÀÌ ("%v"·Î + Ãß°¡ÇÑ) °¡»óÈ£½ºÆ® Á¤º¸ÀÌ°í, ·Î±×ÆÄÀϸíÀº ÇöÀç µð·ºÅ丮¿¡ + °¡»óÈ£½ºÆ®¸í + ".log"¶ó°í °¡Á¤ÇÑ´Ù.

    + +

    °áÇÕµÈ ·Î±×ÆÄÀÏÀ» Ç¥ÁØÀÔ·ÂÀ¸·Î Àд´Ù. ÀÐÀº ³»¿ëÀ» ±âÁ¸ÀÇ + ·Î±×ÆÄÀϵ鿡 Ãß°¡ÇÑ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/programs/other.xml.meta b/trunk/docs/manual/programs/other.xml.meta new file mode 100644 index 0000000000..172b973c63 --- /dev/null +++ b/trunk/docs/manual/programs/other.xml.meta @@ -0,0 +1,12 @@ + + + + other + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/rotatelogs.html b/trunk/docs/manual/programs/rotatelogs.html new file mode 100644 index 0000000000..d4b500ffa0 --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.html @@ -0,0 +1,7 @@ +URI: rotatelogs.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: rotatelogs.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/rotatelogs.html.en b/trunk/docs/manual/programs/rotatelogs.html.en new file mode 100644 index 0000000000..c71d580941 --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.html.en @@ -0,0 +1,146 @@ + + + +rotatelogs - Piped logging program to rotate Apache logs - Apache HTTP Server + + + + + +
    <-
    +

    rotatelogs - Piped logging program to rotate Apache logs

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    rotatelogs is a simple program for use in + conjunction with Apache's piped logfile feature. For example:

    + +

    + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common +

    + +

    This creates the files /var/logs/logfile.nnnn where nnnn is + the system time at which the log nominally starts (this time + will always be a multiple of the rotation time, so you can + synchronize cron scripts with it). At the end of each rotation + time (here after 24 hours) a new log is started.

    + +

    + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common +

    + +

    This configuration will rotate the logfile whenever it reaches + a size of 5 megabytes.

    + +

    + ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" +

    +

    This configuration will rotate the error logfile whenever it + reaches a size of 5 megabytes, and the suffix to the logfile name + will be created of the form + errorlog.YYYY-mm-dd-HH_MM_SS.

    + +
    + +
    top
    +
    +

    Synopsis

    + +

    rotatelogs + [ -l ] + logfile + [ rotationtime [ offset ]] | + [ filesizeM ]

    +
    top
    +
    +

    Options

    + +
    + +
    -l
    +
    Causes the use of local time rather than GMT as the base for the +interval. Note that using -l in an environment which changes the +GMT offset (such as for BST or DST) can lead to unpredictable results!
    + +
    logfile
    + +
    The path plus basename of the logfile. If logfile +includes any '%' characters, it is treated as a format string for +strftime(3). Otherwise, the suffix +.nnnnnnnnnn is automatically added and is the time in +seconds. Both formats compute the start time from the beginning of +the current period.
    + +
    rotationtime
    + +
    The time between log file rotations in seconds.
    + +
    offset
    + +
    The number of minutes offset from UTC. If omitted, zero is +assumed and UTC is used. For example, to use local time in the zone +UTC -5 hours, specify a value of -300 for this argument.
    + +
    filesizeM
    + +
    The maximum file size in megabytes followed by the letter +M to specify size rather than time. Use this parameter +in place of both rotationtime and offset.
    +
    +
    top
    +
    +

    Portability

    + +

    The following logfile format string substitutions should be +supported by all strftime(3) implementations, see +the strftime(3) man page for library-specific +extensions.

    + + + + + + + + + + + + + + + + + + + + + + + +
    %Afull weekday name (localized)
    %a3-character weekday name (localized)
    %Bfull month name (localized)
    %b3-character month name (localized)
    %cdate and time (localized)
    %d2-digit day of month
    %H2-digit hour (24 hour clock)
    %I2-digit hour (12 hour clock)
    %j3-digit day of year
    %M2-digit minute
    %m2-digit month
    %pam/pm of 12 hour clock (localized)
    %S2-digit second
    %U2-digit week of year +(Sunday first day of week)
    %W2-digit week of year +(Monday first day of week)
    %w1-digit weekday +(Sunday first day of week)
    %Xtime (localized)
    %xdate (localized)
    %Y4-digit year
    %y2-digit year
    %Ztime zone name
    %%literal `%'
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/rotatelogs.html.ko.euc-kr b/trunk/docs/manual/programs/rotatelogs.html.ko.euc-kr new file mode 100644 index 0000000000..6a5b70820e --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.html.ko.euc-kr @@ -0,0 +1,143 @@ + + + +rotatelogs - ¾ÆÆÄÄ¡ ·Î±×¸¦ ¼øȯÇϱâÀ§ÇØ ÆÄÀÌÇÁ·Î ¿¬°áÇÒ + ·Î±× ÇÁ·Î±×·¥ - Apache HTTP Server + + + + + +
    <-
    +

    rotatelogs - ¾ÆÆÄÄ¡ ·Î±×¸¦ ¼øȯÇϱâÀ§ÇØ ÆÄÀÌÇÁ·Î ¿¬°áÇÒ + ·Î±× ÇÁ·Î±×·¥

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + +

    rotatelogs´Â ¾ÆÆÄÄ¡ÀÇ ÆÄÀÌÇÁ ·Î±×ÆÄÀÏ ±â´ÉÀ» + À§ÇÑ °£´ÜÇÑ ÇÁ·Î±×·¥ÀÌ´Ù. ¿¹¸¦ µé¾î:

    + +

    + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common +

    + +

    ±×·¯¸é /var/logs/logfile.nnnn ÆÄÀÏÀ» ¸¸µç´Ù. nnnnÀº + ·Î±×¸¦ ½ÃÀÛÇÑ ½Ã½ºÅ۽ð£ÀÌ´Ù (ÀÌ ½Ã°£Àº Ç×»ó ¼øȯ±â°£ÀÇ + ¹è¼öÀÌ´Ù. ±×·¡¼­ cron ½ºÅ©¸³Æ®·Î ó¸®Çϱ⠽±´Ù). ¼øȯ±â°£ + (¿©±â¼­´Â 24 ½Ã°£) ¸¶´Ù »õ·Î¿î ·Î±×¸¦ ½ÃÀÛÇÑ´Ù.

    + +

    + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common +

    + +

    ÀÌ ¼³Á¤Àº ·Î±×ÆÄÀÏ Å©±â°¡ 5 ¸Þ°¡¹ÙÀÌÆ®°¡ µÉ¶§¸¶´Ù + ¼øȯÇÑ´Ù.

    + +

    + ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" +

    +

    ÀÌ ¼³Á¤Àº ¿À·ù·Î±× ÆÄÀÏ Å©±â°¡ 5 ¸Þ°¡¹ÙÀÌÆ®°¡ µÉ¶§¸¶´Ù + errorlog.YYYY-mm-dd-HH_MM_SS¿Í °°Àº ÆÄÀÏÀ» + ¸¸µé¾î¼­ ¿À·ù·Î±× ÆÄÀÏÀ» ¼øȯÇÑ´Ù.

    + +
    + +
    top
    +
    +

    °³¿ä

    + +

    rotatelogs + [ -l ] + logfile + [ rotationtime [ offset ]] | + [ filesizeM ]

    +
    top
    +
    +

    ¿É¼Ç

    + +
    + +
    -l
    +
    ¼øȯÁÖ±â·Î GMT ´ë½Å Áö¿ª½Ã°£À» »ç¿ëÇÑ´Ù. (BST³ª DST¿Í °°ÀÌ) +GMT ½Ã°£Â÷°¡ º¯Çϴ ȯ°æ¿¡¼­ -lÀ» »ç¿ëÇÏ¸é ¿¹±âÄ¡ +¾ÊÀº °á°ú°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù!
    + +
    logfile
    + +
    ·Î±×ÆÄÀÏÀÇ °æ·Î¿Í À̸§. logfile¿¡ '%' ¹®ÀÚ°¡ +ÀÖ´Ù¸é strftime(3)ÀÇ Çü½Ä¹®ÀÚ¿­°ú °°ÀÌ Ã³¸®ÇÑ´Ù. +'%' ¹®ÀÚ°¡ ¾ø´Ù¸é µÚ¿¡ ÃÊ´ÜÀ§ ½Ã°£ .nnnnnnnnnnÀ» +ÀÚµ¿À¸·Î ºÙÀδÙ. µÎ Çü½Ä ¸ðµÎ ÇöÀç ±â°£ºÎÅÍ ½ÃÀ۽ð£À» °è»êÇÑ´Ù.
    + +
    rotationtime
    + +
    ·Î±×ÆÄÀÏÀ» ¼øȯÇÒ ÃÊ´ÜÀ§ ½Ã°£.
    + +
    offset
    + +
    UTC¿¡¼­ ºÐ´ÜÀ§ ½Ã°£Â÷ÀÌ. »ý·«Çϸé 0À¸·Î °¡Á¤ÇÏ¿© UTC¸¦ +»ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, UTC -5 ½Ã°£´ëÀÇ Áö¿ª½Ã°£À» »ç¿ëÇÑ´Ù¸é +¾Æ±Ô¸ÕÆ®·Î -300À» ÁöÁ¤ÇÑ´Ù.
    + +
    filesizeM
    + +
    ½Ã°£ÀÌ ¾Æ´Ñ Å©±â¸¦ ÁöÁ¤ÇÒ¶§ ¸Þ°¡¹ÙÀÌÆ®´ÜÀ§ ÃÖ´ë ÆÄÀÏÅ©±â +µÚ¿¡ MÀ» ºÙÀδÙ. rotationtime°ú offset ´ë½Å ÀÌ +ÆĶó¹ÌÅ͸¦ »ç¿ëÇÑ´Ù.
    +
    +
    top
    +
    +

    Æ÷Æð¡´É¼º

    + +

    ´ÙÀ½ ·Î±×ÆÄÀÏ Çü½Ä¹®ÀÚ¿­ Ç¥ÇöÀº ¸ðµç strftime(3) +±¸ÇöÀÌ Áö¿øÇØ¾ß ÇÑ´Ù. ¶óÀ̺귯¸® ƯÀ¯ÀÇ È®ÀåÀº +strftime(3) manpage¸¦ Âü°íÇ϶ó.

    + + + + + + + + + + + + + + + + + + + + + + + +
    %A(Áö¿ªÈ­µÈ) ¿ÏÀüÇÑ ¿äÀÏ À̸§
    %a(Áö¿ªÈ­µÈ) 3-¹®ÀÚ ¿äÀÏ À̸§
    %B(Áö¿ªÈ­µÈ) ¿ÏÀüÇÑ ´Þ À̸§
    %b(Áö¿ªÈ­µÈ) 3-¹®ÀÚ ´Þ À̸§
    %c(Áö¿ªÈ­µÈ) ³¯Â¥¿Í ½Ã°£
    %d2-ÀÚ¸® ÀÏ
    %H2-ÀÚ¸® ½Ã°£ (24 ½Ã°£ ½Ã°è)
    %I2-ÀÚ¸® ½Ã°£ (12 ½Ã°£ ½Ã°è)
    %j3-ÀÚ¸® ³¯Â¥¼ö
    %M2-ÀÚ¸® ºÐ
    %m2-ÀÚ¸® ´Þ
    %p(Áö¿ªÈ­µÈ) 12 ½Ã°£ ½Ã°èÀÇ am/pm
    %S2-ÀÚ¸® ÃÊ
    %U2-ÀÚ¸® ÁÖÀϼö (ÁÖÀÇ Ã¹¹øÀç ³¯Àº +ÀÏ¿äÀÏ)
    %W2-ÀÚ¸® ÁÖÀϼö (ÁÖÀÇ Ã¹¹øÀç ³¯Àº +¿ù¿äÀÏ)
    %w1-ÀÚ¸® ¿äÀϼö (ÁÖÀÇ Ã¹¹ø° ³¯Àº +ÀÏ¿äÀÏ)
    %X(Áö¿ªÈ­µÈ) ½Ã°£
    %x(Áö¿ªÈ­µÈ) ³¯Â¥
    %Y4-ÀÚ¸® ¿¬µµ
    %y2-ÀÚ¸® ¿¬µµ
    %Z½Ã°£´ë À̸§
    %%¹®ÀÚ±×´ë·Î `%'
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/rotatelogs.xml b/trunk/docs/manual/programs/rotatelogs.xml new file mode 100644 index 0000000000..d24268eb31 --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.xml @@ -0,0 +1,140 @@ + + + + + + + + +Programs + + rotatelogs - Piped logging program to rotate Apache logs + + +

    rotatelogs is a simple program for use in + conjunction with Apache's piped logfile feature. For example:

    + + + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common + + +

    This creates the files /var/logs/logfile.nnnn where nnnn is + the system time at which the log nominally starts (this time + will always be a multiple of the rotation time, so you can + synchronize cron scripts with it). At the end of each rotation + time (here after 24 hours) a new log is started.

    + + + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common + + +

    This configuration will rotate the logfile whenever it reaches + a size of 5 megabytes.

    + + + ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" + +

    This configuration will rotate the error logfile whenever it + reaches a size of 5 megabytes, and the suffix to the logfile name + will be created of the form + errorlog.YYYY-mm-dd-HH_MM_SS.

    + +
    + +
    Synopsis + +

    rotatelogs + [ -l ] + logfile + [ rotationtime [ offset ]] | + [ filesizeM ]

    +
    + +
    Options + +
    + +
    -l
    +
    Causes the use of local time rather than GMT as the base for the +interval. Note that using -l in an environment which changes the +GMT offset (such as for BST or DST) can lead to unpredictable results!
    + +
    logfile
    + +
    The path plus basename of the logfile. If logfile +includes any '%' characters, it is treated as a format string for +strftime(3). Otherwise, the suffix +.nnnnnnnnnn is automatically added and is the time in +seconds. Both formats compute the start time from the beginning of +the current period.
    + +
    rotationtime
    + +
    The time between log file rotations in seconds.
    + +
    offset
    + +
    The number of minutes offset from UTC. If omitted, zero is +assumed and UTC is used. For example, to use local time in the zone +UTC -5 hours, specify a value of -300 for this argument.
    + +
    filesizeM
    + +
    The maximum file size in megabytes followed by the letter +M to specify size rather than time. Use this parameter +in place of both rotationtime and offset.
    +
    +
    + +
    Portability + +

    The following logfile format string substitutions should be +supported by all strftime(3) implementations, see +the strftime(3) man page for library-specific +extensions.

    + + + + + + + + + + + + + + + + + + + + + + + + +
    %Afull weekday name (localized)
    %a3-character weekday name (localized)
    %Bfull month name (localized)
    %b3-character month name (localized)
    %cdate and time (localized)
    %d2-digit day of month
    %H2-digit hour (24 hour clock)
    %I2-digit hour (12 hour clock)
    %j3-digit day of year
    %M2-digit minute
    %m2-digit month
    %pam/pm of 12 hour clock (localized)
    %S2-digit second
    %U2-digit week of year +(Sunday first day of week)
    %W2-digit week of year +(Monday first day of week)
    %w1-digit weekday +(Sunday first day of week)
    %Xtime (localized)
    %xdate (localized)
    %Y4-digit year
    %y2-digit year
    %Ztime zone name
    %%literal `%'
    + +
    +
    diff --git a/trunk/docs/manual/programs/rotatelogs.xml.ko b/trunk/docs/manual/programs/rotatelogs.xml.ko new file mode 100644 index 0000000000..5b82753844 --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.xml.ko @@ -0,0 +1,136 @@ + + + + + + + + +Programs + + rotatelogs - ¾ÆÆÄÄ¡ ·Î±×¸¦ ¼øȯÇϱâÀ§ÇØ ÆÄÀÌÇÁ·Î ¿¬°áÇÒ + ·Î±× ÇÁ·Î±×·¥ + + +

    rotatelogs´Â ¾ÆÆÄÄ¡ÀÇ ÆÄÀÌÇÁ ·Î±×ÆÄÀÏ ±â´ÉÀ» + À§ÇÑ °£´ÜÇÑ ÇÁ·Î±×·¥ÀÌ´Ù. ¿¹¸¦ µé¾î:

    + + + CustomLog "|bin/rotatelogs /var/logs/logfile 86400" common + + +

    ±×·¯¸é /var/logs/logfile.nnnn ÆÄÀÏÀ» ¸¸µç´Ù. nnnnÀº + ·Î±×¸¦ ½ÃÀÛÇÑ ½Ã½ºÅ۽ð£ÀÌ´Ù (ÀÌ ½Ã°£Àº Ç×»ó ¼øȯ±â°£ÀÇ + ¹è¼öÀÌ´Ù. ±×·¡¼­ cron ½ºÅ©¸³Æ®·Î ó¸®Çϱ⠽±´Ù). ¼øȯ±â°£ + (¿©±â¼­´Â 24 ½Ã°£) ¸¶´Ù »õ·Î¿î ·Î±×¸¦ ½ÃÀÛÇÑ´Ù.

    + + + CustomLog "|bin/rotatelogs /var/logs/logfile 5M" common + + +

    ÀÌ ¼³Á¤Àº ·Î±×ÆÄÀÏ Å©±â°¡ 5 ¸Þ°¡¹ÙÀÌÆ®°¡ µÉ¶§¸¶´Ù + ¼øȯÇÑ´Ù.

    + + + ErrorLog "|bin/rotatelogs /var/logs/errorlog.%Y-%m-%d-%H_%M_%S 5M" + +

    ÀÌ ¼³Á¤Àº ¿À·ù·Î±× ÆÄÀÏ Å©±â°¡ 5 ¸Þ°¡¹ÙÀÌÆ®°¡ µÉ¶§¸¶´Ù + errorlog.YYYY-mm-dd-HH_MM_SS¿Í °°Àº ÆÄÀÏÀ» + ¸¸µé¾î¼­ ¿À·ù·Î±× ÆÄÀÏÀ» ¼øȯÇÑ´Ù.

    + +
    + +
    °³¿ä + +

    rotatelogs + [ -l ] + logfile + [ rotationtime [ offset ]] | + [ filesizeM ]

    +
    + +
    ¿É¼Ç + +
    + +
    -l
    +
    ¼øȯÁÖ±â·Î GMT ´ë½Å Áö¿ª½Ã°£À» »ç¿ëÇÑ´Ù. (BST³ª DST¿Í °°ÀÌ) +GMT ½Ã°£Â÷°¡ º¯Çϴ ȯ°æ¿¡¼­ -lÀ» »ç¿ëÇÏ¸é ¿¹±âÄ¡ +¾ÊÀº °á°ú°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù!
    + +
    logfile
    + +
    ·Î±×ÆÄÀÏÀÇ °æ·Î¿Í À̸§. logfile¿¡ '%' ¹®ÀÚ°¡ +ÀÖ´Ù¸é strftime(3)ÀÇ Çü½Ä¹®ÀÚ¿­°ú °°ÀÌ Ã³¸®ÇÑ´Ù. +'%' ¹®ÀÚ°¡ ¾ø´Ù¸é µÚ¿¡ ÃÊ´ÜÀ§ ½Ã°£ .nnnnnnnnnnÀ» +ÀÚµ¿À¸·Î ºÙÀδÙ. µÎ Çü½Ä ¸ðµÎ ÇöÀç ±â°£ºÎÅÍ ½ÃÀ۽ð£À» °è»êÇÑ´Ù.
    + +
    rotationtime
    + +
    ·Î±×ÆÄÀÏÀ» ¼øȯÇÒ ÃÊ´ÜÀ§ ½Ã°£.
    + +
    offset
    + +
    UTC¿¡¼­ ºÐ´ÜÀ§ ½Ã°£Â÷ÀÌ. »ý·«Çϸé 0À¸·Î °¡Á¤ÇÏ¿© UTC¸¦ +»ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, UTC -5 ½Ã°£´ëÀÇ Áö¿ª½Ã°£À» »ç¿ëÇÑ´Ù¸é +¾Æ±Ô¸ÕÆ®·Î -300À» ÁöÁ¤ÇÑ´Ù.
    + +
    filesizeM
    + +
    ½Ã°£ÀÌ ¾Æ´Ñ Å©±â¸¦ ÁöÁ¤ÇÒ¶§ ¸Þ°¡¹ÙÀÌÆ®´ÜÀ§ ÃÖ´ë ÆÄÀÏÅ©±â +µÚ¿¡ MÀ» ºÙÀδÙ. rotationtime°ú offset ´ë½Å ÀÌ +ÆĶó¹ÌÅ͸¦ »ç¿ëÇÑ´Ù.
    +
    +
    + +
    Æ÷Æð¡´É¼º + +

    ´ÙÀ½ ·Î±×ÆÄÀÏ Çü½Ä¹®ÀÚ¿­ Ç¥ÇöÀº ¸ðµç strftime(3) +±¸ÇöÀÌ Áö¿øÇØ¾ß ÇÑ´Ù. ¶óÀ̺귯¸® ƯÀ¯ÀÇ È®ÀåÀº +strftime(3) manpage¸¦ Âü°íÇ϶ó.

    + + + + + + + + + + + + + + + + + + + + + + + + +
    %A(Áö¿ªÈ­µÈ) ¿ÏÀüÇÑ ¿äÀÏ À̸§
    %a(Áö¿ªÈ­µÈ) 3-¹®ÀÚ ¿äÀÏ À̸§
    %B(Áö¿ªÈ­µÈ) ¿ÏÀüÇÑ ´Þ À̸§
    %b(Áö¿ªÈ­µÈ) 3-¹®ÀÚ ´Þ À̸§
    %c(Áö¿ªÈ­µÈ) ³¯Â¥¿Í ½Ã°£
    %d2-ÀÚ¸® ÀÏ
    %H2-ÀÚ¸® ½Ã°£ (24 ½Ã°£ ½Ã°è)
    %I2-ÀÚ¸® ½Ã°£ (12 ½Ã°£ ½Ã°è)
    %j3-ÀÚ¸® ³¯Â¥¼ö
    %M2-ÀÚ¸® ºÐ
    %m2-ÀÚ¸® ´Þ
    %p(Áö¿ªÈ­µÈ) 12 ½Ã°£ ½Ã°èÀÇ am/pm
    %S2-ÀÚ¸® ÃÊ
    %U2-ÀÚ¸® ÁÖÀϼö (ÁÖÀÇ Ã¹¹øÀç ³¯Àº +ÀÏ¿äÀÏ)
    %W2-ÀÚ¸® ÁÖÀϼö (ÁÖÀÇ Ã¹¹øÀç ³¯Àº +¿ù¿äÀÏ)
    %w1-ÀÚ¸® ¿äÀϼö (ÁÖÀÇ Ã¹¹ø° ³¯Àº +ÀÏ¿äÀÏ)
    %X(Áö¿ªÈ­µÈ) ½Ã°£
    %x(Áö¿ªÈ­µÈ) ³¯Â¥
    %Y4-ÀÚ¸® ¿¬µµ
    %y2-ÀÚ¸® ¿¬µµ
    %Z½Ã°£´ë À̸§
    %%¹®ÀÚ±×´ë·Î `%'
    + +
    +
    diff --git a/trunk/docs/manual/programs/rotatelogs.xml.meta b/trunk/docs/manual/programs/rotatelogs.xml.meta new file mode 100644 index 0000000000..6426888332 --- /dev/null +++ b/trunk/docs/manual/programs/rotatelogs.xml.meta @@ -0,0 +1,12 @@ + + + + rotatelogs + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/programs/suexec.html b/trunk/docs/manual/programs/suexec.html new file mode 100644 index 0000000000..f9408988ff --- /dev/null +++ b/trunk/docs/manual/programs/suexec.html @@ -0,0 +1,7 @@ +URI: suexec.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: suexec.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/programs/suexec.html.en b/trunk/docs/manual/programs/suexec.html.en new file mode 100644 index 0000000000..b40770f1c9 --- /dev/null +++ b/trunk/docs/manual/programs/suexec.html.en @@ -0,0 +1,61 @@ + + + +suexec - Switch user before executing external programs - Apache HTTP Server + + + + + +
    <-
    +

    suexec - Switch user before executing external programs

    +
    +

    Available Languages:  en  | + ko 

    +
    + +

    suexec is used by the Apache HTTP Server to switch + to another user before executing CGI programs. In order to achieve this, + it must run as root. Since the HTTP daemon normally doesn't + run as root, the suexec executable needs the + setuid bit set and must be owned by root. It should never be + writable for any other person than root.

    + +

    For further information about the concepts and and the security model + of suexec please refer to the suexec documentation (http://httpd.apache.org/docs-2.1/suexec.html).

    +
    + +
    top
    +
    +

    Synopsis

    +

    suexec -V

    +
    top
    +
    +

    Options

    + +
    +
    -V
    + +
    If you are root, this option displays the compile options of +suexec. For security reasons all configuration options are +changeable only at compile time.
    + +
    +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/suexec.html.ko.euc-kr b/trunk/docs/manual/programs/suexec.html.ko.euc-kr new file mode 100644 index 0000000000..3b3eb94bfc --- /dev/null +++ b/trunk/docs/manual/programs/suexec.html.ko.euc-kr @@ -0,0 +1,62 @@ + + + +suexec - ¿ÜºÎ ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ Àü¿¡ »ç¿ëÀÚ¸¦ º¯°æÇÑ´Ù - Apache HTTP Server + + + + + +
    <-
    +

    suexec - ¿ÜºÎ ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ Àü¿¡ »ç¿ëÀÚ¸¦ º¯°æÇÑ´Ù

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â CGI ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ Àü¿¡ ´Ù¸¥ »ç¿ëÀÚ·Î + ÀüȯÇϱâÀ§ÇØ suexec¸¦ »ç¿ëÇÑ´Ù. À̸¦ »ç¿ëÇÏ·Á¸é + ¼­¹ö¸¦ root °èÁ¤À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù. º¸Åë À¥ + µ¥¸óÀ» root °èÁ¤À¸·Î ½ÇÇàÇÏÁö ¾Ê±â¶§¹®¿¡ + suexec ½ÇÇàÆÄÀÏ¿¡ setuid ºñÆ®¸¦ ¼³Á¤ÇÏ°í + root°¡ ¼ÒÀ¯ÁÖÀ̾î¾ß ÇÑ´Ù. rootÀÌ¿ÜÀÇ + ´Ù¸¥ »ç¿ëÀÚ°¡ ¾²±â±ÇÇÑÀ» °¡Áö¸é ¾ÈµÈ´Ù.

    + +

    suexecÀÇ °³³ä°ú º¸¾È¸ðµ¨¿¡ ´ëÇÑ Á¤º¸´Â suexec ¹®¼­¸¦ + (http://httpd.apache.org/docs-2.1/suexec.html) Âü°íÇ϶ó.

    +
    + +
    top
    +
    +

    °³¿ä

    +

    suexec -V

    +
    top
    +
    +

    ¿É¼Ç

    + +
    +
    -V
    + +
    root°¡ ½ÇÇàÇϸé suexecÀÇ ÄÄÆÄÀÏ +¿É¼ÇÀ» Ãâ·ÂÇÑ´Ù. º¸¾È»ó ÀÌÀ¯·Î ¸ðµç ¼³Á¤¿É¼ÇÀº ÄÄÆÄÀÏÇÒ ¶§¸¸ +ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/programs/suexec.xml b/trunk/docs/manual/programs/suexec.xml new file mode 100644 index 0000000000..14649f1225 --- /dev/null +++ b/trunk/docs/manual/programs/suexec.xml @@ -0,0 +1,58 @@ + + + + + + + + +Programs + +suexec - Switch user before executing external programs + + +

    suexec is used by the Apache HTTP Server to switch + to another user before executing CGI programs. In order to achieve this, + it must run as root. Since the HTTP daemon normally doesn't + run as root, the suexec executable needs the + setuid bit set and must be owned by root. It should never be + writable for any other person than root.

    + +

    For further information about the concepts and and the security model + of suexec please refer to the suexec documentation (http://httpd.apache.org/docs-2.1/suexec.html).

    +
    + +
    Synopsis +

    suexec -V

    +
    + +
    Options + +
    +
    -V
    + +
    If you are root, this option displays the compile options of +suexec. For security reasons all configuration options are +changeable only at compile time.
    + +
    +
    + +
    diff --git a/trunk/docs/manual/programs/suexec.xml.ko b/trunk/docs/manual/programs/suexec.xml.ko new file mode 100644 index 0000000000..a0f198ba19 --- /dev/null +++ b/trunk/docs/manual/programs/suexec.xml.ko @@ -0,0 +1,58 @@ + + + + + + + + +Programs + +suexec - ¿ÜºÎ ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ Àü¿¡ »ç¿ëÀÚ¸¦ º¯°æÇÑ´Ù + + +

    ¾ÆÆÄÄ¡ À¥¼­¹ö´Â CGI ÇÁ·Î±×·¥À» ½ÇÇàÇϱâ Àü¿¡ ´Ù¸¥ »ç¿ëÀÚ·Î + ÀüȯÇϱâÀ§ÇØ suexec¸¦ »ç¿ëÇÑ´Ù. À̸¦ »ç¿ëÇÏ·Á¸é + ¼­¹ö¸¦ root °èÁ¤À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù. º¸Åë À¥ + µ¥¸óÀ» root °èÁ¤À¸·Î ½ÇÇàÇÏÁö ¾Ê±â¶§¹®¿¡ + suexec ½ÇÇàÆÄÀÏ¿¡ setuid ºñÆ®¸¦ ¼³Á¤ÇÏ°í + root°¡ ¼ÒÀ¯ÁÖÀ̾î¾ß ÇÑ´Ù. rootÀÌ¿ÜÀÇ + ´Ù¸¥ »ç¿ëÀÚ°¡ ¾²±â±ÇÇÑÀ» °¡Áö¸é ¾ÈµÈ´Ù.

    + +

    suexecÀÇ °³³ä°ú º¸¾È¸ðµ¨¿¡ ´ëÇÑ Á¤º¸´Â suexec ¹®¼­¸¦ + (http://httpd.apache.org/docs-2.1/suexec.html) Âü°íÇ϶ó.

    +
    + +
    °³¿ä +

    suexec -V

    +
    + +
    ¿É¼Ç + +
    +
    -V
    + +
    root°¡ ½ÇÇàÇϸé suexecÀÇ ÄÄÆÄÀÏ +¿É¼ÇÀ» Ãâ·ÂÇÑ´Ù. º¸¾È»ó ÀÌÀ¯·Î ¸ðµç ¼³Á¤¿É¼ÇÀº ÄÄÆÄÀÏÇÒ ¶§¸¸ +ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù.
    + +
    +
    + +
    diff --git a/trunk/docs/manual/programs/suexec.xml.meta b/trunk/docs/manual/programs/suexec.xml.meta new file mode 100644 index 0000000000..6e2dd4fe0c --- /dev/null +++ b/trunk/docs/manual/programs/suexec.xml.meta @@ -0,0 +1,12 @@ + + + + suexec + /programs/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/rewrite/index.html b/trunk/docs/manual/rewrite/index.html new file mode 100644 index 0000000000..5f97bff8c6 --- /dev/null +++ b/trunk/docs/manual/rewrite/index.html @@ -0,0 +1,3 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/rewrite/index.html.en b/trunk/docs/manual/rewrite/index.html.en new file mode 100644 index 0000000000..103f0307d4 --- /dev/null +++ b/trunk/docs/manual/rewrite/index.html.en @@ -0,0 +1,96 @@ + + + +Apache mod_rewrite - Apache HTTP Server + + + + + +
    <-
    +

    Apache mod_rewrite

    +
    +

    Available Languages:  en 

    +
    + +
    +

    ``The great thing about mod_rewrite is it gives you + all the configurability and flexibility of Sendmail. + The downside to mod_rewrite is that it gives you all + the configurability and flexibility of Sendmail.''

    + +

    -- Brian Behlendorf
    + Apache Group

    + +
    + +
    +

    `` Despite the tons of examples and docs, + mod_rewrite is voodoo. Damned cool voodoo, but still + voodoo. ''

    + +

    -- Brian Moore
    + bem@news.cmc.net

    + +
    + +

    Welcome to mod_rewrite, the Swiss Army Knife of URL + manipulation!

    + +

    This module uses a rule-based rewriting engine (based on a + regular-expression parser) to rewrite requested URLs on the + fly. It supports an unlimited number of rules and an + unlimited number of attached rule conditions for each rule to + provide a really flexible and powerful URL manipulation + mechanism. The URL manipulations can depend on various tests, + for instance server variables, environment variables, HTTP + headers, time stamps and even external database lookups in + various formats can be used to achieve granular URL + matching.

    + +

    This module operates on the full URLs (including the + path-info part) both in per-server context + (httpd.conf) and per-directory context + (.htaccess) and can even generate query-string + parts on result. The rewritten result can lead to internal + sub-processing, external request redirection or even to an + internal proxy throughput.

    + +

    But all this functionality and flexibility has its + drawback: complexity. So don't expect to understand this + entire module in just one day.

    + +
    + +
    top
    +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/rewrite/index.xml b/trunk/docs/manual/rewrite/index.xml new file mode 100644 index 0000000000..fb66cfa683 --- /dev/null +++ b/trunk/docs/manual/rewrite/index.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + Apache mod_rewrite + + +
    +

    ``The great thing about mod_rewrite is it gives you + all the configurability and flexibility of Sendmail. + The downside to mod_rewrite is that it gives you all + the configurability and flexibility of Sendmail.''

    + +

    -- Brian Behlendorf
    + Apache Group

    + +
    + +
    +

    `` Despite the tons of examples and docs, + mod_rewrite is voodoo. Damned cool voodoo, but still + voodoo. ''

    + +

    -- Brian Moore
    + bem@news.cmc.net

    + +
    + +

    Welcome to mod_rewrite, the Swiss Army Knife of URL + manipulation!

    + +

    This module uses a rule-based rewriting engine (based on a + regular-expression parser) to rewrite requested URLs on the + fly. It supports an unlimited number of rules and an + unlimited number of attached rule conditions for each rule to + provide a really flexible and powerful URL manipulation + mechanism. The URL manipulations can depend on various tests, + for instance server variables, environment variables, HTTP + headers, time stamps and even external database lookups in + various formats can be used to achieve granular URL + matching.

    + +

    This module operates on the full URLs (including the + path-info part) both in per-server context + (httpd.conf) and per-directory context + (.htaccess) and can even generate query-string + parts on result. The rewritten result can lead to internal + sub-processing, external request redirection or even to an + internal proxy throughput.

    + +

    But all this functionality and flexibility has its + drawback: complexity. So don't expect to understand this + entire module in just one day.

    + +
    + +mod_rewrite reference +documentation +Introduction +Technical details +Practical solutions to common +problems +Practical solutions to +advanced problems + +
    Documentation + +
    + +
    + + diff --git a/trunk/docs/manual/rewrite/index.xml.meta b/trunk/docs/manual/rewrite/index.xml.meta new file mode 100644 index 0000000000..dd496b6d2c --- /dev/null +++ b/trunk/docs/manual/rewrite/index.xml.meta @@ -0,0 +1,11 @@ + + + + index + /rewrite/ + .. + + + en + + diff --git a/trunk/docs/manual/rewrite/rewrite_guide.html b/trunk/docs/manual/rewrite/rewrite_guide.html new file mode 100644 index 0000000000..49f623e98f --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide.html @@ -0,0 +1,3 @@ +URI: rewrite_guide.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/rewrite/rewrite_guide.html.en b/trunk/docs/manual/rewrite/rewrite_guide.html.en new file mode 100644 index 0000000000..baca86e90d --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide.html.en @@ -0,0 +1,789 @@ + + + +URL Rewriting Guide - Apache HTTP Server + + + + + +
    <-
    +

    URL Rewriting Guide

    +
    +

    Available Languages:  en 

    +
    + + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonony confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + +
    ATTENTION: Depending on your server configuration + it may be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. This + avoids many problems.
    + +
    + +
    top
    +
    +

    Canonical URLs

    + + + +
    +
    Description:
    + +
    +

    On some webservers there are more than one URL for a + resource. Usually there are canonical URLs (which should be + actually used and distributed) and those which are just + shortcuts, internal ones, etc. Independent of which URL the + user supplied with the request he should finally see the + canonical one only.

    +
    + +
    Solution:
    + +
    +

    We do an external HTTP redirect for all non-canonical + URLs to fix them in the location view of the Browser and + for all subsequent requests. In the example ruleset below + we replace /~user by the canonical + /u/user and fix a missing trailing slash for + /u/user.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + +
    top
    +
    +

    Canonical Hostnames

    + +
    +
    Description:
    + +
    The goal of this rule is to force the use of a particular + hostname, in preference to other hostnames which may be used to + reach the same site. For example, if you wish to force the use + of www.example.com instead of + example.com, you might use a variant of the + following recipe.
    + +
    Solution:
    + +
    +

    For sites running on a port other than 80:

    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +
    + +

    And for a site running on port 80

    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + +
    top
    +
    +

    Moved DocumentRoot

    + + + +
    +
    Description:
    + +
    +

    Usually the DocumentRoot +of the webserver directly relates to the URL "/". +But often this data is not really of top-level priority. For example, +you may wish for visitors, on first entering a site, to go to a +particular subdirectory /about/. This may be accomplished +using the following ruleset:

    +
    + +
    Solution:
    + +
    +

    We redirect the URL / to + /about/: +

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /about/  [R]
    +
    + +

    Note that this can also be handled using the RedirectMatch directive:

    + +

    +RedirectMatch ^/$ http://example.com/e/www/ +

    +
    +
    + +
    top
    +
    +

    Trailing Slash Problem

    + + + +
    +
    Description:
    + +

    The vast majority of "trailing slash" problems can be dealt + with using the techniques discussed in the FAQ + entry. However, occasionally, there is a need to use mod_rewrite + to handle a case where a missing trailing slash causes a URL to + fail. This can happen, for example, after a series of complex + rewrite rules.

    +
    + +
    Solution:
    + +
    +

    The solution to this subtle problem is to let the server + add the trailing slash automatically. To do this + correctly we have to use an external redirect, so the + browser correctly requests subsequent images etc. If we + only did a internal rewrite, this would only work for the + directory page, but would go wrong when any images are + included into this page with relative URLs, because the + browser would request an in-lined object. For instance, a + request for image.gif in + /~quux/foo/index.html would become + /~quux/image.gif without the external + redirect!

    + +

    So, to do this trick we write:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    Alternately, you can put the following in a + top-level .htaccess file in the content directory. + But note that this creates some processing overhead.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + +
    top
    +
    +

    Move Homedirs to Different Webserver

    + + + +
    +
    Description:
    + +
    +

    Many webmasters have asked for a solution to the + following situation: They wanted to redirect just all + homedirs on a webserver to another webserver. They usually + need such things when establishing a newer webserver which + will replace the old one over time.

    +
    + +
    Solution:
    + +
    +

    The solution is trivial with mod_rewrite. + On the old webserver we just redirect all + /~user/anypath URLs to + http://newserver/~user/anypath.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + +
    top
    +
    +

    Search pages in more than one directory

    + + + +
    +
    Description:
    + +
    +

    Sometimes it is necessary to let the webserver search + for pages in more than one directory. Here MultiViews or + other techniques cannot help.

    +
    + +
    Solution:
    + +
    +

    We program a explicit ruleset which searches for the + files in the directories.

    + +
    +RewriteEngine on
    +
    +#   first try to find it in custom/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   second try to find it in pub/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   else go on for other Alias or ScriptAlias directives,
    +#   etc.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + +
    top
    +
    +

    Set Environment Variables According To URL Parts

    + + + +
    +
    Description:
    + +
    +

    Perhaps you want to keep status information between + requests and use the URL to encode it. But you don't want + to use a CGI wrapper for all pages just to strip out this + information.

    +
    + +
    Solution:
    + +
    +

    We use a rewrite rule to strip out the status information + and remember it via an environment variable which can be + later dereferenced from within XSSI or CGI. This way a + URL /foo/S=java/bar/ gets translated to + /foo/bar/ and the environment variable named + STATUS is set to the value "java".

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + +
    top
    +
    +

    Virtual User Hosts

    + + + +
    +
    Description:
    + +
    +

    Assume that you want to provide + www.username.host.domain.com + for the homepage of username via just DNS A records to the + same machine and without any virtualhosts on this + machine.

    +
    + +
    Solution:
    + +
    +

    For HTTP/1.0 requests there is no solution, but for + HTTP/1.1 requests which contain a Host: HTTP header we + can use the following ruleset to rewrite + http://www.username.host.com/anypath + internally to /home/username/anypath:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + +
    top
    +
    +

    Redirect Homedirs For Foreigners

    + + + +
    +
    Description:
    + +
    +

    We want to redirect homedir URLs to another webserver + www.somewhere.com when the requesting user + does not stay in the local domain + ourdomain.com. This is sometimes used in + virtual host contexts.

    +
    + +
    Solution:
    + +
    +

    Just a rewrite condition:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + +
    top
    +
    +

    Redirecting Anchors

    + + + +
    +
    Description:
    + +
    +

    By default, redirecting to an HTML anchor doesn't work, + because mod_rewrite escapes the # character, + turning it into %23. This, in turn, breaks the + redirection.

    +
    + +
    Solution:
    + +
    +

    Use the [NE] flag on the + RewriteRule. NE stands for No Escape. +

    +
    +
    + +
    top
    +
    +

    Time-Dependent Rewriting

    + + + +
    +
    Description:
    + +
    +

    When tricks like time-dependent content should happen a + lot of webmasters still use CGI scripts which do for + instance redirects to specialized pages. How can it be done + via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    There are a lot of variables named TIME_xxx + for rewrite conditions. In conjunction with the special + lexicographic comparison patterns <STRING, + >STRING and =STRING we can + do time-dependent redirects:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    This provides the content of foo.day.html + under the URL foo.html from + 07:00-19:00 and at the remaining time the + contents of foo.night.html. Just a nice + feature for a homepage...

    +
    +
    + +
    top
    +
    +

    Backward Compatibility for YYYY to XXXX migration

    + + + +
    +
    Description:
    + +
    +

    How can we make URLs backward compatible (still + existing virtually) after migrating document.YYYY + to document.XXXX, e.g. after translating a + bunch of .html files to .phtml?

    +
    + +
    Solution:
    + +
    +

    We just rewrite the name to its basename and test for + existence of the new extension. If it exists, we take + that name, else we rewrite the URL to its original state.

    + + +
    +#   backward compatibility ruleset for
    +#   rewriting document.html to document.phtml
    +#   when and only when document.phtml exists
    +#   but no longer document.html
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   parse out basename, but remember the fact
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   rewrite to document.phtml if exists
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   else reverse the previous basename cutout
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + +
    top
    +
    +

    Content Handling

    + + + +

    From Old to New (intern)

    + + + +
    +
    Description:
    + +
    +

    Assume we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. Actually + we want that users of the old URL even not recognize that + the pages was renamed.

    +
    + +
    Solution:
    + +
    +

    We rewrite the old URL to the new one internally via the + following rule:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + + + +

    From Old to New (extern)

    + + + +
    +
    Description:
    + +
    +

    Assume again that we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. But this + time we want that the users of the old URL get hinted to + the new one, i.e. their browsers Location field should + change, too.

    +
    + +
    Solution:
    + +
    +

    We force a HTTP redirect to the new URL which leads to a + change of the browsers and thus the users view:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + + + +

    From Static to Dynamic

    + + + +
    +
    Description:
    + +
    +

    How can we transform a static page + foo.html into a dynamic variant + foo.cgi in a seamless way, i.e. without notice + by the browser/user.

    +
    + +
    Solution:
    + +
    +

    We just rewrite the URL to the CGI-script and force the + correct MIME-type so it gets really run as a CGI-script. + This way a request to /~quux/foo.html + internally leads to the invocation of + /~quux/foo.cgi.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + + +
    top
    +
    +

    Access Restriction

    + + + +

    Blocking of Robots

    + + + +
    +
    Description:
    + +
    +

    How can we block a really annoying robot from + retrieving pages of a specific webarea? A + /robots.txt file containing entries of the + "Robot Exclusion Protocol" is typically not enough to get + rid of such a robot.

    +
    + +
    Solution:
    + +
    +

    We use a ruleset which forbids the URLs of the webarea + /~quux/foo/arc/ (perhaps a very deep + directory indexed area where the robot traversal would + create big server load). We have to make sure that we + forbid access only to the particular robot, i.e. just + forbidding the host where the robot runs is not enough. + This would block users from this host, too. We accomplish + this by also matching the User-Agent HTTP header + information.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + + + +

    Blocked Inline-Images

    + + + +
    +
    Description:
    + +
    +

    Assume we have under http://www.quux-corp.de/~quux/ + some pages with inlined GIF graphics. These graphics are + nice, so others directly incorporate them via hyperlinks to + their pages. We don't like this practice because it adds + useless traffic to our server.

    +
    + +
    Solution:
    + +
    +

    While we cannot 100% protect the images from inclusion, + we can at least restrict the cases where the browser + sends a HTTP Referer header.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + + + +

    Proxy Deny

    + + + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + + + +
    top
    +
    +

    Other

    + + + +

    External Rewriting Engine

    + + + +
    +
    Description:
    + +
    +

    A FAQ: How can we solve the FOO/BAR/QUUX/etc. + problem? There seems no solution by the use of + mod_rewrite...

    +
    + +
    Solution:
    + +
    +

    Use an external RewriteMap, i.e. a program which acts + like a RewriteMap. It is run once on startup of Apache + receives the requested URLs on STDIN and has + to put the resulting (usually rewritten) URL on + STDOUT (same order!).

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   disable buffered I/O which would lead
    +#   to deadloops for the Apache server
    +$| = 1;
    +
    +#   read URLs one per line from stdin and
    +#   generate substitution URL on stdout
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    This is a demonstration-only example and just rewrites + all URLs /~quux/foo/... to + /~quux/bar/.... Actually you can program + whatever you like. But notice that while such maps can be + used also by an average user, only the + system administrator can define it.

    +
    +
    + + + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/rewrite/rewrite_guide.xml b/trunk/docs/manual/rewrite/rewrite_guide.xml new file mode 100644 index 0000000000..85aae9728a --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide.xml @@ -0,0 +1,783 @@ + + + + + + + + + + + URL Rewriting Guide + + + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonony confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + + ATTENTION: Depending on your server configuration + it may be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. This + avoids many problems. + +
    +Module +documentation +mod_rewrite +introduction +Practical solutions to +advanced problems +Technical details + + +
    + +Canonical URLs + +
    +
    Description:
    + +
    +

    On some webservers there are more than one URL for a + resource. Usually there are canonical URLs (which should be + actually used and distributed) and those which are just + shortcuts, internal ones, etc. Independent of which URL the + user supplied with the request he should finally see the + canonical one only.

    +
    + +
    Solution:
    + +
    +

    We do an external HTTP redirect for all non-canonical + URLs to fix them in the location view of the Browser and + for all subsequent requests. In the example ruleset below + we replace /~user by the canonical + /u/user and fix a missing trailing slash for + /u/user.

    + +
    +RewriteRule   ^/~([^/]+)/?(.*)    /u/$1/$2  [R]
    +RewriteRule   ^/([uge])/([^/]+)$  /$1/$2/   [R]
    +
    +
    +
    + +
    + +
    Canonical Hostnames + +
    +
    Description:
    + +
    The goal of this rule is to force the use of a particular + hostname, in preference to other hostnames which may be used to + reach the same site. For example, if you wish to force the use + of www.example.com instead of + example.com, you might use a variant of the + following recipe.
    + +
    Solution:
    + +
    +

    For sites running on a port other than 80:

    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteCond %{SERVER_PORT} !^80$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name:%{SERVER_PORT}/$1 [L,R]
    +
    + +

    And for a site running on port 80

    +
    +RewriteCond %{HTTP_HOST}   !^fully\.qualified\.domain\.name [NC]
    +RewriteCond %{HTTP_HOST}   !^$
    +RewriteRule ^/(.*)         http://fully.qualified.domain.name/$1 [L,R]
    +
    +
    +
    + +
    + +
    + + Moved <code>DocumentRoot</code> + +
    +
    Description:
    + +
    +

    Usually the DocumentRoot +of the webserver directly relates to the URL "/". +But often this data is not really of top-level priority. For example, +you may wish for visitors, on first entering a site, to go to a +particular subdirectory /about/. This may be accomplished +using the following ruleset:

    +
    + +
    Solution:
    + +
    +

    We redirect the URL / to + /about/: +

    + +
    +RewriteEngine on
    +RewriteRule   ^/$  /about/  [R]
    +
    + +

    Note that this can also be handled using the RedirectMatch directive:

    + + +RedirectMatch ^/$ http://example.com/e/www/ + +
    +
    + +
    + +
    + + Trailing Slash Problem + +
    +
    Description:
    + +

    The vast majority of "trailing slash" problems can be dealt + with using the techniques discussed in the FAQ + entry. However, occasionally, there is a need to use mod_rewrite + to handle a case where a missing trailing slash causes a URL to + fail. This can happen, for example, after a series of complex + rewrite rules.

    +
    + +
    Solution:
    + +
    +

    The solution to this subtle problem is to let the server + add the trailing slash automatically. To do this + correctly we have to use an external redirect, so the + browser correctly requests subsequent images etc. If we + only did a internal rewrite, this would only work for the + directory page, but would go wrong when any images are + included into this page with relative URLs, because the + browser would request an in-lined object. For instance, a + request for image.gif in + /~quux/foo/index.html would become + /~quux/image.gif without the external + redirect!

    + +

    So, to do this trick we write:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo$  foo/  [R]
    +
    + +

    Alternately, you can put the following in a + top-level .htaccess file in the content directory. + But note that this creates some processing overhead.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteCond    %{REQUEST_FILENAME}  -d
    +RewriteRule    ^(.+[^/])$           $1/  [R]
    +
    +
    +
    + +
    + +
    + + Move Homedirs to Different Webserver + +
    +
    Description:
    + +
    +

    Many webmasters have asked for a solution to the + following situation: They wanted to redirect just all + homedirs on a webserver to another webserver. They usually + need such things when establishing a newer webserver which + will replace the old one over time.

    +
    + +
    Solution:
    + +
    +

    The solution is trivial with mod_rewrite. + On the old webserver we just redirect all + /~user/anypath URLs to + http://newserver/~user/anypath.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(.+)  http://newserver/~$1  [R,L]
    +
    +
    +
    + +
    + +
    + + Search pages in more than one directory + +
    +
    Description:
    + +
    +

    Sometimes it is necessary to let the webserver search + for pages in more than one directory. Here MultiViews or + other techniques cannot help.

    +
    + +
    Solution:
    + +
    +

    We program a explicit ruleset which searches for the + files in the directories.

    + +
    +RewriteEngine on
    +
    +#   first try to find it in custom/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir1/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir1/$1  [L]
    +
    +#   second try to find it in pub/...
    +#   ...and if found stop and be happy:
    +RewriteCond         /your/docroot/dir2/%{REQUEST_FILENAME}  -f
    +RewriteRule  ^(.+)  /your/docroot/dir2/$1  [L]
    +
    +#   else go on for other Alias or ScriptAlias directives,
    +#   etc.
    +RewriteRule   ^(.+)  -  [PT]
    +
    +
    +
    + +
    + +
    + + Set Environment Variables According To URL Parts + +
    +
    Description:
    + +
    +

    Perhaps you want to keep status information between + requests and use the URL to encode it. But you don't want + to use a CGI wrapper for all pages just to strip out this + information.

    +
    + +
    Solution:
    + +
    +

    We use a rewrite rule to strip out the status information + and remember it via an environment variable which can be + later dereferenced from within XSSI or CGI. This way a + URL /foo/S=java/bar/ gets translated to + /foo/bar/ and the environment variable named + STATUS is set to the value "java".

    + +
    +RewriteEngine on
    +RewriteRule   ^(.*)/S=([^/]+)/(.*)    $1/$3 [E=STATUS:$2]
    +
    +
    +
    + +
    + +
    + + Virtual User Hosts + +
    +
    Description:
    + +
    +

    Assume that you want to provide + www.username.host.domain.com + for the homepage of username via just DNS A records to the + same machine and without any virtualhosts on this + machine.

    +
    + +
    Solution:
    + +
    +

    For HTTP/1.0 requests there is no solution, but for + HTTP/1.1 requests which contain a Host: HTTP header we + can use the following ruleset to rewrite + http://www.username.host.com/anypath + internally to /home/username/anypath:

    + +
    +RewriteEngine on
    +RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
    +RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
    +RewriteRule   ^www\.([^.]+)\.host\.com(.*) /home/$1$2
    +
    +
    +
    + +
    + +
    + + Redirect Homedirs For Foreigners + +
    +
    Description:
    + +
    +

    We want to redirect homedir URLs to another webserver + www.somewhere.com when the requesting user + does not stay in the local domain + ourdomain.com. This is sometimes used in + virtual host contexts.

    +
    + +
    Solution:
    + +
    +

    Just a rewrite condition:

    + +
    +RewriteEngine on
    +RewriteCond   %{REMOTE_HOST}  !^.+\.ourdomain\.com$
    +RewriteRule   ^(/~.+)         http://www.somewhere.com/$1 [R,L]
    +
    +
    +
    + +
    + +
    + + Redirecting Anchors + +
    +
    Description:
    + +
    +

    By default, redirecting to an HTML anchor doesn't work, + because mod_rewrite escapes the # character, + turning it into %23. This, in turn, breaks the + redirection.

    +
    + +
    Solution:
    + +
    +

    Use the [NE] flag on the + RewriteRule. NE stands for No Escape. +

    +
    +
    + +
    + +
    + + Time-Dependent Rewriting + +
    +
    Description:
    + +
    +

    When tricks like time-dependent content should happen a + lot of webmasters still use CGI scripts which do for + instance redirects to specialized pages. How can it be done + via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    There are a lot of variables named TIME_xxx + for rewrite conditions. In conjunction with the special + lexicographic comparison patterns <STRING, + >STRING and =STRING we can + do time-dependent redirects:

    + +
    +RewriteEngine on
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
    +RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
    +RewriteRule   ^foo\.html$             foo.day.html
    +RewriteRule   ^foo\.html$             foo.night.html
    +
    + +

    This provides the content of foo.day.html + under the URL foo.html from + 07:00-19:00 and at the remaining time the + contents of foo.night.html. Just a nice + feature for a homepage...

    +
    +
    + +
    + +
    + + Backward Compatibility for YYYY to XXXX migration + +
    +
    Description:
    + +
    +

    How can we make URLs backward compatible (still + existing virtually) after migrating document.YYYY + to document.XXXX, e.g. after translating a + bunch of .html files to .phtml?

    +
    + +
    Solution:
    + +
    +

    We just rewrite the name to its basename and test for + existence of the new extension. If it exists, we take + that name, else we rewrite the URL to its original state.

    + + +
    +#   backward compatibility ruleset for
    +#   rewriting document.html to document.phtml
    +#   when and only when document.phtml exists
    +#   but no longer document.html
    +RewriteEngine on
    +RewriteBase   /~quux/
    +#   parse out basename, but remember the fact
    +RewriteRule   ^(.*)\.html$              $1      [C,E=WasHTML:yes]
    +#   rewrite to document.phtml if exists
    +RewriteCond   %{REQUEST_FILENAME}.phtml -f
    +RewriteRule   ^(.*)$ $1.phtml                   [S=1]
    +#   else reverse the previous basename cutout
    +RewriteCond   %{ENV:WasHTML}            ^yes$
    +RewriteRule   ^(.*)$ $1.html
    +
    +
    +
    + +
    + +
    + + Content Handling + +
    + + From Old to New (intern) + +
    +
    Description:
    + +
    +

    Assume we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. Actually + we want that users of the old URL even not recognize that + the pages was renamed.

    +
    + +
    Solution:
    + +
    +

    We rewrite the old URL to the new one internally via the + following rule:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html
    +
    +
    +
    + +
    + +
    + + From Old to New (extern) + +
    +
    Description:
    + +
    +

    Assume again that we have recently renamed the page + foo.html to bar.html and now want + to provide the old URL for backward compatibility. But this + time we want that the users of the old URL get hinted to + the new one, i.e. their browsers Location field should + change, too.

    +
    + +
    Solution:
    + +
    +

    We force a HTTP redirect to the new URL which leads to a + change of the browsers and thus the users view:

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  bar.html  [R]
    +
    +
    +
    + +
    + +
    + + From Static to Dynamic + +
    +
    Description:
    + +
    +

    How can we transform a static page + foo.html into a dynamic variant + foo.cgi in a seamless way, i.e. without notice + by the browser/user.

    +
    + +
    Solution:
    + +
    +

    We just rewrite the URL to the CGI-script and force the + correct MIME-type so it gets really run as a CGI-script. + This way a request to /~quux/foo.html + internally leads to the invocation of + /~quux/foo.cgi.

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^foo\.html$  foo.cgi  [T=application/x-httpd-cgi]
    +
    +
    +
    + +
    +
    + +
    + + Access Restriction + +
    + + Blocking of Robots + +
    +
    Description:
    + +
    +

    How can we block a really annoying robot from + retrieving pages of a specific webarea? A + /robots.txt file containing entries of the + "Robot Exclusion Protocol" is typically not enough to get + rid of such a robot.

    +
    + +
    Solution:
    + +
    +

    We use a ruleset which forbids the URLs of the webarea + /~quux/foo/arc/ (perhaps a very deep + directory indexed area where the robot traversal would + create big server load). We have to make sure that we + forbid access only to the particular robot, i.e. just + forbidding the host where the robot runs is not enough. + This would block users from this host, too. We accomplish + this by also matching the User-Agent HTTP header + information.

    + +
    +RewriteCond %{HTTP_USER_AGENT}   ^NameOfBadRobot.*
    +RewriteCond %{REMOTE_ADDR}       ^123\.45\.67\.[8-9]$
    +RewriteRule ^/~quux/foo/arc/.+   -   [F]
    +
    +
    +
    + +
    + +
    + + Blocked Inline-Images + +
    +
    Description:
    + +
    +

    Assume we have under http://www.quux-corp.de/~quux/ + some pages with inlined GIF graphics. These graphics are + nice, so others directly incorporate them via hyperlinks to + their pages. We don't like this practice because it adds + useless traffic to our server.

    +
    + +
    Solution:
    + +
    +

    While we cannot 100% protect the images from inclusion, + we can at least restrict the cases where the browser + sends a HTTP Referer header.

    + +
    +RewriteCond %{HTTP_REFERER} !^$
    +RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
    +RewriteRule .*\.gif$        -                                    [F]
    +
    + +
    +RewriteCond %{HTTP_REFERER}         !^$
    +RewriteCond %{HTTP_REFERER}         !.*/foo-with-gif\.html$
    +RewriteRule ^inlined-in-foo\.gif$   -                        [F]
    +
    +
    +
    + +
    + +
    + + Proxy Deny + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + +
    + +
    + +
    + + Other + +
    + + External Rewriting Engine + +
    +
    Description:
    + +
    +

    A FAQ: How can we solve the FOO/BAR/QUUX/etc. + problem? There seems no solution by the use of + mod_rewrite...

    +
    + +
    Solution:
    + +
    +

    Use an external RewriteMap, i.e. a program which acts + like a RewriteMap. It is run once on startup of Apache + receives the requested URLs on STDIN and has + to put the resulting (usually rewritten) URL on + STDOUT (same order!).

    + +
    +RewriteEngine on
    +RewriteMap    quux-map       prg:/path/to/map.quux.pl
    +RewriteRule   ^/~quux/(.*)$  /~quux/${quux-map:$1}
    +
    + +
    +#!/path/to/perl
    +
    +#   disable buffered I/O which would lead
    +#   to deadloops for the Apache server
    +$| = 1;
    +
    +#   read URLs one per line from stdin and
    +#   generate substitution URL on stdout
    +while (<>) {
    +    s|^foo/|bar/|;
    +    print $_;
    +}
    +
    + +

    This is a demonstration-only example and just rewrites + all URLs /~quux/foo/... to + /~quux/bar/.... Actually you can program + whatever you like. But notice that while such maps can be + used also by an average user, only the + system administrator can define it.

    +
    +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/rewrite/rewrite_guide.xml.meta b/trunk/docs/manual/rewrite/rewrite_guide.xml.meta new file mode 100644 index 0000000000..65639c1a25 --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide.xml.meta @@ -0,0 +1,11 @@ + + + + rewrite_guide + /rewrite/ + .. + + + en + + diff --git a/trunk/docs/manual/rewrite/rewrite_guide_advanced.html b/trunk/docs/manual/rewrite/rewrite_guide_advanced.html new file mode 100644 index 0000000000..07850dd6ba --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide_advanced.html @@ -0,0 +1,3 @@ +URI: rewrite_guide_advanced.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/rewrite/rewrite_guide_advanced.html.en b/trunk/docs/manual/rewrite/rewrite_guide_advanced.html.en new file mode 100644 index 0000000000..ca592e8bfd --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide_advanced.html.en @@ -0,0 +1,1289 @@ + + + +URL Rewriting Guide - Advanced topics - Apache HTTP Server + + + + + +
    <-
    +

    URL Rewriting Guide - Advanced topics

    +
    +

    Available Languages:  en 

    +
    + + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonony confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + +
    ATTENTION: Depending on your server configuration + it may be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. This + avoids many problems.
    + +
    + +
    top
    +
    +

    Webcluster through Homogeneous URL Layout

    + + + +
    +
    Description:
    + +
    +

    We want to create a homogeneous and consistent URL + layout over all WWW servers on a Intranet webcluster, i.e. + all URLs (per definition server local and thus server + dependent!) become actually server independent! + What we want is to give the WWW namespace a consistent + server-independent layout: no URL should have to include + any physically correct target server. The cluster itself + should drive us automatically to the physical target + host.

    +
    + +
    Solution:
    + +
    +

    First, the knowledge of the target servers come from + (distributed) external maps which contain information + where our users, groups and entities stay. The have the + form

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    We put them into files map.xxx-to-host. + Second we need to instruct all servers to redirect URLs + of the forms

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    to

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    when the URL is not locally valid to a server. The + following ruleset does this for us by the help of the map + files (assuming that server0 is a default server which + will be used if a user has no entry in the map):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + +
    top
    +
    +

    Structured Homedirs

    + + + +
    +
    Description:
    + +
    +

    Some sites with thousands of users usually use a + structured homedir layout, i.e. each homedir is in a + subdirectory which begins for instance with the first + character of the username. So, /~foo/anypath + is /home/f/foo/.www/anypath + while /~bar/anypath is + /home/b/bar/.www/anypath.

    +
    + +
    Solution:
    + +
    +

    We use the following ruleset to expand the tilde URLs + into exactly the above layout.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + +
    top
    +
    +

    Filesystem Reorganization

    + + + +
    +
    Description:
    + +
    +

    This really is a hardcore example: a killer application + which heavily uses per-directory + RewriteRules to get a smooth look and feel + on the Web while its data structure is never touched or + adjusted. Background: net.sw is + my archive of freely available Unix software packages, + which I started to collect in 1992. It is both my hobby + and job to to this, because while I'm studying computer + science I have also worked for many years as a system and + network administrator in my spare time. Every week I need + some sort of software so I created a deep hierarchy of + directories where I stored the packages:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    In July 1996 I decided to make this archive public to + the world via a nice Web interface. "Nice" means that I + wanted to offer an interface where you can browse + directly through the archive hierarchy. And "nice" means + that I didn't wanted to change anything inside this + hierarchy - not even by putting some CGI scripts at the + top of it. Why? Because the above structure should be + later accessible via FTP as well, and I didn't want any + Web or CGI stuff to be there.

    +
    + +
    Solution:
    + +
    +

    The solution has two parts: The first is a set of CGI + scripts which create all the pages at all directory + levels on-the-fly. I put them under + /e/netsw/.www/ as follows:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    The DATA/ subdirectory holds the above + directory structure, i.e. the real + net.sw stuff and gets + automatically updated via rdist from time to + time. The second part of the problem remains: how to link + these two structures together into one smooth-looking URL + tree? We want to hide the DATA/ directory + from the user while running the appropriate CGI scripts + for the various URLs. Here is the solution: first I put + the following into the per-directory configuration file + in the DocumentRoot + of the server to rewrite the announced URL + /net.sw/ to the internal path + /e/netsw:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    The first rule is for requests which miss the trailing + slash! The second rule does the real thing. And then + comes the killer configuration which stays in the + per-directory config file + /e/netsw/.www/.wwwacl:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  we are reached via /net.sw/ prefix
    +RewriteBase   /net.sw/
    +
    +#  first we rewrite the root dir to
    +#  the handling cgi script
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  strip out the subdirs when
    +#  the browser requests us from perdir pages
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  and now break the rewriting for local files
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  anything else is a subdir which gets handled
    +#  by another cgi script
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Some hints for interpretation:

    + +
      +
    1. Notice the L (last) flag and no + substitution field ('-') in the forth part
    2. + +
    3. Notice the ! (not) character and + the C (chain) flag at the first rule + in the last part
    4. + +
    5. Notice the catch-all pattern in the last rule
    6. +
    +
    +
    + +
    top
    +
    +

    Redirect Failing URLs To Other Webserver

    + + + +
    +
    Description:
    + +
    +

    A typical FAQ about URL rewriting is how to redirect + failing requests on webserver A to webserver B. Usually + this is done via ErrorDocument CGI-scripts in Perl, but + there is also a mod_rewrite solution. + But notice that this performs more poorly than using an + ErrorDocument + CGI-script!

    +
    + +
    Solution:
    + +
    +

    The first solution has the best performance but less + flexibility, and is less error safe:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    The problem here is that this will only work for pages + inside the DocumentRoot. While you can add more + Conditions (for instance to also handle homedirs, etc.) + there is better variant:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    This uses the URL look-ahead feature of mod_rewrite. + The result is that this will work for all types of URLs + and is a safe way. But it does a performance impact on + the webserver, because for every request there is one + more internal subrequest. So, if your webserver runs on a + powerful CPU, use this one. If it is a slow machine, use + the first approach or better a ErrorDocument CGI-script.

    +
    +
    + +
    top
    +
    +

    Archive Access Multiplexer

    + + + +
    +
    Description:
    + +
    +

    Do you know the great CPAN (Comprehensive Perl Archive + Network) under http://www.perl.com/CPAN? + This does a redirect to one of several FTP servers around + the world which carry a CPAN mirror and is approximately + near the location of the requesting client. Actually this + can be called an FTP access multiplexing service. While + CPAN runs via CGI scripts, how can a similar approach + implemented via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    First we notice that from version 3.0.0 + mod_rewrite can + also use the "ftp:" scheme on redirects. + And second, the location approximation can be done by a + RewriteMap + over the top-level domain of the client. + With a tricky chained ruleset we can use this top-level + domain as a key to our multiplexing map.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + +
    top
    +
    +

    Content Handling

    + + + +

    Browser Dependent Content

    + + + +
    +
    Description:
    + +
    +

    At least for important top-level pages it is sometimes + necessary to provide the optimum of browser dependent + content, i.e. one has to provide a maximum version for the + latest Netscape variants, a minimum version for the Lynx + browsers and a average feature version for all others.

    +
    + +
    Solution:
    + +
    +

    We cannot use content negotiation because the browsers do + not provide their type in that form. Instead we have to + act on the HTTP header "User-Agent". The following condig + does the following: If the HTTP header "User-Agent" + begins with "Mozilla/3", the page foo.html + is rewritten to foo.NS.html and and the + rewriting stops. If the browser is "Lynx" or "Mozilla" of + version 1 or 2 the URL becomes foo.20.html. + All other browsers receive page foo.32.html. + This is done by the following ruleset:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + + + +

    Dynamic Mirror

    + + + +
    +
    Description:
    + +
    +

    Assume there are nice webpages on remote hosts we want + to bring into our namespace. For FTP servers we would use + the mirror program which actually maintains an + explicit up-to-date copy of the remote data on the local + machine. For a webserver we could use the program + webcopy which acts similar via HTTP. But both + techniques have one major drawback: The local copy is + always just as up-to-date as often we run the program. It + would be much better if the mirror is not a static one we + have to establish explicitly. Instead we want a dynamic + mirror with data which gets updated automatically when + there is need (updated data on the remote host).

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature + (flag [P]):

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + + + +

    Reverse Dynamic Mirror

    + + + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + + + +

    Retrieve Missing Data from Intranet

    + + + +
    +
    Description:
    + +
    +

    This is a tricky way of virtually running a corporate + (external) Internet webserver + (www.quux-corp.dom), while actually keeping + and maintaining its data on a (internal) Intranet webserver + (www2.quux-corp.dom) which is protected by a + firewall. The trick is that on the external webserver we + retrieve the requested data on-the-fly from the internal + one.

    +
    + +
    Solution:
    + +
    +

    First, we have to make sure that our firewall still + protects the internal webserver and that only the + external webserver is allowed to retrieve data from it. + For a packet-filtering firewall we could for instance + configure a firewall ruleset like the following:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    Just adjust it to your actual configuration syntax. + Now we can establish the mod_rewrite + rules which request the missing data in the background + through the proxy throughput feature:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + + + +

    Load Balancing

    + + + +
    +
    Description:
    + +
    +

    Suppose we want to load balance the traffic to + www.foo.com over www[0-5].foo.com + (a total of 6 servers). How can this be done?

    +
    + +
    Solution:
    + +
    +

    There are a lot of possible solutions for this problem. + We will discuss first a commonly known DNS-based variant + and then the special one with mod_rewrite:

    + +
      +
    1. + DNS Round-Robin + +

      The simplest method for load-balancing is to use + the DNS round-robin feature of BIND. + Here you just configure www[0-9].foo.com + as usual in your DNS with A(address) records, e.g.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      Then you additionally add the following entry:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      Notice that this seems wrong, but is actually an + intended feature of BIND and can be used + in this way. However, now when www.foo.com gets + resolved, BIND gives out www0-www6 + - but in a slightly permutated/rotated order every time. + This way the clients are spread over the various + servers. But notice that this not a perfect load + balancing scheme, because DNS resolve information + gets cached by the other nameservers on the net, so + once a client has resolved www.foo.com + to a particular wwwN.foo.com, all + subsequent requests also go to this particular name + wwwN.foo.com. But the final result is + ok, because the total sum of the requests are really + spread over the various webservers.

      +
    2. + +
    3. + DNS Load-Balancing + +

      A sophisticated DNS-based method for + load-balancing is to use the program + lbnamed which can be found at + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + It is a Perl 5 program in conjunction with auxilliary + tools which provides a real load-balancing for + DNS.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      In this variant we use mod_rewrite + and its proxy throughput feature. First we dedicate + www0.foo.com to be actually + www.foo.com by using a single

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      entry in the DNS. Then we convert + www0.foo.com to a proxy-only server, + i.e. we configure this machine so all arriving URLs + are just pushed through the internal proxy to one of + the 5 other servers (www1-www5). To + accomplish this we first establish a ruleset which + contacts a load balancing script lb.pl + for all URLs.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      Then we write lb.pl:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- load balancing script
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # the hostname base
      +$first  = 1;         # the first server (not 0 here, because 0 is myself)
      +$last   = 5;         # the last server in the round-robin
      +$domain = "foo.dom"; # the domainname
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + +
      A last notice: Why is this useful? Seems like + www0.foo.com still is overloaded? The + answer is yes, it is overloaded, but with plain proxy + throughput requests, only! All SSI, CGI, ePerl, etc. + processing is completely done on the other machines. + This is the essential point.
      +
    6. + +
    7. + Hardware/TCP Round-Robin + +

      There is a hardware solution available, too. Cisco + has a beast called LocalDirector which does a load + balancing at the TCP/IP level. Actually this is some + sort of a circuit level gateway in front of a + webcluster. If you have enough money and really need + a solution with high performance, use this one.

      +
    8. +
    +
    +
    + + + +

    New MIME-type, New Service

    + + + +
    +
    Description:
    + +
    +

    On the net there are a lot of nifty CGI programs. But + their usage is usually boring, so a lot of webmaster + don't use them. Even Apache's Action handler feature for + MIME-types is only appropriate when the CGI programs + don't need special URLs (actually PATH_INFO + and QUERY_STRINGS) as their input. First, + let us configure a new file type with extension + .scgi (for secure CGI) which will be processed + by the popular cgiwrap program. The problem + here is that for instance we use a Homogeneous URL Layout + (see above) a file inside the user homedirs has the URL + /u/user/foo/bar.scgi. But + cgiwrap needs the URL in the form + /~user/foo/bar.scgi/. The following rule + solves the problem:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    Or assume we have some more nifty programs: + wwwlog (which displays the + access.log for a URL subtree and + wwwidx (which runs Glimpse on a URL + subtree). We have to provide the URL area to these + programs so they know on which area they have to act on. + But usually this ugly, because they are all the times + still requested from that areas, i.e. typically we would + run the swwidx program from within + /u/user/foo/ via hyperlink to

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    which is ugly. Because we have to hard-code + both the location of the area + and the location of the CGI inside the + hyperlink. When we have to reorganize the area, we spend a + lot of time changing the various hyperlinks.

    +
    + +
    Solution:
    + +
    +

    The solution here is to provide a special new URL format + which automatically leads to the proper CGI invocation. + We configure the following:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    Now the hyperlink to search at + /u/user/foo/ reads only

    + +
    +HREF="*"
    +
    + +

    which internally gets automatically transformed to

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    The same approach leads to an invocation for the + access log CGI program when the hyperlink + :log gets used.

    +
    +
    + + + +

    On-the-fly Content-Regeneration

    + + + +
    +
    Description:
    + +
    +

    Here comes a really esoteric feature: Dynamically + generated but statically served pages, i.e. pages should be + delivered as pure static pages (read from the filesystem + and just passed through), but they have to be generated + dynamically by the webserver if missing. This way you can + have CGI-generated pages which are statically served unless + one (or a cronjob) removes the static contents. Then the + contents gets refreshed.

    +
    + +
    Solution:
    + +
    + This is done via the following ruleset: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    Here a request to page.html leads to a + internal run of a corresponding page.cgi if + page.html is still missing or has filesize + null. The trick here is that page.cgi is a + usual CGI script which (additionally to its STDOUT) + writes its output to the file page.html. + Once it was run, the server sends out the data of + page.html. When the webmaster wants to force + a refresh the contents, he just removes + page.html (usually done by a cronjob).

    +
    +
    + + + +

    Document With Autorefresh

    + + + +
    +
    Description:
    + +
    +

    Wouldn't it be nice while creating a complex webpage if + the webbrowser would automatically refresh the page every + time we write a new version from within our editor? + Impossible?

    +
    + +
    Solution:
    + +
    +

    No! We just combine the MIME multipart feature, the + webserver NPH feature and the URL manipulation power of + mod_rewrite. First, we establish a new + URL feature: Adding just :refresh to any + URL causes this to be refreshed every time it gets + updated on the filesystem.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    Now when we reference the URL

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    this leads to the internal invocation of the URL

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    The only missing part is the NPH-CGI script. Although + one would usually say "left as an exercise to the reader" + ;-) I will provide this, too.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + + + +

    Mass Virtual Hosting

    + + + +
    +
    Description:
    + +
    +

    The <VirtualHost> feature of Apache is nice + and works great when you just have a few dozens + virtual hosts. But when you are an ISP and have hundreds of + virtual hosts to provide this feature is not the best + choice.

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature (flag [P]):

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   use the canonical hostname on redirects, etc.
    +UseCanonicalName on
    +
    +    :
    +#   add the virtual host in front of the CLF-format
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   enable the rewriting engine in the main server
    +RewriteEngine on
    +
    +#   define two maps: one for fixing the URL and one which defines
    +#   the available virtual hosts with their corresponding
    +#   DocumentRoot.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   Now do the actual virtual host mapping
    +#   via a huge and complicated single rule:
    +#
    +#   1. make sure we don't map for common locations
    +RewriteCond   %{REQUEST_URI}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URI}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URI}  !^/commonurlN/.*
    +#
    +#   2. make sure we have a Host header, because
    +#      currently our approach only supports
    +#      virtual hosting through this header
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. lowercase the hostname
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. lookup this hostname in vhost.map and
    +#      remember it only when it is a path
    +#      (and not "NONE" from above)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. finally we can map the URL to its docroot location
    +#      and remember the virtual host for logging puposes
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + + + +
    top
    +
    +

    Access Restriction

    + + + +

    Host Deny

    + + + +
    +
    Description:
    + +
    +

    How can we forbid a list of externally configured hosts + from using our server?

    +
    + +
    Solution:
    + +
    +

    For Apache >= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    For Apache <= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ATTENTION! This is a map, not a list, even when we treat it as such.
    +##             mod_rewrite parses it for key/value pairs, so at least a
    +##             dummy value "-" must be present for each entry.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + + + +

    Proxy Deny

    + + + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + + + +

    Special Authentication Variant

    + + + +
    +
    Description:
    + +
    +

    Sometimes a very special authentication is needed, for + instance a authentication which checks for a set of + explicitly configured users. Only these should receive + access and without explicit prompting (which would occur + when using the Basic Auth via mod_auth).

    +
    + +
    Solution:
    + +
    +

    We use a list of rewrite conditions to exclude all except + our friends:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + + + +

    Referer-based Deflector

    + + + +
    +
    Description:
    + +
    +

    How can we program a flexible URL Deflector which acts + on the "Referer" HTTP header and can be configured with as + many referring pages as we like?

    +
    + +
    Solution:
    + +
    +

    Use the following really tricky ruleset...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... in conjunction with a corresponding rewrite + map:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    This automatically redirects the request back to the + referring page (when "-" is used as the value + in the map) or to a specific URL (when an URL is specified + in the map as the second argument).

    +
    +
    + + + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml b/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml new file mode 100644 index 0000000000..8b12d819db --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml @@ -0,0 +1,1292 @@ + + + + + + + + + + + URL Rewriting Guide - Advanced topics + + + +

    This document supplements the mod_rewrite + reference documentation. + It describes how one can use Apache's mod_rewrite + to solve typical URL-based problems with which webmasters are + commonony confronted. We give detailed descriptions on how to + solve each problem by configuring URL rewriting rulesets.

    + + ATTENTION: Depending on your server configuration + it may be necessary to slightly change the examples for your + situation, e.g. adding the [PT] flag when + additionally using mod_alias and + mod_userdir, etc. Or rewriting a ruleset + to fit in .htaccess context instead + of per-server context. Always try to understand what a + particular ruleset really does before you use it. This + avoids many problems. + +
    +Module +documentation +mod_rewrite +introduction +Practical solutions to common +problems +Technical details + + +
    + + Webcluster through Homogeneous URL Layout + +
    +
    Description:
    + +
    +

    We want to create a homogeneous and consistent URL + layout over all WWW servers on a Intranet webcluster, i.e. + all URLs (per definition server local and thus server + dependent!) become actually server independent! + What we want is to give the WWW namespace a consistent + server-independent layout: no URL should have to include + any physically correct target server. The cluster itself + should drive us automatically to the physical target + host.

    +
    + +
    Solution:
    + +
    +

    First, the knowledge of the target servers come from + (distributed) external maps which contain information + where our users, groups and entities stay. The have the + form

    + +
    +user1  server_of_user1
    +user2  server_of_user2
    +:      :
    +
    + +

    We put them into files map.xxx-to-host. + Second we need to instruct all servers to redirect URLs + of the forms

    + +
    +/u/user/anypath
    +/g/group/anypath
    +/e/entity/anypath
    +
    + +

    to

    + +
    +http://physical-host/u/user/anypath
    +http://physical-host/g/group/anypath
    +http://physical-host/e/entity/anypath
    +
    + +

    when the URL is not locally valid to a server. The + following ruleset does this for us by the help of the map + files (assuming that server0 is a default server which + will be used if a user has no entry in the map):

    + +
    +RewriteEngine on
    +
    +RewriteMap      user-to-host   txt:/path/to/map.user-to-host
    +RewriteMap     group-to-host   txt:/path/to/map.group-to-host
    +RewriteMap    entity-to-host   txt:/path/to/map.entity-to-host
    +
    +RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2
    +RewriteRule   ^/g/([^/]+)/?(.*)  http://${group-to-host:$1|server0}/g/$1/$2
    +RewriteRule   ^/e/([^/]+)/?(.*) http://${entity-to-host:$1|server0}/e/$1/$2
    +
    +RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
    +RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
    +
    +
    +
    + +
    + +
    + + Structured Homedirs + +
    +
    Description:
    + +
    +

    Some sites with thousands of users usually use a + structured homedir layout, i.e. each homedir is in a + subdirectory which begins for instance with the first + character of the username. So, /~foo/anypath + is /home/f/foo/.www/anypath + while /~bar/anypath is + /home/b/bar/.www/anypath.

    +
    + +
    Solution:
    + +
    +

    We use the following ruleset to expand the tilde URLs + into exactly the above layout.

    + +
    +RewriteEngine on
    +RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
    +
    +
    +
    + +
    + +
    + + Filesystem Reorganization + +
    +
    Description:
    + +
    +

    This really is a hardcore example: a killer application + which heavily uses per-directory + RewriteRules to get a smooth look and feel + on the Web while its data structure is never touched or + adjusted. Background: net.sw is + my archive of freely available Unix software packages, + which I started to collect in 1992. It is both my hobby + and job to to this, because while I'm studying computer + science I have also worked for many years as a system and + network administrator in my spare time. Every week I need + some sort of software so I created a deep hierarchy of + directories where I stored the packages:

    + +
    +drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
    +drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
    +drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
    +drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
    +drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
    +drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
    +drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
    +drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
    +drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
    +drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
    +drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
    +
    + +

    In July 1996 I decided to make this archive public to + the world via a nice Web interface. "Nice" means that I + wanted to offer an interface where you can browse + directly through the archive hierarchy. And "nice" means + that I didn't wanted to change anything inside this + hierarchy - not even by putting some CGI scripts at the + top of it. Why? Because the above structure should be + later accessible via FTP as well, and I didn't want any + Web or CGI stuff to be there.

    +
    + +
    Solution:
    + +
    +

    The solution has two parts: The first is a set of CGI + scripts which create all the pages at all directory + levels on-the-fly. I put them under + /e/netsw/.www/ as follows:

    + +
    +-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
    +drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
    +-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
    +-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
    +-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
    +-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
    +-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
    +-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
    +drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
    +-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
    +-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
    +-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
    +-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
    +
    + +

    The DATA/ subdirectory holds the above + directory structure, i.e. the real + net.sw stuff and gets + automatically updated via rdist from time to + time. The second part of the problem remains: how to link + these two structures together into one smooth-looking URL + tree? We want to hide the DATA/ directory + from the user while running the appropriate CGI scripts + for the various URLs. Here is the solution: first I put + the following into the per-directory configuration file + in the DocumentRoot + of the server to rewrite the announced URL + /net.sw/ to the internal path + /e/netsw:

    + +
    +RewriteRule  ^net.sw$       net.sw/        [R]
    +RewriteRule  ^net.sw/(.*)$  e/netsw/$1
    +
    + +

    The first rule is for requests which miss the trailing + slash! The second rule does the real thing. And then + comes the killer configuration which stays in the + per-directory config file + /e/netsw/.www/.wwwacl:

    + +
    +Options       ExecCGI FollowSymLinks Includes MultiViews
    +
    +RewriteEngine on
    +
    +#  we are reached via /net.sw/ prefix
    +RewriteBase   /net.sw/
    +
    +#  first we rewrite the root dir to
    +#  the handling cgi script
    +RewriteRule   ^$                       netsw-home.cgi     [L]
    +RewriteRule   ^index\.html$            netsw-home.cgi     [L]
    +
    +#  strip out the subdirs when
    +#  the browser requests us from perdir pages
    +RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
    +
    +#  and now break the rewriting for local files
    +RewriteRule   ^netsw-home\.cgi.*       -                  [L]
    +RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
    +RewriteRule   ^netsw-search\.cgi.*     -                  [L]
    +RewriteRule   ^netsw-tree\.cgi$        -                  [L]
    +RewriteRule   ^netsw-about\.html$      -                  [L]
    +RewriteRule   ^netsw-img/.*$           -                  [L]
    +
    +#  anything else is a subdir which gets handled
    +#  by another cgi script
    +RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
    +RewriteRule   (.*)                     netsw-lsdir.cgi/$1
    +
    + +

    Some hints for interpretation:

    + +
      +
    1. Notice the L (last) flag and no + substitution field ('-') in the forth part
    2. + +
    3. Notice the ! (not) character and + the C (chain) flag at the first rule + in the last part
    4. + +
    5. Notice the catch-all pattern in the last rule
    6. +
    +
    +
    + +
    + +
    + + Redirect Failing URLs To Other Webserver + +
    +
    Description:
    + +
    +

    A typical FAQ about URL rewriting is how to redirect + failing requests on webserver A to webserver B. Usually + this is done via ErrorDocument CGI-scripts in Perl, but + there is also a mod_rewrite solution. + But notice that this performs more poorly than using an + ErrorDocument + CGI-script!

    +
    + +
    Solution:
    + +
    +

    The first solution has the best performance but less + flexibility, and is less error safe:

    + +
    +RewriteEngine on
    +RewriteCond   /your/docroot/%{REQUEST_FILENAME} !-f
    +RewriteRule   ^(.+)                             http://webserverB.dom/$1
    +
    + +

    The problem here is that this will only work for pages + inside the DocumentRoot. While you can add more + Conditions (for instance to also handle homedirs, etc.) + there is better variant:

    + +
    +RewriteEngine on
    +RewriteCond   %{REQUEST_URI} !-U
    +RewriteRule   ^(.+)          http://webserverB.dom/$1
    +
    + +

    This uses the URL look-ahead feature of mod_rewrite. + The result is that this will work for all types of URLs + and is a safe way. But it does a performance impact on + the webserver, because for every request there is one + more internal subrequest. So, if your webserver runs on a + powerful CPU, use this one. If it is a slow machine, use + the first approach or better a ErrorDocument CGI-script.

    +
    +
    + +
    + +
    + + Archive Access Multiplexer + +
    +
    Description:
    + +
    +

    Do you know the great CPAN (Comprehensive Perl Archive + Network) under http://www.perl.com/CPAN? + This does a redirect to one of several FTP servers around + the world which carry a CPAN mirror and is approximately + near the location of the requesting client. Actually this + can be called an FTP access multiplexing service. While + CPAN runs via CGI scripts, how can a similar approach + implemented via mod_rewrite?

    +
    + +
    Solution:
    + +
    +

    First we notice that from version 3.0.0 + mod_rewrite can + also use the "ftp:" scheme on redirects. + And second, the location approximation can be done by a + RewriteMap + over the top-level domain of the client. + With a tricky chained ruleset we can use this top-level + domain as a key to our multiplexing map.

    + +
    +RewriteEngine on
    +RewriteMap    multiplex                txt:/path/to/map.cxan
    +RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
    +RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$  ${multiplex:$1|ftp.default.dom}$2  [R,L]
    +
    + +
    +##
    +##  map.cxan -- Multiplexing Map for CxAN
    +##
    +
    +de        ftp://ftp.cxan.de/CxAN/
    +uk        ftp://ftp.cxan.uk/CxAN/
    +com       ftp://ftp.cxan.com/CxAN/
    + :
    +##EOF##
    +
    +
    +
    + +
    + +
    + + Content Handling + +
    + + Browser Dependent Content + +
    +
    Description:
    + +
    +

    At least for important top-level pages it is sometimes + necessary to provide the optimum of browser dependent + content, i.e. one has to provide a maximum version for the + latest Netscape variants, a minimum version for the Lynx + browsers and a average feature version for all others.

    +
    + +
    Solution:
    + +
    +

    We cannot use content negotiation because the browsers do + not provide their type in that form. Instead we have to + act on the HTTP header "User-Agent". The following condig + does the following: If the HTTP header "User-Agent" + begins with "Mozilla/3", the page foo.html + is rewritten to foo.NS.html and and the + rewriting stops. If the browser is "Lynx" or "Mozilla" of + version 1 or 2 the URL becomes foo.20.html. + All other browsers receive page foo.32.html. + This is done by the following ruleset:

    + +
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
    +RewriteRule ^foo\.html$         foo.NS.html          [L]
    +
    +RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
    +RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
    +RewriteRule ^foo\.html$         foo.20.html          [L]
    +
    +RewriteRule ^foo\.html$         foo.32.html          [L]
    +
    +
    +
    + +
    + +
    + + Dynamic Mirror + +
    +
    Description:
    + +
    +

    Assume there are nice webpages on remote hosts we want + to bring into our namespace. For FTP servers we would use + the mirror program which actually maintains an + explicit up-to-date copy of the remote data on the local + machine. For a webserver we could use the program + webcopy which acts similar via HTTP. But both + techniques have one major drawback: The local copy is + always just as up-to-date as often we run the program. It + would be much better if the mirror is not a static one we + have to establish explicitly. Instead we want a dynamic + mirror with data which gets updated automatically when + there is need (updated data on the remote host).

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature + (flag [P]):

    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^hotsheet/(.*)$  http://www.tstimpreso.com/hotsheet/$1  [P]
    +
    + +
    +RewriteEngine  on
    +RewriteBase    /~quux/
    +RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
    +
    +
    +
    + +
    + +
    + + Reverse Dynamic Mirror + +
    +
    Description:
    + +
    ...
    + +
    Solution:
    + +
    +
    +RewriteEngine on
    +RewriteCond   /mirror/of/remotesite/$1           -U
    +RewriteRule   ^http://www\.remotesite\.com/(.*)$ /mirror/of/remotesite/$1
    +
    +
    +
    + +
    + +
    + + Retrieve Missing Data from Intranet + +
    +
    Description:
    + +
    +

    This is a tricky way of virtually running a corporate + (external) Internet webserver + (www.quux-corp.dom), while actually keeping + and maintaining its data on a (internal) Intranet webserver + (www2.quux-corp.dom) which is protected by a + firewall. The trick is that on the external webserver we + retrieve the requested data on-the-fly from the internal + one.

    +
    + +
    Solution:
    + +
    +

    First, we have to make sure that our firewall still + protects the internal webserver and that only the + external webserver is allowed to retrieve data from it. + For a packet-filtering firewall we could for instance + configure a firewall ruleset like the following:

    + +
    +ALLOW Host www.quux-corp.dom Port >1024 --> Host www2.quux-corp.dom Port 80
    +DENY  Host *                 Port *     --> Host www2.quux-corp.dom Port 80
    +
    + +

    Just adjust it to your actual configuration syntax. + Now we can establish the mod_rewrite + rules which request the missing data in the background + through the proxy throughput feature:

    + +
    +RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2
    +RewriteCond %{REQUEST_FILENAME}       !-f
    +RewriteCond %{REQUEST_FILENAME}       !-d
    +RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
    +
    +
    +
    + +
    + +
    + + Load Balancing + +
    +
    Description:
    + +
    +

    Suppose we want to load balance the traffic to + www.foo.com over www[0-5].foo.com + (a total of 6 servers). How can this be done?

    +
    + +
    Solution:
    + +
    +

    There are a lot of possible solutions for this problem. + We will discuss first a commonly known DNS-based variant + and then the special one with mod_rewrite:

    + +
      +
    1. + DNS Round-Robin + +

      The simplest method for load-balancing is to use + the DNS round-robin feature of BIND. + Here you just configure www[0-9].foo.com + as usual in your DNS with A(address) records, e.g.

      + +
      +www0   IN  A       1.2.3.1
      +www1   IN  A       1.2.3.2
      +www2   IN  A       1.2.3.3
      +www3   IN  A       1.2.3.4
      +www4   IN  A       1.2.3.5
      +www5   IN  A       1.2.3.6
      +
      + +

      Then you additionally add the following entry:

      + +
      +www    IN  CNAME   www0.foo.com.
      +       IN  CNAME   www1.foo.com.
      +       IN  CNAME   www2.foo.com.
      +       IN  CNAME   www3.foo.com.
      +       IN  CNAME   www4.foo.com.
      +       IN  CNAME   www5.foo.com.
      +       IN  CNAME   www6.foo.com.
      +
      + +

      Notice that this seems wrong, but is actually an + intended feature of BIND and can be used + in this way. However, now when www.foo.com gets + resolved, BIND gives out www0-www6 + - but in a slightly permutated/rotated order every time. + This way the clients are spread over the various + servers. But notice that this not a perfect load + balancing scheme, because DNS resolve information + gets cached by the other nameservers on the net, so + once a client has resolved www.foo.com + to a particular wwwN.foo.com, all + subsequent requests also go to this particular name + wwwN.foo.com. But the final result is + ok, because the total sum of the requests are really + spread over the various webservers.

      +
    2. + +
    3. + DNS Load-Balancing + +

      A sophisticated DNS-based method for + load-balancing is to use the program + lbnamed which can be found at + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + It is a Perl 5 program in conjunction with auxilliary + tools which provides a real load-balancing for + DNS.

      +
    4. + +
    5. + Proxy Throughput Round-Robin + +

      In this variant we use mod_rewrite + and its proxy throughput feature. First we dedicate + www0.foo.com to be actually + www.foo.com by using a single

      + +
      +www    IN  CNAME   www0.foo.com.
      +
      + +

      entry in the DNS. Then we convert + www0.foo.com to a proxy-only server, + i.e. we configure this machine so all arriving URLs + are just pushed through the internal proxy to one of + the 5 other servers (www1-www5). To + accomplish this we first establish a ruleset which + contacts a load balancing script lb.pl + for all URLs.

      + +
      +RewriteEngine on
      +RewriteMap    lb      prg:/path/to/lb.pl
      +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
      +
      + +

      Then we write lb.pl:

      + +
      +#!/path/to/perl
      +##
      +##  lb.pl -- load balancing script
      +##
      +
      +$| = 1;
      +
      +$name   = "www";     # the hostname base
      +$first  = 1;         # the first server (not 0 here, because 0 is myself)
      +$last   = 5;         # the last server in the round-robin
      +$domain = "foo.dom"; # the domainname
      +
      +$cnt = 0;
      +while (<STDIN>) {
      +    $cnt = (($cnt+1) % ($last+1-$first));
      +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
      +    print "http://$server/$_";
      +}
      +
      +##EOF##
      +
      + + A last notice: Why is this useful? Seems like + www0.foo.com still is overloaded? The + answer is yes, it is overloaded, but with plain proxy + throughput requests, only! All SSI, CGI, ePerl, etc. + processing is completely done on the other machines. + This is the essential point. +
    6. + +
    7. + Hardware/TCP Round-Robin + +

      There is a hardware solution available, too. Cisco + has a beast called LocalDirector which does a load + balancing at the TCP/IP level. Actually this is some + sort of a circuit level gateway in front of a + webcluster. If you have enough money and really need + a solution with high performance, use this one.

      +
    8. +
    +
    +
    + +
    + +
    + + New MIME-type, New Service + +
    +
    Description:
    + +
    +

    On the net there are a lot of nifty CGI programs. But + their usage is usually boring, so a lot of webmaster + don't use them. Even Apache's Action handler feature for + MIME-types is only appropriate when the CGI programs + don't need special URLs (actually PATH_INFO + and QUERY_STRINGS) as their input. First, + let us configure a new file type with extension + .scgi (for secure CGI) which will be processed + by the popular cgiwrap program. The problem + here is that for instance we use a Homogeneous URL Layout + (see above) a file inside the user homedirs has the URL + /u/user/foo/bar.scgi. But + cgiwrap needs the URL in the form + /~user/foo/bar.scgi/. The following rule + solves the problem:

    + +
    +RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
    +... /internal/cgi/user/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
    +
    + +

    Or assume we have some more nifty programs: + wwwlog (which displays the + access.log for a URL subtree and + wwwidx (which runs Glimpse on a URL + subtree). We have to provide the URL area to these + programs so they know on which area they have to act on. + But usually this ugly, because they are all the times + still requested from that areas, i.e. typically we would + run the swwidx program from within + /u/user/foo/ via hyperlink to

    + +
    +/internal/cgi/user/swwidx?i=/u/user/foo/
    +
    + +

    which is ugly. Because we have to hard-code + both the location of the area + and the location of the CGI inside the + hyperlink. When we have to reorganize the area, we spend a + lot of time changing the various hyperlinks.

    +
    + +
    Solution:
    + +
    +

    The solution here is to provide a special new URL format + which automatically leads to the proper CGI invocation. + We configure the following:

    + +
    +RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /internal/cgi/user/wwwidx?i=/$1/$2$3/
    +RewriteRule   ^/([uge])/([^/]+)(/?.*):log /internal/cgi/user/wwwlog?f=/$1/$2$3
    +
    + +

    Now the hyperlink to search at + /u/user/foo/ reads only

    + +
    +HREF="*"
    +
    + +

    which internally gets automatically transformed to

    + +
    +/internal/cgi/user/wwwidx?i=/u/user/foo/
    +
    + +

    The same approach leads to an invocation for the + access log CGI program when the hyperlink + :log gets used.

    +
    +
    + +
    + +
    + + On-the-fly Content-Regeneration + +
    +
    Description:
    + +
    +

    Here comes a really esoteric feature: Dynamically + generated but statically served pages, i.e. pages should be + delivered as pure static pages (read from the filesystem + and just passed through), but they have to be generated + dynamically by the webserver if missing. This way you can + have CGI-generated pages which are statically served unless + one (or a cronjob) removes the static contents. Then the + contents gets refreshed.

    +
    + +
    Solution:
    + +
    + This is done via the following ruleset: + +
    +RewriteCond %{REQUEST_FILENAME}   !-s
    +RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
    +
    + +

    Here a request to page.html leads to a + internal run of a corresponding page.cgi if + page.html is still missing or has filesize + null. The trick here is that page.cgi is a + usual CGI script which (additionally to its STDOUT) + writes its output to the file page.html. + Once it was run, the server sends out the data of + page.html. When the webmaster wants to force + a refresh the contents, he just removes + page.html (usually done by a cronjob).

    +
    +
    + +
    + +
    + + Document With Autorefresh + +
    +
    Description:
    + +
    +

    Wouldn't it be nice while creating a complex webpage if + the webbrowser would automatically refresh the page every + time we write a new version from within our editor? + Impossible?

    +
    + +
    Solution:
    + +
    +

    No! We just combine the MIME multipart feature, the + webserver NPH feature and the URL manipulation power of + mod_rewrite. First, we establish a new + URL feature: Adding just :refresh to any + URL causes this to be refreshed every time it gets + updated on the filesystem.

    + +
    +RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /internal/cgi/apache/nph-refresh?f=$1
    +
    + +

    Now when we reference the URL

    + +
    +/u/foo/bar/page.html:refresh
    +
    + +

    this leads to the internal invocation of the URL

    + +
    +/internal/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
    +
    + +

    The only missing part is the NPH-CGI script. Although + one would usually say "left as an exercise to the reader" + ;-) I will provide this, too.

    + +
    +#!/sw/bin/perl
    +##
    +##  nph-refresh -- NPH/CGI script for auto refreshing pages
    +##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
    +##
    +$| = 1;
    +
    +#   split the QUERY_STRING variable
    +@pairs = split(/&/, $ENV{'QUERY_STRING'});
    +foreach $pair (@pairs) {
    +    ($name, $value) = split(/=/, $pair);
    +    $name =~ tr/A-Z/a-z/;
    +    $name = 'QS_' . $name;
    +    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    +    eval "\$$name = \"$value\"";
    +}
    +$QS_s = 1 if ($QS_s eq '');
    +$QS_n = 3600 if ($QS_n eq '');
    +if ($QS_f eq '') {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: No file given\n";
    +    exit(0);
    +}
    +if (! -f $QS_f) {
    +    print "HTTP/1.0 200 OK\n";
    +    print "Content-type: text/html\n\n";
    +    print "&lt;b&gt;ERROR&lt;/b&gt;: File $QS_f not found\n";
    +    exit(0);
    +}
    +
    +sub print_http_headers_multipart_begin {
    +    print "HTTP/1.0 200 OK\n";
    +    $bound = "ThisRandomString12345";
    +    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
    +    &print_http_headers_multipart_next;
    +}
    +
    +sub print_http_headers_multipart_next {
    +    print "\n--$bound\n";
    +}
    +
    +sub print_http_headers_multipart_end {
    +    print "\n--$bound--\n";
    +}
    +
    +sub displayhtml {
    +    local($buffer) = @_;
    +    $len = length($buffer);
    +    print "Content-type: text/html\n";
    +    print "Content-length: $len\n\n";
    +    print $buffer;
    +}
    +
    +sub readfile {
    +    local($file) = @_;
    +    local(*FP, $size, $buffer, $bytes);
    +    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
    +    $size = sprintf("%d", $size);
    +    open(FP, "&lt;$file");
    +    $bytes = sysread(FP, $buffer, $size);
    +    close(FP);
    +    return $buffer;
    +}
    +
    +$buffer = &readfile($QS_f);
    +&print_http_headers_multipart_begin;
    +&displayhtml($buffer);
    +
    +sub mystat {
    +    local($file) = $_[0];
    +    local($time);
    +
    +    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
    +    return $mtime;
    +}
    +
    +$mtimeL = &mystat($QS_f);
    +$mtime = $mtime;
    +for ($n = 0; $n &lt; $QS_n; $n++) {
    +    while (1) {
    +        $mtime = &mystat($QS_f);
    +        if ($mtime ne $mtimeL) {
    +            $mtimeL = $mtime;
    +            sleep(2);
    +            $buffer = &readfile($QS_f);
    +            &print_http_headers_multipart_next;
    +            &displayhtml($buffer);
    +            sleep(5);
    +            $mtimeL = &mystat($QS_f);
    +            last;
    +        }
    +        sleep($QS_s);
    +    }
    +}
    +
    +&print_http_headers_multipart_end;
    +
    +exit(0);
    +
    +##EOF##
    +
    +
    +
    + +
    + +
    + + Mass Virtual Hosting + +
    +
    Description:
    + +
    +

    The VirtualHost feature of Apache is nice + and works great when you just have a few dozens + virtual hosts. But when you are an ISP and have hundreds of + virtual hosts to provide this feature is not the best + choice.

    +
    + +
    Solution:
    + +
    +

    To provide this feature we map the remote webpage or even + the complete remote webarea to our namespace by the use + of the Proxy Throughput feature (flag [P]):

    + +
    +##
    +##  vhost.map
    +##
    +www.vhost1.dom:80  /path/to/docroot/vhost1
    +www.vhost2.dom:80  /path/to/docroot/vhost2
    +     :
    +www.vhostN.dom:80  /path/to/docroot/vhostN
    +
    + +
    +##
    +##  httpd.conf
    +##
    +    :
    +#   use the canonical hostname on redirects, etc.
    +UseCanonicalName on
    +
    +    :
    +#   add the virtual host in front of the CLF-format
    +CustomLog  /path/to/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
    +    :
    +
    +#   enable the rewriting engine in the main server
    +RewriteEngine on
    +
    +#   define two maps: one for fixing the URL and one which defines
    +#   the available virtual hosts with their corresponding
    +#   DocumentRoot.
    +RewriteMap    lowercase    int:tolower
    +RewriteMap    vhost        txt:/path/to/vhost.map
    +
    +#   Now do the actual virtual host mapping
    +#   via a huge and complicated single rule:
    +#
    +#   1. make sure we don't map for common locations
    +RewriteCond   %{REQUEST_URI}  !^/commonurl1/.*
    +RewriteCond   %{REQUEST_URI}  !^/commonurl2/.*
    +    :
    +RewriteCond   %{REQUEST_URI}  !^/commonurlN/.*
    +#
    +#   2. make sure we have a Host header, because
    +#      currently our approach only supports
    +#      virtual hosting through this header
    +RewriteCond   %{HTTP_HOST}  !^$
    +#
    +#   3. lowercase the hostname
    +RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
    +#
    +#   4. lookup this hostname in vhost.map and
    +#      remember it only when it is a path
    +#      (and not "NONE" from above)
    +RewriteCond   ${vhost:%1}  ^(/.*)$
    +#
    +#   5. finally we can map the URL to its docroot location
    +#      and remember the virtual host for logging puposes
    +RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
    +    :
    +
    +
    +
    + +
    + +
    + +
    + + Access Restriction + +
    + + Host Deny + +
    +
    Description:
    + +
    +

    How can we forbid a list of externally configured hosts + from using our server?

    +
    + +
    Solution:
    + +
    +

    For Apache >= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
    +RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule   ^/.*  -  [F]
    +
    + +

    For Apache <= 1.3b6:

    + +
    +RewriteEngine on
    +RewriteMap    hosts-deny  txt:/path/to/hosts.deny
    +RewriteRule   ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/$1
    +RewriteRule   !^NOT-FOUND/.* - [F]
    +RewriteRule   ^NOT-FOUND/(.*)$ /$1
    +
    + +
    +##
    +##  hosts.deny
    +##
    +##  ATTENTION! This is a map, not a list, even when we treat it as such.
    +##             mod_rewrite parses it for key/value pairs, so at least a
    +##             dummy value "-" must be present for each entry.
    +##
    +
    +193.102.180.41 -
    +bsdti1.sdm.de  -
    +192.76.162.40  -
    +
    +
    +
    + +
    + +
    + + Proxy Deny + +
    +
    Description:
    + +
    +

    How can we forbid a certain host or even a user of a + special host from using the Apache proxy?

    +
    + +
    Solution:
    + +
    +

    We first have to make sure mod_rewrite + is below(!) mod_proxy in the Configuration + file when compiling the Apache webserver. This way it gets + called before mod_proxy. Then we + configure the following for a host-dependent deny...

    + +
    +RewriteCond %{REMOTE_HOST} ^badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    + +

    ...and this one for a user@host-dependent deny:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^badguy@badhost\.mydomain\.com$
    +RewriteRule !^http://[^/.]\.mydomain.com.*  - [F]
    +
    +
    +
    + +
    + +
    + + Special Authentication Variant + +
    +
    Description:
    + +
    +

    Sometimes a very special authentication is needed, for + instance a authentication which checks for a set of + explicitly configured users. Only these should receive + access and without explicit prompting (which would occur + when using the Basic Auth via mod_auth).

    +
    + +
    Solution:
    + +
    +

    We use a list of rewrite conditions to exclude all except + our friends:

    + +
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend1@client1.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend2@client2.quux-corp\.com$
    +RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^friend3@client3.quux-corp\.com$
    +RewriteRule ^/~quux/only-for-friends/      -                                 [F]
    +
    +
    +
    + +
    + +
    + + Referer-based Deflector + +
    +
    Description:
    + +
    +

    How can we program a flexible URL Deflector which acts + on the "Referer" HTTP header and can be configured with as + many referring pages as we like?

    +
    + +
    Solution:
    + +
    +

    Use the following really tricky ruleset...

    + +
    +RewriteMap  deflector txt:/path/to/deflector.map
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
    +RewriteRule ^.* %{HTTP_REFERER} [R,L]
    +
    +RewriteCond %{HTTP_REFERER} !=""
    +RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
    +RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
    +
    + +

    ... in conjunction with a corresponding rewrite + map:

    + +
    +##
    +##  deflector.map
    +##
    +
    +http://www.badguys.com/bad/index.html    -
    +http://www.badguys.com/bad/index2.html   -
    +http://www.badguys.com/bad/index3.html   http://somewhere.com/
    +
    + +

    This automatically redirects the request back to the + referring page (when "-" is used as the value + in the map) or to a specific URL (when an URL is specified + in the map as the second argument).

    +
    +
    + +
    + +
    + +
    + diff --git a/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml.meta b/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml.meta new file mode 100644 index 0000000000..f0c7bf2686 --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_guide_advanced.xml.meta @@ -0,0 +1,11 @@ + + + + rewrite_guide_advanced + /rewrite/ + .. + + + en + + diff --git a/trunk/docs/manual/rewrite/rewrite_intro.html b/trunk/docs/manual/rewrite/rewrite_intro.html new file mode 100644 index 0000000000..607f1c18ab --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_intro.html @@ -0,0 +1,3 @@ +URI: rewrite_intro.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/rewrite/rewrite_intro.html.en b/trunk/docs/manual/rewrite/rewrite_intro.html.en new file mode 100644 index 0000000000..98822eac74 --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_intro.html.en @@ -0,0 +1,165 @@ + + + +Apache mod_rewrite Introduction - Apache HTTP Server + + + + + +
    <-
    +

    Apache mod_rewrite Introduction

    +
    +

    Available Languages:  en 

    +
    + +

    This document supplements the mod_rewrite +reference documentation. It +describes the basic concepts necessary for use of +mod_rewrite. Other documents go into greater detail, +but this doc should help the beginner get their feet wet. +

    +
    + +
    top
    +
    +

    Introduction

    +

    The Apache module mod_rewrite is a very powerful and +sophisticated module which provides a way to do URL manipulations. With +it, you can do nearly all types of URL rewriting that you may need. It +is, however, somewhat complex, and may be intimidating to the beginner. +There is also a tendency to treat rewrite rules as magic incantation, +using them without actually understanding what they do.

    + +

    This document attempts to give sufficient background so that what +follows is understood, rather than just copied blindly. +

    +
    top
    +
    +

    Regular Expressions

    + +

    mod_rewrite uses the Perl Compatible +Regular Expression vocabulary. In this document, we do not attempt +to provide a detailed reference to regular expressions. For that, we +recommend the PCRE man pages, the +Perl regular +expression man page, and Mastering +Regular Expressions, by Jeffrey Friedl.

    + +

    In this document, we attempt to provide enough of a regex vocabulary +to get you started, without being overwhelming, in the hope that +RewriteRules will be scientific +formulae, rather than magical incantations.

    + +

    Regex vocabulary

    + +

    The following are the minimal building blocks you will need, in order +to write regular expressions and RewriteRules.

    + + + + + + + + + +
    CharacterMeaning
    .Matches any character
    + + + +

    Regex Back-Reference Availability

    + +

    One important thing here has to be remembered: Whenever you + use parentheses in Pattern or in one of the + CondPattern, back-references are internally created + which can be used with the strings $N and + %N (see below). These are available for creating + the strings Substitution and TestString. + Figure 2 shows to which locations the back-references are + transferred for expansion.

    + +

    + [Needs graphics capability to display]
    + Figure 2: The back-reference flow through a rule. +

    + + +
    top
    +
    +

    RewriteRule basics

    +

    +Basic anatomy of a RewriteRule, with exhaustively annotated simple +examples. +

    +
    top
    +
    +

    Rewrite Flags

    +

    Discussion of the flags to RewriteRule, and when and why one might +use them.

    +
    top
    +
    +

    Rewrite conditions

    +

    Discussion of RewriteCond, looping, and other related concepts. +

    +
    top
    +
    +

    Rewrite maps

    +

    Discussion of RewriteMap, including simple, but heavily annotated, +examples.

    +
    top
    +
    +

    .htaccess files

    +

    Discussion of the differences between rewrite rules in httpd.conf and +in .htaccess files.

    +
    top
    +
    +

    Environment Variables

    + +

    This module keeps track of two additional (non-standard) +CGI/SSI environment variables named SCRIPT_URL +and SCRIPT_URI. These contain the +logical Web-view to the current resource, while the +standard CGI/SSI variables SCRIPT_NAME and +SCRIPT_FILENAME contain the physical +System-view.

    + +

    Notice: These variables hold the URI/URL as they were +initially requested, i.e., before any +rewriting. This is important because the rewriting process is +primarily used to rewrite logical URLs to physical +pathnames.

    + +

    Example

    +SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
    +SCRIPT_FILENAME=/u/rse/.www/index.html
    +SCRIPT_URL=/u/rse/
    +SCRIPT_URI=http://en1.engelschall.com/u/rse/
    +
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/rewrite/rewrite_intro.xml b/trunk/docs/manual/rewrite/rewrite_intro.xml new file mode 100644 index 0000000000..3336169bde --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_intro.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + Apache mod_rewrite Introduction + + +

    This document supplements the mod_rewrite +reference documentation. It +describes the basic concepts necessary for use of +mod_rewrite. Other documents go into greater detail, +but this doc should help the beginner get their feet wet. +

    +
    + +Module +documentation +Technical details +Practical solutions to common +problems +Practical solutions to +advanced problems + +
    Introduction +

    The Apache module mod_rewrite is a very powerful and +sophisticated module which provides a way to do URL manipulations. With +it, you can do nearly all types of URL rewriting that you may need. It +is, however, somewhat complex, and may be intimidating to the beginner. +There is also a tendency to treat rewrite rules as magic incantation, +using them without actually understanding what they do.

    + +

    This document attempts to give sufficient background so that what +follows is understood, rather than just copied blindly. +

    +
    + +
    Regular Expressions + +

    mod_rewrite uses the Perl Compatible +Regular Expression vocabulary. In this document, we do not attempt +to provide a detailed reference to regular expressions. For that, we +recommend the PCRE man pages, the +Perl regular +expression man page, and Mastering +Regular Expressions, by Jeffrey Friedl.

    + +

    In this document, we attempt to provide enough of a regex vocabulary +to get you started, without being overwhelming, in the hope that +RewriteRules will be scientific +formulae, rather than magical incantations.

    + +
    Regex vocabulary + +

    The following are the minimal building blocks you will need, in order +to write regular expressions and RewriteRules.

    + + + + + + + + + +
    CharacterMeaning
    .Matches any character
    + +
    + +
    Regex Back-Reference Availability + +

    One important thing here has to be remembered: Whenever you + use parentheses in Pattern or in one of the + CondPattern, back-references are internally created + which can be used with the strings $N and + %N (see below). These are available for creating + the strings Substitution and TestString. + Figure 2 shows to which locations the back-references are + transferred for expansion.

    + +

    + [Needs graphics capability to display]
    + Figure 2: The back-reference flow through a rule. +

    + +
    +
    + +
    RewriteRule basics +

    +Basic anatomy of a RewriteRule, with exhaustively annotated simple +examples. +

    +
    + +
    Rewrite Flags +

    Discussion of the flags to RewriteRule, and when and why one might +use them.

    +
    + +
    Rewrite conditions +

    Discussion of RewriteCond, looping, and other related concepts. +

    +
    + +
    Rewrite maps +

    Discussion of RewriteMap, including simple, but heavily annotated, +examples.

    +
    + +
    .htaccess files +

    Discussion of the differences between rewrite rules in httpd.conf and +in .htaccess files.

    +
    + +
    Environment Variables + +

    This module keeps track of two additional (non-standard) +CGI/SSI environment variables named SCRIPT_URL +and SCRIPT_URI. These contain the +logical Web-view to the current resource, while the +standard CGI/SSI variables SCRIPT_NAME and +SCRIPT_FILENAME contain the physical +System-view.

    + +

    Notice: These variables hold the URI/URL as they were +initially requested, i.e., before any +rewriting. This is important because the rewriting process is +primarily used to rewrite logical URLs to physical +pathnames.

    + +Example +
    +SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
    +SCRIPT_FILENAME=/u/rse/.www/index.html
    +SCRIPT_URL=/u/rse/
    +SCRIPT_URI=http://en1.engelschall.com/u/rse/
    +
    +
    + +
    + +
    + diff --git a/trunk/docs/manual/rewrite/rewrite_intro.xml.meta b/trunk/docs/manual/rewrite/rewrite_intro.xml.meta new file mode 100644 index 0000000000..fc07817eff --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_intro.xml.meta @@ -0,0 +1,11 @@ + + + + rewrite_intro + /rewrite/ + .. + + + en + + diff --git a/trunk/docs/manual/rewrite/rewrite_tech.html b/trunk/docs/manual/rewrite/rewrite_tech.html new file mode 100644 index 0000000000..4e06869fbe --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_tech.html @@ -0,0 +1,3 @@ +URI: rewrite_tech.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/rewrite/rewrite_tech.html.en b/trunk/docs/manual/rewrite/rewrite_tech.html.en new file mode 100644 index 0000000000..111795fced --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_tech.html.en @@ -0,0 +1,167 @@ + + + +Apache mod_rewrite Technical Details - Apache HTTP Server + + + + + +
    <-
    +

    Apache mod_rewrite Technical Details

    +
    +

    Available Languages:  en 

    +
    + +

    This document discusses some of the technical details of mod_rewrite +and URL matching.

    +
    + +
    top
    +
    +

    Internal Processing

    + +

    The internal processing of this module is very complex but + needs to be explained once even to the average user to avoid + common mistakes and to let you exploit its full + functionality.

    +
    top
    +
    +

    API Phases

    + +

    First you have to understand that when Apache processes a + HTTP request it does this in phases. A hook for each of these + phases is provided by the Apache API. Mod_rewrite uses two of + these hooks: the URL-to-filename translation hook which is + used after the HTTP request has been read but before any + authorization starts and the Fixup hook which is triggered + after the authorization phases and after the per-directory + config files (.htaccess) have been read, but + before the content handler is activated.

    + +

    So, after a request comes in and Apache has determined the + corresponding server (or virtual server) the rewriting engine + starts processing of all mod_rewrite directives from the + per-server configuration in the URL-to-filename phase. A few + steps later when the final data directories are found, the + per-directory configuration directives of mod_rewrite are + triggered in the Fixup phase. In both situations mod_rewrite + rewrites URLs either to new URLs or to filenames, although + there is no obvious distinction between them. This is a usage + of the API which was not intended to be this way when the API + was designed, but as of Apache 1.x this is the only way + mod_rewrite can operate. To make this point more clear + remember the following two points:

    + +
      +
    1. Although mod_rewrite rewrites URLs to URLs, URLs to + filenames and even filenames to filenames, the API + currently provides only a URL-to-filename hook. In Apache + 2.0 the two missing hooks will be added to make the + processing more clear. But this point has no drawbacks for + the user, it is just a fact which should be remembered: + Apache does more in the URL-to-filename hook than the API + intends for it.
    2. + +
    3. + Unbelievably mod_rewrite provides URL manipulations in + per-directory context, i.e., within + .htaccess files, although these are reached + a very long time after the URLs have been translated to + filenames. It has to be this way because + .htaccess files live in the filesystem, so + processing has already reached this stage. In other + words: According to the API phases at this time it is too + late for any URL manipulations. To overcome this chicken + and egg problem mod_rewrite uses a trick: When you + manipulate a URL/filename in per-directory context + mod_rewrite first rewrites the filename back to its + corresponding URL (which is usually impossible, but see + the RewriteBase directive below for the + trick to achieve this) and then initiates a new internal + sub-request with the new URL. This restarts processing of + the API phases. + +

      Again mod_rewrite tries hard to make this complicated + step totally transparent to the user, but you should + remember here: While URL manipulations in per-server + context are really fast and efficient, per-directory + rewrites are slow and inefficient due to this chicken and + egg problem. But on the other hand this is the only way + mod_rewrite can provide (locally restricted) URL + manipulations to the average user.

      +
    4. +
    + +

    Don't forget these two points!

    +
    top
    +
    +

    Ruleset Processing

    + +

    Now when mod_rewrite is triggered in these two API phases, it + reads the configured rulesets from its configuration + structure (which itself was either created on startup for + per-server context or during the directory walk of the Apache + kernel for per-directory context). Then the URL rewriting + engine is started with the contained ruleset (one or more + rules together with their conditions). The operation of the + URL rewriting engine itself is exactly the same for both + configuration contexts. Only the final result processing is + different.

    + +

    The order of rules in the ruleset is important because the + rewriting engine processes them in a special (and not very + obvious) order. The rule is this: The rewriting engine loops + through the ruleset rule by rule (RewriteRule directives) and + when a particular rule matches it optionally loops through + existing corresponding conditions (RewriteCond + directives). For historical reasons the conditions are given + first, and so the control flow is a little bit long-winded. See + Figure 1 for more details.

    +

    + [Needs graphics capability to display]
    + Figure 1:The control flow through the rewriting ruleset +

    +

    As you can see, first the URL is matched against the + Pattern of each rule. When it fails mod_rewrite + immediately stops processing this rule and continues with the + next rule. If the Pattern matches, mod_rewrite looks + for corresponding rule conditions. If none are present, it + just substitutes the URL with a new value which is + constructed from the string Substitution and goes on + with its rule-looping. But if conditions exist, it starts an + inner loop for processing them in the order that they are + listed. For conditions the logic is different: we don't match + a pattern against the current URL. Instead we first create a + string TestString by expanding variables, + back-references, map lookups, etc. and then we try + to match CondPattern against it. If the pattern + doesn't match, the complete set of conditions and the + corresponding rule fails. If the pattern matches, then the + next condition is processed until no more conditions are + available. If all conditions match, processing is continued + with the substitution of the URL with + Substitution.

    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/rewrite/rewrite_tech.xml b/trunk/docs/manual/rewrite/rewrite_tech.xml new file mode 100644 index 0000000000..c83eba07b7 --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_tech.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + Apache mod_rewrite Technical Details + + +

    This document discusses some of the technical details of mod_rewrite +and URL matching.

    +
    +Module +documentation +mod_rewrite +introduction +Practical solutions to common +problems +Practical solutions to +advanced problems + +
    Internal Processing + +

    The internal processing of this module is very complex but + needs to be explained once even to the average user to avoid + common mistakes and to let you exploit its full + functionality.

    +
    + +
    API Phases + +

    First you have to understand that when Apache processes a + HTTP request it does this in phases. A hook for each of these + phases is provided by the Apache API. Mod_rewrite uses two of + these hooks: the URL-to-filename translation hook which is + used after the HTTP request has been read but before any + authorization starts and the Fixup hook which is triggered + after the authorization phases and after the per-directory + config files (.htaccess) have been read, but + before the content handler is activated.

    + +

    So, after a request comes in and Apache has determined the + corresponding server (or virtual server) the rewriting engine + starts processing of all mod_rewrite directives from the + per-server configuration in the URL-to-filename phase. A few + steps later when the final data directories are found, the + per-directory configuration directives of mod_rewrite are + triggered in the Fixup phase. In both situations mod_rewrite + rewrites URLs either to new URLs or to filenames, although + there is no obvious distinction between them. This is a usage + of the API which was not intended to be this way when the API + was designed, but as of Apache 1.x this is the only way + mod_rewrite can operate. To make this point more clear + remember the following two points:

    + +
      +
    1. Although mod_rewrite rewrites URLs to URLs, URLs to + filenames and even filenames to filenames, the API + currently provides only a URL-to-filename hook. In Apache + 2.0 the two missing hooks will be added to make the + processing more clear. But this point has no drawbacks for + the user, it is just a fact which should be remembered: + Apache does more in the URL-to-filename hook than the API + intends for it.
    2. + +
    3. + Unbelievably mod_rewrite provides URL manipulations in + per-directory context, i.e., within + .htaccess files, although these are reached + a very long time after the URLs have been translated to + filenames. It has to be this way because + .htaccess files live in the filesystem, so + processing has already reached this stage. In other + words: According to the API phases at this time it is too + late for any URL manipulations. To overcome this chicken + and egg problem mod_rewrite uses a trick: When you + manipulate a URL/filename in per-directory context + mod_rewrite first rewrites the filename back to its + corresponding URL (which is usually impossible, but see + the RewriteBase directive below for the + trick to achieve this) and then initiates a new internal + sub-request with the new URL. This restarts processing of + the API phases. + +

      Again mod_rewrite tries hard to make this complicated + step totally transparent to the user, but you should + remember here: While URL manipulations in per-server + context are really fast and efficient, per-directory + rewrites are slow and inefficient due to this chicken and + egg problem. But on the other hand this is the only way + mod_rewrite can provide (locally restricted) URL + manipulations to the average user.

      +
    4. +
    + +

    Don't forget these two points!

    +
    + +
    Ruleset Processing + +

    Now when mod_rewrite is triggered in these two API phases, it + reads the configured rulesets from its configuration + structure (which itself was either created on startup for + per-server context or during the directory walk of the Apache + kernel for per-directory context). Then the URL rewriting + engine is started with the contained ruleset (one or more + rules together with their conditions). The operation of the + URL rewriting engine itself is exactly the same for both + configuration contexts. Only the final result processing is + different.

    + +

    The order of rules in the ruleset is important because the + rewriting engine processes them in a special (and not very + obvious) order. The rule is this: The rewriting engine loops + through the ruleset rule by rule (RewriteRule directives) and + when a particular rule matches it optionally loops through + existing corresponding conditions (RewriteCond + directives). For historical reasons the conditions are given + first, and so the control flow is a little bit long-winded. See + Figure 1 for more details.

    +

    + [Needs graphics capability to display]
    + Figure 1:The control flow through the rewriting ruleset +

    +

    As you can see, first the URL is matched against the + Pattern of each rule. When it fails mod_rewrite + immediately stops processing this rule and continues with the + next rule. If the Pattern matches, mod_rewrite looks + for corresponding rule conditions. If none are present, it + just substitutes the URL with a new value which is + constructed from the string Substitution and goes on + with its rule-looping. But if conditions exist, it starts an + inner loop for processing them in the order that they are + listed. For conditions the logic is different: we don't match + a pattern against the current URL. Instead we first create a + string TestString by expanding variables, + back-references, map lookups, etc. and then we try + to match CondPattern against it. If the pattern + doesn't match, the complete set of conditions and the + corresponding rule fails. If the pattern matches, then the + next condition is processed until no more conditions are + available. If all conditions match, processing is continued + with the substitution of the URL with + Substitution.

    + +
    + + +
    + diff --git a/trunk/docs/manual/rewrite/rewrite_tech.xml.meta b/trunk/docs/manual/rewrite/rewrite_tech.xml.meta new file mode 100644 index 0000000000..afe8c36e2b --- /dev/null +++ b/trunk/docs/manual/rewrite/rewrite_tech.xml.meta @@ -0,0 +1,11 @@ + + + + rewrite_tech + /rewrite/ + .. + + + en + + diff --git a/trunk/docs/manual/sections.html b/trunk/docs/manual/sections.html new file mode 100644 index 0000000000..02645f01bf --- /dev/null +++ b/trunk/docs/manual/sections.html @@ -0,0 +1,11 @@ +URI: sections.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: sections.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: sections.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/sections.html.en b/trunk/docs/manual/sections.html.en new file mode 100644 index 0000000000..cb150c8441 --- /dev/null +++ b/trunk/docs/manual/sections.html.en @@ -0,0 +1,458 @@ + + + +Configuration Sections - Apache HTTP Server + + + + + +
    <-
    +

    Configuration Sections

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +

    Directives in the configuration files may apply to the +entire server, or they may be restricted to apply only to particular +directories, files, hosts, or URLs. This document describes how to +use configuration section containers or .htaccess files +to change the scope of other configuration directives.

    +
    + +
    top
    +
    +

    Types of Configuration Section Containers

    + + + +

    There are two basic types of containers. Most containers are +evaluated for each request. The enclosed directives are applied only +for those requests that match the containers. The <IfDefine> and <IfModule> containers, on the +other hand, are evaluated only at server startup and restart. If +their conditions are true at startup, then the enclosed directives +will apply to all requests. If the conditions are not true, the +enclosed directives will be ignored.

    + +

    The <IfDefine> directive +encloses directives that will only be applied if an appropriate +parameter is defined on the httpd command line. For example, +with the following configuration, all requests will be redirected +to another site only if the server is started using +httpd -DClosedForNow:

    + +

    +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +

    + +

    The <IfModule> +directive is very similar, except it encloses directives that will +only be applied if a particular module is available in the server. +The module must either be statically compiled in the server, or it +must be dynamically compiled and its LoadModule line must be earlier in the +configuration file. This directive should only be used if you need +your configuration file to work whether or not certain modules are +installed. It should not be used to enclose directives that you want +to work all the time, because it can suppress useful error messages +about missing modules.

    + +

    In the following example, the MimeMagicFiles directive will be +applied only if mod_mime_magic is available.

    + +

    +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +

    + +

    Both <IfDefine> +and <IfModule> +can apply negative conditions by preceding their test with "!". +Also, these sections can be nested to achieve more complex +restrictions.

    +
    top
    +
    +

    Filesystem and Webspace

    + +

    The most commonly used configuration section containers are the +ones that change the configuration of particular places in the +filesystem or webspace. First, it is important to understand the +difference between the two. The filesystem is the view of your disks +as seen by your operating system. For example, in a default install, +Apache resides at /usr/local/apache2 in the Unix +filesystem or "c:/Program Files/Apache Group/Apache2" in +the Windows filesystem. (Note that forward slashes should always be +used as the path separator in Apache, even for Windows.) In contrast, +the webspace is the view of your site as delivered by the web server +and seen by the client. So the path /dir/ in the +webspace corresponds to the path +/usr/local/apache2/htdocs/dir/ in the filesystem of a +default Apache install on Unix. The webspace need not map directly to +the filesystem, since webpages may be generated dynamically +from databases or other locations.

    + +

    Filesystem Containers

    + +

    The <Directory> +and <Files> +directives, along with their regex counterparts, apply directives to +parts of the filesystem. Directives enclosed in a <Directory> section apply to +the named filesystem directory and all subdirectories of that +directory. The same effect can be obtained using .htaccess files. For example, in the +following configuration, directory indexes will be enabled for the +/var/web/dir1 directory and all subdirectories.

    + +

    +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +

    + +

    Directives enclosed in a <Files> section apply to any file with +the specified name, regardless of what directory it lies in. +So for example, the following configuration directives will, +when placed in the main section of the configuration file, +deny access to any file named private.html regardless +of where it is found.

    + +

    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +

    + +

    To address files found in a particular part of the filesystem, the +<Files> and +<Directory> sections +can be combined. For example, the following configuration will deny +access to /var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html, and any other instance +of private.html found under the /var/web/dir1/ +directory.

    + +

    +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +

    + + +

    Webspace Containers

    + +

    The <Location> +directive and its regex counterpart, on the other hand, change the +configuration for content in the webspace. For example, the following +configuration prevents access to any URL-path that begins in /private. +In particular, it will apply to requests for +http://yoursite.example.com/private, +http://yoursite.example.com/private123, and +http://yoursite.example.com/private/dir/file.html as well +as any other requests starting with the /private string.

    + +

    +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +

    + +

    The <Location> +directive need not have anything to do with the filesystem. +For example, the following example shows how to map a particular +URL to an internal Apache handler provided by mod_status. +No file called server-status needs to exist in the +filesystem.

    + +

    +<Location /server-status>
    +SetHandler server-status
    +</Location> +

    + + +

    Wildcards and Regular Expressions

    + +

    The <Directory>, +<Files>, and +<Location> +directives can each use shell-style wildcard characters as in +fnmatch from the C standard library. The character "*" +matches any sequence of characters, "?" matches any single character, +and "[seq]" matches any character in seq. The "/" +character will not be matched by any wildcard; it must be specified +explicitly.

    + +

    If even more flexible matching is required, each +container has a regular-expression (regex) counterpart <DirectoryMatch>, <FilesMatch>, and <LocationMatch> that allow +perl-compatible +regular expressions +to be used in choosing the matches. But see the section below on +configuration merging to find out how using regex sections will change +how directives are applied.

    + +

    A non-regex wildcard section that changes the configuration of +all user directories could look as follows:

    + +

    +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +

    + +

    Using regex sections, we can deny access to many types of image files +at once:

    +

    +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +

    + + + +

    What to use When

    + +

    Choosing between filesystem containers and webspace containers is +actually quite easy. When applying directives to objects that reside +in the filesystem always use <Directory> or <Files>. When applying directives to objects +that do not reside in the filesystem (such as a webpage generated from +a database), use <Location>.

    + +

    It is important to never use <Location> when trying to restrict +access to objects in the filesystem. This is because many +different webspace locations (URLs) could map to the same filesystem +location, allowing your restrictions to be circumvented. +For example, consider the following configuration:

    + +

    +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +

    + +

    This works fine if the request is for +http://yoursite.example.com/dir/. But what if you are on +a case-insensitive filesystem? Then your restriction could be easily +circumvented by requesting +http://yoursite.example.com/DIR/. The <Directory> directive, in +contrast, will apply to any content served from that location, +regardless of how it is called. (An exception is filesystem links. +The same directory can be placed in more than one part of the +filesystem using symbolic links. The <Directory> directive will follow the symbolic +link without resetting the pathname. Therefore, for the highest level +of security, symbolic links should be disabled with the appropriate +Options directive.)

    + +

    If you are, perhaps, thinking that none of this applies to you +because you use a case-sensitive filesystem, remember that there are +many other ways to map multiple webspace locations to the same +filesystem location. Therefore you should always use the filesystem +containers when you can. There is, however, one exception to this +rule. Putting configuration restrictions in a <Location +/> section is perfectly safe because this section will apply +to all requests regardless of the specific URL.

    + + +
    top
    +
    +

    Virtual Hosts

    + +

    The <VirtualHost> +container encloses directives that apply to specific hosts. +This is useful when serving multiple hosts from the same machine +with a different configuration for each. For more information, +see the Virtual Host Documentation.

    +
    top
    +
    +

    Proxy

    + +

    The <Proxy> +and <ProxyMatch> +containers apply enclosed configuration directives only +to sites accessed through mod_proxy's proxy server +that match the specified URL. For example, the following configuration +will prevent the proxy server from being used to access the +cnn.com website.

    + +

    +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +

    +
    top
    +
    +

    What Directives are Allowed?

    + +

    To find out what directives are allowed in what types of +configuration sections, check the Context of the directive. +Everything that is allowed in +<Directory> +sections is also syntactically allowed in +<DirectoryMatch>, +<Files>, +<FilesMatch>, +<Location>, +<LocationMatch>, +<Proxy>, +and <ProxyMatch> +sections. There are some exceptions, however:

    + + +
    top
    +
    +

    How the sections are merged

    + +

    The configuration sections are applied in a very particular order. +Since this can have important effects on how configuration directives +are interpreted, it is important to understand how this works.

    + +

    The order of merging is:

    + +
      +
    1. <Directory> (except regular expressions) + and .htaccess done simultaneously (with + .htaccess, if allowed, overriding + <Directory>)
    2. + +
    3. <DirectoryMatch> + (and <Directory ~>)
    4. + +
    5. <Files> and <FilesMatch> done + simultaneously
    6. + +
    7. <Location> + and <LocationMatch> done simultaneously
    8. +
    + +

    Apart from <Directory>, each group is processed in + the order that they appear in the configuration files. <Directory> (group 1 above) + is processed in the order shortest directory component to longest. + So for example, <Directory /var/web/dir> will + be processed before <Directory + /var/web/dir/subdir>. If multiple <Directory> sections apply + to the same directory they are processed in the configuration file + order. Configurations included via the Include directive will be treated as if + they were inside the including file at the location of the + Include directive.

    + +

    Sections inside <VirtualHost> sections + are applied after the corresponding sections outside + the virtual host definition. This allows virtual hosts to + override the main server configuration.

    + +

    When the request is served by mod_proxy, the + <Proxy> + container takes the place of the <Directory> container in the processing + order.

    + +

    Later sections override earlier ones.

    + +

    Technical Note

    + There is actually a + <Location>/<LocationMatch> + sequence performed just before the name translation phase + (where Aliases and DocumentRoots + are used to map URLs to filenames). The results of this + sequence are completely thrown away after the translation has + completed. +
    + +

    Some Examples

    + +

    Below is an artificial example to show the order of +merging. Assuming they all apply to the request, the directives in +this example will be applied in the order A > B > C > D > +E.

    + +

    +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +

    + +

    For a more concrete example, consider the following. Regardless of +any access restrictions placed in <Directory> sections, the <Location> section will be +evaluated last and will allow unrestricted access to the server. In +other words, order of merging is important, so be careful!

    + +

    +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# Woops! This <Directory> section will have no effect
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +

    + + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sections.html.ja.euc-jp b/trunk/docs/manual/sections.html.ja.euc-jp new file mode 100644 index 0000000000..bd3fc3e18a --- /dev/null +++ b/trunk/docs/manual/sections.html.ja.euc-jp @@ -0,0 +1,466 @@ + + + +¥»¥¯¥·¥ç¥ó¤ÎÀßÄê - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥»¥¯¥·¥ç¥ó¤ÎÀßÄê

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +

    ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +¥µ¡¼¥ÐÁ´ÂΤËŬÍѤµ¤ì¤¿¤ê¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥Õ¥¡¥¤¥ë¡¢¥Û¥¹¥È¡¢URL ¤Ë¤Î¤ß +ŬÍѤµ¤ì¤ë¤è¤¦¤ËÀ©¸Â¤·¤¿¤ê¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Îʸ½ñ¤ÏÀßÄêÍѤΥ»¥¯¥·¥ç¥ó¤Î +¥³¥ó¥Æ¥Ê¤ä .htaccess ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¾¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î +¥¹¥³¡¼¥×¤òÊѹ¹¤¹¤ëÊýË¡¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ÀßÄêÍÑ¥»¥¯¥·¥ç¥ó¥³¥ó¥Æ¥Ê¤Î¼ïÎà

    + + + +

    ¥³¥ó¥Æ¥Ê¤Ë¤ÏÆó¤Ä¤Î´ðËܤȤʤë¼ïÎब¤¢¤ê¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¥³¥ó¥Æ¥Ê¤Ï +³Æ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æɾ²Á¤µ¤ì¤Þ¤¹¡£¤½¤Î¾ì¹ç¡¢¥³¥ó¥Æ¥ÊÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +¥³¥ó¥Æ¥Ê¤Ë¥Þ¥Ã¥Á¤¹¤ë¥ê¥¯¥¨¥¹¥È¤Ë¤Î¤ßŬÍѤµ¤ì¤Þ¤¹¡£ +°ìÊý¡¢<IfDefine> ¥³¥ó¥Æ¥Ê¤È <IfModule> ¥³¥ó¥Æ¥Ê¤Ï +¥µ¡¼¥Ð¤Îµ¯Æ°»þ¤ÈºÆµ¯Æ°»þ¤Ë¤Î¤ßɾ²Á¤µ¤ì¤Þ¤¹¡£µ¯Æ°»þ¤Ë¾ò·ï¤¬¿¿¤Ç¤¢¤ì¤Ð¡¢ +¥³¥ó¥Æ¥ÊÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ËŬÍѤµ¤ì¤Þ¤¹¡£¾ò·ï¤¬ +µ¶¤Ç¤¢¤ì¤Ð¡¢¥³¥ó¥Æ¥ÊÃæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£

    + +

    <IfDefine> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +httpd ¥³¥Þ¥ó¥É¥é¥¤¥ó¤ÇŬÀڤʥѥé¥á¡¼¥¿¤¬ÄêµÁ¤µ¤ì¤¿¤È¤­¤Ë¤Î¤ß +ŬÍѤµ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤¤¤Þ¤¹¡£Î㤨¤Ð¼¡¤ÎÀßÄê¤Ç¤Ï¡¢¥µ¡¼¥Ð¤¬ +httpd -DClosedForNow ¤ò»È¤Ã¤Æµ¯Æ°¤µ¤ì¤¿¤È¤­¤À¤±¤¹¤Ù¤Æ¤Î +¥ê¥¯¥¨¥¹¥È¤òÊ̤Υµ¥¤¥È¤Ë¥ê¥À¥¤¥ì¥¯¥È¤·¤Þ¤¹:

    + +

    +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +

    + +

    <IfModule> ¤Ï +Èó¾ï¤Ë»÷¤Æ¤¤¤Þ¤¹¤¬¡¢Âå¤ï¤ê¤Ë¥µ¡¼¥Ð¾å¤Ç¥â¥¸¥å¡¼¥ë¤¬»ÈÍѲÄǽ¤Ê¾ì¹ç¤Ë¤Î¤ß +ŬÍѲÄǽ¤Ê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤¤¤Þ¤¹¡£¥â¥¸¥å¡¼¥ë¤Ï¥µ¡¼¥Ð¤Ë +ÀÅŪ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¡¢Æ°Åª¤ËÁȤ߹þ¤à¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Æ¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Ç +LoadModule ¤Î¹Ô¤¬¤è¤êÁ°¤Î +Éôʬ¤Ë½ñ¤«¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÆÃÄê¤Î¥â¥¸¥å¡¼¥ë¤Î +¸ºß¤Ë´Ø¤ï¤é¤ºÀßÄê¥Õ¥¡¥¤¥ë¤¬Æ°ºî¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Î¤ß»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£ +¾ï¤ËÆ°ºî¤·¤ÆÍߤ·¤¤¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò°Ï¤à¤¿¤á¤Ë»È¤¦¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ +¸ºß¤·¤Ê¤¤¥â¥¸¥å¡¼¥ë¤Ë´Ø¤¹¤ëÍ­ÍѤʥ¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ÎȯÀ¸¤òÍÞÀ©¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¤Î¤Ç¡£ +

    + +

    ¼¡¤ÎÎã¤Ç¤Ï¡¢mod_mime_magic ¤¬¤¢¤ë¤È¤­¤Ë¤Î¤ß MimeMagicFiles ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ +ŬÍѤµ¤ì¤Þ¤¹¡£

    + +

    +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +

    + +

    <IfDefine> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È +<IfModule> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +¥Æ¥¹¥È¤ÎÁ°¤Ë "!" ¤òÉÕ¤±¤ë¤³¤È¤ÇÈÝÄê¤Î¾ò·ï¤òŬÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +¤Þ¤¿¡¢¤³¤ì¤é¤Î¥»¥¯¥·¥ç¥ó¤Ï¤è¤êÊ£»¨¤ÊÀ©¸Â¤ò²Ý¤¹¤¿¤á¤ËÆþ¤ì»Ò¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +

    +
    top
    +
    +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤È¥¦¥§¥Ö¶õ´Ö

    + +

    ºÇ¤â¤è¤¯»È¤ï¤ì¤ëÀßÄê¤Î¥»¥¯¥·¥ç¥ó¥³¥ó¥Æ¥Ê¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ä¥¦¥§¥Ö¶õ´Ö¤Î +ÆÃÄê¤Î¾ì½ê¤ÎÀßÄê¤òÊѹ¹¤¹¤ë¤â¤Î¤Ç¤¹¡£¤Þ¤º¡¢¤³¤ÎÆó¤Ä¤Î°ã¤¤¤òÍý²ò¤¹¤ë¤³¤È¤¬ +ÂçÀڤǤ¹¡£¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ï¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤«¤é¸«¤¿¥Ç¥£¥¹¥¯¤ÎÆâÍƤǤ¹¡£ +¤¿¤È¤¨¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤Ï Apache ¤Ï Unix ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ç¤Ï +/usr/local/apache2 ¤Ë¡¢Windows ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ç¤Ï +"c:/Program Files/Apache Group/Apache2" ¤Ë¸ºß¤·¤Þ¤¹¡£ +(Apache ¤Ç¤Ï Windows ¤Ç¤â¥Ñ¥¹¥»¥Ñ¥ì¡¼¥¿¤È¤·¤Æ¥¹¥é¥Ã¥·¥å¤ò»È¤¦¤³¤È¤Ë +µ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£) ÂоÈŪ¤Ë¡¢¥¦¥§¥Ö¶õ´Ö¤Ï¤¢¤Ê¤¿¤Î¥µ¥¤¥È¤ò +¥¦¥§¥Ö¥µ¡¼¥Ð¤«¤éÇÛ¿®¤µ¤ì¤ë¤â¤Î¤È¤·¤Æ¸«¤¿¤â¤Î¤Ç¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ë¸«¤¨¤ë¤â¤Î¤Ç¤¹¡£ +¥Ç¥Õ¥©¥ë¥È¤Î Unix ¾å¤Î Apache ¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤Ï¥¦¥§¥Ö¶õ´Ö¤Î +/dir/ ¤È¤¤¤¦¥Ñ¥¹¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î +/usr/local/apache2/htdocs/dir/ ¤È¤¤¤¦¥Ñ¥¹¤ËÂбþ¤·¤Þ¤¹¡£ +¥¦¥§¥Ö¥Ú¡¼¥¸¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹¤ä¾¤Î¾ì½ê¤«¤éưŪ¤ËÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤Î¤Ç¡¢ +¥¦¥§¥Ö¶õ´Ö¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ËľÀܥޥåפ¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£

    + +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥³¥ó¥Æ¥Ê

    + +

    <Directory> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È +<Files> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢¤½¤ì¤È +¤½¤ì¤é¤ÎÀµµ¬É½¸½ÈǤϥǥ£¥ì¥¯¥Æ¥£¥Ö¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î°ìÉôʬ¤ËÂФ·¤ÆŬÍѤ·¤Þ¤¹¡£ +<Directory> ¥»¥¯¥·¥ç¥ó¤Î +Ãæ¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤Î¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤Ë +ŬÍѤµ¤ì¤Þ¤¹¡£.htaccess ¥Õ¥¡¥¤¥ë¤ò +»È¤¦¤³¤È¤Ç¤âƱ¤¸¸ú²Ì¤òÆÀ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢¼¡¤ÎÀßÄê¤Ç¤Ï +/var/web/dir1 ¤È¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËÂФ·¤Æ +¥Ç¥£¥ì¥¯¥È¥ê¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£

    + +

    +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +

    + +

    <Files> ¥»¥¯¥·¥ç¥ó¤Î +Ãæ¤Ë¤¢¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤É¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë¤«¤Ë´Ø¤ï¤é¤º¡¢»ØÄꤵ¤ì¤¿Ì¾Á°¤Î +¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë¤ËŬÍѤµ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤éÎ㤨¤Ð°Ê²¼¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ +ÀßÄê¥Õ¥¡¥¤¥ë¤Î¼ç¥»¥¯¥·¥ç¥ó¤Ë½ñ¤«¤ì¤¿¤È¤­¤Ë¤Ï¡¢¤¹¤Ù¤Æ¤Î¾ì½ê¤Î +private.html ¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î¥¢¥¯¥»¥¹¤òµñÈݤ·¤Þ¤¹¡£

    + +

    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +

    + +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎÆÃÄê¤Î¾ì½ê¤Ë¤¢¤ë¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¤¿¤á¤Ë¡¢ +<Files> ¥»¥¯¥·¥ç¥ó¤È +<Directory> ¥»¥¯¥·¥ç¥ó¤ò +ÁȤ߹ç¤ï¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Î㤨¤Ð¡¢¼¡¤ÎÀßÄê¤Ç¤Ï +/var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html ¤Ê¤É¡¢ +/var/web/dir1/ ¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤¢¤ë¤¹¤Ù¤Æ¤Î +private.html ¤Ø¤Î¥¢¥¯¥»¥¹¤òµñÈݤ·¤Þ¤¹¡£

    + +

    +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +

    + + +

    ¥¦¥§¥Ö¶õ´Ö¥³¥ó¥Æ¥Ê

    + +

    °ìÊý¡¢<Location> +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¤½¤ÎÀµµ¬É½¸½ÈǤϥ¦¥§¥Ö¶õ´Ö¾å¤ÎÆâÍƤËÂФ·¤ÆÀßÄê¤òÊѹ¹¤·¤Þ¤¹¡£ +¤¿¤È¤¨¤Ð¡¢¼¡¤ÎÀßÄê¤Ç¤Ï /private ¤Ç»Ï¤Þ¤ë URL ¥Ñ¥¹¤Ø¤Î¥¢¥¯¥»¥¹¤òÀ©¸Â¤·¤Þ¤¹¡£ +¶ñÂÎŪ¤Ë¤Ï¡¢ +http://yoursite.example.com/private, +http://yoursite.example.com/private123, +http://yoursite.example.com/private/dir/file.html +¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ä¡¢ +¾¤ÎƱÍÍ¤Ë /private ʸ»úÎó¤Ç»Ï¤Þ¤ë¥ê¥¯¥¨¥¹¥È¤Ë +ŬÍѤµ¤ì¤Þ¤¹¡£

    + +

    +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +

    + +

    <Location> +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤È´Ø·¸¤¢¤ëɬÍפ¬Á´¤¯¤¢¤ê¤Þ¤»¤ó¡£ +¤¿¤È¤¨¤Ð¼¡¤ÎÎã¤Ç¤Ï¡¢¤É¤Î¤è¤¦¤Ë¤·¤ÆÆÃÄê¤Î URL ¤ò +mod_status¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë Apache +ÆâÉô¥Ï¥ó¥É¥é¤Ë¥Þ¥Ã¥×¤¹¤ë¤«¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë +server-status ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£

    + +

    +<Location /server-status>
    +SetHandler server-status
    +</Location> +

    + + +

    ¥ï¥¤¥ë¥É¥«¡¼¥É¤ÈÀµµ¬É½¸½

    + +

    <Directory>, +<Files>, +<Location> +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¤Ï¡¢ C ɸ½à¥é¥¤¥Ö¥é¥ê¤Î fnmatch ¤Î¤è¤¦¤Ë +shell ¥¹¥¿¥¤¥ë¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¥­¥ã¥é¥¯¥¿¤¬»ÈÍѤǤ­¤Þ¤¹¡£ +"*" ʸ»ú¤ÏǤ°Õ¤Îʸ»úÎó¤Ë¥Þ¥Ã¥Á¤·¡¢"?" ʸ»ú¤ÏǤ°Õ¤Î 1 ʸ»ú¤Ë¥Þ¥Ã¥Á¤·¡¢ +"[seq]" ¤Ï seq ¤ÎǤ°Õ¤Îʸ»ú¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¡£ +"/" ʸ»ú¤Ï¤É¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¤Ç¤â¥Þ¥Ã¥Á¤µ¤ì¤Þ¤»¤ó¡£ +ÌÀ¼¨Åª¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¤³¤ì¤è¤ê½ÀÆð¤Ê¥Þ¥Ã¥Á¥ó¥°¤¬É¬Íפʾì¹ç¤Ï¡¢¤³¤ì¤é¤Î¥³¥ó¥Æ¥Ê¤ËÀµµ¬É½¸½ +(regex) ÈǤǤ¢¤ë +<DirectoryMatch>, +<FilesMatch>, +<LocationMatch> +¤¬¤¢¤ê¡¢¥Þ¥Ã¥Á¤òÁªÂò¤¹¤ë¤Î¤Ë perl ¸ß´¹Àµµ¬É½¸½¤ò»ÈÍѤǤ­¤Þ¤¹¡£¤·¤«¤·¡¢¼¡¤ÎÀßÄê¤Î¥Þ¡¼¥¸¤ËÌܤòÄ̤·¤Æ¡¢ +regex ¥»¥¯¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎŬÍѤ¬¤É¤Î¤è¤¦¤Ë +ÊѲ½¤¹¤ë¤«ÇÄ°®¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Á´¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê¤ÎÀßÄê¤òÊѹ¹¤¹¤ë¡¢Èó regex +¥ï¥¤¥ë¥É¥«¡¼¥É¥»¥¯¥·¥ç¥ó¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +

    + +

    regex ¥»¥¯¥·¥ç¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¡¢²èÁü¥Õ¥¡¥¤¥ë¤Î¿¤¯¤Î¥¿¥¤¥×¤ËÂФ¹¤ë +¥¢¥¯¥»¥¹¤ò°ìÅ٤˵ñÈݤǤ­¤Þ¤¹¡£

    +

    +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +

    + + + +

    ¤¤¤Ä²¿¤ò»È¤¦¤«

    + +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥³¥ó¥Æ¥Ê¤È¥¦¥§¥Ö¶õ´Ö¥³¥ó¥Æ¥Ê¤ò»È¤¤Ê¬¤±¤ë¤Î¤Ï¡¢ +¼ÂºÝ¤Ë¤ÏÈó¾ï¤Ë´Êñ¤Ç¤¹¡£¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë +¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬ±þ¤¹¤ë¾ì¹ç¤Ï¡¢É¬¤º +<Directory> ¤« +<Files> +¤ò»ÈÍѤ·¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë°Í¸¤·¤Ê¤¤¥ª¥Ö¥¸¥§¥¯¥È +(¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤éÀ¸À®¤µ¤ì¤ë¥¦¥§¥Ö¥Ú¡¼¥¸¤Ê¤É) +¤Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òŬÍѤ¹¤ëºÝ¤Ë¤Ï¡¢ +<Location> +¤ò»ÈÍѤ·¤Þ¤¹¡£

    + +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥¢¥¯¥»¥¹¤òÀ©¸Â¤¹¤ë¤¿¤á¤Ë¡¢ +<Location> +¤ò·è¤·¤Æ»ÈÍѤʤ¤¤è¤¦¤Ë¤·¤Þ¤·¤ç¤¦¡£ +Ʊ°ì¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à°ÌÃ֤˥ޥåפ·¤Æ¤¤¤ë¡¢¥¦¥§¥Ö¶õ´Ö°ÌÃÖ (URL) +¤¬Â¿¿ô¤¢¤Ã¤Æ¡¢ÀßÄꤷ¤¿À©¸Â¤ò±ª²ó¤µ¤ì¤Æ¤·¤Þ¤¦¤«¤â¤·¤ì¤Ê¤¤¤«¤é¤Ç¤¹¡£ +Î㤨¤Ð¼¡¤ÎÀßÄê¤ò¹Í¤¨¤Æ¤ß¤Þ¤·¤ç¤¦¡£

    + +

    +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +

    + +

    http://yoursite.example.com/dir/ +¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ç¤Ï¾å¼ê¤¯Æ°ºî¤·¤Þ¤¹¡£¤·¤«¤·Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤ +¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò»È¤Ã¤Æ¤¤¤¿¤é¤É¤¦¤Ê¤ë¤Ç¤·¤ç¤¦? +http://yoursite.example.com/DIR/ +¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ç´Êñ¤Ë¥¢¥¯¥»¥¹À©¸Â¤ò±ª²ó¤µ¤ì¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¤³¤ì¤ËÂФ·¤Æ +<Directory> +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤È¡¢¤É¤Î¤è¤¦¤Ë¸Æ¤Ó½Ð¤µ¤ì¤¿¤«¤Ë´Ø¤ï¤é¤º +¤½¤Î¾ì½ê¤«¤éÄ󶡤µ¤ì¤ëÆâÍƤËŬÍѤµ¤ì¤Þ¤¹¡£ +(Îã³°¤Ï¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¥ê¥ó¥¯¤Ç¤¹¡£¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò»È¤Ã¤Æ¡¢ +Ʊ°ì¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òÊ£¿ô¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ËÀßÃ֤Ǥ­¤Þ¤¹¡£ +<Directory> +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ñ¥¹Ì¾¤ò¥ê¥»¥Ã¥È¤¹¤ë¤³¤È¤Ê¤¯¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò +é¤ê¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¹âÅ٤ʥ»¥­¥å¥ê¥Æ¥£¤¬Í׵ᤵ¤ì¤ë¾ì¹ç¤Ï¡¢ +ŬÀÚ¤Ë Options +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ·¤Æ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò̵¸ú¤Ë¤¹¤ë¤Ù¤­¤Ç¤¹¡£)

    + +

    Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤¹¤ë¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò»ÈÍѤ·¤Æ¤¤¤ë¤«¤é¾åµ­¤Î¤³¤È¤Ï +̵´Ø·¸¤À¤È»×¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢ +Ʊ°ì¤Î¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à°ÌÃÖ¤ËÊ£¿ô¤Î¥¦¥§¥Ö¶õ´Ö°ÌÃÖ¤ò¥Þ¥Ã¥×¤¹¤ëÊýË¡¤Ï¡¢ +¾¤Ë¤¤¤¯¤é¤Ç¤â¤¢¤ë¤È¤¤¤¦¤³¤È¤ò³Ð¤¨¤Æ¤¤¤Æ¤¯¤À¤µ¤¤¡£ +¤Ç¤¹¤«¤é¤Ç¤­¤ë¸Â¤ê¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥³¥ó¥Æ¥Ê¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£ +¤·¤«¤·¤Ê¤¬¤é°ì¤Ä¤À¤±Îã³°¤¬¤¢¤ê¤Þ¤¹¡£ +<Location /> ¥»¥¯¥·¥ç¥ó¤Ï¤É¤ó¤Ê URL +¤Ë¤â´Ø¤ï¤é¤ºÅ¬ÍѤµ¤ì¤ë¤Î¤Ç¡¢´°Á´¤Ë°ÂÁ´¤Ç¤¹¡£

    + + +
    top
    +
    +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    <VirtualHost> +¥³¥ó¥Æ¥Ê¤ÏÆÃÄê¤Î¥Û¥¹¥È¤ËŬÍѤ¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò³ÊǼ¤·¤Þ¤¹¡£ +°ìÂæ¤Î¥Þ¥·¥ó¤ÇÊ£¿ô¤Î¥Û¥¹¥È¤ò°Û¤Ê¤ëÀßÄê¤ÇÄ󶡤·¤¿¤¤¤È¤­¤ËÍ­ÍѤǤ¹¡£ +¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥É¥­¥å¥á¥ó¥È¤ò +¤´Í÷²¼¤µ¤¤¡£

    +
    top
    +
    +

    ¥×¥í¥¯¥·

    + +

    <Proxy> +¤È <ProxyMatch> +¥³¥ó¥Æ¥Ê¤Ï¡¢ÆÃÄê¤Î URL ¤Ë¥Þ¥Ã¥Á¤¹¤ë mod_proxy +¥×¥í¥¯¥·¥µ¡¼¥Ð¤ò·Ðͳ¤·¤Æ¥¢¥¯¥»¥¹¤·¤¿¥µ¥¤¥È¤ËÂФ·¤Æ¤Î¤ßŬÍѤµ¤ì¤ë +ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò³ÊǼ¤·¤Þ¤¹¡£Î㤨¤Ð¼¡¤ÎÀßÄê¤Ï¡¢cnn.com +¥¦¥§¥Ö¥µ¥¤¥È¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥×¥í¥¯¥·¥µ¡¼¥Ð¤ò +À©¸Â¤·¤Þ¤¹¡£

    + +

    +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +

    +
    top
    +
    +

    ¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»È¤¨¤ë¤Î?

    + +

    ¤É¤Î¥¿¥¤¥×¤ÎÀßÄꥻ¥¯¥·¥ç¥ó¤Ç¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»ÈÍѤǤ­¤ë¤«¤Ï¡¢ +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î Context +¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£ +<Directory> +¤Ç»ÈÍѲÄǽ¤Ê¤â¤Î¤ÏÁ´¤Æ¡¢Æ±ÍÍ¤Ë +<DirectoryMatch>, +<Files>, +<FilesMatch>, +<Location>, +<LocationMatch>, +<Proxy>, +<ProxyMatch> +¥»¥¯¥·¥ç¥ó¤Ç»ÈÍѲÄǽ¤Ç¤¹¡£¤·¤«¤·¤Ê¤¬¤é´ö¤Ä¤«Îã³°¤â¸ºß¤·¤Þ¤¹¡£

    + +
      +
    • AllowOverride ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +<Directory> +¥»¥¯¥·¥ç¥ó¤Ç¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
    • + +
    • FollowSymLinks ¤È SymLinksIfOwnerMatch ¤Î +Options ¤Ï¡¢ +<Directory> +¥»¥¯¥·¥ç¥ó¤« .htaccess ¥Õ¥¡¥¤¥ë¤Ç¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
    • + +
    • Options ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ +<Files> +¤È <FilesMatch> +¥»¥¯¥·¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó¡£
    • +
    +
    top
    +
    +

    ¥»¥¯¥·¥ç¥ó¤Î¥Þ¡¼¥¸ÊýË¡

    + +

    ¥Þ¡¼¥¸¤Î½çÈ֤ϰʲ¼¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹:

    + +
      +
    1. <Directory> (Àµµ¬É½¸½Ìµ¤·) ¤È + .htaccess ¤òƱ»þ¤Ë (.htaccess ¤¬µö²Ä¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤¬ + <Directory> ¤ò¾å½ñ¤­¤·¤Þ¤¹) +
    2. + +
    3. <DirectoryMatch> + (¤È <Directory ~>
    4. + +
    5. <Files> ¤È + <FilesMatch> ¤òƱ»þ¤Ë
    6. + +
    7. <Location> ¤È + <LocationMatch> ¤òƱ»þ¤Ë
    8. +
    + +

    <Directory> + °Ê³°¤Ï¡¢¤½¤ì¤¾¤ì¤Î¥°¥ë¡¼¥×¤ÏÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤¿½çÈ֤˽èÍý¤µ¤ì¤Þ¤¹¡£ + <Directory> (¾å¤Î¥°¥ë¡¼¥× 1) + ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤¬Ã»¤¤¤â¤Î¤«¤éŤ¤¤â¤Î¤Ø¤È½èÍý¤µ¤ì¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢ + Î㤨¤Ð <Directory /var/web/dir1> ¤Ï + <Directory /var/web/dir/subdir> ¤ÎÁ°¤Ë½èÍý¤µ¤ì¤Þ¤¹¡£Ê£¿ô¤Î + <Directory> ¥»¥¯¥·¥ç¥ó¤¬ + Ʊ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤Ë + ŬÍѤµ¤ì¤ë¾ì¹ç¤Ï¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î½çÈ֤˽¾¤Ã¤Æ½èÍý¤µ¤ì¤Þ¤¹¡£ + Include + ¤Ë¤è¤Ã¤ÆÁÞÆþ¤µ¤ì¤¿ÀßÄê¤Ï ÁÞÆþ¤·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Î + Include + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ÌÃ֤ˤ¢¤Ã¤¿¤«¤Î¤è¤¦¤Ë°·¤ï¤ì¤Þ¤¹¡£

    + +

    <VirtualHost> ¥»¥¯¥·¥ç¥óÃæ¤Î¥»¥¯¥·¥ç¥ó¤Ï + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÄêµÁ¤Î³°Â¦¤ÎÂбþ¤¹¤ë¥»¥¯¥·¥ç¥ó¤Î + ¸å¤ËŬÍѤµ¤ì¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬ + ¥á¥¤¥ó¤Î¥µ¡¼¥ÐÀßÄê¤ò¾å½ñ¤­¤Ç¤­¤ë¤è¤¦¤Ê¤ê¤Þ¤¹¡£

    + +

    mod_proxy ¤Ç¥ê¥¯¥¨¥¹¥È¤¬½èÍý¤µ¤ì¤ë¾ì¹ç¤Ï¡¢ + ½èÍý½çÈ֤Τ¦¤Á¡¢<Directory> ¥³¥ó¥Æ¥Ê¤ÎÉôʬ¤¬ + <Proxy> + ¥³¥ó¥Æ¥Ê¤Ë¼è¤Ã¤ÆÂå¤ï¤é¤ì¤Þ¤¹¡£

    + +

    ¸å¤Î¥»¥¯¥·¥ç¥ó¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬Á°¤Î¥»¥¯¥·¥ç¥ó¤Î¤â¤Î¤ò¾å½ñ¤­¤·¤Þ¤¹¡£

    + + +

    µ»½Ñ¥á¥â

    + ¼ÂºÝ¤Ë¤Ï¡¢Ì¾Á°¤òÊÑ´¹¤¹¤ëÃʳ¬ (URL + ¤ò¥Õ¥¡¥¤¥ë̾¤Ë¥Þ¥Ã¥×¤¹¤ë¤¿¤á¤Ë Alias ¤ä + DocumentRoot ¤¬»ÈÍѤµ¤ì¤ë¤È¤³¤í) ¤ÎľÁ°¤Ë + <Location>/<LocationMatch> + ¤¬¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + ¤³¤ì¤é¤òŬÍѤ·¤¿·ë²Ì¤ÏÊÑ´¹¤¬½ª¤ï¤Ã¤¿¸å¤Ë´°Á´¤Ë¼Î¤Æ¤é¤ì¤Þ¤¹¡£ +
    +

    Îã

    + +

    ¼¡¤Ï¥Þ¡¼¥¸¤Î½çÈÖ¤ò¼¨¤¹¤¿¤á¤Î×ó°ÕŪ¤ÊÎã¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ +¥ê¥¯¥¨¥¹¥ÈÁ´¤Æ¤ËŬÍѤµ¤ì¤ë¤È¤·¤Æ¡¢ËÜÎã¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +A > B > C > D > E ¤Î½çÈÖ¤ËŬÍѤµ¤ì¤Þ¤¹¡£

    + +

    +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +

    + +

    ¤â¤Ã¤È¶ñÂÎŪ¤Ê¡¢¼¡¤ÎÎã¤ò¹Í¤¨¤Æ¤ß¤Þ¤·¤ç¤¦¡£ +<Directory> +¥»¥¯¥·¥ç¥ó¤ËÀßÃÖ¤µ¤ì¤¿¥¢¥¯¥»¥¹À©¸Â¤Ë´Ø¤ï¤é¤º¡¢ +<Location> +¥»¥¯¥·¥ç¥ó¤¬ºÇ¸å¤Ëɾ²Á¤µ¤ì¤Æ¡¢¥µ¡¼¥Ð¤Ø¤Î¥¢¥¯¥»¥¹¤ÏÀ©¸Â¤µ¤ì¤Þ¤»¤ó¡£ +¸À¤¤´¹¤¨¤ì¤Ð¡¢¥Þ¡¼¥¸¤Î½çÈ֤ϽÅÍפǡ¢Ãí°Õ¤·¤Æ»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤!

    + +

    +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# Woops! This <Directory> section will have no effect
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +

    + + + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sections.html.ko.euc-kr b/trunk/docs/manual/sections.html.ko.euc-kr new file mode 100644 index 0000000000..9ead932ae6 --- /dev/null +++ b/trunk/docs/manual/sections.html.ko.euc-kr @@ -0,0 +1,422 @@ + + + +¼½¼Ç ¼³Á¤ - Apache HTTP Server + + + + + +
    <-
    +

    ¼½¼Ç ¼³Á¤

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    +

    ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â +Áö½Ã¾î´Â ¼­¹ö Àüü¿¡ Àû¿ëµÇ°Å³ª, ƯÁ¤ µð·ºÅ丮, ÆÄÀÏ, È£½ºÆ®, +URL¿¡¸¸ Àû¿ëµÉ ¼ö ÀÖ´Ù. ÀÌ ¹®¼­´Â ´Ù¸¥ Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ +Á¦ÇÑÇϱâÀ§ÇØ ¼³Á¤ ¼½¼ÇÀ̳ª .htaccess ÆÄÀÏÀ» +»ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¼³Á¤ ¼½¼ÇÀÇ Á¾·ù

    + + + +

    ¼½¼Ç¿¡´Â µÎ°¡Áö Á¾·ù°¡ ÀÖ´Ù. ´ëºÎºÐÀº ¸Å¿äû¸¶´Ù 󸮵ȴÙ. +ÇØ´çÇÏ´Â ¿äû¿¡¸¸ ¾È¿¡ Æ÷ÇÔÇÑ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ¹Ý´ë·Î, <IfDefine>°ú <IfModule>Àº ¼­¹ö°¡ +½ÃÀÛÇÒ¶§¿Í ²¨Áú¶§¸¸ ó¸®ÇÑ´Ù. ½ÃÀÛÇÒ¶§ »óÅ°¡ ÂüÀÌ¸é ¾È¿¡ ÀÖ´Â +Áö½Ã¾î°¡ ¸ðµç ¿äû¿¡ Àû¿ëµÈ´Ù. ÂüÀÌ ¾Æ´Ï¸é ¾È¿¡ ÀÖ´Â Áö½Ã¾î´Â +¹«½ÃÇÑ´Ù.

    + +

    <IfDefine> +Áö½Ã¾î´Â httpd ¸í·ÉÇà¿¡ ÀûÀýÇÑ ÆĶó¹ÌÅÍ°¡ ÀÖ´Â +°æ¿ì¿¡¸¸ ¾È¿¡ Æ÷ÇÔÇÑ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, +¼­¹ö¸¦ httpd -DClosedForNow·Î ½ÃÀÛÇÒ °æ¿ì¿¡¸¸ +¸ðµç ¿äûÀÌ ´Ù¸¥ »çÀÌÆ®·Î ¸®´ÙÀÌ·º¼ÇµÈ´Ù:

    + +

    +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +

    + +

    <IfModule> +Áö½Ã¾îµµ ƯÁ¤ ¸ðµâÀÌ ¼­¹ö¿¡ Æ÷ÇÔµÈ °æ¿ì¿¡¸¸ ¾È¿¡ µç Áö½Ã¾î¸¦ +Àû¿ëÇÑ´Ù´Â Á¡À» Á¦¿ÜÇÏ°í´Â ¸Å¿ì ºñ½ÁÇÏ´Ù. ¸ðµâÀ» ¼­¹ö¿¡ Á¤ÀûÀ¸·Î +ÄÄÆÄÀÏÇϰųª µ¿ÀûÀ¸·Î ÄÄÆÄÀÏÇÑÈÄ ¼³Á¤ÆÄÀÏ ¾Õ¿¡ LoadModule ÁÙÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ÀÌ +Áö½Ã¾î´Â ƯÁ¤ ¸ðµâÀÇ ¼³Ä¡À¯¹«¿¡ µû¶ó ¼³Á¤ÆÄÀÏÀÌ ´Ù¸¦ ÇÊ¿ä°¡ +ÀÖÀ»¶§¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ðµâÀÌ ¾ø´Â °æ¿ì À¯¿ëÇÑ ¿À·ù¹®ÀÌ ³ª¿ÀÁö¾ÊÀ» +¼ö Àֱ⠶§¹®¿¡ ¾ðÁ¦³ª »ç¿ëÇÏ±æ ¿øÇÏ´Â Áö½Ã¾î¸¦ ¾È¿¡ µÎ¸é ¾ÈµÈ´Ù.

    + +

    ´ÙÀ½ ¿¹¿¡¼­ mod_mime_magicÀÌ ÀÖÀ»¶§¸¸ MimeMagicFiles Áö½Ã¾î¸¦ +ó¸®ÇÑ´Ù.

    + +

    +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +

    + +

    <IfDefine>°ú +<IfModule>ÀÇ +°Ë»ç ¾Õ¿¡ "!"À» ºÙ¿© Á¶°ÇÀ» ¿ªÀ¸·Î ÇÒ ¼ö ÀÖ´Ù. ¶Ç, ¿©·¯ ¼½¼ÇµéÀ» +°ãÃļ­ »ç¿ëÇÏ¿© ´õ º¹ÀâÇÑ È¿°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ÆÄÀϽýºÅÛ°ú À¥°ø°£

    + +

    °¡Àå ÀÚÁÖ »ç¿ëµÇ´Â ¼³Á¤ ¼½¼ÇÀº ÆÄÀϽýºÅÛ°ú À¥°ø°£(webspace)ÀÇ +ƯÁ¤ Àå¼Ò¿¡ ´ëÇÑ ¼³Á¤À» º¯°æÇÏ´Â °ÍµéÀÌ´Ù. ¸ÕÀú ÀÌ µÑÀÇ Â÷À̸¦ +ÀÌÇØÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù. ÆÄÀϽýºÅÛÀº ¿î¿µÃ¼Á¦ ÀÔÀå¿¡¼­ µð½ºÅ©¸¦ +º¸´Â °üÁ¡ÀÌ´Ù. ¿¹¸¦ µé¾î, ±âº»°ªÀ¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡¸¦ Çϸé À¯´Ð½º +ÆÄÀϽýºÅÛÀÇ °æ¿ì /usr/local/apache2, À©µµ¿ìÁî +ÆÄÀϽýºÅÛÀÇ °æ¿ì "c:/Program Files/Apache +Group/Apache2"¿¡ ¼³Ä¡µÈ´Ù. (¾ÆÆÄÄ¡´Â À©µµ¿ìÁî¿¡¼­ Á¶Â÷ +Ç×»ó, ¿ª½½·¡½¬°¡ ¾Æ´Ñ, ½½·¡½¬¸¦ »ç¿ëÇÔÀ» ÁÖÀÇÇ϶ó.) ¹Ý´ë·Î +À¥°ø°£Àº À¥¼­¹ö°¡ Á¦°øÇÏ°í Ŭ¶óÀ̾ðÆ®°¡ º¸°ÔµÉ »çÀÌÆ®ÀÇ °üÁ¡ÀÌ´Ù. +±×·¡¼­ À¯´Ð½º¿¡¼­ ±âº» ¾ÆÆÄÄ¡ ¼³Ä¡¸¦ ÇÑ °æ¿ì À¥°æ·ÎÀÇ °æ·Î +/dir/Àº ÆÄÀϽýºÅÛ °æ·Î +/usr/local/apache2/htdocs/dir/¿¡ ÇØ´çÇÑ´Ù. À¥°ø°£Àº +µ¥ÀÌŸº£À̽º µî¿¡¼­ µ¿ÀûÀ¸·Î »ý¼ºµÉ ¼ö Àֱ⶧¹®¿¡ ¹Ýµå½Ã +ÆÄÀϽýºÅÛ¿¡ Á÷Á¢ ´ëÀÀµÉ ÇÊ¿ä´Â ¾ø´Ù.

    + +

    ÆÄÀϽýºÅÛ ¼½¼Ç

    + +

    <Directory>¿Í +<Files> Áö½Ã¾î¿Í +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â Áö½Ã¾î´Â ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐ¿¡ Áö½Ã¾î¸¦ +Àû¿ëÇÑ´Ù. <Directory> Áö½Ã¾î¿¡ Æ÷ÇÔµÈ Áö½Ã¾îµéÀº +ÁöÁ¤ÇÑ ÆÄÀϽýºÅÛ µð·ºÅ丮¿Í ±× ÇÏÀ§ µð·ºÅ丮¿¡ Àû¿ëµÈ´Ù. .htaccess ÆÄÀÏÀ» »ç¿ëÇصµ °á°ú´Â +°°´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, µð·ºÅ丮 ¸ñ·Ï(index)ÀÌ +/var/web/dir1 ÀÌÇÏ µð·ºÅ丮¿¡¼­ µð·ºÅ丮 ¸ñ·Ï(index)ÀÌ +°¡´ÉÇÏ´Ù.

    + +

    +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +

    + +

    <Files> ¼½¼Ç¿¡ Æ÷ÇÔµÈ Áö½Ã¾îµéÀº ¾î¶² +µð·ºÅ丮¿¡ ÀÖ´ÂÁö °ü°è¾øÀÌ ÁöÁ¤ÇÑ À̸§À» °¡Áø ÆÄÀÏ¿¡ Àû¿ëµÈ´Ù. +¼³Á¤ÆÄÀÏÀÇ ÁÖ¼³Á¤ºÎºÐ¿¡ ÀÖ´Â ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, Àå¼Ò¿Í +°ü°è¾øÀÌ private.htmlÀ̶õ À̸§À» ÇÑ ÆÄÀÏÀÇ Á¢±ÙÀ» +°ÅºÎÇÑ´Ù.

    + +

    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +

    + +

    ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐ¿¡ ÀÖ´Â ÆÄÀÏÀ» ÁöĪÇϱâÀ§ÇØ <Files>¿Í <Directory> ¼½¼ÇÀ» °°ÀÌ +»ç¿ëÇÑ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, +/var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html °°ÀÌ +/var/web/dir1/ µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â À̸§ÀÌ +private.htmlÀÎ ÆÄÀÏÀÇ Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + +

    +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +

    + + +

    À¥°ø°£ ¼½¼Ç

    + +

    <Location> +Áö½Ã¾î¿Í ÀÌ¿¡ ÇØ´çÇÏ´Â Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â Áö½Ã¾î´Â ¹Ý´ë·Î +ƯÁ¤ À¥°ø°£ÀÇ ¼³Á¤À» ¹Ù²Û´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, /privateÀ¸·Î +½ÃÀÛÇÏ´Â URL-°æ·ÎÀÇ Á¢±ÙÀÌ °ÅºÎµÈ´Ù. ¿©±â¿¡´Â +http://yoursite.example.com/private, +http://yoursite.example.com/private123, +http://yoursite.example.com/private/dir/file.html +°°ÀÌ /private ¹®ÀÚ¿­·Î ½ÃÀÛÇÏ´Â ¿äûÀÌ ÇØ´çµÈ´Ù.

    + +

    +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +

    + +

    <Location> +Áö½Ã¾î´Â ÆÄÀϽýºÅÛ¿¡ ´ëÀÀÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ´ÙÀ½ ¿¹´Â ¾î¶»°Ô ƯÁ¤ +URLÀ» mod_status°¡ Á¦°øÇÏ´Â ¾ÆÆÄÄ¡ ³»ºÎ Çڵ鷯·Î +´ëÀÀ½ÃÅ°´ÂÁö¸¦ º¸¿©ÁØ´Ù. ÆÄÀϽýºÅÛ¿¡ server-status¶ó´Â +ÆÄÀÏÀº ÇÊ¿ä¾ø´Ù.

    + +

    +<Location /server-status>
    +SetHandler server-status
    +</Location> +

    + + +

    ¿ÍÀϵåÄ«µå¿Í Á¤±ÔÇ¥Çö½Ä

    + +

    <Directory>, +<Files>, +<Location> +Áö½Ã¾î¿¡¼­ C Ç¥ÁØ ÆÄÀ̺귯¸®ÀÇ fnmatch¿Í °°Àº +½©¿¡¼­ »ç¿ëÇÏ´Â ¿ÍÀϵåÄ«µå ¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. +"*" ¹®ÀÚ´Â ¾î¶² ¹®ÀÚ¿­ÀÌ¶óµµ ³ªÅ¸³»°í, "?" ¹®ÀÚ´Â ¾î¶² ¹®ÀÚ ÇÑ°³¸¦ +³ªÅ¸³»¸ç, "[seq]"´Â seq Áß¿¡ ÇÑ ¹®ÀÚ¸¦ ³ªÅ¸³½´Ù. +¾î¶² ¿ÍÀϵåÄ«µåµµ "/" ¹®ÀÚ¸¦ ³ªÅ¸³»Áö´Â ¸øÇÑ´Ù. ±×·¡¼­ ÀÌ ¹®ÀÚ´Â +Á÷Á¢ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ´õ À¯¿¬ÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇϸé perlȣȯ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â <DirectoryMatch>, <FilesMatch>, <LocationMatch>¸¦ »ç¿ëÇÒ +¼ö ÀÖ´Ù. ±×·¯³ª ¾Æ·¡ ¼³Á¤ÀÇ °áÇÕ¿¡ °üÇÑ Àý¿¡¼­ Á¤±ÔÇ¥Çö½Ä ¼½¼ÇÀ» +»ç¿ëÇϸé Áö½Ã¾î°¡ Àû¿ëµÇ´Â ¹æ¹ýÀÌ ¾î¶»°Ô º¯ÇÏ´ÂÁö »ìÆìºÁ¶ó.

    + +

    ¸ðµç »ç¿ëÀÚ µð·ºÅ丮 ¼³Á¤À» º¯°æÇÏ´Â ºñÁ¤±ÔÇ¥Çö½Ä ¿ÍÀϵåÄ«µå +¼½¼ÇÀº ´ÙÀ½°ú °°´Ù:

    + +

    +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +

    + +

    Á¤±ÔÇ¥Çö½Ä ¼½¼ÇÀ» »ç¿ëÇÏ¿© Çѹø¿¡ ¿©·¯ Á¾·ùÀÇ ±×¸²ÆÄÀÏ¿¡ +´ëÇÑ Á¢±ÙÀ» °ÅºÎÇÒ ¼ö ÀÖ´Ù:

    +

    +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +

    + + + +

    ¹«¾ùÀ» »ç¿ëÇϳª

    + +

    ÆÄÀϽýºÅÛ ¼½¼Ç°ú À¥°ø°£ ¼½¼Ç Áß Çϳª¸¦ ¼±ÅÃÇÏ´Â °ÍÀº ½ÇÁ¦·Î +¸Å¿ì ½±´Ù. ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â °´Ã¼¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÒ¶§´Â Ç×»ó +<Directory>³ª +<Files>¸¦ +»ç¿ëÇÑ´Ù. (µ¥ÀÌŸº£À̽º¿¡¼­ »ý¼ºÇÑ À¥ÆäÀÌÁö¿Í °°ÀÌ) ÆÄÀϽýºÅÛ¿¡ +ÀÖÁö ¾Ê´Â °´Ã¼¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÒ¶§´Â <Location>À» »ç¿ëÇÑ´Ù.

    + +

    ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â °´Ã¼ÀÇ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ <Location>À» »ç¿ëÇϸé +Àý´ë ¾ÈµÈ´Ù. ¿©·¯ ´Ù¸¥ À¥°ø°£ Àå¼Ò(URL)°¡ °°Àº ÆÄÀϽýºÅÛ Àå¼Ò¿¡ +´ëÀÀµÉ ¼ö ÀÖÀ¸¹Ç·Î, °É¾îµÐ Á¦ÇÑÀ» ¿ìȸÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. ´ÙÀ½ +¼³Á¤ÀÇ ¿¹¸¦ »ìÆ캸ÀÚ:

    + +

    +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +

    + +

    ÀÌ ¼³Á¤Àº http://yoursite.example.com/dir/À» +¿äûÇÑ´Ù¸é Àß ÀÛµ¿ÇÑ´Ù. ±×·¯³ª ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê´Â ÆÄÀϽýºÅÛÀ» +»ç¿ëÇÑ´Ù¸é ¾î¶»°ÔµÇ³ª? +http://yoursite.example.com/DIR/À» ¿äûÇÏ¿© ½±°Ô +Á¦ÇÑÀ» ¿ìȸÇÒ ¼ö ÀÖ´Ù. ¹Ý´ë·Î <Directory> Áö½Ã¾î´Â ¾î¶»°Ô ¿äûÇÏ¿´´ÂÁö +°ü°è¾øÀÌ ±× Àå¼Ò¿¡¼­ ¼­ºñ½ºµÇ´Â ³»¿ë¿¡ Àû¿ëµÈ´Ù. (¿¹¿Ü´Â ÆÄÀϽýºÅÛ +¸µÅ©¸¦ »ç¿ëÇÏ´Â °æ¿ì´Ù. ½Éº¼¸µÅ©¸¦ »ç¿ëÇÏ¿© ÇÑ µð·ºÅ丮¸¦ +ÆÄÀϽýºÅÛÀÇ ¿©·¯ Àå¼Ò¿¡ µÑ ¼ö ÀÖ´Ù. <Directory> Áö½Ã¾î´Â ½Éº¼¸µÅ©¸¦ µû¶ó°£´Ù. +±×·¯¹Ç·Î ³ôÀº ¼öÁØÀÇ º¸¾ÈÀ» À§Çؼ­´Â ÀûÀýÇÑ Options Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ½Éº¼¸µÅ©¸¦ +¹«½ÃÇØ¾ß ÇÑ´Ù.)

    + +

    ¾Æ¸¶µµ ´ç½ÅÀº ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏ´Â ÆÄÀϽýºÅÛÀ» »ç¿ëÇϹǷΠ+ÀÌ·± ÀÏÀÌ ÀϾÁö ¾Ê´Â´Ù°í »ý°¢ÇÒÁöµµ ¸ð¸¥´Ù. ±×·¯³ª ´Ù¸¥ +¹æ¹ýÀ¸·Îµµ ¿©·¯ À¥°ø°£ À§Ä¡°¡ ÇÑ ÆÄÀϽýºÅÛ À§Ä¡¿¡ ´ëÀÀµÉ ¼ö +ÀÖÀ½À» ±â¾ïÇ϶ó. ±×·¡¼­ °¡´ÉÇϸé Ç×»ó ÆÄÀϽýºÅÛ ¼½¼ÇÀ» »ç¿ëÇØ¾ß +ÇÑ´Ù. ±×·¯³ª ÀÌ ±ÔÄ¢¿¡ ¿¹¿Ü°¡ Çϳª ÀÖ´Ù. ¼³Á¤ Á¦ÇÑÀ» +<Location /> ¼½¼Ç¿¡ µÎ¸é ÀÌ ¼½¼ÇÀÌ Æ¯Á¤ +URLÀÌ ¾Æ´Ñ ¸ðµç ¿äû¿¡ Àû¿ëµÇ¹Ç·Î ¿Ïº®ÇÏ°Ô ¾ÈÀüÇÏ´Ù.

    + + +
    top
    +
    +

    °¡»óÈ£½ºÆ®

    + +

    <VirtualHost> +¼½¼ÇÀº ƯÁ¤ È£½ºÆ®¿¡ Àû¿ëµÇ´Â Áö½Ã¾îµéÀ» Æ÷ÇÔÇÑ´Ù. ÀÌ´Â ÇÑ +ÄÄÇ»ÅÍ¿¡¼­ °¢°¢ ´Ù¸¥ ¼³Á¤À» »ç¿ëÇÑ ¿©·¯ È£½ºÆ®¸¦ ¼­ºñ½ºÇÒ¶§ +À¯¿ëÇÏ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â °¡»óÈ£½ºÆ® ¹®¼­¸¦ +Âü°íÇ϶ó.

    +
    top
    +
    +

    ÇÁ·Ï½Ã

    + +

    <Proxy>¿Í +<ProxyMatch> +¼½¼ÇÀº ÁöÁ¤ÇÑ URL¿¡ ´ëÇØ mod_proxy ÇÁ·Ï½Ã ¼­¹ö¸¦ +°ÅÃÄ Á¢±ÙÇÏ´Â °æ¿ì¿¡¸¸ Àû¿ëµÈ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, ÇÁ·Ï½Ã +¼­¹ö¸¦ ÅëÇØ cnn.com À¥»çÀÌÆ®¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù.

    + +

    +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +

    +
    top
    +
    +

    ¾È¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö +ÀÖ³ª?

    + +

    ¾î¶² ¼³Á¤ ¼½¼Ç¾È¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â Áö½Ã¾î¸¦ ¾Ë·Á¸é Áö½Ã¾îÀÇ +»ç¿ëÀå¼Ò¸¦ È®ÀÎÇ϶ó. +<Directory>¿¡¼­ +»ç¿ë°¡´ÉÇÑ Áö½Ã¾î´Â <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, <LocationMatch>, <Proxy>, <ProxyMatch> ¼½¼Ç¿¡¼­µµ »ç¿ë°¡´ÉÇÏ´Ù. +±×·¯³ª, ¿¹¿Ü°¡ ÀÖ´Ù:

    + +
      +
    • AllowOverride Áö½Ã¾î´Â +<Directory> +¼½¼Ç¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    • FollowSymLinks, SymLinksIfOwnerMatch, +Options´Â <Directory> ¼½¼ÇÀ̳ª +.htaccess ÆÄÀÏ¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    • Options Áö½Ã¾î´Â +<Files>°ú +<FilesMatch> +¼½¼Ç¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • +
    +
    top
    +
    +

    ¼½¼ÇµéÀÌ °áÇÕÇÏ´Â ¹æ¹ý

    + +

    ¼³Á¤ ¼½¼ÇÀº ¸Å¿ì Ưº°ÇÑ ¹æ¹ýÀ¸·Î Àû¿ëµÈ´Ù. ÀÌ ¼ø¼­°¡ ¼³Á¤ +Áö½Ã¾î¸¦ Çؼ®ÇÏ´Â ¹æ¹ý¿¡ Áß¿äÇÑ ¿µÇâÀ» Áֱ⶧¹®¿¡ ÀÌ ¹æ¹ýÀ» +ÀÌÇØÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù.

    + +

    °áÇÕÇÏ´Â ¼ø¼­´Â:

    + +
      +
    1. (Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏÁö¾Ê´Â) <Directory>¿Í .htaccess´Â + µ¿½Ã¿¡ ÀϾ´Ù (°æ¿ì¿¡ µû¶ó .htaccessÀÌ + <Directory>¸¦ + ¹«½ÃÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ÀÖ´Ù)
    2. + +
    3. <DirectoryMatch> (±×¸®°í + <Directory ~>)
    4. + +
    5. <Files>¿Í <FilesMatch>´Â µ¿½Ã¿¡ ÀϾ´Ù
    6. + +
    7. <Location>°ú <LocationMatch>´Â µ¿½Ã¿¡ ÀϾ´Ù
    8. +
    + +

    <Directory>¸¦ Á¦¿ÜÇÏ°í °¢ ¼½¼ÇµéÀ» + ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â ¼ø¼­´ë·Î 󸮵ȴÙ. (À§ÀÇ ¼ø¼­ 1) <Directory>´Â µð·ºÅ丮 + ³»¿ëÀÌ °¡Àå ªÀº °Í¿¡¼­ ±äÂÊÀ¸·Î 󸮵ȴÙ. ±×·¡¼­ ¿¹¸¦ µé¾î, + <Directory /var/web/dir>À» + <Directory /var/web/dir/subdir> ÀÌÀü¿¡ + ó¸®ÇÑ´Ù. °°Àº µð·ºÅ丮¸¦ ÁöĪÇÏ´Â ¿©·¯ <Directory> ¼½¼ÇÀÌ + ÀÖ´Ù¸é À̵éÀ» ¼³Á¤ÆÄÀÏ ¼ø¼­´ë·Î ó¸®ÇÑ´Ù. Include Áö½Ã¾î·Î Æ÷ÇÔÇÑ ¼³Á¤Àº + Include Áö½Ã¾î À§Ä¡¿¡ + Æ÷ÇÔÇÑ ÆÄÀÏ ³»¿ëÀÌ ÀÖ´Â °Íó·³ ó¸®ÇÑ´Ù.

    + +

    <VirtualHost> ¼½¼Ç ¾È¿¡ Æ÷ÇÔµÈ ¼½¼ÇÀº + °¡»óÈ£½ºÆ® Á¤ÀÇ ¹Û¿¡ ÀÖ´Â ÇØ´ç ¼½¼Ç ÀÌÈÄ¿¡ Àû¿ëµÈ´Ù. + ±×·¡¼­ °¡»óÈ£½ºÆ® ¾È¿¡¼­ ÁÖ¼­¹öÀÇ ¼³Á¤»çÇ×À» ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    mod_proxy°¡ ¿äû ¼­ºñ½ºÇÒ¶§, <Proxy> ¼½¼ÇÀÇ + 󸮼ø¼­´Â <Directory> ¼½¼Ç°ú °°´Ù.

    + +

    ´ÙÀ½¿¡ ³ª¿À´Â ¼½¼ÇÀº ÀÌÀü ¼½¼ÇÀÇ °á°ú¸¦ ¼öÁ¤ÇÑ´Ù.

    + +

    ±â¼úÀû ÁÖÀÇ

    + ½ÇÁ¦·Î + <Location>/<LocationMatch>´Â + (Aliases¿Í DocumentRoot¸¦ »ç¿ëÇÏ¿© + URLÀ» ÆÄÀϸíÀ¸·Î º¯È¯ÇÏ´Â) À̸§¹ø¿ª ´Ü°è ÀÌÀü¿¡ 󸮵ȴÙ. + º¯¿ªÀÌ ³¡³­ ÀÌÈÄ¿¡´Â ¿ÏÀüÈ÷ ¹«½ÃÇÑ´Ù. +
    + +

    ¿¹Á¦

    + +

    ´ÙÀ½Àº °ãÇÕÇÏ´Â ¼ø¼­¸¦ ¼³¸íÇÏ´Â ¿¹´Ù. ÀÌµé ¸ðµÎ ¿äû¿¡ +Àû¿ëµÈ´Ù°í °¡Á¤Çϸé Áö½Ã¾î´Â A > B > C > D > E +¼ø¼­·Î 󸮵ȴÙ.

    + +

    +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +

    + +

    ´õ Çö½ÇÀûÀÎ ¿¹´Â ´ÙÀ½°ú °°´Ù. <Location> ¼½¼ÇÀ» ³ªÁß¿¡ ó¸®ÇϹǷΠ+<Directory> +¼½¼Ç¿¡ ÀÖ´Â Á¢±ÙÁ¦ÇÑ°ú °ü°è¾øÀÌ ¼­¹ö¿¡ ¹«Á¦ÇÑ Á¢±ÙÀ» °¡´ÉÇÏ´Ù. +Áï, °áÇÕÇÏ´Â ¼ø¼­´Â Áß¿äÇϹǷΠÁÖÀÇÇ϶ó!

    + +

    +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# ¾Ç! ÀÌ <Directory> ¼½¼ÇÀº ¾Æ¹«·± È¿°ú°¡ ¾ø´Ù
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +

    + + + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sections.xml b/trunk/docs/manual/sections.xml new file mode 100644 index 0000000000..0df64ee175 --- /dev/null +++ b/trunk/docs/manual/sections.xml @@ -0,0 +1,496 @@ + + + + + + + + + +Configuration Sections + +

    Directives in the configuration files may apply to the +entire server, or they may be restricted to apply only to particular +directories, files, hosts, or URLs. This document describes how to +use configuration section containers or .htaccess files +to change the scope of other configuration directives.

    +
    + +
    Types of Configuration Section Containers + + + +core +mod_proxy + + +Directory +DirectoryMatch +Files +FilesMatch +IfDefine +IfModule +Location +LocationMatch +Proxy +ProxyMatch +VirtualHost + + + +

    There are two basic types of containers. Most containers are +evaluated for each request. The enclosed directives are applied only +for those requests that match the containers. The IfDefine and IfModule containers, on the +other hand, are evaluated only at server startup and restart. If +their conditions are true at startup, then the enclosed directives +will apply to all requests. If the conditions are not true, the +enclosed directives will be ignored.

    + +

    The IfDefine directive +encloses directives that will only be applied if an appropriate +parameter is defined on the httpd command line. For example, +with the following configuration, all requests will be redirected +to another site only if the server is started using +httpd -DClosedForNow:

    + + +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +
    + +

    The IfModule +directive is very similar, except it encloses directives that will +only be applied if a particular module is available in the server. +The module must either be statically compiled in the server, or it +must be dynamically compiled and its LoadModule line must be earlier in the +configuration file. This directive should only be used if you need +your configuration file to work whether or not certain modules are +installed. It should not be used to enclose directives that you want +to work all the time, because it can suppress useful error messages +about missing modules.

    + +

    In the following example, the MimeMagicFiles directive will be +applied only if mod_mime_magic is available.

    + + +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +
    + +

    Both IfDefine +and IfModule +can apply negative conditions by preceding their test with "!". +Also, these sections can be nested to achieve more complex +restrictions.

    +
    + +
    Filesystem and Webspace + +

    The most commonly used configuration section containers are the +ones that change the configuration of particular places in the +filesystem or webspace. First, it is important to understand the +difference between the two. The filesystem is the view of your disks +as seen by your operating system. For example, in a default install, +Apache resides at /usr/local/apache2 in the Unix +filesystem or "c:/Program Files/Apache Group/Apache2" in +the Windows filesystem. (Note that forward slashes should always be +used as the path separator in Apache, even for Windows.) In contrast, +the webspace is the view of your site as delivered by the web server +and seen by the client. So the path /dir/ in the +webspace corresponds to the path +/usr/local/apache2/htdocs/dir/ in the filesystem of a +default Apache install on Unix. The webspace need not map directly to +the filesystem, since webpages may be generated dynamically +from databases or other locations.

    + +
    Filesystem Containers + +

    The Directory +and Files +directives, along with their regex counterparts, apply directives to +parts of the filesystem. Directives enclosed in a Directory section apply to +the named filesystem directory and all subdirectories of that +directory. The same effect can be obtained using .htaccess files. For example, in the +following configuration, directory indexes will be enabled for the +/var/web/dir1 directory and all subdirectories.

    + + +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +
    + +

    Directives enclosed in a Files section apply to any file with +the specified name, regardless of what directory it lies in. +So for example, the following configuration directives will, +when placed in the main section of the configuration file, +deny access to any file named private.html regardless +of where it is found.

    + + +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +
    + +

    To address files found in a particular part of the filesystem, the +Files and +Directory sections +can be combined. For example, the following configuration will deny +access to /var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html, and any other instance +of private.html found under the /var/web/dir1/ +directory.

    + + +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +
    +
    + +
    Webspace Containers + +

    The Location +directive and its regex counterpart, on the other hand, change the +configuration for content in the webspace. For example, the following +configuration prevents access to any URL-path that begins in /private. +In particular, it will apply to requests for +http://yoursite.example.com/private, +http://yoursite.example.com/private123, and +http://yoursite.example.com/private/dir/file.html as well +as any other requests starting with the /private string.

    + + +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +
    + +

    The Location +directive need not have anything to do with the filesystem. +For example, the following example shows how to map a particular +URL to an internal Apache handler provided by mod_status. +No file called server-status needs to exist in the +filesystem.

    + + +<Location /server-status>
    +SetHandler server-status
    +</Location> +
    +
    + +
    Wildcards and Regular Expressions + +

    The Directory, +Files, and +Location +directives can each use shell-style wildcard characters as in +fnmatch from the C standard library. The character "*" +matches any sequence of characters, "?" matches any single character, +and "[seq]" matches any character in seq. The "/" +character will not be matched by any wildcard; it must be specified +explicitly.

    + +

    If even more flexible matching is required, each +container has a regular-expression (regex) counterpart DirectoryMatch, FilesMatch, and LocationMatch that allow +perl-compatible +regular expressions +to be used in choosing the matches. But see the section below on +configuration merging to find out how using regex sections will change +how directives are applied.

    + +

    A non-regex wildcard section that changes the configuration of +all user directories could look as follows:

    + + +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +
    + +

    Using regex sections, we can deny access to many types of image files +at once:

    + +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +
    + +
    + +
    What to use When + +

    Choosing between filesystem containers and webspace containers is +actually quite easy. When applying directives to objects that reside +in the filesystem always use Directory or Files. When applying directives to objects +that do not reside in the filesystem (such as a webpage generated from +a database), use Location.

    + +

    It is important to never use Location when trying to restrict +access to objects in the filesystem. This is because many +different webspace locations (URLs) could map to the same filesystem +location, allowing your restrictions to be circumvented. +For example, consider the following configuration:

    + + +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +
    + +

    This works fine if the request is for +http://yoursite.example.com/dir/. But what if you are on +a case-insensitive filesystem? Then your restriction could be easily +circumvented by requesting +http://yoursite.example.com/DIR/. The Directory directive, in +contrast, will apply to any content served from that location, +regardless of how it is called. (An exception is filesystem links. +The same directory can be placed in more than one part of the +filesystem using symbolic links. The Directory directive will follow the symbolic +link without resetting the pathname. Therefore, for the highest level +of security, symbolic links should be disabled with the appropriate +Options directive.)

    + +

    If you are, perhaps, thinking that none of this applies to you +because you use a case-sensitive filesystem, remember that there are +many other ways to map multiple webspace locations to the same +filesystem location. Therefore you should always use the filesystem +containers when you can. There is, however, one exception to this +rule. Putting configuration restrictions in a <Location +/> section is perfectly safe because this section will apply +to all requests regardless of the specific URL.

    +
    + +
    + +
    Virtual Hosts + +

    The VirtualHost +container encloses directives that apply to specific hosts. +This is useful when serving multiple hosts from the same machine +with a different configuration for each. For more information, +see the Virtual Host Documentation.

    +
    + +
    Proxy + +

    The Proxy +and ProxyMatch +containers apply enclosed configuration directives only +to sites accessed through mod_proxy's proxy server +that match the specified URL. For example, the following configuration +will prevent the proxy server from being used to access the +cnn.com website.

    + + +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +
    +
    + +
    What Directives are Allowed? + +

    To find out what directives are allowed in what types of +configuration sections, check the Context of the directive. +Everything that is allowed in +Directory +sections is also syntactically allowed in +DirectoryMatch, +Files, +FilesMatch, +Location, +LocationMatch, +Proxy, +and ProxyMatch +sections. There are some exceptions, however:

    + +
      +
    • The AllowOverride directive +works only in Directory +sections.
    • + +
    • The FollowSymLinks and +SymLinksIfOwnerMatch Options work only in Directory sections or +.htaccess files.
    • + +
    • The Options directive cannot +be used in Files +and FilesMatch +sections.
    • +
    +
    + +
    How the sections are merged + +

    The configuration sections are applied in a very particular order. +Since this can have important effects on how configuration directives +are interpreted, it is important to understand how this works.

    + +

    The order of merging is:

    + +
      +
    1. Directory (except regular expressions) + and .htaccess done simultaneously (with + .htaccess, if allowed, overriding + Directory)
    2. + +
    3. DirectoryMatch + (and <Directory ~>)
    4. + +
    5. Files and FilesMatch done + simultaneously
    6. + +
    7. Location + and LocationMatch done simultaneously
    8. +
    + +

    Apart from Directory, each group is processed in + the order that they appear in the configuration files. Directory (group 1 above) + is processed in the order shortest directory component to longest. + So for example, <Directory /var/web/dir> will + be processed before <Directory + /var/web/dir/subdir>. If multiple Directory sections apply + to the same directory they are processed in the configuration file + order. Configurations included via the Include directive will be treated as if + they were inside the including file at the location of the + Include directive.

    + +

    Sections inside VirtualHost sections + are applied after the corresponding sections outside + the virtual host definition. This allows virtual hosts to + override the main server configuration.

    + +

    When the request is served by mod_proxy, the + Proxy + container takes the place of the Directory container in the processing + order.

    + +

    Later sections override earlier ones.

    + +Technical Note + There is actually a + <Location>/<LocationMatch> + sequence performed just before the name translation phase + (where Aliases and DocumentRoots + are used to map URLs to filenames). The results of this + sequence are completely thrown away after the translation has + completed. + + +
    Some Examples + +

    Below is an artificial example to show the order of +merging. Assuming they all apply to the request, the directives in +this example will be applied in the order A > B > C > D > +E.

    + + +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +
    + +

    For a more concrete example, consider the following. Regardless of +any access restrictions placed in Directory sections, the Location section will be +evaluated last and will allow unrestricted access to the server. In +other words, order of merging is important, so be careful!

    + + +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# Woops! This <Directory> section will have no effect
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +
    + +
    + +
    +
    + diff --git a/trunk/docs/manual/sections.xml.ja b/trunk/docs/manual/sections.xml.ja new file mode 100644 index 0000000000..166aef1fc6 --- /dev/null +++ b/trunk/docs/manual/sections.xml.ja @@ -0,0 +1,479 @@ + + + + + + + + + +$B%;%/%7%g%s$N@_Dj(B + +

    $B@_Dj%U%!%$%k(B$BCf$N%G%#%l%/%F%#%V$O(B +$B%5!<%PA4BN$KE,MQ$5$l$?$j!"FCDj$N%G%#%l%/%H%j$d%U%!%$%k!"%[%9%H!"(BURL $B$K$N$_(B +$BE,MQ$5$l$k$h$&$K@)8B$7$?$j$9$k$3$H$,$G$-$^$9!#$3$NJ8=q$O@_DjMQ$N%;%/%7%g%s$N(B +$B%3%s%F%J$d(B .htaccess $B%U%!%$%k$r;H$C$FB>$N@_Dj%G%#%l%/%F%#%V$N(B +$B%9%3!<%W$rJQ99$9$kJ}K!$r@bL@$7$^$9!#(B

    +
    + +
    $B@_DjMQ%;%/%7%g%s%3%s%F%J$N<oN`(B + + + +core +mod_proxy + + +Directory +DirectoryMatch +Files +FilesMatch +IfDefine +IfModule +Location +LocationMatch +Proxy +ProxyMatch +VirtualHost + + + +

    $B%3%s%F%J$K$OFs$D$N4pK\$H$J$k2A$5$l$^$9!#$=$N>l9g!"%3%s%F%JCf$N%G%#%l%/%F%#%V$O(B +$B%3%s%F%J$K%^%C%A$9$k%j%/%(%9%H$K$N$_E,MQ$5$l$^$9!#(B +$B0lJ}!"(BIfDefine $B%3%s%F%J$H(B IfModule $B%3%s%F%J$O(B +$B%5!<%P$N5/F0;~$H:F5/F0;~$K$N$_I>2A$5$l$^$9!#5/F0;~$K>r7o$,??$G$"$l$P!"(B +$B%3%s%F%JCf$N%G%#%l%/%F%#%V$O$9$Y$F$N%j%/%(%9%H$KE,MQ$5$l$^$9!#>r7o$,(B +$B56$G$"$l$P!"%3%s%F%JCf$N%G%#%l%/%F%#%V$OL5;k$5$l$^$9!#(B

    + +

    IfDefine $B%G%#%l%/%F%#%V$O(B +httpd $B%3%^%s%I%i%$%s$GE,@Z$J%Q%i%a!<%?$,Dj5A$5$l$?$H$-$K$N$_(B +$BE,MQ$5$l$k%G%#%l%/%F%#%V$r0O$$$^$9!#Nc$($Phttpd -DClosedForNow $B$r;H$C$F5/F0$5$l$?$H$-$@$1$9$Y$F$N(B +$B%j%/%(%9%H$rJL$N%5%$%H$K%j%@%$%l%/%H$7$^$9(B:

    + + +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +
    + +

    IfModule $B$O(B +$BHs>o$K;w$F$$$^$9$,!"Be$o$j$K%5!<%P>e$G%b%8%e!<%k$,;HMQ2DG=$J>l9g$K$N$_(B +$BE,MQ2DG=$J%G%#%l%/%F%#%V$r0O$$$^$9!#%b%8%e!<%k$O%5!<%P$K(B +$B@EE*$KAH$_9~$^$l$F$$$k$+!"F0E*$KAH$_9~$`$h$&$K$J$C$F$$$F!"@_Dj%U%!%$%kCf$G(B +LoadModule $B$N9T$,$h$jA0$N(B +$BItJ,$K=q$+$l$F$$$kI,MW$,$"$j$^$9!#$3$N%G%#%l%/%F%#%V$OFCDj$N%b%8%e!<%k$N(B +$BB8:_$K4X$o$i$:@_Dj%U%!%$%k$,F0:n$9$kI,MW$,$"$k>l9g$K$N$_;H$C$F$/$@$5$$!#(B +$B>o$KF0:n$7$FM_$7$$%G%#%l%/%F%#%V$r0O$`$?$a$K;H$&$Y$-$G$O$"$j$^$;$s!#(B +$BB8:_$7$J$$%b%8%e!<%k$K4X$9$kM-MQ$J%(%i!<%a%C%;!<%8$NH/@8$rM^@)$7$F$7$^$$$^$9$N$G!#(B +

    + +

    $Bmod_mime_magic $B$,$"$k$H$-$K$N$_(B MimeMagicFiles $B%G%#%l%/%F%#%V$,(B +$BE,MQ$5$l$^$9!#(B

    + + +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +
    + +

    IfDefine $B%G%#%l%/%F%#%V$H(B +IfModule $B%G%#%l%/%F%#%V$O(B +$B%F%9%H$NA0$K(B "!" $B$rIU$1$k$3$H$GH]Dj$N>r7o$rE,MQ$9$k$3$H$,$G$-$^$9!#(B +$B$^$?!"$3$l$i$N%;%/%7%g%s$O$h$jJ#;($J@)8B$r2]$9$?$a$KF~$l;R$K$9$k$3$H$,$G$-$^$9!#(B +

    +
    + +
    $B%U%!%$%k%7%9%F%`$H%&%'%V6u4V(B + +

    $B:G$b$h$/;H$o$l$k@_Dj$N%;%/%7%g%s%3%s%F%J$O%U%!%$%k%7%9%F%`$d%&%'%V6u4V$N(B +$BFCDj$N>l=j$N@_Dj$rJQ99$9$k$b$N$G$9!#$^$:!"$3$NFs$D$N0c$$$rM}2r$9$k$3$H$,(B +$BBg@Z$G$9!#%U%!%$%k%7%9%F%`$O%*%Z%l!<%F%#%s%0%7%9%F%`$+$i8+$?%G%#%9%/$NFbMF$G$9!#(B +$B$?$H$($P!"%G%U%)%k%H$N%$%s%9%H!<%k$G$O(B Apache $B$O(B Unix $B%U%!%$%k%7%9%F%`$G$O(B +/usr/local/apache2 $B$K!"(BWindows $B%U%!%$%k%7%9%F%`$G$O(B +"c:/Program Files/Apache Group/Apache2" $B$KB8:_$7$^$9!#(B +(Apache $B$G$O(B Windows $B$G$b%Q%9%;%Q%l!<%?$H$7$F%9%i%C%7%e$r;H$&$3$H$K(B +$B5$$r$D$1$F$/$@$5$$!#(B) $BBP>HE*$K!"%&%'%V6u4V$O$"$J$?$N%5%$%H$r(B +$B%&%'%V%5!<%P$+$iG[?.$5$l$k$b$N$H$7$F8+$?$b$N$G!"%/%i%$%"%s%H$K8+$($k$b$N$G$9!#(B +$B%G%U%)%k%H$N(B Unix $B>e$N(B Apache $B$N%$%s%9%H!<%k$G$O%&%'%V6u4V$N(B +/dir/ $B$H$$$&%Q%9$O%U%!%$%k%7%9%F%`$N(B +/usr/local/apache2/htdocs/dir/ $B$H$$$&%Q%9$KBP1~$7$^$9!#(B +$B%&%'%V%Z!<%8$O%G!<%?%Y!<%9$dB>$N>l=j$+$iF0E*$K@8@.$9$k$3$H$b$G$-$^$9$N$G!"(B +$B%&%'%V6u4V$O%U%!%$%k%7%9%F%`$KD>@\%^%C%W$9$kI,MW$O$"$j$^$;$s!#(B

    + +
    $B%U%!%$%k%7%9%F%`%3%s%F%J(B + +

    Directory $B%G%#%l%/%F%#%V$H(B +Files $B%G%#%l%/%F%#%V!"$=$l$H(B +$B$=$l$i$N@55,I=8=HG$O%G%#%l%/%F%#%V$r%U%!%$%k%7%9%F%`$N0lItJ,$KBP$7$FE,MQ$7$^$9!#(B +Directory $B%;%/%7%g%s$N(B +$BCf$N%G%#%l%/%F%#%V$O;XDj$5$l$?%G%#%l%/%H%j$H$=$N$9$Y$F$N%5%V%G%#%l%/%H%j$K(B +$BE,MQ$5$l$^$9!#(B.htaccess $B%U%!%$%k(B$B$r(B +$B;H$&$3$H$G$bF1$88z2L$rF@$k$3$H$,$G$-$^$9!#Nc$($P!"/var/web/dir1 $B$H$9$Y$F$N%5%V%G%#%l%/%H%j$KBP$7$F(B +$B%G%#%l%/%H%j%$%s%G%C%/%9$r9T$J$$$^$9!#(B

    + + +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +
    + +

    Files $B%;%/%7%g%s$N(B +$BCf$K$"$k%G%#%l%/%F%#%V$O$I$N%G%#%l%/%H%j$K$"$k$+$K4X$o$i$:!";XDj$5$l$?L>A0$N(B +$B$9$Y$F$N%U%!%$%k$KE,MQ$5$l$^$9!#$G$9$+$iNc$($P0J2<$N@_Dj%G%#%l%/%F%#%V$,(B +$B@_Dj%U%!%$%k$Nl=j$N(B +private.html $B$H$$$&L>A0$N%U%!%$%k$X$N%"%/%;%9$r5qH]$7$^$9!#(B

    + + +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +
    + +

    $B%U%!%$%k%7%9%F%`$NFCDj$N>l=j$K$"$k%U%!%$%k$r;XDj$9$k$?$a$K!"(B +Files $B%;%/%7%g%s$H(B +Directory $B%;%/%7%g%s$r(B +$BAH$_9g$o$;$k$3$H$,$G$-$^$9!#Nc$($P!"/var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html $B$J$I!"(B +/var/web/dir1/ $B%G%#%l%/%H%j$N2<$K$"$k$9$Y$F$N(B +private.html $B$X$N%"%/%;%9$r5qH]$7$^$9!#(B

    + + +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +
    +
    + +
    $B%&%'%V6u4V%3%s%F%J(B + +

    $B0lJ}!"(BLocation +$B%G%#%l%/%F%#%V$H$=$N@55,I=8=HG$O%&%'%V6u4V>e$NFbMF$KBP$7$F@_Dj$rJQ99$7$^$9!#(B +$B$?$H$($P!"http://yoursite.example.com/private, +http://yoursite.example.com/private123, +http://yoursite.example.com/private/dir/file.html +$B$X$N%j%/%(%9%H$d!"(B +$BB>$NF1MM$K(B /private $BJ8;zNs$G;O$^$k%j%/%(%9%H$K(B +$BE,MQ$5$l$^$9!#(B

    + + +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +
    + +

    Location +$B%G%#%l%/%F%#%V$O%U%!%$%k%7%9%F%`$H4X78$"$kI,MW$,A4$/$"$j$^$;$s!#(B +$B$?$H$($Pmod_status$B$GDs6!$5$l$F$$$k(B Apache +$BFbIt%O%s%I%i$K%^%C%W$9$k$+$r<($7$F$$$^$9!#%U%!%$%k%7%9%F%`$K(B +server-status $B$H$$$&%U%!%$%k$,B8:_$9$kI,MW$O$"$j$^$;$s!#(B

    + + +<Location /server-status>
    +SetHandler server-status
    +</Location> +
    +
    + +
    $B%o%$%k%I%+!<%I$H@55,I=8=(B + +

    Directory, +Files, +Location +$B%G%#%l%/%F%#%V$G$O!"(B C $BI8=`%i%$%V%i%j$N(B fnmatch $B$N$h$&$K(B +shell $B%9%?%$%k$N%o%$%k%I%+!<%I%-%c%i%/%?$,;HMQ$G$-$^$9!#(B +"*" $BJ8;z$OG$0U$NJ8;zNs$K%^%C%A$7!"(B"?" $BJ8;z$OG$0U$N(B 1 $BJ8;z$K%^%C%A$7!"(B +"[seq]" $B$O(B seq $B$NG$0U$NJ8;z$K%^%C%A$7$^$9!#(B +"/" $BJ8;z$O$I$N%o%$%k%I%+!<%I$G$b%^%C%A$5$l$^$;$s!#(B +$BL@<(E*$K;XDj$9$kI,MW$,$"$j$^$9!#(B

    + +

    $B$3$l$h$j=@Fp$J%^%C%A%s%0$,I,MW$J>l9g$O!"$3$l$i$N%3%s%F%J$K@55,I=8=(B +(regex) $BHG$G$"$k(B +DirectoryMatch, +FilesMatch, +LocationMatch +$B$,$"$j!"%^%C%A$rA*Br$9$k$N$K(B perl $B8_49(B$B@55,I=8=(B$B$r;HMQ$G$-$^$9!#$7$+$7!" + +

    $BA4%f!<%6%G%#%l%/%H%j$N@_Dj$rJQ99$9$k!"Hs(B regex +$B%o%$%k%I%+!<%I%;%/%7%g%s$O + + +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +
    + +

    regex $B%;%/%7%g%s$r;HMQ$9$k$3$H$G!"2hA|%U%!%$%k$NB?$/$N%?%$%W$KBP$9$k(B +$B%"%/%;%9$r0lEY$K5qH]$G$-$^$9!#(B

    + +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +
    + +
    + +
    $B$$$D2?$r;H$&$+(B + +

    $B%U%!%$%k%7%9%F%`%3%s%F%J$H%&%'%V6u4V%3%s%F%J$r;H$$J,$1$k$N$O!"(B +$Bo$K4JC1$G$9!#%U%!%$%k%7%9%F%`$K0MB8$9$k(B +$B%*%V%8%'%/%H$K%G%#%l%/%F%#%V$rE,1~$9$k>l9g$O!"I,$:(B +Directory $B$+(B +Files +$B$r;HMQ$7$^$9!#%U%!%$%k%7%9%F%`$K0MB8$7$J$$%*%V%8%'%/%H(B +($B%G!<%?%Y!<%9$+$i@8@.$5$l$k%&%'%V%Z!<%8$J$I(B) +$B$K%G%#%l%/%F%#%V$rE,MQ$9$k:]$K$O!"(B +Location +$B$r;HMQ$7$^$9!#(B

    + +

    $B%U%!%$%k%7%9%F%`>e$N%*%V%8%'%/%H$X$N%"%/%;%9$r@)8B$9$k$?$a$K!"(B +Location +$B$r7h$7$F;HMQ$J$$$h$&$K$7$^$7$g$&!#(B +$BF10l$N%U%!%$%k%7%9%F%`0LCV$K%^%C%W$7$F$$$k!"%&%'%V6u4V0LCV(B (URL) +$B$,B??t$"$C$F!"@_Dj$7$?@)8B$r1*2s$5$l$F$7$^$&$+$b$7$l$J$$$+$i$G$9!#(B +$BNc$($P + + +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +
    + +

    http://yoursite.example.com/dir/ +$B$X$N%j%/%(%9%H$G$O>e.J8;z$r6hJL$7$J$$(B +$B%U%!%$%k%7%9%F%`$r;H$C$F$$$?$i$I$&$J$k$G$7$g$&(B? +http://yoursite.example.com/DIR/ +$B$X$N%j%/%(%9%H$G4JC1$K%"%/%;%9@)8B$r1*2s$5$l$F$7$^$$$^$9!#$3$l$KBP$7$F(B +Directory +$B%G%#%l%/%F%#%V$r;HMQ$9$k$H!"$I$N$h$&$K8F$S=P$5$l$?$+$K4X$o$i$:(B +$B$=$N>l=j$+$iDs6!$5$l$kFbMF$KE,MQ$5$l$^$9!#(B +($BNc30$O%U%!%$%k%7%9%F%`$N%j%s%/$G$9!#%7%s%\%j%C%/%j%s%/$r;H$C$F!"(B +$BF10l$N%G%#%l%/%H%j$rJ#?t$N%U%!%$%k%7%9%F%`$K@_CV$G$-$^$9!#(B +Directory +$B%G%#%l%/%F%#%V$O%Q%9L>$r%j%;%C%H$9$k$3$H$J$/%7%s%\%j%C%/%j%s%/$r(B +$BC)$j$^$9!#$G$9$+$i!"9bEY$J%;%-%e%j%F%#$,MW5a$5$l$k>l9g$O!"(B +$BE,@Z$K(B Options +$B%G%#%l%/%F%#%V$r;HMQ$7$F%7%s%\%j%C%/%j%s%/$rL58z$K$9$k$Y$-$G$9!#(B)

    + +

    $BBgJ8;z>.J8;z$r6hJL$9$k%U%!%$%k%7%9%F%`$r;HMQ$7$F$$$k$+$i>e5-$N$3$H$O(B +$BL54X78$@$H;W$o$l$k$+$b$7$l$^$;$s$,!"(B +$BF10l$N%U%!%$%k%7%9%F%`0LCV$KJ#?t$N%&%'%V6u4V0LCV$r%^%C%W$9$kJ}K!$O!"(B +$BB>$K$$$/$i$G$b$"$k$H$$$&$3$H$r3P$($F$$$F$/$@$5$$!#(B +$B$G$9$+$i$G$-$k8B$j%U%!%$%k%7%9%F%`%3%s%F%J$r;HMQ$7$F$/$@$5$$!#(B +$B$7$+$7$J$,$i0l$D$@$1Nc30$,$"$j$^$9!#(B +<Location /> $B%;%/%7%g%s$O$I$s$J(B URL +$B$K$b4X$o$i$:E,MQ$5$l$k$N$G!"40A4$K0BA4$G$9!#(B

    +
    + +
    + +
    $B%P!<%A%c%k%[%9%H(B + +

    VirtualHost +$B%3%s%F%J$OFCDj$N%[%9%H$KE,MQ$9$k%G%#%l%/%F%#%V$r3JG<$7$^$9!#(B +$B0lBf$N%^%7%s$GJ#?t$N%[%9%H$r0[$J$k@_Dj$GDs6!$7$?$$$H$-$KM-MQ$G$9!#(B +$B>\:Y$K4X$7$F$O(B$B%P!<%A%c%k%[%9%H%I%-%e%a%s%H(B$B$r(B +$B$4Mw2<$5$$!#(B

    +
    + +
    $B%W%m%/%7(B + +

    Proxy +$B$H(B ProxyMatch +$B%3%s%F%J$O!"FCDj$N(B URL $B$K%^%C%A$9$k(B mod_proxy +$B%W%m%/%7%5!<%P$r7PM3$7$F%"%/%;%9$7$?%5%$%H$KBP$7$F$N$_E,MQ$5$l$k(B +$B@_Dj%G%#%l%/%F%#%V$r3JG<$7$^$9!#Nc$($Pcnn.com +$B%&%'%V%5%$%H$K%"%/%;%9$9$k$?$a$KMQ$$$i$l$k%W%m%/%7%5!<%P$r(B +$B@)8B$7$^$9!#(B

    + + +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +
    +
    + +
    $B$I$N%G%#%l%/%F%#%V$,;H$($k$N(B? + +

    $B$I$N%?%$%W$N@_Dj%;%/%7%g%s$G$I$N%G%#%l%/%F%#%V$,;HMQ$G$-$k$+$O!"(B +$B%G%#%l%/%F%#%V$N(B Context +$B$r8+$F$/$@$5$$!#(B +Directory +$B$G;HMQ2DG=$J$b$N$OA4$F!"F1MM$K(B +DirectoryMatch, +Files, +FilesMatch, +Location, +LocationMatch, +Proxy, +ProxyMatch +$B%;%/%7%g%s$G;HMQ2DG=$G$9!#$7$+$7$J$,$i4v$D$+Nc30$bB8:_$7$^$9!#(B

    + +
      +
    • AllowOverride $B%G%#%l%/%F%#%V$O(B +Directory +$B%;%/%7%g%s$G$N$_;HMQ2DG=$G$9!#(B
    • + +
    • FollowSymLinks $B$H(B SymLinksIfOwnerMatch $B$N(B +Options $B$O!"(B +Directory +$B%;%/%7%g%s$+(B .htaccess $B%U%!%$%k$G$N$_;HMQ2DG=$G$9!#(B
    • + +
    • Options $B%G%#%l%/%F%#%V$O!"(B +Files +$B$H(B FilesMatch +$B%;%/%7%g%s$G$O;HMQ$G$-$^$;$s!#(B
    • +
    +
    + +
    $B%;%/%7%g%s$N%^!<%8J}K!(B + +

    $B%^!<%8$N=gHV$O0J2<$N$h$&$K$J$C$F$$$^$9(B:

    + +
      +
    1. Directory ($B@55,I=8=L5$7(B) $B$H(B + .htaccess $B$rF1;~$K(B (.htaccess $B$,5v2D$5$l$F$$$l$P!"$=$l$,(B + Directory $B$r>e=q$-$7$^$9(B) +
    2. + +
    3. DirectoryMatch + ($B$H(B <Directory ~>
    4. + +
    5. Files $B$H(B + FilesMatch $B$rF1;~$K(B
    6. + +
    7. Location $B$H(B + LocationMatch $B$rF1;~$K(B
    8. +
    + +

    Directory + $B0J30$O!"$=$l$>$l$N%0%k!<%W$O@_Dj%U%!%$%k$K8=$l$?=gHV$K=hM}$5$l$^$9!#(B + Directory ($B>e$N%0%k!<%W(B 1) + $B$O%G%#%l%/%H%j$,C;$$$b$N$+$iD9$$$b$N$X$H=hM}$5$l$^$9!#$G$9$+$i!"(B + $BNc$($P(B <Directory /var/web/dir1> $B$O(B + <Directory /var/web/dir/subdir> $B$NA0$K=hM}$5$l$^$9!#J#?t$N(B + Directory $B%;%/%7%g%s$,(B + $BF1$8%G%#%l%/%H%j$K(B + $BE,MQ$5$l$k>l9g$O!"@_Dj%U%!%$%kCf$N=gHV$K=>$C$F=hM}$5$l$^$9!#(B + Include + $B$K$h$C$FA^F~$5$l$?@_Dj$O(B $BA^F~$7$F$$$k%U%!%$%k$N(B + Include + $B%G%#%l%/%F%#%V$N0LCV$K$"$C$?$+$N$h$&$K07$o$l$^$9!#(B

    + +

    VirtualHost $B%;%/%7%g%sCf$N%;%/%7%g%s$O(B + $B%P!<%A%c%k%[%9%H$NDj5A$N30B&$NBP1~$9$k%;%/%7%g%s$N(B + $B8e(B$B$KE,MQ$5$l$^$9!#$3$l$K$h$j%P!<%A%c%k%[%9%H$,(B + $B%a%$%s$N%5!<%P@_Dj$r>e=q$-$G$-$k$h$&$J$j$^$9!#(B

    + +

    mod_proxy $B$G%j%/%(%9%H$,=hM}$5$l$k>l9g$O!"(B + $B=hM}=gHV$N$&$A!"(BDirectory $B%3%s%F%J$NItJ,$,(B + Proxy + $B%3%s%F%J$K + +

    $B8e$N%;%/%7%g%s$N%G%#%l%/%F%#%V$,A0$N%;%/%7%g%s$N$b$N$r>e=q$-$7$^$9!#(B

    + + +$B5;=Q%a%b(B + $BA0$rJQ49$9$kCJ3,(B (URL + $B$r%U%!%$%kL>$K%^%C%W$9$k$?$a$K(B Alias $B$d(B + DocumentRoot $B$,;HMQ$5$l$k$H$3$m(B) $B$ND>A0$K(B + Location/LocationMatch + $B$,9T$J$o$l$^$9!#(B + $B$3$l$i$rE,MQ$7$?7k2L$OJQ49$,=*$o$C$?8e$K40A4$K +
    $BNc(B + +

    $B + + +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +
    + +

    $B$b$C$H6qBNE*$J!"Directory +$B%;%/%7%g%s$K@_CV$5$l$?%"%/%;%9@)8B$K4X$o$i$:!"(B +Location +$B%;%/%7%g%s$,:G8e$KI>2A$5$l$F!"%5!<%P$X$N%"%/%;%9$O@)8B$5$l$^$;$s!#(B +$B8@$$49$($l$P!"%^!<%8$N=gHV$O=EMW$G!"Cm0U$7$F;HMQ$7$F$/$@$5$$(B!

    + + +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# Woops! This <Directory> section will have no effect
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +
    + +
    + +
    +
    diff --git a/trunk/docs/manual/sections.xml.ko b/trunk/docs/manual/sections.xml.ko new file mode 100644 index 0000000000..0d52576a60 --- /dev/null +++ b/trunk/docs/manual/sections.xml.ko @@ -0,0 +1,465 @@ + + + + + + + + + +¼½¼Ç ¼³Á¤ + +

    ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â +Áö½Ã¾î´Â ¼­¹ö Àüü¿¡ Àû¿ëµÇ°Å³ª, ƯÁ¤ µð·ºÅ丮, ÆÄÀÏ, È£½ºÆ®, +URL¿¡¸¸ Àû¿ëµÉ ¼ö ÀÖ´Ù. ÀÌ ¹®¼­´Â ´Ù¸¥ Áö½Ã¾îÀÇ Àû¿ë¹üÀ§¸¦ +Á¦ÇÑÇϱâÀ§ÇØ ¼³Á¤ ¼½¼ÇÀ̳ª .htaccess ÆÄÀÏÀ» +»ç¿ëÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù.

    +
    + +
    ¼³Á¤ ¼½¼ÇÀÇ Á¾·ù + + + +core +mod_proxy + + +Directory +DirectoryMatch +Files +FilesMatch +IfDefine +IfModule +Location +LocationMatch +Proxy +ProxyMatch +VirtualHost + + + +

    ¼½¼Ç¿¡´Â µÎ°¡Áö Á¾·ù°¡ ÀÖ´Ù. ´ëºÎºÐÀº ¸Å¿äû¸¶´Ù 󸮵ȴÙ. +ÇØ´çÇÏ´Â ¿äû¿¡¸¸ ¾È¿¡ Æ÷ÇÔÇÑ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ¹Ý´ë·Î, IfDefine°ú IfModuleÀº ¼­¹ö°¡ +½ÃÀÛÇÒ¶§¿Í ²¨Áú¶§¸¸ ó¸®ÇÑ´Ù. ½ÃÀÛÇÒ¶§ »óÅ°¡ ÂüÀÌ¸é ¾È¿¡ ÀÖ´Â +Áö½Ã¾î°¡ ¸ðµç ¿äû¿¡ Àû¿ëµÈ´Ù. ÂüÀÌ ¾Æ´Ï¸é ¾È¿¡ ÀÖ´Â Áö½Ã¾î´Â +¹«½ÃÇÑ´Ù.

    + +

    IfDefine +Áö½Ã¾î´Â httpd ¸í·ÉÇà¿¡ ÀûÀýÇÑ ÆĶó¹ÌÅÍ°¡ ÀÖ´Â +°æ¿ì¿¡¸¸ ¾È¿¡ Æ÷ÇÔÇÑ Áö½Ã¾î¸¦ Àû¿ëÇÑ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, +¼­¹ö¸¦ httpd -DClosedForNow·Î ½ÃÀÛÇÒ °æ¿ì¿¡¸¸ +¸ðµç ¿äûÀÌ ´Ù¸¥ »çÀÌÆ®·Î ¸®´ÙÀÌ·º¼ÇµÈ´Ù:

    + + +<IfDefine ClosedForNow>
    +Redirect / http://otherserver.example.com/
    +</IfDefine> +
    + +

    IfModule +Áö½Ã¾îµµ ƯÁ¤ ¸ðµâÀÌ ¼­¹ö¿¡ Æ÷ÇÔµÈ °æ¿ì¿¡¸¸ ¾È¿¡ µç Áö½Ã¾î¸¦ +Àû¿ëÇÑ´Ù´Â Á¡À» Á¦¿ÜÇÏ°í´Â ¸Å¿ì ºñ½ÁÇÏ´Ù. ¸ðµâÀ» ¼­¹ö¿¡ Á¤ÀûÀ¸·Î +ÄÄÆÄÀÏÇϰųª µ¿ÀûÀ¸·Î ÄÄÆÄÀÏÇÑÈÄ ¼³Á¤ÆÄÀÏ ¾Õ¿¡ LoadModule ÁÙÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ÀÌ +Áö½Ã¾î´Â ƯÁ¤ ¸ðµâÀÇ ¼³Ä¡À¯¹«¿¡ µû¶ó ¼³Á¤ÆÄÀÏÀÌ ´Ù¸¦ ÇÊ¿ä°¡ +ÀÖÀ»¶§¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù. ¸ðµâÀÌ ¾ø´Â °æ¿ì À¯¿ëÇÑ ¿À·ù¹®ÀÌ ³ª¿ÀÁö¾ÊÀ» +¼ö Àֱ⠶§¹®¿¡ ¾ðÁ¦³ª »ç¿ëÇÏ±æ ¿øÇÏ´Â Áö½Ã¾î¸¦ ¾È¿¡ µÎ¸é ¾ÈµÈ´Ù.

    + +

    ´ÙÀ½ ¿¹¿¡¼­ mod_mime_magicÀÌ ÀÖÀ»¶§¸¸ MimeMagicFiles Áö½Ã¾î¸¦ +ó¸®ÇÑ´Ù.

    + + +<IfModule mod_mime_magic.c>
    +MimeMagicFile conf/magic
    +</IfModule> +
    + +

    IfDefine°ú +IfModuleÀÇ +°Ë»ç ¾Õ¿¡ "!"À» ºÙ¿© Á¶°ÇÀ» ¿ªÀ¸·Î ÇÒ ¼ö ÀÖ´Ù. ¶Ç, ¿©·¯ ¼½¼ÇµéÀ» +°ãÃļ­ »ç¿ëÇÏ¿© ´õ º¹ÀâÇÑ È¿°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

    +
    + +
    ÆÄÀϽýºÅÛ°ú À¥°ø°£ + +

    °¡Àå ÀÚÁÖ »ç¿ëµÇ´Â ¼³Á¤ ¼½¼ÇÀº ÆÄÀϽýºÅÛ°ú À¥°ø°£(webspace)ÀÇ +ƯÁ¤ Àå¼Ò¿¡ ´ëÇÑ ¼³Á¤À» º¯°æÇÏ´Â °ÍµéÀÌ´Ù. ¸ÕÀú ÀÌ µÑÀÇ Â÷À̸¦ +ÀÌÇØÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù. ÆÄÀϽýºÅÛÀº ¿î¿µÃ¼Á¦ ÀÔÀå¿¡¼­ µð½ºÅ©¸¦ +º¸´Â °üÁ¡ÀÌ´Ù. ¿¹¸¦ µé¾î, ±âº»°ªÀ¸·Î ¾ÆÆÄÄ¡¸¦ ¼³Ä¡¸¦ Çϸé À¯´Ð½º +ÆÄÀϽýºÅÛÀÇ °æ¿ì /usr/local/apache2, À©µµ¿ìÁî +ÆÄÀϽýºÅÛÀÇ °æ¿ì "c:/Program Files/Apache +Group/Apache2"¿¡ ¼³Ä¡µÈ´Ù. (¾ÆÆÄÄ¡´Â À©µµ¿ìÁî¿¡¼­ Á¶Â÷ +Ç×»ó, ¿ª½½·¡½¬°¡ ¾Æ´Ñ, ½½·¡½¬¸¦ »ç¿ëÇÔÀ» ÁÖÀÇÇ϶ó.) ¹Ý´ë·Î +À¥°ø°£Àº À¥¼­¹ö°¡ Á¦°øÇÏ°í Ŭ¶óÀ̾ðÆ®°¡ º¸°ÔµÉ »çÀÌÆ®ÀÇ °üÁ¡ÀÌ´Ù. +±×·¡¼­ À¯´Ð½º¿¡¼­ ±âº» ¾ÆÆÄÄ¡ ¼³Ä¡¸¦ ÇÑ °æ¿ì À¥°æ·ÎÀÇ °æ·Î +/dir/Àº ÆÄÀϽýºÅÛ °æ·Î +/usr/local/apache2/htdocs/dir/¿¡ ÇØ´çÇÑ´Ù. À¥°ø°£Àº +µ¥ÀÌŸº£À̽º µî¿¡¼­ µ¿ÀûÀ¸·Î »ý¼ºµÉ ¼ö Àֱ⶧¹®¿¡ ¹Ýµå½Ã +ÆÄÀϽýºÅÛ¿¡ Á÷Á¢ ´ëÀÀµÉ ÇÊ¿ä´Â ¾ø´Ù.

    + +
    ÆÄÀϽýºÅÛ ¼½¼Ç + +

    Directory¿Í +Files Áö½Ã¾î¿Í +Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â Áö½Ã¾î´Â ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐ¿¡ Áö½Ã¾î¸¦ +Àû¿ëÇÑ´Ù. Directory Áö½Ã¾î¿¡ Æ÷ÇÔµÈ Áö½Ã¾îµéÀº +ÁöÁ¤ÇÑ ÆÄÀϽýºÅÛ µð·ºÅ丮¿Í ±× ÇÏÀ§ µð·ºÅ丮¿¡ Àû¿ëµÈ´Ù. .htaccess ÆÄÀÏÀ» »ç¿ëÇصµ °á°ú´Â +°°´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, µð·ºÅ丮 ¸ñ·Ï(index)ÀÌ +/var/web/dir1 ÀÌÇÏ µð·ºÅ丮¿¡¼­ µð·ºÅ丮 ¸ñ·Ï(index)ÀÌ +°¡´ÉÇÏ´Ù.

    + + +<Directory /var/web/dir1>
    +Options +Indexes
    +</Directory> +
    + +

    Files ¼½¼Ç¿¡ Æ÷ÇÔµÈ Áö½Ã¾îµéÀº ¾î¶² +µð·ºÅ丮¿¡ ÀÖ´ÂÁö °ü°è¾øÀÌ ÁöÁ¤ÇÑ À̸§À» °¡Áø ÆÄÀÏ¿¡ Àû¿ëµÈ´Ù. +¼³Á¤ÆÄÀÏÀÇ ÁÖ¼³Á¤ºÎºÐ¿¡ ÀÖ´Â ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, Àå¼Ò¿Í +°ü°è¾øÀÌ private.htmlÀ̶õ À̸§À» ÇÑ ÆÄÀÏÀÇ Á¢±ÙÀ» +°ÅºÎÇÑ´Ù.

    + + +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files> +
    + +

    ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐ¿¡ ÀÖ´Â ÆÄÀÏÀ» ÁöĪÇϱâÀ§ÇØ Files¿Í Directory ¼½¼ÇÀ» °°ÀÌ +»ç¿ëÇÑ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, +/var/web/dir1/private.html, +/var/web/dir1/subdir2/private.html, +/var/web/dir1/subdir3/private.html °°ÀÌ +/var/web/dir1/ µð·ºÅ丮 ¾Æ·¡¿¡ ÀÖ´Â À̸§ÀÌ +private.htmlÀÎ ÆÄÀÏÀÇ Á¢±ÙÀ» °ÅºÎÇÑ´Ù.

    + + +<Directory /var/web/dir1>
    +<Files private.html>
    +Order allow,deny
    +Deny from all
    +</Files>
    +</Directory> +
    +
    + +
    À¥°ø°£ ¼½¼Ç + +

    Location +Áö½Ã¾î¿Í ÀÌ¿¡ ÇØ´çÇÏ´Â Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â Áö½Ã¾î´Â ¹Ý´ë·Î +ƯÁ¤ À¥°ø°£ÀÇ ¼³Á¤À» ¹Ù²Û´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, /privateÀ¸·Î +½ÃÀÛÇÏ´Â URL-°æ·ÎÀÇ Á¢±ÙÀÌ °ÅºÎµÈ´Ù. ¿©±â¿¡´Â +http://yoursite.example.com/private, +http://yoursite.example.com/private123, +http://yoursite.example.com/private/dir/file.html +°°ÀÌ /private ¹®ÀÚ¿­·Î ½ÃÀÛÇÏ´Â ¿äûÀÌ ÇØ´çµÈ´Ù.

    + + +<Location /private>
    +Order Allow,Deny
    +Deny from all
    +</Location> +
    + +

    Location +Áö½Ã¾î´Â ÆÄÀϽýºÅÛ¿¡ ´ëÀÀÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ´ÙÀ½ ¿¹´Â ¾î¶»°Ô ƯÁ¤ +URLÀ» mod_status°¡ Á¦°øÇÏ´Â ¾ÆÆÄÄ¡ ³»ºÎ Çڵ鷯·Î +´ëÀÀ½ÃÅ°´ÂÁö¸¦ º¸¿©ÁØ´Ù. ÆÄÀϽýºÅÛ¿¡ server-status¶ó´Â +ÆÄÀÏÀº ÇÊ¿ä¾ø´Ù.

    + + +<Location /server-status>
    +SetHandler server-status
    +</Location> +
    +
    + +
    ¿ÍÀϵåÄ«µå¿Í Á¤±ÔÇ¥Çö½Ä + +

    Directory, +Files, +Location +Áö½Ã¾î¿¡¼­ C Ç¥ÁØ ÆÄÀ̺귯¸®ÀÇ fnmatch¿Í °°Àº +½©¿¡¼­ »ç¿ëÇÏ´Â ¿ÍÀϵåÄ«µå ¹®ÀÚ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. +"*" ¹®ÀÚ´Â ¾î¶² ¹®ÀÚ¿­ÀÌ¶óµµ ³ªÅ¸³»°í, "?" ¹®ÀÚ´Â ¾î¶² ¹®ÀÚ ÇÑ°³¸¦ +³ªÅ¸³»¸ç, "[seq]"´Â seq Áß¿¡ ÇÑ ¹®ÀÚ¸¦ ³ªÅ¸³½´Ù. +¾î¶² ¿ÍÀϵåÄ«µåµµ "/" ¹®ÀÚ¸¦ ³ªÅ¸³»Áö´Â ¸øÇÑ´Ù. ±×·¡¼­ ÀÌ ¹®ÀÚ´Â +Á÷Á¢ »ç¿ëÇØ¾ß ÇÑ´Ù.

    + +

    ´õ À¯¿¬ÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇϸé perlȣȯ Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏ´Â DirectoryMatch, FilesMatch, LocationMatch¸¦ »ç¿ëÇÒ +¼ö ÀÖ´Ù. ±×·¯³ª ¾Æ·¡ ¼³Á¤ÀÇ °áÇÕ¿¡ °üÇÑ Àý¿¡¼­ Á¤±ÔÇ¥Çö½Ä ¼½¼ÇÀ» +»ç¿ëÇϸé Áö½Ã¾î°¡ Àû¿ëµÇ´Â ¹æ¹ýÀÌ ¾î¶»°Ô º¯ÇÏ´ÂÁö »ìÆìºÁ¶ó.

    + +

    ¸ðµç »ç¿ëÀÚ µð·ºÅ丮 ¼³Á¤À» º¯°æÇÏ´Â ºñÁ¤±ÔÇ¥Çö½Ä ¿ÍÀϵåÄ«µå +¼½¼ÇÀº ´ÙÀ½°ú °°´Ù:

    + + +<Directory /home/*/public_html>
    +Options Indexes
    +</Directory> +
    + +

    Á¤±ÔÇ¥Çö½Ä ¼½¼ÇÀ» »ç¿ëÇÏ¿© Çѹø¿¡ ¿©·¯ Á¾·ùÀÇ ±×¸²ÆÄÀÏ¿¡ +´ëÇÑ Á¢±ÙÀ» °ÅºÎÇÒ ¼ö ÀÖ´Ù:

    + +<FilesMatch \.(?i:gif|jpe?g|png)$>
    +Order allow,deny
    +Deny from all
    +</FilesMatch> +
    + +
    + +
    ¹«¾ùÀ» »ç¿ëÇϳª + +

    ÆÄÀϽýºÅÛ ¼½¼Ç°ú À¥°ø°£ ¼½¼Ç Áß Çϳª¸¦ ¼±ÅÃÇÏ´Â °ÍÀº ½ÇÁ¦·Î +¸Å¿ì ½±´Ù. ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â °´Ã¼¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÒ¶§´Â Ç×»ó +Directory³ª +Files¸¦ +»ç¿ëÇÑ´Ù. (µ¥ÀÌŸº£À̽º¿¡¼­ »ý¼ºÇÑ À¥ÆäÀÌÁö¿Í °°ÀÌ) ÆÄÀϽýºÅÛ¿¡ +ÀÖÁö ¾Ê´Â °´Ã¼¿¡ Áö½Ã¾î¸¦ Àû¿ëÇÒ¶§´Â LocationÀ» »ç¿ëÇÑ´Ù.

    + +

    ÆÄÀϽýºÅÛ¿¡ ÀÖ´Â °´Ã¼ÀÇ Á¢±ÙÀ» Á¦ÇÑÇϱâÀ§ÇØ LocationÀ» »ç¿ëÇϸé +Àý´ë ¾ÈµÈ´Ù. ¿©·¯ ´Ù¸¥ À¥°ø°£ Àå¼Ò(URL)°¡ °°Àº ÆÄÀϽýºÅÛ Àå¼Ò¿¡ +´ëÀÀµÉ ¼ö ÀÖÀ¸¹Ç·Î, °É¾îµÐ Á¦ÇÑÀ» ¿ìȸÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. ´ÙÀ½ +¼³Á¤ÀÇ ¿¹¸¦ »ìÆ캸ÀÚ:

    + + +<Location /dir/>
    +Order allow,deny
    +Deny from all
    +</Location> +
    + +

    ÀÌ ¼³Á¤Àº http://yoursite.example.com/dir/À» +¿äûÇÑ´Ù¸é Àß ÀÛµ¿ÇÑ´Ù. ±×·¯³ª ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê´Â ÆÄÀϽýºÅÛÀ» +»ç¿ëÇÑ´Ù¸é ¾î¶»°ÔµÇ³ª? +http://yoursite.example.com/DIR/À» ¿äûÇÏ¿© ½±°Ô +Á¦ÇÑÀ» ¿ìȸÇÒ ¼ö ÀÖ´Ù. ¹Ý´ë·Î Directory Áö½Ã¾î´Â ¾î¶»°Ô ¿äûÇÏ¿´´ÂÁö +°ü°è¾øÀÌ ±× Àå¼Ò¿¡¼­ ¼­ºñ½ºµÇ´Â ³»¿ë¿¡ Àû¿ëµÈ´Ù. (¿¹¿Ü´Â ÆÄÀϽýºÅÛ +¸µÅ©¸¦ »ç¿ëÇÏ´Â °æ¿ì´Ù. ½Éº¼¸µÅ©¸¦ »ç¿ëÇÏ¿© ÇÑ µð·ºÅ丮¸¦ +ÆÄÀϽýºÅÛÀÇ ¿©·¯ Àå¼Ò¿¡ µÑ ¼ö ÀÖ´Ù. Directory Áö½Ã¾î´Â ½Éº¼¸µÅ©¸¦ µû¶ó°£´Ù. +±×·¯¹Ç·Î ³ôÀº ¼öÁØÀÇ º¸¾ÈÀ» À§Çؼ­´Â ÀûÀýÇÑ Options Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ½Éº¼¸µÅ©¸¦ +¹«½ÃÇØ¾ß ÇÑ´Ù.)

    + +

    ¾Æ¸¶µµ ´ç½ÅÀº ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏ´Â ÆÄÀϽýºÅÛÀ» »ç¿ëÇϹǷΠ+ÀÌ·± ÀÏÀÌ ÀϾÁö ¾Ê´Â´Ù°í »ý°¢ÇÒÁöµµ ¸ð¸¥´Ù. ±×·¯³ª ´Ù¸¥ +¹æ¹ýÀ¸·Îµµ ¿©·¯ À¥°ø°£ À§Ä¡°¡ ÇÑ ÆÄÀϽýºÅÛ À§Ä¡¿¡ ´ëÀÀµÉ ¼ö +ÀÖÀ½À» ±â¾ïÇ϶ó. ±×·¡¼­ °¡´ÉÇϸé Ç×»ó ÆÄÀϽýºÅÛ ¼½¼ÇÀ» »ç¿ëÇØ¾ß +ÇÑ´Ù. ±×·¯³ª ÀÌ ±ÔÄ¢¿¡ ¿¹¿Ü°¡ Çϳª ÀÖ´Ù. ¼³Á¤ Á¦ÇÑÀ» +<Location /> ¼½¼Ç¿¡ µÎ¸é ÀÌ ¼½¼ÇÀÌ Æ¯Á¤ +URLÀÌ ¾Æ´Ñ ¸ðµç ¿äû¿¡ Àû¿ëµÇ¹Ç·Î ¿Ïº®ÇÏ°Ô ¾ÈÀüÇÏ´Ù.

    +
    + +
    + +
    °¡»óÈ£½ºÆ® + +

    VirtualHost +¼½¼ÇÀº ƯÁ¤ È£½ºÆ®¿¡ Àû¿ëµÇ´Â Áö½Ã¾îµéÀ» Æ÷ÇÔÇÑ´Ù. ÀÌ´Â ÇÑ +ÄÄÇ»ÅÍ¿¡¼­ °¢°¢ ´Ù¸¥ ¼³Á¤À» »ç¿ëÇÑ ¿©·¯ È£½ºÆ®¸¦ ¼­ºñ½ºÇÒ¶§ +À¯¿ëÇÏ´Ù. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â °¡»óÈ£½ºÆ® ¹®¼­¸¦ +Âü°íÇ϶ó.

    +
    + +
    ÇÁ·Ï½Ã + +

    Proxy¿Í +ProxyMatch +¼½¼ÇÀº ÁöÁ¤ÇÑ URL¿¡ ´ëÇØ mod_proxy ÇÁ·Ï½Ã ¼­¹ö¸¦ +°ÅÃÄ Á¢±ÙÇÏ´Â °æ¿ì¿¡¸¸ Àû¿ëµÈ´Ù. ´ÙÀ½ ¼³Á¤À» ¿¹·Î µé¸é, ÇÁ·Ï½Ã +¼­¹ö¸¦ ÅëÇØ cnn.com À¥»çÀÌÆ®¿¡ Á¢±ÙÇÒ ¼ö ¾ø´Ù.

    + + +<Proxy http://cnn.com/*>
    +Order allow,deny
    +Deny from all
    +</Proxy> +
    +
    + +
    ¾È¿¡ ¾î¶² Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö +ÀÖ³ª? + +

    ¾î¶² ¼³Á¤ ¼½¼Ç¾È¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â Áö½Ã¾î¸¦ ¾Ë·Á¸é Áö½Ã¾îÀÇ +»ç¿ëÀå¼Ò¸¦ È®ÀÎÇ϶ó. +Directory¿¡¼­ +»ç¿ë°¡´ÉÇÑ Áö½Ã¾î´Â DirectoryMatch, Files, FilesMatch, Location, LocationMatch, Proxy, ProxyMatch ¼½¼Ç¿¡¼­µµ »ç¿ë°¡´ÉÇÏ´Ù. +±×·¯³ª, ¿¹¿Ü°¡ ÀÖ´Ù:

    + +
      +
    • AllowOverride Áö½Ã¾î´Â +Directory +¼½¼Ç¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    • FollowSymLinks, SymLinksIfOwnerMatch, +Options´Â Directory ¼½¼ÇÀ̳ª +.htaccess ÆÄÀÏ¿¡¼­¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
    • + +
    • Options Áö½Ã¾î´Â +Files°ú +FilesMatch +¼½¼Ç¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • +
    +
    + +
    ¼½¼ÇµéÀÌ °áÇÕÇÏ´Â ¹æ¹ý + +

    ¼³Á¤ ¼½¼ÇÀº ¸Å¿ì Ưº°ÇÑ ¹æ¹ýÀ¸·Î Àû¿ëµÈ´Ù. ÀÌ ¼ø¼­°¡ ¼³Á¤ +Áö½Ã¾î¸¦ Çؼ®ÇÏ´Â ¹æ¹ý¿¡ Áß¿äÇÑ ¿µÇâÀ» Áֱ⶧¹®¿¡ ÀÌ ¹æ¹ýÀ» +ÀÌÇØÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù.

    + +

    °áÇÕÇÏ´Â ¼ø¼­´Â:

    + +
      +
    1. (Á¤±ÔÇ¥Çö½ÄÀ» »ç¿ëÇÏÁö¾Ê´Â) Directory¿Í .htaccess´Â + µ¿½Ã¿¡ ÀϾ´Ù (°æ¿ì¿¡ µû¶ó .htaccessÀÌ + Directory¸¦ + ¹«½ÃÇϵµ·Ï ¼³Á¤ÇÒ ¼ö ÀÖ´Ù)
    2. + +
    3. DirectoryMatch (±×¸®°í + <Directory ~>)
    4. + +
    5. Files¿Í FilesMatch´Â µ¿½Ã¿¡ ÀϾ´Ù
    6. + +
    7. Location°ú LocationMatch´Â µ¿½Ã¿¡ ÀϾ´Ù
    8. +
    + +

    Directory¸¦ Á¦¿ÜÇÏ°í °¢ ¼½¼ÇµéÀ» + ¼³Á¤ÆÄÀÏ¿¡ ³ª¿Â ¼ø¼­´ë·Î 󸮵ȴÙ. (À§ÀÇ ¼ø¼­ 1) Directory´Â µð·ºÅ丮 + ³»¿ëÀÌ °¡Àå ªÀº °Í¿¡¼­ ±äÂÊÀ¸·Î 󸮵ȴÙ. ±×·¡¼­ ¿¹¸¦ µé¾î, + <Directory /var/web/dir>À» + <Directory /var/web/dir/subdir> ÀÌÀü¿¡ + ó¸®ÇÑ´Ù. °°Àº µð·ºÅ丮¸¦ ÁöĪÇÏ´Â ¿©·¯ Directory ¼½¼ÇÀÌ + ÀÖ´Ù¸é À̵éÀ» ¼³Á¤ÆÄÀÏ ¼ø¼­´ë·Î ó¸®ÇÑ´Ù. Include Áö½Ã¾î·Î Æ÷ÇÔÇÑ ¼³Á¤Àº + Include Áö½Ã¾î À§Ä¡¿¡ + Æ÷ÇÔÇÑ ÆÄÀÏ ³»¿ëÀÌ ÀÖ´Â °Íó·³ ó¸®ÇÑ´Ù.

    + +

    VirtualHost ¼½¼Ç ¾È¿¡ Æ÷ÇÔµÈ ¼½¼ÇÀº + °¡»óÈ£½ºÆ® Á¤ÀÇ ¹Û¿¡ ÀÖ´Â ÇØ´ç ¼½¼Ç ÀÌÈÄ¿¡ Àû¿ëµÈ´Ù. + ±×·¡¼­ °¡»óÈ£½ºÆ® ¾È¿¡¼­ ÁÖ¼­¹öÀÇ ¼³Á¤»çÇ×À» ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù.

    + +

    mod_proxy°¡ ¿äû ¼­ºñ½ºÇÒ¶§, Proxy ¼½¼ÇÀÇ + 󸮼ø¼­´Â Directory ¼½¼Ç°ú °°´Ù.

    + +

    ´ÙÀ½¿¡ ³ª¿À´Â ¼½¼ÇÀº ÀÌÀü ¼½¼ÇÀÇ °á°ú¸¦ ¼öÁ¤ÇÑ´Ù.

    + +±â¼úÀû ÁÖÀÇ + ½ÇÁ¦·Î + <Location>/<LocationMatch>´Â + (Aliases¿Í DocumentRoot¸¦ »ç¿ëÇÏ¿© + URLÀ» ÆÄÀϸíÀ¸·Î º¯È¯ÇÏ´Â) À̸§¹ø¿ª ´Ü°è ÀÌÀü¿¡ 󸮵ȴÙ. + º¯¿ªÀÌ ³¡³­ ÀÌÈÄ¿¡´Â ¿ÏÀüÈ÷ ¹«½ÃÇÑ´Ù. + + +
    ¿¹Á¦ + +

    ´ÙÀ½Àº °ãÇÕÇÏ´Â ¼ø¼­¸¦ ¼³¸íÇÏ´Â ¿¹´Ù. ÀÌµé ¸ðµÎ ¿äû¿¡ +Àû¿ëµÈ´Ù°í °¡Á¤Çϸé Áö½Ã¾î´Â A > B > C > D > E +¼ø¼­·Î 󸮵ȴÙ.

    + + +<Location />
    +E
    +</Location>
    +
    +<Files f.html>
    +D
    +</Files>
    +
    +<VirtualHost *>
    +<Directory /a/b>
    +B
    +</Directory>
    +</VirtualHost>
    +
    +<DirectoryMatch "^.*b$">
    +C
    +</DirectoryMatch>
    +
    +<Directory /a/b>
    +A
    +</Directory>
    +
    +
    + +

    ´õ Çö½ÇÀûÀÎ ¿¹´Â ´ÙÀ½°ú °°´Ù. Location ¼½¼ÇÀ» ³ªÁß¿¡ ó¸®ÇϹǷΠ+Directory +¼½¼Ç¿¡ ÀÖ´Â Á¢±ÙÁ¦ÇÑ°ú °ü°è¾øÀÌ ¼­¹ö¿¡ ¹«Á¦ÇÑ Á¢±ÙÀ» °¡´ÉÇÏ´Ù. +Áï, °áÇÕÇÏ´Â ¼ø¼­´Â Áß¿äÇϹǷΠÁÖÀÇÇ϶ó!

    + + +<Location />
    +Order deny,allow
    +Allow from all
    +</Location>
    +
    +# ¾Ç! ÀÌ <Directory> ¼½¼ÇÀº ¾Æ¹«·± È¿°ú°¡ ¾ø´Ù
    +<Directory />
    +Order allow,deny
    +Allow from all
    +Deny from badguy.example.com
    +</Directory> +
    + +
    + +
    +
    + diff --git a/trunk/docs/manual/sections.xml.meta b/trunk/docs/manual/sections.xml.meta new file mode 100644 index 0000000000..89485c2bd6 --- /dev/null +++ b/trunk/docs/manual/sections.xml.meta @@ -0,0 +1,13 @@ + + + + sections + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/server-wide.html b/trunk/docs/manual/server-wide.html new file mode 100644 index 0000000000..d43014c0f6 --- /dev/null +++ b/trunk/docs/manual/server-wide.html @@ -0,0 +1,11 @@ +URI: server-wide.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: server-wide.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: server-wide.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/server-wide.html.en b/trunk/docs/manual/server-wide.html.en new file mode 100644 index 0000000000..6b81119009 --- /dev/null +++ b/trunk/docs/manual/server-wide.html.en @@ -0,0 +1,99 @@ + + + +Server-Wide Configuration - Apache HTTP Server + + + + + +
    <-
    +

    Server-Wide Configuration

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    This document explains some of the directives provided by +the core server which are used to configure +the basic operations of the server.

    +
    + +
    top
    +
    +

    Server Identification

    + + + + +

    The ServerAdmin and + ServerTokens directives + control what information about the server will be presented + in server-generated documents such as error messages. The + ServerTokens directive + sets the value of the Server HTTP response header field.

    + +

    The ServerName and + UseCanonicalName + directives are used by the server to determine how to construct + self-referential URLs. For example, when a client requests a + directory, but does not include the trailing slash in the + directory name, Apache must redirect the client to the full + name including the trailing slash so that the client will + correctly resolve relative references in the document.

    +
    top
    +
    +

    File Locations

    + + + + +

    These directives control the locations of the various files + that Apache needs for proper operation. When the pathname used + does not begin with a slash (/), the files are located relative + to the ServerRoot. Be careful + about locating files in paths which are writable by non-root users. + See the security tips + documentation for more details.

    +
    top
    +
    +

    Limiting Resource Usage

    + + + + +

    The LimitRequest* + directives are used to place limits on the amount of resources + Apache will use in reading requests from clients. By limiting + these values, some kinds of denial of service attacks can be + mitigated.

    + +

    The RLimit* directives + are used to limit the amount of resources which can be used by + processes forked off from the Apache children. In particular, + this will control resources used by CGI scripts and SSI exec + commands.

    + +

    The ThreadStackSize + directive is used with some platforms to control the stack size.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/server-wide.html.ja.euc-jp b/trunk/docs/manual/server-wide.html.ja.euc-jp new file mode 100644 index 0000000000..bd3a2d5459 --- /dev/null +++ b/trunk/docs/manual/server-wide.html.ja.euc-jp @@ -0,0 +1,99 @@ + + + +¥µ¡¼¥ÐÁ´ÂΤÎÀßÄê - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥µ¡¼¥ÐÁ´ÂΤÎÀßÄê

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ç¤Ïcore +¥µ¡¼¥Ð¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ç¡¢ +´ðËÜÆ°ºî¤òÀßÄꤹ¤ë¤¿¤á¤Î¤â¤Î¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥µ¡¼¥Ð ID

    + + + + +

    ServerAdmin ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + ServerTokens + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ê¤É¤Î¥µ¡¼¥Ð¤¬ºî¤ë¥É¥­¥å¥á¥ó¥È¤Ë¡¢ + ¤É¤Î¤è¤¦¤Ê¥µ¡¼¥Ð¤Î¾ðÊó¤òɽ¼¨¤¹¤ë¤«¤òÀ©¸æ¤·¤Þ¤¹¡£ + ServerTokens ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Server HTTP + ¥ì¥¹¥Ý¥ó¥¹¥Ø¥Ã¥À¥Õ¥£¡¼¥ë¥É¤ÎÃͤòÀßÄꤷ¤Þ¤¹¡£

    + +

    ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + UseCanonicalName + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢¥µ¡¼¥Ð¤¬¼«Ê¬¼«¿È¤ò»²¾È¤¹¤ë URL + ¤òºî¤ë¤È¤­¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬¥Ç¥£¥ì¥¯¥È¥ê¤òÍ׵ᤷ¤Æ¡¢ + ¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê̾¤ÎºÇ¸å¤Ë¥¹¥é¥Ã¥·¥å¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¢ + ¥É¥­¥å¥á¥ó¥È¤ÎÁêÂÐŪ¤Ê»²¾È¤òÀµ¤·¤¯²ò·è¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢ + Apache ¤ÏºÇ¸å¤Î¥¹¥é¥Ã¥·¥å¤ò´Þ¤ó¤À´°Á´¤Ê¥Ñ¥¹¤Ë¥¯¥é¥¤¥¢¥ó¥È¤ò + ¥ê¥À¥¤¥ì¥¯¥È¤µ¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    +
    top
    +
    +

    ¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ

    + + + + +

    ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache + ¤¬Å¬ÀÚ¤ÊÆ°ºî¤ò¤¹¤ë¤¿¤á¤ËɬÍפʳƼï¥Õ¥¡¥¤¥ë¤Î°ÌÃÖ¤òÀ©¸æ¤·¤Þ¤¹¡£ + ¥Ñ¥¹¤¬¥¹¥é¥Ã¥·¥å (/) ¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢¥Õ¥¡¥¤¥ë¤Ï + ServerRoot ¤«¤é¤ÎÁêÂХѥ¹¤È¤·¤Æ + õ¤µ¤ì¤Þ¤¹¡£root + °Ê³°¤Î¥æ¡¼¥¶¤¬½ñ¤­¹þ¤ß²Äǽ¤Ê¥Ñ¥¹¤Ë¥Õ¥¡¥¤¥ë¤òÃÖ¤¯¾ì¹ç¤ÏÃí°Õ¤¬É¬ÍפǤ¹¡£ + ¾ÜºÙ¤Ï¡Ö¥»¥­¥å¥ê¥Æ¥£¾ðÊó¡× + ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    ¥ê¥½¡¼¥¹¤ÎÀ©¸Â

    + + + + +

    LimitRequest* ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache + ¤¬¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¥ê¥¯¥¨¥¹¥ÈÆɤ߹þ¤ß¤Ç»È¤¦ + ¥ê¥½¡¼¥¹¤òÀ©¸Â¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£¤³¤ì¤é¤ÎÃͤòÀ©¸Â¤¹¤ë¤³¤È¤Ç¡¢ + ¤¤¤¯¤Ä¤«¤Î¥µ¡¼¥Ó¥¹µñÈݹ¶·â¤Ï±Æ¶Á¤òϤ餲¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    RLimit* ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢Apache ¤Î»Ò¥×¥í¥»¥¹¤«¤é + fork ¤µ¤ì¤¿¥×¥í¥»¥¹¤¬»ÈÍѤ¹¤ë¥ê¥½¡¼¥¹¤òÀ©¸Â¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ + Æäˡ¢¤³¤ì¤Ï CGI ¥¹¥¯¥ê¥×¥È¤È SSI exec + ¥³¥Þ¥ó¥É¤Ç»È¤ï¤ì¤ë¥ê¥½¡¼¥¹¤òÀ©¸æ¤·¤Þ¤¹¡£

    + +

    ThreadStackSize ¤Ï Netware + ¤Ç¤Î¤ß¡¢¥¹¥¿¥Ã¥¯¤ÎÂ礭¤µ¤òÀ©¸æ¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/server-wide.html.ko.euc-kr b/trunk/docs/manual/server-wide.html.ko.euc-kr new file mode 100644 index 0000000000..fac09ac449 --- /dev/null +++ b/trunk/docs/manual/server-wide.html.ko.euc-kr @@ -0,0 +1,93 @@ + + + +¼­¹ö Àü¿ª ¼³Á¤ - Apache HTTP Server + + + + + +
    <-
    +

    ¼­¹ö Àü¿ª ¼³Á¤

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â core ¼­¹ö°¡ ¼­¹öÀÇ ±âº» ÇൿÀ» +¼³Á¤ÇϱâÀ§ÇØ Á¦°øÇÏ´Â Áö½Ã¾îÁß ÀϺθ¦ ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    ¼­¹ö ½Äº°

    + + + + +

    ServerAdmin°ú + ServerTokens Áö½Ã¾î´Â + ¿À·ù¹® µî ¼­¹ö°¡ »ý¼ºÇÏ´Â ¹®¼­¿¡ ³ª¿Ã ¼­¹ö¿¡ ´ëÇÑ Á¤º¸¸¦ + ¼³Á¤ÇÑ´Ù. ServerTokens + Áö½Ã¾î´Â ¼­¹ö HTTP ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    ¼­¹ö´Â ServerName°ú + UseCanonicalName + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀÚ±âÂüÁ¶ URLÀ» ¸¸µç´Ù. ¿¹¸¦ µé¾î, + Ŭ¶óÀ̾ðÆ®°¡ µð·ºÅ丮¸¦ ¿äûÇßÁö¸¸ µð·ºÅ丮¸í µÚ¿¡ ½½·¡½¬¸¦ + ºÙÀÌÁö¾ÊÀº °æ¿ì ¾ÆÆÄÄ¡´Â µÚ¿¡ ½½·¡½¬¸¦ ºÙÀÎ Àüü À̸§À» + Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·ºÆ®ÇÏ¿©, Ŭ¶óÀ̾ðÆ®°¡ ¹®¼­ÀÇ »ó´ëÂüÁ¶¸¦ + ¿Ã¹Ù·Î ã°Ô ÇÑ´Ù.

    +
    top
    +
    +

    ÆÄÀÏ À§Ä¡

    + + + + +

    ÀÌ Áö½Ã¾îµéÀº ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ + ¿©·¯ ÆÄÀϵéÀÇ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù. °æ·Î¸íÀÌ ½½·¡½¬(/)·Î ½ÃÀÛÇÏÁö + ¾ÊÀ¸¸é, ServerRoot¿¡ + »ó´ëÀûÀÎ ÆÄÀÏÀ» ã´Â´Ù. root°¡ ¾Æ´Ñ »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀÌ + ÀÖ´Â °æ·Î¿¡ ÆÄÀÏÀ» µÎÁö¾Êµµ·Ï Á¶½ÉÇضó. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â + º¸¾È ÆÁ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    top
    +
    +

    ÀÚ¿ø»ç¿ë Á¦ÇÑ

    + + + + +

    LimitRequest* Áö½Ã¾î´Â ¾ÆÆÄÄ¡°¡ + Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ÀÐÀ» ¶§ »ç¿ëÇÒ ÀÚ¿ø·®À» Á¦ÇÑÇÑ´Ù. ÀÌ·± + °ªµéÀ» Á¦ÇÑÇÏ¿© ¼­ºñ½º°ÅºÎ(denial of service)·ù °ø°ÝÀ» + ÁÙÀÏ ¼ö ÀÖ´Ù.

    + +

    RLimit* Áö½Ã¾î´Â ¾ÆÆÄÄ¡ ÀÚ½ÄÀÌ + »ý¼ºÇÏ´Â ÇÁ·Î¼¼½º°¡ »ç¿ëÇÒ ÀÚ¿ø·®À» Á¦ÇÑÇÑ´Ù. ƯÈ÷ CGI + ½ºÅ©¸³Æ®³ª SSI exec ¸í·É¾î°¡ »ç¿ëÇÒ ÀÚ¿øÀ» Á¦ÇÑÇÑ´Ù.

    + +

    ThreadStackSize + Áö½Ã¾î´Â ½ºÅà ũ±â¸¦ Á¶ÀýÇϱâÀ§ÇØ Netware¿¡¼­¸¸ »ç¿ëÇÑ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/server-wide.xml b/trunk/docs/manual/server-wide.xml new file mode 100644 index 0000000000..57c31f48a5 --- /dev/null +++ b/trunk/docs/manual/server-wide.xml @@ -0,0 +1,118 @@ + + + + + + + + + + Server-Wide Configuration + + +

    This document explains some of the directives provided by +the core server which are used to configure +the basic operations of the server.

    +
    + +
    + Server Identification + + + + ServerName + ServerAdmin + ServerSignature + ServerTokens + UseCanonicalName + + + +

    The ServerAdmin and + ServerTokens directives + control what information about the server will be presented + in server-generated documents such as error messages. The + ServerTokens directive + sets the value of the Server HTTP response header field.

    + +

    The ServerName and + UseCanonicalName + directives are used by the server to determine how to construct + self-referential URLs. For example, when a client requests a + directory, but does not include the trailing slash in the + directory name, Apache must redirect the client to the full + name including the trailing slash so that the client will + correctly resolve relative references in the document.

    +
    + +
    + File Locations + + + + CoreDumpDirectory + DocumentRoot + ErrorLog + LockFile + PidFile + ScoreBoardFile + ServerRoot + + + +

    These directives control the locations of the various files + that Apache needs for proper operation. When the pathname used + does not begin with a slash (/), the files are located relative + to the ServerRoot. Be careful + about locating files in paths which are writable by non-root users. + See the security tips + documentation for more details.

    +
    + +
    + Limiting Resource Usage + + + + LimitRequestBody + LimitRequestFields + LimitRequestFieldsize + LimitRequestLine + RLimitCPU + RLimitMEM + RLimitNPROC + ThreadStackSize + + + +

    The LimitRequest* + directives are used to place limits on the amount of resources + Apache will use in reading requests from clients. By limiting + these values, some kinds of denial of service attacks can be + mitigated.

    + +

    The RLimit* directives + are used to limit the amount of resources which can be used by + processes forked off from the Apache children. In particular, + this will control resources used by CGI scripts and SSI exec + commands.

    + +

    The ThreadStackSize + directive is used with some platforms to control the stack size.

    +
    +
    diff --git a/trunk/docs/manual/server-wide.xml.ja b/trunk/docs/manual/server-wide.xml.ja new file mode 100644 index 0000000000..9b2b7ca274 --- /dev/null +++ b/trunk/docs/manual/server-wide.xml.ja @@ -0,0 +1,118 @@ + + + + + + + + + + $B%5!<%PA4BN$N@_Dj(B + + +

    $B$3$N%I%-%e%a%s%H$G$O(Bcore +$B%5!<%P$N%G%#%l%/%F%#%V$NCf$G!"(B +$B4pK\F0:n$r@_Dj$9$k$?$a$N$b$N$r@bL@$7$^$9!#(B

    +
    + +
    + $B%5!<%P(B ID + + + + ServerName + ServerAdmin + ServerSignature + ServerTokens + UseCanonicalName + + + +

    ServerAdmin $B%G%#%l%/%F%#%V$H(B + ServerTokens + $B%G%#%l%/%F%#%V$O!"%(%i!<%a%C%;!<%8$J$I$N%5!<%P$,:n$k%I%-%e%a%s%H$K!"(B + $B$I$N$h$&$J%5!<%P$N>pJs$rI=<($9$k$+$r@)8f$7$^$9!#(B + ServerTokens $B%G%#%l%/%F%#%V$O!"(BServer HTTP + $B%l%9%]%s%9%X%C%@%U%#!<%k%I$NCM$r@_Dj$7$^$9!#(B

    + +

    ServerName $B%G%#%l%/%F%#%V$H(B + UseCanonicalName + $B%G%#%l%/%F%#%V$O!"%5!<%P$,<+J,<+?H$r;2>H$9$k(B URL + $B$r:n$k$H$-$K;H$o$l$^$9!#(B + $B$?$H$($P!"%/%i%$%"%s%H$,%G%#%l%/%H%j$rMW5a$7$F!"(B + $B$=$N%G%#%l%/%H%jL>$N:G8e$K%9%i%C%7%e$,IU$$$F$$$J$$$h$&$J>l9g$K$O!"(B + $B%I%-%e%a%s%H$NAjBPE*$J;2>H$r@5$7$/2r7h$G$-$k$h$&$K$9$k$?$a$K!"(B + Apache $B$O:G8e$N%9%i%C%7%e$r4^$s$@40A4$J%Q%9$K%/%i%$%"%s%H$r(B + $B%j%@%$%l%/%H$5$;$kI,MW$,$"$j$^$9!#(B

    +
    + +
    + $B%U%!%$%k$N0LCV(B + + + + CoreDumpDirectory + DocumentRoot + ErrorLog + LockFile + PidFile + ScoreBoardFile + ServerRoot + + + +

    $B$3$l$i$N%G%#%l%/%F%#%V$O(B Apache + $B$,E,@Z$JF0:n$r$9$k$?$a$KI,MW$J3FServerRoot $B$+$i$NAjBP%Q%9$H$7$F(B + $BC5$5$l$^$9!#(Broot + $B0J30$N%f!<%6$,=q$-9~$_2DG=$J%Q%9$K%U%!%$%k$rCV$/>l9g$OCm0U$,I,MW$G$9!#(B + $B>\:Y$O(B$B!V%;%-%e%j%F%#>pJs!W(B + $B$r;2>H$7$F$/$@$5$$!#(B

    +
    + +
    + $B%j%=!<%9$N@)8B(B + + + + LimitRequestBody + LimitRequestFields + LimitRequestFieldsize + LimitRequestLine + RLimitCPU + RLimitMEM + RLimitNPROC + ThreadStackSize + + + +

    LimitRequest* $B%G%#%l%/%F%#%V$O(B Apache + $B$,%/%i%$%"%s%H$+$i$N%j%/%(%9%HFI$_9~$_$G;H$&(B + $B%j%=!<%9$r@)8B$9$k$?$a$K;H$o$l$^$9!#$3$l$i$NCM$r@)8B$9$k$3$H$G!"(B + $B$$$/$D$+$N%5!<%S%95qH]967b$O1F6A$rOB$i$2$k$3$H$,$G$-$^$9!#(B

    + +

    RLimit* $B%G%#%l%/%F%#%V$O!"(BApache $B$N;R%W%m%;%9$+$i(B + fork $B$5$l$?%W%m%;%9$,;HMQ$9$k%j%=!<%9$r@)8B$9$k$?$a$K;H$o$l$^$9!#(B + $BFC$K!"$3$l$O(B CGI $B%9%/%j%W%H$H(B SSI exec + $B%3%^%s%I$G;H$o$l$k%j%=!<%9$r@)8f$7$^$9!#(B

    + +

    ThreadStackSize $B$O(B Netware + $B$G$N$_!"%9%?%C%/$NBg$-$5$r@)8f$9$k$?$a$K;H$o$l$^$9!#(B

    +
    +
    diff --git a/trunk/docs/manual/server-wide.xml.ko b/trunk/docs/manual/server-wide.xml.ko new file mode 100644 index 0000000000..a8f6b97597 --- /dev/null +++ b/trunk/docs/manual/server-wide.xml.ko @@ -0,0 +1,112 @@ + + + + + + + + + + ¼­¹ö Àü¿ª ¼³Á¤ + + +

    ÀÌ ¹®¼­´Â core ¼­¹ö°¡ ¼­¹öÀÇ ±âº» ÇൿÀ» +¼³Á¤ÇϱâÀ§ÇØ Á¦°øÇÏ´Â Áö½Ã¾îÁß ÀϺθ¦ ¼³¸íÇÑ´Ù.

    +
    + +
    + ¼­¹ö ½Äº° + + + + ServerName + ServerAdmin + ServerSignature + ServerTokens + UseCanonicalName + + + +

    ServerAdmin°ú + ServerTokens Áö½Ã¾î´Â + ¿À·ù¹® µî ¼­¹ö°¡ »ý¼ºÇÏ´Â ¹®¼­¿¡ ³ª¿Ã ¼­¹ö¿¡ ´ëÇÑ Á¤º¸¸¦ + ¼³Á¤ÇÑ´Ù. ServerTokens + Áö½Ã¾î´Â ¼­¹ö HTTP ÀÀ´ä Çì´õ¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    ¼­¹ö´Â ServerName°ú + UseCanonicalName + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÀÚ±âÂüÁ¶ URLÀ» ¸¸µç´Ù. ¿¹¸¦ µé¾î, + Ŭ¶óÀ̾ðÆ®°¡ µð·ºÅ丮¸¦ ¿äûÇßÁö¸¸ µð·ºÅ丮¸í µÚ¿¡ ½½·¡½¬¸¦ + ºÙÀÌÁö¾ÊÀº °æ¿ì ¾ÆÆÄÄ¡´Â µÚ¿¡ ½½·¡½¬¸¦ ºÙÀÎ Àüü À̸§À» + Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸®´ÙÀÌ·ºÆ®ÇÏ¿©, Ŭ¶óÀ̾ðÆ®°¡ ¹®¼­ÀÇ »ó´ëÂüÁ¶¸¦ + ¿Ã¹Ù·Î ã°Ô ÇÑ´Ù.

    +
    + +
    + ÆÄÀÏ À§Ä¡ + + + + CoreDumpDirectory + DocumentRoot + ErrorLog + LockFile + PidFile + ScoreBoardFile + ServerRoot + + + +

    ÀÌ Áö½Ã¾îµéÀº ¾ÆÆÄÄ¡°¡ Á¤»óÀûÀ¸·Î µ¿ÀÛÇϱâÀ§ÇØ ÇÊ¿äÇÑ + ¿©·¯ ÆÄÀϵéÀÇ À§Ä¡¸¦ ¼³Á¤ÇÑ´Ù. °æ·Î¸íÀÌ ½½·¡½¬(/)·Î ½ÃÀÛÇÏÁö + ¾ÊÀ¸¸é, ServerRoot¿¡ + »ó´ëÀûÀÎ ÆÄÀÏÀ» ã´Â´Ù. root°¡ ¾Æ´Ñ »ç¿ëÀÚ¿¡°Ô ¾²±â±ÇÇÑÀÌ + ÀÖ´Â °æ·Î¿¡ ÆÄÀÏÀ» µÎÁö¾Êµµ·Ï Á¶½ÉÇضó. ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â + º¸¾È ÆÁ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + +
    + ÀÚ¿ø»ç¿ë Á¦ÇÑ + + + + LimitRequestBody + LimitRequestFields + LimitRequestFieldsize + LimitRequestLine + RLimitCPU + RLimitMEM + RLimitNPROC + ThreadStackSize + + + +

    LimitRequest* Áö½Ã¾î´Â ¾ÆÆÄÄ¡°¡ + Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» ÀÐÀ» ¶§ »ç¿ëÇÒ ÀÚ¿ø·®À» Á¦ÇÑÇÑ´Ù. ÀÌ·± + °ªµéÀ» Á¦ÇÑÇÏ¿© ¼­ºñ½º°ÅºÎ(denial of service)·ù °ø°ÝÀ» + ÁÙÀÏ ¼ö ÀÖ´Ù.

    + +

    RLimit* Áö½Ã¾î´Â ¾ÆÆÄÄ¡ ÀÚ½ÄÀÌ + »ý¼ºÇÏ´Â ÇÁ·Î¼¼½º°¡ »ç¿ëÇÒ ÀÚ¿ø·®À» Á¦ÇÑÇÑ´Ù. ƯÈ÷ CGI + ½ºÅ©¸³Æ®³ª SSI exec ¸í·É¾î°¡ »ç¿ëÇÒ ÀÚ¿øÀ» Á¦ÇÑÇÑ´Ù.

    + +

    ThreadStackSize + Áö½Ã¾î´Â ½ºÅà ũ±â¸¦ Á¶ÀýÇϱâÀ§ÇØ Netware¿¡¼­¸¸ »ç¿ëÇÑ´Ù.

    +
    +
    diff --git a/trunk/docs/manual/server-wide.xml.meta b/trunk/docs/manual/server-wide.xml.meta new file mode 100644 index 0000000000..2c1fe78d4a --- /dev/null +++ b/trunk/docs/manual/server-wide.xml.meta @@ -0,0 +1,13 @@ + + + + server-wide + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/sitemap.html b/trunk/docs/manual/sitemap.html new file mode 100644 index 0000000000..84947e10e6 --- /dev/null +++ b/trunk/docs/manual/sitemap.html @@ -0,0 +1,19 @@ +URI: sitemap.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: sitemap.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: sitemap.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: sitemap.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: sitemap.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/sitemap.html.de b/trunk/docs/manual/sitemap.html.de new file mode 100644 index 0000000000..118c395551 --- /dev/null +++ b/trunk/docs/manual/sitemap.html.de @@ -0,0 +1,264 @@ + + + +Seitenindex - Apache HTTP Server + + + + + + +
    <-
    + +

    Seitenindex

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Diese Seite verzeichnet die zur Zeit verfügbaren Dokumente der +Dokumentation zum Apache HTTP Server Version 2.1.

    +
    + +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +

    Apache-Module

    + +
    top
    +
    top
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sitemap.html.en b/trunk/docs/manual/sitemap.html.en new file mode 100644 index 0000000000..ba005bd1a5 --- /dev/null +++ b/trunk/docs/manual/sitemap.html.en @@ -0,0 +1,262 @@ + + + +Sitemap - Apache HTTP Server + + + + + + +
    <-
    + +

    Sitemap

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    This page lists the currently available documents of the +Apache HTTP Server Version 2.1 Documentation.

    +
    + +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +

    Apache modules

    + +
    top
    +
    top
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sitemap.html.es b/trunk/docs/manual/sitemap.html.es new file mode 100644 index 0000000000..14683f4d9b --- /dev/null +++ b/trunk/docs/manual/sitemap.html.es @@ -0,0 +1,271 @@ + + + +Mapa de este sitio web - Servidor HTTP Apache + + + + + + +
    <-
    + +

    Mapa de este sitio web

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Esta página contiene la lista con los documentos actualmente +disponibles de la Versión 2.1 de la Documentación del +Servidor HTTP Apache.

    +
    + +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +

    Módulos de Apache

    + +
    top
    +
    top
    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sitemap.html.ja.euc-jp b/trunk/docs/manual/sitemap.html.ja.euc-jp new file mode 100644 index 0000000000..caa8adb11d --- /dev/null +++ b/trunk/docs/manual/sitemap.html.ja.euc-jp @@ -0,0 +1,263 @@ + + + +Site Map - Apache HTTP ¥µ¡¼¥Ð + + + + + + +
    <-
    + +

    Site Map

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    ¤³¤Î¥Ú¡¼¥¸¤Ï¸½»þÅÀ¤ÇÍøÍѲÄǽ¤Ê +Apache HTTP ¥µ¡¼¥Ð¥Ð¡¼¥¸¥ç¥ó 2.1 ¤Î¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó +¤Î°ìÍ÷¤Ç¤¹¡£

    +
    + +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +

    Apache ¥â¥¸¥å¡¼¥ë

    + +
    top
    +
    top
    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sitemap.html.ko.euc-kr b/trunk/docs/manual/sitemap.html.ko.euc-kr new file mode 100644 index 0000000000..9e875cdd39 --- /dev/null +++ b/trunk/docs/manual/sitemap.html.ko.euc-kr @@ -0,0 +1,269 @@ + + + +»çÀÌÆ®¸Ê - Apache HTTP Server + + + + + + +
    <-
    + +

    »çÀÌÆ®¸Ê

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ÆäÀÌÁö´Â ÇöÀç +Apache HTTP Server Version 2.1 ¹®¼­ ¸ñ·ÏÀ» +º¸¿©ÁØ´Ù.

    +
    + +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +
    top
    +

    ¾ÆÆÄÄ¡ ¸ðµâ

    + +
    top
    +
    top
    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/sitemap.xml b/trunk/docs/manual/sitemap.xml new file mode 100644 index 0000000000..b8ff875abe --- /dev/null +++ b/trunk/docs/manual/sitemap.xml @@ -0,0 +1,165 @@ + + + + + + + + + + Sitemap + + +

    This page lists the currently available documents of the +Apache HTTP Server Version 2.1 Documentation.

    +
    + + +Release Notes +Upgrading to 2.0 from 1.3 +New features with Apache 2.0 +Apache License + + + +Using the Apache HTTP Server +Compiling and Installing Apache +Starting Apache +Stopping and Restarting the Server +Configuration Files +How Directory, Location and Files sections work +Server-Wide Configuration +Log Files +Mapping URLs to Filesystem Locations +Security Tips +Dynamic Shared Object (DSO) support +Content Negotiation +Custom error responses +Setting which addresses and ports Apache uses +Multi-Processing Modules (MPMs) +Environment Variables in Apache +Apache's Handler Use +Filters +suEXEC Support +Performance Hints +URL Rewriting Guide + + + +Apache Virtual Host documentation +Overview +Name-based Virtual Hosts +IP-based Virtual Host Support +Dynamically configured mass virtual hosting +VirtualHost Examples +An In-Depth Discussion of Virtual Host Matching +File descriptor limitations +Issues Regarding DNS and Apache + + + +Apache Server Frequently Asked Questions +Overview +Support +Error Messages + + + +Apache SSL/TLS Encryption +Overview +SSL/TLS Encryption: An Introduction +SSL/TLS Encryption: Compatibility +SSL/TLS Encryption: How-To +SSL/TLS Encryption: FAQ + + + +Guides, Tutorials, and HowTos +Overview +Authentication +Dynamic Content with CGI +Introduction to Server Side Includes +.htaccess files +Per-user web directories + + + +Platform-specific Notes +Overview +Using Apache with Microsoft +Windows +Compiling Apache for +Microsoft Windows +Using Apache with Novell NetWare +Running a High-Performance Web +Server on HPUX +The Apache EBCDIC Port + + + +Apache HTTP Server and Supporting Programs +Overview +Manual Page: httpd +Manual Page: ab +Manual Page: apachectl +Manual Page: apxs +Manual Page: configure +Manual Page: dbmmanage +Manual Page: htcacheclean +Manual Page: htdbm +Manual Page: htdigest +Manual Page: htpasswd +Manual Page: logresolve +Manual Page: rotatelogs +Manual Page: suexec +Other Programs + + + +Apache Miscellaneous Documentation +Overview +Relevant Standards + + + +Apache modules +Definitions of terms used to describe Apache modules +Definitions of terms used to describe Apache directives + + + +Developer Documentation +Overview +Apache API notes +Debugging Memory Allocation in APR +Documenting Apache 2.0 +Apache 2.0 Hook Functions +Converting Modules from Apache 1.3 to Apache 2.0 +Request Processing in Apache 2.0 +How Filters Work in Apache 2.0 + + + +Glossary and Index +Glossary +Module index +Directive index +Directive Quick-Reference + + +
    diff --git a/trunk/docs/manual/sitemap.xml.de b/trunk/docs/manual/sitemap.xml.de new file mode 100644 index 0000000000..4d1b8882dd --- /dev/null +++ b/trunk/docs/manual/sitemap.xml.de @@ -0,0 +1,167 @@ + + + + + + + + + + Seitenindex + + +

    Diese Seite verzeichnet die zur Zeit verfügbaren Dokumente der +Dokumentation zum Apache HTTP Server Version 2.1.

    +
    + + +Hinweise zur Version +Upgrade von 1.3 auf 2.0 +Neue Funktionen in Version 2.0 +Apache-Lizenz + + + +Bedienung des Apache HTTP Servers +Kompilieren und Installieren +Apache starten +Beenden und Neustarten des Servers +Konfigurationsdateien +Konfigurationsabschnitte +Serverweite Konfiguration +Log-Dateien +URLs auf das Dateisystem abbilden +Tipps zur Sicherheit +Dynamic Shared Object (DSO) +Content Negotiation +Individuelle Fehlermeldungen +Bestimmen der vom Apache verwendeten Adressen und Ports +Multi-Processing-Module (MPMs) +Umgebungsvariablen +Handler +Filter +suEXEC Unterstützung +Performance-Hinweise +Einführung in die URL-Manipulation + + + +Apache-Dokumentation zu virtuellen Hosts +Übersicht +Namensbasierte virtuelle Hosts +IP-basierte virtuelle Hosts +Dynamisch konfiguriertes Massen-Virtual-Hosting +Beispiele für virtuelle Hosts in + typischen Installationen +Tiefergehende Erörterung der Zuweisung + virtueller Hosts +Datei-Deskriptor-Begrenzungen +Probleme bezüglich DNS und Apache + + + + +Häufig gestellte Fragen (FAQ) +Übersicht +Support +Fehlermeldungen + + + +SSL/TLS-Verschlüsselung des Apache +Übersicht +SSL/TLS-Verschlüsselung: Einführung +SSL/TLS-Verschlüsselung: Kompatibilität +SSL/TLS-Verschlüsselung: Praxis +SSL/TLS-Verschlüsselung: FAQ + + + +Praxis / Anleitungen +Übersicht +Authentisierung, Autorisierung und Zugriffskontrolle +Dynamische Inhalte mit CGI +Einführung in Server Side Includes +.htaccess-Dateien +Web-Verzeichnisse für Benutzer + + + +Plattform-spezifische Anmerkungen +Übersicht +Apache unter Microsoft +Windows einsetzen +Kompilieren des Apache für +Microsoft Windows +Apache unter Novell NetWare einsetzen +Einen Hochleistungs-Web-Server auf +HPUX betreiben +Die Apache EBCDIC-Portierung + + + +Apache HTTP Server und Hilfsprogramme +Übersicht +httpd +ab +apachectl +apxs +configure +dbmmanage +htcacheclean +htdbm +htdigest +htpasswd +logresolve +rotatelogs +suexec +Sonstige Programme + + + +Weitere Apache-Dokumentationen +Übersicht +Wichtige Standards + + + +Apache-Module +Erklärung der Fachbegriffe zu Apache-Modulen +Erklärung der Fachbegriffe zu Apache-Direktiven + + + +Dokumentation für Entwickler +Übersicht +Anmerkungen zur Apache-API +Debuggen der Speicher-Belegung in der APR +Apache 2.0 dokumentieren +Hook-Funktionen des Apache 2.0 +Module von Apache 1.3 nach Apache 2.0 konvertieren +Verarbeitung der Anfragen im Apache 2.0 +Wie Filter im Apache 2.0 arbeiten + + +Glossar und Index +Glossar +Modul-Index +Direktiven-Index +Kurzreferenz der Direktiven + + +
    diff --git a/trunk/docs/manual/sitemap.xml.es b/trunk/docs/manual/sitemap.xml.es new file mode 100644 index 0000000000..dc4f27e429 --- /dev/null +++ b/trunk/docs/manual/sitemap.xml.es @@ -0,0 +1,168 @@ + + + + + + + + + + Mapa de este sitio web + + +

    Esta página contiene la lista con los documentos actualmente +disponibles de la Versión 2.1 de la Documentación del +Servidor HTTP Apache.

    +
    + + +Notas de la Versión +Pasar a usar Apache 2.0 desde Apache 1.3 +Nuevas funcionalidades de Apache 2.0 +Licencia Apache + + + +Funcionamiento del Servidor HTTP Apache +Compilación e Instalación de Apache +Iniciar Apache +Parar y reiniciar Apache +Ficheros de Configuración +Funcionamiento de las secciones Directory, Location y Files +Configuración Básica de Apache +Archivos Log +Mapear URLs a ubicaciones de un sistema de ficheros +Consejos de Seguridad +Soporte de Objetos Dinámicos Compartidos (DSO) +Negociación de Contenido +Mensajes de Error Personalizados +Fijar las direcciones y los puertos que usa Apache +Módulos de Multiproceso (MPMs) +Variables de entorno en Apache +El uso de Handlers en Apache +Filtros +Soporte de suEXEC +Rendimiento del servidor +Documentación adicional sobre mod_rewrite + + + +Documuentación sobre Hosting Virtual en Apache +Visión General +Hosting Virtual basado en nombres +Soporte de Hosting Virtual Basado en IPs +Configurar de forma Dinámica el Hosting Virtual masivo en Apache +Ejemplos de Hosting Virtual +Discusión en profundidad sobre los tipos de Hosting Virtual +Limitaciones de los descriptores de ficheros +Asuntos relacionados con DNS y Apache + + + +Preguntas Más Frecuentes sobre Apache +Visión General +Soporte +Mensajes de error + + + +Encriptado SSL/TLS con Apache +Visión General +Encriptado SSL/TLS: Introducción +Encriptado SSL/TLS: Compatibilidad +Encriptado SSL/TLS: How-To +Encriptado SSL/TLS: Preguntas Frecuentes + + + +Guías, Tutoriales, y HowTos +Visión General +Autentificación +Contenido Dinámico con CGIs +Introducción a Server Side Includes +Archivos .htaccess +Directorios web para cada usuario + + + +Notas específicas sobre plataformas Visión General Usar Apache con Microsoft Windows +Compilar Apache para +Microsoft Windows Usar +Apache con Novell NetWare Servidor Web de alto rendimiento con +HPUX La versión EBCDIC de +Apache + + + +Programas de soporte y el Servidor HTTP Apache +Visión General +Página de Ayuda: httpd +Página de Ayuda: ab +Página de Ayuda: apachectl +Página de Ayuda: apxs +Página de Ayuda: configure +Página de Ayuda: dbmmanage +Página de Ayuda: htcacheclean +Página de Ayuda: htdigest +Página de Ayuda: htpasswd +Página de Ayuda: logresolve +Página de Ayuda: rotatelogs +Página de Ayuda: suexec +Otros Programas + + + +Documentación adicional sobre Apache +Visión General +Estándares Importantes + + + +Módulos de Apache +Definiciones de términos usados +para describir los módulos de Apache +Definiciones de términos +usados para describir las directivas de Apache + + + +Documentación para desarrolladores +Visión General +Notas sobre la API de Apache +Debugging la Reserva de Memoria en APR +Documentando Apache 2.0 +Funciones Hook de Apache 2.0 +Convertir Módulos de Apache 1.3 a Apache 2.0 +Procesamiento de Peticiones en Apache 2.0 +Funcionamiento de los filtros en Apache 2.0 + + + +Glosario e Índice +Glosario +Índice de Módulos +Índice de Directivas +Guía Rápida de +Referencia de Directivas + + +
    + diff --git a/trunk/docs/manual/sitemap.xml.ja b/trunk/docs/manual/sitemap.xml.ja new file mode 100644 index 0000000000..711eb52933 --- /dev/null +++ b/trunk/docs/manual/sitemap.xml.ja @@ -0,0 +1,166 @@ + + + + + + + + + + Site Map + + +

    $B$3$N%Z!<%8$O8=;~E@$GMxMQ2DG=$J(B +Apache HTTP $B%5!<%P%P!<%8%g%s(B 2.1 $B$N%I%-%e%a%s%F!<%7%g%s(B +$B$N0lMw$G$9!#(B

    +
    + + +$B%j%j!<%9$N%a%b(B +1.3 $B$+$i(B 2.0 $B$X$N%"%C%W%0%l!<%I(B +Apache 2.0 $B$N?75!G=(B +Apache License + + + +Apache HTTP $B%5!<%P$N;HMQ(B +Apache $B$N%3%s%Q%$%k$H%$%s%9%H!<%k(B +Apache $B$N5/F0(B +$B%5!<%P$NDd;_$H:F5/F0(B +$B@_Dj%U%!%$%k(B +Directory, Location, Files $B%;%/%7%g%s$NF0:nJ}K!(B +$B%5!<%PA4BN$N@_Dj(B +$B%m%0%U%!%$%k(B +URL $B$+$i%U%!%$%k%7%9%F%`>e$N0LCV$X$N%^%C%W(B +$B%;%-%e%j%F%#$N%3%D(B +$BF0E*6&M-%*%V%8%'%/%H(B (DSO) $B%5%]!<%H(B +$B%3%s%F%s%H%M%4%7%(!<%7%g%s(B +$B%+%9%?%`%(%i!<%l%9%]%s%9(B +Apache $B$,;HMQ$9$k%"%I%l%9$H%]!<%H$N@_Dj(B +$B%^%k%A%W%m%;%C%7%s%0%b%8%e!<%k(B (MPM) +Apache $B$K$*$1$k4D6-JQ?t(B +Apache $B$N%O%s%I%i$N;HMQ(B +$B%U%#%k%?(B +suEXEC $B%5%]!<%H(B +$B@-G=$K4X$9$k%R%s%H(B +URL $B%j%i%$%H%,%$%I(B + + + +Apache $B%P!<%A%c%k%[%9%H%I%-%e%a%s%H(B +$B35N,(B +$BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H(B +IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$N%5%]!<%H(B +$BF0E*$K@_Dj$5$l$?Bg5,LO%P!<%A%c%k%[%9%H(B +VirtualHost $B$NNc(B +$B%P!<%A%c%k%[%9%H$N%^%C%A%s%0$N>\$7$$@bL@(B +$B%U%!%$%k5-=R;R$N8B3&(B +DNS $B$H(B Apache $B$H$K4X78$9$kLdBj(B + + + +Apache $B%5!<%P$N$h$/$"$k<ALd(B +$B35N,(B +$B%5%]!<%H(B +$B%(%i!<%a%C%;!<%8(B + + + +Apache $B$N(B SSL/TLS $B0E9f2=(B +$B35N,(B +SSL/TLS $B0E9f2=(B: $BF~Lg(B +SSL/TLS $B0E9f2=(B: $B8_49@-(B +SSL/TLS $B0E9f2=(B: $B%O%&%D!<(B +SSL/TLS $B0E9f2=(B: FAQ + + + +$B%,%$%I!"%A%e!<%H%j%"%k!"%O%&%D!<(B +$B35N,(B +$BG'>Z(B +CGI $B$K$h$kF0E*%3%s%F%s%D(B +Server Side Includes $BF~Lg(B +.htaccess $B%U%!%$%k(B +$B%f!<%6Kh$N%&%'%V%G%#%l%/%H%j(B + + + +$B%W%i%C%H%U%)!<%`8GM-$N>pJs(B +$B35N,(B +Microsoft Windows $B$G$N(B Apache $B$N;HMQ(B +Microsoft Windows $B$G$N(B Apache +$B$N%3%s%Q%$%k(B +Novell NetWare $B$G(B Apache $B$r;H$&(B +HPUX $B$G9b@-G=%&%'%V%5!<%P$r +EBCDIC $BHG(B Apache + + + +Apache HTTP $B%5!<%P$H%5%]!<%H%W%m%0%i%`(B +$B35N,(B +$B%^%K%e%"%k%Z!<%8(B: httpd +$B%^%K%e%"%k%Z!<%8(B: ab +$B%^%K%e%"%k%Z!<%8(B: apachectl +$B%^%K%e%"%k%Z!<%8(B: apxs +$B%^%K%e%"%k%Z!<%8(B: configure +$B%^%K%e%"%k%Z!<%8(B: dbmmanage +$B%^%K%e%"%k%Z!<%8(B: htcacheclean +$B%^%K%e%"%k%Z!<%8(B: htdbm +$B%^%K%e%"%k%Z!<%8(B: htdigest +$B%^%K%e%"%k%Z!<%8(B: htpasswd +$B%^%K%e%"%k%Z!<%8(B: logresolve +$B%^%K%e%"%k%Z!<%8(B: rotatelogs +$B%^%K%e%"%k%Z!<%8(B: suexec +$BB>$N%W%m%0%i%`(B + + + +Apache $B$=$NB>(B +$B35N,(B +$B4XO"$9$kI8=`5,3J(B + + + +Apache $B%b%8%e!<%k(B +Apache $B%G%#%l%/%F%#%V$N@bL@$K;H$o$l$kMQ8l(B +Apache $B%G%#%l%/%F%#%V$r@bL@$K;H$o$l$kMQ8l(B + + + +$B3+H/<T$N$?$a$N%I%-%e%a%s%H(B +$B35N,(B +Apache API $B%a%b(B +APR +$B$N%a%b%j%"%m%1!<%7%g%s$N%G%P%C%0(B +Apache 2.0 $B$N@bL@$r=q$/(B +Apache 2.0 $B%U%C%/4X?t(B +Apache 1.3 $B$+$i(B Apache 2.0 $B$K%b%8%e!<%k$r(B +$B0\?"$9$k(B +Apache 2.0 $B$N%j%/%(%9%H=hM}(B +Apache 2.0 $B$N%U%#%k%?$NF0:n$N;EJ}(B + + + +$BMQ8l=8$H:w0z(B +$BMQ8l=8(B +$B%b%8%e!<%k:w0z(B +$B%G%#%l%/%F%#%V:w0z(B +$B%G%#%l%/%F%#%V(B $B%/%$%C%/%j%U%!%l%s%9(B + + +
    diff --git a/trunk/docs/manual/sitemap.xml.ko b/trunk/docs/manual/sitemap.xml.ko new file mode 100644 index 0000000000..4fe2d7debc --- /dev/null +++ b/trunk/docs/manual/sitemap.xml.ko @@ -0,0 +1,170 @@ + + + + + + + + + + »çÀÌÆ®¸Ê + + +

    ÀÌ ÆäÀÌÁö´Â ÇöÀç +Apache HTTP Server Version 2.1 ¹®¼­ ¸ñ·ÏÀ» +º¸¿©ÁØ´Ù.

    +
    + + +¹ßÇ¥¹® +1.3¿¡¼­ 2.0À¸·Î ¾÷±×·¹À̵å +¾ÆÆÄÄ¡ 2.0ÀÇ »õ·Î¿î ±â´É +¾ÆÆÄÄ¡ ¶óÀ̼±½º + + + +¾ÆÆÄÄ¡ À¥¼­¹ö »ç¿ëÇϱâ +¾ÆÆÄÄ¡ ÄÄÆÄÀÏ°ú ¼³Ä¡ +¾ÆÆÄÄ¡ ½ÃÀÛ +¼­¹ö Áß´Ü°ú Àç½ÃÀÛ +¼³Á¤ÆÄÀÏ +¾î¶»°Ô Directory, Location, Files ¼½¼ÇÀÌ +µ¿ÀÛÇϳª +¼­¹ö Àü¿ª ¼³Á¤ +·Î±×ÆÄÀÏ +URLÀ» ÆÄÀϽýºÅÛ¿¡ ´ëÀÀ +º¸¾È ÆÁ +µ¿Àû°øÀ¯°´Ã¼ (DSO) Áö¿ø +³»¿ëÇù»ó (content negotiation) +»ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä +¾ÆÆÄÄ¡°¡ »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ® ÁöÁ¤ +´ÙÁß󸮸ðµâ (MPM) +¾ÆÆÄÄ¡ÀÇ È¯°æº¯¼ö +¾ÆÆÄÄ¡¿¡¼­ Çڵ鷯 »ç¿ë +ÇÊÅÍ +suEXEC Áö¿ø +¼º´ÉÇâ»ó ÈùÆ® +URL ÀçÀÛ¼º(rewriting) Áöħ¼­ + + + +¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­ +°³¿ä +À̸§±â¹Ý °¡»óÈ£½ºÆ® +IP±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø +´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ µ¿ÀûÀ¸·Î ¼³Á¤Çϱâ +°¡»óÈ£½ºÆ® ¿¹ +°¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í +ÆÄÀϱâ¼úÀÚ(file descriptor) ÇÑ°è +DNS¿Í ¾ÆÆÄÄ¡¿Í °ü·ÃµÈ »çÇ× + + + +¾ÆÆÄÄ¡ ¼­¹ö¿¡ ´ëÇØ ÀÚÁÖ ¹°¾îº¸´Â Áú¹® +°³¿ä +Áö¿ø +¿À·ù¹® + + + +¾ÆÆÄÄ¡ SSL/TLS ¾Ïȣȭ +¼Ò°³ +SSL/TLS ¾Ïȣȭ: ¼Ò°³ +SSL/TLS ¾Ïȣȭ: ȣȯ¼º +SSL/TLS ¾Ïȣȭ: How-To +SSL/TLS ¾Ïȣȭ: FAQ + + + +Áöħ¼­, ÅõÅ丮¾ó, HowTo +°³¿ä +ÀÎÁõ +CGI·Î µ¿Àû ÆäÀÌÁö »ý¼º +Server Side Includes ¼Ò°³ +.htaccess ÆÄÀÏ +»ç¿ëÀÚº° À¥µð·ºÅ丮 + + + +Ç÷¡Æûº° ¼³¸í +°³¿ä +Microsoft Windows¿¡¼­ ¾ÆÆÄÄ¡ +»ç¿ëÇϱâ +Microsoft Windows¿¡¼­ +¾ÆÆÄÄ¡ ÄÄÆÄÀÏÇϱâ +Novell NetWare¿¡¼­ ¾ÆÆÄÄ¡ +»ç¿ëÇϱâ +HPUX¿¡¼­ °í¼º´É À¥¼­¹ö +½ÇÇàÇϱâ +¾ÆÆÄÄ¡ EBCDIC Æ÷Æà + + + +¾ÆÆÄÄ¡ À¥¼­¹ö¿Í Áö¿ø ÇÁ·Î±×·¥ +°³¿ä +Manpage: httpd +Manpage: ab +Manpage: apachectl +Manpage: apxs +Manpage: configure +Manpage: dbmmanage +Manpage: htcacheclean +Manpage: htdigest +Manpage: htpasswd +Manpage: logresolve +Manpage: rotatelogs +Manpage: suexec +´Ù¸¥ ÇÁ·Î±×·¥µé + + + +±âŸ ¾ÆÆÄÄ¡ ¹®¼­ +°³¿ä +°ü·ÃµÈ Ç¥Áصé + + + +¾ÆÆÄÄ¡ ¸ðµâ +¾ÆÆÄÄ¡ ¸ðµâÀ» ¼³¸íÇϴµ¥ »ç¿ëÇÑ +¿ë¾îÁ¤ÀÇ +¾ÆÆÄÄ¡ Áö½Ã¾î¸¦ ¼³¸íÇϴµ¥ +»ç¿ëÇÑ ¿ë¾îÁ¤ÀÇ + + + +°³¹ßÀÚ ¹®¼­ +°³¿ä +Apache API ¼³¸í +APRÀÇ ¸Þ¸ð¸®ÇÒ´ç µð¹ö±ë +Apache 2.0 ¹®¼­È­ +Apache 2.0 ÈÅ(hook) ÇÔ¼ö +Apache 1.3¿¡¼­ Apache 2.0À¸·Î +¸ðµâÀ» ¼öÁ¤Çϱâ +Apache 2.0ÀÇ ¿äûó¸® +Apache 2.0ÀÇ ÇÊÅÍ µ¿ÀÛ¹ý + + + +¿ë¾î¿Í »öÀÎ +¿ë¾î +¸ðµâ ¸ñ·Ï +Áö½Ã¾î ¸ñ·Ï +Áö½Ã¾î ºü¸¥ÂüÁ¶ + + +
    diff --git a/trunk/docs/manual/sitemap.xml.meta b/trunk/docs/manual/sitemap.xml.meta new file mode 100644 index 0000000000..470f98c179 --- /dev/null +++ b/trunk/docs/manual/sitemap.xml.meta @@ -0,0 +1,15 @@ + + + + sitemap + / + . + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/ssl/index.html b/trunk/docs/manual/ssl/index.html new file mode 100644 index 0000000000..39629cac71 --- /dev/null +++ b/trunk/docs/manual/ssl/index.html @@ -0,0 +1,7 @@ +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/ssl/index.html.en b/trunk/docs/manual/ssl/index.html.en new file mode 100644 index 0000000000..649c2707c1 --- /dev/null +++ b/trunk/docs/manual/ssl/index.html.en @@ -0,0 +1,57 @@ + + + +Apache SSL/TLS Encryption - Apache HTTP Server + + + + + +
    <-
    +

    Apache SSL/TLS Encryption

    +
    +

    Available Languages:  en  | + ja 

    +
    + +

    The Apache HTTP Server module mod_ssl +provides an interface to the OpenSSL library, which provides +Strong Encryption using the Secure Sockets Layer and Transport Layer +Security protocols. The module and this documentation are based on +Ralf S. Engelschall's mod_ssl project.

    +
    + +
    top
    +
    top
    +
    +

    mod_ssl

    +

    Extensive documentation on the directives and environment variables +provided by this module is provided in the mod_ssl reference documentation. +

    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/index.html.ja.euc-jp b/trunk/docs/manual/ssl/index.html.ja.euc-jp new file mode 100644 index 0000000000..acef128dd9 --- /dev/null +++ b/trunk/docs/manual/ssl/index.html.ja.euc-jp @@ -0,0 +1,59 @@ + + + +Apache ¤Î SSL/TLS °Å¹æ²½ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¤Î SSL/TLS °Å¹æ²½

    +
    +

    Available Languages:  en  | + ja 

    +
    + +

    Apache HTTP ¥µ¡¼¥Ð¥â¥¸¥å¡¼¥ë mod_ssl ¤¬ +OpenSSL +¥é¥¤¥Ö¥é¥ê¤Ø¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÄ󶡤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤Ï +Secure Sockts Layer ¤È Transport Layer Security +¥×¥í¥È¥³¥ë¤òÍѤ¤¤¿¶¯ÎϤʰŹ沽¤òÄ󶡤·¤Þ¤¹¡£ +¤³¤Î¥â¥¸¥å¡¼¥ë¤ä¤³¤Îʸ½ñ¤Ï Ralf S. Engelschall ¤Î mod_ssl +¥×¥í¥¸¥§¥¯¥È¤Ë´ð¤Å¤¤¤Æ¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    top
    +
    +

    mod_ssl

    +

    ¤³¤Î¥â¥¸¥å¡¼¥ë¤ÇÄ󶡤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä´Ä¶­ÊÑ¿ô¤Ë´Ø¤¹¤ë +¾Ü¤·¤¤Ê¸½ñ¤Ï¡¢mod_ssl +¥ê¥Õ¥¡¥ì¥ó¥¹¤ò¤´Í÷²¼¤µ¤¤¡£

    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/index.xml b/trunk/docs/manual/ssl/index.xml new file mode 100644 index 0000000000..0d0a65af6a --- /dev/null +++ b/trunk/docs/manual/ssl/index.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + Apache SSL/TLS Encryption + + +

    The Apache HTTP Server module mod_ssl +provides an interface to the OpenSSL library, which provides +Strong Encryption using the Secure Sockets Layer and Transport Layer +Security protocols. The module and this documentation are based on +Ralf S. Engelschall's mod_ssl project.

    +
    + +
    Documentation + +
    + +
    mod_ssl +

    Extensive documentation on the directives and environment variables +provided by this module is provided in the mod_ssl reference documentation. +

    +
    + +
    + + diff --git a/trunk/docs/manual/ssl/index.xml.ja b/trunk/docs/manual/ssl/index.xml.ja new file mode 100644 index 0000000000..2cd3217876 --- /dev/null +++ b/trunk/docs/manual/ssl/index.xml.ja @@ -0,0 +1,56 @@ + + + + + + + + + + + Apache $B$N(B SSL/TLS $B0E9f2=(B + + +

    Apache HTTP $B%5!<%P%b%8%e!<%k(B mod_ssl $B$,(B +OpenSSL +$B%i%$%V%i%j$X$N%$%s%?!<%U%'!<%9$rDs6!$7$F$$$^$9$,!"$3$l$O(B +Secure Sockts Layer $B$H(B Transport Layer Security +$B%W%m%H%3%k$rMQ$$$?6/NO$J0E9f2=$rDs6!$7$^$9!#(B +$B$3$N%b%8%e!<%k$d$3$NJ8=q$O(B Ralf S. Engelschall $B$N(B mod_ssl +$B%W%m%8%'%/%H$K4p$E$$$F$$$^$9!#(B

    +
    + +
    Documentation + +
    + +
    mod_ssl +

    $B$3$N%b%8%e!<%k$GDs6!$5$l$k%G%#%l%/%F%#%V$d4D6-JQ?t$K4X$9$k(B +$B>\$7$$J8=q$O!"(Bmod_ssl +$B%j%U%!%l%s%9(B$B$r$4Mw2<$5$$!#(B

    +
    + +
    + + diff --git a/trunk/docs/manual/ssl/index.xml.meta b/trunk/docs/manual/ssl/index.xml.meta new file mode 100644 index 0000000000..0ab0329f78 --- /dev/null +++ b/trunk/docs/manual/ssl/index.xml.meta @@ -0,0 +1,12 @@ + + + + index + /ssl/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/ssl/ssl_compat.html b/trunk/docs/manual/ssl/ssl_compat.html new file mode 100644 index 0000000000..3a8ed1be8b --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_compat.html @@ -0,0 +1,3 @@ +URI: ssl_compat.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/ssl/ssl_compat.html.en b/trunk/docs/manual/ssl/ssl_compat.html.en new file mode 100644 index 0000000000..eb83cfc3f7 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_compat.html.en @@ -0,0 +1,226 @@ + + + +SSL/TLS Strong Encryption: Compatibility - Apache HTTP Server + + + + + +
    <-
    +

    SSL/TLS Strong Encryption: Compatibility

    +
    +

    Available Languages:  en 

    +
    + +
    +

    All PCs are compatible. But some of +them are more compatible than others.

    +

    -- Unknown

    +
    + +

    +This page covers backwards compatibility between mod_ssl and other +SSL solutions. mod_ssl is not the only SSL solution for Apache; four +additional products are (or were) also available: Ben Laurie's freely +available Apache-SSL (from +where mod_ssl were originally derived in 1998), Red Hat's commercial +Secure +Web Server (which was based on mod_ssl), Covalent's commercial Raven SSL Module (also based on +mod_ssl) and finally C2Net's (now Red Hat's) commercial product Stronghold (based +on a different evolution branch named Sioux up to Stronghold 2.x and +based on mod_ssl since Stronghold 3.x).

    + +

    +mod_ssl mostly provides a superset of the functionality of all the other +solutions, so it's simple to migrate from one of the older modules to +mod_ssl. The configuration directives and environment variable names +used by the older SSL solutions vary from those used in mod_ssl; +mapping tables are included here to give the equivalents used by mod_ssl.

    +
    + +
    top
    +
    +

    Configuration Directives

    +

    The mapping between configuration directives used by Apache-SSL +1.x and mod_ssl 2.0.x is given in Table +1. The mapping from Sioux 1.x and Stronghold 2.x is only partial +because of special functionality in these interfaces which mod_ssl +doesn't provide.

    + + +

    Table 1: Configuration Directive Mapping

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Old Directivemod_ssl DirectiveComment
    Apache-SSL 1.x & mod_ssl 2.0.x compatibility:
    SSLEnableSSLEngine oncompactified
    SSLDisableSSLEngine offcompactified
    SSLLogFile fileSSLLog filecompactified
    SSLRequiredCiphers specSSLCipherSuite specrenamed
    SSLRequireCipher c1 ...SSLRequire %{SSL_CIPHER} in {"c1", +...}generalized
    SSLBanCipher c1 ...SSLRequire not (%{SSL_CIPHER} in {"c1", +...})generalized
    SSLFakeBasicAuthSSLOptions +FakeBasicAuthmerged
    SSLCacheServerPath dir-functionality removed
    SSLCacheServerPort integer-functionality removed
    Apache-SSL 1.x compatibility:
    SSLExportClientCertificatesSSLOptions +ExportCertDatamerged
    SSLCacheServerRunDir dir-functionality not supported
    Sioux 1.x compatibility:
    SSL_CertFile fileSSLCertificateFile filerenamed
    SSL_KeyFile fileSSLCertificateKeyFile filerenamed
    SSL_CipherSuite argSSLCipherSuite argrenamed
    SSL_X509VerifyDir argSSLCACertificatePath argrenamed
    SSL_Log fileSSLLogFile filerenamed
    SSL_Connect flagSSLEngine flagrenamed
    SSL_ClientAuth argSSLVerifyClient argrenamed
    SSL_X509VerifyDepth argSSLVerifyDepth argrenamed
    SSL_FetchKeyPhraseFrom arg-not directly mappable; use SSLPassPhraseDialog
    SSL_SessionDir dir-not directly mappable; use SSLSessionCache
    SSL_Require expr-not directly mappable; use SSLRequire
    SSL_CertFileType arg-functionality not supported
    SSL_KeyFileType arg-functionality not supported
    SSL_X509VerifyPolicy arg-functionality not supported
    SSL_LogX509Attributes arg-functionality not supported
    Stronghold 2.x compatibility:
    StrongholdAccelerator engineSSLCryptoDevice enginerenamed
    StrongholdKey dir-functionality not needed
    StrongholdLicenseFile dir-functionality not needed
    SSLFlag flagSSLEngine flagrenamed
    SSLSessionLockFile fileSSLMutex filerenamed
    SSLCipherList specSSLCipherSuite specrenamed
    RequireSSLSSLRequireSSLrenamed
    SSLErrorFile file-functionality not supported
    SSLRoot dir-functionality not supported
    SSL_CertificateLogDir dir-functionality not supported
    AuthCertDir dir-functionality not supported
    SSL_Group name-functionality not supported
    SSLProxyMachineCertPath dirSSLProxyMachineCertificatePath dirrenamed
    SSLProxyMachineCertFile fileSSLProxyMachineCertificateFile filerenamed
    SSLProxyCipherList specSSLProxyCipherSpec specrenamed
    + +
    top
    +
    +

    Environment Variables

    + +

    The mapping between environment variable names used by the older +SSL solutions and the names used by mod_ssl is given in Table 2.

    + +

    Table 2: Environment Variable Derivation

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Old Variablemod_ssl VariableComment
    SSL_PROTOCOL_VERSIONSSL_PROTOCOLrenamed
    SSLEAY_VERSIONSSL_VERSION_LIBRARYrenamed
    HTTPS_SECRETKEYSIZESSL_CIPHER_USEKEYSIZErenamed
    HTTPS_KEYSIZESSL_CIPHER_ALGKEYSIZErenamed
    HTTPS_CIPHERSSL_CIPHERrenamed
    HTTPS_EXPORTSSL_CIPHER_EXPORTrenamed
    SSL_SERVER_KEY_SIZESSL_CIPHER_ALGKEYSIZErenamed
    SSL_SERVER_CERTIFICATESSL_SERVER_CERTrenamed
    SSL_SERVER_CERT_STARTSSL_SERVER_V_STARTrenamed
    SSL_SERVER_CERT_ENDSSL_SERVER_V_ENDrenamed
    SSL_SERVER_CERT_SERIALSSL_SERVER_M_SERIALrenamed
    SSL_SERVER_SIGNATURE_ALGORITHMSSL_SERVER_A_SIGrenamed
    SSL_SERVER_DNSSL_SERVER_S_DNrenamed
    SSL_SERVER_CNSSL_SERVER_S_DN_CNrenamed
    SSL_SERVER_EMAILSSL_SERVER_S_DN_Emailrenamed
    SSL_SERVER_OSSL_SERVER_S_DN_Orenamed
    SSL_SERVER_OUSSL_SERVER_S_DN_OUrenamed
    SSL_SERVER_CSSL_SERVER_S_DN_Crenamed
    SSL_SERVER_SPSSL_SERVER_S_DN_SPrenamed
    SSL_SERVER_LSSL_SERVER_S_DN_Lrenamed
    SSL_SERVER_IDNSSL_SERVER_I_DNrenamed
    SSL_SERVER_ICNSSL_SERVER_I_DN_CNrenamed
    SSL_SERVER_IEMAILSSL_SERVER_I_DN_Emailrenamed
    SSL_SERVER_IOSSL_SERVER_I_DN_Orenamed
    SSL_SERVER_IOUSSL_SERVER_I_DN_OUrenamed
    SSL_SERVER_ICSSL_SERVER_I_DN_Crenamed
    SSL_SERVER_ISPSSL_SERVER_I_DN_SPrenamed
    SSL_SERVER_ILSSL_SERVER_I_DN_Lrenamed
    SSL_CLIENT_CERTIFICATESSL_CLIENT_CERTrenamed
    SSL_CLIENT_CERT_STARTSSL_CLIENT_V_STARTrenamed
    SSL_CLIENT_CERT_ENDSSL_CLIENT_V_ENDrenamed
    SSL_CLIENT_CERT_SERIALSSL_CLIENT_M_SERIALrenamed
    SSL_CLIENT_SIGNATURE_ALGORITHMSSL_CLIENT_A_SIGrenamed
    SSL_CLIENT_DNSSL_CLIENT_S_DNrenamed
    SSL_CLIENT_CNSSL_CLIENT_S_DN_CNrenamed
    SSL_CLIENT_EMAILSSL_CLIENT_S_DN_Emailrenamed
    SSL_CLIENT_OSSL_CLIENT_S_DN_Orenamed
    SSL_CLIENT_OUSSL_CLIENT_S_DN_OUrenamed
    SSL_CLIENT_CSSL_CLIENT_S_DN_Crenamed
    SSL_CLIENT_SPSSL_CLIENT_S_DN_SPrenamed
    SSL_CLIENT_LSSL_CLIENT_S_DN_Lrenamed
    SSL_CLIENT_IDNSSL_CLIENT_I_DNrenamed
    SSL_CLIENT_ICNSSL_CLIENT_I_DN_CNrenamed
    SSL_CLIENT_IEMAILSSL_CLIENT_I_DN_Emailrenamed
    SSL_CLIENT_IOSSL_CLIENT_I_DN_Orenamed
    SSL_CLIENT_IOUSSL_CLIENT_I_DN_OUrenamed
    SSL_CLIENT_ICSSL_CLIENT_I_DN_Crenamed
    SSL_CLIENT_ISPSSL_CLIENT_I_DN_SPrenamed
    SSL_CLIENT_ILSSL_CLIENT_I_DN_Lrenamed
    SSL_EXPORTSSL_CIPHER_EXPORTrenamed
    SSL_KEYSIZESSL_CIPHER_ALGKEYSIZErenamed
    SSL_SECKEYSIZESSL_CIPHER_USEKEYSIZErenamed
    SSL_SSLEAY_VERSIONSSL_VERSION_LIBRARYrenamed
    SSL_STRONG_CRYPTO-Not supported by mod_ssl
    SSL_SERVER_KEY_EXP-Not supported by mod_ssl
    SSL_SERVER_KEY_ALGORITHM-Not supported by mod_ssl
    SSL_SERVER_KEY_SIZE-Not supported by mod_ssl
    SSL_SERVER_SESSIONDIR-Not supported by mod_ssl
    SSL_SERVER_CERTIFICATELOGDIR-Not supported by mod_ssl
    SSL_SERVER_CERTFILE-Not supported by mod_ssl
    SSL_SERVER_KEYFILE-Not supported by mod_ssl
    SSL_SERVER_KEYFILETYPE-Not supported by mod_ssl
    SSL_CLIENT_KEY_EXP-Not supported by mod_ssl
    SSL_CLIENT_KEY_ALGORITHM-Not supported by mod_ssl
    SSL_CLIENT_KEY_SIZE-Not supported by mod_ssl
    + +
    top
    +
    +

    Custom Log Functions

    +

    +When mod_ssl is enabled, additional functions exist for the Custom Log Format of +mod_log_config as documented in the Reference +Chapter. Beside the ``%{varname}x'' +eXtension format function which can be used to expand any variables provided +by any module, an additional Cryptography +``%{name}c'' cryptography format function +exists for backward compatibility. The currently implemented function calls +are listed in Table 3.

    + +

    Table 3: Custom Log Cryptography Function

    + + + + + + + + + + + + +
    Function CallDescription
    %...{version}c SSL protocol version
    %...{cipher}c SSL cipher
    %...{subjectdn}c Client Certificate Subject Distinguished Name
    %...{issuerdn}c Client Certificate Issuer Distinguished Name
    %...{errcode}c Certificate Verification Error (numerical)
    %...{errstr}c Certificate Verification Error (string)
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/ssl_compat.xml b/trunk/docs/manual/ssl/ssl_compat.xml new file mode 100644 index 0000000000..3f10971d8b --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_compat.xml @@ -0,0 +1,261 @@ + + + + + + + + +SSL/TLS + + SSL/TLS Strong Encryption: Compatibility + + +
    +

    All PCs are compatible. But some of +them are more compatible than others.

    +

    -- Unknown

    +
    + +

    +This page covers backwards compatibility between mod_ssl and other +SSL solutions. mod_ssl is not the only SSL solution for Apache; four +additional products are (or were) also available: Ben Laurie's freely +available Apache-SSL (from +where mod_ssl were originally derived in 1998), Red Hat's commercial +Secure +Web Server (which was based on mod_ssl), Covalent's commercial Raven SSL Module (also based on +mod_ssl) and finally C2Net's (now Red Hat's) commercial product Stronghold (based +on a different evolution branch named Sioux up to Stronghold 2.x and +based on mod_ssl since Stronghold 3.x).

    + +

    +mod_ssl mostly provides a superset of the functionality of all the other +solutions, so it's simple to migrate from one of the older modules to +mod_ssl. The configuration directives and environment variable names +used by the older SSL solutions vary from those used in mod_ssl; +mapping tables are included here to give the equivalents used by mod_ssl.

    +
    + +
    Configuration Directives +

    The mapping between configuration directives used by Apache-SSL +1.x and mod_ssl 2.0.x is given in Table +1. The mapping from Sioux 1.x and Stronghold 2.x is only partial +because of special functionality in these interfaces which mod_ssl +doesn't provide.

    + + +
    +Table 1: Configuration Directive Mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Old Directivemod_ssl DirectiveComment
    Apache-SSL 1.x & mod_ssl 2.0.x compatibility:
    SSLEnableSSLEngine oncompactified
    SSLDisableSSLEngine offcompactified
    SSLLogFile fileSSLLog filecompactified
    SSLRequiredCiphers specSSLCipherSuite specrenamed
    SSLRequireCipher c1 ...SSLRequire %{SSL_CIPHER} in {"c1", +...}generalized
    SSLBanCipher c1 ...SSLRequire not (%{SSL_CIPHER} in {"c1", +...})generalized
    SSLFakeBasicAuthSSLOptions +FakeBasicAuthmerged
    SSLCacheServerPath dir-functionality removed
    SSLCacheServerPort integer-functionality removed
    Apache-SSL 1.x compatibility:
    SSLExportClientCertificatesSSLOptions +ExportCertDatamerged
    SSLCacheServerRunDir dir-functionality not supported
    Sioux 1.x compatibility:
    SSL_CertFile fileSSLCertificateFile filerenamed
    SSL_KeyFile fileSSLCertificateKeyFile filerenamed
    SSL_CipherSuite argSSLCipherSuite argrenamed
    SSL_X509VerifyDir argSSLCACertificatePath argrenamed
    SSL_Log fileSSLLogFile filerenamed
    SSL_Connect flagSSLEngine flagrenamed
    SSL_ClientAuth argSSLVerifyClient argrenamed
    SSL_X509VerifyDepth argSSLVerifyDepth argrenamed
    SSL_FetchKeyPhraseFrom arg-not directly mappable; use SSLPassPhraseDialog
    SSL_SessionDir dir-not directly mappable; use SSLSessionCache
    SSL_Require expr-not directly mappable; use SSLRequire
    SSL_CertFileType arg-functionality not supported
    SSL_KeyFileType arg-functionality not supported
    SSL_X509VerifyPolicy arg-functionality not supported
    SSL_LogX509Attributes arg-functionality not supported
    Stronghold 2.x compatibility:
    StrongholdAccelerator engineSSLCryptoDevice enginerenamed
    StrongholdKey dir-functionality not needed
    StrongholdLicenseFile dir-functionality not needed
    SSLFlag flagSSLEngine flagrenamed
    SSLSessionLockFile fileSSLMutex filerenamed
    SSLCipherList specSSLCipherSuite specrenamed
    RequireSSLSSLRequireSSLrenamed
    SSLErrorFile file-functionality not supported
    SSLRoot dir-functionality not supported
    SSL_CertificateLogDir dir-functionality not supported
    AuthCertDir dir-functionality not supported
    SSL_Group name-functionality not supported
    SSLProxyMachineCertPath dirSSLProxyMachineCertificatePath dirrenamed
    SSLProxyMachineCertFile fileSSLProxyMachineCertificateFile filerenamed
    SSLProxyCipherList specSSLProxyCipherSpec specrenamed
    +
    +
    + +
    Environment Variables + +

    The mapping between environment variable names used by the older +SSL solutions and the names used by mod_ssl is given in Table 2.

    + +
    +Table 2: Environment Variable Derivation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Old Variablemod_ssl VariableComment
    SSL_PROTOCOL_VERSIONSSL_PROTOCOLrenamed
    SSLEAY_VERSIONSSL_VERSION_LIBRARYrenamed
    HTTPS_SECRETKEYSIZESSL_CIPHER_USEKEYSIZErenamed
    HTTPS_KEYSIZESSL_CIPHER_ALGKEYSIZErenamed
    HTTPS_CIPHERSSL_CIPHERrenamed
    HTTPS_EXPORTSSL_CIPHER_EXPORTrenamed
    SSL_SERVER_KEY_SIZESSL_CIPHER_ALGKEYSIZErenamed
    SSL_SERVER_CERTIFICATESSL_SERVER_CERTrenamed
    SSL_SERVER_CERT_STARTSSL_SERVER_V_STARTrenamed
    SSL_SERVER_CERT_ENDSSL_SERVER_V_ENDrenamed
    SSL_SERVER_CERT_SERIALSSL_SERVER_M_SERIALrenamed
    SSL_SERVER_SIGNATURE_ALGORITHMSSL_SERVER_A_SIGrenamed
    SSL_SERVER_DNSSL_SERVER_S_DNrenamed
    SSL_SERVER_CNSSL_SERVER_S_DN_CNrenamed
    SSL_SERVER_EMAILSSL_SERVER_S_DN_Emailrenamed
    SSL_SERVER_OSSL_SERVER_S_DN_Orenamed
    SSL_SERVER_OUSSL_SERVER_S_DN_OUrenamed
    SSL_SERVER_CSSL_SERVER_S_DN_Crenamed
    SSL_SERVER_SPSSL_SERVER_S_DN_SPrenamed
    SSL_SERVER_LSSL_SERVER_S_DN_Lrenamed
    SSL_SERVER_IDNSSL_SERVER_I_DNrenamed
    SSL_SERVER_ICNSSL_SERVER_I_DN_CNrenamed
    SSL_SERVER_IEMAILSSL_SERVER_I_DN_Emailrenamed
    SSL_SERVER_IOSSL_SERVER_I_DN_Orenamed
    SSL_SERVER_IOUSSL_SERVER_I_DN_OUrenamed
    SSL_SERVER_ICSSL_SERVER_I_DN_Crenamed
    SSL_SERVER_ISPSSL_SERVER_I_DN_SPrenamed
    SSL_SERVER_ILSSL_SERVER_I_DN_Lrenamed
    SSL_CLIENT_CERTIFICATESSL_CLIENT_CERTrenamed
    SSL_CLIENT_CERT_STARTSSL_CLIENT_V_STARTrenamed
    SSL_CLIENT_CERT_ENDSSL_CLIENT_V_ENDrenamed
    SSL_CLIENT_CERT_SERIALSSL_CLIENT_M_SERIALrenamed
    SSL_CLIENT_SIGNATURE_ALGORITHMSSL_CLIENT_A_SIGrenamed
    SSL_CLIENT_DNSSL_CLIENT_S_DNrenamed
    SSL_CLIENT_CNSSL_CLIENT_S_DN_CNrenamed
    SSL_CLIENT_EMAILSSL_CLIENT_S_DN_Emailrenamed
    SSL_CLIENT_OSSL_CLIENT_S_DN_Orenamed
    SSL_CLIENT_OUSSL_CLIENT_S_DN_OUrenamed
    SSL_CLIENT_CSSL_CLIENT_S_DN_Crenamed
    SSL_CLIENT_SPSSL_CLIENT_S_DN_SPrenamed
    SSL_CLIENT_LSSL_CLIENT_S_DN_Lrenamed
    SSL_CLIENT_IDNSSL_CLIENT_I_DNrenamed
    SSL_CLIENT_ICNSSL_CLIENT_I_DN_CNrenamed
    SSL_CLIENT_IEMAILSSL_CLIENT_I_DN_Emailrenamed
    SSL_CLIENT_IOSSL_CLIENT_I_DN_Orenamed
    SSL_CLIENT_IOUSSL_CLIENT_I_DN_OUrenamed
    SSL_CLIENT_ICSSL_CLIENT_I_DN_Crenamed
    SSL_CLIENT_ISPSSL_CLIENT_I_DN_SPrenamed
    SSL_CLIENT_ILSSL_CLIENT_I_DN_Lrenamed
    SSL_EXPORTSSL_CIPHER_EXPORTrenamed
    SSL_KEYSIZESSL_CIPHER_ALGKEYSIZErenamed
    SSL_SECKEYSIZESSL_CIPHER_USEKEYSIZErenamed
    SSL_SSLEAY_VERSIONSSL_VERSION_LIBRARYrenamed
    SSL_STRONG_CRYPTO-Not supported by mod_ssl
    SSL_SERVER_KEY_EXP-Not supported by mod_ssl
    SSL_SERVER_KEY_ALGORITHM-Not supported by mod_ssl
    SSL_SERVER_KEY_SIZE-Not supported by mod_ssl
    SSL_SERVER_SESSIONDIR-Not supported by mod_ssl
    SSL_SERVER_CERTIFICATELOGDIR-Not supported by mod_ssl
    SSL_SERVER_CERTFILE-Not supported by mod_ssl
    SSL_SERVER_KEYFILE-Not supported by mod_ssl
    SSL_SERVER_KEYFILETYPE-Not supported by mod_ssl
    SSL_CLIENT_KEY_EXP-Not supported by mod_ssl
    SSL_CLIENT_KEY_ALGORITHM-Not supported by mod_ssl
    SSL_CLIENT_KEY_SIZE-Not supported by mod_ssl
    +
    +
    + +
    Custom Log Functions +

    +When mod_ssl is enabled, additional functions exist for the Custom Log Format of +mod_log_config as documented in the Reference +Chapter. Beside the ``%{varname}x'' +eXtension format function which can be used to expand any variables provided +by any module, an additional Cryptography +``%{name}c'' cryptography format function +exists for backward compatibility. The currently implemented function calls +are listed in Table 3.

    + +
    +Table 3: Custom Log Cryptography Function + + + + + + + + + + + +
    Function CallDescription
    %...{version}c SSL protocol version
    %...{cipher}c SSL cipher
    %...{subjectdn}c Client Certificate Subject Distinguished Name
    %...{issuerdn}c Client Certificate Issuer Distinguished Name
    %...{errcode}c Certificate Verification Error (numerical)
    %...{errstr}c Certificate Verification Error (string)
    +
    +
    + +
    diff --git a/trunk/docs/manual/ssl/ssl_compat.xml.meta b/trunk/docs/manual/ssl/ssl_compat.xml.meta new file mode 100644 index 0000000000..a374a6187b --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_compat.xml.meta @@ -0,0 +1,11 @@ + + + + ssl_compat + /ssl/ + .. + + + en + + diff --git a/trunk/docs/manual/ssl/ssl_faq.html b/trunk/docs/manual/ssl/ssl_faq.html new file mode 100644 index 0000000000..c6d2ea13b9 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_faq.html @@ -0,0 +1,3 @@ +URI: ssl_faq.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/ssl/ssl_faq.html.en b/trunk/docs/manual/ssl/ssl_faq.html.en new file mode 100644 index 0000000000..d87803023b --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_faq.html.en @@ -0,0 +1,1017 @@ + + + +SSL/TLS Strong Encryption: FAQ - Apache HTTP Server + + + + + +
    <-
    +

    SSL/TLS Strong Encryption: FAQ

    +
    +

    Available Languages:  en 

    +
    + +
    +

    The wise man doesn't give the right answers, +he poses the right questions.

    +

    -- Claude Levi-Strauss

    + +
    +

    This chapter is a collection of frequently asked questions (FAQ) and +corresponding answers following the popular USENET tradition. Most of these +questions occurred on the Newsgroup comp.infosystems.www.servers.unix or the mod_ssl Support +Mailing List modssl-users@modssl.org. They are collected at this place +to avoid answering the same questions over and over.

    + +

    Please read this chapter at least once when installing mod_ssl or at least +search for your problem here before submitting a problem report to the +author.

    +
    + +
    top
    +
    +

    About The Module

    + + +

    What is the history of mod_ssl?

    +

    The mod_ssl v1 package was initially created in April 1998 by Ralf S. Engelschall via porting Ben Laurie's Apache-SSL 1.17 source patches for + Apache 1.2.6 to Apache 1.3b6. Because of conflicts with Ben + Laurie's development cycle it then was re-assembled from scratch for + Apache 1.3.0 by merging the old mod_ssl 1.x with the newer Apache-SSL + 1.18. From this point on mod_ssl lived its own life as mod_ssl v2. The + first publicly released version was mod_ssl 2.0.0 from August 10th, + 1998. As of this writing (August 1999) the current mod_ssl version + is 2.4.0.

    + + +

    After one year of very active development with over 1000 working hours and + over 40 releases mod_ssl reached its current state. The result is an + already very clean source base implementing a very rich functionality. + The code size increased by a factor of 4 to currently a total of over + 10.000 lines of ANSI C consisting of approx. 70% code and 30% code + documentation. From the original Apache-SSL code currently approx. 5% is + remaining only.

    + +

    After the US export restrictions for cryptographic software were + opened, mod_ssl was integrated into the code base of Apache V2 in 2001.

    + + +

    Is mod_ssl Year 2000 compliant?

    +

    Yes, mod_ssl is Year 2000 compliant.

    + +

    Because first mod_ssl internally never stores years as two digits. + Instead it always uses the ANSI C & POSIX numerical data type + time_t type, which on almost all Unix platforms at the moment + is a signed long (usually 32-bits) representing seconds since + epoch of January 1st, 1970, 00:00 UTC. This signed value overflows in + early January 2038 and not in the year 2000. Second, date and time + presentations (for instance the variable ``%{TIME_YEAR}'') + are done with full year value instead of abbreviating to two digits.

    + + +

    Additionally according to a Year 2000 + statement from the Apache Group, the Apache webserver is Year 2000 + compliant, too. But whether OpenSSL or the underlying Operating System + (either a Unix or Win32 platform) is Year 2000 compliant is a different + question which cannot be answered here.

    + + +

    What about mod_ssl and the Wassenaar Arrangement?

    +

    First, let us explain what Wassenaar and its Arrangement on + Export Controls for Conventional Arms and Dual-Use Goods and + Technologies is: This is a international regime, established 1995, to + control trade in conventional arms and dual-use goods and technology. It + replaced the previous CoCom regime. 33 countries are signatories: + Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, + Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, + Luxembourg, the Netherlands, New Zealand, Norway, Poland, Portugal, Republic + of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, + Switzerland, Turkey, Ukraine, the United Kingdom and the United States. For more + details look at http://www.wassenaar.org/.

    + + +

    In short: The aim of the Wassenaar Arrangement is to prevent the build up + of military capabilities that threaten regional and international security + and stability. The Wassenaar Arrangement controls the export of + cryptography as a dual-use good, i.e., one that has both military and + civilian applications. However, the Wassenaar Arrangement also provides an + exemption from export controls for mass-market software and free software.

    + +

    In the current Wassenaar List of Dual Use Goods and Technologies And + Munitions, under GENERAL SOFTWARE NOTE (GSN) it says + The Lists do not control "software" which is either: 1. [...] 2. "in + the public domain". And under DEFINITIONS OF TERMS USED IN + THESE LISTS one can find the definition: In the public + domain": This means "technology" or "software" which has been made + available without restrictions upon its further dissemination. N.B. + Copyright restrictions do not remove "technology" or "software" from being + "in the public domain".

    + +

    So, both mod_ssl and OpenSSL are in the public domain for the purposes + of the Wassenaar Agreement and its List of Dual Use Goods and + Technologies And Munitions List.

    + +

    So, mod_ssl and OpenSSL are not affected by the Wassenaar Agreement.

    + +
    top
    +
    +

    About Installation

    + + +

    When I access my website the first time via HTTPS I get a core dump?

    +

    There can be a lot of reasons why a core dump can occur, of course. + Ranging from buggy third-party modules, over buggy vendor libraries up to + a buggy mod_ssl version. But the above situation is often caused by old or + broken vendor DBM libraries. To solve it either build mod_ssl with the + built-in SDBM library (specify --enable-rule=SSL_SDBM at the + APACI command line) or switch from SSLSessionCache dbm: to the + newer SSLSessionCache shm:'' variant (after you have rebuilt + Apache with MM, of course).

    + + +

    When I startup Apache I get permission errors related to SSLMutex?

    +

    When you receive entries like ``mod_ssl: Child could not open + SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows) + [...] System: Permission denied (errno: 13)'' this is usually + caused by to restrictive permissions on the parent directories. + Make sure that all parent directories (here /opt, + /opt/apache and /opt/apache/logs) have the x-bit + set at least for the UID under which Apache's children are running (see + the User directive of Apache).

    + + +

    When I use the MM library and the shared memory cache each process grows +1.5MB according to `top' although I specified 512000 as the cache size?

    +

    The additional 1MB are caused by the global shared memory pool Apache + allocates for all modules and which is not used by mod_ssl for + various reasons. So the actually allocated shared memory is always + 1MB more than what you specify on SSLSessionCache. + But don't be confused by the display of `top': although is + indicates that each process grow, this is not reality, of + course. Instead the additional memory consumption is shared by + all processes, i.e. the 1.5MB are allocated only once per Apache + instance and not once per Apache server process.

    + + +

    When I fire up the server, mod_ssl stops with the error +"Failed to generate temporary 512 bit RSA private key", why?

    +

    Cryptographic software needs a source of unpredictable data + to work correctly. Many open source operating systems provide + a "randomness device" that serves this purpose (usually named + /dev/random). On other systems, applications have to + seed the OpenSSL Pseudo Random Number Generator (PRNG) manually with + appropriate data before generating keys or performing public key + encryption. As of version 0.9.5, the OpenSSL functions that need + randomness report an error if the PRNG has not been seeded with + at least 128 bits of randomness. So mod_ssl has to provide enough + entropy to the PRNG to work correctly. For this one has to use the + SSLRandomSeed directives.

    + +
    top
    +
    +

    About Configuration

    + + +

    Is it possible to provide HTTP and HTTPS with a single server?

    +

    Yes, HTTP and HTTPS use different server ports, so there is no direct + conflict between them. Either run two separate server instances (one binds + to port 80, the other to port 443) or even use Apache's elegant virtual + hosting facility where you can easily create two virtual servers which + Apache dispatches: one responding to port 80 and speaking HTTP and one + responding to port 443 speaking HTTPS.

    + + +

    I know that HTTP is on port 80, but where is HTTPS?

    +

    You can run HTTPS on any port, but the standards specify port 443, which + is where any HTTPS compliant browser will look by default. You can force + your browser to look on a different port by specifying it in the URL like + this (for port 666): https://secure.server.dom:666/

    + + +

    How can I speak HTTPS manually for testing purposes?

    +

    While you usually just use

    + +

    $ telnet localhost 80
    + GET / HTTP/1.0

    + + +

    for simple testing the HTTP protocol of Apache, it's not so easy for + HTTPS because of the SSL protocol between TCP and HTTP. But with the + help of OpenSSL's s_client command you can do a similar + check even for HTTPS:

    + +

    $ openssl s_client -connect localhost:443 -state -debug
    + GET / HTTP/1.0

    + +

    Before the actual HTTP response you receive detailed information about the + SSL handshake. For a more general command line client which directly + understands both the HTTP and HTTPS scheme, can perform GET and POST + methods, can use a proxy, supports byte ranges, etc. you should have a + look at nifty cURL + tool. With it you can directly check if your Apache is running fine on + Port 80 and 443 as following:

    + +

    $ curl http://localhost/
    + $ curl https://localhost/

    + + +

    Why does the connection hang when I connect to my SSL-aware Apache server?

    +

    Because you connected with HTTP to the HTTPS port, i.e. you used an URL of + the form ``http://'' instead of ``https://''. + This also happens the other way round when you connect via HTTPS to a HTTP + port, i.e. when you try to use ``https://'' on a server that + doesn't support SSL (on this port). Make sure you are connecting to a + virtual server that supports SSL, which is probably the IP associated with + your hostname, not localhost (127.0.0.1).

    + + +

    Why do I get ``Connection Refused'' messages when trying to access my freshly +installed Apache+mod_ssl server via HTTPS?

    +

    There can be various reasons. Some of the common mistakes is that people + start Apache with just apachectl start (or + httpd) instead of apachectl startssl (or + httpd -DSSL. Or you're configuration is not correct. At + least make sure that your Listen + directives match your <VirtualHost> + directives. And if all fails, please do yourself a favor and start over with the + default configuration mod_ssl provides you.

    + + +

    In my CGI programs and SSI scripts the various documented +SSL_XXX variables do not exist. Why?

    +

    Just make sure you have ``SSLOptions +StdEnvVars'' + enabled for the context of your CGI/SSI requests.

    + + +

    How can I use relative hyperlinks to switch between HTTP and +HTTPS?

    + +

    Usually you have to use fully-qualified hyperlinks because + you have to change the URL scheme. But with the help of some URL + manipulations through mod_rewrite you can achieve the same effect while + you still can use relative URLs:

    +

    + RewriteEngine on
    + RewriteRule ^/(.*):SSL$ https://%{SERVER_NAME}/$1 [R,L]
    + RewriteRule ^/(.*):NOSSL$ http://%{SERVER_NAME}/$1 [R,L] +

    + +

    This rewrite ruleset lets you use hyperlinks of the form + <a href="document.html:SSL">

    + +
    top
    +
    +

    About Certificates

    + + +

    What are RSA Private Keys, CSRs and Certificates?

    +

    The RSA private key file is a digital file that you can use to decrypt + messages sent to you. It has a public component which you distribute (via + your Certificate file) which allows people to encrypt those messages to + you. A Certificate Signing Request (CSR) is a digital file which contains + your public key and your name. You send the CSR to a Certifying Authority + (CA) to be converted into a real Certificate. A Certificate contains your + RSA public key, your name, the name of the CA, and is digitally signed by + your CA. Browsers that know the CA can verify the signature on that + Certificate, thereby obtaining your RSA public key. That enables them to + send messages which only you can decrypt. + See the Introduction chapter for a general + description of the SSL protocol.

    + + +

    Seems like there is a difference on startup between the original Apache and an SSL-aware Apache?

    +

    Yes, in general, starting Apache with a built-in mod_ssl is just like + starting an unencumbered Apache, except for the fact that when you have a + pass phrase on your SSL private key file. Then a startup dialog pops up + asking you to enter the pass phrase.

    + +

    To type in the pass phrase manually when starting the server can be + problematic, for instance when starting the server from the system boot + scripts. As an alternative to this situation you can follow the steps + below under ``How can I get rid of the pass-phrase dialog at Apache + startup time?''.

    + + +

    Ok, I've got my server installed and want to create a real SSL +server Certificate for it. How do I do it?

    +

    Here is a step-by-step description:

    + +
      +
    1. Make sure OpenSSL is really installed and in your PATH. + But some commands even work ok when you just run the + ``openssl'' program from within the OpenSSL source tree as + ``./apps/openssl''.
      + +
      +
    2. +
    3. Create a RSA private key for your Apache server + (will be Triple-DES encrypted and PEM formatted):
      +
      + $ openssl genrsa -des3 -out server.key 1024
      +
      + Please backup this server.key file and remember the + pass-phrase you had to enter at a secure location. + You can see the details of this RSA private key via the command:
      + +
      + $ openssl rsa -noout -text -in server.key
      +
      + And you could create a decrypted PEM version (not recommended) + of this RSA private key via:
      +
      + $ openssl rsa -in server.key -out server.key.unsecure
      +
      + +
    4. +
    5. Create a Certificate Signing Request (CSR) with the server RSA private + key (output will be PEM formatted):
      +
      + $ openssl req -new -key server.key -out server.csr
      +
      + Make sure you enter the FQDN ("Fully Qualified Domain Name") of the + server when OpenSSL prompts you for the "CommonName", i.e. when you + generate a CSR for a website which will be later accessed via + https://www.foo.dom/, enter "www.foo.dom" here. + You can see the details of this CSR via the command
      + +
      + $ openssl req -noout -text -in server.csr
      +
      +
    6. +
    7. You now have to send this Certificate Signing Request (CSR) to + a Certifying Authority (CA) for signing. The result is then a real + Certificate which can be used for Apache. Here you have two options: + First you can let the CSR sign by a commercial CA like Verisign or + Thawte. Then you usually have to post the CSR into a web form, pay for + the signing and await the signed Certificate you then can store into a + server.crt file. For more information about commercial CAs have a look + at the following locations:
      +
      +
        +
      1. Verisign
        + + + http://digitalid.verisign.com/server/apacheNotice.htm + +
      2. +
      3. Thawte Consulting
        + + http://www.thawte.com/certs/server/request.html + +
      4. + +
      5. CertiSign Certificadora Digital Ltda.
        + + http://www.certisign.com.br + +
      6. +
      7. IKS GmbH
        + + + http://www.iks-jena.de/produkte/ca/ + +
      8. +
      9. Uptime Commerce Ltd.
        + + http://www.uptimecommerce.com + +
      10. +
      11. BelSign NV/SA
        + + + http://www.belsign.be + +
      12. +
      + + Second you can use your own CA and now have to sign the CSR yourself by + this CA. Read the next answer in this FAQ on how to sign a CSR with + your CA yourself. + You can see the details of the received Certificate via the command:
      +
      + $ openssl x509 -noout -text -in server.crt
      + +
    8. +
    9. Now you have two files: server.key and + server.crt. These now can be used as following inside your + Apache's httpd.conf file: +
      +       SSLCertificateFile    /path/to/this/server.crt
      +       SSLCertificateKeyFile /path/to/this/server.key
      +       
      + The server.csr file is no longer needed. +
    10. + +
    + + +

    How can I create and use my own Certificate Authority (CA)?

    +

    The short answer is to use the CA.sh or CA.pl + + script provided by OpenSSL. The long and manual answer is this:

    + +
      +
    1. Create a RSA private key for your CA + (will be Triple-DES encrypted and PEM formatted):
      +
      + $ openssl genrsa -des3 -out ca.key 1024
      +
      + Please backup this ca.key file and remember the + pass-phrase you currently entered at a secure location. + You can see the details of this RSA private key via the command
      + +
      + $ openssl rsa -noout -text -in ca.key
      +
      + And you can create a decrypted PEM version (not recommended) of this + private key via:
      +
      + $ openssl rsa -in ca.key -out ca.key.unsecure
      +
      + +
    2. +
    3. Create a self-signed CA Certificate (X509 structure) + with the RSA key of the CA (output will be PEM formatted):
      +
      + $ openssl req -new -x509 -days 365 -key ca.key -out ca.crt
      +
      + You can see the details of this Certificate via the command:
      +
      + + $ openssl x509 -noout -text -in ca.crt
      +
      +
    4. +
    5. Prepare a script for signing which is needed because + the ``openssl ca'' command has some strange requirements + and the default OpenSSL config doesn't allow one easily to use + ``openssl ca'' directly. So a script named + sign.sh is distributed with the mod_ssl distribution + (subdir pkg.contrib/). Use this script for signing. +
    6. + +
    7. Now you can use this CA to sign server CSR's in order to create real + SSL Certificates for use inside an Apache webserver (assuming + you already have a server.csr at hand):
      +
      + $ ./sign.sh server.csr
      +
      + This signs the server CSR and results in a server.crt file.
      + +
    8. +
    + + + +

    How can I change the pass-phrase on my private key file?

    +

    You simply have to read it with the old pass-phrase and write it again + by specifying the new pass-phrase. You can accomplish this with the following + commands:

    + + +

    $ openssl rsa -des3 -in server.key -out server.key.new
    + $ mv server.key.new server.key

    + +

    Here you're asked two times for a PEM pass-phrase. At the first + prompt enter the old pass-phrase and at the second prompt + enter the new pass-phrase.

    + + +

    How can I get rid of the pass-phrase dialog at Apache startup time?

    +

    The reason why this dialog pops up at startup and every re-start + is that the RSA private key inside your server.key file is stored in + encrypted format for security reasons. The pass-phrase is needed to be + able to read and parse this file. When you can be sure that your server is + secure enough you perform two steps:

    + +
      +
    1. Remove the encryption from the RSA private key (while + preserving the original file):
      +
      + $ cp server.key server.key.org
      + $ openssl rsa -in server.key.org -out server.key
      + +
      +
    2. +
    3. Make sure the server.key file is now only readable by root:
      +
      + $ chmod 400 server.key
      +
      +
    4. +
    + +

    Now server.key will contain an unencrypted copy of the key. + If you point your server at this file it will not prompt you for a + pass-phrase. HOWEVER, if anyone gets this key they will be able to + impersonate you on the net. PLEASE make sure that the permissions on that + file are really such that only root or the web server user can read it + (preferably get your web server to start as root but run as another + server, and have the key readable only by root).

    + +

    As an alternative approach you can use the ``SSLPassPhraseDialog + exec:/path/to/program'' facility. But keep in mind that this is + neither more nor less secure, of course.

    + + +

    How do I verify that a private key matches its Certificate?

    +

    The private key contains a series of numbers. Two of those numbers form + the "public key", the others are part of your "private key". The "public + key" bits are also embedded in your Certificate (we get them from your + CSR). To check that the public key in your cert matches the public + portion of your private key, you need to view the cert and the key and + compare the numbers. To view the Certificate and the key run the + commands:

    + +

    $ openssl x509 -noout -text -in server.crt
    + $ openssl rsa -noout -text -in server.key

    + +

    The `modulus' and the `public exponent' portions in the key and the + Certificate must match. But since the public exponent is usually 65537 + and it's bothering comparing long modulus you can use the following + approach:

    + + +

    $ openssl x509 -noout -modulus -in server.crt | openssl md5
    + $ openssl rsa -noout -modulus -in server.key | openssl md5

    + +

    And then compare these really shorter numbers. With overwhelming + probability they will differ if the keys are different. BTW, if I want to + check to which key or certificate a particular CSR belongs you can compute

    + +

    $ openssl req -noout -modulus -in server.csr | openssl md5

    + + +

    What does it mean when my connections fail with an "alert bad certificate" +error?

    +

    Usually when you see errors like OpenSSL: error:14094412: SSL + routines:SSL3_READ_BYTES:sslv3 alert bad certificate in the SSL + logfile, this means that the browser was unable to handle the server + certificate/private-key which perhaps contain a RSA-key not equal to 1024 + bits. For instance Netscape Navigator 3.x is one of those browsers.

    + + +

    Why does my 2048-bit private key not work?

    +

    The private key sizes for SSL must be either 512 or 1024 for compatibility + with certain web browsers. A keysize of 1024 bits is recommended because + keys larger than 1024 bits are incompatible with some versions of Netscape + Navigator and Microsoft Internet Explorer, and with other browsers that + use RSA's BSAFE cryptography toolkit.

    + + +

    Why is client authentication broken after upgrading from +SSLeay version 0.8 to 0.9?

    +

    The CA certificates under the path you configured with + SSLCACertificatePath are found by SSLeay through hash + symlinks. These hash values are generated by the `openssl x509 -noout + -hash' command. But the algorithm used to calculate the hash for a + certificate has changed between SSLeay 0.8 and 0.9. So you have to remove + all old hash symlinks and re-create new ones after upgrading. Use the + Makefile mod_ssl placed into this directory.

    + + +

    How can I convert a certificate from PEM to DER format?

    +

    The default certificate format for SSLeay/OpenSSL is PEM, which actually + is Base64 encoded DER with header and footer lines. For some applications + (e.g. Microsoft Internet Explorer) you need the certificate in plain DER + format. You can convert a PEM file cert.pem into the + corresponding DER file cert.der with the following command: + $ openssl x509 -in cert.pem -out cert.der -outform DER

    + + +

    I try to install a Verisign certificate. Why can't I find neither the +getca nor getverisign programs Verisign mentions?

    +

    This is because Verisign has never provided specific instructions + for Apache+mod_ssl. Rather they tell you what you should do + if you were using C2Net's Stronghold (a commercial Apache + based server with SSL support). The only thing you have to do + is to save the certificate into a file and give the name of + that file to the SSLCertificateFile directive. + Remember that you need to give the key file in as well (see + SSLCertificateKeyFile directive). For a better + CA-related overview on SSL certificate fiddling you can look at Thawte's mod_ssl instructions.

    + + +

    Can I use the Server Gated Cryptography (SGC) facility (aka Verisign Global +ID) also with mod_ssl?

    +

    Yes, mod_ssl since version 2.1 supports the SGC facility. You don't have + to configure anything special for this, just use a Global ID as your + server certificate. The step up of the clients are then + automatically handled by mod_ssl under run-time. For details please read + the README.GlobalID document in the mod_ssl distribution.

    + + +

    After I have installed my new Verisign Global ID server certificate, the +browsers complain that they cannot verify the server certificate?

    +

    That is because Verisign uses an intermediate CA certificate between + the root CA certificate (which is installed in the browsers) and + the server certificate (which you installed in the server). You + should have received this additional CA certificate from Verisign. + If not, complain to them. Then configure this certificate with the + SSLCertificateChainFile directive in the server. This + makes sure the intermediate CA certificate is send to the browser + and this way fills the gap in the certificate chain.

    + +
    top
    +
    +

    About SSL Protocol

    + + +

    Why do I get lots of random SSL protocol errors under heavy server load?

    +

    There can be a number of reasons for this, but the main one + is problems with the SSL session Cache specified by the + SSLSessionCache directive. The DBM session + cache is most likely the source of the problem, so trying the SHM session cache or + no cache at all may help.

    + + +

    Why has my webserver a higher load now that I run SSL there?

    +

    Because SSL uses strong cryptographic encryption and this needs a lot of + number crunching. And because when you request a webpage via HTTPS even + the images are transferred encrypted. So, when you have a lot of HTTPS + traffic the load increases.

    + + +

    Often HTTPS connections to my server require up to 30 seconds for establishing +the connection, although sometimes it works faster?

    +

    Usually this is caused by using a /dev/random device for + SSLRandomSeed which is blocking in read(2) calls if not + enough entropy is available. Read more about this problem in the reference + chapter under SSLRandomSeed.

    + + +

    What SSL Ciphers are supported by mod_ssl?

    +

    Usually just all SSL ciphers which are supported by the + version of OpenSSL in use (can depend on the way you built + OpenSSL). Typically this at least includes the following:

    + +
      +
    1. RC4 with MD5
    2. + +
    3. RC4 with MD5 (export version restricted to 40-bit key)
    4. +
    5. RC2 with MD5
    6. +
    7. RC2 with MD5 (export version restricted to 40-bit key)
    8. +
    9. IDEA with MD5
    10. +
    11. DES with MD5
    12. +
    13. Triple-DES with MD5
    14. + +
    + +

    To determine the actual list of supported ciphers you can + run the following command:

    +

    $ openssl ciphers -v

    + + +

    I want to use Anonymous Diffie-Hellman (ADH) ciphers, but I always get ``no +shared cipher'' errors?

    +

    In order to use Anonymous Diffie-Hellman (ADH) ciphers, it is not enough + to just put ``ADH'' into your SSLCipherSuite. + Additionally you have to build OpenSSL with + ``-DSSL_ALLOW_ADH''. Because per default OpenSSL does not + allow ADH ciphers for security reasons. So if you are actually enabling + these ciphers make sure you are informed about the side-effects.

    + + +

    I always just get a 'no shared ciphers' error if +I try to connect to my freshly installed server?

    +

    Either you have messed up your SSLCipherSuite + directive (compare it with the pre-configured example in + httpd.conf-dist) or you have chosen the DSA/DH + algorithms instead of RSA when you generated your private key + and ignored or overlooked the warnings. If you have chosen + DSA/DH, then your server no longer speaks RSA-based SSL ciphers + (at least not until you also configure an additional RSA-based + certificate/key pair). But current browsers like NS or IE only speak + RSA ciphers. The result is the "no shared ciphers" error. To fix + this, regenerate your server certificate/key pair and this time + choose the RSA algorithm.

    + + +

    Why can't I use SSL with name-based/non-IP-based virtual hosts?

    +

    The reason is very technical. Actually it's some sort of a chicken and + egg problem: The SSL protocol layer stays below the HTTP protocol layer + and encapsulates HTTP. When an SSL connection (HTTPS) is established + Apache/mod_ssl has to negotiate the SSL protocol parameters with the + client. For this mod_ssl has to consult the configuration of the virtual + server (for instance it has to look for the cipher suite, the server + certificate, etc.). But in order to dispatch to the correct virtual server + Apache has to know the Host HTTP header field. For this the + HTTP request header has to be read. This cannot be done before the SSL + handshake is finished. But the information is already needed at the SSL + handshake phase. Bingo!

    + + +

    Why is it not possible to use Name-Based +Virtual Hosting to identify different SSL virtual hosts?

    +

    Name-Based Virtual Hosting is a very popular method of identifying + different virtual hosts. It allows you to use the same IP address and + the same port number for many different sites. When people move on to + SSL, it seems natural to assume that the same method can be used to have + lots of different SSL virtual hosts on the same server.

    + +

    It comes as rather a shock to learn that it is impossible.

    + +

    The reason is that the SSL protocol is a separate layer which + encapsulates the HTTP protocol. So the problem is that the SSL session + is a separate transaction that takes place before the HTTP session even + starts. Therefore all the server receives is an SSL request on IP + address X and port Y (usually 443). Since the SSL request does not + contain any Host: field, the server has no way to decide which SSL + virtual host to use. Usually, it will just use the first one it finds + that matches the port and IP address.

    + +

    You can, of course, use Name-Based Virtual Hosting to identify many + non-SSL virtual hosts (all on port 80, for example) and then you can + have no more than 1 SSL virtual host (on port 443). But if you do this, + you must make sure to put the non-SSL port number on the NameVirtualHost + directive, e.g.

    + +

    + NameVirtualHost 192.168.1.1:80 +

    + +

    Other workaround solutions are:

    + +

    Use separate IP addresses for different SSL hosts. + Use different port numbers for different SSL hosts.

    + + +

    When I use Basic Authentication over HTTPS the lock icon in Netscape browsers +still shows the unlocked state when the dialog pops up. Does this mean the +username/password is still transmitted unencrypted?

    +

    No, the username/password is already transmitted encrypted. The icon in + Netscape browsers is just not really synchronized with the SSL/TLS layer + (it toggles to the locked state when the first part of the actual webpage + data is transferred which is not quite correct) and this way confuses + people. The Basic Authentication facility is part of the HTTP layer and + this layer is above the SSL/TLS layer in HTTPS. And before any HTTP data + communication takes place in HTTPS the SSL/TLS layer has already done the + handshake phase and switched to encrypted communication. So, don't get + confused by this icon.

    + + +

    When I connect via HTTPS to an Apache+mod_ssl+OpenSSL server with Microsoft Internet +Explorer (MSIE) I get various I/O errors. What is the reason?

    +

    The first reason is that the SSL implementation in some MSIE versions has + some subtle bugs related to the HTTP keep-alive facility and the SSL close + notify alerts on socket connection close. Additionally the interaction + between SSL and HTTP/1.1 features are problematic with some MSIE versions, + too. You've to work-around these problems by forcing + Apache+mod_ssl+OpenSSL to not use HTTP/1.1, keep-alive connections or + sending the SSL close notify messages to MSIE clients. This can be done by + using the following directive in your SSL-aware virtual host section:

    +

    + SetEnvIf User-Agent ".*MSIE.*" \
    + nokeepalive ssl-unclean-shutdown \
    + downgrade-1.0 force-response-1.0 +

    +

    Additionally it is known some MSIE versions have also problems + with particular ciphers. Unfortunately one cannot workaround these + bugs only for those MSIE particular clients, because the ciphers + are already used in the SSL handshake phase. So a MSIE-specific + SetEnvIf doesn't work + to solve these problems. Instead one has to do more drastic + adjustments to the global parameters. But before you decide to do + this, make sure your clients really have problems. If not, do not + do this, because it affects all(!) your clients, i.e., also your + non-MSIE clients.

    + +

    The next problem is that 56bit export versions of MSIE 5.x browsers have a + broken SSLv3 implementation which badly interacts with OpenSSL versions + greater than 0.9.4. You can either accept this and force your clients to + upgrade their browsers, or you downgrade to OpenSSL 0.9.4 (hmmm), or you + can decide to workaround it by accepting the drawback that your workaround + will horribly affect also other browsers:

    +

    SSLProtocol all -SSLv3

    +

    This completely disables the SSLv3 protocol and lets those browsers work. + But usually this is an even less acceptable workaround. A more reasonable + workaround is to address the problem more closely and disable only the + ciphers which cause trouble.

    +

    SSLCipherSuite + ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +

    + +

    This also lets the broken MSIE versions work, but only removes the + newer 56bit TLS ciphers.

    + +

    Another problem with MSIE 5.x clients is that they refuse to connect to + URLs of the form https://12.34.56.78/ (IP-addresses are used + instead of the hostname), if the server is using the Server Gated + Cryptography (SGC) facility. This can only be avoided by using the fully + qualified domain name (FQDN) of the website in hyperlinks instead, because + MSIE 5.x has an error in the way it handles the SGC negotiation.

    + +

    And finally there are versions of MSIE which seem to require that + an SSL session can be reused (a totally non standard-conforming + behaviour, of course). Connection with those MSIE versions only work + if a SSL session cache is used. So, as a work-around, make sure you + are using a session cache (see SSLSessionCache directive).

    + + +

    When I connect via HTTPS to an Apache+mod_ssl server with Netscape Navigator I +get I/O errors and the message "Netscape has encountered bad data from the +server" What's the reason?

    +

    + The problem usually is that you had created a new server certificate with + the same DN, but you had told your browser to accept forever the old + server certificate. Once you clear the entry in your browser for the old + certificate, everything usually will work fine. Netscape's SSL + implementation is correct, so when you encounter I/O errors with Netscape + Navigator it is most of the time caused by the configured certificates.

    + +
    top
    +
    +

    About Support

    + + +

    What information resources are available in case of mod_ssl problems?

    +

    The following information resources are available. + In case of problems you should search here first.

    + +
    +
    Answers in the User Manual's F.A.Q. List (this)
    +
    + http://httpd.apache.org/docs-2.1/ssl/ssl_faq.html
    + First look inside the F.A.Q. (this text), perhaps your problem is such + popular that it was already answered a lot of times in the past. +
    +
    Postings from the modssl-users Support Mailing List + http://www.modssl.org/support/
    +
    Second search for your problem in one of the existing archives of the + modssl-users mailing list. Perhaps your problem popped up at least once for + another user, too. +
    +
    + + +

    What support contacts are available in case of mod_ssl problems?

    +

    The following lists all support possibilities for mod_ssl, in order of + preference, i.e. start in this order and do not pick the support possibility + you just like most, please.

    + +
      +
    1. Write a Problem Report into the Bug Database
      + + http://www.modssl.org/support/bugdb/
      + This is the preferred way of submitting your problem report, because this + way it gets filed into the bug database (it cannot be lost) and + send to the modssl-users mailing list (others see the current problems and + learn from answers). +
    2. + +
    3. Write a Problem Report to the modssl-users Support Mailing List
      + + modssl-users@modssl.org
      + This is the second way of submitting your problem report. You have to + subscribe to the list first, but then you can easily discuss your problem + with both the author and the whole mod_ssl user community. +
    4. +
    + + +

    What information and details should I + provide when writing a bug report?

    +

    You have to at least always provide the following information:

    + +
    +
    Apache and OpenSSL version information
    +
    The Apache version can be determined + by running httpd -v. The OpenSSL version can be + determined by running openssl version. Alternatively when + you have Lynx installed you can run the command lynx -mime_header + http://localhost/ | grep Server to determine all information in a + single step. +
    + +
    The details on how you built and installed Apache+mod_ssl+OpenSSL
    +
    For this you can provide a logfile of your terminal session which shows + the configuration and install steps. Alternatively you can at least + provide the configure command line you used. +
    + +
    In case of core dumps please include a Backtrace
    +
    In case your Apache+mod_ssl+OpenSSL should really dump core please attach + a stack-frame ``backtrace'' (see the next question on how to get it). + Without this information the reason for your core dump cannot be found. + So you have to provide the backtrace, please. +
    + +
    A detailed description of your problem
    +
    Don't laugh, I'm totally serious. I already got a lot of problem reports + where the people not really said what's the actual problem is. So, in your + own interest (you want the problem be solved, don't you?) include as much + details as possible, please. But start with the essentials first, of + course. +
    +
    + + +

    I got a core dump, can you help me?

    +

    In general no, at least not unless you provide more details about the code + location where Apache dumped core. What is usually always required in + order to help you is a backtrace (see next question). Without this + information it is mostly impossible to find the problem and help you in + fixing it.

    + + +

    Ok, I got a core dump but how do I get a backtrace to find out the reason for it?

    +

    Follow the following steps:

    +
      +
    1. Make sure you have debugging symbols available in at least + Apache. On platforms where you use GCC/GDB you have to build + Apache+mod_ssl with ``OPTIM="-g -ggdb3"'' to achieve this. On + other platforms at least ``OPTIM="-g"'' is needed. +
    2. + +
    3. Startup the server and try to produce the core-dump. For this you perhaps + want to use a directive like ``CoreDumpDirectory /tmp'' to + make sure that the core-dump file can be written. You then should get a + /tmp/core or /tmp/httpd.core file. When you + don't get this, try to run your server under an UID != 0 (root), because + most "current" kernels do not allow a process to dump core after it has + done a setuid() (unless it does an exec()) for + security reasons (there can be privileged information left over in + memory). Additionally you can run /path/to/httpd -X + manually to force Apache to not fork. +
    4. + +
    5. Analyze the core-dump. For this run gdb /path/to/httpd + /tmp/httpd.core or a similar command has to run. In GDB you then + just have to enter the bt command and, voila, you get the + backtrace. For other debuggers consult your local debugger manual. Send + this backtrace to the author. +
    6. +
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/ssl_faq.xml b/trunk/docs/manual/ssl/ssl_faq.xml new file mode 100644 index 0000000000..7ffe81023a --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_faq.xml @@ -0,0 +1,1024 @@ + + + + + + + + +SSL/TLS + + SSL/TLS Strong Encryption: FAQ + + +
    +

    The wise man doesn't give the right answers, +he poses the right questions.

    +

    -- Claude Levi-Strauss

    + +
    +

    This chapter is a collection of frequently asked questions (FAQ) and +corresponding answers following the popular USENET tradition. Most of these +questions occurred on the Newsgroup comp.infosystems.www.servers.unix or the mod_ssl Support +Mailing List modssl-users@modssl.org. They are collected at this place +to avoid answering the same questions over and over.

    + +

    Please read this chapter at least once when installing mod_ssl or at least +search for your problem here before submitting a problem report to the +author.

    +
    + +
    About The Module + + +
    What is the history of mod_ssl? +

    The mod_ssl v1 package was initially created in April 1998 by Ralf S. Engelschall via porting Ben Laurie's Apache-SSL 1.17 source patches for + Apache 1.2.6 to Apache 1.3b6. Because of conflicts with Ben + Laurie's development cycle it then was re-assembled from scratch for + Apache 1.3.0 by merging the old mod_ssl 1.x with the newer Apache-SSL + 1.18. From this point on mod_ssl lived its own life as mod_ssl v2. The + first publicly released version was mod_ssl 2.0.0 from August 10th, + 1998. As of this writing (August 1999) the current mod_ssl version + is 2.4.0.

    + + +

    After one year of very active development with over 1000 working hours and + over 40 releases mod_ssl reached its current state. The result is an + already very clean source base implementing a very rich functionality. + The code size increased by a factor of 4 to currently a total of over + 10.000 lines of ANSI C consisting of approx. 70% code and 30% code + documentation. From the original Apache-SSL code currently approx. 5% is + remaining only.

    + +

    After the US export restrictions for cryptographic software were + opened, mod_ssl was integrated into the code base of Apache V2 in 2001.

    +
    + +
    Is mod_ssl Year 2000 compliant? +

    Yes, mod_ssl is Year 2000 compliant.

    + +

    Because first mod_ssl internally never stores years as two digits. + Instead it always uses the ANSI C & POSIX numerical data type + time_t type, which on almost all Unix platforms at the moment + is a signed long (usually 32-bits) representing seconds since + epoch of January 1st, 1970, 00:00 UTC. This signed value overflows in + early January 2038 and not in the year 2000. Second, date and time + presentations (for instance the variable ``%{TIME_YEAR}'') + are done with full year value instead of abbreviating to two digits.

    + + +

    Additionally according to a Year 2000 + statement from the Apache Group, the Apache webserver is Year 2000 + compliant, too. But whether OpenSSL or the underlying Operating System + (either a Unix or Win32 platform) is Year 2000 compliant is a different + question which cannot be answered here.

    +
    + +
    What about mod_ssl and the Wassenaar Arrangement? +

    First, let us explain what Wassenaar and its Arrangement on + Export Controls for Conventional Arms and Dual-Use Goods and + Technologies is: This is a international regime, established 1995, to + control trade in conventional arms and dual-use goods and technology. It + replaced the previous CoCom regime. 33 countries are signatories: + Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, + Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, + Luxembourg, the Netherlands, New Zealand, Norway, Poland, Portugal, Republic + of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, + Switzerland, Turkey, Ukraine, the United Kingdom and the United States. For more + details look at http://www.wassenaar.org/.

    + + +

    In short: The aim of the Wassenaar Arrangement is to prevent the build up + of military capabilities that threaten regional and international security + and stability. The Wassenaar Arrangement controls the export of + cryptography as a dual-use good, i.e., one that has both military and + civilian applications. However, the Wassenaar Arrangement also provides an + exemption from export controls for mass-market software and free software.

    + +

    In the current Wassenaar List of Dual Use Goods and Technologies And + Munitions, under GENERAL SOFTWARE NOTE (GSN) it says + The Lists do not control "software" which is either: 1. [...] 2. "in + the public domain". And under DEFINITIONS OF TERMS USED IN + THESE LISTS one can find the definition: In the public + domain": This means "technology" or "software" which has been made + available without restrictions upon its further dissemination. N.B. + Copyright restrictions do not remove "technology" or "software" from being + "in the public domain".

    + +

    So, both mod_ssl and OpenSSL are in the public domain for the purposes + of the Wassenaar Agreement and its List of Dual Use Goods and + Technologies And Munitions List.

    + +

    So, mod_ssl and OpenSSL are not affected by the Wassenaar Agreement.

    +
    +
    + + +
    About Installation + + +
    When I access my website the first time via HTTPS I get a core dump? +

    There can be a lot of reasons why a core dump can occur, of course. + Ranging from buggy third-party modules, over buggy vendor libraries up to + a buggy mod_ssl version. But the above situation is often caused by old or + broken vendor DBM libraries. To solve it either build mod_ssl with the + built-in SDBM library (specify --enable-rule=SSL_SDBM at the + APACI command line) or switch from SSLSessionCache dbm: to the + newer SSLSessionCache shm:'' variant (after you have rebuilt + Apache with MM, of course).

    +
    + +
    When I startup Apache I get permission errors related to SSLMutex? +

    When you receive entries like ``mod_ssl: Child could not open + SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows) + [...] System: Permission denied (errno: 13)'' this is usually + caused by to restrictive permissions on the parent directories. + Make sure that all parent directories (here /opt, + /opt/apache and /opt/apache/logs) have the x-bit + set at least for the UID under which Apache's children are running (see + the User directive of Apache).

    +
    + +
    When I use the MM library and the shared memory cache each process grows +1.5MB according to `top' although I specified 512000 as the cache size? +

    The additional 1MB are caused by the global shared memory pool Apache + allocates for all modules and which is not used by mod_ssl for + various reasons. So the actually allocated shared memory is always + 1MB more than what you specify on SSLSessionCache. + But don't be confused by the display of `top': although is + indicates that each process grow, this is not reality, of + course. Instead the additional memory consumption is shared by + all processes, i.e. the 1.5MB are allocated only once per Apache + instance and not once per Apache server process.

    +
    + +
    When I fire up the server, mod_ssl stops with the error +"Failed to generate temporary 512 bit RSA private key", why? +

    Cryptographic software needs a source of unpredictable data + to work correctly. Many open source operating systems provide + a "randomness device" that serves this purpose (usually named + /dev/random). On other systems, applications have to + seed the OpenSSL Pseudo Random Number Generator (PRNG) manually with + appropriate data before generating keys or performing public key + encryption. As of version 0.9.5, the OpenSSL functions that need + randomness report an error if the PRNG has not been seeded with + at least 128 bits of randomness. So mod_ssl has to provide enough + entropy to the PRNG to work correctly. For this one has to use the + SSLRandomSeed directives.

    +
    +
    + + +
    About Configuration + + +
    Is it possible to provide HTTP and HTTPS with a single server? +

    Yes, HTTP and HTTPS use different server ports, so there is no direct + conflict between them. Either run two separate server instances (one binds + to port 80, the other to port 443) or even use Apache's elegant virtual + hosting facility where you can easily create two virtual servers which + Apache dispatches: one responding to port 80 and speaking HTTP and one + responding to port 443 speaking HTTPS.

    +
    + +
    I know that HTTP is on port 80, but where is HTTPS? +

    You can run HTTPS on any port, but the standards specify port 443, which + is where any HTTPS compliant browser will look by default. You can force + your browser to look on a different port by specifying it in the URL like + this (for port 666): https://secure.server.dom:666/

    +
    + +
    How can I speak HTTPS manually for testing purposes? +

    While you usually just use

    + + $ telnet localhost 80
    + GET / HTTP/1.0
    + + +

    for simple testing the HTTP protocol of Apache, it's not so easy for + HTTPS because of the SSL protocol between TCP and HTTP. But with the + help of OpenSSL's s_client command you can do a similar + check even for HTTPS:

    + + $ openssl s_client -connect localhost:443 -state -debug
    + GET / HTTP/1.0
    + +

    Before the actual HTTP response you receive detailed information about the + SSL handshake. For a more general command line client which directly + understands both the HTTP and HTTPS scheme, can perform GET and POST + methods, can use a proxy, supports byte ranges, etc. you should have a + look at nifty cURL + tool. With it you can directly check if your Apache is running fine on + Port 80 and 443 as following:

    + + $ curl http://localhost/
    + $ curl https://localhost/
    +
    + +
    Why does the connection hang when I connect to my SSL-aware Apache server? +

    Because you connected with HTTP to the HTTPS port, i.e. you used an URL of + the form ``http://'' instead of ``https://''. + This also happens the other way round when you connect via HTTPS to a HTTP + port, i.e. when you try to use ``https://'' on a server that + doesn't support SSL (on this port). Make sure you are connecting to a + virtual server that supports SSL, which is probably the IP associated with + your hostname, not localhost (127.0.0.1).

    +
    + +
    Why do I get ``Connection Refused'' messages when trying to access my freshly +installed Apache+mod_ssl server via HTTPS? +

    There can be various reasons. Some of the common mistakes is that people + start Apache with just apachectl start (or + httpd) instead of apachectl startssl (or + httpd -DSSL. Or you're configuration is not correct. At + least make sure that your Listen + directives match your VirtualHost + directives. And if all fails, please do yourself a favor and start over with the + default configuration mod_ssl provides you.

    +
    + +
    In my CGI programs and SSI scripts the various documented +<code>SSL_XXX</code> variables do not exist. Why? +

    Just make sure you have ``SSLOptions +StdEnvVars'' + enabled for the context of your CGI/SSI requests.

    +
    + +
    +How can I use relative hyperlinks to switch between HTTP and +HTTPS? +

    Usually you have to use fully-qualified hyperlinks because + you have to change the URL scheme. But with the help of some URL + manipulations through mod_rewrite you can achieve the same effect while + you still can use relative URLs:

    + + RewriteEngine on
    + RewriteRule ^/(.*):SSL$ https://%{SERVER_NAME}/$1 [R,L]
    + RewriteRule ^/(.*):NOSSL$ http://%{SERVER_NAME}/$1 [R,L] +
    + +

    This rewrite ruleset lets you use hyperlinks of the form + <a href="document.html:SSL">

    +
    +
    + + +
    About Certificates + + +
    What are RSA Private Keys, CSRs and Certificates? +

    The RSA private key file is a digital file that you can use to decrypt + messages sent to you. It has a public component which you distribute (via + your Certificate file) which allows people to encrypt those messages to + you. A Certificate Signing Request (CSR) is a digital file which contains + your public key and your name. You send the CSR to a Certifying Authority + (CA) to be converted into a real Certificate. A Certificate contains your + RSA public key, your name, the name of the CA, and is digitally signed by + your CA. Browsers that know the CA can verify the signature on that + Certificate, thereby obtaining your RSA public key. That enables them to + send messages which only you can decrypt. + See the Introduction chapter for a general + description of the SSL protocol.

    +
    + +
    Seems like there is a difference on startup between the original Apache and an SSL-aware Apache? +

    Yes, in general, starting Apache with a built-in mod_ssl is just like + starting an unencumbered Apache, except for the fact that when you have a + pass phrase on your SSL private key file. Then a startup dialog pops up + asking you to enter the pass phrase.

    + +

    To type in the pass phrase manually when starting the server can be + problematic, for instance when starting the server from the system boot + scripts. As an alternative to this situation you can follow the steps + below under ``How can I get rid of the pass-phrase dialog at Apache + startup time?''.

    +
    + +
    Ok, I've got my server installed and want to create a real SSL +server Certificate for it. How do I do it? +

    Here is a step-by-step description:

    + +
      +
    1. Make sure OpenSSL is really installed and in your PATH. + But some commands even work ok when you just run the + ``openssl'' program from within the OpenSSL source tree as + ``./apps/openssl''.
      + +
      +
    2. +
    3. Create a RSA private key for your Apache server + (will be Triple-DES encrypted and PEM formatted):
      +
      + $ openssl genrsa -des3 -out server.key 1024
      +
      + Please backup this server.key file and remember the + pass-phrase you had to enter at a secure location. + You can see the details of this RSA private key via the command:
      + +
      + $ openssl rsa -noout -text -in server.key
      +
      + And you could create a decrypted PEM version (not recommended) + of this RSA private key via:
      +
      + $ openssl rsa -in server.key -out server.key.unsecure
      +
      + +
    4. +
    5. Create a Certificate Signing Request (CSR) with the server RSA private + key (output will be PEM formatted):
      +
      + $ openssl req -new -key server.key -out server.csr
      +
      + Make sure you enter the FQDN ("Fully Qualified Domain Name") of the + server when OpenSSL prompts you for the "CommonName", i.e. when you + generate a CSR for a website which will be later accessed via + https://www.foo.dom/, enter "www.foo.dom" here. + You can see the details of this CSR via the command
      + +
      + $ openssl req -noout -text -in server.csr
      +
      +
    6. +
    7. You now have to send this Certificate Signing Request (CSR) to + a Certifying Authority (CA) for signing. The result is then a real + Certificate which can be used for Apache. Here you have two options: + First you can let the CSR sign by a commercial CA like Verisign or + Thawte. Then you usually have to post the CSR into a web form, pay for + the signing and await the signed Certificate you then can store into a + server.crt file. For more information about commercial CAs have a look + at the following locations:
      +
      +
        +
      1. Verisign
        + + + http://digitalid.verisign.com/server/apacheNotice.htm + +
      2. +
      3. Thawte Consulting
        + + http://www.thawte.com/certs/server/request.html + +
      4. + +
      5. CertiSign Certificadora Digital Ltda.
        + + http://www.certisign.com.br + +
      6. +
      7. IKS GmbH
        + + + http://www.iks-jena.de/produkte/ca/ + +
      8. +
      9. Uptime Commerce Ltd.
        + + http://www.uptimecommerce.com + +
      10. +
      11. BelSign NV/SA
        + + + http://www.belsign.be + +
      12. +
      + + Second you can use your own CA and now have to sign the CSR yourself by + this CA. Read the next answer in this FAQ on how to sign a CSR with + your CA yourself. + You can see the details of the received Certificate via the command:
      +
      + $ openssl x509 -noout -text -in server.crt
      + +
    8. +
    9. Now you have two files: server.key and + server.crt. These now can be used as following inside your + Apache's httpd.conf file: +
      +       SSLCertificateFile    /path/to/this/server.crt
      +       SSLCertificateKeyFile /path/to/this/server.key
      +       
      + The server.csr file is no longer needed. +
    10. + +
    +
    + +
    How can I create and use my own Certificate Authority (CA)? +

    The short answer is to use the CA.sh or CA.pl + + script provided by OpenSSL. The long and manual answer is this:

    + +
      +
    1. Create a RSA private key for your CA + (will be Triple-DES encrypted and PEM formatted):
      +
      + $ openssl genrsa -des3 -out ca.key 1024
      +
      + Please backup this ca.key file and remember the + pass-phrase you currently entered at a secure location. + You can see the details of this RSA private key via the command
      + +
      + $ openssl rsa -noout -text -in ca.key
      +
      + And you can create a decrypted PEM version (not recommended) of this + private key via:
      +
      + $ openssl rsa -in ca.key -out ca.key.unsecure
      +
      + +
    2. +
    3. Create a self-signed CA Certificate (X509 structure) + with the RSA key of the CA (output will be PEM formatted):
      +
      + $ openssl req -new -x509 -days 365 -key ca.key -out ca.crt
      +
      + You can see the details of this Certificate via the command:
      +
      + + $ openssl x509 -noout -text -in ca.crt
      +
      +
    4. +
    5. Prepare a script for signing which is needed because + the ``openssl ca'' command has some strange requirements + and the default OpenSSL config doesn't allow one easily to use + ``openssl ca'' directly. So a script named + sign.sh is distributed with the mod_ssl distribution + (subdir pkg.contrib/). Use this script for signing. +
    6. + +
    7. Now you can use this CA to sign server CSR's in order to create real + SSL Certificates for use inside an Apache webserver (assuming + you already have a server.csr at hand):
      +
      + $ ./sign.sh server.csr
      +
      + This signs the server CSR and results in a server.crt file.
      + +
    8. +
    + +
    + +
    How can I change the pass-phrase on my private key file? +

    You simply have to read it with the old pass-phrase and write it again + by specifying the new pass-phrase. You can accomplish this with the following + commands:

    + + +

    $ openssl rsa -des3 -in server.key -out server.key.new
    + $ mv server.key.new server.key

    + +

    Here you're asked two times for a PEM pass-phrase. At the first + prompt enter the old pass-phrase and at the second prompt + enter the new pass-phrase.

    +
    + +
    How can I get rid of the pass-phrase dialog at Apache startup time? +

    The reason why this dialog pops up at startup and every re-start + is that the RSA private key inside your server.key file is stored in + encrypted format for security reasons. The pass-phrase is needed to be + able to read and parse this file. When you can be sure that your server is + secure enough you perform two steps:

    + +
      +
    1. Remove the encryption from the RSA private key (while + preserving the original file):
      +
      + $ cp server.key server.key.org
      + $ openssl rsa -in server.key.org -out server.key
      + +
      +
    2. +
    3. Make sure the server.key file is now only readable by root:
      +
      + $ chmod 400 server.key
      +
      +
    4. +
    + +

    Now server.key will contain an unencrypted copy of the key. + If you point your server at this file it will not prompt you for a + pass-phrase. HOWEVER, if anyone gets this key they will be able to + impersonate you on the net. PLEASE make sure that the permissions on that + file are really such that only root or the web server user can read it + (preferably get your web server to start as root but run as another + server, and have the key readable only by root).

    + +

    As an alternative approach you can use the ``SSLPassPhraseDialog + exec:/path/to/program'' facility. But keep in mind that this is + neither more nor less secure, of course.

    +
    + +
    How do I verify that a private key matches its Certificate? +

    The private key contains a series of numbers. Two of those numbers form + the "public key", the others are part of your "private key". The "public + key" bits are also embedded in your Certificate (we get them from your + CSR). To check that the public key in your cert matches the public + portion of your private key, you need to view the cert and the key and + compare the numbers. To view the Certificate and the key run the + commands:

    + +

    $ openssl x509 -noout -text -in server.crt
    + $ openssl rsa -noout -text -in server.key

    + +

    The `modulus' and the `public exponent' portions in the key and the + Certificate must match. But since the public exponent is usually 65537 + and it's bothering comparing long modulus you can use the following + approach:

    + + +

    $ openssl x509 -noout -modulus -in server.crt | openssl md5
    + $ openssl rsa -noout -modulus -in server.key | openssl md5

    + +

    And then compare these really shorter numbers. With overwhelming + probability they will differ if the keys are different. BTW, if I want to + check to which key or certificate a particular CSR belongs you can compute

    + +

    $ openssl req -noout -modulus -in server.csr | openssl md5

    +
    + +
    What does it mean when my connections fail with an "alert bad certificate" +error? +

    Usually when you see errors like OpenSSL: error:14094412: SSL + routines:SSL3_READ_BYTES:sslv3 alert bad certificate in the SSL + logfile, this means that the browser was unable to handle the server + certificate/private-key which perhaps contain a RSA-key not equal to 1024 + bits. For instance Netscape Navigator 3.x is one of those browsers.

    +
    + +
    Why does my 2048-bit private key not work? +

    The private key sizes for SSL must be either 512 or 1024 for compatibility + with certain web browsers. A keysize of 1024 bits is recommended because + keys larger than 1024 bits are incompatible with some versions of Netscape + Navigator and Microsoft Internet Explorer, and with other browsers that + use RSA's BSAFE cryptography toolkit.

    +
    + + + +
    How can I convert a certificate from PEM to DER format? +

    The default certificate format for SSLeay/OpenSSL is PEM, which actually + is Base64 encoded DER with header and footer lines. For some applications + (e.g. Microsoft Internet Explorer) you need the certificate in plain DER + format. You can convert a PEM file cert.pem into the + corresponding DER file cert.der with the following command: + $ openssl x509 -in cert.pem -out cert.der -outform DER

    +
    + +
    I try to install a Verisign certificate. Why can't I find neither the +<code>getca</code> nor <code>getverisign</code> programs Verisign mentions? +

    This is because Verisign has never provided specific instructions + for Apache+mod_ssl. Rather they tell you what you should do + if you were using C2Net's Stronghold (a commercial Apache + based server with SSL support). The only thing you have to do + is to save the certificate into a file and give the name of + that file to the SSLCertificateFile directive. + Remember that you need to give the key file in as well (see + SSLCertificateKeyFile directive). For a better + CA-related overview on SSL certificate fiddling you can look at Thawte's mod_ssl instructions.

    +
    + +
    Can I use the Server Gated Cryptography (SGC) facility (aka Verisign Global +ID) also with mod_ssl? +

    Yes, mod_ssl since version 2.1 supports the SGC facility. You don't have + to configure anything special for this, just use a Global ID as your + server certificate. The step up of the clients are then + automatically handled by mod_ssl under run-time. For details please read + the README.GlobalID document in the mod_ssl distribution.

    +
    + +
    After I have installed my new Verisign Global ID server certificate, the +browsers complain that they cannot verify the server certificate? +

    That is because Verisign uses an intermediate CA certificate between + the root CA certificate (which is installed in the browsers) and + the server certificate (which you installed in the server). You + should have received this additional CA certificate from Verisign. + If not, complain to them. Then configure this certificate with the + SSLCertificateChainFile directive in the server. This + makes sure the intermediate CA certificate is send to the browser + and this way fills the gap in the certificate chain.

    +
    +
    + + +
    About SSL Protocol + + +
    Why do I get lots of random SSL protocol errors under heavy server load? +

    There can be a number of reasons for this, but the main one + is problems with the SSL session Cache specified by the + SSLSessionCache directive. The DBM session + cache is most likely the source of the problem, so trying the SHM session cache or + no cache at all may help.

    +
    + +
    Why has my webserver a higher load now that I run SSL there? +

    Because SSL uses strong cryptographic encryption and this needs a lot of + number crunching. And because when you request a webpage via HTTPS even + the images are transferred encrypted. So, when you have a lot of HTTPS + traffic the load increases.

    +
    + +
    Often HTTPS connections to my server require up to 30 seconds for establishing +the connection, although sometimes it works faster? +

    Usually this is caused by using a /dev/random device for + SSLRandomSeed which is blocking in read(2) calls if not + enough entropy is available. Read more about this problem in the reference + chapter under SSLRandomSeed.

    +
    + +
    What SSL Ciphers are supported by mod_ssl? +

    Usually just all SSL ciphers which are supported by the + version of OpenSSL in use (can depend on the way you built + OpenSSL). Typically this at least includes the following:

    + +
      +
    1. RC4 with MD5
    2. + +
    3. RC4 with MD5 (export version restricted to 40-bit key)
    4. +
    5. RC2 with MD5
    6. +
    7. RC2 with MD5 (export version restricted to 40-bit key)
    8. +
    9. IDEA with MD5
    10. +
    11. DES with MD5
    12. +
    13. Triple-DES with MD5
    14. + +
    + +

    To determine the actual list of supported ciphers you can + run the following command:

    + $ openssl ciphers -v +
    + +
    I want to use Anonymous Diffie-Hellman (ADH) ciphers, but I always get ``no +shared cipher'' errors? +

    In order to use Anonymous Diffie-Hellman (ADH) ciphers, it is not enough + to just put ``ADH'' into your SSLCipherSuite. + Additionally you have to build OpenSSL with + ``-DSSL_ALLOW_ADH''. Because per default OpenSSL does not + allow ADH ciphers for security reasons. So if you are actually enabling + these ciphers make sure you are informed about the side-effects.

    +
    + +
    I always just get a 'no shared ciphers' error if +I try to connect to my freshly installed server? +

    Either you have messed up your SSLCipherSuite + directive (compare it with the pre-configured example in + httpd.conf-dist) or you have chosen the DSA/DH + algorithms instead of RSA when you generated your private key + and ignored or overlooked the warnings. If you have chosen + DSA/DH, then your server no longer speaks RSA-based SSL ciphers + (at least not until you also configure an additional RSA-based + certificate/key pair). But current browsers like NS or IE only speak + RSA ciphers. The result is the "no shared ciphers" error. To fix + this, regenerate your server certificate/key pair and this time + choose the RSA algorithm.

    +
    + +
    Why can't I use SSL with name-based/non-IP-based virtual hosts? +

    The reason is very technical. Actually it's some sort of a chicken and + egg problem: The SSL protocol layer stays below the HTTP protocol layer + and encapsulates HTTP. When an SSL connection (HTTPS) is established + Apache/mod_ssl has to negotiate the SSL protocol parameters with the + client. For this mod_ssl has to consult the configuration of the virtual + server (for instance it has to look for the cipher suite, the server + certificate, etc.). But in order to dispatch to the correct virtual server + Apache has to know the Host HTTP header field. For this the + HTTP request header has to be read. This cannot be done before the SSL + handshake is finished. But the information is already needed at the SSL + handshake phase. Bingo!

    +
    + +
    Why is it not possible to use Name-Based +Virtual Hosting to identify different SSL virtual hosts? +

    Name-Based Virtual Hosting is a very popular method of identifying + different virtual hosts. It allows you to use the same IP address and + the same port number for many different sites. When people move on to + SSL, it seems natural to assume that the same method can be used to have + lots of different SSL virtual hosts on the same server.

    + +

    It comes as rather a shock to learn that it is impossible.

    + +

    The reason is that the SSL protocol is a separate layer which + encapsulates the HTTP protocol. So the problem is that the SSL session + is a separate transaction that takes place before the HTTP session even + starts. Therefore all the server receives is an SSL request on IP + address X and port Y (usually 443). Since the SSL request does not + contain any Host: field, the server has no way to decide which SSL + virtual host to use. Usually, it will just use the first one it finds + that matches the port and IP address.

    + +

    You can, of course, use Name-Based Virtual Hosting to identify many + non-SSL virtual hosts (all on port 80, for example) and then you can + have no more than 1 SSL virtual host (on port 443). But if you do this, + you must make sure to put the non-SSL port number on the NameVirtualHost + directive, e.g.

    + + + NameVirtualHost 192.168.1.1:80 + + +

    Other workaround solutions are:

    + +

    Use separate IP addresses for different SSL hosts. + Use different port numbers for different SSL hosts.

    +
    + +
    When I use Basic Authentication over HTTPS the lock icon in Netscape browsers +still shows the unlocked state when the dialog pops up. Does this mean the +username/password is still transmitted unencrypted? +

    No, the username/password is already transmitted encrypted. The icon in + Netscape browsers is just not really synchronized with the SSL/TLS layer + (it toggles to the locked state when the first part of the actual webpage + data is transferred which is not quite correct) and this way confuses + people. The Basic Authentication facility is part of the HTTP layer and + this layer is above the SSL/TLS layer in HTTPS. And before any HTTP data + communication takes place in HTTPS the SSL/TLS layer has already done the + handshake phase and switched to encrypted communication. So, don't get + confused by this icon.

    +
    + +
    When I connect via HTTPS to an Apache+mod_ssl+OpenSSL server with Microsoft Internet +Explorer (MSIE) I get various I/O errors. What is the reason? +

    The first reason is that the SSL implementation in some MSIE versions has + some subtle bugs related to the HTTP keep-alive facility and the SSL close + notify alerts on socket connection close. Additionally the interaction + between SSL and HTTP/1.1 features are problematic with some MSIE versions, + too. You've to work-around these problems by forcing + Apache+mod_ssl+OpenSSL to not use HTTP/1.1, keep-alive connections or + sending the SSL close notify messages to MSIE clients. This can be done by + using the following directive in your SSL-aware virtual host section:

    + + SetEnvIf User-Agent ".*MSIE.*" \
    + nokeepalive ssl-unclean-shutdown \
    + downgrade-1.0 force-response-1.0 +
    +

    Additionally it is known some MSIE versions have also problems + with particular ciphers. Unfortunately one cannot workaround these + bugs only for those MSIE particular clients, because the ciphers + are already used in the SSL handshake phase. So a MSIE-specific + SetEnvIf doesn't work + to solve these problems. Instead one has to do more drastic + adjustments to the global parameters. But before you decide to do + this, make sure your clients really have problems. If not, do not + do this, because it affects all(!) your clients, i.e., also your + non-MSIE clients.

    + +

    The next problem is that 56bit export versions of MSIE 5.x browsers have a + broken SSLv3 implementation which badly interacts with OpenSSL versions + greater than 0.9.4. You can either accept this and force your clients to + upgrade their browsers, or you downgrade to OpenSSL 0.9.4 (hmmm), or you + can decide to workaround it by accepting the drawback that your workaround + will horribly affect also other browsers:

    + SSLProtocol all -SSLv3 +

    This completely disables the SSLv3 protocol and lets those browsers work. + But usually this is an even less acceptable workaround. A more reasonable + workaround is to address the problem more closely and disable only the + ciphers which cause trouble.

    +

    SSLCipherSuite + ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +

    + +

    This also lets the broken MSIE versions work, but only removes the + newer 56bit TLS ciphers.

    + +

    Another problem with MSIE 5.x clients is that they refuse to connect to + URLs of the form https://12.34.56.78/ (IP-addresses are used + instead of the hostname), if the server is using the Server Gated + Cryptography (SGC) facility. This can only be avoided by using the fully + qualified domain name (FQDN) of the website in hyperlinks instead, because + MSIE 5.x has an error in the way it handles the SGC negotiation.

    + +

    And finally there are versions of MSIE which seem to require that + an SSL session can be reused (a totally non standard-conforming + behaviour, of course). Connection with those MSIE versions only work + if a SSL session cache is used. So, as a work-around, make sure you + are using a session cache (see SSLSessionCache directive).

    +
    + +
    When I connect via HTTPS to an Apache+mod_ssl server with Netscape Navigator I +get I/O errors and the message "Netscape has encountered bad data from the +server" What's the reason? +

    + The problem usually is that you had created a new server certificate with + the same DN, but you had told your browser to accept forever the old + server certificate. Once you clear the entry in your browser for the old + certificate, everything usually will work fine. Netscape's SSL + implementation is correct, so when you encounter I/O errors with Netscape + Navigator it is most of the time caused by the configured certificates.

    +
    +
    + + +
    About Support + + +
    What information resources are available in case of mod_ssl problems? +

    The following information resources are available. + In case of problems you should search here first.

    + +
    +
    Answers in the User Manual's F.A.Q. List (this)
    +
    + http://httpd.apache.org/docs-2.1/ssl/ssl_faq.html
    + First look inside the F.A.Q. (this text), perhaps your problem is such + popular that it was already answered a lot of times in the past. +
    +
    Postings from the modssl-users Support Mailing List + http://www.modssl.org/support/
    +
    Second search for your problem in one of the existing archives of the + modssl-users mailing list. Perhaps your problem popped up at least once for + another user, too. +
    +
    +
    + +
    What support contacts are available in case of mod_ssl problems? +

    The following lists all support possibilities for mod_ssl, in order of + preference, i.e. start in this order and do not pick the support possibility + you just like most, please.

    + +
      +
    1. Write a Problem Report into the Bug Database
      + + http://www.modssl.org/support/bugdb/
      + This is the preferred way of submitting your problem report, because this + way it gets filed into the bug database (it cannot be lost) and + send to the modssl-users mailing list (others see the current problems and + learn from answers). +
    2. + +
    3. Write a Problem Report to the modssl-users Support Mailing List
      + + modssl-users@modssl.org
      + This is the second way of submitting your problem report. You have to + subscribe to the list first, but then you can easily discuss your problem + with both the author and the whole mod_ssl user community. +
    4. +
    +
    + +
    What information and details should I + provide when writing a bug report? +

    You have to at least always provide the following information:

    + +
    +
    Apache and OpenSSL version information
    +
    The Apache version can be determined + by running httpd -v. The OpenSSL version can be + determined by running openssl version. Alternatively when + you have Lynx installed you can run the command lynx -mime_header + http://localhost/ | grep Server to determine all information in a + single step. +
    + +
    The details on how you built and installed Apache+mod_ssl+OpenSSL
    +
    For this you can provide a logfile of your terminal session which shows + the configuration and install steps. Alternatively you can at least + provide the configure command line you used. +
    + +
    In case of core dumps please include a Backtrace
    +
    In case your Apache+mod_ssl+OpenSSL should really dump core please attach + a stack-frame ``backtrace'' (see the next question on how to get it). + Without this information the reason for your core dump cannot be found. + So you have to provide the backtrace, please. +
    + +
    A detailed description of your problem
    +
    Don't laugh, I'm totally serious. I already got a lot of problem reports + where the people not really said what's the actual problem is. So, in your + own interest (you want the problem be solved, don't you?) include as much + details as possible, please. But start with the essentials first, of + course. +
    +
    +
    + +
    I got a core dump, can you help me? +

    In general no, at least not unless you provide more details about the code + location where Apache dumped core. What is usually always required in + order to help you is a backtrace (see next question). Without this + information it is mostly impossible to find the problem and help you in + fixing it.

    +
    + +
    Ok, I got a core dump but how do I get a backtrace to find out the reason for it? +

    Follow the following steps:

    +
      +
    1. Make sure you have debugging symbols available in at least + Apache. On platforms where you use GCC/GDB you have to build + Apache+mod_ssl with ``OPTIM="-g -ggdb3"'' to achieve this. On + other platforms at least ``OPTIM="-g"'' is needed. +
    2. + +
    3. Startup the server and try to produce the core-dump. For this you perhaps + want to use a directive like ``CoreDumpDirectory /tmp'' to + make sure that the core-dump file can be written. You then should get a + /tmp/core or /tmp/httpd.core file. When you + don't get this, try to run your server under an UID != 0 (root), because + most "current" kernels do not allow a process to dump core after it has + done a setuid() (unless it does an exec()) for + security reasons (there can be privileged information left over in + memory). Additionally you can run /path/to/httpd -X + manually to force Apache to not fork. +
    4. + +
    5. Analyze the core-dump. For this run gdb /path/to/httpd + /tmp/httpd.core or a similar command has to run. In GDB you then + just have to enter the bt command and, voila, you get the + backtrace. For other debuggers consult your local debugger manual. Send + this backtrace to the author. +
    6. +
    +
    +
    +
    diff --git a/trunk/docs/manual/ssl/ssl_faq.xml.meta b/trunk/docs/manual/ssl/ssl_faq.xml.meta new file mode 100644 index 0000000000..400d91e74a --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_faq.xml.meta @@ -0,0 +1,11 @@ + + + + ssl_faq + /ssl/ + .. + + + en + + diff --git a/trunk/docs/manual/ssl/ssl_howto.html b/trunk/docs/manual/ssl/ssl_howto.html new file mode 100644 index 0000000000..ca42f094cf --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_howto.html @@ -0,0 +1,3 @@ +URI: ssl_howto.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 diff --git a/trunk/docs/manual/ssl/ssl_howto.html.en b/trunk/docs/manual/ssl/ssl_howto.html.en new file mode 100644 index 0000000000..15fd8c804e --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_howto.html.en @@ -0,0 +1,282 @@ + + + +SSL/TLS Strong Encryption: How-To - Apache HTTP Server + + + + + +
    <-
    +

    SSL/TLS Strong Encryption: How-To

    +
    +

    Available Languages:  en 

    +
    + +
    +

    The solution of this problem is trivial +and is left as an exercise for the reader.

    + +

    -- Standard textbook cookie

    +
    + +

    How to solve particular security constraints for an SSL-aware +webserver is not always obvious because of the coherences between SSL, +HTTP and Apache's way of processing requests. This chapter gives +instructions on how to solve such typical situations. Treat it as a first +step to find out the final solution, but always try to understand the +stuff before you use it. Nothing is worse than using a security solution +without knowing its restrictions and coherences.

    +
    + +
    top
    +
    +

    Cipher Suites and Enforced Strong Security

    + + + +

    How can I create a real SSLv2-only server?

    + +

    The following creates an SSL server which speaks only the SSLv2 protocol and + its ciphers.

    + +

    httpd.conf

    + SSLProtocol -all +SSLv2
    + SSLCipherSuite SSLv2:+HIGH:+MEDIUM:+LOW:+EXP
    +

    + + +

    How can I create an SSL server which accepts strong encryption +only?

    + +

    The following enables only the seven strongest ciphers:

    +

    httpd.conf

    + SSLProtocol all
    + SSLCipherSuite HIGH:MEDIUM
    +

    + + +

    How can I create an SSL server which accepts strong encryption +only, but allows export browsers to upgrade to stronger encryption?

    + +

    This facility is called Server Gated Cryptography (SGC) and details + you can find in the README.GlobalID document in the + mod_ssl distribution. In short: The server has a Global ID server + certificate, signed by a special CA certificate from Verisign which + enables strong encryption in export browsers. This works as following: + The browser connects with an export cipher, the server sends its Global + ID certificate, the browser verifies it and subsequently upgrades the + cipher suite before any HTTP communication takes place. The question + now is: How can we allow this upgrade, but enforce strong encryption. + Or in other words: Browser either have to initially connect with + strong encryption or have to upgrade to strong encryption, but are + not allowed to keep the export ciphers. The following does the trick:

    +

    httpd.conf

    + # allow all ciphers for the initial handshake,
    + # so export browsers can upgrade via SGC facility
    + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +
    + <Directory /usr/local/apache2/htdocs>
    + # but finally deny all browsers which haven't upgraded
    + SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
    + </Directory> +

    + + +

    How can I create an SSL server which accepts all types of ciphers +in general, but requires a strong ciphers for access to a particular +URL?

    + +

    Obviously you cannot just use a server-wide SSLCipherSuite which restricts the + ciphers to the strong variants. But mod_ssl allows you to reconfigure + the cipher suite in per-directory context and automatically forces + a renegotiation of the SSL parameters to meet the new configuration. + So, the solution is:

    +

    + # be liberal in general
    + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +
    + <Location /strong/area>
    + # but https://hostname/strong/area/ and below
    + # requires strong ciphers
    + SSLCipherSuite HIGH:MEDIUM
    + </Location> +

    + +
    top
    +
    +

    Client Authentication and Access Control

    + + + +

    How can I authenticate clients based on certificates when I know +all my clients?

    + +

    When you know your user community (i.e. a closed user group + situation), as it's the case for instance in an Intranet, you can + use plain certificate authentication. All you have to do is to + create client certificates signed by your own CA certificate + ca.crt and then verify the clients against this + certificate.

    +

    httpd.conf

    + # require a client certificate which has to be directly
    + # signed by our CA certificate in ca.crt
    + SSLVerifyClient require
    + SSLVerifyDepth 1
    + SSLCACertificateFile conf/ssl.crt/ca.crt +

    + + +

    How can I authenticate my clients for a particular URL based on +certificates but still allow arbitrary clients to access the remaining +parts of the server?

    + +

    For this we again use the per-directory reconfiguration feature + of mod_ssl:

    + +

    httpd.conf

    + SSLVerifyClient none
    + SSLCACertificateFile conf/ssl.crt/ca.crt
    +
    + <Location /secure/area>
    + SSLVerifyClient require
    + SSLVerifyDepth 1
    + </Location>
    +

    + + +

    How can I authenticate only particular clients for a some URLs based +on certificates but still allow arbitrary clients to access the remaining +parts of the server?

    + +

    The key is to check for various ingredients of the client certificate. + Usually this means to check the whole or part of the Distinguished + Name (DN) of the Subject. For this two methods exists: The mod_auth_basic based variant and the SSLRequire variant. The first method is + good when the clients are of totally different type, i.e. when their + DNs have no common fields (usually the organisation, etc.). In this + case you've to establish a password database containing all + clients. The second method is better when your clients are all part of + a common hierarchy which is encoded into the DN. Then you can match + them more easily.

    + +

    The first method:

    +

    httpd.conf

    +SSLVerifyClient      none
    +<Directory /usr/local/apache2/htdocs/secure/area>
    +
    +SSLVerifyClient      require
    +SSLVerifyDepth       5
    +SSLCACertificateFile conf/ssl.crt/ca.crt
    +SSLCACertificatePath conf/ssl.crt
    +SSLOptions           +FakeBasicAuth
    +SSLRequireSSL
    +AuthName             "Snake Oil Authentication"
    +AuthType             Basic
    +AuthBasicProvider    file
    +AuthUserFile         /usr/local/apache2/conf/httpd.passwd
    +require              valid-user
    +</Directory>
    + +

    httpd.passwd

    +/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA
    +/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA
    +/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA
    + +

    The second method:

    + +

    httpd.conf

    +SSLVerifyClient      none
    +<Directory /usr/local/apache2/htdocs/secure/area>
    +
    +  SSLVerifyClient      require
    +  SSLVerifyDepth       5
    +  SSLCACertificateFile conf/ssl.crt/ca.crt
    +  SSLCACertificatePath conf/ssl.crt
    +  SSLOptions           +FakeBasicAuth
    +  SSLRequireSSL
    +  SSLRequire       %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." \
    +               and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
    +</Directory>
    + + +

    How can I require HTTPS with strong ciphers and either basic +authentication or client certificates for access to a subarea on the +Intranet website for clients coming from the Internet but still allow +plain HTTP access for clients on the Intranet?

    + +

    Let us assume the Intranet can be distinguished through the IP + network 192.160.1.0/24 and the subarea on the Intranet website has + the URL /subarea. Then configure the following outside + your HTTPS virtual host (so it applies to both HTTPS and HTTP):

    + +

    httpd.conf

    +SSLCACertificateFile conf/ssl.crt/company-ca.crt
    +
    +<Directory /usr/local/apache2/htdocs>
    +#   Outside the subarea only Intranet access is granted
    +Order                deny,allow
    +Deny                 from all
    +Allow                from 192.168.1.0/24
    +</Directory>
    +
    +<Directory /usr/local/apache2/htdocs/subarea>
    +#   Inside the subarea any Intranet access is allowed
    +#   but from the Internet only HTTPS + Strong-Cipher + Password
    +#   or the alternative HTTPS + Strong-Cipher + Client-Certificate
    +
    +#   If HTTPS is used, make sure a strong cipher is used.
    +#   Additionally allow client certs as alternative to basic auth.
    +SSLVerifyClient      optional
    +SSLVerifyDepth       1
    +SSLOptions           +FakeBasicAuth +StrictRequire
    +SSLRequire           %{SSL_CIPHER_USEKEYSIZE} >= 128
    +
    +#   Force clients from the Internet to use HTTPS
    +RewriteEngine        on
    +RewriteCond          %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$
    +RewriteCond          %{HTTPS} !=on
    +RewriteRule          .* - [F]
    +
    +#   Allow Network Access and/or Basic Auth
    +Satisfy              any
    +
    +#   Network Access Control
    +Order                deny,allow
    +Deny                 from all
    +Allow                192.168.1.0/24
    +
    +#   HTTP Basic Authentication
    +AuthType             basic
    +AuthName             "Protected Intranet Area"
    +AuthBasicProvider    file
    +AuthUserFile         conf/protected.passwd
    +Require              valid-user
    +</Directory>
    + +
    +
    +

    Available Languages:  en 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/ssl_howto.xml b/trunk/docs/manual/ssl/ssl_howto.xml new file mode 100644 index 0000000000..8273e8f6da --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_howto.xml @@ -0,0 +1,291 @@ + + + + + + + + +SSL/TLS + + SSL/TLS Strong Encryption: How-To + + +
    +

    The solution of this problem is trivial +and is left as an exercise for the reader.

    + +

    -- Standard textbook cookie

    +
    + +

    How to solve particular security constraints for an SSL-aware +webserver is not always obvious because of the coherences between SSL, +HTTP and Apache's way of processing requests. This chapter gives +instructions on how to solve such typical situations. Treat it as a first +step to find out the final solution, but always try to understand the +stuff before you use it. Nothing is worse than using a security solution +without knowing its restrictions and coherences.

    +
    + +
    +Cipher Suites and Enforced Strong Security + + +
    +How can I create a real SSLv2-only server? +

    The following creates an SSL server which speaks only the SSLv2 protocol and + its ciphers.

    + + httpd.conf + SSLProtocol -all +SSLv2
    + SSLCipherSuite SSLv2:+HIGH:+MEDIUM:+LOW:+EXP
    +
    +
    + +
    +How can I create an SSL server which accepts strong encryption +only? +

    The following enables only the seven strongest ciphers:

    + httpd.conf + SSLProtocol all
    + SSLCipherSuite HIGH:MEDIUM
    +
    +
    + +
    +How can I create an SSL server which accepts strong encryption +only, but allows export browsers to upgrade to stronger encryption? +

    This facility is called Server Gated Cryptography (SGC) and details + you can find in the README.GlobalID document in the + mod_ssl distribution. In short: The server has a Global ID server + certificate, signed by a special CA certificate from Verisign which + enables strong encryption in export browsers. This works as following: + The browser connects with an export cipher, the server sends its Global + ID certificate, the browser verifies it and subsequently upgrades the + cipher suite before any HTTP communication takes place. The question + now is: How can we allow this upgrade, but enforce strong encryption. + Or in other words: Browser either have to initially connect with + strong encryption or have to upgrade to strong encryption, but are + not allowed to keep the export ciphers. The following does the trick:

    + httpd.conf + # allow all ciphers for the initial handshake,
    + # so export browsers can upgrade via SGC facility
    + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +
    + <Directory /usr/local/apache2/htdocs>
    + # but finally deny all browsers which haven't upgraded
    + SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
    + </Directory> +
    +
    + +
    +How can I create an SSL server which accepts all types of ciphers +in general, but requires a strong ciphers for access to a particular +URL? +

    Obviously you cannot just use a server-wide SSLCipherSuite which restricts the + ciphers to the strong variants. But mod_ssl allows you to reconfigure + the cipher suite in per-directory context and automatically forces + a renegotiation of the SSL parameters to meet the new configuration. + So, the solution is:

    + + # be liberal in general
    + SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    +
    + <Location /strong/area>
    + # but https://hostname/strong/area/ and below
    + # requires strong ciphers
    + SSLCipherSuite HIGH:MEDIUM
    + </Location> +
    +
    +
    + + +
    +Client Authentication and Access Control + + +
    +How can I authenticate clients based on certificates when I know +all my clients? +

    When you know your user community (i.e. a closed user group + situation), as it's the case for instance in an Intranet, you can + use plain certificate authentication. All you have to do is to + create client certificates signed by your own CA certificate + ca.crt and then verify the clients against this + certificate.

    + httpd.conf + # require a client certificate which has to be directly
    + # signed by our CA certificate in ca.crt
    + SSLVerifyClient require
    + SSLVerifyDepth 1
    + SSLCACertificateFile conf/ssl.crt/ca.crt +
    +
    + +
    +How can I authenticate my clients for a particular URL based on +certificates but still allow arbitrary clients to access the remaining +parts of the server? +

    For this we again use the per-directory reconfiguration feature + of mod_ssl:

    + + httpd.conf + SSLVerifyClient none
    + SSLCACertificateFile conf/ssl.crt/ca.crt
    +
    + <Location /secure/area>
    + SSLVerifyClient require
    + SSLVerifyDepth 1
    + </Location>
    +
    +
    + +
    +How can I authenticate only particular clients for a some URLs based +on certificates but still allow arbitrary clients to access the remaining +parts of the server? +

    The key is to check for various ingredients of the client certificate. + Usually this means to check the whole or part of the Distinguished + Name (DN) of the Subject. For this two methods exists: The mod_auth_basic based variant and the SSLRequire variant. The first method is + good when the clients are of totally different type, i.e. when their + DNs have no common fields (usually the organisation, etc.). In this + case you've to establish a password database containing all + clients. The second method is better when your clients are all part of + a common hierarchy which is encoded into the DN. Then you can match + them more easily.

    + +

    The first method:

    + httpd.conf
    +SSLVerifyClient      none
    +<Directory /usr/local/apache2/htdocs/secure/area>
    +
    +SSLVerifyClient      require
    +SSLVerifyDepth       5
    +SSLCACertificateFile conf/ssl.crt/ca.crt
    +SSLCACertificatePath conf/ssl.crt
    +SSLOptions           +FakeBasicAuth
    +SSLRequireSSL
    +AuthName             "Snake Oil Authentication"
    +AuthType             Basic
    +AuthBasicProvider    file
    +AuthUserFile         /usr/local/apache2/conf/httpd.passwd
    +require              valid-user
    +</Directory>
    +
    + + httpd.passwd
    +/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA
    +/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA
    +/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA
    +
    + +

    The second method:

    + + httpd.conf
    +SSLVerifyClient      none
    +<Directory /usr/local/apache2/htdocs/secure/area>
    +
    +  SSLVerifyClient      require
    +  SSLVerifyDepth       5
    +  SSLCACertificateFile conf/ssl.crt/ca.crt
    +  SSLCACertificatePath conf/ssl.crt
    +  SSLOptions           +FakeBasicAuth
    +  SSLRequireSSL
    +  SSLRequire       %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." \
    +               and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
    +</Directory>
    +
    +
    + +
    +How can I require HTTPS with strong ciphers and either basic +authentication or client certificates for access to a subarea on the +Intranet website for clients coming from the Internet but still allow +plain HTTP access for clients on the Intranet? +

    Let us assume the Intranet can be distinguished through the IP + network 192.160.1.0/24 and the subarea on the Intranet website has + the URL /subarea. Then configure the following outside + your HTTPS virtual host (so it applies to both HTTPS and HTTP):

    + + httpd.conf
    +SSLCACertificateFile conf/ssl.crt/company-ca.crt
    +
    +<Directory /usr/local/apache2/htdocs>
    +#   Outside the subarea only Intranet access is granted
    +Order                deny,allow
    +Deny                 from all
    +Allow                from 192.168.1.0/24
    +</Directory>
    +
    +<Directory /usr/local/apache2/htdocs/subarea>
    +#   Inside the subarea any Intranet access is allowed
    +#   but from the Internet only HTTPS + Strong-Cipher + Password
    +#   or the alternative HTTPS + Strong-Cipher + Client-Certificate
    +
    +#   If HTTPS is used, make sure a strong cipher is used.
    +#   Additionally allow client certs as alternative to basic auth.
    +SSLVerifyClient      optional
    +SSLVerifyDepth       1
    +SSLOptions           +FakeBasicAuth +StrictRequire
    +SSLRequire           %{SSL_CIPHER_USEKEYSIZE} >= 128
    +
    +#   Force clients from the Internet to use HTTPS
    +RewriteEngine        on
    +RewriteCond          %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$
    +RewriteCond          %{HTTPS} !=on
    +RewriteRule          .* - [F]
    +
    +#   Allow Network Access and/or Basic Auth
    +Satisfy              any
    +
    +#   Network Access Control
    +Order                deny,allow
    +Deny                 from all
    +Allow                192.168.1.0/24
    +
    +#   HTTP Basic Authentication
    +AuthType             basic
    +AuthName             "Protected Intranet Area"
    +AuthBasicProvider    file
    +AuthUserFile         conf/protected.passwd
    +Require              valid-user
    +</Directory>
    +
    +
    +
    + + +
    + + + diff --git a/trunk/docs/manual/ssl/ssl_howto.xml.meta b/trunk/docs/manual/ssl/ssl_howto.xml.meta new file mode 100644 index 0000000000..5e89167c91 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_howto.xml.meta @@ -0,0 +1,11 @@ + + + + ssl_howto + /ssl/ + .. + + + en + + diff --git a/trunk/docs/manual/ssl/ssl_intro.html b/trunk/docs/manual/ssl/ssl_intro.html new file mode 100644 index 0000000000..263c0f2177 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.html @@ -0,0 +1,7 @@ +URI: ssl_intro.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: ssl_intro.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP diff --git a/trunk/docs/manual/ssl/ssl_intro.html.en b/trunk/docs/manual/ssl/ssl_intro.html.en new file mode 100644 index 0000000000..243cf3d70d --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.html.en @@ -0,0 +1,641 @@ + + + +SSL/TLS Strong Encryption: An Introduction - Apache HTTP Server + + + + + +
    <-
    +

    SSL/TLS Strong Encryption: An Introduction

    +
    +

    Available Languages:  en  | + ja 

    +
    + +
    +

    The nice thing about standards is that there are so many to choose +from. And if you really don't like all the standards you just have to +wait another year until the one arises you are looking for.

    + +

    -- A. Tanenbaum, "Introduction to +Computer Networks"

    +
    + +

    As an introduction this chapter is aimed at readers who are familiar +with the Web, HTTP, and Apache, but are not security experts. It is not +intended to be a definitive guide to the SSL protocol, nor does it discuss +specific techniques for managing certificates in an organization, or the +important legal issues of patents and import and export restrictions. +Rather, it is intended to provide a common background to mod_ssl users by +pulling together various concepts, definitions, and examples as a starting +point for further exploration.

    + +

    The presented content is mainly derived, with permission by the author, +from the article Introducing +SSL and Certificates using SSLeay from Frederick J. Hirsch, of The +Open Group Research Institute, which was published in Web Security: A Matter of +Trust, World Wide Web Journal, Volume 2, Issue 3, Summer 1997. +Please send any positive feedback to Frederick Hirsch (the original +article author) and all negative feedback to Ralf S. Engelschall (the +mod_ssl author).

    +
    + +
    top
    +
    +

    Cryptographic Techniques

    + +

    Understanding SSL requires an understanding of cryptographic +algorithms, message digest functions (aka. one-way or hash functions), and +digital signatures. These techniques are the subject of entire books (see +for instance [AC96]) and provide the basis for privacy, +integrity, and authentication.

    + +

    Cryptographic Algorithms

    + +

    Suppose Alice wants to send a message to her bank to transfer some + money. Alice would like the message to be private, since it will + include information such as her account number and transfer amount. One + solution is to use a cryptographic algorithm, a technique that would + transform her message into an encrypted form, unreadable except by + those it is intended for. Once in this form, the message may only be + interpreted through the use of a secret key. Without the key the + message is useless: good cryptographic algorithms make it so difficult + for intruders to decode the original text that it isn't worth their + effort.

    + +

    There are two categories of cryptographic algorithms: conventional + and public key.

    + +
    +
    Conventional cryptography
    +
    also known as symmetric cryptography, requires the sender and + receiver to share a key: a secret piece of information that may be + used to encrypt or decrypt a message. If this key is secret, then + nobody other than the sender or receiver may read the message. If + Alice and the bank know a secret key, then they may send each other + private messages. The task of privately choosing a key before + communicating, however, can be problematic.
    + +
    Public key cryptography
    +
    also known as asymmetric cryptography, solves the key exchange + problem by defining an algorithm which uses two keys, each of which + may be used to encrypt a message. If one key is used to encrypt a + message then the other must be used to decrypt it. This makes it + possible to receive secure messages by simply publishing one key + (the public key) and keeping the other secret (the private key).
    +
    + +

    Anyone may encrypt a message using the public key, but only the + owner of the private key will be able to read it. In this way, Alice + may send private messages to the owner of a key-pair (the bank), by + encrypting it using their public key. Only the bank will be able to + decrypt it.

    + + +

    Message Digests

    + +

    Although Alice may encrypt her message to make it private, there + is still a concern that someone might modify her original message or + substitute it with a different one, in order to transfer the money + to themselves, for instance. One way of guaranteeing the integrity + of Alice's message is to create a concise summary of her message and + send this to the bank as well. Upon receipt of the message, the bank + creates its own summary and compares it with the one Alice sent. If + they agree then the message was received intact.

    + +

    A summary such as this is called a message digest, one-way +function or hash function. Message digests are used to create +short, fixed-length representations of longer, variable-length messages. +Digest algorithms are designed to produce unique digests for different +messages. Message digests are designed to make it too difficult to determine +the message from the digest, and also impossible to find two different +messages which create the same digest -- thus eliminating the possibility of +substituting one message for another while maintaining the same digest.

    +

    Another challenge that Alice faces is finding a way to send the digest to the +bank securely; when this is achieved, the integrity of the associated message +is assured. One way to do this is to include the digest in a digital +signature.

    + + +

    Digital Signatures

    +

    When Alice sends a message to the bank, the bank needs to ensure that the +message is really from her, so an intruder does not request a transaction +involving her account. A digital signature, created by Alice and +included with the message, serves this purpose.

    + +

    Digital signatures are created by encrypting a digest of the message, +and other information (such as a sequence number) with the sender's +private key. Though anyone may decrypt the signature using the public +key, only the signer knows the private key. This means that only they may +have signed it. Including the digest in the signature means the signature is +only good for that message; it also ensures the integrity of the message since +no one can change the digest and still sign it.

    +

    To guard against interception and reuse of the signature by an intruder at a +later date, the signature contains a unique sequence number. This protects +the bank from a fraudulent claim from Alice that she did not send the message +-- only she could have signed it (non-repudiation).

    + +
    top
    +
    +

    Certificates

    + +

    Although Alice could have sent a private message to the bank, signed +it, and ensured the integrity of the message, she still needs to be sure +that she is really communicating with the bank. This means that she needs +to be sure that the public key she is using corresponds to the bank's +private key. Similarly, the bank also needs to verify that the message +signature really corresponds to Alice's signature.

    + +

    If each party has a certificate which validates the other's identity, +confirms the public key, and is signed by a trusted agency, then they both +will be assured that they are communicating with whom they think they are. +Such a trusted agency is called a Certificate Authority, and +certificates are used for authentication.

    + +

    Certificate Contents

    + +

    A certificate associates a public key with the real identity of + an individual, server, or other entity, known as the subject. As + shown in Table 1, information about the subject + includes identifying information (the distinguished name), and the + public key. It also includes the identification and signature of the + Certificate Authority that issued the certificate, and the period of + time during which the certificate is valid. It may have additional + information (or extensions) as well as administrative information + for the Certificate Authority's use, such as a serial number.

    + +

    Table 1: Certificate Information

    + + + + + + + + + + + + + +
    SubjectDistinguished Name, Public Key
    IssuerDistinguished Name, Signature
    Period of ValidityNot Before Date, Not After Date
    Administrative InformationVersion, Serial Number
    Extended InformationBasic Constraints, Netscape Flags, etc.
    + + +

    A distinguished name is used to provide an identity in a specific + context -- for instance, an individual might have a personal + certificate as well as one for their identity as an employee. + Distinguished names are defined by the X.509 standard [X509], which defines the fields, field names, and + abbreviations used to refer to the fields (see Table + 2).

    + +

    Table 2: Distinguished Name Information

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DN FieldAbbrev.DescriptionExample
    Common NameCNName being certifiedCN=Joe Average
    Organization or CompanyOName is associated with this
    organization
    O=Snake Oil, Ltd.
    Organizational UnitOUName is associated with this
    organization unit, such + as a department
    OU=Research Institute
    City/LocalityLName is located in this CityL=Snake City
    State/ProvinceSTName is located in this State/ProvinceST=Desert
    CountryCName is located in this Country (ISO code)C=XZ
    + + +

    A Certificate Authority may define a policy specifying which + distinguished field names are optional, and which are required. It + may also place requirements upon the field contents, as may users of + certificates. As an example, a Netscape browser requires that the + Common Name for a certificate representing a server has a name which + matches a wildcard pattern for the domain name of that server, such + as *.snakeoil.com.

    + +

    The binary format of a certificate is defined using the ASN.1 + notation [X208] [PKCS]. This + notation defines how to specify the contents, and encoding rules + define how this information is translated into binary form. The binary + encoding of the certificate is defined using Distinguished Encoding + Rules (DER), which are based on the more general Basic Encoding Rules + (BER). For those transmissions which cannot handle binary, the binary + form may be translated into an ASCII form by using Base64 encoding + [MIME]. This encoded version is called PEM encoded + (the name comes from "Privacy Enhanced Mail"), when placed between + begin and end delimiter lines as illustrated in the following + example.

    + +

    Example of a PEM-encoded certificate (snakeoil.crt)

    -----BEGIN CERTIFICATE-----
    +MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCWFkx
    +FTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25ha2UgVG93bjEXMBUG
    +A1UEChMOU25ha2UgT2lsLCBMdGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhv
    +cml0eTEVMBMGA1UEAxMMU25ha2UgT2lsIENBMR4wHAYJKoZIhvcNAQkBFg9jYUBz
    +bmFrZW9pbC5kb20wHhcNOTgxMDIxMDg1ODM2WhcNOTkxMDIxMDg1ODM2WjCBpzEL
    +MAkGA1UEBhMCWFkxFTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25h
    +a2UgVG93bjEXMBUGA1UEChMOU25ha2UgT2lsLCBMdGQxFzAVBgNVBAsTDldlYnNl
    +cnZlciBUZWFtMRkwFwYDVQQDExB3d3cuc25ha2VvaWwuZG9tMR8wHQYJKoZIhvcN
    +AQkBFhB3d3dAc25ha2VvaWwuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
    +gQDH9Ge/s2zcH+da+rPTx/DPRp3xGjHZ4GG6pCmvADIEtBtKBFAcZ64n+Dy7Np8b
    +vKR+yy5DGQiijsH1D/j8HlGE+q4TZ8OFk7BNBFazHxFbYI4OKMiCxdKzdif1yfaa
    +lWoANFlAzlSdbxeGVHoT0K+gT5w3UxwZKv2DLbCTzLZyPwIDAQABoyYwJDAPBgNV
    +HRMECDAGAQH/AgEAMBEGCWCGSAGG+EIBAQQEAwIAQDANBgkqhkiG9w0BAQQFAAOB
    +gQAZUIHAL4D09oE6Lv2k56Gp38OBDuILvwLg1v1KL8mQR+KFjghCrtpqaztZqcDt
    +2q2QoyulCgSzHbEGmi0EsdkPfg6mp0penssIFePYNI+/8u9HT4LuKMJX15hxBam7
    +dUHzICxBVC1lnHyYGjDuAMhe396lYAn8bCld1/L4NMGBCQ==
    +-----END CERTIFICATE-----
    + + +

    Certificate Authorities

    + +

    By first verifying the information in a certificate request + before granting the certificate, the Certificate Authority assures + the identity of the private key owner of a key-pair. For instance, + if Alice requests a personal certificate, the Certificate Authority + must first make sure that Alice really is the person the certificate + request claims.

    + +

    Certificate Chains

    + +

    A Certificate Authority may also issue a certificate for + another Certificate Authority. When examining a certificate, + Alice may need to examine the certificate of the issuer, for each + parent Certificate Authority, until reaching one which she has + confidence in. She may decide to trust only certificates with a + limited chain of issuers, to reduce her risk of a "bad" certificate + in the chain.

    + + +

    Creating a Root-Level CA

    + +

    As noted earlier, each certificate requires an issuer to assert + the validity of the identity of the certificate subject, up to + the top-level Certificate Authority (CA). This presents a problem: + Since this is who vouches for the certificate of the top-level + authority, which has no issuer? In this unique case, the + certificate is "self-signed", so the issuer of the certificate is + the same as the subject. As a result, one must exercise extra care + in trusting a self-signed certificate. The wide publication of a + public key by the root authority reduces the risk in trusting this + key -- it would be obvious if someone else publicized a key + claiming to be the authority. Browsers are preconfigured to trust + well-known certificate authorities.

    + +

    A number of companies, such as Thawte and VeriSign + have established themselves as Certificate Authorities. These + companies provide the following services:

    + +
      +
    • Verifying certificate requests
    • +
    • Processing certificate requests
    • +
    • Issuing and managing certificates
    • +
    + +

    It is also possible to create your own Certificate Authority. + Although risky in the Internet environment, it may be useful + within an Intranet where the organization can easily verify the + identities of individuals and servers.

    + + +

    Certificate Management

    + +

    Establishing a Certificate Authority is a responsibility which + requires a solid administrative, technical, and management + framework. Certificate Authorities not only issue certificates, + they also manage them -- that is, they determine how long + certificates are valid, they renew them, and they keep lists of + certificates that have already been issued but are no longer valid + (Certificate Revocation Lists, or CRLs). Say Alice is entitled to + a certificate as an employee of a company. Say too, that the + certificate needs to be revoked when Alice leaves the company. Since + certificates are objects that get passed around, it is impossible + to tell from the certificate alone that it has been revoked. When + examining certificates for validity, therefore, it is necessary to + contact the issuing Certificate Authority to check CRLs -- this + is not usually an automated part of the process.

    + +

    Note

    +

    If you use a Certificate Authority that is not configured into + browsers by default, it is necessary to load the Certificate + Authority certificate into the browser, enabling the browser to + validate server certificates signed by that Certificate Authority. + Doing so may be dangerous, since once loaded, the browser will + accept all certificates signed by that Certificate Authority.

    +
    + + + +
    top
    +
    +

    Secure Sockets Layer (SSL)

    + +

    The Secure Sockets Layer protocol is a protocol layer which may be +placed between a reliable connection-oriented network layer protocol +(e.g. TCP/IP) and the application protocol layer (e.g. HTTP). SSL provides +for secure communication between client and server by allowing mutual +authentication, the use of digital signatures for integrity, and encryption +for privacy.

    + +

    The protocol is designed to support a range of choices for specific +algorithms used for cryptography, digests, and signatures. This allows +algorithm selection for specific servers to be made based on legal, export +or other concerns, and also enables the protocol to take advantage of new +algorithms. Choices are negotiated between client and server at the start +of establishing a protocol session.

    + +

    Table 4: Versions of the SSL protocol

    + + + + + + + + + + + + + + + + + + + +
    VersionSourceDescriptionBrowser Support
    SSL v2.0Vendor Standard (from Netscape Corp.) [SSL2]First SSL protocol for which implementations exists- NS Navigator 1.x/2.x
    + - MS IE 3.x
    + - Lynx/2.8+OpenSSL
    SSL v3.0Expired Internet Draft (from Netscape Corp.) [SSL3]Revisions to prevent specific security attacks, add non-RSA + ciphers, and support for certificate chains- NS Navigator 2.x/3.x/4.x
    + - MS IE 3.x/4.x
    + - Lynx/2.8+OpenSSL
    TLS v1.0Proposed Internet Standard (from IETF) [TLS1]Revision of SSL 3.0 to update the MAC layer to HMAC, add block + padding for block ciphers, message order standardization and more + alert messages.- Lynx/2.8+OpenSSL
    + + +

    There are a number of versions of the SSL protocol, as shown in +Table 4. As noted there, one of the benefits in +SSL 3.0 is that it adds support of certificate chain loading. This feature +allows a server to pass a server certificate along with issuer certificates +to the browser. Chain loading also permits the browser to validate the +server certificate, even if Certificate Authority certificates are not +installed for the intermediate issuers, since they are included in the +certificate chain. SSL 3.0 is the basis for the Transport Layer Security +[TLS] protocol standard, currently in development by +the Internet Engineering Task Force (IETF).

    + +

    Session Establishment

    + +

    The SSL session is established by following a handshake sequence + between client and server, as shown in Figure 1. This sequence may vary, depending on whether the server + is configured to provide a server certificate or request a client + certificate. Though cases exist where additional handshake steps + are required for management of cipher information, this article + summarizes one common scenario: see the SSL specification for the full + range of possibilities.

    + +

    Note

    +

    Once an SSL session has been established it may be reused, thus + avoiding the performance penalty of repeating the many steps needed + to start a session. For this the server assigns each SSL session a + unique session identifier which is cached in the server and which the + client can use on forthcoming connections to reduce the handshake + (until the session identifer expires in the cache of the server).

    +
    + +

    +
    + Figure 1: Simplified SSL + Handshake Sequence

    + +

    The elements of the handshake sequence, as used by the client and + server, are listed below:

    + +
      +
    1. Negotiate the Cipher Suite to be used during data transfer
    2. +
    3. Establish and share a session key between client and server
    4. +
    5. Optionally authenticate the server to the client
    6. +
    7. Optionally authenticate the client to the server
    8. +
    + +

    The first step, Cipher Suite Negotiation, allows the client and + server to choose a Cipher Suite supportable by both of them. The SSL3.0 + protocol specification defines 31 Cipher Suites. A Cipher Suite is + defined by the following components:

    + +
      +
    • Key Exchange Method
    • +
    • Cipher for Data Transfer
    • +
    • Message Digest for creating the Message Authentication Code (MAC)
    • +
    + +

    These three elements are described in the sections that follow.

    + + +

    Key Exchange Method

    + +

    The key exchange method defines how the shared secret symmetric + cryptography key used for application data transfer will be agreed + upon by client and server. SSL 2.0 uses RSA key exchange only, while + SSL 3.0 supports a choice of key exchange algorithms including the + RSA key exchange when certificates are used, and Diffie-Hellman key + exchange for exchanging keys without certificates and without prior + communication between client and server.

    + +

    One variable in the choice of key exchange methods is digital + signatures -- whether or not to use them, and if so, what kind of + signatures to use. Signing with a private key provides assurance + against a man-in-the-middle-attack during the information exchange + used in generating the shared key [AC96, p516].

    + + +

    Cipher for Data Transfer

    + +

    SSL uses the conventional cryptography algorithm (symmetric + cryptography) described earlier for encrypting messages in a session. + There are nine choices, including the choice to perform no + encryption:

    + +
      +
    • No encryption
    • +
    • Stream Ciphers +
        +
      • RC4 with 40-bit keys
      • +
      • RC4 with 128-bit keys
      • +
    • +
    • CBC Block Ciphers +
      • RC2 with 40 bit key
      • +
      • DES with 40 bit key
      • +
      • DES with 56 bit key
      • +
      • Triple-DES with 168 bit key
      • +
      • Idea (128 bit key)
      • +
      • Fortezza (96 bit key)
      • +
    • +
    + +

    Here "CBC" refers to Cipher Block Chaining, which means that a + portion of the previously encrypted cipher text is used in the + encryption of the current block. "DES" refers to the Data Encryption + Standard [AC96, ch12], which has a number of + variants (including DES40 and 3DES_EDE). "Idea" is one of the best + and cryptographically strongest available algorithms, and "RC2" is + a proprietary algorithm from RSA DSI [AC96, + ch13].

    + + +

    Digest Function

    + +

    The choice of digest function determines how a digest is created + from a record unit. SSL supports the following:

    + +
      +
    • No digest (Null choice)
    • +
    • MD5, a 128-bit hash
    • +
    • Secure Hash Algorithm (SHA-1), a 160-bit hash
    • +
    + +

    The message digest is used to create a Message Authentication Code + (MAC) which is encrypted with the message to provide integrity and to + prevent against replay attacks.

    + + +

    Handshake Sequence Protocol

    + +

    The handshake sequence uses three protocols:

    + +
      +
    • The SSL Handshake Protocol + for performing the client and server SSL session establishment.
    • +
    • The SSL Change Cipher Spec Protocol for actually + establishing agreement on the Cipher Suite for the session.
    • +
    • The SSL Alert Protocol for conveying SSL error + messages between client and server.
    • +
    + +

    These protocols, as well as application protocol data, are + encapsulated in the SSL Record Protocol, as shown in + Figure 2. An encapsulated protocol is + transferred as data by the lower layer protocol, which does not + examine the data. The encapsulated protocol has no knowledge of the + underlying protocol.

    + +

    +
    + Figure 2: SSL Protocol Stack +

    + +

    The encapsulation of SSL control protocols by the record protocol + means that if an active session is renegotiated the control protocols + will be transmitted securely. If there were no session before, then + the Null cipher suite is used, which means there is no encryption and + messages have no integrity digests until the session has been + established.

    + + +

    Data Transfer

    + +

    The SSL Record Protocol, shown in Figure 3, + is used to transfer application and SSL Control data between the + client and server, possibly fragmenting this data into smaller units, + or combining multiple higher level protocol data messages into single + units. It may compress, attach digest signatures, and encrypt these + units before transmitting them using the underlying reliable transport + protocol (Note: currently all major SSL implementations lack support + for compression).

    + +

    +
    + Figure 3: SSL Record Protocol +

    + + +

    Securing HTTP Communication

    + +

    One common use of SSL is to secure Web HTTP communication between + a browser and a webserver. This case does not preclude the use of + non-secured HTTP. The secure version is mainly plain HTTP over SSL + (named HTTPS), but with one major difference: it uses the URL scheme + https rather than http and a different + server port (by default 443). This mainly is what mod_ssl provides to you for the Apache webserver...

    + +
    top
    +
    +

    References

    + +
    +
    [AC96]
    +
    Bruce Schneier, Applied Cryptography, 2nd Edition, Wiley, +1996. See http://www.counterpane.com/ for various other materials by Bruce +Schneier.
    + +
    [X208]
    +
    ITU-T Recommendation X.208, Specification of Abstract Syntax Notation +One (ASN.1), 1988. See for instance http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.208-198811-I. +
    + +
    [X509]
    +
    ITU-T Recommendation X.509, The Directory - Authentication +Framework. See for instance http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.509. +
    + +
    [PKCS]
    +
    Public Key Cryptography Standards (PKCS), +RSA Laboratories Technical Notes, See http://www.rsasecurity.com/rsalabs/pkcs/.
    + +
    [MIME]
    +
    N. Freed, N. Borenstein, Multipurpose Internet Mail Extensions +(MIME) Part One: Format of Internet Message Bodies, RFC2045. +See for instance http://ietf.org/rfc/rfc2045.txt.
    + +
    [SSL2]
    +
    Kipp E.B. Hickman, The SSL Protocol, 1995. See http://www.netscape.com/eng/security/SSL_2.html.
    + +
    [SSL3]
    +
    Alan O. Freier, Philip Karlton, Paul C. Kocher, The SSL Protocol +Version 3.0, 1996. See http://www.netscape.com/eng/ssl3/draft302.txt.
    + +
    [TLS1]
    +
    Tim Dierks, Christopher Allen, The TLS Protocol Version 1.0, +1999. See http://ietf.org/rfc/rfc2246.txt.
    +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/ssl_intro.html.ja.euc-jp b/trunk/docs/manual/ssl/ssl_intro.html.ja.euc-jp new file mode 100644 index 0000000000..d897683021 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.html.ja.euc-jp @@ -0,0 +1,695 @@ + + + +SSL/TLS °Å¹æ²½: ¤Ï¤¸¤á¤Ë - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    SSL/TLS °Å¹æ²½: ¤Ï¤¸¤á¤Ë

    +
    +

    Available Languages:  en  | + ja 

    +
    + +
    +

    ɸ½àµ¬³Ê¤ÎÎɤ¤½ê¤Ï¡¢¤¿¤¯¤µ¤ó¤Îµ¬³Ê¤«¤éÁª¤Ù¤ë¤È¤¤¤¦¤³¤È¤À¡£ +¤½¤·¤Æ¡¢¤â¤·ËÜÅö¤Ë¤É¤Îµ¬³Ê¤âµ¤¤ËÆþ¤é¤Ê¤±¤ì¤Ð¡¢ +°ìǯÂԤĤÀ¤±¤Çõ¤·¤Æ¤¤¤¿µ¬³Ê¤¬¸½¤ì¤ë¡£

    + +

    -- A. Tanenbaum, "Introduction to +Computer Networks"

    +
    + +

    +ÆþÌç¤È¤¤¤¦¤³¤È¤Ç¡¢¤³¤Î¾Ï¤Ï Web¡¢HTTP¡¢Apache ¤ËÄ̤¸¤Æ¤¤¤ë +ÆɼԸþ¤±¤Ç¤¹¤¬¡¢¥»¥­¥å¥ê¥Æ¥£ÀìÌç²È¸þ¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ +SSL ¥×¥í¥È¥³¥ë¤Î·èÄêŪ¤Ê¼ê°ú¤­¤Ç¤¢¤ë¤Ä¤â¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¡£ +¤Þ¤¿¡¢ÁÈ¿¥Æâ¤Îǧ¾Ú´ÉÍý¤Î¤¿¤á¤ÎÆÃÄê¤Î¥Æ¥¯¥Ë¥Ã¥¯¤ä¡¢ +Æõö¤äÍ¢½Ðµ¬À©¤Ê¤É¤Î½ÅÍפÊˡŪ¤ÊÌäÂê¤Ë¤Ä¤¤¤Æ¤â°·¤¤¤Þ¤»¤ó¡£ +¤à¤·¤í¡¢¹¹¤Ê¤ë¸¦µæ¤Ø¤Î½ÐȯÅÀ¤È¤·¤Æ¿§¡¹¤Ê³µÇ°¡¢ÄêµÁ¡¢Îã¤òʤ٤뤳¤È¤Ç + mod_ssl ¤Î¥æ¡¼¥¶¤Ë´ðÁÃÃ챤òÄ󶡤¹¤ë»ö¤òÌÜŪ¤È¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    ¤³¤³¤Ë¼¨¤µ¤ì¤¿ÆâÍƤϼç¤Ë¡¢¸¶Ãø¼Ô¤Îµö²Ä¤Î²¼ +The Open Group Research Institute ¤Î Frederick J. Hirsch + »á¤Îµ­»ö +Introducing SSL and Certificates using SSLeay ¤ò´ð¤Ë¤·¤Æ¤¤¤Þ¤¹¡£ +»á¤Îµ­»ö¤Ï Web Security: A Matter of +Trust, World Wide Web Journal, Volume 2, Issue 3, Summer 1997 +¤Ë·ÇºÜ¤µ¤ì¤Þ¤·¤¿¡£ +¹ÎÄêŪ¤Ê°Õ¸«¤Ï Frederick Hirsch »á + (¸µµ­»ö¤ÎÃø¼Ô) ¤ØÁ´¤Æ¤Î¶ì¾ð¤Ï Ralf S. Engelschall ( +mod_ssl ¤Îºî¼Ô) ¤Ø¤ª´ê¤¤¤·¤Þ¤¹¡£ +[ÌõÃí: Ìõ¤Ë¤Ä¤¤¤Æ¤Ï +Apache ¥É¥­¥å¥á¥ó¥ÈËÝÌõ¥×¥í¥¸¥§¥¯¥È +¤Ø¤ª´ê¤¤¤·¤Þ¤¹¡£]

    +
    + +
    top
    +
    +

    °Å¹æ²½µ»½Ñ

    + +

    SSL ¤òÍý²ò¤¹¤ë¤Ë¤Ï¡¢°Å¹æ¥¢¥ë¥´¥ê¥º¥à¡¢ +¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È´Ø¿ô(ÊÌ̾: °ìÊý¸þ´Ø¿ô¡¢¥Ï¥Ã¥·¥å´Ø¿ô)¡¢ +ÅŻҽð̾¤Ê¤É¤Ø¤ÎÍý²ò¤¬É¬ÍפǤ¹¡£ +¤³¤ì¤é¤Îµ»½Ñ¤ÏËܤ¬´Ý¤´¤ÈɬÍפÊÂêÌÜ¤Ç +(Î㤨¤Ð [AC96] ¤ò»²¾È)¡¢ +¥×¥é¥¤¥Ð¥·¡¼¡¢¿®ÍÑ¡¢Ç§¾Ú¤Ê¤É¤Îµ»½Ñ¤Î´ðÁäȤʤäƤ¤¤Þ¤¹¡£

    + +

    °Å¹æ¥¢¥ë¥´¥ê¥º¥à

    + +

    Î㤨¤Ð¡¢¥¢¥ê¥¹¤¬Á÷¶â¤Î¤¿¤á¤Ë¶ä¹Ô¤Ë¥á¥Ã¥»¡¼¥¸¤òÁ÷¤ê¤¿¤¤¤È¤·¤Þ¤¹¡£ + ¸ýºÂÈÖ¹æ¤äÁ÷¶â¤Î¶â³Û¤¬´Þ¤Þ¤ì¤ë¤¿¤á¡¢ + ¥¢¥ê¥¹¤Ï¤½¤Î¥á¥Ã¥»¡¼¥¸¤òÈëÌ©¤Ë¤·¤¿¤¤¤È»×¤¤¤Þ¤¹¡£ + ²ò·èÊýË¡¤Î°ì¤Ä¤Ï°Å¹æ¥¢¥ë¥´¥ê¥º¥à¤ò»È¤Ã¤Æ¡¢¥á¥Ã¥»¡¼¥¸¤ò + Æɤޤ»¤¿¤¤¿Í°Ê³°¤ÏÆɤळ¤È¤¬¤Ç¤­¤Ê¤¤°Å¹æ²½¤µ¤ì¤¿ + ·ÁÂÖ¤ËÊѤ¨¤Æ¤·¤Þ¤¦¤³¤È¤Ç¤¹¡£ + ¤½¤Î·ÁÂ֤ˤʤë¤È¡¢ + ¥á¥Ã¥»¡¼¥¸¤ÏÈëÌ©¤Î¸°¤Ë¤è¤Ã¤Æ¤Î¤ß²ò¼á¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¸°¤Ê¤·¤Ç¤Ï¡¢¥á¥Ã¥»¡¼¥¸¤ÏÌò¤ËΩ¤Á¤Þ¤»¤ó¡£ + Îɤ¤°Å¹æ¥¢¥ë¥´¥ê¥º¥à¤Ï¡¢¿¯Æþ¼Ô¤¬¸µ¤Î¥Æ¥­¥¹¥È¤ò²òÆɤ¹¤ë¤³¤È¤ò + Èó¾ï¤ËÆñ¤·¤¯¤¹¤ë¤¿¤á¡¢ÅØÎϤ¬³ä¤Ë¹ç¤ï¤Ê¤¯¤µ¤»¤Þ¤¹¡£

    + +

    °Å¹æ¥¢¥ë¥´¥ê¥º¥à¤Ë¤Ï + ½¾Íè·¿¤È¸ø³«¸°¤ÎÆó¤Ä¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡£

    + +
    +
    ½¾Íè·¿°Å¹æ
    +
    ÂоΰŹæ¤È¤·¤Æ¤âÃΤé¤ì¡¢ + Á÷¿®¼Ô¤È¼õ¿®¼Ô¤¬¸°¤ò¶¦Í­¤¹¤ë¤³¤È¤¬É¬ÍפǤ¹¡£ + ¸°¤È¤Ï¡¢¥á¥Ã¥»¡¼¥¸¤ò°Å¹æ²½¤·¤¿¤êÉü¹æ¤¹¤ë¤Î¤Ë»È¤ï¤ì¤ëÈëÌ© + ¤Î¾ðÊó¤Î¤³¤È¤Ç¤¹¡£ + ¤â¤·¡¢¤³¤Î¸°¤¬ÈëÌ©¤Ê¤é¡¢Á÷¿®¼Ô¤È¼õ¿®¼Ô°Ê³°¤Ïï¤â¥á¥Ã¥»¡¼¥¸¤òÆÉ + ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£ + ¤â¤·¤â¡¢¥¢¥ê¥¹¤È¶ä¹Ô¤¬ÈëÌ©¤Î¸°¤òÃΤäƤ¤¤ë¤Ê¤é¡¢ + Èà¤é¤Ï¤ª¸ß¤¤¤ËÈëÌ©¤Î¥á¥Ã¥»¡¼¥¸¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£ + ¤¿¤À¤·¡¢»öÁ°¤ËÆâÌ©¤Ë¸°¤òÁª¤Ö¤È¤¤¤¦»Å»ö¤ÏÌäÂê¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
    + +
    ¸ø³«¸°°Å¹æ
    +
    ÈóÂоΰŹæ¤È¤·¤Æ¤âÃΤé¤ì¡¢ + ¥á¥Ã¥»¡¼¥¸¤ò°Å¹æ²½¤¹¤ë¤³¤È¤Î¤Ç¤­¤ëÆó¤Ä¤Î¸° + ¤ò»ÈÍѤ¹¤ë¥¢¥ë¥´¥ê¥º¥à¤òÄêµÁ¤¹¤ë¤³¤È¤Ç¸°¤Î¤ä¤ê¼è¤ê¤ÎÌäÂê¤ò²ò·è + ¤·¤Þ¤¹¡£ + ¤â¤·¡¢¤¢¤ë¸°¤¬°Å¹æ²½¤Ë»È¤ï¤ì¤¿¤Ê¤é¡¢ + ¤â¤¦ÊÒÊý¤Î¸°¤ÇÉü¹æ¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ + ¤³¤ÎÊý¼°¤Ë¤è¤Ã¤Æ¡¢°ì¤Ä¤Î¸°¤ò¸øɽ¤·¤Æ(¸ø³«¸°)¡¢ + ¤â¤¦ÊÒÊý¤òÈëÌ©¤Ë¤·¤Æ¤ª¤¯(ÈëÌ©¸°)¤À¤±¤Ç¡¢ + °ÂÁ´¤Ê¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    +
    + +

    ï¤â¤¬°Å¹æ²½¤µ¤ì¤¿¥á¥Ã¥»¡¼¥¸¤ò¸ø³«¸°¤Ë¤è¤Ã¤Æ°Å¹æ²½ + ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ÈëÌ©¸°¤Î»ý¤Á¼ç¤À¤±¤¬¤½¤ì¤òÆɤळ¤È¤¬ + ¤Ç¤­¤Þ¤¹¡£ + ¤³¤ÎÊýË¡¤Ç¡¢¶ä¹Ô¤Î¸ø³«¸°¤ò»È¤Ã¤Æ°Å¹æ²½¤¹¤ë¤³¤È¤Ç¡¢ + ¥¢¥ê¥¹¤ÏÈëÌ©¤Î¥á¥Ã¥»¡¼¥¸¤òÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¶ä¹Ô¤Î¤ß¤¬Éü¹æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +

    ¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È

    + +

    ¥¢¥ê¥¹¤Ï¥á¥Ã¥»¡¼¥¸¤òÈëÌ©¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ + 狼¤¬Î㤨¤Ð¼«Ê¬¤ËÁ÷¶â¤¹¤ë¤è¤¦¤Ë¥á¥Ã¥»¡¼¥¸¤òÊѹ¹¤·¤¿¤ê¡¢ + Ê̤Τâ¤Î¤ËÃÖ¤­´¹¤¨¤Æ¤·¤Þ¤¦¤«¤â¤·¤ì¤Ê¤¤¤È¤¤¤¦ÌäÂ꤬¤¢¤ê¤Þ¤¹¡£ + ¥¢¥ê¥¹¤Î¥á¥Ã¥»¡¼¥¸¤Î¿®ÍѤòÊݾڤ¹¤ëÊýË¡¤Î°ì¤Ä¤Ï¡¢ + ¥á¥Ã¥»¡¼¥¸¤Î´Ê·é¤Ê¥À¥¤¥¸¥§¥¹¥È¤òºî¤Ã¤Æ¡¢¤½¤ì¤â¶ä¹Ô¤ËÁ÷¤ë¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£ + ¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤ë¤È¶ä¹Ô¤â¥À¥¤¥¸¥§¥¹¥È¤òºîÀ®¤·¡¢ + ¥¢¥ê¥¹¤¬Á÷¤Ã¤¿¤â¤Î¤ÈÈæ¤Ù¤Þ¤¹¡£¤â¤·°ìÃפ·¤¿¤Ê¤é¡¢ + ¼õ¤±¼è¤Ã¤¿¥á¥Ã¥»¡¼¥¸¤Ï̵½ý¤À¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    ¤³¤Î¤è¤¦¤ÊÍ×Ìó¤Ï¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¡¢ + °ìÊý¹Ô´Ø¿ô¡¢¤Þ¤¿¤Ï¥Ï¥Ã¥·¥å´Ø¿ô¤È¸Æ¤Ð¤ì¤Þ¤¹¡£ + ¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¤ÏŤ¤²ÄÊÑĹ¤Î¥á¥Ã¥»¡¼¥¸¤«¤é + û¤¤¸ÇÄêŤÎɽ¸½¤òºî¤ë¤Î¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¥À¥¤¥¸¥§¥¹¥È¥¢¥ë¥´¥ê¥º¥à¤Ï¥á¥Ã¥»¡¼¥¸¤«¤é + °ì°Õ¤Ê¥À¥¤¥¸¥§¥¹¥È¤òÀ¸À®¤¹¤ë¤è¤¦¤Ëºî¤é¤ì¤Æ¤¤¤Þ¤¹¡£ + ¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¤Ï¥À¥¤¥¸¥§¥¹¥È¤«¤é¸µ¤Î¥á¥Ã¥»¡¼¥¸¤ò + ȽÄꤹ¤ë¤Î¤¬¤È¤Æ¤âÆñ¤·¤¤¤è¤¦¤Ë¤Ç¤­¤Æ¤¤¤Þ¤¹¡£ + ¤Þ¤¿¡¢Æ±¤¸Í×Ìó¤òºîÀ®¤¹¤ëÆó¤Ä¤Î¥á¥Ã¥»¡¼¥¸¤òõ¤¹¤Î¤ÏÉÔ²Äǽ¤Ç¤¹¡£ + ¤è¤Ã¤Æ¡¢Æ±¤¸Í×Ìó¤ò»È¤Ã¤Æ¥á¥Ã¥»¡¼¥¸¤òÃÖ¤­´¹¤¨¤ë¤È¤¤¤¦ + ²ÄǽÀ­¤òÇÓ½ü¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    ¥¢¥ê¥¹¤Ø¤Î¤â¤¦°ì¤Ä¤ÎÌäÂê¤Ï¡¢¤³¤Î¥À¥¤¥¸¥§¥¹¥È¤ò°ÂÁ´¤ËÁ÷¤ëÊýË¡¤òõ¤¹¤³¤È¤Ç¤¹¡£ +¤³¤ì¤¬¤Ç¤­¤ì¤Ð¡¢¥á¥Ã¥»¡¼¥¸¤Î¿®ÍѤ¬Êݾڤµ¤ì¤Þ¤¹¡£ +°ì¤Ä¤ÎÊýË¡¤Ï¤³¤Î¥À¥¤¥¸¥§¥¹¥È¤ËÅŻҽð̾¤ò´Þ¤à¤³¤È¤Ç¤¹¡£

    + + +

    ÅŻҽð̾

    +

    ¥¢¥ê¥¹¤¬¶ä¹Ô¤Ë¥á¥Ã¥»¡¼¥¸¤òÁ÷¤Ã¤¿¤È¤­¡¢¶ä¹Ô¤Ï¡¢ +¿¯Æþ¼Ô¤¬Èà½÷¤Ë¤Ê¤ê¤¹¤Þ¤·¤ÆÈà½÷¤Î¸ýºÂ¤Ø¤Î¼è°ú¤ò¿½ÀÁ¤·¤Æ¤¤¤Ê¤¤¤«¡¢ +¥á¥Ã¥»¡¼¥¸¤¬ËÜÅö¤ËÈà½÷¤«¤é¤Î¤â¤Î¤«³Î¼Â¤Ëʬ¤«¤é¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ +¥¢¥ê¥¹¤Ë¤è¤Ã¤ÆºîÀ®¤µ¤ì¡¢¥á¥Ã¥»¡¼¥¸¤Ë´Þ¤Þ¤ì¤¿ +ÅŻҽð̾¤¬¤³¤³¤ÇÌò¤ËΩ¤Á¤Þ¤¹¡£

    + +

    ÅŻҽð̾¤Ï¥á¥Ã¥»¡¼¥¸¤Î¥À¥¤¥¸¥§¥¹¥È¤ä¤½¤Î¾¤Î¾ðÊó(½èÍýÈÖ¹æ¤Ê¤É)¤ò +Á÷¿®¼Ô¤ÎÈëÌ©¸°¤Ç°Å¹æ²½¤¹¤ë¤³¤È¤Çºî¤é¤ì¤Þ¤¹¡£ +ï¤â¤¬¸ø³«¸°¤ò»È¤Ã¤Æ½ð̾¤òÉü¹æ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¤¬¡¢ +½ð̾¼Ô¤Î¤ß¤¬ÈëÌ©¸°¤òÃΤäƤ¤¤Þ¤¹¡£ +¤³¤ì¤Ï¡¢Èà¤é¤Î¤ß¤¬½ð̾¤·¤¨¤¿¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ +¥À¥¤¥¸¥§¥¹¥È¤òÅŻҽð̾¤Ë´Þ¤à¤³¤È¤Ï¡¢ +¤½¤Î½ð̾¤¬¤½¤Î¥á¥Ã¥»¡¼¥¸¤Î¤ß¤ËÍ­¸ú¤Ç¤¢¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ +¤³¤ì¤Ï¡¢Ã¯¤â¥À¥¤¥¸¥§¥¹¥È¤òÊѤ¨¤Æ½ð̾¤ò¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¤¿¤á¡¢ +¥á¥Ã¥»¡¼¥¸¤Î¿®ÍѤâÊݾڤ·¤Þ¤¹¡£

    + +

    ¿¯Æþ¼Ô¤¬½ð̾¤ò˵¼õ¤·¤Æ¸åÆü¤ËºÆÍøÍѤ¹¤ë¤Î¤òËɤ°¤¿¤á +ÅŻҽð̾¤Ë¤Ï°ì°Õ¤Ê½èÍýÈֹ椬´Þ¤Þ¤ì¤Þ¤¹¡£ +¤³¤ì¤Ï¡¢¥¢¥ê¥¹¤¬¤½¤ó¤Ê¥á¥Ã¥»¡¼¥¸¤ÏÁ÷¤Ã¤Æ¤¤¤Ê¤¤¤È¸À¤¦º¾µ½ +¤«¤é¶ä¹Ô¤ò¼é¤ê¤Þ¤¹¡£ +Èà½÷¤À¤±¤¬½ð̾¤·¤¨¤¿¤«¤é¤Ç¤¹¡£(ÈÝǧËÉ»ß)

    + +
    top
    +
    +

    ¾ÚÌÀ½ñ

    + +

    ¥¢¥ê¥¹¤ÏÈëÌ©¤Î¥á¥Ã¥»¡¼¥¸¤ò¶ä¹Ô¤ËÁ÷¤ê¡¢ +½ð̾¤ò¤·¤Æ¡¢¥á¥Ã¥»¡¼¥¸¤Î¿®ÍѤòÊݾڤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤ª¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¤¬¡¢ +ÄÌ¿®¤·¤Æ¤¤¤ëÁê¼ê¤¬ËÜÅö¤Ë¶ä¹Ô¤Ê¤Î¤«³Î¤«¤á¤Ê¤¯¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£ +¤³¤ì¤Ï¡¢Èà½÷¤¬»È¤¦¸ø³«¸°¤¬¶ä¹Ô¤ÎÈëÌ©¸°¤ÈÂФˤʤäƤ¤¤ë¤â¤Î¤«¡¢ +Èà½÷¤Ï³Î¤«¤á¤Ê¤¯¤Æ¤Ï¤¤¤±¤Ê¤¤¤È¤¤¤¦¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ +ƱÍͤˡ¢¶ä¹Ô¤Ï¥á¥Ã¥»¡¼¥¸¤Î½ð̾¤¬ËÜÅö¤Ë¥¢¥ê¥¹¤Î½ð̾¤«³Îǧ¤¹¤ëɬÍפ¬ +¤¢¤ê¤Þ¤¹¡£

    + +

    ¤â¤·Î¾¼Ô¤Ë¿È¸µ¤ò¾ÚÌÀ¤·¡¢¸ø³«¸°¤ò³Îǧ¤·¡¢¤Þ¤¿¿®Íꤵ¤ì¤¿µ¡´Ø¤¬½ð̾ +¤·¤¿¾ÚÌÀ½ñ¤¬¤¢¤ì¤Ð¡¢Î¾¼Ô¤È¤âÄÌ¿®Áê¼ê¤Ë¤Ä¤¤¤ÆÀµ¤·¤¤Áê¼ê¤À¤È +³Î¿®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +¤½¤Î¤è¤¦¤Ê¿®Íꤵ¤ì¤¿µ¡´Ø¤Ïǧ¾Ú¶É + (Certificate Authority ¤Þ¤¿¤Ï CA) ¤È¸Æ¤Ð¤ì¡¢ +¾ÚÌÀ½ñ (certificate) ¤¬Ç§¾Ú (authentication) ¤Ë»È¤ï¤ì¤Þ¤¹¡£

    + +

    ¾ÚÌÀ½ñ¤ÎÆâÍÆ

    + +

    ¾ÚÌÀ½ñ¤Ï¸ø³«¸°¤È¸Ä¿Í¡¢¥µ¡¼¥Ð¡¢¤½¤Î¾¤Î¼çÂΤμºߤοȸµ¤ò + ´ØÏ¢ÉÕ¤±¤Þ¤¹¡£ + ɽ1¤Ë¼¨¤µ¤ì¤ë¤è¤¦¤Ë¾ÚÌÀÂоݤξðÊó¤Ï + ¿È¸µ¾ÚÌÀ¤Î¾ðÊó(¼±ÊÌ̾)¤È¸ø³«¸°¤¬´Þ¤Þ¤ì¤Þ¤¹¡£ + ¾ÚÌÀ½ñ¤Ï¤Þ¤¿¡¢Ç§¾Ú¶É¤Î¿È¸µ¾ÚÌÀ¤È½ð̾¡¢¤½¤·¤Æ¾ÚÌÀ½ñ¤ÎÍ­¸ú´ü´Ö¤ò + ´Þ¤ß¤Þ¤¹¡£ + ¥·¥ê¥¢¥ë¥Ê¥ó¥Ð¡¼¤Ê¤É¤Îǧ¾Ú¶É¤Î´ÉÍý¾å¤Î¾ðÊó¤ä + ¤½¤Î¾¤ÎÄɲäξðÊ󤬴ޤޤì¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    ɽ1: ¾ÚÌÀ½ñ¾ðÊó

    + + + + + + + + + + + + + +
    ¾ÚÌÀÂоݼ±ÊÌ̾¡¢¸ø³«¸°
    ȯ¹Ô¼Ô¼±ÊÌ̾¡¢¸ø³«¸°
    Í­¸ú´ü´Ö³«»ÏÆü¡¢¼º¸úÆü
    ´ÉÍý¾ðÊó¥Ð¡¼¥¸¥ç¥ó¡¢¥·¥ê¥¢¥ë¥Ê¥ó¥Ð¡¼
    ³ÈÄ¥¾ðÊó´ðËÜŪ¤ÊÀ©Ì󡢥ͥåȥ¹¥±¡¼¥×¥Õ¥é¥Ã¥°¡¢¤½¤Î¾
    + + +

    ¼±ÊÌ̾(¥Ç¥£¥¹¥Æ¥£¥ó¥°¥¤¥Ã¥·¥å¡¦¥Í¡¼¥à)¤ÏÆÃÄê¤Î¾õ¶·¤Ë¤ª¤±¤ë + ¿Èʬ¾ÚÌÀ¤òÄ󶡤¹¤ë¤Î¤Ë»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£Î㤨¤Ð¡¢¤¢¤ë¿Í¤Ï + »äÍѤȲñ¼Ò¤È¤ÇÊÌ¡¹¤Î¿Èʬ¾ÚÌÀ¤ò»ý¤Ä¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + + ¼±ÊÌ̾¤Ï X.509 ɸ½àµ¬³Ê [X509] ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + X.509 ɸ½àµ¬³Ê¤Ï¡¢¹àÌÜ¡¢¹àÌÜ̾¡¢¤½¤·¤Æ¹àÌܤÎά¾Î¤òÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£(ɽ + 2 »²¾È)

    + +

    ɽ 2: ¼±ÊÌ̾¾ðÊó

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ¼±ÊÌ̾¹àÌÜά¾ÎÀâÌÀÎã
    Common Name (¥³¥â¥ó¥Í¡¼¥à)CNǧ¾Ú¤µ¤ì¤ë̾Á°
    + SSLÀܳ¤¹¤ëURL
    CN=www.example.com
    Organization or Company (ÁÈ¿¥Ì¾)OÃÄÂΤÎÀµ¼°±Ñ¸ìÁÈ¿¥Ì¾O=Example Japan K.K.
    Organizational Unit (ÉôÌç̾)OUÉô½ð̾¤Ê¤ÉOU=Customer Service
    City/Locality (»Ô¶èĮ¼)L½êºß¤·¤Æ¤ë»Ô¶èĮ¼L=Sapporo
    State/Province (ÅÔÆ»Éܸ©)ST½êºß¤·¤Æ¤ëÅÔÆ»Éܸ©ST=Hokkaido
    Country(¹ñ)C½êºß¤·¤Æ¤¤¤ë¹ñ̾¤Î ISO ¥³¡¼¥É
    + ÆüËܤξì¹ç JP +
    C=JP
    + + +

    ǧ¾Ú¶É¤Ï¤É¤Î¹àÌܤ¬¾Êά²Äǽ¤Ç¤É¤ì¤¬É¬¿Ü¤«¤ÎÊý¿Ë¤òÄêµÁ¤¹¤ë + ¤«¤â¤·¤ì¤Þ¤»¤ó¡£¹àÌܤÎÆâÍƤˤĤ¤¤Æ¤âǧ¾Ú¶É¤ä¾ÚÌÀ½ñ¤Î¥æ¡¼¥¶¤«¤é¤Î + Í׷郎¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢¥Í¥Ã¥È¥¹¥±¡¼¥×¤Î¥Ö¥é¥¦¥¶¤Ï¥µ¡¼¥Ð¤Î¾ÚÌÀ½ñ¤Î + Common Name (¥³¥â¥ó¥Í¡¼¥à)¤¬¥µ¡¼¥Ð¤Î¥É¥á¥¤¥ó̾¤Î + *.example.com + ¤È¤¤¤¦¤è¤¦¤Ê¥ï¥¤¥ë¥É¥«¡¼¥É¤Î¥Ñ¥¿¡¼¥ó¤Ë¥Þ¥Ã¥Á¤¹¤ë¤³¤È + ¤òÍ׵ᤷ¤Þ¤¹¡£

    + +

    ¥Ð¥¤¥Ê¥ê·Á¼°¤Î¾ÚÌÀ½ñ¤Ï ASN.1 ɽµ­Ë¡ + [X208] [PKCS] ¤Ç + ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Îɽµ­Ë¡¤ÏÆâÍƤò¤É¤Î¤è¤¦¤Ëµ­½Ò¤¹¤ë¤«¤òÄêµÁ¤·¡¢ + Éä¹æ²½¤Îµ¬Ä꤬¤³¤Î¾ðÊ󤬤ɤΤ褦¤Ë¥Ð¥¤¥Ê¥ê·Á¼°¤ËÊÑ´¹¤µ¤ì¤ë¤«¤ò + ÄêµÁ¤·¤Þ¤¹¡£ + ¾ÚÌÀ½ñ¤Î¥Ð¥¤¥Ê¥êÉä¹æ²½¤Ï Distinguished Encoding + Rules (DER) ¤ÇÄêµÁ¤µ¤ì¡¢¤½¤ì¤Ï¤è¤ê°ìÈÌŪ¤Ê Basic Encoding Rules + (BER) ¤Ë´ð¤Å¤¤¤Æ¤¤¤Þ¤¹¡£ + ¥Ð¥¤¥Ê¥ê·Á¼°¤ò°·¤¦¤³¤È¤Î¤Ç¤­¤Ê¤¤Á÷¿®¤Ç¤Ï¡¢ + ¥Ð¥¤¥Ê¥ê·Á¼°¤Ï Base64 Éä¹æ²½ [MIME] ¤Ç + ASCII ·Á¼°¤ËÊÑ´¹¤µ¤ì¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤ËÉä¹æ²½¤µ¤ì¡¢°Ê²¼¤ÎÎã¤Ë¼¨¤µ¤ì¤ë¤è¤¦¤Ë¶èÀÚ¤ê¹Ô¤Ë + ¶´¤Þ¤ì¤¿¤â¤Î¤Ï PEM Éä¹æ²½¤µ¤ì¤¿¤È¸À¤¤¤Þ¤¹¡£ + (PEM ¤Î̾Á°¤Ï "Privacy Enhanced Mail" ¤ËͳÍ褷¤Þ¤¹)

    + +

    PEM Éä¹æ²½¤µ¤ì¤¿¾ÚÌÀ½ñ¤ÎÎã (example.crt)

    -----BEGIN CERTIFICATE-----
    +MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCWFkx
    +FTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25ha2UgVG93bjEXMBUG
    +A1UEChMOU25ha2UgT2lsLCBMdGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhv
    +cml0eTEVMBMGA1UEAxMMU25ha2UgT2lsIENBMR4wHAYJKoZIhvcNAQkBFg9jYUBz
    +bmFrZW9pbC5kb20wHhcNOTgxMDIxMDg1ODM2WhcNOTkxMDIxMDg1ODM2WjCBpzEL
    +MAkGA1UEBhMCWFkxFTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25h
    +a2UgVG93bjEXMBUGA1UEChMOU25ha2UgT2lsLCBMdGQxFzAVBgNVBAsTDldlYnNl
    +cnZlciBUZWFtMRkwFwYDVQQDExB3d3cuc25ha2VvaWwuZG9tMR8wHQYJKoZIhvcN
    +AQkBFhB3d3dAc25ha2VvaWwuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
    +gQDH9Ge/s2zcH+da+rPTx/DPRp3xGjHZ4GG6pCmvADIEtBtKBFAcZ64n+Dy7Np8b
    +vKR+yy5DGQiijsH1D/j8HlGE+q4TZ8OFk7BNBFazHxFbYI4OKMiCxdKzdif1yfaa
    +lWoANFlAzlSdbxeGVHoT0K+gT5w3UxwZKv2DLbCTzLZyPwIDAQABoyYwJDAPBgNV
    +HRMECDAGAQH/AgEAMBEGCWCGSAGG+EIBAQQEAwIAQDANBgkqhkiG9w0BAQQFAAOB
    +gQAZUIHAL4D09oE6Lv2k56Gp38OBDuILvwLg1v1KL8mQR+KFjghCrtpqaztZqcDt
    +2q2QoyulCgSzHbEGmi0EsdkPfg6mp0penssIFePYNI+/8u9HT4LuKMJX15hxBam7
    +dUHzICxBVC1lnHyYGjDuAMhe396lYAn8bCld1/L4NMGBCQ==
    +-----END CERTIFICATE-----
    + + +

    ǧ¾Ú¶É

    + +

    ¤Þ¤º¾ÚÌÀ½ñ¤Î¿½ÀÁ¤Î¾ðÊó¤ò³Îǧ¤¹¤ë¤³¤È¤Ç¡¢ + ǧ¾Ú¶É¤ÏÈëÌ©¸°¤Î»ý¤Á¼ç¤Î¿È¸µ¤òÊݾڤ·¤Þ¤¹¡£ + Î㤨¤Ð¡¢¥¢¥ê¥¹¤¬¸Ä¿Í¾ÚÌÀ½ñ¤ò¿½ÀÁ¤·¤¿¤È¤¹¤ë¤È¡¢ + ǧ¾Ú¶É¤Ï¥¢¥ê¥¹¤¬¾ÚÌÀ½ñ¤Î¿½ÀÁ¤¬¼çÄ¥¤¹¤ëÄ̤ê¤Î + ¿Íʪ¤À¤È¤¤¤¦¤³¤È¤ò³Îǧ¤·¤Ê¤¯¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£

    + +

    ¾ÚÌÀ½ñ³¬Áع½Â¤

    + +

    ǧ¾Ú¶É¤Ï¾¤Îǧ¾Ú¶É¤Ø¤Î¾ÚÌÀ½ñ¤òȯ¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ̤ÃΤξÚÌÀ½ñ¤òÄ´¤Ù¤ë»þ¤Ë¡¢¥¢¥ê¥¹¤Ï¤½¤Î¾ÚÌÀ½ñ¤Îȯ¹Ô¼Ô + ¤Ë¼«¿®¤¬»ý¤Æ¤ë¤Þ¤Ç¡¢È¯¹Ô¼Ô¤Î¾ÚÌÀ½ñ¤ò + ¤½¤Î¾å°Ì³¬ÁؤÎǧ¾Ú¶É¤ò¤¿¤É¤Ã¤ÆÄ´¤Ù¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¡Ö°­¼Á¤Ê¡×¾ÚÌÀ½ñ¤Î´í¸±À­¤ò¸º¤é¤¹¤¿¤á¡¢ + Èà½÷¤Ï¸Â¤é¤ì¤¿Ï¢º¿¤Îȯ¹Ô¼Ô¤Î¤ß¿®Íꤹ¤ë¤è¤¦¤Ë + ·è¤á¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    + + +

    ºÇ¾å°Ìǧ¾Ú¶É¤ÎºîÀ®

    + +

    Á°¤Ë½Ò¤Ù¤¿¤è¤¦¤Ë¡¢Á´¤Æ¤Î¾ÚÌÀ½ñ¤Ë¤Ä¤¤¤Æ¡¢ + ºÇ¾å°Ì¤Îǧ¾Ú¶É(CA)¤Þ¤Ç¤½¤ì¤¾¤ì¤Îȯ¹Ô¼Ô¤¬ + Âоݤοȸµ¾ÚÌÀ¤ÎÍ­¸úÀ­¤òÌÀ¤é¤«¤Ë¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ÌäÂê¤Ï¡¢Ã¯¤¬¤½¤ÎºÇ¾å°Ì¤Îǧ¾Úµ¡´Ø¤Î¾ÚÌÀ½ñ¤òÊݾڤ¹¤ë¤Î¤«¡¢ + ¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + ¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¸Â¤ê¡¢¾ÚÌÀ½ñ¤Ï¡Ö¼«¸Ê½ð̾¡×¤µ¤ì¤Þ¤¹¡£ + ¤Ä¤Þ¤ê¡¢¾ÚÌÀ½ñ¤Îȯ¹Ô¼Ô¤È¾ÚÌÀÂоݤ¬Æ±¤¸¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤½¤Î·ë²Ì¡¢¼«¸Ê½ð̾¤µ¤ì¤¿¾ÚÌÀ½ñ¤ò¿®ÍѤ¹¤ë¤Ë¤Ï + ºÙ¿´¤ÎÃí°Õ¤¬É¬ÍפǤ¹¡£ + ºÇ¾å°Ìǧ¾Ú¶É¤¬¸ø³«¸°¤ò¹­¤¯¸øɽ¤¹¤ë¤³¤È¤Ç¡¢ + ¤½¤Î¸°¤ò¿®Íꤹ¤ë¥ê¥¹¥¯¤òÄ㤯¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤â¤·¡¢Â¾¿Í¤¬¤½¤Îǧ¾Ú¶É¤Ë¤Ê¤ê¤¹¤Þ¤·¤¿»þ¤Ë¡¢¤½¤ì¤¬Ïª¸«¤·¤ä + ¤¹¤¤¤«¤é¤Ç¤¹¡£ + ¿¤¯¤Î¥Ö¥é¥¦¥¶¤Ïͭ̾¤Êǧ¾Ú¶É¤ò¿®Íꤹ¤ë¤è¤¦¤Ë + ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

    + +

    Thawte + ¤ä VeriSign + ¤Î¤è¤¦¤Ê¿¤¯¤Î²ñ¼Ò¤¬Ç§¾Ú¶É¤È¤·¤Æ³«Àߤ·¤Þ¤·¤¿¡£ + ¤³¤Î¤è¤¦¤Ê²ñ¼Ò¤Ï°Ê²¼¤Î¥µ¡¼¥Ó¥¹¤òÄ󶡤·¤Þ¤¹:

    + +
      +
    • ¾ÚÌÀ½ñ¿½ÀÁ¤Î³Îǧ
    • +
    • ¾ÚÌÀ½ñ¿½ÀÁ¤Î½èÍý
    • +
    • ¾ÚÌÀ½ñ¤Îȯ¹Ô¤È´ÉÍý
    • +
    + +

    ¼«Ê¬¤Çǧ¾Ú¶É¤òºî¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£ + ¥¤¥ó¥¿¡¼¥Í¥Ã¥È´Ä¶­¤Ç¤Ï´í¸±¤Ç¤¹¤¬¡¢ + ¸Ä¿Í¤ä¥µ¡¼¥Ð¤Î¿È¸µ¾ÚÌÀ¤¬´Êñ¤Ë¹Ô¤¨¤ëÁÈ¿¥¤Î + ¥¤¥ó¥È¥é¥Í¥Ã¥ÈÆâ¤Ç¤ÏÌò¤ËΩ¤Ä¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + + +

    ¾ÚÌÀ½ñ´ÉÍý

    + +

    ǧ¾Ú¶É¤Î³«ÀߤÏÅ°Ä줷¤¿´ÉÍý¡¢µ»½Ñ¡¢±¿ÍѤÎÂÎÀ©¤òɬÍפȤ¹¤ë + ÀÕǤ¤Î¤¢¤ë»Å»ö¤Ç¤¹¡£ + ǧ¾Ú¶É¤Ï¾ÚÌÀ½ñ¤òȯ¹Ô¤¹¤ë¤À¤±¤Ç¤Ê¤¯¡¢ + ´ÉÍý¤â¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¶ñÂÎŪ¤Ë¤Ï¡¢¾ÚÌÀ½ñ¤¬¤¤¤Ä¤Þ¤ÇÍ­¸ú¤«¤ò·èÄꤷ¡¢¹¹¿·¤·¡¢ + ¤Þ¤¿´û¤Ëȯ¹Ô¤µ¤ì¤¿¤¬¼º¸ú¤·¤¿¾ÚÌÀ½ñ¤Î¥ê¥¹¥È + (Certificate Revocation Lists ¤Þ¤¿¤Ï CRL) + ¤ò´ÉÍý¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢¥¢¥ê¥¹¤¬²ñ¼Ò¤«¤é¼Ò°÷¤È¤·¤Æ¾ÚÌÀ½ñ¤òÍ¿¤¨¤é¤ì¤¿¤È¤·¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¥¢¥ê¥¹¤¬²ñ¼Ò¤ò¼­¤á¤ë¤È¤­¤Ë¤Ï¾ÚÌÀ½ñ¤ò¼è¤ê¾Ã¤µ¤Ê¤±¤ì¤Ð + ¤¤¤±¤Ê¤¤¤È¤·¤Þ¤¹¡£ + ¾ÚÌÀ½ñ¤Ï¼¡¡¹¤È¿Í¤ËÅϤµ¤ì¤Æ¤¤¤¯¤â¤Î¤Ê¤Î¤Ç¡¢ + ¾ÚÌÀ½ñ¤½¤Î¤â¤Î¤«¤é¡¢¤½¤ì¤¬¼è¤ê¾Ã¤µ¤ì¤¿¤«È½ÃǤ¹¤ë¤³¤È¤Ï + ÉÔ²Äǽ¤Ç¤¹¡£ + ¤è¤Ã¤Æ¡¢¾ÚÌÀ½ñ¤ÎÍ­¸úÀ­¤òÄ´¤Ù¤ë¤È¤­¤Ë¤Ï¡¢ + ǧ¾Ú¶É¤ËÏ¢Íí¤·¤Æ CRL ¤ò¾È¹ç¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ÉáÄ̤³¤Î²áÄø¤Ï¼«Æ°²½¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    Ãí°Õ

    +

    ¥Ç¥Õ¥©¥ë¥È¤Ç¥Ö¥é¥¦¥¶¤ËÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤Ç§¾Ú¶É¤ò»È¤Ã¤¿¾ì¹ç¡¢ + ǧ¾Ú¶É¤Î¾ÚÌÀ½ñ¤ò¥Ö¥é¥¦¥¶¤ËÆɤ߹þ¤ó¤Ç¡¢ + ¥Ö¥é¥¦¥¶¤¬¤½¤Îǧ¾Ú¶É¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿¥µ¡¼¥Ð¤Î¾ÚÌÀ½ñ¤ò + Í­¸ú²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + °ìÅÙÆɤ߹þ¤Þ¤ì¤ë¤È¡¢¤½¤Îǧ¾Ú¶É¤Ë¤è¤Ã¤Æ½ð̾¤µ¤ì¤¿Á´¤Æ¤Î + ¾ÚÌÀ½ñ¤ò¼õ¤±Æþ¤ì¤ë¤¿¤á¡¢´í¸±¤òȼ¤¤¤Þ¤¹¡£

    +
    + + + +
    top
    +
    +

    Secure Sockets Layer (SSL)

    + +

    Secure Sockets Layer ¥×¥í¥È¥³¥ë¤Ï¿®ÍêÀ­¤Î¤¢¤ë¥³¥Í¥¯¥·¥ç¥ó·¿¤Î +¥Í¥Ã¥È¥ï¡¼¥¯ÁؤΥץí¥È¥³¥ë(Î㤨¤Ð¡¢TCP/IP)¤È +¥¢¥×¥ê¥±¡¼¥·¥ç¥óÁؤΥץí¥È¥³¥ë(Î㤨¤Ð¡¢HTTP) +¤Î´Ö¤ËÃÖ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +SSL ¤Ï¡¢Áê¸ßǧ¾Ú¤Ë¤è¤Ã¤Æ¥µ¡¼¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È´Ö¤Î°ÂÁ´¤ÊÄÌ¿®¤ò¡¢ +ÅŻҽð̾¤Ë¤è¤Ã¤Æ¥Ç¡¼¥¿¤Î´°Á´À­¤ò¡¢ +¤½¤·¤Æ°Å¹æ²½¤Ë¤è¤Ã¤Æ¥×¥é¥¤¥Ð¥·¤òÄ󶡤·¤Þ¤¹¡£

    + +

    SSL ¥×¥í¥È¥³¥ë¤Ï°Å¹æ²½¡¢¥À¥¤¥¸¥§¥¹¥È¡¢ÅŻҽð̾¤Ë¤Ä¤¤¤Æ¡¢ +ÍÍ¡¹¤Ê¥¢¥ë¥´¥ê¥º¥à¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Æ¤¤¤Þ¤¹¡£ +¤³¤¦¤¹¤ë¤³¤È¤Ç¡¢Ë¡¤äÍ¢½Ð¤Îµ¬À©¤ò¹Íθ¤ËÆþ¤ì¤Æ¡¢¥µ¡¼¥Ð¤Ë¹ç¤ï¤»¤¿ +¥¢¥ë¥´¥ê¥º¥à¤òÁª¤Ö¤³¤È¤¬¤Ç¤­¡¢¤Þ¤¿¡¢¿·¤·¤¤¥¢¥ë¥´¥ê¥º¥à¤ò +ÍøÍѤ·¤Æ¤¤¤¯¤³¤È¤â²Äǽ¤Ë¤·¤Æ¤¤¤Þ¤¹¡£ +¥¢¥ë¥´¥ê¥º¥à¤ÎÁªÂò¤Ï¥×¥í¥È¥³¥ë¥»¥Ã¥·¥ç¥ó³«»Ï»þ¤Ë +¥µ¡¼¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È´Ö¤Ç¼è¤ê·è¤á¤é¤ì¤Þ¤¹¡£

    + +

    ɽ4: SSL ¥×¥í¥È¥³¥ë¤Î¥Ð¡¼¥¸¥ç¥ó

    + + + + + + + + + + + + + + + + + + + +
    ¥Ð¡¼¥¸¥ç¥ó½ÐŵÀâÌÀ¥Ö¥é¥¦¥¶¤Î¥µ¥Ý¡¼¥È
    SSL v2.0Vendor Standard (Netscape Corp. ¤è¤ê) [SSL2]¼ÂÁõ¤¬¸½Â¸¤¹¤ë½é¤á¤Æ¤Î SSL ¥×¥í¥È¥³¥ë- NS Navigator 1.x/2.x
    + - MS IE 3.x
    + - Lynx/2.8+OpenSSL
    SSL v3.0Expired Internet Draft (Netscape Corp. ¤è¤ê) [SSL3]ÆÃÄê¤Î¥»¥­¥å¥ê¥Æ¥£¹¶·â¤òËɤ°¤¿¤á¤Î²þÄû¡¢ + ÈóRSA °Å¹æ¤ÎÄɲᢾÚÌÀ½ñ³¬Áع½Â¤¤Î¥µ¥Ý¡¼¥È- NS Navigator 2.x/3.x/4.x
    + - MS IE 3.x/4.x
    + - Lynx/2.8+OpenSSL
    TLS v1.0Proposed Internet Standard (IETF ¤è¤ê) [TLS1]MAC ¥ì¥¤¥ä¤ò HMAC ¤Ø¹¹¿·¡¢¥Ö¥í¥Ã¥¯°Å¹æ¤Î block + padding¡¢¥á¥Ã¥»¡¼¥¸½ç½ø¤Îɸ½à²½¡¢·Ù¹ðʸ¤Î½¼¼Â¤Ê¤É¤Î¤¿¤á + SSL 3.0 ¤ò²þÄû¡£- Lynx/2.8+OpenSSL
    + + +

    ɽ4¤Ë¼¨¤µ¤ì¤ë¤È¤ª¤ê¡¢SSL ¥×¥í¥È¥³¥ë¤Ë¤Ï +¤¤¤¯¤Ä¤â¤Î¥Ð¡¼¥¸¥ç¥ó¤¬¤¢¤ê¤Þ¤¹¡£ +ɽ¤Ë¤â½ñ¤«¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢SSL 3.0 ¤ÎÍøÅÀ¤Î°ì¤Ä¤Ï +¾ÚÌÀ½ñ³¬Áع½Â¤¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤³¤È¤Ç¤¹¡£ +¤³¤Îµ¡Ç½¤Ë¤è¤Ã¤Æ¡¢¥µ¡¼¥Ð¤Ï¼«Ê¬¤Î¾ÚÌÀ½ñ¤Ë²Ã¤¨¤Æ¡¢ +ȯ¹Ô¼Ô¤Î¾ÚÌÀ½ñ¤ò¥Ö¥é¥¦¥¶¤ËÅϤ¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +¾ÚÌÀ½ñ³¬Áع½Â¤¤Ë¤è¤Ã¤Æ¡¢ +¥Ö¥é¥¦¥¶¤Ëȯ¹Ô¼Ô¤Î¾ÚÌÀ½ñ¤¬Ä¾ÀÜÅÐÏ¿¤µ¤ì¤Æ¤¤¤Ê¤¯¤Æ¤â¡¢ +³¬ÁؤÎÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ì¤Ð¡¢ +¥Ö¥é¥¦¥¶¤Ï¥µ¡¼¥Ð¤Î¾ÚÌÀ½ñ¤òÍ­¸ú²½¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ +SSL 3.0 ¤Ï¸½ºß Internet Engineering Task Force (IETF) +¤Ë¤è¤Ã¤Æ³«È¯¤µ¤ì¤Æ¤¤¤ë Transport Layer Security +[TLS] ¥×¥í¥È¥³¥ëɸ½àµ¬³Ê¤Î´ðÁäȤʤäƤ¤¤Þ¤¹¡£

    + +

    ¥»¥Ã¥·¥ç¥ó¤Î³ÎΩ

    + +

    ¿Þ1¤Ç¼¨¤µ¤ì¤ë¤è¤¦¤Ë¡¢ + ¥»¥Ã¥·¥ç¥ó¤Î³ÎΩ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð´Ö¤Î + ¥Ï¥ó¥É¥·¥§¡¼¥¯¥·¡¼¥¯¥¨¥ó¥¹¤Ë¤è¤Ã¤Æ¹Ô¤Ê¤ï¤ì¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤¬¾ÚÌÀ½ñ¤òÄ󶡤¹¤ë¤«¡¢¥¯¥é¥¤¥¢¥ó¥È¤Î¾ÚÌÀ½ñ¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ë¤« + ¤È¤¤¤¦¥µ¡¼¥Ð¤ÎÀßÄê¤Ë¤è¤ê¡¢¤³¤Î¥·¡¼¥¯¥¨¥ó¥¹¤Ï°Û¤Ê¤ë¤â¤Î¤È¤Ê¤ê¤Þ¤¹¡£ + °Å¹æ¾ðÊó¤Î´ÉÍý¤Î¤¿¤á¤Ë¡¢ÄɲäΥϥó¥É¥·¥§¡¼¥¯²áÄø¤¬É¬Íפˤʤë + ¾ì¹ç¤â¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤Îµ­»ö¤Ç¤Ï + ¤è¤¯¤¢¤ë¥·¥Ê¥ê¥ª¤ò¼êû¤ËÀâÌÀ¤·¤Þ¤¹¡£ + Á´¤Æ¤Î²ÄǽÀ­¤Ë¤Ä¤¤¤Ï¡¢SSL »ÅÍͽñ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    Ãí°Õ

    +

    °ìÅÙ SSL ¥»¥Ã¥·¥ç¥ó¤¬³ÎΩ¤¹¤ë¤È¡¢¥»¥Ã¥·¥ç¥ó¤òºÆÍøÍѤ¹¤ë¤³¤È¤Ç¡¢ + ¥»¥Ã¥·¥ç¥ó¤ò³«»Ï¤¹¤ë¤¿¤á¤Î¿¤¯¤Î²áÄø¤ò·«¤êÊÖ¤¹¤È¤¤¤¦ + ¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤Î»¼º¤òËɤ®¤Þ¤¹¡£ + ¤½¤Î¤¿¤á¡¢¥µ¡¼¥Ð¤ÏÁ´¤Æ¤Î¥»¥Ã¥·¥ç¥ó¤Ë°ì°Õ¤Ê¥»¥Ã¥·¥ç¥ó¼±ÊÌ̾¤ò + ³ä¤êÅö¤Æ¡¢¥µ¡¼¥Ð¤Ë¥­¥ã¥Ã¥·¥å¤·¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï¼¡²ó¤«¤é + (¼±ÊÌ̾¤¬¥µ¡¼¥Ð¤Î¥­¥ã¥Ã¥·¥å¤Ç´ü¸ÂÀÚ¤ì¤Ë¤Ê¤ë¤Þ¤Ç¤Ï) + ¥Ï¥ó¥É¥·¥§¡¼¥¯¤Ê¤·¤ÇÀܳ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    + +

    +
    + ¿Þ1: SSL + ¥Ï¥ó¥É¥·¥§¡¼¥¯¥·¡¼¥¯¥¨¥ó¥¹³µÎ¬

    + +

    ¥µ¡¼¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È¤Ç»È¤ï¤ì¤ë + ¥Ï¥ó¥É¥·¥§¡¼¥¯¥·¡¼¥¯¥¨¥ó¥¹¤ÎÍ×ÁǤò°Ê²¼¤Ë¼¨¤·¤Þ¤¹:

    + +
      +
    1. ¥Ç¡¼¥¿ÄÌ¿®¤Ë»È¤ï¤ì¤ë°Å¹æ¥¹¥¤¡¼¥È¤Î¼è¤ê·è¤á
    2. +
    3. ¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð´Ö¤Ç¤Î¥»¥Ã¥·¥ç¥ó¸°¤Î³ÎΩ¤È¶¦Í­
    4. +
    5. ¥ª¥×¥·¥ç¥ó¤È¤·¤Æ¡¢¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ¹¤ë¥µ¡¼¥Ð¤Îǧ¾Ú
    6. +
    7. ¥ª¥×¥·¥ç¥ó¤È¤·¤Æ¡¢¥µ¡¼¥Ð¤ËÂФ¹¤ë¥¯¥é¥¤¥¢¥ó¥È¤Îǧ¾Ú
    8. +
    + +

    Âè°ì¥¹¥Æ¥Ã¥×¤Î°Å¹æ¥¹¥¤¡¼¥È¼è¤ê·è¤á¤Ë¤è¤Ã¤Æ¡¢ + ¥µ¡¼¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È¤Ï¤½¤ì¤¾¤ì¤Ë¤¢¤Ã¤¿ + °Å¹æ¥¹¥¤¡¼¥È¤òÁª¤Ö¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + SSL3.0 ¥×¥í¥È¥³¥ë¤Î»ÅÍͽñ¤Ï 31 ¤Î°Å¹æ¥¹¥¤¡¼¥È¤òÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£ + °Å¹æ¥¹¥¤¡¼¥È¤Ï°Ê²¼¤Î¥³¥ó¥Ý¡¼¥Í¥ó¥È¤Ë¤è¤êÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹:

    + +
      +
    • ¸°¤Î¸ò´¹¼êÃÊ
    • +
    • ¥Ç¡¼¥¿ÄÌ¿®¤Î°Å¹æ½Ñ
    • +
    • Message Authentication Code (MAC) ºîÀ®¤Î¤¿¤á¤Î + ¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È
    • +
    + +

    ¤³¤ì¤é¤Î»°¤Ä¤ÎÍ×ÁǤϰʲ¼¤Î¥»¥¯¥·¥ç¥ó¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    + + +

    ¸°¤Î¸ò´¹¼êÃÊ

    + +

    ¸°¤Î¸ò´¹¼êÃʤϥ¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥Ç¡¼¥¿ÄÌ¿®¤Ë»È¤ï¤ì¡¢ + ¶¦Í­¤µ¤ì¤ëÂоΰŹ渰¤ò¤É¤Î¤è¤¦¤Ë¤¬¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð¤Ç + ¼è¤ê·è¤á¤ë¤«¤òÄêµÁ¤·¤Þ¤¹¡£ + SSL 2.0 ¤Ï RSA ¸°¸ò´¹¤·¤«»È¤¤¤Þ¤»¤ó¤¬¡¢ + SSL 3.0 ¤Ï¾ÚÌÀ½ñ¤¬»È¤ï¤ì¤ë¤È¤­¤Ï RSA ¸°¸ò´¹¤ò»È¤¤¡¢ + ¾ÚÌÀ½ñ¤¬Ìµ¤¯¡¢¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð¤Î»öÁ°¤ÎÄÌ¿®¤¬Ìµ¤¤¾ì¹ç¤Ï + Diffie-Hellman ¸°¸ò´¹¤ò»È¤¦ + ¤Ê¤ÉÍÍ¡¹¤Ê¸°¸ò´¹¥¢¥ë¥´¥ê¥º¥à¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£

    + +

    ¸°¤Î¸ò´¹ÊýË¡¤Ë¤ª¤±¤ë°ì¤Ä¤ÎÁªÂò»è¤ÏÅŻҽð̾¤Ç¤¹¡£ + ÅŻҽð̾¤ò»È¤¦¤«¤É¤¦¤«¡¢¤Þ¤¿¡¢ + ¤É¤Î¼ïÎà¤Î½ð̾¤ò»È¤¦¤«¤È¤¤¤¦ÁªÂò¤¬¤¢¤ê¤Þ¤¹¡£ + ÈëÌ©¸°¤Ç½ð̾¤¹¤ë¤³¤È¤Ç¶¦Í­¸°¤òÀ¸À®¤¹¤·¡¢¾ðÊó¸ò´¹¤¹¤ë»þ¤Î + ¥Þ¥ó¡¦¥¤¥ó¡¦¥¶¡¦¥ß¥É¥ë¹¶·â¤òËɤ°¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + [AC96, p516]

    + + +

    ¥Ç¡¼¥¿ÄÌ¿®¤Î°Å¹æ½Ñ

    + +

    SSL ¤Ï¥»¥Ã¥·¥ç¥ó¤Î¥á¥Ã¥»¡¼¥¸¤Î°Å¹æ²½¤ËÁ°½Ò¤·¤¿ + ½¾Íè·¿°Å¹æ(ÂоΰŹæ)¤òÍѤ¤¤Þ¤¹¡£ + °Å¹æ²½¤·¤Ê¤¤¤È¤¤¤¦ÁªÂò»è¤â´Þ¤á¶å¤Ä¤ÎÁªÂò»è¤¬¤¢¤ê¤Þ¤¹:

    + +
      +
    • °Å¹æ²½¤Ê¤·
    • +
    • ¥¹¥È¥ê¡¼¥à°Å¹æ +
        +
      • 40-bit ¸°¤Ç¤Î RC4
      • +
      • 128-bit ¸°¤Ç¤Î RC4
      • +
    • +
    • CBC ¥Ö¥í¥Ã¥¯°Å¹æ +
      • 40 bit ¸°¤Ç¤Î RC2
      • +
      • 40 bit ¸°¤Ç¤Î DES
      • +
      • 56 bit ¸°¤Ç¤Î DES
      • +
      • 168 bit ¸°¤Ç¤Î Triple-DES
      • +
      • Idea (128 bit ¸°)
      • +
      • Fortezza (96 bit ¸°)
      • +
    • +
    + +

    ¤³¤³¤Ç¤Î CBC ¤È¤Ï°Å¹æ¥Ö¥í¥Ã¥¯Ï¢º¿ (Cipher Block Chaining) + ¤Îά¤Ç¡¢°ì¤ÄÁ°¤Î°Å¹æ²½¤µ¤ì¤¿°Å¹æʸ¤Î°ìÉô¤¬ + ¥Ö¥í¥Ã¥¯¤Î°Å¹æ²½¤Ë»È¤ï¤ì¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + DES ¤Ï¥Ç¡¼¥¿°Å¹æ²½É¸½àµ¬³Ê (Data Encryption Standard) + [AC96, ch12] ¤Îά¤Ç¡¢ + DES40 ¤ä 3DES_EDE ¤ò´Þ¤à¤¤¤¯¤Ä¤â¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡£ + Idea ¤ÏºÇ¹â¤Ê¤â¤Î¤Î°ì¤Ä¤Ç¡¢°Å¹æ½ÑŪ¤Ë¤Ï¸½ºß¤¢¤ëÃæ¤Ç + ºÇ¤â¶¯ÎϤʤâ¤Î¤Ç¤¹¡£ + RC2 ¤Ï RSA DSI ¤Ë¤è¤ëÆÈÀêŪ¤Ê¥¢¥ë¥´¥ê¥º¥à¤Ç¤¹¡£ + [AC96, + ch13]

    + + +

    ¥À¥¤¥¸¥§¥¹¥È´Ø¿ô

    + +

    + ¥À¥¤¥¸¥§¥¹¥È´Ø¿ô¤ÎÁªÂò¤Ï¥ì¥³¡¼¥É¥æ¥Ë¥Ã¥È¤«¤é¤É¤Î¤è¤¦¤Ë¥À¥¤¥¸¥§¥¹¥È¤¬À¸À®¤µ¤ì¤ë¤«¤ò·èÄꤷ¤Þ¤¹¡£ + SSL ¤Ï°Ê²¼¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹:

    + +
      +
    • ¥À¥¤¥¸¥§¥¹¥È¤Ê¤·
    • +
    • MD5 (128-bit ¥Ï¥Ã¥·¥å)
    • +
    • Secure Hash Algorithm (SHA-1) (160-bit ¥Ï¥Ã¥·¥å)
    • +
    + +

    ¥á¥Ã¥»¡¼¥¸¥À¥¤¥¸¥§¥¹¥È¤Ï Message Authentication Code (MAC) + ¤ÎÀ¸À®¤Ë»È¤ï¤ì¡¢¥á¥Ã¥»¡¼¥¸¤È¶¦¤Ë°Å¹æ²½¤µ¤ì¡¢¥á¥Ã¥»¡¼¥¸¤Î¿®ÍѤò + Ä󶡤·¡¢¥ê¥×¥ì¥¤¹¶·â¤òËɤ®¤Þ¤¹¡£

    + + +

    ¥Ï¥ó¥É¥·¥§¡¼¥¯¥·¡¼¥¯¥¨¥ó¥¹¥×¥í¥È¥³¥ë

    + +

    ¥Ï¥ó¥É¥·¥§¡¼¥¯¥·¡¼¥¯¥¨¥ó¥¹¤Ï»°¤Ä¤Î¥×¥í¥È¥³¥ë¤ò»È¤¤¤Þ¤¹:

    + +
      +
    • SSL ¥Ï¥ó¥É¥·¥§¡¼¥¯¥×¥í¥È¥³¥ë¤Ï + ¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð´Ö¤Ç¤Î SSL ¥»¥Ã¥·¥ç¥ó¤Î³ÎΩ¤Ë»È¤ï¤ì¤Þ¤¹¡£
    • +
    • SSL °Å¹æ»ÅÍÍÊѹ¹¥×¥í¥È¥³¥ë¤Ï + ¥»¥Ã¥·¥ç¥ó¤Ç¤Î°Å¹æ¥¹¥¤¡¼¥È¤Î¼è¤ê·è¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£
    • +
    • SSL ·Ù¹ð¥×¥í¥È¥³¥ë¤Ï + ¥¯¥é¥¤¥¢¥ó¥È¥µ¡¼¥Ð´Ö¤Ç SSL ¥¨¥é¡¼¤òÅÁ㤹¤ë¤Î¤Ë»È¤ï¤ì¤Þ¤¹¡£
    • +
    + +

    »°¤Ä¤Î¥×¥í¥È¥³¥ë¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥È¥³¥ë¥Ç¡¼¥¿¤È¤È¤â¤Ë¡¢ + ¿Þ2¤Ë¼¨¤¹¤È¤ª¤ê SSL ¥ì¥³¡¼¥É¥×¥í¥È¥³¥ë + ¤Ç¥«¥×¥»¥ë²½¤µ¤ì¤Þ¤¹¡£ + ¥«¥×¥»¥ë²½¤µ¤ì¤¿¥×¥í¥È¥³¥ë¤Ï¥Ç¡¼¥¿¤ò¸¡ºº¤·¤Ê¤¤ + ²¼ÁؤΥץí¥È¥³¥ë¤Ë¤è¤Ã¤Æ¥Ç¡¼¥¿¤È¤·¤ÆÅÁ㤵¤ì¤Þ¤¹¡£ + ¥«¥×¥»¥ë²½¤µ¤ì¤¿¥×¥í¥È¥³¥ë¤Ï²¼ÁؤΥץí¥È¥³¥ë¤Ë´Ø¤·¤Æ°ìÀÚ´ØÃΤ·¤Þ¤»¤ó¡£

    + +

    +
    + ¿Þ2: SSL ¥×¥í¥È¥³¥ë¥¹¥¿¥Ã¥¯ +

    + +

    + ¥ì¥³¡¼¥É¥×¥í¥È¥³¥ë¤Ë¤è¤ë SSL ¥³¥ó¥È¥í¡¼¥ë¥×¥í¥È¥³¥ë¤Î¥«¥×¥»¥ë²½¤Ï¡¢ + ¥¢¥¯¥Æ¥£¥Ö¤Ê¥»¥Ã¥·¥ç¥ó¤ÎÆó²óÌܤÎÄÌ¿®¤¬¤¢¤Ã¤¿¾ì¹ç¡¢ + ¥³¥ó¥È¥í¡¼¥ë¥×¥í¥È¥³¥ë¤¬°ÂÁ´¤Ç¤¢¤ë¤³¤È¤ò°ÕÌ£¤·¤Þ¤¹¡£ + ´û¤Ë¥»¥Ã¥·¥ç¥ó¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢Null °Å¹æ¥¹¥¤¡¼¥È¤¬»È¤ï¤ì¡¢ + °Å¹æ²½¤Ï¹Ô¤Ê¤ï¤ì¤º¡¢¥»¥Ã¥·¥ç¥ó¤¬³ÎΩ¤¹¤ë¤Þ¤Ç¤Ï + ¥À¥¤¥¸¥§¥¹¥È¤â̵¤¤¾õÂ֤Ȥʤê¤Þ¤¹¡£

    + + +

    ¥Ç¡¼¥¿ÄÌ¿®

    + +

    ¿Þ3¤Ë¼¨¤µ¤ì¤ë SSL ¥ì¥³¡¼¥É¥×¥í¥È¥³¥ë + ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤È¥µ¡¼¥Ð´Ö¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ä + SSL ¥³¥ó¥È¥í¡¼¥ë¥Ç¡¼¥¿¤ÎÄÌ¿®¤Ë»È¤ï¤ì¤Þ¤¹¡£ + ¤³¤Î¥Ç¡¼¥¿¤Ï¤è¤ê¾®¤µ¤¤¥æ¥Ë¥Ã¥È¤Ëʬ¤±¤é¤ì¤¿¤ê¡¢ + ¤¤¤¯¤Ä¤«¤Î¹âµé¥×¥í¥È¥³¥ë¤ò¤Þ¤È¤á¤Æ°ì¥æ¥Ë¥Ã¥È¤È¤·¤ÆÄÌ¿®¤¬ + ¹Ô¤Ê¤ï¤ì¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£ + ¥Ç¡¼¥¿¤ò°µ½Ì¤·¡¢¥À¥¤¥¸¥§¥¹¥È½ð̾¤òźÉÕ¤·¤Æ¡¢ + ¤³¤ì¤é¤Î¥æ¥Ë¥Ã¥È¤ò°Å¹æ²½¤·¤¿¤Î¤Á¡¢¥Ù¡¼¥¹¤È¤Ê¤Ã¤Æ¤¤¤ë + ¿®ÍêÀ­¤Î¤¢¤ë¥È¥é¥ó¥¹¥Ý¡¼¥È¥×¥í¥È¥³¥ë¤òÍѤ¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + (Ãí°Õ: ¸½ºß¥á¥¸¥ã¡¼¤Ê SLL ¼ÂÁõ¤Ç°µ½Ì¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤â¤Î¤Ï¤¢¤ê¤Þ¤»¤ó)

    + +

    +
    + ¿Þ 3: SSL ¥ì¥³¡¼¥É¥×¥í¥È¥³¥ë +

    + + +

    HTTP ÄÌ¿®¤Î°ÂÁ´²½

    + +

    ¤è¤¯¤¢¤ë SSL ¤Î»È¤¤Êý¤Ï¥Ö¥é¥¦¥¶¤È¥¦¥§¥Ö¥µ¡¼¥Ð´Ö¤Î HTTP ÄÌ¿® + ¤Î°ÂÁ´²½¤Ç¤¹¡£ + ¤³¤ì¤Ï¡¢½¾Íè¤Î°ÂÁ´¤Ç¤Ï¤Ê¤¤ HTTP ¤Î»ÈÍѤò½ü³°¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + °ÂÁ´²½¤µ¤ì¤¿¤â¤Î¤Ï¼ç¤Ë SSH ¾å¤ÎÉáÄ̤ΠHTTP ¤Ç¡¢HTTPS ¤È¸Æ¤Ð¤ì¤Þ¤¹¡£ + Â礭¤Ê°ã¤¤¤Ï¡¢URL ¥¹¥­¡¼¥à¤Ë http ¤ÎÂå¤ï¤ê¤Ë https + ¤òÍѤ¤¡¢¥µ¡¼¥Ð¤¬Ê̤Υݡ¼¥È¤ò»È¤¦¤³¤È¤Ç¤¹ (¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï443)¡£ + ¤³¤ì¤¬¼ç¤Ë mod_ssl ¤¬ Apache ¥¦¥§¥Ö¥µ¡¼¥Ð¤ËÄ󶡤¹¤ëµ¡Ç½¤Ç¤¹¡£

    + +
    top
    +
    +

    »²¹Íʸ¸¥

    + +
    +
    [AC96]
    +
    Bruce Schneier, Applied Cryptography, 2nd Edition, Wiley, +1996. See http://www.counterpane.com/ for various other materials by Bruce +Schneier.
    + +
    [X208]
    +
    ITU-T Recommendation X.208, Specification of Abstract Syntax Notation +One (ASN.1), 1988. See for instance http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.208-198811-I. +
    + +
    [X509]
    +
    ITU-T Recommendation X.509, The Directory - Authentication +Framework. See for instance http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.509. +
    + +
    [PKCS]
    +
    Public Key Cryptography Standards (PKCS), +RSA Laboratories Technical Notes, See http://www.rsasecurity.com/rsalabs/pkcs/.
    + +
    [MIME]
    +
    N. Freed, N. Borenstein, Multipurpose Internet Mail Extensions +(MIME) Part One: Format of Internet Message Bodies, RFC2045. +See for instance http://ietf.org/rfc/rfc2045.txt.
    + +
    [SSL2]
    +
    Kipp E.B. Hickman, The SSL Protocol, 1995. See http://www.netscape.com/eng/security/SSL_2.html.
    + +
    [SSL3]
    +
    Alan O. Freier, Philip Karlton, Paul C. Kocher, The SSL Protocol +Version 3.0, 1996. See http://www.netscape.com/eng/ssl3/draft302.txt.
    + +
    [TLS1]
    +
    Tim Dierks, Christopher Allen, The TLS Protocol Version 1.0, +1999. See http://ietf.org/rfc/rfc2246.txt.
    +
    +
    +
    +

    Available Languages:  en  | + ja 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/ssl/ssl_intro.xml b/trunk/docs/manual/ssl/ssl_intro.xml new file mode 100644 index 0000000000..9dbeb078da --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.xml @@ -0,0 +1,672 @@ + + + + + + + + +SSL/TLS + + SSL/TLS Strong Encryption: An Introduction + + +
    +

    The nice thing about standards is that there are so many to choose +from. And if you really don't like all the standards you just have to +wait another year until the one arises you are looking for.

    + +

    -- A. Tanenbaum, "Introduction to +Computer Networks"

    +
    + +

    As an introduction this chapter is aimed at readers who are familiar +with the Web, HTTP, and Apache, but are not security experts. It is not +intended to be a definitive guide to the SSL protocol, nor does it discuss +specific techniques for managing certificates in an organization, or the +important legal issues of patents and import and export restrictions. +Rather, it is intended to provide a common background to mod_ssl users by +pulling together various concepts, definitions, and examples as a starting +point for further exploration.

    + +

    The presented content is mainly derived, with permission by the author, +from the article Introducing +SSL and Certificates using SSLeay from Frederick J. Hirsch, of The +Open Group Research Institute, which was published in Web Security: A Matter of +Trust, World Wide Web Journal, Volume 2, Issue 3, Summer 1997. +Please send any positive feedback to Frederick Hirsch (the original +article author) and all negative feedback to Ralf S. Engelschall (the +mod_ssl author).

    +
    + +
    +Cryptographic Techniques +

    Understanding SSL requires an understanding of cryptographic +algorithms, message digest functions (aka. one-way or hash functions), and +digital signatures. These techniques are the subject of entire books (see +for instance [AC96]) and provide the basis for privacy, +integrity, and authentication.

    + +
    +Cryptographic Algorithms +

    Suppose Alice wants to send a message to her bank to transfer some + money. Alice would like the message to be private, since it will + include information such as her account number and transfer amount. One + solution is to use a cryptographic algorithm, a technique that would + transform her message into an encrypted form, unreadable except by + those it is intended for. Once in this form, the message may only be + interpreted through the use of a secret key. Without the key the + message is useless: good cryptographic algorithms make it so difficult + for intruders to decode the original text that it isn't worth their + effort.

    + +

    There are two categories of cryptographic algorithms: conventional + and public key.

    + +
    +
    Conventional cryptography
    +
    also known as symmetric cryptography, requires the sender and + receiver to share a key: a secret piece of information that may be + used to encrypt or decrypt a message. If this key is secret, then + nobody other than the sender or receiver may read the message. If + Alice and the bank know a secret key, then they may send each other + private messages. The task of privately choosing a key before + communicating, however, can be problematic.
    + +
    Public key cryptography
    +
    also known as asymmetric cryptography, solves the key exchange + problem by defining an algorithm which uses two keys, each of which + may be used to encrypt a message. If one key is used to encrypt a + message then the other must be used to decrypt it. This makes it + possible to receive secure messages by simply publishing one key + (the public key) and keeping the other secret (the private key).
    +
    + +

    Anyone may encrypt a message using the public key, but only the + owner of the private key will be able to read it. In this way, Alice + may send private messages to the owner of a key-pair (the bank), by + encrypting it using their public key. Only the bank will be able to + decrypt it.

    +
    + +
    +Message Digests +

    Although Alice may encrypt her message to make it private, there + is still a concern that someone might modify her original message or + substitute it with a different one, in order to transfer the money + to themselves, for instance. One way of guaranteeing the integrity + of Alice's message is to create a concise summary of her message and + send this to the bank as well. Upon receipt of the message, the bank + creates its own summary and compares it with the one Alice sent. If + they agree then the message was received intact.

    + +

    A summary such as this is called a message digest, one-way +function or hash function. Message digests are used to create +short, fixed-length representations of longer, variable-length messages. +Digest algorithms are designed to produce unique digests for different +messages. Message digests are designed to make it too difficult to determine +the message from the digest, and also impossible to find two different +messages which create the same digest -- thus eliminating the possibility of +substituting one message for another while maintaining the same digest.

    +

    Another challenge that Alice faces is finding a way to send the digest to the +bank securely; when this is achieved, the integrity of the associated message +is assured. One way to do this is to include the digest in a digital +signature.

    +
    + +
    Digital Signatures +

    When Alice sends a message to the bank, the bank needs to ensure that the +message is really from her, so an intruder does not request a transaction +involving her account. A digital signature, created by Alice and +included with the message, serves this purpose.

    + +

    Digital signatures are created by encrypting a digest of the message, +and other information (such as a sequence number) with the sender's +private key. Though anyone may decrypt the signature using the public +key, only the signer knows the private key. This means that only they may +have signed it. Including the digest in the signature means the signature is +only good for that message; it also ensures the integrity of the message since +no one can change the digest and still sign it.

    +

    To guard against interception and reuse of the signature by an intruder at a +later date, the signature contains a unique sequence number. This protects +the bank from a fraudulent claim from Alice that she did not send the message +-- only she could have signed it (non-repudiation).

    +
    +
    + + +
    +Certificates +

    Although Alice could have sent a private message to the bank, signed +it, and ensured the integrity of the message, she still needs to be sure +that she is really communicating with the bank. This means that she needs +to be sure that the public key she is using corresponds to the bank's +private key. Similarly, the bank also needs to verify that the message +signature really corresponds to Alice's signature.

    + +

    If each party has a certificate which validates the other's identity, +confirms the public key, and is signed by a trusted agency, then they both +will be assured that they are communicating with whom they think they are. +Such a trusted agency is called a Certificate Authority, and +certificates are used for authentication.

    + +
    +Certificate Contents +

    A certificate associates a public key with the real identity of + an individual, server, or other entity, known as the subject. As + shown in Table 1, information about the subject + includes identifying information (the distinguished name), and the + public key. It also includes the identification and signature of the + Certificate Authority that issued the certificate, and the period of + time during which the certificate is valid. It may have additional + information (or extensions) as well as administrative information + for the Certificate Authority's use, such as a serial number.

    + +
    + Table 1: Certificate Information + + + + + + + + + + + + + +
    SubjectDistinguished Name, Public Key
    IssuerDistinguished Name, Signature
    Period of ValidityNot Before Date, Not After Date
    Administrative InformationVersion, Serial Number
    Extended InformationBasic Constraints, Netscape Flags, etc.
    +
    + +

    A distinguished name is used to provide an identity in a specific + context -- for instance, an individual might have a personal + certificate as well as one for their identity as an employee. + Distinguished names are defined by the X.509 standard [X509], which defines the fields, field names, and + abbreviations used to refer to the fields (see Table + 2).

    + +
    + Table 2: Distinguished Name Information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DN FieldAbbrev.DescriptionExample
    Common NameCNName being certifiedCN=Joe Average
    Organization or CompanyOName is associated with this
    organization
    O=Snake Oil, Ltd.
    Organizational UnitOUName is associated with this
    organization unit, such + as a department
    OU=Research Institute
    City/LocalityLName is located in this CityL=Snake City
    State/ProvinceSTName is located in this State/ProvinceST=Desert
    CountryCName is located in this Country (ISO code)C=XZ
    +
    + +

    A Certificate Authority may define a policy specifying which + distinguished field names are optional, and which are required. It + may also place requirements upon the field contents, as may users of + certificates. As an example, a Netscape browser requires that the + Common Name for a certificate representing a server has a name which + matches a wildcard pattern for the domain name of that server, such + as *.snakeoil.com.

    + +

    The binary format of a certificate is defined using the ASN.1 + notation [X208] [PKCS]. This + notation defines how to specify the contents, and encoding rules + define how this information is translated into binary form. The binary + encoding of the certificate is defined using Distinguished Encoding + Rules (DER), which are based on the more general Basic Encoding Rules + (BER). For those transmissions which cannot handle binary, the binary + form may be translated into an ASCII form by using Base64 encoding + [MIME]. This encoded version is called PEM encoded + (the name comes from "Privacy Enhanced Mail"), when placed between + begin and end delimiter lines as illustrated in the following + example.

    + + + Example of a PEM-encoded certificate (snakeoil.crt) +
    -----BEGIN CERTIFICATE-----
    +MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCWFkx
    +FTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25ha2UgVG93bjEXMBUG
    +A1UEChMOU25ha2UgT2lsLCBMdGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhv
    +cml0eTEVMBMGA1UEAxMMU25ha2UgT2lsIENBMR4wHAYJKoZIhvcNAQkBFg9jYUBz
    +bmFrZW9pbC5kb20wHhcNOTgxMDIxMDg1ODM2WhcNOTkxMDIxMDg1ODM2WjCBpzEL
    +MAkGA1UEBhMCWFkxFTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25h
    +a2UgVG93bjEXMBUGA1UEChMOU25ha2UgT2lsLCBMdGQxFzAVBgNVBAsTDldlYnNl
    +cnZlciBUZWFtMRkwFwYDVQQDExB3d3cuc25ha2VvaWwuZG9tMR8wHQYJKoZIhvcN
    +AQkBFhB3d3dAc25ha2VvaWwuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
    +gQDH9Ge/s2zcH+da+rPTx/DPRp3xGjHZ4GG6pCmvADIEtBtKBFAcZ64n+Dy7Np8b
    +vKR+yy5DGQiijsH1D/j8HlGE+q4TZ8OFk7BNBFazHxFbYI4OKMiCxdKzdif1yfaa
    +lWoANFlAzlSdbxeGVHoT0K+gT5w3UxwZKv2DLbCTzLZyPwIDAQABoyYwJDAPBgNV
    +HRMECDAGAQH/AgEAMBEGCWCGSAGG+EIBAQQEAwIAQDANBgkqhkiG9w0BAQQFAAOB
    +gQAZUIHAL4D09oE6Lv2k56Gp38OBDuILvwLg1v1KL8mQR+KFjghCrtpqaztZqcDt
    +2q2QoyulCgSzHbEGmi0EsdkPfg6mp0penssIFePYNI+/8u9HT4LuKMJX15hxBam7
    +dUHzICxBVC1lnHyYGjDuAMhe396lYAn8bCld1/L4NMGBCQ==
    +-----END CERTIFICATE-----
    +
    +
    + +
    +Certificate Authorities +

    By first verifying the information in a certificate request + before granting the certificate, the Certificate Authority assures + the identity of the private key owner of a key-pair. For instance, + if Alice requests a personal certificate, the Certificate Authority + must first make sure that Alice really is the person the certificate + request claims.

    + +
    + Certificate Chains +

    A Certificate Authority may also issue a certificate for + another Certificate Authority. When examining a certificate, + Alice may need to examine the certificate of the issuer, for each + parent Certificate Authority, until reaching one which she has + confidence in. She may decide to trust only certificates with a + limited chain of issuers, to reduce her risk of a "bad" certificate + in the chain.

    +
    + +
    + Creating a Root-Level CA +

    As noted earlier, each certificate requires an issuer to assert + the validity of the identity of the certificate subject, up to + the top-level Certificate Authority (CA). This presents a problem: + Since this is who vouches for the certificate of the top-level + authority, which has no issuer? In this unique case, the + certificate is "self-signed", so the issuer of the certificate is + the same as the subject. As a result, one must exercise extra care + in trusting a self-signed certificate. The wide publication of a + public key by the root authority reduces the risk in trusting this + key -- it would be obvious if someone else publicized a key + claiming to be the authority. Browsers are preconfigured to trust + well-known certificate authorities.

    + +

    A number of companies, such as Thawte and VeriSign + have established themselves as Certificate Authorities. These + companies provide the following services:

    + +
      +
    • Verifying certificate requests
    • +
    • Processing certificate requests
    • +
    • Issuing and managing certificates
    • +
    + +

    It is also possible to create your own Certificate Authority. + Although risky in the Internet environment, it may be useful + within an Intranet where the organization can easily verify the + identities of individuals and servers.

    +
    + +
    + Certificate Management +

    Establishing a Certificate Authority is a responsibility which + requires a solid administrative, technical, and management + framework. Certificate Authorities not only issue certificates, + they also manage them -- that is, they determine how long + certificates are valid, they renew them, and they keep lists of + certificates that have already been issued but are no longer valid + (Certificate Revocation Lists, or CRLs). Say Alice is entitled to + a certificate as an employee of a company. Say too, that the + certificate needs to be revoked when Alice leaves the company. Since + certificates are objects that get passed around, it is impossible + to tell from the certificate alone that it has been revoked. When + examining certificates for validity, therefore, it is necessary to + contact the issuing Certificate Authority to check CRLs -- this + is not usually an automated part of the process.

    + + Note +

    If you use a Certificate Authority that is not configured into + browsers by default, it is necessary to load the Certificate + Authority certificate into the browser, enabling the browser to + validate server certificates signed by that Certificate Authority. + Doing so may be dangerous, since once loaded, the browser will + accept all certificates signed by that Certificate Authority.

    +
    +
    +
    + +
    + + +
    +Secure Sockets Layer (SSL) +

    The Secure Sockets Layer protocol is a protocol layer which may be +placed between a reliable connection-oriented network layer protocol +(e.g. TCP/IP) and the application protocol layer (e.g. HTTP). SSL provides +for secure communication between client and server by allowing mutual +authentication, the use of digital signatures for integrity, and encryption +for privacy.

    + +

    The protocol is designed to support a range of choices for specific +algorithms used for cryptography, digests, and signatures. This allows +algorithm selection for specific servers to be made based on legal, export +or other concerns, and also enables the protocol to take advantage of new +algorithms. Choices are negotiated between client and server at the start +of establishing a protocol session.

    + +
    +Table 4: Versions of the SSL protocol + + + + + + + + + + + + + + + + + + + +
    VersionSourceDescriptionBrowser Support
    SSL v2.0Vendor Standard (from Netscape Corp.) [SSL2]First SSL protocol for which implementations exists- NS Navigator 1.x/2.x
    + - MS IE 3.x
    + - Lynx/2.8+OpenSSL
    SSL v3.0Expired Internet Draft (from Netscape Corp.) [SSL3]Revisions to prevent specific security attacks, add non-RSA + ciphers, and support for certificate chains- NS Navigator 2.x/3.x/4.x
    + - MS IE 3.x/4.x
    + - Lynx/2.8+OpenSSL
    TLS v1.0Proposed Internet Standard (from IETF) [TLS1]Revision of SSL 3.0 to update the MAC layer to HMAC, add block + padding for block ciphers, message order standardization and more + alert messages.- Lynx/2.8+OpenSSL
    +
    + +

    There are a number of versions of the SSL protocol, as shown in +Table 4. As noted there, one of the benefits in +SSL 3.0 is that it adds support of certificate chain loading. This feature +allows a server to pass a server certificate along with issuer certificates +to the browser. Chain loading also permits the browser to validate the +server certificate, even if Certificate Authority certificates are not +installed for the intermediate issuers, since they are included in the +certificate chain. SSL 3.0 is the basis for the Transport Layer Security +[TLS] protocol standard, currently in development by +the Internet Engineering Task Force (IETF).

    + +
    +Session Establishment +

    The SSL session is established by following a handshake sequence + between client and server, as shown in Figure 1. This sequence may vary, depending on whether the server + is configured to provide a server certificate or request a client + certificate. Though cases exist where additional handshake steps + are required for management of cipher information, this article + summarizes one common scenario: see the SSL specification for the full + range of possibilities.

    + + Note +

    Once an SSL session has been established it may be reused, thus + avoiding the performance penalty of repeating the many steps needed + to start a session. For this the server assigns each SSL session a + unique session identifier which is cached in the server and which the + client can use on forthcoming connections to reduce the handshake + (until the session identifer expires in the cache of the server).

    +
    + +

    +
    + Figure 1: Simplified SSL + Handshake Sequence

    + +

    The elements of the handshake sequence, as used by the client and + server, are listed below:

    + +
      +
    1. Negotiate the Cipher Suite to be used during data transfer
    2. +
    3. Establish and share a session key between client and server
    4. +
    5. Optionally authenticate the server to the client
    6. +
    7. Optionally authenticate the client to the server
    8. +
    + +

    The first step, Cipher Suite Negotiation, allows the client and + server to choose a Cipher Suite supportable by both of them. The SSL3.0 + protocol specification defines 31 Cipher Suites. A Cipher Suite is + defined by the following components:

    + +
      +
    • Key Exchange Method
    • +
    • Cipher for Data Transfer
    • +
    • Message Digest for creating the Message Authentication Code (MAC)
    • +
    + +

    These three elements are described in the sections that follow.

    +
    + +
    +Key Exchange Method +

    The key exchange method defines how the shared secret symmetric + cryptography key used for application data transfer will be agreed + upon by client and server. SSL 2.0 uses RSA key exchange only, while + SSL 3.0 supports a choice of key exchange algorithms including the + RSA key exchange when certificates are used, and Diffie-Hellman key + exchange for exchanging keys without certificates and without prior + communication between client and server.

    + +

    One variable in the choice of key exchange methods is digital + signatures -- whether or not to use them, and if so, what kind of + signatures to use. Signing with a private key provides assurance + against a man-in-the-middle-attack during the information exchange + used in generating the shared key [AC96, p516].

    +
    + +
    +Cipher for Data Transfer +

    SSL uses the conventional cryptography algorithm (symmetric + cryptography) described earlier for encrypting messages in a session. + There are nine choices, including the choice to perform no + encryption:

    + +
      +
    • No encryption
    • +
    • Stream Ciphers +
        +
      • RC4 with 40-bit keys
      • +
      • RC4 with 128-bit keys
      • +
    • +
    • CBC Block Ciphers +
      • RC2 with 40 bit key
      • +
      • DES with 40 bit key
      • +
      • DES with 56 bit key
      • +
      • Triple-DES with 168 bit key
      • +
      • Idea (128 bit key)
      • +
      • Fortezza (96 bit key)
      • +
    • +
    + +

    Here "CBC" refers to Cipher Block Chaining, which means that a + portion of the previously encrypted cipher text is used in the + encryption of the current block. "DES" refers to the Data Encryption + Standard [AC96, ch12], which has a number of + variants (including DES40 and 3DES_EDE). "Idea" is one of the best + and cryptographically strongest available algorithms, and "RC2" is + a proprietary algorithm from RSA DSI [AC96, + ch13].

    +
    + +
    +Digest Function +

    The choice of digest function determines how a digest is created + from a record unit. SSL supports the following:

    + +
      +
    • No digest (Null choice)
    • +
    • MD5, a 128-bit hash
    • +
    • Secure Hash Algorithm (SHA-1), a 160-bit hash
    • +
    + +

    The message digest is used to create a Message Authentication Code + (MAC) which is encrypted with the message to provide integrity and to + prevent against replay attacks.

    +
    + +
    +Handshake Sequence Protocol +

    The handshake sequence uses three protocols:

    + +
      +
    • The SSL Handshake Protocol + for performing the client and server SSL session establishment.
    • +
    • The SSL Change Cipher Spec Protocol for actually + establishing agreement on the Cipher Suite for the session.
    • +
    • The SSL Alert Protocol for conveying SSL error + messages between client and server.
    • +
    + +

    These protocols, as well as application protocol data, are + encapsulated in the SSL Record Protocol, as shown in + Figure 2. An encapsulated protocol is + transferred as data by the lower layer protocol, which does not + examine the data. The encapsulated protocol has no knowledge of the + underlying protocol.

    + +

    +
    + Figure 2: SSL Protocol Stack +

    + +

    The encapsulation of SSL control protocols by the record protocol + means that if an active session is renegotiated the control protocols + will be transmitted securely. If there were no session before, then + the Null cipher suite is used, which means there is no encryption and + messages have no integrity digests until the session has been + established.

    +
    + +
    +Data Transfer +

    The SSL Record Protocol, shown in Figure 3, + is used to transfer application and SSL Control data between the + client and server, possibly fragmenting this data into smaller units, + or combining multiple higher level protocol data messages into single + units. It may compress, attach digest signatures, and encrypt these + units before transmitting them using the underlying reliable transport + protocol (Note: currently all major SSL implementations lack support + for compression).

    + +

    +
    + Figure 3: SSL Record Protocol +

    +
    + +
    +Securing HTTP Communication +

    One common use of SSL is to secure Web HTTP communication between + a browser and a webserver. This case does not preclude the use of + non-secured HTTP. The secure version is mainly plain HTTP over SSL + (named HTTPS), but with one major difference: it uses the URL scheme + https rather than http and a different + server port (by default 443). This mainly is what mod_ssl provides to you for the Apache webserver...

    +
    +
    + + +
    +References +
    +
    [AC96]
    +
    Bruce Schneier, Applied Cryptography, 2nd Edition, Wiley, +1996. See http://www.counterpane.com/ for various other materials by Bruce +Schneier.
    + +
    [X208]
    +
    ITU-T Recommendation X.208, Specification of Abstract Syntax Notation +One (ASN.1), 1988. See for instance http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.208-198811-I. +
    + +
    [X509]
    +
    ITU-T Recommendation X.509, The Directory - Authentication +Framework. See for instance http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.509. +
    + +
    [PKCS]
    +
    Public Key Cryptography Standards (PKCS), +RSA Laboratories Technical Notes, See http://www.rsasecurity.com/rsalabs/pkcs/.
    + +
    [MIME]
    +
    N. Freed, N. Borenstein, Multipurpose Internet Mail Extensions +(MIME) Part One: Format of Internet Message Bodies, RFC2045. +See for instance http://ietf.org/rfc/rfc2045.txt.
    + +
    [SSL2]
    +
    Kipp E.B. Hickman, The SSL Protocol, 1995. See http://www.netscape.com/eng/security/SSL_2.html.
    + +
    [SSL3]
    +
    Alan O. Freier, Philip Karlton, Paul C. Kocher, The SSL Protocol +Version 3.0, 1996. See http://www.netscape.com/eng/ssl3/draft302.txt.
    + +
    [TLS1]
    +
    Tim Dierks, Christopher Allen, The TLS Protocol Version 1.0, +1999. See http://ietf.org/rfc/rfc2246.txt.
    +
    +
    + + +
    diff --git a/trunk/docs/manual/ssl/ssl_intro.xml.ja b/trunk/docs/manual/ssl/ssl_intro.xml.ja new file mode 100644 index 0000000000..f88b2d901f --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.xml.ja @@ -0,0 +1,725 @@ + + + + + + + + +SSL/TLS + + SSL/TLS $B0E9f2=(B: $B$O$8$a$K(B + + +
    +

    $BI8=`5,3J$NNI$$=j$O!"$?$/$5$s$N5,3J$+$iA*$Y$k$H$$$&$3$H$@!#(B +$B$=$7$F!"$b$7K\Ev$K$I$N5,3J$b5$$KF~$i$J$1$l$P!"(B +$B0lG/BT$D$@$1$GC5$7$F$$$?5,3J$,8=$l$k!#(B

    + +

    -- A. Tanenbaum, "Introduction to +Computer Networks"

    +
    + +

    +$BF~Lg$H$$$&$3$H$G!"$3$N>O$O(B Web$B!"(BHTTP$B!"(BApache $B$KDL$8$F$$$k(B +$BFIZ4IM}$N$?$a$NFCDj$N%F%/%K%C%/$d!"(B +$BFC5v$dM"=P5,@)$J$I$N=EMW$JK!E*$JLdBj$K$D$$$F$b07$$$^$;$s!#(B +$B$`$7$m!"99$J$k8&5f$X$N=PH/E@$H$7$F?'!9$J35G0!"Dj5A!"Nc$rJB$Y$k$3$H$G(B + mod_ssl $B$N%f!<%6$K4pACCN<1$rDs6!$9$k;v$rL\E*$H$7$F$$$^$9!#(B

    + +

    $B$3$3$K<($5$l$?FbMF$OFrederick J. Hirsch + $B;a$N5-;v(B +Introducing SSL and Certificates using SSLeay $B$r4p$K$7$F$$$^$9!#(B +$B;a$N5-;v$O(B Web Security: A Matter of +Trust, World Wide Web Journal, Volume 2, Issue 3, Summer 1997 +$B$K7G:\$5$l$^$7$?!#(B +$B9NDjE*$J0U8+$O(B Frederick Hirsch $B;a(B + ($B855-;v$NCxp$O(B Ralf S. Engelschall ( +mod_ssl $B$N:n +Apache $B%I%-%e%a%s%HK]Lu%W%m%8%'%/%H(B +$B$X$*4j$$$7$^$9!#(B]

    +
    + +
    +$B0E9f2=5;=Q(B +

    SSL $B$rM}2r$9$k$K$O!"0E9f%"%k%4%j%:%`!"(B +$B%a%C%;!<%8%@%$%8%'%9%H4X?t(B($BJLL>(B: $B0lJ}8~4X?t!"%O%C%7%e4X?t(B)$B!"(B +$BEE;R=pL>$J$I$X$NM}2r$,I,MW$G$9!#(B +$B$3$l$i$N5;=Q$OK\$,4]$4$HI,MW$JBjL\$G(B +($BNc$($P(B [AC96] $B$r;2>H(B)$B!"(B +$B%W%i%$%P%7!Z$J$I$N5;=Q$N4pAC$H$J$C$F$$$^$9!#(B

    + +
    +$B0E9f%"%k%4%j%:%`(B +

    $BNc$($P!"%"%j%9$,Aw6b$N$?$a$K6d9T$K%a%C%;!<%8$rAw$j$?$$$H$7$^$9!#(B + $B8}:BHV9f$dAw6b$N6b3[$,4^$^$l$k$?$a!"(B + $B%"%j%9$O$=$N%a%C%;!<%8$rHkL)$K$7$?$$$H;W$$$^$9!#(B + $B2r7hJ}K!$N0l$D$O0E9f%"%k%4%j%:%`$r;H$C$F!"%a%C%;!<%8$r(B + $BFI$^$;$?$$?M0J30$OFI$`$3$H$,$G$-$J$$0E9f2=$5$l$?(B + $B7ABV$KJQ$($F$7$^$&$3$H$G$9!#(B + $B$=$N7ABV$K$J$k$H!"(B + $B%a%C%;!<%8$OHkL)$N80$K$h$C$F$N$_2ro$KFq$7$/$9$k$?$a!"EXNO$,3d$K9g$o$J$/$5$;$^$9!#(B

    + +

    $B0E9f%"%k%4%j%:%`$K$O(B + $B=>Mh7?$H8x3+80$NFs$D$N + +

    +
    $B=>Mh7?0E9f(B
    +
    $BBP>N0E9f$H$7$F$bCN$i$l!"(B + $BAw?.pJs$N$3$H$G$9!#(B + $B$b$7!"$3$N80$,HkL)$J$i!"Aw?. + +
    $B8x3+800E9f(B
    +
    $BHsBP>N0E9f$H$7$F$bCN$i$l!"(B + $B%a%C%;!<%8$r0E9f2=$9$k$3$H$N$G$-$kFs$D$N80(B + $B$r;HMQ$9$k%"%k%4%j%:%`$rDj5A$9$k$3$H$G80$N$d$j +
    + +

    $BC/$b$,0E9f2=$5$l$?%a%C%;!<%8$r8x3+80$K$h$C$F0E9f2=(B + $B$9$k$3$H$,$G$-$^$9$,!"HkL)80$N;}$A +

    + +
    +$B%a%C%;!<%8%@%$%8%'%9%H(B +

    $B%"%j%9$O%a%C%;!<%8$rHkL)$K$9$k$3$H$,$G$-$^$9$,!"(B + $BC/$+$,Nc$($P<+J,$KAw6b$9$k$h$&$K%a%C%;!<%8$rJQ99$7$?$j!"(B + $BJL$N$b$N$KCV$-49$($F$7$^$&$+$b$7$l$J$$$H$$$&LdBj$,$"$j$^$9!#(B + $B%"%j%9$N%a%C%;!<%8$N?.MQ$rJ]>Z$9$kJ}K!$N0l$D$O!"(B + $B%a%C%;!<%8$N4J7i$J%@%$%8%'%9%H$r:n$C$F!"$=$l$b6d9T$KAw$k$H$$$&$b$N$G$9!#(B + $B%a%C%;!<%8$r + +

    $B$3$N$h$&$JMWLs$O(B$B%a%C%;!<%8%@%$%8%'%9%H(B$B!"(B + $B0lJ}9T4X?t(B$B!"$^$?$O(B$B%O%C%7%e4X?t(B$B$H8F$P$l$^$9!#(B + $B%a%C%;!<%8%@%$%8%'%9%H$OD9$$2DJQD9$N%a%C%;!<%8$+$i(B + $BC;$$8GDjD9$NI=8=$r:n$k$N$K;H$o$l$^$9!#(B + $B%@%$%8%'%9%H%"%k%4%j%:%`$O%a%C%;!<%8$+$i(B + $B0l0U$J%@%$%8%'%9%H$r@8@.$9$k$h$&$K:n$i$l$F$$$^$9!#(B + $B%a%C%;!<%8%@%$%8%'%9%H$O%@%$%8%'%9%H$+$i85$N%a%C%;!<%8$r(B + $BH=Dj$9$k$N$,$H$F$bFq$7$$$h$&$K$G$-$F$$$^$9!#(B + $B$^$?!"F1$8MWLs$r:n@.$9$kFs$D$N%a%C%;!<%8$rC5$9$N$OIT2DG=$G$9!#(B + $B$h$C$F!"F1$8MWLs$r;H$C$F%a%C%;!<%8$rCV$-49$($k$H$$$&(B + $B2DG=@-$rGS=|$7$F$$$^$9!#(B

    + +

    $B%"%j%9$X$N$b$&0l$D$NLdBj$O!"$3$N%@%$%8%'%9%H$r0BA4$KAw$kJ}K!$rC5$9$3$H$G$9!#(B +$B$3$l$,$G$-$l$P!"%a%C%;!<%8$N?.MQ$,J]>Z$5$l$^$9!#(B +$B0l$D$NJ}K!$O$3$N%@%$%8%'%9%H$KEE;R=pL>$r4^$`$3$H$G$9!#(B

    +
    + +
    $BEE;R=pL>(B +

    $B%"%j%9$,6d9T$K%a%C%;!<%8$rAw$C$?$H$-!"6d9T$O!"(B +$B?/F~$BEE;R=pL>(B$B$,$3$3$GLr$KN)$A$^$9!#(B

    + +

    $BEE;R=pL>$O%a%C%;!<%8$N%@%$%8%'%9%H$d$=$NB>$N>pJs(B($B=hM}HV9f$J$I(B)$B$r(B +$BAw?.$r(B$BI|9f(B$B$9$k$3$H$,$G$-$^$9$,!"(B +$B=pL>$7$($?$3$H$r0UL#$7$^$9!#(B +$B%@%$%8%'%9%H$rEE;R=pL>$K4^$`$3$H$O!"(B +$B$=$N=pL>$,$=$N%a%C%;!<%8$N$_$KM-8z$G$"$k$3$H$r0UL#$7$^$9!#(B +$B$3$l$O!"C/$b%@%$%8%'%9%H$rJQ$($F=pL>$r$9$k$3$H$,$G$-$J$$$?$a!"(B +$B%a%C%;!<%8$N?.MQ$bJ]>Z$7$^$9!#(B

    + +

    $B?/F~$rK5$K$O0l0U$J=hM}HV9f$,4^$^$l$^$9!#(B +$B$3$l$O!"%"%j%9$,$=$s$J%a%C%;!<%8$OAw$C$F$$$J$$$H8@$&:>5=(B +$B$+$i6d9T$r$7$($?$+$i$G$9!#(B($BH]G'KI;_(B)

    +
    +
    + + +
    +$B>ZL@=q(B +

    $B%"%j%9$OHkL)$N%a%C%;!<%8$r6d9T$KAw$j!"(B +$B=pL>$r$7$F!"%a%C%;!<%8$N?.MQ$rJ]>Z$9$k$3$H$,$G$-$k$*$&$K$J$j$^$7$?$,!"(B +$BDL?.$7$F$$$kAj$,K\Ev$K%"%j%9$N=pL>$+3NG'$9$kI,MW$,(B +$B$"$j$^$9!#(B

    + +

    $B$b$7N>ZL@$7!"8x3+80$r3NG'$7!"$^$??.Mj$5$l$?5!4X$,=pL>(B +$B$7$?>ZL@=q$,$"$l$P!"N>$BG'>Z6I(B + (Certificate Authority $B$^$?$O(B CA) $B$H8F$P$l!"(B +$B>ZL@=q(B (certificate) $B$,G'>Z(B (authentication) $B$K;H$o$l$^$9!#(B

    + +
    +$B>ZL@=q$NFbMF(B +

    $B>ZL@=q$O8x3+80$H8D?M!"%5!<%P!"$=$NB>$N$BI=(B1$B$K<($5$l$k$h$&$K>ZL@BP>]$N>pJs$O(B + $B?H85>ZL@$N>pJs(B($B<1JLL>(B)$B$H8x3+80$,4^$^$l$^$9!#(B + $B>ZL@=q$O$^$?!"G'>Z6I$N?H85>ZL@$H=pL>!"$=$7$F>ZL@=q$NM-8z4|4V$r(B + $B4^$_$^$9!#(B + $B%7%j%"%k%J%s%P!<$J$I$NG'>Z6I$N4IM}>e$N>pJs$d(B + $B$=$NB>$NDI2C$N>pJs$,4^$^$l$F$$$k$+$b$7$l$^$;$s!#(B

    + +
    + $BI=(B1: $B>ZL@=q>pJs(B + + + + + + + + + + + + +
    $B>ZL@BP>](B$B<1JLL>!"8x3+80(B
    $BH/9T + $B<1JLL>!"8x3+80(B
    $BM-8z4|4V(B$B3+;OF|!"<:8zF|(B
    $B4IM}>pJs(B$B%P!<%8%g%s!"%7%j%"%k%J%s%P!<(B
    $B3HD%>pJs(B$B4pK\E*$J@)Ls!"%M%C%H%9%1!<%W%U%i%C%0!"$=$NB>(B
    +
    + +

    $B<1JLL>(B($B%G%#%9%F%#%s%0%$%C%7%e!&%M!<%`(B)$B$OFCDj$N>u67$K$*$1$k(B + $B?HJ,>ZL@$rDs6!$9$k$N$K;H$o$l$F$$$^$9!#Nc$($P!"$"$k?M$O(B + $B;dMQ$H2qZL@$r;}$D$+$b$7$l$^$;$s!#(B + + $B<1JLL>$O(B X.509 $BI8=`5,3J(B [X509] $B$GDj5A$5$l$F$$$^$9!#(B + X.509 $BI8=`5,3J$O!"9`L\!"9`L\L>!"$=$7$F9`L\$NN,>N$rDj5A$7$F$$$^$9!#(B($BI=(B + 2 $B;2>H(B)

    + +
    + $BI=(B 2: $B<1JLL>>pJs(B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    $B<1JLL>9`L\(B$BN,>N(B$B@bL@(B$BNc(B
    Common Name ($B%3%b%s%M!<%`(B)CN$BG'>Z$5$l$kL>A0(B
    + SSL$B@\B3$9$k(BURL
    CN=www.example.com
    Organization or Company ($BAH?%L>(B)O$BCDBN$N@5<01Q8lAH?%L>(BO=Example Japan K.K.
    Organizational Unit ($BItLgL>(B)OU$BIt=pL>$J$I(BOU=Customer Service
    City/Locality ($B;T6hD.B<(B)L$B=j:_$7$F$k;T6hD.B<(BL=Sapporo
    State/Province ($BETF;I\8)(B)ST$B=j:_$7$F$kETF;I\8)(BST=Hokkaido
    Country($B9q(B)C$B=j:_$7$F$$$k9qL>$N(B ISO $B%3!<%I(B
    + $BF|K\$N>l9g(B JP +
    C=JP
    +
    + +

    $BG'>Z6I$O$I$N9`L\$,>JN,2DG=$G$I$l$,I,?\$+$NJ}?K$rDj5A$9$k(B + $B$+$b$7$l$^$;$s!#9`L\$NFbMF$K$D$$$F$bG'>Z6I$d>ZL@=q$N%f!<%6$+$i$N(B + $BMW7o$,$"$k$+$b$7$l$^$;$s!#(B + $BNc$($P!"%M%C%H%9%1!<%W$N%V%i%&%6$O%5!<%P$N>ZL@=q$N(B + Common Name ($B%3%b%s%M!<%`(B)$B$,%5!<%P$N%I%a%$%sL>$N(B + *.example.com + $B$H$$$&$h$&$J%o%$%k%I%+!<%I$N%Q%?!<%s$K%^%C%A$9$k$3$H(B + $B$rMW5a$7$^$9!#(B

    + +

    $B%P%$%J%j7A<0$N>ZL@=q$O(B ASN.1 $BI=5-K!(B + [X208] [PKCS] $B$G(B + $BDj5A$5$l$F$$$^$9!#(B + $B$3$NI=5-K!$OFbMF$r$I$N$h$&$K5-=R$9$k$+$rDj5A$7!"(B + $BId9f2=$N5,Dj$,$3$N>pJs$,$I$N$h$&$K%P%$%J%j7A<0$KJQ49$5$l$k$+$r(B + $BDj5A$7$^$9!#(B + $B>ZL@=q$N%P%$%J%jId9f2=$O(B Distinguished Encoding + Rules (DER) $B$GDj5A$5$l!"$=$l$O$h$j0lHLE*$J(B Basic Encoding Rules + (BER) $B$K4p$E$$$F$$$^$9!#(B + $B%P%$%J%j7A<0$r07$&$3$H$N$G$-$J$$Aw?.$G$O!"(B + $B%P%$%J%j7A<0$O(B Base64 $BId9f2=(B [MIME] $B$G(B + ASCII $B7A<0$KJQ49$5$l$k$3$H$,$"$j$^$9!#(B + $B$3$N$h$&$KId9f2=$5$l!"0J2<$NNc$K<($5$l$k$h$&$K6h@Z$j9T$K(B + $B64$^$l$?$b$N$O(B PEM $BId9f2=$5$l$?$H8@$$$^$9!#(B + (PEM $B$NL>A0$O(B "Privacy Enhanced Mail" $B$KM3Mh$7$^$9(B)

    + + + PEM $BId9f2=$5$l$?>ZL@=q$NNc(B (example.crt) +
    -----BEGIN CERTIFICATE-----
    +MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCWFkx
    +FTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25ha2UgVG93bjEXMBUG
    +A1UEChMOU25ha2UgT2lsLCBMdGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhv
    +cml0eTEVMBMGA1UEAxMMU25ha2UgT2lsIENBMR4wHAYJKoZIhvcNAQkBFg9jYUBz
    +bmFrZW9pbC5kb20wHhcNOTgxMDIxMDg1ODM2WhcNOTkxMDIxMDg1ODM2WjCBpzEL
    +MAkGA1UEBhMCWFkxFTATBgNVBAgTDFNuYWtlIERlc2VydDETMBEGA1UEBxMKU25h
    +a2UgVG93bjEXMBUGA1UEChMOU25ha2UgT2lsLCBMdGQxFzAVBgNVBAsTDldlYnNl
    +cnZlciBUZWFtMRkwFwYDVQQDExB3d3cuc25ha2VvaWwuZG9tMR8wHQYJKoZIhvcN
    +AQkBFhB3d3dAc25ha2VvaWwuZG9tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
    +gQDH9Ge/s2zcH+da+rPTx/DPRp3xGjHZ4GG6pCmvADIEtBtKBFAcZ64n+Dy7Np8b
    +vKR+yy5DGQiijsH1D/j8HlGE+q4TZ8OFk7BNBFazHxFbYI4OKMiCxdKzdif1yfaa
    +lWoANFlAzlSdbxeGVHoT0K+gT5w3UxwZKv2DLbCTzLZyPwIDAQABoyYwJDAPBgNV
    +HRMECDAGAQH/AgEAMBEGCWCGSAGG+EIBAQQEAwIAQDANBgkqhkiG9w0BAQQFAAOB
    +gQAZUIHAL4D09oE6Lv2k56Gp38OBDuILvwLg1v1KL8mQR+KFjghCrtpqaztZqcDt
    +2q2QoyulCgSzHbEGmi0EsdkPfg6mp0penssIFePYNI+/8u9HT4LuKMJX15hxBam7
    +dUHzICxBVC1lnHyYGjDuAMhe396lYAn8bCld1/L4NMGBCQ==
    +-----END CERTIFICATE-----
    +
    +
    + +
    +$BG'>Z6I(B +

    $B$^$:>ZL@=q$N?=@A$N>pJs$r3NG'$9$k$3$H$G!"(B + $BG'>Z6I$OHkL)80$N;}$AZ$7$^$9!#(B + $BNc$($P!"%"%j%9$,8D?M>ZL@=q$r?=@A$7$?$H$9$k$H!"(B + $BG'>Z6I$O%"%j%9$,>ZL@=q$N?=@A$, + +

    + $B>ZL@=q3,AX9=B$(B +

    $BG'>Z6I$OB>$NG'>Z6I$X$N>ZL@=q$rH/9T$9$k$3$H$,$G$-$^$9!#(B + $BL$CN$N>ZL@=q$rD4$Y$k;~$K!"%"%j%9$O$=$N>ZL@=q$NH/9TZL@=q$r(B + $B$=$N>e0L3,AX$NG'>Z6I$r$?$I$C$FD4$Y$kI,MW$,$"$j$^$9!#(B + $B!V0-ZL@=q$N4m81@-$r8:$i$9$?$a!"(B + $BH`=w$O8B$i$l$?O":?$NH/9T +

    + +
    + $B:G>e0LG'>Z6I$N:n@.(B +

    $BA0$K=R$Y$?$h$&$K!"A4$F$N>ZL@=q$K$D$$$F!"(B + $B:G>e0L$NG'>Z6I(B(CA)$B$^$G$=$l$>$l$NH/9T]$N?H85>ZL@$NM-8z@-$rL@$i$+$K$9$kI,MW$,$"$j$^$9!#(B + $BLdBj$O!"C/$,$=$N:G>e0L$NG'>Z5!4X$N>ZL@=q$rJ]>Z$9$k$N$+!"(B + $B$H$$$&$3$H$G$9!#(B + $B$3$N$h$&$J>l9g$K8B$j!">ZL@=q$O!V<+8J=pL>!W$5$l$^$9!#(B + $B$D$^$j!">ZL@=q$NH/9TZL@BP>]$,F1$8$H$$$&$3$H$K$J$j$^$9!#(B + $B$=$N7k2L!"<+8J=pL>$5$l$?>ZL@=q$r?.MQ$9$k$K$O(B + $B:Y?4$NCm0U$,I,MW$G$9!#(B + $B:G>e0LG'>Z6I$,8x3+80$r9-$/8xI=$9$k$3$H$G!"(B + $B$=$N80$r?.Mj$9$k%j%9%/$rDc$/$9$k$3$H$,$G$-$^$9!#(B + $B$b$7!"B>?M$,$=$NG'>Z6I$K$J$j$9$^$7$?;~$K!"$=$l$,O*8+$7$d(B + $B$9$$$+$i$G$9!#(B + $BB?$/$N%V%i%&%6$OM-L>$JG'>Z6I$r?.Mj$9$k$h$&$K(B + $B@_Dj$5$l$F$$$^$9!#(B

    + +

    Thawte + $B$d(B VeriSign + $B$N$h$&$JB?$/$N2qZ6I$H$7$F3+@_$7$^$7$?!#(B + $B$3$N$h$&$J2q + +

      +
    • $B>ZL@=q?=@A$N3NG'(B
    • +
    • $B>ZL@=q?=@A$N=hM}(B
    • +
    • $B>ZL@=q$NH/9T$H4IM}(B
    • +
    + +

    $B<+J,$GG'>Z6I$r:n$k$3$H$b2DG=$G$9!#(B + $B%$%s%?!<%M%C%H4D6-$G$O4m81$G$9$,!"(B + $B8D?M$d%5!<%P$N?H85>ZL@$,4JC1$K9T$($kAH?%$N(B + $B%$%s%H%i%M%C%HFb$G$OLr$KN)$D$+$b$7$l$^$;$s!#(B

    +
    + +
    + $B>ZL@=q4IM}(B +

    $BG'>Z6I$N3+@_$OE0Dl$7$?4IM}!"5;=Q!"1?MQ$NBN@)$rI,MW$H$9$k(B + $B@UG$$N$"$k;E;v$G$9!#(B + $BG'>Z6I$O>ZL@=q$rH/9T$9$k$@$1$G$J$/!"(B + $B4IM}$b$7$J$1$l$P$J$j$^$;$s!#(B + $B6qBNE*$K$O!">ZL@=q$,$$$D$^$GM-8z$+$r7hDj$7!"99?7$7!"(B + $B$^$?4{$KH/9T$5$l$?$,<:8z$7$?>ZL@=q$N%j%9%H(B + (Certificate Revocation Lists $B$^$?$O(B CRL) + $B$r4IM}$7$J$1$l$P$$$1$^$;$s!#(B + $BNc$($P!"%"%j%9$,2qZL@=q$rM?$($i$l$?$H$7$^$9!#(B + $B$=$7$F!"%"%j%9$,2qZL@=q$rC$5$J$1$l$P(B + $B$$$1$J$$$H$7$^$9!#(B + $B>ZL@=q$OZL@=q$=$N$b$N$+$i!"$=$l$,C$5$l$?$+H=CG$9$k$3$H$O(B + $BIT2DG=$G$9!#(B + $B$h$C$F!">ZL@=q$NM-8z@-$rD4$Y$k$H$-$K$O!"(B + $BG'>Z6I$KO"Mm$7$F(B CRL $B$r>H9g$9$kI,MW$,$"$j$^$9!#(B + $BIaDL$3$N2aDx$O<+F02=$5$l$F$$$k$b$N$G$O$"$j$^$;$s!#(B

    + + $BCm0U(B +

    $B%G%U%)%k%H$G%V%i%&%6$K@_Dj$5$l$F$$$J$$G'>Z6I$r;H$C$?>l9g!"(B + $BG'>Z6I$N>ZL@=q$r%V%i%&%6$KFI$_9~$s$G!"(B + $B%V%i%&%6$,$=$NG'>Z6I$K$h$C$F=pL>$5$l$?%5!<%P$N>ZL@=q$r(B + $BM-8z2=$9$kI,MW$,$"$j$^$9!#(B + $B0lEYFI$_9~$^$l$k$H!"$=$NG'>Z6I$K$h$C$F=pL>$5$l$?A4$F$N(B + $B>ZL@=q$r + +

    +
    + +
    + + +
    +Secure Sockets Layer (SSL) +

    Secure Sockets Layer $B%W%m%H%3%k$O?.Mj@-$N$"$k%3%M%/%7%g%s7?$N(B +$B%M%C%H%o!<%/AX$N%W%m%H%3%k(B($BNc$($P!"(BTCP/IP)$B$H(B +$B%"%W%j%1!<%7%g%sAX$N%W%m%H%3%k(B($BNc$($P!"(BHTTP) +$B$N4V$KCV$/$3$H$,$G$-$^$9!#(B +SSL $B$O!"Aj8_G'>Z$K$h$C$F%5!<%P$H%/%i%$%"%s%H4V$N0BA4$JDL?.$r!"(B +$BEE;R=pL>$K$h$C$F%G!<%?$N40A4@-$r!"(B +$B$=$7$F0E9f2=$K$h$C$F%W%i%$%P%7$rDs6!$7$^$9!#(B

    + +

    SSL $B%W%m%H%3%k$O0E9f2=!"%@%$%8%'%9%H!"EE;R=pL>$K$D$$$F!"(B +$BMM!9$J%"%k%4%j%:%`$r%5%]!<%H$9$k$h$&$K$G$-$F$$$^$9!#(B +$B$3$&$9$k$3$H$G!"K!$dM"=P$N5,@)$r9MN8$KF~$l$F!"%5!<%P$K9g$o$;$?(B +$B%"%k%4%j%:%`$rA*$V$3$H$,$G$-!"$^$?!"?7$7$$%"%k%4%j%:%`$r(B +$BMxMQ$7$F$$$/$3$H$b2DG=$K$7$F$$$^$9!#(B +$B%"%k%4%j%:%`$NA*Br$O%W%m%H%3%k%;%C%7%g%s3+;O;~$K(B +$B%5!<%P$H%/%i%$%"%s%H4V$G + +

    +$BI=(B4: SSL $B%W%m%H%3%k$N%P!<%8%g%s(B + + + + + + + + + + + + + + + + + +
    $B%P!<%8%g%s(B$B=PE5(B$B@bL@(B$B%V%i%&%6$N%5%]!<%H(B
    SSL v2.0Vendor Standard (Netscape Corp. $B$h$j(B) [SSL2]$B + - NS Navigator 1.x/2.x
    + - MS IE 3.x
    + - Lynx/2.8+OpenSSL
    SSL v3.0Expired Internet Draft (Netscape Corp. $B$h$j(B) [SSL3]$BFCDj$N%;%-%e%j%F%#967b$rKI$0$?$a$N2~D{!"(B + $BHs(BRSA $B0E9f$NDI2C!">ZL@=q3,AX9=B$$N%5%]!<%H(B- NS Navigator 2.x/3.x/4.x
    + - MS IE 3.x/4.x
    + - Lynx/2.8+OpenSSL
    TLS v1.0Proposed Internet Standard (IETF $B$h$j(B) [TLS1]MAC $B%l%$%d$r(B HMAC $B$X99?7!"%V%m%C%/0E9f$N(B block + padding$B!"%a%C%;!<%8=g=x$NI8=`2=!"7Y9pJ8$N=< + - Lynx/2.8+OpenSSL
    +
    + +

    $BI=(B4$B$K<($5$l$k$H$*$j!"(BSSL $B%W%m%H%3%k$K$O(B +$B$$$/$D$b$N%P!<%8%g%s$,$"$j$^$9!#(B +$BI=$K$b=q$+$l$F$$$k$h$&$K!"(BSSL 3.0 $B$NMxE@$N0l$D$O(B +$B>ZL@=q3,AX9=B$$r%5%]!<%H$9$k$3$H$G$9!#(B +$B$3$N5!G=$K$h$C$F!"%5!<%P$O<+J,$N>ZL@=q$K2C$($F!"(B +$BH/9TZL@=q$r%V%i%&%6$KEO$9$3$H$,$G$-$^$9!#(B +$B>ZL@=q3,AX9=B$$K$h$C$F!"(B +$B%V%i%&%6$KH/9TZL@=q$,D>@\EPO?$5$l$F$$$J$/$F$b!"(B +$B3,AX$NCf$K4^$^$l$F$$$l$P!"(B +$B%V%i%&%6$O%5!<%P$N>ZL@=q$rM-8z2=$9$k$3$H$,$G$-$^$9!#(B +SSL 3.0 $B$O8=:_(B Internet Engineering Task Force (IETF) +$B$K$h$C$F3+H/$5$l$F$$$k(B Transport Layer Security +[TLS] $B%W%m%H%3%kI8=`5,3J$N4pAC$H$J$C$F$$$^$9!#(B

    + +
    +$B%;%C%7%g%s$N3NN)(B +

    $B?^(B1$B$G<($5$l$k$h$&$K!"(B + $B%;%C%7%g%s$N3NN)$O%/%i%$%"%s%H$H%5!<%P4V$N(B + $B%O%s%I%7%'!<%/%7!<%/%(%s%9$K$h$C$F9T$J$o$l$^$9!#(B + $B%5!<%P$,>ZL@=q$rDs6!$9$k$+!"%/%i%$%"%s%H$N>ZL@=q$r%j%/%(%9%H$9$k$+(B + $B$H$$$&%5!<%P$N@_Dj$K$h$j!"$3$N%7!<%/%(%s%9$O0[$J$k$b$N$H$J$j$^$9!#(B + $B0E9f>pJs$N4IM}$N$?$a$K!"DI2C$N%O%s%I%7%'!<%/2aDx$,I,MW$K$J$k(B + $B>l9g$b$"$j$^$9$,!"$3$N5-;v$G$O(B + $B$h$/$"$k%7%J%j%*$rH$7$F$/$@$5$$!#(B

    + + $BCm0U(B +

    $B0lEY(B SSL $B%;%C%7%g%s$,3NN)$9$k$H!"%;%C%7%g%s$r:FMxMQ$9$k$3$H$G!"(B + $B%;%C%7%g%s$r3+;O$9$k$?$a$NB?$/$N2aDx$r7+$jJV$9$H$$$&(B + $B%Q%U%)!<%^%s%9$NB;<:$rKI$.$^$9!#(B + $B$=$N$?$a!"%5!<%P$OA4$F$N%;%C%7%g%s$K0l0U$J%;%C%7%g%s<1JLL>$r(B + $B3d$jEv$F!"%5!<%P$K%-%c%C%7%e$7!"%/%i%$%"%s%H$O$,%5!<%P$N%-%c%C%7%e$G4|8B@Z$l$K$J$k$^$G$O(B) + $B%O%s%I%7%'!<%/$J$7$G@\B3$9$k$3$H$,$G$-$^$9!#(B

    +
    + +

    +
    + $B?^(B1: SSL + $B%O%s%I%7%'!<%/%7!<%/%(%s%935N,(B

    + +

    $B%5!<%P$H%/%i%$%"%s%H$G;H$o$l$k(B + $B%O%s%I%7%'!<%/%7!<%/%(%s%9$NMWAG$r0J2<$K<($7$^$9(B:

    + +
      +
    1. $B%G!<%?DL?.$K;H$o$l$k0E9f%9%$!<%H$N +
    2. $B%/%i%$%"%s%H$H%5!<%P4V$G$N%;%C%7%g%s80$N3NN)$H6&M-(B
    3. +
    4. $B%*%W%7%g%s$H$7$F!"%/%i%$%"%s%H$KBP$9$k%5!<%P$NG'>Z(B
    5. +
    6. $B%*%W%7%g%s$H$7$F!"%5!<%P$KBP$9$k%/%i%$%"%s%H$NG'>Z(B
    7. +
    + +

    $BBh0l%9%F%C%W$N0E9f%9%$!<%H$l$K$"$C$?(B + $B0E9f%9%$!<%H$rA*$V$3$H$,$G$-$^$9!#(B + SSL3.0 $B%W%m%H%3%k$N;EMM=q$O(B 31 $B$N0E9f%9%$!<%H$rDj5A$7$F$$$^$9!#(B + $B0E9f%9%$!<%H$O0J2<$N%3%s%]!<%M%s%H$K$h$jDj5A$5$l$F$$$^$9(B:

    + +
      +
    • $B80$N8r49 +
    • $B%G!<%?DL?.$N0E9f=Q(B
    • +
    • Message Authentication Code (MAC) $B:n@.$N$?$a$N(B + $B%a%C%;!<%8%@%$%8%'%9%H(B
    • +
    + +

    $B$3$l$i$N;0$D$NMWAG$O0J2<$N%;%/%7%g%s$G@bL@$5$l$F$$$^$9!#(B

    +
    + +
    +$B80$N8r49<jCJ(B +

    $B80$N8r49N0E9f80$r$I$N$h$&$K$,%/%i%$%"%s%H$H%5!<%P$G(B + $BZL@=q$,;H$o$l$k$H$-$O(B RSA $B808r49$r;H$$!"(B + $B>ZL@=q$,L5$/!"%/%i%$%"%s%H$H%5!<%P$N;vA0$NDL?.$,L5$$>l9g$O(B + Diffie-Hellman $B808r49$r;H$&(B + $B$J$IMM!9$J808r49%"%k%4%j%:%`$r%5%]!<%H$7$^$9!#(B

    + +

    $B80$N8r49J}K!$K$*$1$k0l$D$NA*Br;h$OEE;R=pL>$G$9!#(B + $BEE;R=pL>$r;H$&$+$I$&$+!"$^$?!"(B + $B$I$N$r;H$&$+$H$$$&A*Br$,$"$j$^$9!#(B + $BHkL)80$G=pL>$9$k$3$H$G6&M-80$r@8@.$9$7!">pJs8r49$9$k;~$N(B + $B%^%s!&%$%s!&%6!&%_%I%k967b$rKI$0$3$H$,$G$-$^$9!#(B + [AC96, p516]

    +
    + +
    +$B%G!<%?DL?.$N0E9f=Q(B +

    SSL $B$O%;%C%7%g%s$N%a%C%;!<%8$N0E9f2=$KA0=R$7$?(B + $B=>Mh7?0E9f(B($BBP>N0E9f(B)$B$rMQ$$$^$9!#(B + $B0E9f2=$7$J$$$H$$$&A*Br;h$b4^$a6e$D$NA*Br;h$,$"$j$^$9(B:

    + +
      +
    • $B0E9f2=$J$7(B
    • +
    • $B%9%H%j!<%`0E9f(B +
        +
      • 40-bit $B80$G$N(B RC4
      • +
      • 128-bit $B80$G$N(B RC4
      • +
    • +
    • CBC $B%V%m%C%/0E9f(B +
      • 40 bit $B80$G$N(B RC2
      • +
      • 40 bit $B80$G$N(B DES
      • +
      • 56 bit $B80$G$N(B DES
      • +
      • 168 bit $B80$G$N(B Triple-DES
      • +
      • Idea (128 bit $B80(B)
      • +
      • Fortezza (96 bit $B80(B)
      • +
    • +
    + +

    $B$3$3$G$N(B CBC $B$H$O0E9f%V%m%C%/O":?(B (Cipher Block Chaining) + $B$NN,$G!"0l$DA0$N0E9f2=$5$l$?0E9fJ8$N0lIt$,(B + $B%V%m%C%/$N0E9f2=$K;H$o$l$k$3$H$r0UL#$7$^$9!#(B + DES $B$O%G!<%?0E9f2=I8=`5,3J(B (Data Encryption Standard) + [AC96, ch12] $B$NN,$G!"(B + DES40 $B$d(B 3DES_EDE $B$r4^$`$$$/$D$b$NAC96, + ch13]

    +
    + +
    +$B%@%$%8%'%9%H4X?t(B +

    + $B%@%$%8%'%9%H4X?t$NA*Br$O%l%3!<%I%f%K%C%H$+$i$I$N$h$&$K%@%$%8%'%9%H$,@8@.$5$l$k$+$r7hDj$7$^$9!#(B + SSL $B$O0J2<$r%5%]!<%H$7$^$9(B:

    + +
      +
    • $B%@%$%8%'%9%H$J$7(B
    • +
    • MD5 (128-bit $B%O%C%7%e(B)
    • +
    • Secure Hash Algorithm (SHA-1) (160-bit $B%O%C%7%e(B)
    • +
    + +

    $B%a%C%;!<%8%@%$%8%'%9%H$O(B Message Authentication Code (MAC) + $B$N@8@.$K;H$o$l!"%a%C%;!<%8$H6&$K0E9f2=$5$l!"%a%C%;!<%8$N?.MQ$r(B + $BDs6!$7!"%j%W%l%$967b$rKI$.$^$9!#(B

    +
    + +
    +$B%O%s%I%7%'!<%/%7!<%/%(%s%9%W%m%H%3%k(B +

    $B%O%s%I%7%'!<%/%7!<%/%(%s%9$O;0$D$N%W%m%H%3%k$r;H$$$^$9(B:

    + +
      +
    • SSL $B%O%s%I%7%'!<%/%W%m%H%3%k(B$B$O(B + $B%/%i%$%"%s%H$H%5!<%P4V$G$N(B SSL $B%;%C%7%g%s$N3NN)$K;H$o$l$^$9!#(B
    • +
    • SSL $B0E9f;EMMJQ99%W%m%H%3%k(B$B$O(B + $B%;%C%7%g%s$G$N0E9f%9%$!<%H$N +
    • SSL $B7Y9p%W%m%H%3%k(B$B$O(B + $B%/%i%$%"%s%H%5!<%P4V$G(B SSL $B%(%i!<$rEAC#$9$k$N$K;H$o$l$^$9!#(B
    • +
    + +

    $B;0$D$N%W%m%H%3%k$O!"%"%W%j%1!<%7%g%s%W%m%H%3%k%G!<%?$H$H$b$K!"(B + $B?^(B2$B$K<($9$H$*$j(B SSL $B%l%3!<%I%W%m%H%3%k(B + $B$G%+%W%;%k2=$5$l$^$9!#(B + $B%+%W%;%k2=$5$l$?%W%m%H%3%k$O%G!<%?$r8!::$7$J$$(B + $B2 + +

    +
    + $B?^(B2: SSL $B%W%m%H%3%k%9%?%C%/(B +

    + +

    + $B%l%3!<%I%W%m%H%3%k$K$h$k(B SSL $B%3%s%H%m!<%k%W%m%H%3%k$N%+%W%;%k2=$O!"(B + $B%"%/%F%#%V$J%;%C%7%g%s$NFs2sL\$NDL?.$,$"$C$?>l9g!"(B + $B%3%s%H%m!<%k%W%m%H%3%k$,0BA4$G$"$k$3$H$r0UL#$7$^$9!#(B + $B4{$K%;%C%7%g%s$,L5$$>l9g$O!"(BNull $B0E9f%9%$!<%H$,;H$o$l!"(B + $B0E9f2=$O9T$J$o$l$:!"%;%C%7%g%s$,3NN)$9$k$^$G$O(B + $B%@%$%8%'%9%H$bL5$$>uBV$H$J$j$^$9!#(B

    +
    + +
    +$B%G!<%?DL?.(B +

    $B?^(B3$B$K<($5$l$k(B SSL $B%l%3!<%I%W%m%H%3%k(B + $B$O%/%i%$%"%s%H$H%5!<%P4V$N%"%W%j%1!<%7%g%s$d(B + SSL $B%3%s%H%m!<%k%G!<%?$NDL?.$K;H$o$l$^$9!#(B + $B$3$N%G!<%?$O$h$j>.$5$$%f%K%C%H$KJ,$1$i$l$?$j!"(B + $B$$$/$D$+$N9b5i%W%m%H%3%k$r$^$H$a$F0l%f%K%C%H$H$7$FDL?.$,(B + $B9T$J$o$l$k$3$H$b$"$j$^$9!#(B + $B%G!<%?$r05=L$7!"%@%$%8%'%9%H=pL>$rE:IU$7$F!"(B + $B$3$l$i$N%f%K%C%H$r0E9f2=$7$?$N$A!"%Y!<%9$H$J$C$F$$$k(B + $B?.Mj@-$N$"$k%H%i%s%9%]!<%H%W%m%H%3%k$rMQ$$$k$+$b$7$l$^$;$s!#(B + ($BCm0U(B: $B8=:_%a%8%c!<$J(B SLL $B + +

    +
    + $B?^(B 3: SSL $B%l%3!<%I%W%m%H%3%k(B +

    +
    + +
    +HTTP $BDL?.$N0BA42=(B +

    $B$h$/$"$k(B SSL $B$N;H$$J}$O%V%i%&%6$H%&%'%V%5!<%P4V$N(B HTTP $BDL?.(B + $B$N0BA42=$G$9!#(B + $B$3$l$O!"=>Mh$N0BA4$G$O$J$$(B HTTP $B$N;HMQ$r=|30$9$k$b$N$G$O$"$j$^$;$s!#(B + $B0BA42=$5$l$?$b$N$Oe$NIaDL$N(B HTTP $B$G!"(BHTTPS $B$H8F$P$l$^$9!#(B + $BBg$-$J0c$$$O!"(BURL $B%9%-!<%`$K(B http $B$NBe$o$j$K(B https + $B$rMQ$$!"%5!<%P$,JL$N%]!<%H$r;H$&$3$H$G$9(B ($B%G%U%)%k%H$G$O(B443)$B!#(B + $B$3$l$,mod_ssl $B$,(B Apache $B%&%'%V%5!<%P$KDs6!$9$k5!G=$G$9!#(B

    +
    +
    + + +
    +$B;29MJ88%(B +
    +
    [AC96]
    +
    Bruce Schneier, Applied Cryptography, 2nd Edition, Wiley, +1996. See http://www.counterpane.com/ for various other materials by Bruce +Schneier.
    + +
    [X208]
    +
    ITU-T Recommendation X.208, Specification of Abstract Syntax Notation +One (ASN.1), 1988. See for instance http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.208-198811-I. +
    + +
    [X509]
    +
    ITU-T Recommendation X.509, The Directory - Authentication +Framework. See for instance http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.509. +
    + +
    [PKCS]
    +
    Public Key Cryptography Standards (PKCS), +RSA Laboratories Technical Notes, See http://www.rsasecurity.com/rsalabs/pkcs/.
    + +
    [MIME]
    +
    N. Freed, N. Borenstein, Multipurpose Internet Mail Extensions +(MIME) Part One: Format of Internet Message Bodies, RFC2045. +See for instance http://ietf.org/rfc/rfc2045.txt.
    + +
    [SSL2]
    +
    Kipp E.B. Hickman, The SSL Protocol, 1995. See http://www.netscape.com/eng/security/SSL_2.html.
    + +
    [SSL3]
    +
    Alan O. Freier, Philip Karlton, Paul C. Kocher, The SSL Protocol +Version 3.0, 1996. See http://www.netscape.com/eng/ssl3/draft302.txt.
    + +
    [TLS1]
    +
    Tim Dierks, Christopher Allen, The TLS Protocol Version 1.0, +1999. See http://ietf.org/rfc/rfc2246.txt.
    +
    +
    + + +
    diff --git a/trunk/docs/manual/ssl/ssl_intro.xml.meta b/trunk/docs/manual/ssl/ssl_intro.xml.meta new file mode 100644 index 0000000000..da798513f9 --- /dev/null +++ b/trunk/docs/manual/ssl/ssl_intro.xml.meta @@ -0,0 +1,12 @@ + + + + ssl_intro + /ssl/ + .. + + + en + ja + + diff --git a/trunk/docs/manual/stopping.html b/trunk/docs/manual/stopping.html new file mode 100644 index 0000000000..ceae360810 --- /dev/null +++ b/trunk/docs/manual/stopping.html @@ -0,0 +1,19 @@ +URI: stopping.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: stopping.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: stopping.html.es +Content-Language: es +Content-type: text/html; charset=ISO-8859-1 + +URI: stopping.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: stopping.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/stopping.html.de b/trunk/docs/manual/stopping.html.de new file mode 100644 index 0000000000..37c5bad95f --- /dev/null +++ b/trunk/docs/manual/stopping.html.de @@ -0,0 +1,252 @@ + + + +Beenden und Neustarten - Apache HTTP Server + + + + + +
    <-
    +

    Beenden und Neustarten

    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    Dieses Dokument umfasst das Beenden und Neustarten des + Apache auf Unix-ähnlichen Systemen. Anwender von Windows NT, 2000 + und XP sollten Betreiben + des Apache als Dienst lesen, während hingegen Anwender von + Windows 9x sowie ME Betreiben + des Apache als Konsolenanwendung lesen sollten, um mehr Informationen + zur Handhabung des Apache auf diesen Systemen zu erhalten.

    +
    + +
    top
    +
    +

    Einleitung

    + +

    Um den Apache zu stoppen oder neu zu starten, müssen Sie + ein Signal an den laufenden httpd-Prozess senden. Es gibt + zwei Möglichkeiten, diese Signale zu senden. Zum einen können + Sie den Unix-Befehl kill verwenden, um den Prozessen + direkt Signale zu senden. Sie werden feststellen, dass auf Ihrem + System mehrere httpd-Programme laufen. Sie sollten + jedoch nicht jedem dieser Prozesse ein Signal senden, sondern nur dem + Elternprozess, dessen PID im PidFile steht. Das heißt, Sie + sollten es niemals nötig haben, einem anderen Prozess, als dem + Elternprozess, ein Signal zu senden. Es gibt drei Signale, die Sie an den + Elternprozess senden können: TERM, + HUP und + USR1, die nachfolgend beschrieben + werden.

    + +

    Um dem Elternprozess ein Signal zu senden, verwenden Sie einen + Befehl wie z.B.:

    + +

    kill -TERM `cat /usr/local/apache2/logs/httpd.pid`

    + +

    Die zweite Methode, dem httpd-Prozess zu + signalisieren, ist die Verwendung der -k-Befehlszeilenoptionen + stop, restart und graceful, wie + unten beschrieben. Dies sind Argumente des httpd-Programms, es wird jedoch + empfohlen, sie unter Verwendung des Steuerskripts apachectl zu senden, welches diese + an httpd durchreicht.

    + +

    Nachdem Sie httpd signalisiert haben, können Sie + dessen Fortschritt beobachten, indem Sie eingeben:

    + +

    tail -f /usr/local/apache2/logs/error_log

    + +

    Passen Sie diese Beispiele entsprechend Ihren ServerRoot- und PidFile-Einstellungen an.

    +
    top
    +
    +

    Beenden

    + +
    Signal: TERM
    +
    apachectl -k stop
    +
    + +

    Das Senden des TERM- oder stop-Signals an + den Elternprozess veranlasst diesen, sofort zu versuchen, alle seine + Kindprozesse zu beenden. Es kann einige Sekunden dauern, bis alle + Kindprozesse komplett beendet sind. Danach beendet sich der Elternprozess + selbst. Alle gerade bearbeiteten Anfragen werden abgebrochen. + Es werden keine weiteren Anfragen mehr bedient.

    +
    top
    +
    +

    Unterbrechungsfreier Neustart

    + +
    Signal: USR1
    +
    apachectl -k graceful
    +
    + +

    Das USR1- oder graceful-Signal + veranlasst den Elternprozess, die Kinder anzuweisen, sich + nach Abschluß ihrer momentanen bearbeiteten Anfrage zu beenden + (oder sich sofort zu beenden, wenn sie gerade keine Anfrage bedienen). + Der Elternprozess liest seine Konfigurationsdateien erneut ein und + öffnet seine Logdateien neu. Wenn ein Kindprozess stirbt, + ersetzt der Elternprozess ihn durch ein Kind der neuen + Konfigurations-Generation. Dieses beginnt sofort damit, + neue Anfragen zu bedienen.

    + +
    Auf bestimmten Plattformen, welche kein USR1 + für einen unterbrechungsfreien Neustart erlauben, kann ein + alternatives Signal verwendet werden (wie z.B. + WINCH). Der Befehl apachectl graceful + sendet das jeweils richtige Signal für Ihre Platform.
    + +

    Der Code ist dafür ausgelegt, stets die MPM-Direktiven + zur Prozesssteuerung zu beachten, so dass die Anzahl der Prozesse + und Threads, die zur Bedienung der Clients bereitstehen, während + des Neustarts auf die entsprechenden Werte gesetzt werden. + Weiterhin wird StartServers + auf folgende Art und Weise interpretiert: Wenn nach einer Sekunde + nicht mindestens StartServers + neue Kindprozesse erstellt wurden, dann werden, um den Durchsatz zu + beschleunigen, entsprechend weitere erstellt. Auf diese Weise versucht + der Code sowohl die Anzahl der Kinder entsprechend der Serverlast + anzupassen als auch Ihre Wünsche hinsichtlich des Parameters + StartServers zu berücksichtigen.

    + +

    Benutzer von mod_status werden feststellen, + dass die Serverstatistiken nicht auf Null + zurückgesetzt werden, wenn ein USR1 gesendet + wurde. Der Code wurde so geschrieben, dass sowohl die Zeit minimiert + wird, in der der Server nicht in der Lage ist, neue Anfragen zu + bedienen (diese werden vom Betriebssystem in eine Warteschlange + gestellt, so dass sie auf keinen Fall verloren gehen) als auch + Ihre Parameter zur Feinabstimmung berücksichtigt werden. + Um dies zu erreichen, muss die Statustabelle (Scoreboard), + die dazu verwendet wird, alle Kinder über mehrere Generationen + zu verfolgen, erhalten bleiben.

    + +

    Das Statusmodul benutzt außerdem ein G, um + diejenigen Kinder zu kennzeichen, die noch immer Anfragen bedienen, + welche gestartet wurden, bevor ein unterbrechungsfreier Neustart + veranlaßt wurde.

    + +

    Derzeit gibt es keine Möglichkeit für ein + Log-Rotationsskript, das USR1 verwendet, sicher + festzustellen, dass alle Kinder, die in ein vor dem Neustart + geöffnetes Log schreiben, beendet sind. Wir schlagen vor, dass + Sie nach dem Senden des Signals USR1 eine angemessene + Zeitspanne warten, bevor Sie das alte Log anfassen. Wenn beispielsweise + die meisten Ihrer Zugriffe bei Benutzern mit niedriger Bandbreite + weniger als 10 Minuten für eine vollständige Antwort + benötigen, dann könnten Sie 15 Minuten warten, bevor Sie auf + das alte Log zugreifen.

    + +
    Wenn Ihre Konfigurationsdatei Fehler enthält, während + Sie einen Neustart anweisen, dann wird Ihr Elternprozess nicht neu starten, + sondern sich mit einem Fehler beenden. Im Falle eines unterbrechungsfreien + Neustarts läßt er die Kinder weiterlaufen, wenn er sich beendet. + (Dies sind die Kinder, die sich "sanft beenden", indem sie ihre letzte + Anfrage erledigen.) Das verursacht Probleme, wenn Sie versuchen, + den Server neu zu starten -- er ist nicht in der Lage, sich an die Ports zu + binden, an denen er lauschen soll. Bevor Sie einen Neustart + durchführen, können Sie die Syntax der Konfigurationsdateien + mit dem Befehlszeilenargument -t überprüfen + (siehe auch httpd). Das garantiert + allerdings nicht, dass der Server korrekt starten wird. Um sowohl die + Syntax als auch die Semantik der Konfigurationsdateien zu prüfen, + können Sie versuchen, httpd als nicht-root-Benutzer + zu starten. Wenn dabei keine Fehler auftreten, wird er versuchen, seine + Sockets und Logdateien zu öffnen und fehlschlagen, da er nicht root + ist (oder weil sich der gegenwärtig laufende httpd + bereits diese Ports gebunden hat). Wenn er aus einem anderen Grund + fehlschlägt, dann liegt wahrscheinlich ein Konfigurationsfehler vor. + Der Fehler sollte behoben werden, bevor der unterbrechungsfreie Neustart + angewiesen wird.
    +
    top
    +
    +

    Neustarten

    + +
    Signal: HUP
    +
    apachectl -k restart
    +
    + +

    Das Senden des Signals HUP oder restart + veranlaßt den Elternprozess, wie bei TERM alle seine + Kinder zu beenden. Der Elternprozess beendet sich jedoch nicht. Er liest + seine Konfigurationsdateien neu ein und öffnet alle Logdateien + erneut. Dann erzeugt er einen neuen Satz Kindprozesse und setzt die + Bedienung von Zugriffen fort.

    + +

    Benutzer von mod_status werden feststellen, dass + die Serverstatistiken auf Null gesetzt werden, wenn ein HUP + gesendet wurde.

    + +
    Wenn Ihre Konfigurationsdatei einen Fehler enthält, + während Sie einen Neustart anweisen, dann wird Ihr Elternprozess + nicht neu starten, sondern sich mit einem Fehler beenden. Lesen Sie oben, + wie Sie das vermeiden können.
    +
    top
    +
    +

    Anhang: Signale und Wettkampfsituationen

    + +

    Vor der Version 1.2b9 des Apache existierten verschiedene + Wettkampfsituationen (race conditions), die den Neustart und + die Signale beeinflußt haben. (Eine einfache Beschreibung einer + Wettkampfsituation lautet: es ist ein zeitabhängiges Problem; wenn + etwas zum falschen Zeitpunkt erfolgt, wird es sich nicht wie erwartet + verhalten.) Bei Architekturen mit dem "richtigen" Funktionsumfang + haben wir so viele eliminiert wie wir nur konnten. Dennoch + sollte beachtet werden, dass noch immer Wettkampfsituationen auf + bestimmten Architekturen existieren.

    + +

    Bei Architekturen, die ein ScoreBoardFile auf Platte verwenden, + besteht die Gefahr, dass die Statustabelle beschädigt wird. + Das kann zu "bind: Address already in use" ("bind: Adresse wird + bereits verwendet", nach einem HUP) oder "long lost + child came home!" ("Der verlorene Sohn ist heimgekehrt", nach einem + USR1) führen. Ersteres ist ein schwerer Fehler, + wärend letzteres lediglich bewirkt, dass der Server einen Eintrag + in der Statustabelle verliert. So kann es ratsam sein, unterbrechungsfreie + Neustarts zusammen mit einem gelegentlichen harten Neustart zu verwenden. + Diese Probleme lassen sich nur sehr schwer umgehen, aber + glücklicherweise benötigen die meisten Architekturen keine + Statustabelle in Form einer Datei. Bitte lesen Sie für Architekturen, + die sie benötigen, die Dokumentation zu ScoreBoardFile.

    + +

    Alle Architekturen haben in jedem Kindprozess eine kleine + Wettkampfsituation, welche die zweite und nachfolgende Anfragen + einer persistenten HTTP-Verbindung (KeepAlive) umfaßt. Der Prozess + kann nach dem Lesen der Anfragezeile aber vor dem Lesen der Anfrage-Header + enden. Es existiert eine Korrektur, die für 1.2 zu spät kam. + Theoretisch sollte das kein Problem darstellen, da + der KeepAlive-Client derartige Ereignisse aufgrund von + Netzwerk-Latenzzeiten und Auszeiten des Servers erwarten sollte. + In der Praxis scheint keiner von beiden beeinflußt zu werden + -- in einem Testfall wurde der Server zwanzig mal + pro Sekunde neu gestartet, während Clients das Angebot abgegrast + haben, ohne kaputte Bilder oder leere Dokumente zu erhalten.

    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/stopping.html.en b/trunk/docs/manual/stopping.html.en new file mode 100644 index 0000000000..4879eb92d1 --- /dev/null +++ b/trunk/docs/manual/stopping.html.en @@ -0,0 +1,229 @@ + + + +Stopping and Restarting - Apache HTTP Server + + + + + +
    <-
    +

    Stopping and Restarting

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    This document covers stopping and restarting Apache on + Unix-like systems. Windows NT, 2000 and XP users should see + Running Apache as a + Service and Windows 9x and ME users should see Running Apache as a + Console Application for information on how to control + Apache on those platforms.

    +
    + +
    top
    +
    +

    Introduction

    + +

    In order to stop or restart Apache, you must send a signal to + the running httpd processes. There are two ways to + send the signals. First, you can use the unix kill + command to directly send signals to the processes. You will + notice many httpd executables running on your system, + but you should not send signals to any of them except the parent, + whose pid is in the PidFile. That is to say you + shouldn't ever need to send signals to any process except the + parent. There are three signals that you can send the parent: + TERM, + HUP, and + USR1, which + will be described in a moment.

    + +

    To send a signal to the parent you should issue a command + such as:

    + +

    kill -TERM `cat /usr/local/apache2/logs/httpd.pid`

    + +

    The second method of signaling the httpd processes + is to use the -k command line options: stop, + restart, and graceful, + as described below. These are arguments to the httpd binary, but we recommend that + you send them using the apachectl control script, which + will pass them through to httpd.

    + +

    After you have signaled httpd, you can read about + its progress by issuing:

    + +

    tail -f /usr/local/apache2/logs/error_log

    + +

    Modify those examples to match your ServerRoot and PidFile settings.

    +
    top
    +
    +

    Stop Now

    + +
    Signal: TERM
    +
    apachectl -k stop
    +
    + +

    Sending the TERM or stop signal to + the parent causes it to immediately attempt to kill off all of its + children. It may take it several seconds to complete killing off + its children. Then the parent itself exits. Any requests in + progress are terminated, and no further requests are served.

    +
    top
    +
    +

    Graceful Restart

    + +
    Signal: USR1
    +
    apachectl -k graceful
    +
    + +

    The USR1 or graceful signal causes + the parent process to advise the children to exit after + their current request (or to exit immediately if they're not + serving anything). The parent re-reads its configuration files and + re-opens its log files. As each child dies off the parent replaces + it with a child from the new generation of the + configuration, which begins serving new requests immediately.

    + +
    On certain platforms that do not allow USR1 to + be used for a graceful restart, an alternative signal may be used (such + as WINCH). The command apachectl graceful + will send the right signal for your platform.
    + +

    This code is designed to always respect the process control + directive of the MPMs, so the number of processes and threads + available to serve clients will be maintained at the appropriate + values throughout the restart process. Furthermore, it respects + StartServers in the + following manner: if after one second at least StartServers new children have not + been created, then create enough to pick up the slack. Hence the + code tries to maintain both the number of children appropriate for + the current load on the server, and respect your wishes with the + StartServers parameter.

    + +

    Users of the mod_status + will notice that the server statistics are not + set to zero when a USR1 is sent. The code was + written to both minimize the time in which the server is unable + to serve new requests (they will be queued up by the operating + system, so they're not lost in any event) and to respect your + tuning parameters. In order to do this it has to keep the + scoreboard used to keep track of all children across + generations.

    + +

    The status module will also use a G to indicate + those children which are still serving requests started before + the graceful restart was given.

    + +

    At present there is no way for a log rotation script using + USR1 to know for certain that all children writing + the pre-restart log have finished. We suggest that you use a + suitable delay after sending the USR1 signal + before you do anything with the old log. For example if most of + your hits take less than 10 minutes to complete for users on + low bandwidth links then you could wait 15 minutes before doing + anything with the old log.

    + +
    If your configuration file has errors + in it when you issue a restart then your parent will not + restart, it will exit with an error. In the case of graceful + restarts it will also leave children running when it exits. + (These are the children which are "gracefully exiting" by + handling their last request.) This will cause problems if you + attempt to restart the server -- it will not be able to bind to + its listening ports. Before doing a restart, you can check the + syntax of the configuration files with the -t + command line argument (see httpd). This still will not + guarantee that the server will restart correctly. To check the + semantics of the configuration files as well as the syntax, you + can try starting httpd as a non-root user. If there + are no errors it will attempt to open its sockets and logs and fail + because it's not root (or because the currently running + httpd already has those ports bound). If it fails + for any other reason then it's probably a config file error and the error + should be fixed before issuing the graceful restart.
    +
    top
    +
    +

    Restart Now

    + +
    Signal: HUP
    +
    apachectl -k restart
    +
    + +

    Sending the HUP or restart signal to + the parent causes it to kill off its children like in + TERM, but the parent doesn't exit. It re-reads its + configuration files, and re-opens any log files. Then it spawns a + new set of children and continues serving hits.

    + +

    Users of mod_status + will notice that the server statistics are set to zero when a + HUP is sent.

    + +
    If your configuration file has errors in it when you issue a +restart then your parent will not restart, it will exit with an +error. See above for a method of avoiding this.
    +
    top
    +
    +

    Appendix: signals and race conditions

    + +

    Prior to Apache 1.2b9 there were several race + conditions involving the restart and die signals (a simple + description of race condition is: a time-sensitive problem, as + in if something happens at just the wrong time it won't behave + as expected). For those architectures that have the "right" + feature set we have eliminated as many as we can. But it should + be noted that there still do exist race conditions on certain + architectures.

    + +

    Architectures that use an on disk ScoreBoardFile have the potential + to corrupt their scoreboards. This can result in the "bind: + Address already in use" (after HUP) or "long lost + child came home!" (after USR1). The former is a fatal + error, while the latter just causes the server to lose a + scoreboard slot. So it might be advisable to use graceful + restarts, with an occasional hard restart. These problems are very + difficult to work around, but fortunately most architectures do + not require a scoreboard file. See the ScoreBoardFile documentation for a + architecture uses it.

    + +

    All architectures have a small race condition in each child + involving the second and subsequent requests on a persistent + HTTP connection (KeepAlive). It may exit after reading the + request line but before reading any of the request headers. + There is a fix that was discovered too late to make 1.2. In + theory this isn't an issue because the KeepAlive client has to + expect these events because of network latencies and server + timeouts. In practice it doesn't seem to affect anything either + -- in a test case the server was restarted twenty times per + second and clients successfully browsed the site without + getting broken images or empty documents.

    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/stopping.html.es b/trunk/docs/manual/stopping.html.es new file mode 100644 index 0000000000..c9f2d28aba --- /dev/null +++ b/trunk/docs/manual/stopping.html.es @@ -0,0 +1,267 @@ + + + +Iniciar y Parar el servidor Apache - Servidor HTTP Apache + + + + + +
    <-
    +

    Iniciar y Parar el servidor Apache

    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente.
    + +

    Este documento explica como iniciar y parar el servidor Apache + en sistemas tipo Unix. Los usuarios de Windows NT, 2000 y XP + deben consultar la sección Ejecutar Apache como un + servicio y los usuario de Windows 9x y ME deben consultar Ejecutar Apache como una + Aplicación de Consola para obtener información + sobre como controlar Apache en esas plataformas.

    +
    + +
    top
    +
    +

    Introducción

    + +

    Para parar y reiniciar Apache, hay que enviar la señal + apropiada al proceso padre httpd que se esté + ejecutando. Hay dos maneras de enviar estas señales. En + primer lugar, puede usar el comando de Unix kill que + envía señales directamente a los procesos. Puede que + tenga varios procesos httpd ejecutandose en su + sistema, pero las señales deben enviarse solamente al proceso + padre, cuyo pid está especificado en la directiva PidFile. Esto quiere decir que no + debe necesitar enviar señales a ningún proceso excepto + al proceso padre. Hay tres señales que puede enviar al + proceso padre: TERM, HUP, y USR1, que van a ser descritas a + continuación.

    + +

    Para enviar una señal al proceso padre debe escribir un + comando como el que se muestra en el ejemplo:

    + +

    kill -TERM `cat /usr/local/apache2/logs/httpd.pid`

    + +

    La segunda manera de enviar señales a los procesos + httpd es usando las opciones de línea de + comandos -k: stop, restart, + y graceful, como se muestra más abajo. Estas + opciones se le pueden pasar al binario httpd, pero se recomienda que se + pasen al script de control apachectl, que a su vez los + pasará a httpd.

    + +

    Después de haber enviado las señales que desee a + httpd, puede ver como progresa el proceso + escribiendo:

    + +

    tail -f /usr/local/apache2/logs/error_log

    + +

    Modifique estos ejemplos para que coincidan con la + configuración que tenga especificada en las directivas + ServerRoot y PidFile en su fichero principal de + configuración.

    +
    top
    +
    +

    Parar Apache

    + +
    Señal: TERM
    +
    apachectl -k stop
    +
    + +

    Enviar las señales TERM o stop + al proceso padre hace que se intenten eliminar todos los procesos + hijo inmediatamente. Esto puede tardar algunos minutos. Una vez + que hayan terminado todos los procesos hijo, terminará el + proceso padre. Cualquier petición en proceso terminará + inmediatanmente, y ninguna petición posterior será + atendida.

    +
    top
    +
    +

    Reinicio Graceful

    + +
    Señal: USR1
    +
    apachectl -k graceful
    +
    + +

    Las señales USR1 o graceful + hacen que el proceso padre indique a sus hijos que + terminen después de servir la petición que estén + atendiendo en ese momento (o de inmediato si no están + sirviendo ninguna petición). El proceso padre lee de nuevo + sus ficheros de configuración y vuelve a abrir sus ficheros + log. Conforme cada hijo va terminando, el proceso padre lo va + sustituyendo con un hijo de una nueva generación con + la nueva configuración, que empeciezan a servir peticiones + inmediatamente.

    + +
    En algunas plataformas que no permiten usar + USR1 para reinicios graceful, puede usarse una + señal alternativa (como WINCH). Tambien puede + usar apachectl graceful y el script de control + enviará la señal adecuada para su plataforma.
    + +

    Apache está diseñado para respetar en todo momento la + directiva de control de procesos de los MPM, así como para + que el número de procesos y hebras disponibles para servir a + los clientes se mantenga en los valores adecuados durante el + proceso de reinicio. Aún más, está diseñado + para respetar la directiva StartServers de la siguiente + manera: si después de al menos un segundo el nuevo hijo de la + directiva StartServers + no ha sido creado, entonces crea los suficientes para se atienda + el trabajo que queda por hacer. Así, se intenta mantener + tanto el número de hijos adecuado para el trabajo que el + servidor tenga en ese momento, como respetar la configuración + determinada por los parámetros de la directiva + StartServers.

    + +

    Los usuarios del módulo mod_status + notarán que las estadísticas del servidor + no se ponen a cero cuando se usa la señal + USR1. Apache fue escrito tanto para minimizar el + tiempo en el que el servidor no puede servir nuevas peticiones + (que se pondrán en cola por el sistema operativo, de modo que + se no se pierda ningún evento), como para respetar sus + parámetros de ajuste. Para hacer esto, tiene que guardar el + scoreboard usado para llevar el registro de los procesos + hijo a través de las distintas generaciones.

    + +

    El mod_status también usa una G para indicar + que esos hijos están todavía sirviendo peticiones + previas al reinicio graceful.

    + +

    Actualmente no existe ninguna manera de que un script con un + log de rotación usando USR1 sepa con seguridad + que todos los hijos que se registraron en el log con anterioridad + al reinicio han terminado. Se aconseja que se use un retardo + adecuado después de enviar la señal USR1 + antes de hacer nada con el log antiguo. Por ejemplo, si la mayor + parte las visitas que recibe de usuarios que tienen conexiones de + baja velocidad tardan menos de 10 minutos en completarse, entoces + espere 15 minutos antes de hacer nada con el log antiguo.

    + +
    Si su fichero de configuración tiene errores cuando + haga el reinicio, entonces el proceso padre no se reinciciará + y terminará con un error. En caso de un reinicio graceful, + también dejará a los procesos hijo ejecutandose mientras + existan. (Estos son los hijos de los que se está saliendo de + forma graceful y que están sirviendo sus últimas + peticiones.) Esto provocará problemas si intenta reiniciar el + servidor -- no será posible conectarse a la lista de puertos + de escucha. Antes de reiniciar, puede comprobar que la sintaxis de + sus ficheros de configuracion es correcta con la opción de + línea de comandos -t (consulte httpd). No obstante, esto no + garantiza que el servidor se reinicie correctamente. Para + comprobar que no hay errores en los ficheros de + configuración, puede intentar iniciar httpd con + un usuario diferente a root. Si no hay errores, intentará + abrir sus sockets y logs y fallará porque el usuario no es + root (o porque el httpd que se está ejecutando + en ese momento ya está conectado a esos puertos). Si falla + por cualquier otra razón, entonces casi seguro que hay + algún error en alguno de los ficheros de configuración y + debe corregir ese o esos errores antes de hacer un reinicio + graceful.
    +
    top
    +
    +

    Reiniciar Apache

    + +
    Señal: HUP
    +
    apachectl -k restart
    +
    + +

    El envío de las señales HUP o + restart al proceso padre hace que los procesos hijo + terminen como si le enviá ramos la señal + TERM, para eliminar el proceso padre. La diferencia + está en que estas señales vuelven a leer los archivos de + configuración y vuelven a abrir los ficheros log. Se genera + un nuevo conjunto de hijos y se continúa sirviendo + peticiones.

    + +

    Los usuarios del módulo mod_status + notarán que las estadísticas del servidor se ponen a + cero cuando se envía la señal HUP.

    + +
    Si su fichero de configuración contiene errores, cuando +intente reiniciar, el proceso padre del servidor no se +reiniciará, sino que terminará con un error. Consulte +más arriba cómo puede solucionar este problema.
    +
    top
    +
    +

    Apéndice: señales y race conditions

    + +

    Con anterioridad a la versión de Apache 1.2b9 había + varias race conditions implicadas en las señales + para parar y reiniciar procesos (una descripción sencilla de + una race condition es: un problema relacionado con el momento en + que suceden las cosas, como si algo sucediera en momento en que no + debe, y entonces el resultado esperado no se corresponde con el + obtenido). Para aquellas arquitecturas que tienen el conjunto de + características "adecuadas", se han eliminado tantas race + conditions como ha sido posible. Pero hay que tener en cuenta que + todavía existen race conditions en algunas arquitecturas.

    + +

    En las arquitecturas que usan un ScoreBoardFile en disco, existe la + posibilidad de que se corrompan los scoreboards. Esto puede hacer + que se produzca el error "bind: Address already in use" + (después de usarHUP) o el error "long lost child + came home!" (después de usar USR1). En el + primer caso se trata de un error irrecuperable, mientras que en el + segundo, solo ocurre que el servidor pierde un slot del + scoreboard. Por lo tanto, sería aconsejable usar reinicios + graceful, y solo hacer reinicios normales de forma + ocasional. Estos problemas son bastante complicados de solucionar, + pero afortunadamente casi ninguna arquitectura necesita un fichero + scoreboard. Consulte la documentación de la directiva + ScoreBoardFile para ver + las arquitecturas que la usan.

    + +

    Todas las arquitecturas tienen una pequeña race condition + en cada proceso hijo implicada en la segunda y subsiguientes + peticiones en una conexión HTTP persistente + (KeepAlive). Puede ser que el servidor termine después de + leer la línea de petición pero antes de leer cualquiera + de las cebeceras de petición. Hay una solución que fue + descubierta demasiado tarde para la incluirla en versión + 1.2. En teoria esto no debe suponer ningún problema porque el + cliente KeepAlive ha de esperar que estas cosas pasen debido a los + retardos de red y a los timeouts que a veces dan los + servidores. En la practica, parece que no afecta a nada más + -- en una sesión de pruebas, un servidor se reinició + veinte veces por segundo y los clientes pudieron navegar sin + problemas por el sitio web sin encontrar problemas ni para + descargar una sola imagen ni encontrar un solo enlace roto.

    +
    +
    +

    Idiomas disponibles:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/stopping.html.ja.euc-jp b/trunk/docs/manual/stopping.html.ja.euc-jp new file mode 100644 index 0000000000..918de5eb59 --- /dev/null +++ b/trunk/docs/manual/stopping.html.ja.euc-jp @@ -0,0 +1,254 @@ + + + +Ää»ß¤ÈºÆµ¯Æ° - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Ää»ß¤ÈºÆµ¯Æ°

    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï Unix ¤ËÎà»÷¤·¤¿¥·¥¹¥Æ¥à¤Ç¤Î + Apache ¤ÎÄä»ß¤ÈºÆµ¯Æ°¤Ë¤Ä¤¤¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£ + Windows NT, 2000, XP ¥æ¡¼¥¶¤Ï¥µ¡¼¥Ó¥¹¤È¤·¤Æ + Apache ¤ò¼Â¹Ô¤¹¤ë¤Ç¡¢Windows 9x, ME¥æ¡¼¥¶¤Ï¥³¥ó¥½¡¼¥ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È¤·¤Æ + Apache ¤ò¼Â¹Ô¤¹¤ë¤Ç¡¢ + ¤³¤ì¤é¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Î»ÈÍÑÊýË¡¤ò¤´Í÷²¼¤µ¤¤¡£

    +
    + +
    top
    +
    +

    ¥¤¥ó¥È¥í¥À¥¯¥·¥ç¥ó

    + +

    Apache ¤òÄä»ß¤·¤¿¤êºÆµ¯Æ°¤·¤¿¤ê¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë + httpd ¥×¥í¥»¥¹¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¥·¥°¥Ê¥ë¤òÁ÷¤ë¤Ë¤ÏÆó¤Ä¤ÎÊýË¡¤¬¤¢¤ê¤Þ¤¹¡£ + °ì¤ÄÌÜ¤Ï¥×¥í¥»¥¹¤ËľÀÜ¥·¥°¥Ê¥ë¤òÁ÷¤ë unix ¤Î kill + ¥³¥Þ¥ó¥É¤ò»ÈÍѤ¹¤ëÊýË¡¤Ç¤¹¡£ + ¥·¥¹¥Æ¥à¤ò¸«¤ì¤Ð¤¿¤¯¤µ¤ó¤Î httpd ¤¬ + ¼Â¹Ô¤µ¤ì¤Æ¤¤¤ë¤Î¤Ëµ¤¤¬ÉÕ¤¯¤Ç¤·¤ç¤¦¤¬¡¢¥·¥°¥Ê¥ë¤òÁ÷¤ë¤Î¤Ï + ¿Æ¥×¥í¥»¥¹¤À¤±¤Ç¡¢¤½¤ì°Ê³°¤Î¸Ä¡¹¤Î¥×¥í¥»¥¹¤Ë¤Ï + ¥·¥°¥Ê¥ë¤òÁ÷¤é¤Ê¤¤¤Ç²¼¤µ¤¤¡£¤½¤Î¿Æ¥×¥í¥»¥¹¤Î pid ¤Ï + PidFile + ¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¤Ä¤Þ¤ê¡¢¿Æ°Ê³°¤Î¥×¥í¥»¥¹¤Ë + ¥·¥°¥Ê¥ë¤òÁ÷¤ëɬÍפ¹¤é¤Ê¤¤¡¢¤È¤¤¤¦¤³¤È¤Ç¤¹¡£ + ¿Æ¥×¥í¥»¥¹¤ËÁ÷¤ë¤³¤È¤¬¤Ç¤­¤ë 3 ¼ïÎà¤Î¥·¥°¥Ê¥ë¤¬¤¢¤ê¤Þ¤¹: + TERM, + HUP, + USR1 + ¤Ç¤¹¡£¤³¤ì¤é¤ÎÀâÌÀ¤Ë¤Ä¤¤¤Æ¤Ï³¤­¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    ¿Æ¥×¥í¥»¥¹¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë¤Ë¤Ï¡¢ + ¼¡¤Î¤è¤¦¤Ê¥³¥Þ¥ó¥É¤òȯ¹Ô¤·¤Æ²¼¤µ¤¤:

    + +

    kill -TERM `cat /usr/local/apache2/logs/httpd.pid`

    + +

    httpd ¥×¥í¥»¥¹¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë 2 ÈÖÌܤÎÊýË¡¤Ï + -k ¤È¤¤¤¦¥³¥Þ¥ó¥É¥é¥¤¥ó°ú¿ô¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¤¹¡£ + ²¼¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢stop, restart, + graceful ¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤Ï httpd ¤Î°ú¿ô¤Ç¤¹¤¬¡¢ + À©¸æÍѤΥ¹¥¯¥ê¥×¥È apachectl ¤Ï¤½¤ì¤é¤Î°ú¿ô¤ò¤½¤Î¤Þ¤Þ + httpd ¤ËÅϤ·¤Þ¤¹¡£

    + +

    httpd ¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤Ã¤¿¸å¡¢ + ¼Â¹Ô¾õ¶·¤ò¼¡¤Î¥³¥Þ¥ó¥É¤ÇÆɤळ¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    tail -f /usr/local/apache2/logs/error_log

    +

    ¤³¤³¤Ëµó¤²¤¿Îã¤Ï¡¢³Æ¼«¤Î + ServerRoot + ¤È + PidFile + ¤ÎÀßÄê¤ËŬ¹ç¤¹¤ë¤è¤¦¤ËŬµ¹½¤Àµ¤·¤Æ²¼¤µ¤¤¡£

    +
    top
    +
    +

    µÞ¤ÊÄä»ß

    + +
    ¥·¥°¥Ê¥ë: TERM
    +
    apachectl -k stop
    +
    + +

    TERM ¤¢¤ë¤¤¤Ï stop + ¥·¥°¥Ê¥ë¤ò¿Æ¥×¥í¥»¥¹¤ËÁ÷¤ë¤È¡¢Â¨ºÂ¤Ë»Ò¥×¥í¥»¥¹Á´¤Æ¤ò kill ¤·¤è¤¦¤È¤·¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤ò´°Á´¤Ë kill ¤·½ª¤ï¤ë¤Þ¤Ç¤Ë¿ôÉ䫤«¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¤½¤Î¸å¡¢¿Æ¥×¥í¥»¥¹¼«¿È¤¬½ªÎ»¤·¤Þ¤¹¡£ + ½èÍýÃæ¤Î¥ê¥¯¥¨¥¹¥È¤ÏÁ´¤ÆÄä»ß¤µ¤ì¡¢¤â¤Ï¤ä¥ê¥¯¥¨¥¹¥È¤ËÂФ¹¤ë + ±þÅú¤Ï¤µ¤ì¤Þ¤»¤ó¡£

    +
    top
    +
    +

    ´Ë¤ä¤«¤ÊºÆµ¯Æ°

    + +
    ¥·¥°¥Ê¥ë: USR1
    +
    apachectl -k graceful
    +
    + +

    ¿Æ¥×¥í¥»¥¹¤Ï USR1 ¤¢¤ë¤¤¤Ï graceful + ¥·¥°¥Ê¥ë¤ò¼õ¤±¼è¤ë¤È¡¢»Ò¥×¥í¥»¥¹¤Ë¸½ºß¤Î¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤Î¸å¤Ë½ªÎ»¤¹¤ë + (¤¢¤ë¤¤¤Ï²¿¤â¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¤¹¤°¤Ë½ªÎ»¤¹¤ë) + ¤è¤¦¤Ë½õ¸À¤·¤Þ¤¹¡£ + ¿Æ¥×¥í¥»¥¹¤ÏÀßÄê¥Õ¥¡¥¤¥ë¤òºÆÆɹþ¤·¤Æ¡¢¥í¥°¥Õ¥¡¥¤¥ë¤ò³«¤­Ä¾¤·¤Þ¤¹¡£ + »Ò¥×¥í¥»¥¹¤¬½ù¡¹¤Ë¤Ê¤¯¤Ê¤ë¤Ë½¾¤Ã¤Æ¡¢ + ¿·¤·¤¤À¤Âå¤ÎÀßÄê¤Ë¤è¤ë»Ò¥×¥í¥»¥¹¤ËÃÖ¤­´¹¤¨¤Æ¤¤¤­¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¤³¤ì¤é¤¬¿·¤¿¤Ê¥ê¥¯¥¨¥¹¥È¤Ë¨ºÂ¤Ë±þÅú¤·»Ï¤á¤Þ¤¹¡£

    + +
    ÆÃÄê¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Ï USR1 + ¤ò´Ë¤ä¤«¤ÊºÆµ¯Æ°¤Î¤¿¤á¤Ë»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¤¬¡¢Âå¤ï¤ê¤Î¥·¥°¥Ê¥ë + (Î㤨¤Ð WINCH) ¤¬»ÈÍѤǤ­¤ë¤Ç¤·¤ç¤¦¡£ + apachectl graceful + ¤È¤¤¤¦¥³¥Þ¥ó¥É¤Ï¥×¥é¥Ã¥È¥Û¡¼¥à¤Ë¹ç¤Ã¤¿¥·¥°¥Ê¥ë¤òÁ÷¤ê¤Þ¤¹¡£
    + +

    ¤³¤Î¥³¡¼¥É¤Ï¾ï¤Ë + MPM ¤Î¥×¥í¥»¥¹À©¸æ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤ò½Å»ë¤·¤Þ¤¹¤Î¤Ç¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¥×¥í¥»¥¹¤È¥¹¥ì¥Ã¥É¤Î¿ô¤òºÆµ¯Æ°¤Î½èÍýÃæ¤â + ŬÀÚ¤ÊÃͤ˰ݻý¤µ¤ì¤Þ¤¹¡£¡£¤Þ¤¿¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Æ + StartServers + ¤ò¼é¤ê¤Þ¤¹: + ¾¯¤Ê¤¯¤È¤â 1 Éøå¤Ë StartServers ¸Ä¤Î¿·¤·¤¤»Ò¥×¥í¥»¥¹¤¬ + À¸À®¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢¤½¤Î¿ô¤Ë¤Ê¤ë¤è¤¦¤ËŬµ¹¥×¥í¥»¥¹¤òÀ¸À®¤·¤Þ¤¹¡£ + ¤³¤ÎµóÆ°¤Ï¸½ºß¤ÎÉé²Ù¤ËÂФ·¤ÆŬÀÚ¤Ê»Ò¥×¥í¥»¥¹¤Î¿ô¤È + StartServers ¥Ñ¥é¥á¡¼¥¿¤Ç¤Î + ´õ˾¤Î¿ô¤ÎξÊý¤ò°Ý»ý¤·¤è¤¦¤È¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    mod_status ¤ò + »ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢USR1 ¥·¥°¥Ê¥ë¤¬Á÷¤é¤ì¤¿ºÝ¤Ë + ¥µ¡¼¥ÐÅý·×¤¬¥¼¥í¤ËÀßÄꤵ¤ì¤Ê¤¤¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¥µ¡¼¥Ð¤¬¿·¤·¤¤¥ê¥¯¥¨¥¹¥È¤Ë±þÅúÉÔǽ¤Ê»þ´Ö¤òºÇ¾®¤Ë¤¹¤ë¤è¤¦¤Ë + (¥ê¥¯¥¨¥¹¥È¤Ï OS ¤Ë¤è¤Ã¤Æ¥­¥å¡¼¤ËÄɲ䵤ì¤ë¤Î¤ÇÀäÂФËʶ¼º¤Ï¤·¤Þ¤»¤ó)¡¢ + ¤Þ¤¿Æ±»þ¤Ë¡¢´õ˾¤Î¥Á¥å¡¼¥Ë¥ó¥°¥Ñ¥é¥á¡¼¥¿¤ò¼é¤ë¤è¤¦¤Ë + ¥³¡¼¥É¤Ï½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢À¤Âå¤ò¤Þ¤¿¤¬¤Ã¤¿Á´»Ò¥×¥í¥»¥¹¤ÎÄÉÀפ˻Ȥï¤ì¤Æ¤¤¤ë + ¥¹¥³¥¢¥Ü¡¼¥É¤ò°Ý»ý¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    status ¥â¥¸¥å¡¼¥ë¤Ï¡¢´Ë¤ä¤«¤ÊºÆµ¯Æ°°ÊÁ°¤«¤é³«»Ï¤·¤Æ + ¥ê¥¯¥¨¥¹¥È¤Ë±þÅú¤·Â³¤±¤Æ¤¤¤ë»Ò¥×¥í¥»¥¹¤òÆÃÄꤹ¤ë¤¿¤á¤Ë¡¢ + G ¤ò»È¤¦¤³¤È¤â¤·¤Þ¤¹¡£

    + +

    ¸½ºß¡¢USR1 ¤ò»È¤¦¥í¥°°ÜÆ°¥¹¥¯¥ê¥×¥È¤Ç¤Ï¡¢ + ºÆµ¯Æ°Á°¤Î»Ò¥×¥í¥»¥¹¤¬¥í¥°¤ò½ñ¤­½ª¤ï¤Ã¤¿¤³¤È¤ò³Î¾Ú¤¹¤ëÊýË¡¤¬ + ¤¢¤ê¤Þ¤»¤ó¡£¸Å¤¤¥í¥°¤ËÂФ·¤Æ²¿¤«¤¹¤ëÁ°¤Ë¡¢ + USR1 ¥·¥°¥Ê¥ë¤òÁ÷¤Ã¤¿¸å¤¤¤¯¤é¤«Å¬Åö¤Ê»þ´ÖÂԤĤ³¤È¤ò + Äó°Æ¤·¤Þ¤¹¡£Î㤨¤Ð¡¢ÂÓ°è¤Î¶¹¤¤ÄÌ¿®Ï©¤Î¥æ¡¼¥¶¤Î¥ê¥¯¥¨¥¹¥È¤Î¤Û¤È¤ó¤É¤¬ 10 + ʬ°Ê²¼¤Ç´°Î»¤·¤Æ¤¤¤ë¤È¤¤¤¦¤³¤È¤¬Ê¬¤«¤Ã¤Æ¤¤¤ì¤Ð¡¢ + ¸Å¤¤¥í¥°¤Ë²¿¤«¤¹¤ëÁ°¤Ë 15 ʬÂԤĤȤ¤¤¦¤³¤È¤Ç¤¹¡£

    + +
    ºÆµ¯Æ°»þ¤ËÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸í¤ê¤¬¤¢¤ë¤È¡¢ + ¿Æ¥×¥í¥»¥¹¤ÏºÆµ¯Æ°¤»¤º¤Ë¥¨¥é¡¼¤È¤È¤â¤Ë½ªÎ»¤·¤Þ¤¹¡£ + ´Ë¤ä¤«¤ÊºÆµ¯Æ°¤Î¾ì¹ç¤Ï¡¢¿Æ¥×¥í¥»¥¹¤¬½ªÎ»¤·¤¿¸å¤Ç¤â»Ò¥×¥í¥»¥¹¤¬ + ¼Â¹Ô¤µ¤ì¤¿¤Þ¤ÞÊüÃÖ¤µ¤ì¤¿¤ê¤â¤·¤Þ¤¹¡£ + (ºÇ¸å¤Î¥ê¥¯¥¨¥¹¥È¤ò½èÍý¤·¤¿¸å¡Ö´Ë¤ä¤«¤Ë½ªÎ»¡×¤¹¤ë + »Ò¥×¥í¥»¥¹¤È¤Ê¤ê¤Þ¤¹¡£) + ¥µ¡¼¥Ð¤òºÆµ¯Æ°¤¹¤ëºÝ¤Ë¡¢¤³¤ì¤¬ÌäÂê¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó + -- ¥µ¡¼¥Ð¤Ï listen ¤¹¤ë¥Ý¡¼¥È¤Ë¥Ð¥¤¥ó¥É¤Ç¤­¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ºÆµ¯Æ°¤¹¤ëÁ°¤Ë¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤Î¹½Ê¸¤ò -t + ¥³¥Þ¥ó¥É¥é¥¤¥ó°ú¿ô + (httpd ¤ò¤´Í÷²¼¤µ¤¤) + ¤ò»È¤Ã¤Æ¸¡¾Ú¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ÀßÄê¥Õ¥¡¥¤¥ë¤Î°Ọ̃Ū¤ÊÆâÍƤò¹½Ê¸¤ÈƱÍͤ˸¡¾Ú¤·¤¿¤¤¾ì¹ç¤Ï¡¢ + Èó root ¥æ¡¼¥¶¤Ç httpd ¤òµ¯Æ°¤·¤è¤¦¤È¤¹¤ì¤Ð¤ï¤«¤ê¤Þ¤¹¡£ + ¤â¤·¥¨¥é¡¼¤¬¤Ê¤±¤ì¤Ð¡¢¥½¥±¥Ã¥È¤ä¥í¥°¤ò³«¤³¤¦¤È¤·¤Æ + root ¤Ç¤Ê¤¤¤¿¤á + (¤â¤·¤¯¤Ï¼Â¹ÔÃæ¤Î httpd + ¤¬´û¤ËɬÍפʥݡ¼¥È¤Ë¥Ð¥¤¥ó¥É¤·¤Æ¤¤¤ë¤¿¤á) + ¤Ë¼ºÇÔ¤¹¤ë¤Ç¤·¤ç¤¦¡£ + ¤³¤ì°Ê³°¤ÎÍýͳ¤Çµ¯Æ°¤Ë¼ºÇÔ¤·¤¿¤Î¤Ç¤¢¤ì¤Ð¡¢ + ¤½¤ì¤ÏÀßÄê¥Õ¥¡¥¤¥ë¤Î¥¨¥é¡¼¤Ç¡¢ + ´Ë¤ä¤«¤ÊºÆµ¯Æ°¤ò¹Ô¤¦Á°¤Ë¤½¤Î¸í¤ê¤ò½¤Àµ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
    +
    top
    +
    +

    µÞ¤ÊºÆµ¯Æ°

    + +
    ¥·¥°¥Ê¥ë: HUP
    +
    apachectl -k restart
    +
    + +

    HUP ¤¢¤ë¤¤¤Ï restart ¥·¥°¥Ê¥ë¤ò¿Æ¥×¥í¥»¥¹¤ËÁ÷¤ë¤È¡¢ + TERM ¤ÈƱÍÍ¤Ë»Ò¥×¥í¥»¥¹¤ò kill ¤·¤Þ¤¹¤¬¡¢ + ¿Æ¥×¥í¥»¥¹¤Ï½ªÎ»¤·¤Þ¤»¤ó¡£ + ÀßÄê¥Õ¥¡¥¤¥ë¤òºÆÆɹþ¤·¤Æ¡¢¥í¥°¥Õ¥¡¥¤¥ëÁ´¤Æ¤ò³«¤­Ä¾¤·¤Þ¤¹¡£ + ¤½¤Î¸å¡¢¿·¤·¤¤»Ò¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Æ±þÅú¤ò³¤±¤Þ¤¹¡£

    + +

    mod_status + ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢HUP ¤¬Á÷¤é¤ì¤¿¾ì¹ç¤Ë + ¥µ¡¼¥ÐÅý·×¤¬¥¼¥í¤ËÀßÄꤵ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    ºÆµ¯Æ°»þ¤ËÀßÄê¥Õ¥¡¥¤¥ë¤Ë¸í¤ê¤¬¤¢¤ë¤È¡¢ + ¿Æ¥×¥í¥»¥¹¤ÏºÆµ¯Æ°¤»¤º¤Ë¥¨¥é¡¼¤È¤È¤â¤Ë½ªÎ»¤·¤Þ¤¹¡£ + ¤³¤ì¤òÈò¤±¤ë¤Ë¤Ï¼¡¤ÎÊýË¡¤ò¤´Í÷²¼¤µ¤¤¡£
    +
    top
    +
    +

    ÉÕÏ¿: ¥·¥°¥Ê¥ë¤È¶¥¹ç¾õÂÖ

    + +

    Apache 1.2b9 °ÊÁ°¤Ï¡¢ºÆµ¯Æ°¤äÄä»ß¤Î¥·¥°¥Ê¥ë¤ò´Þ¤à¶¥¹ç¾õÂÖ + (¶¥¹ç¾õÂÖ¤ò´Êñ¤ËÀâÌÀ¤¹¤ë¤È: ¥¿¥¤¥ß¥ó¤Ë¥°¤è¤ëÌäÂê¤Ç¡¢ + ¶ñ¹ç¤Î°­¤¤»þ´ÖÂӤˤÁ¤ç¤¦¤É²¿¤«¤¬µ¯¤³¤ë¤ÈͽÁÛ³°¤ÎÆ°ºî¤ò¤¹¤ë + ¤è¤¦¤Ê¤³¤È¤ò»Ø¤·¤Þ¤¹) ¤¬¤¢¤ê¤Þ¤·¤¿¡£ + ¡ÖÀµ¤·¤¤¡×µ¡Ç½¤ò»ý¤Ã¤Æ¤¤¤ë¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¡¢¤Ç¤­¤ë¤À¤± + ¤³¤Î¤è¤¦¤Ê¤³¤È¤¬µ¯¤³¤é¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¤¤Þ¤¹¡£ + ¤·¤«¤·¡¢¤¢¤ë¼ï¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¶¥¹ç¾õÂÖ¤Ï̤¤À³Î¼Â¤Ëµ¯¤³¤ê¤¨¤ë + ¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +

    ¥Ç¥£¥¹¥¯¾å¤Ç + ScoreBoardFile + ¤ò»ÈÍѤ·¤Æ¤¤¤ë¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¡¢ + ÀøºßŪ¤Ë¥¹¥³¥¢¥Ü¡¼¥É¤¬²õ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ + ¥¹¥³¥¢¥Ü¡¼¥É¤¬²õ¤ì¤¿¾ì¹ç¤Ï¡¢ + "bind: Address already in use" (HUP ¸å) ¤ä + "long lost child came home!" (USR1 ¸å) + ¤È¤¤¤Ã¤¿·ë²Ì¤Ë¤Ê¤ê¤Þ¤¹¡£ + Á°¼Ô¤ÏÃ×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹¤¬¡¢ + ¸å¼Ô¤Ï¥¹¥³¥¢¥Ü¡¼¥É¥¹¥í¥Ã¥È¤ò¼º¤¦¤À¤±¤Ç¤¹¡£ + ¤Ç¤¹¤«¤é´Ë¤ä¤«¤ÊºÆµ¯Æ°¤Ï¡¢¤¿¤Þ¤Ë³Î¼Â¤ÊºÆµ¯Æ° (HUP) + ¤âÊ»ÍѤ·¤Æ»È¤Ã¤¿Êý¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ + ¤³¤ì¤é¤ÎÌäÂê¤ò¹îÉþ¤¹¤ë¤Î¤ÏÈó¾ï¤ËÆñ¤·¤¤¤Î¤Ç¤¹¤¬¡¢ + ¹¬¤¤¤Ê¤³¤È¤ËÂçÉôʬ¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¥¹¥³¥¢¥Ü¡¼¥É¤Î¥Õ¥¡¥¤¥ë¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£ + ¤³¤ì¤ò»ÈÍѤ¹¤ë¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ï¡¢ + ScoreBoardFile + ¤ò¤´Í÷²¼¤µ¤¤¡£

    + +

    Á´¤Æ¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ë¤ª¤¤¤Æ¡¢¸Ä¡¹¤Î»Ò¥×¥í¥»¥¹¤Ç + ·Ñ³Ū¤Ê HTTP ¥³¥Í¥¯¥·¥ç¥ó (KeepAlive) + ¤Ë´Ø¤¹¤ë¾®¤µ¤Ê¶¥¹ç¾õÂÖ¤¬µ¯¤³¤ê¤¨¤Þ¤¹¡£ + ¥ê¥¯¥¨¥¹¥È¹Ô¤òÆɤó¤À¸å¡¢¤½¤·¤Æ¥ê¥¯¥¨¥¹¥È¥Ø¥Ã¥À¤òÆɤàÁ°¤Ë + »Ò¥×¥í¥»¥¹¤Ï½ªÎ»¤¹¤ë¤«¤âÃΤì¤Þ¤»¤ó¡£ + ¤³¤ì¤ËÂФ¹¤ë½¤Àµ¤¬¤¢¤ê¤Þ¤¹¤¬ 1.2 ¤Ç½¤Àµ¤¹¤ë¤Ë¤Ïȯ¸«¤¬ÃÙ¤¹¤®¤Þ¤·¤¿¡£ + ÍýÏÀŪ¤Ë¤Ï¡¢¤³¤ì¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£ + ¤Ê¤¼¤Ê¤é KeepAlive ¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢¥Í¥Ã¥È¥ï¡¼¥¯ÃÙ±ä¤ä + ¥µ¡¼¥Ð¤Î¥¿¥¤¥à¥¢¥¦¥È¤Ê¤É¤ËÈ÷¤¨¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤é¤Ç¤¹¡£ + ¼ÂºÝ¤Ë¤â²¿¤«±Æ¶Á¤¬¤¢¤ë¤è¤¦¤Ë¤Ï¸«¤¨¤Þ¤»¤ó + -- ¥Æ¥¹¥È¥±¡¼¥¹¤Ç¥µ¡¼¥Ð¤ò 1 ÉÃ´Ö¤Ë 20 ²óºÆµ¯Æ°¤·¤Æ¤â + ¥¯¥é¥¤¥¢¥ó¥È¤Ï²õ¤ì¤¿²èÁü¤ä¶õ¤Î¥É¥­¥å¥á¥ó¥È¤ò¼õ¤±¼è¤ë¤³¤È¤Ê¤¯ + Àµ¾ï¤Ë±ÜÍ÷¤Ç¤­¤Æ¤¤¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/stopping.html.ko.euc-kr b/trunk/docs/manual/stopping.html.ko.euc-kr new file mode 100644 index 0000000000..bdbd2b100c --- /dev/null +++ b/trunk/docs/manual/stopping.html.ko.euc-kr @@ -0,0 +1,205 @@ + + + +Áß´Ü°ú Àç½ÃÀÛ - Apache HTTP Server + + + + + +
    <-
    +

    Áß´Ü°ú Àç½ÃÀÛ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ÀÌ ¹®¼­´Â À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÏ°í Àç½ÃÀÛÇÏ´Â + ³»¿ëÀ» ´ã°íÀÖ´Ù. À©µµ¿ìÁî NT, 2000, XP »ç¿ëÀÚ´Â ¼­ºñ½º·Î ¾ÆÆÄÄ¡ + ½ÇÇàÇϱ⿡¼­, À©µµ¿ìÁî 9x¿Í ME »ç¿ëÀÚ´Â ÄÝ¼Ö ÇÁ·Î±×·¥À¸·Î + ¾ÆÆÄÄ¡ ½ÇÇàÇϱ⿡¼­ Ç÷¡Æûº° ¾ÆÆÄÄ¡ Á¶ÀÛ¹ýÀ» ¾Ë ¼ö ÀÖ´Ù.

    +
    + +
    top
    +
    +

    ¼Ò°³

    + +

    ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÏ°í Àç½ÃÀÛÇÏ·Á¸é ½ÇÇàÇÏ°í ÀÖ´Â + httpd ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀ» º¸³»¾ß ÇÑ´Ù. ½Ã±×³ÎÀ» + º¸³»´Â ¹æ¹ýÀº µÎ°¡Áö´Ù. Çϳª´Â À¯´Ð½º kill + ¸í·É¾î¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º¿¡ Á÷Á¢ ½Ã±×³ÎÀ» º¸³»´Â ¹æ¹ýÀÌ´Ù. + ½Ã½ºÅÛ¿¡ ¸¹Àº httpd°¡ ½ÇÇàµÇÁö¸¸, PidFile¿¡ pid°¡ ±â·ÏµÈ ºÎ¸ð¿Ü¿¡ + ´Ù¸¥ ÇÁ·Î¼¼½º¿¡ ½Ã±×³Î(signal)À» º¸³»¸é ¾ÈµÈ´Ù. Áï, ºÎ¸ðÀÌ¿Ü¿¡ + ´Ù¸¥ ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀ» º¸³¾ ÇÊ¿ä°¡ ¾ø´Ù´Â ¸»ÀÌ´Ù. ºÎ¸ð¿¡°Ô + º¸³¾ ¼ö ÀÖ´Â ½Ã±×³ÎÀº ¼¼°¡Áö·Î, ÀÌÁ¦ ¼³¸íÇÒ TERM, HUP, USR1ÀÌ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ºÎ¸ð¿¡°Ô ½Ã±×³ÎÀ» º¸³½´Ù:

    + +

    kill -TERM `cat /usr/local/apache2/logs/httpd.pid`

    + +

    httpd ÇÁ·Î¼¼½º¿¡°Ô ½Ã±×³ÎÀ» º¸³»´Â ´Ù¸¥ ¹æ¹ýÀº + ¸í·ÉÇà ¿É¼Ç -k¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ¾Æ·¡¼­ ¼³¸íÇÒ + stop, restart, gracefulÀº + httpd ½ÇÇàÆÄÀÏÀÇ ¾Æ±Ô¸ÕÆ®µéÀÌ´Ù. + ±×·¯³ª ÀÌ ¾Æ±Ô¸ÕÆ®µé·Î httpd¸¦ ½ÇÇàÇÏ´Â, apachectl ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏ±æ ±ÇÇÑ´Ù.

    + +

    httpd¿¡ ½Ã±×³ÎÀ» º¸³½ÈÄ, ´ÙÀ½ ¸í·É¾î·Î + ÁøÇà»óȲÀ» ¾Ë ¼ö ÀÖ´Ù:

    + +

    tail -f /usr/local/apache2/logs/error_log

    + +

    À§ ¿¹¸¦ ´ç½ÅÀÇ ServerRoot¿Í PidFile ¼³Á¤¿¡ ¾Ë¸Â°Ô ¼öÁ¤Ç϶ó.

    +
    top
    +
    +

    ´çÀå Áß´Ü

    + +
    ½Ã±×³Î: TERM
    +
    apachectl -k stop
    +
    + +

    TERMÀ̳ª stop ½Ã±×³ÎÀ» ºÎ¸ð¿¡°Ô + º¸³»¸é Áï½Ã ¸ðµç ÀÚ½ÄÀ» Á×ÀδÙ. ÀÚ½ÄÀ» ¿ÏÀüÈ÷ Á×À̴µ¥´Â + ¸î ÃÊ°¡ °É¸± ¼ö ÀÖ´Ù. ±×·±ÈÄ ºÎ¸ð°¡ Á¾·áÇÑ´Ù. ó¸®ÁßÀÎ ¿äûÀº + Áߴܵǰí, ´õ ÀÌ»ó ¿äûÀ» ¹ÞÁö¾Ê´Â´Ù.

    +
    top
    +
    +

    Á¡ÀÝÀº Àç½ÃÀÛ

    + +
    ½Ã±×³Î: USR1
    +
    apachectl -k graceful
    +
    + +

    USR1À̳ª graceful ½Ã±×³ÎÀ» + ºÎ¸ð¿¡°Ô º¸³»¸é ºÎ¸ð ÇÁ·Î¼¼½º´Â Àڽĵ鿡°Ô ÇöÀç ¿äûÀ» + ó¸®ÇÑÈÄ Á¾·áÇ϶ó°í (ȤÀº ÇöÀç ¾Æ¹«°Íµµ ó¸®ÇÏÁö ¾Ê´Ù¸é + Áï½Ã Á¾·áÇ϶ó°í) Á¶¾ðÇÑ´Ù. ºÎ¸ð´Â ¼³Á¤ÆÄÀÏÀ» + ´Ù½ÃÀÐ°í ·Î±×ÆÄÀϵµ ´Ù½Ã ¿¬´Ù. ÀÚ½ÄÀÌ Á×À»¶§¸¶´Ù ºÎ¸ð´Â + Á×Àº ÀڽĴë½Å »õ·Î¿î ¼³Á¤ ¼¼´ë¿¡ ±âÃÊÇÑ ÀÚ½ÄÀ» + ½ÇÇàÇÏ¿© Áï½Ã ¿äûÀ» ó¸®ÇÏ°Ô ÇÑ´Ù.

    + +
    Á¡ÀÝÀº Àç½ÃÀÛ(graceful restart)À¸·Î USR1À» + »ç¿ëÇÒ ¼ö ¾ø´Â Ç÷¡Æû¿¡¼­´Â ´ë½Å (WINCH¿Í °°Àº) + ´Ù¸¥ ½Ã±×³ÎÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. apachectl gracefulÀº + Ç÷¡Æû¿¡ ¾Ë¸ÂÀº ½Ã±×³ÎÀ» º¸³½´Ù.
    + +

    Á¡ÀÝÀº Àç½ÃÀÛÀº Ç×»ó MPMÀÇ ÇÁ·Î¼¼½º Á¶Àý Áö½Ã¾î ¼³Á¤À» + °í·ÁÇÏ¿©, Àç½ÃÀÛµ¿¾È Ŭ¶óÀ̾ðÆ®¸¦ ¼­ºñ½ºÇÏ´Â ÇÁ·Î¼¼½º³ª ¾²·¹µå°¡ + Àû´çÇÑ ¼ö¸¦ À¯ÁöÇϵµ·Ï ¼³°èµÇ¾ú´Ù. °Ô´Ù°¡ StartServers´Â, ÀÏÃÊ ÈÄ + ÃÖ¼ÒÇÑ StartServers¸¸Å­ »õ·Î¿î ÀÚ½ÄÀÌ ¾È¸¸µé¾îÁö¸é ÀÚ½ÄÀÌ + StartServers °³°¡ µÇµµ·Ï »õ·Î ¸¸µç´Ù. Áï, ÇÁ·Î±×·¥Àº ¼­¹öÀÇ + ÇöÀç ºÎÇÏ¿¡ ¾Ë¸ÂÀº ÀÚ½ÄÀÇ °³¼ö¸¦ À¯ÁöÇϸç, + StartServers ÆĶó¹ÌÅÍ·Î ÁöÁ¤ÇÑ ´ç½ÅÀÇ + ±â´ë¸¦ Á¸ÁßÇÑ´Ù.

    + +

    mod_status »ç¿ëÀÚ´Â USR1À» + ¹ÞÀ»¶§ ¼­¹ö Åë°è°¡ 0ÀÌ µÇÁö ¾ÊÀ½À» ºÃÀ» + °ÍÀÌ´Ù. ¼­¹ö´Â »õ·Î¿î ¿äûÀ» (¿î¿µÃ¼Á¦´Â À̵éÀ» Å¥¿¡ ´ã¾Æ¼­ + ¾î¶² °æ¿ì¿¡µµ ÀÒ¾î¹ö¸®Áö ¾Ê´Â´Ù) ó¸®ÇÏÁö ¸øÇÏ´Â ½Ã°£À» + ÃÖ¼ÒÈ­ÇÏ°í ´ç½ÅÀÇ Æ©´× ÆĶó¹ÌÅ͸¦ Á¸ÁßÇϵµ·Ï ¸¸µé¾îÁ³´Ù. + À̸¦ À§ÇØ ¼¼´ë°£ ¸ðµç ÀÚ½ÄÀ» ±â·ÏÇÏ´Â scoreboard¸¦ + À¯ÁöÇÑ´Ù.

    + +

    status ¸ðµâÀº ¶ÇÇÑ Á¡ÀÝÀº Àç½ÃÀÛ Àü¿¡ ½ÃÀÛÇÏ¿© ¾ÆÁ÷µµ + ¿äûÀ» ó¸®ÇÏ°í ÀÖ´Â ÀÚ½ÄÀ» G·Î ¾Ë·ÁÁØ´Ù.

    + +

    ÇöÀç·Î´Â USR1À» »ç¿ëÇÏ´Â ·Î±×¼øȯ ½ºÅ©¸³Æ®°¡ + Àç½ÃÀÛÀü¿¡ ¸ðµç ÀÚ½ÄÀÌ ·Î±×ÀÛ¼ºÀ» ¸¶ÃÆ´ÂÁö ¾Ë ¼ö ÀÖ´Â + ¹æ¹ýÀÌ ¾ø´Ù. ¿ì¸®´Â USR1 ½Ã±×³ÎÀ» º¸³»°í + Àû´çÇÑ ½Ã°£ÀÌ Áö³­ÈÄ ÀÌÀü ·Î±×¸¦ ´Ù·çµµ·Ï Á¦¾ÈÇÑ´Ù. ¿¹¸¦ + µé¾î ³·Àº ´ë¿ªÆø »ç¿ëÀÚÀÇ °æ¿ì Á¢¼Ó ´ëºÎºÐÀÌ ¸¶Ä¡´Âµ¥ 10ºÐÀÌ + ¾È°É¸°´Ù¸é, ÀÌÀü ·Î±×¸¦ ´Ù·ç±âÀü¿¡ 15ºÐ ±â´Ù¸°´Ù.

    + +
    ¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖ´Ù¸é Àç½ÃÀ۽à ºÎ¸ð´Â Àç½ÃÀÛÇÏÁö + ¾Ê°í ¿À·ù¸¦ ³»¸ç Á¾·áÇÑ´Ù. ¶Ç, Á¡ÀÝÀº Àç½ÃÀÛÀÇ °æ¿ì Á¾·áÇÒ¶§ + ÀÚ½ÄÀÌ ½ÇÇàµÇµµ·Ï ³öµÐ´Ù. (ÀڽĵéÀº ÀÚ½ÅÀÇ ¸¶Áö¸· ¿äûÀ» + ó¸®ÇÏ°í "Á¡ÀÝ°Ô Á¾·áÇÑ´Ù".) ÀÌ´Â ¼­¹ö¸¦ Àç½ÃÀÛÇÒ¶§ + ¹®Á¦°¡ µÈ´Ù. ¼­¹ö´Â ÀÚ½ÅÀÌ ±â´Ù¸± Æ÷Æ®¿¡ ¿¬°áÇÏÁö ¸øÇÑ´Ù. + Àç½ÃÀÛÀü¿¡ -t ¸í·ÉÇà ¿É¼Ç(httpd Âü°í)À¸·Î ¼³Á¤ÆÄÀÏ + ¹®¹ýÀ» °Ë»çÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª ÀÌ·± °Ë»çµµ ¼­¹ö°¡ ¿Ã¹Ù·Î + Àç½ÃÀÛÇÒÁö¸¦ º¸ÀåÇÏÁö ¸øÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ ¹®¹ýÀÌ ¾Æ´Ñ Àǹ̸¦ + °Ë»çÇÏ·Á¸é root°¡ ¾Æ´Ñ »ç¿ëÀÚ·Î httpd¸¦ ½ÃÀÛÇغ¼ ¼ö ÀÖ´Ù. + root°¡ ¾Æ´Ï±â¶§¹®¿¡ (¾Æ´Ï¸é ÇöÀç ±× Æ÷Æ®¸¦ »ç¿ëÇÏ´Â + httpd°¡ ½ÇÇàµÇ±â¶§¹®¿¡) ¿À·ù°¡ ¾ø´Ù¸é ¼ÒÄÏ°ú + ·Î±×ÆÄÀÏÀ» ¿­·Á°í ½ÃµµÇÏ´Â °úÁ¤¿¡¼­ ½ÇÆÐÇÒ °ÍÀÌ´Ù. ´Ù¸¥ + ÀÌÀ¯¶§¹®¿¡ ½ÇÆÐÇÑ´Ù¸é ¾Æ¸¶µµ ¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖÀ» °ÍÀÌ´Ù. + Á¡ÀÝÀº Àç½ÃÀÛÀ» ÇϱâÀü¿¡ ¿À·ù¸¦ °íÃľßÇÑ´Ù.
    +
    top
    +
    +

    ´çÀå Àç½ÃÀÛ

    + +
    ½Ã±×³Î: HUP
    +
    apachectl -k restart
    +
    + +

    HUPÀ̳ª restart ½Ã±×³ÎÀ» + ºÎ¸ð¿¡°Ô º¸³»¸é TERM°ú °°ÀÌ ¸ðµç ÀÚ½ÄÀ» + Á×ÀÌÁö¸¸ ºÎ¸ð´Â Á¾·áÇÏÁö ¾Ê´Â´Ù. ºÎ¸ð´Â ¼³Á¤ÆÄÀÏÀ» ´Ù½ÃÀаí + ·Î±×ÆÄÀÏÀ» ´Ù½Ã ¿¬´Ù. ±×¸®°í »õ·Î¿î ÀڽĵéÀ» ¸¸µé°í ¼­ºñ½º¸¦ + °è¼ÓÇÑ´Ù.

    + +

    mod_status »ç¿ëÀÚ´Â HUP¸¦ + º¸³»¸é ¼­¹ö Åë°è°¡ 0ÀÌ µÊÀ» ¾Ë ¼ö ÀÖ´Ù.

    + +
    ¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖ´Ù¸é Àç½ÃÀÛÀ» Çصµ ºÎ¸ð´Â Àç½ÃÀÛÇÏÁö +¾Ê°í ¿À·ù¸¦ ³»¸ç Á¾·áÇÒ °ÍÀÌ´Ù. À̸¦ ÇÇÇÏ´Â ¹æ¹ýÀº À§¸¦ Âü°íÇ϶ó.
    +
    top
    +
    +

    ºÎ·Ï: ½Ã±×³Î°ú ·¹À̽º ÄÁµð¼Ç

    + +

    Apache 1.2b9 ÀÌÀü¿¡´Â Àç½ÃÀÛ°ú Á¾·á ½Ã±×³Î¿¡ °ü°èµÈ + ·¹À̽º ÄÁµð¼Ç(race condition)ÀÌ ÀÖ¾ú´Ù. (·¹À̽º + ÄÁµð¼ÇÀº °£´ÜÇÑ ¼³¸íÇÏÀÚ¸é, ¾î¶² ÀÏÀÌ À߸øµÈ¶§ ÀϾ¼­ + ±â´ëÇÑ´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â ½Ã°£¿¡ ¹Î°¨ÇÑ ¹®Á¦´Ù.) "¿Ã¹Ù¸¥" + ±â´ÉÀÌ ÀÖ´Â ¾ÆÅ°ÅØÃÄ¿¡¼­ ¿ì¸®´Â ÀÌ·± ¹®Á¦¸¦ ÃÖ´ëÇÑ ÇØ°áÇß´Ù. + ±×·¯³ª ¾î¶² ¾ÆÅ°ÅØÃÄ¿¡´Â ¾ÆÁ÷µµ ·¹À̽º ÄÁµð¼ÇÀÌ Á¸ÀçÇÔÀ» + ÁÖÀÇÇ϶ó.

    + +

    ScoreBoardFileÀ» + µð½ºÅ©¿¡ ÀúÀåÇÏ´Â ¾ÆÅ°ÅØÃÄ´Â scoreboard¸¦ ¸Á°¡Æ®¸± °¡´É¼ºÀÌ + ÀÖ´Ù. ±×·¯¸é (HUPÈÄ) "bind: Address already in use" + ȤÀº (USR1 ÈÄ) "long lost child came home!"ÀÌ + ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ÀüÀÚ´Â ½É°¢ÇÑ ¿À·ùÀÌ°í, ÈÄÀÚ´Â ´ÜÁö ¼­¹ö°¡ + scoreboard slotÀ» ÀÒ°Ô ¸¸µç´Ù. ±×·¡¼­ °­Á¦ Àç½ÃÀÛÀ» ÁÙÀÌ°í + Á¡ÀÝÀº Àç½ÃÀÛÀ» »ç¿ëÇϱæ ÃßõÇÑ´Ù. ÀÌ ¹®Á¦´Â ÇØ°áÇϱ⠸ſì + Èûµé´Ù. ±×·¯³ª ´ÙÇàÈ÷µµ ´ëºÎºÐÀÇ ¾ÆÅ°ÅØÃÄ´Â scoreboard·Î ÆÄÀÏÀ» + »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÆÄÀÏÀ» »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃĶó¸é ScoreBoardFile ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¸ðµç ¾ÆÅ°ÅØÃÄ¿¡´Â Áö¼ÓµÇ´Â HTTP ¿¬°á (KeepAlive)¿¡¼­ + µÎ¹ø° ÀÌÈÄ ¿äûÀ» ó¸®ÇÏ´Â ÀڽĿ¡ ¾à°£ÀÇ ·¹À̽º ÄÁµð¼ÇÀÌ + ÀÖ´Ù. ÀÚ½ÄÀº ¿äûÁÙÀ» ÀÐÀº ÈÄ ¿äû Çì´õ¸¦ ÀбâÀü¿¡ Á¾·áÇÒ ¼ö + ÀÖ´Ù. ÀÌ ¹®Á¦´Â ³Ê¹« ´Ê°Ô ¹ß°ßÇÏ¿© 1.2 ¹öÀüÀÌ ³ª¿ÂÈÄ¿¡¾ß + ¼öÁ¤µÇ¾ú´Ù. ±×·¯³ª ³×Æ®¿÷ Áö¿¬À̳ª ¼­¹ö ½Ã°£Á¦ÇѶ§¹®¿¡ KeepAlive + Ŭ¶óÀ̾ðÆ®´Â ÀÌ·± °æ¿ì¸¦ ¿¹»óÇؾßÇϱ⠶§¹®¿¡ ÀÌ·Ð»ó ¹®Á¦´Â + ¾ÈµÈ´Ù. ½ÇÁ¦·Î ¼­¹ö¸¦ °Ë»çÇϱâÀ§ÇØ ÀÏÃÊ¿¡ 20¹ø Àç½ÃÀÛÇÏ´Â µ¿¾È + Ŭ¶óÀ̾ðÆ®°¡ ±úÁø ±×¸²À̳ª ºó ¹®¼­¾øÀÌ »çÀÌÆ®¸¦ ¼º°øÀûÀ¸·Î + ÀоîµéÀÌ±æ ±â´ëÇÏÁö ¾Ê´Â´Ù¸é ¹®Á¦°¡ ¾ÈµÈ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + es  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/stopping.xml b/trunk/docs/manual/stopping.xml new file mode 100644 index 0000000000..c630b8083a --- /dev/null +++ b/trunk/docs/manual/stopping.xml @@ -0,0 +1,225 @@ + + + + + + + + + + Stopping and Restarting + + +

    This document covers stopping and restarting Apache on + Unix-like systems. Windows NT, 2000 and XP users should see + Running Apache as a + Service and Windows 9x and ME users should see Running Apache as a + Console Application for information on how to control + Apache on those platforms.

    +
    + +httpd +apachectl + +
    Introduction + +

    In order to stop or restart Apache, you must send a signal to + the running httpd processes. There are two ways to + send the signals. First, you can use the unix kill + command to directly send signals to the processes. You will + notice many httpd executables running on your system, + but you should not send signals to any of them except the parent, + whose pid is in the PidFile. That is to say you + shouldn't ever need to send signals to any process except the + parent. There are three signals that you can send the parent: + TERM, + HUP, and + USR1, which + will be described in a moment.

    + +

    To send a signal to the parent you should issue a command + such as:

    + +kill -TERM `cat /usr/local/apache2/logs/httpd.pid` + +

    The second method of signaling the httpd processes + is to use the -k command line options: stop, + restart, and graceful, + as described below. These are arguments to the + httpd binary, but we recommend that + you send them using the apachectl control script, which + will pass them through to httpd.

    + +

    After you have signaled httpd, you can read about + its progress by issuing:

    + +tail -f /usr/local/apache2/logs/error_log + +

    Modify those examples to match your ServerRoot and PidFile settings.

    +
    + +
    Stop Now + +
    Signal: TERM
    +
    apachectl -k stop
    +
    + +

    Sending the TERM or stop signal to + the parent causes it to immediately attempt to kill off all of its + children. It may take it several seconds to complete killing off + its children. Then the parent itself exits. Any requests in + progress are terminated, and no further requests are served.

    +
    + +
    Graceful Restart + +
    Signal: USR1
    +
    apachectl -k graceful
    +
    + +

    The USR1 or graceful signal causes + the parent process to advise the children to exit after + their current request (or to exit immediately if they're not + serving anything). The parent re-reads its configuration files and + re-opens its log files. As each child dies off the parent replaces + it with a child from the new generation of the + configuration, which begins serving new requests immediately.

    + + On certain platforms that do not allow USR1 to + be used for a graceful restart, an alternative signal may be used (such + as WINCH). The command apachectl graceful + will send the right signal for your platform. + +

    This code is designed to always respect the process control + directive of the MPMs, so the number of processes and threads + available to serve clients will be maintained at the appropriate + values throughout the restart process. Furthermore, it respects + StartServers in the + following manner: if after one second at least StartServers new children have not + been created, then create enough to pick up the slack. Hence the + code tries to maintain both the number of children appropriate for + the current load on the server, and respect your wishes with the + StartServers parameter.

    + +

    Users of the mod_status + will notice that the server statistics are not + set to zero when a USR1 is sent. The code was + written to both minimize the time in which the server is unable + to serve new requests (they will be queued up by the operating + system, so they're not lost in any event) and to respect your + tuning parameters. In order to do this it has to keep the + scoreboard used to keep track of all children across + generations.

    + +

    The status module will also use a G to indicate + those children which are still serving requests started before + the graceful restart was given.

    + +

    At present there is no way for a log rotation script using + USR1 to know for certain that all children writing + the pre-restart log have finished. We suggest that you use a + suitable delay after sending the USR1 signal + before you do anything with the old log. For example if most of + your hits take less than 10 minutes to complete for users on + low bandwidth links then you could wait 15 minutes before doing + anything with the old log.

    + + If your configuration file has errors + in it when you issue a restart then your parent will not + restart, it will exit with an error. In the case of graceful + restarts it will also leave children running when it exits. + (These are the children which are "gracefully exiting" by + handling their last request.) This will cause problems if you + attempt to restart the server -- it will not be able to bind to + its listening ports. Before doing a restart, you can check the + syntax of the configuration files with the -t + command line argument (see httpd). This still will not + guarantee that the server will restart correctly. To check the + semantics of the configuration files as well as the syntax, you + can try starting httpd as a non-root user. If there + are no errors it will attempt to open its sockets and logs and fail + because it's not root (or because the currently running + httpd already has those ports bound). If it fails + for any other reason then it's probably a config file error and the error + should be fixed before issuing the graceful restart. +
    + +
    Restart Now + +
    Signal: HUP
    +
    apachectl -k restart
    +
    + +

    Sending the HUP or restart signal to + the parent causes it to kill off its children like in + TERM, but the parent doesn't exit. It re-reads its + configuration files, and re-opens any log files. Then it spawns a + new set of children and continues serving hits.

    + +

    Users of mod_status + will notice that the server statistics are set to zero when a + HUP is sent.

    + +If your configuration file has errors in it when you issue a +restart then your parent will not restart, it will exit with an +error. See above for a method of avoiding this. +
    + +
    Appendix: signals and race conditions + +

    Prior to Apache 1.2b9 there were several race + conditions involving the restart and die signals (a simple + description of race condition is: a time-sensitive problem, as + in if something happens at just the wrong time it won't behave + as expected). For those architectures that have the "right" + feature set we have eliminated as many as we can. But it should + be noted that there still do exist race conditions on certain + architectures.

    + +

    Architectures that use an on disk ScoreBoardFile have the potential + to corrupt their scoreboards. This can result in the "bind: + Address already in use" (after HUP) or "long lost + child came home!" (after USR1). The former is a fatal + error, while the latter just causes the server to lose a + scoreboard slot. So it might be advisable to use graceful + restarts, with an occasional hard restart. These problems are very + difficult to work around, but fortunately most architectures do + not require a scoreboard file. See the ScoreBoardFile documentation for a + architecture uses it.

    + +

    All architectures have a small race condition in each child + involving the second and subsequent requests on a persistent + HTTP connection (KeepAlive). It may exit after reading the + request line but before reading any of the request headers. + There is a fix that was discovered too late to make 1.2. In + theory this isn't an issue because the KeepAlive client has to + expect these events because of network latencies and server + timeouts. In practice it doesn't seem to affect anything either + -- in a test case the server was restarted twenty times per + second and clients successfully browsed the site without + getting broken images or empty documents.

    +
    + +
    diff --git a/trunk/docs/manual/stopping.xml.de b/trunk/docs/manual/stopping.xml.de new file mode 100644 index 0000000000..39540c46e6 --- /dev/null +++ b/trunk/docs/manual/stopping.xml.de @@ -0,0 +1,247 @@ + + + + + + + + + + Beenden und Neustarten + + +

    Dieses Dokument umfasst das Beenden und Neustarten des + Apache auf Unix-ähnlichen Systemen. Anwender von Windows NT, 2000 + und XP sollten Betreiben + des Apache als Dienst lesen, während hingegen Anwender von + Windows 9x sowie ME Betreiben + des Apache als Konsolenanwendung lesen sollten, um mehr Informationen + zur Handhabung des Apache auf diesen Systemen zu erhalten.

    +
    + +httpd +apachectl + +
    Einleitung + +

    Um den Apache zu stoppen oder neu zu starten, müssen Sie + ein Signal an den laufenden httpd-Prozess senden. Es gibt + zwei Möglichkeiten, diese Signale zu senden. Zum einen können + Sie den Unix-Befehl kill verwenden, um den Prozessen + direkt Signale zu senden. Sie werden feststellen, dass auf Ihrem + System mehrere httpd-Programme laufen. Sie sollten + jedoch nicht jedem dieser Prozesse ein Signal senden, sondern nur dem + Elternprozess, dessen PID im PidFile steht. Das heißt, Sie + sollten es niemals nötig haben, einem anderen Prozess, als dem + Elternprozess, ein Signal zu senden. Es gibt drei Signale, die Sie an den + Elternprozess senden können: TERM, + HUP und + USR1, die nachfolgend beschrieben + werden.

    + +

    Um dem Elternprozess ein Signal zu senden, verwenden Sie einen + Befehl wie z.B.:

    + + kill -TERM `cat /usr/local/apache2/logs/httpd.pid` + +

    Die zweite Methode, dem httpd-Prozess zu + signalisieren, ist die Verwendung der -k-Befehlszeilenoptionen + stop, restart und graceful, wie + unten beschrieben. Dies sind Argumente des + httpd-Programms, es wird jedoch + empfohlen, sie unter Verwendung des Steuerskripts + apachectl zu senden, welches diese + an httpd durchreicht.

    + +

    Nachdem Sie httpd signalisiert haben, können Sie + dessen Fortschritt beobachten, indem Sie eingeben:

    + + tail -f /usr/local/apache2/logs/error_log + +

    Passen Sie diese Beispiele entsprechend Ihren ServerRoot- und PidFile-Einstellungen an.

    +
    + +
    Beenden + +
    Signal: TERM
    +
    apachectl -k stop
    +
    + +

    Das Senden des TERM- oder stop-Signals an + den Elternprozess veranlasst diesen, sofort zu versuchen, alle seine + Kindprozesse zu beenden. Es kann einige Sekunden dauern, bis alle + Kindprozesse komplett beendet sind. Danach beendet sich der Elternprozess + selbst. Alle gerade bearbeiteten Anfragen werden abgebrochen. + Es werden keine weiteren Anfragen mehr bedient.

    +
    + +
    Unterbrechungsfreier Neustart + +
    Signal: USR1
    +
    apachectl -k graceful
    +
    + +

    Das USR1- oder graceful-Signal + veranlasst den Elternprozess, die Kinder anzuweisen, sich + nach Abschluß ihrer momentanen bearbeiteten Anfrage zu beenden + (oder sich sofort zu beenden, wenn sie gerade keine Anfrage bedienen). + Der Elternprozess liest seine Konfigurationsdateien erneut ein und + öffnet seine Logdateien neu. Wenn ein Kindprozess stirbt, + ersetzt der Elternprozess ihn durch ein Kind der neuen + Konfigurations-Generation. Dieses beginnt sofort damit, + neue Anfragen zu bedienen.

    + + Auf bestimmten Plattformen, welche kein USR1 + für einen unterbrechungsfreien Neustart erlauben, kann ein + alternatives Signal verwendet werden (wie z.B. + WINCH). Der Befehl apachectl graceful + sendet das jeweils richtige Signal für Ihre Platform. + +

    Der Code ist dafür ausgelegt, stets die MPM-Direktiven + zur Prozesssteuerung zu beachten, so dass die Anzahl der Prozesse + und Threads, die zur Bedienung der Clients bereitstehen, während + des Neustarts auf die entsprechenden Werte gesetzt werden. + Weiterhin wird StartServers + auf folgende Art und Weise interpretiert: Wenn nach einer Sekunde + nicht mindestens StartServers + neue Kindprozesse erstellt wurden, dann werden, um den Durchsatz zu + beschleunigen, entsprechend weitere erstellt. Auf diese Weise versucht + der Code sowohl die Anzahl der Kinder entsprechend der Serverlast + anzupassen als auch Ihre Wünsche hinsichtlich des Parameters + StartServers zu berücksichtigen.

    + +

    Benutzer von mod_status werden feststellen, + dass die Serverstatistiken nicht auf Null + zurückgesetzt werden, wenn ein USR1 gesendet + wurde. Der Code wurde so geschrieben, dass sowohl die Zeit minimiert + wird, in der der Server nicht in der Lage ist, neue Anfragen zu + bedienen (diese werden vom Betriebssystem in eine Warteschlange + gestellt, so dass sie auf keinen Fall verloren gehen) als auch + Ihre Parameter zur Feinabstimmung berücksichtigt werden. + Um dies zu erreichen, muss die Statustabelle (Scoreboard), + die dazu verwendet wird, alle Kinder über mehrere Generationen + zu verfolgen, erhalten bleiben.

    + +

    Das Statusmodul benutzt außerdem ein G, um + diejenigen Kinder zu kennzeichen, die noch immer Anfragen bedienen, + welche gestartet wurden, bevor ein unterbrechungsfreier Neustart + veranlaßt wurde.

    + +

    Derzeit gibt es keine Möglichkeit für ein + Log-Rotationsskript, das USR1 verwendet, sicher + festzustellen, dass alle Kinder, die in ein vor dem Neustart + geöffnetes Log schreiben, beendet sind. Wir schlagen vor, dass + Sie nach dem Senden des Signals USR1 eine angemessene + Zeitspanne warten, bevor Sie das alte Log anfassen. Wenn beispielsweise + die meisten Ihrer Zugriffe bei Benutzern mit niedriger Bandbreite + weniger als 10 Minuten für eine vollständige Antwort + benötigen, dann könnten Sie 15 Minuten warten, bevor Sie auf + das alte Log zugreifen.

    + + Wenn Ihre Konfigurationsdatei Fehler enthält, während + Sie einen Neustart anweisen, dann wird Ihr Elternprozess nicht neu starten, + sondern sich mit einem Fehler beenden. Im Falle eines unterbrechungsfreien + Neustarts läßt er die Kinder weiterlaufen, wenn er sich beendet. + (Dies sind die Kinder, die sich "sanft beenden", indem sie ihre letzte + Anfrage erledigen.) Das verursacht Probleme, wenn Sie versuchen, + den Server neu zu starten -- er ist nicht in der Lage, sich an die Ports zu + binden, an denen er lauschen soll. Bevor Sie einen Neustart + durchführen, können Sie die Syntax der Konfigurationsdateien + mit dem Befehlszeilenargument -t überprüfen + (siehe auch httpd). Das garantiert + allerdings nicht, dass der Server korrekt starten wird. Um sowohl die + Syntax als auch die Semantik der Konfigurationsdateien zu prüfen, + können Sie versuchen, httpd als nicht-root-Benutzer + zu starten. Wenn dabei keine Fehler auftreten, wird er versuchen, seine + Sockets und Logdateien zu öffnen und fehlschlagen, da er nicht root + ist (oder weil sich der gegenwärtig laufende httpd + bereits diese Ports gebunden hat). Wenn er aus einem anderen Grund + fehlschlägt, dann liegt wahrscheinlich ein Konfigurationsfehler vor. + Der Fehler sollte behoben werden, bevor der unterbrechungsfreie Neustart + angewiesen wird. +
    + +
    Neustarten + +
    Signal: HUP
    +
    apachectl -k restart
    +
    + +

    Das Senden des Signals HUP oder restart + veranlaßt den Elternprozess, wie bei TERM alle seine + Kinder zu beenden. Der Elternprozess beendet sich jedoch nicht. Er liest + seine Konfigurationsdateien neu ein und öffnet alle Logdateien + erneut. Dann erzeugt er einen neuen Satz Kindprozesse und setzt die + Bedienung von Zugriffen fort.

    + +

    Benutzer von mod_status werden feststellen, dass + die Serverstatistiken auf Null gesetzt werden, wenn ein HUP + gesendet wurde.

    + + Wenn Ihre Konfigurationsdatei einen Fehler enthält, + während Sie einen Neustart anweisen, dann wird Ihr Elternprozess + nicht neu starten, sondern sich mit einem Fehler beenden. Lesen Sie oben, + wie Sie das vermeiden können. +
    + +
    Anhang: Signale und Wettkampfsituationen + +

    Vor der Version 1.2b9 des Apache existierten verschiedene + Wettkampfsituationen (race conditions), die den Neustart und + die Signale beeinflußt haben. (Eine einfache Beschreibung einer + Wettkampfsituation lautet: es ist ein zeitabhängiges Problem; wenn + etwas zum falschen Zeitpunkt erfolgt, wird es sich nicht wie erwartet + verhalten.) Bei Architekturen mit dem "richtigen" Funktionsumfang + haben wir so viele eliminiert wie wir nur konnten. Dennoch + sollte beachtet werden, dass noch immer Wettkampfsituationen auf + bestimmten Architekturen existieren.

    + +

    Bei Architekturen, die ein ScoreBoardFile auf Platte verwenden, + besteht die Gefahr, dass die Statustabelle beschädigt wird. + Das kann zu "bind: Address already in use" ("bind: Adresse wird + bereits verwendet", nach einem HUP) oder "long lost + child came home!" ("Der verlorene Sohn ist heimgekehrt", nach einem + USR1) führen. Ersteres ist ein schwerer Fehler, + wärend letzteres lediglich bewirkt, dass der Server einen Eintrag + in der Statustabelle verliert. So kann es ratsam sein, unterbrechungsfreie + Neustarts zusammen mit einem gelegentlichen harten Neustart zu verwenden. + Diese Probleme lassen sich nur sehr schwer umgehen, aber + glücklicherweise benötigen die meisten Architekturen keine + Statustabelle in Form einer Datei. Bitte lesen Sie für Architekturen, + die sie benötigen, die Dokumentation zu ScoreBoardFile.

    + +

    Alle Architekturen haben in jedem Kindprozess eine kleine + Wettkampfsituation, welche die zweite und nachfolgende Anfragen + einer persistenten HTTP-Verbindung (KeepAlive) umfaßt. Der Prozess + kann nach dem Lesen der Anfragezeile aber vor dem Lesen der Anfrage-Header + enden. Es existiert eine Korrektur, die für 1.2 zu spät kam. + Theoretisch sollte das kein Problem darstellen, da + der KeepAlive-Client derartige Ereignisse aufgrund von + Netzwerk-Latenzzeiten und Auszeiten des Servers erwarten sollte. + In der Praxis scheint keiner von beiden beeinflußt zu werden + -- in einem Testfall wurde der Server zwanzig mal + pro Sekunde neu gestartet, während Clients das Angebot abgegrast + haben, ohne kaputte Bilder oder leere Dokumente zu erhalten.

    +
    + +
    diff --git a/trunk/docs/manual/stopping.xml.es b/trunk/docs/manual/stopping.xml.es new file mode 100644 index 0000000000..a9670b245b --- /dev/null +++ b/trunk/docs/manual/stopping.xml.es @@ -0,0 +1,263 @@ + + + + + + + + + + Iniciar y Parar el servidor Apache + + +

    Este documento explica como iniciar y parar el servidor Apache + en sistemas tipo Unix. Los usuarios de Windows NT, 2000 y XP + deben consultar la sección Ejecutar Apache como un + servicio y los usuario de Windows 9x y ME deben consultar Ejecutar Apache como una + Aplicación de Consola para obtener información + sobre como controlar Apache en esas plataformas.

    +
    + +httpd +apachectl + +
    Introducción + +

    Para parar y reiniciar Apache, hay que enviar la señal + apropiada al proceso padre httpd que se esté + ejecutando. Hay dos maneras de enviar estas señales. En + primer lugar, puede usar el comando de Unix kill que + envía señales directamente a los procesos. Puede que + tenga varios procesos httpd ejecutandose en su + sistema, pero las señales deben enviarse solamente al proceso + padre, cuyo pid está especificado en la directiva PidFile. Esto quiere decir que no + debe necesitar enviar señales a ningún proceso excepto + al proceso padre. Hay tres señales que puede enviar al + proceso padre: TERM, HUP, y USR1, que van a ser descritas a + continuación.

    + +

    Para enviar una señal al proceso padre debe escribir un + comando como el que se muestra en el ejemplo:

    + +kill -TERM `cat /usr/local/apache2/logs/httpd.pid` + +

    La segunda manera de enviar señales a los procesos + httpd es usando las opciones de línea de + comandos -k: stop, restart, + y graceful, como se muestra más abajo. Estas + opciones se le pueden pasar al binario httpd, pero se recomienda que se + pasen al script de control apachectl, que a su vez los + pasará a httpd.

    + +

    Después de haber enviado las señales que desee a + httpd, puede ver como progresa el proceso + escribiendo:

    + +tail -f /usr/local/apache2/logs/error_log + +

    Modifique estos ejemplos para que coincidan con la + configuración que tenga especificada en las directivas + ServerRoot y PidFile en su fichero principal de + configuración.

    +
    + +
    Parar Apache + +
    Señal: TERM
    +
    apachectl -k stop
    +
    + +

    Enviar las señales TERM o stop + al proceso padre hace que se intenten eliminar todos los procesos + hijo inmediatamente. Esto puede tardar algunos minutos. Una vez + que hayan terminado todos los procesos hijo, terminará el + proceso padre. Cualquier petición en proceso terminará + inmediatanmente, y ninguna petición posterior será + atendida.

    +
    + +
    Reinicio Graceful + +
    Señal: USR1
    +
    apachectl -k graceful
    +
    + +

    Las señales USR1 o graceful + hacen que el proceso padre indique a sus hijos que + terminen después de servir la petición que estén + atendiendo en ese momento (o de inmediato si no están + sirviendo ninguna petición). El proceso padre lee de nuevo + sus ficheros de configuración y vuelve a abrir sus ficheros + log. Conforme cada hijo va terminando, el proceso padre lo va + sustituyendo con un hijo de una nueva generación con + la nueva configuración, que empeciezan a servir peticiones + inmediatamente.

    + + En algunas plataformas que no permiten usar + USR1 para reinicios graceful, puede usarse una + señal alternativa (como WINCH). Tambien puede + usar apachectl graceful y el script de control + enviará la señal adecuada para su plataforma. + +

    Apache está diseñado para respetar en todo momento la + directiva de control de procesos de los MPM, así como para + que el número de procesos y hebras disponibles para servir a + los clientes se mantenga en los valores adecuados durante el + proceso de reinicio. Aún más, está diseñado + para respetar la directiva StartServers de la siguiente + manera: si después de al menos un segundo el nuevo hijo de la + directiva StartServers + no ha sido creado, entonces crea los suficientes para se atienda + el trabajo que queda por hacer. Así, se intenta mantener + tanto el número de hijos adecuado para el trabajo que el + servidor tenga en ese momento, como respetar la configuración + determinada por los parámetros de la directiva + StartServers.

    + +

    Los usuarios del módulo mod_status + notarán que las estadísticas del servidor + no se ponen a cero cuando se usa la señal + USR1. Apache fue escrito tanto para minimizar el + tiempo en el que el servidor no puede servir nuevas peticiones + (que se pondrán en cola por el sistema operativo, de modo que + se no se pierda ningún evento), como para respetar sus + parámetros de ajuste. Para hacer esto, tiene que guardar el + scoreboard usado para llevar el registro de los procesos + hijo a través de las distintas generaciones.

    + +

    El mod_status también usa una G para indicar + que esos hijos están todavía sirviendo peticiones + previas al reinicio graceful.

    + +

    Actualmente no existe ninguna manera de que un script con un + log de rotación usando USR1 sepa con seguridad + que todos los hijos que se registraron en el log con anterioridad + al reinicio han terminado. Se aconseja que se use un retardo + adecuado después de enviar la señal USR1 + antes de hacer nada con el log antiguo. Por ejemplo, si la mayor + parte las visitas que recibe de usuarios que tienen conexiones de + baja velocidad tardan menos de 10 minutos en completarse, entoces + espere 15 minutos antes de hacer nada con el log antiguo.

    + + Si su fichero de configuración tiene errores cuando + haga el reinicio, entonces el proceso padre no se reinciciará + y terminará con un error. En caso de un reinicio graceful, + también dejará a los procesos hijo ejecutandose mientras + existan. (Estos son los hijos de los que se está saliendo de + forma graceful y que están sirviendo sus últimas + peticiones.) Esto provocará problemas si intenta reiniciar el + servidor -- no será posible conectarse a la lista de puertos + de escucha. Antes de reiniciar, puede comprobar que la sintaxis de + sus ficheros de configuracion es correcta con la opción de + línea de comandos -t (consulte httpd). No obstante, esto no + garantiza que el servidor se reinicie correctamente. Para + comprobar que no hay errores en los ficheros de + configuración, puede intentar iniciar httpd con + un usuario diferente a root. Si no hay errores, intentará + abrir sus sockets y logs y fallará porque el usuario no es + root (o porque el httpd que se está ejecutando + en ese momento ya está conectado a esos puertos). Si falla + por cualquier otra razón, entonces casi seguro que hay + algún error en alguno de los ficheros de configuración y + debe corregir ese o esos errores antes de hacer un reinicio + graceful. +
    + +
    Reiniciar Apache + +
    Señal: HUP
    +
    apachectl -k restart
    +
    + +

    El envío de las señales HUP o + restart al proceso padre hace que los procesos hijo + terminen como si le enviá ramos la señal + TERM, para eliminar el proceso padre. La diferencia + está en que estas señales vuelven a leer los archivos de + configuración y vuelven a abrir los ficheros log. Se genera + un nuevo conjunto de hijos y se continúa sirviendo + peticiones.

    + +

    Los usuarios del módulo mod_status + notarán que las estadísticas del servidor se ponen a + cero cuando se envía la señal HUP.

    + +Si su fichero de configuración contiene errores, cuando +intente reiniciar, el proceso padre del servidor no se +reiniciará, sino que terminará con un error. Consulte +más arriba cómo puede solucionar este problema. +
    + +
    Apéndice: señales y race conditions + +

    Con anterioridad a la versión de Apache 1.2b9 había + varias race conditions implicadas en las señales + para parar y reiniciar procesos (una descripción sencilla de + una race condition es: un problema relacionado con el momento en + que suceden las cosas, como si algo sucediera en momento en que no + debe, y entonces el resultado esperado no se corresponde con el + obtenido). Para aquellas arquitecturas que tienen el conjunto de + características "adecuadas", se han eliminado tantas race + conditions como ha sido posible. Pero hay que tener en cuenta que + todavía existen race conditions en algunas arquitecturas.

    + +

    En las arquitecturas que usan un ScoreBoardFile en disco, existe la + posibilidad de que se corrompan los scoreboards. Esto puede hacer + que se produzca el error "bind: Address already in use" + (después de usarHUP) o el error "long lost child + came home!" (después de usar USR1). En el + primer caso se trata de un error irrecuperable, mientras que en el + segundo, solo ocurre que el servidor pierde un slot del + scoreboard. Por lo tanto, sería aconsejable usar reinicios + graceful, y solo hacer reinicios normales de forma + ocasional. Estos problemas son bastante complicados de solucionar, + pero afortunadamente casi ninguna arquitectura necesita un fichero + scoreboard. Consulte la documentación de la directiva + ScoreBoardFile para ver + las arquitecturas que la usan.

    + +

    Todas las arquitecturas tienen una pequeña race condition + en cada proceso hijo implicada en la segunda y subsiguientes + peticiones en una conexión HTTP persistente + (KeepAlive). Puede ser que el servidor termine después de + leer la línea de petición pero antes de leer cualquiera + de las cebeceras de petición. Hay una solución que fue + descubierta demasiado tarde para la incluirla en versión + 1.2. En teoria esto no debe suponer ningún problema porque el + cliente KeepAlive ha de esperar que estas cosas pasen debido a los + retardos de red y a los timeouts que a veces dan los + servidores. En la practica, parece que no afecta a nada más + -- en una sesión de pruebas, un servidor se reinició + veinte veces por segundo y los clientes pudieron navegar sin + problemas por el sitio web sin encontrar problemas ni para + descargar una sola imagen ni encontrar un solo enlace roto.

    +
    + +
    + diff --git a/trunk/docs/manual/stopping.xml.ja b/trunk/docs/manual/stopping.xml.ja new file mode 100644 index 0000000000..51a7565c01 --- /dev/null +++ b/trunk/docs/manual/stopping.xml.ja @@ -0,0 +1,246 @@ + + + + + + + + + + $BDd;_$H:F5/F0(B + + +

    $B$3$NJ8=q$G$O(B Unix $B$KN`;w$7$?%7%9%F%`$G$N(B + Apache $B$NDd;_$H:F5/F0$K$D$$$F07$C$F$$$^$9!#(B + Windows NT, 2000, XP $B%f!<%6$O(B$B%5!<%S%9$H$7$F(B + Apache $B$r$B$G!"(BWindows 9x, ME$B%f!<%6$O(B$B%3%s%=!<%k%"%W%j%1!<%7%g%s$H$7$F(B + Apache $B$r$B$G!"(B + $B$3$l$i$N%W%i%C%H%[!<%`$G$N;HMQJ}K!$r$4Mw2<$5$$!#(B

    +
    + +httpd +apachectl + +
    $B%$%s%H%m%@%/%7%g%s(B + +

    Apache $B$rDd;_$7$?$j:F5/F0$7$?$j$9$k$?$a$K$O!"httpd $B%W%m%;%9$K%7%0%J%k$rAw$kI,MW$,$"$j$^$9!#(B + $B%7%0%J%k$rAw$k$K$OFs$D$NJ}K!$,$"$j$^$9!#(B + $B0l$DL\$O%W%m%;%9$KD>@\%7%0%J%k$rAw$k(B unix $B$N(B kill + $B%3%^%s%I$r;HMQ$9$kJ}K!$G$9!#(B + $B%7%9%F%`$r8+$l$P$?$/$5$s$N(B httpd $B$,(B + $BPidFile + $B$K=q$+$l$F$$$^$9!#$3$l$O$D$^$j!"?F0J30$N%W%m%;%9$K(B + $B%7%0%J%k$rAw$kI,MW$9$i$J$$!"$H$$$&$3$H$G$9!#(B + $B?F%W%m%;%9$KAw$k$3$H$,$G$-$k(B 3 $BTERM, + HUP, + USR1 + $B$G$9!#$3$l$i$N@bL@$K$D$$$F$OB3$-$r$4Mw2<$5$$!#(B

    + +

    $B?F%W%m%;%9$K%7%0%J%k$rAw$k$K$O!"(B + $B + +kill -TERM `cat /usr/local/apache2/logs/httpd.pid` + +

    httpd $B%W%m%;%9$K%7%0%J%k$rAw$k(B 2 $BHVL\$NJ}K!$O(B + -k $B$H$$$&%3%^%s%I%i%$%s0z?t$r;HMQ$9$k$3$H$G$9!#(B + $B2<$G@bL@$5$l$F$$$k$h$&$K!"(Bstop, restart, + graceful $B$r;XDj$G$-$^$9!#(B + $B$3$l$i$O(B httpd $B$N0z?t$G$9$,!"(B + $B@)8fMQ$N%9%/%j%W%H(B apachectl $B$O$=$l$i$N0z?t$r$=$N$^$^(B + httpd $B$KEO$7$^$9!#(B

    + +

    httpd $B$K%7%0%J%k$rAw$C$?8e!"(B + $Bu67$r + +tail -f /usr/local/apache2/logs/error_log +

    $B$3$3$K5s$2$?Nc$O!"3F<+$N(B + ServerRoot + $B$H(B + PidFile + $B$N@_Dj$KE,9g$9$k$h$&$KE,59=$@5$7$F2<$5$$!#(B

    +
    + +
    $B5^$JDd;_(B + +
    $B%7%0%J%k(B: TERM
    +
    apachectl -k stop
    +
    + +

    TERM $B$"$k$$$O(B stop + $B%7%0%J%k$r?F%W%m%;%9$KAw$k$H!"B(:B$K;R%W%m%;%9A4$F$r(B kill $B$7$h$&$H$7$^$9!#(B + $B;R%W%m%;%9$r40A4$K(B kill $B$7=*$o$k$^$G$K?tIC$+$+$k$+$b$7$l$^$;$s!#(B + $B$=$N8e!"?F%W%m%;%9<+?H$,=*N;$7$^$9!#(B + $B=hM}Cf$N%j%/%(%9%H$OA4$FDd;_$5$l!"$b$O$d%j%/%(%9%H$KBP$9$k(B + $B1~Ez$O$5$l$^$;$s!#(B

    +
    + +
    $B4K$d$+$J:F5/F0(B + +
    $B%7%0%J%k(B: USR1
    +
    apachectl -k graceful
    +
    + +

    $B?F%W%m%;%9$O(B USR1 $B$"$k$$$O(B graceful + $B%7%0%J%k$r$B=u8@(B$B$7$^$9!#(B + $B?F%W%m%;%9$O@_Dj%U%!%$%k$r:FFI9~$7$F!"%m%0%U%!%$%k$r3+$-D>$7$^$9!#(B + $B;R%W%m%;%9$,=y!9$K$J$/$J$k$K=>$C$F!"(B + $B?7$7$$(B$B@$Be(B$B$N@_Dj$K$h$k;R%W%m%;%9$KCV$-49$($F$$$-$^$9!#(B + $B$=$7$F!"$3$l$i$,?7$?$J%j%/%(%9%H$KB(:B$K1~Ez$7;O$a$^$9!#(B

    + + $BFCDj$N%W%i%C%H%[!<%`$G$O(B USR1 + $B$r4K$d$+$J:F5/F0$N$?$a$K;H$&$3$H$,$G$-$^$;$s$,!"Be$o$j$N%7%0%J%k(B + ($BNc$($P(B WINCH) $B$,;HMQ$G$-$k$G$7$g$&!#(B + apachectl graceful + $B$H$$$&%3%^%s%I$O%W%i%C%H%[!<%`$K9g$C$?%7%0%J%k$rAw$j$^$9!#(B + +

    $B$3$N%3!<%I$O>o$K(B + MPM $B$N%W%m%;%9@)8f%G%#%l%/%F%#%V$N@_Dj$r=E;k$7$^$9$N$G!"(B + $B%/%i%$%"%s%H$N%j%/%(%9%H$r07$&%W%m%;%9$H%9%l%C%I$N?t$r:F5/F0$N=hM}Cf$b(B + $BE,@Z$JCM$K0];}$5$l$^$9!#!#$^$?!"StartServers + $B$r/$J$/$H$b(B 1 $BIC8e$K(B StartServers $B8D$N?7$7$$;R%W%m%;%9$,(B + $B@8@.$5$l$F$$$J$1$l$P!"$=$N?t$K$J$k$h$&$KE,59%W%m%;%9$r@8@.$7$^$9!#(B + $B$3$N5sF0$O8=:_$NIi2Y$KBP$7$FE,@Z$J;R%W%m%;%9$N?t$H(B + StartServers $B%Q%i%a!<%?$G$N(B + $B4uK>$N?t$NN>J}$r0];}$7$h$&$H$7$F$$$^$9!#(B

    + +

    mod_status $B$r(B + $B;HMQ$7$F$$$k>l9g$O!"(BUSR1 $B%7%0%J%k$,Aw$i$l$?:]$K(B + $B%5!<%PE}7W$,%<%m$K(B$B@_Dj$5$l$J$$(B$B$3$H$K(B + $BCm0U$7$F$/$@$5$$!#(B + $B%5!<%P$,?7$7$$%j%/%(%9%H$K1~EzITG=$J;~4V$r:G>.$K$9$k$h$&$K(B + ($B%j%/%(%9%H$O(B OS $B$K$h$C$F%-%e!<$KDI2C$5$l$k$N$G@dBP$KJ6<:$O$7$^$;$s(B)$B!"(B + $B$^$?F1;~$K!"4uK>$N%A%e!<%K%s%0%Q%i%a!<%?$r$B%9%3%"%\!<%I(B$B$r0];}$7$J$1$l$P$J$j$^$;$s!#(B

    + +

    status $B%b%8%e!<%k$O!"4K$d$+$J:F5/F00JA0$+$i3+;O$7$F(B + $B%j%/%(%9%H$K1~Ez$7B3$1$F$$$k;R%W%m%;%9$rFCDj$9$k$?$a$K!"(B + G $B$r;H$&$3$H$b$7$^$9!#(B

    + +

    $B8=:_!"(BUSR1 $B$r;H$&%m%00\F0%9%/%j%W%H$G$O!"(B + $B:F5/F0A0$N;R%W%m%;%9$,%m%0$r=q$-=*$o$C$?$3$H$r3N>Z$9$kJ}K!$,(B + $B$"$j$^$;$s!#8E$$%m%0$KBP$7$F2?$+$9$kA0$K!"(B + USR1 $B%7%0%J%k$rAw$C$?8e$$$/$i$+E,Ev$J;~4VBT$D$3$H$r(B + $BDs0F$7$^$9!#Nc$($P!"BS0h$N69$$DL?.O)$N%f!<%6$N%j%/%(%9%H$N$[$H$s$I$,(B 10 + $BJ,0J2<$G40N;$7$F$$$k$H$$$&$3$H$,J,$+$C$F$$$l$P!"(B + $B8E$$%m%0$K2?$+$9$kA0$K(B 15 $BJ,BT$D$H$$$&$3$H$G$9!#(B

    + + $B:F5/F0;~$K@_Dj%U%!%$%k$K8m$j$,$"$k$H!"(B + $B?F%W%m%;%9$O:F5/F0$;$:$K%(%i!<$H$H$b$K=*N;$7$^$9!#(B + $B4K$d$+$J:F5/F0$N>l9g$O!"?F%W%m%;%9$,=*N;$7$?8e$G$b;R%W%m%;%9$,(B + $B-t + $B%3%^%s%I%i%$%s0z?t(B + (httpd $B$r$4Mw2<$5$$(B) + $B$r;H$C$F8!>Z$9$k$3$H$,$G$-$^$9!#(B + $B@_Dj%U%!%$%k$N0UL#E*$JFbMF$r9=J8$HF1MM$K8!>Z$7$?$$>l9g$O!"(B + $BHs(B root $B%f!<%6$G(B httpd $B$r5/F0$7$h$&$H$9$l$P$o$+$j$^$9!#(B + $B$b$7%(%i!<$,$J$1$l$P!"%=%1%C%H$d%m%0$r3+$3$&$H$7$F(B + root $B$G$J$$$?$a(B + ($B$b$7$/$Ohttpd + $B$,4{$KI,MW$J%]!<%H$K%P%$%s%I$7$F$$$k$?$a(B) + $B$K<:GT$9$k$G$7$g$&!#(B + $B$3$l0J30$NM}M3$G5/F0$K<:GT$7$?$N$G$"$l$P!"(B + $B$=$l$O@_Dj%U%!%$%k$N%(%i!<$G!"(B + $B4K$d$+$J:F5/F0$r9T$&A0$K$=$N8m$j$r=$@5$7$J$1$l$P$J$j$^$;$s!#(B +
    + +
    $B5^$J:F5/F0(B + +
    $B%7%0%J%k(B: HUP
    +
    apachectl -k restart
    +
    + +

    HUP $B$"$k$$$O(B restart $B%7%0%J%k$r?F%W%m%;%9$KAw$k$H!"(B + TERM $B$HF1MM$K;R%W%m%;%9$r(B kill $B$7$^$9$,!"(B + $B?F%W%m%;%9$O=*N;$7$^$;$s!#(B + $B@_Dj%U%!%$%k$r:FFI9~$7$F!"%m%0%U%!%$%kA4$F$r3+$-D>$7$^$9!#(B + $B$=$N8e!"?7$7$$;R%W%m%;%9$r5/F0$7$F1~Ez$rB3$1$^$9!#(B

    + +

    mod_status + $B$r;H$C$F$$$k>l9g$O!"(BHUP $B$,Aw$i$l$?>l9g$K(B + $B%5!<%PE}7W$,%<%m$K@_Dj$5$l$k$3$H$KCm0U$7$F$/$@$5$$!#(B

    + + $B:F5/F0;~$K@_Dj%U%!%$%k$K8m$j$,$"$k$H!"(B + $B?F%W%m%;%9$O:F5/F0$;$:$K%(%i!<$H$H$b$K=*N;$7$^$9!#(B + $B$3$l$rHr$1$k$K$O +
    + +
    $BIUO?(B: $B%7%0%J%k$H6%9g>uBV(B + +

    Apache 1.2b9 $B0JA0$O!":F5/F0$dDd;_$N%7%0%J%k$r4^$`(B$B6%9g>uBV(B + ($B6%9g>uBV$r4JC1$K@bL@$9$k$H(B: $B%?%$%_%s$K%0$h$kLdBj$G!"(B + $B6q9g$N0-$$;~4VBS$K$A$g$&$I2?$+$,5/$3$k$HM=A[30$NF0:n$r$9$k(B + $B$h$&$J$3$H$r;X$7$^$9(B) $B$,$"$j$^$7$?!#(B + $B!V@5$7$$!W5!G=$r;}$C$F$$$k%"!<%-%F%/%A%c$G$O!"$G$-$k$@$1(B + $B$3$N$h$&$J$3$H$,5/$3$i$J$$$h$&$K$7$F$$$^$9!#(B + $B$7$+$7!"$"$kuBV$OL$$@3N + +

    $B%G%#%9%/>e$G(B + ScoreBoardFile + $B$r;HMQ$7$F$$$k%"!<%-%F%/%A%c$G$O!"(B + $B@x:_E*$K%9%3%"%\!<%I$,2u$l$k2DG=@-$,$"$j$^$9!#(B + $B%9%3%"%\!<%I$,2u$l$?>l9g$O!"(B + "bind: Address already in use" (HUP $B8e(B) $B$d(B + "long lost child came home!" (USR1 $B8e(B) + $B$H$$$C$?7k2L$K$J$j$^$9!#(B + $BA0o$KFq$7$$$N$G$9$,!"(B + $B9,$$$J$3$H$KBgItJ,$N%"!<%-%F%/%A%c$G$O%9%3%"%\!<%I$N%U%!%$%k$OI,MW$"$j$^$;$s!#(B + $B$3$l$r;HMQ$9$k%"!<%-%F%/%A%c$O!"(B + ScoreBoardFile + $B$r$4Mw2<$5$$!#(B

    + +

    $BA4$F$N%"!<%-%F%/%A%c$K$*$$$F!"8D!9$N;R%W%m%;%9$G(B + $B7QB3E*$J(B HTTP $B%3%M%/%7%g%s(B (KeepAlive) + $B$K4X$9$k>.$5$J6%9g>uBV$,5/$3$j$($^$9!#(B + $B%j%/%(%9%H9T$rFI$s$@8e!"$=$7$F%j%/%(%9%H%X%C%@$rFI$`A0$K(B + $B;R%W%m%;%9$O=*N;$9$k$+$bCN$l$^$;$s!#(B + $B$3$l$KBP$9$k=$@5$,$"$j$^$9$,(B 1.2 $B$G=$@5$9$k$K$OH/8+$,CY$9$.$^$7$?!#(B + $BM}O@E*$K$O!"$3$l$OLdBj$G$O$"$j$^$;$s!#(B + $B$J$<$J$i(B KeepAlive $B$N%/%i%$%"%s%H$O!"%M%C%H%o!<%/CY1d$d(B + $B%5!<%P$N%?%$%`%"%&%H$J$I$KHw$($F$$$J$1$l$P$J$i$J$$$+$i$G$9!#(B + $Bo$K1\Mw$G$-$F$$$^$9!#(B

    +
    + +
    diff --git a/trunk/docs/manual/stopping.xml.ko b/trunk/docs/manual/stopping.xml.ko new file mode 100644 index 0000000000..54b64594c4 --- /dev/null +++ b/trunk/docs/manual/stopping.xml.ko @@ -0,0 +1,203 @@ + + + + + + + + + + Áß´Ü°ú Àç½ÃÀÛ + + +

    ÀÌ ¹®¼­´Â À¯´Ð½º·ù ½Ã½ºÅÛ¿¡¼­ ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÏ°í Àç½ÃÀÛÇÏ´Â + ³»¿ëÀ» ´ã°íÀÖ´Ù. À©µµ¿ìÁî NT, 2000, XP »ç¿ëÀÚ´Â ¼­ºñ½º·Î ¾ÆÆÄÄ¡ + ½ÇÇàÇϱ⿡¼­, À©µµ¿ìÁî 9x¿Í ME »ç¿ëÀÚ´Â ÄÝ¼Ö ÇÁ·Î±×·¥À¸·Î + ¾ÆÆÄÄ¡ ½ÇÇàÇϱ⿡¼­ Ç÷¡Æûº° ¾ÆÆÄÄ¡ Á¶ÀÛ¹ýÀ» ¾Ë ¼ö ÀÖ´Ù.

    +
    + +httpd +apachectl + +
    ¼Ò°³ + +

    ¾ÆÆÄÄ¡¸¦ Áß´ÜÇÏ°í Àç½ÃÀÛÇÏ·Á¸é ½ÇÇàÇÏ°í ÀÖ´Â + httpd ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀ» º¸³»¾ß ÇÑ´Ù. ½Ã±×³ÎÀ» + º¸³»´Â ¹æ¹ýÀº µÎ°¡Áö´Ù. Çϳª´Â À¯´Ð½º kill + ¸í·É¾î¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º¿¡ Á÷Á¢ ½Ã±×³ÎÀ» º¸³»´Â ¹æ¹ýÀÌ´Ù. + ½Ã½ºÅÛ¿¡ ¸¹Àº httpd°¡ ½ÇÇàµÇÁö¸¸, PidFile¿¡ pid°¡ ±â·ÏµÈ ºÎ¸ð¿Ü¿¡ + ´Ù¸¥ ÇÁ·Î¼¼½º¿¡ ½Ã±×³Î(signal)À» º¸³»¸é ¾ÈµÈ´Ù. Áï, ºÎ¸ðÀÌ¿Ü¿¡ + ´Ù¸¥ ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀ» º¸³¾ ÇÊ¿ä°¡ ¾ø´Ù´Â ¸»ÀÌ´Ù. ºÎ¸ð¿¡°Ô + º¸³¾ ¼ö ÀÖ´Â ½Ã±×³ÎÀº ¼¼°¡Áö·Î, ÀÌÁ¦ ¼³¸íÇÒ TERM, HUP, USR1ÀÌ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ºÎ¸ð¿¡°Ô ½Ã±×³ÎÀ» º¸³½´Ù:

    + +kill -TERM `cat /usr/local/apache2/logs/httpd.pid` + +

    httpd ÇÁ·Î¼¼½º¿¡°Ô ½Ã±×³ÎÀ» º¸³»´Â ´Ù¸¥ ¹æ¹ýÀº + ¸í·ÉÇà ¿É¼Ç -k¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ¾Æ·¡¼­ ¼³¸íÇÒ + stop, restart, gracefulÀº + httpd ½ÇÇàÆÄÀÏÀÇ ¾Æ±Ô¸ÕÆ®µéÀÌ´Ù. + ±×·¯³ª ÀÌ ¾Æ±Ô¸ÕÆ®µé·Î httpd¸¦ ½ÇÇàÇÏ´Â, apachectl ½ºÅ©¸³Æ®¸¦ + »ç¿ëÇÏ±æ ±ÇÇÑ´Ù.

    + +

    httpd¿¡ ½Ã±×³ÎÀ» º¸³½ÈÄ, ´ÙÀ½ ¸í·É¾î·Î + ÁøÇà»óȲÀ» ¾Ë ¼ö ÀÖ´Ù:

    + +tail -f /usr/local/apache2/logs/error_log + +

    À§ ¿¹¸¦ ´ç½ÅÀÇ ServerRoot¿Í PidFile ¼³Á¤¿¡ ¾Ë¸Â°Ô ¼öÁ¤Ç϶ó.

    +
    + +
    ´çÀå Áß´Ü + +
    ½Ã±×³Î: TERM
    +
    apachectl -k stop
    +
    + +

    TERMÀ̳ª stop ½Ã±×³ÎÀ» ºÎ¸ð¿¡°Ô + º¸³»¸é Áï½Ã ¸ðµç ÀÚ½ÄÀ» Á×ÀδÙ. ÀÚ½ÄÀ» ¿ÏÀüÈ÷ Á×À̴µ¥´Â + ¸î ÃÊ°¡ °É¸± ¼ö ÀÖ´Ù. ±×·±ÈÄ ºÎ¸ð°¡ Á¾·áÇÑ´Ù. ó¸®ÁßÀÎ ¿äûÀº + Áߴܵǰí, ´õ ÀÌ»ó ¿äûÀ» ¹ÞÁö¾Ê´Â´Ù.

    +
    + +
    Á¡ÀÝÀº Àç½ÃÀÛ + +
    ½Ã±×³Î: USR1
    +
    apachectl -k graceful
    +
    + +

    USR1À̳ª graceful ½Ã±×³ÎÀ» + ºÎ¸ð¿¡°Ô º¸³»¸é ºÎ¸ð ÇÁ·Î¼¼½º´Â Àڽĵ鿡°Ô ÇöÀç ¿äûÀ» + ó¸®ÇÑÈÄ Á¾·áÇ϶ó°í (ȤÀº ÇöÀç ¾Æ¹«°Íµµ ó¸®ÇÏÁö ¾Ê´Ù¸é + Áï½Ã Á¾·áÇ϶ó°í) Á¶¾ðÇÑ´Ù. ºÎ¸ð´Â ¼³Á¤ÆÄÀÏÀ» + ´Ù½ÃÀÐ°í ·Î±×ÆÄÀϵµ ´Ù½Ã ¿¬´Ù. ÀÚ½ÄÀÌ Á×À»¶§¸¶´Ù ºÎ¸ð´Â + Á×Àº ÀڽĴë½Å »õ·Î¿î ¼³Á¤ ¼¼´ë¿¡ ±âÃÊÇÑ ÀÚ½ÄÀ» + ½ÇÇàÇÏ¿© Áï½Ã ¿äûÀ» ó¸®ÇÏ°Ô ÇÑ´Ù.

    + + Á¡ÀÝÀº Àç½ÃÀÛ(graceful restart)À¸·Î USR1À» + »ç¿ëÇÒ ¼ö ¾ø´Â Ç÷¡Æû¿¡¼­´Â ´ë½Å (WINCH¿Í °°Àº) + ´Ù¸¥ ½Ã±×³ÎÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. apachectl gracefulÀº + Ç÷¡Æû¿¡ ¾Ë¸ÂÀº ½Ã±×³ÎÀ» º¸³½´Ù. + +

    Á¡ÀÝÀº Àç½ÃÀÛÀº Ç×»ó MPMÀÇ ÇÁ·Î¼¼½º Á¶Àý Áö½Ã¾î ¼³Á¤À» + °í·ÁÇÏ¿©, Àç½ÃÀÛµ¿¾È Ŭ¶óÀ̾ðÆ®¸¦ ¼­ºñ½ºÇÏ´Â ÇÁ·Î¼¼½º³ª ¾²·¹µå°¡ + Àû´çÇÑ ¼ö¸¦ À¯ÁöÇϵµ·Ï ¼³°èµÇ¾ú´Ù. °Ô´Ù°¡ StartServers´Â, ÀÏÃÊ ÈÄ + ÃÖ¼ÒÇÑ StartServers¸¸Å­ »õ·Î¿î ÀÚ½ÄÀÌ ¾È¸¸µé¾îÁö¸é ÀÚ½ÄÀÌ + StartServers °³°¡ µÇµµ·Ï »õ·Î ¸¸µç´Ù. Áï, ÇÁ·Î±×·¥Àº ¼­¹öÀÇ + ÇöÀç ºÎÇÏ¿¡ ¾Ë¸ÂÀº ÀÚ½ÄÀÇ °³¼ö¸¦ À¯ÁöÇϸç, + StartServers ÆĶó¹ÌÅÍ·Î ÁöÁ¤ÇÑ ´ç½ÅÀÇ + ±â´ë¸¦ Á¸ÁßÇÑ´Ù.

    + +

    mod_status »ç¿ëÀÚ´Â USR1À» + ¹ÞÀ»¶§ ¼­¹ö Åë°è°¡ 0ÀÌ µÇÁö ¾ÊÀ½À» ºÃÀ» + °ÍÀÌ´Ù. ¼­¹ö´Â »õ·Î¿î ¿äûÀ» (¿î¿µÃ¼Á¦´Â À̵éÀ» Å¥¿¡ ´ã¾Æ¼­ + ¾î¶² °æ¿ì¿¡µµ ÀÒ¾î¹ö¸®Áö ¾Ê´Â´Ù) ó¸®ÇÏÁö ¸øÇÏ´Â ½Ã°£À» + ÃÖ¼ÒÈ­ÇÏ°í ´ç½ÅÀÇ Æ©´× ÆĶó¹ÌÅ͸¦ Á¸ÁßÇϵµ·Ï ¸¸µé¾îÁ³´Ù. + À̸¦ À§ÇØ ¼¼´ë°£ ¸ðµç ÀÚ½ÄÀ» ±â·ÏÇÏ´Â scoreboard¸¦ + À¯ÁöÇÑ´Ù.

    + +

    status ¸ðµâÀº ¶ÇÇÑ Á¡ÀÝÀº Àç½ÃÀÛ Àü¿¡ ½ÃÀÛÇÏ¿© ¾ÆÁ÷µµ + ¿äûÀ» ó¸®ÇÏ°í ÀÖ´Â ÀÚ½ÄÀ» G·Î ¾Ë·ÁÁØ´Ù.

    + +

    ÇöÀç·Î´Â USR1À» »ç¿ëÇÏ´Â ·Î±×¼øȯ ½ºÅ©¸³Æ®°¡ + Àç½ÃÀÛÀü¿¡ ¸ðµç ÀÚ½ÄÀÌ ·Î±×ÀÛ¼ºÀ» ¸¶ÃÆ´ÂÁö ¾Ë ¼ö ÀÖ´Â + ¹æ¹ýÀÌ ¾ø´Ù. ¿ì¸®´Â USR1 ½Ã±×³ÎÀ» º¸³»°í + Àû´çÇÑ ½Ã°£ÀÌ Áö³­ÈÄ ÀÌÀü ·Î±×¸¦ ´Ù·çµµ·Ï Á¦¾ÈÇÑ´Ù. ¿¹¸¦ + µé¾î ³·Àº ´ë¿ªÆø »ç¿ëÀÚÀÇ °æ¿ì Á¢¼Ó ´ëºÎºÐÀÌ ¸¶Ä¡´Âµ¥ 10ºÐÀÌ + ¾È°É¸°´Ù¸é, ÀÌÀü ·Î±×¸¦ ´Ù·ç±âÀü¿¡ 15ºÐ ±â´Ù¸°´Ù.

    + + ¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖ´Ù¸é Àç½ÃÀ۽à ºÎ¸ð´Â Àç½ÃÀÛÇÏÁö + ¾Ê°í ¿À·ù¸¦ ³»¸ç Á¾·áÇÑ´Ù. ¶Ç, Á¡ÀÝÀº Àç½ÃÀÛÀÇ °æ¿ì Á¾·áÇÒ¶§ + ÀÚ½ÄÀÌ ½ÇÇàµÇµµ·Ï ³öµÐ´Ù. (ÀڽĵéÀº ÀÚ½ÅÀÇ ¸¶Áö¸· ¿äûÀ» + ó¸®ÇÏ°í "Á¡ÀÝ°Ô Á¾·áÇÑ´Ù".) ÀÌ´Â ¼­¹ö¸¦ Àç½ÃÀÛÇÒ¶§ + ¹®Á¦°¡ µÈ´Ù. ¼­¹ö´Â ÀÚ½ÅÀÌ ±â´Ù¸± Æ÷Æ®¿¡ ¿¬°áÇÏÁö ¸øÇÑ´Ù. + Àç½ÃÀÛÀü¿¡ -t ¸í·ÉÇà ¿É¼Ç(httpd Âü°í)À¸·Î ¼³Á¤ÆÄÀÏ + ¹®¹ýÀ» °Ë»çÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª ÀÌ·± °Ë»çµµ ¼­¹ö°¡ ¿Ã¹Ù·Î + Àç½ÃÀÛÇÒÁö¸¦ º¸ÀåÇÏÁö ¸øÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ ¹®¹ýÀÌ ¾Æ´Ñ Àǹ̸¦ + °Ë»çÇÏ·Á¸é root°¡ ¾Æ´Ñ »ç¿ëÀÚ·Î httpd¸¦ ½ÃÀÛÇغ¼ ¼ö ÀÖ´Ù. + root°¡ ¾Æ´Ï±â¶§¹®¿¡ (¾Æ´Ï¸é ÇöÀç ±× Æ÷Æ®¸¦ »ç¿ëÇÏ´Â + httpd°¡ ½ÇÇàµÇ±â¶§¹®¿¡) ¿À·ù°¡ ¾ø´Ù¸é ¼ÒÄÏ°ú + ·Î±×ÆÄÀÏÀ» ¿­·Á°í ½ÃµµÇÏ´Â °úÁ¤¿¡¼­ ½ÇÆÐÇÒ °ÍÀÌ´Ù. ´Ù¸¥ + ÀÌÀ¯¶§¹®¿¡ ½ÇÆÐÇÑ´Ù¸é ¾Æ¸¶µµ ¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖÀ» °ÍÀÌ´Ù. + Á¡ÀÝÀº Àç½ÃÀÛÀ» ÇϱâÀü¿¡ ¿À·ù¸¦ °íÃľßÇÑ´Ù. +
    + +
    ´çÀå Àç½ÃÀÛ + +
    ½Ã±×³Î: HUP
    +
    apachectl -k restart
    +
    + +

    HUPÀ̳ª restart ½Ã±×³ÎÀ» + ºÎ¸ð¿¡°Ô º¸³»¸é TERM°ú °°ÀÌ ¸ðµç ÀÚ½ÄÀ» + Á×ÀÌÁö¸¸ ºÎ¸ð´Â Á¾·áÇÏÁö ¾Ê´Â´Ù. ºÎ¸ð´Â ¼³Á¤ÆÄÀÏÀ» ´Ù½ÃÀаí + ·Î±×ÆÄÀÏÀ» ´Ù½Ã ¿¬´Ù. ±×¸®°í »õ·Î¿î ÀڽĵéÀ» ¸¸µé°í ¼­ºñ½º¸¦ + °è¼ÓÇÑ´Ù.

    + +

    mod_status »ç¿ëÀÚ´Â HUP¸¦ + º¸³»¸é ¼­¹ö Åë°è°¡ 0ÀÌ µÊÀ» ¾Ë ¼ö ÀÖ´Ù.

    + +¼³Á¤ÆÄÀÏ¿¡ ¿À·ù°¡ ÀÖ´Ù¸é Àç½ÃÀÛÀ» Çصµ ºÎ¸ð´Â Àç½ÃÀÛÇÏÁö +¾Ê°í ¿À·ù¸¦ ³»¸ç Á¾·áÇÒ °ÍÀÌ´Ù. À̸¦ ÇÇÇÏ´Â ¹æ¹ýÀº À§¸¦ Âü°íÇ϶ó. +
    + +
    ºÎ·Ï: ½Ã±×³Î°ú ·¹À̽º ÄÁµð¼Ç + +

    Apache 1.2b9 ÀÌÀü¿¡´Â Àç½ÃÀÛ°ú Á¾·á ½Ã±×³Î¿¡ °ü°èµÈ + ·¹À̽º ÄÁµð¼Ç(race condition)ÀÌ ÀÖ¾ú´Ù. (·¹À̽º + ÄÁµð¼ÇÀº °£´ÜÇÑ ¼³¸íÇÏÀÚ¸é, ¾î¶² ÀÏÀÌ À߸øµÈ¶§ ÀϾ¼­ + ±â´ëÇÑ´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â ½Ã°£¿¡ ¹Î°¨ÇÑ ¹®Á¦´Ù.) "¿Ã¹Ù¸¥" + ±â´ÉÀÌ ÀÖ´Â ¾ÆÅ°ÅØÃÄ¿¡¼­ ¿ì¸®´Â ÀÌ·± ¹®Á¦¸¦ ÃÖ´ëÇÑ ÇØ°áÇß´Ù. + ±×·¯³ª ¾î¶² ¾ÆÅ°ÅØÃÄ¿¡´Â ¾ÆÁ÷µµ ·¹À̽º ÄÁµð¼ÇÀÌ Á¸ÀçÇÔÀ» + ÁÖÀÇÇ϶ó.

    + +

    ScoreBoardFileÀ» + µð½ºÅ©¿¡ ÀúÀåÇÏ´Â ¾ÆÅ°ÅØÃÄ´Â scoreboard¸¦ ¸Á°¡Æ®¸± °¡´É¼ºÀÌ + ÀÖ´Ù. ±×·¯¸é (HUPÈÄ) "bind: Address already in use" + ȤÀº (USR1 ÈÄ) "long lost child came home!"ÀÌ + ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ÀüÀÚ´Â ½É°¢ÇÑ ¿À·ùÀÌ°í, ÈÄÀÚ´Â ´ÜÁö ¼­¹ö°¡ + scoreboard slotÀ» ÀÒ°Ô ¸¸µç´Ù. ±×·¡¼­ °­Á¦ Àç½ÃÀÛÀ» ÁÙÀÌ°í + Á¡ÀÝÀº Àç½ÃÀÛÀ» »ç¿ëÇϱæ ÃßõÇÑ´Ù. ÀÌ ¹®Á¦´Â ÇØ°áÇϱ⠸ſì + Èûµé´Ù. ±×·¯³ª ´ÙÇàÈ÷µµ ´ëºÎºÐÀÇ ¾ÆÅ°ÅØÃÄ´Â scoreboard·Î ÆÄÀÏÀ» + »ç¿ëÇÏÁö ¾Ê´Â´Ù. ÆÄÀÏÀ» »ç¿ëÇÏ´Â ¾ÆÅ°ÅØÃĶó¸é ScoreBoardFile ¹®¼­¸¦ Âü°íÇ϶ó.

    + +

    ¸ðµç ¾ÆÅ°ÅØÃÄ¿¡´Â Áö¼ÓµÇ´Â HTTP ¿¬°á (KeepAlive)¿¡¼­ + µÎ¹ø° ÀÌÈÄ ¿äûÀ» ó¸®ÇÏ´Â ÀڽĿ¡ ¾à°£ÀÇ ·¹À̽º ÄÁµð¼ÇÀÌ + ÀÖ´Ù. ÀÚ½ÄÀº ¿äûÁÙÀ» ÀÐÀº ÈÄ ¿äû Çì´õ¸¦ ÀбâÀü¿¡ Á¾·áÇÒ ¼ö + ÀÖ´Ù. ÀÌ ¹®Á¦´Â ³Ê¹« ´Ê°Ô ¹ß°ßÇÏ¿© 1.2 ¹öÀüÀÌ ³ª¿ÂÈÄ¿¡¾ß + ¼öÁ¤µÇ¾ú´Ù. ±×·¯³ª ³×Æ®¿÷ Áö¿¬À̳ª ¼­¹ö ½Ã°£Á¦ÇѶ§¹®¿¡ KeepAlive + Ŭ¶óÀ̾ðÆ®´Â ÀÌ·± °æ¿ì¸¦ ¿¹»óÇؾßÇϱ⠶§¹®¿¡ ÀÌ·Ð»ó ¹®Á¦´Â + ¾ÈµÈ´Ù. ½ÇÁ¦·Î ¼­¹ö¸¦ °Ë»çÇϱâÀ§ÇØ ÀÏÃÊ¿¡ 20¹ø Àç½ÃÀÛÇÏ´Â µ¿¾È + Ŭ¶óÀ̾ðÆ®°¡ ±úÁø ±×¸²À̳ª ºó ¹®¼­¾øÀÌ »çÀÌÆ®¸¦ ¼º°øÀûÀ¸·Î + ÀоîµéÀÌ±æ ±â´ëÇÏÁö ¾Ê´Â´Ù¸é ¹®Á¦°¡ ¾ÈµÈ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/stopping.xml.meta b/trunk/docs/manual/stopping.xml.meta new file mode 100644 index 0000000000..0b82e7c58e --- /dev/null +++ b/trunk/docs/manual/stopping.xml.meta @@ -0,0 +1,15 @@ + + + + stopping + / + . + + + de + en + es + ja + ko + + diff --git a/trunk/docs/manual/style/build.properties b/trunk/docs/manual/style/build.properties new file mode 100644 index 0000000000..57ce7de3bc --- /dev/null +++ b/trunk/docs/manual/style/build.properties @@ -0,0 +1,7 @@ +# This file contains version specific properties + +# No xml files yet +noxml.fr=new_features_2_0.html.fr upgrading.html.fr + +# (pending) httpd version +httpd.version=2.1.4 diff --git a/trunk/docs/manual/style/common.dtd b/trunk/docs/manual/style/common.dtd new file mode 100644 index 0000000000..fba4d5f004 --- /dev/null +++ b/trunk/docs/manual/style/common.dtd @@ -0,0 +1,184 @@ + + + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/css/manual-chm.css b/trunk/docs/manual/style/css/manual-chm.css new file mode 100644 index 0000000000..9cab12ed61 --- /dev/null +++ b/trunk/docs/manual/style/css/manual-chm.css @@ -0,0 +1,27 @@ +@import url(manual-loose-100pc.css); + +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +html { + font-size: 95%; +} + +h1 { + margin: 0 0 0.5em 0; +} + +/* the end */ diff --git a/trunk/docs/manual/style/css/manual-loose-100pc.css b/trunk/docs/manual/style/css/manual-loose-100pc.css new file mode 100644 index 0000000000..44d9c935bc --- /dev/null +++ b/trunk/docs/manual/style/css/manual-loose-100pc.css @@ -0,0 +1,155 @@ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * manual.css - no sidebar, 100% normal font height + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* import the main CSS, so we + * have to adjust only a few things + */ +@import url(manual.css); + +html { + font-size: 100%; +} + +/* "sidebar" background is white here */ +div#quickview a:hover, +div#quickview a:active { + background-color: #f0f0f0; + color: #0073c7; +} + +div#quickview code.module a:hover, +div#quickview code.module a:active { + background-color: #f0f0f0; + color: #8b4513; +} + +div#quickview code.directive a:hover, +div#quickview code.directive a:active { + background-color: #f0f0f0; + color: #287f00; +} + +h1 { + font-size: 1.5em; +} + +h2 { + font-size: 1.2em; +} + +.category h2 { + font-size: 1em; +} + +h3 { + font-size: 1.1em; +} + +h4 { + font-size: 1em; +} + +div.example h3, +div.note h3, +div.warning h3 { + font-size: 1em; +} + +div#quickview h3, +div#quickview h3.directives { + margin: 1em 0 0.3em 0; + font-size: 1.1em; +} + +div#quickview h3.directives { + margin-top: 0; +} + +div#quickview li { + font-size: 1em; +} + +div#quickview ul { + margin-bottom: 1em; +} + +div#quickview ul#toc { + margin-left: 0; +} + +div#quickview li img { + display: inline; + margin-right: 19px; +} + +#module-index div#quickview ul#toc, +#manual-page div#quickview ul#toc, +div#quickview #topics { + padding-left: 0; +} + +div#quickview .seealso { + padding-left: 34px; +} + +#module-index div#quickview ul#toc li, +#manual-page div#quickview ul#toc li, +div#quickview #topics li, +div#quickview .seealso li { + margin: 0; + list-style-type: none; +} + +div#page-header p.menu, +div#path, +div#footer { + font-size: smaller; +} + +div#quickview { + position: static; + margin: 0 0 1em 30px; + padding: 0; + width: auto; + background-color: #fff; +} + +div#page-content { + margin-right: 0; + padding-right: 0; +} + +div.example pre, +div.example p > code { + font-size: 0.9em; +} + +div.note pre, +div.warning pre { + font-size: 0.9em; +} + +table.qref td.descr { + font-size: 0.9em; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * -> The End <- + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/trunk/docs/manual/style/css/manual-print.css b/trunk/docs/manual/style/css/manual-print.css new file mode 100644 index 0000000000..b600efbb50 --- /dev/null +++ b/trunk/docs/manual/style/css/manual-print.css @@ -0,0 +1,717 @@ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * manual.css for printers + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * mainframe ;-) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +html { + font-size: 11pt; +} + +body { + background-color: #fff; + color: #000; + padding: 0 0 0 0; + margin: 0; + font-family: "Times New Roman", serif; + font-weight: normal; +} + +pre, code { + font-family: "Courier New", Courier, monospace; +} + +strong { + font-weight: bold; +} + +q, em, var { + font-style: italic; +} + +span.transnote, span.phonetic { + font-weight: normal; + background-color: inherit; + color: #888; +} + +/* fixup IE & Opera + * otherwise they forget to inherit + * the computed font-size value + */ +table, code { + font-size: 1em; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Links + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* normal links */ +/* ====================== */ +a:link, +a:visited, +a:hover, +a:active { + color: #000; + background-color: inherit; + text-decoration: none; +} + +/* sidebar */ +div#quickview a:hover, +div#quickview a:active { + background-color: #fff; + color: #000; +} + +/* EXPERIMENTAL! I'm waiting for complaints... */ +#page-content p > a[href]:after { + content: " (\002197\0000A0" attr(href) ") "; + color: #036; +} + +/* code.module [links] */ +/* ====================== */ +code.module, +code.module a:link, +code.module a:visited, +code.module a:hover, +code.module a:active { + color: #8b4513; + background-color: inherit; + text-decoration: none; +} + +/* code.directive [links] */ +/* ====================== */ +code.directive, +code.directive a:link, +code.directive a:visited, +code.directive a:hover, +code.directive a:active { + color: #287f00; + background-color: inherit; + text-decoration: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Headings + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* h1 */ +/* ====================== */ +h1 { + padding: 0 0 0.2em 0; + margin: 1em 0 0.5em 0; + border-style: none none solid none; + border-bottom-width: 1px; + border-bottom-color: #405871; + background-color: inherit; + color: #000; + text-decoration: none; + font-size: 17pt; + font-weight: bold; + text-align: center; +} + +/* h2 */ +/* ====================== */ +h2 { + padding: 0.2em 0 0.2em 0.2em; + margin: 0 0 0.5em 0; + width: 80%; + text-decoration: none; + font-size: 15pt; + font-weight: bold; + border-bottom: 1px solid #000; + text-align: left; +} + +.section h2, +.directive-section h2, +.category h2 { + background-color: #fff; + color: #000; +} + +/* take care of s inside */ +h2 a, +h2 a:hover, +h2 a:active { + color: inherit; + background-color: inherit; + text-decoration: none; +} + +/* h3, h4 */ +/* ====================== */ +h3 { + background-color: inherit; + color: #000; + text-decoration: none; + font-weight: bold; + font-size: 13pt; + margin: 1.3em 0 0.4em 0; + padding: 0 0 0 0.2em; +} + +h4 { + background-color: inherit; + color: #000; + text-decoration: none; + font-weight: bold; + font-size: 11pt; + margin: 1.3em 0 0.2em 0; + padding: 0 0 0 0.2em; +} + +/* margin adjustment */ +h3 + *, h4 + * { + margin-top: 0; +} + +/* IE confuses the + * :-( + * so reset some things + */ +ul, .section table, .directive-section table { + margin-bottom: 1em; +} + +/* titles for + * examples, notes and warnings + */ +div.example h3, +div.note h3, +div.warning h3 { + margin: 0 0 0.5em 0; + text-align: left; + font-size: 11pt; +} + +/* sidebar */ +div#quickview h3 { + margin: 1em 0 0.3em 0; + font-size: 13pt; +} + +div#quickview h3.directives { + margin-top: 0; +} + +/* take care of s inside */ +h3 a, +h3 a:hover, +h3 a:active, +h4 a, +h4 a:hover, +h4 a:active { + color: inherit; + background-color: inherit; + text-decoration: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Up & Top helper images + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +div.up, +div.top { + display: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Tables + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* general */ +/* ====================== */ +table { + border: 1px solid #000; + border-collapse: collapse; + padding: 2px; + margin-top: 0.5em; + margin-bottom: 0; + margin-left: 1px; /* border-width == 1px */ +} + +td, th { + empty-cells: show; /* show border around empty cells */ + padding: 0.1em 0.2em; + vertical-align: top; + text-align: left; + line-height: 1.1em; +} + +th { + font-weight: bold; +} + +td.centered { + text-align: center; +} + +tr.header, tr.header th { + border-top: 1px solid #000; + border-bottom: 1px solid #000; +} + +/* bordered table cells */ +/* ====================== */ + +/* turn off borders in tables nested in + * bordered tables per default + */ +table.bordered table td, +table.bordered table th { + border-style: none; +} + +table.bordered td, +table.bordered th, +table table.bordered td, +table table.bordered th { + border: 1px solid #000; +} + +/* mod/dir. overview table and quick reference */ +/* ============================================ */ +table.module th, +table.directive th { + white-space: nowrap; +} + +table.qref { + border-collapse: collapse; + width: auto; +} + +table.qref td { + border-style: none solid; + border-color: #000; + border-width: 1px; +} + +table.qref td.descr { + padding-left: 1em; + font-size: 11pt; +} + +table#legend { + width: 100%; + border-style: none; + border-width: 0; + vertical-align: bottom; + padding: 0; + margin: 0; +} + +table#legend td { + vertical-align: bottom; + margin: 0; + padding: 0; +} + +table#legend table { + vertical-align: bottom; + margin: 0 0 0 0.4em; + padding: 0; + height: 7.5em; +} + +table#legend td.letters span { + display: none; +} + +table#legend table td, +table#legend table th { + vertical-align: middle; + padding: 0.1ex 0.2em; + line-height: 1em; +} + +/* related modules & dir. */ +/* ====================== */ + +/* assuming, all links are enclosed by + * or + * + */ + +table.related { + border-collapse: collapse; +} + +table.related th, +table.related td { + background-color: #fff; + color: #000; + padding: 0.2ex 0.4em; + border: 1px solid #000; +} + +table.related th { + vertical-align: middle; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Lists + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* list default values */ +/* ====================== */ +ul { + list-style-type: disc; +} + +ul ul { + list-style-type: square; +} + +ul ul ul { + list-style-type: circle; +} + +li, dt, dd { + line-height: 1.1em; +} + +dt { + margin-top: 0.5em; + font-weight: bold; +} + +ol li { + margin-top: 0.5em; +} + +ol.up-A { + list-style-type: upper-alpha; +} + +/* table of contents */ +/* ====================== */ +#toc, +#topics { + margin: 0; + padding: 0; +} + +#toc li, +#topics li { + list-style-type: square; + margin: 0 0 1em 0; + padding: 0; +} + +#toc li img, +#topics li img { + margin-right: 19px; +} + +/* see also */ +/* ====================== */ +.seealso { + margin: 0; + padding: 0; +} + +.seealso li { + list-style-type: square; + margin: 0 0 1em 0; + padding: 0 0 0 34px; +} + +/* related modules & dir. */ +/* ====================== */ +table.related td ul, +table.related td li { + list-style-type: none; + margin: 0; + padding: 0; +} + +/* list of all directives */ +/* ====================== */ +div#directive-list ul { + margin: 0; + padding: 0; +} + +/* quickview */ +/* ====================== */ +div#quickview li { + font-size: 11pt; +} + +div#quickview ul { + margin: 0; + padding: 0; +} + +div#quickview ul#toc { + margin: 0; + padding: 0; +} + +div#quickview ul#toc li { + margin: 0 0 0 1em; + padding: 0; + list-style-type: square; + list-style-position: outside; +} + +div#quickview li img { + display: none; +} + +#module-index div#quickview ul#toc, +#manual-page div#quickview ul#toc, +div#quickview #topics, +div#quickview .seealso { + padding-left: 0; +} + +#module-index div#quickview ul#toc li, +#manual-page div#quickview ul#toc li, +div#quickview #topics li, +div#quickview .seealso li { + margin: 0 0 2px 1em; + padding: 0; + list-style-type: square; + list-style-position: outside; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * main page sections + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* page header */ +/* ====================== */ +div#page-header { + margin-left: 0; +} + +div#page-header img { + display: none; +} + +div#page-header p.apache { + background-color: #fff; + color: #000; + padding: 0; + margin: 0; + text-align: center; + vertical-align: middle; + font-size: 20pt; + font-weight: bold; + line-height: 20pt; +} + +div#page-header p.menu { + display: none; +} + +/* breadcrumb navigation */ +div#path { + display: none; +} + +/* content sections */ +/* ====================== */ +div#preamble { + padding-bottom: 1em; + margin-left: 0; +} + +div.section, +div.directive-section { + margin: 0; + padding: 0; +} + +.section p, +.directive-section p { + margin: 0 0 1em 0; + padding: 0; +} + +/* look for this on directive + * list pages + */ +div#directive-list { + margin-left: 0; + padding: 0 0 1em 1em; +} + +div#directive-ref { + margin: -1em 0 0 1px; + padding: 0 0 1em 0; + width: auto; +} + +/* no sidebar */ +div#quickview { + position: static; + margin: 0 0 1em 0; + padding: 0; + width: auto; + background-color: #fff; + color: inherit; +} + +/* -> keep content wide */ +div#page-content { + padding-top: 0; + margin-right: 0; + padding-right: 0; +} + +/* in general */ +p { + line-height: 1.1em; +} + +/* page footer */ +/* ====================== */ +div#footer { + margin-left: 0; + font-size: 11pt; + border-top: 1px solid #000; + padding-top: 0.2em; +} + +div#footer p.apache { + float: none; + text-align: center; + padding: 0 0 1em 0; + margin-top: 0; + font-weight: bold; +} + +div.toplang, +div.bottomlang, +div#footer p.menu { + display: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * subsections (examples, notes, warnings) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* examples */ +/* ====================== */ +div.example, +div.note div.example { + background-color: #fff; + color: #000; + padding: 0.5em; + margin: 1em; + border: 1px dotted #000; +} + +/* the following [block] elements + * may appear inside example... + */ +div.example p, +div.example pre, +div.example table { + padding: 0; + margin: 0; +} + +div.example p { + line-height: 1em; +} + +div.example pre, +div.example p > code { + font-size: 10pt; +} + +/* notes & warnings */ +/* ====================== */ +div.note, +div.warning { + background-color: #fff; + color: #000; + border: 1px solid #000; + padding: 0.5em; + margin: 1em; +} + +div.note p, +div.warning p { + margin: 0; + padding: 0; +} + +div.note pre, +div.warning pre { + font-size: 10pt; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * quotations, indented paragraphs and figures + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +p.letters { + display: none; +} + +blockquote p { + font-style: italic; + margin: 0; +} + +blockquote p.cite { + font-style: normal; + margin-top: 0; + margin-left: 2em; +} + +blockquote p.cite cite { + font-style: normal; +} + +p.indent { + margin-left: 2em; + margin-top: 1em; +} + +#index-page form { + display: none; +} + +p.figure { + margin-left: 2em; + font-style: italic; +} + +p.figure img { + border: 1px solid #000; +} + +p.figure dfn { + font-weight: bold; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * -> The End <- + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/trunk/docs/manual/style/css/manual-zip-100pc.css b/trunk/docs/manual/style/css/manual-zip-100pc.css new file mode 100644 index 0000000000..ab04455305 --- /dev/null +++ b/trunk/docs/manual/style/css/manual-zip-100pc.css @@ -0,0 +1,23 @@ +@import url(manual-loose-100pc.css); + +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +h1 { + margin: 0 0 0.5em 0; +} + +/* the end */ diff --git a/trunk/docs/manual/style/css/manual-zip.css b/trunk/docs/manual/style/css/manual-zip.css new file mode 100644 index 0000000000..db19662c96 --- /dev/null +++ b/trunk/docs/manual/style/css/manual-zip.css @@ -0,0 +1,24 @@ +@import url(manual.css); + +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +h1 { + margin: 0 0 0.5em 0; +} + +/* the end */ diff --git a/trunk/docs/manual/style/css/manual.css b/trunk/docs/manual/style/css/manual.css new file mode 100644 index 0000000000..cf060aecbf --- /dev/null +++ b/trunk/docs/manual/style/css/manual.css @@ -0,0 +1,1017 @@ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * manual.css + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * mainframe ;-) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +html { + font-size: 14px; +} + +body { + background-color: #fff; + color: #036; + padding: 0 1em 0 0; + margin: 0; + font-family: Arial, Helvetica, sans-serif; + font-weight: normal; +} + +pre, code { + font-family: "Courier New", Courier, monospace; +} + +strong { + font-weight: bold; +} + +q, em, var { + font-style: italic; +} + +span.transnote, span.phonetic { + font-weight: normal; + background-color: inherit; + color: #888; +} + +/* fixup IE & Opera + * otherwise they forget to inherit + * the computed font-size value + */ +table, code { + font-size: 1em; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Links + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* normal links */ +/* ====================== */ +a:link { + color: #0073c7; + background-color: inherit; +} + +a:visited { + color: #5A88B5; + background-color: inherit; +} + +a:link:hover, +a:link:active, +a:visited:hover, +a:visited:active { + color: #0073c7; + background-color: #f0f0f0; +} + +/* hover on non-white backgrounds */ +tr.odd a:hover, +tr.odd a:active, +tr.header a:hover, +tr.header a:active, +div.note a:hover, +div.note a:active, +div.example a:hover, +div.example a:active, +div.warning a:hover, +div.warning a:active, +div#quickview a:hover, +div#quickview a:active { + background-color: #fff; + color: #0073c7; +} + +/* code.module [links] */ +/* ====================== */ +code.module, +code.module a:link { + color: #8b4513; + background-color: inherit; +} + +code.module a:visited { + color: #bc8f8f; + background-color: inherit; +} + +code.module a:hover, +code.module a:active { + color: #8b4513; + background-color: #f0f0f0; +} + +/* hover on non-white backgrounds */ +tr.odd code.module a:hover, +tr.odd code.module a:active, +tr.header code.module a:hover, +tr.header code.module a:active, +div.note code.module a:hover, +div.note code.module a:active, +div.example code.module a:hover, +div.example code.module a:active, +div.warning code.module a:hover, +div.warning code.module a:active, +div#quickview code.module a:hover, +div#quickview code.module a:active { + background-color: #fff; + color: #8b4513; +} + +/* code.directive [links] */ +/* ====================== */ +code.directive, +code.directive a:link { + color: #287f00; + background-color: inherit; +} + +code.directive a:visited { + color: #35a500; + background-color: inherit; +} + +code.directive a:hover, +code.directive a:active { + color: #287f00; + background-color: #f0f0f0; +} + +/* hover on non-white backgrounds */ +tr.odd code.directive a:hover, +tr.odd code.directive a:active, +tr.header code.directive a:hover, +tr.header code.directive a:active, +div.note code.directive a:hover, +div.note code.directive a:active, +div.example code.directive a:hover, +div.example code.directive a:active, +div.warning code.directive a:hover, +div.warning code.directive a:active, +div#quickview code.directive a:hover, +div#quickview code.directive a:active { + background-color: #fff; + color: #287f00; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Headings + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* h1 */ +/* ====================== */ +h1 { + padding: 0.2em; + margin: 0; + border: 1px solid #405871; + background-color: inherit; + color: #036; + text-decoration: none; + font-size: 22px; + font-weight: bold; +} + +/* h2 */ +/* ====================== */ +h2 { + padding: 0.2em 0 0.2em 0.7em; + margin: 0 0 0.5em 0; + text-decoration: none; + font-size: 18px; + font-weight: bold; +} + +.section h2 { + background-color: #405871; + color: #fff; +} + +.directive-section h2 { + background-color: #557697; + color: #fff; +} + +.category h2 { + background-color: #e5ecf3; + color: #405871; + font-size: 14px; +} + +/* take care of s inside */ +h2 a, +h2 a:hover, +h2 a:active { + color: inherit; + background-color: inherit; + text-decoration: none; +} + +/* h3, h4 */ +/* ====================== */ +h3 { + background-color: inherit; + color: #036; + text-decoration: none; + font-weight: bold; + font-size: 16px; + margin: 1.3em 0 0.4em 0; + padding: 0; +} + +h4 { + background-color: inherit; + color: #036; + text-decoration: none; + font-weight: bold; + font-size: 14px; + margin: 1.3em 0 0.2em 0; + padding: 0; +} + +/* margin adjustment */ +h3 + *, h4 + * { + margin-top: 0; +} + +/* IE confuses the + * :-( + * so reset some things + */ +ul, .section table, .directive-section table { + margin-bottom: 1em; +} + +/* titles for + * examples, notes and warnings + */ +div.example h3, +div.note h3, +div.warning h3 { + margin: 0 0 0.5em 0; + text-align: left; + font-size: 14px; +} + +/* sidebar */ +div#quickview h3 { + margin: 1em 0 0.3em 0.5em; + font-size: 15px; +} + +div#quickview h3.directives { + margin-top: 0.3em; +} + +/* take care of s inside */ +h3 a, +h3 a:hover, +h3 a:active, +h4 a, +h4 a:hover, +h4 a:active { + color: inherit; + background-color: inherit; + text-decoration: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Up & Top helper images + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* arrow left */ +/* ====================== */ +div.up { + width: 30px; + height: 20px; + padding: 0; + margin: -20px 0 1px 0; + text-align: center; + vertical-align: top; +} + +div.up img { + vertical-align: top; + width: 11px; + height: 11px; + border-style: none; +} + +/* arrow up (to page top) */ +/* ====================== */ +div.top { + width: 30px; + padding: 0 0 0 30px; + margin: 0; +} + +div.top img { + margin-top: 0.5em; + vertical-align: bottom; + width: 11px; + height: 11px; + border-style: none; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Tables + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* general */ +/* ====================== */ +table { + border: 1px solid #aaa; + border-collapse: collapse; + padding: 2px; + margin-top: 0.5em; + margin-bottom: 0; +} + +td, th { + empty-cells: show; /* show border around empty cells */ + padding: 0.1em 0.2em; + vertical-align: top; + text-align: left; + line-height: 1.3em; +} + +th { + font-weight: bold; +} + +td.centered { + text-align: center; +} + +td.data { + font-family: monospace; + text-align: right; + padding-left: 1em; +} + +th.data { + text-align: right; +} + +tr.odd { /* for large tables alternating colors */ + background-color: #f2f2f2; +} + +tr.header, tr.header th { + background-color: #e2e2e2; + border-top: 1px solid #aaa; + border-bottom: 1px solid #aaa; +} + +/* bordered table cells */ +/* ====================== */ + +/* turn off borders in tables nested in + * bordered tables per default + */ +table.bordered table td, +table.bordered table th { + border-style: none; +} + +table.bordered td, +table.bordered th, +table table.bordered td, +table table.bordered th { + border: 1px solid #aaa; +} + +/* index page layout table */ +/* ======================= */ +body#index-page div#page-content { + width: 100%; /* IE fun */ +} + +body[id]#index-page div#page-content { + width: auto; /* reasonable browsers. */ +} + +table#indextable { + width: 100%; + border-collapse: collapse; + border: 0 none; +} + +table#indextable td { + width: 33.3%; + border-left: 1px solid #aaa; + padding-top: 0; + padding-bottom: 0; +} + +table#indextable td.col1 { + border-left: 0 none; + padding-left: 0; +} + +table#indextable td.col3 { + padding-right: 0; +} + +/* mod/dir. overview table and quick reference */ +/* ============================================ */ +table.module th, +table.directive th { + white-space: nowrap; +} + +table.qref { + border-collapse: collapse; + width: 100%; +} + +table.qref td { + border-style: none solid; + border-color: #aaa; + border-width: 1px; +} + +table.qref td.descr { + padding-left: 1em; + font-size: 13px; +} + +table#legend { + width: 100%; + border-style: none; + border-width: 0; + vertical-align: bottom; + padding: 0; + margin: 0; +} + +table#legend td { + vertical-align: bottom; + margin: 0; + padding: 0; +} + +table#legend td.letters { + width: 100%; + padding-bottom: 0.5em; +} + +table#legend table { + vertical-align: bottom; + margin: 0 0 0 0.4em; + padding: 0; + height: 7.5em; +} + +table#legend table td, +table#legend table th { + vertical-align: middle; + padding: 0.1ex 0.2em; + line-height: 1em; + white-space: nowrap; +} + +/* related modules & dir. */ +/* ====================== */ + +/* assuming, all links are enclosed by + * or + * + */ + +table.related { + border-collapse: separate; +} + +table.related th { + padding: 0.2ex 0.3em; + background-color: #e5ecf3; + color: #405871; + vertical-align: middle; +} + +table.related td { + padding: 0.2ex 0.3em; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Lists + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* list default values */ +/* ====================== */ +ul { + list-style-type: disc; +} + +ul ul { + list-style-type: square; +} + +ul ul ul { + list-style-type: circle; +} + +li, dt, dd { + line-height: 1.3em; +} + +dt { + margin-top: 0.5em; + font-weight: bold; +} + +ol li { + margin-top: 0.5em; +} + +ol.up-A { + list-style-type: upper-alpha; +} + +ol.lo-A { + list-style-type: lower-alpha; +} + +dd.separate { + margin-bottom: 2em; +} + +li.separate { + margin-bottom: 1em; +} + +/* table of contents */ +/* ====================== */ +#toc, +#topics { + margin: 0 0 1em 0; + padding: 0; +} + +#toc li, +#topics li { + list-style-type: none; + margin: 0; + padding: 0; +} + +/* see also */ +/* ====================== */ +.seealso { + margin: 0 0 1em 0; + padding: 0; +} + +.seealso li { + list-style-type: none; + margin: 0; + padding: 0 0 0 34px; +} + +/* related modules & dir. */ +/* ====================== */ +table.related td ul, +table.related td li { + list-style-type: none; + margin: 0; + padding: 0; +} + +/* list of all directives */ +/* ====================== */ +div#directive-list ul { + margin: 0; + padding: 0; +} + +/* indextable */ +/* ========== */ +table#indextable td ul { + list-style-type: none; + margin: 0 0 1em 0.5em; + padding: 0 0 0 0; +} + +table#indextable td ul li { + margin-top: 0.3em; +} + +/* sidebar */ +/* ====================== */ +div#quickview li { + font-size: 13px; +} + +div#quickview ul { + margin: 0 0 15px 0; + padding: 0; +} + +div#quickview ul#toc { + margin: 0 0 0 0.5em; + padding: 0; +} + +#module-index div#quickview ul#toc, +#manual-page div#quickview ul#toc { + margin-left: 0; +} + +div#quickview ul#toc li { + margin: 0; + padding: 0; + list-style-type: none; +} + +div#quickview li img { + display: none; +} + +#module-index div#quickview ul#toc, +#manual-page div#quickview ul#toc, +div#quickview #topics, +div#quickview .seealso { + padding-left: 15px; +} + +#module-index div#quickview ul#toc li, +#manual-page div#quickview ul#toc li, +div#quickview #topics li, +div#quickview .seealso li { + margin: 0.4em 0 2px 0; + padding: 0; + list-style-type: square; + list-style-position: outside; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * main page sections + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* page header */ +/* ====================== */ +div#page-header { + margin-left: 30px; +} + +div#page-header img { + padding: 0; + display: block; + margin: -70px 0 1px 2em; + width: 248px; + height: 70px; +} + +div#page-header p.apache { + background-color: #405871; + color: #fff; + padding: 0 0 0 248px; + margin: 0; + text-align: center; + vertical-align: middle; + font-size: 16px; + font-weight: bold; + line-height: 29px; +} + +div#page-header p.menu { + text-align: right; + font-size: 13px; + margin: 30px 0 0.5em 0; + padding: 0; +} + +/* breadcrumb navigation */ +div#path { + margin: 0.2em 0 1.2em 30px; + padding: 0; + font-size: 13px; +} + +/* content sections */ +/* ====================== */ +div#preamble { + padding-bottom: 1em; + margin-left: 30px; +} + +div.section, +div.directive-section { + margin: -1.2em 0 0 60px; + padding: 0; +} + +.section p, +.directive-section p { + margin: 0 0 1em 0; + padding: 0; +} + +/* look for this on directive + * list pages + */ +div#directive-list { + margin-left: 30px; + padding: 0 0 1em 1em; +} + +div#directive-ref { + margin: -1em 0 0 0; + padding: 0 0 1em 30px; + width: 100%; /* IE is BAD (broken as designed) */ +} + +div[id]#directive-ref { /* a big sorry to ICab, Amaya (and old Konquerors?) */ + width: auto; /* other browsers are fine ;-) */ +} + +/* sidebar position: right */ +div#quickview { + position: absolute; + top: 5.5em; + right: 1em; + margin-left: 0; + margin-top: 40px; + padding: 4px; + width: 13.5em; + background-color: #f0f0f0; + color: inherit; +} + +/* -> move content left */ +div#page-content { + padding-top: 0; + margin-right: 13em; + padding-right: 30px; +} + +/* unsqueeze on some pages... */ +body.no-sidebar div#page-content, +body#index-page div#page-content { + margin-right: 0; + padding-right: 0; +} + +body#index-page div#page-content { + margin-left: 30px; + padding-bottom: 1em; +} + +/* in general */ +p { + line-height: 1.3em; +} + +/* translations */ +/* ====================== */ +.toplang { + padding: 0; + margin: 0.2em 0.2em 1em 0; +} + +.bottomlang { + padding: 0; + margin: 0 0.2em 0.2em 0; +} + +.toplang p, +.bottomlang p { + font-size: 13px; + text-align: right; + background-color: inherit; + color: #ccc; + margin: 0; + padding: 0; +} + +.toplang p span, +.bottomlang p span { + background-color: inherit; + color: #036; +} + +.toplang p a:link, +.toplang p a:visited, +.bottomlang p a:link, +.bottomlang p a:visited { + text-decoration: none; + font-weight: bold; +} + +.toplang p a:hover, +.toplang p a:active, +.bottomlang p a:hover, +.bottomlang p a:active { + font-weight: bold; +} + +/* page footer */ +/* ====================== */ +div#footer { + margin-left: 30px; + font-size: 13px; + border-top: 1px solid #405871; + padding-top: 0.2em; +} + +div#footer p.apache { + float: left; + text-align: left; + padding: 0 0 1em 0; + margin-top: 0; +} + +div#footer p.menu { + float: right; + text-align: right; + margin-top: 0; + padding: 0 0 1em 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * subsections (examples, notes, warnings) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* examples */ +/* ====================== */ +div.example { + background-color: #e5ecf3; + color: #000; + padding: 0.5em; + margin: 1em 2em 1em 1em; +} + +/* example inside a note: + * blue in gray doesn't look good + * so simply draw a border around + * and keep it gray + */ +div.note div.example, +div.warning div.example { + border: 1px solid #aaa; + background-color: transparent; + color: inherit; + margin-right: 1em; +} + +/* example inside table */ +table div.example { + margin-right: 1em; +} + +/* the following [block] elements + * may appear inside example... + */ +div.example p, +div.example pre, +div.example table { + padding: 0; + margin: 0; +} + +div.example p { + line-height: 1em; +} + +div.example pre, +div.example p > code { + font-size: 13px; +} + +/* notes & warnings */ +/* ====================== */ +div.note, +div.warning { + background-color: #eee; + color: #036; + padding: 0.5em; + margin: 1em 2em 1em 1em; +} + +div.warning { + border: 1px solid #f00; +} + +div.note p, +div.warning p { + margin: 0.5em 0 0 0; + padding: 0; +} + +div.note pre, +div.warning pre { + font-size: 13px; +} + +/* inside table */ +table div.note, +table div.warning { + margin-right: 1em; +} + +div.outofdate { + background-color: #ffffe0; + color: #036; + padding: 0.5em; + margin: 1em 2em 1em 1em; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * quotations, indented paragraphs, forms and figures + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +p.letters { + margin: 1em 0 0 0; +} + +p.centered { + text-align: center; +} + +.letters { + text-align: center; + background-color: inherit; + color: #ccc; +} + +.letters a:link, +.letters a:visited { + text-decoration: none; + font-weight: bold; +} + +.letters a:hover, +.letters a:active { + font-weight: bold; +} + +blockquote p { + font-style: italic; + margin: 0; +} + +blockquote p.cite { + font-style: normal; + margin-top: 0; + margin-left: 2em; +} + +blockquote p.cite cite { + font-style: normal; +} + +p.indent { + margin-left: 2em; + margin-top: 1em; +} + +span.indent { + padding-left: 1.5em; + display: block; +} + +#index-page form { + text-align: center; +} + +#index-page form p { + line-height: 1.1em; +} + +#index-page form input { + font-size: 1em; +} + +p.figure { + margin-left: 2em; + font-style: italic; +} + +p.figure img { + border: 1px solid #aaa; +} + +p.figure dfn { + font-weight: bold; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * -> The End <- + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/trunk/docs/manual/style/description.xml b/trunk/docs/manual/style/description.xml new file mode 100644 index 0000000000..a02cc1f8d2 --- /dev/null +++ b/trunk/docs/manual/style/description.xml @@ -0,0 +1,47 @@ + + + + + +This build file contains all operations that are necessary for building +the Apache httpd documentation. It is called by invoking build.bat (Win32) +or build.sh (/bin/sh systems) with a target argument (full list below). +For example, if you want to build the Japanese HTML files, type: + + ./build.sh ja + +Some targets have additional requirements: + +* 'metafiles' and 'modulelists' need perl in PATH. (It's checked automatically + and skipped if perl is not available) + +* 'chm-foo' targets need: + - the HTML Help compiler in PATH (or modify this build file). The + compiler (hhc.exe) is part of the HTML Help Workshop which is freely + available and can be downloaded from + http://msdn.microsoft.com/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp + - The appropriate locale (e.g. Japanese) before invoking hhc.exe. Otherwise + the compiler is not able to build the fulltext search index correctly and + the TOC may be garbled, too. In particular: + + chm-de: German (Germany), sorting order: dictionary + + chm-en: English (USA) + + chm-es: Spanish (Spain), sorting order: international + + chm-ja: Japanese + + chm-ko: Korean + + \ No newline at end of file diff --git a/trunk/docs/manual/style/faq.dtd b/trunk/docs/manual/style/faq.dtd new file mode 100644 index 0000000000..0d99b1865b --- /dev/null +++ b/trunk/docs/manual/style/faq.dtd @@ -0,0 +1,35 @@ + + + + + +%common; + + + + + + + + + + + diff --git a/trunk/docs/manual/style/lang-targets.xml b/trunk/docs/manual/style/lang-targets.xml new file mode 100644 index 0000000000..d8a09c05ef --- /dev/null +++ b/trunk/docs/manual/style/lang-targets.xml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/lang/de.xml b/trunk/docs/manual/style/lang/de.xml new file mode 100644 index 0000000000..2a95ccad44 --- /dev/null +++ b/trunk/docs/manual/style/lang/de.xml @@ -0,0 +1,130 @@ + + ]> + + + + + + German + ISO-8859-1 + .xml.de + .html.de + + + 0x407 German (Germany) + ,8,0 + windows-1252 + German (Germany), sorting order: dictionary + + + + + + + Deutsch + + + Kernfunktionen und + Multi-Processing-Module + Andere Module + Veraltete Module + + + Veraltetes Apache-Modul + Apache-Modul + Apache-Kernfunktionen + Allgemeine Direktiven der Apache-MPMs + Apache-MPM + + + Beschreibung + Siehe auch + Themen + Status + Modulbezeichner + Quelltext-Datei + Kompatibilität + + + Referenzierte Module + Referenzierte Direktiven + + + Syntax + Voreinstellung + Kontext + AllowOverride + Status + Modul + + + Serverkonfiguration + Virtual Host + Verzeichnis + .htaccess + + + Direktiven + + Direktive + Dieses Modul enthält keine + Direktiven. + + + Zusammenfassung + + + Anm.d.Ü.: + + + siehe Glossar + + + - Apache HTTP Server + Apache HTTP Server Version + 2.1 + [APACHE DOCUMENTATION] + Google-Suche + Index + Startseite + + + Apache + HTTP-Server + Dokumentation + Version 2.1 + + + Module + FAQ + Glossar + Seitenindex + + + Lizenziert unter der + Verfügbare Sprachen + + + Diese Übersetzung ist möglicherweise + nicht mehr aktuell. Bitte prüfen Sie die englische Version auf + die neuesten Änderungen. + + diff --git a/trunk/docs/manual/style/lang/en.xml b/trunk/docs/manual/style/lang/en.xml new file mode 100644 index 0000000000..3bcd3769be --- /dev/null +++ b/trunk/docs/manual/style/lang/en.xml @@ -0,0 +1,129 @@ + + ]> + + + + + + English + ISO-8859-1 + .xml + .html.en + + + 0x409 English (United States) + ,8,0 + windows-1252 + English (USA) + + + + ISO-8859-1 + + + + + + + English + + + Core Features and Multi-Processing + Modules + Other Modules + Obsolete Modules + + + Obsolete Apache Module + Apache Module + Apache Core Features + Apache MPM Common Directives + Apache MPM + + + Description + See also + Topics + Status + Module Identifier + Source File + Compatibility + + + Related Modules + Related Directives + + + Syntax + Default + Context + Override + Status + Module + + + server config + virtual host + directory + .htaccess + + + Directives + + Directive + This module provides no + directives. + + + Summary + + + see glossary + + + - Apache HTTP Server + Apache HTTP Server Version 2.1 + [APACHE DOCUMENTATION] + Google Search + Index + Home + + + Apache + HTTP Server + Documentation + Version 2.1 + + + Modules + FAQ + Glossary + Sitemap + + + Licensed under the + Available Languages + + + This translation may be out of date. Check the + English version for recent changes. + + diff --git a/trunk/docs/manual/style/lang/es.xml b/trunk/docs/manual/style/lang/es.xml new file mode 100644 index 0000000000..b972403c86 --- /dev/null +++ b/trunk/docs/manual/style/lang/es.xml @@ -0,0 +1,130 @@ + + ]> + + + + + + Spanish + ISO-8859-1 + .xml.es + .html.es + + + 0xC0A Spanish (International) + ,8,0 + windows-1252 + Spanish (Spain), sorting order: international + + + + + + + Español + + + Funcionalidad Básica y Módulos + de MultiProcesamiento + Otros Módulos + Módulos Obsoletos + + + Módulos Obsoletos de + Apache + Módulo Apache + Funcionalidad Básica de Apache + Directivas Comunes de los MPM de + Apache + MPM de Apache + + + Descripción + Consulte también + Temas + Estado + Identificador de Módulos + Fichero de Código Fuente + Compatibilidad + + + Módulos Relacionados + Directivas Relacionadas + + + Sintaxis + Valor por defecto + Contexto + Prevalece sobre + Estado + Módulo + + + server config + virtual host + directory + .htaccess + + + Directivas + + Directiva + Este módulo no suministra ninguna + directiva. + + + Resumen de contenidos + + + ver glosario + + + - Servidor HTTP Apache + Versión 2.1 del Servidor HTTP + Apache + [APACHE DOCUMENTATION] + Buscar en Google + Índice + Página Inicial + + + Apache + Servidor HTTP + Documentación + Versión 2.1 + + + Módulos + Preguntas Frecuentes + Glosario + Mapa de este sitio web + + + Licencia bajo los términos de la + Idiomas disponibles + + + Esta traducción podría estar + obsoleta. Consulte la versión en inglés de la + documentación para comprobar si se han producido cambios + recientemente. + + diff --git a/trunk/docs/manual/style/lang/fr.xml b/trunk/docs/manual/style/lang/fr.xml new file mode 100644 index 0000000000..cb71ff5227 --- /dev/null +++ b/trunk/docs/manual/style/lang/fr.xml @@ -0,0 +1,130 @@ + + ]> + + + + + + French + ISO-8859-1 + .xml.fr + .html.fr + + + + + + + + + Français + + + Fonctionalités de Base et Modules Multi-Processus (MPM) + Autres Modules + Modules Désuets + + + Module Apache Désuet + Mudule Apache + Fonctionalités de Base Apache + Apache MPM: Directives Communes + Apache MPM + + + Description + Voir aussi + Sujets + Status + Identificateur de Module + Fichier Source + Compatibilité + + + Modules Apparentés + Directives Apparentées + + + Syntaxe + Defaut + Contexte + Annuler + Status + Module + + + configuration du serveur + serveur virtuel + répertoire + .htaccess + + + Directives + + Directive + Ce module ne fournit aucune directive. + + + Sommaire + + + see glossary + + + - Serveur Apache HTTP + Serveur Apache HTTP Version 2.1 + [DOCUMENTATION APACHE] + Recherche Google + Index + Accueil + + + Apache + Serveur HTTP + Documentation + Version 2.1 + + + Modules + FAQ + Glossaire + Plan du site + + + Authorisé sous + Langues Disponibles + + + Cette traduction peut être périmée. Verifiez la version + Anglaise pour les changements récents. + + diff --git a/trunk/docs/manual/style/lang/ja.xml b/trunk/docs/manual/style/lang/ja.xml new file mode 100644 index 0000000000..37ba31dd10 --- /dev/null +++ b/trunk/docs/manual/style/lang/ja.xml @@ -0,0 +1,126 @@ + + ]> + + + + + + Japanese + EUC-JP + .xml.ja + .html.ja.euc-jp + + + 0x411 Japanese + MS UI Gothic,10,128 + SHIFT_JIS + Japanese + + + + + + + Japanese + + + $B%3%"5!G=$H(B MPM + $BB>$N%b%8%e!<%k(B + $B5l<0$N%b%8%e!<%k(B + + + $B5l<0$N(B Apache Module + Apache $B%b%8%e!<%k(B + Apache $B%3%"5!G=(B + Apache MPM $B6&DL%G%#%l%/%F%#%V(B + Apache MPM + + + $B@bL@(B + $B;2>H(B + $B%H%T%C%/(B + $B%9%F!<%?%9(B + $B%b%8%e!<%k<1JL;R(B + $B%=!<%9%U%!%$%k(B + $B8_49@-(B + + + $B4XO"%b%8%e!<%k(B + $B4XO"%G%#%l%/%F%#%V(B + + + $B9=J8(B + $B%G%U%)%k%H(B + $B%3%s%F%-%9%H(B + $B>e=q$-(B + $B%9%F!<%?%9(B + $B%b%8%e!<%k(B + + + $B%5!<%P@_Dj%U%!%$%k(B + $B%P!<%A%c%k%[%9%H(B + $B%G%#%l%/%H%j(B + .htaccess + + + $B%G%#%l%/%F%#%V(B + + $B%G%#%l%/%F%#%V(B + $B$3$N%b%8%e!<%k$K%G%#%l%/%F%#%V$O$"$j$^$;$s!#(B + + + $B35MW(B + + + $BLuCm(B: + + + $BMQ8l=8$r;2>H(B + + + - Apache HTTP $B%5!<%P(B + Apache HTTP $B%5!<%P(B $B%P!<%8%g%s(B 2.1 + [APACHE DOCUMENTATION] + Google Search + $B:w0z(B + $B%[!<%`(B + + + Apache + HTTP $B%5!<%P(B + $B%I%-%e%a%s%F!<%7%g%s(B + $B%P!<%8%g%s(B 2.1 + + + $B%b%8%e!<%k(B + FAQ + $BMQ8l(B + $B%5%$%H%^%C%W(B + + + Licensed under the + Available Languages + + + This translation may be out of date. Check the + English version for recent changes. + + diff --git a/trunk/docs/manual/style/lang/ko.xml b/trunk/docs/manual/style/lang/ko.xml new file mode 100644 index 0000000000..5bbd0295af --- /dev/null +++ b/trunk/docs/manual/style/lang/ko.xml @@ -0,0 +1,132 @@ + + ]> + + + + + + Korean + EUC-KR + .xml.ko + .html.ko.euc-kr + + + 0x412 Korean + Gulim,9,129 + EUC-KR + Korean + + + + + + + + + Korean + + + ÇÙ½É ±â´É°ú ´ÙÁßó¸® ¸ðµâ + ´Ù¸¥ ¸ðµâ + ÀÌÀü ¸ðµâ + + + ÀÌÀü ¾ÆÆÄÄ¡ ¸ðµâ + ¾ÆÆÄÄ¡ ¸ðµâ + ¾ÆÆÄÄ¡ ÇÙ½É ±â´É + ¾ÆÆÄÄ¡ MPM °øÅë Áö½Ã¾î + ¾ÆÆÄÄ¡ MPM + + + ¼³¸í + Âü°í + ÁÖÁ¦ + »óÅ + ¸ðµâ¸í + ¼Ò½ºÆÄÀÏ + Áö¿ø + + + °ü·ÃµÈ ¸ðµâ + °ü·ÃµÈ Áö½Ã¾î + + + ¹®¹ý + ±âº»°ª + »ç¿ëÀå¼Ò + Override ¿É¼Ç + »óÅ + ¸ðµâ + + + ÁÖ¼­¹ö¼³Á¤ + °¡»óÈ£½ºÆ® + directory + .htaccess + + + Áö½Ã¾îµé + + Áö½Ã¾î + ÀÌ ¸ðµâ¿¡´Â Áö½Ã¾î°¡ ¾ø½À´Ï´Ù. + + + ¿ä¾à + + + see glossary + + + ¿ªÁÖ; + + + - Apache HTTP Server + Apache HTTP Server Version 2.1 + [APACHE DOCUMENTATION] + Google °Ë»ö + Index + Home + + + Apache + HTTP Server + Documentation + Version 2.1 + + + ¸ðµâ + FAQ + ¿ë¾î + »çÀÌÆ®¸Ê + + + Licensed under the + °¡´ÉÇÑ ¾ð¾î + + + ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä. + + diff --git a/trunk/docs/manual/style/lang/pt-br.xml b/trunk/docs/manual/style/lang/pt-br.xml new file mode 100644 index 0000000000..904417b03c --- /dev/null +++ b/trunk/docs/manual/style/lang/pt-br.xml @@ -0,0 +1,131 @@ + + ]> + + + + + + Portuguese + ISO-8859-1 + .xml.pt-br + .html.pt-br + + + + + + + + + + Português (Brasil) + + + Funcionalidades Principais e Módulos de Multi-Processos (MPM) + Outros Módulos + Módulos Obsoletos + + + Módulo Obsoleto Apache + Módulo Apache + Funcionalidades Principais Apache + Diretrizes Comuns Apache MPM + Apache MPM + + + Descrição + Veja também + Tópicos + Status + Identificador do Módulo + Arquivo Fonte + Compatibilidade + + + Módulos Relacionados + Diretrizes Relacionadas + + + Sintaxe + Padrão + Contexto + Sobrescreve + Status + Módulo + + + configuração do servidor + hospedeiro virtual + diretório + .htaccess + + + Diretrizes + + Diretrizes + Esse módulo não fornece nenhuma diretriz. + + + Sumário + + + ver glossário + + + - Servidor HTTP Apache + Servidor HTTP Apache Versão 2.1 + [DOCUMENTAÇÃO APACHE] + Busca Google + Índice + Início + + + Apache + Servidor HTTP + Documentação + Versão 2.1 + + + Módulos + FAQ + Glossário + Mapa do site + + + Licenciado sob a + Línguas Disponíveis + + + Esta tradução pode estar desatualizada. + Verifique a versão em Inglês para mudanças recentes. + + diff --git a/trunk/docs/manual/style/lang/ru.xml b/trunk/docs/manual/style/lang/ru.xml new file mode 100644 index 0000000000..1ed52c23df --- /dev/null +++ b/trunk/docs/manual/style/lang/ru.xml @@ -0,0 +1,116 @@ + + ]> + + + + + + Russian + KOI8-R + .xml.ru + .html.ru.koi8-r + + + + + + + + Russian + + + ïÓÏÂÅÎÎÏÓÔÉ ÑÄÒÁ É ÍÕÌØÔÉ-ÐÒÏÃÅÓÓÎÙÅ + ÍÏÄÕÌÉ + äÒÕÇÉÅ ÍÏÄÕÌÉ + + + íÏÄÕÌØ Apache + ïÓÏÂÅÎÎÏÓÔÉ ÑÄÒÁ Apache + ïÂÝÉÅ ÄÌÑ ×ÓÅÈ íð-ÍÏÄÕÌÅÊ ÄÉÒÅËÔÉ×Ù + Apache + íÕÌØÔÉ-ÐÒÏÃÅÓÓÎÙÅ ÍÏÄÕÌÉ Apache + + + ïÐÉÓÁÎÉÅ + óÍ. ÔÁËÖÅ + ôÅÍÙ + óÔÁÔÕÓ + éÄÅÎÔÉÆÉËÁÔÏÒ ÍÏÄÕÌÑ + éÓÈÏÄÎÙÊ ËÏÄ + óÏ×ÍÅÓÔÉÍÏÓÔØ + + + óÍÏÔÒÉÔÅ ÔÁËÖÅ ÍÏÄÕÌÉ + óÍÏÔÒÉÔÅ ÔÁËÖÅ ÄÉÒÅËÔÉ×Ù + + + óÉÎÔÁËÓÉÓ + úÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ + ëÏÎÔÅËÓÔ + òÁÚÒÅÛÅÎÉÅ + óÔÁÔÕÓ + íÏÄÕÌØ + + + äÉÒÅËÔÉ×Ù + äÉÒÅËÔÉ×Á + üÔÏÔ ÍÏÄÕÌØ ÎÅ ÐÒÅÄÏÓÔÁ×ÌÑÅÔ ÎÉËÁËÉÈ + ÄÉÒÅËÔÉ×. + + + òÅÚÀÍÅ + + + see glossary + + + - HTTP ÓÅÒ×ÅÒ Apache + HTTP ÓÅÒ×ÅÒ Apache ÷ÅÒÓÉÑ 2.1 + [äïëõíåîôáãéñ APACHE] + Google Search + ïÇÌÁ×ÌÅÎÉÅ + îÁ ÇÌÁ×ÎÕÀ ÓÔÒÁÎÉÃÕ + + + Apache + HTTP ÓÅÒ×ÅÒ + äÏËÕÍÅÎÔÁÃÉÑ + ÷ÅÒÓÉÑ 2.1 + + + íÏÄÕÌÉ + FAQ + çÌÏÓÓÁÒÉÊ + ëÁÒÔÁ ÓÁÊÔÁ + + + Licensed under the + Available Languages + + + This translation may be out of date. Check the + English version for recent changes. + + diff --git a/trunk/docs/manual/style/latex/atbeginend.sty b/trunk/docs/manual/style/latex/atbeginend.sty new file mode 100644 index 0000000000..2a0facf7b7 --- /dev/null +++ b/trunk/docs/manual/style/latex/atbeginend.sty @@ -0,0 +1,80 @@ +% atbeginend.sty +% +% Copyright 2003-2005 The Apache Software Foundation or its licensors, +% as applicable. +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. + +% defines +% \BeforeBegin{environment}{code-to-execute} +% \BeforeEnd {environment}{code-to-execute} +% \AfterBegin {environment}{code-to-execute} +% \AfterEnd {environment}{code-to-execute} +% +% Save \begin and \end to \BeginEnvironment and \EndEnvironment +\let\BeginEnvironment=\begin +\let\EndEnvironment=\end + +\def\IfUnDef#1{\expandafter\ifx\csname#1\endcsname\relax} + +% Null command needed to for \nothing{something}=.nothing. +\def\NullCom#1{} + +\def\begin#1{% +% +% if defined \BeforeBeg for this environment, execute it +\IfUnDef{BeforeBeg#1}\else\csname BeforeBeg#1\endcsname\fi% +% +% +% +\IfUnDef{AfterBeg#1}% This is done to skip the command for environments + % which can take arguments, like multicols; YOU MUST NOT + % USE \AfterBegin{...}{...} for such environments! + \let\SaveBegEng=\BeginEnvironment% +\else% + % Start this environment + \BeginEnvironment{#1}% + % and execute code after \begin{environment} + \csname AfterBeg#1\endcsname% + % + \let\SaveBegEng=\NullCom% +\fi% +\SaveBegEng{#1}% +} + + +\def\end#1{% +% +% execute code before \end{environment} +\IfUnDef{BeforeEnd#1}\else\csname BeforeEnd#1\endcsname\fi% +% +% close this environment +\EndEnvironment{#1}% +% +% and execute code after \begin{environment} +\IfUnDef{AfterEnd#1}\else\csname AfterEnd#1\endcsname\fi% +} + + +%% Now, define commands +% \BeforeBegin{environment}{code-to-execute} +% \BeforeEnd {environment}{code-to-execute} +% \AfterBegin {environment}{code-to-execute} +% \AfterEnd {environment}{code-to-execute} + +\def\BeforeBegin#1#2{\expandafter\gdef\csname BeforeBeg#1\endcsname +{#2}} +\def\BeforeEnd #1#2{\expandafter\gdef\csname BeforeEnd#1\endcsname +{#2}} +\def\AfterBegin #1#2{\expandafter\gdef\csname AfterBeg#1\endcsname {#2}} +\def\AfterEnd #1#2{\expandafter\gdef\csname AfterEnd#1\endcsname{#2}} diff --git a/trunk/docs/manual/style/latex/common.xsl b/trunk/docs/manual/style/latex/common.xsl new file mode 100644 index 0000000000..3a18352705 --- /dev/null +++ b/trunk/docs/manual/style/latex/common.xsl @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + +\subsection*{ + +} + + + + + +\subsubsection*{ + +} + + + + + +\subsubsection*{ + +} + + + + + + + + + + +\label{ +: + +} + + + + + + + + + +\par\smallskip\begin{center} +\fbox{ +\begin{minipage}{.8\textwidth}\begin{flushleft} + +{\ttfamily\small +\noindent +} +\end{flushleft}\end{minipage} +} +\end{center}\par\smallskip + + + +\textbf{ + +}\\ + + + + + + + +\begin{list}{}{\topsep 0pt\rightmargin 0pt\leftmargin 2em} +\item[] + +\end{list} + + + + + + +\par\smallskip +{\Huge + + + \fbox{!} + + + $\Longrightarrow$ + + +}\begin{minipage}[t]{.8\textwidth} +\noindent + + +\end{minipage}\par\smallskip + + + +\textbf{ + +} \\ +\noindent + + + + + + + + + +\textsc{ + \textless{} + \hyperlink{/mod/ + + : + + }{ + + } + \textgreater{} +} + + + + + + + + +\textsc{\hyperlink{/mod/ + + }{ + + } +} + + + + + + + + + + +\fbox{\begin{tabular}{rr} +\begin{minipage}[t]{.49\linewidth} +\textbf{ + +} \\ + + + + \\ + + + +\end{minipage} & +\begin{minipage}[t]{.4\linewidth} +\textbf{ + +} \\ + + + + \\ + + + +\end{minipage} +\end{tabular}} +\smallskip + + + + + + + + + + \textbf{ + + }\begin{itemize} + + \item + + + + +\end{itemize} + + + + + + + + + +\section{ +} +\label{ +} + + + + + diff --git a/trunk/docs/manual/style/latex/directiveindex.xsl b/trunk/docs/manual/style/latex/directiveindex.xsl new file mode 100644 index 0000000000..0ed5eb5744 --- /dev/null +++ b/trunk/docs/manual/style/latex/directiveindex.xsl @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + \begin{itemize} + + + + + +\item + + (p.\ \pageref{/mod/ + : + + }) + + + \end{itemize} + + + + + diff --git a/trunk/docs/manual/style/latex/faq.xsl b/trunk/docs/manual/style/latex/faq.xsl new file mode 100644 index 0000000000..9271da4fea --- /dev/null +++ b/trunk/docs/manual/style/latex/faq.xsl @@ -0,0 +1,43 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/latex/html.xsl b/trunk/docs/manual/style/latex/html.xsl new file mode 100644 index 0000000000..a8a5eb8a4b --- /dev/null +++ b/trunk/docs/manual/style/latex/html.xsl @@ -0,0 +1,323 @@ + + + + + + + + + + + + +\begin{itemize} + + +\end{itemize} + + + + +\begin{enumerate} + + +\end{enumerate} + + + + +\item + + + + + + +\begin{description} + + +\end{description} + + + + +\item[ +] + + + + + + + + + + +\smallskip + + + + + \smallskip + + + + + \\ + + + + + + + + \\ + + + + + + + +\par + + + + +\texttt{ + +} + + + +\textbf{ + +} + + + +\textit{ + +} + + + + +\begin{verbatim} + + +\end{verbatim} + + + + +\begin{quotation} + + +\end{quotation} + + + + + + + + + longtable + tabular + + + +\begin{ +}{| + + + + l + + | + + + + + + l + + | + + + + +|}\hline + + +\hline\end{ + +} + + + + + + \\ + + \hline + + + + + + + + \begin{minipage}[t]{ + + + + + + + + + \textwidth}\small + + \end{minipage} + + & + + + + + + \begin{minipage}[t]{ + + + + + + + + + \textwidth}\bfseries + + \end{minipage} + + & + + + + + + + + + + + + + + + + + + + + + + + + \footnote{ + \href{ + + + + + + }{ + + + + }} + + + + + + + (p.\ \pageref{ + + + + + + + + + + + + + + + + + + + + + + }) + + + + + + + +\includegraphics{ + + + + + +} + + + diff --git a/trunk/docs/manual/style/latex/latex.xsl b/trunk/docs/manual/style/latex/latex.xsl new file mode 100644 index 0000000000..59002e2c27 --- /dev/null +++ b/trunk/docs/manual/style/latex/latex.xsl @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + +\documentclass[10pt]{book} +\usepackage{times} +\usepackage{longtable} +\usepackage{style/latex/atbeginend} +\usepackage[pdftex]{graphicx} +\usepackage[colorlinks=true,letterpaper=true,linkcolor=blue,urlcolor=blue]{hyperref} + +% Let LaTeX be lenient about very-bad line wrapping. +\tolerance=9999 +\emergencystretch=60pt + +% Adjust margins to a reasonable level +\topmargin 0pt +\advance \topmargin by -\headheight +\advance \topmargin by -\headsep +\textheight 8.9in +\oddsidemargin 0pt +\evensidemargin \oddsidemargin +\marginparwidth 0.5in +\textwidth 6.5in + +% Keep paragraphs flush left (rather than the default of indenting +% the first line) and put a space between paragraphs. +\setlength{\parindent}{0ex} +\addtolength{\parskip}{1.2ex} + +% Shrink the inter-item spaces +\AfterBegin{itemize}{\setlength{\itemsep}{0em}} + +\pagestyle{headings} + +\hypersetup{ + pdftitle={ + + + + + + + +}, + pdfauthor={Apache Software Foundation} + } + +\title{ + + + + + + + +\\ \bigskip \bigskip +\includegraphics{images/feather}\\ \bigskip} +\author{Apache Software Foundation} +\date{\today} + +\begin{document} +\frontmatter +\maketitle + +\section*{About The PDF Documentation} + +Copyright \copyright 2004 The Apache Software Foundation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at \href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} + +This version of the Apache HTTP Server Documentation is converted from +XML source files to \LaTeX\ using XSLT with the help of Apache Ant, +Apache XML Xalan, and Apache XML Xerces. + +Since the HTML version of the documentation is more commonly checked +during development, the PDF version may contain some errors and +inconsistencies, especially in formatting. If you have difficulty +reading a part of this file, please consult the HTML version +of the documentation on the Apache HTTP Server website at +\href{http://httpd.apache.org/docs-2.0/}{http://httpd.apache.org/docs-2.0/} + +The Apache HTTP Server Documentation is maintained by the Apache HTTP +Server Documentation Project. More information is available at +\href{http://httpd.apache.org/docs-project/}{http://httpd.apache.org/docs-project/} + +\tableofcontents +\mainmatter + + + + \chapter{ + + } + + + + +\end{document} + + + +\include{ + + + + + + + + +} + + + + + + + + + + + + + + +\include{mod/ + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/latex/manualpage.xsl b/trunk/docs/manual/style/latex/manualpage.xsl new file mode 100644 index 0000000000..ddf912c569 --- /dev/null +++ b/trunk/docs/manual/style/latex/manualpage.xsl @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/latex/moduleindex.xsl b/trunk/docs/manual/style/latex/moduleindex.xsl new file mode 100644 index 0000000000..54714f1865 --- /dev/null +++ b/trunk/docs/manual/style/latex/moduleindex.xsl @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + \subsection*{ + + } + +\begin{description} +\item[ + + ] (p.\ \pageref{/mod/ + + }) + + + + +\item[ + + + ] (p.\ \pageref{/mod/ + + }) + + + + + + + + + + + + + + + + +\item[ + + ] (p.\ \pageref{/mod/ + + }) + + + + + + \end{description} + + + + + + \section*{ + + } +\begin{description} + + + + + + + + + \end{description} + + + + + + + + + + + + + + + + + + + + + + +\item[ + +] (p.\ \pageref{/mod/ + +}) + + + + + + + + + + + + + + + + + + + + + + + +- + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/latex/quickreference.xsl b/trunk/docs/manual/style/latex/quickreference.xsl new file mode 100644 index 0000000000..16017a0676 --- /dev/null +++ b/trunk/docs/manual/style/latex/quickreference.xsl @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + \footnotesize + + + \begin{longtable}{p{.60\textwidth}p{.25\textwidth}ll}\hline + + + + + + \texttt{ + + } + & + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & + + s + v + d + h + + & + + B + M + C + E + X + + + \\* + + + \multicolumn{4}{l}{\begin{minipage}[t]{.95\textwidth} + + + + + + - + + + + \hfill p.\ \pageref{/mod/ + : + + } + + + \end{minipage}} \\ \hline + + + + + \end{longtable} +\normalsize + + + + + + + + diff --git a/trunk/docs/manual/style/latex/synopsis.xsl b/trunk/docs/manual/style/latex/synopsis.xsl new file mode 100644 index 0000000000..cae6785a32 --- /dev/null +++ b/trunk/docs/manual/style/latex/synopsis.xsl @@ -0,0 +1,346 @@ + + + + + + + + + + + + + +\section{ + + + + + + + + + + + + + + + + + + +}\label{ + +}\hypertarget{ + +}{} + + +\begin{tabular}{lp{.75\linewidth}} +\hline + + +: & + +\\ + + + +: & + +\\ + + + + +: & + +\\ + + + + + +: & + +\\ + + + + + +: & + + \\ + + +\hline \end{tabular} + + + + + \subsection*{ + + } + + + + + +\smallskip\textbf{ + + } + + + + + \begin{itemize} + + + \item + + \textless{} + + + + \textgreater{} + + + + (p.\ \pageref{/mod/ + + }) + + + + + \end{itemize} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +\textless{} + +\textgreater{} + + + +\subsection*{ + + + + + + + + + + + +}\label{ + +}\hypertarget{ + +}{} + + + + + + + + +\begin{tabular}{lp{.8\linewidth}} +\hline + + +: & + +\\ + + + +: & {\ttfamily + +}\\ + + + + +: & {\ttfamily + +} \\ + + + + +: & + + \\ + + + + +: & + + \\ + + + + +: & + + \\ + + + +: & + + + + + + + + + \\ + + + + +: & + + \\ + + + +\hline +\end{tabular} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + unknown context: + + + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/manual.de.xsl b/trunk/docs/manual/style/manual.de.xsl new file mode 100644 index 0000000000..2e932500af --- /dev/null +++ b/trunk/docs/manual/style/manual.de.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +de + + + +ISO-8859-1 + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.en.xsl b/trunk/docs/manual/style/manual.en.xsl new file mode 100644 index 0000000000..25bfc1e020 --- /dev/null +++ b/trunk/docs/manual/style/manual.en.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +en + + + +ISO-8859-1 + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.es.xsl b/trunk/docs/manual/style/manual.es.xsl new file mode 100644 index 0000000000..abd3deb341 --- /dev/null +++ b/trunk/docs/manual/style/manual.es.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +es + + + +ISO-8859-1 + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.fr.xsl b/trunk/docs/manual/style/manual.fr.xsl new file mode 100644 index 0000000000..1a7e2b94e5 --- /dev/null +++ b/trunk/docs/manual/style/manual.fr.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +fr + + + +ISO-8859-1 + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.ja.xsl b/trunk/docs/manual/style/manual.ja.xsl new file mode 100644 index 0000000000..bc38303c9c --- /dev/null +++ b/trunk/docs/manual/style/manual.ja.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +ja + + + +EUC-JP + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.ko.xsl b/trunk/docs/manual/style/manual.ko.xsl new file mode 100644 index 0000000000..06c12ed4d7 --- /dev/null +++ b/trunk/docs/manual/style/manual.ko.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +ko + + + +EUC-KR + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.pt-br.xsl b/trunk/docs/manual/style/manual.pt-br.xsl new file mode 100644 index 0000000000..41457227a1 --- /dev/null +++ b/trunk/docs/manual/style/manual.pt-br.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +pt-br + + + +ISO-8859-1 + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manual.ru.xsl b/trunk/docs/manual/style/manual.ru.xsl new file mode 100644 index 0000000000..f55f8ba420 --- /dev/null +++ b/trunk/docs/manual/style/manual.ru.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + +ru + + + +KOI8-R + + + + + + + \ No newline at end of file diff --git a/trunk/docs/manual/style/manualpage.dtd b/trunk/docs/manual/style/manualpage.dtd new file mode 100644 index 0000000000..2b292c78ca --- /dev/null +++ b/trunk/docs/manual/style/manualpage.dtd @@ -0,0 +1,27 @@ + + + + + +%common; + + + + + diff --git a/trunk/docs/manual/style/modulesynopsis.dtd b/trunk/docs/manual/style/modulesynopsis.dtd new file mode 100644 index 0000000000..489ab2b829 --- /dev/null +++ b/trunk/docs/manual/style/modulesynopsis.dtd @@ -0,0 +1,76 @@ + + + + + +%sitemap; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/sitemap.dtd b/trunk/docs/manual/style/sitemap.dtd new file mode 100644 index 0000000000..72fb2ee691 --- /dev/null +++ b/trunk/docs/manual/style/sitemap.dtd @@ -0,0 +1,38 @@ + + + + + +%common; + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/common.xsl b/trunk/docs/manual/style/xsl/common.xsl new file mode 100644 index 0000000000..55d4bafa2c --- /dev/null +++ b/trunk/docs/manual/style/xsl/common.xsl @@ -0,0 +1,1148 @@ + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + p example note table ul ol dl pre img blockquote + + + + + + + + + + + + + + + + + + + + + + + + + + + index.html + + + + + + + + + + + + + + + + + + + + + + &lf; + + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + &lf; + + This file is generated from xml source: + DO NOT EDIT + &lf; + + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + &lf; + + + + &lf; + + + <xsl:choose> + <xsl:when test="name"> + <xsl:value-of select="name"/> + </xsl:when> + + <xsl:otherwise> + <xsl:value-of select="title"/> + </xsl:otherwise> + </xsl:choose> + + <xsl:text> </xsl:text> + <xsl:value-of select="normalize-space($message[@id='apachetitle'])"/> + &lf; + + + + + + + + + &lf; + + + + &lf; + + + &lf; + + + + + &lf; + + + + + + + + + + + +&lf; + +&lf; + +
    &lf; + + + _blank + + + + + > + + + + _blank + + + + + > + + + + _blank + + + + + + > + + + + + + + + > + + + + + + + + > + + + + + + + + +
    + + + + + + + + + + &lf; +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    &lf; +

    + + + : + + + + + + + + + + + + + + + + alternate + + + + + +   + +   + + + | + + +

    &lf; +
    +
    + + + + + +
    + + + + + + + +&lf; +
    &lf; + + +

    + + + + + + + + + + + +

    + + + +
    +
    + + + + + + + + +

    + + + + + + + + + + + +

    + + + +
    + + + + + + + + +

    + + + + + + + + + + + +

    + + + + +
    + + + + + + + + + FATAL: exceeding maximum section nesting level. + &lf;&lf; + Perhaps you should consider to split your document into + &lf; + several ones... + &lf; + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + + + +
  • &lf; +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + +

    +
    + + +
    +
    + +
    +
    + + + + + + + +

    + +

    +
    + + + + + + + + + + + + + + + + + + + +
    + + warning + + + +
    +
    + + + + + + + +

    + +

    +
    + + + + + + + + + + + + + + + + + + < + + > + + + + + < + + > + + + + + + + < + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + +
  • +
    +
    + + + + + + + + +
  • + +
  • +
    +
    + + + + + + + + + + + bordered + + + + + + + + + + + + + +
    +
    + + + + + + + +
  • + + + +
    + + + + + +
    + + + + + +
    + &lf; + + &lf; + + + + + + + + + + +
  • + + separate + + + + + + + + + + + + + + + + +
  • &lf; +
    + + + + + + + +
    + +

    + + + + + + + + + +

    &lf; + + +
      + +
    &lf; +
    +
    + + + + + + + + +get +http://www.google.com/search + + _blank + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +
    + + + diff --git a/trunk/docs/manual/style/xsl/language.xsl b/trunk/docs/manual/style/xsl/language.xsl new file mode 100644 index 0000000000..6c25bd2a08 --- /dev/null +++ b/trunk/docs/manual/style/xsl/language.xsl @@ -0,0 +1,658 @@ + + + + + + +]> + + + + + + + + + + + + + + + + + &lf; + + + + + &lf; + + + + + + + + + + + + + + + + + + + + &lf; + + + + + + + + + + + + + + + + + &lf; + + + + + + &lf; + + + &lf; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &lf;&lf; + + + + + + + + , + + + + &lf; + + + + + zip- + + , + + + + &lf; + + + + + war- + + , + + + + &lf; + + + + + + + + + &lf; + + + + + + &lf; + &lf;&lf; + + + &lf; + + &lf; + + + &lf; + + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + &lf; + + + &lf; + + &lf; + + &lf; + + + + &lf; + + &lf; + + &lf; + + + + &lf; + + &lf; + + &lf; + + + + &lf; + + + + + + + + + + + + + + + + &lf; + + + &lf; + + &lf; + + &lf; + + + + + + + &lf; + + + &lf; + + &lf; + + &lf; + + + &lf; + + + &lf; + + &lf;&lf; + + + + + + + + + + + &lf; + + + + + + ../../../mod/allmodules + + + &lf; + + + + + + + + + + + + + +This build file contains all operations that are necessary for building +the Apache httpd documentation. It is called by invoking build.bat (Win32) +or build.sh (/bin/sh systems) with a target argument (full list below). +For example, if you want to build the Japanese HTML files, type: + + ./build.sh ja + +Some targets have additional requirements: + +* 'metafiles' and 'modulelists' need perl in PATH. (It's checked automatically + and skipped if perl is not available) + +* 'chm-foo' targets need: + - the HTML Help compiler in PATH (or modify this build file). The + compiler (hhc.exe) is part of the HTML Help Workshop which is freely + available and can be downloaded from + http://msdn.microsoft.com/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp + - The appropriate locale (e.g. Japanese) before invoking hhc.exe. Otherwise + the compiler is not able to build the fulltext search index correctly and + the TOC may be garbled, too. In particular: + + + + + + + + + + chm- + + : + + &lf; + + + &lf; + + + + + + + + + + + + + + 1.0 + &lf; + &lf; + + + + + + xml + + + text + + + + Unknown style type ' + + '! + + + + + + + + + + + + + + + + + + no + + + -//W3C//DTD XHTML 1.0 Strict//EN + + + + + http://www.w3.org/TR/xhtml1/DTD/ + xhtml1-strict.dtd + + + + yes + + + &lf;&lf; + + + Read the localized messages from the specified + language file + + &lf; + + + message + + document(' + ../ + lang/ + + .xml')/language/messages/message + + + &lf; + + + + doclang + + + &lf; + + allmodules + + document(' + ../ + xsl/util/allmodules.xml') + /items/item[@lang=$doclang] + + + &lf; + + &lf; + + + + some meta information have to be passed to + the transformation + + &lf; + + + + + output-encoding + + + + + + + + + + &lf; + + + + + is-chm + + + + true() + + + false() + + + + + &lf; + + + is-zip + + + + true() + + + false() + + + + + &lf;&lf; + + + + + toc-font + + + &lf; + + + xml-ext + + + &lf;&lf; + + + + + hhp-lang + + + &lf;&lf; + + + Now get the real guts of the stylesheet + &lf; + + + + + + ../xsl/common.xsl + + + ../xsl/hhc.xsl + + + ../xsl/hhp.xsl + + + ../xsl/nroff.xsl + + + xsl/common.xsl + + + + + &lf;&lf; + + + + + + + +&lf; + + Copyright 2002-2005 The Apache Software Foundation or its licensors, + as applicable. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +&lf;&lf; + + + + +============================================ +======================== + + + + + + + + + +&lf; + + + + + + + + + + + + + +&lf; + + + diff --git a/trunk/docs/manual/style/xsl/maf.xsl b/trunk/docs/manual/style/xsl/maf.xsl new file mode 100644 index 0000000000..2f308b389b --- /dev/null +++ b/trunk/docs/manual/style/xsl/maf.xsl @@ -0,0 +1,56 @@ + + + + + +]> + + + + + + + + + + + + + +&lf; + &lf; + &lf; + &lf; + + &lf; + + &lf; + &lf; +&lf; + + + + diff --git a/trunk/docs/manual/style/xsl/manualpage.xsl b/trunk/docs/manual/style/xsl/manualpage.xsl new file mode 100644 index 0000000000..d2e0fdff8f --- /dev/null +++ b/trunk/docs/manual/style/xsl/manualpage.xsl @@ -0,0 +1,87 @@ + + + + + +]> + + + + + + + + + &lf; + + + + + no-sidebar + + + + +
    +
    +

    + +

    &lf; + + &lf; + + +
    &lf; + + +
    + +
      + +
    +
    + + +

    + +

    +
      + +
    • + +
    • +
      +
    +
    +
    &lf; +
    + + +
    &lf; + + &lf; + + +
    + + +
    diff --git a/trunk/docs/manual/style/xsl/moduleindex.xsl b/trunk/docs/manual/style/xsl/moduleindex.xsl new file mode 100644 index 0000000000..6c413794c0 --- /dev/null +++ b/trunk/docs/manual/style/xsl/moduleindex.xsl @@ -0,0 +1,333 @@ + + + + + +]> + + + + + + + + + &lf; + + + + +
    +
    +

    + +

    &lf; + + &lf; + + +
    &lf; + + +
    + + + + + +

    + +

    &lf; + +
      &lf; + +
    • + +
    • &lf; +
      +
    +
    +
    +
    &lf; + + &lf; + +
    +

    + + + +

    &lf; + + +
    &lf; +
    + + + +
    +
    + +
    &lf; + + +
    + + + +
    +
    + +
    &lf; + + + + + + + + + + + + +
    + + + +
    +
    + +
    &lf; +
    +
    +
    &lf; + + &lf; + +
    +

    + + + +

    &lf; + + + + + + + + + +

    + + + + +

    &lf; + +
    + + + + +
    +
    +
    &lf; + + &lf; + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + +
    +
    + +
    &lf; +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- + + + + + + + + + + - + + + + +
    diff --git a/trunk/docs/manual/style/xsl/nroff.xsl b/trunk/docs/manual/style/xsl/nroff.xsl new file mode 100644 index 0000000000..47d4680211 --- /dev/null +++ b/trunk/docs/manual/style/xsl/nroff.xsl @@ -0,0 +1,448 @@ + + + + + + + +]> + + + + + + + + + + + + + + + + + + +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&lf; +.\" DO NOT EDIT! Generated from XML source.&lf; +.\" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&lf; +.de Sh \" Subsection&lf; +.br&lf; +.if t .Sp&lf; +.ne 5&lf; +.PP&lf; +\fB\\$1\fR&lf; +.PP&lf; +..&lf; +.de Sp \" Vertical space (when we can't use .PP)&lf; +.if t .sp .5v&lf; +.if n .sp&lf; +..&lf; +.de Ip \" List item&lf; +.br&lf; +.ie \\n(.$>=3 .ne \\$3&lf; +.el .ne 3&lf; +.IP "\\$1" \\$2&lf; +..&lf; + + +.TH " + + +" + + + + " + + + +" " + + + +" " + + + +"&lf; + + +&lf; +&lf; +&lf; +&lf; + + + + + + + + + +&lf; +.SH NAME&lf; + + + + + + + \- + + + + + + + + + + +&lf; +.PP&lf; + + + + + + + + + + + + + + + + + + + + + + +&lf; + + + + + + + + + +&lf; +.SH " + + + +"&lf; + + + + + + + + + + + +&lf; +.SS " + + + +"&lf; + + + + + + + + + + +&lf; +.SH " + + + +"&lf; + + + + + + + + + + +\fI + +\fR + + + + + + + + +\fB + +\fR + + + + + + + +< + +> + + + + + + + +&lf; +&lf; + + + + + + + +&lf; +.TP&lf; + + + + +&lf; + + + + + + + + + + + + + + + + + +&lf; +.nf&lf; +&lf; +.fi&lf; + + + + + + + + + + +FATAL: only tables with two (2) columns are supported. + + + +&lf; +.Ip "\(bu \s-1 + + + + + +\s0 \- + + + +&lf; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +FATAL: the behaviour of the <> +element was not tested. You need to modify +the XSLT stylesheet in order to get it work. + + + + + + + + + + + + + + + + + \\ + + + + + + + + + + + + + + + + + + + + + + + + + \&. + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/quickreference.xsl b/trunk/docs/manual/style/xsl/quickreference.xsl new file mode 100644 index 0000000000..7b94886d2c --- /dev/null +++ b/trunk/docs/manual/style/xsl/quickreference.xsl @@ -0,0 +1,210 @@ + + + + + +]> + + + + + + + + + &lf; + + &lf; + &lf; + +
    +

    + +

    &lf; + + &lf; + + +
    &lf; + +
    + + + + + + + + + &lf; + + &lf; + &lf; + + &lf; +
    + + + + + + + + + + +
    &lf; + + &lf; + + + + + +
    +
    &lf; + + &lf; + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s + v + d + h + + + B + M + C + E + X + +
    + + + + + + - + + +
    + + + + &lf; + + + + + + &lf; + + + + + + + &lf; + + + + + + + &lf; + + + + + +
    + + + : + + + +
    + + + : + + + +
    + + + : + + + +
    + + + : + + + +
    + + + : + + + +
    &lf; + + + + +

    + +

    &lf; + + + + &lf; + + +
    + +

    + +

    &lf; + + + + &lf; + + + +

    + +

    &lf; +
    +
    + + +

    + +

    &lf; + +
      &lf; + +
    +
    +
    + + +

    + +

    &lf; + +
      &lf; + +
    • + +
    • &lf; +
      +
    +
    +
    +
    &lf; + + + &lf; + + + + + + &lf; + + &lf; + + + + + + + + + + + + &lf; + +
    + + + + +

    + + < + + > + + + + + + + + + + + + + + +

    &lf; + + + &lf; + + + + &lf; + + + + + + + &lf; + + + + + &lf; + + + + + + + &lf; + + + + + &lf; + + + + + &lf; + + + + + + + &lf; + + + + + &lf; +
    + + + : + + + +
    + + + : + + + + + +
    + + + : + + + + + +
    + + + : + + + +
    + + + : + + + +
    + + + : + + + +
    + + + : + + + + + + + + + + +
    + + + : + + + +
    + + &lf; + + +

    + +

    &lf; + +
      &lf; + +
    • + +
    • &lf; +
      +
    &lf; +
    +
    &lf; +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + unknown context: + + + + + + , + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/typemap.xsl b/trunk/docs/manual/style/xsl/typemap.xsl new file mode 100644 index 0000000000..4b14e98ad4 --- /dev/null +++ b/trunk/docs/manual/style/xsl/typemap.xsl @@ -0,0 +1,80 @@ + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +FATAL: missing designation data for language . +The XSLT-Stylesheet won't work without modification. + + + +URI: + +&lf; + +Content-Language: +&lf; + +Content-type: text/html; charset= +&lf; + +&lf; + + + + diff --git a/trunk/docs/manual/style/xsl/util/allmodules.xml b/trunk/docs/manual/style/xsl/util/allmodules.xml new file mode 100644 index 0000000000..a6da945dc2 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/allmodules.xml @@ -0,0 +1,11 @@ + + +../../../mod/allmodules.xml.de +../../../mod/allmodules.xml +../../../mod/allmodules.xml.es +../../../mod/allmodules.xml.fr +../../../mod/allmodules.xml.ja +../../../mod/allmodules.xml.ko +../../../mod/allmodules.xml.pt-br +../../../mod/allmodules.xml.ru + \ No newline at end of file diff --git a/trunk/docs/manual/style/xsl/util/designations.xml b/trunk/docs/manual/style/xsl/util/designations.xml new file mode 100644 index 0000000000..5211ce9ae1 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/designations.xml @@ -0,0 +1,11 @@ + + +.html.de +.html.en +.html.es +.html.fr +.html.ja.euc-jp +.html.ko.euc-kr +.html.pt-br +.html.ru.koi8-r + diff --git a/trunk/docs/manual/style/xsl/util/lf.xml b/trunk/docs/manual/style/xsl/util/lf.xml new file mode 100644 index 0000000000..1ee21592d5 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/lf.xml @@ -0,0 +1,3 @@ + + + diff --git a/trunk/docs/manual/style/xsl/util/li-end.xml b/trunk/docs/manual/style/xsl/util/li-end.xml new file mode 100644 index 0000000000..94ef8a70b7 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/li-end.xml @@ -0,0 +1 @@ +</li> diff --git a/trunk/docs/manual/style/xsl/util/li-start.xml b/trunk/docs/manual/style/xsl/util/li-start.xml new file mode 100644 index 0000000000..2cf57ca916 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/li-start.xml @@ -0,0 +1 @@ +<li> diff --git a/trunk/docs/manual/style/xsl/util/modtrans.xsl b/trunk/docs/manual/style/xsl/util/modtrans.xsl new file mode 100644 index 0000000000..7f8c82f2e9 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/modtrans.xsl @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/docs/manual/style/xsl/util/nbsp.xml b/trunk/docs/manual/style/xsl/util/nbsp.xml new file mode 100644 index 0000000000..a6b7a0622a --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/nbsp.xml @@ -0,0 +1,3 @@ + + +&nbsp; diff --git a/trunk/docs/manual/style/xsl/util/tab.xml b/trunk/docs/manual/style/xsl/util/tab.xml new file mode 100644 index 0000000000..594be38547 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/tab.xml @@ -0,0 +1,3 @@ + + + diff --git a/trunk/docs/manual/style/xsl/util/ul-end.xml b/trunk/docs/manual/style/xsl/util/ul-end.xml new file mode 100644 index 0000000000..347e2c2e97 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/ul-end.xml @@ -0,0 +1 @@ +</ul> diff --git a/trunk/docs/manual/style/xsl/util/ul-start.xml b/trunk/docs/manual/style/xsl/util/ul-start.xml new file mode 100644 index 0000000000..efd15f5712 --- /dev/null +++ b/trunk/docs/manual/style/xsl/util/ul-start.xml @@ -0,0 +1 @@ +<ul> diff --git a/trunk/docs/manual/suexec.html b/trunk/docs/manual/suexec.html new file mode 100644 index 0000000000..9d5e3a86ca --- /dev/null +++ b/trunk/docs/manual/suexec.html @@ -0,0 +1,11 @@ +URI: suexec.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: suexec.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: suexec.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/suexec.html.en b/trunk/docs/manual/suexec.html.en new file mode 100644 index 0000000000..c002472152 --- /dev/null +++ b/trunk/docs/manual/suexec.html.en @@ -0,0 +1,608 @@ + + + +suEXEC Support - Apache HTTP Server + + + + + +
    <-
    +

    suEXEC Support

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    The suEXEC feature provides + Apache users the ability + to run CGI and SSI programs + under user IDs different from the user ID of the calling + web-server. Normally, when a CGI or SSI program executes, it + runs as the same user who is running the web server.

    + +

    Used properly, this feature can reduce + considerably the security risks involved with allowing users to + develop and run private CGI or SSI programs. However, if suEXEC + is improperly configured, it can cause any number of problems + and possibly create new holes in your computer's security. If + you aren't familiar with managing setuid root programs + and the security issues they present, we highly recommend that + you not consider using suEXEC.

    +
    + +
    top
    +
    +

    Before we begin

    + +

    Before jumping head-first into this document, + you should be aware of the assumptions made on the part of the + Apache Group and this document.

    + +

    First, it is assumed that you are using a UNIX + derivative operating system that is capable of + setuid and setgid operations. + All command examples are given in this regard. Other platforms, + if they are capable of supporting suEXEC, may differ in their + configuration.

    + +

    Second, it is assumed you are familiar with + some basic concepts of your computer's security and its + administration. This involves an understanding of + setuid/setgid operations and the various + effects they may have on your system and its level of + security.

    + +

    Third, it is assumed that you are using an + unmodified version of suEXEC code. All code + for suEXEC has been carefully scrutinized and tested by the + developers as well as numerous beta testers. Every precaution + has been taken to ensure a simple yet solidly safe base of + code. Altering this code can cause unexpected problems and new + security risks. It is highly recommended you + not alter the suEXEC code unless you are well versed in the + particulars of security programming and are willing to share + your work with the Apache Group for consideration.

    + +

    Fourth, and last, it has been the decision of + the Apache Group to NOT make suEXEC part of + the default installation of Apache. To this end, suEXEC + configuration requires of the administrator careful attention + to details. After due consideration has been given to the + various settings for suEXEC, the administrator may install + suEXEC through normal installation methods. The values for + these settings need to be carefully determined and specified by + the administrator to properly maintain system security during + the use of suEXEC functionality. It is through this detailed + process that the Apache Group hopes to limit suEXEC + installation only to those who are careful and determined + enough to use it.

    + +

    Still with us? Yes? Good. Let's move on!

    +
    top
    +
    +

    suEXEC Security Model

    + +

    Before we begin configuring and installing + suEXEC, we will first discuss the security model you are about + to implement. By doing so, you may better understand what + exactly is going on inside suEXEC and what precautions are + taken to ensure your system's security.

    + +

    suEXEC is based on a setuid + "wrapper" program that is called by the main Apache web server. + This wrapper is called when an HTTP request is made for a CGI + or SSI program that the administrator has designated to run as + a userid other than that of the main server. When such a + request is made, Apache provides the suEXEC wrapper with the + program's name and the user and group IDs under which the + program is to execute.

    + +

    The wrapper then employs the following process + to determine success or failure -- if any one of these + conditions fail, the program logs the failure and exits with an + error, otherwise it will continue:

    + +
      +
    1. + Is the user executing this wrapper a valid user of + this system? + +

      + This is to ensure that the user executing the wrapper is + truly a user of the system. +

      +
    2. + +
    3. + Was the wrapper called with the proper number of + arguments? + +

      + The wrapper will only execute if it is given the proper + number of arguments. The proper argument format is known + to the Apache web server. If the wrapper is not receiving + the proper number of arguments, it is either being + hacked, or there is something wrong with the suEXEC + portion of your Apache binary. +

      +
    4. + +
    5. + Is this valid user allowed to run the + wrapper? + +

      + Is this user the user allowed to run this wrapper? Only + one user (the Apache user) is allowed to execute this + program. +

      +
    6. + +
    7. + Does the target CGI or SSI program have an unsafe + hierarchical reference? + +

      + Does the target CGI or SSI program's path contain a leading + '/' or have a '..' backreference? These are not allowed; the + target CGI/SSI program must reside within suEXEC's document + root (see --with-suexec-docroot=DIR + below). +

      +
    8. + +
    9. + Is the target user name valid? + +

      + Does the target user exist? +

      +
    10. + +
    11. + Is the target group name valid? + +

      + Does the target group exist? +

      +
    12. + +
    13. + Is the target user NOT superuser? + + +

      + Presently, suEXEC does not allow root + to execute CGI/SSI programs. +

      +
    14. + +
    15. + Is the target userid ABOVE the minimum ID + number? + +

      + The minimum user ID number is specified during + configuration. This allows you to set the lowest possible + userid that will be allowed to execute CGI/SSI programs. + This is useful to block out "system" accounts. +

      +
    16. + +
    17. + Is the target group NOT the superuser + group? + +

      + Presently, suEXEC does not allow the root + group to execute CGI/SSI programs. +

      +
    18. + +
    19. + Is the target groupid ABOVE the minimum ID + number? + +

      + The minimum group ID number is specified during + configuration. This allows you to set the lowest possible + groupid that will be allowed to execute CGI/SSI programs. + This is useful to block out "system" groups. +

      +
    20. + +
    21. + Can the wrapper successfully become the target user + and group? + +

      + Here is where the program becomes the target user and + group via setuid and setgid calls. The group access list + is also initialized with all of the groups of which the + user is a member. +

      +
    22. + +
    23. + Can we change directory to the one in which the target + CGI/SSI program resides? + +

      + If it doesn't exist, it can't very well contain files. If we + can't change directory to it, it might aswell not exist. +

      +
    24. + +
    25. + Is the directory within the Apache + webspace? + +

      + If the request is for a regular portion of the server, is + the requested directory within suEXEC's document root? If + the request is for a UserDir, is the requested directory + within the directory configured as suEXEC's userdir (see + suEXEC's configuration options)? +

      +
    26. + +
    27. + Is the directory NOT writable by anyone + else? + +

      + We don't want to open up the directory to others; only + the owner user may be able to alter this directories + contents. +

      +
    28. + +
    29. + Does the target CGI/SSI program exist? + +

      + If it doesn't exists, it can't very well be executed. +

      +
    30. + +
    31. + Is the target CGI/SSI program NOT writable + by anyone else? + +

      + We don't want to give anyone other than the owner the + ability to change the CGI/SSI program. +

      +
    32. + +
    33. + Is the target CGI/SSI program NOT setuid or + setgid? + +

      + We do not want to execute programs that will then change + our UID/GID again. +

      +
    34. + +
    35. + Is the target user/group the same as the program's + user/group? + +

      + Is the user the owner of the file? +

      +
    36. + +
    37. + Can we successfully clean the process environment + to ensure safe operations? + +

      + suEXEC cleans the process' environment by establishing a + safe execution PATH (defined during configuration), as + well as only passing through those variables whose names + are listed in the safe environment list (also created + during configuration). +

      +
    38. + +
    39. + Can we successfully become the target CGI/SSI program + and execute? + +

      + Here is where suEXEC ends and the target CGI/SSI program begins. +

      +
    40. +
    + +

    This is the standard operation of the + suEXEC wrapper's security model. It is somewhat stringent and + can impose new limitations and guidelines for CGI/SSI design, + but it was developed carefully step-by-step with security in + mind.

    + +

    For more information as to how this security + model can limit your possibilities in regards to server + configuration, as well as what security risks can be avoided + with a proper suEXEC setup, see the "Beware the Jabberwock" section of this + document.

    +
    top
    +
    +

    Configuring & Installing + suEXEC

    + +

    Here's where we begin the fun.

    + +

    suEXEC configuration + options
    +

    + +
    +
    --enable-suexec
    + +
    This option enables the suEXEC feature which is never + installed or activated by default. At least one + --with-suexec-xxxxx option has to be provided + together with the --enable-suexec option to let + APACI accept your request for using the suEXEC feature.
    + +
    --with-suexec-bin=PATH
    + +
    The path to the suexec binary must be hard-coded + in the server for security reasons. Use this option to override + the default path. e.g. + --with-suexec-bin=/usr/sbin/suexec
    + +
    --with-suexec-caller=UID
    + +
    The username under which + Apache normally runs. This is the only user allowed to + execute this program.
    + +
    --with-suexec-userdir=DIR
    + +
    Define to be the subdirectory under users' home + directories where suEXEC access should be allowed. All + executables under this directory will be executable by suEXEC + as the user so they should be "safe" programs. If you are + using a "simple" UserDir directive (ie. one without a "*" in + it) this should be set to the same value. suEXEC will not + work properly in cases where the UserDir directive points to + a location that is not the same as the user's home directory + as referenced in the passwd file. Default value is + "public_html".
    + If you have virtual hosts with a different UserDir for each, + you will need to define them to all reside in one parent + directory; then name that parent directory here. If + this is not defined properly, "~userdir" cgi requests will + not work!
    + +
    --with-suexec-docroot=DIR
    + +
    Define as the DocumentRoot set for Apache. This will be + the only hierarchy (aside from UserDirs) that can be used for + suEXEC behavior. The default directory is the --datadir + value with the suffix "/htdocs", e.g. if you configure + with "--datadir=/home/apache" the directory + "/home/apache/htdocs" is used as document root for the suEXEC + wrapper.
    + +
    --with-suexec-uidmin=UID
    + +
    Define this as the lowest UID allowed to be a target user + for suEXEC. For most systems, 500 or 100 is common. Default + value is 100.
    + +
    --with-suexec-gidmin=GID
    + +
    Define this as the lowest GID allowed to be a target + group for suEXEC. For most systems, 100 is common and + therefore used as default value.
    + +
    --with-suexec-logfile=FILE
    + +
    This defines the filename to which all suEXEC + transactions and errors are logged (useful for auditing and + debugging purposes). By default the logfile is named + "suexec_log" and located in your standard logfile directory + (--logfiledir).
    + +
    --with-suexec-safepath=PATH
    + +
    Define a safe PATH environment to pass to CGI + executables. Default value is + "/usr/local/bin:/usr/bin:/bin".
    +
    + +

    Compiling and installing the suEXEC + wrapper
    + If you have enabled the suEXEC feature with the + --enable-suexec option the suexec binary + (together with Apache itself) is automatically built if you execute + the make command.
    + After all components have been built you can execute the + command make install to install them. The binary image + suexec is installed in the directory defined by the + --sbindir option. The default location is + "/usr/local/apache2/sbin/suexec".
    + Please note that you need root + privileges for the installation step. In order + for the wrapper to set the user ID, it must be installed as + owner root and must have the setuserid + execution bit set for file modes.

    + +

    Setting paranoid permissions
    + Although the suEXEC wrapper will check to ensure that its + caller is the correct user as specified with the + --with-suexec-caller configure + option, there is + always the possibility that a system or library call suEXEC uses + before this check may be exploitable on your system. To counter + this, and because it is best-practise in general, you should use + filesystem permissions to ensure that only the group Apache + runs as may execute suEXEC.

    + +

    If for example, your web-server is configured to run as:

    + +

    + User www
    + Group webgroup
    +

    + +

    and suexec is installed at + "/usr/local/apache2/sbin/suexec", you should run:

    + +

    + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +

    + +

    This will ensure that only the group Apache runs as can even + execute the suEXEC wrapper.

    +
    top
    +
    +

    Enabling & Disabling + suEXEC

    + +

    Upon startup of Apache, it looks for the file + suexec in the directory defined by the + --sbindir option (default is + "/usr/local/apache/sbin/suexec"). If Apache finds a properly + configured suEXEC wrapper, it will print the following message + to the error log:

    + +

    + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) +

    + +

    If you don't see this message at server startup, the server is + most likely not finding the wrapper program where it expects + it, or the executable is not installed setuid root.

    + +

    If you want to enable the suEXEC mechanism for the first time + and an Apache server is already running you must kill and + restart Apache. Restarting it with a simple HUP or USR1 signal + will not be enough.

    +

    If you want to disable suEXEC you should kill and restart + Apache after you have removed the suexec file.

    +
    top
    +
    +

    Using suEXEC

    + +

    Requests for CGI programs will call the suEXEC wrapper only if + they are for a virtual host containing a SuexecUserGroup directive or if + they are processed by mod_userdir.

    + +

    Virtual Hosts:
    One way to use the suEXEC + wrapper is through the SuexecUserGroup directive in + VirtualHost definitions. By + setting this directive to values different from the main server + user ID, all requests for CGI resources will be executed as the + User and Group defined for that <VirtualHost>. If this + directive is not specified for a <VirtualHost> then the main server userid + is assumed.

    + +

    User directories:
    Requests that are + processed by mod_userdir will call the suEXEC + wrapper to execute CGI programs under the userid of the requested + user directory. The only requirement needed for this feature to + work is for CGI execution to be enabled for the user and that the + script must meet the scrutiny of the security + checks above. See also the + --with-suexec-userdir compile + time option.

    top
    +
    +

    Debugging suEXEC

    + +

    The suEXEC wrapper will write log information + to the file defined with the --with-suexec-logfile + option as indicated above. If you feel you have configured and + installed the wrapper properly, have a look at this log and the + error_log for the server to see where you may have gone astray.

    + +
    top
    +
    +

    Beware the Jabberwock: + Warnings & Examples

    + +

    NOTE! This section may not be + complete. For the latest revision of this section of the + documentation, see the Apache Group's Online + Documentation version.

    + +

    There are a few points of interest regarding + the wrapper that can cause limitations on server setup. Please + review these before submitting any "bugs" regarding suEXEC.

    + +
      +
    • suEXEC Points Of Interest
    • + +
    • + Hierarchy limitations + +

      + For security and efficiency reasons, all suEXEC requests + must remain within either a top-level document root for + virtual host requests, or one top-level personal document + root for userdir requests. For example, if you have four + VirtualHosts configured, you would need to structure all + of your VHosts' document roots off of one main Apache + document hierarchy to take advantage of suEXEC for + VirtualHosts. (Example forthcoming.) +

      +
    • + +
    • + suEXEC's PATH environment variable + +

      + This can be a dangerous thing to change. Make certain + every path you include in this define is a + trusted directory. You don't want to + open people up to having someone from across the world + running a trojan horse on them. +

      +
    • + +
    • + Altering the suEXEC code + +

      + Again, this can cause Big Trouble if you + try this without knowing what you are doing. Stay away + from it if at all possible. +

      +
    • +
    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/suexec.html.ja.euc-jp b/trunk/docs/manual/suexec.html.ja.euc-jp new file mode 100644 index 0000000000..25fe865cae --- /dev/null +++ b/trunk/docs/manual/suexec.html.ja.euc-jp @@ -0,0 +1,609 @@ + + + +suEXEC ¥µ¥Ý¡¼¥È - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    suEXEC ¥µ¥Ý¡¼¥È

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    suEXEC + µ¡Ç½¤Ë¤è¤ê¡¢Apache ¥æ¡¼¥¶¤Ï Web ¥µ¡¼¥Ð¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥æ¡¼¥¶ ID ¤È¤Ï + °Û¤Ê¤ë¥æ¡¼¥¶ ID ¤Ç CGI ¥×¥í¥°¥é¥à¤ä SSI + ¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£CGI ¥×¥í¥°¥é¥à¤Þ¤¿¤Ï SSI + ¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ë¾ì¹ç¡¢Ä̾ï¤Ï web ¥µ¡¼¥Ð¤ÈƱ¤¸¥æ¡¼¥¶¤Ç¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ +

    + +

    ŬÀڤ˻ÈÍѤ¹¤ë¤È¡¢¤³¤Îµ¡Ç½¤Ë¤è¤ê¥æ¡¼¥¶¤¬¸ÄÊ̤ΠCGI + ¤ä SSI ¥×¥í¥°¥é¥à¤ò³«È¯¤·¼Â¹Ô¤¹¤ë¤³¤È¤ÇÀ¸¤¸¤ë¥»¥­¥å¥ê¥Æ¥£¾å¤Î´í¸±¤ò¡¢ + ¤«¤Ê¤ê¸º¤é¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤·¤«¤·¡¢suEXEC ¤ÎÀßÄ꤬ÉÔŬÀÚ¤À¤È¡¢ + ¿¤¯¤ÎÌäÂ꤬À¸¤¸¡¢¤¢¤Ê¤¿¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Ë¿·¤·¤¤¥»¥­¥å¥ê¥Æ¥£¥Û¡¼¥ë¤ò + ºî¤Ã¤Æ¤·¤Þ¤¦²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤¢¤Ê¤¿¤¬ setuid root + ¤µ¤ì¤¿¥×¥í¥°¥é¥à¤È¡¢¤½¤ì¤é¤«¤éÀ¸¤¸¤ë¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÌäÂê¤Î´ÉÍý¤Ë + ¾Ü¤·¤¯¤Ê¤¤¤è¤¦¤Ê¤é¡¢suEXEC ¤Î»ÈÍѤò¸¡Æ¤¤·¤Ê¤¤¤è¤¦¤Ë¶¯¤¯¿ä¾©¤·¤Þ¤¹¡£ +

    +
    + +
    top
    +
    +

    »Ï¤á¤ëÁ°¤Ë

    + +

    ¤³¤Îʸ½ñ¤ÎÀèƬ¤ËÈô¤ÖÁ°¤Ë¡¢Apache + ¥°¥ë¡¼¥×¤È¤³¤Îʸ½ñ¤Ç¤Î²¾Äê¤òÃΤäƤª¤¯¤Ù¤­¤Ç¤·¤ç¤¦¡£ +

    + +

    Âè 1 ¤Ë¡¢¤¢¤Ê¤¿¤¬ setuid ¤È + setgid Áàºî¤¬²Äǽ¤Ê UNIX + ͳÍè¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ò»È¤Ã¤Æ¤¤¤ë¤³¤È¤òÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£ + ¤³¤ì¤Ï¡¢¤¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥ÉÎã¤Ë¤¢¤Æ¤Ï¤Þ¤ê¤Þ¤¹¡£ + ¤½¤Î¾¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ç¤Ï¡¢¤â¤· suEXEC + ¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤¿¤È¤·¤Æ¤âÀßÄê¤Ï°Û¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +

    Âè 2 ¤Ë¡¢¤¢¤Ê¤¿¤¬»ÈÍÑÃæ¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Î + ¥»¥­¥å¥ê¥Æ¥£¤Ë´Ø¤¹¤ë´ðËÜŪ¤Ê³µÇ°¤È¡¢¤½¤ì¤é¤Î´ÉÍý¤Ë¤Ä¤¤¤Æ¾Ü¤·¤¤¤³¤È¤ò + ÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¡¢setuid/setgid + Áàºî¡¢¤¢¤Ê¤¿¤Î¥·¥¹¥Æ¥à¾å¤Ç¤Î¤½¤ÎÁàºî¤Ë¤è¤ëÍÍ¡¹¤Ê¸ú²Ì¡¢ + ¥»¥­¥å¥ê¥Æ¥£¥ì¥Ù¥ë¤Ë¤Ä¤¤¤Æ¤¢¤Ê¤¿¤¬Íý²ò¤·¤Æ¤¤¤ë¤È¤¤¤¦¤³¤È¤ò´Þ¤ß¤Þ¤¹¡£ +

    + +

    Âè 3 ¤Ë¡¢²þ¤¤µ¤ì¤Æ¤¤¤Ê¤¤ suEXEC + ¥³¡¼¥É¤Î»ÈÍѤòÁÛÄꤷ¤Æ¤¤¤Þ¤¹¡£suEXEC ¤Î¥³¡¼¥É¤Ï¡¢ + ¿¤¯¤Î¥Ù¡¼¥¿¥Æ¥¹¥¿¤À¤±¤Ç¤Ê¤¯¡¢³«È¯¼Ô¤Ë¤è¤Ã¤Æ¤âÃí°Õ¿¼¤¯Àººº¤µ¤ì + ¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤é¤ÎÃí°Õ¤Ë¤è¤ê¡¢´Ê·é¤Ç¿®Íê¤Ç¤­¤ë°ÂÁ´¤Ê + ¥³¡¼¥É¤Î´ðÈפ¬Êݾڤµ¤ì¤Þ¤¹¡£¤³¤Î¥³¡¼¥É¤ò²þÊѤ¹¤ë¤³¤È¤Ç¡¢ + ͽ´ü¤µ¤ì¤Ê¤¤ÌäÂê¤ä¿·¤·¤¤¥»¥­¥å¥ê¥Æ¥£¾å¤Î´í¸±¤¬À¸¤¸¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¥»¥­¥å¥ê¥Æ¥£¥×¥í¥°¥é¥ß¥ó¥°¤Î¾ÜºÙ¤ËÄ̤¸¤Æ¤¤¤Æ¡¢ + º£¸å¤Î¸¡Æ¤¤Î¤¿¤á¤ËÀ®²Ì¤ò Apache + ¥°¥ë¡¼¥×¤È¶¦Í­¤·¤è¤¦¤È»×¤¦¤Î¤Ç¤Ê¤±¤ì¤Ð¡¢suEXEC + ¥³¡¼¥É¤ÏÊѤ¨¤Ê¤¤¤³¤È¤ò ¶¯¤¯¿ä¾©¤·¤Þ¤¹¡£

    + +

    Âè 4 ¤Ë¡¢¤³¤ì¤¬ºÇ¸å¤Ç¤¹¤¬¡¢suEXEC ¤ò Apache + ¤Î¥Ç¥Õ¥©¥ë¥È¥¤¥ó¥¹¥È¡¼¥ë¤Ë¤Ï´Þ¤á¤Ê¤¤¤³¤È¤¬ + Apache ¥°¥ë¡¼¥×¤Ç·èÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¡¢suEXEC + ¤ÎÀßÄê¤Ë¤Ï´ÉÍý¼Ô¤Î¾ÜºÙ¤Ë¤ï¤¿¤ë¿µ½Å¤ÊÃí°Õ¤¬É¬ÍפÀ¤«¤é¤Ç¤¹¡£ + suEXEC ¤ÎÍÍ¡¹¤ÊÀßÄê¤Ë¤Ä¤¤¤Æ¸¡Æ¤¤¬½ª¤ï¤ì¤Ð¡¢´ÉÍý¼Ô¤Ï suEXEC + ¤òÄ̾ï¤Î¥¤¥ó¥¹¥È¡¼¥ëÊýË¡¤Ç¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤³¤ì¤é¤ÎÀßÄêÃͤϡ¢suEXEC + µ¡Ç½¤Î»ÈÍÑÃæ¤Ë¥·¥¹¥Æ¥à¥»¥­¥å¥ê¥Æ¥£¤òŬÀÚ¤ËÊݤĤ¿¤á¤Ë¡¢ + ´ÉÍý¼Ô¤Ë¤è¤Ã¤Æ¿µ½Å¤Ë·èÄꤵ¤ì»ØÄꤵ¤ì¤ë¤³¤È¤¬É¬ÍפǤ¹¡£ + ¤³¤Î¾ÜºÙ¤Ê¼ê½ç¤Ë¤è¤ê¡¢Apache ¥°¥ë¡¼¥×¤Ï¡¢suEXEC + ¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Ë¤Ä¤¤¤Æ¡¢Ãí°Õ¿¼¤¯½½Ê¬¤Ë¸¡Æ¤¤·¤Æ¤½¤ì¤ò»ÈÍѤ¹¤ë¤³¤È¤ò + ·èÄꤷ¤¿¾ì¹ç¤Ë¸Â¤Ã¤Æ¤¤¤¿¤À¤­¤¿¤¤¤È¹Í¤¨¤Æ¤¤¤Þ¤¹¡£ +

    + +

    ¤½¤ì¤Ç¤â¿Ê¤ß¤Þ¤¹¤«? ¤è¤í¤·¤¤¡£¤Ç¤Ï¡¢Àè¤Ø¿Ê¤ß¤Þ¤·¤ç¤¦!

    +
    top
    +
    +

    suEXEC ¥»¥­¥å¥ê¥Æ¥£¥â¥Ç¥ë

    + +

    suEXEC ¤ÎÀßÄê¤È¥¤¥ó¥¹¥È¡¼¥ë¤ò»Ï¤á¤ëÁ°¤Ë¡¢ + ¤Þ¤º¼ÂÁõ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¥»¥­¥å¥ê¥Æ¥£¥â¥Ç¥ë¤Ë¤Ä¤¤¤ÆÏÀ¤¸¤Æ¤ª¤­¤Þ¤¹¡£ + ¤½¤ì¤Ë¤Ï¡¢suEXEC ¤ÎÆâÉô¤Ç¹Ô¤Ê¤ï¤ì¤Æ¤¤¤ë¤³¤È¡¢ + ¥·¥¹¥Æ¥à¤Î¥»¥­¥å¥ê¥Æ¥£¤òÊݾڤ¹¤ë¤¿¤á¤Ë·Ù¹ð¤µ¤ì¤ë¤³¤È¤ò + ¤è¤¯Íý²ò¤·¤Æ¤ª¤¤¤¿Êý¤¬¤è¤¤¤Ç¤·¤ç¤¦¡£

    + +

    suEXEC ¤Ï¡¢Apache web + ¥µ¡¼¥Ð¤«¤é¸Æ¤Ó½Ð¤µ¤ì¤ë setuid ¤µ¤ì¤¿ "wrapper" + ¥×¥í¥°¥é¥à¤¬´ðËܤȤʤäƤ¤¤Þ¤¹¡£À߷פ·¤¿ CGI¡¢¤Þ¤¿¤Ï SSI + ¥×¥í¥°¥é¥à¤Ø¤Î HTTP ¥ê¥¯¥¨¥¹¥È¤¬¤¢¤ë¤È¡¢¤³¤Î wrapper + ¤¬¸Æ¤Ó½Ð¤µ¤ì¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ê¥ê¥¯¥¨¥¹¥È¤¬¤¢¤ë¤È¡¢Apache + ¤Ï¤½¤Î¥×¥í¥°¥é¥à¤¬¼Â¹Ô¤µ¤ì¤ëºÝ¤Î¥×¥í¥°¥é¥à̾¤È¥æ¡¼¥¶ ID ¤È¥°¥ë¡¼¥× + ID ¤ò»ØÄꤷ¤Æ suEXEC wrapper ¤ò¼Â¹Ô¤·¤Þ¤¹¡£ +

    + +

    ¤½¤ì¤«¤é¡¢wrapper ¤ÏÀ®¸ù¤Þ¤¿¤Ï¼ºÇÔ¤ò·èÄꤹ¤ë¤¿¤á + °Ê²¼¤Î½èÍý¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£¤³¤ì¤é¤Î¾õÂ֤Τ¦¤Á°ì¤Ä¤Ç¤â¼ºÇÔ¤·¤¿¾ì¹ç¡¢ + ¥×¥í¥°¥é¥à¤Ï¼ºÇÔ¤ò¥í¥°¤Ëµ­Ï¿¤·¤Æ¥¨¥é¡¼¤Ç½ªÎ»¤·¤Þ¤¹¡£ + ¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¡¢¸å¤Î½èÍý¤¬Â³¤±¤é¤ì¤Þ¤¹¡£

    + +
      +
    1. + wrapper + ¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥æ¡¼¥¶¤Ï¤³¤Î¥·¥¹¥Æ¥à¤ÎÀµÅö¤Ê¥æ¡¼¥¶¤«? + +

      + ¤³¤ì¤Ï¡¢wrapper ¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥æ¡¼¥¶¤¬ + ËÜÅö¤Ë¥·¥¹¥Æ¥à¤ÎÍøÍѼԤǤ¢¤ë¤³¤È¤òÊݾڤ¹¤ë¤¿¤á¤Ç¤¹¡£ +

      +
    2. + + +
    3. + wrapper ¤¬Å¬Àڤʿô¤Î°ú¿ô¤Ç¸Æ¤Ó½Ð¤µ¤ì¤¿¤«? + + +

      + wrapper ¤ÏŬÀڤʿô¤Î°ú¿ô¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¤Ë¤Î¤ß¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ + ŬÀڤʰú¿ô¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï Apache Web ¥µ¡¼¥Ð¤Ë²ò¼á¤µ¤ì¤Þ¤¹¡£ + ŬÀڤʿô¤Î°ú¿ô¤ò¼õ¤±¼è¤é¤Ê¤±¤ì¤Ð¡¢¹¶·â¤ò¤µ¤ì¤¿¤« + ¤¢¤Ê¤¿¤Î Apache ¥Ð¥¤¥Ê¥ê¤Î suEXEC ¤ÎÉôʬ¤¬ + ¤É¤³¤«¤ª¤«¤·¤¤²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ +

      +
    4. + +
    5. + ¤³¤ÎÀµÅö¤Ê¥æ¡¼¥¶¤Ï wrapper + ¤Î¼Â¹Ô¤òµö²Ä¤µ¤ì¤Æ¤¤¤ë¤«? + +

      + ¤³¤Î¥æ¡¼¥¶¤Ï wrapper ¼Â¹Ô¤òµö²Ä¤µ¤ì¤¿¥æ¡¼¥¶¤Ç¤¹¤«? + ¤¿¤À°ì¿Í¤Î¥æ¡¼¥¶ (Apache ¥æ¡¼¥¶) ¤À¤±¤¬¡¢ + ¤³¤Î¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤òµö²Ä¤µ¤ì¤Þ¤¹¡£ +

      +
    6. + +
    7. + ÂоݤΠCGI, SSI ¥×¥í¥°¥é¥à¤¬°ÂÁ´¤Ç¤Ê¤¤³¬Áؤλ²¾È¤ò¤·¤Æ¤¤¤ë¤«? + + +

      + ÂоݤΠCGI, SSI ¥×¥í¥°¥é¥à¤¬ '/' ¤«¤é»Ï¤Þ¤ë¡¢¤Þ¤¿¤Ï + '..' ¤Ë¤è¤ë»²¾È¤ò¹Ô¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤«? ¤³¤ì¤é¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó¡£ + ÂÐ¾Ý¤Î¥×¥í¥°¥é¥à¤Ï suEXEC ¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È + (²¼µ­¤Î --with-suexec-docroot=DIR ¤ò»²¾È) + Æâ¤Ë¸ºß¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ +

      +
    8. + +
    9. + ÂоݤȤʤë¥æ¡¼¥¶Ì¾¤ÏÀµÅö¤Ê¤â¤Î¤«? + +

      + ÂоݤȤʤë¥æ¡¼¥¶Ì¾¤Ï¸ºß¤·¤Æ¤¤¤Þ¤¹¤«? +

      +
    10. + +
    11. + ÂоݤȤʤ륰¥ë¡¼¥×̾¤ÏÀµÅö¤Ê¤â¤Î¤«? + +

      + ÂоݤȤʤ륰¥ë¡¼¥×̾¤Ï¸ºß¤·¤Æ¤¤¤Þ¤¹¤«? +

      +
    12. + +
    13. + ÌÜŪ¤Î¥æ¡¼¥¶¤Ï¥¹¡¼¥Ñ¡¼¥æ¡¼¥¶¤Ç¤Ï¤Ê¤¤¤«? + + +

      + º£¤Î¤È¤³¤í¡¢suEXEC ¤Ï root ¤Ë¤è¤ë CGI/SSI + ¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤òµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó¡£ +

      +
    14. + +
    15. + ÂоݤȤʤë¥æ¡¼¥¶ ID ¤Ï¡¢ºÇ¾®¤Î ID + ÈÖ¹æ¤è¤ê¤âÂ礭¤¤¤«? + +

      + ºÇ¾®¥æ¡¼¥¶ ID ÈÖ¹æ¤ÏÀßÄê»þ¤Ë»ØÄꤵ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¡¢ + CGI/SSI ¥×¥í¥°¥é¥à¼Â¹Ô¤òµö²Ä¤µ¤ì¤ë¥æ¡¼¥¶ ID + ¤Î¤È¤ê¤¦¤ëºÇ¾®ÃͤǤ¹¡£¤³¤ì¤Ï + "system" ÍѤΥ¢¥«¥¦¥ó¥È¤òÊĤá½Ð¤¹¤Î¤ËÍ­¸ú¤Ç¤¹¡£ +

      +
    16. + +
    17. + ÂоݤȤʤ륰¥ë¡¼¥×¤Ï¥¹¡¼¥Ñ¡¼¥æ¡¼¥¶¤Î¥°¥ë¡¼¥×¤Ç¤Ï + ¤Ê¤¤¤«? + +

      + º£¤Î¤È¤³¤í¡¢suEXEC ¤Ï 'root' ¥°¥ë¡¼¥×¤Ë¤è¤ë CGI/SSI + ¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤òµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó¡£ +

      +
    18. + +
    19. + ÂоݤȤʤ륰¥ë¡¼¥× ID ¤ÏºÇ¾®¤Î ID + ÈÖ¹æ¤è¤ê¤âÂ礭¤¤¤«? + +

      + ºÇ¾®¥°¥ë¡¼¥× ID ÈÖ¹æ¤ÏÀßÄê»þ¤Ë»ØÄꤵ¤ì¤Þ¤¹¡£¤³¤ì¤Ï¡¢ + CGI/SSI ¥×¥í¥°¥é¥à¼Â¹Ô¤òµö²Ä¤µ¤ì¤ë¥°¥ë¡¼¥× + ID ¤Î¤È¤ê¤¦¤ëºÇ¾®ÃͤǤ¹¡£ + ¤³¤ì¤Ï "system" ÍѤΥ°¥ë¡¼¥×¤òÊĤá½Ð¤¹¤Î¤ËÍ­¸ú¤Ç¤¹¡£ +

      +
    20. + +
    21. + wrapper ¤¬Àµ¾ï¤ËÂоݤȤʤë¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤Ë¤Ê¤ì¤ë¤«? + + +

      + ¤³¤³¤Ç¡¢setuid ¤È setgid + ¤Îµ¯Æ°¤Ë¤è¤ê¥×¥í¥°¥é¥à¤ÏÂоݤȤʤë¥æ¡¼¥¶¤È¥°¥ë¡¼¥×¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¥°¥ë¡¼¥×¥¢¥¯¥»¥¹¥ê¥¹¥È¤Ï¡¢ + ¥æ¡¼¥¶¤¬Â°¤·¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¥°¥ë¡¼¥×¤Ç½é´ü²½¤µ¤ì¤Þ¤¹¡£ +

      +
    22. + +
    23. + CGI/SSI ¥×¥í¥°¥é¥à¤¬ÃÖ¤«¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ° + (change directory) ¤Ç¤­¤ë¤«? + +

      + ¥Ç¥£¥ì¥¯¥È¥ê¤¬Â¸ºß¤·¤Ê¤¤¤Ê¤é¡¢¤½¤Î¥Õ¥¡¥¤¥ë¤â¸ºß¤·¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ + ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°ÜÆ°¤Ç¤­¤Ê¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢¤ª¤½¤é¤¯Â¸ºß¤â¤·¤Ê¤¤¤Ç¤·¤ç¤¦¡£ +

      +
    24. + +
    25. + ¥Ç¥£¥ì¥¯¥È¥ê¤¬ Apache ¤Î¥É¥­¥å¥á¥ó¥È¥Ä¥ê¡¼Æâ¤Ë¤¢¤ë¤«? + + +

      + ¥ê¥¯¥¨¥¹¥È¤¬¥µ¡¼¥ÐÆâ¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢ + Í׵ᤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤¬ suEXEC ¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥ÈÇÛ²¼¤Ë¤¢¤ê¤Þ¤¹¤«? + ¥ê¥¯¥¨¥¹¥È¤¬ UserDir ¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢Í׵ᤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤¬ suEXEC + ¤Î¥æ¡¼¥¶¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥ÈÇÛ²¼¤Ë¤¢¤ê¤Þ¤¹¤«? + (suEXEC ÀßÄꥪ¥×¥·¥ç¥ó »²¾È) +

      +
    26. + +
    27. + ¥Ç¥£¥ì¥¯¥È¥ê¤ò¾¤Î¥æ¡¼¥¶¤¬½ñ¤­¹þ¤á¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ + ¤¤¤Ê¤¤¤«? + +

      + ¥Ç¥£¥ì¥¯¥È¥ê¤ò¾¥æ¡¼¥¶¤Ë³«Êü¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£ + ½êÍ­¥æ¡¼¥¶¤À¤±¤¬¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ÎÆâÍƤò²þÊѤǤ­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ +

      +
    28. + + +
    29. + ÂоݤȤʤë CGI/SSI ¥×¥í¥°¥é¥à¤Ï¸ºß¤¹¤ë¤«? + +

      + ¸ºß¤·¤Ê¤±¤ì¤Ð¼Â¹Ô¤Ç¤­¤Þ¤»¤ó¡£ +

      +
    30. + +
    31. + ÂоݤȤʤë CGI/SSI ¥×¥í¥°¥é¥à¥Õ¥¡¥¤¥ë¤¬Â¾¥¢¥«¥¦¥ó¥È¤«¤é + ½ñ¤­¹þ¤á¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤«? + +

      + ½êÍ­¼Ô°Ê³°¤Ë¤Ï CGI/SSI ¥×¥í¥°¥é¥à¤òÊѹ¹¤¹¤ë¸¢¸Â¤ÏÍ¿¤¨¤é¤ì¤Þ¤»¤ó¡£ +

      +
    32. + + +
    33. + ÂоݤȤʤë CGI/SSI ¥×¥í¥°¥é¥à¤¬ setuid ¤Þ¤¿¤Ï setgid + ¤µ¤ì¤Æ¤¤¤Ê¤¤¤«? + +

      + UID/GID ¤òºÆÅÙÊѹ¹¤·¤Æ¤Î¥×¥í¥°¥é¥à¼Â¹Ô¤Ï¤·¤Þ¤»¤ó +

      +
    34. + + +
    35. + ÂоݤȤʤë¥æ¡¼¥¶/¥°¥ë¡¼¥×¤¬¥×¥í¥°¥é¥à¤Î + ¥æ¡¼¥¶/¥°¥ë¡¼¥×¤ÈƱ¤¸¤«? + +

      + ¥æ¡¼¥¶¤¬¤½¤Î¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤Ç¤¹¤«? +

      +
    36. + +
    37. + °ÂÁ´¤ÊÆ°ºî¤òÊݾڤ¹¤ë¤¿¤á¤Î´Ä¶­ÊÑ¿ô¥¯¥ê¥¢¤¬²Äǽ¤«? + + +

      + suEXEC ¤Ï¡¢°ÂÁ´¤Ê´Ä¶­ÊÑ¿ô¤Î¥ê¥¹¥È + (¤³¤ì¤é¤ÏÀßÄê»þ¤ËºîÀ®¤µ¤ì¤Þ¤¹) Æâ¤ÎÊÑ¿ô¤È¤·¤ÆÅϤµ¤ì¤ë°ÂÁ´¤Ê + PATH ÊÑ¿ô (ÀßÄê»þ¤Ë»ØÄꤵ¤ì¤Þ¤¹) ¤òÀßÄꤹ¤ë¤³¤È¤Ç¡¢ + ¥×¥í¥»¥¹¤Î´Ä¶­ÊÑ¿ô¤ò¥¯¥ê¥¢¤·¤Þ¤¹¡£ +

      +
    38. + + +
    39. + ÂоݤȤʤë CGI/SSI ¥×¥í¥°¥é¥à¤ò exec ¤·¤Æ¼Â¹Ô¤Ç¤­¤ë¤«? + + +

      + ¤³¤³¤Ç suEXEC ¤¬½ªÎ»¤·¡¢ÂоݤȤʤë¥×¥í¥°¥é¥à¤¬³«»Ï¤µ¤ì¤Þ¤¹¡£ +

      +
    40. +
    + +

    ¤³¤³¤Þ¤Ç¤¬ suEXEC ¤Î wrapper + ¤Ë¤ª¤±¤ë¥»¥­¥å¥ê¥Æ¥£¥â¥Ç¥ë¤Îɸ½àŪ¤ÊÆ°ºî¤Ç¤¹¡£¤â¤¦¾¯¤·¸·½Å¤Ë + CGI/SSI À߷פˤĤ¤¤Æ¤Î¿·¤·¤¤À©¸Â¤äµ¬Äê¤ò¼è¤êÆþ¤ì¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢ + suEXEC ¤Ï¥»¥­¥å¥ê¥Æ¥£¤ËÃí°Õ¤·¤Æ¿µ½Å¤Ë¾¯¤·¤º¤Ä³«È¯¤µ¤ì¤Æ¤­¤Þ¤·¤¿¡£ +

    + +

    ¤³¤Î¥»¥­¥å¥ê¥Æ¥£¥â¥Ç¥ë¤òÍѤ¤¤Æ + ¥µ¡¼¥ÐÀßÄê»þ¤Ë¤É¤Î¤è¤¦¤Ëµö¤¹¤³¤È¤òÀ©¸Â¤¹¤ë¤«¡¢¤Þ¤¿¡¢suEXEC + ¤òŬÀÚ¤ËÀßÄꤹ¤ë¤È¤É¤Î¤è¤¦¤Ê¥»¥­¥å¥ê¥Æ¥£¾å¤Î´í¸±¤òÈò¤±¤é¤ì¤ë¤«¤Ë + ´Ø¤¹¤ë¤è¤ê¾Ü¤·¤¤¾ðÊó¤Ë¤Ä¤¤¤Æ¤Ï¡¢"¤È¤«¤²¤ËÃí°Õ" + (Beware the Jabberwock) ¤Î¾Ï¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ +

    +
    top
    +
    +

    suEXEC + ¤ÎÀßÄê¤È¥¤¥ó¥¹¥È¡¼¥ë

    + +

    ¤³¤³¤«¤é³Ú¤·¤¯¤Ê¤ê¤Þ¤¹¡£

    + +

    suEXEC + ÀßÄꥪ¥×¥·¥ç¥ó
    +

    + +
    +
    --enable-suexec
    + +
    ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤º¡¢ + Í­¸ú¤Ë¤Ï¤Ê¤é¤Ê¤¤ suEXEC µ¡Ç½¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£ + suEXEC ¤ò»È¤¦¤è¤¦¤Ë APACI ¤ËÍ׵᤹¤ë¤Ë¤Ï¡¢--enable-suexec + ¥ª¥×¥·¥ç¥ó¤Ë¤¢¤ï¤»¤Æ¾¯¤Ê¤¯¤È¤â°ì¤Ä¤Ï --with-suexec-xxxxx + ¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
    + +
    --with-suexec-bin=PATH
    + +
    ¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤Ë¤è¤ê¡¢suexec ¥Ð¥¤¥Ê¥ê¤Î¥Ñ¥¹¤Ï¥µ¡¼¥Ð¤Ë + ¥Ï¡¼¥É¥³¡¼¥É¤µ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤Î¥Ñ¥¹¤ò + ÊѤ¨¤¿¤¤¤È¤­¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¡¢ + --with-suexec-bin=/usr/sbin/suexec ¤Î¤è¤¦¤Ë¡£
    + +
    --with-suexec-caller=UID
    + +
    Apache ¤òÄ̾ïÆ°ºî¤µ¤»¤ë¥æ¡¼¥¶Ì¾¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥æ¡¼¥¶¤À¤±¤¬ suexec ¤Î¼Â¹Ô¤òµö²Ä¤µ¤ì¤¿¥æ¡¼¥¶¤Ë¤Ê¤ê¤Þ¤¹¡£
    + +
    --with-suexec-userdir=DIR
    + +
    suEXEC ¤¬¥¢¥¯¥»¥¹¤òµö¤µ¤ì¤ë¥æ¡¼¥¶¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥êÇÛ²¼¤Î + ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê°Ê²¼¤ÎÁ´¼Â¹Ô¥Õ¥¡¥¤¥ë¤Ï¡¢"°ÂÁ´¤Ê"¥×¥í¥°¥é¥à¤Ë¤Ê¤ë¤è¤¦¡¢ + suEXEC ¤¬¤½¤Î¥æ¡¼¥¶¤È¤·¤Æ¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + "ñ½ã¤Ê" UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç + (¤¹¤Ê¤ï¤Á "*" ¤ò´Þ¤Þ¤Ê¤¤¤â¤Î)¡¢¤³¤ì¤ÈƱ¤¸ÃͤòÀßÄꤹ¤Ù¤­¤Ç¤¹¡£ + Userdir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬¤½¤Î¥æ¡¼¥¶¤Î¥Ñ¥¹¥ï¡¼¥É¥Õ¥¡¥¤¥ëÆâ¤Î + ¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤ÈƱ¤¸¾ì½ê¤ò»Ø¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢ + suEXEC ¤ÏŬÀÚ¤ËÆ°ºî¤·¤Þ¤»¤ó¡£¥Ç¥Õ¥©¥ë¥È¤Ï "public_html" ¤Ç¤¹¡£ +
    + ³Æ UserDir ¤¬°Û¤Ê¤Ã¤¿²¾ÁÛ¥Û¥¹¥È¤òÀßÄꤷ¤Æ¤¤¤ë¾ì¹ç¡¢ + ¤½¤ì¤é¤òÁ´¤Æ°ì¤Ä¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Ë´Þ¤á¤Æ¡¢ + ¤½¤Î¿Æ¥Ç¥£¥ì¥¯¥È¥ê¤Î̾Á°¤ò¤³¤³¤Ç»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¤è¤¦¤Ë»ØÄꤵ¤ì¤Ê¤±¤ì¤Ð "~userdir" cgi + ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤¬Æ°ºî¤·¤Þ¤»¤ó¡£
    + +
    --with-suexec-docroot=DIR
    + +
    Apache ¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤¬ suEXEC + ¤ÎÆ°ºî¤Ç»ÈÍѤ¹¤ëÍ£°ì¤Î¥Ç¥£¥ì¥¯¥È¥ê³¬Áؤˤʤê¤Þ¤¹ (UserDir + ¤Î»ØÄê¤ÏÊÌ)¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï --datedir ¤Ë "/htdocs" + ¤È¤¤¤¦¥µ¥Õ¥£¥Ã¥¯¥¹¤ò¤Ä¤±¤¿¤â¤Î¤Ç¤¹¡£ + "--datadir=/home/apache" ¤È¤·¤ÆÀßÄꤹ¤ë¤È¡¢ + suEXEC wrapper ¤Ë¤È¤Ã¤Æ "/home/apache/htdocs" + ¤¬¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È¤È¤·¤Æ»È¤ï¤ì¤Þ¤¹¡£
    + +
    --with-suexec-uidmin=UID
    + +
    suEXEC ¤ÎÂоݥ桼¥¶¤È¤·¤Æµö¤µ¤ì¤ë UID ¤ÎºÇ¾®Ãͤò»ØÄꤷ¤Þ¤¹¡£ + ÂçÄñ¤Î¥·¥¹¥Æ¥à¤Ç¤Ï 500 ¤« 100 ¤¬°ìÈÌŪ¤Ç¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï 100 ¤Ç¤¹¡£
    + +
    --with-suexec-gidmin=GID
    + +
    suEXEC ¤ÎÂоݥ°¥ë¡¼¥×¤È¤·¤Æµö¤µ¤ì¤ë GID + ¤ÎºÇ¾®Ãͤò»ØÄꤷ¤Þ¤¹¡£ÂçÄñ¤Î¥·¥¹¥Æ¥à¤Ç¤Ï 100 ¤¬°ìÈÌŪ¤Ê¤Î¤Ç¡¢ + ¥Ç¥Õ¥©¥ë¥ÈÃͤȤ·¤Æ¤â 100 ¤¬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£
    + +
    --with-suexec-logfile=FILE
    + +
    suEXEC ¤Î½èÍý¤È¥¨¥é¡¼¤¬µ­Ï¿¤µ¤ì¤ë¥Õ¥¡¥¤¥ë̾¤ò»ØÄꤷ¤Þ¤¹¡£ + (´Æºº¤ä¥Ç¥Ð¥Ã¥°ÌÜŪ¤ËÍ­ÍÑ) + ¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¥í¥°¥Õ¥¡¥¤¥ë¤Ï "suexec_log" ¤È¤¤¤¦Ì¾Á°¤Ç¡¢ + ɸ½à¤Î¥í¥°¥Õ¥¡¥¤¥ë¥Ç¥£¥ì¥¯¥È¥ê (--logfiledir) ¤ËÃÖ¤«¤ì¤Þ¤¹¡£ +
    + +
    --with-suexec-safepath=PATH
    + +
    CGI ¼Â¹Ô¥Õ¥¡¥¤¥ë¤ËÅϤµ¤ì¤ë°ÂÁ´¤Ê PATH ´Ä¶­ÊÑ¿ô¤Ç¤¹¡£ + ¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï "/usr/local/bin:/usr/bin:/bin" ¤Ç¤¹¡£ +
    +
    + +

    suEXEC wrapper + ¤Î¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë
    + --enable-suexec ¥ª¥×¥·¥ç¥ó¤Ç suEXEC µ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¢ + "make" ¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿»þ¤Ë suexec ¤Î¥Ð¥¤¥Ê¥ê (Apache ¼«ÂΤâ) + ¤¬¼«Æ°Åª¤ËºîÀ®¤µ¤ì¤Þ¤¹¡£ +
    + ¤¹¤Ù¤Æ¤Î¹½À®Í×ÁǤ¬ºîÀ®¤µ¤ì¤ë¤È¡¢¤½¤ì¤é¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Ë¤Ï + make install ¥³¥Þ¥ó¥É¤¬¼Â¹Ô¤Ç¤­¤Þ¤¹¡£¥Ð¥¤¥Ê¥ê¥¤¥á¡¼¥¸¤Î suexec + ¤Ï --sbindir ¥ª¥×¥·¥ç¥ó¤Ç»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Þ¤¹¡£ + ¥Ç¥Õ¥©¥ë¥È¤Î¾ì½ê¤Ï "/usr/local/apache/sbin/suexec" ¤Ç¤¹¡£
    + ¥¤¥ó¥¹¥È¡¼¥ë»þ¤Ë¤Ï root + ¸¢¸Â¤¬É¬ÍפʤΤÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£wrapper ¤¬¥æ¡¼¥¶ ID + ¤òÀßÄꤹ¤ë¤¿¤á¤Ë¡¢½êÍ­¼Ô root + ¤Ç¤Î¥»¥Ã¥È¥æ¡¼¥¶ ID + ¥Ó¥Ã¥È¤ò¤½¤Î¥Õ¥¡¥¤¥ë¤Î¥â¡¼¥É¤ËÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ +

    + +

    °ÂÁ´¤Ê¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÀßÄꤹ¤ë
    + suEXEC ¥é¥Ã¥Ñ¡¼¤Ï¡¢--with-suexec-caller configure + ¥ª¥×¥·¥ç¥ó¤Ç»ØÄꤷ¤¿Àµ¤·¤¤¥æ¡¼¥¶¤Çµ¯Æ°¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Þ¤¹¤¬¡¢ + ¥·¥¹¥Æ¥à¾å¤Ç¤³¤Î¥Á¥§¥Ã¥¯¤¬¹Ô¤Ê¤ï¤ì¤ëÁ°¤Ë¡¢ + suEXEC ¤¬¸Æ¤Ö¥·¥¹¥Æ¥à¤ä¥é¥¤¥Ö¥é¥ê¤¬Àȼå¤Ç¤¢¤ë²ÄǽÀ­¤Ï»Ä¤ê¤Þ¤¹¡£Âй³ºö¤È¤·¤Æ¡¢ + °ìÈ̤ËÎɤ¤½¬´·¤È¤â¤µ¤ì¤¤¤Þ¤¹¤¬¡¢ + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤ò»È¤Ã¤Æ + Apache ¤Î¼Â¹Ô»þ¤Î¥°¥ë¡¼¥×¤Î¤ß¤¬ suEXEC ¤ò¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë + ¤¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£

    + +

    ¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ë¥µ¡¼¥Ð¤¬ÀßÄꤵ¤ì¤Æ¤¤¤¿¤È¤·¤Þ¤¹¡£

    + +

    + User www
    + Group webgroup
    +

    + +

    suexec ¤¬ "/usr/local/apache2/sbin/suexec" + ¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¼¡¤Î¤è¤¦¤ËÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +

    + +

    ¤³¤ì¤Ç Apache ¤¬¼Â¹Ô¤µ¤ì¤ë¥°¥ë¡¼¥×¤Î¤ß¤¬ + suEXEC ¥é¥Ã¥Ñ¡¼¤ò¼Â¹Ô¤Ç¤­¤ë¤È¤¤¤¦¤³¤È¤ò + ³Î¾Ú¤·¤Þ¤¹¡£

    +
    top
    +
    +

    suEXEC + ¤ÎÍ­¸ú²½¤È̵¸ú²½

    + +

    µ¯Æ°»þ¤Ë¡¢Apache ¤Ï --sbindir + ¥ª¥×¥·¥ç¥ó¤ÇÀßÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ç + suexec ¤òõ¤·¤Þ¤¹ + (¥Ç¥Õ¥©¥ë¥È¤Ï "/usr/local/apache/sbin/suexec") ¡£ + ŬÀÚ¤ËÀßÄꤵ¤ì¤¿ suEXEC ¤¬¤ß¤Ä¤«¤ë¤È¡¢ + ¥¨¥é¡¼¥í¥°¤Ë°Ê²¼¤Î¥á¥Ã¥»¡¼¥¸¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£

    + +

    + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) +

    + +

    ¥µ¡¼¥Ðµ¯Æ°»þ¤Ë¤³¤Î¥á¥Ã¥»¡¼¥¸¤¬½Ð¤Ê¤¤¾ì¹ç¡¢ + ÂçÄñ¤Ï¥µ¡¼¥Ð¤¬ÁÛÄꤷ¤¿¾ì½ê¤Ç wrapper ¥×¥í¥°¥é¥à¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¤«¡¢ + setuid root ¤È¤·¤Æ¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤Ê¤¤¤«¤Ç¤¹¡£

    + +

    suEXEC ¤Î»ÅÁȤߤò»ÈÍѤ¹¤ë¤Î¤¬½é¤á¤Æ¤Ç¡¢Apache ¤¬´û¤ËÆ°ºîÃæ¤Ç¤¢¤ì¤Ð¡¢ + Apache ¤ò kill ¤·¤Æ¡¢ºÆµ¯Æ°¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£HUP ¥·¥°¥Ê¥ë¤ä + USR1 ¥·¥°¥Ê¥ë¤Ë¤è¤ëñ½ã¤ÊºÆµ¯Æ°¤Ç¤ÏÉÔ½½Ê¬¤Ç¤¹¡£

    +

    suEXEC ¤ò̵¸ú¤Ë¤¹¤ë¾ì¹ç¤Ï¡¢suexec ¥Õ¥¡¥¤¥ë¤òºï½ü¤·¤Æ¤«¤é + Apache ¤ò kill ¤·¤ÆºÆµ¯Æ°¤·¤Þ¤¹¡£ +

    +
    top
    +
    +

    suEXEC ¤Î»ÈÍÑ

    + +

    CGI ¥×¥í¥°¥é¥à¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤¬ suEXEC ¥é¥Ã¥Ñ¡¼¤ò¸Æ¤Ö¤Î¤Ï¡¢ + SuexecUserGroup ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ´Þ¤à¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤«¡¢mod_userdir ¤Ë¤è¤ê + ½èÍý¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Î¾ì¹ç¤Ë¸Â¤ê¤Þ¤¹¡£

    + +

    ²¾ÁÛ¥Û¥¹¥È:
    + suEXEC wrapper ¤Î»È¤¤Êý¤È¤·¤Æ¡¢ + VirtualHost ÀßÄê¤Ç¤Î + SuexecUserGroup + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÄ̤·¤¿¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò¥á¥¤¥ó¥µ¡¼¥Ð¤Î¥æ¡¼¥¶ ID + ¤È°Û¤Ê¤ë¤â¤Î¤Ë¤¹¤ë¤È¡¢CGI ¥ê¥½¡¼¥¹¤Ø¤Î¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤Ï¡¢¤½¤Î + <VirtualHost> ¤Ç»ØÄꤵ¤ì¤¿ User ¤È + Group ¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤Þ¤¹¡£<VirtualHost> + ¤Ç¤³¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢ + ¥á¥¤¥ó¥µ¡¼¥Ð¤Î¥æ¡¼¥¶ ID ¤¬ÁÛÄꤵ¤ì¤Þ¤¹¡£

    + +

    ¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê:
    + mod_userdir ¤Ë¤è¤ê½èÍý¤µ¤ì¤¿¥ê¥¯¥¨¥¹¥È¤Ï + ¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê¤Î¥æ¡¼¥¶ ID ¤Ç CGI ¥×¥í¥°¥é¥à¤ò + ¼Â¹Ô¤¹¤ë¤¿¤á¤Ë suEXEC ¥é¥Ã¥Ñ¡¼¤ò¸Æ¤Ó¤Þ¤¹¡£ + ¤³¤Îµ¡Ç½¤òÆ°ºî¤µ¤»¤ë¤¿¤á¤ËɬÍפʤ³¤È¤Ï¡¢CGI + ¤ò¤½¤Î¥æ¡¼¥¶¤Ç¼Â¹Ô¤Ç¤­¤ë¤³¤È¡¢¤½¤Î¥¹¥¯¥ê¥×¥È¤¬¾åµ­¤Î¥»¥­¥å¥ê¥Æ¥£¸¡ºº¤ò¥Ñ¥¹¤Ç¤­¤ë¤³¤È¤Ç¤¹¡£ + ¥³¥ó¥Ñ¥¤¥ë + »þ¤Î¥ª¥×¥·¥ç¥ó --with-suexec-userdir ¤â»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    +
    top
    +
    +

    suEXEC ¤Î¥Ç¥Ð¥Ã¥°

    + +

    suEXEC wrapper ¤Ï¡¢¾åµ­¤Ç½Ò¤Ù¤¿ --with-suexec-logfile + ¥ª¥×¥·¥ç¥ó¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¥í¥°¾ðÊó¤òµ­Ï¿¤·¤Þ¤¹¡£ + wrapper ¤òŬÀÚ¤ËÀßÄê¡¢¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤Æ¤¤¤ë¤È»×¤¦¾ì¹ç¡¢ + ¤É¤³¤Ç̤äƤ¤¤ë¤«¸«¤è¤¦¤È¤¹¤ë¤Ê¤é¤³¤Î¥í¥°¤È¥µ¡¼¥Ð¤Î + ¥¨¥é¡¼¥í¥°¤ò¸«¤ë¤È¤è¤¤¤Ç¤·¤ç¤¦¡£

    +
    top
    +
    +

    ¤È¤«¤²¤ËÃí°Õ: ·Ù¹ð¤È»öÎã

    + +

    Ãí°Õ! + ¤³¤Î¾Ï¤Ï´°Á´¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤³¤Î¾Ï¤ÎºÇ¿·²þÄûÈǤˤĤ¤¤Æ¤Ï¡¢ + Apache ¥°¥ë¡¼¥×¤Î + ¥ª¥ó¥é¥¤¥ó¥É¥­¥å¥á¥ó¥ÈÈǤò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£ +

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê¤ËÀ©¸Â¤ò¤â¤¦¤±¤ë wrapper ¤Ë¤Ä¤¤¤Æ¡¢ + ¤¤¤¯¤Ä¤«¶½Ì£¿¼¤¤ÅÀ¤¬¤¢¤ê¤Þ¤¹¡£suEXEC ¤Ë´Ø¤¹¤ë "¥Ð¥°" + ¤òÊó¹ð¤¹¤ëÁ°¤Ë¤³¤ì¤é¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
      +
    • suEXEC ¤Î¶½Ì£¿¼¤¤ÅÀ
    • + +
    • ³¬Áع½Â¤¤ÎÀ©¸Â + + +

      + ¥»¥­¥å¥ê¥Æ¥£¤È¸úΨ¤ÎÍýͳ¤«¤é¡¢suEXEC ¤ÎÁ´¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤Ï + ²¾ÁÛ¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤ª¤±¤ëºÇ¾å°Ì¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥ÈÆ⤫¡¢ + ¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ë¤ª¤±¤ë¸Ä¡¹¤Î¥æ¡¼¥¶¤ÎºÇ¾å°Ì¤Î + ¥É¥­¥å¥á¥ó¥È¥ë¡¼¥ÈÆâ¤Ë»Ä¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + Î㤨¤Ð¡¢»Í¤Ä¤Î²¾ÁÛ¥Û¥¹¥È¤òÀßÄꤷ¤Æ¤¤¤ë¾ì¹ç¡¢ + ²¾ÁÛ¥Û¥¹¥È¤Î suEXEC ¤ËÍ­Íø¤Ê¤è¤¦¤Ë¡¢¥á¥¤¥ó¤Î Apache + ¥É¥­¥å¥á¥ó¥È³¬Áؤγ°Â¦¤ËÁ´¤Æ¤Î²¾ÁÛ¥Û¥¹¥È¤Î¥É¥­¥å¥á¥ó¥È¥ë¡¼¥È¤ò + ¹½ÃÛ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£(Îã¤Ï¸åÆüµ­ºÜ) +

      +
    • + +
    • suEXEC ¤Î PATH ´Ä¶­ÊÑ¿ô + + +

      + ¤³¤ì¤òÊѹ¹¤¹¤ë¤Î¤Ï´í¸±¤Ç¤¹¡£¤³¤Î»ØÄê¤Ë´Þ¤Þ¤ì¤ë³Æ¥Ñ¥¹¤¬ + ¿®Íê¤Ç¤­¤ë + ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¢¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£ + À¤³¦¤«¤é¤Î¥¢¥¯¥»¥¹¤Ë¤è¤ê¡¢Ã¯¤«¤¬¥Û¥¹¥È¾å¤Ç¥È¥í¥¤¤ÎÌÚÇÏ + ¤ò¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¤Ï¤·¤¿¤¯¤Ê¤¤¤Ç¤·¤ç¤¦¡£ +

      +
    • + +
    • suEXEC ¥³¡¼¥É¤Î²þ¤ + + +

      + ·«¤êÊÖ¤·¤Þ¤¹¤¬¡¢²¿¤ò¤ä¤í¤¦¤È¤·¤Æ¤¤¤ë¤«ÇÄ°®¤»¤º¤Ë¤³¤ì¤ò¤ä¤ë¤È + Â礭¤ÊÌäÂê¤ò°ú¤­µ¯¤³¤·¤«¤Í¤Þ¤»¤ó¡£ + ²Äǽ¤Ê¸Â¤êÈò¤±¤Æ¤¯¤À¤µ¤¤¡£ +

      +
    • +
    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/suexec.html.ko.euc-kr b/trunk/docs/manual/suexec.html.ko.euc-kr new file mode 100644 index 0000000000..5993422131 --- /dev/null +++ b/trunk/docs/manual/suexec.html.ko.euc-kr @@ -0,0 +1,534 @@ + + + +suEXEC Áö¿ø - Apache HTTP Server + + + + + +
    <-
    +

    suEXEC Áö¿ø

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    suEXEC ±â´ÉÀº ¾ÆÆÄÄ¡°¡ CGI¿Í + SSI ÇÁ·Î±×·¥À» À¥¼­¹ö¸¦ ½ÇÇàÇÑ »ç¿ëÀÚ ID°¡ + ¾Æ´Ñ ´Ù¸¥ »ç¿ëÀÚ ID·Î ½ÇÇàÇϵµ·Ï ÇÑ´Ù. º¸Åë CGI³ª SSI ÇÁ·Î±×·¥À» + ½ÇÇàÇϸé À¥¼­¹ö¸¦ ½ÇÇàÇÑ »ç¿ëÀÚ¿Í °°Àº »ç¿ëÀÚ·Î ½ÇÇàÇÑ´Ù.

    + +

    ÀÌ ±â´ÉÀ» ÀûÀýÈ÷ »ç¿ëÇÏ¸é »ç¿ëÀÚ°¡ Á÷Á¢ CGI³ª SSI ÇÁ·Î±×·¥À» + °³¹ßÇÏ°í ½ÇÇàÇÒ¶§ ¹ß»ýÇÒ ¼ö ÀÖ´Â º¸¾ÈÀ§ÇèÀ» »ó´çÈ÷ ÁÙÀÏ + ¼ö ÀÖ´Ù. ±×·¯³ª suEXEC°¡ ºÎÀûÀýÇÏ°Ô ¼³Á¤µÇ¸é ¸¹Àº ¹®Á¦¿Í + ÄÄÇ»ÅÍ¿¡ »õ·Î¿î º¸¾È ÇãÁ¡À» ¸¸µé ¼ö ÀÖ´Ù. ¸¸¾à setuid root + ÇÁ·Î±×·¥°ú ÀÌ·± ÇÁ·Î±×·¥ÀÇ º¸¾È ¹®Á¦¿¡ »ý¼ÒÇÏ´Ù¸é suEXEC¸¦ + »ç¿ëÇÏÁö¾Ê±æ Áø½ÉÀ¸·Î ¹Ù¶õ´Ù.

    +
    + +
    top
    +
    +

    ½ÃÀÛÇϱâ Àü¿¡

    + +

    ½ÃÀÛÇϱâ Àü¿¡ ¿ì¼± ¾ÆÆÄÄ¡±×·ì°ú ÀÌ ¹®¼­ÀÇ °¡Á¤À» ¹àÈù´Ù.

    + +

    ¸ÕÀú setuid¿Í setgid + ±â´ÉÀÌ °¡´ÉÇÑ À¯´Ð½º·ù ¿î¿µÃ¼Á¦¸¦ »ç¿ëÇÑ´Ù°í °¡Á¤ÇÑ´Ù. ¸ðµç + ¸í·É¾î ¿¹µéµµ °°Àº °¡Á¤À» ÇÑ´Ù. suEXEC¸¦ Áö¿øÇÏ´Â ´Ù¸¥ Ç÷¡ÆûÀ» + »ç¿ëÇÏ´Ù¸é ¼³Á¤ÀÌ ´Ù¸¦ ¼ö ÀÖ´Ù.

    + +

    µÎ¹ø°, ´ç½ÅÀÌ ÄÄÇ»ÅÍ º¸¾ÈÀÇ ±âº» °³³ä°ú °ü¸®¿¡ Àͼ÷ÇÏ´Ù°í + °¡Á¤ÇÑ´Ù. ¿©±â¿¡´Â setuid/setgid ±â´É°ú + À̵éÀÌ ½Ã½ºÅÛ°ú º¸¾È¿¡ ¹ÌÄ¡´Â ¿©·¯ ¿µÇâ¿¡ ´ëÇÑ ÀÌÇØ°¡ Æ÷ÇԵȴÙ.

    + +

    ¼¼¹ø°, suEXEC ÄÚµåÀÇ ¼öÁ¤ÇÏÁö¾ÊÀº + ¹öÀüÀ» »ç¿ëÇÑ´Ù°í °¡Á¤ÇÑ´Ù. °³¹ßÀÚ¿Í ¿©·¯ º£Å¸Å×½ºÅ͵éÀº + suEXEC¿Í °ü·ÃµÈ ¸ðµç Äڵ带 Á¶½É½º·´°Ô Á¶»çÇÏ°í °Ë»çÇß´Ù. + Äڵ带 °£´ÜÇÏ°Ô ÇÏ°í È®½ÇÇÑ ¾ÈÀüÀ» º¸ÀåÇϱâÀ§ÇØ ¸ðµç ÁÖÀǸ¦ + ±â¿ï¿´´Ù. ÀÌ Äڵ带 ¼öÁ¤ÇÏ¸é ¿¹»óÄ¡¸øÇÑ ¹®Á¦¿Í »õ·Î¿î º¸¾È + À§ÇèÀÌ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. º¸¾È ÇÁ·Î±×·¡¹Ö¿¡ ´ëÇØ ¸Å¿ì Àß ¾Ë°í + Äڵ带 »ìÆ캸±âÀ§ÇØ ¾ÆÆÄÄ¡±×·ì°ú ÀÛ¾÷À» °øÀ¯ÇÒ Àǻ簡 ¾ø´Ù¸é + suEXEC Äڵ带 ¼öÁ¤ÇÏÁö¾Ê±æ °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + +

    ³×¹ø°ÀÌÀÚ ¸¶Áö¸·À¸·Î, ¾ÆÆÄÄ¡±×·ìÀº suEXEC¸¦ ¾ÆÆÄÄ¡ + ±âº»¼³Ä¡¿¡ Æ÷ÇÔÇÏÁö ¾Ê±â·Î °áÁ¤Çß´Ù. °á±¹ + °ü¸®ÀÚ°¡ ÁÖÀǸ¦ ±â¿ï¿©¼­ suEXEC¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. suEXECÀÇ + ¿©·¯ ¼³Á¤À» Àß °í·ÁÇÑÈÄ °ü¸®ÀÚ´Â ÀϹÝÀûÀÎ ¼³Ä¡¹æ¹ýÀ» suEXEC¸¦ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. suEXEC ±â´ÉÀ» »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ º¸¾ÈÀ» Ã¥ÀÓÁö´Â + °ü¸®ÀÚ´Â ÀÌ ¼³Á¤°ªµéÀ» ÁÖÀÇÀÖ°Ô »ìÆ캸°í ÁöÁ¤ÇØ¾ß ÇÑ´Ù. + ÀÌ·± »ó¼¼ÇÑ °úÁ¤Àº suEXEC¸¦ »ç¿ëÇÒ¸¸Å­ ÁÖÀÇÀÖ°í ´ÜÈ£ÇÑ + »ç¶÷¸¸ÀÌ suEXEC¸¦ »ç¿ëÇϵµ·Ï ¾ÆÆÄÄ¡±×·ìÀÌ ¿øÇϱ⠶§¹®ÀÌ´Ù.

    + +

    ¾ÆÁ÷µµ »ç¿ëÇÏ±æ ¿øÇϴ°¡? ±×·±°¡? ÁÁ´Ù. ÀÌÁ¦ ½ÃÀÛÇÏÀÚ!

    +
    top
    +
    +

    suEXEC º¸¾È¸ðµ¨

    + +

    suEXEC¸¦ ±¸¼ºÇÏ°í ¼³Ä¡Çϱâ Àü¿¡ ¿ì¸®´Â º¸¾È¸ðµ¨À» ¸ÕÀú + ¼³¸íÇÑ´Ù. À̸¦ ÅëÇØ Á¤È®È÷ suEXEC ¾È¿¡¼­´Â ¹«½¼ ÀÏÀÌ ÀϾ¸ç + ½Ã½ºÅÛÀÇ º¸¾ÈÀ» À§ÇØ ¹«¾ùÀ» Á¶½ÉÇØ¾ß ÇÒÁö ´õ Àß ÀÌÇØÇÒ ¼ö + ÀÖ´Ù.

    + +

    suEXEC´Â ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ ºÎ¸£´Â setuid + "wrapper" ÇÁ·Î±×·¥À» ±â¹ÝÀ¸·Î ÇÑ´Ù. ÀÌ wrapper´Â °ü¸®ÀÚ°¡ + ÁÖ¼­¹ö¿Í ´Ù¸¥ userid·Î ½ÇÇàÇϵµ·Ï ¼³Á¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥¿¡ + HTTP ¿äûÀÌ ¿À¸é ºÒ¸°´Ù. ÀÌ·± ¿äûÀÌ ¿À¸é ¾ÆÆÄÄ¡´Â suEXEC + wrapper¿¡°Ô ÇÁ·Î±×·¥¸í°ú ÇÁ·Î±×·¥À» ½ÇÇàÇÒ »ç¿ëÀÚ¿Í ±×·ì + ID¸¦ Á¦°øÇÑ´Ù.

    + +

    ±×·¯¸é wrapper´Â ´ÙÀ½ °úÁ¤À» ÅëÇØ ¼º°ø°ú ½ÇÆи¦ °áÁ¤ÇÑ´Ù. + ÀÌ Á¶°ÇÁß Çϳª¶óµµ ½ÇÆÐÇϸé ÇÁ·Î±×·¥Àº ½ÇÆзΠ±â·ÏµÇ°í ¿À·ù¸¦ + ³»¸ç Á¾·áÇÑ´Ù. ½ÇÆÐÇÏÁö ¾ÊÀ¸¸é °úÁ¤À» °è¼ÓÇÑ´Ù:

    + +
      +
    1. + wrapper¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ°¡ ½Ã½ºÅÛÀÇ Á¤»óÀûÀÎ + »ç¿ëÀÚÀΰ¡? + +

      + wrapper¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ°¡ ½ÇÁ¦·Î ½Ã½ºÅÛÀÇ »ç¿ëÀÚÀÎÁö + È®ÀÎÇÑ´Ù. +

      +
    2. + +
    3. + ÀûÀýÇÑ ¼öÀÇ ¾Æ±Ô¸ÕÆ®·Î wrapper¸¦ ½ÇÇàÇϴ°¡? + +

      + wrapper´Â ÀûÀýÇÑ ¼öÀÇ ¾Æ±Ô¸ÕÆ®°¡ ÀÖ¾î¾ß¸¸ ½ÇÇàµÈ´Ù. + ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ ÀÌ °³¼ö¸¦ ¾È´Ù. wrapper°¡ ÀûÀýÇÑ ¼öÀÇ + ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¸øÇϸé ÇØÅ·µÇ¾ú°Å³ª ¾ÆÆÄÄ¡ÀÇ suEXEC¿¡ + ¹º°¡ ¹®Á¦°¡ ÀÖ´Â °ÍÀÌ´Ù. +

      +
    4. + +
    5. + ÀÌ »ç¿ëÀÚ°¡ wrapper¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëµÇ¾ú³ª? + +

      + ÀÌ »ç¿ëÀÚ°¡ wrapper¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëµÇ¾ú³ª? ¿ÀÁ÷ + ÇÑ »ç¿ëÀÚ(¾ÆÆÄÄ¡ »ç¿ëÀÚ)¸¸ÀÌ ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÒ + ¼ö ÀÖ´Ù. +

      +
    6. + +
    7. + ÁöÁ¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥ÀÌ ¾ÈÀüÇÏÁö¾ÊÀº °èÃþÂüÁ¶¸¦ + °¡Áö´Â°¡? + +

      + ÁöÁ¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥ÀÌ '/'·Î ½ÃÀÛÇϰųª µÞÂüÁ¶ + '..'À» °¡Áö´Â°¡? À̵éÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ÁöÁ¤ÇÑ CGI/SSI + ÇÁ·Î±×·¥Àº suEXEC ¹®¼­ root (¾Æ·¡ + --with-suexec-docroot=DIR Âü°í) + ³»¿¡ ÀÖ¾î¾ß ÇÑ´Ù. +

      +
    8. + +
    9. + ÁöÁ¤ÇÑ »ç¿ëÀÚ¸íÀÌ À¯È¿ÇÑ°¡? + +

      + ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ Á¸ÀçÇϴ°¡? +

      +
    10. + +
    11. + ÁöÁ¤ÇÑ ±×·ì¸íÀÌ À¯È¿ÇÑ°¡? + +

      + ÁöÁ¤ÇÑ ±×·ìÀÌ Á¸ÀçÇϴ°¡? +

      +
    12. + +
    13. + ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ superuser°¡ ¾Æ´Ñ°¡? + + +

      + ÇöÀç suEXEC´Â root°¡ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ¾øµµ·Ï ÇÑ´Ù. +

      +
    14. + +
    15. + ÁöÁ¤ÇÑ userid°¡ ÃÖ¼Ò ID ¼ýÀÚº¸´Ù Å«°¡? + +

      + ¼³Á¤¿¡¼­ ÃÖ¼Ò »ç¿ëÀÚ ID ¼ýÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. ±×·¡¼­ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Â useridÀÇ ÃÖ¼ÒÄ¡¸¦ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. "½Ã½ºÅÛ¿ë" °èÁ¤À» Á¦¿ÜÇÒ¶§ À¯¿ëÇÏ´Ù. +

      +
    16. + +
    17. + ÁöÁ¤ÇÑ ±×·ìÀÌ superuser ±×·ìÀÌ ¾Æ´Ñ°¡? + +

      + ÇöÀç suEXEC´Â root ±×·ìÀÌ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ¾øµµ·Ï ÇÑ´Ù. +

      +
    18. + +
    19. + ÁöÁ¤ÇÑ groupid°¡ ÃÖ¼Ò ID ¼ýÀÚº¸´Ù Å«°¡? + +

      + ¼³Á¤¿¡¼­ ÃÖ¼Ò ±×·ì ID ¼ýÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. ±×·¡¼­ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Â groupidÀÇ ÃÖ¼ÒÄ¡¸¦ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. "½Ã½ºÅÛ¿ë" ±×·ìÀ» Á¦¿ÜÇÒ¶§ À¯¿ëÇÏ´Ù. +

      +
    20. + +
    21. + wrapper°¡ ¼º°øÀûÀ¸·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ¿Í ±×·ìÀÌ + µÉ ¼ö Àִ°¡? + +

      + ÀÌ ´Ü°è¿¡¼­ ÇÁ·Î±×·¥Àº setuid¿Í setgid È£ÃâÀ» ÇÏ¿© + ÁöÁ¤ÇÑ »ç¿ëÀÚ¿Í ±×·ìÀÌ µÈ´Ù. ¶Ç, ±×·ì Á¢±Ù¸ñ·ÏÀº + »ç¿ëÀÚ°¡ ÇØ´çµÈ ¸ðµç ±×·ìÀ¸·Î ÃʱâÈ­µÈ´Ù. +

      +
    22. + +
    23. + CGI/SSI ÇÁ·Î±×·¥ÀÌ ÀÖ´Â µð·ºÅ丮·Î µð·ºÅ丮¸¦ + º¯°æÇÒ ¼ö Àִ°¡? + +

      + µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾Ê´Ù¸é ÆÄÀÏÀÌ ÀÖÀ» ¼ö ¾ø´Ù. ÀÌ°÷À¸·Î + µð·ºÅ丮¸¦ º¯°æÇÒ ¼ö ¾ø´Ù¸é µð·ºÅ丮´Â Á¸ÀçÇÏÁö ¾ÊÀ» + °ÍÀÌ´Ù. +

      +
    24. + +
    25. + µð·ºÅ丮°¡ ¾ÆÆÄÄ¡ À¥°ø°£ ¾È¿¡ Àִ°¡? + +

      + ¼­¹öÀÇ ÀϹÝÀûÀÎ ºÎºÐÀ» ¿äûÇÒ °æ¿ì ¿äûÇÏ´Â µð·ºÅ丮°¡ + suEXEC ¹®¼­ root ¾Æ·¡ Àִ°¡? UserDirÀ» ¿äûÇÒ °æ¿ì + ¿äûÇÏ´Â µð·ºÅ丮°¡ suEXEC userdir·Î ¼³Á¤ÇÑ (suEXEC ¼³Á¤ ¿É¼Ç Âü°í) µð·ºÅ丮 + ¾Æ·¡¿¡ Àִ°¡? +

      +
    26. + +
    27. + ´Ù¸¥ ´©±¸µµ µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ ¾ø´Â°¡? + +

      + µð·ºÅ丮¸¦ ´Ù¸¥ »ç¶÷¿¡°Ô ¿­¾îµÎ±æ ¿øÇÏÁö¾Ê´Â´Ù. ¿ÀÁ÷ + ¼ÒÀ¯ÀÚ¸¸ÀÌ µð·ºÅ丮 ³»¿ëÀ» º¯°æÇÒ ¼ö ÀÖ´Ù. +

      +
    28. + +
    29. + ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ Á¸ÀçÇϴ°¡? + +

      + Á¸ÀçÇÏÁö¾Ê´Ù¸é ½ÇÇàÇÒ ¼öµµ ¾ø´Ù. +

      +
    30. + +
    31. + ´Ù¸¥ ´©±¸µµ ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥¿¡ ¾²±â±ÇÇÑÀÌ + ¾ø´Â°¡? + +

      + ¼ÒÀ¯ÀÚ¿Ü ´©±¸µµ CGI/SSI ÇÁ·Î±×·¥À» º¯°æÇÏ±æ ¿øÇÏÁö¾Ê´Â´Ù. +

      +
    32. + +
    33. + ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ setuid³ª setgid°¡ + ¾Æ´Ñ°¡? + +

      + ¿ì¸®´Â ÇÁ·Î±×·¥ÀÌ ´Ù½Ã UID/GID¸¦ º¯°æÇÏ±æ ¿øÇÏÁö¾Ê´Â´Ù. +

      +
    34. + +
    35. + ÁöÁ¤ÇÑ »ç¿ëÀÚ/±×·ìÀÌ ÇÁ·Î±×·¥ÀÇ »ç¿ëÀÚ/±×·ì°ú °°Àº°¡? + +

      + »ç¿ëÀÚ°¡ ÆÄÀÏÀÇ ¼ÒÀ¯ÀÚÀΰ¡? +

      +
    36. + +
    37. + ¾ÈÀüÇÑ µ¿ÀÛÀ» À§ÇØ ÇÁ·Î¼¼½ºÀÇ È¯°æº¯¼ö¸¦ û¼ÒÇÒ + ¼ö Àִ°¡? + +

      + suEXEC´Â (¼³Á¤¿¡¼­ Á¤ÀÇÇÑ) ¾ÈÀüÇÑ ½ÇÇà PATH¸¦ Àâ°í, + (À̰͵µ ¼³Á¤¿¡¼­ Á¤ÀÇ) ¾ÈÀüÇÑ È¯°æº¯¼ö ¸ñ·Ï¿¡ ¿­°ÅµÈ + º¯¼ö¸¸ ³²±â°í ÇÁ·Î¼¼½ºÀÇ È¯°æº¯¼ö¸¦ Áö¿î´Ù. +

      +
    38. + +
    39. + ¼º°øÀûÀ¸·Î ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥À» ½ÇÇàÇÒ + ¼ö Àִ°¡? + +

      + ¿©±â¼­ suEXEC°¡ ³¡³ª°í ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÑ´Ù. +

      +
    40. +
    + +

    ÀÌ°ÍÀÌ suEXEC wrapper º¸¾È¸ðµ¨ÀÇ Ç¥ÁØ µ¿ÀÛÀÌ´Ù. ´Ù¼Ò + ¾ö°ÝÇÏ°í CGI/SSI ¼³°è¿¡ »õ·Î¿î Á¦ÇÑÀÌ µÇÁö¸¸, º¸¾ÈÀ» ¿°µÎ¿¡ + µÎ°í ÇѴܰ辿 Á¶½É½º·´°Ô ¸¸µé¾îÁ³´Ù.

    + +

    ÀÌ º¸¾È ¸ðµ¨ÀÌ ¼­¹ö ¼³Á¤¿¡ ¾î¶² Á¦ÇÑÀ» ÁÖ´ÂÁö¿Í ÀûÀýÇÑ + suEXEC ¼³Á¤À¸·Î ¾î¶² º¸¾È À§ÇèÀ» ÇÇÇÒ ¼ö ÀÖ´ÂÁö¿¡ ´ëÇØ ÀÌ + ¹®¼­ÀÇ "´Ù½Ã Çѹø Á¶½ÉÇ϶ó" ÀýÀ» + Âü°íÇ϶ó.

    +
    top
    +
    +

    suEXEC ±¸¼º°ú ¼³Ä¡

    + +

    ÀÌÁ¦ Àç¹ÌÀÖ´Â ³»¿ëÀÌ ½ÃÀÛÇÑ´Ù.

    + +

    suEXEC ±¸¼º ¿É¼Ç
    +

    + +
    +
    --enable-suexec
    + +
    ÀÌ ¿É¼ÇÀº ±âº»ÀûÀ¸·Î ¼³Ä¡µÇ°Å³ª È°¼ºÈ­µÇÁö¾Ê´Â suEXEC + ±â´ÉÀ» È°¼ºÈ­ÇÑ´Ù. APACI°¡ suEXEC¸¦ ¹Þ¾ÆµéÀÌ·Á¸é + --enable-suexec ¿É¼Ç¿Ü¿¡ + --with-suexec-xxxxx ¿É¼ÇÀÌ ÃÖ¼ÒÇÑ ÇÑ°³ + ÇÊ¿äÇÏ´Ù.
    + +
    --with-suexec-bin=PATH
    + +
    suexec ¹ÙÀ̳ʸ® °æ·Î´Â º¸¾È»ó ÀÌÀ¯·Î + ¼­¹ö¿¡ ±â·ÏµÇ¾ß ÇÑ´Ù. °æ·Î ±âº»°ªÀ» ¹«½ÃÇÏ·Á¸é ÀÌ ¿É¼ÇÀ» + »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î + --with-suexec-bin=/usr/sbin/suexec
    + +
    --with-suexec-caller=UID
    + +
    º¸Åë ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¸í. ÇÁ·Î±×·¥À» + ½ÇÇàÇÒ ¼ö ÀÖ´Â À¯ÀÏÇÑ »ç¿ëÀÚ´Ù.
    + +
    --with-suexec-userdir=DIR
    + +
    suEXEC Á¢±ÙÀÌ Çã¿ëµÇ´Â »ç¿ëÀÚ È¨µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮¸¦ + ÁöÁ¤ÇÑ´Ù. ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ½ÇÇàÆÄÀÏÀ» »ç¿ëÀÚÀÇ + suEXEC·Î ½ÇÇà¹Ç·Î, ¸ðµç ÇÁ·Î±×·¥ÀÌ "¾ÈÀüÇؾß" ÇÑ´Ù. (¿¹¸¦ + µé¾î, °ª¿¡ "*"ÀÌ ¾ø´Â) "°£´ÜÇÑ" UserDir Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù¸é + °°Àº °ªÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù. UserDir Áö½Ã¾î°¡ passwd ÆÄÀÏ¿¡ + ³ª¿Â »ç¿ëÀÚ È¨µð·ºÅ丮¿Í ´Ù¸£¸é suEXEC´Â Á¤»óÀûÀ¸·Î + ÀÛµ¿ÇÏÁö ¾Ê´Â´Ù. ±âº»°ªÀº "public_html"ÀÌ´Ù.
    + °¡»óÈ£½ºÆ®µéÀÌ °¢°¢ ´Ù¸¥ UserDirÀ» »ç¿ëÇÑ´Ù¸é ¸ðµÎ ÇÑ + ºÎ¸ð µð·ºÅ丮 ¾È¿¡ ÀÖµµ·Ï Á¤ÀÇÇØ¾ß ÇÏ°í, ±× ºÎ¸ð µð·ºÅ丮¸íÀ» + ¿©±â Àû´Â´Ù. ÀÌ·¸°Ô Á¤ÀÇÇÏÁö ¾ÊÀ¸¸é, "~userdir" + cgi ¿äûÀÌ ÀÛµ¿ÇÏÁö ¾Ê´Â´Ù!
    + +
    --with-suexec-docroot=DIR
    + +
    ¾ÆÆÄÄ¡ÀÇ DocumentRoot¸¦ Á¤ÀÇÇÑ´Ù. ÀÌ´Â suEXEC°¡ »ç¿ëÇÒ + ¼ö ÀÖ´Â (UserDirsÀ» Á¦¿ÜÇÑ) À¯ÀÏÇÑ °ø°£ÀÌ´Ù. ±âº» µð·ºÅ丮´Â + --datadir °ª¿¡ "/htdocs"À» ºÙÀÎ °ÍÀÌ´Ù. + ¿¹¸¦ µé¾î "--datadir=/home/apache"·Î + ±¸¼ºÇß´Ù¸é suEXEC wrapper´Â document root·Î + "/home/apache/htdocs" µð·ºÅ丮¸¦ »ç¿ëÇÑ´Ù.
    + +
    --with-suexec-uidmin=UID
    + +
    suEXEC¿¡¼­ ÁöÁ¤°¡´ÉÇÑ »ç¿ëÀÚÀÇ ÃÖ¼Ò UID¸¦ Á¤ÀÇÇÑ´Ù. + ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ 500À̳ª 100ÀÌ ÀûÀýÇÏ´Ù. ±âº»°ªÀº + 100ÀÌ´Ù.
    + +
    --with-suexec-gidmin=GID
    + +
    suEXEC¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ±×·ìÀÇ ÃÖ¼Ò GID¸¦ Á¤ÀÇÇÑ´Ù. + ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ 100ÀÌ ÀûÀýÇϹǷΠÀÌ °ªÀÌ ±âº»°ªÀÌ´Ù.
    + +
    --with-suexec-logfile=FILE
    + +
    ¸ðµç suEXEC ÀÛµ¿°ú ¿À·ù¸¦ (°¨½Ã³ª µð¹ö±ë ¸ñÀû¿¡ À¯¿ëÇÑ) + ±â·ÏÇÒ ·Î±×ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ·Î±×ÆÄÀÏÀÇ À̸§Àº + "suexec_log"ÀÌ°í Ç¥ÁØ ·Î±×ÆÄÀÏ µð·ºÅ丮¿¡ + (--logfiledir) À§Ä¡ÇÑ´Ù.
    + +
    --with-suexec-safepath=PATH
    + +
    CGI ½ÇÇàÆÄÀÏ¿¡ ³Ñ°ÜÁú ¾ÈÀüÇÑ PATH ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù. + ±âº»°ªÀº "/usr/local/bin:/usr/bin:/bin"ÀÌ´Ù.
    +
    + +

    suEXEC wrapper¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡Çϱâ
    + --enable-suexec ¿É¼ÇÀ¸·Î suEXEC ±â´ÉÀ» °¡´ÉÇÏ°ÔÇÑ + °æ¿ì make ¸í·É¾î¸¦ ½ÇÇàÇϸé suexec + ½ÇÇàÆÄÀÏÀÌ (¾ÆÆÄÄ¡¿Í ÇÔ²²) ÀÚµ¿À¸·Î ¸¸µé¾îÁø´Ù.
    + ¸ðµç°ÍÀ» ÄÄÆÄÀÏÇÑ ÈÄ make install ¸í·É¾î¸¦ + ½ÇÇàÇÏ¿© ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ¹ÙÀ̳ʸ®ÆÄÀÏ suexec´Â + --sbindir ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ ¼³Ä¡µÈ´Ù. + ±âº» À§Ä¡´Â "/usr/local/apache2/sbin/suexec"ÀÌ´Ù.
    + ¼³Ä¡ °úÁ¤¿¡ root ±ÇÇÑÀÌ ÇÊ¿äÇÔÀ» + ÁÖÀÇÇ϶ó. wrapper°¡ »ç¿ëÀÚ ID¸¦ ¼³Á¤ÇϱâÀ§Çؼ­´Â ¼ÒÀ¯ÀÚ°¡ + rootÀÌ°í ÆÄÀϸðµå·Î setuserid ½ÇÇàºñÆ®°¡ + ¼³Á¤µÇ¾ß ÇÑ´Ù.

    + +

    ÆíÁýÁõÀûÀÎ ±ÇÇѼ³Á¤
    + suEXEC wrapper´Â ÀÚ½ÅÀ» ½ÇÇàÇÑ »ç¿ëÀÚ°¡ ±¸¼º ¿É¼Ç + --with-suexec-caller·Î ÁöÁ¤ÇÑ ¿Ã¹Ù¸¥ »ç¿ëÀÚÀÎÁö + È®ÀÎÀ» ÇÏÁö¸¸, ÀÌ °Ë»ç ÀÌÀü¿¡ suEXEC°¡ »ç¿ëÇÏ´Â ½Ã½ºÅÛÈ£Ãâ + ȤÀº ¶óÀ̺귯¸® ÇÔ¼ö°¡ Á¶À۵ǾúÀ» ¼ö ÀÖ´Ù. À̸¦ ´ëºñÇϸç + ÀϹÝÀûÀ¸·Î ÁÁÀº ½À°üÀ̹ǷΠ¿ÀÁ÷ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â ±×·ì¸¸ÀÌ + suEXEC¸¦ ½ÇÇàÇÒ ¼ö ÀÖµµ·Ï ÆÄÀϽýºÅÛ ±ÇÇÑÀ» ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, À¥¼­¹ö¸¦ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÏ°í:

    + +

    + User www
    + Group webgroup
    +

    + +

    suexec¸¦ "/usr/local/apache2/sbin/suexec"¿¡ + ¼³Ä¡ÇÏ¿´´Ù¸é, ´ÙÀ½À» ½ÇÇàÇØ¾ß ÇÑ´Ù:

    + +

    + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +

    + +

    ±×·¯¸é ¿ÀÁ÷ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â ±×·ì¸¸ÀÌ suEXEC wrapper¸¦ + ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    suEXEC Å°°í ²ô±â

    + +

    ¾ÆÆÄÄ¡´Â ½ÃÀÛÇÒ¶§ --sbindir ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ + µð·ºÅ丮¿¡¼­ suexec ÆÄÀÏÀ» (±âº»°ª + "/usr/local/apache2/sbin/suexec") ã´Â´Ù. ¾ÆÆÄÄ¡°¡ + Á¤»óÀûÀ¸·Î ±¸¼ºµÈ suEXEC wrapper¸¦ ¹ß°ßÇÏ¸é ¿À·ù ·Î±×(error + log)¿¡ ´ÙÀ½°ú °°ÀÌ Ãâ·ÂÇÑ´Ù:

    + +

    + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) +

    + +

    ¼­¹ö ½ÃÀÛÁß¿¡ ÀÌ·± ¹®±¸¸¦ ¾ø´Ù¸é ¼­¹ö´Â ±â´ëÇÑ Àå¼Ò¿¡¼­ + wrapper ÇÁ·Î±×·¥À» ãÁö ¸øÇ߰ųª, ½ÇÇàÆÄÀÏÀÌ setuid + root·Î ¼³Ä¡µÇÁö¾Ê¾Ò±â ¶§¹®ÀÏ °ÍÀÌ´Ù.

    + +

    óÀ½À¸·Î suEXEC ±â´ÉÀ» »ç¿ëÇÏ°í ½Í°í ÀÌ¹Ì ¾ÆÆÄÄ¡ ¼­¹ö°¡ + ½ÇÇàÁßÀ̶ó¸é, ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í ´Ù½Ã ½ÃÀÛÇØ¾ß ÇÑ´Ù. °£´ÜÈ÷ + HUPÀ̳ª USR1 ½Ã±×³Î·Î Àç½ÃÀÛÇÏ´Â °ÍÀ¸·Î´Â ÃæºÐÇÏÁö ¾Ê´Ù.

    +

    suEXEC¸¦ ¾È»ç¿ëÇÏ·Á¸é suexec ÆÄÀÏÀ» Áö¿îÈÄ + ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í Àç½ÃÀÛÇØ¾ß ÇÑ´Ù.

    +
    top
    +
    +

    suEXEC »ç¿ëÇϱâ

    + +

    CGI ÇÁ·Î±×·¥ ¿äûÀÇ °æ¿ì SuexecUserGroup Áö½Ã¾î¸¦ + »ç¿ëÇÑ °¡»óÈ£½ºÆ®¿¡ ¿äûÀ» ÇÏ¿´°Å³ª mod_userdirÀÌ + ¿äûÀ» ó¸®ÇÏ´Â °æ¿ì¿¡¸¸ suEXEC wrapper¸¦ È£ÃâÇÑ´Ù.

    + +

    °¡»óÈ£½ºÆ®:
    suEXEC wrapper¸¦ + »ç¿ëÇÏ´Â ÇÑ°¡Áö ¹æ¹ýÀº VirtualHost Á¤ÀÇ¿¡ SuexecUserGroup Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ÀÌ Áö½Ã¾î¸¦ ÁÖ¼­¹ö »ç¿ëÀÚ ID¿Í ´Ù¸£°Ô + ¼³Á¤Çϸé CGI ÀÚ¿øÀÇ ¸ðµç ¿äûÀÌ <VirtualHost>¿¡¼­ + ÁöÁ¤ÇÑ User¿Í GroupÀ¸·Î ½ÇÇàµÈ´Ù. ÀÌ + Áö½Ã¾îµéÀÌ <VirtualHost>¿¡ ¾øÀ¸¸é ÁÖ¼­¹ö + userid¸¦ »ç¿ëÇÑ´Ù.

    + +

    »ç¿ëÀÚ µð·ºÅ丮:
    + mod_userdirÀÌ ¿äûÀ» ó¸®ÇÑ´Ù¸é suEXEC + wrapper¸¦ È£ÃâÇÏ¿©, ¿äûÇÑ »ç¿ëÀÚ µð·ºÅ丮¿¡ ÇØ´çÇÏ´Â »ç¿ëÀÚ + ID·Î CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù. ÀÌ ±â´ÉÀÌ µ¿ÀÛÇÏ·Á¸é »ç¿ëÀÚ + ID·Î CGI¸¦ ½ÇÇàÇÒ ¼ö ÀÖ°í ½ºÅ©¸³Æ®°¡ À§ÀÇ º¸¾È + °Ë»ç Ç׸ñÀ» ¸¸Á·ÇØ¾ß ÇÑ´Ù. ±¸¼º + ¿É¼Ç --with-suexec-userdirÀ» Âü°íÇ϶ó.

    top
    +
    +

    suEXEC µð¹ö±ëÇϱâ

    + +

    suEXEC wrapper´Â ·Î±× Á¤º¸¸¦ À§¿¡¼­ ´Ù·é + --with-suexec-logfile ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ + ¾´´Ù. wrapper¸¦ ¿Ã¹Ù·Î ±¸¼ºÇÏ°í ¼³Ä¡Çß´Ù¸é ¾îµð¼­ À߸øµÇ¾ú´ÂÁö + ÀÌ ·Î±×ÆÄÀÏ¿Í ¼­¹öÀÇ error_log¸¦ »ìÆìºÁ¶ó.

    + +
    top
    +
    +

    ´Ù½Ã Çѹø Á¶½ÉÇ϶ó: °æ°í¿Í ¿¹Á¦

    + +

    ÁÖÀÇ! ÀÌ ¼½¼ÇÀº ¿ÏÀüÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù. + ¾ÆÆÄÄ¡±×·ìÀÇ ¿Â¶óÀÎ + ¹®¼­¿¡¼­ ÀÌ ¹®¼­ÀÇ ÃÖ½ÅÆÇÀ» Âü°íÇ϶ó.

    + +

    wrapper°¡ ¼­¹ö ¼³Á¤À» Á¦¾àÇÏ´Â ¸î°¡Áö Èï¹Ì·Î¿î Á¡ÀÌ ÀÖ´Ù. + suEXEC¿Í °ü·ÃµÈ "¹ö±×"¸¦ º¸°íÇϱâ Àü¿¡ À̵éÀ» »ìÆ캸±æ ¹Ù¶õ´Ù.

    + +
      +
    • suEXEC Á¦¾à »çÇ×
    • + +
    • + µð·ºÅ丮 ±¸Á¶ Á¦ÇÑ + +

      + º¸¾È°ú È¿À²¼ºÀ» À§ÇØ ¸ðµç suEXEC ¿äûÀº °¡»óÈ£½ºÆ®ÀÇ + °æ¿ì ÃÖ»óÀ§ document root ȤÀº userdir ¿äûÀÇ °æ¿ì + ÃÖ»óÀ§ °³ÀÎ document root ¾È¿¡¼­ ¹ß»ýÇØ¾ß ÇÑ´Ù. ¿¹¸¦ + µé¾î, °¡»óÈ£½ºÆ® ³×°³¸¦ ¼³Á¤Çß´Ù¸é °¡»óÈ£½ºÆ®¿¡¼­ + suEXEC¸¦ ÀÌ¿ëÇϱâÀ§ÇØ °¡»óÈ£½ºÆ®ÀÇ document root¸¦ + ÁÖ ¾ÆÆÄÄ¡ ¹®¼­ °èÃþ±¸Á¶ ¹Û¿¡ ¼³Á¤ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. + (¿¹Á¦´Â ´ÙÀ½¿¡.) +

      +
    • + +
    • + suEXECÀÇ PATH ȯ°æº¯¼ö + +

      + º¯°æÇϸé À§ÇèÇÒ ¼ö ÀÖ´Ù. ¿©±â¿¡ Æ÷ÇÔÇÏ´Â ¸ðµç °æ·Î°¡ + ¹ÏÀ» ¼ö ÀÖ´Â µð·ºÅ丮ÀÎÁö È®ÀÎÇ϶ó. + ÀÌ Áö±¸»óÀÇ ´©±º°¡°¡ ±×°÷¿¡ ÀÖ´Â Æ®·ÎÀ̸ñ¸¶¸¦ ½ÇÇàÇϱæ + ¿øÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. +

      +
    • + +
    • + suEXEC ÄÚµå ¼öÁ¤Çϱâ + +

      + ¹Ýº¹Çؼ­ ¸»ÇÏÁö¸¸, ´ç½ÅÀÌ ¹«¾ùÀ» ÇÏ´ÂÁö ¸ð¸£°í ½ÃµµÇÑ´Ù¸é + Å« ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ¾î¶² °æ¿ì¿¡µµ + ¼öÁ¤ÇÏÁö¸¶¶ó. +

      +
    • +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/suexec.xml b/trunk/docs/manual/suexec.xml new file mode 100644 index 0000000000..b007d0fddd --- /dev/null +++ b/trunk/docs/manual/suexec.xml @@ -0,0 +1,598 @@ + + + + + + + + + + suEXEC Support + + +

    The suEXEC feature provides + Apache users the ability + to run CGI and SSI programs + under user IDs different from the user ID of the calling + web-server. Normally, when a CGI or SSI program executes, it + runs as the same user who is running the web server.

    + +

    Used properly, this feature can reduce + considerably the security risks involved with allowing users to + develop and run private CGI or SSI programs. However, if suEXEC + is improperly configured, it can cause any number of problems + and possibly create new holes in your computer's security. If + you aren't familiar with managing setuid root programs + and the security issues they present, we highly recommend that + you not consider using suEXEC.

    +
    + +
    Before we begin + +

    Before jumping head-first into this document, + you should be aware of the assumptions made on the part of the + Apache Group and this document.

    + +

    First, it is assumed that you are using a UNIX + derivative operating system that is capable of + setuid and setgid operations. + All command examples are given in this regard. Other platforms, + if they are capable of supporting suEXEC, may differ in their + configuration.

    + +

    Second, it is assumed you are familiar with + some basic concepts of your computer's security and its + administration. This involves an understanding of + setuid/setgid operations and the various + effects they may have on your system and its level of + security.

    + +

    Third, it is assumed that you are using an + unmodified version of suEXEC code. All code + for suEXEC has been carefully scrutinized and tested by the + developers as well as numerous beta testers. Every precaution + has been taken to ensure a simple yet solidly safe base of + code. Altering this code can cause unexpected problems and new + security risks. It is highly recommended you + not alter the suEXEC code unless you are well versed in the + particulars of security programming and are willing to share + your work with the Apache Group for consideration.

    + +

    Fourth, and last, it has been the decision of + the Apache Group to NOT make suEXEC part of + the default installation of Apache. To this end, suEXEC + configuration requires of the administrator careful attention + to details. After due consideration has been given to the + various settings for suEXEC, the administrator may install + suEXEC through normal installation methods. The values for + these settings need to be carefully determined and specified by + the administrator to properly maintain system security during + the use of suEXEC functionality. It is through this detailed + process that the Apache Group hopes to limit suEXEC + installation only to those who are careful and determined + enough to use it.

    + +

    Still with us? Yes? Good. Let's move on!

    +
    + +
    suEXEC Security Model + +

    Before we begin configuring and installing + suEXEC, we will first discuss the security model you are about + to implement. By doing so, you may better understand what + exactly is going on inside suEXEC and what precautions are + taken to ensure your system's security.

    + +

    suEXEC is based on a setuid + "wrapper" program that is called by the main Apache web server. + This wrapper is called when an HTTP request is made for a CGI + or SSI program that the administrator has designated to run as + a userid other than that of the main server. When such a + request is made, Apache provides the suEXEC wrapper with the + program's name and the user and group IDs under which the + program is to execute.

    + +

    The wrapper then employs the following process + to determine success or failure -- if any one of these + conditions fail, the program logs the failure and exits with an + error, otherwise it will continue:

    + +
      +
    1. + Is the user executing this wrapper a valid user of + this system? + +

      + This is to ensure that the user executing the wrapper is + truly a user of the system. +

      +
    2. + +
    3. + Was the wrapper called with the proper number of + arguments? + +

      + The wrapper will only execute if it is given the proper + number of arguments. The proper argument format is known + to the Apache web server. If the wrapper is not receiving + the proper number of arguments, it is either being + hacked, or there is something wrong with the suEXEC + portion of your Apache binary. +

      +
    4. + +
    5. + Is this valid user allowed to run the + wrapper? + +

      + Is this user the user allowed to run this wrapper? Only + one user (the Apache user) is allowed to execute this + program. +

      +
    6. + +
    7. + Does the target CGI or SSI program have an unsafe + hierarchical reference? + +

      + Does the target CGI or SSI program's path contain a leading + '/' or have a '..' backreference? These are not allowed; the + target CGI/SSI program must reside within suEXEC's document + root (see --with-suexec-docroot=DIR + below). +

      +
    8. + +
    9. + Is the target user name valid? + +

      + Does the target user exist? +

      +
    10. + +
    11. + Is the target group name valid? + +

      + Does the target group exist? +

      +
    12. + +
    13. + Is the target user NOT superuser? + + +

      + Presently, suEXEC does not allow root + to execute CGI/SSI programs. +

      +
    14. + +
    15. + Is the target userid ABOVE the minimum ID + number? + +

      + The minimum user ID number is specified during + configuration. This allows you to set the lowest possible + userid that will be allowed to execute CGI/SSI programs. + This is useful to block out "system" accounts. +

      +
    16. + +
    17. + Is the target group NOT the superuser + group? + +

      + Presently, suEXEC does not allow the root + group to execute CGI/SSI programs. +

      +
    18. + +
    19. + Is the target groupid ABOVE the minimum ID + number? + +

      + The minimum group ID number is specified during + configuration. This allows you to set the lowest possible + groupid that will be allowed to execute CGI/SSI programs. + This is useful to block out "system" groups. +

      +
    20. + +
    21. + Can the wrapper successfully become the target user + and group? + +

      + Here is where the program becomes the target user and + group via setuid and setgid calls. The group access list + is also initialized with all of the groups of which the + user is a member. +

      +
    22. + +
    23. + Can we change directory to the one in which the target + CGI/SSI program resides? + +

      + If it doesn't exist, it can't very well contain files. If we + can't change directory to it, it might aswell not exist. +

      +
    24. + +
    25. + Is the directory within the Apache + webspace? + +

      + If the request is for a regular portion of the server, is + the requested directory within suEXEC's document root? If + the request is for a UserDir, is the requested directory + within the directory configured as suEXEC's userdir (see + suEXEC's configuration options)? +

      +
    26. + +
    27. + Is the directory NOT writable by anyone + else? + +

      + We don't want to open up the directory to others; only + the owner user may be able to alter this directories + contents. +

      +
    28. + +
    29. + Does the target CGI/SSI program exist? + +

      + If it doesn't exists, it can't very well be executed. +

      +
    30. + +
    31. + Is the target CGI/SSI program NOT writable + by anyone else? + +

      + We don't want to give anyone other than the owner the + ability to change the CGI/SSI program. +

      +
    32. + +
    33. + Is the target CGI/SSI program NOT setuid or + setgid? + +

      + We do not want to execute programs that will then change + our UID/GID again. +

      +
    34. + +
    35. + Is the target user/group the same as the program's + user/group? + +

      + Is the user the owner of the file? +

      +
    36. + +
    37. + Can we successfully clean the process environment + to ensure safe operations? + +

      + suEXEC cleans the process' environment by establishing a + safe execution PATH (defined during configuration), as + well as only passing through those variables whose names + are listed in the safe environment list (also created + during configuration). +

      +
    38. + +
    39. + Can we successfully become the target CGI/SSI program + and execute? + +

      + Here is where suEXEC ends and the target CGI/SSI program begins. +

      +
    40. +
    + +

    This is the standard operation of the + suEXEC wrapper's security model. It is somewhat stringent and + can impose new limitations and guidelines for CGI/SSI design, + but it was developed carefully step-by-step with security in + mind.

    + +

    For more information as to how this security + model can limit your possibilities in regards to server + configuration, as well as what security risks can be avoided + with a proper suEXEC setup, see the "Beware the Jabberwock" section of this + document.

    +
    + +
    Configuring & Installing + suEXEC + +

    Here's where we begin the fun.

    + +

    suEXEC configuration + options
    +

    + +
    +
    --enable-suexec
    + +
    This option enables the suEXEC feature which is never + installed or activated by default. At least one + --with-suexec-xxxxx option has to be provided + together with the --enable-suexec option to let + APACI accept your request for using the suEXEC feature.
    + +
    --with-suexec-bin=PATH
    + +
    The path to the suexec binary must be hard-coded + in the server for security reasons. Use this option to override + the default path. e.g. + --with-suexec-bin=/usr/sbin/suexec
    + +
    --with-suexec-caller=UID
    + +
    The username under which + Apache normally runs. This is the only user allowed to + execute this program.
    + +
    --with-suexec-userdir=DIR
    + +
    Define to be the subdirectory under users' home + directories where suEXEC access should be allowed. All + executables under this directory will be executable by suEXEC + as the user so they should be "safe" programs. If you are + using a "simple" UserDir directive (ie. one without a "*" in + it) this should be set to the same value. suEXEC will not + work properly in cases where the UserDir directive points to + a location that is not the same as the user's home directory + as referenced in the passwd file. Default value is + "public_html".
    + If you have virtual hosts with a different UserDir for each, + you will need to define them to all reside in one parent + directory; then name that parent directory here. If + this is not defined properly, "~userdir" cgi requests will + not work!
    + +
    --with-suexec-docroot=DIR
    + +
    Define as the DocumentRoot set for Apache. This will be + the only hierarchy (aside from UserDirs) that can be used for + suEXEC behavior. The default directory is the --datadir + value with the suffix "/htdocs", e.g. if you configure + with "--datadir=/home/apache" the directory + "/home/apache/htdocs" is used as document root for the suEXEC + wrapper.
    + +
    --with-suexec-uidmin=UID
    + +
    Define this as the lowest UID allowed to be a target user + for suEXEC. For most systems, 500 or 100 is common. Default + value is 100.
    + +
    --with-suexec-gidmin=GID
    + +
    Define this as the lowest GID allowed to be a target + group for suEXEC. For most systems, 100 is common and + therefore used as default value.
    + +
    --with-suexec-logfile=FILE
    + +
    This defines the filename to which all suEXEC + transactions and errors are logged (useful for auditing and + debugging purposes). By default the logfile is named + "suexec_log" and located in your standard logfile directory + (--logfiledir).
    + +
    --with-suexec-safepath=PATH
    + +
    Define a safe PATH environment to pass to CGI + executables. Default value is + "/usr/local/bin:/usr/bin:/bin".
    +
    + +

    Compiling and installing the suEXEC + wrapper
    + If you have enabled the suEXEC feature with the + --enable-suexec option the suexec binary + (together with Apache itself) is automatically built if you execute + the make command.
    + After all components have been built you can execute the + command make install to install them. The binary image + suexec is installed in the directory defined by the + --sbindir option. The default location is + "/usr/local/apache2/sbin/suexec".
    + Please note that you need root + privileges for the installation step. In order + for the wrapper to set the user ID, it must be installed as + owner root and must have the setuserid + execution bit set for file modes.

    + +

    Setting paranoid permissions
    + Although the suEXEC wrapper will check to ensure that its + caller is the correct user as specified with the + --with-suexec-caller configure + option, there is + always the possibility that a system or library call suEXEC uses + before this check may be exploitable on your system. To counter + this, and because it is best-practise in general, you should use + filesystem permissions to ensure that only the group Apache + runs as may execute suEXEC.

    + +

    If for example, your web-server is configured to run as:

    + + + User www
    + Group webgroup
    +
    + +

    and suexec is installed at + "/usr/local/apache2/sbin/suexec", you should run:

    + + + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +
    + +

    This will ensure that only the group Apache runs as can even + execute the suEXEC wrapper.

    +
    + +
    Enabling & Disabling + suEXEC + +

    Upon startup of Apache, it looks for the file + suexec in the directory defined by the + --sbindir option (default is + "/usr/local/apache/sbin/suexec"). If Apache finds a properly + configured suEXEC wrapper, it will print the following message + to the error log:

    + + + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) + + +

    If you don't see this message at server startup, the server is + most likely not finding the wrapper program where it expects + it, or the executable is not installed setuid root.

    + +

    If you want to enable the suEXEC mechanism for the first time + and an Apache server is already running you must kill and + restart Apache. Restarting it with a simple HUP or USR1 signal + will not be enough.

    +

    If you want to disable suEXEC you should kill and restart + Apache after you have removed the suexec file.

    +
    + +
    Using suEXEC + +

    Requests for CGI programs will call the suEXEC wrapper only if + they are for a virtual host containing a SuexecUserGroup directive or if + they are processed by mod_userdir.

    + +

    Virtual Hosts:
    One way to use the suEXEC + wrapper is through the SuexecUserGroup directive in + VirtualHost definitions. By + setting this directive to values different from the main server + user ID, all requests for CGI resources will be executed as the + User and Group defined for that VirtualHost. If this + directive is not specified for a VirtualHost then the main server userid + is assumed.

    + +

    User directories:
    Requests that are + processed by mod_userdir will call the suEXEC + wrapper to execute CGI programs under the userid of the requested + user directory. The only requirement needed for this feature to + work is for CGI execution to be enabled for the user and that the + script must meet the scrutiny of the security + checks above. See also the + --with-suexec-userdir compile + time option.

    + +
    Debugging suEXEC + +

    The suEXEC wrapper will write log information + to the file defined with the --with-suexec-logfile + option as indicated above. If you feel you have configured and + installed the wrapper properly, have a look at this log and the + error_log for the server to see where you may have gone astray.

    + +
    + +
    Beware the Jabberwock: + Warnings & Examples + +

    NOTE! This section may not be + complete. For the latest revision of this section of the + documentation, see the Apache Group's Online + Documentation version.

    + +

    There are a few points of interest regarding + the wrapper that can cause limitations on server setup. Please + review these before submitting any "bugs" regarding suEXEC.

    + +
      +
    • suEXEC Points Of Interest
    • + +
    • + Hierarchy limitations + +

      + For security and efficiency reasons, all suEXEC requests + must remain within either a top-level document root for + virtual host requests, or one top-level personal document + root for userdir requests. For example, if you have four + VirtualHosts configured, you would need to structure all + of your VHosts' document roots off of one main Apache + document hierarchy to take advantage of suEXEC for + VirtualHosts. (Example forthcoming.) +

      +
    • + +
    • + suEXEC's PATH environment variable + +

      + This can be a dangerous thing to change. Make certain + every path you include in this define is a + trusted directory. You don't want to + open people up to having someone from across the world + running a trojan horse on them. +

      +
    • + +
    • + Altering the suEXEC code + +

      + Again, this can cause Big Trouble if you + try this without knowing what you are doing. Stay away + from it if at all possible. +

      +
    • +
    + +
    + +
    diff --git a/trunk/docs/manual/suexec.xml.ja b/trunk/docs/manual/suexec.xml.ja new file mode 100644 index 0000000000..cb40e4c9e6 --- /dev/null +++ b/trunk/docs/manual/suexec.xml.ja @@ -0,0 +1,598 @@ + + + + + + + + + + suEXEC $B%5%]!<%H(B + + +

    suEXEC + $B5!G=$K$h$j!"(BApache $B%f!<%6$O(B Web $B%5!<%P$rCGI $B%W%m%0%i%`$d(B SSI + $B%W%m%0%i%`$rl9g!"DL>o$O(B web $B%5!<%P$HF1$8%f!<%6$G + +

    $BE,@Z$K;HMQ$9$k$H!"$3$N5!G=$K$h$j%f!<%6$,8DJL$N(B CGI + $B$d(B SSI $B%W%m%0%i%`$r3+H/$7e$N4m81$r!"(B + $B$+$J$j8:$i$9$3$H$,$G$-$^$9!#$7$+$7!"(BsuEXEC $B$N@_Dj$,ITE,@Z$@$H!"(B + $BB?$/$NLdBj$,@8$8!"$"$J$?$N%3%s%T%e!<%?$K?7$7$$%;%-%e%j%F%#%[!<%k$r(B + $B:n$C$F$7$^$&2DG=@-$,$"$j$^$9!#$"$J$?$,(B setuid root + $B$5$l$?%W%m%0%i%`$H!"$=$l$i$+$i@8$8$k%;%-%e%j%F%#>e$NLdBj$N4IM}$K(B + $B>\$7$/$J$$$h$&$J$i!"(BsuEXEC $B$N;HMQ$r8!F$$7$J$$$h$&$K6/$/?d>)$7$^$9!#(B +

    +
    + +
    $B;O$a$kA0$K(B + +

    $B$3$NJ8=q$N@hF,$KHt$VA0$K!"(BApache + $B%0%k!<%W$H$3$NJ8=q$G$N2>Dj$rCN$C$F$*$/$Y$-$G$7$g$&!#(B +

    + +

    $BBh(B 1 $B$K!"$"$J$?$,(B setuid $B$H(B + setgid $BA`:n$,2DG=$J(B UNIX + $BM3Mh$N%*%Z%l!<%F%#%s%0%7%9%F%`$r;H$C$F$$$k$3$H$rA[Dj$7$F$$$^$9!#(B + $B$3$l$O!"$9$Y$F$N%3%^%s%INc$K$"$F$O$^$j$^$9!#(B + $B$=$NB>$N%W%i%C%H%[!<%`$G$O!"$b$7(B suEXEC + $B$,%5%]!<%H$5$l$F$$$?$H$7$F$b@_Dj$O0[$J$k$+$b$7$l$^$;$s!#(B

    + +

    $BBh(B 2 $B$K!"$"$J$?$,;HMQCf$N%3%s%T%e!<%?$N(B + $B%;%-%e%j%F%#$K4X$9$k4pK\E*$J35G0$H!"$=$l$i$N4IM}$K$D$$$F>\$7$$$3$H$r(B + $BA[Dj$7$F$$$^$9!#$3$l$O!"(Bsetuid/setgid + $BA`:n!"$"$J$?$N%7%9%F%`>e$G$N$=$NA`:n$K$h$kMM!9$J8z2L!"(B + $B%;%-%e%j%F%#%l%Y%k$K$D$$$F$"$J$?$,M}2r$7$F$$$k$H$$$&$3$H$r4^$_$^$9!#(B +

    + +

    $BBh(B 3 $B$K!"(B$B2~B$$5$l$F$$$J$$(B suEXEC + $B%3!<%I$N;HMQ$rA[Dj$7$F$$$^$9!#(BsuEXEC $B$N%3!<%I$O!"(B + $BB?$/$N%Y!<%?%F%9%?$@$1$G$J$/!"3+H/Z$5$l$^$9!#$3$N%3!<%I$r2~JQ$9$k$3$H$G!"(B + $BM=4|$5$l$J$$LdBj$d?7$7$$%;%-%e%j%F%#>e$N4m81$,@8$8$k$3$H$,$"$j$^$9!#(B + $B%;%-%e%j%F%#%W%m%0%i%_%s%0$N>\:Y$KDL$8$F$$$F!"(B + $B:#8e$N8!F$$N$?$a$K@.2L$r(B Apache + $B%0%k!<%W$H6&M-$7$h$&$H;W$&$N$G$J$1$l$P!"(BsuEXEC + $B%3!<%I$OJQ$($J$$$3$H$r(B $B6/$/(B$B?d>)$7$^$9!#(B

    + +

    $BBh(B 4 $B$K!"$3$l$,:G8e$G$9$,!"(BsuEXEC $B$r(B Apache + $B$N%G%U%)%k%H%$%s%9%H!<%k$K$O(B$B4^$a$J$$(B$B$3$H$,(B + Apache $B%0%k!<%W$G7hDj$5$l$F$$$^$9!#$3$l$O!"(BsuEXEC + $B$N@_Dj$K$O4IM}\:Y$K$o$?$k?5=E$JCm0U$,I,MW$@$+$i$G$9!#(B + suEXEC $B$NMM!9$J@_Dj$K$D$$$F8!F$$,=*$o$l$P!"4IM}o$N%$%s%9%H!<%kJ}K!$G%$%s%9%H!<%k$9$k$3$H$,$G$-$^$9!#(B + $B$3$l$i$N@_DjCM$O!"(BsuEXEC + $B5!G=$N;HMQCf$K%7%9%F%`%;%-%e%j%F%#$rE,@Z$KJ]$D$?$a$K!"(B + $B4IM}\:Y$Jl9g$K8B$C$F$$$?$@$-$?$$$H9M$($F$$$^$9!#(B +

    + +

    $B$=$l$G$b?J$_$^$9$+(B? $B$h$m$7$$!#$G$O!"@h$X?J$_$^$7$g$&(B!

    +
    + +
    suEXEC $B%;%-%e%j%F%#%b%G%k(B + +

    suEXEC $B$N@_Dj$H%$%s%9%H!<%k$r;O$a$kA0$K!"(B + $B$^$:Z$9$k$?$a$K7Y9p$5$l$k$3$H$r(B + $B$h$/M}2r$7$F$*$$$?J}$,$h$$$G$7$g$&!#(B

    + +

    suEXEC $B$O!"(BApache web + $B%5!<%P$+$i8F$S=P$5$l$k(B setuid $B$5$l$?(B "wrapper" + $B%W%m%0%i%`$,4pK\$H$J$C$F$$$^$9!#@_7W$7$?(B CGI$B!"$^$?$O(B SSI + $B%W%m%0%i%`$X$N(B HTTP $B%j%/%(%9%H$,$"$k$H!"$3$N(B wrapper + $B$,8F$S=P$5$l$^$9!#$3$N$h$&$J%j%/%(%9%H$,$"$k$H!"(BApache + $B$O$=$N%W%m%0%i%`$,$H%f!<%6(B ID $B$H%0%k!<%W(B + ID $B$r;XDj$7$F(B suEXEC wrapper $B$r + +

    $B$=$l$+$i!"(Bwrapper $B$O@.8y$^$?$O<:GT$r7hDj$9$k$?$a(B + $B0J2<$N=hM}$r9T$J$$$^$9!#$3$l$i$N>uBV$N$&$A0l$D$G$b<:GT$7$?>l9g!"(B + $B%W%m%0%i%`$O<:GT$r%m%0$K5-O?$7$F%(%i!<$G=*N;$7$^$9!#(B + $B$=$&$G$J$1$l$P!"8e$N=hM}$,B3$1$i$l$^$9!#(B

    + +
      +
    1. + wrapper + $B$r + +

      + $B$3$l$O!"(Bwrapper $B$rZ$9$k$?$a$G$9!#(B +

      +
    2. + + +
    3. + wrapper $B$,E,@Z$J?t$N0z?t$G8F$S=P$5$l$?$+(B? + + +

      + wrapper $B$OE,@Z$J?t$N0z?t$,M?$($i$l$?>l9g$K$N$_ +

    4. + +
    5. + $B$3$N@5Ev$J%f!<%6$O(B wrapper + $B$N + +

      + $B$3$N%f!<%6$O(B wrapper $B +

    6. + +
    7. + $BBP>]$N(B CGI, SSI $B%W%m%0%i%`$,0BA4$G$J$$3,AX$N;2>H$r$7$F$$$k$+(B? + + +

      + $BBP>]$N(B CGI, SSI $B%W%m%0%i%`$,(B '/' $B$+$i;O$^$k!"$^$?$O(B + '..' $B$K$h$k;2>H$r9T$J$C$F$$$^$9$+(B? $B$3$l$i$O5v2D$5$l$^$;$s!#(B + $BBP>]$N%W%m%0%i%`$O(B suEXEC $B$N%I%-%e%a%s%H%k!<%H(B + ($B2<5-$N(B --with-suexec-docroot=DIR $B$r;2>H(B) + $BFb$KB8:_$7$J$1$l$P$J$j$^$;$s!#(B +

      +
    8. + +
    9. + $BBP>]$H$J$k%f!<%6L>$O@5Ev$J$b$N$+(B? + +

      + $BBP>]$H$J$k%f!<%6L>$OB8:_$7$F$$$^$9$+(B? +

      +
    10. + +
    11. + $BBP>]$H$J$k%0%k!<%WL>$O@5Ev$J$b$N$+(B? + +

      + $BBP>]$H$J$k%0%k!<%WL>$OB8:_$7$F$$$^$9$+(B? +

      +
    12. + +
    13. + $BL\E*$N%f!<%6$O%9!<%Q!<%f!<%6$G$O(B$B$J$$(B$B$+(B? + + +

      + $B:#$N$H$3$m!"(BsuEXEC $B$O(B root $B$K$h$k(B CGI/SSI + $B%W%m%0%i%`$N +

    14. + +
    15. + $BBP>]$H$J$k%f!<%6(B ID $B$O!":G>.$N(B ID + $BHV9f$h$j$b(B$BBg$-$$(B$B$+(B? + +

      + $B:G>.%f!<%6(B ID $BHV9f$O@_Dj;~$K;XDj$5$l$^$9!#$3$l$O!"(B + CGI/SSI $B%W%m%0%i%`.CM$G$9!#$3$l$O(B + "system" $BMQ$N%"%+%&%s%H$rJD$a=P$9$N$KM-8z$G$9!#(B +

      +
    16. + +
    17. + $BBP>]$H$J$k%0%k!<%W$O%9!<%Q!<%f!<%6$N%0%k!<%W$G$O(B + $B$J$$(B$B$+(B? + +

      + $B:#$N$H$3$m!"(BsuEXEC $B$O(B 'root' $B%0%k!<%W$K$h$k(B CGI/SSI + $B%W%m%0%i%`$N +

    18. + +
    19. + $BBP>]$H$J$k%0%k!<%W(B ID $B$O:G>.$N(B ID + $BHV9f$h$j$b(B$BBg$-$$(B$B$+(B? + +

      + $B:G>.%0%k!<%W(B ID $BHV9f$O@_Dj;~$K;XDj$5$l$^$9!#$3$l$O!"(B + CGI/SSI $B%W%m%0%i%`.CM$G$9!#(B + $B$3$l$O(B "system" $BMQ$N%0%k!<%W$rJD$a=P$9$N$KM-8z$G$9!#(B +

      +
    20. + +
    21. + wrapper $B$,@5>o$KBP>]$H$J$k%f!<%6$H%0%k!<%W$K$J$l$k$+(B? + + +

      + $B$3$3$G!"(Bsetuid $B$H(B setgid + $B$N5/F0$K$h$j%W%m%0%i%`$OBP>]$H$J$k%f!<%6$H%0%k!<%W$K$J$j$^$9!#(B + $B%0%k!<%W%"%/%;%9%j%9%H$O!"(B + $B%f!<%6$,B0$7$F$$$k$9$Y$F$N%0%k!<%W$G=i4|2=$5$l$^$9!#(B +

      +
    22. + +
    23. + CGI/SSI $B%W%m%0%i%`$,CV$+$l$F$$$k%G%#%l%/%H%j$K0\F0(B + (change directory) $B$G$-$k$+(B? + +

      + $B%G%#%l%/%H%j$,B8:_$7$J$$$J$i!"$=$N%U%!%$%k$bB8:_$7$J$$$+$b$7$l$^$;$s!#(B + $B%G%#%l%/%H%j$K0\F0$G$-$J$$$N$G$"$l$P!"$*$=$i$/B8:_$b$7$J$$$G$7$g$&!#(B +

      +
    24. + +
    25. + $B%G%#%l%/%H%j$,(B Apache $B$N%I%-%e%a%s%H%D%j! + +

      + $B%j%/%(%9%H$,%5!<%PFb$N$b$N$G$"$l$P!"(B + $BMW5a$5$l$?%G%#%l%/%H%j$,(B suEXEC $B$N%I%-%e%a%s%H%k!<%HG[2<$K$"$j$^$9$+(B? + $B%j%/%(%9%H$,(B UserDir $B$N$b$N$G$"$l$P!"MW5a$5$l$?%G%#%l%/%H%j$,(B suEXEC + $B$N%f!<%6$N%I%-%e%a%s%H%k!<%HG[2<$K$"$j$^$9$+(B? + (suEXEC $B@_Dj%*%W%7%g%s(B $B;2>H(B) +

      +
    26. + +
    27. + $B%G%#%l%/%H%j$rB>$N%f!<%6$,=q$-9~$a$k$h$&$K$J$C$F(B + $B$$$J$$(B$B$+(B? + +

      + $B%G%#%l%/%H%j$rB>%f!<%6$K3+J|$7$J$$$h$&$K$7$^$9!#(B + $B=jM-%f!<%6$@$1$,$3$N%G%#%l%/%H%j$NFbMF$r2~JQ$G$-$k$h$&$K$7$^$9!#(B +

      +
    28. + + +
    29. + $BBP>]$H$J$k(B CGI/SSI $B%W%m%0%i%`$OB8:_$9$k$+(B? + +

      + $BB8:_$7$J$1$l$P +

    30. + +
    31. + $BBP>]$H$J$k(B CGI/SSI $B%W%m%0%i%`%U%!%$%k$,B>%"%+%&%s%H$+$i(B + $B=q$-9~$a$k$h$&$K$J$C$F(B$B$$$J$$(B$B$+(B? + +

      + $B=jM- +

    32. + + +
    33. + $BBP>]$H$J$k(B CGI/SSI $B%W%m%0%i%`$,(B setuid $B$^$?$O(B setgid + $B$5$l$F(B$B$$$J$$(B$B$+(B? + +

      + UID/GID $B$r:FEYJQ99$7$F$N%W%m%0%i%` +

    34. + + +
    35. + $BBP>]$H$J$k%f!<%6(B/$B%0%k!<%W$,%W%m%0%i%`$N(B + $B%f!<%6(B/$B%0%k!<%W$HF1$8$+(B? + +

      + $B%f!<%6$,$=$N%U%!%$%k$N=jM- +

    36. + +
    37. + $B0BA4$JF0:n$rJ]>Z$9$k$?$a$N4D6-JQ?t%/%j%"$,2DG=$+(B? + + +

      + suEXEC $B$O!"0BA4$J4D6-JQ?t$N%j%9%H(B + ($B$3$l$i$O@_Dj;~$K:n@.$5$l$^$9(B) $BFb$NJQ?t$H$7$FEO$5$l$k0BA4$J(B + PATH $BJQ?t(B ($B@_Dj;~$K;XDj$5$l$^$9(B) $B$r@_Dj$9$k$3$H$G!"(B + $B%W%m%;%9$N4D6-JQ?t$r%/%j%"$7$^$9!#(B +

      +
    38. + + +
    39. + $BBP>]$H$J$k(B CGI/SSI $B%W%m%0%i%`$r(B exec $B$7$F + + +

      + $B$3$3$G(B suEXEC $B$,=*N;$7!"BP>]$H$J$k%W%m%0%i%`$,3+;O$5$l$^$9!#(B +

      +
    40. +
    + +

    $B$3$3$^$G$,(B suEXEC $B$N(B wrapper + $B$K$*$1$k%;%-%e%j%F%#%b%G%k$NI8=`E*$JF0:n$G$9!#$b$&>/$787=E$K(B + CGI/SSI $B@_7W$K$D$$$F$N?7$7$$@)8B$d5,Dj$r/$7$:$D3+H/$5$l$F$-$^$7$?!#(B +

    + +

    $B$3$N%;%-%e%j%F%#%b%G%k$rMQ$$$F(B + $B%5!<%P@_Dj;~$K$I$N$h$&$K5v$9$3$H$r@)8B$9$k$+!"$^$?!"(BsuEXEC + $B$rE,@Z$K@_Dj$9$k$H$I$N$h$&$J%;%-%e%j%F%#>e$N4m81$rHr$1$i$l$k$+$K(B + $B4X$9$k$h$j>\$7$$>pJs$K$D$$$F$O!"(B"$B$H$+$2$KCm0U(B" + (Beware the Jabberwock) $B$N>O$r;2>H$7$F$/$@$5$$!#(B +

    +
    + +
    suEXEC + $B$N@_Dj$H%$%s%9%H!<%k(B + +

    $B$3$3$+$i3Z$7$/$J$j$^$9!#(B

    + +

    suEXEC + $B@_Dj%*%W%7%g%s(B
    +

    + +
    +
    --enable-suexec
    + +
    $B$3$N%*%W%7%g%s$O!"%G%U%)%k%H$G$O%$%s%9%H!<%k$5$l$:!"(B + $BM-8z$K$O$J$i$J$$(B suEXEC $B5!G=$rM-8z$K$7$^$9!#(B + suEXEC $B$r;H$&$h$&$K(B APACI $B$KMW5a$9$k$K$O!"(B--enable-suexec + $B%*%W%7%g%s$K$"$o$;$F>/$J$/$H$b0l$D$O(B --with-suexec-xxxxx + $B%*%W%7%g%s$,;XDj$5$l$J$1$l$P$J$j$^$;$s!#(B
    + +
    --with-suexec-bin=PATH
    + +
    $B%;%-%e%j%F%#>e$NM}M3$K$h$j!"(Bsuexec $B%P%$%J%j$N%Q%9$O%5!<%P$K(B + $B%O!<%I%3!<%I$5$l$F$$$kI,MW$,$"$j$^$9!#%G%U%)%k%H$N%Q%9$r(B + $BJQ$($?$$$H$-$O$3$N%*%W%7%g%s$r;H$C$F$/$@$5$$!#(B$BNc$($P(B$B!"(B + --with-suexec-bin=/usr/sbin/suexec $B$N$h$&$K!#(B
    + +
    --with-suexec-caller=UID
    + +
    Apache $B$rDL>oF0:n$5$;$k(B$B%f!<%6L>(B$B$r;XDj$7$^$9!#(B + $B$3$N%f!<%6$@$1$,(B suexec $B$N + +
    --with-suexec-userdir=DIR
    + +
    suEXEC $B$,%"%/%;%9$r5v$5$l$k%f!<%6%[!<%`%G%#%l%/%H%jG[2<$N(B + $B%5%V%G%#%l%/%H%j$r;XDj$7$^$9!#(B + $B$3$N%G%#%l%/%H%j0J2<$NA4l9g(B + ($B$9$J$o$A(B "*" $B$r4^$^$J$$$b$N(B)$B!"$3$l$HF1$8CM$r@_Dj$9$Y$-$G$9!#(B + Userdir $B%G%#%l%/%F%#%V$,$=$N%f!<%6$N%Q%9%o!<%I%U%!%$%kFb$N(B + $B%[!<%`%G%#%l%/%H%j$HF1$8>l=j$r;X$7$F$$$J$1$l$P!"(B + suEXEC $B$OE,@Z$KF0:n$7$^$;$s!#%G%U%)%k%H$O(B "public_html" $B$G$9!#(B +
    + $B3F(B UserDir $B$,0[$J$C$?2>A[%[%9%H$r@_Dj$7$F$$$k>l9g!"(B + $B$=$l$i$rA4$F0l$D$N?F%G%#%l%/%H%j$K4^$a$F!"(B + $B$=$N?F%G%#%l%/%H%j$NL>A0$r$3$3$G;XDj$9$kI,MW$,$"$j$^$9!#(B + $B$3$N$h$&$K;XDj$5$l$J$1$l$P(B "~userdir" cgi + $B$X$N%j%/%(%9%H$,F0:n$7$^$;$s!#(B
    + +
    --with-suexec-docroot=DIR
    + +
    Apache $B$N%I%-%e%a%s%H%k!<%H$r@_Dj$7$^$9!#$3$l$,(B suEXEC + $B$NF0:n$G;HMQ$9$kM#0l$N%G%#%l%/%H%j3,AX$K$J$j$^$9(B (UserDir + $B$N;XDj$OJL(B)$B!#%G%U%)%k%H$G$O(B --datedir $B$K(B "/htdocs" + $B$H$$$&%5%U%#%C%/%9$r$D$1$?$b$N$G$9!#(B + "--datadir=/home/apache" $B$H$7$F@_Dj$9$k$H!"(B + suEXEC wrapper $B$K$H$C$F(B "/home/apache/htdocs" + $B$,%I%-%e%a%s%H%k!<%H$H$7$F;H$o$l$^$9!#(B
    + +
    --with-suexec-uidmin=UID
    + +
    suEXEC $B$NBP>]%f!<%6$H$7$F5v$5$l$k(B UID $B$N:G>.CM$r;XDj$7$^$9!#(B + $BBgDq$N%7%9%F%`$G$O(B 500 $B$+(B 100 $B$,0lHLE*$G$9!#(B + $B%G%U%)%k%HCM$O(B 100 $B$G$9!#(B
    + +
    --with-suexec-gidmin=GID
    + +
    suEXEC $B$NBP>]%0%k!<%W$H$7$F5v$5$l$k(B GID + $B$N:G>.CM$r;XDj$7$^$9!#BgDq$N%7%9%F%`$G$O(B 100 $B$,0lHLE*$J$N$G!"(B + $B%G%U%)%k%HCM$H$7$F$b(B 100 $B$,;H$o$l$F$$$^$9!#(B
    + +
    --with-suexec-logfile=FILE
    + +
    suEXEC $B$N=hM}$H%(%i!<$,5-O?$5$l$k%U%!%$%kL>$r;XDj$7$^$9!#(B + ($B4F::$d%G%P%C%0L\E*$KM-MQ(B) + $B%G%U%)%k%H$G$O%m%0%U%!%$%k$O(B "suexec_log" $B$H$$$&L>A0$G!"(B + $BI8=`$N%m%0%U%!%$%k%G%#%l%/%H%j(B (--logfiledir) $B$KCV$+$l$^$9!#(B +
    + +
    --with-suexec-safepath=PATH
    + +
    CGI $B +
    + +

    suEXEC wrapper + $B$N%3%s%Q%$%k$H%$%s%9%H!<%k(B
    + --enable-suexec $B%*%W%7%g%s$G(B suEXEC $B5!G=$rM-8z$K$9$k$H!"(B + "make" $B%3%^%s%I$rsuexec $B$N%P%$%J%j(B (Apache $B<+BN$b(B) + $B$,<+F0E*$K:n@.$5$l$^$9!#(B +
    + $B$9$Y$F$N9=@.MWAG$,:n@.$5$l$k$H!"$=$l$i$N%$%s%9%H!<%k$K$O(B + make install $B%3%^%s%I$,suexec + $B$O(B --sbindir $B%*%W%7%g%s$G;XDj$5$l$?%G%#%l%/%H%j$K%$%s%9%H!<%k$5$l$^$9!#(B + $B%G%U%)%k%H$N>l=j$O(B "/usr/local/apache/sbin/suexec" $B$G$9!#(B
    + $B%$%s%9%H!<%k;~$K$O(B root + $B8"8B$,I,MW$J$N$GCm0U$7$F$/$@$5$$!#(Bwrapper $B$,%f!<%6(B ID + $B$r@_Dj$9$k$?$a$K!"=jM-root + $B$G$N%;%C%H%f!<%6(B ID + $B%S%C%H$r$=$N%U%!%$%k$N%b!<%I$K@_Dj$7$J$1$l$P$J$j$^$;$s!#(B +

    + +

    $B0BA4$J%Q!<%_%C%7%g%s$r@_Dj$9$k(B
    + suEXEC $B%i%C%Q!<$O!"(B--with-suexec-caller configure + $B%*%W%7%g%s$G;XDj$7$?@5$7$$%f!<%6$G5/F0$5$l$F$$$k$3$H$r3NG'$7$^$9$,!"(B + $B%7%9%F%`>e$G$3$N%A%'%C%/$,9T$J$o$l$kA0$K!"(B + suEXEC $B$,8F$V%7%9%F%`$d%i%$%V%i%j$,@H + +

    $B$?$H$($P!" + + + User www
    + Group webgroup
    +
    + +

    suexec $B$,(B "/usr/local/apache2/sbin/suexec" + $B$K%$%s%9%H!<%k$5$l$F$$$?>l9g!" + + + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +
    + +

    $B$3$l$G(B Apache $B$,Z$7$^$9!#(B

    +
    + +
    suEXEC + $B$NM-8z2=$HL58z2=(B + +

    $B5/F0;~$K!"(BApache $B$O(B --sbindir + $B%*%W%7%g%s$G@_Dj$5$l$?%G%#%l%/%H%j$G(B + suexec $B$rC5$7$^$9(B + ($B%G%U%)%k%H$O(B "/usr/local/apache/sbin/suexec") $B!#(B + $BE,@Z$K@_Dj$5$l$?(B suEXEC $B$,$_$D$+$k$H!"(B + $B%(%i!<%m%0$K0J2<$N%a%C%;!<%8$,=PNO$5$l$^$9!#(B

    + + + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) + + +

    $B%5!<%P5/F0;~$K$3$N%a%C%;!<%8$,=P$J$$>l9g!"(B + $BBgDq$O%5!<%P$,A[Dj$7$?>l=j$G(B wrapper $B%W%m%0%i%`$,8+$D$+$i$J$+$C$?$+!"(B + setuid root $B$H$7$F%$%s%9%H!<%k$5$l$F$$$J$$$+$G$9!#(B

    + +

    suEXEC $B$N;EAH$_$r;HMQ$9$k$N$,=i$a$F$G!"(BApache $B$,4{$KF0:nCf$G$"$l$P!"(B + Apache $B$r(B kill $B$7$F!":F5/F0$7$J$1$l$P$J$j$^$;$s!#(BHUP $B%7%0%J%k$d(B + USR1 $B%7%0%J%k$K$h$kC1=c$J:F5/F0$G$OIT==J,$G$9!#(B

    +

    suEXEC $B$rL58z$K$9$k>l9g$O!"(Bsuexec $B%U%!%$%k$r:o=|$7$F$+$i(B + Apache $B$r(B kill $B$7$F:F5/F0$7$^$9!#(B +

    +
    + +
    suEXEC $B$N;HMQ(B + +

    CGI $B%W%m%0%i%`$X$N%j%/%(%9%H$,(B suEXEC $B%i%C%Q!<$r8F$V$N$O!"(B + SuexecUserGroup $B%G%#%l%/%F%#%V$r(B + $B4^$`%P!<%A%c%k%[%9%H$X$N%j%/%(%9%H$+!"(Bmod_userdir $B$K$h$j(B + $B=hM}$5$l$?%j%/%(%9%H$N>l9g$K8B$j$^$9!#(B

    + +

    $B2>A[%[%9%H(B:
    + suEXEC wrapper $B$N;H$$J}$H$7$F!"(B + VirtualHost $B@_Dj$G$N(B + SuexecUserGroup + $B%G%#%l%/%F%#%V$rDL$7$?$b$N$,$"$j$^$9!#(B + $B$3$N%G%#%l%/%F%#%V$r%a%$%s%5!<%P$N%f!<%6(B ID + $B$H0[$J$k$b$N$K$9$k$H!"(BCGI $B%j%=!<%9$X$N$9$Y$F$N%j%/%(%9%H$O!"$=$N(B + VirtualHost $B$G;XDj$5$l$?(B User $B$H(B + Group $B$H$7$FVirtualHost + $B$G$3$N%G%#%l%/%F%#%V$,;XDj$5$l$F$$$J$$>l9g!"(B + $B%a%$%s%5!<%P$N%f!<%6(B ID $B$,A[Dj$5$l$^$9!#(B

    + +

    $B%f!<%6%G%#%l%/%H%j(B:
    + mod_userdir $B$K$h$j=hM}$5$l$?%j%/%(%9%H$O(B + $B%j%/%(%9%H$5$l$?%f!<%6%G%#%l%/%H%j$N%f!<%6(B ID $B$G(B CGI $B%W%m%0%i%`$r(B + $Be5-$N(B$B%;%-%e%j%F%#8!::(B$B$r%Q%9$G$-$k$3$H$G$9!#(B + $B%3%s%Q%$%k(B + $B;~$N%*%W%7%g%s(B --with-suexec-userdir $B$b;2>H$7$F$/$@$5$$!#(B

    +
    + +
    suEXEC $B$N%G%P%C%0(B + +

    suEXEC wrapper $B$O!">e5-$G=R$Y$?(B --with-suexec-logfile + $B%*%W%7%g%s$G;XDj$5$l$?%U%!%$%k$K%m%0>pJs$r5-O?$7$^$9!#(B + wrapper $B$rE,@Z$K@_Dj!"%$%s%9%H!<%k$G$-$F$$$k$H;W$&>l9g!"(B + $B$I$3$GLB$C$F$$$k$+8+$h$&$H$9$k$J$i$3$N%m%0$H%5!<%P$N(B + $B%(%i!<%m%0$r8+$k$H$h$$$G$7$g$&!#(B

    +
    + +
    $B$H$+$2$KCm0U(B: $B7Y9p$H;vNc(B + +

    $BCm0U(B! + $B$3$N>O$O40A4$G$O$"$j$^$;$s!#$3$N>O$N:G?72~D{HG$K$D$$$F$O!"(B + Apache $B%0%k!<%W$N(B + $B%*%s%i%$%s%I%-%e%a%s%H(B$BHG$r;2>H$7$F$/$@$5$$!#(B +

    + +

    $B%5!<%P$N@_Dj$K@)8B$r$b$&$1$k(B wrapper $B$K$D$$$F!"(B + $B$$$/$D$+6=L#?<$$E@$,$"$j$^$9!#(BsuEXEC $B$K4X$9$k(B "$B%P%0(B" + $B$rJs9p$9$kA0$K$3$l$i$r3NG'$7$F$/$@$5$$!#(B

    + +
      +
    • suEXEC $B$N6=L#?<$$E@(B
    • + +
    • $B3,AX9=B$$N@)8B(B + + +

      + $B%;%-%e%j%F%#$H8zN($NM}M3$+$i!"(BsuEXEC $B$NA4$F$N%j%/%(%9%H$O(B + $B2>A[%[%9%H$X$N%j%/%(%9%H$K$*$1$k:G>e0L$N%I%-%e%a%s%H%k!<%HFb$+!"(B + $B%f!<%6%G%#%l%/%H%j$X$N%j%/%(%9%H$K$*$1$k8D!9$N%f!<%6$N:G>e0L$N(B + $B%I%-%e%a%s%H%k!<%HFb$K;D$i$J$1$l$P$J$j$^$;$s!#(B + $BNc$($P!";M$D$N2>A[%[%9%H$r@_Dj$7$F$$$k>l9g!"(B + $B2>A[%[%9%H$N(B suEXEC $B$KM-Mx$J$h$&$K!"%a%$%s$N(B Apache + $B%I%-%e%a%s%H3,AX$N30B&$KA4$F$N2>A[%[%9%H$N%I%-%e%a%s%H%k!<%H$r(B + $B9=C[$9$kI,MW$,$"$j$^$9!#(B($BNc$O8eF|5-:\(B) +

      +
    • + +
    • suEXEC $B$N(B PATH $B4D6-JQ?t(B + + +

      + $B$3$l$rJQ99$9$k$N$O4m81$G$9!#$3$N;XDj$K4^$^$l$k3F%Q%9$,(B + $B?.Mj$G$-$k(B + $B%G%#%l%/%H%j$G$"$k$3$H$r3NG'$7$F$/$@$5$$!#(B + $B@$3&$+$i$N%"%/%;%9$K$h$j!"C/$+$,%[%9%H>e$G%H%m%$$NLZGO(B + $B$r +

    • + +
    • suEXEC $B%3!<%I$N2~B$(B + + +

      + $B7+$jJV$7$^$9$,!"2?$r$d$m$&$H$7$F$$$k$+GD0.$;$:$K$3$l$r$d$k$H(B + $BBg$-$JLdBj(B$B$r0z$-5/$3$7$+$M$^$;$s!#(B + $B2DG=$J8B$jHr$1$F$/$@$5$$!#(B +

      +
    • +
    +
    + +
    diff --git a/trunk/docs/manual/suexec.xml.ko b/trunk/docs/manual/suexec.xml.ko new file mode 100644 index 0000000000..83d130629f --- /dev/null +++ b/trunk/docs/manual/suexec.xml.ko @@ -0,0 +1,527 @@ + + + + + + + + + + suEXEC Áö¿ø + + +

    suEXEC ±â´ÉÀº ¾ÆÆÄÄ¡°¡ CGI¿Í + SSI ÇÁ·Î±×·¥À» À¥¼­¹ö¸¦ ½ÇÇàÇÑ »ç¿ëÀÚ ID°¡ + ¾Æ´Ñ ´Ù¸¥ »ç¿ëÀÚ ID·Î ½ÇÇàÇϵµ·Ï ÇÑ´Ù. º¸Åë CGI³ª SSI ÇÁ·Î±×·¥À» + ½ÇÇàÇϸé À¥¼­¹ö¸¦ ½ÇÇàÇÑ »ç¿ëÀÚ¿Í °°Àº »ç¿ëÀÚ·Î ½ÇÇàÇÑ´Ù.

    + +

    ÀÌ ±â´ÉÀ» ÀûÀýÈ÷ »ç¿ëÇÏ¸é »ç¿ëÀÚ°¡ Á÷Á¢ CGI³ª SSI ÇÁ·Î±×·¥À» + °³¹ßÇÏ°í ½ÇÇàÇÒ¶§ ¹ß»ýÇÒ ¼ö ÀÖ´Â º¸¾ÈÀ§ÇèÀ» »ó´çÈ÷ ÁÙÀÏ + ¼ö ÀÖ´Ù. ±×·¯³ª suEXEC°¡ ºÎÀûÀýÇÏ°Ô ¼³Á¤µÇ¸é ¸¹Àº ¹®Á¦¿Í + ÄÄÇ»ÅÍ¿¡ »õ·Î¿î º¸¾È ÇãÁ¡À» ¸¸µé ¼ö ÀÖ´Ù. ¸¸¾à setuid root + ÇÁ·Î±×·¥°ú ÀÌ·± ÇÁ·Î±×·¥ÀÇ º¸¾È ¹®Á¦¿¡ »ý¼ÒÇÏ´Ù¸é suEXEC¸¦ + »ç¿ëÇÏÁö¾Ê±æ Áø½ÉÀ¸·Î ¹Ù¶õ´Ù.

    +
    + +
    ½ÃÀÛÇϱâ Àü¿¡ + +

    ½ÃÀÛÇϱâ Àü¿¡ ¿ì¼± ¾ÆÆÄÄ¡±×·ì°ú ÀÌ ¹®¼­ÀÇ °¡Á¤À» ¹àÈù´Ù.

    + +

    ¸ÕÀú setuid¿Í setgid + ±â´ÉÀÌ °¡´ÉÇÑ À¯´Ð½º·ù ¿î¿µÃ¼Á¦¸¦ »ç¿ëÇÑ´Ù°í °¡Á¤ÇÑ´Ù. ¸ðµç + ¸í·É¾î ¿¹µéµµ °°Àº °¡Á¤À» ÇÑ´Ù. suEXEC¸¦ Áö¿øÇÏ´Â ´Ù¸¥ Ç÷¡ÆûÀ» + »ç¿ëÇÏ´Ù¸é ¼³Á¤ÀÌ ´Ù¸¦ ¼ö ÀÖ´Ù.

    + +

    µÎ¹ø°, ´ç½ÅÀÌ ÄÄÇ»ÅÍ º¸¾ÈÀÇ ±âº» °³³ä°ú °ü¸®¿¡ Àͼ÷ÇÏ´Ù°í + °¡Á¤ÇÑ´Ù. ¿©±â¿¡´Â setuid/setgid ±â´É°ú + À̵éÀÌ ½Ã½ºÅÛ°ú º¸¾È¿¡ ¹ÌÄ¡´Â ¿©·¯ ¿µÇâ¿¡ ´ëÇÑ ÀÌÇØ°¡ Æ÷ÇԵȴÙ.

    + +

    ¼¼¹ø°, suEXEC ÄÚµåÀÇ ¼öÁ¤ÇÏÁö¾ÊÀº + ¹öÀüÀ» »ç¿ëÇÑ´Ù°í °¡Á¤ÇÑ´Ù. °³¹ßÀÚ¿Í ¿©·¯ º£Å¸Å×½ºÅ͵éÀº + suEXEC¿Í °ü·ÃµÈ ¸ðµç Äڵ带 Á¶½É½º·´°Ô Á¶»çÇÏ°í °Ë»çÇß´Ù. + Äڵ带 °£´ÜÇÏ°Ô ÇÏ°í È®½ÇÇÑ ¾ÈÀüÀ» º¸ÀåÇϱâÀ§ÇØ ¸ðµç ÁÖÀǸ¦ + ±â¿ï¿´´Ù. ÀÌ Äڵ带 ¼öÁ¤ÇÏ¸é ¿¹»óÄ¡¸øÇÑ ¹®Á¦¿Í »õ·Î¿î º¸¾È + À§ÇèÀÌ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. º¸¾È ÇÁ·Î±×·¡¹Ö¿¡ ´ëÇØ ¸Å¿ì Àß ¾Ë°í + Äڵ带 »ìÆ캸±âÀ§ÇØ ¾ÆÆÄÄ¡±×·ì°ú ÀÛ¾÷À» °øÀ¯ÇÒ Àǻ簡 ¾ø´Ù¸é + suEXEC Äڵ带 ¼öÁ¤ÇÏÁö¾Ê±æ °­·ÂÈ÷ ±ÇÇÑ´Ù.

    + +

    ³×¹ø°ÀÌÀÚ ¸¶Áö¸·À¸·Î, ¾ÆÆÄÄ¡±×·ìÀº suEXEC¸¦ ¾ÆÆÄÄ¡ + ±âº»¼³Ä¡¿¡ Æ÷ÇÔÇÏÁö ¾Ê±â·Î °áÁ¤Çß´Ù. °á±¹ + °ü¸®ÀÚ°¡ ÁÖÀǸ¦ ±â¿ï¿©¼­ suEXEC¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. suEXECÀÇ + ¿©·¯ ¼³Á¤À» Àß °í·ÁÇÑÈÄ °ü¸®ÀÚ´Â ÀϹÝÀûÀÎ ¼³Ä¡¹æ¹ýÀ» suEXEC¸¦ + ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. suEXEC ±â´ÉÀ» »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÇ º¸¾ÈÀ» Ã¥ÀÓÁö´Â + °ü¸®ÀÚ´Â ÀÌ ¼³Á¤°ªµéÀ» ÁÖÀÇÀÖ°Ô »ìÆ캸°í ÁöÁ¤ÇØ¾ß ÇÑ´Ù. + ÀÌ·± »ó¼¼ÇÑ °úÁ¤Àº suEXEC¸¦ »ç¿ëÇÒ¸¸Å­ ÁÖÀÇÀÖ°í ´ÜÈ£ÇÑ + »ç¶÷¸¸ÀÌ suEXEC¸¦ »ç¿ëÇϵµ·Ï ¾ÆÆÄÄ¡±×·ìÀÌ ¿øÇϱ⠶§¹®ÀÌ´Ù.

    + +

    ¾ÆÁ÷µµ »ç¿ëÇÏ±æ ¿øÇϴ°¡? ±×·±°¡? ÁÁ´Ù. ÀÌÁ¦ ½ÃÀÛÇÏÀÚ!

    +
    + +
    suEXEC º¸¾È¸ðµ¨ + +

    suEXEC¸¦ ±¸¼ºÇÏ°í ¼³Ä¡Çϱâ Àü¿¡ ¿ì¸®´Â º¸¾È¸ðµ¨À» ¸ÕÀú + ¼³¸íÇÑ´Ù. À̸¦ ÅëÇØ Á¤È®È÷ suEXEC ¾È¿¡¼­´Â ¹«½¼ ÀÏÀÌ ÀϾ¸ç + ½Ã½ºÅÛÀÇ º¸¾ÈÀ» À§ÇØ ¹«¾ùÀ» Á¶½ÉÇØ¾ß ÇÒÁö ´õ Àß ÀÌÇØÇÒ ¼ö + ÀÖ´Ù.

    + +

    suEXEC´Â ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ ºÎ¸£´Â setuid + "wrapper" ÇÁ·Î±×·¥À» ±â¹ÝÀ¸·Î ÇÑ´Ù. ÀÌ wrapper´Â °ü¸®ÀÚ°¡ + ÁÖ¼­¹ö¿Í ´Ù¸¥ userid·Î ½ÇÇàÇϵµ·Ï ¼³Á¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥¿¡ + HTTP ¿äûÀÌ ¿À¸é ºÒ¸°´Ù. ÀÌ·± ¿äûÀÌ ¿À¸é ¾ÆÆÄÄ¡´Â suEXEC + wrapper¿¡°Ô ÇÁ·Î±×·¥¸í°ú ÇÁ·Î±×·¥À» ½ÇÇàÇÒ »ç¿ëÀÚ¿Í ±×·ì + ID¸¦ Á¦°øÇÑ´Ù.

    + +

    ±×·¯¸é wrapper´Â ´ÙÀ½ °úÁ¤À» ÅëÇØ ¼º°ø°ú ½ÇÆи¦ °áÁ¤ÇÑ´Ù. + ÀÌ Á¶°ÇÁß Çϳª¶óµµ ½ÇÆÐÇϸé ÇÁ·Î±×·¥Àº ½ÇÆзΠ±â·ÏµÇ°í ¿À·ù¸¦ + ³»¸ç Á¾·áÇÑ´Ù. ½ÇÆÐÇÏÁö ¾ÊÀ¸¸é °úÁ¤À» °è¼ÓÇÑ´Ù:

    + +
      +
    1. + wrapper¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ°¡ ½Ã½ºÅÛÀÇ Á¤»óÀûÀÎ + »ç¿ëÀÚÀΰ¡? + +

      + wrapper¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ°¡ ½ÇÁ¦·Î ½Ã½ºÅÛÀÇ »ç¿ëÀÚÀÎÁö + È®ÀÎÇÑ´Ù. +

      +
    2. + +
    3. + ÀûÀýÇÑ ¼öÀÇ ¾Æ±Ô¸ÕÆ®·Î wrapper¸¦ ½ÇÇàÇϴ°¡? + +

      + wrapper´Â ÀûÀýÇÑ ¼öÀÇ ¾Æ±Ô¸ÕÆ®°¡ ÀÖ¾î¾ß¸¸ ½ÇÇàµÈ´Ù. + ¾ÆÆÄÄ¡ À¥¼­¹ö°¡ ÀÌ °³¼ö¸¦ ¾È´Ù. wrapper°¡ ÀûÀýÇÑ ¼öÀÇ + ¾Æ±Ô¸ÕÆ®¸¦ ¹ÞÁö¸øÇϸé ÇØÅ·µÇ¾ú°Å³ª ¾ÆÆÄÄ¡ÀÇ suEXEC¿¡ + ¹º°¡ ¹®Á¦°¡ ÀÖ´Â °ÍÀÌ´Ù. +

      +
    4. + +
    5. + ÀÌ »ç¿ëÀÚ°¡ wrapper¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëµÇ¾ú³ª? + +

      + ÀÌ »ç¿ëÀÚ°¡ wrapper¸¦ ½ÇÇàÇϵµ·Ï Çã¿ëµÇ¾ú³ª? ¿ÀÁ÷ + ÇÑ »ç¿ëÀÚ(¾ÆÆÄÄ¡ »ç¿ëÀÚ)¸¸ÀÌ ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÒ + ¼ö ÀÖ´Ù. +

      +
    6. + +
    7. + ÁöÁ¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥ÀÌ ¾ÈÀüÇÏÁö¾ÊÀº °èÃþÂüÁ¶¸¦ + °¡Áö´Â°¡? + +

      + ÁöÁ¤ÇÑ CGI³ª SSI ÇÁ·Î±×·¥ÀÌ '/'·Î ½ÃÀÛÇϰųª µÞÂüÁ¶ + '..'À» °¡Áö´Â°¡? À̵éÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ÁöÁ¤ÇÑ CGI/SSI + ÇÁ·Î±×·¥Àº suEXEC ¹®¼­ root (¾Æ·¡ + --with-suexec-docroot=DIR Âü°í) + ³»¿¡ ÀÖ¾î¾ß ÇÑ´Ù. +

      +
    8. + +
    9. + ÁöÁ¤ÇÑ »ç¿ëÀÚ¸íÀÌ À¯È¿ÇÑ°¡? + +

      + ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ Á¸ÀçÇϴ°¡? +

      +
    10. + +
    11. + ÁöÁ¤ÇÑ ±×·ì¸íÀÌ À¯È¿ÇÑ°¡? + +

      + ÁöÁ¤ÇÑ ±×·ìÀÌ Á¸ÀçÇϴ°¡? +

      +
    12. + +
    13. + ÁöÁ¤ÇÑ »ç¿ëÀÚ°¡ superuser°¡ ¾Æ´Ñ°¡? + + +

      + ÇöÀç suEXEC´Â root°¡ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ¾øµµ·Ï ÇÑ´Ù. +

      +
    14. + +
    15. + ÁöÁ¤ÇÑ userid°¡ ÃÖ¼Ò ID ¼ýÀÚº¸´Ù Å«°¡? + +

      + ¼³Á¤¿¡¼­ ÃÖ¼Ò »ç¿ëÀÚ ID ¼ýÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. ±×·¡¼­ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Â useridÀÇ ÃÖ¼ÒÄ¡¸¦ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. "½Ã½ºÅÛ¿ë" °èÁ¤À» Á¦¿ÜÇÒ¶§ À¯¿ëÇÏ´Ù. +

      +
    16. + +
    17. + ÁöÁ¤ÇÑ ±×·ìÀÌ superuser ±×·ìÀÌ ¾Æ´Ñ°¡? + +

      + ÇöÀç suEXEC´Â root ±×·ìÀÌ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ¾øµµ·Ï ÇÑ´Ù. +

      +
    18. + +
    19. + ÁöÁ¤ÇÑ groupid°¡ ÃÖ¼Ò ID ¼ýÀÚº¸´Ù Å«°¡? + +

      + ¼³Á¤¿¡¼­ ÃÖ¼Ò ±×·ì ID ¼ýÀÚ¸¦ ÁöÁ¤ÇÑ´Ù. ±×·¡¼­ CGI/SSI + ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¼ö ÀÖ´Â groupidÀÇ ÃÖ¼ÒÄ¡¸¦ ÁöÁ¤ÇÒ + ¼ö ÀÖ´Ù. "½Ã½ºÅÛ¿ë" ±×·ìÀ» Á¦¿ÜÇÒ¶§ À¯¿ëÇÏ´Ù. +

      +
    20. + +
    21. + wrapper°¡ ¼º°øÀûÀ¸·Î ÁöÁ¤ÇÑ »ç¿ëÀÚ¿Í ±×·ìÀÌ + µÉ ¼ö Àִ°¡? + +

      + ÀÌ ´Ü°è¿¡¼­ ÇÁ·Î±×·¥Àº setuid¿Í setgid È£ÃâÀ» ÇÏ¿© + ÁöÁ¤ÇÑ »ç¿ëÀÚ¿Í ±×·ìÀÌ µÈ´Ù. ¶Ç, ±×·ì Á¢±Ù¸ñ·ÏÀº + »ç¿ëÀÚ°¡ ÇØ´çµÈ ¸ðµç ±×·ìÀ¸·Î ÃʱâÈ­µÈ´Ù. +

      +
    22. + +
    23. + CGI/SSI ÇÁ·Î±×·¥ÀÌ ÀÖ´Â µð·ºÅ丮·Î µð·ºÅ丮¸¦ + º¯°æÇÒ ¼ö Àִ°¡? + +

      + µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾Ê´Ù¸é ÆÄÀÏÀÌ ÀÖÀ» ¼ö ¾ø´Ù. ÀÌ°÷À¸·Î + µð·ºÅ丮¸¦ º¯°æÇÒ ¼ö ¾ø´Ù¸é µð·ºÅ丮´Â Á¸ÀçÇÏÁö ¾ÊÀ» + °ÍÀÌ´Ù. +

      +
    24. + +
    25. + µð·ºÅ丮°¡ ¾ÆÆÄÄ¡ À¥°ø°£ ¾È¿¡ Àִ°¡? + +

      + ¼­¹öÀÇ ÀϹÝÀûÀÎ ºÎºÐÀ» ¿äûÇÒ °æ¿ì ¿äûÇÏ´Â µð·ºÅ丮°¡ + suEXEC ¹®¼­ root ¾Æ·¡ Àִ°¡? UserDirÀ» ¿äûÇÒ °æ¿ì + ¿äûÇÏ´Â µð·ºÅ丮°¡ suEXEC userdir·Î ¼³Á¤ÇÑ (suEXEC ¼³Á¤ ¿É¼Ç Âü°í) µð·ºÅ丮 + ¾Æ·¡¿¡ Àִ°¡? +

      +
    26. + +
    27. + ´Ù¸¥ ´©±¸µµ µð·ºÅ丮¿¡ ¾²±â±ÇÇÑÀÌ ¾ø´Â°¡? + +

      + µð·ºÅ丮¸¦ ´Ù¸¥ »ç¶÷¿¡°Ô ¿­¾îµÎ±æ ¿øÇÏÁö¾Ê´Â´Ù. ¿ÀÁ÷ + ¼ÒÀ¯ÀÚ¸¸ÀÌ µð·ºÅ丮 ³»¿ëÀ» º¯°æÇÒ ¼ö ÀÖ´Ù. +

      +
    28. + +
    29. + ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ Á¸ÀçÇϴ°¡? + +

      + Á¸ÀçÇÏÁö¾Ê´Ù¸é ½ÇÇàÇÒ ¼öµµ ¾ø´Ù. +

      +
    30. + +
    31. + ´Ù¸¥ ´©±¸µµ ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥¿¡ ¾²±â±ÇÇÑÀÌ + ¾ø´Â°¡? + +

      + ¼ÒÀ¯ÀÚ¿Ü ´©±¸µµ CGI/SSI ÇÁ·Î±×·¥À» º¯°æÇÏ±æ ¿øÇÏÁö¾Ê´Â´Ù. +

      +
    32. + +
    33. + ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ setuid³ª setgid°¡ + ¾Æ´Ñ°¡? + +

      + ¿ì¸®´Â ÇÁ·Î±×·¥ÀÌ ´Ù½Ã UID/GID¸¦ º¯°æÇÏ±æ ¿øÇÏÁö¾Ê´Â´Ù. +

      +
    34. + +
    35. + ÁöÁ¤ÇÑ »ç¿ëÀÚ/±×·ìÀÌ ÇÁ·Î±×·¥ÀÇ »ç¿ëÀÚ/±×·ì°ú °°Àº°¡? + +

      + »ç¿ëÀÚ°¡ ÆÄÀÏÀÇ ¼ÒÀ¯ÀÚÀΰ¡? +

      +
    36. + +
    37. + ¾ÈÀüÇÑ µ¿ÀÛÀ» À§ÇØ ÇÁ·Î¼¼½ºÀÇ È¯°æº¯¼ö¸¦ û¼ÒÇÒ + ¼ö Àִ°¡? + +

      + suEXEC´Â (¼³Á¤¿¡¼­ Á¤ÀÇÇÑ) ¾ÈÀüÇÑ ½ÇÇà PATH¸¦ Àâ°í, + (À̰͵µ ¼³Á¤¿¡¼­ Á¤ÀÇ) ¾ÈÀüÇÑ È¯°æº¯¼ö ¸ñ·Ï¿¡ ¿­°ÅµÈ + º¯¼ö¸¸ ³²±â°í ÇÁ·Î¼¼½ºÀÇ È¯°æº¯¼ö¸¦ Áö¿î´Ù. +

      +
    38. + +
    39. + ¼º°øÀûÀ¸·Î ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥À» ½ÇÇàÇÒ + ¼ö Àִ°¡? + +

      + ¿©±â¼­ suEXEC°¡ ³¡³ª°í ÁöÁ¤ÇÑ CGI/SSI ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÑ´Ù. +

      +
    40. +
    + +

    ÀÌ°ÍÀÌ suEXEC wrapper º¸¾È¸ðµ¨ÀÇ Ç¥ÁØ µ¿ÀÛÀÌ´Ù. ´Ù¼Ò + ¾ö°ÝÇÏ°í CGI/SSI ¼³°è¿¡ »õ·Î¿î Á¦ÇÑÀÌ µÇÁö¸¸, º¸¾ÈÀ» ¿°µÎ¿¡ + µÎ°í ÇѴܰ辿 Á¶½É½º·´°Ô ¸¸µé¾îÁ³´Ù.

    + +

    ÀÌ º¸¾È ¸ðµ¨ÀÌ ¼­¹ö ¼³Á¤¿¡ ¾î¶² Á¦ÇÑÀ» ÁÖ´ÂÁö¿Í ÀûÀýÇÑ + suEXEC ¼³Á¤À¸·Î ¾î¶² º¸¾È À§ÇèÀ» ÇÇÇÒ ¼ö ÀÖ´ÂÁö¿¡ ´ëÇØ ÀÌ + ¹®¼­ÀÇ "´Ù½Ã Çѹø Á¶½ÉÇ϶ó" ÀýÀ» + Âü°íÇ϶ó.

    +
    + +
    suEXEC ±¸¼º°ú ¼³Ä¡ + +

    ÀÌÁ¦ Àç¹ÌÀÖ´Â ³»¿ëÀÌ ½ÃÀÛÇÑ´Ù.

    + +

    suEXEC ±¸¼º ¿É¼Ç
    +

    + +
    +
    --enable-suexec
    + +
    ÀÌ ¿É¼ÇÀº ±âº»ÀûÀ¸·Î ¼³Ä¡µÇ°Å³ª È°¼ºÈ­µÇÁö¾Ê´Â suEXEC + ±â´ÉÀ» È°¼ºÈ­ÇÑ´Ù. APACI°¡ suEXEC¸¦ ¹Þ¾ÆµéÀÌ·Á¸é + --enable-suexec ¿É¼Ç¿Ü¿¡ + --with-suexec-xxxxx ¿É¼ÇÀÌ ÃÖ¼ÒÇÑ ÇÑ°³ + ÇÊ¿äÇÏ´Ù.
    + +
    --with-suexec-bin=PATH
    + +
    suexec ¹ÙÀ̳ʸ® °æ·Î´Â º¸¾È»ó ÀÌÀ¯·Î + ¼­¹ö¿¡ ±â·ÏµÇ¾ß ÇÑ´Ù. °æ·Î ±âº»°ªÀ» ¹«½ÃÇÏ·Á¸é ÀÌ ¿É¼ÇÀ» + »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î + --with-suexec-bin=/usr/sbin/suexec
    + +
    --with-suexec-caller=UID
    + +
    º¸Åë ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¸í. ÇÁ·Î±×·¥À» + ½ÇÇàÇÒ ¼ö ÀÖ´Â À¯ÀÏÇÑ »ç¿ëÀÚ´Ù.
    + +
    --with-suexec-userdir=DIR
    + +
    suEXEC Á¢±ÙÀÌ Çã¿ëµÇ´Â »ç¿ëÀÚ È¨µð·ºÅ丮ÀÇ ÇÏÀ§µð·ºÅ丮¸¦ + ÁöÁ¤ÇÑ´Ù. ÀÌ µð·ºÅ丮¿¡ ÀÖ´Â ¸ðµç ½ÇÇàÆÄÀÏÀ» »ç¿ëÀÚÀÇ + suEXEC·Î ½ÇÇà¹Ç·Î, ¸ðµç ÇÁ·Î±×·¥ÀÌ "¾ÈÀüÇؾß" ÇÑ´Ù. (¿¹¸¦ + µé¾î, °ª¿¡ "*"ÀÌ ¾ø´Â) "°£´ÜÇÑ" UserDir Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù¸é + °°Àº °ªÀ» ¼³Á¤ÇØ¾ß ÇÑ´Ù. UserDir Áö½Ã¾î°¡ passwd ÆÄÀÏ¿¡ + ³ª¿Â »ç¿ëÀÚ È¨µð·ºÅ丮¿Í ´Ù¸£¸é suEXEC´Â Á¤»óÀûÀ¸·Î + ÀÛµ¿ÇÏÁö ¾Ê´Â´Ù. ±âº»°ªÀº "public_html"ÀÌ´Ù.
    + °¡»óÈ£½ºÆ®µéÀÌ °¢°¢ ´Ù¸¥ UserDirÀ» »ç¿ëÇÑ´Ù¸é ¸ðµÎ ÇÑ + ºÎ¸ð µð·ºÅ丮 ¾È¿¡ ÀÖµµ·Ï Á¤ÀÇÇØ¾ß ÇÏ°í, ±× ºÎ¸ð µð·ºÅ丮¸íÀ» + ¿©±â Àû´Â´Ù. ÀÌ·¸°Ô Á¤ÀÇÇÏÁö ¾ÊÀ¸¸é, "~userdir" + cgi ¿äûÀÌ ÀÛµ¿ÇÏÁö ¾Ê´Â´Ù!
    + +
    --with-suexec-docroot=DIR
    + +
    ¾ÆÆÄÄ¡ÀÇ DocumentRoot¸¦ Á¤ÀÇÇÑ´Ù. ÀÌ´Â suEXEC°¡ »ç¿ëÇÒ + ¼ö ÀÖ´Â (UserDirsÀ» Á¦¿ÜÇÑ) À¯ÀÏÇÑ °ø°£ÀÌ´Ù. ±âº» µð·ºÅ丮´Â + --datadir °ª¿¡ "/htdocs"À» ºÙÀÎ °ÍÀÌ´Ù. + ¿¹¸¦ µé¾î "--datadir=/home/apache"·Î + ±¸¼ºÇß´Ù¸é suEXEC wrapper´Â document root·Î + "/home/apache/htdocs" µð·ºÅ丮¸¦ »ç¿ëÇÑ´Ù.
    + +
    --with-suexec-uidmin=UID
    + +
    suEXEC¿¡¼­ ÁöÁ¤°¡´ÉÇÑ »ç¿ëÀÚÀÇ ÃÖ¼Ò UID¸¦ Á¤ÀÇÇÑ´Ù. + ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ 500À̳ª 100ÀÌ ÀûÀýÇÏ´Ù. ±âº»°ªÀº + 100ÀÌ´Ù.
    + +
    --with-suexec-gidmin=GID
    + +
    suEXEC¿¡¼­ ÁöÁ¤°¡´ÉÇÑ ±×·ìÀÇ ÃÖ¼Ò GID¸¦ Á¤ÀÇÇÑ´Ù. + ´ëºÎºÐÀÇ ½Ã½ºÅÛ¿¡¼­ 100ÀÌ ÀûÀýÇϹǷΠÀÌ °ªÀÌ ±âº»°ªÀÌ´Ù.
    + +
    --with-suexec-logfile=FILE
    + +
    ¸ðµç suEXEC ÀÛµ¿°ú ¿À·ù¸¦ (°¨½Ã³ª µð¹ö±ë ¸ñÀû¿¡ À¯¿ëÇÑ) + ±â·ÏÇÒ ·Î±×ÆÄÀϸíÀ» ÁöÁ¤ÇÑ´Ù. ±âº»ÀûÀ¸·Î ·Î±×ÆÄÀÏÀÇ À̸§Àº + "suexec_log"ÀÌ°í Ç¥ÁØ ·Î±×ÆÄÀÏ µð·ºÅ丮¿¡ + (--logfiledir) À§Ä¡ÇÑ´Ù.
    + +
    --with-suexec-safepath=PATH
    + +
    CGI ½ÇÇàÆÄÀÏ¿¡ ³Ñ°ÜÁú ¾ÈÀüÇÑ PATH ȯ°æº¯¼ö¸¦ Á¤ÀÇÇÑ´Ù. + ±âº»°ªÀº "/usr/local/bin:/usr/bin:/bin"ÀÌ´Ù.
    +
    + +

    suEXEC wrapper¸¦ ÄÄÆÄÀÏÇÏ°í ¼³Ä¡Çϱâ
    + --enable-suexec ¿É¼ÇÀ¸·Î suEXEC ±â´ÉÀ» °¡´ÉÇÏ°ÔÇÑ + °æ¿ì make ¸í·É¾î¸¦ ½ÇÇàÇϸé suexec + ½ÇÇàÆÄÀÏÀÌ (¾ÆÆÄÄ¡¿Í ÇÔ²²) ÀÚµ¿À¸·Î ¸¸µé¾îÁø´Ù.
    + ¸ðµç°ÍÀ» ÄÄÆÄÀÏÇÑ ÈÄ make install ¸í·É¾î¸¦ + ½ÇÇàÇÏ¿© ¼³Ä¡ÇÒ ¼ö ÀÖ´Ù. ¹ÙÀ̳ʸ®ÆÄÀÏ suexec´Â + --sbindir ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ µð·ºÅ丮¿¡ ¼³Ä¡µÈ´Ù. + ±âº» À§Ä¡´Â "/usr/local/apache2/sbin/suexec"ÀÌ´Ù.
    + ¼³Ä¡ °úÁ¤¿¡ root ±ÇÇÑÀÌ ÇÊ¿äÇÔÀ» + ÁÖÀÇÇ϶ó. wrapper°¡ »ç¿ëÀÚ ID¸¦ ¼³Á¤ÇϱâÀ§Çؼ­´Â ¼ÒÀ¯ÀÚ°¡ + rootÀÌ°í ÆÄÀϸðµå·Î setuserid ½ÇÇàºñÆ®°¡ + ¼³Á¤µÇ¾ß ÇÑ´Ù.

    + +

    ÆíÁýÁõÀûÀÎ ±ÇÇѼ³Á¤
    + suEXEC wrapper´Â ÀÚ½ÅÀ» ½ÇÇàÇÑ »ç¿ëÀÚ°¡ ±¸¼º ¿É¼Ç + --with-suexec-caller·Î ÁöÁ¤ÇÑ ¿Ã¹Ù¸¥ »ç¿ëÀÚÀÎÁö + È®ÀÎÀ» ÇÏÁö¸¸, ÀÌ °Ë»ç ÀÌÀü¿¡ suEXEC°¡ »ç¿ëÇÏ´Â ½Ã½ºÅÛÈ£Ãâ + ȤÀº ¶óÀ̺귯¸® ÇÔ¼ö°¡ Á¶À۵ǾúÀ» ¼ö ÀÖ´Ù. À̸¦ ´ëºñÇϸç + ÀϹÝÀûÀ¸·Î ÁÁÀº ½À°üÀ̹ǷΠ¿ÀÁ÷ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â ±×·ì¸¸ÀÌ + suEXEC¸¦ ½ÇÇàÇÒ ¼ö ÀÖµµ·Ï ÆÄÀϽýºÅÛ ±ÇÇÑÀ» ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¿¹¸¦ µé¾î, À¥¼­¹ö¸¦ ´ÙÀ½°ú °°ÀÌ ¼³Á¤ÇÏ°í:

    + + + User www
    + Group webgroup
    +
    + +

    suexec¸¦ "/usr/local/apache2/sbin/suexec"¿¡ + ¼³Ä¡ÇÏ¿´´Ù¸é, ´ÙÀ½À» ½ÇÇàÇØ¾ß ÇÑ´Ù:

    + + + chgrp webgroup /usr/local/apache2/bin/suexec
    + chmod 4750 /usr/local/apache2/bin/suexec
    +
    + +

    ±×·¯¸é ¿ÀÁ÷ ¾ÆÆÄÄ¡¸¦ ½ÇÇàÇÏ´Â ±×·ì¸¸ÀÌ suEXEC wrapper¸¦ + ½ÇÇàÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    suEXEC Å°°í ²ô±â + +

    ¾ÆÆÄÄ¡´Â ½ÃÀÛÇÒ¶§ --sbindir ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ + µð·ºÅ丮¿¡¼­ suexec ÆÄÀÏÀ» (±âº»°ª + "/usr/local/apache2/sbin/suexec") ã´Â´Ù. ¾ÆÆÄÄ¡°¡ + Á¤»óÀûÀ¸·Î ±¸¼ºµÈ suEXEC wrapper¸¦ ¹ß°ßÇÏ¸é ¿À·ù ·Î±×(error + log)¿¡ ´ÙÀ½°ú °°ÀÌ Ãâ·ÂÇÑ´Ù:

    + + + [notice] suEXEC mechanism enabled (wrapper: /path/to/suexec) + + +

    ¼­¹ö ½ÃÀÛÁß¿¡ ÀÌ·± ¹®±¸¸¦ ¾ø´Ù¸é ¼­¹ö´Â ±â´ëÇÑ Àå¼Ò¿¡¼­ + wrapper ÇÁ·Î±×·¥À» ãÁö ¸øÇ߰ųª, ½ÇÇàÆÄÀÏÀÌ setuid + root·Î ¼³Ä¡µÇÁö¾Ê¾Ò±â ¶§¹®ÀÏ °ÍÀÌ´Ù.

    + +

    óÀ½À¸·Î suEXEC ±â´ÉÀ» »ç¿ëÇÏ°í ½Í°í ÀÌ¹Ì ¾ÆÆÄÄ¡ ¼­¹ö°¡ + ½ÇÇàÁßÀ̶ó¸é, ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í ´Ù½Ã ½ÃÀÛÇØ¾ß ÇÑ´Ù. °£´ÜÈ÷ + HUPÀ̳ª USR1 ½Ã±×³Î·Î Àç½ÃÀÛÇÏ´Â °ÍÀ¸·Î´Â ÃæºÐÇÏÁö ¾Ê´Ù.

    +

    suEXEC¸¦ ¾È»ç¿ëÇÏ·Á¸é suexec ÆÄÀÏÀ» Áö¿îÈÄ + ¾ÆÆÄÄ¡¸¦ Á×ÀÌ°í Àç½ÃÀÛÇØ¾ß ÇÑ´Ù.

    +
    + +
    suEXEC »ç¿ëÇϱâ + +

    CGI ÇÁ·Î±×·¥ ¿äûÀÇ °æ¿ì SuexecUserGroup Áö½Ã¾î¸¦ + »ç¿ëÇÑ °¡»óÈ£½ºÆ®¿¡ ¿äûÀ» ÇÏ¿´°Å³ª mod_userdirÀÌ + ¿äûÀ» ó¸®ÇÏ´Â °æ¿ì¿¡¸¸ suEXEC wrapper¸¦ È£ÃâÇÑ´Ù.

    + +

    °¡»óÈ£½ºÆ®:
    suEXEC wrapper¸¦ + »ç¿ëÇÏ´Â ÇÑ°¡Áö ¹æ¹ýÀº VirtualHost Á¤ÀÇ¿¡ SuexecUserGroup Áö½Ã¾î¸¦ + »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ÀÌ Áö½Ã¾î¸¦ ÁÖ¼­¹ö »ç¿ëÀÚ ID¿Í ´Ù¸£°Ô + ¼³Á¤Çϸé CGI ÀÚ¿øÀÇ ¸ðµç ¿äûÀÌ VirtualHost¿¡¼­ + ÁöÁ¤ÇÑ User¿Í GroupÀ¸·Î ½ÇÇàµÈ´Ù. ÀÌ + Áö½Ã¾îµéÀÌ VirtualHost¿¡ ¾øÀ¸¸é ÁÖ¼­¹ö + userid¸¦ »ç¿ëÇÑ´Ù.

    + +

    »ç¿ëÀÚ µð·ºÅ丮:
    + mod_userdirÀÌ ¿äûÀ» ó¸®ÇÑ´Ù¸é suEXEC + wrapper¸¦ È£ÃâÇÏ¿©, ¿äûÇÑ »ç¿ëÀÚ µð·ºÅ丮¿¡ ÇØ´çÇÏ´Â »ç¿ëÀÚ + ID·Î CGI ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù. ÀÌ ±â´ÉÀÌ µ¿ÀÛÇÏ·Á¸é »ç¿ëÀÚ + ID·Î CGI¸¦ ½ÇÇàÇÒ ¼ö ÀÖ°í ½ºÅ©¸³Æ®°¡ À§ÀÇ º¸¾È + °Ë»ç Ç׸ñÀ» ¸¸Á·ÇØ¾ß ÇÑ´Ù. ±¸¼º + ¿É¼Ç --with-suexec-userdirÀ» Âü°íÇ϶ó.

    + +
    suEXEC µð¹ö±ëÇϱâ + +

    suEXEC wrapper´Â ·Î±× Á¤º¸¸¦ À§¿¡¼­ ´Ù·é + --with-suexec-logfile ¿É¼ÇÀ¸·Î ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ + ¾´´Ù. wrapper¸¦ ¿Ã¹Ù·Î ±¸¼ºÇÏ°í ¼³Ä¡Çß´Ù¸é ¾îµð¼­ À߸øµÇ¾ú´ÂÁö + ÀÌ ·Î±×ÆÄÀÏ¿Í ¼­¹öÀÇ error_log¸¦ »ìÆìºÁ¶ó.

    + +
    + +
    ´Ù½Ã Çѹø Á¶½ÉÇ϶ó: °æ°í¿Í ¿¹Á¦ + +

    ÁÖÀÇ! ÀÌ ¼½¼ÇÀº ¿ÏÀüÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù. + ¾ÆÆÄÄ¡±×·ìÀÇ ¿Â¶óÀÎ + ¹®¼­¿¡¼­ ÀÌ ¹®¼­ÀÇ ÃÖ½ÅÆÇÀ» Âü°íÇ϶ó.

    + +

    wrapper°¡ ¼­¹ö ¼³Á¤À» Á¦¾àÇÏ´Â ¸î°¡Áö Èï¹Ì·Î¿î Á¡ÀÌ ÀÖ´Ù. + suEXEC¿Í °ü·ÃµÈ "¹ö±×"¸¦ º¸°íÇϱâ Àü¿¡ À̵éÀ» »ìÆ캸±æ ¹Ù¶õ´Ù.

    + +
      +
    • suEXEC Á¦¾à »çÇ×
    • + +
    • + µð·ºÅ丮 ±¸Á¶ Á¦ÇÑ + +

      + º¸¾È°ú È¿À²¼ºÀ» À§ÇØ ¸ðµç suEXEC ¿äûÀº °¡»óÈ£½ºÆ®ÀÇ + °æ¿ì ÃÖ»óÀ§ document root ȤÀº userdir ¿äûÀÇ °æ¿ì + ÃÖ»óÀ§ °³ÀÎ document root ¾È¿¡¼­ ¹ß»ýÇØ¾ß ÇÑ´Ù. ¿¹¸¦ + µé¾î, °¡»óÈ£½ºÆ® ³×°³¸¦ ¼³Á¤Çß´Ù¸é °¡»óÈ£½ºÆ®¿¡¼­ + suEXEC¸¦ ÀÌ¿ëÇϱâÀ§ÇØ °¡»óÈ£½ºÆ®ÀÇ document root¸¦ + ÁÖ ¾ÆÆÄÄ¡ ¹®¼­ °èÃþ±¸Á¶ ¹Û¿¡ ¼³Á¤ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. + (¿¹Á¦´Â ´ÙÀ½¿¡.) +

      +
    • + +
    • + suEXECÀÇ PATH ȯ°æº¯¼ö + +

      + º¯°æÇϸé À§ÇèÇÒ ¼ö ÀÖ´Ù. ¿©±â¿¡ Æ÷ÇÔÇÏ´Â ¸ðµç °æ·Î°¡ + ¹ÏÀ» ¼ö ÀÖ´Â µð·ºÅ丮ÀÎÁö È®ÀÎÇ϶ó. + ÀÌ Áö±¸»óÀÇ ´©±º°¡°¡ ±×°÷¿¡ ÀÖ´Â Æ®·ÎÀ̸ñ¸¶¸¦ ½ÇÇàÇϱæ + ¿øÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. +

      +
    • + +
    • + suEXEC ÄÚµå ¼öÁ¤Çϱâ + +

      + ¹Ýº¹Çؼ­ ¸»ÇÏÁö¸¸, ´ç½ÅÀÌ ¹«¾ùÀ» ÇÏ´ÂÁö ¸ð¸£°í ½ÃµµÇÑ´Ù¸é + Å« ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ¾î¶² °æ¿ì¿¡µµ + ¼öÁ¤ÇÏÁö¸¶¶ó. +

      +
    • +
    + +
    + +
    diff --git a/trunk/docs/manual/suexec.xml.meta b/trunk/docs/manual/suexec.xml.meta new file mode 100644 index 0000000000..eb64d9e261 --- /dev/null +++ b/trunk/docs/manual/suexec.xml.meta @@ -0,0 +1,13 @@ + + + + suexec + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/upgrading.html b/trunk/docs/manual/upgrading.html new file mode 100644 index 0000000000..35b0339c8f --- /dev/null +++ b/trunk/docs/manual/upgrading.html @@ -0,0 +1,27 @@ +URI: upgrading.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: upgrading.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: upgrading.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 + +URI: upgrading.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: upgrading.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR + +URI: upgrading.html.pt-br +Content-Language: pt-br +Content-type: text/html; charset=ISO-8859-1 + +URI: upgrading.html.ru.koi8-r +Content-Language: ru +Content-type: text/html; charset=KOI8-R diff --git a/trunk/docs/manual/upgrading.html.de b/trunk/docs/manual/upgrading.html.de new file mode 100644 index 0000000000..ec749e137a --- /dev/null +++ b/trunk/docs/manual/upgrading.html.de @@ -0,0 +1,110 @@ + + + +Upgrade von 2.0 auf 2.1 - Apache HTTP Server + + + + + +
    <-
    +

    Upgrade von 2.0 auf 2.1

    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    Dieses Dokument dient der Unterstützung beim Upgrade. Es + enthält die entscheidenden Informationen für bisherige + Apache-Nutzer. Diese sind als kurze Anmerkungen + gedacht. Weitere Informationen finden Sie entweder unter + Neue Funktionen oder in + den src/CHANGES-Dateien.

    + +

    Dieses Dokument beschreibt lediglich die Änderungen von Version + 2.2 gegenüber Version 2.0. Wenn Sie ein Upgrade von Version 1.3 + durchführen, sollten Sie auch Upgrade von 1.3 + auf 2.0 zu Rate ziehen.

    +
    + +
    top
    +
    top
    +
    +

    Änderungen der Laufzeit-Konfiguration

    + + +
      +
    • Die mit dem Apache HTTP Server ausgelieferte Konfigurationsdatei + httpd.conf wurde stark vereinfacht, indem alle außer + den unbedingt notwendigen Konfigurationseinstellungen entfernt wurden. + Im conf/extra/-Verzeichnis Ihrer Installation finden Sie + eine Reihe von Konfigurationsbeispielen für erweiterte Funktionen. +
    • + +
    • Die apachectl-Option startssl gibt es + nicht mehr. Um SSL-Unterstützung zu aktivieren müssen Sie die + httpd.conf editieren und die entsprechenden + mod_ssl-Anweisungen einfügen und + anschließend den Server mit apachectl start starten. + Eine Beispielkonfiguration zum Aktivieren von mod_ssl + ist in conf/extra/httpd-ssl.conf enthalten. +
    • + +
    • Die Voreinstellung von UseCanonicalName ist jetzt Off. + Wenn diese Anweisung nicht in Ihrer Konfigurationsdatei enthalten ist, + können Sie UseCanonicalName On einfügen, um das + bisherige Verhalten beizubehalten. +
    • + +
    • Das Modul mod_userdir reagiert nicht länger auf + Anfragen, solange nicht in der Konfigurationsdatei eine UserDir-Anweisung enthalten ist, die + einen Verzeichnisnamen angibt. Fügen Sie Ihrer Konfigurationsdatei + die Anweisung UserDir public_html hinzu, um das + bisherige Verhalten wiederherzustellen. +
    • +
    +
    top
    +
    top
    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.html.en b/trunk/docs/manual/upgrading.html.en new file mode 100644 index 0000000000..993a3214af --- /dev/null +++ b/trunk/docs/manual/upgrading.html.en @@ -0,0 +1,107 @@ + + + +Upgrading to 2.1 from 2.0 - Apache HTTP Server + + + + + +
    <-
    +

    Upgrading to 2.1 from 2.0

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + +

    In order to assist folks upgrading, we maintain a document + describing information critical to existing Apache users. These + are intended to be brief notes, and you should be able to find + more information in either the New Features document, or in + the src/CHANGES file.

    + +

    This document describes only the changes from 2.0 to 2.2. If you + are upgrading from version 1.3, you should also consult the 1.3 to 2.0 + upgrading document.

    + +
    + +
    top
    +
    top
    +
    +

    Run-Time Configuration Changes

    + + +
      +
    • The config file httpd.conf distributed with the + Apache HTTP Server has been greatly simplified by removing all + but the most essential configuration settings. A set of example + configuration settings for more advanced features is present in + the conf/extra/ directory of the installed + server.
    • + +
    • The apachectl option + startssl is no longer available. To enable ssl + support, you should edit httpd.conf to include the + relevant mod_ssl directives and then use + apachectl start to start the server. An example + configuration to activate mod_ssl has been included + in conf/extra/httpd-ssl.conf.
    • + +
    • The default setting of UseCanonicalName is now + Off. If you did not have this directive in your + config file, you can add UseCanonicalName On to + retain the old behavior.
    • + +
    • The module mod_userdir will no longer act + on requests unless a UserDir directive specifying a + directory name is present in the config file. To restore the + old default behavior, place the directive UserDir + public_html in your config file.
    • + +
    +
    top
    +
    +

    Misc Changes

    + + +
    top
    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.html.fr b/trunk/docs/manual/upgrading.html.fr new file mode 100644 index 0000000000..28d055f8eb --- /dev/null +++ b/trunk/docs/manual/upgrading.html.fr @@ -0,0 +1,164 @@ + + + + + + + + Mise à jour de la version 1.3 à la version + 2.0 + + + + +
    + [APACHE DOCUMENTATION] + +

    Apache HTTP Server Version 2.1

    +
    + + + + +

    Mise à de la version 1.3 à la + version 2.0

    + +

    Afin d'aider les personnes souhaitant se mettre à + jour, nous maintenons un document décrivant les + informations critiques concernant les utilisateurs d'Apache. + Ces informations sont sous la forme de brèves notes, et + vous pouvez trouver plus d'informations dans le document Nouvelles + fonctionnalités ou dans le fichier + src/CHANGES.

    + +

    Changement de la configuration à la compilation

    + +
      +
    • Apache utilise maintenant autoconf et + libtool afin de configurer la compilation. + L'utilisation de ces outils est similaire, mais pas tout + à fait identique, au système APACI de + configuration existant dans la version 1.3 d'Apache.
    • + +
    • En plus de l'habituelle sélection de modules que + vous pouvez choisir de compiler, Apache 2.0 a + déplacé la majeure partie du traitement des + requêtes dans les modules + multi-traitements (MPMs).
    • +
    + +

    Changement de la configuration à + l'exécution

    + +
      +
    • La directive CacheNegotiatedDocs prend + maintenant un paramètre qui est soit on + soit off. Les configurations existantes + utilisant la directive CacheNegotiatedDocs + doivent la remplacer par CacheNegotiatedDocs + on.
    • + +
    • + La directive ErrorDocument n'utilise plus de + guillemets ou d'apostrophes au début du + paramètre indiquant le message. Dorénavant, + le message devra être entre guillemets. Par exemple, + la directive + +
      + ErrorDocument 403 "Some Message +
      + devra être remplacé par + +
      + ErrorDocument 403 "Some Message" +
      + Si le second argument n'est pas une URL ou un chemin + valide, il sera traité comme un message. +
    • + +
    • Les directives AccessConfig et + ResourceConfig n'existent plus. Ces directives + peuvent être remplacées de manière + équivalente par la directive Include. Si + vous utilisiez ces directives en utilisant les valeurs par + défaut sans les définir explicitement, vous + devez ajouter les lignes Include + conf/access.conf et Include conf/srm.conf + dans votre fichier httpd.conf. Afin de garantir qu'Apache lit + les différents fichiers de configuration dans le + même ordre que celui pour les anciennes directives, Les + directives Include doivent être + situées à la fin du fichier httpd.conf, celle + représentant srm.conf avant celle pour + access.conf.
    • + +
    • La directive BindAddress n'existe plus. La + même fonctionnalité est fournie par la directive + Listen.
    • + +
    • La directive ExtendedStatus n'existe plus. + Le suivi des statuts a été entièrement + réécrit afin de bénéficier du + nouveau système MPM.
    • + +
    • La directive ServerType n'existe plus. La + méthode utilisée pour servir les requêtes + est déterminée maintenant par la + sélection d'un MPM. Il n'existe pas actuellement de + MPM conçu pour être lancé par inetd.
    • + +
    • Beaucoup de directives qui étaient situées + dans le noyau du serveur pour la version 1.3 se trouvent + maintenant dans les MPMs.
    • + +
    • Les modules mod_log_agent et mod_log_referer qui + traitaient les directives AgentLog, + RefererLog et RefererIgnore ont + été supprimés. Le traçage des + agents et référants et toujours disponible en + utilisant la directive CustomLog du + module mod_log_config.
    • +
    + +

    Changements divers

    + +
      +
    • L'option -S du programme httpd + qui servait à afficher la configuration des + hôtes virtuels est remplacé par -t -D + DUMP_VHOSTS.
    • + +
    • Le module mod_auth_digest, qui était + expérimental dans la version 1.3, est maintenant un + module standard.
    • + +
    • Le module mod_mmap_static, qui était + expérimental dans la version 1.3 a été + remplacé par le module mod_file_cache.
    • +
    + +

    Modules tiers

    + +

    D'énormes changements ont été + réalisés sur l'API du serveur Apache 2.0. Les + modules conçus à l'aide de l'API Apache 1.3 + ne fonctionneront pas sur Apache 2.0 sans + modifications. Plus de détails sont fournis dans la documentation du développeur.

    +
    + +

    Apache HTTP Server Version 2.1

    + Index + + + + + + diff --git a/trunk/docs/manual/upgrading.html.ja.euc-jp b/trunk/docs/manual/upgrading.html.ja.euc-jp new file mode 100644 index 0000000000..5ebff64ac7 --- /dev/null +++ b/trunk/docs/manual/upgrading.html.ja.euc-jp @@ -0,0 +1,224 @@ + + + +1.3 ¤«¤é 2.0 ¤Ø¤Î¥¢¥Ã¥×¥°¥ì¡¼¥É - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    1.3 ¤«¤é 2.0 ¤Ø¤Î¥¢¥Ã¥×¥°¥ì¡¼¥É

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    +
    This translation may be out of date. Check the + English version for recent changes.
    + +

    ¥¢¥Ã¥×¥°¥ì¡¼¥É¤ò´Êñ¤Ë¤¹¤ë¤¿¤á¤Ë¡¢´û¸¤Î Apache ¥æ¡¼¥¶¤Ë + Èó¾ï¤Ë½ÅÍפʾðÊó¤ò¤³¤Îʸ½ñ¤Ë¤Þ¤È¤á¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ïû¤¤ + Ãí°Õ½ñ¤­¤È¤·¤Æ½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£¤è¤ê¾Ü¤·¤¤¾ðÊó¤Ï + ¿·µ¡Ç½¤Îʸ½ñ¤ä + src/CHANGES ¥Õ¥¡¥¤¥ë¤Ç¸«¤Ä¤±¤é¤ì¤ë¤È»×¤¤¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ¥³¥ó¥Ñ¥¤¥ë»þ¤ÎÀßÄê¤ÎÊѹ¹

    + + +
      +
    • Apache ¤Ï ¥Ó¥ë¥É½èÍý¤ÎÀßÄê + ¤Ë autoconf ¤È libtool ¤ò»È¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¤³¤Î¥·¥¹¥Æ¥à¤Ï Apache 1.3 ¤Î APACI ¥·¥¹¥Æ¥à¤È»÷¤Æ¤¤¤Þ¤¹¤¬¡¢ + ¤Þ¤Ã¤¿¤¯Æ±¤¸¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
    • + +
    • Ä̾ï¤Î¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤«¤É¤¦¤«¤òÁªÂò¤Ç¤­¤ë¥â¥¸¥å¡¼¥ë·²¤Ë²Ã¤¨¤Æ¡¢ + Apache 2.0 ¤Ï + ¥ê¥¯¥¨¥¹¥È½èÍý¤Î¼ç¤ÊÉôʬ¤ò ¥Þ¥ë¥Á¥×¥í¥»¥Ã¥·¥ó¥° + ¥â¥¸¥å¡¼¥ë (MPM) ¤Ë°ÜÆ°¤·¤Þ¤·¤¿¡£
    • +
    +
    top
    +
    +

    ¼Â¹Ô»þ¤ÎÀßÄê¤ÎÊѹ¹

    + + +
      +
    • Apache 1.3 ¤Î»þ¤Ë¥³¥¢¥µ¡¼¥Ð¤Ë¤¢¤Ã¤¿Â¿¤¯¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + MPM ¤Ë°ÜÆ°¤·¤Þ¤·¤¿¡£¥µ¡¼¥Ð¤Ë Apache 1.3 ¤È¤Ç¤­¤ë¤À¤±Æ±¤¸¿¶¤ëÉñ¤¤¤ò + ¤µ¤»¤¿¤¤¾ì¹ç¤Ï¡¢prefork MPM ¤ò + Áª¤ó¤Ç¤¯¤À¤µ¤¤¡£Â¾¤Î MPM ¤Ï¥×¥í¥»¥¹¤ÎºîÀ®¤ä¥ê¥¯¥¨¥¹¥È¤Î½èÍý¤Î + À©¸æ¤Ë°Û¤Ê¤Ã¤¿¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹¡£
    • + +
    • Proxy ¥â¥¸¥å¡¼¥ë ¤Ï + HTTP/1.1 ¤ËÂбþ¤¹¤ë¤¿¤á¤ËºÆ¹½À®¤µ¤ì¤Þ¤·¤¿¡£½ÅÍפÊÊѹ¹ÅÀ¤È¤·¤Æ¤Ï¡¢ + ¥×¥í¥­¥·¤Î¥¢¥¯¥»¥¹À©¸æ¤¬ <Directory proxy:> ¥Ö¥í¥Ã¥¯¤Î + Âå¤ï¤ê¤Ë <Proxy> + ¥Ö¥í¥Ã¥¯¤ËÃÖ¤«¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¢¤È¤¤¤¦¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£
    • + +
    • ¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Ë¤Ï¡¢PATH_INFO (ËÜÅö¤Î¥Õ¥¡¥¤¥ë̾¤Î¸å¤Ë³¤¯ + ¥Ñ¥¹¾ðÊó) ¤Î°·¤¤¤¬ÊѤï¤Ã¤¿¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£°ÊÁ°¤Ï¥Ï¥ó¥É¥é¤È¤·¤Æ + ¼ÂÁõ¤µ¤ì¤Æ¤¤¤¿¤â¤Î¤¬¥Õ¥£¥ë¥¿¤È¤·¤Æ¼ÂÁõ¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤â¤Î¤Ï + PATH_INFO ¤Î¤¢¤ë¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó¡£INCLUDES ¤ä + PHP ¤Ê¤É¤Î¥Õ¥£¥ë¥¿¤Ï + ¥³¥¢¥Ï¥ó¥É¥é¤Î¾å¤Ë¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢PATH_INFO + ÉÕ¤­¤Î¥ê¥¯¥¨¥¹¥È¤òµñÈݤ·¤Þ¤¹¡£ + AcceptPathInfo + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¥³¥¢¥Ï¥ó¥É¥é¤¬ PATH_INFO + ÉÕ¤­¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¤Ç¤­¡¢¤½¤ì¤Ë¤è¤Ã¤Æ SSI Åù¤Ç + PATH_INFO ¤ò»È¤¦µ¡Ç½¤òÉü³è¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
    • + +
    • CacheNegotiatedDocs + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï on ¤â¤·¤¯¤Ï off ¤È¤¤¤¦°ú¿ô¤ò + ¼è¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£´û¤Ë¸ºß¤·¤Æ¤¤¤ë + CacheNegotiatedDocs ¤Ï + CacheNegotiatedDocs on + ¤ËÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£
    • + +
    • + ErrorDocument + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Æ¥­¥¹¥È¥á¥Ã¥»¡¼¥¸¤ò + ¼¨¤¹¤¿¤á¤Ë°ú¿ô¤ÎºÇ½é¤Ë»È¤ï¤ì¤Æ¤¤¤¿°úÍÑÉä¤ò»È¤ï¤Ê¤¤¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + Âå¤ï¤ê¤Ë¡¢¥á¥Ã¥»¡¼¥¸¤òÆó½Å°úÍÑÉä¤Ç°Ï¤à¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ + Î㤨¤Ð¡¢´û¸¤Î + +

      + ErrorDocument 403 "Some Message +

      + ¤Ï + +

      + ErrorDocument 403 "Some Message" +

      + + ¤ËÃÖ¤­´¹¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ÆóÈÖÌܤΰú¿ô¤Ï¡¢Í­¸ú¤Ê URL ¤ä¥Ñ¥¹Ì¾¤Ç¤Ê¤¤¸Â¤ê + ¥Æ¥­¥¹¥È¥á¥Ã¥»¡¼¥¸¤È¤·¤Æ°·¤ï¤ì¤Þ¤¹¡£ +
    • + +
    • AccessConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È + ResourceConfig ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£ + ¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏƱÅù¤Îµ¡Ç½¤ò»ý¤Ä + Include ¤Ç + ÃÖ¤­´¹¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ÀßÄê¥Õ¥¡¥¤¥ë¤Ë¼è¤ê¹þ¤àÂå¤ï¤ê¤Ë¡¢ + ¾å¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤò»È¤Ã¤Æ¤¤¤¿¾ì¹ç¤Ï¡¢ + httpd.conf ¤Ë Include conf/access.conf ¤È + Include conf/srm.conf ¤òÄɲ乤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£ + °ÊÁ°¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ë½çÈ֤Τ褦¤Ë Apache ¤¬ÀßÄê¥Õ¥¡¥¤¥ë¤ò + Æɤ߹þ¤à¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¤Ï¡¢httpd.conf ¤ÎºÇ¸å¤Ë + srm.conf¡¢access.conf ¤Î½ç¤Ë¤½¤ì¤¾¤ì + Include + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¤¤Æ¤¯¤À¤µ¤¤¡£
    • + +
    • BindAddress ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È Port + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£Æ±Åù¤Îµ¡Ç½¤Ï¤è¤ê½ÀÆð¤Ê + Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤êÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡£
    • + +
    • Port ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache-1.3 ¤Ë¤Ï¼«¸Ê»²¾È URL ¤Ç + »È¤ï¤ì¤ë¥Ý¡¼¥ÈÈÖ¹æ¤òÀßÄꤹ¤ë¡¢¤È¤¤¤¦»ÈÍÑË¡¤â¤¢¤ê¤Þ¤·¤¿¡£ + ¤³¤ì¤Ï Apache-2.0 ¤Ç¤Ï¿·¤·¤¤ + ServerName + ¹½Ê¸¤Ë¤è¤Ã¤Æ¹Ô¤Ê¤¤¤Þ¤¹¡£°ì¤Ä¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç¥Û¥¹¥È̾¤È + ¼«¸Ê»²¾È URL ¤ÎξÊý¤òÀßÄê¤Ç¤­¤ë¤è¤¦¤Ë¹½Ê¸¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿¡£
    • + +
    • ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£ + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¦ÊýË¡¤Ï MPM ¤ÎÁªÂò¤Ë¤è¤ê·èÄꤵ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£ + ¸½»þÅÀ¤Ç¤Ï inetd ¤«¤éµ¯Æ°¤µ¤ì¤ë¤è¤¦¤ËÀ߷פµ¤ì¤¿ MPM ¤Ï¤¢¤ê¤Þ¤»¤ó¡£
    • + +
    • AgentLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + RefererLog ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¡¢ + RefererIgnore ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤òÄ󶡤·¤Æ¤¤¤¿ + mod_log_agent ¤È mod_log_referer + ¥â¥¸¥å¡¼¥ë¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£ + Agent ¥í¥°¤È refere ¥í¥°¤Ï mod_log_config ¤Î + CustomLog + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¼Â¸½²Äǽ¤Ç¤¹¡£
    • + +
    • AddModule ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È ClearModuleList + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¡¢ + ¥â¥¸¥å¡¼¥ë¤¬Àµ¤·¤¤½çÈ֤ǸƤФì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Æ¤¤¤Þ¤·¤¿¡£ + Apache 2.0 ¤Î¿· API ¤Ï¥â¥¸¥å¡¼¥ë¤¬ÌÀ¼¨Åª¤Ë½çÈÖ¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë + ¤Ê¤Ã¤Æ¤ª¤ê¡¢¤³¤ì¤é¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏɬÍפʤ¯¤Ê¤ê¤Þ¤·¤¿¡£
    • + +
    • FancyIndexing ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿¡£ + Ʊ¤¸µ¡Ç½¤Ï IndexOptions + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î FancyIndexing ¥ª¥×¥·¥ç¥ó¤Ç + ¼Â¸½¤Ç¤­¤Þ¤¹¡£
    • + +
    • mod_negotiation ¤Ë¤è¤ë MultiViews + ¥³¥ó¥Æ¥ó¥È¥Í¥´¥·¥¨¡¼¥·¥ç¥óµ»½Ñ¤Ï¡¢ + ¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥¡¥¤¥ë¥Þ¥Ã¥Á¥ó¥°¤¬¤è¤ê¸·Ì©¤Ê¤â¤Î¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿¡£ + ¥Í¥´¥·¥¨¡¼¥È²Äǽ¤Ê¥Õ¥¡¥¤¥ë¤Î¾ì¹ç¤Ë¤Î¤ßÁªÂò¤µ¤ì¤Þ¤¹¡£ + °ÊÁ°¤ÎµóÆ°¤Ï¡¢MultiviewsMatch + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤ÇÉü³è¤Ç¤­¤Þ¤¹¡£
    • + +
    • (¥Ð¡¼¥¸¥ç¥ó 2.0.51 ¤«¤é) +

      ErrorHeader ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÏÉÔŬÀÚ¤Ê̾Á° + ¤À¤Ã¤¿¤¿¤á¤ËÇѻߤµ¤ì¡¢¤½¤Îµ¡Ç½¤Ï Header ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÅý¹ç¤µ¤ì¤Þ¤·¤¿¡£ + ˾¤ß¤ÎÆ°ºî¤òÆÀ¤ë¤¿¤á¤Ë¤Ï ErrorHeader ¤ÎÂå¤ï¤ê¤Ë

      + +

      + Header always set foo bar +

      + +

      ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£

    • +
    +
    top
    +
    +

    ¤½¤Î¾¤ÎÊѹ¹

    + + +
      +
    • Apache 1.3 ¤Ç¼Â¸³Åª¤Ê¥â¥¸¥å¡¼¥ë¤À¤Ã¤¿ + mod_auth_digest ¤Ï + ɸ½à¥â¥¸¥å¡¼¥ë¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    • + +
    • Apache 1.3 ¤Ç¼Â¸³Åª¤Ê¥â¥¸¥å¡¼¥ë¤À¤Ã¤¿ mod_mmap_static ¤Ï + mod_file_cache ¤ÇÃÖ¤­´¹¤¨¤é¤ì¤Þ¤·¤¿¡£
    • + +
    • Apache ¤ÎÇÛÉÛ¤ÏÆÈΩ¤·¤¿ src ¥Ç¥£¥ì¥¯¥È¥ê¤¬ + ¤Ê¤¯¤Ê¤ë¤è¤¦¤Ë¡¢´°Á´¤ËºÆ¹½À®¤µ¤ì¤Þ¤·¤¿¡£¤½¤ÎÂå¤ï¤ê¤Ë¡¢ + ¥½¡¼¥¹¤Ï¼ç¥Ç¥£¥ì¥¯¥È¥ê¤ËÏÀÍýŪ¤ËÇÛÃÖ¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¡¢ + ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤¿¥µ¡¼¥Ð¤Î¥¤¥ó¥¹¥È¡¼¥ë¤ÏÊ̥ǥ£¥ì¥¯¥È¥ê¤Ø + ¹Ô¤Ê¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
    • +
    +
    top
    +
    +

    ¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¥â¥¸¥å¡¼¥ë

    + + +

    Apache 2.0 ¤Î¥µ¡¼¥Ð API ¤Ë¤Ï¿¤¯¤ÎÊѹ¹¤¬²Ã¤¨¤é¤ì¤Þ¤·¤¿¡£ + Apache 1.3 ÍѤδû¸¤Î¥â¥¸¥å¡¼¥ë¤Ï Apache 2.0 ¤Ç¤Ï½¤Àµ¤Ê¤·¤Ç¤Ï + Æ°¤­¤Þ¤»¤ó¡£¾ÜºÙ¤Ï ³«È¯¼Ô¸þ¤±Ê¸½ñ ¤Ë¤¢¤ê¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.html.ko.euc-kr b/trunk/docs/manual/upgrading.html.ko.euc-kr new file mode 100644 index 0000000000..90d949ec84 --- /dev/null +++ b/trunk/docs/manual/upgrading.html.ko.euc-kr @@ -0,0 +1,206 @@ + + + +1.3¿¡¼­ 2.0À¸·Î ¾÷±×·¹À̵å - Apache HTTP Server + + + + + +
    <-
    +

    1.3¿¡¼­ 2.0À¸·Î ¾÷±×·¹À̵å

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + +

    ¿ì¸®´Â ±âÁ¸ ¾ÆÆÄÄ¡ »ç¿ëÀÚ°¡ ¾÷±×·¹À̵åÇÏ´Â °ÍÀ» µ½±âÀ§ÇØ + Áß¿äÇÑ Á¤º¸¸¦ ¾Ë·ÁÁÖ´Â ¹®¼­¸¦ Á¦°øÇÑ´Ù. ÀÌ ¹®¼­´Â °£´ÜÇÑ + ¿ä¾àÀ̹ǷÎ, »õ·Î¿î ±â´É + ¹®¼­³ª src/CHANGES ÆÄÀÏ¿¡¼­ Á¤º¸¸¦ ã¾ÆºÁ¾ß + ÇÑ´Ù.

    +
    + +
    top
    +
    +

    ÄÄÆÄÀϽà ±¸¼º º¯È­

    + + +
      +
    • ¾ÆÆÄÄ¡´Â ÀÌÁ¦ ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ°ú ¼³Ä¡¸¦ À§ÇØ + autoconf¿Í libtool ½Ã½ºÅÛÀ» + »ç¿ëÇÑ´Ù. ÀÌ ½Ã½ºÅÛÀÇ »ç¿ë¹ýÀº Apache 1.3ÀÇ APACI ½Ã½ºÅÛ°ú + °°Áö´Â ¾ÊÁö¸¸ ºñ½ÁÇÏ´Ù.
    • + +
    • ÄÄÆÄÀÏ ¿©ºÎ¸¦ ¼±ÅÃÇÒ ¸ðµâ¿Ü¿¡ Apache 2.0Àº ¿äûÀ» + ó¸®ÇÏ´Â ÁÖ¿ä ºÎºÐÀ» ´ÙÁßó¸® ¸ðµâ + (Multi-Processing Modules) (MPM)·Î ¿Å°å´Ù.
    • +
    +
    top
    +
    +

    ½ÇÇà½Ã ¼³Á¤ º¯È­

    + + +
      +
    • Apache 1.3¿¡¼­ ¼­¹ö Çٽɿ¡ ÀÖ¾ú´ø ¸¹Àº Áö½Ã¾îµéÀÌ + ÀÌÁ¦´Â MPM¿¡ ÀÖ´Ù. ¼­¹ö°¡ Apache 1.3°ú ÃÖ´ëÇÑ ºñ½ÁÇÏ°Ô + µ¿ÀÛÇÏ±æ ¹Ù¶õ´Ù¸é prefork MPMÀ» ¼±ÅÃÇØ¾ß + ÇÑ´Ù. ´Ù¸¥ MPMÀº ´Ù¸¥ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º »ý¼º°ú + ¿äûÀÇ Ã³¸®¸¦ Á¶ÀýÇÑ´Ù.
    • + +
    • proxy ¸ðµâÀº HTTP/1.1¿¡ + ¸ÂÃß¾î ¼öÁ¤µÇ¾ú´Ù. Áß¿äÇÑ º¯È­Áß Çϳª´Â ÀÌÁ¦ ÇÁ·Ï½Ã Á¢±ÙÁ¦¾î°¡ + <Directory proxy:> ºí·ÏÀÌ ¾Æ´Ï¶ó + <Proxy> + ºí·Ï¿¡ À§Ä¡ÇÏ´Â Á¡ÀÌ´Ù.
    • + +
    • ¸î¸î ¸ðµâ¿¡¼­ PATH_INFO (ÁøÂ¥ °æ·Î¸í + µÚ¿¡ ³ª¿À´Â °æ·Î Á¤º¸) ó¸® ¹æ½ÄÀÌ º¯°æµÇ¾ú´Ù. Àü¿¡ + Çڵ鷯¿´Áö¸¸ ÀÌÁ¦ ÇÊÅÍ·Î ±¸ÇöµÇ´Â ¸ðµâÀº ´õ ÀÌ»ó + PATH_INFO°¡ ÀÖ´Â ¿äûÀ» ¹Þ¾ÆµéÀÌÁö ¸øÇÑ´Ù. + INCLUDES³ª PHP¿Í °°Àº ÇÊÅÍ´Â + core Çڵ鷯 À§¿¡ ±¸ÇöµÇ±â¶§¹®¿¡ PATH_INFO°¡ + ÀÖ´Â ¿äûÀ» °ÅºÎÇÑ´Ù. core Çڵ鷯°¡ PATH_INFO°¡ + ÀÖ´Â ¿äûÀ» ¹Þ¾ÆµéÀÌ°í server-side include¿¡¼­ + PATH_INFO¸¦ »ç¿ëÇÏ°Ô ÇÏ·Á¸é, AcceptPathInfo Áö½Ã¾î¸¦ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    • + +
    • CacheNegotiatedDocs + Áö½Ã¾î´Â ÀÌÁ¦ ¾Æ±Ô¸ÕÆ®·Î on°ú off¸¦ + ¹Þ´Â´Ù. ±âÁ¸ÀÇ CacheNegotiatedDocs´Â + CacheNegotiatedDocs onÀ¸·Î ¼öÁ¤ÇØ¾ß ÇÑ´Ù.
    • + +
    • + ErrorDocument Áö½Ã¾î´Â + ´õÀÌ»ó ¸Þ¼¼Áö¸¦ ³ªÅ¸³»´Â ¾Æ±Ô¸ÕÆ® ¾Õ¿¡ µû¿ÈÇ¥¸¦ »ç¿ëÇÏÁö + ¾Ê´Â´Ù. ´ë½Å ½Öµû¿ÈÇ¥·Î ¸Þ¼¼Áö¸¦ ¹­¾î¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î °ú°Å + +

      + ErrorDocument 403 "Some Message +

      + ´Â ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇØ¾ß ÇÑ´Ù. + +

      + ErrorDocument 403 "Some Message" +

      + µÎ¹ø° ¾Æ±Ô¸ÕÆ®°¡ À¯È¿ÇÑ URLÀ̳ª °æ·Î¸íÀÌ ¾Æ´Ï¶ó¸é ¸Þ¼¼Áö·Î + °£ÁÖÇÑ´Ù. +
    • + +
    • AccessConfig¿Í ResourceConfig + Áö½Ã¾î´Â »ç¶óÁ³´Ù. ±âÁ¸¿¡ »ç¿ëÇÏ´ø Áö½Ã¾î´Â °°Àº ±â´ÉÀ» + ÇÏ´Â Include Áö½Ã¾î·Î + ´ëüÇÒ ¼ö ÀÖ´Ù. °ú°Å¿¡ ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ Áö½Ã¾îµéÀ» »ç¿ëÇÏÁö¾Ê°í + ÀÌ Áö½Ã¾îµéÀÇ ±âº»°ªÀ» »ç¿ëÇß´Ù¸é, http.conf¿¡ + Include conf/access.conf¿Í Include + conf/srm.conf¸¦ Ãß°¡ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ ÀÌÀü + Áö½Ã¾î¿Í °°Àº ¼ø¼­·Î ¼³Á¤ÆÄÀÏÀ» ÀаÔÇÏ·Á¸é + Include Áö½Ã¾î¸¦ + httpd.conf ³¡¿¡ µÎ°í, srm.confÀÌ + access.conf ¾Õ¿¡ ³ª¿Í¾ß ÇÑ´Ù.
    • + +
    • BindAddress¿Í Port Áö½Ã¾î´Â + »ç¶óÁ³´Ù. ´õ À¯¿¬ÇÑ Listen + Áö½Ã¾î°¡ °°Àº ±â´ÉÀ» ÇÑ´Ù.
    • + +
    • Apache-1.3¿¡¼­ Port´Â ÀÚ±âÂüÁ¶ + URLÀÇ Æ÷Æ® ¹øÈ£¸¦ ¼³Á¤ÇÏ´Â Àϵµ Çß´Ù. Apache-2.0¿¡¼­ ÀÌ + ±â´ÉÀº »õ·Î¿î ServerNameÀ¸·Î + ÇÑ´Ù. ÇÑ Áö½Ã¾î¿¡ È£½ºÆ®¸í°ú ÀÚ±âÂüÁ¶ URLÀ» À§ÇÑ + Æ÷Æ® ¹øÈ£¸¦ °°ÀÌ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
    • + +
    • ServerType Áö½Ã¾î´Â »ç¶óÁ³´Ù. ¿äûÀ» + ¼­ºñ½ºÇÏ´Â ¹æ¹ýÀº ÀÌÁ¦ MPM ¼±Åÿ¡ ´Þ·È´Ù. ÇöÀç inetd¿¡¼­ + ½ÃÀÛÇϵµ·Ï ¼³°èµÈ MPMÀº ¾ø´Ù.
    • + +
    • AgentLog, RefererLog, + RefererIgnore Áö½Ã¾î¸¦ Á¦°øÇÑ + mod_log_agent¿Í mod_log_referer + ¸ðµâÀÌ ¾ø¾îÁ³´Ù. agent ·Î±×¿Í referer ·Î±×´Â + mod_log_configÀÇ CustomLog Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© °è¼Ó Á¦°øµÈ´Ù.
    • + +
    • AddModule°ú ClearModuleList + Áö½Ã¾î´Â »ç¶óÁ³´Ù. ÀÌ Áö½Ã¾îµéÀº ¸ðµâÀ» ¿Ã¹Ù¸¥ ¼ø¼­·Î + È°¼ºÈ­ÇÏ·Á°í »ç¿ëÇß´Ù. »õ·Î¿î Apache 2.0 API´Â ¸ðµâÀÌ + È°¼ºÈ­µÇ´Â ¼ø¼­¸¦ ¸í½ÃÀûÀ¸·Î ÁöÁ¤ÇÒ ¼ö À־, ÀÌ Áö½Ã¾îµéÀÌ + ÇÊ¿ä¾ø°Ô µÇ¾ú´Ù.
    • + +
    • FancyIndexing Áö½Ã¾î°¡ ¾ø¾îÁ³´Ù. + IndexOptions + Áö½Ã¾îÀÇ FancyIndexing ¿É¼ÇÀÌ °°Àº ±â´ÉÀ» ÇÑ´Ù.
    • + +
    • mod_negotiationÀÇ MultiViews ³»¿ëÇù»óÀÌ + ´õ ¾ö°ÝÇÏ°Ô ±âº»ÆÄÀÏÀ» ã´Â´Ù. ³»¿ëÇù»óÀº Çù»ó°¡´ÉÇÑ + ÆÄÀÏ Áß¿¡¼­¸¸ ¼±ÅÃÇÑ´Ù. MultiviewsMatch Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ÀÌÀü°ú °°ÀÌ µ¿ÀÛÇÏ°Ô ÇÒ ¼ö ÀÖ´Ù.
    • + +
    • (2.0.51 ¹öÀü ÀÌÈÄ) +

      ErrorHeader Áö½Ã¾î´Â À߸øµÈ ¸íĪÀ¸·Î, + ÀÌ Áö½Ã¾î°¡ ´ã´çÇÑ ±â´ÉÀº Header Áö½Ã¾î·Îµµ °¡´ÉÇÏ´Ù. + ¿øÇÏ´Â ±â´ÉÀ» À§ÇØ,

      + +

      + Header always set ¾î¼°í Àú¼°í +

      + +

      ¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù.

    • +
    +
    top
    +
    +

    ±âŸ º¯È­

    + + +
      +
    • Apache 1.3¿¡¼­ ½ÇÇèÀûÀÌ¿´´ø mod_auth_digest + ¸ðµâÀÌ ÀÌÁ¦ Ç¥ÁØ ¸ðµâÀÌ µÇ¾ú´Ù.
    • + +
    • Apache 1.3¿¡¼­ ½ÇÇèÀûÀÌ¿´´ø mod_mmap_static + ¸ðµâÀÌ mod_file_cache·Î ´ëüµÇ¾ú´Ù.
    • + +
    • ¹èÆ÷º»ÀÌ ¿ÏÀüÈ÷ »õ·Î ±¸¼ºµÇ¾î ´õÀÌ»ó µ¶¸³µÈ src + µð·ºÅ丮°¡ ¾ø´Ù. ´ë½Å ¼Ò½º´Â ÁÖ ¹èÆ÷º» µð·ºÅ丮 ¾Æ·¡ ³í¸®ÀûÀ¸·Î + ±¸¼ºµÇÀÖ°í, ÄÄÆÄÀÏÇÑ ¼­¹ö´Â ´Ù¸¥ µð·ºÅ丮·Î ¼³Ä¡µÈ´Ù.
    • +
    +
    top
    +
    +

    Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ

    + + +

    Apache 2.0¿¡¼­ ¼­¹ö API°¡ ¸¹ÀÌ º¯°æµÇ¾ú´Ù. Apache 1.3 API¿¡ + ¸ÂÃçÁø ±âÁ¸ ¸ðµâÀ» ¼öÁ¤¾øÀÌ Apache 2.0¿¡¼­ »ç¿ëÇÒ ¼ö + ¾ø´Ù. ÀÚ¼¼ÇÑ Á¤º¸´Â °³¹ßÀÚ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.html.pt-br b/trunk/docs/manual/upgrading.html.pt-br new file mode 100644 index 0000000000..5f3bd91caa --- /dev/null +++ b/trunk/docs/manual/upgrading.html.pt-br @@ -0,0 +1,227 @@ + + + +Atualizando da versão 1.3 para 2.0 - Servidor HTTP Apache + + + + + +
    <-
    +

    Atualizando da versão 1.3 para 2.0

    +
    +

    Línguas Disponíveis:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    +
    Esta tradução pode estar desatualizada. + Verifique a versão em Inglês para mudanças recentes.
    + +

    Com a finalidade de ajudar as pessoas na atualização do servidor, + nós mantemos um documento que descreve informações críticas para + os usuários já existentes do Apache. Essas informações tem o + intuito de serem breves notas e você deverá encontrar mais + informações no documento Novas Funcionalidades, ou no + arquivo src/CHANGES.

    +
    + +
    top
    +
    +

    Mudanças na Configuração em tempo de Compilação

    + + +
      +
    • O Apache agora usa o sistema autoconf + e libtool para + configurar o processo de construção. + A utilização desse sistema é similar, mas não o + mesmo, a usar o sistema APACI do Apache 1.3
    • + +
    • Além da seleção habitual de módulos que você + pode escolher para compilar, o Apache 2.0 mudou a parte + principal de processamentos de pedidos para os Módulos Multi-Processamento (MPMs).
    • +
    +
    top
    +
    +

    Mudanças na Configuração em tempo de Execução

    + + +
      +
    • Muitas diretrizes que estavam no núcleo do servidor + no Apache 1.3 estão agora nos MPMs. Se você desejar que + o funcionamento do servidor seja o mais similar possível ao + do Apache 1.3, você deve selecionar o MPM prefork. + Os outros MPMs terão diretrizes diferentes para controlar + a criação de processos e o processamento de pedidos.
    • + +
    • O módulo proxy foi reconstruído + para o padrão HTTP/1.1. Ao longo das mudanças importantes, + o controle de acesso ao proxy agora fica dentro de um bloco + <Proxy>, + ao invés de um bloco <Directory proxy:>.
    • + +
    • A operação com PATH_INFO (informação de + caminho procedente depois do nome do arquivo verdadeiro) mudou + para alguns módulos. Módulos que eram previamente implementados + como manipuladores mas agora são implementados como filtros + não podem mais aceitar pedidos com PATH_INFO. + Filtros como INCLUDES + ou PHP são implementados + no topo dos manipuladores principais, rejeitando pedidos + com PATH_INFO. Você pode usar a diretriz + AcceptPathInfo + para forçar o manipulador principal a aceitar pedidos + com PATH_INFO e assim restaurar a habilidade + de usá-lo em inclusões por parte do servidor (SSI).
    • + +
    • A diretriz CacheNegotiatedDocs agora aceita + o argumento on ou off. Instâncias + existentes de CacheNegotiatedDocs deverão + ser substituídas por CacheNegotiatedDocs on.
    • + +
    • + A diretriz ErrorDocument + não usa mais aspas no começo do argumento para indicar + mensagens de texto. Ao invés disso, você deve colocar + a mensagem inteira entre aspas. Por exemplo, instâncias + existentes de + +

      + ErrorDocument 403 "Alguma mensagem +

      + devem ser substituídas por + +

      + ErrorDocument 403 "Alguma mensagem" +

      + + Contanto que o segundo argumento não seja uma + URL válida ou um caminho de arquivo, irá ser + tratado como uma mensagem de texto. +
    • + +
    • As diretrizes AccessConfig e + ResourceConfig não existem mais. + Instâncias existentes dessas diretrizes podem ser substituídas + com a diretriz Include + que possui uma funcionalidade equivalente. Se você estava + fazendo uso dos valores padrões dessas diretrizes sem incluí-las + nos arquivos de configuração, você provavelmente terá + que adicionar Include conf/access.conf e + Include conf/srm.conf ao seu httpd.conf. + Com o fim de assegurar que o Apache leia os arquivos de + configuração na mesma ordem que as diretrizes velhas usavam, + a diretriz Include deve ser colocada + no final do httpd.conf, com uma entrada para + srm.conf antes de access.conf.
    • + +
    • As diretrizes BindAddress and Port + não existem mais. Uma funcionalidade equivalente é fornecida com + uma diretriz mais flexível Listen.
    • + +
    • Outro uso da diretriz Port no Apache-1.3 + era ajustar o número da porta usada em URLs auto-referenciáveis. + O equivalente no Apache-2.0 é a nova sintaxe ServerName: ela foi modificada para permitir que + sejam especificados ambos "hostname" e o número da porta + para URLs auto-referenciáveis em uma só diretriz.
    • + +
    • A diretriz ServerType não existe mais. + O método usado para atender pedidos é determinado pela + seleção de MPM. Atualmente não existe nenhuma MPM projetada + para ser executada pelo inetd.
    • + +
    • Os módulos mod_log_agent e mod_log_referer + que forneciam as diretrizes AgentLog, + RefererLog e RefererIgnore foram removidas. + Registros de agentes e referências ainda estão disponíveis + usando a diretriz CustomLog do + mod_log_config.
    • + +
    • As diretrizes AddModule e + ClearModuleList não existem mais. + Essas diretrizes eram usadas para garantir que módulos + pudessem ser habilitados na ordem correta. A nova API do + Apache 2.0 permite que os módulos especifiquem explicitamente + a sua ordem, eliminando a necessidade dessas diretrizes.
    • + +
    • A diretriz FancyIndexing foi removida. + A mesma funcionalidade está disponível através da + opção FancyIndexing da diretriz IndexOptions.
    • + +
    • A técnica de negociação de conteúdo (content-negotiation) + MultiViews fornecida pelo mod_negotiation + se tornou mais rigorosa em sua combinação de arquivo + padrão. Ela irá selecionar apenas arquivos negociáveis + (negotiable). O comportamento antigo pode ser restaurado usando a + diretriz MultiviewsMatch.
    • + +
    • (desde a versão 2.0.51) +

      A funcionalidade da diretriz ErrorHeader + foi colocada em conjunto com a diretriz Header, já que era um + uso de um nome impróprio. Utilize

      + +

      + Header always set foo bar +

      + +

      para obter o comportamento desejado.

    • +
    +
    top
    +
    +

    Mudanças Gerais

    + + +
      +
    • O módulo mod_auth_digest, que era + experimental no Apache 1.3, é agora um módulo padrão.
    • + +
    • O módulo mod_mmap_static, que era experimental no + Apache 1.3, foi substituído com mod_file_cache.
    • + +
    • A distribuição foi completamente reorganizada para + não conter mais um diretório src independente. + Em seu lugar, os fontes são organizados + logicamente no diretório principal da distribuição e + a instalação do servidor compilado deve ser direcionada + à um diretório separado.
    • +
    +
    top
    +
    +

    Módulos de Terceiros

    + + +

    Mudanças extensivas foram feitas na API do servidor + no Apache 2.0. Módulos existentes projetados para a API + do Apache 1.3, não funcionarão no Apache + 2.0 sem modificações. Detalhes serão fornecidos na + documentação do desenvolvedor.

    +
    +
    +

    Línguas Disponíveis:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.html.ru.koi8-r b/trunk/docs/manual/upgrading.html.ru.koi8-r new file mode 100644 index 0000000000..c00462a2da --- /dev/null +++ b/trunk/docs/manual/upgrading.html.ru.koi8-r @@ -0,0 +1,203 @@ + + + +ðÅÒÅÈÏÄ ÏÔ ×ÅÒÓÉÉ 1.3 Ë ×ÅÒÓÉÉ 2.0 - HTTP ÓÅÒ×ÅÒ Apache + + + + + +
    <-
    +

    ðÅÒÅÈÏÄ ÏÔ ×ÅÒÓÉÉ 1.3 Ë ×ÅÒÓÉÉ 2.0

    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    +
    This translation may be out of date. Check the + English version for recent changes.
    + +

    üÔÏÔ ÄÏËÕÍÅÎÔ ÎÅÏÂÈÏÄÉÍ ÄÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÐÏÍÏÞØ ÐÏÌØÚÏ×ÁÔÅÌÑÍ + ÐÅÒÅÊÔÉ Ë ÉÓÐÏÌØÚÏ×ÁÎÉÀ ÓÅÒ×ÅÒÁ ×ÅÒÓÉÉ 2.0. úÄÅÓØ ×Ù ÎÁÊÄÅÔÅ ÌÉÛØ + ËÒÁÔËÉÅ ÚÁÍÅÞÁÎÉÑ; ÂÏÌÅÅ ÐÏÄÒÏÂÎÕÀ ÉÎÆÏÒÍÁÃÉÀ Ï ÎÏ×Ï××ÅÄÅÎÉÑÈ ÍÏÖÎÏ + ÎÁÊÔÉ ÌÉÂÏ × ÄÏËÕÍÅÎÔÅ îÏ×ÙÅ ×ÏÚÍÏÖÎÏÓÔÉ, ÌÉÂÏ × ÆÁÊÌÅ src/CHANGES.

    +
    + +
    top
    +
    +

    éÚÍÅÎÅÎÉÑ × ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÉ ÓÂÏÒËÉ ÓÅÒ×ÅÒÁ

    + + +
      +
    • Apache ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÅÔ ÓÉÓÔÅÍÕ autoconf É + libtool ÄÌÑ ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ ÐÒÏÃÅÓÓÁ ÓÂÏÒËÉ. + éÓÐÏÌØÚÏ×ÁÎÉÅ ÜÔÏÊ ÓÉÓÔÅÍÙ ÐÏÈÏÖÅ ÎÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅ + APACI × Apache 1.3, ÈÏÔÑ É ÎÅ Ñ×ÌÑÅÔÓÑ ÁÂÓÏÌÀÔÎÏ ÔÅÍ ÖÅ ÓÁÍÙÍ.
    • + +
    • ÷ ÄÏÂÁ×ÏË Ë ÏÂÙÞÎÏÍÕ ÓÐÉÓËÕ ÍÏÄÕÌÅÊ, ËÏÔÏÒÙÅ ×Ù ÍÏÖÅÔÅ + ×ÙÂÒÁÔØ ÐÒÉ ÓÂÏÒËÅ ÓÅÒ×ÅÒÁ, × Apache 2.0 ÐÏÑ×ÉÌÉÓØ ÍÕÌØÔÉ - ÐÒÏÃÅÓÓÎÙÅ ÍÏÄÕÌÉ (íð - ÍÏÄÕÌÉ), × ËÏÔÏÒÙÈ ÔÅÐÅÒØ + ÓËÏÎÃÅÎÔÒÉÒÏ×ÁÎÁ ÏÓÎÏ×ÎÁÑ ÞÁÓÔØ ËÏÄÁ, ÏÔ×ÅÞÁÀÝÅÇÏ ÚÁ ÏÂÒÁÂÏÔËÕ + ÚÁÐÒÏÓÏ×.
    • +
    +
    top
    +
    +

    éÚÍÅÎÅÎÉÑ × ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÉ ÒÁÂÏÔÙ ÓÅÒ×ÅÒÁ

    + + +
      +
    • íÎÏÇÉÅ ÉÚ ÔÅÈ ÄÉÒÅËÔÉ×, ËÏÔÏÒÙÅ ÏÂÓÌÕÖÉ×ÁÌÉÓØ ÑÄÒÏÍ ÓÅÒ×ÅÒÁ + Apache 1.3, ÔÅÐÅÒØ ÐÅÒÅÎÅÓÅÎÙ × ÍÕÌØÔÉ - ÐÒÏÃÅÓÓÎÙÅ ÍÏÄÕÌÉ. åÓÌÉ ×Ù + ÈÏÔÉÔÅ, ÞÔÏÂÙ ÐÏ×ÅÄÅÎÉÅ ÓÅÒ×ÅÒÁ ÂÙÌÏ ÎÁÉÂÏÌÅÅ ÐÒÉÂÌÉÖÅÎÏ Ë ÐÏ×ÅÄÅÎÉÀ + Apache 1.3, ÔÏ ÐÒÉ ÓÂÏÒËÅ ×Ù ÄÏÌÖÎÙ ×ÙÂÒÁÔØ íð-ÍÏÄÕÌØ prefork. äÒÕÇÉÅ íð-ÍÏÄÕÌÉ ÐÒÅÄÏÓÔÁ×ÌÑÀÔ + ÉÎÙÅ ÄÉÒÅËÔÉ×Ù, ÏÔ×ÅÞÁÀÝÉÅ ÚÁ ÒÁÂÏÔÕ ÐÒÏÃÅÓÓÏ× ÓÅÒ×ÅÒÁ É ÏÂÒÁÂÏÔËÕ + ÚÁÐÒÏÓÏ×.
    • + +
    • ðÒÏËÓÉ ÍÏÄÕÌØ ÂÙÌ ÐÅÒÅÐÉÓÁÎ, + É ÔÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÓÐÅÃÉÆÉËÁÃÉÀ HTTP/1.1. ïÄÎÉÍ ÉÚ ÎÁÉÂÏÌÅÅ + ×ÁÖÎÙÈ ÉÚÍÅÎÅÎÉÊ Ñ×ÌÑÅÔÓÑ ÔÏ, ÞÔÏ ÄÉÒÅËÔÉ×Ù, ËÏÎÔÒÏÌÉÒÕÀÝÉÅ ÒÁÂÏÔÕ + ÍÏÄÕÌÑ, ÔÅÐÅÒØ ÒÁÓÐÏÌÁÇÁÀÔÓÑ × ÓÅËÃÉÉ <Proxy>, Á ÎÅ × + <Directory proxy:>, ËÁË ÜÔÏ ÂÙÌÏ ÒÁÎÅÅ.
    • + +
    • ïÂÒÁÂÏÔËÁ PATH_INFO (ÐÕÔÅ×ÏÊ ÉÎÆÏÒÍÁÃÉÉ, ÓÌÅÄÕÀÝÅÊ ÚÁ + ÉÍÅÎÅÍ ÚÁÐÒÁÛÉ×ÁÅÍÏÇÏ ÄÏËÕÍÅÎÔÁ) ÉÚÍÅÎÉÌÁÓØ ÄÌÑ ÎÅËÏÔÏÒÙÈ ÍÏÄÕÌÅÊ. + íÏÄÕÌÉ, ËÏÔÏÒÙÅ ÒÁÎØÛÅ ÂÙÌÉ ÎÁÐÉÓÁÎÙ ËÁË ÏÂÒÁÂÏÔÞÉËÉ (handler), Á + ÔÅÐÅÒØ ×ÙÐÏÌÎÑÀÔ ÒÏÌØ ÆÉÌØÔÒÏ×, ÍÏÇÕÔ ÂÏÌÅÅ ÎÅ ÐÒÉÎÉÍÁÔØ ÚÁÐÒÏÓÙ, + ÓÏÄÅÒÖÁÝÉÅ PATH_INFO. ôÁËÉÅ ÆÉÌØÔÒÙ, ËÁË INCLUDES ÒÅÁÌÉÚÏ×ÁÎÙ ÐÅÒ×ÙÍÉ × ÂÁÚÏ×ÏÍ + ÏÂÒÁÂÏÔÞÉËÅ, ÔÁËÉÍ ÏÂÒÁÚÏÍ ÏÎÉ ÎÅ ÍÏÇÕÔ ÐÒÉÎÉÍÁÔØ ÚÁÐÒÏÓÙ, ÓÏÄÅÒÖÁÝÉÅ + PATH_INFO. ÷Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÄÉÒÅËÔÉ×Õ AcceptPathInfo, ÞÔÏÂÙ ÚÁÓÔÁ×ÉÔØ ÂÁÚÏ×ÙÊ + ÏÂÒÁÂÏÔÞÉË ÐÒÉÎÉÍÁÔØ ÐÏÄÏÂÎÙÅ ÚÁÐÒÏÓÙ, É ÔÁËÉÍ ÏÂÒÁÚÏÍ ×ÏÓÓÔÁÎÏ×ÉÔØ + ×ÏÚÍÏÖÎÏÓÔØ ÉÓÐÏÌØÚÏ×ÁÎÉÑ PATH_INFO × ÄÏËÕÍÅÎÔÁÈ, ÉÓÐÏÌØÚÕÀÝÉÈ ×ËÌÀÞÅÎÉÑ + ÎÁ ÓÔÏÒÏÎÅ ÓÅÒ×ÅÒÁ (SSI).
    • + +
    • äÉÒÅËÔÉ×Á CacheNegotiatedDocs + ÔÅÐÅÒØ ÍÏÖÅÔ ÐÒÉÎÉÍÁÔØ ÁÒÇÕÍÅÎÔÙ on É + off. õÖÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ ÜËÚÅÍÐÌÑÒÙ ÄÉÒÅËÔÉ×Ù + CacheNegotiatedDocs ÄÏÌÖÎÙ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÎÁ + CacheNegotiatedDocs on.
    • + +
    • + äÉÒÅËÔÉ×Á ErrorDocument + ÂÏÌÅÅ ÎÅ ÉÓÐÏÌØÚÕÅÔ ÏÔËÒÙ×ÁÀÝÕÀ ËÁ×ÙÞËÕ × ÎÁÞÁÌÅ ÁÒÇÕÍÅÎÔÁ + ÄÌÑ ÏÂÏÚÎÁÞÅÎÉÑ ÔÏÇÏ, ÞÔÏ ÁÒÇÕÍÅÎÔ Ñ×ÌÑÅÔÓÑ ÔÅËÓÔÏ×ÙÍ ÓÏÏÂÝÅÎÉÅÍ. + ÷ÍÅÓÔÏ ÜÔÏÇÏ ×ÁÍ ÎÅÏÂÈÏÄÉÍÏ ÚÁËÌÀÞÁÔØ ×ÅÓØ ÔÅËÓÔ ÓÏÏÂÝÅÎÉÑ + × Ä×ÏÊÎÙÅ ËÁ×ÙÞËÉ. îÁÐÒÉÍÅÒ, ÓÕÝÅÓÔ×ÕÀÝÉÅ ÄÉÒÅËÔÉ×Ù + +

      + ErrorDocument 403 "îÅËÏÔÏÒÏÅ ÓÏÏÂÝÅÎÉÅ +

      + ÄÏÌÖÎÙ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÎÁ + +

      + ErrorDocument 403 "îÅËÏÔÏÒÏÅ ÓÏÏÂÝÅÎÉÅ" +

      + åÓÌÉ ×ÔÏÒÏÊ ÁÒÇÕÍÅÎÔ ÎÅ Ñ×ÌÑÅÔÓÑ ÐÒÁ×ÉÌØÎÏ ÏÆÏÒÍÌÅÎÎÙÍ + ÉÄÅÎÔÉÆÉËÁÔÏÒÏÍ ÒÅÓÕÒÓÁ (URL) ÉÌÉ ÐÕÔÅ×ÙÍ ÉÍÅÎÅÍ, ÔÏ ÏÎ + ÂÕÄÅÔ ÉÎÔÅÒÐÒÅÔÉÒÏ×ÁÔØÓÑ ËÁË ÔÅËÓÔÏ×ÏÅ ÓÏÏÂÝÅÎÉÅ. +
    • + +
    • äÉÒÅËÔÉ×Ù AccessConfig É + ResourceConfig ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. + éÍÅÀÝÉÅÓÑ ÉÈ ËÏÐÉÉ ÍÏÇÕÔ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÄÉÒÅËÔÉ×ÏÊ + Include, ËÏÔÏÒÁÑ ÉÍÅÅÔ + ÔÕ ÖÅ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ. åÓÌÉ ÐÒÅÖÄÅ ×Ù ÎÅ ×ËÌÀÞÁÌÉ ÉÈ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÅ + ÆÁÊÌÙ, ÔÅÍ ÓÁÍÙÍ ÉÓÐÏÌØÚÕÑ ÉÈ ÚÎÁÞÅÎÉÑ ÐÏ ÕÍÏÌÞÁÎÉÀ, ÔÏ ÓÅÊÞÁÓ, + ÄÌÑ ÄÏÓÔÉÖÅÎÉÑ ÔÏÇÏ ÖÅ ÒÅÚÕÌØÔÁÔÁ, ×ÁÍ ÎÁÄÏ + ÄÏÂÁ×ÉÔØ ÓÌÅÄÕÀÝÉÅ ÓÔÒÏËÉ × ÆÁÊÌ httpd.conf: Include conf/access.conf É Include + conf/srm.conf. äÌÑ ÔÏÇÏ ÞÔÏÂÙ ÂÙÔØ Õ×ÅÒÅÎÎÙÍ × ÔÏÍ, ÞÔÏ + Apache ÓÞÉÔÙ×ÁÅÔ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÅ ÆÁÊÌÙ ÉÍÅÎÎÏ × ÔÏÍ ÐÏÒÑÄËÅ, + ËÏÔÏÒÙÊ ÂÙÌ ÐÒÅÄÕÓÍÏÔÒÅÎ ÓÔÁÒÙÍÉ ÄÉÒÅËÔÉ×ÁÍÉ, ÎÁÄÏ ÐÏÍÅÓÔÉÔØ + ÄÉÒÅËÔÉ×Ù Include × ËÏÎÃÅ ÆÁÊÌÁ httpd.conf, ÐÒÉÞÅÍ + ÓÐÅÒ×Á ÔÕ, ÞÔÏ ×ËÌÀÞÁÅÔ srm.conf, Á ÚÁÔÅÍ ÔÕ, ÞÔÏ + ×ËÌÀÞÁÅÔ access.conf.
    • + +
    • äÉÒÅËÔÉ×Ù BindAddress É Port + ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. üË×É×ÁÌÅÎÔÎÁÑ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ ÐÒÅÄÏÓÔÁ×ÌÑÅÔÓÑ + ÂÏÌÅÅ ÇÉÂËÏÊ ÄÉÒÅËÔÉ×ÏÊ Listen. +
    • + +
    • ÷ Apache 1.3 ÄÉÒÅËÔÉ×Á Port + ÉÓÐÏÌØÚÏ×ÁÌÁÓØ, ËÒÏÍÅ ×ÓÅÇÏ ÐÒÏÞÅÇÏ, ÄÌÑ ÔÏÇÏ ÞÔÏÂÙ ÓÅÒ×ÅÒ + ÍÏÇ ÆÏÒÍÉÒÏ×ÁÔØ ÐÒÁ×ÉÌØÎÙÅ ÓÓÙÌËÉ ÎÁ ÓÁÍÏÇÏ ÓÅÂÑ. ÷ Apache 2.0 ÄÌÑ + ÔÅÈ ÖÅ ÃÅÌÅÊ ÓÌÕÖÉÔ ÎÏ×ÙÊ ÓÉÎÔÁËÓÉÓ ÄÉÒÅËÔÉ×Ù ServerName: ÏÎ ÂÙÌ ÉÚÍÅÎÅÎ ÔÁËÉÍ ÏÂÒÁÚÏÍ, ÞÔÏ ÔÅÐÅÒØ + ÉÍÑ ÈÏÓÔÁ É ÎÏÍÅÒ ÐÏÒÔÁ ÍÏÖÎÏ ÕËÁÚÙ×ÁÔØ × ÏÄÎÏÊ ÜÔÏÊ ÄÉÒÅËÔÉ×Å.
    • + +
    • äÉÒÅËÔÉ×Á ServerType ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ. + íÅÔÏÄ ÏÂÒÁÂÏÔËÉ ÚÁÐÒÏÓÏ× ÔÅÐÅÒØ ÏÐÒÅÄÅÌÑÅÔÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ + ×ÙÂÏÒÁ íð-ÍÏÄÕÌÑ. ÷ ÎÁÓÔÏÑÝÅÅ ×ÒÅÍÑ ÎÅÔ ÔÁËÏÇÏ íð-ÍÏÄÕÌÑ, + ËÏÔÏÒÙÊ ÍÏÇ ÂÙ ÚÁÐÕÓËÁÔØÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ ÄÅÍÏÎÁ inetd.
    • + +
    • íÏÄÕÌÉ mod_log_agent É mod_log_referer, ËÏÔÏÒÙÅ ÐÒÅÄÏÓÔÁ×ÌÑÌÉ + ÔÁËÉÅ ÄÉÒÅËÔÉ×Ù, ËÁË AgentLog, RefererLog + É RefererIgnore, ÂÙÌÉ ÕÂÒÁÎÙ. ÷ÅÄÅÎÉÅ ÖÕÒÎÁÌÁ ÁÇÅÎÔÏ× + ÐÏÌØÚÏ×ÁÔÅÌÅÊ (agent logs) É ÏÔÐÒÁ×ÉÔÅÌÅÊ (referer logs) ÐÏ-ÐÒÅÖÎÅÍÕ + ×ÏÚÍÏÖÎÏ ÐÏÓÒÅÄÓÔ×ÏÍ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ÄÉÒÅËÔÉ×Ù CustomLog ÍÏÄÕÌÑ mod_log_config.
    • + +
    • äÉÒÅËÔÉ×Ù AddModule É + ClearModuleList ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. ïÎÉ ÉÓÐÏÌØÚÏ×ÁÌÉÓØ + ÄÌÑ ÏÂÅÓÐÅÞÅÎÉÑ ÐÒÁ×ÉÌØÎÏÇÏ ÐÏÒÑÄËÁ ÚÁÇÒÕÚËÉ ÍÏÄÕÌÅÊ. îÏ×ÙÊ API ÄÌÑ + Apache 2.0 ÐÏÚ×ÏÌÑÅÔ ÍÏÄÕÌÑÍ ÓÁÍÉÍ ÕËÁÚÙ×ÁÔØ ÐÏÒÑÄÏË ÉÈ ÚÁÇÒÕÚËÉ, ÞÔÏ + ÄÅÌÁÅÔ ÜÔÉ ÄÉÒÅËÔÉ×Ù ÎÅÎÕÖÎÙÍÉ.
    • + +
    • äÉÒÅËÔÉ×Á FancyIndexing ÂÙÌÁ ÕÂÒÁÎÁ. åÅ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ + ÔÅÐÅÒØ ÏÂÅÓÐÅÞÉ×ÁÅÔÓÑ ÏÐÃÉÅÊ FancyIndexing × ÄÉÒÅËÔÉ×Å IndexOptions
    • +
    +
    top
    +
    +

    äÒÕÇÉÅ ÉÚÍÅÎÅÎÉÑ

    + + +
      +
    • ïÐÃÉÑ ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ httpd -S, + ÐÏÚ×ÏÌÑ×ÛÁÑ ÒÁÓÐÅÞÁÔÙ×ÁÔØ ËÏÎÆÉÇÕÒÁÃÉÀ ×ÉÒÔÕÁÌØÎÙÈ ÈÏÓÔÏ×, ÔÅÐÅÒØ ÚÁÍÅÎÅÎÁ + ÏÐÃÉÅÊ -t -D DUMP_VHOSTS.
    • + +
    • íÏÄÕÌØ mod_auth_digest, ËÏÔÏÒÙÊ ÉÍÅÌ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÓÔÁÔÕÓ × + Apache 1.3, ÔÅÐÅÒØ Ñ×ÌÑÅÔÓÑ ÓÔÁÎÄÁÒÔÎÙÍ ÍÏÄÕÌÅÍ.
    • + +
    • íÏÄÕÌØ mod_mmap_static, ËÏÔÏÒÙÊ ÉÍÅÌ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÓÔÁÔÕÓ × + Apache 1.3, ÚÁÍÅÎÅÎ ÍÏÄÕÌÅÍ mod_file_cache.
    • + +
    • ïÒÇÁÎÉÚÁÃÉÑ ÄÉÓÔÒÉÂÕÔÉ×Á ÐÏÌÎÏÓÔØÀ ÉÚÍÅÎÅÎÁ É ÔÅÐÅÒØ + ÂÏÌÅÅ ÎÅ ÓÏÄÅÒÖÉÔ ÎÅÚÁ×ÉÓÉÍÏÇÏ ËÁÔÁÌÏÇÁ src. ÷ÍÅÓÔÏ ÜÔÏÇÏ + ÉÓÈÏÄÎÙÅ ËÏÄÙ ÌÏÇÉÞÅÓËÉ ÏÒÇÁÎÉÚÏ×ÁÎÙ × ÏÓÎÏ×ÎÏÍ ËÁÔÁÌÏÇÅ ÄÉÓÔÒÉÂÕÔÉ×Á, Á + ÕÓÔÁÎÏ×ËÁ ÓËÏÍÐÉÌÉÒÏ×ÁÎÎÏÇÏ ÓÅÒ×ÅÒÁ ÐÒÏÉÚ×ÏÄÉÔÓÑ × ÏÔÄÅÌØÎÙÊ ËÁÔÁÌÏÇ.
    • +
    +
    top
    +
    +

    íÏÄÕÌÉ ÔÒÅÔØÉÈ ÆÉÒÍ

    + + +

    úÎÁÞÉÔÅÌØÎÙÅ ÉÚÍÅÎÅÎÉÑ ÂÙÌÉ ×ÎÅÓÅÎÙ × API ÄÌÑ Apache 2.0. + óÕÝÅÓÔ×ÕÀÝÉÅ ÍÏÄÕÌÉ, ÎÁÐÉÓÁÎÎÙÅ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ Apache 1.3 API, + ÎÅ ÂÕÄÕÔ ÒÁÂÏÔÁÔØ ÐÏÄ Apache 2.0, ÅÓÌÉ ÎÅ ×ÎÅÓÔÉ + × ÎÉÈ ÎÅÏÂÈÏÄÉÍÙÅ ÉÚÍÅÎÅÎÉÑ. âÏÌÅÅ ÐÏÄÒÏÂÎÁÑ ÉÎÆÏÒÍÁÃÉÑ ÐÏ ÜÔÏÍÕ ÐÏ×ÏÄÕ + ÄÏÓÔÕÐÎÁ × ÄÏËÕÍÅÎÔÁÃÉÉ ÄÌÑ ÒÁÚÒÁÂÏÔÞÉËÏ×.

    +
    +
    +

    Available Languages:  de  | + en  | + fr  | + ja  | + ko  | + pt-br  | + ru 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/upgrading.xml b/trunk/docs/manual/upgrading.xml new file mode 100644 index 0000000000..2079367930 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml @@ -0,0 +1,93 @@ + + + + + + + + + +Upgrading to 2.1 from 2.0 + + +

    In order to assist folks upgrading, we maintain a document + describing information critical to existing Apache users. These + are intended to be brief notes, and you should be able to find + more information in either the New Features document, or in + the src/CHANGES file.

    + +

    This document describes only the changes from 2.0 to 2.2. If you + are upgrading from version 1.3, you should also consult the 1.3 to 2.0 + upgrading document.

    + +
    +Overview of new features in + Apache 2.2 + +
    + Compile-Time Configuration Changes + +
    + +
    + Run-Time Configuration Changes + +
      +
    • The config file httpd.conf distributed with the + Apache HTTP Server has been greatly simplified by removing all + but the most essential configuration settings. A set of example + configuration settings for more advanced features is present in + the conf/extra/ directory of the installed + server.
    • + +
    • The apachectl option + startssl is no longer available. To enable ssl + support, you should edit httpd.conf to include the + relevant mod_ssl directives and then use + apachectl start to start the server. An example + configuration to activate mod_ssl has been included + in conf/extra/httpd-ssl.conf.
    • + +
    • The default setting of UseCanonicalName is now + Off. If you did not have this directive in your + config file, you can add UseCanonicalName On to + retain the old behavior.
    • + +
    • The module mod_userdir will no longer act + on requests unless a UserDir directive specifying a + directory name is present in the config file. To restore the + old default behavior, place the directive UserDir + public_html in your config file.
    • + +
    +
    + +
    + Misc Changes + +
    + +
    + Third Party Modules + +
    +
    diff --git a/trunk/docs/manual/upgrading.xml.de b/trunk/docs/manual/upgrading.xml.de new file mode 100644 index 0000000000..09d061a698 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.de @@ -0,0 +1,95 @@ + + + + + + + + + +Upgrade von 2.0 auf 2.1 + + +

    Dieses Dokument dient der Unterstützung beim Upgrade. Es + enthält die entscheidenden Informationen für bisherige + Apache-Nutzer. Diese sind als kurze Anmerkungen + gedacht. Weitere Informationen finden Sie entweder unter + Neue Funktionen oder in + den src/CHANGES-Dateien.

    + +

    Dieses Dokument beschreibt lediglich die Änderungen von Version + 2.2 gegenüber Version 2.0. Wenn Sie ein Upgrade von Version 1.3 + durchführen, sollten Sie auch Upgrade von 1.3 + auf 2.0 zu Rate ziehen.

    +
    +Übersicht der neuen Funktionen + in Apache 2.0 + +
    + Änderungen der Konfiguration bei der Kompilierung + +
    + +
    + Änderungen der Laufzeit-Konfiguration + +
      +
    • Die mit dem Apache HTTP Server ausgelieferte Konfigurationsdatei + httpd.conf wurde stark vereinfacht, indem alle außer + den unbedingt notwendigen Konfigurationseinstellungen entfernt wurden. + Im conf/extra/-Verzeichnis Ihrer Installation finden Sie + eine Reihe von Konfigurationsbeispielen für erweiterte Funktionen. +
    • + +
    • Die apachectl-Option startssl gibt es + nicht mehr. Um SSL-Unterstützung zu aktivieren müssen Sie die + httpd.conf editieren und die entsprechenden + mod_ssl-Anweisungen einfügen und + anschließend den Server mit apachectl start starten. + Eine Beispielkonfiguration zum Aktivieren von mod_ssl + ist in conf/extra/httpd-ssl.conf enthalten. +
    • + +
    • Die Voreinstellung von UseCanonicalName ist jetzt Off. + Wenn diese Anweisung nicht in Ihrer Konfigurationsdatei enthalten ist, + können Sie UseCanonicalName On einfügen, um das + bisherige Verhalten beizubehalten. +
    • + +
    • Das Modul mod_userdir reagiert nicht länger auf + Anfragen, solange nicht in der Konfigurationsdatei eine UserDir-Anweisung enthalten ist, die + einen Verzeichnisnamen angibt. Fügen Sie Ihrer Konfigurationsdatei + die Anweisung UserDir public_html hinzu, um das + bisherige Verhalten wiederherzustellen. +
    • +
    +
    + +
    + Sonstige Änderungen + +
    + +
    + Module von Drittanbietern + +
    +
    diff --git a/trunk/docs/manual/upgrading.xml.ja b/trunk/docs/manual/upgrading.xml.ja new file mode 100644 index 0000000000..211d9f819a --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.ja @@ -0,0 +1,208 @@ + + + + + + + + + +1.3 $B$+$i(B 2.0 $B$X$N%"%C%W%0%l!<%I(B + + +

    $B%"%C%W%0%l!<%I$r4JC1$K$9$k$?$a$K!"4{B8$N(B Apache $B%f!<%6$K(B + $BHs>o$K=EMW$J>pJs$r$3$NJ8=q$K$^$H$a$F$$$^$9!#$3$l$OC;$$(B + $BCm0U=q$-$H$7$F=q$+$l$F$$$^$9!#$h$j>\$7$$>pJs$O(B + $B?75!G=(B$B$NJ8=q$d(B + src/CHANGES $B%U%!%$%k$G8+$D$1$i$l$k$H;W$$$^$9!#(B

    +
    +Apache 2.0 $B?75!G=$N35MW(B + +
    + $B%3%s%Q%$%k;~$N@_Dj$NJQ99(B + +
      +
    • Apache $B$O(B $B%S%k%I=hM}$N@_Dj(B + $B$K(B autoconf $B$H(B libtool $B$r;H$&$h$&$K$J$j$^$7$?!#(B + $B$3$N%7%9%F%`$O(B Apache 1.3 $B$N(B APACI $B%7%9%F%`$H;w$F$$$^$9$,!"(B + $B$^$C$?$/F1$8$H$$$&$o$1$G$O$"$j$^$;$s!#(B
    • + +
    • $BDL>o$N%3%s%Q%$%k$9$k$+$I$&$+$rA*Br$G$-$k%b%8%e!<%k72$K2C$($F!"(B + Apache 2.0 $B$O(B + $B%j%/%(%9%H=hM}$N$B%^%k%A%W%m%;%C%7%s%0(B + $B%b%8%e!<%k(B (MPM) $B$K0\F0$7$^$7$?!#(B
    • +
    +
    + +
    + $B<B9T;~$N@_Dj$NJQ99(B + +
      +
    • Apache 1.3 $B$N;~$K%3%"%5!<%P$K$"$C$?B?$/$N%G%#%l%/%F%#%V$O(B + MPM $B$K0\F0$7$^$7$?!#%5!<%P$K(B Apache 1.3 $B$H$G$-$k$@$1F1$8?6$kIq$$$r(B + $B$5$;$?$$>l9g$O!"(Bprefork MPM $B$r(B + $BA*$s$G$/$@$5$$!#B>$N(B MPM $B$O%W%m%;%9$N:n@.$d%j%/%(%9%H$N=hM}$N(B + $B@)8f$K0[$J$C$?%G%#%l%/%F%#%V$r;H$$$^$9!#(B
    • + +
    • Proxy $B%b%8%e!<%k(B $B$O(B + HTTP/1.1 $B$KBP1~$9$k$?$a$K:F9=@.$5$l$^$7$?!#=EMW$JJQ99E@$H$7$F$O!"(B + $B%W%m%-%7$N%"%/%;%9@)8f$,(B <Directory proxy:> $B%V%m%C%/$N(B + $BBe$o$j$K(B Proxy + $B%V%m%C%/$KCV$+$l$k$h$&$K$J$C$?!"$H$$$&$b$N$,$"$j$^$9!#(B
    • + +
    • $B%b%8%e!<%k$NCf$K$O!"(BPATH_INFO ($BK\Ev$N%U%!%$%kL>$N8e$KB3$/(B + $B%Q%9>pJs(B) $B$N07$$$,JQ$o$C$?$b$N$,$"$j$^$9!#0JA0$O%O%s%I%i$H$7$F(B + $BPATH_INFO $B$N$"$k%j%/%(%9%H$rINCLUDES $B$d(B + PHP $B$J$I$N%U%#%k%?$O(B + $B%3%"%O%s%I%i$N>e$KPATH_INFO + $BIU$-$N%j%/%(%9%H$r5qH]$7$^$9!#(B + AcceptPathInfo + $B%G%#%l%/%F%#%V$r;H$C$F%3%"%O%s%I%i$,(B PATH_INFO + $BIU$-$N%j%/%(%9%H$rPATH_INFO $B$r;H$&5!G=$rI|3h$5$;$k$3$H$,$G$-$^$9!#(B
    • + +
    • CacheNegotiatedDocs + $B%G%#%l%/%F%#%V$O(B on $B$b$7$/$O(B off $B$H$$$&0z?t$r(B + $BCacheNegotiatedDocs $B$O(B + CacheNegotiatedDocs on + $B$KCV$-49$($F$/$@$5$$!#(B
    • + +
    • + ErrorDocument + $B%G%#%l%/%F%#%V$O%F%-%9%H%a%C%;!<%8$r(B + $B<($9$?$a$K0z?t$N:G=i$K;H$o$l$F$$$?0zMQId$r;H$o$J$$$h$&$K$J$j$^$7$?!#(B + $BBe$o$j$K!"%a%C%;!<%8$rFs=E0zMQId$G0O$`$h$&$K$J$C$F$$$^$9!#(B + $BNc$($P!"4{B8$N(B + + + ErrorDocument 403 "Some Message + + $B$O(B + + + ErrorDocument 403 "Some Message" + + + $B$KCV$-49$($kI,MW$,$"$j$^$9!#(B + $BFsHVL\$N0z?t$O!"M-8z$J(B URL $B$d%Q%9L>$G$J$$8B$j(B + $B%F%-%9%H%a%C%;!<%8$H$7$F07$o$l$^$9!#(B +
    • + +
    • AccessConfig $B%G%#%l%/%F%#%V$H(B + ResourceConfig $B%G%#%l%/%F%#%V$O:o=|$5$l$^$7$?!#(B + $B$3$l$i$N%G%#%l%/%F%#%V$OF1Ey$N5!G=$r;}$D(B + Include $B$G(B + $BCV$-49$($k$3$H$,$G$-$^$9!#@_Dj%U%!%$%k$Ke$N%G%#%l%/%F%#%V$N%G%U%)%k%HCM$r;H$C$F$$$?>l9g$O!"(B + httpd.conf $B$K(B Include conf/access.conf $B$H(B + Include conf/srm.conf $B$rDI2C$9$kI,MW$,$"$k$G$7$g$&!#(B + $B0JA0$N%G%#%l%/%F%#%V$K$h$k=gHV$N$h$&$K(B Apache $B$,@_Dj%U%!%$%k$r(B + $BFI$_9~$`$h$&$K$9$k$?$a$K$O!"(Bhttpd.conf $B$N:G8e$K(B + srm.conf$B!"(Baccess.conf $B$N=g$K$=$l$>$l(B + Include + $B%G%#%l%/%F%#%V$r=q$$$F$/$@$5$$!#(B
    • + +
    • BindAddress $B%G%#%l%/%F%#%V$H(B Port + $B%G%#%l%/%F%#%V$O:o=|$5$l$^$7$?!#F1Ey$N5!G=$O$h$j=@Fp$J(B + Listen + $B%G%#%l%/%F%#%V$K$h$jDs6!$5$l$F$$$^$9!#(B
    • + +
    • Port $B%G%#%l%/%F%#%V$O(B Apache-1.3 $B$K$O<+8J;2>H(B URL $B$G(B + $B;H$o$l$k%]!<%HHV9f$r@_Dj$9$k!"$H$$$&;HMQK!$b$"$j$^$7$?!#(B + $B$3$l$O(B Apache-2.0 $B$G$O?7$7$$(B + ServerName + $B9=J8$K$h$C$F9T$J$$$^$9!#0l$D$N%G%#%l%/%F%#%V$G%[%9%HL>(B$B$H(B + $B<+8J;2>H(B URL $B$NN>J}$r@_Dj$G$-$k$h$&$K9=J8$,JQ99$5$l$^$7$?!#(B
    • + +
    • ServerName $B%G%#%l%/%F%#%V$O:o=|$5$l$^$7$?!#(B + $B%j%/%(%9%H$r07$&J}K!$O(B MPM $B$NA*Br$K$h$j7hDj$5$l$k$h$&$K$J$j$^$7$?!#(B + $B8=;~E@$G$O(B inetd $B$+$i5/F0$5$l$k$h$&$K@_7W$5$l$?(B MPM $B$O$"$j$^$;$s!#(B
    • + +
    • AgentLog $B%G%#%l%/%F%#%V!"(B + RefererLog $B%G%#%l%/%F%#%V!"(B + RefererIgnore $B%G%#%l%/%F%#%V$rDs6!$7$F$$$?(B + mod_log_agent $B$H(B mod_log_referer + $B%b%8%e!<%k$O:o=|$5$l$^$7$?!#(B + Agent $B%m%0$H(B refere $B%m%0$O(B mod_log_config $B$N(B + CustomLog + $B%G%#%l%/%F%#%V$K$h$j + +
    • AddModule $B%G%#%l%/%F%#%V$H(B ClearModuleList + $B%G%#%l%/%F%#%V$O:o=|$5$l$^$7$?!#$3$l$i$N%G%#%l%/%F%#%V$O!"(B + $B%b%8%e!<%k$,@5$7$$=gHV$G8F$P$l$k$h$&$K$9$k$?$a$K;H$o$l$F$$$^$7$?!#(B + Apache 2.0 $B$N?7(B API $B$O%b%8%e!<%k$,L@<(E*$K=gHV$r;XDj$G$-$k$h$&$K(B + $B$J$C$F$*$j!"$3$l$i$N%G%#%l%/%F%#%V$OI,MW$J$/$J$j$^$7$?!#(B
    • + +
    • FancyIndexing $B%G%#%l%/%F%#%V$O:o=|$5$l$^$7$?!#(B + $BF1$85!G=$O(B IndexOptions + $B%G%#%l%/%F%#%V$N(B FancyIndexing $B%*%W%7%g%s$G(B + $B + +
    • mod_negotiation $B$K$h$k(B MultiViews + $B%3%s%F%s%H%M%4%7%(!<%7%g%s5;=Q$O!"(B + $B%G%U%)%k%H$N%U%!%$%k%^%C%A%s%0$,$h$j87L)$J$b$N$KJQ99$5$l$^$7$?!#(B + $B%M%4%7%(!<%H2DG=$J(B$B%U%!%$%k$N>l9g$K$N$_A*Br$5$l$^$9!#(B + $B0JA0$N5sF0$O!"(BMultiviewsMatch + $B%G%#%l%/%F%#%V$r;HMQ$9$k$3$H$GI|3h$G$-$^$9!#(B
    • + +
    • ($B%P!<%8%g%s(B 2.0.51 $B$+$i(B) +

      ErrorHeader $B%G%#%l%/%F%#%V$OITE,@Z$JL>A0(B + $B$@$C$?$?$a$KGQ;_$5$l!"$=$N5!G=$O(B Header $B%G%#%l%/%F%#%V$KE}9g$5$l$^$7$?!#(B + $BK>$_$NF0:n$rF@$k$?$a$K$O(B ErrorHeader $B$NBe$o$j$K(B

      + + + Header always set foo bar + + +

      $B$r;H$C$F$/$@$5$$!#(B

    • +
    +
    + +
    + $B$=$NB>$NJQ99(B + +
      +
    • Apache 1.3 $B$Gmod_auth_digest $B$O(B + $BI8=`%b%8%e!<%k$K$J$j$^$7$?!#(B
    • + +
    • Apache 1.3 $B$Gmod_mmap_static $B$O(B + mod_file_cache $B$GCV$-49$($i$l$^$7$?!#(B
    • + +
    • Apache $B$NG[I[$OFHN)$7$?(B src $B%G%#%l%/%H%j$,(B + $B$J$/$J$k$h$&$K!"40A4$K:F9=@.$5$l$^$7$?!#$=$NBe$o$j$K!"(B + $B%=!<%9$O +
    +
    + +
    + $B%5!<%I%Q!<%F%#%b%8%e!<%k(B + +

    Apache 2.0 $B$N%5!<%P(B API $B$K$OB?$/$NJQ99$,2C$($i$l$^$7$?!#(B + Apache 1.3 $BMQ$N4{B8$N%b%8%e!<%k$O(B Apache 2.0 $B$G$O=$@5$J$7$G$O(B + $BF0$-(B$B$^$;$s(B$B!#>\:Y$O(B $B3+H/ $B$K$"$j$^$9!#(B

    +
    + +
    diff --git a/trunk/docs/manual/upgrading.xml.ko b/trunk/docs/manual/upgrading.xml.ko new file mode 100644 index 0000000000..accf549363 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.ko @@ -0,0 +1,192 @@ + + + + + + + + + +1.3¿¡¼­ 2.0À¸·Î ¾÷±×·¹À̵å + + +

    ¿ì¸®´Â ±âÁ¸ ¾ÆÆÄÄ¡ »ç¿ëÀÚ°¡ ¾÷±×·¹À̵åÇÏ´Â °ÍÀ» µ½±âÀ§ÇØ + Áß¿äÇÑ Á¤º¸¸¦ ¾Ë·ÁÁÖ´Â ¹®¼­¸¦ Á¦°øÇÑ´Ù. ÀÌ ¹®¼­´Â °£´ÜÇÑ + ¿ä¾àÀ̹ǷÎ, »õ·Î¿î ±â´É + ¹®¼­³ª src/CHANGES ÆÄÀÏ¿¡¼­ Á¤º¸¸¦ ã¾ÆºÁ¾ß + ÇÑ´Ù.

    +
    +¾ÆÆÄÄ¡ 2.0ÀÇ »õ·Î¿î +±â´É ¿ä¾à + +
    + ÄÄÆÄÀϽà ±¸¼º º¯È­ + +
      +
    • ¾ÆÆÄÄ¡´Â ÀÌÁ¦ ¾ÆÆÄÄ¡ ÄÄÆÄÀÏ°ú ¼³Ä¡¸¦ À§ÇØ + autoconf¿Í libtool ½Ã½ºÅÛÀ» + »ç¿ëÇÑ´Ù. ÀÌ ½Ã½ºÅÛÀÇ »ç¿ë¹ýÀº Apache 1.3ÀÇ APACI ½Ã½ºÅÛ°ú + °°Áö´Â ¾ÊÁö¸¸ ºñ½ÁÇÏ´Ù.
    • + +
    • ÄÄÆÄÀÏ ¿©ºÎ¸¦ ¼±ÅÃÇÒ ¸ðµâ¿Ü¿¡ Apache 2.0Àº ¿äûÀ» + ó¸®ÇÏ´Â ÁÖ¿ä ºÎºÐÀ» ´ÙÁßó¸® ¸ðµâ + (Multi-Processing Modules) (MPM)·Î ¿Å°å´Ù.
    • +
    +
    + +
    + ½ÇÇà½Ã ¼³Á¤ º¯È­ + +
      +
    • Apache 1.3¿¡¼­ ¼­¹ö Çٽɿ¡ ÀÖ¾ú´ø ¸¹Àº Áö½Ã¾îµéÀÌ + ÀÌÁ¦´Â MPM¿¡ ÀÖ´Ù. ¼­¹ö°¡ Apache 1.3°ú ÃÖ´ëÇÑ ºñ½ÁÇÏ°Ô + µ¿ÀÛÇÏ±æ ¹Ù¶õ´Ù¸é prefork MPMÀ» ¼±ÅÃÇØ¾ß + ÇÑ´Ù. ´Ù¸¥ MPMÀº ´Ù¸¥ Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ÇÁ·Î¼¼½º »ý¼º°ú + ¿äûÀÇ Ã³¸®¸¦ Á¶ÀýÇÑ´Ù.
    • + +
    • proxy ¸ðµâÀº HTTP/1.1¿¡ + ¸ÂÃß¾î ¼öÁ¤µÇ¾ú´Ù. Áß¿äÇÑ º¯È­Áß Çϳª´Â ÀÌÁ¦ ÇÁ·Ï½Ã Á¢±ÙÁ¦¾î°¡ + <Directory proxy:> ºí·ÏÀÌ ¾Æ´Ï¶ó + Proxy + ºí·Ï¿¡ À§Ä¡ÇÏ´Â Á¡ÀÌ´Ù.
    • + +
    • ¸î¸î ¸ðµâ¿¡¼­ PATH_INFO (ÁøÂ¥ °æ·Î¸í + µÚ¿¡ ³ª¿À´Â °æ·Î Á¤º¸) ó¸® ¹æ½ÄÀÌ º¯°æµÇ¾ú´Ù. Àü¿¡ + Çڵ鷯¿´Áö¸¸ ÀÌÁ¦ ÇÊÅÍ·Î ±¸ÇöµÇ´Â ¸ðµâÀº ´õ ÀÌ»ó + PATH_INFO°¡ ÀÖ´Â ¿äûÀ» ¹Þ¾ÆµéÀÌÁö ¸øÇÑ´Ù. + INCLUDES³ª PHP¿Í °°Àº ÇÊÅÍ´Â + core Çڵ鷯 À§¿¡ ±¸ÇöµÇ±â¶§¹®¿¡ PATH_INFO°¡ + ÀÖ´Â ¿äûÀ» °ÅºÎÇÑ´Ù. core Çڵ鷯°¡ PATH_INFO°¡ + ÀÖ´Â ¿äûÀ» ¹Þ¾ÆµéÀÌ°í server-side include¿¡¼­ + PATH_INFO¸¦ »ç¿ëÇÏ°Ô ÇÏ·Á¸é, AcceptPathInfo Áö½Ã¾î¸¦ »ç¿ëÇØ¾ß + ÇÑ´Ù.
    • + +
    • CacheNegotiatedDocs + Áö½Ã¾î´Â ÀÌÁ¦ ¾Æ±Ô¸ÕÆ®·Î on°ú off¸¦ + ¹Þ´Â´Ù. ±âÁ¸ÀÇ CacheNegotiatedDocs´Â + CacheNegotiatedDocs onÀ¸·Î ¼öÁ¤ÇØ¾ß ÇÑ´Ù.
    • + +
    • + ErrorDocument Áö½Ã¾î´Â + ´õÀÌ»ó ¸Þ¼¼Áö¸¦ ³ªÅ¸³»´Â ¾Æ±Ô¸ÕÆ® ¾Õ¿¡ µû¿ÈÇ¥¸¦ »ç¿ëÇÏÁö + ¾Ê´Â´Ù. ´ë½Å ½Öµû¿ÈÇ¥·Î ¸Þ¼¼Áö¸¦ ¹­¾î¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î °ú°Å + + + ErrorDocument 403 "Some Message + + ´Â ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇØ¾ß ÇÑ´Ù. + + + ErrorDocument 403 "Some Message" + + µÎ¹ø° ¾Æ±Ô¸ÕÆ®°¡ À¯È¿ÇÑ URLÀ̳ª °æ·Î¸íÀÌ ¾Æ´Ï¶ó¸é ¸Þ¼¼Áö·Î + °£ÁÖÇÑ´Ù. +
    • + +
    • AccessConfig¿Í ResourceConfig + Áö½Ã¾î´Â »ç¶óÁ³´Ù. ±âÁ¸¿¡ »ç¿ëÇÏ´ø Áö½Ã¾î´Â °°Àº ±â´ÉÀ» + ÇÏ´Â Include Áö½Ã¾î·Î + ´ëüÇÒ ¼ö ÀÖ´Ù. °ú°Å¿¡ ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ Áö½Ã¾îµéÀ» »ç¿ëÇÏÁö¾Ê°í + ÀÌ Áö½Ã¾îµéÀÇ ±âº»°ªÀ» »ç¿ëÇß´Ù¸é, http.conf¿¡ + Include conf/access.conf¿Í Include + conf/srm.conf¸¦ Ãß°¡ÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ ÀÌÀü + Áö½Ã¾î¿Í °°Àº ¼ø¼­·Î ¼³Á¤ÆÄÀÏÀ» ÀаÔÇÏ·Á¸é + Include Áö½Ã¾î¸¦ + httpd.conf ³¡¿¡ µÎ°í, srm.confÀÌ + access.conf ¾Õ¿¡ ³ª¿Í¾ß ÇÑ´Ù.
    • + +
    • BindAddress¿Í Port Áö½Ã¾î´Â + »ç¶óÁ³´Ù. ´õ À¯¿¬ÇÑ Listen + Áö½Ã¾î°¡ °°Àº ±â´ÉÀ» ÇÑ´Ù.
    • + +
    • Apache-1.3¿¡¼­ Port´Â ÀÚ±âÂüÁ¶ + URLÀÇ Æ÷Æ® ¹øÈ£¸¦ ¼³Á¤ÇÏ´Â Àϵµ Çß´Ù. Apache-2.0¿¡¼­ ÀÌ + ±â´ÉÀº »õ·Î¿î ServerNameÀ¸·Î + ÇÑ´Ù. ÇÑ Áö½Ã¾î¿¡ È£½ºÆ®¸í°ú ÀÚ±âÂüÁ¶ URLÀ» À§ÇÑ + Æ÷Æ® ¹øÈ£¸¦ °°ÀÌ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
    • + +
    • ServerType Áö½Ã¾î´Â »ç¶óÁ³´Ù. ¿äûÀ» + ¼­ºñ½ºÇÏ´Â ¹æ¹ýÀº ÀÌÁ¦ MPM ¼±Åÿ¡ ´Þ·È´Ù. ÇöÀç inetd¿¡¼­ + ½ÃÀÛÇϵµ·Ï ¼³°èµÈ MPMÀº ¾ø´Ù.
    • + +
    • AgentLog, RefererLog, + RefererIgnore Áö½Ã¾î¸¦ Á¦°øÇÑ + mod_log_agent¿Í mod_log_referer + ¸ðµâÀÌ ¾ø¾îÁ³´Ù. agent ·Î±×¿Í referer ·Î±×´Â + mod_log_configÀÇ CustomLog Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© °è¼Ó Á¦°øµÈ´Ù.
    • + +
    • AddModule°ú ClearModuleList + Áö½Ã¾î´Â »ç¶óÁ³´Ù. ÀÌ Áö½Ã¾îµéÀº ¸ðµâÀ» ¿Ã¹Ù¸¥ ¼ø¼­·Î + È°¼ºÈ­ÇÏ·Á°í »ç¿ëÇß´Ù. »õ·Î¿î Apache 2.0 API´Â ¸ðµâÀÌ + È°¼ºÈ­µÇ´Â ¼ø¼­¸¦ ¸í½ÃÀûÀ¸·Î ÁöÁ¤ÇÒ ¼ö À־, ÀÌ Áö½Ã¾îµéÀÌ + ÇÊ¿ä¾ø°Ô µÇ¾ú´Ù.
    • + +
    • FancyIndexing Áö½Ã¾î°¡ ¾ø¾îÁ³´Ù. + IndexOptions + Áö½Ã¾îÀÇ FancyIndexing ¿É¼ÇÀÌ °°Àº ±â´ÉÀ» ÇÑ´Ù.
    • + +
    • mod_negotiationÀÇ MultiViews ³»¿ëÇù»óÀÌ + ´õ ¾ö°ÝÇÏ°Ô ±âº»ÆÄÀÏÀ» ã´Â´Ù. ³»¿ëÇù»óÀº Çù»ó°¡´ÉÇÑ + ÆÄÀÏ Áß¿¡¼­¸¸ ¼±ÅÃÇÑ´Ù. MultiviewsMatch Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© ÀÌÀü°ú °°ÀÌ µ¿ÀÛÇÏ°Ô ÇÒ ¼ö ÀÖ´Ù.
    • + +
    • (2.0.51 ¹öÀü ÀÌÈÄ) +

      ErrorHeader Áö½Ã¾î´Â À߸øµÈ ¸íĪÀ¸·Î, + ÀÌ Áö½Ã¾î°¡ ´ã´çÇÑ ±â´ÉÀº Header Áö½Ã¾î·Îµµ °¡´ÉÇÏ´Ù. + ¿øÇÏ´Â ±â´ÉÀ» À§ÇØ,

      + + + Header always set ¾î¼°í Àú¼°í + + +

      ¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù.

    • +
    +
    + +
    + ±âŸ º¯È­ + +
      +
    • Apache 1.3¿¡¼­ ½ÇÇèÀûÀÌ¿´´ø mod_auth_digest + ¸ðµâÀÌ ÀÌÁ¦ Ç¥ÁØ ¸ðµâÀÌ µÇ¾ú´Ù.
    • + +
    • Apache 1.3¿¡¼­ ½ÇÇèÀûÀÌ¿´´ø mod_mmap_static + ¸ðµâÀÌ mod_file_cache·Î ´ëüµÇ¾ú´Ù.
    • + +
    • ¹èÆ÷º»ÀÌ ¿ÏÀüÈ÷ »õ·Î ±¸¼ºµÇ¾î ´õÀÌ»ó µ¶¸³µÈ src + µð·ºÅ丮°¡ ¾ø´Ù. ´ë½Å ¼Ò½º´Â ÁÖ ¹èÆ÷º» µð·ºÅ丮 ¾Æ·¡ ³í¸®ÀûÀ¸·Î + ±¸¼ºµÇÀÖ°í, ÄÄÆÄÀÏÇÑ ¼­¹ö´Â ´Ù¸¥ µð·ºÅ丮·Î ¼³Ä¡µÈ´Ù.
    • +
    +
    + +
    + Á¦»ïÀÚ°¡ ¸¸µç ¸ðµâ + +

    Apache 2.0¿¡¼­ ¼­¹ö API°¡ ¸¹ÀÌ º¯°æµÇ¾ú´Ù. Apache 1.3 API¿¡ + ¸ÂÃçÁø ±âÁ¸ ¸ðµâÀ» ¼öÁ¤¾øÀÌ Apache 2.0¿¡¼­ »ç¿ëÇÒ ¼ö + ¾ø´Ù. ÀÚ¼¼ÇÑ Á¤º¸´Â °³¹ßÀÚ + ¹®¼­¸¦ Âü°íÇ϶ó.

    +
    + diff --git a/trunk/docs/manual/upgrading.xml.meta b/trunk/docs/manual/upgrading.xml.meta new file mode 100644 index 0000000000..f738d57345 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.meta @@ -0,0 +1,17 @@ + + + + upgrading + / + . + + + de + en + fr + ja + ko + pt-br + ru + + diff --git a/trunk/docs/manual/upgrading.xml.pt-br b/trunk/docs/manual/upgrading.xml.pt-br new file mode 100644 index 0000000000..9ea19fe2b9 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.pt-br @@ -0,0 +1,215 @@ + + + + + + + + + +Atualizando da versão 1.3 para 2.0 + + +

    Com a finalidade de ajudar as pessoas na atualização do servidor, + nós mantemos um documento que descreve informações críticas para + os usuários já existentes do Apache. Essas informações tem o + intuito de serem breves notas e você deverá encontrar mais + informações no documento Novas Funcionalidades, ou no + arquivo src/CHANGES.

    +
    +Descrição das novas + funcionalidades do Apache 2.0 + +
    + Mudanças na Configuração em tempo de Compilação + +
      +
    • O Apache agora usa o sistema autoconf + e libtool para + configurar o processo de construção. + A utilização desse sistema é similar, mas não o + mesmo, a usar o sistema APACI do Apache 1.3
    • + +
    • Além da seleção habitual de módulos que você + pode escolher para compilar, o Apache 2.0 mudou a parte + principal de processamentos de pedidos para os Módulos Multi-Processamento (MPMs).
    • +
    +
    + +
    + Mudanças na Configuração em tempo de Execução + +
      +
    • Muitas diretrizes que estavam no núcleo do servidor + no Apache 1.3 estão agora nos MPMs. Se você desejar que + o funcionamento do servidor seja o mais similar possível ao + do Apache 1.3, você deve selecionar o MPM prefork. + Os outros MPMs terão diretrizes diferentes para controlar + a criação de processos e o processamento de pedidos.
    • + +
    • O módulo proxy foi reconstruído + para o padrão HTTP/1.1. Ao longo das mudanças importantes, + o controle de acesso ao proxy agora fica dentro de um bloco + Proxy, + ao invés de um bloco <Directory proxy:>.
    • + +
    • A operação com PATH_INFO (informação de + caminho procedente depois do nome do arquivo verdadeiro) mudou + para alguns módulos. Módulos que eram previamente implementados + como manipuladores mas agora são implementados como filtros + não podem mais aceitar pedidos com PATH_INFO. + Filtros como INCLUDES + ou PHP são implementados + no topo dos manipuladores principais, rejeitando pedidos + com PATH_INFO. Você pode usar a diretriz + AcceptPathInfo + para forçar o manipulador principal a aceitar pedidos + com PATH_INFO e assim restaurar a habilidade + de usá-lo em inclusões por parte do servidor (SSI).
    • + +
    • A diretriz CacheNegotiatedDocs agora aceita + o argumento on ou off. Instâncias + existentes de CacheNegotiatedDocs deverão + ser substituídas por CacheNegotiatedDocs on.
    • + +
    • + A diretriz ErrorDocument + não usa mais aspas no começo do argumento para indicar + mensagens de texto. Ao invés disso, você deve colocar + a mensagem inteira entre aspas. Por exemplo, instâncias + existentes de + + + ErrorDocument 403 "Alguma mensagem + + devem ser substituídas por + + + ErrorDocument 403 "Alguma mensagem" + + + Contanto que o segundo argumento não seja uma + URL válida ou um caminho de arquivo, irá ser + tratado como uma mensagem de texto. +
    • + +
    • As diretrizes AccessConfig e + ResourceConfig não existem mais. + Instâncias existentes dessas diretrizes podem ser substituídas + com a diretriz Include + que possui uma funcionalidade equivalente. Se você estava + fazendo uso dos valores padrões dessas diretrizes sem incluí-las + nos arquivos de configuração, você provavelmente terá + que adicionar Include conf/access.conf e + Include conf/srm.conf ao seu httpd.conf. + Com o fim de assegurar que o Apache leia os arquivos de + configuração na mesma ordem que as diretrizes velhas usavam, + a diretriz Include deve ser colocada + no final do httpd.conf, com uma entrada para + srm.conf antes de access.conf.
    • + +
    • As diretrizes BindAddress and Port + não existem mais. Uma funcionalidade equivalente é fornecida com + uma diretriz mais flexível Listen.
    • + +
    • Outro uso da diretriz Port no Apache-1.3 + era ajustar o número da porta usada em URLs auto-referenciáveis. + O equivalente no Apache-2.0 é a nova sintaxe ServerName: ela foi modificada para permitir que + sejam especificados ambos "hostname" e o número da porta + para URLs auto-referenciáveis em uma só diretriz.
    • + +
    • A diretriz ServerType não existe mais. + O método usado para atender pedidos é determinado pela + seleção de MPM. Atualmente não existe nenhuma MPM projetada + para ser executada pelo inetd.
    • + +
    • Os módulos mod_log_agent e mod_log_referer + que forneciam as diretrizes AgentLog, + RefererLog e RefererIgnore foram removidas. + Registros de agentes e referências ainda estão disponíveis + usando a diretriz CustomLog do + mod_log_config.
    • + +
    • As diretrizes AddModule e + ClearModuleList não existem mais. + Essas diretrizes eram usadas para garantir que módulos + pudessem ser habilitados na ordem correta. A nova API do + Apache 2.0 permite que os módulos especifiquem explicitamente + a sua ordem, eliminando a necessidade dessas diretrizes.
    • + +
    • A diretriz FancyIndexing foi removida. + A mesma funcionalidade está disponível através da + opção FancyIndexing da diretriz IndexOptions.
    • + +
    • A técnica de negociação de conteúdo (content-negotiation) + MultiViews fornecida pelo mod_negotiation + se tornou mais rigorosa em sua combinação de arquivo + padrão. Ela irá selecionar apenas arquivos negociáveis + (negotiable). O comportamento antigo pode ser restaurado usando a + diretriz MultiviewsMatch.
    • + +
    • (desde a versão 2.0.51) +

      A funcionalidade da diretriz ErrorHeader + foi colocada em conjunto com a diretriz Header, já que era um + uso de um nome impróprio. Utilize

      + + + Header always set foo bar + + +

      para obter o comportamento desejado.

    • +
    +
    + +
    + Mudanças Gerais + +
      +
    • O módulo mod_auth_digest, que era + experimental no Apache 1.3, é agora um módulo padrão.
    • + +
    • O módulo mod_mmap_static, que era experimental no + Apache 1.3, foi substituído com mod_file_cache.
    • + +
    • A distribuição foi completamente reorganizada para + não conter mais um diretório src independente. + Em seu lugar, os fontes são organizados + logicamente no diretório principal da distribuição e + a instalação do servidor compilado deve ser direcionada + à um diretório separado.
    • +
    +
    + +
    + Módulos de Terceiros + +

    Mudanças extensivas foram feitas na API do servidor + no Apache 2.0. Módulos existentes projetados para a API + do Apache 1.3, não funcionarão no Apache + 2.0 sem modificações. Detalhes serão fornecidos na + documentação do desenvolvedor.

    +
    +
    diff --git a/trunk/docs/manual/upgrading.xml.ru b/trunk/docs/manual/upgrading.xml.ru new file mode 100644 index 0000000000..39d1e2b744 --- /dev/null +++ b/trunk/docs/manual/upgrading.xml.ru @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + +ðÅÒÅÈÏÄ ÏÔ ×ÅÒÓÉÉ 1.3 Ë ×ÅÒÓÉÉ 2.0 + + +

    üÔÏÔ ÄÏËÕÍÅÎÔ ÎÅÏÂÈÏÄÉÍ ÄÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÐÏÍÏÞØ ÐÏÌØÚÏ×ÁÔÅÌÑÍ + ÐÅÒÅÊÔÉ Ë ÉÓÐÏÌØÚÏ×ÁÎÉÀ ÓÅÒ×ÅÒÁ ×ÅÒÓÉÉ 2.0. úÄÅÓØ ×Ù ÎÁÊÄÅÔÅ ÌÉÛØ + ËÒÁÔËÉÅ ÚÁÍÅÞÁÎÉÑ; ÂÏÌÅÅ ÐÏÄÒÏÂÎÕÀ ÉÎÆÏÒÍÁÃÉÀ Ï ÎÏ×Ï××ÅÄÅÎÉÑÈ ÍÏÖÎÏ + ÎÁÊÔÉ ÌÉÂÏ × ÄÏËÕÍÅÎÔÅ îÏ×ÙÅ ×ÏÚÍÏÖÎÏÓÔÉ, ÌÉÂÏ × ÆÁÊÌÅ src/CHANGES.

    +
    + +
    + éÚÍÅÎÅÎÉÑ × ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÉ ÓÂÏÒËÉ ÓÅÒ×ÅÒÁ + +
      +
    • Apache ÔÅÐÅÒØ ÉÓÐÏÌØÚÕÅÔ ÓÉÓÔÅÍÕ autoconf É + libtool ÄÌÑ ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÑ ÐÒÏÃÅÓÓÁ ÓÂÏÒËÉ. + éÓÐÏÌØÚÏ×ÁÎÉÅ ÜÔÏÊ ÓÉÓÔÅÍÙ ÐÏÈÏÖÅ ÎÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅ + APACI × Apache 1.3, ÈÏÔÑ É ÎÅ Ñ×ÌÑÅÔÓÑ ÁÂÓÏÌÀÔÎÏ ÔÅÍ ÖÅ ÓÁÍÙÍ.
    • + +
    • ÷ ÄÏÂÁ×ÏË Ë ÏÂÙÞÎÏÍÕ ÓÐÉÓËÕ ÍÏÄÕÌÅÊ, ËÏÔÏÒÙÅ ×Ù ÍÏÖÅÔÅ + ×ÙÂÒÁÔØ ÐÒÉ ÓÂÏÒËÅ ÓÅÒ×ÅÒÁ, × Apache 2.0 ÐÏÑ×ÉÌÉÓØ ÍÕÌØÔÉ - ÐÒÏÃÅÓÓÎÙÅ ÍÏÄÕÌÉ (íð - ÍÏÄÕÌÉ), × ËÏÔÏÒÙÈ ÔÅÐÅÒØ + ÓËÏÎÃÅÎÔÒÉÒÏ×ÁÎÁ ÏÓÎÏ×ÎÁÑ ÞÁÓÔØ ËÏÄÁ, ÏÔ×ÅÞÁÀÝÅÇÏ ÚÁ ÏÂÒÁÂÏÔËÕ + ÚÁÐÒÏÓÏ×.
    • +
    +
    + +
    + éÚÍÅÎÅÎÉÑ × ËÏÎÆÉÇÕÒÉÒÏ×ÁÎÉÉ ÒÁÂÏÔÙ ÓÅÒ×ÅÒÁ + +
      +
    • íÎÏÇÉÅ ÉÚ ÔÅÈ ÄÉÒÅËÔÉ×, ËÏÔÏÒÙÅ ÏÂÓÌÕÖÉ×ÁÌÉÓØ ÑÄÒÏÍ ÓÅÒ×ÅÒÁ + Apache 1.3, ÔÅÐÅÒØ ÐÅÒÅÎÅÓÅÎÙ × ÍÕÌØÔÉ - ÐÒÏÃÅÓÓÎÙÅ ÍÏÄÕÌÉ. åÓÌÉ ×Ù + ÈÏÔÉÔÅ, ÞÔÏÂÙ ÐÏ×ÅÄÅÎÉÅ ÓÅÒ×ÅÒÁ ÂÙÌÏ ÎÁÉÂÏÌÅÅ ÐÒÉÂÌÉÖÅÎÏ Ë ÐÏ×ÅÄÅÎÉÀ + Apache 1.3, ÔÏ ÐÒÉ ÓÂÏÒËÅ ×Ù ÄÏÌÖÎÙ ×ÙÂÒÁÔØ íð-ÍÏÄÕÌØ prefork. äÒÕÇÉÅ íð-ÍÏÄÕÌÉ ÐÒÅÄÏÓÔÁ×ÌÑÀÔ + ÉÎÙÅ ÄÉÒÅËÔÉ×Ù, ÏÔ×ÅÞÁÀÝÉÅ ÚÁ ÒÁÂÏÔÕ ÐÒÏÃÅÓÓÏ× ÓÅÒ×ÅÒÁ É ÏÂÒÁÂÏÔËÕ + ÚÁÐÒÏÓÏ×.
    • + +
    • ðÒÏËÓÉ ÍÏÄÕÌØ ÂÙÌ ÐÅÒÅÐÉÓÁÎ, + É ÔÅÐÅÒØ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÓÐÅÃÉÆÉËÁÃÉÀ HTTP/1.1. ïÄÎÉÍ ÉÚ ÎÁÉÂÏÌÅÅ + ×ÁÖÎÙÈ ÉÚÍÅÎÅÎÉÊ Ñ×ÌÑÅÔÓÑ ÔÏ, ÞÔÏ ÄÉÒÅËÔÉ×Ù, ËÏÎÔÒÏÌÉÒÕÀÝÉÅ ÒÁÂÏÔÕ + ÍÏÄÕÌÑ, ÔÅÐÅÒØ ÒÁÓÐÏÌÁÇÁÀÔÓÑ × ÓÅËÃÉÉ <Proxy>, Á ÎÅ × + <Directory proxy:>, ËÁË ÜÔÏ ÂÙÌÏ ÒÁÎÅÅ.
    • + +
    • ïÂÒÁÂÏÔËÁ PATH_INFO (ÐÕÔÅ×ÏÊ ÉÎÆÏÒÍÁÃÉÉ, ÓÌÅÄÕÀÝÅÊ ÚÁ + ÉÍÅÎÅÍ ÚÁÐÒÁÛÉ×ÁÅÍÏÇÏ ÄÏËÕÍÅÎÔÁ) ÉÚÍÅÎÉÌÁÓØ ÄÌÑ ÎÅËÏÔÏÒÙÈ ÍÏÄÕÌÅÊ. + íÏÄÕÌÉ, ËÏÔÏÒÙÅ ÒÁÎØÛÅ ÂÙÌÉ ÎÁÐÉÓÁÎÙ ËÁË ÏÂÒÁÂÏÔÞÉËÉ (handler), Á + ÔÅÐÅÒØ ×ÙÐÏÌÎÑÀÔ ÒÏÌØ ÆÉÌØÔÒÏ×, ÍÏÇÕÔ ÂÏÌÅÅ ÎÅ ÐÒÉÎÉÍÁÔØ ÚÁÐÒÏÓÙ, + ÓÏÄÅÒÖÁÝÉÅ PATH_INFO. ôÁËÉÅ ÆÉÌØÔÒÙ, ËÁË INCLUDES ÒÅÁÌÉÚÏ×ÁÎÙ ÐÅÒ×ÙÍÉ × ÂÁÚÏ×ÏÍ + ÏÂÒÁÂÏÔÞÉËÅ, ÔÁËÉÍ ÏÂÒÁÚÏÍ ÏÎÉ ÎÅ ÍÏÇÕÔ ÐÒÉÎÉÍÁÔØ ÚÁÐÒÏÓÙ, ÓÏÄÅÒÖÁÝÉÅ + PATH_INFO. ÷Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÄÉÒÅËÔÉ×Õ AcceptPathInfo, ÞÔÏÂÙ ÚÁÓÔÁ×ÉÔØ ÂÁÚÏ×ÙÊ + ÏÂÒÁÂÏÔÞÉË ÐÒÉÎÉÍÁÔØ ÐÏÄÏÂÎÙÅ ÚÁÐÒÏÓÙ, É ÔÁËÉÍ ÏÂÒÁÚÏÍ ×ÏÓÓÔÁÎÏ×ÉÔØ + ×ÏÚÍÏÖÎÏÓÔØ ÉÓÐÏÌØÚÏ×ÁÎÉÑ PATH_INFO × ÄÏËÕÍÅÎÔÁÈ, ÉÓÐÏÌØÚÕÀÝÉÈ ×ËÌÀÞÅÎÉÑ + ÎÁ ÓÔÏÒÏÎÅ ÓÅÒ×ÅÒÁ (SSI).
    • + +
    • äÉÒÅËÔÉ×Á CacheNegotiatedDocs + ÔÅÐÅÒØ ÍÏÖÅÔ ÐÒÉÎÉÍÁÔØ ÁÒÇÕÍÅÎÔÙ on É + off. õÖÅ ÓÕÝÅÓÔ×ÕÀÝÉÅ ÜËÚÅÍÐÌÑÒÙ ÄÉÒÅËÔÉ×Ù + CacheNegotiatedDocs ÄÏÌÖÎÙ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÎÁ + CacheNegotiatedDocs on.
    • + +
    • + äÉÒÅËÔÉ×Á ErrorDocument + ÂÏÌÅÅ ÎÅ ÉÓÐÏÌØÚÕÅÔ ÏÔËÒÙ×ÁÀÝÕÀ ËÁ×ÙÞËÕ × ÎÁÞÁÌÅ ÁÒÇÕÍÅÎÔÁ + ÄÌÑ ÏÂÏÚÎÁÞÅÎÉÑ ÔÏÇÏ, ÞÔÏ ÁÒÇÕÍÅÎÔ Ñ×ÌÑÅÔÓÑ ÔÅËÓÔÏ×ÙÍ ÓÏÏÂÝÅÎÉÅÍ. + ÷ÍÅÓÔÏ ÜÔÏÇÏ ×ÁÍ ÎÅÏÂÈÏÄÉÍÏ ÚÁËÌÀÞÁÔØ ×ÅÓØ ÔÅËÓÔ ÓÏÏÂÝÅÎÉÑ + × Ä×ÏÊÎÙÅ ËÁ×ÙÞËÉ. îÁÐÒÉÍÅÒ, ÓÕÝÅÓÔ×ÕÀÝÉÅ ÄÉÒÅËÔÉ×Ù + + + ErrorDocument 403 "îÅËÏÔÏÒÏÅ ÓÏÏÂÝÅÎÉÅ + + ÄÏÌÖÎÙ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÎÁ + + + ErrorDocument 403 "îÅËÏÔÏÒÏÅ ÓÏÏÂÝÅÎÉÅ" + + åÓÌÉ ×ÔÏÒÏÊ ÁÒÇÕÍÅÎÔ ÎÅ Ñ×ÌÑÅÔÓÑ ÐÒÁ×ÉÌØÎÏ ÏÆÏÒÍÌÅÎÎÙÍ + ÉÄÅÎÔÉÆÉËÁÔÏÒÏÍ ÒÅÓÕÒÓÁ (URL) ÉÌÉ ÐÕÔÅ×ÙÍ ÉÍÅÎÅÍ, ÔÏ ÏÎ + ÂÕÄÅÔ ÉÎÔÅÒÐÒÅÔÉÒÏ×ÁÔØÓÑ ËÁË ÔÅËÓÔÏ×ÏÅ ÓÏÏÂÝÅÎÉÅ. +
    • + +
    • äÉÒÅËÔÉ×Ù AccessConfig É + ResourceConfig ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. + éÍÅÀÝÉÅÓÑ ÉÈ ËÏÐÉÉ ÍÏÇÕÔ ÂÙÔØ ÚÁÍÅÎÅÎÙ ÄÉÒÅËÔÉ×ÏÊ + Include, ËÏÔÏÒÁÑ ÉÍÅÅÔ + ÔÕ ÖÅ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ. åÓÌÉ ÐÒÅÖÄÅ ×Ù ÎÅ ×ËÌÀÞÁÌÉ ÉÈ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÅ + ÆÁÊÌÙ, ÔÅÍ ÓÁÍÙÍ ÉÓÐÏÌØÚÕÑ ÉÈ ÚÎÁÞÅÎÉÑ ÐÏ ÕÍÏÌÞÁÎÉÀ, ÔÏ ÓÅÊÞÁÓ, + ÄÌÑ ÄÏÓÔÉÖÅÎÉÑ ÔÏÇÏ ÖÅ ÒÅÚÕÌØÔÁÔÁ, ×ÁÍ ÎÁÄÏ + ÄÏÂÁ×ÉÔØ ÓÌÅÄÕÀÝÉÅ ÓÔÒÏËÉ × ÆÁÊÌ httpd.conf: Include conf/access.conf É Include + conf/srm.conf. äÌÑ ÔÏÇÏ ÞÔÏÂÙ ÂÙÔØ Õ×ÅÒÅÎÎÙÍ × ÔÏÍ, ÞÔÏ + Apache ÓÞÉÔÙ×ÁÅÔ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÅ ÆÁÊÌÙ ÉÍÅÎÎÏ × ÔÏÍ ÐÏÒÑÄËÅ, + ËÏÔÏÒÙÊ ÂÙÌ ÐÒÅÄÕÓÍÏÔÒÅÎ ÓÔÁÒÙÍÉ ÄÉÒÅËÔÉ×ÁÍÉ, ÎÁÄÏ ÐÏÍÅÓÔÉÔØ + ÄÉÒÅËÔÉ×Ù Include × ËÏÎÃÅ ÆÁÊÌÁ httpd.conf, ÐÒÉÞÅÍ + ÓÐÅÒ×Á ÔÕ, ÞÔÏ ×ËÌÀÞÁÅÔ srm.conf, Á ÚÁÔÅÍ ÔÕ, ÞÔÏ + ×ËÌÀÞÁÅÔ access.conf.
    • + +
    • äÉÒÅËÔÉ×Ù BindAddress É Port + ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. üË×É×ÁÌÅÎÔÎÁÑ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ ÐÒÅÄÏÓÔÁ×ÌÑÅÔÓÑ + ÂÏÌÅÅ ÇÉÂËÏÊ ÄÉÒÅËÔÉ×ÏÊ Listen. +
    • + +
    • ÷ Apache 1.3 ÄÉÒÅËÔÉ×Á Port + ÉÓÐÏÌØÚÏ×ÁÌÁÓØ, ËÒÏÍÅ ×ÓÅÇÏ ÐÒÏÞÅÇÏ, ÄÌÑ ÔÏÇÏ ÞÔÏÂÙ ÓÅÒ×ÅÒ + ÍÏÇ ÆÏÒÍÉÒÏ×ÁÔØ ÐÒÁ×ÉÌØÎÙÅ ÓÓÙÌËÉ ÎÁ ÓÁÍÏÇÏ ÓÅÂÑ. ÷ Apache 2.0 ÄÌÑ + ÔÅÈ ÖÅ ÃÅÌÅÊ ÓÌÕÖÉÔ ÎÏ×ÙÊ ÓÉÎÔÁËÓÉÓ ÄÉÒÅËÔÉ×Ù ServerName: ÏÎ ÂÙÌ ÉÚÍÅÎÅÎ ÔÁËÉÍ ÏÂÒÁÚÏÍ, ÞÔÏ ÔÅÐÅÒØ + ÉÍÑ ÈÏÓÔÁ É ÎÏÍÅÒ ÐÏÒÔÁ ÍÏÖÎÏ ÕËÁÚÙ×ÁÔØ × ÏÄÎÏÊ ÜÔÏÊ ÄÉÒÅËÔÉ×Å.
    • + +
    • äÉÒÅËÔÉ×Á ServerType ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ. + íÅÔÏÄ ÏÂÒÁÂÏÔËÉ ÚÁÐÒÏÓÏ× ÔÅÐÅÒØ ÏÐÒÅÄÅÌÑÅÔÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ + ×ÙÂÏÒÁ íð-ÍÏÄÕÌÑ. ÷ ÎÁÓÔÏÑÝÅÅ ×ÒÅÍÑ ÎÅÔ ÔÁËÏÇÏ íð-ÍÏÄÕÌÑ, + ËÏÔÏÒÙÊ ÍÏÇ ÂÙ ÚÁÐÕÓËÁÔØÓÑ ÐÏÓÒÅÄÓÔ×ÏÍ ÄÅÍÏÎÁ inetd.
    • + +
    • íÏÄÕÌÉ mod_log_agent É mod_log_referer, ËÏÔÏÒÙÅ ÐÒÅÄÏÓÔÁ×ÌÑÌÉ + ÔÁËÉÅ ÄÉÒÅËÔÉ×Ù, ËÁË AgentLog, RefererLog + É RefererIgnore, ÂÙÌÉ ÕÂÒÁÎÙ. ÷ÅÄÅÎÉÅ ÖÕÒÎÁÌÁ ÁÇÅÎÔÏ× + ÐÏÌØÚÏ×ÁÔÅÌÅÊ (agent logs) É ÏÔÐÒÁ×ÉÔÅÌÅÊ (referer logs) ÐÏ-ÐÒÅÖÎÅÍÕ + ×ÏÚÍÏÖÎÏ ÐÏÓÒÅÄÓÔ×ÏÍ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ÄÉÒÅËÔÉ×Ù CustomLog ÍÏÄÕÌÑ mod_log_config.
    • + +
    • äÉÒÅËÔÉ×Ù AddModule É + ClearModuleList ÂÏÌÅÅ ÎÅ ÓÕÝÅÓÔ×ÕÀÔ. ïÎÉ ÉÓÐÏÌØÚÏ×ÁÌÉÓØ + ÄÌÑ ÏÂÅÓÐÅÞÅÎÉÑ ÐÒÁ×ÉÌØÎÏÇÏ ÐÏÒÑÄËÁ ÚÁÇÒÕÚËÉ ÍÏÄÕÌÅÊ. îÏ×ÙÊ API ÄÌÑ + Apache 2.0 ÐÏÚ×ÏÌÑÅÔ ÍÏÄÕÌÑÍ ÓÁÍÉÍ ÕËÁÚÙ×ÁÔØ ÐÏÒÑÄÏË ÉÈ ÚÁÇÒÕÚËÉ, ÞÔÏ + ÄÅÌÁÅÔ ÜÔÉ ÄÉÒÅËÔÉ×Ù ÎÅÎÕÖÎÙÍÉ.
    • + +
    • äÉÒÅËÔÉ×Á FancyIndexing ÂÙÌÁ ÕÂÒÁÎÁ. åÅ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ + ÔÅÐÅÒØ ÏÂÅÓÐÅÞÉ×ÁÅÔÓÑ ÏÐÃÉÅÊ FancyIndexing × ÄÉÒÅËÔÉ×Å IndexOptions
    • +
    +
    + +
    + äÒÕÇÉÅ ÉÚÍÅÎÅÎÉÑ + +
      +
    • ïÐÃÉÑ ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ httpd -S, + ÐÏÚ×ÏÌÑ×ÛÁÑ ÒÁÓÐÅÞÁÔÙ×ÁÔØ ËÏÎÆÉÇÕÒÁÃÉÀ ×ÉÒÔÕÁÌØÎÙÈ ÈÏÓÔÏ×, ÔÅÐÅÒØ ÚÁÍÅÎÅÎÁ + ÏÐÃÉÅÊ -t -D DUMP_VHOSTS.
    • + +
    • íÏÄÕÌØ mod_auth_digest, ËÏÔÏÒÙÊ ÉÍÅÌ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÓÔÁÔÕÓ × + Apache 1.3, ÔÅÐÅÒØ Ñ×ÌÑÅÔÓÑ ÓÔÁÎÄÁÒÔÎÙÍ ÍÏÄÕÌÅÍ.
    • + +
    • íÏÄÕÌØ mod_mmap_static, ËÏÔÏÒÙÊ ÉÍÅÌ ÜËÓÐÅÒÉÍÅÎÔÁÌØÎÙÊ ÓÔÁÔÕÓ × + Apache 1.3, ÚÁÍÅÎÅÎ ÍÏÄÕÌÅÍ mod_file_cache.
    • + +
    • ïÒÇÁÎÉÚÁÃÉÑ ÄÉÓÔÒÉÂÕÔÉ×Á ÐÏÌÎÏÓÔØÀ ÉÚÍÅÎÅÎÁ É ÔÅÐÅÒØ + ÂÏÌÅÅ ÎÅ ÓÏÄÅÒÖÉÔ ÎÅÚÁ×ÉÓÉÍÏÇÏ ËÁÔÁÌÏÇÁ src. ÷ÍÅÓÔÏ ÜÔÏÇÏ + ÉÓÈÏÄÎÙÅ ËÏÄÙ ÌÏÇÉÞÅÓËÉ ÏÒÇÁÎÉÚÏ×ÁÎÙ × ÏÓÎÏ×ÎÏÍ ËÁÔÁÌÏÇÅ ÄÉÓÔÒÉÂÕÔÉ×Á, Á + ÕÓÔÁÎÏ×ËÁ ÓËÏÍÐÉÌÉÒÏ×ÁÎÎÏÇÏ ÓÅÒ×ÅÒÁ ÐÒÏÉÚ×ÏÄÉÔÓÑ × ÏÔÄÅÌØÎÙÊ ËÁÔÁÌÏÇ.
    • +
    +
    + +
    + íÏÄÕÌÉ ÔÒÅÔØÉÈ ÆÉÒÍ + +

    úÎÁÞÉÔÅÌØÎÙÅ ÉÚÍÅÎÅÎÉÑ ÂÙÌÉ ×ÎÅÓÅÎÙ × API ÄÌÑ Apache 2.0. + óÕÝÅÓÔ×ÕÀÝÉÅ ÍÏÄÕÌÉ, ÎÁÐÉÓÁÎÎÙÅ Ó ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ Apache 1.3 API, + ÎÅ ÂÕÄÕÔ ÒÁÂÏÔÁÔØ ÐÏÄ Apache 2.0, ÅÓÌÉ ÎÅ ×ÎÅÓÔÉ + × ÎÉÈ ÎÅÏÂÈÏÄÉÍÙÅ ÉÚÍÅÎÅÎÉÑ. âÏÌÅÅ ÐÏÄÒÏÂÎÁÑ ÉÎÆÏÒÍÁÃÉÑ ÐÏ ÜÔÏÍÕ ÐÏ×ÏÄÕ + ÄÏÓÔÕÐÎÁ × ÄÏËÕÍÅÎÔÁÃÉÉ ÄÌÑ ÒÁÚÒÁÂÏÔÞÉËÏ×.

    +
    +
    diff --git a/trunk/docs/manual/urlmapping.html b/trunk/docs/manual/urlmapping.html new file mode 100644 index 0000000000..5a9c3a9278 --- /dev/null +++ b/trunk/docs/manual/urlmapping.html @@ -0,0 +1,11 @@ +URI: urlmapping.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: urlmapping.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: urlmapping.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/urlmapping.html.en b/trunk/docs/manual/urlmapping.html.en new file mode 100644 index 0000000000..1278d1d8c3 --- /dev/null +++ b/trunk/docs/manual/urlmapping.html.en @@ -0,0 +1,285 @@ + + + +Mapping URLs to Filesystem Locations - Apache HTTP Server + + + + + +
    <-
    +

    Mapping URLs to Filesystem Locations

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    This document explains how Apache uses the URL of a request + to determine the filesystem location from which to serve a + file.

    +
    + +
    top
    +
    top
    +
    +

    DocumentRoot

    + +

    In deciding what file to serve for a given request, Apache's + default behavior is to take the URL-Path for the request (the part + of the URL following the hostname and port) and add it to the end + of the DocumentRoot specified + in your configuration files. Therefore, the files and directories + underneath the DocumentRoot + make up the basic document tree which will be visible from the + web.

    + +

    Apache is also capable of Virtual + Hosting, where the server receives requests for more than one + host. In this case, a different DocumentRoot can be specified for each + virtual host, or alternatively, the directives provided by the + module mod_vhost_alias can + be used to dynamically determine the appropriate place from which + to serve content based on the requested IP address or + hostname.

    +
    top
    +
    +

    Files Outside the DocumentRoot

    + +

    There are frequently circumstances where it is necessary to + allow web access to parts of the filesystem that are not strictly + underneath the DocumentRoot. Apache offers several + different ways to accomplish this. On Unix systems, symbolic links + can bring other parts of the filesystem under the DocumentRoot. For security reasons, + Apache will follow symbolic links only if the Options setting for the relevant + directory includes FollowSymLinks or + SymLinksIfOwnerMatch.

    + +

    Alternatively, the Alias directive will map any part + of the filesystem into the web space. For example, with

    + +

    Alias /docs /var/web

    + +

    the URL http://www.example.com/docs/dir/file.html + will be served from /var/web/dir/file.html. The + ScriptAlias directive + works the same way, with the additional effect that all content + located at the target path is treated as CGI scripts.

    + +

    For situations where you require additional flexibility, you + can use the AliasMatch and + ScriptAliasMatch + directives to do powerful regular-expression based matching and + substitution. For example,

    + +

    ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2

    + +

    will map a request to + http://example.com/~user/cgi-bin/script.cgi to the + path /home/user/cgi-bin/script.cgi and will treat + the resulting file as a CGI script.

    +
    top
    +
    +

    User Directories

    + +

    Traditionally on Unix systems, the home directory of a + particular user can be referred to as + ~user/. The module mod_userdir + extends this idea to the web by allowing files under each user's + home directory to be accessed using URLs such as the + following.

    + +

    http://www.example.com/~user/file.html

    + +

    For security reasons, it is inappropriate to give direct + access to a user's home directory from the web. Therefore, the + UserDir directive + specifies a directory underneath the user's home directory + where web files are located. Using the default setting of + Userdir public_html, the above URL maps to a file + at a directory like + /home/user/public_html/file.html where + /home/user/ is the user's home directory as + specified in /etc/passwd.

    + +

    There are also several other forms of the + Userdir directive which you can use on systems + where /etc/passwd does not contain the location of + the home directory.

    + +

    Some people find the "~" symbol (which is often encoded on the + web as %7e) to be awkward and prefer to use an + alternate string to represent user directories. This functionality + is not supported by mod_userdir. However, if users' home + directories are structured in a regular way, then it is possible + to use the AliasMatch + directive to achieve the desired effect. For example, to make + http://www.example.com/upages/user/file.html map to + /home/user/public_html/file.html, use the following + AliasMatch directive:

    + +

    AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2

    +
    top
    +
    +

    URL Redirection

    + +

    The configuration directives discussed in the above sections + tell Apache to get content from a specific place in the filesystem + and return it to the client. Sometimes, it is desirable instead to + inform the client that the requested content is located at a + different URL, and instruct the client to make a new request with + the new URL. This is called redirection and is + implemented by the Redirect directive. For example, if + the contents of the directory /foo/ under the + DocumentRoot are moved + to the new directory /bar/, you can instruct clients + to request the content at the new location as follows:

    + +

    Redirect permanent /foo/ + http://www.example.com/bar/

    + +

    This will redirect any URL-Path starting in + /foo/ to the same URL path on the + www.example.com server with /bar/ + substituted for /foo/. You can redirect clients to + any server, not only the origin server.

    + +

    Apache also provides a RedirectMatch directive for more + complicated rewriting problems. For example, to redirect requests + for the site home page to a different site, but leave all other + requests alone, use the following configuration:

    + +

    RedirectMatch permanent ^/$ + http://www.example.com/startpage.html

    + +

    Alternatively, to temporarily redirect all pages on one site + to a particular page on another site, use the following:

    + +

    RedirectMatch temp .* + http://othersite.example.com/startpage.html

    +
    top
    +
    +

    Reverse Proxy

    + +

    Apache also allows you to bring remote documents into the URL space +of the local server. This technique is called reverse +proxying because the web server acts like a proxy server by +fetching the documents from a remote server and returning them to the +client. It is different from normal proxying because, to the client, +it appears the documents originate at the reverse proxy server.

    + +

    In the following example, when clients request documents under the +/foo/ directory, the server fetches those documents from +the /bar/ directory on internal.example.com +and returns them to the client as if they were from the local +server.

    + +

    +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/ +ProxyPassReverseCookieDomain internal.example.com public.example.com +ProxyPassReverseCookiePath /foo/ /bar/ +

    + +

    The ProxyPass configures +the server to fetch the appropriate documents, while the +ProxyPassReverse +directive rewrites redirects originating at +internal.example.com so that they target the appropriate +directory on the local server. Similarly, the +ProxyPassReverseCookieDomain +and ProxyPassReverseCookieDomain +rewrite cookies set by the backend server.

    +

    It is important to note, however, that +links inside the documents will not be rewritten. So any absolute +links on internal.example.com will result in the client +breaking out of the proxy server and requesting directly from +internal.example.com. A third-party module +mod_proxy_html +is available to rewrite links in HTML and XHTML.

    +
    top
    +
    +

    Rewriting Engine

    + +

    When even more powerful substitution is required, the rewriting + engine provided by mod_rewrite + can be useful. The directives provided by this module use + characteristics of the request such as browser type or source IP + address in deciding from where to serve content. In addition, + mod_rewrite can use external database files or programs to + determine how to handle a request. The rewriting engine is capable + of performing all three types of mappings discussed above: + internal redirects (aliases), external redirects, and proxying. + Many practical examples employing mod_rewrite are discussed in the + URL Rewriting Guide.

    +
    top
    +
    +

    File Not Found

    + +

    Inevitably, URLs will be requested for which no matching + file can be found in the filesystem. This can happen for + several reasons. In some cases, it can be a result of moving + documents from one location to another. In this case, it is + best to use URL redirection to inform + clients of the new location of the resource. In this way, you + can assure that old bookmarks and links will continue to work, + even though the resource is at a new location.

    + +

    Another common cause of "File Not Found" errors is + accidental mistyping of URLs, either directly in the browser, + or in HTML links. Apache provides the module + mod_speling (sic) to help with + this problem. When this module is activated, it will intercept + "File Not Found" errors and look for a resource with a similar + filename. If one such file is found, mod_speling will send an + HTTP redirect to the client informing it of the correct + location. If several "close" files are found, a list of + available alternatives will be presented to the client.

    + +

    An especially useful feature of mod_speling, is that it will + compare filenames without respect to case. This can help + systems where users are unaware of the case-sensitive nature of + URLs and the unix filesystem. But using mod_speling for + anything more than the occasional URL correction can place + additional load on the server, since each "incorrect" request + is followed by a URL redirection and a new request from the + client.

    + +

    If all attempts to locate the content fail, Apache returns + an error page with HTTP status code 404 (file not found). The + appearance of this page is controlled with the + ErrorDocument directive + and can be customized in a flexible manner as discussed in the + Custom error responses + document.

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/urlmapping.html.ja.euc-jp b/trunk/docs/manual/urlmapping.html.ja.euc-jp new file mode 100644 index 0000000000..1bafdd4c2d --- /dev/null +++ b/trunk/docs/manual/urlmapping.html.ja.euc-jp @@ -0,0 +1,284 @@ + + + +URL ¤«¤é¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î°ÌÃÖ¤Ø¤Î¥Þ¥Ã¥× - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    URL ¤«¤é¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î°ÌÃ֤ؤΥޥå×

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ï Apache ¤¬¥ê¥¯¥¨¥¹¥È¤Î URL ¤«¤éÁ÷¿®¤¹¤ë¥Õ¥¡¥¤¥ë¤Î + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î°ÌÃÖ¤ò·èÄꤹ¤ëÊýË¡¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    top
    +
    +

    DocumentRoot

    + +

    ¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¤É¤Î¥Õ¥¡¥¤¥ë¤òÁ÷¿®¤¹¤ë¤«¤ò·èÄꤹ¤ë¤È¤­¤Î + Apache ¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ï¡¢¥ê¥¯¥¨¥¹¥È¤Î URL-Path (URL ¤Î¥Û¥¹¥È̾¤È + ¥Ý¡¼¥ÈÈÖ¹æ¤Î¸å¤Ë³¤¯Éôʬ) ¤ò¼è¤ê½Ð¤·¤ÆÀßÄê¥Õ¥¡¥¤¥ë¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë + DocumentRoot + ¤ÎºÇ¸å¤ËÄɲ乤롢¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£¤Ç¤¹¤«¤é¡¢ + DocumentRoot + ¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥Õ¥¡¥¤¥ë¤¬¥¦¥§¥Ö¤«¤é¸«¤¨¤ë´ðËܤΥɥ­¥å¥á¥ó¥È¤ÎÌÚ¹½Â¤¤ò + ¤Ê¤·¤Þ¤¹¡£

    + +

    Apache ¤Ë¤Ï¥µ¡¼¥Ð¤¬Ê£¿ô¤Î¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±¼è¤ë + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È ¤Îµ¡Ç½¤â¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¡¢¤½¤ì¤¾¤ì¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤Æ°ã¤¦ + DocumentRoot + ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Þ¤¿¡¢mod_vhost_alias + ¥â¥¸¥å¡¼¥ë¤Ë¤è¤êÄ󶡤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¡¢ + Á÷¿®¤¹¤ë¤¿¤á¤Î¥³¥ó¥Æ¥ó¥Ä¤Î¾ì½ê¤ò¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ IP + ¥¢¥É¥ì¥¹¤ä¥Û¥¹¥È̾¤«¤éưŪ¤Ë·è¤á¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    DocumentRoot ³°¤Î¥Õ¥¡¥¤¥ë

    + +

    ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¡¢ + ¸·Ì©¤Ë¤Ï DocumentRoot + ¤Î²¼¤Ë¤Ï¤Ê¤¤Éôʬ¤Ø¤Î¥¦¥§¥Ö¥¢¥¯¥»¥¹¤òµö²Ä¤¹¤ëɬÍפ¬¤¢¤ë + ¾ì¹ç¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£Apache ¤Ï¤³¤Î¤¿¤á¤ËÊ£¿ô¤ÎÊýË¡¤òÍÑ°Õ¤·¤Æ¤¤¤Þ¤¹¡£ + Unix ¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Î¾¤ÎÉôʬ¤ò¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò + »È¤Ã¤Æ DocumentRoot + ¤Î²¼¤Ë»ý¤Ã¤Æ¤¯¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥»¥­¥å¥ê¥Æ¥£¾å¤ÎÍýͳ¤Ë¤è¤ê¡¢ + Apache ¤Ï³ºÅö¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î + Options ¤ÎÀßÄê¤Ë + FollowSymLinks ¤« SymLinksIfOwnerMatch ¤¬ + ¤¢¤ë¾ì¹ç¤Ë¤Î¤ß¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò¤¿¤É¤ê¤Þ¤¹¡£

    + +

    Âå¤ï¤ê¤ÎÊýË¡¤È¤·¤Æ¡¢Alias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎǤ°Õ¤ÎÉôʬ¤ò¥¦¥§¥Ö¤Î¶õ´Ö¤Ë + ¥Þ¥Ã¥×¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢

    + +

    Alias /docs /var/web

    + +

    ¤È¤¤¤¦ÀßÄê¤Î¤È¤­¤Ï¡¢URL + http://www.example.com/docs/dir/file.html ¤Ë¤Ï + /var/web/dir/file.html ¤¬Á÷¿®¤µ¤ì¤Þ¤¹¡£ + ScriptAlias ¤â¡¢ + ÂоݤȤʤäƤ¤¤ë¥Ñ¥¹¤¬ CGI ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ°·¤ï¤ì¤ë¤È¤¤¤¦ÄɲäΠ+ ¸ú²Ì°Ê³°¤ÏƱ¤¸¤è¤¦¤ËÆ°ºî¤·¤Þ¤¹¡£

    + +

    ¤â¤Ã¤È½ÀÆð¤ÊÀßÄ꤬ɬÍפʾõ¶·¤Ç¤Ï¡¢ + AliasMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä + ScriptAliasMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö + ¤ò»È¤Ã¤Æ¶¯ÎϤÊÀµµ¬É½¸½¤Ë´ð¤Å¤¤¤¿¥Þ¥Ã¥Á¤ÈÃÖ´¹¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¡¢

    + +

    ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2

    + +

    ¤Ï http://example.com/~user/cgi-bin/script.cgi ¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤ò /home/user/cgi-bin/script.cgi ¤È¤¤¤¦¥Ñ¥¹¤Ø + ¥Þ¥Ã¥×¤·¡¢¤³¤Î¥Þ¥Ã¥×¤Î·ë²Ì¤È¤·¤Æ¤Î¥Õ¥¡¥¤¥ë¤ò CGI ¥¹¥¯¥ê¥×¥È¤È¤·¤Æ + °·¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    ¥æ¡¼¥¶¥Ç¥£¥ì¥¯¥È¥ê

    + +

    ÅÁÅýŪ¤Ë Unix ¥·¥¹¥Æ¥à¤Ç¤Ï¥æ¡¼¥¶ user ¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤ò + ~user/ ¤È¤·¤Æ»²¾È¤Ç¤­¤Þ¤¹¡£mod_userdir + ¥â¥¸¥å¡¼¥ë¤Ï¤³¤Î³µÇ°¤ò¥¦¥§¥Ö¤Ë³ÈÄ¥¤·¤Æ¡¢ + ¤½¤ì¤¾¤ì¤Î¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥Õ¥¡¥¤¥ë¤ò + °Ê²¼¤Î¤è¤¦¤Ê URL ¤ò»È¤Ã¤Æ¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    + +

    http://www.example.com/~user/file.html

    + +

    ¥»¥­¥å¥ê¥Æ¥£¤Î´ÑÅÀ¤«¤é¡¢¥¦¥§¥Ö¤«¤é¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Ø + ľÀÜ¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤ÏŬÀڤǤϤ¢¤ê¤Þ¤»¤ó¡£¤Ç¤¹¤«¤é¡¢ + UserDir ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ï + ¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Î¡¢¥¦¥§¥Ö¥Õ¥¡¥¤¥ë¤Î + ÃÖ¤«¤ì¤Æ¤¤¤ë¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄꤷ¤Þ¤¹¡£¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¤Î + Userdir public_html ¤ò»È¤¦¤È¡¢¾å¤Î URL ¤Ï + /home/user/public_html/file.html ¤È¤¤¤¦¤è¤¦¤Ê¥Õ¥¡¥¤¥ë¤Ë + ¥Þ¥Ã¥×¤µ¤ì¤Þ¤¹¡£¤³¤³¤Ç¡¢/home/user/ ¤Ï + /etc/passwd ¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ë¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£

    + +

    Userdir ¤Ë¤Ï¡¢ + /etc/passwd ¤Ë¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤Î°ÌÃÖ¤¬½ñ¤«¤ì¤Æ¤¤¤Ê¤¤ + ¥·¥¹¥Æ¥à¤Ç¤â»È¤¦¤³¤È¤Î¤Ç¤­¤ë¾¤Î·Á¼°¤â¤¢¤ê¤Þ¤¹¡£

    + +

    Ãæ¤Ë¤Ï¥·¥ó¥Ü¥ë "~" (%7e ¤Î¤è¤¦¤ËÉä¹æ²½¤µ¤ì¤ë¤³¤È¤¬Â¿¤¤) + ¤ò³Ê¹¥¤¬°­¤¤¤È»×¤Ã¤Æ¡¢¥æ¡¼¥¶¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òɽ¤¹¤¿¤á¤ËÊ̤Îʸ»úÎó¤Î + »ÈÍѤò¹¥¤à¿Í¤¬¤¤¤Þ¤¹¡£mod_userdir ¤Ï¤³¤Îµ¡Ç½¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£ + ¤·¤«¤·¡¢¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤¬µ¬Â§Åª¤Ê¹½À®¤Î¤È¤­¤Ï¡¢ + AliasMatch ¤ò»È¤Ã¤Æ˾¤ß¤Î + ¸ú²Ì¤òãÀ®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ + http://www.example.com/upages/user/file.html ¤¬ + /home/user/public_html/file.html ¤Ë¥Þ¥Ã¥×¤µ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢ + °Ê²¼¤Î¤è¤¦¤Ë AliasMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤¤¤Þ¤¹:

    + +

    AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2

    +
    top
    +
    +

    URL ¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó

    + +

    ¾å¤ÎÀá¤ÇÀâÌÀ¤·¤¿ÀßÄêÍѤΥǥ£¥ì¥¯¥Æ¥£¥Ö¤Ï Apache ¤Ë + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎÆÃÄê¤Î¾ì½ê¤«¤é¥³¥ó¥Æ¥ó¥Ä¤ò¼è¤Ã¤Æ¤­¤Æ + ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤êÊÖ¤¹¤è¤¦¤Ë¤·¤Þ¤¹¡£¤È¤­¤Ë¤Ï¡¢¤½¤ÎÂå¤ï¤ê¤Ë + ¥¯¥é¥¤¥¢¥ó¥È¤Ë¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿¥³¥ó¥Æ¥ó¥Ä¤ÏÊ̤ΠURL ¤Ë¤¢¤ë¤³¤È¤ò + ÃΤ餻¤Æ¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬¿·¤·¤¤ URL ¤Ø¿·¤·¤¤¥ê¥¯¥¨¥¹¥È¤ò¹Ô¤Ê¤¦¤è¤¦¤Ë + ¤¹¤ëÊý¤¬Ë¾¤Þ¤·¤¤¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ï¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó¤È + ¸Æ¤Ð¤ì¤Æ¤¤¤Æ¡¢Redirect + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤è¤ê¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ + DocumentRoot ¤Î²¼¤Î¥Ç¥£¥ì¥¯¥È¥ê + /foo/ ¤¬¿·¤·¤¤¥Ç¥£¥ì¥¯¥È¥ê /bar/ ¤Ë°ÜÆ°¤·¤¿¤È¤­¤Ï¡¢ + °Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤¬¿·¤·¤¤¾ì½ê¤Î¥³¥ó¥Æ¥ó¥Ä¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ë¤è¤¦¤Ë + »Ø¼¨¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹:

    + +

    Redirect permanent /foo/ + http://www.example.com/bar/

    + +

    ¤³¤ì¤Ï¡¢/foo/ ¤Ç»Ï¤Þ¤ë¤¹¤Ù¤Æ¤Î URL-Path ¤ò¡¢ + www.example.com ¥µ¡¼¥Ð¤Î /bar/ ¤¬ + /foo/ ¤ËÃÖ´¹¤µ¤ì¤¿¤â¤Î¤Ë¥ê¥À¥¤¥ì¥¯¥È¤·¤Þ¤¹¡£ + ¥µ¡¼¥Ð¤Ï¼«Ê¬¼«¿È¤Î¥µ¡¼¥Ð¤À¤±¤Ç¤Ê¤¯¡¢¤É¤Î¥µ¡¼¥Ð¤Ë¤Ç¤â¥¯¥é¥¤¥¢¥ó¥È¤ò + ¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ¤Ï¤è¤êÊ£»¨¤Ê½ñ¤­´¹¤¨¤ÎÌäÂê¤Î¤¿¤á¤Ë¡¢ + RedirectMatch ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + Ä󶡤·¤Æ¤¤¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¥µ¥¤¥È¤Î¥Û¡¼¥à¥Ú¡¼¥¸¤ò°ã¤¦¥µ¥¤¥È¤Ë¥ê¥À¥¤¥ì¥¯¥È + ¤¹¤ë¤±¤ì¤É¡¢Â¾¤Î¥ê¥¯¥¨¥¹¥È¤Ï¤½¤Î¤Þ¤Þ°·¤¦¡¢¤È¤¤¤¦¤È¤­¤Ï°Ê²¼¤ÎÀßÄê¤ò + »È¤¤¤Þ¤¹:

    + +

    RedirectMatch permanent ^/$ + http://www.example.com/startpage.html

    + +

    ¤¢¤ë¤¤¤Ï¡¢°ì»þŪ¤Ë¥µ¥¤¥È¤Î¤¹¤Ù¤Æ¤Î¥Ú¡¼¥¸¤ò¾¤Î¥µ¥¤¥È¤ÎÆÃÄê¤Î + ¥Ú¡¼¥¸¤Ø¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤È¤­¤Ï¡¢°Ê²¼¤ò»È¤¤¤Þ¤¹:

    + +

    RedirectMatch temp .* + http://othersite.example.com/startpage.html

    +
    top
    +
    +

    ¥ê¥Ð¡¼¥¹¥×¥í¥­¥·

    + +

    Apache ¤Ï±ó³ÖÃϤˤ¢¤ë¥É¥­¥å¥á¥ó¥È¤ò¥í¡¼¥«¥ë¤Î¥µ¡¼¥Ð¤Î URL ¶õ´Ö¤Ë +»ý¤Ã¤Æ¤¯¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤³¤Î¼êË¡¤Ï¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¤È¸Æ¤Ð¤ì¤Æ¤¤¤Þ¤¹¡£ +¥¦¥§¥Ö¥µ¡¼¥Ð¤¬±ó³ÖÃϤΥɥ­¥å¥á¥ó¥È¤ò¼èÆÀ¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤ËÁ÷¤êÊÖ¤¹¤Î¤¬ +¥×¥í¥­¥·¥µ¡¼¥Ð¤ÎÆ°ºî¤Î¤è¤¦¤Ë¸«¤¨¤ë¤«¤é¤Ç¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¤Ë¤Ï¥É¥­¥å¥á¥ó¥È¤¬ +¥ê¥Ð¡¼¥¹¥×¥í¥­¥·¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤Æ¤­¤Æ¤¤¤ë¤è¤¦¤Ë¸«¤¨¤ëÅÀ¤¬Ä̾ï¤Î +¥×¥í¥­¥·¤È¤Ï°Û¤Ê¤ê¤Þ¤¹¡£

    + +

    ¼¡¤ÎÎã¤Ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤¬ /foo/ ¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤¢¤ë +¥É¥­¥å¥á¥ó¥È¤ò¥ê¥¯¥¨¥¹¥È¤¹¤ë¤È¡¢¥µ¡¼¥Ð¤¬ internal.example.com ¤Î +/bar/ ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼èÆÀ¤·¤Æ¡¢¤µ¤â¥í¡¼¥«¥ë¥µ¡¼¥Ð¤«¤é¤Î +¥É¥­¥å¥á¥ó¥È¤Î¤è¤¦¤Ë¤·¤Æ¥¯¥é¥¤¥¢¥ó¥È¤ËÊÖ¤·¤Þ¤¹¡£

    + +

    +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/
    +ProxyPassReverseCookieDomain internal.example.com public.example.com
    +ProxyPassReverseCookiePath /foo/ /bar/ +

    + +

    ProxyPass ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +¥µ¡¼¥Ð¤¬Å¬Àڤʥɥ­¥å¥á¥ó¥È¤ò¼èÆÀ¤¹¤ë¤è¤¦¤ËÀßÄꤷ¡¢ +ProxyPassReverse ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï +internal.example.com ¤«¤é¤Î¥ê¥À¥¤¥ì¥¯¥È¤¬¥í¡¼¥«¥ë¥µ¡¼¥Ð¤Î +ŬÀڤʥǥ£¥ì¥¯¥È¥ê¤ò»Ø¤¹¤è¤¦¤Ë½ñ¤­´¹¤¨¤Þ¤¹¡£ +ƱÍÍ¤Ë ProxyPassReverseCookieDomain +¤È ProxyPassReverseCookiePath +¤Ç¥Ð¥Ã¥¯¥¨¥ó¥É¦¥µ¡¼¥Ð¤Îȯ¹Ô¤·¤¿ Cookie ¤ò½ñ¤­´¹¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +

    ¤¿¤À¤·¡¢¥É¥­¥å¥á¥ó¥È¤ÎÃæ¤Î¥ê¥ó¥¯¤Ï½ñ¤­´¹¤¨¤é¤ì¤Ê¤¤¡¢ +¤È¤¤¤¦¤³¤È¤ÏÃΤäƤª¤¤¤Æ¤¯¤À¤µ¤¤¡£ +¤Ç¤¹¤«¤é¡¢internal.example.com ¤Ø¤ÎÀäÂХѥ¹¤Ë¤è¤ë¥ê¥ó¥¯¤Ç¤Ï¡¢ +¥¯¥é¥¤¥¢¥ó¥È¤¬¥×¥í¥­¥·¥µ¡¼¥Ð¤òÈ´¤±½Ð¤·¤Æ internal.example.com ¤Ë +ľÀܥꥯ¥¨¥¹¥È¤òÁ÷¤ë¡¢¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ +¥µ¡¼¥É¥Ñ¡¼¥Æ¥£À½¥â¥¸¥å¡¼¥ë¤Î mod_proxy_html +¤Ï¡¢HTML ¤È XHTML Ãæ¤Î¥ê¥ó¥¯¤ò½ñ¤­´¹¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    ¥ê¥é¥¤¥È¥¨¥ó¥¸¥ó

    + +

    ¤è¤ê°ìÁض¯ÎϤÊÃÖ´¹¤¬É¬ÍפʤȤ­¤Ï¡¢mod_rewrite + ¤¬Ä󶡤¹¤ë¥ê¥é¥¤¥È¥¨¥ó¥¸¥ó¤¬Ìò¤ËΩ¤Ä¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¥â¥¸¥å¡¼¥ë¤Ë¤è¤êÄ󶡤µ¤ì¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï + ¥Ö¥é¥¦¥¶¤Î¼ïÎà¡¢¥ê¥¯¥¨¥¹¥È¸µ¤Î IP ¥¢¥É¥ì¥¹¤Ê¤É¤Î¥ê¥¯¥¨¥¹¥È¤ÎÆÃħ¤ò + »È¤Ã¤ÆÁ÷¤êÊÖ¤¹¥³¥ó¥Æ¥ó¥Ä¤Î¾ì½ê¤ò·è¤á¤Þ¤¹¡£¤µ¤é¤Ë¡¢mod_rewrite + ¤Ï³°Éô¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤ä¥×¥í¥°¥é¥à¤ò»È¤Ã¤Æ¥ê¥¯¥¨¥¹¥È¤Î°·¤¤Êý¤ò + ·è¤á¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¥ê¥é¥¤¥È¥¨¥ó¥¸¥ó¤Ï¾å¤Çµó¤²¤é¤ì¤Æ¤¤¤ë»°¤Ä¤Î¥Þ¥Ã¥Ô¥ó¥° + ¤¹¤Ù¤Æ¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹: ÆâÉô¤Î¥ê¥À¥¤¥ì¥¯¥È (¥¨¥¤¥ê¥¢¥¹)¡¢ + ³°Éô¤Î¥ê¥À¥¤¥ì¥¯¥È¡¢¥×¥í¥­¥·¤Ç¤¹¡£mod_rewrite ¤ò»È¤¦Â¿¤¯¤Î¼ÂÍÑŪ¤ÊÎã¤Ï + URL ¥ê¥é¥¤¥È¥¬¥¤¥É + ¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    top
    +
    +

    File Not Found

    + +

    ɬ¤º¡¢¥ê¥¯¥¨¥¹¥È¤µ¤ì¤¿ URL ¤ËÂбþ¤¹¤ë¥Õ¥¡¥¤¥ë¤¬¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë + ̵¤¤¤È¤¤¤¦¾ì¹ç¤¬È¯À¸¤·¤Þ¤¹¡£¤³¤ì¤¬µ¯¤³¤ë¤Î¤Ë¤Ï¤¤¤¯¤Ä¤«¤ÎÍýͳ¤¬¤¢¤ê¤Þ¤¹¡£ + ¾ì¹ç¤Ë¤è¤Ã¤Æ¤Ï¡¢¥É¥­¥å¥á¥ó¥È¤òÊ̤ξì½ê¤Ë°ÜÆ°¤·¤¿·ë²Ì¤Ç¤¢¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤Î¾ì¹ç¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ë¥ê¥½¡¼¥¹¤Î¿·¤·¤¤°ÌÃÖ¤òÃΤ餻¤ë¤¿¤á¤Ë + URL ¥ê¥À¥¤¥ì¥¯¥·¥ç¥ó¤ò»È¤¦¤Î¤¬ºÇÁ±¤ÎÊýË¡¤Ç¤¹¡£ + ¤½¤¦¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¥ê¥½¡¼¥¹¤Ï¿·¤·¤¤°ÌÃ֤˰ÜÆ°¤·¤Æ¤¤¤ë¤±¤ì¤É¤â¡¢ + ¸Å¤¤¥Ö¥Ã¥¯¥Þ¡¼¥¯¤ä¥ê¥ó¥¯¤¬Æ°ºî¤·Â³¤±¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    "File Not Found" ¥¨¥é¡¼¤Î¤â¤¦°ì¤Ä¤Î¤è¤¯¤¢¤ëÍýͳ¤Ï¡¢ + ¥Ö¥é¥¦¥¶¤Ø¤ÎľÀÜÆþÎϤä HTML ¥ê¥ó¥¯¤«¤é¤Î¶öȯŪ¤Ê URL ¤ÎÆþÎϴְ㤤¤Ç¤¹¡£ + Apache ¤Ï¤³¤ÎÌäÂê¤ò²þÁ±¤¹¤ë¤¿¤á¤Ë¡¢mod_speling + ¥â¥¸¥å¡¼¥ë (°Õ¿ÞŪ¤ÊÄÖ¤ê´Ö°ã¤¤) + (ÌõÃí: Àµ¤·¤¯¤Ï spelling) ¤òÄ󶡤·¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥â¥¸¥å¡¼¥ë¤¬ + »ÈÍѤµ¤ì¤Æ¤¤¤ë¤È¤­¤Ï¡¢"File Not Found" ¥¨¥é¡¼¤ò²£¼è¤ê¤·¤Æ¡¢ + »÷¤¿¥Õ¥¡¥¤¥ë̾¤Î¥ê¥½¡¼¥¹¤òõ¤·¤Þ¤¹¡£¤â¤·°ì¤Ä¤À¤±¸«¤Ä¤«¤Ã¤¿¾ì¹ç¤Ï + mod_speling ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ËÀµ¤·¤¤°ÌÃÖ¤òÃΤ餻¤ë¤¿¤á¤Ë HTTP ¥ê¥À¥¤¥ì¥¯¥È¤ò + Á÷¤ê¤Þ¤¹¡£¤â¤·Ê£¿ô¤Î¡Ö¶á¤¤¡×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤Ã¤¿¾ì¹ç¤Ï¡¢¤½¤ì¤é + ÂåÂؤȤʤꤨ¤ë¤â¤Î¤Î¥ê¥¹¥È¤¬¥¯¥é¥¤¥¢¥ó¥È¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£

    + +

    mod_speling ¤ÎÈó¾ï¤ËÍ­ÍѤʵ¡Ç½¤Ï¡¢Âçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤»¤º¤Ë + ¥Õ¥¡¥¤¥ë̾¤òÈæ³Ó¤¹¤ë¤â¤Î¤Ç¤¹¡£¤³¤ì¤Ï URL ¤È unix ¤Î + ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬Î¾Êý¤È¤âÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤¹¤ë¤â¤Î¤Ç¤¢¤ë¡¢ + ¤È¤¤¤¦¤³¤È¤ò¥æ¡¼¥¶¤¬ÃΤé¤Ê¤¤¥·¥¹¥Æ¥à¤ÇÌò¤ËΩ¤Á¤Þ¤¹¡£¤¿¤À¤·¡¢ + »þÀޤΠURL ÄûÀµÄøÅ٤ǺѤޤº¡¢mod_speling ¤ò¤è¤ê¿¤¯»ÈÍѤ¹¤ë¤È¡¢¥µ¡¼¥Ð¤Ë + ¤µ¤é¤Ê¤ëÉé²Ù¤¬¤«¤«¤ê¤Þ¤¹¡£¤¹¤Ù¤Æ¤Î¡ÖÀµ¤·¤¯¤Ê¤¤¡×¥ê¥¯¥¨¥¹¥È¤Î¸å¤Ë + URL ¤Î¥ê¥À¥¤¥ì¥¯¥È¤È¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤Î¿·¤·¤¤¥ê¥¯¥¨¥¹¥È¤¬¤¯¤ë¤³¤È¤Ë + ¤Ê¤ê¤Þ¤¹¤«¤é¡£

    + +

    ¥³¥ó¥Æ¥ó¥Ä¤Î°ÌÃÖ¤ò·è¤á¤è¤¦¤È¤¹¤ë¤¹¤Ù¤Æ¤Î»î¤ß¤¬¼ºÇÔ¤¹¤ë¤È¡¢ + Apache ¤Ï¡¢HTTP ¥¹¥Æ¡¼¥¿¥¹¥³¡¼¥É 404 (file not found) ¤È¶¦¤Ë + ¥¨¥é¡¼¥Ú¡¼¥¸¤òÊÖ¤·¤Þ¤¹¡£¤³¤Î¥¨¥é¡¼¥Ú¡¼¥¸¤Î³°´Ñ¤Ï + ErrorDocument + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀ©¸æ¤µ¤ì¡¢ + ¥«¥¹¥¿¥à¥¨¥é¡¼¥ì¥¹¥Ý¥ó¥¹ ¤Ç + ÀâÌÀ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ë¡¢½ÀÆð¤ÊÀßÄê¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/urlmapping.html.ko.euc-kr b/trunk/docs/manual/urlmapping.html.ko.euc-kr new file mode 100644 index 0000000000..6829599e3f --- /dev/null +++ b/trunk/docs/manual/urlmapping.html.ko.euc-kr @@ -0,0 +1,245 @@ + + + +URLÀ» ÆÄÀϽýºÅÛ À§Ä¡·Î ´ëÀÀÇϱâ - Apache HTTP Server + + + + + +
    <-
    +

    URLÀ» ÆÄÀϽýºÅÛ À§Ä¡·Î ´ëÀÀÇϱâ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â ¿äûÀÇ URLÀ» °¡Áö°í ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ¼­ºñ½ºÇÒ + ÆÄÀÏÀÇ ÆÄÀϽýºÅÛ»ó À§Ä¡¸¦ ã´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    top
    +
    +

    DocumentRoot

    + +

    ¿äûÀ» ¹ÞÀº ¾ÆÆÄÄ¡´Â ¾î¶² ÆÄÀÏÀ» ¼­ºñ½ºÇÒÁö °áÁ¤ÇϱâÀ§ÇØ + ±âº»ÀûÀ¸·Î ¿äûÀÇ URL-°æ·Î(URL¿¡¼­ È£½ºÆ®¸í°ú Æ÷Æ® µÚ¿¡ + ³ª¿À´Â ºÎºÐ)¸¦ ¼³Á¤ÆÄÀÏ¿¡¼­ ÁöÁ¤ÇÑ DocumentRoot µÚ¿¡ ºÙÀδÙ. ±×·¡¼­ + DocumentRoot ¾Æ·¡ÀÖ´Â + ÆÄÀÏ°ú µð·ºÅ丮µéÀº À¥¿¡¼­ º¸°ÔµÉ ±âº»ÀûÀÎ ³»¿ëÀÌ´Ù.

    +
    top
    +
    +

    DocumentRoot ¹Û¿¡ ÀÖ´Â ÆÄÀϵé

    + +

    Á¾Á¾ ÆÄÀϽýºÅÛ¿¡¼­ DocumentRoot ¾Æ·¡ ÀÖÁö¾ÊÀº ºÎºÐÀ» + À¥¿¡¼­ Á¢±ÙÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ÀÌ °æ¿ì ¿©·¯°¡Áö ¹æ¹ýÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ½Éº¼¸µÅ©¸¦ »ç¿ëÇÏ¿© + ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐÀ» DocumentRoot ¾Æ·¡¿¡ µÑ ¼ö ÀÖ´Ù. + º¸¾ÈÀ» À§ÇØ ¾ÆÆÄÄ¡´Â ÇØ´ç µð·ºÅ丮ÀÇ Options ¼³Á¤¿¡ + FollowSymLinks³ª + SymLinksIfOwnerMatch°¡ ÀÖ´Â °æ¿ì¿¡¸¸ ½Éº¼¸µÅ©¸¦ + µû¶ó°£´Ù.

    + +

    ¶Ç, Alias + Áö½Ã¾î´Â ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐÀ» À¥°ø°£¿¡ ´ëÀÀÇÑ´Ù. ¿¹¸¦ + µé¾î ´ÙÀ½°ú °°´Ù¸é

    + +

    Alias /docs /var/web

    + +

    URL http://www.example.com/docs/dir/file.htmlÀº + /var/web/dir/file.htmlÀ» °¡Áö°í ¼­ºñ½ºÇÑ´Ù. + ÁöÁ¤ÇÑ °æ·Î¿¡ ÀÖ´Â ¸ðµç ³»¿ëÀ» CGI ½ºÅ©¸³Æ®·Î Ãë±ÞÇÏ´Â °ÍÀ» + Á¦¿ÜÇÏ°í´Â ScriptAlias + Áö½Ã¾îµµ °°Àº ÀÏÀ» ÇÑ´Ù.

    + +

    AliasMatch¿Í + ScriptAliasMatch + Áö½Ã¾îÀÇ °­·ÂÇÑ Á¤±ÔÇ¥Çö½Ä±â¹Ý ´ëÀÀ°ú ´ëÄ¡¸¦ »ç¿ëÇÏ¿© ´õ + À¯¿¬ÇÑ ¼³Á¤ÀÌ °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î,

    + +

    ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2

    + +

    ´Â http://example.com/~user/cgi-bin/script.cgi·ÎÀÇ + ¿äûÀ» °æ·Î /home/user/cgi-bin/script.cgi·Î + ´ëÀÀÇÏ°í, ÇØ´ç ÆÄÀÏÀ» CGI ½ºÅ©¸³Æ®·Î Ãë±ÞÇÑ´Ù.

    +
    top
    +
    +

    »ç¿ëÀÚ µð·ºÅ丮

    + +

    À¯´Ð½º ½Ã½ºÅÛÀº ÀüÅëÀûÀ¸·Î ƯÁ¤ »ç¿ëÀÚ userÀÇ + Ȩµð·ºÅ丮¸¦ ~user/·Î ÁöĪÇÑ´Ù. + mod_userdir ¸ðµâÀº ÀÌ °³³äÀ» À¥¿¡±îÁö + È®ÀåÇÏ¿©, ´ÙÀ½°ú °°Àº URLÀ» °¡Áö°í °¢ »ç¿ëÀÚ È¨µð·ºÅ丮 + ¾È¿¡ ÀÖ´Â ÆÄÀÏÀ» ¼­ºñ½ºÇÑ´Ù.

    + +

    http://www.example.com/~user/file.html

    + +

    º¸¾È»ó À¥¿¡¼­ »ç¿ëÀÚ È¨µð·ºÅ丮·Î Á÷Á¢ Á¢±ÙÇÒ ¼ö ÀÖÀ¸¸é + ¾ÈµÈ´Ù. ±×·¡¼­ UserDir + Áö½Ã¾î´Â »ç¿ëÀÚ È¨µð·ºÅ丮¿¡¼­ À¥¿ë ÆÄÀϵéÀÌ ÀÖÀ» µð·ºÅ丮¸¦ + ÁöÁ¤ÇÑ´Ù. ±âº» ¼³Á¤ Userdir public_htmlÀ» »ç¿ëÇÏ°í + /home/user/°¡ /etc/passwd¿¡ ÁöÁ¤µÈ + »ç¿ëÀÚ È¨µð·ºÅ丮¶ó¸é, À§ÀÇ URLÀº ÆÄÀÏ + /home/user/public_html/file.html¿¡ ´ëÀÀÇÑ´Ù.

    + +

    ¶Ç, Userdir Áö½Ã¾î´Â /etc/passwd¿¡ + Ȩµð·ºÅ丮ÀÇ À§Ä¡°¡ ÀúÀåµÇÁö¾Ê´Â ½Ã½ºÅÛÀ» À§ÇØ ¿©·¯ ´Ù¸¥ + ÇüŸ¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾î¶² »ç¶÷Àº (º¸Åë À¥¿¡¼­ %7e·Î ÀÎÄÚµùµÇ´Â) + "~" ±âÈ£°¡ ÀÌ»óÇÏ¿© ´Ù¸¥ ¹æ½ÄÀ¸·Î »ç¿ëÀÚ µð·ºÅ丮¸¦ ³ªÅ¸³»°í + ½Í¾îÇÑ´Ù. ÀÌ ±â´ÉÀº mod_userdirÀÌ Á¦°øÇÏÁö¾Ê´Â´Ù. ±×·¯³ª + »ç¿ëÀÚ È¨µð·ºÅ丮°¡ ±ÔÄ¢ÀûÀÎ ¹æ¹ýÀ¸·Î ±¸¼ºµÇÀÖ´Ù¸é, AliasMatch Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¿øÇÏ´Â È¿°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ÀÇ + AliasMatch Áö½Ã¾î¸¦ »ç¿ëÇϸé + http://www.example.com/upages/user/file.htmlÀÌ + /home/user/public_html/file.html¿¡ ´ëÀÀÇÑ´Ù:

    + +

    AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2

    +
    top
    +
    +

    URL ¸®´ÙÀÌ·º¼Ç(Redirection)

    + +

    ¾Õ¿¡¼­ ¼³¸íÇÑ ¼³Á¤ Áö½Ã¾îµéÀº ¾ÆÆÄÄ¡°¡ ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ + Àå¼Ò¿¡ ÀÖ´Â ³»¿ëÀ» Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»°Ô ¸¸µç´Ù. ±×·¯³ª + ¶§¶§·Î ¿äûÇÑ ³»¿ëÀÌ ´Ù¸¥ URL¿¡ ÀÖ´Ù°í Ŭ¶óÀ̾ðÆ®¿¡°Ô ¾Ë·ÁÁÖ¾î, + Ŭ¶óÀ̾ðÆ®°¡ »õ·Î ±× URLÀ» ¿äûÇϵµ·Ï ¸¸µå´Â °ÍÀÌ ÁÁÀ» ¶§°¡ + ÀÖ´Ù. À̸¦ ¸®´ÙÀÌ·º¼Ç(redirection)À̶ó°í Çϸç, + Redirect Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, DocumentRoot ¾Æ·¡ /foo/ + µð·ºÅ丮ÀÇ ³»¿ëÀ» »õ·Î /bar/ µð·ºÅ丮·Î ¿Å°å´Ù¸é + ´ÙÀ½°ú °°ÀÌ Å¬¶óÀ̾ðÆ®°¡ »õ·Î¿î À§Ä¡¸¦ ¿äûÇϵµ·Ï ÇÑ´Ù:

    + +

    Redirect permanent /foo/ + http://www.example.com/bar/

    + +

    ±×·¯¸é www.example.com ¼­¹öÀÇ /foo/·Î + ½ÃÀÛÇÏ´Â URL-°æ·Î´Â /foo/¸¦ /bar/·Î + ¹Ù²Û URL·Î ¸®´ÙÀÌ·º¼ÇµÈ´Ù. Ŭ¶óÀ̾ðÆ®¸¦ ¿ø·¡ ¼­¹ö¿Ü¿¡ ¾î¶² + ´Ù¸¥ ¼­¹ö·Îµµ ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡´Â ´õ º¹ÀâÇÑ ÀçÀÛ¼º ¹®Á¦¸¦ À§ÇØ + RedirectMatch + Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù. ¿¹¸¦ µé¾î, ´Ù¸¥ ¿äûÀº ±×´ë·Î µÎ°í »çÀÌÆ® + ȨÆäÀÌÁö¿¡ ´ëÇÑ ¿äû¸¸À» ´Ù¸¥ »çÀÌÆ®·Î ¸®´ÙÀÌ·º¼ÇÇÏ·Á¸é:

    + +

    RedirectMatch permanent ^/$ + http://www.example.com/startpage.html

    + +

    Àӽ÷Π»çÀÌÆ®ÀÇ ¸ðµç ÆäÀÌÁö¸¦ ´Ù¸¥ »çÀÌÆ®ÀÇ Æ¯Á¤ ÆäÀÌÁö·Î + ¸®´ÙÀÌ·º¼ÇÇÏ·Á¸é:

    + +

    RedirectMatch temp .* + http://othersite.example.com/startpage.html

    +
    top
    +
    +

    ¿ªÇÁ·Ï½Ã(Reverse Proxy)

    + +

    ¾ÆÆÄÄ¡´Â ´Ù¸¥ ¼­¹ö¿¡ ÀÖ´Â ¹®¼­¸¦ ¼­¹öÀÇ URL °ø°£À¸·Î °¡Á®¿Ã +¼ö ÀÖ´Ù. ÀÌ °æ¿ì À¥¼­¹ö°¡ ¿ø°Ý ¼­¹ö¿¡¼­ ¹®¼­¸¦ °¡Á®¿Í¼­ +Ŭ¶óÀ̾ðÆ®¿¡°Ô Àü´ÞÇÏ´Â ÇÁ·Ï½Ã ¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇϱ⶧¹®¿¡ ÀÌ·± +¹æ¹ýÀ» ¿ªÇÁ·Ï½Ã(reverse proxying)¶ó°í ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®ÀÇ +ÀÔÀå¿¡¼­ ¿ªÇÁ·Ï½Ã ¼­¹ö°¡ ¹®¼­¸¦ º¸³»ÁÖ´Â °Íó·³ º¸À̹ǷΠÀÏ¹Ý +ÇÁ·Ï½Ã¿Í´Â ´Ù¸£´Ù.

    + +

    ¾Æ·¡ ¼³Á¤¿¡¼­ Ŭ¶óÀ̾ðÆ®°¡ /foo/¿¡ ÀÖ´Â ¹®¼­¸¦ +¿äûÇϸé, ¼­¹ö´Â internal.example.comÀÇ +/bar/ µð·ºÅ丮¿¡¼­ ¹®¼­¸¦ °¡Á®¿Í¼­ ¹®¼­°¡ ¸¶Ä¡ +¼­¹ö¿¡ ÀÖ¾ú´ø °Íó·³ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù.

    + +

    +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/ +

    + +

    ProxyPass´Â ¼­¹ö°¡ +ÀûÀýÇÑ ¹®¼­¸¦ °¡Á®¿Àµµ·Ï ¼³Á¤Çϸç, ProxyPassReverse Áö½Ã¾î´Â +internal.example.comÀÌ º¸³»´Â ¸®´ÙÀÌ·º¼ÇÀ» ÀçÀÛ¼ºÇÏ¿© +¸®´ÙÀÌ·º¼ÇÀÌ ÇöÀç ¼­¹öÀÇ ÀûÀýÇÑ µð·ºÅ丮¸¦ °¡¸®Å°µµ·Ï ÇÑ´Ù. +¶Ç, ProxyPassReverseCookieDomain°ú +ProxyPassReverseCookieDomainÀº +°°Àº ¹æ¹ýÀ¸·Î ¿ø·¡ ¼­¹ö°¡ º¸³½ ÄíÅ°¸¦ ÀçÀÛ¼ºÇÑ´Ù.

    +

    ±×·¯³ª ¹®¼­ ¾È¿¡ ÀÖ´Â ¸µÅ©´Â ÀçÀÛ¼ºÇÏÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó. +internal.example.com¿¡ ´ëÇÑ Àý´ë¸µÅ©´Â Ŭ¶óÀ̾ðÆ®°¡ +ÇÁ·Ï½Ã¼­¹ö°¡ ¾Æ´Ï¶ó internal.example.comÀ¸·Î Á÷Á¢ +¿äûÇÏ°Ô ÇÑ´Ù. Á¦»ïÀÚ°¡ ¸¸µç mod_proxy_html +¸ðµâÀ» »ç¿ëÇÏ¿© HTML°ú XHTML¿¡ ÀÖ´Â ¸µÅ©¸¦ ÀçÀÛ¼ºÇÒ ¼ö ÀÖ´Ù.

    +
    top
    +
    +

    ÀçÀÛ¼º ¿£Áø (Rewriting Engine)

    + +

    ´õ °­·ÂÇÑ Ä¡È¯ÀÌ ÇÊ¿äÇÒ¶§ mod_rewriteÀÇ + ÀçÀÛ¼º ¿£ÁøÀÌ µµ¿òÀÌ µÈ´Ù. ÀÌ ¸ðµâÀÇ Áö½Ã¾î´Â ºê¶ó¿ìÀú Á¾·ù³ª + Ŭ¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼Ò µî ¿äûÀÇ Æ¯Â¡À» °¡Áö°í ¾îµð¿¡ ÀÖ´Â + ³»¿ëÀ» ¼­ºñ½ºÇÒÁö °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¶Ç, mod_rewrite´Â ¿äûÀ» + ¾î¶»°Ô ó¸®ÇÒÁö °áÁ¤ÇϱâÀ§ÇØ ¿ÜºÎ µ¥ÀÌÅͺ£À̽º ÆÄÀÏÀ̳ª + ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀçÀÛ¼º ¿£ÁøÀº À§¿¡¼­ ´Ù·é ¼¼ + Á¾·ù ´ëÀÀ, Áï, ³»ºÎ ¸®´ÙÀÌ·º¼Ç (alias), ¿ÜºÎ ¸®´ÙÀÌ·º¼Ç, + ÇÁ·Ï½Ã, ¸ðµÎ¸¦ Áö¿øÇÑ´Ù. mod_rewrite¸¦ »ç¿ëÇÏ´Â ½ÇÁ¦ ¿¹´Â + URL Á¦ÀÛ¼º Áöħ¼­¿¡¼­ + ¼³¸íÇÑ´Ù.

    +
    top
    +
    +

    File Not Found

    + +

    °á±¹ ¿äûÇÑ URL¿¡ ´ëÀÀÇÏ´Â ÆÄÀÏÀ» ÆÄÀϽýºÅÛ¿¡¼­ ãÁö + ¸øÇÑ °æ¿ìÀÌ´Ù. ¿©·¯ °¡Áö ÀÌÀ¯°¡ ÀÖ´Ù. ¾î¶² °æ¿ì ¹®¼­¸¦ + ´Ù¸¥ °÷À¸·Î ¿Å°å±â ¶§¹®ÀÏ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®¿¡°Ô + URL ¸®´ÙÀÌ·º¼ÇÀ¸·Î ÀÚ¿øÀÇ »õ·Î¿î + À§Ä¡¸¦ ¾Ë·ÁÁÖ´Â ¹æ¹ýÀÌ Á¦ÀÏ ÁÁ´Ù. ±×·¯¸é ÀÚ¿øÀ» ¿Å°Üµµ + ¿À·¡µÈ ºÏ¸¶Å©³ª ¸µÅ©°¡ °è¼Ó À¯È¿ÇÏ´Ù.

    + +

    "File Not Found" ¿À·ùÀÇ ´Ù¸¥ ÀϹÝÀûÀÎ ¿øÀÎÀº ºê¶ó¿ìÀú¿¡ + Á÷Á¢ ȤÀº HTML ¸µÅ©¿¡ URLÀÌ À߸ø ÀÔ·ÂµÈ °æ¿ìÀÌ´Ù. ¾ÆÆÄÄ¡´Â + mod_speling (¸ÂÃã¹ýÀÌ Æ²¸®Áö ¾Ê¾ÒÀ½) ¸ðµâ·Î + ÀÌ¿Í °°Àº ¹®Á¦¸¦ µ½´Â´Ù. ÀÌ ¸ðµâÀ» »ç¿ëÇϸé "File Not Found" + ¿À·ù°¡ ¹ß»ýÇÏ´Â °æ¿ì ºñ½ÁÇÑ ÆÄÀϸíÀ» °¡Áø ÀÚ¿øÀ» ã´Â´Ù. + ¸¸¾à ¹ß°ßÇϸé mod_spelingÀº Ŭ¶óÀ̾ðÆ®¸¦ ¿Ã¹Ù¸¥ À§Ä¡·Î + HTTP ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. "ºñ½ÁÇÑ" ÆÄÀÏÀÌ ¿©·¯°³ ÀÖ´Ù¸é + Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸ñ·ÏÀ» º¸³½´Ù.

    + +

    mod_spelingÀÇ Æ¯È÷ À¯¿ëÇÑ ÀåÁ¡Àº ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í + ÆÄÀϸíÀ» ºñ±³ÇÏ´Â ±â´ÉÀÌ´Ù. ±×·¡¼­ À¯´Ð½º ÆÄÀϽýºÅÛ°ú URLÀÇ + ´ë¼Ò¹®ÀÚ ¼ºÁúÀ» ¾ËÁö¸øÇÏ´Â »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡ µµ¿òÀÌ + µÈ´Ù. ±×·¯³ª mod_spelingÀÌ ÀÚÁÖ URLÀ» °íÃľßÇÑ´Ù¸é, "À߸øµÈ" + ¿äû¶§¸¶´Ù URL ¸®´ÙÀÌ·º¼Ç°ú Ŭ¶óÀ̾ðÆ®ÀÇ »õ·Î¿î ¿äûÀÌ + ÀϾ¹Ç·Î ¼­¹ö¿¡ ºÎ´ãÀÌ µÈ´Ù.

    + +

    ã´Â ½Ãµµ°¡ ¸ðµÎ ½ÇÆÐÇÏ¸é ¾ÆÆÄÄ¡´Â HTTP status code 404 + (file not found) ¿À·ùÆäÀÌÁö¸¦ º¸³½´Ù. ÀÌ ÆäÀÌÁöÀÇ ³»¿ëÀº + ErrorDocument Áö½Ã¾î·Î + Á¶ÀýÇϸç, »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä + ¹®¼­¸¦ Âü°íÇÏ¿© »ç¿ëÀÚÁ¤ÀÇÇÒ ¼ö ÀÖ´Ù.

    +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/urlmapping.xml b/trunk/docs/manual/urlmapping.xml new file mode 100644 index 0000000000..bde7e69476 --- /dev/null +++ b/trunk/docs/manual/urlmapping.xml @@ -0,0 +1,306 @@ + + + + + + + + + + Mapping URLs to Filesystem Locations + + +

    This document explains how Apache uses the URL of a request + to determine the filesystem location from which to serve a + file.

    +
    + + + +
    DocumentRoot + +

    In deciding what file to serve for a given request, Apache's + default behavior is to take the URL-Path for the request (the part + of the URL following the hostname and port) and add it to the end + of the DocumentRoot specified + in your configuration files. Therefore, the files and directories + underneath the DocumentRoot + make up the basic document tree which will be visible from the + web.

    + +

    Apache is also capable of Virtual + Hosting, where the server receives requests for more than one + host. In this case, a different DocumentRoot can be specified for each + virtual host, or alternatively, the directives provided by the + module mod_vhost_alias can + be used to dynamically determine the appropriate place from which + to serve content based on the requested IP address or + hostname.

    +
    + +
    Files Outside the DocumentRoot + +

    There are frequently circumstances where it is necessary to + allow web access to parts of the filesystem that are not strictly + underneath the DocumentRoot. Apache offers several + different ways to accomplish this. On Unix systems, symbolic links + can bring other parts of the filesystem under the DocumentRoot. For security reasons, + Apache will follow symbolic links only if the Options setting for the relevant + directory includes FollowSymLinks or + SymLinksIfOwnerMatch.

    + +

    Alternatively, the Alias directive will map any part + of the filesystem into the web space. For example, with

    + +Alias /docs /var/web + +

    the URL http://www.example.com/docs/dir/file.html + will be served from /var/web/dir/file.html. The + ScriptAlias directive + works the same way, with the additional effect that all content + located at the target path is treated as CGI scripts.

    + +

    For situations where you require additional flexibility, you + can use the AliasMatch and + ScriptAliasMatch + directives to do powerful regular-expression based matching and + substitution. For example,

    + +ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2 + +

    will map a request to + http://example.com/~user/cgi-bin/script.cgi to the + path /home/user/cgi-bin/script.cgi and will treat + the resulting file as a CGI script.

    +
    + +
    User Directories + +

    Traditionally on Unix systems, the home directory of a + particular user can be referred to as + ~user/. The module mod_userdir + extends this idea to the web by allowing files under each user's + home directory to be accessed using URLs such as the + following.

    + +http://www.example.com/~user/file.html + +

    For security reasons, it is inappropriate to give direct + access to a user's home directory from the web. Therefore, the + UserDir directive + specifies a directory underneath the user's home directory + where web files are located. Using the default setting of + Userdir public_html, the above URL maps to a file + at a directory like + /home/user/public_html/file.html where + /home/user/ is the user's home directory as + specified in /etc/passwd.

    + +

    There are also several other forms of the + Userdir directive which you can use on systems + where /etc/passwd does not contain the location of + the home directory.

    + +

    Some people find the "~" symbol (which is often encoded on the + web as %7e) to be awkward and prefer to use an + alternate string to represent user directories. This functionality + is not supported by mod_userdir. However, if users' home + directories are structured in a regular way, then it is possible + to use the AliasMatch + directive to achieve the desired effect. For example, to make + http://www.example.com/upages/user/file.html map to + /home/user/public_html/file.html, use the following + AliasMatch directive:

    + +AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2 +
    + +
    URL Redirection + +

    The configuration directives discussed in the above sections + tell Apache to get content from a specific place in the filesystem + and return it to the client. Sometimes, it is desirable instead to + inform the client that the requested content is located at a + different URL, and instruct the client to make a new request with + the new URL. This is called redirection and is + implemented by the Redirect directive. For example, if + the contents of the directory /foo/ under the + DocumentRoot are moved + to the new directory /bar/, you can instruct clients + to request the content at the new location as follows:

    + +Redirect permanent /foo/ + http://www.example.com/bar/ + +

    This will redirect any URL-Path starting in + /foo/ to the same URL path on the + www.example.com server with /bar/ + substituted for /foo/. You can redirect clients to + any server, not only the origin server.

    + +

    Apache also provides a RedirectMatch directive for more + complicated rewriting problems. For example, to redirect requests + for the site home page to a different site, but leave all other + requests alone, use the following configuration:

    + +RedirectMatch permanent ^/$ + http://www.example.com/startpage.html + +

    Alternatively, to temporarily redirect all pages on one site + to a particular page on another site, use the following:

    + +RedirectMatch temp .* + http://othersite.example.com/startpage.html +
    + +
    Reverse Proxy + +

    Apache also allows you to bring remote documents into the URL space +of the local server. This technique is called reverse +proxying because the web server acts like a proxy server by +fetching the documents from a remote server and returning them to the +client. It is different from normal proxying because, to the client, +it appears the documents originate at the reverse proxy server.

    + +

    In the following example, when clients request documents under the +/foo/ directory, the server fetches those documents from +the /bar/ directory on internal.example.com +and returns them to the client as if they were from the local +server.

    + + +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/ +ProxyPassReverseCookieDomain internal.example.com public.example.com +ProxyPassReverseCookiePath /foo/ /bar/ +
    + +

    The ProxyPass configures +the server to fetch the appropriate documents, while the +ProxyPassReverse +directive rewrites redirects originating at +internal.example.com so that they target the appropriate +directory on the local server. Similarly, the +ProxyPassReverseCookieDomain +and ProxyPassReverseCookieDomain +rewrite cookies set by the backend server.

    +

    It is important to note, however, that +links inside the documents will not be rewritten. So any absolute +links on internal.example.com will result in the client +breaking out of the proxy server and requesting directly from +internal.example.com. A third-party module +mod_proxy_html +is available to rewrite links in HTML and XHTML.

    +
    + +
    Rewriting Engine + +

    When even more powerful substitution is required, the rewriting + engine provided by mod_rewrite + can be useful. The directives provided by this module use + characteristics of the request such as browser type or source IP + address in deciding from where to serve content. In addition, + mod_rewrite can use external database files or programs to + determine how to handle a request. The rewriting engine is capable + of performing all three types of mappings discussed above: + internal redirects (aliases), external redirects, and proxying. + Many practical examples employing mod_rewrite are discussed in the + URL Rewriting Guide.

    +
    + +
    File Not Found + +

    Inevitably, URLs will be requested for which no matching + file can be found in the filesystem. This can happen for + several reasons. In some cases, it can be a result of moving + documents from one location to another. In this case, it is + best to use URL redirection to inform + clients of the new location of the resource. In this way, you + can assure that old bookmarks and links will continue to work, + even though the resource is at a new location.

    + +

    Another common cause of "File Not Found" errors is + accidental mistyping of URLs, either directly in the browser, + or in HTML links. Apache provides the module + mod_speling (sic) to help with + this problem. When this module is activated, it will intercept + "File Not Found" errors and look for a resource with a similar + filename. If one such file is found, mod_speling will send an + HTTP redirect to the client informing it of the correct + location. If several "close" files are found, a list of + available alternatives will be presented to the client.

    + +

    An especially useful feature of mod_speling, is that it will + compare filenames without respect to case. This can help + systems where users are unaware of the case-sensitive nature of + URLs and the unix filesystem. But using mod_speling for + anything more than the occasional URL correction can place + additional load on the server, since each "incorrect" request + is followed by a URL redirection and a new request from the + client.

    + +

    If all attempts to locate the content fail, Apache returns + an error page with HTTP status code 404 (file not found). The + appearance of this page is controlled with the + ErrorDocument directive + and can be customized in a flexible manner as discussed in the + Custom error responses + document.

    +
    + +
    diff --git a/trunk/docs/manual/urlmapping.xml.ja b/trunk/docs/manual/urlmapping.xml.ja new file mode 100644 index 0000000000..24c646f548 --- /dev/null +++ b/trunk/docs/manual/urlmapping.xml.ja @@ -0,0 +1,299 @@ + + + + + + + + + + URL $B$+$i%U%!%$%k%7%9%F%`>e$N0LCV$X$N%^%C%W(B + + +

    $B$3$NJ8=q$O(B Apache $B$,%j%/%(%9%H$N(B URL $B$+$iAw?.$9$k%U%!%$%k$N(B + $B%U%!%$%k%7%9%F%`>e$N0LCV$r7hDj$9$kJ}K!$r@bL@$7$^$9!#(B

    +
    + + + +
    DocumentRoot + +

    $B%j%/%(%9%H$KBP$7$F$I$N%U%!%$%k$rAw?.$9$k$+$r7hDj$9$k$H$-$N(B + Apache $B$N%G%U%)%k%H$NF0:n$O!"%j%/%(%9%H$N(B URL-Path (URL $B$N%[%9%HL>$H(B + $B%]!<%HHV9f$N8e$KB3$/ItJ,(B) $B$rDocumentRoot + $B$N:G8e$KDI2C$9$k!"$H$$$&$b$N$G$9!#$G$9$+$i!"(B + DocumentRoot + $B$N2<$N%G%#%l%/%H%j$d%U%!%$%k$,%&%'%V$+$i8+$($k4pK\$N%I%-%e%a%s%H$NLZ9=B$$r(B + $B$J$7$^$9!#(B

    + +

    Apache $B$K$O%5!<%P$,J#?t$N%[%9%H$X$N%j%/%(%9%H$r$B%P!<%A%c%k%[%9%H(B $B$N5!G=$b$"$j$^$9!#(B + $B$3$N>l9g!"$=$l$>$l$N%P!<%A%c%k%[%9%H$KBP$7$F0c$&(B + DocumentRoot + $B$r;XDj$9$k$3$H$,$G$-$^$9!#$^$?!"(Bmod_vhost_alias + $B%b%8%e!<%k$K$h$jDs6!$5$l$k%G%#%l%/%F%#%V$r;H$C$F!"(B + $BAw?.$9$k$?$a$N%3%s%F%s%D$N>l=j$r%j%/%(%9%H$5$l$?(B IP + $B%"%I%l%9$d%[%9%HL>$+$iF0E*$K7h$a$k$3$H$b$G$-$^$9!#(B

    +
    + +
    DocumentRoot $B30$N%U%!%$%k(B + +

    $B%U%!%$%k%7%9%F%`>e$N!"(B + $B87L)$K$O(B DocumentRoot + $B$N2<$K$O$J$$ItJ,$X$N%&%'%V%"%/%;%9$r5v2D$9$kI,MW$,$"$k(B + $B>l9g$,$h$/$"$j$^$9!#(BApache $B$O$3$N$?$a$KJ#?t$NJ}K!$rMQ0U$7$F$$$^$9!#(B + Unix $B%7%9%F%`$G$O!"%U%!%$%k%7%9%F%`$NB>$NItJ,$r%7%s%\%j%C%/%j%s%/$r(B + $B;H$C$F(B DocumentRoot + $B$N2<$K;}$C$F$/$k$3$H$,$G$-$^$9!#%;%-%e%j%F%#>e$NM}M3$K$h$j!"(B + Apache $B$O3:Ev$9$k%G%#%l%/%H%j$N(B + Options $B$N@_Dj$K(B + FollowSymLinks $B$+(B SymLinksIfOwnerMatch $B$,(B + $B$"$k>l9g$K$N$_%7%s%\%j%C%/%j%s%/$r$?$I$j$^$9!#(B

    + +

    $BBe$o$j$NJ}K!$H$7$F!"(BAlias + $B%G%#%l%/%F%#%V$r;H$C$F%U%!%$%k%7%9%F%`$NG$0U$NItJ,$r%&%'%V$N6u4V$K(B + $B%^%C%W$G$-$^$9!#$?$H$($P!"(B

    + +Alias /docs /var/web + +

    $B$H$$$&@_Dj$N$H$-$O!"(BURL + http://www.example.com/docs/dir/file.html $B$K$O(B + /var/web/dir/file.html $B$,Aw?.$5$l$^$9!#(B + ScriptAlias $B$b!"(B + $BBP>]$H$J$C$F$$$k%Q%9$,(B CGI $B%9%/%j%W%H$H$7$F07$o$l$k$H$$$&DI2C$N(B + $B8z2L0J30$OF1$8$h$&$KF0:n$7$^$9!#(B

    + +

    $B$b$C$H=@Fp$J@_Dj$,I,MW$J>u67$G$O!"(B + AliasMatch $B%G%#%l%/%F%#%V$d(B + ScriptAliasMatch $B%G%#%l%/%F%#%V(B + $B$r;H$C$F6/NO$J@55,I=8=$K4p$E$$$?%^%C%A$HCV49$r9T$J$&$3$H$,$G$-$^$9!#(B + $B$?$H$($P!"(B

    + +ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2 + +

    $B$O(B http://example.com/~user/cgi-bin/script.cgi $B$X$N(B + $B%j%/%(%9%H$r(B /home/user/cgi-bin/script.cgi $B$H$$$&%Q%9$X(B + $B%^%C%W$7!"$3$N%^%C%W$N7k2L$H$7$F$N%U%!%$%k$r(B CGI $B%9%/%j%W%H$H$7$F(B + $B07$$$^$9!#(B

    +
    + +
    $B%f!<%6%G%#%l%/%H%j(B + +

    $BEAE}E*$K(B Unix $B%7%9%F%`$G$O%f!<%6(B user $B$N%[!<%`%G%#%l%/%H%j$r(B + ~user/ $B$H$7$F;2>H$G$-$^$9!#(Bmod_userdir + $B%b%8%e!<%k$O$3$N35G0$r%&%'%V$K3HD%$7$F!"(B + $B$=$l$>$l$N%f!<%6$N%[!<%`%G%#%l%/%H%j$N%U%!%$%k$r(B + $B0J2<$N$h$&$J(B URL $B$r;H$C$F%"%/%;%9$G$-$k$h$&$K$7$^$9!#(B

    + +http://www.example.com/~user/file.html + +

    $B%;%-%e%j%F%#$N4QE@$+$i!"%&%'%V$+$i%f!<%6$N%[!<%`%G%#%l%/%H%j$X(B + $BD>@\%"%/%;%9$G$-$k$h$&$K$9$k$3$H$OE,@Z$G$O$"$j$^$;$s!#$G$9$+$i!"(B + UserDir $B%G%#%l%/%F%#%V$K$O(B + $B%f!<%6$N%[!<%`%G%#%l%/%H%j$N2<$N!"%&%'%V%U%!%$%k$N(B + $BCV$+$l$F$$$k%G%#%l%/%H%j$r;XDj$7$^$9!#%G%U%)%k%H$N@_Dj$N(B + Userdir public_html $B$r;H$&$H!">e$N(B URL $B$O(B + /home/user/public_html/file.html $B$H$$$&$h$&$J%U%!%$%k$K(B + $B%^%C%W$5$l$^$9!#$3$3$G!"(B/home/user/ $B$O(B + /etc/passwd $B$G;XDj$5$l$F$$$k%f!<%6$N%[!<%`%G%#%l%/%H%j$G$9!#(B

    + +

    Userdir $B$K$O!"(B + /etc/passwd $B$K%[!<%`%G%#%l%/%H%j$N0LCV$,=q$+$l$F$$$J$$(B + $B%7%9%F%`$G$b;H$&$3$H$N$G$-$kB>$N7A<0$b$"$j$^$9!#(B

    + +

    $BCf$K$O%7%s%\%k(B "~" (%7e $B$N$h$&$KId9f2=$5$l$k$3$H$,B?$$(B) + $B$r3J9%$,0-$$$H;W$C$F!"%f!<%6$N%G%#%l%/%H%j$rI=$9$?$a$KJL$NJ8;zNs$N(B + $B;HMQ$r9%$`?M$,$$$^$9!#(Bmod_userdir $B$O$3$N5!G=$r%5%]!<%H$7$F$$$^$;$s!#(B + $B$7$+$7!"%f!<%6$N%[!<%`%G%#%l%/%H%j$,5,B'E*$J9=@.$N$H$-$O!"(B + AliasMatch $B$r;H$C$FK>$_$N(B + $B8z2L$rC#@.$9$k$3$H$,$G$-$^$9!#$?$H$($P!"(B + http://www.example.com/upages/user/file.html $B$,(B + /home/user/public_html/file.html $B$K%^%C%W$5$l$k$h$&$K$9$k$K$O!"(B + $B0J2<$N$h$&$K(B AliasMatch $B%G%#%l%/%F%#%V$r;H$$$^$9(B:

    + +AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2 +
    + +
    URL $B%j%@%$%l%/%7%g%s(B + +

    $B>e$N@a$G@bL@$7$?@_DjMQ$N%G%#%l%/%F%#%V$O(B Apache $B$K(B + $B%U%!%$%k%7%9%F%`$NFCDj$N>l=j$+$i%3%s%F%s%D$r$^$7$$$3$H$,$"$j$^$9!#$3$l$O(B$B%j%@%$%l%/%7%g%s(B$B$H(B + $B8F$P$l$F$$$F!"(BRedirect + $B%G%#%l%/%F%#%V$K$h$jDocumentRoot $B$N2<$N%G%#%l%/%H%j(B + /foo/ $B$,?7$7$$%G%#%l%/%H%j(B /bar/ $B$K0\F0$7$?$H$-$O!"(B + $B0J2<$N$h$&$K$7$F%/%i%$%"%s%H$,?7$7$$>l=j$N%3%s%F%s%D$r%j%/%(%9%H$9$k$h$&$K(B + $B;X<($9$k$3$H$,$G$-$^$9(B:

    + +Redirect permanent /foo/ + http://www.example.com/bar/ + +

    $B$3$l$O!"(B/foo/ $B$G;O$^$k$9$Y$F$N(B URL-Path $B$r!"(B + www.example.com $B%5!<%P$N(B /bar/ $B$,(B + /foo/ $B$KCV49$5$l$?$b$N$K%j%@%$%l%/%H$7$^$9!#(B + $B%5!<%P$O<+J,<+?H$N%5!<%P$@$1$G$J$/!"$I$N%5!<%P$K$G$b%/%i%$%"%s%H$r(B + $B%j%@%$%l%/%H$9$k$3$H$,$G$-$^$9!#(B

    + +

    Apache $B$O$h$jJ#;($J=q$-49$($NLdBj$N$?$a$K!"(B + RedirectMatch $B%G%#%l%/%F%#%V$r(B + $BDs6!$7$F$$$^$9!#$?$H$($P!"%5%$%H$N%[!<%`%Z!<%8$r0c$&%5%$%H$K%j%@%$%l%/%H(B + $B$9$k$1$l$I!"B>$N%j%/%(%9%H$O$=$N$^$^07$&!"$H$$$&$H$-$O0J2<$N@_Dj$r(B + $B;H$$$^$9(B:

    + +RedirectMatch permanent ^/$ + http://www.example.com/startpage.html + +

    $B$"$k$$$O!"0l;~E*$K%5%$%H$N$9$Y$F$N%Z!<%8$rB>$N%5%$%H$NFCDj$N(B + $B%Z!<%8$X%j%@%$%l%/%H$9$k$H$-$O!"0J2<$r;H$$$^$9(B:

    + +RedirectMatch temp .* + http://othersite.example.com/startpage.html +
    + +
    $B%j%P!<%9%W%m%-%7(B + +

    Apache $B$O1s3VCO$K$"$k%I%-%e%a%s%H$r%m!<%+%k$N%5!<%P$N(B URL $B6u4V$K(B +$B;}$C$F$/$k$3$H$b$G$-$^$9!#$3$N$B%j%P!<%9%W%m%-%7(B$B$H8F$P$l$F$$$^$9!#(B +$B%&%'%V%5!<%P$,1s3VCO$N%I%-%e%a%s%H$ro$N(B +$B%W%m%-%7$H$O0[$J$j$^$9!#(B

    + +

    $B/foo/ $B%G%#%l%/%H%j$N2<$K$"$k(B +$B%I%-%e%a%s%H$r%j%/%(%9%H$9$k$H!"%5!<%P$,(B internal.example.com $B$N(B +/bar/ $B%G%#%l%/%H%j$+$i + + +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/
    +ProxyPassReverseCookieDomain internal.example.com public.example.com
    +ProxyPassReverseCookiePath /foo/ /bar/ +
    + +

    ProxyPass $B%G%#%l%/%F%#%V$O(B +$B%5!<%P$,E,@Z$J%I%-%e%a%s%H$rProxyPassReverse $B%G%#%l%/%F%#%V$O(B +internal.example.com $B$+$i$N%j%@%$%l%/%H$,%m!<%+%k%5!<%P$N(B +$BE,@Z$J%G%#%l%/%H%j$r;X$9$h$&$K=q$-49$($^$9!#(B +$BF1MM$K(B ProxyPassReverseCookieDomain +$B$H(B ProxyPassReverseCookiePath +$B$G%P%C%/%(%s%IB&%5!<%P$NH/9T$7$?(B Cookie $B$r=q$-49$($k$3$H$,$G$-$^$9!#(B

    +

    $B$?$@$7!"%I%-%e%a%s%H$NCf$N%j%s%/$O=q$-49$($i$l$J$$!"(B +$B$H$$$&$3$H$OCN$C$F$*$$$F$/$@$5$$!#(B +$B$G$9$+$i!"(Binternal.example.com $B$X$N@dBP%Q%9$K$h$k%j%s%/$G$O!"(B +$B%/%i%$%"%s%H$,%W%m%-%7%5!<%P$rH4$1=P$7$F(B internal.example.com $B$K(B +$BD>@\%j%/%(%9%H$rAw$k!"$H$$$&$3$H$K$J$j$^$9!#(B +$B%5!<%I%Q!<%F%#@=%b%8%e!<%k$N(B mod_proxy_html +$B$O!"(BHTML $B$H(B XHTML $BCf$N%j%s%/$r=q$-49$($k$3$H$,$G$-$^$9!#(B

    +
    + +
    $B%j%i%$%H%(%s%8%s(B + +

    $B$h$j0lAX6/NO$JCV49$,I,MW$J$H$-$O!"(Bmod_rewrite + $B$,Ds6!$9$k%j%i%$%H%(%s%8%s$,Lr$KN)$D$G$7$g$&!#(B + $B$3$N%b%8%e!<%k$K$h$jDs6!$5$l$k%G%#%l%/%F%#%V$O(B + $B%V%i%&%6$Nl=j$r7h$a$^$9!#$5$i$K!"(Bmod_rewrite + $B$O30It$N%G!<%?%Y!<%9%U%!%$%k$d%W%m%0%i%`$r;H$C$F%j%/%(%9%H$N07$$J}$r(B + $B7h$a$k$3$H$b$G$-$^$9!#%j%i%$%H%(%s%8%s$O>e$G5s$2$i$l$F$$$k;0$D$N%^%C%T%s%0(B + $B$9$Y$F$r9T$J$&$3$H$,$G$-$^$9(B: $BFbIt$N%j%@%$%l%/%H(B ($B%(%$%j%"%9(B)$B!"(B + $B30It$N%j%@%$%l%/%H!"%W%m%-%7$G$9!#(Bmod_rewrite $B$r;H$&B?$/$NURL $B%j%i%$%H%,%$%I(B + $B$G@bL@$5$l$F$$$^$9!#(B

    +
    + +
    File Not Found + +

    $BI,$:!"%j%/%(%9%H$5$l$?(B URL $B$KBP1~$9$k%U%!%$%k$,%U%!%$%k%7%9%F%`$K(B + $BL5$$$H$$$&>l9g$,H/@8$7$^$9!#$3$l$,5/$3$k$N$K$O$$$/$D$+$NM}M3$,$"$j$^$9!#(B + $B>l9g$K$h$C$F$O!"%I%-%e%a%s%H$rJL$N>l=j$K0\F0$7$?7k2L$G$"$k$3$H$,$"$j$^$9!#(B + $B$3$N>l9g$O!"%/%i%$%"%s%H$K%j%=!<%9$N?7$7$$0LCV$rCN$i$;$k$?$a$K(B + URL $B%j%@%$%l%/%7%g%s(B$B$r;H$&$N$,:GA1$NJ}K!$G$9!#(B + $B$=$&$9$k$3$H$K$h$C$F!"%j%=!<%9$O?7$7$$0LCV$K0\F0$7$F$$$k$1$l$I$b!"(B + $B8E$$%V%C%/%^!<%/$d%j%s%/$,F0:n$7B3$1$k$h$&$K$9$k$3$H$,$G$-$^$9!#(B

    + +

    "File Not Found" $B%(%i!<$N$b$&0l$D$N$h$/$"$kM}M3$O!"(B + $B%V%i%&%6$X$ND>@\F~NO$d(B HTML $B%j%s%/$+$i$N6vH/E*$J(B URL $B$NF~NO4V0c$$$G$9!#(B + Apache $B$O$3$NLdBj$r2~A1$9$k$?$a$K!"(Bmod_speling + $B%b%8%e!<%k(B ($B0U?^E*$JDV$j4V0c$$(B) + ($BLuCm(B: $B@5$7$/$O(B spelling) $B$rDs6!$7$F$$$^$9!#$3$N%b%8%e!<%k$,(B + $B;HMQ$5$l$F$$$k$H$-$O!"(B"File Not Found" $B%(%i!<$r2#$N%j%=!<%9$rC5$7$^$9!#$b$70l$D$@$18+$D$+$C$?>l9g$O(B + mod_speling $B$O%/%i%$%"%s%H$K@5$7$$0LCV$rCN$i$;$k$?$a$K(B HTTP $B%j%@%$%l%/%H$r(B + $BAw$j$^$9!#$b$7J#?t$N!V6a$$!W%U%!%$%k$,8+$D$+$C$?>l9g$O!"$=$l$i(B + $BBeBX$H$J$j$($k$b$N$N%j%9%H$,%/%i%$%"%s%H$KI=<($5$l$^$9!#(B

    + +

    mod_speling $B$NHs>o$KM-MQ$J5!G=$O!"BgJ8;z>.J8;z$r6hJL$;$:$K(B + $B%U%!%$%kL>$rHf3S$9$k$b$N$G$9!#$3$l$O(B URL $B$H(B unix $B$N(B + $B%U%!%$%k%7%9%F%`$,N>J}$H$bBgJ8;z>.J8;z$r6hJL$9$k$b$N$G$"$k!"(B + $B$H$$$&$3$H$r%f!<%6$,CN$i$J$$%7%9%F%`$GLr$KN)$A$^$9!#$?$@$7!"(B + $B;~@^$N(B URL $BD{@5DxEY$G:Q$^$:!"(Bmod_speling $B$r$h$jB?$/;HMQ$9$k$H!"%5!<%P$K(B + $B$5$i$J$kIi2Y$,$+$+$j$^$9!#$9$Y$F$N!V@5$7$/$J$$!W%j%/%(%9%H$N8e$K(B + URL $B$N%j%@%$%l%/%H$H%/%i%$%"%s%H$+$i$N?7$7$$%j%/%(%9%H$,$/$k$3$H$K(B + $B$J$j$^$9$+$i!#(B

    + +

    $B%3%s%F%s%D$N0LCV$r7h$a$h$&$H$9$k$9$Y$F$N;n$_$,<:GT$9$k$H!"(B + Apache $B$O!"(BHTTP $B%9%F!<%?%9%3!<%I(B 404 (file not found) $B$H6&$K(B + $B%(%i!<%Z!<%8$rJV$7$^$9!#$3$N%(%i!<%Z!<%8$N304Q$O(B + ErrorDocument + $B%G%#%l%/%F%#%V$G@)8f$5$l!"(B + $B%+%9%?%`%(%i!<%l%9%]%s%9(B $B$G(B + $B@bL@$5$l$F$$$k$h$&$K!"=@Fp$J@_Dj$r9T$J$&$3$H$,$G$-$^$9!#(B

    +
    + + diff --git a/trunk/docs/manual/urlmapping.xml.ko b/trunk/docs/manual/urlmapping.xml.ko new file mode 100644 index 0000000000..c80da27e3d --- /dev/null +++ b/trunk/docs/manual/urlmapping.xml.ko @@ -0,0 +1,268 @@ + + + + + + + + + + URLÀ» ÆÄÀϽýºÅÛ À§Ä¡·Î ´ëÀÀÇϱâ + + +

    ÀÌ ¹®¼­´Â ¿äûÀÇ URLÀ» °¡Áö°í ¾ÆÆÄÄ¡°¡ ¾î¶»°Ô ¼­ºñ½ºÇÒ + ÆÄÀÏÀÇ ÆÄÀϽýºÅÛ»ó À§Ä¡¸¦ ã´ÂÁö ¼³¸íÇÑ´Ù.

    +
    + + + +
    DocumentRoot + +

    ¿äûÀ» ¹ÞÀº ¾ÆÆÄÄ¡´Â ¾î¶² ÆÄÀÏÀ» ¼­ºñ½ºÇÒÁö °áÁ¤ÇϱâÀ§ÇØ + ±âº»ÀûÀ¸·Î ¿äûÀÇ URL-°æ·Î(URL¿¡¼­ È£½ºÆ®¸í°ú Æ÷Æ® µÚ¿¡ + ³ª¿À´Â ºÎºÐ)¸¦ ¼³Á¤ÆÄÀÏ¿¡¼­ ÁöÁ¤ÇÑ DocumentRoot µÚ¿¡ ºÙÀδÙ. ±×·¡¼­ + DocumentRoot ¾Æ·¡ÀÖ´Â + ÆÄÀÏ°ú µð·ºÅ丮µéÀº À¥¿¡¼­ º¸°ÔµÉ ±âº»ÀûÀÎ ³»¿ëÀÌ´Ù.

    +
    + +
    DocumentRoot ¹Û¿¡ ÀÖ´Â ÆÄÀϵé + +

    Á¾Á¾ ÆÄÀϽýºÅÛ¿¡¼­ DocumentRoot ¾Æ·¡ ÀÖÁö¾ÊÀº ºÎºÐÀ» + À¥¿¡¼­ Á¢±ÙÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ÀÌ °æ¿ì ¿©·¯°¡Áö ¹æ¹ýÀ» + »ç¿ëÇÒ ¼ö ÀÖ´Ù. À¯´Ð½º ½Ã½ºÅÛ¿¡¼­ ½Éº¼¸µÅ©¸¦ »ç¿ëÇÏ¿© + ÆÄÀϽýºÅÛÀÇ ´Ù¸¥ ºÎºÐÀ» DocumentRoot ¾Æ·¡¿¡ µÑ ¼ö ÀÖ´Ù. + º¸¾ÈÀ» À§ÇØ ¾ÆÆÄÄ¡´Â ÇØ´ç µð·ºÅ丮ÀÇ Options ¼³Á¤¿¡ + FollowSymLinks³ª + SymLinksIfOwnerMatch°¡ ÀÖ´Â °æ¿ì¿¡¸¸ ½Éº¼¸µÅ©¸¦ + µû¶ó°£´Ù.

    + +

    ¶Ç, Alias + Áö½Ã¾î´Â ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ ºÎºÐÀ» À¥°ø°£¿¡ ´ëÀÀÇÑ´Ù. ¿¹¸¦ + µé¾î ´ÙÀ½°ú °°´Ù¸é

    + +Alias /docs /var/web + +

    URL http://www.example.com/docs/dir/file.htmlÀº + /var/web/dir/file.htmlÀ» °¡Áö°í ¼­ºñ½ºÇÑ´Ù. + ÁöÁ¤ÇÑ °æ·Î¿¡ ÀÖ´Â ¸ðµç ³»¿ëÀ» CGI ½ºÅ©¸³Æ®·Î Ãë±ÞÇÏ´Â °ÍÀ» + Á¦¿ÜÇÏ°í´Â ScriptAlias + Áö½Ã¾îµµ °°Àº ÀÏÀ» ÇÑ´Ù.

    + +

    AliasMatch¿Í + ScriptAliasMatch + Áö½Ã¾îÀÇ °­·ÂÇÑ Á¤±ÔÇ¥Çö½Ä±â¹Ý ´ëÀÀ°ú ´ëÄ¡¸¦ »ç¿ëÇÏ¿© ´õ + À¯¿¬ÇÑ ¼³Á¤ÀÌ °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î,

    + +ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) + /home/$1/cgi-bin/$2 + +

    ´Â http://example.com/~user/cgi-bin/script.cgi·ÎÀÇ + ¿äûÀ» °æ·Î /home/user/cgi-bin/script.cgi·Î + ´ëÀÀÇÏ°í, ÇØ´ç ÆÄÀÏÀ» CGI ½ºÅ©¸³Æ®·Î Ãë±ÞÇÑ´Ù.

    +
    + +
    »ç¿ëÀÚ µð·ºÅ丮 + +

    À¯´Ð½º ½Ã½ºÅÛÀº ÀüÅëÀûÀ¸·Î ƯÁ¤ »ç¿ëÀÚ userÀÇ + Ȩµð·ºÅ丮¸¦ ~user/·Î ÁöĪÇÑ´Ù. + mod_userdir ¸ðµâÀº ÀÌ °³³äÀ» À¥¿¡±îÁö + È®ÀåÇÏ¿©, ´ÙÀ½°ú °°Àº URLÀ» °¡Áö°í °¢ »ç¿ëÀÚ È¨µð·ºÅ丮 + ¾È¿¡ ÀÖ´Â ÆÄÀÏÀ» ¼­ºñ½ºÇÑ´Ù.

    + +http://www.example.com/~user/file.html + +

    º¸¾È»ó À¥¿¡¼­ »ç¿ëÀÚ È¨µð·ºÅ丮·Î Á÷Á¢ Á¢±ÙÇÒ ¼ö ÀÖÀ¸¸é + ¾ÈµÈ´Ù. ±×·¡¼­ UserDir + Áö½Ã¾î´Â »ç¿ëÀÚ È¨µð·ºÅ丮¿¡¼­ À¥¿ë ÆÄÀϵéÀÌ ÀÖÀ» µð·ºÅ丮¸¦ + ÁöÁ¤ÇÑ´Ù. ±âº» ¼³Á¤ Userdir public_htmlÀ» »ç¿ëÇÏ°í + /home/user/°¡ /etc/passwd¿¡ ÁöÁ¤µÈ + »ç¿ëÀÚ È¨µð·ºÅ丮¶ó¸é, À§ÀÇ URLÀº ÆÄÀÏ + /home/user/public_html/file.html¿¡ ´ëÀÀÇÑ´Ù.

    + +

    ¶Ç, Userdir Áö½Ã¾î´Â /etc/passwd¿¡ + Ȩµð·ºÅ丮ÀÇ À§Ä¡°¡ ÀúÀåµÇÁö¾Ê´Â ½Ã½ºÅÛÀ» À§ÇØ ¿©·¯ ´Ù¸¥ + ÇüŸ¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    ¾î¶² »ç¶÷Àº (º¸Åë À¥¿¡¼­ %7e·Î ÀÎÄÚµùµÇ´Â) + "~" ±âÈ£°¡ ÀÌ»óÇÏ¿© ´Ù¸¥ ¹æ½ÄÀ¸·Î »ç¿ëÀÚ µð·ºÅ丮¸¦ ³ªÅ¸³»°í + ½Í¾îÇÑ´Ù. ÀÌ ±â´ÉÀº mod_userdirÀÌ Á¦°øÇÏÁö¾Ê´Â´Ù. ±×·¯³ª + »ç¿ëÀÚ È¨µð·ºÅ丮°¡ ±ÔÄ¢ÀûÀÎ ¹æ¹ýÀ¸·Î ±¸¼ºµÇÀÖ´Ù¸é, AliasMatch Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + ¿øÇÏ´Â È¿°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½ÀÇ + AliasMatch Áö½Ã¾î¸¦ »ç¿ëÇϸé + http://www.example.com/upages/user/file.htmlÀÌ + /home/user/public_html/file.html¿¡ ´ëÀÀÇÑ´Ù:

    + +AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) + /home/$1/public_html/$2 +
    + +
    URL ¸®´ÙÀÌ·º¼Ç(Redirection) + +

    ¾Õ¿¡¼­ ¼³¸íÇÑ ¼³Á¤ Áö½Ã¾îµéÀº ¾ÆÆÄÄ¡°¡ ÆÄÀϽýºÅÛÀÇ Æ¯Á¤ + Àå¼Ò¿¡ ÀÖ´Â ³»¿ëÀ» Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³»°Ô ¸¸µç´Ù. ±×·¯³ª + ¶§¶§·Î ¿äûÇÑ ³»¿ëÀÌ ´Ù¸¥ URL¿¡ ÀÖ´Ù°í Ŭ¶óÀ̾ðÆ®¿¡°Ô ¾Ë·ÁÁÖ¾î, + Ŭ¶óÀ̾ðÆ®°¡ »õ·Î ±× URLÀ» ¿äûÇϵµ·Ï ¸¸µå´Â °ÍÀÌ ÁÁÀ» ¶§°¡ + ÀÖ´Ù. À̸¦ ¸®´ÙÀÌ·º¼Ç(redirection)À̶ó°í Çϸç, + Redirect Áö½Ã¾î¸¦ + »ç¿ëÇÑ´Ù. ¿¹¸¦ µé¾î, DocumentRoot ¾Æ·¡ /foo/ + µð·ºÅ丮ÀÇ ³»¿ëÀ» »õ·Î /bar/ µð·ºÅ丮·Î ¿Å°å´Ù¸é + ´ÙÀ½°ú °°ÀÌ Å¬¶óÀ̾ðÆ®°¡ »õ·Î¿î À§Ä¡¸¦ ¿äûÇϵµ·Ï ÇÑ´Ù:

    + +Redirect permanent /foo/ + http://www.example.com/bar/ + +

    ±×·¯¸é www.example.com ¼­¹öÀÇ /foo/·Î + ½ÃÀÛÇÏ´Â URL-°æ·Î´Â /foo/¸¦ /bar/·Î + ¹Ù²Û URL·Î ¸®´ÙÀÌ·º¼ÇµÈ´Ù. Ŭ¶óÀ̾ðÆ®¸¦ ¿ø·¡ ¼­¹ö¿Ü¿¡ ¾î¶² + ´Ù¸¥ ¼­¹ö·Îµµ ¸®´ÙÀÌ·º¼ÇÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç, ¾ÆÆÄÄ¡´Â ´õ º¹ÀâÇÑ ÀçÀÛ¼º ¹®Á¦¸¦ À§ÇØ + RedirectMatch + Áö½Ã¾î¸¦ Á¦°øÇÑ´Ù. ¿¹¸¦ µé¾î, ´Ù¸¥ ¿äûÀº ±×´ë·Î µÎ°í »çÀÌÆ® + ȨÆäÀÌÁö¿¡ ´ëÇÑ ¿äû¸¸À» ´Ù¸¥ »çÀÌÆ®·Î ¸®´ÙÀÌ·º¼ÇÇÏ·Á¸é:

    + +RedirectMatch permanent ^/$ + http://www.example.com/startpage.html + +

    Àӽ÷Π»çÀÌÆ®ÀÇ ¸ðµç ÆäÀÌÁö¸¦ ´Ù¸¥ »çÀÌÆ®ÀÇ Æ¯Á¤ ÆäÀÌÁö·Î + ¸®´ÙÀÌ·º¼ÇÇÏ·Á¸é:

    + +RedirectMatch temp .* + http://othersite.example.com/startpage.html +
    + +
    ¿ªÇÁ·Ï½Ã(Reverse Proxy) + +

    ¾ÆÆÄÄ¡´Â ´Ù¸¥ ¼­¹ö¿¡ ÀÖ´Â ¹®¼­¸¦ ¼­¹öÀÇ URL °ø°£À¸·Î °¡Á®¿Ã +¼ö ÀÖ´Ù. ÀÌ °æ¿ì À¥¼­¹ö°¡ ¿ø°Ý ¼­¹ö¿¡¼­ ¹®¼­¸¦ °¡Á®¿Í¼­ +Ŭ¶óÀ̾ðÆ®¿¡°Ô Àü´ÞÇÏ´Â ÇÁ·Ï½Ã ¼­¹ö¿Í °°ÀÌ µ¿ÀÛÇϱ⶧¹®¿¡ ÀÌ·± +¹æ¹ýÀ» ¿ªÇÁ·Ï½Ã(reverse proxying)¶ó°í ÇÑ´Ù. Ŭ¶óÀ̾ðÆ®ÀÇ +ÀÔÀå¿¡¼­ ¿ªÇÁ·Ï½Ã ¼­¹ö°¡ ¹®¼­¸¦ º¸³»ÁÖ´Â °Íó·³ º¸À̹ǷΠÀÏ¹Ý +ÇÁ·Ï½Ã¿Í´Â ´Ù¸£´Ù.

    + +

    ¾Æ·¡ ¼³Á¤¿¡¼­ Ŭ¶óÀ̾ðÆ®°¡ /foo/¿¡ ÀÖ´Â ¹®¼­¸¦ +¿äûÇϸé, ¼­¹ö´Â internal.example.comÀÇ +/bar/ µð·ºÅ丮¿¡¼­ ¹®¼­¸¦ °¡Á®¿Í¼­ ¹®¼­°¡ ¸¶Ä¡ +¼­¹ö¿¡ ÀÖ¾ú´ø °Íó·³ Ŭ¶óÀ̾ðÆ®¿¡°Ô º¸³½´Ù.

    + + +ProxyPass /foo/ http://internal.example.com/bar/
    +ProxyPassReverse /foo/ http://internal.example.com/bar/ +
    + +

    ProxyPass´Â ¼­¹ö°¡ +ÀûÀýÇÑ ¹®¼­¸¦ °¡Á®¿Àµµ·Ï ¼³Á¤Çϸç, ProxyPassReverse Áö½Ã¾î´Â +internal.example.comÀÌ º¸³»´Â ¸®´ÙÀÌ·º¼ÇÀ» ÀçÀÛ¼ºÇÏ¿© +¸®´ÙÀÌ·º¼ÇÀÌ ÇöÀç ¼­¹öÀÇ ÀûÀýÇÑ µð·ºÅ丮¸¦ °¡¸®Å°µµ·Ï ÇÑ´Ù. +¶Ç, ProxyPassReverseCookieDomain°ú +ProxyPassReverseCookieDomainÀº +°°Àº ¹æ¹ýÀ¸·Î ¿ø·¡ ¼­¹ö°¡ º¸³½ ÄíÅ°¸¦ ÀçÀÛ¼ºÇÑ´Ù.

    +

    ±×·¯³ª ¹®¼­ ¾È¿¡ ÀÖ´Â ¸µÅ©´Â ÀçÀÛ¼ºÇÏÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó. +internal.example.com¿¡ ´ëÇÑ Àý´ë¸µÅ©´Â Ŭ¶óÀ̾ðÆ®°¡ +ÇÁ·Ï½Ã¼­¹ö°¡ ¾Æ´Ï¶ó internal.example.comÀ¸·Î Á÷Á¢ +¿äûÇÏ°Ô ÇÑ´Ù. Á¦»ïÀÚ°¡ ¸¸µç mod_proxy_html +¸ðµâÀ» »ç¿ëÇÏ¿© HTML°ú XHTML¿¡ ÀÖ´Â ¸µÅ©¸¦ ÀçÀÛ¼ºÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    ÀçÀÛ¼º ¿£Áø (Rewriting Engine) + +

    ´õ °­·ÂÇÑ Ä¡È¯ÀÌ ÇÊ¿äÇÒ¶§ mod_rewriteÀÇ + ÀçÀÛ¼º ¿£ÁøÀÌ µµ¿òÀÌ µÈ´Ù. ÀÌ ¸ðµâÀÇ Áö½Ã¾î´Â ºê¶ó¿ìÀú Á¾·ù³ª + Ŭ¶óÀ̾ðÆ®ÀÇ IP ÁÖ¼Ò µî ¿äûÀÇ Æ¯Â¡À» °¡Áö°í ¾îµð¿¡ ÀÖ´Â + ³»¿ëÀ» ¼­ºñ½ºÇÒÁö °áÁ¤ÇÒ ¼ö ÀÖ´Ù. ¶Ç, mod_rewrite´Â ¿äûÀ» + ¾î¶»°Ô ó¸®ÇÒÁö °áÁ¤ÇϱâÀ§ÇØ ¿ÜºÎ µ¥ÀÌÅͺ£À̽º ÆÄÀÏÀ̳ª + ÇÁ·Î±×·¥À» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀçÀÛ¼º ¿£ÁøÀº À§¿¡¼­ ´Ù·é ¼¼ + Á¾·ù ´ëÀÀ, Áï, ³»ºÎ ¸®´ÙÀÌ·º¼Ç (alias), ¿ÜºÎ ¸®´ÙÀÌ·º¼Ç, + ÇÁ·Ï½Ã, ¸ðµÎ¸¦ Áö¿øÇÑ´Ù. mod_rewrite¸¦ »ç¿ëÇÏ´Â ½ÇÁ¦ ¿¹´Â + URL Á¦ÀÛ¼º Áöħ¼­¿¡¼­ + ¼³¸íÇÑ´Ù.

    +
    + +
    File Not Found + +

    °á±¹ ¿äûÇÑ URL¿¡ ´ëÀÀÇÏ´Â ÆÄÀÏÀ» ÆÄÀϽýºÅÛ¿¡¼­ ãÁö + ¸øÇÑ °æ¿ìÀÌ´Ù. ¿©·¯ °¡Áö ÀÌÀ¯°¡ ÀÖ´Ù. ¾î¶² °æ¿ì ¹®¼­¸¦ + ´Ù¸¥ °÷À¸·Î ¿Å°å±â ¶§¹®ÀÏ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì Ŭ¶óÀ̾ðÆ®¿¡°Ô + URL ¸®´ÙÀÌ·º¼ÇÀ¸·Î ÀÚ¿øÀÇ »õ·Î¿î + À§Ä¡¸¦ ¾Ë·ÁÁÖ´Â ¹æ¹ýÀÌ Á¦ÀÏ ÁÁ´Ù. ±×·¯¸é ÀÚ¿øÀ» ¿Å°Üµµ + ¿À·¡µÈ ºÏ¸¶Å©³ª ¸µÅ©°¡ °è¼Ó À¯È¿ÇÏ´Ù.

    + +

    "File Not Found" ¿À·ùÀÇ ´Ù¸¥ ÀϹÝÀûÀÎ ¿øÀÎÀº ºê¶ó¿ìÀú¿¡ + Á÷Á¢ ȤÀº HTML ¸µÅ©¿¡ URLÀÌ À߸ø ÀÔ·ÂµÈ °æ¿ìÀÌ´Ù. ¾ÆÆÄÄ¡´Â + mod_speling (¸ÂÃã¹ýÀÌ Æ²¸®Áö ¾Ê¾ÒÀ½) ¸ðµâ·Î + ÀÌ¿Í °°Àº ¹®Á¦¸¦ µ½´Â´Ù. ÀÌ ¸ðµâÀ» »ç¿ëÇϸé "File Not Found" + ¿À·ù°¡ ¹ß»ýÇÏ´Â °æ¿ì ºñ½ÁÇÑ ÆÄÀϸíÀ» °¡Áø ÀÚ¿øÀ» ã´Â´Ù. + ¸¸¾à ¹ß°ßÇϸé mod_spelingÀº Ŭ¶óÀ̾ðÆ®¸¦ ¿Ã¹Ù¸¥ À§Ä¡·Î + HTTP ¸®´ÙÀÌ·º¼ÇÇÑ´Ù. "ºñ½ÁÇÑ" ÆÄÀÏÀÌ ¿©·¯°³ ÀÖ´Ù¸é + Ŭ¶óÀ̾ðÆ®¿¡°Ô ¸ñ·ÏÀ» º¸³½´Ù.

    + +

    mod_spelingÀÇ Æ¯È÷ À¯¿ëÇÑ ÀåÁ¡Àº ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÏÁö¾Ê°í + ÆÄÀϸíÀ» ºñ±³ÇÏ´Â ±â´ÉÀÌ´Ù. ±×·¡¼­ À¯´Ð½º ÆÄÀϽýºÅÛ°ú URLÀÇ + ´ë¼Ò¹®ÀÚ ¼ºÁúÀ» ¾ËÁö¸øÇÏ´Â »ç¿ëÀÚ°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡ µµ¿òÀÌ + µÈ´Ù. ±×·¯³ª mod_spelingÀÌ ÀÚÁÖ URLÀ» °íÃľßÇÑ´Ù¸é, "À߸øµÈ" + ¿äû¶§¸¶´Ù URL ¸®´ÙÀÌ·º¼Ç°ú Ŭ¶óÀ̾ðÆ®ÀÇ »õ·Î¿î ¿äûÀÌ + ÀϾ¹Ç·Î ¼­¹ö¿¡ ºÎ´ãÀÌ µÈ´Ù.

    + +

    ã´Â ½Ãµµ°¡ ¸ðµÎ ½ÇÆÐÇÏ¸é ¾ÆÆÄÄ¡´Â HTTP status code 404 + (file not found) ¿À·ùÆäÀÌÁö¸¦ º¸³½´Ù. ÀÌ ÆäÀÌÁöÀÇ ³»¿ëÀº + ErrorDocument Áö½Ã¾î·Î + Á¶ÀýÇϸç, »ç¿ëÀÚÁ¤ÀÇ ¿À·ù ÀÀ´ä + ¹®¼­¸¦ Âü°íÇÏ¿© »ç¿ëÀÚÁ¤ÀÇÇÒ ¼ö ÀÖ´Ù.

    +
    + +
    diff --git a/trunk/docs/manual/urlmapping.xml.meta b/trunk/docs/manual/urlmapping.xml.meta new file mode 100644 index 0000000000..9130173382 --- /dev/null +++ b/trunk/docs/manual/urlmapping.xml.meta @@ -0,0 +1,13 @@ + + + + urlmapping + / + . + + + en + ja + ko + + diff --git a/trunk/docs/manual/vhosts/details.html b/trunk/docs/manual/vhosts/details.html new file mode 100644 index 0000000000..caead8e1a2 --- /dev/null +++ b/trunk/docs/manual/vhosts/details.html @@ -0,0 +1,7 @@ +URI: details.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: details.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/details.html.en b/trunk/docs/manual/vhosts/details.html.en new file mode 100644 index 0000000000..b091922d42 --- /dev/null +++ b/trunk/docs/manual/vhosts/details.html.en @@ -0,0 +1,439 @@ + + + +An In-Depth Discussion of Virtual Host Matching - Apache HTTP Server + + + + + +
    <-
    +

    An In-Depth Discussion of Virtual Host Matching

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    The virtual host code was completely rewritten in + Apache 1.3. This document attempts to explain + exactly what Apache does when deciding what virtual host to + serve a hit from. With the help of the new + NameVirtualHost + directive virtual host configuration should be a lot easier and + safer than with versions prior to 1.3.

    + +

    If you just want to make it work without + understanding how, here are some + examples.

    + +
    + +
    top
    +
    +

    Config File Parsing

    + +

    There is a main_server which consists of all the + definitions appearing outside of + <VirtualHost> sections. There are virtual + servers, called vhosts, which are defined by + <VirtualHost> + sections.

    + +

    The directives + Listen, + ServerName, + ServerPath, + and ServerAlias + can appear anywhere within the definition of a server. However, + each appearance overrides the previous appearance (within that + server).

    + +

    The default value of the Listen field for + main_server is 80. The main_server has no default + ServerPath, or ServerAlias. The + default ServerName is deduced from the server's IP + address.

    + +

    The main_server Listen directive has two functions. One + function is to determine the default network port Apache will + bind to. The second function is to specify the port number + which is used in absolute URIs during redirects.

    + +

    Unlike the main_server, vhost ports do not affect + what ports Apache listens for connections on.

    + +

    Each address appearing in the VirtualHost + directive can have an optional port. If the port is unspecified + it defaults to the value of the main_server's most recent + Listen statement. The special port * + indicates a wildcard that matches any port. Collectively the + entire set of addresses (including multiple A + record results from DNS lookups) are called the vhost's + address set.

    + +

    Unless a NameVirtualHost + directive is used for a specific IP address the first vhost + with that address is treated as an IP-based vhost. The IP + address can also be the wildcard *.

    + +

    If name-based vhosts should be used a + NameVirtualHost directive must appear + with the IP address set to be used for the name-based vhosts. + In other words, you must specify the IP address that holds the + hostname aliases (CNAMEs) for your name-based vhosts via a + NameVirtualHost directive in your configuration + file.

    + +

    Multiple NameVirtualHost directives can be used + each with a set of VirtualHost directives but only + one NameVirtualHost directive should be used for + each specific IP:port pair.

    + +

    The ordering of NameVirtualHost and + VirtualHost directives is not important which + makes the following two examples identical (only the order of + the VirtualHost directives for one + address set is important, see below):

    + + + + +

    + NameVirtualHost 111.22.33.44
    + <VirtualHost 111.22.33.44>
    + # server A
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # server B
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.55
    + <VirtualHost 111.22.33.55>
    + # server C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server D
    + ...
    + </VirtualHost> +

    + <VirtualHost 111.22.33.44>
    + # server A
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # server B
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server D
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.44
    + NameVirtualHost 111.22.33.55
    +
    +

    + + +

    (To aid the readability of your configuration you should + prefer the left variant.)

    + +

    After parsing the VirtualHost directive, the + vhost server is given a default Listen equal to the + port assigned to the first name in its VirtualHost + directive.

    + +

    The complete list of names in the VirtualHost + directive are treated just like a ServerAlias (but + are not overridden by any ServerAlias statement) + if all names resolve to the same address set. Note that + subsequent Listen statements for this vhost will not + affect the ports assigned in the address set.

    + +

    During initialization a list for each IP address is + generated and inserted into an hash table. If the IP address is + used in a NameVirtualHost directive the list + contains all name-based vhosts for the given IP address. If + there are no vhosts defined for that address the + NameVirtualHost directive is ignored and an error + is logged. For an IP-based vhost the list in the hash table is + empty.

    + +

    Due to a fast hashing function the overhead of hashing an IP + address during a request is minimal and almost not existent. + Additionally the table is optimized for IP addresses which vary + in the last octet.

    + +

    For every vhost various default values are set. In + particular:

    + +
      +
    1. If a vhost has no ServerAdmin, + ResourceConfig, + AccessConfig, + Timeout, + KeepAliveTimeout, + KeepAlive, + MaxKeepAliveRequests, + or SendBufferSize + directive then the respective value is inherited from the + main_server. (That is, inherited from whatever the final + setting of that value is in the main_server.)
    2. + +
    3. The "lookup defaults" that define the default directory + permissions for a vhost are merged with those of the + main_server. This includes any per-directory configuration + information for any module.
    4. + +
    5. The per-server configs for each module from the + main_server are merged into the vhost server.
    6. +
    + +

    Essentially, the main_server is treated as "defaults" or a + "base" on which to build each vhost. But the positioning of + these main_server definitions in the config file is largely + irrelevant -- the entire config of the main_server has been + parsed when this final merging occurs. So even if a main_server + definition appears after a vhost definition it might affect the + vhost definition.

    + +

    If the main_server has no ServerName at this + point, then the hostname of the machine that httpd + is running on is used instead. We will call the main_server address + set those IP addresses returned by a DNS lookup on the + ServerName of the main_server.

    + +

    For any undefined ServerName fields, a + name-based vhost defaults to the address given first in the + VirtualHost statement defining the vhost.

    + +

    Any vhost that includes the magic _default_ + wildcard is given the same ServerName as the + main_server.

    + +
    top
    +
    +

    Virtual Host Matching

    + +

    The server determines which vhost to use for a request as + follows:

    + +

    Hash table lookup

    + +

    When the connection is first made by a client, the IP + address to which the client connected is looked up in the + internal IP hash table.

    + +

    If the lookup fails (the IP address wasn't found) the + request is served from the _default_ vhost if + there is such a vhost for the port to which the client sent the + request. If there is no matching _default_ vhost + the request is served from the main_server.

    + +

    If the IP address is not found in the hash table then the + match against the port number may also result in an entry + corresponding to a NameVirtualHost *, which is + subsequently handled like other name-based vhosts.

    + +

    If the lookup succeeded (a corresponding list for the IP + address was found) the next step is to decide if we have to + deal with an IP-based or a name-base vhost.

    + + + +

    IP-based vhost

    + +

    If the entry we found has an empty name list then we have + found an IP-based vhost, no further actions are performed and + the request is served from that vhost.

    + + + +

    Name-based vhost

    + +

    If the entry corresponds to a name-based vhost the name list + contains one or more vhost structures. This list contains the + vhosts in the same order as the VirtualHost + directives appear in the config file.

    + +

    The first vhost on this list (the first vhost in the config + file with the specified IP address) has the highest priority + and catches any request to an unknown server name or a request + without a Host: header field.

    + +

    If the client provided a Host: header field the + list is searched for a matching vhost and the first hit on a + ServerName or ServerAlias is taken + and the request is served from that vhost. A Host: + header field can contain a port number, but Apache always + matches against the real port to which the client sent the + request.

    + +

    If the client submitted a HTTP/1.0 request without + Host: header field we don't know to what server + the client tried to connect and any existing + ServerPath is matched against the URI from the + request. The first matching path on the list is used and the + request is served from that vhost.

    + +

    If no matching vhost could be found the request is served + from the first vhost with a matching port number that is on the + list for the IP to which the client connected (as already + mentioned before).

    + + + +

    Persistent connections

    + +

    The IP lookup described above is only done once for a + particular TCP/IP session while the name lookup is done on + every request during a KeepAlive/persistent + connection. In other words a client may request pages from + different name-based vhosts during a single persistent + connection.

    + + + +

    Absolute URI

    + +

    If the URI from the request is an absolute URI, and its + hostname and port match the main server or one of the + configured virtual hosts and match the address and + port to which the client sent the request, then the + scheme/hostname/port prefix is stripped off and the remaining + relative URI is served by the corresponding main server or + virtual host. If it does not match, then the URI remains + untouched and the request is taken to be a proxy request.

    + + +

    Observations

    + +
      +
    • A name-based vhost can never interfere with an IP-base + vhost and vice versa. IP-based vhosts can only be reached + through an IP address of its own address set and never + through any other address. The same applies to name-based + vhosts, they can only be reached through an IP address of the + corresponding address set which must be defined with a + NameVirtualHost directive.
    • + +
    • ServerAlias and ServerPath + checks are never performed for an IP-based vhost.
    • + +
    • The order of name-/IP-based, the _default_ + vhost and the NameVirtualHost directive within + the config file is not important. Only the ordering of + name-based vhosts for a specific address set is significant. + The one name-based vhosts that comes first in the + configuration file has the highest priority for its + corresponding address set.
    • + +
    • For security reasons the port number given in a + Host: header field is never used during the + matching process. Apache always uses the real port to which + the client sent the request.
    • + +
    • If a ServerPath directive exists which is a + prefix of another ServerPath directive that + appears later in the configuration file, then the former will + always be matched and the latter will never be matched. (That + is assuming that no Host: header field was + available to disambiguate the two.)
    • + +
    • If two IP-based vhosts have an address in common, the + vhost appearing first in the config file is always matched. + Such a thing might happen inadvertently. The server will give + a warning in the error logfile when it detects this.
    • + +
    • A _default_ vhost catches a request only if + there is no other vhost with a matching IP address + and a matching port number for the request. The + request is only caught if the port number to which the client + sent the request matches the port number of your + _default_ vhost which is your standard + Listen by default. A wildcard port can be + specified (i.e., _default_:*) to catch + requests to any available port. This also applies to + NameVirtualHost * vhosts.
    • + +
    • The main_server is only used to serve a request if the IP + address and port number to which the client connected is + unspecified and does not match any other vhost (including a + _default_ vhost). In other words the main_server + only catches a request for an unspecified address/port + combination (unless there is a _default_ vhost + which matches that port).
    • + +
    • A _default_ vhost or the main_server is + never matched for a request with an unknown or + missing Host: header field if the client + connected to an address (and port) which is used for + name-based vhosts, e.g., in a + NameVirtualHost directive.
    • + +
    • You should never specify DNS names in + VirtualHost directives because it will force + your server to rely on DNS to boot. Furthermore it poses a + security threat if you do not control the DNS for all the + domains listed. There's more + information available on this and the next two + topics.
    • + +
    • ServerName should always be set for each + vhost. Otherwise A DNS lookup is required for each + vhost.
    • +
    + + +
    top
    +
    +

    Tips

    + +

    In addition to the tips on the DNS Issues page, here are + some further tips:

    + +
      +
    • Place all main_server definitions before any + VirtualHost definitions. (This is to aid the + readability of the configuration -- the post-config merging + process makes it non-obvious that definitions mixed in around + virtual hosts might affect all virtual hosts.)
    • + +
    • Group corresponding NameVirtualHost and + VirtualHost definitions in your configuration to + ensure better readability.
    • + +
    • Avoid ServerPaths which are prefixes of + other ServerPaths. If you cannot avoid this then + you have to ensure that the longer (more specific) prefix + vhost appears earlier in the configuration file than the + shorter (less specific) prefix (i.e., "ServerPath + /abc" should appear after "ServerPath /abc/def").
    • +
    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/details.html.ko.euc-kr b/trunk/docs/manual/vhosts/details.html.ko.euc-kr new file mode 100644 index 0000000000..330fb133ed --- /dev/null +++ b/trunk/docs/manual/vhosts/details.html.ko.euc-kr @@ -0,0 +1,382 @@ + + + +°¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í - Apache HTTP Server + + + + + +
    <-
    +

    °¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    °¡»óÈ£½ºÆ® ÄÚµå´Â ¾ÆÆÄÄ¡ 1.3¿¡¼­ °ÅÀÇ ´Ù½Ã + ÀÛ¼ºµÇ¾ú´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡°¡ ¿äûÀ» ¹ÞÀ¸¸é ¾î¶² °¡»óÈ£½ºÆ®°¡ + ¼­ºñ½ºÇÒÁö °áÁ¤ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. »õ·Î¿î NameVirtualHost Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + °¡»óÈ£½ºÆ® ¼³Á¤ÀÌ 1.3 ¹öÀü ÀÌÀüº¸´Ù ´õ ½±°í ¾ÈÀüÇØÁ³´Ù.

    + +

    ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö ÀÌÇØÇÏÁö¾Ê°í ´ÜÁö µ¿ÀÛÇÏ°Ô¸¸ + ÇÏ°í ½Í´Ù¸é, ¿¹Á¦µéÀ» Âü°íÇ϶ó.

    + +
    + +
    top
    +
    +

    ¼³Á¤ÆÄÀÏ Àбâ

    + +

    <VirtualHost> ¼³Á¤À» Á¦¿ÜÇÑ ¼³Á¤ÀÌ + ÁÖ¼­¹ö¸¦ ¸¸µç´Ù. <VirtualHost> ¼½¼ÇÀ¸·Î Á¤ÀÇÇÑ + ºÎºÐÀ» °¡»óÈ£½ºÆ®¶ó°í ºÎ¸¥´Ù.

    + +

    Listen, + ServerName, + ServerPath, + ServerAlias Áö½Ã¾î´Â + ¼­¹ö Á¤ÀÇ ¾î´À°÷¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª °°Àº Áö½Ã¾î°¡ + ¿©·¯¹ø ³ª¿À¸é (±× ¼­¹ö¿¡¼­) ¸¶Áö¸· Áö½Ã¾î¸¸ÀÌ À¯È¿ÇÏ´Ù.

    + +

    ÁÖ¼­¹ö ListenÀÇ ±âº»°ªÀº 80ÀÌ´Ù. ÁÖ¼­¹öÀÇ + ServerPath³ª ServerAlias¿¡´Â + ±âº»°ªÀº ¾ø´Ù. ServerNameÀÇ ±âº»°ªÀº ¼­¹öÀÇ + IP ÁÖ¼ÒÀÌ´Ù.

    + +

    ÁÖ¼­¹öÀÇ Listen Áö½Ã¾î´Â µÎ°¡Áö ±â´ÉÀ» ÇÑ´Ù. ù°´Â + ¾ÆÆÄÄ¡°¡ ¿¬°áÇÒ ±âº» ³×Æ®¿÷ Æ÷Æ®¸¦ ÁöÁ¤ÇÏ´Â ÀÏÀÌ´Ù. µÑ°´Â + ¸®´ÙÀÌ·º¼ÇÇÒ Àý´ë URI¿¡ »ç¿ëÇÒ Æ÷Æ® ¹øÈ£¸¦ ÁöÁ¤ÇÏ´Â ÀÏÀÌ´Ù.

    + +

    ÁÖ¼­¹ö¿Í ´Þ¸® °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ®´Â ¾ÆÆÄÄ¡°¡ ¿¬°áÀ» ±â´Ù¸®´Â + Æ÷Æ®¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù.

    + +

    VirtualHost Áö½Ã¾î¿¡ Æ÷Æ®¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. + Æ÷Æ®¸¦ ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é ÁÖ¼­¹öÀÇ °¡Àå ÃÖ±Ù Listen + °ªÀ» »ç¿ëÇÑ´Ù. Ưº°ÇÑ Æ÷Æ® *´Â ¾î¶² Æ÷Æ®¶óµµ + ÁöĪÇÏ´Â ¿ÍÀϵåÄ«µåÀÌ´Ù. (DNS °Ë»ö °á°úÀÇ ¿©·¯ A + ·¹Äڵ带 Æ÷ÇÔÇÏ¿©) °¡»óÈ£½ºÆ®ÀÇ ÁÖ¼Ò¸¦ ¸ðµÎ ÃÑĪÇÏ¿© °¡»óÈ£½ºÆ®ÀÇ + ÁÖ¼ÒÁýÇÕ(address set)À̶ó°í ºÎ¸¥´Ù.

    + +

    ƯÁ¤ IP ÁÖ¼Ò¿¡ ´ëÇÑ NameVirtualHost Áö½Ã¾î°¡ ¾ø´Ù¸é + ±× ÁÖ¼Ò¸¦ Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®¸¦ IP±â¹Ý °¡»óÈ£½ºÆ®·Î Ãë±ÞÇÑ´Ù. + IP ÁÖ¼Ò¿¡ ¿ÍÀϵåÄ«µå *¸¦ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù¸é À̸§±â¹Ý °¡»óÈ£½ºÆ®¿¡ + »ç¿ëÇÒ IP ÁÖ¼Ò¸¦ NameVirtualHost Áö½Ã¾î¿¡ + »ç¿ëÇØ¾ß ÇÑ´Ù. Áï, ¼³Á¤ÆÄÀÏÀÇ NameVirtualHost + Áö½Ã¾î¿¡ À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ È£½ºÆ®º°¸í(CNAME)¿¡ ÇØ´çÇÏ´Â + IP ÁÖ¼Ò¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ƯÁ¤ IP:Æ÷Æ® ½Ö¿¡ ´ëÇØ ¿ÀÁ÷ ÇÑ NameVirtualHost + Áö½Ã¾î¸¸À» »ç¿ëÇÑ´Ù¸é, ¿©·¯ NameVirtualHost Áö½Ã¾î¿Í + VirtualHost Áö½Ã¾î¸¦ ¼¯¾î¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    NameVirtualHost¿Í VirtualHost + Áö½Ã¾îÀÇ ¼ø¼­´Â Áß¿äÇÏÁö ¾Ê±â¶§¹®¿¡ ´ÙÀ½ µÎ ¿¹´Â °°´Ù (¿ÀÁ÷ + ÇÑ ÁÖ¼ÒÁýÇÕ¿¡ ´ëÇÑ VirtualHostÀÇ + ¼ø¼­°¡ Áß¿äÇÏ´Ù. ¾Æ·¡ Âü°í):

    + + + + +

    + NameVirtualHost 111.22.33.44
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö A
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö B
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.55
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö D
    + ...
    + </VirtualHost> +

    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö A
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö B
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö D
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.44
    + NameVirtualHost 111.22.33.55
    +
    +

    + + +

    (¿ÞÂÊ ¼³Á¤ÀÌ ´õ Àбâ ÆíÇÏ´Ù.)

    + +

    VirtualHost Áö½Ã¾î¸¦ ÀÐÀ» ´ÙÀ½, °¡»óÈ£½ºÆ® + ¼­¹ö´Â VirtualHost Áö½Ã¾î¿¡ ÁöÁ¤ÇÑ Æ÷Æ®¸¦ ±âº» + ListenÀ¸·Î ÇÑ´Ù.

    + +

    VirtualHost Áö½Ã¾îÀÇ À̸§ÀÌ ¸ðµÎ °°Àº + ÁÖ¼ÒÁýÇÕ¿¡ ¼ÓÇÑ´Ù¸é ServerAlias¿Í °°ÀÌ Ãë±ÞÇÑ´Ù + (±×·¯³ª ´Ù¸¥ ServerAliasÀÇ ¿µÇâÀ» ¹ÞÁö ¾Ê´Â´Ù). + °¡»óÈ£½ºÆ®¿¡ Ãß°¡·Î »ç¿ëÇÑ ListenÀº ÁÖ¼ÒÁýÇÕÀÌ + ÁöÁ¤ÇÑ Æ÷Æ®¿¡ ¿µÇâÀ» ÁÖÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó.

    + +

    ½ÃÀÛÇÒ¶§ IP ÁÖ¼Ò ¸ñ·ÏÀ» ¸¸µé¾î Çؽ¬Å×ÀÌºí¿¡ Ãß°¡ÇÑ´Ù. + NameVirtualHost Áö½Ã¾î¿¡ IP ÁÖ¼Ò¸¦ »ç¿ëÇϸé + ¸ñ·ÏÀº ±× IP ÁÖ¼Ò¿¡ ´ëÇÑ ¸ðµç À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÑ´Ù. + ±× ÁÖ¼Ò¿¡ ´ëÇÑ °¡»óÈ£½ºÆ®°¡ ¾ø´Ù¸é NameVirtualHost + Áö½Ã¾î¸¦ ¹«½ÃÇÏ°í ·Î±×¿¡ ¿À·ù¸¦ ±â·ÏÇÑ´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®´Â + Çؽ¬Å×ÀÌºí¿¡ ¸ñ·ÏÀ» Ãß°¡ÇÏÁö ¾Ê´Â´Ù.

    + +

    ºü¸¥ Çؽ¬ÇÔ¼ö¸¦ »ç¿ëÇϱ⶧¹®¿¡ ¿äû½Ã IP ÁÖ¼Ò¸¦ ÇؽÌÇÏ´Â + ºÎ´ãÀº °ÅÀÇ ¾ø´Ù. ¶Ç Çؽ¬Å×À̺íÀº IP ÁÖ¼ÒÀÇ ¸¶Áö¸· ºÎºÐÀÇ + Â÷ÀÌ¿¡ ÃÖÀûÈ­µÇÀÖ´Ù.

    + +

    °¡»óÈ£½ºÆ®¿¡ ¿©·¯ ±âº»°ªÀÌ ¼³Á¤µÈ´Ù. ƯÈ÷:

    + +
      +
    1. °¡»óÈ£½ºÆ®¿¡ ServerAdmin, + ResourceConfig, + AccessConfig, + Timeout, + KeepAliveTimeout, + KeepAlive, + MaxKeepAliveRequests, + SendBufferSize + Áö½Ã¾î°¡ ¾ø´Ù¸é ÁÖ¼­¹ö¿¡¼­ ÇØ´ç °ªÀ» °¡Á®¿Â´Ù. (Áï, + ÁÖ¼­¹öÀÇ ¼³Á¤°ªÀ» »ç¿ëÇÑ´Ù.)
    2. + +
    3. °¡»óÈ£½ºÆ®ÀÇ µð·ºÅ丮 ±âº»±ÇÇÑÀ» Á¤ÀÇÇÏ´Â "ÂüÁ¶ + ±âº»°ª(lookup defaults)"Àº ÁÖ¼­¹öÀÇ ¼³Á¤°ú ÇÕÃÄÁø´Ù. + ¸ðµâÀÇ µð·ºÅ丮´ç ¼³Á¤(per-directory configuration)µµ + ¿©±â¿¡ ÇØ´çµÈ´Ù.
    4. + +
    5. °¢ ¸ðµâÀÇ ¼­¹ö´ç ¼³Á¤(per-server config)Àº ÁÖ¼­¹öÀÇ + ¼³Á¤°ú °¡»óÈ£½ºÆ®ÀÇ ¼³Á¤À» ÇÕÄ£´Ù.
    6. +
    + +

    ±âº»ÀûÀ¸·Î ÁÖ¼­¹ö´Â °¡»óÈ£½ºÆ®¸¦ ¸¸µå´Â "±âº»" ȤÀº "±â¹Ý"ÀÌ + µÈ´Ù. ±×·¯³ª ¼³Á¤ÆÄÀÏ¿¡¼­ ÁÖ¼­¹ö¸¦ Á¤ÀÇÇÏ´Â À§Ä¡´Â °ü°è¾ø´Ù. + ¸¶Áö¸·À¸·Î ¼³Á¤À» ÇÕÄ¡±â Àü¿¡ ÁÖ¼­¹öÀÇ ¸ðµç ¼³Á¤À» ÀоîµéÀδÙ. + ±×·¡¼­ ÁÖ¼­¹ö Á¤ÀÇ°¡ °¡»óÈ£½ºÆ® Á¤ÀÇ µÚ¿¡ ³ª¿Íµµ °¡»óÈ£½ºÆ® + Á¤ÀÇ¿¡ ¿µÇâÀ» ÁØ´Ù.

    + +

    ÁÖ¼­¹ö¿¡ ServerNameÀÌ ¾ø´Ù¸é À¥¼­¹ö¸¦ ½ÇÇàÇÏ´Â + ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸íÀ» ´ë½Å »ç¿ëÇÑ´Ù. ÁÖ¼­¹öÀÇ + ServerNameÀ» DNS °Ì»öÇÏ¿© ¾òÀº IP ÁÖ¼ÒµéÀ» + ÁÖ¼­¹ö ÁÖ¼ÒÁýÇÕÀ̶ó°í ºÎ¸¥´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ ServerNameÀ» Á¤ÀÇÇÏÁö + ¾ÊÀ¸¸é °¡»óÈ£½ºÆ®¸¦ Á¤ÀÇÇÏ´Â VirtualHost¿¡¼­ + óÀ½À¸·Î ³ª¿Â ÁÖ¼Ò¸¦ ±âº»°ªÀ¸·Î »ç¿ëÇÑ´Ù.

    + +

    Ưº°ÇÑ _default_ ¿ÍÀÏƮīµå¸¦ Æ÷ÇÔÇÏ´Â + °¡»óÈ£½ºÆ®´Â ÁÖ¼­¹ö¿Í °°Àº ServerNameÀ» °¡Áø´Ù.

    + +
    top
    +
    +

    °¡»óÈ£½ºÆ® ã±â

    + +

    ¼­¹ö´Â ¾Æ·¡¿Í °°Àº ¹æ¹ýÀ¸·Î ¾î¶² °¡»óÈ£½ºÆ®°¡ ¿äûÀ» + ó¸®ÇÒÁö °áÁ¤ÇÑ´Ù:

    + +

    Çؽ¬Å×À̺í ã±â

    + +

    Ŭ¶óÀ̾ðÆ®°¡ óÀ½ ¿¬°áÇÏ¸é ¿¬°áÇÑ IP ÁÖ¼Ò¸¦ ³»ºÎ IP + Çؽ¬Å×ÀÌºí¿¡¼­ ã´Â´Ù.

    + +

    IP ÁÖ¼Ò¸¦ ãÀ» ¼ö ¾ø°í Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ Æ÷Æ®¿¡ + ÇØ´çÇÏ´Â °¡»óÈ£½ºÆ®°¡ ÀÖ´Ù¸é, _default_ °¡»óÈ£½ºÆ®°¡ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. _default_ °¡»óÈ£½ºÆ®°¡ + ¾ø´Ù¸é ÁÖ¼­¹ö°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + +

    Çؽ¬Å×ÀÌºí¿¡ IP ÁÖ¼Ò°¡ ¾øÁö¸¸ Æ÷Æ® ¹øÈ£°¡ + NameVirtualHost *¿¡ ÇØ´çÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì + À̸§±â¹Ý °¡»óÈ£½ºÆ®Ã³·³ ó¸®ÇÑ´Ù.

    + +

    ã¾Ò´Ù¸é (¸ñ·Ï¿¡¼­ IP ÁÖ¼Ò¿¡ ÇØ´çÇÏ´Â Ç׸ñÀ» ãÀ¸¸é), + IP±â¹Ý °¡»óÈ£½ºÆ®ÀÎÁö À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÎÁö °áÁ¤ÇÑ´Ù.

    + + + +

    IP±â¹Ý °¡»óÈ£½ºÆ®

    + +

    ãÀº Ç׸ñ¿¡ À̸§ ¸ñ·ÏÀÌ ¾ø´Ù¸é IP±â¹Ý °¡»óÈ£½ºÆ®ÀÌ´Ù. + ´õ ÀÌ»ó ÀÛ¾÷ÀÌ ÇÊ¿ä¾ø°í, ±× °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ó¸®ÇÑ´Ù.

    + + + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®

    + +

    À̸§ ¸ñ·Ï¿¡ ÇÑ°³ ÀÌ»óÀÇ °¡»óÈ£½ºÆ® ±¸Á¶°¡ Æ÷ÇԵǸé + À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÌ´Ù. ÀÌ ¸ñ·Ï¿¡¼­ °¡»óÈ£½ºÆ®µéÀº ¼³Á¤ÆÄÀÏÀÇ + VirtualHost ¼ø¼­´ë·Î À§Ä¡ÇÑ´Ù.

    + +

    ¸ñ·Ï¿¡¼­ ù¹ø° °¡»óÈ£½ºÆ®(¼³Á¤ÆÄÀÏ¿¡¼­ ÇØ´ç IP ÁÖ¼Ò¸¦ + Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®)´Â °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç, + ¼­¹ö¸íÀ» ¾Ë ¼ö ¾ø°Å³ª Host: Çì´õ°¡ ¾ø´Â ¿äûÀ» + ó¸®ÇÑ´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ Host: Çì´õ¸¦ ÁÖ¸é, ¸ñ·Ï¿¡¼­ + ù¹ø°·Î ServerNameÀ̳ª + ServerAlias°¡ ´ëÀÀÇÏ´Â °¡»óÈ£½ºÆ®°¡ ¿äûÀ» + ¼­ºñ½ºÇÑ´Ù. Host: Çì´õ¿¡ Æ÷Æ® ¹øÈ£°¡ ³ª¿Ã ¼ö + ÀÖÁö¸¸, ¾ÆÆÄÄ¡´Â Ç×»ó Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ ½ÇÁ¦ Æ÷Æ®¸¦ + ã´Â´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ Host: Çì´õ¾øÀÌ HTTP/1.0 ¿äûÀ» + Çϸé Ŭ¶óÀ̾ðÆ®°¡ ¾î¶² ¼­¹ö¿¡ ¿¬°áÇÏ·Á´ÂÁö ¾Ë ¼ö ¾ø±â¶§¹®¿¡ + ¿äûÀÇ URI¿¡ ÇØ´çÇÏ´Â ServerPath°¡ ÀÖ´ÂÁö ã´Â´Ù. + ¸ñ·Ï¿¡¼­ Á¦ÀÏ ¸ÕÀú ãÀº °æ·Î¸¦ »ç¿ëÇÏ°í, ±× °¡»óÈ£½ºÆ®°¡ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + +

    ´ëÀÀÇÏ´Â °¡»óÈ£½ºÆ®¸¦ ãÀ» ¼ö ¾ø´Ù¸é, (ÀÌ¹Ì ¾Õ¿¡ ¸»ÇßµíÀÌ) + Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÇÑ IP¿¡ ´ëÇÑ ¸ñ·Ï¿¡¼­ ÀÏÄ¡ÇÏ´Â Æ÷Æ® ¹øÈ£¸¦ + Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + + + +

    Áö¼Ó ¿¬°á

    + +

    IP´Â À§¿¡¼­ ¼³¸íÇѵ¥·Î ƯÁ¤ TCP/IP ¼¼¼Ç´ç Çѹø¸¸ + ãÁö¸¸, À̸§Àº KeepAlive/Áö¼Ó ¿¬°áµ¿¾È ¸Å ¿äû¶§¸¶´Ù + ã´Â´Ù. Áï, Ŭ¶óÀ̾ðÆ®´Â Áö¼Ó ¿¬°áµ¿¾È ¿©·¯ À̸§±â¹Ý + °¡»óÈ£½ºÆ®ÀÇ ÆäÀÌÁö¸¦ ¿äûÇÒ ¼ö ÀÖ´Ù.

    + + + +

    Àý´ë URI

    + +

    ¿äûÀÇ URI°¡ Àý´ë URIÀÌ°í Ŭ¶óÀ̾ðÆ®°¡ º¸³½ ¿äûÀÇ + È£½ºÆ®¸í°ú Æ÷Æ®°¡ ÁÖ¼­¹ö³ª ƯÁ¤ °¡»óÈ£½ºÆ®¿¡ ÇØ´çÇϸé, + ±× ÁÖ¼­¹ö ȤÀº °¡»óÈ£½ºÆ®´Â URI ¾ÕÀÇ ½ºÅ´/È£½ºÆ®¸í/Æ÷Æ® + ºÎºÐÀ» Á¦¿ÜÇÑ ³ª¸ÓÁö »ó´ë URI¸¦ ¼­ºñ½ºÇÑ´Ù. ÇØ´çÇÏ´Â + ÁÖ¼­¹ö³ª °¡»óÈ£½ºÆ®°¡ ¾ø´Ù¸é URI¸¦ ±×´ë·Î µÎ°í ¿äûÀ» + ÇÁ·Ï½Ã ¿äûÀ¸·Î ó¸®ÇÑ´Ù.

    + + +

    ÁÖÀÇ

    + +
      +
    • À̸§±â¹Ý °¡»óÈ£½ºÆ®¿Í IP±â¹Ý °¡»óÈ£½ºÆ®´Â ¼­·Î¿¡°Ô + ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÀÚ½ÅÀÇ À̸§ÁýÇÕ + IP ÁÖ¼Ò¿Ü¿¡ ¾î¶² Áּҷεµ Á¢±ÙÇÒ ¼ö ¾ø´Ù. À̸§±â¹Ý + °¡»óÈ£½ºÆ®µµ ¸¶Âù°¡Áö´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â + NameVirtualHost Áö½Ã¾î·Î Á¤ÀÇÇÑ ÁÖ¼ÒÁýÇÕÀÇ + IP ÁÖ¼Ò¸¦ ÅëÇؼ­¸¸ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.
    • + +
    • IP±â¹Ý °¡»óÈ£½ºÆ®´Â ServerAlias¿Í + ServerPath¸¦ Àý´ë·Î °Ë»çÇÏÁö ¾Ê´Â´Ù.
    • + +
    • ¼³Á¤ÆÄÀÏ¿¡¼­ À̸§±â¹Ý °¡»óÈ£½ºÆ®, IP±â¹Ý °¡»óÈ£½ºÆ®, + _default_ °¡»óÈ£½ºÆ®, NameVirtualHost + Áö½Ã¾îÀÇ ¼ø¼­´Â Áß¿äÇÏÁö ¾Ê´Ù. ƯÁ¤ ÁÖ¼ÒÁýÇÕ¿¡ ´ëÇÑ + À̸§±â¹Ý °¡»óÈ£½ºÆ®µéÀÇ ¼ø¼­¸¸ÀÌ Áß¿äÇÏ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ + ¾Õ¿¡ ³ª¿À´Â À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â ÀÚ½ÅÀÌ ¼ÓÇÑ ÁÖ¼ÒÁýÇÕ¿¡¼­ + °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áø´Ù.
    • + +
    • º¸¾ÈÀ» À§ÇØ Host: Çì´õ¿¡ Æ÷ÇÔµÈ Æ÷Æ® + ¹øÈ£´Â Àý´ë·Î »ç¿ëÇÏÁö ¾Ê´Â´Ù. ¾ÆÆÄÄ¡´Â Ç×»ó Ŭ¶óÀ̾ðÆ®°¡ + ¿äûÀ» º¸³½ ½ÇÁ¦ Æ÷Æ®¸¦ »ç¿ëÇÑ´Ù.
    • + +
    • (µÑ »çÀ̸¦ ±¸º°ÇÒ Host: Çì´õ°¡ ¾ø´Ù°í + °¡Á¤Çϸé,) ServerPath Áö½Ã¾î°¡ ¼³Á¤ÆÄÀÏ¿¡¼­ + µÚ¿¡ ³ª¿À´Â ´Ù¸¥ ServerPath Áö½Ã¾îÀÇ ¾ÕºÎºÐÀ» + ÁöĪÇÏ´Â °æ¿ì Ç×»ó ¾Õ¿¡ ³ª¿Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù.
    • + +
    • µÎ IP±â¹Ý °¡»óÈ£½ºÆ®°¡ °°Àº ÁÖ¼Ò¸¦ °¡Áö¸é, Ç×»ó + ¼³Á¤ÆÄÀÏ¿¡¼­ ¾Õ¿¡ ³ª¿À´Â °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù. ÀÌ·± ÀÏÀº + ¾Æ¹«µµ ¸ð¸£°Ô ÀϾ ¼ö ÀÖ´Ù. ¼­¹ö°¡ ÀÌ·± »óȲÀ» ¹ß°ßÇϸé + ¿À·ù ·Î±×ÆÄÀÏ¿¡ °æ°í¸¦ ±â·ÏÇÑ´Ù.
    • + +
    • _default_ °¡»óÈ£½ºÆ®´Â ¿äûÀÇ IP ÁÖ¼Ò¿Í + Æ÷Æ® ¹øÈ£¿¡ ÇØ´çÇÏ´Â °¡»óÈ£½ºÆ®°¡ ¾øÀ»¶§¸¸ ¿äûÀ» ó¸®ÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ Æ÷Æ® ¹øÈ£°¡ _default_ + °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ® ¹øÈ£(±âº»°ªÀº Listen)¿Í + °°À»¶§¸¸ ¿äûÀ» ó¸®ÇÑ´Ù. ¾î¶² Æ÷Æ®ÀÇ ¿äûÀÌ¶óµµ Àâ±âÀ§ÇØ + (¿¹¸¦ µé¾î, _default_:*) ¿ÍÀϵåÄ«µå + Æ÷Æ®¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. NameVirtualHost * + °¡»óÈ£½ºÆ®µµ ¸¶Âù°¡Áö´Ù.
    • + +
    • ÁÖ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÇÑ IP ÁÖ¼Ò¿Í Æ÷Æ® ¹øÈ£¿¡ + ÇØ´çÇÏ´Â (_default_ °¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÏ¿©) + °¡»óÈ£½ºÆ®°¡ ¾øÀ»¶§¸¸ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. Áï, ÁÖ¼­¹ö´Â + (±× Æ÷Æ®¿¡ ÇØ´çÇÏ´Â _default_ °¡»óÈ£½ºÆ®°¡ + ¾ø´Ù¸é) ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò/Æ÷Æ® ½Ö¿¡ ´ëÇÑ ¿äû¸¸À» ó¸®ÇÑ´Ù.
    • + +
    • Ŭ¶óÀ̾ðÆ®°¡ (¿¹¸¦ µé¾î, NameVirtualHost + Áö½Ã¾î¿¡¼­) À̸§±â¹Ý °¡»óÈ£½ºÆ® ÁÖ¼Ò(¿Í Æ÷Æ®)¿¡ ¿¬°áÇÑ + °æ¿ì Host: Çì´õ¸¦ ¾Ë ¼ö ¾ø°Å³ª Çì´õ°¡ ¾ø´Â + ¿äûÀ» º¸³»¸é ¿äûÀº Àý´ë·Î _default_ + °¡»óÈ£½ºÆ®³ª ÁÖ¼­¹ö¿¡¼­ ó¸®ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • ½ÃÀÛÇÒ¶§ ¼­¹ö°¡ DNS¸¦ ÀÇÁ¸ÇÏÁö ¾ÊÀ¸·Á¸é Àý´ë·Î + VirtualHost Áö½Ã¾î¿¡ DNS À̸§À» »ç¿ëÇÏÁö¸¶¶ó. + °Ô´Ù°¡ ¿­°ÅÇÑ ¸ðµç µµ¸ÞÀÎÀÇ DNS¸¦ ÅëÁ¦ÇÏÁö ¾Ê´Â´Ù¸é + º¸¾È»ó À§Çèµµ ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ Á¤º¸°¡ ÀÖ´Ù.
    • + +
    • °¢ °¡»óÈ£½ºÆ®¸¶´Ù ServerName¸¦ Ç×»ó + Á¤ÀÇÇØ¾ß ÇÑ´Ù. ¾È±×·¯¸é °¡»óÈ£½ºÆ®¸¶´Ù DNS¸¦ ã°Ô µÈ´Ù.
    • +
    + + +
    top
    +
    +

    ÆÁ

    + +

    DNS ¹®Á¦ ÆäÀÌÁöÀÇ + ÆÁ¿¡ Ãß°¡·Î ¾Æ·¡¿¡ ÆÁÀÌ ÀÖ´Ù:

    + +
      +
    • ¸ðµç ÁÖ¼­¹ö Á¤ÀǸ¦ VirtualHost Á¤ÀÇ ¾Õ¿¡ + µÎ¾î¶ó. (±×·¯¸é ¼³Á¤À» Àбâ ÆíÇÏ´Ù. ¾È±×·¯¸é ³ªÁß¿¡ ¼³Á¤ÀÌ + ÇÕÃÄÁú¶§ °¡»óÈ£½ºÆ®µé »çÀÌ¿¡ ¼¯ÀÎ Á¤ÀÇ°¡ ¸ðµç °¡»óÈ£½ºÆ®¿¡ + ¿µÇâÀ» ÁÙ ¼ö Àֱ⶧¹®¿¡ È¥¶õ½º·´´Ù.)
    • + +
    • Àбâ ÆíÇϵµ·Ï ¼³Á¤¿¡¼­ ÇØ´çÇÏ´Â NameVirtualHost°ú + VirtualHost Á¤ÀǵéÀ» ¹­¾î¶ó.
    • + +
    • ServerPath°¡ ´Ù¸¥ ServerPathÀÇ + ¾ÕºÎºÐÀ» ÁöĪÇÏ´Â °æ¿ì¸¦ ÇÇÇ϶ó. ÇÇÇÒ ¼ö ¾ø´Ù¸é ¼³Á¤ÆÄÀÏ¿¡¼­ + ¾ÕºÎºÐÀÌ ´õ ±ä (´õ ÀÚ¼¼ÇÑ) °¡»óÈ£½ºÆ®¸¦ ªÀº (´ú ÀÚ¼¼ÇÑ) + °¡»óÈ£½ºÆ®º¸´Ù ¾Õ¿¡ µÎ¾î¶ó. (¿¹¸¦ µé¾î, + "ServerPath /abc"´Â "ServerPath /abc/def" ´ÙÀ½¿¡ µÎ¾î¾ß + ÇÑ´Ù.
    • +
    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/details.xml b/trunk/docs/manual/vhosts/details.xml new file mode 100644 index 0000000000..2da46607a7 --- /dev/null +++ b/trunk/docs/manual/vhosts/details.xml @@ -0,0 +1,433 @@ + + + + + + + + +Virtual Hosts + An In-Depth Discussion of Virtual Host Matching + + + +

    The virtual host code was completely rewritten in + Apache 1.3. This document attempts to explain + exactly what Apache does when deciding what virtual host to + serve a hit from. With the help of the new + NameVirtualHost + directive virtual host configuration should be a lot easier and + safer than with versions prior to 1.3.

    + +

    If you just want to make it work without + understanding how, here are some + examples.

    + +
    + +
    Config File Parsing + +

    There is a main_server which consists of all the + definitions appearing outside of + <VirtualHost> sections. There are virtual + servers, called vhosts, which are defined by + VirtualHost + sections.

    + +

    The directives + Listen, + ServerName, + ServerPath, + and ServerAlias + can appear anywhere within the definition of a server. However, + each appearance overrides the previous appearance (within that + server).

    + +

    The default value of the Listen field for + main_server is 80. The main_server has no default + ServerPath, or ServerAlias. The + default ServerName is deduced from the server's IP + address.

    + +

    The main_server Listen directive has two functions. One + function is to determine the default network port Apache will + bind to. The second function is to specify the port number + which is used in absolute URIs during redirects.

    + +

    Unlike the main_server, vhost ports do not affect + what ports Apache listens for connections on.

    + +

    Each address appearing in the VirtualHost + directive can have an optional port. If the port is unspecified + it defaults to the value of the main_server's most recent + Listen statement. The special port * + indicates a wildcard that matches any port. Collectively the + entire set of addresses (including multiple A + record results from DNS lookups) are called the vhost's + address set.

    + +

    Unless a NameVirtualHost + directive is used for a specific IP address the first vhost + with that address is treated as an IP-based vhost. The IP + address can also be the wildcard *.

    + +

    If name-based vhosts should be used a + NameVirtualHost directive must appear + with the IP address set to be used for the name-based vhosts. + In other words, you must specify the IP address that holds the + hostname aliases (CNAMEs) for your name-based vhosts via a + NameVirtualHost directive in your configuration + file.

    + +

    Multiple NameVirtualHost directives can be used + each with a set of VirtualHost directives but only + one NameVirtualHost directive should be used for + each specific IP:port pair.

    + +

    The ordering of NameVirtualHost and + VirtualHost directives is not important which + makes the following two examples identical (only the order of + the VirtualHost directives for one + address set is important, see below):

    + + + + +
    + NameVirtualHost 111.22.33.44
    + <VirtualHost 111.22.33.44>
    + # server A
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # server B
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.55
    + <VirtualHost 111.22.33.55>
    + # server C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server D
    + ...
    + </VirtualHost> +
    + <VirtualHost 111.22.33.44>
    + # server A
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # server B
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # server D
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.44
    + NameVirtualHost 111.22.33.55
    +
    +
    + + +

    (To aid the readability of your configuration you should + prefer the left variant.)

    + +

    After parsing the VirtualHost directive, the + vhost server is given a default Listen equal to the + port assigned to the first name in its VirtualHost + directive.

    + +

    The complete list of names in the VirtualHost + directive are treated just like a ServerAlias (but + are not overridden by any ServerAlias statement) + if all names resolve to the same address set. Note that + subsequent Listen statements for this vhost will not + affect the ports assigned in the address set.

    + +

    During initialization a list for each IP address is + generated and inserted into an hash table. If the IP address is + used in a NameVirtualHost directive the list + contains all name-based vhosts for the given IP address. If + there are no vhosts defined for that address the + NameVirtualHost directive is ignored and an error + is logged. For an IP-based vhost the list in the hash table is + empty.

    + +

    Due to a fast hashing function the overhead of hashing an IP + address during a request is minimal and almost not existent. + Additionally the table is optimized for IP addresses which vary + in the last octet.

    + +

    For every vhost various default values are set. In + particular:

    + +
      +
    1. If a vhost has no ServerAdmin, + ResourceConfig, + AccessConfig, + Timeout, + KeepAliveTimeout, + KeepAlive, + MaxKeepAliveRequests, + or SendBufferSize + directive then the respective value is inherited from the + main_server. (That is, inherited from whatever the final + setting of that value is in the main_server.)
    2. + +
    3. The "lookup defaults" that define the default directory + permissions for a vhost are merged with those of the + main_server. This includes any per-directory configuration + information for any module.
    4. + +
    5. The per-server configs for each module from the + main_server are merged into the vhost server.
    6. +
    + +

    Essentially, the main_server is treated as "defaults" or a + "base" on which to build each vhost. But the positioning of + these main_server definitions in the config file is largely + irrelevant -- the entire config of the main_server has been + parsed when this final merging occurs. So even if a main_server + definition appears after a vhost definition it might affect the + vhost definition.

    + +

    If the main_server has no ServerName at this + point, then the hostname of the machine that httpd + is running on is used instead. We will call the main_server address + set those IP addresses returned by a DNS lookup on the + ServerName of the main_server.

    + +

    For any undefined ServerName fields, a + name-based vhost defaults to the address given first in the + VirtualHost statement defining the vhost.

    + +

    Any vhost that includes the magic _default_ + wildcard is given the same ServerName as the + main_server.

    + +
    + +
    Virtual Host Matching + +

    The server determines which vhost to use for a request as + follows:

    + +
    Hash table lookup + +

    When the connection is first made by a client, the IP + address to which the client connected is looked up in the + internal IP hash table.

    + +

    If the lookup fails (the IP address wasn't found) the + request is served from the _default_ vhost if + there is such a vhost for the port to which the client sent the + request. If there is no matching _default_ vhost + the request is served from the main_server.

    + +

    If the IP address is not found in the hash table then the + match against the port number may also result in an entry + corresponding to a NameVirtualHost *, which is + subsequently handled like other name-based vhosts.

    + +

    If the lookup succeeded (a corresponding list for the IP + address was found) the next step is to decide if we have to + deal with an IP-based or a name-base vhost.

    + +
    + +
    IP-based vhost + +

    If the entry we found has an empty name list then we have + found an IP-based vhost, no further actions are performed and + the request is served from that vhost.

    + +
    + +
    Name-based vhost + +

    If the entry corresponds to a name-based vhost the name list + contains one or more vhost structures. This list contains the + vhosts in the same order as the VirtualHost + directives appear in the config file.

    + +

    The first vhost on this list (the first vhost in the config + file with the specified IP address) has the highest priority + and catches any request to an unknown server name or a request + without a Host: header field.

    + +

    If the client provided a Host: header field the + list is searched for a matching vhost and the first hit on a + ServerName or ServerAlias is taken + and the request is served from that vhost. A Host: + header field can contain a port number, but Apache always + matches against the real port to which the client sent the + request.

    + +

    If the client submitted a HTTP/1.0 request without + Host: header field we don't know to what server + the client tried to connect and any existing + ServerPath is matched against the URI from the + request. The first matching path on the list is used and the + request is served from that vhost.

    + +

    If no matching vhost could be found the request is served + from the first vhost with a matching port number that is on the + list for the IP to which the client connected (as already + mentioned before).

    + +
    + +
    Persistent connections + +

    The IP lookup described above is only done once for a + particular TCP/IP session while the name lookup is done on + every request during a KeepAlive/persistent + connection. In other words a client may request pages from + different name-based vhosts during a single persistent + connection.

    + +
    + +
    Absolute URI + +

    If the URI from the request is an absolute URI, and its + hostname and port match the main server or one of the + configured virtual hosts and match the address and + port to which the client sent the request, then the + scheme/hostname/port prefix is stripped off and the remaining + relative URI is served by the corresponding main server or + virtual host. If it does not match, then the URI remains + untouched and the request is taken to be a proxy request.

    +
    + +
    Observations + +
      +
    • A name-based vhost can never interfere with an IP-base + vhost and vice versa. IP-based vhosts can only be reached + through an IP address of its own address set and never + through any other address. The same applies to name-based + vhosts, they can only be reached through an IP address of the + corresponding address set which must be defined with a + NameVirtualHost directive.
    • + +
    • ServerAlias and ServerPath + checks are never performed for an IP-based vhost.
    • + +
    • The order of name-/IP-based, the _default_ + vhost and the NameVirtualHost directive within + the config file is not important. Only the ordering of + name-based vhosts for a specific address set is significant. + The one name-based vhosts that comes first in the + configuration file has the highest priority for its + corresponding address set.
    • + +
    • For security reasons the port number given in a + Host: header field is never used during the + matching process. Apache always uses the real port to which + the client sent the request.
    • + +
    • If a ServerPath directive exists which is a + prefix of another ServerPath directive that + appears later in the configuration file, then the former will + always be matched and the latter will never be matched. (That + is assuming that no Host: header field was + available to disambiguate the two.)
    • + +
    • If two IP-based vhosts have an address in common, the + vhost appearing first in the config file is always matched. + Such a thing might happen inadvertently. The server will give + a warning in the error logfile when it detects this.
    • + +
    • A _default_ vhost catches a request only if + there is no other vhost with a matching IP address + and a matching port number for the request. The + request is only caught if the port number to which the client + sent the request matches the port number of your + _default_ vhost which is your standard + Listen by default. A wildcard port can be + specified (i.e., _default_:*) to catch + requests to any available port. This also applies to + NameVirtualHost * vhosts.
    • + +
    • The main_server is only used to serve a request if the IP + address and port number to which the client connected is + unspecified and does not match any other vhost (including a + _default_ vhost). In other words the main_server + only catches a request for an unspecified address/port + combination (unless there is a _default_ vhost + which matches that port).
    • + +
    • A _default_ vhost or the main_server is + never matched for a request with an unknown or + missing Host: header field if the client + connected to an address (and port) which is used for + name-based vhosts, e.g., in a + NameVirtualHost directive.
    • + +
    • You should never specify DNS names in + VirtualHost directives because it will force + your server to rely on DNS to boot. Furthermore it poses a + security threat if you do not control the DNS for all the + domains listed. There's more + information available on this and the next two + topics.
    • + +
    • ServerName should always be set for each + vhost. Otherwise A DNS lookup is required for each + vhost.
    • +
    +
    + +
    + +
    Tips + +

    In addition to the tips on the DNS Issues page, here are + some further tips:

    + +
      +
    • Place all main_server definitions before any + VirtualHost definitions. (This is to aid the + readability of the configuration -- the post-config merging + process makes it non-obvious that definitions mixed in around + virtual hosts might affect all virtual hosts.)
    • + +
    • Group corresponding NameVirtualHost and + VirtualHost definitions in your configuration to + ensure better readability.
    • + +
    • Avoid ServerPaths which are prefixes of + other ServerPaths. If you cannot avoid this then + you have to ensure that the longer (more specific) prefix + vhost appears earlier in the configuration file than the + shorter (less specific) prefix (i.e., "ServerPath + /abc" should appear after "ServerPath /abc/def").
    • +
    + +
    +
    + diff --git a/trunk/docs/manual/vhosts/details.xml.ko b/trunk/docs/manual/vhosts/details.xml.ko new file mode 100644 index 0000000000..ec207278f5 --- /dev/null +++ b/trunk/docs/manual/vhosts/details.xml.ko @@ -0,0 +1,377 @@ + + + + + + + + +°¡»óÈ£½ºÆ® + °¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í + + + +

    °¡»óÈ£½ºÆ® ÄÚµå´Â ¾ÆÆÄÄ¡ 1.3¿¡¼­ °ÅÀÇ ´Ù½Ã + ÀÛ¼ºµÇ¾ú´Ù. ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡°¡ ¿äûÀ» ¹ÞÀ¸¸é ¾î¶² °¡»óÈ£½ºÆ®°¡ + ¼­ºñ½ºÇÒÁö °áÁ¤ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. »õ·Î¿î NameVirtualHost Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© + °¡»óÈ£½ºÆ® ¼³Á¤ÀÌ 1.3 ¹öÀü ÀÌÀüº¸´Ù ´õ ½±°í ¾ÈÀüÇØÁ³´Ù.

    + +

    ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö ÀÌÇØÇÏÁö¾Ê°í ´ÜÁö µ¿ÀÛÇÏ°Ô¸¸ + ÇÏ°í ½Í´Ù¸é, ¿¹Á¦µéÀ» Âü°íÇ϶ó.

    + +
    + +
    ¼³Á¤ÆÄÀÏ Àбâ + +

    <VirtualHost> ¼³Á¤À» Á¦¿ÜÇÑ ¼³Á¤ÀÌ + ÁÖ¼­¹ö¸¦ ¸¸µç´Ù. VirtualHost ¼½¼ÇÀ¸·Î Á¤ÀÇÇÑ + ºÎºÐÀ» °¡»óÈ£½ºÆ®¶ó°í ºÎ¸¥´Ù.

    + +

    Listen, + ServerName, + ServerPath, + ServerAlias Áö½Ã¾î´Â + ¼­¹ö Á¤ÀÇ ¾î´À°÷¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª °°Àº Áö½Ã¾î°¡ + ¿©·¯¹ø ³ª¿À¸é (±× ¼­¹ö¿¡¼­) ¸¶Áö¸· Áö½Ã¾î¸¸ÀÌ À¯È¿ÇÏ´Ù.

    + +

    ÁÖ¼­¹ö ListenÀÇ ±âº»°ªÀº 80ÀÌ´Ù. ÁÖ¼­¹öÀÇ + ServerPath³ª ServerAlias¿¡´Â + ±âº»°ªÀº ¾ø´Ù. ServerNameÀÇ ±âº»°ªÀº ¼­¹öÀÇ + IP ÁÖ¼ÒÀÌ´Ù.

    + +

    ÁÖ¼­¹öÀÇ Listen Áö½Ã¾î´Â µÎ°¡Áö ±â´ÉÀ» ÇÑ´Ù. ù°´Â + ¾ÆÆÄÄ¡°¡ ¿¬°áÇÒ ±âº» ³×Æ®¿÷ Æ÷Æ®¸¦ ÁöÁ¤ÇÏ´Â ÀÏÀÌ´Ù. µÑ°´Â + ¸®´ÙÀÌ·º¼ÇÇÒ Àý´ë URI¿¡ »ç¿ëÇÒ Æ÷Æ® ¹øÈ£¸¦ ÁöÁ¤ÇÏ´Â ÀÏÀÌ´Ù.

    + +

    ÁÖ¼­¹ö¿Í ´Þ¸® °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ®´Â ¾ÆÆÄÄ¡°¡ ¿¬°áÀ» ±â´Ù¸®´Â + Æ÷Æ®¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù.

    + +

    VirtualHost Áö½Ã¾î¿¡ Æ÷Æ®¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Ù. + Æ÷Æ®¸¦ ÁöÁ¤ÇÏÁö¾ÊÀ¸¸é ÁÖ¼­¹öÀÇ °¡Àå ÃÖ±Ù Listen + °ªÀ» »ç¿ëÇÑ´Ù. Ưº°ÇÑ Æ÷Æ® *´Â ¾î¶² Æ÷Æ®¶óµµ + ÁöĪÇÏ´Â ¿ÍÀϵåÄ«µåÀÌ´Ù. (DNS °Ë»ö °á°úÀÇ ¿©·¯ A + ·¹Äڵ带 Æ÷ÇÔÇÏ¿©) °¡»óÈ£½ºÆ®ÀÇ ÁÖ¼Ò¸¦ ¸ðµÎ ÃÑĪÇÏ¿© °¡»óÈ£½ºÆ®ÀÇ + ÁÖ¼ÒÁýÇÕ(address set)À̶ó°í ºÎ¸¥´Ù.

    + +

    ƯÁ¤ IP ÁÖ¼Ò¿¡ ´ëÇÑ NameVirtualHost Áö½Ã¾î°¡ ¾ø´Ù¸é + ±× ÁÖ¼Ò¸¦ Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®¸¦ IP±â¹Ý °¡»óÈ£½ºÆ®·Î Ãë±ÞÇÑ´Ù. + IP ÁÖ¼Ò¿¡ ¿ÍÀϵåÄ«µå *¸¦ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù¸é À̸§±â¹Ý °¡»óÈ£½ºÆ®¿¡ + »ç¿ëÇÒ IP ÁÖ¼Ò¸¦ NameVirtualHost Áö½Ã¾î¿¡ + »ç¿ëÇØ¾ß ÇÑ´Ù. Áï, ¼³Á¤ÆÄÀÏÀÇ NameVirtualHost + Áö½Ã¾î¿¡ À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ È£½ºÆ®º°¸í(CNAME)¿¡ ÇØ´çÇÏ´Â + IP ÁÖ¼Ò¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.

    + +

    ƯÁ¤ IP:Æ÷Æ® ½Ö¿¡ ´ëÇØ ¿ÀÁ÷ ÇÑ NameVirtualHost + Áö½Ã¾î¸¸À» »ç¿ëÇÑ´Ù¸é, ¿©·¯ NameVirtualHost Áö½Ã¾î¿Í + VirtualHost Áö½Ã¾î¸¦ ¼¯¾î¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    NameVirtualHost¿Í VirtualHost + Áö½Ã¾îÀÇ ¼ø¼­´Â Áß¿äÇÏÁö ¾Ê±â¶§¹®¿¡ ´ÙÀ½ µÎ ¿¹´Â °°´Ù (¿ÀÁ÷ + ÇÑ ÁÖ¼ÒÁýÇÕ¿¡ ´ëÇÑ VirtualHostÀÇ + ¼ø¼­°¡ Áß¿äÇÏ´Ù. ¾Æ·¡ Âü°í):

    + + + + +
    + NameVirtualHost 111.22.33.44
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö A
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö B
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.55
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö D
    + ...
    + </VirtualHost> +
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö A
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö C
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.44>
    + # ¼­¹ö B
    + ...
    + </VirtualHost>
    + <VirtualHost 111.22.33.55>
    + # ¼­¹ö D
    + ...
    + </VirtualHost>
    +
    + NameVirtualHost 111.22.33.44
    + NameVirtualHost 111.22.33.55
    +
    +
    + + +

    (¿ÞÂÊ ¼³Á¤ÀÌ ´õ Àбâ ÆíÇÏ´Ù.)

    + +

    VirtualHost Áö½Ã¾î¸¦ ÀÐÀ» ´ÙÀ½, °¡»óÈ£½ºÆ® + ¼­¹ö´Â VirtualHost Áö½Ã¾î¿¡ ÁöÁ¤ÇÑ Æ÷Æ®¸¦ ±âº» + ListenÀ¸·Î ÇÑ´Ù.

    + +

    VirtualHost Áö½Ã¾îÀÇ À̸§ÀÌ ¸ðµÎ °°Àº + ÁÖ¼ÒÁýÇÕ¿¡ ¼ÓÇÑ´Ù¸é ServerAlias¿Í °°ÀÌ Ãë±ÞÇÑ´Ù + (±×·¯³ª ´Ù¸¥ ServerAliasÀÇ ¿µÇâÀ» ¹ÞÁö ¾Ê´Â´Ù). + °¡»óÈ£½ºÆ®¿¡ Ãß°¡·Î »ç¿ëÇÑ ListenÀº ÁÖ¼ÒÁýÇÕÀÌ + ÁöÁ¤ÇÑ Æ÷Æ®¿¡ ¿µÇâÀ» ÁÖÁö ¾ÊÀ½À» ÁÖÀÇÇ϶ó.

    + +

    ½ÃÀÛÇÒ¶§ IP ÁÖ¼Ò ¸ñ·ÏÀ» ¸¸µé¾î Çؽ¬Å×ÀÌºí¿¡ Ãß°¡ÇÑ´Ù. + NameVirtualHost Áö½Ã¾î¿¡ IP ÁÖ¼Ò¸¦ »ç¿ëÇϸé + ¸ñ·ÏÀº ±× IP ÁÖ¼Ò¿¡ ´ëÇÑ ¸ðµç À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÑ´Ù. + ±× ÁÖ¼Ò¿¡ ´ëÇÑ °¡»óÈ£½ºÆ®°¡ ¾ø´Ù¸é NameVirtualHost + Áö½Ã¾î¸¦ ¹«½ÃÇÏ°í ·Î±×¿¡ ¿À·ù¸¦ ±â·ÏÇÑ´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®´Â + Çؽ¬Å×ÀÌºí¿¡ ¸ñ·ÏÀ» Ãß°¡ÇÏÁö ¾Ê´Â´Ù.

    + +

    ºü¸¥ Çؽ¬ÇÔ¼ö¸¦ »ç¿ëÇϱ⶧¹®¿¡ ¿äû½Ã IP ÁÖ¼Ò¸¦ ÇؽÌÇÏ´Â + ºÎ´ãÀº °ÅÀÇ ¾ø´Ù. ¶Ç Çؽ¬Å×À̺íÀº IP ÁÖ¼ÒÀÇ ¸¶Áö¸· ºÎºÐÀÇ + Â÷ÀÌ¿¡ ÃÖÀûÈ­µÇÀÖ´Ù.

    + +

    °¡»óÈ£½ºÆ®¿¡ ¿©·¯ ±âº»°ªÀÌ ¼³Á¤µÈ´Ù. ƯÈ÷:

    + +
      +
    1. °¡»óÈ£½ºÆ®¿¡ ServerAdmin, + ResourceConfig, + AccessConfig, + Timeout, + KeepAliveTimeout, + KeepAlive, + MaxKeepAliveRequests, + SendBufferSize + Áö½Ã¾î°¡ ¾ø´Ù¸é ÁÖ¼­¹ö¿¡¼­ ÇØ´ç °ªÀ» °¡Á®¿Â´Ù. (Áï, + ÁÖ¼­¹öÀÇ ¼³Á¤°ªÀ» »ç¿ëÇÑ´Ù.)
    2. + +
    3. °¡»óÈ£½ºÆ®ÀÇ µð·ºÅ丮 ±âº»±ÇÇÑÀ» Á¤ÀÇÇÏ´Â "ÂüÁ¶ + ±âº»°ª(lookup defaults)"Àº ÁÖ¼­¹öÀÇ ¼³Á¤°ú ÇÕÃÄÁø´Ù. + ¸ðµâÀÇ µð·ºÅ丮´ç ¼³Á¤(per-directory configuration)µµ + ¿©±â¿¡ ÇØ´çµÈ´Ù.
    4. + +
    5. °¢ ¸ðµâÀÇ ¼­¹ö´ç ¼³Á¤(per-server config)Àº ÁÖ¼­¹öÀÇ + ¼³Á¤°ú °¡»óÈ£½ºÆ®ÀÇ ¼³Á¤À» ÇÕÄ£´Ù.
    6. +
    + +

    ±âº»ÀûÀ¸·Î ÁÖ¼­¹ö´Â °¡»óÈ£½ºÆ®¸¦ ¸¸µå´Â "±âº»" ȤÀº "±â¹Ý"ÀÌ + µÈ´Ù. ±×·¯³ª ¼³Á¤ÆÄÀÏ¿¡¼­ ÁÖ¼­¹ö¸¦ Á¤ÀÇÇÏ´Â À§Ä¡´Â °ü°è¾ø´Ù. + ¸¶Áö¸·À¸·Î ¼³Á¤À» ÇÕÄ¡±â Àü¿¡ ÁÖ¼­¹öÀÇ ¸ðµç ¼³Á¤À» ÀоîµéÀδÙ. + ±×·¡¼­ ÁÖ¼­¹ö Á¤ÀÇ°¡ °¡»óÈ£½ºÆ® Á¤ÀÇ µÚ¿¡ ³ª¿Íµµ °¡»óÈ£½ºÆ® + Á¤ÀÇ¿¡ ¿µÇâÀ» ÁØ´Ù.

    + +

    ÁÖ¼­¹ö¿¡ ServerNameÀÌ ¾ø´Ù¸é À¥¼­¹ö¸¦ ½ÇÇàÇÏ´Â + ÄÄÇ»ÅÍÀÇ È£½ºÆ®¸íÀ» ´ë½Å »ç¿ëÇÑ´Ù. ÁÖ¼­¹öÀÇ + ServerNameÀ» DNS °Ì»öÇÏ¿© ¾òÀº IP ÁÖ¼ÒµéÀ» + ÁÖ¼­¹ö ÁÖ¼ÒÁýÇÕÀ̶ó°í ºÎ¸¥´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ ServerNameÀ» Á¤ÀÇÇÏÁö + ¾ÊÀ¸¸é °¡»óÈ£½ºÆ®¸¦ Á¤ÀÇÇÏ´Â VirtualHost¿¡¼­ + óÀ½À¸·Î ³ª¿Â ÁÖ¼Ò¸¦ ±âº»°ªÀ¸·Î »ç¿ëÇÑ´Ù.

    + +

    Ưº°ÇÑ _default_ ¿ÍÀÏƮīµå¸¦ Æ÷ÇÔÇÏ´Â + °¡»óÈ£½ºÆ®´Â ÁÖ¼­¹ö¿Í °°Àº ServerNameÀ» °¡Áø´Ù.

    + +
    + +
    °¡»óÈ£½ºÆ® ã±â + +

    ¼­¹ö´Â ¾Æ·¡¿Í °°Àº ¹æ¹ýÀ¸·Î ¾î¶² °¡»óÈ£½ºÆ®°¡ ¿äûÀ» + ó¸®ÇÒÁö °áÁ¤ÇÑ´Ù:

    + +
    Çؽ¬Å×À̺í ã±â + +

    Ŭ¶óÀ̾ðÆ®°¡ óÀ½ ¿¬°áÇÏ¸é ¿¬°áÇÑ IP ÁÖ¼Ò¸¦ ³»ºÎ IP + Çؽ¬Å×ÀÌºí¿¡¼­ ã´Â´Ù.

    + +

    IP ÁÖ¼Ò¸¦ ãÀ» ¼ö ¾ø°í Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ Æ÷Æ®¿¡ + ÇØ´çÇÏ´Â °¡»óÈ£½ºÆ®°¡ ÀÖ´Ù¸é, _default_ °¡»óÈ£½ºÆ®°¡ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. _default_ °¡»óÈ£½ºÆ®°¡ + ¾ø´Ù¸é ÁÖ¼­¹ö°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + +

    Çؽ¬Å×ÀÌºí¿¡ IP ÁÖ¼Ò°¡ ¾øÁö¸¸ Æ÷Æ® ¹øÈ£°¡ + NameVirtualHost *¿¡ ÇØ´çÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì + À̸§±â¹Ý °¡»óÈ£½ºÆ®Ã³·³ ó¸®ÇÑ´Ù.

    + +

    ã¾Ò´Ù¸é (¸ñ·Ï¿¡¼­ IP ÁÖ¼Ò¿¡ ÇØ´çÇÏ´Â Ç׸ñÀ» ãÀ¸¸é), + IP±â¹Ý °¡»óÈ£½ºÆ®ÀÎÁö À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÎÁö °áÁ¤ÇÑ´Ù.

    + +
    + +
    IP±â¹Ý °¡»óÈ£½ºÆ® + +

    ãÀº Ç׸ñ¿¡ À̸§ ¸ñ·ÏÀÌ ¾ø´Ù¸é IP±â¹Ý °¡»óÈ£½ºÆ®ÀÌ´Ù. + ´õ ÀÌ»ó ÀÛ¾÷ÀÌ ÇÊ¿ä¾ø°í, ±× °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ó¸®ÇÑ´Ù.

    + +
    + +
    À̸§±â¹Ý °¡»óÈ£½ºÆ® + +

    À̸§ ¸ñ·Ï¿¡ ÇÑ°³ ÀÌ»óÀÇ °¡»óÈ£½ºÆ® ±¸Á¶°¡ Æ÷ÇԵǸé + À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÌ´Ù. ÀÌ ¸ñ·Ï¿¡¼­ °¡»óÈ£½ºÆ®µéÀº ¼³Á¤ÆÄÀÏÀÇ + VirtualHost ¼ø¼­´ë·Î À§Ä¡ÇÑ´Ù.

    + +

    ¸ñ·Ï¿¡¼­ ù¹ø° °¡»óÈ£½ºÆ®(¼³Á¤ÆÄÀÏ¿¡¼­ ÇØ´ç IP ÁÖ¼Ò¸¦ + Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®)´Â °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç, + ¼­¹ö¸íÀ» ¾Ë ¼ö ¾ø°Å³ª Host: Çì´õ°¡ ¾ø´Â ¿äûÀ» + ó¸®ÇÑ´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ Host: Çì´õ¸¦ ÁÖ¸é, ¸ñ·Ï¿¡¼­ + ù¹ø°·Î ServerNameÀ̳ª + ServerAlias°¡ ´ëÀÀÇÏ´Â °¡»óÈ£½ºÆ®°¡ ¿äûÀ» + ¼­ºñ½ºÇÑ´Ù. Host: Çì´õ¿¡ Æ÷Æ® ¹øÈ£°¡ ³ª¿Ã ¼ö + ÀÖÁö¸¸, ¾ÆÆÄÄ¡´Â Ç×»ó Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ ½ÇÁ¦ Æ÷Æ®¸¦ + ã´Â´Ù.

    + +

    Ŭ¶óÀ̾ðÆ®°¡ Host: Çì´õ¾øÀÌ HTTP/1.0 ¿äûÀ» + Çϸé Ŭ¶óÀ̾ðÆ®°¡ ¾î¶² ¼­¹ö¿¡ ¿¬°áÇÏ·Á´ÂÁö ¾Ë ¼ö ¾ø±â¶§¹®¿¡ + ¿äûÀÇ URI¿¡ ÇØ´çÇÏ´Â ServerPath°¡ ÀÖ´ÂÁö ã´Â´Ù. + ¸ñ·Ï¿¡¼­ Á¦ÀÏ ¸ÕÀú ãÀº °æ·Î¸¦ »ç¿ëÇÏ°í, ±× °¡»óÈ£½ºÆ®°¡ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + +

    ´ëÀÀÇÏ´Â °¡»óÈ£½ºÆ®¸¦ ãÀ» ¼ö ¾ø´Ù¸é, (ÀÌ¹Ì ¾Õ¿¡ ¸»ÇßµíÀÌ) + Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÇÑ IP¿¡ ´ëÇÑ ¸ñ·Ï¿¡¼­ ÀÏÄ¡ÇÏ´Â Æ÷Æ® ¹øÈ£¸¦ + Æ÷ÇÔÇϴ ù¹ø° °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù.

    + +
    + +
    Áö¼Ó ¿¬°á + +

    IP´Â À§¿¡¼­ ¼³¸íÇѵ¥·Î ƯÁ¤ TCP/IP ¼¼¼Ç´ç Çѹø¸¸ + ãÁö¸¸, À̸§Àº KeepAlive/Áö¼Ó ¿¬°áµ¿¾È ¸Å ¿äû¶§¸¶´Ù + ã´Â´Ù. Áï, Ŭ¶óÀ̾ðÆ®´Â Áö¼Ó ¿¬°áµ¿¾È ¿©·¯ À̸§±â¹Ý + °¡»óÈ£½ºÆ®ÀÇ ÆäÀÌÁö¸¦ ¿äûÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    Àý´ë URI + +

    ¿äûÀÇ URI°¡ Àý´ë URIÀÌ°í Ŭ¶óÀ̾ðÆ®°¡ º¸³½ ¿äûÀÇ + È£½ºÆ®¸í°ú Æ÷Æ®°¡ ÁÖ¼­¹ö³ª ƯÁ¤ °¡»óÈ£½ºÆ®¿¡ ÇØ´çÇϸé, + ±× ÁÖ¼­¹ö ȤÀº °¡»óÈ£½ºÆ®´Â URI ¾ÕÀÇ ½ºÅ´/È£½ºÆ®¸í/Æ÷Æ® + ºÎºÐÀ» Á¦¿ÜÇÑ ³ª¸ÓÁö »ó´ë URI¸¦ ¼­ºñ½ºÇÑ´Ù. ÇØ´çÇÏ´Â + ÁÖ¼­¹ö³ª °¡»óÈ£½ºÆ®°¡ ¾ø´Ù¸é URI¸¦ ±×´ë·Î µÎ°í ¿äûÀ» + ÇÁ·Ï½Ã ¿äûÀ¸·Î ó¸®ÇÑ´Ù.

    +
    + +
    ÁÖÀÇ + +
      +
    • À̸§±â¹Ý °¡»óÈ£½ºÆ®¿Í IP±â¹Ý °¡»óÈ£½ºÆ®´Â ¼­·Î¿¡°Ô + ¿µÇâÀ» ÁÖÁö ¾Ê´Â´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÀÚ½ÅÀÇ À̸§ÁýÇÕ + IP ÁÖ¼Ò¿Ü¿¡ ¾î¶² Áּҷεµ Á¢±ÙÇÒ ¼ö ¾ø´Ù. À̸§±â¹Ý + °¡»óÈ£½ºÆ®µµ ¸¶Âù°¡Áö´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â + NameVirtualHost Áö½Ã¾î·Î Á¤ÀÇÇÑ ÁÖ¼ÒÁýÇÕÀÇ + IP ÁÖ¼Ò¸¦ ÅëÇؼ­¸¸ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.
    • + +
    • IP±â¹Ý °¡»óÈ£½ºÆ®´Â ServerAlias¿Í + ServerPath¸¦ Àý´ë·Î °Ë»çÇÏÁö ¾Ê´Â´Ù.
    • + +
    • ¼³Á¤ÆÄÀÏ¿¡¼­ À̸§±â¹Ý °¡»óÈ£½ºÆ®, IP±â¹Ý °¡»óÈ£½ºÆ®, + _default_ °¡»óÈ£½ºÆ®, NameVirtualHost + Áö½Ã¾îÀÇ ¼ø¼­´Â Áß¿äÇÏÁö ¾Ê´Ù. ƯÁ¤ ÁÖ¼ÒÁýÇÕ¿¡ ´ëÇÑ + À̸§±â¹Ý °¡»óÈ£½ºÆ®µéÀÇ ¼ø¼­¸¸ÀÌ Áß¿äÇÏ´Ù. ¼³Á¤ÆÄÀÏ¿¡¼­ + ¾Õ¿¡ ³ª¿À´Â À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â ÀÚ½ÅÀÌ ¼ÓÇÑ ÁÖ¼ÒÁýÇÕ¿¡¼­ + °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áø´Ù.
    • + +
    • º¸¾ÈÀ» À§ÇØ Host: Çì´õ¿¡ Æ÷ÇÔµÈ Æ÷Æ® + ¹øÈ£´Â Àý´ë·Î »ç¿ëÇÏÁö ¾Ê´Â´Ù. ¾ÆÆÄÄ¡´Â Ç×»ó Ŭ¶óÀ̾ðÆ®°¡ + ¿äûÀ» º¸³½ ½ÇÁ¦ Æ÷Æ®¸¦ »ç¿ëÇÑ´Ù.
    • + +
    • (µÑ »çÀ̸¦ ±¸º°ÇÒ Host: Çì´õ°¡ ¾ø´Ù°í + °¡Á¤Çϸé,) ServerPath Áö½Ã¾î°¡ ¼³Á¤ÆÄÀÏ¿¡¼­ + µÚ¿¡ ³ª¿À´Â ´Ù¸¥ ServerPath Áö½Ã¾îÀÇ ¾ÕºÎºÐÀ» + ÁöĪÇÏ´Â °æ¿ì Ç×»ó ¾Õ¿¡ ³ª¿Â Áö½Ã¾î¸¦ »ç¿ëÇÑ´Ù.
    • + +
    • µÎ IP±â¹Ý °¡»óÈ£½ºÆ®°¡ °°Àº ÁÖ¼Ò¸¦ °¡Áö¸é, Ç×»ó + ¼³Á¤ÆÄÀÏ¿¡¼­ ¾Õ¿¡ ³ª¿À´Â °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù. ÀÌ·± ÀÏÀº + ¾Æ¹«µµ ¸ð¸£°Ô ÀϾ ¼ö ÀÖ´Ù. ¼­¹ö°¡ ÀÌ·± »óȲÀ» ¹ß°ßÇϸé + ¿À·ù ·Î±×ÆÄÀÏ¿¡ °æ°í¸¦ ±â·ÏÇÑ´Ù.
    • + +
    • _default_ °¡»óÈ£½ºÆ®´Â ¿äûÀÇ IP ÁÖ¼Ò¿Í + Æ÷Æ® ¹øÈ£¿¡ ÇØ´çÇÏ´Â °¡»óÈ£½ºÆ®°¡ ¾øÀ»¶§¸¸ ¿äûÀ» ó¸®ÇÑ´Ù. + Ŭ¶óÀ̾ðÆ®°¡ ¿äûÀ» º¸³½ Æ÷Æ® ¹øÈ£°¡ _default_ + °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ® ¹øÈ£(±âº»°ªÀº Listen)¿Í + °°À»¶§¸¸ ¿äûÀ» ó¸®ÇÑ´Ù. ¾î¶² Æ÷Æ®ÀÇ ¿äûÀÌ¶óµµ Àâ±âÀ§ÇØ + (¿¹¸¦ µé¾î, _default_:*) ¿ÍÀϵåÄ«µå + Æ÷Æ®¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. NameVirtualHost * + °¡»óÈ£½ºÆ®µµ ¸¶Âù°¡Áö´Ù.
    • + +
    • ÁÖ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÇÑ IP ÁÖ¼Ò¿Í Æ÷Æ® ¹øÈ£¿¡ + ÇØ´çÇÏ´Â (_default_ °¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÏ¿©) + °¡»óÈ£½ºÆ®°¡ ¾øÀ»¶§¸¸ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. Áï, ÁÖ¼­¹ö´Â + (±× Æ÷Æ®¿¡ ÇØ´çÇÏ´Â _default_ °¡»óÈ£½ºÆ®°¡ + ¾ø´Ù¸é) ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò/Æ÷Æ® ½Ö¿¡ ´ëÇÑ ¿äû¸¸À» ó¸®ÇÑ´Ù.
    • + +
    • Ŭ¶óÀ̾ðÆ®°¡ (¿¹¸¦ µé¾î, NameVirtualHost + Áö½Ã¾î¿¡¼­) À̸§±â¹Ý °¡»óÈ£½ºÆ® ÁÖ¼Ò(¿Í Æ÷Æ®)¿¡ ¿¬°áÇÑ + °æ¿ì Host: Çì´õ¸¦ ¾Ë ¼ö ¾ø°Å³ª Çì´õ°¡ ¾ø´Â + ¿äûÀ» º¸³»¸é ¿äûÀº Àý´ë·Î _default_ + °¡»óÈ£½ºÆ®³ª ÁÖ¼­¹ö¿¡¼­ ó¸®ÇÏÁö ¾Ê´Â´Ù.
    • + +
    • ½ÃÀÛÇÒ¶§ ¼­¹ö°¡ DNS¸¦ ÀÇÁ¸ÇÏÁö ¾ÊÀ¸·Á¸é Àý´ë·Î + VirtualHost Áö½Ã¾î¿¡ DNS À̸§À» »ç¿ëÇÏÁö¸¶¶ó. + °Ô´Ù°¡ ¿­°ÅÇÑ ¸ðµç µµ¸ÞÀÎÀÇ DNS¸¦ ÅëÁ¦ÇÏÁö ¾Ê´Â´Ù¸é + º¸¾È»ó À§Çèµµ ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ Á¤º¸°¡ ÀÖ´Ù.
    • + +
    • °¢ °¡»óÈ£½ºÆ®¸¶´Ù ServerName¸¦ Ç×»ó + Á¤ÀÇÇØ¾ß ÇÑ´Ù. ¾È±×·¯¸é °¡»óÈ£½ºÆ®¸¶´Ù DNS¸¦ ã°Ô µÈ´Ù.
    • +
    +
    + +
    + +
    ÆÁ + +

    DNS ¹®Á¦ ÆäÀÌÁöÀÇ + ÆÁ¿¡ Ãß°¡·Î ¾Æ·¡¿¡ ÆÁÀÌ ÀÖ´Ù:

    + +
      +
    • ¸ðµç ÁÖ¼­¹ö Á¤ÀǸ¦ VirtualHost Á¤ÀÇ ¾Õ¿¡ + µÎ¾î¶ó. (±×·¯¸é ¼³Á¤À» Àбâ ÆíÇÏ´Ù. ¾È±×·¯¸é ³ªÁß¿¡ ¼³Á¤ÀÌ + ÇÕÃÄÁú¶§ °¡»óÈ£½ºÆ®µé »çÀÌ¿¡ ¼¯ÀÎ Á¤ÀÇ°¡ ¸ðµç °¡»óÈ£½ºÆ®¿¡ + ¿µÇâÀ» ÁÙ ¼ö Àֱ⶧¹®¿¡ È¥¶õ½º·´´Ù.)
    • + +
    • Àбâ ÆíÇϵµ·Ï ¼³Á¤¿¡¼­ ÇØ´çÇÏ´Â NameVirtualHost°ú + VirtualHost Á¤ÀǵéÀ» ¹­¾î¶ó.
    • + +
    • ServerPath°¡ ´Ù¸¥ ServerPathÀÇ + ¾ÕºÎºÐÀ» ÁöĪÇÏ´Â °æ¿ì¸¦ ÇÇÇ϶ó. ÇÇÇÒ ¼ö ¾ø´Ù¸é ¼³Á¤ÆÄÀÏ¿¡¼­ + ¾ÕºÎºÐÀÌ ´õ ±ä (´õ ÀÚ¼¼ÇÑ) °¡»óÈ£½ºÆ®¸¦ ªÀº (´ú ÀÚ¼¼ÇÑ) + °¡»óÈ£½ºÆ®º¸´Ù ¾Õ¿¡ µÎ¾î¶ó. (¿¹¸¦ µé¾î, + "ServerPath /abc"´Â "ServerPath /abc/def" ´ÙÀ½¿¡ µÎ¾î¾ß + ÇÑ´Ù.
    • +
    + +
    +
    + diff --git a/trunk/docs/manual/vhosts/details.xml.meta b/trunk/docs/manual/vhosts/details.xml.meta new file mode 100644 index 0000000000..b053310f3d --- /dev/null +++ b/trunk/docs/manual/vhosts/details.xml.meta @@ -0,0 +1,12 @@ + + + + details + /vhosts/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/vhosts/examples.html b/trunk/docs/manual/vhosts/examples.html new file mode 100644 index 0000000000..4fad113737 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.html @@ -0,0 +1,11 @@ +URI: examples.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: examples.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: examples.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/examples.html.en b/trunk/docs/manual/vhosts/examples.html.en new file mode 100644 index 0000000000..5f7971a48f --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.html.en @@ -0,0 +1,658 @@ + + + +VirtualHost Examples - Apache HTTP Server + + + + + +
    <-
    +

    VirtualHost Examples

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    This document attempts to answer the commonly-asked questions about + setting up virtual hosts. These scenarios are those involving multiple + web sites running on a single server, via name-based or IP-based virtual hosts. +

    + +
    + +
    top
    +
    +

    Running several name-based web + sites on a single IP address.

    + +

    Your server has a single IP address, and multiple aliases (CNAMES) + point to this machine in DNS. You want to run a web server for + www.example.com and www.example.org on this + machine.

    + +

    Note

    Creating virtual + host configurations on your Apache server does not magically + cause DNS entries to be created for those host names. You + must have the names in DNS, resolving to your IP + address, or nobody else will be able to see your web site. You + can put entries in your hosts file for local + testing, but that will work only from the machine with those + hosts entries.

    +
    + +

    Server configuration

    + + + # Ensure that Apache listens on port 80
    + Listen 80
    +
    + # Listen for virtual host requests on all IP addresses
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here
    +
    +
    + </VirtualHost> +

    + +

    The asterisks match all addresses, so the main server serves no + requests. Due to the fact that www.example.com is first + in the configuration file, it has the highest priority and can be seen + as the default or primary server. That means + that if a request is received that does not match one of the specified + ServerName directives, it will be served by this first + VirtualHost.

    + +
    +

    Note

    + +

    You can, if you wish, replace * with the actual + IP address of the system. In that case, the argument to + VirtualHost must match the argument to + NameVirtualHost:

    + +

    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # etc ... +

    + +

    However, it is additionally useful to use * + on systems where the IP address is not predictable - for + example if you have a dynamic IP address with your ISP, and + you are using some variety of dynamic DNS solution. Since + * matches any IP address, this configuration + would work without changes whenever your IP address + changes.

    +
    + +

    The above configuration is what you will want to use in almost + all name-based virtual hosting situations. The only thing that this + configuration will not work for, in fact, is when you are serving + different content based on differing IP addresses or ports.

    + +
    top
    +
    +

    Name-based hosts on more than one + IP address.

    + +
    +

    Note

    Any of the + techniques discussed here can be extended to any number of IP + addresses.

    +
    + +

    The server has two IP addresses. On one (172.20.30.40), we + will serve the "main" server, server.domain.com and on the + other (172.20.30.50), we will serve two or more virtual hosts.

    + +

    Server configuration

    + + + Listen 80
    +
    + # This is the "main" server running on 172.20.30.40
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # This is the other address
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost> +

    + +

    Any request to an address other than 172.20.30.50 will be + served from the main server. A request to 172.20.30.50 with an + unknown hostname, or no Host: header, will be served from + www.example.com.

    + +
    top
    +
    +

    Serving the same content on + different IP addresses (such as an internal and external + address).

    + +

    The server machine has two IP addresses (192.168.1.1 + and 172.20.30.40). The machine is sitting between an + internal (intranet) network and an external (internet) network. Outside + of the network, the name server.example.com resolves to + the external address (172.20.30.40), but inside the + network, that same name resolves to the internal address + (192.168.1.1).

    + +

    The server can be made to respond to internal and external requests + with the same content, with just one VirtualHost + section.

    + +

    Server configuration

    + + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +

    + +

    Now requests from both networks will be served from the same + VirtualHost.

    + +
    +

    Note:

    On the internal + network, one can just use the name server rather + than the fully qualified host name + server.example.com.

    + +

    Note also that, in the above example, you can replace the list + of IP addresses with *, which will cause the server to + respond the same on all addresses.

    +
    + +
    top
    +
    +

    Running different sites on different + ports.

    + +

    You have multiple domains going to the same IP and also want to + serve multiple ports. By defining the ports in the "NameVirtualHost" + tag, you can allow this to work. If you try using <VirtualHost + name:port> without the NameVirtualHost name:port or you try to use + the Listen directive, your configuration will not work.

    + +

    Server configuration

    + + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    IP-based virtual hosting

    + +

    The server has two IP addresses (172.20.30.40 and + 172.20.30.50) which resolve to the names + www.example.com and www.example.org + respectively.

    + +

    Server configuration

    + + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +

    Requests for any address not specified in one of the + <VirtualHost> directives (such as + localhost, for example) will go to the main server, if + there is one.

    + +
    top
    +
    +

    Mixed port-based and ip-based virtual + hosts

    + +

    The server machine has two IP addresses (172.20.30.40 and + 172.20.30.50) which resolve to the names + www.example.com and www.example.org + respectively. In each case, we want to run hosts on ports 80 and + 8080.

    + +

    Server configuration

    + + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    Mixed name-based and IP-based + vhosts

    + +

    On some of my addresses, I want to do name-based virtual hosts, and + on others, IP-based hosts.

    + +

    Server configuration

    + + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-based
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    Using Virtual_host and + mod_proxy together

    + +

    The following example allows a front-end machine to proxy a + virtual host through to a server running on another machine. In the + example, a virtual host of the same name is configured on a machine + at 192.168.111.2. The ProxyPreserveHost On directive is + used so that the desired hostname is passed through, in case we are + proxying multiple hostnames to a single machine.

    + +

    + <VirtualHost *:*>
    + ProxyPreserveHost On
    + ProxyPass / http://192.168.111.2
    + ProxyPassReverse / http://192.168.111.2/
    + ServerName hostname.example.com
    + </VirtualHost> +

    + +
    top
    +
    +

    Using _default_ + vhosts

    + +

    _default_ vhosts + for all ports

    + +

    Catching every request to any unspecified IP address and + port, i.e., an address/port combination that is not used for + any other virtual host.

    + +

    Server configuration

    + + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +

    + +

    Using such a default vhost with a wildcard port effectively prevents + any request going to the main server.

    + +

    A default vhost never serves a request that was sent to an + address/port that is used for name-based vhosts. If the request + contained an unknown or no Host: header it is always + served from the primary name-based vhost (the vhost for that + address/port appearing first in the configuration file).

    + +

    You can use AliasMatch or + RewriteRule to rewrite any + request to a single information page (or script).

    + + +

    _default_ vhosts + for different ports

    + +

    Same as setup 1, but the server listens on several ports and we want + to use a second _default_ vhost for port 80.

    + +

    Server configuration

    + + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +

    + +

    The default vhost for port 80 (which must appear before any + default vhost with a wildcard port) catches all requests that were sent + to an unspecified IP address. The main server is never used to serve a + request.

    + + +

    _default_ vhosts + for one port

    + +

    We want to have a default vhost for port 80, but no other default + vhosts.

    + +

    Server configuration

    + + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +

    + +

    A request to an unspecified address on port 80 is served from the + default vhost. Any other request to an unspecified address and port is + served from the main server.

    + + +
    top
    +
    +

    Migrating a name-based vhost to an + IP-based vhost

    + +

    The name-based vhost with the hostname + www.example.org (from our name-based example, setup 2) should get its own IP + address. To avoid problems with name servers or proxies who cached the + old IP address for the name-based vhost we want to provide both + variants during a migration phase.

    + +

    + The solution is easy, because we can simply add the new IP address + (172.20.30.50) to the VirtualHost + directive.

    + +

    Server configuration

    + + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +

    + +

    The vhost can now be accessed through the new address (as an + IP-based vhost) and through the old address (as a name-based + vhost).

    + +
    top
    +
    +

    Using the ServerPath + directive

    + +

    We have a server with two name-based vhosts. In order to match the + correct virtual host a client must send the correct Host: + header. Old HTTP/1.0 clients do not send such a header and Apache has + no clue what vhost the client tried to reach (and serves the request + from the primary vhost). To provide as much backward compatibility as + possible we create a primary vhost which returns a single page + containing links with an URL prefix to the name-based virtual + hosts.

    + +

    Server configuration

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +

    + +

    Due to the ServerPath + directive a request to the URL + http://www.sub1.domain.tld/sub1/ is always served + from the sub1-vhost.
    A request to the URL + http://www.sub1.domain.tld/ is only + served from the sub1-vhost if the client sent a correct + Host: header. If no Host: header is sent the + client gets the information page from the primary host.

    + +

    Please note that there is one oddity: A request to + http://www.sub2.domain.tld/sub1/ is also served from the + sub1-vhost if the client sent no Host: header.

    + +

    The RewriteRule directives + are used to make sure that a client which sent a correct + Host: header can use both URL variants, i.e., + with or without URL prefix.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/examples.html.ja.euc-jp b/trunk/docs/manual/vhosts/examples.html.ja.euc-jp new file mode 100644 index 0000000000..7d387eeeb2 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.html.ja.euc-jp @@ -0,0 +1,646 @@ + + + +¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÎã - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÎã

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    ¤³¤Îʸ½ñ¤Ï¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤ÎºÝ¤Ë + ¤è¤¯¤¢¤ë¼ÁÌä¤ËÅú¤¨¤ë¤â¤Î¤Ç¤¹¡£ÁÛÄꤷ¤Æ¤¤¤ëÂÐ¾Ý¤Ï Ì¾Á°¥Ù¡¼¥¹ ¤ä IP ¥Ù¡¼¥¹ ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤Ã¤Æ + °ì¤Ä¤Î¥µ¡¼¥Ð¤ÇÊ£¿ô¤Î¥¦¥§¥Ö¥µ¥¤¥È¤ò±¿ÍѤ·¤Æ¤¤¤ë¾õ¶·¤Ç¤¹¡£ +

    + +
    + +
    top
    +
    +

    °ì¤Ä¤Î IP ¥¢¥É¥ì¥¹¤Ç¤¤¤¯¤Ä¤«¤Î̾Á°¥Ù¡¼¥¹¤Î + ¥¦¥§¥Ö¥µ¥¤¥È¤ò¼Â¹Ô¤¹¤ë

    + +

    ¥µ¡¼¥Ð¤Ï IP ¥¢¥É¥ì¥¹¤ò°ì¤Ä³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Æ¡¢DNS ¤Ç¥Þ¥·¥ó¤Ë + Ê£¿ô¤Î̾Á° (CNAME) ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥Þ¥·¥ó¤Ç + www.example.com ¤È www.example.org + ¤Î¤¿¤á¤Î¥¦¥§¥Ö¥µ¡¼¥Ð¤ò¼Â¹Ô¤µ¤»¤¿¤¤¤È¤·¤Þ¤¹¡£

    + +

    Ãí

    + Apache ¥µ¡¼¥Ð¤ÎÀßÄê¤Ç¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤ò¤·¤¿¤À¤±¤Ç¡¢ + ÃΤé¤Ê¤¤´Ö¤Ë¤½¤Î¥Û¥¹¥È̾¤ËÂбþ¤¹¤ë DNS ¤Î¥¨¥ó¥È¥ê¤¬ + ºîÀ®¤µ¤ì¤¿¤ê¤Ï¤·¤Þ¤»¤ó¡£¤½¤Î¥µ¡¼¥Ð¤Î IP ¥¢¥É¥ì¥¹¤Ë²ò·è¤µ¤ì¤ë + ¤è¤¦¤Ë DNS ¤Ë̾Á°¤òÅÐÏ¿¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤½¤¦¤Ç¤Ê¤¤¤Èï¤â¤¢¤Ê¤¿¤Î¥¦¥§¥Ö¥µ¥¤¥È¤ò¸«¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ + ¥í¡¼¥«¥ë¤Ç¤Î¥Æ¥¹¥È¤Î¤¿¤á¤Ë hosts ¥Õ¥¡¥¤¥ë¤Ë + ¥¨¥ó¥È¥ê¤òÄɲ乤뤳¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤Î¾ì¹ç¤Ï¤½¤Î + hosts ¥¨¥ó¥È¥ê¤Î¤¢¤ë¥Þ¥·¥ó¤«¤é¤·¤«Æ°ºî¤·¤Þ¤»¤ó¡£

    +
    + +

    ¥µ¡¼¥ÐÀßÄê

    + + + # Ensure that Apache listens on port 80
    + Listen 80
    +
    + # Listen for virtual host requests on all IP addresses
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here
    +
    +
    + </VirtualHost> +

    + +

    ¥¢¥¹¥¿¥ê¥¹¥¯¤Ï¤¹¤Ù¤Æ¤Î¥¢¥É¥ì¥¹¤Ë¥Þ¥Ã¥Á¤·¤Þ¤¹¤Î¤Ç¡¢¼ç¥µ¡¼¥Ð¤Ï + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¤¤Þ¤»¤ó¡£www.example.com ¤Ï + ºÇ½é¤Ë¤¢¤ë¤¿¤á¡¢Í¥Àè½ç°Ì¤Ï°ìÈֹ⤯¤Ê¤ê¡¢default ¤â¤·¤¯¤Ï + primary ¤Î¥µ¡¼¥Ð¤È¹Í¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤Ä¤Þ¤ê¡¢¥ê¥¯¥¨¥¹¥È¤¬ + ¤É¤Î ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤â¥Þ¥Ã¥Á¤·¤Ê¤¤¾ì¹ç¡¢ + °ìÈֺǽé¤Î VirtualHost ¤Ë¤è¤ê°·¤ï¤ì¤Þ¤¹¡£

    + +

    Ãí

    + +

    * ¤ò¥·¥¹¥Æ¥à¤Î¼ÂºÝ¤Î IP ¥¢¥É¥ì¥¹¤ËÃÖ¤­´¹¤¨¤ë + ¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤½¤Î¾ì¹ç¤Ï VirtualHost ¤Î°ú¿ô¤Ï + NameVirtualHost ¤Î°ú¿ô¤ÈƱ¤¸¤Ë¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó + :

    + +

    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # etc ... +

    + +

    ¤·¤«¤·¡¢IP ¥¢¥É¥ì¥¹¤¬Í½Â¬ÉÔ²Äǽ¤Ê¥·¥¹¥Æ¥à + ¡½¡½Î㤨¤Ð¥×¥í¥Ð¥¤¥À¤«¤éưŪ¤Ë IP ¥¢¥É¥ì¥¹¤ò¼èÆÀ¤·¤Æ²¿¤é¤«¤Î + ¥À¥¤¥Ê¥ß¥Ã¥¯ DNS ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ê¤É¡½¡½¤Ë¤ª¤¤¤Æ¤Ï¡¢* + »ØÄê¤Ï¤µ¤é¤ËÊØÍø¤Ç¤¹¡£* ¤Ï¤¹¤Ù¤Æ¤Î IP ¥¢¥É¥ì¥¹¤Ë + ¥Þ¥Ã¥Á¤·¤Þ¤¹¤Î¤Ç¡¢¤³¤ÎÀßÄê¤Ë¤·¤Æ¤ª¤±¤Ð IP ¥¢¥É¥ì¥¹¤¬Êѹ¹¤µ¤ì¤Æ¤â + ÀßÄêÊѹ¹¤»¤º¤ËÆ°ºî¤·¤Þ¤¹¡£

    +
    + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥Æ¥£¥ó¥°¤Ç¤Ï¤Û¤Ü¤¹¤Ù¤Æ¤Î¾õ¶·¤Ç¡¢ + ¾åµ­¤ÎÀßÄê¤Ç´õ˾¤ÎÀßÄê¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤Ç¤·¤ç¤¦¡£ + ¼ÂºÝ¤³¤ÎÀßÄ꤬ưºî¤·¤Ê¤¤¤Î¤Ï¡¢IP ¥¢¥É¥ì¥¹¤ä¥Ý¡¼¥È¤Î°ã¤¤¤Ë¤è¤Ã¤Æ + °ã¤¦¥³¥ó¥Æ¥ó¥Ä¤òÁ÷¤ë¤È¤­¤À¤±¤Ç¤¹¡£

    + +
    top
    +
    +

    Ê£¿ô¤Î IP ¥¢¥É¥ì¥¹¤Î¤¢¤ë¥Û¥¹¥È¤Ç̾Á°¥Ù¡¼¥¹¤Î + ¥Û¥¹¥Æ¥£¥ó¥°¤ò¹Ô¤Ê¤¦

    + +
    +

    Ãí

    ¤³¤³¤ÇÀâÌÀ¤µ¤ì¤Æ¤¤¤ëÊýË¡¤Ï IP ¥¢¥É¥ì¥¹¤¬ + ²¿¸Ä¤¢¤Ã¤Æ¤âƱÍͤˤǤ­¤Þ¤¹¡£

    +
    + +

    ¥µ¡¼¥Ð¤Ë¤ÏÆó¤Ä IP ¥¢¥É¥ì¥¹¤¬¤Ä¤¤¤Æ¤¤¤Þ¤¹¡£°ì¤ÄÌÜ + (172.20.30.40) ¤Ç¤Ï¼ç¥µ¡¼¥Ð + server.domain.com ¤ò°·¤¤¡¢¤â¤¦°ìÊý + (172.20.30.50) ¤Ç¤ÏÆó¤Ä¤«¤½¤ì°Ê¾å¤Î¿ô¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò°·¤¤¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + Listen 80
    +
    + # This is the "main" server running on 172.20.30.40
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # This is the other address
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost> +

    + +

    172.20.30.50 °Ê³°¤Î¥¢¥É¥ì¥¹¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¼ç¥µ¡¼¥Ð + ¤¬°·¤¤¤Þ¤¹¡£172.20.30.50 ¤Ø¤Î¡¢Ì¤ÃΤΥۥ¹¥È̾¤Þ¤¿¤Ï + Host: ¥Ø¥Ã¥À¤Ê¤·¤Î¥ê¥¯¥¨¥¹¥È¤Ï www.example.com + ¤¬°·¤¤¤Þ¤¹¡£

    + +
    top
    +
    +

    °ã¤¦ IP ¥¢¥É¥ì¥¹ (Î㤨¤Ð¡¢ÆâÉô¤È³°Éô¥¢¥É¥ì¥¹) + ¤ÇƱ¤¸¥³¥ó¥Æ¥ó¥Ä¤òÁ÷¤ë

    + +

    ¥µ¡¼¥Ð¥Þ¥·¥ó¤Ï IP ¥¢¥É¥ì¥¹¤òÆó¤Ä (192.168.1.1 + ¤È 172.20.30.40) »ý¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥Þ¥·¥ó¤ÏÆâÉô + (¥¤¥ó¥È¥é¥Í¥Ã¥È) ¤È ³°Éô (¥¤¥ó¥¿¡¼¥Í¥Ã¥È) ¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤Î´Ö¤Ë + ¤¢¤ê¤Þ¤¹¡£server.example.com ¤Ï¥Í¥Ã¥È¥ï¡¼¥¯¤Î³°¤«¤é¤Ï + ³°Éô¥¢¥É¥ì¥¹ (172.20.30.40) ¤È¤·¤Æ²ò·è¤µ¤ì¤Þ¤¹¤¬¡¢ + ¥Í¥Ã¥È¥ï¡¼¥¯¤ÎÃ椫¤é¤ÏÆâÉô¥¢¥É¥ì¥¹ (192.168.1.1) + ¤È¤·¤Æ²ò·è¤µ¤ì¤Þ¤¹¡£

    + +

    VirtualHost °ì¤Ä¤À¤±¤Ç¥µ¡¼¥Ð¤¬ÆâÉô¤Î¥ê¥¯¥¨¥¹¥È¤È + ³°Éô¤Î¥ê¥¯¥¨¥¹¥È¤ÎξÊý¤ËƱ¤¸¥³¥ó¥Æ¥ó¥Ä¤Ç±þÅú¤¹¤ë¤è¤¦¤Ë¤Ç¤­¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +

    + +

    ¤³¤ì¤Ç¤É¤Á¤é¤Î¥Í¥Ã¥È¥ï¡¼¥¯¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤âƱ¤¸ VirtualHost + ¤Ç°·¤ï¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +

    Ãí:

    ÆâÉô¥Í¥Ã¥È¥ï¡¼¥¯¤Ç¤Ï´°Á´¤Ê¥Û¥¹¥È̾¤Î + server.example.com ¤ÎÂå¤ï¤ê¤Ë¡¢Ã±¤Ë server + ¤ò»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¾å¤ÎÎã¤Ç¤Ï¡¢IP ¥¢¥É¥ì¥¹¤Î¥ê¥¹¥È¤ò¡¢¤¹¤Ù¤Æ¤Î¥¢¥É¥ì¥¹¤Ë + Ʊ¤¸¥³¥ó¥Æ¥ó¥Ä¤Ç±þÅú¤¹¤ë * ¤ËÃÖ¤­´¹¤¨¤é¤ì¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    °ã¤¦¥Ý¡¼¥È¤Ç°ã¤¦¥µ¥¤¥È¤ò±¿±Ä¤¹¤ë

    + +

    Ʊ¤¸ IP ¤ËÊ£¿ô¤Î¥É¥á¥¤¥ó¤¬¤¢¤ê¡¢¤µ¤é¤ËÊ£¿ô¤Î¥Ý¡¼¥È¤ò»È¤Ã¤Æ + ¥ê¥¯¥¨¥¹¥È¤ò°·¤¤¤¿¤¤¤È¤­¤¬¤¢¤ê¤Þ¤¹¡£"NameVirtualHost" ¥¿¥°¤ÎÃæ¤Ç + ¥Ý¡¼¥È¤òÄêµÁ¤¹¤ë¤³¤È¤Ç¡¢¤³¤ì¤òÆ°ºî¤µ¤»¤é¤ì¤Þ¤¹¡£ + NameVirtualHost name:port ̵¤·¤ä Listen ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + <VirtualHost name:port> ¤ò»È¤ª¤¦¤È¤·¤Æ¤â¡¢¤½¤ÎÀßÄê¤ÏÆ°ºî¤·¤Þ¤»¤ó¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥Æ¥£¥ó¥°

    + +

    ¥µ¡¼¥Ð¤Ï www.example.com ¤È www.example.org + ¤Ë¤½¤ì¤¾¤ì²ò·è¤µ¤ì¤ë¡¢Æó¤Ä¤Î IP ¥¢¥É¥ì¥¹ (172.20.30.40 ¤È + 172.20.30.50) ¤¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +

    <VirtualHost> ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î¤É¤ì¤Ç¤â + »ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤¥¢¥É¥ì¥¹ (Î㤨¤Ð localhost) ¤Ï¡¢ + ¼ç¥µ¡¼¥Ð¤¬¤¢¤ì¤Ð¤½¤³¤Ë¹Ô¤­¤Þ¤¹¡£

    + +
    top
    +
    +

    ¥Ý¡¼¥È¥Ù¡¼¥¹¤È IP ¥Ù¡¼¥¹¤Îº®¤¶¤Ã¤¿ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    ¥µ¡¼¥Ð¥Þ¥·¥ó¤Ï¤½¤ì¤¾¤ì www.example.com ¤È + www.example.org ¤Ë¤½¤ì¤¾¤ì²ò·è¤µ¤ì¤ë¡¢IP ¥¢¥É¥ì¥¹¤òÆó¤Ä + (172.20.30.40 ¤È 172.20.30.50) »ý¤Ã¤Æ¤¤¤Þ¤¹¡£ + ¤É¤Á¤é¤â¥Ý¡¼¥È 80 ¤È 8080 ¤Ç¥Û¥¹¥È¤òÁö¤é¤»¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    ̾Á°¥Ù¡¼¥¹¤È IP ¥Ù¡¼¥¹¤òº®¤¼¤¿ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    ¤¤¤¯¤Ä¤«¤Î¥Þ¥·¥ó¤Ç¤Ï̾Á°¥Ù¡¼¥¹¤Î¡¢¤½¤Î¾¤Ç¤Ï IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë + ¥Û¥¹¥È¤ò¤·¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-based
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    Virtual_host ¤È + mod_proxy ¤òÊ»ÍѤ¹¤ë

    + +

    ¼¡¤ÎÎã¤Ï¡¢¥Õ¥í¥ó¥È¦¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¾¤Î¥Þ¥·¥ó¤Ø¥×¥í¥¯¥·¤·¤Þ¤¹¡£ + Îã¤Ç¤Ï 192.168.111.2 ¤Î¥Þ¥·¥ó¤Ç¤Ï¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È̾¤Ï + Ʊ¤¸Ì¾Á°¤ÇÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£Ê£¿ô¤Î¥Û¥¹¥È̾¤ò°ìÂæ¤Î¥Þ¥·¥ó¤Ë¥×¥í¥¯¥·¤¹¤ë + ¾ì¹ç¤Ï¡¢ProxyPreserveHost On + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¡¢´õ˾¤Î¥Û¥¹¥È̾¤òÅϤ»¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ +

    + +

    + <VirtualHost *:*>
    + ProxyPreserveHost On
    + ProxyPass / http://192.168.111.2
    + ProxyPassReverse / http://192.168.111.2/
    + ServerName hostname.example.com
    + </VirtualHost> +

    + +
    top
    +
    +

    _default_ ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + »È¤¦

    + +

    ¤¹¤Ù¤Æ¤Î¥Ý¡¼¥È¤ËÂФ¹¤ë + _default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    ̤»ØÄê¤Î IP ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¡¢¤Ä¤Þ¤ê¾¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë + »È¤ï¤ì¤Æ¤¤¤Ê¤¤¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÎÁȤ߹ç¤ï¤»¡¢¤Ø¤Î¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ò + ¼õ¤±¼è¤ê¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +

    + +

    ¤³¤Î¤è¤¦¤Ë¥ï¥¤¥ë¥É¥«¡¼¥É¤Î¥Ý¡¼¥È¤Ç¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + »ØÄꤹ¤ë¤È¡¢¼ç¥µ¡¼¥Ð¤Ë¥ê¥¯¥¨¥¹¥È¤¬¹Ô¤¯¤Î¤òËɤ²¤Þ¤¹¡£

    + +

    ¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë + »È¤ï¤ì¤Æ¤¤¤ë¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÎÁȤËÁ÷¤é¤ì¤¿¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤³¤È¤Ï + ¤¢¤ê¤Þ¤»¤ó¡£¥ê¥¯¥¨¥¹¥È¤¬ÉÔÌÀ¤Ê Host: ¥Ø¥Ã¥À¤ä¤½¤Î + ¥Ø¥Ã¥À¤¬¤Ê¤«¤Ã¤¿¤ê¤¹¤ë¾ì¹ç¤Ï´ðËÜ̾Á°¥Ù¡¼¥¹¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È (¤½¤Î + ¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤ÇÀßÄê¥Õ¥¡¥¤¥ëÃæ¤ÇºÇ½é¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È) ¤Ë¤è¤ê + °·¤ï¤ì¤Þ¤¹¡£

    + +

    ¤É¤ó¤Ê¥ê¥¯¥¨¥¹¥È¤Ç¤â AliasMatch + ¤ä RewriteRule ¤ò»È¤Ã¤Æ + ñ°ì¤Î¾ðÊó¥Ú¡¼¥¸ (¤ä¥¹¥¯¥ê¥×¥È) ¤Ë½ñ¤­´¹¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + + +

    °ã¤¦¥Ý¡¼¥È¤Î¤¿¤á¤Î + _default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    °ì¤Ä¤á¤ÎÀßÄê¤È¤Û¤ÜƱ¤¸¤Ç¤¹¤¬¡¢¥µ¡¼¥Ð¤ÏÊ£¿ô¤Î¥Ý¡¼¥È¤ò listen ¤·¤Æ¤ª¤ê¡¢ + 80 È֥ݡ¼¥È¤ËÂФ·¤ÆÆó¤Ä¤á¤Î _default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + ÀßÄꤷ¤¿¤¤¾ì¹ç¤Ç¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +

    + +

    80 È֥ݡ¼¥È¤Î¥Ç¥Õ¥©¥ë¥È¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È (¥ï¥¤¥ë¥É¥«¡¼¥É¥Ý¡¼¥È¤Î + ¥Ç¥Õ¥©¥ë¥È¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤è¤ê¤âÁ°¤Ë½ñ¤«¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó) ¤Ï + ̤»ØÄê¤Î IP ¥¢¥É¥ì¥¹¤ËÁ÷¤é¤ì¤¿¤¹¤Ù¤Æ¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¤¤Þ¤¹¡£ + ¼ç¥µ¡¼¥Ð¤Ï¥ê¥¯¥¨¥¹¥È¤ò°·¤¤¤Þ¤»¤ó¡£

    + + +

    °ì¤Ä¤Î¥Ý¡¼¥È¤ËÂФ·¤Æ¤À¤±¤Î + _default_ ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    + +

    80 È֥ݡ¼¥È¤Ë¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬É¬Íפǡ¢Â¾¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï¥Ç¥Õ¥©¥ë¥È¤¬É¬Íפʤ¤¾ì¹ç¤Ç¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +

    + +

    80 È֥ݡ¼¥È¤Ø¤Î¥¢¥É¥ì¥¹Ì¤»ØÄê¤Î¥ê¥¯¥¨¥¹¥È¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Ð¡¼¥Á¥ã¥ë + ¥Û¥¹¥È¤«¤éÁ÷¤é¤ì¤Þ¤¹¡£Â¾¤Î̤»ØÄê¤Î¥¢¥É¥ì¥¹¤È¥Ý¡¼¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï + ¼ç¥µ¡¼¥Ð¤«¤éÁ÷¤é¤ì¤Þ¤¹¡£

    + + +
    top
    +
    +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤«¤é IP ¥Ù¡¼¥¹¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë°Ü¹Ô¤¹¤ë

    + +

    ¥Û¥¹¥È̾¤¬Ì¾Á° www.example.org ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È + (̾Á°¥Ù¡¼¥¹¤ÎÎã¤Î 2 ÈÖÌܤÎÀßÄê) ¤¬ÀìÍѤΠIP ¥¢¥É¥ì¥¹¤ò + ÆÀ¤¿¤È¤·¤Þ¤¹¡£Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¸Å¤¤ IP ¥¢¥É¥ì¥¹¤ò + ¥­¥ã¥Ã¥·¥å¤·¤Æ¤¤¤ë¥Í¡¼¥à¥µ¡¼¥Ð¤ä¥×¥í¥­¥·¤Î¤¿¤á¤Ë°Ü¹Ô´ü´ÖÃæ¤ÏξÊý¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÄ󶡤·¤¿¤¤¤È¤·¤Þ¤¹¡£

    + +

    Åú¤Ï´Êñ¤Ç¤¹¡£Ã±¤Ë¿·¤·¤¤ IP ¥¢¥É¥ì¥¹ (172.20.30.50) + ¤ò VirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ËÄɲ乤뤳¤È¤Ç + ¤Ç¤­¤Þ¤¹¡£

    + +

    ¥µ¡¼¥ÐÀßÄê

    + + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +

    + +

    ¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï¿·¤·¤¤¥¢¥É¥ì¥¹ (IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤È¤·¤Æ) + ¤È¸Å¤¤¥¢¥É¥ì¥¹(̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤È¤·¤Æ) ¤ÎξÊý¤«¤é + ¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹¡£

    + +
    top
    +
    +

    ServerPath ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + »È¤¦

    + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬Æó¤Ä¤¢¤ë¥µ¡¼¥Ð¤¬¤¢¤ë¤È¤·¤Þ¤¹¡£ + Àµ¤·¤¤¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ÏÀµ¤·¤¤ + Host: ¥Ø¥Ã¥À¤òÁ÷¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¸Å¤¤ HTTP/1.0 ¤Ï¤½¤Î¤è¤¦¤Ê¥Ø¥Ã¥À¤òÁ÷¤é¤Ê¤¤¤Î¤Ç¡¢Apache ¤Ï¥¯¥é¥¤¥¢¥ó¥È¤¬ + ¤É¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò°Õ¿Þ¤·¤¿¤Î¤«¤µ¤Ã¤Ñ¤ê¤ï¤«¤ê¤Þ¤»¤ó + (¤Ê¤Î¤Ç¡¢¼ç¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¥ê¥¯¥¨¥¹¥È¤ò°·¤¤¤Þ¤¹)¡£ + ²Äǽ¤Ê¸Â¤ê¤Î²¼°Ì¸ß´¹À­¤òÆÀ¤ë¤¿¤á¡¢Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î + URL ÀÜƬ¼­¤Ø¤Î¥ê¥ó¥¯¤Î½ñ¤«¤ì¤¿¥Ú¡¼¥¸¤òÊÖ¤¹¡¢ + ¼ç¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬ºîÀ®¤µ¤ì¤Þ¤¹¡£

    + +

    ¥µ¡¼¥Ð¤ÎÀßÄê

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +

    + +

    ServerPath ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÀßÄê¤Ë + ¤è¤ê¡¢URL http://www.sub1.domain.tld/sub1/ ¤Ï + ¾ï¤Ë sub1-vhost ¤Ë¤è¤ê°·¤ï¤ì¤Þ¤¹¡£URL + http://www.sub1.domain.tld/ ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï + ¥¯¥é¥¤¥¢¥ó¥È¤¬Àµ¤·¤¤ Host: ¥Ø¥Ã¥À¤òÁ÷¤Ã¤¿¤È¤­¤Ë¤Î¤ß + sub1-vhost ¤«¤éÁ÷¤é¤ì¤Þ¤¹¡£Host: ¥Ø¥Ã¥À¤¬¤Ê¤±¤ì¤Ð + ¥¯¥é¥¤¥¢¥ó¥È¤Ï¼ç¥Û¥¹¥È¤Î¾ðÊó¥Ú¡¼¥¸¤òÆÀ¤Þ¤¹¡£

    + +

    °ì¤Ä´ñ̯¤ÊÆ°ºî¤ò¤¹¤ëÅÀ¤¬¤¢¤ë¤³¤È¤Ï³Ð¤¨¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£ + http://www.sub2.domain.tld/sub1/ ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤â + Host: ¥Ø¥Ã¥À¤¬¤Ê¤±¤ì¤Ð sub1-vhost ¤Ë¤è¤ê°·¤ï¤ì¤Þ¤¹¡£

    + +

    Àµ¤·¤¤ Host: ¥Ø¥Ã¥À¤òÁ÷¤Ã¤¿¥¯¥é¥¤¥¢¥ó¥È¤Ï¤É¤Á¤é¤Î + URL¡¢¤Ä¤Þ¤êÀÜƬ¼­¤¬¤¢¤ëÊý¤â̵¤¤Êý¤â»È¤¨¤ë¤è¤¦¤Ë + RewriteRule ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ + »È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£

    +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/examples.html.ko.euc-kr b/trunk/docs/manual/vhosts/examples.html.ko.euc-kr new file mode 100644 index 0000000000..78d4cb0acb --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.html.ko.euc-kr @@ -0,0 +1,627 @@ + + + +°¡»óÈ£½ºÆ® ¿¹ - Apache HTTP Server + + + + + +
    <-
    +

    °¡»óÈ£½ºÆ® ¿¹

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ÀÌ ¹®¼­´Â ÀÚÁÖ ¹®ÀǵǴ °¡»óÈ£½ºÆ® + Áú¹®¿¡ ´äÀ» ÇÏ·Á°í ¾²¿©Á³´Ù. »óȲÀº À̸§±â¹ÝÀ̳ª IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÅëÇØ ÇÑ ¼­¹ö¿¡¼­ + ¿©·¯ À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇÏ·Á´Â °æ¿ìÀÌ´Ù. ÇÑ ÇÁ·Ï½Ã ¼­¹ö µÚ¿¡¼­ + ¿©·¯ ¼­¹ö¸¦ »ç¿ëÇÏ¿© »çÀÌÆ®¸¦ ¿î¿µÇÏ´Â °æ¿ì¸¦ ´Ù·é ¹®¼­µµ + °ð ³ª¿Ã °ÍÀÌ´Ù.

    + +
    + +
    top
    +
    +

    IP ÁÖ¼Ò ÇÑ°³¿¡ ¿©·¯ À̸§±â¹Ý + À¥»çÀÌÆ® ¿î¿µÇϱâ.

    + +

    ¼­¹ö¿¡ IP ÁÖ¼Ò°¡ ÇÑ°³ ÀÖ°í, DNS¿¡¼­ ¿©·¯ ÁÖ¼Ò(CNAMES)°¡ + ÀÌ ÄÄÇ»Å͸¦ °¡¸®Å²´Ù. ÀÌ ÄÄÇ»ÅÍ¿¡¼­ www.example.com°ú + www.example.orgÀÇ À¥¼­¹ö¸¦ ½ÇÇàÇÏ°í ½Í´Ù.

    + +

    Note

    ¾ÆÆÄÄ¡ ¼­¹ö¿¡ °¡»óÈ£½ºÆ® ¼³Á¤À» + ÇÑ´Ù°í ±× È£½ºÆ®¸í¿¡ ´ëÇÑ DNS Ç׸ñÀÌ ÀÚµ¿ÀÌ·Î »ý¼ºµÇÁö + ¾Ê´Â´Ù. ¹Ýµå½Ã DNS¿¡ IP ÁÖ¼Ò¸¦ °¡¸®Å°´Â + À̸§ÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ¾È±×·¯¸é ¾Æ¹«µµ À¥»çÀÌÆ®¸¦ º¼ + ¼ö ¾ø´Ù. °Ë»çÇغ¸±â À§ÇØ hosts ÆÄÀÏ¿¡ Ç׸ñÀ» + Ãß°¡ÇÒ ¼ö ÀÖÁö¸¸, ÀÌ´Â hosts Ç׸ñÀ» °¡Áø ÄÄÇ»ÅÍ¿¡¸¸ + ¹Ý¿µµÈ´Ù.

    +
    + +

    ¼­¹ö ¼³Á¤

    + + + # ¾ÆÆÄÄ¡°¡ Æ÷Æ® 80À» ±â´Ù¸°´Ù
    + Listen 80
    +
    + # ¸ðµç IP ÁÖ¼Ò¿¡¼­ °¡»óÈ£½ºÆ® ¿äûÀ» ±â´Ù¸°´Ù
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù
    +
    +
    + </VirtualHost> +

    + +

    º°Ç¥´Â ¸ðµç ÁÖ¼Ò¸¦ °¡¸®Å°¹Ç·Î, ÁÖ¼­¹ö´Â ¾î¶² ¿äûµµ + ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. www.example.comÀÌ + ¼³Á¤ÆÄÀÏ¿¡ óÀ½À¸·Î ³ª¿À¹Ç·Î °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç, + ±âº»È¤Àº Ãʱ⠼­¹ö°¡ µÈ´Ù. + ¾î¶² ServerName Áö½Ã¾î¿¡µµ ÇØ´çµÇÁö¾Ê´Â ¿äûÀº + ù¹ø° VirtualHost°¡ ¼­ºñ½ºÇÑ´Ù.

    + +
    +

    ÁÖÀÇ

    + +

    ¿øÇÑ´Ù¸é * ´ë½Å ½Ã½ºÅÛÀÇ ½ÇÁ¦ IP + ÁÖ¼Ò¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì + VirtualHostÀÇ ¾Æ±Ô¸ÕÆ®´Â + NameVirtualHostÀÇ ¾Æ±Ô¸ÕÆ®¿Í ÀÏÄ¡ÇØ¾ß + ÇÑ´Ù:

    + +

    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # »ý·« ... +

    + +

    ±×·¯³ª ISP¿¡¼­ µ¿ÀûÀ¸·Î IP ÁÖ¼Ò¸¦ °¡Á®¿À´Â µî + IP ÁÖ¼Ò¸¦ ¸ð¸£´Â °æ¿ì¿¡´Â *¸¦ »ç¿ëÇÏ´Â + °ÍÀÌ À¯¿ëÇÏ´Ù. *´Â ¸ðµç IP ÁÖ¼Ò¿¡ + ÇØ´çÇϹǷÎ, IP ÁÖ¼Ò°¡ º¯°æµÇ¾îµµ ¼³Á¤À» º¯°æÇÒ + ÇÊ¿ä°¡ ¾ø´Ù.

    +
    + +

    °ÅÀÇ ´ëºÎºÐÀÇ À̸§±â¹Ý °¡»óÈ£½ºÆ® ¼³Á¤Àº À§¿Í °°´Ù. + ¿¹¿Ü´Â ´Ù¸¥ IP ÁÖ¼Ò³ª Æ÷Æ®·Î ´Ù¸¥ ³»¿ëÀ» ¼­ºñ½ºÇÏ·Á´Â + °æ¿ìÀÌ´Ù.

    + +
    top
    +
    +

    ¿©·¯ IP ÁÖ¼Ò¿¡¼­ À̸§±â¹Ý + È£½ºÆ®.

    + +
    +

    ÁÖÀÇ

    ¿©±â¼­ ¼³¸íÇÑ ¹æ¹ýÀº IP ÁÖ¼Ò°¡ + ¸î°³¶óµµ Àû¿ë°¡´ÉÇÏ´Ù.

    +
    + +

    ¼­¹ö´Â IP ÁÖ¼Ò°¡ µÎ°³ÀÖ´Ù. Çϳª¿¡¼­ + (172.20.30.40) "ÁÖ" ¼­¹ö + server.domain.comÀ» ¼­ºñ½ºÇÏ°í, ´Ù¸¥ Çϳª¿¡¼­ + (172.20.30.50) ¿©·¯ °¡»óÈ£½ºÆ®¸¦ ¼­ºñ½ºÇÒ + °ÍÀÌ´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 80
    +
    + # 172.20.30.40¿¡¼­ ½ÇÇàÇÏ´Â "ÁÖ"¼­¹öÀÌ´Ù
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # ´Ù¸¥ ÁÖ¼Ò´Ù
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù ...
    +
    +
    + </VirtualHost> +

    + +

    172.20.30.50ÀÌ ¾Æ´Ñ ÁÖ¼Ò¿¡ ´ëÇÑ ¿äûÀº + ÁÖ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù. È£½ºÆ®¸í ¾øÀÌ, Áï Host: + Çì´õ¾øÀÌ 172.20.30.50·Î ¿äûÇϸé + www.example.comÀÌ ¼­ºñ½ºÇÑ´Ù.

    + +
    top
    +
    +

    (³»ºÎ¿Í ¿ÜºÎ ÁÖ¼Ò¿Í °°ÀÌ) + ´Ù¸¥ IP ÁÖ¼Ò·Î °°Àº ³»¿ëÀ» ¼­ºñ½ºÇϱâ.

    + +

    ¼­¹ö ÄÄÇ»ÅÍ¿¡ IP ÁÖ¼Ò°¡ µÎ°³ (192.168.1.1°ú + 172.20.30.40) ÀÖ´Ù. ÄÄÇ»ÅÍ´Â ³»ºÎ (ÀÎÆ®¶ó³Ý) + ³×Æ®¿÷°ú ¿ÜºÎ (ÀÎÅͳÝ) ³×Æ®¿÷ »çÀÌ¿¡ À§Ä¡ÇÑ´Ù. ³×Æ®¿÷ ¹Û¿¡¼­ + server.example.comÀº ¿ÜºÎ ÁÖ¼Ò¸¦ + (172.20.30.40) ÀǹÌÇÏ°í, ³×Æ®¿÷ ³»ºÎ¿¡¼­ °°Àº + À̸§À» ³»ºÎ ÁÖ¼Ò·Î (192.168.1.1) »ç¿ëÇÑ´Ù.

    + +

    ¼­¹ö´Â VirtualHost ¼½¼Ç ÇÑ°³·Î ³»ºÎ¿Í ¿ÜºÎ + ÀÀ´ä¿¡ °°Àº ³»¿ëÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +

    + +

    ÀÌÁ¦ µÎ ³×Æ®¿÷¿¡¼­ µé¾î¿Â ¿äûÀ» °°Àº + VirtualHost¿¡¼­ ¼­ºñ½ºÇÑ´Ù.

    + +
    +

    ÁÖÀÇ:

    ³»ºÎ ³×Æ®¿÷¿¡¼­´Â ¿ÏÀüÇÑ È£½ºÆ®¸í + server.example.com ´ë½Å À̸§ + serverµµ °¡´ÉÇÏ´Ù.

    + +

    ¶ÇÇÑ À§ÀÇ ¿¹¿¡¼­ IP ÁÖ¼Ò ´ë½Å *À» + »ç¿ëÇÏ¿© ¼­¹ö°¡ ¸ðµç ÁÖ¼Ò¿¡ µ¿ÀÏÇÏ°Ô µ¿ÀÛÇÒ ¼ö + ÀÖ´Ù.

    +
    + +
    top
    +
    +

    ¿©·¯ Æ÷Æ®¿¡¼­ ¼­·Î ´Ù¸¥ »çÀÌÆ® + ¿î¿µÇϱâ.

    + +

    °°Àº IPÀÇ ¿©·¯ Æ÷Æ®¿¡¼­ ¼­·Î ´Ù¸¥ µµ¸ÞÀÎÀ» ¼­ºñ½ºÇÑ´Ù°í + °¡Á¤ÇÏÀÚ. ÀÌ´Â "NameVirtualHost" ű׿¡ Æ÷Æ®¸¦ Á¤ÀÇÇϸé + °¡´ÉÇÏ´Ù. NameVirtualHost name:port¾øÀÌ <VirtualHost + name:port>¸¸ ȤÀº Listen Áö½Ã¾î¸¸ »ç¿ëÇÏ¸é ¾ÈµÈ´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    IP±â¹Ý °¡»óÈ£½ºÆ®

    + +

    ¼­¹ö´Â °¢°¢ www.example.com°ú + www.example.org¿¡ ÇØ´çÇÏ´Â µÎ IP ÁÖ¼Ò¸¦ + (172.20.30.40°ú 172.20.30.50) + °¡Áø´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +

    <VirtualHost> Áö½Ã¾î·Î ÁöÁ¤ÇÑ ÁÖ¼Ò¿¡ + ÇØ´çÇÏÁö¾Ê´Â ÁÖ¼Ò·Î (¿¹¸¦ µé¾î, localhost) + ¿äûÀÌ µé¾î¿À¸é ÁÖ¼­¹ö°¡ ÀÖ´Â °æ¿ì ÁÖ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù.

    + +
    top
    +
    +

    Æ÷Æ®±â¹Ý°ú ip±â¹ÝÀÌ È¥ÇÕµÈ + °¡»óÈ£½ºÆ®

    + +

    ¼­¹ö´Â °¢°¢ www.example.com°ú + www.example.org¿¡ ÇØ´çÇÏ´Â µÎ IP ÁÖ¼Ò¸¦ + (172.20.30.40°ú 172.20.30.50) + °¡Áø´Ù. °¢ IPÀÇ 80¹ø°ú 8080¹ø Æ÷Æ®¿¡ °¡»óÈ£½ºÆ®¸¦ µ¹¸°´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    À̸§±â¹Ý°ú IP±â¹ÝÀÌ È¥ÇÕµÈ + °¡»óÈ£½ºÆ®

    + +

    ÁÖ¼ÒÁß ¸î¸îÀº À̸§±â¹Ý °¡»óÈ£½ºÆ®·Î, ´Ù¸¥ °ÍÀº IP±â¹Ý + °¡»óÈ£½ºÆ®·Î ¼­ºñ½ºÇÏ°í ½Í´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-±â¹Ý
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +

    + +
    top
    +
    +

    _default_ °¡»óÈ£½ºÆ® + »ç¿ëÇϱâ

    + +

    ¸ðµç Æ÷Æ®¿¡ ´ëÇÑ + _default_ °¡»óÈ£½ºÆ®

    + +

    ¾î¶² °¡»óÈ£½ºÆ®¿¡µµ ÇØ´çÇÏÁö¾ÊÀº IP ÁÖ¼Ò¿Í Æ÷Æ®¿¡ ´ëÇÑ + ¸ðµç ¿äûÀ» ó¸®Çϱâ.

    + +

    ¼­¹ö ¼³Á¤

    + + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +

    + +

    default(±âº») °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ®·Î ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ¿© ¾î¶² ¿äûµµ + ÁÖ¼­¹ö·Î ¸ø°¡µµ·Ï ¸¸µç´Ù.

    + +

    default °¡»óÈ£½ºÆ®´Â Àý´ë·Î À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ »ç¿ëÇÏ´Â + ÁÖ¼Ò/Æ÷Æ®·ÎÀÇ ¿äûÀ» ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. ¾Ë ¼ö ¾ø°Å³ª + Host: Çì´õ°¡ »ý·«µÈ ¿äûÀº Ç×»ó ÃÖÃÊÀÇ À̸§±â¹Ý + °¡»óÈ£½ºÆ®(¼³Á¤ÆÄÀÏ¿¡¼­ + ÁÖ¼Ò/Æ÷Æ®°¡ óÀ½À¸·Î ³ª¿Â °¡»óÈ£½ºÆ®)°¡ ¼­ºñ½ºÇÑ´Ù.

    + +

    AliasMatch³ª + RewriteRuleÀ» + »ç¿ëÇÏ¿© ¾î¶² ¿äûÀ» ƯÁ¤ ÆäÀÌÁö(ȤÀº ½ºÅ©¸³Æ®)·Î + ÀçÀÛ¼ºÇÒ(rewrite) ¼ö ÀÖ´Ù.

    + + +

    ¿©·¯ Æ÷Æ®¿¡ ´ëÇÑ + _default_ °¡»óÈ£½ºÆ®

    + +

    À§ÀÇ °æ¿ì¿Í °°Áö¸¸, ¼­¹ö´Â ¿©·¯ Æ÷Æ®¸¦ ±â´Ù¸®°í 80¹ø + Æ÷Æ®¿¡ ´ëÇؼ­ Ãß°¡·Î _default_ °¡»óÈ£½ºÆ®¸¦ + »ç¿ëÇÏ°í ½Í´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +

    + +

    80¹ø Æ÷Æ®¿¡ ´ëÇÑ default °¡»óÈ£½ºÆ®´Â (¹Ýµå½Ã + ¿ÍÀϵåÄ«µå Æ÷Æ®¸¦ °¡Áø ±âº» °¡»óÈ£½ºÆ® ÀÌÀü¿¡ ³ª¿Í¾ß ÇÑ´Ù) + ÁöÁ¤ÇÏÁö¾ÊÀº IP ÁÖ¼Ò·Î º¸³»Áø ¸ðµç ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. + ÁÖ¼­¹ö´Â Àý´ë·Î ¿äûÀ» ¼­ºñ½ºÇÏÁö ¸øÇÑ´Ù.

    + + +

    ÇÑ Æ÷Æ®¿¡ ´ëÇÑ + _default_ °¡»óÈ£½ºÆ®

    + +

    80¹ø Æ÷Æ®¿¡ ´ëÇؼ­¸¸ default °¡»óÈ£½ºÆ®¸¦ ¸¸µé°í ½Í´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +

    + +

    Æ÷Æ® 80¹ø¿¡ ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò¿¡ ´ëÇÑ ¿äûÀº ±âº» + °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÏ°í, ´Ù¸¥ ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò¿Í Æ÷Æ®¸¦ + °¡Áø ¿äûÀº ÁÖ ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù.

    + + +
    top
    +
    +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ IP±â¹Ý + °¡»óÈ£½ºÆ®·Î ¿Å±â±â

    + +

    (À̸§±â¹ÝÀÇ Ã¹¹ø° ¿¹¿¡¼­) È£½ºÆ®¸í + www.example.org¿¡ ´ëÇÑ À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â + ÀÚ½ÅÀÇ IP ÁÖ¼Ò¸¦ °¡Á®¾ß ÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ ÀÌÀü + IP ÁÖ¼Ò¸¦ ij½ÌÇÏ´Â ³×ÀÓ¼­¹ö³ª ÇÁ·Ï½Ã¿ÍÀÇ ¹®Á¦¸¦ ÇÇÇϱâÀ§ÇØ + ¿Å±â´Â µ¿¾È µÑ ¸ðµÎ¸¦ ¼­ºñ½ºÇÏ°í ½Í´Ù.

    + +

    + ¹æ¹ýÀº VirtualHost Áö½Ã¾î¿¡ »õ IP ÁÖ¼Ò¸¸À» + (172.20.30.50) Ãß°¡ÇϸéµÇ¹Ç·Î ½±´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +

    + +

    ÀÌÁ¦ (IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÅëÇÑ) »õ·Î¿î ÁÖ¼Ò¿Í (À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ ÅëÇÑ) ÀÌÀü ÁÖ¼Ò ¸ðµÎ °¡»óÈ£½ºÆ®¿¡ Á¢±ÙÇÒ + ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    ServerPath + Áö½Ã¾î »ç¿ëÇϱâ

    + +

    µÎ À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ °¡Áø ¼­¹ö°¡ ÀÖ´Ù. ¿Ã¹Ù¸¥ + °¡»óÈ£½ºÆ®¸¦ ¼±ÅÃÇϱâÀ§ÇØ Å¬¶óÀ̾ðÆ®´Â ¿Ã¹Ù¸¥ + Host: Çì´õ¸¦ º¸³»¾ß ÇÑ´Ù. ¿À·¡µÈ HTTP/1.0 + Ŭ¶óÀ̾ðÆ®°¡ ÀÌ Çì´õ¸¦ º¸³»Áö ¸øÇÏ¸é ¾ÆÆÄÄ¡´Â Ŭ¶óÀ̾ðÆ®°¡ + ¾î¶² °¡»óÈ£½ºÆ®¸¦ º¸·Á°íÇÏ´ÂÁö ¾Ë ¼ö ¾ø´Ù (±×·¡¼­ ÃÖÃÊÀÇ + °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù). ¿À·¡µÈ ºê¶ó¿ìÀú¿Í °¡´ÉÇÑ È£È¯À» + À¯ÁöÇϱâÀ§ÇØ ÃÖÃÊÀÇ °¡»óÈ£½ºÆ®¸¦ ¸¸µé°í, ¿©±â¿¡ À̸§±â¹Ý + °¡»óÈ£½ºÆ®ÀÇ URL Á¢µÎ»ç¸¦ Æ÷ÇÔÇÏ´Â ¸µÅ© ¸ñ·Ï ÆäÀÌÁö¸¦ + µÐ´Ù.

    + +

    ¼­¹ö ¼³Á¤

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +

    + +

    ServerPath Áö½Ã¾î¶§¹®¿¡ + URL http://www.sub1.domain.tld/sub1/¿¡ ´ëÇÑ + ¿äûÀº Ç×»ó subl-°¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù.
    + Ŭ¶óÀ̾ðÆ®°¡ ¿Ã¹Ù¸¥ Host: Çì´õ¸¦ º¸³½´Ù¸é, + URL http://www.sub1.domain.tld/¿¡ ´ëÇÑ ¿äûÀº + subl-°¡»óÈ£½ºÆ®¿¡¼­¸¸ ¼­ºñ½ºÇÑ´Ù. ¸¸¾à Host: Çì´õ¸¦ + º¸³»Áö¾ÊÀ¸¸é Ŭ¶óÀ̾ðÆ®´Â ÃÖÃÊÀÇ È£½ºÆ®¿¡ ÀÖ´Â Á¤º¸ÆäÀÌÁö¸¦ + º¸°ÔµÈ´Ù.

    + +

    ¿©±â¿¡ ¹®Á¦°¡ ÀÖÀ½À» ÁÖÀÇÇ϶ó: Ŭ¶óÀ̾ðÆ®°¡ + Host: Çì´õ¸¦ º¸³»Áö¾ÊÀ¸¸é + http://www.sub2.domain.tld/sub1/¿¡ ´ëÇÑ ¿äûµµ + subl-°¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù.

    + +

    RewriteRule + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿Ã¹Ù¸¥ Host: Çì´õ¸¦ º¸³»´Â + Ŭ¶óÀ̾ðÆ®´Â (¿¹¸¦ µé¾î, URL ÀüÄ¡»ç°¡ Àְųª ¾ø´Â) + µÎ URLÀ» ¸ðµÎ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/examples.xml b/trunk/docs/manual/vhosts/examples.xml new file mode 100644 index 0000000000..5f4b1a26b7 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.xml @@ -0,0 +1,634 @@ + + + + + + + + +Virtual Hosts + VirtualHost Examples + + + +

    This document attempts to answer the commonly-asked questions about + setting up virtual hosts. These scenarios are those involving multiple + web sites running on a single server, via name-based or IP-based virtual hosts. +

    + +
    + +
    Running several name-based web + sites on a single IP address. + +

    Your server has a single IP address, and multiple aliases (CNAMES) + point to this machine in DNS. You want to run a web server for + www.example.com and www.example.org on this + machine.

    + + Note

    Creating virtual + host configurations on your Apache server does not magically + cause DNS entries to be created for those host names. You + must have the names in DNS, resolving to your IP + address, or nobody else will be able to see your web site. You + can put entries in your hosts file for local + testing, but that will work only from the machine with those + hosts entries.

    +
    + + + Server configuration + + # Ensure that Apache listens on port 80
    + Listen 80
    +
    + # Listen for virtual host requests on all IP addresses
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here
    +
    +
    + </VirtualHost> +
    + +

    The asterisks match all addresses, so the main server serves no + requests. Due to the fact that www.example.com is first + in the configuration file, it has the highest priority and can be seen + as the default or primary server. That means + that if a request is received that does not match one of the specified + ServerName directives, it will be served by this first + VirtualHost.

    + + + Note + +

    You can, if you wish, replace * with the actual + IP address of the system. In that case, the argument to + VirtualHost must match the argument to + NameVirtualHost:

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # etc ... +
    + +

    However, it is additionally useful to use * + on systems where the IP address is not predictable - for + example if you have a dynamic IP address with your ISP, and + you are using some variety of dynamic DNS solution. Since + * matches any IP address, this configuration + would work without changes whenever your IP address + changes.

    +
    + +

    The above configuration is what you will want to use in almost + all name-based virtual hosting situations. The only thing that this + configuration will not work for, in fact, is when you are serving + different content based on differing IP addresses or ports.

    + +
    + +
    Name-based hosts on more than one + IP address. + + + Note

    Any of the + techniques discussed here can be extended to any number of IP + addresses.

    +
    + +

    The server has two IP addresses. On one (172.20.30.40), we + will serve the "main" server, server.domain.com and on the + other (172.20.30.50), we will serve two or more virtual hosts.

    + + + Server configuration + + Listen 80
    +
    + # This is the "main" server running on 172.20.30.40
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # This is the other address
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost> +
    + +

    Any request to an address other than 172.20.30.50 will be + served from the main server. A request to 172.20.30.50 with an + unknown hostname, or no Host: header, will be served from + www.example.com.

    + +
    + +
    Serving the same content on + different IP addresses (such as an internal and external + address). + +

    The server machine has two IP addresses (192.168.1.1 + and 172.20.30.40). The machine is sitting between an + internal (intranet) network and an external (internet) network. Outside + of the network, the name server.example.com resolves to + the external address (172.20.30.40), but inside the + network, that same name resolves to the internal address + (192.168.1.1).

    + +

    The server can be made to respond to internal and external requests + with the same content, with just one VirtualHost + section.

    + + + Server configuration + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +
    + +

    Now requests from both networks will be served from the same + VirtualHost.

    + + + Note:

    On the internal + network, one can just use the name server rather + than the fully qualified host name + server.example.com.

    + +

    Note also that, in the above example, you can replace the list + of IP addresses with *, which will cause the server to + respond the same on all addresses.

    +
    + +
    + +
    Running different sites on different + ports. + +

    You have multiple domains going to the same IP and also want to + serve multiple ports. By defining the ports in the "NameVirtualHost" + tag, you can allow this to work. If you try using <VirtualHost + name:port> without the NameVirtualHost name:port or you try to use + the Listen directive, your configuration will not work.

    + + + Server configuration + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +
    + +
    + +
    IP-based virtual hosting + +

    The server has two IP addresses (172.20.30.40 and + 172.20.30.50) which resolve to the names + www.example.com and www.example.org + respectively.

    + + + Server configuration + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +

    Requests for any address not specified in one of the + <VirtualHost> directives (such as + localhost, for example) will go to the main server, if + there is one.

    + +
    + +
    Mixed port-based and ip-based virtual + hosts + +

    The server machine has two IP addresses (172.20.30.40 and + 172.20.30.50) which resolve to the names + www.example.com and www.example.org + respectively. In each case, we want to run hosts on ports 80 and + 8080.

    + + + Server configuration + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +
    + +
    Mixed name-based and IP-based + vhosts + +

    On some of my addresses, I want to do name-based virtual hosts, and + on others, IP-based hosts.

    + + + Server configuration + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-based
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +
    + +
    + +
    Using <code>Virtual_host</code> and + mod_proxy together + +

    The following example allows a front-end machine to proxy a + virtual host through to a server running on another machine. In the + example, a virtual host of the same name is configured on a machine + at 192.168.111.2. The ProxyPreserveHost On directive is + used so that the desired hostname is passed through, in case we are + proxying multiple hostnames to a single machine.

    + + + <VirtualHost *:*>
    + ProxyPreserveHost On
    + ProxyPass / http://192.168.111.2
    + ProxyPassReverse / http://192.168.111.2/
    + ServerName hostname.example.com
    + </VirtualHost> +
    + +
    + +
    Using <code>_default_</code> + vhosts + +
    <code>_default_</code> vhosts + for all ports + +

    Catching every request to any unspecified IP address and + port, i.e., an address/port combination that is not used for + any other virtual host.

    + + + Server configuration + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +
    + +

    Using such a default vhost with a wildcard port effectively prevents + any request going to the main server.

    + +

    A default vhost never serves a request that was sent to an + address/port that is used for name-based vhosts. If the request + contained an unknown or no Host: header it is always + served from the primary name-based vhost (the vhost for that + address/port appearing first in the configuration file).

    + +

    You can use AliasMatch or + RewriteRule to rewrite any + request to a single information page (or script).

    +
    + +
    <code>_default_</code> vhosts + for different ports + +

    Same as setup 1, but the server listens on several ports and we want + to use a second _default_ vhost for port 80.

    + + + Server configuration + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +
    + +

    The default vhost for port 80 (which must appear before any + default vhost with a wildcard port) catches all requests that were sent + to an unspecified IP address. The main server is never used to serve a + request.

    +
    + +
    <code>_default_</code> vhosts + for one port + +

    We want to have a default vhost for port 80, but no other default + vhosts.

    + + + Server configuration + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +
    + +

    A request to an unspecified address on port 80 is served from the + default vhost. Any other request to an unspecified address and port is + served from the main server.

    +
    + +
    + +
    Migrating a name-based vhost to an + IP-based vhost + +

    The name-based vhost with the hostname + www.example.org (from our name-based example, setup 2) should get its own IP + address. To avoid problems with name servers or proxies who cached the + old IP address for the name-based vhost we want to provide both + variants during a migration phase.

    + +

    + The solution is easy, because we can simply add the new IP address + (172.20.30.50) to the VirtualHost + directive.

    + + + Server configuration + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +
    + +

    The vhost can now be accessed through the new address (as an + IP-based vhost) and through the old address (as a name-based + vhost).

    + +
    + +
    Using the <code>ServerPath</code> + directive + +

    We have a server with two name-based vhosts. In order to match the + correct virtual host a client must send the correct Host: + header. Old HTTP/1.0 clients do not send such a header and Apache has + no clue what vhost the client tried to reach (and serves the request + from the primary vhost). To provide as much backward compatibility as + possible we create a primary vhost which returns a single page + containing links with an URL prefix to the name-based virtual + hosts.

    + + + Server configuration + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +
    + +

    Due to the ServerPath + directive a request to the URL + http://www.sub1.domain.tld/sub1/ is always served + from the sub1-vhost.
    A request to the URL + http://www.sub1.domain.tld/ is only + served from the sub1-vhost if the client sent a correct + Host: header. If no Host: header is sent the + client gets the information page from the primary host.

    + +

    Please note that there is one oddity: A request to + http://www.sub2.domain.tld/sub1/ is also served from the + sub1-vhost if the client sent no Host: header.

    + +

    The RewriteRule directives + are used to make sure that a client which sent a correct + Host: header can use both URL variants, i.e., + with or without URL prefix.

    + +
    + +
    diff --git a/trunk/docs/manual/vhosts/examples.xml.ja b/trunk/docs/manual/vhosts/examples.xml.ja new file mode 100644 index 0000000000..0e1b903c74 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.xml.ja @@ -0,0 +1,622 @@ + + + + + + + + +$B%P!<%A%c%k%[%9%H(B + $B%P!<%A%c%k%[%9%H$NNc(B + + + +

    $B$3$NJ8=q$O!"%P!<%A%c%k%[%9%H$N@_Dj$N:]$K(B + $B$h$/$"$k]$O(B $BL>A0%Y!<%9(B $B$d(B IP $B%Y!<%9(B $B$N%P!<%A%c%k%[%9%H$r;H$C$F(B + $B0l$D$N%5!<%P$GJ#?t$N%&%'%V%5%$%H$r1?MQ$7$F$$$k>u67$G$9!#(B +

    + +
    + +
    $B0l$D$N(B IP $B%"%I%l%9$G$$$/$D$+$NL>A0%Y!<%9$N(B + $B%&%'%V%5%$%H$r<B9T$9$k(B + +

    $B%5!<%P$O(B IP $B%"%I%l%9$r0l$D3d$jEv$F$i$l$F$$$F!"(BDNS $B$G%^%7%s$K(B + $BJ#?t$NL>A0(B (CNAME) $B$,;XDj$5$l$F$$$^$9!#$3$N%^%7%s$G(B + www.example.com $B$H(B www.example.org + $B$N$?$a$N%&%'%V%5!<%P$r + + $BCm(B

    + Apache $B%5!<%P$N@_Dj$G%P!<%A%c%k%[%9%H$N@_Dj$r$7$?$@$1$G!"(B + $BCN$i$J$$4V$K$=$N%[%9%HL>$KBP1~$9$k(B DNS $B$N%(%s%H%j$,(B + $B:n@.$5$l$?$j$O$7$^$;$s!#$=$N%5!<%P$N(B IP $B%"%I%l%9$K2r7h$5$l$k(B + $B$h$&$K(B DNS $B$KL>A0$rEPO?$7$J$1$l$P(B$B$J$j$^$;$s(B$B!#(B + $B$=$&$G$J$$$HC/$b$"$J$?$N%&%'%V%5%$%H$r8+$k$3$H$O$G$-$^$;$s!#(B + $B%m!<%+%k$G$N%F%9%H$N$?$a$K(B hosts $B%U%!%$%k$K(B + $B%(%s%H%j$rDI2C$9$k$3$H$b$G$-$^$9$,!"$3$N>l9g$O$=$N(B + hosts $B%(%s%H%j$N$"$k%^%7%s$+$i$7$+F0:n$7$^$;$s!#(B

    + + + + $B%5!<%P@_Dj(B + + # Ensure that Apache listens on port 80
    + Listen 80
    +
    + # Listen for virtual host requests on all IP addresses
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here
    +
    +
    + </VirtualHost> +
    + +

    $B%"%9%?%j%9%/$O$9$Y$F$N%"%I%l%9$K%^%C%A$7$^$9$N$G!"www.example.com $B$O(B + $B:G=i$K$"$k$?$a!"M%@h=g0L$O0lHV9b$/$J$j!"(Bdefault $B$b$7$/$O(B + primary $B$N%5!<%P$H9M$($k$3$H$,$G$-$^$9!#$D$^$j!"%j%/%(%9%H$,(B + $B$I$N(B ServerName $B%G%#%l%/%F%#%V$K$b%^%C%A$7$J$$>l9g!"(B + $B0lHV:G=i$N(B VirtualHost $B$K$h$j07$o$l$^$9!#(B

    + + $BCm(B + +

    * $B$r%7%9%F%`$Nl9g$O(B VirtualHost $B$N0z?t$O(B + NameVirtualHost $B$N0z?t$HF1$8$K(B$B$7$J$1$l$P$J$j$^$;$s(B + :

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # etc ... +
    + +

    $B$7$+$7!"(BIP $B%"%I%l%9$,M=B,IT2DG=$J%7%9%F%`(B + $B!=!=Nc$($P%W%m%P%$%@$+$iF0E*$K(B IP $B%"%I%l%9$rl9g$J$I!=!=$K$*$$$F$O!"(B* + $B;XDj$O$5$i$KJXMx$G$9!#(B* $B$O$9$Y$F$N(B IP $B%"%I%l%9$K(B + $B%^%C%A$7$^$9$N$G!"$3$N@_Dj$K$7$F$*$1$P(B IP $B%"%I%l%9$,JQ99$5$l$F$b(B + $B@_DjJQ99$;$:$KF0:n$7$^$9!#(B

    +
    + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%F%#%s%0$G$O$[$\$9$Y$F$N>u67$G!"(B + $B>e5-$N@_Dj$G4uK>$N@_Dj$K$J$C$F$$$k$3$H$G$7$g$&!#(B + $B + +

    + +
    $BJ#?t$N(B IP $B%"%I%l%9$N$"$k%[%9%H$GL>A0%Y!<%9$N(B + $B%[%9%F%#%s%0$r9T$J$&(B + + + $BCm(B

    $B$3$3$G@bL@$5$l$F$$$kJ}K!$O(B IP $B%"%I%l%9$,(B + $B2?8D$"$C$F$bF1MM$K$G$-$^$9!#(B

    +
    + +

    $B%5!<%P$K$OFs$D(B IP $B%"%I%l%9$,$D$$$F$$$^$9!#0l$DL\(B + (172.20.30.40) $B$G$Oserver.domain.com $B$r07$$!"$b$&0lJ}(B + (172.20.30.50) $B$G$OFs$D$+$=$l0J>e$N?t$N(B + $B%P!<%A%c%k%[%9%H$r07$$$^$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + Listen 80
    +
    + # This is the "main" server running on 172.20.30.40
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # This is the other address
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # Other directives here ...
    +
    +
    + </VirtualHost> +
    + +

    172.20.30.50 $B0J30$N%"%I%l%9$X$N%j%/%(%9%H$O172.20.30.50 $B$X$N!"L$CN$N%[%9%HL>$^$?$O(B + Host: $B%X%C%@$J$7$N%j%/%(%9%H$O(B www.example.com + $B$,07$$$^$9!#(B

    + +
    + +
    $B0c$&(B IP $B%"%I%l%9(B ($BNc$($P!"FbIt$H30It%"%I%l%9(B) + $B$GF1$8%3%s%F%s%D$rAw$k(B + +

    $B%5!<%P%^%7%s$O(B IP $B%"%I%l%9$rFs$D(B (192.168.1.1 + $B$H(B 172.20.30.40) $B;}$C$F$$$^$9!#$3$N%^%7%s$OFbIt(B + ($B%$%s%H%i%M%C%H(B) $B$H(B $B30It(B ($B%$%s%?!<%M%C%H(B) $B$N%M%C%H%o!<%/$N4V$K(B + $B$"$j$^$9!#(Bserver.example.com $B$O%M%C%H%o!<%/$N30$+$i$O(B + $B30It%"%I%l%9(B (172.20.30.40) $B$H$7$F2r7h$5$l$^$9$,!"(B + $B%M%C%H%o!<%/$NCf$+$i$OFbIt%"%I%l%9(B (192.168.1.1) + $B$H$7$F2r7h$5$l$^$9!#(B

    + +

    VirtualHost $B0l$D$@$1$G%5!<%P$,FbIt$N%j%/%(%9%H$H(B + $B30It$N%j%/%(%9%H$NN>J}$KF1$8%3%s%F%s%D$G1~Ez$9$k$h$&$K$G$-$^$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +
    + +

    $B$3$l$G$I$A$i$N%M%C%H%o!<%/$+$i$N%j%/%(%9%H$bF1$8(B VirtualHost + $B$G07$o$l$k$h$&$K$J$j$^$9!#(B

    + + $BCm(B:

    $BFbIt%M%C%H%o!<%/$G$O40A4$J%[%9%HL>$N(B + server.example.com $B$NBe$o$j$K!"C1$K(B server + $B$r;H$&$3$H$,$G$-$^$9!#(B

    + +

    $B>e$NNc$G$O!"(BIP $B%"%I%l%9$N%j%9%H$r!"$9$Y$F$N%"%I%l%9$K(B + $BF1$8%3%s%F%s%D$G1~Ez$9$k(B * $B$KCV$-49$($i$l$^$9!#(B

    +
    + +
    + +
    $B0c$&%]!<%H$G0c$&%5%$%H$r1?1D$9$k(B + +

    $BF1$8(B IP $B$KJ#?t$N%I%a%$%s$,$"$j!"$5$i$KJ#?t$N%]!<%H$r;H$C$F(B + $B%j%/%(%9%H$r07$$$?$$$H$-$,$"$j$^$9!#(B"NameVirtualHost" $B%?%0$NCf$G(B + $B%]!<%H$rDj5A$9$k$3$H$G!"$3$l$rF0:n$5$;$i$l$^$9!#(B + NameVirtualHost name:port $BL5$7$d(B Listen $B%G%#%l%/%F%#%V$G(B + <VirtualHost name:port> $B$r;H$*$&$H$7$F$b!"$=$N@_Dj$OF0:n$7$^$;$s!#(B

    + + + $B%5!<%P$N@_Dj(B + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +
    + +
    + +
    IP $B%Y!<%9$N%P!<%A%c%k%[%9%F%#%s%0(B + +

    $B%5!<%P$O(B www.example.com $B$H(B www.example.org + $B$K$=$l$>$l2r7h$5$l$k!"Fs$D$N(B IP $B%"%I%l%9(B (172.20.30.40 $B$H(B + 172.20.30.50) $B$,$"$j$^$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +

    <VirtualHost> $B%G%#%l%/%F%#%V$N$I$l$G$b(B + $B;XDj$5$l$F$$$J$$%"%I%l%9(B ($BNc$($P(B localhost) $B$O!"(B + $B + +

    + +
    $B%]!<%H%Y!<%9$H(B IP $B%Y!<%9$N:.$6$C$?(B + $B%P!<%A%c%k%[%9%H(B + +

    $B%5!<%P%^%7%s$O$=$l$>$l(B www.example.com $B$H(B + www.example.org $B$K$=$l$>$l2r7h$5$l$k!"(BIP $B%"%I%l%9$rFs$D(B + (172.20.30.40 $B$H(B 172.20.30.50) $B;}$C$F$$$^$9!#(B + $B$I$A$i$b%]!<%H(B 80 $B$H(B 8080 $B$G%[%9%H$rAv$i$;$^$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +
    + +
    $BL>A0%Y!<%9$H(B IP $B%Y!<%9$r:.$<$?(B + $B%P!<%A%c%k%[%9%H(B + +

    $B$$$/$D$+$N%^%7%s$G$OL>A0%Y!<%9$N!"$=$NB>$G$O(B IP $B%Y!<%9$N%P!<%A%c%k(B + $B%[%9%H$r$7$^$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-based
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +
    + +
    + +
    <code>Virtual_host</code> $B$H(B + mod_proxy $B$rJ;MQ$9$k(B + +

    $B$N%^%7%s$X%W%m%/%7$7$^$9!#(B + $BNc$G$O(B 192.168.111.2 $B$N%^%7%s$G$O%P!<%A%c%k%[%9%HL>$O(B + $BF1$8L>A0$G@_Dj$5$l$F$$$^$9!#J#?t$N%[%9%HL>$r0lBf$N%^%7%s$K%W%m%/%7$9$k(B + $B>l9g$O!"(BProxyPreserveHost On + $B%G%#%l%/%F%#%V$r;H$C$F!"4uK>$N%[%9%HL>$rEO$;$k$h$&$K$J$j$^$9!#(B +

    + + + <VirtualHost *:*>
    + ProxyPreserveHost On
    + ProxyPass / http://192.168.111.2
    + ProxyPassReverse / http://192.168.111.2/
    + ServerName hostname.example.com
    + </VirtualHost> +
    + +
    + +
    <code>_default_</code> $B$N%P!<%A%c%k%[%9%H$r(B + $B;H$&(B + +
    $B$9$Y$F$N%]!<%H$KBP$9$k(B + <code>_default_</code> $B%P!<%A%c%k%[%9%H(B + +

    $BL$;XDj$N(B IP $B%"%I%l%9$H%]!<%H!"(B$B$D$^$j(B$BB>$N%P!<%A%c%k%[%9%H$K(B + $B;H$o$l$F$$$J$$%"%I%l%9$H%]!<%H$NAH$_9g$o$;!"$X$N(B$B$9$Y$F$N(B$B%j%/%(%9%H$r(B + $B + + + $B%5!<%P$N@_Dj(B + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +
    + +

    $B$3$N$h$&$K%o%$%k%I%+!<%I$N%]!<%H$G%G%U%)%k%H$N%P!<%A%c%k%[%9%H$r(B + $B;XDj$9$k$H!" + +

    $B%G%U%)%k%H$N%P!<%A%c%k%[%9%H$OL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$K(B + $B;H$o$l$F$$$k%"%I%l%9$H%]!<%H$NAH$KAw$i$l$?%j%/%(%9%H$r07$&$3$H$O(B + $B$"$j$^$;$s!#%j%/%(%9%H$,ITL@$J(B Host: $B%X%C%@$d$=$N(B + $B%X%C%@$,$J$+$C$?$j$9$k>l9g$O4pK\L>A0%Y!<%9%P!<%A%c%k%[%9%H(B ($B$=$N(B + $B%"%I%l%9$H%]!<%H$G@_Dj%U%!%$%kCf$G:G=i$N%P!<%A%c%k%[%9%H(B) $B$K$h$j(B + $B07$o$l$^$9!#(B

    + +

    $B$I$s$J%j%/%(%9%H$G$b(B AliasMatch + $B$d(B RewriteRule $B$r;H$C$F(B + $BC10l$N>pJs%Z!<%8(B ($B$d%9%/%j%W%H(B) $B$K=q$-49$($k$3$H$,$G$-$^$9!#(B

    +
    + +
    $B0c$&%]!<%H$N$?$a$N(B + <code>_default_</code> $B%P!<%A%c%k%[%9%H(B + +

    $B0l$D$a$N@_Dj$H$[$\F1$8$G$9$,!"%5!<%P$OJ#?t$N%]!<%H$r(B listen $B$7$F$*$j!"(B + 80 $BHV%]!<%H$KBP$7$FFs$D$a$N(B _default_ $B%P!<%A%c%k%[%9%H$r(B + $B@_Dj$7$?$$>l9g$G$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +
    + +

    80 $BHV%]!<%H$N%G%U%)%k%H%P!<%A%c%k%[%9%H(B ($B%o%$%k%I%+!<%I%]!<%H$N(B + $B%G%U%)%k%H%P!<%A%c%k%[%9%H$h$j$bA0$K=q$+$l$F$$$J$1$l$P(B$B$J$j$^$;$s(B) $B$O(B + $BL$;XDj$N(B IP $B%"%I%l%9$KAw$i$l$?$9$Y$F$N%j%/%(%9%H$r07$$$^$9!#(B + $B +

    + +
    $B0l$D$N%]!<%H$KBP$7$F$@$1$N(B + <code>_default_</code> $B%P!<%A%c%k%[%9%H(B + +

    80 $BHV%]!<%H$K$O%G%U%)%k%H$N%P!<%A%c%k%[%9%H$,I,MW$G!"B>$N(B + $B%P!<%A%c%k%[%9%H$O%G%U%)%k%H$,I,MW$J$$>l9g$G$9!#(B

    + + + $B%5!<%P$N@_Dj(B + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +
    + +

    80 $BHV%]!<%H$X$N%"%I%l%9L$;XDj$N%j%/%(%9%H$O%G%U%)%k%H$N%P!<%A%c%k(B + $B%[%9%H$+$iAw$i$l$^$9!#B>$NL$;XDj$N%"%I%l%9$H%]!<%H$X$N%j%/%(%9%H$O(B + $B +

    + +
    + +
    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$+$i(B IP $B%Y!<%9$N(B + $B%P!<%A%c%k%[%9%H$K0\9T$9$k(B + +

    $B%[%9%HL>$,L>A0(B www.example.org $B$N%P!<%A%c%k%[%9%H(B + ($BL>A0%Y!<%9(B$B$NNc$N(B 2 $BHVL\$N@_Dj(B) $B$,@lMQ$N(B IP $B%"%I%l%9$r(B + $BF@$?$H$7$^$9!#L>A0%Y!<%9$N%P!<%A%c%k%[%9%H$N8E$$(B IP $B%"%I%l%9$r(B + $B%-%c%C%7%e$7$F$$$k%M!<%`%5!<%P$d%W%m%-%7$N$?$a$K0\9T4|4VCf$ON>J}$N(B + $B%P!<%A%c%k%[%9%H$rDs6!$7$?$$$H$7$^$9!#(B

    + +

    $BEz$O4JC1$G$9!#C1$K?7$7$$(B IP $B%"%I%l%9(B (172.20.30.50) + $B$r(B VirtualHost $B%G%#%l%/%F%#%V$KDI2C$9$k$3$H$G(B + $B$G$-$^$9!#(B

    + + + $B%5!<%P@_Dj(B + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +
    + +

    $B$3$N%P!<%A%c%k%[%9%H$O?7$7$$%"%I%l%9(B (IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$H$7$F(B) + $B$H8E$$%"%I%l%9(B($BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$H$7$F(B) $B$NN>J}$+$i(B + $B%"%/%;%9$G$-$^$9!#(B

    + +
    + +
    <code>ServerPath</code> $B%G%#%l%/%F%#%V$r(B + $B;H$&(B + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$,Fs$D$"$k%5!<%P$,$"$k$H$7$^$9!#(B + $B@5$7$$%P!<%A%c%k%[%9%H$rF@$k$?$a$K$O%/%i%$%"%s%H$O@5$7$$(B + Host: $B%X%C%@$rAw$i$J$1$l$P$J$j$^$;$s!#(B + $B8E$$(B HTTP/1.0 $B$O$=$N$h$&$J%X%C%@$rAw$i$J$$$N$G!"(BApache $B$O%/%i%$%"%s%H$,(B + $B$I$N%P!<%A%c%k%[%9%H$r0U?^$7$?$N$+$5$C$Q$j$o$+$j$^$;$s(B + ($B$J$N$G!"A0%Y!<%9$N%P!<%A%c%k%[%9%H$N(B + URL $B@\F,<-$X$N%j%s%/$N=q$+$l$?%Z!<%8$rJV$9!"(B + $B + + + $B%5!<%P$N@_Dj(B + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +
    + +

    ServerPath $B%G%#%l%/%F%#%V$N@_Dj$K(B + $B$h$j!"(BURL http://www.sub1.domain.tld/sub1/ $B$O(B + $B>o$K(B sub1-vhost $B$K$h$j07$o$l$^$9!#(BURL + http://www.sub1.domain.tld/ $B$X$N%j%/%(%9%H$O(B + $B%/%i%$%"%s%H$,@5$7$$(B Host: $B%X%C%@$rAw$C$?$H$-$K$N$_(B + sub1-vhost $B$+$iAw$i$l$^$9!#(BHost: $B%X%C%@$,$J$1$l$P(B + $B%/%i%$%"%s%H$OpJs%Z!<%8$rF@$^$9!#(B

    + +

    $B0l$D4qL/$JF0:n$r$9$kE@$,$"$k$3$H$O3P$($F$*$$$F$/$@$5$$!#(B + http://www.sub2.domain.tld/sub1/ $B$X$N%j%/%(%9%H$b(B + Host: $B%X%C%@$,$J$1$l$P(B sub1-vhost $B$K$h$j07$o$l$^$9!#(B

    + +

    $B@5$7$$(B Host: $B%X%C%@$rAw$C$?%/%i%$%"%s%H$O$I$A$i$N(B + URL$B!"(B$B$D$^$j(B$B@\F,<-$,$"$kJ}$bL5$$J}$b;H$($k$h$&$K(B + RewriteRule $B%G%#%l%/%F%#%V$,(B + $B;H$o$l$F$$$^$9!#(B

    +
    + +
    diff --git a/trunk/docs/manual/vhosts/examples.xml.ko b/trunk/docs/manual/vhosts/examples.xml.ko new file mode 100644 index 0000000000..3059d3e1f8 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.xml.ko @@ -0,0 +1,602 @@ + + + + + + + + +°¡»óÈ£½ºÆ® + °¡»óÈ£½ºÆ® ¿¹ + + + +

    ÀÌ ¹®¼­´Â ÀÚÁÖ ¹®ÀǵǴ °¡»óÈ£½ºÆ® + Áú¹®¿¡ ´äÀ» ÇÏ·Á°í ¾²¿©Á³´Ù. »óȲÀº À̸§±â¹ÝÀ̳ª IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÅëÇØ ÇÑ ¼­¹ö¿¡¼­ + ¿©·¯ À¥»çÀÌÆ®¸¦ ¼­ºñ½ºÇÏ·Á´Â °æ¿ìÀÌ´Ù. ÇÑ ÇÁ·Ï½Ã ¼­¹ö µÚ¿¡¼­ + ¿©·¯ ¼­¹ö¸¦ »ç¿ëÇÏ¿© »çÀÌÆ®¸¦ ¿î¿µÇÏ´Â °æ¿ì¸¦ ´Ù·é ¹®¼­µµ + °ð ³ª¿Ã °ÍÀÌ´Ù.

    + +
    + +
    IP ÁÖ¼Ò ÇÑ°³¿¡ ¿©·¯ À̸§±â¹Ý + À¥»çÀÌÆ® ¿î¿µÇϱâ. + +

    ¼­¹ö¿¡ IP ÁÖ¼Ò°¡ ÇÑ°³ ÀÖ°í, DNS¿¡¼­ ¿©·¯ ÁÖ¼Ò(CNAMES)°¡ + ÀÌ ÄÄÇ»Å͸¦ °¡¸®Å²´Ù. ÀÌ ÄÄÇ»ÅÍ¿¡¼­ www.example.com°ú + www.example.orgÀÇ À¥¼­¹ö¸¦ ½ÇÇàÇÏ°í ½Í´Ù.

    + + Note

    ¾ÆÆÄÄ¡ ¼­¹ö¿¡ °¡»óÈ£½ºÆ® ¼³Á¤À» + ÇÑ´Ù°í ±× È£½ºÆ®¸í¿¡ ´ëÇÑ DNS Ç׸ñÀÌ ÀÚµ¿ÀÌ·Î »ý¼ºµÇÁö + ¾Ê´Â´Ù. ¹Ýµå½Ã DNS¿¡ IP ÁÖ¼Ò¸¦ °¡¸®Å°´Â + À̸§ÀÌ ÀÖ¾î¾ß ÇÑ´Ù. ¾È±×·¯¸é ¾Æ¹«µµ À¥»çÀÌÆ®¸¦ º¼ + ¼ö ¾ø´Ù. °Ë»çÇغ¸±â À§ÇØ hosts ÆÄÀÏ¿¡ Ç׸ñÀ» + Ãß°¡ÇÒ ¼ö ÀÖÁö¸¸, ÀÌ´Â hosts Ç׸ñÀ» °¡Áø ÄÄÇ»ÅÍ¿¡¸¸ + ¹Ý¿µµÈ´Ù.

    +
    + + + ¼­¹ö ¼³Á¤ + + # ¾ÆÆÄÄ¡°¡ Æ÷Æ® 80À» ±â´Ù¸°´Ù
    + Listen 80
    +
    + # ¸ðµç IP ÁÖ¼Ò¿¡¼­ °¡»óÈ£½ºÆ® ¿äûÀ» ±â´Ù¸°´Ù
    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù
    +
    +
    + </VirtualHost> +
    + +

    º°Ç¥´Â ¸ðµç ÁÖ¼Ò¸¦ °¡¸®Å°¹Ç·Î, ÁÖ¼­¹ö´Â ¾î¶² ¿äûµµ + ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. www.example.comÀÌ + ¼³Á¤ÆÄÀÏ¿¡ óÀ½À¸·Î ³ª¿À¹Ç·Î °¡Àå ³ôÀº ¿ì¼±¼øÀ§¸¦ °¡Áö¸ç, + ±âº»È¤Àº Ãʱ⠼­¹ö°¡ µÈ´Ù. + ¾î¶² ServerName Áö½Ã¾î¿¡µµ ÇØ´çµÇÁö¾Ê´Â ¿äûÀº + ù¹ø° VirtualHost°¡ ¼­ºñ½ºÇÑ´Ù.

    + + + ÁÖÀÇ + +

    ¿øÇÑ´Ù¸é * ´ë½Å ½Ã½ºÅÛÀÇ ½ÇÁ¦ IP + ÁÖ¼Ò¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì + VirtualHostÀÇ ¾Æ±Ô¸ÕÆ®´Â + NameVirtualHostÀÇ ¾Æ±Ô¸ÕÆ®¿Í ÀÏÄ¡ÇØ¾ß + ÇÑ´Ù:

    + + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + # »ý·« ... +
    + +

    ±×·¯³ª ISP¿¡¼­ µ¿ÀûÀ¸·Î IP ÁÖ¼Ò¸¦ °¡Á®¿À´Â µî + IP ÁÖ¼Ò¸¦ ¸ð¸£´Â °æ¿ì¿¡´Â *¸¦ »ç¿ëÇÏ´Â + °ÍÀÌ À¯¿ëÇÏ´Ù. *´Â ¸ðµç IP ÁÖ¼Ò¿¡ + ÇØ´çÇϹǷÎ, IP ÁÖ¼Ò°¡ º¯°æµÇ¾îµµ ¼³Á¤À» º¯°æÇÒ + ÇÊ¿ä°¡ ¾ø´Ù.

    +
    + +

    °ÅÀÇ ´ëºÎºÐÀÇ À̸§±â¹Ý °¡»óÈ£½ºÆ® ¼³Á¤Àº À§¿Í °°´Ù. + ¿¹¿Ü´Â ´Ù¸¥ IP ÁÖ¼Ò³ª Æ÷Æ®·Î ´Ù¸¥ ³»¿ëÀ» ¼­ºñ½ºÇÏ·Á´Â + °æ¿ìÀÌ´Ù.

    + +
    + +
    ¿©·¯ IP ÁÖ¼Ò¿¡¼­ À̸§±â¹Ý + È£½ºÆ®. + + + ÁÖÀÇ

    ¿©±â¼­ ¼³¸íÇÑ ¹æ¹ýÀº IP ÁÖ¼Ò°¡ + ¸î°³¶óµµ Àû¿ë°¡´ÉÇÏ´Ù.

    +
    + +

    ¼­¹ö´Â IP ÁÖ¼Ò°¡ µÎ°³ÀÖ´Ù. Çϳª¿¡¼­ + (172.20.30.40) "ÁÖ" ¼­¹ö + server.domain.comÀ» ¼­ºñ½ºÇÏ°í, ´Ù¸¥ Çϳª¿¡¼­ + (172.20.30.50) ¿©·¯ °¡»óÈ£½ºÆ®¸¦ ¼­ºñ½ºÇÒ + °ÍÀÌ´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 80
    +
    + # 172.20.30.40¿¡¼­ ½ÇÇàÇÏ´Â "ÁÖ"¼­¹öÀÌ´Ù
    + ServerName server.domain.com
    + DocumentRoot /www/mainserver
    +
    + # ´Ù¸¥ ÁÖ¼Ò´Ù
    + NameVirtualHost 172.20.30.50
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù ...
    +
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + # ´Ù¸¥ Áö½Ã¾îµéµµ ÀÖ´Ù ...
    +
    +
    + </VirtualHost> +
    + +

    172.20.30.50ÀÌ ¾Æ´Ñ ÁÖ¼Ò¿¡ ´ëÇÑ ¿äûÀº + ÁÖ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù. È£½ºÆ®¸í ¾øÀÌ, Áï Host: + Çì´õ¾øÀÌ 172.20.30.50·Î ¿äûÇϸé + www.example.comÀÌ ¼­ºñ½ºÇÑ´Ù.

    + +
    + +
    (³»ºÎ¿Í ¿ÜºÎ ÁÖ¼Ò¿Í °°ÀÌ) + ´Ù¸¥ IP ÁÖ¼Ò·Î °°Àº ³»¿ëÀ» ¼­ºñ½ºÇϱâ. + +

    ¼­¹ö ÄÄÇ»ÅÍ¿¡ IP ÁÖ¼Ò°¡ µÎ°³ (192.168.1.1°ú + 172.20.30.40) ÀÖ´Ù. ÄÄÇ»ÅÍ´Â ³»ºÎ (ÀÎÆ®¶ó³Ý) + ³×Æ®¿÷°ú ¿ÜºÎ (ÀÎÅͳÝ) ³×Æ®¿÷ »çÀÌ¿¡ À§Ä¡ÇÑ´Ù. ³×Æ®¿÷ ¹Û¿¡¼­ + server.example.comÀº ¿ÜºÎ ÁÖ¼Ò¸¦ + (172.20.30.40) ÀǹÌÇÏ°í, ³×Æ®¿÷ ³»ºÎ¿¡¼­ °°Àº + À̸§À» ³»ºÎ ÁÖ¼Ò·Î (192.168.1.1) »ç¿ëÇÑ´Ù.

    + +

    ¼­¹ö´Â VirtualHost ¼½¼Ç ÇÑ°³·Î ³»ºÎ¿Í ¿ÜºÎ + ÀÀ´ä¿¡ °°Àº ³»¿ëÀ» ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

    + + + ¼­¹ö ¼³Á¤ + + NameVirtualHost 192.168.1.1
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 192.168.1.1 172.20.30.40>
    + + DocumentRoot /www/server1
    + ServerName server.example.com
    + ServerAlias server
    +
    + </VirtualHost> +
    + +

    ÀÌÁ¦ µÎ ³×Æ®¿÷¿¡¼­ µé¾î¿Â ¿äûÀ» °°Àº + VirtualHost¿¡¼­ ¼­ºñ½ºÇÑ´Ù.

    + + + ÁÖÀÇ:

    ³»ºÎ ³×Æ®¿÷¿¡¼­´Â ¿ÏÀüÇÑ È£½ºÆ®¸í + server.example.com ´ë½Å À̸§ + serverµµ °¡´ÉÇÏ´Ù.

    + +

    ¶ÇÇÑ À§ÀÇ ¿¹¿¡¼­ IP ÁÖ¼Ò ´ë½Å *À» + »ç¿ëÇÏ¿© ¼­¹ö°¡ ¸ðµç ÁÖ¼Ò¿¡ µ¿ÀÏÇÏ°Ô µ¿ÀÛÇÒ ¼ö + ÀÖ´Ù.

    +
    + +
    + +
    ¿©·¯ Æ÷Æ®¿¡¼­ ¼­·Î ´Ù¸¥ »çÀÌÆ® + ¿î¿µÇϱâ. + +

    °°Àº IPÀÇ ¿©·¯ Æ÷Æ®¿¡¼­ ¼­·Î ´Ù¸¥ µµ¸ÞÀÎÀ» ¼­ºñ½ºÇÑ´Ù°í + °¡Á¤ÇÏÀÚ. ÀÌ´Â "NameVirtualHost" ű׿¡ Æ÷Æ®¸¦ Á¤ÀÇÇϸé + °¡´ÉÇÏ´Ù. NameVirtualHost name:port¾øÀÌ <VirtualHost + name:port>¸¸ ȤÀº Listen Áö½Ã¾î¸¸ »ç¿ëÇÏ¸é ¾ÈµÈ´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 80
    + Listen 8080
    +
    + NameVirtualHost 172.20.30.40:80
    + NameVirtualHost 172.20.30.40:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.com
    + DocumentRoot /www/domain-8080
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:80>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-80
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + ServerName www.example.org
    + DocumentRoot /www/otherdomain-8080
    +
    + </VirtualHost> +
    + +
    + +
    IP±â¹Ý °¡»óÈ£½ºÆ® + +

    ¼­¹ö´Â °¢°¢ www.example.com°ú + www.example.org¿¡ ÇØ´çÇÏ´Â µÎ IP ÁÖ¼Ò¸¦ + (172.20.30.40°ú 172.20.30.50) + °¡Áø´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 80
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +

    <VirtualHost> Áö½Ã¾î·Î ÁöÁ¤ÇÑ ÁÖ¼Ò¿¡ + ÇØ´çÇÏÁö¾Ê´Â ÁÖ¼Ò·Î (¿¹¸¦ µé¾î, localhost) + ¿äûÀÌ µé¾î¿À¸é ÁÖ¼­¹ö°¡ ÀÖ´Â °æ¿ì ÁÖ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù.

    + +
    + +
    Æ÷Æ®±â¹Ý°ú ip±â¹ÝÀÌ È¥ÇÕµÈ + °¡»óÈ£½ºÆ® + +

    ¼­¹ö´Â °¢°¢ www.example.com°ú + www.example.org¿¡ ÇØ´çÇÏ´Â µÎ IP ÁÖ¼Ò¸¦ + (172.20.30.40°ú 172.20.30.50) + °¡Áø´Ù. °¢ IPÀÇ 80¹ø°ú 8080¹ø Æ÷Æ®¿¡ °¡»óÈ£½ºÆ®¸¦ µ¹¸°´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 172.20.30.40:80
    + Listen 172.20.30.40:8080
    + Listen 172.20.30.50:80
    + Listen 172.20.30.50:8080
    +
    + <VirtualHost 172.20.30.40:80>
    + + DocumentRoot /www/example1-80
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40:8080>
    + + DocumentRoot /www/example1-8080
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:80>
    + + DocumentRoot /www/example2-80
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.50:8080>
    + + DocumentRoot /www/example2-8080
    + ServerName www.example.org
    +
    + </VirtualHost> +
    + +
    + +
    À̸§±â¹Ý°ú IP±â¹ÝÀÌ È¥ÇÕµÈ + °¡»óÈ£½ºÆ® + +

    ÁÖ¼ÒÁß ¸î¸îÀº À̸§±â¹Ý °¡»óÈ£½ºÆ®·Î, ´Ù¸¥ °ÍÀº IP±â¹Ý + °¡»óÈ£½ºÆ®·Î ¼­ºñ½ºÇÏ°í ½Í´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 80
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example1
    + ServerName www.example.com
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example3.net
    +
    + </VirtualHost>
    +
    + # IP-±â¹Ý
    + <VirtualHost 172.20.30.50>
    + + DocumentRoot /www/example4
    + ServerName www.example4.edu
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.60>
    + + DocumentRoot /www/example5
    + ServerName www.example5.gov
    +
    + </VirtualHost> +
    + +
    + +
    <code>_default_</code> °¡»óÈ£½ºÆ® + »ç¿ëÇϱâ + +
    ¸ðµç Æ÷Æ®¿¡ ´ëÇÑ + <code>_default_</code> °¡»óÈ£½ºÆ® + +

    ¾î¶² °¡»óÈ£½ºÆ®¿¡µµ ÇØ´çÇÏÁö¾ÊÀº IP ÁÖ¼Ò¿Í Æ÷Æ®¿¡ ´ëÇÑ + ¸ðµç ¿äûÀ» ó¸®Çϱâ.

    + + + ¼­¹ö ¼³Á¤ + + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    +
    + </VirtualHost> +
    + +

    default(±âº») °¡»óÈ£½ºÆ®ÀÇ Æ÷Æ®·Î ¿ÍÀϵåÄ«µå¸¦ »ç¿ëÇÏ¿© ¾î¶² ¿äûµµ + ÁÖ¼­¹ö·Î ¸ø°¡µµ·Ï ¸¸µç´Ù.

    + +

    default °¡»óÈ£½ºÆ®´Â Àý´ë·Î À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ »ç¿ëÇÏ´Â + ÁÖ¼Ò/Æ÷Æ®·ÎÀÇ ¿äûÀ» ¼­ºñ½ºÇÏÁö ¾Ê´Â´Ù. ¾Ë ¼ö ¾ø°Å³ª + Host: Çì´õ°¡ »ý·«µÈ ¿äûÀº Ç×»ó ÃÖÃÊÀÇ À̸§±â¹Ý + °¡»óÈ£½ºÆ®(¼³Á¤ÆÄÀÏ¿¡¼­ + ÁÖ¼Ò/Æ÷Æ®°¡ óÀ½À¸·Î ³ª¿Â °¡»óÈ£½ºÆ®)°¡ ¼­ºñ½ºÇÑ´Ù.

    + +

    AliasMatch³ª + RewriteRuleÀ» + »ç¿ëÇÏ¿© ¾î¶² ¿äûÀ» ƯÁ¤ ÆäÀÌÁö(ȤÀº ½ºÅ©¸³Æ®)·Î + ÀçÀÛ¼ºÇÒ(rewrite) ¼ö ÀÖ´Ù.

    +
    + +
    ¿©·¯ Æ÷Æ®¿¡ ´ëÇÑ + <code>_default_</code> °¡»óÈ£½ºÆ® + +

    À§ÀÇ °æ¿ì¿Í °°Áö¸¸, ¼­¹ö´Â ¿©·¯ Æ÷Æ®¸¦ ±â´Ù¸®°í 80¹ø + Æ÷Æ®¿¡ ´ëÇؼ­ Ãß°¡·Î _default_ °¡»óÈ£½ºÆ®¸¦ + »ç¿ëÇÏ°í ½Í´Ù.

    + + + ¼­¹ö ¼³Á¤ + + <VirtualHost _default_:80>
    + + DocumentRoot /www/default80
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost _default_:*>
    + + DocumentRoot /www/default
    + # ...
    +
    + </VirtualHost> +
    + +

    80¹ø Æ÷Æ®¿¡ ´ëÇÑ default °¡»óÈ£½ºÆ®´Â (¹Ýµå½Ã + ¿ÍÀϵåÄ«µå Æ÷Æ®¸¦ °¡Áø ±âº» °¡»óÈ£½ºÆ® ÀÌÀü¿¡ ³ª¿Í¾ß ÇÑ´Ù) + ÁöÁ¤ÇÏÁö¾ÊÀº IP ÁÖ¼Ò·Î º¸³»Áø ¸ðµç ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. + ÁÖ¼­¹ö´Â Àý´ë·Î ¿äûÀ» ¼­ºñ½ºÇÏÁö ¸øÇÑ´Ù.

    +
    + +
    ÇÑ Æ÷Æ®¿¡ ´ëÇÑ + <code>_default_</code> °¡»óÈ£½ºÆ® + +

    80¹ø Æ÷Æ®¿¡ ´ëÇؼ­¸¸ default °¡»óÈ£½ºÆ®¸¦ ¸¸µé°í ½Í´Ù.

    + + + ¼­¹ö ¼³Á¤ + + <VirtualHost _default_:80>
    + DocumentRoot /www/default
    + ...
    + </VirtualHost> +
    + +

    Æ÷Æ® 80¹ø¿¡ ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò¿¡ ´ëÇÑ ¿äûÀº ±âº» + °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÏ°í, ´Ù¸¥ ÁöÁ¤ÇÏÁö¾ÊÀº ÁÖ¼Ò¿Í Æ÷Æ®¸¦ + °¡Áø ¿äûÀº ÁÖ ¼­¹ö°¡ ¼­ºñ½ºÇÑ´Ù.

    +
    + +
    + +
    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ IP±â¹Ý + °¡»óÈ£½ºÆ®·Î ¿Å±â±â + +

    (À̸§±â¹ÝÀÇ Ã¹¹ø° ¿¹¿¡¼­) È£½ºÆ®¸í + www.example.org¿¡ ´ëÇÑ À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â + ÀÚ½ÅÀÇ IP ÁÖ¼Ò¸¦ °¡Á®¾ß ÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ ÀÌÀü + IP ÁÖ¼Ò¸¦ ij½ÌÇÏ´Â ³×ÀÓ¼­¹ö³ª ÇÁ·Ï½Ã¿ÍÀÇ ¹®Á¦¸¦ ÇÇÇϱâÀ§ÇØ + ¿Å±â´Â µ¿¾È µÑ ¸ðµÎ¸¦ ¼­ºñ½ºÇÏ°í ½Í´Ù.

    + +

    + ¹æ¹ýÀº VirtualHost Áö½Ã¾î¿¡ »õ IP ÁÖ¼Ò¸¸À» + (172.20.30.50) Ãß°¡ÇϸéµÇ¹Ç·Î ½±´Ù.

    + + + ¼­¹ö ¼³Á¤ + + Listen 80
    + ServerName www.example.com
    + DocumentRoot /www/example1
    +
    + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40 172.20.30.50>
    + + DocumentRoot /www/example2
    + ServerName www.example.org
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/example3
    + ServerName www.example.net
    + ServerAlias *.example.net
    + # ...
    +
    + </VirtualHost> +
    + +

    ÀÌÁ¦ (IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ÅëÇÑ) »õ·Î¿î ÁÖ¼Ò¿Í (À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ ÅëÇÑ) ÀÌÀü ÁÖ¼Ò ¸ðµÎ °¡»óÈ£½ºÆ®¿¡ Á¢±ÙÇÒ + ¼ö ÀÖ´Ù.

    + +
    + +
    <code>ServerPath</code> + Áö½Ã¾î »ç¿ëÇϱâ + +

    µÎ À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ °¡Áø ¼­¹ö°¡ ÀÖ´Ù. ¿Ã¹Ù¸¥ + °¡»óÈ£½ºÆ®¸¦ ¼±ÅÃÇϱâÀ§ÇØ Å¬¶óÀ̾ðÆ®´Â ¿Ã¹Ù¸¥ + Host: Çì´õ¸¦ º¸³»¾ß ÇÑ´Ù. ¿À·¡µÈ HTTP/1.0 + Ŭ¶óÀ̾ðÆ®°¡ ÀÌ Çì´õ¸¦ º¸³»Áö ¸øÇÏ¸é ¾ÆÆÄÄ¡´Â Ŭ¶óÀ̾ðÆ®°¡ + ¾î¶² °¡»óÈ£½ºÆ®¸¦ º¸·Á°íÇÏ´ÂÁö ¾Ë ¼ö ¾ø´Ù (±×·¡¼­ ÃÖÃÊÀÇ + °¡»óÈ£½ºÆ®°¡ ¿äûÀ» ¼­ºñ½ºÇÑ´Ù). ¿À·¡µÈ ºê¶ó¿ìÀú¿Í °¡´ÉÇÑ È£È¯À» + À¯ÁöÇϱâÀ§ÇØ ÃÖÃÊÀÇ °¡»óÈ£½ºÆ®¸¦ ¸¸µé°í, ¿©±â¿¡ À̸§±â¹Ý + °¡»óÈ£½ºÆ®ÀÇ URL Á¢µÎ»ç¸¦ Æ÷ÇÔÇÏ´Â ¸µÅ© ¸ñ·Ï ÆäÀÌÁö¸¦ + µÐ´Ù.

    + + + ¼­¹ö ¼³Á¤ + + NameVirtualHost 172.20.30.40
    +
    + <VirtualHost 172.20.30.40>
    + + # primary vhost
    + DocumentRoot /www/subdomain
    + RewriteEngine On
    + RewriteRule ^/.* /www/subdomain/index.html
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + DocumentRoot /www/subdomain/sub1
    + + ServerName www.sub1.domain.tld
    + ServerPath /sub1/
    + RewriteEngine On
    + RewriteRule ^(/sub1/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost>
    +
    + <VirtualHost 172.20.30.40>
    + + DocumentRoot /www/subdomain/sub2
    + ServerName www.sub2.domain.tld
    + ServerPath /sub2/
    + RewriteEngine On
    + RewriteRule ^(/sub2/.*) /www/subdomain$1
    + # ...
    +
    + </VirtualHost> +
    + +

    ServerPath Áö½Ã¾î¶§¹®¿¡ + URL http://www.sub1.domain.tld/sub1/¿¡ ´ëÇÑ + ¿äûÀº Ç×»ó subl-°¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù.
    + Ŭ¶óÀ̾ðÆ®°¡ ¿Ã¹Ù¸¥ Host: Çì´õ¸¦ º¸³½´Ù¸é, + URL http://www.sub1.domain.tld/¿¡ ´ëÇÑ ¿äûÀº + subl-°¡»óÈ£½ºÆ®¿¡¼­¸¸ ¼­ºñ½ºÇÑ´Ù. ¸¸¾à Host: Çì´õ¸¦ + º¸³»Áö¾ÊÀ¸¸é Ŭ¶óÀ̾ðÆ®´Â ÃÖÃÊÀÇ È£½ºÆ®¿¡ ÀÖ´Â Á¤º¸ÆäÀÌÁö¸¦ + º¸°ÔµÈ´Ù.

    + +

    ¿©±â¿¡ ¹®Á¦°¡ ÀÖÀ½À» ÁÖÀÇÇ϶ó: Ŭ¶óÀ̾ðÆ®°¡ + Host: Çì´õ¸¦ º¸³»Áö¾ÊÀ¸¸é + http://www.sub2.domain.tld/sub1/¿¡ ´ëÇÑ ¿äûµµ + subl-°¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù.

    + +

    RewriteRule + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿Ã¹Ù¸¥ Host: Çì´õ¸¦ º¸³»´Â + Ŭ¶óÀ̾ðÆ®´Â (¿¹¸¦ µé¾î, URL ÀüÄ¡»ç°¡ Àְųª ¾ø´Â) + µÎ URLÀ» ¸ðµÎ »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    diff --git a/trunk/docs/manual/vhosts/examples.xml.meta b/trunk/docs/manual/vhosts/examples.xml.meta new file mode 100644 index 0000000000..9d727c0674 --- /dev/null +++ b/trunk/docs/manual/vhosts/examples.xml.meta @@ -0,0 +1,13 @@ + + + + examples + /vhosts/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/vhosts/fd-limits.html b/trunk/docs/manual/vhosts/fd-limits.html new file mode 100644 index 0000000000..d3a03abdd8 --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.html @@ -0,0 +1,11 @@ +URI: fd-limits.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: fd-limits.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: fd-limits.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/fd-limits.html.en b/trunk/docs/manual/vhosts/fd-limits.html.en new file mode 100644 index 0000000000..39ed1abc8e --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.html.en @@ -0,0 +1,126 @@ + + + +File Descriptor Limits - Apache HTTP Server + + + + + +
    <-
    +

    File Descriptor Limits

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    When using a large number of Virtual Hosts, Apache may run + out of available file descriptors (sometimes called file + handles) if each Virtual Host specifies different log + files. The total number of file descriptors used by Apache is + one for each distinct error log file, one for every other log + file directive, plus 10-20 for internal use. Unix operating + systems limit the number of file descriptors that may be used + by a process; the limit is typically 64, and may usually be + increased up to a large hard-limit.

    + +

    Although Apache attempts to increase the limit as required, + this may not work if:

    + +
      +
    1. Your system does not provide the setrlimit() + system call.
    2. + +
    3. The setrlimit(RLIMIT_NOFILE) call does not + function on your system (such as Solaris 2.3)
    4. + +
    5. The number of file descriptors required exceeds the hard + limit.
    6. + +
    7. Your system imposes other limits on file descriptors, + such as a limit on stdio streams only using file descriptors + below 256. (Solaris 2)
    8. +
    + +

    In the event of problems you can:

    + +
      +
    • Reduce the number of log files; don't specify log files + in the <VirtualHost> + sections, but only log to the main log files. (See Splitting up your log files, below, for more + information on doing this.)
    • + +
    • + If you system falls into 1 or 2 (above), then increase the + file descriptor limit before starting Apache, using a + script like + +

      + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      +

      +
    • +
    + +
    +
    top
    +
    +

    Splitting up your log files

    + +

    If you want to log multiple virtual hosts to the same log file, you +may want to split up the log files afterwards in order to run +statistical analysis of the various virtual hosts. This can be +accomplished in the following manner.

    + +

    First, you will need to add the virtual host information to the log +entries. This can be done using the +LogFormat +directive, and the %v variable. Add this to the beginning +of your log format string:

    + +

    +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +

    + +

    This will create a log file in the common log format, but with the +canonical virtual host (whatever appears in the +ServerName directive) prepended to +each line. (See Custom Log Formats for +more about customizing your log files.)

    + +

    When you wish to split your log file into its component parts (one +file per virtual host) you can use the program split-logfile to accomplish +this. You'll find this program in the support directory +of the Apache distribution.

    + +

    Run this program with the command:

    + +

    +split-logfile < /logs/multiple_vhost_log +

    + +

    This program, when run with the name of your vhost log file, will +generate one file for each virtual host that appears in your log file. +Each file will be called hostname.log.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/fd-limits.html.ja.euc-jp b/trunk/docs/manual/vhosts/fd-limits.html.ja.euc-jp new file mode 100644 index 0000000000..de6f21f3ce --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.html.ja.euc-jp @@ -0,0 +1,123 @@ + + + +¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¸Â³¦ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¸Â³¦

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + + +

    ¤¿¤¯¤µ¤ó¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò±¿ÍѤ¹¤ë¾ì¹ç¡¢¤â¤·¡¢ + ³Æ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤´¤È¤Ë°Û¤Ê¤ë¥í¥°¥Õ¥¡¥¤¥ë¤¬»ØÄꤷ¤Æ¤¢¤ë¤È¡¢ + Apache ¤¬¥Õ¥¡¥¤¥ëµ­½Ò»Ò (¥Õ¥¡¥¤¥ë¥Ï¥ó¥É¥ë¤È¤â¸Æ¤Ð¤ì¤Þ¤¹) + ¤ò»È¤¤ÀڤäƤ·¤Þ¤¦¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£Apache ¤¬»ÈÍѤ¹¤ë¥Õ¥¡¥¤¥ë + µ­½Ò»Ò¤Î¿ô¤Ï¡¢³Æ¥¨¥é¡¼¥í¥°¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­ 1 ¤Ä¡¢Â¾¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Î + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¤Ä¤­ 1 ¤Ä¡¢¤µ¤é¤ËÆâÉô¤Ç»ÈÍѤ¹¤ë 10 ¤«¤é 20¡¢ + ¤Î¹ç·×¤Ë¤Ê¤ê¤Þ¤¹¡£Unix ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ç¤Ï¥×¥í¥»¥¹¤´¤È¤Ë + »ÈÍѲÄǽ¤Ê¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¿ô¤òÀ©¸Â¤·¤Æ¤¤¤Þ¤¹¡£¤¿¤¤¤Æ¤¤¤Î¾ì¹ç¤Ï 64 ¤Ç¡¢ + ÉáÄ̤ÏÂ礭¤ÊÃͤΥϡ¼¥É¥ê¥ß¥Ã¥È¤Þ¤ÇÁý¤ä¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    Apache ¤ÏɬÍפ˱þ¤¸¤Æ¾å¸Â¤ò³ÈÂ礷¤è¤¦¤È»î¤ß¤Þ¤¹¤¬¡¢ + °Ê²¼¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¤¦¤Þ¤¯¤¤¤«¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£

    + +
      +
    1. ÍøÍѤ·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ç setrlimit() + ¥·¥¹¥Æ¥à¥³¡¼¥ë¤¬Ä󶡤µ¤ì¤Æ¤¤¤Ê¤¤¡£
    2. + +
    3. ¥·¥¹¥Æ¥à¾å¤Ç setrlimit(RLIMIT_NOFILE) ¤¬Æ°ºî¤·¤Ê¤¤ + (¤¿¤È¤¨¤Ð Solaris 2.3 ¤Î¤è¤¦¤Ë)¡£
    4. + +
    5. Í׵ᤵ¤ì¤ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î¿ô¤¬ + ¥Ï¡¼¥É¥ê¥ß¥Ã¥È¤òĶ¤¨¤Æ¤·¤Þ¤¦¡£
    6. + +
    7. ¥·¥¹¥Æ¥à¤Ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Ë´Ø¤·¤ÆÊ̤ÎÀ©¸Â¤¬Â¸ºß¤·¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¡£ + ¤¿¤È¤¨¤Ð¡¢stdio ¥¹¥È¥ê¡¼¥à¤Ç¤Ï¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤ò 256 °Ê¾å»È¤¨¤Ê¤¤ + (Solaris 2)¡¢¤Ê¤É¡£
    8. +
    + +

    ÌäÂ꤬ȯÀ¸¤·¤¿»þ¤Ë¼è¤êÆÀ¤ëÂнèÊýË¡¤Ï¼¡¤Î¤È¤ª¤ê:

    + +
      +
    • ¥í¥°¥Õ¥¡¥¤¥ë¤Î¿ô¤ò¸º¤é¤¹¡£<VirtualHost> + ¥»¥¯¥·¥ç¥ó¤Ç¥í¥°¥Õ¥¡¥¤¥ë¤ò»ØÄꤻ¤º¡¢¥á¥¤¥ó¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Ë¤Î¤ßµ­Ï¿¤¹¤ë¡£ + (¤³¤ì¤Ë´Ø¤¹¤ë¾Ü¤·¤¤¾ðÊó¤Ï°Ê²¼¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Îʬ³ä¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£)
    • + +
    • + ¤â¤·¡¢Á°½Ò¤Î 1 ¤Þ¤¿¤Ï 2 ¤Î¾ì¹ç¤Ç¤¢¤ì¤Ð¡¢ + Apache ¤òµ¯Æ°¤¹¤ëÁ°¤Ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤òÁý¤ä¤·¤Þ¤¹¡£ + ¤¿¤È¤¨¤Ð¼¡¤Î¤è¤¦¤Ê¥¹¥¯¥ê¥×¥È¤ò»È¤¤¤Þ¤¹¡£ + +

      + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      +

      +
    • +
    +
    +
    top
    +
    +

    ¥í¥°¥Õ¥¡¥¤¥ë¤Îʬ³ä

    + +

    Ê£¿ô¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥í¥°¤òƱ¤¸¥í¥°¥Õ¥¡¥¤¥ë¤Ë¼ý½¸¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¤È¤­¤Ë¤Ï¡¢ +³Æ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤Ä¤¤¤ÆÅý·×Ū¤Ê²òÀϤò¼Â¹Ô¤¹¤ë¤¿¤á¤Ë¸å¤Ç¥í¥°¥Õ¥¡¥¤¥ë¤ò +ʬ³ä¤·¤¿¤¯¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤³¤ì¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ¼Â¸½¤Ç¤­¤Þ¤¹¡£

    + +

    ¤Þ¤º¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¾ðÊó¤ò¥í¥°¤Î¥¨¥ó¥È¥ê¤ËÄɲ乤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ +¤³¤ì¤Ï LogFormat +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î %v ÊÑ¿ô¤ò»È¤¦¤³¤È¤Ç¤Ç¤­¤Þ¤¹¡£ +¤³¤ì¤ò¥í¥°¤Î¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ÎÀèƬ¤ËÄɲä·¤Þ¤¹:

    + +

    +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +

    + +

    ¤³¤ì¤Ï common log format ¤Î¥í¥°¤òºîÀ®¤·¤Þ¤¹¤¬¡¢¤½¤ì¤¾¤ì¤Î¹Ô¤ÎÀèƬ¤Ë +Àµµ¬²½¤µ¤ì¤¿¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î̾Á° +(ServerName +¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¤â¤Î) ¤¬Éղ䵤ì¤Þ¤¹¡£ +(¥í¥°¥Õ¥¡¥¤¥ë¤Î¥«¥¹¥¿¥Þ¥¤¥º¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï Custom Log Formats ¤ò +Æɤó¤Ç¤¯¤À¤µ¤¤¡£)

    + +

    ¥í¥°¥Õ¥¡¥¤¥ë¤ò³ÆÉôʬ (¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Ë 1 ¥Õ¥¡¥¤¥ë) ¤Ëʬ¤±¤¿¤¤¤È¤­¤Ï¡¢ +split-logfile +¤ò»È¤Ã¤Æ¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥×¥í¥°¥é¥à¤Ï Apache ÇÛÉۤΠ+support ¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ê¤Þ¤¹¡£

    + +

    °Ê²¼¤Î¤è¤¦¤Ê¥³¥Þ¥ó¥É¤Ç¤³¤Î¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤·¤Þ¤¹:

    + +

    +split-logfile < /logs/multiple_vhost_log +

    + +

    ¤³¤Î¥×¥í¥°¥é¥à¤Ï¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥í¥°¥Õ¥¡¥¤¥ë¤Î̾Á°¤È¤È¤â¤Ë¼Â¹Ô¤µ¤ì¡¢ +¥í¥°¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤ë¤½¤ì¤¾¤ì¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈËè¤Ë°ì¤Ä¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤Þ¤¹¡£ +¤½¤ì¤¾¤ì¤Î¥Õ¥¡¥¤¥ë¤Ï ¥Û¥¹¥È̾.log ¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤ê¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/fd-limits.html.ko.euc-kr b/trunk/docs/manual/vhosts/fd-limits.html.ko.euc-kr new file mode 100644 index 0000000000..c199a06040 --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.html.ko.euc-kr @@ -0,0 +1,120 @@ + + + +ÆÄÀϱâ¼úÀÚ(file descriptor) ÇÑ°è - Apache HTTP Server + + + + + +
    <-
    +

    ÆÄÀϱâ¼úÀÚ(file descriptor) ÇÑ°è

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + + +

    °¡»óÈ£½ºÆ®¸¦ ¸¹ÀÌ »ç¿ëÇÏ°í °¢ °¡»óÈ£½ºÆ®¿¡ ¼­·Î ´Ù¸¥ + ·Î±×ÆÄÀÏÀ» ÁöÁ¤Çϸé, ¾ÆÆÄÄ¡°¡ »ç¿ë°¡´ÉÇÑ ÆÄÀϱâ¼úÀÚ(file + descriptor, ÈçÈ÷ ÆÄÀÏÇÚµé(file handle)À̶ó°í + ºÎ¸§)¸¦ ´Ù ½á¹ö¸± ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ÆÄÀϱâ¼úÀÚÀÇ + ÃÑ °³¼ö´Â ¿À·ù ·Î±×ÆÄÀÏ´ç ÇÑ°³, ´Ù¸¥ ·Î±×ÆÄÀÏ Áö½Ã¾î´ç + ÇÑ°³, Ãß°¡·Î ³»ºÎ¿ëµµ·Î 10-20°³¸¦ ´õÇÑ ¼ö´Ù. À¯´Ð½º ¿î¿µÃ¼Á¦´Â + ÇÁ·Î¼¼½º°¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ÆÄÀϱâ¼úÀÚ °³¼ö¸¦ Á¦ÇÑÇÑ´Ù. ÀÌ ÇÑ°è´Â + º¸Åë 64°³·Î, º¸Åë À̺¸´Ù Å« hard-limit±îÁö ´Ã¸± ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ÀÌ ÇѰ踦 ÇÊ¿äÇѸ¸Å­ ´Ã¸®·Á°í ÇÏÁö¸¸, ½ÇÆÐÇÏ´Â + °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    1. ½Ã½ºÅÛÀÌ setrlimit() ½Ã½ºÅÛÈ£ÃâÀ» + Á¦°øÇÏÁö ¾Ê´Â´Ù.
    2. + +
    3. (Solaris 2.3°ú °°ÀÌ) ½Ã½ºÅÛ¿¡¼­ + setrlimit(RLIMIT_NOFILE) ÇÔ¼ö°¡ µ¿ÀÛÇÏÁö + ¾Ê´Â´Ù.
    4. + +
    5. ÇÊ¿äÇÑ ÆÄÀϱâ¼úÀÚ °³¼ö°¡ hard limit º¸´Ù ¸¹´Ù.
    6. + +
    7. (Solaris 2) ½Ã½ºÅÛÀÌ stdio ½ºÆ®¸²À» 256ÀÌÇÏÀÇ + ÆÄÀϱâ¼úÀÚ¸¸À» »ç¿ëÇϵµ·Ï Á¦ÇÑÇÏ´Â µî ÆÄÀϱâ¼úÀÚ¿¡ + Á¦¾àÀ» °¡ÇÑ´Ù.
    8. +
    + +

    ÀÌ °æ¿ì ÇØ°áÃ¥Àº:

    + +
      +
    • ·Î±×ÆÄÀÏ °³¼ö¸¦ ÁÙÀδÙ. <VirtualHost> ¼½¼Ç¿¡¼­ ·Î±×ÆÄÀÏÀ» + ÁöÁ¤ÇÏÁö ¾Ê°í ÁÖ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÑ´Ù. (´õ ÀÚ¼¼ÇÑ ¹æ¹ýÀº + ¾Æ·¡ ·Î±×ÆÄÀÏ ³ª´©±â¸¦ Âü°íÇ϶ó.)
    • + +
    • + »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÌ (À§ÀÇ) 1¹ø°³ª 2¹ø° °æ¿ì¿¡ ÇØ´çÇÑ´Ù¸é, + ´ÙÀ½°ú °°Àº ½ºÅ©¸³Æ®·Î ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϱâ Àü¿¡ ÆÄÀϱâ¼úÀÚ + ÇѰ踦 ´Ã¸°´Ù. + +

      + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      +

      +
    • +
    + +
    +
    top
    +
    +

    ·Î±×ÆÄÀÏ ³ª´©±â

    + +

    ¿©·¯ °¡»óÈ£½ºÆ®°¡ °°Àº ·Î±×ÆÄÀÏÀ» »ç¿ëÇÑ´Ù¸é ³ªÁß¿¡ °¢ +°¡»óÈ£½ºÆ®ÀÇ Åë°èºÐ¼®À» À§ÇØ ·Î±×ÆÄÀÏÀ» ³ª´©°í ½ÍÀ» °ÍÀÌ´Ù. +ÀÌ ÀÛ¾÷Àº ´ÙÀ½°ú °°ÀÌ ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ÕÀú ·Î±× Ç׸ñ¿¡ °¡»óÈ£½ºÆ® Á¤º¸¸¦ Ãß°¡ÇÑ´Ù. À̸¦ À§ÇØ +LogFormat +Áö½Ã¾î¿Í %v º¯¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ º¯¼ö¸¦ ·Î±× +Çü½Ä¹®ÀÚ¿­ ¾Õ¿¡ Ãß°¡ÇÑ´Ù:

    + +

    +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +

    + +

    ±×·¯¸é common ·Î±×Çü½Ä ¾Õ¿¡ (ServerName Áö½Ã¾î¿¡ ³ª¿À´Â) Á¤±Ô +°¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÏ¿© ·Î±×ÆÄÀÏÀ» ±â·ÏÇÑ´Ù. (·Î±×ÆÄÀÏ +»ç¿ëÀÚÁ¤ÀÇ¿¡ °üÇÑ ³»¿ëÀº »ç¿ëÀÚÁ¤ÀÇ ·Î±×Çü½ÄÀ» +Âü°íÇ϶ó.)

    + +

    ·Î±×ÆÄÀÏÀ» (°¡»óÈ£½ºÆ®´ç ÇÑ ÆÄÀϾ¿) ³ª´©°í ½Í´Ù¸é split-logfile ÇÁ·Î±×·¥À» +»ç¿ëÇÑ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡ ¹èÆ÷º»ÀÇ support +µð·ºÅ丮¿¡ ÀÖ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù:

    + +

    +split-logfile < /logs/multiple_vhost_log +

    + +

    °¡»óÈ£½ºÆ® ·Î±×ÆÄÀÏÀ» °¡Áö°í ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¸é ·Î±×ÆÄÀÏ¿¡ +³ª¿À´Â °¢ °¡»óÈ£½ºÆ®´ç ÆÄÀÏÀ» Çϳª¾¿ ¸¸µç´Ù. °¢°¢ÀÇ ÆÄÀϸíÀº +hostname.logÀÌ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/fd-limits.xml b/trunk/docs/manual/vhosts/fd-limits.xml new file mode 100644 index 0000000000..54a3563aba --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.xml @@ -0,0 +1,124 @@ + + + + + + + + +Virtual Hosts + File Descriptor Limits + + + +

    When using a large number of Virtual Hosts, Apache may run + out of available file descriptors (sometimes called file + handles) if each Virtual Host specifies different log + files. The total number of file descriptors used by Apache is + one for each distinct error log file, one for every other log + file directive, plus 10-20 for internal use. Unix operating + systems limit the number of file descriptors that may be used + by a process; the limit is typically 64, and may usually be + increased up to a large hard-limit.

    + +

    Although Apache attempts to increase the limit as required, + this may not work if:

    + +
      +
    1. Your system does not provide the setrlimit() + system call.
    2. + +
    3. The setrlimit(RLIMIT_NOFILE) call does not + function on your system (such as Solaris 2.3)
    4. + +
    5. The number of file descriptors required exceeds the hard + limit.
    6. + +
    7. Your system imposes other limits on file descriptors, + such as a limit on stdio streams only using file descriptors + below 256. (Solaris 2)
    8. +
    + +

    In the event of problems you can:

    + +
      +
    • Reduce the number of log files; don't specify log files + in the VirtualHost + sections, but only log to the main log files. (See Splitting up your log files, below, for more + information on doing this.)
    • + +
    • + If you system falls into 1 or 2 (above), then increase the + file descriptor limit before starting Apache, using a + script like + + + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      +
      +
    • +
    + +
    + +
    Splitting up your log files + +

    If you want to log multiple virtual hosts to the same log file, you +may want to split up the log files afterwards in order to run +statistical analysis of the various virtual hosts. This can be +accomplished in the following manner.

    + +

    First, you will need to add the virtual host information to the log +entries. This can be done using the +LogFormat +directive, and the %v variable. Add this to the beginning +of your log format string:

    + + +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +
    + +

    This will create a log file in the common log format, but with the +canonical virtual host (whatever appears in the +ServerName directive) prepended to +each line. (See Custom Log Formats for +more about customizing your log files.)

    + +

    When you wish to split your log file into its component parts (one +file per virtual host) you can use the program split-logfile to accomplish +this. You'll find this program in the support directory +of the Apache distribution.

    + +

    Run this program with the command:

    + + +split-logfile < /logs/multiple_vhost_log + + +

    This program, when run with the name of your vhost log file, will +generate one file for each virtual host that appears in your log file. +Each file will be called hostname.log.

    + +
    +
    + diff --git a/trunk/docs/manual/vhosts/fd-limits.xml.ja b/trunk/docs/manual/vhosts/fd-limits.xml.ja new file mode 100644 index 0000000000..41d0817837 --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.xml.ja @@ -0,0 +1,121 @@ + + + + + + + + +$B%P!<%A%c%k%[%9%H(B + $B%U%!%$%k5-=R;R$N8B3&(B + + + +

    $B$?$/$5$s$N%P!<%A%c%k%[%9%H$r1?MQ$9$k>l9g!"$b$7!"(B + $B3F%P!<%A%c%k%[%9%H$4$H$K0[$J$k%m%0%U%!%$%k$,;XDj$7$F$"$k$H!"(B + Apache $B$,%U%!%$%k5-=R;R(B ($B%U%!%$%k%O%s%I%k(B$B$H$b8F$P$l$^$9(B) + $B$r;H$$@Z$C$F$7$^$&$3$H$,$"$j$^$9!#(BApache $B$,;HMQ$9$k%U%!%$%k(B + $B5-=R;R$N?t$O!"3F%(%i!<%m%0%U%!%$%k$K$D$-(B 1 $B$D!"B>$N%m%0%U%!%$%k$N(B + $B%G%#%l%/%F%#%V$K$D$-(B 1 $B$D!"$5$i$KFbIt$G;HMQ$9$k(B 10 $B$+$i(B 20$B!"(B + $B$N9g7W$K$J$j$^$9!#(BUnix $B%*%Z%l!<%F%#%s%0%7%9%F%`$G$O%W%m%;%9$4$H$K(B + $B;HMQ2DG=$J%U%!%$%k5-=R;R$N?t$r@)8B$7$F$$$^$9!#$?$$$F$$$N>l9g$O(B 64 $B$G!"(B + $BIaDL$OBg$-$JCM$N%O!<%I%j%_%C%H$^$GA}$d$9$3$H$,$G$-$^$9!#(B

    + +

    Apache $B$OI,MW$K1~$8$F>e8B$r3HBg$7$h$&$H;n$_$^$9$,!"(B + $B0J2<$N$h$&$J>l9g$K$O$&$^$/$$$+$J$$$+$b$7$l$^$;$s!#(B

    + +
      +
    1. $BMxMQ$7$F$$$k%7%9%F%`$G(B setrlimit() + $B%7%9%F%`%3!<%k$,Ds6!$5$l$F$$$J$$!#(B
    2. + +
    3. $B%7%9%F%`>e$G(B setrlimit(RLIMIT_NOFILE) $B$,F0:n$7$J$$(B + ($B$?$H$($P(B Solaris 2.3 $B$N$h$&$K(B)$B!#(B
    4. + +
    5. $BMW5a$5$l$k%U%!%$%k5-=R;R$N?t$,(B + $B%O!<%I%j%_%C%H$rD6$($F$7$^$&!#(B
    6. + +
    7. $B%7%9%F%`$K%U%!%$%k5-=R;R$K4X$7$FJL$N@)8B$,B8:_$7$F$7$^$C$F$$$k!#(B + $B$?$H$($P!"(Bstdio $B%9%H%j!<%`$G$O%U%!%$%k5-=R;R$r(B 256 $B0J>e;H$($J$$(B + (Solaris 2)$B!"$J$I!#(B
    8. +
    + +

    $BLdBj$,H/@8$7$?;~$K + +

      +
    • $B%m%0%U%!%$%k$N?t$r8:$i$9!#(BVirtualHost + $B%;%/%7%g%s$G%m%0%U%!%$%k$r;XDj$;$:!"%a%$%s$N%m%0%U%!%$%k$K$N$_5-O?$9$k!#(B + ($B$3$l$K4X$9$k>\$7$$>pJs$O0J2<$N(B$B%m%0%U%!%$%k$NJ,3d(B$B$rFI$s$G$/$@$5$$!#(B)
    • + +
    • + $B$b$7!"A0=R$N(B 1 $B$^$?$O(B 2 $B$N>l9g$G$"$l$P!"(B + Apache $B$r5/F0$9$kA0$K%U%!%$%k5-=R;R$rA}$d$7$^$9!#(B + $B$?$H$($P + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      + +
    • +
    +
    + +
    $B%m%0%U%!%$%k$NJ,3d(B + +

    $BJ#?t$N%P!<%A%c%k%[%9%H$N%m%0$rF1$8%m%0%U%!%$%k$K<}=8$7$h$&$H$7$F$$$k$H$-$K$O!"(B +$B3F%P!<%A%c%k%[%9%H$K$D$$$FE}7WE*$J2r@O$r + +

    $B$^$:!"%P!<%A%c%k%[%9%H$N>pJs$r%m%0$N%(%s%H%j$KDI2C$9$kI,MW$,$"$j$^$9!#(B +$B$3$l$O(B LogFormat +$B%G%#%l%/%F%#%V$N(B %v $BJQ?t$r;H$&$3$H$G$G$-$^$9!#(B +$B$3$l$r%m%0$N%U%)!<%^%C%HJ8;zNs$N@hF,$KDI2C$7$^$9(B:

    + + +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +
    + +

    $B$3$l$O(B common log format $B$N%m%0$r:n@.$7$^$9$,!"$=$l$>$l$N9T$N@hF,$K(B +$B@55,2=$5$l$?%P!<%A%c%k%[%9%H$NL>A0(B +(ServerName +$B%G%#%l%/%F%#%V$K=q$+$l$F$$$k$b$N(B) $B$,IU2C$5$l$^$9!#(B +($B%m%0%U%!%$%k$N%+%9%?%^%$%:$N>\:Y$K$D$$$F$O(B Custom Log Formats $B$r(B +$BFI$s$G$/$@$5$$!#(B)

    + +

    $B%m%0%U%!%$%k$r3FItJ,(B ($B%P!<%A%c%k%[%9%HKh$K(B 1 $B%U%!%$%k(B) $B$KJ,$1$?$$$H$-$O!"(B +split-logfile +$B$r;H$C$F9T$J$&$3$H$,$G$-$^$9!#%W%m%0%i%`$O(B Apache $BG[I[$N(B +support $B%G%#%l%/%H%j$K$"$j$^$9!#(B

    + +

    $B0J2<$N$h$&$J%3%^%s%I$G$3$N%W%m%0%i%`$r + + +split-logfile < /logs/multiple_vhost_log + + +

    $B$3$N%W%m%0%i%`$O%P!<%A%c%k%[%9%H$N%m%0%U%!%$%k$NL>A0$H$H$b$K$l$N%P!<%A%c%k%[%9%HKh$K0l$D$N%U%!%$%k$r:n@.$7$^$9!#(B +$B$=$l$>$l$N%U%!%$%k$O(B $B%[%9%HL>(B.log $B$H$$$&L>A0$K$J$j$^$9!#(B

    + +
    +
    + diff --git a/trunk/docs/manual/vhosts/fd-limits.xml.ko b/trunk/docs/manual/vhosts/fd-limits.xml.ko new file mode 100644 index 0000000000..53c75e22af --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.xml.ko @@ -0,0 +1,119 @@ + + + + + + + + +°¡»óÈ£½ºÆ® + ÆÄÀϱâ¼úÀÚ(file descriptor) ÇÑ°è + + + +

    °¡»óÈ£½ºÆ®¸¦ ¸¹ÀÌ »ç¿ëÇÏ°í °¢ °¡»óÈ£½ºÆ®¿¡ ¼­·Î ´Ù¸¥ + ·Î±×ÆÄÀÏÀ» ÁöÁ¤Çϸé, ¾ÆÆÄÄ¡°¡ »ç¿ë°¡´ÉÇÑ ÆÄÀϱâ¼úÀÚ(file + descriptor, ÈçÈ÷ ÆÄÀÏÇÚµé(file handle)À̶ó°í + ºÎ¸§)¸¦ ´Ù ½á¹ö¸± ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡°¡ »ç¿ëÇÏ´Â ÆÄÀϱâ¼úÀÚÀÇ + ÃÑ °³¼ö´Â ¿À·ù ·Î±×ÆÄÀÏ´ç ÇÑ°³, ´Ù¸¥ ·Î±×ÆÄÀÏ Áö½Ã¾î´ç + ÇÑ°³, Ãß°¡·Î ³»ºÎ¿ëµµ·Î 10-20°³¸¦ ´õÇÑ ¼ö´Ù. À¯´Ð½º ¿î¿µÃ¼Á¦´Â + ÇÁ·Î¼¼½º°¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ÆÄÀϱâ¼úÀÚ °³¼ö¸¦ Á¦ÇÑÇÑ´Ù. ÀÌ ÇÑ°è´Â + º¸Åë 64°³·Î, º¸Åë À̺¸´Ù Å« hard-limit±îÁö ´Ã¸± ¼ö ÀÖ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ÀÌ ÇѰ踦 ÇÊ¿äÇѸ¸Å­ ´Ã¸®·Á°í ÇÏÁö¸¸, ½ÇÆÐÇÏ´Â + °æ¿ì°¡ ÀÖ´Ù:

    + +
      +
    1. ½Ã½ºÅÛÀÌ setrlimit() ½Ã½ºÅÛÈ£ÃâÀ» + Á¦°øÇÏÁö ¾Ê´Â´Ù.
    2. + +
    3. (Solaris 2.3°ú °°ÀÌ) ½Ã½ºÅÛ¿¡¼­ + setrlimit(RLIMIT_NOFILE) ÇÔ¼ö°¡ µ¿ÀÛÇÏÁö + ¾Ê´Â´Ù.
    4. + +
    5. ÇÊ¿äÇÑ ÆÄÀϱâ¼úÀÚ °³¼ö°¡ hard limit º¸´Ù ¸¹´Ù.
    6. + +
    7. (Solaris 2) ½Ã½ºÅÛÀÌ stdio ½ºÆ®¸²À» 256ÀÌÇÏÀÇ + ÆÄÀϱâ¼úÀÚ¸¸À» »ç¿ëÇϵµ·Ï Á¦ÇÑÇÏ´Â µî ÆÄÀϱâ¼úÀÚ¿¡ + Á¦¾àÀ» °¡ÇÑ´Ù.
    8. +
    + +

    ÀÌ °æ¿ì ÇØ°áÃ¥Àº:

    + +
      +
    • ·Î±×ÆÄÀÏ °³¼ö¸¦ ÁÙÀδÙ. VirtualHost ¼½¼Ç¿¡¼­ ·Î±×ÆÄÀÏÀ» + ÁöÁ¤ÇÏÁö ¾Ê°í ÁÖ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÑ´Ù. (´õ ÀÚ¼¼ÇÑ ¹æ¹ýÀº + ¾Æ·¡ ·Î±×ÆÄÀÏ ³ª´©±â¸¦ Âü°íÇ϶ó.)
    • + +
    • + »ç¿ëÇÏ´Â ½Ã½ºÅÛÀÌ (À§ÀÇ) 1¹ø°³ª 2¹ø° °æ¿ì¿¡ ÇØ´çÇÑ´Ù¸é, + ´ÙÀ½°ú °°Àº ½ºÅ©¸³Æ®·Î ¾ÆÆÄÄ¡¸¦ ½ÃÀÛÇϱâ Àü¿¡ ÆÄÀϱâ¼úÀÚ + ÇѰ踦 ´Ã¸°´Ù. + + + #!/bin/sh
      + ulimit -S -n 100
      + exec httpd
      +
      +
    • +
    + +
    + +
    ·Î±×ÆÄÀÏ ³ª´©±â + +

    ¿©·¯ °¡»óÈ£½ºÆ®°¡ °°Àº ·Î±×ÆÄÀÏÀ» »ç¿ëÇÑ´Ù¸é ³ªÁß¿¡ °¢ +°¡»óÈ£½ºÆ®ÀÇ Åë°èºÐ¼®À» À§ÇØ ·Î±×ÆÄÀÏÀ» ³ª´©°í ½ÍÀ» °ÍÀÌ´Ù. +ÀÌ ÀÛ¾÷Àº ´ÙÀ½°ú °°ÀÌ ÇÒ ¼ö ÀÖ´Ù.

    + +

    ¸ÕÀú ·Î±× Ç׸ñ¿¡ °¡»óÈ£½ºÆ® Á¤º¸¸¦ Ãß°¡ÇÑ´Ù. À̸¦ À§ÇØ +LogFormat +Áö½Ã¾î¿Í %v º¯¼ö¸¦ »ç¿ëÇÑ´Ù. ÀÌ º¯¼ö¸¦ ·Î±× +Çü½Ä¹®ÀÚ¿­ ¾Õ¿¡ Ãß°¡ÇÑ´Ù:

    + + +LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost
    +CustomLog logs/multiple_vhost_log vhost +
    + +

    ±×·¯¸é common ·Î±×Çü½Ä ¾Õ¿¡ (ServerName Áö½Ã¾î¿¡ ³ª¿À´Â) Á¤±Ô +°¡»óÈ£½ºÆ®¸¦ Æ÷ÇÔÇÏ¿© ·Î±×ÆÄÀÏÀ» ±â·ÏÇÑ´Ù. (·Î±×ÆÄÀÏ +»ç¿ëÀÚÁ¤ÀÇ¿¡ °üÇÑ ³»¿ëÀº »ç¿ëÀÚÁ¤ÀÇ ·Î±×Çü½ÄÀ» +Âü°íÇ϶ó.)

    + +

    ·Î±×ÆÄÀÏÀ» (°¡»óÈ£½ºÆ®´ç ÇÑ ÆÄÀϾ¿) ³ª´©°í ½Í´Ù¸é split-logfile ÇÁ·Î±×·¥À» +»ç¿ëÇÑ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ¾ÆÆÄÄ¡ ¹èÆ÷º»ÀÇ support +µð·ºÅ丮¿¡ ÀÖ´Ù.

    + +

    ´ÙÀ½°ú °°ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù:

    + + +split-logfile < /logs/multiple_vhost_log + + +

    °¡»óÈ£½ºÆ® ·Î±×ÆÄÀÏÀ» °¡Áö°í ÀÌ ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¸é ·Î±×ÆÄÀÏ¿¡ +³ª¿À´Â °¢ °¡»óÈ£½ºÆ®´ç ÆÄÀÏÀ» Çϳª¾¿ ¸¸µç´Ù. °¢°¢ÀÇ ÆÄÀϸíÀº +hostname.logÀÌ´Ù.

    + +
    +
    + diff --git a/trunk/docs/manual/vhosts/fd-limits.xml.meta b/trunk/docs/manual/vhosts/fd-limits.xml.meta new file mode 100644 index 0000000000..c58579265b --- /dev/null +++ b/trunk/docs/manual/vhosts/fd-limits.xml.meta @@ -0,0 +1,13 @@ + + + + fd-limits + /vhosts/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/vhosts/index.html b/trunk/docs/manual/vhosts/index.html new file mode 100644 index 0000000000..f2b6eb94f2 --- /dev/null +++ b/trunk/docs/manual/vhosts/index.html @@ -0,0 +1,15 @@ +URI: index.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: index.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: index.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/index.html.de b/trunk/docs/manual/vhosts/index.html.de new file mode 100644 index 0000000000..7493e0a85b --- /dev/null +++ b/trunk/docs/manual/vhosts/index.html.de @@ -0,0 +1,106 @@ + + + +Apache-Dokumentation zu virtuellen Hosts - Apache HTTP Server + + + + + +
    <-
    +

    Apache-Dokumentation zu virtuellen Hosts

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + +

    Der Begriff virtueller Host (Anm.d.Ü.: engl. 'virtual + host') bezieht sich auf die Praxis, mehr als ein Webangebot + (z.B. www.company1.com und www.company2.com) + auf einer einzigen Maschine zu betreiben. Virtuelle Hosts können + "IP-basiert" sein, was bedeutet, dass jedes + Webangebot eine andere IP besitzt, oder "Namens-basiert", was bedeutet, dass + unter jeder IP-Adresse mehrere Namen laufen. Die Tatsache, dass sie + auf dem gleichen physischen Server laufen, ist für den Endbenutzer + nicht offensichtlich.

    + +

    Der Apache war einer der ersten Server, der IP-basierte + virtuelle Hosts von Haus aus direkt unterstützt hat. Seit Version 1.1 + unterstützt der Apache sowohl IP-basierte als auch namensbasierte + virtuelle Hosts (vhosts). Letzteres wird zuweilen auch + Host-basiert oder non-IP-Virtual-Host genannt.

    + +

    Nachfolgend finden Sie eine Liste von Dokumenten, die alle Details + der Unterstützung von virtuellen Hosts ab Apache Version 1.3 + beschreiben.

    + +
    + +
    top
    +
    top
    +
    +

    Konfigurationsdirektiven

    + + + +

    Bei der Suche von Fehlern in Ihrer Virtual-Host-Konfiguration ist + die Apache-Befehlszeilenoption -S möglicherweise + hilfreich. Geben Sie dazu den folgenden Befehl ein:

    + +

    + /usr/local/apache2/bin/httpd -S +

    + +

    Diese Anweisung gibt eine Beschreibung aus, wie der Apache die + Konfigurationsdatei analysiert hat. Eine sorgfältige + Überprüfung der IP-Adressen und Servernamen kann helfen, + Konfigurationsfehler aufzudecken. (Lesen Sie die Dokumentation zum + httpd-Programm für weitere + Befehlszeilenoptionen.)

    +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/index.html.en b/trunk/docs/manual/vhosts/index.html.en new file mode 100644 index 0000000000..fb2b084f6f --- /dev/null +++ b/trunk/docs/manual/vhosts/index.html.en @@ -0,0 +1,106 @@ + + + +Apache Virtual Host documentation - Apache HTTP Server + + + + + +
    <-
    +

    Apache Virtual Host documentation

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + + +

    The term Virtual Host refers to the practice of + running more than one web site (such as + www.company1.com and www.company2.com) + on a single machine. Virtual hosts can be "IP-based", meaning that you have a + different IP address for every web site, or "name-based", meaning that you have + multiple names running on each IP address. The fact that they + are running on the same physical server is not apparent to the + end user.

    + +

    Apache was one of the first servers to support IP-based + virtual hosts right out of the box. Versions 1.1 and later of + Apache support both IP-based and name-based virtual hosts + (vhosts). The latter variant of virtual hosts is sometimes also + called host-based or non-IP virtual hosts.

    + +

    Below is a list of documentation pages which explain all + details of virtual host support in Apache version 1.3 and + later.

    + +
    + +
    top
    +
    top
    +
    +

    Configuration directives

    + + + +

    If you are trying to debug your virtual host configuration, you + may find the Apache -S command line switch + useful. That is, type the following command:

    + +

    + /usr/local/apache2/bin/httpd -S +

    + +

    This command will dump out a description of how Apache parsed + the configuration file. Careful examination of the IP addresses and + server names may help uncover configuration mistakes. (See + the docs for the httpd program for + other command line options)

    + +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/index.html.ja.euc-jp b/trunk/docs/manual/vhosts/index.html.ja.euc-jp new file mode 100644 index 0000000000..476b32a15c --- /dev/null +++ b/trunk/docs/manual/vhosts/index.html.ja.euc-jp @@ -0,0 +1,101 @@ + + + +Apache ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈÀâÌÀ½ñ - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥ÈÀâÌÀ½ñ

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + + +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤È¤¤¤¦ÍѸì¤Ï¡¢1 Âæ¤Î¥Þ¥·¥ó¾å¤Ç + (www.company1.com and www.company2.com ¤Î¤è¤¦¤Ê) + Æó¤Ä°Ê¾å¤Î¥¦¥§¥Ö¥µ¥¤¥È¤ò°·¤¦±¿ÍÑÊýË¡¤Î¤³¤È¤ò»Ø¤·¤Þ¤¹¡£ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤Ï¡¢³Æ¥¦¥§¥Ö¥µ¥¤¥È¤Ë°ã¤¦ IP ¥¢¥É¥ì¥¹¤¬¤¢¤ë + ¡ÖIP ¥Ù¡¼¥¹¡×¤È¡¢¤½¤ì¤¾¤ì¤Î IP ¥¢¥É¥ì¥¹¤Ë + Ê£¿ô¤Î̾Á°¤¬¤¢¤ë¡Ö̾Á°¥Ù¡¼¥¹¡×¤È¤¬¤¢¤ê¤Þ¤¹¡£ + Ê£¿ô¤Î¥µ¥¤¥È¤¬ÊªÍýŪ¤ËƱ¤¸¥µ¡¼¥Ð¤Ç°·¤ï¤ì¤Æ¤¤¤ë¡¢¤È¤¤¤¦¤³¤È¤Ï¥¨¥ó¥É¥æ¡¼¥¶¤Ë¤Ï + ÌÀ¤é¤«¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£

    + +

    Apache ¤Ï¡¢Æä˼ê¤òÆþ¤ì¤Ê¤¤¾õÂÖ¤Ç IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È + ¤ò¥µ¥Ý¡¼¥È¤·¤¿ºÇ½é¤Î¥µ¡¼¥Ð¤Î°ì¤Ä¤Ç¤¹¡£¥Ð¡¼¥¸¥ç¥ó 1.1 °Ê¹ß¤Î Apache + ¤Ç¤Ï¡¢IP ¥Ù¡¼¥¹¤È¥Í¡¼¥à¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎξÊý¤ò¥µ¥Ý¡¼¥È + ¤·¤Æ¤¤¤Þ¤¹¡£¥Í¡¼¥à¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï¡¢¥Û¥¹¥È¥Ù¡¼¥¹¤¢¤ë¤¤¤Ï + Èó IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤È¸Æ¤Ð¤ì¤ë¤³¤È¤â¤¢¤ê¤Þ¤¹¡£

    + +

    °Ê²¼¤Î¥Ú¡¼¥¸¤Ç¤Ï¡¢Apache ¥Ð¡¼¥¸¥ç¥ó 1.3 + °Ê¹ß¤Ç¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥µ¥Ý¡¼¥È¤Ë¤Ä¤¤¤Æ¤Î¾ÜºÙ¤òÀâÌÀ¤·¤Þ¤¹¡£

    + +
    + +
    top
    +
    top
    +
    +

    ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö

    + + + +

    ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤Î¥Ç¥Ð¥Ã¥°¤ò¤¹¤ë¤Ë¤Ï + Apache ¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¥¹¥¤¥Ã¥Á -S ¤¬ÊØÍø¤Ç¤¹¡£ + ¤Ä¤Þ¤ê¡¢°Ê²¼¤Î¥³¥Þ¥ó¥É¤òÆþÎϤ·¤Þ¤¹:

    + +

    + /usr/local/apache2/bin/httpd -S +

    + +

    ¤³¤Î¥³¥Þ¥ó¥É¤Ï Apache ¤¬ÀßÄê¥Õ¥¡¥¤¥ë¤ò¤É¤¦²òÀϤ·¤¿¤«¤Ë¤Ä¤¤¤Æ½ÐÎϤ·¤Þ¤¹¡£ + IP ¥¢¥É¥ì¥¹¤È¥µ¡¼¥Ð̾¤òÃí°Õ¿¼¤¯Ä´¤Ù¤ì¤Ð¡¢ + ÀßÄê¤Î´Ö°ã¤¤¤ò¸«¤Ä¤±¤ë½õ¤±¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£ + (¾¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¤Î¥ª¥×¥·¥ç¥ó¤Ï httpd + ¥×¥í¥°¥é¥à¤ÎÀâÌÀʸ½ñ¤ò¸«¤Æ¤¯¤À¤µ¤¤)

    + +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/index.html.ko.euc-kr b/trunk/docs/manual/vhosts/index.html.ko.euc-kr new file mode 100644 index 0000000000..2095299aea --- /dev/null +++ b/trunk/docs/manual/vhosts/index.html.ko.euc-kr @@ -0,0 +1,104 @@ + + + +¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­ - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    °¡»óÈ£½ºÆ® (Virtual Host)´Â ÇÑ ÄÄÇ»ÅÍ¿¡¼­ + ¿©·¯ À¥»çÀÌÆ®¸¦ (¿¹¸¦ µé¾î, www.company1.com°ú + www.company2.com) ¼­ºñ½ºÇÔÀ» ¶æÇÑ´Ù. + °¡»óÈ£½ºÆ®¿¡´Â °¢ À¥»çÀÌÆ®¸¶´Ù ´Ù¸¥ IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ´Â + "IP±â¹Ý (IP-based)" ¹æ½Ä°ú ÇÑ + IP ÁÖ¼Ò´ç ¿©·¯ À̸§À» °¡Áö´Â "À̸§±â¹Ý (name-based)" ¹æ½ÄÀÌ + ÀÖ´Ù. ¿©·¯ »çÀÌÆ®µéÀÌ °°Àº ¼­¹ö¿¡¼­ µ¹°íÀÖ´Ù´Â »ç½ÇÀ» À¥»ç¿ëÀÚ´Â + ´«Ä¡Ã¤Áö ¸øÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ±âº»À¸·Î IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÑ ÃÊâ±â + ¼­¹öµéÁß Çϳª´Ù. ¾ÆÆÄÄ¡ ¹öÀü 1.1 ÀÌ»óÀº IP±â¹Ý°ú À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ ¸ðµÎ Áö¿øÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ + È£½ºÆ®±â¹Ý (host-based) ¶Ç´Â ºñIP °¡»óÈ£½ºÆ® + (non-IP virtual hosts)¶ó°íµµ ºÎ¸¥´Ù.

    + +

    ´ÙÀ½Àº ¾ÆÆÄÄ¡ ¹öÀü 1.3 ÀÌ»óÀÇ °¡»óÈ£½ºÆ® Áö¿øÀ» ÀÚ¼¼È÷ + ¼³¸íÇÑ ¹®¼­µéÀÌ´Ù.

    + +
    + +
    top
    +
    top
    +
    +

    ¼³Á¤ Áö½Ã¾î

    + + + +

    °¡»óÈ£½ºÆ® ¼³Á¤À» Å×½ºÆ®ÇÒ¶§ ¾ÆÆÄÄ¡ÀÇ -S + ¸í·ÉÇà ¿É¼ÇÀÌ À¯¿ëÇÏ´Ù. Áï, ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù:

    + +

    + /usr/local/apache2/bin/httpd -S +

    + +

    ÀÌ ¸í·É¾î´Â ¾ÆÆÄÄ¡°¡ ÀÐÀº ¼³Á¤ÆÄÀÏ¿¡ ´ëÇÑ + Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. IP ÁÖ¼Ò¿Í ¼­¹ö¸íÀ» ÀÚ¼¼È÷ »ìÆ캸¸é ¼³Á¤¿¡¼­ + ½Ç¼ö¸¦ ¹ß°ßÇϴµ¥ µµ¿òÀÌ µÉ °ÍÀÌ´Ù. (´Ù¸¥ ¸í·ÉÇà ¿É¼ÇµéÀº + httpd ÇÁ·Î±×·¥ ¹®¼­¸¦ + Âü°íÇ϶ó.)

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/index.xml b/trunk/docs/manual/vhosts/index.xml new file mode 100644 index 0000000000..3e73056adc --- /dev/null +++ b/trunk/docs/manual/vhosts/index.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + Apache Virtual Host documentation + + + +

    The term Virtual Host refers to the practice of + running more than one web site (such as + www.company1.com and www.company2.com) + on a single machine. Virtual hosts can be "IP-based", meaning that you have a + different IP address for every web site, or "name-based", meaning that you have + multiple names running on each IP address. The fact that they + are running on the same physical server is not apparent to the + end user.

    + +

    Apache was one of the first servers to support IP-based + virtual hosts right out of the box. Versions 1.1 and later of + Apache support both IP-based and name-based virtual hosts + (vhosts). The latter variant of virtual hosts is sometimes also + called host-based or non-IP virtual hosts.

    + +

    Below is a list of documentation pages which explain all + details of virtual host support in Apache version 1.3 and + later.

    + +
    + +mod_vhost_alias +Name-based virtual +hosts +IP-based virtual hosts +Virtual host examples +File descriptor limits +Mass virtual hosting +Details of host matching + +
    Virtual Host Support + + + +
    + +
    Configuration directives + +
      +
    • VirtualHost
    • +
    • NameVirtualHost
    • +
    • ServerName
    • +
    • ServerAlias
    • +
    • ServerPath
    • +
    + +

    If you are trying to debug your virtual host configuration, you + may find the Apache -S command line switch + useful. That is, type the following command:

    + + + /usr/local/apache2/bin/httpd -S + + +

    This command will dump out a description of how Apache parsed + the configuration file. Careful examination of the IP addresses and + server names may help uncover configuration mistakes. (See + the docs for the httpd program for + other command line options)

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/index.xml.de b/trunk/docs/manual/vhosts/index.xml.de new file mode 100644 index 0000000000..378ff85ff1 --- /dev/null +++ b/trunk/docs/manual/vhosts/index.xml.de @@ -0,0 +1,106 @@ + + + + + + + + + + + Apache-Dokumentation zu virtuellen Hosts + + +

    Der Begriff virtueller Host engl. 'virtual + host' bezieht sich auf die Praxis, mehr als ein Webangebot + (z.B. www.company1.com und www.company2.com) + auf einer einzigen Maschine zu betreiben. Virtuelle Hosts können + "IP-basiert" sein, was bedeutet, dass jedes + Webangebot eine andere IP besitzt, oder "Namens-basiert", was bedeutet, dass + unter jeder IP-Adresse mehrere Namen laufen. Die Tatsache, dass sie + auf dem gleichen physischen Server laufen, ist für den Endbenutzer + nicht offensichtlich.

    + +

    Der Apache war einer der ersten Server, der IP-basierte + virtuelle Hosts von Haus aus direkt unterstützt hat. Seit Version 1.1 + unterstützt der Apache sowohl IP-basierte als auch namensbasierte + virtuelle Hosts (vhosts). Letzteres wird zuweilen auch + Host-basiert oder non-IP-Virtual-Host genannt.

    + +

    Nachfolgend finden Sie eine Liste von Dokumenten, die alle Details + der Unterstützung von virtuellen Hosts ab Apache Version 1.3 + beschreiben.

    + +
    + +mod_vhost_alias +Namensbasierte virtuelle Hosts +IP-basierte virtuelle Hosts +Beispiele für virtuelle + Hosts +Datei-Deskriptor-Begrenzungen +Massen-Virtual-Hosting +Zuweisung virtueller Hosts + +
    Unterstützung virtueller Hosts + + + +
    + +
    Konfigurationsdirektiven + +
      +
    • VirtualHost
    • +
    • NameVirtualHost
    • +
    • ServerName
    • +
    • ServerAlias
    • +
    • ServerPath
    • +
    + +

    Bei der Suche von Fehlern in Ihrer Virtual-Host-Konfiguration ist + die Apache-Befehlszeilenoption -S möglicherweise + hilfreich. Geben Sie dazu den folgenden Befehl ein:

    + + + /usr/local/apache2/bin/httpd -S + + +

    Diese Anweisung gibt eine Beschreibung aus, wie der Apache die + Konfigurationsdatei analysiert hat. Eine sorgfältige + Überprüfung der IP-Adressen und Servernamen kann helfen, + Konfigurationsfehler aufzudecken. (Lesen Sie die Dokumentation zum + httpd-Programm für weitere + Befehlszeilenoptionen.)

    +
    +
    diff --git a/trunk/docs/manual/vhosts/index.xml.ja b/trunk/docs/manual/vhosts/index.xml.ja new file mode 100644 index 0000000000..32567308c0 --- /dev/null +++ b/trunk/docs/manual/vhosts/index.xml.ja @@ -0,0 +1,100 @@ + + + + + + + + + + + Apache $B%P!<%A%c%k%[%9%H@bL@=q(B + + + +

    $B%P!<%A%c%k%[%9%H(B$B$H$$$&MQ8l$O!"(B1 $BBf$N%^%7%s>e$G(B + (www.company1.com and www.company2.com $B$N$h$&$J(B) + $BFs$D0J>e$N%&%'%V%5%$%H$r07$&1?MQJ}K!$N$3$H$r;X$7$^$9!#(B + $B%P!<%A%c%k%[%9%H$K$O!"3F%&%'%V%5%$%H$K0c$&(B IP $B%"%I%l%9$,$"$k(B + $B!V(BIP $B%Y!<%9(B$B!W$H!"$=$l$>$l$N(B IP $B%"%I%l%9$K(B + $BJ#?t$NL>A0$,$"$k!V(B$BL>A0%Y!<%9(B$B!W$H$,$"$j$^$9!#(B + $BJ#?t$N%5%$%H$,J*M}E*$KF1$8%5!<%P$G07$o$l$F$$$k!"$H$$$&$3$H$O%(%s%I%f!<%6$K$O(B + $BL@$i$+$G$O$"$j$^$;$s!#(B

    + +

    Apache $B$O!"FC$KuBV$G(B IP $B%Y!<%9$N%P!<%A%c%k%[%9%H(B + $B$r%5%]!<%H$7$?:G=i$N%5!<%P$N0l$D$G$9!#%P!<%8%g%s(B 1.1 $B0J9_$N(B Apache + $B$G$O!"(BIP $B%Y!<%9$H%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H$NN>J}$r%5%]!<%H(B + $B$7$F$$$^$9!#%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H$O!"(B$B%[%9%H%Y!<%9(B$B$"$k$$$O(B + $BHs(B IP $B%Y!<%9(B$B$N%P!<%A%c%k%[%9%H$H8F$P$l$k$3$H$b$"$j$^$9!#(B

    + +

    $B0J2<$N%Z!<%8$G$O!"(BApache $B%P!<%8%g%s(B 1.3 + $B0J9_$G$N%P!<%A%c%k%[%9%H$N%5%]!<%H$K$D$$$F$N>\:Y$r@bL@$7$^$9!#(B

    + +
    + +mod_vhost_alias +$B%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H(B +IP $B%Y!<%9$N%P!<%A%c%k%[%9%H(B +$B%P!<%A%c%k%[%9%H$N0lHLE*$J@_DjNc(B +$B%U%!%$%k5-=R;R$N8B3&(B +$BBgNL$N%P!<%A%c%k%[%9%H$N@_Dj(B +$B%P!<%A%c%k%[%9%H$N%^%C%A%s%0$K$D$$$F$N>\:Y(B + +
    $B%P!<%A%c%k%[%9%H$N%5%]!<%H(B + + + +
    + +
    $B@_Dj%G%#%l%/%F%#%V(B + +
      +
    • VirtualHost
    • +
    • NameVirtualHost
    • +
    • ServerName
    • +
    • ServerAlias
    • +
    • ServerPath
    • +
    + +

    $B%P!<%A%c%k%[%9%H$N@_Dj$N%G%P%C%0$r$9$k$K$O(B + Apache $B$N%3%^%s%I%i%$%s%9%$%C%A(B -S $B$,JXMx$G$9!#(B + $B$D$^$j!"0J2<$N%3%^%s%I$rF~NO$7$^$9(B:

    + + + /usr/local/apache2/bin/httpd -S + + +

    $B$3$N%3%^%s%I$O(B Apache $B$,@_Dj%U%!%$%k$r$I$&2r@O$7$?$+$K$D$$$F=PNO$7$^$9!#(B + IP $B%"%I%l%9$H%5!<%PL>$rCm0U?<$/D4$Y$l$P!"(B + $B@_Dj$N4V0c$$$r8+$D$1$k=u$1$K$J$k$G$7$g$&!#(B + ($BB>$N%3%^%s%I%i%$%s$N%*%W%7%g%s$O(B httpd + $B%W%m%0%i%`$N@bL@J8=q$r8+$F$/$@$5$$(B)

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/index.xml.ko b/trunk/docs/manual/vhosts/index.xml.ko new file mode 100644 index 0000000000..ed4726a188 --- /dev/null +++ b/trunk/docs/manual/vhosts/index.xml.ko @@ -0,0 +1,101 @@ + + + + + + + + + + ¾ÆÆÄÄ¡ °¡»óÈ£½ºÆ® ¹®¼­ + + + +

    °¡»óÈ£½ºÆ® (Virtual Host)´Â ÇÑ ÄÄÇ»ÅÍ¿¡¼­ + ¿©·¯ À¥»çÀÌÆ®¸¦ (¿¹¸¦ µé¾î, www.company1.com°ú + www.company2.com) ¼­ºñ½ºÇÔÀ» ¶æÇÑ´Ù. + °¡»óÈ£½ºÆ®¿¡´Â °¢ À¥»çÀÌÆ®¸¶´Ù ´Ù¸¥ IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ´Â + "IP±â¹Ý (IP-based)" ¹æ½Ä°ú ÇÑ + IP ÁÖ¼Ò´ç ¿©·¯ À̸§À» °¡Áö´Â "À̸§±â¹Ý (name-based)" ¹æ½ÄÀÌ + ÀÖ´Ù. ¿©·¯ »çÀÌÆ®µéÀÌ °°Àº ¼­¹ö¿¡¼­ µ¹°íÀÖ´Ù´Â »ç½ÇÀ» À¥»ç¿ëÀÚ´Â + ´«Ä¡Ã¤Áö ¸øÇÑ´Ù.

    + +

    ¾ÆÆÄÄ¡´Â ±âº»À¸·Î IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÑ ÃÊâ±â + ¼­¹öµéÁß Çϳª´Ù. ¾ÆÆÄÄ¡ ¹öÀü 1.1 ÀÌ»óÀº IP±â¹Ý°ú À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ ¸ðµÎ Áö¿øÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ + È£½ºÆ®±â¹Ý (host-based) ¶Ç´Â ºñIP °¡»óÈ£½ºÆ® + (non-IP virtual hosts)¶ó°íµµ ºÎ¸¥´Ù.

    + +

    ´ÙÀ½Àº ¾ÆÆÄÄ¡ ¹öÀü 1.3 ÀÌ»óÀÇ °¡»óÈ£½ºÆ® Áö¿øÀ» ÀÚ¼¼È÷ + ¼³¸íÇÑ ¹®¼­µéÀÌ´Ù.

    + +
    + +mod_vhost_alias +À̸§±â¹Ý °¡»óÈ£½ºÆ® +IP±â¹Ý °¡»óÈ£½ºÆ® +°¡»óÈ£½ºÆ® ¿¹ +ÆÄÀϱâ¼úÀÚ ÇÑ°è +´ë·®ÀÇ °¡»óÈ£½ºÆ® +°¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í + +
    °¡»óÈ£½ºÆ® Áö¿ø + + + +
    + +
    ¼³Á¤ Áö½Ã¾î + +
      +
    • VirtualHost
    • +
    • NameVirtualHost
    • +
    • ServerName
    • +
    • ServerAlias
    • +
    • ServerPath
    • +
    + +

    °¡»óÈ£½ºÆ® ¼³Á¤À» Å×½ºÆ®ÇÒ¶§ ¾ÆÆÄÄ¡ÀÇ -S + ¸í·ÉÇà ¿É¼ÇÀÌ À¯¿ëÇÏ´Ù. Áï, ´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÑ´Ù:

    + + + /usr/local/apache2/bin/httpd -S + + +

    ÀÌ ¸í·É¾î´Â ¾ÆÆÄÄ¡°¡ ÀÐÀº ¼³Á¤ÆÄÀÏ¿¡ ´ëÇÑ + Á¤º¸¸¦ Ãâ·ÂÇÑ´Ù. IP ÁÖ¼Ò¿Í ¼­¹ö¸íÀ» ÀÚ¼¼È÷ »ìÆ캸¸é ¼³Á¤¿¡¼­ + ½Ç¼ö¸¦ ¹ß°ßÇϴµ¥ µµ¿òÀÌ µÉ °ÍÀÌ´Ù. (´Ù¸¥ ¸í·ÉÇà ¿É¼ÇµéÀº + httpd ÇÁ·Î±×·¥ ¹®¼­¸¦ + Âü°íÇ϶ó.)

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/index.xml.meta b/trunk/docs/manual/vhosts/index.xml.meta new file mode 100644 index 0000000000..ea18d20a4e --- /dev/null +++ b/trunk/docs/manual/vhosts/index.xml.meta @@ -0,0 +1,14 @@ + + + + index + /vhosts/ + .. + + + de + en + ja + ko + + diff --git a/trunk/docs/manual/vhosts/ip-based.html b/trunk/docs/manual/vhosts/ip-based.html new file mode 100644 index 0000000000..8c88795e92 --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.html @@ -0,0 +1,11 @@ +URI: ip-based.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: ip-based.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: ip-based.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/ip-based.html.en b/trunk/docs/manual/vhosts/ip-based.html.en new file mode 100644 index 0000000000..ede13469d3 --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.html.en @@ -0,0 +1,160 @@ + + + +Apache IP-based Virtual Host Support - Apache HTTP Server + + + + + +
    <-
    +

    Apache IP-based Virtual Host Support

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    + +
    top
    +
    +

    System requirements

    + +

    As the term IP-based indicates, the server + must have a different IP address for each IP-based + virtual host. This can be achieved by the machine + having several physical network connections, or by use of + virtual interfaces which are supported by most modern operating + systems (see system documentation for details, these are + frequently called "ip aliases", and the "ifconfig" command is + most commonly used to set them up).

    + +
    top
    +
    +

    How to set up Apache

    + +

    There are two ways of configuring apache to support multiple + hosts. Either by running a separate httpd daemon for + each hostname, or by running a single daemon which supports all the + virtual hosts.

    + +

    Use multiple daemons when:

    + +
      +
    • There are security partitioning issues, such as company1 + does not want anyone at company2 to be able to read their + data except via the web. In this case you would need two + daemons, each running with different User, Group, Listen, and ServerRoot settings.
    • + +
    • You can afford the memory and file descriptor + requirements of listening to every IP alias on the + machine. It's only possible to Listen to the "wildcard" + address, or to specific addresses. So if you have a need to + listen to a specific address for whatever reason, then you + will need to listen to all specific addresses. (Although one + httpd could listen to N-1 of the addresses, and another could + listen to the remaining address.)
    • +
    + +

    Use a single daemon when:

    + +
      +
    • Sharing of the httpd configuration between virtual hosts + is acceptable.
    • + +
    • The machine services a large number of requests, and so + the performance loss in running separate daemons may be + significant.
    • +
    + +
    top
    +
    +

    Setting up multiple daemons

    + +

    Create a separate httpd installation for each + virtual host. For each installation, use the Listen directive in the + configuration file to select which IP address (or virtual host) + that daemon services. e.g.

    + +

    + Listen www.smallco.com:80 +

    + +

    It is recommended that you use an IP address instead of a + hostname (see DNS caveats).

    + +
    top
    +
    +

    Setting up a single daemon + with virtual hosts

    + +

    For this case, a single httpd will service + requests for the main server and all the virtual hosts. The VirtualHost directive + in the configuration file is used to set the values of ServerAdmin, ServerName, DocumentRoot, ErrorLog and TransferLog + or CustomLog + configuration directives to different values for each virtual + host. e.g.

    + +

    + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +

    + +

    It is recommended that you use an IP address instead of a + hostname (see DNS caveats).

    + +

    Almost any configuration directive can be + put in the VirtualHost directive, with the exception of + directives that control process creation and a few other + directives. To find out if a directive can be used in the + VirtualHost directive, check the Context using the + directive index.

    + +

    SuexecUserGroup + may be used inside a + VirtualHost directive if the suEXEC + wrapper is used.

    + +

    SECURITY: When specifying where to write log files, + be aware of some security risks which are present if anyone + other than the user that starts Apache has write access to the + directory where they are written. See the security tips document + for details.

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/ip-based.html.ja.euc-jp b/trunk/docs/manual/vhosts/ip-based.html.ja.euc-jp new file mode 100644 index 0000000000..1be357c45a --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.html.ja.euc-jp @@ -0,0 +1,156 @@ + + + +Apache ¤Î IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥µ¥Ý¡¼¥È - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    Apache ¤Î IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¥µ¥Ý¡¼¥È

    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    +
    + +
    top
    +
    +

    ¥·¥¹¥Æ¥àÍ×·ï

    + +

    IP ¥Ù¡¼¥¹ ¤È¤¤¤¦Ì¾Á°¤¬¼¨¤¹¤è¤¦¤Ë¡¢¥µ¡¼¥Ð¤Ë¤Ï + IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤½¤ì¤¾¤ì¤Ë¤Ä¤­¡¢ÊÌ¡¹¤Î IP ¥¢¥É¥ì¥¹¤¬ + ɬÍפǤ¹¡£Ê£¿ô¤ÎʪÍý¥³¥Í¥¯¥·¥ç¥ó¤ò»ý¤Ã¤Æ¤¤¤ë¥Þ¥·¥ó¤òÍÑ°Õ¤¹¤ë¤«¡¢ + ºÇ¶á¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¥Ð¡¼¥Á¥ã¥ë + ¥¤¥ó¥¿¥Õ¥§¡¼¥¹ (¾ÜºÙ¤Ï¥·¥¹¥Æ¥à¤ÎÀâÌÀ½ñ¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£¤¿¤¤¤Æ¤¤¤Ï + "ip ¥¨¥¤¥ê¥¢¥¹" ¤È¸Æ¤Ð¤ì¤Æ¤¤¤Æ¡¢ÀßÄê¤Ë¤ÏÉáÄÌ "ifconfig" ¥³¥Þ¥ó¥É¤ò + »È¤¤¤Þ¤¹) ¤ò»È¤¦¤«¤Ç¼Â¸½¤Ç¤­¤Þ¤¹¡£

    +
    top
    +
    +

    Apache ¤ÎÀßÄêÊýË¡

    + +

    Ê£¿ô¤Î¥Û¥¹¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë Apache ¤òÀßÄꤹ¤ëÊýË¡¤Ï + ÆóÄ̤ꤢ¤ê¤Þ¤¹¡£Ê̤Πhttpd ¥Ç¡¼¥â¥ó¤ò³Æ¥Û¥¹¥ÈËè¤Ë¼Â¹Ô¤¹¤ë¤«¡¢ + ¤¹¤Ù¤Æ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¥Ç¡¼¥â¥ó¤ò°ì¤Ä¼Â¹Ô¤¹¤ë¤«¤Ç¤¹¡£

    + +

    °Ê²¼¤Î¤È¤­¤Ë¤ÏÊ£¿ô¤Î¥Ç¡¼¥â¥ó¤ò»È¤¦¤ÈÎɤ¤¤Ç¤·¤ç¤¦:

    + +
      +
    • ²ñ¼Ò1 ¤Ï¥¦¥§¥Ö·Ðͳ°Ê³°¤Ç¤Ï²ñ¼Ò2 ¤«¤é¤Ï¥Ç¡¼¥¿¤òÆɤޤ줿¤¯¤Ê¤¤¡¢ + ¤È¤¤¤Ã¤¿¥»¥­¥å¥ê¥Æ¥£¤ÎʬΥ¤ÎÌäÂ꤬¤¢¤ë¤È¤­¡£¤³¤Î¾ì¹ç¡¢¤½¤ì¤¾¤ì + User, Group, Listen, ServerRoot ¤ÎÀßÄ꤬°ã¤¦Æó¤Ä¤Î¥Ç¡¼¥â¥ó¤ò + ¼Â¹Ô¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
    • + +
    • ¥Þ¥·¥ó¤Î¤¹¤Ù¤Æ¤Î IP ¥¨¥¤¥ê¥¢¥¹¤ò listen ¤¹¤ë¤À¤±¤Î + ¥á¥â¥ê¤È¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤Î;͵¤¬¤¢¤ë¤È¤­¡£Listen ¤Ï¡Ö¥ï¥¤¥ë¥É¥«¡¼¥É¡× + ¥¢¥É¥ì¥¹¤«¡¢ÆÃÄê¤Î¥¢¥É¥ì¥¹¤Î¤ß¤ò listen ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Ç¤¹¤«¤é¡¢²¿¤é¤«¤ÎÍýͳ¤ÇÆÃÄê¤Î¥¢¥É¥ì¥¹¤ò listen ¤·¤Ê¤±¤Ð¤Ê¤é¤Ê¤¤ + ¤È¤­¤Ï¡¢¤½¤ÎÆÃÄê¤Î¥¢¥É¥ì¥¹¤ò¤¹¤Ù¤Æ listen ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + (¤¿¤À¤·¡¢°ì¤Ä¤Î httpd ¤¬ N-1 ¸Ä¤Î¥¢¥É¥ì¥¹¤ò listen ¤·¡¢ + Ê̤Πhttpd ¤¬»Ä¤ê¤Î¥¢¥É¥ì¥¹¤ò listen ¤¹¤ë¤È¤¤¤Ã¤¿¤³¤È¤Ï²Äǽ¤Ç¤¹¡£)
    • +
    + +

    °Ê²¼¤Î¤È¤­¤Ë¤ÏñÆȤΥǡ¼¥â¥ó¤ò»È¤¦¤ÈÎɤ¤¤Ç¤·¤ç¤¦:

    + +
      +
    • ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È´Ö¤Ç¤Î httpd ¤ÎÀßÄê¤ò¶¦Í­¤·¤Æ¤â¤è¤¤¤È¤­¡£
    • + +
    • ¥Þ¥·¥ó¤¬Â¿¤¯¤Î¥ê¥¯¥¨¥¹¥È¤ò°·¤¦¤¿¤á¡¢Ê̥ǡ¼¥â¥ó¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ë¤è¤ë + À­Ç½¤ÎÄã²¼¤Î±Æ¶Á¤¬Ãø¤·¤¤¤È¤­¡£
    • +
    + +
    top
    +
    +

    Ê£¿ô¥Ç¡¼¥â¥ó¤ÎÀßÄê

    + +

    ³Æ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤ÆÊ̤Πhttpd ¤Î¥¤¥ó¥¹¥È¡¼¥ë¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ + ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤Î Listen + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¡¢ + ³Æ¥¤¥ó¥¹¥È¡¼¥ë¤Ç¥Ç¡¼¥â¥ó¤¬°·¤¦ IP ¥¢¥É¥ì¥¹ (¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È) + ¤òÁªÂò¤·¤Þ¤¹¡£Î㤨¤Ð

    + +

    + Listen www.smallco.com:80 +

    + +

    ¤³¤³¤Ç¡¢¥Û¥¹¥È̾¤ÎÂå¤ï¤ê¤Ë IP ¥¢¥É¥ì¥¹¤ò»È¤¦Êý¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤ + (DNS ¤ÎÃí°Õ»ö¹à »²¾È)¡£

    + +
    top
    +
    +

    Ê£¿ô¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤ò¤·¤¿ +¥Ç¡¼¥â¥ó¤ò°ì¤ÄÀßÄꤹ¤ë

    + +

    ¤³¤Î¾ì¹ç¤Ï¡¢°ì¤Ä¤Î httpd ¤¬¼ç¥µ¡¼¥Ð¤È¤¹¤Ù¤Æ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥ê¥¯¥¨¥¹¥È¤ò + ½èÍý¤·¤Þ¤¹¡£ÀßÄê¥Õ¥¡¥¤¥ë¤Î VirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»È¤Ã¤Æ¡¢ + ServerAdmin, ServerName, DocumentRoot, ErrorLog, TransferLog + ¤ä CustomLog + ÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃͤ¬³Æ¥Û¥¹¥ÈËè¤Ë°Û¤Ê¤ëÃͤËÀßÄꤵ¤ì¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£ + Î㤨¤Ð

    + +

    + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +

    + +

    ¤³¤³¤Ç¡¢¥Û¥¹¥È̾¤ÎÂå¤ï¤ê¤Ë IP ¥¢¥É¥ì¥¹¤ò»È¤¦Êý¤¬¿ä¾©¤µ¤ì¤Æ¤¤¤ë¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤ + (DNS ¤ÎÃí°Õ»ö¹à »²¾È)¡£

    + +

    ¥×¥í¥»¥¹À¸À®¤òÀ©¸æ¤¹¤ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ä¤½¤Î¾¤Î¤¤¤¯¤Ä¤«¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ½ü¤¤¤Æ¡¢¤Û¤Ü¤¹¤Ù¤Æ¤ÎÀßÄê¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò VirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ë½ñ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤¬ VirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ÈÍѤǤ­¤ë¤«¤É¤¦¤«¤Ï ¥Ç¥£¥ì¥¯¥Æ¥£¥Öº÷°ú¤ò»È¤Ã¤Æ¥³¥ó¥Æ¥­¥¹¥È¤Î + Íó¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£

    + +

    suEXEC¥é¥Ã¥Ñ¡¼¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ + SuexecUserGroup + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò VirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ç»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

    + +

    ¥»¥­¥å¥ê¥Æ¥£: ¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¤¯¾ì½ê¤ò»ØÄꤹ¤ë¤È¤­¤Ï¡¢ + Apache ¤òµ¯Æ°¤·¤¿¥æ¡¼¥¶°Ê³°¤¬¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë½ñ¤­¹þ¤ß¸¢¸Â¤ò + »ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¥»¥­¥å¥ê¥Æ¥£¾å¤Î´í¸±¤¬¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£ + ¾ÜºÙ¤Ï¥»¥­¥å¥ê¥Æ¥£¤Î¤³¤Ä¥É¥­¥å¥á¥ó¥È¤ò + »²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    +
    +

    Available Languages:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/ip-based.html.ko.euc-kr b/trunk/docs/manual/vhosts/ip-based.html.ko.euc-kr new file mode 100644 index 0000000000..dd9bfab17e --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.html.ko.euc-kr @@ -0,0 +1,150 @@ + + + +¾ÆÆÄÄ¡ IP±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø - Apache HTTP Server + + + + + +
    <-
    +

    ¾ÆÆÄÄ¡ IP±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    +
    + +
    top
    +
    +

    ½Ã½ºÅÛ ¿ä±¸»çÇ×

    + +

    IP±â¹ÝÀ̶õ ¸»ÀÌ ÀǹÌÇϵíÀÌ ¼­¹ö´Â + IP±â¹Ý °¡»óÈ£½ºÆ® °¢°¢¿¡ ´ëÇØ ´Ù¸¥ IP ÁÖ¼Ò¸¦ + °¡Á®¾ßÇÑ´Ù. ÀÌ´Â ÄÄÇ»Å͸¦ ¹°¸®ÀûÀ¸·Î ¿©·¯ ³×Æ®¿÷¿¡ + ¿¬°áÇϰųª, ÃÖ±Ù ¿î¿µÃ¼Á¦¿¡¼­ Áö¿øÇÏ´Â °¡»ó ÀÎÅÍÆäÀ̽º¸¦ + (ÀÚ¼¼ÇÑ ³»¿ëÀº ½Ã½ºÅÛ ¹®¼­¸¦ Âü°íÇ϶ó. ÈçÈ÷ "ip aliases"¶ó°í + Çϸç, º¸Åë "ifconfig" ¸í·É¾î·Î ¸¸µç´Ù) »ç¿ëÇÏ¿© °¡´ÉÇÏ´Ù.

    + +
    top
    +
    +

    ¾ÆÆÄÄ¡ ¼³Á¤¹æ¹ý

    + +

    ¿©·¯ È£½ºÆ®¸¦ Áö¿øÇϵµ·Ï ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÏ´Â ¹æ¹ýÀº µÎ°¡Áö´Ù. + Çϳª´Â °¢ È£½ºÆ®¸¶´Ù º°µµÀÇ À¥¼­¹ö¸¦ ½ÇÇàÇÏ´Â + ¹ýÀÌ°í, ´Ù¸¥ Çϳª´Â ¸ðµç °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÏ´Â ¼­¹ö ÇÑ°³¸¦ + ½ÇÇàÇÏ´Â ¹æ¹ýÀÌ´Ù.

    + +

    ¾ðÁ¦ ¿©·¯ ¼­¹ö¸¦ »ç¿ëÇϳª:

    + +
      +
    • ȸ»ç2ÀÇ »ç¿ëÀÚ°¡ À¥ÀÌ¿ÜÀÇ ¹æ¹ýÀ¸·Î ȸ»ç1ÀÇ ÀڷḦ ÀÐÀ» + ¼ö ¾ø°Ô ÇÏ´Â µî º¸¾È»ó ±¸ºÐÀÌ ÇÊ¿äÇÑ °æ¿ì. ÀÌ °æ¿ì + µÎ ¼­¹ö¸¦ °¢°¢ ´Ù¸¥ User, Group, Listen, ServerRoot ¼³Á¤À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù.
    • + +
    • ÃæºÐÇÑ ¸Þ¸ð¸®°¡ ÀÖ°í, ÄÄÇ»ÅÍÀÇ ¸ðµç IP¸¦ ±â´Ù¸®±âÀ§ÇÑ + ÆÄÀϱâ¼úÀÚ(file descriptor) ¿ä±¸»çÇ×µµ ¸¸Á·ÇÑ´Ù. "¿ÍÀϵåÄ«µå"³ª + ƯÁ¤ ÁÖ¼Ò¸¦ ListenÇÒ ¼ö¸¸ ÀÖ´Ù. ±×·¡¼­ + ¾î¶² ÀÌÀ¯¿¡¼­°Ç ƯÁ¤ ÁÖ¼Ò¸¦ ±â´Ù¸± ÇÊ¿ä°¡ ÀÖ´Ù¸é, (ÇÑ + À¥¼­¹ö°¡ ÇÑ ÁÖ¼Ò¸¦ Á¦¿ÜÇÑ ¸ðµç ÁÖ¼Ò¸¦ ±â´Ù¸®°í ´Ù¸¥ ÇÑ + À¥¼­¹ö°¡ Á¦¿ÜÇÑ ÁÖ¼Ò¸¦ ±â´Ù¸± ¼ö ÀÖÁö¸¸) ÁöÁ¤ÇÑ ÁÖ¼Ò + ¸ðµÎ¸¦ ±â´Ù·Á¾ß ÇÑ´Ù.
    • +
    + +

    ¾ðÁ¦ ¼­¹ö ÇÑ°³¸¦ »ç¿ëÇϳª:

    + +
      +
    • °¡»óÈ£½ºÆ®µéÀÇ À¥¼­¹ö ¼³Á¤À» °øÀ¯ÇÒ ¼ö ÀÖ´Â °æ¿ì.
    • + +
    • ÄÄÇ»ÅÍ°¡ ¸Å¿ì ¸¹Àº ¿äûÀ» ¼­ºñ½ºÇÑ´Ù¸é ¿©·¯ ¼­¹ö¸¦ + ½ÇÇàÇϱ⿡ ¼Óµµ ¼Õ½ÇÀÌ Å¬ ¼ö ÀÖ´Ù.
    • +
    + +
    top
    +
    +

    ¿©·¯ ¼­¹ö¸¦ ½ÇÇàÇϱâ

    + +

    °¢ °¡»óÈ£½ºÆ®º°·Î À¥¼­¹ö¸¦ ¼³Ä¡ÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ + Listen Áö½Ã¾î¿¡ + ¼­¹ö°¡ ¼­ºñ½ºÇÒ IP ÁÖ¼Ò(ȤÀº °¡»óÈ£½ºÆ®)¸¦ Àû¾îÁØ´Ù. ¿¹¸¦ + µé¸é,

    + +

    + Listen www.smallco.com:80 +

    + +

    È£½ºÆ®¸í º¸´Ù´Â IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + (DNS ¹®Á¦ Âü°í)

    + +
    top
    +
    +

    ¼­¹ö Çϳª·Î °¡»óÈ£½ºÆ® ½ÇÇàÇϱâ

    + +

    ÀÌ °æ¿ì À¥¼­¹ö ÇÑ°³·Î ÁÖ¼­¹ö¿Í ¸ðµç °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ VirtualHost Áö½Ã¾î¿¡ °¡»óÈ£½ºÆ®¸¶´Ù + ´Ù¸¥ ServerAdmin, + ServerName, DocumentRoot, ErrorLog, TransferLog, + CustomLog + Áö½Ã¾î °ªÀ» ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¸é,

    + +

    + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +

    + +

    È£½ºÆ®¸í º¸´Ù´Â IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + (DNS ¹®Á¦ Âü°í)

    + +

    VirtualHost Áö½Ã¾î ¾È¿¡¼­´Â ÇÁ·Î¼¼½º »ý¼º°ú ±âŸ ¸î¸î Áö½Ã¾î¸¦ + Á¦¿ÜÇÏ°í °ÅÀÇ ¸ðµç ¼³Á¤Áö½Ã¾î¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù. VirtualHost Áö½Ã¾î ¾È¿¡¼­ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + ¾Ë·Á¸é Áö½Ã¾î ¸ñ·Ï¿¡¼­ + »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó.

    + +

    suEXEC ÇÁ·Î±×·¥À» + »ç¿ëÇÑ´Ù¸é VirtualHost Áö½Ã¾î ¾È¿¡ User¿Í GroupÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    º¸¾È: ¼­¹ö¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿Ü¿¡ ´Ù¸¥ »ç¶÷¿¡°Ô + ·Î±×ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮ÀÇ ¾²±â±ÇÇÑÀÌ ÀÖ´Ù¸é º¸¾È + ¹®Á¦¸¦ Á¶½ÉÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº º¸¾È ÆÁÀ» Âü°íÇ϶ó.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/ip-based.xml b/trunk/docs/manual/vhosts/ip-based.xml new file mode 100644 index 0000000000..25b54c0fdd --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.xml @@ -0,0 +1,162 @@ + + + + + + + + +Virtual Hosts + Apache IP-based Virtual Host Support + + +Name-based Virtual Hosts Support + + +
    System requirements + +

    As the term IP-based indicates, the server + must have a different IP address for each IP-based + virtual host. This can be achieved by the machine + having several physical network connections, or by use of + virtual interfaces which are supported by most modern operating + systems (see system documentation for details, these are + frequently called "ip aliases", and the "ifconfig" command is + most commonly used to set them up).

    + +
    + +
    How to set up Apache + +

    There are two ways of configuring apache to support multiple + hosts. Either by running a separate httpd daemon for + each hostname, or by running a single daemon which supports all the + virtual hosts.

    + +

    Use multiple daemons when:

    + +
      +
    • There are security partitioning issues, such as company1 + does not want anyone at company2 to be able to read their + data except via the web. In this case you would need two + daemons, each running with different User, Group, Listen, and ServerRoot settings.
    • + +
    • You can afford the memory and file descriptor + requirements of listening to every IP alias on the + machine. It's only possible to Listen to the "wildcard" + address, or to specific addresses. So if you have a need to + listen to a specific address for whatever reason, then you + will need to listen to all specific addresses. (Although one + httpd could listen to N-1 of the addresses, and another could + listen to the remaining address.)
    • +
    + +

    Use a single daemon when:

    + +
      +
    • Sharing of the httpd configuration between virtual hosts + is acceptable.
    • + +
    • The machine services a large number of requests, and so + the performance loss in running separate daemons may be + significant.
    • +
    + +
    + +
    Setting up multiple daemons + +

    Create a separate httpd installation for each + virtual host. For each installation, use the Listen directive in the + configuration file to select which IP address (or virtual host) + that daemon services. e.g.

    + + + Listen www.smallco.com:80 + + +

    It is recommended that you use an IP address instead of a + hostname (see DNS caveats).

    + +
    + +
    Setting up a single daemon + with virtual hosts + +

    For this case, a single httpd will service + requests for the main server and all the virtual hosts. The VirtualHost directive + in the configuration file is used to set the values of ServerAdmin, ServerName, DocumentRoot, ErrorLog and TransferLog + or CustomLog + configuration directives to different values for each virtual + host. e.g.

    + + + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +
    + +

    It is recommended that you use an IP address instead of a + hostname (see DNS caveats).

    + +

    Almost any configuration directive can be + put in the VirtualHost directive, with the exception of + directives that control process creation and a few other + directives. To find out if a directive can be used in the + VirtualHost directive, check the Context using the + directive index.

    + +

    SuexecUserGroup + may be used inside a + VirtualHost directive if the suEXEC + wrapper is used.

    + +

    SECURITY: When specifying where to write log files, + be aware of some security risks which are present if anyone + other than the user that starts Apache has write access to the + directory where they are written. See the security tips document + for details.

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/ip-based.xml.ja b/trunk/docs/manual/vhosts/ip-based.xml.ja new file mode 100644 index 0000000000..03efa3a1a3 --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.xml.ja @@ -0,0 +1,158 @@ + + + + + + + + +$B%P!<%A%c%k%[%9%H(B + Apache $B$N(B IP $B%Y!<%9$N%P!<%A%c%k%[%9%H%5%]!<%H(B + + +$BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H%5%]!<%H(B + + +
    $B%7%9%F%`MW7o(B + +

    IP $B%Y!<%9(B $B$H$$$&L>A0$,<($9$h$&$K!"%5!<%P$K$O(B + IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$=$l$>$l$K$D$-!"JL!9$N(B IP $B%"%I%l%9$,(B + $BI,MW$G$9(B$B!#J#?t$NJ*M}%3%M%/%7%g%s$r;}$C$F$$$k%^%7%s$rMQ0U$9$k$+!"(B + $B:G6a$N%*%Z%l!<%F%#%s%0%7%9%F%`$G%5%]!<%H$5$l$F$$$k%P!<%A%c%k(B + $B%$%s%?%U%'!<%9(B ($B>\:Y$O%7%9%F%`$N@bL@=q$rFI$s$G$/$@$5$$!#$?$$$F$$$O(B + "ip $B%(%$%j%"%9(B" $B$H8F$P$l$F$$$F!"@_Dj$K$OIaDL(B "ifconfig" $B%3%^%s%I$r(B + $B;H$$$^$9(B) $B$r;H$&$+$G +

    + +
    Apache $B$N@_DjJ}K!(B + +

    $BJ#?t$N%[%9%H$r%5%]!<%H$9$k$h$&$K(B Apache $B$r@_Dj$9$kJ}K!$O(B + $BFsDL$j$"$j$^$9!#JL$N(B httpd $B%G!<%b%s$r3F%[%9%HKh$K + +

    $B0J2<$N$H$-$K$OJ#?t$N%G!<%b%s$r;H$&$HNI$$$G$7$g$&(B:

    + +
      +
    • $B2ql9g!"$=$l$>$l(B + User, Group, Listen, ServerRoot $B$N@_Dj$,0c$&Fs$D$N%G!<%b%s$r(B + $B + +
    • $B%^%7%s$N$9$Y$F$N(B IP $B%(%$%j%"%9$r(B listen $B$9$k$@$1$N(B + $B%a%b%j$H%U%!%$%k5-=R;R$NM>M5$,$"$k$H$-!#(BListen $B$O!V%o%$%k%I%+!<%I!W(B + $B%"%I%l%9$+!"FCDj$N%"%I%l%9$N$_$r(B listen $B$9$k$3$H$,$G$-$^$9!#(B + $B$G$9$+$i!"2?$i$+$NM}M3$GFCDj$N%"%I%l%9$r(B listen $B$7$J$1$P$J$i$J$$(B + $B$H$-$O!"$=$NFCDj$N%"%I%l%9$r$9$Y$F(B listen $B$9$kI,MW$,$"$j$^$9!#(B + ($B$?$@$7!"0l$D$N(B httpd $B$,(B N-1 $B8D$N%"%I%l%9$r(B listen $B$7!"(B + $BJL$N(B httpd $B$,;D$j$N%"%I%l%9$r(B listen $B$9$k$H$$$C$?$3$H$O2DG=$G$9!#(B)
    • +
    + +

    $B0J2<$N$H$-$K$OC1FH$N%G!<%b%s$r;H$&$HNI$$$G$7$g$&(B:

    + +
      +
    • $B%P!<%A%c%k%[%9%H4V$G$N(B httpd $B$N@_Dj$r6&M-$7$F$b$h$$$H$-!#(B
    • + +
    • $B%^%7%s$,B?$/$N%j%/%(%9%H$r07$&$?$a!"JL%G!<%b%s$r +
    + +
    + +
    $BJ#?t%G!<%b%s$N@_Dj(B + +

    $B3F%P!<%A%c%k%[%9%H$KBP$7$FJL$N(B httpd $B$N%$%s%9%H!<%k$r9T$J$$$^$9!#(B + $B@_Dj%U%!%$%kCf$N(B Listen + $B%G%#%l%/%F%#%V$r;H$C$F!"(B + $B3F%$%s%9%H!<%k$G%G!<%b%s$,07$&(B IP $B%"%I%l%9(B ($B%P!<%A%c%k%[%9%H(B) + $B$rA*Br$7$^$9!#Nc$($P(B

    + + + Listen www.smallco.com:80 + + +

    $B$3$3$G!"%[%9%HL>$NBe$o$j$K(B IP $B%"%I%l%9$r;H$&J}$,?d>)$5$l$F$$$k$3$H$K(B + $BCm0U$7$F$*$$$F$/$@$5$$(B + (DNS $B$NCm0U;v9`(B $B;2>H(B)$B!#(B

    + +
    + +
    $BJ#?t$N%P!<%A%c%k%[%9%H$N@_Dj$r$7$?(B +$B%G!<%b%s$r0l$D@_Dj$9$k(B + +

    $B$3$N>l9g$O!"0l$D$N(B httpd $B$,VirtualHost $B%G%#%l%/%F%#%V$r;H$C$F!"(B + ServerAdmin, ServerName, DocumentRoot, ErrorLog, TransferLog + $B$d(B CustomLog + $B@_Dj%G%#%l%/%F%#%V$NCM$,3F%[%9%HKh$K0[$J$kCM$K@_Dj$5$l$k$h$&$K$7$^$9!#(B + $BNc$($P(B

    + + + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +
    + +

    $B$3$3$G!"%[%9%HL>$NBe$o$j$K(B IP $B%"%I%l%9$r;H$&J}$,?d>)$5$l$F$$$k$3$H$K(B + $BCm0U$7$F$*$$$F$/$@$5$$(B + (DNS $B$NCm0U;v9`(B $B;2>H(B)$B!#(B

    + +

    $B%W%m%;%9@8@.$r@)8f$9$k%G%#%l%/%F%#%V$d$=$NB>$N$$$/$D$+$N%G%#%l%/%F%#%V$r(B + $B=|$$$F!"$[$\(B$B$9$Y$F(B$B$N@_Dj%G%#%l%/%F%#%V$r(B VirtualHost + $B%G%#%l%/%F%#%V$NCf$K=q$/$3$H$,$G$-$^$9!#%G%#%l%/%F%#%V$,(B VirtualHost + $B%G%#%l%/%F%#%V$G;HMQ$G$-$k$+$I$&$+$O(B $B%G%#%l%/%F%#%V:w0z(B$B$r;H$C$F(B$B%3%s%F%-%9%H(B$B$N(B + $BMs$rD4$Y$F$/$@$5$$!#(B

    + +

    suEXEC$B%i%C%Q!<(B$B$r;H$C$F$$$k>l9g$O!"(B + SuexecUserGroup + $B%G%#%l%/%F%#%V$r(B VirtualHost + $B%G%#%l%/%F%#%V$NCf$G;HMQ$9$k$3$H$,$G$-$^$9!#(B

    + +

    $B%;%-%e%j%F%#(B: $B%m%0%U%!%$%k$r=q$/>l=j$r;XDj$9$k$H$-$O!"(B + Apache $B$r5/F0$7$?%f!<%60J30$,$=$N%G%#%l%/%H%j$K=q$-9~$_8"8B$r(B + $B;}$C$F$$$k>l9g$K%;%-%e%j%F%#>e$N4m81$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#(B + $B>\:Y$O(B$B%;%-%e%j%F%#$N$3$D(B$B%I%-%e%a%s%H$r(B + $B;2>H$7$F$/$@$5$$!#(B

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/ip-based.xml.ko b/trunk/docs/manual/vhosts/ip-based.xml.ko new file mode 100644 index 0000000000..c3b96f8ba8 --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.xml.ko @@ -0,0 +1,149 @@ + + + + + + + + +°¡»óÈ£½ºÆ® + ¾ÆÆÄÄ¡ IP±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø + + +À̸§±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø + + +
    ½Ã½ºÅÛ ¿ä±¸»çÇ× + +

    IP±â¹ÝÀ̶õ ¸»ÀÌ ÀǹÌÇϵíÀÌ ¼­¹ö´Â + IP±â¹Ý °¡»óÈ£½ºÆ® °¢°¢¿¡ ´ëÇØ ´Ù¸¥ IP ÁÖ¼Ò¸¦ + °¡Á®¾ßÇÑ´Ù. ÀÌ´Â ÄÄÇ»Å͸¦ ¹°¸®ÀûÀ¸·Î ¿©·¯ ³×Æ®¿÷¿¡ + ¿¬°áÇϰųª, ÃÖ±Ù ¿î¿µÃ¼Á¦¿¡¼­ Áö¿øÇÏ´Â °¡»ó ÀÎÅÍÆäÀ̽º¸¦ + (ÀÚ¼¼ÇÑ ³»¿ëÀº ½Ã½ºÅÛ ¹®¼­¸¦ Âü°íÇ϶ó. ÈçÈ÷ "ip aliases"¶ó°í + Çϸç, º¸Åë "ifconfig" ¸í·É¾î·Î ¸¸µç´Ù) »ç¿ëÇÏ¿© °¡´ÉÇÏ´Ù.

    + +
    + +
    ¾ÆÆÄÄ¡ ¼³Á¤¹æ¹ý + +

    ¿©·¯ È£½ºÆ®¸¦ Áö¿øÇϵµ·Ï ¾ÆÆÄÄ¡¸¦ ¼³Á¤ÇÏ´Â ¹æ¹ýÀº µÎ°¡Áö´Ù. + Çϳª´Â °¢ È£½ºÆ®¸¶´Ù º°µµÀÇ À¥¼­¹ö¸¦ ½ÇÇàÇÏ´Â + ¹ýÀÌ°í, ´Ù¸¥ Çϳª´Â ¸ðµç °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÏ´Â ¼­¹ö ÇÑ°³¸¦ + ½ÇÇàÇÏ´Â ¹æ¹ýÀÌ´Ù.

    + +

    ¾ðÁ¦ ¿©·¯ ¼­¹ö¸¦ »ç¿ëÇϳª:

    + +
      +
    • ȸ»ç2ÀÇ »ç¿ëÀÚ°¡ À¥ÀÌ¿ÜÀÇ ¹æ¹ýÀ¸·Î ȸ»ç1ÀÇ ÀڷḦ ÀÐÀ» + ¼ö ¾ø°Ô ÇÏ´Â µî º¸¾È»ó ±¸ºÐÀÌ ÇÊ¿äÇÑ °æ¿ì. ÀÌ °æ¿ì + µÎ ¼­¹ö¸¦ °¢°¢ ´Ù¸¥ User, Group, Listen, ServerRoot ¼³Á¤À¸·Î ½ÇÇàÇØ¾ß ÇÑ´Ù.
    • + +
    • ÃæºÐÇÑ ¸Þ¸ð¸®°¡ ÀÖ°í, ÄÄÇ»ÅÍÀÇ ¸ðµç IP¸¦ ±â´Ù¸®±âÀ§ÇÑ + ÆÄÀϱâ¼úÀÚ(file descriptor) ¿ä±¸»çÇ×µµ ¸¸Á·ÇÑ´Ù. "¿ÍÀϵåÄ«µå"³ª + ƯÁ¤ ÁÖ¼Ò¸¦ ListenÇÒ ¼ö¸¸ ÀÖ´Ù. ±×·¡¼­ + ¾î¶² ÀÌÀ¯¿¡¼­°Ç ƯÁ¤ ÁÖ¼Ò¸¦ ±â´Ù¸± ÇÊ¿ä°¡ ÀÖ´Ù¸é, (ÇÑ + À¥¼­¹ö°¡ ÇÑ ÁÖ¼Ò¸¦ Á¦¿ÜÇÑ ¸ðµç ÁÖ¼Ò¸¦ ±â´Ù¸®°í ´Ù¸¥ ÇÑ + À¥¼­¹ö°¡ Á¦¿ÜÇÑ ÁÖ¼Ò¸¦ ±â´Ù¸± ¼ö ÀÖÁö¸¸) ÁöÁ¤ÇÑ ÁÖ¼Ò + ¸ðµÎ¸¦ ±â´Ù·Á¾ß ÇÑ´Ù.
    • +
    + +

    ¾ðÁ¦ ¼­¹ö ÇÑ°³¸¦ »ç¿ëÇϳª:

    + +
      +
    • °¡»óÈ£½ºÆ®µéÀÇ À¥¼­¹ö ¼³Á¤À» °øÀ¯ÇÒ ¼ö ÀÖ´Â °æ¿ì.
    • + +
    • ÄÄÇ»ÅÍ°¡ ¸Å¿ì ¸¹Àº ¿äûÀ» ¼­ºñ½ºÇÑ´Ù¸é ¿©·¯ ¼­¹ö¸¦ + ½ÇÇàÇϱ⿡ ¼Óµµ ¼Õ½ÇÀÌ Å¬ ¼ö ÀÖ´Ù.
    • +
    + +
    + +
    ¿©·¯ ¼­¹ö¸¦ ½ÇÇàÇϱâ + +

    °¢ °¡»óÈ£½ºÆ®º°·Î À¥¼­¹ö¸¦ ¼³Ä¡ÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ + Listen Áö½Ã¾î¿¡ + ¼­¹ö°¡ ¼­ºñ½ºÇÒ IP ÁÖ¼Ò(ȤÀº °¡»óÈ£½ºÆ®)¸¦ Àû¾îÁØ´Ù. ¿¹¸¦ + µé¸é,

    + + + Listen www.smallco.com:80 + + +

    È£½ºÆ®¸í º¸´Ù´Â IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + (DNS ¹®Á¦ Âü°í)

    + +
    + +
    ¼­¹ö Çϳª·Î °¡»óÈ£½ºÆ® ½ÇÇàÇϱâ + +

    ÀÌ °æ¿ì À¥¼­¹ö ÇÑ°³·Î ÁÖ¼­¹ö¿Í ¸ðµç °¡»óÈ£½ºÆ®¿¡ ´ëÇÑ + ¿äûÀ» ¼­ºñ½ºÇÑ´Ù. ¼³Á¤ÆÄÀÏÀÇ VirtualHost Áö½Ã¾î¿¡ °¡»óÈ£½ºÆ®¸¶´Ù + ´Ù¸¥ ServerAdmin, + ServerName, DocumentRoot, ErrorLog, TransferLog, + CustomLog + Áö½Ã¾î °ªÀ» ¼³Á¤ÇÑ´Ù. ¿¹¸¦ µé¸é,

    + + + <VirtualHost www.smallco.com>
    + ServerAdmin webmaster@mail.smallco.com
    + DocumentRoot /groups/smallco/www
    + ServerName www.smallco.com
    + ErrorLog /groups/smallco/logs/error_log
    + TransferLog /groups/smallco/logs/access_log
    + </VirtualHost>
    +
    + <VirtualHost www.baygroup.org>
    + ServerAdmin webmaster@mail.baygroup.org
    + DocumentRoot /groups/baygroup/www
    + ServerName www.baygroup.org
    + ErrorLog /groups/baygroup/logs/error_log
    + TransferLog /groups/baygroup/logs/access_log
    + </VirtualHost> +
    + +

    È£½ºÆ®¸í º¸´Ù´Â IP ÁÖ¼Ò¸¦ »ç¿ëÇÏ±æ ¹Ù¶õ´Ù. + (DNS ¹®Á¦ Âü°í)

    + +

    VirtualHost Áö½Ã¾î ¾È¿¡¼­´Â ÇÁ·Î¼¼½º »ý¼º°ú ±âŸ ¸î¸î Áö½Ã¾î¸¦ + Á¦¿ÜÇÏ°í °ÅÀÇ ¸ðµç ¼³Á¤Áö½Ã¾î¸¦ »ç¿ëÇÒ + ¼ö ÀÖ´Ù. VirtualHost Áö½Ã¾î ¾È¿¡¼­ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖ´ÂÁö + ¾Ë·Á¸é Áö½Ã¾î ¸ñ·Ï¿¡¼­ + »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó.

    + +

    suEXEC ÇÁ·Î±×·¥À» + »ç¿ëÇÑ´Ù¸é VirtualHost Áö½Ã¾î ¾È¿¡ User¿Í GroupÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù.

    + +

    º¸¾È: ¼­¹ö¸¦ ½ÇÇàÇÏ´Â »ç¿ëÀÚ¿Ü¿¡ ´Ù¸¥ »ç¶÷¿¡°Ô + ·Î±×ÆÄÀÏÀÌ ÀÖ´Â µð·ºÅ丮ÀÇ ¾²±â±ÇÇÑÀÌ ÀÖ´Ù¸é º¸¾È + ¹®Á¦¸¦ Á¶½ÉÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº º¸¾È ÆÁÀ» Âü°íÇ϶ó.

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/ip-based.xml.meta b/trunk/docs/manual/vhosts/ip-based.xml.meta new file mode 100644 index 0000000000..a4c69d9cdf --- /dev/null +++ b/trunk/docs/manual/vhosts/ip-based.xml.meta @@ -0,0 +1,13 @@ + + + + ip-based + /vhosts/ + .. + + + en + ja + ko + + diff --git a/trunk/docs/manual/vhosts/mass.html b/trunk/docs/manual/vhosts/mass.html new file mode 100644 index 0000000000..6c05d28e88 --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.html @@ -0,0 +1,7 @@ +URI: mass.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: mass.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/mass.html.en b/trunk/docs/manual/vhosts/mass.html.en new file mode 100644 index 0000000000..1f8c238076 --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.html.en @@ -0,0 +1,445 @@ + + + +Dynamically configured mass virtual hosting - Apache HTTP Server + + + + + +
    <-
    +

    Dynamically configured mass virtual hosting

    +
    +

    Available Languages:  en  | + ko 

    +
    + + +

    This document describes how to efficiently serve an + arbitrary number of virtual hosts with Apache. +

    + +
    + +
    top
    +
    +

    Motivation

    + +

    The techniques described here are of interest if your + httpd.conf contains many + <VirtualHost> sections that are + substantially the same, for example:

    + +

    +NameVirtualHost 111.22.33.44
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-1.com
    + DocumentRoot /www/hosts/www.customer-1.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
    +
    +</VirtualHost>
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-2.com
    + DocumentRoot /www/hosts/www.customer-2.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
    +
    +</VirtualHost>
    +# blah blah blah
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-N.com
    + DocumentRoot /www/hosts/www.customer-N.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
    +
    +</VirtualHost> +

    + +

    The basic idea is to replace all of the static + <VirtualHost> configuration with a mechanism + that works it out dynamically. This has a number of + advantages:

    + +
      +
    1. Your configuration file is smaller so Apache starts + faster and uses less memory.
    2. + +
    3. Adding virtual hosts is simply a matter of creating the + appropriate directories in the filesystem and entries in the + DNS - you don't need to reconfigure or restart Apache.
    4. +
    + +

    The main disadvantage is that you cannot have a different + log file for each virtual host; however if you have very many + virtual hosts then doing this is dubious anyway because it eats + file descriptors. It is better to log to a pipe or a fifo and + arrange for the process at the other end to distribute the logs + to the customers (it can also accumulate statistics, etc.).

    + +
    top
    +
    +

    Overview

    + +

    A virtual host is defined by two pieces of information: its + IP address, and the contents of the Host: header + in the HTTP request. The dynamic mass virtual hosting technique + is based on automatically inserting this information into the + pathname of the file that is used to satisfy the request. This + is done most easily using mod_vhost_alias, + but if you are using a version of Apache up to 1.3.6 then you + must use mod_rewrite. + Both of these modules are disabled by default; you must enable + one of them when configuring and building Apache if you want to + use this technique.

    + +

    A couple of things need to be `faked' to make the dynamic + virtual host look like a normal one. The most important is the + server name which is used by Apache to generate + self-referential URLs, etc. It is configured with the + ServerName directive, and it is available to CGIs + via the SERVER_NAME environment variable. The + actual value used at run time is controlled by the UseCanonicalName + setting. With UseCanonicalName Off the server name + comes from the contents of the Host: header in the + request. With UseCanonicalName DNS it comes from a + reverse DNS lookup of the virtual host's IP address. The former + setting is used for name-based dynamic virtual hosting, and the + latter is used for IP-based hosting. If Apache cannot work out + the server name because there is no Host: header + or the DNS lookup fails then the value configured with + ServerName is used instead.

    + +

    The other thing to `fake' is the document root (configured + with DocumentRoot and available to CGIs via the + DOCUMENT_ROOT environment variable). In a normal + configuration this setting is used by the core module when + mapping URIs to filenames, but when the server is configured to + do dynamic virtual hosting that job is taken over by another + module (either mod_vhost_alias or + mod_rewrite) which has a different way of doing + the mapping. Neither of these modules is responsible for + setting the DOCUMENT_ROOT environment variable so + if any CGIs or SSI documents make use of it they will get a + misleading value.

    + +
    top
    +
    +

    Simple dynamic virtual hosts

    + +

    This extract from httpd.conf implements the + virtual host arrangement outlined in the Motivation section above, but in a + generic fashion using mod_vhost_alias.

    + +

    +# get the server name from the Host: header
    +UseCanonicalName Off
    +
    +# this log format can be split per-virtual-host based on the first field
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# include the server name in the filenames used to satisfy requests
    +VirtualDocumentRoot /www/hosts/%0/docs
    +VirtualScriptAlias /www/hosts/%0/cgi-bin +

    + +

    This configuration can be changed into an IP-based virtual + hosting solution by just turning UseCanonicalName + Off into UseCanonicalName DNS. The server + name that is inserted into the filename is then derived from + the IP address of the virtual host.

    + +
    top
    +
    +

    A virtually hosted homepages system

    + +

    This is an adjustment of the above system tailored for an + ISP's homepages server. Using a slightly more complicated + configuration we can select substrings of the server name to + use in the filename so that e.g. the documents for + www.user.isp.com are found in + /home/user/. It uses a single cgi-bin + directory instead of one per virtual host.

    + +

    +# all the preliminary stuff is the same as above, then
    +
    +# include part of the server name in the filenames
    +VirtualDocumentRoot /www/hosts/%2/docs
    +
    +# single cgi-bin directory
    +ScriptAlias /cgi-bin/ /www/std-cgi/
    +

    + +

    There are examples of more complicated + VirtualDocumentRoot settings in the + mod_vhost_alias documentation.

    + +
    top
    +
    +

    Using more than + one virtual hosting system on the same server

    + +

    With more complicated setups you can use Apache's normal + <VirtualHost> directives to control the + scope of the various virtual hosting configurations. For + example, you could have one IP address for homepages customers + and another for commercial customers with the following setup. + This can of course be combined with conventional + <VirtualHost> configuration sections.

    + +

    +UseCanonicalName Off
    +
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +
    +<Directory /www/commercial>
    + + Options FollowSymLinks
    + AllowOverride All
    +
    +</Directory>
    +
    +<Directory /www/homepages>
    + + Options FollowSymLinks
    + AllowOverride None
    +
    +</Directory>
    +
    +<VirtualHost 111.22.33.44>
    + + ServerName www.commercial.isp.com
    +
    + CustomLog logs/access_log.commercial vcommon
    +
    + VirtualDocumentRoot /www/commercial/%0/docs
    + VirtualScriptAlias /www/commercial/%0/cgi-bin
    +
    +</VirtualHost>
    +
    +<VirtualHost 111.22.33.45>
    + + ServerName www.homepages.isp.com
    +
    + CustomLog logs/access_log.homepages vcommon
    +
    + VirtualDocumentRoot /www/homepages/%0/docs
    + ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    +</VirtualHost> +

    + +
    top
    +
    +

    More efficient IP-based virtual hosting

    + +

    After the first example I noted that + it is easy to turn it into an IP-based virtual hosting setup. + Unfortunately that configuration is not very efficient because + it requires a DNS lookup for every request. This can be avoided + by laying out the filesystem according to the IP addresses + themselves rather than the corresponding names and changing the + logging similarly. Apache will then usually not need to work + out the server name and so incur a DNS lookup.

    + +

    +# get the server name from the reverse DNS of the IP address
    +UseCanonicalName DNS
    +
    +# include the IP address in the logs so they may be split
    +LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# include the IP address in the filenames
    +VirtualDocumentRootIP /www/hosts/%0/docs
    +VirtualScriptAliasIP /www/hosts/%0/cgi-bin
    +

    + +
    top
    +
    +

    Using older versions of Apache

    + +

    The examples above rely on mod_vhost_alias + which appeared after version 1.3.6. If you are using a version + of Apache without mod_vhost_alias then you can + implement this technique with mod_rewrite as + illustrated below, but only for Host:-header-based virtual + hosts.

    + +

    In addition there are some things to beware of with logging. + Apache 1.3.6 is the first version to include the + %V log format directive; in versions 1.3.0 - 1.3.3 + the %v option did what %V does; + version 1.3.4 has no equivalent. In all these versions of + Apache the UseCanonicalName directive can appear + in .htaccess files which means that customers can + cause the wrong thing to be logged. Therefore the best thing to + do is use the %{Host}i directive which logs the + Host: header directly; note that this may include + :port on the end which is not the case for + %V.

    + +
    top
    +
    +

    Simple dynamic + virtual hosts using mod_rewrite

    + +

    This extract from httpd.conf does the same + thing as the first example. The first + half is very similar to the corresponding part above but with + some changes for backward compatibility and to make the + mod_rewrite part work properly; the second half + configures mod_rewrite to do the actual work.

    + +

    There are a couple of especially tricky bits: By default, + mod_rewrite runs before the other URI translation + modules (mod_alias etc.) so if they are used then + mod_rewrite must be configured to accommodate + them. Also, some magic must be performed to do a + per-dynamic-virtual-host equivalent of + ScriptAlias.

    + +

    +# get the server name from the Host: header
    +UseCanonicalName Off
    +
    +# splittable logs
    +LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +<Directory /www/hosts>
    + + # ExecCGI is needed here because we can't force
    + # CGI execution in the way that ScriptAlias does
    + Options FollowSymLinks ExecCGI
    +
    +</Directory>
    +
    +# now for the hard bit
    +
    +RewriteEngine On
    +
    +# a ServerName derived from a Host: header may be any case at all
    +RewriteMap lowercase int:tolower
    +
    +## deal with normal documents first:
    +# allow Alias /icons/ to work - repeat for other aliases
    +RewriteCond %{REQUEST_URI} !^/icons/
    +# allow CGIs to work
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +# do the magic
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
    +
    +## and now deal with CGIs - we have to force a MIME type
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
    +
    +# that's it! +

    + +
    top
    +
    +

    A + homepages system using mod_rewrite

    + +

    This does the same thing as the second + example.

    + +

    +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# allow CGIs to work
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +
    +# check the hostname is right so that the RewriteRule works
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^www\.[a-z-]+\.isp\.com$
    +
    +# concatenate the virtual host name onto the start of the URI
    +# the [C] means do the next rewrite on the result of this one
    +RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
    +
    +# now create the real file name
    +RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
    +
    +# define the global CGI directory
    +ScriptAlias /cgi-bin/ /www/std-cgi/ +

    + +
    top
    +
    +

    Using a separate virtual + host configuration file

    + +

    This arrangement uses more advanced mod_rewrite + features to get the translation from virtual host to document + root from a separate configuration file. This provides more + flexibility but requires more complicated configuration.

    + +

    The vhost.map file contains something like + this:

    + +

    +www.customer-1.com /www/customers/1
    +www.customer-2.com /www/customers/2
    +# ...
    +www.customer-N.com /www/customers/N
    +

    + +

    The http.conf contains this:

    + +

    +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# define the map file
    +RewriteMap vhost txt:/www/conf/vhost.map
    +
    +# deal with aliases as above
    +RewriteCond %{REQUEST_URI} !^/icons/
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +# this does the file-based remap
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/docs/$1
    +
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/cgi-bin/$1 +

    + +
    +
    +

    Available Languages:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/mass.html.ko.euc-kr b/trunk/docs/manual/vhosts/mass.html.ko.euc-kr new file mode 100644 index 0000000000..e331a3e528 --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.html.ko.euc-kr @@ -0,0 +1,423 @@ + + + +´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ µ¿ÀûÀ¸·Î ¼³Á¤Çϱâ - Apache HTTP Server + + + + + +
    <-
    +

    ´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ µ¿ÀûÀ¸·Î ¼³Á¤Çϱâ

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    +
    ÀÌ ¹®¼­´Â ÃÖ½ÅÆÇ ¹ø¿ªÀÌ ¾Æ´Õ´Ï´Ù. + ÃÖ±Ù¿¡ º¯°æµÈ ³»¿ëÀº ¿µ¾î ¹®¼­¸¦ Âü°íÇϼ¼¿ä.
    + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ 1.3¿¡¼­ ´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ È¿À²ÀûÀ¸·Î + ¼­ºñ½ºÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. +

    + +
    + +
    top
    +
    +

    µ¿±â

    + +

    ´ç½ÅÀÇ httpd.conf¿¡ ´ÙÀ½°ú °°ÀÌ ¼­·Î ºñ½ÁÇÑ + <VirtualHost> ¼½¼ÇµéÀ» ¸¹ÀÌ ÀÖ´Ù¸é ¿©±â¼­ + ¼³¸íÇÏ´Â ¹æ¹ýÀÌ µµ¿òÀÌ µÉ °ÍÀÌ´Ù:

    + +

    +NameVirtualHost 111.22.33.44
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-1.com
    + DocumentRoot /www/hosts/www.customer-1.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
    +
    +</VirtualHost>
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-2.com
    + DocumentRoot /www/hosts/www.customer-2.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
    +
    +</VirtualHost>
    +# ¹Ùº¸ ¹Ùº¸ ¹Ùº¸
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-N.com
    + DocumentRoot /www/hosts/www.customer-N.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
    +
    +</VirtualHost> +

    + +

    ±âº» °³³äÀº Á¤ÀûÀÎ <VirtualHost> + ¼³Á¤ ¸ðµÎ¸¦ µ¿ÀûÀ¸·Î ó¸®Çϵµ·Ï ´ëüÇÏ´Â °ÍÀÌ´Ù. + ±×·¯¸é ¸¹Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    1. ¼³Á¤ÆÄÀÏÀÌ ÀÛ¾ÆÁ®¼­ ¾ÆÆÄÄ¡°¡ »¡¸® ½ÃÀÛÇÏ°í ¸Þ¸ð¸®¸¦ + Àû°Ô »ç¿ëÇÑ´Ù.
    2. + +
    3. °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇϱâÀ§ÇØ ÆÄÀϽýºÅÛ¿¡ Àû´çÇÑ + µð·ºÅ丮¸¦ ¸¸µé°í DNS¿¡ Ç׸ñÀ» Ãß°¡Çϱ⸸ ÇϸéµÈ´Ù. Áï, + ¾ÆÆÄÄ¡¸¦ Àç¼³Á¤ÇÏ°í Àç½ÃÀÛÇÒ ÇÊ¿ä°¡ ¾ø´Ù.
    4. +
    + +

    ´ÜÁ¡Àº °¢ °¡»óÈ£½ºÆ®º°·Î ´Ù¸¥ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù´Â + Á¡ÀÌ´Ù. ±×·¯³ª ¸Å¿ì ¸¹Àº °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù¸é ÆÄÀϱâ¼úÀÚ¸¦ + ´Ù ½á¹ö¸®±â¶§¹®¿¡ ¼­·Î ´Ù¸¥ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ÆÄÀÌÇÁ³ª + fifo·Î ·Î±×¸¦ º¸³»°í, ¹Þ´Â Æí¿¡¼­ ·Î±×¸¦ ó¸®ÇÏ¿© ³ª´©´Â + ¹æ¹ýÀÌ (Åë°è µîÀ» ¸ðÀ» ¼öµµ ÀÖ´Ù) ´õ ³´´Ù.

    + +
    top
    +
    +

    °³¿ä

    + +

    °¡»óÈ£½ºÆ®´Â IP ÁÖ¼Ò¿Í HTTP ¿äûÀÇ Host: + Çì´õ Á¤º¸·Î Á¤ÀÇÇÑ´Ù. ±âº»ÀûÀ¸·Î ´ë·®ÀÇ + µ¿Àû °¡»óÈ£½ºÆ® ±â¼úÀº ÀÚµ¿À¸·Î °¡»óÈ£½ºÆ® Á¤º¸¸¦ ¿äûÀÇ + ÆÄÀÏ°æ·Î¿¡ Æ÷ÇÔÇÑ´Ù. ÀÌ´Â ´ëºÎºÐ mod_vhost_alias¸¦ + »ç¿ëÇÏ¿© ½±°Ô ÇØ°áÇÒ ¼ö ÀÖÁö¸¸, ¾ÆÆÄÄ¡ 1.3.6 ÀÌÇϸ¦ »ç¿ëÇÑ´Ù¸é + mod_rewrite¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ÀÌ µÎ ¸ðµâ + ¸ðµÎ ±âº»ÀûÀ¸·Î ¼­¹ö¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â´Ù. ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ·Á¸é + ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÏ°í ÄÄÆÄÀÏÇÒ¶§ Æ÷ÇÔÇØ¾ß ÇÑ´Ù.

    + +

    µ¿Àû °¡»óÈ£½ºÆ®¸¦ ÀϹÝÀûÀÎ °¡»óÈ£½ºÆ®Ã³·³ º¸ÀÌ°ÔÇÏ·Á¸é + ¿©·¯°¡Áö¸¦ `¼Ó¿©¾ß' ÇÑ´Ù. °¡Àå Áß¿äÇÑ °ÍÀº ¾ÆÆÄÄ¡°¡ ÀÚ±âÂüÁ¶ + URL µîÀ» ¸¸µé¶§ »ç¿ëÇÒ ¼­¹ö¸íÀÌ´Ù. ¼­¹ö¸íÀº + ServerName Áö½Ã¾î·Î ¼³Á¤Çϸç, CGI¿¡´Â + SERVER_NAME ȯ°æº¯¼ö·Î ÁÖ¾îÁø´Ù. ½ÇÇàÁß ½ÇÁ¦ + ¼­¹ö¸íÀº UseCanonicalName ¼³Á¤¿¡ ´Þ·È´Ù. + UseCanonicalName OffÀÌ¸é ¿äûÀÇ Host: + Çì´õ ³»¿ëÀÌ ¼­¹ö¸íÀÌ µÈ´Ù. UseCanonicalName DNSÀ̸é + °¡»óÈ£½ºÆ®ÀÇ IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù. + ÀüÀÚ´Â À̸§±â¹Ý µ¿Àû °¡»óÈ£½ºÆ®¿¡¼­ »ç¿ëÇÏ°í, ÈÄÀÚ´Â IP±â¹Ý + °¡»óÈ£½ºÆ®¿¡¼­ »ç¿ëÇÑ´Ù. Host: Çì´õ°¡ ¾ø°Å³ª + DNS °Ë»öÀÌ ½ÇÆÐÇÏ¿© ¾ÆÆÄÄ¡°¡ ¼­¹ö¸íÀ» ¾Ë¾Æ³»Áö ¸øÇϸé + ServerNameÀ¸·Î ¼³Á¤ÇÑ °ªÀ» ´ë½Å »ç¿ëÇÑ´Ù.

    + +

    ´Ù¸¥ `¼ÓÀÏ' °ÍÀº (DocumentRoot·Î ¼³Á¤Çϸç, + CGI¿¡´Â DOCUMENT_ROOT ȯ°æº¯¼ö·Î ÁÖ¾îÁö´Â) + ¹®¼­·çÆ®ÀÌ´Ù. ÀϹÝÀûÀÎ °æ¿ì core ¸ðµâÀÌ ÀÌ ¼³Á¤À» »ç¿ëÇÏ¿© + URI¿¡ ÇØ´çÇÏ´Â ÆÄÀϸíÀ» ãÁö¸¸, ¼­¹ö¸¦ µ¿Àû °¡»óÈ£½ºÆÃÀ» ÇÒ¶§´Â ´Ù¸¥ + ¸ðµâÀÌ (mod_vhost_alias³ª mod_rewrite) + ´Ù¸¥ ¹æ¹ýÀ¸·Î ÀÌ·± ÀÛ¾÷À» ÇÑ´Ù. µÎ ¸ðµâ ¸ðµÎ + DOCUMENT_ROOT ȯ°æº¯¼ö¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¹Ç·Î + CGI³ª SSI ¹®¼­°¡ ÀÌ °ªÀ» »ç¿ëÇÑ´Ù¸é À߸øµÈ °á°ú¸¦ ¾òÀ» ¼ö + ÀÖ´Ù.

    + +
    top
    +
    +

    °£´ÜÇÑ µ¿Àû °¡»óÈ£½ºÆ®

    + +

    À§ µ¿±â ÀýÀÇ °¡»óÈ£½ºÆ® + ¼³Á¤À» mod_vhost_alias¸¦ »ç¿ëÇÏ¿© ´õ ÀϹÝÀûÀ¸·Î + ±¸ÇöÇß´Ù.

    + +

    +# Host: Çì´õ¿¡¼­ ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù
    +UseCanonicalName Off
    +
    +# ù¹ø° Çʵ带 »ç¿ëÇÏ¿© ÀÌ ·Î±×¸¦ °¡»óÈ£½ºÆ®º°·Î ³ª´­ ¼ö ÀÖ´Ù
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# ¿äûÀ» ó¸®ÇϱâÀ§ÇØ ÆÄÀÏ¸í¿¡ ¼­¹ö¸íÀ» Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRoot /www/hosts/%0/docs
    +VirtualScriptAlias /www/hosts/%0/cgi-bin +

    + +

    ÀÌ ¼³Á¤¿¡¼­ UseCanonicalName Off¸¦ + UseCanonicalName DNS·Î º¯°æÇϱ⸸ Çϸé IP±â¹Ý + °¡»óÈ£½ºÆ®°¡ µÈ´Ù. °¡»óÈ£½ºÆ®ÀÇ IP ÁÖ¼Ò¸¦ °¡Áö°í + ÆÄÀÏ¸í¿¡ Ãß°¡ÇÒ ¼­¹ö¸íÀ» ¾Ë ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    °¡»óÀ¸·Î È£½ºÆ®Çϴ ȨÆäÀÌÁö ½Ã½ºÅÛ

    + +

    ISP ȨÆäÀÌÁö ¼­¹ö¸¦ À§ÇØ À§ÀÇ ¼³Á¤À» ¼öÁ¤Çß´Ù. Á¶±Ý ´õ + º¹ÀâÇÑ ¼³Á¤À» »ç¿ëÇϸé www.user.isp.comÀÇ ¹®¼­¸¦ + /home/user/¿¡ µÎ´Â ½ÄÀ¸·Î ¼­¹ö¸íÀÇ ÀϺθ¦ °¡Áö°í + ÆÄÀϸíÀ» ¸¸µé ¼ö ÀÖ´Ù. ÀÌ ¼³Á¤Àº + cgi-binÀ» °¢ °¡»óÈ£½ºÆ®°¡ µû·Î °¡ÁöÁö¾Ê°í + ¸ðµç °¡»óÈ£½ºÆ®°¡ °°ÀÌ »ç¿ëÇÑ´Ù.

    + +

    +# ±âº»ÀûÀÎ ³»¿ëÀº À§¿Í °°´Ù. ±×¸®°í
    +
    +# ÆÄÀÏ¸í¿¡ ¼­¹ö¸íÀÇ ÀϺθ¦ Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRoot /www/hosts/%2/docs
    +
    +# ÇϳªÀÇ cgi-bin µð·ºÅ丮
    +ScriptAlias /cgi-bin/ /www/std-cgi/
    +

    + +

    mod_vhost_alias ¹®¼­¿¡´Â ´õ º¹ÀâÇÑ + VirtualDocumentRoot ¼³Á¤ÀÇ ¿¹°¡ ÀÖ´Ù.

    + +
    top
    +
    +

    ÇÑ ¼­¹ö¿¡ ¿©·¯ °¡»óÈ£½ºÆ® + ½Ã½ºÅÛ »ç¿ëÇϱâ

    + +

    ´õ º¹ÀâÇÑ ¼³Á¤ÀÇ ¿¹·Î ¾ÆÆÄÄ¡ÀÇ ÀϹÝÀûÀÎ + <VirtualHost> Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿©·¯ + °¡»óÈ£½ºÆ® ¼³Á¤ÀÇ ¹üÀ§¸¦ Á¶ÀýÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°Àº ¼³Á¤Àº ȨÆäÀÌÁö °í°´¿¡ IP ÁÖ¼Ò ÇÑ°³, »ó¾÷ÀûÀÎ + °í°´¿¡°Ô ´Ù¸¥ IP ÁÖ¼Ò ÇÑ°³¸¦ ºÎ¿©ÇÑ´Ù. ¹°·Ð ÀÌÀüó·³ + <VirtualHost> ¼³Á¤ ¼½¼Ç¿¡ ¸ðµÎ ¹­À» ¼öµµ + ÀÖ´Ù.

    + +

    +UseCanonicalName Off
    +
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +
    +<Directory /www/commercial>
    + + Options FollowSymLinks
    + AllowOverride All
    +
    +</Directory>
    +
    +<Directory /www/homepages>
    + + Options FollowSymLinks
    + AllowOverride None
    +
    +</Directory>
    +
    +<VirtualHost 111.22.33.44>
    + + ServerName www.commercial.isp.com
    +
    + CustomLog logs/access_log.commercial vcommon
    +
    + VirtualDocumentRoot /www/commercial/%0/docs
    + VirtualScriptAlias /www/commercial/%0/cgi-bin
    +
    +</VirtualHost>
    +
    +<VirtualHost 111.22.33.45>
    + + ServerName www.homepages.isp.com
    +
    + CustomLog logs/access_log.homepages vcommon
    +
    + VirtualDocumentRoot /www/homepages/%0/docs
    + ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    +</VirtualHost> +

    + +
    top
    +
    +

    ´õ È¿À²ÀûÀÎ IP±â¹Ý °¡»óÈ£½ºÆ®

    + +

    ù¹ø° ¿¹¿¡¼­ ³ª´Â ¼³Á¤À» °£´ÜÈ÷ + IP±â¹Ý °¡»óÈ£½ºÆ®·Î ¹Ù²Ü ¼ö ÀÖ´Ù°í ¸»Çß´Ù. ºÒÇàÈ÷µµ + ±×·± ¼³Á¤Àº ¸Å ¿äû¸¶´Ù DNS¸¦ ã¾Æ¾ßÇϹǷΠ¸Å¿ì ºñÈ¿À²ÀûÀÌ´Ù. + À̸§´ë½Å IP ÁÖ¼Ò·Î ÆÄÀϽýºÅÛÀ» ±¸¼ºÇÏ°í °°Àº ¹æ½ÄÀ¸·Î + ·Î±×¸¦ ¼öÁ¤ÇÏ¸é ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¼­¹ö¸íÀ» + ´Ù·ê ÇÊ¿ä°¡ ¾ø¾îÁö°í, DNS °Ë»öµµ ÇÏÁö ¾Ê°Ô µÈ´Ù.

    + +

    +# IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù
    +UseCanonicalName DNS
    +
    +# ·Î±×¸¦ ³ª´­ ¼ö ÀÖµµ·Ï IP ÁÖ¼Ò¸¦ Æ÷ÇÔÇÑ´Ù
    +LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# ÆÄÀÏ¸í¿¡ IP ÁÖ¼Ò¸¦ Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRootIP /www/hosts/%0/docs
    +VirtualScriptAliasIP /www/hosts/%0/cgi-bin
    +

    + +
    top
    +
    +

    ¾ÆÆÄÄ¡ ÀÌÀü ¹öÀü »ç¿ëÇϱâ

    + +

    À§ ¿¹µéÀº ¾ÆÆÄÄ¡ ¹öÀü 1.3.6 ÀÌÈÄ¿¡ Æ÷ÇÔµÈ + mod_vhost_aliasÀ» »ç¿ëÇÑ´Ù. + mod_vhost_alias°¡ ¾ø´Â ¾ÆÆÄÄ¡ ¹öÀüÀ» »ç¿ëÇÑ´Ù¸é + ÀÌ¹Ì ¸»ÇßµíÀÌ mod_rewrite¸¦ »ç¿ëÇÏ¿©, ´Ü + Host:-Çì´õ±â¹Ý °¡»óÈ£½ºÆ®¸¸À», ±¸ÇöÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç ·Î±×¿¡ °üÇÏ¿© ÁÖÀÇÇÒ Á¡ÀÌ ÀÖ´Ù. ¾ÆÆÄÄ¡ 1.3.6¿¡¼­ + ·Î±×Çü½Ä Áö½Ã¾î %V°¡ Æ÷ÇԵǾú°í, ¹öÀü 1.3.0 + - 1.3.3¿¡¼­ ÀÌ ±â´ÉÀ» %v ¿É¼ÇÀÌ ´ë½Å Çß´Ù. ±×·¯³ª + ¹öÀü 1.3.4¿¡´Â ÀÌ·± ±â´ÉÀÌ ¾ø´Ù. ¾î¶² ¾ÆÆÄÄ¡ ¹öÀü¿¡¼­µµ + .htaccess ÆÄÀÏ¿¡¼­ UseCanonicalName + Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖÀ¸¹Ç·Î ·Î±×¿¡ ÀÌ»óÇÑ ³»¿ëÀÌ ±â·ÏµÉ ¼ö ÀÖ´Ù. + ±×·¯¹Ç·Î °¡Àå ÁÁÀº ¹æ¹ýÀº %{Host}i Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Host: Çì´õ¸¦ Á÷Á¢ ·Î±×¿¡ ³²±â´Â °ÍÀÌ´Ù. + ¶Ç, ÀÌ ¹æ¹ýÀº %V´Â Æ÷ÇÔÇÏÁö¾Ê´Â :port¸¦ + µÚ¿¡ Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +
    top
    +
    +

    mod_rewrite¸¦ + »ç¿ëÇÑ °£´ÜÇÑ µ¿Àû °¡»óÈ£½ºÆ®

    + +

    ´ÙÀ½Àº ù¹ø° ¿¹¿Í °°Àº ÀÏÀ» ÇÏ´Â + httpd.conf ¿¹ÀÌ´Ù. óÀ½ Àý¹ÝÀº ù¹ø° ¿¹¿Í + °ÅÀÇ ºñ½ÁÇÏÁö¸¸, ÀÌÀü ¹öÀü°úÀÇ È£È¯¼º°ú mod_rewriteÀÇ + ÀûÀýÇÑ µ¿ÀÛÀ» À§ÇØ ¼öÁ¤µÇ¾ú´Ù. ³ª¸ÓÁö Àý¹ÝÀº ½ÇÁ¦ ÀÛ¾÷À» + ÇÏ´Â mod_rewrite¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    Ưº°È÷ ÁÖÀÇÇØ¾ß ÇÒ »çÇ×ÀÌ ÀÖ´Ù. ±âº»ÀûÀ¸·Î + mod_rewrite´Â (mod_alias µî) ´Ù¸¥ + URI ¹ø¿ª ¸ðµâ ÀÌÀü¿¡ ½ÇÇàµÈ´Ù. ±×·¡¼­ ´Ù¸¥ URI ¹ø¿ª ¸ðµâµé°ú + °°ÀÌ µ¿ÀÛÇÒ °ÍÀ» °í·ÁÇÏ¿© mod_rewrite¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. + ¶Ç, µ¿Àû °¡»óÈ£½ºÆ®¿¡¼­ ScriptAlias°ú °°Àº + ±â´ÉÀ» À§Çؼ­´Â Ưº°ÇÑ ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù.

    + +

    +# Host: Çì´õ¿¡¼­ ¼­¹ö¸íÀ» ¾ò´Â´Ù
    +UseCanonicalName Off
    +
    +# splittable logs
    +LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +<Directory /www/hosts>
    + + # ScriptAlias ½ÄÀ¸·Î CGI ½ÇÇàÀ» °­Á¦ÇÒ ¼ö ¾ø±â¶§¹®¿¡
    + # ¿©±â¿¡ ExecCGI¸¦ »ç¿ëÇÑ´Ù
    + Options FollowSymLinks ExecCGI
    +
    +</Directory>
    +
    +# ÀÌÁ¦ ¾î·Á¿î ºÎºÐÀÌ´Ù
    +
    +RewriteEngine On
    +
    +# Host: Çì´õ¿¡¼­ °¡Á®¿Â ¼­¹ö¸í¿¡´Â ´ë¼Ò¹®ÀÚ°¡ µÚ¼¯¿©ÀÖÀ» ¼ö ÀÖ´Ù
    +RewriteMap lowercase int:tolower
    +
    +## ÀÏ¹Ý ¹®¼­¸¦ ¸ÕÀú ó¸®ÇÑ´Ù:
    +# Alias /icons/ °¡ µ¿ÀÛÇϵµ·Ï - ´Ù¸¥ alias¿¡ ´ëÇؼ­µµ ¹Ýº¹
    +RewriteCond %{REQUEST_URI} !^/icons/
    +# CGI°¡ µ¿ÀÛÇϵµ·Ï
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +# Ưº°ÇÑ ÀÛ¾÷
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
    +
    +## ÀÌÁ¦ CGI¸¦ ó¸®ÇÑ´Ù - MIME typeÀ» °­Á¦ÇØ¾ß ÇÑ´Ù
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
    +
    +# ³¡! +

    + +
    top
    +
    +

    mod_rewrite¸¦ + »ç¿ëÇÑ È¨ÆäÀÌÁö ½Ã½ºÅÛ

    + +

    ´ÙÀ½Àº µÎ¹ø° ¿¹¿Í °°Àº ÀÏÀ» + ÇÑ´Ù.

    + +

    +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# CGI°¡ µ¿ÀÛÇϵµ·Ï
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +
    +# RewriteRuleÀÌ µ¿ÀÛÇϵµ·Ï È£½ºÆ®¸íÀÌ ¿Ã¹Ù¸¥Áö °Ë»çÇÑ´Ù
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^www\.[a-z-]+\.isp\.com$
    +
    +# °¡»óÈ£½ºÆ®¸íÀ» URI ¾Õ¿¡ ºÙÀδÙ
    +# [C]´Â ÀÌ °á°ú¸¦ °¡Áö°í ´ÙÀ½ ÀçÀÛ¼ºÀ» ¼öÇàÇÔÀ» ¶æÇÑ´Ù
    +RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
    +
    +# ÀÌÁ¦ ½ÇÁ¦ ÆÄÀϸíÀ» ¸¸µç´Ù
    +RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
    +
    +# Àüü CGI µð·ºÅ丮¸¦ Á¤ÀÇÇÑ´Ù
    +ScriptAlias /cgi-bin/ /www/std-cgi/ +

    + +
    top
    +
    +

    º°µµÀÇ °¡»óÈ£½ºÆ® ¼³Á¤ÆÄÀÏ + »ç¿ëÇϱâ

    + +

    ´ÙÀ½Àº mod_rewriteÀÇ °í±Þ ±â´ÉÀ» »ç¿ëÇÏ¿© + º°µµÀÇ ¼³Á¤ÆÄÀÏÀ» °¡Áö°í °¡»óÈ£½ºÆ®ÀÇ ¹®¼­·çÆ®¸¦ ¾Ë¾Æ³½´Ù. + ´õ À¯¿¬ÇÏÁö¸¸ ´õ º¹ÀâÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇÏ´Ù.

    + +

    vhost.map ÆÄÀÏÀº ´ÙÀ½°ú °°´Ù:

    + +

    +www.customer-1.com /www/customers/1
    +www.customer-2.com /www/customers/2
    +# ...
    +www.customer-N.com /www/customers/N
    +

    + +

    http.conf´Â ´ÙÀ½°ú °°´Ù:

    + +

    +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# ´ëÀÀÆÄÀÏÀ» Á¤ÀÇÇÑ´Ù
    +RewriteMap vhost txt:/www/conf/vhost.map
    +
    +# À§¿Í °°ÀÌ aliasµéÀ» ó¸®ÇÑ´Ù
    +RewriteCond %{REQUEST_URI} !^/icons/
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +# ÆÄÀÏ ³»¿ëÀ» °¡Áö°í ã´Â´Ù
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/docs/$1
    +
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/cgi-bin/$1 +

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  en  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/mass.xml b/trunk/docs/manual/vhosts/mass.xml new file mode 100644 index 0000000000..f430ff6109 --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.xml @@ -0,0 +1,437 @@ + + + + + + + + +Virtual Hosts + Dynamically configured mass virtual hosting + + + +

    This document describes how to efficiently serve an + arbitrary number of virtual hosts with Apache. +

    + +
    + +
    Motivation + +

    The techniques described here are of interest if your + httpd.conf contains many + <VirtualHost> sections that are + substantially the same, for example:

    + + +NameVirtualHost 111.22.33.44
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-1.com
    + DocumentRoot /www/hosts/www.customer-1.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
    +
    +</VirtualHost>
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-2.com
    + DocumentRoot /www/hosts/www.customer-2.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
    +
    +</VirtualHost>
    +# blah blah blah
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-N.com
    + DocumentRoot /www/hosts/www.customer-N.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
    +
    +</VirtualHost> +
    + +

    The basic idea is to replace all of the static + <VirtualHost> configuration with a mechanism + that works it out dynamically. This has a number of + advantages:

    + +
      +
    1. Your configuration file is smaller so Apache starts + faster and uses less memory.
    2. + +
    3. Adding virtual hosts is simply a matter of creating the + appropriate directories in the filesystem and entries in the + DNS - you don't need to reconfigure or restart Apache.
    4. +
    + +

    The main disadvantage is that you cannot have a different + log file for each virtual host; however if you have very many + virtual hosts then doing this is dubious anyway because it eats + file descriptors. It is better to log to a pipe or a fifo and + arrange for the process at the other end to distribute the logs + to the customers (it can also accumulate statistics, etc.).

    + +
    + +
    Overview + +

    A virtual host is defined by two pieces of information: its + IP address, and the contents of the Host: header + in the HTTP request. The dynamic mass virtual hosting technique + is based on automatically inserting this information into the + pathname of the file that is used to satisfy the request. This + is done most easily using mod_vhost_alias, + but if you are using a version of Apache up to 1.3.6 then you + must use mod_rewrite. + Both of these modules are disabled by default; you must enable + one of them when configuring and building Apache if you want to + use this technique.

    + +

    A couple of things need to be `faked' to make the dynamic + virtual host look like a normal one. The most important is the + server name which is used by Apache to generate + self-referential URLs, etc. It is configured with the + ServerName directive, and it is available to CGIs + via the SERVER_NAME environment variable. The + actual value used at run time is controlled by the UseCanonicalName + setting. With UseCanonicalName Off the server name + comes from the contents of the Host: header in the + request. With UseCanonicalName DNS it comes from a + reverse DNS lookup of the virtual host's IP address. The former + setting is used for name-based dynamic virtual hosting, and the + latter is used for IP-based hosting. If Apache cannot work out + the server name because there is no Host: header + or the DNS lookup fails then the value configured with + ServerName is used instead.

    + +

    The other thing to `fake' is the document root (configured + with DocumentRoot and available to CGIs via the + DOCUMENT_ROOT environment variable). In a normal + configuration this setting is used by the core module when + mapping URIs to filenames, but when the server is configured to + do dynamic virtual hosting that job is taken over by another + module (either mod_vhost_alias or + mod_rewrite) which has a different way of doing + the mapping. Neither of these modules is responsible for + setting the DOCUMENT_ROOT environment variable so + if any CGIs or SSI documents make use of it they will get a + misleading value.

    + +
    + +
    Simple dynamic virtual hosts + +

    This extract from httpd.conf implements the + virtual host arrangement outlined in the Motivation section above, but in a + generic fashion using mod_vhost_alias.

    + + +# get the server name from the Host: header
    +UseCanonicalName Off
    +
    +# this log format can be split per-virtual-host based on the first field
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# include the server name in the filenames used to satisfy requests
    +VirtualDocumentRoot /www/hosts/%0/docs
    +VirtualScriptAlias /www/hosts/%0/cgi-bin +
    + +

    This configuration can be changed into an IP-based virtual + hosting solution by just turning UseCanonicalName + Off into UseCanonicalName DNS. The server + name that is inserted into the filename is then derived from + the IP address of the virtual host.

    + +
    + +
    A virtually hosted homepages system + +

    This is an adjustment of the above system tailored for an + ISP's homepages server. Using a slightly more complicated + configuration we can select substrings of the server name to + use in the filename so that e.g. the documents for + www.user.isp.com are found in + /home/user/. It uses a single cgi-bin + directory instead of one per virtual host.

    + + +# all the preliminary stuff is the same as above, then
    +
    +# include part of the server name in the filenames
    +VirtualDocumentRoot /www/hosts/%2/docs
    +
    +# single cgi-bin directory
    +ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    + +

    There are examples of more complicated + VirtualDocumentRoot settings in the + mod_vhost_alias documentation.

    + +
    + +
    Using more than + one virtual hosting system on the same server + +

    With more complicated setups you can use Apache's normal + <VirtualHost> directives to control the + scope of the various virtual hosting configurations. For + example, you could have one IP address for homepages customers + and another for commercial customers with the following setup. + This can of course be combined with conventional + <VirtualHost> configuration sections.

    + + +UseCanonicalName Off
    +
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +
    +<Directory /www/commercial>
    + + Options FollowSymLinks
    + AllowOverride All
    +
    +</Directory>
    +
    +<Directory /www/homepages>
    + + Options FollowSymLinks
    + AllowOverride None
    +
    +</Directory>
    +
    +<VirtualHost 111.22.33.44>
    + + ServerName www.commercial.isp.com
    +
    + CustomLog logs/access_log.commercial vcommon
    +
    + VirtualDocumentRoot /www/commercial/%0/docs
    + VirtualScriptAlias /www/commercial/%0/cgi-bin
    +
    +</VirtualHost>
    +
    +<VirtualHost 111.22.33.45>
    + + ServerName www.homepages.isp.com
    +
    + CustomLog logs/access_log.homepages vcommon
    +
    + VirtualDocumentRoot /www/homepages/%0/docs
    + ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    +</VirtualHost> +
    + +
    + +
    More efficient IP-based virtual hosting + +

    After the first example I noted that + it is easy to turn it into an IP-based virtual hosting setup. + Unfortunately that configuration is not very efficient because + it requires a DNS lookup for every request. This can be avoided + by laying out the filesystem according to the IP addresses + themselves rather than the corresponding names and changing the + logging similarly. Apache will then usually not need to work + out the server name and so incur a DNS lookup.

    + + +# get the server name from the reverse DNS of the IP address
    +UseCanonicalName DNS
    +
    +# include the IP address in the logs so they may be split
    +LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# include the IP address in the filenames
    +VirtualDocumentRootIP /www/hosts/%0/docs
    +VirtualScriptAliasIP /www/hosts/%0/cgi-bin
    +
    + +
    + +
    Using older versions of Apache + +

    The examples above rely on mod_vhost_alias + which appeared after version 1.3.6. If you are using a version + of Apache without mod_vhost_alias then you can + implement this technique with mod_rewrite as + illustrated below, but only for Host:-header-based virtual + hosts.

    + +

    In addition there are some things to beware of with logging. + Apache 1.3.6 is the first version to include the + %V log format directive; in versions 1.3.0 - 1.3.3 + the %v option did what %V does; + version 1.3.4 has no equivalent. In all these versions of + Apache the UseCanonicalName directive can appear + in .htaccess files which means that customers can + cause the wrong thing to be logged. Therefore the best thing to + do is use the %{Host}i directive which logs the + Host: header directly; note that this may include + :port on the end which is not the case for + %V.

    + +
    + +
    Simple dynamic + virtual hosts using <code>mod_rewrite</code> + +

    This extract from httpd.conf does the same + thing as the first example. The first + half is very similar to the corresponding part above but with + some changes for backward compatibility and to make the + mod_rewrite part work properly; the second half + configures mod_rewrite to do the actual work.

    + +

    There are a couple of especially tricky bits: By default, + mod_rewrite runs before the other URI translation + modules (mod_alias etc.) so if they are used then + mod_rewrite must be configured to accommodate + them. Also, some magic must be performed to do a + per-dynamic-virtual-host equivalent of + ScriptAlias.

    + + +# get the server name from the Host: header
    +UseCanonicalName Off
    +
    +# splittable logs
    +LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +<Directory /www/hosts>
    + + # ExecCGI is needed here because we can't force
    + # CGI execution in the way that ScriptAlias does
    + Options FollowSymLinks ExecCGI
    +
    +</Directory>
    +
    +# now for the hard bit
    +
    +RewriteEngine On
    +
    +# a ServerName derived from a Host: header may be any case at all
    +RewriteMap lowercase int:tolower
    +
    +## deal with normal documents first:
    +# allow Alias /icons/ to work - repeat for other aliases
    +RewriteCond %{REQUEST_URI} !^/icons/
    +# allow CGIs to work
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +# do the magic
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
    +
    +## and now deal with CGIs - we have to force a MIME type
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
    +
    +# that's it! +
    + +
    + +
    A + homepages system using <code>mod_rewrite</code> + +

    This does the same thing as the second + example.

    + + +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# allow CGIs to work
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +
    +# check the hostname is right so that the RewriteRule works
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^www\.[a-z-]+\.isp\.com$
    +
    +# concatenate the virtual host name onto the start of the URI
    +# the [C] means do the next rewrite on the result of this one
    +RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
    +
    +# now create the real file name
    +RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
    +
    +# define the global CGI directory
    +ScriptAlias /cgi-bin/ /www/std-cgi/ +
    + +
    + +
    Using a separate virtual + host configuration file + +

    This arrangement uses more advanced mod_rewrite + features to get the translation from virtual host to document + root from a separate configuration file. This provides more + flexibility but requires more complicated configuration.

    + +

    The vhost.map file contains something like + this:

    + + +www.customer-1.com /www/customers/1
    +www.customer-2.com /www/customers/2
    +# ...
    +www.customer-N.com /www/customers/N
    +
    + +

    The http.conf contains this:

    + + +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# define the map file
    +RewriteMap vhost txt:/www/conf/vhost.map
    +
    +# deal with aliases as above
    +RewriteCond %{REQUEST_URI} !^/icons/
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +# this does the file-based remap
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/docs/$1
    +
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/cgi-bin/$1 +
    + +
    +
    diff --git a/trunk/docs/manual/vhosts/mass.xml.ko b/trunk/docs/manual/vhosts/mass.xml.ko new file mode 100644 index 0000000000..2d266c062c --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.xml.ko @@ -0,0 +1,412 @@ + + + + + + + + +°¡»óÈ£½ºÆ® + ´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ µ¿ÀûÀ¸·Î ¼³Á¤Çϱâ + + + +

    ÀÌ ¹®¼­´Â ¾ÆÆÄÄ¡ 1.3¿¡¼­ ´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ È¿À²ÀûÀ¸·Î + ¼­ºñ½ºÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇÑ´Ù. +

    + +
    + +
    µ¿±â + +

    ´ç½ÅÀÇ httpd.conf¿¡ ´ÙÀ½°ú °°ÀÌ ¼­·Î ºñ½ÁÇÑ + <VirtualHost> ¼½¼ÇµéÀ» ¸¹ÀÌ ÀÖ´Ù¸é ¿©±â¼­ + ¼³¸íÇÏ´Â ¹æ¹ýÀÌ µµ¿òÀÌ µÉ °ÍÀÌ´Ù:

    + + +NameVirtualHost 111.22.33.44
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-1.com
    + DocumentRoot /www/hosts/www.customer-1.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
    +
    +</VirtualHost>
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-2.com
    + DocumentRoot /www/hosts/www.customer-2.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
    +
    +</VirtualHost>
    +# ¹Ùº¸ ¹Ùº¸ ¹Ùº¸
    +<VirtualHost 111.22.33.44>
    + + ServerName www.customer-N.com
    + DocumentRoot /www/hosts/www.customer-N.com/docs
    + ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
    +
    +</VirtualHost> +
    + +

    ±âº» °³³äÀº Á¤ÀûÀÎ <VirtualHost> + ¼³Á¤ ¸ðµÎ¸¦ µ¿ÀûÀ¸·Î ó¸®Çϵµ·Ï ´ëüÇÏ´Â °ÍÀÌ´Ù. + ±×·¯¸é ¸¹Àº ÀåÁ¡ÀÌ ÀÖ´Ù:

    + +
      +
    1. ¼³Á¤ÆÄÀÏÀÌ ÀÛ¾ÆÁ®¼­ ¾ÆÆÄÄ¡°¡ »¡¸® ½ÃÀÛÇÏ°í ¸Þ¸ð¸®¸¦ + Àû°Ô »ç¿ëÇÑ´Ù.
    2. + +
    3. °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇϱâÀ§ÇØ ÆÄÀϽýºÅÛ¿¡ Àû´çÇÑ + µð·ºÅ丮¸¦ ¸¸µé°í DNS¿¡ Ç׸ñÀ» Ãß°¡Çϱ⸸ ÇϸéµÈ´Ù. Áï, + ¾ÆÆÄÄ¡¸¦ Àç¼³Á¤ÇÏ°í Àç½ÃÀÛÇÒ ÇÊ¿ä°¡ ¾ø´Ù.
    4. +
    + +

    ´ÜÁ¡Àº °¢ °¡»óÈ£½ºÆ®º°·Î ´Ù¸¥ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù´Â + Á¡ÀÌ´Ù. ±×·¯³ª ¸Å¿ì ¸¹Àº °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÑ´Ù¸é ÆÄÀϱâ¼úÀÚ¸¦ + ´Ù ½á¹ö¸®±â¶§¹®¿¡ ¼­·Î ´Ù¸¥ ·Î±×ÆÄÀÏÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ÆÄÀÌÇÁ³ª + fifo·Î ·Î±×¸¦ º¸³»°í, ¹Þ´Â Æí¿¡¼­ ·Î±×¸¦ ó¸®ÇÏ¿© ³ª´©´Â + ¹æ¹ýÀÌ (Åë°è µîÀ» ¸ðÀ» ¼öµµ ÀÖ´Ù) ´õ ³´´Ù.

    + +
    + +
    °³¿ä + +

    °¡»óÈ£½ºÆ®´Â IP ÁÖ¼Ò¿Í HTTP ¿äûÀÇ Host: + Çì´õ Á¤º¸·Î Á¤ÀÇÇÑ´Ù. ±âº»ÀûÀ¸·Î ´ë·®ÀÇ + µ¿Àû °¡»óÈ£½ºÆ® ±â¼úÀº ÀÚµ¿À¸·Î °¡»óÈ£½ºÆ® Á¤º¸¸¦ ¿äûÀÇ + ÆÄÀÏ°æ·Î¿¡ Æ÷ÇÔÇÑ´Ù. ÀÌ´Â ´ëºÎºÐ mod_vhost_alias¸¦ + »ç¿ëÇÏ¿© ½±°Ô ÇØ°áÇÒ ¼ö ÀÖÁö¸¸, ¾ÆÆÄÄ¡ 1.3.6 ÀÌÇϸ¦ »ç¿ëÇÑ´Ù¸é + mod_rewrite¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. ÀÌ µÎ ¸ðµâ + ¸ðµÎ ±âº»ÀûÀ¸·Î ¼­¹ö¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â´Ù. ÀÌ ¹æ¹ýÀ» »ç¿ëÇÏ·Á¸é + ¾ÆÆÄÄ¡¸¦ ±¸¼ºÇÏ°í ÄÄÆÄÀÏÇÒ¶§ Æ÷ÇÔÇØ¾ß ÇÑ´Ù.

    + +

    µ¿Àû °¡»óÈ£½ºÆ®¸¦ ÀϹÝÀûÀÎ °¡»óÈ£½ºÆ®Ã³·³ º¸ÀÌ°ÔÇÏ·Á¸é + ¿©·¯°¡Áö¸¦ `¼Ó¿©¾ß' ÇÑ´Ù. °¡Àå Áß¿äÇÑ °ÍÀº ¾ÆÆÄÄ¡°¡ ÀÚ±âÂüÁ¶ + URL µîÀ» ¸¸µé¶§ »ç¿ëÇÒ ¼­¹ö¸íÀÌ´Ù. ¼­¹ö¸íÀº + ServerName Áö½Ã¾î·Î ¼³Á¤Çϸç, CGI¿¡´Â + SERVER_NAME ȯ°æº¯¼ö·Î ÁÖ¾îÁø´Ù. ½ÇÇàÁß ½ÇÁ¦ + ¼­¹ö¸íÀº UseCanonicalName ¼³Á¤¿¡ ´Þ·È´Ù. + UseCanonicalName OffÀÌ¸é ¿äûÀÇ Host: + Çì´õ ³»¿ëÀÌ ¼­¹ö¸íÀÌ µÈ´Ù. UseCanonicalName DNSÀ̸é + °¡»óÈ£½ºÆ®ÀÇ IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù. + ÀüÀÚ´Â À̸§±â¹Ý µ¿Àû °¡»óÈ£½ºÆ®¿¡¼­ »ç¿ëÇÏ°í, ÈÄÀÚ´Â IP±â¹Ý + °¡»óÈ£½ºÆ®¿¡¼­ »ç¿ëÇÑ´Ù. Host: Çì´õ°¡ ¾ø°Å³ª + DNS °Ë»öÀÌ ½ÇÆÐÇÏ¿© ¾ÆÆÄÄ¡°¡ ¼­¹ö¸íÀ» ¾Ë¾Æ³»Áö ¸øÇϸé + ServerNameÀ¸·Î ¼³Á¤ÇÑ °ªÀ» ´ë½Å »ç¿ëÇÑ´Ù.

    + +

    ´Ù¸¥ `¼ÓÀÏ' °ÍÀº (DocumentRoot·Î ¼³Á¤Çϸç, + CGI¿¡´Â DOCUMENT_ROOT ȯ°æº¯¼ö·Î ÁÖ¾îÁö´Â) + ¹®¼­·çÆ®ÀÌ´Ù. ÀϹÝÀûÀÎ °æ¿ì core ¸ðµâÀÌ ÀÌ ¼³Á¤À» »ç¿ëÇÏ¿© + URI¿¡ ÇØ´çÇÏ´Â ÆÄÀϸíÀ» ãÁö¸¸, ¼­¹ö¸¦ µ¿Àû °¡»óÈ£½ºÆÃÀ» ÇÒ¶§´Â ´Ù¸¥ + ¸ðµâÀÌ (mod_vhost_alias³ª mod_rewrite) + ´Ù¸¥ ¹æ¹ýÀ¸·Î ÀÌ·± ÀÛ¾÷À» ÇÑ´Ù. µÎ ¸ðµâ ¸ðµÎ + DOCUMENT_ROOT ȯ°æº¯¼ö¸¦ »ç¿ëÇÏÁö ¾ÊÀ¸¹Ç·Î + CGI³ª SSI ¹®¼­°¡ ÀÌ °ªÀ» »ç¿ëÇÑ´Ù¸é À߸øµÈ °á°ú¸¦ ¾òÀ» ¼ö + ÀÖ´Ù.

    + +
    + +
    °£´ÜÇÑ µ¿Àû °¡»óÈ£½ºÆ® + +

    À§ µ¿±â ÀýÀÇ °¡»óÈ£½ºÆ® + ¼³Á¤À» mod_vhost_alias¸¦ »ç¿ëÇÏ¿© ´õ ÀϹÝÀûÀ¸·Î + ±¸ÇöÇß´Ù.

    + + +# Host: Çì´õ¿¡¼­ ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù
    +UseCanonicalName Off
    +
    +# ù¹ø° Çʵ带 »ç¿ëÇÏ¿© ÀÌ ·Î±×¸¦ °¡»óÈ£½ºÆ®º°·Î ³ª´­ ¼ö ÀÖ´Ù
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# ¿äûÀ» ó¸®ÇϱâÀ§ÇØ ÆÄÀÏ¸í¿¡ ¼­¹ö¸íÀ» Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRoot /www/hosts/%0/docs
    +VirtualScriptAlias /www/hosts/%0/cgi-bin +
    + +

    ÀÌ ¼³Á¤¿¡¼­ UseCanonicalName Off¸¦ + UseCanonicalName DNS·Î º¯°æÇϱ⸸ Çϸé IP±â¹Ý + °¡»óÈ£½ºÆ®°¡ µÈ´Ù. °¡»óÈ£½ºÆ®ÀÇ IP ÁÖ¼Ò¸¦ °¡Áö°í + ÆÄÀÏ¸í¿¡ Ãß°¡ÇÒ ¼­¹ö¸íÀ» ¾Ë ¼ö ÀÖ´Ù.

    + +
    + +
    °¡»óÀ¸·Î È£½ºÆ®Çϴ ȨÆäÀÌÁö ½Ã½ºÅÛ + +

    ISP ȨÆäÀÌÁö ¼­¹ö¸¦ À§ÇØ À§ÀÇ ¼³Á¤À» ¼öÁ¤Çß´Ù. Á¶±Ý ´õ + º¹ÀâÇÑ ¼³Á¤À» »ç¿ëÇϸé www.user.isp.comÀÇ ¹®¼­¸¦ + /home/user/¿¡ µÎ´Â ½ÄÀ¸·Î ¼­¹ö¸íÀÇ ÀϺθ¦ °¡Áö°í + ÆÄÀϸíÀ» ¸¸µé ¼ö ÀÖ´Ù. ÀÌ ¼³Á¤Àº + cgi-binÀ» °¢ °¡»óÈ£½ºÆ®°¡ µû·Î °¡ÁöÁö¾Ê°í + ¸ðµç °¡»óÈ£½ºÆ®°¡ °°ÀÌ »ç¿ëÇÑ´Ù.

    + + +# ±âº»ÀûÀÎ ³»¿ëÀº À§¿Í °°´Ù. ±×¸®°í
    +
    +# ÆÄÀÏ¸í¿¡ ¼­¹ö¸íÀÇ ÀϺθ¦ Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRoot /www/hosts/%2/docs
    +
    +# ÇϳªÀÇ cgi-bin µð·ºÅ丮
    +ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    + +

    mod_vhost_alias ¹®¼­¿¡´Â ´õ º¹ÀâÇÑ + VirtualDocumentRoot ¼³Á¤ÀÇ ¿¹°¡ ÀÖ´Ù.

    + +
    + +
    ÇÑ ¼­¹ö¿¡ ¿©·¯ °¡»óÈ£½ºÆ® + ½Ã½ºÅÛ »ç¿ëÇϱâ + +

    ´õ º¹ÀâÇÑ ¼³Á¤ÀÇ ¿¹·Î ¾ÆÆÄÄ¡ÀÇ ÀϹÝÀûÀÎ + <VirtualHost> Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© ¿©·¯ + °¡»óÈ£½ºÆ® ¼³Á¤ÀÇ ¹üÀ§¸¦ Á¶ÀýÇÒ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ´ÙÀ½°ú + °°Àº ¼³Á¤Àº ȨÆäÀÌÁö °í°´¿¡ IP ÁÖ¼Ò ÇÑ°³, »ó¾÷ÀûÀÎ + °í°´¿¡°Ô ´Ù¸¥ IP ÁÖ¼Ò ÇÑ°³¸¦ ºÎ¿©ÇÑ´Ù. ¹°·Ð ÀÌÀüó·³ + <VirtualHost> ¼³Á¤ ¼½¼Ç¿¡ ¸ðµÎ ¹­À» ¼öµµ + ÀÖ´Ù.

    + + +UseCanonicalName Off
    +
    +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    +
    +<Directory /www/commercial>
    + + Options FollowSymLinks
    + AllowOverride All
    +
    +</Directory>
    +
    +<Directory /www/homepages>
    + + Options FollowSymLinks
    + AllowOverride None
    +
    +</Directory>
    +
    +<VirtualHost 111.22.33.44>
    + + ServerName www.commercial.isp.com
    +
    + CustomLog logs/access_log.commercial vcommon
    +
    + VirtualDocumentRoot /www/commercial/%0/docs
    + VirtualScriptAlias /www/commercial/%0/cgi-bin
    +
    +</VirtualHost>
    +
    +<VirtualHost 111.22.33.45>
    + + ServerName www.homepages.isp.com
    +
    + CustomLog logs/access_log.homepages vcommon
    +
    + VirtualDocumentRoot /www/homepages/%0/docs
    + ScriptAlias /cgi-bin/ /www/std-cgi/
    +
    +</VirtualHost> +
    + +
    + +
    ´õ È¿À²ÀûÀÎ IP±â¹Ý °¡»óÈ£½ºÆ® + +

    ù¹ø° ¿¹¿¡¼­ ³ª´Â ¼³Á¤À» °£´ÜÈ÷ + IP±â¹Ý °¡»óÈ£½ºÆ®·Î ¹Ù²Ü ¼ö ÀÖ´Ù°í ¸»Çß´Ù. ºÒÇàÈ÷µµ + ±×·± ¼³Á¤Àº ¸Å ¿äû¸¶´Ù DNS¸¦ ã¾Æ¾ßÇϹǷΠ¸Å¿ì ºñÈ¿À²ÀûÀÌ´Ù. + À̸§´ë½Å IP ÁÖ¼Ò·Î ÆÄÀϽýºÅÛÀ» ±¸¼ºÇÏ°í °°Àº ¹æ½ÄÀ¸·Î + ·Î±×¸¦ ¼öÁ¤ÇÏ¸é ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Ù. ¾ÆÆÄÄ¡´Â ¼­¹ö¸íÀ» + ´Ù·ê ÇÊ¿ä°¡ ¾ø¾îÁö°í, DNS °Ë»öµµ ÇÏÁö ¾Ê°Ô µÈ´Ù.

    + + +# IP ÁÖ¼Ò¸¦ ¿ªDNS °Ë»öÇÏ¿© ¼­¹ö¸íÀ» ¾Ë¾Æ³½´Ù
    +UseCanonicalName DNS
    +
    +# ·Î±×¸¦ ³ª´­ ¼ö ÀÖµµ·Ï IP ÁÖ¼Ò¸¦ Æ÷ÇÔÇÑ´Ù
    +LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +# ÆÄÀÏ¸í¿¡ IP ÁÖ¼Ò¸¦ Æ÷ÇÔÇÑ´Ù
    +VirtualDocumentRootIP /www/hosts/%0/docs
    +VirtualScriptAliasIP /www/hosts/%0/cgi-bin
    +
    + +
    + +
    ¾ÆÆÄÄ¡ ÀÌÀü ¹öÀü »ç¿ëÇϱâ + +

    À§ ¿¹µéÀº ¾ÆÆÄÄ¡ ¹öÀü 1.3.6 ÀÌÈÄ¿¡ Æ÷ÇÔµÈ + mod_vhost_aliasÀ» »ç¿ëÇÑ´Ù. + mod_vhost_alias°¡ ¾ø´Â ¾ÆÆÄÄ¡ ¹öÀüÀ» »ç¿ëÇÑ´Ù¸é + ÀÌ¹Ì ¸»ÇßµíÀÌ mod_rewrite¸¦ »ç¿ëÇÏ¿©, ´Ü + Host:-Çì´õ±â¹Ý °¡»óÈ£½ºÆ®¸¸À», ±¸ÇöÇÒ ¼ö ÀÖ´Ù.

    + +

    ¶Ç ·Î±×¿¡ °üÇÏ¿© ÁÖÀÇÇÒ Á¡ÀÌ ÀÖ´Ù. ¾ÆÆÄÄ¡ 1.3.6¿¡¼­ + ·Î±×Çü½Ä Áö½Ã¾î %V°¡ Æ÷ÇԵǾú°í, ¹öÀü 1.3.0 + - 1.3.3¿¡¼­ ÀÌ ±â´ÉÀ» %v ¿É¼ÇÀÌ ´ë½Å Çß´Ù. ±×·¯³ª + ¹öÀü 1.3.4¿¡´Â ÀÌ·± ±â´ÉÀÌ ¾ø´Ù. ¾î¶² ¾ÆÆÄÄ¡ ¹öÀü¿¡¼­µµ + .htaccess ÆÄÀÏ¿¡¼­ UseCanonicalName + Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖÀ¸¹Ç·Î ·Î±×¿¡ ÀÌ»óÇÑ ³»¿ëÀÌ ±â·ÏµÉ ¼ö ÀÖ´Ù. + ±×·¯¹Ç·Î °¡Àå ÁÁÀº ¹æ¹ýÀº %{Host}i Áö½Ã¾î¸¦ + »ç¿ëÇÏ¿© Host: Çì´õ¸¦ Á÷Á¢ ·Î±×¿¡ ³²±â´Â °ÍÀÌ´Ù. + ¶Ç, ÀÌ ¹æ¹ýÀº %V´Â Æ÷ÇÔÇÏÁö¾Ê´Â :port¸¦ + µÚ¿¡ Ãß°¡ÇÒ ¼ö ÀÖ´Ù.

    + +
    + +
    <code>mod_rewrite</code>¸¦ + »ç¿ëÇÑ °£´ÜÇÑ µ¿Àû °¡»óÈ£½ºÆ® + +

    ´ÙÀ½Àº ù¹ø° ¿¹¿Í °°Àº ÀÏÀ» ÇÏ´Â + httpd.conf ¿¹ÀÌ´Ù. óÀ½ Àý¹ÝÀº ù¹ø° ¿¹¿Í + °ÅÀÇ ºñ½ÁÇÏÁö¸¸, ÀÌÀü ¹öÀü°úÀÇ È£È¯¼º°ú mod_rewriteÀÇ + ÀûÀýÇÑ µ¿ÀÛÀ» À§ÇØ ¼öÁ¤µÇ¾ú´Ù. ³ª¸ÓÁö Àý¹ÝÀº ½ÇÁ¦ ÀÛ¾÷À» + ÇÏ´Â mod_rewrite¸¦ ¼³Á¤ÇÑ´Ù.

    + +

    Ưº°È÷ ÁÖÀÇÇØ¾ß ÇÒ »çÇ×ÀÌ ÀÖ´Ù. ±âº»ÀûÀ¸·Î + mod_rewrite´Â (mod_alias µî) ´Ù¸¥ + URI ¹ø¿ª ¸ðµâ ÀÌÀü¿¡ ½ÇÇàµÈ´Ù. ±×·¡¼­ ´Ù¸¥ URI ¹ø¿ª ¸ðµâµé°ú + °°ÀÌ µ¿ÀÛÇÒ °ÍÀ» °í·ÁÇÏ¿© mod_rewrite¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. + ¶Ç, µ¿Àû °¡»óÈ£½ºÆ®¿¡¼­ ScriptAlias°ú °°Àº + ±â´ÉÀ» À§Çؼ­´Â Ưº°ÇÑ ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù.

    + + +# Host: Çì´õ¿¡¼­ ¼­¹ö¸íÀ» ¾ò´Â´Ù
    +UseCanonicalName Off
    +
    +# splittable logs
    +LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
    +CustomLog logs/access_log vcommon
    +
    +<Directory /www/hosts>
    + + # ScriptAlias ½ÄÀ¸·Î CGI ½ÇÇàÀ» °­Á¦ÇÒ ¼ö ¾ø±â¶§¹®¿¡
    + # ¿©±â¿¡ ExecCGI¸¦ »ç¿ëÇÑ´Ù
    + Options FollowSymLinks ExecCGI
    +
    +</Directory>
    +
    +# ÀÌÁ¦ ¾î·Á¿î ºÎºÐÀÌ´Ù
    +
    +RewriteEngine On
    +
    +# Host: Çì´õ¿¡¼­ °¡Á®¿Â ¼­¹ö¸í¿¡´Â ´ë¼Ò¹®ÀÚ°¡ µÚ¼¯¿©ÀÖÀ» ¼ö ÀÖ´Ù
    +RewriteMap lowercase int:tolower
    +
    +## ÀÏ¹Ý ¹®¼­¸¦ ¸ÕÀú ó¸®ÇÑ´Ù:
    +# Alias /icons/ °¡ µ¿ÀÛÇϵµ·Ï - ´Ù¸¥ alias¿¡ ´ëÇؼ­µµ ¹Ýº¹
    +RewriteCond %{REQUEST_URI} !^/icons/
    +# CGI°¡ µ¿ÀÛÇϵµ·Ï
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +# Ưº°ÇÑ ÀÛ¾÷
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
    +
    +## ÀÌÁ¦ CGI¸¦ ó¸®ÇÑ´Ù - MIME typeÀ» °­Á¦ÇØ¾ß ÇÑ´Ù
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
    +
    +# ³¡! +
    + +
    + +
    <code>mod_rewrite</code>¸¦ + »ç¿ëÇÑ È¨ÆäÀÌÁö ½Ã½ºÅÛ + +

    ´ÙÀ½Àº µÎ¹ø° ¿¹¿Í °°Àº ÀÏÀ» + ÇÑ´Ù.

    + + +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# CGI°¡ µ¿ÀÛÇϵµ·Ï
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +
    +# RewriteRuleÀÌ µ¿ÀÛÇϵµ·Ï È£½ºÆ®¸íÀÌ ¿Ã¹Ù¸¥Áö °Ë»çÇÑ´Ù
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^www\.[a-z-]+\.isp\.com$
    +
    +# °¡»óÈ£½ºÆ®¸íÀ» URI ¾Õ¿¡ ºÙÀδÙ
    +# [C]´Â ÀÌ °á°ú¸¦ °¡Áö°í ´ÙÀ½ ÀçÀÛ¼ºÀ» ¼öÇàÇÔÀ» ¶æÇÑ´Ù
    +RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
    +
    +# ÀÌÁ¦ ½ÇÁ¦ ÆÄÀϸíÀ» ¸¸µç´Ù
    +RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
    +
    +# Àüü CGI µð·ºÅ丮¸¦ Á¤ÀÇÇÑ´Ù
    +ScriptAlias /cgi-bin/ /www/std-cgi/ +
    + +
    + +
    º°µµÀÇ °¡»óÈ£½ºÆ® ¼³Á¤ÆÄÀÏ + »ç¿ëÇϱâ + +

    ´ÙÀ½Àº mod_rewriteÀÇ °í±Þ ±â´ÉÀ» »ç¿ëÇÏ¿© + º°µµÀÇ ¼³Á¤ÆÄÀÏÀ» °¡Áö°í °¡»óÈ£½ºÆ®ÀÇ ¹®¼­·çÆ®¸¦ ¾Ë¾Æ³½´Ù. + ´õ À¯¿¬ÇÏÁö¸¸ ´õ º¹ÀâÇÑ ¼³Á¤ÀÌ ÇÊ¿äÇÏ´Ù.

    + +

    vhost.map ÆÄÀÏÀº ´ÙÀ½°ú °°´Ù:

    + + +www.customer-1.com /www/customers/1
    +www.customer-2.com /www/customers/2
    +# ...
    +www.customer-N.com /www/customers/N
    +
    + +

    http.conf´Â ´ÙÀ½°ú °°´Ù:

    + + +RewriteEngine on
    +
    +RewriteMap lowercase int:tolower
    +
    +# ´ëÀÀÆÄÀÏÀ» Á¤ÀÇÇÑ´Ù
    +RewriteMap vhost txt:/www/conf/vhost.map
    +
    +# À§¿Í °°ÀÌ aliasµéÀ» ó¸®ÇÑ´Ù
    +RewriteCond %{REQUEST_URI} !^/icons/
    +RewriteCond %{REQUEST_URI} !^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +# ÆÄÀÏ ³»¿ëÀ» °¡Áö°í ã´Â´Ù
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/docs/$1
    +
    +RewriteCond %{REQUEST_URI} ^/cgi-bin/
    +RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
    +RewriteCond ${vhost:%1} ^(/.*)$
    +RewriteRule ^/(.*)$ %1/cgi-bin/$1 +
    + +
    +
    diff --git a/trunk/docs/manual/vhosts/mass.xml.meta b/trunk/docs/manual/vhosts/mass.xml.meta new file mode 100644 index 0000000000..3706942cd0 --- /dev/null +++ b/trunk/docs/manual/vhosts/mass.xml.meta @@ -0,0 +1,12 @@ + + + + mass + /vhosts/ + .. + + + en + ko + + diff --git a/trunk/docs/manual/vhosts/name-based.html b/trunk/docs/manual/vhosts/name-based.html new file mode 100644 index 0000000000..3f1e91843f --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.html @@ -0,0 +1,15 @@ +URI: name-based.html.de +Content-Language: de +Content-type: text/html; charset=ISO-8859-1 + +URI: name-based.html.en +Content-Language: en +Content-type: text/html; charset=ISO-8859-1 + +URI: name-based.html.ja.euc-jp +Content-Language: ja +Content-type: text/html; charset=EUC-JP + +URI: name-based.html.ko.euc-kr +Content-Language: ko +Content-type: text/html; charset=EUC-KR diff --git a/trunk/docs/manual/vhosts/name-based.html.de b/trunk/docs/manual/vhosts/name-based.html.de new file mode 100644 index 0000000000..282405efe0 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.html.de @@ -0,0 +1,266 @@ + + + +Unterstützung namensbasierter virtueller Hosts - Apache HTTP Server + + + + + +
    <-
    +

    Unterstützung namensbasierter virtueller Hosts

    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + +

    Das Dokument beschreibt, wann und wie namensbasierte virtuelle Hosts zu + verwenden sind.

    +
    + +
    top
    +
    +

    Namensbasierte gegenüber IP-basierten + virtuellen Hosts

    + +

    IP-basierte virtuelle Hosts verwenden die IP-Adresse der Verbindung, um den + korrekten virtuellen Host zur Bedienung einer Anfrage zu ermitteln. Folglich + benötigen Sie eine IP-Adresse für jeden virtuellen Host. Bei der + Verwendung von namensbasierten virtuellen Hosts verläßt sich der + Server darauf, dass der Client den Hostnamen als Bestandteil der HTTP-Header + angibt. Durch Anwendung dieser Technik können sich mehrere verschiedene + Hosts die gleiche IP-Adresse teilen.

    + +

    Die Verwendung von namensbasierten virtuellen Hosts ist gewöhnlich + einfacher. Sie müssen lediglich Ihren DNS-Server darauf einstellen, + jeden Hostnamen auf die richtige IP-Adresse abzubilden, und dann den Apache + HTTP Server so konfigurieren, dass er die verschiedenen Hostnamen erkennt. + Namensbasierte virtuelle Hosts entschärfen auch den Bedarf an + knappen IP-Adressen. Daher sollten Sie namensbasierte virtuelle Hosts + verwenden, sofern kein besonderer Grund dafür existiert, IP-basierte + virtuelle Hosts zu wählen. Mögliche Gründe für die + Verwendung IP-basierter virtueller Hosts sind:

    + +
      +
    • Einige antike Clients sind nicht kompatibel zu namensbasierten + virtuellen Hosts. Damit namensbasierte virtuelle Hosts funktionieren, + muss der Client den HTTP-Host-Header senden. Dies ist bei HTTP/1.1 + vorgeschrieben und in allen modernen HTTP/1.0-Browsern als Erweiterung + implementiert. Wenn Sie Unterstützung für veraltete Clients + benötigen und dennoch namensbasierte virtuelle Hosts verwenden, + dann finden Sie eine mögliche Lösung dafür am Ende des + Dokuments.
    • + +
    • Namensbasierte virtuelle Hosts können aufgrund der Natur des + SSL-Protokolls nicht mit SSL-gesicherten Servern verwendet werden.
    • + +
    • Einige Betriebssysteme und Netzwerkanlagen setzen Techniken zum + Bandbreiten-Management ein, die nicht zwischen Hosts unterscheiden + können, wenn diese nicht auf verschiedenen IP-Adressen liegen.
    • +
    + +
    top
    +
    +

    Die Verwendung von namensbasierten virtuellen Hosts

    + + + +

    Um namensbasierte virtuelle Hosts zu verwenden, müssen Sie die + IP-Adresse (und möglicherweise den Port) des Servers benennen, an + der Anfragen für die Hosts entgegengenommen werden. Dies wird mit + der Direktive NameVirtualHost + eingestellt. Im Normalfall, wenn alle IP-Adressen des Server verwendet + werden sollen, können Sie * als Argument für + NameVirtualHost verwenden. Wenn Sie + vorhaben, mehrere Ports zu nutzen (etwa wenn SSL läuft), sollten + Sie dem Argument einen Port hinzufügen, wie zum Beispiel + *:80. Beachten Sie, + dass die Angabe einer IP-Adresse in einer NameVirtualHost-Anweisung den Server nicht + automatisch an dieser Adresse lauschen läßt. Lesen Sie bitte "Bestimmen der vom Apache verwendeten Adressen und + Ports" für weitere Details. Zusätzlich muss jede hier + angegebene IP-Adresse einer Netzwerkkarte des Servers zugeordnet sein.

    + +

    Der nächste Schritt ist die Erstellung eines <VirtualHost>-Blocks für jeden einzelnen + Host, den Sie bedienen wollen. Das Argument der Direktive <VirtualHost> sollte das gleiche + sein wie das Argument der NameVirtualHost-Anweisung (d.h. eine IP-Adresse + oder * für alle Adressen). Innerhalb jedes <VirtualHost>-Blocks benötigen + Sie zumindestens eine ServerName-Anweisung, um zu bestimmen, welcher + Host bedient wird, und eine DocumentRoot-Anweisung, um anzugeben, wo im + Dateisystem der Inhalt des Hosts abgelegt ist.

    + +

    Der Hauptserver verschwindet

    + Wenn Sie virtuelle Hosts zu einem bestehenden Webserver hinzufügen, + müssen Sie auch einen <VirtualHost>-Block für den bestehenden Host + (Anm.d.Ü.: und bisherigen Hauptserver) erstellen. + Die ServerName- und + DocumentRoot-Anweisungen zu diesem + virtuellen Host sollten die gleichen sein wie die globalen ServerName- und DocumentRoot-Anweisungen. Führen Sie diesen + virtuellen Host als erstes in der Konfigurationsdatei auf, so dass er als + Standard-Host fungiert. +
    + +

    Vorausgesetzt, Sie bedienen z.B. die Domain + www.domain.tld und möchten den virtuellen Host + www.otherdomain.tld hinzufügen, welcher auf + die gleiche IP-Adresse zeigt. Dann fügen Sie einfach Folgendes der + httpd.conf hinzu:

    + +

    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +

    + +

    Sie können anstelle des * bei den beiden Anweisungen + NameVirtualHost und <VirtualHost> alternativ eine + eindeutige IP-Adresse angeben. Das kann man beispielsweise machen, um + einige namensbasierte virtuelle Hosts auf einer IP-Adresse zu betreiben und + entweder IP-basierte oder ein anderes Set von namensbasierten virtuellen + Hosts auf einer anderen Adresse.

    + +

    Viele Server wollen unter mehr als einem Namen erreichbar sein. Die + Direktive ServerAlias, die innerhalb + des <VirtualHost>-Abschnittes angegeben wird, + ermöglicht dies. Zum Beispiel zeigt die ServerAlias-Anweisung in dem ersten <VirtualHost>-Block oben an, dass die + aufgeführten Namen alternative Namen sind, die man verwenden kann, um + das gleiche Webangebot zu erreichen:

    + +

    + ServerAlias domain.tld *.domain.tld +

    + +

    Anfragen für alle Hosts der Domain domain.tld werden + von dem virtuellen Host www.domain.tld bedient. Die + Platzhalter * und ? können anstelle + entsprechender Namen verwendet werden. Natürlich können Sie nicht + einfach Namen erfinden und diese bei ServerName oder ServerAlias + angeben, Sie müssen zunächst Ihren DNS Server entsprechend + konfigurieren, dass er diese Namen auf die mit Ihrem Server verknüpfte + IP-Adresse abbildet.

    + +

    Und schlußendlich können Sie die Konfiguration der virtuellen + Hosts mittels Angabe weiterer Direktiven innherhalb der <VirtualHost>-Container + feineinstellen. Die meisten Direktiven können in diesen Containern + angegeben werden und verändern dann ausschließlich die + Konfiguration des entsprechenden virtuellen Hosts. Prüfen Sie den Kontext einer Direktive, um + herauszufinden, ob eine bestimmte Direktive zulässig ist. + Im Hauptserver-Kontext (außerhalb der <VirtualHost>-Container) definierte + Konfigurationsanweisungen werden nur dann angewendet, wenn sie nicht durch + Einstellungen des virtuellen Hosts außer Kraft gesetzt wurden.

    + +

    Wenn nun eine Anfrage eintrifft, prüft der Server zuerst, ob sie eine + IP-Adresse verwendet, die der NameVirtualHost-Anweisung entspricht. Ist dies der + Fall, dann sieht er sich jeden <VirtualHost>-Abschnitt mit einer passenden + IP-Adresse an und versucht den einen zu finden, dessen ServerName- oder ServerAlias-Anweisung mit dem gewünschten + Hostnamen übereinstimmt. Findet er einen, dann verwendet er die + Konfiguration dieses Servers. Wird kein passender virtueller Host gefunden, + dann wird der erste angegeben virtuelle Host verwendet, + dessen IP-Adresse paßt.

    + +

    Die Folge davon ist, dass der erste aufgeführte virtuelle Host der + Standard-Virtual-Host ist. Die DocumentRoot-Anweisung des Hauptservers + wird niemals verwendet, wenn eine IP-Adresse mit einer + NameVirtualHost-Anweisung + übereinstimmt. Wenn Sie eine spezielle Konfiguration für Anfragen + angeben möchten, die keinem bestimmten virtuellen Host entsprechen, + packen Sie diese Konfiguration einfach in einen <VirtualHost>-Container und führen diesen als + erstes in der Konfigurationsdatei auf.

    + +
    top
    +
    +

    Kompatibilität mit älteren Browsern

    + +

    Wie zuvor erwähnt gibt es einige Clients, die nicht die notwendigen + Daten senden, mit denen namensbasierte virtuelle Hosts korrekt + funktionieren. Diesen Clients werden stets die Seiten des ersten, für + diese IP-Adresse aufgeführten virtuellen Hosts gesendet werden (des + primären namensbasierten virtuellen Hosts).

    + +

    Was bedeutet älter?

    +

    Beachten Sie bitte, wenn wir von älter sprechen, meinen wir auch + älter. Es ist sehr unwahrscheinlich, dass sie einen dieser Browser + heutzutage in Verwendung finden werden. Alle aktuellen Browser-Versionen + senden den Host-Header, so wie er für namensbasierte + virtuelle Hosts benäötigt wird.

    +
    + +

    Mit der Direktive ServerPath existiert + eine mögliche Behelfskonstruktion, obgleich sie etwas schwerfällig + ist:

    + +

    Beispielkonfiguration:

    + +

    + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +

    + +

    Was bedeutet das? Es bedeutet, dass eine Anfrage für eine mit + "/domain" beginnende URI von dem virtuellen Host + www.domain.tld bedient wird. Dies heißt, dass die Seiten + für alle Clients unter http://www.domain.tld/domain/ + abrufbar sind, wenngleich Clients, die den Header Host: + senden, auch über http://www.domain.tld/ auf sie zugreifen + können.

    + +

    Legen Sie einen Link auf der Seite Ihres primären virtuellen Hosts zu + http://www.domain.tld/domain/, um die Behelfslösung + verfügbar zu machen. Bei den Seiten der virtuellen Hosts müssen + Sie dann sicherstellen, entweder außschließlich relative Links + (z.B. "file.html" oder + "../icons/image.gif") zu verwenden oder Links, die das + einleitende /domain/ enthalten (z.B., + "http://www.domain.tld/domain/misc/file.html" oder + "/domain/misc/file.html").

    + +

    Dies erfordert etwas Disziplin, die Befolgung dieser Richtlinien stellt + jedoch größtenteils sicher, dass Ihre Seiten mit allen Browsern + funktionieren, alten wie neuen.

    + +
    +
    +

    Verfügbare Sprachen:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/name-based.html.en b/trunk/docs/manual/vhosts/name-based.html.en new file mode 100644 index 0000000000..b07f8aaade --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.html.en @@ -0,0 +1,244 @@ + + + +Name-based Virtual Host Support - Apache HTTP Server + + + + + +
    <-
    +

    Name-based Virtual Host Support

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + +

    This document describes when and how to use name-based virtual hosts.

    +
    + +
    top
    +
    +

    Name-based vs. IP-based Virtual Hosts

    + +

    IP-based virtual hosts use the IP address of the connection to + determine the correct virtual host to serve. Therefore you need to + have a separate IP address for each host. With name-based virtual + hosting, the server relies on the client to report the hostname as + part of the HTTP headers. Using this technique, many different hosts + can share the same IP address.

    + +

    Name-based virtual hosting is usually simpler, since you need + only configure your DNS server to map each hostname to the correct + IP address and then configure the Apache HTTP Server to recognize + the different hostnames. Name-based virtual hosting also eases + the demand for scarce IP addresses. Therefore you should use + name-based virtual hosting unless there is a specific reason to + choose IP-based virtual hosting. Some reasons why you might consider + using IP-based virtual hosting:

    + +
      +
    • Some ancient clients are not compatible with name-based virtual + hosting. For name-based virtual hosting to work, the client must send + the HTTP Host header. This is required by HTTP/1.1, and is + implemented by all modern HTTP/1.0 browsers as an extension. If you + need to support obsolete clients and still use name-based virtual + hosting, a possible technique is discussed at the end of this + document.
    • + +
    • Name-based virtual hosting cannot be used with SSL secure servers + because of the nature of the SSL protocol.
    • + +
    • Some operating systems and network equipment implement bandwidth + management techniques that cannot differentiate between hosts unless + they are on separate IP addresses.
    • +
    + +
    top
    +
    +

    Using Name-based Virtual Hosts

    + + + +

    To use name-based virtual hosting, you must designate the IP + address (and possibly port) on the server that will be accepting + requests for the hosts. This is configured using the NameVirtualHost directive. + In the normal case where any and all IP addresses on the server should + be used, you can use * as the argument to NameVirtualHost. If you're planning to use + multiple ports (e.g. running SSL) you should add a Port to the argument, + such as *:80. Note that mentioning an IP address in a + NameVirtualHost directive does not + automatically make the server listen to that IP address. See + Setting which addresses and ports Apache uses + for more details. In addition, any IP address specified here must be + associated with a network interface on the server.

    + +

    The next step is to create a <VirtualHost> block for + each different host that you would like to serve. The argument to the + <VirtualHost> directive + should be the same as the argument to the NameVirtualHost directive (ie, an IP address, + or * for all addresses). Inside each <VirtualHost> block, you will need at minimum a + ServerName directive to designate + which host is served and a DocumentRoot + directive to show where in the filesystem the content for that host + lives.

    + +

    Main host goes away

    +

    If you are adding virtual hosts to an existing web server, you + must also create a <VirtualHost> block for the existing host. The ServerName and DocumentRoot included in this virtual host should be the + same as the global ServerName and + DocumentRoot. List this virtual + host first in the configuration file so that it will act as the default + host.

    +
    + +

    For example, suppose that you are serving the domain + www.domain.tld and you wish to add the virtual host + www.otherdomain.tld, which points at the same IP address. + Then you simply add the following to httpd.conf:

    + +

    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +

    + +

    You can alternatively specify an explicit IP address in place of the + * in both the NameVirtualHost and <VirtualHost> directives. For example, you might want to do this + in order to run some name-based virtual hosts on one IP address, and either + IP-based, or another set of name-based virtual hosts on another address.

    + +

    Many servers want to be accessible by more than one name. This is + possible with the ServerAlias + directive, placed inside the <VirtualHost> section. For example in the first <VirtualHost> block above, the + ServerAlias directive indicates that + the listed names are other names which people can use to see that same + web site:

    + +

    + ServerAlias domain.tld *.domain.tld +

    + +

    then requests for all hosts in the domain.tld domain will + be served by the www.domain.tld virtual host. The wildcard + characters * and ? can be used to match names. + Of course, you can't just make up names and place them in ServerName or ServerAlias. You must + first have your DNS server properly configured to map those names to an IP + address associated with your server.

    + +

    Finally, you can fine-tune the configuration of the virtual hosts + by placing other directives inside the <VirtualHost> containers. Most directives can be + placed in these containers and will then change the configuration only of + the relevant virtual host. To find out if a particular directive is allowed, + check the Context of the + directive. Configuration directives set in the main server context + (outside any <VirtualHost> + container) will be used only if they are not overridden by the virtual host + settings.

    + +

    Now when a request arrives, the server will first check if it is using + an IP address that matches the NameVirtualHost. If it is, then it will look at each <VirtualHost> section with a matching + IP address and try to find one where the ServerName or ServerAlias matches the requested + hostname. If it finds one, then it uses the configuration for that server. + If no matching virtual host is found, then the first listed virtual + host that matches the IP address will be used.

    + +

    As a consequence, the first listed virtual host is the default + virtual host. The DocumentRoot from + the main server will never be used when an IP + address matches the NameVirtualHost + directive. If you would like to have a special configuration for requests + that do not match any particular virtual host, simply put that configuration + in a <VirtualHost> + container and list it first in the configuration file.

    + +
    top
    +
    +

    Compatibility with Older Browsers

    + +

    As mentioned earlier, there are some clients + 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 first virtual host listed for that IP address + (the primary name-based virtual host).

    + +

    How much older?

    +

    Please note that when we say older, we really do mean older. You are + very unlikely to encounter one of these browsers in use today. All + current versions of any browser send the Host header as + required for name-based virtual hosts.

    +
    + +

    There is a possible workaround with the ServerPath + directive, albeit a slightly cumbersome one:

    + +

    Example configuration:

    + +

    + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +

    + +

    What does this mean? It means that a request for any URI + beginning with "/domain" will be served from the + virtual host www.domain.tld. This means that the + pages can be accessed as http://www.domain.tld/domain/ + for all clients, although clients sending a Host: header + can also access it as http://www.domain.tld/.

    + +

    In order to make this work, put a link on your primary + virtual host's page to + http://www.domain.tld/domain/. Then, in the virtual + host's pages, be sure to use either purely relative links + (e.g., "file.html" or + "../icons/image.gif") or links containing the + prefacing /domain/ (e.g., + "http://www.domain.tld/domain/misc/file.html" or + "/domain/misc/file.html").

    + +

    This requires a bit of discipline, but adherence to these + guidelines will, for the most part, ensure that your pages will + work with all browsers, new and old.

    + +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/name-based.html.ja.euc-jp b/trunk/docs/manual/vhosts/name-based.html.ja.euc-jp new file mode 100644 index 0000000000..3d63ce17f7 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.html.ja.euc-jp @@ -0,0 +1,269 @@ + + + +̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È - Apache HTTP ¥µ¡¼¥Ð + + + + + +
    <-
    +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È

    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + +

    ¤³¤Îʸ½ñ¤Ç¤Ï̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò¤É¤ó¤Ê¤È¤­¡¢ + ¤É¤¦¤ä¤Ã¤Æ»È¤¦¤«¤òÀâÌÀ¤·¤Þ¤¹¡£

    +
    + +
    top
    +
    +

    ̾Á°¥Ù¡¼¥¹¤È IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÈæ³Ó

    + +

    IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¤Ï¡¢±þÅú¤¹¤ë + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò·èÄꤹ¤ë¤¿¤á¤Ë IP + ¥¢¥É¥ì¥¹¤ò»ÈÍѤ·¤Þ¤¹¡£¤Ç¤¹¤«¤é¡¢¤½¤ì¤¾¤ì¤Î¥Û¥¹¥È¤Ë¸Ä¡¹¤Ë IP + ¥¢¥É¥ì¥¹¤¬É¬Íפˤʤê¤Þ¤¹¡£¤³¤ì¤ËÂФ·¤Æ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¤Ï¡¢ + ¥¯¥é¥¤¥¢¥ó¥È¤¬ HTTP ¥Ø¥Ã¥À¤Î°ìÉô¤È¤·¤Æ¥Û¥¹¥È̾¤ò¹ð¤²¤ë¡¢ + ¤È¤¤¤¦¤³¤È¤Ë°Í¸¤·¤Þ¤¹¡£¤³¤Îµ»½Ñ¤ÇƱ°ì IP + ¥¢¥É¥ì¥¹¤ò°Û¤Ê¤ë¿¿ô¤Î¥Û¥¹¥È¤Ç¶¦Í­¤·¤Æ¤¤¤Þ¤¹¡£

    + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÏÄ̾ïñ½ã¤Ç¡¢¤½¤ì¤¾¤ì¤Î¥Û¥¹¥È̾¤È + ¤½¤ì¤ËÂбþ¤¹¤ëÀµ³Î¤Ê IP ¥¢¥É¥ì¥¹¤ò DNS ¤ÇÀßÄꤷ¡¢°Û¤Ê¤ë + ¥Û¥¹¥È̾¤ò¶èÊ̤¹¤ë¤è¤¦¤Ë Apache HTTP ¥µ¡¼¥Ð¤òÀßÄꤹ¤ë¤À¤±¤Ç¤¹¡£ + ¤µ¤é¤Ë¡¢Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÏÉÔ­¤¹¤ë IP + ¥¢¥É¥ì¥¹¤Î¼ûÍפò´ËϤ·¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ¡¢IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò + ÁªÂò¤¹¤Ù¤­ÆÃÄê¤ÎÍýͳ¤¬¤Ê¤±¤ì¤Ð̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤¦¤Ù¤­¤Ç¤¹¡£ + IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò¹Íθ¤¹¤ëÍýͳ¤È¤·¤Æ¡¢

    + +
      +
    • ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂбþ¤·¤Æ¤¤¤Ê¤¤¸Å¤¤¥¯¥é¥¤¥¢¥ó¥È¤¬¤¢¤ë + ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬Æ¯¤¯¤¿¤á¤Ë¤Ï¡¢¥¯¥é¥¤¥¢¥ó¥È¤Ï + HTTP ¥Û¥¹¥È¥Ø¥Ã¥À¤òÁ÷¤Ã¤Æ¤³¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ + ¤³¤ì¤Ï HTTP/1.1 ¤Î»ÅÍͤÇÍ׵ᤵ¤ì¤Æ¤¤¤Æ¡¢¤¹¤Ù¤Æ¤Î¸½ÂåŪ¤Ê + HTTP/1.0 ¥Ö¥é¥¦¥¶¤Ç¤â³ÈÄ¥¤È¤·¤Æ¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤È¤Æ¤â¸Å¤¤¥¯¥é¥¤¥¢¥ó¥È¤ò¥µ¥Ý¡¼¥È¤·¤Ä¤Ä¡¢Ì¾Á°¥Ù¡¼¥¹¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò¹Ô¤¤¤¿¤¤¾ì¹ç¤Ï¡¢¤³¤Îʸ½ñ¤ÎºÇ¸å¤ÎÊý¤Ë + ½ñ¤«¤ì¤Æ¤¤¤ë²ò·èºö¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Ê¤¤ÊýË¡¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
    • + +
    • ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ï SSL ¥×¥í¥È¥³¥ë¤ÎÆÃħ¤Ë¤è¤ê¡¢ + SSL ¥»¥­¥å¥¢¥µ¡¼¥Ð¤Ë¤Ï»È¤¨¤Þ¤»¤ó¡£
    • + +
    • ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ä¥Í¥Ã¥È¥ï¡¼¥¯ÁõÃ֤Τʤ«¤Ë¤Ï¡¢ + Ê̤ΠIP ¥¢¥É¥ì¥¹¾å¤Ç¤Ê¤¤¾ì¹ç¡¢Ê£¿ô¤Î¥Û¥¹¥È¤òÊÌ°·¤¤¤Ç¤­¤Ê¤¤¤è¤¦¤Ê + ÂÓ°è´ÉÍý¤ÎÊýË¡¤ò¼ÂÁõ¤·¤Æ¤¤¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£
    • +
    + +
    top
    +
    +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÍøÍѤ¹¤ë

    + + + +

    ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤¦¤Ë¤Ï¡¢¤½¤Î¥Û¥¹¥È¤Ø¤Î + ¥ê¥¯¥¨¥¹¥È¤ò¼õ¤±ÉÕ¤±¤ë¥µ¡¼¥Ð¤Î IP ¥¢¥É¥ì¥¹ (¤â¤·¤«¤·¤¿¤é¥Ý¡¼¥È¤â) + ¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ + ¤³¤ì¤Ï NameVirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÀßÄꤷ¤Þ¤¹¡£Ä̾NameVirtualHost ¤Ç + * ¤Î°À­¤ò»È¤Ã¤Æ¥µ¡¼¥Ð¤ÎÁ´¤Æ¤Î IP ¥¢¥É¥ì¥¹¤ò»È¤¤¤Þ¤¹¡£ + (Î㤨¤Ð SSL ¤Î»ÈÍѤʤɤÇ) Ê£¿ô¤Î¥Ý¡¼¥È¤ò»È¤¦¤³¤È¤ò·×²è¤·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢ + °ú¿ô¤Ë *:80 ¤Î¤è¤¦¤Ë¥Ý¡¼¥È¤â´Þ¤á¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£ + NameVirtualHost ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç + IP ¥¢¥É¥ì¥¹¤ò½ñ¤¤¤Æ¤â¡¢ + ¼«Æ°Åª¤Ë¥µ¡¼¥Ð¤¬¤½¤Î IP ¥¢¥É¥ì¥¹¤ò¥ê¥Ã¥¹¥ó¤¹¤ë¤È¤¤¤¦¤³¤È¤Ï¤Ê¤¤¤³¤È¤Ë + Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¾ÜºÙ¤Ï¡ÖApache ¤Î»È¤¦¥¢¥É¥ì¥¹¤È + ¥Ý¡¼¥È¤òÀßÄꤹ¤ë¡×¤òÆɤó¤Ç¤¯¤À¤µ¤¤¡£¤µ¤é¤Ë¡¢¤³¤³¤Ç»ØÄꤵ¤ì¤¿ + IP ¥¢¥É¥ì¥¹¤ÏÁ´¤Æ¥µ¡¼¥Ð¤Î¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ + ¤¤¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ¼¡¤Ï¡¢°·¤¦¥Û¥¹¥È¤½¤ì¤¾¤ì¤ËÂФ·¤Æ <VirtualHost> ¥Ö¥í¥Ã¥¯¤ò + ºîÀ®¤·¤Æ¤¯¤À¤µ¤¤¡£<VirtualHost> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤Ï NameVirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î°ú¿ô¤ÈƱ¤¸¤Ë¤·¤Æ¤¯¤À¤µ¤¤ (¤¹¤Ê¤ï¤Á¡¢IP ¥¢¥É¥ì¥¹¤«¡¢Á´¤Æ¤Î¥¢¥É¥ì¥¹¤ò°ÕÌ£¤¹¤ë + *)¡£¤½¤ì¤¾¤ì¤Î <VirtualHost> + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÎÃæ¤Ë¤Ï¡¢ºÇÄã¸Â¡¢¤É¤Î¥Û¥¹¥È¤¬°·¤ï¤ì¤ë¤«¤ò¼¨¤¹ ServerName ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤È¡¢ + ¤½¤Î¥Û¥¹¥ÈÍѤΥ³¥ó¥Æ¥ó¥Ä¤¬¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¾å¤Î¤É¤³¤Ë¤¢¤ë¤«¤ò¼¨¤¹ + DocumentRoot ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò + ½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

    + +

    ¥á¥¤¥ó¥Û¥¹¥È¤Ï¤Ê¤¯¤Ê¤ê¤Þ¤¹

    +

    ´û¤Ë¤¢¤ë¥¦¥§¥Ö¥µ¡¼¥Ð¤Ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÄɲ乤ë¾ì¹ç¡¢ + ´û¸¤Î¥¦¥§¥Ö¥µ¡¼¥Ð¤ËÂФ·¤Æ¤â <VirtualHost> + ¥Ö¥í¥Ã¥¯¤òºî¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î + ServerName ¤È + DocumentRoot + ¤Ï¡¢¥°¥í¡¼¥Ð¥ë¤Ê ServerName ¤È + DocumentRoot + ¤ÈƱ¤¸¤â¤Î¤Ë¤·¤Þ¤¹¡£¤Þ¤¿¡¢¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤òÀßÄê¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ç + ÀèƬ¤ËÃÖ¤¤¤Æ¡¢¥Ç¥Õ¥©¥ë¥È¥Û¥¹¥È¤È¤·¤ÆÆ°ºî¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£

    +
    + +

    ¤¿¤È¤¨¤Ð¡¢www.domain.tld ¤òÆ°¤«¤·¤Æ¤¤¤Æ¡¢ + ¤µ¤é¤Ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È www.otherdomain.tld + ¤òÄɲ乤ë¤È¤·¤Þ¤·¤ç¤¦¡£¤³¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÏƱ°ì IP ¤ò»Ø¤·¤Æ¤¤¤ë¤È¤·¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ï¡¢httpd.conf + ¤Ë°Ê²¼¤Î¤è¤¦¤Ê¥³¡¼¥É¤òÄɲ乤ë¤À¤±¤Ç¤¹

    + +

    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +

    + +

    NameVirtualHost µÚ¤Ó + VirtualHost ¤Î¤É¤Á¤é¤Î¾ì¹ç¤â¡¢ + * ¤ÎÉôʬ¤Ë¤ÏÌÀ¼¨Åª¤Ë IP ¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð¡¢¤¢¤ë IP ¥¢¥É¥ì¥¹¤Ç¤Ï̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤¤¤¿¤¤°ìÊý¤Ç¡¢ + Ê̤ΠIP ¥¢¥É¥ì¥¹¤Ç¤Ï¡¢Â¾¤Î IP ¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ä + ÊÌÁȤÎ̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ò»È¤¤¤¿¤¤¾ì¹ç¡¢ + ¤½¤¦ÀßÄꤹ¤ë¤³¤È¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£

    + +

    Ê£¿ô¤Î̾Á°¤Ç¥µ¡¼¥Ð¥¢¥¯¥»¥¹¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿¤¤¤³¤È¤â¿¤¤¤Ç¤·¤ç¤¦¡£ + ¤³¤Î¤è¤¦¤Ê¤³¤È¤Ï¡¢ServerAlias ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò <VirtualHost> + ¥»¥¯¥·¥ç¥ó¤Ëµ­½Ò¤¹¤ë¤³¤È¤Ç¼Â¸½¤Ç¤­¤Þ¤¹¡£ + Î㤨¤Ð¾åµ­¤Î <VirtualHost> ¤ÎÎã¤Ç¤¢¤ì¤Ð¡¢ + ¼¡¤Î¤è¤¦¤Ë°ìÍ÷¤Ëµó¤²¤é¤ì¤¿Ì¾Á°¤¬¡¢ + ¥æ¡¼¥¶¤¬Æ±°ì¤Î¥¦¥§¥Ö¥µ¥¤¥È¤È¤·¤ÆÌܤˤ·¤Æ»ÈÍѤǤ­¤ë¥µ¡¼¥Ð̾¤Ç¤¢¤ë¡¢ + ¤È ServerAlias + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ç»ØÄê¤Ç¤­¤Þ¤¹¡£

    + +

    + ServerAlias domain.tld *.domain.tld +

    + +

    domain.tld ¥É¥á¥¤¥ó¤Ø¤ÎÁ´¤Æ¤Î¥Û¥¹¥È¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï + www.domain.tld ¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬½èÍý¤·¤Þ¤¹¡£ + ̾Á°¤ò¥Þ¥Ã¥Á¤µ¤»¤ë¤¿¤á¤Ë¡¢¥ï¥¤¥ë¥É¥«¡¼¥Éʸ»ú * ¤ä ? + ¤ò»ÈÍѤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤â¤Á¤í¤ó»×¤¤¤Ä¤­¤Î̾Á°¤òºî¤Ã¤Æ¡¢ + ServerName ¤ä + ServerAlias + ¤Ë¤½¤Î̾Á°¤ò½ñ¤¯¤È¤¤¤Ã¤¿¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤Þ¤º¤Ï¡¢ + ¤³¤ì¤é¤Î̾Á°¤¬ ¥µ¡¼¥Ð¤ËÉÕ¤±¤é¤ì¤¿ IP ¥¢¥É¥ì¥¹¤Ë¥Þ¥Ã¥×¤µ¤ì¤ë¤è¤¦¤Ë + DNS ¥µ¡¼¥Ð¤òŬÀÚ¤ËÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

    + +

    ºÇ¸å¤Ë¡¢<VirtualHost> ¥³¥ó¥Æ¥Ê¤ÎÃæ¤Ë + ¾¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤Ç¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ÎÀßÄê¤òºÙ¤«¤¯Ä´À° + ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ + ¤Û¤È¤ó¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ï¤³¤ì¤é¤Î¥³¥ó¥Æ¥Ê¤ËÀßÃÖ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Æ¡¢ + Êѹ¹ÅÀ¤Ï¤½¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËÂФ·¤Æ¤Î¤ßÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£ + ¤É¤Î¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¤«¤Ï¡¢¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Î ¥³¥ó¥Æ¥­¥¹¥È ¤ò + Ä´¤Ù¤Æ¤¯¤À¤µ¤¤¡£¼ç¥µ¡¼¥Ð¥³¥ó¥Æ¥­¥¹¥È + (<VirtualHost> + ¥³¥ó¥Æ¥Ê¤Î³°) ¤ÎÀßÄêÍѥǥ£¥ì¥¯¥Æ¥£¥Ö¤Ï¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ç¤ÎÀßÄê¤Ç + ¾å½ñ¤­¤µ¤ì¤Ê¤¤¾ì¹ç¤Î¤ß»ÈÍѤµ¤ì¤Þ¤¹¡£

    + +

    ¥ê¥¯¥¨¥¹¥È¤¬Íè¤ë¤È¡¢¥µ¡¼¥Ð¤Ï¤Þ¤ººÇ½é¤Ë <NameVirtualHost> + ¤Ë¥Þ¥Ã¥Á¤¹¤ë IP ¥¢¥É¥ì¥¹¤«¤É¤¦¤«¤ò¥Á¥§¥Ã¥¯¤·¤Þ¤¹¡£¥Þ¥Ã¥Á¤¹¤ì¤Ð + ¥Þ¥Ã¥Á¤·¤¿ IP ¥¢¥É¥ì¥¹¤Î <VirtualHost> + ¤Î¤½¤ì¤¾¤ì¤Î¥»¥¯¥·¥ç¥ó¤ÎÃ椫¤é + ServerName ¤« + ServerAlias + ¤ËÍ׵ᤵ¤ì¤¿¥Û¥¹¥È̾¤¬¤¢¤ë¤«Ãµ¤·¤Þ¤¹¡£ + ¸«¤Ä¤«¤ì¤Ð¤½¤Î¥µ¡¼¥ÐÍѤÎÀßÄê¤ò»È¤¤¤Þ¤¹¡£¥Þ¥Ã¥Á¤¹¤ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È + ¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥Þ¥Ã¥Á¤·¤¿ IP ¥¢¥É¥ì¥¹¤Î + ¥ê¥¹¥È¤ÎºÇ½é¤Ë¤¢¤ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È ¤¬»È¤ï¤ì¤Þ¤¹¡£

    + +

    ·ë²Ì¤È¤·¤Æ¡¢¥ê¥¹¥È¤ÎºÇ½é¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬ ¥Ç¥Õ¥©¥ë¥È ¤Î + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤Ê¤ê¤Þ¤¹¡£IP ¥¢¥É¥ì¥¹¤¬ NameVirtualHost + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤Ë¥Þ¥Ã¥Á¤·¤¿¾ì¹ç¤Ï¡¢¥á¥¤¥ó¤Î¥µ¡¼¥Ð ¤Î + DocumentRoot + ¤Ï·è¤·¤Æ»È¤ï¤ì¤Þ¤»¤ó + ¤É¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Ë¤â¥Þ¥Ã¥Á¤·¤Ê¤¤¥ê¥¯¥¨¥¹¥È¤ËÂФ·¤Æ¡¢ + ÆÃÊ̤ÊÀßÄê¤ò¤·¤¿¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢ÀßÄê¥Õ¥¡¥¤¥ëÃæ¤ÎºÇ½é¤Î + <VirtualHost> ¥³¥ó¥Æ¥Ê¤Ë¤½¤ì¤òµ­½Ò¤·¤Æ¤¯¤À¤µ¤¤¡£

    + +
    top
    +
    +

    ¸Å¤¤¥Ö¥é¥¦¥¶¤È¤Î¸ß´¹À­

    + +

    °ÊÁ°½Ò¤Ù¤¿¤è¤¦¤Ë¡¢Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤¬Àµ¤·¤¯Æ°ºî¤¹¤ë + ¤¿¤á¤ËɬÍפʾðÊó¤òÁ÷¤Ã¤Æ¤³¤Ê¤¤¥¯¥é¥¤¥¢¥ó¥È¤¬°ÍÁ³¤È¤·¤Æ¸ºß¤·¤Æ¤¤¤Þ¤¹¡£ + ¤½¤Î¤è¤¦¤Ê¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ¤Ï¡¢³ºÅö¤¹¤ë IP ¥¢¥É¥ì¥¹¤Ë¤Ä¤¤¤Æ¡¢ + °ìÈֺǽé¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È + (¥×¥é¥¤¥Þ¥ê¤Î̾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È) + ¤«¤é¥Ú¡¼¥¸¤¬Á÷¤êÊÖ¤µ¤ì¤Þ¤¹¡£

    + +

    ¤É¤Î¤°¤é¤¤¸Å¤¤¤Î ?

    +

    ¡Ö¸Å¤¤¡×¤Èɽ¸½¤·¤Æ¤¤¤ë¾ì¹ç¡¢ËÜÅö¤Ë¸Å¤¤¤³¤È¤ò°ÕÌ£¤·¤Æ»È¤Ã¤Æ¤¤¤Þ¤¹¡£ + ÉÔ¹¬¤Ë¤·¤Æº£¸½ºß¤Ç¤â¤³¤Î¤è¤¦¤Ê¸Å¤¤¥Ö¥é¥¦¥¶¤ËÁø¶ø¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£ + ¸½ºß¤Î¥Ö¥é¥¦¥¶¤ÏÁ´¤Æ¡¢Ì¾Á°¥Ù¡¼¥¹¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤ËɬÍ×¤Ê + Host ¥Ø¥Ã¥À¤òÁ÷¤ê¤Þ¤¹¡£

    +
    + +

    ServerPath + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ÇÂн褬²Äǽ¤Ç¤¹¡£¤Á¤ç¤Ã¤ÈÉԳʹ¥¤Ç¤¹¤±¤ì¤É¤â¡£

    + +

    ÀßÄêÎã

    + +

    + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +

    + +

    ¤³¤ÎÎã¤Ë¤Ï¤É¤¦¤¤¤¦°ÕÌ£¤¬¤¢¤ë¤Ç¤·¤ç¤¦¤«? ¤³¤ì¤Ï + "/domain" ¤Ç»Ï¤Þ¤ë URI ¤Ø¤Î¥ê¥¯¥¨¥¹¥È¤Ï¤¹¤Ù¤Æ¡¢ + ¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È www.domain.tld ¤Ç½èÍý¤µ¤ì¤ë¡¢ + ¤È¤¤¤¦°ÕÌ£¤Ç¤¹¡£¤Ä¤Þ¤ê¡¢¤¹¤Ù¤Æ¤Î¥¯¥é¥¤¥¢¥ó¥È¤Ç + http://www.domain.tld/domain/ ¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¥Ú¡¼¥¸¤¬¡¢ + Host: ¥Ø¥Ã¥À¤òÁ÷¤Ã¤Æ¤¯¤ë¥¯¥é¥¤¥¢¥ó¥È¤Ç¤¢¤ì¤Ð + http://www.domain.tld/ ¤È¤·¤Æ¤â¥¢¥¯¥»¥¹¤Ç¤­¤ë¡¢ + ¤È¤¤¤¦°ÕÌ£¤Ç¤¹¡£

    + +

    ¤³¤ì¤¬Æ°ºî¤¹¤ë¤è¤¦¤Ë¤¹¤ë¤Ë¤Ï¡¢ + ¥×¥é¥¤¥Þ¥ê¤Î¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥Ú¡¼¥¸¤Ë + http://www.domain.tld/domain/ ¤Ø¤Î¥ê¥ó¥¯¤òÀßÃÖ¤·¤Þ¤¹¡£ + ¤½¤·¤Æ¡¢¥Ð¡¼¥Á¥ã¥ë¥Û¥¹¥È¤Î¥Ú¡¼¥¸¤Ç¤Ï¡¢½ã¿è¤ÊÁêÂÐ¥ê¥ó¥¯ (Îã: + "file.html" ¤ä "../icons/image.gif")¡¢ + ¤¢¤ë¤¤¤Ï /domain/ ¤Ç»Ï¤Þ¤ë¥ê¥ó¥¯ (Îã: + "http://www.domain.tld/domain/misc/file.html" ¤ä + "/domain/misc/file.html") ¤À¤±¤òÀßÃÖ¤·¤Þ¤¹¡£

    + +

    ¤³¤ì¤Ë¤Ï¡¢´öʬ¤«¤Îµ¬Î§¤¬É¬ÍפȤʤê¤Þ¤¹¤¬¡¢ + ¤³¤Î¤è¤¦¤Ê¥¬¥¤¥É¥é¥¤¥ó¤òÃé¼Â¤Ë¼é¤ë¤³¤È¤Ë¤è¤ê¡¢¤¿¤¤¤Æ¤¤¤Î¾ì¹ç¡¢ + ¤¹¤Ù¤Æ¤Î¥Ö¥é¥¦¥¶¤Ç ¡½ ¿·¤·¤¤¥Ö¥é¥¦¥¶¤Ç¤â¸Å¤¤¤â¤Î¤Ç¤â ¡½ + ºîÀ®¤·¤¿¥Ú¡¼¥¸¤¬¸«¤¨¤ë¤È¤¤¤¦¤³¤È¤òÊݾڤ·¤Þ¤¹¡£

    + +
    +
    +

    Available Languages:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/name-based.html.ko.euc-kr b/trunk/docs/manual/vhosts/name-based.html.ko.euc-kr new file mode 100644 index 0000000000..02adaa43df --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.html.ko.euc-kr @@ -0,0 +1,234 @@ + + + +À̸§±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø - Apache HTTP Server + + + + + +
    <-
    +

    À̸§±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø

    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + +

    ÀÌ ¹®¼­´Â À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ´Â °æ¿ì¿Í ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    +
    + +
    top
    +
    +

    À̸§±â¹Ý ´ë IP±â¹Ý °¡»óÈ£½ºÆ®

    + +

    IP±â¹Ý °¡»óÈ£½ºÆ®´Â ¿¬°áÇÑ IP ÁÖ¼Ò¸¦ °¡Áö°í ¼­ºñ½ºÇÒ + °¡»óÈ£½ºÆ®¸¦ °áÁ¤ÇÑ´Ù. ±×·¡¼­ °¢ È£½ºÆ®´Â ¼­·Î ´Ù¸¥ IP ÁÖ¼Ò¸¦ + °¡Á®¾ß ÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ °æ¿ì ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ + HTTP Çì´õ·Î È£½ºÆ®¸íÀ» ¾Ë·ÁÁÖ±æ ¹Ù¶õ´Ù. ÀÌ·± ¹æ¹ýÀ¸·Î ÇÑ + IP ÁÖ¼Ò·Î ¿©·¯ ´Ù¸¥ È£½ºÆ®¸¦ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â DNS ¼­¹ö°¡ °¢ È£½ºÆ®¸íÀÌ ¿Ã¹Ù¸¥ + IP ÁÖ¼Ò·Î ´ëÀÀÇϵµ·Ï °¡»óÈ£½ºÆ®¸¦ ¼³Á¤ÇÏ°í, ´Ù¸¥ È£½ºÆ®¸íÀ» ±¸º°ÇÒ + ¼ö ÀÖµµ·Ï ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¼³Á¤Çϱ⸸ ÇϸéµÇ¹Ç·Î ´õ °£´ÜÇÏ´Ù. À̸§±â¹Ý + °¡»óÈ£½ºÆ®´Â ¶Ç ¿©·¯ IP ÁÖ¼Ò°¡ ÇÊ¿ä¾ø´Ù. ±×·¯¹Ç·Î Ưº°È÷ + IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ¼±ÅÃÇÒ ÀÌÀ¯°¡ ¾ø´Ù¸é À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇؾßÇÒ ÀÌÀ¯·Î´Â:

    + +
      +
    • À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÏÁö¾Ê´Â ¿À·¡µÈ + Ŭ¶óÀ̾ðÆ®µéÀÌ ÀÖ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ·Á¸é + Ŭ¶óÀ̾ðÆ®°¡ HTTP Host Çì´õ¸¦ º¸³»¾ß ÇÑ´Ù. ÀÌ´Â + HTTP/1.1¿¡¼­´Â ÇʼöÀÌ°í, ÃÖ±Ù ¸ðµç HTTP/1.0 ºê¶ó¿ìÀúµéµµ + È®ÀåÀ¸·Î Áö¿øÇÑ´Ù. ¸¸¾à À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇϸ鼭 + ¿À·¡µÈ Ŭ¶óÀ̾ðÆ®¸¦ Áö¿øÇØ¾ß ÇÑ´Ù¸é ÀÌ ¹®¼­ ³¡¿¡ ÀÖ´Â + ¹æ¹ýÀ» »ìÆìºÁ¶ó.
    • + +
    • SSL ÇÁ·ÎÅäÄÝÀÇ ¼º°Ý»ó SSL º¸¾È¼­¹ö¿¡¼­ À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • + +
    • ¾î¶² ¿î¿µÃ¼Á¦³ª ³×Æ®¿÷ ÀåÄ¡´Â ´Ù¸¥ IP ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é È£½ºÆ®¸¦ ±¸º°ÇÏÁö ¸øÇÏ´Â ³×Æ®¿÷ »ç¿ë·®(bandwidth) + °ü¸®±â¼úÀ» »ç¿ëÇÑ´Ù.
    • +
    + +
    top
    +
    +

    À̸§±â¹Ý °¡»óÈ£½ºÆ® »ç¿ëÇϱâ

    + + + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ·Á¸é ¼­¹ö´Â ¿¬°áÀ» ¹ÞÀ» + IP ÁÖ¼Ò¸¦ (¾Æ¸¶ Æ÷Æ®µµ) Á¤ÇØ¾ß ÇÑ´Ù. ÀÌ´Â NameVirtualHost Áö½Ã¾î·Î °¡´ÉÇÏ´Ù. + ÀϹÝÀûÀ¸·Î ¼­¹öÀÇ ¸ðµç IP ÁÖ¼Ò¸¦ »ç¿ëÇÑ´Ù¸é + NameVirtualHostÀÇ + ¾Æ±Ô¸ÕÆ®·Î *¸¦ »ç¿ëÇÑ´Ù. ¿©·¯ Æ÷Æ®¸¦ »ç¿ëÇÒ + (¿¹¸¦ µé¾î, SSLÀ» »ç¿ëÇÒ) °èȹÀ̶ó¸é *:80°ú + °°ÀÌ ¾Æ±Ô¸ÕÆ®¿¡ Æ÷Æ®¸¦ Ãß°¡ÇØ¾ß ÇÑ´Ù. NameVirtualHost Áö½Ã¾î¿¡ IP ÁÖ¼Ò¸¦ + Àû¾îÁÖ¾ú´Ù°í ¼­¹ö°¡ ÀÚµ¿À¸·Î ±× IP ÁÖ¼Ò¸¦ ±â´Ù¸®Áö ¾ÊÀ½À» + ÁÖÀÇÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº ¾ÆÆÄÄ¡°¡ + »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ® ¼³Á¤Çϱ⸦ Âü°íÇ϶ó. ¶Ç, ¿©±â¼­ + ÁöÁ¤ÇÑ IP ÁÖ¼Ò´Â ¼­¹öÀÇ ³×Æ®¿÷ ÀÎÅÍÆäÀ̽ºÀ̾î¾ß ÇÑ´Ù.

    + +

    ´ÙÀ½ ´Ü°è´Â ¼­ºñ½ºÇÏ·Á´Â È£½ºÆ®º°·Î <VirtualHost> ºí·ÏÀ» + ¸¸µå´Â ÀÏÀÌ´Ù. <VirtualHost>> Áö½Ã¾îÀÇ ¾Æ±Ô¸ÕÆ®´Â + NameVirtualHost Áö½Ã¾îÀÇ + ¾Æ±Ô¸ÕÆ®(¿¹¸¦ µé¾î, IP ÁÖ¼Ò³ª ¸ðµç ÁÖ¼Ò¸¦ ¶æÇÏ´Â *)¿Í + °°¾Æ¾ß ÇÑ´Ù. <VirtualHost>> ºí·Ï ¾È¿¡´Â + ÃÖ¼ÒÇÑ ¼­ºñ½ºÇÒ È£½ºÆ®¸¦ ÁöÁ¤ÇÏ´Â ServerName Áö½Ã¾î¿Í È£½ºÆ®ÀÇ + ³»¿ëÀÌ ÆÄÀϽýºÅÛ ¾îµð¿¡ ÀÖ´ÂÁö¸¦ ÁöÁ¤ÇÏ´Â DocumentRoot Áö½Ã¾î°¡ ÇÊ¿äÇÏ´Ù.

    + +

    ÁÖ È£½ºÆ®°¡ ¾ø¾îÁø´Ù

    +

    ±âÁ¸¿¡ »ç¿ëÇÏ´ø À¥¼­¹ö¿¡ °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇÑ´Ù¸é + ±âÁ¸¿¡ »ç¿ëÇÏ´ø È£½ºÆ®¿¡ ´ëÇÑ <VirtualHost> ºí·Ïµµ Ãß°¡ÇØ¾ß + ÇÑ´Ù. ÀÌ ºí·Ï¿¡ Æ÷ÇÔÇÏ´Â ServerName°ú DocumentRoot´Â Àüü ServerName°ú DocumentRoot¿Í °°¾Æ¾ß ÇÑ´Ù. + ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ °¡»óÈ£½ºÆ®¸¦ °¡Àå ¸ÕÀú ÀûÀ¸¸é ±âº» È£½ºÆ®°¡ + µÈ´Ù.

    +
    + +

    ¿¹¸¦ µé¾î www.domain.tld µµ¸ÞÀÎÀ» ¼­ºñ½ºÇÏ°í + ÀÖ¾ú´Âµ¥ °°Àº IP ÁÖ¼Ò¿¡ + www.otherdomain.tld¶õ °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. httpd.conf¿¡ ´ÙÀ½°ú °°ÀÌ + Ãß°¡ÇÏ¸é µÈ´Ù:

    + +

    + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +

    + +

    NameVirtualHost¿Í + <VirtualHost> + Áö½Ã¾î µÑ ¸ðµÎ * ´ë½Å Á÷Á¢ IP ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ + ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, ÀÌ·±½ÄÀ¸·Î ÇÑ IP ÁÖ¼Ò¿¡ ¿©·¯ À̸§±â¹Ý + °¡»óÈ£½ºÆ®µéÀ» µ¹¸®°í, ´Ù¸¥ ÁÖ¼Ò¿¡ IP±â¹Ý ȤÀº À̸§±â¹Ý + °¡»óÈ£½ºÆ®µéÀ» µ¹¸± ¼ö ÀÖ´Ù.

    + +

    ¾î¶² ¼­¹ö´Â ¿©·¯ À̸§À¸·Î Á¢¼ÓÇÒ ¼ö ÀÖ±æ ¹Ù¶õ´Ù. ÀÌ´Â + <VirtualHost> + ¼½¼Ç ¾È¿¡ ServerAlias + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î À§ÀÇ Ã¹¹ø° <VirtualHost> ºí·Ï¿¡¼­ + ServerAlias Áö½Ã¾î¸¦ + »ç¿ëÇÏ¸é ¿­°ÅÇÑ À̸§À¸·Î °°Àº À¥»çÀÌÆ®¸¦ º¼ ¼ö ÀÖ´Ù:

    + +

    + ServerAlias domain.tld *.domain.tld +

    + +

    domain.tld µµ¸ÞÀο¡ ÀÖ´Â ¸ðµç È£½ºÆ®¿¡ ´ëÇÑ + ¿äûÀ» www.domain.tld °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù. + À̸§À» ÁÙ¶§ ¿ÍÀϵåÄ«µå ¹®ÀÚ *¿Í ?¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¹°·Ð ServerNameÀ̳ª ServerAlias¿¡ + À̸§À» Àû¾îÁÖ¾ú´Ù°í ³¡ÀÌ ¾Æ´Ï´Ù. ¸ÕÀú ÀÌ À̸§µéÀÌ ¼­¹öÀÇ + IP ÁÖ¼Ò·Î ´ëÀÀÇϵµ·Ï DNS ¼­¹ö¸¦ ¾Ë¸Â°Ô ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¸¶Áö¸·À¸·Î <<VirtualHost>> ¾È¿¡ ´Ù¸¥ + Áö½Ã¾îµéÀ» »ç¿ëÇÏ¿© °¡»óÈ£½ºÆ®¸¦ ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. + ´ëºÎºÐÀÇ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, °ü·ÃµÈ °¡»óÈ£½ºÆ®ÀÇ ¼³Á¤¸¸À» + º¯°æÇÑ´Ù. ¾î¶² Áö½Ã¾î°¡ »ç¿ë°¡´ÉÇÑÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó. (<<VirtualHost>> ¾ÈÀÌ ¾Æ´Ñ) + ÁÖ¼­¹ö¼³Á¤¿¡¼­ ÁöÁ¤ÇÑ ¼³Á¤ Áö½Ã¾î´Â °¡»óÈ£½ºÆ®¿¡ + °°Àº ¼³Á¤ Áö½Ã¾î°¡ ¾ø´Â °æ¿ì¿¡¸¸ »ç¿ëµÈ´Ù.

    + +

    ¿äûÀ» ¹ÞÀ¸¸é ¼­¹ö´Â ¸ÕÀú NameVirtualHost¿¡¼­ ÁöÁ¤ÇÑ IP + ÁÖ¼ÒÀÎÁö °Ë»çÇÑ´Ù. ±×·¸´Ù¸é ±× IP ÁÖ¼Ò¸¦ °¡Áø <VirtualHost> + ¼½¼Çµé¿¡¼­ ¿äûÇÑ È£½ºÆ®¸í°ú ÀÏÄ¡ÇÏ´Â ServerNameÀ̳ª + ServerAlias¸¦ ã´Â´Ù. ãÀ¸¸é ±× ¼³Á¤À» »ç¿ëÇÑ´Ù. + ÀûÀýÇÑ °¡»óÈ£½ºÆ®¸¦ ãÁö¸øÇϸé, IP ÁÖ¼Ò¿¡ ÇØ´çÇÏ´Â + °¡»óÈ£½ºÆ®µéÁß Ã¹¹ø° °ÍÀ» »ç¿ëÇÑ´Ù.

    + +

    °á°úÀûÀ¸·Î óÀ½¿¡ ³ª¿Â °¡»óÈ£½ºÆ®°¡ ±âº» + °¡»óÈ£½ºÆ®°¡ µÈ´Ù. IP ÁÖ¼Ò°¡ NameVirtualHost Áö½Ã¾î¿¡ ÇØ´çÇϸé, + ÁÖ¼­¹öÀÇ DocumentRoot´Â + Àý´ë·Î »ç¿ëÇÏÁö ¾Ê´Â´Ù. ƯÁ¤ °¡»óÈ£½ºÆ®¿¡ + ÇØ´çÇÏÁö¾Ê´Â ¿äûÀ» ¼³Á¤ÇÏ·Á¸é ¼³Á¤À» <VirtualHost>¿¡ ´ã°í ¼³Á¤ÆÄÀÏ¿¡¼­ + ¸ÕÀú ³ª¿Àµµ·Ï ÇÏ¸é µÈ´Ù.

    + +
    top
    +
    +

    ¿À·¡µÈ ºê¶ó¿ìÀú¿Í ȣȯ

    + +

    ÀÌ¹Ì Àû¾úµíÀÌ À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ ¿Ã¹Ù·Î µ¿ÀÛÇϱâÀ§ÇØ + ÇÊ¿äÇÑ Á¤º¸¸¦ º¸³»Áö¾Ê´Â Ŭ¶óÀ̾ðÆ®°¡ ÀÖ´Ù. ÀÌ·± Ŭ¶óÀ̾ðÆ®´Â + Ç×»ó ¿äûÇÑ IP ÁÖ¼Ò¿¡ ´ëÇØ Ã¹¹ø°·Î ³ª¿À´Â °¡»óÈ£½ºÆ® + (ÃÖÃÊÀÇ À̸§±â¹Ý °¡»óÈ£½ºÆ®)°¡ + ¼­ºñ½ºÇÑ´Ù.

    + +

    ¾ó¸¶³ª ¿À·¡µÈ °ÍÀ» ¸»Çϴ°¡?

    +

    ¿©±â¼­ ¿À·¡µÇ¾úÀ½Àº ½ÇÁ¦·Î »ó´çÈ÷ ¿À·¡µÈ °ÍÀ» ¶æÇÑ´Ù. + ¿À´Ã³¯ ÀÌ·± ºê¶ó¿ìÀú¸¦ »ç¿ëÇÒ ÀÏÀº °ÅÀǾø´Ù. ¿äÁò + ºê¶ó¿ìÀú´Â ¸ðµÎ À̸§±â¹Ý °¡»óÈ£½ºÆ®¿¡ ÇÊ¿äÇÑ Host + Çì´õ¸¦ º¸³½´Ù.

    +
    + +

    ÀÌ ¹®Á¦´Â ¾à°£ °ÅÃßÀ彺·´Áö¸¸ ServerPath Áö½Ã¾î·Î ÇØ°áÇÒ ¼ö ÀÖ´Ù:

    + +

    ¼³Á¤ ¿¹:

    + +

    + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +

    + +

    ÀÌ°Ô ¹«½¼ ¶æÀΰ¡? "/domain"·Î ½ÃÀÛÇÏ´Â + URI¿¡ ´ëÇÑ ¿äûÀº °¡»óÈ£½ºÆ® www.domain.tld°¡ + ¼­ºñ½ºÇÑ´Ù. Áï, Host: Çì´õ¸¦ º¸³»´Â Ŭ¶óÀ̾ðÆ®´Â + http://www.domain.tld/¸¸À¸·Îµµ Á¢±ÙÇÒ ¼ö ÀÖÁö¸¸, + http://www.domain.tld/domain/À¸·Î´Â ¸ðµç + Ŭ¶óÀ̾ðÆ®°¡ ÆäÀÌÁö¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    + +

    À̸¦ À§ÇØ ÃÖÃÊÀÇ °¡»óÈ£½ºÆ®¿¡ ÀÖ´Â ÆäÀÌÁö¿¡ + http://www.domain.tld/domain/À¸·Î °¡´Â ¸µÅ©¸¦ + ³Ö´Â´Ù. ±×¸®°í °¡»óÈ£½ºÆ® ÆäÀÌÁö¿¡¼­´Â »ó´ë¸µÅ© (¿¹¸¦ µé¾î, + "file.html" À̳ª "../icons/image.gif") + ȤÀº ("http://www.domain.tld/domain/misc/file.html"À̳ª + "/domain/misc/file.html"°ú °°ÀÌ) ¾Õ¿¡ + /domain/ÀÌ ºÙÀº ¸µÅ©¸¸À» »ç¿ëÇÑ´Ù.

    + +

    Á¶±Ý ±ÔÄ¢ÀÌ ÇÊ¿äÇÏÁö¸¸ ÀÌ ±ÔÄ¢À» µû¸£¸é ´ëºÎºÐÀÇ °æ¿ì + ¿äÁò °ÍÀ̳ª ¿À·¡µÈ °ÍÀ̳ª °ü°è¾øÀÌ ¸ðµç ºê¶ó¿ìÀú·Î ÆäÀÌÁö¸¦ + º¼ ¼ö ÀÖ´Ù.

    + +
    +
    +

    °¡´ÉÇÑ ¾ð¾î:  de  | + en  | + ja  | + ko 

    +
    + \ No newline at end of file diff --git a/trunk/docs/manual/vhosts/name-based.xml b/trunk/docs/manual/vhosts/name-based.xml new file mode 100644 index 0000000000..567b3faba1 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.xml @@ -0,0 +1,269 @@ + + + + + + + + +Virtual Hosts +Name-based Virtual Host Support + + +

    This document describes when and how to use name-based virtual hosts.

    +
    + +IP-based Virtual Host Support +An In-Depth Discussion of Virtual Host Matching +Dynamically configured mass virtual hosting +Virtual Host examples for common setups +ServerPath configuration example + +
    Name-based vs. IP-based Virtual Hosts + +

    IP-based virtual hosts use the IP address of the connection to + determine the correct virtual host to serve. Therefore you need to + have a separate IP address for each host. With name-based virtual + hosting, the server relies on the client to report the hostname as + part of the HTTP headers. Using this technique, many different hosts + can share the same IP address.

    + +

    Name-based virtual hosting is usually simpler, since you need + only configure your DNS server to map each hostname to the correct + IP address and then configure the Apache HTTP Server to recognize + the different hostnames. Name-based virtual hosting also eases + the demand for scarce IP addresses. Therefore you should use + name-based virtual hosting unless there is a specific reason to + choose IP-based virtual hosting. Some reasons why you might consider + using IP-based virtual hosting:

    + +
      +
    • Some ancient clients are not compatible with name-based virtual + hosting. For name-based virtual hosting to work, the client must send + the HTTP Host header. This is required by HTTP/1.1, and is + implemented by all modern HTTP/1.0 browsers as an extension. If you + need to support obsolete clients and still use name-based virtual + hosting, a possible technique is discussed at the end of this + document.
    • + +
    • Name-based virtual hosting cannot be used with SSL secure servers + because of the nature of the SSL protocol.
    • + +
    • Some operating systems and network equipment implement bandwidth + management techniques that cannot differentiate between hosts unless + they are on separate IP addresses.
    • +
    + +
    + +
    Using Name-based Virtual Hosts + + + + core + + + + DocumentRoot + NameVirtualHost + ServerAlias + ServerName + ServerPath + VirtualHost + + + +

    To use name-based virtual hosting, you must designate the IP + address (and possibly port) on the server that will be accepting + requests for the hosts. This is configured using the NameVirtualHost directive. + In the normal case where any and all IP addresses on the server should + be used, you can use * as the argument to NameVirtualHost. If you're planning to use + multiple ports (e.g. running SSL) you should add a Port to the argument, + such as *:80. Note that mentioning an IP address in a + NameVirtualHost directive does not + automatically make the server listen to that IP address. See + Setting which addresses and ports Apache uses + for more details. In addition, any IP address specified here must be + associated with a network interface on the server.

    + +

    The next step is to create a VirtualHost block for + each different host that you would like to serve. The argument to the + VirtualHost directive + should be the same as the argument to the NameVirtualHost directive (ie, an IP address, + or * for all addresses). Inside each VirtualHost block, you will need at minimum a + ServerName directive to designate + which host is served and a DocumentRoot + directive to show where in the filesystem the content for that host + lives.

    + + Main host goes away +

    If you are adding virtual hosts to an existing web server, you + must also create a VirtualHost block for the existing host. The ServerName and DocumentRoot included in this virtual host should be the + same as the global ServerName and + DocumentRoot. List this virtual + host first in the configuration file so that it will act as the default + host.

    +
    + +

    For example, suppose that you are serving the domain + www.domain.tld and you wish to add the virtual host + www.otherdomain.tld, which points at the same IP address. + Then you simply add the following to httpd.conf:

    + + + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +
    + +

    You can alternatively specify an explicit IP address in place of the + * in both the NameVirtualHost and VirtualHost directives. For example, you might want to do this + in order to run some name-based virtual hosts on one IP address, and either + IP-based, or another set of name-based virtual hosts on another address.

    + +

    Many servers want to be accessible by more than one name. This is + possible with the ServerAlias + directive, placed inside the VirtualHost section. For example in the first VirtualHost block above, the + ServerAlias directive indicates that + the listed names are other names which people can use to see that same + web site:

    + + + ServerAlias domain.tld *.domain.tld + + +

    then requests for all hosts in the domain.tld domain will + be served by the www.domain.tld virtual host. The wildcard + characters * and ? can be used to match names. + Of course, you can't just make up names and place them in ServerName or ServerAlias. You must + first have your DNS server properly configured to map those names to an IP + address associated with your server.

    + +

    Finally, you can fine-tune the configuration of the virtual hosts + by placing other directives inside the VirtualHost containers. Most directives can be + placed in these containers and will then change the configuration only of + the relevant virtual host. To find out if a particular directive is allowed, + check the Context of the + directive. Configuration directives set in the main server context + (outside any VirtualHost + container) will be used only if they are not overridden by the virtual host + settings.

    + +

    Now when a request arrives, the server will first check if it is using + an IP address that matches the NameVirtualHost. If it is, then it will look at each VirtualHost section with a matching + IP address and try to find one where the ServerName or ServerAlias matches the requested + hostname. If it finds one, then it uses the configuration for that server. + If no matching virtual host is found, then the first listed virtual + host that matches the IP address will be used.

    + +

    As a consequence, the first listed virtual host is the default + virtual host. The DocumentRoot from + the main server will never be used when an IP + address matches the NameVirtualHost + directive. If you would like to have a special configuration for requests + that do not match any particular virtual host, simply put that configuration + in a VirtualHost + container and list it first in the configuration file.

    + +
    + +
    Compatibility with Older Browsers + +

    As mentioned earlier, there are some clients + 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 first virtual host listed for that IP address + (the primary name-based virtual host).

    + + How much older? +

    Please note that when we say older, we really do mean older. You are + very unlikely to encounter one of these browsers in use today. All + current versions of any browser send the Host header as + required for name-based virtual hosts.

    +
    + +

    There is a possible workaround with the ServerPath + directive, albeit a slightly cumbersome one:

    + +

    Example configuration:

    + + + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +
    + +

    What does this mean? It means that a request for any URI + beginning with "/domain" will be served from the + virtual host www.domain.tld. This means that the + pages can be accessed as http://www.domain.tld/domain/ + for all clients, although clients sending a Host: header + can also access it as http://www.domain.tld/.

    + +

    In order to make this work, put a link on your primary + virtual host's page to + http://www.domain.tld/domain/. Then, in the virtual + host's pages, be sure to use either purely relative links + (e.g., "file.html" or + "../icons/image.gif") or links containing the + prefacing /domain/ (e.g., + "http://www.domain.tld/domain/misc/file.html" or + "/domain/misc/file.html").

    + +

    This requires a bit of discipline, but adherence to these + guidelines will, for the most part, ensure that your pages will + work with all browsers, new and old.

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/name-based.xml.de b/trunk/docs/manual/vhosts/name-based.xml.de new file mode 100644 index 0000000000..2472840cf0 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.xml.de @@ -0,0 +1,298 @@ + + + + + + + + +Virtual Hosts +Unterstützung namensbasierter virtueller Hosts + + +

    Das Dokument beschreibt, wann und wie namensbasierte virtuelle Hosts zu + verwenden sind.

    +
    + +Unterstützung IP-basierter virtueller + Hosts +Tiefergehende Erörterung der Zuweisung + virtueller Hosts +Dynamisch konfiguriertes + Massen-Virtual-Hosting +Beispiele für virtuelle Hosts in typischen + Installationen +ServerPath-Beispielkonfiguration + +
    Namensbasierte gegenüber IP-basierten + virtuellen Hosts + +

    IP-basierte virtuelle Hosts verwenden die IP-Adresse der Verbindung, um den + korrekten virtuellen Host zur Bedienung einer Anfrage zu ermitteln. Folglich + benötigen Sie eine IP-Adresse für jeden virtuellen Host. Bei der + Verwendung von namensbasierten virtuellen Hosts verläßt sich der + Server darauf, dass der Client den Hostnamen als Bestandteil der HTTP-Header + angibt. Durch Anwendung dieser Technik können sich mehrere verschiedene + Hosts die gleiche IP-Adresse teilen.

    + +

    Die Verwendung von namensbasierten virtuellen Hosts ist gewöhnlich + einfacher. Sie müssen lediglich Ihren DNS-Server darauf einstellen, + jeden Hostnamen auf die richtige IP-Adresse abzubilden, und dann den Apache + HTTP Server so konfigurieren, dass er die verschiedenen Hostnamen erkennt. + Namensbasierte virtuelle Hosts entschärfen auch den Bedarf an + knappen IP-Adressen. Daher sollten Sie namensbasierte virtuelle Hosts + verwenden, sofern kein besonderer Grund dafür existiert, IP-basierte + virtuelle Hosts zu wählen. Mögliche Gründe für die + Verwendung IP-basierter virtueller Hosts sind:

    + +
      +
    • Einige antike Clients sind nicht kompatibel zu namensbasierten + virtuellen Hosts. Damit namensbasierte virtuelle Hosts funktionieren, + muss der Client den HTTP-Host-Header senden. Dies ist bei HTTP/1.1 + vorgeschrieben und in allen modernen HTTP/1.0-Browsern als Erweiterung + implementiert. Wenn Sie Unterstützung für veraltete Clients + benötigen und dennoch namensbasierte virtuelle Hosts verwenden, + dann finden Sie eine mögliche Lösung dafür am Ende des + Dokuments.
    • + +
    • Namensbasierte virtuelle Hosts können aufgrund der Natur des + SSL-Protokolls nicht mit SSL-gesicherten Servern verwendet werden.
    • + +
    • Einige Betriebssysteme und Netzwerkanlagen setzen Techniken zum + Bandbreiten-Management ein, die nicht zwischen Hosts unterscheiden + können, wenn diese nicht auf verschiedenen IP-Adressen liegen.
    • +
    + +
    + +
    Die Verwendung von namensbasierten virtuellen Hosts + + + + core + + + + DocumentRoot + NameVirtualHost + ServerAlias + ServerName + ServerPath + VirtualHost + + + +

    Um namensbasierte virtuelle Hosts zu verwenden, müssen Sie die + IP-Adresse (und möglicherweise den Port) des Servers benennen, an + der Anfragen für die Hosts entgegengenommen werden. Dies wird mit + der Direktive NameVirtualHost + eingestellt. Im Normalfall, wenn alle IP-Adressen des Server verwendet + werden sollen, können Sie * als Argument für + NameVirtualHost verwenden. Wenn Sie + vorhaben, mehrere Ports zu nutzen (etwa wenn SSL läuft), sollten + Sie dem Argument einen Port hinzufügen, wie zum Beispiel + *:80. Beachten Sie, + dass die Angabe einer IP-Adresse in einer NameVirtualHost-Anweisung den Server nicht + automatisch an dieser Adresse lauschen läßt. Lesen Sie bitte "Bestimmen der vom Apache verwendeten Adressen und + Ports" für weitere Details. Zusätzlich muss jede hier + angegebene IP-Adresse einer Netzwerkkarte des Servers zugeordnet sein.

    + +

    Der nächste Schritt ist die Erstellung eines VirtualHost-Blocks für jeden einzelnen + Host, den Sie bedienen wollen. Das Argument der Direktive VirtualHost sollte das gleiche + sein wie das Argument der NameVirtualHost-Anweisung (d.h. eine IP-Adresse + oder * für alle Adressen). Innerhalb jedes VirtualHost-Blocks benötigen + Sie zumindestens eine ServerName-Anweisung, um zu bestimmen, welcher + Host bedient wird, und eine DocumentRoot-Anweisung, um anzugeben, wo im + Dateisystem der Inhalt des Hosts abgelegt ist.

    + + Der Hauptserver verschwindet + Wenn Sie virtuelle Hosts zu einem bestehenden Webserver hinzufügen, + müssen Sie auch einen VirtualHost-Block für den bestehenden Host + und bisherigen Hauptserver erstellen. + Die ServerName- und + DocumentRoot-Anweisungen zu diesem + virtuellen Host sollten die gleichen sein wie die globalen ServerName- und DocumentRoot-Anweisungen. Führen Sie diesen + virtuellen Host als erstes in der Konfigurationsdatei auf, so dass er als + Standard-Host fungiert. + + +

    Vorausgesetzt, Sie bedienen z.B. die Domain + www.domain.tld und möchten den virtuellen Host + www.otherdomain.tld hinzufügen, welcher auf + die gleiche IP-Adresse zeigt. Dann fügen Sie einfach Folgendes der + httpd.conf hinzu:

    + + + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +
    + +

    Sie können anstelle des * bei den beiden Anweisungen + NameVirtualHost und VirtualHost alternativ eine + eindeutige IP-Adresse angeben. Das kann man beispielsweise machen, um + einige namensbasierte virtuelle Hosts auf einer IP-Adresse zu betreiben und + entweder IP-basierte oder ein anderes Set von namensbasierten virtuellen + Hosts auf einer anderen Adresse.

    + +

    Viele Server wollen unter mehr als einem Namen erreichbar sein. Die + Direktive ServerAlias, die innerhalb + des VirtualHost-Abschnittes angegeben wird, + ermöglicht dies. Zum Beispiel zeigt die ServerAlias-Anweisung in dem ersten VirtualHost-Block oben an, dass die + aufgeführten Namen alternative Namen sind, die man verwenden kann, um + das gleiche Webangebot zu erreichen:

    + + + ServerAlias domain.tld *.domain.tld + + +

    Anfragen für alle Hosts der Domain domain.tld werden + von dem virtuellen Host www.domain.tld bedient. Die + Platzhalter * und ? können anstelle + entsprechender Namen verwendet werden. Natürlich können Sie nicht + einfach Namen erfinden und diese bei ServerName oder ServerAlias + angeben, Sie müssen zunächst Ihren DNS Server entsprechend + konfigurieren, dass er diese Namen auf die mit Ihrem Server verknüpfte + IP-Adresse abbildet.

    + +

    Und schlußendlich können Sie die Konfiguration der virtuellen + Hosts mittels Angabe weiterer Direktiven innherhalb der VirtualHost-Container + feineinstellen. Die meisten Direktiven können in diesen Containern + angegeben werden und verändern dann ausschließlich die + Konfiguration des entsprechenden virtuellen Hosts. Prüfen Sie den Kontext einer Direktive, um + herauszufinden, ob eine bestimmte Direktive zulässig ist. + Im Hauptserver-Kontext (außerhalb der VirtualHost-Container) definierte + Konfigurationsanweisungen werden nur dann angewendet, wenn sie nicht durch + Einstellungen des virtuellen Hosts außer Kraft gesetzt wurden.

    + +

    Wenn nun eine Anfrage eintrifft, prüft der Server zuerst, ob sie eine + IP-Adresse verwendet, die der NameVirtualHost-Anweisung entspricht. Ist dies der + Fall, dann sieht er sich jeden VirtualHost-Abschnitt mit einer passenden + IP-Adresse an und versucht den einen zu finden, dessen ServerName- oder ServerAlias-Anweisung mit dem gewünschten + Hostnamen übereinstimmt. Findet er einen, dann verwendet er die + Konfiguration dieses Servers. Wird kein passender virtueller Host gefunden, + dann wird der erste angegeben virtuelle Host verwendet, + dessen IP-Adresse paßt.

    + +

    Die Folge davon ist, dass der erste aufgeführte virtuelle Host der + Standard-Virtual-Host ist. Die DocumentRoot-Anweisung des Hauptservers + wird niemals verwendet, wenn eine IP-Adresse mit einer + NameVirtualHost-Anweisung + übereinstimmt. Wenn Sie eine spezielle Konfiguration für Anfragen + angeben möchten, die keinem bestimmten virtuellen Host entsprechen, + packen Sie diese Konfiguration einfach in einen VirtualHost-Container und führen diesen als + erstes in der Konfigurationsdatei auf.

    + +
    + +
    Kompatibilität mit älteren Browsern + +

    Wie zuvor erwähnt gibt es einige Clients, die nicht die notwendigen + Daten senden, mit denen namensbasierte virtuelle Hosts korrekt + funktionieren. Diesen Clients werden stets die Seiten des ersten, für + diese IP-Adresse aufgeführten virtuellen Hosts gesendet werden (des + primären namensbasierten virtuellen Hosts).

    + + Was bedeutet älter? +

    Beachten Sie bitte, wenn wir von älter sprechen, meinen wir auch + älter. Es ist sehr unwahrscheinlich, dass sie einen dieser Browser + heutzutage in Verwendung finden werden. Alle aktuellen Browser-Versionen + senden den Host-Header, so wie er für namensbasierte + virtuelle Hosts benäötigt wird.

    +
    + +

    Mit der Direktive ServerPath existiert + eine mögliche Behelfskonstruktion, obgleich sie etwas schwerfällig + ist:

    + +

    Beispielkonfiguration:

    + + + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +
    + +

    Was bedeutet das? Es bedeutet, dass eine Anfrage für eine mit + "/domain" beginnende URI von dem virtuellen Host + www.domain.tld bedient wird. Dies heißt, dass die Seiten + für alle Clients unter http://www.domain.tld/domain/ + abrufbar sind, wenngleich Clients, die den Header Host: + senden, auch über http://www.domain.tld/ auf sie zugreifen + können.

    + +

    Legen Sie einen Link auf der Seite Ihres primären virtuellen Hosts zu + http://www.domain.tld/domain/, um die Behelfslösung + verfügbar zu machen. Bei den Seiten der virtuellen Hosts müssen + Sie dann sicherstellen, entweder außschließlich relative Links + (z.B. "file.html" oder + "../icons/image.gif") zu verwenden oder Links, die das + einleitende /domain/ enthalten (z.B., + "http://www.domain.tld/domain/misc/file.html" oder + "/domain/misc/file.html").

    + +

    Dies erfordert etwas Disziplin, die Befolgung dieser Richtlinien stellt + jedoch größtenteils sicher, dass Ihre Seiten mit allen Browsern + funktionieren, alten wie neuen.

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/name-based.xml.ja b/trunk/docs/manual/vhosts/name-based.xml.ja new file mode 100644 index 0000000000..2e4d5fee62 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.xml.ja @@ -0,0 +1,289 @@ + + + + + + + + +$B%P!<%A%c%k%[%9%H(B +$BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H(B + + +

    $B$3$NJ8=q$G$OL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r$I$s$J$H$-!"(B + $B$I$&$d$C$F;H$&$+$r@bL@$7$^$9!#(B

    +
    + +$B%M!<%`%Y!<%9$N%P!<%A%c%k%[%9%H(B +$B%P!<%A%c%k%[%9%H$N%^%C%A%s%0$K$D$$$F$N>\:Y(B +$BBgNL$N%P!<%A%c%k%[%9%H$NF0E*$J@_Dj(B +$B%P!<%A%c%k%[%9%H$N0lHLE*$J@_DjNc(B +ServerPath $B@_DjNc(B + +
    $BL>A0%Y!<%9$H(B IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$NHf3S(B + +

    IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$G$O!"1~Ez$9$k(B + $B%P!<%A%c%k%[%9%H$X$N%3%M%/%7%g%s$r7hDj$9$k$?$a$K(B IP + $B%"%I%l%9$r;HMQ$7$^$9!#$G$9$+$i!"$=$l$>$l$N%[%9%H$K8D!9$K(B IP + $B%"%I%l%9$,I,MW$K$J$j$^$9!#$3$l$KBP$7$FL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$G$O!"(B + $B%/%i%$%"%s%H$,(B HTTP $B%X%C%@$N0lIt$H$7$F%[%9%HL>$r9p$2$k!"(B + $B$H$$$&$3$H$K0MB8$7$^$9!#$3$N5;=Q$GF10l(B IP + $B%"%I%l%9$r0[$J$kB??t$N%[%9%H$G6&M-$7$F$$$^$9!#(B

    + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$ODL>oC1=c$G!"$=$l$>$l$N%[%9%HL>$H(B + $B$=$l$KBP1~$9$k@53N$J(B IP $B%"%I%l%9$r(B DNS $B$G@_Dj$7!"0[$J$k(B + $B%[%9%HL>$r6hJL$9$k$h$&$K(B Apache HTTP $B%5!<%P$r@_Dj$9$k$@$1$G$9!#(B + $B$5$i$K!"L>A0%Y!<%9$N%P!<%A%c%k%[%9%H$OITB-$9$k(B IP + $B%"%I%l%9$N<{MW$r4KOB$7$^$9!#$7$?$,$C$F!"(BIP $B%Y!<%9$N%P!<%A%c%k%[%9%H$r(B + $BA*Br$9$Y$-FCDj$NM}M3$,$J$1$l$PL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r;H$&$Y$-$G$9!#(B + IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$r;HMQ$9$k$3$H$r9MN8$9$kM}M3$H$7$F!"(B

    + +
      +
    • $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$KBP1~$7$F$$$J$$8E$$%/%i%$%"%s%H$,$"$k(B + $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$,F/$/$?$a$K$O!"%/%i%$%"%s%H$O(B + HTTP $B%[%9%H%X%C%@$rAw$C$F$3$J$1$l$P$J$j$^$;$s!#(B + $B$3$l$O(B HTTP/1.1 $B$N;EMM$GMW5a$5$l$F$$$F!"$9$Y$F$N8=BeE*$J(B + HTTP/1.0 $B%V%i%&%6$G$b3HD%$H$7$FA0%Y!<%9$N(B + $B%P!<%A%c%k%[%9%H$r9T$$$?$$>l9g$O!"$3$NJ8=q$N:G8e$NJ}$K(B + $B=q$+$l$F$$$k2r7h:v$K$J$k$+$b$7$l$J$$J}K!$r8+$F$/$@$5$$!#(B
    • + +
    • $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$O(B SSL $B%W%m%H%3%k$NFCD'$K$h$j!"(B + SSL $B%;%-%e%"%5!<%P$K$O;H$($^$;$s!#(B
    • + +
    • $B%*%Z%l!<%F%#%s%0%7%9%F%`$d%M%C%H%o!<%/AuCV$N$J$+$K$O!"(B + $BJL$N(B IP $B%"%I%l%9>e$G$J$$>l9g!"J#?t$N%[%9%H$rJL07$$$G$-$J$$$h$&$J(B + $BBS0h4IM}$NJ}K!$r +
    + +
    + +
    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$rMxMQ$9$k(B + + + + core + + + + DocumentRoot + NameVirtualHost + ServerAlias + ServerName + ServerPath + VirtualHost + VirtualHost + + + +

    $BL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r;H$&$K$O!"$=$N%[%9%H$X$N(B + $B%j%/%(%9%H$rNameVirtualHost + $B%G%#%l%/%F%#%V$G@_Dj$7$^$9!#DL>o!"(BNameVirtualHost $B$G(B + * $B$NB0@-$r;H$C$F%5!<%P$NA4$F$N(B IP $B%"%I%l%9$r;H$$$^$9!#(B + ($BNc$($P(B SSL $B$N;HMQ$J$I$G(B) $BJ#?t$N%]!<%H$r;H$&$3$H$r7W2h$7$F$$$k$N$G$"$l$P!"(B + $B0z?t$K(B *:80 $B$N$h$&$K%]!<%H$b4^$a$k$h$&$K$7$F$/$@$5$$!#(B + NameVirtualHost $B%G%#%l%/%F%#%V$G(B + IP $B%"%I%l%9$r=q$$$F$b!"(B + $B<+F0E*$K%5!<%P$,$=$N(B IP $B%"%I%l%9$r%j%C%9%s$9$k$H$$$&$3$H$O$J$$$3$H$K(B + $BCm0U$7$F$/$@$5$$!#>\:Y$O!V(BApache $B$N;H$&%"%I%l%9$H(B + $B%]!<%H$r@_Dj$9$k(B$B!W$rFI$s$G$/$@$5$$!#$5$i$K!"$3$3$G;XDj$5$l$?(B + IP $B%"%I%l%9$OA4$F%5!<%P$N%M%C%H%o!<%/%$%s%?!<%U%'!<%9$H4XO"IU$1$i$l$F(B + $B$$$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B$l$KBP$7$F(B VirtualHost $B%V%m%C%/$r(B + $B:n@.$7$F$/$@$5$$!#(BVirtualHost + $B%G%#%l%/%F%#%V$N0z?t$O(B NameVirtualHost + $B%G%#%l%/%F%#%V$N0z?t$HF1$8$K$7$F$/$@$5$$(B ($B$9$J$o$A!"(BIP $B%"%I%l%9$+!"A4$F$N%"%I%l%9$r0UL#$9$k(B + *)$B!#$=$l$>$l$N(B VirtualHost + $B%G%#%l%/%F%#%V$NCf$K$O!":GDc8B!"$I$N%[%9%H$,07$o$l$k$+$r<($9(B ServerName $B%G%#%l%/%F%#%V$H!"(B + $B$=$N%[%9%HMQ$N%3%s%F%s%D$,%U%!%$%k%7%9%F%`>e$N$I$3$K$"$k$+$r<($9(B + DocumentRoot $B%G%#%l%/%F%#%V$r(B + $B=q$/I,MW$,$"$j$^$9!#(B

    + + $B%a%$%s%[%9%H$O$J$/$J$j$^$9(B +

    $B4{$K$"$k%&%'%V%5!<%P$K%P!<%A%c%k%[%9%H$rDI2C$9$k>l9g!"(B + $B4{B8$N%&%'%V%5!<%P$KBP$7$F$b(B VirtualHost + $B%V%m%C%/$r:n$i$J$1$l$P$J$j$^$;$s!#$3$N%P!<%A%c%k%[%9%H$N(B + ServerName $B$H(B + DocumentRoot + $B$O!"%0%m!<%P%k$J(B ServerName $B$H(B + DocumentRoot + $B$HF1$8$b$N$K$7$^$9!#$^$?!"$3$N%P!<%A%c%k%[%9%H$r@_Dj%U%!%$%k$NCf$G(B + $B@hF,$KCV$$$F!"%G%U%)%k%H%[%9%H$H$7$FF0:n$9$k$h$&$K$7$^$9!#(B

    +
    + +

    $B$?$H$($P!"(Bwww.domain.tld $B$rF0$+$7$F$$$F!"(B + $B$5$i$K%P!<%A%c%k%[%9%H(B www.otherdomain.tld + $B$rDI2C$9$k$H$7$^$7$g$&!#$3$N%P!<%A%c%k%[%9%H$OF10l(B IP $B$r;X$7$F$$$k$H$7$^$9!#(B + $B$=$N$h$&$J>l9g$O!"(Bhttpd.conf + $B$K0J2<$N$h$&$J%3!<%I$rDI2C$9$k$@$1$G$9(B

    + + + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +
    + +

    NameVirtualHost $B5Z$S(B + VirtualHost $B$N$I$A$i$N>l9g$b!"(B + * $B$NItJ,$K$OL@<(E*$K(B IP $B%"%I%l%9$r;XDj$9$k$3$H$,$G$-$^$9!#(B + $BNc$($P!"$"$k(B IP $B%"%I%l%9$G$OL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r;H$$$?$$0lJ}$G!"(B + $BJL$N(B IP $B%"%I%l%9$G$O!"B>$N(B IP $B%Y!<%9$N%P!<%A%c%k%[%9%H$d(B + $BJLAH$NL>A0%Y!<%9$N%P!<%A%c%k%[%9%H$r;H$$$?$$>l9g!"(B + $B$=$&@_Dj$9$k$3$H$K$J$k$G$7$g$&!#(B

    + +

    $BJ#?t$NL>A0$G%5!<%P%"%/%;%9$,$G$-$k$h$&$K$7$?$$$3$H$bB?$$$G$7$g$&!#(B + $B$3$N$h$&$J$3$H$O!"(BServerAlias $B%G%#%l%/%F%#%V$r(B VirtualHost + $B%;%/%7%g%s$K5-=R$9$k$3$H$Ge5-$N(B VirtualHost $B$NNc$G$"$l$P!"(B + $BA0$,!"(B + $B%f!<%6$,F10l$N%&%'%V%5%$%H$H$7$FL\$K$7$F;HMQ$G$-$k%5!<%PL>$G$"$k!"(B + $B$H(B ServerAlias + $B%G%#%l%/%F%#%V$G;XDj$G$-$^$9!#(B

    + + + ServerAlias domain.tld *.domain.tld + + +

    domain.tld $B%I%a%$%s$X$NA4$F$N%[%9%H$X$N%j%/%(%9%H$O(B + www.domain.tld $B$N%P!<%A%c%k%[%9%H$,=hM}$7$^$9!#(B + $BL>A0$r%^%C%A$5$;$k$?$a$K!"%o%$%k%I%+!<%IJ8;z(B * $B$d(B ? + $B$r;HMQ$9$k$3$H$b$G$-$^$9!#$b$A$m$s;W$$$D$-$NL>A0$r:n$C$F!"(B + ServerName $B$d(B + ServerAlias + $B$K$=$NL>A0$r=q$/$H$$$C$?$3$H$O$G$-$^$;$s!#$^$:$O!"(B + $B$3$l$i$NL>A0$,(B $B%5!<%P$KIU$1$i$l$?(B IP $B%"%I%l%9$K%^%C%W$5$l$k$h$&$K(B + DNS $B%5!<%P$rE,@Z$K@_Dj$7$J$1$l$P$J$j$^$;$s!#(B

    + +

    $B:G8e$K!"(BVirtualHost $B%3%s%F%J$NCf$K(B + $BB>$N%G%#%l%/%F%#%V$r=q$/$3$H$G!"%P!<%A%c%k%[%9%H$N@_Dj$r:Y$+$/D4@0(B + $B$9$k$3$H$,$G$-$^$9!#(B + $B$[$H$s$I$N%G%#%l%/%F%#%V$O$3$l$i$N%3%s%F%J$K@_CV$9$k$3$H$,$G$-$F!"(B + $BJQ99E@$O$=$N%P!<%A%c%k%[%9%H$KBP$7$F$N$_M-8z$K$J$j$^$9!#(B + $B$I$N%G%#%l%/%F%#%V$r=q$/$3$H$,$G$-$k$+$O!"%G%#%l%/%F%#%V$N(B $B%3%s%F%-%9%H(B $B$r(B + $BD4$Y$F$/$@$5$$!#(B$B + (VirtualHost + $B%3%s%F%J$N30(B) $B$N@_DjMQ%G%#%l%/%F%#%V$O%P!<%A%c%k%[%9%H$G$N@_Dj$G(B + $B>e=q$-$5$l$J$$>l9g$N$_;HMQ$5$l$^$9!#(B

    + +

    $B%j%/%(%9%H$,Mh$k$H!"%5!<%P$O$^$::G=i$K(B NameVirtualHost + $B$K%^%C%A$9$k(B IP $B%"%I%l%9$+$I$&$+$r%A%'%C%/$7$^$9!#%^%C%A$9$l$P(B + $B%^%C%A$7$?(B IP $B%"%I%l%9$N(B VirtualHost + $B$N$=$l$>$l$N%;%/%7%g%s$NCf$+$i(B + ServerName $B$+(B + ServerAlias + $B$KMW5a$5$l$?%[%9%HL>$,$"$k$+C5$7$^$9!#(B + $B8+$D$+$l$P$=$N%5!<%PMQ$N@_Dj$r;H$$$^$9!#%^%C%A$9$k%P!<%A%c%k%[%9%H(B + $B$,8+$D$+$i$J$1$l$P!"%^%C%A$7$?(B IP $B%"%I%l%9$N(B + $B%j%9%H$N:G=i$K$"$k%P!<%A%c%k%[%9%H(B $B$,;H$o$l$^$9!#(B

    + +

    $B7k2L$H$7$F!"%j%9%H$N:G=i$N%P!<%A%c%k%[%9%H$,(B $B%G%U%)%k%H(B $B$N(B + $B%P!<%A%c%k%[%9%H$K$J$j$^$9!#(BIP $B%"%I%l%9$,(B NameVirtualHost + $B%G%#%l%/%F%#%V$K%^%C%A$7$?>l9g$O!"(B$B%a%$%s$N%5!<%P(B $B$N(B + DocumentRoot + $B$O(B$B7h$7$F;H$o$l$^$;$s(B + $B$I$N%P!<%A%c%k%[%9%H$K$b%^%C%A$7$J$$%j%/%(%9%H$KBP$7$F!"(B + $BFCJL$J@_Dj$r$7$?$$$N$G$"$l$P!"@_Dj%U%!%$%kCf$N:G=i$N(B + <VirtualHost> $B%3%s%F%J$K$=$l$r5-=R$7$F$/$@$5$$!#(B

    + +
    + +
    $B8E$$%V%i%&%6$H$N8_49@-(B + +

    $B0JA0=R$Y$?$h$&$K!"L>A0%Y!<%9$N%P!<%A%c%k%[%9%H$,@5$7$/F0:n$9$k(B + $B$?$a$KI,MW$J>pJs$rAw$C$F$3$J$$%/%i%$%"%s%H$,0MA3$H$7$FB8:_$7$F$$$^$9!#(B + $B$=$N$h$&$J%/%i%$%"%s%H$KBP$7$F$O!"3:Ev$9$k(B IP $B%"%I%l%9$K$D$$$F!"(B + $B0lHV:G=i$K@_Dj$5$l$F$$$k%P!<%A%c%k%[%9%H(B + ($B%W%i%$%^%j(B$B$NL>A0%Y!<%9$N%P!<%A%c%k%[%9%H(B) + $B$+$i%Z!<%8$,Aw$jJV$5$l$^$9!#(B

    + + $B$I$N$0$i$$8E$$$N(B ? +

    $B!V8E$$!W$HI=8=$7$F$$$k>l9g!"K\Ev$K8E$$$3$H$r0UL#$7$F;H$C$F$$$^$9!#(B + $BIT9,$K$7$F:#8=:_$G$b$3$N$h$&$J8E$$%V%i%&%6$KAx6x$9$k$3$H$,$"$j$^$9!#(B + $B8=:_$N%V%i%&%6$OA4$F!"L>A0%Y!<%9$N%P!<%A%c%k%[%9%H$KI,MW$J(B + Host $B%X%C%@$rAw$j$^$9!#(B

    +
    + +

    ServerPath + $B%G%#%l%/%F%#%V$GBP=h$,2DG=$G$9!#$A$g$C$HIT3J9%$G$9$1$l$I$b!#(B

    + +

    $B@_DjNc(B

    + + + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +
    + +

    $B$3$NNc$K$O$I$&$$$&0UL#$,$"$k$G$7$g$&$+(B? $B$3$l$O(B + "/domain" $B$G;O$^$k(B URI $B$X$N%j%/%(%9%H$O$9$Y$F!"(B + $B%P!<%A%c%k%[%9%H(B www.domain.tld $B$G=hM}$5$l$k!"(B + $B$H$$$&0UL#$G$9!#$D$^$j!"$9$Y$F$N%/%i%$%"%s%H$G(B + http://www.domain.tld/domain/ $B$G%"%/%;%9$G$-$k%Z!<%8$,!"(B + Host: $B%X%C%@$rAw$C$F$/$k%/%i%$%"%s%H$G$"$l$P(B + http://www.domain.tld/ $B$H$7$F$b%"%/%;%9$G$-$k!"(B + $B$H$$$&0UL#$G$9!#(B

    + +

    $B$3$l$,F0:n$9$k$h$&$K$9$k$K$O!"(B + $B%W%i%$%^%j$N%P!<%A%c%k%[%9%H$N%Z!<%8$K(B + http://www.domain.tld/domain/ $B$X$N%j%s%/$r@_CV$7$^$9!#(B + $B$=$7$F!"%P!<%A%c%k%[%9%H$N%Z!<%8$G$O!"=c?h$JAjBP%j%s%/(B ($BNc(B: + "file.html" $B$d(B "../icons/image.gif")$B!"(B + $B$"$k$$$O(B /domain/ $B$G;O$^$k%j%s%/(B ($BNc(B: + "http://www.domain.tld/domain/misc/file.html" $B$d(B + "/domain/misc/file.html") $B$@$1$r@_CV$7$^$9!#(B

    + +

    $B$3$l$K$O!"4vJ,$+$N5,N'$,I,MW$H$J$j$^$9$,!"(B + $B$3$N$h$&$J%,%$%I%i%$%s$rCil9g!"(B + $B$9$Y$F$N%V%i%&%6$G(B $B!=(B $B?7$7$$%V%i%&%6$G$b8E$$$b$N$G$b(B $B!=(B + $B:n@.$7$?%Z!<%8$,8+$($k$H$$$&$3$H$rJ]>Z$7$^$9!#(B

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/name-based.xml.ko b/trunk/docs/manual/vhosts/name-based.xml.ko new file mode 100644 index 0000000000..6aa5894d26 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.xml.ko @@ -0,0 +1,264 @@ + + + + + + + + +°¡»óÈ£½ºÆ® +À̸§±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø + + +

    ÀÌ ¹®¼­´Â À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ´Â °æ¿ì¿Í ¹æ¹ýÀ» + ¼³¸íÇÑ´Ù.

    +
    + +IP±â¹Ý °¡»óÈ£½ºÆ® Áö¿ø +°¡»óÈ£½ºÆ® ã±â¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸í +´ë·®ÀÇ °¡»óÈ£½ºÆ®¸¦ µ¿ÀûÀ¸·Î ¼³Á¤Çϱâ +ÀϹÝÀûÀÎ °¡»óÈ£½ºÆ® ¿¹ +ServerPath ¼³Á¤ ¿¹ + +
    À̸§±â¹Ý ´ë IP±â¹Ý °¡»óÈ£½ºÆ® + +

    IP±â¹Ý °¡»óÈ£½ºÆ®´Â ¿¬°áÇÑ IP ÁÖ¼Ò¸¦ °¡Áö°í ¼­ºñ½ºÇÒ + °¡»óÈ£½ºÆ®¸¦ °áÁ¤ÇÑ´Ù. ±×·¡¼­ °¢ È£½ºÆ®´Â ¼­·Î ´Ù¸¥ IP ÁÖ¼Ò¸¦ + °¡Á®¾ß ÇÑ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®ÀÇ °æ¿ì ¼­¹ö´Â Ŭ¶óÀ̾ðÆ®°¡ + HTTP Çì´õ·Î È£½ºÆ®¸íÀ» ¾Ë·ÁÁÖ±æ ¹Ù¶õ´Ù. ÀÌ·± ¹æ¹ýÀ¸·Î ÇÑ + IP ÁÖ¼Ò·Î ¿©·¯ ´Ù¸¥ È£½ºÆ®¸¦ ¼­ºñ½ºÇÒ ¼ö ÀÖ´Ù.

    + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®´Â DNS ¼­¹ö°¡ °¢ È£½ºÆ®¸íÀÌ ¿Ã¹Ù¸¥ + IP ÁÖ¼Ò·Î ´ëÀÀÇϵµ·Ï °¡»óÈ£½ºÆ®¸¦ ¼³Á¤ÇÏ°í, ´Ù¸¥ È£½ºÆ®¸íÀ» ±¸º°ÇÒ + ¼ö ÀÖµµ·Ï ¾ÆÆÄÄ¡ À¥¼­¹ö¸¦ ¼³Á¤Çϱ⸸ ÇϸéµÇ¹Ç·Î ´õ °£´ÜÇÏ´Ù. À̸§±â¹Ý + °¡»óÈ£½ºÆ®´Â ¶Ç ¿©·¯ IP ÁÖ¼Ò°¡ ÇÊ¿ä¾ø´Ù. ±×·¯¹Ç·Î Ưº°È÷ + IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ ¼±ÅÃÇÒ ÀÌÀ¯°¡ ¾ø´Ù¸é À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ + »ç¿ëÇØ¾ß ÇÑ´Ù. IP±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇؾßÇÒ ÀÌÀ¯·Î´Â:

    + +
      +
    • À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ Áö¿øÇÏÁö¾Ê´Â ¿À·¡µÈ + Ŭ¶óÀ̾ðÆ®µéÀÌ ÀÖ´Ù. À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ·Á¸é + Ŭ¶óÀ̾ðÆ®°¡ HTTP Host Çì´õ¸¦ º¸³»¾ß ÇÑ´Ù. ÀÌ´Â + HTTP/1.1¿¡¼­´Â ÇʼöÀÌ°í, ÃÖ±Ù ¸ðµç HTTP/1.0 ºê¶ó¿ìÀúµéµµ + È®ÀåÀ¸·Î Áö¿øÇÑ´Ù. ¸¸¾à À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇϸ鼭 + ¿À·¡µÈ Ŭ¶óÀ̾ðÆ®¸¦ Áö¿øÇØ¾ß ÇÑ´Ù¸é ÀÌ ¹®¼­ ³¡¿¡ ÀÖ´Â + ¹æ¹ýÀ» »ìÆìºÁ¶ó.
    • + +
    • SSL ÇÁ·ÎÅäÄÝÀÇ ¼º°Ý»ó SSL º¸¾È¼­¹ö¿¡¼­ À̸§±â¹Ý + °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù.
    • + +
    • ¾î¶² ¿î¿µÃ¼Á¦³ª ³×Æ®¿÷ ÀåÄ¡´Â ´Ù¸¥ IP ÁÖ¼Ò¸¦ »ç¿ëÇÏÁö + ¾ÊÀ¸¸é È£½ºÆ®¸¦ ±¸º°ÇÏÁö ¸øÇÏ´Â ³×Æ®¿÷ »ç¿ë·®(bandwidth) + °ü¸®±â¼úÀ» »ç¿ëÇÑ´Ù.
    • +
    + +
    + +
    À̸§±â¹Ý °¡»óÈ£½ºÆ® »ç¿ëÇϱâ + + + + core + + + + DocumentRoot + NameVirtualHost + ServerAlias + ServerName + ServerPath + VirtualHost + + + +

    À̸§±â¹Ý °¡»óÈ£½ºÆ®¸¦ »ç¿ëÇÏ·Á¸é ¼­¹ö´Â ¿¬°áÀ» ¹ÞÀ» + IP ÁÖ¼Ò¸¦ (¾Æ¸¶ Æ÷Æ®µµ) Á¤ÇØ¾ß ÇÑ´Ù. ÀÌ´Â NameVirtualHost Áö½Ã¾î·Î °¡´ÉÇÏ´Ù. + ÀϹÝÀûÀ¸·Î ¼­¹öÀÇ ¸ðµç IP ÁÖ¼Ò¸¦ »ç¿ëÇÑ´Ù¸é + NameVirtualHostÀÇ + ¾Æ±Ô¸ÕÆ®·Î *¸¦ »ç¿ëÇÑ´Ù. ¿©·¯ Æ÷Æ®¸¦ »ç¿ëÇÒ + (¿¹¸¦ µé¾î, SSLÀ» »ç¿ëÇÒ) °èȹÀ̶ó¸é *:80°ú + °°ÀÌ ¾Æ±Ô¸ÕÆ®¿¡ Æ÷Æ®¸¦ Ãß°¡ÇØ¾ß ÇÑ´Ù. NameVirtualHost Áö½Ã¾î¿¡ IP ÁÖ¼Ò¸¦ + Àû¾îÁÖ¾ú´Ù°í ¼­¹ö°¡ ÀÚµ¿À¸·Î ±× IP ÁÖ¼Ò¸¦ ±â´Ù¸®Áö ¾ÊÀ½À» + ÁÖÀÇÇ϶ó. ÀÚ¼¼ÇÑ ³»¿ëÀº ¾ÆÆÄÄ¡°¡ + »ç¿ëÇÒ ÁÖ¼Ò¿Í Æ÷Æ® ¼³Á¤Çϱ⸦ Âü°íÇ϶ó. ¶Ç, ¿©±â¼­ + ÁöÁ¤ÇÑ IP ÁÖ¼Ò´Â ¼­¹öÀÇ ³×Æ®¿÷ ÀÎÅÍÆäÀ̽ºÀ̾î¾ß ÇÑ´Ù.

    + +

    ´ÙÀ½ ´Ü°è´Â ¼­ºñ½ºÇÏ·Á´Â È£½ºÆ®º°·Î VirtualHost ºí·ÏÀ» + ¸¸µå´Â ÀÏÀÌ´Ù. VirtualHost> Áö½Ã¾îÀÇ ¾Æ±Ô¸ÕÆ®´Â + NameVirtualHost Áö½Ã¾îÀÇ + ¾Æ±Ô¸ÕÆ®(¿¹¸¦ µé¾î, IP ÁÖ¼Ò³ª ¸ðµç ÁÖ¼Ò¸¦ ¶æÇÏ´Â *)¿Í + °°¾Æ¾ß ÇÑ´Ù. VirtualHost> ºí·Ï ¾È¿¡´Â + ÃÖ¼ÒÇÑ ¼­ºñ½ºÇÒ È£½ºÆ®¸¦ ÁöÁ¤ÇÏ´Â ServerName Áö½Ã¾î¿Í È£½ºÆ®ÀÇ + ³»¿ëÀÌ ÆÄÀϽýºÅÛ ¾îµð¿¡ ÀÖ´ÂÁö¸¦ ÁöÁ¤ÇÏ´Â DocumentRoot Áö½Ã¾î°¡ ÇÊ¿äÇÏ´Ù.

    + + ÁÖ È£½ºÆ®°¡ ¾ø¾îÁø´Ù +

    ±âÁ¸¿¡ »ç¿ëÇÏ´ø À¥¼­¹ö¿¡ °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇÑ´Ù¸é + ±âÁ¸¿¡ »ç¿ëÇÏ´ø È£½ºÆ®¿¡ ´ëÇÑ VirtualHost ºí·Ïµµ Ãß°¡ÇØ¾ß + ÇÑ´Ù. ÀÌ ºí·Ï¿¡ Æ÷ÇÔÇÏ´Â ServerName°ú DocumentRoot´Â Àüü ServerName°ú DocumentRoot¿Í °°¾Æ¾ß ÇÑ´Ù. + ¼³Á¤ÆÄÀÏ¿¡¼­ ÀÌ °¡»óÈ£½ºÆ®¸¦ °¡Àå ¸ÕÀú ÀûÀ¸¸é ±âº» È£½ºÆ®°¡ + µÈ´Ù.

    +
    + +

    ¿¹¸¦ µé¾î www.domain.tld µµ¸ÞÀÎÀ» ¼­ºñ½ºÇÏ°í + ÀÖ¾ú´Âµ¥ °°Àº IP ÁÖ¼Ò¿¡ + www.otherdomain.tld¶õ °¡»óÈ£½ºÆ®¸¦ Ãß°¡ÇÏ°í + ½Í´Ù°í °¡Á¤ÇÏÀÚ. httpd.conf¿¡ ´ÙÀ½°ú °°ÀÌ + Ãß°¡ÇÏ¸é µÈ´Ù:

    + + + NameVirtualHost *:80
    +
    + <VirtualHost *:80>
    + + ServerName www.domain.tld
    + ServerAlias domain.tld *.domain.tld
    + DocumentRoot /www/domain
    +
    + </VirtualHost>
    +
    + <VirtualHost *:80>
    + ServerName www.otherdomain.tld
    + DocumentRoot /www/otherdomain
    +
    + </VirtualHost>
    +
    + +

    NameVirtualHost¿Í + VirtualHost + Áö½Ã¾î µÑ ¸ðµÎ * ´ë½Å Á÷Á¢ IP ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ + ¼öµµ ÀÖ´Ù. ¿¹¸¦ µé¾î, ÀÌ·±½ÄÀ¸·Î ÇÑ IP ÁÖ¼Ò¿¡ ¿©·¯ À̸§±â¹Ý + °¡»óÈ£½ºÆ®µéÀ» µ¹¸®°í, ´Ù¸¥ ÁÖ¼Ò¿¡ IP±â¹Ý ȤÀº À̸§±â¹Ý + °¡»óÈ£½ºÆ®µéÀ» µ¹¸± ¼ö ÀÖ´Ù.

    + +

    ¾î¶² ¼­¹ö´Â ¿©·¯ À̸§À¸·Î Á¢¼ÓÇÒ ¼ö ÀÖ±æ ¹Ù¶õ´Ù. ÀÌ´Â + VirtualHost + ¼½¼Ç ¾È¿¡ ServerAlias + Áö½Ã¾î¸¦ »ç¿ëÇÏ¿© °¡´ÉÇÏ´Ù. ¿¹¸¦ µé¾î À§ÀÇ Ã¹¹ø° VirtualHost ºí·Ï¿¡¼­ + ServerAlias Áö½Ã¾î¸¦ + »ç¿ëÇÏ¸é ¿­°ÅÇÑ À̸§À¸·Î °°Àº À¥»çÀÌÆ®¸¦ º¼ ¼ö ÀÖ´Ù:

    + + + ServerAlias domain.tld *.domain.tld + + +

    domain.tld µµ¸ÞÀο¡ ÀÖ´Â ¸ðµç È£½ºÆ®¿¡ ´ëÇÑ + ¿äûÀ» www.domain.tld °¡»óÈ£½ºÆ®°¡ ¼­ºñ½ºÇÑ´Ù. + À̸§À» ÁÙ¶§ ¿ÍÀϵåÄ«µå ¹®ÀÚ *¿Í ?¸¦ + »ç¿ëÇÒ ¼ö ÀÖ´Ù. ¹°·Ð ServerNameÀ̳ª ServerAlias¿¡ + À̸§À» Àû¾îÁÖ¾ú´Ù°í ³¡ÀÌ ¾Æ´Ï´Ù. ¸ÕÀú ÀÌ À̸§µéÀÌ ¼­¹öÀÇ + IP ÁÖ¼Ò·Î ´ëÀÀÇϵµ·Ï DNS ¼­¹ö¸¦ ¾Ë¸Â°Ô ¼³Á¤ÇØ¾ß ÇÑ´Ù.

    + +

    ¸¶Áö¸·À¸·Î <VirtualHost> ¾È¿¡ ´Ù¸¥ + Áö½Ã¾îµéÀ» »ç¿ëÇÏ¿© °¡»óÈ£½ºÆ®¸¦ ÀÚ¼¼È÷ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. + ´ëºÎºÐÀÇ Áö½Ã¾î¸¦ »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, °ü·ÃµÈ °¡»óÈ£½ºÆ®ÀÇ ¼³Á¤¸¸À» + º¯°æÇÑ´Ù. ¾î¶² Áö½Ã¾î°¡ »ç¿ë°¡´ÉÇÑÁö ¾Ë·Á¸é Áö½Ã¾îÀÇ »ç¿ëÀå¼Ò¸¦ + È®ÀÎÇ϶ó. (<VirtualHost> ¾ÈÀÌ ¾Æ´Ñ) + ÁÖ¼­¹ö¼³Á¤¿¡¼­ ÁöÁ¤ÇÑ ¼³Á¤ Áö½Ã¾î´Â °¡»óÈ£½ºÆ®¿¡ + °°Àº ¼³Á¤ Áö½Ã¾î°¡ ¾ø´Â °æ¿ì¿¡¸¸ »ç¿ëµÈ´Ù.

    + +

    ¿äûÀ» ¹ÞÀ¸¸é ¼­¹ö´Â ¸ÕÀú NameVirtualHost¿¡¼­ ÁöÁ¤ÇÑ IP + ÁÖ¼ÒÀÎÁö °Ë»çÇÑ´Ù. ±×·¸´Ù¸é ±× IP ÁÖ¼Ò¸¦ °¡Áø VirtualHost + ¼½¼Çµé¿¡¼­ ¿äûÇÑ È£½ºÆ®¸í°ú ÀÏÄ¡ÇÏ´Â ServerNameÀ̳ª + ServerAlias¸¦ ã´Â´Ù. ãÀ¸¸é ±× ¼³Á¤À» »ç¿ëÇÑ´Ù. + ÀûÀýÇÑ °¡»óÈ£½ºÆ®¸¦ ãÁö¸øÇϸé, IP ÁÖ¼Ò¿¡ ÇØ´çÇÏ´Â + °¡»óÈ£½ºÆ®µéÁß Ã¹¹ø° °ÍÀ» »ç¿ëÇÑ´Ù.

    + +

    °á°úÀûÀ¸·Î óÀ½¿¡ ³ª¿Â °¡»óÈ£½ºÆ®°¡ ±âº» + °¡»óÈ£½ºÆ®°¡ µÈ´Ù. IP ÁÖ¼Ò°¡ NameVirtualHost Áö½Ã¾î¿¡ ÇØ´çÇϸé, + ÁÖ¼­¹öÀÇ DocumentRoot´Â + Àý´ë·Î »ç¿ëÇÏÁö ¾Ê´Â´Ù. ƯÁ¤ °¡»óÈ£½ºÆ®¿¡ + ÇØ´çÇÏÁö¾Ê´Â ¿äûÀ» ¼³Á¤ÇÏ·Á¸é ¼³Á¤À» VirtualHost¿¡ ´ã°í ¼³Á¤ÆÄÀÏ¿¡¼­ + ¸ÕÀú ³ª¿Àµµ·Ï ÇÏ¸é µÈ´Ù.

    + +
    + +
    ¿À·¡µÈ ºê¶ó¿ìÀú¿Í ȣȯ + +

    ÀÌ¹Ì Àû¾úµíÀÌ À̸§±â¹Ý °¡»óÈ£½ºÆ®°¡ ¿Ã¹Ù·Î µ¿ÀÛÇϱâÀ§ÇØ + ÇÊ¿äÇÑ Á¤º¸¸¦ º¸³»Áö¾Ê´Â Ŭ¶óÀ̾ðÆ®°¡ ÀÖ´Ù. ÀÌ·± Ŭ¶óÀ̾ðÆ®´Â + Ç×»ó ¿äûÇÑ IP ÁÖ¼Ò¿¡ ´ëÇØ Ã¹¹ø°·Î ³ª¿À´Â °¡»óÈ£½ºÆ® + (ÃÖÃÊÀÇ À̸§±â¹Ý °¡»óÈ£½ºÆ®)°¡ + ¼­ºñ½ºÇÑ´Ù.

    + + ¾ó¸¶³ª ¿À·¡µÈ °ÍÀ» ¸»Çϴ°¡? +

    ¿©±â¼­ ¿À·¡µÇ¾úÀ½Àº ½ÇÁ¦·Î »ó´çÈ÷ ¿À·¡µÈ °ÍÀ» ¶æÇÑ´Ù. + ¿À´Ã³¯ ÀÌ·± ºê¶ó¿ìÀú¸¦ »ç¿ëÇÒ ÀÏÀº °ÅÀǾø´Ù. ¿äÁò + ºê¶ó¿ìÀú´Â ¸ðµÎ À̸§±â¹Ý °¡»óÈ£½ºÆ®¿¡ ÇÊ¿äÇÑ Host + Çì´õ¸¦ º¸³½´Ù.

    +
    + +

    ÀÌ ¹®Á¦´Â ¾à°£ °ÅÃßÀ彺·´Áö¸¸ ServerPath Áö½Ã¾î·Î ÇØ°áÇÒ ¼ö ÀÖ´Ù:

    + +

    ¼³Á¤ ¿¹:

    + + + NameVirtualHost 111.22.33.44
    +
    + <VirtualHost 111.22.33.44>
    + + ServerName www.domain.tld
    + ServerPath /domain
    + DocumentRoot /web/domain
    +
    + </VirtualHost>
    +
    + +

    ÀÌ°Ô ¹«½¼ ¶æÀΰ¡? "/domain"·Î ½ÃÀÛÇÏ´Â + URI¿¡ ´ëÇÑ ¿äûÀº °¡»óÈ£½ºÆ® www.domain.tld°¡ + ¼­ºñ½ºÇÑ´Ù. Áï, Host: Çì´õ¸¦ º¸³»´Â Ŭ¶óÀ̾ðÆ®´Â + http://www.domain.tld/¸¸À¸·Îµµ Á¢±ÙÇÒ ¼ö ÀÖÁö¸¸, + http://www.domain.tld/domain/À¸·Î´Â ¸ðµç + Ŭ¶óÀ̾ðÆ®°¡ ÆäÀÌÁö¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

    + +

    À̸¦ À§ÇØ ÃÖÃÊÀÇ °¡»óÈ£½ºÆ®¿¡ ÀÖ´Â ÆäÀÌÁö¿¡ + http://www.domain.tld/domain/À¸·Î °¡´Â ¸µÅ©¸¦ + ³Ö´Â´Ù. ±×¸®°í °¡»óÈ£½ºÆ® ÆäÀÌÁö¿¡¼­´Â »ó´ë¸µÅ© (¿¹¸¦ µé¾î, + "file.html" À̳ª "../icons/image.gif") + ȤÀº ("http://www.domain.tld/domain/misc/file.html"À̳ª + "/domain/misc/file.html"°ú °°ÀÌ) ¾Õ¿¡ + /domain/ÀÌ ºÙÀº ¸µÅ©¸¸À» »ç¿ëÇÑ´Ù.

    + +

    Á¶±Ý ±ÔÄ¢ÀÌ ÇÊ¿äÇÏÁö¸¸ ÀÌ ±ÔÄ¢À» µû¸£¸é ´ëºÎºÐÀÇ °æ¿ì + ¿äÁò °ÍÀ̳ª ¿À·¡µÈ °ÍÀ̳ª °ü°è¾øÀÌ ¸ðµç ºê¶ó¿ìÀú·Î ÆäÀÌÁö¸¦ + º¼ ¼ö ÀÖ´Ù.

    + +
    +
    diff --git a/trunk/docs/manual/vhosts/name-based.xml.meta b/trunk/docs/manual/vhosts/name-based.xml.meta new file mode 100644 index 0000000000..5c011302e2 --- /dev/null +++ b/trunk/docs/manual/vhosts/name-based.xml.meta @@ -0,0 +1,14 @@ + + + + name-based + /vhosts/ + .. + + + de + en + ja + ko + + diff --git a/trunk/emacs-style b/trunk/emacs-style new file mode 100644 index 0000000000..7ca4f40414 --- /dev/null +++ b/trunk/emacs-style @@ -0,0 +1,12 @@ +(add-hook 'c-mode-hook + (function (lambda () + (c-set-offset 'inclass' ++) + (c-set-offset 'defun-block-intro' ++) + (c-set-offset 'statement-block-intro' ++) + (c-set-offset 'substatement' ++) + (c-set-offset 'brace-list-intro' ++) + (c-set-offset 'statement-case-intro' ++) + (c-set-offset 'inextern-lang' 0) + ))) +(setq c++-mode-hook c-mode-hook) +(setq-default indent-tabs-mode nil) diff --git a/trunk/httpd.dsp b/trunk/httpd.dsp new file mode 100644 index 0000000000..27482fed3d --- /dev/null +++ b/trunk/httpd.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="httpd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=httpd - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "httpd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "httpd.mak" CFG="httpd - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "httpd - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "httpd - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "httpd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "SHARED_MODULE" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Fd"Release\httpd" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "httpd - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /Fd"Debug\httpd" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /stack:0x40000 /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "httpd - Win32 Release" +# Name "httpd - Win32 Debug" +# Begin Source File + +SOURCE=.\build\win32\Apache.ico +# End Source File +# Begin Source File + +SOURCE=.\build\win32\httpd.rc +# End Source File +# Begin Source File + +SOURCE=.\server\main.c +# End Source File +# Begin Source File + +SOURCE=.\build\win32\win32ver.awk + +!IF "$(CFG)" == "httpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=.\build\win32\win32ver.awk + +".\build\win32\httpd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ./build/win32/win32ver.awk httpd.exe "Apache HTTP Server" ./include/ap_release.h icon=apache.ico > .\build\win32\httpd.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "httpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=.\build\win32\win32ver.awk + +".\build\win32\httpd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ./build/win32/win32ver.awk httpd.exe "Apache HTTP Server" ./include/ap_release.h icon=apache.ico > .\build\win32\httpd.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/include/.indent.pro b/trunk/include/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/include/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/include/ap_compat.h b/trunk/include/ap_compat.h new file mode 100644 index 0000000000..4c25b0ad9d --- /dev/null +++ b/trunk/include/ap_compat.h @@ -0,0 +1,25 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_COMPAT_H +#define AP_COMPAT_H + +/* redefine 1.3.x symbols to the new symbol names */ + +#define MODULE_VAR_EXPORT AP_MODULE_DECLARE_DATA +#define ap_send_http_header(r) ; + +#endif /* AP_COMPAT_H */ diff --git a/trunk/include/ap_config.h b/trunk/include/ap_config.h new file mode 100644 index 0000000000..cfcd04ac95 --- /dev/null +++ b/trunk/include/ap_config.h @@ -0,0 +1,252 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_CONFIG_H +#define AP_CONFIG_H + +#include "apr.h" +#include "apr_hooks.h" +#include "apr_optional_hooks.h" + +/** + * @file ap_config.h + * @brief Symbol export macros and hook functions + */ + +/* Although this file doesn't declare any hooks, declare the hook group here */ +/** @defgroup hooks Apache Hooks */ + +#ifdef DOXYGEN +/* define these just so doxygen documents them */ + +/** + * AP_DECLARE_STATIC is defined when including Apache's Core headers, + * to provide static linkage when the dynamic library may be unavailable. + * + * @see AP_DECLARE_EXPORT + * + * AP_DECLARE_STATIC and AP_DECLARE_EXPORT are left undefined when + * including Apache's Core headers, to import and link the symbols from the + * dynamic Apache Core library and assure appropriate indirection and calling + * conventions at compile time. + */ +# define AP_DECLARE_STATIC +/** + * AP_DECLARE_EXPORT is defined when building the Apache Core dynamic + * library, so that all public symbols are exported. + * + * @see AP_DECLARE_STATIC + */ +# define AP_DECLARE_EXPORT + +#endif /* def DOXYGEN */ + +#if !defined(WIN32) +/** + * Apache Core dso functions are declared with AP_DECLARE(), so they may + * use the most appropriate calling convention. Hook functions and other + * Core functions with variable arguments must use AP_DECLARE_NONSTD(). + * @code + * AP_DECLARE(rettype) ap_func(args) + * @endcode + */ +#define AP_DECLARE(type) type + +/** + * Apache Core dso variable argument and hook functions are declared with + * AP_DECLARE_NONSTD(), as they must use the C language calling convention. + * @see AP_DECLARE + * @code + * AP_DECLARE_NONSTD(rettype) ap_func(args [...]) + * @endcode + */ +#define AP_DECLARE_NONSTD(type) type + +/** + * Apache Core dso variables are declared with AP_MODULE_DECLARE_DATA. + * This assures the appropriate indirection is invoked at compile time. + * + * @note AP_DECLARE_DATA extern type apr_variable; syntax is required for + * declarations within headers to properly import the variable. + * @code + * AP_DECLARE_DATA type apr_variable + * @endcode + */ +#define AP_DECLARE_DATA + +#elif defined(AP_DECLARE_STATIC) +#define AP_DECLARE(type) type __stdcall +#define AP_DECLARE_NONSTD(type) type +#define AP_DECLARE_DATA +#elif defined(AP_DECLARE_EXPORT) +#define AP_DECLARE(type) __declspec(dllexport) type __stdcall +#define AP_DECLARE_NONSTD(type) __declspec(dllexport) type +#define AP_DECLARE_DATA __declspec(dllexport) +#else +#define AP_DECLARE(type) __declspec(dllimport) type __stdcall +#define AP_DECLARE_NONSTD(type) __declspec(dllimport) type +#define AP_DECLARE_DATA __declspec(dllimport) +#endif + +#if !defined(WIN32) || defined(AP_MODULE_DECLARE_STATIC) +/** + * Declare a dso module's exported module structure as AP_MODULE_DECLARE_DATA. + * + * Unless AP_MODULE_DECLARE_STATIC is defined at compile time, symbols + * declared with AP_MODULE_DECLARE_DATA are always exported. + * @code + * module AP_MODULE_DECLARE_DATA mod_tag + * @endcode + */ +#if defined(WIN32) +#define AP_MODULE_DECLARE(type) type __stdcall +#else +#define AP_MODULE_DECLARE(type) type +#endif +#define AP_MODULE_DECLARE_NONSTD(type) type +#define AP_MODULE_DECLARE_DATA +#else +/** + * AP_MODULE_DECLARE_EXPORT is a no-op. Unless contradicted by the + * AP_MODULE_DECLARE_STATIC compile-time symbol, it is assumed and defined. + * + * The old SHARED_MODULE compile-time symbol is now the default behavior, + * so it is no longer referenced anywhere with Apache 2.0. + */ +#define AP_MODULE_DECLARE_EXPORT +#define AP_MODULE_DECLARE(type) __declspec(dllexport) type __stdcall +#define AP_MODULE_DECLARE_NONSTD(type) __declspec(dllexport) type +#define AP_MODULE_DECLARE_DATA __declspec(dllexport) +#endif + +/** + * Declare a hook function + * @param ret The return type of the hook + * @param name The hook's name (as a literal) + * @param args The arguments the hook function takes, in brackets. + */ +#define AP_DECLARE_HOOK(ret,name,args) \ + APR_DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args) + +/** @internal */ +#define AP_IMPLEMENT_HOOK_BASE(name) \ + APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ap,AP,name) + +/** + * Implement an Apache core hook that has no return code, and + * therefore runs all of the registered functions. The implementation + * is called ap_run_name. + * + * @param name The name of the hook + * @param args_decl The declaration of the arguments for the hook, for example + * "(int x,void *y)" + * @param args_use The arguments for the hook as used in a call, for example + * "(x,y)" + * @note If IMPLEMENTing a hook that is not linked into the Apache core, + * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_VOID. + */ +#define AP_IMPLEMENT_HOOK_VOID(name,args_decl,args_use) \ + APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ap,AP,name,args_decl,args_use) + +/** + * Implement an Apache core hook that runs until one of the functions + * returns something other than ok or decline. That return value is + * then returned from the hook runner. If the hooks run to completion, + * then ok is returned. Note that if no hook runs it would probably be + * more correct to return decline, but this currently does not do + * so. The implementation is called ap_run_name. + * + * @param ret The return type of the hook (and the hook runner) + * @param name The name of the hook + * @param args_decl The declaration of the arguments for the hook, for example + * "(int x,void *y)" + * @param args_use The arguments for the hook as used in a call, for example + * "(x,y)" + * @param ok The "ok" return value + * @param decline The "decline" return value + * @return ok, decline or an error. + * @note If IMPLEMENTing a hook that is not linked into the Apache core, + * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL. + */ +#define AP_IMPLEMENT_HOOK_RUN_ALL(ret,name,args_decl,args_use,ok,decline) \ + APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap,AP,ret,name,args_decl, \ + args_use,ok,decline) + +/** + * Implement a hook that runs until a function returns something other than + * decline. If all functions return decline, the hook runner returns decline. + * The implementation is called ap_run_name. + * + * @param ret The return type of the hook (and the hook runner) + * @param name The name of the hook + * @param args_decl The declaration of the arguments for the hook, for example + * "(int x,void *y)" + * @param args_use The arguments for the hook as used in a call, for example + * "(x,y)" + * @param decline The "decline" return value + * @return decline or an error. + * @note If IMPLEMENTing a hook that is not linked into the Apache core + * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST. + */ +#define AP_IMPLEMENT_HOOK_RUN_FIRST(ret,name,args_decl,args_use,decline) \ + APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap,AP,ret,name,args_decl, \ + args_use,decline) + +/* Note that the other optional hook implementations are straightforward but + * have not yet been needed + */ + +/** + * Implement an optional hook. This is exactly the same as a standard hook + * implementation, except the hook is optional. + * @see AP_IMPLEMENT_HOOK_RUN_ALL + */ +#define AP_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ret,name,args_decl,args_use,ok, \ + decline) \ + APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap,AP,ret,name,args_decl, \ + args_use,ok,decline) + +/** + * Hook an optional hook. Unlike static hooks, this uses a macro instead of a + * function. + */ +#define AP_OPTIONAL_HOOK(name,fn,pre,succ,order) \ + APR_OPTIONAL_HOOK(ap,name,fn,pre,succ,order) + +#include "os.h" +#if !defined(WIN32) && !defined(NETWARE) +#include "ap_config_auto.h" +#include "ap_config_layout.h" +#endif +#if defined(NETWARE) +#define AP_NONBLOCK_WHEN_MULTI_LISTEN 1 +#endif + +/* TODO - We need to put OS detection back to make all the following work */ + +#if defined(SUNOS4) || defined(IRIX) || defined(NEXT) || defined(AUX3) \ + || defined (UW) || defined(LYNXOS) || defined(TPF) +/* These systems don't do well with any lingering close code; I don't know + * why -- manoj */ +#define NO_LINGCLOSE +#endif + +/* If APR has OTHER_CHILD logic, use reliable piped logs. */ +#if APR_HAS_OTHER_CHILD +#define AP_HAVE_RELIABLE_PIPED_LOGS TRUE +#endif + +#endif /* AP_CONFIG_H */ diff --git a/trunk/include/ap_config_layout.h.in b/trunk/include/ap_config_layout.h.in new file mode 100644 index 0000000000..74397ffe96 --- /dev/null +++ b/trunk/include/ap_config_layout.h.in @@ -0,0 +1,58 @@ +/* Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_CONFIG_LAYOUT_H +#define AP_CONFIG_LAYOUT_H + +/* Configured Apache directory layout */ +#define DEFAULT_PREFIX "@prefix@" +#define DEFAULT_EXP_EXEC_PREFIX "@exp_exec_prefix@" +#define DEFAULT_REL_EXEC_PREFIX "@rel_exec_prefix@" +#define DEFAULT_EXP_BINDIR "@exp_bindir@" +#define DEFAULT_REL_BINDIR "@rel_bindir@" +#define DEFAULT_EXP_SBINDIR "@exp_sbindir@" +#define DEFAULT_REL_SBINDIR "@rel_sbindir@" +#define DEFAULT_EXP_LIBEXECDIR "@exp_libexecdir@" +#define DEFAULT_REL_LIBEXECDIR "@rel_libexecdir@" +#define DEFAULT_EXP_MANDIR "@exp_mandir@" +#define DEFAULT_REL_MANDIR "@rel_mandir@" +#define DEFAULT_EXP_SYSCONFDIR "@exp_sysconfdir@" +#define DEFAULT_REL_SYSCONFDIR "@rel_sysconfdir@" +#define DEFAULT_EXP_DATADIR "@exp_datadir@" +#define DEFAULT_REL_DATADIR "@rel_datadir@" +#define DEFAULT_EXP_INSTALLBUILDDIR "@exp_installbuilddir@" +#define DEFAULT_REL_INSTALLBUILDDIR "@rel_installbuilddir@" +#define DEFAULT_EXP_ERRORDIR "@exp_errordir@" +#define DEFAULT_REL_ERRORDIR "@rel_errordir@" +#define DEFAULT_EXP_ICONSDIR "@exp_iconsdir@" +#define DEFAULT_REL_ICONSDIR "@rel_iconsdir@" +#define DEFAULT_EXP_HTDOCSDIR "@exp_htdocsdir@" +#define DEFAULT_REL_HTDOCSDIR "@rel_htdocsdir@" +#define DEFAULT_EXP_MANUALDIR "@exp_manualdir@" +#define DEFAULT_REL_MANUALDIR "@rel_manualdir@" +#define DEFAULT_EXP_CGIDIR "@exp_cgidir@" +#define DEFAULT_REL_CGIDIR "@rel_cgidir@" +#define DEFAULT_EXP_INCLUDEDIR "@exp_includedir@" +#define DEFAULT_REL_INCLUDEDIR "@rel_includedir@" +#define DEFAULT_EXP_LOCALSTATEDIR "@exp_localstatedir@" +#define DEFAULT_REL_LOCALSTATEDIR "@rel_localstatedir@" +#define DEFAULT_EXP_RUNTIMEDIR "@exp_runtimedir@" +#define DEFAULT_REL_RUNTIMEDIR "@rel_runtimedir@" +#define DEFAULT_EXP_LOGFILEDIR "@exp_logfiledir@" +#define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@" +#define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@" +#define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@" + +#endif /* AP_CONFIG_LAYOUT_H */ diff --git a/trunk/include/ap_listen.h b/trunk/include/ap_listen.h new file mode 100644 index 0000000000..7f456c569d --- /dev/null +++ b/trunk/include/ap_listen.h @@ -0,0 +1,102 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_LISTEN_H +#define AP_LISTEN_H + +#include "apr_network_io.h" +#include "httpd.h" +#include "http_config.h" + +/** + * @package Apache Listeners Library + */ + +typedef struct ap_listen_rec ap_listen_rec; +typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans); + +/** + * Apache's listeners record. These are used in the Multi-Processing Modules + * to setup all of the sockets for the MPM to listen to and accept on. + */ +struct ap_listen_rec { + /** + * The next listener in the list + */ + ap_listen_rec *next; + /** + * The actual socket + */ + apr_socket_t *sd; + /** + * The sockaddr the socket should bind to + */ + apr_sockaddr_t *bind_addr; + /** + * The accept function for this socket + */ + accept_function accept_func; + /** + * Is this socket currently active + */ + int active; +/* more stuff here, like which protocol is bound to the port */ +}; + +/** + * The global list of ap_listen_rec structures + */ +AP_DECLARE_DATA extern ap_listen_rec *ap_listeners; + +/** + * Setup all of the defaults for the listener list + */ +AP_DECLARE(void) ap_listen_pre_config(void); + +/** + * Loop through the global ap_listen_rec list and create all of the required + * sockets. This executes the listen and bind on the sockets. + * @param s The global server_rec + * @return The number of open sockets. + */ +AP_DECLARE(int) ap_setup_listeners(server_rec *s); + +/* Although these functions are exported from libmain, they are not really + * public functions. These functions are actually called while parsing the + * config file, when one of the LISTEN_COMMANDS directives is read. These + * should not ever be called by external modules. ALL MPMs should include + * LISTEN_COMMANDS in their command_rec table so that these functions are + * called. + */ +AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg); +AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips); +AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, + const char *arg); +AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, + void *dummy, + const char *arg); + +#define LISTEN_COMMANDS \ +AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ + "Maximum length of the queue of pending connections, as used by listen(2)"), \ +AP_INIT_TAKE1("Listen", ap_set_listener, NULL, RSRC_CONF, \ + "A port number or a numeric IP address and a port number"), \ +AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ + "Send buffer size in bytes"), \ +AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ + RSRC_CONF, "Receive buffer size in bytes") + +#endif diff --git a/trunk/include/ap_mmn.h b/trunk/include/ap_mmn.h new file mode 100644 index 0000000000..96245efe0d --- /dev/null +++ b/trunk/include/ap_mmn.h @@ -0,0 +1,134 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_AP_MMN_H +#define APACHE_AP_MMN_H + +/** + * @package Module Magic Number + */ + +/* + * MODULE_MAGIC_NUMBER_MAJOR + * Major API changes that could cause compatibility problems for older modules + * such as structure size changes. No binary compatibility is possible across + * a change in the major version. + * + * MODULE_MAGIC_NUMBER_MINOR + * Minor API changes that do not cause binary compatibility problems. + * Should be reset to 0 when upgrading MODULE_MAGIC_NUMBER_MAJOR. + * + * See the MODULE_MAGIC_AT_LEAST macro below for an example. + */ + +/* + * 20010224 (2.0.13-dev) MODULE_MAGIC_COOKIE reset to "AP20" + * 20010523 (2.0.19-dev) bump for scoreboard structure reordering + * 20010627 (2.0.19-dev) more API changes than I can count + * 20010726 (2.0.22-dev) more big API changes + * 20010808 (2.0.23-dev) dir d_is_absolute bit introduced, bucket changes, etc + * 20010825 (2.0.25-dev) removed d_is_absolute, introduced map_to_storage hook + * 20011002 (2.0.26-dev) removed 1.3-depreciated request_rec.content_language + * 20011127 (2.0.29-dev) bump for postconfig hook change, and removal of socket + * from connection record + * 20011212 (2.0.30-dev) bump for new used_path_info member of request_rec + * 20011218 (2.0.30-dev) bump for new sbh member of conn_rec, different + * declarations for scoreboard, new parameter to + * create_connection hook + * 20020102 (2.0.30-dev) bump for changed type of limit_req_body in + * core_dir_config + * 20020109 (2.0.31-dev) bump for changed shm and scoreboard declarations + * 20020111 (2.0.31-dev) bump for ETag fields added at end of cor_dir_config + * 20020114 (2.0.31-dev) mod_dav changed how it asks its provider to fulfill + * a GET request + * 20020118 (2.0.31-dev) Input filtering split of blocking and mode + * 20020127 (2.0.31-dev) bump for pre_mpm hook change + * 20020128 (2.0.31-dev) bump for pre_config hook change + * 20020218 (2.0.33-dev) bump for AddOutputFilterByType directive + * 20020220 (2.0.33-dev) bump for scoreboard.h structure change + * 20020302 (2.0.33-dev) bump for protocol_filter additions. + * 20020306 (2.0.34-dev) bump for filter type renames. + * 20020318 (2.0.34-dev) mod_dav's API for REPORT generation changed + * 20020319 (2.0.34-dev) M_INVALID changed, plus new M_* methods for RFC 3253 + * 20020327 (2.0.35-dev) Add parameter to quick_handler hook + * 20020329 (2.0.35-dev) bump for addition of freelists to bucket API + * 20020329.1 (2.0.36) minor bump for new arg to opt fn ap_cgi_build_command + * 20020506 (2.0.37-dev) Removed r->boundary in request_rec. + * 20020529 (2.0.37-dev) Standardized the names of some apr_pool_*_set funcs + * 20020602 (2.0.37-dev) Bucket API change (metadata buckets) + * 20020612 (2.0.38-dev) Changed server_rec->[keep_alive_]timeout to apr time + * 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration + * 20020628 (2.0.40-dev) Added filter_init to filter registration functions + * 20020903 (2.0.41-dev) APR's error constants changed + * 20020903.1 (2.1.0-dev) allow_encoded_slashes added to core_dir_config + * 20020903.2 (2.0.46-dev) add ap_escape_logitem + * 20030213.1 (2.1.0-dev) changed log_writer optional fn's to return previous + * handler + * 20030821 (2.1.0-dev) bumped mod_include's entire API + * 20030821.1 (2.1.0-dev) added XHTML doctypes + * 20030821.2 (2.1.0-dev) added ap_escape_errorlog_item + * 20030821.3 (2.1.0-dev) added ap_get_server_revision / ap_version_t + * 20040425 (2.1.0-dev) removed ap_add_named_module API + * changed ap_add_module, ap_add_loaded_module, + * ap_setup_prelinked_modules, ap_process_resource_config + * 20040425.1 (2.1.0-dev) Added ap_module_symbol_t and ap_prelinked_module_symbols + * 20050101.0 (2.1.2-dev) Axed misnamed http_method for http_scheme (which it was!) + * 20050127.0 (2.1.3-dev) renamed regex_t->ap_regex_t, regmatch_t->ap_regmatch_t, + * REG_*->AP_REG_*, removed reg* in place of ap_reg*; + * added ap_regex.h + * 20050217.0 (2.1.3-dev) Axed find_child_by_pid, mpm_*_completion_context (winnt mpm) + * symbols from the public sector, and decorated real_exit_code + * with ap_ in the win32 os.h. + * 20050305.0 (2.1.4-dev) added pid and generation fields to worker_score + * 20050305.1 (2.1.5-dev) added ap_vhost_iterate_given_conn. + * 20050305.2 (2.1.5-dev) added AP_INIT_TAKE_ARGV. + */ + +#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */ + +#ifndef MODULE_MAGIC_NUMBER_MAJOR +#define MODULE_MAGIC_NUMBER_MAJOR 20050305 +#endif +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ + +/** + * Determine if the server's current MODULE_MAGIC_NUMBER is at least a + * specified value. + *
    + * Useful for testing for features.
    + * For example, suppose you wish to use the apr_table_overlap
    + *    function.  You can do this:
    + * 
    + * #if AP_MODULE_MAGIC_AT_LEAST(19980812,2)
    + *     ... use apr_table_overlap()
    + * #else
    + *     ... alternative code which doesn't use apr_table_overlap()
    + * #endif
    + * 
    + * @param major The major module magic number + * @param minor The minor module magic number + * @deffunc AP_MODULE_MAGIC_AT_LEAST(int major, int minor) + */ +#define AP_MODULE_MAGIC_AT_LEAST(major,minor) \ + ((major) < MODULE_MAGIC_NUMBER_MAJOR \ + || ((major) == MODULE_MAGIC_NUMBER_MAJOR \ + && (minor) <= MODULE_MAGIC_NUMBER_MINOR)) + +/** @deprecated present for backwards compatibility */ +#define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR +#define MODULE_MAGIC_AT_LEAST old_broken_macro_we_hope_you_are_not_using + +#endif /* !APACHE_AP_MMN_H */ diff --git a/trunk/include/ap_mpm.h b/trunk/include/ap_mpm.h new file mode 100644 index 0000000000..b1e303fe05 --- /dev/null +++ b/trunk/include/ap_mpm.h @@ -0,0 +1,177 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_MPM_H +#define AP_MPM_H + +#include "apr_thread_proc.h" + +/** + * @package Multi-Processing Module library + */ + +/* + The MPM, "multi-processing model" provides an abstraction of the + interface with the OS for distributing incoming connections to + threads/process for processing. http_main invokes the MPM, and + the MPM runs until a shutdown/restart has been indicated. + The MPM calls out to the apache core via the ap_process_connection + function when a connection arrives. + + The MPM may or may not be multithreaded. In the event that it is + multithreaded, at any instant it guarantees a 1:1 mapping of threads + ap_process_connection invocations. + + Note: In the future it will be possible for ap_process_connection + to return to the MPM prior to finishing the entire connection; and + the MPM will proceed with asynchronous handling for the connection; + in the future the MPM may call ap_process_connection again -- but + does not guarantee it will occur on the same thread as the first call. + + The MPM further guarantees that no asynchronous behaviour such as + longjmps and signals will interfere with the user code that is + invoked through ap_process_connection. The MPM may reserve some + signals for its use (i.e. SIGUSR1), but guarantees that these signals + are ignored when executing outside the MPM code itself. (This + allows broken user code that does not handle EINTR to function + properly.) + + The suggested server restart and stop behaviour will be "graceful". + However the MPM may choose to terminate processes when the user + requests a non-graceful restart/stop. When this occurs, the MPM kills + all threads with extreme prejudice, and destroys the pchild pool. + User cleanups registered in the pchild apr_pool_t will be invoked at + this point. (This can pose some complications, the user cleanups + are asynchronous behaviour not unlike longjmp/signal... but if the + admin is asking for a non-graceful shutdown, how much effort should + we put into doing it in a nice way?) + + unix/posix notes: + - The MPM does not set a SIGALRM handler, user code may use SIGALRM. + But the preferred method of handling timeouts is to use the + timeouts provided by the BUFF abstraction. + - The proper setting for SIGPIPE is SIG_IGN, if user code changes it + for any of their own processing, it must be restored to SIG_IGN + prior to executing or returning to any apache code. + TODO: add SIGPIPE debugging check somewhere to make sure it's SIG_IGN +*/ + +/** + * This is the function that MPMs must create. This function is responsible + * for controlling the parent and child processes. It will run until a + * restart/shutdown is indicated. + * @param pconf the configuration pool, reset before the config file is read + * @param plog the log pool, reset after the config file is read + * @param server_conf the global server config. + * @return 1 for shutdown 0 otherwise. + * @deffunc int ap_mpm_run(apr_pool_t *pconf, apr_pool_t *plog, server_rec *server_conf) + */ +AP_DECLARE(int) ap_mpm_run(apr_pool_t *pconf, apr_pool_t *plog, server_rec *server_conf); + +/** + * predicate indicating if a graceful stop has been requested ... + * used by the connection loop + * @return 1 if a graceful stop has been requested, 0 otherwise + * @deffunc int ap_graceful_stop_signalled(*void) + */ +AP_DECLARE(int) ap_graceful_stop_signalled(void); + +/** + * Spawn a process with privileges that another module has requested + * @param r The request_rec of the current request + * @param newproc The resulting process handle. + * @param progname The program to run + * @param const_args the arguments to pass to the new program. The first + * one should be the program name. + * @param env The new environment apr_table_t for the new process. This + * should be a list of NULL-terminated strings. + * @param attr the procattr we should use to determine how to create the new + * process + * @param p The pool to use. + */ +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, + const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, + apr_pool_t *p); + +/* Subtypes/Values for AP_MPMQ_IS_THREADED and AP_MPMQ_IS_FORKED */ +#define AP_MPMQ_NOT_SUPPORTED 0 /* This value specifies whether */ + /* an MPM is capable of */ + /* threading or forking. */ +#define AP_MPMQ_STATIC 1 /* This value specifies whether */ + /* an MPM is using a static # */ + /* threads or daemons. */ +#define AP_MPMQ_DYNAMIC 2 /* This value specifies whether */ + /* an MPM is using a dynamic # */ + /* threads or daemons. */ + +/* Values returned for AP_MPMQ_MPM_STATE */ +#define AP_MPMQ_STARTING 0 +#define AP_MPMQ_RUNNING 1 +#define AP_MPMQ_STOPPING 2 + +#define AP_MPMQ_MAX_DAEMON_USED 1 /* Max # of daemons used so far */ +#define AP_MPMQ_IS_THREADED 2 /* MPM can do threading */ +#define AP_MPMQ_IS_FORKED 3 /* MPM can do forking */ +#define AP_MPMQ_HARD_LIMIT_DAEMONS 4 /* The compiled max # daemons */ +#define AP_MPMQ_HARD_LIMIT_THREADS 5 /* The compiled max # threads */ +#define AP_MPMQ_MAX_THREADS 6 /* # of threads/child by config */ +#define AP_MPMQ_MIN_SPARE_DAEMONS 7 /* Min # of spare daemons */ +#define AP_MPMQ_MIN_SPARE_THREADS 8 /* Min # of spare threads */ +#define AP_MPMQ_MAX_SPARE_DAEMONS 9 /* Max # of spare daemons */ +#define AP_MPMQ_MAX_SPARE_THREADS 10 /* Max # of spare threads */ +#define AP_MPMQ_MAX_REQUESTS_DAEMON 11 /* Max # of requests per daemon */ +#define AP_MPMQ_MAX_DAEMONS 12 /* Max # of daemons by config */ +#define AP_MPMQ_MPM_STATE 13 /* starting, running, stopping */ +#define AP_MPMQ_IS_ASYNC 14 /* MPM can process async connections */ + +/** + * Query a property of the current MPM. + * @param query_code One of APM_MPMQ_* + * @param result A location to place the result of the query + * @return APR_SUCCESS or APR_ENOTIMPL + * @deffunc int ap_mpm_query(int query_code, int *result) + */ +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result); + +/* Defining GPROF when compiling uses the moncontrol() function to + * disable gprof profiling in the parent, and enable it only for + * request processing in children (or in one_process mode). It's + * absolutely required to get useful gprof results under linux + * because the profile itimers and such are disabled across a + * fork(). It's probably useful elsewhere as well. + */ +#ifdef GPROF +extern void moncontrol(int); +#define AP_MONCONTROL(x) moncontrol(x) +#else +#define AP_MONCONTROL(x) +#endif + +#if AP_ENABLE_EXCEPTION_HOOK +typedef struct ap_exception_info_t { + int sig; + pid_t pid; +} ap_exception_info_t; + +AP_DECLARE_HOOK(int,fatal_exception,(ap_exception_info_t *ei)) +#endif /*AP_ENABLE_EXCEPTION_HOOK*/ + +#endif diff --git a/trunk/include/ap_provider.h b/trunk/include/ap_provider.h new file mode 100644 index 0000000000..c05da554c5 --- /dev/null +++ b/trunk/include/ap_provider.h @@ -0,0 +1,54 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_PROVIDER_H +#define AP_PROVIDER_H + +#include "ap_config.h" + +/** + * @package Provider API + */ + +/** + * This function is used to register a provider with the global + * provider pool. + * @param pool The pool to create any storage from + * @param provider_group The group to store the provider in + * @param provider_name The name for this provider + * @param provider_version The version for this provider + * @param provider Opaque structure for this provider + * @return APR_SUCCESS if all went well + */ +AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + const void *provider); + +/** + * This function is used to retrieve a provider from the global + * provider pool. + * @param provider_group The group to look for this provider in + * @param provider_name The name for the provider + * @param provider_version The version for the provider + * @return provider pointer to provider if found, NULL otherwise + */ +AP_DECLARE(void *) ap_lookup_provider(const char *provider_group, + const char *provider_name, + const char *provider_version); + +#endif diff --git a/trunk/include/ap_regex.h b/trunk/include/ap_regex.h new file mode 100644 index 0000000000..a52ade8180 --- /dev/null +++ b/trunk/include/ap_regex.h @@ -0,0 +1,135 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Derived from PCRE's pcreposix.h. + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#ifndef AP_REGEX_H +#define AP_REGEX_H + +#include "apr.h" + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options for ap_regexec: */ + +#define AP_REG_ICASE 0x01 /** use a case-insensitive match */ +#define AP_REG_NEWLINE 0x02 /** don't match newlines against '.' etc */ +#define AP_REG_NOTBOL 0x04 /** ^ will not match against start-of-string */ +#define AP_REG_NOTEOL 0x08 /** $ will not match against end-of-string */ + +#define AP_REG_EXTENDED (0) /** unused */ +#define AP_REG_NOSUB (0) /** unused */ + +/* Error values: */ +enum { + AP_REG_ASSERT = 1, /** internal error ? */ + AP_REG_ESPACE, /** failed to get memory */ + AP_REG_INVARG, /** invalid argument */ + AP_REG_NOMATCH /** match failed */ +}; + +/* The structure representing a compiled regular expression. */ +typedef struct { + void *re_pcre; + apr_size_t re_nsub; + apr_size_t re_erroffset; +} ap_regex_t; + +/* The structure in which a captured offset is returned. */ +typedef struct { + int rm_so; + int rm_eo; +} ap_regmatch_t; + +/* The functions */ + +/** + * Compile a regular expression. + * @param preg Returned compiled regex + * @param regex The regular expression string + * @param cflags Must be zero (currently). + * @return Zero on success or non-zero on error + */ +AP_DECLARE(int) ap_regcomp(ap_regex_t *preg, const char *regex, int cflags); + +/** + * Match a NUL-terminated string against a pre-compiled regex. + * @param preg The pre-compiled regex + * @param string The string to match + * @param nmatch Provide information regarding the location of any matches + * @param pmatch Provide information regarding the location of any matches + * @param eflags Bitwise OR of any of AP_REG_* flags + * @return 0 for successful match, #REG_NOMATCH otherwise + */ +AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string, + apr_size_t nmatch, ap_regmatch_t *pmatch, int eflags); + +/** + * Return the error code returned by regcomp or regexec into error messages + * @param errcode the error code returned by regexec or regcomp + * @param preg The precompiled regex + * @param errbuf A buffer to store the error in + * @param errbuf_size The size of the buffer + */ +AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg, + char *errbuf, apr_size_t errbuf_size); + +/** Destroy a pre-compiled regex. + * @param preg The pre-compiled regex to free. + */ +AP_DECLARE(void) ap_regfree(ap_regex_t *preg); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* AP_REGEX_T */ + diff --git a/trunk/include/ap_regkey.h b/trunk/include/ap_regkey.h new file mode 100644 index 0000000000..1964ccd2d3 --- /dev/null +++ b/trunk/include/ap_regkey.h @@ -0,0 +1,218 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_REGKEY_H +#define AP_REGKEY_H + +#if defined(WIN32) || defined(DOXYGEN) + +#include "apr.h" +#include "apr_pools.h" +#include "ap_config.h" /* Just for AP_DECLARE */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ap_regkey_t ap_regkey_t; + +/* Used to recover AP_REGKEY_* constants + */ +AP_DECLARE(const ap_regkey_t *) ap_regkey_const(int i); + +/** + * @file ap_regkey.h + * @brief APR-style Win32 Registry Manipulation + */ + +/** + * Win32 Only: Constants for ap_regkey_open() + */ +#define AP_REGKEY_CLASSES_ROOT ap_regkey_const(0) +#define AP_REGKEY_CURRENT_CONFIG ap_regkey_const(1) +#define AP_REGKEY_CURRENT_USER ap_regkey_const(2) +#define AP_REGKEY_LOCAL_MACHINE ap_regkey_const(3) +#define AP_REGKEY_USERS ap_regkey_const(4) +#define AP_REGKEY_PERFORMANCE_DATA ap_regkey_const(5) +#define AP_REGKEY_DYN_DATA ap_regkey_const(6) + +/** + * Win32 Only: Flags for ap_regkey_value_set() + */ +#define AP_REGKEY_EXPAND 0x0001 + +/** + * Win32 Only: Open the specified registry key. + * @param newkey The opened registry key + * @param parentkey The open registry key of the parent, or one of + *
    + *           AP_REGKEY_CLASSES_ROOT
    + *           AP_REGKEY_CURRENT_CONFIG
    + *           AP_REGKEY_CURRENT_USER
    + *           AP_REGKEY_LOCAL_MACHINE
    + *           AP_REGKEY_USERS
    + *           AP_REGKEY_PERFORMANCE_DATA 
    + *           AP_REGKEY_DYN_DATA 
    + * 
    + * @param keyname The path of the key relative to the parent key + * @param flags Or'ed value of: + *
    + *           APR_READ             open key for reading
    + *           APR_WRITE            open key for writing
    + *           APR_CREATE           create the key if it doesn't exist
    + *           APR_EXCL             return error if APR_CREATE and key exists
    + * 
    + * @param pool The pool in which newkey is allocated + */ +AP_DECLARE(apr_status_t) ap_regkey_open(ap_regkey_t **newkey, + const ap_regkey_t *parentkey, + const char *keyname, + apr_int32_t flags, + apr_pool_t *pool); + +/** + * Win32 Only: Close the registry key opened or created by ap_regkey_open(). + * @param key The registry key to close + */ +AP_DECLARE(apr_status_t) ap_regkey_close(ap_regkey_t *key); + +/** + * Win32 Only: Remove the given registry key. + * @param parentkey The open registry key of the parent, or one of + *
    + *           AP_REGKEY_CLASSES_ROOT
    + *           AP_REGKEY_CURRENT_CONFIG
    + *           AP_REGKEY_CURRENT_USER
    + *           AP_REGKEY_LOCAL_MACHINE
    + *           AP_REGKEY_USERS
    + *           AP_REGKEY_PERFORMANCE_DATA 
    + *           AP_REGKEY_DYN_DATA 
    + * 
    + * @param keyname The path of the key relative to the parent key + * @param pool The pool used for temp allocations + * @remark ap_regkey_remove() is not recursive, although it removes + * all values within the given keyname, it will not remove a key + * containing subkeys. + */ +AP_DECLARE(apr_status_t) ap_regkey_remove(const ap_regkey_t *parent, + const char *keyname, + apr_pool_t *pool); + +/** + * Win32 Only: Retrieve a registry value string from an open key. + * @param result The string value retrieved + * @param key The registry key to retrieve the value from + * @param valuename The named value to retrieve (pass "" for the default) + * @param pool The pool used to store the result + * @remark There is no toggle to prevent environment variable expansion + * if the registry value is set with AP_REG_EXPAND (REG_EXPAND_SZ), such + * expansions are always performed. + */ +AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool); + +/** + * Win32 Only: Store a registry value string into an open key. + * @param key The registry key to store the value into + * @param valuename The named value to store (pass "" for the default) + * @param value The string to store for the named value + * @param flags The option AP_REGKEY_EXPAND or 0, where AP_REGKEY_EXPAND + * values will find all %foo% variables expanded from the environment. + * @param pool The pool used for temp allocations + */ +AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key, + const char *valuename, + const char *value, + apr_int32_t flags, + apr_pool_t *pool); + +/** + * Win32 Only: Retrieve a raw byte value from an open key. + * @param result The raw bytes value retrieved + * @param resultsize Pointer to a variable to store the number raw bytes retrieved + * @param key The registry key to retrieve the value from + * @param valuename The named value to retrieve (pass "" for the default) + * @param pool The pool used to store the result + */ +AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result, + apr_size_t *resultsize, + apr_int32_t *resulttype, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool); + +/** + * Win32 Only: Store a raw bytes value into an open key. + * @param key The registry key to store the value into + * @param valuename The named value to store (pass "" for the default) + * @param value The bytes to store for the named value + * @param valuesize The number of bytes for value + * @param valuetype The + * values will find all %foo% variables expanded from the environment. + * @param pool The pool used for temp allocations + */ +AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key, + const char *valuename, + const void *value, + apr_size_t valuesize, + apr_int32_t valuetype, + apr_pool_t *pool); + +/** + * Win32 Only: Retrieve a registry value string from an open key. + * @param result The string elements retrieved from a REG_MULTI_SZ string array + * @param key The registry key to retrieve the value from + * @param valuename The named value to retrieve (pass "" for the default) + * @param pool The pool used to store the result + */ +AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool); + +/** + * Win32 Only: Store a registry value string array into an open key. + * @param key The registry key to store the value into + * @param valuename The named value to store (pass "" for the default) + * @param nelts The string elements to store in a REG_MULTI_SZ string array + * @param elts The number of elements in the elts string array + * @param pool The pool used for temp allocations + */ +AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key, + const char *valuename, + int nelts, + const char * const * elts, + apr_pool_t *pool); + +/** + * Win32 Only: Remove a registry value from an open key. + * @param key The registry key to remove the value from + * @param valuename The named value to remove (pass "" for the default) + * @param pool The pool used for temp allocations + */ +AP_DECLARE(apr_status_t) ap_regkey_value_remove(const ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool); + +#ifdef __cplusplus +} +#endif + +#endif /* def WIN32 || def DOXYGEN */ + +#endif /* AP_REGKEY_H */ diff --git a/trunk/include/ap_release.h b/trunk/include/ap_release.h new file mode 100644 index 0000000000..a9698c122f --- /dev/null +++ b/trunk/include/ap_release.h @@ -0,0 +1,70 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_RELEASE_H +#define AP_RELEASE_H + +/* The numeric compile-time version constants. These constants are the + * authoritative version numbers for APR. + */ +/** Properly quote a value as a string in the C preprocessor */ +#define AP_STRINGIFY(n) AP_STRINGIFY_HELPER(n) +/** Helper macro for AP_STRINGIFY */ +#define AP_STRINGIFY_HELPER(n) #n + +/* + * The below defines the base string of the Server: header. Additional + * tokens can be added via the ap_add_version_component() API call. + * + * The tokens are listed in order of their significance for identifying the + * application. + * + * "Product tokens should be short and to the point -- use of them for + * advertizing or other non-essential information is explicitly forbidden." + * + * Example: "Apache/1.1.0 MrWidget/0.1-alpha" + */ +#define AP_SERVER_BASEVENDOR "Apache Software Foundation" +#define AP_SERVER_BASEPRODUCT "Apache" + +#define AP_SERVER_MAJORVERSION_NUMBER 2 +#define AP_SERVER_MINORVERSION_NUMBER 1 +#define AP_SERVER_PATCHLEVEL_NUMBER 5 +#define AP_SERVER_DEVBUILD_BOOLEAN 1 + +#if AP_SERVER_DEVBUILD_BOOLEAN +#define AP_SERVER_ADD_STRING "-dev" +#else +#define AP_SERVER_ADD_STRING "" +#endif + +/* keep old macros as well */ +#define AP_SERVER_MAJORVERSION AP_STRINGIFY(AP_SERVER_MAJORVERSION_NUMBER) +#define AP_SERVER_MINORVERSION AP_STRINGIFY(AP_SERVER_MINORVERSION_NUMBER) +#define AP_SERVER_PATCHLEVEL AP_STRINGIFY(AP_SERVER_PATCHLEVEL_NUMBER) \ + AP_SERVER_ADD_STRING + +#define AP_SERVER_MINORREVISION AP_SERVER_MAJORVERSION "." AP_SERVER_MINORVERSION +#define AP_SERVER_BASEREVISION AP_SERVER_MINORREVISION "." AP_SERVER_PATCHLEVEL +#define AP_SERVER_BASEVERSION AP_SERVER_BASEPRODUCT "/" AP_SERVER_BASEREVISION +#define AP_SERVER_VERSION AP_SERVER_BASEVERSION + +/* macro for Win32 .rc files using numeric csv representation */ +#define AP_SERVER_PATCHLEVEL_CSV AP_SERVER_MAJORVERSION_NUMBER ##, \ + ##AP_SERVER_MINORVERSION_NUMBER ##, \ + ##AP_SERVER_PATCHLEVEL_NUMBER + +#endif diff --git a/trunk/include/http_config.h b/trunk/include/http_config.h new file mode 100644 index 0000000000..483cae56d2 --- /dev/null +++ b/trunk/include/http_config.h @@ -0,0 +1,1051 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_CONFIG_H +#define APACHE_HTTP_CONFIG_H + +#include "apr_hooks.h" +#include "util_cfgtree.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file http_config.h + * @brief Apache Configuration + */ + +/* + * The central data structures around here... + */ + +/* Command dispatch structures... */ + +/** + * How the directives arguments should be parsed. + * @remark Note that for all of these except RAW_ARGS, the config routine is + * passed a freshly allocated string which can be modified or stored + * or whatever... + */ +enum cmd_how { + RAW_ARGS, /**< cmd_func parses command line itself */ + TAKE1, /**< one argument only */ + TAKE2, /**< two arguments only */ + ITERATE, /**< one argument, occuring multiple times + * (e.g., IndexIgnore) + */ + ITERATE2, /**< two arguments, 2nd occurs multiple times + * (e.g., AddIcon) + */ + FLAG, /**< One of 'On' or 'Off' */ + NO_ARGS, /**< No args at all, e.g. */ + TAKE12, /**< one or two arguments */ + TAKE3, /**< three arguments only */ + TAKE23, /**< two or three arguments */ + TAKE123, /**< one, two or three arguments */ + TAKE13, /**< one or three arguments */ + TAKE_ARGV /**< an argc and argv are passed */ +}; +/** + * This structure is passed to a command which is being invoked, + * to carry a large variety of miscellaneous data which is all of + * use to *somebody*... + */ +typedef struct cmd_parms_struct cmd_parms; + +#if defined(AP_HAVE_DESIGNATED_INITIALIZER) || defined(DOXYGEN) + +/** + * All the types of functions that can be used in directives + * @internal + */ +typedef union { + /** function to call for a no-args */ + const char *(*no_args) (cmd_parms *parms, void *mconfig); + /** function to call for a raw-args */ + const char *(*raw_args) (cmd_parms *parms, void *mconfig, + const char *args); + /** function to call for a argv/argc */ + const char *(*take_argv) (cmd_parms *parms, void *mconfig, + int argc, char *const argv[]); + /** function to call for a take1 */ + const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w); + /** function to call for a take2 */ + const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w, + const char *w2); + /** function to call for a take3 */ + const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w, + const char *w2, const char *w3); + /** function to call for a flag */ + const char *(*flag) (cmd_parms *parms, void *mconfig, int on); +} cmd_func; + +/** This configuration directive does not take any arguments */ +# define AP_NO_ARGS func.no_args +/** This configuration directive will handle it's own parsing of arguments*/ +# define AP_RAW_ARGS func.raw_args +/** This configuration directive will handle it's own parsing of arguments*/ +# define AP_TAKE_ARGV func.take_argv +/** This configuration directive takes 1 argument*/ +# define AP_TAKE1 func.take1 +/** This configuration directive takes 2 arguments */ +# define AP_TAKE2 func.take2 +/** This configuration directive takes 3 arguments */ +# define AP_TAKE3 func.take3 +/** This configuration directive takes a flag (on/off) as a argument*/ +# define AP_FLAG func.flag + +/** method of declaring a directive with no arguments */ +# define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \ + { directive, { .no_args=func }, mconfig, where, RAW_ARGS, help } +/** method of declaring a directive with raw argument parsing */ +# define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \ + { directive, { .raw_args=func }, mconfig, where, RAW_ARGS, help } +/** method of declaring a directive with raw argument parsing */ +# define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \ + { directive, { .take_argv=func }, mconfig, where, TAKE_ARGV, help } +/** method of declaring a directive which takes 1 argument */ +# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \ + { directive, { .take1=func }, mconfig, where, TAKE1, help } +/** method of declaring a directive which takes multiple arguments */ +# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \ + { directive, { .take1=func }, mconfig, where, ITERATE, help } +/** method of declaring a directive which takes 2 arguments */ +# define AP_INIT_TAKE2(directive, func, mconfig, where, help) \ + { directive, { .take2=func }, mconfig, where, TAKE2, help } +/** method of declaring a directive which takes 1 or 2 arguments */ +# define AP_INIT_TAKE12(directive, func, mconfig, where, help) \ + { directive, { .take2=func }, mconfig, where, TAKE12, help } +/** method of declaring a directive which takes multiple 2 arguments */ +# define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \ + { directive, { .take2=func }, mconfig, where, ITERATE2, help } +/** method of declaring a directive which takes 1 or 3 arguments */ +# define AP_INIT_TAKE13(directive, func, mconfig, where, help) \ + { directive, { .take3=func }, mconfig, where, TAKE13, help } +/** method of declaring a directive which takes 2 or 3 arguments */ +# define AP_INIT_TAKE23(directive, func, mconfig, where, help) \ + { directive, { .take3=func }, mconfig, where, TAKE23, help } +/** method of declaring a directive which takes 1 to 3 arguments */ +# define AP_INIT_TAKE123(directive, func, mconfig, where, help) \ + { directive, { .take3=func }, mconfig, where, TAKE123, help } +/** method of declaring a directive which takes 3 arguments */ +# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \ + { directive, { .take3=func }, mconfig, where, TAKE3, help } +/** method of declaring a directive which takes a flag (on/off) as a argument*/ +# define AP_INIT_FLAG(directive, func, mconfig, where, help) \ + { directive, { .flag=func }, mconfig, where, FLAG, help } + +#else /* AP_HAVE_DESIGNATED_INITIALIZER */ + +typedef const char *(*cmd_func) (); + +# define AP_NO_ARGS func +# define AP_RAW_ARGS func +# define AP_TAKE_ARGV func +# define AP_TAKE1 func +# define AP_TAKE2 func +# define AP_TAKE3 func +# define AP_FLAG func + +# define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, RAW_ARGS, help } +# define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, RAW_ARGS, help } +# define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE_ARGV, help } +# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE1, help } +# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, ITERATE, help } +# define AP_INIT_TAKE2(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE2, help } +# define AP_INIT_TAKE12(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE12, help } +# define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, ITERATE2, help } +# define AP_INIT_TAKE13(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE13, help } +# define AP_INIT_TAKE23(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE23, help } +# define AP_INIT_TAKE123(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE123, help } +# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, TAKE3, help } +# define AP_INIT_FLAG(directive, func, mconfig, where, help) \ + { directive, func, mconfig, where, FLAG, help } + +#endif /* AP_HAVE_DESIGNATED_INITIALIZER */ + +/** + * The command record structure. Each modules can define a table of these + * to define the directives it will implement. + */ +typedef struct command_struct command_rec; +struct command_struct { + /** Name of this command */ + const char *name; + /** The function to be called when this directive is parsed */ + cmd_func func; + /** Extra data, for functions which implement multiple commands... */ + void *cmd_data; + /** What overrides need to be allowed to enable this command. */ + int req_override; + /** What the command expects as arguments + * @defvar cmd_how args_how*/ + enum cmd_how args_how; + + /** 'usage' message, in case of syntax errors */ + const char *errmsg; +}; + +/** + * @defgroup ConfigDirectives Allowed locations for configuration directives. + * + * The allowed locations for a configuration directive are the union of + * those indicated by each set bit in the req_override mask. + * + * @{ + */ +#define OR_NONE 0 /**< *.conf is not available anywhere in this override */ +#define OR_LIMIT 1 /**< *.conf inside or + and .htaccess when AllowOverride Limit */ +#define OR_OPTIONS 2 /**< *.conf anywhere + and .htaccess when AllowOverride Options */ +#define OR_FILEINFO 4 /**< *.conf anywhere + and .htaccess when AllowOverride FileInfo */ +#define OR_AUTHCFG 8 /**< *.conf inside or + and .htaccess when AllowOverride AuthConfig */ +#define OR_INDEXES 16 /**< *.conf anywhere + and .htaccess when AllowOverride Indexes */ +#define OR_UNSET 32 /**< unset a directive (in Allow) */ +#define ACCESS_CONF 64 /**< *.conf inside or */ +#define RSRC_CONF 128 /**< *.conf outside or */ +#define EXEC_ON_READ 256 /**< force directive to execute a command + which would modify the configuration (like including another + file, or IFModule */ +/** this directive can be placed anywhere */ +#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES) + +/** @} */ + +/** + * This can be returned by a function if they don't wish to handle + * a command. Make it something not likely someone will actually use + * as an error code. + */ +#define DECLINE_CMD "\a\b" + +/** Common structure for reading of config files / passwd files etc. */ +typedef struct ap_configfile_t ap_configfile_t; +struct ap_configfile_t { + int (*getch) (void *param); /**< a getc()-like function */ + void *(*getstr) (void *buf, size_t bufsiz, void *param); + /**< a fgets()-like function */ + int (*close) (void *param); /**< a close handler function */ + void *param; /**< the argument passed to getch/getstr/close */ + const char *name; /**< the filename / description */ + unsigned line_number; /**< current line number, starting at 1 */ +}; + +/** + * This structure is passed to a command which is being invoked, + * to carry a large variety of miscellaneous data which is all of + * use to *somebody*... + */ +struct cmd_parms_struct { + /** Argument to command from cmd_table */ + void *info; + /** Which allow-override bits are set */ + int override; + /** Which methods are ed */ + apr_int64_t limited; + /** methods which are limited */ + apr_array_header_t *limited_xmethods; + /** methods which are xlimited */ + ap_method_list_t *xlimited; + + /** Config file structure. */ + ap_configfile_t *config_file; + /** the directive specifying this command */ + ap_directive_t *directive; + + /** Pool to allocate new storage in */ + apr_pool_t *pool; + /** Pool for scratch memory; persists during configuration, but + * wiped before the first request is served... */ + apr_pool_t *temp_pool; + /** Server_rec being configured for */ + server_rec *server; + /** If configuring for a directory, pathname of that directory. + * NOPE! That's what it meant previous to the existance of , + * and regex matching. Now the only usefulness that can be + * derived from this field is whether a command is being called in a + * server context (path == NULL) or being called in a dir context + * (path != NULL). */ + char *path; + /** configuration command */ + const command_rec *cmd; + + /** per_dir_config vector passed to handle_command */ + struct ap_conf_vector_t *context; + /** directive with syntax error */ + const ap_directive_t *err_directive; + + /** Which allow-override-opts bits are set */ + int override_opts; +}; + +/** + * Module structures. Just about everything is dispatched through + * these, directly or indirectly (through the command and handler + * tables). + */ +typedef struct module_struct module; +struct module_struct { + /** API version, *not* module version; check that module is + * compatible with this version of the server. + */ + int version; + /** API minor version. Provides API feature milestones. Not checked + * during module init */ + int minor_version; + /** Index to this modules structures in config vectors. */ + int module_index; + + /** The name of the module's C file */ + const char *name; + /** The handle for the DSO. Internal use only */ + void *dynamic_load_handle; + + /** A pointer to the next module in the list + * @defvar module_struct *next */ + struct module_struct *next; + + /** Magic Cookie to identify a module structure; It's mainly + * important for the DSO facility (see also mod_so). */ + unsigned long magic; + + /** Function to allow MPMs to re-write command line arguments. This + * hook is only available to MPMs. + * @param The process that the server is running in. + */ + void (*rewrite_args) (process_rec *process); + /** Function to allow all modules to create per directory configuration + * structures. + * @param p The pool to use for all allocations. + * @param dir The directory currently being processed. + * @return The per-directory structure created + */ + void *(*create_dir_config) (apr_pool_t *p, char *dir); + /** Function to allow all modules to merge the per directory configuration + * structures for two directories. + * @param p The pool to use for all allocations. + * @param base_conf The directory structure created for the parent directory. + * @param new_conf The directory structure currently being processed. + * @return The new per-directory structure created + */ + void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf); + /** Function to allow all modules to create per server configuration + * structures. + * @param p The pool to use for all allocations. + * @param s The server currently being processed. + * @return The per-server structure created + */ + void *(*create_server_config) (apr_pool_t *p, server_rec *s); + /** Function to allow all modules to merge the per server configuration + * structures for two servers. + * @param p The pool to use for all allocations. + * @param base_conf The directory structure created for the parent directory. + * @param new_conf The directory structure currently being processed. + * @return The new per-directory structure created + */ + void *(*merge_server_config) (apr_pool_t *p, void *base_conf, + void *new_conf); + + /** A command_rec table that describes all of the directives this module + * defines. */ + const command_rec *cmds; + + /** A hook to allow modules to hook other points in the request processing. + * In this function, modules should call the ap_hook_*() functions to + * register an interest in a specific step in processing the current + * request. + * @param p the pool to use for all allocations + */ + void (*register_hooks) (apr_pool_t *p); +}; + +/** + * @defgroup ModuleInit Module structure initializers + * + * Initializer for the first few module slots, which are only + * really set up once we start running. Note that the first two slots + * provide a version check; this should allow us to deal with changes to + * the API. The major number should reflect changes to the API handler table + * itself or removal of functionality. The minor number should reflect + * additions of functionality to the existing API. (the server can detect + * an old-format module, and either handle it back-compatibly, or at least + * signal an error). See src/include/ap_mmn.h for MMN version history. + * @{ + */ + +/** The one used in Apache 1.3, which will deliberately cause an error */ +#define STANDARD_MODULE_STUFF this_module_needs_to_be_ported_to_apache_2_0 + +/** Use this in all standard modules */ +#define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \ + MODULE_MAGIC_NUMBER_MINOR, \ + -1, \ + __FILE__, \ + NULL, \ + NULL, \ + MODULE_MAGIC_COOKIE, \ + NULL /* rewrite args spot */ + +/** Use this only in MPMs */ +#define MPM20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \ + MODULE_MAGIC_NUMBER_MINOR, \ + -1, \ + __FILE__, \ + NULL, \ + NULL, \ + MODULE_MAGIC_COOKIE + +/** @} */ + +/* CONFIGURATION VECTOR FUNCTIONS */ + +/** configuration vector structure */ +typedef struct ap_conf_vector_t ap_conf_vector_t; + +/** + * Generic accessors for other modules to get at their own module-specific + * data + * @param conf_vector The vector in which the modules configuration is stored. + * usually r->per_dir_config or s->module_config + * @param m The module to get the data for. + * @return The module-specific data + */ +AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, + const module *m); + +/** + * Generic accessors for other modules to set at their own module-specific + * data + * @param conf_vector The vector in which the modules configuration is stored. + * usually r->per_dir_config or s->module_config + * @param m The module to set the data for. + * @param val The module-specific data to set + */ +AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, + void *val); + +#if !defined(AP_DEBUG) + +#define ap_get_module_config(v,m) \ + (((void **)(v))[(m)->module_index]) +#define ap_set_module_config(v,m,val) \ + ((((void **)(v))[(m)->module_index]) = (val)) + +#endif /* AP_DEBUG */ + + +/** + * Generic command handling function for strings + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive + * @return An error string or NULL on success + */ +AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, + void *struct_ptr, + const char *arg); + +/** + * Generic command handling function for integers + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive + * @return An error string or NULL on success + */ +AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd, + void *struct_ptr, + const char *arg); + +/** + * Return true if the specified method is limited by being listed in + * a container, or by *not* being listed in a + * container. + * + * @param method Pointer to a string specifying the method to check. + * @param cmd Pointer to the cmd_parms structure passed to the + * directive handler. + * @return 0 if the method is not limited in the current scope + */ +AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method); + +/** + * Generic command handling function for strings, always sets the value + * to a lowercase string + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive + * @return An error string or NULL on success + */ +AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, + void *struct_ptr, + const char *arg); +/** + * Generic command handling function for flags + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive (either 1 or 0) + * @return An error string or NULL on success + */ +AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, + void *struct_ptr, + int arg); +/** + * Generic command handling function for files + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive + * @return An error string or NULL on success + */ +AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, + void *struct_ptr, + const char *arg); +/** + * Generic command handling function to respond with cmd->help as an error + * @param cmd The command parameters for this directive + * @param struct_ptr pointer into a given type + * @param arg The argument to the directive + * @return The cmd->help value as the error string + * @tip This allows simple declarations such as; + *
    + *     AP_INIT_RAW_ARGS("Foo", ap_set_deprecated, NULL, OR_ALL, 
    + *         "The Foo directive is no longer supported, use Bar"),
    + * 
    + */ +AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd, + void *struct_ptr, + const char *arg); +/** + * For modules which need to read config files, open logs, etc. this returns + * the canonical form of fname made absolute to ap_server_root. + * @param p pool to allocate data from + * @param fname The file name + */ +AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname); + +/* Finally, the hook for dynamically loading modules in... */ + +/** + * Add a module to the server + * @param m The module structure of the module to add + * @param p The pool of the same lifetime as the module + */ +AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p); + +/** + * Remove a module from the server. There are some caveats: + * when the module is removed, its slot is lost so all the current + * per-dir and per-server configurations are invalid. So we should + * only ever call this function when you are invalidating almost + * all our current data. I.e. when doing a restart. + * @param m the module structure of the module to remove + */ +AP_DECLARE(void) ap_remove_module(module *m); +/** + * Add a module to the chained modules list and the list of loaded modules + * @param m The module structure of the module to add + * @param p The pool with the same lifetime as the module + */ +AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p); +/** + * Remove a module fromthe chained modules list and the list of loaded modules + * @param m the module structure of the module to remove + */ +AP_DECLARE(void) ap_remove_loaded_module(module *mod); +/** + * Find the name of the specified module + * @param m The module to get the name for + * @return the name of the module + */ +AP_DECLARE(const char *) ap_find_module_name(module *m); +/** + * Find a module based on the name of the module + * @param name the name of the module + * @return the module structure if found, NULL otherwise + */ +AP_DECLARE(module *) ap_find_linked_module(const char *name); + +/** + * Open a ap_configfile_t as apr_file_t + * @param ret_cfg open ap_configfile_t struct pointer + * @param p The pool to allocate the structure from + * @param name the name of the file to open + */ +AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg, + apr_pool_t *p, const char *name); + +/** + * Allocate a ap_configfile_t handle with user defined functions and params + * @param p The pool to allocate from + * @param descr The name of the file + * @param param The argument passed to getch/getstr/close + * @param getc_func The getch function + * @param gets_func The getstr function + * @param close_func The close function + */ +AP_DECLARE(ap_configfile_t *) ap_pcfg_open_custom(apr_pool_t *p, + const char *descr, + void *param, + int(*getc_func)(void*), + void *(*gets_func) (void *buf, size_t bufsiz, void *param), + int(*close_func)(void *param)); + +/** + * Read one line from open ap_configfile_t, strip LF, increase line number + * @param buf place to store the line read + * @param bufsize size of the buffer + * @param cfp File to read from + * @return 1 on success, 0 on failure + */ +AP_DECLARE(int) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp); + +/** + * Read one char from open configfile_t, increase line number upon LF + * @param cfp The file to read from + * @return the character read + */ +AP_DECLARE(int) ap_cfg_getc(ap_configfile_t *cfp); + +/** + * Detach from open ap_configfile_t, calling the close handler + * @param cfp The file to close + * @return 1 on sucess, 0 on failure + */ +AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp); + +/** + * Read all data between the current and the matching . All + * of this data is forgotten immediately. + * @param cmd The cmd_parms to pass to the directives inside the container + * @param directive The directive name to read until + * @return Error string on failure, NULL on success + */ +AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive); + +/** + * Read all data between the current and the matching and build + * a config tree from it + * @param p pool to allocate from + * @param temp_pool Temporary pool to allocate from + * @param parms The cmd_parms to pass to all directives read + * @param current The current node in the tree + * @param curr_parent The current parent node + * @param orig_directive The directive to read until hit. + * @return Error string on failure, NULL on success +*/ +AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p, + apr_pool_t *temp_pool, + cmd_parms *parms, + ap_directive_t **current, + ap_directive_t **curr_parent, + char *orig_directive); + +/** + * Build a config tree from a config file + * @param parms The cmd_parms to pass to all of the directives in the file + * @param conf_pool The pconf pool + * @param temp_pool The temporary pool + * @param conftree Place to store the root node of the config tree + * @return Error string on erro, NULL otherwise + */ +AP_DECLARE(const char *) ap_build_config(cmd_parms *parms, + apr_pool_t *conf_pool, + apr_pool_t *temp_pool, + ap_directive_t **conftree); + +/** + * Walk a config tree and setup the server's internal structures + * @param conftree The config tree to walk + * @param parms The cmd_parms to pass to all functions + * @param section_vector The per-section config vector. + * @return Error string on error, NULL otherwise + */ +AP_DECLARE(const char *) ap_walk_config(ap_directive_t *conftree, + cmd_parms *parms, + ap_conf_vector_t *section_vector); + +/** + * @defgroup ap_check_cmd_context ap_check_cmd_context + * @{ + */ +/** + * Check the context a command is used in. + * @param cmd The command to check + * @param forbidden Where the command is forbidden. + * @return Error string on error, NULL on success + */ +AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd, + unsigned forbidden); + +#define NOT_IN_VIRTUALHOST 0x01 /**< Forbidden in */ +#define NOT_IN_LIMIT 0x02 /**< Forbidden in */ +#define NOT_IN_DIRECTORY 0x04 /**< Forbidden in */ +#define NOT_IN_LOCATION 0x08 /**< Forbidden in */ +#define NOT_IN_FILES 0x10 /**< Forbidden in */ +/** Forbidden in //*/ +#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES) +/** Forbidden in //// */ +#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE) + +/** @} */ + +#ifdef CORE_PRIVATE + +/** + * This structure is used to assign symbol names to module pointers + */ +typedef struct { + const char *name; + module *modp; +} ap_module_symbol_t; + +/** + * The topmost module in the list + * @defvar module *ap_top_module + */ +AP_DECLARE_DATA extern module *ap_top_module; + +/** + * Array of all statically linked modules + * @defvar module *ap_prelinked_modules[] + */ +AP_DECLARE_DATA extern module *ap_prelinked_modules[]; +/** + * Array of all statically linked modulenames (symbols) + * @defvar ap_module_symbol_t ap_prelinked_modulenames[] + */ +AP_DECLARE_DATA extern ap_module_symbol_t ap_prelinked_module_symbols[]; +/** + * Array of all preloaded modules + * @defvar module *ap_preloaded_modules[] + */ +AP_DECLARE_DATA extern module *ap_preloaded_modules[]; +/** + * Array of all loaded modules + * @defvar module **ap_loaded_modules + */ +AP_DECLARE_DATA extern module **ap_loaded_modules; + +/* For mod_so.c... */ +/** Run a single module's two create_config hooks + * @param p the pool to allocate from + * @param s The server to configure for. + * @param m The module to configure + */ +AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s, + module *m); + +/* For http_main.c... */ +/** + * Add all of the prelinked modules into the loaded module list + * @param process The process that is currently running the server + */ +AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process); + +/** + * Show the preloaded configuration directives, the help string explaining + * the directive arguments, in what module they are handled, and in + * what parts of the configuration they are allowed. Used for httpd -h. + */ +AP_DECLARE(void) ap_show_directives(void); + +/** + * Show the preloaded module names. Used for httpd -l. + */ +AP_DECLARE(void) ap_show_modules(void); + +/** + * Show the MPM name. Used in reporting modules such as mod_info to + * provide extra information to the user + */ +AP_DECLARE(const char *) ap_show_mpm(void); + +/** + * Read all config files and setup the server + * @param process The process running the server + * @param temp_pool A pool to allocate temporary data from. + * @param config_name The name of the config file + * @param conftree Place to store the root of the config tree + * @return The setup server_rec list. + */ +AP_DECLARE(server_rec *) ap_read_config(process_rec *process, + apr_pool_t *temp_pool, + const char *config_name, + ap_directive_t **conftree); + +/** + * Run all rewrite args hooks for loaded modules + * @param process The process currently running the server + */ +AP_DECLARE(void) ap_run_rewrite_args(process_rec *process); + +/** + * Run the register hooks function for a specified module + * @param m The module to run the register hooks function fo + * @param p The pool valid for the lifetime of the module + */ +AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p); + +/** + * Setup all virtual hosts + * @param p The pool to allocate from + * @param main_server The head of the server_rec list + */ +AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, + server_rec *main_server); + +/* For http_request.c... */ + +/** + * Setup the config vector for a request_rec + * @param p The pool to allocate the config vector from + * @return The config vector + */ +AP_CORE_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p); + +/** + * Setup the config vector for per dir module configs + * @param p The pool to allocate the config vector from + * @return The config vector + */ +AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p); + +/** + * Run all of the modules merge per dir config functions + * @param p The pool to pass to the merge functions + * @param base The base directory config structure + * @param new_conf The new directory config structure + */ +AP_CORE_DECLARE(ap_conf_vector_t*) ap_merge_per_dir_configs(apr_pool_t *p, + ap_conf_vector_t *base, + ap_conf_vector_t *new_conf); + +/* For http_connection.c... */ +/** + * Setup the config vector for a connection_rec + * @param p The pool to allocate the config vector from + * @return The config vector + */ +AP_CORE_DECLARE(ap_conf_vector_t*) ap_create_conn_config(apr_pool_t *p); + +/* For http_core.c... ( command and virtual hosts) */ + +/** + * parse an htaccess file + * @param resulting htaccess_result + * @param r The request currently being served + * @param override Which overrides are active + * @param path The path to the htaccess file + * @param access_name The list of possible names for .htaccess files + * int The status of the current request + */ +AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, + request_rec *r, int override, + int override_opts, + const char *path, + const char *access_name); + +/** + * Setup a virtual host + * @param p The pool to allocate all memory from + * @param hostname The hostname of the virtual hsot + * @param main_server The main server for this Apache configuration + * @param ps Place to store the new server_rec + * return Error string on error, NULL on success + */ +AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p, + const char *hostname, + server_rec *main_server, + server_rec **ps); + +/** + * Process the config file for Apache + * @param s The server rec to use for the command parms + * @param fname The name of the config file + * @param conftree The root node of the created config tree + * @param p Pool for general allocation + * @param ptem Pool for temporary allocation + */ +AP_DECLARE(const char *) ap_process_resource_config(server_rec *s, + const char *fname, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp); + +/** + * Process all directives in the config tree + * @param s The server rec to use in the command parms + * @param conftree The config tree to process + * @param p The pool for general allocation + * @param ptemp The pool for temporary allocations + * @return OK if no problems + */ +AP_DECLARE(int) ap_process_config_tree(server_rec *s, + ap_directive_t *conftree, + apr_pool_t *p, + apr_pool_t *ptemp); + +/* Module-method dispatchers, also for http_request.c */ +/** + * Run the handler phase of each module until a module accepts the + * responsibility of serving the request + * @param r The current request + * @return The status of the current request + */ +AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r); + +/* for mod_perl */ + +/** + * Find a given directive in a command_rec table + * @param name The directive to search for + * @param cmds The table to search + * @return The directive definition of the specified directive + */ +AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name, + const command_rec *cmds); + +/** + * Find a given directive in a list module + * @param cmd_name The directive to search for + * @param mod The module list to search + * @return The directive definition of the specified directive + */ +AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(const char *cmd_name, + module **mod); + +/** + * Ask a module to create per-server and per-section (dir/loc/file) configs + * (if it hasn't happened already). The results are stored in the server's + * config, and the specified per-section config vector. + * @param server The server to operate upon. + * @param section_vector The per-section config vector. + * @param section Which section to create a config for. + * @param mod The module which is defining the config data. + * @param pconf A pool for all configuration allocations. + * @return The (new) per-section config data. + */ +AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server, + ap_conf_vector_t *section_vector, + const char *section, + module *mod, apr_pool_t *pconf); + +#endif + + /* Hooks */ + +/** + * Run the header parser functions for each module + * @param r The current request + * @return OK or DECLINED + */ +AP_DECLARE_HOOK(int,header_parser,(request_rec *r)) + +/** + * Run the pre_config function for each module + * @param pconf The config pool + * @param plog The logging streams pool + * @param ptemp The temporary pool + * @return OK or DECLINED on success anything else is a error + */ +AP_DECLARE_HOOK(int,pre_config,(apr_pool_t *pconf,apr_pool_t *plog, + apr_pool_t *ptemp)) + +/** + * Run the test_config function for each module; this hook is run + * only if the server was invoked to test the configuration syntax. + * @param pconf The config pool + * @param s The list of server_recs + */ +AP_DECLARE_HOOK(void,test_config,(apr_pool_t *pconf, server_rec *s)) + +/** + * Run the post_config function for each module + * @param pconf The config pool + * @param plog The logging streams pool + * @param ptemp The temporary pool + * @param s The list of server_recs + * @return OK or DECLINED on success anything else is a error + */ +AP_DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog, + apr_pool_t *ptemp,server_rec *s)) + +/** + * Run the open_logs functions for each module + * @param pconf The config pool + * @param plog The logging streams pool + * @param ptemp The temporary pool + * @param s The list of server_recs + * @return OK or DECLINED on success anything else is a error + */ +AP_DECLARE_HOOK(int,open_logs,(apr_pool_t *pconf,apr_pool_t *plog, + apr_pool_t *ptemp,server_rec *s)) + +/** + * Run the child_init functions for each module + * @param pchild The child pool + * @param s The list of server_recs in this server + */ +AP_DECLARE_HOOK(void,child_init,(apr_pool_t *pchild, server_rec *s)) + +/** + * Run the handler functions for each module + * @param r The request_rec + * @remark non-wildcard handlers should HOOK_MIDDLE, wildcard HOOK_LAST + */ +AP_DECLARE_HOOK(int,handler,(request_rec *r)) + +/** + * Run the quick handler functions for each module. The quick_handler + * is run before any other requests hooks are called (location_walk, + * directory_walk, access checking, et. al.). This hook was added + * to provide a quick way to serve content from a URI keyed cache. + * + * @param r The request_rec + * @param lookup_uri Controls whether the caller actually wants content or not. + * lookup is set when the quick_handler is called out of + * ap_sub_req_lookup_uri() + */ +AP_DECLARE_HOOK(int,quick_handler,(request_rec *r, int lookup_uri)) + +/** + * Retrieve the optional functions for each module. + * This is run immediately before the server starts. Optional functions should + * be registered during the hook registration phase. + */ +AP_DECLARE_HOOK(void,optional_fn_retrieve,(void)) + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_CONFIG_H */ diff --git a/trunk/include/http_connection.h b/trunk/include/http_connection.h new file mode 100644 index 0000000000..8ade757b1d --- /dev/null +++ b/trunk/include/http_connection.h @@ -0,0 +1,139 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_CONNECTION_H +#define APACHE_HTTP_CONNECTION_H + +#include "apr_hooks.h" +#include "apr_network_io.h" +#include "apr_buckets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Apache connection library + */ +#ifdef CORE_PRIVATE +/** + * This is the protocol module driver. This calls all of the + * pre-connection and connection hooks for all protocol modules. + * @param c The connection on which the request is read + * @param csd The mechanism on which this connection is to be read. + * Most times this will be a socket, but it is up to the module + * that accepts the request to determine the exact type. + * @deffunc void ap_process_connection(conn_rec *c, void *csd) + */ +AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd); + +AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c); + +/** + * This function is responsible for the following cases: + *
    + * we now proceed to read from the client until we get EOF, or until
    + * MAX_SECS_TO_LINGER has passed.  the reasons for doing this are
    + * documented in a draft:
    + *
    + * http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt
    + *
    + * in a nutshell -- if we don't make this effort we risk causing
    + * TCP RST packets to be sent which can tear down a connection before
    + * all the response data has been sent to the client.
    + * 
    + * @param c The connection we are closing + */ +AP_DECLARE(void) ap_lingering_close(conn_rec *c); +#endif + + /* Hooks */ +/** + * create_connection is a RUN_FIRST hook which allows modules to create + * connections. In general, you should not install filters with the + * create_connection hook. If you require vhost configuration information + * to make filter installation decisions, you must use the pre_connection + * or install_network_transport hook. This hook should close the connection + * if it encounters a fatal error condition. + * + * @param p The pool from which to allocate the connection record + * @param csd The socket that has been accepted + * @param conn_id A unique identifier for this connection. The ID only + * needs to be unique at that time, not forever. + * @param sbh A handle to scoreboard information for this connection. + * @return An allocated connection record or NULL. + */ +AP_DECLARE_HOOK(conn_rec *, create_connection, + (apr_pool_t *p, server_rec *server, apr_socket_t *csd, + long conn_id, void *sbh, apr_bucket_alloc_t *alloc)) + +/** + * This hook gives protocol modules an opportunity to set everything up + * before calling the protocol handler. All pre-connection hooks are + * run until one returns something other than ok or decline + * @param c The connection on which the request has been received. + * @param csd The mechanism on which this connection is to be read. + * Most times this will be a socket, but it is up to the module + * that accepts the request to determine the exact type. + * @return OK or DECLINED + * @deffunc int ap_run_pre_connection(conn_rec *c, void *csd) + */ +AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd)) + +/** + * This hook implements different protocols. After a connection has been + * established, the protocol module must read and serve the request. This + * function does that for each protocol module. The first protocol module + * to handle the request is the last module run. + * @param c The connection on which the request has been received. + * @return OK or DECLINED + * @deffunc int ap_run_process_connection(conn_rec *c) + */ +AP_DECLARE_HOOK(int,process_connection,(conn_rec *c)) + +/* End Of Connection (EOC) bucket */ + +AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eoc; + +/** + * Determine if a bucket is an End Of Connection (EOC) bucket + * @param e The bucket to inspect + * @return true or false + */ +#define AP_BUCKET_IS_EOC(e) (e->type == &ap_bucket_type_eoc) + +/** + * Make the bucket passed in an End Of Connection (EOC) bucket + * @param b The bucket to make into an EOC bucket + * @return The new bucket, or NULL if allocation failed + * @deffunc apr_bucket *ap_bucket_eoc_make(apr_bucket *b) + */ +AP_DECLARE(apr_bucket *) ap_bucket_eoc_make(apr_bucket *b); + +/** + * Create a bucket referring to an End Of Connection (EOC). This indicates + * that the connection will be closed. + * @param list The freelist from which this bucket should be allocated + * @return The new bucket, or NULL if allocation failed + * @deffunc apr_bucket *ap_bucket_eoc_create(apr_bucket_alloc_t *list) + */ +AP_DECLARE(apr_bucket *) ap_bucket_eoc_create(apr_bucket_alloc_t *list); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_REQUEST_H */ diff --git a/trunk/include/http_core.h b/trunk/include/http_core.h new file mode 100644 index 0000000000..175055d51c --- /dev/null +++ b/trunk/include/http_core.h @@ -0,0 +1,648 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_CORE_H +#define APACHE_HTTP_CORE_H + +#include "apr.h" +#include "apr_hash.h" +#include "apr_optional.h" +#include "util_filter.h" + +#if APR_HAVE_STRUCT_RLIMIT +#include +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package CORE HTTP Daemon + */ + +/* **************************************************************** + * + * The most basic server code is encapsulated in a single module + * known as the core, which is just *barely* functional enough to + * serve documents, though not terribly well. + * + * Largely for NCSA back-compatibility reasons, the core needs to + * make pieces of its config structures available to other modules. + * The accessors are declared here, along with the interpretation + * of one of them (allow_options). + */ + +#define OPT_NONE 0 +#define OPT_INDEXES 1 +#define OPT_INCLUDES 2 +#define OPT_SYM_LINKS 4 +#define OPT_EXECCGI 8 +#define OPT_UNSET 16 +#define OPT_INCNOEXEC 32 +#define OPT_SYM_OWNER 64 +#define OPT_MULTI 128 +#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI) + +/* options for get_remote_host() */ +/* REMOTE_HOST returns the hostname, or NULL if the hostname + * lookup fails. It will force a DNS lookup according to the + * HostnameLookups setting. + */ +#define REMOTE_HOST (0) + +/* REMOTE_NAME returns the hostname, or the dotted quad if the + * hostname lookup fails. It will force a DNS lookup according + * to the HostnameLookups setting. + */ +#define REMOTE_NAME (1) + +/* REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is + * never forced. + */ +#define REMOTE_NOLOOKUP (2) + +/* REMOTE_DOUBLE_REV will always force a DNS lookup, and also force + * a double reverse lookup, regardless of the HostnameLookups + * setting. The result is the (double reverse checked) hostname, + * or NULL if any of the lookups fail. + */ +#define REMOTE_DOUBLE_REV (3) + +#define SATISFY_ALL 0 +#define SATISFY_ANY 1 +#define SATISFY_NOSPEC 2 + +/* Make sure we don't write less than 8000 bytes at any one time. + */ +#define AP_MIN_BYTES_TO_WRITE 8000 + +/* default maximum of internal redirects */ +# define AP_DEFAULT_MAX_INTERNAL_REDIRECTS 10 + +/* default maximum subrequest nesting level */ +# define AP_DEFAULT_MAX_SUBREQ_DEPTH 10 + +/** + * Retrieve the value of Options for this request + * @param r The current request + * @return the Options bitmask + * @deffunc int ap_allow_options(request_rec *r) + */ +AP_DECLARE(int) ap_allow_options(request_rec *r); + +/** + * Retrieve the value of the AllowOverride for this request + * @param r The current request + * @return the overrides bitmask + * @deffunc int ap_allow_overrides(request_rec *r) + */ +AP_DECLARE(int) ap_allow_overrides(request_rec *r); + +/** + * Retrieve the value of the DefaultType directive, or text/plain if not set + * @param r The current request + * @return The default type + * @deffunc const char *ap_default_type(request_rec *r) + */ +AP_DECLARE(const char *) ap_default_type(request_rec *r); + +/** + * Retrieve the document root for this server + * @param r The current request + * @warning Don't use this! If your request went through a Userdir, or + * something like that, it'll screw you. But it's back-compatible... + * @return The document root + * @deffunc const char *ap_document_root(request_rec *r) + */ +AP_DECLARE(const char *) ap_document_root(request_rec *r); + +/** + * Lookup the remote client's DNS name or IP address + * @param conn The current connection + * @param dir_config The directory config vector from the request + * @param type The type of lookup to perform. One of: + *
    + *     REMOTE_HOST returns the hostname, or NULL if the hostname
    + *                 lookup fails.  It will force a DNS lookup according to the
    + *                 HostnameLookups setting.
    + *     REMOTE_NAME returns the hostname, or the dotted quad if the
    + *                 hostname lookup fails.  It will force a DNS lookup according
    + *                 to the HostnameLookups setting.
    + *     REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
    + *                     never forced.
    + *     REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
    + *                   a double reverse lookup, regardless of the HostnameLookups
    + *                   setting.  The result is the (double reverse checked) 
    + *                   hostname, or NULL if any of the lookups fail.
    + * 
    + * @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an IP address + * string is returned + * @return The remote hostname + * @deffunc const char *ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip) + */ +AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip); + +/** + * Retrieve the login name of the remote user. Undef if it could not be + * determined + * @param r The current request + * @return The user logged in to the client machine + * @deffunc const char *ap_get_remote_logname(request_rec *r) + */ +AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r); + +/* Used for constructing self-referencing URLs, and things like SERVER_PORT, + * and SERVER_NAME. + */ +/** + * build a fully qualified URL from the uri and information in the request rec + * @param p The pool to allocate the URL from + * @param uri The path to the requested file + * @param r The current request + * @return A fully qualified URL + * @deffunc char *ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r) + */ +AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r); + +/** + * Get the current server name from the request + * @param r The current request + * @return the server name + * @deffunc const char *ap_get_server_name(request_rec *r) + */ +AP_DECLARE(const char *) ap_get_server_name(request_rec *r); + +/** + * Get the current server port + * @param The current request + * @return The server's port + * @deffunc apr_port_t ap_get_server_port(const request_rec *r) + */ +AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r); + +/** + * Return the limit on bytes in request msg body + * @param r The current request + * @return the maximum number of bytes in the request msg body + * @deffunc apr_off_t ap_get_limit_req_body(const request_rec *r) + */ +AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r); + +/** + * Return the limit on bytes in XML request msg body + * @param r The current request + * @return the maximum number of bytes in XML request msg body + * @deffunc size_t ap_get_limit_xml_body(const request_rec *r) + */ +AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r); + +/** + * Install a custom response handler for a given status + * @param r The current request + * @param status The status for which the custom response should be used + * @param string The custom response. This can be a static string, a file + * or a URL + */ +AP_DECLARE(void) ap_custom_response(request_rec *r, int status, const char *string); + +/** + * Check if the current request is beyond the configured max. number of redirects or subrequests + * @param r The current request + * @return true (is exceeded) or false + * @deffunc int ap_is_recursion_limit_exceeded(const request_rec *r) + */ +AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r); + +/** + * Check for a definition from the server command line + * @param name The define to check for + * @return 1 if defined, 0 otherwise + * @deffunc int ap_exists_config_define(const char *name) + */ +AP_DECLARE(int) ap_exists_config_define(const char *name); +/* FIXME! See STATUS about how */ +AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r); + +/* Authentication stuff. This is one of the places where compatibility + * with the old config files *really* hurts; they don't discriminate at + * all between different authentication schemes, meaning that we need + * to maintain common state for all of them in the core, and make it + * available to the other modules through interfaces. + */ +typedef struct require_line require_line; + +/** A structure to keep track of authorization requirements */ +struct require_line { + /** Where the require line is in the config file. */ + apr_int64_t method_mask; + /** The complete string from the command line */ + char *requirement; +}; + +/** + * Return the type of authorization required for this request + * @param r The current request + * @return The authorization required + * @deffunc const char *ap_auth_type(request_rec *r) + */ +AP_DECLARE(const char *) ap_auth_type(request_rec *r); + +/** + * Return the current Authorization realm + * @param r The current request + * @return The current authorization realm + * @deffunc const char *ap_auth_name(request_rec *r) + */ +AP_DECLARE(const char *) ap_auth_name(request_rec *r); + +/** + * How the requires lines must be met. + * @param r The current request + * @return How the requirements must be met. One of: + *
    + *      SATISFY_ANY    -- any of the requirements must be met.
    + *      SATISFY_ALL    -- all of the requirements must be met.
    + *      SATISFY_NOSPEC -- There are no applicable satisfy lines
    + * 
    + * @deffunc int ap_satisfies(request_rec *r) + */ +AP_DECLARE(int) ap_satisfies(request_rec *r); + +/** + * Retrieve information about all of the requires directives for this request + * @param r The current request + * @return An array of all requires directives for this request + * @deffunc const apr_array_header_t *ap_requires(request_rec *r) + */ +AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r); + +#ifdef CORE_PRIVATE + +/* + * Core is also unlike other modules in being implemented in more than + * one file... so, data structures are declared here, even though most of + * the code that cares really is in http_core.c. Also, another accessor. + */ + +AP_DECLARE_DATA extern module core_module; + +/* Per-request configuration */ + +typedef struct { + /* bucket brigade used by getline for look-ahead and + * ap_get_client_block for holding left-over request body */ + struct apr_bucket_brigade *bb; + + /* an array of per-request working data elements, accessed + * by ID using ap_get_request_note() + * (Use ap_register_request_note() during initialization + * to add elements) + */ + void **notes; + + /* There is a script processor installed on the output filter chain, + * so it needs the default_handler to deliver a (script) file into + * the chain so it can process it. Normally, default_handler only + * serves files on a GET request (assuming the file is actual content), + * since other methods are not content-retrieval. This flag overrides + * that behavior, stating that the "content" is actually a script and + * won't actually be delivered as the response for the non-GET method. + */ + int deliver_script; + + /* Custom response strings registered via ap_custom_response(), + * or NULL; check per-dir config if nothing found here + */ + char **response_code_strings; /* from ap_custom_response(), not from + * ErrorDocument + */ + /* Should addition of charset= be suppressed for this request? + */ + int suppress_charset; +} core_request_config; + +/* Standard entries that are guaranteed to be accessible via + * ap_get_request_note() for each request (additional entries + * can be added with ap_register_request_note()) + */ +#define AP_NOTE_DIRECTORY_WALK 0 +#define AP_NOTE_LOCATION_WALK 1 +#define AP_NOTE_FILE_WALK 2 +#define AP_NUM_STD_NOTES 3 + +/** + * Reserve an element in the core_request_config->notes array + * for some application-specific data + * @return An integer key that can be passed to ap_get_request_note() + * during request processing to access this element for the + * current request. + */ +AP_DECLARE(apr_size_t) ap_register_request_note(void); + +/** + * Retrieve a pointer to an element in the core_request_config->notes array + * @param r The request + * @param note_num A key for the element: either a value obtained from + * ap_register_request_note() or one of the predefined AP_NOTE_* + * values. + * @return NULL if the note_num is invalid, otherwise a pointer to the + * requested note element. + * @remark At the start of a request, each note element is NULL. The + * handle provided by ap_get_request_note() is a pointer-to-pointer + * so that the caller can point the element to some app-specific + * data structure. The caller should guarantee that any such + * structure will last as long as the request itself. + */ +AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num); + +/* Per-directory configuration */ + +typedef unsigned char allow_options_t; +typedef unsigned char overrides_t; + +/* + * Bits of info that go into making an ETag for a file + * document. Why a long? Because char historically + * proved too short for Options, and int can be different + * sizes on different platforms. + */ +typedef unsigned long etag_components_t; + +#define ETAG_UNSET 0 +#define ETAG_NONE (1 << 0) +#define ETAG_MTIME (1 << 1) +#define ETAG_INODE (1 << 2) +#define ETAG_SIZE (1 << 3) +#define ETAG_BACKWARD (ETAG_MTIME | ETAG_INODE | ETAG_SIZE) +#define ETAG_ALL (ETAG_MTIME | ETAG_INODE | ETAG_SIZE) + +typedef enum { + srv_sig_unset, + srv_sig_off, + srv_sig_on, + srv_sig_withmail +} server_signature_e; + +typedef struct { + /* path of the directory/regex/etc. see also d_is_fnmatch/absolute below */ + char *d; + /* the number of slashes in d */ + unsigned d_components; + + /* If (opts & OPT_UNSET) then no absolute assignment to options has + * been made. + * invariant: (opts_add & opts_remove) == 0 + * Which said another way means that the last relative (options + or -) + * assignment made to each bit is recorded in exactly one of opts_add + * or opts_remove. + */ + allow_options_t opts; + allow_options_t opts_add; + allow_options_t opts_remove; + overrides_t override; + allow_options_t override_opts; + + /* MIME typing --- the core doesn't do anything at all with this, + * but it does know what to slap on a request for a document which + * goes untyped by other mechanisms before it slips out the door... + */ + + char *ap_default_type; + + /* Authentication stuff. Groan... */ + + int *satisfy; /* for every method one */ + char *ap_auth_type; + char *ap_auth_name; + apr_array_header_t *ap_requires; + + /* Custom response config. These can contain text or a URL to redirect to. + * if response_code_strings is NULL then there are none in the config, + * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES. + * This lets us do quick merges in merge_core_dir_configs(). + */ + + char **response_code_strings; /* from ErrorDocument, not from + * ap_custom_response() */ + + /* Hostname resolution etc */ +#define HOSTNAME_LOOKUP_OFF 0 +#define HOSTNAME_LOOKUP_ON 1 +#define HOSTNAME_LOOKUP_DOUBLE 2 +#define HOSTNAME_LOOKUP_UNSET 3 + unsigned int hostname_lookups : 4; + + signed int content_md5 : 2; /* calculate Content-MD5? */ + +#define USE_CANONICAL_NAME_OFF (0) +#define USE_CANONICAL_NAME_ON (1) +#define USE_CANONICAL_NAME_DNS (2) +#define USE_CANONICAL_NAME_UNSET (3) + unsigned use_canonical_name : 2; + + /* since is_fnmatch(conf->d) was being called so frequently in + * directory_walk() and its relatives, this field was created and + * is set to the result of that call. + */ + unsigned d_is_fnmatch : 1; + + /* should we force a charset on any outgoing parameterless content-type? + * if so, which charset? + */ +#define ADD_DEFAULT_CHARSET_OFF (0) +#define ADD_DEFAULT_CHARSET_ON (1) +#define ADD_DEFAULT_CHARSET_UNSET (2) + unsigned add_default_charset : 2; + const char *add_default_charset_name; + + /* System Resource Control */ +#ifdef RLIMIT_CPU + struct rlimit *limit_cpu; +#endif +#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) + struct rlimit *limit_mem; +#endif +#ifdef RLIMIT_NPROC + struct rlimit *limit_nproc; +#endif + apr_off_t limit_req_body; /* limit on bytes in request msg body */ + long limit_xml_body; /* limit on bytes in XML request msg body */ + + /* logging options */ + + server_signature_e server_signature; + + int loglevel; + + /* Access control */ + apr_array_header_t *sec_file; + ap_regex_t *r; + + const char *mime_type; /* forced with ForceType */ + const char *handler; /* forced with SetHandler */ + const char *output_filters; /* forced with SetOutputFilters */ + const char *input_filters; /* forced with SetInputFilters */ + int accept_path_info; /* forced with AcceptPathInfo */ + + apr_hash_t *ct_output_filters; /* added with AddOutputFilterByType */ + + /* + * What attributes/data should be included in ETag generation? + */ + etag_components_t etag_bits; + etag_components_t etag_add; + etag_components_t etag_remove; + + /* + * Run-time performance tuning + */ +#define ENABLE_MMAP_OFF (0) +#define ENABLE_MMAP_ON (1) +#define ENABLE_MMAP_UNSET (2) + unsigned int enable_mmap : 2; /* whether files in this dir can be mmap'ed */ + +#define ENABLE_SENDFILE_OFF (0) +#define ENABLE_SENDFILE_ON (1) +#define ENABLE_SENDFILE_UNSET (2) + unsigned int enable_sendfile : 2; /* files in this dir can be mmap'ed */ + unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being + * pitched indiscriminately */ +} core_dir_config; + +/* Per-server core configuration */ + +typedef struct { + +#ifdef GPROF + char *gprof_dir; +#endif + + /* Name translations --- we want the core to be able to do *something* + * so it's at least a minimally functional web server on its own (and + * can be tested that way). But let's keep it to the bare minimum: + */ + const char *ap_document_root; + + /* Access control */ + + char *access_name; + apr_array_header_t *sec_dir; + apr_array_header_t *sec_url; + + /* recursion backstopper */ + int redirect_limit; /* maximum number of internal redirects */ + int subreq_limit; /* maximum nesting level of subrequests */ +} core_server_config; + +/* for AddOutputFiltersByType in core.c */ +void ap_add_output_filters_by_type(request_rec *r); + +/* for http_config.c */ +void ap_core_reorder_directories(apr_pool_t *, server_rec *); + +/* for mod_perl */ +AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config); +AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config); +AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config); +AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg); + +/* Core filters; not exported. */ +int ap_net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes); +int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes); +apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b); + +#endif /* CORE_PRIVATE */ + + +/* ---------------------------------------------------------------------- + * + * Runtime status/management + */ + +typedef enum { + ap_mgmt_type_string, + ap_mgmt_type_long, + ap_mgmt_type_hash +} ap_mgmt_type_e; + +typedef union { + const char *s_value; + long i_value; + apr_hash_t *h_value; +} ap_mgmt_value; + +typedef struct { + const char *description; + const char *name; + ap_mgmt_type_e vtype; + ap_mgmt_value v; +} ap_mgmt_item_t; + +/* Handles for core filters */ +extern AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; + +/** + * This hook provdes a way for modules to provide metrics/statistics about + * their operational status. + * + * @param p A pool to use to create entries in the hash table + * @param val The name of the parameter(s) that is wanted. This is + * tree-structured would be in the form ('*' is all the tree, + * 'module.*' all of the module , 'module.foo.*', or + * 'module.foo.bar' ) + * @param ht The hash table to store the results. Keys are item names, and + * the values point to ap_mgmt_item_t structures. + * @ingroup hooks + */ +AP_DECLARE_HOOK(int, get_mgmt_items, + (apr_pool_t *p, const char * val, apr_hash_t *ht)) + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + * + * I/O logging with mod_logio + */ + +APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out, + (conn_rec *c, apr_off_t bytes)); + +/* ---------------------------------------------------------------------- + * + * ident lookups with mod_ident + */ + +APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup, + (request_rec *r)); + +/* ---------------------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_CORE_H */ diff --git a/trunk/include/http_log.h b/trunk/include/http_log.h new file mode 100644 index 0000000000..8912beca0b --- /dev/null +++ b/trunk/include/http_log.h @@ -0,0 +1,333 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_LOG_H +#define APACHE_HTTP_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "apr_thread_proc.h" + +/** + * @package Apache logging library + */ + +#ifdef HAVE_SYSLOG +#include + +#ifndef LOG_PRIMASK +#define LOG_PRIMASK 7 +#endif + +#define APLOG_EMERG LOG_EMERG /* system is unusable */ +#define APLOG_ALERT LOG_ALERT /* action must be taken immediately */ +#define APLOG_CRIT LOG_CRIT /* critical conditions */ +#define APLOG_ERR LOG_ERR /* error conditions */ +#define APLOG_WARNING LOG_WARNING /* warning conditions */ +#define APLOG_NOTICE LOG_NOTICE /* normal but significant condition */ +#define APLOG_INFO LOG_INFO /* informational */ +#define APLOG_DEBUG LOG_DEBUG /* debug-level messages */ + +#define APLOG_LEVELMASK LOG_PRIMASK /* mask off the level value */ + +#else + +#define APLOG_EMERG 0 /* system is unusable */ +#define APLOG_ALERT 1 /* action must be taken immediately */ +#define APLOG_CRIT 2 /* critical conditions */ +#define APLOG_ERR 3 /* error conditions */ +#define APLOG_WARNING 4 /* warning conditions */ +#define APLOG_NOTICE 5 /* normal but significant condition */ +#define APLOG_INFO 6 /* informational */ +#define APLOG_DEBUG 7 /* debug-level messages */ + +#define APLOG_LEVELMASK 7 /* mask off the level value */ + +#endif + +/* APLOG_NOERRNO is ignored and should not be used. It will be + * removed in a future release of Apache. + */ +#define APLOG_NOERRNO (APLOG_LEVELMASK + 1) + +/* Use APLOG_TOCLIENT on ap_log_rerror() to give content + * handlers the option of including the error text in the + * ErrorDocument sent back to the client. Setting APLOG_TOCLIENT + * will cause the error text to be saved in the request_rec->notes + * table, keyed to the string "error-notes", if and only if: + * - the severity level of the message is APLOG_WARNING or greater + * - there are no other "error-notes" set in request_rec->notes + * Once error-notes is set, it is up to the content handler to + * determine whether this text should be sent back to the client. + * Note: Client generated text streams sent back to the client MUST + * be escaped to prevent CSS attacks. + */ +#define APLOG_TOCLIENT ((APLOG_LEVELMASK + 1) * 2) + +/* normal but significant condition on startup, usually printed to stderr */ +#define APLOG_STARTUP ((APLOG_LEVELMASK + 1) * 4) + +#ifndef DEFAULT_LOGLEVEL +#define DEFAULT_LOGLEVEL APLOG_WARNING +#endif + +extern int AP_DECLARE_DATA ap_default_loglevel; + +#define APLOG_MARK __FILE__,__LINE__ + +/** + * Set up for logging to stderr. + * @param p The pool to allocate out of + */ +AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p); + +/** + * Replace logging to stderr with logging to the given file. + * @param p The pool to allocate out of + * @param file Name of the file to log stderr output + */ +AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p, + const char *file); + +/** + * Open the error log and replace stderr with it. + * @param pconf Not used + * @param plog The pool to allocate the logs from + * @param ptemp Pool used for temporary allocations + * @param s_main The main server + * @tip ap_open_logs isn't expected to be used by modules, it is + * an internal core function + */ +int ap_open_logs(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s_main); + +#ifdef CORE_PRIVATE + +/** + * Perform special processing for piped loggers in MPM child + * processes. + * @param p Not used + * @param s Not used + * @tip ap_logs_child_init is not for use by modules; it is an + * internal core function + */ +void ap_logs_child_init(apr_pool_t *p, server_rec *s); + +#endif /* CORE_PRIVATE */ + +/* + * The primary logging functions, ap_log_error, ap_log_rerror, ap_log_cerror, + * and ap_log_perror use a printf style format string to build the log message. + * It is VERY IMPORTANT that you not include any raw data from the network, + * such as the request-URI or request header fields, within the format + * string. Doing so makes the server vulnerable to a denial-of-service + * attack and other messy behavior. Instead, use a simple format string + * like "%s", followed by the string containing the untrusted data. + */ + +/** + * ap_log_error() - log messages which are not related to a particular + * request or connection. This uses a printf-like format to log messages + * to the error_log. + * @param file The file in which this function is called + * @param line The line number on which this function is called + * @param level The level of this error message + * @param status The status code from the previous command + * @param s The server on which we are logging + * @param fmt The format string + * @param ... The arguments to use to fill out fmt. + * @tip Use APLOG_MARK to fill out file and line + * @tip If a request_rec is available, use that with ap_log_rerror() + * in preference to calling this function. Otherwise, if a conn_rec is + * available, use that with ap_log_cerror() in preference to calling + * this function. + * @warning It is VERY IMPORTANT that you not include any raw data from + * the network, such as the request-URI or request header fields, within + * the format string. Doing so makes the server vulnerable to a + * denial-of-service attack and other messy behavior. Instead, use a + * simple format string like "%s", followed by the string containing the + * untrusted data. + * @deffunc void ap_log_error(const char *file, int line, int level, apr_status_t status, const server_rec *s, const char *fmt, ...) + */ +AP_DECLARE(void) ap_log_error(const char *file, int line, int level, + apr_status_t status, const server_rec *s, + const char *fmt, ...) + __attribute__((format(printf,6,7))); + +/** + * ap_log_perror() - log messages which are not related to a particular + * request, connection, or virtual server. This uses a printf-like + * format to log messages to the error_log. + * @param file The file in which this function is called + * @param line The line number on which this function is called + * @param level The level of this error message + * @param status The status code from the previous command + * @param p The pool which we are logging for + * @param fmt The format string + * @param ... The arguments to use to fill out fmt. + * @tip Use APLOG_MARK to fill out file and line + * @warning It is VERY IMPORTANT that you not include any raw data from + * the network, such as the request-URI or request header fields, within + * the format string. Doing so makes the server vulnerable to a + * denial-of-service attack and other messy behavior. Instead, use a + * simple format string like "%s", followed by the string containing the + * untrusted data. + * @deffunc void ap_log_perror(const char *file, int line, int level, apr_status_t status, apr_pool_t *p, const char *fmt, ...) + */ +AP_DECLARE(void) ap_log_perror(const char *file, int line, int level, + apr_status_t status, apr_pool_t *p, + const char *fmt, ...) + __attribute__((format(printf,6,7))); + +/** + * ap_log_rerror() - log messages which are related to a particular + * request. This uses a a printf-like format to log messages to the + * error_log. + * @param file The file in which this function is called + * @param line The line number on which this function is called + * @param level The level of this error message + * @param status The status code from the previous command + * @param r The request which we are logging for + * @param fmt The format string + * @param ... The arguments to use to fill out fmt. + * @tip Use APLOG_MARK to fill out file and line + * @warning It is VERY IMPORTANT that you not include any raw data from + * the network, such as the request-URI or request header fields, within + * the format string. Doing so makes the server vulnerable to a + * denial-of-service attack and other messy behavior. Instead, use a + * simple format string like "%s", followed by the string containing the + * untrusted data. + * @deffunc void ap_log_rerror(const char *file, int line, int level, apr_status_t status, const request_rec *r, const char *fmt, ...) + */ +AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level, + apr_status_t status, const request_rec *r, + const char *fmt, ...) + __attribute__((format(printf,6,7))); + +/** + * ap_log_cerror() - log messages which are related to a particular + * connection. This uses a a printf-like format to log messages to the + * error_log. + * @param file The file in which this function is called + * @param line The line number on which this function is called + * @param level The level of this error message + * @param status The status code from the previous command + * @param c The connection which we are logging for + * @param fmt The format string + * @param ... The arguments to use to fill out fmt. + * @tip Use APLOG_MARK to fill out file and line + * @tip If a request_rec is available, use that with ap_log_rerror() + * in preference to calling this function. + * @warning It is VERY IMPORTANT that you not include any raw data from + * the network, such as the request-URI or request header fields, within + * the format string. Doing so makes the server vulnerable to a + * denial-of-service attack and other messy behavior. Instead, use a + * simple format string like "%s", followed by the string containing the + * untrusted data. + * @deffunc void ap_log_cerror(const char *file, int line, int level, apr_status_t status, const conn_rec *c, const char *fmt, ...) + */ +AP_DECLARE(void) ap_log_cerror(const char *file, int line, int level, + apr_status_t status, const conn_rec *c, + const char *fmt, ...) + __attribute__((format(printf,6,7))); + +/** + * Convert stderr to the error log + * @param s The current server + * @deffunc void ap_error_log2stderr(server_rec *s) + */ +AP_DECLARE(void) ap_error_log2stderr(server_rec *s); + +/** + * Log the current pid of the parent process + * @param p The pool to use for logging + * @param fname The name of the file to log to + */ +AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *fname); + +/** + * Retrieve the pid from a pidfile. + * @param p The pool to use for logging + * @param filename The name of the file containing the pid + * @param mypid Pointer to pid_t (valid only if return APR_SUCCESS) + */ +AP_DECLARE(apr_status_t) ap_read_pid(apr_pool_t *p, const char *filename, pid_t *mypid); + +typedef struct piped_log piped_log; + +/** + * The piped logging structure. Piped logs are used to move functionality + * out of the main server. For example, log rotation is done with piped logs. + */ +struct piped_log { + /** The pool to use for the piped log */ + apr_pool_t *p; + /** The pipe between the server and the logging process */ + apr_file_t *fds[2]; + /* XXX - an #ifdef that needs to be eliminated from public view. Shouldn't + * be hard */ +#ifdef AP_HAVE_RELIABLE_PIPED_LOGS + /** The name of the program the logging process is running */ + char *program; + /** The pid of the logging process */ + apr_proc_t *pid; +#endif +}; + +/** + * Open the piped log process + * @param p The pool to allocate out of + * @param program The program to run in the logging process + * @return The piped log structure + * @deffunc piped_log *ap_open_piped_log(apr_pool_t *p, const char *program) + */ +AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program); + +/** + * Close the piped log and kill the logging process + * @param pl The piped log structure + * @deffunc void ap_close_piped_log(piped_log *pl) + */ +AP_DECLARE(void) ap_close_piped_log(piped_log *pl); + +/** + * A macro to access the read side of the piped log pipe + * @param pl The piped log structure + * @return The native file descriptor + * @deffunc ap_piped_log_read_fd(pl) + */ +#define ap_piped_log_read_fd(pl) ((pl)->fds[0]) + +/** + * A macro to access the write side of the piped log pipe + * @param pl The piped log structure + * @return The native file descriptor + * @deffunc ap_piped_log_read_fd(pl) + */ +#define ap_piped_log_write_fd(pl) ((pl)->fds[1]) + +AP_DECLARE_HOOK(void, error_log, (const char *file, int line, int level, + apr_status_t status, const server_rec *s, + const request_rec *r, apr_pool_t *pool, + const char *errstr)) + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_LOG_H */ diff --git a/trunk/include/http_main.h b/trunk/include/http_main.h new file mode 100644 index 0000000000..fcd6236dcf --- /dev/null +++ b/trunk/include/http_main.h @@ -0,0 +1,58 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_MAIN_H +#define APACHE_HTTP_MAIN_H + +#include "apr_optional.h" + +/* AP_SERVER_BASEARGS is the command argument list parsed by http_main.c + * in apr_getopt() format. Use this for default'ing args that the MPM + * can safely ignore and pass on from its rewrite_args() handler. + */ +#define AP_SERVER_BASEARGS "C:c:D:d:E:e:f:vVlLtSMh?X" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Command line options + */ + +/** The name of the Apache executable */ +AP_DECLARE_DATA extern const char *ap_server_argv0; +/** The global server's ServerRoot */ +AP_DECLARE_DATA extern const char *ap_server_root; + +/* for -C, -c and -D switches */ +/** An array of all -C directives. These are processed before the server's + * config file */ +AP_DECLARE_DATA extern apr_array_header_t *ap_server_pre_read_config; +/** An array of all -c directives. These are processed after the server's + * config file */ +AP_DECLARE_DATA extern apr_array_header_t *ap_server_post_read_config; +/** An array of all -D defines on the command line. This allows people to + * effect the server based on command line options */ +AP_DECLARE_DATA extern apr_array_header_t *ap_server_config_defines; + +APR_DECLARE_OPTIONAL_FN(int, ap_signal_server, (int *, apr_pool_t *)); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_MAIN_H */ diff --git a/trunk/include/http_protocol.h b/trunk/include/http_protocol.h new file mode 100644 index 0000000000..405ff2415a --- /dev/null +++ b/trunk/include/http_protocol.h @@ -0,0 +1,690 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_PROTOCOL_H +#define APACHE_HTTP_PROTOCOL_H + +#include "httpd.h" +#include "apr_hooks.h" +#include "apr_portable.h" +#include "apr_mmap.h" +#include "apr_buckets.h" +#include "util_filter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package HTTP protocol handling + */ + +/** + * This hook allows modules to insert filters for the current error response + * @param r the current request + * @ingroup hooks + */ +AP_DECLARE_HOOK(void,insert_error_filter,(request_rec *r)) + +/* This is an optimization. We keep a record of the filter_rec that + * stores the old_write filter, so that we can avoid strcmp's later. + */ +AP_DECLARE_DATA extern ap_filter_rec_t *ap_old_write_func; + +/* + * Prototypes for routines which either talk directly back to the user, + * or control the ones that eventually do. + */ + +/** + * Read a request and fill in the fields. + * @param c The current connection + * @return The new request_rec + */ +request_rec *ap_read_request(conn_rec *c); + +/** + * Read the mime-encoded headers. + * @param r The current request + */ +AP_DECLARE(void) ap_get_mime_headers(request_rec *r); + +/** + * Optimized version of ap_get_mime_headers() that requires a + * temporary brigade to work with + * @param r The current request + * @param bb temp brigade + */ +AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, + apr_bucket_brigade *bb); + +/* Finish up stuff after a request */ + +/** + * Called at completion of sending the response. It sends the terminating + * protocol information. + * @param r The current request + * @deffunc void ap_finalize_request_protocol(request_rec *r) + */ +AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r); + +/** + * Send error back to client. + * @param r The current request + * @param recursive_error last arg indicates error status in case we get + * an error in the process of trying to deal with an ErrorDocument + * to handle some other error. In that case, we print the default + * report for the first thing that went wrong, and more briefly report + * on the problem with the ErrorDocument. + * @deffunc void ap_send_error_response(request_rec *r, int recursive_error) + */ +AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error); + +/* Set last modified header line from the lastmod date of the associated file. + * Also, set content length. + * + * May return an error status, typically HTTP_NOT_MODIFIED (that when the + * permit_cache argument is set to one). + */ + +/** + * Set the content length for this request + * @param r The current request + * @param length The new content length + * @deffunc void ap_set_content_length(request_rec *r, apr_off_t length) + */ +AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t length); + +/** + * Set the keepalive status for this request + * @param r The current request + * @return 1 if keepalive can be set, 0 otherwise + * @deffunc int ap_set_keepalive(request_rec *r) + */ +AP_DECLARE(int) ap_set_keepalive(request_rec *r); + +/** + * Return the latest rational time from a request/mtime pair. Mtime is + * returned unless it's in the future, in which case we return the current time. + * @param r The current request + * @param mtime The last modified time + * @return the latest rational time. + * @deffunc apr_time_t ap_rationalize_mtime(request_rec *r, apr_time_t mtime) + */ +AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime); + +/** + * Build the content-type that should be sent to the client from the + * content-type specified. The following rules are followed: + * - if type is NULL, type is set to ap_default_type(r) + * - if charset adding is disabled, stop processing and return type. + * - then, if there are no parameters on type, add the default charset + * - return type + * @param r The current request + * @return The content-type + * @deffunc const char *ap_make_content_type(request_rec *r, const char *type); + */ +AP_DECLARE(const char *) ap_make_content_type(request_rec *r, + const char *type); + +#ifdef CORE_PRIVATE +/** + * Precompile metadata structures used by ap_make_content_type() + * @param r The pool to use for allocations + * @deffunc void ap_setup_make_content_type(apr_pool_t *pool) + */ +AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool); +#endif /* CORE_PRIVATE */ + +/** + * Construct an entity tag from the resource information. If it's a real + * file, build in some of the file characteristics. + * @param r The current request + * @param force_weak Force the entity tag to be weak - it could be modified + * again in as short an interval. + * @return The entity tag + * @deffunc char *ap_make_etag(request_rec *r, int force_weak) + */ +AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak); + +/** + * Set the E-tag outgoing header + * @param The current request + * @deffunc void ap_set_etag(request_rec *r) + */ +AP_DECLARE(void) ap_set_etag(request_rec *r); + +/** + * Set the last modified time for the file being sent + * @param r The current request + * @deffunc void ap_set_last_modified(request_rec *r) + */ +AP_DECLARE(void) ap_set_last_modified(request_rec *r); + +/** + * Implements condition GET rules for HTTP/1.1 specification. This function + * inspects the client headers and determines if the response fulfills + * the requirements specified. + * @param r The current request + * @return OK if the response fulfills the condition GET rules, some + * other status code otherwise + * @deffunc int ap_meets_conditions(request_rec *r) + */ +AP_DECLARE(int) ap_meets_conditions(request_rec *r); + +/* Other ways to send stuff at the client. All of these keep track + * of bytes_sent automatically. This indirection is intended to make + * it a little more painless to slide things like HTTP-NG packetization + * underneath the main body of the code later. In the meantime, it lets + * us centralize a bit of accounting (bytes_sent). + * + * These also return the number of bytes written by the call. + * They should only be called with a timeout registered, for obvious reaasons. + * (Ditto the send_header stuff). + */ + +/** + * Send an entire file to the client, using sendfile if supported by the + * current platform + * @param fd The file to send. + * @param r The current request + * @param offset Offset into the file to start sending. + * @param length Amount of data to send + * @param nbytes Amount of data actually sent + * @deffunc apr_status_t ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset, apr_size_t length, apr_size_t *nbytes); + */ +AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset, + apr_size_t length, apr_size_t *nbytes); + +#if APR_HAS_MMAP +/** + * Send an MMAP'ed file to the client + * @param mm The MMAP'ed file to send + * @param r The current request + * @param offset The offset into the MMAP to start sending + * @param length The amount of data to send + * @return The number of bytes sent + * @deffunc size_t ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset, size_t length) + */ +AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset, + size_t length); +#endif + + +/** + * Register a new request method, and return the offset that will be + * associated with that method. + * + * @param p The pool to create registered method numbers from. + * @param methname The name of the new method to register. + * @return Ab int value representing an offset into a bitmask. + */ +AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname); + +/** + * Initialize the method_registry and allocate memory for it. + * + * @param p Pool to allocate memory for the registry from. + */ +AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p); + +/* + * This is a convenience macro to ease with checking a mask + * against a method name. + */ +#define AP_METHOD_CHECK_ALLOWED(mask, methname) \ + ((mask) & (AP_METHOD_BIT << ap_method_number_of((methname)))) + +/** + * Create a new method list with the specified number of preallocated + * slots for extension methods. + * + * @param p Pointer to a pool in which the structure should be + * allocated. + * @param nelts Number of preallocated extension slots + * @return Pointer to the newly created structure. + * @deffunc ap_method_list_t ap_make_method_list(apr_pool_t *p, int nelts) + */ +AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts); +AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest, + ap_method_list_t *src); + +/** + * Search for an HTTP method name in an ap_method_list_t structure, and + * return true if found. + * + * @param method String containing the name of the method to check. + * @param l Pointer to a method list, such as cmd->methods_limited. + * @return 1 if method is in the list, otherwise 0 + * @deffunc int ap_method_in_list(const char *method, ap_method_list_t *l) + */ +AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method); + +/** + * Add an HTTP method name to an ap_method_list_t structure if it isn't + * already listed. + * + * @param method String containing the name of the method to check. + * @param l Pointer to a method list, such as cmd->methods_limited. + * @return None. + * @deffunc void ap_method_in_list(ap_method_list_t *l, const char *method) + */ +AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method); + +/** + * Remove an HTTP method name from an ap_method_list_t structure. + * + * @param l Pointer to a method list, such as cmd->methods_limited. + * @param method String containing the name of the method to remove. + * @return None. + * @deffunc void ap_method_list_remove(ap_method_list_t *l, const char *method) + */ +AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l, + const char *method); + +/** + * Reset a method list to be completely empty. + * + * @param l Pointer to a method list, such as cmd->methods_limited. + * @return None. + * @deffunc void ap_clear_method_list(ap_method_list_t *l) + */ +AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l); + +/** + * Set the content type for this request (r->content_type). + * @param r The current request + * @param ct The new content type + * @deffunc void ap_set_content_type(request_rec *r, const char* ct) + * @warning This function must be called to set r->content_type in order + * for the AddOutputFilterByType directive to work correctly. + */ +AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct); + +/* Hmmm... could macrofy these for now, and maybe forever, though the + * definitions of the macros would get a whole lot hairier. + */ + +/** + * Output one character for this request + * @param c the character to output + * @param r the current request + * @return The number of bytes sent + * @deffunc int ap_rputc(int c, request_rec *r) + */ +AP_DECLARE(int) ap_rputc(int c, request_rec *r); + +/** + * Output a string for the current request + * @param str The string to output + * @param r The current request + * @return The number of bytes sent + * @deffunc int ap_rputs(const char *str, request_rec *r) + */ +AP_DECLARE(int) ap_rputs(const char *str, request_rec *r); + +/** + * Write a buffer for the current request + * @param buf The buffer to write + * @param nbyte The number of bytes to send from the buffer + * @param r The current request + * @return The number of bytes sent + * @deffunc int ap_rwrite(const void *buf, int nbyte, request_rec *r) + */ +AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r); + +/** + * Write an unspecified number of strings to the request + * @param r The current request + * @param ... The strings to write + * @return The number of bytes sent + * @deffunc int ap_rvputs(request_rec *r, ...) + */ +AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r,...); + +/** + * Output data to the client in a printf format + * @param r The current request + * @param fmt The format string + * @param vlist The arguments to use to fill out the format string + * @return The number of bytes sent + * @deffunc int ap_vrprintf(request_rec *r, const char *fmt, va_list vlist) + */ +AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list vlist); + +/** + * Output data to the client in a printf format + * @param r The current request + * @param fmt The format string + * @param ... The arguments to use to fill out the format string + * @return The number of bytes sent + * @deffunc int ap_rprintf(request_rec *r, const char *fmt, ...) + */ +AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt,...) + __attribute__((format(printf,2,3))); +/** + * Flush all of the data for the current request to the client + * @param r The current request + * @return The number of bytes sent + * @deffunc int ap_rflush(request_rec *r) + */ +AP_DECLARE(int) ap_rflush(request_rec *r); + +/** + * Index used in custom_responses array for a specific error code + * (only use outside protocol.c is in getting them configured). + * @param status HTTP status code + * @return The index of the response + * @deffunc int ap_index_of_response(int status) + */ +AP_DECLARE(int) ap_index_of_response(int status); + +/** + * Return the Status-Line for a given status code (excluding the + * HTTP-Version field). If an invalid or unknown status code is + * passed, "500 Internal Server Error" will be returned. + * @param status The HTTP status code + * @return The Status-Line + * @deffunc const char *ap_get_status_line(int status) + */ +AP_DECLARE(const char *) ap_get_status_line(int status); + +/* Reading a block of data from the client connection (e.g., POST arg) */ + +/** + * Setup the client to allow Apache to read the request body. + * @param r The current request + * @param read_policy How the server should interpret a chunked + * transfer-encoding. One of:
    + *    REQUEST_NO_BODY          Send 413 error if message has any body
    + *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
    + *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
    + * 
    + * @return either OK or an error code + * @deffunc int ap_setup_client_block(request_rec *r, int read_policy) + */ +AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy); + +/** + * Determine if the client has sent any data. This also sends a + * 100 Continue response to HTTP/1.1 clients, so modules should not be called + * until the module is ready to read content. + * @warning Never call this function more than once. + * @param r The current request + * @return 0 if there is no message to read, 1 otherwise + * @deffunc int ap_should_client_block(request_rec *r) + */ +AP_DECLARE(int) ap_should_client_block(request_rec *r); + +/** + * Call this in a loop. It will put data into a buffer and return the length + * of the input block + * @param r The current request + * @param buffer The buffer in which to store the data + * @param bufsiz The size of the buffer + * @return Number of bytes inserted into the buffer. When done reading, 0 + * if EOF, or -1 if there was an error + * @deffunc long ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz) + */ +AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz); + +/** + * In HTTP/1.1, any method can have a body. However, most GET handlers + * wouldn't know what to do with a request body if they received one. + * This helper routine tests for and reads any message body in the request, + * simply discarding whatever it receives. We need to do this because + * failing to read the request body would cause it to be interpreted + * as the next request on a persistent connection. + * @param r The current request + * @return error status if request is malformed, OK otherwise + * @deffunc int ap_discard_request_body(request_rec *r) + */ +AP_DECLARE(int) ap_discard_request_body(request_rec *r); + + +/** + * Setup the output headers so that the client knows how to authenticate + * itself the next time, if an authentication request failed. This function + * works for both basic and digest authentication + * @param r The current request + * @deffunc void ap_note_auth_failure(request_rec *r) + */ +AP_DECLARE(void) ap_note_auth_failure(request_rec *r); + +/** + * Setup the output headers so that the client knows how to authenticate + * itself the next time, if an authentication request failed. This function + * works only for basic authentication + * @param r The current request + * @deffunc void ap_note_basic_auth_failure(request_rec *r) + */ +AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r); + +/** + * Setup the output headers so that the client knows how to authenticate + * itself the next time, if an authentication request failed. This function + * works only for digest authentication + * @param r The current request + * @deffunc void ap_note_digest_auth_failure(request_rec *r) + */ +AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r); + +/** + * Get the password from the request headers + * @param r The current request + * @param pw The password as set in the headers + * @return 0 (OK) if it set the 'pw' argument (and assured + * a correct value in r->user); otherwise it returns + * an error code, either HTTP_INTERNAL_SERVER_ERROR if things are + * really confused, HTTP_UNAUTHORIZED if no authentication at all + * seemed to be in use, or DECLINED if there was authentication but + * it wasn't Basic (in which case, the caller should presumably + * decline as well). + * @deffunc int ap_get_basic_auth_pw(request_rec *r, const char **pw) + */ +AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw); + +/** + * parse_uri: break apart the uri + * @warning Side Effects:
    + *    - sets r->args to rest after '?' (or NULL if no '?')
    + *    - sets r->uri to request uri (without r->args part)
    + *    - sets r->hostname (if not set already) from request (scheme://host:port)
    + * 
    + * @param r The current request + * @param uri The uri to break apart + * @deffunc void ap_parse_uri(request_rec *r, const char *uri) + */ +AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri); + +/** + * Get the next line of input for the request + * @param s The buffer into which to read the line + * @param n The size of the buffer + * @param r The request + * @param fold Whether to merge continuation lines + * @return The length of the line, if successful + * n, if the line is too big to fit in the buffer + * -1 for miscellaneous errors + * @deffunc int ap_method_number_of(const char *method) + */ +AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold); + +/** + * Get the next line of input for the request + * + * Note: on ASCII boxes, ap_rgetline is a macro which simply calls + * ap_rgetline_core to get the line of input. + * + * on EBCDIC boxes, ap_rgetline is a wrapper function which + * translates ASCII protocol lines to the local EBCDIC code page + * after getting the line of input. + * + * @param s Pointer to the pointer to the buffer into which the line + * should be read; if *s==NULL, a buffer of the necessary size + * to hold the data will be allocated from the request pool + * @param n The size of the buffer + * @param read The length of the line. + * @param r The request + * @param fold Whether to merge continuation lines + * @param bb Working brigade to use when reading buckets + * @return APR_SUCCESS, if successful + * APR_ENOSPC, if the line is too big to fit in the buffer + * Other errors where appropriate + */ +#if APR_CHARSET_EBCDIC +AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n, + apr_size_t *read, + request_rec *r, int fold, + apr_bucket_brigade *bb); +#else /* ASCII box */ +#define ap_rgetline(s, n, read, r, fold, bb) \ + ap_rgetline_core((s), (n), (read), (r), (fold), (bb)) +#endif +AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + apr_size_t *read, + request_rec *r, int fold, + apr_bucket_brigade *bb); + +/** + * Get the method number associated with the given string, assumed to + * contain an HTTP method. Returns M_INVALID if not recognized. + * @param method A string containing a valid HTTP method + * @return The method number + */ +AP_DECLARE(int) ap_method_number_of(const char *method); + +/** + * Get the method name associated with the given internal method + * number. Returns NULL if not recognized. + * @param p A pool to use for temporary allocations. + * @param methnum An integer value corresponding to an internal method number + * @return The name corresponding to the method number + */ +AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum); + + + /* Hooks */ + /* + * post_read_request --- run right after read_request or internal_redirect, + * and not run during any subrequests. + */ +/** + * This hook allows modules to affect the request immediately after the request + * has been read, and before any other phases have been processes. This allows + * modules to make decisions based upon the input header fields + * @param r The current request + * @return OK or DECLINED + * @deffunc ap_run_post_read_request(request_rec *r) + */ +AP_DECLARE_HOOK(int,post_read_request,(request_rec *r)) + +/** + * This hook allows modules to perform any module-specific logging activities + * over and above the normal server things. + * @param r The current request + * @return OK, DECLINED, or HTTP_... + * @deffunc int ap_run_log_transaction(request_rec *r) + */ +AP_DECLARE_HOOK(int,log_transaction,(request_rec *r)) + +/** + * This hook allows modules to retrieve the http scheme for a request. This + * allows Apache modules to easily extend the schemes that Apache understands + * @param r The current request + * @return The http scheme from the request + * @deffunc const char *ap_run_http_scheme(const request_rec *r) + */ +AP_DECLARE_HOOK(const char *,http_scheme,(const request_rec *r)) + +/** + * Return the default port from the current request + * @param r The current request + * @return The current port + * @deffunc apr_port_t ap_run_default_port(const request_rec *r) + */ +AP_DECLARE_HOOK(apr_port_t,default_port,(const request_rec *r)) + +typedef struct ap_bucket_error ap_bucket_error; + +/** + * A bucket referring to an HTTP error + * This bucket can be passed down the filter stack to indicate that an + * HTTP error occurred while running a filter. In order for this bucket + * to be used successfully, it MUST be sent as the first bucket in the + * first brigade to be sent from a given filter. + */ +struct ap_bucket_error { + /** Number of buckets using this memory */ + apr_bucket_refcount refcount; + /** The error code */ + int status; + /** The error string */ + const char *data; +}; + +AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_error; + +/** + * Determine if a bucket is an error bucket + * @param e The bucket to inspect + * @return true or false + */ +#define AP_BUCKET_IS_ERROR(e) (e->type == &ap_bucket_type_error) + +/** + * Make the bucket passed in an error bucket + * @param b The bucket to make into an error bucket + * @param error The HTTP error code to put in the bucket. + * @param buf An optional error string to put in the bucket. + * @param p A pool to allocate out of. + * @return The new bucket, or NULL if allocation failed + * @deffunc apr_bucket *ap_bucket_error_make(apr_bucket *b, int error, const char *buf, apr_pool_t *p) + */ +AP_DECLARE(apr_bucket *) ap_bucket_error_make(apr_bucket *b, int error, + const char *buf, apr_pool_t *p); + +/** + * Create a bucket referring to an HTTP error. + * @param error The HTTP error code to put in the bucket. + * @param buf An optional error string to put in the bucket. + * @param p A pool to allocate the error string out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + * @deffunc apr_bucket *ap_bucket_error_create(int error, const char *buf, apr_pool_t *p, apr_bucket_alloc_t *list) + */ +AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +AP_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *b); +AP_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, apr_bucket_brigade *b); +AP_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *, + apr_bucket_brigade *); +AP_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(ap_filter_t *f, apr_bucket_brigade *b); + +/* + * Setting up the protocol fields for subsidiary requests... + * Also, a wrapup function to keep the internal accounting straight. + */ +AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r); +AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_PROTOCOL_H */ diff --git a/trunk/include/http_request.h b/trunk/include/http_request.h new file mode 100644 index 0000000000..f5651388e7 --- /dev/null +++ b/trunk/include/http_request.h @@ -0,0 +1,373 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_REQUEST_H +#define APACHE_HTTP_REQUEST_H + +#include "apr_hooks.h" +#include "util_filter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AP_SUBREQ_NO_ARGS 0 +#define AP_SUBREQ_MERGE_ARGS 1 + +/** + * @file http_request.h + * @brief Apache Request library + */ + +/* http_request.c is the code which handles the main line of request + * processing, once a request has been read in (finding the right per- + * directory configuration, building it if necessary, and calling all + * the module dispatch functions in the right order). + * + * The pieces here which are public to the modules, allow them to learn + * how the server would handle some other file or URI, or perhaps even + * direct the server to serve that other file instead of the one the + * client requested directly. + * + * There are two ways to do that. The first is the sub_request mechanism, + * which handles looking up files and URIs as adjuncts to some other + * request (e.g., directory entries for multiviews and directory listings); + * the lookup functions stop short of actually running the request, but + * (e.g., for includes), a module may call for the request to be run + * by calling run_sub_req. The space allocated to create sub_reqs can be + * reclaimed by calling destroy_sub_req --- be sure to copy anything you care + * about which was allocated in its apr_pool_t elsewhere before doing this. + */ + +/** + * An internal handler used by the ap_process_request, all subrequest mechanisms + * and the redirect mechanism. + * @param r The request, subrequest or internal redirect to pre-process + * @return The return code for the request + */ +AP_DECLARE(int) ap_process_request_internal(request_rec *r); + +/** + * Create a subrequest from the given URI. This subrequest can be + * inspected to find information about the requested URI + * @param new_uri The URI to lookup + * @param r The current request + * @param next_filter The first filter the sub_request should use. If this is + * NULL, it defaults to the first filter for the main request + * @return The new request record + * @deffunc request_rec * ap_sub_req_lookup_uri(const char *new_uri, const request_rec *r) + */ +AP_DECLARE(request_rec *) ap_sub_req_lookup_uri(const char *new_uri, + const request_rec *r, + ap_filter_t *next_filter); + +/** + * Create a subrequest for the given file. This subrequest can be + * inspected to find information about the requested file + * @param new_file The file to lookup + * @param r The current request + * @param next_filter The first filter the sub_request should use. If this is + * NULL, it defaults to the first filter for the main request + * @return The new request record + * @deffunc request_rec * ap_sub_req_lookup_file(const char *new_file, const request_rec *r) + */ +AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, + const request_rec *r, + ap_filter_t *next_filter); +/** + * Create a subrequest for the given apr_dir_read result. This subrequest + * can be inspected to find information about the requested file + * @param finfo The apr_dir_read result to lookup + * @param r The current request + * @param subtype What type of subrequest to perform, one of; + *
    + *      AP_SUBREQ_NO_ARGS     ignore r->args and r->path_info
    + *      AP_SUBREQ_MERGE_ARGS  merge r->args and r->path_info
    + * 
    + * @param next_filter The first filter the sub_request should use. If this is + * NULL, it defaults to the first filter for the main request + * @return The new request record + * @deffunc request_rec * ap_sub_req_lookup_dirent(apr_finfo_t *finfo, int subtype, const request_rec *r) + * @tip The apr_dir_read flags value APR_FINFO_MIN|APR_FINFO_NAME flag is the + * minimum recommended query if the results will be passed to apr_dir_read. + * The file info passed must include the name, and must have the same relative + * directory as the current request. + */ +AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *finfo, + const request_rec *r, + int subtype, + ap_filter_t *next_filter); +/** + * Create a subrequest for the given URI using a specific method. This + * subrequest can be inspected to find information about the requested URI + * @param method The method to use in the new subrequest + * @param new_uri The URI to lookup + * @param r The current request + * @param next_filter The first filter the sub_request should use. If this is + * NULL, it defaults to the first filter for the main request + * @return The new request record + * @deffunc request_rec * ap_sub_req_method_uri(const char *method, const char *new_uri, const request_rec *r) + */ +AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_uri, + const request_rec *r, + ap_filter_t *next_filter); +/** + * An output filter to strip EOS buckets from sub-requests. This always + * has to be inserted at the end of a sub-requests filter stack. + * @param f The current filter + * @param bb The brigade to filter + * @deffunc apr_status_t ap_sub_req_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) + */ +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f, + apr_bucket_brigade *bb); + +/** + * Run the handler for the subrequest + * @param r The subrequest to run + * @return The return code for the subrequest + * @deffunc int ap_run_sub_req(request_rec *r) + */ +AP_DECLARE(int) ap_run_sub_req(request_rec *r); + +/** + * Free the memory associated with a subrequest + * @param r The subrequest to finish + * @deffunc void ap_destroy_sub_req(request_rec *r) + */ +AP_DECLARE(void) ap_destroy_sub_req(request_rec *r); + +/* + * Then there's the case that you want some other request to be served + * as the top-level request INSTEAD of what the client requested directly. + * If so, call this from a handler, and then immediately return OK. + */ + +/** + * Redirect the current request to some other uri + * @param new_uri The URI to replace the current request with + * @param r The current request + * @deffunc void ap_internal_redirect(const char *new_uri, request_rec *r) + */ +AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r); + +/** + * This function is designed for things like actions or CGI scripts, when + * using AddHandler, and you want to preserve the content type across + * an internal redirect. + * @param new_uri The URI to replace the current request with. + * @param r The current request + * @deffunc void ap_internal_redirect_handler(const char *new_uri, request_rec *r) + */ +AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r); + +/** + * Redirect the current request to a sub_req, merging the pools + * @param sub_req A subrequest created from this request + * @param r The current request + * @deffunc void ap_internal_fast_redirect(request_rec *sub_req, request_rec *r) + * @tip the sub_req's pool will be merged into r's pool, be very careful + * not to destroy this subrequest, it will be destroyed with the main request! + */ +AP_DECLARE(void) ap_internal_fast_redirect(request_rec *sub_req, request_rec *r); + +/** + * Can be used within any handler to determine if any authentication + * is required for the current request + * @param r The current request + * @return 1 if authentication is required, 0 otherwise + * @deffunc int ap_some_auth_required(request_rec *r) + */ +AP_DECLARE(int) ap_some_auth_required(request_rec *r); + +/** + * Determine if the current request is the main request or a subrequest + * @param r The current request + * @return 1 if this is the main request, 0 otherwise + * @deffunc int ap_is_initial_req(request_rec *r) + */ +AP_DECLARE(int) ap_is_initial_req(request_rec *r); + +/** + * Function to set the r->mtime field to the specified value if it's later + * than what's already there. + * @param r The current request + * @param dependency_time Time to set the mtime to + * @deffunc void ap_update_mtime(request_rec *r, apr_time_t dependency_mtime) + */ +AP_DECLARE(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime); + +/** + * Add one or more methods to the list permitted to access the resource. + * Usually executed by the content handler before the response header is + * sent, but sometimes invoked at an earlier phase if a module knows it + * can set the list authoritatively. Note that the methods are ADDED + * to any already permitted unless the reset flag is non-zero. The + * list is used to generate the Allow response header field when it + * is needed. + * @param r The pointer to the request identifying the resource. + * @param reset Boolean flag indicating whether this list should + * completely replace any current settings. + * @param ... A NULL-terminated list of strings, each identifying a + * method name to add. + * @return None. + * @deffunc void ap_allow_methods(request_rec *r, int reset, ...) + */ +AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...); + +/** + * Add one or more methods to the list permitted to access the resource. + * Usually executed by the content handler before the response header is + * sent, but sometimes invoked at an earlier phase if a module knows it + * can set the list authoritatively. Note that the methods are ADDED + * to any already permitted unless the reset flag is non-zero. The + * list is used to generate the Allow response header field when it + * is needed. + * @param r The pointer to the request identifying the resource. + * @param reset Boolean flag indicating whether this list should + * completely replace any current settings. + * @param ... A list of method identifiers, from the "M_" series + * defined in httpd.h, terminated with a value of -1 + * (e.g., "M_GET, M_POST, M_OPTIONS, -1") + * @return None. + * @deffunc void ap_allow_standard_methods(request_rec *r, int reset, ...) + */ +AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...); + +#define MERGE_ALLOW 0 +#define REPLACE_ALLOW 1 + +#ifdef CORE_PRIVATE +/* Function called by main.c to handle first-level request */ +void ap_process_request(request_rec *); +/** + * Kill the current request + * @param type Why the request is dieing + * @param r The current request + * @deffunc void ap_die(int type, request_rec *r) + */ +AP_DECLARE(void) ap_die(int type, request_rec *r); +#endif + +/* Hooks */ + +/** + * Gives modules a chance to create their request_config entry when the + * request is created. + * @param r The current request + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,create_request,(request_rec *r)) + +/** + * This hook allow modules an opportunity to translate the URI into an + * actual filename. If no modules do anything special, the server's default + * rules will be followed. + * @param r The current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,translate_name,(request_rec *r)) + +/** + * This hook allow modules to set the per_dir_config based on their own + * context (such as sections) and responds to contextless requests + * such as TRACE that need no security or filesystem mapping. + * based on the filesystem. + * @param r The current request + * @return DONE (or HTTP_) if this contextless request was just fulfilled + * (such as TRACE), OK if this is not a file, and DECLINED if this is a file. + * The core map_to_storage (HOOK_RUN_REALLY_LAST) will directory_walk + * and file_walk the r->filename. + * + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,map_to_storage,(request_rec *r)) + +/** + * This hook is used to analyze the request headers, authenticate the user, + * and set the user information in the request record (r->user and + * r->ap_auth_type). This hook is only run when Apache determines that + * authentication/authorization is required for this resource (as determined + * by the 'Require' directive). It runs after the access_checker hook, and + * before the auth_checker hook. + * + * @param r The current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,check_user_id,(request_rec *r)) + +/** + * Allows modules to perform module-specific fixing of header fields. This + * is invoked just before any content-handler + * @param r The current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,fixups,(request_rec *r)) + +/** + * This routine is called to determine and/or set the various document type + * information bits, like Content-type (via r->content_type), language, et + * cetera. + * @param r the current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,type_checker,(request_rec *r)) + +/** + * This hook is used to apply additional access control to this resource. + * It runs *before* a user is authenticated, so this hook is really to + * apply additional restrictions independent of a user. It also runs + * independent of 'Require' directive usage. + * + * @param r the current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,access_checker,(request_rec *r)) + +/** + * This hook is used to check to see if the resource being requested + * is available for the authenticated user (r->user and r->ap_auth_type). + * It runs after the access_checker and check_user_id hooks. Note that + * it will *only* be called if Apache determines that access control has + * been applied to this resource (through a 'Require' directive). + * + * @param r the current request + * @return OK, DECLINED, or HTTP_... + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,auth_checker,(request_rec *r)) + +/** + * This hook allows modules to insert filters for the current request + * @param r the current request + * @ingroup hooks + */ +AP_DECLARE_HOOK(void,insert_filter,(request_rec *r)) + +AP_DECLARE(int) ap_location_walk(request_rec *r); +AP_DECLARE(int) ap_directory_walk(request_rec *r); +AP_DECLARE(int) ap_file_walk(request_rec *r); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_REQUEST_H */ diff --git a/trunk/include/http_vhost.h b/trunk/include/http_vhost.h new file mode 100644 index 0000000000..1459441246 --- /dev/null +++ b/trunk/include/http_vhost.h @@ -0,0 +1,109 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTP_VHOST_H +#define APACHE_HTTP_VHOST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Virtual Host package + */ + +/** + * called before any config is read + * @param p Pool to allocate out of + */ +AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p); + +/** + * called after the config has been read to compile the tables needed to do + * the run-time vhost lookups + * @param p The pool to allocate out of + * @param main_server The start of the virtual host list + * @deffunc ap_fini_vhost_config(apr_pool_t *p, server_rec *main_server) + */ +AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_server); + +/** + * handle addresses in statement + * @param p The pool to allocate out of + * @param hostname The hostname in the VirtualHost statement + * @param s The list of Virtual Hosts. + */ +const char *ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s); + +/* handle NameVirtualHost directive */ +const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, + const char *arg); + +/** + * Callback function for every Name Based Virtual Host. + * @param baton Opaque user object + * @param conn The current Connection + * @param s The current Server + * @see ap_vhost_iterate_given_conn + * @return 0 on success, any non-zero return will stop the iteration. + */ +typedef int(*ap_vhost_iterate_conn_cb)(void* baton, conn_rec* conn, server_rec* s); + +/** + * For every virtual host on this connection, call func_cb. + * @param conn The current connection + * @param func_cb Function called for every Name Based Virtual Host for this + * connection. + * @param baton Opaque object passed to func_cb. + * @return The return value from func_cb. + * @note If func_cb returns non-zero, the function will return at this point, + * and not continue iterating the virtual hosts. + */ +AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn, + ap_vhost_iterate_conn_cb func_cb, + void* baton); + +/** + * given an ip address only, give our best guess as to what vhost it is + * @param conn The current connection + */ +AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn); + +/** + * ap_update_vhost_given_ip is never enough, and this is always called after + * the headers have been read. It may change r->server. + * @param r The current request + */ +AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r); + +/** + * Match the host in the header with the hostname of the server for this + * request. + * @param r The current request + * @param host The hostname in the headers + * @param port The port from the headers + * @return return 1 if the host:port matches any of the aliases of r->server, + * return 0 otherwise + * @deffunc int ap_matches_request_vhost(request_rec *r, const char *host, apr_port_t port) + */ +AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host, + apr_port_t port); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_VHOST_H */ diff --git a/trunk/include/httpd.h b/trunk/include/httpd.h new file mode 100644 index 0000000000..761a612b6a --- /dev/null +++ b/trunk/include/httpd.h @@ -0,0 +1,1758 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_HTTPD_H +#define APACHE_HTTPD_H + +/** + * @file httpd.h + * @brief HTTP Daemon routines + */ + +/* XXX - We need to push more stuff to other .h files, or even .c files, to + * make this file smaller + */ + +/* Headers in which EVERYONE has an interest... */ +#include "ap_config.h" +#include "ap_mmn.h" + +#include "ap_release.h" + +#include "apr.h" +#include "apr_general.h" +#include "apr_tables.h" +#include "apr_pools.h" +#include "apr_time.h" +#include "apr_network_io.h" +#include "apr_buckets.h" +#include "apr_poll.h" + +#include "os.h" + +#include "ap_regex.h" + +#if APR_HAVE_STDLIB_H +#include +#endif + +/* Note: apr_uri.h is also included, see below */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CORE_PRIVATE + +/* ----------------------------- config dir ------------------------------ */ + +/* Define this to be the default server home dir. Most things later in this + * file with a relative pathname will have this added. + */ +#ifndef HTTPD_ROOT +#ifdef OS2 +/* Set default for OS/2 file system */ +#define HTTPD_ROOT "/os2httpd" +#elif defined(WIN32) +/* Set default for Windows file system */ +#define HTTPD_ROOT "/apache" +#elif defined (BEOS) +/* Set the default for BeOS */ +#define HTTPD_ROOT "/boot/home/apache" +#elif defined (NETWARE) +/* Set the default for NetWare */ +#define HTTPD_ROOT "/apache" +#else +#define HTTPD_ROOT "/usr/local/apache" +#endif +#endif /* HTTPD_ROOT */ + +/* + * --------- You shouldn't have to edit anything below this line ---------- + * + * Any modifications to any defaults not defined above should be done in the + * respective configuration file. + * + */ + +/* Default location of documents. Can be overridden by the DocumentRoot + * directive. + */ +#ifndef DOCUMENT_LOCATION +#ifdef OS2 +/* Set default for OS/2 file system */ +#define DOCUMENT_LOCATION HTTPD_ROOT "/docs" +#else +#define DOCUMENT_LOCATION HTTPD_ROOT "/htdocs" +#endif +#endif /* DOCUMENT_LOCATION */ + +/* Maximum number of dynamically loaded modules */ +#ifndef DYNAMIC_MODULE_LIMIT +#define DYNAMIC_MODULE_LIMIT 128 +#endif + +/* Default administrator's address */ +#define DEFAULT_ADMIN "[no address given]" + +/* The name of the log files */ +#ifndef DEFAULT_ERRORLOG +#if defined(OS2) || defined(WIN32) +#define DEFAULT_ERRORLOG "logs/error.log" +#else +#define DEFAULT_ERRORLOG "logs/error_log" +#endif +#endif /* DEFAULT_ERRORLOG */ + +/* Define this to be what your per-directory security files are called */ +#ifndef DEFAULT_ACCESS_FNAME +#ifdef OS2 +/* Set default for OS/2 file system */ +#define DEFAULT_ACCESS_FNAME "htaccess" +#else +#define DEFAULT_ACCESS_FNAME ".htaccess" +#endif +#endif /* DEFAULT_ACCESS_FNAME */ + +/* The name of the server config file */ +#ifndef SERVER_CONFIG_FILE +#define SERVER_CONFIG_FILE "conf/httpd.conf" +#endif + +/* The default path for CGI scripts if none is currently set */ +#ifndef DEFAULT_PATH +#define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin" +#endif + +/* The path to the suExec wrapper, can be overridden in Configuration */ +#ifndef SUEXEC_BIN +#define SUEXEC_BIN HTTPD_ROOT "/bin/suexec" +#endif + +/* The timeout for waiting for messages */ +#ifndef DEFAULT_TIMEOUT +#define DEFAULT_TIMEOUT 300 +#endif + +/* The timeout for waiting for keepalive timeout until next request */ +#ifndef DEFAULT_KEEPALIVE_TIMEOUT +#define DEFAULT_KEEPALIVE_TIMEOUT 5 +#endif + +/* The number of requests to entertain per connection */ +#ifndef DEFAULT_KEEPALIVE +#define DEFAULT_KEEPALIVE 100 +#endif + +/* Limits on the size of various request items. These limits primarily + * exist to prevent simple denial-of-service attacks on a server based + * on misuse of the protocol. The recommended values will depend on the + * nature of the server resources -- CGI scripts and database backends + * might require large values, but most servers could get by with much + * smaller limits than we use below. The request message body size can + * be limited by the per-dir config directive LimitRequestBody. + * + * Internal buffer sizes are two bytes more than the DEFAULT_LIMIT_REQUEST_LINE + * and DEFAULT_LIMIT_REQUEST_FIELDSIZE below, which explains the 8190. + * These two limits can be lowered (but not raised) by the server config + * directives LimitRequestLine and LimitRequestFieldsize, respectively. + * + * DEFAULT_LIMIT_REQUEST_FIELDS can be modified or disabled (set = 0) by + * the server config directive LimitRequestFields. + */ +#ifndef DEFAULT_LIMIT_REQUEST_LINE +#define DEFAULT_LIMIT_REQUEST_LINE 8190 +#endif /* default limit on bytes in Request-Line (Method+URI+HTTP-version) */ +#ifndef DEFAULT_LIMIT_REQUEST_FIELDSIZE +#define DEFAULT_LIMIT_REQUEST_FIELDSIZE 8190 +#endif /* default limit on bytes in any one header field */ +#ifndef DEFAULT_LIMIT_REQUEST_FIELDS +#define DEFAULT_LIMIT_REQUEST_FIELDS 100 +#endif /* default limit on number of request header fields */ + + +/** + * The default default character set name to add if AddDefaultCharset is + * enabled. Overridden with AddDefaultCharsetName. + */ +#define DEFAULT_ADD_DEFAULT_CHARSET_NAME "iso-8859-1" + +#endif /* CORE_PRIVATE */ + +/** default HTTP Server protocol */ +#define AP_SERVER_PROTOCOL "HTTP/1.1" + + +/* ------------------ stuff that modules are allowed to look at ----------- */ + +/** Define this to be what your HTML directory content files are called */ +#ifndef AP_DEFAULT_INDEX +#define AP_DEFAULT_INDEX "index.html" +#endif + + +/** + * Define this to be what type you'd like returned for files with unknown + * suffixes. + * @warning MUST be all lower case. + */ +#ifndef DEFAULT_CONTENT_TYPE +#define DEFAULT_CONTENT_TYPE "text/plain" +#endif + +/** The name of the MIME types file */ +#ifndef AP_TYPES_CONFIG_FILE +#define AP_TYPES_CONFIG_FILE "conf/mime.types" +#endif + +/* + * Define the HTML doctype strings centrally. + */ +/** HTML 2.0 Doctype */ +#define DOCTYPE_HTML_2_0 "\n" +/** HTML 3.2 Doctype */ +#define DOCTYPE_HTML_3_2 "\n" +/** HTML 4.0 Strict Doctype */ +#define DOCTYPE_HTML_4_0S "\n" +/** HTML 4.0 Transitional Doctype */ +#define DOCTYPE_HTML_4_0T "\n" +/** HTML 4.0 Frameset Doctype */ +#define DOCTYPE_HTML_4_0F "\n" +/** XHTML 1.0 Strict Doctype */ +#define DOCTYPE_XHTML_1_0S "\n" +/** XHTML 1.0 Transitional Doctype */ +#define DOCTYPE_XHTML_1_0T "\n" +/** XHTML 1.0 Frameset Doctype */ +#define DOCTYPE_XHTML_1_0F "" + +/** Internal representation for a HTTP protocol number, e.g., HTTP/1.1 */ + +#define HTTP_VERSION(major,minor) (1000*(major)+(minor)) +/** Major part of HTTP protocol */ +#define HTTP_VERSION_MAJOR(number) ((number)/1000) +/** Minor part of HTTP protocol */ +#define HTTP_VERSION_MINOR(number) ((number)%1000) + +/* -------------- Port number for server running standalone --------------- */ + +/** default HTTP Port */ +#define DEFAULT_HTTP_PORT 80 +/** default HTTPS Port */ +#define DEFAULT_HTTPS_PORT 443 +/** + * Check whether @a port is the default port for the request @a r. + * @param port The port number + * @param r The request + * @see #ap_default_port + */ +#define ap_is_default_port(port,r) ((port) == ap_default_port(r)) +/** + * Get the default port for a request (which depends on the scheme). + * @param r The request + */ +#define ap_default_port(r) ap_run_default_port(r) +/** + * Get the scheme for a request. + * @param r The request + */ +#define ap_http_scheme(r) ap_run_http_scheme(r) + +/** The default string lengths */ +#define MAX_STRING_LEN HUGE_STRING_LEN +#define HUGE_STRING_LEN 8192 + +/** The size of the server's internal read-write buffers */ +#define AP_IOBUFSIZE 8192 + +/** The max number of regex captures that can be expanded by ap_pregsub */ +#define AP_MAX_REG_MATCH 10 + +/** + * APR_HAS_LARGE_FILES introduces the problem of spliting sendfile into + * mutiple buckets, no greater than MAX(apr_size_t), and more granular + * than that in case the brigade code/filters attempt to read it directly. + * ### 16mb is an invention, no idea if it is reasonable. + */ +#define AP_MAX_SENDFILE 16777216 /* 2^24 */ + +/** + * Special Apache error codes. These are basically used + * in http_main.c so we can keep track of various errors. + * + */ +/** a normal exit */ +#define APEXIT_OK 0x0 +/** A fatal error arising during the server's init sequence */ +#define APEXIT_INIT 0x2 +/** The child died during its init sequence */ +#define APEXIT_CHILDINIT 0x3 +/** + * The child exited due to a resource shortage. + * The parent should limit the rate of forking until + * the situation is resolved. + */ +#define APEXIT_CHILDSICK 0x7 +/** + * A fatal error, resulting in the whole server aborting. + * If a child exits with this error, the parent process + * considers this a server-wide fatal error and aborts. + */ +#define APEXIT_CHILDFATAL 0xf + +#ifndef AP_DECLARE +/** + * Stuff marked #AP_DECLARE is part of the API, and intended for use + * by modules. Its purpose is to allow us to add attributes that + * particular platforms or compilers require to every exported function. + */ +# define AP_DECLARE(type) type +#endif + +#ifndef AP_DECLARE_NONSTD +/** + * Stuff marked #AP_DECLARE_NONSTD is part of the API, and intended for + * use by modules. The difference between #AP_DECLARE and + * #AP_DECLARE_NONSTD is that the latter is required for any functions + * which use varargs or are used via indirect function call. This + * is to accomodate the two calling conventions in windows dlls. + */ +# define AP_DECLARE_NONSTD(type) type +#endif +#ifndef AP_DECLARE_DATA +# define AP_DECLARE_DATA +#endif + +#ifndef AP_MODULE_DECLARE +# define AP_MODULE_DECLARE(type) type +#endif +#ifndef AP_MODULE_DECLARE_NONSTD +# define AP_MODULE_DECLARE_NONSTD(type) type +#endif +#ifndef AP_MODULE_DECLARE_DATA +# define AP_MODULE_DECLARE_DATA +#endif + +/** + * @internal + * modules should not used functions marked AP_CORE_DECLARE + */ +#ifndef AP_CORE_DECLARE +# define AP_CORE_DECLARE AP_DECLARE +#endif +/** + * @internal + * modules should not used functions marked AP_CORE_DECLARE_NONSTD + */ + +#ifndef AP_CORE_DECLARE_NONSTD +# define AP_CORE_DECLARE_NONSTD AP_DECLARE_NONSTD +#endif + +/** + * The numeric version information is broken out into fields within this + * structure. + */ +typedef struct { + int major; /**< major number */ + int minor; /**< minor number */ + int patch; /**< patch number */ + const char *add_string; /**< additional string like "-dev" */ +} ap_version_t; + +/** + * Return httpd's version information in a numeric form. + * + * @param version Pointer to a version structure for returning the version + * information. + */ +AP_DECLARE(void) ap_get_server_revision(ap_version_t *version); + +/** + * Get the server version string + * @return The server version string + */ +AP_DECLARE(const char *) ap_get_server_version(void); + +/** + * Add a component to the version string + * @param pconf The pool to allocate the component from + * @param component The string to add + */ +AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component); + +/** + * Get the date a time that the server was built + * @return The server build time string + */ +AP_DECLARE(const char *) ap_get_server_built(void); + +#define DECLINED -1 /**< Module declines to handle */ +#define DONE -2 /**< Module has served the response completely + * - it's safe to die() with no more output + */ +#define OK 0 /**< Module has handled this stage. */ + + +/** + * @defgroup HTTP_Status HTTP Status Codes + * @{ + */ +/** + * The size of the static array in http_protocol.c for storing + * all of the potential response status-lines (a sparse table). + * A future version should dynamically generate the apr_table_t at startup. + */ +#define RESPONSE_CODES 57 + +#define HTTP_CONTINUE 100 +#define HTTP_SWITCHING_PROTOCOLS 101 +#define HTTP_PROCESSING 102 +#define HTTP_OK 200 +#define HTTP_CREATED 201 +#define HTTP_ACCEPTED 202 +#define HTTP_NON_AUTHORITATIVE 203 +#define HTTP_NO_CONTENT 204 +#define HTTP_RESET_CONTENT 205 +#define HTTP_PARTIAL_CONTENT 206 +#define HTTP_MULTI_STATUS 207 +#define HTTP_MULTIPLE_CHOICES 300 +#define HTTP_MOVED_PERMANENTLY 301 +#define HTTP_MOVED_TEMPORARILY 302 +#define HTTP_SEE_OTHER 303 +#define HTTP_NOT_MODIFIED 304 +#define HTTP_USE_PROXY 305 +#define HTTP_TEMPORARY_REDIRECT 307 +#define HTTP_BAD_REQUEST 400 +#define HTTP_UNAUTHORIZED 401 +#define HTTP_PAYMENT_REQUIRED 402 +#define HTTP_FORBIDDEN 403 +#define HTTP_NOT_FOUND 404 +#define HTTP_METHOD_NOT_ALLOWED 405 +#define HTTP_NOT_ACCEPTABLE 406 +#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407 +#define HTTP_REQUEST_TIME_OUT 408 +#define HTTP_CONFLICT 409 +#define HTTP_GONE 410 +#define HTTP_LENGTH_REQUIRED 411 +#define HTTP_PRECONDITION_FAILED 412 +#define HTTP_REQUEST_ENTITY_TOO_LARGE 413 +#define HTTP_REQUEST_URI_TOO_LARGE 414 +#define HTTP_UNSUPPORTED_MEDIA_TYPE 415 +#define HTTP_RANGE_NOT_SATISFIABLE 416 +#define HTTP_EXPECTATION_FAILED 417 +#define HTTP_UNPROCESSABLE_ENTITY 422 +#define HTTP_LOCKED 423 +#define HTTP_FAILED_DEPENDENCY 424 +#define HTTP_UPGRADE_REQUIRED 426 +#define HTTP_INTERNAL_SERVER_ERROR 500 +#define HTTP_NOT_IMPLEMENTED 501 +#define HTTP_BAD_GATEWAY 502 +#define HTTP_SERVICE_UNAVAILABLE 503 +#define HTTP_GATEWAY_TIME_OUT 504 +#define HTTP_VERSION_NOT_SUPPORTED 505 +#define HTTP_VARIANT_ALSO_VARIES 506 +#define HTTP_INSUFFICIENT_STORAGE 507 +#define HTTP_NOT_EXTENDED 510 + +/** is the status code informational */ +#define ap_is_HTTP_INFO(x) (((x) >= 100)&&((x) < 200)) +/** is the status code OK ?*/ +#define ap_is_HTTP_SUCCESS(x) (((x) >= 200)&&((x) < 300)) +/** is the status code a redirect */ +#define ap_is_HTTP_REDIRECT(x) (((x) >= 300)&&((x) < 400)) +/** is the status code a error (client or server) */ +#define ap_is_HTTP_ERROR(x) (((x) >= 400)&&((x) < 600)) +/** is the status code a client error */ +#define ap_is_HTTP_CLIENT_ERROR(x) (((x) >= 400)&&((x) < 500)) +/** is the status code a server error */ +#define ap_is_HTTP_SERVER_ERROR(x) (((x) >= 500)&&((x) < 600)) + +/** should the status code drop the connection */ +#define ap_status_drops_connection(x) \ + (((x) == HTTP_BAD_REQUEST) || \ + ((x) == HTTP_REQUEST_TIME_OUT) || \ + ((x) == HTTP_LENGTH_REQUIRED) || \ + ((x) == HTTP_REQUEST_ENTITY_TOO_LARGE) || \ + ((x) == HTTP_REQUEST_URI_TOO_LARGE) || \ + ((x) == HTTP_INTERNAL_SERVER_ERROR) || \ + ((x) == HTTP_SERVICE_UNAVAILABLE) || \ + ((x) == HTTP_NOT_IMPLEMENTED)) +/** @} */ +/** + * @defgroup Methods List of Methods recognized by the server + * @{ + */ +/** + * Methods recognized (but not necessarily handled) by the server. + * These constants are used in bit shifting masks of size int, so it is + * unsafe to have more methods than bits in an int. HEAD == M_GET. + * This list must be tracked by the list in http_protocol.c in routine + * ap_method_name_of(). + */ +#define M_GET 0 /* RFC 2616: HTTP */ +#define M_PUT 1 /* : */ +#define M_POST 2 +#define M_DELETE 3 +#define M_CONNECT 4 +#define M_OPTIONS 5 +#define M_TRACE 6 /* RFC 2616: HTTP */ +#define M_PATCH 7 /* no rfc(!) ### remove this one? */ +#define M_PROPFIND 8 /* RFC 2518: WebDAV */ +#define M_PROPPATCH 9 /* : */ +#define M_MKCOL 10 +#define M_COPY 11 +#define M_MOVE 12 +#define M_LOCK 13 +#define M_UNLOCK 14 /* RFC 2518: WebDAV */ +#define M_VERSION_CONTROL 15 /* RFC 3253: WebDAV Versioning */ +#define M_CHECKOUT 16 /* : */ +#define M_UNCHECKOUT 17 +#define M_CHECKIN 18 +#define M_UPDATE 19 +#define M_LABEL 20 +#define M_REPORT 21 +#define M_MKWORKSPACE 22 +#define M_MKACTIVITY 23 +#define M_BASELINE_CONTROL 24 +#define M_MERGE 25 +#define M_INVALID 26 /* RFC 3253: WebDAV Versioning */ + +/** + * METHODS needs to be equal to the number of bits + * we are using for limit masks. + */ +#define METHODS 64 + +/** + * The method mask bit to shift for anding with a bitmask. + */ +#define AP_METHOD_BIT ((apr_int64_t)1) +/** @} */ + + +/** + * Structure for handling HTTP methods. Methods known to the server are + * accessed via a bitmask shortcut; extension methods are handled by + * an array. + */ +typedef struct ap_method_list_t ap_method_list_t; +struct ap_method_list_t { + /* The bitmask used for known methods */ + apr_int64_t method_mask; + /* the array used for extension methods */ + apr_array_header_t *method_list; +}; +/** + * @defgroup module_magic Module Magic mime types + * @{ + */ +/** Magic for mod_cgi[d] */ +#define CGI_MAGIC_TYPE "application/x-httpd-cgi" +/** Magic for mod_include */ +#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html" +/** Magic for mod_include */ +#define INCLUDES_MAGIC_TYPE3 "text/x-server-parsed-html3" +/** Magic for mod_dir */ +#define DIR_MAGIC_TYPE "httpd/unix-directory" + +/** @} */ +/* Just in case your linefeed isn't the one the other end is expecting. */ +#if !APR_CHARSET_EBCDIC +/** linefeed */ +#define LF 10 +/** carrige return */ +#define CR 13 +/** carrige return /Line Feed Combo */ +#define CRLF "\015\012" +#else /* APR_CHARSET_EBCDIC */ +/* For platforms using the EBCDIC charset, the transition ASCII->EBCDIC is done + * in the buff package (bread/bputs/bwrite). Everywhere else, we use + * "native EBCDIC" CR and NL characters. These are therefore + * defined as + * '\r' and '\n'. + */ +#define CR '\r' +#define LF '\n' +#define CRLF "\r\n" +#endif /* APR_CHARSET_EBCDIC */ + +/** + * @defgroup values_request_rec_body Possible values for request_rec.read_body + * @{ + * Possible values for request_rec.read_body (set by handling module): + */ + +/** Send 413 error if message has any body */ +#define REQUEST_NO_BODY 0 +/** Send 411 error if body without Content-Length */ +#define REQUEST_CHUNKED_ERROR 1 +/** If chunked, remove the chunks for me. */ +#define REQUEST_CHUNKED_DECHUNK 2 +/** @} */ + +/** + * @defgroup values_request_rec_used_path_info Possible values for request_rec.used_path_info + * @{ + * Possible values for request_rec.used_path_info: + */ + +/** Accept the path_info from the request */ +#define AP_REQ_ACCEPT_PATH_INFO 0 +/** Return a 404 error if path_info was given */ +#define AP_REQ_REJECT_PATH_INFO 1 +/** Module may chose to use the given path_info */ +#define AP_REQ_DEFAULT_PATH_INFO 2 +/** @} */ + +/* + * Things which may vary per file-lookup WITHIN a request --- + * e.g., state of MIME config. Basically, the name of an object, info + * about the object, and any other info we may ahve which may need to + * change as we go poking around looking for it (e.g., overridden by + * .htaccess files). + * + * Note how the default state of almost all these things is properly + * zero, so that allocating it with pcalloc does the right thing without + * a whole lot of hairy initialization... so long as we are willing to + * make the (fairly) portable assumption that the bit pattern of a NULL + * pointer is, in fact, zero. + */ + +/** + * This represents the result of calling htaccess; these are cached for + * each request. + */ +struct htaccess_result { + /** the directory to which this applies */ + const char *dir; + /** the overrides allowed for the .htaccess file */ + int override; + /** the override options allowed for the .htaccess file */ + int override_opts; + /** the configuration directives */ + struct ap_conf_vector_t *htaccess; + /** the next one, or NULL if no more; N.B. never change this */ + const struct htaccess_result *next; +}; + +/* The following four types define a hierarchy of activities, so that + * given a request_rec r you can write r->connection->server->process + * to get to the process_rec. While this reduces substantially the + * number of arguments that various hooks require beware that in + * threaded versions of the server you must consider multiplexing + * issues. */ + + +/** A structure that represents one process */ +typedef struct process_rec process_rec; +/** A structure that represents a virtual server */ +typedef struct server_rec server_rec; +/** A structure that represents one connection */ +typedef struct conn_rec conn_rec; +/** A structure that represents the current request */ +typedef struct request_rec request_rec; +/** A structure that represents the status of the current connection */ +typedef struct conn_state_t conn_state_t; + +/* ### would be nice to not include this from httpd.h ... */ +/* This comes after we have defined the request_rec type */ +#include "apr_uri.h" + +/** A structure that represents one process */ +struct process_rec { + /** Global pool. Cleared upon normal exit */ + apr_pool_t *pool; + /** Configuration pool. Cleared upon restart */ + apr_pool_t *pconf; + /** Number of command line arguments passed to the program */ + int argc; + /** The command line arguments */ + const char * const *argv; + /** The program name used to execute the program */ + const char *short_name; +}; + +/** A structure that represents the current request */ +struct request_rec { + /** The pool associated with the request */ + apr_pool_t *pool; + /** The connection to the client */ + conn_rec *connection; + /** The virtual host for this request */ + server_rec *server; + + /** Pointer to the redirected request if this is an external redirect */ + request_rec *next; + /** Pointer to the previous request if this is an internal redirect */ + request_rec *prev; + + /** Pointer to the main request if this is a sub-request + * (see http_request.h) */ + request_rec *main; + + /* Info about the request itself... we begin with stuff that only + * protocol.c should ever touch... + */ + /** First line of request */ + char *the_request; + /** HTTP/0.9, "simple" request (e.g. GET /foo\n w/no headers) */ + int assbackwards; + /** A proxy request (calculated during post_read_request/translate_name) + * possible values PROXYREQ_NONE, PROXYREQ_PROXY, PROXYREQ_REVERSE, + * PROXYREQ_RESPONSE + */ + int proxyreq; + /** HEAD request, as opposed to GET */ + int header_only; + /** Protocol string, as given to us, or HTTP/0.9 */ + char *protocol; + /** Protocol version number of protocol; 1.1 = 1001 */ + int proto_num; + /** Host, as set by full URI or Host: */ + const char *hostname; + + /** Time when the request started */ + apr_time_t request_time; + + /** Status line, if set by script */ + const char *status_line; + /** Status line */ + int status; + + /* Request method, two ways; also, protocol, etc.. Outside of protocol.c, + * look, but don't touch. + */ + + /** Request method (eg. GET, HEAD, POST, etc.) */ + const char *method; + /** M_GET, M_POST, etc. */ + int method_number; + + /** + * 'allowed' is a bitvector of the allowed methods. + * + * A handler must ensure that the request method is one that + * it is capable of handling. Generally modules should DECLINE + * any request methods they do not handle. Prior to aborting the + * handler like this the handler should set r->allowed to the list + * of methods that it is willing to handle. This bitvector is used + * to construct the "Allow:" header required for OPTIONS requests, + * and HTTP_METHOD_NOT_ALLOWED and HTTP_NOT_IMPLEMENTED status codes. + * + * Since the default_handler deals with OPTIONS, all modules can + * usually decline to deal with OPTIONS. TRACE is always allowed, + * modules don't need to set it explicitly. + * + * Since the default_handler will always handle a GET, a + * module which does *not* implement GET should probably return + * HTTP_METHOD_NOT_ALLOWED. Unfortunately this means that a Script GET + * handler can't be installed by mod_actions. + */ + apr_int64_t allowed; + /** Array of extension methods */ + apr_array_header_t *allowed_xmethods; + /** List of allowed methods */ + ap_method_list_t *allowed_methods; + + /** byte count in stream is for body */ + apr_off_t sent_bodyct; + /** body byte count, for easy access */ + apr_off_t bytes_sent; + /** Last modified time of the requested resource */ + apr_time_t mtime; + + /* HTTP/1.1 connection-level features */ + + /** sending chunked transfer-coding */ + int chunked; + /** The Range: header */ + const char *range; + /** The "real" content length */ + apr_off_t clength; + + /** Remaining bytes left to read from the request body */ + apr_off_t remaining; + /** Number of bytes that have been read from the request body */ + apr_off_t read_length; + /** Method for reading the request body + * (eg. REQUEST_CHUNKED_ERROR, REQUEST_NO_BODY, + * REQUEST_CHUNKED_DECHUNK, etc...) */ + int read_body; + /** reading chunked transfer-coding */ + int read_chunked; + /** is client waiting for a 100 response? */ + unsigned expecting_100; + + /* MIME header environments, in and out. Also, an array containing + * environment variables to be passed to subprocesses, so people can + * write modules to add to that environment. + * + * The difference between headers_out and err_headers_out is that the + * latter are printed even on error, and persist across internal redirects + * (so the headers printed for ErrorDocument handlers will have them). + * + * The 'notes' apr_table_t is for notes from one module to another, with no + * other set purpose in mind... + */ + + /** MIME header environment from the request */ + apr_table_t *headers_in; + /** MIME header environment for the response */ + apr_table_t *headers_out; + /** MIME header environment for the response, printed even on errors and + * persist across internal redirects */ + apr_table_t *err_headers_out; + /** Array of environment variables to be used for sub processes */ + apr_table_t *subprocess_env; + /** Notes from one module to another */ + apr_table_t *notes; + + /* content_type, handler, content_encoding, and all content_languages + * MUST be lowercased strings. They may be pointers to static strings; + * they should not be modified in place. + */ + /** The content-type for the current request */ + const char *content_type; /* Break these out --- we dispatch on 'em */ + /** The handler string that we use to call a handler function */ + const char *handler; /* What we *really* dispatch on */ + + /** How to encode the data */ + const char *content_encoding; + /** Array of strings representing the content languages */ + apr_array_header_t *content_languages; + + /** variant list validator (if negotiated) */ + char *vlist_validator; + + /** If an authentication check was made, this gets set to the user name. */ + char *user; + /** If an authentication check was made, this gets set to the auth type. */ + char *ap_auth_type; + + /** This response can not be cached */ + int no_cache; + /** There is no local copy of this response */ + int no_local_copy; + + /* What object is being requested (either directly, or via include + * or content-negotiation mapping). + */ + + /** The URI without any parsing performed */ + char *unparsed_uri; + /** The path portion of the URI */ + char *uri; + /** The filename on disk corresponding to this response */ + char *filename; + /* XXX: What does this mean? Please define "canonicalize" -aaron */ + /** The true filename, we canonicalize r->filename if these don't match */ + char *canonical_filename; + /** The PATH_INFO extracted from this request */ + char *path_info; + /** The QUERY_ARGS extracted from this request */ + char *args; + /** finfo.protection (st_mode) set to zero if no such file */ + apr_finfo_t finfo; + /** A struct containing the components of URI */ + apr_uri_t parsed_uri; + + /** + * Flag for the handler to accept or reject path_info on + * the current request. All modules should respect the + * AP_REQ_ACCEPT_PATH_INFO and AP_REQ_REJECT_PATH_INFO + * values, while AP_REQ_DEFAULT_PATH_INFO indicates they + * may follow existing conventions. This is set to the + * user's preference upon HOOK_VERY_FIRST of the fixups. + */ + int used_path_info; + + /* Various other config info which may change with .htaccess files + * These are config vectors, with one void* pointer for each module + * (the thing pointed to being the module's business). + */ + + /** Options set in config files, etc. */ + struct ap_conf_vector_t *per_dir_config; + /** Notes on *this* request */ + struct ap_conf_vector_t *request_config; + + /** + * A linked list of the .htaccess configuration directives + * accessed by this request. + * N.B. always add to the head of the list, _never_ to the end. + * that way, a sub request's list can (temporarily) point to a parent's list + */ + const struct htaccess_result *htaccess; + + /** A list of output filters to be used for this request */ + struct ap_filter_t *output_filters; + /** A list of input filters to be used for this request */ + struct ap_filter_t *input_filters; + + /** A list of protocol level output filters to be used for this + * request */ + struct ap_filter_t *proto_output_filters; + /** A list of protocol level input filters to be used for this + * request */ + struct ap_filter_t *proto_input_filters; + + /** A flag to determine if the eos bucket has been sent yet */ + int eos_sent; + +/* Things placed at the end of the record to avoid breaking binary + * compatibility. It would be nice to remember to reorder the entire + * record to improve 64bit alignment the next time we need to break + * binary compatibility for some other reason. + */ +}; + +/** + * @defgroup ProxyReq Proxy request types + * + * Possible values of request_rec->proxyreq. A request could be normal, + * proxied or reverse proxied. Normally proxied and reverse proxied are + * grouped together as just "proxied", but sometimes it's necessary to + * tell the difference between the two, such as for authentication. + * @{ + */ + +#define PROXYREQ_NONE 0 /**< No proxy */ +#define PROXYREQ_PROXY 1 /**< Standard proxy */ +#define PROXYREQ_REVERSE 2 /**< Reverse proxy */ +#define PROXYREQ_RESPONSE 3 /**< Origin response */ + +/* @} */ + +typedef enum { + AP_CONN_UNKNOWN, + AP_CONN_CLOSE, + AP_CONN_KEEPALIVE +} ap_conn_keepalive_e; + +/** Structure to store things which are per connection */ +struct conn_rec { + /** Pool associated with this connection */ + apr_pool_t *pool; + /** Physical vhost this conn came in on */ + server_rec *base_server; + /** used by http_vhost.c */ + void *vhost_lookup_data; + + /* Information about the connection itself */ + /** local address */ + apr_sockaddr_t *local_addr; + /** remote address */ + apr_sockaddr_t *remote_addr; + + /** Client's IP address */ + char *remote_ip; + /** Client's DNS name, if known. NULL if DNS hasn't been checked, + * "" if it has and no address was found. N.B. Only access this though + * get_remote_host() */ + char *remote_host; + /** Only ever set if doing rfc1413 lookups. N.B. Only access this through + * get_remote_logname() */ + char *remote_logname; + + /** Are we still talking? */ + unsigned aborted:1; + + /** Are we going to keep the connection alive for another request? + * @see ap_conn_keepalive_e */ + ap_conn_keepalive_e keepalive; + + /** have we done double-reverse DNS? -1 yes/failure, 0 not yet, + * 1 yes/success */ + signed int double_reverse:2; + + /** How many times have we used it? */ + int keepalives; + /** server IP address */ + char *local_ip; + /** used for ap_get_server_name when UseCanonicalName is set to DNS + * (ignores setting of HostnameLookups) */ + char *local_host; + + /** ID of this connection; unique at any point in time */ + long id; + /** Config vector containing pointers to connections per-server + * config structures. */ + struct ap_conf_vector_t *conn_config; + /** Notes on *this* connection: send note from one module to + * another. must remain valid for all requests on this conn */ + apr_table_t *notes; + /** A list of input filters to be used for this connection */ + struct ap_filter_t *input_filters; + /** A list of output filters to be used for this connection */ + struct ap_filter_t *output_filters; + /** handle to scoreboard information for this connection */ + void *sbh; + /** The bucket allocator to use for all bucket/brigade creations */ + struct apr_bucket_alloc_t *bucket_alloc; + /** The current state of this connection */ + conn_state_t *cs; + /** Is there data pending in the input filters? */ + int data_in_input_filters; +}; + +typedef enum { + CONN_STATE_CHECK_REQUEST_LINE_READABLE, + CONN_STATE_READ_REQUEST_LINE, + CONN_STATE_LINGER, +} conn_state_e; + +struct conn_state_t { + APR_RING_ENTRY(conn_state_t) timeout_list; + apr_time_t expiration_time; + conn_state_e state; + conn_rec *c; + apr_pool_t *p; + apr_bucket_alloc_t *bucket_alloc; + apr_pollfd_t pfd; +}; + +/* Per-vhost config... */ + +/** + * The address 255.255.255.255, when used as a virtualhost address, + * will become the "default" server when the ip doesn't match other vhosts. + */ +#define DEFAULT_VHOST_ADDR 0xfffffffful + + +/** A structure to be used for Per-vhost config */ +typedef struct server_addr_rec server_addr_rec; +struct server_addr_rec { + /** The next server in the list */ + server_addr_rec *next; + /** The bound address, for this server */ + apr_sockaddr_t *host_addr; + /** The bound port, for this server */ + apr_port_t host_port; + /** The name given in */ + char *virthost; +}; + +/** A structure to store information for each virtual server */ +struct server_rec { + /** The process this server is running in */ + process_rec *process; + /** The next server in the list */ + server_rec *next; + + /** The name of the server */ + const char *defn_name; + /** The line of the config file that the server was defined on */ + unsigned defn_line_number; + + /* Contact information */ + + /** The admin's contact information */ + char *server_admin; + /** The server hostname */ + char *server_hostname; + /** for redirects, etc. */ + apr_port_t port; + + /* Log files --- note that transfer log is now in the modules... */ + + /** The name of the error log */ + char *error_fname; + /** A file descriptor that references the error log */ + apr_file_t *error_log; + /** The log level for this server */ + int loglevel; + + /* Module-specific configuration for server, and defaults... */ + + /** true if this is the virtual server */ + int is_virtual; + /** Config vector containing pointers to modules' per-server config + * structures. */ + struct ap_conf_vector_t *module_config; + /** MIME type info, etc., before we start checking per-directory info */ + struct ap_conf_vector_t *lookup_defaults; + + /* Transaction handling */ + + /** I haven't got a clue */ + server_addr_rec *addrs; + /** Timeout, as an apr interval, before we give up */ + apr_interval_time_t timeout; + /** The apr interval we will wait for another request */ + apr_interval_time_t keep_alive_timeout; + /** Maximum requests per connection */ + int keep_alive_max; + /** Use persistent connections? */ + int keep_alive; + + /** Pathname for ServerPath */ + const char *path; + /** Length of path */ + int pathlen; + + /** Normal names for ServerAlias servers */ + apr_array_header_t *names; + /** Wildcarded names for ServerAlias servers */ + apr_array_header_t *wild_names; + + /** limit on size of the HTTP request line */ + int limit_req_line; + /** limit on size of any request header field */ + int limit_req_fieldsize; + /** limit on number of request header fields */ + int limit_req_fields; +}; + +typedef struct core_output_filter_ctx { + apr_bucket_brigade *b; + apr_pool_t *deferred_write_pool; /* subpool of c->pool used for resources + * which may outlive the request + */ +} core_output_filter_ctx_t; + +typedef struct core_filter_ctx { + apr_bucket_brigade *b; + apr_bucket_brigade *tmpbb; +} core_ctx_t; + +typedef struct core_net_rec { + /** Connection to the client */ + apr_socket_t *client_socket; + + /** connection record */ + conn_rec *c; + + core_output_filter_ctx_t *out_ctx; + core_ctx_t *in_ctx; +} core_net_rec; + +/** + * Examine a field value (such as a media-/content-type) string and return + * it sans any parameters; e.g., strip off any ';charset=foo' and the like. + * @param p Pool to allocate memory from + * @param intype The field to examine + * @return A copy of the field minus any parameters + */ +AP_DECLARE(char *) ap_field_noparam(apr_pool_t *p, const char *intype); + +/** + * Convert a time from an integer into a string in a specified format + * @param p The pool to allocate memory from + * @param t The time to convert + * @param fmt The format to use for the conversion + * @param gmt Convert the time for GMT? + * @return The string that represents the specified time + */ +AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt, int gmt); + +/* String handling. The *_nc variants allow you to use non-const char **s as + arguments (unfortunately C won't automatically convert a char ** to a const + char **) */ + +/** + * Get the characters until the first occurance of a specified character + * @param p The pool to allocate memory from + * @param line The string to get the characters from + * @param stop The character to stop at + * @return A copy of the characters up to the first stop character + */ +AP_DECLARE(char *) ap_getword(apr_pool_t *p, const char **line, char stop); +/** + * Get the characters until the first occurance of a specified character + * @param p The pool to allocate memory from + * @param line The string to get the characters from + * @param stop The character to stop at + * @return A copy of the characters up to the first stop character + * @note This is the same as ap_getword(), except it doesn't use const char **. + */ +AP_DECLARE(char *) ap_getword_nc(apr_pool_t *p, char **line, char stop); + +/** + * Get the first word from a given string. A word is defined as all characters + * up to the first whitespace. + * @param p The pool to allocate memory from + * @param line The string to traverse + * @return The first word in the line + */ +AP_DECLARE(char *) ap_getword_white(apr_pool_t *p, const char **line); +/** + * Get the first word from a given string. A word is defined as all characters + * up to the first whitespace. + * @param p The pool to allocate memory from + * @param line The string to traverse + * @return The first word in the line + * @note The same as ap_getword_white(), except it doesn't use const char **. + */ +AP_DECLARE(char *) ap_getword_white_nc(apr_pool_t *p, char **line); + +/** + * Get all characters from the first occurance of @a stop to the first '\0' + * @param p The pool to allocate memory from + * @param line The line to traverse + * @param stop The character to start at + * @return A copy of all caracters after the first occurance of the specified + * character + */ +AP_DECLARE(char *) ap_getword_nulls(apr_pool_t *p, const char **line, + char stop); +/** + * Get all characters from the first occurance of @a stop to the first '\0' + * @param p The pool to allocate memory from + * @param line The line to traverse + * @param stop The character to start at + * @return A copy of all caracters after the first occurance of the specified + * character + * @note The same as ap_getword_nulls(), except it doesn't use const char **. + */ +AP_DECLARE(char *) ap_getword_nulls_nc(apr_pool_t *p, char **line, char stop); + +/** + * Get the second word in the string paying attention to quoting + * @param p The pool to allocate from + * @param line The line to traverse + * @return A copy of the string + */ +AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line); +/** + * Get the second word in the string paying attention to quoting + * @param p The pool to allocate from + * @param line The line to traverse + * @return A copy of the string + * @note The same as ap_getword_conf(), except it doesn't use const char **. + */ +AP_DECLARE(char *) ap_getword_conf_nc(apr_pool_t *p, char **line); + +/** + * Check a string for any ${ENV} environment variable construct and replace + * each them by the value of that environment variable, if it exists. If the + * environment value does not exist, leave the ${ENV} construct alone; it + * means something else. + * @param p The pool to allocate from + * @param word The string to check + * @return The string with the replaced environment variables + */ +AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word); + +/** + * Size an HTTP header field list item, as separated by a comma. + * @param field The field to size + * @param len The length of the field + * @return 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. + */ +AP_DECLARE(const char *) ap_size_list_item(const char **field, int *len); + +/** + * 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. + * @param p The pool to allocate from + * @param field The field to retrieve + * @return 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. + */ +AP_DECLARE(char *) ap_get_list_item(apr_pool_t *p, const char **field); + +/** + * Find an item in canonical form (lowercase, no extra spaces) within + * an HTTP field value list. + * @param p The pool to allocate from + * @param line The field value list to search + * @param tok The token to search for + * @return 1 if found, 0 if not found. + */ +AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line, const char *tok); + +/** + * Retrieve a token, spacing over it and adjusting the pointer to + * the first non-white byte afterwards. Note that these tokens + * are delimited by semis and commas and can also be delimited + * by whitespace at the caller's option. + * @param p The pool to allocate from + * @param accept_line The line to retrieve the token from (adjusted afterwards) + * @param accept_white Is it delimited by whitespace + * @return the token + */ +AP_DECLARE(char *) ap_get_token(apr_pool_t *p, const char **accept_line, int accept_white); + +/** + * Find http tokens, see the definition of token from RFC2068 + * @param p The pool to allocate from + * @param line The line to find the token + * @param tok The token to find + * @return 1 if the token is found, 0 otherwise + */ +AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok); + +/** + * find http tokens from the end of the line + * @param p The pool to allocate from + * @param line The line to find the token + * @param tok The token to find + * @return 1 if the token is found, 0 otherwise + */ +AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line, const char *tok); + +/** + * Check for an Absolute URI syntax + * @param u The string to check + * @return 1 if URI, 0 otherwise + */ +AP_DECLARE(int) ap_is_url(const char *u); + +/** + * Unescape a URL + * @param url The url to unescape + * @return 0 on success, non-zero otherwise + */ +AP_DECLARE(int) ap_unescape_url(char *url); +/** + * Unescape a URL, but leaving %2f (slashes) escaped + * @param url The url to unescape + * @return 0 on success, non-zero otherwise + */ +AP_DECLARE(int) ap_unescape_url_keep2f(char *url); +/** + * Convert all double slashes to single slashes + * @param name The string to convert + */ +AP_DECLARE(void) ap_no2slash(char *name); + +/** + * Remove all ./ and xx/../ substrings from a file name. Also remove + * any leading ../ or /../ substrings. + * @param name the file name to parse + */ +AP_DECLARE(void) ap_getparents(char *name); + +/** + * Escape a path segment, as defined in RFC 1808 + * @param p The pool to allocate from + * @param s The path to convert + * @return The converted URL + */ +AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *s); +/** + * convert an OS path to a URL in an OS dependant way. + * @param p The pool to allocate from + * @param path The path to convert + * @param partial if set, assume that the path will be appended to something + * with a '/' in it (and thus does not prefix "./") + * @return The converted URL + */ +AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial); +/** @see ap_os_escape_path */ +#define ap_escape_uri(ppool,path) ap_os_escape_path(ppool,path,1) + +/** + * Escape an html string + * @param p The pool to allocate from + * @param s The html to escape + * @return The escaped string + */ +AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s); + +/** + * Escape a string for logging + * @param p The pool to allocate from + * @param str The string to escape + * @return The escaped string + */ +AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str); + +/** + * Escape a string for logging into the error log (without a pool) + * @param dest The buffer to write to + * @param source The string to escape + * @param buflen The buffer size for the escaped string (including \0) + * @return The len of the escaped string (always < maxlen) + */ +AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source, + apr_size_t buflen); + +/** + * Construct a full hostname + * @param p The pool to allocate from + * @param hostname The hostname of the server + * @param port The port the server is running on + * @param r The current request + * @return The server's hostname + */ +AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname, + apr_port_t port, const request_rec *r); +/** + * Escape a shell command + * @param p The pool to allocate from + * @param s The command to escape + * @return The escaped shell command + */ +AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *s); + +/** + * Count the number of directories in a path + * @param path The path to count + * @return The number of directories + */ +AP_DECLARE(int) ap_count_dirs(const char *path); + +/** + * Copy at most @a n leading directories of @a s into @a d. @a d + * should be at least as large as @a s plus 1 extra byte + * + * @param d The location to copy to + * @param s The location to copy from + * @param n The number of directories to copy + * @return value is the ever useful pointer to the trailing \0 of d + * @note on platforms with drive letters, n = 0 returns the "/" root, + * whereas n = 1 returns the "d:/" root. On all other platforms, n = 0 + * returns the empty string. */ +AP_DECLARE(char *) ap_make_dirstr_prefix(char *d, const char *s, int n); + +/** + * Return the parent directory name (including trailing /) of the file + * @a s + * @param p The pool to allocate from + * @param s The file to get the parent of + * @return A copy of the file's parent directory + */ +AP_DECLARE(char *) ap_make_dirstr_parent(apr_pool_t *p, const char *s); + +/** + * Given a directory and filename, create a single path from them. This + * function is smart enough to ensure that there is a sinlge '/' between the + * directory and file names + * @param a The pool to allocate from + * @param dir The directory name + * @param f The filename + * @return A copy of the full path + * @tip Never consider using this function if you are dealing with filesystem + * names that need to remain canonical, unless you are merging an apr_dir_read + * path and returned filename. Otherwise, the result is not canonical. + */ +AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *dir, const char *f); + +/** + * Test if the given path has an an absolute path. + * @param p The pool to allocate from + * @param dir The directory name + * @tip The converse is not necessarily true, some OS's (Win32/OS2/Netware) have + * multiple forms of absolute paths. This only reports if the path is absolute + * in a canonical sense. + */ +AP_DECLARE(int) ap_os_is_path_absolute(apr_pool_t *p, const char *dir); + +/** + * Does the provided string contain wildcard characters? This is useful + * for determining if the string should be passed to strcmp_match or to strcmp. + * The only wildcard characters recognized are '?' and '*' + * @param str The string to check + * @return 1 if the string has wildcards, 0 otherwise + */ +AP_DECLARE(int) ap_is_matchexp(const char *str); + +/** + * Determine if a string matches a patterm containing the wildcards '?' or '*' + * @param str The string to check + * @param expected The pattern to match against + * @return 1 if the two strings match, 0 otherwise + */ +AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected); +/** + * Determine if a string matches a patterm containing the wildcards '?' or '*', + * ignoring case + * @param str The string to check + * @param expected The pattern to match against + * @return 1 if the two strings match, 0 otherwise + */ +AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected); + +/** + * Find the first occurrence of the substring s2 in s1, regardless of case + * @param s1 The string to search + * @param s2 The substring to search for + * @return A pointer to the beginning of the substring + * @remark See apr_strmatch() for a faster alternative + */ +AP_DECLARE(char *) ap_strcasestr(const char *s1, const char *s2); + +/** + * Return a pointer to the location inside of bigstring immediately after prefix + * @param bigstring The input string + * @param prefix The prefix to strip away + * @return A pointer relative to bigstring after prefix + */ +AP_DECLARE(const char *) ap_stripprefix(const char *bigstring, + const char *prefix); + +/** + * Decode a base64 encoded string into memory allocated from a pool + * @param p The pool to allocate from + * @param bufcoded The encoded string + * @return The decoded string + */ +AP_DECLARE(char *) ap_pbase64decode(apr_pool_t *p, const char *bufcoded); + +/** + * Encode a string into memory allocated from a pool in base 64 format + * @param p The pool to allocate from + * @param strin The plaintext string + * @return The encoded string + */ +AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string); + + +/** + * Compile a regular expression to be used later + * @param p The pool to allocate from + * @param pattern the regular expression to compile + * @param cflags The bitwise or of one or more of the following: + * @li #REG_EXTENDED - Use POSIX extended Regular Expressions + * @li #REG_ICASE - Ignore case + * @li #REG_NOSUB - Support for substring addressing of matches + * not required + * @li #REG_NEWLINE - Match-any-character operators don't match new-line + * @return The compiled regular expression + */ +AP_DECLARE(ap_regex_t *) ap_pregcomp(apr_pool_t *p, const char *pattern, + int cflags); + +/** + * Free the memory associated with a compiled regular expression + * @param p The pool the regex was allocated from + * @param reg The regular expression to free + */ +AP_DECLARE(void) ap_pregfree(apr_pool_t *p, ap_regex_t *reg); + +/** + * After performing a successful regex match, you may use this function to + * perform a series of string substitutions based on subexpressions that were + * matched during the call to ap_regexec + * @param p The pool to allocate from + * @param input An arbitrary string containing $1 through $9. These are + * replaced with the corresponding matched sub-expressions + * @param source The string that was originally matched to the regex + * @param nmatch the nmatch returned from ap_pregex + * @param pmatch the pmatch array returned from ap_pregex + */ +AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input, const char *source, + size_t nmatch, ap_regmatch_t pmatch[]); + +/** + * We want to downcase the type/subtype for comparison purposes + * but nothing else because ;parameter=foo values are case sensitive. + * @param s The content-type to convert to lowercase + */ +AP_DECLARE(void) ap_content_type_tolower(char *s); + +/** + * convert a string to all lowercase + * @param s The string to convert to lowercase + */ +AP_DECLARE(void) ap_str_tolower(char *s); + +/** + * Search a string from left to right for the first occurrence of a + * specific character + * @param str The string to search + * @param c The character to search for + * @return The index of the first occurrence of c in str + */ +AP_DECLARE(int) ap_ind(const char *str, char c); /* Sigh... */ + +/** + * Search a string from right to left for the first occurrence of a + * specific character + * @param str The string to search + * @param c The character to search for + * @return The index of the first occurrence of c in str + */ +AP_DECLARE(int) ap_rind(const char *str, char c); + +/** + * Given a string, replace any bare " with \" . + * @param p The pool to allocate memory from + * @param instring The string to search for " + * @return A copy of the string with escaped quotes + */ +AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring); + +/* Misc system hackery */ +/** + * Given the name of an object in the file system determine if it is a directory + * @param p The pool to allocate from + * @param name The name of the object to check + * @return 1 if it is a directory, 0 otherwise + */ +AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *name); + +/** + * Given the name of an object in the file system determine if it is a directory - this version is symlink aware + * @param p The pool to allocate from + * @param name The name of the object to check + * @return 1 if it is a directory, 0 otherwise + */ +AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *name); + +#ifdef _OSD_POSIX +extern int os_init_job_environment(server_rec *s, const char *user_name, int one_process); +#endif /* _OSD_POSIX */ + +/** + * Determine the local host name for the current machine + * @param p The pool to allocate from + * @return A copy of the local host name + */ +char *ap_get_local_host(apr_pool_t *p); + +/** + * Log an assertion to the error log + * @param szExp The assertion that failed + * @param szFile The file the assertion is in + * @param nLine The line the assertion is defined on + */ +AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, int nLine) + __attribute__((noreturn)); + +/** @internal */ +#define ap_assert(exp) ((exp) ? (void)0 : ap_log_assert(#exp,__FILE__,__LINE__)) + +/** + * Redefine assert() to something more useful for an Apache... + * + * Use ap_assert() if the condition should always be checked. + * Use AP_DEBUG_ASSERT() if the condition should only be checked when AP_DEBUG + * is defined. + */ + +#ifdef AP_DEBUG +#define AP_DEBUG_ASSERT(exp) ap_assert(exp) +#else +#define AP_DEBUG_ASSERT(exp) ((void)0) +#endif + +/** + * @defgroup stopsignal flags which indicate places where the sever should stop for debugging. + * @{ + * A set of flags which indicate places where the server should raise(SIGSTOP). + * This is useful for debugging, because you can then attach to that process + * with gdb and continue. This is important in cases where one_process + * debugging isn't possible. + */ +/** stop on a Detach */ +#define SIGSTOP_DETACH 1 +/** stop making a child process */ +#define SIGSTOP_MAKE_CHILD 2 +/** stop spawning a child process */ +#define SIGSTOP_SPAWN_CHILD 4 +/** stop spawning a child process with a piped log */ +#define SIGSTOP_PIPED_LOG_SPAWN 8 +/** stop spawning a CGI child process */ +#define SIGSTOP_CGI_CHILD 16 + +/** Macro to get GDB started */ +#ifdef DEBUG_SIGSTOP +extern int raise_sigstop_flags; +#define RAISE_SIGSTOP(x) do { \ + if (raise_sigstop_flags & SIGSTOP_##x) raise(SIGSTOP);\ + } while (0) +#else +#define RAISE_SIGSTOP(x) +#endif +/** @} */ +/** + * Get HTML describing the address and (optionally) admin of the server. + * @param prefix Text which is prepended to the return value + * @param r The request_rec + * @return HTML describing the server, allocated in @a r's pool. + */ +AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r); + +/** strtoul does not exist on sunos4. */ +#ifdef strtoul +#undef strtoul +#endif +#define strtoul strtoul_is_not_a_portable_function_use_strtol_instead + + /* The C library has functions that allow const to be silently dropped ... + these macros detect the drop in maintainer mode, but use the native + methods for normal builds + + Note that on some platforms (e.g., AIX with gcc, Solaris with gcc), string.h needs + to be included before the macros are defined or compilation will fail. + */ +#include + +AP_DECLARE(char *) ap_strchr(char *s, int c); +AP_DECLARE(const char *) ap_strchr_c(const char *s, int c); +AP_DECLARE(char *) ap_strrchr(char *s, int c); +AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c); +AP_DECLARE(char *) ap_strstr(char *s, const char *c); +AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c); + +#ifdef AP_DEBUG + +#undef strchr +# define strchr(s, c) ap_strchr(s,c) +#undef strrchr +# define strrchr(s, c) ap_strrchr(s,c) +#undef strstr +# define strstr(s, c) ap_strstr(s,c) + +#else + +/** use this instead of strchr */ +# define ap_strchr(s, c) strchr(s, c) +/** use this instead of strchr */ +# define ap_strchr_c(s, c) strchr(s, c) +/** use this instead of strrchr */ +# define ap_strrchr(s, c) strrchr(s, c) +/** use this instead of strrchr */ +# define ap_strrchr_c(s, c) strrchr(s, c) +/** use this instead of strrstr*/ +# define ap_strstr(s, c) strstr(s, c) +/** use this instead of strrstr*/ +# define ap_strstr_c(s, c) strstr(s, c) + +#endif + +#define AP_NORESTART APR_OS_START_USEERR + 1 + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTPD_H */ diff --git a/trunk/include/mpm_common.h b/trunk/include/mpm_common.h new file mode 100644 index 0000000000..1fdac30671 --- /dev/null +++ b/trunk/include/mpm_common.h @@ -0,0 +1,303 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The purpose of this file is to store the code that MOST mpm's will need + * this does not mean a function only goes into this file if every MPM needs + * it. It means that if a function is needed by more than one MPM, and + * future maintenance would be served by making the code common, then the + * function belongs here. + * + * This is going in src/main because it is not platform specific, it is + * specific to multi-process servers, but NOT to Unix. Which is why it + * does not belong in src/os/unix + */ + +#ifndef APACHE_MPM_COMMON_H +#define APACHE_MPM_COMMON_H + +#include "ap_config.h" + +#if APR_HAVE_NETINET_TCP_H +#include /* for TCP_NODELAY */ +#endif + +#include "mpm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Multi-Processing Modules functions + */ + +/* The maximum length of the queue of pending connections, as defined + * by listen(2). Under some systems, it should be increased if you + * are experiencing a heavy TCP SYN flood attack. + * + * It defaults to 511 instead of 512 because some systems store it + * as an 8-bit datatype; 512 truncated to 8-bits is 0, while 511 is + * 255 when truncated. + */ +#ifndef DEFAULT_LISTENBACKLOG +#define DEFAULT_LISTENBACKLOG 511 +#endif + +/** + * Make sure all child processes that have been spawned by the parent process + * have died. This includes process registered as "other_children". + * @warning This is only defined if the MPM defines + * AP_MPM_WANT_RECLAIM_CHILD_PROCESSES + * @param terminate Either 1 or 0. If 1, send the child processes SIGTERM + * each time through the loop. If 0, give the process time to die + * on its own before signalling it. + * @tip This function requires that some macros are defined by the MPM:
    + *  MPM_CHILD_PID -- Get the pid from the specified spot in the scoreboard
    + *  MPM_NOTE_CHILD_KILLED -- Note the child died in the scoreboard
    + * 
    + * @tip The MPM child processes which are reclaimed are those listed + * in the scoreboard as well as those currently registered via + * ap_register_extra_mpm_process(). + */ +#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +void ap_reclaim_child_processes(int terminate); +#endif + +/** + * Tell ap_reclaim_child_processes() about an MPM child process which has no + * entry in the scoreboard. + * @warning This is only defined if the MPM defines + * AP_MPM_WANT_RECLAIM_CHILD_PROCESSES + * @param pid The process id of an MPM child process which should be + * reclaimed when ap_reclaim_child_processes() is called. + * @tip If an extra MPM child process terminates prior to calling + * ap_reclaim_child_processes(), remove it from the list of such processes + * by calling ap_unregister_extra_mpm_process(). + */ +#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +void ap_register_extra_mpm_process(pid_t pid); +#endif + +/** + * Unregister an MPM child process which was previously registered by a + * call to ap_register_extra_mpm_process(). + * @warning This is only defined if the MPM defines + * AP_MPM_WANT_RECLAIM_CHILD_PROCESSES + * @param pid The process id of an MPM child process which no longer needs to + * be reclaimed. + * @return 1 if the process was found and removed, 0 otherwise + */ +#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +int ap_unregister_extra_mpm_process(pid_t pid); +#endif + +/** + * Determine if any child process has died. If no child process died, then + * this process sleeps for the amount of time specified by the MPM defined + * macro SCOREBOARD_MAINTENANCE_INTERVAL. + * @param status The return code if a process has died + * @param ret The process id of the process that died + * @param p The pool to allocate out of + */ +#ifdef AP_MPM_WANT_WAIT_OR_TIMEOUT +void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret, + apr_pool_t *p); +#endif + +/** + * Log why a child died to the error log, if the child died without the + * parent signalling it. + * @param pid The child that has died + * @param status The status returned from ap_wait_or_timeout + * @return 0 on success, APEXIT_CHILDFATAL if MPM should terminate + */ +#ifdef AP_MPM_WANT_PROCESS_CHILD_STATUS +int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status); +#endif + +#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF) +/** + * Turn off the nagle algorithm for the specified socket. The nagle algorithm + * says that we should delay sending partial packets in the hopes of getting + * more data. There are bad interactions between persistent connections and + * Nagle's algorithm that have severe performance penalties. + * @param s The socket to disable nagle for. + */ +void ap_sock_disable_nagle(apr_socket_t *s); +#else +#define ap_sock_disable_nagle(s) /* NOOP */ +#endif + +#ifdef HAVE_GETPWNAM +/** + * Convert a username to a numeric ID + * @param name The name to convert + * @return The user id corresponding to a name + * @deffunc uid_t ap_uname2id(const char *name) + */ +AP_DECLARE(uid_t) ap_uname2id(const char *name); +#endif + +#ifdef HAVE_GETGRNAM +/** + * Convert a group name to a numeric ID + * @param name The name to convert + * @return The group id corresponding to a name + * @deffunc gid_t ap_gname2id(const char *name) + */ +AP_DECLARE(gid_t) ap_gname2id(const char *name); +#endif + +#define AP_MPM_HARD_LIMITS_FILE APACHE_MPM_DIR "/mpm_default.h" + +#ifdef AP_MPM_USES_POD + +typedef struct ap_pod_t ap_pod_t; + +struct ap_pod_t { + apr_file_t *pod_in; + apr_file_t *pod_out; + apr_pool_t *p; +}; + +/** + * Open the pipe-of-death. The pipe of death is used to tell all child + * processes that it is time to die gracefully. + * @param p The pool to use for allocating the pipe + */ +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod); + +/** + * Check the pipe to determine if the process has been signalled to die. + */ +AP_DECLARE(apr_status_t) ap_mpm_pod_check(ap_pod_t *pod); + +/** + * Close the pipe-of-death + */ +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod); + +/** + * Write data to the pipe-of-death, signalling that one child process + * should die. + * @param p The pool to use when allocating any required structures. + */ +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod); + +/** + * Write data to the pipe-of-death, signalling that all child process + * should die. + * @param p The pool to use when allocating any required structures. + * @param num The number of child processes to kill + */ +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num); +#endif + +/* + * These data members are common to all mpms. Each new mpm + * should either use the appropriate ap_mpm_set_* function + * in their command table or create their own for custom or + * OS specific needs. These should work for most. + */ + +/** + * The maximum number of requests each child thread or + * process handles before dying off + */ +#ifdef AP_MPM_WANT_SET_MAX_REQUESTS +extern int ap_max_requests_per_child; +const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +/** + * The filename used to store the process id. + */ +#ifdef AP_MPM_WANT_SET_PIDFILE +extern const char *ap_pid_fname; +const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +/** + * The name of lockfile used when Apache needs to lock the accept() call. + */ +#ifdef AP_MPM_WANT_SET_LOCKFILE +extern const char *ap_lock_fname; +const char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +/** + * The system mutex implementation to use for the accept mutex. + */ +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +extern apr_lockmech_e ap_accept_lock_mech; +extern const char ap_valid_accept_mutex_string[]; +const char *ap_mpm_set_accept_lock_mech(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +/* + * Set the scorboard file. + */ +#ifdef AP_MPM_WANT_SET_SCOREBOARD +const char *ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +/* + * The directory that the server changes directory to dump core. + */ +#ifdef AP_MPM_WANT_SET_COREDUMPDIR +extern char ap_coredump_dir[MAX_STRING_LEN]; +extern int ap_coredumpdir_configured; +const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +#ifdef AP_MPM_WANT_SIGNAL_SERVER +int ap_signal_server(int *, apr_pool_t *); +void ap_mpm_rewrite_args(process_rec *); +#endif + +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE +extern apr_uint32_t ap_max_mem_free; +extern const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +#ifdef AP_MPM_WANT_SET_STACKSIZE +extern apr_size_t ap_thread_stacksize; +extern const char *ap_mpm_set_thread_stacksize(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER +extern apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *pconf); +extern apr_status_t ap_fatal_signal_child_setup(server_rec *s); +#endif + +#if AP_ENABLE_EXCEPTION_HOOK +extern const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, + const char *arg); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_MPM_COMMON_H */ diff --git a/trunk/include/scoreboard.h b/trunk/include/scoreboard.h new file mode 100644 index 0000000000..726ee1ee19 --- /dev/null +++ b/trunk/include/scoreboard.h @@ -0,0 +1,223 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_SCOREBOARD_H +#define APACHE_SCOREBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SYS_TIMES_H +#include +#include +#elif defined(TPF) +#include +#endif + +#include "ap_config.h" +#include "apr_hooks.h" +#include "apr_thread_proc.h" +#include "apr_portable.h" +#include "apr_shm.h" +#include "apr_optional.h" + +/* Scoreboard file, if there is one */ +#ifndef DEFAULT_SCOREBOARD +#define DEFAULT_SCOREBOARD "logs/apache_runtime_status" +#endif + +/* Scoreboard info on a process is, for now, kept very brief --- + * just status value and pid (the latter so that the caretaker process + * can properly update the scoreboard when a process dies). We may want + * to eventually add a separate set of long_score structures which would + * give, for each process, the number of requests serviced, and info on + * the current, or most recent, request. + * + * Status values: + */ + +#define SERVER_DEAD 0 +#define SERVER_STARTING 1 /* Server Starting up */ +#define SERVER_READY 2 /* Waiting for connection (or accept() lock) */ +#define SERVER_BUSY_READ 3 /* Reading a client request */ +#define SERVER_BUSY_WRITE 4 /* Processing a client request */ +#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */ +#define SERVER_BUSY_LOG 6 /* Logging the request */ +#define SERVER_BUSY_DNS 7 /* Looking up a hostname */ +#define SERVER_CLOSING 8 /* Closing the connection */ +#define SERVER_GRACEFUL 9 /* server is gracefully finishing request */ +#define SERVER_IDLE_KILL 10 /* Server is cleaning up idle children. */ +#define SERVER_NUM_STATUS 11 /* number of status settings */ + +/* Type used for generation indicies. Startup and every restart cause a + * new generation of children to be spawned. Children within the same + * generation share the same configuration information -- pointers to stuff + * created at config time in the parent are valid across children. However, + * this can't work effectively with non-forked architectures. So while the + * arrays in the scoreboard never change between the parent and forked + * children, so they do not require shm storage, the contents of the shm + * may contain no pointers. + */ +typedef int ap_generation_t; + +/* Is the scoreboard shared between processes or not? + * Set by the MPM when the scoreboard is created. + */ +typedef enum { + SB_NOT_SHARED = 1, + SB_SHARED = 2 +} ap_scoreboard_e; + +#define SB_WORKING 0 /* The server is busy and the child is useful. */ +#define SB_IDLE_DIE 1 /* The server is idle and the child is superfluous. */ + /* The child should check for this and exit gracefully. */ + +/* stuff which is worker specific */ +/***********************WARNING***************************************/ +/* These are things that are used by mod_status. Do not put anything */ +/* in here that you cannot live without. This structure will not */ +/* be available if mod_status is not loaded. */ +/*********************************************************************/ +typedef struct worker_score worker_score; + +struct worker_score { + int thread_num; +#if APR_HAS_THREADS + apr_os_thread_t tid; +#endif + /* With some MPMs (e.g., worker), a worker_score can represent + * a thread in a terminating process which is no longer + * represented by the corresponding process_score. These MPMs + * should set pid and generation fields in the worker_score. + */ + pid_t pid; + ap_generation_t generation; + unsigned char status; + unsigned long access_count; + apr_off_t bytes_served; + unsigned long my_access_count; + apr_off_t my_bytes_served; + apr_off_t conn_bytes; + unsigned short conn_count; + apr_time_t start_time; + apr_time_t stop_time; +#ifdef HAVE_TIMES + struct tms times; +#endif + apr_time_t last_used; + char client[32]; /* Keep 'em small... */ + char request[64]; /* We just want an idea... */ + char vhost[32]; /* What virtual host is being accessed? */ +}; + +typedef struct { + int server_limit; + int thread_limit; + ap_scoreboard_e sb_type; + ap_generation_t running_generation; /* the generation of children which + * should still be serving requests. + */ + apr_time_t restart_time; + int lb_limit; +} global_score; + +/* stuff which the parent generally writes and the children rarely read */ +typedef struct process_score process_score; +struct process_score{ + pid_t pid; + ap_generation_t generation; /* generation of this child */ + ap_scoreboard_e sb_type; + int quiescing; /* the process whose pid is stored above is + * going down gracefully + */ +}; + +/* stuff which is lb specific */ +typedef struct lb_score lb_score; +struct lb_score{ + /* TODO: make a real stuct from this */ + unsigned char data[1024]; +}; + +/* Scoreboard is now in 'local' memory, since it isn't updated once created, + * even in forked architectures. Child created-processes (non-fork) will + * set up these indicies into the (possibly relocated) shmem records. + */ +typedef struct { + global_score *global; + process_score *parent; + worker_score **servers; + lb_score *balancers; +} scoreboard; + +typedef struct ap_sb_handle_t ap_sb_handle_t; + +AP_DECLARE(int) ap_exists_scoreboard_image(void); +AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sbh, request_rec *r); + +int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t); +apr_status_t ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached); +void ap_init_scoreboard(void *shared_score); +AP_DECLARE(int) ap_calc_scoreboard_size(void); +apr_status_t ap_cleanup_scoreboard(void *d); + +AP_DECLARE(void) ap_create_sb_handle(ap_sb_handle_t **new_sbh, apr_pool_t *p, + int child_num, int thread_num); + +int find_child_by_pid(apr_proc_t *pid); +AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, request_rec *r); +AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num, + int status, request_rec *r); +void ap_time_process_request(ap_sb_handle_t *sbh, int status); + +AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y); +AP_DECLARE(process_score *) ap_get_scoreboard_process(int x); +AP_DECLARE(global_score *) ap_get_scoreboard_global(void); +AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num); + +AP_DECLARE_DATA extern scoreboard *ap_scoreboard_image; +AP_DECLARE_DATA extern const char *ap_scoreboard_fname; +AP_DECLARE_DATA extern int ap_extended_status; + +AP_DECLARE_DATA extern ap_generation_t volatile ap_my_generation; + +/* Hooks */ +/** + * Hook for post scoreboard creation, pre mpm. + * @param p Apache pool to allocate from. + * @param sb_type + * @ingroup hooks + * @return OK or DECLINE on success; anything else is a error + */ +AP_DECLARE_HOOK(int, pre_mpm, (apr_pool_t *p, ap_scoreboard_e sb_type)) + +/** + * proxy load balancer + * @return the number of load balancer workers. + */ +APR_DECLARE_OPTIONAL_FN(int, ap_proxy_lb_workers, + (void)); + +/* for time_process_request() in http_main.c */ +#define START_PREQUEST 1 +#define STOP_PREQUEST 2 + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_SCOREBOARD_H */ diff --git a/trunk/include/util_cfgtree.h b/trunk/include/util_cfgtree.h new file mode 100644 index 0000000000..4257e3605b --- /dev/null +++ b/trunk/include/util_cfgtree.h @@ -0,0 +1,79 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_CONFTREE_H +#define AP_CONFTREE_H + +#include "ap_config.h" + +/** + * @package Config Tree Package + */ + +typedef struct ap_directive_t ap_directive_t; + +/** + * Structure used to build the config tree. The config tree only stores + * the directives that will be active in the running server. Directives + * that contain other directions, such as cause a sub-level + * to be created, where the included directives are stored. The closing + * directive () is not stored in the tree. + */ +struct ap_directive_t { + /** The current directive */ + const char *directive; + /** The arguments for the current directive, stored as a space + * separated list */ + const char *args; + /** The next directive node in the tree + * @defvar ap_directive_t *next */ + struct ap_directive_t *next; + /** The first child node of this directive + * @defvar ap_directive_t *first_child */ + struct ap_directive_t *first_child; + /** The parent node of this directive + * @defvar ap_directive_t *parent */ + struct ap_directive_t *parent; + + /** directive's module can store add'l data here */ + void *data; + + /* ### these may go away in the future, but are needed for now */ + /** The name of the file this directive was found in */ + const char *filename; + /** The line number the directive was on */ + int line_num; +}; + +/** + * The root of the configuration tree + * @defvar ap_directive_t *conftree + */ +AP_DECLARE_DATA extern ap_directive_t *ap_conftree; + +/** + * Add a node to the configuration tree. + * @param parent The current parent node. If the added node is a first_child, + then this is changed to the current node + * @param current The current node + * @param toadd The node to add to the tree + * @param child Is the node to add a child node + * @return the added node + */ +ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current, + ap_directive_t *toadd, int child); + +#endif diff --git a/trunk/include/util_charset.h b/trunk/include/util_charset.h new file mode 100644 index 0000000000..bfc743b0c5 --- /dev/null +++ b/trunk/include/util_charset.h @@ -0,0 +1,48 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_UTIL_CHARSET_H +#define APACHE_UTIL_CHARSET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package charset conversion + */ +#include "apr.h" + +#if APR_CHARSET_EBCDIC + +#include "apr_xlate.h" + +/** On EBCDIC machine this is a translation handle used to translate the + * headers from the local machine format to ASCII for network transmission. + * On an ASCII machine this is NULL */ +extern apr_xlate_t *ap_hdrs_to_ascii; +/** On EBCDIC machine this is a translation handle used to translate the + * headers from ASCII to the local machine format after network transmission. + * On an ASCII machine this is NULL */ +extern apr_xlate_t *ap_hdrs_from_ascii; + +#endif /* APR_CHARSET_EBCDIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_UTIL_CHARSET_H */ diff --git a/trunk/include/util_ebcdic.h b/trunk/include/util_ebcdic.h new file mode 100644 index 0000000000..70dbd2ee00 --- /dev/null +++ b/trunk/include/util_ebcdic.h @@ -0,0 +1,78 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_UTIL_EBCDIC_H +#define APACHE_UTIL_EBCDIC_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "apr_xlate.h" +#include "httpd.h" +#include "util_charset.h" + +/** + * @package Utilities for EBCDIC conversion + */ + +#if APR_CHARSET_EBCDIC + +/** + * Setup all of the global translation handlers + * @param pool pool to allocate out of + */ +apr_status_t ap_init_ebcdic(apr_pool_t *pool); + +/** + * Convert protocol data from the implementation character + * set to ASCII. + * @param buffer buffer to translate + * @param len number of bytes to translate + */ +void ap_xlate_proto_to_ascii(char *buffer, apr_size_t len); + +/** + * Convert protocol data to the implementation character + * set from ASCII. + * @param buffer buffer to translate + * @param len number of bytes to translate + */ +void ap_xlate_proto_from_ascii(char *buffer, apr_size_t len); + +/** + * Convert protocol data from the implementation charater + * set to ASCII, then send it. + * @param r the current request + * @param ... the strings to write, followed by a NULL pointer + */ +int ap_rvputs_proto_in_ascii(request_rec *r, ...); + +#else /* APR_CHARSET_EBCDIC */ + +#define ap_xlate_proto_to_ascii(x,y) /* NOOP */ +#define ap_xlate_proto_from_ascii(x,y) /* NOOP */ + +#define ap_rvputs_proto_in_ascii ap_rvputs + +#endif /* APR_CHARSET_EBCDIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_UTIL_EBCDIC_H */ diff --git a/trunk/include/util_filter.h b/trunk/include/util_filter.h new file mode 100644 index 0000000000..81f86fe985 --- /dev/null +++ b/trunk/include/util_filter.h @@ -0,0 +1,591 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_FILTER_H +#define AP_FILTER_H + +#include "apr.h" +#include "apr_buckets.h" + +#include "httpd.h" + +#if APR_HAVE_STDARG_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file util_filter.h + * @brief Apache filter library + */ + +/** Returned by the bottom-most filter if no data was written. + * @see ap_pass_brigade(). */ +#define AP_NOBODY_WROTE -1 +/** Returned by the bottom-most filter if no data was read. + * @see ap_get_brigade(). */ +#define AP_NOBODY_READ -2 +/** Returned when?? @bug find out when! */ +#define AP_FILTER_ERROR -3 + +/** + * input filtering modes + */ +typedef enum { + /** The filter should return at most readbytes data. */ + AP_MODE_READBYTES, + /** The filter should return at most one line of CRLF data. + * (If a potential line is too long or no CRLF is found, the + * filter may return partial data). + */ + AP_MODE_GETLINE, + /** The filter should implicitly eat any CRLF pairs that it sees. */ + AP_MODE_EATCRLF, + /** The filter read should be treated as speculative and any returned + * data should be stored for later retrieval in another mode. */ + AP_MODE_SPECULATIVE, + /** The filter read should be exhaustive and read until it can not + * read any more. + * Use this mode with extreme caution. + */ + AP_MODE_EXHAUSTIVE, + /** The filter should initialize the connection if needed, + * NNTP or FTP over SSL for example. + */ + AP_MODE_INIT +} ap_input_mode_t; + +/** + * @defgroup filter FILTER CHAIN + * + * Filters operate using a "chaining" mechanism. The filters are chained + * together into a sequence. When output is generated, it is passed through + * each of the filters on this chain, until it reaches the end (or "bottom") + * and is placed onto the network. + * + * The top of the chain, the code generating the output, is typically called + * a "content generator." The content generator's output is fed into the + * filter chain using the standard Apache output mechanisms: ap_rputs(), + * ap_rprintf(), ap_rwrite(), etc. + * + * Each filter is defined by a callback. This callback takes the output from + * the previous filter (or the content generator if there is no previous + * filter), operates on it, and passes the result to the next filter in the + * chain. This pass-off is performed using the ap_fc_* functions, such as + * ap_fc_puts(), ap_fc_printf(), ap_fc_write(), etc. + * + * When content generation is complete, the system will pass an "end of + * stream" marker into the filter chain. The filters will use this to flush + * out any internal state and to detect incomplete syntax (for example, an + * unterminated SSI directive). + */ + +/* forward declare the filter type */ +typedef struct ap_filter_t ap_filter_t; + +/** + * @name Filter callbacks + * + * This function type is used for filter callbacks. It will be passed a + * pointer to "this" filter, and a "bucket" containing the content to be + * filtered. + * + * In filter->ctx, the callback will find its context. This context is + * provided here, so that a filter may be installed multiple times, each + * receiving its own per-install context pointer. + * + * Callbacks are associated with a filter definition, which is specified + * by name. See ap_register_input_filter() and ap_register_output_filter() + * for setting the association between a name for a filter and its + * associated callback (and other information). + * + * If the initialization function argument passed to the registration + * functions is non-NULL, it will be called iff the filter is in the input + * or output filter chains and before any data is generated to allow the + * filter to prepare for processing. + * + * The *bucket structure (and all those referenced by ->next and ->prev) + * should be considered "const". The filter is allowed to modify the + * next/prev to insert/remove/replace elements in the bucket list, but + * the types and values of the individual buckets should not be altered. + * + * For the input and output filters, the return value of a filter should be + * an APR status value. For the init function, the return value should + * be an HTTP error code or OK if it was successful. + * + * @ingroup filter + * @{ + */ +typedef apr_status_t (*ap_out_filter_func)(ap_filter_t *f, + apr_bucket_brigade *b); +typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f, + apr_bucket_brigade *b, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes); +typedef int (*ap_init_filter_func)(ap_filter_t *f); + +typedef union ap_filter_func { + ap_out_filter_func out_func; + ap_in_filter_func in_func; +} ap_filter_func; + +/** @} */ + +/** + * Filters have different types/classifications. These are used to group + * and sort the filters to properly sequence their operation. + * + * The types have a particular sort order, which allows us to insert them + * into the filter chain in a determistic order. Within a particular grouping, + * the ordering is equivalent to the order of calls to ap_add_*_filter(). + */ +typedef enum { + /** These filters are used to alter the content that is passed through + * them. Examples are SSI or PHP. */ + AP_FTYPE_RESOURCE = 10, + /** These filters are used to alter the content as a whole, but after all + * AP_FTYPE_RESOURCE filters are executed. These filters should not + * change the content-type. An example is deflate. */ + AP_FTYPE_CONTENT_SET = 20, + /** These filters are used to handle the protocol between server and + * client. Examples are HTTP and POP. */ + AP_FTYPE_PROTOCOL = 30, + /** These filters implement transport encodings (e.g., chunking). */ + AP_FTYPE_TRANSCODE = 40, + /** These filters will alter the content, but in ways that are + * more strongly associated with the connection. Examples are + * splitting an HTTP connection into multiple requests and + * buffering HTTP responses across multiple requests. + * + * It is important to note that these types of filters are not + * allowed in a sub-request. A sub-request's output can certainly + * be filtered by ::AP_FTYPE_RESOURCE filters, but all of the "final + * processing" is determined by the main request. */ + AP_FTYPE_CONNECTION = 50, + /** These filters don't alter the content. They are responsible for + * sending/receiving data to/from the client. */ + AP_FTYPE_NETWORK = 60 +} ap_filter_type; + +/** + * This is the request-time context structure for an installed filter (in + * the output filter chain). It provides the callback to use for filtering, + * the request this filter is associated with (which is important when + * an output chain also includes sub-request filters), the context for this + * installed filter, and the filter ordering/chaining fields. + * + * Filter callbacks are free to use ->ctx as they please, to store context + * during the filter process. Generally, this is superior over associating + * the state directly with the request. A callback should not change any of + * the other fields. + */ + +typedef struct ap_filter_rec_t ap_filter_rec_t; +typedef struct ap_filter_provider_t ap_filter_provider_t; + +/** + * This structure is used for recording information about the + * registered filters. It associates a name with the filter's callback + * and filter type. + * + * At the moment, these are simply linked in a chain, so a ->next pointer + * is available. + * + * It is used for any filter that can be inserted in the filter chain. + * This may be either a httpd-2.0 filter or a mod_filter harness. + * In the latter case it contains dispatch, provider and protocol information. + * In the former case, the new fields (from dispatch) are ignored. + */ +struct ap_filter_rec_t { + /** The registered name for this filter */ + const char *name; + + /** The function to call when this filter is invoked. */ + ap_filter_func filter_func; + + /** The function to call before the handlers are invoked. Notice + * that this function is called only for filters participating in + * the http protocol. Filters for other protocols are to be + * initialized by the protocols themselves. + */ + ap_init_filter_func filter_init_func; + + /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION. + * An AP_FTYPE_CONTENT filter modifies the data based on information + * found in the content. An AP_FTYPE_CONNECTION filter modifies the + * data based on the type of connection. + */ + ap_filter_type ftype; + + /** The next filter_rec in the list */ + struct ap_filter_rec_t *next; + + /** Providers for this filter */ + ap_filter_provider_t *providers; + + /** Trace level for this filter */ + int debug; + + /** Protocol flags for this filter */ + unsigned int proto_flags; +}; + +/** + * The representation of a filter chain. Each request has a list + * of these structures which are called in turn to filter the data. Sub + * requests get an exact copy of the main requests filter chain. + */ +struct ap_filter_t { + /** The internal representation of this filter. This includes + * the filter's name, type, and the actual function pointer. + */ + ap_filter_rec_t *frec; + + /** A place to store any data associated with the current filter */ + void *ctx; + + /** The next filter in the chain */ + ap_filter_t *next; + + /** The request_rec associated with the current filter. If a sub-request + * adds filters, then the sub-request is the request associated with the + * filter. + */ + request_rec *r; + + /** The conn_rec associated with the current filter. This is analogous + * to the request_rec, except that it is used for input filtering. + */ + conn_rec *c; +}; + +/** + * Get the current bucket brigade from the next filter on the filter + * stack. The filter returns an apr_status_t value. If the bottom-most + * filter doesn't read from the network, then ::AP_NOBODY_READ is returned. + * The bucket brigade will be empty when there is nothing left to get. + * @param filter The next filter in the chain + * @param bucket The current bucket brigade. The original brigade passed + * to ap_get_brigade() must be empty. + * @param mode The way in which the data should be read + * @param block How the operations should be performed + * ::APR_BLOCK_READ, ::APR_NONBLOCK_READ + * @param readbytes How many bytes to read from the next filter. + */ +AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter, + apr_bucket_brigade *bucket, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes); + +/** + * Pass the current bucket brigade down to the next filter on the filter + * stack. The filter returns an apr_status_t value. If the bottom-most + * filter doesn't write to the network, then ::AP_NOBODY_WROTE is returned. + * The caller relinquishes ownership of the brigade. + * @param filter The next filter in the chain + * @param bucket The current bucket brigade + */ +AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter, + apr_bucket_brigade *bucket); + +/** + * This function is used to register an input filter with the system. + * After this registration is performed, then a filter may be added + * into the filter chain by using ap_add_input_filter() and simply + * specifying the name. + * + * @param name The name to attach to the filter function + * @param filter_func The filter function to name + * @param filter_init The function to call before the filter handlers + are invoked + * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or + * ::AP_FTYPE_CONNECTION + * @see add_input_filter() + */ +AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, + ap_in_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype); + +/** + * This function is used to register an output filter with the system. + * After this registration is performed, then a filter may be added + * into the filter chain by using ap_add_output_filter() and simply + * specifying the name. It may also be used as a provider under mod_filter. + * This is (equivalent to) ap_register_output_filter_protocol with + * proto_flags=0, and is retained for back-compatibility with 2.0 modules. + * + * @param name The name to attach to the filter function + * @param filter_func The filter function to name + * @param filter_init The function to call before the filter handlers + * are invoked + * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or + * ::AP_FTYPE_CONNECTION + * @see ap_add_output_filter() + */ +AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, + ap_out_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype); + +/* For httpd-2.2 I suggest replacing the above with +#define ap_register_output_filter(name,ffunc,init,ftype) \ + ap_register_output_filter_protocol(name,ffunc,init,ftype,0) +*/ + +/** + * This function is used to register an output filter with the system. + * After this registration is performed, then a filter may be added + * into the filter chain by using ap_add_output_filter() and simply + * specifying the name. It may also be used as a provider under mod_filter. + * + * @param name The name to attach to the filter function + * @param filter_func The filter function to name + * @param filter_init The function to call before the filter handlers + * are invoked + * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or + * ::AP_FTYPE_CONNECTION + * @param proto_flags Protocol flags: logical OR of AP_FILTER_PROTO_* bits + * @see ap_add_output_filter() + */ +AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol( + const char *name, + ap_out_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype, + unsigned int proto_flags); + +/** + * Adds a named filter into the filter chain on the specified request record. + * The filter will be installed with the specified context pointer. + * + * Filters added in this way will always be placed at the end of the filters + * that have the same type (thus, the filters have the same order as the + * calls to ap_add_filter). If the current filter chain contains filters + * from another request, then this filter will be added before those other + * filters. + * + * To re-iterate that last comment. This function is building a FIFO + * list of filters. Take note of that when adding your filter to the chain. + * + * @param name The name of the filter to add + * @param ctx Context data to provide to the filter + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add the fillter for + */ +AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, + request_rec *r, conn_rec *c); + +/** + * Variant of ap_add_input_filter() that accepts a registered filter handle + * (as returned by ap_register_input_filter()) rather than a filter name + * + * @param f The filter handle to add + * @param ctx Context data to provide to the filter + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add the fillter for + */ +AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c); + +/** + * Returns the filter handle for use with ap_add_input_filter_handle. + * + * @param name The filter name to look up + */ +AP_DECLARE(ap_filter_rec_t *) ap_get_input_filter_handle(const char *name); + +/** + * Add a filter to the current request. Filters are added in a FIFO manner. + * The first filter added will be the first filter called. + * @param name The name of the filter to add + * @param ctx Context data to set in the filter + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add this filter for + */ +AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, + request_rec *r, conn_rec *c); + +/** + * Variant of ap_add_output_filter() that accepts a registered filter handle + * (as returned by ap_register_output_filter()) rather than a filter name + * + * @param f The filter handle to add + * @param r The request to add this filter for (or NULL if it isn't associated with a request) + * @param c The connection to add the fillter for + */ +AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c); + +/** + * Returns the filter handle for use with ap_add_output_filter_handle. + * + * @param name The filter name to look up + */ +AP_DECLARE(ap_filter_rec_t *) ap_get_output_filter_handle(const char *name); + +/** + * Remove an input filter from either the request or connection stack + * it is associated with. + * @param f The filter to remove + */ + +AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f); + +/** + * Remove an output filter from either the request or connection stack + * it is associated with. + * @param f The filter to remove + */ + +AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f); + +/* The next two filters are for abstraction purposes only. They could be + * done away with, but that would require that we break modules if we ever + * want to change our filter registration method. The basic idea, is that + * all filters have a place to store data, the ctx pointer. These functions + * fill out that pointer with a bucket brigade, and retrieve that data on + * the next call. The nice thing about these functions, is that they + * automatically concatenate the bucket brigades together for you. This means + * that if you have already stored a brigade in the filters ctx pointer, then + * when you add more it will be tacked onto the end of that brigade. When + * you retrieve data, if you pass in a bucket brigade to the get function, + * it will append the current brigade onto the one that you are retrieving. + */ + +/** + * prepare a bucket brigade to be setaside. If a different brigade was + * set-aside earlier, then the two brigades are concatenated together. + * @param f The current filter + * @param save_to The brigade that was previously set-aside. Regardless, the + * new bucket brigade is returned in this location. + * @param b The bucket brigade to save aside. This brigade is always empty + * on return + * @param p Ensure that all data in the brigade lives as long as this pool + */ +AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, + apr_bucket_brigade **save_to, + apr_bucket_brigade **b, apr_pool_t *p); + +/** + * Flush function for apr_brigade_* calls. This calls ap_pass_brigade + * to flush the brigade if the brigade buffer overflows. + * @param bb The brigade to flush + * @param ctx The filter to pass the brigade to + * @note this function has nothing to do with FLUSH buckets. It is simply + * a way to flush content out of a brigade and down a filter stack. + */ +AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, + void *ctx); + +/** + * Flush the current brigade down the filter stack. + * @param f The filter we are passing to + * @param bb The brigade to flush + */ +AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb); + +/** + * Write a buffer for the current filter, buffering if possible. + * @param f the filter we are writing to + * @param bb The brigade to buffer into + * @param data The data to write + * @param nbyte The number of bytes in the data + */ +#define ap_fwrite(f, bb, data, nbyte) \ + apr_brigade_write(bb, ap_filter_flush, f, data, nbyte) + +/** + * Write a buffer for the current filter, buffering if possible. + * @param f the filter we are writing to + * @param bb The brigade to buffer into + * @param str The string to write + */ +#define ap_fputs(f, bb, str) \ + apr_brigade_puts(bb, ap_filter_flush, f, str) + +/** + * Write a character for the current filter, buffering if possible. + * @param f the filter we are writing to + * @param bb The brigade to buffer into + * @param c The character to write + */ +#define ap_fputc(f, bb, c) \ + apr_brigade_putc(bb, ap_filter_flush, f, c) + +/** + * Write an unspecified number of strings to the current filter + * @param f the filter we are writing to + * @param bb The brigade to buffer into + * @param ... The strings to write + */ +AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f, + apr_bucket_brigade *bb, + ...); + +/** + * Output data to the filter in printf format + * @param f the filter we are writing to + * @param bb The brigade to buffer into + * @param fmt The format string + * @param ... The argumets to use to fill out the format string + */ +AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f, + apr_bucket_brigade *bb, + const char *fmt, + ...) + __attribute__((format(printf,3,4))); + +/** + * set protocol requirements for an output content filter + * (only works with AP_FTYPE_RESOURCE and AP_FTYPE_CONTENT_SET) + * @param f the filter in question + * @param proto_flags Logical OR of AP_FILTER_PROTO_* bits + */ +AP_DECLARE(void) ap_filter_protocol(ap_filter_t* f, unsigned int proto_flags); + +/** Filter changes contents (so invalidating checksums/etc) */ +#define AP_FILTER_PROTO_CHANGE 0x1 + +/** Filter changes length of contents (so invalidating content-length/etc) */ +#define AP_FILTER_PROTO_CHANGE_LENGTH 0x2 + +/** Filter requires complete input and can't work on byteranges */ +#define AP_FILTER_PROTO_NO_BYTERANGE 0x4 + +/** Filter should not run in a proxy */ +#define AP_FILTER_PROTO_NO_PROXY 0x8 + +/** Filter makes output non-cacheable */ +#define AP_FILTER_PROTO_NO_CACHE 0x10 + +/** Filter is incompatible with "Cache-Control: no-transform" */ +#define AP_FILTER_PROTO_TRANSFORM 0x20 + +#ifdef __cplusplus +} +#endif + +#endif /* !AP_FILTER_H */ diff --git a/trunk/include/util_ldap.h b/trunk/include/util_ldap.h new file mode 100644 index 0000000000..ad8013adcd --- /dev/null +++ b/trunk/include/util_ldap.h @@ -0,0 +1,323 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTIL_LDAP_H +#define UTIL_LDAP_H + +/* APR header files */ +#include "apr.h" +#include "apr_thread_mutex.h" +#include "apr_thread_rwlock.h" +#include "apr_tables.h" +#include "apr_time.h" +#include "apr_ldap.h" + +#if APR_HAS_SHARED_MEMORY +#include "apr_rmm.h" +#include "apr_shm.h" +#endif + +/* this whole thing disappears if LDAP is not enabled */ +#if APR_HAS_LDAP + +/* Apache header files */ +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" +#include "apr_optional.h" + +/* Create a set of LDAP_DECLARE macros with appropriate export + * and import tags for the platform + */ +#if !defined(WIN32) +#define LDAP_DECLARE(type) type +#define LDAP_DECLARE_NONSTD(type) type +#define LDAP_DECLARE_DATA +#elif defined(LDAP_DECLARE_STATIC) +#define LDAP_DECLARE(type) type __stdcall +#define LDAP_DECLARE_NONSTD(type) type +#define LDAP_DECLARE_DATA +#elif defined(LDAP_DECLARE_EXPORT) +#define LDAP_DECLARE(type) __declspec(dllexport) type __stdcall +#define LDAP_DECLARE_NONSTD(type) __declspec(dllexport) type +#define LDAP_DECLARE_DATA __declspec(dllexport) +#else +#define LDAP_DECLARE(type) __declspec(dllimport) type __stdcall +#define LDAP_DECLARE_NONSTD(type) __declspec(dllimport) type +#define LDAP_DECLARE_DATA __declspec(dllimport) +#endif + +/* + * LDAP Connections + */ + +/* Values that the deref member can have */ +typedef enum { + never=LDAP_DEREF_NEVER, + searching=LDAP_DEREF_SEARCHING, + finding=LDAP_DEREF_FINDING, + always=LDAP_DEREF_ALWAYS +} deref_options; + +/* Structure representing an LDAP connection */ +typedef struct util_ldap_connection_t { + LDAP *ldap; + apr_pool_t *pool; /* Pool from which this connection is created */ +#if APR_HAS_THREADS + apr_thread_mutex_t *lock; /* Lock to indicate this connection is in use */ +#endif + int bound; /* Flag to indicate whether this connection is bound yet */ + + const char *host; /* Name of the LDAP server (or space separated list) */ + int port; /* Port of the LDAP server */ + deref_options deref; /* how to handle alias dereferening */ + + const char *binddn; /* DN to bind to server (can be NULL) */ + const char *bindpw; /* Password to bind to server (can be NULL) */ + + int secure; /* SSL/TLS mode of the connection */ + apr_array_header_t *client_certs; /* Client certificates on this connection */ + + const char *reason; /* Reason for an error failure */ + + struct util_ldap_connection_t *next; +} util_ldap_connection_t; + +/* LDAP cache state information */ +typedef struct util_ldap_state_t { + apr_pool_t *pool; /* pool from which this state is allocated */ +#if APR_HAS_THREADS + apr_thread_mutex_t *mutex; /* mutex lock for the connection list */ +#endif + apr_global_mutex_t *util_ldap_cache_lock; + + apr_size_t cache_bytes; /* Size (in bytes) of shared memory cache */ + char *cache_file; /* filename for shm */ + long search_cache_ttl; /* TTL for search cache */ + long search_cache_size; /* Size (in entries) of search cache */ + long compare_cache_ttl; /* TTL for compare cache */ + long compare_cache_size; /* Size (in entries) of compare cache */ + + struct util_ldap_connection_t *connections; + int ssl_supported; + apr_array_header_t *global_certs; /* Global CA certificates */ + apr_array_header_t *client_certs; /* Client certificates */ + int secure; + int secure_set; + +#if APR_HAS_SHARED_MEMORY + apr_shm_t *cache_shm; + apr_rmm_t *cache_rmm; +#endif + + /* cache ald */ + void *util_ldap_cache; + char *lock_file; /* filename for shm lock mutex */ + long connectionTimeout; + int verify_svr_cert; + +} util_ldap_state_t; + + +/** + * Open a connection to an LDAP server + * @param ldc A structure containing the expanded details of the server + * to connect to. The handle to the LDAP connection is returned + * as ldc->ldap. + * @tip This function connects to the LDAP server and binds. It does not + * connect if already connected (ldc->ldap != NULL). Does not bind + * if already bound. + * @return If successful LDAP_SUCCESS is returned. + * @deffunc int util_ldap_connection_open(request_rec *r, + * util_ldap_connection_t *ldc) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_connection_open,(request_rec *r, + util_ldap_connection_t *ldc)); + +/** + * Close a connection to an LDAP server + * @param ldc A structure containing the expanded details of the server + * that was connected. + * @tip This function unbinds from the LDAP server, and clears ldc->ldap. + * It is possible to rebind to this server again using the same ldc + * structure, using apr_ldap_open_connection(). + * @deffunc util_ldap_close_connection(util_ldap_connection_t *ldc) + */ +APR_DECLARE_OPTIONAL_FN(void,uldap_connection_close,(util_ldap_connection_t *ldc)); + +/** + * Unbind a connection to an LDAP server + * @param ldc A structure containing the expanded details of the server + * that was connected. + * @tip This function unbinds the LDAP connection, and disconnects from + * the server. It is used during error conditions, to bring the LDAP + * connection back to a known state. + * @deffunc apr_status_t util_ldap_connection_unbind(util_ldap_connection_t *ldc) + */ +APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_unbind,(void *param)); + +/** + * Cleanup a connection to an LDAP server + * @param ldc A structure containing the expanded details of the server + * that was connected. + * @tip This function is registered with the pool cleanup to close down the + * LDAP connections when the server is finished with them. + * @deffunc apr_status_t util_ldap_connection_cleanup(util_ldap_connection_t *ldc) + */ +APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_cleanup,(void *param)); + +/** + * Find a connection in a list of connections + * @param r The request record + * @param host The hostname to connect to (multiple hosts space separated) + * @param port The port to connect to + * @param binddn The DN to bind with + * @param bindpw The password to bind with + * @param deref The dereferencing behavior + * @param secure use SSL on the connection + * @tip Once a connection is found and returned, a lock will be acquired to + * lock that particular connection, so that another thread does not try and + * use this connection while it is busy. Once you are finished with a connection, + * apr_ldap_connection_close() must be called to release this connection. + * @deffunc util_ldap_connection_t *util_ldap_connection_find(request_rec *r, const char *host, int port, + * const char *binddn, const char *bindpw, deref_options deref, + * int netscapessl, int starttls) + */ +APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find,(request_rec *r, const char *host, int port, + const char *binddn, const char *bindpw, deref_options deref, + int secure)); + +/** + * Compare two DNs for sameness + * @param r The request record + * @param ldc The LDAP connection being used. + * @param url The URL of the LDAP connection - used for deciding which cache to use. + * @param dn The first DN to compare. + * @param reqdn The DN to compare the first DN to. + * @param compare_dn_on_server Flag to determine whether the DNs should be checked using + * LDAP calls or with a direct string comparision. A direct + * string comparison is faster, but not as accurate - false + * negative comparisons are possible. + * @tip Two DNs can be equal and still fail a string comparison. Eg "dc=example,dc=com" + * and "dc=example, dc=com". Use the compare_dn_on_server unless there are serious + * performance issues. + * @deffunc int util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, + * const char *url, const char *dn, const char *reqdn, + * int compare_dn_on_server) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_cache_comparedn,(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *dn, const char *reqdn, + int compare_dn_on_server)); + +/** + * A generic LDAP compare function + * @param r The request record + * @param ldc The LDAP connection being used. + * @param url The URL of the LDAP connection - used for deciding which cache to use. + * @param dn The DN of the object in which we do the compare. + * @param attrib The attribute within the object we are comparing for. + * @param value The value of the attribute we are trying to compare for. + * @tip Use this function to determine whether an attribute/value pair exists within an + * object. Typically this would be used to determine LDAP group membership. + * @deffunc int util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, + * const char *url, const char *dn, const char *attrib, const char *value) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_cache_compare,(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *dn, const char *attrib, const char *value)); + +/** + * Checks a username/password combination by binding to the LDAP server + * @param r The request record + * @param ldc The LDAP connection being used. + * @param url The URL of the LDAP connection - used for deciding which cache to use. + * @param basedn The Base DN to search for the user in. + * @param scope LDAP scope of the search. + * @param attrs LDAP attributes to return in search. + * @param filter The user to search for in the form of an LDAP filter. This filter must return + * exactly one user for the check to be successful. + * @param bindpw The user password to bind as. + * @param binddn The DN of the user will be returned in this variable. + * @param retvals The values corresponding to the attributes requested in the attrs array. + * @tip The filter supplied will be searched for. If a single entry is returned, an attempt + * is made to bind as that user. If this bind succeeds, the user is not validated. + * @deffunc int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, + * char *url, const char *basedn, int scope, char **attrs, + * char *filter, char *bindpw, char **binddn, char ***retvals) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_cache_checkuserid,(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *basedn, int scope, char **attrs, + const char *filter, const char *bindpw, const char **binddn, const char ***retvals)); + +/** + * Searches for a specified user object in an LDAP directory + * @param r The request record + * @param ldc The LDAP connection being used. + * @param url The URL of the LDAP connection - used for deciding which cache to use. + * @param basedn The Base DN to search for the user in. + * @param scope LDAP scope of the search. + * @param attrs LDAP attributes to return in search. + * @param filter The user to search for in the form of an LDAP filter. This filter must return + * exactly one user for the check to be successful. + * @param binddn The DN of the user will be returned in this variable. + * @param retvals The values corresponding to the attributes requested in the attrs array. + * @tip The filter supplied will be searched for. If a single entry is returned, an attempt + * is made to bind as that user. If this bind succeeds, the user is not validated. + * @deffunc int util_ldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, + * char *url, const char *basedn, int scope, char **attrs, + * char *filter, char **binddn, char ***retvals) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_cache_getuserdn,(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *basedn, int scope, char **attrs, + const char *filter, const char **binddn, const char ***retvals)); + +/** + * Checks if SSL support is available in mod_ldap + * @deffunc int util_ldap_ssl_supported(request_rec *r) + */ +APR_DECLARE_OPTIONAL_FN(int,uldap_ssl_supported,(request_rec *r)); + +/* from apr_ldap_cache.c */ + +/** + * Init the LDAP cache + * @param pool The pool to use to initialise the cache + * @param reqsize The size of the shared memory segement to request. A size + * of zero requests the max size possible from + * apr_shmem_init() + * @deffunc void util_ldap_cache_init(apr_pool_t *p, util_ldap_state_t *st) + * @return The status code returned is the status code of the + * apr_smmem_init() call. Regardless of the status, the cache + * will be set up at least for in-process or in-thread operation. + */ +apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st); + +/* from apr_ldap_cache_mgr.c */ + +/** + * Display formatted stats for cache + * @param The pool to allocate the returned string from + * @tip This function returns a string allocated from the provided pool that describes + * various stats about the cache. + * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st) + */ +char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st); + +#endif /* APR_HAS_LDAP */ +#endif /* UTIL_LDAP_H */ diff --git a/trunk/include/util_md5.h b/trunk/include/util_md5.h new file mode 100644 index 0000000000..16b0e0144c --- /dev/null +++ b/trunk/include/util_md5.h @@ -0,0 +1,70 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_UTIL_MD5_H +#define APACHE_UTIL_MD5_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Apache MD5 library + */ + +#include "apr_md5.h" + +/** + * Create an MD5 checksum of a given string + * @param a Pool to allocate out of + * @param string String to get the checksum of + * @return The checksum + * @deffunc char *ap_md5(apr_pool_t *a, const unsigned char *string) + */ +AP_DECLARE(char *) ap_md5(apr_pool_t *a, const unsigned char *string); + +/** + * Create an MD5 checksum of a string of binary data + * @param a Pool to allocate out of + * @param buf Buffer to generate checksum for + * @param len The length of the buffer + * @return The checksum + * @deffunc char *ap_md5_binary(apr_pool_t *a, const unsigned char *buf, int len) + */ +AP_DECLARE(char *) ap_md5_binary(apr_pool_t *a, const unsigned char *buf, int len); + +/** + * Convert an MD5 checksum into a base64 encoding + * @param p The pool to allocate out of + * @param context The context to convert + * @return The converted encoding + * @deffunc char *ap_md5contextTo64(apr_pool_t *p, apr_md5_ctx_t *context) + */ +AP_DECLARE(char *) ap_md5contextTo64(apr_pool_t *p, apr_md5_ctx_t *context); + +/** + * Create an MD5 Digest for a given file + * @param p The pool to allocate out of + * @param infile The file to create the digest for + * @deffunc char *ap_md5digest(apr_pool_t *p, apr_file_t *infile) + */ +AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_UTIL_MD5_H */ diff --git a/trunk/include/util_script.h b/trunk/include/util_script.h new file mode 100644 index 0000000000..8ee1ea6722 --- /dev/null +++ b/trunk/include/util_script.h @@ -0,0 +1,142 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_UTIL_SCRIPT_H +#define APACHE_UTIL_SCRIPT_H + +#include "apr_buckets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Apache script tools + */ + +#ifndef APACHE_ARG_MAX +#ifdef _POSIX_ARG_MAX +#define APACHE_ARG_MAX _POSIX_ARG_MAX +#else +#define APACHE_ARG_MAX 512 +#endif +#endif + +/** + * Create an environment variable out of an Apache table of key-value pairs + * @param p pool to allocate out of + * @param t Apache table of key-value pairs + * @return An array containing the same key-value pairs suitable for + * use with an exec call. + * @deffunc char **ap_create_environment(apr_pool_t *p, apr_table_t *t) + */ +AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t); + +/** + * This "cute" little function comes about because the path info on + * filenames and URLs aren't always the same. So we take the two, + * and find as much of the two that match as possible. + * @param uri The uri we are currently parsing + * @param path_info The current path info + * @return The length of the path info + * @deffunc int ap_find_path_info(const char *uri, const char *path_info) + */ +AP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info); + +/** + * Add CGI environment variables required by HTTP/1.1 to the request's + * environment table + * @param r the current request + * @deffunc void ap_add_cgi_vars(request_rec *r) + */ +AP_DECLARE(void) ap_add_cgi_vars(request_rec *r); + +/** + * Add common CGI environment variables to the requests environment table + * @param r The current request + * @deffunc void ap_add_common_vars(request_rec *r) + */ +AP_DECLARE(void) ap_add_common_vars(request_rec *r); + +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param f The file to read from + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + * @deffunc int ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer) + */ +AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer); + +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param bb The brigade from which to read + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + * @deffunc int ap_scan_script_header_err_brigade(request_rec *r, apr_bucket_brigade *bb, char *buffer) + */ +AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, + apr_bucket_brigade *bb, + char *buffer); + +/** + * Read headers strings from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param termch Pointer to the last character parsed. + * @param termarg Pointer to an int to capture the last argument parsed. + * @param args String arguments to parse consecutively for headers, + * a NULL argument terminates the list. + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + * @deffunc int ap_scan_script_header_err_core(request_rec *r, char *buffer, int (*getsfunc)(char *, int, void *), void *getsfunc_data) + */ +AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, + char *buffer, + const char **termch, + int *termarg, ...); + +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param getsfunc Function to read the headers from. This function should + act like gets() + * @param getsfunc_data The place to read from + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + * @deffunc int ap_scan_script_header_err_core(request_rec *r, char *buffer, int (*getsfunc)(char *, int, void *), void *getsfunc_data) + */ +AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, + int (*getsfunc) (char *, int, void *), + void *getsfunc_data); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_UTIL_SCRIPT_H */ diff --git a/trunk/include/util_time.h b/trunk/include/util_time.h new file mode 100644 index 0000000000..2e34388d52 --- /dev/null +++ b/trunk/include/util_time.h @@ -0,0 +1,85 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_UTIL_TIME_H +#define APACHE_UTIL_TIME_H + +#include "apr.h" +#include "apr_time.h" +#include "httpd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Apache date-time handling functions + */ + +/* Maximum delta from the current time, in seconds, for a past time + * to qualify as "recent" for use in the ap_explode_recent_*() functions: + * (Must be a power of two minus one!) + */ +#define AP_TIME_RECENT_THRESHOLD 15 + +/** + * convert a recent time to its human readable components in local timezone + * @param tm the exploded time + * @param t the time to explode: MUST be within the last + * AP_TIME_RECENT_THRESHOLD seconds + * @note This is a faster alternative to apr_time_exp_lt that uses + * a cache of pre-exploded time structures. It is useful for things + * that need to explode the current time multiple times per second, + * like loggers. + * @return APR_SUCCESS iff successful + */ +AP_DECLARE(apr_status_t) ap_explode_recent_localtime(apr_time_exp_t *tm, + apr_time_t t); + +/** + * convert a recent time to its human readable components in GMT timezone + * @param tm the exploded time + * @param t the time to explode: MUST be within the last + * AP_TIME_RECENT_THRESHOLD seconds + * @note This is a faster alternative to apr_time_exp_gmt that uses + * a cache of pre-exploded time structures. It is useful for things + * that need to explode the current time multiple times per second, + * like loggers. + * @return APR_SUCCESS iff successful + */ +AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t *tm, + apr_time_t t); + + +/** + * format a recent timestamp in the ctime() format. + * @param date_str String to write to. + * @param t the time to convert + */ +AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t); + +/** + * format a recent timestamp in the RFC822 format + * @param date_str String to write to (must have length >= APR_RFC822_DATE_LEN) + * @param t the time to convert + */ +AP_DECLARE(apr_status_t) ap_recent_rfc822_date(char *date_str, apr_time_t t); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_UTIL_TIME_H */ diff --git a/trunk/include/util_xml.h b/trunk/include/util_xml.h new file mode 100644 index 0000000000..b97da2c1e0 --- /dev/null +++ b/trunk/include/util_xml.h @@ -0,0 +1,46 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTIL_XML_H +#define UTIL_XML_H + +#include "apr_xml.h" + +#include "httpd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package Apache XML library + */ + +/** + * Get XML post data and parse it + * @param r The current request + * @param pdoc The XML post data + * @return HTTP status code + * @deffunc int ap_xml_parse_input(request_rec *r, apr_xml_doc **pdoc) + */ +AP_DECLARE(int) ap_xml_parse_input(request_rec *r, apr_xml_doc **pdoc); + + +#ifdef __cplusplus +} +#endif + +#endif /* UTIL_XML_H */ diff --git a/trunk/libhttpd.dsp b/trunk/libhttpd.dsp new file mode 100644 index 0000000000..796dc80b4b --- /dev/null +++ b/trunk/libhttpd.dsp @@ -0,0 +1,715 @@ +# Microsoft Developer Studio Project File - Name="libhttpd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=libhttpd - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libhttpd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libhttpd.mak" CFG="libhttpd - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libhttpd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libhttpd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PCRE_STATIC" /D "AP_DECLARE_EXPORT" /Fd"Release\libhttpd_cl" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Release\buildmark.obj" /nologo /subsystem:windows /dll /debug /machine:I386 /base:@"os\win32\BaseAddr.ref",libhttpd.dll /opt:ref +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Desc=Compiling buildmark +PreLink_Cmds=cl.exe /nologo /MD /W3 /O2 /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PCRE_STATIC" /D "AP_DECLARE_EXPORT" /Fd"Release\libhttpd" /FD /c server\buildmark.c /Fo"Release\buildmark.obj" +# End Special Build Tool + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_DECLARE_EXPORT" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PCRE_STATIC" /D "AP_DECLARE_EXPORT" /Fd"Debug\libhttpd_cl" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib "Debug\buildmark.obj" /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /base:@"os\win32\BaseAddr.ref",libhttpd.dll +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Desc=Compiling buildmark +PreLink_Cmds=cl.exe /nologo /MDd /W3 /GX /Zi /Od /I "./include" /I "./srclib/apr/include" /I "./srclib/apr-util/include" /I "./srclib/pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PCRE_STATIC" /D "AP_DECLARE_EXPORT" /Fd"Debug\libhttpd" /FD /c server\buildmark.c /Fo"Debug\buildmark.obj" +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "libhttpd - Win32 Release" +# Name "libhttpd - Win32 Debug" +# Begin Group "headers" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\include\ap_compat.h +# End Source File +# Begin Source File + +SOURCE=.\include\ap_config.h +# End Source File +# Begin Source File + +SOURCE=.\include\ap_mmn.h +# End Source File +# Begin Source File + +SOURCE=.\include\ap_release.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_config.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_connection.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_core.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_log.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_main.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_protocol.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_request.h +# End Source File +# Begin Source File + +SOURCE=.\include\http_vhost.h +# End Source File +# Begin Source File + +SOURCE=.\include\httpd.h +# End Source File +# Begin Source File + +SOURCE=.\modules\generators\mod_cgi.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_cgi.h +InputPath=.\modules\generators\mod_cgi.h + +".\include\mod_cgi.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\generators\mod_cgi.h > .\include\mod_cgi.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_cgi.h +InputPath=.\modules\generators\mod_cgi.h + +".\include\mod_cgi.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\generators\mod_cgi.h > .\include\mod_cgi.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\modules\http\mod_core.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_core.h +InputPath=.\modules\http\mod_core.h + +".\include\mod_core.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\http\mod_core.h > .\include\mod_core.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_core.h +InputPath=.\modules\http\mod_core.h + +".\include\mod_core.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\http\mod_core.h > .\include\mod_core.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\modules\dav\main\mod_dav.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_dav.h +InputPath=.\modules\dav\main\mod_dav.h + +".\include\mod_dav.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\dav\main\mod_dav.h > .\include\mod_dav.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_dav.h +InputPath=.\modules\dav\main\mod_dav.h + +".\include\mod_dav.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\dav\main\mod_dav.h > .\include\mod_dav.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\modules\filters\mod_include.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_include.h +InputPath=.\modules\filters\mod_include.h + +".\include\mod_include.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\filters\mod_include.h > .\include\mod_include.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_include.h +InputPath=.\modules\filters\mod_include.h + +".\include\mod_include.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\filters\mod_include.h > .\include\mod_include.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\modules\proxy\mod_proxy.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_proxy.h +InputPath=.\modules\proxy\mod_proxy.h + +".\include\mod_proxy.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\proxy\mod_proxy.h > .\include\mod_proxy.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_proxy.h +InputPath=.\modules\proxy\mod_proxy.h + +".\include\mod_proxy.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\proxy\mod_proxy.h > .\include\mod_proxy.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\modules\mappers\mod_so.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_so.h +InputPath=.\modules\mappers\mod_so.h + +".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\mappers\mod_so.h > .\include\mod_so.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mod_so.h +InputPath=.\modules\mappers\mod_so.h + +".\include\mod_so.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\modules\mappers\mod_so.h > .\include\mod_so.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\os\win32\os.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/os.h +InputPath=.\os\win32\os.h + +".\include\os.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\os\win32\os.h > .\include\os.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/os.h +InputPath=.\os\win32\os.h + +".\include\os.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\os\win32\os.h > .\include\os.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\server\test_char.h +# End Source File +# End Group +# Begin Group "httpd" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\server\buildmark.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\modules\http\byterange_filter.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\chunk_filter.c +# End Source File +# Begin Source File + +SOURCE=.\server\config.c +# End Source File +# Begin Source File + +SOURCE=.\server\connection.c +# End Source File +# Begin Source File + +SOURCE=.\server\core.c +# End Source File +# Begin Source File + +SOURCE=.\server\core_filters.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\http_core.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\http_etag.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\http_filters.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\http_protocol.c +# End Source File +# Begin Source File + +SOURCE=.\modules\http\http_request.c +# End Source File +# Begin Source File + +SOURCE=.\server\log.c +# End Source File +# Begin Source File + +SOURCE=.\server\protocol.c +# End Source File +# Begin Source File + +SOURCE=.\server\request.c +# End Source File +# Begin Source File + +SOURCE=.\server\vhost.c +# End Source File +# End Group +# Begin Group "modules" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\modules\mappers\mod_so.c +# End Source File +# Begin Source File + +SOURCE=.\modules\arch\win32\mod_win32.c +# End Source File +# Begin Source File + +SOURCE=.\os\win32\modules.c +# End Source File +# End Group +# Begin Group "util" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\include\ap_regex.h +# End Source File +# Begin Source File + +SOURCE=.\server\eoc_bucket.c +# End Source File +# Begin Source File + +SOURCE=.\server\error_bucket.c +# End Source File +# Begin Source File + +SOURCE=.\server\util.c +# End Source File +# Begin Source File + +SOURCE=.\server\util_cfgtree.c +# End Source File +# Begin Source File + +SOURCE=.\include\util_cfgtree.h +# End Source File +# Begin Source File + +SOURCE=.\include\util_charset.h +# End Source File +# Begin Source File + +SOURCE=.\include\util_ebcdic.h +# End Source File +# Begin Source File + +SOURCE=.\server\util_filter.c +# End Source File +# Begin Source File + +SOURCE=.\include\util_filter.h +# End Source File +# Begin Source File + +SOURCE=.\server\util_md5.c +# End Source File +# Begin Source File + +SOURCE=.\include\util_md5.h +# End Source File +# Begin Source File + +SOURCE=.\server\util_pcre.c +# End Source File +# Begin Source File + +SOURCE=.\server\util_script.c +# End Source File +# Begin Source File + +SOURCE=.\include\util_script.h +# End Source File +# Begin Source File + +SOURCE=.\server\util_time.c +# End Source File +# Begin Source File + +SOURCE=.\os\win32\util_win32.c +# End Source File +# Begin Source File + +SOURCE=.\server\util_xml.c +# End Source File +# Begin Source File + +SOURCE=.\include\util_xml.h +# End Source File +# End Group +# Begin Group "mpm_winnt" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\include\ap_listen.h +# End Source File +# Begin Source File + +SOURCE=.\include\ap_mpm.h +# End Source File +# Begin Source File + +SOURCE=.\os\win32\ap_regkey.c +# End Source File +# Begin Source File + +SOURCE=.\include\ap_regkey.h +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\child.c +# End Source File +# Begin Source File + +SOURCE=.\server\listen.c +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\mpm.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mpm.h +InputPath=.\server\mpm\winnt\mpm.h + +".\include\mpm.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\server\mpm\winnt\mpm.h > .\include\mpm.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mpm.h +InputPath=.\server\mpm\winnt\mpm.h + +".\include\mpm.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\server\mpm\winnt\mpm.h > .\include\mpm.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\server\mpm_common.c +# End Source File +# Begin Source File + +SOURCE=.\include\mpm_common.h +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\mpm_default.h + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mpm_default.h +InputPath=.\server\mpm\winnt\mpm_default.h + +".\include\mpm_default.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\server\mpm\winnt\mpm_default.h > .\include\mpm_default.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating include/mpm_default.h +InputPath=.\server\mpm\winnt\mpm_default.h + +".\include\mpm_default.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\server\mpm\winnt\mpm_default.h > .\include\mpm_default.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\mpm_winnt.c +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\mpm_winnt.h +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\nt_eventlog.c +# End Source File +# Begin Source File + +SOURCE=.\server\provider.c +# End Source File +# Begin Source File + +SOURCE=.\server\scoreboard.c +# End Source File +# Begin Source File + +SOURCE=.\include\scoreboard.h +# End Source File +# Begin Source File + +SOURCE=.\server\mpm\winnt\service.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\server\gen_test_char.exe + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +USERDEP__GEN_T=".\include\os.h" +# Begin Custom Build - Generating test_char.h from gen_test_char.exe +InputPath=.\server\gen_test_char.exe + +".\server\test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + .\server\gen_test_char.exe >.\server\test_char.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +USERDEP__GEN_T=".\include\os.h" +# Begin Custom Build - Generating test_char.h from gen_test_char.exe +InputPath=.\server\gen_test_char.exe + +".\server\test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + .\server\gen_test_char.exe >.\server\test_char.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\build\win32\libhttpd.rc +# End Source File +# Begin Source File + +SOURCE=.\build\win32\win32ver.awk + +!IF "$(CFG)" == "libhttpd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=.\build\win32\win32ver.awk + +".\build\win32\libhttpd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ./build/win32/win32ver.awk libhttpd.dll "Apache HTTP Server Core" ./include/ap_release.h > .\build\win32\libhttpd.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "libhttpd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=.\build\win32\win32ver.awk + +".\build\win32\libhttpd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ./build/win32/win32ver.awk libhttpd.dll "Apache HTTP Server Core" ./include/ap_release.h > .\build\win32\libhttpd.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/Makefile.in b/trunk/modules/Makefile.in new file mode 100644 index 0000000000..1320ec2616 --- /dev/null +++ b/trunk/modules/Makefile.in @@ -0,0 +1,6 @@ + +SUBDIRS = $(MODULE_DIRS) +CLEAN_SUBDIRS = $(MODULE_CLEANDIRS) + +include $(top_builddir)/build/rules.mk + diff --git a/trunk/modules/NWGNUmakefile b/trunk/modules/NWGNUmakefile new file mode 100644 index 0000000000..57387949b2 --- /dev/null +++ b/trunk/modules/NWGNUmakefile @@ -0,0 +1,74 @@ +# +# Declare the sub-directories to be built here +# +# To build with exerimental modules set the environment +# variable EXPERIMENTAL=1 + +SUBDIRS = \ + aaa \ + cache \ + dav\main \ + dav\fs \ + dav\lock \ + echo \ + generators \ + loggers \ + mappers \ + metadata \ + proxy \ + filters \ + $(EOLIST) + +# If LDAPSDK has been defined then build the util_ldap module +ifneq "$(LDAPSDK)" "" +SUBDIRS += ldap \ + $(EOLIST) +endif + +# If OSSLSDK has been defined then build the mod_ssl module +ifndef USE_STDSOCKETS +ifneq "$(OSSLSDK)" "" +SUBDIRS += ssl \ + $(EOLIST) +endif +endif + +#If the mod_edir directory exists then build the mod_edir module +ifeq "$(wildcard $(AP_WORK)\modules\mod_edir)" "$(AP_WORK)\modules\mod_edir" +SUBDIRS += mod_edir \ + $(EOLIST) +endif + +# Allow the experimental modules to be built if EXPERIMENTAL is defined +ifdef EXPERIMENTAL +SUBDIRS += experimental \ + $(EOLIST) +endif + +# Allow the experimental modules to be built if EXPERIMENTAL is defined +ifdef DEBUG +SUBDIRS += debug \ + $(EOLIST) +endif + + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +ifeq "$(wildcard NWGNUmakefile.mak)" "NWGNUmakefile.mak" +include NWGNUmakefile.mak +endif + +# +# You can use this target if all that is needed is to copy files to the +# installation area +# +install :: nlms FORCE + diff --git a/trunk/modules/README b/trunk/modules/README new file mode 100644 index 0000000000..eab7067e0d --- /dev/null +++ b/trunk/modules/README @@ -0,0 +1,54 @@ +The directory structure for this level is as follows: + +aaa/ + This directory contains modules dealing with authorization and + authentication. + +arch/ + +cache/ + This directory houses modules that implement file and data caching + capability. + +dav/ + This directory houses modules that implement WebDAV functionality. + +echo/ + +experimental/ + In this directory we've placed some modules which we think + provide some pretty interesting functionality, but which + are still in the early stages of development and could + evolve radically in the future. This code isn't supported + officially. + +filters/ + This directory houses modules that perform general inline data filtering. + +generators/ + This directory houses modules that perform data generation functions. + +http/ + This directory houses modules that basic HTTP protocol implementation. + +loggers/ + This directory houses modules that handle logging functions. + +mappers/ + This directory houses modules that handle URL mapping and + rewriting. + +metadata/ + This directory houses modules that deal with Header metadata. + +proxy/ + This houses the code for the proxy module for Apache. + +ssl/ + This directory houses code for OpenSSL functionality. + +test/ + This directory houses modules which test various components + of Apache. You should not compile these into a production + server. + diff --git a/trunk/modules/aaa/.indent.pro b/trunk/modules/aaa/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/aaa/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/aaa/Makefile.in b/trunk/modules/aaa/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/aaa/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/aaa/NWGNUauthbasc b/trunk/modules/aaa/NWGNUauthbasc new file mode 100644 index 0000000000..bc7e1ec92c --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthbasc @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authbasc + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Basic Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthBasic Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authbasc.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_auth_basic.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + auth_basic_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthdigt b/trunk/modules/aaa/NWGNUauthdigt new file mode 100644 index 0000000000..3b594b29c3 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthdigt @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authdigt + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Digest Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Digest Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authdigt.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_auth_digest.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + auth_digest_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthnalias b/trunk/modules/aaa/NWGNUauthnalias new file mode 100644 index 0000000000..819c10ceb1 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthnalias @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authnalias + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Authentication Alias Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthnAlias Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authnalias.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authn_alias.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authn_alias_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthnano b/trunk/modules/aaa/NWGNUauthnano new file mode 100644 index 0000000000..5bdd1c2f82 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthnano @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authnano + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Anonymous Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthAnon Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authnano.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authn_anon.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authn_anon_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthndbm b/trunk/modules/aaa/NWGNUauthndbm new file mode 100644 index 0000000000..9ebfd871a9 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthndbm @@ -0,0 +1,249 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authndbm + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Database Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthnDBM Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authndbm.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authn_dbm.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authn_dbm_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthndef b/trunk/modules/aaa/NWGNUauthndef new file mode 100644 index 0000000000..e77d40dc33 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthndef @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authndef + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Default Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Authndef Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authndef.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authn_default.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authn_default_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthnfil b/trunk/modules/aaa/NWGNUauthnfil new file mode 100644 index 0000000000..1cfbb42273 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthnfil @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authnfil + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) File Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthnFile Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authnfil.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authn_file.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authn_file_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthnzldap b/trunk/modules/aaa/NWGNUauthnzldap new file mode 100644 index 0000000000..b1e996df70 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthnzldap @@ -0,0 +1,264 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +#LDAP client requires the use of Winsock +# +ifdef USE_STDSOCKETS +XDEFINES += -DUSE_WINSOCK \ + $(EOLIST) +endif + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authnzldap + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) LDAP Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthnzLDAP Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authnzldap.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authnz_ldap.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + lldapsdk \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + util_ldap_connection_find \ + util_ldap_connection_close \ + util_ldap_cache_checkuserid \ + util_ldap_cache_getuserdn \ + util_ldap_cache_compare \ + util_ldap_cache_comparedn \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + @$(LDAPSDK)/imports/lldapsdk.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authnz_ldap_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthzdbm b/trunk/modules/aaa/NWGNUauthzdbm new file mode 100644 index 0000000000..1b7bd13760 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthzdbm @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authzdbm + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Database Authorization Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthzDBM Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authzdbm.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authz_dbm.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authz_dbm_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthzdef b/trunk/modules/aaa/NWGNUauthzdef new file mode 100644 index 0000000000..348785b04d --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthzdef @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authzdef + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Default Authorization Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Authzdef Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authzdef.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authz_default.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authz_default_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthzgrp b/trunk/modules/aaa/NWGNUauthzgrp new file mode 100644 index 0000000000..a104c4fd76 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthzgrp @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authzgrp + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Group File Authorization Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthzGrp Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authzgrp.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authz_groupfile.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authz_groupfile_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUauthzusr b/trunk/modules/aaa/NWGNUauthzusr new file mode 100644 index 0000000000..eb9e2c93c3 --- /dev/null +++ b/trunk/modules/aaa/NWGNUauthzusr @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = authzusr + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) User Authorization Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = AuthzUser Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authzusr.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_authz_user.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + authz_user_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/NWGNUmakefile b/trunk/modules/aaa/NWGNUmakefile new file mode 100644 index 0000000000..302aec8cb3 --- /dev/null +++ b/trunk/modules/aaa/NWGNUmakefile @@ -0,0 +1,261 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/authbasc.nlm \ + $(OBJDIR)/authdigt.nlm \ + $(OBJDIR)/authnano.nlm \ + $(OBJDIR)/authnalias.nlm \ + $(OBJDIR)/authndbm.nlm \ + $(OBJDIR)/authndef.nlm \ + $(OBJDIR)/authnfil.nlm \ + $(OBJDIR)/authzdbm.nlm \ + $(OBJDIR)/authzdef.nlm \ + $(OBJDIR)/authzgrp.nlm \ + $(OBJDIR)/authzusr.nlm \ + $(OBJDIR)/authzusr.nlm \ + $(EOLIST) + +# If LDAPSDK has been defined then build the authnz_ldap module +ifneq "$(LDAPSDK)" "" +TARGET_nlm += $(OBJDIR)/authnzldap.nlm \ + $(EOLIST) +endif + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/aaa/config.m4 b/trunk/modules/aaa/config.m4 new file mode 100644 index 0000000000..6a853d758a --- /dev/null +++ b/trunk/modules/aaa/config.m4 @@ -0,0 +1,54 @@ +dnl modules enabled in this directory by default + +dnl Authentication (authn), Access, and Authorization (authz) + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(aaa) + +dnl Authentication modules; modules checking a username and password against a +dnl file, database, or other similar magic. +dnl +APACHE_MODULE(authn_file, file-based authentication control, , , yes) +APACHE_MODULE(authn_dbm, DBM-based authentication control, , , most) +APACHE_MODULE(authn_anon, anonymous user authentication control, , , most) + +dnl - and just in case all of the above punt; a default handler to +dnl keep the bad guys out. +APACHE_MODULE(authn_default, authentication backstopper, , , yes) + +dnl Provider alias module. +APACHE_MODULE(authn_alias, auth provider alias, , , no) + +dnl Authorization modules: modules which verify a certain property such as +dnl membership of a group, value of the IP address against a list of pre +dnl configured directives (e.g. require, allow) or against an external file +dnl or database. +dnl +APACHE_MODULE(authz_host, host-based authorization control, , , yes) +APACHE_MODULE(authz_groupfile, 'require group' authorization control, , , yes) +APACHE_MODULE(authz_user, 'require user' authorization control, , , yes) +APACHE_MODULE(authz_dbm, DBM-based authorization control, , , most) +APACHE_MODULE(authz_owner, 'require file-owner' authorization control, , , most) + +dnl LDAP authentication module. This module has both the authn and authz +dnl modules in one, so as to share the LDAP server config directives. +APACHE_MODULE(authnz_ldap, LDAP based authentication, , , no) + +dnl - and just in case all of the above punt; a default handler to +dnl keep the bad guys out. +APACHE_MODULE(authz_default, authorization control backstopper, , , yes) + +dnl these are the front-end authentication modules + +APACHE_MODULE(auth_basic, basic authentication, , , yes) +APACHE_MODULE(auth_digest, RFC2617 Digest authentication, , , most, [ + APR_CHECK_APR_DEFINE(APR_HAS_RANDOM) + if test $ac_cv_define_APR_HAS_RANDOM = "no"; then + echo "You need APR random support to use mod_auth_digest." + echo "Look at APR configure options --with-egd and --with-devrandom." + enable_auth_digest="no" + fi +]) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/aaa/mod_auth.h b/trunk/modules/aaa/mod_auth.h new file mode 100644 index 0000000000..7595f8b393 --- /dev/null +++ b/trunk/modules/aaa/mod_auth.h @@ -0,0 +1,75 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MOD_AUTH_H +#define APACHE_MOD_AUTH_H + +#include "apr_pools.h" +#include "apr_hash.h" + +#include "httpd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AUTHN_PROVIDER_GROUP "authn" +#define AUTHN_DEFAULT_PROVIDER "file" + +#define AUTHZ_GROUP_NOTE "authz_group_note" +#define AUTHN_PROVIDER_NAME_NOTE "authn_provider_name" + +typedef enum { + AUTH_DENIED, + AUTH_GRANTED, + AUTH_USER_FOUND, + AUTH_USER_NOT_FOUND, + AUTH_GENERAL_ERROR +} authn_status; + +typedef struct { + /* Given a username and password, expected to return AUTH_GRANTED + * if we can validate this user/password combination. + */ + authn_status (*check_password)(request_rec *r, const char *user, + const char *password); + + /* Given a user and realm, expected to return AUTH_USER_FOUND if we + * can find a md5 hash of 'user:realm:password' + */ + authn_status (*get_realm_hash)(request_rec *r, const char *user, + const char *realm, char **rethash); +} authn_provider; + +/* A linked-list of authn providers. */ +typedef struct authn_provider_list authn_provider_list; + +struct authn_provider_list { + const char *provider_name; + const authn_provider *provider; + authn_provider_list *next; +}; + +typedef struct { + /* For a given user, return a hash of all groups the user belongs to. */ + apr_hash_t * (*get_user_groups)(request_rec *r, const char *user); +} authz_provider; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/modules/aaa/mod_auth_basic.c b/trunk/modules/aaa/mod_auth_basic.c new file mode 100644 index 0000000000..ee296a4491 --- /dev/null +++ b/trunk/modules/aaa/mod_auth_basic.c @@ -0,0 +1,314 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_md5.h" /* for apr_password_validate */ +#include "apr_lib.h" /* for apr_isspace */ +#include "apr_base64.h" /* for apr_base64_decode et al */ +#define APR_WANT_STRFUNC /* for strcasecmp */ +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" +#include "ap_provider.h" + +#include "mod_auth.h" + +typedef struct { + authn_provider_list *providers; + char *dir; + int authoritative; +} auth_basic_config_rec; + +static void *create_auth_basic_dir_config(apr_pool_t *p, char *d) +{ + auth_basic_config_rec *conf = apr_pcalloc(p, sizeof(*conf)); + + conf->dir = d; + /* Any failures are fatal. */ + conf->authoritative = 1; + + return conf; +} + +static const char *add_authn_provider(cmd_parms *cmd, void *config, + const char *arg) +{ + auth_basic_config_rec *conf = (auth_basic_config_rec*)config; + authn_provider_list *newp; + const char *provider_name; + + if (strcasecmp(arg, "on") == 0) { + provider_name = AUTHN_DEFAULT_PROVIDER; + } + else if (strcasecmp(arg, "off") == 0) { + /* Clear all configured providers and return. */ + conf->providers = NULL; + return NULL; + } + else { + provider_name = apr_pstrdup(cmd->pool, arg); + } + + newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list)); + newp->provider_name = provider_name; + + /* lookup and cache the actual provider now */ + newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, + newp->provider_name, "0"); + + if (newp->provider == NULL) { + /* by the time they use it, the provider should be loaded and + registered with us. */ + return apr_psprintf(cmd->pool, + "Unknown Authn provider: %s", + newp->provider_name); + } + + if (!newp->provider->check_password) { + /* if it doesn't provide the appropriate function, reject it */ + return apr_psprintf(cmd->pool, + "The '%s' Authn provider doesn't support " + "Basic Authentication", provider_name); + } + + /* Add it to the list now. */ + if (!conf->providers) { + conf->providers = newp; + } + else { + authn_provider_list *last = conf->providers; + + while (last->next) { + last = last->next; + } + last->next = newp; + } + + return NULL; +} + +static const command_rec auth_basic_cmds[] = +{ + AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG, + "specify the auth providers for a directory or location"), + AP_INIT_FLAG("AuthBasicAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(auth_basic_config_rec, authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules if the UserID is not known to this module"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA auth_basic_module; + +/* These functions return 0 if client is OK, and proper error status + * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or + * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we + * couldn't figure out how to tell if the client is authorized or not. + * + * If they return DECLINED, and all other modules also decline, that's + * treated by the server core as a configuration error, logged and + * reported as such. + */ + +static void note_basic_auth_failure(request_rec *r) +{ + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); +} + +static int get_basic_auth(request_rec *r, const char **user, + const char **pw) +{ + const char *auth_line; + char *decoded_line; + int length; + + /* Get the appropriate header */ + auth_line = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq) + ? "Proxy-Authorization" + : "Authorization"); + + if (!auth_line) { + note_basic_auth_failure(r); + return HTTP_UNAUTHORIZED; + } + + if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) { + /* Client tried to authenticate using wrong auth scheme */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "client used wrong authentication scheme: %s", r->uri); + note_basic_auth_failure(r); + return HTTP_UNAUTHORIZED; + } + + /* Skip leading spaces. */ + while (apr_isspace(*auth_line)) { + auth_line++; + } + + decoded_line = apr_palloc(r->pool, apr_base64_decode_len(auth_line) + 1); + length = apr_base64_decode(decoded_line, auth_line); + /* Null-terminate the string. */ + decoded_line[length] = '\0'; + + *user = ap_getword_nulls(r->pool, (const char**)&decoded_line, ':'); + *pw = decoded_line; + + /* set the user, even though the user is unauthenticated at this point */ + r->user = (char *) *user; + + return OK; +} + +/* Determine user ID, and check if it really is that user, for HTTP + * basic authentication... + */ +static int authenticate_basic_user(request_rec *r) +{ + auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config, + &auth_basic_module); + const char *sent_user, *sent_pw, *current_auth; + int res; + authn_status auth_result; + authn_provider_list *current_provider; + + /* Are we configured to be Basic auth? */ + current_auth = ap_auth_type(r); + if (!current_auth || strcasecmp(current_auth, "Basic")) { + return DECLINED; + } + + /* We need an authentication realm. */ + if (!ap_auth_name(r)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, + 0, r, "need AuthName: %s", r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + + r->ap_auth_type = "Basic"; + + res = get_basic_auth(r, &sent_user, &sent_pw); + if (res) { + return res; + } + + current_provider = conf->providers; + do { + const authn_provider *provider; + + /* For now, if a provider isn't set, we'll be nice and use the file + * provider. + */ + if (!current_provider) { + provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, + AUTHN_DEFAULT_PROVIDER, "0"); + + if (!provider || !provider->check_password) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "No Authn provider configured"); + auth_result = AUTH_GENERAL_ERROR; + break; + } + apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, AUTHN_DEFAULT_PROVIDER); + } + else { + provider = current_provider->provider; + apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, current_provider->provider_name); + } + + + auth_result = provider->check_password(r, sent_user, sent_pw); + + apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE); + + /* Something occured. Stop checking. */ + if (auth_result != AUTH_USER_NOT_FOUND) { + break; + } + + /* If we're not really configured for providers, stop now. */ + if (!conf->providers) { + break; + } + + current_provider = current_provider->next; + } while (current_provider); + + if (auth_result != AUTH_GRANTED) { + int return_code; + + /* If we're not authoritative, then any error is ignored. */ + if (!(conf->authoritative) && auth_result != AUTH_DENIED) { + return DECLINED; + } + + switch (auth_result) { + case AUTH_DENIED: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "user %s: authentication failure for \"%s\": " + "Password Mismatch", + sent_user, r->uri); + return_code = HTTP_UNAUTHORIZED; + break; + case AUTH_USER_NOT_FOUND: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "user %s not found: %s", sent_user, r->uri); + return_code = HTTP_UNAUTHORIZED; + break; + case AUTH_GENERAL_ERROR: + default: + /* We'll assume that the module has already said what its error + * was in the logs. + */ + return_code = HTTP_INTERNAL_SERVER_ERROR; + break; + } + + /* If we're returning 403, tell them to try again. */ + if (return_code == HTTP_UNAUTHORIZED) { + note_basic_auth_failure(r); + } + return return_code; + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA auth_basic_module = +{ + STANDARD20_MODULE_STUFF, + create_auth_basic_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + auth_basic_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_auth_basic.dsp b/trunk/modules/aaa/mod_auth_basic.dsp new file mode 100644 index 0000000000..a79fc2fb48 --- /dev/null +++ b/trunk/modules/aaa/mod_auth_basic.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_auth_basic" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_auth_basic - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_auth_basic.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_auth_basic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_auth_basic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_auth_basic - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Release\mod_auth_basic_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Debug\mod_auth_basic_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so + +!ENDIF + +# Begin Target + +# Name "mod_auth_basic - Win32 Release" +# Name "mod_auth_basic - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_auth_basic.c +# End Source File +# Begin Source File + +SOURCE=.\mod_auth_basic.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_auth_basic - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_auth_basic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_auth_basic.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_auth_basic.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_auth_basic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_auth_basic.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_auth_basic.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_auth_digest.c b/trunk/modules/aaa/mod_auth_digest.c new file mode 100644 index 0000000000..9756ac2611 --- /dev/null +++ b/trunk/modules/aaa/mod_auth_digest.c @@ -0,0 +1,2059 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_auth_digest: MD5 digest authentication + * + * Originally by Alexei Kosut + * Updated to RFC-2617 by Ronald Tschalär + * based on mod_auth, by Rob McCool and Robert S. Thau + * + * This module an updated version of modules/standard/mod_digest.c + * It is still fairly new and problems may turn up - submit problem + * reports to the Apache bug-database, or send them directly to me + * at ronald@innovation.ch. + * + * Requires either /dev/random (or equivalent) or the truerand library, + * available for instance from + * ftp://research.att.com/dist/mab/librand.shar + * + * Open Issues: + * - qop=auth-int (when streams and trailer support available) + * - nonce-format configurability + * - Proxy-Authorization-Info header is set by this module, but is + * currently ignored by mod_proxy (needs patch to mod_proxy) + * - generating the secret takes a while (~ 8 seconds) if using the + * truerand library + * - The source of the secret should be run-time directive (with server + * scope: RSRC_CONF). However, that could be tricky when trying to + * choose truerand vs. file... + * - shared-mem not completely tested yet. Seems to work ok for me, + * but... (definitely won't work on Windoze) + * - Sharing a realm among multiple servers has following problems: + * o Server name and port can't be included in nonce-hash + * (we need two nonce formats, which must be configured explicitly) + * o Nonce-count check can't be for equal, or then nonce-count checking + * must be disabled. What we could do is the following: + * (expected < received) ? set expected = received : issue error + * The only problem is that it allows replay attacks when somebody + * captures a packet sent to one server and sends it to another + * one. Should we add "AuthDigestNcCheck Strict"? + * - expired nonces give amaya fits. + */ + +#include "apr_sha1.h" +#include "apr_base64.h" +#include "apr_lib.h" +#include "apr_time.h" +#include "apr_errno.h" +#include "apr_global_mutex.h" +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" +#include "http_log.h" +#include "http_protocol.h" +#include "apr_uri.h" +#include "util_md5.h" +#include "apr_shm.h" +#include "apr_rmm.h" +#include "ap_provider.h" + +#include "mod_auth.h" + +/* Disable shmem until pools/init gets sorted out + * remove following two lines when fixed + */ +#undef APR_HAS_SHARED_MEMORY +#define APR_HAS_SHARED_MEMORY 0 + +/* struct to hold the configuration info */ + +typedef struct digest_config_struct { + const char *dir_name; + authn_provider_list *providers; + const char *realm; + char **qop_list; + apr_sha1_ctx_t nonce_ctx; + apr_time_t nonce_lifetime; + const char *nonce_format; + int check_nc; + const char *algorithm; + char *uri_list; + const char *ha1; +} digest_config_rec; + + +#define DFLT_ALGORITHM "MD5" + +#define DFLT_NONCE_LIFE apr_time_from_sec(300) +#define NEXTNONCE_DELTA apr_time_from_sec(30) + + +#define NONCE_TIME_LEN (((sizeof(apr_time_t)+2)/3)*4) +#define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE) +#define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN) + +#define SECRET_LEN 20 + + +/* client list definitions */ + +typedef struct hash_entry { + unsigned long key; /* the key for this entry */ + struct hash_entry *next; /* next entry in the bucket */ + unsigned long nonce_count; /* for nonce-count checking */ + char ha1[2*APR_MD5_DIGESTSIZE+1]; /* for algorithm=MD5-sess */ + char last_nonce[NONCE_LEN+1]; /* for one-time nonce's */ +} client_entry; + +static struct hash_table { + client_entry **table; + unsigned long tbl_len; + unsigned long num_entries; + unsigned long num_created; + unsigned long num_removed; + unsigned long num_renewed; +} *client_list; + + +/* struct to hold a parsed Authorization header */ + +enum hdr_sts { NO_HEADER, NOT_DIGEST, INVALID, VALID }; + +typedef struct digest_header_struct { + const char *scheme; + const char *realm; + const char *username; + char *nonce; + const char *uri; + const char *method; + const char *digest; + const char *algorithm; + const char *cnonce; + const char *opaque; + unsigned long opaque_num; + const char *message_qop; + const char *nonce_count; + /* the following fields are not (directly) from the header */ + apr_time_t nonce_time; + enum hdr_sts auth_hdr_sts; + const char *raw_request_uri; + apr_uri_t *psd_request_uri; + int needed_auth; + client_entry *client; +} digest_header_rec; + + +/* (mostly) nonce stuff */ + +typedef union time_union { + apr_time_t time; + unsigned char arr[sizeof(apr_time_t)]; +} time_rec; + +static unsigned char secret[SECRET_LEN]; + +/* client-list, opaque, and one-time-nonce stuff */ + +static apr_shm_t *client_shm = NULL; +static apr_rmm_t *client_rmm = NULL; +static unsigned long *opaque_cntr; +static apr_time_t *otn_counter; /* one-time-nonce counter */ +static apr_global_mutex_t *client_lock = NULL; +static apr_global_mutex_t *opaque_lock = NULL; +static char client_lock_name[L_tmpnam]; +static char opaque_lock_name[L_tmpnam]; + +#define DEF_SHMEM_SIZE 1000L /* ~ 12 entries */ +#define DEF_NUM_BUCKETS 15L +#define HASH_DEPTH 5 + +static long shmem_size = DEF_SHMEM_SIZE; +static long num_buckets = DEF_NUM_BUCKETS; + + +module AP_MODULE_DECLARE_DATA auth_digest_module; + +/* + * initialization code + */ + +static apr_status_t cleanup_tables(void *not_used) +{ + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Digest: cleaning up shared memory"); + fflush(stderr); + + if (client_shm) { + apr_shm_destroy(client_shm); + client_shm = NULL; + } + + if (client_lock) { + apr_global_mutex_destroy(client_lock); + client_lock = NULL; + } + + if (opaque_lock) { + apr_global_mutex_destroy(opaque_lock); + opaque_lock = NULL; + } + + return APR_SUCCESS; +} + +static apr_status_t initialize_secret(server_rec *s) +{ + apr_status_t status; + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "Digest: generating secret for digest authentication ..."); + +#if APR_HAS_RANDOM + status = apr_generate_random_bytes(secret, sizeof(secret)); +#else +#error APR random number support is missing; you probably need to install the truerand library. +#endif + + if (status != APR_SUCCESS) { + char buf[120]; + ap_log_error(APLOG_MARK, APLOG_CRIT, status, s, + "Digest: error generating secret: %s", + apr_strerror(status, buf, sizeof(buf))); + return status; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "Digest: done"); + + return APR_SUCCESS; +} + +static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s) +{ + ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, + "Digest: %s - all nonce-count checking, one-time nonces, and " + "MD5-sess algorithm disabled", msg); + + cleanup_tables(NULL); +} + +#if APR_HAS_SHARED_MEMORY + +static void initialize_tables(server_rec *s, apr_pool_t *ctx) +{ + unsigned long idx; + apr_status_t sts; + + /* set up client list */ + + sts = apr_shm_create(&client_shm, shmem_size, tmpnam(NULL), ctx); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to create shared memory segments", sts, s); + return; + } + + client_list = apr_rmm_malloc(client_rmm, sizeof(*client_list) + + sizeof(client_entry*)*num_buckets); + if (!client_list) { + log_error_and_cleanup("failed to allocate shared memory", -1, s); + return; + } + client_list->table = (client_entry**) (client_list + 1); + for (idx = 0; idx < num_buckets; idx++) { + client_list->table[idx] = NULL; + } + client_list->tbl_len = num_buckets; + client_list->num_entries = 0; + + tmpnam(client_lock_name); + /* FIXME: get the client_lock_name from a directive so we're portable + * to non-process-inheriting operating systems, like Win32. */ + sts = apr_global_mutex_create(&client_lock, client_lock_name, + APR_LOCK_DEFAULT, ctx); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to create lock (client_lock)", sts, s); + return; + } + + + /* setup opaque */ + + opaque_cntr = apr_rmm_malloc(client_rmm, sizeof(*opaque_cntr)); + if (opaque_cntr == NULL) { + log_error_and_cleanup("failed to allocate shared memory", -1, s); + return; + } + *opaque_cntr = 1UL; + + tmpnam(opaque_lock_name); + /* FIXME: get the opaque_lock_name from a directive so we're portable + * to non-process-inheriting operating systems, like Win32. */ + sts = apr_global_mutex_create(&opaque_lock, opaque_lock_name, + APR_LOCK_DEFAULT, ctx); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); + return; + } + + + /* setup one-time-nonce counter */ + + otn_counter = apr_rmm_malloc(client_rmm, sizeof(*otn_counter)); + if (otn_counter == NULL) { + log_error_and_cleanup("failed to allocate shared memory", -1, s); + return; + } + *otn_counter = 0; + /* no lock here */ + + + /* success */ + return; +} + +#endif /* APR_HAS_SHARED_MEMORY */ + + +static int initialize_module(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + void *data; + const char *userdata_key = "auth_digest_init"; + + /* initialize_module() will be called twice, and if it's a DSO + * then all static data from the first call will be lost. Only + * set up our static data on the second call. */ + apr_pool_userdata_get(&data, userdata_key, s->process->pool); + if (!data) { + apr_pool_userdata_set((const void *)1, userdata_key, + apr_pool_cleanup_null, s->process->pool); + return OK; + } + if (initialize_secret(s) != APR_SUCCESS) { + return !OK; + } + +#if APR_HAS_SHARED_MEMORY + /* Note: this stuff is currently fixed for the lifetime of the server, + * i.e. even across restarts. This means that A) any shmem-size + * configuration changes are ignored, and B) certain optimizations, + * such as only allocating the smallest necessary entry for each + * client, can't be done. However, the alternative is a nightmare: + * we can't call apr_shm_destroy on a graceful restart because there + * will be children using the tables, and we also don't know when the + * last child dies. Therefore we can never clean up the old stuff, + * creating a creeping memory leak. + */ + initialize_tables(s, p); + apr_pool_cleanup_register(p, NULL, cleanup_tables, apr_pool_cleanup_null); +#endif /* APR_HAS_SHARED_MEMORY */ + return OK; +} + +static void initialize_child(apr_pool_t *p, server_rec *s) +{ + apr_status_t sts; + + if (!client_shm) { + return; + } + + /* FIXME: get the client_lock_name from a directive so we're portable + * to non-process-inheriting operating systems, like Win32. */ + sts = apr_global_mutex_child_init(&client_lock, client_lock_name, p); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to create lock (client_lock)", sts, s); + return; + } + /* FIXME: get the opaque_lock_name from a directive so we're portable + * to non-process-inheriting operating systems, like Win32. */ + sts = apr_global_mutex_child_init(&opaque_lock, opaque_lock_name, p); + if (sts != APR_SUCCESS) { + log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s); + return; + } +} + +/* + * configuration code + */ + +static void *create_digest_dir_config(apr_pool_t *p, char *dir) +{ + digest_config_rec *conf; + + if (dir == NULL) { + return NULL; + } + + conf = (digest_config_rec *) apr_pcalloc(p, sizeof(digest_config_rec)); + if (conf) { + conf->qop_list = apr_palloc(p, sizeof(char*)); + conf->qop_list[0] = NULL; + conf->nonce_lifetime = DFLT_NONCE_LIFE; + conf->dir_name = apr_pstrdup(p, dir); + conf->algorithm = DFLT_ALGORITHM; + } + + return conf; +} + +static const char *set_realm(cmd_parms *cmd, void *config, const char *realm) +{ + digest_config_rec *conf = (digest_config_rec *) config; + + /* The core already handles the realm, but it's just too convenient to + * grab it ourselves too and cache some setups. However, we need to + * let the core get at it too, which is why we decline at the end - + * this relies on the fact that http_core is last in the list. + */ + conf->realm = realm; + + /* we precompute the part of the nonce hash that is constant (well, + * the host:port would be too, but that varies for .htaccess files + * and directives outside a virtual host section) + */ + apr_sha1_init(&conf->nonce_ctx); + apr_sha1_update_binary(&conf->nonce_ctx, secret, sizeof(secret)); + apr_sha1_update_binary(&conf->nonce_ctx, (const unsigned char *) realm, + strlen(realm)); + + return DECLINE_CMD; +} + +static const char *add_authn_provider(cmd_parms *cmd, void *config, + const char *arg) +{ + digest_config_rec *conf = (digest_config_rec*)config; + authn_provider_list *newp; + const char *provider_name; + + if (strcasecmp(arg, "on") == 0) { + provider_name = AUTHN_DEFAULT_PROVIDER; + } + else if (strcasecmp(arg, "off") == 0) { + /* Clear all configured providers and return. */ + conf->providers = NULL; + return NULL; + } + else { + provider_name = apr_pstrdup(cmd->pool, arg); + } + + newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list)); + newp->provider_name = provider_name; + + /* lookup and cache the actual provider now */ + newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, + newp->provider_name, "0"); + + if (newp->provider == NULL) { + /* by the time they use it, the provider should be loaded and + registered with us. */ + return apr_psprintf(cmd->pool, + "Unknown Authn provider: %s", + newp->provider_name); + } + + if (!newp->provider->get_realm_hash) { + /* if it doesn't provide the appropriate function, reject it */ + return apr_psprintf(cmd->pool, + "The '%s' Authn provider doesn't support " + "Digest Authentication", provider_name); + } + + /* Add it to the list now. */ + if (!conf->providers) { + conf->providers = newp; + } + else { + authn_provider_list *last = conf->providers; + + while (last->next) { + last = last->next; + } + last->next = newp; + } + + return NULL; +} + +static const char *set_qop(cmd_parms *cmd, void *config, const char *op) +{ + digest_config_rec *conf = (digest_config_rec *) config; + char **tmp; + int cnt; + + if (!strcasecmp(op, "none")) { + if (conf->qop_list[0] == NULL) { + conf->qop_list = apr_palloc(cmd->pool, 2 * sizeof(char*)); + conf->qop_list[1] = NULL; + } + conf->qop_list[0] = "none"; + return NULL; + } + + if (!strcasecmp(op, "auth-int")) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "Digest: WARNING: qop `auth-int' currently only works " + "correctly for responses with no entity"); + } + else if (strcasecmp(op, "auth")) { + return apr_pstrcat(cmd->pool, "Unrecognized qop: ", op, NULL); + } + + for (cnt = 0; conf->qop_list[cnt] != NULL; cnt++) + ; + + tmp = apr_palloc(cmd->pool, (cnt + 2) * sizeof(char*)); + memcpy(tmp, conf->qop_list, cnt*sizeof(char*)); + tmp[cnt] = apr_pstrdup(cmd->pool, op); + tmp[cnt+1] = NULL; + conf->qop_list = tmp; + + return NULL; +} + +static const char *set_nonce_lifetime(cmd_parms *cmd, void *config, + const char *t) +{ + char *endptr; + long lifetime; + + lifetime = strtol(t, &endptr, 10); + if (endptr < (t+strlen(t)) && !apr_isspace(*endptr)) { + return apr_pstrcat(cmd->pool, + "Invalid time in AuthDigestNonceLifetime: ", + t, NULL); + } + + ((digest_config_rec *) config)->nonce_lifetime = apr_time_from_sec(lifetime); + return NULL; +} + +static const char *set_nonce_format(cmd_parms *cmd, void *config, + const char *fmt) +{ + ((digest_config_rec *) config)->nonce_format = fmt; + return "AuthDigestNonceFormat is not implemented (yet)"; +} + +static const char *set_nc_check(cmd_parms *cmd, void *config, int flag) +{ + if (flag && !client_shm) + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + cmd->server, "Digest: WARNING: nonce-count checking " + "is not supported on platforms without shared-memory " + "support - disabling check"); + + ((digest_config_rec *) config)->check_nc = flag; + return NULL; +} + +static const char *set_algorithm(cmd_parms *cmd, void *config, const char *alg) +{ + if (!strcasecmp(alg, "MD5-sess")) { + if (!client_shm) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + cmd->server, "Digest: WARNING: algorithm `MD5-sess' " + "is not supported on platforms without shared-memory " + "support - reverting to MD5"); + alg = "MD5"; + } + } + else if (strcasecmp(alg, "MD5")) { + return apr_pstrcat(cmd->pool, "Invalid algorithm in AuthDigestAlgorithm: ", alg, NULL); + } + + ((digest_config_rec *) config)->algorithm = alg; + return NULL; +} + +static const char *set_uri_list(cmd_parms *cmd, void *config, const char *uri) +{ + digest_config_rec *c = (digest_config_rec *) config; + if (c->uri_list) { + c->uri_list[strlen(c->uri_list)-1] = '\0'; + c->uri_list = apr_pstrcat(cmd->pool, c->uri_list, " ", uri, "\"", NULL); + } + else { + c->uri_list = apr_pstrcat(cmd->pool, ", domain=\"", uri, "\"", NULL); + } + return NULL; +} + +static const char *set_shmem_size(cmd_parms *cmd, void *config, + const char *size_str) +{ + char *endptr; + long size, min; + + size = strtol(size_str, &endptr, 10); + while (apr_isspace(*endptr)) endptr++; + if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') { + ; + } + else if (*endptr == 'k' || *endptr == 'K') { + size *= 1024; + } + else if (*endptr == 'm' || *endptr == 'M') { + size *= 1048576; + } + else { + return apr_pstrcat(cmd->pool, "Invalid size in AuthDigestShmemSize: ", + size_str, NULL); + } + + min = sizeof(*client_list) + sizeof(client_entry*) + sizeof(client_entry); + if (size < min) { + return apr_psprintf(cmd->pool, "size in AuthDigestShmemSize too small: " + "%ld < %ld", size, min); + } + + shmem_size = size; + num_buckets = (size - sizeof(*client_list)) / + (sizeof(client_entry*) + HASH_DEPTH * sizeof(client_entry)); + if (num_buckets == 0) { + num_buckets = 1; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, + "Digest: Set shmem-size: %ld, num-buckets: %ld", shmem_size, + num_buckets); + + return NULL; +} + +static const command_rec digest_cmds[] = +{ + AP_INIT_TAKE1("AuthName", set_realm, NULL, OR_AUTHCFG, + "The authentication realm (e.g. \"Members Only\")"), + AP_INIT_ITERATE("AuthDigestProvider", add_authn_provider, NULL, OR_AUTHCFG, + "specify the auth providers for a directory or location"), + AP_INIT_ITERATE("AuthDigestQop", set_qop, NULL, OR_AUTHCFG, + "A list of quality-of-protection options"), + AP_INIT_TAKE1("AuthDigestNonceLifetime", set_nonce_lifetime, NULL, OR_AUTHCFG, + "Maximum lifetime of the server nonce (seconds)"), + AP_INIT_TAKE1("AuthDigestNonceFormat", set_nonce_format, NULL, OR_AUTHCFG, + "The format to use when generating the server nonce"), + AP_INIT_FLAG("AuthDigestNcCheck", set_nc_check, NULL, OR_AUTHCFG, + "Whether or not to check the nonce-count sent by the client"), + AP_INIT_TAKE1("AuthDigestAlgorithm", set_algorithm, NULL, OR_AUTHCFG, + "The algorithm used for the hash calculation"), + AP_INIT_ITERATE("AuthDigestDomain", set_uri_list, NULL, OR_AUTHCFG, + "A list of URI's which belong to the same protection space as the current URI"), + AP_INIT_TAKE1("AuthDigestShmemSize", set_shmem_size, NULL, RSRC_CONF, + "The amount of shared memory to allocate for keeping track of clients"), + {NULL} +}; + + +/* + * client list code + * + * Each client is assigned a number, which is transferred in the opaque + * field of the WWW-Authenticate and Authorization headers. The number + * is just a simple counter which is incremented for each new client. + * Clients can't forge this number because it is hashed up into the + * server nonce, and that is checked. + * + * The clients are kept in a simple hash table, which consists of an + * array of client_entry's, each with a linked list of entries hanging + * off it. The client's number modulo the size of the array gives the + * bucket number. + * + * The clients are garbage collected whenever a new client is allocated + * but there is not enough space left in the shared memory segment. A + * simple semi-LRU is used for this: whenever a client entry is accessed + * it is moved to the beginning of the linked list in its bucket (this + * also makes for faster lookups for current clients). The garbage + * collecter then just removes the oldest entry (i.e. the one at the + * end of the list) in each bucket. + * + * The main advantages of the above scheme are that it's easy to implement + * and it keeps the hash table evenly balanced (i.e. same number of entries + * in each bucket). The major disadvantage is that you may be throwing + * entries out which are in active use. This is not tragic, as these + * clients will just be sent a new client id (opaque field) and nonce + * with a stale=true (i.e. it will just look like the nonce expired, + * thereby forcing an extra round trip). If the shared memory segment + * has enough headroom over the current client set size then this should + * not occur too often. + * + * To help tune the size of the shared memory segment (and see if the + * above algorithm is really sufficient) a set of counters is kept + * indicating the number of clients held, the number of garbage collected + * clients, and the number of erroneously purged clients. These are printed + * out at each garbage collection run. Note that access to the counters is + * not synchronized because they are just indicaters, and whether they are + * off by a few doesn't matter; and for the same reason no attempt is made + * to guarantee the num_renewed is correct in the face of clients spoofing + * the opaque field. + */ + +/* + * Get the client given its client number (the key). Returns the entry, + * or NULL if it's not found. + * + * Access to the list itself is synchronized via locks. However, access + * to the entry returned by get_client() is NOT synchronized. This means + * that there are potentially problems if a client uses multiple, + * simultaneous connections to access url's within the same protection + * space. However, these problems are not new: when using multiple + * connections you have no guarantee of the order the requests are + * processed anyway, so you have problems with the nonce-count and + * one-time nonces anyway. + */ +static client_entry *get_client(unsigned long key, const request_rec *r) +{ + int bucket; + client_entry *entry, *prev = NULL; + + + if (!key || !client_shm) return NULL; + + bucket = key % client_list->tbl_len; + entry = client_list->table[bucket]; + + apr_global_mutex_lock(client_lock); + + while (entry && key != entry->key) { + prev = entry; + entry = entry->next; + } + + if (entry && prev) { /* move entry to front of list */ + prev->next = entry->next; + entry->next = client_list->table[bucket]; + client_list->table[bucket] = entry; + } + + apr_global_mutex_unlock(client_lock); + + if (entry) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "get_client(): client %lu found", key); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "get_client(): client %lu not found", key); + } + + return entry; +} + + +/* A simple garbage-collecter to remove unused clients. It removes the + * last entry in each bucket and updates the counters. Returns the + * number of removed entries. + */ +static long gc(void) +{ + client_entry *entry, *prev; + unsigned long num_removed = 0, idx; + + /* garbage collect all last entries */ + + for (idx = 0; idx < client_list->tbl_len; idx++) { + entry = client_list->table[idx]; + prev = NULL; + while (entry->next) { /* find last entry */ + prev = entry; + entry = entry->next; + } + if (prev) { + prev->next = NULL; /* cut list */ + } + else { + client_list->table[idx] = NULL; + } + if (entry) { /* remove entry */ + apr_rmm_free(client_rmm, (apr_rmm_off_t)entry); + num_removed++; + } + } + + /* update counters and log */ + + client_list->num_entries -= num_removed; + client_list->num_removed += num_removed; + + return num_removed; +} + + +/* + * Add a new client to the list. Returns the entry if successful, NULL + * otherwise. This triggers the garbage collection if memory is low. + */ +static client_entry *add_client(unsigned long key, client_entry *info, + server_rec *s) +{ + int bucket; + client_entry *entry; + + + if (!key || !client_shm) { + return NULL; + } + + bucket = key % client_list->tbl_len; + entry = client_list->table[bucket]; + + apr_global_mutex_lock(client_lock); + + /* try to allocate a new entry */ + + entry = (client_entry *)apr_rmm_malloc(client_rmm, sizeof(client_entry)); + if (!entry) { + long num_removed = gc(); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Digest: gc'd %ld client entries. Total new clients: " + "%ld; Total removed clients: %ld; Total renewed clients: " + "%ld", num_removed, + client_list->num_created - client_list->num_renewed, + client_list->num_removed, client_list->num_renewed); + entry = (client_entry *)apr_rmm_malloc(client_rmm, sizeof(client_entry)); + if (!entry) { + return NULL; /* give up */ + } + } + + /* now add the entry */ + + memcpy(entry, info, sizeof(client_entry)); + entry->key = key; + entry->next = client_list->table[bucket]; + client_list->table[bucket] = entry; + client_list->num_created++; + client_list->num_entries++; + + apr_global_mutex_unlock(client_lock); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "allocated new client %lu", key); + + return entry; +} + + +/* + * Authorization header parser code + */ + +/* Parse the Authorization header, if it exists */ +static int get_digest_rec(request_rec *r, digest_header_rec *resp) +{ + const char *auth_line; + apr_size_t l; + int vk = 0, vv = 0; + char *key, *value; + + auth_line = apr_table_get(r->headers_in, + (PROXYREQ_PROXY == r->proxyreq) + ? "Proxy-Authorization" + : "Authorization"); + if (!auth_line) { + resp->auth_hdr_sts = NO_HEADER; + return !OK; + } + + resp->scheme = ap_getword_white(r->pool, &auth_line); + if (strcasecmp(resp->scheme, "Digest")) { + resp->auth_hdr_sts = NOT_DIGEST; + return !OK; + } + + l = strlen(auth_line); + + key = apr_palloc(r->pool, l+1); + value = apr_palloc(r->pool, l+1); + + while (auth_line[0] != '\0') { + + /* find key */ + + while (apr_isspace(auth_line[0])) { + auth_line++; + } + vk = 0; + while (auth_line[0] != '=' && auth_line[0] != ',' + && auth_line[0] != '\0' && !apr_isspace(auth_line[0])) { + key[vk++] = *auth_line++; + } + key[vk] = '\0'; + while (apr_isspace(auth_line[0])) { + auth_line++; + } + + /* find value */ + + if (auth_line[0] == '=') { + auth_line++; + while (apr_isspace(auth_line[0])) { + auth_line++; + } + + vv = 0; + if (auth_line[0] == '\"') { /* quoted string */ + auth_line++; + while (auth_line[0] != '\"' && auth_line[0] != '\0') { + if (auth_line[0] == '\\' && auth_line[1] != '\0') { + auth_line++; /* escaped char */ + } + value[vv++] = *auth_line++; + } + if (auth_line[0] != '\0') { + auth_line++; + } + } + else { /* token */ + while (auth_line[0] != ',' && auth_line[0] != '\0' + && !apr_isspace(auth_line[0])) { + value[vv++] = *auth_line++; + } + } + value[vv] = '\0'; + } + + while (auth_line[0] != ',' && auth_line[0] != '\0') { + auth_line++; + } + if (auth_line[0] != '\0') { + auth_line++; + } + + if (!strcasecmp(key, "username")) + resp->username = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "realm")) + resp->realm = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "nonce")) + resp->nonce = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "uri")) + resp->uri = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "response")) + resp->digest = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "algorithm")) + resp->algorithm = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "cnonce")) + resp->cnonce = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "opaque")) + resp->opaque = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "qop")) + resp->message_qop = apr_pstrdup(r->pool, value); + else if (!strcasecmp(key, "nc")) + resp->nonce_count = apr_pstrdup(r->pool, value); + } + + if (!resp->username || !resp->realm || !resp->nonce || !resp->uri + || !resp->digest + || (resp->message_qop && (!resp->cnonce || !resp->nonce_count))) { + resp->auth_hdr_sts = INVALID; + return !OK; + } + + if (resp->opaque) { + resp->opaque_num = (unsigned long) strtol(resp->opaque, NULL, 16); + } + + resp->auth_hdr_sts = VALID; + return OK; +} + + +/* Because the browser may preemptively send auth info, incrementing the + * nonce-count when it does, and because the client does not get notified + * if the URI didn't need authentication after all, we need to be sure to + * update the nonce-count each time we receive an Authorization header no + * matter what the final outcome of the request. Furthermore this is a + * convenient place to get the request-uri (before any subrequests etc + * are initiated) and to initialize the request_config. + * + * Note that this must be called after mod_proxy had its go so that + * r->proxyreq is set correctly. + */ +static int parse_hdr_and_update_nc(request_rec *r) +{ + digest_header_rec *resp; + int res; + + if (!ap_is_initial_req(r)) { + return DECLINED; + } + + resp = apr_pcalloc(r->pool, sizeof(digest_header_rec)); + resp->raw_request_uri = r->unparsed_uri; + resp->psd_request_uri = &r->parsed_uri; + resp->needed_auth = 0; + resp->method = r->method; + ap_set_module_config(r->request_config, &auth_digest_module, resp); + + res = get_digest_rec(r, resp); + resp->client = get_client(resp->opaque_num, r); + if (res == OK && resp->client) { + resp->client->nonce_count++; + } + + return DECLINED; +} + + +/* + * Nonce generation code + */ + +/* The hash part of the nonce is a SHA-1 hash of the time, realm, server host + * and port, opaque, and our secret. + */ +static void gen_nonce_hash(char *hash, const char *timestr, const char *opaque, + const server_rec *server, + const digest_config_rec *conf) +{ + const char *hex = "0123456789abcdef"; + unsigned char sha1[APR_SHA1_DIGESTSIZE]; + apr_sha1_ctx_t ctx; + int idx; + + memcpy(&ctx, &conf->nonce_ctx, sizeof(ctx)); + /* + apr_sha1_update_binary(&ctx, (const unsigned char *) server->server_hostname, + strlen(server->server_hostname)); + apr_sha1_update_binary(&ctx, (const unsigned char *) &server->port, + sizeof(server->port)); + */ + apr_sha1_update_binary(&ctx, (const unsigned char *) timestr, strlen(timestr)); + if (opaque) { + apr_sha1_update_binary(&ctx, (const unsigned char *) opaque, + strlen(opaque)); + } + apr_sha1_final(sha1, &ctx); + + for (idx=0; idx> 4]; + *hash++ = hex[sha1[idx] & 0xF]; + } + + *hash++ = '\0'; +} + + +/* The nonce has the format b64(time)+hash . + */ +static const char *gen_nonce(apr_pool_t *p, apr_time_t now, const char *opaque, + const server_rec *server, + const digest_config_rec *conf) +{ + char *nonce = apr_palloc(p, NONCE_LEN+1); + int len; + time_rec t; + + if (conf->nonce_lifetime != 0) { + t.time = now; + } + else if (otn_counter) { + /* this counter is not synch'd, because it doesn't really matter + * if it counts exactly. + */ + t.time = (*otn_counter)++; + } + else { + /* XXX: WHAT IS THIS CONSTANT? */ + t.time = 42; + } + len = apr_base64_encode_binary(nonce, t.arr, sizeof(t.arr)); + gen_nonce_hash(nonce+NONCE_TIME_LEN, nonce, opaque, server, conf); + + return nonce; +} + + +/* + * Opaque and hash-table management + */ + +/* + * Generate a new client entry, add it to the list, and return the + * entry. Returns NULL if failed. + */ +static client_entry *gen_client(const request_rec *r) +{ + unsigned long op; + client_entry new_entry = { 0, NULL, 0, "", "" }, *entry; + + if (!opaque_cntr) { + return NULL; + } + + apr_global_mutex_lock(opaque_lock); + op = (*opaque_cntr)++; + apr_global_mutex_lock(opaque_lock); + + if (!(entry = add_client(op, &new_entry, r->server))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: failed to allocate client entry - ignoring " + "client"); + return NULL; + } + + return entry; +} + + +/* + * MD5-sess code. + * + * If you want to use algorithm=MD5-sess you must write get_userpw_hash() + * yourself (see below). The dummy provided here just uses the hash from + * the auth-file, i.e. it is only useful for testing client implementations + * of MD5-sess . + */ + +/* + * get_userpw_hash() will be called each time a new session needs to be + * generated and is expected to return the equivalent of + * + * h_urp = ap_md5(r->pool, + * apr_pstrcat(r->pool, username, ":", ap_auth_name(r), ":", passwd)) + * ap_md5(r->pool, + * (unsigned char *) apr_pstrcat(r->pool, h_urp, ":", resp->nonce, ":", + * resp->cnonce, NULL)); + * + * or put differently, it must return + * + * MD5(MD5(username ":" realm ":" password) ":" nonce ":" cnonce) + * + * If something goes wrong, the failure must be logged and NULL returned. + * + * You must implement this yourself, which will probably consist of code + * contacting the password server with the necessary information (typically + * the username, realm, nonce, and cnonce) and receiving the hash from it. + * + * TBD: This function should probably be in a seperate source file so that + * people need not modify mod_auth_digest.c each time they install a new + * version of apache. + */ +static const char *get_userpw_hash(const request_rec *r, + const digest_header_rec *resp, + const digest_config_rec *conf) +{ + return ap_md5(r->pool, + (unsigned char *) apr_pstrcat(r->pool, conf->ha1, ":", resp->nonce, + ":", resp->cnonce, NULL)); +} + + +/* Retrieve current session H(A1). If there is none and "generate" is + * true then a new session for MD5-sess is generated and stored in the + * client struct; if generate is false, or a new session could not be + * generated then NULL is returned (in case of failure to generate the + * failure reason will have been logged already). + */ +static const char *get_session_HA1(const request_rec *r, + digest_header_rec *resp, + const digest_config_rec *conf, + int generate) +{ + const char *ha1 = NULL; + + /* return the current sessions if there is one */ + if (resp->opaque && resp->client && resp->client->ha1[0]) { + return resp->client->ha1; + } + else if (!generate) { + return NULL; + } + + /* generate a new session */ + if (!resp->client) { + resp->client = gen_client(r); + } + if (resp->client) { + ha1 = get_userpw_hash(r, resp, conf); + if (ha1) { + memcpy(resp->client->ha1, ha1, sizeof(resp->client->ha1)); + } + } + + return ha1; +} + + +static void clear_session(const digest_header_rec *resp) +{ + if (resp->client) { + resp->client->ha1[0] = '\0'; + } +} + +/* + * Authorization challenge generation code (for WWW-Authenticate) + */ + +static const char *ltox(apr_pool_t *p, unsigned long num) +{ + if (num != 0) { + return apr_psprintf(p, "%lx", num); + } + else { + return ""; + } +} + +static void note_digest_auth_failure(request_rec *r, + const digest_config_rec *conf, + digest_header_rec *resp, int stale) +{ + const char *qop, *opaque, *opaque_param, *domain, *nonce; + int cnt; + + /* Setup qop */ + + if (conf->qop_list[0] == NULL) { + qop = ", qop=\"auth\""; + } + else if (!strcasecmp(conf->qop_list[0], "none")) { + qop = ""; + } + else { + qop = apr_pstrcat(r->pool, ", qop=\"", conf->qop_list[0], NULL); + for (cnt = 1; conf->qop_list[cnt] != NULL; cnt++) { + qop = apr_pstrcat(r->pool, qop, ",", conf->qop_list[cnt], NULL); + } + qop = apr_pstrcat(r->pool, qop, "\"", NULL); + } + + /* Setup opaque */ + + if (resp->opaque == NULL) { + /* new client */ + if ((conf->check_nc || conf->nonce_lifetime == 0 + || !strcasecmp(conf->algorithm, "MD5-sess")) + && (resp->client = gen_client(r)) != NULL) { + opaque = ltox(r->pool, resp->client->key); + } + else { + opaque = ""; /* opaque not needed */ + } + } + else if (resp->client == NULL) { + /* client info was gc'd */ + resp->client = gen_client(r); + if (resp->client != NULL) { + opaque = ltox(r->pool, resp->client->key); + stale = 1; + client_list->num_renewed++; + } + else { + opaque = ""; /* ??? */ + } + } + else { + opaque = resp->opaque; + /* we're generating a new nonce, so reset the nonce-count */ + resp->client->nonce_count = 0; + } + + if (opaque[0]) { + opaque_param = apr_pstrcat(r->pool, ", opaque=\"", opaque, "\"", NULL); + } + else { + opaque_param = NULL; + } + + /* Setup nonce */ + + nonce = gen_nonce(r->pool, r->request_time, opaque, r->server, conf); + if (resp->client && conf->nonce_lifetime == 0) { + memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1); + } + + /* Setup MD5-sess stuff. Note that we just clear out the session + * info here, since we can't generate a new session until the request + * from the client comes in with the cnonce. + */ + + if (!strcasecmp(conf->algorithm, "MD5-sess")) { + clear_session(resp); + } + + /* setup domain attribute. We want to send this attribute wherever + * possible so that the client won't send the Authorization header + * unneccessarily (it's usually > 200 bytes!). + */ + + + /* don't send domain + * - for proxy requests + * - if it's no specified + */ + if (r->proxyreq || !conf->uri_list) { + domain = NULL; + } + else { + domain = conf->uri_list; + } + + apr_table_mergen(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) + ? "Proxy-Authenticate" : "WWW-Authenticate", + apr_psprintf(r->pool, "Digest realm=\"%s\", " + "nonce=\"%s\", algorithm=%s%s%s%s%s", + ap_auth_name(r), nonce, conf->algorithm, + opaque_param ? opaque_param : "", + domain ? domain : "", + stale ? ", stale=true" : "", qop)); + +} + + +/* + * Authorization header verification code + */ + +static authn_status get_hash(request_rec *r, const char *user, + digest_config_rec *conf) +{ + authn_status auth_result; + char *password; + authn_provider_list *current_provider; + + current_provider = conf->providers; + do { + const authn_provider *provider; + + /* For now, if a provider isn't set, we'll be nice and use the file + * provider. + */ + if (!current_provider) { + provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, + AUTHN_DEFAULT_PROVIDER, "0"); + + if (!provider || !provider->get_realm_hash) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "No Authn provider configured"); + auth_result = AUTH_GENERAL_ERROR; + break; + } + apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, AUTHN_DEFAULT_PROVIDER); + } + else { + provider = current_provider->provider; + apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, current_provider->provider_name); + } + + + /* We expect the password to be md5 hash of user:realm:password */ + auth_result = provider->get_realm_hash(r, user, conf->realm, + &password); + + apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE); + + /* Something occured. Stop checking. */ + if (auth_result != AUTH_USER_NOT_FOUND) { + break; + } + + /* If we're not really configured for providers, stop now. */ + if (!conf->providers) { + break; + } + + current_provider = current_provider->next; + } while (current_provider); + + if (auth_result == AUTH_USER_FOUND) { + conf->ha1 = password; + } + + return auth_result; +} + +static int check_nc(const request_rec *r, const digest_header_rec *resp, + const digest_config_rec *conf) +{ + unsigned long nc; + const char *snc = resp->nonce_count; + char *endptr; + + if (!conf->check_nc || !client_shm) { + return OK; + } + + nc = strtol(snc, &endptr, 16); + if (endptr < (snc+strlen(snc)) && !apr_isspace(*endptr)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid nc %s received - not a number", snc); + return !OK; + } + + if (!resp->client) { + return !OK; + } + + if (nc != resp->client->nonce_count) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: Warning, possible replay attack: nonce-count " + "check failed: %lu != %lu", nc, + resp->client->nonce_count); + return !OK; + } + + return OK; +} + +static int check_nonce(request_rec *r, digest_header_rec *resp, + const digest_config_rec *conf) +{ + apr_time_t dt; + int len; + time_rec nonce_time; + char tmp, hash[NONCE_HASH_LEN+1]; + + if (strlen(resp->nonce) != NONCE_LEN) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid nonce %s received - length is not %d", + resp->nonce, NONCE_LEN); + note_digest_auth_failure(r, conf, resp, 1); + return HTTP_UNAUTHORIZED; + } + + tmp = resp->nonce[NONCE_TIME_LEN]; + resp->nonce[NONCE_TIME_LEN] = '\0'; + len = apr_base64_decode_binary(nonce_time.arr, resp->nonce); + gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf); + resp->nonce[NONCE_TIME_LEN] = tmp; + resp->nonce_time = nonce_time.time; + + if (strcmp(hash, resp->nonce+NONCE_TIME_LEN)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid nonce %s received - hash is not %s", + resp->nonce, hash); + note_digest_auth_failure(r, conf, resp, 1); + return HTTP_UNAUTHORIZED; + } + + dt = r->request_time - nonce_time.time; + if (conf->nonce_lifetime > 0 && dt < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid nonce %s received - user attempted " + "time travel", resp->nonce); + note_digest_auth_failure(r, conf, resp, 1); + return HTTP_UNAUTHORIZED; + } + + if (conf->nonce_lifetime > 0) { + if (dt > conf->nonce_lifetime) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0,r, + "Digest: user %s: nonce expired (%.2f seconds old " + "- max lifetime %.2f) - sending new nonce", + r->user, (double)apr_time_sec(dt), + (double)apr_time_sec(conf->nonce_lifetime)); + note_digest_auth_failure(r, conf, resp, 1); + return HTTP_UNAUTHORIZED; + } + } + else if (conf->nonce_lifetime == 0 && resp->client) { + if (memcmp(resp->client->last_nonce, resp->nonce, NONCE_LEN)) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "Digest: user %s: one-time-nonce mismatch - sending " + "new nonce", r->user); + note_digest_auth_failure(r, conf, resp, 1); + return HTTP_UNAUTHORIZED; + } + } + /* else (lifetime < 0) => never expires */ + + return OK; +} + +/* The actual MD5 code... whee */ + +/* RFC-2069 */ +static const char *old_digest(const request_rec *r, + const digest_header_rec *resp, const char *ha1) +{ + const char *ha2; + + ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":", + resp->uri, NULL)); + return ap_md5(r->pool, + (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, + ":", ha2, NULL)); +} + +/* RFC-2617 */ +static const char *new_digest(const request_rec *r, + digest_header_rec *resp, + const digest_config_rec *conf) +{ + const char *ha1, *ha2, *a2; + + if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) { + ha1 = get_session_HA1(r, resp, conf, 1); + if (!ha1) { + return NULL; + } + } + else { + ha1 = conf->ha1; + } + + if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) { + a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, ":", + ap_md5(r->pool, (const unsigned char*) ""), NULL); + /* TBD */ + } + else { + a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); + } + ha2 = ap_md5(r->pool, (const unsigned char *)a2); + + return ap_md5(r->pool, + (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, + ":", resp->nonce_count, ":", + resp->cnonce, ":", + resp->message_qop, ":", ha2, + NULL)); +} + + +static void copy_uri_components(apr_uri_t *dst, + apr_uri_t *src, request_rec *r) { + if (src->scheme && src->scheme[0] != '\0') { + dst->scheme = src->scheme; + } + else { + dst->scheme = (char *) "http"; + } + + if (src->hostname && src->hostname[0] != '\0') { + dst->hostname = apr_pstrdup(r->pool, src->hostname); + ap_unescape_url(dst->hostname); + } + else { + dst->hostname = (char *) ap_get_server_name(r); + } + + if (src->port_str && src->port_str[0] != '\0') { + dst->port = src->port; + } + else { + dst->port = ap_get_server_port(r); + } + + if (src->path && src->path[0] != '\0') { + dst->path = apr_pstrdup(r->pool, src->path); + ap_unescape_url(dst->path); + } + else { + dst->path = src->path; + } + + if (src->query && src->query[0] != '\0') { + dst->query = apr_pstrdup(r->pool, src->query); + ap_unescape_url(dst->query); + } + else { + dst->query = src->query; + } +} + +/* These functions return 0 if client is OK, and proper error status + * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or + * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we + * couldn't figure out how to tell if the client is authorized or not. + * + * If they return DECLINED, and all other modules also decline, that's + * treated by the server core as a configuration error, logged and + * reported as such. + */ + +/* Determine user ID, and check if the attributes are correct, if it + * really is that user, if the nonce is correct, etc. + */ + +static int authenticate_digest_user(request_rec *r) +{ + digest_config_rec *conf; + digest_header_rec *resp; + request_rec *mainreq; + const char *t; + int res; + authn_status return_code; + + /* do we require Digest auth for this URI? */ + + if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest")) { + return DECLINED; + } + + if (!ap_auth_name(r)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: need AuthName: %s", r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + + + /* get the client response and mark */ + + mainreq = r; + while (mainreq->main != NULL) { + mainreq = mainreq->main; + } + while (mainreq->prev != NULL) { + mainreq = mainreq->prev; + } + resp = (digest_header_rec *) ap_get_module_config(mainreq->request_config, + &auth_digest_module); + resp->needed_auth = 1; + + + /* get our conf */ + + conf = (digest_config_rec *) ap_get_module_config(r->per_dir_config, + &auth_digest_module); + + + /* check for existence and syntax of Auth header */ + + if (resp->auth_hdr_sts != VALID) { + if (resp->auth_hdr_sts == NOT_DIGEST) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: client used wrong authentication scheme " + "`%s': %s", resp->scheme, r->uri); + } + else if (resp->auth_hdr_sts == INVALID) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: missing user, realm, nonce, uri, digest, " + "cnonce, or nonce_count in authorization header: %s", + r->uri); + } + /* else (resp->auth_hdr_sts == NO_HEADER) */ + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + r->user = (char *) resp->username; + r->ap_auth_type = (char *) "Digest"; + + /* check the auth attributes */ + + if (strcmp(resp->uri, resp->raw_request_uri)) { + /* Hmm, the simple match didn't work (probably a proxy modified the + * request-uri), so lets do a more sophisticated match + */ + apr_uri_t r_uri, d_uri; + + copy_uri_components(&r_uri, resp->psd_request_uri, r); + if (apr_uri_parse(r->pool, resp->uri, &d_uri) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid uri <%s> in Authorization header", + resp->uri); + return HTTP_BAD_REQUEST; + } + + if (d_uri.hostname) { + ap_unescape_url(d_uri.hostname); + } + if (d_uri.path) { + ap_unescape_url(d_uri.path); + } + + if (d_uri.query) { + ap_unescape_url(d_uri.query); + } + else if (r_uri.query) { + /* MSIE compatibility hack. MSIE has some RFC issues - doesn't + * include the query string in the uri Authorization component + * or when computing the response component. the second part + * works out ok, since we can hash the header and get the same + * result. however, the uri from the request line won't match + * the uri Authorization component since the header lacks the + * query string, leaving us incompatable with a (broken) MSIE. + * + * the workaround is to fake a query string match if in the proper + * environment - BrowserMatch MSIE, for example. the cool thing + * is that if MSIE ever fixes itself the simple match ought to + * work and this code won't be reached anyway, even if the + * environment is set. + */ + + if (apr_table_get(r->subprocess_env, + "AuthDigestEnableQueryStringHack")) { + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Digest: " + "applying AuthDigestEnableQueryStringHack " + "to uri <%s>", resp->raw_request_uri); + + d_uri.query = r_uri.query; + } + } + + if (r->method_number == M_CONNECT) { + if (strcmp(resp->uri, r_uri.hostinfo)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: uri mismatch - <%s> does not match " + "request-uri <%s>", resp->uri, r_uri.hostinfo); + return HTTP_BAD_REQUEST; + } + } + else if ( + /* check hostname matches, if present */ + (d_uri.hostname && d_uri.hostname[0] != '\0' + && strcasecmp(d_uri.hostname, r_uri.hostname)) + /* check port matches, if present */ + || (d_uri.port_str && d_uri.port != r_uri.port) + /* check that server-port is default port if no port present */ + || (d_uri.hostname && d_uri.hostname[0] != '\0' + && !d_uri.port_str && r_uri.port != ap_default_port(r)) + /* check that path matches */ + || (d_uri.path != r_uri.path + /* either exact match */ + && (!d_uri.path || !r_uri.path + || strcmp(d_uri.path, r_uri.path)) + /* or '*' matches empty path in scheme://host */ + && !(d_uri.path && !r_uri.path && resp->psd_request_uri->hostname + && d_uri.path[0] == '*' && d_uri.path[1] == '\0')) + /* check that query matches */ + || (d_uri.query != r_uri.query + && (!d_uri.query || !r_uri.query + || strcmp(d_uri.query, r_uri.query))) + ) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: uri mismatch - <%s> does not match " + "request-uri <%s>", resp->uri, resp->raw_request_uri); + return HTTP_BAD_REQUEST; + } + } + + if (resp->opaque && resp->opaque_num == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: received invalid opaque - got `%s'", + resp->opaque); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + if (strcmp(resp->realm, conf->realm)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: realm mismatch - got `%s' but expected `%s'", + resp->realm, conf->realm); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + if (resp->algorithm != NULL + && strcasecmp(resp->algorithm, "MD5") + && strcasecmp(resp->algorithm, "MD5-sess")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: unknown algorithm `%s' received: %s", + resp->algorithm, r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + return_code = get_hash(r, r->user, conf); + + if (return_code == AUTH_USER_NOT_FOUND) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: user `%s' in realm `%s' not found: %s", + r->user, conf->realm, r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + else if (return_code == AUTH_USER_FOUND) { + /* we have a password, so continue */ + } + else if (return_code == AUTH_DENIED) { + /* authentication denied in the provider before attempting a match */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: user `%s' in realm `%s' denied by provider: %s", + r->user, conf->realm, r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + else { + /* AUTH_GENERAL_ERROR (or worse) + * We'll assume that the module has already said what its error + * was in the logs. + */ + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (resp->message_qop == NULL) { + /* old (rfc-2069) style digest */ + if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: user %s: password mismatch: %s", r->user, + r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + } + else { + const char *exp_digest; + int match = 0, idx; + for (idx = 0; conf->qop_list[idx] != NULL; idx++) { + if (!strcasecmp(conf->qop_list[idx], resp->message_qop)) { + match = 1; + break; + } + } + + if (!match + && !(conf->qop_list[0] == NULL + && !strcasecmp(resp->message_qop, "auth"))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: invalid qop `%s' received: %s", + resp->message_qop, r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + exp_digest = new_digest(r, resp, conf); + if (!exp_digest) { + /* we failed to allocate a client struct */ + return HTTP_INTERNAL_SERVER_ERROR; + } + if (strcmp(resp->digest, exp_digest)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: user %s: password mismatch: %s", r->user, + r->uri); + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + } + + if (check_nc(r, resp, conf) != OK) { + note_digest_auth_failure(r, conf, resp, 0); + return HTTP_UNAUTHORIZED; + } + + /* Note: this check is done last so that a "stale=true" can be + generated if the nonce is old */ + if ((res = check_nonce(r, resp, conf))) { + return res; + } + + return OK; +} + +/* + * Authorization-Info header code + */ + +#ifdef SEND_DIGEST +static const char *hdr(const apr_table_t *tbl, const char *name) +{ + const char *val = apr_table_get(tbl, name); + if (val) { + return val; + } + else { + return ""; + } +} +#endif + +static int add_auth_info(request_rec *r) +{ + const digest_config_rec *conf = + (digest_config_rec *) ap_get_module_config(r->per_dir_config, + &auth_digest_module); + digest_header_rec *resp = + (digest_header_rec *) ap_get_module_config(r->request_config, + &auth_digest_module); + const char *ai = NULL, *digest = NULL, *nextnonce = ""; + + if (resp == NULL || !resp->needed_auth || conf == NULL) { + return OK; + } + + + /* rfc-2069 digest + */ + if (resp->message_qop == NULL) { + /* old client, so calc rfc-2069 digest */ + +#ifdef SEND_DIGEST + /* most of this totally bogus because the handlers don't set the + * headers until the final handler phase (I wonder why this phase + * is called fixup when there's almost nothing you can fix up...) + * + * Because it's basically impossible to get this right (e.g. the + * Content-length is never set yet when we get here, and we can't + * calc the entity hash) it's best to just leave this #def'd out. + */ + char date[APR_RFC822_DATE_LEN]; + apr_rfc822_date(date, r->request_time); + char *entity_info = + ap_md5(r->pool, + (unsigned char *) apr_pstrcat(r->pool, resp->raw_request_uri, + ":", + r->content_type ? r->content_type : ap_default_type(r), ":", + hdr(r->headers_out, "Content-Length"), ":", + r->content_encoding ? r->content_encoding : "", ":", + hdr(r->headers_out, "Last-Modified"), ":", + r->no_cache && !apr_table_get(r->headers_out, "Expires") ? + date : + hdr(r->headers_out, "Expires"), + NULL)); + digest = + ap_md5(r->pool, + (unsigned char *)apr_pstrcat(r->pool, conf->ha1, ":", + resp->nonce, ":", + r->method, ":", + date, ":", + entity_info, ":", + ap_md5(r->pool, (unsigned char *) ""), /* H(entity) - TBD */ + NULL)); +#endif + } + + + /* setup nextnonce + */ + if (conf->nonce_lifetime > 0) { + /* send nextnonce if current nonce will expire in less than 30 secs */ + if ((r->request_time - resp->nonce_time) > (conf->nonce_lifetime-NEXTNONCE_DELTA)) { + nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"", + gen_nonce(r->pool, r->request_time, + resp->opaque, r->server, conf), + "\"", NULL); + if (resp->client) + resp->client->nonce_count = 0; + } + } + else if (conf->nonce_lifetime == 0 && resp->client) { + const char *nonce = gen_nonce(r->pool, 0, resp->opaque, r->server, + conf); + nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"", nonce, "\"", NULL); + memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1); + } + /* else nonce never expires, hence no nextnonce */ + + + /* do rfc-2069 digest + */ + if (conf->qop_list[0] && !strcasecmp(conf->qop_list[0], "none") + && resp->message_qop == NULL) { + /* use only RFC-2069 format */ + if (digest) { + ai = apr_pstrcat(r->pool, "digest=\"", digest, "\"", nextnonce,NULL); + } + else { + ai = nextnonce; + } + } + else { + const char *resp_dig, *ha1, *a2, *ha2; + + /* calculate rspauth attribute + */ + if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) { + ha1 = get_session_HA1(r, resp, conf, 0); + if (!ha1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Digest: internal error: couldn't find session " + "info for user %s", resp->username); + return !OK; + } + } + else { + ha1 = conf->ha1; + } + + if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) { + a2 = apr_pstrcat(r->pool, ":", resp->uri, ":", + ap_md5(r->pool,(const unsigned char *) ""), NULL); + /* TBD */ + } + else { + a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); + } + ha2 = ap_md5(r->pool, (const unsigned char *)a2); + + resp_dig = ap_md5(r->pool, + (unsigned char *)apr_pstrcat(r->pool, ha1, ":", + resp->nonce, ":", + resp->nonce_count, ":", + resp->cnonce, ":", + resp->message_qop ? + resp->message_qop : "", + ":", ha2, NULL)); + + /* assemble Authentication-Info header + */ + ai = apr_pstrcat(r->pool, + "rspauth=\"", resp_dig, "\"", + nextnonce, + resp->cnonce ? ", cnonce=\"" : "", + resp->cnonce + ? ap_escape_quotes(r->pool, resp->cnonce) + : "", + resp->cnonce ? "\"" : "", + resp->nonce_count ? ", nc=" : "", + resp->nonce_count ? resp->nonce_count : "", + resp->message_qop ? ", qop=" : "", + resp->message_qop ? resp->message_qop : "", + digest ? "digest=\"" : "", + digest ? digest : "", + digest ? "\"" : "", + NULL); + } + + if (ai && ai[0]) { + apr_table_mergen(r->headers_out, + (PROXYREQ_PROXY == r->proxyreq) + ? "Proxy-Authentication-Info" + : "Authentication-Info", + ai); + } + + return OK; +} + + +static void register_hooks(apr_pool_t *p) +{ + static const char * const cfgPost[]={ "http_core.c", NULL }; + static const char * const parsePre[]={ "mod_proxy.c", NULL }; + + ap_hook_post_config(initialize_module, NULL, cfgPost, APR_HOOK_MIDDLE); + ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_read_request(parse_hdr_and_update_nc, parsePre, NULL, APR_HOOK_MIDDLE); + ap_hook_check_user_id(authenticate_digest_user, NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_fixups(add_auth_info, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA auth_digest_module = +{ + STANDARD20_MODULE_STUFF, + create_digest_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + digest_cmds, /* command table */ + register_hooks /* register hooks */ +}; + diff --git a/trunk/modules/aaa/mod_auth_digest.dsp b/trunk/modules/aaa/mod_auth_digest.dsp new file mode 100644 index 0000000000..60d887578a --- /dev/null +++ b/trunk/modules/aaa/mod_auth_digest.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_auth_digest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_auth_digest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_auth_digest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_auth_digest.mak" CFG="mod_auth_digest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_auth_digest - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_auth_digest - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_auth_digest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_auth_digest_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_auth_digest_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so + +!ENDIF + +# Begin Target + +# Name "mod_auth_digest - Win32 Release" +# Name "mod_auth_digest - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_auth_digest.c +# End Source File +# Begin Source File + +SOURCE=.\mod_auth_digest.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_auth_digest - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_auth_digest.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_auth_digest.so "auth_digest_module for Apache" ../../include/ap_release.h > .\mod_auth_digest.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_auth_digest.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_auth_digest.so "auth_digest_module for Apache" ../../include/ap_release.h > .\mod_auth_digest.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authn_alias.c b/trunk/modules/aaa/mod_authn_alias.c new file mode 100644 index 0000000000..83d067774f --- /dev/null +++ b/trunk/modules/aaa/mod_authn_alias.c @@ -0,0 +1,209 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#define APR_WANT_STRFUNC /* for strcasecmp */ +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" +#include "ap_provider.h" + +#include "mod_auth.h" + +typedef struct provider_alias_rec { + char *provider_name; + char *provider_alias; + ap_conf_vector_t *sec_auth; + const authn_provider *provider; +} provider_alias_rec; + +typedef struct authn_alias_srv_conf { + apr_hash_t *alias_rec; +} authn_alias_srv_conf; + +module AP_MODULE_DECLARE_DATA authn_alias_module; + +static authn_status authn_alias_check_password(request_rec *r, const char *user, + const char *password) +{ + /* Look up the provider alias in the alias list */ + /* Get the the dir_config and call ap_Merge_per_dir_configs() */ + /* Call the real provider->check_password() function */ + /* return the result of the above function call */ + + const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE); + authn_status ret = AUTH_USER_NOT_FOUND; + authn_alias_srv_conf *authcfg = + (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config, + &authn_alias_module); + + if (provider_name) { + provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec, + provider_name, APR_HASH_KEY_STRING); + ap_conf_vector_t *orig_dir_config = r->per_dir_config; + + /* If we found the alias provider in the list, then merge the directory + configurations and call the real provider */ + if (prvdraliasrec) { + r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config, + prvdraliasrec->sec_auth); + ret = prvdraliasrec->provider->check_password(r,user,password); + r->per_dir_config = orig_dir_config; + } + } + + return ret; +} + +static authn_status authn_alias_get_realm_hash(request_rec *r, const char *user, + const char *realm, char **rethash) +{ + /* Look up the provider alias in the alias list */ + /* Get the the dir_config and call ap_Merge_per_dir_configs() */ + /* Call the real provider->get_realm_hash() function */ + /* return the result of the above function call */ + + const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE); + authn_status ret = AUTH_USER_NOT_FOUND; + authn_alias_srv_conf *authcfg = + (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config, + &authn_alias_module); + + if (provider_name) { + provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec, + provider_name, APR_HASH_KEY_STRING); + ap_conf_vector_t *orig_dir_config = r->per_dir_config; + + /* If we found the alias provider in the list, then merge the directory + configurations and call the real provider */ + if (prvdraliasrec) { + r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config, + prvdraliasrec->sec_auth); + ret = prvdraliasrec->provider->get_realm_hash(r,user,realm,rethash); + r->per_dir_config = orig_dir_config; + } + } + + return ret; +} + +static void *create_authn_alias_svr_config(apr_pool_t *p, server_rec *s) +{ + + authn_alias_srv_conf *authcfg; + + authcfg = (authn_alias_srv_conf *) apr_pcalloc(p, sizeof(authn_alias_srv_conf)); + authcfg->alias_rec = apr_hash_make(p); + + return (void *) authcfg; +} + +static const authn_provider authn_alias_provider = +{ + &authn_alias_check_password, + &authn_alias_get_realm_hash, +}; + +static const char *authaliassection(cmd_parms *cmd, void *mconfig, const char *arg) +{ + int old_overrides = cmd->override; + const char *endp = ap_strrchr_c(arg, '>'); + const char *args; + char *provider_alias; + char *provider_name; + const char *errmsg; + ap_conf_vector_t *new_auth_config = ap_create_per_dir_config(cmd->pool); + authn_alias_srv_conf *authcfg = + (authn_alias_srv_conf *)ap_get_module_config(cmd->server->module_config, + &authn_alias_module); + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive missing closing '>'", NULL); + } + + args = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!args[0]) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive requires additional arguments", NULL); + } + + /* Pull the real provider name and the alias name from the block header */ + provider_name = ap_getword_conf(cmd->pool, &args); + provider_alias = ap_getword_conf(cmd->pool, &args); + + if (!provider_name[0] || !provider_alias[0]) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive requires additional arguments", NULL); + } + + /* walk the subsection configuration to get the per_dir config that we will + merge just before the real provider is called. */ + cmd->override = OR_ALL|ACCESS_CONF; + errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_auth_config); + + if (!errmsg) { + provider_alias_rec *prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(provider_alias_rec)); + const authn_provider *provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_name,"0"); + + /* Save off the new directory config along with the original provider name + and function pointer data */ + prvdraliasrec->sec_auth = new_auth_config; + prvdraliasrec->provider_name = provider_name; + prvdraliasrec->provider_alias = provider_alias; + prvdraliasrec->provider = provider; + apr_hash_set(authcfg->alias_rec, provider_alias, APR_HASH_KEY_STRING, prvdraliasrec); + + /* Register the fake provider so that we get called first */ + ap_register_provider(cmd->pool, AUTHN_PROVIDER_GROUP, provider_alias, "0", + &authn_alias_provider); + } + + cmd->override = old_overrides; + + return errmsg; +} + +static const command_rec authn_alias_cmds[] = +{ + AP_INIT_RAW_ARGS(" setup: + * + * Anonymous magic-userid [magic-userid]... + * + * Anonymous_MustGiveEmail [ on | off ] default = on + * Anonymous_LogEmail [ on | off ] default = on + * Anonymous_VerifyEmail [ on | off ] default = off + * Anonymous_NoUserId [ on | off ] default = off + * + * The magic user id is something like 'anonymous', it is NOT case sensitive. + * + * The MustGiveEmail flag can be used to force users to enter something + * in the password field (like an email address). Default is on. + * + * Furthermore the 'NoUserID' flag can be set to allow completely empty + * usernames in as well; this can be is convenient as a single return + * in broken GUIs like W95 is often given by the user. The Default is off. + * + * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx + * + */ + +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_provider.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" + +#include "mod_auth.h" + +typedef struct anon_auth_user { + char *user; + struct anon_auth_user *next; +} anon_auth_user; + +typedef struct { + anon_auth_user *users; + int nouserid; + int logemail; + int verifyemail; + int mustemail; + int anyuserid; +} authn_anon_config_rec; + +static void *create_authn_anon_dir_config(apr_pool_t *p, char *d) +{ + authn_anon_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + /* just to illustrate the defaults really. */ + conf->users = NULL; + + conf->nouserid = 0; + conf->anyuserid = 0; + conf->logemail = 1; + conf->verifyemail = 0; + conf->mustemail = 1; + return conf; +} + +static const char *anon_set_string_slots(cmd_parms *cmd, + void *my_config, const char *arg) +{ + authn_anon_config_rec *conf = my_config; + anon_auth_user *first; + + if (!*arg) { + return "Anonymous string cannot be empty, use Anonymous_NoUserId"; + } + + /* squeeze in a record */ + if (!conf->anyuserid) { + if (!strcmp(arg, "*")) { + conf->anyuserid = 1; + } + else { + first = conf->users; + conf->users = apr_palloc(cmd->pool, sizeof(*conf->users)); + conf->users->user = apr_pstrdup(cmd->pool, arg); + conf->users->next = first; + } + } + + return NULL; +} + +static const command_rec authn_anon_cmds[] = +{ + AP_INIT_ITERATE("Anonymous", anon_set_string_slots, NULL, OR_AUTHCFG, + "a space-separated list of user IDs"), + AP_INIT_FLAG("Anonymous_MustGiveEmail", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_anon_config_rec, mustemail), + OR_AUTHCFG, "Limited to 'on' or 'off'"), + AP_INIT_FLAG("Anonymous_NoUserId", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_anon_config_rec, nouserid), + OR_AUTHCFG, "Limited to 'on' or 'off'"), + AP_INIT_FLAG("Anonymous_VerifyEmail", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_anon_config_rec, verifyemail), + OR_AUTHCFG, "Limited to 'on' or 'off'"), + AP_INIT_FLAG("Anonymous_LogEmail", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_anon_config_rec, logemail), + OR_AUTHCFG, "Limited to 'on' or 'off'"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authn_anon_module; + +static authn_status check_anonymous(request_rec *r, const char *user, + const char *sent_pw) +{ + authn_anon_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_anon_module); + authn_status res = AUTH_USER_NOT_FOUND; + + /* Ignore if we are not configured */ + if (!conf->users && !conf->anyuserid) { + return AUTH_USER_NOT_FOUND; + } + + /* Do we allow an empty userID and/or is it the magic one + */ + if (!*user) { + if (conf->nouserid) { + res = AUTH_USER_FOUND; + } + } + else if (conf->anyuserid) { + res = AUTH_USER_FOUND; + } + else { + anon_auth_user *p = conf->users; + + while (p) { + if (!strcasecmp(user, p->user)) { + res = AUTH_USER_FOUND; + break; + } + p = p->next; + } + } + + /* Now if the supplied user-ID was ok, grant access if: + * (a) no passwd was sent and no password and no verification + * were configured. + * (b) password was sent and no verification was configured + * (c) verification was configured and the password (sent or not) + * looks like an email address + */ + if ( (res == AUTH_USER_FOUND) + && (!conf->mustemail || *sent_pw) + && ( !conf->verifyemail + || (ap_strchr_c(sent_pw, '@') && ap_strchr_c(sent_pw, '.')))) + { + if (conf->logemail && ap_is_initial_req(r)) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r, + "Anonymous: Passwd <%s> Accepted", + sent_pw ? sent_pw : "\'none\'"); + } + + return AUTH_GRANTED; + } + + return (res == AUTH_USER_NOT_FOUND ? res : AUTH_DENIED); +} + +static const authn_provider authn_anon_provider = +{ + &check_anonymous, + NULL +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AUTHN_PROVIDER_GROUP, "anon", "0", + &authn_anon_provider); +} + +module AP_MODULE_DECLARE_DATA authn_anon_module = +{ + STANDARD20_MODULE_STUFF, + create_authn_anon_dir_config, /* dir config creater */ + NULL, /* dir merger ensure strictness */ + NULL, /* server config */ + NULL, /* merge server config */ + authn_anon_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authn_anon.dsp b/trunk/modules/aaa/mod_authn_anon.dsp new file mode 100644 index 0000000000..a5546bfa54 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_anon.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authn_anon" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authn_anon - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_anon.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_anon.mak" CFG="mod_authn_anon - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authn_anon - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authn_anon - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authn_anon - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_anon_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_anon_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so + +!ENDIF + +# Begin Target + +# Name "mod_authn_anon - Win32 Release" +# Name "mod_authn_anon - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authn_anon.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authn_anon.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authn_anon - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_anon.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_anon.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_anon.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_anon.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_anon.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_anon.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authn_dbm.c b/trunk/modules/aaa/mod_authn_dbm.c new file mode 100644 index 0000000000..2f66203212 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_dbm.c @@ -0,0 +1,205 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_auth: authentication + * + * Rob McCool & Brian Behlendorf. + * + * Adapted to Apache by rst. + * + */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_strings.h" +#include "apr_dbm.h" +#include "apr_md5.h" /* for apr_password_validate */ + +#include "ap_provider.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/ + +#include "mod_auth.h" + +typedef struct { + char *pwfile; + char *dbmtype; +} authn_dbm_config_rec; + +static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d) +{ + authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->pwfile = NULL; + conf->dbmtype = "default"; + + return conf; +} + +static const char *set_dbm_type(cmd_parms *cmd, + void *dir_config, + const char *arg) +{ + authn_dbm_config_rec *conf = dir_config; + + conf->dbmtype = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +static const command_rec authn_dbm_cmds[] = +{ + AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot, + (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile), + OR_AUTHCFG, "dbm database file containing user IDs and passwords"), + AP_INIT_TAKE1("AuthDBMType", set_dbm_type, + NULL, + OR_AUTHCFG, "what type of DBM file the user file is"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authn_dbm_module; + +static apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile, + const char *user, char **value, + apr_pool_t *pool) +{ + apr_dbm_t *f; + apr_datum_t key, val; + apr_status_t rv; + + rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY, + APR_OS_DEFAULT, pool); + + if (rv != APR_SUCCESS) { + return rv; + } + + key.dptr = (char*)user; +#ifndef NETSCAPE_DBM_COMPAT + key.dsize = strlen(key.dptr); +#else + key.dsize = strlen(key.dptr) + 1; +#endif + + *value = NULL; + + if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) { + *value = apr_pstrmemdup(pool, val.dptr, val.dsize); + } + + apr_dbm_close(f); + + return rv; +} + +static authn_status check_dbm_pw(request_rec *r, const char *user, + const char *password) +{ + authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_dbm_module); + apr_status_t rv; + char *dbm_password; + char *colon_pw; + + rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password, + r->pool); + + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "could not open dbm (type %s) auth file: %s", + conf->dbmtype, conf->pwfile); + return AUTH_GENERAL_ERROR; + } + + if (!dbm_password) { + return AUTH_USER_NOT_FOUND; + } + + colon_pw = ap_strchr(dbm_password, ':'); + if (colon_pw) { + *colon_pw = '\0'; + } + + rv = apr_password_validate(password, dbm_password); + + if (rv != APR_SUCCESS) { + return AUTH_DENIED; + } + + return AUTH_GRANTED; +} + +static authn_status get_dbm_realm_hash(request_rec *r, const char *user, + const char *realm, char **rethash) +{ + authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_dbm_module); + apr_status_t rv; + char *dbm_hash; + char *colon_hash; + + rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, + apr_pstrcat(r->pool, user, ":", realm, NULL), + &dbm_hash, r->pool); + + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Could not open dbm (type %s) hash file: %s", + conf->dbmtype, conf->pwfile); + return AUTH_GENERAL_ERROR; + } + + if (!dbm_hash) { + return AUTH_USER_NOT_FOUND; + } + + colon_hash = ap_strchr(dbm_hash, ':'); + if (colon_hash) { + *colon_hash = '\0'; + } + + *rethash = dbm_hash; + + return AUTH_USER_FOUND; +} + +static const authn_provider authn_dbm_provider = +{ + &check_dbm_pw, + &get_dbm_realm_hash +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AUTHN_PROVIDER_GROUP, "dbm", "0", + &authn_dbm_provider); +} + +module AP_MODULE_DECLARE_DATA authn_dbm_module = +{ + STANDARD20_MODULE_STUFF, + create_authn_dbm_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authn_dbm_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authn_dbm.dsp b/trunk/modules/aaa/mod_authn_dbm.dsp new file mode 100644 index 0000000000..47f01a1a21 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_dbm.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authn_dbm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authn_dbm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_dbm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_dbm.mak" CFG="mod_authn_dbm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authn_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authn_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authn_dbm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_dbm_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_dbm_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so + +!ENDIF + +# Begin Target + +# Name "mod_authn_dbm - Win32 Release" +# Name "mod_authn_dbm - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authn_dbm.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authn_dbm.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authn_dbm - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_dbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_dbm.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_dbm.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_dbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_dbm.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_dbm.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authn_default.c b/trunk/modules/aaa/mod_authn_default.c new file mode 100644 index 0000000000..babeebd3e6 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_default.c @@ -0,0 +1,103 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +typedef struct { + int authoritative; +} authn_default_config_rec; + +static void *create_authn_default_dir_config(apr_pool_t *p, char *d) +{ + authn_default_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->authoritative = 1; /* keep the fortress secure by default */ + return conf; +} + +static const command_rec authn_default_cmds[] = +{ + AP_INIT_FLAG("AuthDefaultAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_default_config_rec, + authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules if the UserID is not known to this module. " + "(default is On)."), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authn_default_module; + +static int authenticate_no_user(request_rec *r) +{ + authn_default_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_default_module); + + const char *type; + + if (!(type = ap_auth_type(r))) { + return DECLINED; + } + + /* fill in the r->user field */ + if (!strcasecmp(type, "Basic")) { + const char *sent_pw; + int res; + + if ((res = ap_get_basic_auth_pw(r, &sent_pw)) != OK) { + return res; + } + } + + if (conf->authoritative == 0) { + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: verification of user id '%s' " + "not configured", + r->uri, r->user ? r->user : ""); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_check_user_id(authenticate_no_user,NULL,NULL,APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA authn_default_module = +{ + STANDARD20_MODULE_STUFF, + create_authn_default_dir_config,/* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authn_default_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authn_default.dsp b/trunk/modules/aaa/mod_authn_default.dsp new file mode 100644 index 0000000000..db3fb60617 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_default.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authn_default" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authn_default - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_default.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_default.mak" CFG="mod_authn_default - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authn_default - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authn_default - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authn_default - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_default_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authn_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_default.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authn_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_default.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authn_default - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_default_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_default.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_default.so + +!ENDIF + +# Begin Target + +# Name "mod_authn_default - Win32 Release" +# Name "mod_authn_default - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authn_default.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authn_default.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authn_default - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_default.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_default.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_default.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authn_default - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_default.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_default.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_default.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authn_file.c b/trunk/modules/aaa/mod_authn_file.c new file mode 100644 index 0000000000..726ed46494 --- /dev/null +++ b/trunk/modules/aaa/mod_authn_file.c @@ -0,0 +1,179 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_md5.h" /* for apr_password_validate */ + +#include "ap_config.h" +#include "ap_provider.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +#include "mod_auth.h" + +typedef struct { + char *pwfile; +} authn_file_config_rec; + +static void *create_authn_file_dir_config(apr_pool_t *p, char *d) +{ + authn_file_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->pwfile = NULL; /* just to illustrate the default really */ + return conf; +} + +static const char *set_authn_file_slot(cmd_parms *cmd, void *offset, + const char *f, const char *t) +{ + if (t && strcmp(t, "standard")) { + return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL); + } + + return ap_set_file_slot(cmd, offset, f); +} + +static const command_rec authn_file_cmds[] = +{ + AP_INIT_TAKE12("AuthUserFile", set_authn_file_slot, + (void *)APR_OFFSETOF(authn_file_config_rec, pwfile), + OR_AUTHCFG, "text file containing user IDs and passwords"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authn_file_module; + +static authn_status check_password(request_rec *r, const char *user, + const char *password) +{ + authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_file_module); + ap_configfile_t *f; + char l[MAX_STRING_LEN]; + apr_status_t status; + char *file_password = NULL; + + status = ap_pcfg_openfile(&f, r->pool, conf->pwfile); + + if (status != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "Could not open password file: %s", conf->pwfile); + return AUTH_GENERAL_ERROR; + } + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) { + const char *rpw, *w; + + /* Skip # or blank lines. */ + if ((l[0] == '#') || (!l[0])) { + continue; + } + + rpw = l; + w = ap_getword(r->pool, &rpw, ':'); + + if (!strcmp(user, w)) { + file_password = ap_getword(r->pool, &rpw, ':'); + break; + } + } + ap_cfg_closefile(f); + + if (!file_password) { + return AUTH_USER_NOT_FOUND; + } + + status = apr_password_validate(password, file_password); + if (status != APR_SUCCESS) { + return AUTH_DENIED; + } + + return AUTH_GRANTED; +} + +static authn_status get_realm_hash(request_rec *r, const char *user, + const char *realm, char **rethash) +{ + authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authn_file_module); + ap_configfile_t *f; + char l[MAX_STRING_LEN]; + apr_status_t status; + char *file_hash = NULL; + + status = ap_pcfg_openfile(&f, r->pool, conf->pwfile); + + if (status != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "Could not open password file: %s", conf->pwfile); + return AUTH_GENERAL_ERROR; + } + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) { + const char *rpw, *w, *x; + + /* Skip # or blank lines. */ + if ((l[0] == '#') || (!l[0])) { + continue; + } + + rpw = l; + w = ap_getword(r->pool, &rpw, ':'); + x = ap_getword(r->pool, &rpw, ':'); + + if (x && w && !strcmp(user, w) && !strcmp(realm, x)) { + /* Remember that this is a md5 hash of user:realm:password. */ + file_hash = ap_getword(r->pool, &rpw, ':'); + break; + } + } + ap_cfg_closefile(f); + + if (!file_hash) { + return AUTH_USER_NOT_FOUND; + } + + *rethash = file_hash; + + return AUTH_USER_FOUND; +} + +static const authn_provider authn_file_provider = +{ + &check_password, + &get_realm_hash, +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, AUTHN_PROVIDER_GROUP, "file", "0", + &authn_file_provider); +} + +module AP_MODULE_DECLARE_DATA authn_file_module = +{ + STANDARD20_MODULE_STUFF, + create_authn_file_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authn_file_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authn_file.dsp b/trunk/modules/aaa/mod_authn_file.dsp new file mode 100644 index 0000000000..0a5c13146e --- /dev/null +++ b/trunk/modules/aaa/mod_authn_file.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authn_file" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authn_file - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_file.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authn_file.mak" CFG="mod_authn_file - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authn_file - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authn_file - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authn_file - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_file_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_file_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so + +!ENDIF + +# Begin Target + +# Name "mod_authn_file - Win32 Release" +# Name "mod_authn_file - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authn_file.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authn_file.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authn_file - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_file.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_file.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_file.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authn_file.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authn_file.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authn_file.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authnz_ldap.c b/trunk/modules/aaa/mod_authnz_ldap.c new file mode 100644 index 0000000000..a26e33712c --- /dev/null +++ b/trunk/modules/aaa/mod_authnz_ldap.c @@ -0,0 +1,1179 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_provider.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" +#include "util_ldap.h" + +#include "mod_auth.h" + +#include "apr_strings.h" +#include "apr_xlate.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +/* for getpid() */ +#include +#endif +#include + +#if !APR_HAS_LDAP +#error mod_authnz_ldap requires APR-util to have LDAP support built in. To fix add --with-ldap to ./configure. +#endif + +typedef struct { + apr_pool_t *pool; /* Pool that this config is allocated from */ +#if APR_HAS_THREADS + apr_thread_mutex_t *lock; /* Lock for this config */ +#endif + int auth_authoritative; /* Is this auth method the one and only? */ +/* int authz_enabled; Is ldap authorization enabled in this directory? */ + + + /* These parameters are all derived from the AuthLDAPURL directive */ + char *url; /* String representation of the URL */ + + char *host; /* Name of the LDAP server (or space separated list) */ + int port; /* Port of the LDAP server */ + char *basedn; /* Base DN to do all searches from */ + char *attribute; /* Attribute to search for */ + char **attributes; /* Array of all the attributes to return */ + int scope; /* Scope of the search */ + char *filter; /* Filter to further limit the search */ + deref_options deref; /* how to handle alias dereferening */ + char *binddn; /* DN to bind to server (can be NULL) */ + char *bindpw; /* Password to bind to server (can be NULL) */ + + int user_is_dn; /* If true, connection->user is DN instead of userid */ + int compare_dn_on_server; /* If true, will use server to do DN compare */ + + int have_ldap_url; /* Set if we have found an LDAP url */ + + apr_array_header_t *groupattr; /* List of Group attributes */ + int group_attrib_is_dn; /* If true, the group attribute is the DN, otherwise, + it's the exact string passed by the HTTP client */ + + int secure; /* True if SSL connections are requested */ +} authn_ldap_config_t; + +typedef struct { + char *dn; /* The saved dn from a successful search */ + char *user; /* The username provided by the client */ +} authn_ldap_request_t; + +/* maximum group elements supported */ +#define GROUPATTR_MAX_ELTS 10 + +struct mod_auth_ldap_groupattr_entry_t { + char *name; +}; + +module AP_MODULE_DECLARE_DATA authnz_ldap_module; + +static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close; +static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find; +static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn; +static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare; +static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid; +static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn; +static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported; + +static apr_hash_t *charset_conversions = NULL; +static char *to_charset = NULL; /* UTF-8 identifier derived from the charset.conv file */ + + +/* Derive a code page ID give a language name or ID */ +static char* derive_codepage_from_lang (apr_pool_t *p, char *language) +{ + int lang_len; + char *charset; + + if (!language) /* our default codepage */ + return apr_pstrdup(p, "ISO-8859-1"); + else + lang_len = strlen(language); + + charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING); + + if (!charset) { + language[2] = '\0'; + charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING); + } + + if (charset) { + charset = apr_pstrdup(p, charset); + } + + return charset; +} + +static apr_xlate_t* get_conv_set (request_rec *r) +{ + char *lang_line = (char*)apr_table_get(r->headers_in, "accept-language"); + char *lang; + apr_xlate_t *convset; + + if (lang_line) { + lang_line = apr_pstrdup(r->pool, lang_line); + for (lang = lang_line;*lang;lang++) { + if ((*lang == ',') || (*lang == ';')) { + *lang = '\0'; + break; + } + } + lang = derive_codepage_from_lang(r->pool, lang_line); + + if (lang && (apr_xlate_open(&convset, to_charset, lang, r->pool) == APR_SUCCESS)) { + return convset; + } + } + + return NULL; +} + + +/* + * Build the search filter, or at least as much of the search filter that + * will fit in the buffer. We don't worry about the buffer not being able + * to hold the entire filter. If the buffer wasn't big enough to hold the + * filter, ldap_search_s will complain, but the only situation where this + * is likely to happen is if the client sent a really, really long + * username, most likely as part of an attack. + * + * The search filter consists of the filter provided with the URL, + * combined with a filter made up of the attribute provided with the URL, + * and the actual username passed by the HTTP client. For example, assume + * that the LDAP URL is + * + * ldap://ldap.airius.com/ou=People, o=Airius?uid??(posixid=*) + * + * Further, assume that the userid passed by the client was `userj'. The + * search filter will be (&(posixid=*)(uid=userj)). + */ +#define FILTER_LENGTH MAX_STRING_LEN +static void authn_ldap_build_filter(char *filtbuf, + request_rec *r, + const char* sent_user, + const char* sent_filter, + authn_ldap_config_t *sec) +{ + char *p, *q, *filtbuf_end; + char *user, *filter; + apr_xlate_t *convset = NULL; + apr_size_t inbytes; + apr_size_t outbytes; + char *outbuf; + + if (sent_user != NULL) { + user = apr_pstrdup (r->pool, sent_user); + } + else + return; + + if (sent_filter != NULL) { + filter = apr_pstrdup (r->pool, sent_filter); + } + else + filter = sec->filter; + + if (charset_conversions) { + convset = get_conv_set(r); + } + + if (convset) { + inbytes = strlen(user); + outbytes = (inbytes+1)*3; + outbuf = apr_pcalloc(r->pool, outbytes); + + /* Convert the user name to UTF-8. This is only valid for LDAP v3 */ + if (apr_xlate_conv_buffer(convset, user, &inbytes, outbuf, &outbytes) == APR_SUCCESS) { + user = apr_pstrdup(r->pool, outbuf); + } + } + + /* + * Create the first part of the filter, which consists of the + * config-supplied portions. + */ + apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", filter, sec->attribute); + + /* + * Now add the client-supplied username to the filter, ensuring that any + * LDAP filter metachars are escaped. + */ + filtbuf_end = filtbuf + FILTER_LENGTH - 1; +#if APR_HAS_MICROSOFT_LDAPSDK + for (p = user, q=filtbuf + strlen(filtbuf); + *p && q < filtbuf_end; ) { + if (strchr("*()\\", *p) != NULL) { + if ( q + 3 >= filtbuf_end) + break; /* Don't write part of escape sequence if we can't write all of it */ + *q++ = '\\'; + switch ( *p++ ) + { + case '*': + *q++ = '2'; + *q++ = 'a'; + break; + case '(': + *q++ = '2'; + *q++ = '8'; + break; + case ')': + *q++ = '2'; + *q++ = '9'; + break; + case '\\': + *q++ = '5'; + *q++ = 'c'; + break; + } + } + else + *q++ = *p++; + } +#else + for (p = user, q=filtbuf + strlen(filtbuf); + *p && q < filtbuf_end; *q++ = *p++) { + if (strchr("*()\\", *p) != NULL) { + *q++ = '\\'; + if (q >= filtbuf_end) { + break; + } + } + } +#endif + *q = '\0'; + + /* + * Append the closing parens of the filter, unless doing so would + * overrun the buffer. + */ + if (q + 2 <= filtbuf_end) + strcat(filtbuf, "))"); +} + +static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d) +{ + authn_ldap_config_t *sec = + (authn_ldap_config_t *)apr_pcalloc(p, sizeof(authn_ldap_config_t)); + + sec->pool = p; +#if APR_HAS_THREADS + apr_thread_mutex_create(&sec->lock, APR_THREAD_MUTEX_DEFAULT, p); +#endif +/* + sec->authz_enabled = 1; +*/ + sec->groupattr = apr_array_make(p, GROUPATTR_MAX_ELTS, + sizeof(struct mod_auth_ldap_groupattr_entry_t)); + + sec->have_ldap_url = 0; + sec->url = ""; + sec->host = NULL; + sec->binddn = NULL; + sec->bindpw = NULL; + sec->deref = always; + sec->group_attrib_is_dn = 1; + sec->auth_authoritative = 1; + +/* + sec->frontpage_hack = 0; +*/ + + sec->secure = -1; /*Initialize to unset*/ + + sec->user_is_dn = 0; + sec->compare_dn_on_server = 0; + + return sec; +} + +static apr_status_t authnz_ldap_cleanup_connection_close(void *param) +{ + util_ldap_connection_t *ldc = param; + util_ldap_connection_close(ldc); + return APR_SUCCESS; +} + + +/* + * Authentication Phase + * -------------------- + * + * This phase authenticates the credentials the user has sent with + * the request (ie the username and password are checked). This is done + * by making an attempt to bind to the LDAP server using this user's + * DN and the supplied password. + * + */ +static authn_status authn_ldap_check_password(request_rec *r, const char *user, + const char *password) +{ + int failures = 0; + const char **vals = NULL; + char filtbuf[FILTER_LENGTH]; + authn_ldap_config_t *sec = + (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module); + + util_ldap_connection_t *ldc = NULL; + int result = 0; + const char *dn = NULL; + + authn_ldap_request_t *req = + (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t)); + ap_set_module_config(r->request_config, &authnz_ldap_module, req); + +/* + if (!sec->enabled) { + return AUTH_USER_NOT_FOUND; + } +*/ + + /* + * Basic sanity checks before any LDAP operations even happen. + */ + if (!sec->have_ldap_url) { + return AUTH_GENERAL_ERROR; + } + +start_over: + + /* There is a good AuthLDAPURL, right? */ + if (sec->host) { + ldc = util_ldap_connection_find(r, sec->host, sec->port, + sec->binddn, sec->bindpw, sec->deref, + sec->secure); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: no sec->host - weird...?", getpid()); + return AUTH_GENERAL_ERROR; + } + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: using URL %s", getpid(), sec->url); + + /* Get the password that the client sent */ + if (password == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: no password specified", getpid()); + util_ldap_connection_close(ldc); + return AUTH_GENERAL_ERROR; + } + + if (user == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: no user specified", getpid()); + util_ldap_connection_close(ldc); + return AUTH_GENERAL_ERROR; + } + + /* build the username filter */ + authn_ldap_build_filter(filtbuf, r, user, NULL, sec); + + /* do the user search */ + result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope, + sec->attributes, filtbuf, password, &dn, &vals); + util_ldap_connection_close(ldc); + + /* sanity check - if server is down, retry it up to 5 times */ + if (result == LDAP_SERVER_DOWN) { + if (failures++ <= 5) { + goto start_over; + } + } + + /* handle bind failure */ + if (result != LDAP_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: " + "user %s authentication failed; URI %s [%s][%s]", + getpid(), user, r->uri, ldc->reason, ldap_err2string(result)); + + return (LDAP_NO_SUCH_OBJECT == result) ? AUTH_USER_NOT_FOUND +#ifdef LDAP_SECURITY_ERROR + : (LDAP_SECURITY_ERROR(result)) ? AUTH_DENIED +#endif + : AUTH_GENERAL_ERROR; + } + + /* mark the user and DN */ + req->dn = apr_pstrdup(r->pool, dn); + req->user = apr_pstrdup(r->pool, user); + if (sec->user_is_dn) { + r->user = req->dn; + } + + /* add environment variables */ + if (sec->attributes && vals) { + apr_table_t *e = r->subprocess_env; + int i = 0; + while (sec->attributes[i]) { + char *str = apr_pstrcat(r->pool, "AUTHENTICATE_", sec->attributes[i], NULL); + int j = 13; + while (str[j]) { + if (str[j] >= 'a' && str[j] <= 'z') { + str[j] = str[j] - ('a' - 'A'); + } + j++; + } + apr_table_setn(e, str, vals[i]); + i++; + } + } + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authenticate: accepting %s", getpid(), user); + + return AUTH_GRANTED; +} + +/* + * Authorisation Phase + * ------------------- + * + * After checking whether the username and password are correct, we need + * to check whether that user is authorised to view this resource. The + * require directive is used to do this: + * + * require valid-user Any authenticated is allowed in. + * require user This particular user is allowed in. + * require group The user must be a member of this group + * in order to be allowed in. + * require dn The user must have the following DN in the + * LDAP tree to be let in. + * + */ +static int authz_ldap_check_user_access(request_rec *r) +{ + int result = 0; + authn_ldap_request_t *req = + (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module); + authn_ldap_config_t *sec = + (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module); + + util_ldap_connection_t *ldc = NULL; + int m = r->method_number; + + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL; + + register int x; + const char *t; + char *w, *value; + int method_restricted = 0; + + char filtbuf[FILTER_LENGTH]; + const char *dn = NULL; + const char **vals = NULL; + const char *type = ap_auth_type(r); + +/* + if (!sec->enabled) { + return DECLINED; + } +*/ + + if (!sec->have_ldap_url) { + return DECLINED; + } + + if (sec->host) { + ldc = util_ldap_connection_find(r, sec->host, sec->port, + sec->binddn, sec->bindpw, sec->deref, + sec->secure); + apr_pool_cleanup_register(r->pool, ldc, + authnz_ldap_cleanup_connection_close, + apr_pool_cleanup_null); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: no sec->host - weird...?", getpid()); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + + /* + * If there are no elements in the group attribute array, the default should be + * member and uniquemember; populate the array now. + */ + if (sec->groupattr->nelts == 0) { + struct mod_auth_ldap_groupattr_entry_t *grp; +#if APR_HAS_THREADS + apr_thread_mutex_lock(sec->lock); +#endif + grp = apr_array_push(sec->groupattr); + grp->name = "member"; + grp = apr_array_push(sec->groupattr); + grp->name = "uniquemember"; +#if APR_HAS_THREADS + apr_thread_mutex_unlock(sec->lock); +#endif + } + + if (!reqs_arr) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: no requirements array", getpid()); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + + /* + * If we have been authenticated by some other module than mod_auth_ldap, + * the req structure needed for authorization needs to be created + * and populated with the userid and DN of the account in LDAP + */ + + /* Check that we have a userid to start with */ + if ((!r->user) || (strlen(r->user) == 0)) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, + "ldap authorize: Userid is blank, AuthType=%s", + r->ap_auth_type); + } + + if(!req) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "ldap authorize: Creating LDAP req structure"); + + /* Build the username filter */ + authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec); + + /* Search for the user DN */ + result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn, + sec->scope, sec->attributes, filtbuf, &dn, &vals); + + /* Search failed, log error and return failure */ + if(result != LDAP_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "auth_ldap authorise: User DN not found, %s", ldc->reason); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + + req = (authn_ldap_request_t *)apr_pcalloc(r->pool, + sizeof(authn_ldap_request_t)); + ap_set_module_config(r->request_config, &authnz_ldap_module, req); + req->dn = apr_pstrdup(r->pool, dn); + req->user = r->user; + } + + /* Loop through the requirements array until there's no elements + * left, or something causes a return from inside the loop */ + for(x=0; x < reqs_arr->nelts; x++) { + if (! (reqs[x].method_mask & (1 << m))) { + continue; + } + method_restricted = 1; + + t = reqs[x].requirement; + w = ap_getword_white(r->pool, &t); + + if (strcmp(w, "ldap-user") == 0) { + if (req->dn == NULL || strlen(req->dn) == 0) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require user: user's DN has not been defined; failing authorisation", + getpid()); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + /* + * First do a whole-line compare, in case it's something like + * require user Babs Jensen + */ + result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, t); + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require user: authorisation successful", getpid()); + return OK; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require user: " + "authorisation failed [%s][%s]", getpid(), + ldc->reason, ldap_err2string(result)); + } + } + /* + * Now break apart the line and compare each word on it + */ + while (t[0]) { + w = ap_getword_conf(r->pool, &t); + result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, w); + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require user: authorisation successful", getpid()); + return OK; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require user: authorisation failed [%s][%s]", + getpid(), ldc->reason, ldap_err2string(result)); + } + } + } + } + else if (strcmp(w, "ldap-dn") == 0) { + if (req->dn == NULL || strlen(req->dn) == 0) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require dn: user's DN has not been defined; failing authorisation", + getpid()); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + + result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, t, sec->compare_dn_on_server); + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require dn: authorisation successful", getpid()); + return OK; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "require dn \"%s\": LDAP error [%s][%s]", + getpid(), t, ldc->reason, ldap_err2string(result)); + } + } + } + else if (strcmp(w, "ldap-group") == 0) { + struct mod_auth_ldap_groupattr_entry_t *ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts; + int i; + + if (sec->group_attrib_is_dn) { + if (req->dn == NULL || strlen(req->dn) == 0) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require group: user's DN has not been defined; failing authorisation", + getpid()); + return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; + } + } + else { + if (req->user == NULL || strlen(req->user) == 0) { + /* We weren't called in the authentication phase, so we didn't have a + * chance to set the user field. Do so now. */ + req->user = r->user; + } + } + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require group: testing for group membership in \"%s\"", + getpid(), t); + + for (i = 0; i < sec->groupattr->nelts; i++) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require group: testing for %s: %s (%s)", getpid(), + ent[i].name, sec->group_attrib_is_dn ? req->dn : req->user, t); + + result = util_ldap_cache_compare(r, ldc, sec->url, t, ent[i].name, + sec->group_attrib_is_dn ? req->dn : req->user); + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require group: " + "authorisation successful (attribute %s) [%s][%s]", + getpid(), ent[i].name, ldc->reason, ldap_err2string(result)); + return OK; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: require group \"%s\": " + "authorisation failed [%s][%s]", + getpid(), t, ldc->reason, ldap_err2string(result)); + } + } + } + } + else if (strcmp(w, "ldap-attribute") == 0) { + while (t[0]) { + w = ap_getword(r->pool, &t, '='); + value = ap_getword_conf(r->pool, &t); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: checking attribute" + " %s has value %s", getpid(), w, value); + result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, + w, value); + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, + 0, r, "[%d] auth_ldap authorise: " + "require attribute: authorisation " + "successful", getpid()); + return OK; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, + 0, r, "[%d] auth_ldap authorise: " + "require attribute: authorisation " + "failed [%s][%s]", getpid(), + ldc->reason, ldap_err2string(result)); + } + } + } + } + else if (strcmp(w, "ldap-filter") == 0) { + if (t[0]) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: checking filter %s", + getpid(), t); + + /* Build the username filter */ + authn_ldap_build_filter(filtbuf, r, req->user, t, sec); + + /* Search for the user DN */ + result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn, + sec->scope, sec->attributes, filtbuf, &dn, &vals); + + /* Make sure that the filtered search returned the correct user dn */ + if (result == LDAP_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: checking dn match %s", + getpid(), dn); + result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, dn, + sec->compare_dn_on_server); + } + + switch(result) { + case LDAP_COMPARE_TRUE: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, + 0, r, "[%d] auth_ldap authorise: " + "require ldap-filter: authorisation " + "successful", getpid()); + return OK; + } + case LDAP_FILTER_ERROR: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, + 0, r, "[%d] auth_ldap authorise: " + "require ldap-filter: %s authorisation " + "failed [%s][%s]", getpid(), + filtbuf, ldc->reason, ldap_err2string(result)); + break; + } + default: { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, + 0, r, "[%d] auth_ldap authorise: " + "require ldap-filter: authorisation " + "failed [%s][%s]", getpid(), + ldc->reason, ldap_err2string(result)); + } + } + } + } + } + + if (!method_restricted) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: agreeing because non-restricted", + getpid()); + return OK; + } + + if (!sec->auth_authoritative) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: declining to authorise", getpid()); + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: authorisation denied", getpid()); + ap_note_basic_auth_failure (r); + + return HTTP_UNAUTHORIZED; +} + + +/* + * Use the ldap url parsing routines to break up the ldap url into + * host and port. + */ +static const char *mod_auth_ldap_parse_url(cmd_parms *cmd, + void *config, + const char *url, + const char *mode) +{ + int rc; + apr_ldap_url_desc_t *urld; + apr_ldap_err_t *result; + + authn_ldap_config_t *sec = config; + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: `%s'", getpid(), url); + + rc = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result)); + if (rc != APR_SUCCESS) { + return result->reason; + } + sec->url = apr_pstrdup(cmd->pool, url); + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: Host: %s", getpid(), urld->lud_host); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: Port: %d", getpid(), urld->lud_port); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: DN: %s", getpid(), urld->lud_dn); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: attrib: %s", getpid(), urld->lud_attrs? urld->lud_attrs[0] : "(null)"); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: scope: %s", getpid(), + (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" : + urld->lud_scope == LDAP_SCOPE_BASE? "base" : + urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown")); + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, + cmd->server, "[%d] auth_ldap url parse: filter: %s", getpid(), urld->lud_filter); + + /* Set all the values, or at least some sane defaults */ + if (sec->host) { + char *p = apr_palloc(cmd->pool, strlen(sec->host) + strlen(urld->lud_host) + 2); + strcpy(p, urld->lud_host); + strcat(p, " "); + strcat(p, sec->host); + sec->host = p; + } + else { + sec->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost"; + } + sec->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : ""; + if (urld->lud_attrs && urld->lud_attrs[0]) { + int i = 1; + while (urld->lud_attrs[i]) { + i++; + } + sec->attributes = apr_pcalloc(cmd->pool, sizeof(char *) * (i+1)); + i = 0; + while (urld->lud_attrs[i]) { + sec->attributes[i] = apr_pstrdup(cmd->pool, urld->lud_attrs[i]); + i++; + } + sec->attribute = sec->attributes[0]; + } + else { + sec->attribute = "uid"; + } + + sec->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ? + LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE; + + if (urld->lud_filter) { + if (urld->lud_filter[0] == '(') { + /* + * Get rid of the surrounding parens; later on when generating the + * filter, they'll be put back. + */ + sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1); + sec->filter[strlen(sec->filter)-1] = '\0'; + } + else { + sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter); + } + } + else { + sec->filter = "objectclass=*"; + } + + if (mode) { + if (0 == strcasecmp("NONE", mode)) { + sec->secure = APR_LDAP_NONE; + } + else if (0 == strcasecmp("SSL", mode)) { + sec->secure = APR_LDAP_SSL; + } + else if (0 == strcasecmp("TLS", mode) || 0 == strcasecmp("STARTTLS", mode)) { + sec->secure = APR_LDAP_STARTTLS; + } + else { + return "Invalid LDAP connection mode setting: must be one of NONE, " + "SSL, or TLS/STARTTLS"; + } + } + + /* "ldaps" indicates secure ldap connections desired + */ + if (strncasecmp(url, "ldaps", 5) == 0) + { + sec->secure = APR_LDAP_SSL; + sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT; + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP: auth_ldap using SSL connections"); + } + else + { + sec->port = urld->lud_port? urld->lud_port : LDAP_PORT; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, + "LDAP: auth_ldap not using SSL connections"); + } + + sec->have_ldap_url = 1; + + return NULL; +} + +static const char *mod_auth_ldap_set_deref(cmd_parms *cmd, void *config, const char *arg) +{ + authn_ldap_config_t *sec = config; + + if (strcmp(arg, "never") == 0 || strcasecmp(arg, "off") == 0) { + sec->deref = never; + } + else if (strcmp(arg, "searching") == 0) { + sec->deref = searching; + } + else if (strcmp(arg, "finding") == 0) { + sec->deref = finding; + } + else if (strcmp(arg, "always") == 0 || strcasecmp(arg, "on") == 0) { + sec->deref = always; + } + else { + return "Unrecognized value for AuthLDAPAliasDereference directive"; + } + return NULL; +} + +static const char *mod_auth_ldap_add_group_attribute(cmd_parms *cmd, void *config, const char *arg) +{ + struct mod_auth_ldap_groupattr_entry_t *new; + + authn_ldap_config_t *sec = config; + + if (sec->groupattr->nelts > GROUPATTR_MAX_ELTS) + return "Too many AuthLDAPGroupAttribute directives"; + + new = apr_array_push(sec->groupattr); + new->name = apr_pstrdup(cmd->pool, arg); + + return NULL; +} + +static const char *set_charset_config(cmd_parms *cmd, void *config, const char *arg) +{ + ap_set_module_config(cmd->server->module_config, &authnz_ldap_module, + (void *)arg); + return NULL; +} + +static const command_rec authnz_ldap_cmds[] = +{ + AP_INIT_TAKE12("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG, + "URL to define LDAP connection. This should be an RFC 2255 complaint\n" + "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n" + "
      \n" + "
    • Host is the name of the LDAP server. Use a space separated list of hosts \n" + "to specify redundant servers.\n" + "
    • Port is optional, and specifies the port to connect to.\n" + "
    • basedn specifies the base DN to start searches from\n" + "
    • Attrib specifies what attribute to search for in the directory. If not " + "provided, it defaults to uid.\n" + "
    • Scope is the scope of the search, and can be either sub or " + "one. If not provided, the default is sub.\n" + "
    • Filter is a filter to use in the search. If not provided, " + "defaults to (objectClass=*).\n" + "
    \n" + "Searches are performed using the attribute and the filter combined. " + "For example, assume that the\n" + "LDAP URL is ldap://ldap.airius.com/ou=People, o=Airius?uid?sub?(posixid=*). " + "Searches will\n" + "be done using the filter (&((posixid=*))(uid=username)), " + "where username\n" + "is the user name passed by the HTTP client. The search will be a subtree " + "search on the branch ou=People, o=Airius."), + + AP_INIT_TAKE1("AuthLDAPBindDN", ap_set_string_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, binddn), OR_AUTHCFG, + "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."), + + AP_INIT_TAKE1("AuthLDAPBindPassword", ap_set_string_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, bindpw), OR_AUTHCFG, + "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."), + + AP_INIT_FLAG("AuthLDAPRemoteUserIsDN", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, user_is_dn), OR_AUTHCFG, + "Set to 'on' to set the REMOTE_USER environment variable to be the full " + "DN of the remote user. By default, this is set to off, meaning that " + "the REMOTE_USER variable will contain whatever value the remote user sent."), + + AP_INIT_FLAG("AuthzLDAPAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, auth_authoritative), OR_AUTHCFG, + "Set to 'off' to allow access control to be passed along to lower modules if " + "the UserID and/or group is not known to this module"), + + AP_INIT_FLAG("AuthLDAPCompareDNOnServer", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, compare_dn_on_server), OR_AUTHCFG, + "Set to 'on' to force auth_ldap to do DN compares (for the \"require dn\" " + "directive) using the server, and set it 'off' to do the compares locally " + "(at the expense of possible false matches). See the documentation for " + "a complete description of this option."), + + AP_INIT_ITERATE("AuthLDAPGroupAttribute", mod_auth_ldap_add_group_attribute, NULL, OR_AUTHCFG, + "A list of attributes used to define group membership - defaults to " + "member and uniquemember"), + + AP_INIT_FLAG("AuthLDAPGroupAttributeIsDN", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, group_attrib_is_dn), OR_AUTHCFG, + "If set to 'on', auth_ldap uses the DN that is retrieved from the server for" + "subsequent group comparisons. If set to 'off', auth_ldap uses the string" + "provided by the client directly. Defaults to 'on'."), + + AP_INIT_TAKE1("AuthLDAPDereferenceAliases", mod_auth_ldap_set_deref, NULL, OR_AUTHCFG, + "Determines how aliases are handled during a search. Can bo one of the" + "values \"never\", \"searching\", \"finding\", or \"always\". " + "Defaults to always."), + +/* + AP_INIT_FLAG("AuthLDAPAuthzEnabled", ap_set_flag_slot, + (void *)APR_OFFSETOF(authn_ldap_config_t, authz_enabled), OR_AUTHCFG, + "Set to off to disable the LDAP authorization handler, even if it's been enabled in a higher tree"), +*/ + + AP_INIT_TAKE1("AuthLDAPCharsetConfig", set_charset_config, NULL, RSRC_CONF, + "Character set conversion configuration file. If omitted, character set" + "conversion is disabled."), + + {NULL} +}; + +static int authnz_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + ap_configfile_t *f; + char l[MAX_STRING_LEN]; + const char *charset_confname = ap_get_module_config(s->module_config, + &authnz_ldap_module); + apr_status_t status; + + /* + authn_ldap_config_t *sec = (authn_ldap_config_t *) + ap_get_module_config(s->module_config, + &authnz_ldap_module); + + if (sec->secure) + { + if (!util_ldap_ssl_supported(s)) + { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, + "LDAP: SSL connections (ldaps://) not supported by utilLDAP"); + return(!OK); + } + } + */ + + /* make sure that mod_ldap (util_ldap) is loaded */ + if (ap_find_linked_module("util_ldap.c") == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, + "Module mod_ldap missing. Mod_ldap (aka. util_ldap) " + "must be loaded in order for mod_auth_ldap to function properly"); + return HTTP_INTERNAL_SERVER_ERROR; + + } + + if (!charset_confname) { + return OK; + } + + charset_confname = ap_server_root_relative(p, charset_confname); + if (!charset_confname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + "Invalid charset conversion config path %s", + (const char *)ap_get_module_config(s->module_config, + &authnz_ldap_module)); + return HTTP_INTERNAL_SERVER_ERROR; + } + if ((status = ap_pcfg_openfile(&f, ptemp, charset_confname)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, s, + "could not open charset conversion config file %s.", + charset_confname); + return HTTP_INTERNAL_SERVER_ERROR; + } + + charset_conversions = apr_hash_make(p); + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) { + const char *ll = l; + char *lang; + + if (l[0] == '#') { + continue; + } + lang = ap_getword_conf(p, &ll); + ap_str_tolower(lang); + + if (ll[0]) { + char *charset = ap_getword_conf(p, &ll); + apr_hash_set(charset_conversions, lang, APR_HASH_KEY_STRING, charset); + } + } + ap_cfg_closefile(f); + + to_charset = derive_codepage_from_lang (p, "utf-8"); + if (to_charset == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, s, + "could not find the UTF-8 charset in the file %s.", + charset_confname); + return HTTP_INTERNAL_SERVER_ERROR; + } + + return OK; +} + +static const authn_provider authn_ldap_provider = +{ + &authn_ldap_check_password, +}; + +static void ImportULDAPOptFn(void) +{ + util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close); + util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find); + util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn); + util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare); + util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid); + util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn); + util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported); +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPost[]={ "mod_authz_user.c", NULL }; + + ap_register_provider(p, AUTHN_PROVIDER_GROUP, "ldap", "0", + &authn_ldap_provider); + ap_hook_post_config(authnz_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_auth_checker(authz_ldap_check_user_access, NULL, aszPost, APR_HOOK_MIDDLE); + + ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authnz_ldap_module = +{ + STANDARD20_MODULE_STUFF, + create_authnz_ldap_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authnz_ldap_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authnz_ldap.dsp b/trunk/modules/aaa/mod_authnz_ldap.dsp new file mode 100644 index 0000000000..89983bb136 --- /dev/null +++ b/trunk/modules/aaa/mod_authnz_ldap.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authnz_ldap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authnz_ldap - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authnz_ldap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authnz_ldap.mak" CFG="mod_authnz_ldap - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authnz_ldap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authnz_ldap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Release\mod_authnz_ldap_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so +# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Debug\mod_authnz_ldap_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so +# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so + +!ENDIF + +# Begin Target + +# Name "mod_authnz_ldap - Win32 Release" +# Name "mod_authnz_ldap - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authnz_ldap.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authnz_ldap.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authnz_ldap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authnz_ldap.so "LDAP Utility Module for Apache" ../../include/ap_release.h > .\mod_authnz_ldap.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authnz_ldap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authnz_ldap.so "LDAP Utility Module for Apache" ../../include/ap_release.h > .\mod_authnz_ldap.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authz_dbm.c b/trunk/modules/aaa/mod_authz_dbm.c new file mode 100644 index 0000000000..436c42a6f7 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_dbm.c @@ -0,0 +1,283 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_strings.h" +#include "apr_dbm.h" +#include "apr_md5.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/ + +#include "mod_auth.h" + +typedef struct { + char *grpfile; + char *dbmtype; + int authoritative; +} authz_dbm_config_rec; + +/* This should go into APR; perhaps with some nice + * caching/locking/flocking of the open dbm file. + */ +static char *get_dbm_entry_as_str(apr_pool_t *pool, apr_dbm_t *f, char *key) +{ + apr_datum_t d, q; + q.dptr = key; + +#ifndef NETSCAPE_DBM_COMPAT + q.dsize = strlen(q.dptr); +#else + q.dsize = strlen(q.dptr) + 1; +#endif + + if (apr_dbm_fetch(f, q, &d) == APR_SUCCESS && d.dptr) { + return apr_pstrmemdup(pool, d.dptr, d.dsize); + } + + return NULL; +} + +static void *create_authz_dbm_dir_config(apr_pool_t *p, char *d) +{ + authz_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->grpfile = NULL; + conf->dbmtype = "default"; + conf->authoritative = 1; /* fortress is secure by default */ + + return conf; +} + +static const command_rec authz_dbm_cmds[] = +{ + AP_INIT_TAKE1("AuthDBMGroupFile", ap_set_file_slot, + (void *)APR_OFFSETOF(authz_dbm_config_rec, grpfile), + OR_AUTHCFG, "database file containing group names and member user IDs"), + AP_INIT_TAKE1("AuthzDBMType", ap_set_string_slot, + (void *)APR_OFFSETOF(authz_dbm_config_rec, dbmtype), + OR_AUTHCFG, "what type of DBM file the group file is"), + AP_INIT_FLAG("AuthzDBMAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authz_dbm_config_rec, authoritative), + OR_AUTHCFG, "Set to 'Off' to allow access control to be passed along to " + "lower modules, if the group required is not found or empty, or the user " + " is not in the required groups. (default is On.)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authz_dbm_module; + +/* We do something strange with the group file. If the group file + * contains any : we assume the format is + * key=username value=":"groupname [":"anything here is ignored] + * otherwise we now (0.8.14+) assume that the format is + * key=username value=groupname + * The first allows the password and group files to be the same + * physical DBM file; key=username value=password":"groupname[":"anything] + * + * mark@telescope.org, 22Sep95 + */ + +static apr_status_t get_dbm_grp(request_rec *r, char *key1, char *key2, + char *dbmgrpfile, char *dbtype, + const char ** out) +{ + char *grp_colon, *val; + apr_status_t retval; + apr_dbm_t *f; + + retval = apr_dbm_open_ex(&f, dbtype, dbmgrpfile, APR_DBM_READONLY, + APR_OS_DEFAULT, r->pool); + + if (retval != APR_SUCCESS) { + return retval; + } + + /* Try key2 only if key1 failed */ + if (!(val = get_dbm_entry_as_str(r->pool, f, key1))) { + val = get_dbm_entry_as_str(r->pool, f, key2); + } + + apr_dbm_close(f); + + if (val && (grp_colon = ap_strchr(val, ':')) != NULL) { + char *grp_colon2 = ap_strchr(++grp_colon, ':'); + + if (grp_colon2) { + *grp_colon2 = '\0'; + } + *out = grp_colon; + } + else { + *out = val; + } + + return retval; +} + +/* Checking ID */ +static int dbm_check_auth(request_rec *r) +{ + authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authz_dbm_module); + char *user = r->user; + int m = r->method_number; + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL; + register int x; + const char *t; + char *w; + int required_group = 0; + const char *filegroup = NULL; + const char *orig_groups = NULL; + char *reason = NULL; + + if (!conf->grpfile) { + return DECLINED; + } + + if (!reqs_arr) { + return DECLINED; + } + + for (x = 0; x < reqs_arr->nelts; x++) { + + if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) { + continue; + } + + t = reqs[x].requirement; + w = ap_getword_white(r->pool, &t); + + if (!strcmp(w, "file-group")) { + filegroup = apr_table_get(r->notes, AUTHZ_GROUP_NOTE); + + if (!filegroup) { + /* mod_authz_owner is not present or not + * authoritative. We are just a helper module for testing + * group membership, so we don't care and decline. + */ + continue; + } + } + + if (!strcmp(w, "group") || filegroup) { + const char *realm = ap_auth_name(r); + const char *groups; + char *v; + + /* remember that actually a group is required */ + required_group = 1; + + /* fetch group data from dbm file only once. */ + if (!orig_groups) { + apr_status_t status; + + status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, + NULL), + user, + conf->grpfile, conf->dbmtype, &groups); + + if (status != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "could not open dbm (type %s) group access " + "file: %s", conf->dbmtype, conf->grpfile); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (groups == NULL) { + /* no groups available, so exit immediately */ + reason = apr_psprintf(r->pool, + "user doesn't appear in DBM group " + "file (%s).", conf->grpfile); + break; + } + + orig_groups = groups; + } + + if (filegroup) { + groups = orig_groups; + while (groups[0]) { + v = ap_getword(r->pool, &groups, ','); + if (!strcmp(v, filegroup)) { + return OK; + } + } + + if (conf->authoritative) { + reason = apr_psprintf(r->pool, + "file group '%s' does not match.", + filegroup); + break; + } + + /* now forget the filegroup, thus alternatively require'd + groups get a real chance */ + filegroup = NULL; + } + else { + while (t[0]) { + w = ap_getword_white(r->pool, &t); + groups = orig_groups; + while (groups[0]) { + v = ap_getword(r->pool, &groups, ','); + if (!strcmp(v, w)) { + return OK; + } + } + } + } + } + } + + /* No applicable "require group" for this method seen */ + if (!required_group || !conf->authoritative) { + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Authorization of user %s to access %s failed, reason: %s", + r->user, r->uri, + reason ? reason : "user is not part of the " + "'require'ed group(s)."); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[]={ "mod_authz_owner.c", NULL }; + + ap_hook_auth_checker(dbm_check_auth, aszPre, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authz_dbm_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_dbm_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_dbm_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_dbm.dsp b/trunk/modules/aaa/mod_authz_dbm.dsp new file mode 100644 index 0000000000..f6c6f3b583 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_dbm.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authz_dbm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authz_dbm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_dbm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_dbm.mak" CFG="mod_authz_dbm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authz_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authz_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authz_dbm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_dbm_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_dbm_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so + +!ENDIF + +# Begin Target + +# Name "mod_authz_dbm - Win32 Release" +# Name "mod_authz_dbm - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authz_dbm.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authz_dbm.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authz_dbm - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_dbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_dbm.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_dbm.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_dbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_dbm.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_dbm.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authz_default.c b/trunk/modules/aaa/mod_authz_default.c new file mode 100644 index 0000000000..88859b2061 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_default.c @@ -0,0 +1,115 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_md5.h" /* for apr_password_validate */ + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +typedef struct { + int authoritative; +} authz_default_config_rec; + +static void *create_authz_default_dir_config(apr_pool_t *p, char *d) +{ + authz_default_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->authoritative = 1; /* keep the fortress secure by default */ + return conf; +} + +static const command_rec authz_default_cmds[] = +{ + AP_INIT_FLAG("AuthzDefaultAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authz_default_config_rec, authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules. (default is On.)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authz_default_module; + +static int check_user_access(request_rec *r) +{ + authz_default_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authz_default_module); + int m = r->method_number; + int method_restricted = 0; + register int x; + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs; + + /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive, + * then any user will do. + */ + if (!reqs_arr) { + return OK; + } + reqs = (require_line *)reqs_arr->elts; + + for (x = 0; x < reqs_arr->nelts; x++) { + if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) { + continue; + } + method_restricted = 1; + break; + } + + if (method_restricted == 0) { + return OK; + } + + if (!(conf->authoritative)) { + return DECLINED; + } + + /* if we aren't authoritative, any require directive could be + * considered valid even if noone groked it. However, if we are + * authoritative, we can warn the user they did something wrong. + * + * That something could be a missing "AuthAuthoritative off", but + * more likely is a typo in the require directive. + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: require directives " + "present and no Authoritative handler.", r->uri); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_auth_checker(check_user_access,NULL,NULL,APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA authz_default_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_default_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_default_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_default.dsp b/trunk/modules/aaa/mod_authz_default.dsp new file mode 100644 index 0000000000..798089faa6 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_default.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authz_default" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authz_default - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_default.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_default.mak" CFG="mod_authz_default - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authz_default - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authz_default - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authz_default - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_default_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authz_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_default.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authz_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_default.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authz_default - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_default_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_default.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_default.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_default.so + +!ENDIF + +# Begin Target + +# Name "mod_authz_default - Win32 Release" +# Name "mod_authz_default - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authz_default.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authz_default.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authz_default - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_default.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_default.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_default.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authz_default - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_default.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_default.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_default.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authz_groupfile.c b/trunk/modules/aaa/mod_authz_groupfile.c new file mode 100644 index 0000000000..6f02d06d9d --- /dev/null +++ b/trunk/modules/aaa/mod_authz_groupfile.c @@ -0,0 +1,284 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This module is triggered by an + * + * AuthGroupFile standard /path/to/file + * + * and the presense of a + * + * require group + * + * In an applicable limit/directory block for that method. + * + * If there are no AuthGroupFile directives valid for + * the request; we DECLINED. + * + * If the AuthGroupFile is defined; but somehow not + * accessible: we SERVER_ERROR (was DECLINED). + * + * If there are no 'require ' directives defined for + * this request then we DECLINED (was OK). + * + * If there are no 'require ' directives valid for + * this request method then we DECLINED. (was OK) + * + * If there are any 'require group' blocks and we + * are not in any group - we HTTP_UNAUTHORIZE + * unless we are non-authoritative; in which + * case we DECLINED. + * + */ + +#include "apr_strings.h" +#include "apr_lib.h" /* apr_isspace */ + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +#include "mod_auth.h" + +typedef struct { + char *groupfile; + int authoritative; +} authz_groupfile_config_rec; + +static void *create_authz_groupfile_dir_config(apr_pool_t *p, char *d) +{ + authz_groupfile_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->groupfile = NULL; + conf->authoritative = 1; /* keep the fortress secure by default */ + return conf; +} + +static const char *set_authz_groupfile_slot(cmd_parms *cmd, void *offset, const char *f, + const char *t) +{ + if (t && strcmp(t, "standard")) { + return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL); + } + + return ap_set_file_slot(cmd, offset, f); +} + +static const command_rec authz_groupfile_cmds[] = +{ + AP_INIT_TAKE12("AuthGroupFile", set_authz_groupfile_slot, + (void *)APR_OFFSETOF(authz_groupfile_config_rec, groupfile), + OR_AUTHCFG, + "text file containing group names and member user IDs"), + AP_INIT_FLAG("AuthzGroupFileAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authz_groupfile_config_rec, + authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules if the 'require group' fails. (default is " + "On)."), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authz_groupfile_module; + +static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile, + apr_table_t ** out) +{ + ap_configfile_t *f; + apr_table_t *grps = apr_table_make(p, 15); + apr_pool_t *sp; + char l[MAX_STRING_LEN]; + const char *group_name, *ll, *w; + apr_status_t status; + apr_size_t group_len; + + if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) { + return status ; + } + + apr_pool_create(&sp, p); + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) { + if ((l[0] == '#') || (!l[0])) { + continue; + } + ll = l; + apr_pool_clear(sp); + + group_name = ap_getword(sp, &ll, ':'); + group_len = strlen(group_name); + + while (group_len && apr_isspace(*(group_name + group_len - 1))) { + --group_len; + } + + while (ll[0]) { + w = ap_getword_conf(sp, &ll); + if (!strcmp(w, user)) { + apr_table_setn(grps, apr_pstrmemdup(p, group_name, group_len), + "in"); + break; + } + } + } + ap_cfg_closefile(f); + apr_pool_destroy(sp); + + *out = grps; + return APR_SUCCESS; +} + +/* Checking ID */ + +static int check_user_access(request_rec *r) +{ + authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authz_groupfile_module); + char *user = r->user; + int m = r->method_number; + int required_group = 0; + register int x; + const char *t, *w; + apr_table_t *grpstatus = NULL; + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs; + const char *filegroup = NULL; + char *reason = NULL; + + /* If there is no group file - then we are not + * configured. So decline. + */ + if (!(conf->groupfile)) { + return DECLINED; + } + + if (!reqs_arr) { + return DECLINED; /* XXX change from legacy */ + } + + reqs = (require_line *)reqs_arr->elts; + + for (x = 0; x < reqs_arr->nelts; x++) { + + if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) { + continue; + } + + t = reqs[x].requirement; + w = ap_getword_white(r->pool, &t); + + /* needs mod_authz_owner to be present */ + if (!strcmp(w, "file-group")) { + filegroup = apr_table_get(r->notes, AUTHZ_GROUP_NOTE); + + if (!filegroup) { + /* mod_authz_owner is not present or not + * authoritative. We are just a helper module for testing + * group membership, so we don't care and decline. + */ + continue; + } + } + + if (!strcmp(w, "group") || filegroup) { + required_group = 1; /* remember the requirement */ + + /* create group table only if actually needed. */ + if (!grpstatus) { + apr_status_t status; + + status = groups_for_user(r->pool, user, conf->groupfile, + &grpstatus); + + if (status != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "Could not open group file: %s", + conf->groupfile); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (apr_table_elts(grpstatus)->nelts == 0) { + /* no groups available, so exit immediately */ + reason = apr_psprintf(r->pool, + "user doesn't appear in group file " + "(%s).", conf->groupfile); + break; + } + } + + if (filegroup) { + if (apr_table_get(grpstatus, filegroup)) { + return OK; + } + + if (conf->authoritative) { + reason = apr_psprintf(r->pool, + "file group '%s' does not match.", + filegroup); + break; + } + + /* now forget the filegroup, thus alternatively require'd + groups get a real chance */ + filegroup = NULL; + } + else { + while (t[0]) { + w = ap_getword_conf(r->pool, &t); + if (apr_table_get(grpstatus, w)) { + return OK; + } + } + } + } + } + + /* No applicable "require group" for this method seen */ + if (!required_group || !conf->authoritative) { + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Authorization of user %s to access %s failed, reason: %s", + r->user, r->uri, + reason ? reason : "user is not part of the " + "'require'ed group(s)."); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[]={ "mod_authz_owner.c", NULL }; + + ap_hook_auth_checker(check_user_access, aszPre, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authz_groupfile_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_groupfile_dir_config,/* dir config creater */ + NULL, /* dir merger -- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_groupfile_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_groupfile.dsp b/trunk/modules/aaa/mod_authz_groupfile.dsp new file mode 100644 index 0000000000..070846a7f9 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_groupfile.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authz_groupfile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authz_groupfile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_groupfile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_groupfile.mak" CFG="mod_authz_groupfile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authz_groupfile - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authz_groupfile - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_groupfile_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_groupfile_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so + +!ENDIF + +# Begin Target + +# Name "mod_authz_groupfile - Win32 Release" +# Name "mod_authz_groupfile - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authz_groupfile.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authz_groupfile.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_groupfile.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_groupfile.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_groupfile.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_groupfile.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_groupfile.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_groupfile.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authz_host.c b/trunk/modules/aaa/mod_authz_host.c new file mode 100644 index 0000000000..b817b9eb12 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_host.c @@ -0,0 +1,322 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Security options etc. + * + * Module derived from code originally written by Rob McCool + * + */ + +#include "apr_strings.h" +#include "apr_network_io.h" +#include "apr_md5.h" + +#define APR_WANT_STRFUNC +#define APR_WANT_BYTEFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_core.h" +#include "http_config.h" +#include "http_log.h" +#include "http_request.h" + +#if APR_HAVE_NETINET_IN_H +#include +#endif + +enum allowdeny_type { + T_ENV, + T_ALL, + T_IP, + T_HOST, + T_FAIL +}; + +typedef struct { + apr_int64_t limited; + union { + char *from; + apr_ipsubnet_t *ip; + } x; + enum allowdeny_type type; +} allowdeny; + +/* things in the 'order' array */ +#define DENY_THEN_ALLOW 0 +#define ALLOW_THEN_DENY 1 +#define MUTUAL_FAILURE 2 + +typedef struct { + int order[METHODS]; + apr_array_header_t *allows; + apr_array_header_t *denys; +} authz_host_dir_conf; + +module AP_MODULE_DECLARE_DATA authz_host_module; + +static void *create_authz_host_dir_config(apr_pool_t *p, char *dummy) +{ + int i; + authz_host_dir_conf *conf = + (authz_host_dir_conf *)apr_pcalloc(p, sizeof(authz_host_dir_conf)); + + for (i = 0; i < METHODS; ++i) { + conf->order[i] = DENY_THEN_ALLOW; + } + conf->allows = apr_array_make(p, 1, sizeof(allowdeny)); + conf->denys = apr_array_make(p, 1, sizeof(allowdeny)); + + return (void *)conf; +} + +static const char *order(cmd_parms *cmd, void *dv, const char *arg) +{ + authz_host_dir_conf *d = (authz_host_dir_conf *) dv; + int i, o; + + if (!strcasecmp(arg, "allow,deny")) + o = ALLOW_THEN_DENY; + else if (!strcasecmp(arg, "deny,allow")) + o = DENY_THEN_ALLOW; + else if (!strcasecmp(arg, "mutual-failure")) + o = MUTUAL_FAILURE; + else + return "unknown order"; + + for (i = 0; i < METHODS; ++i) + if (cmd->limited & (AP_METHOD_BIT << i)) + d->order[i] = o; + + return NULL; +} + +static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from, + const char *where_c) +{ + authz_host_dir_conf *d = (authz_host_dir_conf *) dv; + allowdeny *a; + char *where = apr_pstrdup(cmd->pool, where_c); + char *s; + char msgbuf[120]; + apr_status_t rv; + + if (strcasecmp(from, "from")) + return "allow and deny must be followed by 'from'"; + + a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys); + a->x.from = where; + a->limited = cmd->limited; + + if (!strncasecmp(where, "env=", 4)) { + a->type = T_ENV; + a->x.from += 4; + + } + else if (!strcasecmp(where, "all")) { + a->type = T_ALL; + } + else if ((s = ap_strchr(where, '/'))) { + *s++ = '\0'; + rv = apr_ipsubnet_create(&a->x.ip, where, s, cmd->pool); + if(APR_STATUS_IS_EINVAL(rv)) { + /* looked nothing like an IP address */ + return "An IP address was expected"; + } + else if (rv != APR_SUCCESS) { + apr_strerror(rv, msgbuf, sizeof msgbuf); + return apr_pstrdup(cmd->pool, msgbuf); + } + a->type = T_IP; + } + else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&a->x.ip, where, + NULL, cmd->pool))) { + if (rv != APR_SUCCESS) { + apr_strerror(rv, msgbuf, sizeof msgbuf); + return apr_pstrdup(cmd->pool, msgbuf); + } + a->type = T_IP; + } + else { /* no slash, didn't look like an IP address => must be a host */ + a->type = T_HOST; + } + + return NULL; +} + +static char its_an_allow; + +static const command_rec authz_host_cmds[] = +{ + AP_INIT_TAKE1("order", order, NULL, OR_LIMIT, + "'allow,deny', 'deny,allow', or 'mutual-failure'"), + AP_INIT_ITERATE2("allow", allow_cmd, &its_an_allow, OR_LIMIT, + "'from' followed by hostnames or IP-address wildcards"), + AP_INIT_ITERATE2("deny", allow_cmd, NULL, OR_LIMIT, + "'from' followed by hostnames or IP-address wildcards"), + {NULL} +}; + +static int in_domain(const char *domain, const char *what) +{ + int dl = strlen(domain); + int wl = strlen(what); + + if ((wl - dl) >= 0) { + if (strcasecmp(domain, &what[wl - dl]) != 0) { + return 0; + } + + /* Make sure we matched an *entire* subdomain --- if the user + * said 'allow from good.com', we don't want people from nogood.com + * to be able to get in. + */ + + if (wl == dl) { + return 1; /* matched whole thing */ + } + else { + return (domain[0] == '.' || what[wl - dl - 1] == '.'); + } + } + else { + return 0; + } +} + +static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method) +{ + + allowdeny *ap = (allowdeny *) a->elts; + apr_int64_t mmask = (AP_METHOD_BIT << method); + int i; + int gothost = 0; + const char *remotehost = NULL; + + for (i = 0; i < a->nelts; ++i) { + if (!(mmask & ap[i].limited)) { + continue; + } + + switch (ap[i].type) { + case T_ENV: + if (apr_table_get(r->subprocess_env, ap[i].x.from)) { + return 1; + } + break; + + case T_ALL: + return 1; + + case T_IP: + if (apr_ipsubnet_test(ap[i].x.ip, r->connection->remote_addr)) { + return 1; + } + break; + + case T_HOST: + if (!gothost) { + int remotehost_is_ip; + + remotehost = ap_get_remote_host(r->connection, + r->per_dir_config, + REMOTE_DOUBLE_REV, + &remotehost_is_ip); + + if ((remotehost == NULL) || remotehost_is_ip) { + gothost = 1; + } + else { + gothost = 2; + } + } + + if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) { + return 1; + } + break; + + case T_FAIL: + /* do nothing? */ + break; + } + } + + return 0; +} + +static int check_dir_access(request_rec *r) +{ + int method = r->method_number; + int ret = OK; + authz_host_dir_conf *a = (authz_host_dir_conf *) + ap_get_module_config(r->per_dir_config, &authz_host_module); + + if (a->order[method] == ALLOW_THEN_DENY) { + ret = HTTP_FORBIDDEN; + if (find_allowdeny(r, a->allows, method)) { + ret = OK; + } + if (find_allowdeny(r, a->denys, method)) { + ret = HTTP_FORBIDDEN; + } + } + else if (a->order[method] == DENY_THEN_ALLOW) { + if (find_allowdeny(r, a->denys, method)) { + ret = HTTP_FORBIDDEN; + } + if (find_allowdeny(r, a->allows, method)) { + ret = OK; + } + } + else { + if (find_allowdeny(r, a->allows, method) + && !find_allowdeny(r, a->denys, method)) { + ret = OK; + } + else { + ret = HTTP_FORBIDDEN; + } + } + + if (ret == HTTP_FORBIDDEN + && (ap_satisfies(r) != SATISFY_ANY || !ap_some_auth_required(r))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "client denied by server configuration: %s", + r->filename); + } + + return ret; +} + +static void register_hooks(apr_pool_t *p) +{ + /* This can be access checker since we don't require r->user to be set. */ + ap_hook_access_checker(check_dir_access,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authz_host_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_host_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_host_cmds, + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_host.dsp b/trunk/modules/aaa/mod_authz_host.dsp new file mode 100644 index 0000000000..8320a7a339 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_host.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authz_host" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authz_host - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_host.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_host.mak" CFG="mod_authz_host - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authz_host - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authz_host - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authz_host - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_host_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_host_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so + +!ENDIF + +# Begin Target + +# Name "mod_authz_host - Win32 Release" +# Name "mod_authz_host - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authz_host.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authz_host.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authz_host - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_host.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_host.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_host.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_host.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_host.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_host.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/aaa/mod_authz_owner.c b/trunk/modules/aaa/mod_authz_owner.c new file mode 100644 index 0000000000..8f56879545 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_owner.c @@ -0,0 +1,239 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_file_info.h" +#include "apr_user.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +#include "mod_auth.h" /* for AUTHZ_GROUP_NOTE */ + +typedef struct { + int authoritative; +} authz_owner_config_rec; + +static void *create_authz_owner_dir_config(apr_pool_t *p, char *d) +{ + authz_owner_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->authoritative = 1; /* keep the fortress secure by default */ + return conf; +} + +static const command_rec authz_owner_cmds[] = +{ + AP_INIT_FLAG("AuthzOwnerAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authz_owner_config_rec, authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules. (default is On.)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authz_owner_module; + +static int check_file_owner(request_rec *r) +{ + authz_owner_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authz_owner_module); + int m = r->method_number; + register int x; + const char *t, *w; + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs; + int required_owner = 0; + apr_status_t status = 0; + char *reason = NULL; + + if (!reqs_arr) { + return DECLINED; + } + + reqs = (require_line *)reqs_arr->elts; + for (x = 0; x < reqs_arr->nelts; x++) { + + /* if authoritative = On then break if a require already failed. */ + if (reason && conf->authoritative) { + break; + } + + if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) { + continue; + } + + t = reqs[x].requirement; + w = ap_getword_white(r->pool, &t); + + if (!strcmp(w, "file-owner")) { +#if !APR_HAS_USER + if ((required_owner & ~1) && conf->authoritative) { + break; + } + + required_owner |= 1; /* remember the requirement */ + reason = "'Require file-owner' is not supported on this platform."; + continue; +#else /* APR_HAS_USER */ + char *owner = NULL; + apr_finfo_t finfo; + + if ((required_owner & ~1) && conf->authoritative) { + break; + } + + required_owner |= 1; /* remember the requirement */ + + if (!r->filename) { + reason = "no filename available"; + continue; + } + + status = apr_stat(&finfo, r->filename, APR_FINFO_USER, r->pool); + if (status != APR_SUCCESS) { + reason = apr_pstrcat(r->pool, "could not stat file ", + r->filename, NULL); + continue; + } + + if (!(finfo.valid & APR_FINFO_USER)) { + reason = "no file owner information available"; + continue; + } + + status = apr_uid_name_get(&owner, finfo.user, r->pool); + if (status != APR_SUCCESS || !owner) { + reason = "could not get name of file owner"; + continue; + } + + if (strcmp(owner, r->user)) { + reason = apr_psprintf(r->pool, "file owner %s does not match.", + owner); + continue; + } + + /* this user is authorized */ + return OK; +#endif /* APR_HAS_USER */ + } + + /* file-group only figures out the file's group and lets + * other modules do the actual authorization (against a group file/db). + * Thus, these modules have to hook themselves after + * mod_authz_owner and of course recognize 'file-group', too. + */ + if (!strcmp(w, "file-group")) { +#if !APR_HAS_USER + if ((required_owner & ~6) && conf->authoritative) { + break; + } + + required_owner |= 2; /* remember the requirement */ + reason = "'Require file-group' is not supported on this platform."; + continue; +#else /* APR_HAS_USER */ + char *group = NULL; + apr_finfo_t finfo; + + if ((required_owner & ~6) && conf->authoritative) { + break; + } + + required_owner |= 2; /* remember the requirement */ + + if (!r->filename) { + reason = "no filename available"; + continue; + } + + status = apr_stat(&finfo, r->filename, APR_FINFO_GROUP, r->pool); + if (status != APR_SUCCESS) { + reason = apr_pstrcat(r->pool, "could not stat file ", + r->filename, NULL); + continue; + } + + if (!(finfo.valid & APR_FINFO_GROUP)) { + reason = "no file group information available"; + continue; + } + + status = apr_gid_name_get(&group, finfo.group, r->pool); + if (status != APR_SUCCESS || !group) { + reason = "could not get name of file group"; + continue; + } + + /* store group name in a note and let others decide... */ + apr_table_setn(r->notes, AUTHZ_GROUP_NOTE, group); + required_owner |= 4; + continue; +#endif /* APR_HAS_USER */ + } + } + + if (!required_owner || !conf->authoritative) { + return DECLINED; + } + + /* allow file-group passed to group db modules either if this is the + * only applicable requirement here or if a file-owner failed but we're + * not authoritative. + * This allows configurations like: + * + * AuthzOwnerAuthoritative Off + * require file-owner + * require file-group + * + * with the semantical meaning of "either owner or group must match" + * (inclusive or) + * + * [ 6 == 2 | 4; 7 == 1 | 2 | 4 ] should I use #defines instead? + */ + if (required_owner == 6 || (required_owner == 7 && !conf->authoritative)) { + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "Authorization of user %s to access %s failed, reason: %s", + r->user, r->uri, reason ? reason : "unknown"); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_auth_checker(check_file_owner, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authz_owner_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_owner_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_owner_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_user.c b/trunk/modules/aaa/mod_authz_user.c new file mode 100644 index 0000000000..3478359593 --- /dev/null +++ b/trunk/modules/aaa/mod_authz_user.c @@ -0,0 +1,129 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" + +typedef struct { + int authoritative; +} authz_user_config_rec; + +static void *create_authz_user_dir_config(apr_pool_t *p, char *d) +{ + authz_user_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->authoritative = 1; /* keep the fortress secure by default */ + return conf; +} + +static const command_rec authz_user_cmds[] = +{ + AP_INIT_FLAG("AuthzUserAuthoritative", ap_set_flag_slot, + (void *)APR_OFFSETOF(authz_user_config_rec, authoritative), + OR_AUTHCFG, + "Set to 'Off' to allow access control to be passed along to " + "lower modules if the 'require user' or 'require valid-user' " + "statement is not met. (default: On)."), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA authz_user_module; + +static int check_user_access(request_rec *r) +{ + authz_user_config_rec *conf = ap_get_module_config(r->per_dir_config, + &authz_user_module); + char *user = r->user; + int m = r->method_number; + int required_user = 0; + register int x; + const char *t, *w; + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs; + + /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive, + * then any user will do. + */ + if (!reqs_arr) { + return DECLINED; + } + reqs = (require_line *)reqs_arr->elts; + + for (x = 0; x < reqs_arr->nelts; x++) { + + if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) { + continue; + } + + t = reqs[x].requirement; + w = ap_getword_white(r->pool, &t); + if (!strcmp(w, "valid-user")) { + return OK; + } + if (!strcmp(w, "user")) { + /* And note that there are applicable requirements + * which we consider ourselves the owner of. + */ + required_user = 1; + while (t[0]) { + w = ap_getword_conf(r->pool, &t); + if (!strcmp(user, w)) { + return OK; + } + } + } + } + + if (!required_user) { + /* no applicable requirements */ + return DECLINED; + } + + if (!conf->authoritative) { + return DECLINED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: user '%s' does not meet " + "'require'ments for user/valid-user to be allowed access", + r->uri, user); + + ap_note_auth_failure(r); + return HTTP_UNAUTHORIZED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_auth_checker(check_user_access, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA authz_user_module = +{ + STANDARD20_MODULE_STUFF, + create_authz_user_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + authz_user_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/aaa/mod_authz_user.dsp b/trunk/modules/aaa/mod_authz_user.dsp new file mode 100644 index 0000000000..4058fd8dfe --- /dev/null +++ b/trunk/modules/aaa/mod_authz_user.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_authz_user" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_authz_user - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_user.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_authz_user.mak" CFG="mod_authz_user - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_authz_user - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_authz_user - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_authz_user - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_user_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_user_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so + +!ENDIF + +# Begin Target + +# Name "mod_authz_user - Win32 Release" +# Name "mod_authz_user - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_authz_user.c +# End Source File +# Begin Source File + +SOURCE=.\mod_authz_user.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_authz_user - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_user.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_user.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_user.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_authz_user.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_authz_user.so "auth_basic_module for Apache" ../../include/ap_release.h > .\mod_authz_user.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/arch/netware/libprews.c b/trunk/modules/arch/netware/libprews.c new file mode 100644 index 0000000000..264ae054b8 --- /dev/null +++ b/trunk/modules/arch/netware/libprews.c @@ -0,0 +1,80 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*------------------------------------------------------------------ + These functions are to be called when the shared NLM starts and + stops. By using these functions instead of defining a main() + and calling ExitThread(TSR_THREAD, 0), the load time of the + shared NLM is faster and memory size reduced. + + You may also want to override these in your own Apache module + to do any cleanup other than the mechanism Apache modules + provide. +------------------------------------------------------------------*/ +#include +//#include "stddef.h" +#ifdef USE_WINSOCK +#include "novsock2.h" +#endif + +int _NonAppStart +( + void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)( int conn, void *fileHandle, size_t offset, + size_t nbytes, size_t *bytesRead, void *buffer ), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages +) +{ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) + +#ifdef USE_WINSOCK + WSADATA wsaData; + + return WSAStartup((WORD) MAKEWORD(2, 0), &wsaData); +#else + return 0; +#endif +} + +void _NonAppStop( void ) +{ +#ifdef USE_WINSOCK + WSACleanup(); +#else + return;0; +#endif +} + +int _NonAppCheckUnload( void ) +{ + return 0; +} diff --git a/trunk/modules/arch/netware/mod_auth_basic.def b/trunk/modules/arch/netware/mod_auth_basic.def new file mode 100644 index 0000000000..0a6f81aa21 --- /dev/null +++ b/trunk/modules/arch/netware/mod_auth_basic.def @@ -0,0 +1 @@ +EXPORT auth_basic_module diff --git a/trunk/modules/arch/netware/mod_auth_digest.def b/trunk/modules/arch/netware/mod_auth_digest.def new file mode 100644 index 0000000000..6a3aa085d2 --- /dev/null +++ b/trunk/modules/arch/netware/mod_auth_digest.def @@ -0,0 +1 @@ +EXPORT auth_digest_module diff --git a/trunk/modules/arch/netware/mod_authn_anon.def b/trunk/modules/arch/netware/mod_authn_anon.def new file mode 100644 index 0000000000..78bb61be2d --- /dev/null +++ b/trunk/modules/arch/netware/mod_authn_anon.def @@ -0,0 +1 @@ +EXPORT authn_anon_module diff --git a/trunk/modules/arch/netware/mod_authn_dbm.def b/trunk/modules/arch/netware/mod_authn_dbm.def new file mode 100644 index 0000000000..7a242b0317 --- /dev/null +++ b/trunk/modules/arch/netware/mod_authn_dbm.def @@ -0,0 +1,2 @@ +EXPORT authn_dbm_module + diff --git a/trunk/modules/arch/netware/mod_authn_default.def b/trunk/modules/arch/netware/mod_authn_default.def new file mode 100644 index 0000000000..fb94aa37fb --- /dev/null +++ b/trunk/modules/arch/netware/mod_authn_default.def @@ -0,0 +1 @@ +EXPORT authn_default_module diff --git a/trunk/modules/arch/netware/mod_authn_file.def b/trunk/modules/arch/netware/mod_authn_file.def new file mode 100644 index 0000000000..fd0765a10b --- /dev/null +++ b/trunk/modules/arch/netware/mod_authn_file.def @@ -0,0 +1,3 @@ +EXPORT authn_file_module + + diff --git a/trunk/modules/arch/netware/mod_authz_dbm.def b/trunk/modules/arch/netware/mod_authz_dbm.def new file mode 100644 index 0000000000..d52639c15b --- /dev/null +++ b/trunk/modules/arch/netware/mod_authz_dbm.def @@ -0,0 +1 @@ +EXPORT authz_dbm_module diff --git a/trunk/modules/arch/netware/mod_authz_default.def b/trunk/modules/arch/netware/mod_authz_default.def new file mode 100644 index 0000000000..164564f540 --- /dev/null +++ b/trunk/modules/arch/netware/mod_authz_default.def @@ -0,0 +1 @@ +EXPORT authz_default_module diff --git a/trunk/modules/arch/netware/mod_authz_groupfile.def b/trunk/modules/arch/netware/mod_authz_groupfile.def new file mode 100644 index 0000000000..25d955519a --- /dev/null +++ b/trunk/modules/arch/netware/mod_authz_groupfile.def @@ -0,0 +1,2 @@ +EXPORT authz_groupfile_module + diff --git a/trunk/modules/arch/netware/mod_authz_user.def b/trunk/modules/arch/netware/mod_authz_user.def new file mode 100644 index 0000000000..043418b620 --- /dev/null +++ b/trunk/modules/arch/netware/mod_authz_user.def @@ -0,0 +1 @@ +EXPORT authz_user_module diff --git a/trunk/modules/arch/netware/mod_cache.def b/trunk/modules/arch/netware/mod_cache.def new file mode 100644 index 0000000000..6fd6423bb3 --- /dev/null +++ b/trunk/modules/arch/netware/mod_cache.def @@ -0,0 +1,5 @@ +EXPORT cache_module +EXPORT @mod_cache.imp + + + diff --git a/trunk/modules/arch/netware/mod_cern_meta.def b/trunk/modules/arch/netware/mod_cern_meta.def new file mode 100644 index 0000000000..5638325bbd --- /dev/null +++ b/trunk/modules/arch/netware/mod_cern_meta.def @@ -0,0 +1 @@ +EXPORT cern_meta_module diff --git a/trunk/modules/arch/netware/mod_dav.def b/trunk/modules/arch/netware/mod_dav.def new file mode 100644 index 0000000000..fb56c92fc6 --- /dev/null +++ b/trunk/modules/arch/netware/mod_dav.def @@ -0,0 +1,3 @@ +EXPORT dav_module +EXPORT @dav.imp + diff --git a/trunk/modules/arch/netware/mod_disk_cache.def b/trunk/modules/arch/netware/mod_disk_cache.def new file mode 100644 index 0000000000..0a9440ad8e --- /dev/null +++ b/trunk/modules/arch/netware/mod_disk_cache.def @@ -0,0 +1,3 @@ +IMPORT @mod_cache.imp +EXPORT disk_cache_module + diff --git a/trunk/modules/arch/netware/mod_echo.def b/trunk/modules/arch/netware/mod_echo.def new file mode 100644 index 0000000000..694135a52c --- /dev/null +++ b/trunk/modules/arch/netware/mod_echo.def @@ -0,0 +1,2 @@ +EXPORT echo_module + diff --git a/trunk/modules/arch/netware/mod_expires.def b/trunk/modules/arch/netware/mod_expires.def new file mode 100644 index 0000000000..bc416630b0 --- /dev/null +++ b/trunk/modules/arch/netware/mod_expires.def @@ -0,0 +1 @@ +EXPORT expires_module diff --git a/trunk/modules/arch/netware/mod_file_cache.def b/trunk/modules/arch/netware/mod_file_cache.def new file mode 100644 index 0000000000..8ab98cfb22 --- /dev/null +++ b/trunk/modules/arch/netware/mod_file_cache.def @@ -0,0 +1,2 @@ +EXPORT file_cache_module + diff --git a/trunk/modules/arch/netware/mod_headers.def b/trunk/modules/arch/netware/mod_headers.def new file mode 100644 index 0000000000..2fe35a858b --- /dev/null +++ b/trunk/modules/arch/netware/mod_headers.def @@ -0,0 +1 @@ +EXPORT headers_module diff --git a/trunk/modules/arch/netware/mod_info.def b/trunk/modules/arch/netware/mod_info.def new file mode 100644 index 0000000000..ce71cb37cf --- /dev/null +++ b/trunk/modules/arch/netware/mod_info.def @@ -0,0 +1 @@ +EXPORT info_module diff --git a/trunk/modules/arch/netware/mod_logio.def b/trunk/modules/arch/netware/mod_logio.def new file mode 100644 index 0000000000..68c708917c --- /dev/null +++ b/trunk/modules/arch/netware/mod_logio.def @@ -0,0 +1,2 @@ +EXPORT logio_module + diff --git a/trunk/modules/arch/netware/mod_mem_cache.def b/trunk/modules/arch/netware/mod_mem_cache.def new file mode 100644 index 0000000000..531d687154 --- /dev/null +++ b/trunk/modules/arch/netware/mod_mem_cache.def @@ -0,0 +1,3 @@ +IMPORT @mod_cache.imp +EXPORT mem_cache_module + diff --git a/trunk/modules/arch/netware/mod_mime_magic.def b/trunk/modules/arch/netware/mod_mime_magic.def new file mode 100644 index 0000000000..95307476de --- /dev/null +++ b/trunk/modules/arch/netware/mod_mime_magic.def @@ -0,0 +1 @@ +EXPORT mime_magic_module diff --git a/trunk/modules/arch/netware/mod_netware.c b/trunk/modules/arch/netware/mod_netware.c new file mode 100644 index 0000000000..f7fd0b0594 --- /dev/null +++ b/trunk/modules/arch/netware/mod_netware.c @@ -0,0 +1,194 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_buckets.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "util_script.h" +#include "mod_core.h" +#include "apr_optional.h" +#include "apr_lib.h" +#include "mod_cgi.h" + +#ifdef NETWARE + + +module AP_MODULE_DECLARE_DATA netware_module; + +typedef struct { + apr_table_t *file_type_handlers; /* CGI map from file types to CGI modules */ + apr_table_t *file_handler_mode; /* CGI module mode (spawn in same address space or not) */ + apr_table_t *extra_env_vars; /* Environment variables to be added to the CGI environment */ +} netware_dir_config; + + +static void *create_netware_dir_config(apr_pool_t *p, char *dir) +{ + netware_dir_config *new = (netware_dir_config*) apr_palloc(p, sizeof(netware_dir_config)); + + new->file_type_handlers = apr_table_make(p, 10); + new->file_handler_mode = apr_table_make(p, 10); + new->extra_env_vars = apr_table_make(p, 10); + + apr_table_set(new->file_type_handlers, "NLM", "OS"); + + return new; +} + +static void *merge_netware_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + netware_dir_config *base = (netware_dir_config *) basev; + netware_dir_config *add = (netware_dir_config *) addv; + netware_dir_config *new = (netware_dir_config *) apr_palloc(p, sizeof(netware_dir_config)); + + new->file_type_handlers = apr_table_overlay(p, add->file_type_handlers, base->file_type_handlers); + new->file_handler_mode = apr_table_overlay(p, add->file_handler_mode, base->file_handler_mode); + new->extra_env_vars = apr_table_overlay(p, add->extra_env_vars, base->extra_env_vars); + + return new; +} + +static const char *set_extension_map(cmd_parms *cmd, netware_dir_config *m, + char *CGIhdlr, char *ext, char *detach) +{ + int i, len; + + if (*ext == '.') + ++ext; + + if (CGIhdlr != NULL) { + len = strlen(CGIhdlr); + for (i=0; ifile_type_handlers, ext, CGIhdlr); + if (detach) { + apr_table_set(m->file_handler_mode, ext, "y"); + } + + return NULL; +} + +static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv, + request_rec *r, apr_pool_t *p, + cgi_exec_info_t *e_info) +{ + char *ext = NULL; + char *cmd_only, *ptr; + const char *new_cmd; + netware_dir_config *d; + apr_file_t *fh; + const char *args = ""; + + d = (netware_dir_config *)ap_get_module_config(r->per_dir_config, + &netware_module); + + if (e_info->process_cgi) { + /* Handle the complete file name, we DON'T want to follow suexec, since + * an unrooted command is as predictable as shooting craps in Win32. + * + * Notice that unlike most mime extension parsing, we have to use the + * win32 parsing here, therefore the final extension is the only one + * we will consider + */ + *cmd = r->filename; + if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) { + args = r->args; + } + } + + cmd_only = apr_pstrdup(p, *cmd); + e_info->cmd_type = APR_PROGRAM; + + /* truncate any arguments from the cmd */ + for (ptr = cmd_only; *ptr && (*ptr != ' '); ptr++); + *ptr = '\0'; + + /* Figure out what the extension is so that we can matche it. */ + ext = strrchr(apr_filepath_name_get(cmd_only), '.'); + + /* If there isn't an extension then give it an empty string */ + if (!ext) { + ext = ""; + } + + /* eliminate the '.' if there is one */ + if (*ext == '.') + ++ext; + + /* check if we have a registered command for the extension*/ + new_cmd = apr_table_get(d->file_type_handlers, ext); + e_info->detached = 1; + if (new_cmd == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Could not find a command associated with the %s extension", ext); + return APR_EBADF; + } + if (stricmp(new_cmd, "OS")) { + /* If we have a registered command then add the file that was passed in as a + parameter to the registered command. */ + *cmd = apr_pstrcat (p, new_cmd, " ", cmd_only, NULL); + + /* Run in its own address space if specified */ + if(apr_table_get(d->file_handler_mode, ext)) + e_info->addrspace = 1; + } + + /* Tokenize the full command string into its arguments */ + apr_tokenize_to_argv(*cmd, (char***)argv, p); + + /* The first argument should be the executible */ + *cmd = ap_server_root_relative(p, *argv[0]); + + return APR_SUCCESS; +} + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command); +} + +static const command_rec netware_cmds[] = { +AP_INIT_TAKE23("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO, + "Full path to the CGI NLM module followed by a file extension. If the " + "first parameter is set to \"OS\" then the following file extension is " + "treated as NLM. The optional parameter \"detach\" can be specified if " + "the NLM should be launched in its own address space."), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA netware_module = { + STANDARD20_MODULE_STUFF, + create_netware_dir_config, /* create per-dir config */ + merge_netware_dir_configs, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + netware_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + +#endif diff --git a/trunk/modules/arch/netware/mod_nw_ssl.c b/trunk/modules/arch/netware/mod_nw_ssl.c new file mode 100644 index 0000000000..93cda08be7 --- /dev/null +++ b/trunk/modules/arch/netware/mod_nw_ssl.c @@ -0,0 +1,1276 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_tls.c - Apache SSL/TLS module for NetWare by Mike Gardiner. + * + * This module gives Apache the ability to do SSL/TLS with a minimum amount + * of effort. All of the SSL/TLS logic is already on NetWare versions 5 and + * above and is interfaced through WinSock on NetWare. As you can see in + * the code below SSL/TLS sockets can be created with three WinSock calls. + * + * To load, simply place the module in the modules directory under the main + * apache tree. Then add a "SecureListen" with two arguments. The first + * argument is an address and/or port. The second argument is the key pair + * name as created in ConsoleOne. + * + * Examples: + * + * SecureListen 443 "SSL CertificateIP" + * SecureListen 123.45.67.89:443 mycert + */ + +#define WS_SSL + +#define MAX_ADDRESS 512 +#define MAX_KEY 80 + + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_core.h" +#include "ap_listen.h" +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_optional.h" + +#include + +#ifndef SO_TLS_UNCLEAN_SHUTDOWN +#define SO_TLS_UNCLEAN_SHUTDOWN 0 +#endif + +/* The ssl_var_lookup() optional function retrieves SSL environment + * variables. */ +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, + char *)); + +/* An optional function which returns non-zero if the given connection + * is using SSL/TLS. */ +APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); + +/* The ssl_proxy_enable() and ssl_engine_disable() optional functions + * are used by mod_proxy to enable use of SSL for outgoing + * connections. */ +APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); +APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); + +#define strEQ(s1,s2) (strcmp(s1,s2) == 0) +#define strNE(s1,s2) (strcmp(s1,s2) != 0) +#define strEQn(s1,s2,n) (strncmp(s1,s2,n) == 0) +#define strNEn(s1,s2,n) (strncmp(s1,s2,n) != 0) + +#define strcEQ(s1,s2) (strcasecmp(s1,s2) == 0) +#define strcNE(s1,s2) (strcasecmp(s1,s2) != 0) +#define strcEQn(s1,s2,n) (strncasecmp(s1,s2,n) == 0) +#define strcNEn(s1,s2,n) (strncasecmp(s1,s2,n) != 0) + +#define strIsEmpty(s) (s == NULL || s[0] == NUL) + + +module AP_MODULE_DECLARE_DATA nwssl_module; + +typedef struct NWSSLSrvConfigRec NWSSLSrvConfigRec; +typedef struct seclisten_rec seclisten_rec; +typedef struct seclistenup_rec seclistenup_rec; +typedef struct secsocket_data secsocket_data; + +struct seclisten_rec { + seclisten_rec *next; + struct sockaddr_in local_addr; /* local IP address and port */ + int fd; + int used; /* Only used during restart */ + char key[MAX_KEY]; + int mutual; + char *addr; + apr_port_t port; +}; + +struct seclistenup_rec { + seclistenup_rec *next; + char key[MAX_KEY]; + char *addr; + apr_port_t port; +}; + +struct NWSSLSrvConfigRec { + apr_table_t *sltable; + apr_table_t *slutable; + apr_pool_t *pPool; +}; + +struct secsocket_data { + apr_socket_t* csd; + int is_secure; +}; + +static apr_array_header_t *certlist = NULL; +static unicode_t** certarray = NULL; +static int numcerts = 0; +static seclisten_rec* ap_seclisteners = NULL; +static seclistenup_rec* ap_seclistenersup = NULL; + +static ap_listen_rec *nw_old_listeners; + +#define get_nwssl_cfg(srv) (NWSSLSrvConfigRec *) ap_get_module_config(srv->module_config, &nwssl_module) + + +static void build_cert_list (apr_pool_t *p) +{ + int i; + char **rootcerts = (char **)certlist->elts; + + numcerts = certlist->nelts; + certarray = apr_palloc(p, sizeof(unicode_t*)*numcerts); + + for (i = 0; i < numcerts; ++i) { + unicode_t *unistr; + unistr = (unicode_t*)apr_palloc(p, strlen(rootcerts[i])*4); + loc2uni (UNI_LOCAL_DEFAULT, unistr, rootcerts[i], 0, 2); + certarray[i] = unistr; + } +} + +/* + * Parses a host of the form
    [:port] + * :port is permitted if 'port' is not NULL + */ +static unsigned long parse_addr(const char *w, unsigned short *ports) +{ + struct hostent *hep; + unsigned long my_addr; + char *p; + + p = strchr(w, ':'); + if (ports != NULL) { + *ports = 0; + if (p != NULL && strcmp(p + 1, "*") != 0) + *ports = atoi(p + 1); + } + + if (p != NULL) + *p = '\0'; + if (strcmp(w, "*") == 0) { + if (p != NULL) + *p = ':'; + return htonl(INADDR_ANY); + } + + my_addr = apr_inet_addr((char *)w); + if (my_addr != INADDR_NONE) { + if (p != NULL) + *p = ':'; + return my_addr; + } + + hep = gethostbyname(w); + + if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) { + /* XXX Should be echoing by h_errno the actual failure, no? + * ap_log_error would be good here. Better yet - APRize. + */ + fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w); + exit(1); + } + + if (hep->h_addr_list[1]) { + fprintf(stderr, "Host %s has multiple addresses ---\n", w); + fprintf(stderr, "you must choose one explicitly for use as\n"); + fprintf(stderr, "a secure port. Exiting!!!\n"); + exit(1); + } + + if (p != NULL) + *p = ':'; + + return ((struct in_addr *) (hep->h_addr))->s_addr; +} + +static int find_secure_listener(seclisten_rec *lr) +{ + seclisten_rec *sl; + + for (sl = ap_seclisteners; sl; sl = sl->next) { + if (!memcmp(&sl->local_addr, &lr->local_addr, sizeof(sl->local_addr))) { + sl->used = 1; + return sl->fd; + } + } + return -1; +} + +static char *get_port_key(conn_rec *c) +{ + seclistenup_rec *sl; + + for (sl = ap_seclistenersup; sl; sl = sl->next) { + if ((sl->port == (c->local_addr)->port) && + ((strcmp(sl->addr, "0.0.0.0") == 0) || (strcmp(sl->addr, c->local_ip) == 0))) { + return sl->key; + } + } + return NULL; +} + +static int make_secure_socket(apr_pool_t *pconf, const struct sockaddr_in *server, + char* key, int mutual, server_rec *sconf) +{ + int s; + int one = 1; + char addr[MAX_ADDRESS]; + struct sslserveropts opts; + unsigned int optParam; + WSAPROTOCOL_INFO SecureProtoInfo; + int no = 1; + + if (server->sin_addr.s_addr != htonl(INADDR_ANY)) + apr_snprintf(addr, sizeof(addr), "address %s port %d", + inet_ntoa(server->sin_addr), ntohs(server->sin_port)); + else + apr_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port)); + + /* note that because we're about to slack we don't use psocket */ + memset(&SecureProtoInfo, 0, sizeof(WSAPROTOCOL_INFO)); + + SecureProtoInfo.iAddressFamily = AF_INET; + SecureProtoInfo.iSocketType = SOCK_STREAM; + SecureProtoInfo.iProtocol = IPPROTO_TCP; + SecureProtoInfo.iSecurityScheme = SECURITY_PROTOCOL_SSL; + + s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, + (LPWSAPROTOCOL_INFO)&SecureProtoInfo, 0, 0); + + if (s == INVALID_SOCKET) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: failed to get a socket for %s", + addr); + return -1; + } + + if (!mutual) { + optParam = SO_SSL_ENABLE | SO_SSL_SERVER; + + if (WSAIoctl(s, SO_SSL_SET_FLAGS, (char *)&optParam, + sizeof(optParam), NULL, 0, NULL, NULL, NULL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_FLAGS)", addr); + return -1; + } + } + + opts.cert = key; + opts.certlen = strlen(key); + opts.sidtimeout = 0; + opts.sidentries = 0; + opts.siddir = NULL; + + if (WSAIoctl(s, SO_SSL_SET_SERVER, (char *)&opts, sizeof(opts), + NULL, 0, NULL, NULL, NULL) != 0) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_SERVER)", addr); + return -1; + } + + if (mutual) { + optParam = 0x07; // SO_SSL_AUTH_CLIENT + + if(WSAIoctl(s, SO_SSL_SET_FLAGS, (char*)&optParam, + sizeof(optParam), NULL, 0, NULL, NULL, NULL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_FLAGS)", addr); + return -1; + } + } + + optParam = SO_TLS_UNCLEAN_SHUTDOWN; + WSAIoctl(s, SO_SSL_SET_FLAGS, (char *)&optParam, sizeof(optParam), + NULL, 0, NULL, NULL, NULL); + + return s; +} + +int convert_secure_socket(conn_rec *c, apr_socket_t *csd) +{ + int rcode; + struct tlsclientopts sWS2Opts; + struct nwtlsopts sNWTLSOpts; + struct sslserveropts opts; + unsigned long ulFlags; + SOCKET sock; + unicode_t keyFileName[60]; + + apr_os_sock_get(&sock, csd); + + /* zero out buffers */ + memset((char *)&sWS2Opts, 0, sizeof(struct tlsclientopts)); + memset((char *)&sNWTLSOpts, 0, sizeof(struct nwtlsopts)); + + /* turn on ssl for the socket */ + ulFlags = (numcerts ? SO_TLS_ENABLE : SO_TLS_ENABLE | SO_TLS_BLIND_ACCEPT); + rcode = WSAIoctl(sock, SO_TLS_SET_FLAGS, &ulFlags, sizeof(unsigned long), + NULL, 0, NULL, NULL, NULL); + if (SOCKET_ERROR == rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, + "Error: %d with ioctlsocket(flag SO_TLS_ENABLE)", WSAGetLastError()); + return rcode; + } + + ulFlags = SO_TLS_UNCLEAN_SHUTDOWN; + WSAIoctl(sock, SO_TLS_SET_FLAGS, &ulFlags, sizeof(unsigned long), + NULL, 0, NULL, NULL, NULL); + + /* setup the socket for SSL */ + memset (&sWS2Opts, 0, sizeof(sWS2Opts)); + memset (&sNWTLSOpts, 0, sizeof(sNWTLSOpts)); + sWS2Opts.options = &sNWTLSOpts; + + if (numcerts) { + sNWTLSOpts.walletProvider = WAL_PROV_DER; //the wallet provider defined in wdefs.h + sNWTLSOpts.TrustedRootList = certarray; //array of certs in UNICODE format + sNWTLSOpts.numElementsInTRList = numcerts; //number of certs in TRList + } + else { + /* setup the socket for SSL */ + unicpy(keyFileName, L"SSL CertificateIP"); + sWS2Opts.wallet = keyFileName; /* no client certificate */ + sWS2Opts.walletlen = unilen(keyFileName); + + sNWTLSOpts.walletProvider = WAL_PROV_KMO; //the wallet provider defined in wdefs.h + } + + /* make the IOCTL call */ + rcode = WSAIoctl(sock, SO_TLS_SET_CLIENT, &sWS2Opts, + sizeof(struct tlsclientopts), NULL, 0, NULL, + NULL, NULL); + + /* make sure that it was successfull */ + if(SOCKET_ERROR == rcode ){ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, + "Error: %d with ioctl (SO_TLS_SET_CLIENT)", WSAGetLastError()); + } + return rcode; +} + +int SSLize_Socket(SOCKET socketHnd, char *key, request_rec *r) +{ + int rcode; + struct tlsserveropts sWS2Opts; + struct nwtlsopts sNWTLSOpts; + unicode_t SASKey[512]; + unsigned long ulFlag; + + memset((char *)&sWS2Opts, 0, sizeof(struct tlsserveropts)); + memset((char *)&sNWTLSOpts, 0, sizeof(struct nwtlsopts)); + + + ulFlag = SO_TLS_ENABLE; + rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long), NULL, 0, NULL, NULL, NULL); + if(rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_ENABLE)", WSAGetLastError()); + goto ERR; + } + + + ulFlag = SO_TLS_SERVER; + rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long),NULL, 0, NULL, NULL, NULL); + + if(rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_SERVER)", WSAGetLastError()); + goto ERR; + } + + loc2uni(UNI_LOCAL_DEFAULT, SASKey, key, 0, 0); + + //setup the tlsserveropts struct + sWS2Opts.wallet = SASKey; + sWS2Opts.walletlen = unilen(SASKey); + sWS2Opts.sidtimeout = 0; + sWS2Opts.sidentries = 0; + sWS2Opts.siddir = NULL; + sWS2Opts.options = &sNWTLSOpts; + + //setup the nwtlsopts structure + + sNWTLSOpts.walletProvider = WAL_PROV_KMO; + sNWTLSOpts.keysList = NULL; + sNWTLSOpts.numElementsInKeyList = 0; + sNWTLSOpts.reservedforfutureuse = NULL; + sNWTLSOpts.reservedforfutureCRL = NULL; + sNWTLSOpts.reservedforfutureCRLLen = 0; + sNWTLSOpts.reserved1 = NULL; + sNWTLSOpts.reserved2 = NULL; + sNWTLSOpts.reserved3 = NULL; + + + rcode = WSAIoctl(socketHnd, + SO_TLS_SET_SERVER, + &sWS2Opts, + sizeof(struct tlsserveropts), + NULL, + 0, + NULL, + NULL, + NULL); + if(SOCKET_ERROR == rcode) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_SERVER)", WSAGetLastError()); + goto ERR; + } + +ERR: + return rcode; +} + +static const char *set_secure_listener(cmd_parms *cmd, void *dummy, + const char *ips, const char* key, + const char* mutual) +{ + NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + char *ports, *addr; + unsigned short port; + seclisten_rec *new; + ap_listen_rec **walk; + apr_sockaddr_t *sa; + int found_listener = 0; + + + if (err != NULL) + return err; + + ports = strchr(ips, ':'); + + if (ports != NULL) { + if (ports == ips) + return "Missing IP address"; + else if (ports[1] == '\0') + return "Address must end in :"; + + *(ports++) = '\0'; + } + else { + ports = (char*)ips; + } + + new = apr_pcalloc(cmd->server->process->pool, sizeof(seclisten_rec)); + new->local_addr.sin_family = AF_INET; + + if (ports == ips) { + new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr = apr_pstrdup(cmd->server->process->pool, "0.0.0.0"); + } + else { + new->local_addr.sin_addr.s_addr = parse_addr(ips, NULL); + addr = apr_pstrdup(cmd->server->process->pool, ips); + } + + port = atoi(ports); + + if (!port) + return "Port must be numeric"; + + /* If the specified addr:port was created previously, put the listen + socket record back on the ap_listeners list so that the socket + will be reused rather than recreated */ + for (walk = &nw_old_listeners; *walk;) { + sa = (*walk)->bind_addr; + if (sa) { + ap_listen_rec *new; + apr_port_t oldport; + + oldport = sa->port; + /* If both ports are equivalent, then if their names are equivalent, + * then we will re-use the existing record. + */ + if (port == oldport && + ((!addr && !sa->hostname) || + ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { + new = *walk; + *walk = new->next; + new->next = ap_listeners; + ap_listeners = new; + found_listener = 1; + continue; + } + } + + walk = &(*walk)->next; + } + + /* If we found a pre-existing listen socket record, then there + is no need to create a new secure listen socket record. */ + if (found_listener) { + return NULL; + } + + apr_table_add(sc->sltable, ports, addr); + + new->local_addr.sin_port = htons(port); + new->fd = -1; + new->used = 0; + new->next = ap_seclisteners; + strcpy(new->key, key); + new->mutual = (mutual) ? 1 : 0; + new->addr = addr; + new->port = port; + ap_seclisteners = new; + return NULL; +} + +static const char *set_secure_upgradeable_listener(cmd_parms *cmd, void *dummy, + const char *ips, const char* key) +{ + NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server); + seclistenup_rec *listen_node; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + char *ports, *addr; + unsigned short port; + seclistenup_rec *new; + + if (err != NULL) + return err; + + ports = strchr(ips, ':'); + + if (ports != NULL) { + if (ports == ips) + return "Missing IP address"; + else if (ports[1] == '\0') + return "Address must end in :"; + + *(ports++) = '\0'; + } + else { + ports = (char*)ips; + } + + if (ports == ips) { + addr = apr_pstrdup(cmd->pool, "0.0.0.0"); + } + else { + addr = apr_pstrdup(cmd->pool, ips); + } + + port = atoi(ports); + + if (!port) + return "Port must be numeric"; + + apr_table_set(sc->slutable, ports, addr); + + new = apr_pcalloc(cmd->pool, sizeof(seclistenup_rec)); + new->next = ap_seclistenersup; + strcpy(new->key, key); + new->addr = addr; + new->port = port; + ap_seclistenersup = new; + + return err; +} + +static apr_status_t nwssl_socket_cleanup(void *data) +{ + ap_listen_rec* slr = (ap_listen_rec*)data; + ap_listen_rec* lr; + + /* Remove our secure listener from the listener list */ + for (lr = ap_listeners; lr; lr = lr->next) { + /* slr is at the head of the list */ + if (lr == slr) { + ap_listeners = slr->next; + break; + } + /* slr is somewhere in between or at the end*/ + if (lr->next == slr) { + lr->next = slr->next; + break; + } + } + return APR_SUCCESS; +} + +static const char *set_trusted_certs(cmd_parms *cmd, void *dummy, char *arg) +{ + char **ptr = (char **)apr_array_push(certlist); + + *ptr = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +static int nwssl_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + seclisten_rec* ap_old_seclisteners; + char *ports, *addr; + unsigned short port; + ap_listen_rec **walk; + seclisten_rec **secwalk; + apr_sockaddr_t *sa; + int found; + + /* Pull all of the listeners that were created by mod_nw_ssl out of the + ap_listeners list so that the normal listen socket processing does + automatically close them */ + nw_old_listeners = NULL; + ap_old_seclisteners = NULL; + + for (secwalk = &ap_seclisteners; *secwalk;) { + found = 0; + for (walk = &ap_listeners; *walk;) { + sa = (*walk)->bind_addr; + if (sa) { + ap_listen_rec *new; + seclisten_rec *secnew; + apr_port_t oldport; + + oldport = sa->port; + /* If both ports are equivalent, then if their names are equivalent, + * then we will re-use the existing record. + */ + if ((*secwalk)->port == oldport && + ((!(*secwalk)->addr && !sa->hostname) || + (((*secwalk)->addr && sa->hostname) && !strcmp(sa->hostname, (*secwalk)->addr)))) { + /* Move the listen socket from ap_listeners to nw_old_listeners */ + new = *walk; + *walk = new->next; + new->next = nw_old_listeners; + nw_old_listeners = new; + + /* Move the secure socket record to ap_old_seclisterners */ + secnew = *secwalk; + *secwalk = secnew->next; + secnew->next = ap_old_seclisteners; + ap_old_seclisteners = secnew; + found = 1; + break; + } + } + + walk = &(*walk)->next; + } + if (!found && &(*secwalk)->next) { + secwalk = &(*secwalk)->next; + } + } + + /* Restore the secure socket records list so that the post config can + process all of the sockets normally */ + ap_seclisteners = ap_old_seclisteners; + ap_seclistenersup = NULL; + certlist = apr_array_make(pconf, 1, sizeof(char *)); + + /* Now that we have removed all of the mod_nw_ssl created socket records, + allow the normal listen socket handling to occur. + NOTE: If for any reason mod_nw_ssl is removed as a built-in module, + the following call must be put back into the pre-config handler of the + MPM. It is only here to ensure that mod_nw_ssl fixes up the listen + socket list before anything else looks at it. */ + ap_listen_pre_config(); + + return OK; +} + +static int nwssl_pre_connection(conn_rec *c, void *csd) +{ + + if (apr_table_get(c->notes, "nwconv-ssl")) { + convert_secure_socket(c, (apr_socket_t*)csd); + } + else { + secsocket_data *csd_data = apr_palloc(c->pool, sizeof(secsocket_data)); + + csd_data->csd = (apr_socket_t*)csd; + csd_data->is_secure = 0; + ap_set_module_config(c->conn_config, &nwssl_module, (void*)csd_data); + } + + return OK; +} + +static int nwssl_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + seclisten_rec* sl; + ap_listen_rec* lr; + apr_socket_t* sd; + apr_status_t status; + seclistenup_rec *slu; + int found; + ap_listen_rec *walk; + seclisten_rec *secwalk, *lastsecwalk; + apr_sockaddr_t *sa; + int found_listener = 0; + + /* Walk the old listeners list and compare it to the secure + listeners list and remove any secure listener records that + are not being reused */ + for (walk = nw_old_listeners; walk; walk = walk->next) { + sa = walk->bind_addr; + if (sa) { + ap_listen_rec *new; + apr_port_t oldport; + + oldport = sa->port; + for (secwalk = ap_seclisteners, lastsecwalk = ap_seclisteners; secwalk; secwalk = lastsecwalk->next) { + unsigned short port = secwalk->port; + char *addr = secwalk->addr; + /* If both ports are equivalent, then if their names are equivalent, + * then we will re-use the existing record. + */ + if (port == oldport && + ((!addr && !sa->hostname) || + ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { + if (secwalk == ap_seclisteners) { + ap_seclisteners = secwalk->next; + } + else { + lastsecwalk->next = secwalk->next; + } + apr_socket_close(walk->sd); + walk->active = 0; + break; + } + else { + lastsecwalk = secwalk; + } + } + } + } + + for (sl = ap_seclisteners; sl != NULL; sl = sl->next) { + /* If we find a pre-existing listen socket and it has already been + created, then no neeed to go any further, just reuse it. */ + if (((sl->fd = find_secure_listener(sl)) >= 0) && (sl->used)) { + continue; + } + + if (sl->fd < 0) + sl->fd = make_secure_socket(s->process->pool, &sl->local_addr, sl->key, sl->mutual, s); + + if (sl->fd >= 0) { + apr_os_sock_info_t sock_info; + + sock_info.os_sock = &(sl->fd); + sock_info.local = (struct sockaddr*)&(sl->local_addr); + sock_info.remote = NULL; + sock_info.family = APR_INET; + sock_info.type = SOCK_STREAM; + + apr_os_sock_make(&sd, &sock_info, s->process->pool); + + lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec)); + + if (lr) { + lr->sd = sd; + if ((status = apr_sockaddr_info_get(&lr->bind_addr, sl->addr, APR_UNSPEC, sl->port, 0, + s->process->pool)) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, status, pconf, + "alloc_listener: failed to set up sockaddr for %s:%d", sl->addr, sl->port); + return HTTP_INTERNAL_SERVER_ERROR; + } + lr->next = ap_listeners; + ap_listeners = lr; + apr_pool_cleanup_register(s->process->pool, lr, nwssl_socket_cleanup, apr_pool_cleanup_null); + } + } else { + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + for (slu = ap_seclistenersup; slu; slu = slu->next) { + /* Check the listener list for a matching upgradeable listener */ + found = 0; + for (lr = ap_listeners; lr; lr = lr->next) { + if (slu->port == lr->bind_addr->port) { + found = 1; + break; + } + } + if (!found) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, plog, + "No Listen directive found for upgradeable listener %s:%d", slu->addr, slu->port); + } + } + + build_cert_list(s->process->pool); + + return OK; +} + +static void *nwssl_config_server_create(apr_pool_t *p, server_rec *s) +{ + NWSSLSrvConfigRec *new = apr_palloc(p, sizeof(NWSSLSrvConfigRec)); + new->sltable = apr_table_make(p, 5); + new->slutable = apr_table_make(p, 5); + return new; +} + +static void *nwssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) +{ + NWSSLSrvConfigRec *base = (NWSSLSrvConfigRec *)basev; + NWSSLSrvConfigRec *add = (NWSSLSrvConfigRec *)addv; + NWSSLSrvConfigRec *merged = (NWSSLSrvConfigRec *)apr_palloc(p, sizeof(NWSSLSrvConfigRec)); + return merged; +} + +static int compare_ipports(void *rec, const char *key, const char *value) +{ + conn_rec *c = (conn_rec*)rec; + + if (value && + ((strcmp(value, "0.0.0.0") == 0) || (strcmp(value, c->local_ip) == 0))) + { + return 0; + } + return 1; +} + +static int isSecureConnEx (const server_rec *s, const conn_rec *c, const apr_table_t *t) +{ + char port[8]; + + itoa((c->local_addr)->port, port, 10); + if (!apr_table_do(compare_ipports, (void*)c, t, port, NULL)) + { + return 1; + } + + return 0; +} + +static int isSecureConn (const server_rec *s, const conn_rec *c) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(s); + + return isSecureConnEx (s, c, sc->sltable); +} + +static int isSecureConnUpgradeable (const server_rec *s, const conn_rec *c) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(s); + + return isSecureConnEx (s, c, sc->slutable); +} + +static int isSecure (const request_rec *r) +{ + return isSecureConn (r->server, r->connection); +} + +static int isSecureUpgradeable (const request_rec *r) +{ + return isSecureConnUpgradeable (r->server, r->connection); +} + +static int isSecureUpgraded (const request_rec *r) +{ + secsocket_data *csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module); + + return csd_data->is_secure; +} + +static int nwssl_hook_Fixup(request_rec *r) +{ + int i; + + if (!isSecure(r) && !isSecureUpgraded(r)) + return DECLINED; + + apr_table_set(r->subprocess_env, "HTTPS", "on"); + + return DECLINED; +} + +static const char *nwssl_hook_http_scheme(const request_rec *r) +{ + if (isSecure(r) && !isSecureUpgraded(r)) + return "https"; + + return NULL; +} + +static apr_port_t nwssl_hook_default_port(const request_rec *r) +{ + if (isSecure(r)) + return DEFAULT_HTTPS_PORT; + + return 0; +} + +int ssl_proxy_enable(conn_rec *c) +{ + apr_table_set(c->notes, "nwconv-ssl", "Y"); + + return 1; +} + +int ssl_engine_disable(conn_rec *c) +{ + return 1; +} + +static int ssl_is_https(conn_rec *c) +{ + secsocket_data *csd_data = (secsocket_data*)ap_get_module_config(c->conn_config, &nwssl_module); + + return isSecureConn (c->base_server, c) || (csd_data && csd_data->is_secure); +} + +/* This function must remain safe to use for a non-SSL connection. */ +char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, char *var) +{ + NWSSLSrvConfigRec *mc = get_nwssl_cfg(s); + const char *result; + BOOL resdup; + apr_time_exp_t tm; + + result = NULL; + resdup = TRUE; + + /* + * When no pool is given try to find one + */ + if (p == NULL) { + if (r != NULL) + p = r->pool; + else if (c != NULL) + p = c->pool; + else + p = mc->pPool; + } + + /* + * Request dependent stuff + */ + if (r != NULL) { + switch (var[0]) { + case 'H': + case 'h': + if (strcEQ(var, "HTTP_USER_AGENT")) + result = apr_table_get(r->headers_in, "User-Agent"); + else if (strcEQ(var, "HTTP_REFERER")) + result = apr_table_get(r->headers_in, "Referer"); + else if (strcEQ(var, "HTTP_COOKIE")) + result = apr_table_get(r->headers_in, "Cookie"); + else if (strcEQ(var, "HTTP_FORWARDED")) + result = apr_table_get(r->headers_in, "Forwarded"); + else if (strcEQ(var, "HTTP_HOST")) + result = apr_table_get(r->headers_in, "Host"); + else if (strcEQ(var, "HTTP_PROXY_CONNECTION")) + result = apr_table_get(r->headers_in, "Proxy-Connection"); + else if (strcEQ(var, "HTTP_ACCEPT")) + result = apr_table_get(r->headers_in, "Accept"); + else if (strcEQ(var, "HTTPS")) { + if (isSecure(r) || isSecureUpgraded(r)) + result = "on"; + else + result = "off"; + } + else if (strlen(var) > 5 && strcEQn(var, "HTTP:", 5)) + /* all other headers from which we are still not know about */ + result = apr_table_get(r->headers_in, var+5); + break; + + case 'R': + case 'r': + if (strcEQ(var, "REQUEST_METHOD")) + result = r->method; + else if (strcEQ(var, "REQUEST_SCHEME")) + result = ap_http_scheme(r); + else if (strcEQ(var, "REQUEST_URI")) + result = r->uri; + else if (strcEQ(var, "REQUEST_FILENAME")) + result = r->filename; + else if (strcEQ(var, "REMOTE_HOST")) + result = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME, NULL); + else if (strcEQ(var, "REMOTE_IDENT")) + result = ap_get_remote_logname(r); + else if (strcEQ(var, "REMOTE_USER")) + result = r->user; + break; + + case 'S': + case 's': + if (strcEQn(var, "SSL", 3)) break; /* shortcut common case */ + + if (strcEQ(var, "SERVER_ADMIN")) + result = r->server->server_admin; + else if (strcEQ(var, "SERVER_NAME")) + result = ap_get_server_name(r); + else if (strcEQ(var, "SERVER_PORT")) + result = apr_psprintf(p, "%u", ap_get_server_port(r)); + else if (strcEQ(var, "SERVER_PROTOCOL")) + result = r->protocol; + else if (strcEQ(var, "SCRIPT_FILENAME")) + result = r->filename; + break; + + default: + if (strcEQ(var, "PATH_INFO")) + result = r->path_info; + else if (strcEQ(var, "QUERY_STRING")) + result = r->args; + else if (strcEQ(var, "IS_SUBREQ")) + result = (r->main != NULL ? "true" : "false"); + else if (strcEQ(var, "DOCUMENT_ROOT")) + result = ap_document_root(r); + else if (strcEQ(var, "AUTH_TYPE")) + result = r->ap_auth_type; + else if (strcEQ(var, "THE_REQUEST")) + result = r->the_request; + break; + } + } + + /* + * Connection stuff + */ + if (result == NULL && c != NULL) { + + /* XXX-Can't get specific SSL info from NetWare */ + /* SSLConnRec *sslconn = myConnConfig(c); + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4) + && sslconn && sslconn->ssl) + result = ssl_var_lookup_ssl(p, c, var+4);*/ + + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)) + result = NULL; + else if (strcEQ(var, "REMOTE_ADDR")) + result = c->remote_ip; + } + + /* + * Totally independent stuff + */ + if (result == NULL) { + if (strlen(var) > 12 && strcEQn(var, "SSL_VERSION_", 12)) + result = NULL; + /* XXX-Can't get specific SSL info from NetWare */ + /*result = ssl_var_lookup_ssl_version(p, var+12);*/ + else if (strcEQ(var, "SERVER_SOFTWARE")) + result = ap_get_server_version(); + else if (strcEQ(var, "API_VERSION")) { + result = apr_itoa(p, MODULE_MAGIC_NUMBER); + resdup = FALSE; + } + else if (strcEQ(var, "TIME_YEAR")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, "%02d%02d", + (tm.tm_year / 100) + 19, tm.tm_year % 100); + resdup = FALSE; + } +#define MKTIMESTR(format, tmfield) \ + apr_time_exp_lt(&tm, apr_time_now()); \ + result = apr_psprintf(p, format, tm.tmfield); \ + resdup = FALSE; + else if (strcEQ(var, "TIME_MON")) { + MKTIMESTR("%02d", tm_mon+1) + } + else if (strcEQ(var, "TIME_DAY")) { + MKTIMESTR("%02d", tm_mday) + } + else if (strcEQ(var, "TIME_HOUR")) { + MKTIMESTR("%02d", tm_hour) + } + else if (strcEQ(var, "TIME_MIN")) { + MKTIMESTR("%02d", tm_min) + } + else if (strcEQ(var, "TIME_SEC")) { + MKTIMESTR("%02d", tm_sec) + } + else if (strcEQ(var, "TIME_WDAY")) { + MKTIMESTR("%d", tm_wday) + } + else if (strcEQ(var, "TIME")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, + "%02d%02d%02d%02d%02d%02d%02d", (tm.tm_year / 100) + 19, + (tm.tm_year % 100), tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + resdup = FALSE; + } + /* all other env-variables from the parent Apache process */ + else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) { + result = apr_table_get(r->notes, var+4); + if (result == NULL) + result = apr_table_get(r->subprocess_env, var+4); + if (result == NULL) + result = getenv(var+4); + } + } + + if (result != NULL && resdup) + result = apr_pstrdup(p, result); + if (result == NULL) + result = ""; + return (char *)result; +} + +#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols" +#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1" +#define CONNECTION_HEADER "Connection: Upgrade" + +static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, + apr_bucket_brigade *bb) + +{ + const char *upgrade; + apr_bucket_brigade *upgradebb; + request_rec *r = f->r; + apr_socket_t *csd = NULL; + char *key; + int ret; + secsocket_data *csd_data; + apr_bucket *b; + apr_status_t rv; + + /* Just remove the filter, if it doesn't work the first time, it won't + * work at all for this request. + */ + ap_remove_output_filter(f); + + /* No need to ensure that this is a server with optional SSL, the filter + * is only inserted if that is true. + */ + + upgrade = apr_table_get(r->headers_in, "Upgrade"); + if (upgrade == NULL + || strcmp(ap_getword(r->pool, &upgrade, ','), "TLS/1.0")) { + /* "Upgrade: TLS/1.0, ..." header not found, don't do Upgrade */ + return ap_pass_brigade(f->next, bb); + } + + apr_table_unset(r->headers_out, "Upgrade"); + + if (r) { + csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module); + csd = csd_data->csd; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Unable to get upgradeable socket handle"); + return ap_pass_brigade(f->next, bb); + } + + + /* Send the interim 101 response. */ + upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc); + + ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF, + UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL); + + b = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(upgradebb, b); + + rv = ap_pass_brigade(f->next, upgradebb); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "could not send interim 101 Upgrade response"); + return AP_FILTER_ERROR; + } + + key = get_port_key(r->connection); + + if (csd && key) { + int sockdes; + apr_os_sock_get(&sockdes, csd); + + + ret = SSLize_Socket(sockdes, key, r); + if (!ret) { + csd_data->is_secure = 1; + } + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Upgradeable socket handle not found"); + return AP_FILTER_ERROR; + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Awaiting re-negotiation handshake"); + + /* Now that we have initialized the ssl connection which added the ssl_io_filter, + pass the brigade off to the connection based output filters so that the + request can complete encrypted */ + return ap_pass_brigade(f->c->output_filters, bb); +} + +static void ssl_hook_Insert_Filter(request_rec *r) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(r->server); + + if (isSecureUpgradeable (r)) { + ap_add_output_filter("UPGRADE_FILTER", NULL, r, r->connection); + } +} + +static const command_rec nwssl_module_cmds[] = +{ + AP_INIT_TAKE23("SecureListen", set_secure_listener, NULL, RSRC_CONF, + "specify an address and/or port with a key pair name.\n" + "Optional third parameter of MUTUAL configures the port for mutual authentication."), + AP_INIT_TAKE2("NWSSLUpgradeable", set_secure_upgradeable_listener, NULL, RSRC_CONF, + "specify an address and/or port with a key pair name, that can be upgraded to an SSL connection.\n" + "The address and/or port must have already be defined using a Listen directive."), + AP_INIT_ITERATE("NWSSLTrustedCerts", set_trusted_certs, NULL, RSRC_CONF, + "Adds trusted certificates that are used to create secure connections to proxied servers"), + {NULL} +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_output_filter ("UPGRADE_FILTER", ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); + + ap_hook_pre_config(nwssl_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_connection(nwssl_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(nwssl_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_fixups(nwssl_hook_Fixup, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_http_scheme(nwssl_hook_http_scheme, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_default_port(nwssl_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter(ssl_hook_Insert_Filter, NULL, NULL, APR_HOOK_MIDDLE); + + APR_REGISTER_OPTIONAL_FN(ssl_is_https); + APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); + + APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); + APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); +} + +module AP_MODULE_DECLARE_DATA nwssl_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + nwssl_config_server_create, /* server config */ + nwssl_config_server_merge, /* merge server config */ + nwssl_module_cmds, /* command apr_table_t */ + register_hooks +}; + diff --git a/trunk/modules/arch/netware/mod_proxy.def b/trunk/modules/arch/netware/mod_proxy.def new file mode 100644 index 0000000000..ab02a53c73 --- /dev/null +++ b/trunk/modules/arch/netware/mod_proxy.def @@ -0,0 +1,6 @@ +EXPORT proxy_module +EXPORT proxy_hook_scheme_handler +EXPORT proxy_hook_canon_handler +EXPORT ap_proxy_ssl_enable +EXPORT ap_proxy_ssl_disable +EXPORT proxy_run_fixups diff --git a/trunk/modules/arch/netware/mod_proxy_connect.def b/trunk/modules/arch/netware/mod_proxy_connect.def new file mode 100644 index 0000000000..136111408b --- /dev/null +++ b/trunk/modules/arch/netware/mod_proxy_connect.def @@ -0,0 +1,4 @@ +EXPORT proxy_connect_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_hook_canon_handler diff --git a/trunk/modules/arch/netware/mod_proxy_ftp.def b/trunk/modules/arch/netware/mod_proxy_ftp.def new file mode 100644 index 0000000000..f2dba7d6c5 --- /dev/null +++ b/trunk/modules/arch/netware/mod_proxy_ftp.def @@ -0,0 +1,4 @@ +EXPORT proxy_ftp_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_hook_canon_handler diff --git a/trunk/modules/arch/netware/mod_proxy_http.def b/trunk/modules/arch/netware/mod_proxy_http.def new file mode 100644 index 0000000000..b24358b169 --- /dev/null +++ b/trunk/modules/arch/netware/mod_proxy_http.def @@ -0,0 +1,7 @@ +EXPORT proxy_http_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_run_fixups +IMPORT proxy_hook_canon_handler +IMPORT ap_proxy_ssl_enable +IMPORT ap_proxy_ssl_disable diff --git a/trunk/modules/arch/netware/mod_rewrite.def b/trunk/modules/arch/netware/mod_rewrite.def new file mode 100644 index 0000000000..cfdcf6b132 --- /dev/null +++ b/trunk/modules/arch/netware/mod_rewrite.def @@ -0,0 +1 @@ +EXPORT rewrite_module diff --git a/trunk/modules/arch/netware/mod_speling.def b/trunk/modules/arch/netware/mod_speling.def new file mode 100644 index 0000000000..3d45a6aa1a --- /dev/null +++ b/trunk/modules/arch/netware/mod_speling.def @@ -0,0 +1 @@ +EXPORT speling_module diff --git a/trunk/modules/arch/netware/mod_status.def b/trunk/modules/arch/netware/mod_status.def new file mode 100644 index 0000000000..9a5a32d46c --- /dev/null +++ b/trunk/modules/arch/netware/mod_status.def @@ -0,0 +1,2 @@ +EXPORT status_module + diff --git a/trunk/modules/arch/netware/mod_unique_id.def b/trunk/modules/arch/netware/mod_unique_id.def new file mode 100644 index 0000000000..0b72c1ecc0 --- /dev/null +++ b/trunk/modules/arch/netware/mod_unique_id.def @@ -0,0 +1 @@ +EXPORT unique_id_module diff --git a/trunk/modules/arch/netware/mod_usertrack.def b/trunk/modules/arch/netware/mod_usertrack.def new file mode 100644 index 0000000000..7264c41ecf --- /dev/null +++ b/trunk/modules/arch/netware/mod_usertrack.def @@ -0,0 +1 @@ +EXPORT usertrack_module diff --git a/trunk/modules/arch/netware/mod_vhost_alias.def b/trunk/modules/arch/netware/mod_vhost_alias.def new file mode 100644 index 0000000000..574b85f987 --- /dev/null +++ b/trunk/modules/arch/netware/mod_vhost_alias.def @@ -0,0 +1,2 @@ +EXPORT vhost_alias_module + diff --git a/trunk/modules/arch/netware/moddavfs.def b/trunk/modules/arch/netware/moddavfs.def new file mode 100644 index 0000000000..67ec311758 --- /dev/null +++ b/trunk/modules/arch/netware/moddavfs.def @@ -0,0 +1 @@ +EXPORT dav_fs_module diff --git a/trunk/modules/arch/win32/Makefile.in b/trunk/modules/arch/win32/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/arch/win32/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/arch/win32/config.m4 b/trunk/modules/arch/win32/config.m4 new file mode 100644 index 0000000000..584e76d9c2 --- /dev/null +++ b/trunk/modules/arch/win32/config.m4 @@ -0,0 +1,9 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(arch/win32) + +APACHE_MODULE(isapi, isapi extension support, , , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/arch/win32/mod_isapi.c b/trunk/modules/arch/win32/mod_isapi.c new file mode 100644 index 0000000000..dd6c40ccaa --- /dev/null +++ b/trunk/modules/arch/win32/mod_isapi.c @@ -0,0 +1,1647 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_isapi.c - Internet Server Application (ISA) module for Apache + * by Alexei Kosut , significant overhauls and + * redesign by William Rowe , and hints from many + * other developer/users who have hit on specific flaws. + * + * This module implements the ISAPI Handler architecture, allowing + * Apache to load Internet Server Applications (ISAPI extensions), + * similar to the support in IIS, Zope, O'Reilly's WebSite and others. + * + * It is a complete implementation of the ISAPI 2.0 specification, + * except for "Microsoft extensions" to the API which provide + * asynchronous I/O. It is further extended to include additional + * "Microsoft extentions" through IIS 5.0, with some deficiencies + * where one-to-one mappings don't exist. + * + * Refer to /manual/mod/mod_isapi.html for additional details on + * configuration and use, but check this source for specific support + * of the API, + */ + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "util_script.h" +#include "mod_core.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_buckets.h" +#include "apr_thread_mutex.h" +#include "apr_thread_rwlock.h" +#include "apr_hash.h" +#include "mod_isapi.h" + +/* Retry frequency for a failed-to-load isapi .dll */ +#define ISAPI_RETRY apr_time_from_sec(30) + +/********************************************************** + * + * ISAPI Module Configuration + * + **********************************************************/ + +module AP_MODULE_DECLARE_DATA isapi_module; + +#define ISAPI_UNDEF -1 + +/* Our isapi per-dir config structure */ +typedef struct isapi_dir_conf { + int read_ahead_buflen; + int log_unsupported; + int log_to_errlog; + int log_to_query; + int fake_async; +} isapi_dir_conf; + +typedef struct isapi_loaded isapi_loaded; + +apr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r, + const char *fpath, isapi_loaded** isa); + +static void *create_isapi_dir_config(apr_pool_t *p, char *dummy) +{ + isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf)); + + dir->read_ahead_buflen = ISAPI_UNDEF; + dir->log_unsupported = ISAPI_UNDEF; + dir->log_to_errlog = ISAPI_UNDEF; + dir->log_to_query = ISAPI_UNDEF; + dir->fake_async = ISAPI_UNDEF; + + return dir; +} + +static void *merge_isapi_dir_configs(apr_pool_t *p, void *base_, void *add_) +{ + isapi_dir_conf *base = (isapi_dir_conf *) base_; + isapi_dir_conf *add = (isapi_dir_conf *) add_; + isapi_dir_conf *dir = apr_palloc(p, sizeof(isapi_dir_conf)); + + dir->read_ahead_buflen = (add->read_ahead_buflen == ISAPI_UNDEF) + ? base->read_ahead_buflen + : add->read_ahead_buflen; + dir->log_unsupported = (add->log_unsupported == ISAPI_UNDEF) + ? base->log_unsupported + : add->log_unsupported; + dir->log_to_errlog = (add->log_to_errlog == ISAPI_UNDEF) + ? base->log_to_errlog + : add->log_to_errlog; + dir->log_to_query = (add->log_to_query == ISAPI_UNDEF) + ? base->log_to_query + : add->log_to_query; + dir->fake_async = (add->fake_async == ISAPI_UNDEF) + ? base->fake_async + : add->fake_async; + + return dir; +} + +static const char *isapi_cmd_cachefile(cmd_parms *cmd, void *dummy, + const char *filename) +{ + isapi_loaded *isa; + apr_finfo_t tmp; + apr_status_t rv; + char *fspec; + + /* ### Just an observation ... it would be terribly cool to be + * able to use this per-dir, relative to the directory block being + * defined. The hash result remains global, but shorthand of + * + * ISAPICacheFile myapp.dll anotherapp.dll thirdapp.dll + * + * would be very convienent. + */ + fspec = ap_server_root_relative(cmd->pool, filename); + if (!fspec) { + ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, + "ISAPI: invalid module path, skipping %s", filename); + return NULL; + } + if ((rv = apr_stat(&tmp, fspec, APR_FINFO_TYPE, + cmd->temp_pool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, + "ISAPI: unable to stat, skipping %s", fspec); + return NULL; + } + if (tmp.filetype != APR_REG) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "ISAPI: not a regular file, skipping %s", fspec); + return NULL; + } + + /* Load the extention as cached (with null request_rec) */ + rv = isapi_lookup(cmd->pool, cmd->server, NULL, fspec, &isa); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, cmd->server, + "ISAPI: unable to cache, skipping %s", fspec); + return NULL; + } + + return NULL; +} + +static const command_rec isapi_cmds[] = { + AP_INIT_TAKE1("ISAPIReadAheadBuffer", ap_set_int_slot, + (void *)APR_OFFSETOF(isapi_dir_conf, read_ahead_buflen), + OR_FILEINFO, "Maximum client request body to initially pass to the" + " ISAPI handler (default: 49152)"), + AP_INIT_FLAG("ISAPILogNotSupported", ap_set_flag_slot, + (void *)APR_OFFSETOF(isapi_dir_conf, log_unsupported), + OR_FILEINFO, "Log requests not supported by the ISAPI server" + " on or off (default: off)"), + AP_INIT_FLAG("ISAPIAppendLogToErrors", ap_set_flag_slot, + (void *)APR_OFFSETOF(isapi_dir_conf, log_to_errlog), + OR_FILEINFO, "Send all Append Log requests to the error log" + " on or off (default: off)"), + AP_INIT_FLAG("ISAPIAppendLogToQuery", ap_set_flag_slot, + (void *)APR_OFFSETOF(isapi_dir_conf, log_to_query), + OR_FILEINFO, "Append Log requests are concatinated to the query args" + " on or off (default: on)"), + AP_INIT_FLAG("ISAPIFakeAsync", ap_set_flag_slot, + (void *)APR_OFFSETOF(isapi_dir_conf, fake_async), + OR_FILEINFO, "Fake Asynchronous support for isapi callbacks" + " on or off [Experimental] (default: off)"), + AP_INIT_ITERATE("ISAPICacheFile", isapi_cmd_cachefile, NULL, + RSRC_CONF, "Cache the specified ISAPI extension in-process"), + {NULL} +}; + +/********************************************************** + * + * ISAPI Module Cache handling section + * + **********************************************************/ + +/* Our isapi global config values */ +static struct isapi_global_conf { + apr_pool_t *pool; + apr_thread_mutex_t *lock; + apr_hash_t *hash; +} loaded; + +/* Our loaded isapi module description structure */ +struct isapi_loaded { + const char *filename; + apr_thread_rwlock_t *in_progress; + apr_status_t last_load_rv; + apr_time_t last_load_time; + apr_dso_handle_t *handle; + HSE_VERSION_INFO *isapi_version; + apr_uint32_t report_version; + apr_uint32_t timeout; + PFN_GETEXTENSIONVERSION GetExtensionVersion; + PFN_HTTPEXTENSIONPROC HttpExtensionProc; + PFN_TERMINATEEXTENSION TerminateExtension; +}; + +static apr_status_t isapi_unload(isapi_loaded *isa, int force) +{ + /* All done with the DLL... get rid of it... + * + * If optionally cached, and we weren't asked to force the unload, + * pass HSE_TERM_ADVISORY_UNLOAD, and if it returns 1, unload, + * otherwise, leave it alone (it didn't choose to cooperate.) + */ + if (!isa->handle) { + return APR_SUCCESS; + } + if (isa->TerminateExtension) { + if (force) { + (*isa->TerminateExtension)(HSE_TERM_MUST_UNLOAD); + } + else if (!(*isa->TerminateExtension)(HSE_TERM_ADVISORY_UNLOAD)) { + return APR_EGENERAL; + } + } + apr_dso_unload(isa->handle); + isa->handle = NULL; + return APR_SUCCESS; +} + +static apr_status_t cleanup_isapi(void *isa_) +{ + isapi_loaded* isa = (isapi_loaded*) isa_; + + /* We must force the module to unload, we are about + * to lose the isapi structure's allocation entirely. + */ + return isapi_unload(isa, 1); +} + +static apr_status_t isapi_load(apr_pool_t *p, server_rec *s, isapi_loaded *isa) +{ + apr_status_t rv; + + isa->isapi_version = apr_pcalloc(p, sizeof(HSE_VERSION_INFO)); + + /* TODO: These aught to become overrideable, so that we + * assure a given isapi can be fooled into behaving well. + * + * The tricky bit, they aren't really a per-dir sort of + * config, they will always be constant across every + * reference to the .dll no matter what context (vhost, + * location, etc) they apply to. + */ + isa->report_version = MAKELONG(0, 5); /* Revision 5.0 */ + isa->timeout = 300 * 1000000; /* microsecs, not used */ + + rv = apr_dso_load(&isa->handle, isa->filename, p); + if (rv) + { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "ISAPI: failed to load %s", isa->filename); + isa->handle = NULL; + return rv; + } + + rv = apr_dso_sym((void**)&isa->GetExtensionVersion, isa->handle, + "GetExtensionVersion"); + if (rv) + { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "ISAPI: missing GetExtensionVersion() in %s", + isa->filename); + apr_dso_unload(isa->handle); + isa->handle = NULL; + return rv; + } + + rv = apr_dso_sym((void**)&isa->HttpExtensionProc, isa->handle, + "HttpExtensionProc"); + if (rv) + { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "ISAPI: missing HttpExtensionProc() in %s", + isa->filename); + apr_dso_unload(isa->handle); + isa->handle = NULL; + return rv; + } + + /* TerminateExtension() is an optional interface */ + rv = apr_dso_sym((void**)&isa->TerminateExtension, isa->handle, + "TerminateExtension"); + SetLastError(0); + + /* Run GetExtensionVersion() */ + if (!(isa->GetExtensionVersion)(isa->isapi_version)) { + apr_status_t rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "ISAPI: failed call to GetExtensionVersion() in %s", + isa->filename); + apr_dso_unload(isa->handle); + isa->handle = NULL; + return rv; + } + + apr_pool_cleanup_register(p, isa, cleanup_isapi, + apr_pool_cleanup_null); + + return APR_SUCCESS; +} + +apr_status_t isapi_lookup(apr_pool_t *p, server_rec *s, request_rec *r, + const char *fpath, isapi_loaded** isa) +{ + apr_status_t rv; + const char *key; + + if ((rv = apr_thread_mutex_lock(loaded.lock)) != APR_SUCCESS) { + return rv; + } + + *isa = apr_hash_get(loaded.hash, fpath, APR_HASH_KEY_STRING); + + if (*isa) { + + /* If we find this lock exists, use a set-aside copy of gainlock + * to avoid race conditions on NULLing the in_progress variable + * when the load has completed. Release the global isapi hash + * lock so other requests can proceed, then rdlock for completion + * of loading our desired dll or wrlock if we would like to retry + * loading the dll (because last_load_rv failed and retry is up.) + */ + apr_thread_rwlock_t *gainlock = (*isa)->in_progress; + + /* gainlock is NULLed after the module loads successfully. + * This free-threaded module can be used without any locking. + */ + if (!gainlock) { + rv = (*isa)->last_load_rv; + apr_thread_mutex_unlock(loaded.lock); + return rv; + } + + + if ((*isa)->last_load_rv == APR_SUCCESS) { + apr_thread_mutex_unlock(loaded.lock); + if ((rv = apr_thread_rwlock_rdlock(gainlock)) + != APR_SUCCESS) { + return rv; + } + rv = (*isa)->last_load_rv; + apr_thread_rwlock_unlock(gainlock); + return rv; + } + + if (apr_time_now() > (*isa)->last_load_time + ISAPI_RETRY) { + + /* Remember last_load_time before releasing the global + * hash lock to avoid colliding with another thread + * that hit this exception at the same time as our + * retry attempt, since we unlock the global mutex + * before attempting a write lock for this module. + */ + apr_time_t check_time = (*isa)->last_load_time; + apr_thread_mutex_unlock(loaded.lock); + + if ((rv = apr_thread_rwlock_wrlock(gainlock)) + != APR_SUCCESS) { + return rv; + } + + /* If last_load_time is unchanged, we still own this + * retry, otherwise presume another thread provided + * our retry (for good or ill). Relock the global + * hash for updating last_load_ vars, so their update + * is always atomic to the global lock. + */ + if (check_time == (*isa)->last_load_time) { + + rv = isapi_load(loaded.pool, s, *isa); + + apr_thread_mutex_lock(loaded.lock); + (*isa)->last_load_rv = rv; + (*isa)->last_load_time = apr_time_now(); + apr_thread_mutex_unlock(loaded.lock); + } + else { + rv = (*isa)->last_load_rv; + } + apr_thread_rwlock_unlock(gainlock); + + return rv; + } + + /* We haven't hit timeup on retry, let's grab the last_rv + * within the hash mutex before unlocking. + */ + rv = (*isa)->last_load_rv; + apr_thread_mutex_unlock(loaded.lock); + + return rv; + } + + /* If the module was not found, it's time to create a hash key entry + * before releasing the hash lock to avoid multiple threads from + * loading the same module. + */ + key = apr_pstrdup(loaded.pool, fpath); + *isa = apr_pcalloc(loaded.pool, sizeof(isapi_loaded)); + (*isa)->filename = key; + if (r) { + /* A mutex that exists only long enough to attempt to + * load this isapi dll, the release this module to all + * other takers that came along during the one-time + * load process. Short lifetime for this lock would + * be great, however, using r->pool is nasty if those + * blocked on the lock haven't all unlocked before we + * attempt to destroy. A nastier race condition than + * I want to deal with at this moment... + */ + apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool); + apr_thread_rwlock_wrlock((*isa)->in_progress); + } + + apr_hash_set(loaded.hash, key, APR_HASH_KEY_STRING, *isa); + + /* Now attempt to load the isapi on our own time, + * allow other isapi processing to resume. + */ + apr_thread_mutex_unlock(loaded.lock); + + rv = isapi_load(loaded.pool, s, *isa); + (*isa)->last_load_time = apr_time_now(); + (*isa)->last_load_rv = rv; + + if (r && (rv == APR_SUCCESS)) { + /* Let others who are blocked on this particular + * module resume their requests, for better or worse. + */ + apr_thread_rwlock_t *unlock = (*isa)->in_progress; + (*isa)->in_progress = NULL; + apr_thread_rwlock_unlock(unlock); + } + else if (!r && (rv != APR_SUCCESS)) { + /* We must leave a rwlock around for requests to retry + * loading this dll after timeup... since we were in + * the setup code we had avoided creating this lock. + */ + apr_thread_rwlock_create(&(*isa)->in_progress, loaded.pool); + } + + return (*isa)->last_load_rv; +} + +/********************************************************** + * + * ISAPI Module request callbacks section + * + **********************************************************/ + +/* Our "Connection ID" structure */ +struct isapi_cid { + EXTENSION_CONTROL_BLOCK *ecb; + isapi_dir_conf dconf; + isapi_loaded *isa; + request_rec *r; + int headers_set; + int response_sent; + PFN_HSE_IO_COMPLETION completion; + void *completion_arg; + apr_thread_mutex_t *completed; +}; + +int APR_THREAD_FUNC GetServerVariable (isapi_cid *cid, + char *variable_name, + void *buf_data, + apr_uint32_t *buf_size) +{ + request_rec *r = cid->r; + const char *result; + apr_uint32_t len; + + if (!strcmp(variable_name, "ALL_HTTP")) + { + /* crlf delimited, colon split, comma separated and + * null terminated list of HTTP_ vars + */ + const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); + const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; + int i; + + for (len = 0, i = 0; i < arr->nelts; i++) { + if (!strncmp(elts[i].key, "HTTP_", 5)) { + len += strlen(elts[i].key) + strlen(elts[i].val) + 3; + } + } + + if (*buf_size < len + 1) { + *buf_size = len + 1; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + + for (i = 0; i < arr->nelts; i++) { + if (!strncmp(elts[i].key, "HTTP_", 5)) { + strcpy(buf_data, elts[i].key); + ((char*)buf_data) += strlen(elts[i].key); + *(((char*)buf_data)++) = ':'; + strcpy(buf_data, elts[i].val); + ((char*)buf_data) += strlen(elts[i].val); + *(((char*)buf_data)++) = '\r'; + *(((char*)buf_data)++) = '\n'; + } + } + + *(((char*)buf_data)++) = '\0'; + *buf_size = len + 1; + return 1; + } + + if (!strcmp(variable_name, "ALL_RAW")) + { + /* crlf delimited, colon split, comma separated and + * null terminated list of the raw request header + */ + const apr_array_header_t *arr = apr_table_elts(r->headers_in); + const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; + int i; + + for (len = 0, i = 0; i < arr->nelts; i++) { + len += strlen(elts[i].key) + strlen(elts[i].val) + 4; + } + + if (*buf_size < len + 1) { + *buf_size = len + 1; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + + for (i = 0; i < arr->nelts; i++) { + strcpy(buf_data, elts[i].key); + ((char*)buf_data) += strlen(elts[i].key); + *(((char*)buf_data)++) = ':'; + *(((char*)buf_data)++) = ' '; + strcpy(buf_data, elts[i].val); + ((char*)buf_data) += strlen(elts[i].val); + *(((char*)buf_data)++) = '\r'; + *(((char*)buf_data)++) = '\n'; + } + *(((char*)buf_data)++) = '\0'; + *buf_size = len + 1; + return 1; + } + + /* Not a special case */ + result = apr_table_get(r->subprocess_env, variable_name); + + if (result) { + len = strlen(result); + if (*buf_size < len + 1) { + *buf_size = len + 1; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return 0; + } + strcpy(buf_data, result); + *buf_size = len + 1; + return 1; + } + + /* Not Found */ + SetLastError(ERROR_INVALID_INDEX); + return 0; +} + +int APR_THREAD_FUNC ReadClient(isapi_cid *cid, + void *buf_data, + apr_uint32_t *buf_size) +{ + request_rec *r = cid->r; + apr_uint32_t read = 0; + int res; + + if (r->remaining < *buf_size) { + *buf_size = (apr_size_t)r->remaining; + } + + while (read < *buf_size && + ((res = ap_get_client_block(r, (char*)buf_data + read, + *buf_size - read)) > 0)) { + read += res; + } + + *buf_size = read; + if (res < 0) { + SetLastError(ERROR_READ_FAULT); + } + return (res >= 0); +} + +/* Common code invoked for both HSE_REQ_SEND_RESPONSE_HEADER and + * the newer HSE_REQ_SEND_RESPONSE_HEADER_EX ServerSupportFunction(s) + * as well as other functions that write responses and presume that + * the support functions above are optional. + * + * Other callers trying to split headers and body bytes should pass + * head/headlen alone (leaving stat/statlen NULL/0), so that they + * get a proper count of bytes consumed. The argument passed to stat + * isn't counted as the head bytes are. + */ +static apr_ssize_t send_response_header(isapi_cid *cid, + const char *stat, + const char *head, + apr_size_t statlen, + apr_size_t headlen) +{ + int head_present = 1; + int termarg; + char *termch; + apr_size_t ate = 0; + + if (!head || headlen == 0 || !*head) { + head = stat; + stat = NULL; + headlen = statlen; + statlen = 0; + head_present = 0; /* Don't eat the header */ + } + + if (!stat || statlen == 0 || !*stat) { + if (head && headlen && *head && ((stat = memchr(head, '\r', headlen)) + || (stat = memchr(head, '\n', headlen)) + || (stat = memchr(head, '\0', headlen)) + || (stat = head + headlen))) { + statlen = stat - head; + if (memchr(head, ':', statlen)) { + stat = "Status: 200 OK"; + statlen = strlen(stat); + } + else { + const char *flip = head; + head = stat; + stat = flip; + headlen -= statlen; + ate += statlen; + if (*head == '\r' && headlen) + ++head, --headlen, ++ate; + if (*head == '\n' && headlen) + ++head, --headlen, ++ate; + } + } + } + + if (stat && (statlen > 0) && *stat) { + char *newstat; + if (!apr_isdigit(*stat)) { + const char *stattok = stat; + int toklen = statlen; + while (toklen && *stattok && !apr_isspace(*stattok)) { + ++stattok; --toklen; + } + while (toklen && apr_isspace(*stattok)) { + ++stattok; --toklen; + } + /* Now decide if we follow the xxx message + * or the http/x.x xxx message format + */ + if (toklen && apr_isdigit(*stattok)) { + statlen -= toklen; + stat = stattok; + } + } + newstat = apr_palloc(cid->r->pool, statlen + 9); + strcpy(newstat, "Status: "); + apr_cpystrn(newstat + 8, stat, statlen + 1); + stat = newstat; + statlen += 8; + } + + if (!head || headlen == 0 || !*head) { + head = "\r\n"; + headlen = 2; + } + else + { + if (head[headlen - 1] && head[headlen]) { + /* Whoops... not NULL terminated */ + head = apr_pstrndup(cid->r->pool, head, headlen); + } + } + + /* Seems IIS does not enforce the requirement for \r\n termination + * on HSE_REQ_SEND_RESPONSE_HEADER, but we won't panic... + * ap_scan_script_header_err_strs handles this aspect for us. + * + * Parse them out, or die trying + */ + if (stat) { + cid->r->status = ap_scan_script_header_err_strs(cid->r, NULL, + &termch, &termarg, stat, head, NULL); + cid->ecb->dwHttpStatusCode = cid->r->status; + } + else { + cid->r->status = ap_scan_script_header_err_strs(cid->r, NULL, + &termch, &termarg, head, NULL); + if (cid->ecb->dwHttpStatusCode && cid->r->status == HTTP_OK + && cid->ecb->dwHttpStatusCode != HTTP_OK) { + /* We tried every way to Sunday to get the status... + * so now we fall back on dwHttpStatusCode if it appears + * ap_scan_script_header fell back on the default code. + * Any other results set dwHttpStatusCode to the decoded + * status value. + */ + cid->r->status = cid->ecb->dwHttpStatusCode; + cid->r->status_line = ap_get_status_line(cid->r->status); + } + else { + cid->ecb->dwHttpStatusCode = cid->r->status; + } + } + if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR) { + return -1; + } + + /* If only Status was passed, we consumed nothing + */ + if (!head_present) + return 0; + + cid->headers_set = 1; + + /* If all went well, tell the caller we consumed the headers complete + */ + if (!termch) + return(ate + headlen); + + /* Any data left must be sent directly by the caller, all we + * give back is the size of the headers we consumed (which only + * happens if the parser got to the head arg, which varies based + * on whether we passed stat+head to scan, or only head. + */ + if (termch && (termarg == (stat ? 1 : 0)) + && head_present && head + headlen > termch) { + return ate + termch - head; + } + return ate; +} + +int APR_THREAD_FUNC WriteClient(isapi_cid *cid, + void *buf_data, + apr_uint32_t *size_arg, + apr_uint32_t flags) +{ + request_rec *r = cid->r; + conn_rec *c = r->connection; + apr_uint32_t buf_size = *size_arg; + apr_bucket_brigade *bb; + apr_bucket *b; + apr_status_t rv; + + if (!cid->headers_set) { + /* It appears that the foxisapi module and other clients + * presume that WriteClient("headers\n\nbody") will work. + * Parse them out, or die trying. + */ + apr_ssize_t ate; + ate = send_response_header(cid, NULL, (char*)buf_data, + 0, buf_size); + if (ate < 0) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + (char*)buf_data += ate; + buf_size -= ate; + } + + if (buf_size) { + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_transient_create(buf_data, buf_size, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + rv = ap_pass_brigade(r->output_filters, bb); + cid->response_sent = 1; + } + + if ((flags & HSE_IO_ASYNC) && cid->completion) { + if (rv == OK) { + cid->completion(cid->ecb, cid->completion_arg, + *size_arg, ERROR_SUCCESS); + } + else { + cid->completion(cid->ecb, cid->completion_arg, + *size_arg, ERROR_WRITE_FAULT); + } + } + return (rv == OK); +} + +int APR_THREAD_FUNC ServerSupportFunction(isapi_cid *cid, + apr_uint32_t HSE_code, + void *buf_data, + apr_uint32_t *buf_size, + apr_uint32_t *data_type) +{ + request_rec *r = cid->r; + conn_rec *c = r->connection; + request_rec *subreq; + + switch (HSE_code) { + case HSE_REQ_SEND_URL_REDIRECT_RESP: + /* Set the status to be returned when the HttpExtensionProc() + * is done. + * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP + * and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK. + * They most definately are not, even in their own samples. + */ + apr_table_set (r->headers_out, "Location", buf_data); + cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; + cid->r->status_line = ap_get_status_line(cid->r->status); + cid->headers_set = 1; + return 1; + + case HSE_REQ_SEND_URL: + /* Soak up remaining input */ + if (r->remaining > 0) { + char argsbuffer[HUGE_STRING_LEN]; + while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN)); + } + + /* Reset the method to GET */ + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + + /* Don't let anyone think there's still data */ + apr_table_unset(r->headers_in, "Content-Length"); + + /* AV fault per PR3598 - redirected path is lost! */ + (char*)buf_data = apr_pstrdup(r->pool, (char*)buf_data); + ap_internal_redirect((char*)buf_data, r); + return 1; + + case HSE_REQ_SEND_RESPONSE_HEADER: + { + /* Parse them out, or die trying */ + apr_size_t statlen = 0, headlen = 0; + apr_ssize_t ate; + if (buf_data) + statlen = strlen((char*) buf_data); + if (data_type) + headlen = strlen((char*) data_type); + ate = send_response_header(cid, (char*) buf_data, + (char*) data_type, + statlen, headlen); + if (ate < 0) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + else if ((apr_size_t)ate < headlen) { + apr_bucket_brigade *bb; + apr_bucket *b; + bb = apr_brigade_create(cid->r->pool, c->bucket_alloc); + b = apr_bucket_transient_create((char*) data_type + ate, + headlen - ate, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(cid->r->output_filters, bb); + cid->response_sent = 1; + } + return 1; + } + + case HSE_REQ_DONE_WITH_SESSION: + /* Signal to resume the thread completing this request, + * leave it to the pool cleanup to dispose of our mutex. + */ + if (cid->completed) { + (void)apr_thread_mutex_unlock(cid->completed); + return 1; + } + else if (cid->dconf.log_unsupported) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_DONE_WITH_SESSION is not supported: %s", + r->filename); + } + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_MAP_URL_TO_PATH: + { + /* Map a URL to a filename */ + char *file = (char *)buf_data; + apr_uint32_t len; + subreq = ap_sub_req_lookup_uri(apr_pstrndup(r->pool, file, *buf_size), + r, NULL); + + len = apr_cpystrn(file, subreq->filename, *buf_size) - file; + + + /* IIS puts a trailing slash on directories, Apache doesn't */ + if (subreq->finfo.filetype == APR_DIR) { + if (len < *buf_size - 1) { + file[len++] = '\\'; + file[len] = '\0'; + } + } + *buf_size = len; + return 1; + } + + case HSE_REQ_GET_SSPI_INFO: + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction HSE_REQ_GET_SSPI_INFO " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_APPEND_LOG_PARAMETER: + /* Log buf_data, of buf_size bytes, in the URI Query (cs-uri-query) field + */ + apr_table_set(r->notes, "isapi-parameter", (char*) buf_data); + if (cid->dconf.log_to_query) { + if (r->args) + r->args = apr_pstrcat(r->pool, r->args, (char*) buf_data, NULL); + else + r->args = apr_pstrdup(r->pool, (char*) buf_data); + } + if (cid->dconf.log_to_errlog) + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "ISAPI: %s: %s", cid->r->filename, + (char*) buf_data); + return 1; + + case HSE_REQ_IO_COMPLETION: + /* Emulates a completion port... Record callback address and + * user defined arg, we will call this after any async request + * (e.g. transmitfile) as if the request executed async. + * Per MS docs... HSE_REQ_IO_COMPLETION replaces any prior call + * to HSE_REQ_IO_COMPLETION, and buf_data may be set to NULL. + */ + if (cid->dconf.fake_async) { + cid->completion = (PFN_HSE_IO_COMPLETION) buf_data; + cid->completion_arg = (void *) data_type; + return 1; + } + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction HSE_REQ_IO_COMPLETION " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_TRANSMIT_FILE: + { + /* we do nothing with (tf->dwFlags & HSE_DISCONNECT_AFTER_SEND) + */ + HSE_TF_INFO *tf = (HSE_TF_INFO*)buf_data; + apr_uint32_t sent = 0; + apr_ssize_t ate = 0; + apr_status_t rv; + apr_bucket_brigade *bb; + apr_bucket *b; + apr_file_t *fd; + apr_off_t fsize; + + if (!cid->dconf.fake_async && (tf->dwFlags & HSE_IO_ASYNC)) { + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction HSE_REQ_TRANSMIT_FILE " + "as HSE_IO_ASYNC is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* Presume the handle was opened with the CORRECT semantics + * for TransmitFile + */ + if ((rv = apr_os_file_put(&fd, &tf->hFile, + APR_READ | APR_XTHREAD, r->pool)) + != APR_SUCCESS) { + return 0; + } + if (tf->BytesToWrite) { + fsize = tf->BytesToWrite; + } + else { + apr_finfo_t fi; + if (apr_file_info_get(&fi, APR_FINFO_SIZE, fd) != APR_SUCCESS) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + fsize = fi.size - tf->Offset; + } + + /* apr_dupfile_oshandle (&fd, tf->hFile, r->pool); */ + bb = apr_brigade_create(r->pool, c->bucket_alloc); + + /* According to MS: if calling HSE_REQ_TRANSMIT_FILE with the + * HSE_IO_SEND_HEADERS flag, then you can't otherwise call any + * HSE_SEND_RESPONSE_HEADERS* fn, but if you don't use the flag, + * you must have done so. They document that the pHead headers + * option is valid only for HSE_IO_SEND_HEADERS - we are a bit + * more flexible and assume with the flag, pHead are the + * response headers, and without, pHead simply contains text + * (handled after this case). + */ + if ((tf->dwFlags & HSE_IO_SEND_HEADERS) && tf->pszStatusCode) { + ate = send_response_header(cid, tf->pszStatusCode, + (char*)tf->pHead, + strlen(tf->pszStatusCode), + tf->HeadLength); + } + else if (!cid->headers_set && tf->pHead && tf->HeadLength + && *(char*)tf->pHead) { + ate = send_response_header(cid, NULL, (char*)tf->pHead, + 0, tf->HeadLength); + if (ate < 0) + { + apr_brigade_destroy(bb); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + } + + if (tf->pHead && (apr_size_t)ate < tf->HeadLength) { + b = apr_bucket_transient_create((char*)tf->pHead + ate, + tf->HeadLength - ate, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + sent = tf->HeadLength; + } + + sent += (apr_uint32_t)fsize; +#if APR_HAS_LARGE_FILES + if (r->finfo.size > AP_MAX_SENDFILE) { + /* APR_HAS_LARGE_FILES issue; must split into mutiple buckets, + * no greater than MAX(apr_size_t), and more granular than that + * in case the brigade code/filters attempt to read it directly. + */ + b = apr_bucket_file_create(fd, tf->Offset, AP_MAX_SENDFILE, + r->pool, c->bucket_alloc); + while (fsize > AP_MAX_SENDFILE) { + apr_bucket *bc; + apr_bucket_copy(b, &bc); + APR_BRIGADE_INSERT_TAIL(bb, bc); + b->start += AP_MAX_SENDFILE; + fsize -= AP_MAX_SENDFILE; + } + b->length = (apr_size_t)fsize; /* Resize just the last bucket */ + } + else +#endif + b = apr_bucket_file_create(fd, tf->Offset, (apr_size_t)fsize, + r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if (tf->pTail && tf->TailLength) { + sent += tf->TailLength; + b = apr_bucket_transient_create((char*)tf->pTail, + tf->TailLength, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + } + + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(r->output_filters, bb); + cid->response_sent = 1; + + /* Use tf->pfnHseIO + tf->pContext, or if NULL, then use cid->fnIOComplete + * pass pContect to the HseIO callback. + */ + if (tf->dwFlags & HSE_IO_ASYNC) { + if (tf->pfnHseIO) { + if (rv == OK) { + tf->pfnHseIO(cid->ecb, tf->pContext, + ERROR_SUCCESS, sent); + } + else { + tf->pfnHseIO(cid->ecb, tf->pContext, + ERROR_WRITE_FAULT, sent); + } + } + else if (cid->completion) { + if (rv == OK) { + cid->completion(cid->ecb, cid->completion_arg, + sent, ERROR_SUCCESS); + } + else { + cid->completion(cid->ecb, cid->completion_arg, + sent, ERROR_WRITE_FAULT); + } + } + } + return (rv == OK); + } + + case HSE_REQ_REFRESH_ISAPI_ACL: + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_REFRESH_ISAPI_ACL " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_IS_KEEP_CONN: + *((int *)buf_data) = (r->connection->keepalive == AP_CONN_KEEPALIVE); + return 1; + + case HSE_REQ_ASYNC_READ_CLIENT: + { + apr_uint32_t read = 0; + int res; + if (!cid->dconf.fake_async) { + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: asynchronous I/O not supported: %s", + r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + if (r->remaining < *buf_size) { + *buf_size = (apr_size_t)r->remaining; + } + + while (read < *buf_size && + ((res = ap_get_client_block(r, (char*)buf_data + read, + *buf_size - read)) > 0)) { + read += res; + } + + if ((*data_type & HSE_IO_ASYNC) && cid->completion) { + if (res >= 0) { + cid->completion(cid->ecb, cid->completion_arg, + read, ERROR_SUCCESS); + } + else { + cid->completion(cid->ecb, cid->completion_arg, + read, ERROR_READ_FAULT); + } + } + return (res >= 0); + } + + case HSE_REQ_GET_IMPERSONATION_TOKEN: /* Added in ISAPI 4.0 */ + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_GET_IMPERSONATION_TOKEN " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_MAP_URL_TO_PATH_EX: + { + /* Map a URL to a filename */ + HSE_URL_MAPEX_INFO *info = (HSE_URL_MAPEX_INFO*)data_type; + char* test_uri = apr_pstrndup(r->pool, (char *)buf_data, *buf_size); + + subreq = ap_sub_req_lookup_uri(test_uri, r, NULL); + info->cchMatchingURL = strlen(test_uri); + info->cchMatchingPath = apr_cpystrn(info->lpszPath, subreq->filename, + sizeof(info->lpszPath)) - info->lpszPath; + + /* Mapping started with assuming both strings matched. + * Now roll on the path_info as a mismatch and handle + * terminating slashes for directory matches. + */ + if (subreq->path_info && *subreq->path_info) { + apr_cpystrn(info->lpszPath + info->cchMatchingPath, + subreq->path_info, + sizeof(info->lpszPath) - info->cchMatchingPath); + info->cchMatchingURL -= strlen(subreq->path_info); + if (subreq->finfo.filetype == APR_DIR + && info->cchMatchingPath < sizeof(info->lpszPath) - 1) { + /* roll forward over path_info's first slash */ + ++info->cchMatchingPath; + ++info->cchMatchingURL; + } + } + else if (subreq->finfo.filetype == APR_DIR + && info->cchMatchingPath < sizeof(info->lpszPath) - 1) { + /* Add a trailing slash for directory */ + info->lpszPath[info->cchMatchingPath++] = '/'; + info->lpszPath[info->cchMatchingPath] = '\0'; + } + + /* If the matched isn't a file, roll match back to the prior slash */ + if (subreq->finfo.filetype == APR_NOFILE) { + while (info->cchMatchingPath && info->cchMatchingURL) { + if (info->lpszPath[info->cchMatchingPath - 1] == '/') + break; + --info->cchMatchingPath; + --info->cchMatchingURL; + } + } + + /* Paths returned with back slashes */ + for (test_uri = info->lpszPath; *test_uri; ++test_uri) + if (*test_uri == '/') + *test_uri = '\\'; + + /* is a combination of: + * HSE_URL_FLAGS_READ 0x001 Allow read + * HSE_URL_FLAGS_WRITE 0x002 Allow write + * HSE_URL_FLAGS_EXECUTE 0x004 Allow execute + * HSE_URL_FLAGS_SSL 0x008 Require SSL + * HSE_URL_FLAGS_DONT_CACHE 0x010 Don't cache (VRoot only) + * HSE_URL_FLAGS_NEGO_CERT 0x020 Allow client SSL cert + * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert + * HSE_URL_FLAGS_MAP_CERT 0x080 Map client SSL cert to account + * HSE_URL_FLAGS_SSL128 0x100 Require 128-bit SSL cert + * HSE_URL_FLAGS_SCRIPT 0x200 Allow script execution + * + * XxX: As everywhere, EXEC flags could use some work... + * and this could go further with more flags, as desired. + */ + info->dwFlags = (subreq->finfo.protection & APR_UREAD ? 0x001 : 0) + | (subreq->finfo.protection & APR_UWRITE ? 0x002 : 0) + | (subreq->finfo.protection & APR_UEXECUTE ? 0x204 : 0); + return 1; + } + + case HSE_REQ_ABORTIVE_CLOSE: + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE" + " is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_GET_CERT_INFO_EX: /* Added in ISAPI 4.0 */ + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_GET_CERT_INFO_EX " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_SEND_RESPONSE_HEADER_EX: /* Added in ISAPI 4.0 */ + { + HSE_SEND_HEADER_EX_INFO *shi = (HSE_SEND_HEADER_EX_INFO*)buf_data; + + /* Ignore shi->fKeepConn - we don't want the advise + */ + apr_ssize_t ate = send_response_header(cid, shi->pszStatus, + shi->pszHeader, + shi->cchStatus, + shi->cchHeader); + if (ate < 0) { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + else if ((apr_size_t)ate < shi->cchHeader) { + apr_bucket_brigade *bb; + apr_bucket *b; + bb = apr_brigade_create(cid->r->pool, c->bucket_alloc); + b = apr_bucket_transient_create(shi->pszHeader + ate, + shi->cchHeader - ate, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(cid->r->output_filters, bb); + cid->response_sent = 1; + } + return 1; + } + + case HSE_REQ_CLOSE_CONNECTION: /* Added after ISAPI 4.0 */ + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_CLOSE_CONNECTION " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + case HSE_REQ_IS_CONNECTED: /* Added after ISAPI 4.0 */ + /* Returns True if client is connected c.f. MSKB Q188346 + * assuming the identical return mechanism as HSE_REQ_IS_KEEP_CONN + */ + *((int *)buf_data) = (r->connection->aborted == 0); + return 1; + + case HSE_REQ_EXTENSION_TRIGGER: /* Added after ISAPI 4.0 */ + /* Undocumented - defined by the Microsoft Jan '00 Platform SDK + */ + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction " + "HSE_REQ_EXTENSION_TRIGGER " + "is not supported: %s", r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + + default: + if (cid->dconf.log_unsupported) + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: ServerSupportFunction (%d) not supported: " + "%s", HSE_code, r->filename); + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } +} + +/********************************************************** + * + * ISAPI Module request invocation section + * + **********************************************************/ + +apr_status_t isapi_handler (request_rec *r) +{ + isapi_dir_conf *dconf; + apr_table_t *e; + apr_status_t rv; + isapi_loaded *isa; + isapi_cid *cid; + const char *val; + apr_uint32_t read; + int res; + + if(strcmp(r->handler, "isapi-isa") + && strcmp(r->handler, "isapi-handler")) { + /* Hang on to the isapi-isa for compatibility with older docs + * (wtf did '-isa' mean in the first place?) but introduce + * a newer and clearer "isapi-handler" name. + */ + return DECLINED; + } + dconf = ap_get_module_config(r->per_dir_config, &isapi_module); + e = r->subprocess_env; + + /* Use similar restrictions as CGIs + * + * If this fails, it's pointless to load the isapi dll. + */ + if (!(ap_allow_options(r) & OPT_EXECCGI)) { + return HTTP_FORBIDDEN; + } + if (r->finfo.filetype == APR_NOFILE) { + return HTTP_NOT_FOUND; + } + if (r->finfo.filetype != APR_REG) { + return HTTP_FORBIDDEN; + } + if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) && + r->path_info && *r->path_info) { + /* default to accept */ + return HTTP_NOT_FOUND; + } + + if (isapi_lookup(r->pool, r->server, r, r->filename, &isa) + != APR_SUCCESS) { + return HTTP_INTERNAL_SERVER_ERROR; + } + /* Set up variables */ + ap_add_common_vars(r); + ap_add_cgi_vars(r); + apr_table_setn(e, "UNMAPPED_REMOTE_USER", "REMOTE_USER"); + if ((val = apr_table_get(e, "HTTPS")) && strcmp(val, "on")) + apr_table_setn(e, "SERVER_PORT_SECURE", "1"); + else + apr_table_setn(e, "SERVER_PORT_SECURE", "0"); + apr_table_setn(e, "URL", r->uri); + + /* Set up connection structure and ecb, + * NULL or zero out most fields. + */ + cid = apr_pcalloc(r->pool, sizeof(isapi_cid)); + + /* Fixup defaults for dconf */ + cid->dconf.read_ahead_buflen = (dconf->read_ahead_buflen == ISAPI_UNDEF) + ? 49152 : dconf->read_ahead_buflen; + cid->dconf.log_unsupported = (dconf->log_unsupported == ISAPI_UNDEF) + ? 0 : dconf->log_unsupported; + cid->dconf.log_to_errlog = (dconf->log_to_errlog == ISAPI_UNDEF) + ? 0 : dconf->log_to_errlog; + cid->dconf.log_to_query = (dconf->log_to_query == ISAPI_UNDEF) + ? 1 : dconf->log_to_query; + cid->dconf.fake_async = (dconf->fake_async == ISAPI_UNDEF) + ? 0 : dconf->fake_async; + + cid->ecb = apr_pcalloc(r->pool, sizeof(EXTENSION_CONTROL_BLOCK)); + cid->ecb->ConnID = cid; + cid->isa = isa; + cid->r = r; + r->status = 0; + + cid->ecb->cbSize = sizeof(EXTENSION_CONTROL_BLOCK); + cid->ecb->dwVersion = isa->report_version; + cid->ecb->dwHttpStatusCode = 0; + strcpy(cid->ecb->lpszLogData, ""); + /* TODO: are copies really needed here? + */ + cid->ecb->lpszMethod = (char*) r->method; + cid->ecb->lpszQueryString = (char*) apr_table_get(e, "QUERY_STRING"); + cid->ecb->lpszPathInfo = (char*) apr_table_get(e, "PATH_INFO"); + cid->ecb->lpszPathTranslated = (char*) apr_table_get(e, "PATH_TRANSLATED"); + cid->ecb->lpszContentType = (char*) apr_table_get(e, "CONTENT_TYPE"); + + /* Set up the callbacks */ + cid->ecb->GetServerVariable = GetServerVariable; + cid->ecb->WriteClient = WriteClient; + cid->ecb->ReadClient = ReadClient; + cid->ecb->ServerSupportFunction = ServerSupportFunction; + + /* Set up client input */ + res = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR); + if (res) { + isapi_unload(isa, 0); + return res; + } + + if (ap_should_client_block(r)) { + /* Time to start reading the appropriate amount of data, + * and allow the administrator to tweak the number + */ + if (r->remaining) { + cid->ecb->cbTotalBytes = (apr_size_t)r->remaining; + if (cid->ecb->cbTotalBytes > (apr_uint32_t)cid->dconf.read_ahead_buflen) + cid->ecb->cbAvailable = cid->dconf.read_ahead_buflen; + else + cid->ecb->cbAvailable = cid->ecb->cbTotalBytes; + } + else + { + cid->ecb->cbTotalBytes = 0xffffffff; + cid->ecb->cbAvailable = cid->dconf.read_ahead_buflen; + } + + cid->ecb->lpbData = apr_pcalloc(r->pool, cid->ecb->cbAvailable + 1); + + read = 0; + while (read < cid->ecb->cbAvailable && + ((res = ap_get_client_block(r, cid->ecb->lpbData + read, + cid->ecb->cbAvailable - read)) > 0)) { + read += res; + } + + if (res < 0) { + isapi_unload(isa, 0); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Although it's not to spec, IIS seems to null-terminate + * its lpdData string. So we will too. + */ + if (res == 0) + cid->ecb->cbAvailable = cid->ecb->cbTotalBytes = read; + else + cid->ecb->cbAvailable = read; + cid->ecb->lpbData[read] = '\0'; + } + else { + cid->ecb->cbTotalBytes = 0; + cid->ecb->cbAvailable = 0; + cid->ecb->lpbData = NULL; + } + + /* To emulate async behavior... + * + * We create a cid->completed mutex and lock on it so that the + * app can believe is it running async. + * + * This request completes upon a notification through + * ServerSupportFunction(HSE_REQ_DONE_WITH_SESSION), which + * unlocks this mutex. If the HttpExtensionProc() returns + * HSE_STATUS_PENDING, we will attempt to gain this lock again + * which may *only* happen once HSE_REQ_DONE_WITH_SESSION has + * unlocked the mutex. + */ + if (cid->dconf.fake_async) { + rv = apr_thread_mutex_create(&cid->completed, + APR_THREAD_MUTEX_UNNESTED, + r->pool); + if (cid->completed && (rv == APR_SUCCESS)) { + rv = apr_thread_mutex_lock(cid->completed); + } + + if (!cid->completed || (rv != APR_SUCCESS)) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: Failed to create completion mutex"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + /* All right... try and run the sucker */ + rv = (*isa->HttpExtensionProc)(cid->ecb); + + /* Check for a log message - and log it */ + if (cid->ecb->lpszLogData && *cid->ecb->lpszLogData) + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "ISAPI: %s: %s", r->filename, cid->ecb->lpszLogData); + + switch(rv) { + case 0: /* Strange, but MS isapi accepts this as success */ + case HSE_STATUS_SUCCESS: + case HSE_STATUS_SUCCESS_AND_KEEP_CONN: + /* Ignore the keepalive stuff; Apache handles it just fine without + * the ISAPI Handler's "advice". + * Per Microsoft: "In IIS versions 4.0 and later, the return + * values HSE_STATUS_SUCCESS and HSE_STATUS_SUCCESS_AND_KEEP_CONN + * are functionally identical: Keep-Alive connections are + * maintained, if supported by the client." + * ... so we were pat all this time + */ + break; + + case HSE_STATUS_PENDING: + /* emulating async behavior... + */ + if (cid->completed) { + /* The completion port was locked prior to invoking + * HttpExtensionProc(). Once we can regain the lock, + * when ServerSupportFunction(HSE_REQ_DONE_WITH_SESSION) + * is called by the extension to release the lock, + * we may finally destroy the request. + */ + (void)apr_thread_mutex_lock(cid->completed); + break; + } + else if (cid->dconf.log_unsupported) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: asynch I/O result HSE_STATUS_PENDING " + "from HttpExtensionProc() is not supported: %s", + r->filename); + r->status = HTTP_INTERNAL_SERVER_ERROR; + } + break; + + case HSE_STATUS_ERROR: + /* end response if we have yet to do so. + */ + r->status = HTTP_INTERNAL_SERVER_ERROR; + break; + + default: + /* TODO: log unrecognized retval for debugging + */ + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "ISAPI: return code %d from HttpExtensionProc() " + "was not not recognized", rv); + r->status = HTTP_INTERNAL_SERVER_ERROR; + break; + } + + /* Flush the response now, including headers-only responses */ + if (cid->headers_set) { + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *b; + apr_status_t rv; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + rv = ap_pass_brigade(r->output_filters, bb); + cid->response_sent = 1; + + return OK; /* NOT r->status or cid->r->status, even if it has changed. */ + } + + /* As the client returned no error, and if we did not error out + * ourselves, trust dwHttpStatusCode to say something relevant. + */ + if (!ap_is_HTTP_SERVER_ERROR(r->status) && cid->ecb->dwHttpStatusCode) { + r->status = cid->ecb->dwHttpStatusCode; + } + + /* For all missing-response situations simply return the status. + * and let the core deal respond to the client. + */ + return r->status; +} + +/********************************************************** + * + * ISAPI Module Setup Hooks + * + **********************************************************/ + +static int isapi_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) +{ + apr_status_t rv; + + apr_pool_create_ex(&loaded.pool, pconf, NULL, NULL); + if (!loaded.pool) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EGENERAL, NULL, + "ISAPI: could not create the isapi cache pool"); + return APR_EGENERAL; + } + + loaded.hash = apr_hash_make(loaded.pool); + if (!loaded.hash) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ISAPI: Failed to create module cache"); + return APR_EGENERAL; + } + + rv = apr_thread_mutex_create(&loaded.lock, APR_THREAD_MUTEX_DEFAULT, + loaded.pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, rv, 0, NULL, + "ISAPI: Failed to create module cache lock"); + return rv; + } + return OK; +} + +static void isapi_hooks(apr_pool_t *cont) +{ + ap_hook_pre_config(isapi_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_handler(isapi_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA isapi_module = { + STANDARD20_MODULE_STUFF, + create_isapi_dir_config, /* create per-dir config */ + merge_isapi_dir_configs, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + isapi_cmds, /* command apr_table_t */ + isapi_hooks /* register hooks */ +}; diff --git a/trunk/modules/arch/win32/mod_isapi.dsp b/trunk/modules/arch/win32/mod_isapi.dsp new file mode 100644 index 0000000000..8be6979c06 --- /dev/null +++ b/trunk/modules/arch/win32/mod_isapi.dsp @@ -0,0 +1,132 @@ +# Microsoft Developer Studio Project File - Name="mod_isapi" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_isapi - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_isapi.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_isapi.mak" CFG="mod_isapi - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_isapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_isapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_isapi - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_isapi_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_isapi - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_isapi_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_isapi.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_isapi.so + +!ENDIF + +# Begin Target + +# Name "mod_isapi - Win32 Release" +# Name "mod_isapi - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_isapi.c +# End Source File +# Begin Source File + +SOURCE=.\mod_isapi.h +# End Source File +# Begin Source File + +SOURCE=.\mod_isapi.rc +# End Source File +# Begin Source File + +SOURCE=..\..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_isapi - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_isapi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_isapi.so "isapi_module for Apache" ../../../include/ap_release.h > .\mod_isapi.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_isapi - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_isapi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_isapi.so "isapi_module for Apache" ../../../include/ap_release.h > .\mod_isapi.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/arch/win32/mod_isapi.h b/trunk/modules/arch/win32/mod_isapi.h new file mode 100644 index 0000000000..a932d507f8 --- /dev/null +++ b/trunk/modules/arch/win32/mod_isapi.h @@ -0,0 +1,260 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_ISAPI_H +#define MOD_ISAPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* The Version Information storage passed to a module on startup + * via the GetExtensionVersion() entry point. + */ +typedef struct HSE_VERSION_INFO { + apr_uint32_t dwExtensionVersion; + char lpszExtensionDesc[256]; +} HSE_VERSION_INFO; + +/* The startup entry point that must be exported by every ISAPI handler + */ +int APR_THREAD_FUNC GetExtensionVersion(HSE_VERSION_INFO *ver_info); +typedef int (APR_THREAD_FUNC *PFN_GETEXTENSIONVERSION)(HSE_VERSION_INFO *ver_info); + +/* Our internal 'HCONN' representation, always opaque to the user. + */ +typedef struct isapi_cid isapi_cid; +typedef struct isapi_cid *HCONN; + +/* Prototypes of the essential functions exposed by mod_isapi + * for the module to communicate with Apache. + */ +typedef int (APR_THREAD_FUNC + *PFN_GETSERVERVARIABLE)(HCONN cid, + char *variable_name, + void *buf_data, + apr_uint32_t *buf_size); +typedef int (APR_THREAD_FUNC + *PFN_WRITECLIENT)(HCONN cid, + void *buf_data, + apr_uint32_t *buf_size, + apr_uint32_t flags); +typedef int (APR_THREAD_FUNC + *PFN_READCLIENT)(HCONN cid, + void *buf_data, + apr_uint32_t *buf_size); +typedef int (APR_THREAD_FUNC + *PFN_SERVERSUPPORTFUNCTION)(HCONN cid, + apr_uint32_t HSE_code, + void *buf_data, + apr_uint32_t *buf_size, + apr_uint32_t *flags); + +/* The ecb structure is passed on each invocation of the module + */ +typedef struct EXTENSION_CONTROL_BLOCK { + apr_uint32_t cbSize; + apr_uint32_t dwVersion; + HCONN ConnID; + apr_uint32_t dwHttpStatusCode; + char lpszLogData[80]; + char *lpszMethod; + char *lpszQueryString; + char *lpszPathInfo; + char *lpszPathTranslated; + apr_uint32_t cbTotalBytes; + apr_uint32_t cbAvailable; + unsigned char *lpbData; + char *lpszContentType; + + PFN_GETSERVERVARIABLE GetServerVariable; + PFN_WRITECLIENT WriteClient; + PFN_READCLIENT ReadClient; + PFN_SERVERSUPPORTFUNCTION ServerSupportFunction; +} EXTENSION_CONTROL_BLOCK; + +/* Status/Headers structure to pass to HSE_SEND_HEADER_EX, + * an MS extension to ServerSupportFunction + */ +typedef struct HSE_SEND_HEADER_EX_INFO { + const char * pszStatus; /* HTTP status text, such as "200 OK" */ + const char * pszHeader; /* HTTP header lines text, such as + * "Content-type: text/plain\r\n" + * "Content-Language: en\r\n" + * Note that (in spite of cchFoo lengths below) + * NULL characters will interfere in headers. + */ + apr_uint32_t cchStatus; /* length of pszStatus text */ + apr_uint32_t cchHeader; /* length of pszHeader text */ + int fKeepConn; /* Ignored: used to set keep-alive status, + * but Apache follows the client's negotiated + * HTTP contract to decide. + */ +} HSE_SEND_HEADER_EX_INFO; + +/* Our only 'supported' MS extended flag bit for TransmitFile, + * HSE_IO_SEND_HEADERS indicates that Status+Headers are present + * in the pszStatusCode member of the HSE_TF_INFO structure. + */ +#define HSE_IO_SEND_HEADERS 8 + +/* The remaining flags are MS extended flag bits that bear little + * relation to Apache; the rules that the Apache server obeys follow + * its own design and HTTP protocol filter rules. + * + * We do not support async, however, we fake it. If HSE_IO_SYNC is + * not passed, and a completion context was defined, we will invoke the + * completion function immediately following the transfer, and then + * return to the caller. If HSE_IO_SYNC is passed, there is no call + * neccessary to the completion context. + */ +#define HSE_IO_SYNC 1 +#define HSE_IO_ASYNC 2 +#define HSE_IO_DISCONNECT_AFTER_SEND 4 +#define HSE_IO_NODELAY 4096 + +/* The Completion function prototype. This callback may be fixed with + * the HSE_REQ_IO_COMPLETION ServerSupportFunction call, or overriden + * for the HSE_REQ_TRANSMIT_FILE call. + */ +typedef void (APR_THREAD_FUNC *PFN_HSE_IO_COMPLETION) + (EXTENSION_CONTROL_BLOCK *ecb, + void *ctxt, + apr_uint32_t cbIO, + apr_uint32_t dwError); + +/* TransmitFile structure to pass to HSE_REQ_TRANSMIT_FILE, an MS extension + */ +typedef struct HSE_TF_INFO { + PFN_HSE_IO_COMPLETION pfnHseIO; /* Overrides the default setting of + * HSE_REQ_IO_COMPLETION if not NULL + */ + void *pContext; + apr_os_file_t hFile; /* HANDLE/fd to transmit */ + const char *pszStatusCode; /* Ignored if HSE_IO_SEND_HEADERS is + * not set. Includes HTTP status text + * plus header text lines, such as + * "200 OK\r\n" + * "Content-type: text/plain\r\n" + */ + apr_uint32_t BytesToWrite; /* 0 is write-all */ + apr_uint32_t Offset; /* File Offset */ + void *pHead; /* Prefix with *pHead body text */ + apr_uint32_t HeadLength; /* Length of *pHead body text */ + void *pTail; /* Prefix with *pTail body text */ + apr_uint32_t TailLength; /* Length of *pTail body text */ + apr_uint32_t dwFlags; /* bit flags described above */ +} HSE_TF_INFO; + +typedef struct HSE_URL_MAPEX_INFO { + char lpszPath[260]; + apr_uint32_t dwFlags; + apr_uint32_t cchMatchingPath; + apr_uint32_t cchMatchingURL; + apr_uint32_t dwReserved1; + apr_uint32_t dwReserved2; +} HSE_URL_MAPEX_INFO; + +/* Original ISAPI ServerSupportFunction() HSE_code methods */ +#define HSE_REQ_SEND_URL_REDIRECT_RESP 1 +#define HSE_REQ_SEND_URL 2 +#define HSE_REQ_SEND_RESPONSE_HEADER 3 +#define HSE_REQ_DONE_WITH_SESSION 4 + +/* MS Extented methods to ISAPI ServerSupportFunction() HSE_code */ +#define HSE_REQ_MAP_URL_TO_PATH 1001 /* Emulated */ +#define HSE_REQ_GET_SSPI_INFO 1002 /* Not Supported */ +#define HSE_APPEND_LOG_PARAMETER 1003 /* Supported */ +#define HSE_REQ_IO_COMPLETION 1005 /* Emulated */ +#define HSE_REQ_TRANSMIT_FILE 1006 /* Async Emulated */ +#define HSE_REQ_REFRESH_ISAPI_ACL 1007 /* Not Supported */ +#define HSE_REQ_IS_KEEP_CONN 1008 /* Supported */ +#define HSE_REQ_ASYNC_READ_CLIENT 1010 /* Emulated */ +/* Added with ISAPI 4.0 */ +#define HSE_REQ_GET_IMPERSONATION_TOKEN 1011 /* Not Supported */ +#define HSE_REQ_MAP_URL_TO_PATH_EX 1012 /* Emulated */ +#define HSE_REQ_ABORTIVE_CLOSE 1014 /* Ignored */ +/* Added after ISAPI 4.0 in IIS 5.0 */ +#define HSE_REQ_GET_CERT_INFO_EX 1015 /* Not Supported */ +#define HSE_REQ_SEND_RESPONSE_HEADER_EX 1016 /* Supported (no nulls!) */ +#define HSE_REQ_CLOSE_CONNECTION 1017 /* Ignored */ +#define HSE_REQ_IS_CONNECTED 1018 /* Supported */ +#define HSE_REQ_EXTENSION_TRIGGER 1020 /* Not Supported */ + +/* The request entry point that must be exported by every ISAPI handler + */ +apr_uint32_t APR_THREAD_FUNC HttpExtensionProc(EXTENSION_CONTROL_BLOCK *ecb); +typedef apr_uint32_t (APR_THREAD_FUNC + *PFN_HTTPEXTENSIONPROC)(EXTENSION_CONTROL_BLOCK *ecb); + +/* Allowable return values from HttpExtensionProc (apparently 0 is also + * accepted by MS IIS, and we will respect it as Success.) + * If the HttpExtensionProc returns HSE_STATUS_PENDING, we will create + * a wait mutex and lock on it, until HSE_REQ_DONE_WITH_SESSION is called. + */ +#define HSE_STATUS_SUCCESS 1 +#define HSE_STATUS_SUCCESS_AND_KEEP_CONN 2 /* 1 vs 2 Ignored, we choose */ +#define HSE_STATUS_PENDING 3 /* Emulated (thread lock) */ +#define HSE_STATUS_ERROR 4 + +/* Anticipated error code for common faults within mod_isapi itself + */ +#ifndef ERROR_INSUFFICIENT_BUFFER +#define ERROR_INSUFFICIENT_BUFFER ENOBUFS +#endif +#ifndef ERROR_INVALID_INDEX +#define ERROR_INVALID_INDEX EINVAL +#endif +#ifndef ERROR_INVALID_PARAMETER +#define ERROR_INVALID_PARAMETER EINVAL +#endif +#ifndef ERROR_READ_FAULT +#define ERROR_READ_FAULT EIO +#endif +#ifndef ERROR_WRITE_FAULT +#define ERROR_WRITE_FAULT EIO +#endif +#ifndef ERROR_SUCCESS +#define ERROR_SUCCESS 0 +#endif + +/* Valid flags passed with TerminateExtension() + */ +#define HSE_TERM_MUST_UNLOAD 1 +#define HSE_TERM_ADVISORY_UNLOAD 2 + +/* The shutdown entry point óptionally exported by an ISAPI handler, passed + * HSE_TERM_MUST_UNLOAD or HSE_TERM_ADVISORY_UNLOAD. The module may return + * if passed HSE_TERM_ADVISORY_UNLOAD, and the module will remain loaded. + * If the module returns 1 to HSE_TERM_ADVISORY_UNLOAD it is immediately + * unloaded. If the module is passed HSE_TERM_MUST_UNLOAD, its return value + * is ignored. + */ +int APR_THREAD_FUNC TerminateExtension(apr_uint32_t flags); +typedef int (APR_THREAD_FUNC *PFN_TERMINATEEXTENSION)(apr_uint32_t flags); + +/* Module may return 0 if passed HSE_TERM_ADVISORY_UNLOAD, and the module + * will remain loaded, or 1 if it consents to being unloaded. If the module + * is passed HSE_TERM_MUST_UNLOAD, it's return value is ignored. + */ +#define HSE_TERM_MUST_UNLOAD 1 +#define HSE_TERM_ADVISORY_UNLOAD 2 + +#ifdef __cplusplus +} +#endif + +#endif /* !MOD_ISAPI_H */ diff --git a/trunk/modules/arch/win32/mod_win32.c b/trunk/modules/arch/win32/mod_win32.c new file mode 100644 index 0000000000..e313ad92cc --- /dev/null +++ b/trunk/modules/arch/win32/mod_win32.c @@ -0,0 +1,574 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_buckets.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "util_script.h" +#include "mod_core.h" +#include "mod_cgi.h" +#include "apr_lib.h" +#include "ap_regkey.h" + +extern OSVERSIONINFO osver; /* hiding in mpm_winnt.c */ +static int win_nt; + +/* + * CGI Script stuff for Win32... + */ +typedef enum { eFileTypeUNKNOWN, eFileTypeBIN, eFileTypeEXE16, eFileTypeEXE32, + eFileTypeSCRIPT } file_type_e; +typedef enum { INTERPRETER_SOURCE_UNSET, INTERPRETER_SOURCE_REGISTRY_STRICT, + INTERPRETER_SOURCE_REGISTRY, INTERPRETER_SOURCE_SHEBANG + } interpreter_source_e; +AP_DECLARE(file_type_e) ap_get_win32_interpreter(const request_rec *, + char **interpreter, + char **arguments); + +module AP_MODULE_DECLARE_DATA win32_module; + +typedef struct { + /* Where to find interpreter to run scripts */ + interpreter_source_e script_interpreter_source; +} win32_dir_conf; + +static void *create_win32_dir_config(apr_pool_t *p, char *dir) +{ + win32_dir_conf *conf; + conf = (win32_dir_conf*)apr_palloc(p, sizeof(win32_dir_conf)); + conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET; + return conf; +} + +static void *merge_win32_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + win32_dir_conf *new; + win32_dir_conf *base = (win32_dir_conf *) basev; + win32_dir_conf *add = (win32_dir_conf *) addv; + + new = (win32_dir_conf *) apr_pcalloc(p, sizeof(win32_dir_conf)); + new->script_interpreter_source = (add->script_interpreter_source + != INTERPRETER_SOURCE_UNSET) + ? add->script_interpreter_source + : base->script_interpreter_source; + return new; +} + +static const char *set_interpreter_source(cmd_parms *cmd, void *dv, + char *arg) +{ + win32_dir_conf *d = (win32_dir_conf *)dv; + if (!strcasecmp(arg, "registry")) { + d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY; + } + else if (!strcasecmp(arg, "registry-strict")) { + d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY_STRICT; + } + else if (!strcasecmp(arg, "script")) { + d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG; + } + else { + return apr_pstrcat(cmd->temp_pool, "ScriptInterpreterSource \"", arg, + "\" must be \"registry\", \"registry-strict\" or " + "\"script\"", NULL); + } + return NULL; +} + +/* XXX: prep_string should translate the string into unicode, + * such that it is compatible with whatever codepage the client + * will read characters 80-ff. For the moment, use the unicode + * values 0080-00ff. This isn't trivial, since the code page + * varies between msdos and Windows applications. + * For subsystem 2 [GUI] the default is the system Ansi CP. + * For subsystem 3 [CLI] the default is the system OEM CP. + */ +static void prep_string(const char ** str, apr_pool_t *p) +{ + const char *ch = *str; + char *ch2; + apr_size_t widen = 0; + + if (!ch) { + return; + } + while (*ch) { + if (*(ch++) & 0x80) { + ++widen; + } + } + if (!widen) { + return; + } + widen += (ch - *str) + 1; + ch = *str; + *str = ch2 = apr_palloc(p, widen); + while (*ch) { + if (*ch & 0x80) { + /* sign extension won't hurt us here */ + *(ch2++) = 0xC0 | ((*ch >> 6) & 0x03); + *(ch2++) = 0x80 | (*(ch++) & 0x3f); + } + else { + *(ch2++) = *(ch++); + } + } + *(ch2++) = '\0'; +} + +/* Somewhat more exciting ... figure out where the registry has stashed the + * ExecCGI or Open command - it may be nested one level deep (or more???) + */ +static char* get_interpreter_from_win32_registry(apr_pool_t *p, + const char* ext, + int strict) +{ + apr_status_t rv; + ap_regkey_t *name_key = NULL; + ap_regkey_t *type_key; + ap_regkey_t *key; + char execcgi_path[] = "SHELL\\EXECCGI\\COMMAND"; + char execopen_path[] = "SHELL\\OPEN\\COMMAND"; + char *type_name; + char *buffer; + + if (!ext) { + return NULL; + } + /* + * Future optimization: + * When the registry is successfully searched, store the strings for + * interpreter and arguments in an ext hash to speed up subsequent look-ups + */ + + /* Open the key associated with the script filetype extension */ + rv = ap_regkey_open(&type_key, AP_REGKEY_CLASSES_ROOT, ext, APR_READ, p); + + if (rv != APR_SUCCESS) { + return NULL; + } + + /* Retrieve the name of the script filetype extension */ + rv = ap_regkey_value_get(&type_name, type_key, "", p); + + if (rv == APR_SUCCESS && type_name[0]) { + /* Open the key associated with the script filetype extension */ + rv = ap_regkey_open(&name_key, AP_REGKEY_CLASSES_ROOT, type_name, + APR_READ, p); + } + + /* Open the key for the script command path by: + * + * 1) the 'named' filetype key for ExecCGI/Command + * 2) the extension's type key for ExecCGI/Command + * + * and if the strict arg is false, then continue trying: + * + * 3) the 'named' filetype key for Open/Command + * 4) the extension's type key for Open/Command + */ + + if (name_key) { + if ((rv = ap_regkey_open(&key, name_key, execcgi_path, APR_READ, p)) + == APR_SUCCESS) { + rv = ap_regkey_value_get(&buffer, key, "", p); + ap_regkey_close(name_key); + } + } + + if (!name_key || (rv != APR_SUCCESS)) { + if ((rv = ap_regkey_open(&key, type_key, execcgi_path, APR_READ, p)) + == APR_SUCCESS) { + rv = ap_regkey_value_get(&buffer, key, "", p); + ap_regkey_close(type_key); + } + } + + if (!strict && name_key && (rv != APR_SUCCESS)) { + if ((rv = ap_regkey_open(&key, name_key, execopen_path, APR_READ, p)) + == APR_SUCCESS) { + rv = ap_regkey_value_get(&buffer, key, "", p); + ap_regkey_close(name_key); + } + } + + if (!strict && (rv != APR_SUCCESS)) { + if ((rv = ap_regkey_open(&key, type_key, execopen_path, APR_READ, p)) + == APR_SUCCESS) { + rv = ap_regkey_value_get(&buffer, key, "", p); + ap_regkey_close(type_key); + } + } + + if (name_key) { + ap_regkey_close(name_key); + } + + ap_regkey_close(type_key); + + if (rv != APR_SUCCESS || !buffer[0]) { + return NULL; + } + + return buffer; +} + + +static apr_array_header_t *split_argv(apr_pool_t *p, const char *interp, + const char *cgiprg, const char *cgiargs) +{ + apr_array_header_t *args = apr_array_make(p, 8, sizeof(char*)); + char *d = apr_palloc(p, strlen(interp)+1); + const char *ch = interp; + const char **arg; + int prgtaken = 0; + int argtaken = 0; + int inquo; + int sl; + + while (*ch) { + /* Skip on through Deep Space */ + if (apr_isspace(*ch)) { + ++ch; continue; + } + /* One Arg */ + if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '*')) { + const char *cgiarg = cgiargs; + argtaken = 1; + for (;;) { + char *w = ap_getword_nulls(p, &cgiarg, '+'); + if (!*w) { + break; + } + ap_unescape_url(w); + if (win_nt) { + prep_string(&w, p); + } + arg = (const char**)apr_array_push(args); + *arg = ap_escape_shell_cmd(p, w); + } + ch += 2; + continue; + } + if (((*ch == '$') || (*ch == '%')) && (*(ch + 1) == '1')) { + /* Todo: Make short name!!! */ + prgtaken = 1; + arg = (const char**)apr_array_push(args); + if (*ch == '%') { + char *repl = apr_pstrdup(p, cgiprg); + *arg = repl; + while ((repl = strchr(repl, '/'))) { + *repl++ = '\\'; + } + } + else { + *arg = cgiprg; + } + ch += 2; + continue; + } + if ((*ch == '\"') && ((*(ch + 1) == '$') + || (*(ch + 1) == '%')) && (*(ch + 2) == '1') + && (*(ch + 3) == '\"')) { + prgtaken = 1; + arg = (const char**)apr_array_push(args); + if (*(ch + 1) == '%') { + char *repl = apr_pstrdup(p, cgiprg); + *arg = repl; + while ((repl = strchr(repl, '/'))) { + *repl++ = '\\'; + } + } + else { + *arg = cgiprg; + } + ch += 4; + continue; + } + arg = (const char**)apr_array_push(args); + *arg = d; + inquo = 0; + while (*ch) { + if (apr_isspace(*ch) && !inquo) { + ++ch; break; + } + /* Get 'em backslashes */ + for (sl = 0; *ch == '\\'; ++sl) { + *d++ = *ch++; + } + if (sl & 1) { + /* last unmatched '\' + '"' sequence is a '"' */ + if (*ch == '\"') { + *(d - 1) = *ch++; + } + continue; + } + if (*ch == '\"') { + /* '""' sequence within quotes is a '"' */ + if (*++ch == '\"' && inquo) { + *d++ = *ch++; continue; + } + /* Flip quote state */ + inquo = !inquo; + if (apr_isspace(*ch) && !inquo) { + ++ch; break; + } + /* All other '"'s are Munched */ + continue; + } + /* Anything else is, well, something else */ + *d++ = *ch++; + } + /* Term that arg, already pushed on args */ + *d++ = '\0'; + } + + if (!prgtaken) { + arg = (const char**)apr_array_push(args); + *arg = cgiprg; + } + + if (!argtaken) { + const char *cgiarg = cgiargs; + for (;;) { + char *w = ap_getword_nulls(p, &cgiarg, '+'); + if (!*w) { + break; + } + ap_unescape_url(w); + if (win_nt) { + prep_string(&w, p); + } + arg = (const char**)apr_array_push(args); + *arg = ap_escape_shell_cmd(p, w); + } + } + + arg = (const char**)apr_array_push(args); + *arg = NULL; + + return args; +} + + +static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv, + request_rec *r, apr_pool_t *p, + cgi_exec_info_t *e_info) +{ + const apr_array_header_t *elts_arr = apr_table_elts(r->subprocess_env); + const apr_table_entry_t *elts = (apr_table_entry_t *) elts_arr->elts; + const char *ext = NULL; + const char *interpreter = NULL; + win32_dir_conf *d; + apr_file_t *fh; + const char *args = ""; + int i; + + d = (win32_dir_conf *)ap_get_module_config(r->per_dir_config, + &win32_module); + + if (e_info->cmd_type) { + /* We have to consider that the client gets any QUERY_ARGS + * without any charset interpretation, use prep_string to + * create a string of the literal QUERY_ARGS bytes. + */ + *cmd = r->filename; + if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) { + args = r->args; + } + } + /* Handle the complete file name, we DON'T want to follow suexec, since + * an unrooted command is as predictable as shooting craps in Win32. + * Notice that unlike most mime extension parsing, we have to use the + * win32 parsing here, therefore the final extension is the only one + * we will consider. + */ + ext = strrchr(apr_filepath_name_get(*cmd), '.'); + + /* If the file has an extension and it is not .com and not .exe and + * we've been instructed to search the registry, then do so. + * Let apr_proc_create do all of the .bat/.cmd dirty work. + */ + if (ext && (!strcasecmp(ext,".exe") || !strcasecmp(ext,".com") + || !strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) { + interpreter = ""; + } + if (!interpreter && ext + && (d->script_interpreter_source + == INTERPRETER_SOURCE_REGISTRY + || d->script_interpreter_source + == INTERPRETER_SOURCE_REGISTRY_STRICT)) { + /* Check the registry */ + int strict = (d->script_interpreter_source + == INTERPRETER_SOURCE_REGISTRY_STRICT); + interpreter = get_interpreter_from_win32_registry(r->pool, ext, + strict); + if (interpreter && e_info->cmd_type != APR_SHELLCMD) { + e_info->cmd_type = APR_PROGRAM_PATH; + } + else { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + strict ? "No ExecCGI verb found for files of type '%s'." + : "No ExecCGI or Open verb found for files of type '%s'.", + ext); + } + } + if (!interpreter) { + apr_status_t rv; + char buffer[1024]; + apr_size_t bytes = sizeof(buffer); + apr_size_t i; + + /* Need to peek into the file figure out what it really is... + * ### aught to go back and build a cache for this one of these days. + */ + if ((rv = apr_file_open(&fh, *cmd, APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Failed to open cgi file %s for testing", *cmd); + return rv; + } + if ((rv = apr_file_read(fh, buffer, &bytes)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Failed to read cgi file %s for testing", *cmd); + return rv; + } + apr_file_close(fh); + + /* Some twisted character [no pun intended] at MS decided that a + * zero width joiner as the lead wide character would be ideal for + * describing Unicode text files. This was further convoluted to + * another MSism that the same character mapped into utf-8, EF BB BF + * would signify utf-8 text files. + * + * Since MS configuration files are all protecting utf-8 encoded + * Unicode path, file and resource names, we already have the correct + * WinNT encoding. But at least eat the stupid three bytes up front. + * + * ### A more thorough check would also allow UNICODE text in buf, and + * convert it to UTF-8 for invoking unicode scripts. Those are few + * and far between, so leave that code an enterprising soul with a need. + */ + if ((bytes >= 3) && memcmp(buffer, "\xEF\xBB\xBF", 3) == 0) { + memmove(buffer, buffer + 3, bytes -= 3); + } + + /* Script or executable, that is the question... */ + if ((bytes >= 2) && (buffer[0] == '#') && (buffer[1] == '!')) { + /* Assuming file is a script since it starts with a shebang */ + for (i = 2; i < bytes; i++) { + if ((buffer[i] == '\r') || (buffer[i] == '\n')) { + buffer[i] = '\0'; + break; + } + } + if (i < bytes) { + interpreter = buffer + 2; + while (apr_isspace(*interpreter)) { + ++interpreter; + } + if (e_info->cmd_type != APR_SHELLCMD) { + e_info->cmd_type = APR_PROGRAM_PATH; + } + } + } + else if (bytes >= sizeof(IMAGE_DOS_HEADER)) { + /* Not a script, is it an executable? */ + IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer; + if (hdr->e_magic == IMAGE_DOS_SIGNATURE) { + if (hdr->e_lfarlc < 0x40) { + /* Ought to invoke this 16 bit exe by a stub, (cmd /c?) */ + interpreter = ""; + } + else { + interpreter = ""; + } + } + } + } + if (!interpreter) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s is not executable; ensure interpreted scripts have " + "\"#!\" first line", *cmd); + return APR_EBADF; + } + + *argv = (const char **)(split_argv(p, interpreter, *cmd, + args)->elts); + *cmd = (*argv)[0]; + + e_info->detached = 1; + + /* XXX: Must fix r->subprocess_env to follow utf-8 conventions from + * the client's octets so that win32 apr_proc_create is happy. + * The -best- way is to determine if the .exe is unicode aware + * (using 0x0080-0x00ff) or is linked as a command or windows + * application (following the OEM or Ansi code page in effect.) + */ + for (i = 0; i < elts_arr->nelts; ++i) { + if (win_nt && elts[i].key && *elts[i].key + && (strncmp(elts[i].key, "HTTP_", 5) == 0 + || strncmp(elts[i].key, "SERVER_", 7) == 0 + || strncmp(elts[i].key, "REQUEST_", 8) == 0 + || strcmp(elts[i].key, "QUERY_STRING") == 0 + || strcmp(elts[i].key, "PATH_INFO") == 0 + || strcmp(elts[i].key, "PATH_TRANSLATED") == 0)) { + prep_string((const char**) &elts[i].val, r->pool); + } + } + return APR_SUCCESS; +} + +static int win32_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *ptemp) +{ + win_nt = (osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command); + ap_hook_pre_config(win32_pre_config, NULL, NULL, APR_HOOK_MIDDLE); +} + +static const command_rec win32_cmds[] = { +AP_INIT_TAKE1("ScriptInterpreterSource", set_interpreter_source, NULL, + OR_FILEINFO, + "Where to find interpreter to run Win32 scripts " + "(Registry or script shebang line)"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA win32_module = { + STANDARD20_MODULE_STUFF, + create_win32_dir_config, /* create per-dir config */ + merge_win32_dir_configs, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + win32_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + +#endif /* defined WIN32 */ diff --git a/trunk/modules/cache/.indent.pro b/trunk/modules/cache/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/cache/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/cache/Makefile.in b/trunk/modules/cache/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/cache/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/cache/NWGNUdsk_cach b/trunk/modules/cache/NWGNUdsk_cach new file mode 100644 index 0000000000..9dc385e77e --- /dev/null +++ b/trunk/modules/cache/NWGNUdsk_cach @@ -0,0 +1,266 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = dsk_cach + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Memory Cache Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = dsk_cach + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/dsk_cach.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_disk_cache.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + mod_cach \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + @mod_cache.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + disk_cache_module \ + $(EOLIST) + +# @cache.imp \ +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/cache/NWGNUmakefile b/trunk/modules/cache/NWGNUmakefile new file mode 100644 index 0000000000..71d7e1ba20 --- /dev/null +++ b/trunk/modules/cache/NWGNUmakefile @@ -0,0 +1,246 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_cach.nlm \ + $(OBJDIR)/mem_cach.nlm \ + $(OBJDIR)/dsk_cach.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/cache/NWGNUmem_cach b/trunk/modules/cache/NWGNUmem_cach new file mode 100644 index 0000000000..782d8834cf --- /dev/null +++ b/trunk/modules/cache/NWGNUmem_cach @@ -0,0 +1,270 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + -DDEBUG \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mem_cach + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Memory Cache Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = mem_cach + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mem_cach.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_mem_cache.o \ + $(OBJDIR)/cache_hash.o \ + $(OBJDIR)/cache_pqueue.o \ + $(OBJDIR)/cache_cache.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + mod_cach \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + @mod_cache.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + mem_cache_module \ + $(EOLIST) + +# @cache.imp \ +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/cache/NWGNUmod_cach b/trunk/modules/cache/NWGNUmod_cach new file mode 100644 index 0000000000..125c456794 --- /dev/null +++ b/trunk/modules/cache/NWGNUmod_cach @@ -0,0 +1,269 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + -DDEBUG \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_cach + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Cache module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = mod_cach + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_cach.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/cache_util.o \ + $(OBJDIR)/cache_storage.o \ + $(OBJDIR)/mod_cache.o \ + $(EOLIST) + +# $(OBJDIR)/mod_mem_cache.o \ +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + @netware.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + @mod_cache.imp \ + cache_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/cache/cache_cache.c b/trunk/modules/cache/cache_cache.c new file mode 100644 index 0000000000..16237986a7 --- /dev/null +++ b/trunk/modules/cache/cache_cache.c @@ -0,0 +1,171 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_general.h" + +#include "mod_cache.h" +#include "cache_hash.h" +#include "cache_pqueue.h" +#include "cache_cache.h" + +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif + +struct cache_cache_t { + int max_entries; + apr_size_t max_size; + apr_size_t current_size; + int total_purges; + long queue_clock; + cache_hash_t *ht; + cache_pqueue_t *pq; + cache_pqueue_set_priority set_pri; + cache_pqueue_get_priority get_pri; + cache_cache_inc_frequency *inc_entry; + cache_cache_get_size *size_entry; + cache_cache_get_key *key_entry; + cache_cache_free *free_entry; +}; + +CACHE_DECLARE(cache_cache_t *)cache_init(int max_entries, + apr_size_t max_size, + cache_pqueue_get_priority get_pri, + cache_pqueue_set_priority set_pri, + cache_pqueue_getpos get_pos, + cache_pqueue_setpos set_pos, + cache_cache_inc_frequency *inc_entry, + cache_cache_get_size *size_entry, + cache_cache_get_key* key_entry, + cache_cache_free *free_entry) +{ + cache_cache_t *tmp; + tmp = malloc(sizeof(cache_cache_t)); + tmp->max_entries = max_entries; + tmp->max_size = max_size; + tmp->current_size = 0; + tmp->total_purges = 0; + tmp->queue_clock = 0; + tmp->get_pri = get_pri; + tmp->set_pri = set_pri; + tmp->inc_entry = inc_entry; + tmp->size_entry = size_entry; + tmp->key_entry = key_entry; + tmp->free_entry = free_entry; + + tmp->ht = cache_hash_make(max_entries); + tmp->pq = cache_pq_init(max_entries, get_pri, get_pos, set_pos); + + return tmp; +} + +CACHE_DECLARE(void) cache_free(cache_cache_t *c) +{ + cache_pq_free(c->pq); + cache_hash_free(c->ht); + free(c); +} + + +CACHE_DECLARE(void*) cache_find(cache_cache_t* c, const char *key) +{ + void *e; + + e = cache_hash_get(c->ht, key, CACHE_HASH_KEY_STRING); + if (!e) + return NULL; + + return e; +} + +CACHE_DECLARE(void) cache_update(cache_cache_t* c, void *entry) +{ + long old_priority; + long new_priority; + + old_priority = c->set_pri(c->queue_clock, entry); + c->inc_entry(entry); + new_priority = c->set_pri(c->queue_clock, entry); + cache_pq_change_priority(c->pq, old_priority, new_priority, entry); +} + +CACHE_DECLARE(void) cache_insert(cache_cache_t* c, void *entry) +{ + void *ejected = NULL; + long priority; + + c->set_pri(c->queue_clock, entry); + /* FIX: check if priority of bottom item is greater than inserted one */ + while ((cache_pq_size(c->pq) >= c->max_entries) || + ((c->current_size + c->size_entry(entry)) > c->max_size)) { + + ejected = cache_pq_pop(c->pq); + /* FIX: If ejected is NULL, we'll segfault here */ + priority = c->get_pri(ejected); + + if (c->queue_clock > priority) + c->queue_clock = priority; + + cache_hash_set(c->ht, + c->key_entry(ejected), + CACHE_HASH_KEY_STRING, + NULL); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "Cache Purge of %s",c->key_entry(ejected)); + c->current_size -= c->size_entry(ejected); + c->free_entry(ejected); + c->total_purges++; + } + c->current_size += c->size_entry(entry); + + cache_pq_insert(c->pq, entry); + cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, entry); +} + +CACHE_DECLARE(void *) cache_pop(cache_cache_t *c) +{ + void *entry; + + if (!c) + return NULL; + + entry = cache_pq_pop(c->pq); + + if (!entry) + return NULL; + + c->current_size -= c->size_entry(entry); + cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL); + + return entry; +} + +CACHE_DECLARE(apr_status_t) cache_remove(cache_cache_t *c, void *entry) +{ + apr_size_t entry_size = c->size_entry(entry); + apr_status_t rc; + rc = cache_pq_remove(c->pq, entry); + if (rc != APR_SUCCESS) + return rc; + + cache_hash_set(c->ht, c->key_entry(entry), CACHE_HASH_KEY_STRING, NULL); + c->current_size -= entry_size; + + return APR_SUCCESS; +} diff --git a/trunk/modules/cache/cache_cache.h b/trunk/modules/cache/cache_cache.h new file mode 100644 index 0000000000..011cea825f --- /dev/null +++ b/trunk/modules/cache/cache_cache.h @@ -0,0 +1,112 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CACHE_CACHE_H +#define CACHE_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mod_cache.h" + +/** + * @file cache_hash.h + * @brief Cache Cache Functions + */ + +/** + * @defgroup Cache_cache Cache Functions + * @ingroup CACHE + * @{ + */ +/** ADT for the cache */ +typedef struct cache_cache_t cache_cache_t; + +/** callback to increment the frequency of a item */ +typedef void cache_cache_inc_frequency(void*a); +/** callback to get the size of a item */ +typedef apr_size_t cache_cache_get_size(void*a); +/** callback to get the key of a item */ +typedef const char* cache_cache_get_key(void *a); +/** callback to free an entry */ +typedef void cache_cache_free(void *a); + +/** + * initialize the cache ADT + * @param max_entries the number of entries in the cache + * @param max_size the size of the cache + * @param get_pri callback to get a priority of a entry + * @param set_pri callback to set a priority of a entry + * @param get_pos callback to get the position of a entry in the cache + * @param set_pos callback to set the position of a entry in the cache + * @param inc_entry callback to increment the frequency of a entry + * @param size_entry callback to get the size of a entry + * @param key_entry callback to get the key of a entry + * @param free_entry callback to free an entry + */ +CACHE_DECLARE(cache_cache_t *)cache_init(int max_entries, + apr_size_t max_size, + cache_pqueue_get_priority get_pri, + cache_pqueue_set_priority set_pri, + cache_pqueue_getpos get_pos, + cache_pqueue_setpos set_pos, + cache_cache_inc_frequency *inc_entry, + cache_cache_get_size *size_entry, + cache_cache_get_key *key_entry, + cache_cache_free *free_entry); + +/** + * free up the cache + * @param c the cache + */ +CACHE_DECLARE(void) cache_free(cache_cache_t *c); +/** + * find a entry in the cache, incrementing the frequency if found + * @param c the cache + * @param key the key + */ +CACHE_DECLARE(void*) cache_find(cache_cache_t* c, const char *key); +/** + * insert a entry into the cache + * @param c the cache + * @param entry the entry + */ +CACHE_DECLARE(void) cache_update(cache_cache_t* c, void *entry); +/** + * insert a entry into the cache + * @param c the cache + * @param entry the entry + */ +CACHE_DECLARE(void) cache_insert(cache_cache_t* c, void *entry); +/** + * pop the lowest priority item off + * @param c the cache + * @returns the entry or NULL + */ +CACHE_DECLARE(void *)cache_pop(cache_cache_t* c); +/** + * remove an item from the cache + * @param c the cache + * @param entry the actual entry (from a find) + */ +CACHE_DECLARE(apr_status_t) cache_remove(cache_cache_t* c, void *entry); +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* !CACHE_CACHE_H */ diff --git a/trunk/modules/cache/cache_hash.c b/trunk/modules/cache/cache_hash.c new file mode 100644 index 0000000000..8c5e0c1594 --- /dev/null +++ b/trunk/modules/cache/cache_hash.c @@ -0,0 +1,290 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_general.h" + +#include "mod_cache.h" +#include "cache_hash.h" + +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif + + +/* + * The internal form of a hash table. + * + * The table is an array indexed by the hash of the key; collisions + * are resolved by hanging a linked list of hash entries off each + * element of the array. Although this is a really simple design it + * isn't too bad given that pools have a low allocation overhead. + */ + +typedef struct cache_hash_entry_t cache_hash_entry_t; + +struct cache_hash_entry_t { + cache_hash_entry_t *next; + unsigned int hash; + const void *key; + apr_ssize_t klen; + const void *val; +}; + +/* + * Data structure for iterating through a hash table. + * + * We keep a pointer to the next hash entry here to allow the current + * hash entry to be freed or otherwise mangled between calls to + * cache_hash_next(). + */ +struct cache_hash_index_t { + cache_hash_t *ht; + cache_hash_entry_t *this, *next; + int index; +}; + +/* + * The size of the array is always a power of two. We use the maximum + * index rather than the size so that we can use bitwise-AND for + * modular arithmetic. + * The count of hash entries may be greater depending on the chosen + * collision rate. + */ +struct cache_hash_t { + cache_hash_entry_t **array; + cache_hash_index_t iterator; /* For cache_hash_first(NULL, ...) */ + int count, max; +}; + +/* + * Hash creation functions. + */ +static cache_hash_entry_t **alloc_array(cache_hash_t *ht, int max) +{ + return calloc(1, sizeof(*ht->array) * (max + 1)); +} + +CACHE_DECLARE(cache_hash_t *) cache_hash_make(apr_size_t size) +{ + cache_hash_t *ht; + ht = malloc(sizeof(cache_hash_t)); + if (!ht) { + return NULL; + } + ht->count = 0; + ht->max = size; + ht->array = alloc_array(ht, ht->max); + if (!ht->array) { + free(ht); + return NULL; + } + return ht; +} + +CACHE_DECLARE(void) cache_hash_free(cache_hash_t *ht) +{ + if (ht) { + if (ht->array) { + free (ht->array); + } + free (ht); + } +} +/* + * Hash iteration functions. + */ + +CACHE_DECLARE(cache_hash_index_t *) cache_hash_next(cache_hash_index_t *hi) +{ + hi->this = hi->next; + while (!hi->this) { + if (hi->index > hi->ht->max) + return NULL; + hi->this = hi->ht->array[hi->index++]; + } + hi->next = hi->this->next; + return hi; +} + +CACHE_DECLARE(cache_hash_index_t *) cache_hash_first(cache_hash_t *ht) +{ + cache_hash_index_t *hi; + + hi = &ht->iterator; + hi->ht = ht; + hi->index = 0; + hi->this = NULL; + hi->next = NULL; + return cache_hash_next(hi); +} + +CACHE_DECLARE(void) cache_hash_this(cache_hash_index_t *hi, + const void **key, + apr_ssize_t *klen, + void **val) +{ + if (key) *key = hi->this->key; + if (klen) *klen = hi->this->klen; + if (val) *val = (void *)hi->this->val; +} + + +/* + * This is where we keep the details of the hash function and control + * the maximum collision rate. + * + * If val is non-NULL it creates and initializes a new hash entry if + * there isn't already one there; it returns an updatable pointer so + * that hash entries can be removed. + */ + +static cache_hash_entry_t **find_entry(cache_hash_t *ht, + const void *key, + apr_ssize_t klen, + const void *val) +{ + cache_hash_entry_t **hep, *he; + const unsigned char *p; + unsigned int hash; + apr_ssize_t i; + + /* + * This is the popular `times 33' hash algorithm which is used by + * perl and also appears in Berkeley DB. This is one of the best + * known hash functions for strings because it is both computed + * very fast and distributes very well. + * + * The originator may be Dan Bernstein but the code in Berkeley DB + * cites Chris Torek as the source. The best citation I have found + * is "Chris Torek, Hash function for text in C, Usenet message + * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich + * Salz's USENIX 1992 paper about INN which can be found at + * . + * + * The magic of number 33, i.e. why it works better than many other + * constants, prime or not, has never been adequately explained by + * anyone. So I try an explanation: if one experimentally tests all + * multipliers between 1 and 256 (as I did while writing a low-level + * data structure library some time ago) one detects that even + * numbers are not useable at all. The remaining 128 odd numbers + * (except for the number 1) work more or less all equally well. + * They all distribute in an acceptable way and this way fill a hash + * table with an average percent of approx. 86%. + * + * If one compares the chi^2 values of the variants (see + * Bob Jenkins ``Hashing Frequently Asked Questions'' at + * http://burtleburtle.net/bob/hash/hashfaq.html for a description + * of chi^2), the number 33 not even has the best value. But the + * number 33 and a few other equally good numbers like 17, 31, 63, + * 127 and 129 have nevertheless a great advantage to the remaining + * numbers in the large set of possible multipliers: their multiply + * operation can be replaced by a faster operation based on just one + * shift plus either a single addition or subtraction operation. And + * because a hash function has to both distribute good _and_ has to + * be very fast to compute, those few numbers should be preferred. + * + * -- Ralf S. Engelschall + */ + hash = 0; + if (klen == CACHE_HASH_KEY_STRING) { + for (p = key; *p; p++) { + hash = hash * 33 + *p; + } + klen = p - (const unsigned char *)key; + } + else { + for (p = key, i = klen; i; i--, p++) { + hash = hash * 33 + *p; + } + } + + /* scan linked list */ + for (hep = &ht->array[hash % ht->max], he = *hep; + he; + hep = &he->next, he = *hep) { + if (he->hash == hash && + he->klen == klen && + memcmp(he->key, key, klen) == 0) + break; + } + if (he || !val) + return hep; + /* add a new entry for non-NULL values */ + he = malloc(sizeof(*he)); + if (!he) { + return NULL; + } + he->next = NULL; + he->hash = hash; + he->key = key; + he->klen = klen; + he->val = val; + *hep = he; + ht->count++; + return hep; +} + +CACHE_DECLARE(void *) cache_hash_get(cache_hash_t *ht, + const void *key, + apr_ssize_t klen) +{ + cache_hash_entry_t *he; + he = *find_entry(ht, key, klen, NULL); + if (he) + return (void *)he->val; + else + return NULL; +} + +CACHE_DECLARE(void *) cache_hash_set(cache_hash_t *ht, + const void *key, + apr_ssize_t klen, + const void *val) +{ + cache_hash_entry_t **hep, *tmp; + const void *tval; + hep = find_entry(ht, key, klen, val); + /* If hep == NULL, then the malloc() in find_entry failed */ + if (hep && *hep) { + if (!val) { + /* delete entry */ + tval = (*hep)->val; + tmp = *hep; + *hep = (*hep)->next; + free(tmp); + --ht->count; + } + else { + /* replace entry */ + tval = (*hep)->val; + (*hep)->val = val; + } + /* Return the object just removed from the cache to let the + * caller clean it up. Cast the constness away upon return. + */ + return (void *) tval; + } + /* else key not present and val==NULL */ + return NULL; +} + +CACHE_DECLARE(int) cache_hash_count(cache_hash_t *ht) +{ + return ht->count; +} diff --git a/trunk/modules/cache/cache_hash.h b/trunk/modules/cache/cache_hash.h new file mode 100644 index 0000000000..f945deed86 --- /dev/null +++ b/trunk/modules/cache/cache_hash.h @@ -0,0 +1,161 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CACHE_HASH_H +#define CACHE_HASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mod_cache.h" + +/** + * @file cache_hash.h + * @brief Cache Hash Tables + */ + +/** + * @defgroup Cache_Hash Hash Tables + * @ingroup CACHE + * @{ + */ + +/** + * When passing a key to cache_hash_set or cache_hash_get, this value can be + * passed to indicate a string-valued key, and have cache_hash compute the + * length automatically. + * + * @remark cache_hash will use strlen(key) for the length. The null-terminator + * is not included in the hash value (why throw a constant in?). + * Since the hash table merely references the provided key (rather + * than copying it), cache_hash_this() will return the null-term'd key. + */ +#define CACHE_HASH_KEY_STRING (-1) + +/** + * Abstract type for hash tables. + */ +typedef struct cache_hash_t cache_hash_t; + +/** + * Abstract type for scanning hash tables. + */ +typedef struct cache_hash_index_t cache_hash_index_t; + +/** + * Create a hash table. + * @param size + * @return The hash table just created + */ +CACHE_DECLARE(cache_hash_t *) cache_hash_make(apr_size_t size); + +/** + * Create a hash table. + * @param *ht Pointer to the hash table to be freed. + * @return void + * @remark The caller should ensure that all objects have been removed + * from the cache prior to calling cache_hash_free(). Objects + * not removed from the cache prior to calling cache_hash_free() + * will be unaccessable. + */ +CACHE_DECLARE(void) cache_hash_free(cache_hash_t *ht); + + +/** + * Associate a value with a key in a hash table. + * @param ht The hash table + * @param key Pointer to the key + * @param klen Length of the key. Can be CACHE_HASH_KEY_STRING to use the string length. + * @param val Value to associate with the key + * @remark If the value is NULL the hash entry is deleted. + * @return The value of the deleted cache entry (so the caller can clean it up). + */ +CACHE_DECLARE(void *) cache_hash_set(cache_hash_t *ht, const void *key, + apr_ssize_t klen, const void *val); + +/** + * Look up the value associated with a key in a hash table. + * @param ht The hash table + * @param key Pointer to the key + * @param klen Length of the key. Can be CACHE_HASH_KEY_STRING to use the string length. + * @return Returns NULL if the key is not present. + */ +CACHE_DECLARE(void *) cache_hash_get(cache_hash_t *ht, const void *key, + apr_ssize_t klen); + +/** + * Start iterating over the entries in a hash table. + * @param ht The hash table + * @example + */ +/** + *
    + * 
    + *     int sum_values(cache_hash_t *ht)
    + *     {
    + *         cache_hash_index_t *hi;
    + * 	   void *val;
    + * 	   int sum = 0;
    + * 	   for (hi = cache_hash_first(ht); hi; hi = cache_hash_next(hi)) {
    + * 	       cache_hash_this(hi, NULL, NULL, &val);
    + * 	       sum += *(int *)val;
    + * 	   }
    + * 	   return sum;
    + *     }
    + * 
    + * There is no restriction on adding or deleting hash entries during an
    + * iteration (although the results may be unpredictable unless all you do
    + * is delete the current entry) and multiple iterations can be in
    + * progress at the same time.
    + * 
    + */ +CACHE_DECLARE(cache_hash_index_t *) cache_hash_first(cache_hash_t *ht); + +/** + * Continue iterating over the entries in a hash table. + * @param hi The iteration state + * @return a pointer to the updated iteration state. NULL if there are no more + * entries. + */ +CACHE_DECLARE(cache_hash_index_t *) cache_hash_next(cache_hash_index_t *hi); + +/** + * Get the current entry's details from the iteration state. + * @param hi The iteration state + * @param key Return pointer for the pointer to the key. + * @param klen Return pointer for the key length. + * @param val Return pointer for the associated value. + * @remark The return pointers should point to a variable that will be set to the + * corresponding data, or they may be NULL if the data isn't interesting. + */ +CACHE_DECLARE(void) cache_hash_this(cache_hash_index_t *hi, const void **key, + apr_ssize_t *klen, void **val); + +/** + * Get the number of key/value pairs in the hash table. + * @param ht The hash table + * @return The number of key/value pairs in the hash table. + */ +CACHE_DECLARE(int) cache_hash_count(cache_hash_t *ht); + + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* !CACHE_HASH_H */ diff --git a/trunk/modules/cache/cache_pqueue.c b/trunk/modules/cache/cache_pqueue.c new file mode 100644 index 0000000000..97d0133bf6 --- /dev/null +++ b/trunk/modules/cache/cache_pqueue.c @@ -0,0 +1,290 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_general.h" + +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STDIO_H +#include +#endif + +#if APR_HAVE_STRING_H +#include +#endif + +#include "cache_pqueue.h" +#define left(i) (2*(i)) +#define right(i) ((2*(i))+1) +#define parent(i) ((i)/2) +/* + * Priority queue structure + */ +struct cache_pqueue_t +{ + apr_ssize_t size; + apr_ssize_t avail; + apr_ssize_t step; + cache_pqueue_get_priority pri; + cache_pqueue_getpos get; + cache_pqueue_setpos set; + void **d; +}; + +cache_pqueue_t *cache_pq_init(apr_ssize_t n, + cache_pqueue_get_priority pri, + cache_pqueue_getpos get, + cache_pqueue_setpos set) +{ + cache_pqueue_t *q; + + if (!(q = malloc(sizeof(cache_pqueue_t)))) { + return NULL; + } + + /* Need to allocate n+1 elements since element 0 isn't used. */ + if (!(q->d = malloc(sizeof(void*) * (n+1)))) { + free(q); + return NULL; + } + q->avail = q->step = (n+1); /* see comment above about n+1 */ + q->pri = pri; + q->size = 1; + q->get = get; + q->set = set; + return q; +} +/* + * cleanup + */ +void cache_pq_free(cache_pqueue_t *q) +{ + free(q->d); + free(q); +} +/* + * pqsize: size of the queue. + */ +apr_ssize_t cache_pq_size(cache_pqueue_t *q) +{ + /* queue element 0 exists but doesn't count since it isn't used. */ + return (q->size - 1); +} + +static void cache_pq_bubble_up(cache_pqueue_t *q, apr_ssize_t i) +{ + apr_ssize_t parent_node; + void *moving_node = q->d[i]; + long moving_pri = q->pri(moving_node); + + for (parent_node = parent(i); + ((i > 1) && (q->pri(q->d[parent_node]) < moving_pri)); + i = parent_node, parent_node = parent(i)) + { + q->d[i] = q->d[parent_node]; + q->set(q->d[i], i); + } + + q->d[i] = moving_node; + q->set(moving_node, i); +} + +static apr_ssize_t maxchild(cache_pqueue_t *q, apr_ssize_t i) +{ + apr_ssize_t child_node = left(i); + + if (child_node >= q->size) + return 0; + + if ((child_node+1 < q->size) && + (q->pri(q->d[child_node+1]) > q->pri(q->d[child_node]))) + { + child_node++; /* use right child instead of left */ + } + + return child_node; +} + +static void cache_pq_percolate_down(cache_pqueue_t *q, apr_ssize_t i) +{ + apr_ssize_t child_node; + void *moving_node = q->d[i]; + long moving_pri = q->pri(moving_node); + + while ((child_node = maxchild(q, i)) && + (moving_pri < q->pri(q->d[child_node]))) + { + q->d[i] = q->d[child_node]; + q->set(q->d[i], i); + i = child_node; + } + + q->d[i] = moving_node; + q->set(moving_node, i); +} + +apr_status_t cache_pq_insert(cache_pqueue_t *q, void *d) +{ + void *tmp; + apr_ssize_t i; + apr_ssize_t newsize; + + if (!q) return APR_EGENERAL; + + /* allocate more memory if necessary */ + if (q->size >= q->avail) { + newsize = q->size + q->step; + if (!(tmp = realloc(q->d, sizeof(void*) * newsize))) { + return APR_EGENERAL; + }; + q->d = tmp; + q->avail = newsize; + } + + /* insert item */ + i = q->size++; + q->d[i] = d; + cache_pq_bubble_up(q, i); + return APR_SUCCESS; +} + +/* + * move a existing entry to a new priority + */ +void cache_pq_change_priority(cache_pqueue_t *q, + long old_priority, + long new_priority, + void *d) +{ + apr_ssize_t posn; + + posn = q->get(d); + if (new_priority > old_priority) + cache_pq_bubble_up(q, posn); + else + cache_pq_percolate_down(q, posn); +} + +apr_status_t cache_pq_remove(cache_pqueue_t *q, void *d) +{ + apr_ssize_t posn = q->get(d); + q->d[posn] = q->d[--q->size]; + if (q->pri(q->d[posn]) > q->pri(d)) + cache_pq_bubble_up(q, posn); + else + cache_pq_percolate_down(q, posn); + + return APR_SUCCESS; +} + +void *cache_pq_pop(cache_pqueue_t *q) +{ + void *head; + + if (!q || q->size == 1) + return NULL; + + head = q->d[1]; + q->d[1] = q->d[--q->size]; + cache_pq_percolate_down(q, 1); + + return head; +} + +void *cache_pq_peek(cache_pqueue_t *q) +{ + void *d; + if (!q || q->size == 1) + return NULL; + d = q->d[1]; + return d; +} + +static void cache_pq_set_null( void*d, apr_ssize_t val) +{ + /* do nothing */ +} + +/* + * this is a debug function.. so it's EASY not fast + */ +void cache_pq_dump(cache_pqueue_t *q, + FILE*out, + cache_pqueue_print_entry print) +{ + int i; + + fprintf(stdout,"posn\tleft\tright\tparent\tmaxchild\t...\n"); + for (i = 1; i < q->size ;i++) { + fprintf(stdout, + "%d\t%d\t%d\t%d\t%" APR_SSIZE_T_FMT "\t", + i, + left(i), right(i), parent(i), + maxchild(q, i)); + print(out, q->d[i]); + } +} + +/* + * this is a debug function.. so it's EASY not fast + */ +void cache_pq_print(cache_pqueue_t *q, + FILE*out, + cache_pqueue_print_entry print) +{ + cache_pqueue_t *dup; + dup = cache_pq_init(q->size, q->pri, q->get, cache_pq_set_null); + dup->size = q->size; + dup->avail = q->avail; + dup->step = q->step; + + memcpy(dup->d, q->d, q->size*sizeof(void*)); + + while (cache_pq_size(dup) > 1) { + void *e = NULL; + e = cache_pq_pop(dup); + if (e) + print(out, e); + else + break; + } + cache_pq_free(dup); +} + +static int cache_pq_subtree_is_valid(cache_pqueue_t *q, int pos) +{ + if (left(pos) < q->size) { + /* has a left child */ + if (q->pri(q->d[pos]) < q->pri(q->d[left(pos)])) + return 0; + if (!cache_pq_subtree_is_valid(q, left(pos))) + return 0; + } + if (right(pos) < q->size) { + /* has a right child */ + if (q->pri(q->d[pos]) < q->pri(q->d[right(pos)])) + return 0; + if (!cache_pq_subtree_is_valid(q, right(pos))) + return 0; + } + return 1; +} + +int cache_pq_is_valid(cache_pqueue_t *q) +{ + return cache_pq_subtree_is_valid(q, 1); +} diff --git a/trunk/modules/cache/cache_pqueue.h b/trunk/modules/cache/cache_pqueue.h new file mode 100644 index 0000000000..d9559ebff5 --- /dev/null +++ b/trunk/modules/cache/cache_pqueue.h @@ -0,0 +1,160 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CACHE_PQUEUE_H +#define CACHE_PQUEUE_H + +#include +#include + +#if APR_HAVE_STDIO_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** the cache priority queue handle */ +typedef struct cache_pqueue_t cache_pqueue_t; + +/** + * callback function to assign a priority for a element + * @param a the element + * @return the score (the lower the score the longer it is kept int the queue) + */ +typedef long (*cache_pqueue_set_priority)(long queue_clock, void *a); +typedef long (*cache_pqueue_get_priority)(void *a); + +/** callback function to get a position of a element */ +typedef apr_ssize_t (*cache_pqueue_getpos)(void *a); + +/** + * callback function to set a position of a element + * @param a the element + * @param pos the position to set it to + */ +typedef void (*cache_pqueue_setpos)(void *a, apr_ssize_t pos); + +/** debug callback function to print a entry */ +typedef void (*cache_pqueue_print_entry)(FILE *out, void *a); + +/** + * initialize the queue + * + * @param n the initial estimate of the number of queue items for which memory + * should be preallocated + * @param pri the callback function to run to assign a score to a element + * @param get the callback function to get the current element's position + * @param set the callback function to set the current element's position + * + * @Return the handle or NULL for insufficent memory + */ +cache_pqueue_t *cache_pq_init(apr_ssize_t n, + cache_pqueue_get_priority pri, + cache_pqueue_getpos get, + cache_pqueue_setpos set); +/** + * free all memory used by the queue + * @param q the queue + */ +void cache_pq_free(cache_pqueue_t *q); +/** + * return the size of the queue. + * @param q the queue + */ +apr_ssize_t cache_pq_size(cache_pqueue_t *q); + +/** + * insert an item into the queue. + * @param q the queue + * @param d the item + * @return APR_SUCCESS on success + */ +apr_status_t cache_pq_insert(cache_pqueue_t *q, void *d); + +/* + * move a existing entry to a different priority + * @param q the queue + * @param old the old priority + * @param d the entry + */ +void cache_pq_change_priority(cache_pqueue_t *q, + long old_priority, + long new_priority, + void *d); + +/** + * pop the highest-ranking item from the queue. + * @param p the queue + * @param d where to copy the entry to + * @return NULL on error, otherwise the entry + */ +void *cache_pq_pop(cache_pqueue_t *q); + +/** + * remove an item from the queue. + * @param p the queue + * @param d the entry + * @return APR_SUCCESS on success + */ +apr_status_t cache_pq_remove(cache_pqueue_t *q, void *d); + +/** + * access highest-ranking item without removing it. + * @param q the queue + * @param d the entry + * @return NULL on error, otherwise the entry + */ +void *cache_pq_peek(cache_pqueue_t *q); + +/** + * print the queue + * @internal + * DEBUG function only + * @param q the queue + * @param out the output handle + * @param the callback function to print the entry + */ +void cache_pq_print(cache_pqueue_t *q, + FILE *out, + cache_pqueue_print_entry print); + +/** + * dump the queue and it's internal structure + * @internal + * debug function only + * @param q the queue + * @param out the output handle + * @param the callback function to print the entry + */ +void cache_pq_dump(cache_pqueue_t *q, + FILE *out, + cache_pqueue_print_entry print); + +/** + * checks that the pq is in the right order, etc + * @internal + * debug function only + * @param q the queue + */ +int cache_pq_is_valid(cache_pqueue_t *q); + +#ifdef __cplusplus +} +#endif + +#endif /* !CACHE_PQUEUE_H */ diff --git a/trunk/modules/cache/cache_storage.c b/trunk/modules/cache/cache_storage.c new file mode 100644 index 0000000000..f43bbb1fe6 --- /dev/null +++ b/trunk/modules/cache/cache_storage.c @@ -0,0 +1,328 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE + +#include "mod_cache.h" + +extern APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key; + +extern module AP_MODULE_DECLARE_DATA cache_module; + +/* -------------------------------------------------------------- */ + +/* + * delete all URL entities from the cache + * + */ +int cache_remove_url(request_rec *r, char *url) +{ + cache_provider_list *list; + apr_status_t rv; + char *key; + cache_request_rec *cache = (cache_request_rec *) + ap_get_module_config(r->request_config, &cache_module); + + rv = cache_generate_key(r,r->pool,&key); + if (rv != APR_SUCCESS) { + return rv; + } + + list = cache->providers; + + /* for each specified cache type, delete the URL */ + while(list) { + list->provider->remove_url(key); + list = list->next; + } + return OK; +} + + +/* + * create a new URL entity in the cache + * + * It is possible to store more than once entity per URL. This + * function will always create a new entity, regardless of whether + * other entities already exist for the same URL. + * + * The size of the entity is provided so that a cache module can + * decide whether or not it wants to cache this particular entity. + * If the size is unknown, a size of -1 should be set. + */ +int cache_create_entity(request_rec *r, char *url, apr_off_t size) +{ + cache_provider_list *list; + cache_handle_t *h = apr_pcalloc(r->pool, sizeof(cache_handle_t)); + char *key; + apr_status_t rv; + cache_request_rec *cache = (cache_request_rec *) + ap_get_module_config(r->request_config, &cache_module); + + rv = cache_generate_key(r, r->pool, &key); + if (rv != APR_SUCCESS) { + return rv; + } + + list = cache->providers; + /* for each specified cache type, delete the URL */ + while (list) { + switch (rv = list->provider->create_entity(h, r, key, size)) { + case OK: { + cache->handle = h; + cache->provider = list->provider; + cache->provider_name = list->provider_name; + return OK; + } + case DECLINED: { + list = list->next; + continue; + } + default: { + return rv; + } + } + } + return DECLINED; +} + +static int set_cookie_doo_doo(void *v, const char *key, const char *val) +{ + apr_table_addn(v, key, val); + return 1; +} + +CACHE_DECLARE(void) ap_cache_accept_headers(cache_handle_t *h, request_rec *r, + int preserve_orig) +{ + apr_table_t *cookie_table, *hdr_copy; + const char *v; + + v = apr_table_get(h->resp_hdrs, "Content-Type"); + if (v) { + ap_set_content_type(r, v); + apr_table_unset(h->resp_hdrs, "Content-Type"); + } + + /* If the cache gave us a Last-Modified header, we can't just + * pass it on blindly because of restrictions on future values. + */ + v = apr_table_get(h->resp_hdrs, "Last-Modified"); + if (v) { + ap_update_mtime(r, apr_date_parse_http(v)); + ap_set_last_modified(r); + apr_table_unset(h->resp_hdrs, "Last-Modified"); + } + + /* The HTTP specification says that it is legal to merge duplicate + * headers into one. Some browsers that support Cookies don't like + * merged headers and prefer that each Set-Cookie header is sent + * separately. Lets humour those browsers by not merging. + * Oh what a pain it is. + */ + cookie_table = apr_table_make(r->pool, 2); + apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, + "Set-Cookie", NULL); + apr_table_do(set_cookie_doo_doo, cookie_table, h->resp_hdrs, + "Set-Cookie", NULL); + apr_table_unset(r->err_headers_out, "Set-Cookie"); + apr_table_unset(h->resp_hdrs, "Set-Cookie"); + + if (preserve_orig) { + hdr_copy = apr_table_copy(r->pool, h->resp_hdrs); + apr_table_overlap(hdr_copy, r->headers_out, APR_OVERLAP_TABLES_SET); + r->headers_out = hdr_copy; + } + else { + apr_table_overlap(r->headers_out, h->resp_hdrs, APR_OVERLAP_TABLES_SET); + } + if (!apr_is_empty_table(cookie_table)) { + r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out, + cookie_table); + } +} + +/* + * select a specific URL entity in the cache + * + * It is possible to store more than one entity per URL. Content + * negotiation is used to select an entity. Once an entity is + * selected, details of it are stored in the per request + * config to save time when serving the request later. + * + * This function returns OK if successful, DECLINED if no + * cached entity fits the bill. + */ +int cache_select_url(request_rec *r, char *url) +{ + cache_provider_list *list; + apr_status_t rv; + cache_handle_t *h; + char *key; + cache_request_rec *cache = (cache_request_rec *) + ap_get_module_config(r->request_config, &cache_module); + + rv = cache_generate_key(r, r->pool, &key); + if (rv != APR_SUCCESS) { + return rv; + } + /* go through the cache types till we get a match */ + h = apr_palloc(r->pool, sizeof(cache_handle_t)); + + list = cache->providers; + + while (list) { + switch ((rv = list->provider->open_entity(h, r, key))) { + case OK: { + char *vary = NULL; + int fresh; + + if (list->provider->recall_headers(h, r) != APR_SUCCESS) { + /* TODO: Handle this error */ + return DECLINED; + } + + /* + * Check Content-Negotiation - Vary + * + * At this point we need to make sure that the object we found in + * the cache is the same object that would be delivered to the + * client, when the effects of content negotiation are taken into + * effect. + * + * In plain english, we want to make sure that a language-negotiated + * document in one language is not given to a client asking for a + * language negotiated document in a different language by mistake. + * + * This code makes the assumption that the storage manager will + * cache the req_hdrs if the response contains a Vary + * header. + * + * RFC2616 13.6 and 14.44 describe the Vary mechanism. + */ + vary = apr_pstrdup(r->pool, apr_table_get(h->resp_hdrs, "Vary")); + while (vary && *vary) { + char *name = vary; + const char *h1, *h2; + + /* isolate header name */ + while (*vary && !apr_isspace(*vary) && (*vary != ',')) + ++vary; + while (*vary && (apr_isspace(*vary) || (*vary == ','))) { + *vary = '\0'; + ++vary; + } + + /* + * is this header in the request and the header in the cached + * request identical? If not, we give up and do a straight get + */ + h1 = apr_table_get(r->headers_in, name); + h2 = apr_table_get(h->req_hdrs, name); + if (h1 == h2) { + /* both headers NULL, so a match - do nothing */ + } + else if (h1 && h2 && !strcmp(h1, h2)) { + /* both headers exist and are equal - do nothing */ + } + else { + /* headers do not match, so Vary failed */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, + r->server, + "cache_select_url(): Vary header mismatch."); + return DECLINED; + } + } + + cache->provider = list->provider; + cache->provider_name = list->provider_name; + + /* Is our cached response fresh enough? */ + fresh = ap_cache_check_freshness(h, r); + if (!fresh) { + const char *etag, *lastmod; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "Cached response for %s isn't fresh. Adding/replacing " + "conditional request headers.", r->uri); + + /* Make response into a conditional */ + cache->stale_headers = apr_table_copy(r->pool, + r->headers_in); + + /* We can only revalidate with our own conditionals: remove the + * conditions from the original request. + */ + apr_table_unset(r->headers_in, "If-Match"); + apr_table_unset(r->headers_in, "If-Modified-Since"); + apr_table_unset(r->headers_in, "If-None-Match"); + apr_table_unset(r->headers_in, "If-Range"); + apr_table_unset(r->headers_in, "If-Unmodified-Since"); + + etag = apr_table_get(h->resp_hdrs, "ETag"); + lastmod = apr_table_get(h->resp_hdrs, "Last-Modified"); + + if (etag || lastmod) { + /* If we have a cached etag and/or Last-Modified add in + * our own conditionals. + */ + + if (etag) { + apr_table_set(r->headers_in, "If-None-Match", etag); + } + + if (lastmod) { + apr_table_set(r->headers_in, "If-Modified-Since", + lastmod); + } + cache->stale_handle = h; + } + + return DECLINED; + } + + /* Okay, this response looks okay. Merge in our stuff and go. */ + ap_cache_accept_headers(h, r, 0); + + cache->handle = h; + return OK; + } + case DECLINED: { + /* try again with next cache type */ + list = list->next; + continue; + } + default: { + /* oo-er! an error */ + return rv; + } + } + } + return DECLINED; +} + +apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p, + char**key) +{ + if (r->hostname) { + *key = apr_pstrcat(p, r->hostname, r->uri, "?", r->args, NULL); + } + else { + *key = apr_pstrcat(p, r->uri, "?", r->args, NULL); + } + return APR_SUCCESS; +} + diff --git a/trunk/modules/cache/cache_util.c b/trunk/modules/cache/cache_util.c new file mode 100644 index 0000000000..21c6fee5bb --- /dev/null +++ b/trunk/modules/cache/cache_util.c @@ -0,0 +1,536 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE + +#include "mod_cache.h" + +#include + +/* -------------------------------------------------------------- */ + +extern module AP_MODULE_DECLARE_DATA cache_module; + + +CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r, + cache_server_conf *conf, + const char *url) +{ + cache_provider_list *providers = NULL; + int i; + + /* we can't cache if there's no URL */ + /* Is this case even possible?? */ + if (!url) return NULL; + + /* loop through all the cacheenable entries */ + for (i = 0; i < conf->cacheenable->nelts; i++) { + struct cache_enable *ent = + (struct cache_enable *)conf->cacheenable->elts; + if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) { + /* Fetch from global config and add to the list. */ + cache_provider *provider; + provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent[i].type, + "0"); + if (!provider) { + /* Log an error! */ + } + else { + cache_provider_list *newp; + newp = apr_pcalloc(r->pool, sizeof(cache_provider_list)); + newp->provider_name = ent[i].type; + newp->provider = provider; + + if (!providers) { + providers = newp; + } + else { + cache_provider_list *last = providers; + + while (last->next) { + last = last->next; + } + last->next = newp; + } + } + } + } + + /* then loop through all the cachedisable entries + * Looking for urls that contain the full cachedisable url and possibly + * more. + * This means we are disabling cachedisable url and below... + */ + for (i = 0; i < conf->cachedisable->nelts; i++) { + struct cache_disable *ent = + (struct cache_disable *)conf->cachedisable->elts; + if ((ent[i].url) && !strncasecmp(url, ent[i].url, ent[i].urllen)) { + /* Stop searching now. */ + return NULL; + } + } + + return providers; +} + + +/* do a HTTP/1.1 age calculation */ +CACHE_DECLARE(apr_int64_t) ap_cache_current_age(cache_info *info, + const apr_time_t age_value, + apr_time_t now) +{ + apr_time_t apparent_age, corrected_received_age, response_delay, + corrected_initial_age, resident_time, current_age, + age_value_usec; + + age_value_usec = apr_time_from_sec(age_value); + + /* Perform an HTTP/1.1 age calculation. (RFC2616 13.2.3) */ + + apparent_age = MAX(0, info->response_time - info->date); + corrected_received_age = MAX(apparent_age, age_value_usec); + response_delay = info->response_time - info->request_time; + corrected_initial_age = corrected_received_age + response_delay; + resident_time = now - info->response_time; + current_age = corrected_initial_age + resident_time; + + return apr_time_sec(current_age); +} + +CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h, + request_rec *r) +{ + apr_int64_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale; + apr_int64_t minfresh; + const char *cc_cresp, *cc_req; + const char *pragma; + const char *agestr = NULL; + const char *expstr = NULL; + char *val; + apr_time_t age_c = 0; + cache_info *info = &(h->cache_obj->info); + cache_server_conf *conf = + (cache_server_conf *)ap_get_module_config(r->server->module_config, + &cache_module); + + /* + * We now want to check if our cached data is still fresh. This depends + * on a few things, in this order: + * + * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache in + * either the request or the cached response means that we must + * revalidate the request unconditionally, overriding any expiration + * mechanism. It's equivalent to max-age=0,must-revalidate. + * + * - RFC2616 14.32 Pragma: no-cache This is treated the same as + * Cache-Control: no-cache. + * + * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate, + * proxy-revalidate if the max-stale request header exists, modify the + * stale calculations below so that an object can be at most + * seconds stale before we request a revalidation, _UNLESS_ a + * must-revalidate or proxy-revalidate cached response header exists to + * stop us doing this. + * + * - RFC2616 14.9.3 Cache-Control: s-maxage the origin server specifies the + * maximum age an object can be before it is considered stale. This + * directive has the effect of proxy|must revalidate, which in turn means + * simple ignore any max-stale setting. + * + * - RFC2616 14.9.4 Cache-Control: max-age this header can appear in both + * requests and responses. If both are specified, the smaller of the two + * takes priority. + * + * - RFC2616 14.21 Expires: if this request header exists in the cached + * entity, and it's value is in the past, it has expired. + * + */ + + /* This value comes from the client's initial request. */ + cc_req = apr_table_get(r->headers_in, "Cache-Control"); + pragma = apr_table_get(r->headers_in, "Pragma"); + + if (ap_cache_liststr(NULL, pragma, "no-cache", NULL) + || ap_cache_liststr(NULL, cc_req, "no-cache", NULL)) { + + if (!conf->ignorecachecontrol) { + /* Treat as stale, causing revalidation */ + return 0; + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Incoming request is asking for a uncached version of " + "%s, but we know better and are ignoring it", + r->unparsed_uri); + } + + /* These come from the cached entity. */ + cc_cresp = apr_table_get(h->resp_hdrs, "Cache-Control"); + expstr = apr_table_get(h->resp_hdrs, "Expires"); + + if ((agestr = apr_table_get(h->resp_hdrs, "Age"))) { + age_c = apr_atoi64(agestr); + } + + /* calculate age of object */ + age = ap_cache_current_age(info, age_c, r->request_time); + + /* extract s-maxage */ + if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "s-maxage", &val)) { + smaxage = apr_atoi64(val); + } + else { + smaxage = -1; + } + + /* extract max-age from request */ + if (!conf->ignorecachecontrol + && cc_req && ap_cache_liststr(r->pool, cc_req, "max-age", &val)) { + maxage_req = apr_atoi64(val); + } + else { + maxage_req = -1; + } + + /* extract max-age from response */ + if (cc_cresp && ap_cache_liststr(r->pool, cc_cresp, "max-age", &val)) { + maxage_cresp = apr_atoi64(val); + } + else { + maxage_cresp = -1; + } + + /* + * if both maxage request and response, the smaller one takes priority + */ + if (maxage_req == -1) { + maxage = maxage_cresp; + } + else if (maxage_cresp == -1) { + maxage = maxage_req; + } + else { + maxage = MIN(maxage_req, maxage_cresp); + } + + /* extract max-stale */ + if (cc_req && ap_cache_liststr(r->pool, cc_req, "max-stale", &val)) { + maxstale = apr_atoi64(val); + } + else { + maxstale = 0; + } + + /* extract min-fresh */ + if (!conf->ignorecachecontrol + && cc_req && ap_cache_liststr(r->pool, cc_req, "min-fresh", &val)) { + minfresh = apr_atoi64(val); + } + else { + minfresh = 0; + } + + /* override maxstale if must-revalidate or proxy-revalidate */ + if (maxstale && ((cc_cresp && + ap_cache_liststr(NULL, cc_cresp, + "must-revalidate", NULL)) || + (cc_cresp && + ap_cache_liststr(NULL, cc_cresp, + "proxy-revalidate", NULL)))) { + maxstale = 0; + } + + /* handle expiration */ + if (((smaxage != -1) && (age < (smaxage - minfresh))) || + ((maxage != -1) && (age < (maxage + maxstale - minfresh))) || + ((smaxage == -1) && (maxage == -1) && + (info->expire != APR_DATE_BAD) && + (age < (apr_time_sec(info->expire - info->date) + maxstale - minfresh)))) { + const char *warn_head; + + warn_head = apr_table_get(h->resp_hdrs, "Warning"); + + /* it's fresh darlings... */ + /* set age header on response */ + apr_table_set(h->resp_hdrs, "Age", + apr_psprintf(r->pool, "%lu", (unsigned long)age)); + + /* add warning if maxstale overrode freshness calculation */ + if (!(((smaxage != -1) && age < smaxage) || + ((maxage != -1) && age < maxage) || + (info->expire != APR_DATE_BAD && + (info->expire - info->date) > age))) { + /* make sure we don't stomp on a previous warning */ + if ((warn_head == NULL) || + ((warn_head != NULL) && (ap_strstr_c(warn_head, "110") == NULL))) { + apr_table_merge(h->resp_hdrs, "Warning", + "110 Response is stale"); + } + } + /* + * If none of Expires, Cache-Control: max-age, or Cache-Control: + * s-maxage appears in the response, and the respose header age + * calculated is more than 24 hours add the warning 113 + */ + if ((maxage_cresp == -1) && (smaxage == -1) && + (expstr == NULL) && (age > 86400)) { + + /* Make sure we don't stomp on a previous warning, and don't dup + * a 113 marning that is already present. Also, make sure to add + * the new warning to the correct *headers_out location. + */ + if ((warn_head == NULL) || + ((warn_head != NULL) && (ap_strstr_c(warn_head, "113") == NULL))) { + apr_table_merge(h->resp_hdrs, "Warning", + "113 Heuristic expiration"); + } + } + return 1; /* Cache object is fresh (enough) */ + } + + return 0; /* Cache object is stale */ +} + +/* + * list is a comma-separated list of case-insensitive tokens, with + * optional whitespace around the tokens. + * The return returns 1 if the token val is found in the list, or 0 + * otherwise. + */ +CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list, + const char *key, char **val) +{ + apr_size_t key_len; + const char *next; + + if (!list) { + return 0; + } + + key_len = strlen(key); + next = list; + + for (;;) { + + /* skip whitespace and commas to find the start of the next key */ + while (*next && (apr_isspace(*next) || (*next == ','))) { + next++; + } + + if (!*next) { + return 0; + } + + if (!strncasecmp(next, key, key_len)) { + /* this field matches the key (though it might just be + * a prefix match, so make sure the match is followed + * by either a space or an equals sign) + */ + next += key_len; + if (!*next || (*next == '=') || apr_isspace(*next) || + (*next == ',')) { + /* valid match */ + if (val) { + while (*next && (*next != '=') && (*next != ',')) { + next++; + } + if (*next == '=') { + next++; + while (*next && apr_isspace(*next )) { + next++; + } + if (!*next) { + *val = NULL; + } + else { + const char *val_start = next; + while (*next && !apr_isspace(*next) && + (*next != ',')) { + next++; + } + *val = apr_pstrmemdup(p, val_start, + next - val_start); + } + } + } + return 1; + } + } + + /* skip to the next field */ + do { + next++; + if (!*next) { + return 0; + } + } while (*next != ','); + } +} + +/* return each comma separated token, one at a time */ +CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, + const char **str) +{ + apr_size_t i; + const char *s; + + s = ap_strchr_c(list, ','); + if (s != NULL) { + i = s - list; + do + s++; + while (apr_isspace(*s)) + ; /* noop */ + } + else + i = strlen(list); + + while (i > 0 && apr_isspace(list[i - 1])) + i--; + + *str = s; + if (i) + return apr_pstrndup(p, list, i); + else + return NULL; +} + +/* + * Converts apr_time_t expressed as hex digits to + * a true apr_time_t. + */ +CACHE_DECLARE(apr_time_t) ap_cache_hex2usec(const char *x) +{ + int i, ch; + apr_time_t j; + for (i = 0, j = 0; i < sizeof(j) * 2; i++) { + ch = x[i]; + j <<= 4; + if (apr_isdigit(ch)) + j |= ch - '0'; + else if (apr_isupper(ch)) + j |= ch - ('A' - 10); + else + j |= ch - ('a' - 10); + } + return j; +} + +/* + * Converts apr_time_t to apr_time_t expressed as hex digits. + */ +CACHE_DECLARE(void) ap_cache_usec2hex(apr_time_t j, char *y) +{ + int i, ch; + + for (i = (sizeof(j) * 2)-1; i >= 0; i--) { + ch = (int)(j & 0xF); + j >>= 4; + if (ch >= 10) + y[i] = ch + ('A' - 10); + else + y[i] = ch + '0'; + } + y[sizeof(j) * 2] = '\0'; +} + +static void cache_hash(const char *it, char *val, int ndepth, int nlength) +{ + apr_md5_ctx_t context; + unsigned char digest[16]; + char tmp[22]; + int i, k, d; + unsigned int x; + static const char enc_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@"; + + apr_md5_init(&context); + apr_md5_update(&context, (const unsigned char *) it, strlen(it)); + apr_md5_final(digest, &context); + + /* encode 128 bits as 22 characters, using a modified uuencoding + * the encoding is 3 bytes -> 4 characters* i.e. 128 bits is + * 5 x 3 bytes + 1 byte -> 5 * 4 characters + 2 characters + */ + for (i = 0, k = 0; i < 15; i += 3) { + x = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2]; + tmp[k++] = enc_table[x >> 18]; + tmp[k++] = enc_table[(x >> 12) & 0x3f]; + tmp[k++] = enc_table[(x >> 6) & 0x3f]; + tmp[k++] = enc_table[x & 0x3f]; + } + + /* one byte left */ + x = digest[15]; + tmp[k++] = enc_table[x >> 2]; /* use up 6 bits */ + tmp[k++] = enc_table[(x << 4) & 0x3f]; + + /* now split into directory levels */ + for (i = k = d = 0; d < ndepth; ++d) { + memcpy(&val[i], &tmp[k], nlength); + k += nlength; + val[i + nlength] = '/'; + i += nlength + 1; + } + memcpy(&val[i], &tmp[k], 22 - k); + val[i + 22 - k] = '\0'; +} + +CACHE_DECLARE(char *)ap_cache_generate_name(apr_pool_t *p, int dirlevels, + int dirlength, const char *name) +{ + char hashfile[66]; + cache_hash(name, hashfile, dirlevels, dirlength); + return apr_pstrdup(p, hashfile); +} + +/* Create a new table consisting of those elements from an input + * headers table that are allowed to be stored in a cache. + */ +CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(apr_pool_t *pool, + apr_table_t *t, + server_rec *s) +{ + cache_server_conf *conf; + char **header; + int i; + + /* Make a copy of the headers, and remove from + * the copy any hop-by-hop headers, as defined in Section + * 13.5.1 of RFC 2616 + */ + apr_table_t *headers_out; + headers_out = apr_table_copy(pool, t); + apr_table_unset(headers_out, "Connection"); + apr_table_unset(headers_out, "Keep-Alive"); + apr_table_unset(headers_out, "Proxy-Authenticate"); + apr_table_unset(headers_out, "Proxy-Authorization"); + apr_table_unset(headers_out, "TE"); + apr_table_unset(headers_out, "Trailers"); + apr_table_unset(headers_out, "Transfer-Encoding"); + apr_table_unset(headers_out, "Upgrade"); + + conf = (cache_server_conf *)ap_get_module_config(s->module_config, + &cache_module); + /* Remove the user defined headers set with CacheIgnoreHeaders. + * This may break RFC 2616 compliance on behalf of the administrator. + */ + header = (char **)conf->ignore_headers->elts; + for (i = 0; i < conf->ignore_headers->nelts; i++) { + apr_table_unset(headers_out, header[i]); + } + return headers_out; +} diff --git a/trunk/modules/cache/config.m4 b/trunk/modules/cache/config.m4 new file mode 100644 index 0000000000..9572e06d5b --- /dev/null +++ b/trunk/modules/cache/config.m4 @@ -0,0 +1,26 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(cache) + +APACHE_MODULE(file_cache, File cache, , , no) + +dnl # list of object files for mod_cache +cache_objs="dnl +mod_cache.lo dnl +cache_storage.lo dnl +cache_util.lo dnl +" +dnl # list of object files for mod_mem_cache +mem_cache_objs="dnl +mod_mem_cache.lo dnl +cache_cache.lo dnl +cache_pqueue.lo dnl +cache_hash.lo dnl +" +APACHE_MODULE(cache, dynamic file caching, $cache_objs, , no) +APACHE_MODULE(disk_cache, disk caching module, , , no) +APACHE_MODULE(mem_cache, memory caching module, $mem_cache_objs, , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/cache/mod_cache.c b/trunk/modules/cache/mod_cache.c new file mode 100644 index 0000000000..4be8970917 --- /dev/null +++ b/trunk/modules/cache/mod_cache.c @@ -0,0 +1,1047 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE + +#include "mod_cache.h" + +module AP_MODULE_DECLARE_DATA cache_module; +APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key; + +/* -------------------------------------------------------------- */ + + +/* Handles for cache filters, resolved at startup to eliminate + * a name-to-function mapping on each request + */ +static ap_filter_rec_t *cache_save_filter_handle; +static ap_filter_rec_t *cache_out_filter_handle; + +/* + * CACHE handler + * ------------- + * + * Can we deliver this request from the cache? + * If yes: + * deliver the content by installing the CACHE_OUT filter. + * If no: + * check whether we're allowed to try cache it + * If yes: + * add CACHE_SAVE filter + * If No: + * oh well. + */ + +static int cache_url_handler(request_rec *r, int lookup) +{ + apr_status_t rv; + const char *auth; + apr_uri_t uri; + char *url; + char *path; + cache_provider_list *providers; + cache_info *info; + cache_request_rec *cache; + cache_server_conf *conf; + apr_bucket_brigade *out; + + /* Delay initialization until we know we are handling a GET */ + if (r->method_number != M_GET) { + return DECLINED; + } + + uri = r->parsed_uri; + url = r->unparsed_uri; + path = uri.path; + info = NULL; + + conf = (cache_server_conf *) ap_get_module_config(r->server->module_config, + &cache_module); + + /* + * Which cache module (if any) should handle this request? + */ + if (!(providers = ap_cache_get_providers(r, conf, path))) { + return DECLINED; + } + + /* make space for the per request config */ + cache = (cache_request_rec *) ap_get_module_config(r->request_config, + &cache_module); + if (!cache) { + cache = apr_pcalloc(r->pool, sizeof(cache_request_rec)); + ap_set_module_config(r->request_config, &cache_module, cache); + } + + /* save away the possible providers */ + cache->providers = providers; + + /* + * Are we allowed to serve cached info at all? + */ + + /* find certain cache controlling headers */ + auth = apr_table_get(r->headers_in, "Authorization"); + + /* First things first - does the request allow us to return + * cached information at all? If not, just decline the request. + */ + if (auth) { + return DECLINED; + } + + /* + * Try to serve this request from the cache. + * + * If no existing cache file (DECLINED) + * add cache_save filter + * If cached file (OK) + * clear filter stack + * add cache_out filter + * return OK + */ + rv = cache_select_url(r, url); + if (rv != OK) { + if (rv == DECLINED) { + if (!lookup) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "Adding CACHE_SAVE filter."); + + /* add cache_save filter to cache this request */ + ap_add_output_filter_handle(cache_save_filter_handle, NULL, r, + r->connection); + } + else if (cache->stale_headers) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "Restoring request headers."); + + r->headers_in = cache->stale_headers; + } + } + else { + /* error */ + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "cache: error returned while checking for cached " + "file by %s cache", cache->provider_name); + } + return DECLINED; + } + + rv = ap_meets_conditions(r); + if (rv != OK) { + /* Return cached status. */ + return rv; + } + + /* If we're a lookup, we can exit now instead of serving the content. */ + if (lookup) { + return OK; + } + + /* Serve up the content */ + + /* We are in the quick handler hook, which means that no output + * filters have been set. So lets run the insert_filter hook. + */ + ap_run_insert_filter(r); + ap_add_output_filter_handle(cache_out_filter_handle, NULL, + r, r->connection); + + /* kick off the filter stack */ + out = apr_brigade_create(r->pool, r->connection->bucket_alloc); + rv = ap_pass_brigade(r->output_filters, out); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "cache: error returned while trying to return %s " + "cached data", + cache->provider_name); + return rv; + } + + return OK; +} + +/* + * CACHE_OUT filter + * ---------------- + * + * Deliver cached content (headers and body) up the stack. + */ +static int cache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + cache_request_rec *cache; + + cache = (cache_request_rec *) ap_get_module_config(r->request_config, + &cache_module); + + if (!cache) { + /* user likely configured CACHE_OUT manually; they should use mod_cache + * configuration to do that */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "CACHE_OUT enabled unexpectedly"); + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "cache: running CACHE_OUT filter"); + + /* recall_headers() was called in cache_select_url() */ + cache->provider->recall_body(cache->handle, r->pool, bb); + + /* This filter is done once it has served up its content */ + ap_remove_output_filter(f); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "cache: serving %s", r->uri); + return ap_pass_brigade(f->next, bb); +} + + +/* + * CACHE_SAVE filter + * --------------- + * + * Decide whether or not this content should be cached. + * If we decide no it should not: + * remove the filter from the chain + * If we decide yes it should: + * Have we already started saving the response? + * If we have started, pass the data to the storage manager via store_body + * Otherwise: + * Check to see if we *can* save this particular response. + * If we can, call cache_create_entity() and save the headers and body + * Finally, pass the data to the next filter (the network or whatever) + */ + +static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in) +{ + int rv = !OK; + int date_in_errhdr = 0; + request_rec *r = f->r; + cache_request_rec *cache; + cache_server_conf *conf; + char *url = r->unparsed_uri; + const char *cc_in, *cc_out, *cl, *vary_out; + const char *exps, *lastmods, *dates, *etag; + apr_time_t exp, date, lastmod, now; + apr_off_t size; + cache_info *info = NULL; + char *reason; + apr_pool_t *p; + + conf = (cache_server_conf *) ap_get_module_config(r->server->module_config, + &cache_module); + + /* If the request has Cache-Control: no-store from RFC 2616, don't store + * unless CacheStoreNoStore is active. + */ + cc_in = apr_table_get(r->headers_in, "Cache-Control"); + vary_out = apr_table_get(r->headers_out, "Vary"); + if (r->no_cache || + ap_cache_liststr(NULL, vary_out, "*", NULL) || + (!conf->store_nostore && + ap_cache_liststr(NULL, cc_in, "no-store", NULL))) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, in); + } + + /* Setup cache_request_rec */ + cache = (cache_request_rec *) ap_get_module_config(r->request_config, + &cache_module); + if (!cache) { + /* user likely configured CACHE_SAVE manually; they should really use + * mod_cache configuration to do that + */ + cache = apr_pcalloc(r->pool, sizeof(cache_request_rec)); + ap_set_module_config(r->request_config, &cache_module, cache); + } + + reason = NULL; + p = r->pool; + /* + * Pass Data to Cache + * ------------------ + * This section passes the brigades into the cache modules, but only + * if the setup section (see below) is complete. + */ + if (cache->block_response) { + /* We've already sent down the response and EOS. So, ignore + * whatever comes now. + */ + return APR_SUCCESS; + } + + /* have we already run the cachability check and set up the + * cached file handle? + */ + if (cache->in_checked) { + /* pass the brigades into the cache, then pass them + * up the filter stack + */ + rv = cache->provider->store_body(cache->handle, r, in); + if (rv != APR_SUCCESS) { + ap_remove_output_filter(f); + } + return ap_pass_brigade(f->next, in); + } + + /* + * Setup Data in Cache + * ------------------- + * This section opens the cache entity and sets various caching + * parameters, and decides whether this URL should be cached at + * all. This section is* run before the above section. + */ + + /* read expiry date; if a bad date, then leave it so the client can + * read it + */ + exps = apr_table_get(r->err_headers_out, "Expires"); + if (exps == NULL) { + exps = apr_table_get(r->headers_out, "Expires"); + } + if (exps != NULL) { + if (APR_DATE_BAD == (exp = apr_date_parse_http(exps))) { + exps = NULL; + } + } + else { + exp = APR_DATE_BAD; + } + + /* read the last-modified date; if the date is bad, then delete it */ + lastmods = apr_table_get(r->err_headers_out, "Last-Modified"); + if (lastmods == NULL) { + lastmods = apr_table_get(r->headers_out, "Last-Modified"); + } + if (lastmods != NULL) { + lastmod = apr_date_parse_http(lastmods); + if (lastmod == APR_DATE_BAD) { + lastmods = NULL; + } + } + else { + lastmod = APR_DATE_BAD; + } + + /* read the etag and cache-control from the entity */ + etag = apr_table_get(r->err_headers_out, "Etag"); + if (etag == NULL) { + etag = apr_table_get(r->headers_out, "Etag"); + } + cc_out = apr_table_get(r->err_headers_out, "Cache-Control"); + if (cc_out == NULL) { + cc_out = apr_table_get(r->headers_out, "Cache-Control"); + } + + /* + * what responses should we not cache? + * + * At this point we decide based on the response headers whether it + * is appropriate _NOT_ to cache the data from the server. There are + * a whole lot of conditions that prevent us from caching this data. + * They are tested here one by one to be clear and unambiguous. + */ + if (r->status != HTTP_OK && r->status != HTTP_NON_AUTHORITATIVE + && r->status != HTTP_MULTIPLE_CHOICES + && r->status != HTTP_MOVED_PERMANENTLY + && r->status != HTTP_NOT_MODIFIED) { + /* RFC2616 13.4 we are allowed to cache 200, 203, 206, 300, 301 or 410 + * We don't cache 206, because we don't (yet) cache partial responses. + * We include 304 Not Modified here too as this is the origin server + * telling us to serve the cached copy. + */ + reason = apr_psprintf(p, "Response status %d", r->status); + } + else if (exps != NULL && exp == APR_DATE_BAD) { + /* if a broken Expires header is present, don't cache it */ + reason = apr_pstrcat(p, "Broken expires header: ", exps, NULL); + } + else if (r->args && exps == NULL) { + /* if query string present but no expiration time, don't cache it + * (RFC 2616/13.9) + */ + reason = "Query string present but no expires header"; + } + else if (r->status == HTTP_NOT_MODIFIED && + !cache->handle && !cache->stale_handle) { + /* if the server said 304 Not Modified but we have no cache + * file - pass this untouched to the user agent, it's not for us. + */ + reason = "HTTP Status 304 Not Modified"; + } + else if (r->status == HTTP_OK && lastmods == NULL && etag == NULL + && (exps == NULL) && (conf->no_last_mod_ignore ==0)) { + /* 200 OK response from HTTP/1.0 and up without Last-Modified, + * Etag, or Expires headers. + */ + /* Note: mod-include clears last_modified/expires/etags - this + * is why we have an optional function for a key-gen ;-) + */ + reason = "No Last-Modified, Etag, or Expires headers"; + } + else if (r->header_only) { + /* HEAD requests */ + reason = "HTTP HEAD request"; + } + else if (!conf->store_nostore && + ap_cache_liststr(NULL, cc_out, "no-store", NULL)) { + /* RFC2616 14.9.2 Cache-Control: no-store response + * indicating do not cache, or stop now if you are + * trying to cache it. + */ + /* FIXME: The Cache-Control: no-store could have come in on a 304, + * FIXME: while the original request wasn't conditional. IOW, we + * FIXME: made the the request conditional earlier to revalidate + * FIXME: our cached response. + */ + reason = "Cache-Control: no-store present"; + } + else if (!conf->store_private && + ap_cache_liststr(NULL, cc_out, "private", NULL)) { + /* RFC2616 14.9.1 Cache-Control: private response + * this object is marked for this user's eyes only. Behave + * as a tunnel. + */ + /* FIXME: See above (no-store) */ + reason = "Cache-Control: private present"; + } + else if (apr_table_get(r->headers_in, "Authorization") != NULL + && !(ap_cache_liststr(NULL, cc_out, "s-maxage", NULL) + || ap_cache_liststr(NULL, cc_out, "must-revalidate", NULL) + || ap_cache_liststr(NULL, cc_out, "public", NULL))) { + /* RFC2616 14.8 Authorisation: + * if authorisation is included in the request, we don't cache, + * but we can cache if the following exceptions are true: + * 1) If Cache-Control: s-maxage is included + * 2) If Cache-Control: must-revalidate is included + * 3) If Cache-Control: public is included + */ + reason = "Authorization required"; + } + else if (r->no_cache) { + /* or we've been asked not to cache it above */ + reason = "no_cache present"; + } + + if (reason) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "cache: %s not cached. Reason: %s", url, reason); + /* remove this object from the cache + * BillS Asks.. Why do we need to make this call to remove_url? + * leave it in for now.. + */ + cache_remove_url(r, url); + + /* remove this filter from the chain */ + ap_remove_output_filter(f); + + /* ship the data up the stack */ + return ap_pass_brigade(f->next, in); + } + + /* Make it so that we don't execute this path again. */ + cache->in_checked = 1; + + /* Set the content length if known. + */ + cl = apr_table_get(r->err_headers_out, "Content-Length"); + if (cl == NULL) { + cl = apr_table_get(r->headers_out, "Content-Length"); + } + if (cl) { + char *errp; + if (apr_strtoff(&size, cl, &errp, 10) || *errp || size < 0) { + cl = NULL; /* parse error, see next 'if' block */ + } + } + + if (!cl) { + /* if we don't get the content-length, see if we have all the + * buckets and use their length to calculate the size + */ + apr_bucket *e; + int all_buckets_here=0; + int unresolved_length = 0; + size=0; + for (e = APR_BRIGADE_FIRST(in); + e != APR_BRIGADE_SENTINEL(in); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + all_buckets_here=1; + break; + } + if (APR_BUCKET_IS_FLUSH(e)) { + unresolved_length = 1; + continue; + } + if (e->length == (apr_size_t)-1) { + break; + } + size += e->length; + } + if (!all_buckets_here) { + size = -1; + } + } + + /* It's safe to cache the response. + * + * There are two possiblities at this point: + * - cache->handle == NULL. In this case there is no previously + * cached entity anywhere on the system. We must create a brand + * new entity and store the response in it. + * - cache->stale_handle != NULL. In this case there is a stale + * entity in the system which needs to be replaced by new + * content (unless the result was 304 Not Modified, which means + * the cached entity is actually fresh, and we should update + * the headers). + */ + + /* Did we have a stale cache entry that really is stale? */ + if (cache->stale_handle) { + if (r->status == HTTP_NOT_MODIFIED) { + /* Oh, hey. It isn't that stale! Yay! */ + cache->handle = cache->stale_handle; + info = &cache->handle->cache_obj->info; + rv = OK; + } + else { + /* Oh, well. Toss it. */ + cache->provider->remove_entity(cache->stale_handle); + /* Treat the request as if it wasn't conditional. */ + cache->stale_handle = NULL; + } + } + + /* no cache handle, create a new entity */ + if (!cache->handle) { + rv = cache_create_entity(r, url, size); + info = apr_pcalloc(r->pool, sizeof(cache_info)); + /* We only set info->status upon the initial creation. */ + info->status = r->status; + } + + if (rv != OK) { + /* Caching layer declined the opportunity to cache the response */ + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, in); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "cache: Caching url: %s", url); + + /* + * We now want to update the cache file header information with + * the new date, last modified, expire and content length and write + * it away to our cache file. First, we determine these values from + * the response, using heuristics if appropriate. + * + * In addition, we make HTTP/1.1 age calculations and write them away + * too. + */ + + /* Read the date. Generate one if one is not supplied */ + dates = apr_table_get(r->err_headers_out, "Date"); + if (dates != NULL) { + date_in_errhdr = 1; + } + else { + dates = apr_table_get(r->headers_out, "Date"); + } + if (dates != NULL) { + info->date = apr_date_parse_http(dates); + } + else { + info->date = APR_DATE_BAD; + } + + now = apr_time_now(); + if (info->date == APR_DATE_BAD) { /* No, or bad date */ + char *dates; + /* no date header (or bad header)! */ + /* add one; N.B. use the time _now_ rather than when we were checking + * the cache + */ + if (date_in_errhdr == 1) { + apr_table_unset(r->err_headers_out, "Date"); + } + date = now; + dates = apr_pcalloc(r->pool, MAX_STRING_LEN); + apr_rfc822_date(dates, now); + apr_table_set(r->headers_out, "Date", dates); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "cache: Added date header"); + info->date = date; + } + else { + date = info->date; + } + + /* set response_time for HTTP/1.1 age calculations */ + info->response_time = now; + + /* get the request time */ + info->request_time = r->request_time; + + /* check last-modified date */ + if (lastmod != APR_DATE_BAD && lastmod > date) { + /* if it's in the future, then replace by date */ + lastmod = date; + lastmods = dates; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + r->server, + "cache: Last modified is in the future, " + "replacing with now"); + } + + /* if no expiry date then + * if lastmod + * expiry date = date + min((date - lastmod) * factor, maxexpire) + * else + * expire date = date + defaultexpire + */ + if (exp == APR_DATE_BAD) { + char expire_hdr[APR_RFC822_DATE_LEN]; + + /* if lastmod == date then you get 0*conf->factor which results in + * an expiration time of now. This causes some problems with + * freshness calculations, so we choose the else path... + */ + if ((lastmod != APR_DATE_BAD) && (lastmod < date)) { + apr_time_t x = (apr_time_t) ((date - lastmod) * conf->factor); + + if (x > conf->maxex) { + x = conf->maxex; + } + exp = date + x; + apr_rfc822_date(expire_hdr, exp); + apr_table_set(r->headers_out, "Expires", expire_hdr); + } + else { + exp = date + conf->defex; + apr_rfc822_date(expire_hdr, exp); + apr_table_set(r->headers_out, "Expires", expire_hdr); + } + } + info->expire = exp; + + /* We found a stale entry which wasn't really stale. */ + if (cache->stale_handle) { + /* Load in the saved status and clear the status line. */ + r->status = info->status; + r->status_line = NULL; + + /* RFC 2616 10.3.5 states that entity headers are not supposed + * to be in the 304 response. Therefore, we need to combine the + * response headers with the cached headers *before* we update + * the cached headers. + * + * However, before doing that, we need to first merge in + * err_headers_out and we also need to strip any hop-by-hop + * headers that might have snuck in. + */ + r->headers_out = apr_table_overlay(r->pool, r->headers_out, + r->err_headers_out); + r->headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out, + r->server); + apr_table_clear(r->err_headers_out); + + /* Merge in our cached headers. However, keep any updated values. */ + ap_cache_accept_headers(cache->handle, r, 1); + } + + /* Write away header information to cache. */ + rv = cache->provider->store_headers(cache->handle, r, info); + + /* Did we just update the cached headers on a revalidated response? + * + * If so, we can now decide what to serve to the client. This is done in + * the same way as with a regular response, but conditions are now checked + * against the cached or merged response headers. + */ + if (rv == APR_SUCCESS && cache->stale_handle) { + apr_bucket_brigade *bb; + apr_bucket *bkt; + int status; + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + + /* Restore the original request headers and see if we need to + * return anything else than the cached response (ie. the original + * request was conditional). + */ + r->headers_in = cache->stale_headers; + status = ap_meets_conditions(r); + if (status != OK) { + r->status = status; + + bkt = apr_bucket_flush_create(bb->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bkt); + } + else { + cache->provider->recall_body(cache->handle, r->pool, bb); + } + + cache->block_response = 1; + return ap_pass_brigade(f->next, bb); + } + + if (rv == APR_SUCCESS) { + rv = cache->provider->store_body(cache->handle, r, in); + } + if (rv != APR_SUCCESS) { + ap_remove_output_filter(f); + } + + return ap_pass_brigade(f->next, in); +} + +/* -------------------------------------------------------------- */ +/* Setup configurable data */ + +static void * create_cache_config(apr_pool_t *p, server_rec *s) +{ + cache_server_conf *ps = apr_pcalloc(p, sizeof(cache_server_conf)); + + /* array of URL prefixes for which caching is enabled */ + ps->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable)); + /* array of URL prefixes for which caching is disabled */ + ps->cachedisable = apr_array_make(p, 10, sizeof(struct cache_disable)); + /* maximum time to cache a document */ + ps->maxex = DEFAULT_CACHE_MAXEXPIRE; + ps->maxex_set = 0; + /* default time to cache a document */ + ps->defex = DEFAULT_CACHE_EXPIRE; + ps->defex_set = 0; + /* factor used to estimate Expires date from LastModified date */ + ps->factor = DEFAULT_CACHE_LMFACTOR; + ps->factor_set = 0; + ps->no_last_mod_ignore_set = 0; + ps->no_last_mod_ignore = 0; + ps->ignorecachecontrol = 0; + ps->ignorecachecontrol_set = 0; + ps->store_private = 0; + ps->store_private_set = 0; + ps->store_nostore = 0; + ps->store_nostore_set = 0; + /* array of headers that should not be stored in cache */ + ps->ignore_headers = apr_array_make(p, 10, sizeof(char *)); + ps->ignore_headers_set = CACHE_IGNORE_HEADERS_UNSET; + return ps; +} + +static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv) +{ + cache_server_conf *ps = apr_pcalloc(p, sizeof(cache_server_conf)); + cache_server_conf *base = (cache_server_conf *) basev; + cache_server_conf *overrides = (cache_server_conf *) overridesv; + + /* array of URL prefixes for which caching is disabled */ + ps->cachedisable = apr_array_append(p, + base->cachedisable, + overrides->cachedisable); + /* array of URL prefixes for which caching is enabled */ + ps->cacheenable = apr_array_append(p, + base->cacheenable, + overrides->cacheenable); + /* maximum time to cache a document */ + ps->maxex = (overrides->maxex_set == 0) ? base->maxex : overrides->maxex; + /* default time to cache a document */ + ps->defex = (overrides->defex_set == 0) ? base->defex : overrides->defex; + /* factor used to estimate Expires date from LastModified date */ + ps->factor = + (overrides->factor_set == 0) ? base->factor : overrides->factor; + + ps->no_last_mod_ignore = + (overrides->no_last_mod_ignore_set == 0) + ? base->no_last_mod_ignore + : overrides->no_last_mod_ignore; + ps->ignorecachecontrol = + (overrides->ignorecachecontrol_set == 0) + ? base->ignorecachecontrol + : overrides->ignorecachecontrol; + ps->store_private = + (overrides->store_private_set == 0) + ? base->store_private + : overrides->store_private; + ps->store_nostore = + (overrides->store_nostore_set == 0) + ? base->store_nostore + : overrides->store_nostore; + ps->ignore_headers = + (overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET) + ? base->ignore_headers + : overrides->ignore_headers; + return ps; +} +static const char *set_cache_ignore_no_last_mod(cmd_parms *parms, void *dummy, + int flag) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->no_last_mod_ignore = flag; + conf->no_last_mod_ignore_set = 1; + return NULL; + +} + +static const char *set_cache_ignore_cachecontrol(cmd_parms *parms, + void *dummy, int flag) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->ignorecachecontrol = flag; + conf->ignorecachecontrol_set = 1; + return NULL; +} + +static const char *set_cache_store_private(cmd_parms *parms, void *dummy, + int flag) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->store_private = flag; + conf->store_private_set = 1; + return NULL; +} + +static const char *set_cache_store_nostore(cmd_parms *parms, void *dummy, + int flag) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->store_nostore = flag; + conf->store_nostore_set = 1; + return NULL; +} + +static const char *add_ignore_header(cmd_parms *parms, void *dummy, + const char *header) +{ + cache_server_conf *conf; + char **new; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + if (!strncasecmp(header, "None", 4)) { + /* if header None is listed clear array */ + conf->ignore_headers->nelts = 0; + } + else { + if ((conf->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET) || + (conf->ignore_headers->nelts)) { + /* Only add header if no "None" has been found in header list + * so far. + * (When 'None' is passed, IGNORE_HEADERS_SET && nelts == 0.) + */ + new = (char **)apr_array_push(conf->ignore_headers); + (*new) = (char *)header; + } + } + conf->ignore_headers_set = CACHE_IGNORE_HEADERS_SET; + return NULL; +} + +static const char *add_cache_enable(cmd_parms *parms, void *dummy, + const char *type, + const char *url) +{ + cache_server_conf *conf; + struct cache_enable *new; + + if (*type == '/') { + return apr_psprintf(parms->pool, + "provider (%s) starts with a '/'. Are url and provider switched?", + type); + } + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + new = apr_array_push(conf->cacheenable); + new->type = type; + new->url = url; + new->urllen = strlen(url); + return NULL; +} + +static const char *add_cache_disable(cmd_parms *parms, void *dummy, + const char *url) +{ + cache_server_conf *conf; + struct cache_disable *new; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + new = apr_array_push(conf->cachedisable); + new->url = url; + new->urllen = strlen(url); + return NULL; +} + +static const char *set_cache_maxex(cmd_parms *parms, void *dummy, + const char *arg) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->maxex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC); + conf->maxex_set = 1; + return NULL; +} + +static const char *set_cache_defex(cmd_parms *parms, void *dummy, + const char *arg) +{ + cache_server_conf *conf; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + conf->defex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC); + conf->defex_set = 1; + return NULL; +} + +static const char *set_cache_factor(cmd_parms *parms, void *dummy, + const char *arg) +{ + cache_server_conf *conf; + double val; + + conf = + (cache_server_conf *)ap_get_module_config(parms->server->module_config, + &cache_module); + if (sscanf(arg, "%lg", &val) != 1) { + return "CacheLastModifiedFactor value must be a float"; + } + conf->factor = val; + conf->factor_set = 1; + return NULL; +} + +static int cache_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* This is the means by which unusual (non-unix) os's may find alternate + * means to run a given command (e.g. shebang/registry parsing on Win32) + */ + cache_generate_key = APR_RETRIEVE_OPTIONAL_FN(ap_cache_generate_key); + if (!cache_generate_key) { + cache_generate_key = cache_generate_key_default; + } + return OK; +} + +static const command_rec cache_cmds[] = +{ + /* XXX + * Consider a new config directive that enables loading specific cache + * implememtations (like mod_cache_mem, mod_cache_file, etc.). + * Rather than using a LoadModule directive, admin would use something + * like CacheModule mem_cache_module | file_cache_module, etc, + * which would cause the approprpriate cache module to be loaded. + * This is more intuitive that requiring a LoadModule directive. + */ + + AP_INIT_TAKE2("CacheEnable", add_cache_enable, NULL, RSRC_CONF, + "A cache type and partial URL prefix below which " + "caching is enabled"), + AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF, + "A partial URL prefix below which caching is disabled"), + AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF, + "The maximum time in seconds to cache a document"), + AP_INIT_TAKE1("CacheDefaultExpire", set_cache_defex, NULL, RSRC_CONF, + "The default time in seconds to cache a document"), + AP_INIT_FLAG("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL, + RSRC_CONF, + "Ignore Responses where there is no Last Modified Header"), + AP_INIT_FLAG("CacheIgnoreCacheControl", set_cache_ignore_cachecontrol, + NULL, RSRC_CONF, + "Ignore requests from the client for uncached content"), + AP_INIT_FLAG("CacheStorePrivate", set_cache_store_private, + NULL, RSRC_CONF, + "Ignore 'Cache-Control: private' and store private content"), + AP_INIT_FLAG("CacheStoreNoStore", set_cache_store_nostore, + NULL, RSRC_CONF, + "Ignore 'Cache-Control: no-store' and store sensitive content"), + AP_INIT_ITERATE("CacheIgnoreHeaders", add_ignore_header, NULL, RSRC_CONF, + "A space separated list of headers that should not be " + "stored by the cache"), + AP_INIT_TAKE1("CacheLastModifiedFactor", set_cache_factor, NULL, RSRC_CONF, + "The factor used to estimate Expires date from " + "LastModified date"), + {NULL} +}; + +static void register_hooks(apr_pool_t *p) +{ + /* cache initializer */ + /* cache handler */ + ap_hook_quick_handler(cache_url_handler, NULL, NULL, APR_HOOK_FIRST); + /* cache filters + * XXX The cache filters need to run right after the handlers and before + * any other filters. Consider creating AP_FTYPE_CACHE for this purpose. + * Make them AP_FTYPE_CONTENT for now. + * XXX ianhH:they should run AFTER all the other content filters. + */ + cache_save_filter_handle = + ap_register_output_filter("CACHE_SAVE", + cache_save_filter, + NULL, + AP_FTYPE_CONTENT_SET-1); + /* CACHE_OUT must go into the filter chain before SUBREQ_CORE to + * handle subrequsts. Decrementing filter type by 1 ensures this + * happens. + */ + cache_out_filter_handle = + ap_register_output_filter("CACHE_OUT", + cache_out_filter, + NULL, + AP_FTYPE_CONTENT_SET-1); + ap_hook_post_config(cache_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +module AP_MODULE_DECLARE_DATA cache_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + create_cache_config, /* create per-server config structure */ + merge_cache_config, /* merge per-server config structures */ + cache_cmds, /* command apr_table_t */ + register_hooks +}; diff --git a/trunk/modules/cache/mod_cache.dsp b/trunk/modules/cache/mod_cache.dsp new file mode 100644 index 0000000000..1adddf2708 --- /dev/null +++ b/trunk/modules/cache/mod_cache.dsp @@ -0,0 +1,168 @@ +# Microsoft Developer Studio Project File - Name="mod_cache" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_cache - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_cache.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_cache.mak" CFG="mod_cache - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_cache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_cache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_cache - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "MOD_CACHE_EXPORTS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "CACHE_DECLARE_EXPORT" /D "MOD_CACHE_EXPORTS" /Fd"Release\mod_cache_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_cache - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "CACHE_DECLARE_EXPORT" /Fd"Debug\mod_cache_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cache.so + +!ENDIF + +# Begin Target + +# Name "mod_cache - Win32 Release" +# Name "mod_cache - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\cache_cache.c +# End Source File +# Begin Source File + +SOURCE=.\cache_hash.c +# End Source File +# Begin Source File + +SOURCE=.\cache_pqueue.c +# End Source File +# Begin Source File + +SOURCE=.\cache_storage.c +# End Source File +# Begin Source File + +SOURCE=.\cache_util.c +# End Source File +# Begin Source File + +SOURCE=.\mod_cache.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\cache_cache.h +# End Source File +# Begin Source File + +SOURCE=.\cache_hash.h +# End Source File +# Begin Source File + +SOURCE=.\cache_pqueue.h +# End Source File +# Begin Source File + +SOURCE=.\mod_cache.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_cache - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cache.so "cache_module for Apache" ../../include/ap_release.h > .\mod_cache.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_cache - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cache.so "cache_module for Apache" ../../include/ap_release.h > .\mod_cache.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/cache/mod_cache.h b/trunk/modules/cache/mod_cache.h new file mode 100644 index 0000000000..26675e7805 --- /dev/null +++ b/trunk/modules/cache/mod_cache.h @@ -0,0 +1,320 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_CACHE_H +#define MOD_CACHE_H + +/* + * Main include file for the Apache Transparent Cache + */ + +#define CORE_PRIVATE + +#include "apr_hooks.h" +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_md5.h" +#include "apr_pools.h" +#include "apr_strings.h" +#include "apr_optional.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "ap_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_main.h" +#include "http_log.h" +#include "http_connection.h" +#include "util_filter.h" +#include "apr_date.h" +#include "apr_uri.h" + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "apr_atomic.h" + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define MSEC_ONE_DAY ((apr_time_t)(86400*APR_USEC_PER_SEC)) /* one day, in microseconds */ +#define MSEC_ONE_HR ((apr_time_t)(3600*APR_USEC_PER_SEC)) /* one hour, in microseconds */ +#define MSEC_ONE_MIN ((apr_time_t)(60*APR_USEC_PER_SEC)) /* one minute, in microseconds */ +#define MSEC_ONE_SEC ((apr_time_t)(APR_USEC_PER_SEC)) /* one second, in microseconds */ +#define DEFAULT_CACHE_MAXEXPIRE MSEC_ONE_DAY +#define DEFAULT_CACHE_EXPIRE MSEC_ONE_HR +#define DEFAULT_CACHE_LMFACTOR (0.1) + +/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and + * PROXY_DECLARE_DATA with appropriate export and import tags for the platform + */ +#if !defined(WIN32) +#define CACHE_DECLARE(type) type +#define CACHE_DECLARE_NONSTD(type) type +#define CACHE_DECLARE_DATA +#elif defined(CACHE_DECLARE_STATIC) +#define CACHE_DECLARE(type) type __stdcall +#define CACHE_DECLARE_NONSTD(type) type +#define CACHE_DECLARE_DATA +#elif defined(CACHE_DECLARE_EXPORT) +#define CACHE_DECLARE(type) __declspec(dllexport) type __stdcall +#define CACHE_DECLARE_NONSTD(type) __declspec(dllexport) type +#define CACHE_DECLARE_DATA __declspec(dllexport) +#else +#define CACHE_DECLARE(type) __declspec(dllimport) type __stdcall +#define CACHE_DECLARE_NONSTD(type) __declspec(dllimport) type +#define CACHE_DECLARE_DATA __declspec(dllimport) +#endif + +struct cache_enable { + const char *url; + const char *type; + apr_size_t urllen; +}; + +struct cache_disable { + const char *url; + apr_size_t urllen; +}; + +/* static information about the local cache */ +typedef struct { + apr_array_header_t *cacheenable; /* URLs to cache */ + apr_array_header_t *cachedisable; /* URLs not to cache */ + /* Maximum time to keep cached files in msecs */ + apr_time_t maxex; + int maxex_set; + /* default time to keep cached file in msecs */ + apr_time_t defex; + int defex_set; + /* factor for estimating expires date */ + double factor; + int factor_set; + /** ignore the last-modified header when deciding to cache this request */ + int no_last_mod_ignore_set; + int no_last_mod_ignore; + /** ignore client's requests for uncached responses */ + int ignorecachecontrol; + int ignorecachecontrol_set; + /** ignore Cache-Control: private header from server */ + int store_private; + int store_private_set; + /** ignore Cache-Control: no-store header from client or server */ + int store_nostore; + int store_nostore_set; + /** store the headers that should not be stored in the cache */ + apr_array_header_t *ignore_headers; + /* flag if CacheIgnoreHeader has been set */ + #define CACHE_IGNORE_HEADERS_SET 1 + #define CACHE_IGNORE_HEADERS_UNSET 0 + int ignore_headers_set; +} cache_server_conf; + +/* cache info information */ +typedef struct cache_info cache_info; +struct cache_info { + int status; + apr_time_t date; + apr_time_t expire; + apr_time_t request_time; + apr_time_t response_time; +}; + +/* cache handle information */ + +/* XXX TODO On the next structure change/MMN bump, + * count must become an apr_off_t, representing + * the potential size of disk cached objects. + * Then dig for + * "XXX Bad Temporary Cast - see cache_object_t notes" + */ +typedef struct cache_object cache_object_t; +struct cache_object { + char *key; + cache_object_t *next; + cache_info info; + /* Opaque portion (specific to the implementation) of the cache object */ + void *vobj; + /* FIXME: These are only required for mod_mem_cache. */ + apr_size_t count; /* Number of body bytes written to the cache so far */ + int complete; + apr_uint32_t refcount; /* refcount and bit flag to cleanup object */ +}; + +typedef struct cache_handle cache_handle_t; +struct cache_handle { + cache_object_t *cache_obj; + apr_table_t *req_hdrs; /* cached request headers */ + apr_table_t *resp_hdrs; /* cached response headers */ +}; + +#define CACHE_PROVIDER_GROUP "cache" + +typedef struct { + int (*remove_entity) (cache_handle_t *h); + apr_status_t (*store_headers)(cache_handle_t *h, request_rec *r, cache_info *i); + apr_status_t (*store_body)(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b); + apr_status_t (*recall_headers) (cache_handle_t *h, request_rec *r); + apr_status_t (*recall_body) (cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb); + int (*create_entity) (cache_handle_t *h, request_rec *r, + const char *urlkey, apr_off_t len); + int (*open_entity) (cache_handle_t *h, request_rec *r, + const char *urlkey); + int (*remove_url) (const char *urlkey); +} cache_provider; + +/* A linked-list of authn providers. */ +typedef struct cache_provider_list cache_provider_list; + +struct cache_provider_list { + const char *provider_name; + const cache_provider *provider; + cache_provider_list *next; +}; + +/* per request cache information */ +typedef struct { + cache_provider_list *providers; /* possible cache providers */ + const cache_provider *provider; /* current cache provider */ + const char *provider_name; /* current cache provider name */ + int fresh; /* is the entitey fresh? */ + cache_handle_t *handle; /* current cache handle */ + cache_handle_t *stale_handle; /* stale cache handle */ + apr_table_t *stale_headers; /* original request headers. */ + int in_checked; /* CACHE_SAVE must cache the entity */ + int block_response; /* CACHE_SAVE must block response. */ + apr_bucket_brigade *saved_brigade; /* copy of partial response */ + apr_off_t saved_size; /* length of saved_brigade */ + apr_time_t exp; /* expiration */ + apr_time_t lastmod; /* last-modified time */ + cache_info *info; /* current cache info */ +} cache_request_rec; + + +/* cache_util.c */ +/* do a HTTP/1.1 age calculation */ +CACHE_DECLARE(apr_time_t) ap_cache_current_age(cache_info *info, const apr_time_t age_value, + apr_time_t now); + +/** + * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model) + * @param h cache_handle_t + * @param r request_rec + * @return 0 ==> cache object is stale, 1 ==> cache object is fresh + */ +CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h, request_rec *r); + +/** + * Merge in cached headers into the response + * @param h cache_handle_t + * @param r request_rec + * @param preserve_orig If 1, the values in r->headers_out are preserved. + * Otherwise, they are overwritten by the cached value. + */ +CACHE_DECLARE(void) ap_cache_accept_headers(cache_handle_t *h, request_rec *r, + int preserve_orig); + +CACHE_DECLARE(apr_time_t) ap_cache_hex2usec(const char *x); +CACHE_DECLARE(void) ap_cache_usec2hex(apr_time_t j, char *y); +CACHE_DECLARE(char *) ap_cache_generate_name(apr_pool_t *p, int dirlevels, + int dirlength, + const char *name); +CACHE_DECLARE(cache_provider_list *)ap_cache_get_providers(request_rec *r, cache_server_conf *conf, const char *url); +CACHE_DECLARE(int) ap_cache_liststr(apr_pool_t *p, const char *list, + const char *key, char **val); +CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str); + +/* Create a new table consisting of those elements from a request_rec's + * headers_out that are allowed to be stored in a cache + */ +CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_hdrs_out(apr_pool_t *pool, + apr_table_t *t, + server_rec *s); + +/** + * cache_storage.c + */ +int cache_remove_url(request_rec *r, char *url); +int cache_create_entity(request_rec *r, char *url, apr_off_t size); +int cache_select_url(request_rec *r, char *url); +apr_status_t cache_generate_key_default( request_rec *r, apr_pool_t*p, char**key ); +/** + * create a key for the cache based on the request record + * this is the 'default' version, which can be overridden by a default function + */ +const char* cache_create_key( request_rec*r ); + +/* +apr_status_t cache_store_entity_headers(cache_handle_t *h, request_rec *r, cache_info *info); +apr_status_t cache_store_entity_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *bb); + +apr_status_t cache_recall_entity_headers(cache_handle_t *h, request_rec *r); +apr_status_t cache_recall_entity_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb); +*/ + +/* hooks */ + +/* Create a set of CACHE_DECLARE(type), CACHE_DECLARE_NONSTD(type) and + * CACHE_DECLARE_DATA with appropriate export and import tags for the platform + */ +#if !defined(WIN32) +#define CACHE_DECLARE(type) type +#define CACHE_DECLARE_NONSTD(type) type +#define CACHE_DECLARE_DATA +#elif defined(CACHE_DECLARE_STATIC) +#define CACHE_DECLARE(type) type __stdcall +#define CACHE_DECLARE_NONSTD(type) type +#define CACHE_DECLARE_DATA +#elif defined(CACHE_DECLARE_EXPORT) +#define CACHE_DECLARE(type) __declspec(dllexport) type __stdcall +#define CACHE_DECLARE_NONSTD(type) __declspec(dllexport) type +#define CACHE_DECLARE_DATA __declspec(dllexport) +#else +#define CACHE_DECLARE(type) __declspec(dllimport) type __stdcall +#define CACHE_DECLARE_NONSTD(type) __declspec(dllimport) type +#define CACHE_DECLARE_DATA __declspec(dllimport) +#endif + +APR_DECLARE_OPTIONAL_FN(apr_status_t, + ap_cache_generate_key, + (request_rec *r, apr_pool_t*p, char**key )); + + +#endif /*MOD_CACHE_H*/ diff --git a/trunk/modules/cache/mod_cache.imp b/trunk/modules/cache/mod_cache.imp new file mode 100644 index 0000000000..593bc354a0 --- /dev/null +++ b/trunk/modules/cache/mod_cache.imp @@ -0,0 +1,9 @@ + (MODCACHE) + ap_cache_get_providers, + ap_cache_liststr, + ap_cache_tokstr, + ap_cache_hex2usec, + ap_cache_usec2hex, + ap_cache_cacheable_hdrs_out, + generate_name + diff --git a/trunk/modules/cache/mod_disk_cache.c b/trunk/modules/cache/mod_disk_cache.c new file mode 100644 index 0000000000..b7365c4742 --- /dev/null +++ b/trunk/modules/cache/mod_disk_cache.c @@ -0,0 +1,822 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_file_io.h" +#include "apr_strings.h" +#include "mod_cache.h" +#include "ap_provider.h" +#include "util_filter.h" +#include "util_script.h" +#include "util_charset.h" + +#if APR_HAVE_UNISTD_H +#include /* needed for unlink/link */ +#endif + +/* Our on-disk header format is: + * + * disk_cache_info_t + * entity name (dobj->name) [length is in disk_cache_info_t->name_len] + * r->headers_out (delimited by CRLF) + * CRLF + * r->headers_in (delimited by CRLF) + * CRLF + */ +#define DISK_FORMAT_VERSION 0 +typedef struct { + /* Indicates the format of the header struct stored on-disk. */ + int format; + /* The HTTP status code returned for this response. */ + int status; + /* The size of the entity name that follows. */ + apr_size_t name_len; + /* The number of times we've cached this entity. */ + apr_size_t entity_version; + /* Miscellaneous time values. */ + apr_time_t date; + apr_time_t expire; + apr_time_t request_time; + apr_time_t response_time; +} disk_cache_info_t; + +/* + * disk_cache_object_t + * Pointed to by cache_object_t::vobj + */ +typedef struct disk_cache_object { + const char *root; /* the location of the cache directory */ + char *tempfile; /* temp file tohold the content */ +#if 0 + int dirlevels; /* Number of levels of subdirectories */ + int dirlength; /* Length of subdirectory names */ +#endif + char *datafile; /* name of file where the data will go */ + char *hdrsfile; /* name of file where the hdrs will go */ + char *hashfile; /* Computed hash key for this URI */ + char *name; + apr_file_t *fd; /* data file */ + apr_file_t *hfd; /* headers file */ + apr_file_t *tfd; /* temporary file for data */ + apr_off_t file_size; /* File size of the cached data file */ + disk_cache_info_t disk_info; /* Header information. */ +} disk_cache_object_t; + + +/* + * mod_disk_cache configuration + */ +/* TODO: Make defaults OS specific */ +#define CACHEFILE_LEN 20 /* must be less than HASH_LEN/2 */ +#define DEFAULT_DIRLEVELS 3 +#define DEFAULT_DIRLENGTH 2 +#define DEFAULT_MIN_FILE_SIZE 1 +#define DEFAULT_MAX_FILE_SIZE 1000000 + +typedef struct { + const char* cache_root; + apr_size_t cache_root_len; + int dirlevels; /* Number of levels of subdirectories */ + int dirlength; /* Length of subdirectory names */ + apr_size_t minfs; /* minumum file size for cached files */ + apr_size_t maxfs; /* maximum file size for cached files */ +} disk_cache_conf; + +module AP_MODULE_DECLARE_DATA disk_cache_module; + +/* Forward declarations */ +static int remove_entity(cache_handle_t *h); +static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *i); +static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b); +static apr_status_t recall_headers(cache_handle_t *h, request_rec *r); +static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb); + +/* + * Local static functions + */ +#define CACHE_HEADER_SUFFIX ".header" +#define CACHE_DATA_SUFFIX ".data" +static char *header_file(apr_pool_t *p, disk_cache_conf *conf, + disk_cache_object_t *dobj, const char *name) +{ + if (!dobj->hashfile) { + dobj->hashfile = ap_cache_generate_name(p, conf->dirlevels, + conf->dirlength, name); + } + return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, + CACHE_HEADER_SUFFIX, NULL); +} + +static char *data_file(apr_pool_t *p, disk_cache_conf *conf, + disk_cache_object_t *dobj, const char *name) +{ + if (!dobj->hashfile) { + dobj->hashfile = ap_cache_generate_name(p, conf->dirlevels, + conf->dirlength, name); + } + return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, + CACHE_DATA_SUFFIX, NULL); +} + +static void mkdir_structure(disk_cache_conf *conf, char *file, apr_pool_t *pool) +{ + apr_status_t rv; + char *p; + + for (p = file + conf->cache_root_len + 1;;) { + p = strchr(p, '/'); + if (!p) + break; + *p = '\0'; + + rv = apr_dir_make(file, + APR_UREAD|APR_UWRITE|APR_UEXECUTE, pool); + if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) { + /* XXX */ + } + *p = '/'; + ++p; + } +} + +static apr_status_t file_cache_el_final(disk_cache_object_t *dobj, + request_rec *r) +{ + /* move the data over */ + if (dobj->tfd) { + apr_status_t rv; + + apr_file_close(dobj->tfd); + + /* This assumes that the tempfile is on the same file system + * as the cache_root. If not, then we need a file copy/move + * rather than a rename. + */ + rv = apr_file_rename(dobj->tempfile, dobj->datafile, r->pool); + if (rv != APR_SUCCESS) { + /* XXX log */ + } + + dobj->tfd = NULL; + } + + return APR_SUCCESS; +} + +static apr_status_t file_cache_errorcleanup(disk_cache_object_t *dobj, request_rec *r) +{ + /* Remove the header file and the body file. */ + apr_file_remove(dobj->hdrsfile, r->pool); + apr_file_remove(dobj->datafile, r->pool); + + /* If we opened the temporary data file, close and remove it. */ + if (dobj->tfd) { + apr_file_close(dobj->tfd); + apr_file_remove(dobj->tempfile, r->pool); + dobj->tfd = NULL; + } + + return APR_SUCCESS; +} + + +/* These two functions get and put state information into the data + * file for an ap_cache_el, this state information will be read + * and written transparent to clients of this module + */ +static int file_cache_recall_mydata(apr_file_t *fd, cache_info *info, + disk_cache_object_t *dobj, request_rec *r) +{ + apr_status_t rv; + char *urlbuff; + disk_cache_info_t disk_info; + apr_size_t len; + + /* read the data from the cache file */ + len = sizeof(disk_cache_info_t); + rv = apr_file_read_full(fd, &disk_info, len, &len); + if (rv != APR_SUCCESS) { + return rv; + } + + if (disk_info.format != DISK_FORMAT_VERSION) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "cache_disk: URL %s had a on-disk version mismatch", + r->uri); + return APR_EGENERAL; + } + + /* Store it away so we can get it later. */ + dobj->disk_info = disk_info; + + info->status = disk_info.status; + info->date = disk_info.date; + info->expire = disk_info.expire; + info->request_time = disk_info.request_time; + info->response_time = disk_info.response_time; + + /* Note that we could optimize this by conditionally doing the palloc + * depending upon the size. */ + urlbuff = apr_palloc(r->pool, disk_info.name_len + 1); + len = disk_info.name_len; + rv = apr_file_read_full(fd, urlbuff, len, &len); + if (rv != APR_SUCCESS) { + return rv; + } + urlbuff[disk_info.name_len] = '\0'; + + /* check that we have the same URL */ + /* Would strncmp be correct? */ + if (strcmp(urlbuff, dobj->name) != 0) { + return APR_EGENERAL; + } + + return APR_SUCCESS; +} + +/* + * Hook and mod_cache callback functions + */ +#define AP_TEMPFILE "/aptmpXXXXXX" +static int create_entity(cache_handle_t *h, request_rec *r, const char *key, apr_off_t len) +{ + disk_cache_conf *conf = ap_get_module_config(r->server->module_config, + &disk_cache_module); + cache_object_t *obj; + disk_cache_object_t *dobj; + + if (conf->cache_root == NULL) { + return DECLINED; + } + + /* Allocate and initialize cache_object_t and disk_cache_object_t */ + h->cache_obj = obj = apr_pcalloc(r->pool, sizeof(*obj)); + obj->vobj = dobj = apr_pcalloc(r->pool, sizeof(*dobj)); + + obj->key = apr_pstrdup(r->pool, key); + + dobj->name = obj->key; + dobj->datafile = data_file(r->pool, conf, dobj, key); + dobj->hdrsfile = header_file(r->pool, conf, dobj, key); + dobj->tempfile = apr_pstrcat(r->pool, conf->cache_root, AP_TEMPFILE, NULL); + + return OK; +} + +static int open_entity(cache_handle_t *h, request_rec *r, const char *key) +{ + apr_status_t rc; + static int error_logged = 0; + disk_cache_conf *conf = ap_get_module_config(r->server->module_config, + &disk_cache_module); + apr_finfo_t finfo; + cache_object_t *obj; + cache_info *info; + disk_cache_object_t *dobj; + int flags; + + h->cache_obj = NULL; + + /* Look up entity keyed to 'url' */ + if (conf->cache_root == NULL) { + if (!error_logged) { + error_logged = 1; + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "disk_cache: Cannot cache files to disk without a CacheRoot specified."); + } + return DECLINED; + } + + /* Create and init the cache object */ + h->cache_obj = obj = apr_pcalloc(r->pool, sizeof(cache_object_t)); + obj->vobj = dobj = apr_pcalloc(r->pool, sizeof(disk_cache_object_t)); + + info = &(obj->info); + obj->key = (char *) key; + dobj->name = (char *) key; + dobj->datafile = data_file(r->pool, conf, dobj, key); + dobj->hdrsfile = header_file(r->pool, conf, dobj, key); + dobj->tempfile = apr_pstrcat(r->pool, conf->cache_root, AP_TEMPFILE, NULL); + + /* Open the data file */ + flags = APR_READ|APR_BINARY; +#ifdef APR_SENDFILE_ENABLED + flags |= APR_SENDFILE_ENABLED; +#endif + rc = apr_file_open(&dobj->fd, dobj->datafile, flags, 0, r->pool); + if (rc != APR_SUCCESS) { + /* XXX: Log message */ + return DECLINED; + } + + /* Open the headers file */ + flags = APR_READ|APR_BINARY|APR_BUFFERED; + rc = apr_file_open(&dobj->hfd, dobj->hdrsfile, flags, 0, r->pool); + if (rc != APR_SUCCESS) { + /* XXX: Log message */ + return DECLINED; + } + + rc = apr_file_info_get(&finfo, APR_FINFO_SIZE, dobj->fd); + if (rc == APR_SUCCESS) { + dobj->file_size = finfo.size; + } + + /* Read the bytes to setup the cache_info fields */ + rc = file_cache_recall_mydata(dobj->hfd, info, dobj, r); + if (rc != APR_SUCCESS) { + /* XXX log message */ + return DECLINED; + } + + /* Initialize the cache_handle callback functions */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "disk_cache: Recalled cached URL info header %s", dobj->name); + return OK; +} + +static int remove_entity(cache_handle_t *h) +{ + /* Null out the cache object pointer so next time we start from scratch */ + h->cache_obj = NULL; + return OK; +} + +static int remove_url(const char *key) +{ + /* XXX: Delete file from cache! */ + return OK; +} + +static apr_status_t read_table(cache_handle_t *handle, request_rec *r, + apr_table_t *table, apr_file_t *file) +{ + char w[MAX_STRING_LEN]; + char *l; + int p; + apr_status_t rv; + + while (1) { + + /* ### What about APR_EOF? */ + rv = apr_file_gets(w, MAX_STRING_LEN - 1, file); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Premature end of cache headers."); + return rv; + } + + /* Delete terminal (CR?)LF */ + + p = strlen(w); + /* Indeed, the host's '\n': + '\012' for UNIX; '\015' for MacOS; '\025' for OS/390 + -- whatever the script generates. + */ + if (p > 0 && w[p - 1] == '\n') { + if (p > 1 && w[p - 2] == CR) { + w[p - 2] = '\0'; + } + else { + w[p - 1] = '\0'; + } + } + + /* If we've finished reading the headers, break out of the loop. */ + if (w[0] == '\0') { + break; + } + +#if APR_CHARSET_EBCDIC + /* Chances are that we received an ASCII header text instead of + * the expected EBCDIC header lines. Try to auto-detect: + */ + if (!(l = strchr(w, ':'))) { + int maybeASCII = 0, maybeEBCDIC = 0; + unsigned char *cp, native; + apr_size_t inbytes_left, outbytes_left; + + for (cp = w; *cp != '\0'; ++cp) { + native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp); + if (apr_isprint(*cp) && !apr_isprint(native)) + ++maybeEBCDIC; + if (!apr_isprint(*cp) && apr_isprint(native)) + ++maybeASCII; + } + if (maybeASCII > maybeEBCDIC) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)", + r->filename); + inbytes_left = outbytes_left = cp - w; + apr_xlate_conv_buffer(ap_hdrs_from_ascii, + w, &inbytes_left, w, &outbytes_left); + } + } +#endif /*APR_CHARSET_EBCDIC*/ + + /* if we see a bogus header don't ignore it. Shout and scream */ + if (!(l = strchr(w, ':'))) { + return APR_EGENERAL; + } + + *l++ = '\0'; + while (*l && apr_isspace(*l)) { + ++l; + } + + apr_table_add(table, w, l); + } + + return APR_SUCCESS; +} + +/* + * Reads headers from a buffer and returns an array of headers. + * Returns NULL on file error + * This routine tries to deal with too long lines and continuation lines. + * @@@: XXX: FIXME: currently the headers are passed thru un-merged. + * Is that okay, or should they be collapsed where possible? + */ +static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) +{ + disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj; + + /* This case should not happen... */ + if (!dobj->hfd) { + /* XXX log message */ + return APR_NOTFOUND; + } + + h->req_hdrs = apr_table_make(r->pool, 20); + h->resp_hdrs = apr_table_make(r->pool, 20); + + /* Call routine to read the header lines/status line */ + read_table(h, r, h->resp_hdrs, dobj->hfd); + read_table(h, r, h->req_hdrs, dobj->hfd); + + apr_file_close(dobj->hfd); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "disk_cache: Recalled headers for URL %s", dobj->name); + return APR_SUCCESS; +} + +static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb) +{ + apr_bucket *e; + disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj; + + e = apr_bucket_file_create(dobj->fd, 0, (apr_size_t) dobj->file_size, p, + bb->bucket_alloc); + APR_BRIGADE_INSERT_HEAD(bb, e); + e = apr_bucket_eos_create(bb->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + + return APR_SUCCESS; +} + +static apr_status_t store_table(apr_file_t *fd, apr_table_t *table) +{ + int i; + apr_status_t rv; + struct iovec iov[4]; + apr_size_t amt; + apr_table_entry_t *elts; + + elts = (apr_table_entry_t *) apr_table_elts(table)->elts; + for (i = 0; i < apr_table_elts(table)->nelts; ++i) { + if (elts[i].key != NULL) { + iov[0].iov_base = elts[i].key; + iov[0].iov_len = strlen(elts[i].key); + iov[1].iov_base = ": "; + iov[1].iov_len = sizeof(": ") - 1; + iov[2].iov_base = elts[i].val; + iov[2].iov_len = strlen(elts[i].val); + iov[3].iov_base = CRLF; + iov[3].iov_len = sizeof(CRLF) - 1; + + rv = apr_file_writev(fd, (const struct iovec *) &iov, 4, + &amt); + if (rv != APR_SUCCESS) { + return rv; + } + } + } + iov[0].iov_base = CRLF; + iov[0].iov_len = sizeof(CRLF) - 1; + rv = apr_file_writev(fd, (const struct iovec *) &iov, 1, + &amt); + return rv; +} + +static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *info) +{ + disk_cache_conf *conf = ap_get_module_config(r->server->module_config, + &disk_cache_module); + apr_status_t rv; + apr_size_t amt; + disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj; + + disk_cache_info_t disk_info; + struct iovec iov[2]; + + /* This is flaky... we need to manage the cache_info differently */ + h->cache_obj->info = *info; + + /* Remove old file with the same name. If remove fails, then + * perhaps we need to create the directory tree where we are + * about to write the new headers file. + */ + rv = apr_file_remove(dobj->hdrsfile, r->pool); + if (rv != APR_SUCCESS) { + mkdir_structure(conf, dobj->hdrsfile, r->pool); + } + + rv = apr_file_open(&dobj->hfd, dobj->hdrsfile, + APR_WRITE | APR_CREATE | APR_EXCL, + APR_OS_DEFAULT, r->pool); + if (rv != APR_SUCCESS) { + return rv; + } + dobj->name = h->cache_obj->key; + + disk_info.format = DISK_FORMAT_VERSION; + disk_info.date = info->date; + disk_info.expire = info->expire; + disk_info.entity_version = dobj->disk_info.entity_version++; + disk_info.request_time = info->request_time; + disk_info.response_time = info->response_time; + disk_info.status = info->status; + + disk_info.name_len = strlen(dobj->name); + + iov[0].iov_base = (void*)&disk_info; + iov[0].iov_len = sizeof(disk_cache_info_t); + iov[1].iov_base = dobj->name; + iov[1].iov_len = disk_info.name_len; + + rv = apr_file_writev(dobj->hfd, (const struct iovec *) &iov, 2, &amt); + if (rv != APR_SUCCESS) { + return rv; + } + + if (r->headers_out) { + apr_table_t *headers_out; + + headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out, + r->server); + + if (!apr_table_get(headers_out, "Content-Type") + && r->content_type) { + apr_table_setn(headers_out, "Content-Type", + ap_make_content_type(r, r->content_type)); + } + + headers_out = apr_table_overlay(r->pool, headers_out, + r->err_headers_out); + rv = store_table(dobj->hfd, headers_out); + if (rv != APR_SUCCESS) { + return rv; + } + } + + /* Parse the vary header and dump those fields from the headers_in. */ + /* FIXME: Make call to the same thing cache_select_url calls to crack Vary. */ + if (r->headers_in) { + apr_table_t *headers_in; + + headers_in = ap_cache_cacheable_hdrs_out(r->pool, r->headers_in, + r->server); + rv = store_table(dobj->hfd, headers_in); + if (rv != APR_SUCCESS) { + return rv; + } + } + + apr_file_close(dobj->hfd); /* flush and close */ + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "disk_cache: Stored headers for URL %s", dobj->name); + return APR_SUCCESS; +} + +static apr_status_t store_body(cache_handle_t *h, request_rec *r, + apr_bucket_brigade *bb) +{ + apr_bucket *e; + apr_status_t rv; + disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj; + disk_cache_conf *conf = ap_get_module_config(r->server->module_config, + &disk_cache_module); + + /* We write to a temp file and then atomically rename the file over + * in file_cache_el_final(). + */ + if (!dobj->tfd) { + rv = apr_file_mktemp(&dobj->tfd, dobj->tempfile, + APR_CREATE | APR_WRITE | APR_BINARY | + APR_BUFFERED | APR_EXCL, r->pool); + if (rv != APR_SUCCESS) { + return rv; + } + dobj->file_size = 0; + } + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + const char *str; + apr_size_t length, written; + apr_bucket_read(e, &str, &length, APR_BLOCK_READ); + rv = apr_file_write_full(dobj->tfd, str, length, &written); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "cache_disk: Error when writing cache file for URL %s", + h->cache_obj->key); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + file_cache_errorcleanup(dobj, r); + return APR_EGENERAL; + } + dobj->file_size += written; + if (dobj->file_size > conf->maxfs) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "cache_disk: URL %s failed the size check " + "(%" APR_OFF_T_FMT ">%" APR_SIZE_T_FMT ")", + h->cache_obj->key, dobj->file_size, conf->maxfs); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + file_cache_errorcleanup(dobj, r); + return APR_EGENERAL; + } + } + + /* Was this the final bucket? If yes, close the temp file and perform + * sanity checks. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + if (r->connection->aborted) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "disk_cache: Discarding body for URL %s " + "because connection has been aborted.", + h->cache_obj->key); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + file_cache_errorcleanup(dobj, r); + return APR_EGENERAL; + } + if (dobj->file_size < conf->minfs) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "cache_disk: URL %s failed the size check " + "(%" APR_OFF_T_FMT "<%" APR_SIZE_T_FMT ")", + h->cache_obj->key, dobj->file_size, conf->minfs); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + file_cache_errorcleanup(dobj, r); + return APR_EGENERAL; + } + + /* All checks were fine. Move tempfile to final destination */ + /* Link to the perm file, and close the descriptor */ + file_cache_el_final(dobj, r); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "disk_cache: Body for URL %s cached.", dobj->name); + } + + return APR_SUCCESS; +} + +static void *create_config(apr_pool_t *p, server_rec *s) +{ + disk_cache_conf *conf = apr_pcalloc(p, sizeof(disk_cache_conf)); + + /* XXX: Set default values */ + conf->dirlevels = DEFAULT_DIRLEVELS; + conf->dirlength = DEFAULT_DIRLENGTH; + conf->maxfs = DEFAULT_MAX_FILE_SIZE; + conf->minfs = DEFAULT_MIN_FILE_SIZE; + + conf->cache_root = NULL; + conf->cache_root_len = 0; + + return conf; +} + +/* + * mod_disk_cache configuration directives handlers. + */ +static const char +*set_cache_root(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, + &disk_cache_module); + conf->cache_root = arg; + conf->cache_root_len = strlen(arg); + /* TODO: canonicalize cache_root and strip off any trailing slashes */ + + return NULL; +} + +/* + * Consider eliminating the next two directives in favor of + * Ian's prime number hash... + * key = hash_fn( r->uri) + * filename = "/key % prime1 /key %prime2/key %prime3" + */ +static const char +*set_cache_dirlevels(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, + &disk_cache_module); + int val = atoi(arg); + if (val < 1) + return "CacheDirLevels value must be an integer greater than 0"; + if (val * conf->dirlength > CACHEFILE_LEN) + return "CacheDirLevels*CacheDirLength value must not be higher than 20"; + conf->dirlevels = val; + return NULL; +} +static const char +*set_cache_dirlength(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, + &disk_cache_module); + int val = atoi(arg); + if (val < 1) + return "CacheDirLength value must be an integer greater than 0"; + if (val * conf->dirlevels > CACHEFILE_LEN) + return "CacheDirLevels*CacheDirLength value must not be higher than 20"; + + conf->dirlength = val; + return NULL; +} + +static const char +*set_cache_minfs(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, + &disk_cache_module); + conf->minfs = atoi(arg); + return NULL; +} +static const char +*set_cache_maxfs(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + disk_cache_conf *conf = ap_get_module_config(parms->server->module_config, + &disk_cache_module); + conf->maxfs = atoi(arg); + return NULL; +} + +static const command_rec disk_cache_cmds[] = +{ + AP_INIT_TAKE1("CacheRoot", set_cache_root, NULL, RSRC_CONF, + "The directory to store cache files"), + AP_INIT_TAKE1("CacheDirLevels", set_cache_dirlevels, NULL, RSRC_CONF, + "The number of levels of subdirectories in the cache"), + AP_INIT_TAKE1("CacheDirLength", set_cache_dirlength, NULL, RSRC_CONF, + "The number of characters in subdirectory names"), + AP_INIT_TAKE1("CacheMinFileSize", set_cache_minfs, NULL, RSRC_CONF, + "The minimum file size to cache a document"), + AP_INIT_TAKE1("CacheMaxFileSize", set_cache_maxfs, NULL, RSRC_CONF, + "The maximum file size to cache a document"), + {NULL} +}; + +static const cache_provider cache_disk_provider = +{ + &remove_entity, + &store_headers, + &store_body, + &recall_headers, + &recall_body, + &create_entity, + &open_entity, + &remove_url, +}; + +static void disk_cache_register_hook(apr_pool_t *p) +{ + /* cache initializer */ + ap_register_provider(p, CACHE_PROVIDER_GROUP, "disk", "0", + &cache_disk_provider); +} + +module AP_MODULE_DECLARE_DATA disk_cache_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + create_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + disk_cache_cmds, /* command apr_table_t */ + disk_cache_register_hook /* register hooks */ +}; diff --git a/trunk/modules/cache/mod_disk_cache.dsp b/trunk/modules/cache/mod_disk_cache.dsp new file mode 100644 index 0000000000..688dd94ace --- /dev/null +++ b/trunk/modules/cache/mod_disk_cache.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_disk_cache" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_disk_cache - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_disk_cache.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_disk_cache.mak" CFG="mod_disk_cache - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_disk_cache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_disk_cache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_disk_cache - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fd"Release\mod_disk_cache_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_disk_cache - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fd"Debug\mod_disk_cache_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_disk_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_disk_cache.so + +!ENDIF + +# Begin Target + +# Name "mod_disk_cache - Win32 Release" +# Name "mod_disk_cache - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_cache.h +# End Source File +# Begin Source File + +SOURCE=.\mod_disk_cache.c +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_disk_cache - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_disk_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_disk_cache.so "disk_cache_module for Apache" ../../include/ap_release.h > .\mod_disk_cache.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_disk_cache - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_disk_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_disk_cache.so "disk_cache_module for Apache" ../../include/ap_release.h > .\mod_disk_cache.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/cache/mod_file_cache.c b/trunk/modules/cache/mod_file_cache.c new file mode 100644 index 0000000000..a23eb6ecde --- /dev/null +++ b/trunk/modules/cache/mod_file_cache.c @@ -0,0 +1,417 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Author: mod_file_cache by Bill Stoddard + * Based on mod_mmap_static by Dean Gaudet + * + * v0.01: initial implementation + */ + +/* + Documentation: + + Some sites have a set of static files that are really busy, and + change infrequently (or even on a regular schedule). Save time + by caching open handles to these files. This module, unlike + mod_mmap_static, caches open file handles, not file content. + On systems (like Windows) with heavy system call overhead and + that have an efficient sendfile implementation, caching file handles + offers several advantages over caching content. First, the file system + can manage the memory, allowing infrequently hit cached files to + be paged out. Second, since caching open handles does not consume + significant resources, it will be possible to enable an AutoLoadCache + feature where static files are dynamically loaded in the cache + as the server runs. On systems that have file change notification, + this module can be enhanced to automatically garbage collect + cached files that change on disk. + + This module should work on Unix systems that have sendfile. Place + cachefile directives into your configuration to direct files to + be cached. + + cachefile /path/to/file1 + cachefile /path/to/file2 + ... + + These files are only cached when the server is restarted, so if you + change the list, or if the files are changed, then you'll need to + restart the server. + + To reiterate that point: if the files are modified *in place* + without restarting the server you may end up serving requests that + are completely bogus. You should update files by unlinking the old + copy and putting a new copy in place. + + There's no such thing as inheriting these files across vhosts or + whatever... place the directives in the main server only. + + Known problems: + + Don't use Alias or RewriteRule to move these files around... unless + you feel like paying for an extra stat() on each request. This is + a deficiency in the Apache API that will hopefully be solved some day. + The file will be served out of the file handle cache, but there will be + an extra stat() that's a waste. +*/ + +#include "apr.h" + +#if !(APR_HAS_SENDFILE || APR_HAS_MMAP) +#error mod_file_cache only works on systems with APR_HAS_SENDFILE or APR_HAS_MMAP +#endif + +#include "apr_mmap.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "apr_buckets.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_SYS_TYPES_H +#include +#endif + +#define CORE_PRIVATE + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_core.h" + +module AP_MODULE_DECLARE_DATA file_cache_module; + +typedef struct { +#if APR_HAS_SENDFILE + apr_file_t *file; +#endif + const char *filename; + apr_finfo_t finfo; + int is_mmapped; +#if APR_HAS_MMAP + apr_mmap_t *mm; +#endif + char mtimestr[APR_RFC822_DATE_LEN]; + char sizestr[21]; /* big enough to hold any 64-bit file size + null */ +} a_file; + +typedef struct { + apr_hash_t *fileht; +} a_server_config; + + +static void *create_server_config(apr_pool_t *p, server_rec *s) +{ + a_server_config *sconf = apr_palloc(p, sizeof(*sconf)); + + sconf->fileht = apr_hash_make(p); + return sconf; +} + +static void cache_the_file(cmd_parms *cmd, const char *filename, int mmap) +{ + a_server_config *sconf; + a_file *new_file; + a_file tmp; + apr_file_t *fd = NULL; + apr_status_t rc; + const char *fspec; + + fspec = ap_server_root_relative(cmd->pool, filename); + if (!fspec) { + ap_log_error(APLOG_MARK, APLOG_WARNING, APR_EBADPATH, cmd->server, + "mod_file_cache: invalid file path " + "%s, skipping", filename); + return; + } + if ((rc = apr_stat(&tmp.finfo, fspec, APR_FINFO_MIN, + cmd->temp_pool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, + "mod_file_cache: unable to stat(%s), skipping", fspec); + return; + } + if (tmp.finfo.filetype != APR_REG) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "mod_file_cache: %s isn't a regular file, skipping", fspec); + return; + } + if (tmp.finfo.size > AP_MAX_SENDFILE) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "mod_file_cache: %s is too large to cache, skipping", fspec); + return; + } + + rc = apr_file_open(&fd, fspec, APR_READ | APR_BINARY | APR_XTHREAD, + APR_OS_DEFAULT, cmd->pool); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, + "mod_file_cache: unable to open(%s, O_RDONLY), skipping", fspec); + return; + } + apr_file_inherit_set(fd); + + /* WooHoo, we have a file to put in the cache */ + new_file = apr_pcalloc(cmd->pool, sizeof(a_file)); + new_file->finfo = tmp.finfo; + +#if APR_HAS_MMAP + if (mmap) { + /* MMAPFile directive. MMAP'ing the file + * XXX: APR_HAS_LARGE_FILES issue; need to reject this request if + * size is greater than MAX(apr_size_t) (perhaps greater than 1M?). + */ + if ((rc = apr_mmap_create(&new_file->mm, fd, 0, + (apr_size_t)new_file->finfo.size, + APR_MMAP_READ, cmd->pool)) != APR_SUCCESS) { + apr_file_close(fd); + ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server, + "mod_file_cache: unable to mmap %s, skipping", filename); + return; + } + apr_file_close(fd); + new_file->is_mmapped = TRUE; + } +#endif +#if APR_HAS_SENDFILE + if (!mmap) { + /* CacheFile directive. Caching the file handle */ + new_file->is_mmapped = FALSE; + new_file->file = fd; + } +#endif + + new_file->filename = fspec; + apr_rfc822_date(new_file->mtimestr, new_file->finfo.mtime); + apr_snprintf(new_file->sizestr, sizeof new_file->sizestr, "%" APR_OFF_T_FMT, new_file->finfo.size); + + sconf = ap_get_module_config(cmd->server->module_config, &file_cache_module); + apr_hash_set(sconf->fileht, new_file->filename, strlen(new_file->filename), new_file); + +} + +static const char *cachefilehandle(cmd_parms *cmd, void *dummy, const char *filename) +{ +#if APR_HAS_SENDFILE + cache_the_file(cmd, filename, 0); +#else + /* Sendfile not supported by this OS */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "mod_file_cache: unable to cache file: %s. Sendfile is not supported on this OS", filename); +#endif + return NULL; +} +static const char *cachefilemmap(cmd_parms *cmd, void *dummy, const char *filename) +{ +#if APR_HAS_MMAP + cache_the_file(cmd, filename, 1); +#else + /* MMAP not supported by this OS */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "mod_file_cache: unable to cache file: %s. MMAP is not supported by this OS", filename); +#endif + return NULL; +} + +static int file_cache_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* Hummm, anything to do here? */ + return OK; +} + +/* If it's one of ours, fill in r->finfo now to avoid extra stat()... this is a + * bit of a kludge, because we really want to run after core_translate runs. + */ +static int file_cache_xlat(request_rec *r) +{ + a_server_config *sconf; + a_file *match; + int res; + + sconf = ap_get_module_config(r->server->module_config, &file_cache_module); + + /* we only operate when at least one cachefile directive was used */ + if (!apr_hash_count(sconf->fileht)) { + return DECLINED; + } + + res = ap_core_translate(r); + if (res != OK || !r->filename) { + return res; + } + + /* search the cache */ + match = (a_file *) apr_hash_get(sconf->fileht, r->filename, APR_HASH_KEY_STRING); + if (match == NULL) + return DECLINED; + + /* pass search results to handler */ + ap_set_module_config(r->request_config, &file_cache_module, match); + + /* shortcircuit the get_path_info() stat() calls and stuff */ + r->finfo = match->finfo; + return OK; +} + +static int mmap_handler(request_rec *r, a_file *file) +{ +#if APR_HAS_MMAP + conn_rec *c = r->connection; + apr_bucket *b; + apr_mmap_t *mm; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); + + apr_mmap_dup(&mm, file->mm, r->pool); + b = apr_bucket_mmap_create(mm, 0, (apr_size_t)file->finfo.size, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) + return HTTP_INTERNAL_SERVER_ERROR; +#endif + return OK; +} + +static int sendfile_handler(request_rec *r, a_file *file) +{ +#if APR_HAS_SENDFILE + conn_rec *c = r->connection; + apr_bucket *b; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); + + b = apr_bucket_file_create(file->file, 0, (apr_size_t)file->finfo.size, + r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) + return HTTP_INTERNAL_SERVER_ERROR; +#endif + return OK; +} + +static int file_cache_handler(request_rec *r) +{ + a_file *match; + int errstatus; + int rc = OK; + + /* XXX: not sure if this is right yet + * see comment in http_core.c:default_handler + */ + if (ap_strcmp_match(r->handler, "*/*")) { + return DECLINED; + } + + /* we don't handle anything but GET */ + if (r->method_number != M_GET) return DECLINED; + + /* did xlat phase find the file? */ + match = ap_get_module_config(r->request_config, &file_cache_module); + + if (match == NULL) { + return DECLINED; + } + + /* note that we would handle GET on this resource */ + r->allowed |= (AP_METHOD_BIT << M_GET); + + /* This handler has no use for a request body (yet), but we still + * need to read and discard it if the client sent one. + */ + if ((errstatus = ap_discard_request_body(r)) != OK) + return errstatus; + + ap_update_mtime(r, match->finfo.mtime); + + /* ap_set_last_modified() always converts the file mtime to a string + * which is slow. Accelerate the common case. + * ap_set_last_modified(r); + */ + { + apr_time_t mod_time; + char *datestr; + + mod_time = ap_rationalize_mtime(r, r->mtime); + if (mod_time == match->finfo.mtime) + datestr = match->mtimestr; + else { + datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN); + apr_rfc822_date(datestr, mod_time); + } + apr_table_setn(r->headers_out, "Last-Modified", datestr); + } + + ap_set_etag(r); + if ((errstatus = ap_meets_conditions(r)) != OK) { + return errstatus; + } + + /* ap_set_content_length() always converts the same number and never + * returns an error. Accelerate it. + */ + r->clength = match->finfo.size; + apr_table_setn(r->headers_out, "Content-Length", match->sizestr); + + /* Call appropriate handler */ + if (!r->header_only) { + if (match->is_mmapped == TRUE) + rc = mmap_handler(r, match); + else + rc = sendfile_handler(r, match); + } + + return rc; +} + +static command_rec file_cache_cmds[] = +{ +AP_INIT_ITERATE("cachefile", cachefilehandle, NULL, RSRC_CONF, + "A space separated list of files to add to the file handle cache at config time"), +AP_INIT_ITERATE("mmapfile", cachefilemmap, NULL, RSRC_CONF, + "A space separated list of files to mmap at config time"), + {NULL} +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(file_cache_handler, NULL, NULL, APR_HOOK_LAST); + ap_hook_post_config(file_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_translate_name(file_cache_xlat, NULL, NULL, APR_HOOK_MIDDLE); + /* This trick doesn't work apparently because the translate hooks + are single shot. If the core_hook returns OK, then our hook is + not called. + ap_hook_translate_name(file_cache_xlat, aszPre, NULL, APR_HOOK_MIDDLE); + */ + +} + +module AP_MODULE_DECLARE_DATA file_cache_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + create_server_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + file_cache_cmds, /* command handlers */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/cache/mod_file_cache.dsp b/trunk/modules/cache/mod_file_cache.dsp new file mode 100644 index 0000000000..96dc5a3706 --- /dev/null +++ b/trunk/modules/cache/mod_file_cache.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_file_cache" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_file_cache - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_file_cache.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_file_cache.mak" CFG="mod_file_cache - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_file_cache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_file_cache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_file_cache - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_file_cache_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so +# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_file_cache - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_file_cache_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL" +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so +# ADD LINK32 /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_file_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_file_cache.so + +!ENDIF + +# Begin Target + +# Name "mod_file_cache - Win32 Release" +# Name "mod_file_cache - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_file_cache.c +# End Source File +# Begin Source File + +SOURCE=.\mod_file_cache.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_file_cache - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_file_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_file_cache.so "file_cache_module for Apache" ../../include/ap_release.h > .\mod_file_cache.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_file_cache - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_file_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_file_cache.so "file_cache_module for Apache" ../../include/ap_release.h > .\mod_file_cache.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/cache/mod_file_cache.exp b/trunk/modules/cache/mod_file_cache.exp new file mode 100644 index 0000000000..23b092a640 --- /dev/null +++ b/trunk/modules/cache/mod_file_cache.exp @@ -0,0 +1 @@ +file_cache_module diff --git a/trunk/modules/cache/mod_mem_cache.c b/trunk/modules/cache/mod_mem_cache.c new file mode 100644 index 0000000000..b5ddead953 --- /dev/null +++ b/trunk/modules/cache/mod_mem_cache.c @@ -0,0 +1,1087 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Rules for managing obj->refcount: + * refcount should be incremented when an object is placed in the cache. Insertion + * of an object into the cache and the refcount increment should happen under + * protection of the sconf->lock. + * + * refcount should be decremented when the object is removed from the cache. + * Object should be removed from the cache and the refcount decremented while + * under protection of the sconf->lock. + * + * refcount should be incremented when an object is retrieved from the cache + * by a worker thread. The retrieval/find operation and refcount increment + * should occur under protection of the sconf->lock + * + * refcount can be atomically decremented w/o protection of the sconf->lock + * by worker threads. + * + * Any object whose refcount drops to 0 should be freed/cleaned up. A refcount + * of 0 means the object is not in the cache and no worker threads are accessing + * it. + */ +#define CORE_PRIVATE +#include "mod_cache.h" +#include "cache_pqueue.h" +#include "cache_cache.h" +#include "ap_provider.h" +#include "ap_mpm.h" +#include "apr_thread_mutex.h" +#if APR_HAVE_UNISTD_H +#include +#endif + +#if !APR_HAS_THREADS +#error This module does not currently compile unless you have a thread-capable APR. Sorry! +#endif + +module AP_MODULE_DECLARE_DATA mem_cache_module; + +typedef enum { + CACHE_TYPE_FILE = 1, + CACHE_TYPE_HEAP, + CACHE_TYPE_MMAP +} cache_type_e; + +typedef struct { + char* hdr; + char* val; +} cache_header_tbl_t; + +typedef struct mem_cache_object { + cache_type_e type; + apr_ssize_t num_header_out; + apr_ssize_t num_req_hdrs; + cache_header_tbl_t *header_out; + cache_header_tbl_t *req_hdrs; /* for Vary negotiation */ + apr_size_t m_len; + void *m; + apr_os_file_t fd; + apr_int32_t flags; /* File open flags */ + long priority; /**< the priority of this entry */ + long total_refs; /**< total number of references this entry has had */ + + apr_uint32_t pos; /**< the position of this entry in the cache */ + +} mem_cache_object_t; + +typedef struct { + apr_thread_mutex_t *lock; + cache_cache_t *cache_cache; + + /* Fields set by config directives */ + apr_size_t min_cache_object_size; /* in bytes */ + apr_size_t max_cache_object_size; /* in bytes */ + apr_size_t max_cache_size; /* in bytes */ + apr_size_t max_object_cnt; + cache_pqueue_set_priority cache_remove_algorithm; + + /* maximum amount of data to buffer on a streamed response where + * we haven't yet seen EOS */ + apr_off_t max_streaming_buffer_size; +} mem_cache_conf; +static mem_cache_conf *sconf; + +#define DEFAULT_MAX_CACHE_SIZE 100*1024 +#define DEFAULT_MIN_CACHE_OBJECT_SIZE 0 +#define DEFAULT_MAX_CACHE_OBJECT_SIZE 10000 +#define DEFAULT_MAX_OBJECT_CNT 1009 +#define DEFAULT_MAX_STREAMING_BUFFER_SIZE 100000 +#define CACHEFILE_LEN 20 + +/* Forward declarations */ +static int remove_entity(cache_handle_t *h); +static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *i); +static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b); +static apr_status_t recall_headers(cache_handle_t *h, request_rec *r); +static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb); + +static void cleanup_cache_object(cache_object_t *obj); + +static long memcache_get_priority(void*a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + + return mobj->priority; +} + +static void memcache_inc_frequency(void*a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + + mobj->total_refs++; + mobj->priority = 0; +} + +static void memcache_set_pos(void *a, apr_ssize_t pos) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + + apr_atomic_set32(&mobj->pos, pos); +} +static apr_ssize_t memcache_get_pos(void *a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + + return apr_atomic_read32(&mobj->pos); +} + +static apr_size_t memcache_cache_get_size(void*a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + return mobj->m_len; +} +/** callback to get the key of a item */ +static const char* memcache_cache_get_key(void*a) +{ + cache_object_t *obj = (cache_object_t *)a; + return obj->key; +} +/** + * memcache_cache_free() + * memcache_cache_free is a callback that is only invoked by a thread + * running in cache_insert(). cache_insert() runs under protection + * of sconf->lock. By the time this function has been entered, the cache_object + * has been ejected from the cache. decrement the refcount and if the refcount drops + * to 0, cleanup the cache object. + */ +static void memcache_cache_free(void*a) +{ + cache_object_t *obj = (cache_object_t *)a; + + /* Decrement the refcount to account for the object being ejected + * from the cache. If the refcount is 0, free the object. + */ + if (!apr_atomic_dec32(&obj->refcount)) { + cleanup_cache_object(obj); + } +} +/* + * functions return a 'negative' score since priority queues + * dequeue the object with the highest value first + */ +static long memcache_lru_algorithm(long queue_clock, void *a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + if (mobj->priority == 0) + mobj->priority = queue_clock - mobj->total_refs; + + /* + * a 'proper' LRU function would just be + * mobj->priority = mobj->total_refs; + */ + return mobj->priority; +} + +static long memcache_gdsf_algorithm(long queue_clock, void *a) +{ + cache_object_t *obj = (cache_object_t *)a; + mem_cache_object_t *mobj = obj->vobj; + + if (mobj->priority == 0) + mobj->priority = queue_clock - + (long)(mobj->total_refs*1000 / mobj->m_len); + + return mobj->priority; +} + +static void cleanup_cache_object(cache_object_t *obj) +{ + mem_cache_object_t *mobj = obj->vobj; + + /* TODO: + * We desperately need a more efficient way of allocating objects. We're + * making way too many malloc calls to create a fully populated + * cache object... + */ + + /* Cleanup the cache_object_t */ + if (obj->key) { + free(obj->key); + } + + free(obj); + + /* Cleanup the mem_cache_object_t */ + if (mobj) { + if (mobj->type == CACHE_TYPE_HEAP && mobj->m) { + free(mobj->m); + } + if (mobj->type == CACHE_TYPE_FILE && mobj->fd) { +#ifdef WIN32 + CloseHandle(mobj->fd); +#else + close(mobj->fd); +#endif + } + if (mobj->header_out) { + if (mobj->header_out[0].hdr) + free(mobj->header_out[0].hdr); + free(mobj->header_out); + } + if (mobj->req_hdrs) { + if (mobj->req_hdrs[0].hdr) + free(mobj->req_hdrs[0].hdr); + free(mobj->req_hdrs); + } + free(mobj); + } +} +static apr_status_t decrement_refcount(void *arg) +{ + cache_object_t *obj = (cache_object_t *) arg; + + /* If obj->complete is not set, the cache update failed and the + * object needs to be removed from the cache then cleaned up. + * The garbage collector may have ejected the object from the + * cache already, so make sure it is really still in the cache + * before attempting to remove it. + */ + if (!obj->complete) { + cache_object_t *tobj = NULL; + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + tobj = cache_find(sconf->cache_cache, obj->key); + if (tobj == obj) { + cache_remove(sconf->cache_cache, obj); + apr_atomic_dec32(&obj->refcount); + } + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + } + + /* If the refcount drops to 0, cleanup the cache object */ + if (!apr_atomic_dec32(&obj->refcount)) { + cleanup_cache_object(obj); + } + return APR_SUCCESS; +} +static apr_status_t cleanup_cache_mem(void *sconfv) +{ + cache_object_t *obj; + mem_cache_conf *co = (mem_cache_conf*) sconfv; + + if (!co) { + return APR_SUCCESS; + } + if (!co->cache_cache) { + return APR_SUCCESS; + } + + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + obj = cache_pop(co->cache_cache); + while (obj) { + /* Iterate over the cache and clean up each unreferenced entry */ + if (!apr_atomic_dec32(&obj->refcount)) { + cleanup_cache_object(obj); + } + obj = cache_pop(co->cache_cache); + } + + /* Cache is empty, free the cache table */ + cache_free(co->cache_cache); + + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + return APR_SUCCESS; +} +/* + * TODO: enable directives to be overridden in various containers + */ +static void *create_cache_config(apr_pool_t *p, server_rec *s) +{ + sconf = apr_pcalloc(p, sizeof(mem_cache_conf)); + + sconf->min_cache_object_size = DEFAULT_MIN_CACHE_OBJECT_SIZE; + sconf->max_cache_object_size = DEFAULT_MAX_CACHE_OBJECT_SIZE; + /* Number of objects in the cache */ + sconf->max_object_cnt = DEFAULT_MAX_OBJECT_CNT; + /* Size of the cache in bytes */ + sconf->max_cache_size = DEFAULT_MAX_CACHE_SIZE; + sconf->cache_cache = NULL; + sconf->cache_remove_algorithm = memcache_gdsf_algorithm; + sconf->max_streaming_buffer_size = DEFAULT_MAX_STREAMING_BUFFER_SIZE; + + return sconf; +} + +static int create_entity(cache_handle_t *h, cache_type_e type_e, + request_rec *r, const char *key, apr_off_t len) +{ + cache_object_t *obj, *tmp_obj; + mem_cache_object_t *mobj; + apr_size_t key_len; + + if (len == -1) { + /* Caching a streaming response. Assume the response is + * less than or equal to max_streaming_buffer_size. We will + * correct all the cache size counters in store_body once + * we know exactly know how much we are caching. + */ + len = sconf->max_streaming_buffer_size; + } + + /* Note: cache_insert() will automatically garbage collect + * objects from the cache if the max_cache_size threshold is + * exceeded. This means mod_mem_cache does not need to implement + * max_cache_size checks. + */ + if (len < sconf->min_cache_object_size || + len > sconf->max_cache_object_size) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "mem_cache: URL %s failed the size check and will not be cached.", + key); + return DECLINED; + } + + if (type_e == CACHE_TYPE_FILE) { + /* CACHE_TYPE_FILE is only valid for local content handled by the + * default handler. Need a better way to check if the file is + * local or not. + */ + if (!r->filename) { + return DECLINED; + } + } + + /* Allocate and initialize cache_object_t */ + obj = calloc(1, sizeof(*obj)); + if (!obj) { + return DECLINED; + } + key_len = strlen(key) + 1; + obj->key = malloc(key_len); + if (!obj->key) { + cleanup_cache_object(obj); + return DECLINED; + } + memcpy(obj->key, key, key_len); + + /* Allocate and init mem_cache_object_t */ + mobj = calloc(1, sizeof(*mobj)); + if (!mobj) { + cleanup_cache_object(obj); + return DECLINED; + } + + /* Finish initing the cache object */ + apr_atomic_set32(&obj->refcount, 1); + mobj->total_refs = 1; + obj->complete = 0; + obj->vobj = mobj; + /* Safe cast: We tested < sconf->max_cache_object_size above */ + mobj->m_len = (apr_size_t)len; + mobj->type = type_e; + + /* Place the cache_object_t into the hash table. + * Note: Perhaps we should wait to put the object in the + * hash table when the object is complete? I add the object here to + * avoid multiple threads attempting to cache the same content only + * to discover at the very end that only one of them will succeed. + * Furthermore, adding the cache object to the table at the end could + * open up a subtle but easy to exploit DoS hole: someone could request + * a very large file with multiple requests. Better to detect this here + * rather than after the cache object has been completely built and + * initialized... + * XXX Need a way to insert into the cache w/o such coarse grained locking + */ + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + tmp_obj = (cache_object_t *) cache_find(sconf->cache_cache, key); + + if (!tmp_obj) { + cache_insert(sconf->cache_cache, obj); + /* Add a refcount to account for the reference by the + * hashtable in the cache. Refcount should be 2 now, one + * for this thread, and one for the cache. + */ + apr_atomic_inc32(&obj->refcount); + } + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + + if (tmp_obj) { + /* This thread collided with another thread loading the same object + * into the cache at the same time. Defer to the other thread which + * is further along. + */ + cleanup_cache_object(obj); + return DECLINED; + } + + apr_pool_cleanup_register(r->pool, obj, decrement_refcount, + apr_pool_cleanup_null); + + /* Populate the cache handle */ + h->cache_obj = obj; + + return OK; +} + +static int create_mem_entity(cache_handle_t *h, request_rec *r, + const char *key, apr_off_t len) +{ + return create_entity(h, CACHE_TYPE_HEAP, r, key, len); +} + +static int create_fd_entity(cache_handle_t *h, request_rec *r, + const char *key, apr_off_t len) +{ + return create_entity(h, CACHE_TYPE_FILE, r, key, len); +} + +static int open_entity(cache_handle_t *h, request_rec *r, const char *key) +{ + cache_object_t *obj; + + /* Look up entity keyed to 'url' */ + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + obj = (cache_object_t *) cache_find(sconf->cache_cache, key); + if (obj) { + if (obj->complete) { + request_rec *rmain=r, *rtmp; + apr_atomic_inc32(&obj->refcount); + /* cache is worried about overall counts, not 'open' ones */ + cache_update(sconf->cache_cache, obj); + + /* If this is a subrequest, register the cleanup against + * the main request. This will prevent the cache object + * from being cleaned up from under the request after the + * subrequest is destroyed. + */ + rtmp = r; + while (rtmp) { + rmain = rtmp; + rtmp = rmain->main; + } + apr_pool_cleanup_register(rmain->pool, obj, decrement_refcount, + apr_pool_cleanup_null); + } + else { + obj = NULL; + } + } + + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + + if (!obj) { + return DECLINED; + } + + /* Initialize the cache_handle */ + h->cache_obj = obj; + h->req_hdrs = NULL; /* Pick these up in recall_headers() */ + return OK; +} + +/* remove_entity() + * Notes: + * refcount should be at least 1 upon entry to this function to account + * for this thread's reference to the object. If the refcount is 1, then + * object has been removed from the cache by another thread and this thread + * is the last thread accessing the object. + */ +static int remove_entity(cache_handle_t *h) +{ + cache_object_t *obj = h->cache_obj; + cache_object_t *tobj = NULL; + + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + + /* If the entity is still in the cache, remove it and decrement the + * refcount. If the entity is not in the cache, do nothing. In both cases + * decrement_refcount called by the last thread referencing the object will + * trigger the cleanup. + */ + tobj = cache_find(sconf->cache_cache, obj->key); + if (tobj == obj) { + cache_remove(sconf->cache_cache, obj); + apr_atomic_dec32(&obj->refcount); + } + + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + + return OK; +} +static apr_status_t serialize_table(cache_header_tbl_t **obj, + apr_ssize_t *nelts, + apr_table_t *table) +{ + const apr_array_header_t *elts_arr = apr_table_elts(table); + apr_table_entry_t *elts = (apr_table_entry_t *) elts_arr->elts; + apr_ssize_t i; + apr_size_t len = 0; + apr_size_t idx = 0; + char *buf; + + *nelts = elts_arr->nelts; + if (*nelts == 0 ) { + *obj=NULL; + return APR_SUCCESS; + } + *obj = malloc(sizeof(cache_header_tbl_t) * elts_arr->nelts); + if (NULL == *obj) { + return APR_ENOMEM; + } + for (i = 0; i < elts_arr->nelts; ++i) { + len += strlen(elts[i].key); + len += strlen(elts[i].val); + len += 2; /* Extra space for NULL string terminator for key and val */ + } + + /* Transfer the headers into a contiguous memory block */ + buf = malloc(len); + if (!buf) { + *obj = NULL; + return APR_ENOMEM; + } + + for (i = 0; i < *nelts; ++i) { + (*obj)[i].hdr = &buf[idx]; + len = strlen(elts[i].key) + 1; /* Include NULL terminator */ + memcpy(&buf[idx], elts[i].key, len); + idx+=len; + + (*obj)[i].val = &buf[idx]; + len = strlen(elts[i].val) + 1; + memcpy(&buf[idx], elts[i].val, len); + idx+=len; + } + return APR_SUCCESS; +} +static int unserialize_table( cache_header_tbl_t *ctbl, + int num_headers, + apr_table_t *t ) +{ + int i; + + for (i = 0; i < num_headers; ++i) { + apr_table_addn(t, ctbl[i].hdr, ctbl[i].val); + } + + return APR_SUCCESS; +} +/* Define request processing hook handlers */ +/* remove_url() + * Notes: + */ +static int remove_url(const char *key) +{ + cache_object_t *obj; + int cleanup = 0; + + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + + obj = cache_find(sconf->cache_cache, key); + if (obj) { + cache_remove(sconf->cache_cache, obj); + /* For performance, cleanup cache object after releasing the lock */ + cleanup = !apr_atomic_dec32(&obj->refcount); + } + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + + if (cleanup) { + cleanup_cache_object(obj); + } + + return OK; +} + +static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) +{ + int rc; + mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj; + + h->req_hdrs = apr_table_make(r->pool, mobj->num_req_hdrs); + h->resp_hdrs = apr_table_make(r->pool, mobj->num_header_out); + + rc = unserialize_table(mobj->req_hdrs, mobj->num_req_hdrs, h->req_hdrs); + rc = unserialize_table(mobj->header_out, mobj->num_header_out, + h->resp_hdrs); + + return rc; +} + +static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb) +{ + apr_bucket *b; + mem_cache_object_t *mobj = (mem_cache_object_t*) h->cache_obj->vobj; + + if (mobj->type == CACHE_TYPE_FILE) { + /* CACHE_TYPE_FILE */ + apr_file_t *file; + apr_os_file_put(&file, &mobj->fd, mobj->flags, p); + b = apr_bucket_file_create(file, 0, mobj->m_len, p, bb->bucket_alloc); + } + else { + /* CACHE_TYPE_HEAP */ + b = apr_bucket_immortal_create(mobj->m, mobj->m_len, bb->bucket_alloc); + } + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(bb->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + return APR_SUCCESS; +} + + +static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *info) +{ + cache_object_t *obj = h->cache_obj; + mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj; + int rc; + apr_table_t *headers_out; + + /* + * The cache needs to keep track of the following information: + * - Date, LastMod, Version, ReqTime, RespTime, ContentLength + * - The original request headers (for Vary) + * - The original response headers (for returning with a cached response) + * - The body of the message + */ + rc = serialize_table(&mobj->req_hdrs, + &mobj->num_req_hdrs, + r->headers_in); + if (rc != APR_SUCCESS) { + return rc; + } + + /* Precompute how much storage we need to hold the headers */ + headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out, + r->server); + headers_out = apr_table_overlay(r->pool, headers_out, r->err_headers_out); + + rc = serialize_table(&mobj->header_out, &mobj->num_header_out, + headers_out); + if (rc != APR_SUCCESS) { + return rc; + } + + /* Init the info struct */ + obj->info.status = info->status; + if (info->date) { + obj->info.date = info->date; + } + if (info->response_time) { + obj->info.response_time = info->response_time; + } + if (info->request_time) { + obj->info.request_time = info->request_time; + } + if (info->expire) { + obj->info.expire = info->expire; + } + + return APR_SUCCESS; +} + +static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b) +{ + apr_status_t rv; + cache_object_t *obj = h->cache_obj; + cache_object_t *tobj = NULL; + mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj; + apr_read_type_e eblock = APR_BLOCK_READ; + apr_bucket *e; + char *cur; + int eos = 0; + + if (mobj->type == CACHE_TYPE_FILE) { + apr_file_t *file = NULL; + int fd = 0; + int other = 0; + + /* We can cache an open file descriptor if: + * - the brigade contains one and only one file_bucket && + * - the brigade is complete && + * - the file_bucket is the last data bucket in the brigade + */ + for (e = APR_BRIGADE_FIRST(b); + e != APR_BRIGADE_SENTINEL(b); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + eos = 1; + } + else if (APR_BUCKET_IS_FILE(e)) { + apr_bucket_file *a = e->data; + fd++; + file = a->fd; + } + else { + other++; + } + } + if (fd == 1 && !other && eos) { + apr_file_t *tmpfile; + const char *name; + /* Open a new XTHREAD handle to the file */ + apr_file_name_get(&name, file); + mobj->flags = ((APR_SENDFILE_ENABLED & apr_file_flags_get(file)) + | APR_READ | APR_BINARY | APR_XTHREAD | APR_FILE_NOCLEANUP); + rv = apr_file_open(&tmpfile, name, mobj->flags, + APR_OS_DEFAULT, r->pool); + if (rv != APR_SUCCESS) { + return rv; + } + apr_file_inherit_unset(tmpfile); + apr_os_file_get(&(mobj->fd), tmpfile); + + /* Open for business */ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "mem_cache: Cached file: %s with key: %s", name, obj->key); + obj->complete = 1; + return APR_SUCCESS; + } + + /* Content not suitable for fd caching. Cache in-memory instead. */ + mobj->type = CACHE_TYPE_HEAP; + } + + /* + * FD cacheing is not enabled or the content was not + * suitable for fd caching. + */ + if (mobj->m == NULL) { + mobj->m = malloc(mobj->m_len); + if (mobj->m == NULL) { + return APR_ENOMEM; + } + obj->count = 0; + } + cur = (char*) mobj->m + obj->count; + + /* Iterate accross the brigade and populate the cache storage */ + for (e = APR_BRIGADE_FIRST(b); + e != APR_BRIGADE_SENTINEL(b); + e = APR_BUCKET_NEXT(e)) + { + const char *s; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(e)) { + if (mobj->m_len > obj->count) { + /* Caching a streamed response. Reallocate a buffer of the + * correct size and copy the streamed response into that + * buffer */ + char *buf = malloc(obj->count); + if (!buf) { + return APR_ENOMEM; + } + memcpy(buf, mobj->m, obj->count); + free(mobj->m); + mobj->m = buf; + + /* Now comes the crufty part... there is no way to tell the + * cache that the size of the object has changed. We need + * to remove the object, update the size and re-add the + * object, all under protection of the lock. + */ + if (sconf->lock) { + apr_thread_mutex_lock(sconf->lock); + } + /* Has the object been ejected from the cache? + */ + tobj = (cache_object_t *) cache_find(sconf->cache_cache, obj->key); + if (tobj == obj) { + /* Object is still in the cache, remove it, update the len field then + * replace it under protection of sconf->lock. + */ + cache_remove(sconf->cache_cache, obj); + /* For illustration, cache no longer has reference to the object + * so decrement the refcount + * apr_atomic_dec32(&obj->refcount); + */ + mobj->m_len = obj->count; + + cache_insert(sconf->cache_cache, obj); + /* For illustration, cache now has reference to the object, so + * increment the refcount + * apr_atomic_inc32(&obj->refcount); + */ + } + else if (tobj) { + /* Different object with the same key found in the cache. Doing nothing + * here will cause the object refcount to drop to 0 in decrement_refcount + * and the object will be cleaned up. + */ + + } else { + /* Object has been ejected from the cache, add it back to the cache */ + mobj->m_len = obj->count; + cache_insert(sconf->cache_cache, obj); + apr_atomic_inc32(&obj->refcount); + } + + if (sconf->lock) { + apr_thread_mutex_unlock(sconf->lock); + } + } + /* Open for business */ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "mem_cache: Cached url: %s", obj->key); + obj->complete = 1; + break; + } + rv = apr_bucket_read(e, &s, &len, eblock); + if (rv != APR_SUCCESS) { + return rv; + } + if (len) { + /* Check for buffer overflow */ + if ((obj->count + len) > mobj->m_len) { + return APR_ENOMEM; + } + else { + memcpy(cur, s, len); + cur+=len; + obj->count+=len; + } + } + /* This should not fail, but if it does, we are in BIG trouble + * cause we just stomped all over the heap. + */ + AP_DEBUG_ASSERT(obj->count <= mobj->m_len); + } + return APR_SUCCESS; +} +/** + * Configuration and start-up + */ +static int mem_cache_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + int threaded_mpm; + + /* Sanity check the cache configuration */ + if (sconf->min_cache_object_size >= sconf->max_cache_object_size) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, + "MCacheMaxObjectSize must be greater than MCacheMinObjectSize"); + return DONE; + } + if (sconf->max_cache_object_size >= sconf->max_cache_size) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, + "MCacheSize must be greater than MCacheMaxObjectSize"); + return DONE; + } + if (sconf->max_streaming_buffer_size > sconf->max_cache_object_size) { + /* Issue a notice only if something other than the default config + * is being used */ + if (sconf->max_streaming_buffer_size != DEFAULT_MAX_STREAMING_BUFFER_SIZE && + sconf->max_cache_object_size != DEFAULT_MAX_CACHE_OBJECT_SIZE) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "MCacheMaxStreamingBuffer must be less than or equal to MCacheMaxObjectSize. " + "Resetting MCacheMaxStreamingBuffer to MCacheMaxObjectSize."); + } + sconf->max_streaming_buffer_size = sconf->max_cache_object_size; + } + if (sconf->max_streaming_buffer_size < sconf->min_cache_object_size) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "MCacheMaxStreamingBuffer must be greater than or equal to MCacheMinObjectSize. " + "Resetting MCacheMaxStreamingBuffer to MCacheMinObjectSize."); + sconf->max_streaming_buffer_size = sconf->min_cache_object_size; + } + ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm); + if (threaded_mpm) { + apr_thread_mutex_create(&sconf->lock, APR_THREAD_MUTEX_DEFAULT, p); + } + + sconf->cache_cache = cache_init(sconf->max_object_cnt, + sconf->max_cache_size, + memcache_get_priority, + sconf->cache_remove_algorithm, + memcache_get_pos, + memcache_set_pos, + memcache_inc_frequency, + memcache_cache_get_size, + memcache_cache_get_key, + memcache_cache_free); + apr_pool_cleanup_register(p, sconf, cleanup_cache_mem, apr_pool_cleanup_null); + + if (sconf->cache_cache) + return OK; + + return -1; + +} + +static const char +*set_max_cache_size(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + apr_size_t val; + + if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) { + return "MCacheSize argument must be an integer representing the max cache size in KBytes."; + } + sconf->max_cache_size = val*1024; + return NULL; +} +static const char +*set_min_cache_object_size(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + apr_size_t val; + + if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) { + return "MCacheMinObjectSize value must be an integer (bytes)"; + } + sconf->min_cache_object_size = val; + return NULL; +} +static const char +*set_max_cache_object_size(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + apr_size_t val; + + if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) { + return "MCacheMaxObjectSize value must be an integer (bytes)"; + } + sconf->max_cache_object_size = val; + return NULL; +} +static const char +*set_max_object_count(cmd_parms *parms, void *in_struct_ptr, const char *arg) +{ + apr_size_t val; + + if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) { + return "MCacheMaxObjectCount value must be an integer"; + } + sconf->max_object_cnt = val; + return NULL; +} + +static const char +*set_cache_removal_algorithm(cmd_parms *parms, void *name, const char *arg) +{ + if (strcasecmp("LRU", arg)) { + sconf->cache_remove_algorithm = memcache_lru_algorithm; + } + else { + if (strcasecmp("GDSF", arg)) { + sconf->cache_remove_algorithm = memcache_gdsf_algorithm; + } + else { + return "currently implemented algorithms are LRU and GDSF"; + } + } + return NULL; +} + +static const char *set_max_streaming_buffer(cmd_parms *parms, void *dummy, + const char *arg) +{ + char *err; + if (apr_strtoff(&sconf->max_streaming_buffer_size, arg, &err, 10) || *err) { + return "MCacheMaxStreamingBuffer value must be a number"; + } + + return NULL; +} + +static const command_rec cache_cmds[] = +{ + AP_INIT_TAKE1("MCacheSize", set_max_cache_size, NULL, RSRC_CONF, + "The maximum amount of memory used by the cache in KBytes"), + AP_INIT_TAKE1("MCacheMaxObjectCount", set_max_object_count, NULL, RSRC_CONF, + "The maximum number of objects allowed to be placed in the cache"), + AP_INIT_TAKE1("MCacheMinObjectSize", set_min_cache_object_size, NULL, RSRC_CONF, + "The minimum size (in bytes) of an object to be placed in the cache"), + AP_INIT_TAKE1("MCacheMaxObjectSize", set_max_cache_object_size, NULL, RSRC_CONF, + "The maximum size (in bytes) of an object to be placed in the cache"), + AP_INIT_TAKE1("MCacheRemovalAlgorithm", set_cache_removal_algorithm, NULL, RSRC_CONF, + "The algorithm used to remove entries from the cache (default: GDSF)"), + AP_INIT_TAKE1("MCacheMaxStreamingBuffer", set_max_streaming_buffer, NULL, RSRC_CONF, + "Maximum number of bytes of content to buffer for a streamed response"), + {NULL} +}; + +static const cache_provider cache_mem_provider = +{ + &remove_entity, + &store_headers, + &store_body, + &recall_headers, + &recall_body, + &create_mem_entity, + &open_entity, + &remove_url, +}; + +static const cache_provider cache_fd_provider = +{ + &remove_entity, + &store_headers, + &store_body, + &recall_headers, + &recall_body, + &create_fd_entity, + &open_entity, + &remove_url, +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_post_config(mem_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE); + /* cache initializer */ + /* cache_hook_init(cache_mem_init, NULL, NULL, APR_HOOK_MIDDLE); */ + /* + cache_hook_create_entity(create_entity, NULL, NULL, APR_HOOK_MIDDLE); + cache_hook_open_entity(open_entity, NULL, NULL, APR_HOOK_MIDDLE); + cache_hook_remove_url(remove_url, NULL, NULL, APR_HOOK_MIDDLE); + */ + ap_register_provider(p, CACHE_PROVIDER_GROUP, "mem", "0", + &cache_mem_provider); + ap_register_provider(p, CACHE_PROVIDER_GROUP, "fd", "0", + &cache_fd_provider); +} + +module AP_MODULE_DECLARE_DATA mem_cache_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + create_cache_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + cache_cmds, /* command apr_table_t */ + register_hooks +}; diff --git a/trunk/modules/cache/mod_mem_cache.dsp b/trunk/modules/cache/mod_mem_cache.dsp new file mode 100644 index 0000000000..9b908b7a8d --- /dev/null +++ b/trunk/modules/cache/mod_mem_cache.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_mem_cache" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_mem_cache - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_mem_cache.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_mem_cache.mak" CFG="mod_mem_cache - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_mem_cache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_mem_cache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_mem_cache - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "mod_mem_cache_EXPORTS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_mem_cache_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_mem_cache - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_mem_cache_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_mem_cache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mem_cache.so + +!ENDIF + +# Begin Target + +# Name "mod_mem_cache - Win32 Release" +# Name "mod_mem_cache - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_cache.h +# End Source File +# Begin Source File + +SOURCE=.\mod_mem_cache.c +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_mem_cache - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mem_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mem_cache.so "mem_cache_module for Apache" ../../include/ap_release.h > .\mod_mem_cache.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_mem_cache - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mem_cache.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mem_cache.so "mem_cache_module for Apache" ../../include/ap_release.h > .\mod_mem_cache.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/config5.m4 b/trunk/modules/config5.m4 new file mode 100644 index 0000000000..b8a5868bfe --- /dev/null +++ b/trunk/modules/config5.m4 @@ -0,0 +1,57 @@ +AC_MSG_CHECKING(for extra modules) +AC_ARG_WITH(module, + APACHE_HELP_STRING(--with-module=module-type:module-file, + Enable module-file in the modules/ directory.), + [ + as_save_IFS="$IFS"; IFS="," + for mod in $withval + do + modtype=`echo $mod | sed -e's/\(.*\):.*/\1/'` + pkg=`echo $mod | sed -e's/.*:\(.*\)/\1/'` + modfilec=`echo $pkg | sed -e 's;^.*/;;'` + modfileo=`echo $pkg | sed -e 's;^.*/;;' -e 's;\.c$;.o;'` + modpath_current="modules/$modtype" + if test "x$mod" != "x$modpath_current/$modfilec"; then + if test ! -d "$modpath_current"; then + mkdir $modpath_current + echo 'include $(top_srcdir)/build/special.mk' > $modpath_current/Makefile.in + fi + cp $pkg $modpath_current/$modfilec + fi + module=`echo $pkg | sed -e 's;\(.*/\)*mod_\(.*\).c;\2;'` + objects="mod_$module.lo" + # The filename of a convenience library must have a "lib" prefix: + libname="libmod_$module.la" + BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname" + if test ! -s "$modpath_current/modules.mk"; then + cat >>$modpath_current/modules.mk<>$modpath_current/modules.mk.tmp<> $modpath_current/modules.mk.tmp + rm $modpath_current/modules.mk + mv $modpath_current/modules.mk.tmp $modpath_current/modules.mk + sed -e "s/\(static =.*\)/\1 $libname/" $modpath_current/modules.mk > $modpath_current/modules.mk.tmp + rm $modpath_current/modules.mk + mv $modpath_current/modules.mk.tmp $modpath_current/modules.mk + fi + MODLIST="$MODLIST $module" + EXTRA_MODLIST="$EXTRA_MODLIST $modtype:$modfilec" + MODULE_DIRS="$MODULE_DIRS $modtype" + APACHE_FAST_OUTPUT($modpath_current/Makefile) + done + if test ! -z "$EXTRA_MODLIST"; then + AC_MSG_RESULT(added:$EXTRA_MODLIST) + fi + IFS="$as_save_IFS" + ], + [ AC_MSG_RESULT(none) + ]) diff --git a/trunk/modules/dav/fs/Makefile.in b/trunk/modules/dav/fs/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/dav/fs/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/dav/fs/NWGNUmakefile b/trunk/modules/dav/fs/NWGNUmakefile new file mode 100644 index 0000000000..3e596613fb --- /dev/null +++ b/trunk/modules/dav/fs/NWGNUmakefile @@ -0,0 +1,273 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(AP_WORK)/modules/dav/main \ + $(AP_WORK)/modules/arch/netware \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = modDAVFS + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) DAV FileSystem Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = modDAVFS Thread + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/moddavfs.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_dav_fs.o \ + $(OBJDIR)/dbm.o \ + $(OBJDIR)/lock.o \ + $(OBJDIR)/repos.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + mod_dav \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + @../main/dav.imp \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + dav_fs_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\moddavfs.nlm $(INSTALL)\Apache2\modules +# +# Any specialized rules here +# + +vpath %.c ../../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/dav/fs/config6.m4 b/trunk/modules/dav/fs/config6.m4 new file mode 100644 index 0000000000..515111cd01 --- /dev/null +++ b/trunk/modules/dav/fs/config6.m4 @@ -0,0 +1,23 @@ +dnl modules enabled in this directory by default + +APACHE_MODPATH_INIT(dav/fs) + +dav_fs_objects="mod_dav_fs.lo dbm.lo lock.lo repos.lo" + +if test "x$enable_dav" != "x"; then + dav_fs_enable=$enable_dav +else + dav_fs_enable=$dav_enable +fi + +case "$host" in + *os2*) + # OS/2 DLLs must resolve all symbols at build time + # and we need some from main DAV module + dav_fs_objects="$dav_fs_objects ../main/mod_dav.la" + ;; +esac + +APACHE_MODULE(dav_fs, DAV provider for the filesystem, $dav_fs_objects, , $dav_fs_enable) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/dav/fs/dbm.c b/trunk/modules/dav/fs/dbm.c new file mode 100644 index 0000000000..c5493fcf1c --- /dev/null +++ b/trunk/modules/dav/fs/dbm.c @@ -0,0 +1,753 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV extension module for Apache 2.0.* +** - Database support using DBM-style databases, +** part of the filesystem repository implementation +*/ + +/* +** This implementation uses a SDBM database per file and directory to +** record the properties. These databases are kept in a subdirectory (of +** the directory in question or the directory that holds the file in +** question) named by the macro DAV_FS_STATE_DIR (.DAV). The filename of the +** database is equivalent to the target filename, and is +** DAV_FS_STATE_FILE_FOR_DIR (.state_for_dir) for the directory itself. +*/ + +#include "apr_strings.h" +#include "apr_file_io.h" + +#include "apr_dbm.h" + +#define APR_WANT_BYTEFUNC +#include "apr_want.h" /* for ntohs and htons */ + +#include "mod_dav.h" +#include "repos.h" + + +struct dav_db { + apr_pool_t *pool; + apr_dbm_t *file; + + /* when used as a property database: */ + + int version; /* *minor* version of this db */ + + dav_buffer ns_table; /* table of namespace URIs */ + short ns_count; /* number of entries in table */ + int ns_table_dirty; /* ns_table was modified */ + apr_hash_t *uri_index; /* map URIs to (1-based) table indices */ + + dav_buffer wb_key; /* work buffer for dav_gdbm_key */ + + apr_datum_t iter; /* iteration key */ +}; + +/* ------------------------------------------------------------------------- + * + * GENERIC DBM ACCESS + * + * For the most part, this just uses the APR DBM functions. They are wrapped + * a bit with some error handling (using the mod_dav error functions). + */ + +void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, + const char **state1, const char **state2) +{ + if (fname == NULL) + fname = DAV_FS_STATE_FILE_FOR_DIR; + + apr_dbm_get_usednames(p, fname, state1, state2); +} + +static dav_error * dav_fs_dbm_error(dav_db *db, apr_pool_t *p, + apr_status_t status) +{ + int save_errno = errno; + int errcode; + const char *errstr; + dav_error *err; + char errbuf[200]; + + if (status == APR_SUCCESS) + return NULL; + + p = db ? db->pool : p; + + /* There might not be a if we had problems creating it. */ + if (db == NULL) { + errcode = 1; + errstr = "Could not open property database."; + } + else { + (void) apr_dbm_geterror(db->file, &errcode, errbuf, sizeof(errbuf)); + errstr = apr_pstrdup(p, errbuf); + } + + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, errstr); + err->save_errno = save_errno; + return err; +} + +/* ensure that our state subdirectory is present */ +/* ### does this belong here or in dav_fs_repos.c ?? */ +void dav_fs_ensure_state_dir(apr_pool_t * p, const char *dirname) +{ + const char *pathname = apr_pstrcat(p, dirname, "/" DAV_FS_STATE_DIR, NULL); + + /* ### do we need to deal with the umask? */ + + /* just try to make it, ignoring any resulting errors */ + (void) apr_dir_make(pathname, APR_OS_DEFAULT, p); +} + +/* dav_dbm_open_direct: Opens a *dbm database specified by path. + * ro = boolean read-only flag. + */ +dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, + dav_db **pdb) +{ + apr_status_t status; + apr_dbm_t *file; + + *pdb = NULL; + + if ((status = apr_dbm_open(&file, pathname, + ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, + APR_OS_DEFAULT, p)) + != APR_SUCCESS + && !ro) { + /* ### do something with 'status' */ + + /* we can't continue if we couldn't open the file + and we need to write */ + return dav_fs_dbm_error(NULL, p, status); + } + + /* may be NULL if we tried to open a non-existent db as read-only */ + if (file != NULL) { + /* we have an open database... return it */ + *pdb = apr_pcalloc(p, sizeof(**pdb)); + (*pdb)->pool = p; + (*pdb)->file = file; + } + + return NULL; +} + +static dav_error * dav_dbm_open(apr_pool_t * p, const dav_resource *resource, + int ro, dav_db **pdb) +{ + const char *dirpath; + const char *fname; + const char *pathname; + + /* Get directory and filename for resource */ + /* ### should test this result value... */ + (void) dav_fs_dir_file_name(resource, &dirpath, &fname); + + /* If not opening read-only, ensure the state dir exists */ + if (!ro) { + /* ### what are the perf implications of always checking this? */ + dav_fs_ensure_state_dir(p, dirpath); + } + + pathname = apr_pstrcat(p, dirpath, "/" DAV_FS_STATE_DIR "/", + fname ? fname : DAV_FS_STATE_FILE_FOR_DIR, + NULL); + + /* ### readers cannot open while a writer has this open; we should + ### perform a few retries with random pauses. */ + + /* ### do we need to deal with the umask? */ + + return dav_dbm_open_direct(p, pathname, ro, pdb); +} + +void dav_dbm_close(dav_db *db) +{ + apr_dbm_close(db->file); +} + +dav_error * dav_dbm_fetch(dav_db *db, apr_datum_t key, apr_datum_t *pvalue) +{ + apr_status_t status = apr_dbm_fetch(db->file, key, pvalue); + + return dav_fs_dbm_error(db, NULL, status); +} + +dav_error * dav_dbm_store(dav_db *db, apr_datum_t key, apr_datum_t value) +{ + apr_status_t status = apr_dbm_store(db->file, key, value); + + return dav_fs_dbm_error(db, NULL, status); +} + +dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key) +{ + apr_status_t status = apr_dbm_delete(db->file, key); + + return dav_fs_dbm_error(db, NULL, status); +} + +int dav_dbm_exists(dav_db *db, apr_datum_t key) +{ + return apr_dbm_exists(db->file, key); +} + +static dav_error * dav_dbm_firstkey(dav_db *db, apr_datum_t *pkey) +{ + apr_status_t status = apr_dbm_firstkey(db->file, pkey); + + return dav_fs_dbm_error(db, NULL, status); +} + +static dav_error * dav_dbm_nextkey(dav_db *db, apr_datum_t *pkey) +{ + apr_status_t status = apr_dbm_nextkey(db->file, pkey); + + return dav_fs_dbm_error(db, NULL, status); +} + +void dav_dbm_freedatum(dav_db *db, apr_datum_t data) +{ + apr_dbm_freedatum(db->file, data); +} + +/* ------------------------------------------------------------------------- + * + * PROPERTY DATABASE FUNCTIONS + */ + + +#define DAV_GDBM_NS_KEY "METADATA" +#define DAV_GDBM_NS_KEY_LEN 8 + +typedef struct { + unsigned char major; +#define DAV_DBVSN_MAJOR 4 + /* + ** V4 -- 0.9.9 .. + ** Prior versions could have keys or values with invalid + ** namespace prefixes as a result of the xmlns="" form not + ** resetting the default namespace to be "no namespace". The + ** namespace would be set to "" which is invalid; it should + ** be set to "no namespace". + ** + ** V3 -- 0.9.8 + ** Prior versions could have values with invalid namespace + ** prefixes due to an incorrect mapping of input to propdb + ** namespace indices. Version bumped to obsolete the old + ** values. + ** + ** V2 -- 0.9.7 + ** This introduced the xml:lang value into the property value's + ** record in the propdb. + ** + ** V1 -- .. 0.9.6 + ** Initial version. + */ + + + unsigned char minor; +#define DAV_DBVSN_MINOR 0 + + short ns_count; + +} dav_propdb_metadata; + +struct dav_deadprop_rollback { + apr_datum_t key; + apr_datum_t value; +}; + +struct dav_namespace_map { + int *ns_map; +}; + +/* +** Internal function to build a key +** +** WARNING: returns a pointer to a "static" buffer holding the key. The +** value must be copied or no longer used if this function is +** called again. +*/ +static apr_datum_t dav_build_key(dav_db *db, const dav_prop_name *name) +{ + char nsbuf[20]; + apr_size_t l_ns, l_name = strlen(name->name); + apr_datum_t key = { 0 }; + + /* + * Convert namespace ID to a string. "no namespace" is an empty string, + * so the keys will have the form ":name". Otherwise, the keys will + * have the form "#:name". + */ + if (*name->ns == '\0') { + nsbuf[0] = '\0'; + l_ns = 0; + } + else { + int ns_id = (int)apr_hash_get(db->uri_index, name->ns, + APR_HASH_KEY_STRING); + + + if (ns_id == 0) { + /* the namespace was not found(!) */ + return key; /* zeroed */ + } + + l_ns = sprintf(nsbuf, "%d", ns_id - 1); + } + + /* assemble: #:name */ + dav_set_bufsize(db->pool, &db->wb_key, l_ns + 1 + l_name + 1); + memcpy(db->wb_key.buf, nsbuf, l_ns); + db->wb_key.buf[l_ns] = ':'; + memcpy(&db->wb_key.buf[l_ns + 1], name->name, l_name + 1); + + /* build the database key */ + key.dsize = l_ns + 1 + l_name + 1; + key.dptr = db->wb_key.buf; + + return key; +} + +static void dav_append_prop(apr_pool_t *pool, + const char *name, const char *value, + apr_text_header *phdr) +{ + const char *s; + const char *lang = value; + + /* skip past the xml:lang value */ + value += strlen(lang) + 1; + + if (*value == '\0') { + /* the property is an empty value */ + if (*name == ':') { + /* "no namespace" case */ + s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name+1); + } + else { + s = apr_psprintf(pool, "" DEBUG_CR, name); + } + } + else if (*lang != '\0') { + if (*name == ':') { + /* "no namespace" case */ + s = apr_psprintf(pool, "<%s xml:lang=\"%s\">%s" DEBUG_CR, + name+1, lang, value, name+1); + } + else { + s = apr_psprintf(pool, "%s" DEBUG_CR, + name, lang, value, name); + } + } + else if (*name == ':') { + /* "no namespace" case */ + s = apr_psprintf(pool, "<%s>%s" DEBUG_CR, name+1, value, name+1); + } + else { + s = apr_psprintf(pool, "%s" DEBUG_CR, name, value, name); + } + + apr_text_append(pool, phdr, s); +} + +static dav_error * dav_propdb_open(apr_pool_t *pool, + const dav_resource *resource, int ro, + dav_db **pdb) +{ + dav_db *db; + dav_error *err; + apr_datum_t key; + apr_datum_t value = { 0 }; + + *pdb = NULL; + + /* + ** Return if an error occurred, or there is no database. + ** + ** NOTE: db could be NULL if we attempted to open a readonly + ** database that doesn't exist. If we require read/write + ** access, then a database was created and opened. + */ + if ((err = dav_dbm_open(pool, resource, ro, &db)) != NULL + || db == NULL) + return err; + + db->uri_index = apr_hash_make(pool); + + key.dptr = DAV_GDBM_NS_KEY; + key.dsize = DAV_GDBM_NS_KEY_LEN; + if ((err = dav_dbm_fetch(db, key, &value)) != NULL) { + /* ### push a higher-level description? */ + return err; + } + + if (value.dptr == NULL) { + dav_propdb_metadata m = { + DAV_DBVSN_MAJOR, DAV_DBVSN_MINOR, 0 + }; + + /* + ** If there is no METADATA key, then the database may be + ** from versions 0.9.0 .. 0.9.4 (which would be incompatible). + ** These can be identified by the presence of an NS_TABLE entry. + */ + key.dptr = "NS_TABLE"; + key.dsize = 8; + if (dav_dbm_exists(db, key)) { + dav_dbm_close(db); + + /* call it a major version error */ + return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_PROP_BAD_MAJOR, + "Prop database has the wrong major " + "version number and cannot be used."); + } + + /* initialize a new metadata structure */ + dav_set_bufsize(pool, &db->ns_table, sizeof(m)); + memcpy(db->ns_table.buf, &m, sizeof(m)); + } + else { + dav_propdb_metadata m; + int ns; + const char *uri; + + dav_set_bufsize(pool, &db->ns_table, value.dsize); + memcpy(db->ns_table.buf, value.dptr, value.dsize); + + memcpy(&m, value.dptr, sizeof(m)); + if (m.major != DAV_DBVSN_MAJOR) { + dav_dbm_close(db); + + return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_PROP_BAD_MAJOR, + "Prop database has the wrong major " + "version number and cannot be used."); + } + db->version = m.minor; + db->ns_count = ntohs(m.ns_count); + + dav_dbm_freedatum(db, value); + + /* create db->uri_index */ + for (ns = 0, uri = db->ns_table.buf + sizeof(dav_propdb_metadata); + ns++ < db->ns_count; + uri += strlen(uri) + 1) { + + /* we must copy the key, in case ns_table.buf moves */ + apr_hash_set(db->uri_index, + apr_pstrdup(pool, uri), APR_HASH_KEY_STRING, + (void *)ns); + } + } + + *pdb = db; + return NULL; +} + +static void dav_propdb_close(dav_db *db) +{ + + if (db->ns_table_dirty) { + dav_propdb_metadata m; + apr_datum_t key; + apr_datum_t value; + dav_error *err; + + key.dptr = DAV_GDBM_NS_KEY; + key.dsize = DAV_GDBM_NS_KEY_LEN; + + value.dptr = db->ns_table.buf; + value.dsize = db->ns_table.cur_len; + + /* fill in the metadata that we store into the prop db. */ + m.major = DAV_DBVSN_MAJOR; + m.minor = db->version; /* ### keep current minor version? */ + m.ns_count = htons(db->ns_count); + + memcpy(db->ns_table.buf, &m, sizeof(m)); + + err = dav_dbm_store(db, key, value); + /* ### what to do with the error? */ + } + + dav_dbm_close(db); +} + +static dav_error * dav_propdb_define_namespaces(dav_db *db, dav_xmlns_info *xi) +{ + int ns; + const char *uri = db->ns_table.buf + sizeof(dav_propdb_metadata); + + /* within the prop values, we use "ns%d" for prefixes... register them */ + for (ns = 0; ns < db->ns_count; ++ns, uri += strlen(uri) + 1) { + + /* Empty URIs signify the empty namespace. These do not get a + namespace prefix. when we generate the value, we will simply + leave off the prefix, which is defined by mod_dav to be the + empty namespace. */ + if (*uri == '\0') + continue; + + /* ns_table.buf can move, so copy its value (we want the values to + last as long as the provided dav_xmlns_info). */ + dav_xmlns_add(xi, + apr_psprintf(xi->pool, "ns%d", ns), + apr_pstrdup(xi->pool, uri)); + } + + return NULL; +} + +static dav_error * dav_propdb_output_value(dav_db *db, + const dav_prop_name *name, + dav_xmlns_info *xi, + apr_text_header *phdr, + int *found) +{ + apr_datum_t key = dav_build_key(db, name); + apr_datum_t value; + dav_error *err; + + if ((err = dav_dbm_fetch(db, key, &value)) != NULL) + return err; + if (value.dptr == NULL) { + *found = 0; + return NULL; + } + *found = 1; + + dav_append_prop(db->pool, key.dptr, value.dptr, phdr); + + dav_dbm_freedatum(db, value); + + return NULL; +} + +static dav_error * dav_propdb_map_namespaces( + dav_db *db, + const apr_array_header_t *namespaces, + dav_namespace_map **mapping) +{ + dav_namespace_map *m = apr_palloc(db->pool, sizeof(*m)); + int i; + int *pmap; + const char **puri; + + /* + ** Iterate over the provided namespaces. If a namespace already appears + ** in our internal map of URI -> ns_id, then store that in the map. If + ** we don't know the namespace yet, then add it to the map and to our + ** table of known namespaces. + */ + m->ns_map = pmap = apr_palloc(db->pool, namespaces->nelts * sizeof(*pmap)); + for (i = namespaces->nelts, puri = (const char **)namespaces->elts; + i-- > 0; + ++puri, ++pmap) { + + const char *uri = *puri; + apr_size_t uri_len = strlen(uri); + int ns_id = (int)apr_hash_get(db->uri_index, uri, uri_len); + + if (ns_id == 0) { + dav_check_bufsize(db->pool, &db->ns_table, uri_len + 1); + memcpy(db->ns_table.buf + db->ns_table.cur_len, uri, uri_len + 1); + db->ns_table.cur_len += uri_len + 1; + + /* copy the uri in case the passed-in namespaces changes in + some way. */ + apr_hash_set(db->uri_index, apr_pstrdup(db->pool, uri), uri_len, + (void *)(db->ns_count + 1)); + + db->ns_table_dirty = 1; + + *pmap = db->ns_count++; + } + else { + *pmap = ns_id - 1; + } + } + + *mapping = m; + return NULL; +} + +static dav_error * dav_propdb_store(dav_db *db, const dav_prop_name *name, + const apr_xml_elem *elem, + dav_namespace_map *mapping) +{ + apr_datum_t key = dav_build_key(db, name); + apr_datum_t value; + + /* Note: mapping->ns_map was set up in dav_propdb_map_namespaces() */ + + /* ### use a db- subpool for these values? clear on exit? */ + + /* quote all the values in the element */ + /* ### be nice to do this without affecting the element itself */ + /* ### of course, the cast indicates Badness is occurring here */ + apr_xml_quote_elem(db->pool, (apr_xml_elem *)elem); + + /* generate a text blob for the xml:lang plus the contents */ + apr_xml_to_text(db->pool, elem, APR_XML_X2T_LANG_INNER, NULL, + mapping->ns_map, + (const char **)&value.dptr, &value.dsize); + + return dav_dbm_store(db, key, value); +} + +static dav_error * dav_propdb_remove(dav_db *db, const dav_prop_name *name) +{ + apr_datum_t key = dav_build_key(db, name); + return dav_dbm_delete(db, key); +} + +static int dav_propdb_exists(dav_db *db, const dav_prop_name *name) +{ + apr_datum_t key = dav_build_key(db, name); + return dav_dbm_exists(db, key); +} + +static const char *dav_get_ns_table_uri(dav_db *db, int ns_id) +{ + const char *p = db->ns_table.buf + sizeof(dav_propdb_metadata); + + while (ns_id--) + p += strlen(p) + 1; + + return p; +} + +static void dav_set_name(dav_db *db, dav_prop_name *pname) +{ + const char *s = db->iter.dptr; + + if (s == NULL) { + pname->ns = pname->name = NULL; + } + else if (*s == ':') { + pname->ns = ""; + pname->name = s + 1; + } + else { + int id = atoi(s); + + pname->ns = dav_get_ns_table_uri(db, id); + if (s[1] == ':') { + pname->name = s + 2; + } + else { + pname->name = ap_strchr_c(s + 2, ':') + 1; + } + } +} + +static dav_error * dav_propdb_next_name(dav_db *db, dav_prop_name *pname) +{ + dav_error *err; + + /* free the previous key. note: if the loop is aborted, then the DBM + will toss the key (via pool cleanup) */ + if (db->iter.dptr != NULL) + dav_dbm_freedatum(db, db->iter); + + if ((err = dav_dbm_nextkey(db, &db->iter)) != NULL) + return err; + + /* skip past the METADATA key */ + if (db->iter.dptr != NULL && *db->iter.dptr == 'M') + return dav_propdb_next_name(db, pname); + + dav_set_name(db, pname); + return NULL; +} + +static dav_error * dav_propdb_first_name(dav_db *db, dav_prop_name *pname) +{ + dav_error *err; + + if ((err = dav_dbm_firstkey(db, &db->iter)) != NULL) + return err; + + /* skip past the METADATA key */ + if (db->iter.dptr != NULL && *db->iter.dptr == 'M') + return dav_propdb_next_name(db, pname); + + dav_set_name(db, pname); + return NULL; +} + +static dav_error * dav_propdb_get_rollback(dav_db *db, + const dav_prop_name *name, + dav_deadprop_rollback **prollback) +{ + dav_deadprop_rollback *rb = apr_pcalloc(db->pool, sizeof(*rb)); + apr_datum_t key; + apr_datum_t value; + dav_error *err; + + key = dav_build_key(db, name); + rb->key.dptr = apr_pstrdup(db->pool, key.dptr); + rb->key.dsize = key.dsize; + + if ((err = dav_dbm_fetch(db, key, &value)) != NULL) + return err; + if (value.dptr != NULL) { + rb->value.dptr = apr_pmemdup(db->pool, value.dptr, value.dsize); + rb->value.dsize = value.dsize; + } + + *prollback = rb; + return NULL; +} + +static dav_error * dav_propdb_apply_rollback(dav_db *db, + dav_deadprop_rollback *rollback) +{ + if (rollback->value.dptr == NULL) { + /* don't fail if the thing isn't really there. */ + (void) dav_dbm_delete(db, rollback->key); + return NULL; + } + + return dav_dbm_store(db, rollback->key, rollback->value); +} + +const dav_hooks_db dav_hooks_db_dbm = +{ + dav_propdb_open, + dav_propdb_close, + dav_propdb_define_namespaces, + dav_propdb_output_value, + dav_propdb_map_namespaces, + dav_propdb_store, + dav_propdb_remove, + dav_propdb_exists, + dav_propdb_first_name, + dav_propdb_next_name, + dav_propdb_get_rollback, + dav_propdb_apply_rollback, + + NULL /* ctx */ +}; diff --git a/trunk/modules/dav/fs/lock.c b/trunk/modules/dav/fs/lock.c new file mode 100644 index 0000000000..c3f071c5b8 --- /dev/null +++ b/trunk/modules/dav/fs/lock.c @@ -0,0 +1,1517 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV filesystem lock implementation +*/ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_uuid.h" + +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_log.h" + +#include "mod_dav.h" +#include "repos.h" + + +/* --------------------------------------------------------------- +** +** Lock database primitives +** +*/ + +/* +** LOCK DATABASES +** +** Lockdiscovery information is stored in the single lock database specified +** by the DAVLockDB directive. Information about this db is stored in the +** global server configuration. +** +** KEY +** +** The database is keyed by a key_type unsigned char (DAV_TYPE_INODE or +** DAV_TYPE_FNAME) followed by inode and device number if possible, +** otherwise full path (in the case of Win32 or lock-null resources). +** +** VALUE +** +** The value consists of a list of elements. +** DIRECT LOCK: [char (DAV_LOCK_DIRECT), +** char (dav_lock_scope), +** char (dav_lock_type), +** int depth, +** time_t expires, +** apr_uuid_t locktoken, +** char[] owner, +** char[] auth_user] +** +** INDIRECT LOCK: [char (DAV_LOCK_INDIRECT), +** apr_uuid_t locktoken, +** time_t expires, +** apr_size_t key_size, +** char[] key] +** The key is to the collection lock that resulted in this indirect lock +*/ + +#define DAV_TRUE 1 +#define DAV_FALSE 0 + +#define DAV_CREATE_LIST 23 +#define DAV_APPEND_LIST 24 + +/* Stored lock_discovery prefix */ +#define DAV_LOCK_DIRECT 1 +#define DAV_LOCK_INDIRECT 2 + +#define DAV_TYPE_INODE 10 +#define DAV_TYPE_FNAME 11 + + +/* ack. forward declare. */ +static dav_error * dav_fs_remove_locknull_member(apr_pool_t *p, + const char *filename, + dav_buffer *pbuf); + +/* +** Use the opaquelock scheme for locktokens +*/ +struct dav_locktoken { + apr_uuid_t uuid; +}; +#define dav_compare_locktoken(plt1, plt2) \ + memcmp(&(plt1)->uuid, &(plt2)->uuid, sizeof((plt1)->uuid)) + + +/* ################################################################# +** ### keep these structures (internal) or move fully to dav_lock? +*/ + +/* +** We need to reliably size the fixed-length portion of +** dav_lock_discovery; best to separate it into another +** struct for a convenient sizeof, unless we pack lock_discovery. +*/ +typedef struct dav_lock_discovery_fixed +{ + char scope; + char type; + int depth; + time_t timeout; +} dav_lock_discovery_fixed; + +typedef struct dav_lock_discovery +{ + struct dav_lock_discovery_fixed f; + + dav_locktoken *locktoken; + const char *owner; /* owner field from activelock */ + const char *auth_user; /* authenticated user who created the lock */ + struct dav_lock_discovery *next; +} dav_lock_discovery; + +/* Indirect locks represent locks inherited from containing collections. + * They reference the lock token for the collection the lock is + * inherited from. A lock provider may also define a key to the + * inherited lock, for fast datbase lookup. The key is opaque outside + * the lock provider. + */ +typedef struct dav_lock_indirect +{ + dav_locktoken *locktoken; + apr_datum_t key; + struct dav_lock_indirect *next; + time_t timeout; +} dav_lock_indirect; + +/* ################################################################# */ + + +/* +** Stored direct lock info - full lock_discovery length: +** prefix + Fixed length + lock token + 2 strings + 2 nulls (one for each string) +*/ +#define dav_size_direct(a) (1 + sizeof(dav_lock_discovery_fixed) \ + + sizeof(apr_uuid_t) \ + + ((a)->owner ? strlen((a)->owner) : 0) \ + + ((a)->auth_user ? strlen((a)->auth_user) : 0) \ + + 2) + +/* Stored indirect lock info - lock token and apr_datum_t */ +#define dav_size_indirect(a) (1 + sizeof(apr_uuid_t) \ + + sizeof(time_t) \ + + sizeof((a)->key.dsize) + (a)->key.dsize) + +/* +** The lockdb structure. +** +** The field may be NULL, meaning one of two things: +** 1) That we have not actually opened the underlying database (yet). The +** field should be false. +** 2) We opened it readonly and it wasn't present. +** +** The delayed opening (determined by ) makes creating a lockdb +** quick, while deferring the underlying I/O until it is actually required. +** +** We export the notion of a lockdb, but hide the details of it. Most +** implementations will use a database of some kind, but it is certainly +** possible that alternatives could be used. +*/ +struct dav_lockdb_private +{ + request_rec *r; /* for accessing the uuid state */ + apr_pool_t *pool; /* a pool to use */ + const char *lockdb_path; /* where is the lock database? */ + + int opened; /* we opened the database */ + dav_db *db; /* if non-NULL, the lock database */ +}; +typedef struct +{ + dav_lockdb pub; + dav_lockdb_private priv; +} dav_lockdb_combined; + +/* +** The private part of the lock structure. +*/ +struct dav_lock_private +{ + apr_datum_t key; /* key into the lock database */ +}; +typedef struct +{ + dav_lock pub; + dav_lock_private priv; + dav_locktoken token; +} dav_lock_combined; + +/* +** This must be forward-declared so the open_lockdb function can use it. +*/ +extern const dav_hooks_locks dav_hooks_locks_fs; + + +/* internal function for creating locks */ +static dav_lock *dav_fs_alloc_lock(dav_lockdb *lockdb, apr_datum_t key, + const dav_locktoken *locktoken) +{ + dav_lock_combined *comb; + + comb = apr_pcalloc(lockdb->info->pool, sizeof(*comb)); + comb->pub.rectype = DAV_LOCKREC_DIRECT; + comb->pub.info = &comb->priv; + comb->priv.key = key; + + if (locktoken == NULL) { + comb->pub.locktoken = &comb->token; + apr_uuid_get(&comb->token.uuid); + } + else { + comb->pub.locktoken = locktoken; + } + + return &comb->pub; +} + +/* +** dav_fs_parse_locktoken +** +** Parse an opaquelocktoken URI into a locktoken. +*/ +static dav_error * dav_fs_parse_locktoken( + apr_pool_t *p, + const char *char_token, + dav_locktoken **locktoken_p) +{ + dav_locktoken *locktoken; + + if (ap_strstr_c(char_token, "opaquelocktoken:") != char_token) { + return dav_new_error(p, + HTTP_BAD_REQUEST, DAV_ERR_LOCK_UNK_STATE_TOKEN, + "The lock token uses an unknown State-token " + "format and could not be parsed."); + } + char_token += 16; + + locktoken = apr_pcalloc(p, sizeof(*locktoken)); + if (apr_uuid_parse(&locktoken->uuid, char_token)) { + return dav_new_error(p, HTTP_BAD_REQUEST, DAV_ERR_LOCK_PARSE_TOKEN, + "The opaquelocktoken has an incorrect format " + "and could not be parsed."); + } + + *locktoken_p = locktoken; + return NULL; +} + +/* +** dav_fs_format_locktoken +** +** Generate the URI for a locktoken +*/ +static const char *dav_fs_format_locktoken( + apr_pool_t *p, + const dav_locktoken *locktoken) +{ + char buf[APR_UUID_FORMATTED_LENGTH + 1]; + + apr_uuid_format(buf, &locktoken->uuid); + return apr_pstrcat(p, "opaquelocktoken:", buf, NULL); +} + +/* +** dav_fs_compare_locktoken +** +** Determine whether two locktokens are the same +*/ +static int dav_fs_compare_locktoken( + const dav_locktoken *lt1, + const dav_locktoken *lt2) +{ + return dav_compare_locktoken(lt1, lt2); +} + +/* +** dav_fs_really_open_lockdb: +** +** If the database hasn't been opened yet, then open the thing. +*/ +static dav_error * dav_fs_really_open_lockdb(dav_lockdb *lockdb) +{ + dav_error *err; + + if (lockdb->info->opened) + return NULL; + + err = dav_dbm_open_direct(lockdb->info->pool, + lockdb->info->lockdb_path, + lockdb->ro, + &lockdb->info->db); + if (err != NULL) { + return dav_push_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_OPENDB, + "Could not open the lock database.", + err); + } + + /* all right. it is opened now. */ + lockdb->info->opened = 1; + + return NULL; +} + +/* +** dav_fs_open_lockdb: +** +** "open" the lock database, as specified in the global server configuration. +** If force is TRUE, then the database is opened now, rather than lazily. +** +** Note that only one can be open read/write. +*/ +static dav_error * dav_fs_open_lockdb(request_rec *r, int ro, int force, + dav_lockdb **lockdb) +{ + dav_lockdb_combined *comb; + + comb = apr_pcalloc(r->pool, sizeof(*comb)); + comb->pub.hooks = &dav_hooks_locks_fs; + comb->pub.ro = ro; + comb->pub.info = &comb->priv; + comb->priv.r = r; + comb->priv.pool = r->pool; + + comb->priv.lockdb_path = dav_get_lockdb_path(r); + if (comb->priv.lockdb_path == NULL) { + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_NO_DB, + "A lock database was not specified with the " + "DAVLockDB directive. One must be specified " + "to use the locking functionality."); + } + + /* done initializing. return it. */ + *lockdb = &comb->pub; + + if (force) { + /* ### add a higher-level comment? */ + return dav_fs_really_open_lockdb(*lockdb); + } + + return NULL; +} + +/* +** dav_fs_close_lockdb: +** +** Close it. Duh. +*/ +static void dav_fs_close_lockdb(dav_lockdb *lockdb) +{ + if (lockdb->info->db != NULL) + dav_dbm_close(lockdb->info->db); +} + +/* +** dav_fs_build_fname_key +** +** Given a pathname, build a DAV_TYPE_FNAME lock database key. +*/ +static apr_datum_t dav_fs_build_fname_key(apr_pool_t *p, const char *pathname) +{ + apr_datum_t key; + + /* ### does this allocation have a proper lifetime? need to check */ + /* ### can we use a buffer for this? */ + + /* size is TYPE + pathname + null */ + key.dsize = strlen(pathname) + 2; + key.dptr = apr_palloc(p, key.dsize); + *key.dptr = DAV_TYPE_FNAME; + memcpy(key.dptr + 1, pathname, key.dsize - 1); + if (key.dptr[key.dsize - 2] == '/') + key.dptr[--key.dsize - 1] = '\0'; + return key; +} + +/* +** dav_fs_build_key: Given a resource, return a apr_datum_t key +** to look up lock information for this file. +** +** (inode/dev not supported or file is lock-null): +** apr_datum_t->dvalue = full path +** +** (inode/dev supported and file exists ): +** apr_datum_t->dvalue = inode, dev +*/ +static apr_datum_t dav_fs_build_key(apr_pool_t *p, + const dav_resource *resource) +{ + const char *file = dav_fs_pathname(resource); + apr_datum_t key; + apr_finfo_t finfo; + apr_status_t rv; + + /* ### use lstat() ?? */ + /* + * XXX: What for platforms with no IDENT (dev/inode)? + */ + rv = apr_stat(&finfo, file, APR_FINFO_IDENT, p); + if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE) + && ((finfo.valid & APR_FINFO_IDENT) == APR_FINFO_IDENT)) + { + /* ### can we use a buffer for this? */ + key.dsize = 1 + sizeof(finfo.inode) + sizeof(finfo.device); + key.dptr = apr_palloc(p, key.dsize); + *key.dptr = DAV_TYPE_INODE; + memcpy(key.dptr + 1, &finfo.inode, sizeof(finfo.inode)); + memcpy(key.dptr + 1 + sizeof(finfo.inode), &finfo.device, + sizeof(finfo.device)); + + return key; + } + + return dav_fs_build_fname_key(p, file); +} + +/* +** dav_fs_lock_expired: return 1 (true) if the given timeout is in the past +** or present (the lock has expired), or 0 (false) if in the future +** (the lock has not yet expired). +*/ +static int dav_fs_lock_expired(time_t expires) +{ + return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires; +} + +/* +** dav_fs_save_lock_record: Saves the lock information specified in the +** direct and indirect lock lists about path into the lock database. +** If direct and indirect == NULL, the key is removed. +*/ +static dav_error * dav_fs_save_lock_record(dav_lockdb *lockdb, apr_datum_t key, + dav_lock_discovery *direct, + dav_lock_indirect *indirect) +{ + dav_error *err; + apr_datum_t val = { 0 }; + char *ptr; + dav_lock_discovery *dp = direct; + dav_lock_indirect *ip = indirect; + +#if DAV_DEBUG + if (lockdb->ro) { + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: the lockdb was opened " + "readonly, but an attempt to save locks was " + "performed."); + } +#endif + + if ((err = dav_fs_really_open_lockdb(lockdb)) != NULL) { + /* ### add a higher-level error? */ + return err; + } + + /* If nothing to save, delete key */ + if (dp == NULL && ip == NULL) { + /* don't fail if the key is not present */ + /* ### but what about other errors? */ + (void) dav_dbm_delete(lockdb->info->db, key); + return NULL; + } + + while(dp) { + val.dsize += dav_size_direct(dp); + dp = dp->next; + } + while(ip) { + val.dsize += dav_size_indirect(ip); + ip = ip->next; + } + + /* ### can this be apr_palloc() ? */ + /* ### hmmm.... investigate the use of a buffer here */ + ptr = val.dptr = apr_pcalloc(lockdb->info->pool, val.dsize); + dp = direct; + ip = indirect; + + while(dp) { + *ptr++ = DAV_LOCK_DIRECT; /* Direct lock - lock_discovery struct follows */ + memcpy(ptr, dp, sizeof(dp->f)); /* Fixed portion of struct */ + ptr += sizeof(dp->f); + memcpy(ptr, dp->locktoken, sizeof(*dp->locktoken)); + ptr += sizeof(*dp->locktoken); + if (dp->owner == NULL) { + *ptr++ = '\0'; + } + else { + memcpy(ptr, dp->owner, strlen(dp->owner) + 1); + ptr += strlen(dp->owner) + 1; + } + if (dp->auth_user == NULL) { + *ptr++ = '\0'; + } + else { + memcpy(ptr, dp->auth_user, strlen(dp->auth_user) + 1); + ptr += strlen(dp->auth_user) + 1; + } + + dp = dp->next; + } + + while(ip) { + *ptr++ = DAV_LOCK_INDIRECT; /* Indirect lock prefix */ + memcpy(ptr, ip->locktoken, sizeof(*ip->locktoken)); /* Locktoken */ + ptr += sizeof(*ip->locktoken); + memcpy(ptr, &ip->timeout, sizeof(ip->timeout)); /* Expire time */ + ptr += sizeof(ip->timeout); + memcpy(ptr, &ip->key.dsize, sizeof(ip->key.dsize)); /* Size of key */ + ptr += sizeof(ip->key.dsize); + memcpy(ptr, ip->key.dptr, ip->key.dsize); /* Key data */ + ptr += ip->key.dsize; + ip = ip->next; + } + + if ((err = dav_dbm_store(lockdb->info->db, key, val)) != NULL) { + /* ### more details? add an error_id? */ + return dav_push_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_SAVE_LOCK, + "Could not save lock information.", + err); + } + + return NULL; +} + +/* +** dav_load_lock_record: Reads lock information about key from lock db; +** creates linked lists of the direct and indirect locks. +** +** If add_method = DAV_APPEND_LIST, the result will be appended to the +** head of the direct and indirect lists supplied. +** +** Passive lock removal: If lock has timed out, it will not be returned. +** ### How much "logging" does RFC 2518 require? +*/ +static dav_error * dav_fs_load_lock_record(dav_lockdb *lockdb, apr_datum_t key, + int add_method, + dav_lock_discovery **direct, + dav_lock_indirect **indirect) +{ + apr_pool_t *p = lockdb->info->pool; + dav_error *err; + apr_size_t offset = 0; + int need_save = DAV_FALSE; + apr_datum_t val = { 0 }; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + dav_buffer buf = { 0 }; + + if (add_method != DAV_APPEND_LIST) { + *direct = NULL; + *indirect = NULL; + } + + if ((err = dav_fs_really_open_lockdb(lockdb)) != NULL) { + /* ### add a higher-level error? */ + return err; + } + + /* + ** If we opened readonly and the db wasn't there, then there are no + ** locks for this resource. Just exit. + */ + if (lockdb->info->db == NULL) + return NULL; + + if ((err = dav_dbm_fetch(lockdb->info->db, key, &val)) != NULL) + return err; + + if (!val.dsize) + return NULL; + + while (offset < val.dsize) { + switch (*(val.dptr + offset++)) { + case DAV_LOCK_DIRECT: + /* Create and fill a dav_lock_discovery structure */ + + dp = apr_pcalloc(p, sizeof(*dp)); + memcpy(dp, val.dptr + offset, sizeof(dp->f)); + offset += sizeof(dp->f); + dp->locktoken = apr_palloc(p, sizeof(*dp->locktoken)); + memcpy(dp->locktoken, val.dptr + offset, sizeof(*dp->locktoken)); + offset += sizeof(*dp->locktoken); + if (*(val.dptr + offset) == '\0') { + ++offset; + } + else { + dp->owner = apr_pstrdup(p, val.dptr + offset); + offset += strlen(dp->owner) + 1; + } + + if (*(val.dptr + offset) == '\0') { + ++offset; + } + else { + dp->auth_user = apr_pstrdup(p, val.dptr + offset); + offset += strlen(dp->auth_user) + 1; + } + + if (!dav_fs_lock_expired(dp->f.timeout)) { + dp->next = *direct; + *direct = dp; + } + else { + need_save = DAV_TRUE; + + /* Remove timed-out locknull fm .locknull list */ + if (*key.dptr == DAV_TYPE_FNAME) { + const char *fname = key.dptr + 1; + apr_finfo_t finfo; + apr_status_t rv; + + /* if we don't see the file, then it's a locknull */ + rv = apr_stat(&finfo, fname, APR_FINFO_MIN | APR_FINFO_LINK, p); + if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) { + if ((err = dav_fs_remove_locknull_member(p, fname, &buf)) != NULL) { + /* ### push a higher-level description? */ + return err; + } + } + } + } + break; + + case DAV_LOCK_INDIRECT: + /* Create and fill a dav_lock_indirect structure */ + + ip = apr_pcalloc(p, sizeof(*ip)); + ip->locktoken = apr_palloc(p, sizeof(*ip->locktoken)); + memcpy(ip->locktoken, val.dptr + offset, sizeof(*ip->locktoken)); + offset += sizeof(*ip->locktoken); + memcpy(&ip->timeout, val.dptr + offset, sizeof(ip->timeout)); + offset += sizeof(ip->timeout); + memcpy(&ip->key.dsize, val.dptr + offset, sizeof(ip->key.dsize)); /* length of datum */ + offset += sizeof(ip->key.dsize); + ip->key.dptr = apr_palloc(p, ip->key.dsize); + memcpy(ip->key.dptr, val.dptr + offset, ip->key.dsize); + offset += ip->key.dsize; + + if (!dav_fs_lock_expired(ip->timeout)) { + ip->next = *indirect; + *indirect = ip; + } + else { + need_save = DAV_TRUE; + /* A locknull resource will never be locked indirectly */ + } + + break; + + default: + dav_dbm_freedatum(lockdb->info->db, val); + + /* ### should use a computed_desc and insert corrupt token data */ + --offset; + return dav_new_error(p, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_CORRUPT_DB, + apr_psprintf(p, + "The lock database was found to " + "be corrupt. offset %" + APR_SIZE_T_FMT ", c=%02x", + offset, val.dptr[offset])); + } + } + + dav_dbm_freedatum(lockdb->info->db, val); + + /* Clean up this record if we found expired locks */ + /* + ** ### shouldn't do this if we've been opened READONLY. elide the + ** ### timed-out locks from the response, but don't save that info back + */ + if (need_save == DAV_TRUE) { + return dav_fs_save_lock_record(lockdb, key, *direct, *indirect); + } + + return NULL; +} + +/* resolve , returning <*direct> */ +static dav_error * dav_fs_resolve(dav_lockdb *lockdb, + dav_lock_indirect *indirect, + dav_lock_discovery **direct, + dav_lock_discovery **ref_dp, + dav_lock_indirect **ref_ip) +{ + dav_error *err; + dav_lock_discovery *dir; + dav_lock_indirect *ind; + + if ((err = dav_fs_load_lock_record(lockdb, indirect->key, + DAV_CREATE_LIST, + &dir, &ind)) != NULL) { + /* ### insert a higher-level description? */ + return err; + } + if (ref_dp != NULL) { + *ref_dp = dir; + *ref_ip = ind; + } + + for (; dir != NULL; dir = dir->next) { + if (!dav_compare_locktoken(indirect->locktoken, dir->locktoken)) { + *direct = dir; + return NULL; + } + } + + /* No match found (but we should have found one!) */ + + /* ### use a different description and/or error ID? */ + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_CORRUPT_DB, + "The lock database was found to be corrupt. " + "An indirect lock's direct lock could not " + "be found."); +} + +/* --------------------------------------------------------------- +** +** Property-related lock functions +** +*/ + +/* +** dav_fs_get_supportedlock: Returns a static string for all supportedlock +** properties. I think we save more returning a static string than +** constructing it every time, though it might look cleaner. +*/ +static const char *dav_fs_get_supportedlock(const dav_resource *resource) +{ + static const char supported[] = DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR; + + return supported; +} + +/* --------------------------------------------------------------- +** +** General lock functions +** +*/ + +/* --------------------------------------------------------------- +** +** Functions dealing with lock-null resources +** +*/ + +/* +** dav_fs_load_locknull_list: Returns a dav_buffer dump of the locknull file +** for the given directory. +*/ +static dav_error * dav_fs_load_locknull_list(apr_pool_t *p, const char *dirpath, + dav_buffer *pbuf) +{ + apr_finfo_t finfo; + apr_file_t *file = NULL; + dav_error *err = NULL; + apr_size_t amt; + apr_status_t rv; + + dav_buffer_init(p, pbuf, dirpath); + + if (pbuf->buf[pbuf->cur_len - 1] == '/') + pbuf->buf[--pbuf->cur_len] = '\0'; + + dav_buffer_place(p, pbuf, "/" DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE); + + /* reset this in case we leave w/o reading into the buffer */ + pbuf->cur_len = 0; + + if (apr_file_open(&file, pbuf->buf, APR_READ | APR_BINARY, APR_OS_DEFAULT, + p) != APR_SUCCESS) { + return NULL; + } + + rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, file); + if (rv != APR_SUCCESS) { + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Opened but could not stat file %s", + pbuf->buf)); + goto loaderror; + } + + if (finfo.size != (apr_size_t)finfo.size) { + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Opened but rejected huge file %s", + pbuf->buf)); + goto loaderror; + } + + amt = (apr_size_t)finfo.size; + dav_set_bufsize(p, pbuf, amt); + if (apr_file_read(file, pbuf->buf, &amt) != APR_SUCCESS + || amt != finfo.size) { + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Failure reading locknull file " + "for %s", dirpath)); + + /* just in case the caller disregards the returned error */ + pbuf->cur_len = 0; + goto loaderror; + } + + loaderror: + apr_file_close(file); + return err; +} + +/* +** dav_fs_save_locknull_list: Saves contents of pbuf into the +** locknull file for dirpath. +*/ +static dav_error * dav_fs_save_locknull_list(apr_pool_t *p, const char *dirpath, + dav_buffer *pbuf) +{ + const char *pathname; + apr_file_t *file = NULL; + dav_error *err = NULL; + apr_size_t amt; + + if (pbuf->buf == NULL) + return NULL; + + dav_fs_ensure_state_dir(p, dirpath); + pathname = apr_pstrcat(p, + dirpath, + dirpath[strlen(dirpath) - 1] == '/' ? "" : "/", + DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE, + NULL); + + if (pbuf->cur_len == 0) { + /* delete the file if cur_len == 0 */ + if (apr_file_remove(pathname, p) != 0) { + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Error removing %s", pathname)); + } + return NULL; + } + + if (apr_file_open(&file, pathname, + APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY, + APR_OS_DEFAULT, p) != APR_SUCCESS) { + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Error opening %s for writing", + pathname)); + } + + amt = pbuf->cur_len; + if (apr_file_write(file, pbuf->buf, &amt) != APR_SUCCESS + || amt != pbuf->cur_len) { + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(p, + "Error writing %" APR_SIZE_T_FMT + " bytes to %s", + pbuf->cur_len, pathname)); + } + + apr_file_close(file); + return err; +} + +/* +** dav_fs_remove_locknull_member: Removes filename from the locknull list +** for directory path. +*/ +static dav_error * dav_fs_remove_locknull_member(apr_pool_t *p, + const char *filename, + dav_buffer *pbuf) +{ + dav_error *err; + apr_size_t len; + apr_size_t scanlen; + char *scan; + const char *scanend; + char *dirpath = apr_pstrdup(p, filename); + char *fname = strrchr(dirpath, '/'); + int dirty = 0; + + if (fname != NULL) + *fname++ = '\0'; + else + fname = dirpath; + len = strlen(fname) + 1; + + if ((err = dav_fs_load_locknull_list(p, dirpath, pbuf)) != NULL) { + /* ### add a higher level description? */ + return err; + } + + for (scan = pbuf->buf, scanend = scan + pbuf->cur_len; + scan < scanend; + scan += scanlen) { + scanlen = strlen(scan) + 1; + if (len == scanlen && memcmp(fname, scan, scanlen) == 0) { + pbuf->cur_len -= scanlen; + memmove(scan, scan + scanlen, scanend - (scan + scanlen)); + dirty = 1; + break; + } + } + + if (dirty) { + if ((err = dav_fs_save_locknull_list(p, dirpath, pbuf)) != NULL) { + /* ### add a higher level description? */ + return err; + } + } + + return NULL; +} + +/* Note: used by dav_fs_repos.c */ +dav_error * dav_fs_get_locknull_members( + const dav_resource *resource, + dav_buffer *pbuf) +{ + const char *dirpath; + + /* ### should test this result value... */ + (void) dav_fs_dir_file_name(resource, &dirpath, NULL); + return dav_fs_load_locknull_list(dav_fs_pool(resource), dirpath, pbuf); +} + +/* ### fold into append_lock? */ +/* ### take an optional buf parameter? */ +static dav_error * dav_fs_add_locknull_state( + dav_lockdb *lockdb, + const dav_resource *resource) +{ + dav_buffer buf = { 0 }; + apr_pool_t *p = lockdb->info->pool; + const char *dirpath; + const char *fname; + dav_error *err; + + /* ### should test this result value... */ + (void) dav_fs_dir_file_name(resource, &dirpath, &fname); + + if ((err = dav_fs_load_locknull_list(p, dirpath, &buf)) != NULL) { + return dav_push_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not load .locknull file.", err); + } + + dav_buffer_append(p, &buf, fname); + buf.cur_len++; /* we want the null-term here */ + + if ((err = dav_fs_save_locknull_list(p, dirpath, &buf)) != NULL) { + return dav_push_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not save .locknull file.", err); + } + + return NULL; +} + +/* +** dav_fs_remove_locknull_state: Given a request, check to see if r->filename +** is/was a lock-null resource. If so, return it to an existant state. +** +** ### this function is broken... it doesn't check! +** +** In this implementation, this involves two things: +** (a) remove it from the list in the appropriate .DAV/locknull file +** (b) on *nix, convert the key from a filename to an inode. +*/ +static dav_error * dav_fs_remove_locknull_state( + dav_lockdb *lockdb, + const dav_resource *resource) +{ + dav_buffer buf = { 0 }; + dav_error *err; + apr_pool_t *p = lockdb->info->pool; + const char *pathname = dav_fs_pathname(resource); + + if ((err = dav_fs_remove_locknull_member(p, pathname, &buf)) != NULL) { + /* ### add a higher-level description? */ + return err; + } + + { + dav_lock_discovery *ld; + dav_lock_indirect *id; + apr_datum_t key; + + /* + ** Fetch the lock(s) that made the resource lock-null. Remove + ** them under the filename key. Obtain the new inode key, and + ** save the same lock information under it. + */ + key = dav_fs_build_fname_key(p, pathname); + if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &ld, &id)) != NULL) { + /* ### insert a higher-level error description */ + return err; + } + + if ((err = dav_fs_save_lock_record(lockdb, key, NULL, NULL)) != NULL) { + /* ### insert a higher-level error description */ + return err; + } + + key = dav_fs_build_key(p, resource); + if ((err = dav_fs_save_lock_record(lockdb, key, ld, id)) != NULL) { + /* ### insert a higher-level error description */ + return err; + } + } + + return NULL; +} + +static dav_error * dav_fs_create_lock(dav_lockdb *lockdb, + const dav_resource *resource, + dav_lock **lock) +{ + apr_datum_t key; + + key = dav_fs_build_key(lockdb->info->pool, resource); + + *lock = dav_fs_alloc_lock(lockdb, + key, + NULL); + + (*lock)->is_locknull = !resource->exists; + + return NULL; +} + +static dav_error * dav_fs_get_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int calltype, + dav_lock **locks) +{ + apr_pool_t *p = lockdb->info->pool; + apr_datum_t key; + dav_error *err; + dav_lock *lock = NULL; + dav_lock *newlock; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + +#if DAV_DEBUG + if (calltype == DAV_GETLOCKS_COMPLETE) { + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: DAV_GETLOCKS_COMPLETE " + "is not yet supported"); + } +#endif + + key = dav_fs_build_key(p, resource); + if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + /* copy all direct locks to the result list */ + for (; dp != NULL; dp = dp->next) { + newlock = dav_fs_alloc_lock(lockdb, key, dp->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp->f.scope; + newlock->type = dp->f.type; + newlock->depth = dp->f.depth; + newlock->timeout = dp->f.timeout; + newlock->owner = dp->owner; + newlock->auth_user = dp->auth_user; + + /* hook into the result list */ + newlock->next = lock; + lock = newlock; + } + + /* copy all the indirect locks to the result list. resolve as needed. */ + for (; ip != NULL; ip = ip->next) { + newlock = dav_fs_alloc_lock(lockdb, ip->key, ip->locktoken); + newlock->is_locknull = !resource->exists; + + if (calltype == DAV_GETLOCKS_RESOLVED) { + if ((err = dav_fs_resolve(lockdb, ip, &dp, NULL, NULL)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + newlock->scope = dp->f.scope; + newlock->type = dp->f.type; + newlock->depth = dp->f.depth; + newlock->timeout = dp->f.timeout; + newlock->owner = dp->owner; + newlock->auth_user = dp->auth_user; + } + else { + /* DAV_GETLOCKS_PARTIAL */ + newlock->rectype = DAV_LOCKREC_INDIRECT_PARTIAL; + } + + /* hook into the result list */ + newlock->next = lock; + lock = newlock; + } + + *locks = lock; + return NULL; +} + +static dav_error * dav_fs_find_lock(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken, + int partial_ok, + dav_lock **lock) +{ + dav_error *err; + apr_datum_t key; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + + *lock = NULL; + + key = dav_fs_build_key(lockdb->info->pool, resource); + if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + for (; dp != NULL; dp = dp->next) { + if (!dav_compare_locktoken(locktoken, dp->locktoken)) { + *lock = dav_fs_alloc_lock(lockdb, key, locktoken); + (*lock)->is_locknull = !resource->exists; + (*lock)->scope = dp->f.scope; + (*lock)->type = dp->f.type; + (*lock)->depth = dp->f.depth; + (*lock)->timeout = dp->f.timeout; + (*lock)->owner = dp->owner; + (*lock)->auth_user = dp->auth_user; + return NULL; + } + } + + for (; ip != NULL; ip = ip->next) { + if (!dav_compare_locktoken(locktoken, ip->locktoken)) { + *lock = dav_fs_alloc_lock(lockdb, ip->key, locktoken); + (*lock)->is_locknull = !resource->exists; + + /* ### nobody uses the resolving right now! */ + if (partial_ok) { + (*lock)->rectype = DAV_LOCKREC_INDIRECT_PARTIAL; + } + else { + (*lock)->rectype = DAV_LOCKREC_INDIRECT; + if ((err = dav_fs_resolve(lockdb, ip, &dp, + NULL, NULL)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + (*lock)->scope = dp->f.scope; + (*lock)->type = dp->f.type; + (*lock)->depth = dp->f.depth; + (*lock)->timeout = dp->f.timeout; + (*lock)->owner = dp->owner; + (*lock)->auth_user = dp->auth_user; + } + return NULL; + } + } + + return NULL; +} + +static dav_error * dav_fs_has_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int *locks_present) +{ + dav_error *err; + apr_datum_t key; + + *locks_present = 0; + + if ((err = dav_fs_really_open_lockdb(lockdb)) != NULL) { + /* ### insert a higher-level error description */ + return err; + } + + /* + ** If we opened readonly and the db wasn't there, then there are no + ** locks for this resource. Just exit. + */ + if (lockdb->info->db == NULL) + return NULL; + + key = dav_fs_build_key(lockdb->info->pool, resource); + + *locks_present = dav_dbm_exists(lockdb->info->db, key); + + return NULL; +} + +static dav_error * dav_fs_append_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int make_indirect, + const dav_lock *lock) +{ + apr_pool_t *p = lockdb->info->pool; + dav_error *err; + dav_lock_indirect *ip; + dav_lock_discovery *dp; + apr_datum_t key; + + key = dav_fs_build_key(lockdb->info->pool, resource); + if ((err = dav_fs_load_lock_record(lockdb, key, 0, &dp, &ip)) != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* + ** ### when we store the lock more directly, we need to update + ** ### lock->rectype and lock->is_locknull + */ + + if (make_indirect) { + for (; lock != NULL; lock = lock->next) { + + /* ### this works for any rectype */ + dav_lock_indirect *newi = apr_pcalloc(p, sizeof(*newi)); + + /* ### shut off the const warning for now */ + newi->locktoken = (dav_locktoken *)lock->locktoken; + newi->timeout = lock->timeout; + newi->key = lock->info->key; + newi->next = ip; + ip = newi; + } + } + else { + for (; lock != NULL; lock = lock->next) { + /* create and link in the right kind of lock */ + + if (lock->rectype == DAV_LOCKREC_DIRECT) { + dav_lock_discovery *newd = apr_pcalloc(p, sizeof(*newd)); + + newd->f.scope = lock->scope; + newd->f.type = lock->type; + newd->f.depth = lock->depth; + newd->f.timeout = lock->timeout; + /* ### shut off the const warning for now */ + newd->locktoken = (dav_locktoken *)lock->locktoken; + newd->owner = lock->owner; + newd->auth_user = lock->auth_user; + newd->next = dp; + dp = newd; + } + else { + /* DAV_LOCKREC_INDIRECT(_PARTIAL) */ + + dav_lock_indirect *newi = apr_pcalloc(p, sizeof(*newi)); + + /* ### shut off the const warning for now */ + newi->locktoken = (dav_locktoken *)lock->locktoken; + newi->key = lock->info->key; + newi->next = ip; + ip = newi; + } + } + } + + if ((err = dav_fs_save_lock_record(lockdb, key, dp, ip)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + /* we have a special list for recording locknull resources */ + /* ### ack! this can add two copies to the locknull list */ + if (!resource->exists + && (err = dav_fs_add_locknull_state(lockdb, resource)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + return NULL; +} + +static dav_error * dav_fs_remove_lock(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken) +{ + dav_error *err; + dav_buffer buf = { 0 }; + dav_lock_discovery *dh = NULL; + dav_lock_indirect *ih = NULL; + apr_datum_t key; + + key = dav_fs_build_key(lockdb->info->pool, resource); + + if (locktoken != NULL) { + dav_lock_discovery *dp; + dav_lock_discovery *dprev = NULL; + dav_lock_indirect *ip; + dav_lock_indirect *iprev = NULL; + + if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dh, &ih)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + for (dp = dh; dp != NULL; dp = dp->next) { + if (dav_compare_locktoken(locktoken, dp->locktoken) == 0) { + if (dprev) + dprev->next = dp->next; + else + dh = dh->next; + } + dprev = dp; + } + + for (ip = ih; ip != NULL; ip = ip->next) { + if (dav_compare_locktoken(locktoken, ip->locktoken) == 0) { + if (iprev) + iprev->next = ip->next; + else + ih = ih->next; + } + iprev = ip; + } + + } + + /* save the modified locks, or remove all locks (dh=ih=NULL). */ + if ((err = dav_fs_save_lock_record(lockdb, key, dh, ih)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + /* + ** If this resource is a locknull resource AND no more locks exist, + ** then remove the locknull member. + ** + ** Note: remove_locknull_state() attempts to convert a locknull member + ** to a real member. In this case, all locks are gone, so the + ** locknull resource returns to the null state (ie. doesn't exist), + ** so there is no need to update the lockdb (and it won't find + ** any because a precondition is that none exist). + */ + if (!resource->exists && dh == NULL && ih == NULL + && (err = dav_fs_remove_locknull_member(lockdb->info->pool, + dav_fs_pathname(resource), + &buf)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + return NULL; +} + +static int dav_fs_do_refresh(dav_lock_discovery *dp, + const dav_locktoken_list *ltl, + time_t new_time) +{ + int dirty = 0; + + for (; ltl != NULL; ltl = ltl->next) { + if (dav_compare_locktoken(dp->locktoken, ltl->locktoken) == 0) + { + dp->f.timeout = new_time; + dirty = 1; + } + } + + return dirty; +} + +static dav_error * dav_fs_refresh_locks(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken_list *ltl, + time_t new_time, + dav_lock **locks) +{ + dav_error *err; + apr_datum_t key; + dav_lock_discovery *dp; + dav_lock_discovery *dp_scan; + dav_lock_indirect *ip; + int dirty = 0; + dav_lock *newlock; + + *locks = NULL; + + key = dav_fs_build_key(lockdb->info->pool, resource); + if ((err = dav_fs_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* ### we should be refreshing direct AND (resolved) indirect locks! */ + + /* refresh all of the direct locks on this resource */ + for (dp_scan = dp; dp_scan != NULL; dp_scan = dp_scan->next) { + if (dav_fs_do_refresh(dp_scan, ltl, new_time)) { + /* the lock was refreshed. return the lock. */ + newlock = dav_fs_alloc_lock(lockdb, key, dp_scan->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp_scan->f.scope; + newlock->type = dp_scan->f.type; + newlock->depth = dp_scan->f.depth; + newlock->timeout = dp_scan->f.timeout; + newlock->owner = dp_scan->owner; + newlock->auth_user = dp_scan->auth_user; + + newlock->next = *locks; + *locks = newlock; + + dirty = 1; + } + } + + /* if we refreshed any locks, then save them back. */ + if (dirty + && (err = dav_fs_save_lock_record(lockdb, key, dp, ip)) != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* for each indirect lock, find its direct lock and refresh it. */ + for (; ip != NULL; ip = ip->next) { + dav_lock_discovery *ref_dp; + dav_lock_indirect *ref_ip; + + if ((err = dav_fs_resolve(lockdb, ip, &dp_scan, + &ref_dp, &ref_ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + if (dav_fs_do_refresh(dp_scan, ltl, new_time)) { + /* the lock was refreshed. return the lock. */ + newlock = dav_fs_alloc_lock(lockdb, ip->key, dp_scan->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp_scan->f.scope; + newlock->type = dp_scan->f.type; + newlock->depth = dp_scan->f.depth; + newlock->timeout = dp_scan->f.timeout; + newlock->owner = dp_scan->owner; + newlock->auth_user = dp_scan->auth_user; + + newlock->next = *locks; + *locks = newlock; + + /* save the (resolved) direct lock back */ + if ((err = dav_fs_save_lock_record(lockdb, ip->key, ref_dp, + ref_ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + } + } + + return NULL; +} + + +const dav_hooks_locks dav_hooks_locks_fs = +{ + dav_fs_get_supportedlock, + dav_fs_parse_locktoken, + dav_fs_format_locktoken, + dav_fs_compare_locktoken, + dav_fs_open_lockdb, + dav_fs_close_lockdb, + dav_fs_remove_locknull_state, + dav_fs_create_lock, + dav_fs_get_locks, + dav_fs_find_lock, + dav_fs_has_locks, + dav_fs_append_locks, + dav_fs_remove_lock, + dav_fs_refresh_locks, + NULL, /* lookup_resource */ + + NULL /* ctx */ +}; diff --git a/trunk/modules/dav/fs/mod_dav_fs.c b/trunk/modules/dav/fs/mod_dav_fs.c new file mode 100644 index 0000000000..2f3197d2f9 --- /dev/null +++ b/trunk/modules/dav/fs/mod_dav_fs.c @@ -0,0 +1,108 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "apr_strings.h" + +#include "mod_dav.h" +#include "repos.h" + +/* per-server configuration */ +typedef struct { + const char *lockdb_path; + +} dav_fs_server_conf; + +extern module AP_MODULE_DECLARE_DATA dav_fs_module; + +const char *dav_get_lockdb_path(const request_rec *r) +{ + dav_fs_server_conf *conf; + + conf = ap_get_module_config(r->server->module_config, &dav_fs_module); + return conf->lockdb_path; +} + +static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s) +{ + return apr_pcalloc(p, sizeof(dav_fs_server_conf)); +} + +static void *dav_fs_merge_server_config(apr_pool_t *p, + void *base, void *overrides) +{ + dav_fs_server_conf *parent = base; + dav_fs_server_conf *child = overrides; + dav_fs_server_conf *newconf; + + newconf = apr_pcalloc(p, sizeof(*newconf)); + + newconf->lockdb_path = + child->lockdb_path ? child->lockdb_path : parent->lockdb_path; + + return newconf; +} + +/* + * Command handler for the DAVLockDB directive, which is TAKE1 + */ +static const char *dav_fs_cmd_davlockdb(cmd_parms *cmd, void *config, + const char *arg1) +{ + dav_fs_server_conf *conf; + conf = ap_get_module_config(cmd->server->module_config, + &dav_fs_module); + conf->lockdb_path = ap_server_root_relative(cmd->pool, arg1); + + if (!conf->lockdb_path) { + return apr_pstrcat(cmd->pool, "Invalid DAVLockDB path ", + arg1, NULL); + } + + return NULL; +} + +static const command_rec dav_fs_cmds[] = +{ + /* per server */ + AP_INIT_TAKE1("DAVLockDB", dav_fs_cmd_davlockdb, NULL, RSRC_CONF, + "specify a lock database"), + + { NULL } +}; + +static void register_hooks(apr_pool_t *p) +{ + dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, + APR_HOOK_MIDDLE); + dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); + dav_hook_insert_all_liveprops(dav_fs_insert_all_liveprops, NULL, NULL, + APR_HOOK_MIDDLE); + + dav_fs_register(p); +} + +module AP_MODULE_DECLARE_DATA dav_fs_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + dav_fs_create_server_config, /* server config */ + dav_fs_merge_server_config, /* merge server config */ + dav_fs_cmds, /* command table */ + register_hooks, /* register hooks */ +}; diff --git a/trunk/modules/dav/fs/mod_dav_fs.dsp b/trunk/modules/dav/fs/mod_dav_fs.dsp new file mode 100644 index 0000000000..6a64598929 --- /dev/null +++ b/trunk/modules/dav/fs/mod_dav_fs.dsp @@ -0,0 +1,152 @@ +# Microsoft Developer Studio Project File - Name="mod_dav_fs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_dav_fs - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_dav_fs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_dav_fs.mak" CFG="mod_dav_fs - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_dav_fs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_dav_fs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_dav_fs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_dav_fs_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_dav_fs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_dav_fs_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dav_fs.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav_fs.so + +!ENDIF + +# Begin Target + +# Name "mod_dav_fs - Win32 Release" +# Name "mod_dav_fs - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\dbm.c +# End Source File +# Begin Source File + +SOURCE=.\lock.c +# End Source File +# Begin Source File + +SOURCE=.\mod_dav_fs.c +# End Source File +# Begin Source File + +SOURCE=.\repos.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\repos.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\mod_dav_fs.rc +# End Source File +# Begin Source File + +SOURCE=..\..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_dav_fs - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_dav_fs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_dav_fs.so "dav_fs_module for Apache" ../../../include/ap_release.h > .\mod_dav_fs.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_dav_fs - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_dav_fs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_dav_fs.so "dav_fs_module for Apache" ../../../include/ap_release.h > .\mod_dav_fs.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/dav/fs/repos.c b/trunk/modules/dav/fs/repos.c new file mode 100644 index 0000000000..9c3e974e1e --- /dev/null +++ b/trunk/modules/dav/fs/repos.c @@ -0,0 +1,2157 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV filesystem-based repository provider +*/ + +#include "apr.h" +#include "apr_file_io.h" +#include "apr_strings.h" +#include "apr_buckets.h" + +#if APR_HAVE_STDIO_H +#include /* for sprintf() */ +#endif + +#include "httpd.h" +#include "http_log.h" +#include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */ +#include "http_request.h" /* for ap_update_mtime() */ + +#include "mod_dav.h" +#include "repos.h" + + +/* to assist in debugging mod_dav's GET handling */ +#define DEBUG_GET_HANDLER 0 + +#define DAV_FS_COPY_BLOCKSIZE 16384 /* copy 16k at a time */ + +/* context needed to identify a resource */ +struct dav_resource_private { + apr_pool_t *pool; /* memory storage pool associated with request */ + const char *pathname; /* full pathname to resource */ + apr_finfo_t finfo; /* filesystem info */ +}; + +/* private context for doing a filesystem walk */ +typedef struct { + /* the input walk parameters */ + const dav_walk_params *params; + + /* reused as we walk */ + dav_walk_resource wres; + + dav_resource res1; + dav_resource_private info1; + dav_buffer path1; + dav_buffer uri_buf; + + /* MOVE/COPY need a secondary path */ + dav_resource res2; + dav_resource_private info2; + dav_buffer path2; + + dav_buffer locknull_buf; + +} dav_fs_walker_context; + +typedef struct { + int is_move; /* is this a MOVE? */ + dav_buffer work_buf; /* handy buffer for copymove_file() */ + + /* CALLBACK: this is a secondary resource managed specially for us */ + const dav_resource *res_dst; + + /* copied from dav_walk_params (they are invariant across the walk) */ + const dav_resource *root; + apr_pool_t *pool; + +} dav_fs_copymove_walk_ctx; + +/* an internal WALKTYPE to walk hidden files (the .DAV directory) */ +#define DAV_WALKTYPE_HIDDEN 0x4000 + +/* an internal WALKTYPE to call collections (again) after their contents */ +#define DAV_WALKTYPE_POSTFIX 0x8000 + +#define DAV_CALLTYPE_POSTFIX 1000 /* a private call type */ + + +/* pull this in from the other source file */ +extern const dav_hooks_locks dav_hooks_locks_fs; + +/* forward-declare the hook structures */ +static const dav_hooks_repository dav_hooks_repository_fs; +static const dav_hooks_liveprop dav_hooks_liveprop_fs; + +/* +** The namespace URIs that we use. This list and the enumeration must +** stay in sync. +*/ +static const char * const dav_fs_namespace_uris[] = +{ + "DAV:", + "http://apache.org/dav/props/", + + NULL /* sentinel */ +}; +enum { + DAV_FS_URI_DAV, /* the DAV: namespace URI */ + DAV_FS_URI_MYPROPS /* the namespace URI for our custom props */ +}; + +/* +** Does this platform support an executable flag? +** +** ### need a way to portably abstract this query +*/ +#ifndef WIN32 +#define DAV_FS_HAS_EXECUTABLE +#endif + +/* +** The single property that we define (in the DAV_FS_URI_MYPROPS namespace) +*/ +#define DAV_PROPID_FS_executable 1 + +static const dav_liveprop_spec dav_fs_props[] = +{ + /* standard DAV properties */ + { + DAV_FS_URI_DAV, + "creationdate", + DAV_PROPID_creationdate, + 0 + }, + { + DAV_FS_URI_DAV, + "getcontentlength", + DAV_PROPID_getcontentlength, + 0 + }, + { + DAV_FS_URI_DAV, + "getetag", + DAV_PROPID_getetag, + 0 + }, + { + DAV_FS_URI_DAV, + "getlastmodified", + DAV_PROPID_getlastmodified, + 0 + }, + + /* our custom properties */ + { + DAV_FS_URI_MYPROPS, + "executable", + DAV_PROPID_FS_executable, + 0 /* handled special in dav_fs_is_writable */ + }, + + { 0 } /* sentinel */ +}; + +static const dav_liveprop_group dav_fs_liveprop_group = +{ + dav_fs_props, + dav_fs_namespace_uris, + &dav_hooks_liveprop_fs +}; + + +/* define the dav_stream structure for our use */ +struct dav_stream { + apr_pool_t *p; + apr_file_t *f; + const char *pathname; /* we may need to remove it at close time */ +}; + +/* returns an appropriate HTTP status code given an APR status code for a + * failed I/O operation. ### use something besides 500? */ +#define MAP_IO2HTTP(e) (APR_STATUS_IS_ENOSPC(e) ? HTTP_INSUFFICIENT_STORAGE : \ + HTTP_INTERNAL_SERVER_ERROR) + +/* forward declaration for internal treewalkers */ +static dav_error * dav_fs_walk(const dav_walk_params *params, int depth, + dav_response **response); +static dav_error * dav_fs_internal_walk(const dav_walk_params *params, + int depth, int is_move, + const dav_resource *root_dst, + dav_response **response); + +/* -------------------------------------------------------------------- +** +** PRIVATE REPOSITORY FUNCTIONS +*/ +apr_pool_t *dav_fs_pool(const dav_resource *resource) +{ + return resource->info->pool; +} + +const char *dav_fs_pathname(const dav_resource *resource) +{ + return resource->info->pathname; +} + +dav_error * dav_fs_dir_file_name( + const dav_resource *resource, + const char **dirpath_p, + const char **fname_p) +{ + dav_resource_private *ctx = resource->info; + + if (resource->collection) { + *dirpath_p = ctx->pathname; + if (fname_p != NULL) + *fname_p = NULL; + } + else { + const char *testpath, *rootpath; + char *dirpath = ap_make_dirstr_parent(ctx->pool, ctx->pathname); + apr_size_t dirlen = strlen(dirpath); + apr_status_t rv = APR_SUCCESS; + + testpath = dirpath; + if (dirlen > 0) { + rv = apr_filepath_root(&rootpath, &testpath, 0, ctx->pool); + } + + /* remove trailing slash from dirpath, unless it's a root path + */ + if ((rv == APR_SUCCESS && testpath && *testpath) + || rv == APR_ERELATIVE) { + if (dirpath[dirlen - 1] == '/') { + dirpath[dirlen - 1] = '\0'; + } + } + + /* ###: Looks like a response could be appropriate + * + * APR_SUCCESS here tells us the dir is a root + * APR_ERELATIVE told us we had no root (ok) + * APR_EINCOMPLETE an incomplete testpath told us + * there was no -file- name here! + * APR_EBADPATH or other errors tell us this file + * path is undecipherable + */ + + if (rv == APR_SUCCESS || rv == APR_ERELATIVE) { + *dirpath_p = dirpath; + if (fname_p != NULL) + *fname_p = ctx->pathname + dirlen; + } + else { + return dav_new_error(ctx->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "An incomplete/bad path was found in " + "dav_fs_dir_file_name."); + } + } + + return NULL; +} + +/* Note: picked up from ap_gm_timestr_822() */ +/* NOTE: buf must be at least DAV_TIMEBUF_SIZE chars in size */ +static void dav_format_time(int style, apr_time_t sec, char *buf) +{ + apr_time_exp_t tms; + + /* ### what to do if fails? */ + (void) apr_time_exp_gmt(&tms, sec); + + if (style == DAV_STYLE_ISO8601) { + /* ### should we use "-00:00" instead of "Z" ?? */ + + /* 20 chars plus null term */ + sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec); + return; + } + + /* RFC 822 date format; as strftime '%a, %d %b %Y %T GMT' */ + + /* 29 chars plus null term */ + sprintf(buf, + "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", + apr_day_snames[tms.tm_wday], + tms.tm_mday, apr_month_snames[tms.tm_mon], + tms.tm_year + 1900, + tms.tm_hour, tms.tm_min, tms.tm_sec); +} + +/* Copy or move src to dst; src_finfo is used to propagate permissions + * bits across if non-NULL; dst_finfo must be non-NULL iff dst already + * exists. */ +static dav_error * dav_fs_copymove_file( + int is_move, + apr_pool_t * p, + const char *src, + const char *dst, + const apr_finfo_t *src_finfo, + const apr_finfo_t *dst_finfo, + dav_buffer *pbuf) +{ + dav_buffer work_buf = { 0 }; + apr_file_t *inf = NULL; + apr_file_t *outf = NULL; + apr_status_t status; + apr_fileperms_t perms; + + if (pbuf == NULL) + pbuf = &work_buf; + + /* Determine permissions to use for destination */ + if (src_finfo && src_finfo->valid & APR_FINFO_PROT + && src_finfo->protection & APR_UEXECUTE) { + perms = src_finfo->protection; + + if (dst_finfo != NULL) { + /* chmod it if it already exist */ + if (apr_file_perms_set(dst, perms)) { + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not set permissions on destination"); + } + } + } + else { + perms = APR_OS_DEFAULT; + } + + dav_set_bufsize(p, pbuf, DAV_FS_COPY_BLOCKSIZE); + + if ((apr_file_open(&inf, src, APR_READ | APR_BINARY, APR_OS_DEFAULT, p)) + != APR_SUCCESS) { + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not open file for reading"); + } + + /* ### do we need to deal with the umask? */ + status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE + | APR_BINARY, perms, p); + if (status != APR_SUCCESS) { + apr_file_close(inf); + + return dav_new_error(p, MAP_IO2HTTP(status), 0, + "Could not open file for writing"); + } + + while (1) { + apr_size_t len = DAV_FS_COPY_BLOCKSIZE; + + status = apr_file_read(inf, pbuf->buf, &len); + if (status != APR_SUCCESS && status != APR_EOF) { + apr_file_close(inf); + apr_file_close(outf); + + if (apr_file_remove(dst, p) != APR_SUCCESS) { + /* ### ACK! Inconsistent state... */ + + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not delete output after read " + "failure. Server is now in an " + "inconsistent state."); + } + + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not read input file"); + } + + if (status == APR_EOF) + break; + + /* write any bytes that were read */ + status = apr_file_write_full(outf, pbuf->buf, len, NULL); + if (status != APR_SUCCESS) { + apr_file_close(inf); + apr_file_close(outf); + + if (apr_file_remove(dst, p) != APR_SUCCESS) { + /* ### ACK! Inconsistent state... */ + + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not delete output after write " + "failure. Server is now in an " + "inconsistent state."); + } + + return dav_new_error(p, MAP_IO2HTTP(status), 0, + "Could not write output file"); + } + } + + apr_file_close(inf); + apr_file_close(outf); + + if (is_move && apr_file_remove(src, p) != APR_SUCCESS) { + dav_error *err; + int save_errno = errno; /* save the errno that got us here */ + + if (apr_file_remove(dst, p) != APR_SUCCESS) { + /* ### ACK. this creates an inconsistency. do more!? */ + + /* ### use something besides 500? */ + /* Note that we use the latest errno */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not remove source or destination " + "file. Server is now in an inconsistent " + "state."); + } + + /* ### use something besides 500? */ + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not remove source file after move. " + "Destination was removed to ensure consistency."); + err->save_errno = save_errno; + return err; + } + + return NULL; +} + +/* copy/move a file from within a state dir to another state dir */ +/* ### need more buffers to replace the pool argument */ +static dav_error * dav_fs_copymove_state( + int is_move, + apr_pool_t * p, + const char *src_dir, const char *src_file, + const char *dst_dir, const char *dst_file, + dav_buffer *pbuf) +{ + apr_finfo_t src_finfo; /* finfo for source file */ + apr_finfo_t dst_state_finfo; /* finfo for STATE directory */ + apr_status_t rv; + const char *src; + const char *dst; + + /* build the propset pathname for the source file */ + src = apr_pstrcat(p, src_dir, "/" DAV_FS_STATE_DIR "/", src_file, NULL); + + /* the source file doesn't exist */ + rv = apr_stat(&src_finfo, src, APR_FINFO_NORM, p); + if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) { + return NULL; + } + + /* build the pathname for the destination state dir */ + dst = apr_pstrcat(p, dst_dir, "/" DAV_FS_STATE_DIR, NULL); + + /* ### do we need to deal with the umask? */ + + /* ensure that it exists */ + rv = apr_dir_make(dst, APR_OS_DEFAULT, p); + if (rv != APR_SUCCESS) { + if (!APR_STATUS_IS_EEXIST(rv)) { + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not create internal state directory"); + } + } + + /* get info about the state directory */ + rv = apr_stat(&dst_state_finfo, dst, APR_FINFO_NORM, p); + if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) { + /* Ack! Where'd it go? */ + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "State directory disappeared"); + } + + /* The mkdir() may have failed because a *file* exists there already */ + if (dst_state_finfo.filetype != APR_DIR) { + /* ### try to recover by deleting this file? (and mkdir again) */ + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "State directory is actually a file"); + } + + /* append the target file to the state directory pathname */ + dst = apr_pstrcat(p, dst, "/", dst_file, NULL); + + /* copy/move the file now */ + if (is_move && src_finfo.device == dst_state_finfo.device) { + /* simple rename is possible since it is on the same device */ + if (apr_file_rename(src, dst, p) != APR_SUCCESS) { + /* ### use something besides 500? */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not move state file."); + } + } + else + { + /* gotta copy (and delete) */ + return dav_fs_copymove_file(is_move, p, src, dst, NULL, NULL, pbuf); + } + + return NULL; +} + +static dav_error *dav_fs_copymoveset(int is_move, apr_pool_t *p, + const dav_resource *src, + const dav_resource *dst, + dav_buffer *pbuf) +{ + const char *src_dir; + const char *src_file; + const char *src_state1; + const char *src_state2; + const char *dst_dir; + const char *dst_file; + const char *dst_state1; + const char *dst_state2; + dav_error *err; + + /* Get directory and filename for resources */ + /* ### should test these result values... */ + (void) dav_fs_dir_file_name(src, &src_dir, &src_file); + (void) dav_fs_dir_file_name(dst, &dst_dir, &dst_file); + + /* Get the corresponding state files for each resource */ + dav_dbm_get_statefiles(p, src_file, &src_state1, &src_state2); + dav_dbm_get_statefiles(p, dst_file, &dst_state1, &dst_state2); +#if DAV_DEBUG + if ((src_state2 != NULL && dst_state2 == NULL) || + (src_state2 == NULL && dst_state2 != NULL)) { + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "DESIGN ERROR: dav_dbm_get_statefiles() " + "returned inconsistent results."); + } +#endif + + err = dav_fs_copymove_state(is_move, p, + src_dir, src_state1, + dst_dir, dst_state1, + pbuf); + + if (err == NULL && src_state2 != NULL) { + err = dav_fs_copymove_state(is_move, p, + src_dir, src_state2, + dst_dir, dst_state2, + pbuf); + + if (err != NULL) { + /* ### CRAP. inconsistency. */ + /* ### should perform some cleanup at the target if we still + ### have the original files */ + + /* Change the error to reflect the bad server state. */ + err->status = HTTP_INTERNAL_SERVER_ERROR; + err->desc = + "Could not fully copy/move the properties. " + "The server is now in an inconsistent state."; + } + } + + return err; +} + +static dav_error *dav_fs_deleteset(apr_pool_t *p, const dav_resource *resource) +{ + const char *dirpath; + const char *fname; + const char *state1; + const char *state2; + const char *pathname; + apr_status_t status; + + /* Get directory, filename, and state-file names for the resource */ + /* ### should test this result value... */ + (void) dav_fs_dir_file_name(resource, &dirpath, &fname); + dav_dbm_get_statefiles(p, fname, &state1, &state2); + + /* build the propset pathname for the file */ + pathname = apr_pstrcat(p, + dirpath, + "/" DAV_FS_STATE_DIR "/", + state1, + NULL); + + /* note: we may get ENOENT if the state dir is not present */ + if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS + && !APR_STATUS_IS_ENOENT(status)) { + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not remove properties."); + } + + if (state2 != NULL) { + /* build the propset pathname for the file */ + pathname = apr_pstrcat(p, + dirpath, + "/" DAV_FS_STATE_DIR "/", + state2, + NULL); + + if ((status = apr_file_remove(pathname, p)) != APR_SUCCESS + && !APR_STATUS_IS_ENOENT(status)) { + /* ### CRAP. only removed half. */ + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not fully remove properties. " + "The server is now in an inconsistent " + "state."); + } + } + + return NULL; +} + +/* -------------------------------------------------------------------- +** +** REPOSITORY HOOK FUNCTIONS +*/ + +static dav_error * dav_fs_get_resource( + request_rec *r, + const char *root_dir, + const char *label, + int use_checked_in, + dav_resource **result_resource) +{ + dav_resource_private *ctx; + dav_resource *resource; + char *s; + char *filename; + apr_size_t len; + + /* ### optimize this into a single allocation! */ + + /* Create private resource context descriptor */ + ctx = apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->finfo = r->finfo; + + /* ### this should go away */ + ctx->pool = r->pool; + + /* Preserve case on OSes which fold canonical filenames */ +#if 0 + /* ### not available in Apache 2.0 yet */ + filename = r->case_preserved_filename; +#else + filename = r->filename; +#endif + + /* + ** If there is anything in the path_info, then this indicates that the + ** entire path was not used to specify the file/dir. We want to append + ** it onto the filename so that we get a "valid" pathname for null + ** resources. + */ + s = apr_pstrcat(r->pool, filename, r->path_info, NULL); + + /* make sure the pathname does not have a trailing "/" */ + len = strlen(s); + if (len > 1 && s[len - 1] == '/') { + s[len - 1] = '\0'; + } + ctx->pathname = s; + + /* Create resource descriptor */ + resource = apr_pcalloc(r->pool, sizeof(*resource)); + resource->type = DAV_RESOURCE_TYPE_REGULAR; + resource->info = ctx; + resource->hooks = &dav_hooks_repository_fs; + resource->pool = r->pool; + + /* make sure the URI does not have a trailing "/" */ + len = strlen(r->uri); + if (len > 1 && r->uri[len - 1] == '/') { + s = apr_pstrdup(r->pool, r->uri); + s[len - 1] = '\0'; + resource->uri = s; + } + else { + resource->uri = r->uri; + } + + if (r->finfo.filetype != 0) { + resource->exists = 1; + resource->collection = r->finfo.filetype == APR_DIR; + + /* unused info in the URL will indicate a null resource */ + + if (r->path_info != NULL && *r->path_info != '\0') { + if (resource->collection) { + /* only a trailing "/" is allowed */ + if (*r->path_info != '/' || r->path_info[1] != '\0') { + + /* + ** This URL/filename represents a locknull resource or + ** possibly a destination of a MOVE/COPY + */ + resource->exists = 0; + resource->collection = 0; + } + } + else + { + /* + ** The base of the path refers to a file -- nothing should + ** be in path_info. The resource is simply an error: it + ** can't be a null or a locknull resource. + */ + return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, + "The URL contains extraneous path " + "components. The resource could not " + "be identified."); + } + + /* retain proper integrity across the structures */ + if (!resource->exists) { + ctx->finfo.filetype = 0; + } + } + } + + *result_resource = resource; + return NULL; +} + +static dav_error * dav_fs_get_parent_resource(const dav_resource *resource, + dav_resource **result_parent) +{ + dav_resource_private *ctx = resource->info; + dav_resource_private *parent_ctx; + dav_resource *parent_resource; + apr_status_t rv; + char *dirpath; + const char *testroot; + const char *testpath; + + /* If we're at the root of the URL space, then there is no parent. */ + if (strcmp(resource->uri, "/") == 0) { + *result_parent = NULL; + return NULL; + } + + /* If given resource is root, then there is no parent. + * Unless we can retrieve the filepath root, this is + * intendend to fail. If we split the root and + * no path info remains, then we also fail. + */ + testpath = ctx->pathname; + rv = apr_filepath_root(&testroot, &testpath, 0, ctx->pool); + if ((rv != APR_SUCCESS && rv != APR_ERELATIVE) + || !testpath || !*testpath) { + *result_parent = NULL; + return NULL; + } + + /* ### optimize this into a single allocation! */ + + /* Create private resource context descriptor */ + parent_ctx = apr_pcalloc(ctx->pool, sizeof(*parent_ctx)); + + /* ### this should go away */ + parent_ctx->pool = ctx->pool; + + dirpath = ap_make_dirstr_parent(ctx->pool, ctx->pathname); + if (strlen(dirpath) > 1 && dirpath[strlen(dirpath) - 1] == '/') + dirpath[strlen(dirpath) - 1] = '\0'; + parent_ctx->pathname = dirpath; + + parent_resource = apr_pcalloc(ctx->pool, sizeof(*parent_resource)); + parent_resource->info = parent_ctx; + parent_resource->collection = 1; + parent_resource->hooks = &dav_hooks_repository_fs; + parent_resource->pool = resource->pool; + + if (resource->uri != NULL) { + char *uri = ap_make_dirstr_parent(ctx->pool, resource->uri); + if (strlen(uri) > 1 && uri[strlen(uri) - 1] == '/') + uri[strlen(uri) - 1] = '\0'; + parent_resource->uri = uri; + } + + rv = apr_stat(&parent_ctx->finfo, parent_ctx->pathname, + APR_FINFO_NORM, ctx->pool); + if (rv == APR_SUCCESS || rv == APR_INCOMPLETE) { + parent_resource->exists = 1; + } + + *result_parent = parent_resource; + return NULL; +} + +static int dav_fs_is_same_resource( + const dav_resource *res1, + const dav_resource *res2) +{ + dav_resource_private *ctx1 = res1->info; + dav_resource_private *ctx2 = res2->info; + + if (res1->hooks != res2->hooks) + return 0; + + if ((ctx1->finfo.filetype != 0) && (ctx2->finfo.filetype != 0) + && (ctx1->finfo.valid & ctx2->finfo.valid & APR_FINFO_INODE)) { + return ctx1->finfo.inode == ctx2->finfo.inode; + } + else { + return strcmp(ctx1->pathname, ctx2->pathname) == 0; + } +} + +static int dav_fs_is_parent_resource( + const dav_resource *res1, + const dav_resource *res2) +{ + dav_resource_private *ctx1 = res1->info; + dav_resource_private *ctx2 = res2->info; + apr_size_t len1 = strlen(ctx1->pathname); + apr_size_t len2; + + if (res1->hooks != res2->hooks) + return 0; + + /* it is safe to use ctx2 now */ + len2 = strlen(ctx2->pathname); + + return (len2 > len1 + && memcmp(ctx1->pathname, ctx2->pathname, len1) == 0 + && ctx2->pathname[len1] == '/'); +} + +static dav_error * dav_fs_open_stream(const dav_resource *resource, + dav_stream_mode mode, + dav_stream **stream) +{ + apr_pool_t *p = resource->info->pool; + dav_stream *ds = apr_pcalloc(p, sizeof(*ds)); + apr_int32_t flags; + apr_status_t rv; + + switch (mode) { + default: + flags = APR_READ | APR_BINARY; + break; + + case DAV_MODE_WRITE_TRUNC: + flags = APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY; + break; + case DAV_MODE_WRITE_SEEKABLE: + flags = APR_WRITE | APR_CREATE | APR_BINARY; + break; + } + + ds->p = p; + ds->pathname = resource->info->pathname; + rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p); + if (rv != APR_SUCCESS) { + return dav_new_error(p, MAP_IO2HTTP(rv), 0, + "An error occurred while opening a resource."); + } + + /* (APR registers cleanups for the fd with the pool) */ + + *stream = ds; + return NULL; +} + +static dav_error * dav_fs_close_stream(dav_stream *stream, int commit) +{ + apr_file_close(stream->f); + + if (!commit) { + if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) { + /* ### use a better description? */ + return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0, + "There was a problem removing (rolling " + "back) the resource " + "when it was being closed."); + } + } + + return NULL; +} + +static dav_error * dav_fs_write_stream(dav_stream *stream, + const void *buf, apr_size_t bufsize) +{ + apr_status_t status; + + status = apr_file_write_full(stream->f, buf, bufsize, NULL); + if (APR_STATUS_IS_ENOSPC(status)) { + return dav_new_error(stream->p, HTTP_INSUFFICIENT_STORAGE, 0, + "There is not enough storage to write to " + "this resource."); + } + else if (status != APR_SUCCESS) { + /* ### use something besides 500? */ + return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0, + "An error occurred while writing to a " + "resource."); + } + return NULL; +} + +static dav_error * dav_fs_seek_stream(dav_stream *stream, apr_off_t abs_pos) +{ + if (apr_file_seek(stream->f, APR_SET, &abs_pos) != APR_SUCCESS) { + /* ### should check whether apr_file_seek set abs_pos was set to the + * correct position? */ + /* ### use something besides 500? */ + return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not seek to specified position in the " + "resource."); + } + return NULL; +} + + +#if DEBUG_GET_HANDLER + +/* only define set_headers() and deliver() for debug purposes */ + + +static dav_error * dav_fs_set_headers(request_rec *r, + const dav_resource *resource) +{ + /* ### this function isn't really used since we have a get_pathname */ + if (!resource->exists) + return NULL; + + /* make sure the proper mtime is in the request record */ + ap_update_mtime(r, resource->info->finfo.mtime); + + /* ### note that these use r->filename rather than */ + ap_set_last_modified(r); + ap_set_etag(r); + + /* we accept byte-ranges */ + apr_table_setn(r->headers_out, "Accept-Ranges", "bytes"); + + /* set up the Content-Length header */ + ap_set_content_length(r, resource->info->finfo.size); + + /* ### how to set the content type? */ + /* ### until this is resolved, the Content-Type header is busted */ + + return NULL; +} + +static dav_error * dav_fs_deliver(const dav_resource *resource, + ap_filter_t *output) +{ + apr_pool_t *pool = resource->pool; + apr_bucket_brigade *bb; + apr_file_t *fd; + apr_status_t status; + apr_bucket *bkt; + + /* Check resource type */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR + && resource->type != DAV_RESOURCE_TYPE_VERSION + && resource->type != DAV_RESOURCE_TYPE_WORKING) { + return dav_new_error(pool, HTTP_CONFLICT, 0, + "Cannot GET this type of resource."); + } + if (resource->collection) { + return dav_new_error(pool, HTTP_CONFLICT, 0, + "There is no default response to GET for a " + "collection."); + } + + if ((status = apr_file_open(&fd, resource->info->pathname, + APR_READ | APR_BINARY, 0, + pool)) != APR_SUCCESS) { + return dav_new_error(pool, HTTP_FORBIDDEN, 0, + "File permissions deny server access."); + } + + bb = apr_brigade_create(pool, output->c->bucket_alloc); + + /* ### this does not handle large files. but this is test code anyway */ + bkt = apr_bucket_file_create(fd, 0, + (apr_size_t)resource->info->finfo.size, + pool, output->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bkt); + + bkt = apr_bucket_eos_create(output->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bkt); + + if ((status = ap_pass_brigade(output, bb)) != APR_SUCCESS) { + return dav_new_error(pool, HTTP_FORBIDDEN, 0, + "Could not write contents to filter."); + } + + return NULL; +} + +#endif /* DEBUG_GET_HANDLER */ + + +static dav_error * dav_fs_create_collection(dav_resource *resource) +{ + dav_resource_private *ctx = resource->info; + apr_status_t status; + + status = apr_dir_make(ctx->pathname, APR_OS_DEFAULT, ctx->pool); + if (APR_STATUS_IS_ENOSPC(status)) { + return dav_new_error(ctx->pool, HTTP_INSUFFICIENT_STORAGE, 0, + "There is not enough storage to create " + "this collection."); + } + else if (APR_STATUS_IS_ENOENT(status)) { + return dav_new_error(ctx->pool, HTTP_CONFLICT, 0, + "Cannot create collection; intermediate " + "collection does not exist."); + } + else if (status != APR_SUCCESS) { + /* ### refine this error message? */ + return dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, + "Unable to create collection."); + } + + /* update resource state to show it exists as a collection */ + resource->exists = 1; + resource->collection = 1; + + return NULL; +} + +static dav_error * dav_fs_copymove_walker(dav_walk_resource *wres, + int calltype) +{ + dav_fs_copymove_walk_ctx *ctx = wres->walk_ctx; + dav_resource_private *srcinfo = wres->resource->info; + dav_resource_private *dstinfo = ctx->res_dst->info; + dav_error *err = NULL; + + if (wres->resource->collection) { + if (calltype == DAV_CALLTYPE_POSTFIX) { + /* Postfix call for MOVE. delete the source dir. + * Note: when copying, we do not enable the postfix-traversal. + */ + /* ### we are ignoring any error here; what should we do? */ + (void) apr_dir_remove(srcinfo->pathname, ctx->pool); + } + else { + /* copy/move of a collection. Create the new, target collection */ + if (apr_dir_make(dstinfo->pathname, APR_OS_DEFAULT, + ctx->pool) != APR_SUCCESS) { + /* ### assume it was a permissions problem */ + /* ### need a description here */ + err = dav_new_error(ctx->pool, HTTP_FORBIDDEN, 0, NULL); + } + } + } + else { + err = dav_fs_copymove_file(ctx->is_move, ctx->pool, + srcinfo->pathname, dstinfo->pathname, + &srcinfo->finfo, + ctx->res_dst->exists ? &dstinfo->finfo : NULL, + &ctx->work_buf); + /* ### push a higher-level description? */ + } + + /* + ** If we have a "not so bad" error, then it might need to go into a + ** multistatus response. + ** + ** For a MOVE, it will always go into the multistatus. It could be + ** that everything has been moved *except* for the root. Using a + ** multistatus (with no errors for the other resources) will signify + ** this condition. + ** + ** For a COPY, we are traversing in a prefix fashion. If the root fails, + ** then we can just bail out now. + */ + if (err != NULL + && !ap_is_HTTP_SERVER_ERROR(err->status) + && (ctx->is_move + || !dav_fs_is_same_resource(wres->resource, ctx->root))) { + /* ### use errno to generate DAV:responsedescription? */ + dav_add_response(wres, err->status, NULL); + + /* the error is in the multistatus now. do not stop the traversal. */ + return NULL; + } + + return err; +} + +static dav_error *dav_fs_copymove_resource( + int is_move, + const dav_resource *src, + const dav_resource *dst, + int depth, + dav_response **response) +{ + dav_error *err = NULL; + dav_buffer work_buf = { 0 }; + + *response = NULL; + + /* if a collection, recursively copy/move it and its children, + * including the state dirs + */ + if (src->collection) { + dav_walk_params params = { 0 }; + dav_response *multi_status; + + params.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_HIDDEN; + params.func = dav_fs_copymove_walker; + params.pool = src->info->pool; + params.root = src; + + /* params.walk_ctx is managed by dav_fs_internal_walk() */ + + /* postfix is needed for MOVE to delete source dirs */ + if (is_move) + params.walk_type |= DAV_WALKTYPE_POSTFIX; + + /* note that we return the error OR the multistatus. never both */ + + if ((err = dav_fs_internal_walk(¶ms, depth, is_move, dst, + &multi_status)) != NULL) { + /* on a "real" error, then just punt. nothing else to do. */ + return err; + } + + if ((*response = multi_status) != NULL) { + /* some multistatus responses exist. wrap them in a 207 */ + return dav_new_error(src->info->pool, HTTP_MULTI_STATUS, 0, + "Error(s) occurred on some resources during " + "the COPY/MOVE process."); + } + + return NULL; + } + + /* not a collection */ + if ((err = dav_fs_copymove_file(is_move, src->info->pool, + src->info->pathname, dst->info->pathname, + &src->info->finfo, + dst->exists ? &dst->info->finfo : NULL, + &work_buf)) != NULL) { + /* ### push a higher-level description? */ + return err; + } + + /* copy/move properties as well */ + return dav_fs_copymoveset(is_move, src->info->pool, src, dst, &work_buf); +} + +static dav_error * dav_fs_copy_resource( + const dav_resource *src, + dav_resource *dst, + int depth, + dav_response **response) +{ + dav_error *err; + +#if DAV_DEBUG + if (src->hooks != dst->hooks) { + /* + ** ### strictly speaking, this is a design error; we should not + ** ### have reached this point. + */ + return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "DESIGN ERROR: a mix of repositories " + "was passed to copy_resource."); + } +#endif + + if ((err = dav_fs_copymove_resource(0, src, dst, depth, + response)) == NULL) { + + /* update state of destination resource to show it exists */ + dst->exists = 1; + dst->collection = src->collection; + } + + return err; +} + +static dav_error * dav_fs_move_resource( + dav_resource *src, + dav_resource *dst, + dav_response **response) +{ + dav_resource_private *srcinfo = src->info; + dav_resource_private *dstinfo = dst->info; + dav_error *err; + int can_rename = 0; + +#if DAV_DEBUG + if (src->hooks != dst->hooks) { + /* + ** ### strictly speaking, this is a design error; we should not + ** ### have reached this point. + */ + return dav_new_error(src->info->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "DESIGN ERROR: a mix of repositories " + "was passed to move_resource."); + } +#endif + + /* determine whether a simple rename will work. + * Assume source exists, else we wouldn't get called. + */ + if (dstinfo->finfo.filetype != 0) { + if (dstinfo->finfo.device == srcinfo->finfo.device) { + /* target exists and is on the same device. */ + can_rename = 1; + } + } + else { + const char *dirpath; + apr_finfo_t finfo; + apr_status_t rv; + + /* destination does not exist, but the parent directory should, + * so try it + */ + dirpath = ap_make_dirstr_parent(dstinfo->pool, dstinfo->pathname); + /* + * XXX: If missing dev ... then what test? + * Really need a try and failover for those platforms. + * + */ + rv = apr_stat(&finfo, dirpath, APR_FINFO_DEV, dstinfo->pool); + if ((rv == APR_SUCCESS || rv == APR_INCOMPLETE) + && (finfo.valid & srcinfo->finfo.valid & APR_FINFO_DEV) + && (finfo.device == srcinfo->finfo.device)) { + can_rename = 1; + } + } + + /* if we can't simply rename, then do it the hard way... */ + if (!can_rename) { + if ((err = dav_fs_copymove_resource(1, src, dst, DAV_INFINITY, + response)) == NULL) { + /* update resource states */ + dst->exists = 1; + dst->collection = src->collection; + src->exists = 0; + src->collection = 0; + } + + return err; + } + + /* a rename should work. do it, and move properties as well */ + + /* no multistatus response */ + *response = NULL; + + /* ### APR has no rename? */ + if (apr_file_rename(srcinfo->pathname, dstinfo->pathname, + srcinfo->pool) != APR_SUCCESS) { + /* ### should have a better error than this. */ + return dav_new_error(srcinfo->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not rename resource."); + } + + /* update resource states */ + dst->exists = 1; + dst->collection = src->collection; + src->exists = 0; + src->collection = 0; + + if ((err = dav_fs_copymoveset(1, src->info->pool, + src, dst, NULL)) == NULL) { + /* no error. we're done. go ahead and return now. */ + return NULL; + } + + /* error occurred during properties move; try to put resource back */ + if (apr_file_rename(dstinfo->pathname, srcinfo->pathname, + srcinfo->pool) != APR_SUCCESS) { + /* couldn't put it back! */ + return dav_push_error(srcinfo->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "The resource was moved, but a failure " + "occurred during the move of its " + "properties. The resource could not be " + "restored to its original location. The " + "server is now in an inconsistent state.", + err); + } + + /* update resource states again */ + src->exists = 1; + src->collection = dst->collection; + dst->exists = 0; + dst->collection = 0; + + /* resource moved back, but properties may be inconsistent */ + return dav_push_error(srcinfo->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "The resource was moved, but a failure " + "occurred during the move of its properties. " + "The resource was moved back to its original " + "location, but its properties may have been " + "partially moved. The server may be in an " + "inconsistent state.", + err); +} + +static dav_error * dav_fs_delete_walker(dav_walk_resource *wres, int calltype) +{ + dav_resource_private *info = wres->resource->info; + + /* do not attempt to remove a null resource, + * or a collection with children + */ + if (wres->resource->exists && + (!wres->resource->collection || calltype == DAV_CALLTYPE_POSTFIX)) { + /* try to remove the resource */ + apr_status_t result; + + result = wres->resource->collection + ? apr_dir_remove(info->pathname, wres->pool) + : apr_file_remove(info->pathname, wres->pool); + + /* + ** If an error occurred, then add it to multistatus response. + ** Note that we add it for the root resource, too. It is quite + ** possible to delete the whole darn tree, yet fail on the root. + ** + ** (also: remember we are deleting via a postfix traversal) + */ + if (result != APR_SUCCESS) { + /* ### assume there is a permissions problem */ + + /* ### use errno to generate DAV:responsedescription? */ + dav_add_response(wres, HTTP_FORBIDDEN, NULL); + } + } + + return NULL; +} + +static dav_error * dav_fs_remove_resource(dav_resource *resource, + dav_response **response) +{ + dav_resource_private *info = resource->info; + + *response = NULL; + + /* if a collection, recursively remove it and its children, + * including the state dirs + */ + if (resource->collection) { + dav_walk_params params = { 0 }; + dav_error *err = NULL; + dav_response *multi_status; + + params.walk_type = (DAV_WALKTYPE_NORMAL + | DAV_WALKTYPE_HIDDEN + | DAV_WALKTYPE_POSTFIX); + params.func = dav_fs_delete_walker; + params.pool = info->pool; + params.root = resource; + + if ((err = dav_fs_walk(¶ms, DAV_INFINITY, + &multi_status)) != NULL) { + /* on a "real" error, then just punt. nothing else to do. */ + return err; + } + + if ((*response = multi_status) != NULL) { + /* some multistatus responses exist. wrap them in a 207 */ + return dav_new_error(info->pool, HTTP_MULTI_STATUS, 0, + "Error(s) occurred on some resources during " + "the deletion process."); + } + + /* no errors... update resource state */ + resource->exists = 0; + resource->collection = 0; + + return NULL; + } + + /* not a collection; remove the file and its properties */ + if (apr_file_remove(info->pathname, info->pool) != APR_SUCCESS) { + /* ### put a description in here */ + return dav_new_error(info->pool, HTTP_FORBIDDEN, 0, NULL); + } + + /* update resource state */ + resource->exists = 0; + resource->collection = 0; + + /* remove properties and return its result */ + return dav_fs_deleteset(info->pool, resource); +} + +/* ### move this to dav_util? */ +/* Walk recursively down through directories, * + * including lock-null resources as we go. */ +static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth) +{ + const dav_walk_params *params = fsctx->params; + apr_pool_t *pool = params->pool; + dav_error *err = NULL; + int isdir = fsctx->res1.collection; + apr_finfo_t dirent; + apr_dir_t *dirp; + + /* ensure the context is prepared properly, then call the func */ + err = (*params->func)(&fsctx->wres, + isdir + ? DAV_CALLTYPE_COLLECTION + : DAV_CALLTYPE_MEMBER); + if (err != NULL) { + return err; + } + + if (depth == 0 || !isdir) { + return NULL; + } + + /* put a trailing slash onto the directory, in preparation for appending + * files to it as we discovery them within the directory */ + dav_check_bufsize(pool, &fsctx->path1, DAV_BUFFER_PAD); + fsctx->path1.buf[fsctx->path1.cur_len++] = '/'; + fsctx->path1.buf[fsctx->path1.cur_len] = '\0'; /* in pad area */ + + /* if a secondary path is present, then do that, too */ + if (fsctx->path2.buf != NULL) { + dav_check_bufsize(pool, &fsctx->path2, DAV_BUFFER_PAD); + fsctx->path2.buf[fsctx->path2.cur_len++] = '/'; + fsctx->path2.buf[fsctx->path2.cur_len] = '\0'; /* in pad area */ + } + + /* Note: the URI should ALREADY have a trailing "/" */ + + /* for this first pass of files, all resources exist */ + fsctx->res1.exists = 1; + + /* a file is the default; we'll adjust if we hit a directory */ + fsctx->res1.collection = 0; + fsctx->res2.collection = 0; + + /* open and scan the directory */ + if ((apr_dir_open(&dirp, fsctx->path1.buf, pool)) != APR_SUCCESS) { + /* ### need a better error */ + return dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL); + } + while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) { + apr_size_t len; + apr_status_t status; + + len = strlen(dirent.name); + + /* avoid recursing into our current, parent, or state directories */ + if (dirent.name[0] == '.' + && (len == 1 || (dirent.name[1] == '.' && len == 2))) { + continue; + } + + if (params->walk_type & DAV_WALKTYPE_AUTH) { + /* ### need to authorize each file */ + /* ### example: .htaccess is normally configured to fail auth */ + + /* stuff in the state directory is never authorized! */ + if (!strcmp(dirent.name, DAV_FS_STATE_DIR)) { + continue; + } + } + /* skip the state dir unless a HIDDEN is performed */ + if (!(params->walk_type & DAV_WALKTYPE_HIDDEN) + && !strcmp(dirent.name, DAV_FS_STATE_DIR)) { + continue; + } + + /* append this file onto the path buffer (copy null term) */ + dav_buffer_place_mem(pool, &fsctx->path1, dirent.name, len + 1, 0); + + + /* ### Optimize me, dirent can give us what we need! */ + status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf, + APR_FINFO_NORM | APR_FINFO_LINK, pool); + if (status != APR_SUCCESS && status != APR_INCOMPLETE) { + /* woah! where'd it go? */ + /* ### should have a better error here */ + err = dav_new_error(pool, HTTP_NOT_FOUND, 0, NULL); + break; + } + + /* copy the file to the URI, too. NOTE: we will pad an extra byte + for the trailing slash later. */ + dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1); + + /* if there is a secondary path, then do that, too */ + if (fsctx->path2.buf != NULL) { + dav_buffer_place_mem(pool, &fsctx->path2, dirent.name, len + 1, 0); + } + + /* set up the (internal) pathnames for the two resources */ + fsctx->info1.pathname = fsctx->path1.buf; + fsctx->info2.pathname = fsctx->path2.buf; + + /* set up the URI for the current resource */ + fsctx->res1.uri = fsctx->uri_buf.buf; + + /* ### for now, only process regular files (e.g. skip symlinks) */ + if (fsctx->info1.finfo.filetype == APR_REG) { + /* call the function for the specified dir + file */ + if ((err = (*params->func)(&fsctx->wres, + DAV_CALLTYPE_MEMBER)) != NULL) { + /* ### maybe add a higher-level description? */ + break; + } + } + else if (fsctx->info1.finfo.filetype == APR_DIR) { + apr_size_t save_path_len = fsctx->path1.cur_len; + apr_size_t save_uri_len = fsctx->uri_buf.cur_len; + apr_size_t save_path2_len = fsctx->path2.cur_len; + + /* adjust length to incorporate the subdir name */ + fsctx->path1.cur_len += len; + fsctx->path2.cur_len += len; + + /* adjust URI length to incorporate subdir and a slash */ + fsctx->uri_buf.cur_len += len + 1; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/'; + fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0'; + + /* switch over to a collection */ + fsctx->res1.collection = 1; + fsctx->res2.collection = 1; + + /* recurse on the subdir */ + /* ### don't always want to quit on error from single child */ + if ((err = dav_fs_walker(fsctx, depth - 1)) != NULL) { + /* ### maybe add a higher-level description? */ + break; + } + + /* put the various information back */ + fsctx->path1.cur_len = save_path_len; + fsctx->path2.cur_len = save_path2_len; + fsctx->uri_buf.cur_len = save_uri_len; + + fsctx->res1.collection = 0; + fsctx->res2.collection = 0; + + /* assert: res1.exists == 1 */ + } + } + + /* ### check the return value of this? */ + apr_dir_close(dirp); + + if (err != NULL) + return err; + + if (params->walk_type & DAV_WALKTYPE_LOCKNULL) { + apr_size_t offset = 0; + + /* null terminate the directory name */ + fsctx->path1.buf[fsctx->path1.cur_len - 1] = '\0'; + + /* Include any lock null resources found in this collection */ + fsctx->res1.collection = 1; + if ((err = dav_fs_get_locknull_members(&fsctx->res1, + &fsctx->locknull_buf)) != NULL) { + /* ### maybe add a higher-level description? */ + return err; + } + + /* put a slash back on the end of the directory */ + fsctx->path1.buf[fsctx->path1.cur_len - 1] = '/'; + + /* these are all non-existant (files) */ + fsctx->res1.exists = 0; + fsctx->res1.collection = 0; + memset(&fsctx->info1.finfo, 0, sizeof(fsctx->info1.finfo)); + + while (offset < fsctx->locknull_buf.cur_len) { + apr_size_t len = strlen(fsctx->locknull_buf.buf + offset); + dav_lock *locks = NULL; + + /* + ** Append the locknull file to the paths and the URI. Note that + ** we don't have to pad the URI for a slash since a locknull + ** resource is not a collection. + */ + dav_buffer_place_mem(pool, &fsctx->path1, + fsctx->locknull_buf.buf + offset, len + 1, 0); + dav_buffer_place_mem(pool, &fsctx->uri_buf, + fsctx->locknull_buf.buf + offset, len + 1, 0); + if (fsctx->path2.buf != NULL) { + dav_buffer_place_mem(pool, &fsctx->path2, + fsctx->locknull_buf.buf + offset, + len + 1, 0); + } + + /* set up the (internal) pathnames for the two resources */ + fsctx->info1.pathname = fsctx->path1.buf; + fsctx->info2.pathname = fsctx->path2.buf; + + /* set up the URI for the current resource */ + fsctx->res1.uri = fsctx->uri_buf.buf; + + /* + ** To prevent a PROPFIND showing an expired locknull + ** resource, query the lock database to force removal + ** of both the lock entry and .locknull, if necessary.. + ** Sure, the query in PROPFIND would do this.. after + ** the locknull resource was already included in the + ** return. + ** + ** NOTE: we assume the caller has opened the lock database + ** if they have provided DAV_WALKTYPE_LOCKNULL. + */ + /* ### we should also look into opening it read-only and + ### eliding timed-out items from the walk, yet leaving + ### them in the locknull database until somebody opens + ### the thing writable. + */ + /* ### probably ought to use has_locks. note the problem + ### mentioned above, though... we would traverse this as + ### a locknull, but then a PROPFIND would load the lock + ### info, causing a timeout and the locks would not be + ### reported. Therefore, a null resource would be returned + ### in the PROPFIND. + ### + ### alternative: just load unresolved locks. any direct + ### locks will be timed out (correct). any indirect will + ### not (correct; consider if a parent timed out -- the + ### timeout routines do not walk and remove indirects; + ### even the resolve func would probably fail when it + ### tried to find a timed-out direct lock). + */ + if ((err = dav_lock_query(params->lockdb, &fsctx->res1, + &locks)) != NULL) { + /* ### maybe add a higher-level description? */ + return err; + } + + /* call the function for the specified dir + file */ + if (locks != NULL && + (err = (*params->func)(&fsctx->wres, + DAV_CALLTYPE_LOCKNULL)) != NULL) { + /* ### maybe add a higher-level description? */ + return err; + } + + offset += len + 1; + } + + /* reset the exists flag */ + fsctx->res1.exists = 1; + } + + if (params->walk_type & DAV_WALKTYPE_POSTFIX) { + /* replace the dirs' trailing slashes with null terms */ + fsctx->path1.buf[--fsctx->path1.cur_len] = '\0'; + fsctx->uri_buf.buf[--fsctx->uri_buf.cur_len] = '\0'; + if (fsctx->path2.buf != NULL) { + fsctx->path2.buf[--fsctx->path2.cur_len] = '\0'; + } + + /* this is a collection which exists */ + fsctx->res1.collection = 1; + + return (*params->func)(&fsctx->wres, DAV_CALLTYPE_POSTFIX); + } + + return NULL; +} + +static dav_error * dav_fs_internal_walk(const dav_walk_params *params, + int depth, int is_move, + const dav_resource *root_dst, + dav_response **response) +{ + dav_fs_walker_context fsctx = { 0 }; + dav_error *err; + dav_fs_copymove_walk_ctx cm_ctx = { 0 }; + +#if DAV_DEBUG + if ((params->walk_type & DAV_WALKTYPE_LOCKNULL) != 0 + && params->lockdb == NULL) { + return dav_new_error(params->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "DESIGN ERROR: walker called to walk locknull " + "resources, but a lockdb was not provided."); + } +#endif + + fsctx.params = params; + fsctx.wres.walk_ctx = params->walk_ctx; + fsctx.wres.pool = params->pool; + + /* ### zero out versioned, working, baselined? */ + + fsctx.res1 = *params->root; + fsctx.res1.pool = params->pool; + + fsctx.res1.info = &fsctx.info1; + fsctx.info1 = *params->root->info; + + /* the pathname is stored in the path1 buffer */ + dav_buffer_init(params->pool, &fsctx.path1, fsctx.info1.pathname); + fsctx.info1.pathname = fsctx.path1.buf; + + if (root_dst != NULL) { + /* internal call from the COPY/MOVE code. set it up. */ + + fsctx.wres.walk_ctx = &cm_ctx; + cm_ctx.is_move = is_move; + cm_ctx.res_dst = &fsctx.res2; + cm_ctx.root = params->root; + cm_ctx.pool = params->pool; + + fsctx.res2 = *root_dst; + fsctx.res2.exists = 0; + fsctx.res2.collection = 0; + fsctx.res2.uri = NULL; /* we don't track this */ + fsctx.res2.pool = params->pool; + + fsctx.res2.info = &fsctx.info2; + fsctx.info2 = *root_dst->info; + + /* res2 does not exist -- clear its finfo structure */ + memset(&fsctx.info2.finfo, 0, sizeof(fsctx.info2.finfo)); + + /* the pathname is stored in the path2 buffer */ + dav_buffer_init(params->pool, &fsctx.path2, fsctx.info2.pathname); + fsctx.info2.pathname = fsctx.path2.buf; + } + + /* prep the URI buffer */ + dav_buffer_init(params->pool, &fsctx.uri_buf, params->root->uri); + + /* if we have a directory, then ensure the URI has a trailing "/" */ + if (fsctx.res1.collection + && fsctx.uri_buf.buf[fsctx.uri_buf.cur_len - 1] != '/') { + + /* this will fall into the pad area */ + fsctx.uri_buf.buf[fsctx.uri_buf.cur_len++] = '/'; + fsctx.uri_buf.buf[fsctx.uri_buf.cur_len] = '\0'; + } + + /* the current resource's URI is stored in the uri_buf buffer */ + fsctx.res1.uri = fsctx.uri_buf.buf; + + /* point the callback's resource at our structure */ + fsctx.wres.resource = &fsctx.res1; + + /* always return the error, and any/all multistatus responses */ + err = dav_fs_walker(&fsctx, depth); + *response = fsctx.wres.response; + return err; +} + +static dav_error * dav_fs_walk(const dav_walk_params *params, int depth, + dav_response **response) +{ + /* always return the error, and any/all multistatus responses */ + return dav_fs_internal_walk(params, depth, 0, NULL, response); +} + +/* dav_fs_etag: Stolen from ap_make_etag. Creates a strong etag + * for file path. + * ### do we need to return weak tags sometimes? + */ +static const char *dav_fs_getetag(const dav_resource *resource) +{ + dav_resource_private *ctx = resource->info; + + if (!resource->exists) + return apr_pstrdup(ctx->pool, ""); + + if (ctx->finfo.filetype != 0) { + return apr_psprintf(ctx->pool, "\"%lx-%lx-%lx\"", + (unsigned long) ctx->finfo.inode, + (unsigned long) ctx->finfo.size, + (unsigned long) ctx->finfo.mtime); + } + + return apr_psprintf(ctx->pool, "\"%lx\"", (unsigned long) ctx->finfo.mtime); +} + +static const dav_hooks_repository dav_hooks_repository_fs = +{ + DEBUG_GET_HANDLER, /* normally: special GET handling not required */ + dav_fs_get_resource, + dav_fs_get_parent_resource, + dav_fs_is_same_resource, + dav_fs_is_parent_resource, + dav_fs_open_stream, + dav_fs_close_stream, + dav_fs_write_stream, + dav_fs_seek_stream, +#if DEBUG_GET_HANDLER + dav_fs_set_headers, + dav_fs_deliver, +#else + NULL, + NULL, +#endif + dav_fs_create_collection, + dav_fs_copy_resource, + dav_fs_move_resource, + dav_fs_remove_resource, + dav_fs_walk, + dav_fs_getetag, +}; + +static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, + int propid, dav_prop_insert what, + apr_text_header *phdr) +{ + const char *value; + const char *s; + apr_pool_t *p = resource->info->pool; + const dav_liveprop_spec *info; + int global_ns; + + /* an HTTP-date can be 29 chars plus a null term */ + /* a 64-bit size can be 20 chars plus a null term */ + char buf[DAV_TIMEBUF_SIZE]; + + /* + ** None of FS provider properties are defined if the resource does not + ** exist. Just bail for this case. + ** + ** Even though we state that the FS properties are not defined, the + ** client cannot store dead values -- we deny that thru the is_writable + ** hook function. + */ + if (!resource->exists) + return DAV_PROP_INSERT_NOTDEF; + + switch (propid) { + case DAV_PROPID_creationdate: + /* + ** Closest thing to a creation date. since we don't actually + ** perform the operations that would modify ctime (after we + ** create the file), then we should be pretty safe here. + */ + dav_format_time(DAV_STYLE_ISO8601, + resource->info->finfo.ctime, + buf); + value = buf; + break; + + case DAV_PROPID_getcontentlength: + /* our property, but not defined on collection resources */ + if (resource->collection) + return DAV_PROP_INSERT_NOTDEF; + + (void) sprintf(buf, "%" APR_OFF_T_FMT, resource->info->finfo.size); + value = buf; + break; + + case DAV_PROPID_getetag: + value = dav_fs_getetag(resource); + break; + + case DAV_PROPID_getlastmodified: + dav_format_time(DAV_STYLE_RFC822, + resource->info->finfo.mtime, + buf); + value = buf; + break; + + case DAV_PROPID_FS_executable: + /* our property, but not defined on collection resources */ + if (resource->collection) + return DAV_PROP_INSERT_NOTDEF; + + /* our property, but not defined on this platform */ + if (!(resource->info->finfo.valid & APR_FINFO_UPROT)) + return DAV_PROP_INSERT_NOTDEF; + + /* the files are "ours" so we only need to check owner exec privs */ + if (resource->info->finfo.protection & APR_UEXECUTE) + value = "T"; + else + value = "F"; + break; + + default: + /* ### what the heck was this property? */ + return DAV_PROP_INSERT_NOTDEF; + } + + /* assert: value != NULL */ + + /* get the information and global NS index for the property */ + global_ns = dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info); + + /* assert: info != NULL && info->name != NULL */ + + /* DBG3("FS: inserting lp%d:%s (local %d)", ns, scan->name, scan->ns); */ + + if (what == DAV_PROP_INSERT_VALUE) { + s = apr_psprintf(p, "%s" DEBUG_CR, + global_ns, info->name, value, global_ns, info->name); + } + else if (what == DAV_PROP_INSERT_NAME) { + s = apr_psprintf(p, "" DEBUG_CR, global_ns, info->name); + } + else { + /* assert: what == DAV_PROP_INSERT_SUPPORTED */ + s = apr_psprintf(p, + "" DEBUG_CR, + info->name, dav_fs_namespace_uris[info->ns]); + } + apr_text_append(p, phdr, s); + + /* we inserted what was asked for */ + return what; +} + +static int dav_fs_is_writable(const dav_resource *resource, int propid) +{ + const dav_liveprop_spec *info; + +#ifdef DAV_FS_HAS_EXECUTABLE + /* if we have the executable property, and this isn't a collection, + then the property is writable. */ + if (propid == DAV_PROPID_FS_executable && !resource->collection) + return 1; +#endif + + (void) dav_get_liveprop_info(propid, &dav_fs_liveprop_group, &info); + return info->is_writable; +} + +static dav_error *dav_fs_patch_validate(const dav_resource *resource, + const apr_xml_elem *elem, + int operation, + void **context, + int *defer_to_dead) +{ + const apr_text *cdata; + const apr_text *f_cdata; + char value; + dav_elem_private *priv = elem->priv; + + if (priv->propid != DAV_PROPID_FS_executable) { + *defer_to_dead = 1; + return NULL; + } + + if (operation == DAV_PROP_OP_DELETE) { + return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, + "The 'executable' property cannot be removed."); + } + + cdata = elem->first_cdata.first; + + /* ### hmm. this isn't actually looking at all the possible text items */ + f_cdata = elem->first_child == NULL + ? NULL + : elem->first_child->following_cdata.first; + + /* DBG3("name=%s cdata=%s f_cdata=%s",elem->name,cdata ? cdata->text : "[null]",f_cdata ? f_cdata->text : "[null]"); */ + + if (cdata == NULL) { + if (f_cdata == NULL) { + return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, + "The 'executable' property expects a single " + "character, valued 'T' or 'F'. There was no " + "value submitted."); + } + cdata = f_cdata; + } + else if (f_cdata != NULL) + goto too_long; + + if (cdata->next != NULL || strlen(cdata->text) != 1) + goto too_long; + + value = cdata->text[0]; + if (value != 'T' && value != 'F') { + return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, + "The 'executable' property expects a single " + "character, valued 'T' or 'F'. The value " + "submitted is invalid."); + } + + *context = (void *)(value == 'T'); + + return NULL; + + too_long: + return dav_new_error(resource->info->pool, HTTP_CONFLICT, 0, + "The 'executable' property expects a single " + "character, valued 'T' or 'F'. The value submitted " + "has too many characters."); + +} + +static dav_error *dav_fs_patch_exec(const dav_resource *resource, + const apr_xml_elem *elem, + int operation, + void *context, + dav_liveprop_rollback **rollback_ctx) +{ + int value = context != NULL; + apr_fileperms_t perms = resource->info->finfo.protection; + int old_value = (perms & APR_UEXECUTE) != 0; + + /* assert: prop == executable. operation == SET. */ + + /* don't do anything if there is no change. no rollback info either. */ + /* DBG2("new value=%d (old=%d)", value, old_value); */ + if (value == old_value) + return NULL; + + perms &= ~APR_UEXECUTE; + if (value) + perms |= APR_UEXECUTE; + + if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) { + return dav_new_error(resource->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not set the executable flag of the " + "target resource."); + } + + /* update the resource and set up the rollback context */ + resource->info->finfo.protection = perms; + *rollback_ctx = (dav_liveprop_rollback *)old_value; + + return NULL; +} + +static void dav_fs_patch_commit(const dav_resource *resource, + int operation, + void *context, + dav_liveprop_rollback *rollback_ctx) +{ + /* nothing to do */ +} + +static dav_error *dav_fs_patch_rollback(const dav_resource *resource, + int operation, + void *context, + dav_liveprop_rollback *rollback_ctx) +{ + apr_fileperms_t perms = resource->info->finfo.protection & ~APR_UEXECUTE; + int value = rollback_ctx != NULL; + + /* assert: prop == executable. operation == SET. */ + + /* restore the executable bit */ + if (value) + perms |= APR_UEXECUTE; + + if (apr_file_perms_set(resource->info->pathname, perms) != APR_SUCCESS) { + return dav_new_error(resource->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "After a failure occurred, the resource's " + "executable flag could not be restored."); + } + + /* restore the resource's state */ + resource->info->finfo.protection = perms; + + return NULL; +} + + +static const dav_hooks_liveprop dav_hooks_liveprop_fs = +{ + dav_fs_insert_prop, + dav_fs_is_writable, + dav_fs_namespace_uris, + dav_fs_patch_validate, + dav_fs_patch_exec, + dav_fs_patch_commit, + dav_fs_patch_rollback +}; + +static const dav_provider dav_fs_provider = +{ + &dav_hooks_repository_fs, + &dav_hooks_db_dbm, + &dav_hooks_locks_fs, + NULL, /* vsn */ + NULL, /* binding */ + NULL, /* search */ + + NULL /* ctx */ +}; + +void dav_fs_gather_propsets(apr_array_header_t *uris) +{ +#ifdef DAV_FS_HAS_EXECUTABLE + *(const char **)apr_array_push(uris) = + ""; +#endif +} + +int dav_fs_find_liveprop(const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks) +{ + /* don't try to find any liveprops if this isn't "our" resource */ + if (resource->hooks != &dav_hooks_repository_fs) + return 0; + return dav_do_find_liveprop(ns_uri, name, &dav_fs_liveprop_group, hooks); +} + +void dav_fs_insert_all_liveprops(request_rec *r, const dav_resource *resource, + dav_prop_insert what, apr_text_header *phdr) +{ + /* don't insert any liveprops if this isn't "our" resource */ + if (resource->hooks != &dav_hooks_repository_fs) + return; + + if (!resource->exists) { + /* a lock-null resource */ + /* + ** ### technically, we should insert empty properties. dunno offhand + ** ### what part of the spec said this, but it was essentially thus: + ** ### "the properties should be defined, but may have no value". + */ + return; + } + + (void) dav_fs_insert_prop(resource, DAV_PROPID_creationdate, + what, phdr); + (void) dav_fs_insert_prop(resource, DAV_PROPID_getcontentlength, + what, phdr); + (void) dav_fs_insert_prop(resource, DAV_PROPID_getlastmodified, + what, phdr); + (void) dav_fs_insert_prop(resource, DAV_PROPID_getetag, + what, phdr); + +#ifdef DAV_FS_HAS_EXECUTABLE + /* Only insert this property if it is defined for this platform. */ + (void) dav_fs_insert_prop(resource, DAV_PROPID_FS_executable, + what, phdr); +#endif + + /* ### we know the others aren't defined as liveprops */ +} + +void dav_fs_register(apr_pool_t *p) +{ + /* register the namespace URIs */ + dav_register_liveprop_group(p, &dav_fs_liveprop_group); + + /* register the repository provider */ + dav_register_provider(p, "filesystem", &dav_fs_provider); +} diff --git a/trunk/modules/dav/fs/repos.h b/trunk/modules/dav/fs/repos.h new file mode 100644 index 0000000000..1e19de4892 --- /dev/null +++ b/trunk/modules/dav/fs/repos.h @@ -0,0 +1,78 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** Declarations for the filesystem repository implementation +*/ + +#ifndef _DAV_FS_REPOS_H_ +#define _DAV_FS_REPOS_H_ + +/* the subdirectory to hold all DAV-related information for a directory */ +#define DAV_FS_STATE_DIR ".DAV" +#define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir" +#define DAV_FS_LOCK_NULL_FILE ".locknull" + + +/* ensure that our state subdirectory is present */ +void dav_fs_ensure_state_dir(apr_pool_t *p, const char *dirname); + +/* return the storage pool associated with a resource */ +apr_pool_t *dav_fs_pool(const dav_resource *resource); + +/* return the full pathname for a resource */ +const char *dav_fs_pathname(const dav_resource *resource); + +/* return the directory and filename for a resource */ +dav_error * dav_fs_dir_file_name(const dav_resource *resource, + const char **dirpath, + const char **fname); + +/* return the list of locknull members in this resource's directory */ +dav_error * dav_fs_get_locknull_members(const dav_resource *resource, + dav_buffer *pbuf); + + +/* DBM functions used by the repository and locking providers */ +extern const dav_hooks_db dav_hooks_db_dbm; + +dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, + dav_db **pdb); +void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, + const char **state1, const char **state2); +dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key); +dav_error * dav_dbm_store(dav_db *db, apr_datum_t key, apr_datum_t value); +dav_error * dav_dbm_fetch(dav_db *db, apr_datum_t key, apr_datum_t *pvalue); +void dav_dbm_freedatum(dav_db *db, apr_datum_t data); +int dav_dbm_exists(dav_db *db, apr_datum_t key); +void dav_dbm_close(dav_db *db); + +/* where is the lock database located? */ +const char *dav_get_lockdb_path(const request_rec *r); + +const dav_hooks_locks *dav_fs_get_lock_hooks(request_rec *r); +const dav_hooks_propdb *dav_fs_get_propdb_hooks(request_rec *r); + +void dav_fs_gather_propsets(apr_array_header_t *uris); +int dav_fs_find_liveprop(const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks); +void dav_fs_insert_all_liveprops(request_rec *r, const dav_resource *resource, + dav_prop_insert what, apr_text_header *phdr); + +void dav_fs_register(apr_pool_t *p); + +#endif /* _DAV_FS_REPOS_H_ */ diff --git a/trunk/modules/dav/lock/Makefile.in b/trunk/modules/dav/lock/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/dav/lock/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/dav/lock/NWGNUmakefile b/trunk/modules/dav/lock/NWGNUmakefile new file mode 100644 index 0000000000..6036fab3b8 --- /dev/null +++ b/trunk/modules/dav/lock/NWGNUmakefile @@ -0,0 +1,261 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(AP_WORK)/modules/dav/main \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = modDAVLK + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) DAV Database Lock Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = modDAVLK Thread + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/moddavlk.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_dav_lock.o \ + $(OBJDIR)/locks.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + mod_dav \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + @../main/dav.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + dav_lock_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\moddavlk.nlm $(INSTALL)\Apache2\modules +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/dav/lock/config6.m4 b/trunk/modules/dav/lock/config6.m4 new file mode 100644 index 0000000000..bc35ee3c03 --- /dev/null +++ b/trunk/modules/dav/lock/config6.m4 @@ -0,0 +1,17 @@ +dnl modules enabled in this directory by default + +APACHE_MODPATH_INIT(dav/lock) + +dav_lock_objects="mod_dav_lock.lo locks.lo" + +case "$host" in + *os2*) + # OS/2 DLLs must resolve all symbols at build time + # and we need some from main DAV module + dav_lock_objects="$dav_lock_objects ../main/mod_dav.la" + ;; +esac + +APACHE_MODULE(dav_lock, DAV provider for generic locking, $dav_lock_objects, , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/dav/lock/locks.c b/trunk/modules/dav/lock/locks.c new file mode 100644 index 0000000000..a9eefeef66 --- /dev/null +++ b/trunk/modules/dav/lock/locks.c @@ -0,0 +1,1215 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Generic DAV lock implementation that a DAV provider can use. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_uuid.h" + +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_log.h" + +#include "mod_dav.h" + +#include "locks.h" + + +/* --------------------------------------------------------------- + * + * Lock database primitives + * + */ + +/* + * LOCK DATABASES + * + * Lockdiscovery information is stored in the single lock database specified + * by the DAVGenericLockDB directive. Information about this db is stored in + * the per-dir configuration. + * + * KEY + * + * The database is keyed by a key_type unsigned char (DAV_TYPE_FNAME) + * followed by full path. + * + * VALUE + * + * The value consists of a list of elements. + * DIRECT LOCK: [char (DAV_LOCK_DIRECT), + * char (dav_lock_scope), + * char (dav_lock_type), + * int depth, + * time_t expires, + * apr_uuid_t locktoken, + * char[] owner, + * char[] auth_user] + * + * INDIRECT LOCK: [char (DAV_LOCK_INDIRECT), + * apr_uuid_t locktoken, + * time_t expires, + * int key_size, + * char[] key] + * The key is to the collection lock that resulted in this indirect lock + */ + +#define DAV_TRUE 1 +#define DAV_FALSE 0 + +#define DAV_CREATE_LIST 23 +#define DAV_APPEND_LIST 24 + +/* Stored lock_discovery prefix */ +#define DAV_LOCK_DIRECT 1 +#define DAV_LOCK_INDIRECT 2 + +#define DAV_TYPE_FNAME 11 + +/* Use the opaquelock scheme for locktokens */ +struct dav_locktoken { + apr_uuid_t uuid; +}; +#define dav_compare_locktoken(plt1, plt2) \ + memcmp(&(plt1)->uuid, &(plt2)->uuid, sizeof((plt1)->uuid)) + + +/* ################################################################# + * ### keep these structures (internal) or move fully to dav_lock? + */ + +/* + * We need to reliably size the fixed-length portion of + * dav_lock_discovery; best to separate it into another + * struct for a convenient sizeof, unless we pack lock_discovery. + */ +typedef struct dav_lock_discovery_fixed +{ + char scope; + char type; + int depth; + time_t timeout; +} dav_lock_discovery_fixed; + +typedef struct dav_lock_discovery +{ + struct dav_lock_discovery_fixed f; + + dav_locktoken *locktoken; + const char *owner; /* owner field from activelock */ + const char *auth_user; /* authenticated user who created the lock */ + struct dav_lock_discovery *next; +} dav_lock_discovery; + +/* Indirect locks represent locks inherited from containing collections. + * They reference the lock token for the collection the lock is + * inherited from. A lock provider may also define a key to the + * inherited lock, for fast datbase lookup. The key is opaque outside + * the lock provider. + */ +typedef struct dav_lock_indirect +{ + dav_locktoken *locktoken; + apr_datum_t key; + struct dav_lock_indirect *next; + time_t timeout; +} dav_lock_indirect; + +/* ################################################################# */ + +/* + * Stored direct lock info - full lock_discovery length: + * prefix + Fixed length + lock token + 2 strings + 2 nulls (one for each + * string) + */ +#define dav_size_direct(a) (1 + sizeof(dav_lock_discovery_fixed) \ + + sizeof(apr_uuid_t) \ + + ((a)->owner ? strlen((a)->owner) : 0) \ + + ((a)->auth_user ? strlen((a)->auth_user) : 0) \ + + 2) + +/* Stored indirect lock info - lock token and apr_datum_t */ +#define dav_size_indirect(a) (1 + sizeof(apr_uuid_t) \ + + sizeof(time_t) \ + + sizeof(int) + (a)->key.dsize) + +/* + * The lockdb structure. + * + * The field may be NULL, meaning one of two things: + * 1) That we have not actually opened the underlying database (yet). The + * field should be false. + * 2) We opened it readonly and it wasn't present. + * + * The delayed opening (determined by ) makes creating a lockdb + * quick, while deferring the underlying I/O until it is actually required. + * + * We export the notion of a lockdb, but hide the details of it. Most + * implementations will use a database of some kind, but it is certainly + * possible that alternatives could be used. + */ +struct dav_lockdb_private +{ + request_rec *r; /* for accessing the uuid state */ + apr_pool_t *pool; /* a pool to use */ + const char *lockdb_path; /* where is the lock database? */ + + int opened; /* we opened the database */ + apr_dbm_t *db; /* if non-NULL, the lock database */ +}; + +typedef struct +{ + dav_lockdb pub; + dav_lockdb_private priv; +} dav_lockdb_combined; + +/* + * The private part of the lock structure. + */ +struct dav_lock_private +{ + apr_datum_t key; /* key into the lock database */ +}; +typedef struct +{ + dav_lock pub; + dav_lock_private priv; + dav_locktoken token; +} dav_lock_combined; + +/* + * This must be forward-declared so the open_lockdb function can use it. + */ +extern const dav_hooks_locks dav_hooks_locks_generic; + +static dav_error * dav_generic_dbm_new_error(apr_dbm_t *db, apr_pool_t *p, + apr_status_t status) +{ + int save_errno = errno; + int errcode; + const char *errstr; + dav_error *err; + char errbuf[200]; + + if (status == APR_SUCCESS) { + return NULL; + } + + /* There might not be a if we had problems creating it. */ + if (db == NULL) { + errcode = 1; + errstr = "Could not open property database."; + } + else { + (void) apr_dbm_geterror(db, &errcode, errbuf, sizeof(errbuf)); + errstr = apr_pstrdup(p, errbuf); + } + + err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, errcode, errstr); + err->save_errno = save_errno; + return err; +} + +/* internal function for creating locks */ +static dav_lock *dav_generic_alloc_lock(dav_lockdb *lockdb, apr_datum_t key, + const dav_locktoken *locktoken) +{ + dav_lock_combined *comb; + + comb = apr_pcalloc(lockdb->info->pool, sizeof(*comb)); + comb->pub.rectype = DAV_LOCKREC_DIRECT; + comb->pub.info = &comb->priv; + comb->priv.key = key; + + if (locktoken == NULL) { + comb->pub.locktoken = &comb->token; + apr_uuid_get(&comb->token.uuid); + } + else { + comb->pub.locktoken = locktoken; + } + + return &comb->pub; +} + +/* + * dav_generic_parse_locktoken + * + * Parse an opaquelocktoken URI into a locktoken. + */ +static dav_error * dav_generic_parse_locktoken(apr_pool_t *p, + const char *char_token, + dav_locktoken **locktoken_p) +{ + dav_locktoken *locktoken; + + if (ap_strstr_c(char_token, "opaquelocktoken:") != char_token) { + return dav_new_error(p, + HTTP_BAD_REQUEST, DAV_ERR_LOCK_UNK_STATE_TOKEN, + "The lock token uses an unknown State-token " + "format and could not be parsed."); + } + char_token += 16; + + locktoken = apr_pcalloc(p, sizeof(*locktoken)); + if (apr_uuid_parse(&locktoken->uuid, char_token)) { + return dav_new_error(p, HTTP_BAD_REQUEST, DAV_ERR_LOCK_PARSE_TOKEN, + "The opaquelocktoken has an incorrect format " + "and could not be parsed."); + } + + *locktoken_p = locktoken; + return NULL; +} + +/* + * dav_generic_format_locktoken + * + * Generate the URI for a locktoken + */ +static const char *dav_generic_format_locktoken(apr_pool_t *p, + const dav_locktoken *locktoken) +{ + char buf[APR_UUID_FORMATTED_LENGTH + 1]; + + apr_uuid_format(buf, &locktoken->uuid); + return apr_pstrcat(p, "opaquelocktoken:", buf, NULL); +} + +/* + * dav_generic_compare_locktoken + * + * Determine whether two locktokens are the same + */ +static int dav_generic_compare_locktoken(const dav_locktoken *lt1, + const dav_locktoken *lt2) +{ + return dav_compare_locktoken(lt1, lt2); +} + +/* + * dav_generic_really_open_lockdb: + * + * If the database hasn't been opened yet, then open the thing. + */ +static dav_error * dav_generic_really_open_lockdb(dav_lockdb *lockdb) +{ + dav_error *err; + apr_status_t status; + + if (lockdb->info->opened) { + return NULL; + } + + status = apr_dbm_open(&lockdb->info->db, lockdb->info->lockdb_path, + lockdb->ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, + APR_OS_DEFAULT, lockdb->info->pool); + + if (status) { + err = dav_generic_dbm_new_error(lockdb->info->db, lockdb->info->pool, + status); + return dav_push_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_OPENDB, + "Could not open the lock database.", + err); + } + + /* all right. it is opened now. */ + lockdb->info->opened = 1; + + return NULL; +} + +/* + * dav_generic_open_lockdb: + * + * "open" the lock database, as specified in the global server configuration. + * If force is TRUE, then the database is opened now, rather than lazily. + * + * Note that only one can be open read/write. + */ +static dav_error * dav_generic_open_lockdb(request_rec *r, int ro, int force, + dav_lockdb **lockdb) +{ + dav_lockdb_combined *comb; + + comb = apr_pcalloc(r->pool, sizeof(*comb)); + comb->pub.hooks = &dav_hooks_locks_generic; + comb->pub.ro = ro; + comb->pub.info = &comb->priv; + comb->priv.r = r; + comb->priv.pool = r->pool; + + comb->priv.lockdb_path = dav_generic_get_lockdb_path(r); + if (comb->priv.lockdb_path == NULL) { + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_NO_DB, + "A lock database was not specified with the " + "DAVGenericLockDB directive. One must be " + "specified to use the locking functionality."); + } + + /* done initializing. return it. */ + *lockdb = &comb->pub; + + if (force) { + /* ### add a higher-level comment? */ + return dav_generic_really_open_lockdb(*lockdb); + } + + return NULL; +} + +/* + * dav_generic_close_lockdb: + * + * Close it. Duh. + */ +static void dav_generic_close_lockdb(dav_lockdb *lockdb) +{ + if (lockdb->info->db != NULL) { + apr_dbm_close(lockdb->info->db); + } + lockdb->info->opened = 0; +} + +/* + * dav_generic_build_key + * + * Given a pathname, build a DAV_TYPE_FNAME lock database key. + */ +static apr_datum_t dav_generic_build_key(apr_pool_t *p, + const dav_resource *resource) +{ + apr_datum_t key; + const char *pathname = resource->uri; + + /* ### does this allocation have a proper lifetime? need to check */ + /* ### can we use a buffer for this? */ + + /* size is TYPE + pathname + null */ + key.dsize = strlen(pathname) + 2; + key.dptr = apr_palloc(p, key.dsize); + *key.dptr = DAV_TYPE_FNAME; + memcpy(key.dptr + 1, pathname, key.dsize - 1); + if (key.dptr[key.dsize - 2] == '/') + key.dptr[--key.dsize - 1] = '\0'; + return key; +} + +/* + * dav_generic_lock_expired: return 1 (true) if the given timeout is in the + * past or present (the lock has expired), or 0 (false) if in the future + * (the lock has not yet expired). + */ +static int dav_generic_lock_expired(time_t expires) +{ + return expires != DAV_TIMEOUT_INFINITE && time(NULL) >= expires; +} + +/* + * dav_generic_save_lock_record: Saves the lock information specified in the + * direct and indirect lock lists about path into the lock database. + * If direct and indirect == NULL, the key is removed. + */ +static dav_error * dav_generic_save_lock_record(dav_lockdb *lockdb, + apr_datum_t key, + dav_lock_discovery *direct, + dav_lock_indirect *indirect) +{ + dav_error *err; + apr_status_t status; + apr_datum_t val = { 0 }; + char *ptr; + dav_lock_discovery *dp = direct; + dav_lock_indirect *ip = indirect; + +#if DAV_DEBUG + if (lockdb->ro) { + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: the lockdb was opened " + "readonly, but an attempt to save locks was " + "performed."); + } +#endif + + if ((err = dav_generic_really_open_lockdb(lockdb)) != NULL) { + /* ### add a higher-level error? */ + return err; + } + + /* If nothing to save, delete key */ + if (dp == NULL && ip == NULL) { + /* don't fail if the key is not present */ + /* ### but what about other errors? */ + apr_dbm_delete(lockdb->info->db, key); + return NULL; + } + + while(dp) { + val.dsize += dav_size_direct(dp); + dp = dp->next; + } + while(ip) { + val.dsize += dav_size_indirect(ip); + ip = ip->next; + } + + /* ### can this be apr_palloc() ? */ + /* ### hmmm.... investigate the use of a buffer here */ + ptr = val.dptr = apr_pcalloc(lockdb->info->pool, val.dsize); + dp = direct; + ip = indirect; + + while(dp) { + /* Direct lock - lock_discovery struct follows */ + *ptr++ = DAV_LOCK_DIRECT; + memcpy(ptr, dp, sizeof(dp->f)); /* Fixed portion of struct */ + ptr += sizeof(dp->f); + memcpy(ptr, dp->locktoken, sizeof(*dp->locktoken)); + ptr += sizeof(*dp->locktoken); + if (dp->owner == NULL) { + *ptr++ = '\0'; + } + else { + memcpy(ptr, dp->owner, strlen(dp->owner) + 1); + ptr += strlen(dp->owner) + 1; + } + if (dp->auth_user == NULL) { + *ptr++ = '\0'; + } + else { + memcpy(ptr, dp->auth_user, strlen(dp->auth_user) + 1); + ptr += strlen(dp->auth_user) + 1; + } + + dp = dp->next; + } + + while(ip) { + /* Indirect lock prefix */ + *ptr++ = DAV_LOCK_INDIRECT; + + memcpy(ptr, ip->locktoken, sizeof(*ip->locktoken)); + ptr += sizeof(*ip->locktoken); + + memcpy(ptr, &ip->timeout, sizeof(ip->timeout)); + ptr += sizeof(ip->timeout); + + memcpy(ptr, &ip->key.dsize, sizeof(ip->key.dsize)); + ptr += sizeof(ip->key.dsize); + + memcpy(ptr, ip->key.dptr, ip->key.dsize); + ptr += ip->key.dsize; + + ip = ip->next; + } + + if ((status = apr_dbm_store(lockdb->info->db, key, val)) != APR_SUCCESS) { + /* ### more details? add an error_id? */ + err = dav_generic_dbm_new_error(lockdb->info->db, lockdb->info->pool, + status); + return dav_push_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_SAVE_LOCK, + "Could not save lock information.", + err); + } + + return NULL; +} + +/* + * dav_load_lock_record: Reads lock information about key from lock db; + * creates linked lists of the direct and indirect locks. + * + * If add_method = DAV_APPEND_LIST, the result will be appended to the + * head of the direct and indirect lists supplied. + * + * Passive lock removal: If lock has timed out, it will not be returned. + * ### How much "logging" does RFC 2518 require? + */ +static dav_error * dav_generic_load_lock_record(dav_lockdb *lockdb, + apr_datum_t key, + int add_method, + dav_lock_discovery **direct, + dav_lock_indirect **indirect) +{ + apr_pool_t *p = lockdb->info->pool; + dav_error *err; + apr_status_t status; + apr_size_t offset = 0; + int need_save = DAV_FALSE; + apr_datum_t val = { 0 }; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + + if (add_method != DAV_APPEND_LIST) { + *direct = NULL; + *indirect = NULL; + } + + if ((err = dav_generic_really_open_lockdb(lockdb)) != NULL) { + /* ### add a higher-level error? */ + return err; + } + + /* + * If we opened readonly and the db wasn't there, then there are no + * locks for this resource. Just exit. + */ + if (lockdb->info->db == NULL) { + return NULL; + } + + if ((status = apr_dbm_fetch(lockdb->info->db, key, &val)) != APR_SUCCESS) { + return dav_generic_dbm_new_error(lockdb->info->db, p, status); + } + + if (!val.dsize) { + return NULL; + } + + while (offset < val.dsize) { + switch (*(val.dptr + offset++)) { + case DAV_LOCK_DIRECT: + /* Create and fill a dav_lock_discovery structure */ + + dp = apr_pcalloc(p, sizeof(*dp)); + + /* Copy the dav_lock_discovery_fixed portion */ + memcpy(dp, val.dptr + offset, sizeof(dp->f)); + offset += sizeof(dp->f); + + /* Copy the lock token. */ + dp->locktoken = apr_palloc(p, sizeof(*dp->locktoken)); + memcpy(dp->locktoken, val.dptr + offset, sizeof(*dp->locktoken)); + offset += sizeof(*dp->locktoken); + + /* Do we have an owner field? */ + if (*(val.dptr + offset) == '\0') { + ++offset; + } + else { + apr_size_t len = strlen(val.dptr + offset); + dp->owner = apr_pstrmemdup(p, val.dptr + offset, len); + offset += len + 1; + } + + if (*(val.dptr + offset) == '\0') { + ++offset; + } + else { + apr_size_t len = strlen(val.dptr + offset); + dp->auth_user = apr_pstrmemdup(p, val.dptr + offset, len); + offset += len + 1; + } + + if (!dav_generic_lock_expired(dp->f.timeout)) { + dp->next = *direct; + *direct = dp; + } + else { + need_save = DAV_TRUE; + } + break; + + case DAV_LOCK_INDIRECT: + /* Create and fill a dav_lock_indirect structure */ + + ip = apr_pcalloc(p, sizeof(*ip)); + ip->locktoken = apr_palloc(p, sizeof(*ip->locktoken)); + memcpy(ip->locktoken, val.dptr + offset, sizeof(*ip->locktoken)); + offset += sizeof(*ip->locktoken); + memcpy(&ip->timeout, val.dptr + offset, sizeof(ip->timeout)); + offset += sizeof(ip->timeout); + /* length of datum */ + ip->key.dsize = *((int *) (val.dptr + offset)); + offset += sizeof(ip->key.dsize); + ip->key.dptr = apr_palloc(p, ip->key.dsize); + memcpy(ip->key.dptr, val.dptr + offset, ip->key.dsize); + offset += ip->key.dsize; + + if (!dav_generic_lock_expired(ip->timeout)) { + ip->next = *indirect; + *indirect = ip; + } + else { + need_save = DAV_TRUE; + } + + break; + + default: + apr_dbm_freedatum(lockdb->info->db, val); + + /* ### should use a computed_desc and insert corrupt token data */ + --offset; + return dav_new_error(p, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_CORRUPT_DB, + apr_psprintf(p, + "The lock database was found to " + "be corrupt. offset %" + APR_SIZE_T_FMT ", c=%02x", + offset, val.dptr[offset])); + } + } + + apr_dbm_freedatum(lockdb->info->db, val); + + /* Clean up this record if we found expired locks */ + /* + * ### shouldn't do this if we've been opened READONLY. elide the + * ### timed-out locks from the response, but don't save that info back + */ + if (need_save == DAV_TRUE) { + return dav_generic_save_lock_record(lockdb, key, *direct, *indirect); + } + + return NULL; +} + +/* resolve , returning <*direct> */ +static dav_error * dav_generic_resolve(dav_lockdb *lockdb, + dav_lock_indirect *indirect, + dav_lock_discovery **direct, + dav_lock_discovery **ref_dp, + dav_lock_indirect **ref_ip) +{ + dav_error *err; + dav_lock_discovery *dir; + dav_lock_indirect *ind; + + if ((err = dav_generic_load_lock_record(lockdb, indirect->key, + DAV_CREATE_LIST, + &dir, &ind)) != NULL) { + /* ### insert a higher-level description? */ + return err; + } + if (ref_dp != NULL) { + *ref_dp = dir; + *ref_ip = ind; + } + + for (; dir != NULL; dir = dir->next) { + if (!dav_compare_locktoken(indirect->locktoken, dir->locktoken)) { + *direct = dir; + return NULL; + } + } + + /* No match found (but we should have found one!) */ + + /* ### use a different description and/or error ID? */ + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_CORRUPT_DB, + "The lock database was found to be corrupt. " + "An indirect lock's direct lock could not " + "be found."); +} + +/* --------------------------------------------------------------- + * + * Property-related lock functions + * + */ + +/* + * dav_generic_get_supportedlock: Returns a static string for all + * supportedlock properties. I think we save more returning a static string + * than constructing it every time, though it might look cleaner. + */ +static const char *dav_generic_get_supportedlock(const dav_resource *resource) +{ + static const char supported[] = DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR; + + return supported; +} + +/* --------------------------------------------------------------- + * + * General lock functions + * + */ + +static dav_error * dav_generic_remove_locknull_state(dav_lockdb *lockdb, + const dav_resource *resource) +{ + /* We don't need to do anything. */ + return NULL; +} + +static dav_error * dav_generic_create_lock(dav_lockdb *lockdb, + const dav_resource *resource, + dav_lock **lock) +{ + apr_datum_t key; + + key = dav_generic_build_key(lockdb->info->pool, resource); + + *lock = dav_generic_alloc_lock(lockdb, key, NULL); + + (*lock)->is_locknull = !resource->exists; + + return NULL; +} + +static dav_error * dav_generic_get_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int calltype, + dav_lock **locks) +{ + apr_pool_t *p = lockdb->info->pool; + apr_datum_t key; + dav_error *err; + dav_lock *lock = NULL; + dav_lock *newlock; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + +#if DAV_DEBUG + if (calltype == DAV_GETLOCKS_COMPLETE) { + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: DAV_GETLOCKS_COMPLETE " + "is not yet supported"); + } +#endif + + key = dav_generic_build_key(p, resource); + if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + /* copy all direct locks to the result list */ + for (; dp != NULL; dp = dp->next) { + newlock = dav_generic_alloc_lock(lockdb, key, dp->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp->f.scope; + newlock->type = dp->f.type; + newlock->depth = dp->f.depth; + newlock->timeout = dp->f.timeout; + newlock->owner = dp->owner; + newlock->auth_user = dp->auth_user; + + /* hook into the result list */ + newlock->next = lock; + lock = newlock; + } + + /* copy all the indirect locks to the result list. resolve as needed. */ + for (; ip != NULL; ip = ip->next) { + newlock = dav_generic_alloc_lock(lockdb, ip->key, ip->locktoken); + newlock->is_locknull = !resource->exists; + + if (calltype == DAV_GETLOCKS_RESOLVED) { + err = dav_generic_resolve(lockdb, ip, &dp, NULL, NULL); + if (err != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + newlock->scope = dp->f.scope; + newlock->type = dp->f.type; + newlock->depth = dp->f.depth; + newlock->timeout = dp->f.timeout; + newlock->owner = dp->owner; + newlock->auth_user = dp->auth_user; + } + else { + /* DAV_GETLOCKS_PARTIAL */ + newlock->rectype = DAV_LOCKREC_INDIRECT_PARTIAL; + } + + /* hook into the result list */ + newlock->next = lock; + lock = newlock; + } + + *locks = lock; + return NULL; +} + +static dav_error * dav_generic_find_lock(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken, + int partial_ok, + dav_lock **lock) +{ + dav_error *err; + apr_datum_t key; + dav_lock_discovery *dp; + dav_lock_indirect *ip; + + *lock = NULL; + + key = dav_generic_build_key(lockdb->info->pool, resource); + if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + + for (; dp != NULL; dp = dp->next) { + if (!dav_compare_locktoken(locktoken, dp->locktoken)) { + *lock = dav_generic_alloc_lock(lockdb, key, locktoken); + (*lock)->is_locknull = !resource->exists; + (*lock)->scope = dp->f.scope; + (*lock)->type = dp->f.type; + (*lock)->depth = dp->f.depth; + (*lock)->timeout = dp->f.timeout; + (*lock)->owner = dp->owner; + (*lock)->auth_user = dp->auth_user; + return NULL; + } + } + + for (; ip != NULL; ip = ip->next) { + if (!dav_compare_locktoken(locktoken, ip->locktoken)) { + *lock = dav_generic_alloc_lock(lockdb, ip->key, locktoken); + (*lock)->is_locknull = !resource->exists; + + /* ### nobody uses the resolving right now! */ + if (partial_ok) { + (*lock)->rectype = DAV_LOCKREC_INDIRECT_PARTIAL; + } + else { + (*lock)->rectype = DAV_LOCKREC_INDIRECT; + if ((err = dav_generic_resolve(lockdb, ip, &dp, + NULL, NULL)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + (*lock)->scope = dp->f.scope; + (*lock)->type = dp->f.type; + (*lock)->depth = dp->f.depth; + (*lock)->timeout = dp->f.timeout; + (*lock)->owner = dp->owner; + (*lock)->auth_user = dp->auth_user; + } + return NULL; + } + } + + return NULL; +} + +static dav_error * dav_generic_has_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int *locks_present) +{ + dav_error *err; + apr_datum_t key; + + *locks_present = 0; + + if ((err = dav_generic_really_open_lockdb(lockdb)) != NULL) { + /* ### insert a higher-level error description */ + return err; + } + + /* + * If we opened readonly and the db wasn't there, then there are no + * locks for this resource. Just exit. + */ + if (lockdb->info->db == NULL) + return NULL; + + key = dav_generic_build_key(lockdb->info->pool, resource); + + *locks_present = apr_dbm_exists(lockdb->info->db, key); + + return NULL; +} + +static dav_error * dav_generic_append_locks(dav_lockdb *lockdb, + const dav_resource *resource, + int make_indirect, + const dav_lock *lock) +{ + apr_pool_t *p = lockdb->info->pool; + dav_error *err; + dav_lock_indirect *ip; + dav_lock_discovery *dp; + apr_datum_t key; + + key = dav_generic_build_key(lockdb->info->pool, resource); + + err = dav_generic_load_lock_record(lockdb, key, 0, &dp, &ip); + if (err != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* + * ### when we store the lock more directly, we need to update + * ### lock->rectype and lock->is_locknull + */ + + if (make_indirect) { + for (; lock != NULL; lock = lock->next) { + + /* ### this works for any rectype */ + dav_lock_indirect *newi = apr_pcalloc(p, sizeof(*newi)); + + /* ### shut off the const warning for now */ + newi->locktoken = (dav_locktoken *)lock->locktoken; + newi->timeout = lock->timeout; + newi->key = lock->info->key; + newi->next = ip; + ip = newi; + } + } + else { + for (; lock != NULL; lock = lock->next) { + /* create and link in the right kind of lock */ + + if (lock->rectype == DAV_LOCKREC_DIRECT) { + dav_lock_discovery *newd = apr_pcalloc(p, sizeof(*newd)); + + newd->f.scope = lock->scope; + newd->f.type = lock->type; + newd->f.depth = lock->depth; + newd->f.timeout = lock->timeout; + /* ### shut off the const warning for now */ + newd->locktoken = (dav_locktoken *)lock->locktoken; + newd->owner = lock->owner; + newd->auth_user = lock->auth_user; + newd->next = dp; + dp = newd; + } + else { + /* DAV_LOCKREC_INDIRECT(_PARTIAL) */ + + dav_lock_indirect *newi = apr_pcalloc(p, sizeof(*newi)); + + /* ### shut off the const warning for now */ + newi->locktoken = (dav_locktoken *)lock->locktoken; + newi->key = lock->info->key; + newi->next = ip; + ip = newi; + } + } + } + + if ((err = dav_generic_save_lock_record(lockdb, key, dp, ip)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + return NULL; +} + +static dav_error * dav_generic_remove_lock(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken) +{ + dav_error *err; + dav_lock_discovery *dh = NULL; + dav_lock_indirect *ih = NULL; + apr_datum_t key; + + key = dav_generic_build_key(lockdb->info->pool, resource); + + if (locktoken != NULL) { + dav_lock_discovery *dp; + dav_lock_discovery *dprev = NULL; + dav_lock_indirect *ip; + dav_lock_indirect *iprev = NULL; + + if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dh, &ih)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + for (dp = dh; dp != NULL; dp = dp->next) { + if (dav_compare_locktoken(locktoken, dp->locktoken) == 0) { + if (dprev) + dprev->next = dp->next; + else + dh = dh->next; + } + dprev = dp; + } + + for (ip = ih; ip != NULL; ip = ip->next) { + if (dav_compare_locktoken(locktoken, ip->locktoken) == 0) { + if (iprev) + iprev->next = ip->next; + else + ih = ih->next; + } + iprev = ip; + } + + } + + /* save the modified locks, or remove all locks (dh=ih=NULL). */ + if ((err = dav_generic_save_lock_record(lockdb, key, dh, ih)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + return NULL; +} + +static int dav_generic_do_refresh(dav_lock_discovery *dp, + const dav_locktoken_list *ltl, + time_t new_time) +{ + int dirty = 0; + + for (; ltl != NULL; ltl = ltl->next) { + if (dav_compare_locktoken(dp->locktoken, ltl->locktoken) == 0) + { + dp->f.timeout = new_time; + dirty = 1; + } + } + + return dirty; +} + +static dav_error * dav_generic_refresh_locks(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken_list *ltl, + time_t new_time, + dav_lock **locks) +{ + dav_error *err; + apr_datum_t key; + dav_lock_discovery *dp; + dav_lock_discovery *dp_scan; + dav_lock_indirect *ip; + int dirty = 0; + dav_lock *newlock; + + *locks = NULL; + + key = dav_generic_build_key(lockdb->info->pool, resource); + if ((err = dav_generic_load_lock_record(lockdb, key, DAV_CREATE_LIST, + &dp, &ip)) != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* ### we should be refreshing direct AND (resolved) indirect locks! */ + + /* refresh all of the direct locks on this resource */ + for (dp_scan = dp; dp_scan != NULL; dp_scan = dp_scan->next) { + if (dav_generic_do_refresh(dp_scan, ltl, new_time)) { + /* the lock was refreshed. return the lock. */ + newlock = dav_generic_alloc_lock(lockdb, key, dp_scan->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp_scan->f.scope; + newlock->type = dp_scan->f.type; + newlock->depth = dp_scan->f.depth; + newlock->timeout = dp_scan->f.timeout; + newlock->owner = dp_scan->owner; + newlock->auth_user = dp_scan->auth_user; + + newlock->next = *locks; + *locks = newlock; + + dirty = 1; + } + } + + /* if we refreshed any locks, then save them back. */ + if (dirty + && (err = dav_generic_save_lock_record(lockdb, key, dp, ip)) != NULL) { + /* ### maybe add in a higher-level description */ + return err; + } + + /* for each indirect lock, find its direct lock and refresh it. */ + for (; ip != NULL; ip = ip->next) { + dav_lock_discovery *ref_dp; + dav_lock_indirect *ref_ip; + + if ((err = dav_generic_resolve(lockdb, ip, &dp_scan, + &ref_dp, &ref_ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + if (dav_generic_do_refresh(dp_scan, ltl, new_time)) { + /* the lock was refreshed. return the lock. */ + newlock = dav_generic_alloc_lock(lockdb, ip->key, dp->locktoken); + newlock->is_locknull = !resource->exists; + newlock->scope = dp->f.scope; + newlock->type = dp->f.type; + newlock->depth = dp->f.depth; + newlock->timeout = dp->f.timeout; + newlock->owner = dp->owner; + newlock->auth_user = dp_scan->auth_user; + + newlock->next = *locks; + *locks = newlock; + + /* save the (resolved) direct lock back */ + if ((err = dav_generic_save_lock_record(lockdb, ip->key, ref_dp, + ref_ip)) != NULL) { + /* ### push a higher-level desc? */ + return err; + } + } + } + + return NULL; +} + + +const dav_hooks_locks dav_hooks_locks_generic = +{ + dav_generic_get_supportedlock, + dav_generic_parse_locktoken, + dav_generic_format_locktoken, + dav_generic_compare_locktoken, + dav_generic_open_lockdb, + dav_generic_close_lockdb, + dav_generic_remove_locknull_state, + dav_generic_create_lock, + dav_generic_get_locks, + dav_generic_find_lock, + dav_generic_has_locks, + dav_generic_append_locks, + dav_generic_remove_lock, + dav_generic_refresh_locks, + NULL, /* lookup_resource */ + + NULL /* ctx */ +}; diff --git a/trunk/modules/dav/lock/locks.h b/trunk/modules/dav/lock/locks.h new file mode 100644 index 0000000000..71f59974ee --- /dev/null +++ b/trunk/modules/dav/lock/locks.h @@ -0,0 +1,27 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** Declarations for the generic lock implementation +*/ + +#ifndef _DAV_LOCK_LOCKS_H_ +#define _DAV_LOCK_LOCKS_H_ + +/* where is the lock database located? */ +const char *dav_generic_get_lockdb_path(const request_rec *r); + +#endif /* _DAV_LOCK_LOCKS_H_ */ diff --git a/trunk/modules/dav/lock/mod_dav_lock.c b/trunk/modules/dav/lock/mod_dav_lock.c new file mode 100644 index 0000000000..08019a907b --- /dev/null +++ b/trunk/modules/dav/lock/mod_dav_lock.c @@ -0,0 +1,104 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "apr_strings.h" +#include "ap_provider.h" + +#include "mod_dav.h" +#include "locks.h" + +/* per-dir configuration */ +typedef struct { + const char *lockdb_path; +} dav_lock_dir_conf; + +extern const dav_hooks_locks dav_hooks_locks_generic; + +extern module AP_MODULE_DECLARE_DATA dav_lock_module; + +const char *dav_generic_get_lockdb_path(const request_rec *r) +{ + dav_lock_dir_conf *conf; + + conf = ap_get_module_config(r->per_dir_config, &dav_lock_module); + return conf->lockdb_path; +} + +static void *dav_lock_create_dir_config(apr_pool_t *p, char *dir) +{ + return apr_pcalloc(p, sizeof(dav_lock_dir_conf)); +} + +static void *dav_lock_merge_dir_config(apr_pool_t *p, + void *base, void *overrides) +{ + dav_lock_dir_conf *parent = base; + dav_lock_dir_conf *child = overrides; + dav_lock_dir_conf *newconf; + + newconf = apr_pcalloc(p, sizeof(*newconf)); + + newconf->lockdb_path = + child->lockdb_path ? child->lockdb_path : parent->lockdb_path; + + return newconf; +} + +/* + * Command handler for the DAVGenericLockDB directive, which is TAKE1 + */ +static const char *dav_lock_cmd_davlockdb(cmd_parms *cmd, void *config, + const char *arg1) +{ + dav_lock_dir_conf *conf = config; + + conf->lockdb_path = ap_server_root_relative(cmd->pool, arg1); + + if (!conf->lockdb_path) { + return apr_pstrcat(cmd->pool, "Invalid DAVGenericLockDB path ", + arg1, NULL); + } + + return NULL; +} + +static const command_rec dav_lock_cmds[] = +{ + /* per server */ + AP_INIT_TAKE1("DAVGenericLockDB", dav_lock_cmd_davlockdb, NULL, ACCESS_CONF, + "specify a lock database"), + + { NULL } +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_provider(p, "dav-lock", "generic", "0", + &dav_hooks_locks_generic); +} + +module AP_MODULE_DECLARE_DATA dav_lock_module = +{ + STANDARD20_MODULE_STUFF, + dav_lock_create_dir_config, /* dir config creater */ + dav_lock_merge_dir_config, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + dav_lock_cmds, /* command table */ + register_hooks, /* register hooks */ +}; diff --git a/trunk/modules/dav/main/Makefile.in b/trunk/modules/dav/main/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/dav/main/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/dav/main/NWGNUmakefile b/trunk/modules/dav/main/NWGNUmakefile new file mode 100644 index 0000000000..9fc46c030d --- /dev/null +++ b/trunk/modules/dav/main/NWGNUmakefile @@ -0,0 +1,271 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(APR)/include \ + $(APRUTIL)/include \ + $(AP_WORK)/include \ + $(AP_WORK)/os/NetWare \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/srclib/pcre \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_DAV + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) DAV module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = mod_DAV + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_dav.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_dav.o \ + $(OBJDIR)/props.o \ + $(OBJDIR)/util.o \ + $(OBJDIR)/util_lock.o \ + $(OBJDIR)/liveprop.o \ + $(OBJDIR)/providers.o \ + $(OBJDIR)/std_liveprop.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + dav_module \ + @dav.imp \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\mod_dav.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/dav/main/config5.m4 b/trunk/modules/dav/main/config5.m4 new file mode 100644 index 0000000000..fa2eee4762 --- /dev/null +++ b/trunk/modules/dav/main/config5.m4 @@ -0,0 +1,22 @@ +dnl modules enabled in this directory by default + +APACHE_MODPATH_INIT(dav/main) + +dav_objects="mod_dav.lo props.lo util.lo util_lock.lo liveprop.lo providers.lo std_liveprop.lo" + +if test "$enable_http" = "no"; then + dav_enable=no +else + dav_enable=most +fi + +APACHE_MODULE(dav, WebDAV protocol handling, $dav_objects, , $dav_enable) + +if test "$dav_enable" != "no" -o "$enable_dav" != "no"; then + apache_need_expat=yes + + APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) +fi + + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/dav/main/dav.imp b/trunk/modules/dav/main/dav.imp new file mode 100644 index 0000000000..88b306da4b --- /dev/null +++ b/trunk/modules/dav/main/dav.imp @@ -0,0 +1,64 @@ + + (mod_dav) + dav_add_all_liveprop_xmlns, + dav_add_lock, + dav_add_response, + dav_add_vary_header, + dav_auto_checkin, + dav_auto_checkout, + dav_buffer_append, + dav_buffer_init, + dav_buffer_place, + dav_buffer_place_mem, + dav_check_bufsize, + dav_close_propdb, + dav_core_find_liveprop, + dav_core_insert_all_liveprops, + dav_core_register_uris, + dav_do_find_liveprop, + dav_find_child, + dav_get_allprops, + dav_get_binding_hooks, + dav_get_depth, + dav_get_liveprop_info, + dav_get_liveprop_ns_count, + dav_get_liveprop_ns_index, + dav_get_liveprop_supported, + dav_get_lock_hooks, + dav_get_locktoken_list, + dav_get_propdb_hooks, + dav_get_props, + dav_get_resource_state, + dav_get_search_hooks, + dav_get_timeout, + dav_get_vsn_hooks, + dav_hook_find_liveprop, + dav_hook_gather_propsets, + dav_hook_insert_all_liveprops, + dav_lock_get_activelock, + dav_lock_parse_lockinfo, + dav_lock_query, + dav_lookup_provider, + dav_lookup_uri, + dav_new_error, + dav_new_error_tag, + dav_notify_created, + dav_open_propdb, + dav_prop_commit, + dav_prop_exec, + dav_prop_rollback, + dav_prop_validate, + dav_push_error, + dav_register_liveprop_group, + dav_register_provider, + dav_set_bufsize, + dav_unlock, + dav_validate_request, + dav_validate_root, + dav_xml_get_cdata, + dav_xmlns_add, + dav_xmlns_add_uri, + dav_xmlns_create, + dav_xmlns_generate, + dav_xmlns_get_prefix, + dav_xmlns_get_uri diff --git a/trunk/modules/dav/main/liveprop.c b/trunk/modules/dav/main/liveprop.c new file mode 100644 index 0000000000..ed7e30ce75 --- /dev/null +++ b/trunk/modules/dav/main/liveprop.c @@ -0,0 +1,140 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_pools.h" +#include "apr_hash.h" +#include "apr_errno.h" +#include "apr_strings.h" +#include "util_xml.h" /* for apr_text_header */ +#include "mod_dav.h" + + +static apr_hash_t *dav_liveprop_uris = NULL; +static int dav_liveprop_count = 0; + + +static apr_status_t dav_cleanup_liveprops(void *ctx) +{ + dav_liveprop_uris = NULL; + dav_liveprop_count = 0; + return APR_SUCCESS; +} + +static void dav_register_liveprop_namespace(apr_pool_t *p, const char *uri) +{ + int value; + + if (dav_liveprop_uris == NULL) { + dav_liveprop_uris = apr_hash_make(p); + apr_pool_cleanup_register(p, NULL, dav_cleanup_liveprops, apr_pool_cleanup_null); + } + + value = (int)apr_hash_get(dav_liveprop_uris, uri, APR_HASH_KEY_STRING); + if (value != 0) { + /* already registered */ + return; + } + + /* start at 1, and count up */ + apr_hash_set(dav_liveprop_uris, uri, APR_HASH_KEY_STRING, + (void *)++dav_liveprop_count); +} + +DAV_DECLARE(int) dav_get_liveprop_ns_index(const char *uri) +{ + return (int)apr_hash_get(dav_liveprop_uris, uri, APR_HASH_KEY_STRING); +} + +DAV_DECLARE(int) dav_get_liveprop_ns_count(void) +{ + return dav_liveprop_count; +} + +DAV_DECLARE(void) dav_add_all_liveprop_xmlns(apr_pool_t *p, + apr_text_header *phdr) +{ + apr_hash_index_t *idx = apr_hash_first(p, dav_liveprop_uris); + + for ( ; idx != NULL; idx = apr_hash_next(idx) ) { + const void *key; + void *val; + const char *s; + + apr_hash_this(idx, &key, NULL, &val); + + s = apr_psprintf(p, " xmlns:lp%d=\"%s\"", (int)val, (const char *)key); + apr_text_append(p, phdr, s); + } +} + +DAV_DECLARE(int) dav_do_find_liveprop(const char *ns_uri, const char *name, + const dav_liveprop_group *group, + const dav_hooks_liveprop **hooks) +{ + const char * const *uris = group->namespace_uris; + const dav_liveprop_spec *scan; + int ns; + + /* first: locate the namespace in the namespace table */ + for (ns = 0; uris[ns] != NULL; ++ns) + if (strcmp(ns_uri, uris[ns]) == 0) + break; + if (uris[ns] == NULL) { + /* not our property (the namespace matched none of ours) */ + return 0; + } + + /* second: look for the property in the liveprop specs */ + for (scan = group->specs; scan->name != NULL; ++scan) + if (ns == scan->ns && strcmp(name, scan->name) == 0) { + *hooks = group->hooks; + return scan->propid; + } + + /* not our property (same namespace, but no matching prop name) */ + return 0; +} + +DAV_DECLARE(int) dav_get_liveprop_info(int propid, + const dav_liveprop_group *group, + const dav_liveprop_spec **info) +{ + const dav_liveprop_spec *scan; + + for (scan = group->specs; scan->name != NULL; ++scan) { + if (scan->propid == propid) { + *info = scan; + + /* map the provider-local NS into a global NS index */ + return dav_get_liveprop_ns_index(group->namespace_uris[scan->ns]); + } + } + + /* assert: should not reach this point */ + *info = NULL; + return 0; +} + +DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *p, + const dav_liveprop_group *group) +{ + /* register the namespace URIs */ + const char * const * uris = group->namespace_uris; + + for ( ; *uris != NULL; ++uris) { + dav_register_liveprop_namespace(p, *uris); + } +} diff --git a/trunk/modules/dav/main/mod_dav.c b/trunk/modules/dav/main/mod_dav.c new file mode 100644 index 0000000000..47dfab0039 --- /dev/null +++ b/trunk/modules/dav/main/mod_dav.c @@ -0,0 +1,4852 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * DAV extension module for Apache 2.0.* + * + * This module is repository-independent. It depends on hooks provided by a + * repository implementation. + * + * APACHE ISSUES: + * - within a DAV hierarchy, if an unknown method is used and we default + * to Apache's implementation, it sends back an OPTIONS with the wrong + * set of methods -- there is NO HOOK for us. + * therefore: we need to manually handle the HTTP_METHOD_NOT_ALLOWED + * and HTTP_NOT_IMPLEMENTED responses (not ap_send_error_response). + * - process_mkcol_body() had to dup code from ap_setup_client_block(). + * - it would be nice to get status lines from Apache for arbitrary + * status codes + * - it would be nice to be able to extend Apache's set of response + * codes so that it doesn't return 500 when an unknown code is placed + * into r->status. + * - http_vhost functions should apply "const" to their params + * + * DESIGN NOTES: + * - For PROPFIND, we batch up the entire response in memory before + * sending it. We may want to reorganize around sending the information + * as we suck it in from the propdb. Alternatively, we should at least + * generate a total Content-Length if we're going to buffer in memory + * so that we can keep the connection open. + */ + +#include "apr_strings.h" +#include "apr_lib.h" /* for apr_is* */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "http_request.h" +#include "util_script.h" + +#include "mod_dav.h" + + +/* ### what is the best way to set this? */ +#define DAV_DEFAULT_PROVIDER "filesystem" + +/* used to denote that mod_dav will be handling this request */ +#define DAV_HANDLER_NAME "dav-handler" + +enum { + DAV_ENABLED_UNSET = 0, + DAV_ENABLED_OFF, + DAV_ENABLED_ON +}; + +/* per-dir configuration */ +typedef struct { + const char *provider_name; + const dav_provider *provider; + const char *dir; + int locktimeout; + int allow_depthinfinity; + +} dav_dir_conf; + +/* per-server configuration */ +typedef struct { + int unused; + +} dav_server_conf; + +#define DAV_INHERIT_VALUE(parent, child, field) \ + ((child)->field ? (child)->field : (parent)->field) + + +/* forward-declare for use in configuration lookup */ +extern module DAV_DECLARE_DATA dav_module; + +/* DAV methods */ +enum { + DAV_M_BIND = 0, + DAV_M_SEARCH, + DAV_M_LAST +}; +static int dav_methods[DAV_M_LAST]; + + +static int dav_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, + server_rec *s) +{ + /* DBG0("dav_init_handler"); */ + + /* Register DAV methods */ + dav_methods[DAV_M_BIND] = ap_method_register(p, "BIND"); + dav_methods[DAV_M_SEARCH] = ap_method_register(p, "SEARCH"); + + ap_add_version_component(p, "DAV/2"); + + return OK; +} + +static void *dav_create_server_config(apr_pool_t *p, server_rec *s) +{ + dav_server_conf *newconf; + + newconf = (dav_server_conf *)apr_pcalloc(p, sizeof(*newconf)); + + /* ### this isn't used at the moment... */ + + return newconf; +} + +static void *dav_merge_server_config(apr_pool_t *p, void *base, void *overrides) +{ +#if 0 + dav_server_conf *child = overrides; +#endif + dav_server_conf *newconf; + + newconf = (dav_server_conf *)apr_pcalloc(p, sizeof(*newconf)); + + /* ### nothing to merge right now... */ + + return newconf; +} + +static void *dav_create_dir_config(apr_pool_t *p, char *dir) +{ + /* NOTE: dir==NULL creates the default per-dir config */ + + dav_dir_conf *conf; + + conf = (dav_dir_conf *)apr_pcalloc(p, sizeof(*conf)); + + /* clean up the directory to remove any trailing slash */ + if (dir != NULL) { + char *d; + apr_size_t l; + + d = apr_pstrdup(p, dir); + l = strlen(d); + if (l > 1 && d[l - 1] == '/') + d[l - 1] = '\0'; + conf->dir = d; + } + + return conf; +} + +static void *dav_merge_dir_config(apr_pool_t *p, void *base, void *overrides) +{ + dav_dir_conf *parent = base; + dav_dir_conf *child = overrides; + dav_dir_conf *newconf = (dav_dir_conf *)apr_pcalloc(p, sizeof(*newconf)); + + /* DBG3("dav_merge_dir_config: new=%08lx base=%08lx overrides=%08lx", + (long)newconf, (long)base, (long)overrides); */ + + newconf->provider_name = DAV_INHERIT_VALUE(parent, child, provider_name); + newconf->provider = DAV_INHERIT_VALUE(parent, child, provider); + if (parent->provider_name != NULL) { + if (child->provider_name == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "\"DAV Off\" cannot be used to turn off a subtree " + "of a DAV-enabled location."); + } + else if (strcasecmp(child->provider_name, + parent->provider_name) != 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "A subtree cannot specify a different DAV provider " + "than its parent."); + } + } + + newconf->locktimeout = DAV_INHERIT_VALUE(parent, child, locktimeout); + newconf->dir = DAV_INHERIT_VALUE(parent, child, dir); + newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child, + allow_depthinfinity); + + return newconf; +} + +static const dav_provider *dav_get_provider(request_rec *r) +{ + dav_dir_conf *conf; + + conf = ap_get_module_config(r->per_dir_config, &dav_module); + /* assert: conf->provider_name != NULL + (otherwise, DAV is disabled, and we wouldn't be here) */ + + /* assert: conf->provider != NULL + (checked when conf->provider_name is set) */ + return conf->provider; +} + +DAV_DECLARE(const dav_hooks_locks *) dav_get_lock_hooks(request_rec *r) +{ + return dav_get_provider(r)->locks; +} + +DAV_DECLARE(const dav_hooks_propdb *) dav_get_propdb_hooks(request_rec *r) +{ + return dav_get_provider(r)->propdb; +} + +DAV_DECLARE(const dav_hooks_vsn *) dav_get_vsn_hooks(request_rec *r) +{ + return dav_get_provider(r)->vsn; +} + +DAV_DECLARE(const dav_hooks_binding *) dav_get_binding_hooks(request_rec *r) +{ + return dav_get_provider(r)->binding; +} + +DAV_DECLARE(const dav_hooks_search *) dav_get_search_hooks(request_rec *r) +{ + return dav_get_provider(r)->search; +} + +/* + * Command handler for the DAV directive, which is TAKE1. + */ +static const char *dav_cmd_dav(cmd_parms *cmd, void *config, const char *arg1) +{ + dav_dir_conf *conf = (dav_dir_conf *)config; + + if (strcasecmp(arg1, "on") == 0) { + conf->provider_name = DAV_DEFAULT_PROVIDER; + } + else if (strcasecmp(arg1, "off") == 0) { + conf->provider_name = NULL; + conf->provider = NULL; + } + else { + conf->provider_name = apr_pstrdup(cmd->pool, arg1); + } + + if (conf->provider_name != NULL) { + /* lookup and cache the actual provider now */ + conf->provider = dav_lookup_provider(conf->provider_name); + + if (conf->provider == NULL) { + /* by the time they use it, the provider should be loaded and + registered with us. */ + return apr_psprintf(cmd->pool, + "Unknown DAV provider: %s", + conf->provider_name); + } + } + + return NULL; +} + +/* + * Command handler for the DAVDepthInfinity directive, which is FLAG. + */ +static const char *dav_cmd_davdepthinfinity(cmd_parms *cmd, void *config, + int arg) +{ + dav_dir_conf *conf = (dav_dir_conf *)config; + + if (arg) + conf->allow_depthinfinity = DAV_ENABLED_ON; + else + conf->allow_depthinfinity = DAV_ENABLED_OFF; + return NULL; +} + +/* + * Command handler for DAVMinTimeout directive, which is TAKE1 + */ +static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config, + const char *arg1) +{ + dav_dir_conf *conf = (dav_dir_conf *)config; + + conf->locktimeout = atoi(arg1); + if (conf->locktimeout < 0) + return "DAVMinTimeout requires a non-negative integer."; + + return NULL; +} + +/* +** dav_error_response() +** +** Send a nice response back to the user. In most cases, Apache doesn't +** allow us to provide details in the body about what happened. This +** function allows us to completely specify the response body. +** +** ### this function is not logging any errors! (e.g. the body) +*/ +static int dav_error_response(request_rec *r, int status, const char *body) +{ + r->status = status; + + /* ### I really don't think this is needed; gotta test */ + r->status_line = ap_get_status_line(status); + + ap_set_content_type(r, "text/html"); + + /* begin the response now... */ + ap_rvputs(r, + DAV_RESPONSE_BODY_1, + r->status_line, + DAV_RESPONSE_BODY_2, + &r->status_line[4], + DAV_RESPONSE_BODY_3, + body, + DAV_RESPONSE_BODY_4, + ap_psignature("
    \n", r), + DAV_RESPONSE_BODY_5, + NULL); + + /* the response has been sent. */ + /* + * ### Use of DONE obviates logging..! + */ + return DONE; +} + + +/* + * Send a "standardized" error response based on the error's namespace & tag + */ +static int dav_error_response_tag(request_rec *r, + dav_error *err) +{ + r->status = err->status; + + /* ### I really don't think this is needed; gotta test */ + r->status_line = ap_get_status_line(err->status); + + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + ap_rputs(DAV_XML_HEADER DEBUG_CR + "desc != NULL) { + /* ### should move this namespace somewhere (with the others!) */ + ap_rputs(" xmlns:m=\"http://apache.org/dav/xmlns\"", r); + } + + if (err->namespace != NULL) { + ap_rprintf(r, + " xmlns:C=\"%s\">" DEBUG_CR + "" DEBUG_CR, + err->namespace, err->tagname); + } + else { + ap_rprintf(r, + ">" DEBUG_CR + "" DEBUG_CR, err->tagname); + } + + /* here's our mod_dav specific tag: */ + if (err->desc != NULL) { + ap_rprintf(r, + "" DEBUG_CR + "%s" DEBUG_CR + "" DEBUG_CR, + err->error_id, + apr_xml_quote_string(r->pool, err->desc, 0)); + } + + ap_rputs("" DEBUG_CR, r); + + /* the response has been sent. */ + /* + * ### Use of DONE obviates logging..! + */ + return DONE; +} + + +/* + * Apache's URI escaping does not replace '&' since that is a valid character + * in a URI (to form a query section). We must explicitly handle it so that + * we can embed the URI into an XML document. + */ +static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri) +{ + const char *e_uri = ap_escape_uri(p, uri); + + /* check the easy case... */ + if (ap_strchr_c(e_uri, '&') == NULL) + return e_uri; + + /* there was a '&', so more work is needed... sigh. */ + + /* + * Note: this is a teeny bit of overkill since we know there are no + * '<' or '>' characters, but who cares. + */ + return apr_xml_quote_string(p, e_uri, 0); +} + + +/* Write a complete RESPONSE object out as a xml + element. Data is sent into brigade BB, which is auto-flushed into + OUTPUT filter stack. Use POOL for any temporary allocations. + + [Presumably the tag has already been written; this + routine is shared by dav_send_multistatus and dav_stream_response.] +*/ +static void dav_send_one_response(dav_response *response, + apr_bucket_brigade *bb, + ap_filter_t *output, + apr_pool_t *pool) +{ + apr_text *t = NULL; + + if (response->propresult.xmlns == NULL) { + ap_fputs(output, bb, ""); + } + else { + ap_fputs(output, bb, "propresult.xmlns; t; t = t->next) { + ap_fputs(output, bb, t->text); + } + ap_fputc(output, bb, '>'); + } + + ap_fputstrs(output, bb, + DEBUG_CR "", + dav_xml_escape_uri(pool, response->href), + "" DEBUG_CR, + NULL); + + if (response->propresult.propstats == NULL) { + /* use the Status-Line text from Apache. Note, this will + * default to 500 Internal Server Error if first->status + * is not a known (or valid) status code. + */ + ap_fputstrs(output, bb, + "HTTP/1.1 ", + ap_get_status_line(response->status), + "" DEBUG_CR, + NULL); + } + else { + /* assume this includes and is quoted properly */ + for (t = response->propresult.propstats; t; t = t->next) { + ap_fputs(output, bb, t->text); + } + } + + if (response->desc != NULL) { + /* + * We supply the description, so we know it doesn't have to + * have any escaping/encoding applied to it. + */ + ap_fputstrs(output, bb, + "", + response->desc, + "" DEBUG_CR, + NULL); + } + + ap_fputs(output, bb, "" DEBUG_CR); +} + + +/* Factorized helper function: prep request_rec R for a multistatus + response and write tag into BB, destined for + R->output_filters. Use xml NAMESPACES in initial tag, if + non-NULL. */ +static void dav_begin_multistatus(apr_bucket_brigade *bb, + request_rec *r, int status, + apr_array_header_t *namespaces) +{ + /* Set the correct status and Content-Type */ + r->status = status; + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + /* Send the headers and actual multistatus response now... */ + ap_fputs(r->output_filters, bb, DAV_XML_HEADER DEBUG_CR + "nelts; i--; ) { + ap_fprintf(r->output_filters, bb, " xmlns:ns%d=\"%s\"", i, + APR_XML_GET_URI_ITEM(namespaces, i)); + } + } + + ap_fputs(r->output_filters, bb, ">" DEBUG_CR); +} + +/* Finish a multistatus response started by dav_begin_multistatus: */ +static apr_status_t dav_finish_multistatus(request_rec *r, + apr_bucket_brigade *bb) +{ + apr_bucket *b; + + ap_fputs(r->output_filters, bb, "" DEBUG_CR); + + /* indicate the end of the response body */ + b = apr_bucket_eos_create(r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + /* deliver whatever might be remaining in the brigade */ + return ap_pass_brigade(r->output_filters, bb); +} + +static void dav_send_multistatus(request_rec *r, int status, + dav_response *first, + apr_array_header_t *namespaces) +{ + apr_pool_t *subpool; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, + r->connection->bucket_alloc); + + dav_begin_multistatus(bb, r, status, namespaces); + + apr_pool_create(&subpool, r->pool); + + for (; first != NULL; first = first->next) { + apr_pool_clear(subpool); + dav_send_one_response(first, bb, r->output_filters, subpool); + } + apr_pool_destroy(subpool); + + dav_finish_multistatus(r, bb); +} + +/* + * dav_log_err() + * + * Write error information to the log. + */ +static void dav_log_err(request_rec *r, dav_error *err, int level) +{ + dav_error *errscan; + + /* Log the errors */ + /* ### should have a directive to log the first or all */ + for (errscan = err; errscan != NULL; errscan = errscan->prev) { + if (errscan->desc == NULL) + continue; + + if (errscan->save_errno != 0) { + errno = errscan->save_errno; + ap_log_rerror(APLOG_MARK, level, errno, r, "%s [%d, #%d]", + errscan->desc, errscan->status, errscan->error_id); + } + else { + ap_log_rerror(APLOG_MARK, level, 0, r, + "%s [%d, #%d]", + errscan->desc, errscan->status, errscan->error_id); + } + } +} + +/* + * dav_handle_err() + * + * Handle the standard error processing. must be non-NULL. + * + * is set by the following: + * - dav_validate_request() + * - dav_add_lock() + * - repos_hooks->remove_resource + * - repos_hooks->move_resource + * - repos_hooks->copy_resource + * - vsn_hooks->update + */ +static int dav_handle_err(request_rec *r, dav_error *err, + dav_response *response) +{ + /* log the errors */ + dav_log_err(r, err, APLOG_ERR); + + if (response == NULL) { + dav_error *stackerr = err; + + /* our error messages are safe; tell Apache this */ + apr_table_setn(r->notes, "verbose-error-to", "*"); + + /* Didn't get a multistatus response passed in, but we still + might be able to generate a standard response. + Search the error stack for an errortag. */ + while (stackerr != NULL && stackerr->tagname == NULL) + stackerr = stackerr->prev; + + if (stackerr != NULL && stackerr->tagname != NULL) + return dav_error_response_tag(r, stackerr); + + return err->status; + } + + /* send the multistatus and tell Apache the request/response is DONE. */ + dav_send_multistatus(r, err->status, response, NULL); + return DONE; +} + +/* handy function for return values of methods that (may) create things */ +static int dav_created(request_rec *r, const char *locn, const char *what, + int replaced) +{ + const char *body; + + if (locn == NULL) { + locn = r->uri; + } + + /* did the target resource already exist? */ + if (replaced) { + /* Apache will supply a default message */ + return HTTP_NO_CONTENT; + } + + /* Per HTTP/1.1, S10.2.2: add a Location header to contain the + * URI that was created. */ + + /* Convert locn to an absolute URI, and return in Location header */ + apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, locn, r)); + + /* ### insert an ETag header? see HTTP/1.1 S10.2.2 */ + + /* Apache doesn't allow us to set a variable body for HTTP_CREATED, so + * we must manufacture the entire response. */ + body = apr_psprintf(r->pool, "%s %s has been created.", + what, ap_escape_html(r->pool, locn)); + return dav_error_response(r, HTTP_CREATED, body); +} + +/* ### move to dav_util? */ +DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth) +{ + const char *depth = apr_table_get(r->headers_in, "Depth"); + + if (depth == NULL) { + return def_depth; + } + + if (strcasecmp(depth, "infinity") == 0) { + return DAV_INFINITY; + } + else if (strcmp(depth, "0") == 0) { + return 0; + } + else if (strcmp(depth, "1") == 0) { + return 1; + } + + /* The caller will return an HTTP_BAD_REQUEST. This will augment the + * default message that Apache provides. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "An invalid Depth header was specified."); + return -1; +} + +static int dav_get_overwrite(request_rec *r) +{ + const char *overwrite = apr_table_get(r->headers_in, "Overwrite"); + + if (overwrite == NULL) { + return 1; /* default is "T" */ + } + + if ((*overwrite == 'F' || *overwrite == 'f') && overwrite[1] == '\0') { + return 0; + } + + if ((*overwrite == 'T' || *overwrite == 't') && overwrite[1] == '\0') { + return 1; + } + + /* The caller will return an HTTP_BAD_REQUEST. This will augment the + * default message that Apache provides. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "An invalid Overwrite header was specified."); + return -1; +} + +/* resolve a request URI to a resource descriptor. + * + * If label_allowed != 0, then allow the request target to be altered by + * a Label: header. + * + * If use_checked_in is true, then the repository provider should return + * the resource identified by the DAV:checked-in property of the resource + * identified by the Request-URI. + */ +static dav_error *dav_get_resource(request_rec *r, int label_allowed, + int use_checked_in, dav_resource **res_p) +{ + dav_dir_conf *conf; + const char *label = NULL; + dav_error *err; + + /* if the request target can be overridden, get any target selector */ + if (label_allowed) { + label = apr_table_get(r->headers_in, "label"); + } + + conf = ap_get_module_config(r->per_dir_config, &dav_module); + /* assert: conf->provider != NULL */ + + /* resolve the resource */ + err = (*conf->provider->repos->get_resource)(r, conf->dir, + label, use_checked_in, + res_p); + if (err != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "Could not fetch resource information.", err); + return err; + } + + /* Note: this shouldn't happen, but just be sure... */ + if (*res_p == NULL) { + /* ### maybe use HTTP_INTERNAL_SERVER_ERROR */ + return dav_new_error(r->pool, HTTP_NOT_FOUND, 0, + apr_psprintf(r->pool, + "The provider did not define a " + "resource for %s.", + ap_escape_html(r->pool, r->uri))); + } + + /* ### hmm. this doesn't feel like the right place or thing to do */ + /* if there were any input headers requiring a Vary header in the response, + * add it now */ + dav_add_vary_header(r, r, *res_p); + + return NULL; +} + +static dav_error * dav_open_lockdb(request_rec *r, int ro, dav_lockdb **lockdb) +{ + const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); + + if (hooks == NULL) { + *lockdb = NULL; + return NULL; + } + + /* open the thing lazily */ + return (*hooks->open_lockdb)(r, ro, 0, lockdb); +} + +static int dav_parse_range(request_rec *r, + apr_off_t *range_start, apr_off_t *range_end) +{ + const char *range_c; + char *range; + char *dash; + char *slash; + char *errp; + + range_c = apr_table_get(r->headers_in, "content-range"); + if (range_c == NULL) + return 0; + + range = apr_pstrdup(r->pool, range_c); + if (strncasecmp(range, "bytes ", 6) != 0 + || (dash = ap_strchr(range, '-')) == NULL + || (slash = ap_strchr(range, '/')) == NULL) { + /* malformed header. ignore it (per S14.16 of RFC2616) */ + return 0; + } + + *dash++ = *slash++ = '\0'; + + /* ignore invalid ranges. (per S14.16 of RFC2616) */ + if (apr_strtoff(range_start, range + 6, &errp, 10) + || *errp || *range_start < 0) { + return 0; + } + + if (apr_strtoff(range_end, dash, &errp, 10) + || *errp || *range_end < 0 || *range_end < *range_start) { + return 0; + } + + if (*slash != '*') { + apr_off_t dummy; + + if (apr_strtoff(&dummy, slash, &errp, 10) + || *errp || dummy <= *range_end) { + return 0; + } + } + + /* we now have a valid range */ + return 1; +} + +/* handle the GET method */ +static int dav_method_get(request_rec *r) +{ + dav_resource *resource; + dav_error *err; + int status; + + /* This method should only be called when the resource is not + * visible to Apache. We will fetch the resource from the repository, + * then create a subrequest for Apache to handle. + */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* set up the HTTP headers for the response */ + if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "Unable to set up HTTP headers.", + err); + return dav_handle_err(r, err, NULL); + } + + /* Handle conditional requests */ + status = ap_meets_conditions(r); + if (status) { + return status; + } + + if (r->header_only) { + return DONE; + } + + /* okay... time to deliver the content */ + if ((err = (*resource->hooks->deliver)(resource, + r->output_filters)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "Unable to deliver content.", + err); + return dav_handle_err(r, err, NULL); + } + + return DONE; +} + +/* validate resource/locks on POST, then pass to the default handler */ +static int dav_method_post(request_rec *r) +{ + dav_resource *resource; + dav_error *err; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* Note: depth == 0. Implies no need for a multistatus response. */ + if ((err = dav_validate_request(r, resource, 0, NULL, NULL, + DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + return DECLINED; +} + +/* handle the PUT method */ +static int dav_method_put(request_rec *r) +{ + dav_resource *resource; + int resource_state; + dav_auto_version_info av_info; + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + const char *body; + dav_error *err; + dav_error *err2; + dav_stream_mode mode; + dav_stream *stream; + dav_response *multi_response; + int has_range; + apr_off_t range_start; + apr_off_t range_end; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* If not a file or collection resource, PUT not allowed */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR + && resource->type != DAV_RESOURCE_TYPE_WORKING) { + body = apr_psprintf(r->pool, + "Cannot create resource %s with PUT.", + ap_escape_html(r->pool, r->uri)); + return dav_error_response(r, HTTP_CONFLICT, body); + } + + /* Cannot PUT a collection */ + if (resource->collection) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot PUT to a collection."); + + } + + resource_state = dav_get_resource_state(r, resource); + + /* + * Note: depth == 0 normally requires no multistatus response. However, + * if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI + * other than the Request-URI, thereby requiring a multistatus. + * + * If the resource does not exist (DAV_RESOURCE_NULL), then we must + * check the resource *and* its parent. If the resource exists or is + * a locknull resource, then we check only the resource. + */ + if ((err = dav_validate_request(r, resource, 0, NULL, &multi_response, + resource_state == DAV_RESOURCE_NULL ? + DAV_VALIDATE_PARENT : + DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, multi_response); + } + + /* make sure the resource can be modified (if versioning repository) */ + if ((err = dav_auto_checkout(r, resource, + 0 /* not parent_only */, + &av_info)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* truncate and rewrite the file unless we see a Content-Range */ + mode = DAV_MODE_WRITE_TRUNC; + + has_range = dav_parse_range(r, &range_start, &range_end); + if (has_range) { + mode = DAV_MODE_WRITE_SEEKABLE; + } + + /* Create the new file in the repository */ + if ((err = (*resource->hooks->open_stream)(resource, mode, + &stream)) != NULL) { + /* ### assuming FORBIDDEN is probably not quite right... */ + err = dav_push_error(r->pool, HTTP_FORBIDDEN, 0, + apr_psprintf(r->pool, + "Unable to PUT new contents for %s.", + ap_escape_html(r->pool, r->uri)), + err); + } + + if (err == NULL && has_range) { + /* a range was provided. seek to the start */ + err = (*resource->hooks->seek_stream)(stream, range_start); + } + + if (err == NULL) { + apr_bucket_brigade *bb; + apr_bucket *b; + int seen_eos = 0; + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + + do { + apr_status_t rc; + + rc = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, DAV_READ_BLOCKSIZE); + + if (rc != APR_SUCCESS) { + err = dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not get next bucket brigade"); + break; + } + + for (b = APR_BRIGADE_FIRST(bb); + b != APR_BRIGADE_SENTINEL(bb); + b = APR_BUCKET_NEXT(b)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(b)) { + seen_eos = 1; + break; + } + + if (APR_BUCKET_IS_METADATA(b)) { + continue; + } + + rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); + if (rc != APR_SUCCESS) { + err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, + "An error occurred while reading " + "the request body."); + break; + } + + if (err == NULL) { + /* write whatever we read, until we see an error */ + err = (*resource->hooks->write_stream)(stream, data, len); + } + } + + apr_brigade_cleanup(bb); + } while (!seen_eos); + + apr_brigade_destroy(bb); + + err2 = (*resource->hooks->close_stream)(stream, + err == NULL /* commit */); + if (err2 != NULL && err == NULL) { + /* no error during the write, but we hit one at close. use it. */ + err = err2; + } + } + + /* + * Ensure that we think the resource exists now. + * ### eek. if an error occurred during the write and we did not commit, + * ### then the resource might NOT exist (e.g. dav_fs_repos.c) + */ + if (err == NULL) { + resource->exists = 1; + } + + /* restore modifiability of resources back to what they were */ + err2 = dav_auto_checkin(r, resource, err != NULL /* undo if error */, + 0 /*unlock*/, &av_info); + + /* check for errors now */ + if (err != NULL) { + return dav_handle_err(r, err, NULL); + } + + if (err2 != NULL) { + /* just log a warning */ + err2 = dav_push_error(r->pool, err2->status, 0, + "The PUT was successful, but there " + "was a problem automatically checking in " + "the resource or its parent collection.", + err2); + dav_log_err(r, err2, APLOG_WARNING); + } + + /* ### place the Content-Type and Content-Language into the propdb */ + + if (locks_hooks != NULL) { + dav_lockdb *lockdb; + + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) { + /* The file creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The file was PUT successfully, but there " + "was a problem opening the lock database " + "which prevents inheriting locks from the " + "parent resources.", + err); + return dav_handle_err(r, err, NULL); + } + + /* notify lock system that we have created/replaced a resource */ + err = dav_notify_created(r, lockdb, resource, resource_state, 0); + + (*locks_hooks->close_lockdb)(lockdb); + + if (err != NULL) { + /* The file creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The file was PUT successfully, but there " + "was a problem updating its lock " + "information.", + err); + return dav_handle_err(r, err, NULL); + } + } + + /* NOTE: WebDAV spec, S8.7.1 states properties should be unaffected */ + + /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ + return dav_created(r, NULL, "Resource", resource_state == DAV_RESOURCE_EXISTS); +} + + +/* Use POOL to temporarily construct a dav_response object (from WRES + STATUS, and PROPSTATS) and stream it via WRES's ctx->brigade. */ +static void dav_stream_response(dav_walk_resource *wres, + int status, + dav_get_props_result *propstats, + apr_pool_t *pool) +{ + dav_response resp = { 0 }; + dav_walker_ctx *ctx = wres->walk_ctx; + + resp.href = wres->resource->uri; + resp.status = status; + if (propstats) { + resp.propresult = *propstats; + } + + dav_send_one_response(&resp, ctx->bb, ctx->r->output_filters, pool); +} + + +/* ### move this to dav_util? */ +DAV_DECLARE(void) dav_add_response(dav_walk_resource *wres, + int status, dav_get_props_result *propstats) +{ + dav_response *resp; + + /* just drop some data into an dav_response */ + resp = apr_pcalloc(wres->pool, sizeof(*resp)); + resp->href = apr_pstrdup(wres->pool, wres->resource->uri); + resp->status = status; + if (propstats) { + resp->propresult = *propstats; + } + + resp->next = wres->response; + wres->response = resp; +} + + +/* handle the DELETE method */ +static int dav_method_delete(request_rec *r) +{ + dav_resource *resource; + dav_auto_version_info av_info; + dav_error *err; + dav_error *err2; + dav_response *multi_response; + int result; + int depth; + + /* We don't use the request body right now, so torch it. */ + if ((result = ap_discard_request_body(r)) != OK) { + return result; + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* 2518 says that depth must be infinity only for collections. + * For non-collections, depth is ignored, unless it is an illegal value (1). + */ + depth = dav_get_depth(r, DAV_INFINITY); + + if (resource->collection && depth != DAV_INFINITY) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth must be \"infinity\" for DELETE of a collection."); + return HTTP_BAD_REQUEST; + } + + if (!resource->collection && depth == 1) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth of \"1\" is not allowed for DELETE."); + return HTTP_BAD_REQUEST; + } + + /* + ** If any resources fail the lock/If: conditions, then we must fail + ** the delete. Each of the failing resources will be listed within + ** a DAV:multistatus body, wrapped into a 424 response. + ** + ** Note that a failure on the resource itself does not generate a + ** multistatus response -- only internal members/collections. + */ + if ((err = dav_validate_request(r, resource, depth, NULL, + &multi_response, + DAV_VALIDATE_PARENT + | DAV_VALIDATE_USE_424, NULL)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not DELETE %s due to a failed " + "precondition (e.g. locks).", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* ### RFC 2518 s. 8.10.5 says to remove _all_ locks, not just those + * locked by the token(s) in the if_header. + */ + if ((result = dav_unlock(r, resource, NULL)) != OK) { + return result; + } + + /* if versioned resource, make sure parent is checked out */ + if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */, + &av_info)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* try to remove the resource */ + err = (*resource->hooks->remove_resource)(resource, &multi_response); + + /* restore writability of parent back to what it was */ + err2 = dav_auto_checkin(r, NULL, err != NULL /* undo if error */, + 0 /*unlock*/, &av_info); + + /* check for errors now */ + if (err != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not DELETE %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + if (err2 != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err2->status, 0, + "The DELETE was successful, but there " + "was a problem automatically checking in " + "the parent collection.", + err2); + dav_log_err(r, err, APLOG_WARNING); + } + + /* ### HTTP_NO_CONTENT if no body, HTTP_OK if there is a body (some day) */ + + /* Apache will supply a default error for this. */ + return HTTP_NO_CONTENT; +} + +/* generate DAV:supported-method-set OPTIONS response */ +static dav_error *dav_gen_supported_methods(request_rec *r, + const apr_xml_elem *elem, + const apr_table_t *methods, + apr_text_header *body) +{ + const apr_array_header_t *arr; + const apr_table_entry_t *elts; + apr_xml_elem *child; + apr_xml_attr *attr; + char *s; + int i; + + apr_text_append(r->pool, body, "" DEBUG_CR); + + if (elem->first_child == NULL) { + /* show all supported methods */ + arr = apr_table_elts(methods); + elts = (const apr_table_entry_t *)arr->elts; + + for (i = 0; i < arr->nelts; ++i) { + if (elts[i].key == NULL) + continue; + + s = apr_psprintf(r->pool, + "" + DEBUG_CR, + elts[i].key); + apr_text_append(r->pool, body, s); + } + } + else { + /* check for support of specific methods */ + for (child = elem->first_child; child != NULL; child = child->next) { + if (child->ns == APR_XML_NS_DAV_ID + && strcmp(child->name, "supported-method") == 0) { + const char *name = NULL; + + /* go through attributes to find method name */ + for (attr = child->attr; attr != NULL; attr = attr->next) { + if (attr->ns == APR_XML_NS_DAV_ID + && strcmp(attr->name, "name") == 0) + name = attr->value; + } + + if (name == NULL) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, + "A DAV:supported-method element " + "does not have a \"name\" attribute"); + } + + /* see if method is supported */ + if (apr_table_get(methods, name) != NULL) { + s = apr_psprintf(r->pool, + "" + DEBUG_CR, + name); + apr_text_append(r->pool, body, s); + } + } + } + } + + apr_text_append(r->pool, body, "" DEBUG_CR); + return NULL; +} + +/* generate DAV:supported-live-property-set OPTIONS response */ +static dav_error *dav_gen_supported_live_props(request_rec *r, + const dav_resource *resource, + const apr_xml_elem *elem, + apr_text_header *body) +{ + dav_lockdb *lockdb; + dav_propdb *propdb; + apr_xml_elem *child; + apr_xml_attr *attr; + dav_error *err; + + /* open lock database, to report on supported lock properties */ + /* ### should open read-only */ + if ((err = dav_open_lockdb(r, 0, &lockdb)) != NULL) { + return dav_push_error(r->pool, err->status, 0, + "The lock database could not be opened, " + "preventing the reporting of supported lock " + "properties.", + err); + } + + /* open the property database (readonly) for the resource */ + if ((err = dav_open_propdb(r, lockdb, resource, 1, NULL, + &propdb)) != NULL) { + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + return dav_push_error(r->pool, err->status, 0, + "The property database could not be opened, " + "preventing report of supported properties.", + err); + } + + apr_text_append(r->pool, body, "" DEBUG_CR); + + if (elem->first_child == NULL) { + /* show all supported live properties */ + dav_get_props_result props = dav_get_allprops(propdb, DAV_PROP_INSERT_SUPPORTED); + body->last->next = props.propstats; + while (body->last->next != NULL) + body->last = body->last->next; + } + else { + /* check for support of specific live property */ + for (child = elem->first_child; child != NULL; child = child->next) { + if (child->ns == APR_XML_NS_DAV_ID + && strcmp(child->name, "supported-live-property") == 0) { + const char *name = NULL; + const char *nmspace = NULL; + + /* go through attributes to find name and namespace */ + for (attr = child->attr; attr != NULL; attr = attr->next) { + if (attr->ns == APR_XML_NS_DAV_ID) { + if (strcmp(attr->name, "name") == 0) + name = attr->value; + else if (strcmp(attr->name, "namespace") == 0) + nmspace = attr->value; + } + } + + if (name == NULL) { + err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, + "A DAV:supported-live-property " + "element does not have a \"name\" " + "attribute"); + break; + } + + /* default namespace to DAV: */ + if (nmspace == NULL) + nmspace = "DAV:"; + + /* check for support of property */ + dav_get_liveprop_supported(propdb, nmspace, name, body); + } + } + } + + apr_text_append(r->pool, body, "" DEBUG_CR); + + dav_close_propdb(propdb); + + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + return err; +} + +/* generate DAV:supported-report-set OPTIONS response */ +static dav_error *dav_gen_supported_reports(request_rec *r, + const dav_resource *resource, + const apr_xml_elem *elem, + const dav_hooks_vsn *vsn_hooks, + apr_text_header *body) +{ + apr_xml_elem *child; + apr_xml_attr *attr; + dav_error *err; + char *s; + + apr_text_append(r->pool, body, "" DEBUG_CR); + + if (vsn_hooks != NULL) { + const dav_report_elem *reports; + const dav_report_elem *rp; + + if ((err = (*vsn_hooks->avail_reports)(resource, &reports)) != NULL) { + return dav_push_error(r->pool, err->status, 0, + "DAV:supported-report-set could not be " + "determined due to a problem fetching the " + "available reports for this resource.", + err); + } + + if (reports != NULL) { + if (elem->first_child == NULL) { + /* show all supported reports */ + for (rp = reports; rp->nmspace != NULL; ++rp) { + /* Note: we presume reports->namespace is + * properly XML/URL quoted */ + s = apr_psprintf(r->pool, + "" DEBUG_CR, + rp->name, rp->nmspace); + apr_text_append(r->pool, body, s); + } + } + else { + /* check for support of specific report */ + for (child = elem->first_child; child != NULL; child = child->next) { + if (child->ns == APR_XML_NS_DAV_ID + && strcmp(child->name, "supported-report") == 0) { + const char *name = NULL; + const char *nmspace = NULL; + + /* go through attributes to find name and namespace */ + for (attr = child->attr; attr != NULL; attr = attr->next) { + if (attr->ns == APR_XML_NS_DAV_ID) { + if (strcmp(attr->name, "name") == 0) + name = attr->value; + else if (strcmp(attr->name, "namespace") == 0) + nmspace = attr->value; + } + } + + if (name == NULL) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, + "A DAV:supported-report element " + "does not have a \"name\" attribute"); + } + + /* default namespace to DAV: */ + if (nmspace == NULL) + nmspace = "DAV:"; + + for (rp = reports; rp->nmspace != NULL; ++rp) { + if (strcmp(name, rp->name) == 0 + && strcmp(nmspace, rp->nmspace) == 0) { + /* Note: we presume reports->nmspace is + * properly XML/URL quoted + */ + s = apr_psprintf(r->pool, + "" + DEBUG_CR, + rp->name, rp->nmspace); + apr_text_append(r->pool, body, s); + break; + } + } + } + } + } + } + } + + apr_text_append(r->pool, body, "" DEBUG_CR); + return NULL; +} + + +/* handle the SEARCH method */ +static int dav_method_search(request_rec *r) +{ + const dav_hooks_search *search_hooks = DAV_GET_HOOKS_SEARCH(r); + dav_resource *resource; + dav_error *err; + dav_response *multi_status; + + /* If no search provider, decline the request */ + if (search_hooks == NULL) + return DECLINED; + + /* This method should only be called when the resource is not + * visible to Apache. We will fetch the resource from the repository, + * then create a subrequest for Apache to handle. + */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* set up the HTTP headers for the response */ + if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "Unable to set up HTTP headers.", + err); + return dav_handle_err(r, err, NULL); + } + + if (r->header_only) { + return DONE; + } + + /* okay... time to search the content */ + /* Let's validate XML and process walk function + * in the hook function + */ + if ((err = (*search_hooks->search_resource)(r, &multi_status)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* We have results in multi_status */ + /* Should I pass namespace?? */ + dav_send_multistatus(r, HTTP_MULTI_STATUS, multi_status, NULL); + + return DONE; +} + + +/* handle the OPTIONS method */ +static int dav_method_options(request_rec *r) +{ + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + const dav_hooks_binding *binding_hooks = DAV_GET_HOOKS_BINDING(r); + const dav_hooks_search *search_hooks = DAV_GET_HOOKS_SEARCH(r); + dav_resource *resource; + const char *dav_level; + char *allow; + char *s; + const apr_array_header_t *arr; + const apr_table_entry_t *elts; + apr_table_t *methods = apr_table_make(r->pool, 12); + apr_text_header vsn_options = { 0 }; + apr_text_header body = { 0 }; + apr_text *t; + int text_size; + int result; + int i; + apr_array_header_t *uri_ary; + apr_xml_doc *doc; + const apr_xml_elem *elem; + dav_error *err; + + /* resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* parse any request body */ + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + /* note: doc == NULL if no request body */ + + if (doc && !dav_validate_root(doc, "options")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"options\" element was not found."); + return HTTP_BAD_REQUEST; + } + + /* determine which providers are available */ + dav_level = "1"; + + if (locks_hooks != NULL) { + dav_level = "1,2"; + } + + if (binding_hooks != NULL) + dav_level = apr_pstrcat(r->pool, dav_level, ",bindings", NULL); + + /* ### + * MSFT Web Folders chokes if length of DAV header value > 63 characters! + * To workaround that, we use separate DAV headers for versioning and + * live prop provider namespace URIs. + * ### + */ + apr_table_setn(r->headers_out, "DAV", dav_level); + + /* + * If there is a versioning provider, generate DAV headers + * for versioning options. + */ + if (vsn_hooks != NULL) { + (*vsn_hooks->get_vsn_options)(r->pool, &vsn_options); + + for (t = vsn_options.first; t != NULL; t = t->next) + apr_table_addn(r->headers_out, "DAV", t->text); + } + + /* + * Gather property set URIs from all the liveprop providers, + * and generate a separate DAV header for each URI, to avoid + * problems with long header lengths. + */ + uri_ary = apr_array_make(r->pool, 5, sizeof(const char *)); + dav_run_gather_propsets(uri_ary); + for (i = 0; i < uri_ary->nelts; ++i) { + if (((char **)uri_ary->elts)[i] != NULL) + apr_table_addn(r->headers_out, "DAV", ((char **)uri_ary->elts)[i]); + } + + /* this tells MSFT products to skip looking for FrontPage extensions */ + apr_table_setn(r->headers_out, "MS-Author-Via", "DAV"); + + /* + * Determine which methods are allowed on the resource. + * Three cases: resource is null (3), is lock-null (7.4), or exists. + * + * All cases support OPTIONS, and if there is a lock provider, LOCK. + * (Lock-) null resources also support MKCOL and PUT. + * Lock-null supports PROPFIND and UNLOCK. + * Existing resources support lots of stuff. + */ + + apr_table_addn(methods, "OPTIONS", ""); + + /* ### take into account resource type */ + switch (dav_get_resource_state(r, resource)) + { + case DAV_RESOURCE_EXISTS: + /* resource exists */ + apr_table_addn(methods, "GET", ""); + apr_table_addn(methods, "HEAD", ""); + apr_table_addn(methods, "POST", ""); + apr_table_addn(methods, "DELETE", ""); + apr_table_addn(methods, "TRACE", ""); + apr_table_addn(methods, "PROPFIND", ""); + apr_table_addn(methods, "PROPPATCH", ""); + apr_table_addn(methods, "COPY", ""); + apr_table_addn(methods, "MOVE", ""); + + if (!resource->collection) + apr_table_addn(methods, "PUT", ""); + + if (locks_hooks != NULL) { + apr_table_addn(methods, "LOCK", ""); + apr_table_addn(methods, "UNLOCK", ""); + } + + break; + + case DAV_RESOURCE_LOCK_NULL: + /* resource is lock-null. */ + apr_table_addn(methods, "MKCOL", ""); + apr_table_addn(methods, "PROPFIND", ""); + apr_table_addn(methods, "PUT", ""); + + if (locks_hooks != NULL) { + apr_table_addn(methods, "LOCK", ""); + apr_table_addn(methods, "UNLOCK", ""); + } + + break; + + case DAV_RESOURCE_NULL: + /* resource is null. */ + apr_table_addn(methods, "MKCOL", ""); + apr_table_addn(methods, "PUT", ""); + + if (locks_hooks != NULL) + apr_table_addn(methods, "LOCK", ""); + + break; + + default: + /* ### internal error! */ + break; + } + + /* If there is a versioning provider, add versioning methods */ + if (vsn_hooks != NULL) { + if (!resource->exists) { + if ((*vsn_hooks->versionable)(resource)) + apr_table_addn(methods, "VERSION-CONTROL", ""); + + if (vsn_hooks->can_be_workspace != NULL + && (*vsn_hooks->can_be_workspace)(resource)) + apr_table_addn(methods, "MKWORKSPACE", ""); + + if (vsn_hooks->can_be_activity != NULL + && (*vsn_hooks->can_be_activity)(resource)) + apr_table_addn(methods, "MKACTIVITY", ""); + } + else if (!resource->versioned) { + if ((*vsn_hooks->versionable)(resource)) + apr_table_addn(methods, "VERSION-CONTROL", ""); + } + else if (resource->working) { + apr_table_addn(methods, "CHECKIN", ""); + + /* ### we might not support this DeltaV option */ + apr_table_addn(methods, "UNCHECKOUT", ""); + } + else if (vsn_hooks->add_label != NULL) { + apr_table_addn(methods, "CHECKOUT", ""); + apr_table_addn(methods, "LABEL", ""); + } + else { + apr_table_addn(methods, "CHECKOUT", ""); + } + } + + /* If there is a bindings provider, see if resource is bindable */ + if (binding_hooks != NULL + && (*binding_hooks->is_bindable)(resource)) { + apr_table_addn(methods, "BIND", ""); + } + + /* If there is a search provider, set SEARCH in option */ + if (search_hooks != NULL) { + apr_table_addn(methods, "SEARCH", ""); + } + + /* Generate the Allow header */ + arr = apr_table_elts(methods); + elts = (const apr_table_entry_t *)arr->elts; + text_size = 0; + + /* first, compute total length */ + for (i = 0; i < arr->nelts; ++i) { + if (elts[i].key == NULL) + continue; + + /* add 1 for comma or null */ + text_size += strlen(elts[i].key) + 1; + } + + s = allow = apr_palloc(r->pool, text_size); + + for (i = 0; i < arr->nelts; ++i) { + if (elts[i].key == NULL) + continue; + + if (s != allow) + *s++ = ','; + + strcpy(s, elts[i].key); + s += strlen(s); + } + + apr_table_setn(r->headers_out, "Allow", allow); + + + /* If there is search set_option_head function, set head */ + /* DASL: + * DASL: + * DASL: + */ + if (search_hooks != NULL + && *search_hooks->set_option_head != NULL) { + if ((err = (*search_hooks->set_option_head)(r)) != NULL) { + return dav_handle_err(r, err, NULL); + } + } + + /* if there was no request body, then there is no response body */ + if (doc == NULL) { + ap_set_content_length(r, 0); + + /* ### this sends a Content-Type. the default OPTIONS does not. */ + + /* ### the default (ap_send_http_options) returns OK, but I believe + * ### that is because it is the default handler and nothing else + * ### will run after the thing. */ + return DONE; + } + + /* handle each options request */ + for (elem = doc->root->first_child; elem != NULL; elem = elem->next) { + /* check for something we recognize first */ + int core_option = 0; + dav_error *err = NULL; + + if (elem->ns == APR_XML_NS_DAV_ID) { + if (strcmp(elem->name, "supported-method-set") == 0) { + err = dav_gen_supported_methods(r, elem, methods, &body); + core_option = 1; + } + else if (strcmp(elem->name, "supported-live-property-set") == 0) { + err = dav_gen_supported_live_props(r, resource, elem, &body); + core_option = 1; + } + else if (strcmp(elem->name, "supported-report-set") == 0) { + err = dav_gen_supported_reports(r, resource, elem, vsn_hooks, &body); + core_option = 1; + } + } + + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* if unrecognized option, pass to versioning provider */ + if (!core_option && vsn_hooks != NULL) { + if ((err = (*vsn_hooks->get_option)(resource, elem, &body)) + != NULL) { + return dav_handle_err(r, err, NULL); + } + } + } + + /* send the options response */ + r->status = HTTP_OK; + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + /* send the headers and response body */ + ap_rputs(DAV_XML_HEADER DEBUG_CR + "" DEBUG_CR, r); + + for (t = body.first; t != NULL; t = t->next) + ap_rputs(t->text, r); + + ap_rputs("" DEBUG_CR, r); + + /* we've sent everything necessary to the client. */ + return DONE; +} + +static void dav_cache_badprops(dav_walker_ctx *ctx) +{ + const apr_xml_elem *elem; + apr_text_header hdr = { 0 }; + + /* just return if we built the thing already */ + if (ctx->propstat_404 != NULL) { + return; + } + + apr_text_append(ctx->w.pool, &hdr, + "" DEBUG_CR + "" DEBUG_CR); + + elem = dav_find_child(ctx->doc->root, "prop"); + for (elem = elem->first_child; elem; elem = elem->next) { + apr_text_append(ctx->w.pool, &hdr, + apr_xml_empty_elem(ctx->w.pool, elem)); + } + + apr_text_append(ctx->w.pool, &hdr, + "" DEBUG_CR + "HTTP/1.1 404 Not Found" DEBUG_CR + "" DEBUG_CR); + + ctx->propstat_404 = hdr.first; +} + +static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype) +{ + dav_walker_ctx *ctx = wres->walk_ctx; + dav_error *err; + dav_propdb *propdb; + dav_get_props_result propstats = { 0 }; + + /* + ** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since + ** dav_get_allprops() does not need to do namespace translation, + ** we're okay. + ** + ** Note: we cast to lose the "const". The propdb won't try to change + ** the resource, however, since we are opening readonly. + */ + err = dav_open_propdb(ctx->r, ctx->w.lockdb, wres->resource, 1, + ctx->doc ? ctx->doc->namespaces : NULL, &propdb); + if (err != NULL) { + /* ### do something with err! */ + + if (ctx->propfind_type == DAV_PROPFIND_IS_PROP) { + dav_get_props_result badprops = { 0 }; + + /* some props were expected on this collection/resource */ + dav_cache_badprops(ctx); + badprops.propstats = ctx->propstat_404; + dav_stream_response(wres, 0, &badprops, ctx->scratchpool); + } + else { + /* no props on this collection/resource */ + dav_stream_response(wres, HTTP_OK, NULL, ctx->scratchpool); + } + + apr_pool_clear(ctx->scratchpool); + return NULL; + } + /* ### what to do about closing the propdb on server failure? */ + + if (ctx->propfind_type == DAV_PROPFIND_IS_PROP) { + propstats = dav_get_props(propdb, ctx->doc); + } + else { + dav_prop_insert what = ctx->propfind_type == DAV_PROPFIND_IS_ALLPROP + ? DAV_PROP_INSERT_VALUE + : DAV_PROP_INSERT_NAME; + propstats = dav_get_allprops(propdb, what); + } + dav_close_propdb(propdb); + + dav_stream_response(wres, 0, &propstats, ctx->scratchpool); + + /* at this point, ctx->scratchpool has been used to stream a + single response. this function fully controls the pool, and + thus has the right to clear it for the next iteration of this + callback. */ + apr_pool_clear(ctx->scratchpool); + + return NULL; +} + +/* handle the PROPFIND method */ +static int dav_method_propfind(request_rec *r) +{ + dav_resource *resource; + int depth; + dav_error *err; + int result; + apr_xml_doc *doc; + const apr_xml_elem *child; + dav_walker_ctx ctx = { { 0 } }; + dav_response *multi_status; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (dav_get_resource_state(r, resource) == DAV_RESOURCE_NULL) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + if ((depth = dav_get_depth(r, DAV_INFINITY)) < 0) { + /* dav_get_depth() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + + if (depth == DAV_INFINITY && resource->collection) { + dav_dir_conf *conf; + conf = (dav_dir_conf *)ap_get_module_config(r->per_dir_config, + &dav_module); + /* default is to DISALLOW these requests */ + if (conf->allow_depthinfinity != DAV_ENABLED_ON) { + return dav_error_response(r, HTTP_FORBIDDEN, + apr_psprintf(r->pool, + "PROPFIND requests with a " + "Depth of \"infinity\" are " + "not allowed for %s.", + ap_escape_html(r->pool, + r->uri))); + } + } + + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + /* note: doc == NULL if no request body */ + + if (doc && !dav_validate_root(doc, "propfind")) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"propfind\" element was not found."); + return HTTP_BAD_REQUEST; + } + + /* ### validate that only one of these three elements is present */ + + if (doc == NULL + || (child = dav_find_child(doc->root, "allprop")) != NULL) { + /* note: no request body implies allprop */ + ctx.propfind_type = DAV_PROPFIND_IS_ALLPROP; + } + else if ((child = dav_find_child(doc->root, "propname")) != NULL) { + ctx.propfind_type = DAV_PROPFIND_IS_PROPNAME; + } + else if ((child = dav_find_child(doc->root, "prop")) != NULL) { + ctx.propfind_type = DAV_PROPFIND_IS_PROP; + } + else { + /* "propfind" element must have one of the above three children */ + + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"propfind\" element does not contain one of " + "the required child elements (the specific command)."); + return HTTP_BAD_REQUEST; + } + + ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH; + ctx.w.func = dav_propfind_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = resource; + + ctx.doc = doc; + ctx.r = r; + ctx.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + apr_pool_create(&ctx.scratchpool, r->pool); + + /* ### should open read-only */ + if ((err = dav_open_lockdb(r, 0, &ctx.w.lockdb)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "The lock database could not be opened, " + "preventing access to the various lock " + "properties for the PROPFIND.", + err); + return dav_handle_err(r, err, NULL); + } + if (ctx.w.lockdb != NULL) { + /* if we have a lock database, then we can walk locknull resources */ + ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL; + } + + /* send tag, with all doc->namespaces attached. */ + + /* NOTE: we *cannot* leave out the doc's namespaces from the + initial tag. if a 404 was generated for an HREF, + then we need to spit out the doc's namespaces for use by the + 404. Note that elements will override these ns0, + ns1, etc, but NOT within the scope for the + badprops. */ + dav_begin_multistatus(ctx.bb, r, HTTP_MULTI_STATUS, + doc ? doc->namespaces : NULL); + + /* Have the provider walk the resource. */ + err = (*resource->hooks->walk)(&ctx.w, depth, &multi_status); + + if (ctx.w.lockdb != NULL) { + (*ctx.w.lockdb->hooks->close_lockdb)(ctx.w.lockdb); + } + + if (err != NULL) { + /* If an error occurred during the resource walk, there's + basically nothing we can do but abort the connection and + log an error. This is one of the limitations of HTTP; it + needs to "know" the entire status of the response before + generating it, which is just impossible in these streamy + response situations. */ + err = dav_push_error(r->pool, err->status, 0, + "Provider encountered an error while streaming" + " a multistatus PROPFIND response.", err); + dav_log_err(r, err, APLOG_ERR); + r->connection->aborted = 1; + return DONE; + } + + dav_finish_multistatus(r, ctx.bb); + + /* the response has been sent. */ + return DONE; +} + +static apr_text * dav_failed_proppatch(apr_pool_t *p, + apr_array_header_t *prop_ctx) +{ + apr_text_header hdr = { 0 }; + int i = prop_ctx->nelts; + dav_prop_ctx *ctx = (dav_prop_ctx *)prop_ctx->elts; + dav_error *err424_set = NULL; + dav_error *err424_delete = NULL; + const char *s; + + /* ### might be nice to sort by status code and description */ + + for ( ; i-- > 0; ++ctx ) { + apr_text_append(p, &hdr, + "" DEBUG_CR + ""); + apr_text_append(p, &hdr, apr_xml_empty_elem(p, ctx->prop)); + apr_text_append(p, &hdr, "" DEBUG_CR); + + if (ctx->err == NULL) { + /* nothing was assigned here yet, so make it a 424 */ + + if (ctx->operation == DAV_PROP_OP_SET) { + if (err424_set == NULL) + err424_set = dav_new_error(p, HTTP_FAILED_DEPENDENCY, 0, + "Attempted DAV:set operation " + "could not be completed due " + "to other errors."); + ctx->err = err424_set; + } + else if (ctx->operation == DAV_PROP_OP_DELETE) { + if (err424_delete == NULL) + err424_delete = dav_new_error(p, HTTP_FAILED_DEPENDENCY, 0, + "Attempted DAV:remove " + "operation could not be " + "completed due to other " + "errors."); + ctx->err = err424_delete; + } + } + + s = apr_psprintf(p, + "" + "HTTP/1.1 %d (status)" + "" DEBUG_CR, + ctx->err->status); + apr_text_append(p, &hdr, s); + + /* ### we should use compute_desc if necessary... */ + if (ctx->err->desc != NULL) { + apr_text_append(p, &hdr, "" DEBUG_CR); + apr_text_append(p, &hdr, ctx->err->desc); + apr_text_append(p, &hdr, "" DEBUG_CR); + } + + apr_text_append(p, &hdr, "" DEBUG_CR); + } + + return hdr.first; +} + +static apr_text * dav_success_proppatch(apr_pool_t *p, apr_array_header_t *prop_ctx) +{ + apr_text_header hdr = { 0 }; + int i = prop_ctx->nelts; + dav_prop_ctx *ctx = (dav_prop_ctx *)prop_ctx->elts; + + /* + * ### we probably need to revise the way we assemble the response... + * ### this code assumes everything will return status==200. + */ + + apr_text_append(p, &hdr, + "" DEBUG_CR + "" DEBUG_CR); + + for ( ; i-- > 0; ++ctx ) { + apr_text_append(p, &hdr, apr_xml_empty_elem(p, ctx->prop)); + } + + apr_text_append(p, &hdr, + "" DEBUG_CR + "HTTP/1.1 200 OK" DEBUG_CR + "" DEBUG_CR); + + return hdr.first; +} + +static void dav_prop_log_errors(dav_prop_ctx *ctx) +{ + dav_log_err(ctx->r, ctx->err, APLOG_ERR); +} + +/* + * Call for each context. This can stop when an error occurs, or + * simply iterate through the whole list. + * + * Returns 1 if an error occurs (and the iteration is aborted). Returns 0 + * if all elements are processed. + * + * If is true (non-zero), then the list is traversed in + * reverse order. + */ +static int dav_process_ctx_list(void (*func)(dav_prop_ctx *ctx), + apr_array_header_t *ctx_list, int stop_on_error, + int reverse) +{ + int i = ctx_list->nelts; + dav_prop_ctx *ctx = (dav_prop_ctx *)ctx_list->elts; + + if (reverse) + ctx += i; + + while (i--) { + if (reverse) + --ctx; + + (*func)(ctx); + if (stop_on_error && DAV_PROP_CTX_HAS_ERR(*ctx)) { + return 1; + } + + if (!reverse) + ++ctx; + } + + return 0; +} + +/* handle the PROPPATCH method */ +static int dav_method_proppatch(request_rec *r) +{ + dav_error *err; + dav_resource *resource; + int result; + apr_xml_doc *doc; + apr_xml_elem *child; + dav_propdb *propdb; + int failure = 0; + dav_response resp = { 0 }; + apr_text *propstat_text; + apr_array_header_t *ctx_list; + dav_prop_ctx *ctx; + dav_auto_version_info av_info; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + /* note: doc == NULL if no request body */ + + if (doc == NULL || !dav_validate_root(doc, "propertyupdate")) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body does not contain " + "a \"propertyupdate\" element."); + return HTTP_BAD_REQUEST; + } + + /* Check If-Headers and existing locks */ + /* Note: depth == 0. Implies no need for a multistatus response. */ + if ((err = dav_validate_request(r, resource, 0, NULL, NULL, + DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* make sure the resource can be modified (if versioning repository) */ + if ((err = dav_auto_checkout(r, resource, + 0 /* not parent_only */, + &av_info)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + if ((err = dav_open_propdb(r, NULL, resource, 0, doc->namespaces, + &propdb)) != NULL) { + /* undo any auto-checkout */ + dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, &av_info); + + err = dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Could not open the property " + "database for %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + /* ### what to do about closing the propdb on server failure? */ + + /* ### validate "live" properties */ + + /* set up an array to hold property operation contexts */ + ctx_list = apr_array_make(r->pool, 10, sizeof(dav_prop_ctx)); + + /* do a first pass to ensure that all "remove" properties exist */ + for (child = doc->root->first_child; child; child = child->next) { + int is_remove; + apr_xml_elem *prop_group; + apr_xml_elem *one_prop; + + /* Ignore children that are not set/remove */ + if (child->ns != APR_XML_NS_DAV_ID + || (!(is_remove = strcmp(child->name, "remove") == 0) + && strcmp(child->name, "set") != 0)) { + continue; + } + + /* make sure that a "prop" child exists for set/remove */ + if ((prop_group = dav_find_child(child, "prop")) == NULL) { + dav_close_propdb(propdb); + + /* undo any auto-checkout */ + dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, &av_info); + + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "A \"prop\" element is missing inside " + "the propertyupdate command."); + return HTTP_BAD_REQUEST; + } + + for (one_prop = prop_group->first_child; one_prop; + one_prop = one_prop->next) { + + ctx = (dav_prop_ctx *)apr_array_push(ctx_list); + ctx->propdb = propdb; + ctx->operation = is_remove ? DAV_PROP_OP_DELETE : DAV_PROP_OP_SET; + ctx->prop = one_prop; + + ctx->r = r; /* for later use by dav_prop_log_errors() */ + + dav_prop_validate(ctx); + + if ( DAV_PROP_CTX_HAS_ERR(*ctx) ) { + failure = 1; + } + } + } + + /* ### should test that we found at least one set/remove */ + + /* execute all of the operations */ + if (!failure && dav_process_ctx_list(dav_prop_exec, ctx_list, 1, 0)) { + failure = 1; + } + + /* generate a failure/success response */ + if (failure) { + (void)dav_process_ctx_list(dav_prop_rollback, ctx_list, 0, 1); + propstat_text = dav_failed_proppatch(r->pool, ctx_list); + } + else { + (void)dav_process_ctx_list(dav_prop_commit, ctx_list, 0, 0); + propstat_text = dav_success_proppatch(r->pool, ctx_list); + } + + /* make sure this gets closed! */ + dav_close_propdb(propdb); + + /* complete any auto-versioning */ + dav_auto_checkin(r, resource, failure, 0 /*unlock*/, &av_info); + + /* log any errors that occurred */ + (void)dav_process_ctx_list(dav_prop_log_errors, ctx_list, 0, 0); + + resp.href = resource->uri; + + /* ### should probably use something new to pass along this text... */ + resp.propresult.propstats = propstat_text; + + dav_send_multistatus(r, HTTP_MULTI_STATUS, &resp, doc->namespaces); + + /* the response has been sent. */ + return DONE; +} + +static int process_mkcol_body(request_rec *r) +{ + /* This is snarfed from ap_setup_client_block(). We could get pretty + * close to this behavior by passing REQUEST_NO_BODY, but we need to + * return HTTP_UNSUPPORTED_MEDIA_TYPE (while ap_setup_client_block + * returns HTTP_REQUEST_ENTITY_TOO_LARGE). */ + + const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); + const char *lenp = apr_table_get(r->headers_in, "Content-Length"); + + /* make sure to set the Apache request fields properly. */ + r->read_body = REQUEST_NO_BODY; + r->read_chunked = 0; + r->remaining = 0; + + if (tenc) { + if (strcasecmp(tenc, "chunked")) { + /* Use this instead of Apache's default error string */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Unknown Transfer-Encoding %s", tenc); + return HTTP_NOT_IMPLEMENTED; + } + + r->read_chunked = 1; + } + else if (lenp) { + const char *pos = lenp; + + while (apr_isdigit(*pos) || apr_isspace(*pos)) { + ++pos; + } + + if (*pos != '\0') { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid Content-Length %s", lenp); + return HTTP_BAD_REQUEST; + } + + r->remaining = apr_atoi64(lenp); + } + + if (r->read_chunked || r->remaining > 0) { + /* ### log something? */ + + /* Apache will supply a default error for this. */ + return HTTP_UNSUPPORTED_MEDIA_TYPE; + } + + /* + * Get rid of the body. this will call ap_setup_client_block(), but + * our copy above has already verified its work. + */ + return ap_discard_request_body(r); +} + +/* handle the MKCOL method */ +static int dav_method_mkcol(request_rec *r) +{ + dav_resource *resource; + int resource_state; + dav_auto_version_info av_info; + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + dav_error *err; + dav_error *err2; + int result; + dav_dir_conf *conf; + dav_response *multi_status; + + /* handle the request body */ + /* ### this may move lower once we start processing bodies */ + if ((result = process_mkcol_body(r)) != OK) { + return result; + } + + conf = (dav_dir_conf *)ap_get_module_config(r->per_dir_config, + &dav_module); + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (resource->exists) { + /* oops. something was already there! */ + + /* Apache will supply a default error for this. */ + /* ### we should provide a specific error message! */ + return HTTP_METHOD_NOT_ALLOWED; + } + + resource_state = dav_get_resource_state(r, resource); + + /* + * Check If-Headers and existing locks. + * + * Note: depth == 0 normally requires no multistatus response. However, + * if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI + * other than the Request-URI, thereby requiring a multistatus. + * + * If the resource does not exist (DAV_RESOURCE_NULL), then we must + * check the resource *and* its parent. If the resource exists or is + * a locknull resource, then we check only the resource. + */ + if ((err = dav_validate_request(r, resource, 0, NULL, &multi_status, + resource_state == DAV_RESOURCE_NULL ? + DAV_VALIDATE_PARENT : + DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, multi_status); + } + + /* if versioned resource, make sure parent is checked out */ + if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */, + &av_info)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* try to create the collection */ + resource->collection = 1; + err = (*resource->hooks->create_collection)(resource); + + /* restore modifiability of parent back to what it was */ + err2 = dav_auto_checkin(r, NULL, err != NULL /* undo if error */, + 0 /*unlock*/, &av_info); + + /* check for errors now */ + if (err != NULL) { + return dav_handle_err(r, err, NULL); + } + if (err2 != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err->status, 0, + "The MKCOL was successful, but there " + "was a problem automatically checking in " + "the parent collection.", + err2); + dav_log_err(r, err, APLOG_WARNING); + } + + if (locks_hooks != NULL) { + dav_lockdb *lockdb; + + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) { + /* The directory creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The MKCOL was successful, but there " + "was a problem opening the lock database " + "which prevents inheriting locks from the " + "parent resources.", + err); + return dav_handle_err(r, err, NULL); + } + + /* notify lock system that we have created/replaced a resource */ + err = dav_notify_created(r, lockdb, resource, resource_state, 0); + + (*locks_hooks->close_lockdb)(lockdb); + + if (err != NULL) { + /* The dir creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The MKCOL was successful, but there " + "was a problem updating its lock " + "information.", + err); + return dav_handle_err(r, err, NULL); + } + } + + /* return an appropriate response (HTTP_CREATED) */ + return dav_created(r, NULL, "Collection", 0); +} + +/* handle the COPY and MOVE methods */ +static int dav_method_copymove(request_rec *r, int is_move) +{ + dav_resource *resource; + dav_resource *resnew; + dav_auto_version_info src_av_info = { 0 }; + dav_auto_version_info dst_av_info = { 0 }; + const char *body; + const char *dest; + dav_error *err; + dav_error *err2; + dav_error *err3; + dav_response *multi_response; + dav_lookup_result lookup; + int is_dir; + int overwrite; + int depth; + int result; + dav_lockdb *lockdb; + int replace_dest; + int resnew_state; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, !is_move /* label_allowed */, + 0 /* use_checked_in */, &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* If not a file or collection resource, COPY/MOVE not allowed */ + /* ### allow COPY/MOVE of DeltaV resource types */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR) { + body = apr_psprintf(r->pool, + "Cannot COPY/MOVE resource %s.", + ap_escape_html(r->pool, r->uri)); + return dav_error_response(r, HTTP_METHOD_NOT_ALLOWED, body); + } + + /* get the destination URI */ + dest = apr_table_get(r->headers_in, "Destination"); + if (dest == NULL) { + /* Look in headers provided by Netscape's Roaming Profiles */ + const char *nscp_host = apr_table_get(r->headers_in, "Host"); + const char *nscp_path = apr_table_get(r->headers_in, "New-uri"); + + if (nscp_host != NULL && nscp_path != NULL) + dest = apr_psprintf(r->pool, "http://%s%s", nscp_host, nscp_path); + } + if (dest == NULL) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request is missing a Destination header."); + return HTTP_BAD_REQUEST; + } + + lookup = dav_lookup_uri(dest, r, 1 /* must_be_absolute */); + if (lookup.rnew == NULL) { + if (lookup.err.status == HTTP_BAD_REQUEST) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", lookup.err.desc); + return HTTP_BAD_REQUEST; + } + + /* ### this assumes that dav_lookup_uri() only generates a status + * ### that Apache can provide a status line for!! */ + + return dav_error_response(r, lookup.err.status, lookup.err.desc); + } + if (lookup.rnew->status != HTTP_OK) { + const char *auth = apr_table_get(lookup.rnew->err_headers_out, + "WWW-Authenticate"); + if (lookup.rnew->status == HTTP_UNAUTHORIZED && auth != NULL) { + /* propagate the WWW-Authorization header up from the + * subreq so the client sees it. */ + apr_table_set(r->err_headers_out, "WWW-Authenticate", + apr_pstrdup(r->pool, auth)); + } + + /* ### how best to report this... */ + return dav_error_response(r, lookup.rnew->status, + "Destination URI had an error."); + } + + /* Resolve destination resource */ + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &resnew); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* are the two resources handled by the same repository? */ + if (resource->hooks != resnew->hooks) { + /* ### this message exposes some backend config, but screw it... */ + return dav_error_response(r, HTTP_BAD_GATEWAY, + "Destination URI is handled by a " + "different repository than the source URI. " + "MOVE or COPY between repositories is " + "not possible."); + } + + /* get and parse the overwrite header value */ + if ((overwrite = dav_get_overwrite(r)) < 0) { + /* dav_get_overwrite() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + + /* quick failure test: if dest exists and overwrite is false. */ + if (resnew->exists && !overwrite) { + /* Supply some text for the error response body. */ + return dav_error_response(r, HTTP_PRECONDITION_FAILED, + "Destination is not empty and " + "Overwrite is not \"T\""); + } + + /* are the source and destination the same? */ + if ((*resource->hooks->is_same_resource)(resource, resnew)) { + /* Supply some text for the error response body. */ + return dav_error_response(r, HTTP_FORBIDDEN, + "Source and Destination URIs are the same."); + + } + + is_dir = resource->collection; + + /* get and parse the Depth header value. "0" and "infinity" are legal. */ + if ((depth = dav_get_depth(r, DAV_INFINITY)) < 0) { + /* dav_get_depth() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + if (depth == 1) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth must be \"0\" or \"infinity\" for COPY or MOVE."); + return HTTP_BAD_REQUEST; + } + if (is_move && is_dir && depth != DAV_INFINITY) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth must be \"infinity\" when moving a collection."); + return HTTP_BAD_REQUEST; + } + + /* + * Check If-Headers and existing locks for each resource in the source + * if we are performing a MOVE. We will return a 424 response with a + * DAV:multistatus body. The multistatus responses will contain the + * information about any resource that fails the validation. + * + * We check the parent resource, too, since this is a MOVE. Moving the + * resource effectively removes it from the parent collection, so we + * must ensure that we have met the appropriate conditions. + * + * If a problem occurs with the Request-URI itself, then a plain error + * (rather than a multistatus) will be returned. + */ + if (is_move + && (err = dav_validate_request(r, resource, depth, NULL, + &multi_response, + DAV_VALIDATE_PARENT + | DAV_VALIDATE_USE_424, + NULL)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not MOVE %s due to a failed " + "precondition on the source " + "(e.g. locks).", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* + * Check If-Headers and existing locks for destination. Note that we + * use depth==infinity since the target (hierarchy) will be deleted + * before the move/copy is completed. + * + * Note that we are overwriting the target, which implies a DELETE, so + * we are subject to the error/response rules as a DELETE. Namely, we + * will return a 424 error if any of the validations fail. + * (see dav_method_delete() for more information) + */ + if ((err = dav_validate_request(lookup.rnew, resnew, DAV_INFINITY, NULL, + &multi_response, + DAV_VALIDATE_PARENT + | DAV_VALIDATE_USE_424, NULL)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not MOVE/COPY %s due to a " + "failed precondition on the " + "destination (e.g. locks).", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + if (is_dir + && depth == DAV_INFINITY + && (*resource->hooks->is_parent_resource)(resource, resnew)) { + /* Supply some text for the error response body. */ + return dav_error_response(r, HTTP_FORBIDDEN, + "Source collection contains the " + "Destination."); + + } + if (is_dir + && (*resnew->hooks->is_parent_resource)(resnew, resource)) { + /* The destination must exist (since it contains the source), and + * a condition above implies Overwrite==T. Obviously, we cannot + * delete the Destination before the MOVE/COPY, as that would + * delete the Source. + */ + + /* Supply some text for the error response body. */ + return dav_error_response(r, HTTP_FORBIDDEN, + "Destination collection contains the Source " + "and Overwrite has been specified."); + } + + /* ### for now, we don't need anything in the body */ + if ((result = ap_discard_request_body(r)) != OK) { + return result; + } + + if ((err = dav_open_lockdb(r, 0, &lockdb)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* remove any locks from the old resources */ + /* + * ### this is Yet Another Traversal. if we do a rename(), then we + * ### really don't have to do this in some cases since the inode + * ### values will remain constant across the move. but we can't + * ### know that fact from outside the provider :-( + * + * ### note that we now have a problem atomicity in the move/copy + * ### since a failure after this would have removed locks (technically, + * ### this is okay to do, but really...) + */ + if (is_move && lockdb != NULL) { + /* ### this is wrong! it blasts direct locks on parent resources */ + /* ### pass lockdb! */ + (void)dav_unlock(r, resource, NULL); + } + + /* if this is a move, then the source parent collection will be modified */ + if (is_move) { + if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */, + &src_av_info)) != NULL) { + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + } + + /* + * Remember the initial state of the destination, so the lock system + * can be notified as to how it changed. + */ + resnew_state = dav_get_resource_state(lookup.rnew, resnew); + + /* In a MOVE operation, the destination is replaced by the source. + * In a COPY operation, if the destination exists, is under version + * control, and is the same resource type as the source, + * then it should not be replaced, but modified to be a copy of + * the source. + */ + if (!resnew->exists) + replace_dest = 0; + else if (is_move || !resource->versioned) + replace_dest = 1; + else if (resource->type != resnew->type) + replace_dest = 1; + else if ((resource->collection == 0) != (resnew->collection == 0)) + replace_dest = 1; + else + replace_dest = 0; + + /* If the destination must be created or replaced, + * make sure the parent collection is writable + */ + if (!resnew->exists || replace_dest) { + if ((err = dav_auto_checkout(r, resnew, 1 /*parent_only*/, + &dst_av_info)) != NULL) { + /* could not make destination writable: + * if move, restore state of source parent + */ + if (is_move) { + (void)dav_auto_checkin(r, NULL, 1 /* undo */, + 0 /*unlock*/, &src_av_info); + } + + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + } + + /* If source and destination parents are the same, then + * use the same resource object, so status updates to one are reflected + * in the other, when doing auto-versioning. Otherwise, + * we may try to checkin the parent twice. + */ + if (src_av_info.parent_resource != NULL + && dst_av_info.parent_resource != NULL + && (*src_av_info.parent_resource->hooks->is_same_resource) + (src_av_info.parent_resource, dst_av_info.parent_resource)) { + + dst_av_info.parent_resource = src_av_info.parent_resource; + } + + /* If destination is being replaced, remove it first + * (we know Ovewrite must be TRUE). Then try to copy/move the resource. + */ + if (replace_dest) + err = (*resnew->hooks->remove_resource)(resnew, &multi_response); + + if (err == NULL) { + if (is_move) + err = (*resource->hooks->move_resource)(resource, resnew, + &multi_response); + else + err = (*resource->hooks->copy_resource)(resource, resnew, depth, + &multi_response); + } + + /* perform any auto-versioning cleanup */ + err2 = dav_auto_checkin(r, NULL, err != NULL /* undo if error */, + 0 /*unlock*/, &dst_av_info); + + if (is_move) { + err3 = dav_auto_checkin(r, NULL, err != NULL /* undo if error */, + 0 /*unlock*/, &src_av_info); + } + else + err3 = NULL; + + /* check for error from remove/copy/move operations */ + if (err != NULL) { + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not MOVE/COPY %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* check for errors from auto-versioning */ + if (err2 != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err2->status, 0, + "The MOVE/COPY was successful, but there was a " + "problem automatically checking in the " + "source parent collection.", + err2); + dav_log_err(r, err, APLOG_WARNING); + } + if (err3 != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err3->status, 0, + "The MOVE/COPY was successful, but there was a " + "problem automatically checking in the " + "destination or its parent collection.", + err3); + dav_log_err(r, err, APLOG_WARNING); + } + + /* propagate any indirect locks at the target */ + if (lockdb != NULL) { + + /* notify lock system that we have created/replaced a resource */ + err = dav_notify_created(r, lockdb, resnew, resnew_state, depth); + + (*lockdb->hooks->close_lockdb)(lockdb); + + if (err != NULL) { + /* The move/copy was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The MOVE/COPY was successful, but there " + "was a problem updating the lock " + "information.", + err); + return dav_handle_err(r, err, NULL); + } + } + + /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ + return dav_created(r, lookup.rnew->uri, "Destination", + resnew_state == DAV_RESOURCE_EXISTS); +} + +/* dav_method_lock: Handler to implement the DAV LOCK method + * Returns appropriate HTTP_* response. + */ +static int dav_method_lock(request_rec *r) +{ + dav_error *err; + dav_resource *resource; + const dav_hooks_locks *locks_hooks; + int result; + int depth; + int new_lock_request = 0; + apr_xml_doc *doc; + dav_lock *lock; + dav_response *multi_response = NULL; + dav_lockdb *lockdb; + int resource_state; + + /* If no locks provider, decline the request */ + locks_hooks = DAV_GET_HOOKS_LOCKS(r); + if (locks_hooks == NULL) + return DECLINED; + + if ((result = ap_xml_parse_input(r, &doc)) != OK) + return result; + + depth = dav_get_depth(r, DAV_INFINITY); + if (depth != 0 && depth != DAV_INFINITY) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth must be 0 or \"infinity\" for LOCK."); + return HTTP_BAD_REQUEST; + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* + * Open writable. Unless an error occurs, we'll be + * writing into the database. + */ + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + if (doc != NULL) { + if ((err = dav_lock_parse_lockinfo(r, resource, lockdb, doc, + &lock)) != NULL) { + /* ### add a higher-level description to err? */ + goto error; + } + new_lock_request = 1; + + lock->auth_user = apr_pstrdup(r->pool, r->user); + } + + resource_state = dav_get_resource_state(r, resource); + + /* + * Check If-Headers and existing locks. + * + * If this will create a locknull resource, then the LOCK will affect + * the parent collection (much like a PUT/MKCOL). For that case, we must + * validate the parent resource's conditions. + */ + if ((err = dav_validate_request(r, resource, depth, NULL, &multi_response, + (resource_state == DAV_RESOURCE_NULL + ? DAV_VALIDATE_PARENT + : DAV_VALIDATE_RESOURCE) + | (new_lock_request ? lock->scope : 0) + | DAV_VALIDATE_ADD_LD, + lockdb)) != OK) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not LOCK %s due to a failed " + "precondition (e.g. other locks).", + ap_escape_html(r->pool, r->uri)), + err); + goto error; + } + + if (new_lock_request == 0) { + dav_locktoken_list *ltl; + + /* + * Refresh request + * ### Assumption: We can renew multiple locks on the same resource + * ### at once. First harvest all the positive lock-tokens given in + * ### the If header. Then modify the lock entries for this resource + * ### with the new Timeout val. + */ + + if ((err = dav_get_locktoken_list(r, <l)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "The lock refresh for %s failed " + "because no lock tokens were " + "specified in an \"If:\" " + "header.", + ap_escape_html(r->pool, r->uri)), + err); + goto error; + } + + if ((err = (*locks_hooks->refresh_locks)(lockdb, resource, ltl, + dav_get_timeout(r), + &lock)) != NULL) { + /* ### add a higher-level description to err? */ + goto error; + } + } else { + /* New lock request */ + char *locktoken_txt; + dav_dir_conf *conf; + + conf = (dav_dir_conf *)ap_get_module_config(r->per_dir_config, + &dav_module); + + /* apply lower bound (if any) from DAVMinTimeout directive */ + if (lock->timeout != DAV_TIMEOUT_INFINITE + && lock->timeout < time(NULL) + conf->locktimeout) + lock->timeout = time(NULL) + conf->locktimeout; + + err = dav_add_lock(r, resource, lockdb, lock, &multi_response); + if (err != NULL) { + /* ### add a higher-level description to err? */ + goto error; + } + + locktoken_txt = apr_pstrcat(r->pool, "<", + (*locks_hooks->format_locktoken)(r->pool, + lock->locktoken), + ">", NULL); + + apr_table_set(r->headers_out, "Lock-Token", locktoken_txt); + } + + (*locks_hooks->close_lockdb)(lockdb); + + r->status = HTTP_OK; + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + ap_rputs(DAV_XML_HEADER DEBUG_CR "" DEBUG_CR, r); + if (lock == NULL) + ap_rputs("" DEBUG_CR, r); + else { + ap_rprintf(r, + "" DEBUG_CR + "%s" DEBUG_CR + "" DEBUG_CR, + dav_lock_get_activelock(r, lock, NULL)); + } + ap_rputs("", r); + + /* the response has been sent. */ + return DONE; + + error: + (*locks_hooks->close_lockdb)(lockdb); + return dav_handle_err(r, err, multi_response); +} + +/* dav_method_unlock: Handler to implement the DAV UNLOCK method + * Returns appropriate HTTP_* response. + */ +static int dav_method_unlock(request_rec *r) +{ + dav_error *err; + dav_resource *resource; + const dav_hooks_locks *locks_hooks; + int result; + const char *const_locktoken_txt; + char *locktoken_txt; + dav_locktoken *locktoken = NULL; + int resource_state; + dav_response *multi_response; + + /* If no locks provider, decline the request */ + locks_hooks = DAV_GET_HOOKS_LOCKS(r); + if (locks_hooks == NULL) + return DECLINED; + + if ((const_locktoken_txt = apr_table_get(r->headers_in, + "Lock-Token")) == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Unlock failed (%s): " + "No Lock-Token specified in header", r->filename); + return HTTP_BAD_REQUEST; + } + + locktoken_txt = apr_pstrdup(r->pool, const_locktoken_txt); + if (locktoken_txt[0] != '<') { + /* ### should provide more specifics... */ + return HTTP_BAD_REQUEST; + } + locktoken_txt++; + + if (locktoken_txt[strlen(locktoken_txt) - 1] != '>') { + /* ### should provide more specifics... */ + return HTTP_BAD_REQUEST; + } + locktoken_txt[strlen(locktoken_txt) - 1] = '\0'; + + if ((err = (*locks_hooks->parse_locktoken)(r->pool, locktoken_txt, + &locktoken)) != NULL) { + err = dav_push_error(r->pool, HTTP_BAD_REQUEST, 0, + apr_psprintf(r->pool, + "The UNLOCK on %s failed -- an " + "invalid lock token was specified " + "in the \"If:\" header.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + resource_state = dav_get_resource_state(r, resource); + + /* + * Check If-Headers and existing locks. + * + * Note: depth == 0 normally requires no multistatus response. However, + * if we pass DAV_VALIDATE_PARENT, then we could get an error on a URI + * other than the Request-URI, thereby requiring a multistatus. + * + * If the resource is a locknull resource, then the UNLOCK will affect + * the parent collection (much like a delete). For that case, we must + * validate the parent resource's conditions. + */ + if ((err = dav_validate_request(r, resource, 0, locktoken, + &multi_response, + resource_state == DAV_RESOURCE_LOCK_NULL + ? DAV_VALIDATE_PARENT + : DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, multi_response); + } + + /* ### RFC 2518 s. 8.11: If this resource is locked by locktoken, + * _all_ resources locked by locktoken are released. It does not say + * resource has to be the root of an infinte lock. Thus, an UNLOCK + * on any part of an infinte lock will remove the lock on all resources. + * + * For us, if r->filename represents an indirect lock (part of an infinity lock), + * we must actually perform an UNLOCK on the direct lock for this resource. + */ + if ((result = dav_unlock(r, resource, locktoken)) != OK) { + return result; + } + + return HTTP_NO_CONTENT; +} + +static int dav_method_vsn_control(request_rec *r) +{ + dav_resource *resource; + int resource_state; + dav_auto_version_info av_info; + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + apr_xml_doc *doc; + const char *target = NULL; + int result; + + /* if no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + /* ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* remember the pre-creation resource state */ + resource_state = dav_get_resource_state(r, resource); + + /* parse the request body (may be a version-control element) */ + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + /* note: doc == NULL if no request body */ + + if (doc != NULL) { + const apr_xml_elem *child; + apr_size_t tsize; + + if (!dav_validate_root(doc, "version-control")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body does not contain " + "a \"version-control\" element."); + return HTTP_BAD_REQUEST; + } + + /* get the version URI */ + if ((child = dav_find_child(doc->root, "version")) == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"version-control\" element does not contain " + "a \"version\" element."); + return HTTP_BAD_REQUEST; + } + + if ((child = dav_find_child(child, "href")) == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"version\" element does not contain " + "an \"href\" element."); + return HTTP_BAD_REQUEST; + } + + /* get version URI */ + apr_xml_to_text(r->pool, child, APR_XML_X2T_INNER, NULL, NULL, + &target, &tsize); + if (tsize == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "An \"href\" element does not contain a URI."); + return HTTP_BAD_REQUEST; + } + } + + /* Check request preconditions */ + + /* ### need a general mechanism for reporting precondition violations + * ### (should be returning XML document for 403/409 responses) + */ + + /* if not versioning existing resource, must specify version to select */ + if (!resource->exists && target == NULL) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + return dav_handle_err(r, err, NULL); + } + else if (resource->exists) { + /* cannot add resource to existing version history */ + if (target != NULL) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + return dav_handle_err(r, err, NULL); + } + + /* resource must be unversioned and versionable, or version selector */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR + || (!resource->versioned && !(vsn_hooks->versionable)(resource))) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + return dav_handle_err(r, err, NULL); + } + + /* the DeltaV spec says if resource is a version selector, + * then VERSION-CONTROL is a no-op + */ + if (resource->versioned) { + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* no body */ + ap_set_content_length(r, 0); + + return DONE; + } + } + + /* Check If-Headers and existing locks */ + /* Note: depth == 0. Implies no need for a multistatus response. */ + if ((err = dav_validate_request(r, resource, 0, NULL, NULL, + resource_state == DAV_RESOURCE_NULL ? + DAV_VALIDATE_PARENT : + DAV_VALIDATE_RESOURCE, NULL)) != NULL) { + return dav_handle_err(r, err, NULL); + } + + /* if in versioned collection, make sure parent is checked out */ + if ((err = dav_auto_checkout(r, resource, 1 /* parent_only */, + &av_info)) != NULL) { + return dav_handle_err(r, err, NULL); + } + + /* attempt to version-control the resource */ + if ((err = (*vsn_hooks->vsn_control)(resource, target)) != NULL) { + dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, &av_info); + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Could not VERSION-CONTROL resource %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* revert writability of parent directory */ + err = dav_auto_checkin(r, resource, 0 /*undo*/, 0 /*unlock*/, &av_info); + if (err != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err->status, 0, + "The VERSION-CONTROL was successful, but there " + "was a problem automatically checking in " + "the parent collection.", + err); + dav_log_err(r, err, APLOG_WARNING); + } + + /* if the resource is lockable, let lock system know of new resource */ + if (locks_hooks != NULL + && (*locks_hooks->get_supportedlock)(resource) != NULL) { + dav_lockdb *lockdb; + + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) { + /* The resource creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The VERSION-CONTROL was successful, but there " + "was a problem opening the lock database " + "which prevents inheriting locks from the " + "parent resources.", + err); + return dav_handle_err(r, err, NULL); + } + + /* notify lock system that we have created/replaced a resource */ + err = dav_notify_created(r, lockdb, resource, resource_state, 0); + + (*locks_hooks->close_lockdb)(lockdb); + + if (err != NULL) { + /* The dir creation was successful, but the locking failed. */ + err = dav_push_error(r->pool, err->status, 0, + "The VERSION-CONTROL was successful, but there " + "was a problem updating its lock " + "information.", + err); + return dav_handle_err(r, err, NULL); + } + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* return an appropriate response (HTTP_CREATED) */ + return dav_created(r, resource->uri, "Version selector", 0 /*replaced*/); +} + +/* handle the CHECKOUT method */ +static int dav_method_checkout(request_rec *r) +{ + dav_resource *resource; + dav_resource *working_resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + int result; + apr_xml_doc *doc; + int apply_to_vsn = 0; + int is_unreserved = 0; + int is_fork_ok = 0; + int create_activity = 0; + apr_array_header_t *activities = NULL; + + /* If no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + if ((result = ap_xml_parse_input(r, &doc)) != OK) + return result; + + if (doc != NULL) { + const apr_xml_elem *aset; + + if (!dav_validate_root(doc, "checkout")) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body, if present, must be a " + "DAV:checkout element."); + return HTTP_BAD_REQUEST; + } + + if (dav_find_child(doc->root, "apply-to-version") != NULL) { + if (apr_table_get(r->headers_in, "label") != NULL) { + /* ### we want generic 403/409 XML reporting here */ + /* ### DAV:must-not-have-label-and-apply-to-version */ + return dav_error_response(r, HTTP_CONFLICT, + "DAV:apply-to-version cannot be " + "used in conjunction with a " + "Label header."); + } + apply_to_vsn = 1; + } + + is_unreserved = dav_find_child(doc->root, "unreserved") != NULL; + is_fork_ok = dav_find_child(doc->root, "fork-ok") != NULL; + + if ((aset = dav_find_child(doc->root, "activity-set")) != NULL) { + if (dav_find_child(aset, "new") != NULL) { + create_activity = 1; + } + else { + const apr_xml_elem *child = aset->first_child; + + activities = apr_array_make(r->pool, 1, sizeof(const char *)); + + for (; child != NULL; child = child->next) { + if (child->ns == APR_XML_NS_DAV_ID + && strcmp(child->name, "href") == 0) { + const char *href; + + href = dav_xml_get_cdata(child, r->pool, + 1 /* strip_white */); + *(const char **)apr_array_push(activities) = href; + } + } + + if (activities->nelts == 0) { + /* no href's is a DTD violation: + + */ + + /* This supplies additional info for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Within the DAV:activity-set element, the " + "DAV:new element must be used, or at least " + "one DAV:href must be specified."); + return HTTP_BAD_REQUEST; + } + } + } + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 1 /*label_allowed*/, apply_to_vsn, &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* Check the state of the resource: must be a file or collection, + * must be versioned, and must not already be checked out. + */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR + && resource->type != DAV_RESOURCE_TYPE_VERSION) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot checkout this type of resource."); + } + + if (!resource->versioned) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot checkout unversioned resource."); + } + + if (resource->working) { + return dav_error_response(r, HTTP_CONFLICT, + "The resource is already checked out to the workspace."); + } + + /* ### do lock checks, once behavior is defined */ + + /* Do the checkout */ + if ((err = (*vsn_hooks->checkout)(resource, 0 /*auto_checkout*/, + is_unreserved, is_fork_ok, + create_activity, activities, + &working_resource)) != NULL) { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Could not CHECKOUT resource %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* if no working resource created, return OK, + * else return CREATED with working resource URL in Location header + */ + if (working_resource == NULL) { + /* no body */ + ap_set_content_length(r, 0); + return DONE; + } + + return dav_created(r, working_resource->uri, "Checked-out resource", 0); +} + +/* handle the UNCHECKOUT method */ +static int dav_method_uncheckout(request_rec *r) +{ + dav_resource *resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + int result; + + /* If no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + if ((result = ap_discard_request_body(r)) != OK) { + return result; + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* Check the state of the resource: must be a file or collection, + * must be versioned, and must be checked out. + */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot uncheckout this type of resource."); + } + + if (!resource->versioned) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot uncheckout unversioned resource."); + } + + if (!resource->working) { + return dav_error_response(r, HTTP_CONFLICT, + "The resource is not checked out to the workspace."); + } + + /* ### do lock checks, once behavior is defined */ + + /* Do the uncheckout */ + if ((err = (*vsn_hooks->uncheckout)(resource)) != NULL) { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Could not UNCHECKOUT resource %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* no body */ + ap_set_content_length(r, 0); + + return DONE; +} + +/* handle the CHECKIN method */ +static int dav_method_checkin(request_rec *r) +{ + dav_resource *resource; + dav_resource *new_version; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + int result; + apr_xml_doc *doc; + int keep_checked_out = 0; + + /* If no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + if ((result = ap_xml_parse_input(r, &doc)) != OK) + return result; + + if (doc != NULL) { + if (!dav_validate_root(doc, "checkin")) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body, if present, must be a " + "DAV:checkin element."); + return HTTP_BAD_REQUEST; + } + + keep_checked_out = dav_find_child(doc->root, "keep-checked-out") != NULL; + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* Check the state of the resource: must be a file or collection, + * must be versioned, and must be checked out. + */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot checkin this type of resource."); + } + + if (!resource->versioned) { + return dav_error_response(r, HTTP_CONFLICT, + "Cannot checkin unversioned resource."); + } + + if (!resource->working) { + return dav_error_response(r, HTTP_CONFLICT, + "The resource is not checked out."); + } + + /* ### do lock checks, once behavior is defined */ + + /* Do the checkin */ + if ((err = (*vsn_hooks->checkin)(resource, keep_checked_out, &new_version)) + != NULL) { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Could not CHECKIN resource %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + return dav_created(r, new_version->uri, "Version", 0); +} + +static int dav_method_update(request_rec *r) +{ + dav_resource *resource; + dav_resource *version = NULL; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + apr_xml_doc *doc; + apr_xml_elem *child; + int is_label = 0; + int depth; + int result; + apr_size_t tsize; + const char *target; + dav_response *multi_response; + dav_error *err; + dav_lookup_result lookup; + + /* If no versioning provider, or UPDATE not supported, + * decline the request */ + if (vsn_hooks == NULL || vsn_hooks->update == NULL) + return DECLINED; + + if ((depth = dav_get_depth(r, 0)) < 0) { + /* dav_get_depth() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + + /* parse the request body */ + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + + if (doc == NULL || !dav_validate_root(doc, "update")) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body does not contain " + "an \"update\" element."); + return HTTP_BAD_REQUEST; + } + + /* check for label-name or version element, but not both */ + if ((child = dav_find_child(doc->root, "label-name")) != NULL) + is_label = 1; + else if ((child = dav_find_child(doc->root, "version")) != NULL) { + /* get the href element */ + if ((child = dav_find_child(child, "href")) == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The version element does not contain " + "an \"href\" element."); + return HTTP_BAD_REQUEST; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"update\" element does not contain " + "a \"label-name\" or \"version\" element."); + return HTTP_BAD_REQUEST; + } + + /* a depth greater than zero is only allowed for a label */ + if (!is_label && depth != 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Depth must be zero for UPDATE with a version"); + return HTTP_BAD_REQUEST; + } + + /* get the target value (a label or a version URI) */ + apr_xml_to_text(r->pool, child, APR_XML_X2T_INNER, NULL, NULL, + &target, &tsize); + if (tsize == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "A \"label-name\" or \"href\" element does not contain " + "any content."); + return HTTP_BAD_REQUEST; + } + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* ### need a general mechanism for reporting precondition violations + * ### (should be returning XML document for 403/409 responses) + */ + if (resource->type != DAV_RESOURCE_TYPE_REGULAR + || !resource->versioned || resource->working) { + return dav_error_response(r, HTTP_CONFLICT, + ""); + } + + /* if target is a version, resolve the version resource */ + /* ### dav_lookup_uri only allows absolute URIs; is that OK? */ + if (!is_label) { + lookup = dav_lookup_uri(target, r, 0 /* must_be_absolute */); + if (lookup.rnew == NULL) { + if (lookup.err.status == HTTP_BAD_REQUEST) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", lookup.err.desc); + return HTTP_BAD_REQUEST; + } + + /* ### this assumes that dav_lookup_uri() only generates a status + * ### that Apache can provide a status line for!! */ + + return dav_error_response(r, lookup.err.status, lookup.err.desc); + } + if (lookup.rnew->status != HTTP_OK) { + /* ### how best to report this... */ + return dav_error_response(r, lookup.rnew->status, + "Version URI had an error."); + } + + /* resolve version resource */ + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &version); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* NULL out target, since we're using a version resource */ + target = NULL; + } + + /* do the UPDATE operation */ + err = (*vsn_hooks->update)(resource, version, target, depth, &multi_response); + + if (err != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not UPDATE %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* no body */ + ap_set_content_length(r, 0); + + return DONE; +} + +/* context maintained during LABEL treewalk */ +typedef struct dav_label_walker_ctx +{ + /* input: */ + dav_walk_params w; + + /* label being manipulated */ + const char *label; + + /* label operation */ + int label_op; +#define DAV_LABEL_ADD 1 +#define DAV_LABEL_SET 2 +#define DAV_LABEL_REMOVE 3 + + /* version provider hooks */ + const dav_hooks_vsn *vsn_hooks; + +} dav_label_walker_ctx; + +static dav_error * dav_label_walker(dav_walk_resource *wres, int calltype) +{ + dav_label_walker_ctx *ctx = wres->walk_ctx; + dav_error *err = NULL; + + /* Check the state of the resource: must be a version or + * non-checkedout version selector + */ + /* ### need a general mechanism for reporting precondition violations + * ### (should be returning XML document for 403/409 responses) + */ + if (wres->resource->type != DAV_RESOURCE_TYPE_VERSION && + (wres->resource->type != DAV_RESOURCE_TYPE_REGULAR + || !wres->resource->versioned)) { + err = dav_new_error(ctx->w.pool, HTTP_CONFLICT, 0, + ""); + } + else if (wres->resource->working) { + err = dav_new_error(ctx->w.pool, HTTP_CONFLICT, 0, + ""); + } + else { + /* do the label operation */ + if (ctx->label_op == DAV_LABEL_REMOVE) + err = (*ctx->vsn_hooks->remove_label)(wres->resource, ctx->label); + else + err = (*ctx->vsn_hooks->add_label)(wres->resource, ctx->label, + ctx->label_op == DAV_LABEL_SET); + } + + if (err != NULL) { + /* ### need utility routine to add response with description? */ + dav_add_response(wres, err->status, NULL); + wres->response->desc = err->desc; + } + + return NULL; +} + +static int dav_method_label(request_rec *r) +{ + dav_resource *resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + apr_xml_doc *doc; + apr_xml_elem *child; + int depth; + int result; + apr_size_t tsize; + dav_error *err; + dav_label_walker_ctx ctx = { { 0 } }; + dav_response *multi_status; + + /* If no versioning provider, or the provider doesn't support + * labels, decline the request */ + if (vsn_hooks == NULL || vsn_hooks->add_label == NULL) + return DECLINED; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + if ((depth = dav_get_depth(r, 0)) < 0) { + /* dav_get_depth() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + + /* parse the request body */ + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + + if (doc == NULL || !dav_validate_root(doc, "label")) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body does not contain " + "a \"label\" element."); + return HTTP_BAD_REQUEST; + } + + /* check for add, set, or remove element */ + if ((child = dav_find_child(doc->root, "add")) != NULL) { + ctx.label_op = DAV_LABEL_ADD; + } + else if ((child = dav_find_child(doc->root, "set")) != NULL) { + ctx.label_op = DAV_LABEL_SET; + } + else if ((child = dav_find_child(doc->root, "remove")) != NULL) { + ctx.label_op = DAV_LABEL_REMOVE; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The \"label\" element does not contain " + "an \"add\", \"set\", or \"remove\" element."); + return HTTP_BAD_REQUEST; + } + + /* get the label string */ + if ((child = dav_find_child(child, "label-name")) == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The label command element does not contain " + "a \"label-name\" element."); + return HTTP_BAD_REQUEST; + } + + apr_xml_to_text(r->pool, child, APR_XML_X2T_INNER, NULL, NULL, + &ctx.label, &tsize); + if (tsize == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "A \"label-name\" element does not contain " + "a label name."); + return HTTP_BAD_REQUEST; + } + + /* do the label operation walk */ + ctx.w.walk_type = DAV_WALKTYPE_NORMAL; + ctx.w.func = dav_label_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = resource; + ctx.vsn_hooks = vsn_hooks; + + err = (*resource->hooks->walk)(&ctx.w, depth, &multi_status); + + if (err != NULL) { + /* some sort of error occurred which terminated the walk */ + err = dav_push_error(r->pool, err->status, 0, + "The LABEL operation was terminated prematurely.", + err); + return dav_handle_err(r, err, multi_status); + } + + if (multi_status != NULL) { + /* One or more resources had errors. If depth was zero, convert + * response to simple error, else make sure there is an + * overall error to pass to dav_handle_err() + */ + if (depth == 0) { + err = dav_new_error(r->pool, multi_status->status, 0, multi_status->desc); + multi_status = NULL; + } + else { + err = dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, + "Errors occurred during the LABEL operation."); + } + + return dav_handle_err(r, err, multi_status); + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* no body */ + ap_set_content_length(r, 0); + + return DONE; +} + +static int dav_method_report(request_rec *r) +{ + dav_resource *resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + int result; + int label_allowed; + apr_xml_doc *doc; + dav_error *err; + + /* If no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + if ((result = ap_xml_parse_input(r, &doc)) != OK) + return result; + if (doc == NULL) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body must specify a report."); + return HTTP_BAD_REQUEST; + } + + /* Ask repository module to resolve the resource. + * First determine whether a Target-Selector header is allowed + * for this report. + */ + label_allowed = (*vsn_hooks->report_label_header_allowed)(doc); + err = dav_get_resource(r, label_allowed, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* set up defaults for the report response */ + r->status = HTTP_OK; + ap_set_content_type(r, DAV_XML_CONTENT_TYPE); + + /* run report hook */ + if ((err = (*vsn_hooks->deliver_report)(r, resource, doc, + r->output_filters)) != NULL) { + if (! r->sent_bodyct) + /* No data has been sent to client yet; throw normal error. */ + return dav_handle_err(r, err, NULL); + + /* If an error occurred during the report delivery, there's + basically nothing we can do but abort the connection and + log an error. This is one of the limitations of HTTP; it + needs to "know" the entire status of the response before + generating it, which is just impossible in these streamy + response situations. */ + err = dav_push_error(r->pool, err->status, 0, + "Provider encountered an error while streaming" + " a REPORT response.", err); + dav_log_err(r, err, APLOG_ERR); + r->connection->aborted = 1; + return DONE; + } + + return DONE; +} + +static int dav_method_make_workspace(request_rec *r) +{ + dav_resource *resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + apr_xml_doc *doc; + int result; + + /* if no versioning provider, or the provider does not support workspaces, + * decline the request + */ + if (vsn_hooks == NULL || vsn_hooks->make_workspace == NULL) + return DECLINED; + + /* ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* parse the request body (must be a mkworkspace element) */ + if ((result = ap_xml_parse_input(r, &doc)) != OK) { + return result; + } + + if (doc == NULL + || !dav_validate_root(doc, "mkworkspace")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body does not contain " + "a \"mkworkspace\" element."); + return HTTP_BAD_REQUEST; + } + + /* Check request preconditions */ + + /* ### need a general mechanism for reporting precondition violations + * ### (should be returning XML document for 403/409 responses) + */ + + /* resource must not already exist */ + if (resource->exists) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + return dav_handle_err(r, err, NULL); + } + + /* ### what about locking? */ + + /* attempt to create the workspace */ + if ((err = (*vsn_hooks->make_workspace)(resource, doc)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not create workspace %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* return an appropriate response (HTTP_CREATED) */ + return dav_created(r, resource->uri, "Workspace", 0 /*replaced*/); +} + +static int dav_method_make_activity(request_rec *r) +{ + dav_resource *resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + int result; + + /* if no versioning provider, or the provider does not support activities, + * decline the request + */ + if (vsn_hooks == NULL || vsn_hooks->make_activity == NULL) + return DECLINED; + + /* ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* MKACTIVITY does not have a defined request body. */ + if ((result = ap_discard_request_body(r)) != OK) { + return result; + } + + /* Check request preconditions */ + + /* ### need a general mechanism for reporting precondition violations + * ### (should be returning XML document for 403/409 responses) + */ + + /* resource must not already exist */ + if (resource->exists) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + return dav_handle_err(r, err, NULL); + } + + /* the provider must say whether the resource can be created as + an activity, i.e. whether the location is ok. */ + if (vsn_hooks->can_be_activity != NULL + && !(*vsn_hooks->can_be_activity)(resource)) { + err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0, + ""); + return dav_handle_err(r, err, NULL); + } + + /* ### what about locking? */ + + /* attempt to create the activity */ + if ((err = (*vsn_hooks->make_activity)(resource)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not create activity %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* set the Cache-Control header, per the spec */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* return an appropriate response (HTTP_CREATED) */ + return dav_created(r, resource->uri, "Activity", 0 /*replaced*/); +} + +static int dav_method_baseline_control(request_rec *r) +{ + /* ### */ + return HTTP_METHOD_NOT_ALLOWED; +} + +static int dav_method_merge(request_rec *r) +{ + dav_resource *resource; + dav_resource *source_resource; + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err; + int result; + apr_xml_doc *doc; + apr_xml_elem *source_elem; + apr_xml_elem *href_elem; + apr_xml_elem *prop_elem; + const char *source; + int no_auto_merge; + int no_checkout; + dav_lookup_result lookup; + + /* If no versioning provider, decline the request */ + if (vsn_hooks == NULL) + return DECLINED; + + if ((result = ap_xml_parse_input(r, &doc)) != OK) + return result; + + if (doc == NULL || !dav_validate_root(doc, "merge")) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request body must be present and must be a " + "DAV:merge element."); + return HTTP_BAD_REQUEST; + } + + if ((source_elem = dav_find_child(doc->root, "source")) == NULL) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The DAV:merge element must contain a DAV:source " + "element."); + return HTTP_BAD_REQUEST; + } + if ((href_elem = dav_find_child(source_elem, "href")) == NULL) { + /* This supplies additional information for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The DAV:source element must contain a DAV:href " + "element."); + return HTTP_BAD_REQUEST; + } + source = dav_xml_get_cdata(href_elem, r->pool, 1 /* strip_white */); + + /* get a subrequest for the source, so that we can get a dav_resource + for that source. */ + lookup = dav_lookup_uri(source, r, 0 /* must_be_absolute */); + if (lookup.rnew == NULL) { + if (lookup.err.status == HTTP_BAD_REQUEST) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", lookup.err.desc); + return HTTP_BAD_REQUEST; + } + + /* ### this assumes that dav_lookup_uri() only generates a status + * ### that Apache can provide a status line for!! */ + + return dav_error_response(r, lookup.err.status, lookup.err.desc); + } + if (lookup.rnew->status != HTTP_OK) { + /* ### how best to report this... */ + return dav_error_response(r, lookup.rnew->status, + "Merge source URI had an error."); + } + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &source_resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + no_auto_merge = dav_find_child(doc->root, "no-auto-merge") != NULL; + no_checkout = dav_find_child(doc->root, "no-checkout") != NULL; + + prop_elem = dav_find_child(doc->root, "prop"); + + /* ### check RFC. I believe the DAV:merge element may contain any + ### element also allowed within DAV:checkout. need to extract them + ### here, and pass them along. + ### if so, then refactor the CHECKOUT method handling so we can reuse + ### the code. maybe create a structure to hold CHECKOUT parameters + ### which can be passed to the checkout() and merge() hooks. */ + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* ### check the source and target resources flags/types */ + + /* ### do lock checks, once behavior is defined */ + + /* set the Cache-Control header, per the spec */ + /* ### correct? */ + apr_table_setn(r->headers_out, "Cache-Control", "no-cache"); + + /* Initialize these values for a standard MERGE response. If the MERGE + is going to do something different (i.e. an error), then it must + return a dav_error, and we'll reset these values properly. */ + r->status = HTTP_OK; + ap_set_content_type(r, "text/xml"); + + /* ### should we do any preliminary response generation? probably not, + ### because we may have an error, thus demanding something else in + ### the response body. */ + + /* Do the merge, including any response generation. */ + if ((err = (*vsn_hooks->merge)(resource, source_resource, + no_auto_merge, no_checkout, + prop_elem, + r->output_filters)) != NULL) { + /* ### is err->status the right error here? */ + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not MERGE resource \"%s\" " + "into \"%s\".", + ap_escape_html(r->pool, source), + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, NULL); + } + + /* the response was fully generated by the merge() hook. */ + /* ### urk. does this prevent logging? need to check... */ + return DONE; +} + +static int dav_method_bind(request_rec *r) +{ + dav_resource *resource; + dav_resource *binding; + dav_auto_version_info av_info; + const dav_hooks_binding *binding_hooks = DAV_GET_HOOKS_BINDING(r); + const char *dest; + dav_error *err; + dav_error *err2; + dav_response *multi_response = NULL; + dav_lookup_result lookup; + int overwrite; + + /* If no bindings provider, decline the request */ + if (binding_hooks == NULL) + return DECLINED; + + /* Ask repository module to resolve the resource */ + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* get the destination URI */ + dest = apr_table_get(r->headers_in, "Destination"); + if (dest == NULL) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "The request is missing a Destination header."); + return HTTP_BAD_REQUEST; + } + + lookup = dav_lookup_uri(dest, r, 0 /* must_be_absolute */); + if (lookup.rnew == NULL) { + if (lookup.err.status == HTTP_BAD_REQUEST) { + /* This supplies additional information for the default message. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", lookup.err.desc); + return HTTP_BAD_REQUEST; + } + else if (lookup.err.status == HTTP_BAD_GATEWAY) { + /* ### Bindings protocol draft 02 says to return 507 + * ### (Cross Server Binding Forbidden); Apache already defines 507 + * ### as HTTP_INSUFFICIENT_STORAGE. So, for now, we'll return + * ### HTTP_FORBIDDEN + */ + return dav_error_response(r, HTTP_FORBIDDEN, + "Cross server bindings are not " + "allowed by this server."); + } + + /* ### this assumes that dav_lookup_uri() only generates a status + * ### that Apache can provide a status line for!! */ + + return dav_error_response(r, lookup.err.status, lookup.err.desc); + } + if (lookup.rnew->status != HTTP_OK) { + /* ### how best to report this... */ + return dav_error_response(r, lookup.rnew->status, + "Destination URI had an error."); + } + + /* resolve binding resource */ + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &binding); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + /* are the two resources handled by the same repository? */ + if (resource->hooks != binding->hooks) { + /* ### this message exposes some backend config, but screw it... */ + return dav_error_response(r, HTTP_BAD_GATEWAY, + "Destination URI is handled by a " + "different repository than the source URI. " + "BIND between repositories is not possible."); + } + + /* get and parse the overwrite header value */ + if ((overwrite = dav_get_overwrite(r)) < 0) { + /* dav_get_overwrite() supplies additional information for the + * default message. */ + return HTTP_BAD_REQUEST; + } + + /* quick failure test: if dest exists and overwrite is false. */ + if (binding->exists && !overwrite) { + return dav_error_response(r, HTTP_PRECONDITION_FAILED, + "Destination is not empty and " + "Overwrite is not \"T\""); + } + + /* are the source and destination the same? */ + if ((*resource->hooks->is_same_resource)(resource, binding)) { + return dav_error_response(r, HTTP_FORBIDDEN, + "Source and Destination URIs are the same."); + } + + /* + * Check If-Headers and existing locks for destination. Note that we + * use depth==infinity since the target (hierarchy) will be deleted + * before the move/copy is completed. + * + * Note that we are overwriting the target, which implies a DELETE, so + * we are subject to the error/response rules as a DELETE. Namely, we + * will return a 424 error if any of the validations fail. + * (see dav_method_delete() for more information) + */ + if ((err = dav_validate_request(lookup.rnew, binding, DAV_INFINITY, NULL, + &multi_response, + DAV_VALIDATE_PARENT + | DAV_VALIDATE_USE_424, NULL)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not BIND %s due to a " + "failed precondition on the " + "destination (e.g. locks).", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* guard against creating circular bindings */ + if (resource->collection + && (*resource->hooks->is_parent_resource)(resource, binding)) { + return dav_error_response(r, HTTP_FORBIDDEN, + "Source collection contains the Destination."); + } + if (resource->collection + && (*resource->hooks->is_parent_resource)(binding, resource)) { + /* The destination must exist (since it contains the source), and + * a condition above implies Overwrite==T. Obviously, we cannot + * delete the Destination before the BIND, as that would + * delete the Source. + */ + + return dav_error_response(r, HTTP_FORBIDDEN, + "Destination collection contains the Source and " + "Overwrite has been specified."); + } + + /* prepare the destination collection for modification */ + if ((err = dav_auto_checkout(r, binding, 1 /* parent_only */, + &av_info)) != NULL) { + /* could not make destination writable */ + return dav_handle_err(r, err, NULL); + } + + /* If target exists, remove it first (we know Ovewrite must be TRUE). + * Then try to bind to the resource. + */ + if (binding->exists) + err = (*resource->hooks->remove_resource)(binding, &multi_response); + + if (err == NULL) { + err = (*binding_hooks->bind_resource)(resource, binding); + } + + /* restore parent collection states */ + err2 = dav_auto_checkin(r, NULL, + err != NULL /* undo if error */, + 0 /* unlock */, &av_info); + + /* check for error from remove/bind operations */ + if (err != NULL) { + err = dav_push_error(r->pool, err->status, 0, + apr_psprintf(r->pool, + "Could not BIND %s.", + ap_escape_html(r->pool, r->uri)), + err); + return dav_handle_err(r, err, multi_response); + } + + /* check for errors from reverting writability */ + if (err2 != NULL) { + /* just log a warning */ + err = dav_push_error(r->pool, err2->status, 0, + "The BIND was successful, but there was a " + "problem automatically checking in the " + "source parent collection.", + err2); + dav_log_err(r, err, APLOG_WARNING); + } + + /* return an appropriate response (HTTP_CREATED) */ + /* ### spec doesn't say what happens when destination was replaced */ + return dav_created(r, lookup.rnew->uri, "Binding", 0); +} + + +/* + * Response handler for DAV resources + */ +static int dav_handler(request_rec *r) +{ + if (strcmp(r->handler, DAV_HANDLER_NAME) != 0) + return DECLINED; + + /* Reject requests with an unescaped hash character, as these may + * be more destructive than the user intended. */ + if (r->parsed_uri.fragment != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "buggy client used un-escaped hash in Request-URI"); + return dav_error_response(r, HTTP_BAD_REQUEST, + "The request was invalid: the URI included " + "an un-escaped hash character"); + } + + /* ### do we need to do anything with r->proxyreq ?? */ + + /* + * ### anything else to do here? could another module and/or + * ### config option "take over" the handler here? i.e. how do + * ### we lock down this hierarchy so that we are the ultimate + * ### arbiter? (or do we simply depend on the administrator + * ### to avoid conflicting configurations?) + */ + + /* + * Set up the methods mask, since that's one of the reasons this handler + * gets called, and lower-level things may need the info. + * + * First, set the mask to the methods we handle directly. Since by + * definition we own our managed space, we unconditionally set + * the r->allowed field rather than ORing our values with anything + * any other module may have put in there. + * + * These are the HTTP-defined methods that we handle directly. + */ + r->allowed = 0 + | (AP_METHOD_BIT << M_GET) + | (AP_METHOD_BIT << M_PUT) + | (AP_METHOD_BIT << M_DELETE) + | (AP_METHOD_BIT << M_OPTIONS) + | (AP_METHOD_BIT << M_INVALID); + + /* + * These are the DAV methods we handle. + */ + r->allowed |= 0 + | (AP_METHOD_BIT << M_COPY) + | (AP_METHOD_BIT << M_LOCK) + | (AP_METHOD_BIT << M_UNLOCK) + | (AP_METHOD_BIT << M_MKCOL) + | (AP_METHOD_BIT << M_MOVE) + | (AP_METHOD_BIT << M_PROPFIND) + | (AP_METHOD_BIT << M_PROPPATCH); + + /* + * These are methods that we don't handle directly, but let the + * server's default handler do for us as our agent. + */ + r->allowed |= 0 + | (AP_METHOD_BIT << M_POST); + + /* ### hrm. if we return HTTP_METHOD_NOT_ALLOWED, then an Allow header + * ### is sent; it will need the other allowed states; since the default + * ### handler is not called on error, then it doesn't add the other + * ### allowed states, so we must + */ + + /* ### we might need to refine this for just where we return the error. + * ### also, there is the issue with other methods (see ISSUES) + */ + + /* dispatch the appropriate method handler */ + if (r->method_number == M_GET) { + return dav_method_get(r); + } + + if (r->method_number == M_PUT) { + return dav_method_put(r); + } + + if (r->method_number == M_POST) { + return dav_method_post(r); + } + + if (r->method_number == M_DELETE) { + return dav_method_delete(r); + } + + if (r->method_number == M_OPTIONS) { + return dav_method_options(r); + } + + if (r->method_number == M_PROPFIND) { + return dav_method_propfind(r); + } + + if (r->method_number == M_PROPPATCH) { + return dav_method_proppatch(r); + } + + if (r->method_number == M_MKCOL) { + return dav_method_mkcol(r); + } + + if (r->method_number == M_COPY) { + return dav_method_copymove(r, DAV_DO_COPY); + } + + if (r->method_number == M_MOVE) { + return dav_method_copymove(r, DAV_DO_MOVE); + } + + if (r->method_number == M_LOCK) { + return dav_method_lock(r); + } + + if (r->method_number == M_UNLOCK) { + return dav_method_unlock(r); + } + + if (r->method_number == M_VERSION_CONTROL) { + return dav_method_vsn_control(r); + } + + if (r->method_number == M_CHECKOUT) { + return dav_method_checkout(r); + } + + if (r->method_number == M_UNCHECKOUT) { + return dav_method_uncheckout(r); + } + + if (r->method_number == M_CHECKIN) { + return dav_method_checkin(r); + } + + if (r->method_number == M_UPDATE) { + return dav_method_update(r); + } + + if (r->method_number == M_LABEL) { + return dav_method_label(r); + } + + if (r->method_number == M_REPORT) { + return dav_method_report(r); + } + + if (r->method_number == M_MKWORKSPACE) { + return dav_method_make_workspace(r); + } + + if (r->method_number == M_MKACTIVITY) { + return dav_method_make_activity(r); + } + + if (r->method_number == M_BASELINE_CONTROL) { + return dav_method_baseline_control(r); + } + + if (r->method_number == M_MERGE) { + return dav_method_merge(r); + } + + /* BIND method */ + if (r->method_number == dav_methods[DAV_M_BIND]) { + return dav_method_bind(r); + } + + /* DASL method */ + if (r->method_number == dav_methods[DAV_M_SEARCH]) { + return dav_method_search(r); + } + + /* ### add'l methods for Advanced Collections, ACLs */ + + return DECLINED; +} + +static int dav_fixups(request_rec *r) +{ + dav_dir_conf *conf; + + /* quickly ignore any HTTP/0.9 requests which aren't subreqs. */ + if (r->assbackwards && !r->main) { + return DECLINED; + } + + conf = (dav_dir_conf *)ap_get_module_config(r->per_dir_config, + &dav_module); + + /* if DAV is not enabled, then we've got nothing to do */ + if (conf->provider == NULL) { + return DECLINED; + } + + /* We are going to handle almost every request. In certain cases, + the provider maps to the filesystem (thus, handle_get is + FALSE), and core Apache will handle it. a For that case, we + just return right away. */ + if (r->method_number == M_GET) { + /* + * ### need some work to pull Content-Type and Content-Language + * ### from the property database. + */ + + /* + * If the repository hasn't indicated that it will handle the + * GET method, then just punt. + * + * ### this isn't quite right... taking over the response can break + * ### things like mod_negotiation. need to look into this some more. + */ + if (!conf->provider->repos->handle_get) { + return DECLINED; + } + } + + /* ### this is wrong. We should only be setting the r->handler for the + * requests that mod_dav knows about. If we set the handler for M_POST + * requests, then CGI scripts that use POST will return the source for the + * script. However, mod_dav DOES handle POST, so something else needs + * to be fixed. + */ + if (r->method_number != M_POST) { + + /* We are going to be handling the response for this resource. */ + r->handler = DAV_HANDLER_NAME; + return OK; + } + + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(dav_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(dav_init_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_fixups(dav_fixups, NULL, NULL, APR_HOOK_MIDDLE); + + dav_hook_find_liveprop(dav_core_find_liveprop, NULL, NULL, APR_HOOK_LAST); + dav_hook_insert_all_liveprops(dav_core_insert_all_liveprops, + NULL, NULL, APR_HOOK_MIDDLE); + + dav_core_register_uris(p); +} + +/*--------------------------------------------------------------------------- + * + * Configuration info for the module + */ + +static const command_rec dav_cmds[] = +{ + /* per directory/location */ + AP_INIT_TAKE1("DAV", dav_cmd_dav, NULL, ACCESS_CONF, + "specify the DAV provider for a directory or location"), + + /* per directory/location, or per server */ + AP_INIT_TAKE1("DAVMinTimeout", dav_cmd_davmintimeout, NULL, + ACCESS_CONF|RSRC_CONF, + "specify minimum allowed timeout"), + + /* per directory/location, or per server */ + AP_INIT_FLAG("DAVDepthInfinity", dav_cmd_davdepthinfinity, NULL, + ACCESS_CONF|RSRC_CONF, + "allow Depth infinity PROPFIND requests"), + + { NULL } +}; + +module DAV_DECLARE_DATA dav_module = +{ + STANDARD20_MODULE_STUFF, + dav_create_dir_config, /* dir config creater */ + dav_merge_dir_config, /* dir merger --- default is to override */ + dav_create_server_config, /* server config */ + dav_merge_server_config, /* merge server config */ + dav_cmds, /* command table */ + register_hooks, /* register hooks */ +}; + +APR_HOOK_STRUCT( + APR_HOOK_LINK(gather_propsets) + APR_HOOK_LINK(find_liveprop) + APR_HOOK_LINK(insert_all_liveprops) + ) + +APR_IMPLEMENT_EXTERNAL_HOOK_VOID(dav, DAV, gather_propsets, + (apr_array_header_t *uris), + (uris)) + +APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(dav, DAV, int, find_liveprop, + (const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks), + (resource, ns_uri, name, hooks), 0) + +APR_IMPLEMENT_EXTERNAL_HOOK_VOID(dav, DAV, insert_all_liveprops, + (request_rec *r, const dav_resource *resource, + dav_prop_insert what, apr_text_header *phdr), + (r, resource, what, phdr)) diff --git a/trunk/modules/dav/main/mod_dav.dsp b/trunk/modules/dav/main/mod_dav.dsp new file mode 100644 index 0000000000..003bb47b89 --- /dev/null +++ b/trunk/modules/dav/main/mod_dav.dsp @@ -0,0 +1,164 @@ +# Microsoft Developer Studio Project File - Name="mod_dav" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_dav - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_dav.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_dav.mak" CFG="mod_dav - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_dav - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_dav - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_dav - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DAV_DECLARE_EXPORT" /Fd"Release\mod_dav_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_dav - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../../include" /I "../../../srclib/apr/include" /I "../../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DAV_DECLARE_EXPORT" /Fd"Debug\mod_dav_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dav.so" /base:@..\..\..\os\win32\BaseAddr.ref,mod_dav.so + +!ENDIF + +# Begin Target + +# Name "mod_dav - Win32 Release" +# Name "mod_dav - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\liveprop.c +# End Source File +# Begin Source File + +SOURCE=.\mod_dav.c +# End Source File +# Begin Source File + +SOURCE=.\props.c +# End Source File +# Begin Source File + +SOURCE=.\providers.c +# End Source File +# Begin Source File + +SOURCE=.\std_liveprop.c +# End Source File +# Begin Source File + +SOURCE=.\util.c +# End Source File +# Begin Source File + +SOURCE=.\util_lock.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\mod_dav.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\mod_dav.rc +# End Source File +# Begin Source File + +SOURCE=..\..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_dav - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_dav.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_dav.so "dav_module for Apache" ../../../include/ap_release.h > .\mod_dav.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_dav - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\..\build\win32\win32ver.awk + +".\mod_dav.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../../build/win32/win32ver.awk mod_dav.so "dav_module for Apache" ../../../include/ap_release.h > .\mod_dav.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/dav/main/mod_dav.h b/trunk/modules/dav/main/mod_dav.h new file mode 100644 index 0000000000..bce7c8dc6f --- /dev/null +++ b/trunk/modules/dav/main/mod_dav.h @@ -0,0 +1,2420 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV extension module for Apache 2.0.* +*/ + +#ifndef _MOD_DAV_H_ +#define _MOD_DAV_H_ + +#include "apr_hooks.h" +#include "apr_hash.h" +#include "apr_dbm.h" +#include "apr_tables.h" + +#include "httpd.h" +#include "util_filter.h" +#include "util_xml.h" + +#include /* for INT_MAX */ +#include /* for time_t */ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define DAV_VERSION AP_SERVER_BASEREVISION + +#define DAV_XML_HEADER "" +#define DAV_XML_CONTENT_TYPE "text/xml; charset=\"utf-8\"" + +#define DAV_READ_BLOCKSIZE 2048 /* used for reading input blocks */ + +#define DAV_RESPONSE_BODY_1 "\n\n" +#define DAV_RESPONSE_BODY_2 "\n\n

    " +#define DAV_RESPONSE_BODY_3 "

    \n

    " +#define DAV_RESPONSE_BODY_4 "

    \n" +#define DAV_RESPONSE_BODY_5 "\n" + +#define DAV_DO_COPY 0 +#define DAV_DO_MOVE 1 + + +#if 1 +#define DAV_DEBUG 1 +#define DEBUG_CR "\n" +#define DBG0(f) ap_log_error(APLOG_MARK, \ + APLOG_ERR, 0, NULL, (f)) +#define DBG1(f,a1) ap_log_error(APLOG_MARK, \ + APLOG_ERR, 0, NULL, f, a1) +#define DBG2(f,a1,a2) ap_log_error(APLOG_MARK, \ + APLOG_ERR, 0, NULL, f, a1, a2) +#define DBG3(f,a1,a2,a3) ap_log_error(APLOG_MARK, \ + APLOG_ERR, 0, NULL, f, a1, a2, a3) +#else +#undef DAV_DEBUG +#define DEBUG_CR "" +#endif + +#define DAV_INFINITY INT_MAX /* for the Depth: header */ + +/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and + * DAV_DECLARE_DATA with appropriate export and import tags for the platform + */ +#if !defined(WIN32) +#define DAV_DECLARE(type) type +#define DAV_DECLARE_NONSTD(type) type +#define DAV_DECLARE_DATA +#elif defined(DAV_DECLARE_STATIC) +#define DAV_DECLARE(type) type __stdcall +#define DAV_DECLARE_NONSTD(type) type +#define DAV_DECLARE_DATA +#elif defined(DAV_DECLARE_EXPORT) +#define DAV_DECLARE(type) __declspec(dllexport) type __stdcall +#define DAV_DECLARE_NONSTD(type) __declspec(dllexport) type +#define DAV_DECLARE_DATA __declspec(dllexport) +#else +#define DAV_DECLARE(type) __declspec(dllimport) type __stdcall +#define DAV_DECLARE_NONSTD(type) __declspec(dllimport) type +#define DAV_DECLARE_DATA __declspec(dllimport) +#endif + +/* -------------------------------------------------------------------- +** +** ERROR MANAGEMENT +*/ + +/* +** dav_error structure. +** +** In most cases, mod_dav uses a pointer to a dav_error structure. If the +** pointer is NULL, then no error has occurred. +** +** In certain cases, a dav_error structure is directly used. In these cases, +** a status value of 0 means that an error has not occurred. +** +** Note: this implies that status != 0 whenever an error occurs. +** +** The desc field is optional (it may be NULL). When NULL, it typically +** implies that Apache has a proper description for the specified status. +*/ +typedef struct dav_error { + int status; /* suggested HTTP status (0 for no error) */ + int error_id; /* DAV-specific error ID */ + const char *desc; /* DAV:responsedescription and error log */ + + int save_errno; /* copy of errno causing the error */ + + const char *namespace; /* [optional] namespace of error */ + const char *tagname; /* name of error-tag */ + + struct dav_error *prev; /* previous error (in stack) */ + +} dav_error; + +/* +** Create a new error structure. save_errno will be filled with the current +** errno value. +*/ +DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, + int error_id, const char *desc); + + +/* +** Create a new error structure with tagname and (optional) namespace; +** namespace may be NULL, which means "DAV:". save_errno will be +** filled with the current errno value. +*/ +DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status, + int error_id, const char *desc, + const char *namespace, + const char *tagname); + + +/* +** Push a new error description onto the stack of errors. +** +** This function is used to provide an additional description to an existing +** error. +** +** should contain the caller's view of what the current status is, +** given the underlying error. If it doesn't have a better idea, then the +** caller should pass prev->status. +** +** can specify a new error_id since the topmost description has +** changed. +*/ +DAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status, int error_id, + const char *desc, dav_error *prev); + + +/* error ID values... */ + +/* IF: header errors */ +#define DAV_ERR_IF_PARSE 100 /* general parsing error */ +#define DAV_ERR_IF_MULTIPLE_NOT 101 /* multiple "Not" found */ +#define DAV_ERR_IF_UNK_CHAR 102 /* unknown char in header */ +#define DAV_ERR_IF_ABSENT 103 /* no locktokens given */ +#define DAV_ERR_IF_TAGGED 104 /* in parsing tagged-list */ +#define DAV_ERR_IF_UNCLOSED_PAREN 105 /* in no-tagged-list */ + +/* Prop DB errors */ +#define DAV_ERR_PROP_BAD_MAJOR 200 /* major version was wrong */ +#define DAV_ERR_PROP_READONLY 201 /* prop is read-only */ +#define DAV_ERR_PROP_NO_DATABASE 202 /* writable db not avail */ +#define DAV_ERR_PROP_NOT_FOUND 203 /* prop not found */ +#define DAV_ERR_PROP_BAD_LOCKDB 204 /* could not open lockdb */ +#define DAV_ERR_PROP_OPENING 205 /* problem opening propdb */ +#define DAV_ERR_PROP_EXEC 206 /* problem exec'ing patch */ + +/* Predefined DB errors */ +/* ### any to define?? */ + +/* Predefined locking system errors */ +#define DAV_ERR_LOCK_OPENDB 400 /* could not open lockdb */ +#define DAV_ERR_LOCK_NO_DB 401 /* no database defined */ +#define DAV_ERR_LOCK_CORRUPT_DB 402 /* DB is corrupt */ +#define DAV_ERR_LOCK_UNK_STATE_TOKEN 403 /* unknown State-token */ +#define DAV_ERR_LOCK_PARSE_TOKEN 404 /* bad opaquelocktoken */ +#define DAV_ERR_LOCK_SAVE_LOCK 405 /* err saving locks */ + +/* +** Some comments on Error ID values: +** +** The numbers do not necessarily need to be unique. Uniqueness simply means +** that two errors that have not been predefined above can be distinguished +** from each other. At the moment, mod_dav does not use this distinguishing +** feature, but it could be used in the future to collapse elements +** into groups based on the error ID (and associated responsedescription). +** +** If a compute_desc is provided, then the error ID should be unique within +** the context of the compute_desc function (so the function can figure out +** what to filled into the desc). +** +** Basically, subsystems can ignore defining new error ID values if they want +** to. The subsystems *do* need to return the predefined errors when +** appropriate, so that mod_dav can figure out what to do. Subsystems can +** simply leave the error ID field unfilled (zero) if there isn't an error +** that must be placed there. +*/ + + +/* -------------------------------------------------------------------- +** +** HOOK STRUCTURES +** +** These are here for forward-declaration purposes. For more info, see +** the section title "HOOK HANDLING" for more information, plus each +** structure definition. +*/ + +/* forward-declare this structure */ +typedef struct dav_hooks_propdb dav_hooks_propdb; +typedef struct dav_hooks_locks dav_hooks_locks; +typedef struct dav_hooks_vsn dav_hooks_vsn; +typedef struct dav_hooks_repository dav_hooks_repository; +typedef struct dav_hooks_liveprop dav_hooks_liveprop; +typedef struct dav_hooks_binding dav_hooks_binding; +typedef struct dav_hooks_search dav_hooks_search; + +/* ### deprecated name */ +typedef dav_hooks_propdb dav_hooks_db; + + +/* -------------------------------------------------------------------- +** +** RESOURCE HANDLING +*/ + +/* +** Resource Types: +** The base protocol defines only file and collection resources. +** The versioning protocol defines several additional resource types +** to represent artifacts of a version control system. +** +** This enumeration identifies the type of URL used to identify the +** resource. Since the same resource may have more than one type of +** URL which can identify it, dav_resource_type cannot be used +** alone to determine the type of the resource; attributes of the +** dav_resource object must also be consulted. +*/ +typedef enum { + DAV_RESOURCE_TYPE_UNKNOWN, + + DAV_RESOURCE_TYPE_REGULAR, /* file or collection; could be + * unversioned, or version selector, + * or baseline selector */ + + DAV_RESOURCE_TYPE_VERSION, /* version or baseline URL */ + + DAV_RESOURCE_TYPE_HISTORY, /* version or baseline history URL */ + + DAV_RESOURCE_TYPE_WORKING, /* working resource URL */ + + DAV_RESOURCE_TYPE_WORKSPACE, /* workspace URL */ + + DAV_RESOURCE_TYPE_ACTIVITY, /* activity URL */ + + DAV_RESOURCE_TYPE_PRIVATE /* repository-private type */ + +} dav_resource_type; + +/* +** Opaque, repository-specific information for a resource. +*/ +typedef struct dav_resource_private dav_resource_private; + +/* +** Resource descriptor, generated by a repository provider. +** +** Note: the lock-null state is not explicitly represented here, +** since it may be expensive to compute. Use dav_get_resource_state() +** to determine whether a non-existent resource is a lock-null resource. +** +** A quick explanation of how the flags can apply to different resources: +** +** unversioned file or collection: +** type = DAV_RESOURCE_TYPE_REGULAR +** exists = ? (1 if exists) +** collection = ? (1 if collection) +** versioned = 0 +** baselined = 0 +** working = 0 +** +** version-controlled resource or configuration: +** type = DAV_RESOURCE_TYPE_REGULAR +** exists = 1 +** collection = ? (1 if collection) +** versioned = 1 +** baselined = ? (1 if configuration) +** working = ? (1 if checked out) +** +** version/baseline history: +** type = DAV_RESOURCE_TYPE_HISTORY +** exists = 1 +** collection = 0 +** versioned = 0 +** baselined = 0 +** working = 0 +** +** version/baseline: +** type = DAV_RESOURCE_TYPE_VERSION +** exists = 1 +** collection = ? (1 if collection) +** versioned = 1 +** baselined = ? (1 if baseline) +** working = 0 +** +** working resource: +** type = DAV_RESOURCE_TYPE_WORKING +** exists = 1 +** collection = ? (1 if collection) +** versioned = 1 +** baselined = 0 +** working = 1 +** +** workspace: +** type = DAV_RESOURCE_TYPE_WORKSPACE +** exists = ? (1 if exists) +** collection = 1 +** versioned = ? (1 if version-controlled) +** baselined = ? (1 if baseline-controlled) +** working = ? (1 if checked out) +** +** activity: +** type = DAV_RESOURCE_TYPE_ACTIVITY +** exists = ? (1 if exists) +** collection = 0 +** versioned = 0 +** baselined = 0 +** working = 0 +*/ +typedef struct dav_resource { + dav_resource_type type; + + int exists; /* 0 => null resource */ + + int collection; /* 0 => file; can be 1 for + * REGULAR, VERSION, and WORKING resources, + * and is always 1 for WORKSPACE */ + + int versioned; /* 0 => unversioned; can be 1 for + * REGULAR and WORKSPACE resources, + * and is always 1 for VERSION and WORKING */ + + int baselined; /* 0 => not baselined; can be 1 for + * REGULAR, VERSION, and WORKSPACE resources; + * versioned == 1 when baselined == 1 */ + + int working; /* 0 => not checked out; can be 1 for + * REGULAR and WORKSPACE resources, + * and is always 1 for WORKING */ + + const char *uri; /* the URI for this resource */ + + dav_resource_private *info; /* the provider's private info */ + + const dav_hooks_repository *hooks; /* hooks used for this resource */ + + /* When allocating items related specifically to this resource, the + following pool should be used. Its lifetime will be at least as + long as the dav_resource structure. */ + apr_pool_t *pool; + +} dav_resource; + +/* +** Lock token type. Lock providers define the details of a lock token. +** However, all providers are expected to at least be able to parse +** the "opaquelocktoken" scheme, which is represented by a uuid_t. +*/ +typedef struct dav_locktoken dav_locktoken; + + +/* -------------------------------------------------------------------- +** +** BUFFER HANDLING +** +** These buffers are used as a lightweight buffer reuse mechanism. Apache +** provides sub-pool creation and destruction to much the same effect, but +** the sub-pools are a bit more general and heavyweight than these buffers. +*/ + +/* buffer for reuse; can grow to accomodate needed size */ +typedef struct +{ + apr_size_t alloc_len; /* how much has been allocated */ + apr_size_t cur_len; /* how much is currently being used */ + char *buf; /* buffer contents */ +} dav_buffer; +#define DAV_BUFFER_MINSIZE 256 /* minimum size for buffer */ +#define DAV_BUFFER_PAD 64 /* amount of pad when growing */ + +/* set the cur_len to the given size and ensure space is available */ +DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf, + apr_size_t size); + +/* initialize a buffer and copy the specified (null-term'd) string into it */ +DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf, + const char *str); + +/* check that the buffer can accomodate more bytes */ +DAV_DECLARE(void) dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf, + apr_size_t extra_needed); + +/* append a string to the end of the buffer, adjust length */ +DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, + const char *str); + +/* place a string on the end of the buffer, do NOT adjust length */ +DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf, + const char *str); + +/* place some memory on the end of a buffer; do NOT adjust length */ +DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf, + const void *mem, apr_size_t amt, + apr_size_t pad); + + +/* -------------------------------------------------------------------- +** +** HANDY UTILITIES +*/ + +/* contains results from one of the getprop functions */ +typedef struct +{ + apr_text * propstats; /* element text */ + apr_text * xmlns; /* namespace decls for elem */ +} dav_get_props_result; + +/* holds the contents of a element */ +typedef struct dav_response +{ + const char *href; /* always */ + const char *desc; /* optional description at level */ + + /* use status if propresult.propstats is NULL. */ + dav_get_props_result propresult; + + int status; + + struct dav_response *next; +} dav_response; + +typedef struct +{ + request_rec *rnew; /* new subrequest */ + dav_error err; /* potential error response */ +} dav_lookup_result; + + +DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, request_rec *r, + int must_be_absolute); + +/* defines type of property info a provider is to return */ +typedef enum { + DAV_PROP_INSERT_NOTDEF, /* property is defined by this provider, + but nothing was inserted because the + (live) property is not defined for this + resource (it may be present as a dead + property). */ + DAV_PROP_INSERT_NOTSUPP, /* property is recognized by this provider, + but it is not supported, and cannot be + treated as a dead property */ + DAV_PROP_INSERT_NAME, /* a property name (empty elem) was + inserted into the text block */ + DAV_PROP_INSERT_VALUE, /* a property name/value pair was inserted + into the text block */ + DAV_PROP_INSERT_SUPPORTED /* a supported live property was added to + the text block as a + element */ +} dav_prop_insert; + +/* ### this stuff is private to dav/fs/repos.c; move it... */ +/* format a time string (buf must be at least DAV_TIMEBUF_SIZE chars) */ +#define DAV_STYLE_ISO8601 1 +#define DAV_STYLE_RFC822 2 +#define DAV_TIMEBUF_SIZE 30 + +DAV_DECLARE(int) dav_get_depth(request_rec *r, int def_depth); + +DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, + const char *tagname); +DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, + const char *tagname); + +/* gather up all the CDATA into a single string */ +DAV_DECLARE(const char *) dav_xml_get_cdata(const apr_xml_elem *elem, apr_pool_t *pool, + int strip_white); + +/* +** XML namespace handling +** +** This structure tracks namespace declarations (xmlns:prefix="URI"). +** It maintains a one-to-many relationship of URIs-to-prefixes. In other +** words, one URI may be defined by many prefixes, but any specific +** prefix will specify only one URI. +** +** Prefixes using the "g###" pattern can be generated automatically if +** the caller does not have specific prefix requirements. +*/ +typedef struct { + apr_pool_t *pool; + apr_hash_t *uri_prefix; /* map URIs to an available prefix */ + apr_hash_t *prefix_uri; /* map all prefixes to their URIs */ + int count; /* counter for "g###" prefixes */ +} dav_xmlns_info; + +/* create an empty dav_xmlns_info structure */ +DAV_DECLARE(dav_xmlns_info *) dav_xmlns_create(apr_pool_t *pool); + +/* add a specific prefix/URI pair. the prefix/uri should have a lifetime + at least that of xmlns->pool */ +DAV_DECLARE(void) dav_xmlns_add(dav_xmlns_info *xi, + const char *prefix, const char *uri); + +/* add a URI (if not present); any prefix is acceptable and is returned. + the uri should have a lifetime at least that xmlns->pool */ +DAV_DECLARE(const char *) dav_xmlns_add_uri(dav_xmlns_info *xi, + const char *uri); + +/* return the URI for a specified prefix (or NULL if the prefix is unknown) */ +DAV_DECLARE(const char *) dav_xmlns_get_uri(dav_xmlns_info *xi, + const char *prefix); + +/* return an available prefix for a specified URI (or NULL if the URI + is unknown) */ +DAV_DECLARE(const char *) dav_xmlns_get_prefix(dav_xmlns_info *xi, + const char *uri); + +/* generate xmlns declarations (appending into the given text) */ +DAV_DECLARE(void) dav_xmlns_generate(dav_xmlns_info *xi, + apr_text_header *phdr); + +/* -------------------------------------------------------------------- +** +** DAV PLUGINS +*/ + +/* ### docco ... */ + +/* +** dav_provider +** +** This structure wraps up all of the hooks that a mod_dav provider can +** supply. The provider MUST supply and . The rest are +** optional and should contain NULL if that feature is not supplied. +** +** Note that a provider cannot pick and choose portions from various +** underlying implementations (which was theoretically possible in +** mod_dav 1.0). There are too many dependencies between a dav_resource +** (defined by ) and the other functionality. +** +** Live properties are not part of the dav_provider structure because they +** are handled through the APR_HOOK interface (to allow for multiple liveprop +** providers). The core always provides some properties, and then a given +** provider will add more properties. +** +** Some providers may need to associate a context with the dav_provider +** structure -- the ctx field is available for storing this context. Just +** leave it NULL if it isn't required. +*/ +typedef struct { + const dav_hooks_repository *repos; + const dav_hooks_propdb *propdb; + const dav_hooks_locks *locks; + const dav_hooks_vsn *vsn; + const dav_hooks_binding *binding; + const dav_hooks_search *search; + + void *ctx; +} dav_provider; + +/* +** gather_propsets: gather all live property propset-URIs +** +** The hook implementor should push one or more URIs into the specified +** array. These URIs are returned in the DAV: header to let clients know +** what sets of live properties are supported by the installation. mod_dav +** will place open/close angle brackets around each value (much like +** a Coded-URL); quotes and brackets should not be in the value. +** +** Example: http://apache.org/dav/props/ +** +** (of course, use your own domain to ensure a unique value) +*/ +APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_propsets, + (apr_array_header_t *uris)) + +/* +** find_liveprop: find a live property, returning a non-zero, unique, +** opaque identifier. +** +** If the hook implementor determines the specified URI/name refers to +** one of its properties, then it should fill in HOOKS and return a +** non-zero value. The returned value is the "property ID" and will +** be passed to the various liveprop hook functions. +** +** Return 0 if the property is not defined by the hook implementor. +*/ +APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, find_liveprop, + (const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks)) + +/* +** insert_all_liveprops: insert all (known) live property names/values. +** +** The hook implementor should append XML text to PHDR, containing liveprop +** names. If INSVALUE is true, then the property values should also be +** inserted into the output XML stream. +** +** The liveprop provider should insert *all* known and *defined* live +** properties on the specified resource. If a particular liveprop is +** not defined for this resource, then it should not be inserted. +*/ +APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops, + (request_rec *r, const dav_resource *resource, + dav_prop_insert what, apr_text_header *phdr)) + +DAV_DECLARE(const dav_hooks_locks *) dav_get_lock_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_propdb *) dav_get_propdb_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_vsn *) dav_get_vsn_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_binding *) dav_get_binding_hooks(request_rec *r); +DAV_DECLARE(const dav_hooks_search *) dav_get_search_hooks(request_rec *r); + +DAV_DECLARE(void) dav_register_provider(apr_pool_t *p, const char *name, + const dav_provider *hooks); +DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name); + + +/* ### deprecated */ +#define DAV_GET_HOOKS_PROPDB(r) dav_get_propdb_hooks(r) +#define DAV_GET_HOOKS_LOCKS(r) dav_get_lock_hooks(r) +#define DAV_GET_HOOKS_VSN(r) dav_get_vsn_hooks(r) +#define DAV_GET_HOOKS_BINDING(r) dav_get_binding_hooks(r) +#define DAV_GET_HOOKS_SEARCH(r) dav_get_search_hooks(r) + + +/* -------------------------------------------------------------------- +** +** IF HEADER PROCESSING +** +** Here is the definition of the If: header from RFC 2518, S9.4: +** +** If = "If" ":" (1*No-tag-list | 1*Tagged-list) +** No-tag-list = List +** Tagged-list = Resource 1*List +** Resource = Coded-URL +** List = "(" 1*(["Not"](State-token | "[" entity-tag "]")) ")" +** State-token = Coded-URL +** Coded-URL = "<" absoluteURI ">" ; absoluteURI from RFC 2616 +** +** List corresponds to dav_if_state_list. No-tag-list corresponds to +** dav_if_header with uri==NULL. Tagged-list corresponds to a sequence of +** dav_if_header structures with (duplicate) uri==Resource -- one +** dav_if_header per state_list. A second Tagged-list will start a new +** sequence of dav_if_header structures with the new URI. +** +** A summary of the semantics, mapped into our structures: +** - Chained dav_if_headers: OR +** - Chained dav_if_state_lists: AND +** - NULL uri matches all resources +*/ + +typedef enum +{ + dav_if_etag, + dav_if_opaquelock +} dav_if_state_type; + +typedef struct dav_if_state_list +{ + dav_if_state_type type; + + int condition; +#define DAV_IF_COND_NORMAL 0 +#define DAV_IF_COND_NOT 1 /* "Not" was applied */ + + const char *etag; + dav_locktoken *locktoken; + + struct dav_if_state_list *next; +} dav_if_state_list; + +typedef struct dav_if_header +{ + const char *uri; + apr_size_t uri_len; + struct dav_if_state_list *state; + struct dav_if_header *next; + + int dummy_header; /* used internally by the lock/etag validation */ +} dav_if_header; + +typedef struct dav_locktoken_list +{ + dav_locktoken *locktoken; + struct dav_locktoken_list *next; +} dav_locktoken_list; + +DAV_DECLARE(dav_error *) dav_get_locktoken_list(request_rec *r, + dav_locktoken_list **ltl); + + +/* -------------------------------------------------------------------- +** +** LIVE PROPERTY HANDLING +*/ + +/* opaque type for PROPPATCH rollback information */ +typedef struct dav_liveprop_rollback dav_liveprop_rollback; + +struct dav_hooks_liveprop +{ + /* + ** Insert property information into a text block. The property to + ** insert is identified by the propid value. The information to insert + ** is identified by the "what" argument, as follows: + ** DAV_PROP_INSERT_NAME + ** property name, as an empty XML element + ** DAV_PROP_INSERT_VALUE + ** property name/value, as an XML element + ** DAV_PROP_INSERT_SUPPORTED + ** if the property is defined on the resource, then + ** a DAV:supported-live-property element, as defined + ** by the DeltaV extensions to RFC2518. + ** + ** Providers should return DAV_PROP_INSERT_NOTDEF if the property is + ** known and not defined for this resource, so should be handled as a + ** dead property. If a provider recognizes, but does not support, a + ** property, and does not want it handled as a dead property, it should + ** return DAV_PROP_INSERT_NOTSUPP. + ** + ** Returns one of DAV_PROP_INSERT_* based on what happened. + ** + ** ### we may need more context... ie. the lock database + */ + dav_prop_insert (*insert_prop)(const dav_resource *resource, + int propid, dav_prop_insert what, + apr_text_header *phdr); + + /* + ** Determine whether a given property is writable. + ** + ** ### we may want a different semantic. i.e. maybe it should be + ** ### "can we write into this property?" + ** + ** Returns 1 if the live property can be written, 0 if read-only. + */ + int (*is_writable)(const dav_resource *resource, int propid); + + /* + ** This member defines the set of namespace URIs that the provider + ** uses for its properties. When insert_all is called, it will be + ** passed a list of integers that map from indices into this list + ** to namespace IDs for output generation. + ** + ** The last entry in this list should be a NULL value (sentinel). + */ + const char * const * namespace_uris; + + /* + ** ### this is not the final design. we want an open-ended way for + ** ### liveprop providers to attach *new* properties. To this end, + ** ### we'll have a "give me a list of the props you define", a way + ** ### to check for a prop's existence, a way to validate a set/remove + ** ### of a prop, and a way to execute/commit/rollback that change. + */ + + /* + ** Validate that the live property can be assigned a value, and that + ** the provided value is valid. + ** + ** elem will point to the XML element that names the property. For + ** example: + ** T + ** + ** The provider can access the cdata fields and the child elements + ** to extract the relevant pieces. + ** + ** operation is one of DAV_PROP_OP_SET or _DELETE. + ** + ** The provider may return a value in *context which will be passed + ** to each of the exec/commit/rollback functions. For example, this + ** may contain an internal value which has been processed from the + ** input element. + ** + ** The provider must set defer_to_dead to true (non-zero) or false. + ** If true, then the set/remove is deferred to the dead property + ** database. Note: it will be set to zero on entry. + */ + dav_error * (*patch_validate)(const dav_resource *resource, + const apr_xml_elem *elem, + int operation, + void **context, + int *defer_to_dead); + + /* ### doc... */ + dav_error * (*patch_exec)(const dav_resource *resource, + const apr_xml_elem *elem, + int operation, + void *context, + dav_liveprop_rollback **rollback_ctx); + + /* ### doc... */ + void (*patch_commit)(const dav_resource *resource, + int operation, + void *context, + dav_liveprop_rollback *rollback_ctx); + + /* ### doc... */ + dav_error * (*patch_rollback)(const dav_resource *resource, + int operation, + void *context, + dav_liveprop_rollback *rollback_ctx); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; +}; + +/* +** dav_liveprop_spec: specify a live property +** +** This structure is used as a standard way to determine if a particular +** property is a live property. Its use is not part of the mandated liveprop +** interface, but can be used by liveprop providers in conjuction with the +** utility routines below. +** +** spec->name == NULL is the defined end-sentinel for a list of specs. +*/ +typedef struct { + int ns; /* provider-local namespace index */ + const char *name; /* name of the property */ + + int propid; /* provider-local property ID */ + + int is_writable; /* is the property writable? */ + +} dav_liveprop_spec; + +/* +** dav_liveprop_group: specify a group of liveprops +** +** This structure specifies a group of live properties, their namespaces, +** and how to handle them. +*/ +typedef struct { + const dav_liveprop_spec *specs; + const char * const *namespace_uris; + const dav_hooks_liveprop *hooks; + +} dav_liveprop_group; + +/* ### docco */ +DAV_DECLARE(int) dav_do_find_liveprop(const char *ns_uri, const char *name, + const dav_liveprop_group *group, + const dav_hooks_liveprop **hooks); + +/* ### docco */ +DAV_DECLARE(int) dav_get_liveprop_info(int propid, + const dav_liveprop_group *group, + const dav_liveprop_spec **info); + +/* ### docco */ +DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *pool, + const dav_liveprop_group *group); + +/* ### docco */ +DAV_DECLARE(int) dav_get_liveprop_ns_index(const char *uri); + +/* ### docco */ +DAV_DECLARE(int) dav_get_liveprop_ns_count(void); + +/* ### docco */ +DAV_DECLARE(void) dav_add_all_liveprop_xmlns(apr_pool_t *p, + apr_text_header *phdr); + +/* +** The following three functions are part of mod_dav's internal handling +** for the core WebDAV properties. They are not part of mod_dav's API. +*/ +DAV_DECLARE_NONSTD(int) dav_core_find_liveprop( + const dav_resource *resource, + const char *ns_uri, + const char *name, + const dav_hooks_liveprop **hooks); +DAV_DECLARE_NONSTD(void) dav_core_insert_all_liveprops( + request_rec *r, + const dav_resource *resource, + dav_prop_insert what, + apr_text_header *phdr); +DAV_DECLARE_NONSTD(void) dav_core_register_uris(apr_pool_t *p); + + +/* +** Standard WebDAV Property Identifiers +** +** A live property provider does not need to use these; they are simply +** provided for convenience. +** +** Property identifiers need to be unique within a given provider, but not +** *across* providers (note: this uniqueness constraint was different in +** older versions of mod_dav). +** +** The identifiers start at 20000 to make it easier for providers to avoid +** conflicts with the standard properties. The properties are arranged +** alphabetically, and may be reordered from time to time (as properties +** are introduced). +** +** NOTE: there is no problem with reordering (e.g. binary compat) since the +** identifiers are only used within a given provider, which would pick up +** the entire set of changes upon a recompile. +*/ +enum { + DAV_PROPID_BEGIN = 20000, + + /* Standard WebDAV properties (RFC 2518) */ + DAV_PROPID_creationdate, + DAV_PROPID_displayname, + DAV_PROPID_getcontentlanguage, + DAV_PROPID_getcontentlength, + DAV_PROPID_getcontenttype, + DAV_PROPID_getetag, + DAV_PROPID_getlastmodified, + DAV_PROPID_lockdiscovery, + DAV_PROPID_resourcetype, + DAV_PROPID_source, + DAV_PROPID_supportedlock, + + /* DeltaV properties (from the I-D (#14)) */ + DAV_PROPID_activity_checkout_set, + DAV_PROPID_activity_set, + DAV_PROPID_activity_version_set, + DAV_PROPID_auto_merge_set, + DAV_PROPID_auto_version, + DAV_PROPID_baseline_collection, + DAV_PROPID_baseline_controlled_collection, + DAV_PROPID_baseline_controlled_collection_set, + DAV_PROPID_checked_in, + DAV_PROPID_checked_out, + DAV_PROPID_checkin_fork, + DAV_PROPID_checkout_fork, + DAV_PROPID_checkout_set, + DAV_PROPID_comment, + DAV_PROPID_creator_displayname, + DAV_PROPID_current_activity_set, + DAV_PROPID_current_workspace_set, + DAV_PROPID_default_variant, + DAV_PROPID_eclipsed_set, + DAV_PROPID_label_name_set, + DAV_PROPID_merge_set, + DAV_PROPID_precursor_set, + DAV_PROPID_predecessor_set, + DAV_PROPID_root_version, + DAV_PROPID_subactivity_set, + DAV_PROPID_subbaseline_set, + DAV_PROPID_successor_set, + DAV_PROPID_supported_method_set, + DAV_PROPID_supported_live_property_set, + DAV_PROPID_supported_report_set, + DAV_PROPID_unreserved, + DAV_PROPID_variant_set, + DAV_PROPID_version_controlled_binding_set, + DAV_PROPID_version_controlled_configuration, + DAV_PROPID_version_history, + DAV_PROPID_version_name, + DAV_PROPID_workspace, + DAV_PROPID_workspace_checkout_set, + + DAV_PROPID_END +}; + +/* +** Property Identifier Registration +** +** At the moment, mod_dav requires live property providers to ensure that +** each property returned has a unique value. For now, this is done through +** central registration (there are no known providers other than the default, +** so this remains manageable). +** +** WARNING: the TEST ranges should never be "shipped". +*/ +#define DAV_PROPID_CORE 10000 /* ..10099. defined by mod_dav */ +#define DAV_PROPID_FS 10100 /* ..10299. + mod_dav filesystem provider. */ +#define DAV_PROPID_TEST1 10300 /* ..10399 */ +#define DAV_PROPID_TEST2 10400 /* ..10499 */ +#define DAV_PROPID_TEST3 10500 /* ..10599 */ +/* Next: 10600 */ + + +/* -------------------------------------------------------------------- +** +** DATABASE FUNCTIONS +*/ + +typedef struct dav_db dav_db; +typedef struct dav_namespace_map dav_namespace_map; +typedef struct dav_deadprop_rollback dav_deadprop_rollback; + +typedef struct { + const char *ns; /* "" signals "no namespace" */ + const char *name; +} dav_prop_name; + +/* hook functions to enable pluggable databases */ +struct dav_hooks_propdb +{ + dav_error * (*open)(apr_pool_t *p, const dav_resource *resource, int ro, + dav_db **pdb); + void (*close)(dav_db *db); + + /* + ** In bulk, define any namespaces that the values and their name + ** elements may need. + ** + ** Note: sometimes mod_dav will defer calling this until output_value + ** returns found==1. If the output process needs the dav_xmlns_info + ** filled for its work, then it will need to fill it on demand rather + ** than depending upon this hook to fill in the structure. + ** + ** Note: this will *always* be called during an output sequence. Thus, + ** the provider may rely solely on using this to fill the xmlns info. + */ + dav_error * (*define_namespaces)(dav_db *db, dav_xmlns_info *xi); + + /* + ** Output the value from the database (i.e. add an element name and + ** the value into *phdr). Set *found based on whether the name/value + ** was found in the propdb. + ** + ** Note: it is NOT an error for the key/value pair to not exist. + ** + ** The dav_xmlns_info passed to define_namespaces() is also passed to + ** each output_value() call so that namespaces can be added on-demand. + ** It can also be used to look up prefixes or URIs during the output + ** process. + */ + dav_error * (*output_value)(dav_db *db, const dav_prop_name *name, + dav_xmlns_info *xi, + apr_text_header *phdr, int *found); + + /* + ** Build a mapping from "global" namespaces (stored in apr_xml_*) + ** into provider-local namespace identifiers. + ** + ** This mapping should be done once per set of namespaces, and the + ** resulting mapping should be passed into the store() hook function. + ** + ** Note: usually, there is just a single document/namespaces for all + ** elements passed. However, the generality of creating multiple + ** mappings and passing them to store() is provided here. + ** + ** Note: this is only in preparation for a series of store() calls. + ** As a result, the propdb must be open for read/write access when + ** this function is called. + */ + dav_error * (*map_namespaces)(dav_db *db, + const apr_array_header_t *namespaces, + dav_namespace_map **mapping); + + /* + ** Store a property value for a given name. The value->combined field + ** MUST be set for this call. + ** + ** ### WARNING: current providers will quote the text within ELEM. + ** ### this implies you can call this function only once with a given + ** ### element structure (a second time will quote it again). + */ + dav_error * (*store)(dav_db *db, const dav_prop_name *name, + const apr_xml_elem *elem, + dav_namespace_map *mapping); + + /* remove a given property */ + dav_error * (*remove)(dav_db *db, const dav_prop_name *name); + + /* returns 1 if the record specified by "key" exists; 0 otherwise */ + int (*exists)(dav_db *db, const dav_prop_name *name); + + /* + ** Iterate over the property names in the database. + ** + ** iter->name.ns == iter->name.name == NULL when there are no more names. + ** + ** Note: only one iteration may occur over the propdb at a time. + */ + dav_error * (*first_name)(dav_db *db, dav_prop_name *pname); + dav_error * (*next_name)(dav_db *db, dav_prop_name *pname); + + /* + ** Rollback support: get rollback context, and apply it. + ** + ** struct dav_deadprop_rollback is a provider-private structure; it + ** should remember the name, and the name's old value (or the fact that + ** the value was not present, and should be deleted if a rollback occurs). + */ + dav_error * (*get_rollback)(dav_db *db, const dav_prop_name *name, + dav_deadprop_rollback **prollback); + dav_error * (*apply_rollback)(dav_db *db, + dav_deadprop_rollback *rollback); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; +}; + + +/* -------------------------------------------------------------------- +** +** LOCK FUNCTIONS +*/ + +/* Used to represent a Timeout header of "Infinity" */ +#define DAV_TIMEOUT_INFINITE 0 + +DAV_DECLARE(time_t) dav_get_timeout(request_rec *r); + +/* +** Opaque, provider-specific information for a lock database. +*/ +typedef struct dav_lockdb_private dav_lockdb_private; + +/* +** Opaque, provider-specific information for a lock record. +*/ +typedef struct dav_lock_private dav_lock_private; + +/* +** Lock database type. Lock providers are urged to implement a "lazy" open, so +** doing an "open" is cheap until something is actually needed from the DB. +*/ +typedef struct +{ + const dav_hooks_locks *hooks; /* the hooks used for this lockdb */ + int ro; /* was it opened readonly? */ + + dav_lockdb_private *info; + +} dav_lockdb; + +typedef enum { + DAV_LOCKSCOPE_UNKNOWN, + DAV_LOCKSCOPE_EXCLUSIVE, + DAV_LOCKSCOPE_SHARED +} dav_lock_scope; + +typedef enum { + DAV_LOCKTYPE_UNKNOWN, + DAV_LOCKTYPE_WRITE +} dav_lock_type; + +typedef enum { + DAV_LOCKREC_DIRECT, /* lock asserted on this resource */ + DAV_LOCKREC_INDIRECT, /* lock inherited from a parent */ + DAV_LOCKREC_INDIRECT_PARTIAL /* most info is not filled in */ +} dav_lock_rectype; + +/* +** dav_lock: hold information about a lock on a resource. +** +** This structure is used for both direct and indirect locks. A direct lock +** is a lock applied to a specific resource by the client. An indirect lock +** is one that is inherited from a parent resource by virtue of a non-zero +** Depth: header when the lock was applied. +** +** mod_dav records both types of locks in the lock database, managing their +** addition/removal as resources are moved about the namespace. +** +** Note that the lockdb is free to marshal this structure in any form that +** it likes. +** +** For a "partial" lock, the and fields must be filled +** in. All other (user) fields should be zeroed. The lock provider will +** usually fill in the field, and the field may be used to +** construct a list of partial locks. +** +** The lock provider MUST use the info field to store a value such that a +** dav_lock structure can locate itself in the underlying lock database. +** This requirement is needed for refreshing: when an indirect dav_lock is +** refreshed, its reference to the direct lock does not specify the direct's +** resource, so the only way to locate the (refreshed, direct) lock in the +** database is to use the info field. +** +** Note that only refers to the resource where this lock was +** found. +** ### hrm. that says the abstraction is wrong. is_locknull may disappear. +*/ +typedef struct dav_lock +{ + dav_lock_rectype rectype; /* type of lock record */ + int is_locknull; /* lock establishes a locknull resource */ + + /* ### put the resource in here? */ + + dav_lock_scope scope; /* scope of the lock */ + dav_lock_type type; /* type of lock */ + int depth; /* depth of the lock */ + time_t timeout; /* when the lock will timeout */ + + const dav_locktoken *locktoken; /* the token that was issued */ + + const char *owner; /* (XML) owner of the lock */ + const char *auth_user; /* auth'd username owning lock */ + + dav_lock_private *info; /* private to the lockdb */ + + struct dav_lock *next; /* for managing a list of locks */ +} dav_lock; + +/* Property-related public lock functions */ +DAV_DECLARE(const char *)dav_lock_get_activelock(request_rec *r, + dav_lock *locks, + dav_buffer *pbuf); + +/* LockDB-related public lock functions */ +DAV_DECLARE(dav_error *) dav_lock_parse_lockinfo(request_rec *r, + const dav_resource *resrouce, + dav_lockdb *lockdb, + const apr_xml_doc *doc, + dav_lock **lock_request); +DAV_DECLARE(int) dav_unlock(request_rec *r, + const dav_resource *resource, + const dav_locktoken *locktoken); +DAV_DECLARE(dav_error *) dav_add_lock(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, dav_lock *request, + dav_response **response); +DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r, + dav_lockdb *lockdb, + const dav_resource *resource, + int resource_state, + int depth); + +DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, + const dav_resource *resource, + dav_lock **locks); + +DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, + dav_resource *resource, + int depth, + dav_locktoken *locktoken, + dav_response **response, + int flags, + dav_lockdb *lockdb); +/* +** flags: +** 0x0F -- reserved for values +** +** other flags, detailed below +*/ +#define DAV_VALIDATE_RESOURCE 0x0010 /* validate just the resource */ +#define DAV_VALIDATE_PARENT 0x0020 /* validate resource AND its parent */ +#define DAV_VALIDATE_ADD_LD 0x0040 /* add DAV:lockdiscovery into + the 424 DAV:response */ +#define DAV_VALIDATE_USE_424 0x0080 /* return 424 status, not 207 */ +#define DAV_VALIDATE_IS_PARENT 0x0100 /* for internal use */ + +/* Lock-null related public lock functions */ +DAV_DECLARE(int) dav_get_resource_state(request_rec *r, + const dav_resource *resource); + +/* Lock provider hooks. Locking is optional, so there may be no + * lock provider for a given repository. + */ +struct dav_hooks_locks +{ + /* Return the supportedlock property for a resource */ + const char * (*get_supportedlock)( + const dav_resource *resource + ); + + /* Parse a lock token URI, returning a lock token object allocated + * in the given pool. + */ + dav_error * (*parse_locktoken)( + apr_pool_t *p, + const char *char_token, + dav_locktoken **locktoken_p + ); + + /* Format a lock token object into a URI string, allocated in + * the given pool. + * + * Always returns non-NULL. + */ + const char * (*format_locktoken)( + apr_pool_t *p, + const dav_locktoken *locktoken + ); + + /* Compare two lock tokens. + * + * Result < 0 => lt1 < lt2 + * Result == 0 => lt1 == lt2 + * Result > 0 => lt1 > lt2 + */ + int (*compare_locktoken)( + const dav_locktoken *lt1, + const dav_locktoken *lt2 + ); + + /* Open the provider's lock database. + * + * The provider may or may not use a "real" database for locks + * (a lock could be an attribute on a resource, for example). + * + * The provider may choose to use the value of the DAVLockDB directive + * (as returned by dav_get_lockdb_path()) to decide where to place + * any storage it may need. + * + * The request storage pool should be associated with the lockdb, + * so it can be used in subsequent operations. + * + * If ro != 0, only readonly operations will be performed. + * If force == 0, the open can be "lazy"; no subsequent locking operations + * may occur. + * If force != 0, locking operations will definitely occur. + */ + dav_error * (*open_lockdb)( + request_rec *r, + int ro, + int force, + dav_lockdb **lockdb + ); + + /* Indicates completion of locking operations */ + void (*close_lockdb)( + dav_lockdb *lockdb + ); + + /* Take a resource out of the lock-null state. */ + dav_error * (*remove_locknull_state)( + dav_lockdb *lockdb, + const dav_resource *resource + ); + + /* + ** Create a (direct) lock structure for the given resource. A locktoken + ** will be created. + ** + ** The lock provider may store private information into lock->info. + */ + dav_error * (*create_lock)(dav_lockdb *lockdb, + const dav_resource *resource, + dav_lock **lock); + + /* + ** Get the locks associated with the specified resource. + ** + ** If resolve_locks is true (non-zero), then any indirect locks are + ** resolved to their actual, direct lock (i.e. the reference to followed + ** to the original lock). + ** + ** The locks, if any, are returned as a linked list in no particular + ** order. If no locks are present, then *locks will be NULL. + */ + dav_error * (*get_locks)(dav_lockdb *lockdb, + const dav_resource *resource, + int calltype, + dav_lock **locks); + +#define DAV_GETLOCKS_RESOLVED 0 /* resolve indirects to directs */ +#define DAV_GETLOCKS_PARTIAL 1 /* leave indirects partially filled */ +#define DAV_GETLOCKS_COMPLETE 2 /* fill out indirect locks */ + + /* + ** Find a particular lock on a resource (specified by its locktoken). + ** + ** *lock will be set to NULL if the lock is not found. + ** + ** Note that the provider can optimize the unmarshalling -- only one + ** lock (or none) must be constructed and returned. + ** + ** If partial_ok is true (non-zero), then an indirect lock can be + ** partially filled in. Otherwise, another lookup is done and the + ** lock structure will be filled out as a DAV_LOCKREC_INDIRECT. + */ + dav_error * (*find_lock)(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken, + int partial_ok, + dav_lock **lock); + + /* + ** Quick test to see if the resource has *any* locks on it. + ** + ** This is typically used to determine if a non-existent resource + ** has a lock and is (therefore) a locknull resource. + ** + ** WARNING: this function may return TRUE even when timed-out locks + ** exist (i.e. it may not perform timeout checks). + */ + dav_error * (*has_locks)(dav_lockdb *lockdb, + const dav_resource *resource, + int *locks_present); + + /* + ** Append the specified lock(s) to the set of locks on this resource. + ** + ** If "make_indirect" is true (non-zero), then the specified lock(s) + ** should be converted to an indirect lock (if it is a direct lock) + ** before appending. Note that the conversion to an indirect lock does + ** not alter the passed-in lock -- the change is internal the + ** append_locks function. + ** + ** Multiple locks are specified using the lock->next links. + */ + dav_error * (*append_locks)(dav_lockdb *lockdb, + const dav_resource *resource, + int make_indirect, + const dav_lock *lock); + + /* + ** Remove any lock that has the specified locktoken. + ** + ** If locktoken == NULL, then ALL locks are removed. + */ + dav_error * (*remove_lock)(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken *locktoken); + + /* + ** Refresh all locks, found on the specified resource, which has a + ** locktoken in the provided list. + ** + ** If the lock is indirect, then the direct lock is referenced and + ** refreshed. + ** + ** Each lock that is updated is returned in the argument. + ** Note that the locks will be fully resolved. + */ + dav_error * (*refresh_locks)(dav_lockdb *lockdb, + const dav_resource *resource, + const dav_locktoken_list *ltl, + time_t new_time, + dav_lock **locks); + + /* + ** Look up the resource associated with a particular locktoken. + ** + ** The search begins at the specified and the lock + ** specified by . + ** + ** If the resource/token specifies an indirect lock, then the direct + ** lock will be looked up, and THAT resource will be returned. In other + ** words, this function always returns the resource where a particular + ** lock (token) was asserted. + ** + ** NOTE: this function pointer is allowed to be NULL, indicating that + ** the provider does not support this type of functionality. The + ** caller should then traverse up the repository hierarchy looking + ** for the resource defining a lock with this locktoken. + */ + dav_error * (*lookup_resource)(dav_lockdb *lockdb, + const dav_locktoken *locktoken, + const dav_resource *start_resource, + const dav_resource **resource); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; +}; + +/* what types of resources can be discovered by dav_get_resource_state() */ +#define DAV_RESOURCE_LOCK_NULL 10 /* resource lock-null */ +#define DAV_RESOURCE_NULL 11 /* resource null */ +#define DAV_RESOURCE_EXISTS 12 /* resource exists */ +#define DAV_RESOURCE_ERROR 13 /* an error occurred */ + + +/* -------------------------------------------------------------------- +** +** PROPERTY HANDLING +*/ + +typedef struct dav_propdb dav_propdb; + + +DAV_DECLARE(dav_error *) dav_open_propdb( + request_rec *r, + dav_lockdb *lockdb, + const dav_resource *resource, + int ro, + apr_array_header_t *ns_xlate, + dav_propdb **propdb); + +DAV_DECLARE(void) dav_close_propdb(dav_propdb *db); + +DAV_DECLARE(dav_get_props_result) dav_get_props( + dav_propdb *db, + apr_xml_doc *doc); + +DAV_DECLARE(dav_get_props_result) dav_get_allprops( + dav_propdb *db, + dav_prop_insert what); + +DAV_DECLARE(void) dav_get_liveprop_supported( + dav_propdb *propdb, + const char *ns_uri, + const char *propname, + apr_text_header *body); + +/* +** 3-phase property modification. +** +** 1) validate props. readable? unlocked? ACLs allow access? +** 2) execute operation (set/delete) +** 3) commit or rollback +** +** ### eventually, auth must be available. a ref to the request_rec (which +** ### contains the auth info) should be in the shared context struct. +** +** Each function may alter the error values and information contained within +** the context record. This should be done as an "increasing" level of +** error, rather than overwriting any previous error. +** +** Note that commit() cannot generate errors. It should simply free the +** rollback information. +** +** rollback() may generate additional errors because the rollback operation +** can sometimes fail(!). +** +** The caller should allocate an array of these, one per operation. It should +** be zero-initialized, then the db, operation, and prop fields should be +** filled in before calling dav_prop_validate. Note that the set/delete +** operations are order-dependent. For a given (logical) context, the same +** pointer must be passed to each phase. +** +** error_type is an internal value, but will have the same numeric value +** for each possible "desc" value. This allows the caller to group the +** descriptions via the error_type variable, rather than through string +** comparisons. Note that "status" does not provide enough granularity to +** differentiate/group the "desc" values. +** +** Note that the propdb will maintain some (global) context across all +** of the property change contexts. This implies that you can have only +** one open transaction per propdb. +*/ +typedef struct dav_prop_ctx +{ + dav_propdb *propdb; + + int operation; +#define DAV_PROP_OP_SET 1 /* set a property value */ +#define DAV_PROP_OP_DELETE 2 /* delete a prop value */ +/* ### add a GET? */ + + apr_xml_elem *prop; /* property to affect */ + + dav_error *err; /* error (if any) */ + + /* private items to the propdb */ + int is_liveprop; + void *liveprop_ctx; + struct dav_rollback_item *rollback; /* optional rollback info */ + + /* private to mod_dav.c */ + request_rec *r; + +} dav_prop_ctx; + +DAV_DECLARE_NONSTD(void) dav_prop_validate(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_exec(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_commit(dav_prop_ctx *ctx); +DAV_DECLARE_NONSTD(void) dav_prop_rollback(dav_prop_ctx *ctx); + +#define DAV_PROP_CTX_HAS_ERR(dpc) ((dpc).err && (dpc).err->status >= 300) + + +/* -------------------------------------------------------------------- +** +** WALKER STRUCTURE +*/ + +enum { + DAV_CALLTYPE_MEMBER = 1, /* called for a member resource */ + DAV_CALLTYPE_COLLECTION, /* called for a collection */ + DAV_CALLTYPE_LOCKNULL /* called for a locknull resource */ +}; + +typedef struct +{ + /* the client-provided context */ + void *walk_ctx; + + /* pool to use for allocations in the callback */ + apr_pool_t *pool; + + /* the current resource */ + const dav_resource *resource; + + /* OUTPUT: add responses to this */ + dav_response *response; + +} dav_walk_resource; + +typedef struct +{ + int walk_type; +#define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */ +#define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */ +#define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */ + + /* callback function and a client context for the walk */ + dav_error * (*func)(dav_walk_resource *wres, int calltype); + void *walk_ctx; + + /* what pool to use for allocations needed by walk logic */ + apr_pool_t *pool; + + /* beginning root of the walk */ + const dav_resource *root; + + /* lock database to enable walking LOCKNULL resources */ + dav_lockdb *lockdb; + +} dav_walk_params; + +/* directory tree walking context */ +typedef struct dav_walker_ctx +{ + /* input: */ + dav_walk_params w; + + + /* ### client data... phasing out this big glom */ + + /* this brigade buffers data being sent to r->output_filters */ + apr_bucket_brigade *bb; + + /* a scratch pool, used to stream responses and iteratively cleared. */ + apr_pool_t *scratchpool; + + request_rec *r; /* original request */ + + /* for PROPFIND operations */ + apr_xml_doc *doc; + int propfind_type; +#define DAV_PROPFIND_IS_ALLPROP 1 +#define DAV_PROPFIND_IS_PROPNAME 2 +#define DAV_PROPFIND_IS_PROP 3 + + apr_text *propstat_404; /* (cached) propstat giving a 404 error */ + + const dav_if_header *if_header; /* for validation */ + const dav_locktoken *locktoken; /* for UNLOCK */ + const dav_lock *lock; /* for LOCK */ + int skip_root; /* for dav_inherit_locks() */ + + int flags; + + dav_buffer work_buf; /* for dav_validate_request() */ + +} dav_walker_ctx; + +DAV_DECLARE(void) dav_add_response(dav_walk_resource *wres, + int status, + dav_get_props_result *propstats); + + +/* -------------------------------------------------------------------- +** +** "STREAM" STRUCTURE +** +** mod_dav uses this abstraction for interacting with the repository +** while fetching/storing resources. mod_dav views resources as a stream +** of bytes. +** +** Note that the structure is opaque -- it is private to the repository +** that created the stream in the repository's "open" function. +** +** ### THIS STUFF IS GOING AWAY ... GET/read requests are handled by +** ### having the provider jam stuff straight into the filter stack. +** ### this is only left for handling PUT/write requests. +*/ + +typedef struct dav_stream dav_stream; + +typedef enum { + DAV_MODE_WRITE_TRUNC, /* truncate and open for writing */ + DAV_MODE_WRITE_SEEKABLE /* open for writing; random access */ +} dav_stream_mode; + + +/* -------------------------------------------------------------------- +** +** REPOSITORY FUNCTIONS +*/ + +/* Repository provider hooks */ +struct dav_hooks_repository +{ + /* Flag for whether repository requires special GET handling. + * If resources in the repository are not visible in the + * filesystem location which URLs map to, then special handling + * is required to first fetch a resource from the repository, + * respond to the GET request, then free the resource copy. + */ + int handle_get; + + /* Get a resource descriptor for the URI in a request. A descriptor + * should always be returned even if the resource does not exist. This + * repository has been identified as handling the resource given by + * the URI, so an answer must be given. If there is a problem with the + * URI or accessing the resource or whatever, then an error should be + * returned. + * + * root_dir: + * the root of the directory for which this repository is configured. + * + * label: + * if a Label: header is present (and allowed), this is the label + * to use to identify a version resource from the resource's + * corresponding version history. Otherwise, it will be NULL. + * + * use_checked_in: + * use the DAV:checked-in property of the resource identified by the + * Request-URI to identify and return a version resource + * + * The provider may associate the request storage pool with the resource + * (in the resource->pool field), to use in other operations on that + * resource. + */ + dav_error * (*get_resource)( + request_rec *r, + const char *root_dir, + const char *label, + int use_checked_in, + dav_resource **resource + ); + + /* Get a resource descriptor for the parent of the given resource. + * The resources need not exist. NULL is returned if the resource + * is the root collection. + * + * An error should be returned only if there is a fatal error in + * fetching information about the parent resource. + */ + dav_error * (*get_parent_resource)( + const dav_resource *resource, + dav_resource **parent_resource + ); + + /* Determine whether two resource descriptors refer to the same resource. + * + * Result != 0 => the resources are the same. + */ + int (*is_same_resource)( + const dav_resource *res1, + const dav_resource *res2 + ); + + /* Determine whether one resource is a parent (immediate or otherwise) + * of another. + * + * Result != 0 => res1 is a parent of res2. + */ + int (*is_parent_resource)( + const dav_resource *res1, + const dav_resource *res2 + ); + + /* + ** Open a stream for this resource, using the specified mode. The + ** stream will be returned in *stream. + */ + dav_error * (*open_stream)(const dav_resource *resource, + dav_stream_mode mode, + dav_stream **stream); + + /* + ** Close the specified stream. + ** + ** mod_dav will (ideally) make sure to call this. For safety purposes, + ** a provider should (ideally) register a cleanup function with the + ** request pool to get this closed and cleaned up. + ** + ** Note the possibility of an error from the close -- it is entirely + ** feasible that the close does a "commit" of some kind, which can + ** produce an error. + ** + ** commit should be TRUE (non-zero) or FALSE (0) if the stream was + ** opened for writing. This flag states whether to retain the file + ** or not. + ** Note: the commit flag is ignored for streams opened for reading. + */ + dav_error * (*close_stream)(dav_stream *stream, int commit); + + /* + ** Write data to the stream. + ** + ** All of the bytes must be written, or an error should be returned. + */ + dav_error * (*write_stream)(dav_stream *stream, + const void *buf, apr_size_t bufsize); + + /* + ** Seek to an absolute position in the stream. This is used to support + ** Content-Range in a GET/PUT. + ** + ** NOTE: if this function is NULL (which is allowed), then any + ** operations using Content-Range will be refused. + */ + dav_error * (*seek_stream)(dav_stream *stream, apr_off_t abs_position); + + /* + ** If a GET is processed using a stream (open_stream, read_stream) + ** rather than via a sub-request (on get_pathname), then this function + ** is used to provide the repository with a way to set the headers + ** in the response. + ** + ** This function may be called without a following deliver(), to + ** handle a HEAD request. + ** + ** This may be NULL if handle_get is FALSE. + */ + dav_error * (*set_headers)(request_rec *r, + const dav_resource *resource); + + /* + ** The provider should deliver the resource into the specified filter. + ** Basically, this is the response to the GET method. + ** + ** Note that this is called for all resources, including collections. + ** The provider should determine what has content to deliver or not. + ** + ** set_headers will be called prior to this function, allowing the + ** provider to set the appropriate response headers. + ** + ** This may be NULL if handle_get is FALSE. + ** ### maybe toss handle_get and just use this function as the marker + */ + dav_error * (*deliver)(const dav_resource *resource, + ap_filter_t *output); + + /* Create a collection resource. The resource must not already exist. + * + * Result == NULL if the collection was created successfully. Also, the + * resource object is updated to reflect that the resource exists, and + * is a collection. + */ + dav_error * (*create_collection)( + dav_resource *resource + ); + + /* Copy one resource to another. The destination may exist, if it is + * versioned. + * Handles both files and collections. Properties are copied as well. + * If the destination exists and is versioned, the provider must update + * the destination to have identical content to the source, + * recursively for collections. + * The depth argument is ignored for a file, and can be either 0 or + * DAV_INFINITY for a collection. + * If an error occurs in a child resource, then the return value is + * non-NULL, and *response is set to a multistatus response. + * If the copy is successful, the dst resource object is + * updated to reflect that the resource exists. + */ + dav_error * (*copy_resource)( + const dav_resource *src, + dav_resource *dst, + int depth, + dav_response **response + ); + + /* Move one resource to another. The destination must not exist. + * Handles both files and collections. Properties are moved as well. + * If an error occurs in a child resource, then the return value is + * non-NULL, and *response is set to a multistatus response. + * If the move is successful, the src and dst resource objects are + * updated to reflect that the source no longer exists, and the + * destination does. + */ + dav_error * (*move_resource)( + dav_resource *src, + dav_resource *dst, + dav_response **response + ); + + /* Remove a resource. Handles both files and collections. + * Removes any associated properties as well. + * If an error occurs in a child resource, then the return value is + * non-NULL, and *response is set to a multistatus response. + * If the delete is successful, the resource object is updated to + * reflect that the resource no longer exists. + */ + dav_error * (*remove_resource)( + dav_resource *resource, + dav_response **response + ); + + /* Walk a resource hierarchy. + * + * Iterates over the resource hierarchy specified by params->root. + * Control of the walk and the callback are specified by 'params'. + * + * An error may be returned. *response will contain multistatus + * responses (if any) suitable for the body of the error. It is also + * possible to return NULL, yet still have multistatus responses. + * In this case, typically the caller should return a 207 (Multistatus) + * and the responses (in the body) as the HTTP response. + */ + dav_error * (*walk)(const dav_walk_params *params, int depth, + dav_response **response); + + /* Get the entity tag for a resource */ + const char * (*getetag)(const dav_resource *resource); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; +}; + + +/* -------------------------------------------------------------------- +** +** VERSIONING FUNCTIONS +*/ + + +/* dav_add_vary_header + * + * If there were any headers in the request which require a Vary header + * in the response, add it. + */ +DAV_DECLARE(void) dav_add_vary_header(request_rec *in_req, + request_rec *out_req, + const dav_resource *resource); + +/* +** Flags specifying auto-versioning behavior, returned by +** the auto_versionable hook. The value returned depends +** on both the state of the resource and the value of the +** DAV:auto-versioning property for the resource. +** +** If the resource does not exist (null or lock-null), +** DAV_AUTO_VERSION_ALWAYS causes creation of a new version-controlled resource +** +** If the resource is checked in, +** DAV_AUTO_VERSION_ALWAYS causes it to be checked out always, +** DAV_AUTO_VERSION_LOCKED causes it to be checked out only when locked +** +** If the resource is checked out, +** DAV_AUTO_VERSION_ALWAYS causes it to be checked in always, +** DAV_AUTO_VERSION_LOCKED causes it to be checked in when unlocked +** (note: a provider should allow auto-checkin only for resources which +** were automatically checked out) +** +** In all cases, DAV_AUTO_VERSION_NEVER results in no auto-versioning behavior. +*/ +typedef enum { + DAV_AUTO_VERSION_NEVER, + DAV_AUTO_VERSION_ALWAYS, + DAV_AUTO_VERSION_LOCKED +} dav_auto_version; + +/* +** This structure is used to record what auto-versioning operations +** were done to make a resource writable, so that they can be undone +** at the end of a request. +*/ +typedef struct { + int resource_versioned; /* 1 => resource was auto-version-controlled */ + int resource_checkedout; /* 1 => resource was auto-checked-out */ + int parent_checkedout; /* 1 => parent was auto-checked-out */ + dav_resource *parent_resource; /* parent resource, if it was needed */ +} dav_auto_version_info; + +/* Ensure that a resource is writable. If there is no versioning + * provider, then this is essentially a no-op. Versioning repositories + * require explicit resource creation and checkout before they can + * be written to. If a new resource is to be created, or an existing + * resource deleted, the parent collection must be checked out as well. + * + * Set the parent_only flag to only make the parent collection writable. + * Otherwise, both parent and child are made writable as needed. If the + * child does not exist, then a new versioned resource is created and + * checked out. + * + * If auto-versioning is not enabled for a versioned resource, then an error is + * returned, since the resource cannot be modified. + * + * The dav_auto_version_info structure is filled in with enough information + * to restore both parent and child resources to the state they were in + * before the auto-versioning operations occurred. + */ +DAV_DECLARE(dav_error *) dav_auto_checkout( + request_rec *r, + dav_resource *resource, + int parent_only, + dav_auto_version_info *av_info); + +/* Revert the writability of resources back to what they were + * before they were modified. If undo == 0, then the resource + * modifications are maintained (i.e. they are checked in). + * If undo != 0, then resource modifications are discarded + * (i.e. they are unchecked out). + * + * Set the unlock flag to indicate that the resource is about + * to be unlocked; it will be checked in if the resource + * auto-versioning property indicates it should be. In this case, + * av_info is ignored, so it can be NULL. + * + * The resource argument may be NULL if only the parent resource + * was checked out (i.e. the parent_only was != 0 in the + * dav_auto_checkout call). + */ +DAV_DECLARE(dav_error *) dav_auto_checkin( + request_rec *r, + dav_resource *resource, + int undo, + int unlock, + dav_auto_version_info *av_info); + +/* +** This structure is used to describe available reports +** +** "nmspace" should be valid XML and URL-quoted. mod_dav will place +** double-quotes around it and use it in an xmlns declaration. +*/ +typedef struct { + const char *nmspace; /* namespace of the XML report element */ + const char *name; /* element name for the XML report */ +} dav_report_elem; + + +/* Versioning provider hooks */ +struct dav_hooks_vsn +{ + /* + ** MANDATORY HOOKS + ** The following hooks are mandatory for all versioning providers; + ** they define the functionality needed to implement "core" versioning. + */ + + /* Return supported versioning options. + * Each dav_text item in the list will be returned as a separate + * DAV header. Providers are advised to limit the length of an + * individual text item to 63 characters, to conform to the limit + * used by MS Web Folders. + */ + void (*get_vsn_options)(apr_pool_t *p, apr_text_header *phdr); + + /* Get the value of a specific option for an OPTIONS request. + * The option being requested is given by the parsed XML + * element object "elem". The value of the option should be + * appended to the "option" text object. + */ + dav_error * (*get_option)(const dav_resource *resource, + const apr_xml_elem *elem, + apr_text_header *option); + + /* Determine whether a non-versioned (or non-existent) resource + * is versionable. Returns != 0 if resource can be versioned. + */ + int (*versionable)(const dav_resource *resource); + + /* Determine whether auto-versioning is enabled for a resource + * (which may not exist, or may not be versioned). If the resource + * is a checked-out resource, the provider must only enable + * auto-checkin if the resource was automatically checked out. + * + * The value returned depends on both the state of the resource + * and the value of its DAV:auto-version property. See the description + * of the dav_auto_version enumeration above for the details. + */ + dav_auto_version (*auto_versionable)(const dav_resource *resource); + + /* Put a resource under version control. If the resource already + * exists unversioned, then it becomes the initial version of the + * new version history, and it is replaced by a version selector + * which targets the new version. + * + * If the resource does not exist, then a new version-controlled + * resource is created which either targets an existing version (if the + * "target" argument is not NULL), or the initial, empty version + * in a new history resource (if the "target" argument is NULL). + * + * If successful, the resource object state is updated appropriately + * (that is, changed to refer to the new version-controlled resource). + */ + dav_error * (*vsn_control)(dav_resource *resource, + const char *target); + + /* Checkout a resource. If successful, the resource + * object state is updated appropriately. + * + * The auto_checkout flag will be set if this checkout is being + * done automatically, as part of some method which modifies + * the resource. The provider must remember that the resource + * was automatically checked out, so it can determine whether it + * can be automatically checked in. (Auto-checkin should only be + * enabled for resources which were automatically checked out.) + * + * If the working resource has a different URL from the + * target resource, a dav_resource descriptor is returned + * for the new working resource. Otherwise, the original + * resource descriptor will refer to the working resource. + * The working_resource argument can be NULL if the caller + * is not interested in the working resource. + * + * If the client has specified DAV:unreserved or DAV:fork-ok in the + * checkout request, then the corresponding flags are set. If + * DAV:activity-set has been specified, then create_activity is set + * if DAV:new was specified; otherwise, the DAV:href elements' CDATA + * (the actual href text) is passed in the "activities" array (each + * element of the array is a const char *). activities will be NULL + * no DAV:activity-set was provided or when create_activity is set. + */ + dav_error * (*checkout)(dav_resource *resource, + int auto_checkout, + int is_unreserved, int is_fork_ok, + int create_activity, + apr_array_header_t *activities, + dav_resource **working_resource); + + /* Uncheckout a checked-out resource. If successful, the resource + * object state is updated appropriately. + */ + dav_error * (*uncheckout)(dav_resource *resource); + + /* Checkin a checked-out resource. If successful, the resource + * object state is updated appropriately, and the + * version_resource descriptor will refer to the new version. + * The version_resource argument can be NULL if the caller + * is not interested in the new version resource. + * + * If the client has specified DAV:keep-checked-out in the checkin + * request, then the keep_checked_out flag is set. The provider + * should create a new version, but keep the resource in the + * checked-out state. + */ + dav_error * (*checkin)(dav_resource *resource, + int keep_checked_out, + dav_resource **version_resource); + + /* + ** Return the set of reports available at this resource. + ** + ** An array of report elements should be returned, with an end-marker + ** element containing namespace==NULL. The value of the + ** DAV:supported-report-set property will be constructed and + ** returned. + */ + dav_error * (*avail_reports)(const dav_resource *resource, + const dav_report_elem **reports); + + /* + ** Determine whether a Label header can be used + ** with a particular report. The dav_xml_doc structure + ** contains the parsed report request body. + ** Returns 0 if the Label header is not allowed. + */ + int (*report_label_header_allowed)(const apr_xml_doc *doc); + + /* + ** Generate a report on a resource. Since a provider is free + ** to define its own reports, and the value of request headers + ** may affect the interpretation of a report, the request record + ** must be passed to this routine. + ** + ** The dav_xml_doc structure contains the parsed report request + ** body. The report response should be generated into the specified + ** output filter. + ** + ** If an error occurs, and a response has not yet been generated, + ** then an error can be returned from this function. mod_dav will + ** construct an appropriate error response. Once some output has + ** been placed into the filter, however, the provider should not + ** return an error -- there is no way that mod_dav can deliver it + ** properly. + ** + ** ### maybe we need a way to signal an error anyways, and then + ** ### apache can abort the connection? + */ + dav_error * (*deliver_report)(request_rec *r, + const dav_resource *resource, + const apr_xml_doc *doc, + ap_filter_t *output); + + /* + ** OPTIONAL HOOKS + ** The following hooks are optional; if not defined, then the + ** corresponding protocol methods will be unsupported. + */ + + /* + ** Set the state of a checked-in version-controlled resource. + ** + ** If the request specified a version, the version resource + ** represents that version. If the request specified a label, + ** then "version" is NULL, and "label" is the label. + ** + ** The depth argument is ignored for a file, and can be 0, 1, or + ** DAV_INFINITY for a collection. The depth argument only applies + ** with a label, not a version. + ** + ** If an error occurs in a child resource, then the return value is + ** non-NULL, and *response is set to a multistatus response. + ** + ** This hook is optional; if not defined, then the UPDATE method + ** will not be supported. + */ + dav_error * (*update)(const dav_resource *resource, + const dav_resource *version, + const char *label, + int depth, + dav_response **response); + + /* + ** Add a label to a version. The resource is either a specific + ** version, or a version selector, in which case the label should + ** be added to the current target of the version selector. The + ** version selector cannot be checked out. + ** + ** If replace != 0, any existing label by the same name is + ** effectively deleted first. Otherwise, it is an error to + ** attempt to add a label which already exists on some version + ** of the same history resource. + ** + ** This hook is optional; if not defined, then the LABEL method + ** will not be supported. If it is defined, then the remove_label + ** hook must be defined also. + */ + dav_error * (*add_label)(const dav_resource *resource, + const char *label, + int replace); + + /* + ** Remove a label from a version. The resource is either a specific + ** version, or a version selector, in which case the label should + ** be added to the current target of the version selector. The + ** version selector cannot be checked out. + ** + ** It is an error if no such label exists on the specified version. + ** + ** This hook is optional, but if defined, the add_label hook + ** must be defined also. + */ + dav_error * (*remove_label)(const dav_resource *resource, + const char *label); + + /* + ** Determine whether a null resource can be created as a workspace. + ** The provider may restrict workspaces to certain locations. + ** Returns 0 if the resource cannot be a workspace. + ** + ** This hook is optional; if the provider does not support workspaces, + ** it should be set to NULL. + */ + int (*can_be_workspace)(const dav_resource *resource); + + /* + ** Create a workspace resource. The resource must not already + ** exist. Any element is passed to the provider + ** in the "doc" structure; it may be empty. + ** + ** If workspace creation is succesful, the state of the resource + ** object is updated appropriately. + ** + ** This hook is optional; if the provider does not support workspaces, + ** it should be set to NULL. + */ + dav_error * (*make_workspace)(dav_resource *resource, + apr_xml_doc *doc); + + /* + ** Determine whether a null resource can be created as an activity. + ** The provider may restrict activities to certain locations. + ** Returns 0 if the resource cannot be an activity. + ** + ** This hook is optional; if the provider does not support activities, + ** it should be set to NULL. + */ + int (*can_be_activity)(const dav_resource *resource); + + /* + ** Create an activity resource. The resource must not already + ** exist. + ** + ** If activity creation is succesful, the state of the resource + ** object is updated appropriately. + ** + ** This hook is optional; if the provider does not support activities, + ** it should be set to NULL. + */ + dav_error * (*make_activity)(dav_resource *resource); + + /* + ** Merge a resource (tree) into target resource (tree). + ** + ** ### more doc... + ** + ** This hook is optional; if the provider does not support merging, + ** then this should be set to NULL. + */ + dav_error * (*merge)(dav_resource *target, dav_resource *source, + int no_auto_merge, int no_checkout, + apr_xml_elem *prop_elem, + ap_filter_t *output); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; +}; + + +/* -------------------------------------------------------------------- +** +** BINDING FUNCTIONS +*/ + +/* binding provider hooks */ +struct dav_hooks_binding { + + /* Determine whether a resource can be the target of a binding. + * Returns 0 if the resource cannot be a binding target. + */ + int (*is_bindable)(const dav_resource *resource); + + /* Create a binding to a resource. + * The resource argument is the target of the binding; + * the binding argument must be a resource which does not already + * exist. + */ + dav_error * (*bind_resource)(const dav_resource *resource, + dav_resource *binding); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; + +}; + + +/* -------------------------------------------------------------------- +** +** SEARCH(DASL) FUNCTIONS +*/ + +/* search provider hooks */ +struct dav_hooks_search { + /* Set header for a OPTION method + * An error may be returned. + * To set a hadder, this function might call + * apr_table_setn(r->headers_out, "DASL", dasl_optin1); + * + * Examples: + * DASL: + * DASL: + * DASL: + */ + dav_error * (*set_option_head)(request_rec *r); + + /* Search resources + * An error may be returned. *response will contain multistatus + * responses (if any) suitable for the body of the error. It is also + * possible to return NULL, yet still have multistatus responses. + * In this case, typically the caller should return a 207 (Multistatus) + * and the responses (in the body) as the HTTP response. + */ + dav_error * (*search_resource)(request_rec *r, + dav_response **response); + + /* + ** If a provider needs a context to associate with this hooks structure, + ** then this field may be used. In most cases, it will just be NULL. + */ + void *ctx; + +}; + + +/* -------------------------------------------------------------------- +** +** MISCELLANEOUS STUFF +*/ + +/* fetch the "LimitXMLRequestBody" in force for this resource */ +DAV_DECLARE(apr_size_t) dav_get_limit_xml_body(const request_rec *r); + +typedef struct { + int propid; /* live property ID */ + const dav_hooks_liveprop *provider; /* the provider defining this prop */ +} dav_elem_private; + +#ifdef __cplusplus +} +#endif + +#endif /* _MOD_DAV_H_ */ diff --git a/trunk/modules/dav/main/props.c b/trunk/modules/dav/main/props.c new file mode 100644 index 0000000000..480135de67 --- /dev/null +++ b/trunk/modules/dav/main/props.c @@ -0,0 +1,1121 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV extension module for Apache 2.0.* +** - Property database handling (repository-independent) +** +** NOTES: +** +** PROPERTY DATABASE +** +** This version assumes that there is a per-resource database provider +** to record properties. The database provider decides how and where to +** store these databases. +** +** The DBM keys for the properties have the following form: +** +** namespace ":" propname +** +** For example: 5:author +** +** The namespace provides an integer index into the namespace table +** (see below). propname is simply the property name, without a namespace +** prefix. +** +** A special case exists for properties that had a prefix starting with +** "xml". The XML Specification reserves these for future use. mod_dav +** stores and retrieves them unchanged. The keys for these properties +** have the form: +** +** ":" propname +** +** The propname will contain the prefix and the property name. For +** example, a key might be ":xmlfoo:name" +** +** The ":name" style will also be used for properties that do not +** exist within a namespace. +** +** The DBM values consist of two null-terminated strings, appended +** together (the null-terms are retained and stored in the database). +** The first string is the xml:lang value for the property. An empty +** string signifies that a lang value was not in context for the value. +** The second string is the property value itself. +** +** +** NAMESPACE TABLE +** +** The namespace table is an array that lists each of the namespaces +** that are in use by the properties in the given propdb. Each entry +** in the array is a simple URI. +** +** For example: http://www.foo.bar/standards/props/ +** +** The prefix used for the property is stripped and the URI for it +** is entered into the namespace table. Also, any namespaces used +** within the property value will be entered into the table (and +** stripped from the child elements). +** +** The namespaces are stored in the DBM database under the "METADATA" key. +** +** +** STRIPPING NAMESPACES +** +** Within the property values, the namespace declarations (xmlns...) +** are stripped. Each element and attribute will have its prefix removed +** and a new prefix inserted. +** +** This must be done so that we can return multiple properties in a +** PROPFIND which may have (originally) used conflicting prefixes. For +** that case, we must bind all property value elements to new namespace +** values. +** +** This implies that clients must NOT be sensitive to the namespace +** prefix used for their properties. It WILL change when the properties +** are returned (we return them as "ns", e.g. "ns5"). Also, the +** property value can contain ONLY XML elements and CDATA. PI and comment +** elements will be stripped. CDATA whitespace will be preserved, but +** whitespace within element tags will be altered. Attribute ordering +** may be altered. Element and CDATA ordering will be preserved. +** +** +** ATTRIBUTES ON PROPERTY NAME ELEMENTS +** +** When getting/setting properties, the XML used looks like: +** +** +** value +** value +** +** +** This implementation (mod_dav) DOES NOT save any attributes that are +** associated with the element. The property value is deemed +** to be only the contents ("value" in the above example). +** +** We do store the xml:lang value (if any) that applies to the context +** of the element. Whether the xml:lang attribute is on +** itself, or from a higher level element, we will store it +** with the property value. +** +** +** VERSIONING +** +** The DBM db contains a key named "METADATA" that holds database-level +** information, such as the namespace table. The record also contains the +** db's version number as the very first 16-bit value. This first number +** is actually stored as two single bytes: the first byte is a "major" +** version number. The second byte is a "minor" number. +** +** If the major number is not what mod_dav expects, then the db is closed +** immediately and an error is returned. A minor number change is +** acceptable -- it is presumed that old/new dav_props.c can deal with +** the database format. For example, a newer dav_props might update the +** minor value and append information to the end of the metadata record +** (which would be ignored by previous versions). +** +** +** ISSUES: +** +** At the moment, for the dav_get_allprops() and dav_get_props() functions, +** we must return a set of xmlns: declarations for ALL known namespaces +** in the file. There isn't a way to filter this because we don't know +** which are going to be used or not. Examining property names is not +** sufficient because the property values could use entirely different +** namespaces. +** +** ==> we must devise a scheme where we can "garbage collect" the namespace +** entries from the property database. +*/ + +#include "apr.h" +#include "apr_strings.h" + +#define APR_WANT_STDIO +#define APR_WANT_BYTEFUNC +#include "apr_want.h" + +#include "mod_dav.h" + +#include "http_log.h" +#include "http_request.h" + +/* +** There is some rough support for writable DAV:getcontenttype and +** DAV:getcontentlanguage properties. If this #define is (1), then +** this support is disabled. +** +** We are disabling it because of a lack of support in GET and PUT +** operations. For GET, it would be "expensive" to look for a propdb, +** open it, and attempt to extract the Content-Type and Content-Language +** values for the response. +** (Handling the PUT would not be difficult, though) +*/ +#define DAV_DISABLE_WRITABLE_PROPS 1 + +#define DAV_EMPTY_VALUE "\0" /* TWO null terms */ + +struct dav_propdb { + apr_pool_t *p; /* the pool we should use */ + request_rec *r; /* the request record */ + + const dav_resource *resource; /* the target resource */ + + int deferred; /* open of db has been deferred */ + dav_db *db; /* underlying database containing props */ + + apr_array_header_t *ns_xlate; /* translation of an elem->ns to URI */ + dav_namespace_map *mapping; /* namespace mapping */ + + dav_lockdb *lockdb; /* the lock database */ + + dav_buffer wb_lock; /* work buffer for lockdiscovery property */ + + /* if we ever run a GET subreq, it will be stored here */ + request_rec *subreq; + + /* hooks we should use for processing (based on the target resource) */ + const dav_hooks_db *db_hooks; +}; + +/* NOTE: dav_core_props[] and the following enum must stay in sync. */ +/* ### move these into a "core" liveprop provider? */ +static const char * const dav_core_props[] = +{ + "getcontenttype", + "getcontentlanguage", + "lockdiscovery", + "supportedlock", + + NULL /* sentinel */ +}; +enum { + DAV_PROPID_CORE_getcontenttype = DAV_PROPID_CORE, + DAV_PROPID_CORE_getcontentlanguage, + DAV_PROPID_CORE_lockdiscovery, + DAV_PROPID_CORE_supportedlock, + + DAV_PROPID_CORE_UNKNOWN +}; + +/* +** This structure is used to track information needed for a rollback. +*/ +typedef struct dav_rollback_item { + /* select one of the two rollback context structures based on the + value of dav_prop_ctx.is_liveprop */ + dav_deadprop_rollback *deadprop; + dav_liveprop_rollback *liveprop; + +} dav_rollback_item; + + +static int dav_find_liveprop_provider(dav_propdb *propdb, + const char *ns_uri, + const char *propname, + const dav_hooks_liveprop **provider) +{ + int propid; + + *provider = NULL; + + if (ns_uri == NULL) { + /* policy: liveprop providers cannot define no-namespace properties */ + return DAV_PROPID_CORE_UNKNOWN; + } + + /* check liveprop providers first, so they can define core properties */ + propid = dav_run_find_liveprop(propdb->resource, ns_uri, propname, + provider); + if (propid != 0) { + return propid; + } + + /* check for core property */ + if (strcmp(ns_uri, "DAV:") == 0) { + const char * const *p = dav_core_props; + + for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid) + if (strcmp(propname, *p) == 0) { + return propid; + } + } + + /* no provider for this property */ + return DAV_PROPID_CORE_UNKNOWN; +} + +static void dav_find_liveprop(dav_propdb *propdb, apr_xml_elem *elem) +{ + const char *ns_uri; + dav_elem_private *priv = elem->priv; + const dav_hooks_liveprop *hooks; + + + if (elem->ns == APR_XML_NS_NONE) + ns_uri = NULL; + else if (elem->ns == APR_XML_NS_DAV_ID) + ns_uri = "DAV:"; + else + ns_uri = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns); + + priv->propid = dav_find_liveprop_provider(propdb, ns_uri, elem->name, + &hooks); + + /* ### this test seems redundant... */ + if (priv->propid != DAV_PROPID_CORE_UNKNOWN) { + priv->provider = hooks; + } +} + +/* is the live property read/write? */ +static int dav_rw_liveprop(dav_propdb *propdb, dav_elem_private *priv) +{ + int propid = priv->propid; + + /* + ** Check the liveprop provider (if this is a provider-defined prop) + */ + if (priv->provider != NULL) { + return (*priv->provider->is_writable)(propdb->resource, propid); + } + + /* these are defined as read-only */ + if (propid == DAV_PROPID_CORE_lockdiscovery +#if DAV_DISABLE_WRITABLE_PROPS + || propid == DAV_PROPID_CORE_getcontenttype + || propid == DAV_PROPID_CORE_getcontentlanguage +#endif + || propid == DAV_PROPID_CORE_supportedlock + ) { + + return 0; + } + + /* these are defined as read/write */ + if (propid == DAV_PROPID_CORE_getcontenttype + || propid == DAV_PROPID_CORE_getcontentlanguage + || propid == DAV_PROPID_CORE_UNKNOWN) { + + return 1; + } + + /* + ** We don't recognize the property, so it must be dead (and writable) + */ + return 1; +} + +/* do a sub-request to fetch properties for the target resource's URI. */ +static void dav_do_prop_subreq(dav_propdb *propdb) +{ + /* perform a "GET" on the resource's URI (note that the resource + may not correspond to the current request!). */ + propdb->subreq = ap_sub_req_lookup_uri(propdb->resource->uri, propdb->r, + NULL); +} + +static dav_error * dav_insert_coreprop(dav_propdb *propdb, + int propid, const char *name, + dav_prop_insert what, + apr_text_header *phdr, + dav_prop_insert *inserted) +{ + const char *value = NULL; + dav_error *err; + + *inserted = DAV_PROP_INSERT_NOTDEF; + + /* fast-path the common case */ + if (propid == DAV_PROPID_CORE_UNKNOWN) + return NULL; + + switch (propid) { + + case DAV_PROPID_CORE_lockdiscovery: + if (propdb->lockdb != NULL) { + dav_lock *locks; + + if ((err = dav_lock_query(propdb->lockdb, propdb->resource, + &locks)) != NULL) { + return dav_push_error(propdb->p, err->status, 0, + "DAV:lockdiscovery could not be " + "determined due to a problem fetching " + "the locks for this resource.", + err); + } + + /* fast-path the no-locks case */ + if (locks == NULL) { + value = ""; + } + else { + /* + ** This may modify the buffer. value may point to + ** wb_lock.pbuf or a string constant. + */ + value = dav_lock_get_activelock(propdb->r, locks, + &propdb->wb_lock); + + /* make a copy to isolate it from changes to wb_lock */ + value = apr_pstrdup(propdb->p, propdb->wb_lock.buf); + } + } + break; + + case DAV_PROPID_CORE_supportedlock: + if (propdb->lockdb != NULL) { + value = (*propdb->lockdb->hooks->get_supportedlock)(propdb->resource); + } + break; + + case DAV_PROPID_CORE_getcontenttype: + if (propdb->subreq == NULL) { + dav_do_prop_subreq(propdb); + } + if (propdb->subreq->content_type != NULL) { + value = propdb->subreq->content_type; + } + break; + + case DAV_PROPID_CORE_getcontentlanguage: + { + const char *lang; + + if (propdb->subreq == NULL) { + dav_do_prop_subreq(propdb); + } + if ((lang = apr_table_get(propdb->subreq->headers_out, + "Content-Language")) != NULL) { + value = lang; + } + break; + } + + default: + /* fall through to interpret as a dead property */ + break; + } + + /* if something was supplied, then insert it */ + if (value != NULL) { + const char *s; + + if (what == DAV_PROP_INSERT_SUPPORTED) { + /* use D: prefix to refer to the DAV: namespace URI, + * and let the namespace attribute default to "DAV:" + */ + s = apr_psprintf(propdb->p, + "" DEBUG_CR, + name); + } + else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') { + /* use D: prefix to refer to the DAV: namespace URI */ + s = apr_psprintf(propdb->p, "%s" DEBUG_CR, + name, value, name); + } + else { + /* use D: prefix to refer to the DAV: namespace URI */ + s = apr_psprintf(propdb->p, "" DEBUG_CR, name); + } + apr_text_append(propdb->p, phdr, s); + + *inserted = what; + } + + return NULL; +} + +static dav_error * dav_insert_liveprop(dav_propdb *propdb, + const apr_xml_elem *elem, + dav_prop_insert what, + apr_text_header *phdr, + dav_prop_insert *inserted) +{ + dav_elem_private *priv = elem->priv; + + *inserted = DAV_PROP_INSERT_NOTDEF; + + if (priv->provider == NULL) { + /* this is a "core" property that we define */ + return dav_insert_coreprop(propdb, priv->propid, elem->name, + what, phdr, inserted); + } + + /* ask the provider (that defined this prop) to insert the prop */ + *inserted = (*priv->provider->insert_prop)(propdb->resource, priv->propid, + what, phdr); + + return NULL; +} + +static void dav_output_prop_name(apr_pool_t *pool, + const dav_prop_name *name, + dav_xmlns_info *xi, + apr_text_header *phdr) +{ + const char *s; + + if (*name->ns == '\0') + s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name->name); + else { + const char *prefix = dav_xmlns_add_uri(xi, name->ns); + + s = apr_psprintf(pool, "<%s:%s/>" DEBUG_CR, prefix, name->name); + } + + apr_text_append(pool, phdr, s); +} + +static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, int ns, + const char *ns_uri, apr_text_header *phdr) +{ + const char *s; + + s = apr_psprintf(p, " xmlns:%s%d=\"%s\"", pre_prefix, ns, ns_uri); + apr_text_append(p, phdr, s); +} + +static dav_error *dav_really_open_db(dav_propdb *propdb, int ro) +{ + dav_error *err; + + /* we're trying to open the db; turn off the 'deferred' flag */ + propdb->deferred = 0; + + /* ask the DB provider to open the thing */ + err = (*propdb->db_hooks->open)(propdb->p, propdb->resource, ro, + &propdb->db); + if (err != NULL) { + return dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_PROP_OPENING, + "Could not open the property database.", + err); + } + + /* + ** NOTE: propdb->db could be NULL if we attempted to open a readonly + ** database that doesn't exist. If we require read/write + ** access, then a database was created and opened. + */ + + return NULL; +} + +DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb, + const dav_resource *resource, + int ro, + apr_array_header_t * ns_xlate, + dav_propdb **p_propdb) +{ + dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb)); + + *p_propdb = NULL; + +#if DAV_DEBUG + if (resource->uri == NULL) { + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: resource must define " + "its URI."); + } +#endif + + propdb->r = r; + apr_pool_create(&propdb->p, r->pool); + propdb->resource = resource; + propdb->ns_xlate = ns_xlate; + + propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r); + + propdb->lockdb = lockdb; + + /* always defer actual open, to avoid expense of accessing db + * when only live properties are involved + */ + propdb->deferred = 1; + + /* ### what to do about closing the propdb on server failure? */ + + *p_propdb = propdb; + return NULL; +} + +DAV_DECLARE(void) dav_close_propdb(dav_propdb *propdb) +{ + if (propdb->db != NULL) { + (*propdb->db_hooks->close)(propdb->db); + } + + /* Currently, mod_dav's pool usage doesn't allow clearing this pool. */ +#if 0 + apr_pool_destroy(propdb->p); +#endif + return; +} + +DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb, + dav_prop_insert what) +{ + const dav_hooks_db *db_hooks = propdb->db_hooks; + apr_text_header hdr = { 0 }; + apr_text_header hdr_ns = { 0 }; + dav_get_props_result result = { 0 }; + int found_contenttype = 0; + int found_contentlang = 0; + dav_prop_insert unused_inserted; + + /* if not just getting supported live properties, + * scan all properties in the dead prop database + */ + if (what != DAV_PROP_INSERT_SUPPORTED) { + if (propdb->deferred) { + /* ### what to do with db open error? */ + (void) dav_really_open_db(propdb, 1 /*ro*/); + } + + /* initialize the result with some start tags... */ + apr_text_append(propdb->p, &hdr, + "" DEBUG_CR + "" DEBUG_CR); + + /* if there ARE properties, then scan them */ + if (propdb->db != NULL) { + dav_xmlns_info *xi = dav_xmlns_create(propdb->p); + dav_prop_name name; + + /* define (up front) any namespaces the db might need */ + (void) (*db_hooks->define_namespaces)(propdb->db, xi); + + /* get the first property name, beginning the scan */ + (void) (*db_hooks->first_name)(propdb->db, &name); + while (name.ns != NULL) { + + /* + ** We also look for and + ** . If they are not stored as dead + ** properties, then we need to perform a subrequest to get + ** their values (if any). + */ + if (*name.ns == 'D' && strcmp(name.ns, "DAV:") == 0 + && *name.name == 'g') { + if (strcmp(name.name, "getcontenttype") == 0) { + found_contenttype = 1; + } + else if (strcmp(name.name, "getcontentlanguage") == 0) { + found_contentlang = 1; + } + } + + if (what == DAV_PROP_INSERT_VALUE) { + dav_error *err; + int found; + + if ((err = (*db_hooks->output_value)(propdb->db, &name, + xi, &hdr, + &found)) != NULL) { + /* ### anything better to do? */ + /* ### probably should enter a 500 error */ + goto next_key; + } + /* assert: found == 1 */ + } + else { + /* the value was not requested, so just add an empty + tag specifying the property name. */ + dav_output_prop_name(propdb->p, &name, xi, &hdr); + } + + next_key: + (void) (*db_hooks->next_name)(propdb->db, &name); + } + + /* all namespaces have been entered into xi. generate them into + the output now. */ + dav_xmlns_generate(xi, &hdr_ns); + + } /* propdb->db != NULL */ + + /* add namespaces for all the liveprop providers */ + dav_add_all_liveprop_xmlns(propdb->p, &hdr_ns); + } + + /* ask the liveprop providers to insert their properties */ + dav_run_insert_all_liveprops(propdb->r, propdb->resource, what, &hdr); + + /* insert the standard properties */ + /* ### should be handling the return errors here */ + (void)dav_insert_coreprop(propdb, + DAV_PROPID_CORE_supportedlock, "supportedlock", + what, &hdr, &unused_inserted); + (void)dav_insert_coreprop(propdb, + DAV_PROPID_CORE_lockdiscovery, "lockdiscovery", + what, &hdr, &unused_inserted); + + /* if we didn't find these, then do the whole subreq thing. */ + if (!found_contenttype) { + /* ### should be handling the return error here */ + (void)dav_insert_coreprop(propdb, + DAV_PROPID_CORE_getcontenttype, + "getcontenttype", + what, &hdr, &unused_inserted); + } + if (!found_contentlang) { + /* ### should be handling the return error here */ + (void)dav_insert_coreprop(propdb, + DAV_PROPID_CORE_getcontentlanguage, + "getcontentlanguage", + what, &hdr, &unused_inserted); + } + + /* if not just reporting on supported live props, + * terminate the result */ + if (what != DAV_PROP_INSERT_SUPPORTED) { + apr_text_append(propdb->p, &hdr, + "" DEBUG_CR + "HTTP/1.1 200 OK" DEBUG_CR + "" DEBUG_CR); + } + + result.propstats = hdr.first; + result.xmlns = hdr_ns.first; + return result; +} + +DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb, + apr_xml_doc *doc) +{ + const dav_hooks_db *db_hooks = propdb->db_hooks; + apr_xml_elem *elem = dav_find_child(doc->root, "prop"); + apr_text_header hdr_good = { 0 }; + apr_text_header hdr_bad = { 0 }; + apr_text_header hdr_ns = { 0 }; + int have_good = 0; + dav_get_props_result result = { 0 }; + char *marks_liveprop; + dav_xmlns_info *xi; + int xi_filled = 0; + + /* ### NOTE: we should pass in TWO buffers -- one for keys, one for + the marks */ + + /* we will ALWAYS provide a "good" result, even if it is EMPTY */ + apr_text_append(propdb->p, &hdr_good, + "" DEBUG_CR + "" DEBUG_CR); + + /* ### the marks should be in a buffer! */ + /* allocate zeroed-memory for the marks. These marks indicate which + liveprop namespaces we've generated into the output xmlns buffer */ + + /* same for the liveprops */ + marks_liveprop = apr_pcalloc(propdb->p, dav_get_liveprop_ns_count() + 1); + + xi = dav_xmlns_create(propdb->p); + + for (elem = elem->first_child; elem; elem = elem->next) { + dav_elem_private *priv; + dav_error *err; + dav_prop_insert inserted; + dav_prop_name name; + + /* + ** First try live property providers; if they don't handle + ** the property, then try looking it up in the propdb. + */ + + if (elem->priv == NULL) { + elem->priv = apr_pcalloc(propdb->p, sizeof(*priv)); + } + priv = elem->priv; + + /* cache the propid; dav_get_props() could be called many times */ + if (priv->propid == 0) + dav_find_liveprop(propdb, elem); + + if (priv->propid != DAV_PROPID_CORE_UNKNOWN) { + + /* insert the property. returns 1 if an insertion was done. */ + if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE, + &hdr_good, &inserted)) != NULL) { + /* ### need to propagate the error to the caller... */ + /* ### skip it for now, as if nothing was inserted */ + } + if (inserted == DAV_PROP_INSERT_VALUE) { + have_good = 1; + + /* + ** Add the liveprop's namespace URIs. Note that provider==NULL + ** for core properties. + */ + if (priv->provider != NULL) { + const char * const * scan_ns_uri; + + for (scan_ns_uri = priv->provider->namespace_uris; + *scan_ns_uri != NULL; + ++scan_ns_uri) { + int ns; + + ns = dav_get_liveprop_ns_index(*scan_ns_uri); + if (marks_liveprop[ns]) + continue; + marks_liveprop[ns] = 1; + + dav_insert_xmlns(propdb->p, "lp", ns, *scan_ns_uri, + &hdr_ns); + } + } + + /* property added. move on to the next property. */ + continue; + } + else if (inserted == DAV_PROP_INSERT_NOTDEF) { + /* nothing to do. fall thru to allow property to be handled + as a dead property */ + } +#if DAV_DEBUG + else { +#if 0 + /* ### need to change signature to return an error */ + return dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, 0, + "INTERNAL DESIGN ERROR: insert_liveprop " + "did not insert what was asked for."); +#endif + } +#endif + } + + /* The property wasn't a live property, so look in the dead property + database. */ + + /* make sure propdb is really open */ + if (propdb->deferred) { + /* ### what to do with db open error? */ + (void) dav_really_open_db(propdb, 1 /*ro*/); + } + + if (elem->ns == APR_XML_NS_NONE) + name.ns = ""; + else + name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns); + name.name = elem->name; + + /* only bother to look if a database exists */ + if (propdb->db != NULL) { + int found; + + if ((err = (*db_hooks->output_value)(propdb->db, &name, + xi, &hdr_good, + &found)) != NULL) { + /* ### what to do? continue doesn't seem right... */ + continue; + } + + if (found) { + have_good = 1; + + /* if we haven't added the db's namespaces, then do so... */ + if (!xi_filled) { + (void) (*db_hooks->define_namespaces)(propdb->db, xi); + xi_filled = 1; + } + continue; + } + } + + /* not found as a live OR dead property. add a record to the "bad" + propstats */ + + /* make sure we've started our "bad" propstat */ + if (hdr_bad.first == NULL) { + apr_text_append(propdb->p, &hdr_bad, + "" DEBUG_CR + "" DEBUG_CR); + } + + /* output this property's name (into the bad propstats) */ + dav_output_prop_name(propdb->p, &name, xi, &hdr_bad); + } + + apr_text_append(propdb->p, &hdr_good, + "" DEBUG_CR + "HTTP/1.1 200 OK" DEBUG_CR + "" DEBUG_CR); + + /* default to start with the good */ + result.propstats = hdr_good.first; + + /* we may not have any "bad" results */ + if (hdr_bad.first != NULL) { + /* "close" the bad propstat */ + apr_text_append(propdb->p, &hdr_bad, + "" DEBUG_CR + "HTTP/1.1 404 Not Found" DEBUG_CR + "" DEBUG_CR); + + /* if there are no good props, then just return the bad */ + if (!have_good) { + result.propstats = hdr_bad.first; + } + else { + /* hook the bad propstat to the end of the good one */ + hdr_good.last->next = hdr_bad.first; + } + } + + /* add in all the various namespaces, and return them */ + dav_xmlns_generate(xi, &hdr_ns); + result.xmlns = hdr_ns.first; + + return result; +} + +DAV_DECLARE(void) dav_get_liveprop_supported(dav_propdb *propdb, + const char *ns_uri, + const char *propname, + apr_text_header *body) +{ + int propid; + const dav_hooks_liveprop *hooks; + + propid = dav_find_liveprop_provider(propdb, ns_uri, propname, &hooks); + + if (propid != DAV_PROPID_CORE_UNKNOWN) { + if (hooks == NULL) { + /* this is a "core" property that we define */ + dav_prop_insert unused_inserted; + dav_insert_coreprop(propdb, propid, propname, + DAV_PROP_INSERT_SUPPORTED, body, &unused_inserted); + } + else { + (*hooks->insert_prop)(propdb->resource, propid, + DAV_PROP_INSERT_SUPPORTED, body); + } + } +} + +DAV_DECLARE_NONSTD(void) dav_prop_validate(dav_prop_ctx *ctx) +{ + dav_propdb *propdb = ctx->propdb; + apr_xml_elem *prop = ctx->prop; + dav_elem_private *priv; + + priv = ctx->prop->priv = apr_pcalloc(propdb->p, sizeof(*priv)); + + /* + ** Check to see if this is a live property, and fill the fields + ** in the XML elem, as appropriate. + ** + ** Verify that the property is read/write. If not, then it cannot + ** be SET or DELETEd. + */ + if (priv->propid == 0) { + dav_find_liveprop(propdb, prop); + + /* it's a liveprop if a provider was found */ + /* ### actually the "core" props should really be liveprops, but + ### there is no "provider" for those and the r/w props are + ### treated as dead props anyhow */ + ctx->is_liveprop = priv->provider != NULL; + } + + if (!dav_rw_liveprop(propdb, priv)) { + ctx->err = dav_new_error(propdb->p, HTTP_CONFLICT, + DAV_ERR_PROP_READONLY, + "Property is read-only."); + return; + } + + if (ctx->is_liveprop) { + int defer_to_dead = 0; + + ctx->err = (*priv->provider->patch_validate)(propdb->resource, + prop, ctx->operation, + &ctx->liveprop_ctx, + &defer_to_dead); + if (ctx->err != NULL || !defer_to_dead) + return; + + /* clear is_liveprop -- act as a dead prop now */ + ctx->is_liveprop = 0; + } + + /* + ** The property is supposed to be stored into the dead-property + ** database. Make sure the thing is truly open (and writable). + */ + if (propdb->deferred + && (ctx->err = dav_really_open_db(propdb, 0 /* ro */)) != NULL) { + return; + } + + /* + ** There should be an open, writable database in here! + ** + ** Note: the database would be NULL if it was opened readonly and it + ** did not exist. + */ + if (propdb->db == NULL) { + ctx->err = dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_PROP_NO_DATABASE, + "Attempted to set/remove a property " + "without a valid, open, read/write " + "property database."); + return; + } + + if (ctx->operation == DAV_PROP_OP_SET) { + /* + ** Prep the element => propdb namespace index mapping, inserting + ** namespace URIs into the propdb that don't exist. + */ + (void) (*propdb->db_hooks->map_namespaces)(propdb->db, + propdb->ns_xlate, + &propdb->mapping); + } + else if (ctx->operation == DAV_PROP_OP_DELETE) { + /* + ** There are no checks to perform here. If a property exists, then + ** we will delete it. If it does not exist, then it does not matter + ** (see S12.13.1). + ** + ** Note that if a property does not exist, that does not rule out + ** that a SET will occur during this PROPPATCH (thusly creating it). + */ + } +} + +DAV_DECLARE_NONSTD(void) dav_prop_exec(dav_prop_ctx *ctx) +{ + dav_propdb *propdb = ctx->propdb; + dav_error *err = NULL; + dav_elem_private *priv = ctx->prop->priv; + + ctx->rollback = apr_pcalloc(propdb->p, sizeof(*ctx->rollback)); + + if (ctx->is_liveprop) { + err = (*priv->provider->patch_exec)(propdb->resource, + ctx->prop, ctx->operation, + ctx->liveprop_ctx, + &ctx->rollback->liveprop); + } + else { + dav_prop_name name; + + if (ctx->prop->ns == APR_XML_NS_NONE) + name.ns = ""; + else + name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, ctx->prop->ns); + name.name = ctx->prop->name; + + /* save the old value so that we can do a rollback. */ + if ((err = (*propdb->db_hooks + ->get_rollback)(propdb->db, &name, + &ctx->rollback->deadprop)) != NULL) + goto error; + + if (ctx->operation == DAV_PROP_OP_SET) { + + /* Note: propdb->mapping was set in dav_prop_validate() */ + err = (*propdb->db_hooks->store)(propdb->db, &name, ctx->prop, + propdb->mapping); + + /* + ** If an error occurred, then assume that we didn't change the + ** value. Remove the rollback item so that we don't try to set + ** its value during the rollback. + */ + /* ### euh... where is the removal? */ + } + else if (ctx->operation == DAV_PROP_OP_DELETE) { + + /* + ** Delete the property. Ignore errors -- the property is there, or + ** we are deleting it for a second time. + */ + /* ### but what about other errors? */ + (void) (*propdb->db_hooks->remove)(propdb->db, &name); + } + } + + error: + /* push a more specific error here */ + if (err != NULL) { + /* + ** Use HTTP_INTERNAL_SERVER_ERROR because we shouldn't have seen + ** any errors at this point. + */ + ctx->err = dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_PROP_EXEC, + "Could not execute PROPPATCH.", err); + } +} + +DAV_DECLARE_NONSTD(void) dav_prop_commit(dav_prop_ctx *ctx) +{ + dav_elem_private *priv = ctx->prop->priv; + + /* + ** Note that a commit implies ctx->err is NULL. The caller should assume + ** a status of HTTP_OK for this case. + */ + + if (ctx->is_liveprop) { + (*priv->provider->patch_commit)(ctx->propdb->resource, + ctx->operation, + ctx->liveprop_ctx, + ctx->rollback->liveprop); + } +} + +DAV_DECLARE_NONSTD(void) dav_prop_rollback(dav_prop_ctx *ctx) +{ + dav_error *err = NULL; + dav_elem_private *priv = ctx->prop->priv; + + /* do nothing if there is no rollback information. */ + if (ctx->rollback == NULL) + return; + + /* + ** ### if we have an error, and a rollback occurs, then the namespace + ** ### mods should not happen at all. Basically, the namespace management + ** ### is simply a bitch. + */ + + if (ctx->is_liveprop) { + err = (*priv->provider->patch_rollback)(ctx->propdb->resource, + ctx->operation, + ctx->liveprop_ctx, + ctx->rollback->liveprop); + } + else { + err = (*ctx->propdb->db_hooks + ->apply_rollback)(ctx->propdb->db, ctx->rollback->deadprop); + } + + if (err != NULL) { + if (ctx->err == NULL) + ctx->err = err; + else { + dav_error *scan = err; + + /* hook previous errors at the end of the rollback error */ + while (scan->prev != NULL) + scan = scan->prev; + scan->prev = ctx->err; + ctx->err = err; + } + } +} diff --git a/trunk/modules/dav/main/providers.c b/trunk/modules/dav/main/providers.c new file mode 100644 index 0000000000..77322bef82 --- /dev/null +++ b/trunk/modules/dav/main/providers.c @@ -0,0 +1,33 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_pools.h" +#include "apr_hash.h" +#include "ap_provider.h" +#include "mod_dav.h" + +#define DAV_PROVIDER_GROUP "dav" + +DAV_DECLARE(void) dav_register_provider(apr_pool_t *p, const char *name, + const dav_provider *provider) +{ + ap_register_provider(p, DAV_PROVIDER_GROUP, name, "0", provider); +} + +DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name) +{ + return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0"); +} diff --git a/trunk/modules/dav/main/std_liveprop.c b/trunk/modules/dav/main/std_liveprop.c new file mode 100644 index 0000000000..416472ddc2 --- /dev/null +++ b/trunk/modules/dav/main/std_liveprop.c @@ -0,0 +1,194 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "util_xml.h" +#include "apr_strings.h" + +#include "mod_dav.h" + +/* forward-declare */ +static const dav_hooks_liveprop dav_core_hooks_liveprop; + +/* +** The namespace URIs that we use. There will only ever be "DAV:". +*/ +static const char * const dav_core_namespace_uris[] = +{ + "DAV:", + NULL /* sentinel */ +}; + +/* +** Define each of the core properties that this provider will handle. +** Note that all of them are in the DAV: namespace, which has a +** provider-local index of 0. +*/ +static const dav_liveprop_spec dav_core_props[] = +{ + { 0, "comment", DAV_PROPID_comment, 1 }, + { 0, "creator-displayname", DAV_PROPID_creator_displayname, 1 }, + { 0, "displayname", DAV_PROPID_displayname, 1 }, + { 0, "resourcetype", DAV_PROPID_resourcetype, 0 }, + { 0, "source", DAV_PROPID_source, 1 }, + + { 0 } /* sentinel */ +}; + +static const dav_liveprop_group dav_core_liveprop_group = +{ + dav_core_props, + dav_core_namespace_uris, + &dav_core_hooks_liveprop +}; + +static dav_prop_insert dav_core_insert_prop(const dav_resource *resource, + int propid, dav_prop_insert what, + apr_text_header *phdr) +{ + const char *value; + const char *s; + apr_pool_t *p = resource->pool; + const dav_liveprop_spec *info; + int global_ns; + + switch (propid) + { + case DAV_PROPID_resourcetype: + switch (resource->type) { + case DAV_RESOURCE_TYPE_VERSION: + if (resource->baselined) { + value = ""; + break; + } + /* fall through */ + case DAV_RESOURCE_TYPE_REGULAR: + case DAV_RESOURCE_TYPE_WORKING: + if (resource->collection) { + value = ""; + } + else { + /* ### should we denote lock-null resources? */ + + value = ""; /* becomes: */ + } + break; + case DAV_RESOURCE_TYPE_HISTORY: + value = ""; + break; + case DAV_RESOURCE_TYPE_WORKSPACE: + value = ""; + break; + case DAV_RESOURCE_TYPE_ACTIVITY: + value = ""; + break; + + default: + /* ### bad juju */ + return DAV_PROP_INSERT_NOTDEF; + } + break; + + case DAV_PROPID_comment: + case DAV_PROPID_creator_displayname: + case DAV_PROPID_displayname: + case DAV_PROPID_source: + default: + /* + ** This property is known, but not defined as a liveprop. However, + ** it may be a dead property. + */ + return DAV_PROP_INSERT_NOTDEF; + } + + /* assert: value != NULL */ + + /* get the information and global NS index for the property */ + global_ns = dav_get_liveprop_info(propid, &dav_core_liveprop_group, &info); + + /* assert: info != NULL && info->name != NULL */ + + if (what == DAV_PROP_INSERT_SUPPORTED) { + s = apr_psprintf(p, + "" DEBUG_CR, + info->name, dav_core_namespace_uris[info->ns]); + } + else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') { + s = apr_psprintf(p, "%s" DEBUG_CR, + global_ns, info->name, value, global_ns, info->name); + } + else { + s = apr_psprintf(p, "" DEBUG_CR, global_ns, info->name); + } + apr_text_append(p, phdr, s); + + /* we inserted what was asked for */ + return what; +} + +static int dav_core_is_writable(const dav_resource *resource, int propid) +{ + const dav_liveprop_spec *info; + + (void) dav_get_liveprop_info(propid, &dav_core_liveprop_group, &info); + return info->is_writable; +} + +static dav_error * dav_core_patch_validate(const dav_resource *resource, + const apr_xml_elem *elem, + int operation, void **context, + int *defer_to_dead) +{ + /* all of our writable props go in the dead prop database */ + *defer_to_dead = 1; + + return NULL; +} + +static const dav_hooks_liveprop dav_core_hooks_liveprop = { + dav_core_insert_prop, + dav_core_is_writable, + dav_core_namespace_uris, + dav_core_patch_validate, + NULL, /* patch_exec */ + NULL, /* patch_commit */ + NULL, /* patch_rollback */ +}; + +DAV_DECLARE_NONSTD(int) dav_core_find_liveprop( + const dav_resource *resource, + const char *ns_uri, const char *name, + const dav_hooks_liveprop **hooks) +{ + return dav_do_find_liveprop(ns_uri, name, &dav_core_liveprop_group, hooks); +} + +DAV_DECLARE_NONSTD(void) dav_core_insert_all_liveprops( + request_rec *r, + const dav_resource *resource, + dav_prop_insert what, + apr_text_header *phdr) +{ + (void) dav_core_insert_prop(resource, DAV_PROPID_resourcetype, + what, phdr); +} + +DAV_DECLARE_NONSTD(void) dav_core_register_uris(apr_pool_t *p) +{ + /* register the namespace URIs */ + dav_register_liveprop_group(p, &dav_core_liveprop_group); +} diff --git a/trunk/modules/dav/main/util.c b/trunk/modules/dav/main/util.c new file mode 100644 index 0000000000..0593298786 --- /dev/null +++ b/trunk/modules/dav/main/util.c @@ -0,0 +1,2041 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV extension module for Apache 2.0.* +** - various utilities, repository-independent +*/ + +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "mod_dav.h" + +#include "http_request.h" +#include "http_config.h" +#include "http_vhost.h" +#include "http_log.h" +#include "http_protocol.h" + +DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, + int error_id, const char *desc) +{ + int save_errno = errno; + dav_error *err = apr_pcalloc(p, sizeof(*err)); + + /* DBG3("dav_new_error: %d %d %s", status, error_id, desc ? desc : "(no desc)"); */ + + err->status = status; + err->error_id = error_id; + err->desc = desc; + err->save_errno = save_errno; + + return err; +} + +DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status, + int error_id, const char *desc, + const char *namespace, + const char *tagname) +{ + dav_error *err = dav_new_error(p, status, error_id, desc); + + err->tagname = tagname; + err->namespace = namespace; + + return err; +} + + +DAV_DECLARE(dav_error*) dav_push_error(apr_pool_t *p, int status, + int error_id, const char *desc, + dav_error *prev) +{ + dav_error *err = apr_pcalloc(p, sizeof(*err)); + + err->status = status; + err->error_id = error_id; + err->desc = desc; + err->prev = prev; + + return err; +} + +DAV_DECLARE(void) dav_check_bufsize(apr_pool_t * p, dav_buffer *pbuf, + apr_size_t extra_needed) +{ + /* grow the buffer if necessary */ + if (pbuf->cur_len + extra_needed > pbuf->alloc_len) { + char *newbuf; + + pbuf->alloc_len += extra_needed + DAV_BUFFER_PAD; + newbuf = apr_palloc(p, pbuf->alloc_len); + memcpy(newbuf, pbuf->buf, pbuf->cur_len); + pbuf->buf = newbuf; + } +} + +DAV_DECLARE(void) dav_set_bufsize(apr_pool_t * p, dav_buffer *pbuf, + apr_size_t size) +{ + /* NOTE: this does not retain prior contents */ + + /* NOTE: this function is used to init the first pointer, too, since + the PAD will be larger than alloc_len (0) for zeroed structures */ + + /* grow if we don't have enough for the requested size plus padding */ + if (size + DAV_BUFFER_PAD > pbuf->alloc_len) { + /* set the new length; min of MINSIZE */ + pbuf->alloc_len = size + DAV_BUFFER_PAD; + if (pbuf->alloc_len < DAV_BUFFER_MINSIZE) + pbuf->alloc_len = DAV_BUFFER_MINSIZE; + + pbuf->buf = apr_palloc(p, pbuf->alloc_len); + } + pbuf->cur_len = size; +} + + +/* initialize a buffer and copy the specified (null-term'd) string into it */ +DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf, + const char *str) +{ + dav_set_bufsize(p, pbuf, strlen(str)); + memcpy(pbuf->buf, str, pbuf->cur_len + 1); +} + +/* append a string to the end of the buffer, adjust length */ +DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, + const char *str) +{ + apr_size_t len = strlen(str); + + dav_check_bufsize(p, pbuf, len + 1); + memcpy(pbuf->buf + pbuf->cur_len, str, len + 1); + pbuf->cur_len += len; +} + +/* place a string on the end of the buffer, do NOT adjust length */ +DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf, + const char *str) +{ + apr_size_t len = strlen(str); + + dav_check_bufsize(p, pbuf, len + 1); + memcpy(pbuf->buf + pbuf->cur_len, str, len + 1); +} + +/* place some memory on the end of a buffer; do NOT adjust length */ +DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf, + const void *mem, apr_size_t amt, + apr_size_t pad) +{ + dav_check_bufsize(p, pbuf, amt + pad); + memcpy(pbuf->buf + pbuf->cur_len, mem, amt); +} + +/* +** dav_lookup_uri() +** +** Extension for ap_sub_req_lookup_uri() which can't handle absolute +** URIs properly. +** +** If NULL is returned, then an error occurred with parsing the URI or +** the URI does not match the current server. +*/ +DAV_DECLARE(dav_lookup_result) dav_lookup_uri(const char *uri, + request_rec * r, + int must_be_absolute) +{ + dav_lookup_result result = { 0 }; + const char *scheme; + apr_port_t port; + apr_uri_t comp; + char *new_file; + const char *domain; + + /* first thing to do is parse the URI into various components */ + if (apr_uri_parse(r->pool, uri, &comp) != APR_SUCCESS) { + result.err.status = HTTP_BAD_REQUEST; + result.err.desc = "Invalid syntax in Destination URI."; + return result; + } + + /* the URI must be an absoluteURI (WEBDAV S9.3) */ + if (comp.scheme == NULL && must_be_absolute) { + result.err.status = HTTP_BAD_REQUEST; + result.err.desc = "Destination URI must be an absolute URI."; + return result; + } + + /* the URI must not have a query (args) or a fragment */ + if (comp.query != NULL || comp.fragment != NULL) { + result.err.status = HTTP_BAD_REQUEST; + result.err.desc = + "Destination URI contains invalid components " + "(a query or a fragment)."; + return result; + } + + /* If the scheme or port was provided, then make sure that it matches + the scheme/port of this request. If the request must be absolute, + then require the (explicit/implicit) scheme/port be matching. + + ### hmm. if a port wasn't provided (does the parse return port==0?), + ### but we're on a non-standard port, then we won't detect that the + ### URI's port implies the wrong one. + */ + if (comp.scheme != NULL || comp.port != 0 || must_be_absolute) + { + /* ### not sure this works if the current request came in via https: */ + scheme = r->parsed_uri.scheme; + if (scheme == NULL) + scheme = ap_http_scheme(r); + + /* insert a port if the URI did not contain one */ + if (comp.port == 0) + comp.port = apr_uri_port_of_scheme(comp.scheme); + + /* now, verify that the URI uses the same scheme as the current. + request. the port must match our port. + */ + port = r->connection->local_addr->port; + if (strcasecmp(comp.scheme, scheme) != 0 +#ifdef APACHE_PORT_HANDLING_IS_BUSTED + || comp.port != port +#endif + ) { + result.err.status = HTTP_BAD_GATEWAY; + result.err.desc = apr_psprintf(r->pool, + "Destination URI refers to " + "different scheme or port " + "(%s://hostname:%d)" APR_EOL_STR + "(want: %s://hostname:%d)", + comp.scheme ? comp.scheme : scheme, + comp.port ? comp.port : port, + scheme, port); + return result; + } + } + + /* we have verified the scheme, port, and general structure */ + + /* + ** Hrm. IE5 will pass unqualified hostnames for both the + ** Host: and Destination: headers. This breaks the + ** http_vhost.c::matches_aliases function. + ** + ** For now, qualify unqualified comp.hostnames with + ** r->server->server_hostname. + ** + ** ### this is a big hack. Apache should provide a better way. + ** ### maybe the admin should list the unqualified hosts in a + ** ### block? + */ + if (comp.hostname != NULL + && strrchr(comp.hostname, '.') == NULL + && (domain = strchr(r->server->server_hostname, '.')) != NULL) { + comp.hostname = apr_pstrcat(r->pool, comp.hostname, domain, NULL); + } + + /* now, if a hostname was provided, then verify that it represents the + same server as the current connection. note that we just use our + port, since we've verified the URI matches ours */ +#ifdef APACHE_PORT_HANDLING_IS_BUSTED + if (comp.hostname != NULL && + !ap_matches_request_vhost(r, comp.hostname, port)) { + result.err.status = HTTP_BAD_GATEWAY; + result.err.desc = "Destination URI refers to a different server."; + return result; + } +#endif + + /* we have verified that the requested URI denotes the same server as + the current request. Therefore, we can use ap_sub_req_lookup_uri() */ + + /* reconstruct a URI as just the path */ + new_file = apr_uri_unparse(r->pool, &comp, APR_URI_UNP_OMITSITEPART); + + /* + * Lookup the URI and return the sub-request. Note that we use the + * same HTTP method on the destination. This allows the destination + * to apply appropriate restrictions (e.g. readonly). + */ + result.rnew = ap_sub_req_method_uri(r->method, new_file, r, NULL); + + return result; +} + +/* --------------------------------------------------------------- +** +** XML UTILITY FUNCTIONS +*/ + +/* validate that the root element uses a given DAV: tagname (TRUE==valid) */ +DAV_DECLARE(int) dav_validate_root(const apr_xml_doc *doc, + const char *tagname) +{ + return doc->root && + doc->root->ns == APR_XML_NS_DAV_ID && + strcmp(doc->root->name, tagname) == 0; +} + +/* find and return the (unique) child with a given DAV: tagname */ +DAV_DECLARE(apr_xml_elem *) dav_find_child(const apr_xml_elem *elem, + const char *tagname) +{ + apr_xml_elem *child = elem->first_child; + + for (; child; child = child->next) + if (child->ns == APR_XML_NS_DAV_ID && !strcmp(child->name, tagname)) + return child; + return NULL; +} + +/* gather up all the CDATA into a single string */ +DAV_DECLARE(const char *) dav_xml_get_cdata(const apr_xml_elem *elem, apr_pool_t *pool, + int strip_white) +{ + apr_size_t len = 0; + apr_text *scan; + const apr_xml_elem *child; + char *cdata; + char *s; + apr_size_t tlen; + const char *found_text = NULL; /* initialize to avoid gcc warning */ + int found_count = 0; + + for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) { + found_text = scan->text; + ++found_count; + len += strlen(found_text); + } + + for (child = elem->first_child; child != NULL; child = child->next) { + for (scan = child->following_cdata.first; + scan != NULL; + scan = scan->next) { + found_text = scan->text; + ++found_count; + len += strlen(found_text); + } + } + + /* some fast-path cases: + * 1) zero-length cdata + * 2) a single piece of cdata with no whitespace to strip + */ + if (len == 0) + return ""; + if (found_count == 1) { + if (!strip_white + || (!apr_isspace(*found_text) + && !apr_isspace(found_text[len - 1]))) + return found_text; + } + + cdata = s = apr_palloc(pool, len + 1); + + for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) { + tlen = strlen(scan->text); + memcpy(s, scan->text, tlen); + s += tlen; + } + + for (child = elem->first_child; child != NULL; child = child->next) { + for (scan = child->following_cdata.first; + scan != NULL; + scan = scan->next) { + tlen = strlen(scan->text); + memcpy(s, scan->text, tlen); + s += tlen; + } + } + + *s = '\0'; + + if (strip_white) { + /* trim leading whitespace */ + while (apr_isspace(*cdata)) /* assume: return false for '\0' */ + ++cdata; + + /* trim trailing whitespace */ + while (len-- > 0 && apr_isspace(cdata[len])) + continue; + cdata[len + 1] = '\0'; + } + + return cdata; +} + +DAV_DECLARE(dav_xmlns_info *) dav_xmlns_create(apr_pool_t *pool) +{ + dav_xmlns_info *xi = apr_pcalloc(pool, sizeof(*xi)); + + xi->pool = pool; + xi->uri_prefix = apr_hash_make(pool); + xi->prefix_uri = apr_hash_make(pool); + + return xi; +} + +DAV_DECLARE(void) dav_xmlns_add(dav_xmlns_info *xi, + const char *prefix, const char *uri) +{ + /* this "should" not overwrite a prefix mapping */ + apr_hash_set(xi->prefix_uri, prefix, APR_HASH_KEY_STRING, uri); + + /* note: this may overwrite an existing URI->prefix mapping, but it + doesn't matter -- any prefix is usuable to specify the URI. */ + apr_hash_set(xi->uri_prefix, uri, APR_HASH_KEY_STRING, prefix); +} + +DAV_DECLARE(const char *) dav_xmlns_add_uri(dav_xmlns_info *xi, + const char *uri) +{ + const char *prefix; + + if ((prefix = apr_hash_get(xi->uri_prefix, uri, + APR_HASH_KEY_STRING)) != NULL) + return prefix; + + prefix = apr_psprintf(xi->pool, "g%d", xi->count++); + dav_xmlns_add(xi, prefix, uri); + return prefix; +} + +DAV_DECLARE(const char *) dav_xmlns_get_uri(dav_xmlns_info *xi, + const char *prefix) +{ + return apr_hash_get(xi->prefix_uri, prefix, APR_HASH_KEY_STRING); +} + +DAV_DECLARE(const char *) dav_xmlns_get_prefix(dav_xmlns_info *xi, + const char *uri) +{ + return apr_hash_get(xi->uri_prefix, uri, APR_HASH_KEY_STRING); +} + +DAV_DECLARE(void) dav_xmlns_generate(dav_xmlns_info *xi, + apr_text_header *phdr) +{ + apr_hash_index_t *hi = apr_hash_first(xi->pool, xi->prefix_uri); + + for (; hi != NULL; hi = apr_hash_next(hi)) { + const void *prefix; + void *uri; + const char *s; + + apr_hash_this(hi, &prefix, NULL, &uri); + + s = apr_psprintf(xi->pool, " xmlns:%s=\"%s\"", + (const char *)prefix, (const char *)uri); + apr_text_append(xi->pool, phdr, s); + } +} + +/* --------------------------------------------------------------- +** +** Timeout header processing +** +*/ + +/* dav_get_timeout: If the Timeout: header exists, return a time_t + * when this lock is expected to expire. Otherwise, return + * a time_t of DAV_TIMEOUT_INFINITE. + * + * It's unclear if DAV clients are required to understand + * Seconds-xxx and Infinity time values. We assume that they do. + * In addition, for now, that's all we understand, too. + */ +DAV_DECLARE(time_t) dav_get_timeout(request_rec *r) +{ + time_t now, expires = DAV_TIMEOUT_INFINITE; + + const char *timeout_const = apr_table_get(r->headers_in, "Timeout"); + const char *timeout = apr_pstrdup(r->pool, timeout_const), *val; + + if (timeout == NULL) + return DAV_TIMEOUT_INFINITE; + + /* Use the first thing we understand, or infinity if + * we don't understand anything. + */ + + while ((val = ap_getword_white(r->pool, &timeout)) && strlen(val)) { + if (!strncmp(val, "Infinite", 8)) { + return DAV_TIMEOUT_INFINITE; + } + + if (!strncmp(val, "Second-", 7)) { + val += 7; + /* ### We need to handle overflow better: + * ### timeout will be <= 2^32 - 1 + */ + expires = atol(val); + now = time(NULL); + return now + expires; + } + } + + return DAV_TIMEOUT_INFINITE; +} + +/* --------------------------------------------------------------- +** +** If Header processing +** +*/ + +/* add_if_resource returns a new if_header, linking it to next_ih. + */ +static dav_if_header *dav_add_if_resource(apr_pool_t *p, dav_if_header *next_ih, + const char *uri, apr_size_t uri_len) +{ + dav_if_header *ih; + + if ((ih = apr_pcalloc(p, sizeof(*ih))) == NULL) + return NULL; + + ih->uri = uri; + ih->uri_len = uri_len; + ih->next = next_ih; + + return ih; +} + +/* add_if_state adds a condition to an if_header. + */ +static dav_error * dav_add_if_state(apr_pool_t *p, dav_if_header *ih, + const char *state_token, + dav_if_state_type t, int condition, + const dav_hooks_locks *locks_hooks) +{ + dav_if_state_list *new_sl; + + new_sl = apr_pcalloc(p, sizeof(*new_sl)); + + new_sl->condition = condition; + new_sl->type = t; + + if (t == dav_if_opaquelock) { + dav_error *err; + + if ((err = (*locks_hooks->parse_locktoken)(p, state_token, + &new_sl->locktoken)) != NULL) { + /* In cases where the state token is invalid, we'll just skip + * it rather than return 400. + */ + if (err->error_id == DAV_ERR_LOCK_UNK_STATE_TOKEN) { + return NULL; + } + else { + /* ### maybe add a higher-level description */ + return err; + } + } + } + else + new_sl->etag = state_token; + + new_sl->next = ih->state; + ih->state = new_sl; + + return NULL; +} + +/* fetch_next_token returns the substring from str+1 + * to the next occurence of char term, or \0, whichever + * occurs first. Leading whitespace is ignored. + */ +static char *dav_fetch_next_token(char **str, char term) +{ + char *sp; + char *token; + + token = *str + 1; + + while (*token && (*token == ' ' || *token == '\t')) + token++; + + if ((sp = strchr(token, term)) == NULL) + return NULL; + + *sp = '\0'; + *str = sp; + return token; +} + +/* dav_process_if_header: + * + * If NULL (no error) is returned, then **if_header points to the + * "If" productions structure (or NULL if "If" is not present). + * + * ### this part is bogus: + * If an error is encountered, the error is logged. Parent should + * return err->status. + */ +static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih) +{ + dav_error *err; + char *str; + char *list; + const char *state_token; + const char *uri = NULL; /* scope of current production; NULL=no-tag */ + apr_size_t uri_len = 0; + dav_if_header *ih = NULL; + apr_uri_t parsed_uri; + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + enum {no_tagged, tagged, unknown} list_type = unknown; + int condition; + + *p_ih = NULL; + + if ((str = apr_pstrdup(r->pool, apr_table_get(r->headers_in, "If"))) == NULL) + return NULL; + + while (*str) { + switch(*str) { + case '<': + /* Tagged-list production - following states apply to this uri */ + if (list_type == no_tagged + || ((uri = dav_fetch_next_token(&str, '>')) == NULL)) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_TAGGED, + "Invalid If-header: unclosed \"<\" or " + "unexpected tagged-list production."); + } + + /* 2518 specifies this must be an absolute URI; just take the + * relative part for later comparison against r->uri */ + if (apr_uri_parse(r->pool, uri, &parsed_uri) != APR_SUCCESS) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_TAGGED, + "Invalid URI in tagged If-header."); + } + /* note that parsed_uri.path is allocated; we can trash it */ + + /* clean up the URI a bit */ + ap_getparents(parsed_uri.path); + uri_len = strlen(parsed_uri.path); + if (uri_len > 1 && parsed_uri.path[uri_len - 1] == '/') + parsed_uri.path[--uri_len] = '\0'; + + uri = parsed_uri.path; + list_type = tagged; + break; + + case '(': + /* List production */ + + /* If a uri has not been encountered, this is a No-Tagged-List */ + if (list_type == unknown) + list_type = no_tagged; + + if ((list = dav_fetch_next_token(&str, ')')) == NULL) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_UNCLOSED_PAREN, + "Invalid If-header: unclosed \"(\"."); + } + + if ((ih = dav_add_if_resource(r->pool, ih, uri, uri_len)) == NULL) { + /* ### dav_add_if_resource() should return an error for us! */ + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_PARSE, + "Internal server error parsing \"If:\" " + "header."); + } + + condition = DAV_IF_COND_NORMAL; + + while (*list) { + /* List is the entire production (in a uri scope) */ + + switch (*list) { + case '<': + if ((state_token = dav_fetch_next_token(&list, '>')) == NULL) { + /* ### add a description to this error */ + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_PARSE, NULL); + } + + if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_opaquelock, + condition, locks_hooks)) != NULL) { + /* ### maybe add a higher level description */ + return err; + } + condition = DAV_IF_COND_NORMAL; + break; + + case '[': + if ((state_token = dav_fetch_next_token(&list, ']')) == NULL) { + /* ### add a description to this error */ + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_PARSE, NULL); + } + + if ((err = dav_add_if_state(r->pool, ih, state_token, dav_if_etag, + condition, locks_hooks)) != NULL) { + /* ### maybe add a higher level description */ + return err; + } + condition = DAV_IF_COND_NORMAL; + break; + + case 'N': + if (list[1] == 'o' && list[2] == 't') { + if (condition != DAV_IF_COND_NORMAL) { + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_MULTIPLE_NOT, + "Invalid \"If:\" header: " + "Multiple \"not\" entries " + "for the same state."); + } + condition = DAV_IF_COND_NOT; + } + list += 2; + break; + + case ' ': + case '\t': + break; + + default: + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_UNK_CHAR, + apr_psprintf(r->pool, + "Invalid \"If:\" " + "header: Unexpected " + "character encountered " + "(0x%02x, '%c').", + *list, *list)); + } + + list++; + } + break; + + case ' ': + case '\t': + break; + + default: + return dav_new_error(r->pool, HTTP_BAD_REQUEST, + DAV_ERR_IF_UNK_CHAR, + apr_psprintf(r->pool, + "Invalid \"If:\" header: " + "Unexpected character " + "encountered (0x%02x, '%c').", + *str, *str)); + } + + str++; + } + + *p_ih = ih; + return NULL; +} + +static int dav_find_submitted_locktoken(const dav_if_header *if_header, + const dav_lock *lock_list, + const dav_hooks_locks *locks_hooks) +{ + for (; if_header != NULL; if_header = if_header->next) { + const dav_if_state_list *state_list; + + for (state_list = if_header->state; + state_list != NULL; + state_list = state_list->next) { + + if (state_list->type == dav_if_opaquelock) { + const dav_lock *lock; + + /* given state_list->locktoken, match it */ + + /* + ** The resource will have one or more lock tokens. We only + ** need to match one of them against any token in the + ** If: header. + ** + ** One token case: It is an exclusive or shared lock. Either + ** way, we must find it. + ** + ** N token case: They are shared locks. By policy, we need + ** to match only one. The resource's other + ** tokens may belong to somebody else (so we + ** shouldn't see them in the If: header anyway) + */ + for (lock = lock_list; lock != NULL; lock = lock->next) { + + if (!(*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) { + return 1; + } + } + } + } + } + + return 0; +} + +/* dav_validate_resource_state: + * Returns NULL if path/uri meets if-header and lock requirements + */ +static dav_error * dav_validate_resource_state(apr_pool_t *p, + const dav_resource *resource, + dav_lockdb *lockdb, + const dav_if_header *if_header, + int flags, + dav_buffer *pbuf, + request_rec *r) +{ + dav_error *err; + const char *uri; + const char *etag; + const dav_hooks_locks *locks_hooks = (lockdb ? lockdb->hooks : NULL); + const dav_if_header *ifhdr_scan; + dav_if_state_list *state_list; + dav_lock *lock_list; + dav_lock *lock; + int num_matched; + int num_that_apply; + int seen_locktoken; + apr_size_t uri_len; + const char *reason = NULL; + + /* DBG1("validate: <%s>", resource->uri); */ + + /* + ** The resource will have one of three states: + ** + ** 1) No locks. We have no special requirements that the user supply + ** specific locktokens. One of the state lists must match, and + ** we're done. + ** + ** 2) One exclusive lock. The locktoken must appear *anywhere* in the + ** If: header. Of course, asserting the token in a "Not" term will + ** quickly fail that state list :-). If the locktoken appears in + ** one of the state lists *and* one state list matches, then we're + ** done. + ** + ** 3) One or more shared locks. One of the locktokens must appear + ** *anywhere* in the If: header. If one of the locktokens appears, + ** and we match one state list, then we are done. + ** + ** The variable determines whether we have seen one + ** of this resource's locktokens in the If: header. + */ + + /* + ** If this is a new lock request, will contain the requested + ** lock scope. Three rules apply: + ** + ** 1) Do not require a (shared) locktoken to be seen (when we are + ** applying another shared lock) + ** 2) If the scope is exclusive and we see any locks, fail. + ** 3) If the scope is shared and we see an exclusive lock, fail. + */ + + if (lockdb == NULL) { + /* we're in State 1. no locks. */ + lock_list = NULL; + } + else { + /* + ** ### hrm... we don't need to have these fully + ** ### resolved since we're only looking at the + ** ### locktokens... + ** + ** ### use get_locks w/ calltype=PARTIAL + */ + if ((err = dav_lock_query(lockdb, resource, &lock_list)) != NULL) { + return dav_push_error(p, + HTTP_INTERNAL_SERVER_ERROR, 0, + "The locks could not be queried for " + "verification against a possible \"If:\" " + "header.", + err); + } + + /* lock_list now determines whether we're in State 1, 2, or 3. */ + } + + /* + ** For a new, exclusive lock: if any locks exist, fail. + ** For a new, shared lock: if an exclusive lock exists, fail. + ** else, do not require a token to be seen. + */ + if (flags & DAV_LOCKSCOPE_EXCLUSIVE) { + if (lock_list != NULL) { + return dav_new_error(p, HTTP_LOCKED, 0, + "Existing lock(s) on the requested resource " + "prevent an exclusive lock."); + } + + /* + ** There are no locks, so we can pretend that we've already met + ** any requirement to find the resource's locks in an If: header. + */ + seen_locktoken = 1; + } + else if (flags & DAV_LOCKSCOPE_SHARED) { + /* + ** Strictly speaking, we don't need this loop. Either the first + ** (and only) lock will be EXCLUSIVE, or none of them will be. + */ + for (lock = lock_list; lock != NULL; lock = lock->next) { + if (lock->scope == DAV_LOCKSCOPE_EXCLUSIVE) { + return dav_new_error(p, HTTP_LOCKED, 0, + "The requested resource is already " + "locked exclusively."); + } + } + + /* + ** The locks on the resource (if any) are all shared. Set the + ** flag to indicate that we do not need to find + ** the locks in an If: header. + */ + seen_locktoken = 1; + } + else { + /* + ** For methods other than LOCK: + ** + ** If we have no locks, then can be set to true -- + ** pretending that we've already met the requirement of seeing one + ** of the resource's locks in the If: header. + ** + ** Otherwise, it must be cleared and we'll look for one. + */ + seen_locktoken = (lock_list == NULL); + } + + /* + ** If there is no If: header, then we can shortcut some logic: + ** + ** 1) if we do not need to find a locktoken in the (non-existent) If: + ** header, then we are successful. + ** + ** 2) if we must find a locktoken in the (non-existent) If: header, then + ** we fail. + */ + if (if_header == NULL) { + if (seen_locktoken) + return NULL; + + return dav_new_error(p, HTTP_LOCKED, 0, + "This resource is locked and an \"If:\" header " + "was not supplied to allow access to the " + "resource."); + } + /* the If: header is present */ + + /* + ** If a dummy header is present (because of a Lock-Token: header), then + ** we are required to find that token in this resource's set of locks. + ** If we have no locks, then we immediately fail. + ** + ** This is a 400 (Bad Request) since they should only submit a locktoken + ** that actually exists. + ** + ** Don't issue this response if we're talking about the parent resource. + ** It is okay for that resource to NOT have this locktoken. + ** (in fact, it certainly will not: a dummy_header only occurs for the + ** UNLOCK method, the parent is checked only for locknull resources, + ** and the parent certainly does not have the (locknull's) locktoken) + */ + if (lock_list == NULL && if_header->dummy_header) { + if (flags & DAV_VALIDATE_IS_PARENT) + return NULL; + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "The locktoken specified in the \"Lock-Token:\" " + "header is invalid because this resource has no " + "outstanding locks."); + } + + /* + ** Prepare the input URI. We want the URI to never have a trailing slash. + ** + ** When URIs are placed into the dav_if_header structure, they are + ** guaranteed to never have a trailing slash. If the URIs are equivalent, + ** then it doesn't matter if they both lack a trailing slash -- they're + ** still equivalent. + ** + ** Note: we could also ensure that a trailing slash is present on both + ** URIs, but the majority of URIs provided to us via a resource walk + ** will not contain that trailing slash. + */ + uri = resource->uri; + uri_len = strlen(uri); + if (uri[uri_len - 1] == '/') { + dav_set_bufsize(p, pbuf, uri_len); + memcpy(pbuf->buf, uri, uri_len); + pbuf->buf[--uri_len] = '\0'; + uri = pbuf->buf; + } + + /* get the resource's etag; we may need it during the checks */ + etag = (*resource->hooks->getetag)(resource); + + /* how many state_lists apply to this URI? */ + num_that_apply = 0; + + /* If there are if-headers, fail if this resource + * does not match at least one state_list. + */ + for (ifhdr_scan = if_header; + ifhdr_scan != NULL; + ifhdr_scan = ifhdr_scan->next) { + + /* DBG2("uri=<%s> if_uri=<%s>", uri, ifhdr_scan->uri ? ifhdr_scan->uri : "(no uri)"); */ + + if (ifhdr_scan->uri != NULL + && (uri_len != ifhdr_scan->uri_len + || memcmp(uri, ifhdr_scan->uri, uri_len) != 0)) { + /* + ** A tagged-list's URI doesn't match this resource's URI. + ** Skip to the next state_list to see if it will match. + */ + continue; + } + + /* this state_list applies to this resource */ + + /* + ** ### only one state_list should ever apply! a no-tag, or a tagged + ** ### where S9.4.2 states only one can match. + ** + ** ### revamp this code to loop thru ifhdr_scan until we find the + ** ### matching state_list. process it. stop. + */ + ++num_that_apply; + + /* To succeed, resource must match *all* of the states + * specified in the state_list. + */ + for (state_list = ifhdr_scan->state; + state_list != NULL; + state_list = state_list->next) { + + switch(state_list->type) { + case dav_if_etag: + { + const char *given_etag, *current_etag; + int mismatch; + + /* Do a weak entity comparison function as defined in + * RFC 2616 13.3.3. + */ + if (state_list->etag[0] == 'W' && + state_list->etag[1] == '/') { + given_etag = state_list->etag + 2; + } + else { + given_etag = state_list->etag; + } + if (etag[0] == 'W' && + etag[1] == '/') { + current_etag = etag + 2; + } + else { + current_etag = etag; + } + + mismatch = strcmp(given_etag, current_etag); + + if (state_list->condition == DAV_IF_COND_NORMAL && mismatch) { + /* + ** The specified entity-tag does not match the + ** entity-tag on the resource. This state_list is + ** not going to match. Bust outta here. + */ + reason = + "an entity-tag was specified, but the resource's " + "actual ETag does not match."; + goto state_list_failed; + } + else if (state_list->condition == DAV_IF_COND_NOT + && !mismatch) { + /* + ** The specified entity-tag DOES match the + ** entity-tag on the resource. This state_list is + ** not going to match. Bust outta here. + */ + reason = + "an entity-tag was specified using the \"Not\" form, " + "but the resource's actual ETag matches the provided " + "entity-tag."; + goto state_list_failed; + } + break; + } + + case dav_if_opaquelock: + if (lockdb == NULL) { + if (state_list->condition == DAV_IF_COND_NOT) { + /* the locktoken is definitely not there! (success) */ + continue; + } + + /* condition == DAV_IF_COND_NORMAL */ + + /* + ** If no lockdb is provided, then validation fails for + ** this state_list (NORMAL means we were supposed to + ** find the token, which we obviously cannot do without + ** a lock database). + ** + ** Go and try the next state list. + */ + reason = + "a State-token was supplied, but a lock database " + "is not available for to provide the required lock."; + goto state_list_failed; + } + + /* Resource validation 'fails' if: + * ANY of the lock->locktokens match + * a NOT state_list->locktoken, + * OR + * NONE of the lock->locktokens match + * a NORMAL state_list->locktoken. + */ + num_matched = 0; + for (lock = lock_list; lock != NULL; lock = lock->next) { + + /* + DBG2("compare: rsrc=%s ifhdr=%s", + (*locks_hooks->format_locktoken)(p, lock->locktoken), + (*locks_hooks->format_locktoken)(p, state_list->locktoken)); + */ + + /* nothing to do if the locktokens do not match. */ + if ((*locks_hooks->compare_locktoken)(state_list->locktoken, lock->locktoken)) { + continue; + } + + /* + ** We have now matched up one of the resource's locktokens + ** to a locktoken in a State-token in the If: header. + ** Note this fact, so that we can pass the overall + ** requirement of seeing at least one of the resource's + ** locktokens. + */ + seen_locktoken = 1; + + if (state_list->condition == DAV_IF_COND_NOT) { + /* + ** This state requires that the specified locktoken + ** is NOT present on the resource. But we just found + ** it. There is no way this state-list can now + ** succeed, so go try another one. + */ + reason = + "a State-token was supplied, which used a " + "\"Not\" condition. The State-token was found " + "in the locks on this resource"; + goto state_list_failed; + } + + /* condition == DAV_IF_COND_NORMAL */ + + /* Validate auth_user: If an authenticated user created + ** the lock, only the same user may submit that locktoken + ** to manipulate a resource. + */ + if (lock->auth_user && + (!r->user || + strcmp(lock->auth_user, r->user))) { + const char *errmsg; + + errmsg = apr_pstrcat(p, "User \"", + r->user, + "\" submitted a locktoken created " + "by user \"", + lock->auth_user, "\".", NULL); + return dav_new_error(p, HTTP_FORBIDDEN, 0, errmsg); + } + + /* + ** We just matched a specified State-Token to one of the + ** resource's locktokens. + ** + ** Break out of the lock scan -- we only needed to find + ** one match (actually, there shouldn't be any other + ** matches in the lock list). + */ + num_matched = 1; + break; + } + + if (num_matched == 0 + && state_list->condition == DAV_IF_COND_NORMAL) { + /* + ** We had a NORMAL state, meaning that we should have + ** found the State-Token within the locks on this + ** resource. We didn't, so this state_list must fail. + */ + reason = + "a State-token was supplied, but it was not found " + "in the locks on this resource."; + goto state_list_failed; + } + + break; + + } /* switch */ + } /* foreach ( state_list ) */ + + /* + ** We've checked every state in this state_list and none of them + ** have failed. Since all of them succeeded, then we have a matching + ** state list and we may be done. + ** + ** The next requirement is that we have seen one of the resource's + ** locktokens (if any). If we have, then we can just exit. If we + ** haven't, then we need to keep looking. + */ + if (seen_locktoken) { + /* woo hoo! */ + return NULL; + } + + /* + ** Haven't seen one. Let's break out of the search and just look + ** for a matching locktoken. + */ + break; + + /* + ** This label is used when we detect that a state_list is not + ** going to match this resource. We bust out and try the next + ** state_list. + */ + state_list_failed: + ; + + } /* foreach ( ifhdr_scan ) */ + + /* + ** The above loop exits for one of two reasons: + ** 1) a state_list matched and seen_locktoken is false. + ** 2) all if_header structures were scanned, without (1) occurring + */ + + if (ifhdr_scan == NULL) { + /* + ** We finished the loop without finding any matching state lists. + */ + + /* + ** If none of the state_lists apply to this resource, then we + ** may have succeeded. Note that this scenario implies a + ** tagged-list with no matching state_lists. If the If: header + ** was a no-tag-list, then it would have applied to this resource. + ** + ** S9.4.2 states that when no state_lists apply, then the header + ** should be ignored. + ** + ** If we saw one of the resource's locktokens, then we're done. + ** If we did not see a locktoken, then we fail. + */ + if (num_that_apply == 0) { + if (seen_locktoken) + return NULL; + + /* + ** We may have aborted the scan before seeing the locktoken. + ** Rescan the If: header to see if we can find the locktoken + ** somewhere. + ** + ** Note that seen_locktoken == 0 implies lock_list != NULL + ** which implies locks_hooks != NULL. + */ + if (dav_find_submitted_locktoken(if_header, lock_list, + locks_hooks)) { + /* + ** We found a match! We're set... none of the If: header + ** assertions apply (implicit success), and the If: header + ** specified the locktoken somewhere. We're done. + */ + return NULL; + } + + return dav_new_error(p, HTTP_LOCKED, 0 /* error_id */, + "This resource is locked and the \"If:\" " + "header did not specify one of the " + "locktokens for this resource's lock(s)."); + } + /* else: one or more state_lists were applicable, but failed. */ + + /* + ** If the dummy_header did not match, then they specified an + ** incorrect token in the Lock-Token header. Forget whether the + ** If: statement matched or not... we'll tell them about the + ** bad Lock-Token first. That is considered a 400 (Bad Request). + */ + if (if_header->dummy_header) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "The locktoken specified in the " + "\"Lock-Token:\" header did not specify one " + "of this resource's locktoken(s)."); + } + + if (reason == NULL) { + return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, + "The preconditions specified by the \"If:\" " + "header did not match this resource."); + } + + return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, + apr_psprintf(p, + "The precondition(s) specified by " + "the \"If:\" header did not match " + "this resource. At least one " + "failure is because: %s", reason)); + } + + /* assert seen_locktoken == 0 */ + + /* + ** ifhdr_scan != NULL implies we found a matching state_list. + ** + ** Since we're still here, it also means that we have not yet found + ** one the resource's locktokens in the If: header. + ** + ** Scan all the if_headers and states looking for one of this + ** resource's locktokens. Note that we need to go back and scan them + ** all -- we may have aborted a scan with a failure before we saw a + ** matching token. + ** + ** Note that seen_locktoken == 0 implies lock_list != NULL which implies + ** locks_hooks != NULL. + */ + if (dav_find_submitted_locktoken(if_header, lock_list, locks_hooks)) { + /* + ** We found a match! We're set... we have a matching state list, + ** and the If: header specified the locktoken somewhere. We're done. + */ + return NULL; + } + + /* + ** We had a matching state list, but the user agent did not specify one + ** of this resource's locktokens. Tell them so. + ** + ** Note that we need to special-case the message on whether a "dummy" + ** header exists. If it exists, yet we didn't see a needed locktoken, + ** then that implies the dummy header (Lock-Token header) did NOT + ** specify one of this resource's locktokens. (this implies something + ** in the real If: header matched) + ** + ** We want to note the 400 (Bad Request) in favor of a 423 (Locked). + */ + if (if_header->dummy_header) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "The locktoken specified in the " + "\"Lock-Token:\" header did not specify one " + "of this resource's locktoken(s)."); + } + + return dav_new_error(p, HTTP_LOCKED, 1 /* error_id */, + "This resource is locked and the \"If:\" header " + "did not specify one of the " + "locktokens for this resource's lock(s)."); +} + +/* dav_validate_walker: Walker callback function to validate resource state */ +static dav_error * dav_validate_walker(dav_walk_resource *wres, int calltype) +{ + dav_walker_ctx *ctx = wres->walk_ctx; + dav_error *err; + + if ((err = dav_validate_resource_state(ctx->w.pool, wres->resource, + ctx->w.lockdb, + ctx->if_header, ctx->flags, + &ctx->work_buf, ctx->r)) == NULL) { + /* There was no error, so just bug out. */ + return NULL; + } + + /* + ** If we have a serious server error, or if the request itself failed, + ** then just return error (not a multistatus). + */ + if (ap_is_HTTP_SERVER_ERROR(err->status) + || (*wres->resource->hooks->is_same_resource)(wres->resource, + ctx->w.root)) { + /* ### maybe push a higher-level description? */ + return err; + } + + /* associate the error with the current URI */ + dav_add_response(wres, err->status, NULL); + + return NULL; +} + +/* +** dav_validate_request: Validate if-headers (and check for locks) on: +** (1) r->filename @ depth; +** (2) Parent of r->filename if check_parent == 1 +** +** The check of parent should be done when it is necessary to verify that +** the parent collection will accept a new member (ie current resource +** state is null). +** +** Return OK on successful validation. +** On error, return appropriate HTTP_* code, and log error. If a multi-stat +** error is necessary, response will point to it, else NULL. +*/ +DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, + dav_resource *resource, + int depth, + dav_locktoken *locktoken, + dav_response **response, + int flags, + dav_lockdb *lockdb) +{ + dav_error *err; + int result; + dav_if_header *if_header; + int lock_db_opened_locally = 0; + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + const dav_hooks_repository *repos_hooks = resource->hooks; + dav_buffer work_buf = { 0 }; + dav_response *new_response; + +#if DAV_DEBUG + if (depth && response == NULL) { + /* + ** ### bleck. we can't return errors for other URIs unless we have + ** ### a "response" ptr. + */ + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "DESIGN ERROR: dav_validate_request called " + "with depth>0, but no response ptr."); + } +#endif + + if (response != NULL) + *response = NULL; + + /* Do the standard checks for conditional requests using + * If-..-Since, If-Match etc */ + if ((result = ap_meets_conditions(r)) != OK) { + /* ### fix this up... how? */ + return dav_new_error(r->pool, result, 0, NULL); + } + + /* always parse (and later process) the If: header */ + if ((err = dav_process_if_header(r, &if_header)) != NULL) { + /* ### maybe add higher-level description */ + return err; + } + + /* If a locktoken was specified, create a dummy if_header with which + * to validate resources. In the interim, figure out why DAV uses + * locktokens in an if-header without a Lock-Token header to refresh + * locks, but a Lock-Token header without an if-header to remove them. + */ + if (locktoken != NULL) { + dav_if_header *ifhdr_new; + + ifhdr_new = apr_pcalloc(r->pool, sizeof(*ifhdr_new)); + ifhdr_new->uri = resource->uri; + ifhdr_new->uri_len = strlen(resource->uri); + ifhdr_new->dummy_header = 1; + + ifhdr_new->state = apr_pcalloc(r->pool, sizeof(*ifhdr_new->state)); + ifhdr_new->state->type = dav_if_opaquelock; + ifhdr_new->state->condition = DAV_IF_COND_NORMAL; + ifhdr_new->state->locktoken = locktoken; + + ifhdr_new->next = if_header; + if_header = ifhdr_new; + } + + /* + ** If necessary, open the lock database (read-only, lazily); + ** the validation process may need to retrieve or update lock info. + ** Otherwise, assume provided lockdb is valid and opened rw. + */ + if (lockdb == NULL) { + if (locks_hooks != NULL) { + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, &lockdb)) != NULL) { + /* ### maybe insert higher-level comment */ + return err; + } + lock_db_opened_locally = 1; + } + } + + /* (1) Validate the specified resource, at the specified depth */ + if (resource->exists && depth > 0) { + dav_walker_ctx ctx = { { 0 } }; + dav_response *multi_status; + + ctx.w.walk_type = DAV_WALKTYPE_NORMAL; + ctx.w.func = dav_validate_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = resource; + + ctx.if_header = if_header; + ctx.r = r; + ctx.flags = flags; + + if (lockdb != NULL) { + ctx.w.lockdb = lockdb; + ctx.w.walk_type |= DAV_WALKTYPE_LOCKNULL; + } + + err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status); + if (err == NULL) { + *response = multi_status;; + } + /* else: implies a 5xx status code occurred. */ + } + else { + err = dav_validate_resource_state(r->pool, resource, lockdb, + if_header, flags, &work_buf, r); + } + + /* (2) Validate the parent resource if requested */ + if (err == NULL && (flags & DAV_VALIDATE_PARENT)) { + dav_resource *parent_resource; + + err = (*repos_hooks->get_parent_resource)(resource, &parent_resource); + + if (err == NULL && parent_resource == NULL) { + err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0, + "Cannot access parent of repository root."); + } + else if (err == NULL) { + err = dav_validate_resource_state(r->pool, parent_resource, lockdb, + if_header, + flags | DAV_VALIDATE_IS_PARENT, + &work_buf, r); + + /* + ** This error occurred on the parent resource. This implies that + ** we have to create a multistatus response (to report the error + ** against a URI other than the Request-URI). "Convert" this error + ** into a multistatus response. + */ + if (err != NULL) { + new_response = apr_pcalloc(r->pool, sizeof(*new_response)); + + new_response->href = parent_resource->uri; + new_response->status = err->status; + new_response->desc = + "A validation error has occurred on the parent resource, " + "preventing the operation on the resource specified by " + "the Request-URI."; + if (err->desc != NULL) { + new_response->desc = apr_pstrcat(r->pool, + new_response->desc, + " The error was: ", + err->desc, NULL); + } + + /* assert: DAV_VALIDATE_PARENT implies response != NULL */ + new_response->next = *response; + *response = new_response; + + err = NULL; + } + } + } + + if (lock_db_opened_locally) + (*locks_hooks->close_lockdb)(lockdb); + + /* + ** If we don't have a (serious) error, and we have multistatus responses, + ** then we need to construct an "error". This error will be the overall + ** status returned, and the multistatus responses will go into its body. + ** + ** For certain methods, the overall error will be a 424. The default is + ** to construct a standard 207 response. + */ + if (err == NULL && response != NULL && *response != NULL) { + apr_text *propstat = NULL; + + if ((flags & DAV_VALIDATE_USE_424) != 0) { + /* manufacture a 424 error to hold the multistatus response(s) */ + return dav_new_error(r->pool, HTTP_FAILED_DEPENDENCY, 0, + "An error occurred on another resource, " + "preventing the requested operation on " + "this resource."); + } + + /* + ** Whatever caused the error, the Request-URI should have a 424 + ** associated with it since we cannot complete the method. + ** + ** For a LOCK operation, insert an empty DAV:lockdiscovery property. + ** For other methods, return a simple 424. + */ + if ((flags & DAV_VALIDATE_ADD_LD) != 0) { + propstat = apr_pcalloc(r->pool, sizeof(*propstat)); + propstat->text = + "" DEBUG_CR + "" DEBUG_CR + "HTTP/1.1 424 Failed Dependency" DEBUG_CR + "" DEBUG_CR; + } + + /* create the 424 response */ + new_response = apr_pcalloc(r->pool, sizeof(*new_response)); + new_response->href = resource->uri; + new_response->status = HTTP_FAILED_DEPENDENCY; + new_response->propresult.propstats = propstat; + new_response->desc = + "An error occurred on another resource, preventing the " + "requested operation on this resource."; + + new_response->next = *response; + *response = new_response; + + /* manufacture a 207 error for the multistatus response(s) */ + return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, + "Error(s) occurred on resources during the " + "validation process."); + } + + return err; +} + +/* dav_get_locktoken_list: + * + * Sets ltl to a locktoken_list of all positive locktokens in header, + * else NULL if no If-header, or no positive locktokens. + */ +DAV_DECLARE(dav_error *) dav_get_locktoken_list(request_rec *r, + dav_locktoken_list **ltl) +{ + dav_error *err; + dav_if_header *if_header; + dav_if_state_list *if_state; + dav_locktoken_list *lock_token = NULL; + + *ltl = NULL; + + if ((err = dav_process_if_header(r, &if_header)) != NULL) { + /* ### add a higher-level description? */ + return err; + } + + while (if_header != NULL) { + if_state = if_header->state; /* Begining of the if_state linked list */ + while (if_state != NULL) { + if (if_state->condition == DAV_IF_COND_NORMAL + && if_state->type == dav_if_opaquelock) { + lock_token = apr_pcalloc(r->pool, sizeof(dav_locktoken_list)); + lock_token->locktoken = if_state->locktoken; + lock_token->next = *ltl; + *ltl = lock_token; + } + if_state = if_state->next; + } + if_header = if_header->next; + } + if (*ltl == NULL) { + /* No nodes added */ + return dav_new_error(r->pool, HTTP_BAD_REQUEST, DAV_ERR_IF_ABSENT, + "No locktokens were specified in the \"If:\" " + "header, so the refresh could not be performed."); + } + + return NULL; +} + +#if 0 /* not needed right now... */ + +static const char *strip_white(const char *s, apr_pool_t *pool) +{ + apr_size_t idx; + + /* trim leading whitespace */ + while (apr_isspace(*s)) /* assume: return false for '\0' */ + ++s; + + /* trim trailing whitespace */ + idx = strlen(s) - 1; + if (apr_isspace(s[idx])) { + char *s2 = apr_pstrdup(pool, s); + + while (apr_isspace(s2[idx]) && idx > 0) + --idx; + s2[idx + 1] = '\0'; + return s2; + } + + return s; +} +#endif + +#define DAV_LABEL_HDR "Label" + +/* dav_add_vary_header + * + * If there were any headers in the request which require a Vary header + * in the response, add it. + */ +DAV_DECLARE(void) dav_add_vary_header(request_rec *in_req, + request_rec *out_req, + const dav_resource *resource) +{ + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(in_req); + + /* ### this is probably all wrong... I think there is a function in + ### the Apache API to add things to the Vary header. need to check */ + + /* Only versioning headers require a Vary response header, + * so only do this check if there is a versioning provider */ + if (vsn_hooks != NULL) { + const char *target = apr_table_get(in_req->headers_in, DAV_LABEL_HDR); + const char *vary = apr_table_get(out_req->headers_out, "Vary"); + + /* If Target-Selector specified, add it to the Vary header */ + if (target != NULL) { + if (vary == NULL) + vary = DAV_LABEL_HDR; + else + vary = apr_pstrcat(out_req->pool, vary, "," DAV_LABEL_HDR, + NULL); + + apr_table_setn(out_req->headers_out, "Vary", vary); + } + } +} + +/* dav_can_auto_checkout + * + * Determine whether auto-checkout is enabled for a resource. + * r - the request_rec + * resource - the resource + * auto_version - the value of the auto_versionable hook for the resource + * lockdb - pointer to lock database (opened if necessary) + * auto_checkout - set to 1 if auto-checkout enabled + */ +static dav_error * dav_can_auto_checkout( + request_rec *r, + dav_resource *resource, + dav_auto_version auto_version, + dav_lockdb **lockdb, + int *auto_checkout) +{ + dav_error *err; + dav_lock *lock_list; + + *auto_checkout = 0; + + if (auto_version == DAV_AUTO_VERSION_ALWAYS) { + *auto_checkout = 1; + } + else if (auto_version == DAV_AUTO_VERSION_LOCKED) { + if (*lockdb == NULL) { + const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); + + if (locks_hooks == NULL) { + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "Auto-checkout is only enabled for locked resources, " + "but there is no lock provider."); + } + + if ((err = (*locks_hooks->open_lockdb)(r, 0, 0, lockdb)) != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "Cannot open lock database to determine " + "auto-versioning behavior.", + err); + } + } + + if ((err = dav_lock_query(*lockdb, resource, &lock_list)) != NULL) { + return dav_push_error(r->pool, + HTTP_INTERNAL_SERVER_ERROR, 0, + "The locks could not be queried for " + "determining auto-versioning behavior.", + err); + } + + if (lock_list != NULL) + *auto_checkout = 1; + } + + return NULL; +} + +/* see mod_dav.h for docco */ +DAV_DECLARE(dav_error *) dav_auto_checkout( + request_rec *r, + dav_resource *resource, + int parent_only, + dav_auto_version_info *av_info) +{ + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_lockdb *lockdb = NULL; + dav_error *err = NULL; + + /* Initialize results */ + memset(av_info, 0, sizeof(*av_info)); + + /* if no versioning provider, just return */ + if (vsn_hooks == NULL) + return NULL; + + /* check parent resource if requested or if resource must be created */ + if (!resource->exists || parent_only) { + dav_resource *parent; + + if ((err = (*resource->hooks->get_parent_resource)(resource, + &parent)) != NULL) + goto done; + + if (parent == NULL || !parent->exists) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Missing one or more intermediate " + "collections. Cannot create resource %s.", + ap_escape_html(r->pool, resource->uri))); + goto done; + } + + av_info->parent_resource = parent; + + /* if parent versioned and not checked out, see if it can be */ + if (parent->versioned && !parent->working) { + int checkout_parent; + + if ((err = dav_can_auto_checkout(r, parent, + (*vsn_hooks->auto_versionable)(parent), + &lockdb, &checkout_parent)) + != NULL) { + goto done; + } + + if (!checkout_parent) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + goto done; + } + + /* Try to checkout the parent collection. + * Note that auto-versioning can only be applied to a version selector, + * so no separate working resource will be created. + */ + if ((err = (*vsn_hooks->checkout)(parent, 1 /*auto_checkout*/, + 0, 0, 0, NULL, NULL)) + != NULL) + { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Unable to auto-checkout parent collection. " + "Cannot create resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + goto done; + } + + /* remember that parent was checked out */ + av_info->parent_checkedout = 1; + } + } + + /* if only checking parent, we're done */ + if (parent_only) + goto done; + + /* if creating a new resource, see if it should be version-controlled */ + if (!resource->exists + && (*vsn_hooks->auto_versionable)(resource) == DAV_AUTO_VERSION_ALWAYS) { + + if ((err = (*vsn_hooks->vsn_control)(resource, NULL)) != NULL) { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Unable to create versioned resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + goto done; + } + + /* remember that resource was created */ + av_info->resource_versioned = 1; + } + + /* if resource is versioned, make sure it is checked out */ + if (resource->versioned && !resource->working) { + int checkout_resource; + + if ((err = dav_can_auto_checkout(r, resource, + (*vsn_hooks->auto_versionable)(resource), + &lockdb, &checkout_resource)) != NULL) { + goto done; + } + + if (!checkout_resource) { + err = dav_new_error(r->pool, HTTP_CONFLICT, 0, + ""); + goto done; + } + + /* Auto-versioning can only be applied to version selectors, so + * no separate working resource will be created. */ + if ((err = (*vsn_hooks->checkout)(resource, 1 /*auto_checkout*/, + 0, 0, 0, NULL, NULL)) + != NULL) + { + err = dav_push_error(r->pool, HTTP_CONFLICT, 0, + apr_psprintf(r->pool, + "Unable to checkout resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + goto done; + } + + /* remember that resource was checked out */ + av_info->resource_checkedout = 1; + } + +done: + + /* make sure lock database is closed */ + if (lockdb != NULL) + (*lockdb->hooks->close_lockdb)(lockdb); + + /* if an error occurred, undo any auto-versioning operations already done */ + if (err != NULL) { + dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, av_info); + return err; + } + + return NULL; +} + +/* see mod_dav.h for docco */ +DAV_DECLARE(dav_error *) dav_auto_checkin( + request_rec *r, + dav_resource *resource, + int undo, + int unlock, + dav_auto_version_info *av_info) +{ + const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); + dav_error *err = NULL; + dav_auto_version auto_version; + + /* If no versioning provider, this is a no-op */ + if (vsn_hooks == NULL) + return NULL; + + /* If undoing auto-checkouts, then do uncheckouts */ + if (undo) { + if (resource != NULL) { + if (av_info->resource_checkedout) { + if ((err = (*vsn_hooks->uncheckout)(resource)) != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Unable to undo auto-checkout " + "of resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + } + } + + if (av_info->resource_versioned) { + dav_response *response; + + /* ### should we do anything with the response? */ + if ((err = (*resource->hooks->remove_resource)(resource, + &response)) != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Unable to undo auto-version-control " + "of resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + } + } + } + + if (av_info->parent_resource != NULL && av_info->parent_checkedout) { + if ((err = (*vsn_hooks->uncheckout)(av_info->parent_resource)) != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Unable to undo auto-checkout " + "of parent collection %s.", + ap_escape_html(r->pool, av_info->parent_resource->uri)), + err); + } + } + + return NULL; + } + + /* If the resource was checked out, and auto-checkin is enabled, + * then check it in. + */ + if (resource != NULL && resource->working + && (unlock || av_info->resource_checkedout)) { + + auto_version = (*vsn_hooks->auto_versionable)(resource); + + if (auto_version == DAV_AUTO_VERSION_ALWAYS || + (unlock && (auto_version == DAV_AUTO_VERSION_LOCKED))) { + + if ((err = (*vsn_hooks->checkin)(resource, + 0 /*keep_checked_out*/, NULL)) + != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Unable to auto-checkin resource %s.", + ap_escape_html(r->pool, resource->uri)), + err); + } + } + } + + /* If parent resource was checked out, and auto-checkin is enabled, + * then check it in. + */ + if (!unlock + && av_info->parent_checkedout + && av_info->parent_resource != NULL + && av_info->parent_resource->working) { + + auto_version = (*vsn_hooks->auto_versionable)(av_info->parent_resource); + + if (auto_version == DAV_AUTO_VERSION_ALWAYS) { + if ((err = (*vsn_hooks->checkin)(av_info->parent_resource, + 0 /*keep_checked_out*/, NULL)) + != NULL) { + return dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + apr_psprintf(r->pool, + "Unable to auto-checkin parent collection %s.", + ap_escape_html(r->pool, av_info->parent_resource->uri)), + err); + } + } + } + + return NULL; +} diff --git a/trunk/modules/dav/main/util_lock.c b/trunk/modules/dav/main/util_lock.c new file mode 100644 index 0000000000..cf960efbe3 --- /dev/null +++ b/trunk/modules/dav/main/util_lock.c @@ -0,0 +1,791 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +** DAV repository-independent lock functions +*/ + +#include "apr.h" +#include "apr_strings.h" + +#if APR_HAVE_STDIO_H +#include /* for sprintf() */ +#endif + +#include "mod_dav.h" +#include "http_log.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_core.h" + + +/* --------------------------------------------------------------- +** +** Property-related lock functions +** +*/ + +/* +** dav_lock_get_activelock: Returns a containing +** an activelock element for every item in the lock_discovery tree +*/ +DAV_DECLARE(const char *) dav_lock_get_activelock(request_rec *r, + dav_lock *lock, + dav_buffer *pbuf) +{ + dav_lock *lock_scan; + const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); + int count = 0; + dav_buffer work_buf = { 0 }; + apr_pool_t *p = r->pool; + + /* If no locks or no lock provider, there are no locks */ + if (lock == NULL || hooks == NULL) { + /* + ** Since resourcediscovery is defined with (activelock)*, + ** shouldn't be necessary for an empty lock. + */ + return ""; + } + + /* + ** Note: it could be interesting to sum the lengths of the owners + ** and locktokens during this loop. However, the buffer + ** mechanism provides some rough padding so that we don't + ** really need to have an exact size. Further, constructing + ** locktoken strings could be relatively expensive. + */ + for (lock_scan = lock; lock_scan != NULL; lock_scan = lock_scan->next) + count++; + + /* if a buffer was not provided, then use an internal buffer */ + if (pbuf == NULL) + pbuf = &work_buf; + + /* reset the length before we start appending stuff */ + pbuf->cur_len = 0; + + /* prep the buffer with a "good" size */ + dav_check_bufsize(p, pbuf, count * 300); + + for (; lock != NULL; lock = lock->next) { + char tmp[100]; + +#if DAV_DEBUG + if (lock->rectype == DAV_LOCKREC_INDIRECT_PARTIAL) { + /* ### crap. design error */ + dav_buffer_append(p, pbuf, + "DESIGN ERROR: attempted to product an " + "activelock element from a partial, indirect " + "lock record. Creating an XML parsing error " + "to ease detection of this situation: <"); + } +#endif + + dav_buffer_append(p, pbuf, "" DEBUG_CR ""); + switch (lock->type) { + case DAV_LOCKTYPE_WRITE: + dav_buffer_append(p, pbuf, ""); + break; + default: + /* ### internal error. log something? */ + break; + } + dav_buffer_append(p, pbuf, "" DEBUG_CR ""); + switch (lock->scope) { + case DAV_LOCKSCOPE_EXCLUSIVE: + dav_buffer_append(p, pbuf, ""); + break; + case DAV_LOCKSCOPE_SHARED: + dav_buffer_append(p, pbuf, ""); + break; + default: + /* ### internal error. log something? */ + break; + } + dav_buffer_append(p, pbuf, "" DEBUG_CR); + sprintf(tmp, "%s" DEBUG_CR, + lock->depth == DAV_INFINITY ? "infinity" : "0"); + dav_buffer_append(p, pbuf, tmp); + + if (lock->owner) { + /* + ** This contains a complete, self-contained element, + ** with namespace declarations and xml:lang handling. Just drop + ** it in. + */ + dav_buffer_append(p, pbuf, lock->owner); + } + + dav_buffer_append(p, pbuf, ""); + if (lock->timeout == DAV_TIMEOUT_INFINITE) { + dav_buffer_append(p, pbuf, "Infinite"); + } + else { + time_t now = time(NULL); + sprintf(tmp, "Second-%lu", (long unsigned int)(lock->timeout - now)); + dav_buffer_append(p, pbuf, tmp); + } + + dav_buffer_append(p, pbuf, + "" DEBUG_CR + "" DEBUG_CR + ""); + dav_buffer_append(p, pbuf, + (*hooks->format_locktoken)(p, lock->locktoken)); + dav_buffer_append(p, pbuf, + "" DEBUG_CR + "" DEBUG_CR + "" DEBUG_CR); + } + + return pbuf->buf; +} + +/* +** dav_lock_parse_lockinfo: Validates the given xml_doc to contain a +** lockinfo XML element, then populates a dav_lock structure +** with its contents. +*/ +DAV_DECLARE(dav_error *) dav_lock_parse_lockinfo(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, + const apr_xml_doc *doc, + dav_lock **lock_request) +{ + apr_pool_t *p = r->pool; + dav_error *err; + apr_xml_elem *child; + dav_lock *lock; + + if (!dav_validate_root(doc, "lockinfo")) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "The request body contains an unexpected " + "XML root element."); + } + + if ((err = (*lockdb->hooks->create_lock)(lockdb, resource, + &lock)) != NULL) { + return dav_push_error(p, err->status, 0, + "Could not parse the lockinfo due to an " + "internal problem creating a lock structure.", + err); + } + + lock->depth = dav_get_depth(r, DAV_INFINITY); + if (lock->depth == -1) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "An invalid Depth header was specified."); + } + lock->timeout = dav_get_timeout(r); + + /* Parse elements in the XML body */ + for (child = doc->root->first_child; child; child = child->next) { + if (strcmp(child->name, "locktype") == 0 + && child->first_child + && lock->type == DAV_LOCKTYPE_UNKNOWN) { + if (strcmp(child->first_child->name, "write") == 0) { + lock->type = DAV_LOCKTYPE_WRITE; + continue; + } + } + if (strcmp(child->name, "lockscope") == 0 + && child->first_child + && lock->scope == DAV_LOCKSCOPE_UNKNOWN) { + if (strcmp(child->first_child->name, "exclusive") == 0) + lock->scope = DAV_LOCKSCOPE_EXCLUSIVE; + else if (strcmp(child->first_child->name, "shared") == 0) + lock->scope = DAV_LOCKSCOPE_SHARED; + if (lock->scope != DAV_LOCKSCOPE_UNKNOWN) + continue; + } + + if (strcmp(child->name, "owner") == 0 && lock->owner == NULL) { + const char *text; + + /* quote all the values in the element */ + apr_xml_quote_elem(p, child); + + /* + ** Store a full element with namespace definitions + ** and an xml:lang definition, if applicable. + */ + apr_xml_to_text(p, child, APR_XML_X2T_FULL_NS_LANG, doc->namespaces, + NULL, &text, NULL); + lock->owner = text; + + continue; + } + + return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, + apr_psprintf(p, + "The server cannot satisfy the " + "LOCK request due to an unknown XML " + "element (\"%s\") within the " + "DAV:lockinfo element.", + child->name)); + } + + *lock_request = lock; + return NULL; +} + +/* --------------------------------------------------------------- +** +** General lock functions +** +*/ + +/* dav_lock_walker: Walker callback function to record indirect locks */ +static dav_error * dav_lock_walker(dav_walk_resource *wres, int calltype) +{ + dav_walker_ctx *ctx = wres->walk_ctx; + dav_error *err; + + /* We don't want to set indirects on the target */ + if ((*wres->resource->hooks->is_same_resource)(wres->resource, + ctx->w.root)) + return NULL; + + if ((err = (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb, + wres->resource, 1, + ctx->lock)) != NULL) { + if (ap_is_HTTP_SERVER_ERROR(err->status)) { + /* ### add a higher-level description? */ + return err; + } + + /* add to the multistatus response */ + dav_add_response(wres, err->status, NULL); + + /* + ** ### actually, this is probably wrong: we want to fail the whole + ** ### LOCK process if something goes bad. maybe the caller should + ** ### do a dav_unlock() (e.g. a rollback) if any errors occurred. + */ + } + + return NULL; +} + +/* +** dav_add_lock: Add a direct lock for resource, and indirect locks for +** all children, bounded by depth. +** ### assume request only contains one lock +*/ +DAV_DECLARE(dav_error *) dav_add_lock(request_rec *r, + const dav_resource *resource, + dav_lockdb *lockdb, dav_lock *lock, + dav_response **response) +{ + dav_error *err; + int depth = lock->depth; + + *response = NULL; + + /* Requested lock can be: + * Depth: 0 for null resource, existing resource, or existing collection + * Depth: Inf for existing collection + */ + + /* + ** 2518 9.2 says to ignore depth if target is not a collection (it has + ** no internal children); pretend the client gave the correct depth. + */ + if (!resource->collection) { + depth = 0; + } + + /* In all cases, first add direct entry in lockdb */ + + /* + ** Append the new (direct) lock to the resource's existing locks. + ** + ** Note: this also handles locknull resources + */ + if ((err = (*lockdb->hooks->append_locks)(lockdb, resource, 0, + lock)) != NULL) { + /* ### maybe add a higher-level description */ + return err; + } + + if (depth > 0) { + /* Walk existing collection and set indirect locks */ + dav_walker_ctx ctx = { { 0 } }; + dav_response *multi_status; + + ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH; + ctx.w.func = dav_lock_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = resource; + ctx.w.lockdb = lockdb; + + ctx.r = r; + ctx.lock = lock; + + err = (*resource->hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status); + if (err != NULL) { + /* implies a 5xx status code occurred. screw the multistatus */ + return err; + } + + if (multi_status != NULL) { + /* manufacture a 207 error for the multistatus response */ + *response = multi_status; + return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, + "Error(s) occurred on resources during the " + "addition of a depth lock."); + } + } + + return NULL; +} + +/* +** dav_lock_query: Opens the lock database. Returns a linked list of +** dav_lock structures for all direct locks on path. +*/ +DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, + const dav_resource *resource, + dav_lock **locks) +{ + /* If no lock database, return empty result */ + if (lockdb == NULL) { + *locks = NULL; + return NULL; + } + + /* ### insert a higher-level description? */ + return (*lockdb->hooks->get_locks)(lockdb, resource, + DAV_GETLOCKS_RESOLVED, + locks); +} + +/* dav_unlock_walker: Walker callback function to remove indirect locks */ +static dav_error * dav_unlock_walker(dav_walk_resource *wres, int calltype) +{ + dav_walker_ctx *ctx = wres->walk_ctx; + dav_error *err; + + /* Before removing the lock, do any auto-checkin required */ + if (wres->resource->working) { + /* ### get rid of this typecast */ + if ((err = dav_auto_checkin(ctx->r, (dav_resource *) wres->resource, + 0 /*undo*/, 1 /*unlock*/, NULL)) + != NULL) { + return err; + } + } + + if ((err = (*ctx->w.lockdb->hooks->remove_lock)(ctx->w.lockdb, + wres->resource, + ctx->locktoken)) != NULL) { + /* ### should we stop or return a multistatus? looks like STOP */ + /* ### add a higher-level description? */ + return err; + } + + return NULL; +} + +/* +** dav_get_direct_resource: +** +** Find a lock on the specified resource, then return the resource the +** lock was applied to (in other words, given a (possibly) indirect lock, +** return the direct lock's corresponding resource). +** +** If the lock is an indirect lock, this usually means traversing up the +** namespace [repository] hierarchy. Note that some lock providers may be +** able to return this information with a traversal. +*/ +static dav_error * dav_get_direct_resource(apr_pool_t *p, + dav_lockdb *lockdb, + const dav_locktoken *locktoken, + const dav_resource *resource, + const dav_resource **direct_resource) +{ + if (lockdb->hooks->lookup_resource != NULL) { + return (*lockdb->hooks->lookup_resource)(lockdb, locktoken, + resource, direct_resource); + } + + *direct_resource = NULL; + + /* Find the top of this lock- + * If r->filename's direct locks include locktoken, use r->filename. + * If r->filename's indirect locks include locktoken, retry r->filename/.. + * Else fail. + */ + while (resource != NULL) { + dav_error *err; + dav_lock *lock; + dav_resource *parent; + + /* + ** Find the lock specified by on . If it is + ** an indirect lock, then partial results are okay. We're just + ** trying to find the thing and know whether it is a direct or + ** an indirect lock. + */ + if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken, + 1, &lock)) != NULL) { + /* ### add a higher-level desc? */ + return err; + } + + /* not found! that's an error. */ + if (lock == NULL) { + return dav_new_error(p, HTTP_BAD_REQUEST, 0, + "The specified locktoken does not correspond " + "to an existing lock on this resource."); + } + + if (lock->rectype == DAV_LOCKREC_DIRECT) { + /* we found the direct lock. return this resource. */ + + *direct_resource = resource; + return NULL; + } + + /* the lock was indirect. move up a level in the URL namespace */ + if ((err = (*resource->hooks->get_parent_resource)(resource, + &parent)) != NULL) { + /* ### add a higher-level desc? */ + return err; + } + resource = parent; + } + + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, + "The lock database is corrupt. A direct lock could " + "not be found for the corresponding indirect lock " + "on this resource."); +} + +/* +** dav_unlock: Removes all direct and indirect locks for r->filename, +** with given locktoken. If locktoken == null_locktoken, all locks +** are removed. If r->filename represents an indirect lock, +** we must unlock the appropriate direct lock. +** Returns OK or appropriate HTTP_* response and logs any errors. +** +** ### We've already crawled the tree to ensure everything was locked +** by us; there should be no need to incorporate a rollback. +*/ +DAV_DECLARE(int) dav_unlock(request_rec *r, const dav_resource *resource, + const dav_locktoken *locktoken) +{ + int result; + dav_lockdb *lockdb; + const dav_resource *lock_resource = resource; + const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); + const dav_hooks_repository *repos_hooks = resource->hooks; + dav_walker_ctx ctx = { { 0 } }; + dav_response *multi_status; + dav_error *err; + + /* If no locks provider, then there is nothing to unlock. */ + if (hooks == NULL) { + return OK; + } + + /* 2518 requires the entire lock to be removed if resource/locktoken + * point to an indirect lock. We need resource of the _direct_ + * lock in order to walk down the tree and remove the locks. So, + * If locktoken != null_locktoken, + * Walk up the resource hierarchy until we see a direct lock. + * Or, we could get the direct lock's db/key, pick out the URL + * and do a subrequest. I think walking up is faster and will work + * all the time. + * Else + * Just start removing all locks at and below resource. + */ + + if ((err = (*hooks->open_lockdb)(r, 0, 1, &lockdb)) != NULL) { + /* ### return err! maybe add a higher-level desc */ + /* ### map result to something nice; log an error */ + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (locktoken != NULL + && (err = dav_get_direct_resource(r->pool, lockdb, + locktoken, resource, + &lock_resource)) != NULL) { + /* ### add a higher-level desc? */ + /* ### should return err! */ + return err->status; + } + + /* At this point, lock_resource/locktoken refers to a direct lock (key), ie + * the root of a depth > 0 lock, or locktoken is null. + */ + ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL; + ctx.w.func = dav_unlock_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = lock_resource; + ctx.w.lockdb = lockdb; + + ctx.r = r; + ctx.locktoken = locktoken; + + err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status); + + /* ### fix this! */ + /* ### do something with multi_status */ + result = err == NULL ? OK : err->status; + + (*hooks->close_lockdb)(lockdb); + + return result; +} + +/* dav_inherit_walker: Walker callback function to inherit locks */ +static dav_error * dav_inherit_walker(dav_walk_resource *wres, int calltype) +{ + dav_walker_ctx *ctx = wres->walk_ctx; + + if (ctx->skip_root + && (*wres->resource->hooks->is_same_resource)(wres->resource, + ctx->w.root)) { + return NULL; + } + + /* ### maybe add a higher-level desc */ + return (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb, + wres->resource, 1, + ctx->lock); +} + +/* +** dav_inherit_locks: When a resource or collection is added to a collection, +** locks on the collection should be inherited to the resource/collection. +** (MOVE, MKCOL, etc) Here we propagate any direct or indirect locks from +** parent of resource to resource and below. +*/ +static dav_error * dav_inherit_locks(request_rec *r, dav_lockdb *lockdb, + const dav_resource *resource, + int use_parent) +{ + dav_error *err; + const dav_resource *which_resource; + dav_lock *locks; + dav_lock *scan; + dav_lock *prev; + dav_walker_ctx ctx = { { 0 } }; + const dav_hooks_repository *repos_hooks = resource->hooks; + dav_response *multi_status; + + if (use_parent) { + dav_resource *parent; + if ((err = (*repos_hooks->get_parent_resource)(resource, + &parent)) != NULL) { + /* ### add a higher-level desc? */ + return err; + } + if (parent == NULL) { + /* ### map result to something nice; log an error */ + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, + "Could not fetch parent resource. Unable to " + "inherit locks from the parent and apply " + "them to this resource."); + } + which_resource = parent; + } + else { + which_resource = resource; + } + + if ((err = (*lockdb->hooks->get_locks)(lockdb, which_resource, + DAV_GETLOCKS_PARTIAL, + &locks)) != NULL) { + /* ### maybe add a higher-level desc */ + return err; + } + + if (locks == NULL) { + /* No locks to propagate, just return */ + return NULL; + } + + /* + ** (1) Copy all indirect locks from our parent; + ** (2) Create indirect locks for the depth infinity, direct locks + ** in our parent. + ** + ** The append_locks call in the walker callback will do the indirect + ** conversion, but we need to remove any direct locks that are NOT + ** depth "infinity". + */ + for (scan = locks, prev = NULL; + scan != NULL; + prev = scan, scan = scan->next) { + + if (scan->rectype == DAV_LOCKREC_DIRECT + && scan->depth != DAV_INFINITY) { + + if (prev == NULL) + locks = scan->next; + else + prev->next = scan->next; + } + } + + /* has all our new locks. Walk down and propagate them. */ + + ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL; + ctx.w.func = dav_inherit_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; + ctx.w.root = resource; + ctx.w.lockdb = lockdb; + + ctx.r = r; + ctx.lock = locks; + ctx.skip_root = !use_parent; + + /* ### do something with multi_status */ + return (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status); +} + +/* --------------------------------------------------------------- +** +** Functions dealing with lock-null resources +** +*/ + +/* +** dav_get_resource_state: Returns the state of the resource +** r->filename: DAV_RESOURCE_NULL, DAV_RESOURCE_LOCK_NULL, +** or DAV_RESOURCE_EXIST. +** +** Returns DAV_RESOURCE_ERROR if an error occurs. +*/ +DAV_DECLARE(int) dav_get_resource_state(request_rec *r, + const dav_resource *resource) +{ + const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r); + + if (resource->exists) + return DAV_RESOURCE_EXISTS; + + if (hooks != NULL) { + dav_error *err; + dav_lockdb *lockdb; + int locks_present; + + /* + ** A locknull resource has the form: + ** + ** known-dir "/" locknull-file + ** + ** It would be nice to look into to verify this form, + ** but it does not have enough information for us. Instead, we + ** can look at the path_info. If the form does not match, then + ** there is no way we could have a locknull resource -- it must + ** be a plain, null resource. + ** + ** Apache sets r->filename to known-dir/unknown-file and r->path_info + ** to "" for the "proper" case. If anything is in path_info, then + ** it can't be a locknull resource. + ** + ** ### I bet this path_info hack doesn't work for repositories. + ** ### Need input from repository implementors! What kind of + ** ### restructure do we need? New provider APIs? + */ + if (r->path_info != NULL && *r->path_info != '\0') { + return DAV_RESOURCE_NULL; + } + + if ((err = (*hooks->open_lockdb)(r, 1, 1, &lockdb)) == NULL) { + /* note that we might see some expired locks... *shrug* */ + err = (*hooks->has_locks)(lockdb, resource, &locks_present); + (*hooks->close_lockdb)(lockdb); + } + + if (err != NULL) { + /* ### don't log an error. return err. add higher-level desc. */ + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Failed to query lock-null status for %s", + r->filename); + + return DAV_RESOURCE_ERROR; + } + + if (locks_present) + return DAV_RESOURCE_LOCK_NULL; + } + + return DAV_RESOURCE_NULL; +} + +DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r, + dav_lockdb *lockdb, + const dav_resource *resource, + int resource_state, + int depth) +{ + dav_error *err; + + if (resource_state == DAV_RESOURCE_LOCK_NULL) { + + /* + ** The resource is no longer a locknull resource. This will remove + ** the special marker. + ** + ** Note that a locknull resource has already inherited all of the + ** locks from the parent. We do not need to call dav_inherit_locks. + ** + ** NOTE: some lock providers record locks for locknull resources using + ** a different key than for regular resources. this will shift + ** the lock information between the two key types. + */ + (void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource); + + /* + ** There are resources under this one, which are new. We must + ** propagate the locks down to the new resources. + */ + if (depth > 0 && + (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) { + /* ### add a higher level desc? */ + return err; + } + } + else if (resource_state == DAV_RESOURCE_NULL) { + + /* ### should pass depth to dav_inherit_locks so that it can + ** ### optimize for the depth==0 case. + */ + + /* this resource should inherit locks from its parent */ + if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) { + + err = dav_push_error(r->pool, err->status, 0, + "The resource was created successfully, but " + "there was a problem inheriting locks from " + "the parent resource.", + err); + return err; + } + } + /* else the resource already exists and its locks are correct. */ + + return NULL; +} diff --git a/trunk/modules/debug/Makefile.in b/trunk/modules/debug/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/debug/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/debug/NWGNUmakefile b/trunk/modules/debug/NWGNUmakefile new file mode 100644 index 0000000000..7e3e148601 --- /dev/null +++ b/trunk/modules/debug/NWGNUmakefile @@ -0,0 +1,246 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/moddumpio.nlm \ + $(OBJDIR)/modbucketeer.nlm \ + $(EOLIST) + + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/debug/NWGNUmodbucketeer b/trunk/modules/debug/NWGNUmodbucketeer new file mode 100644 index 0000000000..1c14170ad5 --- /dev/null +++ b/trunk/modules/debug/NWGNUmodbucketeer @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = modbucketeer + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Debugging IO Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Bucketeer Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/modbucketeer.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_bucketeer.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + bucketeer_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/debug/NWGNUmoddumpio b/trunk/modules/debug/NWGNUmoddumpio new file mode 100644 index 0000000000..7db7075d1e --- /dev/null +++ b/trunk/modules/debug/NWGNUmoddumpio @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = moddumpio + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Debugging IO Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = DumpIO Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/moddumpio.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_dumpio.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + dumpio_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/debug/README b/trunk/modules/debug/README new file mode 100644 index 0000000000..df71d0740d --- /dev/null +++ b/trunk/modules/debug/README @@ -0,0 +1 @@ +debugging modules for Apache 2.x diff --git a/trunk/modules/debug/config.m4 b/trunk/modules/debug/config.m4 new file mode 100644 index 0000000000..2d2afdfd7b --- /dev/null +++ b/trunk/modules/debug/config.m4 @@ -0,0 +1,7 @@ + +APACHE_MODPATH_INIT(debug) + +APACHE_MODULE(bucketeer, buckets manipulation filter, , , no) +APACHE_MODULE(dumpio, I/O dump filter, , , most) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/debug/mod_bucketeer.c b/trunk/modules/debug/mod_bucketeer.c new file mode 100644 index 0000000000..215617e6bf --- /dev/null +++ b/trunk/modules/debug/mod_bucketeer.c @@ -0,0 +1,184 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_bucketeer.c: split buckets whenever we find a control-char + * + * Written by Ian Holsman + * + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "apr_strings.h" +#include "apr_general.h" +#include "util_filter.h" +#include "apr_buckets.h" +#include "http_request.h" +#include "http_protocol.h" + +static const char bucketeerFilterName[] = "BUCKETEER"; +module AP_MODULE_DECLARE_DATA bucketeer_module; + +typedef struct bucketeer_filter_config_t +{ + char bucketdelimiter; + char passdelimiter; + char flushdelimiter; +} bucketeer_filter_config_t; + + +static void *create_bucketeer_server_config(apr_pool_t *p, server_rec *s) +{ + bucketeer_filter_config_t *c = apr_pcalloc(p, sizeof *c); + + c->bucketdelimiter = 0x02; /* ^B */ + c->passdelimiter = 0x10; /* ^P */ + c->flushdelimiter = 0x06; /* ^F */ + + return c; +} + +typedef struct bucketeer_ctx_t +{ + apr_bucket_brigade *bb; +} bucketeer_ctx_t; + +static apr_status_t bucketeer_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + apr_bucket *e; + request_rec *r = f->r; + bucketeer_ctx_t *ctx = f->ctx; + bucketeer_filter_config_t *c; + + c = ap_get_module_config(r->server->module_config, &bucketeer_module); + + /* If have a context, it means we've done this before successfully. */ + if (!ctx) { + if (!r->content_type || strncmp(r->content_type, "text/", 5)) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* We're cool with filtering this. */ + ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); + ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + apr_table_unset(f->r->headers_out, "Content-Length"); + } + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + const char *data; + apr_size_t len, i, lastpos; + + if (APR_BUCKET_IS_EOS(e)) { + APR_BUCKET_REMOVE(e); + APR_BRIGADE_INSERT_TAIL(ctx->bb, e); + + /* Okay, we've seen the EOS. + * Time to pass it along down the chain. + */ + return ap_pass_brigade(f->next, ctx->bb); + } + + if (APR_BUCKET_IS_FLUSH(e)) { + /* + * Ignore flush buckets for the moment.. + * we decide what to stream + */ + continue; + } + + if (APR_BUCKET_IS_METADATA(e)) { + /* metadata bucket */ + apr_bucket *cpy; + apr_bucket_copy(e, &cpy); + APR_BRIGADE_INSERT_TAIL(ctx->bb, cpy); + continue; + } + + /* read */ + apr_bucket_read(e, &data, &len, APR_BLOCK_READ); + + if (len > 0) { + lastpos = 0; + for (i = 0; i < len; i++) { + if (data[i] == c->flushdelimiter || + data[i] == c->bucketdelimiter || + data[i] == c->passdelimiter) { + apr_bucket *p; + if (i - lastpos > 0) { + p = apr_bucket_pool_create(apr_pmemdup(f->r->pool, + &data[lastpos], + i - lastpos), + i - lastpos, + f->r->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, p); + } + lastpos = i + 1; + if (data[i] == c->flushdelimiter) { + p = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, p); + } + if (data[i] == c->flushdelimiter || + data[i] == c->passdelimiter) { + ap_pass_brigade(f->next, ctx->bb); + /* apr_brigade_cleanup(ctx->bb);*/ + } + } + } + /* XXX: really should append this to the next 'real' bucket */ + if (lastpos < i) { + apr_bucket *p; + p = apr_bucket_pool_create(apr_pmemdup(f->r->pool, + &data[lastpos], + i - lastpos), + i - lastpos, + f->r->pool, + f->c->bucket_alloc); + lastpos = i; + APR_BRIGADE_INSERT_TAIL(ctx->bb, p); + } + } + } + + return APR_SUCCESS; +} + +static void register_hooks(apr_pool_t * p) +{ + ap_register_output_filter(bucketeerFilterName, bucketeer_out_filter, + NULL, AP_FTYPE_RESOURCE-1); +} + +static const command_rec bucketeer_filter_cmds[] = { + {NULL} +}; + +module AP_MODULE_DECLARE_DATA bucketeer_module = { + STANDARD20_MODULE_STUFF, + NULL, + NULL, + create_bucketeer_server_config, + NULL, + bucketeer_filter_cmds, + register_hooks +}; diff --git a/trunk/modules/debug/mod_bucketeer.dsp b/trunk/modules/debug/mod_bucketeer.dsp new file mode 100644 index 0000000000..9e60d4988e --- /dev/null +++ b/trunk/modules/debug/mod_bucketeer.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_bucketeer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_bucketeer - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_bucketeer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_bucketeer.mak" CFG="mod_bucketeer - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_bucketeer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_bucketeer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_bucketeer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_bucketeer_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_bucketeer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_bucketeer_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_bucketeer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_bucketeer.so + +!ENDIF + +# Begin Target + +# Name "mod_bucketeer - Win32 Release" +# Name "mod_bucketeer - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_bucketeer.c +# End Source File +# Begin Source File + +SOURCE=.\mod_bucketeer.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_bucketeer - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_bucketeer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_bucketeer.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_bucketeer.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_bucketeer - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_bucketeer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_bucketeer.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_bucketeer.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/debug/mod_dumpio.c b/trunk/modules/debug/mod_dumpio.c new file mode 100644 index 0000000000..7af9bbefb2 --- /dev/null +++ b/trunk/modules/debug/mod_dumpio.c @@ -0,0 +1,214 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Originally written @ Covalent by Jim Jagielski + */ + +/* + * mod_dumpio.c: + * Think of this as a filter sniffer for Apache 2.x. It logs + * all filter data right before and after it goes out on the + * wire (BUT right before SSL encoded or after SSL decoded). + * It can produce a *huge* amount of data. + */ + + +#include "httpd.h" +#include "http_connection.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" + +module AP_MODULE_DECLARE_DATA dumpio_module ; + +typedef struct dumpio_conf_t { + int enable_input; + int enable_output; +} dumpio_conf_t; + +/* + * Workhorse function: simply log to the current error_log + * info about the data in the bucket as well as the data itself + */ +static void dumpit(ap_filter_t *f, apr_bucket *b) +{ + conn_rec *c = f->c; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, + "mod_dumpio: %s (%s-%s): %" APR_SIZE_T_FMT " bytes", + f->frec->name, + (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", + b->type->name, + b->length) ; + + if (!(APR_BUCKET_IS_METADATA(b))) { + const char *buf; + apr_size_t nbytes; + char *obuf; + if (apr_bucket_read(b, &buf, &nbytes, APR_BLOCK_READ) == APR_SUCCESS) { + if (nbytes) { + obuf = malloc(nbytes+1); /* use pool? */ + memcpy(obuf, buf, nbytes); + obuf[nbytes] = '\0'; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, + "mod_dumpio: %s (%s-%s): %s", + f->frec->name, + (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", + b->type->name, + obuf); + free(obuf); + } + } else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, + "mod_dumpio: %s (%s-%s): %s", + f->frec->name, + (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", + b->type->name, + "error reading data"); + } + } +} + +#define whichmode( mode ) \ + ( (( mode ) == AP_MODE_READBYTES) ? "readbytes" : \ + (( mode ) == AP_MODE_GETLINE) ? "getline" : \ + (( mode ) == AP_MODE_EATCRLF) ? "eatcrlf" : \ + (( mode ) == AP_MODE_SPECULATIVE) ? "speculative" : \ + (( mode ) == AP_MODE_EXHAUSTIVE) ? "exhaustive" : \ + (( mode ) == AP_MODE_INIT) ? "init" : "unknown" \ + ) + +static int dumpio_input_filter (ap_filter_t *f, apr_bucket_brigade *bb, + ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) +{ + + apr_bucket *b; + apr_status_t ret; + conn_rec *c = f->c; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, + "mod_dumpio: %s [%s-%s] %" APR_OFF_T_FMT " readbytes", + f->frec->name, + whichmode(mode), + ((block) == APR_BLOCK_READ) ? "blocking" : "nonblocking", + readbytes) ; + + ret = ap_get_brigade(f->next, bb, mode, block, readbytes); + + if (ret == APR_SUCCESS) { + for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { + dumpit(f, b); + } + } else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, + "mod_dumpio: %s - %d", f->frec->name, ret) ; + } + + return APR_SUCCESS ; +} + +static int dumpio_output_filter (ap_filter_t *f, apr_bucket_brigade *bb) +{ + apr_bucket *b; + conn_rec *c = f->c; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "mod_dumpio: %s", f->frec->name) ; + + for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { + /* + * If we ever see an EOS, make sure to FLUSH. + */ + if (APR_BUCKET_IS_EOS(b)) { + apr_bucket *flush = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BUCKET_INSERT_BEFORE(b, flush); + } + dumpit(f, b); + } + + return ap_pass_brigade(f->next, bb) ; +} + +static int dumpio_pre_conn(conn_rec *c, void *csd) +{ + dumpio_conf_t *ptr = + (dumpio_conf_t *) ap_get_module_config(c->base_server->module_config, + &dumpio_module); + + if (ptr->enable_input) + ap_add_input_filter("DUMPIO_IN", NULL, NULL, c); + if (ptr->enable_output) + ap_add_output_filter("DUMPIO_OUT", NULL, NULL, c); + return OK; +} + +static void dumpio_register_hooks(apr_pool_t *p) +{ +/* + * We know that SSL is CONNECTION + 5 + */ + ap_register_output_filter("DUMPIO_OUT", dumpio_output_filter, + NULL, AP_FTYPE_CONNECTION + 3) ; + + ap_register_input_filter("DUMPIO_IN", dumpio_input_filter, + NULL, AP_FTYPE_CONNECTION + 3) ; + + ap_hook_pre_connection(dumpio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE); +} + +static void *dumpio_create_sconfig(apr_pool_t *p, server_rec *s) +{ + dumpio_conf_t *ptr = apr_pcalloc(p, sizeof *ptr); + ptr->enable_input = ptr->enable_output = 0; + return ptr; +} + +static const char *dumpio_enable_input(cmd_parms *cmd, void *dummy, int arg) +{ + dumpio_conf_t *ptr = + (dumpio_conf_t *) ap_get_module_config(cmd->server->module_config, + &dumpio_module); + + ptr->enable_input = arg; + return NULL; +} + +static const char *dumpio_enable_output(cmd_parms *cmd, void *dummy, int arg) +{ + dumpio_conf_t *ptr = + (dumpio_conf_t *) ap_get_module_config(cmd->server->module_config, + &dumpio_module); + + ptr->enable_output = arg; + return NULL; +} + +static const command_rec dumpio_cmds[] = { + AP_INIT_FLAG("DumpIOInput", dumpio_enable_input, NULL, + RSRC_CONF, "Enable I/O Dump on Input Data"), + AP_INIT_FLAG("DumpIOOutput", dumpio_enable_output, NULL, + RSRC_CONF, "Enable I/O Dump on Output Data"), + { NULL } +}; + +module AP_MODULE_DECLARE_DATA dumpio_module = { + STANDARD20_MODULE_STUFF, + NULL, + NULL, + dumpio_create_sconfig, + NULL, + dumpio_cmds, + dumpio_register_hooks +}; diff --git a/trunk/modules/debug/mod_dumpio.dsp b/trunk/modules/debug/mod_dumpio.dsp new file mode 100644 index 0000000000..ba83def95c --- /dev/null +++ b/trunk/modules/debug/mod_dumpio.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_dumpio" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_dumpio - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_dumpio.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_dumpio.mak" CFG="mod_dumpio - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_dumpio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_dumpio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_dumpio - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_dumpio_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_dumpio - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_dumpio_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so + +!ENDIF + +# Begin Target + +# Name "mod_dumpio - Win32 Release" +# Name "mod_dumpio - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_dumpio.c +# End Source File +# Begin Source File + +SOURCE=.\mod_dumpio.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_dumpio - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_dumpio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_dumpio.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_dumpio.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_dumpio - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_dumpio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_dumpio.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_dumpio.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/echo/.indent.pro b/trunk/modules/echo/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/echo/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/echo/Makefile.in b/trunk/modules/echo/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/echo/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/echo/NWGNUmakefile b/trunk/modules/echo/NWGNUmakefile new file mode 100644 index 0000000000..d3d40e2814 --- /dev/null +++ b/trunk/modules/echo/NWGNUmakefile @@ -0,0 +1,261 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = echo + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Echo Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Echo Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/echo.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_echo.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + echo_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/echo/config.m4 b/trunk/modules/echo/config.m4 new file mode 100644 index 0000000000..02c42b1522 --- /dev/null +++ b/trunk/modules/echo/config.m4 @@ -0,0 +1,9 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(echo) + +APACHE_MODULE(echo, ECHO server, , , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/echo/mod_echo.c b/trunk/modules/echo/mod_echo.c new file mode 100644 index 0000000000..9d223f8b85 --- /dev/null +++ b/trunk/modules/echo/mod_echo.c @@ -0,0 +1,105 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" +#include "ap_mmn.h" +#include "httpd.h" +#include "http_config.h" +#include "http_connection.h" + +#include "apr_buckets.h" +#include "util_filter.h" + +module AP_MODULE_DECLARE_DATA echo_module; + +typedef struct { + int bEnabled; +} EchoConfig; + +static void *create_echo_server_config(apr_pool_t *p, server_rec *s) +{ + EchoConfig *pConfig = apr_pcalloc(p, sizeof *pConfig); + + pConfig->bEnabled = 0; + + return pConfig; +} + +static const char *echo_on(cmd_parms *cmd, void *dummy, int arg) +{ + EchoConfig *pConfig = ap_get_module_config(cmd->server->module_config, + &echo_module); + pConfig->bEnabled = arg; + + return NULL; +} + +static int process_echo_connection(conn_rec *c) +{ + apr_bucket_brigade *bb; + apr_bucket *b; + apr_status_t rv; + EchoConfig *pConfig = ap_get_module_config(c->base_server->module_config, + &echo_module); + + if (!pConfig->bEnabled) { + return DECLINED; + } + + do { + bb = apr_brigade_create(c->pool, c->bucket_alloc); + + /* Get a single line of input from the client */ + if ((rv = ap_get_brigade(c->input_filters, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0) != APR_SUCCESS || + APR_BRIGADE_EMPTY(bb))) { + apr_brigade_destroy(bb); + break; + } + + /* Make sure the data is flushed to the client */ + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + /* Send back the data. */ + rv = ap_pass_brigade(c->output_filters, bb); + } while (rv == APR_SUCCESS); + + return OK; +} + +static const command_rec echo_cmds[] = +{ + AP_INIT_FLAG("ProtocolEcho", echo_on, NULL, RSRC_CONF, + "Run an echo server on this host"), + { NULL } +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_process_connection(process_echo_connection, NULL, NULL, + APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA echo_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + create_echo_server_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + echo_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/echo/mod_echo.dsp b/trunk/modules/echo/mod_echo.dsp new file mode 100644 index 0000000000..6ac71749b8 --- /dev/null +++ b/trunk/modules/echo/mod_echo.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_echo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_echo - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_echo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_echo.mak" CFG="mod_echo - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_echo - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_echo - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_echo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_echo_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_echo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_echo_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_echo.so" /base:@..\..\os\win32\BaseAddr.ref,mod_echo.so + +!ENDIF + +# Begin Target + +# Name "mod_echo - Win32 Release" +# Name "mod_echo - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_echo.c +# End Source File +# Begin Source File + +SOURCE=.\mod_echo.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_echo - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_echo.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_echo.so "echo_module for Apache" ../../include/ap_release.h > .\mod_echo.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_echo - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_echo.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_echo.so "echo_module for Apache" ../../include/ap_release.h > .\mod_echo.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/experimental/.indent.pro b/trunk/modules/experimental/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/experimental/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/experimental/Makefile.in b/trunk/modules/experimental/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/experimental/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/experimental/NWGNUcharsetl b/trunk/modules/experimental/NWGNUcharsetl new file mode 100644 index 0000000000..7094e9447f --- /dev/null +++ b/trunk/modules/experimental/NWGNUcharsetl @@ -0,0 +1,260 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + -DAP_WANT_DIR_TRANSLATION \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = charsetl + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Charset Lite Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = charsetl + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/charsetl.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_charset_lite.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + charset_lite_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/experimental/NWGNUexample b/trunk/modules/experimental/NWGNUexample new file mode 100644 index 0000000000..13c97b1d66 --- /dev/null +++ b/trunk/modules/experimental/NWGNUexample @@ -0,0 +1,260 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = example + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Example Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Example Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/example.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_example.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + example_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/experimental/NWGNUmakefile b/trunk/modules/experimental/NWGNUmakefile new file mode 100644 index 0000000000..d6e1337a29 --- /dev/null +++ b/trunk/modules/experimental/NWGNUmakefile @@ -0,0 +1,246 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/charsetl.nlm \ + $(OBJDIR)/example.nlm \ + $(OBJDIR)/mod_filter.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/experimental/NWGNUmod_filter b/trunk/modules/experimental/NWGNUmod_filter new file mode 100644 index 0000000000..ec671c5963 --- /dev/null +++ b/trunk/modules/experimental/NWGNUmod_filter @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_filter + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Filter Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Filter Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_filter.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_filter.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + filter_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/experimental/README b/trunk/modules/experimental/README new file mode 100644 index 0000000000..64824a6563 --- /dev/null +++ b/trunk/modules/experimental/README @@ -0,0 +1,41 @@ +README for Apache 2.0 Example Module +[April, 1997, updated May 2000] + +The files in the src/modules/example directory under the Apache +distribution directory tree are provided as an example to those that +wish to write modules that use the Apache API. + +The main file is mod_example.c, which illustrates all the different +callback mechanisms and call syntaces. By no means does an add-on +module need to include routines for all of the callbacks - quite the +contrary! + +The example module is an actual working module. If you link it into +your server, enable the "example-handler" handler for a location, and then +browse to that location, you will see a display of some of the tracing +the example module did as the various callbacks were made. + +To include the example module in your server add --enable-example to the +other ./configure arguments executed from the httpd-2.1 directory. After +that run 'make'. + +To add another module of your own: + + A. cp modules/experimental/mod_example.c modules/experimental/mod_myexample.c + B. Modify the file + C. Build the server with --enable--myexample + +To activate the example module, include a block similar to the +following in your httpd.conf file: + + + SetHandler example-handler + + +As an alternative, you can put the following into a .htaccess file and +then request the file "test.example" from that location: + + AddHandler example-handler .example + +After reloading/restarting your server, you should be able to browse +to this location and see the brief display mentioned earlier. diff --git a/trunk/modules/experimental/config.m4 b/trunk/modules/experimental/config.m4 new file mode 100644 index 0000000000..c5bfacd6db --- /dev/null +++ b/trunk/modules/experimental/config.m4 @@ -0,0 +1,17 @@ + +APACHE_MODPATH_INIT(experimental) + +if test "$ac_cv_ebcdic" = "yes"; then +# mod_charset_lite can be very useful on an ebcdic system, +# so include it by default + APACHE_MODULE(charset_lite, character set translation, , , yes) +else + APACHE_MODULE(charset_lite, character set translation, , , no) +fi + +APACHE_MODULE(example, example and demo module, , , no) +APACHE_MODULE(case_filter, example uppercase conversion filter, , , no) +APACHE_MODULE(case_filter_in, example uppercase conversion input filter, , , no) +APACHE_MODULE(filter, smart filtering module, , , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/experimental/mod_case_filter.c b/trunk/modules/experimental/mod_case_filter.c new file mode 100644 index 0000000000..8a3b08457c --- /dev/null +++ b/trunk/modules/experimental/mod_case_filter.c @@ -0,0 +1,130 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "apr_buckets.h" +#include "apr_general.h" +#include "apr_lib.h" +#include "util_filter.h" +#include "http_request.h" + +#include + +static const char s_szCaseFilterName[]="CaseFilter"; +module AP_MODULE_DECLARE_DATA case_filter_module; + +typedef struct + { + int bEnabled; + } CaseFilterConfig; + +static void *CaseFilterCreateServerConfig(apr_pool_t *p,server_rec *s) + { + CaseFilterConfig *pConfig=apr_pcalloc(p,sizeof *pConfig); + + pConfig->bEnabled=0; + + return pConfig; + } + +static void CaseFilterInsertFilter(request_rec *r) + { + CaseFilterConfig *pConfig=ap_get_module_config(r->server->module_config, + &case_filter_module); + + if(!pConfig->bEnabled) + return; + + ap_add_output_filter(s_szCaseFilterName,NULL,r,r->connection); + } + +static apr_status_t CaseFilterOutFilter(ap_filter_t *f, + apr_bucket_brigade *pbbIn) + { + request_rec *r = f->r; + conn_rec *c = r->connection; + apr_bucket *pbktIn; + apr_bucket_brigade *pbbOut; + + pbbOut=apr_brigade_create(r->pool, c->bucket_alloc); + for (pbktIn = APR_BRIGADE_FIRST(pbbIn); + pbktIn != APR_BRIGADE_SENTINEL(pbbIn); + pbktIn = APR_BUCKET_NEXT(pbktIn)) + { + const char *data; + apr_size_t len; + char *buf; + apr_size_t n; + apr_bucket *pbktOut; + + if(APR_BUCKET_IS_EOS(pbktIn)) + { + apr_bucket *pbktEOS=apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS); + continue; + } + + /* read */ + apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ); + + /* write */ + buf = apr_bucket_alloc(len, c->bucket_alloc); + for(n=0 ; n < len ; ++n) + buf[n] = apr_toupper(data[n]); + + pbktOut = apr_bucket_heap_create(buf, len, apr_bucket_free, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(pbbOut,pbktOut); + } + + /* XXX: is there any advantage to passing a brigade for each bucket? */ + return ap_pass_brigade(f->next,pbbOut); + } + +static const char *CaseFilterEnable(cmd_parms *cmd, void *dummy, int arg) + { + CaseFilterConfig *pConfig=ap_get_module_config(cmd->server->module_config, + &case_filter_module); + pConfig->bEnabled=arg; + + return NULL; + } + +static const command_rec CaseFilterCmds[] = + { + AP_INIT_FLAG("CaseFilter", CaseFilterEnable, NULL, RSRC_CONF, + "Run a case filter on this host"), + { NULL } + }; + +static void CaseFilterRegisterHooks(apr_pool_t *p) + { + ap_hook_insert_filter(CaseFilterInsertFilter,NULL,NULL,APR_HOOK_MIDDLE); + ap_register_output_filter(s_szCaseFilterName,CaseFilterOutFilter,NULL, + AP_FTYPE_RESOURCE); + } + +module AP_MODULE_DECLARE_DATA case_filter_module = +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + CaseFilterCreateServerConfig, + NULL, + CaseFilterCmds, + CaseFilterRegisterHooks +}; diff --git a/trunk/modules/experimental/mod_case_filter_in.c b/trunk/modules/experimental/mod_case_filter_in.c new file mode 100644 index 0000000000..2b1d42075e --- /dev/null +++ b/trunk/modules/experimental/mod_case_filter_in.c @@ -0,0 +1,160 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * An example input filter - this converts input to upper case. Note that + * because of the moment it gets inserted it does NOT convert request headers. + */ + +#include "httpd.h" +#include "http_config.h" +#include "apr_buckets.h" +#include "apr_general.h" +#include "apr_lib.h" +#include "util_filter.h" +#include "http_request.h" + +#include + +static const char s_szCaseFilterName[] = "CaseFilterIn"; +module AP_MODULE_DECLARE_DATA case_filter_in_module; + +typedef struct +{ + int bEnabled; +} CaseFilterInConfig; + +typedef struct +{ + apr_bucket_brigade *pbbTmp; +} CaseFilterInContext; + +static void *CaseFilterInCreateServerConfig(apr_pool_t *p, server_rec *s) +{ + CaseFilterInConfig *pConfig = apr_pcalloc(p, sizeof *pConfig); + + pConfig->bEnabled = 0; + + return pConfig; +} + +static void CaseFilterInInsertFilter(request_rec *r) +{ + CaseFilterInConfig *pConfig=ap_get_module_config(r->server->module_config, + &case_filter_in_module); + if(!pConfig->bEnabled) + return; + + ap_add_input_filter(s_szCaseFilterName,NULL,r,r->connection); +} + +static apr_status_t CaseFilterInFilter(ap_filter_t *f, + apr_bucket_brigade *pbbOut, + ap_input_mode_t eMode, + apr_read_type_e eBlock, + apr_off_t nBytes) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + CaseFilterInContext *pCtx; + apr_status_t ret; + + if (!(pCtx = f->ctx)) { + f->ctx = pCtx = apr_palloc(r->pool, sizeof *pCtx); + pCtx->pbbTmp = apr_brigade_create(r->pool, c->bucket_alloc); + } + + if (APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { + ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); + + if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS) + return ret; + } + + while(!APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { + apr_bucket *pbktIn = APR_BRIGADE_FIRST(pCtx->pbbTmp); + apr_bucket *pbktOut; + const char *data; + apr_size_t len; + char *buf; + int n; + + /* It is tempting to do this... + * APR_BUCKET_REMOVE(pB); + * APR_BRIGADE_INSERT_TAIL(pbbOut,pB); + * and change the case of the bucket data, but that would be wrong + * for a file or socket buffer, for example... + */ + + if(APR_BUCKET_IS_EOS(pbktIn)) { + APR_BUCKET_REMOVE(pbktIn); + APR_BRIGADE_INSERT_TAIL(pbbOut, pbktIn); + break; + } + + ret=apr_bucket_read(pbktIn, &data, &len, eBlock); + if(ret != APR_SUCCESS) + return ret; + + buf = malloc(len); + for(n=0 ; n < len ; ++n) + buf[n] = apr_toupper(data[n]); + + pbktOut = apr_bucket_heap_create(buf, len, 0, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut); + apr_bucket_delete(pbktIn); + } + + return APR_SUCCESS; +} + + +static const char *CaseFilterInEnable(cmd_parms *cmd, void *dummy, int arg) +{ + CaseFilterInConfig *pConfig + = ap_get_module_config(cmd->server->module_config, + &case_filter_in_module); + pConfig->bEnabled=arg; + + return NULL; +} + +static const command_rec CaseFilterInCmds[] = +{ + AP_INIT_FLAG("CaseFilterIn", CaseFilterInEnable, NULL, RSRC_CONF, + "Run an input case filter on this host"), + { NULL } +}; + + +static void CaseFilterInRegisterHooks(apr_pool_t *p) +{ + ap_hook_insert_filter(CaseFilterInInsertFilter, NULL, NULL, + APR_HOOK_MIDDLE); + ap_register_input_filter(s_szCaseFilterName, CaseFilterInFilter, NULL, + AP_FTYPE_RESOURCE); +} + +module AP_MODULE_DECLARE_DATA case_filter_in_module = +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + CaseFilterInCreateServerConfig, + NULL, + CaseFilterInCmds, + CaseFilterInRegisterHooks +}; diff --git a/trunk/modules/experimental/mod_charset_lite.c b/trunk/modules/experimental/mod_charset_lite.c new file mode 100644 index 0000000000..66b8ef0793 --- /dev/null +++ b/trunk/modules/experimental/mod_charset_lite.c @@ -0,0 +1,1138 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * simple hokey charset recoding configuration module + * + * See mod_ebcdic and mod_charset for more thought-out examples. This + * one is just so Jeff can learn how a module works and experiment with + * basic character set recoding configuration. + * + * !!!This is an extremely cheap ripoff of mod_charset.c from Russian Apache!!! + */ + +#include "httpd.h" +#include "http_config.h" +#define CORE_PRIVATE +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "http_request.h" +#include "util_charset.h" +#include "apr_buckets.h" +#include "util_filter.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_xlate.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define OUTPUT_XLATE_BUF_SIZE (16*1024) /* size of translation buffer used on output */ +#define INPUT_XLATE_BUF_SIZE (8*1024) /* size of translation buffer used on input */ + +#define XLATE_MIN_BUFF_LEFT 128 /* flush once there is no more than this much + * space left in the translation buffer + */ + +#define FATTEST_CHAR 8 /* we don't handle chars wider than this that straddle + * two buckets + */ + +/* extended error status codes; this is used in addition to an apr_status_t to + * track errors in the translation filter + */ +typedef enum { + EES_INIT = 0, /* no error info yet; value must be 0 for easy init */ + EES_LIMIT, /* built-in restriction encountered */ + EES_INCOMPLETE_CHAR, /* incomplete multi-byte char at end of content */ + EES_BUCKET_READ, + EES_DOWNSTREAM, /* something bad happened in a filter below xlate */ + EES_BAD_INPUT /* input data invalid */ +} ees_t; + +/* registered name of the output translation filter */ +#define XLATEOUT_FILTER_NAME "XLATEOUT" +/* registered name of input translation filter */ +#define XLATEIN_FILTER_NAME "XLATEIN" + +typedef struct charset_dir_t { + /** debug level; -1 means uninitialized, 0 means no debug */ + int debug; + const char *charset_source; /* source encoding */ + const char *charset_default; /* how to ship on wire */ + /** module does ap_add_*_filter()? */ + enum {IA_INIT, IA_IMPADD, IA_NOIMPADD} implicit_add; +} charset_dir_t; + +/* charset_filter_ctx_t is created for each filter instance; because the same + * filter code is used for translating in both directions, we need this context + * data to tell the filter which translation handle to use; it also can hold a + * character which was split between buckets + */ +typedef struct charset_filter_ctx_t { + apr_xlate_t *xlate; + charset_dir_t *dc; + ees_t ees; /* extended error status */ + apr_size_t saved; + char buf[FATTEST_CHAR]; /* we want to be able to build a complete char here */ + int ran; /* has filter instance run before? */ + int noop; /* should we pass brigades through unchanged? */ + char *tmp; /* buffer for input filtering */ + apr_bucket_brigade *bb; /* input buckets we couldn't finish translating */ +} charset_filter_ctx_t; + +/* charset_req_t is available via r->request_config if any translation is + * being performed + */ +typedef struct charset_req_t { + charset_dir_t *dc; + charset_filter_ctx_t *output_ctx, *input_ctx; +} charset_req_t; + +/* debug level definitions */ +#define DBGLVL_GORY 9 /* gory details */ +#define DBGLVL_FLOW 4 /* enough messages to see what happens on + * each request */ +#define DBGLVL_PMC 2 /* messages about possible misconfiguration */ + +module AP_MODULE_DECLARE_DATA charset_lite_module; + +static void *create_charset_dir_conf(apr_pool_t *p,char *dummy) +{ + charset_dir_t *dc = (charset_dir_t *)apr_pcalloc(p,sizeof(charset_dir_t)); + + dc->debug = -1; + return dc; +} + +static void *merge_charset_dir_conf(apr_pool_t *p, void *basev, void *overridesv) +{ + charset_dir_t *a = (charset_dir_t *)apr_pcalloc (p, sizeof(charset_dir_t)); + charset_dir_t *base = (charset_dir_t *)basev, + *over = (charset_dir_t *)overridesv; + + /* If it is defined in the current container, use it. Otherwise, use the one + * from the enclosing container. + */ + + a->debug = + over->debug != -1 ? over->debug : base->debug; + a->charset_default = + over->charset_default ? over->charset_default : base->charset_default; + a->charset_source = + over->charset_source ? over->charset_source : base->charset_source; + a->implicit_add = + over->implicit_add != IA_INIT ? over->implicit_add : base->implicit_add; + return a; +} + +/* CharsetSourceEnc charset + */ +static const char *add_charset_source(cmd_parms *cmd, void *in_dc, + const char *name) +{ + charset_dir_t *dc = in_dc; + + dc->charset_source = name; + return NULL; +} + +/* CharsetDefault charset + */ +static const char *add_charset_default(cmd_parms *cmd, void *in_dc, + const char *name) +{ + charset_dir_t *dc = in_dc; + + dc->charset_default = name; + return NULL; +} + +/* CharsetOptions optionflag... + */ +static const char *add_charset_options(cmd_parms *cmd, void *in_dc, + const char *flag) +{ + charset_dir_t *dc = in_dc; + + if (!strcasecmp(flag, "ImplicitAdd")) { + dc->implicit_add = IA_IMPADD; + } + else if (!strcasecmp(flag, "NoImplicitAdd")) { + dc->implicit_add = IA_NOIMPADD; + } + else if (!strncasecmp(flag, "DebugLevel=", 11)) { + dc->debug = atoi(flag + 11); + } + else { + return apr_pstrcat(cmd->temp_pool, + "Invalid CharsetOptions option: ", + flag, + NULL); + } + + return NULL; +} + +/* find_code_page() is a fixup hook that decides if translation should be + * enabled; if so, it sets up request data for use by the filter registration + * hook so that it knows what to do + */ +static int find_code_page(request_rec *r) +{ + charset_dir_t *dc = ap_get_module_config(r->per_dir_config, + &charset_lite_module); + charset_req_t *reqinfo; + charset_filter_ctx_t *input_ctx, *output_ctx; + apr_status_t rv; + const char *mime_type; + + if (dc->debug >= DBGLVL_FLOW) { + ap_log_rerror(APLOG_MARK,APLOG_DEBUG, 0, r, + "uri: %s file: %s method: %d " + "imt: %s flags: %s%s%s %s->%s", + r->uri, r->filename, r->method_number, + r->content_type ? r->content_type : "(unknown)", + r->main ? "S" : "", /* S if subrequest */ + r->prev ? "R" : "", /* R if redirect */ + r->proxyreq ? "P" : "", /* P if proxy */ + dc->charset_source, dc->charset_default); + } + + /* If we don't have a full directory configuration, bail out. + */ + if (!dc->charset_source || !dc->charset_default) { + if (dc->debug >= DBGLVL_PMC) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "incomplete configuration: src %s, dst %s", + dc->charset_source ? dc->charset_source : "unspecified", + dc->charset_default ? dc->charset_default : "unspecified"); + } + return DECLINED; + } + + /* catch proxy requests */ + if (r->proxyreq) return DECLINED; + /* mod_rewrite indicators */ + if (!strncmp(r->filename, "redirect:", 9)) return DECLINED; + if (!strncmp(r->filename, "gone:", 5)) return DECLINED; + if (!strncmp(r->filename, "passthrough:", 12)) return DECLINED; + if (!strncmp(r->filename, "forbidden:", 10)) return DECLINED; + + mime_type = r->content_type ? r->content_type : ap_default_type(r); + + /* If mime type isn't text or message, bail out. + */ + +/* XXX When we handle translation of the request body, watch out here as + * 1.3 allowed additional mime types: multipart and + * application/x-www-form-urlencoded + */ + + if (strncasecmp(mime_type, "text/", 5) && +#if APR_CHARSET_EBCDIC || AP_WANT_DIR_TRANSLATION + /* On an EBCDIC machine, be willing to translate mod_autoindex- + * generated output. Otherwise, it doesn't look too cool. + * + * XXX This isn't a perfect fix because this doesn't trigger us + * to convert from the charset of the source code to ASCII. The + * general solution seems to be to allow a generator to set an + * indicator in the r specifying that the body is coded in the + * implementation character set (i.e., the charset of the source + * code). This would get several different types of documents + * translated properly: mod_autoindex output, mod_status output, + * mod_info output, hard-coded error documents, etc. + */ + strcmp(mime_type, DIR_MAGIC_TYPE) && +#endif + strncasecmp(mime_type, "message/", 8)) { + if (dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "mime type is %s; no translation selected", + mime_type); + } + /* We must not bail out here (i.e., the MIME test must be in the filter + * itself, not in the fixup, because only then is the final MIME type known. + * Examples for late changes to the MIME type include CGI handling (MIME + * type is set in the Content-Type header produced by the CGI script), or + * PHP (until PHP runs, the MIME type is set to application/x-httpd-php) + */ + } + + if (dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "charset_source: %s charset_default: %s", + dc && dc->charset_source ? dc->charset_source : "(none)", + dc && dc->charset_default ? dc->charset_default : "(none)"); + } + + /* Get storage for the request data and the output filter context. + * We rarely need the input filter context, so allocate that separately. + */ + reqinfo = (charset_req_t *)apr_pcalloc(r->pool, + sizeof(charset_req_t) + + sizeof(charset_filter_ctx_t)); + output_ctx = (charset_filter_ctx_t *)(reqinfo + 1); + + reqinfo->dc = dc; + output_ctx->dc = dc; + ap_set_module_config(r->request_config, &charset_lite_module, reqinfo); + + reqinfo->output_ctx = output_ctx; + + /* We must not open the xlation table here yet, because the final MIME + * type is not known until we are actually called in the output filter. + * With POST or PUT request, the case is different, because their MIME + * type is set in the request headers, and their data are prerequisites + * for actually calling, e.g., the CGI handler later on. + */ + output_ctx->xlate = NULL; + + switch (r->method_number) { + case M_PUT: + case M_POST: + /* Set up input translation. Note: A request body can be included + * with the OPTIONS method, but for now we don't set up translation + * of it. + */ + input_ctx = apr_pcalloc(r->pool, sizeof(charset_filter_ctx_t)); + input_ctx->bb = apr_brigade_create(r->pool, + r->connection->bucket_alloc); + input_ctx->tmp = apr_palloc(r->pool, INPUT_XLATE_BUF_SIZE); + input_ctx->dc = dc; + reqinfo->input_ctx = input_ctx; + rv = apr_xlate_open(&input_ctx->xlate, dc->charset_source, + dc->charset_default, r->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "can't open translation %s->%s", + dc->charset_default, dc->charset_source); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + return DECLINED; +} + +static int configured_in_list(request_rec *r, const char *filter_name, + struct ap_filter_t *filter_list) +{ + struct ap_filter_t *filter = filter_list; + + while (filter) { + if (!strcasecmp(filter_name, filter->frec->name)) { + return 1; + } + filter = filter->next; + } + return 0; +} + +static int configured_on_input(request_rec *r, const char *filter_name) +{ + return configured_in_list(r, filter_name, r->input_filters); +} + +static int configured_on_output(request_rec *r, const char *filter_name) +{ + return configured_in_list(r, filter_name, r->output_filters); +} + +/* xlate_insert_filter() is a filter hook which decides whether or not + * to insert a translation filter for the current request. + */ +static void xlate_insert_filter(request_rec *r) +{ + /* Hey... don't be so quick to use reqinfo->dc here; reqinfo may be NULL */ + charset_req_t *reqinfo = ap_get_module_config(r->request_config, + &charset_lite_module); + charset_dir_t *dc = ap_get_module_config(r->per_dir_config, + &charset_lite_module); + + if (reqinfo) { + if (reqinfo->output_ctx && !configured_on_output(r, XLATEOUT_FILTER_NAME)) { + ap_add_output_filter(XLATEOUT_FILTER_NAME, reqinfo->output_ctx, r, + r->connection); + } + else if (dc->debug >= DBGLVL_FLOW) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "xlate output filter not added implicitly because %s", + !reqinfo->output_ctx ? + "no output configuration available" : + "another module added the filter"); + } + + if (reqinfo->input_ctx && !configured_on_input(r, XLATEIN_FILTER_NAME)) { + ap_add_input_filter(XLATEIN_FILTER_NAME, reqinfo->input_ctx, r, + r->connection); + } + else if (dc->debug >= DBGLVL_FLOW) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "xlate input filter not added implicitly because %s", + !reqinfo->input_ctx ? + "no input configuration available" : + "another module added the filter"); + } + } +} + +/* stuff that sucks that I know of: + * + * bucket handling: + * why create an eos bucket when we see it come down the stream? just send the one + * passed as input... news flash: this will be fixed when xlate_out_filter() starts + * using the more generic xlate_brigade() + * + * translation mechanics: + * we don't handle characters that straddle more than two buckets; an error + * will be generated + */ + +/* send_downstream() is passed the translated data; it puts it in a single- + * bucket brigade and passes the brigade to the next filter + */ +static apr_status_t send_downstream(ap_filter_t *f, const char *tmp, apr_size_t len) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *b; + charset_filter_ctx_t *ctx = f->ctx; + apr_status_t rv; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_transient_create(tmp, len, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + rv = ap_pass_brigade(f->next, bb); + if (rv != APR_SUCCESS) { + ctx->ees = EES_DOWNSTREAM; + } + return rv; +} + +static apr_status_t send_eos(ap_filter_t *f) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *b; + charset_filter_ctx_t *ctx = f->ctx; + apr_status_t rv; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + rv = ap_pass_brigade(f->next, bb); + if (rv != APR_SUCCESS) { + ctx->ees = EES_DOWNSTREAM; + } + return rv; +} + +static apr_status_t set_aside_partial_char(charset_filter_ctx_t *ctx, + const char *partial, + apr_size_t partial_len) +{ + apr_status_t rv; + + if (sizeof(ctx->buf) > partial_len) { + ctx->saved = partial_len; + memcpy(ctx->buf, partial, partial_len); + rv = APR_SUCCESS; + } + else { + rv = APR_INCOMPLETE; + ctx->ees = EES_LIMIT; /* we don't handle chars this wide which straddle + * buckets + */ + } + return rv; +} + +static apr_status_t finish_partial_char(charset_filter_ctx_t *ctx, + /* input buffer: */ + const char **cur_str, + apr_size_t *cur_len, + /* output buffer: */ + char **out_str, + apr_size_t *out_len) +{ + apr_status_t rv; + apr_size_t tmp_input_len; + + /* Keep adding bytes from the input string to the saved string until we + * 1) finish the input char + * 2) get an error + * or 3) run out of bytes to add + */ + + do { + ctx->buf[ctx->saved] = **cur_str; + ++ctx->saved; + ++*cur_str; + --*cur_len; + tmp_input_len = ctx->saved; + rv = apr_xlate_conv_buffer(ctx->xlate, + ctx->buf, + &tmp_input_len, + *out_str, + out_len); + } while (rv == APR_INCOMPLETE && *cur_len); + + if (rv == APR_SUCCESS) { + ctx->saved = 0; + } + else { + ctx->ees = EES_LIMIT; /* code isn't smart enough to handle chars + * straddling more than two buckets + */ + } + + return rv; +} + +static void log_xlate_error(ap_filter_t *f, apr_status_t rv) +{ + charset_filter_ctx_t *ctx = f->ctx; + const char *msg; + char msgbuf[100]; + int cur; + + switch(ctx->ees) { + case EES_LIMIT: + rv = 0; + msg = "xlate filter - a built-in restriction was encountered"; + break; + case EES_BAD_INPUT: + rv = 0; + msg = "xlate filter - an input character was invalid"; + break; + case EES_BUCKET_READ: + rv = 0; + msg = "xlate filter - bucket read routine failed"; + break; + case EES_INCOMPLETE_CHAR: + rv = 0; + strcpy(msgbuf, "xlate filter - incomplete char at end of input - "); + cur = 0; + while ((apr_size_t)cur < ctx->saved) { + apr_snprintf(msgbuf + strlen(msgbuf), sizeof(msgbuf) - strlen(msgbuf), + "%02X", (unsigned)ctx->buf[cur]); + ++cur; + } + msg = msgbuf; + break; + case EES_DOWNSTREAM: + msg = "xlate filter - an error occurred in a lower filter"; + break; + default: + msg = "xlate filter - returning error"; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, + "%s", msg); +} + +/* chk_filter_chain() is called once per filter instance; it tries to + * determine if the current filter instance should be disabled because + * its translation is incompatible with the translation of an existing + * instance of the translate filter + * + * Example bad scenario: + * + * configured filter chain for the request: + * INCLUDES XLATEOUT(8859-1->UTS-16) + * configured filter chain for the subrequest: + * XLATEOUT(8859-1->UTS-16) + * + * When the subrequest is processed, the filter chain will be + * XLATEOUT(8859-1->UTS-16) XLATEOUT(8859-1->UTS-16) + * This makes no sense, so the instance of XLATEOUT added for the + * subrequest will be noop-ed. + * + * Example good scenario: + * + * configured filter chain for the request: + * INCLUDES XLATEOUT(8859-1->UTS-16) + * configured filter chain for the subrequest: + * XLATEOUT(IBM-1047->8859-1) + * + * When the subrequest is processed, the filter chain will be + * XLATEOUT(IBM-1047->8859-1) XLATEOUT(8859-1->UTS-16) + * This makes sense, so the instance of XLATEOUT added for the + * subrequest will be left alone and it will translate from + * IBM-1047->8859-1. + */ +static void chk_filter_chain(ap_filter_t *f) +{ + ap_filter_t *curf; + charset_filter_ctx_t *curctx, *last_xlate_ctx = NULL, + *ctx = f->ctx; + int debug = ctx->dc->debug; + int output = !strcasecmp(f->frec->name, XLATEOUT_FILTER_NAME); + + if (ctx->noop) { + return; + } + + /* walk the filter chain; see if it makes sense for our filter to + * do any translation + */ + curf = output ? f->r->output_filters : f->r->input_filters; + while (curf) { + if (!strcasecmp(curf->frec->name, f->frec->name) && + curf->ctx) { + curctx = (charset_filter_ctx_t *)curf->ctx; + if (!last_xlate_ctx) { + last_xlate_ctx = curctx; + } + else { + if (strcmp(last_xlate_ctx->dc->charset_default, + curctx->dc->charset_source)) { + /* incompatible translation + * if our filter instance is incompatible with an instance + * already in place, noop our instance + * Notes: + * . We are only willing to noop our own instance. + * . It is possible to noop another instance which has not + * yet run, but this is not currently implemented. + * Hopefully it will not be needed. + * . It is not possible to noop an instance which has + * already run. + */ + if (last_xlate_ctx == f->ctx) { + last_xlate_ctx->noop = 1; + if (debug >= DBGLVL_PMC) { + const char *symbol = output ? "->" : "<-"; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, + 0, f->r, + "%s %s - disabling " + "translation %s%s%s; existing " + "translation %s%s%s", + f->r->uri ? "uri" : "file", + f->r->uri ? f->r->uri : f->r->filename, + last_xlate_ctx->dc->charset_source, + symbol, + last_xlate_ctx->dc->charset_default, + curctx->dc->charset_source, + symbol, + curctx->dc->charset_default); + } + } + else { + const char *symbol = output ? "->" : "<-"; + + ap_log_rerror(APLOG_MARK, APLOG_ERR, + 0, f->r, + "chk_filter_chain() - can't disable " + "translation %s%s%s; existing " + "translation %s%s%s", + last_xlate_ctx->dc->charset_source, + symbol, + last_xlate_ctx->dc->charset_default, + curctx->dc->charset_source, + symbol, + curctx->dc->charset_default); + } + break; + } + } + } + curf = curf->next; + } +} + +/* xlate_brigade() is used to filter request and response bodies + * + * we'll stop when one of the following occurs: + * . we run out of buckets + * . we run out of space in the output buffer + * . we hit an error + * + * inputs: + * bb: brigade to process + * buffer: storage to hold the translated characters + * buffer_size: size of buffer + * (and a few more uninteresting parms) + * + * outputs: + * return value: APR_SUCCESS or some error code + * bb: we've removed any buckets representing the + * translated characters; the eos bucket, if + * present, will be left in the brigade + * buffer: filled in with translated characters + * buffer_size: updated with the bytes remaining + * hit_eos: did we hit an EOS bucket? + */ +static apr_status_t xlate_brigade(charset_filter_ctx_t *ctx, + apr_bucket_brigade *bb, + char *buffer, + apr_size_t *buffer_avail, + int *hit_eos) +{ + apr_bucket *b = NULL; /* set to NULL only to quiet some gcc */ + apr_bucket *consumed_bucket; + const char *bucket; + apr_size_t bytes_in_bucket; /* total bytes read from current bucket */ + apr_size_t bucket_avail; /* bytes left in current bucket */ + apr_status_t rv = APR_SUCCESS; + + *hit_eos = 0; + bucket_avail = 0; + consumed_bucket = NULL; + while (1) { + if (!bucket_avail) { /* no bytes left to process in the current bucket... */ + if (consumed_bucket) { + apr_bucket_delete(consumed_bucket); + consumed_bucket = NULL; + } + b = APR_BRIGADE_FIRST(bb); + if (b == APR_BRIGADE_SENTINEL(bb) || + APR_BUCKET_IS_EOS(b)) { + break; + } + rv = apr_bucket_read(b, &bucket, &bytes_in_bucket, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + ctx->ees = EES_BUCKET_READ; + break; + } + bucket_avail = bytes_in_bucket; + consumed_bucket = b; /* for axing when we're done reading it */ + } + if (bucket_avail) { + /* We've got data, so translate it. */ + if (ctx->saved) { + /* Rats... we need to finish a partial character from the previous + * bucket. + * + * Strangely, finish_partial_char() increments the input buffer + * pointer but does not increment the output buffer pointer. + */ + apr_size_t old_buffer_avail = *buffer_avail; + rv = finish_partial_char(ctx, + &bucket, &bucket_avail, + &buffer, buffer_avail); + buffer += old_buffer_avail - *buffer_avail; + } + else { + apr_size_t old_buffer_avail = *buffer_avail; + apr_size_t old_bucket_avail = bucket_avail; + rv = apr_xlate_conv_buffer(ctx->xlate, + bucket, &bucket_avail, + buffer, + buffer_avail); + buffer += old_buffer_avail - *buffer_avail; + bucket += old_bucket_avail - bucket_avail; + + if (rv == APR_INCOMPLETE) { /* partial character at end of input */ + /* We need to save the final byte(s) for next time; we can't + * convert it until we look at the next bucket. + */ + rv = set_aside_partial_char(ctx, bucket, bucket_avail); + bucket_avail = 0; + } + } + if (rv != APR_SUCCESS) { + /* bad input byte or partial char too big to store */ + break; + } + if (*buffer_avail < XLATE_MIN_BUFF_LEFT) { + /* if any data remains in the current bucket, split there */ + if (bucket_avail) { + apr_bucket_split(b, bytes_in_bucket - bucket_avail); + } + apr_bucket_delete(b); + break; + } + } + } + + if (!APR_BRIGADE_EMPTY(bb)) { + b = APR_BRIGADE_FIRST(bb); + if (APR_BUCKET_IS_EOS(b)) { + /* Leave the eos bucket in the brigade for reporting to + * subsequent filters. + */ + *hit_eos = 1; + if (ctx->saved) { + /* Oops... we have a partial char from the previous bucket + * that won't be completed because there's no more data. + */ + rv = APR_INCOMPLETE; + ctx->ees = EES_INCOMPLETE_CHAR; + } + } + } + + return rv; +} + +/* xlate_out_filter() handles (almost) arbitrary conversions from one charset + * to another... + * translation is determined in the fixup hook (find_code_page), which is + * where the filter's context data is set up... the context data gives us + * the translation handle + */ +static apr_status_t xlate_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) +{ + charset_req_t *reqinfo = ap_get_module_config(f->r->request_config, + &charset_lite_module); + charset_dir_t *dc = ap_get_module_config(f->r->per_dir_config, + &charset_lite_module); + charset_filter_ctx_t *ctx = f->ctx; + apr_bucket *dptr, *consumed_bucket; + const char *cur_str; + apr_size_t cur_len, cur_avail; + char tmp[OUTPUT_XLATE_BUF_SIZE]; + apr_size_t space_avail; + int done; + apr_status_t rv = APR_SUCCESS; + + if (!ctx) { + /* this is SetOutputFilter path; grab the preallocated context, + * if any; note that if we decided not to do anything in an earlier + * handler, we won't even have a reqinfo + */ + if (reqinfo) { + ctx = f->ctx = reqinfo->output_ctx; + reqinfo->output_ctx = NULL; /* prevent SNAFU if user coded us twice + * in the filter chain; we can't have two + * instances using the same context + */ + } + if (!ctx) { /* no idea how to translate; don't do anything */ + ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(charset_filter_ctx_t)); + ctx->dc = dc; + ctx->noop = 1; + } + } + + /* catch proxy requests */ + if (f->r->proxyreq) return DECLINED; + + /* Opening the output translation (this used to be done in the fixup hook, + * but that was too early: a subsequent type modification, e.g., by a + * CGI script, would go unnoticed. Now we do it in the filter itself.) + */ + if (!ctx->noop && ctx->xlate == NULL) + { + const char *mime_type = f->r->content_type ? f->r->content_type : ap_default_type(f->r); + + /* XXX When we handle translation of the request body, watch out here as + * 1.3 allowed additional mime types: multipart and + * application/x-www-form-urlencoded + */ + if (strncasecmp(mime_type, "text/", 5) == 0 || +#if APR_CHARSET_EBCDIC + /* On an EBCDIC machine, be willing to translate mod_autoindex- + * generated output. Otherwise, it doesn't look too cool. + * + * XXX This isn't a perfect fix because this doesn't trigger us + * to convert from the charset of the source code to ASCII. The + * general solution seems to be to allow a generator to set an + * indicator in the r specifying that the body is coded in the + * implementation character set (i.e., the charset of the source + * code). This would get several different types of documents + * translated properly: mod_autoindex output, mod_status output, + * mod_info output, hard-coded error documents, etc. + */ + strcmp(mime_type, DIR_MAGIC_TYPE) == 0 || +#endif + strncasecmp(mime_type, "message/", 8) == 0) { + + rv = apr_xlate_open(&ctx->xlate, + dc->charset_default, dc->charset_source, f->r->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, + "can't open translation %s->%s", + dc->charset_source, dc->charset_default); + ctx->noop = 1; + } + } + else { + ctx->noop = 1; + if (dc->debug >= DBGLVL_GORY) + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, + "mime type is %s; no translation selected", + mime_type); + } + } + + if (dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, + "xlate_out_filter() - " + "charset_source: %s charset_default: %s", + dc && dc->charset_source ? dc->charset_source : "(none)", + dc && dc->charset_default ? dc->charset_default : "(none)"); + } + + if (!ctx->ran) { /* filter never ran before */ + chk_filter_chain(f); + ctx->ran = 1; + } + + if (ctx->noop) { + return ap_pass_brigade(f->next, bb); + } + + dptr = APR_BRIGADE_FIRST(bb); + done = 0; + cur_len = 0; + space_avail = sizeof(tmp); + consumed_bucket = NULL; + while (!done) { + if (!cur_len) { /* no bytes left to process in the current bucket... */ + if (consumed_bucket) { + apr_bucket_delete(consumed_bucket); + consumed_bucket = NULL; + } + if (dptr == APR_BRIGADE_SENTINEL(bb)) { + done = 1; + break; + } + if (APR_BUCKET_IS_EOS(dptr)) { + done = 1; + cur_len = -1; /* XXX yuck, but that tells us to send + * eos down; when we minimize our bb construction + * we'll fix this crap */ + if (ctx->saved) { + /* Oops... we have a partial char from the previous bucket + * that won't be completed because there's no more data. + */ + rv = APR_INCOMPLETE; + ctx->ees = EES_INCOMPLETE_CHAR; + } + break; + } + rv = apr_bucket_read(dptr, &cur_str, &cur_len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + done = 1; + ctx->ees = EES_BUCKET_READ; + break; + } + consumed_bucket = dptr; /* for axing when we're done reading it */ + dptr = APR_BUCKET_NEXT(dptr); /* get ready for when we access the + * next bucket */ + } + /* Try to fill up our tmp buffer with translated data. */ + cur_avail = cur_len; + + if (cur_len) { /* maybe we just hit the end of a pipe (len = 0) ? */ + if (ctx->saved) { + /* Rats... we need to finish a partial character from the previous + * bucket. + */ + char *tmp_tmp; + + tmp_tmp = tmp + sizeof(tmp) - space_avail; + rv = finish_partial_char(ctx, + &cur_str, &cur_len, + &tmp_tmp, &space_avail); + } + else { + rv = apr_xlate_conv_buffer(ctx->xlate, + cur_str, &cur_avail, + tmp + sizeof(tmp) - space_avail, &space_avail); + + /* Update input ptr and len after consuming some bytes */ + cur_str += cur_len - cur_avail; + cur_len = cur_avail; + + if (rv == APR_INCOMPLETE) { /* partial character at end of input */ + /* We need to save the final byte(s) for next time; we can't + * convert it until we look at the next bucket. + */ + rv = set_aside_partial_char(ctx, cur_str, cur_len); + cur_len = 0; + } + } + } + + if (rv != APR_SUCCESS) { + /* bad input byte or partial char too big to store */ + done = 1; + } + + if (space_avail < XLATE_MIN_BUFF_LEFT) { + /* It is time to flush, as there is not enough space left in the + * current output buffer to bother with converting more data. + */ + rv = send_downstream(f, tmp, sizeof(tmp) - space_avail); + if (rv != APR_SUCCESS) { + done = 1; + } + + /* tmp is now empty */ + space_avail = sizeof(tmp); + } + } + + if (rv == APR_SUCCESS) { + if (space_avail < sizeof(tmp)) { /* gotta write out what we converted */ + rv = send_downstream(f, tmp, sizeof(tmp) - space_avail); + } + } + if (rv == APR_SUCCESS) { + if (cur_len == -1) { + rv = send_eos(f); + } + } + else { + log_xlate_error(f, rv); + } + + return rv; +} + +static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) +{ + apr_status_t rv; + charset_req_t *reqinfo = ap_get_module_config(f->r->request_config, + &charset_lite_module); + charset_dir_t *dc = ap_get_module_config(f->r->per_dir_config, + &charset_lite_module); + charset_filter_ctx_t *ctx = f->ctx; + apr_size_t buffer_size; + int hit_eos; + + if (!ctx) { + /* this is SetInputFilter path; grab the preallocated context, + * if any; note that if we decided not to do anything in an earlier + * handler, we won't even have a reqinfo + */ + if (reqinfo) { + ctx = f->ctx = reqinfo->input_ctx; + reqinfo->input_ctx = NULL; /* prevent SNAFU if user coded us twice + * in the filter chain; we can't have two + * instances using the same context + */ + } + if (!ctx) { /* no idea how to translate; don't do anything */ + ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(charset_filter_ctx_t)); + ctx->dc = dc; + ctx->noop = 1; + } + } + + if (dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, + "xlate_in_filter() - " + "charset_source: %s charset_default: %s", + dc && dc->charset_source ? dc->charset_source : "(none)", + dc && dc->charset_default ? dc->charset_default : "(none)"); + } + + if (!ctx->ran) { /* filter never ran before */ + chk_filter_chain(f); + ctx->ran = 1; + } + + if (ctx->noop) { + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + if (APR_BRIGADE_EMPTY(ctx->bb)) { + if ((rv = ap_get_brigade(f->next, bb, mode, block, + readbytes)) != APR_SUCCESS) { + return rv; + } + } + else { + APR_BRIGADE_PREPEND(bb, ctx->bb); /* first use the leftovers */ + } + + buffer_size = INPUT_XLATE_BUF_SIZE; + rv = xlate_brigade(ctx, bb, ctx->tmp, &buffer_size, &hit_eos); + if (rv == APR_SUCCESS) { + if (!hit_eos) { + /* move anything leftover into our context for next time; + * we don't currently "set aside" since the data came from + * down below, but I suspect that for long-term we need to + * do that + */ + APR_BRIGADE_CONCAT(ctx->bb, bb); + } + if (buffer_size < INPUT_XLATE_BUF_SIZE) { /* do we have output? */ + apr_bucket *e; + + e = apr_bucket_heap_create(ctx->tmp, + INPUT_XLATE_BUF_SIZE - buffer_size, + NULL, f->r->connection->bucket_alloc); + /* make sure we insert at the head, because there may be + * an eos bucket already there, and the eos bucket should + * come after the data + */ + APR_BRIGADE_INSERT_HEAD(bb, e); + } + else { + /* XXX need to get some more data... what if the last brigade + * we got had only the first byte of a multibyte char? we need + * to grab more data from the network instead of returning an + * empty brigade + */ + } + } + else { + log_xlate_error(f, rv); + } + + return rv; +} + +static const command_rec cmds[] = +{ + AP_INIT_TAKE1("CharsetSourceEnc", + add_charset_source, + NULL, + OR_FILEINFO, + "source (html,cgi,ssi) file charset"), + AP_INIT_TAKE1("CharsetDefault", + add_charset_default, + NULL, + OR_FILEINFO, + "name of default charset"), + AP_INIT_ITERATE("CharsetOptions", + add_charset_options, + NULL, + OR_FILEINFO, + "valid options: ImplicitAdd, NoImplicitAdd, DebugLevel=n"), + {NULL} +}; + +static void charset_register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(find_code_page, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter(xlate_insert_filter, NULL, NULL, APR_HOOK_REALLY_LAST); + ap_register_output_filter(XLATEOUT_FILTER_NAME, xlate_out_filter, NULL, + AP_FTYPE_RESOURCE); + ap_register_input_filter(XLATEIN_FILTER_NAME, xlate_in_filter, NULL, + AP_FTYPE_RESOURCE); +} + +module AP_MODULE_DECLARE_DATA charset_lite_module = +{ + STANDARD20_MODULE_STUFF, + create_charset_dir_conf, + merge_charset_dir_conf, + NULL, + NULL, + cmds, + charset_register_hooks +}; + diff --git a/trunk/modules/experimental/mod_charset_lite.dsp b/trunk/modules/experimental/mod_charset_lite.dsp new file mode 100644 index 0000000000..de3707707a --- /dev/null +++ b/trunk/modules/experimental/mod_charset_lite.dsp @@ -0,0 +1,124 @@ +# Microsoft Developer Studio Project File - Name="mod_charset_lite" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_charset_lite - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_charset_lite.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_charset_lite.mak" CFG="mod_charset_lite - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_charset_lite - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_charset_lite - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_charset_lite - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_charset_lite_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_charset_lite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_charset_lite - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_charset_lite_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_charset_lite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_charset_lite.so + +!ENDIF + +# Begin Target + +# Name "mod_charset_lite - Win32 Release" +# Name "mod_charset_lite - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_charset_lite.c +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_charset_lite - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_charset_lite.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_charset_lite.so "charset_lite_module for Apache" ../../include/ap_release.h > .\mod_charset_lite.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_charset_lite - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_charset_lite.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_charset_lite.so "charset_lite_module for Apache" ../../include/ap_release.h > .\mod_charset_lite.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/experimental/mod_charset_lite.exp b/trunk/modules/experimental/mod_charset_lite.exp new file mode 100644 index 0000000000..3f0bf14b4a --- /dev/null +++ b/trunk/modules/experimental/mod_charset_lite.exp @@ -0,0 +1 @@ +charset_lite_module diff --git a/trunk/modules/experimental/mod_dbd.c b/trunk/modules/experimental/mod_dbd.c new file mode 100644 index 0000000000..370568a2bf --- /dev/null +++ b/trunk/modules/experimental/mod_dbd.c @@ -0,0 +1,461 @@ +/* Copyright 2003-5 WebThing Ltd + * Copyright 2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Overview of what this is and does: + * http://www.apache.org/~niq/dbd.html + * or + * http://apache.webthing.com/database/ + */ + +/* Bump the version for committing to apache svn */ +#define VERSION "0.2" + +#include + +#include "http_protocol.h" +#include "http_config.h" +#include "http_log.h" +#include "apr_reslist.h" +#include "apr_strings.h" + +#include "apr_dbd.h" +#include "mod_dbd.h" + +extern module AP_MODULE_DECLARE_DATA dbd_module; + +/************ svr cfg: manage db connection pool ****************/ + +typedef struct dbd_prepared { + const char *label; + const char *query; + struct dbd_prepared *next; +} dbd_prepared; +typedef struct svr_cfg { + const char *name; + const char *params; + int persist; + dbd_prepared *prepared; +#if APR_HAS_THREADS + apr_reslist_t *dbpool; + int nmin; + int nkeep; + int nmax; + int exptime; +#else + ap_dbd_t *conn; +#endif +} svr_cfg; + +typedef enum { cmd_name, cmd_params, cmd_persist, + cmd_min, cmd_keep, cmd_max, cmd_exp +} cmd_parts; + + +#define ISINT(val) \ + for (p = val; *p; ++p) \ + if (!isdigit(*p)) \ + return "Argument must be numeric!" +static const char *dbd_param(cmd_parms *cmd, void *cfg, const char *val) +{ + const char *p; + apr_dbd_driver_t *driver = NULL; + svr_cfg *svr = (svr_cfg*) ap_get_module_config + (cmd->server->module_config, &dbd_module); + + switch ((int) cmd->info) { + case cmd_name: + svr->name = val; + /* loading the driver involves once-only dlloading that is + * best done at server startup. This also guarantees that + * load_driver won't return an error later. + */ + switch (apr_dbd_get_driver(cmd->pool, svr->name, &driver)) { + case APR_ENOTIMPL: + return apr_psprintf(cmd->pool, "DBD: No driver for %s", svr->name); + case APR_EDSOOPEN: + return apr_psprintf(cmd->pool, + "DBD: Can't load driver file apr_dbd_%s.so", + svr->name); + case APR_ESYMNOTFOUND: + return apr_psprintf(cmd->pool, + "DBD: Failed to load driver apr_dbd_%s_driver", + svr->name); + } + break; + case cmd_params: + svr->params = val; + break; + case cmd_persist: + ISINT(val); + svr->persist = atoi(val); + break; +#if APR_HAS_THREADS + case cmd_min: + ISINT(val); + svr->nmin = atoi(val); + break; + case cmd_keep: + ISINT(val); + svr->nkeep = atoi(val); + break; + case cmd_max: + ISINT(val); + svr->nmax = atoi(val); + break; + case cmd_exp: + ISINT(val); + svr->exptime = atoi(val); + break; +#endif + } + return NULL; +} +static const char *dbd_prepare(cmd_parms *cmd, void *cfg, const char *query, + const char *label) +{ + svr_cfg *svr = (svr_cfg*) ap_get_module_config + (cmd->server->module_config, &dbd_module); + dbd_prepared *prepared = apr_pcalloc(cmd->pool, sizeof(dbd_prepared)); + prepared->label = label; + prepared->query = query; + prepared->next = svr->prepared; + svr->prepared = prepared; + return NULL; +} +static const command_rec dbd_cmds[] = { + AP_INIT_TAKE1("DBDriver", dbd_param, (void*)cmd_name, RSRC_CONF, + "SQL Driver"), + AP_INIT_TAKE1("DBDParams", dbd_param, (void*)cmd_params, RSRC_CONF, + "SQL Driver Params"), + AP_INIT_TAKE1("DBDPersist", dbd_param, (void*)cmd_persist, RSRC_CONF, + "Use persistent connection/pool"), + AP_INIT_TAKE2("DBDPrepareSQL", dbd_prepare, NULL, RSRC_CONF, + "Prepared SQL statement, label"), +#if APR_HAS_THREADS + AP_INIT_TAKE1("DBDMin", dbd_param, (void*)cmd_min, RSRC_CONF, + "Minimum number of connections"), + AP_INIT_TAKE1("DBDKeep", dbd_param, (void*)cmd_keep, RSRC_CONF, + "Maximum number of sustained connections"), + AP_INIT_TAKE1("DBDMax", dbd_param, (void*)cmd_max, RSRC_CONF, + "Maximum number of connections"), + AP_INIT_TAKE1("DBDExptime", dbd_param, (void*)cmd_exp, RSRC_CONF, + "Keepalive time for idle connections"), +#endif + {NULL} +}; +#define COND_PARAM(x,val) \ + if (cfg->x == val) { \ + cfg->x = ((svr_cfg*)base)->x; \ + } +#define COND_PARAM0(x) COND_PARAM(x,0) +#define COND_PARAM1(x) COND_PARAM(x,-1) +static void *dbd_merge(apr_pool_t *pool, void *base, void *add) { + svr_cfg *cfg = apr_pmemdup(pool, add, sizeof(svr_cfg)); + COND_PARAM0(name); + COND_PARAM0(params); + COND_PARAM1(persist); +#if APR_HAS_THREADS + COND_PARAM0(nmin); + COND_PARAM0(nkeep); + COND_PARAM0(nmax); + COND_PARAM0(exptime); +#endif + return cfg; +} +#undef COND_PARAM +#undef COND_PARAM0 +#undef COND_PARAM1 +static void *dbd_cfg(apr_pool_t *p, server_rec *x) +{ + svr_cfg *svr = (svr_cfg*) apr_pcalloc(p, sizeof(svr_cfg)); + svr->persist = -1; + return svr; +} +static apr_status_t dbd_prepared_init(apr_pool_t *pool, svr_cfg *svr, + ap_dbd_t *dbd) +{ + dbd_prepared *p; + apr_status_t ret = APR_SUCCESS; + apr_dbd_prepared_t *stmt = NULL; + dbd->prepared = apr_hash_make(pool); + + for (p = svr->prepared; p; p = p->next) { + if (apr_dbd_prepare(dbd->driver, pool, dbd->handle, p->query, + p->label, &stmt) == 0) { + apr_hash_set(dbd->prepared, p->label, APR_HASH_KEY_STRING, stmt); + } + else { + ret = APR_EGENERAL; + } + } + return ret; +} +#if APR_HAS_THREADS +/************ svr cfg: manage db connection pool ****************/ +/* an apr_reslist_constructor for SQL connections */ +static apr_status_t dbd_construct(void **db, void *params, apr_pool_t *pool) +{ + svr_cfg *svr = (svr_cfg*) params; + ap_dbd_t *rec = apr_pcalloc(pool, sizeof(ap_dbd_t)); + apr_status_t rv = apr_dbd_get_driver(pool, svr->name, &rec->driver); + + rv = apr_dbd_open(rec->driver, pool, svr->params, &rec->handle); + switch (rv) { + case APR_EGENERAL: + ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, + "DBD: Can't connect to %s[%s]", svr->name, svr->params); + return rv; + } + *db = rec; + dbd_prepared_init(pool, svr, rec); + return rv; +} +static apr_status_t dbd_destruct(void *sql, void *params, apr_pool_t *pool) +{ + ap_dbd_t *rec = sql; + return apr_dbd_close(rec->driver, rec->handle); +} + +static apr_status_t dbd_setup(apr_pool_t *pool, server_rec *s) +{ + svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); + apr_status_t rv = apr_reslist_create(&svr->dbpool, svr->nmin, svr->nkeep, + svr->nmax, svr->exptime, + dbd_construct, dbd_destruct, + svr, pool); + if (rv == APR_SUCCESS) { + apr_pool_cleanup_register(pool, svr->dbpool, + (void*)apr_reslist_destroy, + apr_pool_cleanup_null); + } + else { + ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, + "DBD Pool: failed to initialise"); + } + return rv; +} + +#endif + + +/* Functions we export for modules to use: + - open acquires a connection from the pool (opens one if necessary) + - close releases it back in to the pool +*/ + +#if APR_HAS_THREADS +ap_dbd_t* ap_dbd_open(apr_pool_t *pool, server_rec *s) +{ + ap_dbd_t *rec = NULL; + svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); + apr_status_t rv; + const char *errmsg; + + if (!svr->persist) { + rec = apr_pcalloc(pool, sizeof(ap_dbd_t)); + rv = apr_dbd_get_driver(pool, svr->name, &rec->driver); + + rv = apr_dbd_open(rec->driver, pool, svr->params, &rec->handle); + switch (rv) { + case APR_EGENERAL: + ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, + "DBD: Can't connect to %s[%s]", + svr->name, svr->params); + return NULL; + } + dbd_prepared_init(pool, svr, rec); + return rec; + } + + if (!svr->dbpool) { + if (dbd_setup(s->process->pool, s) != APR_SUCCESS) { + return NULL; + } + } + if (apr_reslist_acquire(svr->dbpool, (void**)&rec) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool, + "Failed to acquire DBD connection from pool!"); + return NULL; + } + if (apr_dbd_check_conn(rec->driver, pool, rec->handle) != APR_SUCCESS) { + errmsg = apr_dbd_error(rec->driver, rec->handle, rv); + if (!errmsg) { + errmsg = "(unknown)"; + } + ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool, + "DBD[%s] Error: %s", svr->name, errmsg ); + apr_reslist_invalidate(svr->dbpool, rec); + return NULL; + } + return rec; +} +#else +ap_dbd_t* ap_dbd_open(apr_pool_t *pool, server_rec *s) +{ + apr_status_t rv; + const char *errmsg; + ap_dbd_t *rec = NULL; + svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); + + if (!svr->persist) { + rec = apr_pcalloc(pool, sizeof(ap_dbd_t)); + rv = apr_dbd_get_driver(pool, svr->name, &rec->driver); + + rv = apr_dbd_open(rec->driver, pool, svr->params, &rec->handle); + switch (rv) { + case APR_EGENERAL: + ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, + "DBD: Can't connect to %s[%s]", + svr->name, svr->params); + return NULL; + } + dbd_prepared_init(pool, svr, rec); + return rec; + } +/* since we're in nothread-land, we can mess with svr->conn with impunity */ + if (svr->conn) { + if (apr_dbd_check_conn(svr->conn->driver, pool, svr->conn->handle) != 0){ + errmsg = apr_dbd_error(rec->driver, rec->handle, rv); + if (!errmsg) { + errmsg = "(unknown)"; + } + ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool, + "DBD[%s] Error: %s", svr->name, errmsg); + svr->conn = NULL; + } + } + if (!svr->conn) { + svr->conn = apr_pcalloc(pool, sizeof(ap_dbd_t)); + rv = apr_dbd_get_driver(pool, svr->name, &svr->conn->driver); + + rv = apr_dbd_open(svr->conn->driver, pool, svr->params, + &svr->conn->handle); + switch (rv) { + case APR_EGENERAL: + ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, pool, + "DBD: Can't connect to %s[%s]", + svr->name, svr->params); + return NULL; + } + dbd_prepared_init(pool, svr, rec); + } + return svr->conn; +} +#endif +void ap_dbd_close(server_rec *s, ap_dbd_t *sql) +{ + svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); + if (!svr->persist) { + apr_dbd_close(sql->driver, sql->handle); + } +#if APR_HAS_THREADS + else { + apr_reslist_release(svr->dbpool, sql); + } +#endif +} +#if APR_HAS_THREADS +typedef struct { + ap_dbd_t *conn; + apr_reslist_t *dbpool; +} dbd_pool_rec; +static apr_status_t dbd_release(void *REQ) +{ + dbd_pool_rec *req = REQ; + apr_reslist_release(req->dbpool, req->conn); + return APR_SUCCESS; +} +ap_dbd_t *ap_dbd_acquire(request_rec *r) +{ + svr_cfg *svr; + dbd_pool_rec *req = ap_get_module_config(r->request_config, &dbd_module); + if (!req) { + req = apr_palloc(r->pool, sizeof(dbd_pool_rec)); + req->conn = ap_dbd_open(r->pool, r->server); + if (req->conn) { + svr = ap_get_module_config(r->server->module_config, &dbd_module); + ap_set_module_config(r->request_config, &dbd_module, req); + if (svr->persist) { + req->dbpool = svr->dbpool; + apr_pool_cleanup_register(r->pool, req, dbd_release, + apr_pool_cleanup_null); + } + else { + apr_pool_cleanup_register(r->pool, req->conn->handle, + (void*)req->conn->driver->close, + apr_pool_cleanup_null); + } + } + } + return req->conn; +} +#else +ap_dbd_t *ap_dbd_acquire(request_rec *r) +{ + svr_cfg *svr; + ap_dbd_t *ret = ap_get_module_config(r->request_config, &dbd_module); + if (!ret) { + svr = ap_get_module_config(r->server->module_config, &dbd_module); + ret = ap_dbd_open(r->pool, r->server); + if ( ret ) { + ap_set_module_config(r->request_config, &dbd_module, ret); + if (!svr->persist) { + apr_pool_cleanup_register(r->pool, svr->conn->handle, + (void*)svr->conn->driver->close, + apr_pool_cleanup_null); + } + /* if persist then dbd_open registered cleanup on proc pool */ + } + } + return ret; +} +#endif +static int dbd_token(apr_pool_t *pool, apr_pool_t *p0, + apr_pool_t *p1, server_rec *s) +{ + svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); + if (svr && svr->name) { + ap_add_version_component(pool, apr_psprintf(pool, "DBD:%s/%s", + svr->name, VERSION)); + } + else { + ap_add_version_component(pool, "DBD/" VERSION); + } + return OK; +} + +static void dbd_hooks(apr_pool_t *pool) +{ +#if APR_HAS_THREADS + ap_hook_child_init((void*)dbd_setup, NULL, NULL, APR_HOOK_MIDDLE); +#endif + ap_hook_post_config(dbd_token, NULL, NULL, APR_HOOK_MIDDLE); + APR_REGISTER_OPTIONAL_FN(ap_dbd_open); + APR_REGISTER_OPTIONAL_FN(ap_dbd_close); + APR_REGISTER_OPTIONAL_FN(ap_dbd_acquire); + apr_dbd_init(pool); +} + +module AP_MODULE_DECLARE_DATA dbd_module = { + STANDARD20_MODULE_STUFF, + NULL, + NULL, + dbd_cfg, + dbd_merge, + dbd_cmds, + dbd_hooks +}; diff --git a/trunk/modules/experimental/mod_dbd.h b/trunk/modules/experimental/mod_dbd.h new file mode 100644 index 0000000000..c0f975ab43 --- /dev/null +++ b/trunk/modules/experimental/mod_dbd.h @@ -0,0 +1,57 @@ +/* Copyright 2003-5 WebThing Ltd + * Copyright 2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Overview of what this is and does: + * http://www.apache.org/~niq/dbd.html + * or + * http://apache.webthing.com/database/ + */ +#ifndef DBD_H +#define DBD_H + +#include +#include +#include + +typedef struct { + apr_dbd_t *handle; + apr_dbd_driver_t *driver; + apr_hash_t *prepared; +} ap_dbd_t; + +/* Export functions to access the database */ + +/* acquire a connection that MUST be explicitly closed. + * Returns NULL on error + */ +AP_DECLARE(ap_dbd_t*) ap_dbd_open(apr_pool_t*, server_rec*); + +/* release a connection acquired with ap_dbd_open */ +AP_DECLARE(void) ap_dbd_close(server_rec*, ap_dbd_t*); + +/* acquire a connection that will have the lifetime of a request + * and MUST NOT be explicitly closed. Return NULL on error. + * This is the preferred function for most applications. + */ +AP_DECLARE(ap_dbd_t*) ap_dbd_acquire(request_rec*); + +/* Also export them as optional functions for modules that prefer it */ +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_open, (apr_pool_t*, server_rec*)); +APR_DECLARE_OPTIONAL_FN(void, ap_dbd_close, (server_rec*, ap_dbd_t*)); +APR_DECLARE_OPTIONAL_FN(ap_dbd_t*, ap_dbd_acquire, (request_rec*)); + +#endif diff --git a/trunk/modules/experimental/mod_example.c b/trunk/modules/experimental/mod_example.c new file mode 100644 index 0000000000..507c525032 --- /dev/null +++ b/trunk/modules/experimental/mod_example.c @@ -0,0 +1,1345 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Apache example module. Provide demonstrations of how modules do things. + * It is not meant to be used in a production server. Since it participates + * in all of the processing phases, it could conceivable interfere with + * the proper operation of other modules -- particularly the ones related + * to security. + * + * In the interest of brevity, all functions and structures internal to + * this module, but which may have counterparts in *real* modules, are + * prefixed with 'x_' instead of 'example_'. + * + * IMPORTANT NOTE + * ============== + * + * Some of the code in this module has problems. + * Before using it to base your work on, see + * + * http://issues.apache.org/bugzilla/show_bug.cgi?id=29709 + * http://issues.apache.org/bugzilla/show_bug.cgi?id=32051 + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "http_request.h" +#include "util_script.h" +#include "http_connection.h" + +#include "apr_strings.h" + +#include + +/*--------------------------------------------------------------------------*/ +/* */ +/* Data declarations. */ +/* */ +/* Here are the static cells and structure declarations private to our */ +/* module. */ +/* */ +/*--------------------------------------------------------------------------*/ + +/* + * Sample configuration record. Used for both per-directory and per-server + * configuration data. + * + * It's perfectly reasonable to have two different structures for the two + * different environments. The same command handlers will be called for + * both, though, so the handlers need to be able to tell them apart. One + * possibility is for both structures to start with an int which is 0 for + * one and 1 for the other. + * + * Note that while the per-directory and per-server configuration records are + * available to most of the module handlers, they should be treated as + * READ-ONLY by all except the command and merge handlers. Sometimes handlers + * are handed a record that applies to the current location by implication or + * inheritance, and modifying it will change the rules for other locations. + */ +typedef struct x_cfg { + int cmode; /* Environment to which record applies + * (directory, server, or combination). + */ +#define CONFIG_MODE_SERVER 1 +#define CONFIG_MODE_DIRECTORY 2 +#define CONFIG_MODE_COMBO 3 /* Shouldn't ever happen. */ + int local; /* Boolean: "Example" directive declared + * here? + */ + int congenital; /* Boolean: did we inherit an "Example"? */ + char *trace; /* Pointer to trace string. */ + char *loc; /* Location to which this record applies. */ +} x_cfg; + +/* + * Let's set up a module-local static cell to point to the accreting callback + * trace. As each API callback is made to us, we'll tack on the particulars + * to whatever we've already recorded. To avoid massive memory bloat as + * directories are walked again and again, we record the routine/environment + * the first time (non-request context only), and ignore subsequent calls for + * the same routine/environment. + */ +static const char *trace = NULL; +static apr_table_t *static_calls_made = NULL; + +/* + * To avoid leaking memory from pools other than the per-request one, we + * allocate a module-private pool, and then use a sub-pool of that which gets + * freed each time we modify the trace. That way previous layers of trace + * data don't get lost. + */ +static apr_pool_t *x_pool = NULL; +static apr_pool_t *x_subpool = NULL; + +/* + * Declare ourselves so the configuration routines can find and know us. + * We'll fill it in at the end of the module. + */ +module AP_MODULE_DECLARE_DATA example_module; + +/*--------------------------------------------------------------------------*/ +/* */ +/* The following pseudo-prototype declarations illustrate the parameters */ +/* passed to command handlers for the different types of directive */ +/* syntax. If an argument was specified in the directive definition */ +/* (look for "command_rec" below), it's available to the command handler */ +/* via the (void *) info field in the cmd_parms argument passed to the */ +/* handler (cmd->info for the examples below). */ +/* */ +/*--------------------------------------------------------------------------*/ + +/* + * Command handler for a NO_ARGS directive. Declared in the command_rec + * list with + * AP_INIT_NO_ARGS("directive", function, mconfig, where, help) + * + * static const char *handle_NO_ARGS(cmd_parms *cmd, void *mconfig); + */ + +/* + * Command handler for a RAW_ARGS directive. The "args" argument is the text + * of the commandline following the directive itself. Declared in the + * command_rec list with + * AP_INIT_RAW_ARGS("directive", function, mconfig, where, help) + * + * static const char *handle_RAW_ARGS(cmd_parms *cmd, void *mconfig, + * const char *args); + */ + +/* + * Command handler for a FLAG directive. The single parameter is passed in + * "bool", which is either zero or not for Off or On respectively. + * Declared in the command_rec list with + * AP_INIT_FLAG("directive", function, mconfig, where, help) + * + * static const char *handle_FLAG(cmd_parms *cmd, void *mconfig, int bool); + */ + +/* + * Command handler for a TAKE1 directive. The single parameter is passed in + * "word1". Declared in the command_rec list with + * AP_INIT_TAKE1("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE1(cmd_parms *cmd, void *mconfig, + * char *word1); + */ + +/* + * Command handler for a TAKE2 directive. TAKE2 commands must always have + * exactly two arguments. Declared in the command_rec list with + * AP_INIT_TAKE2("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE2(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2); + */ + +/* + * Command handler for a TAKE3 directive. Like TAKE2, these must have exactly + * three arguments, or the parser complains and doesn't bother calling us. + * Declared in the command_rec list with + * AP_INIT_TAKE3("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE3(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2, char *word3); + */ + +/* + * Command handler for a TAKE12 directive. These can take either one or two + * arguments. + * - word2 is a NULL pointer if no second argument was specified. + * Declared in the command_rec list with + * AP_INIT_TAKE12("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE12(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2); + */ + +/* + * Command handler for a TAKE123 directive. A TAKE123 directive can be given, + * as might be expected, one, two, or three arguments. + * - word2 is a NULL pointer if no second argument was specified. + * - word3 is a NULL pointer if no third argument was specified. + * Declared in the command_rec list with + * AP_INIT_TAKE123("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE123(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2, char *word3); + */ + +/* + * Command handler for a TAKE13 directive. Either one or three arguments are + * permitted - no two-parameters-only syntax is allowed. + * - word2 and word3 are NULL pointers if only one argument was specified. + * Declared in the command_rec list with + * AP_INIT_TAKE13("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE13(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2, char *word3); + */ + +/* + * Command handler for a TAKE23 directive. At least two and as many as three + * arguments must be specified. + * - word3 is a NULL pointer if no third argument was specified. + * Declared in the command_rec list with + * AP_INIT_TAKE23("directive", function, mconfig, where, help) + * + * static const char *handle_TAKE23(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2, char *word3); + */ + +/* + * Command handler for a ITERATE directive. + * - Handler is called once for each of n arguments given to the directive. + * - word1 points to each argument in turn. + * Declared in the command_rec list with + * AP_INIT_ITERATE("directive", function, mconfig, where, help) + * + * static const char *handle_ITERATE(cmd_parms *cmd, void *mconfig, + * char *word1); + */ + +/* + * Command handler for a ITERATE2 directive. + * - Handler is called once for each of the second and subsequent arguments + * given to the directive. + * - word1 is the same for each call for a particular directive instance (the + * first argument). + * - word2 points to each of the second and subsequent arguments in turn. + * Declared in the command_rec list with + * AP_INIT_ITERATE2("directive", function, mconfig, where, help) + * + * static const char *handle_ITERATE2(cmd_parms *cmd, void *mconfig, + * char *word1, char *word2); + */ + +/*--------------------------------------------------------------------------*/ +/* */ +/* These routines are strictly internal to this module, and support its */ +/* operation. They are not referenced by any external portion of the */ +/* server. */ +/* */ +/*--------------------------------------------------------------------------*/ + +/* + * Locate our directory configuration record for the current request. + */ +static x_cfg *our_dconfig(const request_rec *r) +{ + return (x_cfg *) ap_get_module_config(r->per_dir_config, &example_module); +} + +#if 0 +/* + * Locate our server configuration record for the specified server. + */ +static x_cfg *our_sconfig(const server_rec *s) +{ + return (x_cfg *) ap_get_module_config(s->module_config, &example_module); +} + +/* + * Likewise for our configuration record for the specified request. + */ +static x_cfg *our_rconfig(const request_rec *r) +{ + return (x_cfg *) ap_get_module_config(r->request_config, &example_module); +} +#endif + +/* + * Likewise for our configuration record for a connection. + */ +static x_cfg *our_cconfig(const conn_rec *c) +{ + return (x_cfg *) ap_get_module_config(c->conn_config, &example_module); +} + +/* + * This routine sets up some module-wide cells if they haven't been already. + */ +static void setup_module_cells(void) +{ + /* + * If we haven't already allocated our module-private pool, do so now. + */ + if (x_pool == NULL) { + apr_pool_create(&x_pool, NULL); + }; + /* + * Likewise for the table of routine/environment pairs we visit outside of + * request context. + */ + if (static_calls_made == NULL) { + static_calls_made = apr_table_make(x_pool, 16); + }; +} + +/* + * This routine is used to add a trace of a callback to the list. We're + * passed the server record (if available), the request record (if available), + * a pointer to our private configuration record (if available) for the + * environment to which the callback is supposed to apply, and some text. We + * turn this into a textual representation and add it to the tail of the list. + * The list can be displayed by the x_handler() routine. + * + * If the call occurs within a request context (i.e., we're passed a request + * record), we put the trace into the request apr_pool_t and attach it to the + * request via the notes mechanism. Otherwise, the trace gets added + * to the static (non-request-specific) list. + * + * Note that the r->notes table is only for storing strings; if you need to + * maintain per-request data of any other type, you need to use another + * mechanism. + */ + +#define TRACE_NOTE "example-trace" + +static void trace_add(server_rec *s, request_rec *r, x_cfg *mconfig, + const char *note) +{ + const char *sofar; + char *addon; + char *where; + apr_pool_t *p; + const char *trace_copy; + + /* + * Make sure our pools and tables are set up - we need 'em. + */ + setup_module_cells(); + /* + * Now, if we're in request-context, we use the request pool. + */ + if (r != NULL) { + p = r->pool; + if ((trace_copy = apr_table_get(r->notes, TRACE_NOTE)) == NULL) { + trace_copy = ""; + } + } + else { + /* + * We're not in request context, so the trace gets attached to our + * module-wide pool. We do the create/destroy every time we're called + * in non-request context; this avoids leaking memory in some of + * the subsequent calls that allocate memory only once (such as the + * key formation below). + * + * Make a new sub-pool and copy any existing trace to it. Point the + * trace cell at the copied value. + */ + apr_pool_create(&p, x_pool); + if (trace != NULL) { + trace = apr_pstrdup(p, trace); + } + /* + * Now, if we have a sub-pool from before, nuke it and replace with + * the one we just allocated. + */ + if (x_subpool != NULL) { + apr_pool_destroy(x_subpool); + } + x_subpool = p; + trace_copy = trace; + } + /* + * If we weren't passed a configuration record, we can't figure out to + * what location this call applies. This only happens for co-routines + * that don't operate in a particular directory or server context. If we + * got a valid record, extract the location (directory or server) to which + * it applies. + */ + where = (mconfig != NULL) ? mconfig->loc : "nowhere"; + where = (where != NULL) ? where : ""; + /* + * Now, if we're not in request context, see if we've been called with + * this particular combination before. The apr_table_t is allocated in the + * module's private pool, which doesn't get destroyed. + */ + if (r == NULL) { + char *key; + + key = apr_pstrcat(p, note, ":", where, NULL); + if (apr_table_get(static_calls_made, key) != NULL) { + /* + * Been here, done this. + */ + return; + } + else { + /* + * First time for this combination of routine and environment - + * log it so we don't do it again. + */ + apr_table_set(static_calls_made, key, "been here"); + } + } + addon = apr_pstrcat(p, + "
  • \n" + "
    \n" + "
    ", note, "
    \n" + "
    [", where, "]
    \n" + "
    \n" + "
  • \n", + NULL); + sofar = (trace_copy == NULL) ? "" : trace_copy; + trace_copy = apr_pstrcat(p, sofar, addon, NULL); + if (r != NULL) { + apr_table_set(r->notes, TRACE_NOTE, trace_copy); + } + else { + trace = trace_copy; + } + /* + * You *could* change the following if you wanted to see the calling + * sequence reported in the server's error_log, but beware - almost all of + * these co-routines are called for every single request, and the impact + * on the size (and readability) of the error_log is considerable. + */ +#define EXAMPLE_LOG_EACH 0 + if (EXAMPLE_LOG_EACH && (s != NULL)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_example: %s", note); + } +} + +/*--------------------------------------------------------------------------*/ +/* We prototyped the various syntax for command handlers (routines that */ +/* are called when the configuration parser detects a directive declared */ +/* by our module) earlier. Now we actually declare a "real" routine that */ +/* will be invoked by the parser when our "real" directive is */ +/* encountered. */ +/* */ +/* If a command handler encounters a problem processing the directive, it */ +/* signals this fact by returning a non-NULL pointer to a string */ +/* describing the problem. */ +/* */ +/* The magic return value DECLINE_CMD is used to deal with directives */ +/* that might be declared by multiple modules. If the command handler */ +/* returns NULL, the directive was processed; if it returns DECLINE_CMD, */ +/* the next module (if any) that declares the directive is given a chance */ +/* at it. If it returns any other value, it's treated as the text of an */ +/* error message. */ +/*--------------------------------------------------------------------------*/ +/* + * Command handler for the NO_ARGS "Example" directive. All we do is mark the + * call in the trace log, and flag the applicability of the directive to the + * current location in that location's configuration record. + */ +static const char *cmd_example(cmd_parms *cmd, void *mconfig) +{ + x_cfg *cfg = (x_cfg *) mconfig; + + /* + * "Example Wuz Here" + */ + cfg->local = 1; + trace_add(cmd->server, NULL, cfg, "cmd_example()"); + return NULL; +} + +/*--------------------------------------------------------------------------*/ +/* */ +/* Now we declare our content handlers, which are invoked when the server */ +/* encounters a document which our module is supposed to have a chance to */ +/* see. (See mod_mime's SetHandler and AddHandler directives, and the */ +/* mod_info and mod_status examples, for more details.) */ +/* */ +/* Since content handlers are dumping data directly into the connection */ +/* (using the r*() routines, such as rputs() and rprintf()) without */ +/* intervention by other parts of the server, they need to make */ +/* sure any accumulated HTTP headers are sent first. This is done by */ +/* calling send_http_header(). Otherwise, no header will be sent at all, */ +/* and the output sent to the client will actually be HTTP-uncompliant. */ +/*--------------------------------------------------------------------------*/ +/* + * Sample content handler. All this does is display the call list that has + * been built up so far. + * + * The return value instructs the caller concerning what happened and what to + * do next: + * OK ("we did our thing") + * DECLINED ("this isn't something with which we want to get involved") + * HTTP_mumble ("an error status should be reported") + */ +static int x_handler(request_rec *r) +{ + x_cfg *dcfg; + + if (strcmp(r->handler, "example-handler")) { + return DECLINED; + } + + dcfg = our_dconfig(r); + trace_add(r->server, r, dcfg, "x_handler()"); + /* + * We're about to start sending content, so we need to force the HTTP + * headers to be sent at this point. Otherwise, no headers will be sent + * at all. We can set any we like first, of course. **NOTE** Here's + * where you set the "Content-type" header, and you do so by putting it in + * r->content_type, *not* r->headers_out("Content-type"). If you don't + * set it, it will be filled in with the server's default type (typically + * "text/plain"). You *must* also ensure that r->content_type is lower + * case. + * + * We also need to start a timer so the server can know if the connexion + * is broken. + */ + ap_set_content_type(r, "text/html"); + /* + * If we're only supposed to send header information (HEAD request), we're + * already there. + */ + if (r->header_only) { + return OK; + } + + /* + * Now send our actual output. Since we tagged this as being + * "text/html", we need to embed any HTML. + */ + ap_rputs(DOCTYPE_HTML_3_2, r); + ap_rputs("\n", r); + ap_rputs(" \n", r); + ap_rputs(" mod_example Module Content-Handler Output\n", r); + ap_rputs(" \n", r); + ap_rputs(" \n", r); + ap_rputs(" \n", r); + ap_rputs("

    mod_example Module Content-Handler Output\n", r); + ap_rputs("

    \n", r); + ap_rputs("

    \n", r); + ap_rprintf(r, " Apache HTTP Server version: \"%s\"\n", + ap_get_server_version()); + ap_rputs("
    \n", r); + ap_rprintf(r, " Server built: \"%s\"\n", ap_get_server_built()); + ap_rputs("

    \n", r);; + ap_rputs("

    \n", r); + ap_rputs(" The format for the callback trace is:\n", r); + ap_rputs("

    \n", r); + ap_rputs("
    \n", r); + ap_rputs("
    n.<routine-name>", r); + ap_rputs("(<routine-data>)\n", r); + ap_rputs("
    \n", r); + ap_rputs("
    [<applies-to>]\n", r); + ap_rputs("
    \n", r); + ap_rputs("
    \n", r); + ap_rputs("

    \n", r); + ap_rputs(" The <routine-data> is supplied by\n", r); + ap_rputs(" the routine when it requests the trace,\n", r); + ap_rputs(" and the <applies-to> is extracted\n", r); + ap_rputs(" from the configuration record at the time of the trace.\n", r); + ap_rputs(" SVR() indicates a server environment\n", r); + ap_rputs(" (blank means the main or default server, otherwise it's\n", r); + ap_rputs(" the name of the VirtualHost); DIR()\n", r); + ap_rputs(" indicates a location in the URL or filesystem\n", r); + ap_rputs(" namespace.\n", r); + ap_rputs("

    \n", r); + ap_rprintf(r, "

    Static callbacks so far:

    \n
      \n%s
    \n", + trace); + ap_rputs("

    Request-specific callbacks so far:

    \n", r); + ap_rprintf(r, "
      \n%s
    \n", apr_table_get(r->notes, TRACE_NOTE)); + ap_rputs("

    Environment for this call:

    \n", r); + ap_rputs("
      \n", r); + ap_rprintf(r, "
    • Applies-to: %s\n
    • \n", dcfg->loc); + ap_rprintf(r, "
    • \"Example\" directive declared here: %s\n
    • \n", + (dcfg->local ? "YES" : "NO")); + ap_rprintf(r, "
    • \"Example\" inherited: %s\n
    • \n", + (dcfg->congenital ? "YES" : "NO")); + ap_rputs("
    \n", r); + ap_rputs(" \n", r); + ap_rputs("\n", r); + /* + * We're all done, so cancel the timeout we set. Since this is probably + * the end of the request we *could* assume this would be done during + * post-processing - but it's possible that another handler might be + * called and inherit our outstanding timer. Not good; to each its own. + */ + /* + * We did what we wanted to do, so tell the rest of the server we + * succeeded. + */ + return OK; +} + +/*--------------------------------------------------------------------------*/ +/* */ +/* Now let's declare routines for each of the callback phase in order. */ +/* (That's the order in which they're listed in the callback list, *not */ +/* the order in which the server calls them! See the command_rec */ +/* declaration near the bottom of this file.) Note that these may be */ +/* called for situations that don't relate primarily to our function - in */ +/* other words, the fixup handler shouldn't assume that the request has */ +/* to do with "example" stuff. */ +/* */ +/* With the exception of the content handler, all of our routines will be */ +/* called for each request, unless an earlier handler from another module */ +/* aborted the sequence. */ +/* */ +/* Handlers that are declared as "int" can return the following: */ +/* */ +/* OK Handler accepted the request and did its thing with it. */ +/* DECLINED Handler took no action. */ +/* HTTP_mumble Handler looked at request and found it wanting. */ +/* */ +/* What the server does after calling a module handler depends upon the */ +/* handler's return value. In all cases, if the handler returns */ +/* DECLINED, the server will continue to the next module with an handler */ +/* for the current phase. However, if the handler return a non-OK, */ +/* non-DECLINED status, the server aborts the request right there. If */ +/* the handler returns OK, the server's next action is phase-specific; */ +/* see the individual handler comments below for details. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* + * This function is called during server initialisation. Any information + * that needs to be recorded must be in static cells, since there's no + * configuration record. + * + * There is no return value. + */ + +/* + * This function is called when an heavy-weight process (such as a child) is + * being run down or destroyed. As with the child initialisation function, + * any information that needs to be recorded must be in static cells, since + * there's no configuration record. + * + * There is no return value. + */ + +/* + * This function is called during server initialisation when an heavy-weight + * process (such as a child) is being initialised. As with the + * module initialisation function, any information that needs to be recorded + * must be in static cells, since there's no configuration record. + * + * There is no return value. + */ + +/* + * This function gets called to create a per-directory configuration + * record. This will be called for the "default" server environment, and for + * each directory for which the parser finds any of our directives applicable. + * If a directory doesn't have any of our directives involved (i.e., they + * aren't in the .htaccess file, or a , , or related + * block), this routine will *not* be called - the configuration for the + * closest ancestor is used. + * + * The return value is a pointer to the created module-specific + * structure. + */ +static void *x_create_dir_config(apr_pool_t *p, char *dirspec) +{ + x_cfg *cfg; + char *dname = dirspec; + + /* + * Allocate the space for our record from the pool supplied. + */ + cfg = (x_cfg *) apr_pcalloc(p, sizeof(x_cfg)); + /* + * Now fill in the defaults. If there are any `parent' configuration + * records, they'll get merged as part of a separate callback. + */ + cfg->local = 0; + cfg->congenital = 0; + cfg->cmode = CONFIG_MODE_DIRECTORY; + /* + * Finally, add our trace to the callback list. + */ + dname = (dname != NULL) ? dname : ""; + cfg->loc = apr_pstrcat(p, "DIR(", dname, ")", NULL); + trace_add(NULL, NULL, cfg, "x_create_dir_config()"); + return (void *) cfg; +} + +/* + * This function gets called to merge two per-directory configuration + * records. This is typically done to cope with things like .htaccess files + * or directives for directories that are beneath one for which a + * configuration record was already created. The routine has the + * responsibility of creating a new record and merging the contents of the + * other two into it appropriately. If the module doesn't declare a merge + * routine, the record for the closest ancestor location (that has one) is + * used exclusively. + * + * The routine MUST NOT modify any of its arguments! + * + * The return value is a pointer to the created module-specific structure + * containing the merged values. + */ +static void *x_merge_dir_config(apr_pool_t *p, void *parent_conf, + void *newloc_conf) +{ + + x_cfg *merged_config = (x_cfg *) apr_pcalloc(p, sizeof(x_cfg)); + x_cfg *pconf = (x_cfg *) parent_conf; + x_cfg *nconf = (x_cfg *) newloc_conf; + char *note; + + /* + * Some things get copied directly from the more-specific record, rather + * than getting merged. + */ + merged_config->local = nconf->local; + merged_config->loc = apr_pstrdup(p, nconf->loc); + /* + * Others, like the setting of the `congenital' flag, get ORed in. The + * setting of that particular flag, for instance, is TRUE if it was ever + * true anywhere in the upstream configuration. + */ + merged_config->congenital = (pconf->congenital | pconf->local); + /* + * If we're merging records for two different types of environment (server + * and directory), mark the new record appropriately. Otherwise, inherit + * the current value. + */ + merged_config->cmode = + (pconf->cmode == nconf->cmode) ? pconf->cmode : CONFIG_MODE_COMBO; + /* + * Now just record our being called in the trace list. Include the + * locations we were asked to merge. + */ + note = apr_pstrcat(p, "x_merge_dir_config(\"", pconf->loc, "\",\"", + nconf->loc, "\")", NULL); + trace_add(NULL, NULL, merged_config, note); + return (void *) merged_config; +} + +/* + * This function gets called to create a per-server configuration + * record. It will always be called for the "default" server. + * + * The return value is a pointer to the created module-specific + * structure. + */ +static void *x_create_server_config(apr_pool_t *p, server_rec *s) +{ + + x_cfg *cfg; + char *sname = s->server_hostname; + + /* + * As with the x_create_dir_config() reoutine, we allocate and fill + * in an empty record. + */ + cfg = (x_cfg *) apr_pcalloc(p, sizeof(x_cfg)); + cfg->local = 0; + cfg->congenital = 0; + cfg->cmode = CONFIG_MODE_SERVER; + /* + * Note that we were called in the trace list. + */ + sname = (sname != NULL) ? sname : ""; + cfg->loc = apr_pstrcat(p, "SVR(", sname, ")", NULL); + trace_add(s, NULL, cfg, "x_create_server_config()"); + return (void *) cfg; +} + +/* + * This function gets called to merge two per-server configuration + * records. This is typically done to cope with things like virtual hosts and + * the default server configuration The routine has the responsibility of + * creating a new record and merging the contents of the other two into it + * appropriately. If the module doesn't declare a merge routine, the more + * specific existing record is used exclusively. + * + * The routine MUST NOT modify any of its arguments! + * + * The return value is a pointer to the created module-specific structure + * containing the merged values. + */ +static void *x_merge_server_config(apr_pool_t *p, void *server1_conf, + void *server2_conf) +{ + + x_cfg *merged_config = (x_cfg *) apr_pcalloc(p, sizeof(x_cfg)); + x_cfg *s1conf = (x_cfg *) server1_conf; + x_cfg *s2conf = (x_cfg *) server2_conf; + char *note; + + /* + * Our inheritance rules are our own, and part of our module's semantics. + * Basically, just note whence we came. + */ + merged_config->cmode = + (s1conf->cmode == s2conf->cmode) ? s1conf->cmode : CONFIG_MODE_COMBO; + merged_config->local = s2conf->local; + merged_config->congenital = (s1conf->congenital | s1conf->local); + merged_config->loc = apr_pstrdup(p, s2conf->loc); + /* + * Trace our call, including what we were asked to merge. + */ + note = apr_pstrcat(p, "x_merge_server_config(\"", s1conf->loc, "\",\"", + s2conf->loc, "\")", NULL); + trace_add(NULL, NULL, merged_config, note); + return (void *) merged_config; +} + +/* + * This routine is called before the server processes the configuration + * files. There is no return value. + */ +static int x_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + /* + * Log the call and exit. + */ + trace_add(NULL, NULL, NULL, "x_pre_config()"); + + return OK; +} + +/* + * This routine is called to perform any module-specific fixing of header + * fields, et cetera. It is invoked just before any content-handler. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static int x_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* + * Log the call and exit. + */ + trace_add(NULL, NULL, NULL, "x_post_config()"); + return OK; +} + +/* + * This routine is called to perform any module-specific log file + * openings. It is invoked just before the post_config phase + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static int x_open_logs(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + /* + * Log the call and exit. + */ + trace_add(s, NULL, NULL, "x_open_logs()"); + return OK; +} + +/* + * All our process-death routine does is add its trace to the log. + */ +static apr_status_t x_child_exit(void *data) +{ + char *note; + server_rec *s = data; + char *sname = s->server_hostname; + + /* + * The arbitrary text we add to our trace entry indicates for which server + * we're being called. + */ + sname = (sname != NULL) ? sname : ""; + note = apr_pstrcat(s->process->pool, "x_child_exit(", sname, ")", NULL); + trace_add(s, NULL, NULL, note); + return APR_SUCCESS; +} + +/* + * All our process initialiser does is add its trace to the log. + */ +static void x_child_init(apr_pool_t *p, server_rec *s) +{ + char *note; + char *sname = s->server_hostname; + + /* + * Set up any module cells that ought to be initialised. + */ + setup_module_cells(); + /* + * The arbitrary text we add to our trace entry indicates for which server + * we're being called. + */ + sname = (sname != NULL) ? sname : ""; + note = apr_pstrcat(p, "x_child_init(", sname, ")", NULL); + trace_add(s, NULL, NULL, note); + + apr_pool_cleanup_register(p, s, x_child_exit, x_child_exit); +} + +/* + * XXX: This routine is called XXX + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +#if 0 +static const char *x_http_scheme(const request_rec *r) +{ + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and exit. + */ + trace_add(r->server, NULL, cfg, "x_http_scheme()"); + return "example"; +} + +/* + * XXX: This routine is called XXX + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static apr_port_t x_default_port(const request_rec *r) +{ + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and exit. + */ + trace_add(r->server, NULL, cfg, "x_default_port()"); + return 80; +} +#endif /*0*/ + +/* + * XXX: This routine is called XXX + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static void x_insert_filter(request_rec *r) +{ + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and exit. + */ + trace_add(r->server, NULL, cfg, "x_insert_filter()"); +} + +/* + * XXX: This routine is called XXX + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static int x_quick_handler(request_rec *r, int lookup_uri) +{ + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and exit. + */ + trace_add(r->server, NULL, cfg, "x_quick_handler()"); + return DECLINED; +} + +/* + * This routine is called just after the server accepts the connection, + * but before it is handed off to a protocol module to be served. The point + * of this hook is to allow modules an opportunity to modify the connection + * as soon as possible. The core server uses this phase to setup the + * connection record based on the type of connection that is being used. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static int x_pre_connection(conn_rec *c, void *csd) +{ + x_cfg *cfg; + + cfg = our_cconfig(c); +#if 0 + /* + * Log the call and exit. + */ + trace_add(r->server, NULL, cfg, "x_pre_connection()"); +#endif + return OK; +} + +/* This routine is used to actually process the connection that was received. + * Only protocol modules should implement this hook, as it gives them an + * opportunity to replace the standard HTTP processing with processing for + * some other protocol. Both echo and POP3 modules are available as + * examples. + * + * The return VALUE is OK, DECLINED, or HTTP_mumble. If we return OK, no + * further modules are called for this phase. + */ +static int x_process_connection(conn_rec *c) +{ + return DECLINED; +} + +/* + * This routine is called after the request has been read but before any other + * phases have been processed. This allows us to make decisions based upon + * the input header fields. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no + * further modules are called for this phase. + */ +static int x_post_read_request(request_rec *r) +{ + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * We don't actually *do* anything here, except note the fact that we were + * called. + */ + trace_add(r->server, r, cfg, "x_post_read_request()"); + return DECLINED; +} + +/* + * This routine gives our module an opportunity to translate the URI into an + * actual filename. If we don't do anything special, the server's default + * rules (Alias directives and the like) will continue to be followed. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no + * further modules are called for this phase. + */ +static int x_translate_handler(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * We don't actually *do* anything here, except note the fact that we were + * called. + */ + trace_add(r->server, r, cfg, "x_translate_handler()"); + return DECLINED; +} + +/* + * This routine maps r->filename to a physical file on disk. Useful for + * overriding default core behavior, including skipping mapping for + * requests that are not file based. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no + * further modules are called for this phase. + */ +static int x_map_to_storage_handler(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * We don't actually *do* anything here, except note the fact that we were + * called. + */ + trace_add(r->server, r, cfg, "x_map_to_storage_handler()"); + return DECLINED; +} + +/* + * this routine gives our module another chance to examine the request + * headers and to take special action. This is the first phase whose + * hooks' configuration directives can appear inside the + * and similar sections, because at this stage the URI has been mapped + * to the filename. For example this phase can be used to block evil + * clients, while little resources were wasted on these. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, + * the server will still call any remaining modules with an handler + * for this phase. + */ +static int x_header_parser_handler(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * We don't actually *do* anything here, except note the fact that we were + * called. + */ + trace_add(r->server, r, cfg, "header_parser_handler()"); + return DECLINED; +} + + +/* + * This routine is called to check the authentication information sent with + * the request (such as looking up the user in a database and verifying that + * the [encrypted] password sent matches the one in the database). + * + * The return value is OK, DECLINED, or some HTTP_mumble error (typically + * HTTP_UNAUTHORIZED). If we return OK, no other modules are given a chance + * at the request during this phase. + */ +static int x_check_user_id(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Don't do anything except log the call. + */ + trace_add(r->server, r, cfg, "x_check_user_id()"); + return DECLINED; +} + +/* + * This routine is called to check to see if the resource being requested + * requires authorisation. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no + * other modules are called during this phase. + * + * If *all* modules return DECLINED, the request is aborted with a server + * error. + */ +static int x_auth_checker(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and return OK, or access will be denied (even though we + * didn't actually do anything). + */ + trace_add(r->server, r, cfg, "x_auth_checker()"); + return DECLINED; +} + +/* + * This routine is called to check for any module-specific restrictions placed + * upon the requested resource. (See the mod_access module for an example.) + * + * The return value is OK, DECLINED, or HTTP_mumble. All modules with an + * handler for this phase are called regardless of whether their predecessors + * return OK or DECLINED. The first one to return any other status, however, + * will abort the sequence (and the request) as usual. + */ +static int x_access_checker(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + trace_add(r->server, r, cfg, "x_access_checker()"); + return DECLINED; +} + +/* + * This routine is called to determine and/or set the various document type + * information bits, like Content-type (via r->content_type), language, et + * cetera. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, no + * further modules are given a chance at the request for this phase. + */ +static int x_type_checker(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call, but don't do anything else - and report truthfully that + * we didn't do anything. + */ + trace_add(r->server, r, cfg, "x_type_checker()"); + return DECLINED; +} + +/* + * This routine is called to perform any module-specific fixing of header + * fields, et cetera. It is invoked just before any content-handler. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, the + * server will still call any remaining modules with an handler for this + * phase. + */ +static int x_fixer_upper(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + /* + * Log the call and exit. + */ + trace_add(r->server, r, cfg, "x_fixer_upper()"); + return OK; +} + +/* + * This routine is called to perform any module-specific logging activities + * over and above the normal server things. + * + * The return value is OK, DECLINED, or HTTP_mumble. If we return OK, any + * remaining modules with an handler for this phase will still be called. + */ +static int x_logger(request_rec *r) +{ + + x_cfg *cfg; + + cfg = our_dconfig(r); + trace_add(r->server, r, cfg, "x_logger()"); + return DECLINED; +} + +/*--------------------------------------------------------------------------*/ +/* */ +/* Which functions are responsible for which hooks in the server. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* + * Each function our module provides to handle a particular hook is + * specified here. The functions are registered using + * ap_hook_foo(name, predecessors, successors, position) + * where foo is the name of the hook. + * + * The args are as follows: + * name -> the name of the function to call. + * predecessors -> a list of modules whose calls to this hook must be + * invoked before this module. + * successors -> a list of modules whose calls to this hook must be + * invoked after this module. + * position -> The relative position of this module. One of + * APR_HOOK_FIRST, APR_HOOK_MIDDLE, or APR_HOOK_LAST. + * Most modules will use APR_HOOK_MIDDLE. If multiple + * modules use the same relative position, Apache will + * determine which to call first. + * If your module relies on another module to run first, + * or another module running after yours, use the + * predecessors and/or successors. + * + * The number in brackets indicates the order in which the routine is called + * during request processing. Note that not all routines are necessarily + * called (such as if a resource doesn't have access restrictions). + * The actual delivery of content to the browser [9] is not handled by + * a hook; see the handler declarations below. + */ +static void x_register_hooks(apr_pool_t *p) +{ + ap_hook_pre_config(x_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(x_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_open_logs(x_open_logs, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(x_child_init, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_handler(x_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_quick_handler(x_quick_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_connection(x_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_process_connection(x_process_connection, NULL, NULL, APR_HOOK_MIDDLE); + /* [1] post read_request handling */ + ap_hook_post_read_request(x_post_read_request, NULL, NULL, + APR_HOOK_MIDDLE); + ap_hook_log_transaction(x_logger, NULL, NULL, APR_HOOK_MIDDLE); +#if 0 + ap_hook_http_scheme(x_http_scheme, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_default_port(x_default_port, NULL, NULL, APR_HOOK_MIDDLE); +#endif + ap_hook_translate_name(x_translate_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_map_to_storage(x_map_to_storage_handler, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_header_parser(x_header_parser_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_check_user_id(x_check_user_id, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_fixups(x_fixer_upper, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_type_checker(x_type_checker, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_access_checker(x_access_checker, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_auth_checker(x_auth_checker, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter(x_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); +} + +/*--------------------------------------------------------------------------*/ +/* */ +/* All of the routines have been declared now. Here's the list of */ +/* directives specific to our module, and information about where they */ +/* may appear and how the command parser should pass them to us for */ +/* processing. Note that care must be taken to ensure that there are NO */ +/* collisions of directive names between modules. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* + * List of directives specific to our module. + */ +static const command_rec x_cmds[] = +{ + AP_INIT_NO_ARGS( + "Example", /* directive name */ + cmd_example, /* config action routine */ + NULL, /* argument to include in call */ + OR_OPTIONS, /* where available */ + "Example directive - no arguments" /* directive description */ + ), + {NULL} +}; +/*--------------------------------------------------------------------------*/ +/* */ +/* Finally, the list of callback routines and data structures that provide */ +/* the static hooks into our module from the other parts of the server. */ +/* */ +/*--------------------------------------------------------------------------*/ +/* + * Module definition for configuration. If a particular callback is not + * needed, replace its routine name below with the word NULL. + */ +module AP_MODULE_DECLARE_DATA example_module = +{ + STANDARD20_MODULE_STUFF, + x_create_dir_config, /* per-directory config creator */ + x_merge_dir_config, /* dir config merger */ + x_create_server_config, /* server config creator */ + x_merge_server_config, /* server config merger */ + x_cmds, /* command table */ + x_register_hooks, /* set up other request processing hooks */ +}; diff --git a/trunk/modules/experimental/mod_filter.c b/trunk/modules/experimental/mod_filter.c new file mode 100644 index 0000000000..dbaad2db24 --- /dev/null +++ b/trunk/modules/experimental/mod_filter.c @@ -0,0 +1,848 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Originally contributed by Nick Kew + * + * At the time of writing, this is designed primarily for use with + * httpd 2.2, but is also back-compatible with 2.0. It is likely + * that the 2.0 and 2.2 versions may diverge in future, as additional + * capabilities for 2.2 are added, including updates to util_filter. + * + * 21/9/04: Unifying data structures with util_filter. + * From now on, until and unless we backport, mod_filter requires + * util_filter.h from CVS or httpd-2.1+ to compile. + * There's a minimal patch for httpd-2.0 users maintained by Nick + * to compile mod_filter at http://www.apache.org/~niq/ + */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_log.h" +#include "util_filter.h" + +module AP_MODULE_DECLARE_DATA filter_module; + +/** + * ap_filter_provider_t is a filter provider, as defined and implemented + * by mod_filter. The struct is a linked list, with dispatch criteria + * defined for each filter. The provider implementation itself is a + * (2.0-compatible) ap_filter_rec_t* frec. + */ +struct ap_filter_provider_t { + /** How to match this provider to filter dispatch criterion */ + enum { + STRING_MATCH, + STRING_CONTAINS, + REGEX_MATCH, + INT_EQ, + INT_LT, + INT_LE, + INT_GT, + INT_GE, + DEFINED + } match_type; + + /** negation on match_type */ + int not; + + /** The dispatch match itself - union member depends on match_type */ + union { + const char *string; + ap_regex_t *regex; + int number; + } match; + + /** The filter that implements this provider */ + ap_filter_rec_t *frec; + + /** The next provider in the list */ + ap_filter_provider_t *next; + + /** Dispatch criteria for filter providers */ + enum { + HANDLER, + REQUEST_HEADERS, + RESPONSE_HEADERS, + SUBPROCESS_ENV, + CONTENT_TYPE + } dispatch; + + /** Match value for filter providers */ + const char* value; +}; + +/** we need provider_ctx to save ctx values set by providers in filter_init */ +typedef struct provider_ctx provider_ctx; +struct provider_ctx { + ap_filter_provider_t *provider; + void *ctx; + provider_ctx *next; +}; +typedef struct { + ap_out_filter_func func; + void *fctx; + provider_ctx *init_ctx; +} harness_ctx; + +typedef struct mod_filter_chain { + const char *fname; + struct mod_filter_chain *next; +} mod_filter_chain; + +typedef struct { + apr_hash_t *live_filters; + mod_filter_chain *chain; +} mod_filter_cfg; + +typedef struct { + const char* range ; +} mod_filter_ctx ; + + +static void filter_trace(conn_rec *c, int debug, const char *fname, + apr_bucket_brigade *bb) +{ + apr_bucket *b; + + switch (debug) { + case 0: /* normal, operational use */ + return; + case 1: /* mod_diagnostics level */ + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, fname); + for (b = APR_BRIGADE_FIRST(bb); + b != APR_BRIGADE_SENTINEL(bb); + b = APR_BUCKET_NEXT(b)) { + + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, + "%s: type: %s, length: %" APR_SIZE_T_FMT, + fname, b->type->name ? b->type->name : "(unknown)", + b->length); + } + break; + } +} + +static int filter_init(ap_filter_t *f) +{ + ap_filter_provider_t *p; + provider_ctx *pctx; + int err; + ap_filter_rec_t *filter = f->frec; + + harness_ctx *fctx = apr_pcalloc(f->r->pool, sizeof(harness_ctx)); + for (p = filter->providers; p; p = p->next) { + if (p->frec->filter_init_func) { + f->ctx = NULL; + if ((err = p->frec->filter_init_func(f)) != OK) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, + "filter_init for %s failed", p->frec->name); + return err; /* if anyone errors out here, so do we */ + } + if (f->ctx != NULL) { + /* the filter init function set a ctx - we need to record it */ + pctx = apr_pcalloc(f->r->pool, sizeof(provider_ctx)); + pctx->provider = p; + pctx->ctx = f->ctx; + pctx->next = fctx->init_ctx; + fctx->init_ctx = pctx; + } + } + } + f->ctx = fctx; + return OK; +} + +static int filter_lookup(ap_filter_t *f, ap_filter_rec_t *filter) +{ + ap_filter_provider_t *provider; + const char *str = NULL; + char *str1; + int match; + unsigned int proto_flags; + request_rec *r = f->r; + harness_ctx *ctx = f->ctx; + provider_ctx *pctx; + mod_filter_ctx *rctx = ap_get_module_config(r->request_config, + &filter_module); + + /* Check registered providers in order */ + for (provider = filter->providers; provider; provider = provider->next) { + match = 1; + switch (provider->dispatch) { + case REQUEST_HEADERS: + str = apr_table_get(r->headers_in, provider->value); + break; + case RESPONSE_HEADERS: + str = apr_table_get(r->headers_out, provider->value); + break; + case SUBPROCESS_ENV: + str = apr_table_get(r->subprocess_env, provider->value); + break; + case CONTENT_TYPE: + str = r->content_type; + break; + case HANDLER: + str = r->handler; + break; + } + + /* treat nulls so we don't have to check every strcmp individually + * Not sure if there's anything better to do with them + */ + if (!str) { + if (provider->match_type == DEFINED && provider->match.string) { + match = 0; + } + } + else if (!provider->match.string) { + match = 0; + } + else { + /* Now we have no nulls, so we can do string and regexp matching */ + switch (provider->match_type) { + case STRING_MATCH: + if (strcasecmp(str, provider->match.string)) { + match = 0; + } + break; + case STRING_CONTAINS: + str1 = apr_pstrdup(r->pool, str); + ap_str_tolower(str1); + if (!strstr(str1, provider->match.string)) { + match = 0; + } + break; + case REGEX_MATCH: + if (ap_regexec(provider->match.regex, str, 0, NULL, 0) + == AP_REG_NOMATCH) { + match = 0; + } + break; + case INT_EQ: + if (atoi(str) != provider->match.number) { + match = 0; + } + break; + case INT_LT: + if (atoi(str) < provider->match.number) { + match = 0; + } + break; + case INT_LE: + if (atoi(str) <= provider->match.number) { + match = 0; + } + break; + case INT_GT: + if (atoi(str) > provider->match.number) { + match = 0; + } + break; + case INT_GE: + if (atoi(str) >= provider->match.number) { + match = 0; + } + break; + case DEFINED: /* we already handled this:-) */ + break; + } + } + + if (match != provider->not) { + /* condition matches this provider */ +#ifndef NO_PROTOCOL + /* check protocol + * + * FIXME: + * This is a quick hack and almost certainly buggy. + * The idea is that by putting this in mod_filter, we relieve + * filter implementations of the burden of fixing up HTTP headers + * for cases that are routinely affected by filters. + * + * Default is ALWAYS to do nothing, so as not to tread on the + * toes of filters which want to do it themselves. + * + */ + proto_flags = provider->frec->proto_flags; + + /* some specific things can't happen in a proxy */ + if (r->proxyreq) { + if (proto_flags & AP_FILTER_PROTO_NO_PROXY) { + /* can't use this provider; try next */ + continue; + } + + if (proto_flags & AP_FILTER_PROTO_TRANSFORM) { + str = apr_table_get(r->headers_out, "Cache-Control"); + if (str) { + str1 = apr_pstrdup(r->pool, str); + ap_str_tolower(str1); + if (strstr(str1, "no-transform")) { + /* can't use this provider; try next */ + continue; + } + } + apr_table_addn(r->headers_out, "Warning", + apr_psprintf(r->pool, + "214 %s Transformation applied", + r->hostname)); + } + } + + /* things that are invalidated if the filter transforms content */ + if (proto_flags & AP_FILTER_PROTO_CHANGE) { + apr_table_unset(r->headers_out, "Content-MD5"); + apr_table_unset(r->headers_out, "ETag"); + if (proto_flags & AP_FILTER_PROTO_CHANGE_LENGTH) { + apr_table_unset(r->headers_out, "Content-Length"); + } + } + + /* no-cache is for a filter that has different effect per-hit */ + if (proto_flags & AP_FILTER_PROTO_NO_CACHE) { + apr_table_unset(r->headers_out, "Last-Modified"); + apr_table_addn(r->headers_out, "Cache-Control", "no-cache"); + } + + if (proto_flags & AP_FILTER_PROTO_NO_BYTERANGE) { + apr_table_unset(r->headers_out, "Accept-Ranges"); + } + else if (rctx && rctx->range) { + /* restore range header we saved earlier */ + apr_table_setn(r->headers_in, "Range", rctx->range); + rctx->range = NULL; + } +#endif + for (pctx = ctx->init_ctx; pctx; pctx = pctx->next) { + if (pctx->provider == provider) { + ctx->fctx = pctx->ctx ; + } + } + ctx->func = provider->frec->filter_func.out_func; + return 1; + } + } + + /* No provider matched */ + return 0; +} + +static apr_status_t filter_harness(ap_filter_t *f, apr_bucket_brigade *bb) +{ + apr_status_t ret; + const char *cachecontrol; + char *str; + harness_ctx *ctx = f->ctx; + ap_filter_rec_t *filter = f->frec; + + if (f->r->status != 200) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + filter_trace(f->c, filter->debug, f->frec->name, bb); + + /* look up a handler function if we haven't already set it */ + if (!ctx->func) { +#ifndef NO_PROTOCOL + if (f->r->proxyreq) { + if (filter->proto_flags & AP_FILTER_PROTO_NO_PROXY) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + if (filter->proto_flags & AP_FILTER_PROTO_TRANSFORM) { + cachecontrol = apr_table_get(f->r->headers_out, + "Cache-Control"); + if (cachecontrol) { + str = apr_pstrdup(f->r->pool, cachecontrol); + ap_str_tolower(str); + if (strstr(str, "no-transform")) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + } + } + } +#endif + if (!filter_lookup(f, filter)) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + } + + /* call the content filter with its own context, then restore our + * context + */ + f->ctx = ctx->fctx; + ret = ctx->func(f, bb); + ctx->fctx = f->ctx; + f->ctx = ctx; + + return ret; +} + +#ifndef NO_PROTOCOL +static const char *filter_protocol(cmd_parms *cmd, void *CFG, const char *fname, + const char *pname, const char *proto) +{ + static const char *sep = ";, \t"; + char *arg; + char *tok = 0; + unsigned int flags = 0; + mod_filter_cfg *cfg = CFG; + ap_filter_provider_t *provider = NULL; + ap_filter_rec_t *filter = apr_hash_get(cfg->live_filters, fname, + APR_HASH_KEY_STRING); + + if (!filter) { + return "FilterProtocol: No such filter"; + } + + /* Fixup the args: it's really pname that's optional */ + if (proto == NULL) { + proto = pname; + pname = NULL; + } + else { + /* Find provider */ + for (provider = filter->providers; provider; provider = provider->next){ + if (!strcasecmp(provider->frec->name, pname)) { + break; + } + } + if (!provider) { + return "FilterProtocol: No such provider for this filter"; + } + } + + /* Now set flags from our args */ + for (arg = apr_strtok(apr_pstrdup(cmd->pool, proto), sep, &tok); + arg; arg = apr_strtok(NULL, sep, &tok)) { + + if (!strcasecmp(arg, "change=yes")) { + flags |= AP_FILTER_PROTO_CHANGE | AP_FILTER_PROTO_CHANGE_LENGTH; + } + else if (!strcasecmp(arg, "change=1:1")) { + flags |= AP_FILTER_PROTO_CHANGE; + } + else if (!strcasecmp(arg, "byteranges=no")) { + flags |= AP_FILTER_PROTO_NO_BYTERANGE; + } + else if (!strcasecmp(arg, "proxy=no")) { + flags |= AP_FILTER_PROTO_NO_PROXY; + } + else if (!strcasecmp(arg, "proxy=transform")) { + flags |= AP_FILTER_PROTO_TRANSFORM; + } + else if (!strcasecmp(arg, "cache=no")) { + flags |= AP_FILTER_PROTO_NO_CACHE; + } + } + + if (pname) { + provider->frec->proto_flags = flags; + } + else { + filter->proto_flags = flags; + } + + return NULL; +} +#endif + +static const char *filter_declare(cmd_parms *cmd, void *CFG, const char *fname, + const char *place) +{ + mod_filter_cfg *cfg = (mod_filter_cfg *)CFG; + ap_filter_rec_t *filter; + + filter = apr_pcalloc(cmd->pool, sizeof(ap_filter_rec_t)); + apr_hash_set(cfg->live_filters, fname, APR_HASH_KEY_STRING, filter); + + filter->name = fname; + filter->filter_init_func = filter_init; + filter->filter_func.out_func = filter_harness; + filter->ftype = AP_FTYPE_RESOURCE; + filter->next = NULL; + + if (place) { + if (!strcasecmp(place, "CONTENT_SET")) { + filter->ftype = AP_FTYPE_CONTENT_SET; + } + else if (!strcasecmp(place, "PROTOCOL")) { + filter->ftype = AP_FTYPE_PROTOCOL; + } + else if (!strcasecmp(place, "CONNECTION")) { + filter->ftype = AP_FTYPE_CONNECTION; + } + else if (!strcasecmp(place, "NETWORK")) { + filter->ftype = AP_FTYPE_NETWORK; + } + } + + return NULL; +} + +static const char *filter_provider(cmd_parms *cmd, void *CFG, const char *args) +{ + mod_filter_cfg *cfg = CFG; + int flags; + ap_filter_provider_t *provider; + const char *rxend; + const char *c; + char *str; + const char *eq; + ap_filter_rec_t* frec; + ap_filter_rec_t* provider_frec; + + /* insist on exactly four arguments */ + const char *fname = ap_getword_conf(cmd->pool, &args) ; + const char *pname = ap_getword_conf(cmd->pool, &args) ; + const char *condition = ap_getword_conf(cmd->pool, &args) ; + const char *match = ap_getword_conf(cmd->pool, &args) ; + eq = ap_getword_conf(cmd->pool, &args) ; + if ( !*fname || !*pname || !*match || !*condition || *eq ) { + return "usage: FilterProvider filter provider condition match" ; + } + + /* fname has been declared with DeclareFilter, so we can look it up */ + frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); + + /* or if provider is mod_filter itself, we can also look it up */ + if (!frec) { + c = filter_declare(cmd, CFG, fname, NULL); + if ( c ) { + return c; + } + frec = apr_hash_get(cfg->live_filters, fname, APR_HASH_KEY_STRING); + } + + if (!frec) { + return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname); + } + + /* if provider has been registered, we can look it up */ + provider_frec = ap_get_output_filter_handle(pname); + if (!provider_frec) { + provider_frec = apr_hash_get(cfg->live_filters, pname, + APR_HASH_KEY_STRING); + } + if (!provider_frec) { + return apr_psprintf(cmd->pool, "Unknown filter provider %s", pname); + } + + provider = apr_palloc(cmd->pool, sizeof(ap_filter_provider_t)); + if (*match == '!') { + provider->not = 1; + ++match; + } + else { + provider->not = 0; + } + + switch (*match++) { + case '<': + if (*match == '=') { + provider->match_type = INT_LE; + ++match; + } + else { + provider->match_type = INT_LT; + } + provider->match.number = atoi(match); + break; + case '>': + if (*match == '=') { + provider->match_type = INT_GE; + ++match; + } + else { + provider->match_type = INT_GT; + } + provider->match.number = atoi(match); + break; + case '=': + provider->match_type = INT_EQ; + provider->match.number = atoi(match); + break; + case '/': + provider->match_type = REGEX_MATCH; + rxend = ap_strchr_c(match, '/'); + if (!rxend) { + return "Bad regexp syntax"; + } + flags = AP_REG_NOSUB; /* we're not mod_rewrite:-) */ + for (c = rxend+1; *c; ++c) { + switch (*c) { + case 'i': flags |= AP_REG_ICASE; break; + } + } + provider->match.regex = ap_pregcomp(cmd->pool, + apr_pstrndup(cmd->pool, + match, + rxend-match), + flags); + break; + case '*': + provider->match_type = DEFINED; + provider->match.number = -1; + break; + case '$': + provider->match_type = STRING_CONTAINS; + str = apr_pstrdup(cmd->pool, match); + ap_str_tolower(str); + provider->match.string = str; + break; + default: + provider->match_type = STRING_MATCH; + provider->match.string = apr_pstrdup(cmd->pool, match-1); + break; + } + provider->frec = provider_frec; + provider->next = frec->providers; + frec->providers = provider; + + /* determine what a filter will dispatch this provider on */ + eq = ap_strchr_c(condition, '='); + if (eq) { + str = apr_pstrdup(cmd->pool, eq+1); + if (!strncasecmp(condition, "env=", 4)) { + provider->dispatch = SUBPROCESS_ENV; + } + else if (!strncasecmp(condition, "req=", 4)) { + provider->dispatch = REQUEST_HEADERS; + } + else if (!strncasecmp(condition, "resp=", 5)) { + provider->dispatch = RESPONSE_HEADERS; + } + else { + return "FilterProvider: unrecognized dispatch table"; + } + } + else { + if (!strcasecmp(condition, "handler")) { + provider->dispatch = HANDLER; + } + else { + provider->dispatch = RESPONSE_HEADERS; + } + str = apr_pstrdup(cmd->pool, condition); + ap_str_tolower(str); + } + + if ( (provider->dispatch == RESPONSE_HEADERS) + && !strcmp(str, "content-type")) { + provider->dispatch = CONTENT_TYPE; + } + provider->value = str; + + return NULL; +} + +static const char *filter_chain(cmd_parms *cmd, void *CFG, const char *arg) +{ + mod_filter_chain *p; + mod_filter_chain *q; + mod_filter_cfg *cfg = CFG; + + switch (arg[0]) { + case '+': /* add to end of chain */ + p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain)); + p->fname = arg+1; + if (cfg->chain) { + for (q = cfg->chain; q->next; q = q->next); + q->next = p; + } + else { + cfg->chain = p; + } + break; + + case '@': /* add to start of chain */ + p = apr_palloc(cmd->pool, sizeof(mod_filter_chain)); + p->fname = arg+1; + p->next = cfg->chain; + cfg->chain = p; + break; + + case '-': /* remove from chain */ + if (cfg->chain) { + if (strcasecmp(cfg->chain->fname, arg+1)) { + for (p = cfg->chain; p->next; p = p->next) { + if (!strcasecmp(p->next->fname, arg+1)) { + p->next = p->next->next; + } + } + } + else { + cfg->chain = cfg->chain->next; + } + } + break; + + case '!': /* Empty the chain */ + cfg->chain = NULL; + break; + + case '=': /* initialise chain with this arg */ + p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain)); + p->fname = arg+1; + cfg->chain = p; + break; + + default: /* add to end */ + p = apr_pcalloc(cmd->pool, sizeof(mod_filter_chain)); + p->fname = arg; + if (cfg->chain) { + for (q = cfg->chain; q->next; q = q->next); + q->next = p; + } + else { + cfg->chain = p; + } + break; + } + + return NULL; +} + +static const char *filter_debug(cmd_parms *cmd, void *CFG, const char *fname, + const char *level) +{ + mod_filter_cfg *cfg = CFG; + ap_filter_rec_t *frec = apr_hash_get(cfg->live_filters, fname, + APR_HASH_KEY_STRING); + if (!frec) { + return apr_psprintf(cmd->pool, "Undeclared smart filter %s", fname); + } + frec->debug = atoi(level); + + return NULL; +} + +static void filter_insert(request_rec *r) +{ + mod_filter_chain *p; + ap_filter_rec_t *filter; + mod_filter_cfg *cfg = ap_get_module_config(r->per_dir_config, + &filter_module); +#ifndef NO_PROTOCOL + int ranges = 1; + mod_filter_ctx *ctx = apr_pcalloc(r->pool, sizeof(mod_filter_ctx)); + ap_set_module_config(r->request_config, &filter_module, ctx); +#endif + + for (p = cfg->chain; p; p = p->next) { + filter = apr_hash_get(cfg->live_filters, p->fname, APR_HASH_KEY_STRING); + ap_add_output_filter_handle(filter, NULL, r, r->connection); +#ifndef NO_PROTOCOL + if (ranges && (filter->proto_flags + & (AP_FILTER_PROTO_NO_BYTERANGE + | AP_FILTER_PROTO_CHANGE_LENGTH))) { + ctx->range = apr_table_get(r->headers_in, "Range"); + apr_table_unset(r->headers_in, "Range"); + ranges = 0; + } +#endif + } + + return; +} + +static void filter_hooks(apr_pool_t *pool) +{ + ap_hook_insert_filter(filter_insert, NULL, NULL, APR_HOOK_MIDDLE); +} + +static void *filter_config(apr_pool_t *pool, char *x) +{ + mod_filter_cfg *cfg = apr_palloc(pool, sizeof(mod_filter_cfg)); + cfg->live_filters = apr_hash_make(pool); + cfg->chain = NULL; + return cfg; +} + +static void *filter_merge(apr_pool_t *pool, void *BASE, void *ADD) +{ + mod_filter_cfg *base = BASE; + mod_filter_cfg *add = ADD; + mod_filter_chain *savelink = 0; + mod_filter_chain *newlink; + mod_filter_chain *p; + mod_filter_cfg *conf = apr_palloc(pool, sizeof(mod_filter_cfg)); + + conf->live_filters = apr_hash_overlay(pool, add->live_filters, + base->live_filters); + if (base->chain && add->chain) { + for (p = base->chain; p; p = p->next) { + newlink = apr_pmemdup(pool, p, sizeof(mod_filter_chain)); + if (savelink) { + savelink->next = newlink; + savelink = newlink; + } + else { + conf->chain = savelink = newlink; + } + } + + for (p = add->chain; p; p = p->next) { + newlink = apr_pmemdup(pool, p, sizeof(mod_filter_chain)); + savelink->next = newlink; + savelink = newlink; + } + } + else if (add->chain) { + conf->chain = add->chain; + } + else { + conf->chain = base->chain; + } + + return conf; +} + +static const command_rec filter_cmds[] = { + AP_INIT_TAKE12("FilterDeclare", filter_declare, NULL, OR_OPTIONS, + "filter-name [, filter-type]"), + /** we don't have a TAKE4, so we have to use RAW_ARGS */ + AP_INIT_RAW_ARGS("FilterProvider", filter_provider, NULL, OR_OPTIONS, + "filter-name, provider-name, dispatch--criterion, dispatch-match"), + AP_INIT_ITERATE("FilterChain", filter_chain, NULL, OR_OPTIONS, + "list of filter names with optional [+-=!@]"), + AP_INIT_TAKE2("FilterTrace", filter_debug, NULL, RSRC_CONF | ACCESS_CONF, + "Debug level"), +#ifndef NO_PROTOCOL + AP_INIT_TAKE23("FilterProtocol", filter_protocol, NULL, OR_OPTIONS, + "filter-name [provider-name] protocol-args"), +#endif + { NULL } +}; + +module AP_MODULE_DECLARE_DATA filter_module = { + STANDARD20_MODULE_STUFF, + filter_config, + filter_merge, + NULL, + NULL, + filter_cmds, + filter_hooks +}; diff --git a/trunk/modules/filters/.indent.pro b/trunk/modules/filters/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/filters/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/filters/Makefile.in b/trunk/modules/filters/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/filters/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/filters/NWGNUdeflate b/trunk/modules/filters/NWGNUdeflate new file mode 100644 index 0000000000..53b4f78910 --- /dev/null +++ b/trunk/modules/filters/NWGNUdeflate @@ -0,0 +1,281 @@ +# +# The MOD_DEFLATE module requires the ZLib source which +# can be downloaded from http://www.gzip.org/zlib/ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = deflate + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Deflate Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Deflate Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/deflate.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_deflate.o \ + $(OBJDIR)/adler32.o \ + $(OBJDIR)/crc32.o \ + $(OBJDIR)/deflate.o \ + $(OBJDIR)/inflate.o \ + $(OBJDIR)/inffast.o \ + $(OBJDIR)/inftrees.o \ + $(OBJDIR)/trees.o \ + $(OBJDIR)/zutil.o \ + $(EOLIST) + +ifeq "$(wildcard $(ZLIBSDK)/infblock.c)" "$(ZLIBSDK)/infblock.c" +FILES_nlm_objs += \ + $(OBJDIR)/infblock.o \ + $(OBJDIR)/infcodes.o \ + $(OBJDIR)/infutil.o \ + $(EOLIST) +endif + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + deflate_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +vpath %.c $(ZLIBSDK) + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/filters/NWGNUextfiltr b/trunk/modules/filters/NWGNUextfiltr new file mode 100644 index 0000000000..1de291ca2b --- /dev/null +++ b/trunk/modules/filters/NWGNUextfiltr @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = extfiltr + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) External Filter Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = ExtFilter Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/extfiltr.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_ext_filter.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + ext_filter_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/filters/NWGNUmakefile b/trunk/modules/filters/NWGNUmakefile new file mode 100644 index 0000000000..c8509428eb --- /dev/null +++ b/trunk/modules/filters/NWGNUmakefile @@ -0,0 +1,255 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/extfiltr.nlm \ + $(EOLIST) + +# If the zlib libraries source exists then build the mod_deflate module +ifneq "$(ZLIBSDK)" "" +ifeq "$(wildcard $(ZLIBSDK))" "$(ZLIBSDK)" +TARGET_nlm += $(OBJDIR)/deflate.nlm \ + $(EOLIST) +endif +else +TARGET_nlm += $(OBJDIR)/extfiltr.nlm \ + $(EOLIST) +endif + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/filters/config.m4 b/trunk/modules/filters/config.m4 new file mode 100644 index 0000000000..a481e40370 --- /dev/null +++ b/trunk/modules/filters/config.m4 @@ -0,0 +1,62 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(filters) + +APACHE_MODULE(ext_filter, external filter module, , , most) +APACHE_MODULE(include, Server Side Includes, , , yes) + +APACHE_MODULE(deflate, Deflate transfer encoding support, , , most, [ + AC_ARG_WITH(z, APACHE_HELP_STRING(--with-z=DIR,use a specific zlib library), + [ + if test "x$withval" != "xyes" && test "x$withval" != "x"; then + ap_zlib_base="$withval" + fi + ]) + if test "x$ap_zlib_base" = "x"; then + AC_MSG_CHECKING([for zlib location]) + AC_CACHE_VAL(ap_cv_zlib,[ + for dir in /usr/local /usr ; do + if test -d $dir && test -f $dir/include/zlib.h; then + ap_cv_zlib=$dir + break + fi + done + ]) + ap_zlib_base=$ap_cv_zlib + if test "x$ap_zlib_base" = "x"; then + enable_deflate=no + AC_MSG_RESULT([not found]) + else + AC_MSG_RESULT([$ap_zlib_base]) + fi + fi + if test "$enable_deflate" != "no"; then + ap_save_includes=$INCLUDES + ap_save_ldflags=$LDFLAGS + ap_save_cppflags=$CPPFLAGS + if test "$ap_zlib_base" != "/usr"; then + APR_ADDTO(INCLUDES, [-I${ap_zlib_base}/include]) + dnl put in CPPFLAGS temporarily so that AC_TRY_LINK below will work + CPPFLAGS="$CPPFLAGS $INCLUDES" + APR_ADDTO(LDFLAGS, [-L${ap_zlib_base}/lib]) + if test "x$ap_platform_runtime_link_flag" != "x"; then + APR_ADDTO(LDFLAGS, [$ap_platform_runtime_link_flag${ap_zlib_base}/lib]) + fi + fi + APR_ADDTO(LIBS, [-lz]) + AC_MSG_CHECKING([for zlib library]) + AC_TRY_LINK([#include ], [int i = Z_OK;], + [AC_MSG_RESULT(found) + APR_SETVAR(MOD_DEFLATE_LDADD, [-lz])], + [AC_MSG_RESULT(not found) + enable_deflate=no + INCLUDES=$ap_save_includes + LDFLAGS=$ap_save_ldflags]) + APR_REMOVEFROM(LIBS, [-lz]) + CPPFLAGS=$ap_save_cppflags + fi +]) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/filters/mod_deflate.c b/trunk/modules/filters/mod_deflate.c new file mode 100644 index 0000000000..f248a82354 --- /dev/null +++ b/trunk/modules/filters/mod_deflate.c @@ -0,0 +1,1123 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_deflate.c: Perform deflate content-encoding on the fly + * + * Written by Ian Holsman, Justin Erenkrantz, and Nick Kew + */ + +/* + * Portions of this software are based upon zlib code by Jean-loup Gailly + * (zlib functions gz_open and gzwrite, check_header) + */ + +/* zlib flags */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "apr_strings.h" +#include "apr_general.h" +#include "util_filter.h" +#include "apr_buckets.h" +#include "http_request.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "zlib.h" + +static const char deflateFilterName[] = "DEFLATE"; +module AP_MODULE_DECLARE_DATA deflate_module; + +typedef struct deflate_filter_config_t +{ + int windowSize; + int memlevel; + int compressionlevel; + apr_size_t bufferSize; + char *note_ratio_name; + char *note_input_name; + char *note_output_name; +} deflate_filter_config; + +/* RFC 1952 Section 2.3 defines the gzip header: + * + * +---+---+---+---+---+---+---+---+---+---+ + * |ID1|ID2|CM |FLG| MTIME |XFL|OS | + * +---+---+---+---+---+---+---+---+---+---+ + */ +static const char gzip_header[10] = +{ '\037', '\213', Z_DEFLATED, 0, + 0, 0, 0, 0, /* mtime */ + 0, 0x03 /* Unix OS_CODE */ +}; + +/* magic header */ +static const char deflate_magic[2] = { '\037', '\213' }; + +/* windowsize is negative to suppress Zlib header */ +#define DEFAULT_COMPRESSION Z_DEFAULT_COMPRESSION +#define DEFAULT_WINDOWSIZE -15 +#define DEFAULT_MEMLEVEL 9 +#define DEFAULT_BUFFERSIZE 8096 + +/* Outputs a long in LSB order to the given file + * only the bottom 4 bits are required for the deflate file format. + */ +static void putLong(unsigned char *string, unsigned long x) +{ + string[0] = (unsigned char)(x & 0xff); + string[1] = (unsigned char)((x & 0xff00) >> 8); + string[2] = (unsigned char)((x & 0xff0000) >> 16); + string[3] = (unsigned char)((x & 0xff000000) >> 24); +} + +/* Inputs a string and returns a long. + */ +static unsigned long getLong(unsigned char *string) +{ + return ((unsigned long)string[0]) + | (((unsigned long)string[1]) << 8) + | (((unsigned long)string[2]) << 16) + | (((unsigned long)string[3]) << 24); +} + +static void *create_deflate_server_config(apr_pool_t *p, server_rec *s) +{ + deflate_filter_config *c = apr_pcalloc(p, sizeof *c); + + c->memlevel = DEFAULT_MEMLEVEL; + c->windowSize = DEFAULT_WINDOWSIZE; + c->bufferSize = DEFAULT_BUFFERSIZE; + c->compressionlevel = DEFAULT_COMPRESSION; + + return c; +} + +static const char *deflate_set_window_size(cmd_parms *cmd, void *dummy, + const char *arg) +{ + deflate_filter_config *c = ap_get_module_config(cmd->server->module_config, + &deflate_module); + int i; + + i = atoi(arg); + + if (i < 1 || i > 15) + return "DeflateWindowSize must be between 1 and 15"; + + c->windowSize = i * -1; + + return NULL; +} + +static const char *deflate_set_buffer_size(cmd_parms *cmd, void *dummy, + const char *arg) +{ + deflate_filter_config *c = ap_get_module_config(cmd->server->module_config, + &deflate_module); + int n = atoi(arg); + + if (n <= 0) { + return "DeflateBufferSize should be positive"; + } + + c->bufferSize = (apr_size_t)n; + + return NULL; +} +static const char *deflate_set_note(cmd_parms *cmd, void *dummy, + const char *arg1, const char *arg2) +{ + deflate_filter_config *c = ap_get_module_config(cmd->server->module_config, + &deflate_module); + + if (arg2 == NULL) { + c->note_ratio_name = apr_pstrdup(cmd->pool, arg1); + } + else if (!strcasecmp(arg1, "ratio")) { + c->note_ratio_name = apr_pstrdup(cmd->pool, arg2); + } + else if (!strcasecmp(arg1, "input")) { + c->note_input_name = apr_pstrdup(cmd->pool, arg2); + } + else if (!strcasecmp(arg1, "output")) { + c->note_output_name = apr_pstrdup(cmd->pool, arg2); + } + else { + return apr_psprintf(cmd->pool, "Unknown note type %s", arg1); + } + + return NULL; +} + +static const char *deflate_set_memlevel(cmd_parms *cmd, void *dummy, + const char *arg) +{ + deflate_filter_config *c = ap_get_module_config(cmd->server->module_config, + &deflate_module); + int i; + + i = atoi(arg); + + if (i < 1 || i > 9) + return "DeflateMemLevel must be between 1 and 9"; + + c->memlevel = i; + + return NULL; +} + +static const char *deflate_set_compressionlevel(cmd_parms *cmd, void *dummy, + const char *arg) +{ + deflate_filter_config *c = ap_get_module_config(cmd->server->module_config, + &deflate_module); + int i; + + i = atoi(arg); + + if (i < 1 || i > 9) + return "Compression Level must be between 1 and 9"; + + c->compressionlevel = i; + + return NULL; +} + +typedef struct deflate_ctx_t +{ + z_stream stream; + unsigned char *buffer; + unsigned long crc; + apr_bucket_brigade *bb, *proc_bb; +} deflate_ctx; + +static apr_status_t deflate_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + apr_bucket *e; + request_rec *r = f->r; + deflate_ctx *ctx = f->ctx; + int zRC; + deflate_filter_config *c = ap_get_module_config(r->server->module_config, + &deflate_module); + + /* Do nothing if asked to filter nothing. */ + if (APR_BRIGADE_EMPTY(bb)) { + return APR_SUCCESS; + } + + /* If we don't have a context, we need to ensure that it is okay to send + * the deflated content. If we have a context, that means we've done + * this before and we liked it. + * This could be not so nice if we always fail. But, if we succeed, + * we're in better shape. + */ + if (!ctx) { + char *token; + const char *encoding; + + /* only work on main request/no subrequests */ + if (!ap_is_initial_req(r)) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* some browsers might have problems, so set no-gzip + * (with browsermatch) for them + */ + if (apr_table_get(r->subprocess_env, "no-gzip")) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* Some browsers might have problems with content types + * other than text/html, so set gzip-only-text/html + * (with browsermatch) for them + */ + if (r->content_type == NULL + || strncmp(r->content_type, "text/html", 9)) { + const char *env_value = apr_table_get(r->subprocess_env, + "gzip-only-text/html"); + if ( env_value && (strcmp(env_value,"1") == 0) ) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + } + + /* Let's see what our current Content-Encoding is. + * If it's already encoded, don't compress again. + * (We could, but let's not.) + */ + encoding = apr_table_get(r->headers_out, "Content-Encoding"); + if (encoding) { + const char *err_enc; + + err_enc = apr_table_get(r->err_headers_out, "Content-Encoding"); + if (err_enc) { + encoding = apr_pstrcat(r->pool, encoding, ",", err_enc, NULL); + } + } + else { + encoding = apr_table_get(r->err_headers_out, "Content-Encoding"); + } + + if (r->content_encoding) { + encoding = encoding ? apr_pstrcat(r->pool, encoding, ",", + r->content_encoding, NULL) + : r->content_encoding; + } + + if (encoding) { + const char *tmp = encoding; + + token = ap_get_token(r->pool, &tmp, 0); + while (token && *token) { + /* stolen from mod_negotiation: */ + if (strcmp(token, "identity") && strcmp(token, "7bit") && + strcmp(token, "8bit") && strcmp(token, "binary")) { + + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* Otherwise, skip token */ + if (*tmp) { + ++tmp; + } + token = (*tmp) ? ap_get_token(r->pool, &tmp, 0) : NULL; + } + } + + /* Even if we don't accept this request based on it not having + * the Accept-Encoding, we need to note that we were looking + * for this header and downstream proxies should be aware of that. + */ + apr_table_mergen(r->headers_out, "Vary", "Accept-Encoding"); + + /* force-gzip will just force it out regardless if the browser + * can actually do anything with it. + */ + if (!apr_table_get(r->subprocess_env, "force-gzip")) { + const char *accepts; + /* if they don't have the line, then they can't play */ + accepts = apr_table_get(r->headers_in, "Accept-Encoding"); + if (accepts == NULL) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + token = ap_get_token(r->pool, &accepts, 0); + while (token && token[0] && strcasecmp(token, "gzip")) { + /* skip parameters, XXX: ;q=foo evaluation? */ + while (*accepts == ';') { + ++accepts; + token = ap_get_token(r->pool, &accepts, 1); + } + + /* retrieve next token */ + if (*accepts == ',') { + ++accepts; + } + token = (*accepts) ? ap_get_token(r->pool, &accepts, 0) : NULL; + } + + /* No acceptable token found. */ + if (token == NULL || token[0] == '\0') { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + } + + /* For a 304 or 204 response there is no entity included in + * the response and hence nothing to deflate. */ + if (r->status == HTTP_NOT_MODIFIED || r->status == HTTP_NO_CONTENT) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* We're cool with filtering this. */ + ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc); + ctx->buffer = apr_palloc(r->pool, c->bufferSize); + + zRC = deflateInit2(&ctx->stream, c->compressionlevel, Z_DEFLATED, + c->windowSize, c->memlevel, + Z_DEFAULT_STRATEGY); + + if (zRC != Z_OK) { + f->ctx = NULL; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "unable to init Zlib: " + "deflateInit2 returned %d: URL %s", + zRC, r->uri); + return ap_pass_brigade(f->next, bb); + } + + /* add immortal gzip header */ + e = apr_bucket_immortal_create(gzip_header, sizeof gzip_header, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, e); + + /* If the entire Content-Encoding is "identity", we can replace it. */ + if (!encoding || !strcasecmp(encoding, "identity")) { + apr_table_setn(r->headers_out, "Content-Encoding", "gzip"); + } + else { + apr_table_mergen(r->headers_out, "Content-Encoding", "gzip"); + } + apr_table_unset(r->headers_out, "Content-Length"); + + /* initialize deflate output buffer */ + ctx->stream.next_out = ctx->buffer; + ctx->stream.avail_out = c->bufferSize; + } + + while (!APR_BRIGADE_EMPTY(bb)) + { + const char *data; + apr_bucket *b; + apr_size_t len; + int done = 0; + + e = APR_BRIGADE_FIRST(bb); + + if (APR_BUCKET_IS_EOS(e)) { + char *buf; + unsigned int deflate_len; + + ctx->stream.avail_in = 0; /* should be zero already anyway */ + for (;;) { + deflate_len = c->bufferSize - ctx->stream.avail_out; + + if (deflate_len != 0) { + b = apr_bucket_heap_create((char *)ctx->buffer, + deflate_len, NULL, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); + ctx->stream.next_out = ctx->buffer; + ctx->stream.avail_out = c->bufferSize; + } + + if (done) { + break; + } + + zRC = deflate(&ctx->stream, Z_FINISH); + + if (deflate_len == 0 && zRC == Z_BUF_ERROR) { + zRC = Z_OK; + } + + done = (ctx->stream.avail_out != 0 || zRC == Z_STREAM_END); + + if (zRC != Z_OK && zRC != Z_STREAM_END) { + break; + } + } + + buf = apr_palloc(r->pool, 8); + putLong((unsigned char *)&buf[0], ctx->crc); + putLong((unsigned char *)&buf[4], ctx->stream.total_in); + + b = apr_bucket_pool_create(buf, 8, r->pool, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "Zlib: Compressed %ld to %ld : URL %s", + ctx->stream.total_in, ctx->stream.total_out, r->uri); + + /* leave notes for logging */ + if (c->note_input_name) { + apr_table_setn(r->notes, c->note_input_name, + (ctx->stream.total_in > 0) + ? apr_off_t_toa(r->pool, + ctx->stream.total_in) + : "-"); + } + + if (c->note_output_name) { + apr_table_setn(r->notes, c->note_output_name, + (ctx->stream.total_in > 0) + ? apr_off_t_toa(r->pool, + ctx->stream.total_out) + : "-"); + } + + if (c->note_ratio_name) { + apr_table_setn(r->notes, c->note_ratio_name, + (ctx->stream.total_in > 0) + ? apr_itoa(r->pool, + (int)(ctx->stream.total_out + * 100 + / ctx->stream.total_in)) + : "-"); + } + + deflateEnd(&ctx->stream); + + /* Remove EOS from the old list, and insert into the new. */ + APR_BUCKET_REMOVE(e); + APR_BRIGADE_INSERT_TAIL(ctx->bb, e); + + /* Okay, we've seen the EOS. + * Time to pass it along down the chain. + */ + return ap_pass_brigade(f->next, ctx->bb); + } + + if (APR_BUCKET_IS_FLUSH(e)) { + apr_bucket *bkt; + apr_status_t rv; + + apr_bucket_delete(e); + + if (ctx->stream.avail_in > 0) { + zRC = deflate(&(ctx->stream), Z_SYNC_FLUSH); + if (zRC != Z_OK) { + return APR_EGENERAL; + } + } + + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + b = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); + ctx->stream.avail_out = c->bufferSize; + + bkt = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, bkt); + rv = ap_pass_brigade(f->next, ctx->bb); + if (rv != APR_SUCCESS) { + return rv; + } + continue; + } + + /* read */ + apr_bucket_read(e, &data, &len, APR_BLOCK_READ); + + /* This crc32 function is from zlib. */ + ctx->crc = crc32(ctx->crc, (const Bytef *)data, len); + + /* write */ + ctx->stream.next_in = (unsigned char *)data; /* We just lost const-ness, + * but we'll just have to + * trust zlib */ + ctx->stream.avail_in = len; + + while (ctx->stream.avail_in != 0) { + if (ctx->stream.avail_out == 0) { + apr_status_t rv; + + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + b = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->bb, b); + ctx->stream.avail_out = c->bufferSize; + /* Send what we have right now to the next filter. */ + rv = ap_pass_brigade(f->next, ctx->bb); + if (rv != APR_SUCCESS) { + return rv; + } + } + + zRC = deflate(&(ctx->stream), Z_NO_FLUSH); + + if (zRC != Z_OK) + return APR_EGENERAL; + } + + apr_bucket_delete(e); + } + + apr_brigade_cleanup(bb); + return APR_SUCCESS; +} + +/* This is the deflate input filter (inflates). */ +static apr_status_t deflate_in_filter(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + apr_bucket *bkt; + request_rec *r = f->r; + deflate_ctx *ctx = f->ctx; + int zRC; + apr_status_t rv; + deflate_filter_config *c; + + /* just get out of the way of things we don't want. */ + if (mode != AP_MODE_READBYTES) { + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + c = ap_get_module_config(r->server->module_config, &deflate_module); + + if (!ctx) { + int found = 0; + char *token, deflate_hdr[10]; + const char *encoding; + apr_size_t len; + + /* only work on main request/no subrequests */ + if (!ap_is_initial_req(r)) { + ap_remove_input_filter(f); + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + /* Let's see what our current Content-Encoding is. + * If gzip is present, don't gzip again. (We could, but let's not.) + */ + encoding = apr_table_get(r->headers_in, "Content-Encoding"); + if (encoding) { + const char *tmp = encoding; + + token = ap_get_token(r->pool, &tmp, 0); + while (token && token[0]) { + if (!strcasecmp(token, "gzip")) { + found = 1; + break; + } + /* Otherwise, skip token */ + tmp++; + token = ap_get_token(r->pool, &tmp, 0); + } + } + + if (found == 0) { + ap_remove_input_filter(f); + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); + ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc); + ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); + ctx->buffer = apr_palloc(r->pool, c->bufferSize); + + rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10); + if (rv != APR_SUCCESS) { + return rv; + } + + len = 10; + rv = apr_brigade_flatten(ctx->bb, deflate_hdr, &len); + if (rv != APR_SUCCESS) { + return rv; + } + + /* We didn't get the magic bytes. */ + if (len != 10 || + deflate_hdr[0] != deflate_magic[0] || + deflate_hdr[1] != deflate_magic[1]) { + return APR_EGENERAL; + } + + /* We can't handle flags for now. */ + if (deflate_hdr[3] != 0) { + return APR_EGENERAL; + } + + zRC = inflateInit2(&ctx->stream, c->windowSize); + + if (zRC != Z_OK) { + f->ctx = NULL; + inflateEnd(&ctx->stream); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "unable to init Zlib: " + "inflateInit2 returned %d: URL %s", + zRC, r->uri); + ap_remove_input_filter(f); + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + /* initialize deflate output buffer */ + ctx->stream.next_out = ctx->buffer; + ctx->stream.avail_out = c->bufferSize; + + apr_brigade_cleanup(ctx->bb); + } + + if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { + rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes); + + if (rv != APR_SUCCESS) { + /* What about APR_EAGAIN errors? */ + inflateEnd(&ctx->stream); + return rv; + } + + for (bkt = APR_BRIGADE_FIRST(ctx->bb); + bkt != APR_BRIGADE_SENTINEL(ctx->bb); + bkt = APR_BUCKET_NEXT(bkt)) + { + const char *data; + apr_size_t len; + + /* If we actually see the EOS, that means we screwed up! */ + if (APR_BUCKET_IS_EOS(bkt)) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + + if (APR_BUCKET_IS_FLUSH(bkt)) { + apr_bucket *tmp_heap; + zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH); + if (zRC != Z_OK) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + + /* Move everything to the returning brigade. */ + APR_BUCKET_REMOVE(bkt); + APR_BRIGADE_CONCAT(bb, ctx->bb); + break; + } + + /* read */ + apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ); + + /* pass through zlib inflate. */ + ctx->stream.next_in = (unsigned char *)data; + ctx->stream.avail_in = len; + + zRC = Z_OK; + + while (ctx->stream.avail_in != 0) { + if (ctx->stream.avail_out == 0) { + apr_bucket *tmp_heap; + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + } + + zRC = inflate(&ctx->stream, Z_NO_FLUSH); + + if (zRC == Z_STREAM_END) { + break; + } + + if (zRC != Z_OK) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + } + if (zRC == Z_STREAM_END) { + apr_bucket *tmp_heap, *eos; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "Zlib: Inflated %ld to %ld : URL %s", + ctx->stream.total_in, ctx->stream.total_out, + r->uri); + + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + + /* Is the remaining 8 bytes already in the avail stream? */ + if (ctx->stream.avail_in >= 8) { + unsigned long compCRC, compLen; + compCRC = getLong(ctx->stream.next_in); + if (ctx->crc != compCRC) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + ctx->stream.next_in += 4; + compLen = getLong(ctx->stream.next_in); + if (ctx->stream.total_out != compLen) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + } + else { + /* FIXME: We need to grab the 8 verification bytes + * from the wire! */ + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + + inflateEnd(&ctx->stream); + + eos = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); + break; + } + + } + apr_brigade_cleanup(ctx->bb); + } + + /* If we are about to return nothing for a 'blocking' read and we have + * some data in our zlib buffer, flush it out so we can return something. + */ + if (block == APR_BLOCK_READ && + APR_BRIGADE_EMPTY(ctx->proc_bb) && + ctx->stream.avail_out < c->bufferSize) { + apr_bucket *tmp_heap; + apr_size_t len; + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + } + + if (!APR_BRIGADE_EMPTY(ctx->proc_bb)) { + apr_bucket_brigade *newbb; + + /* May return APR_INCOMPLETE which is fine by us. */ + apr_brigade_partition(ctx->proc_bb, readbytes, &bkt); + + newbb = apr_brigade_split(ctx->proc_bb, bkt); + APR_BRIGADE_CONCAT(bb, ctx->proc_bb); + APR_BRIGADE_CONCAT(ctx->proc_bb, newbb); + } + + return APR_SUCCESS; +} + + +/* Filter to inflate for a content-transforming proxy. */ +static apr_status_t inflate_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + int zlib_method; + int zlib_flags; + int deflate_init = 1; + apr_bucket *bkt; + request_rec *r = f->r; + deflate_ctx *ctx = f->ctx; + int zRC; + apr_status_t rv; + deflate_filter_config *c; + + /* Do nothing if asked to filter nothing. */ + if (APR_BRIGADE_EMPTY(bb)) { + return APR_SUCCESS; + } + + c = ap_get_module_config(r->server->module_config, &deflate_module); + + if (!ctx) { + int found = 0; + char *token; + const char *encoding; + + /* only work on main request/no subrequests */ + if (!ap_is_initial_req(r)) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* Let's see what our current Content-Encoding is. + * If gzip is present, don't gzip again. (We could, but let's not.) + */ + encoding = apr_table_get(r->headers_out, "Content-Encoding"); + if (encoding) { + const char *tmp = encoding; + + token = ap_get_token(r->pool, &tmp, 0); + while (token && token[0]) { + if (!strcasecmp(token, "gzip")) { + found = 1; + break; + } + /* Otherwise, skip token */ + tmp++; + token = ap_get_token(r->pool, &tmp, 0); + } + } + + if (found == 0) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + apr_table_unset(r->headers_out, "Content-Encoding"); + + /* No need to inflate HEAD or 204/304 */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + + f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); + ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); + ctx->buffer = apr_palloc(r->pool, c->bufferSize); + + + zRC = inflateInit2(&ctx->stream, c->windowSize); + + if (zRC != Z_OK) { + f->ctx = NULL; + inflateEnd(&ctx->stream); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "unable to init Zlib: " + "inflateInit2 returned %d: URL %s", + zRC, r->uri); + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + /* initialize deflate output buffer */ + ctx->stream.next_out = ctx->buffer; + ctx->stream.avail_out = c->bufferSize; + + deflate_init = 0; + } + + for (bkt = APR_BRIGADE_FIRST(bb); + bkt != APR_BRIGADE_SENTINEL(bb); + bkt = APR_BUCKET_NEXT(bkt)) + { + const char *data; + apr_size_t len; + + /* If we actually see the EOS, that means we screwed up! */ + /* no it doesn't - not in a HEAD or 204/304 */ + if (APR_BUCKET_IS_EOS(bkt)) { + inflateEnd(&ctx->stream); + return ap_pass_brigade(f->next, bb); + } + + if (APR_BUCKET_IS_FLUSH(bkt)) { + apr_bucket *tmp_heap; + zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH); + if (zRC != Z_OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Inflate error %d on flush", zRC); + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + + /* Move everything to the returning brigade. */ + APR_BUCKET_REMOVE(bkt); + break; + } + + /* read */ + apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ); + + /* first bucket contains zlib header */ + if (!deflate_init++) { + if (len < 10) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Insufficient data for inflate"); + return APR_EGENERAL; + } + else { + zlib_method = data[2]; + zlib_flags = data[3]; + if (zlib_method != Z_DEFLATED) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "inflate: data not deflated!"); + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + if (data[0] != deflate_magic[0] || + data[1] != deflate_magic[1] || + (zlib_flags & RESERVED) != 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "inflate: bad header"); + return APR_EGENERAL ; + } + data += 10 ; + len -= 10 ; + } + if (zlib_flags & EXTRA_FIELD) { + unsigned int bytes = (unsigned int)(data[0]); + bytes += ((unsigned int)(data[1])) << 8; + bytes += 2; + if (len < bytes) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "inflate: extra field too big (not " + "supported)"); + return APR_EGENERAL; + } + data += bytes; + len -= bytes; + } + if (zlib_flags & ORIG_NAME) { + while (len-- && *data++); + } + if (zlib_flags & COMMENT) { + while (len-- && *data++); + } + if (zlib_flags & HEAD_CRC) { + len -= 2; + data += 2; + } + } + + /* pass through zlib inflate. */ + ctx->stream.next_in = (unsigned char *)data; + ctx->stream.avail_in = len; + + zRC = Z_OK; + + while (ctx->stream.avail_in != 0) { + if (ctx->stream.avail_out == 0) { + apr_bucket *tmp_heap; + ctx->stream.next_out = ctx->buffer; + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + } + + zRC = inflate(&ctx->stream, Z_NO_FLUSH); + + if (zRC == Z_STREAM_END) { + break; + } + + if (zRC != Z_OK) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + } + if (zRC == Z_STREAM_END) { + apr_bucket *tmp_heap, *eos; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "Zlib: Inflated %ld to %ld : URL %s", + ctx->stream.total_in, ctx->stream.total_out, + r->uri); + + len = c->bufferSize - ctx->stream.avail_out; + + ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); + tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, + NULL, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); + ctx->stream.avail_out = c->bufferSize; + + /* Is the remaining 8 bytes already in the avail stream? */ + if (ctx->stream.avail_in >= 8) { + unsigned long compCRC, compLen; + compCRC = getLong(ctx->stream.next_in); + if (ctx->crc != compCRC) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + ctx->stream.next_in += 4; + compLen = getLong(ctx->stream.next_in); + if (ctx->stream.total_out != compLen) { + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + } + else { + /* FIXME: We need to grab the 8 verification bytes + * from the wire! */ + inflateEnd(&ctx->stream); + return APR_EGENERAL; + } + + inflateEnd(&ctx->stream); + + eos = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); + break; + } + + } + + rv = ap_pass_brigade(f->next, ctx->proc_bb); + apr_brigade_cleanup(ctx->proc_bb); + return rv ; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_register_output_filter(deflateFilterName, deflate_out_filter, NULL, + AP_FTYPE_CONTENT_SET); + ap_register_output_filter("INFLATE", inflate_out_filter, NULL, + AP_FTYPE_RESOURCE-1); + ap_register_input_filter(deflateFilterName, deflate_in_filter, NULL, + AP_FTYPE_CONTENT_SET); +} + +static const command_rec deflate_filter_cmds[] = { + AP_INIT_TAKE12("DeflateFilterNote", deflate_set_note, NULL, RSRC_CONF, + "Set a note to report on compression ratio"), + AP_INIT_TAKE1("DeflateWindowSize", deflate_set_window_size, NULL, + RSRC_CONF, "Set the Deflate window size (1-15)"), + AP_INIT_TAKE1("DeflateBufferSize", deflate_set_buffer_size, NULL, RSRC_CONF, + "Set the Deflate Buffer Size"), + AP_INIT_TAKE1("DeflateMemLevel", deflate_set_memlevel, NULL, RSRC_CONF, + "Set the Deflate Memory Level (1-9)"), + AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF, + "Set the Deflate Compression Level (1-9)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA deflate_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_deflate_server_config, /* server config */ + NULL, /* merge server config */ + deflate_filter_cmds, /* command table */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/filters/mod_deflate.dsp b/trunk/modules/filters/mod_deflate.dsp new file mode 100644 index 0000000000..a105429cfe --- /dev/null +++ b/trunk/modules/filters/mod_deflate.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_deflate" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_deflate - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_deflate.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_deflate.mak" CFG="mod_deflate - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_deflate - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_deflate - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_deflate - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_deflate_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_deflate.so" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so +# ADD LINK32 kernel32.lib zlib.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_deflate.so" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_deflate - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fd"Debug\mod_deflate_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_deflate.so" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so +# ADD LINK32 kernel32.lib zlib.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_deflate.so" /libpath:"../../srclib/zlib" /base:@..\..\os\win32\BaseAddr.ref,mod_deflate.so + +!ENDIF + +# Begin Target + +# Name "mod_deflate - Win32 Release" +# Name "mod_deflate - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_deflate.c +# End Source File +# Begin Source File + +SOURCE=.\mod_deflate.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_deflate - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_deflate.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_deflate.so "deflate_module for Apache" ../../include/ap_release.h > .\mod_deflate.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_deflate - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_deflate.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_deflate.so "deflate_module for Apache" ../../include/ap_release.h > .\mod_deflate.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/filters/mod_deflate.exp b/trunk/modules/filters/mod_deflate.exp new file mode 100644 index 0000000000..9ec76883cd --- /dev/null +++ b/trunk/modules/filters/mod_deflate.exp @@ -0,0 +1 @@ +deflate_module diff --git a/trunk/modules/filters/mod_ext_filter.c b/trunk/modules/filters/mod_ext_filter.c new file mode 100644 index 0000000000..0fbb0f61d8 --- /dev/null +++ b/trunk/modules/filters/mod_ext_filter.c @@ -0,0 +1,907 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_ext_filter allows Unix-style filters to filter http content. + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_protocol.h" +#define CORE_PRIVATE +#include "http_core.h" +#include "apr_buckets.h" +#include "util_filter.h" +#include "util_script.h" +#include "util_time.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "apr_lib.h" +#include "apr_poll.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +typedef struct ef_server_t { + apr_pool_t *p; + apr_hash_t *h; +} ef_server_t; + +typedef struct ef_filter_t { + const char *name; + enum {INPUT_FILTER=1, OUTPUT_FILTER} mode; + ap_filter_type ftype; + const char *command; + const char *enable_env; + const char *disable_env; + char **args; + const char *intype; /* list of IMTs we process (well, just one for now) */ +#define INTYPE_ALL (char *)1 + const char *outtype; /* IMT of filtered output */ +#define OUTTYPE_UNCHANGED (char *)1 + int preserves_content_length; +} ef_filter_t; + +typedef struct ef_dir_t { + int debug; + int log_stderr; +} ef_dir_t; + +typedef struct ef_ctx_t { + apr_pool_t *p; + apr_proc_t *proc; + apr_procattr_t *procattr; + ef_dir_t *dc; + ef_filter_t *filter; + int noop; +#if APR_FILES_AS_SOCKETS + apr_pollset_t *pollset; +#endif +} ef_ctx_t; + +module AP_MODULE_DECLARE_DATA ext_filter_module; +static const server_rec *main_server; + +static apr_status_t ef_output_filter(ap_filter_t *, apr_bucket_brigade *); +static apr_status_t ef_input_filter(ap_filter_t *, apr_bucket_brigade *, + ap_input_mode_t, apr_read_type_e, + apr_off_t); + +#define DBGLVL_SHOWOPTIONS 1 +#define DBGLVL_ERRORCHECK 2 +#define DBGLVL_GORY 9 + +#define ERRFN_USERDATA_KEY "EXTFILTCHILDERRFN" + +static void *create_ef_dir_conf(apr_pool_t *p, char *dummy) +{ + ef_dir_t *dc = (ef_dir_t *)apr_pcalloc(p, sizeof(ef_dir_t)); + + dc->debug = -1; + dc->log_stderr = -1; + + return dc; +} + +static void *create_ef_server_conf(apr_pool_t *p, server_rec *s) +{ + ef_server_t *conf; + + conf = (ef_server_t *)apr_pcalloc(p, sizeof(ef_server_t)); + conf->p = p; + conf->h = apr_hash_make(conf->p); + return conf; +} + +static void *merge_ef_dir_conf(apr_pool_t *p, void *basev, void *overridesv) +{ + ef_dir_t *a = (ef_dir_t *)apr_pcalloc (p, sizeof(ef_dir_t)); + ef_dir_t *base = (ef_dir_t *)basev, *over = (ef_dir_t *)overridesv; + + if (over->debug != -1) { /* if admin coded something... */ + a->debug = over->debug; + } + else { + a->debug = base->debug; + } + + if (over->log_stderr != -1) { /* if admin coded something... */ + a->log_stderr = over->log_stderr; + } + else { + a->log_stderr = base->log_stderr; + } + + return a; +} + +static const char *add_options(cmd_parms *cmd, void *in_dc, + const char *arg) +{ + ef_dir_t *dc = in_dc; + + if (!strncasecmp(arg, "DebugLevel=", 11)) { + dc->debug = atoi(arg + 11); + } + else if (!strcasecmp(arg, "LogStderr")) { + dc->log_stderr = 1; + } + else if (!strcasecmp(arg, "NoLogStderr")) { + dc->log_stderr = 0; + } + else { + return apr_pstrcat(cmd->temp_pool, + "Invalid ExtFilterOptions option: ", + arg, + NULL); + } + + return NULL; +} + +static const char *parse_cmd(apr_pool_t *p, const char **args, ef_filter_t *filter) +{ + if (**args == '"') { + const char *start = *args + 1; + char *parms; + int escaping = 0; + apr_status_t rv; + + ++*args; /* move past leading " */ + /* find true end of args string (accounting for escaped quotes) */ + while (**args && (**args != '"' || (**args == '"' && escaping))) { + if (escaping) { + escaping = 0; + } + else if (**args == '\\') { + escaping = 1; + } + ++*args; + } + if (**args != '"') { + return "Expected cmd= delimiter"; + } + /* copy *just* the arg string for parsing, */ + parms = apr_pstrndup(p, start, *args - start); + ++*args; /* move past trailing " */ + + /* parse and tokenize the args. */ + rv = apr_tokenize_to_argv(parms, &(filter->args), p); + if (rv != APR_SUCCESS) { + return "cmd= parse error"; + } + } + else + { + /* simple path */ + /* Allocate space for two argv pointers and parse the args. */ + filter->args = (char **)apr_palloc(p, 2 * sizeof(char *)); + filter->args[0] = ap_getword_white(p, args); + filter->args[1] = NULL; /* end of args */ + } + if (!filter->args[0]) { + return "Invalid cmd= parameter"; + } + filter->command = filter->args[0]; + + return NULL; +} + +static const char *define_filter(cmd_parms *cmd, void *dummy, const char *args) +{ + ef_server_t *conf = ap_get_module_config(cmd->server->module_config, + &ext_filter_module); + const char *token; + const char *name; + ef_filter_t *filter; + + name = ap_getword_white(cmd->pool, &args); + if (!name) { + return "Filter name not found"; + } + + if (apr_hash_get(conf->h, name, APR_HASH_KEY_STRING)) { + return apr_psprintf(cmd->pool, "ExtFilter %s is already defined", + name); + } + + filter = (ef_filter_t *)apr_pcalloc(conf->p, sizeof(ef_filter_t)); + filter->name = name; + filter->mode = OUTPUT_FILTER; + filter->ftype = AP_FTYPE_RESOURCE; + apr_hash_set(conf->h, name, APR_HASH_KEY_STRING, filter); + + while (*args) { + while (apr_isspace(*args)) { + ++args; + } + + /* Nasty parsing... I wish I could simply use ap_getword_white() + * here and then look at the token, but ap_getword_white() doesn't + * do the right thing when we have cmd="word word word" + */ + if (!strncasecmp(args, "preservescontentlength", 22)) { + token = ap_getword_white(cmd->pool, &args); + if (!strcasecmp(token, "preservescontentlength")) { + filter->preserves_content_length = 1; + } + else { + return apr_psprintf(cmd->pool, + "mangled argument `%s'", + token); + } + continue; + } + + if (!strncasecmp(args, "mode=", 5)) { + args += 5; + token = ap_getword_white(cmd->pool, &args); + if (!strcasecmp(token, "output")) { + filter->mode = OUTPUT_FILTER; + } + else if (!strcasecmp(token, "input")) { + filter->mode = INPUT_FILTER; + } + else { + return apr_psprintf(cmd->pool, "Invalid mode: `%s'", + token); + } + continue; + } + + if (!strncasecmp(args, "ftype=", 6)) { + args += 6; + token = ap_getword_white(cmd->pool, &args); + filter->ftype = atoi(token); + continue; + } + + if (!strncasecmp(args, "enableenv=", 10)) { + args += 10; + token = ap_getword_white(cmd->pool, &args); + filter->enable_env = token; + continue; + } + + if (!strncasecmp(args, "disableenv=", 11)) { + args += 11; + token = ap_getword_white(cmd->pool, &args); + filter->disable_env = token; + continue; + } + + if (!strncasecmp(args, "intype=", 7)) { + args += 7; + filter->intype = ap_getword_white(cmd->pool, &args); + continue; + } + + if (!strncasecmp(args, "outtype=", 8)) { + args += 8; + filter->outtype = ap_getword_white(cmd->pool, &args); + continue; + } + + if (!strncasecmp(args, "cmd=", 4)) { + args += 4; + if ((token = parse_cmd(cmd->pool, &args, filter))) { + return token; + } + continue; + } + + return apr_psprintf(cmd->pool, "Unexpected parameter: `%s'", + args); + } + + /* parsing is done... register the filter + */ + if (filter->mode == OUTPUT_FILTER) { + /* XXX need a way to ensure uniqueness among all filters */ + ap_register_output_filter(filter->name, ef_output_filter, NULL, filter->ftype); + } + else if (filter->mode == INPUT_FILTER) { + /* XXX need a way to ensure uniqueness among all filters */ + ap_register_input_filter(filter->name, ef_input_filter, NULL, filter->ftype); + } + else { + ap_assert(1 != 1); /* we set the field wrong somehow */ + } + + return NULL; +} + +static const command_rec cmds[] = +{ + AP_INIT_ITERATE("ExtFilterOptions", + add_options, + NULL, + ACCESS_CONF, /* same as SetInputFilter/SetOutputFilter */ + "valid options: DebugLevel=n, LogStderr, NoLogStderr"), + AP_INIT_RAW_ARGS("ExtFilterDefine", + define_filter, + NULL, + RSRC_CONF, + "Define an external filter"), + {NULL} +}; + +static int ef_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_s) +{ + main_server = main_s; + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_post_config(ef_init, NULL, NULL, APR_HOOK_MIDDLE); +} + +static apr_status_t set_resource_limits(request_rec *r, + apr_procattr_t *procattr) +{ +#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \ + defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS) + core_dir_config *conf = + (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + apr_status_t rv; + +#ifdef RLIMIT_CPU + rv = apr_procattr_limit_set(procattr, APR_LIMIT_CPU, conf->limit_cpu); + ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */ +#endif +#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + rv = apr_procattr_limit_set(procattr, APR_LIMIT_MEM, conf->limit_mem); + ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */ +#endif +#ifdef RLIMIT_NPROC + rv = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc); + ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */ +#endif + +#endif /* if at least one limit defined */ + + return APR_SUCCESS; +} + +static apr_status_t ef_close_file(void *vfile) +{ + return apr_file_close(vfile); +} + +static void child_errfn(apr_pool_t *pool, apr_status_t err, const char *description) +{ + request_rec *r; + void *vr; + apr_file_t *stderr_log; + char errbuf[200]; + char time_str[APR_CTIME_LEN]; + + apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); + r = vr; + apr_file_open_stderr(&stderr_log, pool); + ap_recent_ctime(time_str, apr_time_now()); + apr_file_printf(stderr_log, + "[%s] [client %s] mod_ext_filter (%d)%s: %s\n", + time_str, + r->connection->remote_ip, + err, + apr_strerror(err, errbuf, sizeof(errbuf)), + description); +} + +/* init_ext_filter_process: get the external filter process going + * This is per-filter-instance (i.e., per-request) initialization. + */ +static apr_status_t init_ext_filter_process(ap_filter_t *f) +{ + ef_ctx_t *ctx = f->ctx; + apr_status_t rc; + ef_dir_t *dc = ctx->dc; + const char * const *env; + + ctx->proc = apr_pcalloc(ctx->p, sizeof(*ctx->proc)); + + rc = apr_procattr_create(&ctx->procattr, ctx->p); + ap_assert(rc == APR_SUCCESS); + + rc = apr_procattr_io_set(ctx->procattr, + APR_CHILD_BLOCK, + APR_CHILD_BLOCK, + APR_CHILD_BLOCK); + ap_assert(rc == APR_SUCCESS); + + rc = set_resource_limits(f->r, ctx->procattr); + ap_assert(rc == APR_SUCCESS); + + if (dc->log_stderr > 0) { + rc = apr_procattr_child_err_set(ctx->procattr, + f->r->server->error_log, /* stderr in child */ + NULL); + ap_assert(rc == APR_SUCCESS); + } + + rc = apr_procattr_child_errfn_set(ctx->procattr, child_errfn); + ap_assert(rc == APR_SUCCESS); + apr_pool_userdata_set(f->r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ctx->p); + + if (dc->debug >= DBGLVL_ERRORCHECK) { + rc = apr_procattr_error_check_set(ctx->procattr, 1); + ap_assert(rc == APR_SUCCESS); + } + + /* add standard CGI variables as well as DOCUMENT_URI, DOCUMENT_PATH_INFO, + * and QUERY_STRING_UNESCAPED + */ + ap_add_cgi_vars(f->r); + ap_add_common_vars(f->r); + apr_table_setn(f->r->subprocess_env, "DOCUMENT_URI", f->r->uri); + apr_table_setn(f->r->subprocess_env, "DOCUMENT_PATH_INFO", f->r->path_info); + if (f->r->args) { + /* QUERY_STRING is added by ap_add_cgi_vars */ + char *arg_copy = apr_pstrdup(f->r->pool, f->r->args); + ap_unescape_url(arg_copy); + apr_table_setn(f->r->subprocess_env, "QUERY_STRING_UNESCAPED", + ap_escape_shell_cmd(f->r->pool, arg_copy)); + } + + env = (const char * const *) ap_create_environment(ctx->p, + f->r->subprocess_env); + + rc = apr_proc_create(ctx->proc, + ctx->filter->command, + (const char * const *)ctx->filter->args, + env, /* environment */ + ctx->procattr, + ctx->p); + if (rc != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, f->r, + "couldn't create child process to run `%s'", + ctx->filter->command); + return rc; + } + + apr_pool_note_subprocess(ctx->p, ctx->proc, APR_KILL_AFTER_TIMEOUT); + + /* We don't want the handle to the child's stdin inherited by any + * other processes created by httpd. Otherwise, when we close our + * handle, the child won't see EOF because another handle will still + * be open. + */ + + apr_pool_cleanup_register(ctx->p, ctx->proc->in, + apr_pool_cleanup_null, /* other mechanism */ + ef_close_file); + +#if APR_FILES_AS_SOCKETS + { + apr_pollfd_t pfd = { 0 }; + + rc = apr_pollset_create(&ctx->pollset, 2, ctx->p, 0); + ap_assert(rc == APR_SUCCESS); + + pfd.p = ctx->p; + pfd.desc_type = APR_POLL_FILE; + pfd.reqevents = APR_POLLOUT; + pfd.desc.f = ctx->proc->in; + rc = apr_pollset_add(ctx->pollset, &pfd); + ap_assert(rc == APR_SUCCESS); + + pfd.reqevents = APR_POLLIN; + pfd.desc.f = ctx->proc->out; + rc = apr_pollset_add(ctx->pollset, &pfd); + ap_assert(rc == APR_SUCCESS); + } +#endif + + return APR_SUCCESS; +} + +static const char *get_cfg_string(ef_dir_t *dc, ef_filter_t *filter, apr_pool_t *p) +{ + const char *debug_str = dc->debug == -1 ? + "DebugLevel=0" : apr_psprintf(p, "DebugLevel=%d", dc->debug); + const char *log_stderr_str = dc->log_stderr < 1 ? + "NoLogStderr" : "LogStderr"; + const char *preserve_content_length_str = filter->preserves_content_length ? + "PreservesContentLength" : "!PreserveContentLength"; + const char *intype_str = !filter->intype ? + "*/*" : filter->intype; + const char *outtype_str = !filter->outtype ? + "(unchanged)" : filter->outtype; + + return apr_psprintf(p, + "ExtFilterOptions %s %s %s ExtFilterInType %s " + "ExtFilterOuttype %s", + debug_str, log_stderr_str, preserve_content_length_str, + intype_str, outtype_str); +} + +static ef_filter_t *find_filter_def(const server_rec *s, const char *fname) +{ + ef_server_t *sc; + ef_filter_t *f; + + sc = ap_get_module_config(s->module_config, &ext_filter_module); + f = apr_hash_get(sc->h, fname, APR_HASH_KEY_STRING); + if (!f && s != main_server) { + s = main_server; + sc = ap_get_module_config(s->module_config, &ext_filter_module); + f = apr_hash_get(sc->h, fname, APR_HASH_KEY_STRING); + } + return f; +} + +static apr_status_t init_filter_instance(ap_filter_t *f) +{ + ef_ctx_t *ctx; + ef_dir_t *dc; + apr_status_t rv; + + f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(ef_ctx_t)); + dc = ap_get_module_config(f->r->per_dir_config, + &ext_filter_module); + ctx->dc = dc; + /* look for the user-defined filter */ + ctx->filter = find_filter_def(f->r->server, f->frec->name); + if (!ctx->filter) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, + "couldn't find definition of filter '%s'", + f->frec->name); + return APR_EINVAL; + } + ctx->p = f->r->pool; + if (ctx->filter->intype && + ctx->filter->intype != INTYPE_ALL) { + const char *ctypes; + + if (ctx->filter->mode == INPUT_FILTER) { + ctypes = apr_table_get(f->r->headers_in, "Content-Type"); + } + else { + ctypes = f->r->content_type; + } + + if (ctypes) { + const char *ctype = ap_getword(f->r->pool, &ctypes, ';'); + + if (strcasecmp(ctx->filter->intype, ctype)) { + /* wrong IMT for us; don't mess with the output */ + ctx->noop = 1; + } + } + else { + ctx->noop = 1; + } + } + if (ctx->filter->enable_env && + !apr_table_get(f->r->subprocess_env, ctx->filter->enable_env)) { + /* an environment variable that enables the filter isn't set; bail */ + ctx->noop = 1; + } + if (ctx->filter->disable_env && + apr_table_get(f->r->subprocess_env, ctx->filter->disable_env)) { + /* an environment variable that disables the filter is set; bail */ + ctx->noop = 1; + } + if (!ctx->noop) { + rv = init_ext_filter_process(f); + if (rv != APR_SUCCESS) { + return rv; + } + if (ctx->filter->outtype && + ctx->filter->outtype != OUTTYPE_UNCHANGED) { + ap_set_content_type(f->r, ctx->filter->outtype); + } + if (ctx->filter->preserves_content_length != 1) { + /* nasty, but needed to avoid confusing the browser + */ + apr_table_unset(f->r->headers_out, "Content-Length"); + } + } + + if (dc->debug >= DBGLVL_SHOWOPTIONS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, + "%sfiltering `%s' of type `%s' through `%s', cfg %s", + ctx->noop ? "NOT " : "", + f->r->uri ? f->r->uri : f->r->filename, + f->r->content_type ? f->r->content_type : "(unspecified)", + ctx->filter->command, + get_cfg_string(dc, ctx->filter, f->r->pool)); + } + + return APR_SUCCESS; +} + +/* drain_available_output(): + * + * if any data is available from the filter, read it and append it + * to the the bucket brigade + */ +static apr_status_t drain_available_output(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + ef_ctx_t *ctx = f->ctx; + ef_dir_t *dc = ctx->dc; + apr_size_t len; + char buf[4096]; + apr_status_t rv; + apr_bucket *b; + + while (1) { + len = sizeof(buf); + rv = apr_file_read(ctx->proc->out, + buf, + &len); + if ((rv && !APR_STATUS_IS_EAGAIN(rv)) || + dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, + "apr_file_read(child output), len %" APR_SIZE_T_FMT, + !rv ? len : -1); + } + if (rv != APR_SUCCESS) { + return rv; + } + b = apr_bucket_heap_create(buf, len, NULL, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + return APR_SUCCESS; + } + /* we should never get here; if we do, a bogus error message would be + * the least of our problems + */ + return APR_ANONYMOUS; +} + +static apr_status_t pass_data_to_filter(ap_filter_t *f, const char *data, + apr_size_t len, apr_bucket_brigade *bb) +{ + ef_ctx_t *ctx = f->ctx; + ef_dir_t *dc = ctx->dc; + apr_status_t rv; + apr_size_t bytes_written = 0; + apr_size_t tmplen; + + do { + tmplen = len - bytes_written; + rv = apr_file_write(ctx->proc->in, + (const char *)data + bytes_written, + &tmplen); + bytes_written += tmplen; + if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, + "apr_file_write(child input), len %" APR_SIZE_T_FMT, + tmplen); + return rv; + } + if (APR_STATUS_IS_EAGAIN(rv)) { + /* XXX handle blocking conditions here... if we block, we need + * to read data from the child process and pass it down to the + * next filter! + */ + rv = drain_available_output(f, bb); + if (APR_STATUS_IS_EAGAIN(rv)) { +#if APR_FILES_AS_SOCKETS + int num_events; + const apr_pollfd_t *pdesc; + + rv = apr_pollset_poll(ctx->pollset, f->r->server->timeout, + &num_events, &pdesc); + if (rv || dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, + rv, f->r, "apr_pollset_poll()"); + } + if (rv != APR_SUCCESS && !APR_STATUS_IS_EINTR(rv)) { + /* some error such as APR_TIMEUP */ + return rv; + } +#else /* APR_FILES_AS_SOCKETS */ + /* Yuck... I'd really like to wait until I can read + * or write, but instead I have to sleep and try again + */ + apr_sleep(100000); /* 100 milliseconds */ + if (dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, + 0, f->r, "apr_sleep()"); + } +#endif /* APR_FILES_AS_SOCKETS */ + } + else if (rv != APR_SUCCESS) { + return rv; + } + } + } while (bytes_written < len); + return rv; +} + +/* ef_unified_filter: + * + * runs the bucket brigade bb through the filter and puts the result into + * bb, dropping the previous content of bb (the input) + */ + +static int ef_unified_filter(ap_filter_t *f, apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + ef_ctx_t *ctx = f->ctx; + apr_bucket *b; + ef_dir_t *dc; + apr_size_t len; + const char *data; + apr_status_t rv; + char buf[4096]; + apr_bucket *eos = NULL; + apr_bucket_brigade *bb_tmp; + + dc = ctx->dc; + bb_tmp = apr_brigade_create(r->pool, c->bucket_alloc); + + for (b = APR_BRIGADE_FIRST(bb); + b != APR_BRIGADE_SENTINEL(bb); + b = APR_BUCKET_NEXT(b)) + { + if (APR_BUCKET_IS_EOS(b)) { + eos = b; + break; + } + + rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "apr_bucket_read()"); + return rv; + } + + /* Good cast, we just tested len isn't negative */ + if (len > 0 && + (rv = pass_data_to_filter(f, data, (apr_size_t)len, bb_tmp)) + != APR_SUCCESS) { + return rv; + } + } + + apr_brigade_cleanup(bb); + APR_BRIGADE_CONCAT(bb, bb_tmp); + apr_brigade_destroy(bb_tmp); + + if (eos) { + /* close the child's stdin to signal that no more data is coming; + * that will cause the child to finish generating output + */ + if ((rv = apr_file_close(ctx->proc->in)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_file_close(child input)"); + return rv; + } + /* since we've seen eos and closed the child's stdin, set the proper pipe + * timeout; we don't care if we don't return from apr_file_read() for a while... + */ + rv = apr_file_pipe_timeout_set(ctx->proc->out, + r->server->timeout); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_file_pipe_timeout_set(child output)"); + return rv; + } + } + + do { + len = sizeof(buf); + rv = apr_file_read(ctx->proc->out, + buf, + &len); + if ((rv && !APR_STATUS_IS_EOF(rv) && !APR_STATUS_IS_EAGAIN(rv)) || + dc->debug >= DBGLVL_GORY) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, + "apr_file_read(child output), len %" APR_SIZE_T_FMT, + !rv ? len : -1); + } + if (APR_STATUS_IS_EAGAIN(rv)) { + if (eos) { + /* should not occur, because we have an APR timeout in place */ + AP_DEBUG_ASSERT(1 != 1); + } + return APR_SUCCESS; + } + + if (rv == APR_SUCCESS) { + b = apr_bucket_heap_create(buf, len, NULL, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + } + } while (rv == APR_SUCCESS); + + if (!APR_STATUS_IS_EOF(rv)) { + return rv; + } + + if (eos) { + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + } + + return APR_SUCCESS; +} + +static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + ef_ctx_t *ctx = f->ctx; + apr_status_t rv; + + if (!ctx) { + if ((rv = init_filter_instance(f)) != APR_SUCCESS) { + return rv; + } + ctx = f->ctx; + } + if (ctx->noop) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + rv = ef_unified_filter(f, bb); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "ef_unified_filter() failed"); + } + + if ((rv = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "ap_pass_brigade() failed"); + } + return rv; +} + +static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) +{ + ef_ctx_t *ctx = f->ctx; + apr_status_t rv; + + if (!ctx) { + if ((rv = init_filter_instance(f)) != APR_SUCCESS) { + return rv; + } + ctx = f->ctx; + } + + if (ctx->noop) { + ap_remove_input_filter(f); + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + rv = ap_get_brigade(f->next, bb, mode, block, readbytes); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = ef_unified_filter(f, bb); + return rv; +} + +module AP_MODULE_DECLARE_DATA ext_filter_module = +{ + STANDARD20_MODULE_STUFF, + create_ef_dir_conf, + merge_ef_dir_conf, + create_ef_server_conf, + NULL, + cmds, + register_hooks +}; diff --git a/trunk/modules/filters/mod_ext_filter.dsp b/trunk/modules/filters/mod_ext_filter.dsp new file mode 100644 index 0000000000..c53c98ea10 --- /dev/null +++ b/trunk/modules/filters/mod_ext_filter.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_ext_filter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_ext_filter - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_ext_filter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_ext_filter.mak" CFG="mod_ext_filter - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_ext_filter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_ext_filter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_ext_filter - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_ext_filter_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_ext_filter - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_ext_filter_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ext_filter.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ext_filter.so + +!ENDIF + +# Begin Target + +# Name "mod_ext_filter - Win32 Release" +# Name "mod_ext_filter - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_ext_filter.c +# End Source File +# Begin Source File + +SOURCE=.\mod_ext_filter.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_ext_filter - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ext_filter.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ext_filter.so "ext_filter_module for Apache" ../../include/ap_release.h > .\mod_ext_filter.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ext_filter - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ext_filter.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ext_filter.so "ext_filter_module for Apache" ../../include/ap_release.h > .\mod_ext_filter.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/filters/mod_ext_filter.exp b/trunk/modules/filters/mod_ext_filter.exp new file mode 100644 index 0000000000..ed3b8fc60c --- /dev/null +++ b/trunk/modules/filters/mod_ext_filter.exp @@ -0,0 +1 @@ +ext_filter_module diff --git a/trunk/modules/filters/mod_include.c b/trunk/modules/filters/mod_include.c new file mode 100644 index 0000000000..71b5e2b5a0 --- /dev/null +++ b/trunk/modules/filters/mod_include.c @@ -0,0 +1,3842 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_thread_proc.h" +#include "apr_hash.h" +#include "apr_user.h" +#include "apr_lib.h" +#include "apr_optional.h" + +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "util_filter.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "util_script.h" +#include "http_core.h" +#include "mod_include.h" + +/* helper for Latin1 <-> entity encoding */ +#if APR_CHARSET_EBCDIC +#include "util_ebcdic.h" +#define RAW_ASCII_CHAR(ch) apr_xlate_conv_byte(ap_hdrs_from_ascii, \ + (unsigned char)ch) +#else /* APR_CHARSET_EBCDIC */ +#define RAW_ASCII_CHAR(ch) (ch) +#endif /* !APR_CHARSET_EBCDIC */ + + +/* + * +-------------------------------------------------------+ + * | | + * | Types and Structures + * | | + * +-------------------------------------------------------+ + */ + +/* sll used for string expansion */ +typedef struct result_item { + struct result_item *next; + apr_size_t len; + const char *string; +} result_item_t; + +/* conditional expression parser stuff */ +typedef enum { + TOKEN_STRING, + TOKEN_RE, + TOKEN_AND, + TOKEN_OR, + TOKEN_NOT, + TOKEN_EQ, + TOKEN_NE, + TOKEN_RBRACE, + TOKEN_LBRACE, + TOKEN_GROUP, + TOKEN_GE, + TOKEN_LE, + TOKEN_GT, + TOKEN_LT +} token_type_t; + +typedef struct { + token_type_t type; + const char *value; +#ifdef DEBUG_INCLUDE + const char *s; +#endif +} token_t; + +typedef struct parse_node { + struct parse_node *parent; + struct parse_node *left; + struct parse_node *right; + token_t token; + int value; + int done; +#ifdef DEBUG_INCLUDE + int dump_done; +#endif +} parse_node_t; + +typedef enum { + XBITHACK_OFF, + XBITHACK_ON, + XBITHACK_FULL +} xbithack_t; + +typedef struct { + const char *default_error_msg; + const char *default_time_fmt; + const char *undefined_echo; + xbithack_t xbithack; +} include_dir_config; + +typedef struct { + const char *default_start_tag; + const char *default_end_tag; +} include_server_config; + +/* main parser states */ +typedef enum { + PARSE_PRE_HEAD, + PARSE_HEAD, + PARSE_DIRECTIVE, + PARSE_DIRECTIVE_POSTNAME, + PARSE_DIRECTIVE_TAIL, + PARSE_DIRECTIVE_POSTTAIL, + PARSE_PRE_ARG, + PARSE_ARG, + PARSE_ARG_NAME, + PARSE_ARG_POSTNAME, + PARSE_ARG_EQ, + PARSE_ARG_PREVAL, + PARSE_ARG_VAL, + PARSE_ARG_VAL_ESC, + PARSE_ARG_POSTVAL, + PARSE_TAIL, + PARSE_TAIL_SEQ, + PARSE_EXECUTE +} parse_state_t; + +typedef struct arg_item { + struct arg_item *next; + char *name; + apr_size_t name_len; + char *value; + apr_size_t value_len; +} arg_item_t; + +typedef struct { + const char *source; + const char *rexp; + apr_size_t nsub; + ap_regmatch_t match[AP_MAX_REG_MATCH]; +} backref_t; + +typedef struct { + unsigned int T[256]; + unsigned int x; + apr_size_t pattern_len; +} bndm_t; + +struct ssi_internal_ctx { + parse_state_t state; + int seen_eos; + int error; + char quote; /* quote character value (or \0) */ + apr_size_t parse_pos; /* parse position of partial matches */ + apr_size_t bytes_read; + + apr_bucket_brigade *tmp_bb; + + request_rec *r; + const char *start_seq; + bndm_t *start_seq_pat; + const char *end_seq; + apr_size_t end_seq_len; + char *directive; /* name of the current directive */ + apr_size_t directive_len; /* length of the current directive name */ + + arg_item_t *current_arg; /* currently parsed argument */ + arg_item_t *argv; /* all arguments */ + + backref_t *re; /* NULL if there wasn't a regex yet */ + + const char *undefined_echo; + apr_size_t undefined_echo_len; + +#ifdef DEBUG_INCLUDE + struct { + ap_filter_t *f; + apr_bucket_brigade *bb; + } debug; +#endif +}; + + +/* + * +-------------------------------------------------------+ + * | | + * | Debugging Utilities + * | | + * +-------------------------------------------------------+ + */ + +#ifdef DEBUG_INCLUDE + +#define TYPE_TOKEN(token, ttype) do { \ + (token)->type = ttype; \ + (token)->s = #ttype; \ +} while(0) + +#define CREATE_NODE(ctx, name) do { \ + (name) = apr_palloc((ctx)->dpool, sizeof(*(name))); \ + (name)->parent = (name)->left = (name)->right = NULL; \ + (name)->done = 0; \ + (name)->dump_done = 0; \ +} while(0) + +static void debug_printf(include_ctx_t *ctx, const char *fmt, ...) +{ + va_list ap; + char *debug__str; + + va_start(ap, fmt); + debug__str = apr_pvsprintf(ctx->pool, fmt, ap); + va_end(ap); + + APR_BRIGADE_INSERT_TAIL(ctx->intern->debug.bb, apr_bucket_pool_create( + debug__str, strlen(debug__str), ctx->pool, + ctx->intern->debug.f->c->bucket_alloc)); +} + +#define DUMP__CHILD(ctx, is, node, child) if (1) { \ + parse_node_t *d__c = node->child; \ + if (d__c) { \ + if (!d__c->dump_done) { \ + if (d__c->parent != node) { \ + debug_printf(ctx, "!!! Parse tree is not consistent !!!\n"); \ + if (!d__c->parent) { \ + debug_printf(ctx, "Parent of " #child " child node is " \ + "NULL.\n"); \ + } \ + else { \ + debug_printf(ctx, "Parent of " #child " child node " \ + "points to another node (of type %s)!\n", \ + d__c->parent->token.s); \ + } \ + return; \ + } \ + node = d__c; \ + continue; \ + } \ + } \ + else { \ + debug_printf(ctx, "%s(missing)\n", is); \ + } \ +} + +static void debug_dump_tree(include_ctx_t *ctx, parse_node_t *root) +{ + parse_node_t *current; + char *is; + + if (!root) { + debug_printf(ctx, " -- Parse Tree empty --\n\n"); + return; + } + + debug_printf(ctx, " ----- Parse Tree -----\n"); + current = root; + is = " "; + + while (current) { + switch (current->token.type) { + case TOKEN_STRING: + case TOKEN_RE: + debug_printf(ctx, "%s%s (%s)\n", is, current->token.s, + current->token.value); + current->dump_done = 1; + current = current->parent; + continue; + + case TOKEN_NOT: + case TOKEN_GROUP: + case TOKEN_RBRACE: + case TOKEN_LBRACE: + if (!current->dump_done) { + debug_printf(ctx, "%s%s\n", is, current->token.s); + is = apr_pstrcat(ctx->dpool, is, " ", NULL); + current->dump_done = 1; + } + + DUMP__CHILD(ctx, is, current, right) + + if (!current->right || current->right->dump_done) { + is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4); + if (current->right) current->right->dump_done = 0; + current = current->parent; + } + continue; + + default: + if (!current->dump_done) { + debug_printf(ctx, "%s%s\n", is, current->token.s); + is = apr_pstrcat(ctx->dpool, is, " ", NULL); + current->dump_done = 1; + } + + DUMP__CHILD(ctx, is, current, left) + DUMP__CHILD(ctx, is, current, right) + + if ((!current->left || current->left->dump_done) && + (!current->right || current->right->dump_done)) { + + is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4); + if (current->left) current->left->dump_done = 0; + if (current->right) current->right->dump_done = 0; + current = current->parent; + } + continue; + } + } + + /* it is possible to call this function within the parser loop, to see + * how the tree is built. That way, we must cleanup after us to dump + * always the whole tree + */ + root->dump_done = 0; + if (root->left) root->left->dump_done = 0; + if (root->right) root->right->dump_done = 0; + + debug_printf(ctx, " --- End Parse Tree ---\n\n"); + + return; +} + +#define DEBUG_INIT(ctx, filter, brigade) do { \ + (ctx)->intern->debug.f = filter; \ + (ctx)->intern->debug.bb = brigade; \ +} while(0) + +#define DEBUG_PRINTF(arg) debug_printf arg + +#define DEBUG_DUMP_TOKEN(ctx, token) do { \ + token_t *d__t = (token); \ + \ + if (d__t->type == TOKEN_STRING || d__t->type == TOKEN_RE) { \ + DEBUG_PRINTF(((ctx), " Found: %s (%s)\n", d__t->s, d__t->value)); \ + } \ + else { \ + DEBUG_PRINTF((ctx, " Found: %s\n", d__t->s)); \ + } \ +} while(0) + +#define DEBUG_DUMP_EVAL(ctx, node) do { \ + char c = '"'; \ + switch ((node)->token.type) { \ + case TOKEN_STRING: \ + debug_printf((ctx), " Evaluate: %s (%s) -> %c\n", (node)->token.s,\ + (node)->token.value, ((node)->value) ? '1':'0'); \ + break; \ + case TOKEN_AND: \ + case TOKEN_OR: \ + debug_printf((ctx), " Evaluate: %s (Left: %s; Right: %s) -> %c\n",\ + (node)->token.s, \ + (((node)->left->done) ? ((node)->left->value ?"1":"0") \ + : "short circuited"), \ + (((node)->right->done) ? ((node)->right->value?"1":"0") \ + : "short circuited"), \ + (node)->value ? '1' : '0'); \ + break; \ + case TOKEN_EQ: \ + case TOKEN_NE: \ + case TOKEN_GT: \ + case TOKEN_GE: \ + case TOKEN_LT: \ + case TOKEN_LE: \ + if ((node)->right->token.type == TOKEN_RE) c = '/'; \ + debug_printf((ctx), " Compare: %s (\"%s\" with %c%s%c) -> %c\n", \ + (node)->token.s, \ + (node)->left->token.value, \ + c, (node)->right->token.value, c, \ + (node)->value ? '1' : '0'); \ + break; \ + default: \ + debug_printf((ctx), " Evaluate: %s -> %c\n", (node)->token.s, \ + (node)->value ? '1' : '0'); \ + break; \ + } \ +} while(0) + +#define DEBUG_DUMP_UNMATCHED(ctx, unmatched) do { \ + if (unmatched) { \ + DEBUG_PRINTF(((ctx), " Unmatched %c\n", (char)(unmatched))); \ + } \ +} while(0) + +#define DEBUG_DUMP_COND(ctx, text) \ + DEBUG_PRINTF(((ctx), "**** %s cond status=\"%c\"\n", (text), \ + ((ctx)->flags & SSI_FLAG_COND_TRUE) ? '1' : '0')) + +#define DEBUG_DUMP_TREE(ctx, root) debug_dump_tree(ctx, root) + +#else /* DEBUG_INCLUDE */ + +#define TYPE_TOKEN(token, ttype) (token)->type = ttype + +#define CREATE_NODE(ctx, name) do { \ + (name) = apr_palloc((ctx)->dpool, sizeof(*(name))); \ + (name)->parent = (name)->left = (name)->right = NULL; \ + (name)->done = 0; \ +} while(0) + +#define DEBUG_INIT(ctx, f, bb) +#define DEBUG_PRINTF(arg) +#define DEBUG_DUMP_TOKEN(ctx, token) +#define DEBUG_DUMP_EVAL(ctx, node) +#define DEBUG_DUMP_UNMATCHED(ctx, unmatched) +#define DEBUG_DUMP_COND(ctx, text) +#define DEBUG_DUMP_TREE(ctx, root) + +#endif /* !DEBUG_INCLUDE */ + + +/* + * +-------------------------------------------------------+ + * | | + * | Static Module Data + * | | + * +-------------------------------------------------------+ + */ + +/* global module structure */ +module AP_MODULE_DECLARE_DATA include_module; + +/* function handlers for include directives */ +static apr_hash_t *include_handlers; + +/* forward declaration of handler registry */ +static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *ssi_pfn_register; + +/* Sentinel value to store in subprocess_env for items that + * shouldn't be evaluated until/unless they're actually used + */ +static const char lazy_eval_sentinel; +#define LAZY_VALUE (&lazy_eval_sentinel) + +/* default values */ +#define DEFAULT_START_SEQUENCE "" +#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]" +#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z" +#define DEFAULT_UNDEFINED_ECHO "(none)" + +#ifdef XBITHACK +#define DEFAULT_XBITHACK XBITHACK_FULL +#else +#define DEFAULT_XBITHACK XBITHACK_OFF +#endif + + +/* + * +-------------------------------------------------------+ + * | | + * | Environment/Expansion Functions + * | | + * +-------------------------------------------------------+ + */ + +/* + * decodes a string containing html entities or numeric character references. + * 's' is overwritten with the decoded string. + * If 's' is syntatically incorrect, then the followed fixups will be made: + * unknown entities will be left undecoded; + * references to unused numeric characters will be deleted. + * In particular, � will not be decoded, but will be deleted. + */ + +/* maximum length of any ISO-LATIN-1 HTML entity name. */ +#define MAXENTLEN (6) + +/* The following is a shrinking transformation, therefore safe. */ + +static void decodehtml(char *s) +{ + int val, i, j; + char *p; + const char *ents; + static const char * const entlist[MAXENTLEN + 1] = + { + NULL, /* 0 */ + NULL, /* 1 */ + "lt\074gt\076", /* 2 */ + "amp\046ETH\320eth\360", /* 3 */ + "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml" + "\353iuml\357ouml\366uuml\374yuml\377", /* 4 */ + + "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc" + "\333THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352" + "icirc\356ocirc\364ucirc\373thorn\376", /* 5 */ + + "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311" + "Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde" + "\325Oslash\330Ugrave\331Uacute\332Yacute\335agrave\340" + "aacute\341atilde\343ccedil\347egrave\350eacute\351igrave" + "\354iacute\355ntilde\361ograve\362oacute\363otilde\365" + "oslash\370ugrave\371uacute\372yacute\375" /* 6 */ + }; + + /* Do a fast scan through the string until we find anything + * that needs more complicated handling + */ + for (; *s != '&'; s++) { + if (*s == '\0') { + return; + } + } + + for (p = s; *s != '\0'; s++, p++) { + if (*s != '&') { + *p = *s; + continue; + } + /* find end of entity */ + for (i = 1; s[i] != ';' && s[i] != '\0'; i++) { + continue; + } + + if (s[i] == '\0') { /* treat as normal data */ + *p = *s; + continue; + } + + /* is it numeric ? */ + if (s[1] == '#') { + for (j = 2, val = 0; j < i && apr_isdigit(s[j]); j++) { + val = val * 10 + s[j] - '0'; + } + s += i; + if (j < i || val <= 8 || (val >= 11 && val <= 31) || + (val >= 127 && val <= 160) || val >= 256) { + p--; /* no data to output */ + } + else { + *p = RAW_ASCII_CHAR(val); + } + } + else { + j = i - 1; + if (j > MAXENTLEN || entlist[j] == NULL) { + /* wrong length */ + *p = '&'; + continue; /* skip it */ + } + for (ents = entlist[j]; *ents != '\0'; ents += i) { + if (strncmp(s + 1, ents, j) == 0) { + break; + } + } + + if (*ents == '\0') { + *p = '&'; /* unknown */ + } + else { + *p = RAW_ASCII_CHAR(((const unsigned char *) ents)[j]); + s += i; + } + } + } + + *p = '\0'; +} + +static void add_include_vars(request_rec *r, const char *timefmt) +{ + apr_table_t *e = r->subprocess_env; + char *t; + + apr_table_setn(e, "DATE_LOCAL", LAZY_VALUE); + apr_table_setn(e, "DATE_GMT", LAZY_VALUE); + apr_table_setn(e, "LAST_MODIFIED", LAZY_VALUE); + apr_table_setn(e, "DOCUMENT_URI", r->uri); + if (r->path_info && *r->path_info) { + apr_table_setn(e, "DOCUMENT_PATH_INFO", r->path_info); + } + apr_table_setn(e, "USER_NAME", LAZY_VALUE); + if (r->filename && (t = strrchr(r->filename, '/'))) { + apr_table_setn(e, "DOCUMENT_NAME", ++t); + } + else { + apr_table_setn(e, "DOCUMENT_NAME", r->uri); + } + if (r->args) { + char *arg_copy = apr_pstrdup(r->pool, r->args); + + ap_unescape_url(arg_copy); + apr_table_setn(e, "QUERY_STRING_UNESCAPED", + ap_escape_shell_cmd(r->pool, arg_copy)); + } +} + +static const char *add_include_vars_lazy(request_rec *r, const char *var) +{ + char *val; + if (!strcasecmp(var, "DATE_LOCAL")) { + include_dir_config *conf = + (include_dir_config *)ap_get_module_config(r->per_dir_config, + &include_module); + val = ap_ht_time(r->pool, r->request_time, conf->default_time_fmt, 0); + } + else if (!strcasecmp(var, "DATE_GMT")) { + include_dir_config *conf = + (include_dir_config *)ap_get_module_config(r->per_dir_config, + &include_module); + val = ap_ht_time(r->pool, r->request_time, conf->default_time_fmt, 1); + } + else if (!strcasecmp(var, "LAST_MODIFIED")) { + include_dir_config *conf = + (include_dir_config *)ap_get_module_config(r->per_dir_config, + &include_module); + val = ap_ht_time(r->pool, r->finfo.mtime, conf->default_time_fmt, 0); + } + else if (!strcasecmp(var, "USER_NAME")) { + if (apr_uid_name_get(&val, r->finfo.user, r->pool) != APR_SUCCESS) { + val = ""; + } + } + else { + val = NULL; + } + + if (val) { + apr_table_setn(r->subprocess_env, var, val); + } + return val; +} + +static const char *get_include_var(const char *var, include_ctx_t *ctx) +{ + const char *val; + request_rec *r = ctx->intern->r; + + if (apr_isdigit(*var) && !var[1]) { + apr_size_t idx = *var - '0'; + backref_t *re = ctx->intern->re; + + /* Handle $0 .. $9 from the last regex evaluated. + * The choice of returning NULL strings on not-found, + * v.s. empty strings on an empty match is deliberate. + */ + if (!re) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "regex capture $%" APR_SIZE_T_FMT " refers to no regex in %s", + idx, r->filename); + return NULL; + } + else { + if (re->nsub < idx || idx >= AP_MAX_REG_MATCH) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "regex capture $%" APR_SIZE_T_FMT + " is out of range (last regex was: '%s') in %s", + idx, re->rexp, r->filename); + return NULL; + } + + if (re->match[idx].rm_so < 0 || re->match[idx].rm_eo < 0) { + return NULL; + } + + val = apr_pstrmemdup(ctx->dpool, re->source + re->match[idx].rm_so, + re->match[idx].rm_eo - re->match[idx].rm_so); + } + } + else { + val = apr_table_get(r->subprocess_env, var); + + if (val == LAZY_VALUE) { + val = add_include_vars_lazy(r, var); + } + } + + return val; +} + +/* + * Do variable substitution on strings + * + * (Note: If out==NULL, this function allocs a buffer for the resulting + * string from ctx->pool. The return value is always the parsed string) + */ +static char *ap_ssi_parse_string(include_ctx_t *ctx, const char *in, char *out, + apr_size_t length, int leave_name) +{ + request_rec *r = ctx->intern->r; + result_item_t *result = NULL, *current = NULL; + apr_size_t outlen = 0, inlen, span; + char *ret = NULL, *eout = NULL; + const char *p; + + if (out) { + /* sanity check, out && !length is not supported */ + ap_assert(out && length); + + ret = out; + eout = out + length - 1; + } + + span = strcspn(in, "\\$"); + inlen = strlen(in); + + /* fast exit */ + if (inlen == span) { + if (out) { + apr_cpystrn(out, in, length); + } + else { + ret = apr_pstrmemdup(ctx->pool, in, (length && length <= inlen) + ? length - 1 : inlen); + } + + return ret; + } + + /* well, actually something to do */ + p = in + span; + + if (out) { + if (span) { + memcpy(out, in, (out+span <= eout) ? span : (eout-out)); + out += span; + } + } + else { + current = result = apr_palloc(ctx->dpool, sizeof(*result)); + current->next = NULL; + current->string = in; + current->len = span; + outlen = span; + } + + /* loop for specials */ + do { + if ((out && out >= eout) || (length && outlen >= length)) { + break; + } + + /* prepare next entry */ + if (!out && current->len) { + current->next = apr_palloc(ctx->dpool, sizeof(*current->next)); + current = current->next; + current->next = NULL; + current->len = 0; + } + + /* + * escaped character + */ + if (*p == '\\') { + if (out) { + *out++ = (p[1] == '$') ? *++p : *p; + ++p; + } + else { + current->len = 1; + current->string = (p[1] == '$') ? ++p : p; + ++p; + ++outlen; + } + } + + /* + * variable expansion + */ + else { /* *p == '$' */ + const char *newp = NULL, *ep, *key = NULL; + + if (*++p == '{') { + ep = ap_strchr_c(++p, '}'); + if (!ep) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Missing '}' on " + "variable \"%s\" in %s", p, r->filename); + break; + } + + if (p < ep) { + key = apr_pstrmemdup(ctx->dpool, p, ep - p); + newp = ep + 1; + } + p -= 2; + } + else { + ep = p; + while (*ep == '_' || apr_isalnum(*ep)) { + ++ep; + } + + if (p < ep) { + key = apr_pstrmemdup(ctx->dpool, p, ep - p); + newp = ep; + } + --p; + } + + /* empty name results in a copy of '$' in the output string */ + if (!key) { + if (out) { + *out++ = *p++; + } + else { + current->len = 1; + current->string = p++; + ++outlen; + } + } + else { + const char *val = get_include_var(key, ctx); + apr_size_t len = 0; + + if (val) { + len = strlen(val); + } + else if (leave_name) { + val = p; + len = ep - p; + } + + if (val && len) { + if (out) { + memcpy(out, val, (out+len <= eout) ? len : (eout-out)); + out += len; + } + else { + current->len = len; + current->string = val; + outlen += len; + } + } + + p = newp; + } + } + + if ((out && out >= eout) || (length && outlen >= length)) { + break; + } + + /* check the remainder */ + if (*p && (span = strcspn(p, "\\$")) > 0) { + if (!out && current->len) { + current->next = apr_palloc(ctx->dpool, sizeof(*current->next)); + current = current->next; + current->next = NULL; + } + + if (out) { + memcpy(out, p, (out+span <= eout) ? span : (eout-out)); + out += span; + } + else { + current->len = span; + current->string = p; + outlen += span; + } + + p += span; + } + } while (p < in+inlen); + + /* assemble result */ + if (out) { + if (out > eout) { + *eout = '\0'; + } + else { + *out = '\0'; + } + } + else { + const char *ep; + + if (length && outlen > length) { + outlen = length - 1; + } + + ret = out = apr_palloc(ctx->pool, outlen + 1); + ep = ret + outlen; + + do { + if (result->len) { + memcpy(out, result->string, (out+result->len <= ep) + ? result->len : (ep-out)); + out += result->len; + } + result = result->next; + } while (result && out < ep); + + ret[outlen] = '\0'; + } + + return ret; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Conditional Expression Parser + * | | + * +-------------------------------------------------------+ + */ + +static APR_INLINE int re_check(include_ctx_t *ctx, const char *string, + const char *rexp) +{ + ap_regex_t *compiled; + backref_t *re = ctx->intern->re; + int rc; + + compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED); + if (!compiled) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->intern->r, "unable to " + "compile pattern \"%s\"", rexp); + return -1; + } + + if (!re) { + re = ctx->intern->re = apr_palloc(ctx->pool, sizeof(*re)); + } + + re->source = apr_pstrdup(ctx->pool, string); + re->rexp = apr_pstrdup(ctx->pool, rexp); + re->nsub = compiled->re_nsub; + rc = !ap_regexec(compiled, string, AP_MAX_REG_MATCH, re->match, 0); + + ap_pregfree(ctx->dpool, compiled); + return rc; +} + +static int get_ptoken(apr_pool_t *pool, const char **parse, token_t *token) +{ + const char *p; + apr_size_t shift; + int unmatched; + + token->value = NULL; + + if (!*parse) { + return 0; + } + + /* Skip leading white space */ + while (apr_isspace(**parse)) { + ++*parse; + } + + if (!**parse) { + *parse = NULL; + return 0; + } + + TYPE_TOKEN(token, TOKEN_STRING); /* the default type */ + p = *parse; + unmatched = 0; + + switch (*(*parse)++) { + case '(': + TYPE_TOKEN(token, TOKEN_LBRACE); + return 0; + case ')': + TYPE_TOKEN(token, TOKEN_RBRACE); + return 0; + case '=': + if (**parse == '=') ++*parse; + TYPE_TOKEN(token, TOKEN_EQ); + return 0; + case '!': + if (**parse == '=') { + TYPE_TOKEN(token, TOKEN_NE); + ++*parse; + return 0; + } + TYPE_TOKEN(token, TOKEN_NOT); + return 0; + case '\'': + unmatched = '\''; + break; + case '/': + TYPE_TOKEN(token, TOKEN_RE); + unmatched = '/'; + break; + case '|': + if (**parse == '|') { + TYPE_TOKEN(token, TOKEN_OR); + ++*parse; + return 0; + } + break; + case '&': + if (**parse == '&') { + TYPE_TOKEN(token, TOKEN_AND); + ++*parse; + return 0; + } + break; + case '>': + if (**parse == '=') { + TYPE_TOKEN(token, TOKEN_GE); + ++*parse; + return 0; + } + TYPE_TOKEN(token, TOKEN_GT); + return 0; + case '<': + if (**parse == '=') { + TYPE_TOKEN(token, TOKEN_LE); + ++*parse; + return 0; + } + TYPE_TOKEN(token, TOKEN_LT); + return 0; + } + + /* It's a string or regex token + * Now search for the next token, which finishes this string + */ + shift = 0; + p = *parse = token->value = unmatched ? *parse : p; + + for (; **parse; p = ++*parse) { + if (**parse == '\\') { + if (!*(++*parse)) { + p = *parse; + break; + } + + ++shift; + } + else { + if (unmatched) { + if (**parse == unmatched) { + unmatched = 0; + ++*parse; + break; + } + } else if (apr_isspace(**parse)) { + break; + } + else { + int found = 0; + + switch (**parse) { + case '(': + case ')': + case '=': + case '!': + case '<': + case '>': + ++found; + break; + + case '|': + case '&': + if ((*parse)[1] == **parse) { + ++found; + } + break; + } + + if (found) { + break; + } + } + } + } + + if (unmatched) { + token->value = apr_pstrdup(pool, ""); + } + else { + apr_size_t len = p - token->value - shift; + char *c = apr_palloc(pool, len + 1); + + p = token->value; + token->value = c; + + while (shift--) { + const char *e = ap_strchr_c(p, '\\'); + + memcpy(c, p, e-p); + c += e-p; + *c++ = *++e; + len -= e-p; + p = e+1; + } + + if (len) { + memcpy(c, p, len); + } + c[len] = '\0'; + } + + return unmatched; +} + +static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error) +{ + parse_node_t *new, *root = NULL, *current = NULL; + request_rec *r = ctx->intern->r; + const char *error = "Invalid expression \"%s\" in file %s"; + const char *parse = expr; + int was_unmatched = 0; + unsigned regex = 0; + + *was_error = 0; + + if (!parse) { + return 0; + } + + /* Create Parse Tree */ + while (1) { + /* uncomment this to see how the tree a built: + * + * DEBUG_DUMP_TREE(ctx, root); + */ + CREATE_NODE(ctx, new); + + was_unmatched = get_ptoken(ctx->dpool, &parse, &new->token); + if (!parse) { + break; + } + + DEBUG_DUMP_UNMATCHED(ctx, was_unmatched); + DEBUG_DUMP_TOKEN(ctx, &new->token); + + if (!current) { + switch (new->token.type) { + case TOKEN_STRING: + case TOKEN_NOT: + case TOKEN_LBRACE: + root = current = new; + continue; + + default: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr, + r->filename); + *was_error = 1; + return 0; + } + } + + switch (new->token.type) { + case TOKEN_STRING: + switch (current->token.type) { + case TOKEN_STRING: + current->token.value = + apr_pstrcat(ctx->dpool, current->token.value, + *current->token.value ? " " : "", + new->token.value, NULL); + continue; + + case TOKEN_RE: + case TOKEN_RBRACE: + case TOKEN_GROUP: + break; + + default: + new->parent = current; + current = current->right = new; + continue; + } + break; + + case TOKEN_RE: + switch (current->token.type) { + case TOKEN_EQ: + case TOKEN_NE: + new->parent = current; + current = current->right = new; + ++regex; + continue; + + default: + break; + } + break; + + case TOKEN_AND: + case TOKEN_OR: + switch (current->token.type) { + case TOKEN_STRING: + case TOKEN_RE: + case TOKEN_GROUP: + current = current->parent; + + while (current) { + switch (current->token.type) { + case TOKEN_AND: + case TOKEN_OR: + case TOKEN_LBRACE: + break; + + default: + current = current->parent; + continue; + } + break; + } + + if (!current) { + new->left = root; + root->parent = new; + current = root = new; + continue; + } + + new->left = current->right; + new->left->parent = new; + new->parent = current; + current = current->right = new; + continue; + + default: + break; + } + break; + + case TOKEN_EQ: + case TOKEN_NE: + case TOKEN_GE: + case TOKEN_GT: + case TOKEN_LE: + case TOKEN_LT: + if (current->token.type == TOKEN_STRING) { + current = current->parent; + + if (!current) { + new->left = root; + root->parent = new; + current = root = new; + continue; + } + + switch (current->token.type) { + case TOKEN_LBRACE: + case TOKEN_AND: + case TOKEN_OR: + new->left = current->right; + new->left->parent = new; + new->parent = current; + current = current->right = new; + continue; + + default: + break; + } + } + break; + + case TOKEN_RBRACE: + while (current && current->token.type != TOKEN_LBRACE) { + current = current->parent; + } + + if (current) { + TYPE_TOKEN(¤t->token, TOKEN_GROUP); + continue; + } + + error = "Unmatched ')' in \"%s\" in file %s"; + break; + + case TOKEN_NOT: + case TOKEN_LBRACE: + switch (current->token.type) { + case TOKEN_STRING: + case TOKEN_RE: + case TOKEN_RBRACE: + case TOKEN_GROUP: + break; + + default: + current->right = new; + new->parent = current; + current = new; + continue; + } + break; + + default: + break; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr, r->filename); + *was_error = 1; + return 0; + } + + DEBUG_DUMP_TREE(ctx, root); + + /* Evaluate Parse Tree */ + current = root; + error = NULL; + while (current) { + switch (current->token.type) { + case TOKEN_STRING: + current->token.value = + ap_ssi_parse_string(ctx, current->token.value, NULL, 0, + SSI_EXPAND_DROP_NAME); + current->value = !!*current->token.value; + break; + + case TOKEN_AND: + case TOKEN_OR: + if (!current->left || !current->right) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid expression \"%s\" in file %s", + expr, r->filename); + *was_error = 1; + return 0; + } + + if (!current->left->done) { + switch (current->left->token.type) { + case TOKEN_STRING: + current->left->token.value = + ap_ssi_parse_string(ctx, current->left->token.value, + NULL, 0, SSI_EXPAND_DROP_NAME); + current->left->value = !!*current->left->token.value; + DEBUG_DUMP_EVAL(ctx, current->left); + current->left->done = 1; + break; + + default: + current = current->left; + continue; + } + } + + /* short circuit evaluation */ + if (!current->right->done && !regex && + ((current->token.type == TOKEN_AND && !current->left->value) || + (current->token.type == TOKEN_OR && current->left->value))) { + current->value = current->left->value; + } + else { + if (!current->right->done) { + switch (current->right->token.type) { + case TOKEN_STRING: + current->right->token.value = + ap_ssi_parse_string(ctx,current->right->token.value, + NULL, 0, SSI_EXPAND_DROP_NAME); + current->right->value = !!*current->right->token.value; + DEBUG_DUMP_EVAL(ctx, current->right); + current->right->done = 1; + break; + + default: + current = current->right; + continue; + } + } + + if (current->token.type == TOKEN_AND) { + current->value = current->left->value && + current->right->value; + } + else { + current->value = current->left->value || + current->right->value; + } + } + break; + + case TOKEN_EQ: + case TOKEN_NE: + if (!current->left || !current->right || + current->left->token.type != TOKEN_STRING || + (current->right->token.type != TOKEN_STRING && + current->right->token.type != TOKEN_RE)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid expression \"%s\" in file %s", + expr, r->filename); + *was_error = 1; + return 0; + } + current->left->token.value = + ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0, + SSI_EXPAND_DROP_NAME); + current->right->token.value = + ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0, + SSI_EXPAND_DROP_NAME); + + if (current->right->token.type == TOKEN_RE) { + current->value = re_check(ctx, current->left->token.value, + current->right->token.value); + --regex; + } + else { + current->value = !strcmp(current->left->token.value, + current->right->token.value); + } + + if (current->token.type == TOKEN_NE) { + current->value = !current->value; + } + break; + + case TOKEN_GE: + case TOKEN_GT: + case TOKEN_LE: + case TOKEN_LT: + if (!current->left || !current->right || + current->left->token.type != TOKEN_STRING || + current->right->token.type != TOKEN_STRING) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid expression \"%s\" in file %s", + expr, r->filename); + *was_error = 1; + return 0; + } + + current->left->token.value = + ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0, + SSI_EXPAND_DROP_NAME); + current->right->token.value = + ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0, + SSI_EXPAND_DROP_NAME); + + current->value = strcmp(current->left->token.value, + current->right->token.value); + + switch (current->token.type) { + case TOKEN_GE: current->value = current->value >= 0; break; + case TOKEN_GT: current->value = current->value > 0; break; + case TOKEN_LE: current->value = current->value <= 0; break; + case TOKEN_LT: current->value = current->value < 0; break; + default: current->value = 0; break; /* should not happen */ + } + break; + + case TOKEN_NOT: + case TOKEN_GROUP: + if (current->right) { + if (!current->right->done) { + current = current->right; + continue; + } + current->value = current->right->value; + } + else { + current->value = 1; + } + + if (current->token.type == TOKEN_NOT) { + current->value = !current->value; + } + break; + + case TOKEN_RE: + if (!error) { + error = "No operator before regex in expr \"%s\" in file %s"; + } + case TOKEN_LBRACE: + if (!error) { + error = "Unmatched '(' in \"%s\" in file %s"; + } + default: + if (!error) { + error = "internal parser error in \"%s\" in file %s"; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr,r->filename); + *was_error = 1; + return 0; + } + + DEBUG_DUMP_EVAL(ctx, current); + current->done = 1; + current = current->parent; + } + + return (root ? root->value : 0); +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Action Handlers + * | | + * +-------------------------------------------------------+ + */ + +/* + * Extract the next tag name and value. + * If there are no more tags, set the tag name to NULL. + * The tag value is html decoded if dodecode is non-zero. + * The tag value may be NULL if there is no tag value.. + */ +static void ap_ssi_get_tag_and_value(include_ctx_t *ctx, char **tag, + char **tag_val, int dodecode) +{ + if (!ctx->intern->argv) { + *tag = NULL; + *tag_val = NULL; + + return; + } + + *tag_val = ctx->intern->argv->value; + *tag = ctx->intern->argv->name; + + ctx->intern->argv = ctx->intern->argv->next; + + if (dodecode && *tag_val) { + decodehtml(*tag_val); + } + + return; +} + +static int find_file(request_rec *r, const char *directive, const char *tag, + char *tag_val, apr_finfo_t *finfo) +{ + char *to_send = tag_val; + request_rec *rr = NULL; + int ret=0; + char *error_fmt = NULL; + apr_status_t rv = APR_SUCCESS; + + if (!strcmp(tag, "file")) { + char *newpath; + + /* be safe; only files in this directory or below allowed */ + rv = apr_filepath_merge(&newpath, NULL, tag_val, + APR_FILEPATH_NOTABOVEROOT | + APR_FILEPATH_SECUREROOTTEST | + APR_FILEPATH_NOTABSOLUTE, r->pool); + + if (rv != APR_SUCCESS) { + error_fmt = "unable to access file \"%s\" " + "in parsed file %s"; + } + else { + /* note: it is okay to pass NULL for the "next filter" since + we never attempt to "run" this sub request. */ + rr = ap_sub_req_lookup_file(newpath, r, NULL); + + if (rr->status == HTTP_OK && rr->finfo.filetype != 0) { + to_send = rr->filename; + if ((rv = apr_stat(finfo, to_send, + APR_FINFO_GPROT | APR_FINFO_MIN, rr->pool)) != APR_SUCCESS + && rv != APR_INCOMPLETE) { + error_fmt = "unable to get information about \"%s\" " + "in parsed file %s"; + } + } + else { + error_fmt = "unable to lookup information about \"%s\" " + "in parsed file %s"; + } + } + + if (error_fmt) { + ret = -1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, + rv, r, error_fmt, to_send, r->filename); + } + + if (rr) ap_destroy_sub_req(rr); + + return ret; + } + else if (!strcmp(tag, "virtual")) { + /* note: it is okay to pass NULL for the "next filter" since + we never attempt to "run" this sub request. */ + rr = ap_sub_req_lookup_uri(tag_val, r, NULL); + + if (rr->status == HTTP_OK && rr->finfo.filetype != 0) { + memcpy((char *) finfo, (const char *) &rr->finfo, + sizeof(rr->finfo)); + ap_destroy_sub_req(rr); + return 0; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unable to get " + "information about \"%s\" in parsed file %s", + tag_val, r->filename); + ap_destroy_sub_req(rr); + return -1; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter \"%s\" " + "to tag %s in %s", tag, directive, r->filename); + return -1; + } +} + +/* + * + */ +static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for include element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + request_rec *rr = NULL; + char *error_fmt = NULL; + char *parsed_string; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (strcmp(tag, "virtual") && strcmp(tag, "file")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " + "\"%s\" to tag include in %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + + parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + if (tag[0] == 'f') { + char *newpath; + apr_status_t rv; + + /* be safe; only files in this directory or below allowed */ + rv = apr_filepath_merge(&newpath, NULL, parsed_string, + APR_FILEPATH_NOTABOVEROOT | + APR_FILEPATH_SECUREROOTTEST | + APR_FILEPATH_NOTABSOLUTE, ctx->dpool); + + if (rv != APR_SUCCESS) { + error_fmt = "unable to include file \"%s\" in parsed file %s"; + } + else { + rr = ap_sub_req_lookup_file(newpath, r, f->next); + } + } + else { + rr = ap_sub_req_lookup_uri(parsed_string, r, f->next); + } + + if (!error_fmt && rr->status != HTTP_OK) { + error_fmt = "unable to include \"%s\" in parsed file %s"; + } + + if (!error_fmt && (ctx->flags & SSI_FLAG_NO_EXEC) && + rr->content_type && strncmp(rr->content_type, "text/", 5)) { + + error_fmt = "unable to include potential exec \"%s\" in parsed " + "file %s"; + } + + /* See the Kludge in includes_filter for why. + * Basically, it puts a bread crumb in here, then looks + * for the crumb later to see if its been here. + */ + if (rr) { + ap_set_module_config(rr->request_config, &include_module, r); + } + + if (!error_fmt && ap_run_sub_req(rr)) { + error_fmt = "unable to include \"%s\" in parsed file %s"; + } + + if (error_fmt) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error_fmt, tag_val, + r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + } + + /* Do *not* destroy the subrequest here; it may have allocated + * variables in this r->subprocess_env in the subrequest's + * r->pool, so that pool must survive as long as this request. + * Yes, this is a memory leak. */ + + if (error_fmt) { + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_echo(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + enum {E_NONE, E_URL, E_ENTITY} encode; + request_rec *r = f->r; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for echo element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + encode = E_ENTITY; + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "var")) { + const char *val; + const char *echo_text = NULL; + apr_size_t e_len; + + val = get_include_var(ap_ssi_parse_string(ctx, tag_val, NULL, + 0, SSI_EXPAND_DROP_NAME), + ctx); + + if (val) { + switch(encode) { + case E_NONE: + echo_text = val; + break; + case E_URL: + echo_text = ap_escape_uri(ctx->dpool, val); + break; + case E_ENTITY: + echo_text = ap_escape_html(ctx->dpool, val); + break; + } + + e_len = strlen(echo_text); + } + else { + echo_text = ctx->intern->undefined_echo; + e_len = ctx->intern->undefined_echo_len; + } + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create( + apr_pmemdup(ctx->pool, echo_text, e_len), + e_len, ctx->pool, f->c->bucket_alloc)); + } + else if (!strcmp(tag, "encoding")) { + if (!strcasecmp(tag_val, "none")) { + encode = E_NONE; + } + else if (!strcasecmp(tag_val, "url")) { + encode = E_URL; + } + else if (!strcasecmp(tag_val, "entity")) { + encode = E_ENTITY; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value " + "\"%s\" to parameter \"encoding\" of tag echo in " + "%s", tag_val, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " + "\"%s\" in tag echo of %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_config(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + apr_table_t *env = r->subprocess_env; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for config element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_RAW); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "errmsg")) { + ctx->error_str = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + } + else if (!strcmp(tag, "echomsg")) { + ctx->intern->undefined_echo = + ap_ssi_parse_string(ctx, tag_val, NULL, 0,SSI_EXPAND_DROP_NAME); + ctx->intern->undefined_echo_len=strlen(ctx->intern->undefined_echo); + } + else if (!strcmp(tag, "timefmt")) { + apr_time_t date = r->request_time; + + ctx->time_str = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + + apr_table_setn(env, "DATE_LOCAL", ap_ht_time(r->pool, date, + ctx->time_str, 0)); + apr_table_setn(env, "DATE_GMT", ap_ht_time(r->pool, date, + ctx->time_str, 1)); + apr_table_setn(env, "LAST_MODIFIED", + ap_ht_time(r->pool, r->finfo.mtime, + ctx->time_str, 0)); + } + else if (!strcmp(tag, "sizefmt")) { + char *parsed_string; + + parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + if (!strcmp(parsed_string, "bytes")) { + ctx->flags |= SSI_FLAG_SIZE_IN_BYTES; + } + else if (!strcmp(parsed_string, "abbrev")) { + ctx->flags &= SSI_FLAG_SIZE_ABBREV; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown value " + "\"%s\" to parameter \"sizefmt\" of tag config " + "in %s", parsed_string, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " + "\"%s\" to tag config in %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_fsize(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for fsize element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + apr_finfo_t finfo; + char *parsed_string; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + + if (!find_file(r, "fsize", tag, parsed_string, &finfo)) { + char *buf; + apr_size_t len; + + if (!(ctx->flags & SSI_FLAG_SIZE_IN_BYTES)) { + buf = apr_strfsize(finfo.size, apr_palloc(ctx->pool, 5)); + len = 4; /* omit the \0 terminator */ + } + else { + apr_size_t l, x, pos; + char *tmp; + + tmp = apr_psprintf(ctx->dpool, "%" APR_OFF_T_FMT, finfo.size); + len = l = strlen(tmp); + + for (x = 0; x < l; ++x) { + if (x && !((l - x) % 3)) { + ++len; + } + } + + if (len == l) { + buf = apr_pstrmemdup(ctx->pool, tmp, len); + } + else { + buf = apr_palloc(ctx->pool, len); + + for (pos = x = 0; x < l; ++x) { + if (x && !((l - x) % 3)) { + buf[pos++] = ','; + } + buf[pos++] = tmp[x]; + } + } + } + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(buf, len, + ctx->pool, f->c->bucket_alloc)); + } + else { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_flastmod(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for flastmod element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + apr_finfo_t finfo; + char *parsed_string; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + + if (!find_file(r, "flastmod", tag, parsed_string, &finfo)) { + char *t_val; + apr_size_t t_len; + + t_val = ap_ht_time(ctx->pool, finfo.mtime, ctx->time_str, 0); + t_len = strlen(t_val); + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(t_val, t_len, + ctx->pool, f->c->bucket_alloc)); + } + else { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_if(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *expr = NULL; + request_rec *r = f->r; + int expr_ret, was_error; + + if (ctx->argc != 1) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, (ctx->argc) + ? "too many arguments for if element in %s" + : "missing expr argument for if element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + ++(ctx->if_nesting_level); + return APR_SUCCESS; + } + + if (ctx->argc != 1) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + ap_ssi_get_tag_and_value(ctx, &tag, &expr, SSI_VALUE_RAW); + + if (strcmp(tag, "expr")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter \"%s\" " + "to tag if in %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (!expr) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "missing expr value for if " + "element in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + DEBUG_PRINTF((ctx, "**** if expr=\"%s\"\n", expr)); + + expr_ret = parse_expr(ctx, expr, &was_error); + + if (was_error) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (expr_ret) { + ctx->flags |= (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); + } + else { + ctx->flags &= SSI_FLAG_CLEAR_PRINT_COND; + } + + DEBUG_DUMP_COND(ctx, " if"); + + ctx->if_nesting_level = 0; + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_elif(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *expr = NULL; + request_rec *r = f->r; + int expr_ret, was_error; + + if (ctx->argc != 1) { + ap_log_rerror(APLOG_MARK, + (!(ctx->if_nesting_level)) ? APLOG_ERR : APLOG_WARNING, + 0, r, (ctx->argc) + ? "too many arguments for if element in %s" + : "missing expr argument for if element in %s", + r->filename); + } + + if (ctx->if_nesting_level) { + return APR_SUCCESS; + } + + if (ctx->argc != 1) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + ap_ssi_get_tag_and_value(ctx, &tag, &expr, SSI_VALUE_RAW); + + if (strcmp(tag, "expr")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter \"%s\" " + "to tag if in %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (!expr) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "missing expr in elif " + "statement: %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + DEBUG_PRINTF((ctx, "**** elif expr=\"%s\"\n", expr)); + DEBUG_DUMP_COND(ctx, " elif"); + + if (ctx->flags & SSI_FLAG_COND_TRUE) { + ctx->flags &= SSI_FLAG_CLEAR_PRINTING; + return APR_SUCCESS; + } + + expr_ret = parse_expr(ctx, expr, &was_error); + + if (was_error) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (expr_ret) { + ctx->flags |= (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); + } + else { + ctx->flags &= SSI_FLAG_CLEAR_PRINT_COND; + } + + DEBUG_DUMP_COND(ctx, " elif"); + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_else(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + + if (ctx->argc) { + ap_log_rerror(APLOG_MARK, + (!(ctx->if_nesting_level)) ? APLOG_ERR : APLOG_WARNING, + 0, r, "else directive does not take tags in %s", + r->filename); + } + + if (ctx->if_nesting_level) { + return APR_SUCCESS; + } + + if (ctx->argc) { + if (ctx->flags & SSI_FLAG_PRINTING) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + } + + return APR_SUCCESS; + } + + DEBUG_DUMP_COND(ctx, " else"); + + if (ctx->flags & SSI_FLAG_COND_TRUE) { + ctx->flags &= SSI_FLAG_CLEAR_PRINTING; + } + else { + ctx->flags |= (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_endif(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + + if (ctx->argc) { + ap_log_rerror(APLOG_MARK, + (!(ctx->if_nesting_level)) ? APLOG_ERR : APLOG_WARNING, + 0, r, "endif directive does not take tags in %s", + r->filename); + } + + if (ctx->if_nesting_level) { + --(ctx->if_nesting_level); + return APR_SUCCESS; + } + + if (ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + DEBUG_DUMP_COND(ctx, "endif"); + + ctx->flags |= (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_set(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *var = NULL; + request_rec *r = f->r; + request_rec *sub = r->main; + apr_pool_t *p = r->pool; + + if (ctx->argc < 2) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for set element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (ctx->argc < 2) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + /* we need to use the 'main' request pool to set notes as that is + * a notes lifetime + */ + while (sub) { + p = sub->pool; + sub = sub->main; + } + + while (1) { + char *tag = NULL; + char *tag_val = NULL; + + ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "var")) { + var = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + } + else if (!strcmp(tag, "value")) { + char *parsed_string; + + if (!var) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "variable must " + "precede value in set directive in %s", + r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + + parsed_string = ap_ssi_parse_string(ctx, tag_val, NULL, 0, + SSI_EXPAND_DROP_NAME); + apr_table_setn(r->subprocess_env, apr_pstrdup(p, var), + apr_pstrdup(p, parsed_string)); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid tag for set " + "directive in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* + * + */ +static apr_status_t handle_printenv(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + request_rec *r = f->r; + const apr_array_header_t *arr; + const apr_table_entry_t *elts; + int i; + + if (ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "printenv directive does not take tags in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + arr = apr_table_elts(r->subprocess_env); + elts = (apr_table_entry_t *)arr->elts; + + for (i = 0; i < arr->nelts; ++i) { + const char *key_text, *val_text; + char *key_val, *next; + apr_size_t k_len, v_len, kv_length; + + /* get key */ + key_text = ap_escape_html(ctx->dpool, elts[i].key); + k_len = strlen(key_text); + + /* get value */ + val_text = elts[i].val; + if (val_text == LAZY_VALUE) { + val_text = add_include_vars_lazy(r, elts[i].key); + } + val_text = ap_escape_html(ctx->dpool, elts[i].val); + v_len = strlen(val_text); + + /* assemble result */ + kv_length = k_len + v_len + sizeof("=\n"); + key_val = apr_palloc(ctx->pool, kv_length); + next = key_val; + + memcpy(next, key_text, k_len); + next += k_len; + *next++ = '='; + memcpy(next, val_text, v_len); + next += v_len; + *next++ = '\n'; + *next = 0; + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(key_val, kv_length-1, + ctx->pool, f->c->bucket_alloc)); + } + + ctx->flush_now = 1; + return APR_SUCCESS; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Main Includes-Filter Engine + * | | + * +-------------------------------------------------------+ + */ + +/* This is an implementation of the BNDM search algorithm. + * + * Fast and Flexible String Matching by Combining Bit-parallelism and + * Suffix Automata (2001) + * Gonzalo Navarro, Mathieu Raffinot + * + * http://www-igm.univ-mlv.fr/~raffinot/ftp/jea2001.ps.gz + * + * Initial code submitted by Sascha Schumann. + */ + +/* Precompile the bndm_t data structure. */ +static bndm_t *bndm_compile(apr_pool_t *pool, const char *n, apr_size_t nl) +{ + unsigned int x; + const char *ne = n + nl; + bndm_t *t = apr_palloc(pool, sizeof(*t)); + + memset(t->T, 0, sizeof(unsigned int) * 256); + t->pattern_len = nl; + + for (x = 1; n < ne; x <<= 1) { + t->T[(unsigned char) *n++] |= x; + } + + t->x = x - 1; + + return t; +} + +/* Implements the BNDM search algorithm (as described above). + * + * h - the string to look in + * hl - length of the string to look for + * t - precompiled bndm structure against the pattern + * + * Returns the count of character that is the first match or hl if no + * match is found. + */ +static apr_size_t bndm(bndm_t *t, const char *h, apr_size_t hl) +{ + const char *skip; + const char *he, *p, *pi; + unsigned int *T, x, d; + apr_size_t nl; + + he = h + hl; + + T = t->T; + x = t->x; + nl = t->pattern_len; + + pi = h - 1; /* pi: p initial */ + p = pi + nl; /* compare window right to left. point to the first char */ + + while (p < he) { + skip = p; + d = x; + do { + d &= T[(unsigned char) *p--]; + if (!d) { + break; + } + if ((d & 1)) { + if (p != pi) { + skip = p; + } + else { + return p - h + 1; + } + } + d >>= 1; + } while (d); + + pi = skip; + p = pi + nl; + } + + return hl; +} + +/* + * returns the index position of the first byte of start_seq (or the len of + * the buffer as non-match) + */ +static apr_size_t find_start_sequence(include_ctx_t *ctx, const char *data, + apr_size_t len) +{ + struct ssi_internal_ctx *intern = ctx->intern; + apr_size_t slen = intern->start_seq_pat->pattern_len; + apr_size_t index; + const char *p, *ep; + + if (len < slen) { + p = data; /* try partial match at the end of the buffer (below) */ + } + else { + /* try fast bndm search over the buffer + * (hopefully the whole start sequence can be found in this buffer) + */ + index = bndm(intern->start_seq_pat, data, len); + + /* wow, found it. ready. */ + if (index < len) { + intern->state = PARSE_DIRECTIVE; + return index; + } + else { + /* ok, the pattern can't be found as whole in the buffer, + * check the end for a partial match + */ + p = data + len - slen + 1; + } + } + + ep = data + len; + do { + while (p < ep && *p != *intern->start_seq) { + ++p; + } + + index = p - data; + + /* found a possible start_seq start */ + if (p < ep) { + apr_size_t pos = 1; + + ++p; + while (p < ep && *p == intern->start_seq[pos]) { + ++p; + ++pos; + } + + /* partial match found. Store the info for the next round */ + if (p == ep) { + intern->state = PARSE_HEAD; + intern->parse_pos = pos; + return index; + } + } + + /* we must try all combinations; consider (e.g.) SSIStartTag "--->" + * and a string data of "--.-" and the end of the buffer + */ + p = data + index + 1; + } while (p < ep); + + /* no match */ + return len; +} + +/* + * returns the first byte *after* the partial (or final) match. + * + * If we had to trick with the start_seq start, 'release' returns the + * number of chars of the start_seq which appeared not to be part of a + * full tag and may have to be passed down the filter chain. + */ +static apr_size_t find_partial_start_sequence(include_ctx_t *ctx, + const char *data, + apr_size_t len, + apr_size_t *release) +{ + struct ssi_internal_ctx *intern = ctx->intern; + apr_size_t pos, spos = 0; + apr_size_t slen = intern->start_seq_pat->pattern_len; + const char *p, *ep; + + pos = intern->parse_pos; + ep = data + len; + *release = 0; + + do { + p = data; + + while (p < ep && pos < slen && *p == intern->start_seq[pos]) { + ++p; + ++pos; + } + + /* full match */ + if (pos == slen) { + intern->state = PARSE_DIRECTIVE; + return (p - data); + } + + /* the whole buffer is a partial match */ + if (p == ep) { + intern->parse_pos = pos; + return (p - data); + } + + /* No match so far, but again: + * We must try all combinations, since the start_seq is a random + * user supplied string + * + * So: look if the first char of start_seq appears somewhere within + * the current partial match. If it does, try to start a match that + * begins with this offset. (This can happen, if a strange + * start_seq like "---->" spans buffers) + */ + if (spos < intern->parse_pos) { + do { + ++spos; + ++*release; + p = intern->start_seq + spos; + pos = intern->parse_pos - spos; + + while (pos && *p != *intern->start_seq) { + ++p; + ++spos; + ++*release; + --pos; + } + + /* if a matching beginning char was found, try to match the + * remainder of the old buffer. + */ + if (pos > 1) { + apr_size_t t = 1; + + ++p; + while (t < pos && *p == intern->start_seq[t]) { + ++p; + ++t; + } + + if (t == pos) { + /* yeah, another partial match found in the *old* + * buffer, now test the *current* buffer for + * continuing match + */ + break; + } + } + } while (pos > 1); + + if (pos) { + continue; + } + } + + break; + } while (1); /* work hard to find a match ;-) */ + + /* no match at all, release all (wrongly) matched chars so far */ + *release = intern->parse_pos; + intern->state = PARSE_PRE_HEAD; + return 0; +} + +/* + * returns the position after the directive + */ +static apr_size_t find_directive(include_ctx_t *ctx, const char *data, + apr_size_t len, char ***store, + apr_size_t **store_len) +{ + struct ssi_internal_ctx *intern = ctx->intern; + const char *p = data; + const char *ep = data + len; + apr_size_t pos; + + switch (intern->state) { + case PARSE_DIRECTIVE: + while (p < ep && !apr_isspace(*p)) { + /* we have to consider the case of missing space between directive + * and end_seq (be somewhat lenient), e.g. + */ + if (*p == *intern->end_seq) { + intern->state = PARSE_DIRECTIVE_TAIL; + intern->parse_pos = 1; + ++p; + return (p - data); + } + ++p; + } + + if (p < ep) { /* found delimiter whitespace */ + intern->state = PARSE_DIRECTIVE_POSTNAME; + *store = &intern->directive; + *store_len = &intern->directive_len; + } + + break; + + case PARSE_DIRECTIVE_TAIL: + pos = intern->parse_pos; + + while (p < ep && pos < intern->end_seq_len && + *p == intern->end_seq[pos]) { + ++p; + ++pos; + } + + /* full match, we're done */ + if (pos == intern->end_seq_len) { + intern->state = PARSE_DIRECTIVE_POSTTAIL; + *store = &intern->directive; + *store_len = &intern->directive_len; + break; + } + + /* partial match, the buffer is too small to match fully */ + if (p == ep) { + intern->parse_pos = pos; + break; + } + + /* no match. continue normal parsing */ + intern->state = PARSE_DIRECTIVE; + return 0; + + case PARSE_DIRECTIVE_POSTTAIL: + intern->state = PARSE_EXECUTE; + intern->directive_len -= intern->end_seq_len; + /* continue immediately with the next state */ + + case PARSE_DIRECTIVE_POSTNAME: + if (PARSE_DIRECTIVE_POSTNAME == intern->state) { + intern->state = PARSE_PRE_ARG; + } + ctx->argc = 0; + intern->argv = NULL; + + if (!intern->directive_len) { + intern->error = 1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, intern->r, "missing " + "directive name in parsed document %s", + intern->r->filename); + } + else { + char *sp = intern->directive; + char *sep = intern->directive + intern->directive_len; + + /* normalize directive name */ + for (; sp < sep; ++sp) { + *sp = apr_tolower(*sp); + } + } + + return 0; + + default: + /* get a rid of a gcc warning about unhandled enumerations */ + break; + } + + return (p - data); +} + +/* + * find out whether the next token is (a possible) end_seq or an argument + */ +static apr_size_t find_arg_or_tail(include_ctx_t *ctx, const char *data, + apr_size_t len) +{ + struct ssi_internal_ctx *intern = ctx->intern; + const char *p = data; + const char *ep = data + len; + + /* skip leading WS */ + while (p < ep && apr_isspace(*p)) { + ++p; + } + + /* buffer doesn't consist of whitespaces only */ + if (p < ep) { + intern->state = (*p == *intern->end_seq) ? PARSE_TAIL : PARSE_ARG; + } + + return (p - data); +} + +/* + * test the stream for end_seq. If it doesn't match at all, it must be an + * argument + */ +static apr_size_t find_tail(include_ctx_t *ctx, const char *data, + apr_size_t len) +{ + struct ssi_internal_ctx *intern = ctx->intern; + const char *p = data; + const char *ep = data + len; + apr_size_t pos = intern->parse_pos; + + if (PARSE_TAIL == intern->state) { + intern->state = PARSE_TAIL_SEQ; + pos = intern->parse_pos = 0; + } + + while (p < ep && pos < intern->end_seq_len && *p == intern->end_seq[pos]) { + ++p; + ++pos; + } + + /* bingo, full match */ + if (pos == intern->end_seq_len) { + intern->state = PARSE_EXECUTE; + return (p - data); + } + + /* partial match, the buffer is too small to match fully */ + if (p == ep) { + intern->parse_pos = pos; + return (p - data); + } + + /* no match. It must be an argument string then + * The caller should cleanup and rewind to the reparse point + */ + intern->state = PARSE_ARG; + return 0; +} + +/* + * extract name=value from the buffer + * A pcre-pattern could look (similar to): + * name\s*(?:=\s*(["'`]?)value\1(?>\s*))? + */ +static apr_size_t find_argument(include_ctx_t *ctx, const char *data, + apr_size_t len, char ***store, + apr_size_t **store_len) +{ + struct ssi_internal_ctx *intern = ctx->intern; + const char *p = data; + const char *ep = data + len; + + switch (intern->state) { + case PARSE_ARG: + /* + * create argument structure and append it to the current list + */ + intern->current_arg = apr_palloc(ctx->dpool, + sizeof(*intern->current_arg)); + intern->current_arg->next = NULL; + + ++(ctx->argc); + if (!intern->argv) { + intern->argv = intern->current_arg; + } + else { + arg_item_t *newarg = intern->argv; + + while (newarg->next) { + newarg = newarg->next; + } + newarg->next = intern->current_arg; + } + + /* check whether it's a valid one. If it begins with a quote, we + * can safely assume, someone forgot the name of the argument + */ + switch (*p) { + case '"': case '\'': case '`': + *store = NULL; + + intern->state = PARSE_ARG_VAL; + intern->quote = *p++; + intern->current_arg->name = NULL; + intern->current_arg->name_len = 0; + intern->error = 1; + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, intern->r, "missing " + "argument name for value to tag %s in %s", + apr_pstrmemdup(intern->r->pool, intern->directive, + intern->directive_len), + intern->r->filename); + + return (p - data); + + default: + intern->state = PARSE_ARG_NAME; + } + /* continue immediately with next state */ + + case PARSE_ARG_NAME: + while (p < ep && !apr_isspace(*p) && *p != '=') { + ++p; + } + + if (p < ep) { + intern->state = PARSE_ARG_POSTNAME; + *store = &intern->current_arg->name; + *store_len = &intern->current_arg->name_len; + return (p - data); + } + break; + + case PARSE_ARG_POSTNAME: + intern->current_arg->name = apr_pstrmemdup(ctx->dpool, + intern->current_arg->name, + intern->current_arg->name_len); + if (!intern->current_arg->name_len) { + intern->error = 1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, intern->r, "missing " + "argument name for value to tag %s in %s", + apr_pstrmemdup(intern->r->pool, intern->directive, + intern->directive_len), + intern->r->filename); + } + else { + char *sp = intern->current_arg->name; + + /* normalize the name */ + while (*sp) { + *sp = apr_tolower(*sp); + ++sp; + } + } + + intern->state = PARSE_ARG_EQ; + /* continue with next state immediately */ + + case PARSE_ARG_EQ: + *store = NULL; + + while (p < ep && apr_isspace(*p)) { + ++p; + } + + if (p < ep) { + if (*p == '=') { + intern->state = PARSE_ARG_PREVAL; + ++p; + } + else { /* no value */ + intern->current_arg->value = NULL; + intern->state = PARSE_PRE_ARG; + } + + return (p - data); + } + break; + + case PARSE_ARG_PREVAL: + *store = NULL; + + while (p < ep && apr_isspace(*p)) { + ++p; + } + + /* buffer doesn't consist of whitespaces only */ + if (p < ep) { + intern->state = PARSE_ARG_VAL; + switch (*p) { + case '"': case '\'': case '`': + intern->quote = *p++; + break; + default: + intern->quote = '\0'; + break; + } + + return (p - data); + } + break; + + case PARSE_ARG_VAL_ESC: + if (*p == intern->quote) { + ++p; + } + intern->state = PARSE_ARG_VAL; + /* continue with next state immediately */ + + case PARSE_ARG_VAL: + for (; p < ep; ++p) { + if (intern->quote && *p == '\\') { + ++p; + if (p == ep) { + intern->state = PARSE_ARG_VAL_ESC; + break; + } + + if (*p != intern->quote) { + --p; + } + } + else if (intern->quote && *p == intern->quote) { + ++p; + *store = &intern->current_arg->value; + *store_len = &intern->current_arg->value_len; + intern->state = PARSE_ARG_POSTVAL; + break; + } + else if (!intern->quote && apr_isspace(*p)) { + ++p; + *store = &intern->current_arg->value; + *store_len = &intern->current_arg->value_len; + intern->state = PARSE_ARG_POSTVAL; + break; + } + } + + return (p - data); + + case PARSE_ARG_POSTVAL: + /* + * The value is still the raw input string. Finally clean it up. + */ + --(intern->current_arg->value_len); + + /* strip quote escaping \ from the string */ + if (intern->quote) { + apr_size_t shift = 0; + char *sp; + + sp = intern->current_arg->value; + ep = intern->current_arg->value + intern->current_arg->value_len; + while (sp < ep && *sp != '\\') { + ++sp; + } + for (; sp < ep; ++sp) { + if (*sp == '\\' && sp[1] == intern->quote) { + ++sp; + ++shift; + } + if (shift) { + *(sp-shift) = *sp; + } + } + + intern->current_arg->value_len -= shift; + } + + intern->current_arg->value[intern->current_arg->value_len] = '\0'; + intern->state = PARSE_PRE_ARG; + + return 0; + + default: + /* get a rid of a gcc warning about unhandled enumerations */ + break; + } + + return len; /* partial match of something */ +} + +/* + * This is the main loop over the current bucket brigade. + */ +static apr_status_t send_parsed_content(ap_filter_t *f, apr_bucket_brigade *bb) +{ + include_ctx_t *ctx = f->ctx; + struct ssi_internal_ctx *intern = ctx->intern; + request_rec *r = f->r; + apr_bucket *b = APR_BRIGADE_FIRST(bb); + apr_bucket_brigade *pass_bb; + apr_status_t rv = APR_SUCCESS; + char *magic; /* magic pointer for sentinel use */ + + /* fast exit */ + if (APR_BRIGADE_EMPTY(bb)) { + return APR_SUCCESS; + } + + /* we may crash, since already cleaned up; hand over the responsibility + * to the next filter;-) + */ + if (intern->seen_eos) { + return ap_pass_brigade(f->next, bb); + } + + /* All stuff passed along has to be put into that brigade */ + pass_bb = apr_brigade_create(ctx->pool, f->c->bucket_alloc); + + /* initialization for this loop */ + intern->bytes_read = 0; + intern->error = 0; + intern->r = r; + ctx->flush_now = 0; + + /* loop over the current bucket brigade */ + while (b != APR_BRIGADE_SENTINEL(bb)) { + const char *data = NULL; + apr_size_t len, index, release; + apr_bucket *newb = NULL; + char **store = &magic; + apr_size_t *store_len; + + /* handle meta buckets before reading any data */ + if (APR_BUCKET_IS_METADATA(b)) { + newb = APR_BUCKET_NEXT(b); + + APR_BUCKET_REMOVE(b); + + if (APR_BUCKET_IS_EOS(b)) { + intern->seen_eos = 1; + + /* Hit end of stream, time for cleanup ... But wait! + * Perhaps we're not ready yet. We may have to loop one or + * two times again to finish our work. In that case, we + * just re-insert the EOS bucket to allow for an extra loop. + * + * PARSE_EXECUTE means, we've hit a directive just before the + * EOS, which is now waiting for execution. + * + * PARSE_DIRECTIVE_POSTTAIL means, we've hit a directive with + * no argument and no space between directive and end_seq + * just before the EOS. (consider as last + * or only string within the stream). This state, however, + * just cleans up and turns itself to PARSE_EXECUTE, which + * will be passed through within the next (and actually + * last) round. + */ + if (PARSE_EXECUTE == intern->state || + PARSE_DIRECTIVE_POSTTAIL == intern->state) { + APR_BUCKET_INSERT_BEFORE(newb, b); + } + else { + break; /* END OF STREAM */ + } + } + else { + APR_BRIGADE_INSERT_TAIL(pass_bb, b); + + if (APR_BUCKET_IS_FLUSH(b)) { + ctx->flush_now = 1; + } + + b = newb; + continue; + } + } + + /* enough is enough ... */ + if (ctx->flush_now || + intern->bytes_read > AP_MIN_BYTES_TO_WRITE) { + + if (!APR_BRIGADE_EMPTY(pass_bb)) { + rv = ap_pass_brigade(f->next, pass_bb); + if (rv != APR_SUCCESS) { + apr_brigade_destroy(pass_bb); + return rv; + } + } + + ctx->flush_now = 0; + intern->bytes_read = 0; + } + + /* read the current bucket data */ + len = 0; + if (!intern->seen_eos) { + if (intern->bytes_read > 0) { + rv = apr_bucket_read(b, &data, &len, APR_NONBLOCK_READ); + if (APR_STATUS_IS_EAGAIN(rv)) { + ctx->flush_now = 1; + continue; + } + } + + if (!len || rv != APR_SUCCESS) { + rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ); + } + + if (rv != APR_SUCCESS) { + apr_brigade_destroy(pass_bb); + return rv; + } + + intern->bytes_read += len; + } + + /* zero length bucket, fetch next one */ + if (!len && !intern->seen_eos) { + b = APR_BUCKET_NEXT(b); + continue; + } + + /* + * it's actually a data containing bucket, start/continue parsing + */ + + switch (intern->state) { + /* no current tag; search for start sequence */ + case PARSE_PRE_HEAD: + index = find_start_sequence(ctx, data, len); + + if (index < len) { + apr_bucket_split(b, index); + } + + newb = APR_BUCKET_NEXT(b); + if (ctx->flags & SSI_FLAG_PRINTING) { + APR_BUCKET_REMOVE(b); + APR_BRIGADE_INSERT_TAIL(pass_bb, b); + } + else { + apr_bucket_delete(b); + } + + if (index < len) { + /* now delete the start_seq stuff from the remaining bucket */ + if (PARSE_DIRECTIVE == intern->state) { /* full match */ + apr_bucket_split(newb, intern->start_seq_pat->pattern_len); + ctx->flush_now = 1; /* pass pre-tag stuff */ + } + + b = APR_BUCKET_NEXT(newb); + apr_bucket_delete(newb); + } + else { + b = newb; + } + + break; + + /* we're currently looking for the end of the start sequence */ + case PARSE_HEAD: + index = find_partial_start_sequence(ctx, data, len, &release); + + /* check if we mismatched earlier and have to release some chars */ + if (release && (ctx->flags & SSI_FLAG_PRINTING)) { + char *to_release = apr_palloc(ctx->pool, release); + + memcpy(to_release, intern->start_seq, release); + newb = apr_bucket_pool_create(to_release, release, ctx->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(pass_bb, newb); + } + + if (index) { /* any match */ + /* now delete the start_seq stuff from the remaining bucket */ + if (PARSE_DIRECTIVE == intern->state) { /* final match */ + apr_bucket_split(b, index); + ctx->flush_now = 1; /* pass pre-tag stuff */ + } + newb = APR_BUCKET_NEXT(b); + apr_bucket_delete(b); + b = newb; + } + + break; + + /* we're currently grabbing the directive name */ + case PARSE_DIRECTIVE: + case PARSE_DIRECTIVE_POSTNAME: + case PARSE_DIRECTIVE_TAIL: + case PARSE_DIRECTIVE_POSTTAIL: + index = find_directive(ctx, data, len, &store, &store_len); + + if (index) { + apr_bucket_split(b, index); + newb = APR_BUCKET_NEXT(b); + } + + if (store) { + if (index) { + APR_BUCKET_REMOVE(b); + APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b); + b = newb; + } + + /* time for cleanup? */ + if (store != &magic) { + apr_brigade_pflatten(intern->tmp_bb, store, store_len, + ctx->dpool); + apr_brigade_cleanup(intern->tmp_bb); + } + } + else if (index) { + apr_bucket_delete(b); + b = newb; + } + + break; + + /* skip WS and find out what comes next (arg or end_seq) */ + case PARSE_PRE_ARG: + index = find_arg_or_tail(ctx, data, len); + + if (index) { /* skipped whitespaces */ + if (index < len) { + apr_bucket_split(b, index); + } + newb = APR_BUCKET_NEXT(b); + apr_bucket_delete(b); + b = newb; + } + + break; + + /* currently parsing name[=val] */ + case PARSE_ARG: + case PARSE_ARG_NAME: + case PARSE_ARG_POSTNAME: + case PARSE_ARG_EQ: + case PARSE_ARG_PREVAL: + case PARSE_ARG_VAL: + case PARSE_ARG_VAL_ESC: + case PARSE_ARG_POSTVAL: + index = find_argument(ctx, data, len, &store, &store_len); + + if (index) { + apr_bucket_split(b, index); + newb = APR_BUCKET_NEXT(b); + } + + if (store) { + if (index) { + APR_BUCKET_REMOVE(b); + APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b); + b = newb; + } + + /* time for cleanup? */ + if (store != &magic) { + apr_brigade_pflatten(intern->tmp_bb, store, store_len, + ctx->dpool); + apr_brigade_cleanup(intern->tmp_bb); + } + } + else if (index) { + apr_bucket_delete(b); + b = newb; + } + + break; + + /* try to match end_seq at current pos. */ + case PARSE_TAIL: + case PARSE_TAIL_SEQ: + index = find_tail(ctx, data, len); + + switch (intern->state) { + case PARSE_EXECUTE: /* full match */ + apr_bucket_split(b, index); + newb = APR_BUCKET_NEXT(b); + apr_bucket_delete(b); + b = newb; + break; + + case PARSE_ARG: /* no match */ + /* PARSE_ARG must reparse at the beginning */ + APR_BRIGADE_PREPEND(bb, intern->tmp_bb); + b = APR_BRIGADE_FIRST(bb); + break; + + default: /* partial match */ + newb = APR_BUCKET_NEXT(b); + APR_BUCKET_REMOVE(b); + APR_BRIGADE_INSERT_TAIL(intern->tmp_bb, b); + b = newb; + break; + } + + break; + + /* now execute the parsed directive, cleanup the space and + * start again with PARSE_PRE_HEAD + */ + case PARSE_EXECUTE: + /* if there was an error, it was already logged; just stop here */ + if (intern->error) { + if (ctx->flags & SSI_FLAG_PRINTING) { + SSI_CREATE_ERROR_BUCKET(ctx, f, pass_bb); + intern->error = 0; + } + } + else { + include_handler_fn_t *handle_func; + + handle_func = + (include_handler_fn_t *)apr_hash_get(include_handlers, intern->directive, + intern->directive_len); + + if (handle_func) { + DEBUG_INIT(ctx, f, pass_bb); + rv = handle_func(ctx, f, pass_bb); + if (rv != APR_SUCCESS) { + apr_brigade_destroy(pass_bb); + return rv; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "unknown directive \"%s\" in parsed doc %s", + apr_pstrmemdup(r->pool, intern->directive, + intern->directive_len), + r->filename); + if (ctx->flags & SSI_FLAG_PRINTING) { + SSI_CREATE_ERROR_BUCKET(ctx, f, pass_bb); + } + } + } + + /* cleanup */ + apr_pool_clear(ctx->dpool); + apr_brigade_cleanup(intern->tmp_bb); + + /* Oooof. Done here, start next round */ + intern->state = PARSE_PRE_HEAD; + break; + + } /* switch(ctx->state) */ + + } /* while(brigade) */ + + /* End of stream. Final cleanup */ + if (intern->seen_eos) { + if (PARSE_HEAD == intern->state) { + if (ctx->flags & SSI_FLAG_PRINTING) { + char *to_release = apr_palloc(ctx->pool, intern->parse_pos); + + memcpy(to_release, intern->start_seq, intern->parse_pos); + APR_BRIGADE_INSERT_TAIL(pass_bb, + apr_bucket_pool_create(to_release, + intern->parse_pos, ctx->pool, + f->c->bucket_alloc)); + } + } + else if (PARSE_PRE_HEAD != intern->state) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "SSI directive was not properly finished at the end " + "of parsed document %s", r->filename); + if (ctx->flags & SSI_FLAG_PRINTING) { + SSI_CREATE_ERROR_BUCKET(ctx, f, pass_bb); + } + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "missing closing endif directive in parsed document" + " %s", r->filename); + } + + /* cleanup our temporary memory */ + apr_brigade_destroy(intern->tmp_bb); + apr_pool_destroy(ctx->dpool); + + /* don't forget to finally insert the EOS bucket */ + APR_BRIGADE_INSERT_TAIL(pass_bb, b); + } + + /* if something's left over, pass it along */ + if (!APR_BRIGADE_EMPTY(pass_bb)) { + rv = ap_pass_brigade(f->next, pass_bb); + } + else { + rv = APR_SUCCESS; + apr_brigade_destroy(pass_bb); + } + return rv; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Runtime Hooks + * | | + * +-------------------------------------------------------+ + */ + +static int includes_setup(ap_filter_t *f) +{ + include_dir_config *conf = ap_get_module_config(f->r->per_dir_config, + &include_module); + + /* When our xbithack value isn't set to full or our platform isn't + * providing group-level protection bits or our group-level bits do not + * have group-execite on, we will set the no_local_copy value to 1 so + * that we will not send 304s. + */ + if ((conf->xbithack != XBITHACK_FULL) + || !(f->r->finfo.valid & APR_FINFO_GPROT) + || !(f->r->finfo.protection & APR_GEXECUTE)) { + f->r->no_local_copy = 1; + } + + /* Don't allow ETag headers to be generated - see RFC2616 - 13.3.4. + * We don't know if we are going to be including a file or executing + * a program - in either case a strong ETag header will likely be invalid. + */ + apr_table_setn(f->r->notes, "no-etag", ""); + + return OK; +} + +static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b) +{ + request_rec *r = f->r; + include_ctx_t *ctx = f->ctx; + request_rec *parent; + include_dir_config *conf = ap_get_module_config(r->per_dir_config, + &include_module); + + include_server_config *sconf= ap_get_module_config(r->server->module_config, + &include_module); + + if (!(ap_allow_options(r) & OPT_INCLUDES)) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "mod_include: Options +Includes (or IncludesNoExec) " + "wasn't set, INCLUDES filter removed"); + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, b); + } + + if (!f->ctx) { + struct ssi_internal_ctx *intern; + + /* create context for this filter */ + f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx)); + ctx->intern = intern = apr_palloc(r->pool, sizeof(*ctx->intern)); + ctx->pool = r->pool; + apr_pool_create(&ctx->dpool, ctx->pool); + + /* runtime data */ + intern->tmp_bb = apr_brigade_create(ctx->pool, f->c->bucket_alloc); + intern->seen_eos = 0; + intern->state = PARSE_PRE_HEAD; + ctx->flags = (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); + if (ap_allow_options(r) & OPT_INCNOEXEC) { + ctx->flags |= SSI_FLAG_NO_EXEC; + } + + ctx->if_nesting_level = 0; + intern->re = NULL; + + ctx->error_str = conf->default_error_msg; + ctx->time_str = conf->default_time_fmt; + intern->start_seq = sconf->default_start_tag; + intern->start_seq_pat = bndm_compile(ctx->pool, intern->start_seq, + strlen(intern->start_seq)); + intern->end_seq = sconf->default_end_tag; + intern->end_seq_len = strlen(intern->end_seq); + intern->undefined_echo = conf->undefined_echo; + intern->undefined_echo_len = strlen(conf->undefined_echo); + } + + if ((parent = ap_get_module_config(r->request_config, &include_module))) { + /* Kludge --- for nested includes, we want to keep the subprocess + * environment of the base document (for compatibility); that means + * torquing our own last_modified date as well so that the + * LAST_MODIFIED variable gets reset to the proper value if the + * nested document resets . + */ + r->subprocess_env = r->main->subprocess_env; + apr_pool_join(r->main->pool, r->pool); + r->finfo.mtime = r->main->finfo.mtime; + } + else { + /* we're not a nested include, so we create an initial + * environment */ + ap_add_common_vars(r); + ap_add_cgi_vars(r); + add_include_vars(r, conf->default_time_fmt); + } + /* Always unset the content-length. There is no way to know if + * the content will be modified at some point by send_parsed_content. + * It is very possible for us to not find any content in the first + * 9k of the file, but still have to modify the content of the file. + * If we are going to pass the file through send_parsed_content, then + * the content-length should just be unset. + */ + apr_table_unset(f->r->headers_out, "Content-Length"); + + /* Always unset the Last-Modified field - see RFC2616 - 13.3.4. + * We don't know if we are going to be including a file or executing + * a program which may change the Last-Modified header or make the + * content completely dynamic. Therefore, we can't support these + * headers. + * Exception: XBitHack full means we *should* set the Last-Modified field. + */ + + /* Assure the platform supports Group protections */ + if ((conf->xbithack == XBITHACK_FULL) + && (r->finfo.valid & APR_FINFO_GPROT) + && (r->finfo.protection & APR_GEXECUTE)) { + ap_update_mtime(r, r->finfo.mtime); + ap_set_last_modified(r); + } + else { + apr_table_unset(f->r->headers_out, "Last-Modified"); + } + + /* add QUERY stuff to env cause it ain't yet */ + if (r->args) { + char *arg_copy = apr_pstrdup(r->pool, r->args); + + apr_table_setn(r->subprocess_env, "QUERY_STRING", r->args); + ap_unescape_url(arg_copy); + apr_table_setn(r->subprocess_env, "QUERY_STRING_UNESCAPED", + ap_escape_shell_cmd(r->pool, arg_copy)); + } + + return send_parsed_content(f, b); +} + +static int include_fixup(request_rec *r) +{ + include_dir_config *conf; + + conf = ap_get_module_config(r->per_dir_config, &include_module); + + if (r->handler && (strcmp(r->handler, "server-parsed") == 0)) + { + if (!r->content_type || !*r->content_type) { + ap_set_content_type(r, "text/html"); + } + r->handler = "default-handler"; + } + else +#if defined(OS2) || defined(WIN32) || defined(NETWARE) + /* These OS's don't support xbithack. This is being worked on. */ + { + return DECLINED; + } +#else + { + if (conf->xbithack == XBITHACK_OFF) { + return DECLINED; + } + + if (!(r->finfo.protection & APR_UEXECUTE)) { + return DECLINED; + } + + if (!r->content_type || strcmp(r->content_type, "text/html")) { + return DECLINED; + } + } +#endif + + /* We always return declined, because the default handler actually + * serves the file. All we have to do is add the filter. + */ + ap_add_output_filter("INCLUDES", NULL, r, r->connection); + return DECLINED; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Configuration Handling + * | | + * +-------------------------------------------------------+ + */ + +static void *create_includes_dir_config(apr_pool_t *p, char *dummy) +{ + include_dir_config *result = apr_palloc(p, sizeof(include_dir_config)); + + result->default_error_msg = DEFAULT_ERROR_MSG; + result->default_time_fmt = DEFAULT_TIME_FORMAT; + result->undefined_echo = DEFAULT_UNDEFINED_ECHO; + result->xbithack = DEFAULT_XBITHACK; + + return result; +} + +static void *create_includes_server_config(apr_pool_t *p, server_rec *server) +{ + include_server_config *result; + + result = apr_palloc(p, sizeof(include_server_config)); + result->default_end_tag = DEFAULT_END_SEQUENCE; + result->default_start_tag = DEFAULT_START_SEQUENCE; + + return result; +} + +static const char *set_xbithack(cmd_parms *cmd, void *mconfig, const char *arg) +{ + include_dir_config *conf = mconfig; + + if (!strcasecmp(arg, "off")) { + conf->xbithack = XBITHACK_OFF; + } + else if (!strcasecmp(arg, "on")) { + conf->xbithack = XBITHACK_ON; + } + else if (!strcasecmp(arg, "full")) { + conf->xbithack = XBITHACK_FULL; + } + else { + return "XBitHack must be set to Off, On, or Full"; + } + + return NULL; +} + +static const char *set_default_start_tag(cmd_parms *cmd, void *mconfig, + const char *tag) +{ + include_server_config *conf; + const char *p = tag; + + /* be consistent. (See below in set_default_end_tag) */ + while (*p) { + if (apr_isspace(*p)) { + return "SSIStartTag may not contain any whitespaces"; + } + ++p; + } + + conf= ap_get_module_config(cmd->server->module_config , &include_module); + conf->default_start_tag = tag; + + return NULL; +} + +static const char *set_default_end_tag(cmd_parms *cmd, void *mconfig, + const char *tag) +{ + include_server_config *conf; + const char *p = tag; + + /* sanity check. The parser may fail otherwise */ + while (*p) { + if (apr_isspace(*p)) { + return "SSIEndTag may not contain any whitespaces"; + } + ++p; + } + + conf= ap_get_module_config(cmd->server->module_config , &include_module); + conf->default_end_tag = tag; + + return NULL; +} + +static const char *set_undefined_echo(cmd_parms *cmd, void *mconfig, + const char *msg) +{ + include_dir_config *conf = mconfig; + conf->undefined_echo = msg; + + return NULL; +} + +static const char *set_default_error_msg(cmd_parms *cmd, void *mconfig, + const char *msg) +{ + include_dir_config *conf = mconfig; + conf->default_error_msg = msg; + + return NULL; +} + +static const char *set_default_time_fmt(cmd_parms *cmd, void *mconfig, + const char *fmt) +{ + include_dir_config *conf = mconfig; + conf->default_time_fmt = fmt; + + return NULL; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Module Initialization and Configuration + * | | + * +-------------------------------------------------------+ + */ + +static int include_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + include_handlers = apr_hash_make(p); + + ssi_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); + + if(ssi_pfn_register) { + ssi_pfn_register("if", handle_if); + ssi_pfn_register("set", handle_set); + ssi_pfn_register("else", handle_else); + ssi_pfn_register("elif", handle_elif); + ssi_pfn_register("echo", handle_echo); + ssi_pfn_register("endif", handle_endif); + ssi_pfn_register("fsize", handle_fsize); + ssi_pfn_register("config", handle_config); + ssi_pfn_register("include", handle_include); + ssi_pfn_register("flastmod", handle_flastmod); + ssi_pfn_register("printenv", handle_printenv); + } + + return OK; +} + +static const command_rec includes_cmds[] = +{ + AP_INIT_TAKE1("XBitHack", set_xbithack, NULL, OR_OPTIONS, + "Off, On, or Full"), + AP_INIT_TAKE1("SSIErrorMsg", set_default_error_msg, NULL, OR_ALL, + "a string"), + AP_INIT_TAKE1("SSITimeFormat", set_default_time_fmt, NULL, OR_ALL, + "a strftime(3) formatted string"), + AP_INIT_TAKE1("SSIStartTag", set_default_start_tag, NULL, RSRC_CONF, + "SSI Start String Tag"), + AP_INIT_TAKE1("SSIEndTag", set_default_end_tag, NULL, RSRC_CONF, + "SSI End String Tag"), + AP_INIT_TAKE1("SSIUndefinedEcho", set_undefined_echo, NULL, OR_ALL, + "String to be displayed if an echoed variable is undefined"), + {NULL} +}; + +static void ap_register_include_handler(char *tag, include_handler_fn_t *func) +{ + apr_hash_set(include_handlers, tag, strlen(tag), (const void *)func); +} + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_ssi_get_tag_and_value); + APR_REGISTER_OPTIONAL_FN(ap_ssi_parse_string); + APR_REGISTER_OPTIONAL_FN(ap_register_include_handler); + ap_hook_post_config(include_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); + ap_hook_fixups(include_fixup, NULL, NULL, APR_HOOK_LAST); + ap_register_output_filter("INCLUDES", includes_filter, includes_setup, + AP_FTYPE_RESOURCE); +} + +module AP_MODULE_DECLARE_DATA include_module = +{ + STANDARD20_MODULE_STUFF, + create_includes_dir_config, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_includes_server_config,/* server config */ + NULL, /* merge server config */ + includes_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/filters/mod_include.dsp b/trunk/modules/filters/mod_include.dsp new file mode 100644 index 0000000000..486a364fd4 --- /dev/null +++ b/trunk/modules/filters/mod_include.dsp @@ -0,0 +1,132 @@ +# Microsoft Developer Studio Project File - Name="mod_include" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_include - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_include.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_include.mak" CFG="mod_include - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_include - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_include - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_include - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_include_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_include - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_include_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_include.so" /base:@..\..\os\win32\BaseAddr.ref,mod_include.so + +!ENDIF + +# Begin Target + +# Name "mod_include - Win32 Release" +# Name "mod_include - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_include.c +# End Source File +# Begin Source File + +SOURCE=.\mod_include.h +# End Source File +# Begin Source File + +SOURCE=.\mod_include.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_include - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_include.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_include.so "include_module for Apache" ../../include/ap_release.h > .\mod_include.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_include - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_include.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_include.so "include_module for Apache" ../../include/ap_release.h > .\mod_include.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/filters/mod_include.exp b/trunk/modules/filters/mod_include.exp new file mode 100644 index 0000000000..112e1c4d0e --- /dev/null +++ b/trunk/modules/filters/mod_include.exp @@ -0,0 +1 @@ +include_module diff --git a/trunk/modules/filters/mod_include.h b/trunk/modules/filters/mod_include.h new file mode 100644 index 0000000000..12e2ca1cb1 --- /dev/null +++ b/trunk/modules/filters/mod_include.h @@ -0,0 +1,106 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MOD_INCLUDE_H +#define _MOD_INCLUDE_H 1 + +#include "apr_pools.h" +#include "apr_optional.h" + +/* + * Constants used for ap_ssi_get_tag_and_value's decode parameter + */ +#define SSI_VALUE_DECODED 1 +#define SSI_VALUE_RAW 0 + +/* + * Constants used for ap_ssi_parse_string's leave_name parameter + */ +#define SSI_EXPAND_LEAVE_NAME 1 +#define SSI_EXPAND_DROP_NAME 0 + +/* + * This macro creates a bucket which contains an error message and appends it + * to the current pass brigade + */ +#define SSI_CREATE_ERROR_BUCKET(ctx, f, bb) APR_BRIGADE_INSERT_TAIL((bb), \ + apr_bucket_pool_create(apr_pstrdup((ctx)->pool, (ctx)->error_str), \ + strlen((ctx)->error_str), (ctx)->pool, \ + (f)->c->bucket_alloc)) + +/* + * These constants are used to set or clear flag bits. + */ +#define SSI_FLAG_PRINTING (1<<0) /* Printing conditional lines. */ +#define SSI_FLAG_COND_TRUE (1<<1) /* Conditional eval'd to true. */ +#define SSI_FLAG_SIZE_IN_BYTES (1<<2) /* Sizes displayed in bytes. */ +#define SSI_FLAG_NO_EXEC (1<<3) /* No Exec in current context. */ + +#define SSI_FLAG_SIZE_ABBREV (~(SSI_FLAG_SIZE_IN_BYTES)) +#define SSI_FLAG_CLEAR_PRINT_COND (~((SSI_FLAG_PRINTING) | \ + (SSI_FLAG_COND_TRUE))) +#define SSI_FLAG_CLEAR_PRINTING (~(SSI_FLAG_PRINTING)) + +/* + * The public SSI context structure + */ +typedef struct { + /* permanent pool, use this for creating bucket data */ + apr_pool_t *pool; + + /* temp pool; will be cleared after the execution of every directive */ + apr_pool_t *dpool; + + /* See the SSI_FLAG_XXXXX definitions. */ + int flags; + + /* nesting of *invisible* ifs */ + int if_nesting_level; + + /* if true, the current buffer will be passed down the filter chain before + * continuing with next input bucket and the variable will be reset to + * false. + */ + int flush_now; + + /* argument counter (of the current directive) */ + unsigned argc; + + /* currently configured error string */ + const char *error_str; + + /* currently configured time format */ + const char *time_str; + + /* pointer to internal (non-public) data, don't touch */ + struct ssi_internal_ctx *intern; +} include_ctx_t; + +typedef apr_status_t (include_handler_fn_t)(include_ctx_t *, ap_filter_t *, + apr_bucket_brigade *); + +APR_DECLARE_OPTIONAL_FN(void, ap_ssi_get_tag_and_value, + (include_ctx_t *ctx, char **tag, char **tag_val, + int dodecode)); + +APR_DECLARE_OPTIONAL_FN(char*, ap_ssi_parse_string, + (include_ctx_t *ctx, const char *in, char *out, + apr_size_t length, int leave_name)); + +APR_DECLARE_OPTIONAL_FN(void, ap_register_include_handler, + (char *tag, include_handler_fn_t *func)); + +#endif /* MOD_INCLUDE */ diff --git a/trunk/modules/generators/.indent.pro b/trunk/modules/generators/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/generators/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/generators/Makefile.in b/trunk/modules/generators/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/generators/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/generators/NWGNUautoindex b/trunk/modules/generators/NWGNUautoindex new file mode 100644 index 0000000000..5446586118 --- /dev/null +++ b/trunk/modules/generators/NWGNUautoindex @@ -0,0 +1,251 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/http \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = autoindex + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Autoindex Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Autoindex Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/autoindex.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_autoindex.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + autoindex_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/generators/NWGNUinfo b/trunk/modules/generators/NWGNUinfo new file mode 100644 index 0000000000..8d1a8972f9 --- /dev/null +++ b/trunk/modules/generators/NWGNUinfo @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = info + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Info Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Info Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/info.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_info.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + info_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/generators/NWGNUmakefile b/trunk/modules/generators/NWGNUmakefile new file mode 100644 index 0000000000..67d67c4096 --- /dev/null +++ b/trunk/modules/generators/NWGNUmakefile @@ -0,0 +1,250 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_asis.nlm \ + $(OBJDIR)/autoindex.nlm \ + $(OBJDIR)/mod_cgi.nlm \ + $(OBJDIR)/info.nlm \ + $(OBJDIR)/status.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/generators/NWGNUmod_asis b/trunk/modules/generators/NWGNUmod_asis new file mode 100644 index 0000000000..f4d22a9922 --- /dev/null +++ b/trunk/modules/generators/NWGNUmod_asis @@ -0,0 +1,251 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/http \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_asis + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) ASIS Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Mod_asis Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_asis.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_asis.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + asis_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/generators/NWGNUmod_cgi b/trunk/modules/generators/NWGNUmod_cgi new file mode 100644 index 0000000000..1796212167 --- /dev/null +++ b/trunk/modules/generators/NWGNUmod_cgi @@ -0,0 +1,252 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/filters \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_cgi + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) CGI Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Mod_cgi Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_cgi.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_cgi.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + cgi_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/generators/NWGNUstatus b/trunk/modules/generators/NWGNUstatus new file mode 100644 index 0000000000..6e9c1d823a --- /dev/null +++ b/trunk/modules/generators/NWGNUstatus @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = status + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Status Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Status Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/status.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_status.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + status_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/generators/config5.m4 b/trunk/modules/generators/config5.m4 new file mode 100644 index 0000000000..d4f6282194 --- /dev/null +++ b/trunk/modules/generators/config5.m4 @@ -0,0 +1,27 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(generators) + +APACHE_MODULE(status, process/thread monitoring, , , yes) +APACHE_MODULE(autoindex, directory listing, , , yes) +APACHE_MODULE(asis, as-is filetypes, , , yes) +APACHE_MODULE(info, server information, , , most) +APACHE_MODULE(suexec, set uid and gid for spawned processes, , , no, [ + other_targets=suexec ] ) + +if ap_mpm_is_threaded; then +# if we are using a threaded MPM, we will get better performance with +# mod_cgid, so make it the default. + APACHE_MODULE(cgid, CGI scripts, , , yes) + APACHE_MODULE(cgi, CGI scripts, , , no) +else +# if we are using a non-threaded MPM, it makes little sense to use +# mod_cgid, and it just opens up holes we don't need. Make mod_cgi the +# default + APACHE_MODULE(cgi, CGI scripts, , , yes) + APACHE_MODULE(cgid, CGI scripts, , , no) +fi + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/generators/mod_asis.c b/trunk/modules/generators/mod_asis.c new file mode 100644 index 0000000000..4887d43bc9 --- /dev/null +++ b/trunk/modules/generators/mod_asis.c @@ -0,0 +1,145 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_log.h" +#include "util_script.h" +#include "http_main.h" +#include "http_request.h" + +#include "mod_core.h" + +#define ASIS_MAGIC_TYPE "httpd/send-as-is" + +static int asis_handler(request_rec *r) +{ + conn_rec *c = r->connection; + apr_file_t *f = NULL; + apr_status_t rv; + const char *location; + + if(strcmp(r->handler,ASIS_MAGIC_TYPE) && strcmp(r->handler,"send-as-is")) + return DECLINED; + + r->allowed |= (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + if (r->finfo.filetype == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "File does not exist: %s", r->filename); + return HTTP_NOT_FOUND; + } + + if ((rv = apr_file_open(&f, r->filename, APR_READ, + APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "file permissions deny server access: %s", r->filename); + return HTTP_FORBIDDEN; + } + + ap_scan_script_header_err(r, f, NULL); + location = apr_table_get(r->headers_out, "Location"); + + if (location && location[0] == '/' && + ((r->status == HTTP_OK) || ap_is_HTTP_REDIRECT(r->status))) { + + apr_file_close(f); + + /* Internal redirect -- fake-up a pseudo-request */ + r->status = HTTP_OK; + + /* This redirect needs to be a GET no matter what the original + * method was. + */ + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + + ap_internal_redirect_handler(location, r); + return OK; + } + + if (!r->header_only) { + apr_bucket_brigade *bb; + apr_bucket *b; + apr_off_t pos = 0; + + rv = apr_file_seek(f, APR_CUR, &pos); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "mod_asis: failed to find end-of-headers position " + "for %s", r->filename); + apr_file_close(f); + return HTTP_INTERNAL_SERVER_ERROR; + } + + bb = apr_brigade_create(r->pool, c->bucket_alloc); +#if APR_HAS_LARGE_FILES + if (r->finfo.size - pos > AP_MAX_SENDFILE) { + /* APR_HAS_LARGE_FILES issue; must split into mutiple buckets, + * no greater than MAX(apr_size_t), and more granular than that + * in case the brigade code/filters attempt to read it directly. + */ + apr_off_t fsize = r->finfo.size - pos; + b = apr_bucket_file_create(f, pos, AP_MAX_SENDFILE, + r->pool, c->bucket_alloc); + while (fsize > AP_MAX_SENDFILE) { + APR_BRIGADE_INSERT_TAIL(bb, b); + apr_bucket_copy(b, &b); + b->start += AP_MAX_SENDFILE; + fsize -= AP_MAX_SENDFILE; + } + b->length = (apr_size_t)fsize; /* Resize just the last bucket */ + } + else +#endif + b = apr_bucket_file_create(f, pos, (apr_size_t) (r->finfo.size - pos), + r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + rv = ap_pass_brigade(r->output_filters, bb); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "mod_asis: ap_pass_brigade failed for file %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + else { + apr_file_close(f); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(asis_handler,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA asis_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/generators/mod_asis.dsp b/trunk/modules/generators/mod_asis.dsp new file mode 100644 index 0000000000..378c0ce7e5 --- /dev/null +++ b/trunk/modules/generators/mod_asis.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_asis" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_asis - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_asis.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_asis.mak" CFG="mod_asis - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_asis - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_asis - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_asis - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_asis_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_asis - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_asis_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_asis.so" /base:@..\..\os\win32\BaseAddr.ref,mod_asis.so + +!ENDIF + +# Begin Target + +# Name "mod_asis - Win32 Release" +# Name "mod_asis - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_asis.c +# End Source File +# Begin Source File + +SOURCE=.\mod_asis.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_asis - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_asis.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_asis.so "asis_module for Apache" ../../include/ap_release.h > .\mod_asis.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_asis - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_asis.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_asis.so "asis_module for Apache" ../../include/ap_release.h > .\mod_asis.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/generators/mod_asis.exp b/trunk/modules/generators/mod_asis.exp new file mode 100644 index 0000000000..4f347d921e --- /dev/null +++ b/trunk/modules/generators/mod_asis.exp @@ -0,0 +1 @@ +asis_module diff --git a/trunk/modules/generators/mod_autoindex.c b/trunk/modules/generators/mod_autoindex.c new file mode 100644 index 0000000000..9a6cdcc335 --- /dev/null +++ b/trunk/modules/generators/mod_autoindex.c @@ -0,0 +1,2265 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_autoindex.c: Handles the on-the-fly html index generation + * + * Rob McCool + * 3/23/93 + * + * Adapted to Apache by rst. + * + * Version sort added by Martin Pool . + */ + +#include "apr_strings.h" +#include "apr_fnmatch.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "util_script.h" + +#include "mod_core.h" + +module AP_MODULE_DECLARE_DATA autoindex_module; + +/**************************************************************** + * + * Handling configuration directives... + */ + +#define NO_OPTIONS (1 << 0) /* Indexing options */ +#define ICONS_ARE_LINKS (1 << 1) +#define SCAN_HTML_TITLES (1 << 2) +#define SUPPRESS_ICON (1 << 3) +#define SUPPRESS_LAST_MOD (1 << 4) +#define SUPPRESS_SIZE (1 << 5) +#define SUPPRESS_DESC (1 << 6) +#define SUPPRESS_PREAMBLE (1 << 7) +#define SUPPRESS_COLSORT (1 << 8) +#define SUPPRESS_RULES (1 << 9) +#define FOLDERS_FIRST (1 << 10) +#define VERSION_SORT (1 << 11) +#define TRACK_MODIFIED (1 << 12) +#define FANCY_INDEXING (1 << 13) +#define TABLE_INDEXING (1 << 14) +#define IGNORE_CLIENT (1 << 15) +#define IGNORE_CASE (1 << 16) +#define EMIT_XHTML (1 << 17) +#define SHOW_FORBIDDEN (1 << 18) + +#define K_NOADJUST 0 +#define K_ADJUST 1 +#define K_UNSET 2 + +/* + * Define keys for sorting. + */ +#define K_NAME 'N' /* Sort by file name (default) */ +#define K_LAST_MOD 'M' /* Last modification date */ +#define K_SIZE 'S' /* Size (absolute, not as displayed) */ +#define K_DESC 'D' /* Description */ +#define K_VALID "NMSD" /* String containing _all_ valid K_ opts */ + +#define D_ASCENDING 'A' +#define D_DESCENDING 'D' +#define D_VALID "AD" /* String containing _all_ valid D_ opts */ + +/* + * These are the dimensions of the default icons supplied with Apache. + */ +#define DEFAULT_ICON_WIDTH 20 +#define DEFAULT_ICON_HEIGHT 22 + +/* + * Other default dimensions. + */ +#define DEFAULT_NAME_WIDTH 23 +#define DEFAULT_DESC_WIDTH 23 + +struct item { + char *type; + char *apply_to; + char *apply_path; + char *data; +}; + +typedef struct ai_desc_t { + char *pattern; + char *description; + int full_path; + int wildcards; +} ai_desc_t; + +typedef struct autoindex_config_struct { + + char *default_icon; + char *style_sheet; + apr_int32_t opts; + apr_int32_t incremented_opts; + apr_int32_t decremented_opts; + int name_width; + int name_adjust; + int desc_width; + int desc_adjust; + int icon_width; + int icon_height; + char default_keyid; + char default_direction; + + apr_array_header_t *icon_list; + apr_array_header_t *alt_list; + apr_array_header_t *desc_list; + apr_array_header_t *ign_list; + apr_array_header_t *hdr_list; + apr_array_header_t *rdme_list; + +} autoindex_config_rec; + +static char c_by_encoding, c_by_type, c_by_path; + +#define BY_ENCODING &c_by_encoding +#define BY_TYPE &c_by_type +#define BY_PATH &c_by_path + +/* + * This routine puts the standard HTML header at the top of the index page. + * We include the DOCTYPE because we may be using features therefrom (i.e., + * HEIGHT and WIDTH attributes on the icons if we're FancyIndexing). + */ +static void emit_preamble(request_rec *r, int xhtml, const char *title) +{ + autoindex_config_rec *d; + + d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, + &autoindex_module); + + ap_rvputs(r, xhtml ? DOCTYPE_XHTML_1_0T : DOCTYPE_HTML_3_2, + "\n \n Index of ", title, + "\n", NULL); + if (d->style_sheet != NULL) { + ap_rvputs(r, " style_sheet, + "\" type=\"text/css\"", xhtml ? " />\n" : ">\n", NULL); + } + ap_rvputs(r, " \n \n", NULL); +} + +static void push_item(apr_array_header_t *arr, char *type, const char *to, + const char *path, const char *data) +{ + struct item *p = (struct item *) apr_array_push(arr); + + if (!to) { + to = ""; + } + if (!path) { + path = ""; + } + + p->type = type; + p->data = data ? apr_pstrdup(arr->pool, data) : NULL; + p->apply_path = apr_pstrcat(arr->pool, path, "*", NULL); + + if ((type == BY_PATH) && (!ap_is_matchexp(to))) { + p->apply_to = apr_pstrcat(arr->pool, "*", to, NULL); + } + else if (to) { + p->apply_to = apr_pstrdup(arr->pool, to); + } + else { + p->apply_to = NULL; + } +} + +static const char *add_alt(cmd_parms *cmd, void *d, const char *alt, + const char *to) +{ + if (cmd->info == BY_PATH) { + if (!strcmp(to, "**DIRECTORY**")) { + to = "^^DIRECTORY^^"; + } + } + if (cmd->info == BY_ENCODING) { + char *tmp = apr_pstrdup(cmd->pool, to); + ap_str_tolower(tmp); + to = tmp; + } + + push_item(((autoindex_config_rec *) d)->alt_list, cmd->info, to, + cmd->path, alt); + return NULL; +} + +static const char *add_icon(cmd_parms *cmd, void *d, const char *icon, + const char *to) +{ + char *iconbak = apr_pstrdup(cmd->pool, icon); + + if (icon[0] == '(') { + char *alt; + char *cl = strchr(iconbak, ')'); + + if (cl == NULL) { + return "missing closing paren"; + } + alt = ap_getword_nc(cmd->pool, &iconbak, ','); + *cl = '\0'; /* Lose closing paren */ + add_alt(cmd, d, &alt[1], to); + } + if (cmd->info == BY_PATH) { + if (!strcmp(to, "**DIRECTORY**")) { + to = "^^DIRECTORY^^"; + } + } + if (cmd->info == BY_ENCODING) { + char *tmp = apr_pstrdup(cmd->pool, to); + ap_str_tolower(tmp); + to = tmp; + } + + push_item(((autoindex_config_rec *) d)->icon_list, cmd->info, to, + cmd->path, iconbak); + return NULL; +} + +/* + * Add description text for a filename pattern. If the pattern has + * wildcards already (or we need to add them), add leading and + * trailing wildcards to it to ensure substring processing. If the + * pattern contains a '/' anywhere, force wildcard matching mode, + * add a slash to the prefix so that "bar/bletch" won't be matched + * by "foobar/bletch", and make a note that there's a delimiter; + * the matching routine simplifies to just the actual filename + * whenever it can. This allows definitions in parent directories + * to be made for files in subordinate ones using relative paths. + */ + +/* + * Absent a strcasestr() function, we have to force wildcards on + * systems for which "AAA" and "aaa" mean the same file. + */ +#ifdef CASE_BLIND_FILESYSTEM +#define WILDCARDS_REQUIRED 1 +#else +#define WILDCARDS_REQUIRED 0 +#endif + +static const char *add_desc(cmd_parms *cmd, void *d, const char *desc, + const char *to) +{ + autoindex_config_rec *dcfg = (autoindex_config_rec *) d; + ai_desc_t *desc_entry; + char *prefix = ""; + + desc_entry = (ai_desc_t *) apr_array_push(dcfg->desc_list); + desc_entry->full_path = (ap_strchr_c(to, '/') == NULL) ? 0 : 1; + desc_entry->wildcards = (WILDCARDS_REQUIRED + || desc_entry->full_path + || apr_fnmatch_test(to)); + if (desc_entry->wildcards) { + prefix = desc_entry->full_path ? "*/" : "*"; + desc_entry->pattern = apr_pstrcat(dcfg->desc_list->pool, + prefix, to, "*", NULL); + } + else { + desc_entry->pattern = apr_pstrdup(dcfg->desc_list->pool, to); + } + desc_entry->description = apr_pstrdup(dcfg->desc_list->pool, desc); + return NULL; +} + +static const char *add_ignore(cmd_parms *cmd, void *d, const char *ext) +{ + push_item(((autoindex_config_rec *) d)->ign_list, 0, ext, cmd->path, NULL); + return NULL; +} + +static const char *add_header(cmd_parms *cmd, void *d, const char *name) +{ + push_item(((autoindex_config_rec *) d)->hdr_list, 0, NULL, cmd->path, + name); + return NULL; +} + +static const char *add_readme(cmd_parms *cmd, void *d, const char *name) +{ + push_item(((autoindex_config_rec *) d)->rdme_list, 0, NULL, cmd->path, + name); + return NULL; +} + +static const char *add_opts(cmd_parms *cmd, void *d, int argc, char *const argv[]) +{ + int i; + char *w; + apr_int32_t opts; + apr_int32_t opts_add; + apr_int32_t opts_remove; + char action; + autoindex_config_rec *d_cfg = (autoindex_config_rec *) d; + + opts = d_cfg->opts; + opts_add = d_cfg->incremented_opts; + opts_remove = d_cfg->decremented_opts; + + for (i = 0; i < argc; i++) { + int option = 0; + w = argv[i]; + + if ((*w == '+') || (*w == '-')) { + action = *(w++); + } + else { + action = '\0'; + } + if (!strcasecmp(w, "FancyIndexing")) { + option = FANCY_INDEXING; + } + else if (!strcasecmp(w, "FoldersFirst")) { + option = FOLDERS_FIRST; + } + else if (!strcasecmp(w, "HTMLTable")) { + option = TABLE_INDEXING; + } + else if (!strcasecmp(w, "IconsAreLinks")) { + option = ICONS_ARE_LINKS; + } + else if (!strcasecmp(w, "IgnoreCase")) { + option = IGNORE_CASE; + } + else if (!strcasecmp(w, "IgnoreClient")) { + option = IGNORE_CLIENT; + } + else if (!strcasecmp(w, "ScanHTMLTitles")) { + option = SCAN_HTML_TITLES; + } + else if (!strcasecmp(w, "SuppressColumnSorting")) { + option = SUPPRESS_COLSORT; + } + else if (!strcasecmp(w, "SuppressDescription")) { + option = SUPPRESS_DESC; + } + else if (!strcasecmp(w, "SuppressHTMLPreamble")) { + option = SUPPRESS_PREAMBLE; + } + else if (!strcasecmp(w, "SuppressIcon")) { + option = SUPPRESS_ICON; + } + else if (!strcasecmp(w, "SuppressLastModified")) { + option = SUPPRESS_LAST_MOD; + } + else if (!strcasecmp(w, "SuppressSize")) { + option = SUPPRESS_SIZE; + } + else if (!strcasecmp(w, "SuppressRules")) { + option = SUPPRESS_RULES; + } + else if (!strcasecmp(w, "TrackModified")) { + option = TRACK_MODIFIED; + } + else if (!strcasecmp(w, "VersionSort")) { + option = VERSION_SORT; + } + else if (!strcasecmp(w, "XHTML")) { + option = EMIT_XHTML; + } + else if (!strcasecmp(w, "ShowForbidden")) { + option = SHOW_FORBIDDEN; + } + else if (!strcasecmp(w, "None")) { + if (action != '\0') { + return "Cannot combine '+' or '-' with 'None' keyword"; + } + opts = NO_OPTIONS; + opts_add = 0; + opts_remove = 0; + } + else if (!strcasecmp(w, "IconWidth")) { + if (action != '-') { + d_cfg->icon_width = DEFAULT_ICON_WIDTH; + } + else { + d_cfg->icon_width = 0; + } + } + else if (!strncasecmp(w, "IconWidth=", 10)) { + if (action == '-') { + return "Cannot combine '-' with IconWidth=n"; + } + d_cfg->icon_width = atoi(&w[10]); + } + else if (!strcasecmp(w, "IconHeight")) { + if (action != '-') { + d_cfg->icon_height = DEFAULT_ICON_HEIGHT; + } + else { + d_cfg->icon_height = 0; + } + } + else if (!strncasecmp(w, "IconHeight=", 11)) { + if (action == '-') { + return "Cannot combine '-' with IconHeight=n"; + } + d_cfg->icon_height = atoi(&w[11]); + } + else if (!strcasecmp(w, "NameWidth")) { + if (action != '-') { + return "NameWidth with no value may only appear as " + "'-NameWidth'"; + } + d_cfg->name_width = DEFAULT_NAME_WIDTH; + d_cfg->name_adjust = K_NOADJUST; + } + else if (!strncasecmp(w, "NameWidth=", 10)) { + if (action == '-') { + return "Cannot combine '-' with NameWidth=n"; + } + if (w[10] == '*') { + d_cfg->name_adjust = K_ADJUST; + } + else { + int width = atoi(&w[10]); + + if (width && (width < 5)) { + return "NameWidth value must be greater than 5"; + } + d_cfg->name_width = width; + d_cfg->name_adjust = K_NOADJUST; + } + } + else if (!strcasecmp(w, "DescriptionWidth")) { + if (action != '-') { + return "DescriptionWidth with no value may only appear as " + "'-DescriptionWidth'"; + } + d_cfg->desc_width = DEFAULT_DESC_WIDTH; + d_cfg->desc_adjust = K_NOADJUST; + } + else if (!strncasecmp(w, "DescriptionWidth=", 17)) { + if (action == '-') { + return "Cannot combine '-' with DescriptionWidth=n"; + } + if (w[17] == '*') { + d_cfg->desc_adjust = K_ADJUST; + } + else { + int width = atoi(&w[17]); + + if (width && (width < 12)) { + return "DescriptionWidth value must be greater than 12"; + } + d_cfg->desc_width = width; + d_cfg->desc_adjust = K_NOADJUST; + } + } + else { + return "Invalid directory indexing option"; + } + if (action == '\0') { + opts |= option; + opts_add = 0; + opts_remove = 0; + } + else if (action == '+') { + opts_add |= option; + opts_remove &= ~option; + } + else { + opts_remove |= option; + opts_add &= ~option; + } + } + if ((opts & NO_OPTIONS) && (opts & ~NO_OPTIONS)) { + return "Cannot combine other IndexOptions keywords with 'None'"; + } + d_cfg->incremented_opts = opts_add; + d_cfg->decremented_opts = opts_remove; + d_cfg->opts = opts; + return NULL; +} + +static const char *set_default_order(cmd_parms *cmd, void *m, + const char *direction, const char *key) +{ + autoindex_config_rec *d_cfg = (autoindex_config_rec *) m; + + if (!strcasecmp(direction, "Ascending")) { + d_cfg->default_direction = D_ASCENDING; + } + else if (!strcasecmp(direction, "Descending")) { + d_cfg->default_direction = D_DESCENDING; + } + else { + return "First keyword must be 'Ascending' or 'Descending'"; + } + + if (!strcasecmp(key, "Name")) { + d_cfg->default_keyid = K_NAME; + } + else if (!strcasecmp(key, "Date")) { + d_cfg->default_keyid = K_LAST_MOD; + } + else if (!strcasecmp(key, "Size")) { + d_cfg->default_keyid = K_SIZE; + } + else if (!strcasecmp(key, "Description")) { + d_cfg->default_keyid = K_DESC; + } + else { + return "Second keyword must be 'Name', 'Date', 'Size', or " + "'Description'"; + } + + return NULL; +} + +#define DIR_CMD_PERMS OR_INDEXES + +static const command_rec autoindex_cmds[] = +{ + AP_INIT_ITERATE2("AddIcon", add_icon, BY_PATH, DIR_CMD_PERMS, + "an icon URL followed by one or more filenames"), + AP_INIT_ITERATE2("AddIconByType", add_icon, BY_TYPE, DIR_CMD_PERMS, + "an icon URL followed by one or more MIME types"), + AP_INIT_ITERATE2("AddIconByEncoding", add_icon, BY_ENCODING, DIR_CMD_PERMS, + "an icon URL followed by one or more content encodings"), + AP_INIT_ITERATE2("AddAlt", add_alt, BY_PATH, DIR_CMD_PERMS, + "alternate descriptive text followed by one or more " + "filenames"), + AP_INIT_ITERATE2("AddAltByType", add_alt, BY_TYPE, DIR_CMD_PERMS, + "alternate descriptive text followed by one or more MIME " + "types"), + AP_INIT_ITERATE2("AddAltByEncoding", add_alt, BY_ENCODING, DIR_CMD_PERMS, + "alternate descriptive text followed by one or more " + "content encodings"), + AP_INIT_TAKE_ARGV("IndexOptions", add_opts, NULL, DIR_CMD_PERMS, + "one or more index options [+|-][]"), + AP_INIT_TAKE2("IndexOrderDefault", set_default_order, NULL, DIR_CMD_PERMS, + "{Ascending,Descending} {Name,Size,Description,Date}"), + AP_INIT_ITERATE("IndexIgnore", add_ignore, NULL, DIR_CMD_PERMS, + "one or more file extensions"), + AP_INIT_ITERATE2("AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS, + "Descriptive text followed by one or more filenames"), + AP_INIT_TAKE1("HeaderName", add_header, NULL, DIR_CMD_PERMS, + "a filename"), + AP_INIT_TAKE1("ReadmeName", add_readme, NULL, DIR_CMD_PERMS, + "a filename"), + AP_INIT_RAW_ARGS("FancyIndexing", ap_set_deprecated, NULL, OR_ALL, + "The FancyIndexing directive is no longer supported. " + "Use IndexOptions FancyIndexing."), + AP_INIT_TAKE1("DefaultIcon", ap_set_string_slot, + (void *)APR_OFFSETOF(autoindex_config_rec, default_icon), + DIR_CMD_PERMS, "an icon URL"), + AP_INIT_TAKE1("IndexStyleSheet", ap_set_string_slot, + (void *)APR_OFFSETOF(autoindex_config_rec, style_sheet), + DIR_CMD_PERMS, "URL to style sheet"), + {NULL} +}; + +static void *create_autoindex_config(apr_pool_t *p, char *dummy) +{ + autoindex_config_rec *new = + (autoindex_config_rec *) apr_pcalloc(p, sizeof(autoindex_config_rec)); + + new->icon_width = 0; + new->icon_height = 0; + new->name_width = DEFAULT_NAME_WIDTH; + new->name_adjust = K_UNSET; + new->desc_width = DEFAULT_DESC_WIDTH; + new->desc_adjust = K_UNSET; + new->icon_list = apr_array_make(p, 4, sizeof(struct item)); + new->alt_list = apr_array_make(p, 4, sizeof(struct item)); + new->desc_list = apr_array_make(p, 4, sizeof(ai_desc_t)); + new->ign_list = apr_array_make(p, 4, sizeof(struct item)); + new->hdr_list = apr_array_make(p, 4, sizeof(struct item)); + new->rdme_list = apr_array_make(p, 4, sizeof(struct item)); + new->opts = 0; + new->incremented_opts = 0; + new->decremented_opts = 0; + new->default_keyid = '\0'; + new->default_direction = '\0'; + + return (void *) new; +} + +static void *merge_autoindex_configs(apr_pool_t *p, void *basev, void *addv) +{ + autoindex_config_rec *new; + autoindex_config_rec *base = (autoindex_config_rec *) basev; + autoindex_config_rec *add = (autoindex_config_rec *) addv; + + new = (autoindex_config_rec *) apr_pcalloc(p, sizeof(autoindex_config_rec)); + new->default_icon = add->default_icon ? add->default_icon + : base->default_icon; + new->style_sheet = add->style_sheet ? add->style_sheet + : base->style_sheet; + new->icon_height = add->icon_height ? add->icon_height : base->icon_height; + new->icon_width = add->icon_width ? add->icon_width : base->icon_width; + + new->alt_list = apr_array_append(p, add->alt_list, base->alt_list); + new->ign_list = apr_array_append(p, add->ign_list, base->ign_list); + new->hdr_list = apr_array_append(p, add->hdr_list, base->hdr_list); + new->desc_list = apr_array_append(p, add->desc_list, base->desc_list); + new->icon_list = apr_array_append(p, add->icon_list, base->icon_list); + new->rdme_list = apr_array_append(p, add->rdme_list, base->rdme_list); + if (add->opts & NO_OPTIONS) { + /* + * If the current directory says 'no options' then we also + * clear any incremental mods from being inheritable further down. + */ + new->opts = NO_OPTIONS; + new->incremented_opts = 0; + new->decremented_opts = 0; + } + else { + /* + * If there were any nonincremental options selected for + * this directory, they dominate and we don't inherit *anything.* + * Contrariwise, we *do* inherit if the only settings here are + * incremental ones. + */ + if (add->opts == 0) { + new->incremented_opts = (base->incremented_opts + | add->incremented_opts) + & ~add->decremented_opts; + new->decremented_opts = (base->decremented_opts + | add->decremented_opts); + /* + * We may have incremental settings, so make sure we don't + * inadvertently inherit an IndexOptions None from above. + */ + new->opts = (base->opts & ~NO_OPTIONS); + } + else { + /* + * There are local nonincremental settings, which clear + * all inheritance from above. They *are* the new base settings. + */ + new->opts = add->opts;; + } + /* + * We're guaranteed that there'll be no overlap between + * the add-options and the remove-options. + */ + new->opts |= new->incremented_opts; + new->opts &= ~new->decremented_opts; + } + /* + * Inherit the NameWidth settings if there aren't any specific to + * the new location; otherwise we'll end up using the defaults set in the + * config-rec creation routine. + */ + if (add->name_adjust == K_UNSET) { + new->name_width = base->name_width; + new->name_adjust = base->name_adjust; + } + else { + new->name_width = add->name_width; + new->name_adjust = add->name_adjust; + } + + /* + * Likewise for DescriptionWidth. + */ + if (add->desc_adjust == K_UNSET) { + new->desc_width = base->desc_width; + new->desc_adjust = base->desc_adjust; + } + else { + new->desc_width = add->desc_width; + new->desc_adjust = add->desc_adjust; + } + + new->default_keyid = add->default_keyid ? add->default_keyid + : base->default_keyid; + new->default_direction = add->default_direction ? add->default_direction + : base->default_direction; + return new; +} + +/**************************************************************** + * + * Looking things up in config entries... + */ + +/* Structure used to hold entries when we're actually building an index */ + +struct ent { + char *name; + char *icon; + char *alt; + char *desc; + apr_off_t size; + apr_time_t lm; + struct ent *next; + int ascending, ignore_case, version_sort; + char key; + int isdir; +}; + +static char *find_item(request_rec *r, apr_array_header_t *list, int path_only) +{ + const char *content_type = ap_field_noparam(r->pool, r->content_type); + const char *content_encoding = r->content_encoding; + char *path = r->filename; + + struct item *items = (struct item *) list->elts; + int i; + + for (i = 0; i < list->nelts; ++i) { + struct item *p = &items[i]; + + /* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */ + if ((path[0] == '^') || (!ap_strcmp_match(path, p->apply_path))) { + if (!*(p->apply_to)) { + return p->data; + } + else if (p->type == BY_PATH || path[0] == '^') { + if (!ap_strcmp_match(path, p->apply_to)) { + return p->data; + } + } + else if (!path_only) { + if (!content_encoding) { + if (p->type == BY_TYPE) { + if (content_type + && !ap_strcasecmp_match(content_type, + p->apply_to)) { + return p->data; + } + } + } + else { + if (p->type == BY_ENCODING) { + if (!ap_strcasecmp_match(content_encoding, + p->apply_to)) { + return p->data; + } + } + } + } + } + } + return NULL; +} + +#define find_icon(d,p,t) find_item(p,d->icon_list,t) +#define find_alt(d,p,t) find_item(p,d->alt_list,t) +#define find_header(d,p) find_item(p,d->hdr_list,0) +#define find_readme(d,p) find_item(p,d->rdme_list,0) + +static char *find_default_item(char *bogus_name, apr_array_header_t *list) +{ + request_rec r; + /* Bleah. I tried to clean up find_item, and it lead to this bit + * of ugliness. Note that the fields initialized are precisely + * those that find_item looks at... + */ + r.filename = bogus_name; + r.content_type = r.content_encoding = NULL; + return find_item(&r, list, 1); +} + +#define find_default_icon(d,n) find_default_item(n, d->icon_list) +#define find_default_alt(d,n) find_default_item(n, d->alt_list) + +/* + * Look through the list of pattern/description pairs and return the first one + * if any) that matches the filename in the request. If multiple patterns + * match, only the first one is used; since the order in the array is the + * same as the order in which directives were processed, earlier matching + * directives will dominate. + */ + +#ifdef CASE_BLIND_FILESYSTEM +#define MATCH_FLAGS APR_FNM_CASE_BLIND +#else +#define MATCH_FLAGS 0 +#endif + +static char *find_desc(autoindex_config_rec *dcfg, const char *filename_full) +{ + int i; + ai_desc_t *list = (ai_desc_t *) dcfg->desc_list->elts; + const char *filename_only; + const char *filename; + + /* + * If the filename includes a path, extract just the name itself + * for the simple matches. + */ + if ((filename_only = ap_strrchr_c(filename_full, '/')) == NULL) { + filename_only = filename_full; + } + else { + filename_only++; + } + for (i = 0; i < dcfg->desc_list->nelts; ++i) { + ai_desc_t *tuple = &list[i]; + int found; + + /* + * Only use the full-path filename if the pattern contains '/'s. + */ + filename = (tuple->full_path) ? filename_full : filename_only; + /* + * Make the comparison using the cheapest method; only do + * wildcard checking if we must. + */ + if (tuple->wildcards) { + found = (apr_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0); + } + else { + found = (ap_strstr_c(filename, tuple->pattern) != NULL); + } + if (found) { + return tuple->description; + } + } + return NULL; +} + +static int ignore_entry(autoindex_config_rec *d, char *path) +{ + apr_array_header_t *list = d->ign_list; + struct item *items = (struct item *) list->elts; + char *tt; + int i; + + if ((tt = strrchr(path, '/')) == NULL) { + tt = path; + } + else { + tt++; + } + + for (i = 0; i < list->nelts; ++i) { + struct item *p = &items[i]; + char *ap; + + if ((ap = strrchr(p->apply_to, '/')) == NULL) { + ap = p->apply_to; + } + else { + ap++; + } + +#ifndef CASE_BLIND_FILESYSTEM + if (!ap_strcmp_match(path, p->apply_path) + && !ap_strcmp_match(tt, ap)) { + return 1; + } +#else /* !CASE_BLIND_FILESYSTEM */ + /* + * On some platforms, the match must be case-blind. This is really + * a factor of the filesystem involved, but we can't detect that + * reliably - so we have to granularise at the OS level. + */ + if (!ap_strcasecmp_match(path, p->apply_path) + && !ap_strcasecmp_match(tt, ap)) { + return 1; + } +#endif /* !CASE_BLIND_FILESYSTEM */ + } + return 0; +} + +/***************************************************************** + * + * Actually generating output + */ + +/* + * Elements of the emitted document: + * Preamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) header file. + * Header file + * Emitted if found (and able). + * H1 tag line + * Emitted if a header file is NOT emitted. + * Directory stuff + * Always emitted. + * HR + * Emitted if FANCY_INDEXING is set. + * Readme file + * Emitted if found (and able). + * ServerSig + * Emitted if ServerSignature is not Off AND a readme file + * is NOT emitted. + * Postamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) readme file. + */ + + +/* + * emit a plain text file + */ +static void do_emit_plain(request_rec *r, apr_file_t *f) +{ + char buf[AP_IOBUFSIZE + 1]; + int ch; + apr_size_t i, c, n; + apr_status_t rv; + + ap_rputs("
    \n", r);
    +    while (!apr_file_eof(f)) {
    +        do {
    +            n = sizeof(char) * AP_IOBUFSIZE;
    +            rv = apr_file_read(f, buf, &n);
    +        } while (APR_STATUS_IS_EINTR(rv));
    +        if (n == 0 || rv != APR_SUCCESS) {
    +            /* ###: better error here? */
    +            break;
    +        }
    +        buf[n] = '\0';
    +        c = 0;
    +        while (c < n) {
    +            for (i = c; i < n; i++) {
    +                if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') {
    +                    break;
    +                }
    +            }
    +            ch = buf[i];
    +            buf[i] = '\0';
    +            ap_rputs(&buf[c], r);
    +            if (ch == '<') {
    +                ap_rputs("<", r);
    +            }
    +            else if (ch == '>') {
    +                ap_rputs(">", r);
    +            }
    +            else if (ch == '&') {
    +                ap_rputs("&", r);
    +            }
    +            c = i + 1;
    +        }
    +    }
    +    ap_rputs("
    \n", r); +} + +/* + * Handle the preamble through the H1 tag line, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as HEADER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_head(request_rec *r, char *header_fname, int suppress_amble, + int emit_xhtml, char *title) +{ + apr_table_t *hdrs = r->headers_in; + apr_file_t *f = NULL; + request_rec *rr = NULL; + int emit_amble = 1; + int emit_H1 = 1; + const char *r_accept; + const char *r_accept_enc; + + /* + * If there's a header file, send a subrequest to look for it. If it's + * found and html do the subrequest, otherwise handle it + */ + r_accept = apr_table_get(hdrs, "Accept"); + r_accept_enc = apr_table_get(hdrs, "Accept-Encoding"); + apr_table_setn(hdrs, "Accept", "text/html, text/plain"); + apr_table_unset(hdrs, "Accept-Encoding"); + + + if ((header_fname != NULL) && r->args) { + header_fname = apr_pstrcat(r->pool, header_fname, "?", r->args, NULL); + } + + if ((header_fname != NULL) + && (rr = ap_sub_req_lookup_uri(header_fname, r, r->output_filters)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && (rr->finfo.filetype == APR_REG)) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + ap_filter_t *f; + /* Hope everything will work... */ + emit_amble = 0; + emit_H1 = 0; + + if (! suppress_amble) { + emit_preamble(r, emit_xhtml, title); + } + /* This is a hack, but I can't find any better way to do this. + * The problem is that we have already created the sub-request, + * but we just inserted the OLD_WRITE filter, and the + * sub-request needs to pass its data through the OLD_WRITE + * filter, or things go horribly wrong (missing data, data in + * the wrong order, etc). To fix it, if you create a + * sub-request and then insert the OLD_WRITE filter before you + * run the request, you need to make sure that the sub-request + * data goes through the OLD_WRITE filter. Just steal this + * code. The long-term solution is to remove the ap_r* + * functions. + */ + for (f=rr->output_filters; + f->frec != ap_subreq_core_filter_handle; f = f->next); + f->next = r->output_filters; + + /* + * If there's a problem running the subrequest, display the + * preamble if we didn't do it before -- the header file + * didn't get displayed. + */ + if (ap_run_sub_req(rr) != OK) { + /* It didn't work */ + emit_amble = suppress_amble; + emit_H1 = 1; + } + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, prefix it with the preamble + * regardless; since we'll be sending a
     block around
    +                 * the file's contents, any HTML header it had won't end up
    +                 * where it belongs.
    +                 */
    +                if (apr_file_open(&f, rr->filename, APR_READ,
    +                                  APR_OS_DEFAULT, r->pool) == APR_SUCCESS) {
    +                    emit_preamble(r, emit_xhtml, title);
    +                    emit_amble = 0;
    +                    do_emit_plain(r, f);
    +                    apr_file_close(f);
    +                    emit_H1 = 0;
    +                }
    +            }
    +        }
    +    }
    +
    +    if (r_accept) {
    +        apr_table_setn(hdrs, "Accept", r_accept);
    +    }
    +    else {
    +        apr_table_unset(hdrs, "Accept");
    +    }
    +
    +    if (r_accept_enc) {
    +        apr_table_setn(hdrs, "Accept-Encoding", r_accept_enc);
    +    }
    +
    +    if (emit_amble) {
    +        emit_preamble(r, emit_xhtml, title);
    +    }
    +    if (emit_H1) {
    +        ap_rvputs(r, "

    Index of ", title, "

    \n", NULL); + } + if (rr != NULL) { + ap_destroy_sub_req(rr); + } +} + + +/* + * Handle the Readme file through the postamble, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as FOOTER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_tail(request_rec *r, char *readme_fname, int suppress_amble) +{ + apr_file_t *f = NULL; + request_rec *rr = NULL; + int suppress_post = 0; + int suppress_sig = 0; + + /* + * If there's a readme file, send a subrequest to look for it. If it's + * found and a text file, handle it -- otherwise fall through and + * pretend there's nothing there. + */ + if ((readme_fname != NULL) + && (rr = ap_sub_req_lookup_uri(readme_fname, r, r->output_filters)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && rr->finfo.filetype == APR_REG) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + ap_filter_t *f; + for (f=rr->output_filters; + f->frec != ap_subreq_core_filter_handle; f = f->next); + f->next = r->output_filters; + + + if (ap_run_sub_req(rr) == OK) { + /* worked... */ + suppress_sig = 1; + suppress_post = suppress_amble; + } + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, suppress the signature. + */ + if (apr_file_open(&f, rr->filename, APR_READ, + APR_OS_DEFAULT, r->pool) == APR_SUCCESS) { + do_emit_plain(r, f); + apr_file_close(f); + suppress_sig = 1; + } + } + } + } + + if (!suppress_sig) { + ap_rputs(ap_psignature("", r), r); + } + if (!suppress_post) { + ap_rputs("\n", r); + } + if (rr != NULL) { + ap_destroy_sub_req(rr); + } +} + + +static char *find_title(request_rec *r) +{ + char titlebuf[MAX_STRING_LEN], *find = ""; + apr_file_t *thefile = NULL; + int x, y, p; + apr_size_t n; + + if (r->status != HTTP_OK) { + return NULL; + } + if ((r->content_type != NULL) + && (!strcasecmp(ap_field_noparam(r->pool, r->content_type), + "text/html") + || !strcmp(r->content_type, INCLUDES_MAGIC_TYPE)) + && !r->content_encoding) { + if (apr_file_open(&thefile, r->filename, APR_READ, + APR_OS_DEFAULT, r->pool) != APR_SUCCESS) { + return NULL; + } + n = sizeof(char) * (MAX_STRING_LEN - 1); + apr_file_read(thefile, titlebuf, &n); + if (n <= 0) { + apr_file_close(thefile); + return NULL; + } + titlebuf[n] = '\0'; + for (x = 0, p = 0; titlebuf[x]; x++) { + if (apr_tolower(titlebuf[x]) == find[p]) { + if (!find[++p]) { + if ((p = ap_ind(&titlebuf[++x], '<')) != -1) { + titlebuf[x + p] = '\0'; + } + /* Scan for line breaks for Tanmoy's secretary */ + for (y = x; titlebuf[y]; y++) { + if ((titlebuf[y] == CR) || (titlebuf[y] == LF)) { + if (y == x) { + x++; + } + else { + titlebuf[y] = ' '; + } + } + } + apr_file_close(thefile); + return apr_pstrdup(r->pool, &titlebuf[x]); + } + } + else { + p = 0; + } + } + apr_file_close(thefile); + } + return NULL; +} + +static struct ent *make_parent_entry(apr_int32_t autoindex_opts, + autoindex_config_rec *d, + request_rec *r, char keyid, + char direction) +{ + struct ent *p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent)); + char *testpath; + /* + * p->name is now the true parent URI. + * testpath is a crafted lie, so that the syntax '/some/..' + * (or simply '..')be used to describe 'up' from '/some/' + * when processeing IndexIgnore, and Icon|Alt|Desc configs. + */ + + /* The output has always been to the parent. Don't make ourself + * our own parent (worthless cyclical reference). + */ + if (!(p->name = ap_make_full_path(r->pool, r->uri, "../"))) { + return (NULL); + } + ap_getparents(p->name); + if (!*p->name) { + return (NULL); + } + + /* IndexIgnore has always compared "/thispath/.." */ + testpath = ap_make_full_path(r->pool, r->filename, ".."); + if (ignore_entry(d, testpath)) { + return (NULL); + } + + p->size = -1; + p->lm = -1; + p->key = apr_toupper(keyid); + p->ascending = (apr_toupper(direction) == D_ASCENDING); + p->version_sort = autoindex_opts & VERSION_SORT; + if (autoindex_opts & FANCY_INDEXING) { + if (!(p->icon = find_default_icon(d, testpath))) { + p->icon = find_default_icon(d, "^^DIRECTORY^^"); + } + if (!(p->alt = find_default_alt(d, testpath))) { + if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) { + p->alt = "DIR"; + } + } + p->desc = find_desc(d, testpath); + } + return p; +} + +static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, + int autoindex_opts, + autoindex_config_rec *d, + request_rec *r, char keyid, + char direction, + const char *pattern) +{ + request_rec *rr; + struct ent *p; + int show_forbidden = 0; + + /* Dot is ignored, Parent is handled by make_parent_entry() */ + if ((dirent->name[0] == '.') && (!dirent->name[1] + || ((dirent->name[1] == '.') && !dirent->name[2]))) + return (NULL); + + /* + * On some platforms, the match must be case-blind. This is really + * a factor of the filesystem involved, but we can't detect that + * reliably - so we have to granularise at the OS level. + */ + if (pattern && (apr_fnmatch(pattern, dirent->name, + APR_FNM_NOESCAPE | APR_FNM_PERIOD +#ifdef CASE_BLIND_FILESYSTEM + | APR_FNM_CASE_BLIND +#endif + ) + != APR_SUCCESS)) { + return (NULL); + } + + if (ignore_entry(d, ap_make_full_path(r->pool, + r->filename, dirent->name))) { + return (NULL); + } + + if (!(rr = ap_sub_req_lookup_dirent(dirent, r, AP_SUBREQ_NO_ARGS, NULL))) { + return (NULL); + } + + if((autoindex_opts & SHOW_FORBIDDEN) + && (rr->status == HTTP_UNAUTHORIZED || rr->status == HTTP_FORBIDDEN)) { + show_forbidden = 1; + } + + if ((rr->finfo.filetype != APR_DIR && rr->finfo.filetype != APR_REG) + || !(rr->status == OK || ap_is_HTTP_SUCCESS(rr->status) + || ap_is_HTTP_REDIRECT(rr->status) + || show_forbidden == 1)) { + ap_destroy_sub_req(rr); + return (NULL); + } + + p = (struct ent *) apr_pcalloc(r->pool, sizeof(struct ent)); + if (dirent->filetype == APR_DIR) { + p->name = apr_pstrcat(r->pool, dirent->name, "/", NULL); + } + else { + p->name = apr_pstrdup(r->pool, dirent->name); + } + p->size = -1; + p->icon = NULL; + p->alt = NULL; + p->desc = NULL; + p->lm = -1; + p->isdir = 0; + p->key = apr_toupper(keyid); + p->ascending = (apr_toupper(direction) == D_ASCENDING); + p->version_sort = !!(autoindex_opts & VERSION_SORT); + p->ignore_case = !!(autoindex_opts & IGNORE_CASE); + + if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) { + p->lm = rr->finfo.mtime; + if (dirent->filetype == APR_DIR) { + if (autoindex_opts & FOLDERS_FIRST) { + p->isdir = 1; + } + rr->filename = ap_make_dirstr_parent (rr->pool, rr->filename); + + /* omit the trailing slash (1.3 compat) */ + rr->filename[strlen(rr->filename) - 1] = '\0'; + + if (!(p->icon = find_icon(d, rr, 1))) { + p->icon = find_default_icon(d, "^^DIRECTORY^^"); + } + if (!(p->alt = find_alt(d, rr, 1))) { + if (!(p->alt = find_default_alt(d, "^^DIRECTORY^^"))) { + p->alt = "DIR"; + } + } + } + else { + p->icon = find_icon(d, rr, 0); + p->alt = find_alt(d, rr, 0); + p->size = rr->finfo.size; + } + + p->desc = find_desc(d, rr->filename); + + if ((!p->desc) && (autoindex_opts & SCAN_HTML_TITLES)) { + p->desc = apr_pstrdup(r->pool, find_title(rr)); + } + } + ap_destroy_sub_req(rr); + /* + * We don't need to take any special action for the file size key. + * If we did, it would go here. + */ + if (keyid == K_LAST_MOD) { + if (p->lm < 0) { + p->lm = 0; + } + } + return (p); +} + +static char *terminate_description(autoindex_config_rec *d, char *desc, + apr_int32_t autoindex_opts, int desc_width) +{ + int maxsize = desc_width; + register int x; + + /* + * If there's no DescriptionWidth in effect, default to the old + * behaviour of adjusting the description size depending upon + * what else is being displayed. Otherwise, stick with the + * setting. + */ + if (d->desc_adjust == K_UNSET) { + if (autoindex_opts & SUPPRESS_ICON) { + maxsize += 6; + } + if (autoindex_opts & SUPPRESS_LAST_MOD) { + maxsize += 19; + } + if (autoindex_opts & SUPPRESS_SIZE) { + maxsize += 7; + } + } + for (x = 0; desc[x] && ((maxsize > 0) || (desc[x] == '<')); x++) { + if (desc[x] == '<') { + while (desc[x] != '>') { + if (!desc[x]) { + maxsize = 0; + break; + } + ++x; + } + } + else if (desc[x] == '&') { + /* entities like ä count as one character */ + --maxsize; + for ( ; desc[x] != ';'; ++x) { + if (desc[x] == '\0') { + maxsize = 0; + break; + } + } + } + else { + --maxsize; + } + } + if (!maxsize && desc[x] != '\0') { + desc[x - 1] = '>'; /* Grump. */ + desc[x] = '\0'; /* Double Grump! */ + } + return desc; +} + +/* + * Emit the anchor for the specified field. If a field is the key for the + * current request, the link changes its meaning to reverse the order when + * selected again. Non-active fields always start in ascending order. + */ +static void emit_link(request_rec *r, const char *anchor, char column, + char curkey, char curdirection, + const char *colargs, int nosort) +{ + if (!nosort) { + char qvalue[9]; + + qvalue[0] = '?'; + qvalue[1] = 'C'; + qvalue[2] = '='; + qvalue[3] = column; + qvalue[4] = ';'; + qvalue[5] = 'O'; + qvalue[6] = '='; + /* reverse? */ + qvalue[7] = ((curkey == column) && (curdirection == D_ASCENDING)) + ? D_DESCENDING : D_ASCENDING; + qvalue[8] = '\0'; + ap_rvputs(r, "<a href=\"", qvalue, colargs ? colargs : "", + "\">", anchor, "</a>", NULL); + } + else { + ap_rputs(anchor, r); + } +} + +static void output_directories(struct ent **ar, int n, + autoindex_config_rec *d, request_rec *r, + apr_int32_t autoindex_opts, char keyid, + char direction, const char *colargs) +{ + int x; + apr_size_t rv; + char *name = r->uri; + char *tp; + int static_columns = !!(autoindex_opts & SUPPRESS_COLSORT); + apr_pool_t *scratch; + int name_width; + int desc_width; + char *name_scratch; + char *pad_scratch; + char *breakrow = ""; + + apr_pool_create(&scratch, r->pool); + if (name[0] == '\0') { + name = "/"; + } + + name_width = d->name_width; + desc_width = d->desc_width; + + if ((autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) + == FANCY_INDEXING) { + if (d->name_adjust == K_ADJUST) { + for (x = 0; x < n; x++) { + int t = strlen(ar[x]->name); + if (t > name_width) { + name_width = t; + } + } + } + + if (d->desc_adjust == K_ADJUST) { + for (x = 0; x < n; x++) { + if (ar[x]->desc != NULL) { + int t = strlen(ar[x]->desc); + if (t > desc_width) { + desc_width = t; + } + } + } + } + } + name_scratch = apr_palloc(r->pool, name_width + 1); + pad_scratch = apr_palloc(r->pool, name_width + 1); + memset(pad_scratch, ' ', name_width); + pad_scratch[name_width] = '\0'; + + if (autoindex_opts & TABLE_INDEXING) { + int cols = 1; + ap_rputs("<table><tr>", r); + if (!(autoindex_opts & SUPPRESS_ICON)) { + ap_rputs("<th>", r); + if ((tp = find_default_icon(d, "^^BLANKICON^^"))) { + ap_rvputs(r, "<img src=\"", ap_escape_html(scratch, tp), + "\" alt=\"[ICO]\"", NULL); + if (d->icon_width) { + ap_rprintf(r, " width=\"%d\"", d->icon_width); + } + if (d->icon_height) { + ap_rprintf(r, " height=\"%d\"", d->icon_height); + } + + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs("></th>", r); + } + else { + ap_rputs(" </th>", r); + } + + ++cols; + } + ap_rputs("<th>", r); + emit_link(r, "Name", K_NAME, keyid, direction, + colargs, static_columns); + if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { + ap_rputs("</th><th>", r); + emit_link(r, "Last modified", K_LAST_MOD, keyid, direction, + colargs, static_columns); + ++cols; + } + if (!(autoindex_opts & SUPPRESS_SIZE)) { + ap_rputs("</th><th>", r); + emit_link(r, "Size", K_SIZE, keyid, direction, + colargs, static_columns); + ++cols; + } + if (!(autoindex_opts & SUPPRESS_DESC)) { + ap_rputs("</th><th>", r); + emit_link(r, "Description", K_DESC, keyid, direction, + colargs, static_columns); + ++cols; + } + if (!(autoindex_opts & SUPPRESS_RULES)) { + breakrow = apr_psprintf(r->pool, + "<tr><th colspan=\"%d\">" + "<hr%s></th></tr>\n", cols, + (autoindex_opts & EMIT_XHTML) ? " /" : ""); + } + ap_rvputs(r, "</th></tr>", breakrow, NULL); + } + else if (autoindex_opts & FANCY_INDEXING) { + ap_rputs("<pre>", r); + if (!(autoindex_opts & SUPPRESS_ICON)) { + if ((tp = find_default_icon(d, "^^BLANKICON^^"))) { + ap_rvputs(r, "<img src=\"", ap_escape_html(scratch, tp), + "\" alt=\"Icon \"", NULL); + if (d->icon_width) { + ap_rprintf(r, " width=\"%d\"", d->icon_width); + } + if (d->icon_height) { + ap_rprintf(r, " height=\"%d\"", d->icon_height); + } + + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs("> ", r); + } + else { + ap_rputs(" ", r); + } + } + emit_link(r, "Name", K_NAME, keyid, direction, + colargs, static_columns); + ap_rputs(pad_scratch + 4, r); + /* + * Emit the guaranteed-at-least-one-space-between-columns byte. + */ + ap_rputs(" ", r); + if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { + emit_link(r, "Last modified", K_LAST_MOD, keyid, direction, + colargs, static_columns); + ap_rputs(" ", r); + } + if (!(autoindex_opts & SUPPRESS_SIZE)) { + emit_link(r, "Size", K_SIZE, keyid, direction, + colargs, static_columns); + ap_rputs(" ", r); + } + if (!(autoindex_opts & SUPPRESS_DESC)) { + emit_link(r, "Description", K_DESC, keyid, direction, + colargs, static_columns); + } + if (!(autoindex_opts & SUPPRESS_RULES)) { + ap_rputs("<hr", r); + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs(">", r); + } + else { + ap_rputc('\n', r); + } + } + else { + ap_rputs("<ul>", r); + } + + for (x = 0; x < n; x++) { + char *anchor, *t, *t2; + int nwidth; + + apr_pool_clear(scratch); + + t = ar[x]->name; + anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0)); + + if (!x && t[0] == '/') { + t2 = "Parent Directory"; + } + else { + t2 = t; + } + + if (autoindex_opts & TABLE_INDEXING) { + ap_rputs("<tr>", r); + if (!(autoindex_opts & SUPPRESS_ICON)) { + ap_rputs("<td valign=\"top\">", r); + if (autoindex_opts & ICONS_ARE_LINKS) { + ap_rvputs(r, "<a href=\"", anchor, "\">", NULL); + } + if ((ar[x]->icon) || d->default_icon) { + ap_rvputs(r, "<img src=\"", + ap_escape_html(scratch, + ar[x]->icon ? ar[x]->icon + : d->default_icon), + "\" alt=\"[", (ar[x]->alt ? ar[x]->alt : " "), + "]\"", NULL); + if (d->icon_width) { + ap_rprintf(r, " width=\"%d\"", d->icon_width); + } + if (d->icon_height) { + ap_rprintf(r, " height=\"%d\"", d->icon_height); + } + + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs(">", r); + } + else { + ap_rputs(" ", r); + } + if (autoindex_opts & ICONS_ARE_LINKS) { + ap_rputs("</a></td>", r); + } + else { + ap_rputs("</td>", r); + } + } + if (d->name_adjust == K_ADJUST) { + ap_rvputs(r, "<td><a href=\"", anchor, "\">", + ap_escape_html(scratch, t2), "</a>", NULL); + } + else { + nwidth = strlen(t2); + if (nwidth > name_width) { + memcpy(name_scratch, t2, name_width - 3); + name_scratch[name_width - 3] = '.'; + name_scratch[name_width - 2] = '.'; + name_scratch[name_width - 1] = '>'; + name_scratch[name_width] = 0; + t2 = name_scratch; + nwidth = name_width; + } + ap_rvputs(r, "<td><a href=\"", anchor, "\">", + ap_escape_html(scratch, t2), + "</a>", pad_scratch + nwidth, NULL); + } + if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { + if (ar[x]->lm != -1) { + char time_str[MAX_STRING_LEN]; + apr_time_exp_t ts; + apr_time_exp_lt(&ts, ar[x]->lm); + apr_strftime(time_str, &rv, MAX_STRING_LEN, + "</td><td align=\"right\">%d-%b-%Y %H:%M ", + &ts); + ap_rputs(time_str, r); + } + else { + ap_rputs("</td><td> ", r); + } + } + if (!(autoindex_opts & SUPPRESS_SIZE)) { + char buf[5]; + ap_rvputs(r, "</td><td align=\"right\">", + apr_strfsize(ar[x]->size, buf), NULL); + } + if (!(autoindex_opts & SUPPRESS_DESC)) { + if (ar[x]->desc) { + if (d->desc_adjust == K_ADJUST) { + ap_rvputs(r, "</td><td>", ar[x]->desc, NULL); + } + else { + ap_rvputs(r, "</td><td>", + terminate_description(d, ar[x]->desc, + autoindex_opts, + desc_width), NULL); + } + } + } + else { + ap_rputs("</td><td> ", r); + } + ap_rputs("</td></tr>\n", r); + } + else if (autoindex_opts & FANCY_INDEXING) { + if (!(autoindex_opts & SUPPRESS_ICON)) { + if (autoindex_opts & ICONS_ARE_LINKS) { + ap_rvputs(r, "<a href=\"", anchor, "\">", NULL); + } + if ((ar[x]->icon) || d->default_icon) { + ap_rvputs(r, "<img src=\"", + ap_escape_html(scratch, + ar[x]->icon ? ar[x]->icon + : d->default_icon), + "\" alt=\"[", (ar[x]->alt ? ar[x]->alt : " "), + "]\"", NULL); + if (d->icon_width) { + ap_rprintf(r, " width=\"%d\"", d->icon_width); + } + if (d->icon_height) { + ap_rprintf(r, " height=\"%d\"", d->icon_height); + } + + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs(">", r); + } + else { + ap_rputs(" ", r); + } + if (autoindex_opts & ICONS_ARE_LINKS) { + ap_rputs("</a> ", r); + } + else { + ap_rputc(' ', r); + } + } + nwidth = strlen(t2); + if (nwidth > name_width) { + memcpy(name_scratch, t2, name_width - 3); + name_scratch[name_width - 3] = '.'; + name_scratch[name_width - 2] = '.'; + name_scratch[name_width - 1] = '>'; + name_scratch[name_width] = 0; + t2 = name_scratch; + nwidth = name_width; + } + ap_rvputs(r, "<a href=\"", anchor, "\">", + ap_escape_html(scratch, t2), + "</a>", pad_scratch + nwidth, NULL); + /* + * The blank before the storm.. er, before the next field. + */ + ap_rputs(" ", r); + if (!(autoindex_opts & SUPPRESS_LAST_MOD)) { + if (ar[x]->lm != -1) { + char time_str[MAX_STRING_LEN]; + apr_time_exp_t ts; + apr_time_exp_lt(&ts, ar[x]->lm); + apr_strftime(time_str, &rv, MAX_STRING_LEN, + "%d-%b-%Y %H:%M ", &ts); + ap_rputs(time_str, r); + } + else { + /*Length="22-Feb-1998 23:42 " (see 4 lines above) */ + ap_rputs(" ", r); + } + } + if (!(autoindex_opts & SUPPRESS_SIZE)) { + char buf[5]; + ap_rputs(apr_strfsize(ar[x]->size, buf), r); + ap_rputs(" ", r); + } + if (!(autoindex_opts & SUPPRESS_DESC)) { + if (ar[x]->desc) { + ap_rputs(terminate_description(d, ar[x]->desc, + autoindex_opts, + desc_width), r); + } + } + ap_rputc('\n', r); + } + else { + ap_rvputs(r, "<li><a href=\"", anchor, "\"> ", t2, + "</a></li>\n", NULL); + } + } + if (autoindex_opts & TABLE_INDEXING) { + ap_rvputs(r, breakrow, "</table>\n", NULL); + } + else if (autoindex_opts & FANCY_INDEXING) { + if (!(autoindex_opts & SUPPRESS_RULES)) { + ap_rputs("<hr", r); + if (autoindex_opts & EMIT_XHTML) { + ap_rputs(" /", r); + } + ap_rputs("></pre>\n", r); + } + else { + ap_rputs("</pre>\n", r); + } + } + else { + ap_rputs("</ul>\n", r); + } +} + +/* + * Compare two file entries according to the sort criteria. The return + * is essentially a signum function value. + */ + +static int dsortf(struct ent **e1, struct ent **e2) +{ + struct ent *c1; + struct ent *c2; + int result = 0; + + /* + * First, see if either of the entries is for the parent directory. + * If so, that *always* sorts lower than anything else. + */ + if ((*e1)->name[0] == '/') { + return -1; + } + if ((*e2)->name[0] == '/') { + return 1; + } + /* + * Now see if one's a directory and one isn't, if we're set + * isdir for FOLDERS_FIRST. + */ + if ((*e1)->isdir != (*e2)->isdir) { + return (*e1)->isdir ? -1 : 1; + } + /* + * All of our comparisons will be of the c1 entry against the c2 one, + * so assign them appropriately to take care of the ordering. + */ + if ((*e1)->ascending) { + c1 = *e1; + c2 = *e2; + } + else { + c1 = *e2; + c2 = *e1; + } + + switch (c1->key) { + case K_LAST_MOD: + if (c1->lm > c2->lm) { + return 1; + } + else if (c1->lm < c2->lm) { + return -1; + } + break; + case K_SIZE: + if (c1->size > c2->size) { + return 1; + } + else if (c1->size < c2->size) { + return -1; + } + break; + case K_DESC: + if (c1->version_sort) { + result = apr_strnatcmp(c1->desc ? c1->desc : "", + c2->desc ? c2->desc : ""); + } + else { + result = strcmp(c1->desc ? c1->desc : "", + c2->desc ? c2->desc : ""); + } + if (result) { + return result; + } + break; + } + + /* names may identical when treated case-insensitively, + * so always fall back on strcmp() flavors to put entries + * in deterministic order. This means that 'ABC' and 'abc' + * will always appear in the same order, rather than + * variably between 'ABC abc' and 'abc ABC' order. + */ + + if (c1->version_sort) { + if (c1->ignore_case) { + result = apr_strnatcasecmp (c1->name, c2->name); + } + if (!result) { + result = apr_strnatcmp(c1->name, c2->name); + } + } + + /* The names may be identical in respects other other than + * filename case when strnatcmp is used above, so fall back + * to strcmp on conflicts so that fn1.01.zzz and fn1.1.zzz + * are also sorted in a deterministic order. + */ + + if (!result && c1->ignore_case) { + result = strcasecmp (c1->name, c2->name); + } + + if (!result) { + result = strcmp (c1->name, c2->name); + } + + return result; +} + + +static int index_directory(request_rec *r, + autoindex_config_rec *autoindex_conf) +{ + char *title_name = ap_escape_html(r->pool, r->uri); + char *title_endp; + char *name = r->filename; + char *pstring = NULL; + apr_finfo_t dirent; + apr_dir_t *thedir; + apr_status_t status; + int num_ent = 0, x; + struct ent *head, *p; + struct ent **ar = NULL; + const char *qstring; + apr_int32_t autoindex_opts = autoindex_conf->opts; + char keyid; + char direction; + char *colargs; + char *fullpath; + apr_size_t dirpathlen; + + if ((status = apr_dir_open(&thedir, name, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "Can't open directory for index: %s", r->filename); + return HTTP_FORBIDDEN; + } + +#if APR_HAS_UNICODE_FS + ap_set_content_type(r, "text/html;charset=utf-8"); +#else + ap_set_content_type(r, "text/html"); +#endif + if (autoindex_opts & TRACK_MODIFIED) { + ap_update_mtime(r, r->finfo.mtime); + ap_set_last_modified(r); + ap_set_etag(r); + } + if (r->header_only) { + apr_dir_close(thedir); + return 0; + } + + /* + * If there is no specific ordering defined for this directory, + * default to ascending by filename. + */ + keyid = autoindex_conf->default_keyid + ? autoindex_conf->default_keyid : K_NAME; + direction = autoindex_conf->default_direction + ? autoindex_conf->default_direction : D_ASCENDING; + + /* + * Figure out what sort of indexing (if any) we're supposed to use. + * + * If no QUERY_STRING was specified or client query strings have been + * explicitly disabled. + * If we are ignoring the client, suppress column sorting as well. + */ + if (autoindex_opts & IGNORE_CLIENT) { + qstring = NULL; + autoindex_opts |= SUPPRESS_COLSORT; + colargs = ""; + } + else { + char fval[5], vval[5], *ppre = "", *epattern = ""; + fval[0] = '\0'; vval[0] = '\0'; + qstring = r->args; + + while (qstring && *qstring) { + + /* C= First Sort key Column (N, M, S, D) */ + if ( qstring[0] == 'C' && qstring[1] == '=' + && qstring[2] && strchr(K_VALID, qstring[2]) + && ( qstring[3] == '&' || qstring[3] == ';' + || !qstring[3])) { + keyid = qstring[2]; + qstring += qstring[3] ? 4 : 3; + } + + /* O= Sort order (A, D) */ + else if ( qstring[0] == 'O' && qstring[1] == '=' + && ( (qstring[2] == D_ASCENDING) + || (qstring[2] == D_DESCENDING)) + && ( qstring[3] == '&' || qstring[3] == ';' + || !qstring[3])) { + direction = qstring[2]; + qstring += qstring[3] ? 4 : 3; + } + + /* F= Output Format (0 plain, 1 fancy (pre), 2 table) */ + else if ( qstring[0] == 'F' && qstring[1] == '=' + && qstring[2] && strchr("012", qstring[2]) + && ( qstring[3] == '&' || qstring[3] == ';' + || !qstring[3])) { + if (qstring[2] == '0') { + autoindex_opts &= ~(FANCY_INDEXING | TABLE_INDEXING); + } + else if (qstring[2] == '1') { + autoindex_opts = (autoindex_opts | FANCY_INDEXING) + & ~TABLE_INDEXING; + } + else if (qstring[2] == '2') { + autoindex_opts |= FANCY_INDEXING | TABLE_INDEXING; + } + strcpy(fval, ";F= "); + fval[3] = qstring[2]; + qstring += qstring[3] ? 4 : 3; + } + + /* V= Version sort (0, 1) */ + else if ( qstring[0] == 'V' && qstring[1] == '=' + && (qstring[2] == '0' || qstring[2] == '1') + && ( qstring[3] == '&' || qstring[3] == ';' + || !qstring[3])) { + if (qstring[2] == '0') { + autoindex_opts &= ~VERSION_SORT; + } + else if (qstring[2] == '1') { + autoindex_opts |= VERSION_SORT; + } + strcpy(vval, ";V= "); + vval[3] = qstring[2]; + qstring += qstring[3] ? 4 : 3; + } + + /* P= wildcard pattern (*.foo) */ + else if (qstring[0] == 'P' && qstring[1] == '=') { + const char *eos = qstring += 2; /* for efficiency */ + + while (*eos && *eos != '&' && *eos != ';') { + ++eos; + } + + if (eos == qstring) { + pstring = NULL; + } + else { + pstring = apr_pstrndup(r->pool, qstring, eos - qstring); + if (ap_unescape_url(pstring) != OK) { + /* ignore the pattern, if it's bad. */ + pstring = NULL; + } + else { + ppre = ";P="; + /* be correct */ + epattern = ap_escape_uri(r->pool, pstring); + } + } + + if (*eos && *++eos) { + qstring = eos; + } + else { + qstring = NULL; + } + } + + /* Syntax error? Ignore the remainder! */ + else { + qstring = NULL; + } + } + colargs = apr_pstrcat(r->pool, fval, vval, ppre, epattern, NULL); + } + + /* Spew HTML preamble */ + title_endp = title_name + strlen(title_name) - 1; + + while (title_endp > title_name && *title_endp == '/') { + *title_endp-- = '\0'; + } + + emit_head(r, find_header(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE, + autoindex_opts & EMIT_XHTML, title_name); + + /* + * Since we don't know how many dir. entries there are, put them into a + * linked list and then arrayificate them so qsort can use them. + */ + head = NULL; + p = make_parent_entry(autoindex_opts, autoindex_conf, r, keyid, direction); + if (p != NULL) { + p->next = head; + head = p; + num_ent++; + } + fullpath = apr_palloc(r->pool, APR_PATH_MAX); + dirpathlen = strlen(name); + memcpy(fullpath, name, dirpathlen); + + do { + status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir); + if (APR_STATUS_IS_INCOMPLETE(status)) { + continue; /* ignore un-stat()able files */ + } + else if (status != APR_SUCCESS) { + break; + } + + /* We want to explode symlinks here. */ + if (dirent.filetype == APR_LNK) { + const char *savename; + apr_finfo_t fi; + /* We *must* have FNAME. */ + savename = dirent.name; + apr_cpystrn(fullpath + dirpathlen, dirent.name, + APR_PATH_MAX - dirpathlen); + status = apr_stat(&fi, fullpath, + dirent.valid & ~(APR_FINFO_NAME), r->pool); + if (status != APR_SUCCESS) { + /* Something bad happened, skip this file. */ + continue; + } + memcpy(&dirent, &fi, sizeof(fi)); + dirent.name = savename; + dirent.valid |= APR_FINFO_NAME; + } + p = make_autoindex_entry(&dirent, autoindex_opts, autoindex_conf, r, + keyid, direction, pstring); + if (p != NULL) { + p->next = head; + head = p; + num_ent++; + } + } while (1); + + if (num_ent > 0) { + ar = (struct ent **) apr_palloc(r->pool, + num_ent * sizeof(struct ent *)); + p = head; + x = 0; + while (p) { + ar[x++] = p; + p = p->next; + } + + qsort((void *) ar, num_ent, sizeof(struct ent *), + (int (*)(const void *, const void *)) dsortf); + } + output_directories(ar, num_ent, autoindex_conf, r, autoindex_opts, + keyid, direction, colargs); + apr_dir_close(thedir); + + emit_tail(r, find_readme(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE); + + return 0; +} + +/* The formal handler... */ + +static int handle_autoindex(request_rec *r) +{ + autoindex_config_rec *d; + int allow_opts; + + if(strcmp(r->handler,DIR_MAGIC_TYPE)) { + return DECLINED; + } + + allow_opts = ap_allow_options(r); + + d = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, + &autoindex_module); + + r->allowed |= (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) { + return DECLINED; + } + + /* OK, nothing easy. Trot out the heavy artillery... */ + + if (allow_opts & OPT_INDEXES) { + int errstatus; + + if ((errstatus = ap_discard_request_body(r)) != OK) { + return errstatus; + } + + /* KLUDGE --- make the sub_req lookups happen in the right directory. + * Fixing this in the sub_req_lookup functions themselves is difficult, + * and would probably break virtual includes... + */ + + if (r->filename[strlen(r->filename) - 1] != '/') { + r->filename = apr_pstrcat(r->pool, r->filename, "/", NULL); + } + return index_directory(r, d); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Directory index forbidden by " + "Options directive: %s", r->filename); + return HTTP_FORBIDDEN; + } +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(handle_autoindex,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA autoindex_module = +{ + STANDARD20_MODULE_STUFF, + create_autoindex_config, /* dir config creater */ + merge_autoindex_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + autoindex_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/generators/mod_autoindex.dsp b/trunk/modules/generators/mod_autoindex.dsp new file mode 100644 index 0000000000..1887553a28 --- /dev/null +++ b/trunk/modules/generators/mod_autoindex.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_autoindex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_autoindex - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_autoindex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_autoindex.mak" CFG="mod_autoindex - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_autoindex - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_autoindex - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_autoindex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_autoindex_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_autoindex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_autoindex_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_autoindex.so" /base:@..\..\os\win32\BaseAddr.ref,mod_autoindex.so + +!ENDIF + +# Begin Target + +# Name "mod_autoindex - Win32 Release" +# Name "mod_autoindex - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_autoindex.c +# End Source File +# Begin Source File + +SOURCE=.\mod_autoindex.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_autoindex - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_autoindex.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_autoindex.so "autoindex_module for Apache" ../../include/ap_release.h > .\mod_autoindex.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_autoindex - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_autoindex.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_autoindex.so "autoindex_module for Apache" ../../include/ap_release.h > .\mod_autoindex.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/generators/mod_autoindex.exp b/trunk/modules/generators/mod_autoindex.exp new file mode 100644 index 0000000000..90f4057e9c --- /dev/null +++ b/trunk/modules/generators/mod_autoindex.exp @@ -0,0 +1 @@ +autoindex_module diff --git a/trunk/modules/generators/mod_cgi.c b/trunk/modules/generators/mod_cgi.c new file mode 100644 index 0000000000..8c11071f75 --- /dev/null +++ b/trunk/modules/generators/mod_cgi.c @@ -0,0 +1,1233 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_script: keeps all script-related ramblings together. + * + * Compliant to CGI/1.1 spec + * + * Adapted by rst from original NCSA code by Rob McCool + * + * Apache adds some new env vars; REDIRECT_URL and REDIRECT_QUERY_STRING for + * custom error responses, and DOCUMENT_ROOT because we found it useful. + * It also adds SERVER_ADMIN - useful for scripts to know who to mail when + * they fail. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ +#include "apr_optional.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_poll.h" + +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE + +#include "util_filter.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#include "util_script.h" +#include "ap_mpm.h" +#include "mod_core.h" +#include "mod_cgi.h" + +module AP_MODULE_DECLARE_DATA cgi_module; + +static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi; +static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv; +static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps; +static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) *cgi_build_command; + +/* Read and discard the data in the brigade produced by a CGI script */ +static void discard_script_output(apr_bucket_brigade *bb); + +/* KLUDGE --- for back-combatibility, we don't have to check ExecCGI + * in ScriptAliased directories, which means we need to know if this + * request came through ScriptAlias or not... so the Alias module + * leaves a note for us. + */ + +static int is_scriptaliased(request_rec *r) +{ + const char *t = apr_table_get(r->notes, "alias-forced-type"); + return t && (!strcasecmp(t, "cgi-script")); +} + +/* Configuration stuff */ + +#define DEFAULT_LOGBYTES 10385760 +#define DEFAULT_BUFBYTES 1024 + +typedef struct { + const char *logname; + long logbytes; + apr_size_t bufbytes; +} cgi_server_conf; + +static void *create_cgi_config(apr_pool_t *p, server_rec *s) +{ + cgi_server_conf *c = + (cgi_server_conf *) apr_pcalloc(p, sizeof(cgi_server_conf)); + + c->logname = NULL; + c->logbytes = DEFAULT_LOGBYTES; + c->bufbytes = DEFAULT_BUFBYTES; + + return c; +} + +static void *merge_cgi_config(apr_pool_t *p, void *basev, void *overridesv) +{ + cgi_server_conf *base = (cgi_server_conf *) basev, + *overrides = (cgi_server_conf *) overridesv; + + return overrides->logname ? overrides : base; +} + +static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + cgi_server_conf *conf = ap_get_module_config(s->module_config, + &cgi_module); + + conf->logname = ap_server_root_relative(cmd->pool, arg); + + if (!conf->logname) { + return apr_pstrcat(cmd->pool, "Invalid ScriptLog path ", + arg, NULL); + } + + return NULL; +} + +static const char *set_scriptlog_length(cmd_parms *cmd, void *dummy, + const char *arg) +{ + server_rec *s = cmd->server; + cgi_server_conf *conf = ap_get_module_config(s->module_config, + &cgi_module); + + conf->logbytes = atol(arg); + return NULL; +} + +static const char *set_scriptlog_buffer(cmd_parms *cmd, void *dummy, + const char *arg) +{ + server_rec *s = cmd->server; + cgi_server_conf *conf = ap_get_module_config(s->module_config, + &cgi_module); + + conf->bufbytes = atoi(arg); + return NULL; +} + +static const command_rec cgi_cmds[] = +{ +AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, + "the name of a log for script debugging info"), +AP_INIT_TAKE1("ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF, + "the maximum length (in bytes) of the script debug log"), +AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, + "the maximum size (in bytes) to record of a POST request"), + {NULL} +}; + +static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, + apr_status_t rv, char *error) +{ + apr_file_t *f = NULL; + apr_finfo_t finfo; + char time_str[APR_CTIME_LEN]; + int log_flags = rv ? APLOG_ERR : APLOG_ERR; + + ap_log_rerror(APLOG_MARK, log_flags, rv, r, + "%s: %s", error, r->filename); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((apr_stat(&finfo, conf->logname, + APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && + (finfo.size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS)) { + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgi-bin */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_printf(f, "%%error\n%s\n", error); + + apr_file_close(f); + return ret; +} + +/* Soak up stderr from a script and redirect it to the error log. + */ +static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) +{ + char argsbuffer[HUGE_STRING_LEN]; + char *newline; + apr_status_t rv; + + while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err)) == APR_SUCCESS) { + newline = strchr(argsbuffer, '\n'); + if (newline) { + *newline = '\0'; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", argsbuffer); + } + + return rv; +} + +static int log_script(request_rec *r, cgi_server_conf * conf, int ret, + char *dbuf, const char *sbuf, apr_bucket_brigade *bb, + apr_file_t *script_err) +{ + const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); + const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts; + char argsbuffer[HUGE_STRING_LEN]; + apr_file_t *f = NULL; + apr_bucket *e; + const char *buf; + apr_size_t len; + apr_status_t rv; + int first; + int i; + apr_finfo_t finfo; + char time_str[APR_CTIME_LEN]; + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((apr_stat(&finfo, conf->logname, + APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && + (finfo.size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS)) { + /* Soak up script output */ + discard_script_output(bb); + log_script_err(r, script_err); + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgi-bin" */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_puts("%request\n", f); + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + if ((r->method_number == M_POST || r->method_number == M_PUT) && + *dbuf) { + apr_file_printf(f, "\n%s\n", dbuf); + } + + apr_file_puts("%response\n", f); + hdrs_arr = apr_table_elts(r->err_headers_out); + hdrs = (const apr_table_entry_t *) hdrs_arr->elts; + + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + + if (sbuf && *sbuf) + apr_file_printf(f, "%s\n", sbuf); + + first = 1; + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + break; + } + rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS || (len == 0)) { + break; + } + if (first) { + apr_file_puts("%stdout\n", f); + first = 0; + } + apr_file_write(f, buf, &len); + apr_file_puts("\n", f); + } + + if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, script_err) == APR_SUCCESS) { + apr_file_puts("%stderr\n", f); + apr_file_puts(argsbuffer, f); + while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err) == APR_SUCCESS) { + apr_file_puts(argsbuffer, f); + } + apr_file_puts("\n", f); + } + + apr_brigade_destroy(bb); + apr_file_close(script_err); + + apr_file_close(f); + return ret; +} + + +/* This is the special environment used for running the "exec cmd=" + * variety of SSI directives. + */ +static void add_ssi_vars(request_rec *r) +{ + apr_table_t *e = r->subprocess_env; + + if (r->path_info && r->path_info[0] != '\0') { + request_rec *pa_req; + + apr_table_setn(e, "PATH_INFO", ap_escape_shell_cmd(r->pool, + r->path_info)); + + pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), + r, NULL); + if (pa_req->filename) { + apr_table_setn(e, "PATH_TRANSLATED", + apr_pstrcat(r->pool, pa_req->filename, + pa_req->path_info, NULL)); + } + ap_destroy_sub_req(pa_req); + } + + if (r->args) { + char *arg_copy = apr_pstrdup(r->pool, r->args); + + apr_table_setn(e, "QUERY_STRING", r->args); + ap_unescape_url(arg_copy); + apr_table_setn(e, "QUERY_STRING_UNESCAPED", + ap_escape_shell_cmd(r->pool, arg_copy)); + } +} + +static void cgi_child_errfn(apr_pool_t *pool, apr_status_t err, + const char *description) +{ + apr_file_t *stderr_log; + char errbuf[200]; + + apr_file_open_stderr(&stderr_log, pool); + /* Escape the logged string because it may be something that + * came in over the network. + */ + apr_file_printf(stderr_log, + "(%d)%s: %s\n", + err, + apr_strerror(err, errbuf, sizeof(errbuf)), +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + ap_escape_logitem(pool, +#endif + description +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + ) +#endif + ); +} + +static apr_status_t run_cgi_child(apr_file_t **script_out, + apr_file_t **script_in, + apr_file_t **script_err, + const char *command, + const char * const argv[], + request_rec *r, + apr_pool_t *p, + cgi_exec_info_t *e_info) +{ + const char * const *env; + apr_procattr_t *procattr; + apr_proc_t *procnew; + apr_status_t rc = APR_SUCCESS; + +#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \ + defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS) + + core_dir_config *conf = ap_get_module_config(r->per_dir_config, + &core_module); +#endif + +#ifdef DEBUG_CGI +#ifdef OS2 + /* Under OS/2 need to use device con. */ + FILE *dbg = fopen("con", "w"); +#else + FILE *dbg = fopen("/dev/tty", "w"); +#endif + int i; +#endif + + RAISE_SIGSTOP(CGI_CHILD); +#ifdef DEBUG_CGI + fprintf(dbg, "Attempting to exec %s as CGI child (argv0 = %s)\n", + r->filename, argv[0]); +#endif + + env = (const char * const *)ap_create_environment(p, r->subprocess_env); + +#ifdef DEBUG_CGI + fprintf(dbg, "Environment: \n"); + for (i = 0; env[i]; ++i) + fprintf(dbg, "'%s'\n", env[i]); +#endif + + /* Transmute ourselves into the script. + * NB only ISINDEX scripts get decoded arguments. + */ + if (((rc = apr_procattr_create(&procattr, p)) != APR_SUCCESS) || + ((rc = apr_procattr_io_set(procattr, + e_info->in_pipe, + e_info->out_pipe, + e_info->err_pipe)) != APR_SUCCESS) || + ((rc = apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(r->pool, + r->filename))) != APR_SUCCESS) || +#ifdef RLIMIT_CPU + ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_CPU, + conf->limit_cpu)) != APR_SUCCESS) || +#endif +#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_MEM, + conf->limit_mem)) != APR_SUCCESS) || +#endif +#ifdef RLIMIT_NPROC + ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, + conf->limit_nproc)) != APR_SUCCESS) || +#endif + ((rc = apr_procattr_cmdtype_set(procattr, + e_info->cmd_type)) != APR_SUCCESS) || + + ((rc = apr_procattr_detach_set(procattr, + e_info->detached)) != APR_SUCCESS) || + ((rc = apr_procattr_addrspace_set(procattr, + e_info->addrspace)) != APR_SUCCESS) || + ((rc = apr_procattr_child_errfn_set(procattr, cgi_child_errfn)) != APR_SUCCESS)) { + /* Something bad happened, tell the world. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, + "couldn't set child process attributes: %s", r->filename); + } + else { + procnew = apr_pcalloc(p, sizeof(*procnew)); + rc = ap_os_create_privileged_process(r, procnew, command, argv, env, + procattr, p); + + if (rc != APR_SUCCESS) { + /* Bad things happened. Everyone should have cleaned up. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, rc, r, + "couldn't create child process: %d: %s", rc, + apr_filepath_name_get(r->filename)); + } + else { + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + + *script_in = procnew->out; + if (!*script_in) + return APR_EBADF; + apr_file_pipe_timeout_set(*script_in, r->server->timeout); + + if (e_info->prog_type == RUN_AS_CGI) { + *script_out = procnew->in; + if (!*script_out) + return APR_EBADF; + apr_file_pipe_timeout_set(*script_out, r->server->timeout); + + *script_err = procnew->err; + if (!*script_err) + return APR_EBADF; + apr_file_pipe_timeout_set(*script_err, r->server->timeout); + } + } + } +#ifdef DEBUG_CGI + fclose(dbg); +#endif + return (rc); +} + + +static apr_status_t default_build_command(const char **cmd, const char ***argv, + request_rec *r, apr_pool_t *p, + cgi_exec_info_t *e_info) +{ + int numwords, x, idx; + char *w; + const char *args = NULL; + + if (e_info->process_cgi) { + *cmd = r->filename; + /* Do not process r->args if they contain an '=' assignment + */ + if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) { + args = r->args; + } + } + + if (!args) { + numwords = 1; + } + else { + /* count the number of keywords */ + for (x = 0, numwords = 2; args[x]; x++) { + if (args[x] == '+') { + ++numwords; + } + } + } + /* Everything is - 1 to account for the first parameter + * which is the program name. + */ + if (numwords > APACHE_ARG_MAX - 1) { + numwords = APACHE_ARG_MAX - 1; /* Truncate args to prevent overrun */ + } + *argv = apr_palloc(p, (numwords + 2) * sizeof(char *)); + (*argv)[0] = *cmd; + for (x = 1, idx = 1; x < numwords; x++) { + w = ap_getword_nulls(p, &args, '+'); + ap_unescape_url(w); + (*argv)[idx++] = ap_escape_shell_cmd(p, w); + } + (*argv)[idx] = NULL; + + return APR_SUCCESS; +} + +static void discard_script_output(apr_bucket_brigade *bb) +{ + apr_bucket *e; + const char *buf; + apr_size_t len; + apr_status_t rv; + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + break; + } + rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + break; + } + } +} + +#if APR_FILES_AS_SOCKETS + +/* A CGI bucket type is needed to catch any output to stderr from the + * script; see PR 22030. */ +static const apr_bucket_type_t bucket_type_cgi; + +struct cgi_bucket_data { + apr_pollset_t *pollset; + request_rec *r; +}; + +/* Create a CGI bucket using pipes from script stdout 'out' + * and stderr 'err', for request 'r'. */ +static apr_bucket *cgi_bucket_create(request_rec *r, + apr_file_t *out, apr_file_t *err, + apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + apr_status_t rv; + apr_pollfd_t fd; + struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); + + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + b->type = &bucket_type_cgi; + b->length = (apr_size_t)(-1); + b->start = -1; + + /* Create the pollset */ + rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); + AP_DEBUG_ASSERT(rv == APR_SUCCESS); + + fd.desc_type = APR_POLL_FILE; + fd.reqevents = APR_POLLIN; + fd.p = r->pool; + fd.desc.f = out; /* script's stdout */ + fd.client_data = (void *)1; + rv = apr_pollset_add(data->pollset, &fd); + AP_DEBUG_ASSERT(rv == APR_SUCCESS); + + fd.desc.f = err; /* script's stderr */ + fd.client_data = (void *)2; + rv = apr_pollset_add(data->pollset, &fd); + AP_DEBUG_ASSERT(rv == APR_SUCCESS); + + data->r = r; + b->data = data; + return b; +} + +/* Create a duplicate CGI bucket using given bucket data */ +static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, + apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + b->type = &bucket_type_cgi; + b->length = (apr_size_t)(-1); + b->start = -1; + b->data = data; + return b; +} + +/* Handle stdout from CGI child. Duplicate of logic from the _read + * method of the real APR pipe bucket implementation. */ +static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, + const char **str, apr_size_t *len) +{ + char *buf; + apr_status_t rv; + + *str = NULL; + *len = APR_BUCKET_BUFF_SIZE; + buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ + + rv = apr_file_read(out, buf, len); + + if (rv != APR_SUCCESS && rv != APR_EOF) { + apr_bucket_free(buf); + return rv; + } + + if (*len > 0) { + struct cgi_bucket_data *data = a->data; + apr_bucket_heap *h; + + /* Change the current bucket to refer to what we read */ + a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); + h = a->data; + h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ + *str = buf; + APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); + } + else { + apr_bucket_free(buf); + a = apr_bucket_immortal_make(a, "", 0); + *str = a->data; + } + return rv; +} + +/* Read method of CGI bucket: polls on stderr and stdout of the child, + * sending any stderr output immediately away to the error log. */ +static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, + apr_size_t *len, apr_read_type_e block) +{ + struct cgi_bucket_data *data = b->data; + apr_interval_time_t timeout; + apr_status_t rv; + int gotdata = 0; + + timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout; + + do { + const apr_pollfd_t *results; + apr_int32_t num; + + rv = apr_pollset_poll(data->pollset, timeout, &num, &results); + if (APR_STATUS_IS_TIMEUP(rv)) { + return timeout == 0 ? APR_EAGAIN : rv; + } + else if (APR_STATUS_IS_EINTR(rv)) { + continue; + } + else if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, + "poll failed waiting for CGI child"); + return rv; + } + + for (; num; num--, results++) { + if (results[0].client_data == (void *)1) { + /* stdout */ + rv = cgi_read_stdout(b, results[0].desc.f, str, len); + if (APR_STATUS_IS_EOF(rv)) { + rv = APR_SUCCESS; + } + gotdata = 1; + } else { + /* stderr */ + apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); + if (APR_STATUS_IS_EOF(rv2)) { + apr_pollset_remove(data->pollset, &results[0]); + } + } + } + + } while (!gotdata); + + return rv; +} + +static const apr_bucket_type_t bucket_type_cgi = { + "CGI", 5, APR_BUCKET_DATA, + apr_bucket_destroy_noop, + cgi_bucket_read, + apr_bucket_setaside_notimpl, + apr_bucket_split_notimpl, + apr_bucket_copy_notimpl +}; + +#endif + +static int cgi_handler(request_rec *r) +{ + int nph; + apr_size_t dbpos = 0; + const char *argv0; + const char *command; + const char **argv; + char *dbuf = NULL; + apr_file_t *script_out = NULL, *script_in = NULL, *script_err = NULL; + apr_bucket_brigade *bb; + apr_bucket *b; + int is_included; + int seen_eos, child_stopped_reading; + apr_pool_t *p; + cgi_server_conf *conf; + apr_status_t rv; + cgi_exec_info_t e_info; + conn_rec *c = r->connection; + + if(strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) + return DECLINED; + + is_included = !strcmp(r->protocol, "INCLUDED"); + + p = r->main ? r->main->pool : r->pool; + + if (r->method_number == M_OPTIONS) { + /* 99 out of 100 CGI scripts, this is all they support */ + r->allowed |= (AP_METHOD_BIT << M_GET); + r->allowed |= (AP_METHOD_BIT << M_POST); + return DECLINED; + } + + argv0 = apr_filepath_name_get(r->filename); + nph = !(strncmp(argv0, "nph-", 4)); + conf = ap_get_module_config(r->server->module_config, &cgi_module); + + if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "Options ExecCGI is off in this directory"); + if (nph && is_included) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "attempt to include NPH CGI script"); + + if (r->finfo.filetype == 0) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, + "script not found or unable to stat"); + if (r->finfo.filetype == APR_DIR) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "attempt to invoke directory as script"); + + if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) && + r->path_info && *r->path_info) + { + /* default to accept */ + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, + "AcceptPathInfo off disallows user's path"); + } +/* + if (!ap_suexec_enabled) { + if (!ap_can_exec(&r->finfo)) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "file permissions deny server execution"); + } + +*/ + ap_add_common_vars(r); + ap_add_cgi_vars(r); + + e_info.process_cgi = 1; + e_info.cmd_type = APR_PROGRAM; + e_info.detached = 0; + e_info.in_pipe = APR_CHILD_BLOCK; + e_info.out_pipe = APR_CHILD_BLOCK; + e_info.err_pipe = APR_CHILD_BLOCK; + e_info.prog_type = RUN_AS_CGI; + e_info.bb = NULL; + e_info.ctx = NULL; + e_info.next = NULL; + e_info.addrspace = 0; + + /* build the command line */ + if ((rv = cgi_build_command(&command, &argv, r, p, &e_info)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "don't know how to spawn child process: %s", + r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* run the script in its own process */ + if ((rv = run_cgi_child(&script_out, &script_in, &script_err, + command, argv, r, p, &e_info)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "couldn't spawn child process: %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Transfer any put/post args, CERN style... + * Note that we already ignore SIGPIPE in the core server. + */ + bb = apr_brigade_create(r->pool, c->bucket_alloc); + seen_eos = 0; + child_stopped_reading = 0; + if (conf->logname) { + dbuf = apr_palloc(r->pool, conf->bufbytes + 1); + dbpos = 0; + } + do { + apr_bucket *bucket; + + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, HUGE_STRING_LEN); + + if (rv != APR_SUCCESS) { + return rv; + } + + for (bucket = APR_BRIGADE_FIRST(bb); + bucket != APR_BRIGADE_SENTINEL(bb); + bucket = APR_BUCKET_NEXT(bucket)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + /* We can't do much with this. */ + if (APR_BUCKET_IS_FLUSH(bucket)) { + continue; + } + + /* If the child stopped, we still must read to EOS. */ + if (child_stopped_reading) { + continue; + } + + /* read */ + apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + + if (conf->logname && dbpos < conf->bufbytes) { + int cursize; + + if ((dbpos + len) > conf->bufbytes) { + cursize = conf->bufbytes - dbpos; + } + else { + cursize = len; + } + memcpy(dbuf + dbpos, data, cursize); + dbpos += cursize; + } + + /* Keep writing data to the child until done or too much time + * elapses with no progress or an error occurs. + */ + rv = apr_file_write_full(script_out, data, len, NULL); + + if (rv != APR_SUCCESS) { + /* silly script stopped reading, soak up remaining message */ + child_stopped_reading = 1; + } + } + apr_brigade_cleanup(bb); + } + while (!seen_eos); + + if (conf->logname) { + dbuf[dbpos] = '\0'; + } + /* Is this flush really needed? */ + apr_file_flush(script_out); + apr_file_close(script_out); + + AP_DEBUG_ASSERT(script_in != NULL); + + apr_brigade_cleanup(bb); + +#if APR_FILES_AS_SOCKETS + apr_file_pipe_timeout_set(script_in, 0); + apr_file_pipe_timeout_set(script_err, 0); + + b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc); +#else + b = apr_bucket_pipe_create(script_in, c->bucket_alloc); +#endif + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + /* Handle script return... */ + if (!nph) { + const char *location; + char sbuf[MAX_STRING_LEN]; + int ret; + + if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) { + return log_script(r, conf, ret, dbuf, sbuf, bb, script_err); + } + + location = apr_table_get(r->headers_out, "Location"); + + if (location && r->status == 200) { + /* For a redirect whether internal or not, discard any + * remaining stdout from the script, and log any remaining + * stderr output, as normal. */ + discard_script_output(bb); + apr_brigade_destroy(bb); + apr_file_pipe_timeout_set(script_err, r->server->timeout); + log_script_err(r, script_err); + } + + if (location && location[0] == '/' && r->status == 200) { + /* This redirect needs to be a GET no matter what the original + * method was. + */ + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + + /* We already read the message body (if any), so don't allow + * the redirected request to think it has one. We can ignore + * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. + */ + apr_table_unset(r->headers_in, "Content-Length"); + + ap_internal_redirect_handler(location, r); + return OK; + } + else if (location && r->status == 200) { + /* XX Note that if a script wants to produce its own Redirect + * body, it now has to explicitly *say* "Status: 302" + */ + return HTTP_MOVED_TEMPORARILY; + } + + rv = ap_pass_brigade(r->output_filters, bb); + } + else /* nph */ { + struct ap_filter_t *cur; + + /* get rid of all filters up through protocol... since we + * haven't parsed off the headers, there is no way they can + * work + */ + + cur = r->proto_output_filters; + while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { + cur = cur->next; + } + r->output_filters = r->proto_output_filters = cur; + + rv = ap_pass_brigade(r->output_filters, bb); + } + + /* don't soak up script output if errors occurred writing it + * out... otherwise, we prolong the life of the script when the + * connection drops or we stopped sending output for some other + * reason */ + if (rv == APR_SUCCESS && !r->connection->aborted) { + apr_file_pipe_timeout_set(script_err, r->server->timeout); + log_script_err(r, script_err); + } + + apr_file_close(script_err); + + return OK; /* NOT r->status, even if it has changed. */ +} + +/*============================================================================ + *============================================================================ + * This is the beginning of the cgi filter code moved from mod_include. This + * is the code required to handle the "exec" SSI directive. + *============================================================================ + *============================================================================*/ +static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, char *s) +{ + request_rec *r = f->r; + request_rec *rr = ap_sub_req_lookup_uri(s, r, f->next); + int rr_status; + + if (rr->status != HTTP_OK) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + + /* No hardwired path info or query allowed */ + if ((rr->path_info && rr->path_info[0]) || rr->args) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + if (rr->finfo.filetype != APR_REG) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + + /* Script gets parameters of the *document*, for back compatibility */ + rr->path_info = r->path_info; /* hard to get right; see mod_cgi.c */ + rr->args = r->args; + + /* Force sub_req to be treated as a CGI request, even if ordinary + * typing rules would have called it something else. + */ + ap_set_content_type(rr, CGI_MAGIC_TYPE); + + /* Run it. */ + rr_status = ap_run_sub_req(rr); + if (ap_is_HTTP_REDIRECT(rr_status)) { + const char *location = apr_table_get(rr->headers_out, "Location"); + + if (location) { + char *buffer; + + location = ap_escape_html(rr->pool, location); + buffer = apr_pstrcat(ctx->pool, "<a href=\"", location, "\">", + location, "</a>", NULL); + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(buffer, + strlen(buffer), ctx->pool, + f->c->bucket_alloc)); + } + } + + ap_destroy_sub_req(rr); + + return APR_SUCCESS; +} + +static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, const char *command) +{ + cgi_exec_info_t e_info; + const char **argv; + apr_file_t *script_out = NULL, *script_in = NULL, *script_err = NULL; + apr_status_t rv; + request_rec *r = f->r; + + add_ssi_vars(r); + + e_info.process_cgi = 0; + e_info.cmd_type = APR_SHELLCMD; + e_info.detached = 0; + e_info.in_pipe = APR_NO_PIPE; + e_info.out_pipe = APR_FULL_BLOCK; + e_info.err_pipe = APR_NO_PIPE; + e_info.prog_type = RUN_AS_SSI; + e_info.bb = &bb; + e_info.ctx = ctx; + e_info.next = f->next; + e_info.addrspace = 0; + + if ((rv = cgi_build_command(&command, &argv, r, r->pool, + &e_info)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "don't know how to spawn cmd child process: %s", + r->filename); + return rv; + } + + /* run the script in its own process */ + if ((rv = run_cgi_child(&script_out, &script_in, &script_err, + command, argv, r, r->pool, + &e_info)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "couldn't spawn child process: %s", r->filename); + return rv; + } + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(script_in, + f->c->bucket_alloc)); + ctx->flush_now = 1; + + /* We can't close the pipe here, because we may return before the + * full CGI has been sent to the network. That's okay though, + * because we can rely on the pool to close the pipe for us. + */ + return APR_SUCCESS; +} + +static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *tag_val = NULL; + request_rec *r = f->r; + char *file = r->filename; + char parsed_string[MAX_STRING_LEN]; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for exec element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (ctx->flags & SSI_FLAG_NO_EXEC) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "exec used but not allowed " + "in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "cmd")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_LEAVE_NAME); + + rv = include_cmd(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "execution failure " + "for parameter \"%s\" to tag exec in file %s", + tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else if (!strcmp(tag, "cgi")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_DROP_NAME); + + rv = include_cgi(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "invalid CGI ref " + "\"%s\" in %s", tag_val, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " + "\"%s\" to tag exec in %s", tag, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + + +/*============================================================================ + *============================================================================ + * This is the end of the cgi filter code moved from mod_include. + *============================================================================ + *============================================================================*/ + + +static int cgi_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); + cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); + cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); + + if ((cgi_pfn_reg_with_ssi) && (cgi_pfn_gtv) && (cgi_pfn_ps)) { + /* Required by mod_include filter. This is how mod_cgi registers + * with mod_include to provide processing of the exec directive. + */ + cgi_pfn_reg_with_ssi("exec", handle_exec); + } + + /* This is the means by which unusual (non-unix) os's may find alternate + * means to run a given command (e.g. shebang/registry parsing on Win32) + */ + cgi_build_command = APR_RETRIEVE_OPTIONAL_FN(ap_cgi_build_command); + if (!cgi_build_command) { + cgi_build_command = default_build_command; + } + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[] = { "mod_include.c", NULL }; + ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(cgi_post_config, aszPre, NULL, APR_HOOK_REALLY_FIRST); +} + +module AP_MODULE_DECLARE_DATA cgi_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_cgi_config, /* server config */ + merge_cgi_config, /* merge server config */ + cgi_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/generators/mod_cgi.dsp b/trunk/modules/generators/mod_cgi.dsp new file mode 100644 index 0000000000..a17ceaea37 --- /dev/null +++ b/trunk/modules/generators/mod_cgi.dsp @@ -0,0 +1,132 @@ +# Microsoft Developer Studio Project File - Name="mod_cgi" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_cgi - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_cgi.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_cgi.mak" CFG="mod_cgi - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_cgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_cgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_cgi - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_cgi_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_cgi - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_cgi_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_cgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cgi.so + +!ENDIF + +# Begin Target + +# Name "mod_cgi - Win32 Release" +# Name "mod_cgi - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_cgi.c +# End Source File +# Begin Source File + +SOURCE=.\mod_cgi.h +# End Source File +# Begin Source File + +SOURCE=.\mod_cgi.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_cgi - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cgi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cgi.so "cgi_module for Apache" ../../include/ap_release.h > .\mod_cgi.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_cgi - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cgi.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cgi.so "cgi_module for Apache" ../../include/ap_release.h > .\mod_cgi.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/generators/mod_cgi.exp b/trunk/modules/generators/mod_cgi.exp new file mode 100644 index 0000000000..96ea0c2348 --- /dev/null +++ b/trunk/modules/generators/mod_cgi.exp @@ -0,0 +1 @@ +cgi_module diff --git a/trunk/modules/generators/mod_cgi.h b/trunk/modules/generators/mod_cgi.h new file mode 100644 index 0000000000..1429efadf3 --- /dev/null +++ b/trunk/modules/generators/mod_cgi.h @@ -0,0 +1,59 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MOD_CGI_H +#define _MOD_CGI_H 1 + +#include "mod_include.h" + +typedef enum {RUN_AS_SSI, RUN_AS_CGI} prog_types; + +typedef struct { + apr_int32_t in_pipe; + apr_int32_t out_pipe; + apr_int32_t err_pipe; + int process_cgi; + apr_cmdtype_e cmd_type; + apr_int32_t detached; + prog_types prog_type; + apr_bucket_brigade **bb; + include_ctx_t *ctx; + ap_filter_t *next; + apr_int32_t addrspace; +} cgi_exec_info_t; + +/** + * Registerable optional function to override CGI behavior; + * Reprocess the command and arguments to execute the given CGI script. + * @param cmd Pointer to the command to execute (may be overridden) + * @param argv Pointer to the arguments to pass (may be overridden) + * @param r The current request + * @param p The pool to allocate correct cmd/argv elements within. + * @param process_cgi Set true if processing r->filename and r->args + * as a CGI invocation, otherwise false + * @param type Set to APR_SHELLCMD or APR_PROGRAM on entry, may be + * changed to invoke the program with alternate semantics. + * @param detach Should the child start in detached state? Default is no. + * @remark This callback may be registered by the os-specific module + * to correct the command and arguments for apr_proc_create invocation + * on a given os. mod_cgi will call the function if registered. + */ +APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_cgi_build_command, + (const char **cmd, const char ***argv, + request_rec *r, apr_pool_t *p, + cgi_exec_info_t *e_info)); + +#endif /* _MOD_CGI_H */ diff --git a/trunk/modules/generators/mod_cgid.c b/trunk/modules/generators/mod_cgid.c new file mode 100644 index 0000000000..997445972a --- /dev/null +++ b/trunk/modules/generators/mod_cgid.c @@ -0,0 +1,1787 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_script: keeps all script-related ramblings together. + * + * Compliant to cgi/1.1 spec + * + * Adapted by rst from original NCSA code by Rob McCool + * + * Apache adds some new env vars; REDIRECT_URL and REDIRECT_QUERY_STRING for + * custom error responses, and DOCUMENT_ROOT because we found it useful. + * It also adds SERVER_ADMIN - useful for scripts to know who to mail when + * they fail. + */ + +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_general.h" +#include "apr_file_io.h" +#include "apr_portable.h" +#include "apr_buckets.h" +#include "apr_optional.h" +#include "apr_signal.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#if APR_HAVE_UNISTD_H +#include <unistd.h> +#endif +#if APR_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#define CORE_PRIVATE + +#include "util_filter.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#include "util_script.h" +#include "ap_mpm.h" +#include "unixd.h" +#include "mod_suexec.h" +#include "../filters/mod_include.h" + +#include "mod_core.h" + + +/* ### should be tossed in favor of APR */ +#include <sys/stat.h> +#include <sys/un.h> /* for sockaddr_un */ + + +module AP_MODULE_DECLARE_DATA cgid_module; + +static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew); +static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server); +static int handle_exec(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb); + +static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgid_pfn_reg_with_ssi; +static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgid_pfn_gtv; +static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgid_pfn_ps; + +static apr_pool_t *pcgi = NULL; +static int total_modules = 0; +static pid_t daemon_pid; +static int daemon_should_exit = 0; +static server_rec *root_server = NULL; +static apr_pool_t *root_pool = NULL; +static const char *sockname; +static pid_t parent_pid; + +/* Read and discard the data in the brigade produced by a CGI script */ +static void discard_script_output(apr_bucket_brigade *bb); + +/* KLUDGE --- for back-combatibility, we don't have to check ExecCGI + * in ScriptAliased directories, which means we need to know if this + * request came through ScriptAlias or not... so the Alias module + * leaves a note for us. + */ + +static int is_scriptaliased(request_rec *r) +{ + const char *t = apr_table_get(r->notes, "alias-forced-type"); + return t && (!strcasecmp(t, "cgi-script")); +} + +/* Configuration stuff */ + +#define DEFAULT_LOGBYTES 10385760 +#define DEFAULT_BUFBYTES 1024 +#define DEFAULT_SOCKET DEFAULT_REL_RUNTIMEDIR "/cgisock" + +#define CGI_REQ 1 +#define SSI_REQ 2 +#define GETPID_REQ 3 /* get the pid of script created for prior request */ + +#define ERRFN_USERDATA_KEY "CGIDCHILDERRFN" + +/* DEFAULT_CGID_LISTENBACKLOG controls the max depth on the unix socket's + * pending connection queue. If a bunch of cgi requests arrive at about + * the same time, connections from httpd threads/processes will back up + * in the queue while the cgid process slowly forks off a child to process + * each connection on the unix socket. If the queue is too short, the + * httpd process will get ECONNREFUSED when trying to connect. + */ +#ifndef DEFAULT_CGID_LISTENBACKLOG +#define DEFAULT_CGID_LISTENBACKLOG 100 +#endif + +/* DEFAULT_CONNECT_ATTEMPTS controls how many times we'll try to connect + * to the cgi daemon from the thread/process handling the cgi request. + * Generally we want to retry when we get ECONNREFUSED since it is + * probably because the listen queue is full. We need to try harder so + * the client doesn't see it as a 503 error. + * + * Set this to 0 to continually retry until the connect works or Apache + * terminates. + */ +#ifndef DEFAULT_CONNECT_ATTEMPTS +#define DEFAULT_CONNECT_ATTEMPTS 15 +#endif + +typedef struct { + const char *logname; + long logbytes; + int bufbytes; +} cgid_server_conf; + +typedef struct { + int req_type; /* request type (CGI_REQ, SSI_REQ, etc.) */ + unsigned long conn_id; /* connection id; daemon uses this as a hash value + * to find the script pid when it is time for that + * process to be cleaned up + */ + pid_t ppid; /* sanity check for config problems leading to + * wrong cgid socket use + */ + int core_module_index; + int have_suexec; + int suexec_module_index; + suexec_config_t suexec_cfg; + int env_count; + apr_size_t filename_len; + apr_size_t argv0_len; + apr_size_t uri_len; + apr_size_t args_len; + apr_size_t mod_userdir_user_len; + int loglevel; /* to stuff in server_rec */ +} cgid_req_t; + +/* This routine is called to create the argument list to be passed + * to the CGI script. When suexec is enabled, the suexec path, user, and + * group are the first three arguments to be passed; if not, all three + * must be NULL. The query info is split into separate arguments, where + * "+" is the separator between keyword arguments. + * + * Do not process the args if they containing an '=' assignment. + */ +static char **create_argv(apr_pool_t *p, char *path, char *user, char *group, + char *av0, const char *args) +{ + int x, numwords; + char **av; + char *w; + int idx = 0; + + if (ap_strchr_c(args, '=')) { + numwords = 0; + } + else { + /* count the number of keywords */ + + for (x = 0, numwords = 1; args[x]; x++) { + if (args[x] == '+') { + ++numwords; + } + } + } + + if (numwords > APACHE_ARG_MAX - 5) { + numwords = APACHE_ARG_MAX - 5; /* Truncate args to prevent overrun */ + } + av = (char **) apr_pcalloc(p, (numwords + 5) * sizeof(char *)); + + if (path) { + av[idx++] = path; + } + if (user) { + av[idx++] = user; + } + if (group) { + av[idx++] = group; + } + + av[idx++] = apr_pstrdup(p, av0); + + for (x = 1; x <= numwords; x++) { + w = ap_getword_nulls(p, &args, '+'); + if (strcmp(w, "")) { + ap_unescape_url(w); + av[idx++] = ap_escape_shell_cmd(p, w); + } + } + av[idx] = NULL; + return av; +} + +#if APR_HAS_OTHER_CHILD +static void cgid_maint(int reason, void *data, apr_wait_t status) +{ + apr_proc_t *proc = data; + int mpm_state; + int stopping; + + switch (reason) { + case APR_OC_REASON_DEATH: + apr_proc_other_child_unregister(data); + /* If apache is not terminating or restarting, + * restart the cgid daemon + */ + stopping = 1; /* if MPM doesn't support query, + * assume we shouldn't restart daemon + */ + if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state) == APR_SUCCESS && + mpm_state != AP_MPMQ_STOPPING) { + stopping = 0; + } + if (!stopping) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "cgid daemon process died, restarting"); + cgid_start(root_pool, root_server, proc); + } + break; + case APR_OC_REASON_RESTART: + /* don't do anything; server is stopping or restarting */ + apr_proc_other_child_unregister(data); + break; + case APR_OC_REASON_LOST: + /* Restart the child cgid daemon process */ + apr_proc_other_child_unregister(data); + cgid_start(root_pool, root_server, proc); + break; + case APR_OC_REASON_UNREGISTER: + /* we get here when pcgi is cleaned up; pcgi gets cleaned + * up when pconf gets cleaned up + */ + kill(proc->pid, SIGHUP); /* send signal to daemon telling it to die */ + break; + } +} +#endif + +/* deal with incomplete reads and signals + * assume you really have to read buf_size bytes + */ +static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) +{ + char *buf = vbuf; + int rc; + size_t bytes_read = 0; + + do { + do { + rc = read(fd, buf + bytes_read, buf_size - bytes_read); + } while (rc < 0 && errno == EINTR); + switch(rc) { + case -1: + return errno; + case 0: /* unexpected */ + return ECONNRESET; + default: + bytes_read += rc; + } + } while (bytes_read < buf_size); + + return APR_SUCCESS; +} + +/* deal with signals + */ +static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) +{ + int rc; + + do { + rc = write(fd, buf, buf_size); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { + return errno; + } + + return APR_SUCCESS; +} + +static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, + cgid_req_t *req) +{ + int i; + char *user; + char **environ; + core_dir_config *temp_core; + void **dconf; + apr_status_t stat; + + r->server = apr_pcalloc(r->pool, sizeof(server_rec)); + + /* read the request header */ + stat = sock_read(fd, req, sizeof(*req)); + if (stat != APR_SUCCESS) { + return stat; + } + r->server->loglevel = req->loglevel; + if (req->req_type == GETPID_REQ) { + /* no more data sent for this request */ + return APR_SUCCESS; + } + + /* handle module indexes and such */ + dconf = (void **) apr_pcalloc(r->pool, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT)); + + temp_core = (core_dir_config *)apr_palloc(r->pool, sizeof(core_module)); + dconf[req->core_module_index] = (void *)temp_core; + + if (req->have_suexec) { + dconf[req->suexec_module_index] = &req->suexec_cfg; + } + + r->per_dir_config = (ap_conf_vector_t *)dconf; + + /* Read the filename, argv0, uri, and args */ + r->filename = apr_pcalloc(r->pool, req->filename_len + 1); + *argv0 = apr_pcalloc(r->pool, req->argv0_len + 1); + r->uri = apr_pcalloc(r->pool, req->uri_len + 1); + if ((stat = sock_read(fd, r->filename, req->filename_len)) != APR_SUCCESS || + (stat = sock_read(fd, *argv0, req->argv0_len)) != APR_SUCCESS || + (stat = sock_read(fd, r->uri, req->uri_len)) != APR_SUCCESS) { + return stat; + } + + r->args = apr_pcalloc(r->pool, req->args_len + 1); /* empty string if no args */ + if (req->args_len) { + if ((stat = sock_read(fd, r->args, req->args_len)) != APR_SUCCESS) { + return stat; + } + } + + /* read the environment variables */ + environ = apr_pcalloc(r->pool, (req->env_count + 2) *sizeof(char *)); + for (i = 0; i < req->env_count; i++) { + apr_size_t curlen; + + if ((stat = sock_read(fd, &curlen, sizeof(curlen))) != APR_SUCCESS) { + return stat; + } + environ[i] = apr_pcalloc(r->pool, curlen + 1); + if ((stat = sock_read(fd, environ[i], curlen)) != APR_SUCCESS) { + return stat; + } + } + *env = environ; + + /* basic notes table to avoid segfaults */ + r->notes = apr_table_make(r->pool, 1); + + /* mod_userdir requires the mod_userdir_user note */ + if (req->mod_userdir_user_len) { + user = apr_pcalloc(r->pool, req->mod_userdir_user_len + 1); /* last byte is '\0' */ + stat = sock_read(fd, user, req->mod_userdir_user_len); + if (stat != APR_SUCCESS) { + return stat; + } + apr_table_set(r->notes, "mod_userdir_user", (const char *)user); + } + +#if 0 +#ifdef RLIMIT_CPU + sock_read(fd, &j, sizeof(int)); + if (j) { + temp_core->limit_cpu = (struct rlimit *)apr_palloc (sizeof(struct rlimit)); + sock_read(fd, temp_core->limit_cpu, sizeof(struct rlimit)); + } + else { + temp_core->limit_cpu = NULL; + } +#endif + +#if defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + sock_read(fd, &j, sizeof(int)); + if (j) { + temp_core->limit_mem = (struct rlimit *)apr_palloc(r->pool, sizeof(struct rlimit)); + sock_read(fd, temp_core->limit_mem, sizeof(struct rlimit)); + } + else { + temp_core->limit_mem = NULL; + } +#endif + +#ifdef RLIMIT_NPROC + sock_read(fd, &j, sizeof(int)); + if (j) { + temp_core->limit_nproc = (struct rlimit *)apr_palloc(r->pool, sizeof(struct rlimit)); + sock_read(fd, temp_core->limit_nproc, sizeof(struct rlimit)); + } + else { + temp_core->limit_nproc = NULL; + } +#endif +#endif + + return APR_SUCCESS; +} + +static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, + int req_type) +{ + int i; + const char *user; + module *suexec_mod = ap_find_linked_module("mod_suexec.c"); + cgid_req_t req = {0}; + suexec_config_t *suexec_cfg; + apr_status_t stat; + + req.req_type = req_type; + req.ppid = parent_pid; + req.conn_id = r->connection->id; + req.core_module_index = core_module.module_index; + if (suexec_mod) { + req.have_suexec = 1; + req.suexec_module_index = suexec_mod->module_index; + suexec_cfg = ap_get_module_config(r->per_dir_config, + suexec_mod); + req.suexec_cfg = *suexec_cfg; + } + for (req.env_count = 0; env[req.env_count]; req.env_count++) { + continue; + } + req.filename_len = strlen(r->filename); + req.argv0_len = strlen(argv0); + req.uri_len = strlen(r->uri); + req.args_len = r->args ? strlen(r->args) : 0; + user = (const char *)apr_table_get(r->notes, "mod_userdir_user"); + if (user != NULL) { + req.mod_userdir_user_len = strlen(user); + } + req.loglevel = r->server->loglevel; + + /* Write the request header */ + if ((stat = sock_write(fd, &req, sizeof(req))) != APR_SUCCESS) { + return stat; + } + + /* Write filename, argv0, uri, and args */ + if ((stat = sock_write(fd, r->filename, req.filename_len)) != APR_SUCCESS || + (stat = sock_write(fd, argv0, req.argv0_len)) != APR_SUCCESS || + (stat = sock_write(fd, r->uri, req.uri_len)) != APR_SUCCESS) { + return stat; + } + if (req.args_len) { + if ((stat = sock_write(fd, r->args, req.args_len)) != APR_SUCCESS) { + return stat; + } + } + + /* write the environment variables */ + for (i = 0; i < req.env_count; i++) { + apr_size_t curlen = strlen(env[i]); + + if ((stat = sock_write(fd, &curlen, sizeof(curlen))) != APR_SUCCESS) { + return stat; + } + + if ((stat = sock_write(fd, env[i], curlen)) != APR_SUCCESS) { + return stat; + } + } + + /* send a minimal notes table */ + if (user) { + if ((stat = sock_write(fd, user, req.mod_userdir_user_len)) != APR_SUCCESS) { + return stat; + } + } + +#if 0 +#ifdef RLIMIT_CPU + if (conf->limit_cpu) { + len = 1; + stat = sock_write(fd, &len, sizeof(int)); + stat = sock_write(fd, conf->limit_cpu, sizeof(struct rlimit)); + } + else { + len = 0; + stat = sock_write(fd, &len, sizeof(int)); + } +#endif + +#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + if (conf->limit_mem) { + len = 1; + stat = sock_write(fd, &len, sizeof(int)); + stat = sock_write(fd, conf->limit_mem, sizeof(struct rlimit)); + } + else { + len = 0; + stat = sock_write(fd, &len, sizeof(int)); + } +#endif + +#ifdef RLIMIT_NPROC + if (conf->limit_nproc) { + len = 1; + stat = sock_write(fd, &len, sizeof(int)); + stat = sock_write(fd, conf->limit_nproc, sizeof(struct rlimit)); + } + else { + len = 0; + stat = sock_write(fd, &len, sizeof(int)); + } +#endif +#endif + return APR_SUCCESS; +} + +static void daemon_signal_handler(int sig) +{ + if (sig == SIGHUP) { + ++daemon_should_exit; + } +} + +static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, + const char *description) +{ + request_rec *r; + void *vr; + + apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); + r = vr; + + /* sure we got r, but don't call ap_log_rerror() because we don't + * have r->headers_in and possibly other storage referenced by + * ap_log_rerror() + */ + ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, "%s", description); +} + +static int cgid_server(void *data) +{ + struct sockaddr_un unix_addr; + int sd, sd2, rc; + mode_t omask; + apr_socklen_t len; + apr_pool_t *ptrans; + server_rec *main_server = data; + apr_hash_t *script_hash = apr_hash_make(pcgi); + + apr_pool_create(&ptrans, pcgi); + + apr_signal(SIGCHLD, SIG_IGN); + apr_signal(SIGHUP, daemon_signal_handler); + + if (unlink(sockname) < 0 && errno != ENOENT) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "Couldn't unlink unix domain socket %s", + sockname); + /* just a warning; don't bail out */ + } + + if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "Couldn't create unix domain socket"); + return errno; + } + + memset(&unix_addr, 0, sizeof(unix_addr)); + unix_addr.sun_family = AF_UNIX; + strcpy(unix_addr.sun_path, sockname); + + omask = umask(0077); /* so that only Apache can use socket */ + rc = bind(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)); + umask(omask); /* can't fail, so can't clobber errno */ + if (rc < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "Couldn't bind unix domain socket %s", + sockname); + return errno; + } + + if (listen(sd, DEFAULT_CGID_LISTENBACKLOG) < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "Couldn't listen on unix domain socket"); + return errno; + } + + if (!geteuid()) { + if (chown(sockname, unixd_config.user_id, -1) < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "Couldn't change owner of unix domain socket %s", + sockname); + return errno; + } + } + + unixd_setup_child(); /* if running as root, switch to configured user/group */ + + while (!daemon_should_exit) { + int errfileno = STDERR_FILENO; + char *argv0; + char **env; + const char * const *argv; + apr_int32_t in_pipe; + apr_int32_t out_pipe; + apr_int32_t err_pipe; + apr_cmdtype_e cmd_type; + request_rec *r; + apr_procattr_t *procattr = NULL; + apr_proc_t *procnew = NULL; + apr_file_t *inout; + cgid_req_t cgid_req; + apr_status_t stat; + + apr_pool_clear(ptrans); + + len = sizeof(unix_addr); + sd2 = accept(sd, (struct sockaddr *)&unix_addr, &len); + if (sd2 < 0) { +#if defined(ENETDOWN) + if (errno == ENETDOWN) { + /* The network has been shut down, no need to continue. Die gracefully */ + ++daemon_should_exit; + } +#endif + if (errno != EINTR) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, + (server_rec *)data, + "Error accepting on cgid socket"); + } + continue; + } + + r = apr_pcalloc(ptrans, sizeof(request_rec)); + procnew = apr_pcalloc(ptrans, sizeof(*procnew)); + r->pool = ptrans; + stat = get_req(sd2, r, &argv0, &env, &cgid_req); + if (stat != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, stat, + main_server, + "Error reading request on cgid socket"); + close(sd2); + continue; + } + + if (cgid_req.ppid != parent_pid) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, main_server, + "CGI request received from wrong server instance; " + "see ScriptSock directive"); + close(sd2); + continue; + } + + if (cgid_req.req_type == GETPID_REQ) { + pid_t pid; + + pid = (pid_t)apr_hash_get(script_hash, &cgid_req.conn_id, sizeof(cgid_req.conn_id)); + if (write(sd2, &pid, sizeof(pid)) != sizeof(pid)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + main_server, + "Error writing pid %" APR_PID_T_FMT " to handler", pid); + } + close(sd2); + continue; + } + + apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool); + apr_os_file_put(&inout, &sd2, 0, r->pool); + + if (cgid_req.req_type == SSI_REQ) { + in_pipe = APR_NO_PIPE; + out_pipe = APR_FULL_BLOCK; + err_pipe = APR_NO_PIPE; + cmd_type = APR_SHELLCMD; + } + else { + in_pipe = APR_CHILD_BLOCK; + out_pipe = APR_CHILD_BLOCK; + err_pipe = APR_CHILD_BLOCK; + cmd_type = APR_PROGRAM; + } + + if (((rc = apr_procattr_create(&procattr, ptrans)) != APR_SUCCESS) || + ((cgid_req.req_type == CGI_REQ) && + (((rc = apr_procattr_io_set(procattr, + in_pipe, + out_pipe, + err_pipe)) != APR_SUCCESS) || + /* XXX apr_procattr_child_*_set() is creating an unnecessary + * pipe between this process and the child being created... + * It is cleaned up with the temporary pool for this request. + */ + ((rc = apr_procattr_child_err_set(procattr, r->server->error_log, NULL)) != APR_SUCCESS) || + ((rc = apr_procattr_child_in_set(procattr, inout, NULL)) != APR_SUCCESS))) || + ((rc = apr_procattr_child_out_set(procattr, inout, NULL)) != APR_SUCCESS) || + ((rc = apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(r->pool, r->filename))) != APR_SUCCESS) || + ((rc = apr_procattr_cmdtype_set(procattr, cmd_type)) != APR_SUCCESS) || + ((rc = apr_procattr_child_errfn_set(procattr, cgid_child_errfn)) != APR_SUCCESS)) { + /* Something bad happened, tell the world. + * ap_log_rerror() won't work because the header table used by + * ap_log_rerror() hasn't been replicated in the phony r + */ + ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, + "couldn't set child process attributes: %s", r->filename); + } + else { + apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); + + argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args); + + /* We want to close sd2 for the new CGI process too. + * If it is left open it'll make ap_pass_brigade() block + * waiting for EOF if CGI forked something running long. + * close(sd2) here should be okay, as CGI channel + * is already dup()ed by apr_procattr_child_{in,out}_set() + * above. + */ + close(sd2); + + rc = ap_os_create_privileged_process(r, procnew, argv0, argv, + (const char * const *)env, + procattr, ptrans); + + if (rc != APR_SUCCESS) { + /* Bad things happened. Everyone should have cleaned up. + * ap_log_rerror() won't work because the header table used by + * ap_log_rerror() hasn't been replicated in the phony r + */ + ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, + "couldn't create child process: %d: %s", rc, + apr_filepath_name_get(r->filename)); + } + else { + /* We don't want to leak storage for the key, so only allocate + * a key if the key doesn't exist yet in the hash; there are + * only a limited number of possible keys (one for each + * possible thread in the server), so we can allocate a copy + * of the key the first time a thread has a cgid request. + * Note that apr_hash_set() only uses the storage passed in + * for the key if it is adding the key to the hash for the + * first time; new key storage isn't needed for replacing the + * existing value of a key. + */ + void *key; + + if (apr_hash_get(script_hash, &cgid_req.conn_id, sizeof(cgid_req.conn_id))) { + key = &cgid_req.conn_id; + } + else { + key = apr_pcalloc(pcgi, sizeof(cgid_req.conn_id)); + memcpy(key, &cgid_req.conn_id, sizeof(cgid_req.conn_id)); + } + apr_hash_set(script_hash, key, sizeof(cgid_req.conn_id), + (void *)procnew->pid); + } + } + } + return -1; +} + +static int cgid_start(apr_pool_t *p, server_rec *main_server, + apr_proc_t *procnew) +{ + + daemon_should_exit = 0; /* clear setting from previous generation */ + if ((daemon_pid = fork()) < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, + "mod_cgid: Couldn't spawn cgid daemon process"); + return DECLINED; + } + else if (daemon_pid == 0) { + if (pcgi == NULL) { + apr_pool_create(&pcgi, p); + } + cgid_server(main_server); + exit(-1); + } + procnew->pid = daemon_pid; + procnew->err = procnew->in = procnew->out = NULL; + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); +#if APR_HAS_OTHER_CHILD + apr_proc_other_child_register(procnew, cgid_maint, procnew, NULL, p); +#endif + return OK; +} + +static int cgid_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + sockname = DEFAULT_SOCKET; + return OK; +} + +static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, + server_rec *main_server) +{ + apr_proc_t *procnew = NULL; + int first_time = 0; + const char *userdata_key = "cgid_init"; + module **m; + int ret = OK; + void *data; + + root_server = main_server; + root_pool = p; + + apr_pool_userdata_get(&data, userdata_key, main_server->process->pool); + if (!data) { + first_time = 1; + procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew)); + procnew->pid = -1; + procnew->err = procnew->in = procnew->out = NULL; + apr_pool_userdata_set((const void *)procnew, userdata_key, + apr_pool_cleanup_null, main_server->process->pool); + } + else { + procnew = data; + } + + if (!first_time) { + total_modules = 0; + for (m = ap_preloaded_modules; *m != NULL; m++) + total_modules++; + + parent_pid = getpid(); + sockname = ap_server_root_relative(p, sockname); + ret = cgid_start(p, main_server, procnew); + if (ret != OK ) { + return ret; + } + cgid_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); + cgid_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); + cgid_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); + + if ((cgid_pfn_reg_with_ssi) && (cgid_pfn_gtv) && (cgid_pfn_ps)) { + /* Required by mod_include filter. This is how mod_cgid registers + * with mod_include to provide processing of the exec directive. + */ + cgid_pfn_reg_with_ssi("exec", handle_exec); + } + } + return ret; +} + +static void *create_cgid_config(apr_pool_t *p, server_rec *s) +{ + cgid_server_conf *c = + (cgid_server_conf *) apr_pcalloc(p, sizeof(cgid_server_conf)); + + c->logname = NULL; + c->logbytes = DEFAULT_LOGBYTES; + c->bufbytes = DEFAULT_BUFBYTES; + return c; +} + +static void *merge_cgid_config(apr_pool_t *p, void *basev, void *overridesv) +{ + cgid_server_conf *base = (cgid_server_conf *) basev, *overrides = (cgid_server_conf *) overridesv; + + return overrides->logname ? overrides : base; +} + +static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + cgid_server_conf *conf = ap_get_module_config(s->module_config, + &cgid_module); + + conf->logname = ap_server_root_relative(cmd->pool, arg); + + if (!conf->logname) { + return apr_pstrcat(cmd->pool, "Invalid ScriptLog path ", + arg, NULL); + } + return NULL; +} + +static const char *set_scriptlog_length(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + cgid_server_conf *conf = ap_get_module_config(s->module_config, + &cgid_module); + + conf->logbytes = atol(arg); + return NULL; +} + +static const char *set_scriptlog_buffer(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + cgid_server_conf *conf = ap_get_module_config(s->module_config, + &cgid_module); + + conf->bufbytes = atoi(arg); + return NULL; +} + +static const char *set_script_socket(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + sockname = ap_server_root_relative(cmd->pool, arg); + + if (!sockname) { + return apr_pstrcat(cmd->pool, "Invalid Scriptsock path", + arg, NULL); + } + + return NULL; +} + +static const command_rec cgid_cmds[] = +{ + AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, + "the name of a log for script debugging info"), + AP_INIT_TAKE1("ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF, + "the maximum length (in bytes) of the script debug log"), + AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, + "the maximum size (in bytes) to record of a POST request"), + AP_INIT_TAKE1("Scriptsock", set_script_socket, NULL, RSRC_CONF, + "the name of the socket to use for communication with " + "the cgi daemon."), + {NULL} +}; + +static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, + apr_status_t rv, char *error) +{ + apr_file_t *f = NULL; + struct stat finfo; + char time_str[APR_CTIME_LEN]; + int log_flags = rv ? APLOG_ERR : APLOG_ERR; + + ap_log_rerror(APLOG_MARK, log_flags, rv, r, + "%s: %s", error, r->filename); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((stat(conf->logname, &finfo) == 0) + && (finfo.st_size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgid-bin */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_printf(f, "%%error\n%s\n", error); + + apr_file_close(f); + return ret; +} + +static int log_script(request_rec *r, cgid_server_conf * conf, int ret, + char *dbuf, const char *sbuf, apr_bucket_brigade *bb, + apr_file_t *script_err) +{ + const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); + const apr_table_entry_t *hdrs = (apr_table_entry_t *) hdrs_arr->elts; + char argsbuffer[HUGE_STRING_LEN]; + apr_file_t *f = NULL; + apr_bucket *e; + const char *buf; + apr_size_t len; + apr_status_t rv; + int first; + int i; + struct stat finfo; + char time_str[APR_CTIME_LEN]; + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((stat(conf->logname, &finfo) == 0) + && (finfo.st_size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { + /* Soak up script output */ + discard_script_output(bb); + if (script_err) { + while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err) == APR_SUCCESS) + continue; + } + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgid-bin" */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_puts("%request\n", f); + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + if ((r->method_number == M_POST || r->method_number == M_PUT) + && *dbuf) { + apr_file_printf(f, "\n%s\n", dbuf); + } + + apr_file_puts("%response\n", f); + hdrs_arr = apr_table_elts(r->err_headers_out); + hdrs = (const apr_table_entry_t *) hdrs_arr->elts; + + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + apr_file_printf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + + if (sbuf && *sbuf) + apr_file_printf(f, "%s\n", sbuf); + + first = 1; + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + break; + } + rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS || (len == 0)) { + break; + } + if (first) { + apr_file_puts("%stdout\n", f); + first = 0; + } + apr_file_write(f, buf, &len); + apr_file_puts("\n", f); + } + + if (script_err) { + if (apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err) == APR_SUCCESS) { + apr_file_puts("%stderr\n", f); + apr_file_puts(argsbuffer, f); + while (apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err) == APR_SUCCESS) + apr_file_puts(argsbuffer, f); + apr_file_puts("\n", f); + } + } + + if (script_err) { + apr_file_close(script_err); + } + + apr_file_close(f); + return ret; +} + +static apr_status_t close_unix_socket(void *thefd) +{ + int fd = (int)thefd; + + return close(fd); +} + +static int connect_to_daemon(int *sdptr, request_rec *r, + cgid_server_conf *conf) +{ + struct sockaddr_un unix_addr; + int sd; + int connect_tries; + apr_interval_time_t sliding_timer; + + memset(&unix_addr, 0, sizeof(unix_addr)); + unix_addr.sun_family = AF_UNIX; + strcpy(unix_addr.sun_path, sockname); + + connect_tries = 0; + sliding_timer = 100000; /* 100 milliseconds */ + while (1) { + ++connect_tries; + if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, + "unable to create socket to cgi daemon"); + } + if (connect(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) < 0) { + if (errno == ECONNREFUSED && connect_tries < DEFAULT_CONNECT_ATTEMPTS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, + "connect #%d to cgi daemon failed, sleeping before retry", + connect_tries); + close(sd); + apr_sleep(sliding_timer); + if (sliding_timer < apr_time_from_sec(2)) { + sliding_timer *= 2; + } + } + else { + close(sd); + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, + "unable to connect to cgi daemon after multiple tries"); + } + } + else { + apr_pool_cleanup_register(r->pool, (void *)sd, close_unix_socket, + apr_pool_cleanup_null); + break; /* we got connected! */ + } + /* gotta try again, but make sure the cgid daemon is still around */ + if (kill(daemon_pid, 0) != 0) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, + "cgid daemon is gone; is Apache terminating?"); + } + } + *sdptr = sd; + return OK; +} + +static void discard_script_output(apr_bucket_brigade *bb) +{ + apr_bucket *e; + const char *buf; + apr_size_t len; + apr_status_t rv; + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + break; + } + rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + break; + } + } +} + +/**************************************************************** + * + * Actual cgid handling... + */ + +struct cleanup_script_info { + request_rec *r; + unsigned long conn_id; + cgid_server_conf *conf; +}; + +static apr_status_t dead_yet(pid_t pid, apr_interval_time_t max_wait) +{ + apr_interval_time_t interval = 10000; /* 10 ms */ + apr_interval_time_t total = 0; + + do { +#ifdef _AIX + /* On AIX, for processes like mod_cgid's script children where + * SIGCHLD is ignored, kill(pid,0) returns success for up to + * one second after the script child exits, based on when a + * daemon runs to clean up unnecessary process table entries. + * getpgid() can report the proper info (-1/ESRCH) immediately. + */ + if (getpgid(pid) < 0) { +#else + if (kill(pid, 0) < 0) { +#endif + return APR_SUCCESS; + } + apr_sleep(interval); + total = total + interval; + if (interval < 500000) { + interval *= 2; + } + } while (total < max_wait); + return APR_EGENERAL; +} + +static apr_status_t cleanup_nonchild_process(request_rec *r, pid_t pid) +{ + kill(pid, SIGTERM); /* in case it isn't dead yet */ + if (dead_yet(pid, apr_time_from_sec(3)) == APR_SUCCESS) { + return APR_SUCCESS; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "CGI process %" APR_PID_T_FMT " didn't exit, sending SIGKILL", + pid); + kill(pid, SIGKILL); + if (dead_yet(pid, apr_time_from_sec(3)) == APR_SUCCESS) { + return APR_SUCCESS; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "CGI process %" APR_PID_T_FMT " didn't exit, sending SIGKILL again", + pid); + kill(pid, SIGKILL); + + return APR_EGENERAL; +} + +static apr_status_t cleanup_script(void *vptr) +{ + struct cleanup_script_info *info = vptr; + int sd; + int rc; + cgid_req_t req = {0}; + pid_t pid; + apr_status_t stat; + + rc = connect_to_daemon(&sd, info->r, info->conf); + if (rc != OK) { + return APR_EGENERAL; + } + + /* we got a socket, and there is already a cleanup registered for it */ + + req.req_type = GETPID_REQ; + req.ppid = parent_pid; + req.conn_id = info->r->connection->id; + + stat = sock_write(sd, &req, sizeof(req)); + if (stat != APR_SUCCESS) { + return stat; + } + + /* wait for pid of script */ + stat = sock_read(sd, &pid, sizeof(pid)); + if (stat != APR_SUCCESS) { + return stat; + } + + if (pid == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, info->r, + "daemon couldn't find CGI process for connection %lu", + info->conn_id); + return APR_EGENERAL; + } + return cleanup_nonchild_process(info->r, pid); +} + +static int cgid_handler(request_rec *r) +{ + conn_rec *c = r->connection; + int retval, nph, dbpos = 0; + char *argv0, *dbuf = NULL; + apr_bucket_brigade *bb; + apr_bucket *b; + cgid_server_conf *conf; + int is_included; + int seen_eos, child_stopped_reading; + int sd; + char **env; + apr_file_t *tempsock; + struct cleanup_script_info *info; + apr_status_t rv; + + if (strcmp(r->handler,CGI_MAGIC_TYPE) && strcmp(r->handler,"cgi-script")) + return DECLINED; + + if (r->method_number == M_OPTIONS) { + /* 99 out of 100 cgid scripts, this is all they support */ + r->allowed |= (AP_METHOD_BIT << M_GET); + r->allowed |= (AP_METHOD_BIT << M_POST); + return DECLINED; + } + + conf = ap_get_module_config(r->server->module_config, &cgid_module); + is_included = !strcmp(r->protocol, "INCLUDED"); + + if ((argv0 = strrchr(r->filename, '/')) != NULL) + argv0++; + else + argv0 = r->filename; + + nph = !(strncmp(argv0, "nph-", 4)); + + if ((argv0 = strrchr(r->filename, '/')) != NULL) + argv0++; + else + argv0 = r->filename; + + if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "Options ExecCGI is off in this directory"); + if (nph && is_included) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "attempt to include NPH CGI script"); + +#if defined(OS2) || defined(WIN32) +#error mod_cgid does not work on this platform. If you teach it to, look +#error at mod_cgi.c for required code in this path. +#else + if (r->finfo.filetype == 0) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, + "script not found or unable to stat"); +#endif + if (r->finfo.filetype == APR_DIR) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "attempt to invoke directory as script"); + + if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) && + r->path_info && *r->path_info) + { + /* default to accept */ + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, + "AcceptPathInfo off disallows user's path"); + } +/* + if (!ap_suexec_enabled) { + if (!ap_can_exec(&r->finfo)) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, + "file permissions deny server execution"); + } +*/ + ap_add_common_vars(r); + ap_add_cgi_vars(r); + env = ap_create_environment(r->pool, r->subprocess_env); + + if ((retval = connect_to_daemon(&sd, r, conf)) != OK) { + return retval; + } + + rv = send_req(sd, r, argv0, env, CGI_REQ); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "write to cgi daemon process"); + } + + info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); + info->r = r; + info->conn_id = r->connection->id; + info->conf = conf; + apr_pool_cleanup_register(r->pool, info, + cleanup_script, + apr_pool_cleanup_null); + /* We are putting the socket discriptor into an apr_file_t so that we can + * use a pipe bucket to send the data to the client. APR will create + * a cleanup for the apr_file_t which will close the socket, so we'll + * get rid of the cleanup we registered when we created the socket. + */ + + apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); + apr_pool_cleanup_kill(r->pool, (void *)sd, close_unix_socket); + + if ((argv0 = strrchr(r->filename, '/')) != NULL) + argv0++; + else + argv0 = r->filename; + + /* Transfer any put/post args, CERN style... + * Note that we already ignore SIGPIPE in the core server. + */ + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + seen_eos = 0; + child_stopped_reading = 0; + if (conf->logname) { + dbuf = apr_palloc(r->pool, conf->bufbytes + 1); + dbpos = 0; + } + do { + apr_bucket *bucket; + + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, HUGE_STRING_LEN); + + if (rv != APR_SUCCESS) { + return rv; + } + + for (bucket = APR_BRIGADE_FIRST(bb); + bucket != APR_BRIGADE_SENTINEL(bb); + bucket = APR_BUCKET_NEXT(bucket)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + /* We can't do much with this. */ + if (APR_BUCKET_IS_FLUSH(bucket)) { + continue; + } + + /* If the child stopped, we still must read to EOS. */ + if (child_stopped_reading) { + continue; + } + + /* read */ + apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + + if (conf->logname && dbpos < conf->bufbytes) { + int cursize; + + if ((dbpos + len) > conf->bufbytes) { + cursize = conf->bufbytes - dbpos; + } + else { + cursize = len; + } + memcpy(dbuf + dbpos, data, cursize); + dbpos += cursize; + } + + /* Keep writing data to the child until done or too much time + * elapses with no progress or an error occurs. + */ + rv = apr_file_write_full(tempsock, data, len, NULL); + + if (rv != APR_SUCCESS) { + /* silly script stopped reading, soak up remaining message */ + child_stopped_reading = 1; + } + } + apr_brigade_cleanup(bb); + } + while (!seen_eos); + + if (conf->logname) { + dbuf[dbpos] = '\0'; + } + + /* we're done writing, or maybe we didn't write at all; + * force EOF on child's stdin so that the cgi detects end (or + * absence) of data + */ + shutdown(sd, 1); + + /* Handle script return... */ + if (!nph) { + const char *location; + char sbuf[MAX_STRING_LEN]; + int ret; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) { + return log_script(r, conf, ret, dbuf, sbuf, bb, NULL); + } + + location = apr_table_get(r->headers_out, "Location"); + + if (location && location[0] == '/' && r->status == 200) { + + /* Soak up all the script output */ + discard_script_output(bb); + apr_brigade_destroy(bb); + /* This redirect needs to be a GET no matter what the original + * method was. + */ + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + + /* We already read the message body (if any), so don't allow + * the redirected request to think it has one. We can ignore + * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. + */ + apr_table_unset(r->headers_in, "Content-Length"); + + ap_internal_redirect_handler(location, r); + return OK; + } + else if (location && r->status == 200) { + /* XX Note that if a script wants to produce its own Redirect + * body, it now has to explicitly *say* "Status: 302" + */ + discard_script_output(bb); + apr_brigade_destroy(bb); + return HTTP_MOVED_TEMPORARILY; + } + + ap_pass_brigade(r->output_filters, bb); + } + + if (nph) { + struct ap_filter_t *cur; + + /* get rid of all filters up through protocol... since we + * haven't parsed off the headers, there is no way they can + * work + */ + + cur = r->proto_output_filters; + while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { + cur = cur->next; + } + r->output_filters = r->proto_output_filters = cur; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(r->output_filters, bb); + } + + return OK; /* NOT r->status, even if it has changed. */ +} + + + + +/*============================================================================ + *============================================================================ + * This is the beginning of the cgi filter code moved from mod_include. This + * is the code required to handle the "exec" SSI directive. + *============================================================================ + *============================================================================*/ +static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, char *s) +{ + request_rec *r = f->r; + request_rec *rr = ap_sub_req_lookup_uri(s, r, f->next); + int rr_status; + + if (rr->status != HTTP_OK) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + + /* No hardwired path info or query allowed */ + if ((rr->path_info && rr->path_info[0]) || rr->args) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + if (rr->finfo.filetype != APR_REG) { + ap_destroy_sub_req(rr); + return APR_EGENERAL; + } + + /* Script gets parameters of the *document*, for back compatibility */ + rr->path_info = r->path_info; /* hard to get right; see mod_cgi.c */ + rr->args = r->args; + + /* Force sub_req to be treated as a CGI request, even if ordinary + * typing rules would have called it something else. + */ + ap_set_content_type(rr, CGI_MAGIC_TYPE); + + /* Run it. */ + rr_status = ap_run_sub_req(rr); + if (ap_is_HTTP_REDIRECT(rr_status)) { + const char *location = apr_table_get(rr->headers_out, "Location"); + + if (location) { + char *buffer; + + location = ap_escape_html(rr->pool, location); + buffer = apr_pstrcat(ctx->pool, "<a href=\"", location, "\">", + location, "</a>", NULL); + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(buffer, + strlen(buffer), ctx->pool, + f->c->bucket_alloc)); + } + } + + ap_destroy_sub_req(rr); + + return APR_SUCCESS; +} + +/* This is the special environment used for running the "exec cmd=" + * variety of SSI directives. + */ +static void add_ssi_vars(request_rec *r) +{ + apr_table_t *e = r->subprocess_env; + + if (r->path_info && r->path_info[0] != '\0') { + request_rec *pa_req; + + apr_table_setn(e, "PATH_INFO", ap_escape_shell_cmd(r->pool, r->path_info)); + + pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r, NULL); + if (pa_req->filename) { + apr_table_setn(e, "PATH_TRANSLATED", + apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info, NULL)); + } + ap_destroy_sub_req(pa_req); + } + + if (r->args) { + char *arg_copy = apr_pstrdup(r->pool, r->args); + + apr_table_setn(e, "QUERY_STRING", r->args); + ap_unescape_url(arg_copy); + apr_table_setn(e, "QUERY_STRING_UNESCAPED", ap_escape_shell_cmd(r->pool, arg_copy)); + } +} + +static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, char *command) +{ + char **env; + int sd; + int retval; + apr_file_t *tempsock = NULL; + request_rec *r = f->r; + cgid_server_conf *conf = ap_get_module_config(r->server->module_config, + &cgid_module); + struct cleanup_script_info *info; + + add_ssi_vars(r); + env = ap_create_environment(r->pool, r->subprocess_env); + + if ((retval = connect_to_daemon(&sd, r, conf)) != OK) { + return retval; + } + + send_req(sd, r, command, env, SSI_REQ); + + info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); + info->r = r; + info->conn_id = r->connection->id; + info->conf = conf; + /* for this type of request, the script is invoked through an + * intermediate shell process... cleanup_script is only able + * to knock out the shell process, not the actual script + */ + apr_pool_cleanup_register(r->pool, info, + cleanup_script, + apr_pool_cleanup_null); + + /* We are putting the socket discriptor into an apr_file_t so that we can + * use a pipe bucket to send the data to the client. APR will create + * a cleanup for the apr_file_t which will close the socket, so we'll + * get rid of the cleanup we registered when we created the socket. + */ + apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); + apr_pool_cleanup_kill(r->pool, (void *)sd, close_unix_socket); + + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(tempsock, + f->c->bucket_alloc)); + ctx->flush_now = 1; + + return APR_SUCCESS; +} + +static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *tag_val = NULL; + request_rec *r = f->r; + char *file = r->filename; + char parsed_string[MAX_STRING_LEN]; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, "missing argument for exec element in %s", + r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (ctx->flags & SSI_FLAG_NO_EXEC) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "exec used but not allowed " + "in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + cgid_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "cmd")) { + apr_status_t rv; + + cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_LEAVE_NAME); + + rv = include_cmd(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "execution failure for parameter \"%s\" " + "to tag exec in file %s", tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else if (!strcmp(tag, "cgi")) { + apr_status_t rv; + + cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_DROP_NAME); + + rv = include_cgi(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "invalid CGI ref " + "\"%s\" in %s", tag_val, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter " + "\"%s\" to tag exec in %s", tag, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} +/*============================================================================ + *============================================================================ + * This is the end of the cgi filter code moved from mod_include. + *============================================================================ + *============================================================================*/ + + +static void register_hook(apr_pool_t *p) +{ + static const char * const aszPre[] = { "mod_include.c", NULL }; + + ap_hook_pre_config(cgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(cgid_init, aszPre, NULL, APR_HOOK_MIDDLE); + ap_hook_handler(cgid_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA cgid_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_cgid_config, /* server config */ + merge_cgid_config, /* merge server config */ + cgid_cmds, /* command table */ + register_hook /* register_handlers */ +}; + diff --git a/trunk/modules/generators/mod_cgid.exp b/trunk/modules/generators/mod_cgid.exp new file mode 100644 index 0000000000..5f10d486da --- /dev/null +++ b/trunk/modules/generators/mod_cgid.exp @@ -0,0 +1 @@ +cgid_module diff --git a/trunk/modules/generators/mod_info.c b/trunk/modules/generators/mod_info.c new file mode 100644 index 0000000000..a944c380b9 --- /dev/null +++ b/trunk/modules/generators/mod_info.c @@ -0,0 +1,811 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Info Module. Display configuration information for the server and + * all included modules. + * + * <Location /server-info> + * SetHandler server-info + * </Location> + * + * GET /server-info - Returns full configuration page for server and all modules + * GET /server-info?server - Returns server configuration only + * GET /server-info?module_name - Returns configuration for a single module + * GET /server-info?list - Returns quick list of included modules + * GET /server-info?config - Returns full configuration + * GET /server-info?hooks - Returns a listing of the modules active for each hook + * + * Original Author: + * Rasmus Lerdorf <rasmus vex.net>, May 1996 + * + * Modified By: + * Lou Langholtz <ldl usi.utah.edu>, July 1997 + * + * Apache 2.0 Port: + * Ryan Morgan <rmorgan covalent.net>, August 2000 + * + */ + + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "http_connection.h" +#include "http_request.h" +#include "util_script.h" +#include "ap_mpm.h" + +typedef struct +{ + const char *name; /* matching module name */ + const char *info; /* additional info */ +} info_entry; + +typedef struct +{ + apr_array_header_t *more_info; +} info_svr_conf; + +module AP_MODULE_DECLARE_DATA info_module; + +static void *create_info_config(apr_pool_t * p, server_rec * s) +{ + info_svr_conf *conf = + (info_svr_conf *) apr_pcalloc(p, sizeof(info_svr_conf)); + + conf->more_info = apr_array_make(p, 20, sizeof(info_entry)); + return conf; +} + +static void *merge_info_config(apr_pool_t * p, void *basev, void *overridesv) +{ + info_svr_conf *new = + (info_svr_conf *) apr_pcalloc(p, sizeof(info_svr_conf)); + info_svr_conf *base = (info_svr_conf *) basev; + info_svr_conf *overrides = (info_svr_conf *) overridesv; + + new->more_info = + apr_array_append(p, overrides->more_info, base->more_info); + return new; +} + +static void put_int_flush_right(request_rec * r, int i, int field) +{ + if (field > 1 || i > 9) + put_int_flush_right(r, i / 10, field - 1); + if (i) + ap_rputc('0' + i % 10, r); + else + ap_rputs(" ", r); +} + +static void mod_info_indent(request_rec * r, int nest, + const char *thisfn, int linenum) +{ + int i; + const char *prevfn = + ap_get_module_config(r->request_config, &info_module); + if (thisfn == NULL) + thisfn = "*UNKNOWN*"; + if (prevfn == NULL || 0 != strcmp(prevfn, thisfn)) { + thisfn = ap_escape_html(r->pool, thisfn); + ap_rprintf(r, "<dd><tt><strong>In file: %s</strong></tt></dd>\n", + thisfn); + ap_set_module_config(r->request_config, &info_module, + (void *) thisfn); + } + + ap_rputs("<dd><tt>", r); + put_int_flush_right(r, linenum > 0 ? linenum : 0, 4); + ap_rputs(": ", r); + + for (i = 1; i <= nest; ++i) { + ap_rputs("  ", r); + } +} + +static void mod_info_show_cmd(request_rec * r, const ap_directive_t * dir, + int nest) +{ + mod_info_indent(r, nest, dir->filename, dir->line_num); + ap_rprintf(r, "%s <i>%s</i></tt></dd>\n", + ap_escape_html(r->pool, dir->directive), + ap_escape_html(r->pool, dir->args)); +} + +static void mod_info_show_open(request_rec * r, const ap_directive_t * dir, + int nest) +{ + mod_info_indent(r, nest, dir->filename, dir->line_num); + ap_rprintf(r, "%s %s</tt></dd>\n", + ap_escape_html(r->pool, dir->directive), + ap_escape_html(r->pool, dir->args)); +} + +static void mod_info_show_close(request_rec * r, const ap_directive_t * dir, + int nest) +{ + const char *dirname = dir->directive; + mod_info_indent(r, nest, dir->filename, 0); + if (*dirname == '<') { + ap_rprintf(r, "</%s></tt></dd>", + ap_escape_html(r->pool, dirname + 1)); + } + else { + ap_rprintf(r, "/%s</tt></dd>", ap_escape_html(r->pool, dirname)); + } +} + +static int mod_info_has_cmd(const command_rec * cmds, ap_directive_t * dir) +{ + const command_rec *cmd; + if (cmds == NULL) + return 1; + for (cmd = cmds; cmd->name; ++cmd) { + if (strcasecmp(cmd->name, dir->directive) == 0) + return 1; + } + return 0; +} + +static void mod_info_show_parents(request_rec * r, ap_directive_t * node, + int from, int to) +{ + if (from < to) + mod_info_show_parents(r, node->parent, from, to - 1); + mod_info_show_open(r, node, to); +} + +static int mod_info_module_cmds(request_rec * r, const command_rec * cmds, + ap_directive_t * node, int from, int level) +{ + int shown = from; + ap_directive_t *dir; + if (level == 0) + ap_set_module_config(r->request_config, &info_module, NULL); + for (dir = node; dir; dir = dir->next) { + if (dir->first_child != NULL) { + if (level < mod_info_module_cmds(r, cmds, dir->first_child, + shown, level + 1)) { + shown = level; + mod_info_show_close(r, dir, level); + } + } + else if (mod_info_has_cmd(cmds, dir)) { + if (shown < level) { + mod_info_show_parents(r, dir->parent, shown, level - 1); + shown = level; + } + mod_info_show_cmd(r, dir, level); + } + } + return shown; +} + +typedef struct +{ /*XXX: should get something from apr_hooks.h instead */ + void (*pFunc) (void); /* just to get the right size */ + const char *szName; + const char *const *aszPredecessors; + const char *const *aszSuccessors; + int nOrder; +} hook_struct_t; + +/* + * hook_get_t is a pointer to a function that takes void as an argument and + * returns a pointer to an apr_array_header_t. The nasty WIN32 ifdef + * is required to account for the fact that the ap_hook* calls all use + * STDCALL calling convention. + */ +typedef apr_array_header_t *( +#ifdef WIN32 + __stdcall +#endif + * hook_get_t) (void); + +typedef struct +{ + const char *name; + hook_get_t get; +} hook_lookup_t; + +static hook_lookup_t startup_hooks[] = { + {"Pre-Config", ap_hook_get_pre_config}, + {"Test Configuration", ap_hook_get_test_config}, + {"Post Configuration", ap_hook_get_post_config}, + {"Open Logs", ap_hook_get_open_logs}, + {"Child Init", ap_hook_get_child_init}, + {NULL}, +}; + +static hook_lookup_t request_hooks[] = { + {"Pre-Connection", ap_hook_get_pre_connection}, + {"Create Connection", ap_hook_get_create_connection}, + {"Process Connection", ap_hook_get_process_connection}, + {"Create Request", ap_hook_get_create_request}, + {"Post-Read Request", ap_hook_get_post_read_request}, + {"Header Parse", ap_hook_get_header_parser}, + {"HTTP Scheme", ap_hook_get_http_scheme}, + {"Default Port", ap_hook_get_default_port}, + {"Quick Handler", ap_hook_get_quick_handler}, + {"Translate Name", ap_hook_get_translate_name}, + {"Map to Storage", ap_hook_get_map_to_storage}, + {"Check Access", ap_hook_get_access_checker}, + {"Verify User ID", ap_hook_get_check_user_id}, + {"Verify User Access", ap_hook_get_auth_checker}, + {"Check Type", ap_hook_get_type_checker}, + {"Fixups", ap_hook_get_fixups}, + {"Insert Filters", ap_hook_get_insert_filter}, + {"Content Handlers", ap_hook_get_handler}, + {"Logging", ap_hook_get_log_transaction}, + {"Insert Errors", ap_hook_get_insert_error_filter}, + {NULL}, +}; + +static int module_find_hook(module * modp, hook_get_t hook_get) +{ + int i; + apr_array_header_t *hooks = hook_get(); + hook_struct_t *elts; + + if (!hooks) { + return 0; + } + + elts = (hook_struct_t *) hooks->elts; + + for (i = 0; i < hooks->nelts; i++) { + if (strcmp(elts[i].szName, modp->name) == 0) { + return 1; + } + } + + return 0; +} + +static void module_participate(request_rec * r, + module * modp, + hook_lookup_t * lookup, int *comma) +{ + if (module_find_hook(modp, lookup->get)) { + if (*comma) { + ap_rputs(", ", r); + } + ap_rvputs(r, "<tt>", lookup->name, "</tt>", NULL); + *comma = 1; + } +} + +static void module_request_hook_participate(request_rec * r, module * modp) +{ + int i, comma = 0; + + ap_rputs("<dt><strong>Request Phase Participation:</strong>\n", r); + + for (i = 0; request_hooks[i].name; i++) { + module_participate(r, modp, &request_hooks[i], &comma); + } + + if (!comma) { + ap_rputs("<tt> <em>none</em></tt>", r); + } + ap_rputs("</dt>\n", r); +} + +static const char *find_more_info(server_rec * s, const char *module_name) +{ + int i; + info_svr_conf *conf = + (info_svr_conf *) ap_get_module_config(s->module_config, + &info_module); + info_entry *entry = (info_entry *) conf->more_info->elts; + + if (!module_name) { + return 0; + } + for (i = 0; i < conf->more_info->nelts; i++) { + if (!strcmp(module_name, entry->name)) { + return entry->info; + } + entry++; + } + return 0; +} + +static int show_server_settings(request_rec * r) +{ + server_rec *serv = r->server; + int max_daemons, forked, threaded; + + ap_rputs("<h2><a name=\"server\">Server Settings</a></h2>", r); + ap_rprintf(r, + "<dl><dt><strong>Server Version:</strong> " + "<font size=\"+1\"><tt>%s</tt></font></dt>\n", + ap_get_server_version()); + ap_rprintf(r, + "<dt><strong>Server Built:</strong> " + "<font size=\"+1\"><tt>%s</tt></font></dt>\n", + ap_get_server_built()); + ap_rprintf(r, + "<dt><strong>Module Magic Number:</strong> " + "<tt>%d:%d</tt></dt>\n", MODULE_MAGIC_NUMBER_MAJOR, + MODULE_MAGIC_NUMBER_MINOR); + ap_rprintf(r, + "<dt><strong>Hostname/port:</strong> " + "<tt>%s:%u</tt></dt>\n", ap_get_server_name(r), + ap_get_server_port(r)); + ap_rprintf(r, + "<dt><strong>Timeouts:</strong> " + "<tt>connection: %d    " + "keep-alive: %d</tt></dt>", + (int) (apr_time_sec(serv->timeout)), + (int) (apr_time_sec(serv->timeout))); + ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons); + ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded); + ap_mpm_query(AP_MPMQ_IS_FORKED, &forked); + ap_rprintf(r, "<dt><strong>MPM Name:</strong> <tt>%s</tt></dt>\n", + ap_show_mpm()); + ap_rprintf(r, + "<dt><strong>MPM Information:</strong> " + "<tt>Max Daemons: %d Threaded: %s Forked: %s</tt></dt>\n", + max_daemons, threaded ? "yes" : "no", forked ? "yes" : "no"); + ap_rprintf(r, + "<dt><strong>Server Architecture:</strong> " + "<tt>%ld-bit</tt></dt>\n", 8 * (long) sizeof(void *)); + ap_rprintf(r, + "<dt><strong>Server Root:</strong> " + "<tt>%s</tt></dt>\n", ap_server_root); + ap_rprintf(r, + "<dt><strong>Config File:</strong> " + "<tt>%s</tt></dt>\n", ap_conftree->filename); + + ap_rputs("<dt><strong>Server Built With:</strong>\n" + "<tt style=\"white-space: pre;\">\n", r); + + /* TODO: Not all of these defines are getting set like they do in main.c. + * Missing some headers? + */ + +#ifdef BIG_SECURITY_HOLE + ap_rputs(" -D BIG_SECURITY_HOLE\n", r); +#endif + +#ifdef SECURITY_HOLE_PASS_AUTHORIZATION + ap_rputs(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n", r); +#endif + +#ifdef OS + ap_rputs(" -D OS=\"" OS "\"\n", r); +#endif + +#ifdef APACHE_MPM_DIR + ap_rputs(" -D APACHE_MPM_DIR=\"" APACHE_MPM_DIR "\"\n", r); +#endif + +#ifdef HAVE_SHMGET + ap_rputs(" -D HAVE_SHMGET\n", r); +#endif + +#if APR_FILE_BASED_SHM + ap_rputs(" -D APR_FILE_BASED_SHM\n", r); +#endif + +#if APR_HAS_SENDFILE + ap_rputs(" -D APR_HAS_SENDFILE\n", r); +#endif + +#if APR_HAS_MMAP + ap_rputs(" -D APR_HAS_MMAP\n", r); +#endif + +#ifdef NO_WRITEV + ap_rputs(" -D NO_WRITEV\n", r); +#endif + +#ifdef NO_LINGCLOSE + ap_rputs(" -D NO_LINGCLOSE\n", r); +#endif + +#if APR_HAVE_IPV6 + ap_rputs(" -D APR_HAVE_IPV6 (IPv4-mapped addresses ", r); +#ifdef AP_ENABLE_V4_MAPPED + ap_rputs("enabled)\n", r); +#else + ap_rputs("disabled)\n", r); +#endif +#endif + +#if APR_USE_FLOCK_SERIALIZE + ap_rputs(" -D APR_USE_FLOCK_SERIALIZE\n", r); +#endif + +#if APR_USE_SYSVSEM_SERIALIZE + ap_rputs(" -D APR_USE_SYSVSEM_SERIALIZE\n", r); +#endif + +#if APR_USE_POSIXSEM_SERIALIZE + ap_rputs(" -D APR_USE_POSIXSEM_SERIALIZE\n", r); +#endif + +#if APR_USE_FCNTL_SERIALIZE + ap_rputs(" -D APR_USE_FCNTL_SERIALIZE\n", r); +#endif + +#if APR_USE_PROC_PTHREAD_SERIALIZE + ap_rputs(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n", r); +#endif +#if APR_PROCESS_LOCK_IS_GLOBAL + ap_rputs(" -D APR_PROCESS_LOCK_IS_GLOBAL\n", r); +#endif + +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT + ap_rputs(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n", r); +#endif + +#if APR_HAS_OTHER_CHILD + ap_rputs(" -D APR_HAS_OTHER_CHILD\n", r); +#endif + +#ifdef AP_HAVE_RELIABLE_PIPED_LOGS + ap_rputs(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n", r); +#endif + +#ifdef BUFFERED_LOGS + ap_rputs(" -D BUFFERED_LOGS\n", r); +#ifdef PIPE_BUF + ap_rputs(" -D PIPE_BUF=%ld\n", (long) PIPE_BUF, r); +#endif +#endif + +#if APR_CHARSET_EBCDIC + ap_rputs(" -D APR_CHARSET_EBCDIC\n", r); +#endif + +#ifdef NEED_HASHBANG_EMUL + ap_rputs(" -D NEED_HASHBANG_EMUL\n", r); +#endif + +#ifdef SHARED_CORE + ap_rputs(" -D SHARED_CORE\n", r); +#endif + +/* This list displays the compiled in default paths: */ +#ifdef HTTPD_ROOT + ap_rputs(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n", r); +#endif + +#ifdef SUEXEC_BIN + ap_rputs(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n", r); +#endif + +#if defined(SHARED_CORE) && defined(SHARED_CORE_DIR) + ap_rputs(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n", r); +#endif + +#ifdef DEFAULT_PIDLOG + ap_rputs(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n", r); +#endif + +#ifdef DEFAULT_SCOREBOARD + ap_rputs(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n", r); +#endif + +#ifdef DEFAULT_LOCKFILE + ap_rputs(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n", r); +#endif + +#ifdef DEFAULT_ERRORLOG + ap_rputs(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n", r); +#endif + + +#ifdef AP_TYPES_CONFIG_FILE + ap_rputs(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n", r); +#endif + +#ifdef SERVER_CONFIG_FILE + ap_rputs(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n", r); +#endif + ap_rputs("</tt></dt>\n", r); + ap_rputs("</dl><hr />", r); + return 0; +} + +static int dump_a_hook(request_rec * r, hook_get_t hook_get) +{ + int i; + char qs; + hook_struct_t *elts; + apr_array_header_t *hooks = hook_get(); + + if (!hooks) { + return 0; + } + + if (r->args && strcasecmp(r->args, "hooks") == 0) { + qs = '?'; + } + else { + qs = '#'; + } + + elts = (hook_struct_t *) hooks->elts; + + for (i = 0; i < hooks->nelts; i++) { + ap_rprintf(r, + "   %02d <a href=\"%c%s\">%s</a> <br/>", + elts[i].nOrder, qs, elts[i].szName, elts[i].szName); + } + return 0; +} + +static int show_active_hooks(request_rec * r) +{ + int i; + ap_rputs("<h2><a name=\"startup_hooks\">Startup Hooks</a></h2>\n<dl>", r); + + for (i = 0; startup_hooks[i].name; i++) { + ap_rprintf(r, "<dt><strong>%s:</strong>\n <br /><tt>\n", + startup_hooks[i].name); + dump_a_hook(r, startup_hooks[i].get); + ap_rputs("\n </tt>\n</dt>\n", r); + } + + ap_rputs + ("</dl>\n<hr />\n<h2><a name=\"request_hooks\">Request Hooks</a></h2>\n<dl>", + r); + + for (i = 0; request_hooks[i].name; i++) { + ap_rprintf(r, "<dt><strong>%s:</strong>\n <br /><tt>\n", + request_hooks[i].name); + dump_a_hook(r, request_hooks[i].get); + ap_rputs("\n </tt>\n</dt>\n", r); + } + + ap_rputs("</dl>\n<hr />\n", r); + + return 0; +} + +static int display_info(request_rec * r) +{ + module *modp = NULL; + server_rec *serv = r->server; + const char *more_info; + const command_rec *cmd = NULL; + int comma = 0; + + if (strcmp(r->handler, "server-info")) + return DECLINED; + + r->allowed |= (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + ap_set_content_type(r, "text/html"); + + ap_rputs(DOCTYPE_XHTML_1_0T + "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" + "<head>\n" + " <title>Server Information\n" "\n", r); + ap_rputs("

    " + "Apache Server Information

    \n", r); + if (!r->args || strcasecmp(r->args, "list")) { + if (!r->args) { + ap_rputs("
    Subpages:
    ", r); + ap_rputs("Configuration Files, " + "Server Settings, " + "Module List, " + "Active Hooks", r); + ap_rputs("

    ", r); + + ap_rputs("
    Sections:
    ", r); + ap_rputs("Server Settings, " + "Startup Hooks, " + "Request Hooks", r); + ap_rputs("

    ", r); + + ap_rputs("
    Loaded Modules:
    ", r); + /* TODO: Sort by Alpha */ + for (modp = ap_top_module; modp; modp = modp->next) { + ap_rprintf(r, "%s", modp->name, + modp->name); + if (modp->next) { + ap_rputs(", ", r); + } + } + ap_rputs("

    ", r); + } + + if (!r->args || !strcasecmp(r->args, "server")) { + show_server_settings(r); + } + + if (!r->args || !strcasecmp(r->args, "hooks")) { + show_active_hooks(r); + } + + if (r->args && 0 == strcasecmp(r->args, "config")) { + ap_rputs("
    Configuration:\n", r); + mod_info_module_cmds(r, NULL, ap_conftree, 0, 0); + ap_rputs("

    ", r); + } + else { + for (modp = ap_top_module; modp; modp = modp->next) { + if (!r->args || !strcasecmp(modp->name, r->args)) { + ap_rprintf(r, + "
    Module Name: " + "%s
    \n", + modp->name, modp->name, modp->name); + ap_rputs("
    Content handlers: ", r); + + if (module_find_hook(modp, ap_hook_get_handler)) { + ap_rputs(" yes", r); + } + else { + ap_rputs(" none", r); + } + + ap_rputs("
    ", r); + ap_rputs + ("
    Configuration Phase Participation:\n", + r); + if (modp->create_dir_config) { + if (comma) { + ap_rputs(", ", r); + } + ap_rputs("Create Directory Config", r); + comma = 1; + } + if (modp->merge_dir_config) { + if (comma) { + ap_rputs(", ", r); + } + ap_rputs("Merge Directory Configs", r); + comma = 1; + } + if (modp->create_server_config) { + if (comma) { + ap_rputs(", ", r); + } + ap_rputs("Create Server Config", r); + comma = 1; + } + if (modp->merge_server_config) { + if (comma) { + ap_rputs(", ", r); + } + ap_rputs("Merge Server Configs", r); + comma = 1; + } + if (!comma) + ap_rputs(" none", r); + comma = 0; + ap_rputs("
    ", r); + + module_request_hook_participate(r, modp); + + cmd = modp->cmds; + if (cmd) { + ap_rputs + ("
    Module Directives:
    ", + r); + while (cmd) { + if (cmd->name) { + ap_rprintf(r, "
    %s%s - ", + ap_escape_html(r->pool, cmd->name), + cmd->name[0] == '<' ? ">" : ""); + if (cmd->errmsg) { + ap_rputs(cmd->errmsg, r); + } + ap_rputs("
    \n", r); + } + else { + break; + } + cmd++; + } + ap_rputs + ("
    Current Configuration:
    \n", + r); + mod_info_module_cmds(r, modp->cmds, ap_conftree, 0, + 0); + } + else { + ap_rputs + ("
    Module Directives: none
    ", + r); + } + more_info = find_more_info(serv, modp->name); + if (more_info) { + ap_rputs + ("
    Additional Information:\n
    ", + r); + ap_rputs(more_info, r); + ap_rputs("
    ", r); + } + ap_rputs("

    \n", r); + if (r->args) { + break; + } + } + } + if (!modp && r->args && strcasecmp(r->args, "server")) { + ap_rputs("

    No such module

    \n", r); + } + } + } + else { + ap_rputs("
    Server Module List
    ", r); + for (modp = ap_top_module; modp; modp = modp->next) { + ap_rputs("
    ", r); + ap_rputs(modp->name, r); + ap_rputs("
    ", r); + } + ap_rputs("

    ", r); + } + ap_rputs(ap_psignature("", r), r); + ap_rputs("\n", r); + /* Done, turn off timeout, close file and return */ + return 0; +} + +static const char *add_module_info(cmd_parms * cmd, void *dummy, + const char *name, const char *info) +{ + server_rec *s = cmd->server; + info_svr_conf *conf = + (info_svr_conf *) ap_get_module_config(s->module_config, + &info_module); + info_entry *new = apr_array_push(conf->more_info); + + new->name = name; + new->info = info; + return NULL; +} + +static const command_rec info_cmds[] = { + AP_INIT_TAKE2("AddModuleInfo", add_module_info, NULL, RSRC_CONF, + "a module name and additional information on that module"), + {NULL} +}; + +static void register_hooks(apr_pool_t * p) +{ + ap_hook_handler(display_info, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA info_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_info_config, /* server config */ + merge_info_config, /* merge server config */ + info_cmds, /* command apr_table_t */ + register_hooks +}; diff --git a/trunk/modules/generators/mod_info.dsp b/trunk/modules/generators/mod_info.dsp new file mode 100644 index 0000000000..aceb8b6767 --- /dev/null +++ b/trunk/modules/generators/mod_info.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_info" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_info - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_info.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_info.mak" CFG="mod_info - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_info - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_info - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_info - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_info_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_info - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_info_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_info.so" /base:@..\..\os\win32\BaseAddr.ref,mod_info.so + +!ENDIF + +# Begin Target + +# Name "mod_info - Win32 Release" +# Name "mod_info - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_info.c +# End Source File +# Begin Source File + +SOURCE=.\mod_info.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_info - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_info.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_info.so "info_module for Apache" ../../include/ap_release.h > .\mod_info.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_info - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_info.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_info.so "info_module for Apache" ../../include/ap_release.h > .\mod_info.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/generators/mod_info.exp b/trunk/modules/generators/mod_info.exp new file mode 100644 index 0000000000..c304fa776d --- /dev/null +++ b/trunk/modules/generators/mod_info.exp @@ -0,0 +1 @@ +info_module diff --git a/trunk/modules/generators/mod_status.c b/trunk/modules/generators/mod_status.c new file mode 100644 index 0000000000..6f28d024a3 --- /dev/null +++ b/trunk/modules/generators/mod_status.c @@ -0,0 +1,865 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Status Module. Display lots of internal data about how Apache is + * performing and the state of all children processes. + * + * To enable this, add the following lines into any config file: + * + * + * SetHandler server-status + * + * + * You may want to protect this location by password or domain so no one + * else can look at it. Then you can access the statistics with a URL like: + * + * http://your_server_name/server-status + * + * /server-status - Returns page using tables + * /server-status?notable - Returns page for browsers without table support + * /server-status?refresh - Returns page with 1 second refresh + * /server-status?refresh=6 - Returns page with refresh every 6 seconds + * /server-status?auto - Returns page with data for automatic parsing + * + * Mark Cox, mark@ukweb.com, November 1995 + * + * 12.11.95 Initial version for www.telescope.org + * 13.3.96 Updated to remove rprintf's [Mark] + * 18.3.96 Added CPU usage, process information, and tidied [Ben Laurie] + * 18.3.96 Make extra Scoreboard variables #definable + * 25.3.96 Make short report have full precision [Ben Laurie suggested] + * 25.3.96 Show uptime better [Mark/Ben Laurie] + * 29.3.96 Better HTML and explanation [Mark/Rob Hartill suggested] + * 09.4.96 Added message for non-STATUS compiled version + * 18.4.96 Added per child and per slot counters [Jim Jagielski] + * 01.5.96 Table format, cleanup, even more spiffy data [Chuck Murcko/Jim J.] + * 18.5.96 Adapted to use new rprintf() routine, incidentally fixing a missing + * piece in short reports [Ben Laurie] + * 21.5.96 Additional Status codes (DNS and LOGGING only enabled if + * extended STATUS is enabled) [George Burgyan/Jim J.] + * 10.8.98 Allow for extended status info at runtime (no more STATUS) + * [Jim J.] + */ + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "ap_mpm.h" +#include "util_script.h" +#include +#include "scoreboard.h" +#include "http_log.h" +#include "mod_status.h" +#if APR_HAVE_UNISTD_H +#include +#endif +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#ifdef NEXT +#if (NX_CURRENT_COMPILER_RELEASE == 410) +#ifdef m68k +#define HZ 64 +#else +#define HZ 100 +#endif +#else +#include +#endif +#endif /* NEXT */ + +#define STATUS_MAXLINE 64 + +#define KBYTE 1024 +#define MBYTE 1048576L +#define GBYTE 1073741824L + +#ifndef DEFAULT_TIME_FORMAT +#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z" +#endif + +#define STATUS_MAGIC_TYPE "application/x-httpd-status" + +module AP_MODULE_DECLARE_DATA status_module; + +static int server_limit, thread_limit; + +/* Implement 'ap_run_status_hook'. */ +APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook, + (request_rec *r, int flags), + (r, flags), + OK, DECLINED) + +#ifdef HAVE_TIMES +/* ugh... need to know if we're running with a pthread implementation + * such as linuxthreads that treats individual threads as distinct + * processes; that affects how we add up CPU time in a process + */ +static pid_t child_pid; +#endif + +/* + * command-related code. This is here to prevent use of ExtendedStatus + * without status_module included. + */ +static const char *set_extended_status(cmd_parms *cmd, void *dummy, int arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + ap_extended_status = arg; + return NULL; +} + +static const command_rec status_module_cmds[] = +{ + AP_INIT_FLAG("ExtendedStatus", set_extended_status, NULL, RSRC_CONF, + "\"On\" to enable extended status information, \"Off\" to disable"), + {NULL} +}; + +/* Format the number of bytes nicely */ +static void format_byte_out(request_rec *r, apr_off_t bytes) +{ + if (bytes < (5 * KBYTE)) + ap_rprintf(r, "%d B", (int) bytes); + else if (bytes < (MBYTE / 2)) + ap_rprintf(r, "%.1f kB", (float) bytes / KBYTE); + else if (bytes < (GBYTE / 2)) + ap_rprintf(r, "%.1f MB", (float) bytes / MBYTE); + else + ap_rprintf(r, "%.1f GB", (float) bytes / GBYTE); +} + +static void format_kbyte_out(request_rec *r, apr_off_t kbytes) +{ + if (kbytes < KBYTE) + ap_rprintf(r, "%d kB", (int) kbytes); + else if (kbytes < MBYTE) + ap_rprintf(r, "%.1f MB", (float) kbytes / KBYTE); + else + ap_rprintf(r, "%.1f GB", (float) kbytes / MBYTE); +} + +static void show_time(request_rec *r, apr_interval_time_t tsecs) +{ + int days, hrs, mins, secs; + + secs = (int)(tsecs % 60); + tsecs /= 60; + mins = (int)(tsecs % 60); + tsecs /= 60; + hrs = (int)(tsecs % 24); + days = (int)(tsecs / 24); + + if (days) + ap_rprintf(r, " %d day%s", days, days == 1 ? "" : "s"); + + if (hrs) + ap_rprintf(r, " %d hour%s", hrs, hrs == 1 ? "" : "s"); + + if (mins) + ap_rprintf(r, " %d minute%s", mins, mins == 1 ? "" : "s"); + + if (secs) + ap_rprintf(r, " %d second%s", secs, secs == 1 ? "" : "s"); +} + +/* Main handler for x-httpd-status requests */ + +/* ID values for command table */ + +#define STAT_OPT_END -1 +#define STAT_OPT_REFRESH 0 +#define STAT_OPT_NOTABLE 1 +#define STAT_OPT_AUTO 2 + +struct stat_opt { + int id; + const char *form_data_str; + const char *hdr_out_str; +}; + +static const struct stat_opt status_options[] = /* see #defines above */ +{ + {STAT_OPT_REFRESH, "refresh", "Refresh"}, + {STAT_OPT_NOTABLE, "notable", NULL}, + {STAT_OPT_AUTO, "auto", NULL}, + {STAT_OPT_END, NULL, NULL} +}; + +static char status_flags[SERVER_NUM_STATUS]; + +static int status_handler(request_rec *r) +{ + const char *loc; + apr_time_t nowtime; + apr_interval_time_t up_time; + int j, i, res; + int ready; + int busy; + unsigned long count; + unsigned long lres, my_lres, conn_lres; + apr_off_t bytes, my_bytes, conn_bytes; + apr_off_t bcount, kbcount; + long req_time; +#ifdef HAVE_TIMES + float tick; + int times_per_thread = getpid() != child_pid; +#endif + int short_report; + int no_table_report; + worker_score *ws_record; + process_score *ps_record; + char *stat_buffer; + pid_t *pid_buffer, worker_pid; + clock_t tu, ts, tcu, tcs; + ap_generation_t worker_generation; + + if (strcmp(r->handler, STATUS_MAGIC_TYPE) && + strcmp(r->handler, "server-status")) { + return DECLINED; + } + +#ifdef HAVE_TIMES +#ifdef _SC_CLK_TCK + tick = sysconf(_SC_CLK_TCK); +#else + tick = HZ; +#endif +#endif + + ready = 0; + busy = 0; + count = 0; + bcount = 0; + kbcount = 0; + short_report = 0; + no_table_report = 0; + + pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t)); + stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); + + nowtime = apr_time_now(); + tu = ts = tcu = tcs = 0; + + if (!ap_exists_scoreboard_image()) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Server status unavailable in inetd mode"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + r->allowed = (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + ap_set_content_type(r, "text/html"); + + /* + * Simple table-driven form data set parser that lets you alter the header + */ + + if (r->args) { + i = 0; + while (status_options[i].id != STAT_OPT_END) { + if ((loc = ap_strstr_c(r->args, + status_options[i].form_data_str)) != NULL) { + switch (status_options[i].id) { + case STAT_OPT_REFRESH: + if (*(loc + strlen(status_options[i].form_data_str)) == '=' + && atol(loc + strlen(status_options[i].form_data_str) + + 1) > 0) + apr_table_set(r->headers_out, + status_options[i].hdr_out_str, + loc + + strlen(status_options[i].hdr_out_str) + + 1); + else + apr_table_set(r->headers_out, + status_options[i].hdr_out_str, "1"); + break; + case STAT_OPT_NOTABLE: + no_table_report = 1; + break; + case STAT_OPT_AUTO: + ap_set_content_type(r, "text/plain"); + short_report = 1; + break; + } + } + + i++; + } + } + + for (i = 0; i < server_limit; ++i) { +#ifdef HAVE_TIMES + clock_t proc_tu = 0, proc_ts = 0, proc_tcu = 0, proc_tcs = 0; + clock_t tmp_tu, tmp_ts, tmp_tcu, tmp_tcs; +#endif + + ps_record = ap_get_scoreboard_process(i); + for (j = 0; j < thread_limit; ++j) { + int indx = (i * thread_limit) + j; + + ws_record = ap_get_scoreboard_worker(i, j); + res = ws_record->status; + stat_buffer[indx] = status_flags[res]; + + if (!ps_record->quiescing + && ps_record->pid) { + if (res == SERVER_READY + && ps_record->generation == ap_my_generation) + ready++; + else if (res != SERVER_DEAD && + res != SERVER_STARTING && + res != SERVER_IDLE_KILL) + busy++; + } + + /* XXX what about the counters for quiescing/seg faulted + * processes? should they be counted or not? GLA + */ + if (ap_extended_status) { + lres = ws_record->access_count; + bytes = ws_record->bytes_served; + + if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) { +#ifdef HAVE_TIMES + tmp_tu = ws_record->times.tms_utime; + tmp_ts = ws_record->times.tms_stime; + tmp_tcu = ws_record->times.tms_cutime; + tmp_tcs = ws_record->times.tms_cstime; + + if (times_per_thread) { + proc_tu += tmp_tu; + proc_ts += tmp_ts; + proc_tcu += tmp_tcu; + proc_tcs += proc_tcs; + } + else { + if (tmp_tu > proc_tu || + tmp_ts > proc_ts || + tmp_tcu > proc_tcu || + tmp_tcs > proc_tcs) { + proc_tu = tmp_tu; + proc_ts = tmp_ts; + proc_tcu = tmp_tcu; + proc_tcs = proc_tcs; + } + } +#endif /* HAVE_TIMES */ + + count += lres; + bcount += bytes; + + if (bcount >= KBYTE) { + kbcount += (bcount >> 10); + bcount = bcount & 0x3ff; + } + } + } + } +#ifdef HAVE_TIMES + tu += proc_tu; + ts += proc_ts; + tcu += proc_tcu; + tcs += proc_tcs; +#endif + pid_buffer[i] = ps_record->pid; + } + + /* up_time in seconds */ + up_time = (apr_uint32_t) apr_time_sec(nowtime - + ap_scoreboard_image->global->restart_time); + + if (!short_report) { + ap_rputs(DOCTYPE_HTML_3_2 + "\nApache Status\n\n", + r); + ap_rputs("

    Apache Server Status for ", r); + ap_rvputs(r, ap_get_server_name(r), "

    \n\n", NULL); + ap_rvputs(r, "
    Server Version: ", + ap_get_server_version(), "
    \n", NULL); + ap_rvputs(r, "
    Server Built: ", + ap_get_server_built(), "\n

    \n", NULL); + ap_rvputs(r, "
    Current Time: ", + ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), + "
    \n", NULL); + ap_rvputs(r, "
    Restart Time: ", + ap_ht_time(r->pool, + ap_scoreboard_image->global->restart_time, + DEFAULT_TIME_FORMAT, 0), + "
    \n", NULL); + ap_rprintf(r, "
    Parent Server Generation: %d
    \n", + (int)ap_my_generation); + ap_rputs("
    Server uptime: ", r); + show_time(r, up_time); + ap_rputs("
    \n", r); + } + + if (ap_extended_status) { + if (short_report) { + ap_rprintf(r, "Total Accesses: %lu\nTotal kBytes: %" + APR_OFF_T_FMT "\n", + count, kbcount); + +#ifdef HAVE_TIMES + /* Allow for OS/2 not having CPU stats */ + if (ts || tu || tcu || tcs) + ap_rprintf(r, "CPULoad: %g\n", + (tu + ts + tcu + tcs) / tick / up_time * 100.); +#endif + + ap_rprintf(r, "Uptime: %ld\n", (long) (up_time)); + if (up_time > 0) + ap_rprintf(r, "ReqPerSec: %g\n", + (float) count / (float) up_time); + + if (up_time > 0) + ap_rprintf(r, "BytesPerSec: %g\n", + KBYTE * (float) kbcount / (float) up_time); + + if (count > 0) + ap_rprintf(r, "BytesPerReq: %g\n", + KBYTE * (float) kbcount / (float) count); + } + else { /* !short_report */ + ap_rprintf(r, "
    Total accesses: %lu - Total Traffic: ", count); + format_kbyte_out(r, kbcount); + ap_rputs("
    \n", r); + +#ifdef HAVE_TIMES + /* Allow for OS/2 not having CPU stats */ + ap_rprintf(r, "
    CPU Usage: u%g s%g cu%g cs%g", + tu / tick, ts / tick, tcu / tick, tcs / tick); + + if (ts || tu || tcu || tcs) + ap_rprintf(r, " - %.3g%% CPU load
    \n", + (tu + ts + tcu + tcs) / tick / up_time * 100.); +#endif + + if (up_time > 0) + ap_rprintf(r, "
    %.3g requests/sec - ", + (float) count / (float) up_time); + + if (up_time > 0) { + format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount + / (float) up_time)); + ap_rputs("/second - ", r); + } + + if (count > 0) { + format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount + / (float) count)); + ap_rputs("/request", r); + } + + ap_rputs("
    \n", r); + } /* short_report */ + } /* ap_extended_status */ + + if (!short_report) + ap_rprintf(r, "
    %d requests currently being processed, " + "%d idle workers
    \n", busy, ready); + else + ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready); + + /* send the scoreboard 'table' out */ + if (!short_report) + ap_rputs("
    ", r);
    +    else
    +        ap_rputs("Scoreboard: ", r);
    +
    +    for (i = 0; i < server_limit; ++i) {
    +        for (j = 0; j < thread_limit; ++j) {
    +            int indx = (i * thread_limit) + j;
    +            ap_rputc(stat_buffer[indx], r);
    +            if ((indx % STATUS_MAXLINE == (STATUS_MAXLINE - 1))
    +                && !short_report)
    +                ap_rputs("\n", r);
    +        }
    +    }
    +
    +    if (short_report)
    +        ap_rputs("\n", r);
    +    else {
    +        ap_rputs("
    \n", r); + ap_rputs("

    Scoreboard Key:
    \n", r); + ap_rputs("\"_\" Waiting for Connection, \n", r); + ap_rputs("\"S\" Starting up, \n", r); + ap_rputs("\"R\" Reading Request,
    \n", r); + ap_rputs("\"W\" Sending Reply, \n", r); + ap_rputs("\"K\" Keepalive (read), \n", r); + ap_rputs("\"D\" DNS Lookup,
    \n", r); + ap_rputs("\"C\" Closing connection, \n", r); + ap_rputs("\"L\" Logging, \n", r); + ap_rputs("\"G\" Gracefully finishing,
    \n", r); + ap_rputs("\"I\" Idle cleanup of worker, \n", r); + ap_rputs("\".\" Open slot with no current process

    \n", r); + ap_rputs("

    \n", r); + if (!ap_extended_status) { + int j; + int k = 0; + ap_rputs("PID Key:
    \n", r); + ap_rputs("

    \n", r);
    +            for (i = 0; i < server_limit; ++i) {
    +                for (j = 0; j < thread_limit; ++j) {
    +                    int indx = (i * thread_limit) + j;
    +
    +                    if (stat_buffer[indx] != '.') {
    +                        ap_rprintf(r, "   %" APR_PID_T_FMT
    +                                   " in state: %c ", pid_buffer[i],
    +                                   stat_buffer[indx]);
    +
    +                        if (++k >= 3) {
    +                            ap_rputs("\n", r);
    +                            k = 0;
    +                        } else
    +                            ap_rputs(",", r);
    +                    }
    +                }
    +            }
    +
    +            ap_rputs("\n", r);
    +            ap_rputs("
    \n", r); + } + } + + if (ap_extended_status && !short_report) { + if (no_table_report) + ap_rputs("

    Server Details

    \n\n", r); + else + ap_rputs("\n\n" + "" + "" +#ifdef HAVE_TIMES + "" +#endif + "" + "" + "" + "\n\n", r); + + for (i = 0; i < server_limit; ++i) { + for (j = 0; j < thread_limit; ++j) { + ws_record = ap_get_scoreboard_worker(i, j); + + if (ws_record->access_count == 0 && + (ws_record->status == SERVER_READY || + ws_record->status == SERVER_DEAD)) { + continue; + } + + ps_record = ap_get_scoreboard_process(i); + + if (ws_record->start_time == 0L) + req_time = 0L; + else + req_time = (long) + ((ws_record->stop_time - + ws_record->start_time) / 1000); + if (req_time < 0L) + req_time = 0L; + + lres = ws_record->access_count; + my_lres = ws_record->my_access_count; + conn_lres = ws_record->conn_count; + bytes = ws_record->bytes_served; + my_bytes = ws_record->my_bytes_served; + conn_bytes = ws_record->conn_bytes; + if (ws_record->pid) { /* MPM sets per-worker pid and generation */ + worker_pid = ws_record->pid; + worker_generation = ws_record->generation; + } + else { + worker_pid = ps_record->pid; + worker_generation = ps_record->generation; + } + + if (no_table_report) { + if (ws_record->status == SERVER_DEAD) + ap_rprintf(r, + "Server %d-%d (-): %d|%lu|%lu [", + i, (int)worker_generation, + (int)conn_lres, my_lres, lres); + else + ap_rprintf(r, + "Server %d-%d (%" + APR_PID_T_FMT "): %d|%lu|%lu [", + i, (int) worker_generation, + worker_pid, + (int)conn_lres, my_lres, lres); + + switch (ws_record->status) { + case SERVER_READY: + ap_rputs("Ready", r); + break; + case SERVER_STARTING: + ap_rputs("Starting", r); + break; + case SERVER_BUSY_READ: + ap_rputs("Read", r); + break; + case SERVER_BUSY_WRITE: + ap_rputs("Write", r); + break; + case SERVER_BUSY_KEEPALIVE: + ap_rputs("Keepalive", r); + break; + case SERVER_BUSY_LOG: + ap_rputs("Logging", r); + break; + case SERVER_BUSY_DNS: + ap_rputs("DNS lookup", r); + break; + case SERVER_CLOSING: + ap_rputs("Closing", r); + break; + case SERVER_DEAD: + ap_rputs("Dead", r); + break; + case SERVER_GRACEFUL: + ap_rputs("Graceful", r); + break; + case SERVER_IDLE_KILL: + ap_rputs("Dying", r); + break; + default: + ap_rputs("?STATE?", r); + break; + } + + ap_rprintf(r, "] " +#ifdef HAVE_TIMES + "u%g s%g cu%g cs%g" +#endif + "\n %ld %ld (", +#ifdef HAVE_TIMES + ws_record->times.tms_utime / tick, + ws_record->times.tms_stime / tick, + ws_record->times.tms_cutime / tick, + ws_record->times.tms_cstime / tick, +#endif + (long)apr_time_sec(nowtime - + ws_record->last_used), + (long) req_time); + + format_byte_out(r, conn_bytes); + ap_rputs("|", r); + format_byte_out(r, my_bytes); + ap_rputs("|", r); + format_byte_out(r, bytes); + ap_rputs(")\n", r); + ap_rprintf(r, + " %s {%s}[%s]
    \n\n", + ap_escape_html(r->pool, + ws_record->client), + ap_escape_html(r->pool, + ws_record->request), + ap_escape_html(r->pool, + ws_record->vhost)); + } + else { /* !no_table_report */ + if (ws_record->status == SERVER_DEAD) + ap_rprintf(r, + "" +#ifdef HAVE_TIMES + "" +#endif + "\n\n"); + else + ap_rprintf(r, + "\n\n", + ap_escape_html(r->pool, + ws_record->client), + ap_escape_html(r->pool, + ws_record->vhost), + ap_escape_html(r->pool, + ws_record->request)); + } /* no_table_report */ + } /* for (j...) */ + } /* for (i...) */ + + if (!no_table_report) { + ap_rputs("
    SrvPIDAccMCPU\nSSReqConnChildSlotClientVHostRequest
    %d-%d-%d/%lu/%lu", + i, (int)worker_generation, + (int)conn_lres, my_lres, lres); + else + ap_rprintf(r, + "
    %d-%d%" + APR_PID_T_FMT + "%d/%lu/%lu", + i, (int)worker_generation, + worker_pid, + (int)conn_lres, + my_lres, lres); + + switch (ws_record->status) { + case SERVER_READY: + ap_rputs("_", r); + break; + case SERVER_STARTING: + ap_rputs("S", r); + break; + case SERVER_BUSY_READ: + ap_rputs("R", r); + break; + case SERVER_BUSY_WRITE: + ap_rputs("W", r); + break; + case SERVER_BUSY_KEEPALIVE: + ap_rputs("K", r); + break; + case SERVER_BUSY_LOG: + ap_rputs("L", r); + break; + case SERVER_BUSY_DNS: + ap_rputs("D", r); + break; + case SERVER_CLOSING: + ap_rputs("C", r); + break; + case SERVER_DEAD: + ap_rputs(".", r); + break; + case SERVER_GRACEFUL: + ap_rputs("G", r); + break; + case SERVER_IDLE_KILL: + ap_rputs("I", r); + break; + default: + ap_rputs("?", r); + break; + } + + ap_rprintf(r, + "\n%.2f%ld%ld", +#ifdef HAVE_TIMES + (ws_record->times.tms_utime + + ws_record->times.tms_stime + + ws_record->times.tms_cutime + + ws_record->times.tms_cstime) / tick, +#endif + (long)apr_time_sec(nowtime - + ws_record->last_used), + (long)req_time); + + ap_rprintf(r, "%-1.1f%-2.2f%-2.2f\n", + (float)conn_bytes / KBYTE, (float) my_bytes / MBYTE, + (float)bytes / MBYTE); + + if (ws_record->status == SERVER_BUSY_READ) + ap_rprintf(r, + "??..reading..
    %s%s%s
    \n \ +
    \ +\n \ +\n \ +\n \ +\n \ +\n" + +#ifdef HAVE_TIMES +"\n" +#endif + +"\n \ +\n \ +\n \ +\n \ +\n \ +
    SrvChild Server number - generation
    PIDOS process ID
    AccNumber of accesses this connection / this child / this slot
    MMode of operation
    CPUCPU usage, number of seconds
    SSSeconds since beginning of most recent request
    ReqMilliseconds required to process most recent request
    ConnKilobytes transferred this connection
    ChildMegabytes transferred this child
    SlotTotal megabytes transferred this slot
    \n", r); + } + } /* if (ap_extended_status && !short_report) */ + else { + + if (!short_report) { + ap_rputs("
    To obtain a full report with current status " + "information you need to use the " + "ExtendedStatus On directive.\n", r); + } + } + + { + /* Run extension hooks to insert extra content. */ + int flags = + (short_report ? AP_STATUS_SHORT : 0) | + (no_table_report ? AP_STATUS_NOTABLE : 0) | + (ap_extended_status ? AP_STATUS_EXTENDED : 0); + + ap_run_status_hook(r, flags); + } + + if (!short_report) { + ap_rputs(ap_psignature("
    \n",r), r); + ap_rputs("\n", r); + } + + return 0; +} + + +static int status_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, + server_rec *s) +{ + status_flags[SERVER_DEAD] = '.'; /* We don't want to assume these are in */ + status_flags[SERVER_READY] = '_'; /* any particular order in scoreboard.h */ + status_flags[SERVER_STARTING] = 'S'; + status_flags[SERVER_BUSY_READ] = 'R'; + status_flags[SERVER_BUSY_WRITE] = 'W'; + status_flags[SERVER_BUSY_KEEPALIVE] = 'K'; + status_flags[SERVER_BUSY_LOG] = 'L'; + status_flags[SERVER_BUSY_DNS] = 'D'; + status_flags[SERVER_CLOSING] = 'C'; + status_flags[SERVER_GRACEFUL] = 'G'; + status_flags[SERVER_IDLE_KILL] = 'I'; + ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); + ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); + return OK; +} + +#ifdef HAVE_TIMES +static void status_child_init(apr_pool_t *p, server_rec *s) +{ + child_pid = getpid(); +} +#endif + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(status_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(status_init, NULL, NULL, APR_HOOK_MIDDLE); +#ifdef HAVE_TIMES + ap_hook_child_init(status_child_init, NULL, NULL, APR_HOOK_MIDDLE); +#endif +} + +module AP_MODULE_DECLARE_DATA status_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + status_module_cmds, /* command table */ + register_hooks /* register_hooks */ +}; + diff --git a/trunk/modules/generators/mod_status.dsp b/trunk/modules/generators/mod_status.dsp new file mode 100644 index 0000000000..e727401ffa --- /dev/null +++ b/trunk/modules/generators/mod_status.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_status" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_status - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_status.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_status.mak" CFG="mod_status - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_status - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_status - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_status - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /Fd"Release\mod_status_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_status - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STATUS_DECLARE_EXPORT" /Fd"Debug\mod_status_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_status.so" /base:@..\..\os\win32\BaseAddr.ref,mod_status.so + +!ENDIF + +# Begin Target + +# Name "mod_status - Win32 Release" +# Name "mod_status - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_status.c +# End Source File +# Begin Source File + +SOURCE=.\mod_status.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_status - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_status.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_status.so "status_module for Apache" ../../include/ap_release.h > .\mod_status.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_status - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_status.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_status.so "status_module for Apache" ../../include/ap_release.h > .\mod_status.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/generators/mod_status.exp b/trunk/modules/generators/mod_status.exp new file mode 100644 index 0000000000..5438093686 --- /dev/null +++ b/trunk/modules/generators/mod_status.exp @@ -0,0 +1 @@ +status_module diff --git a/trunk/modules/generators/mod_status.h b/trunk/modules/generators/mod_status.h new file mode 100644 index 0000000000..03041825e2 --- /dev/null +++ b/trunk/modules/generators/mod_status.h @@ -0,0 +1,54 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_STATUS_H +#define MOD_STATUS_H + +#include "ap_config.h" +#include "httpd.h" + +#define AP_STATUS_SHORT (0x1) /* short, non-HTML report requested */ +#define AP_STATUS_NOTABLE (0x2) /* HTML report without tables */ +#define AP_STATUS_EXTENDED (0x4) /* detailed report */ + +#if !defined(WIN32) +#define STATUS_DECLARE(type) type +#define STATUS_DECLARE_NONSTD(type) type +#define STATUS_DECLARE_DATA +#elif defined(STATUS_DECLARE_STATIC) +#define STATUS_DECLARE(type) type __stdcall +#define STATUS_DECLARE_NONSTD(type) type +#define STATUS_DECLARE_DATA +#elif defined(STATUS_DECLARE_EXPORT) +#define STATUS_DECLARE(type) __declspec(dllexport) type __stdcall +#define STATUS_DECLARE_NONSTD(type) __declspec(dllexport) type +#define STATUS_DECLARE_DATA __declspec(dllexport) +#else +#define STATUS_DECLARE(type) __declspec(dllimport) type __stdcall +#define STATUS_DECLARE_NONSTD(type) __declspec(dllimport) type +#define STATUS_DECLARE_DATA __declspec(dllimport) +#endif + +/* Optional hooks which can insert extra content into the mod_status + * output. FLAGS will be set to the bitwise OR of any of the + * AP_STATUS_* flags. + * + * Implementations of this hook should generate content using + * functions in the ap_rputs/ap_rprintf family; each hook should + * return OK or DECLINED. */ +APR_DECLARE_EXTERNAL_HOOK(ap, STATUS, int, status_hook, + (request_rec *r, int flags)) +#endif diff --git a/trunk/modules/generators/mod_suexec.c b/trunk/modules/generators/mod_suexec.c new file mode 100644 index 0000000000..080c51d959 --- /dev/null +++ b/trunk/modules/generators/mod_suexec.c @@ -0,0 +1,138 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_request.h" +#include "apr_strings.h" +#include "unixd.h" +#include "mpm_common.h" +#include "mod_suexec.h" + +module AP_MODULE_DECLARE_DATA suexec_module; + +/* + * Create a configuration specific to this module for a server or directory + * location, and fill it with the default settings. + */ +static void *mkconfig(apr_pool_t *p) +{ + suexec_config_t *cfg = apr_palloc(p, sizeof(suexec_config_t)); + + cfg->active = 0; + return cfg; +} + +/* + * Respond to a callback to create configuration record for a server or + * vhost environment. + */ +static void *create_mconfig_for_server(apr_pool_t *p, server_rec *s) +{ + return mkconfig(p); +} + +/* + * Respond to a callback to create a config record for a specific directory. + */ +static void *create_mconfig_for_directory(apr_pool_t *p, char *dir) +{ + return mkconfig(p); +} + +static const char *set_suexec_ugid(cmd_parms *cmd, void *mconfig, + const char *uid, const char *gid) +{ + suexec_config_t *cfg = (suexec_config_t *) mconfig; + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + if (unixd_config.suexec_enabled) { + cfg->ugid.uid = ap_uname2id(uid); + cfg->ugid.gid = ap_gname2id(gid); + cfg->ugid.userdir = 0; + cfg->active = 1; + } + else { + fprintf(stderr, + "Warning: SuexecUserGroup directive requires SUEXEC wrapper.\n"); + } + return NULL; +} + +static ap_unix_identity_t *get_suexec_id_doer(const request_rec *r) +{ + suexec_config_t *cfg = + (suexec_config_t *) ap_get_module_config(r->per_dir_config, &suexec_module); + + return cfg->active ? &cfg->ugid : NULL; +} + +#define SUEXEC_POST_CONFIG_USERDATA "suexec_post_config_userdata" +static int suexec_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + void *reported; + + apr_pool_userdata_get(&reported, SUEXEC_POST_CONFIG_USERDATA, + s->process->pool); + + if ((reported == NULL) && unixd_config.suexec_enabled) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "suEXEC mechanism enabled (wrapper: %s)", SUEXEC_BIN); + + apr_pool_userdata_set((void *)1, SUEXEC_POST_CONFIG_USERDATA, + apr_pool_cleanup_null, s->process->pool); + } + + return OK; +} +#undef SUEXEC_POST_CONFIG_USERDATA + +/* + * Define the directives specific to this module. This structure is referenced + * later by the 'module' structure. + */ +static const command_rec suexec_cmds[] = +{ + /* XXX - Another important reason not to allow this in .htaccess is that + * the ap_[ug]name2id() is not thread-safe */ + AP_INIT_TAKE2("SuexecUserGroup", set_suexec_ugid, NULL, RSRC_CONF, + "User and group for spawned processes"), + { NULL } +}; + +static void suexec_hooks(apr_pool_t *p) +{ + ap_hook_get_suexec_identity(get_suexec_id_doer,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_post_config(suexec_post_config,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA suexec_module = +{ + STANDARD20_MODULE_STUFF, + create_mconfig_for_directory, /* create per-dir config */ + NULL, /* merge per-dir config */ + create_mconfig_for_server, /* server config */ + NULL, /* merge server config */ + suexec_cmds, /* command table */ + suexec_hooks /* register hooks */ +}; diff --git a/trunk/modules/generators/mod_suexec.h b/trunk/modules/generators/mod_suexec.h new file mode 100644 index 0000000000..5169beeee9 --- /dev/null +++ b/trunk/modules/generators/mod_suexec.h @@ -0,0 +1,23 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "unixd.h" + +typedef struct { + ap_unix_identity_t ugid; + int active; +} suexec_config_t; + diff --git a/trunk/modules/http/.indent.pro b/trunk/modules/http/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/http/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/http/Makefile.in b/trunk/modules/http/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/http/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/http/byterange_filter.c b/trunk/modules/http/byterange_filter.c new file mode 100644 index 0000000000..422a008b85 --- /dev/null +++ b/trunk/modules/http/byterange_filter.c @@ -0,0 +1,383 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * byterange_filter.c --- HTTP byterange filter and friends. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_signal.h" + +#define APR_WANT_STDIO /* for sscanf */ +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "util_filter.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_log.h" /* For errors detected in basic auth common + * support code... */ +#include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */ +#include "util_charset.h" +#include "util_ebcdic.h" +#include "util_time.h" + +#include "mod_core.h" + +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +static int parse_byterange(char *range, apr_off_t clength, + apr_off_t *start, apr_off_t *end) +{ + char *dash = strchr(range, '-'); + char *errp; + apr_off_t number; + + if (!dash) { + return 0; + } + + if ((dash == range)) { + /* In the form "-5" */ + if (apr_strtoff(&number, dash+1, &errp, 10) || *errp) { + return 0; + } + *start = clength - number; + *end = clength - 1; + } + else { + *dash++ = '\0'; + if (apr_strtoff(&number, range, &errp, 10) || *errp) { + return 0; + } + *start = number; + if (*dash) { + if (apr_strtoff(&number, dash, &errp, 10) || *errp) { + return 0; + } + *end = number; + } + else { /* "5-" */ + *end = clength - 1; + } + } + + if (*start < 0) { + *start = 0; + } + + if (*end >= clength) { + *end = clength - 1; + } + + if (*start > *end) { + return -1; + } + + return (*start > 0 || *end < clength); +} + +static int ap_set_byterange(request_rec *r); + +typedef struct byterange_ctx { + apr_bucket_brigade *bb; + int num_ranges; + char *boundary; + char *bound_head; +} byterange_ctx; + +/* + * Here we try to be compatible with clients that want multipart/x-byteranges + * instead of multipart/byteranges (also see above), as per HTTP/1.1. We + * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication + * that the browser supports an older protocol. We also check User-Agent + * for Microsoft Internet Explorer 3, which needs this as well. + */ +static int use_range_x(request_rec *r) +{ + const char *ua; + return (apr_table_get(r->headers_in, "Request-Range") + || ((ua = apr_table_get(r->headers_in, "User-Agent")) + && ap_strstr_c(ua, "MSIE 3"))); +} + +#define BYTERANGE_FMT "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT "/%" APR_OFF_T_FMT +#define PARTITION_ERR_FMT "apr_brigade_partition() failed " \ + "[%" APR_OFF_T_FMT ",%" APR_OFF_T_FMT "]" + +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ +#define MIN_LENGTH(len1, len2) ((len1 > len2) ? len2 : len1) + request_rec *r = f->r; + conn_rec *c = r->connection; + byterange_ctx *ctx; + apr_bucket *e; + apr_bucket_brigade *bsend; + apr_off_t range_start; + apr_off_t range_end; + char *current; + apr_off_t clength = 0; + apr_status_t rv; + int found = 0; + + /* Iterate through the brigade until reaching EOS or a bucket with + * unknown length. */ + for (e = APR_BRIGADE_FIRST(bb); + (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e) + && e->length != (apr_size_t)-1); + e = APR_BUCKET_NEXT(e)) { + clength += e->length; + } + + /* Don't attempt to do byte range work if this brigade doesn't + * contain an EOS, or if any of the buckets has an unknown length; + * this avoids the cases where it is expensive to perform + * byteranging (i.e. may require arbitrary amounts of memory). */ + if (!APR_BUCKET_IS_EOS(e) || clength <= 0) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + { + int num_ranges = ap_set_byterange(r); + + /* We have nothing to do, get out of the way. */ + if (num_ranges == 0) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb); + } + + ctx = apr_pcalloc(r->pool, sizeof(*ctx)); + ctx->num_ranges = num_ranges; + /* create a brigade in case we never call ap_save_brigade() */ + ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc); + + if (ctx->num_ranges > 1) { + /* Is ap_make_content_type required here? */ + const char *orig_ct = ap_make_content_type(r, r->content_type); + ctx->boundary = apr_psprintf(r->pool, "%" APR_UINT64_T_HEX_FMT "%lx", + (apr_uint64_t)r->request_time, (long) getpid()); + + ap_set_content_type(r, apr_pstrcat(r->pool, "multipart", + use_range_x(r) ? "/x-" : "/", + "byteranges; boundary=", + ctx->boundary, NULL)); + + ctx->bound_head = apr_pstrcat(r->pool, + CRLF "--", ctx->boundary, + CRLF "Content-type: ", + orig_ct, + CRLF "Content-range: bytes ", + NULL); + ap_xlate_proto_to_ascii(ctx->bound_head, strlen(ctx->bound_head)); + } + } + + /* this brigade holds what we will be sending */ + bsend = apr_brigade_create(r->pool, c->bucket_alloc); + + while ((current = ap_getword(r->pool, &r->range, ',')) + && (rv = parse_byterange(current, clength, &range_start, + &range_end))) { + apr_bucket *e2; + apr_bucket *ec; + + if (rv == -1) { + continue; + } + + /* these calls to apr_brigade_partition() should theoretically + * never fail because of the above call to apr_brigade_length(), + * but what the heck, we'll check for an error anyway */ + if ((rv = apr_brigade_partition(bb, range_start, &ec)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + PARTITION_ERR_FMT, range_start, clength); + continue; + } + if ((rv = apr_brigade_partition(bb, range_end+1, &e2)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + PARTITION_ERR_FMT, range_end+1, clength); + continue; + } + + found = 1; + + /* For single range requests, we must produce Content-Range header. + * Otherwise, we need to produce the multipart boundaries. + */ + if (ctx->num_ranges == 1) { + apr_table_setn(r->headers_out, "Content-Range", + apr_psprintf(r->pool, "bytes " BYTERANGE_FMT, + range_start, range_end, clength)); + } + else { + char *ts; + + e = apr_bucket_pool_create(ctx->bound_head, strlen(ctx->bound_head), + r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + + ts = apr_psprintf(r->pool, BYTERANGE_FMT CRLF CRLF, + range_start, range_end, clength); + ap_xlate_proto_to_ascii(ts, strlen(ts)); + e = apr_bucket_pool_create(ts, strlen(ts), r->pool, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + } + + do { + apr_bucket *foo; + const char *str; + apr_size_t len; + + if (apr_bucket_copy(ec, &foo) != APR_SUCCESS) { + /* this shouldn't ever happen due to the call to + * apr_brigade_length() above which normalizes + * indeterminate-length buckets. just to be sure, + * though, this takes care of uncopyable buckets that + * do somehow manage to slip through. + */ + /* XXX: check for failure? */ + apr_bucket_read(ec, &str, &len, APR_BLOCK_READ); + apr_bucket_copy(ec, &foo); + } + APR_BRIGADE_INSERT_TAIL(bsend, foo); + ec = APR_BUCKET_NEXT(ec); + } while (ec != e2); + } + + if (found == 0) { + ap_remove_output_filter(f); + r->status = HTTP_OK; + /* bsend is assumed to be empty if we get here. */ + e = ap_bucket_error_create(HTTP_RANGE_NOT_SATISFIABLE, NULL, + r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + e = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + return ap_pass_brigade(f->next, bsend); + } + + if (ctx->num_ranges > 1) { + char *end; + + /* add the final boundary */ + end = apr_pstrcat(r->pool, CRLF "--", ctx->boundary, "--" CRLF, NULL); + ap_xlate_proto_to_ascii(end, strlen(end)); + e = apr_bucket_pool_create(end, strlen(end), r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + } + + e = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bsend, e); + + /* we're done with the original content - all of our data is in bsend. */ + apr_brigade_destroy(bb); + + /* send our multipart output */ + return ap_pass_brigade(f->next, bsend); +} + +static int ap_set_byterange(request_rec *r) +{ + const char *range; + const char *if_range; + const char *match; + const char *ct; + int num_ranges; + + if (r->assbackwards) { + return 0; + } + + /* Check for Range request-header (HTTP/1.1) or Request-Range for + * backwards-compatibility with second-draft Luotonen/Franks + * byte-ranges (e.g. Netscape Navigator 2-3). + * + * We support this form, with Request-Range, and (farther down) we + * send multipart/x-byteranges instead of multipart/byteranges for + * Request-Range based requests to work around a bug in Netscape + * Navigator 2-3 and MSIE 3. + */ + + if (!(range = apr_table_get(r->headers_in, "Range"))) { + range = apr_table_get(r->headers_in, "Request-Range"); + } + + if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) { + return 0; + } + + /* is content already a single range? */ + if (apr_table_get(r->headers_out, "Content-Range")) { + return 0; + } + + /* is content already a multiple range? */ + if ((ct = apr_table_get(r->headers_out, "Content-Type")) + && (!strncasecmp(ct, "multipart/byteranges", 20) + || !strncasecmp(ct, "multipart/x-byteranges", 22))) { + return 0; + } + + /* 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 = apr_table_get(r->headers_in, "If-Range"))) { + if (if_range[0] == '"') { + if (!(match = apr_table_get(r->headers_out, "Etag")) + || (strcmp(if_range, match) != 0)) { + return 0; + } + } + else if (!(match = apr_table_get(r->headers_out, "Last-Modified")) + || (strcmp(if_range, match) != 0)) { + return 0; + } + } + + if (!ap_strchr_c(range, ',')) { + /* a single range */ + num_ranges = 1; + } + else { + /* a multiple range */ + num_ranges = 2; + } + + r->status = HTTP_PARTIAL_CONTENT; + r->range = range + 6; + + return num_ranges; +} diff --git a/trunk/modules/http/chunk_filter.c b/trunk/modules/http/chunk_filter.c new file mode 100644 index 0000000000..c5175e6ee3 --- /dev/null +++ b/trunk/modules/http/chunk_filter.c @@ -0,0 +1,168 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * chunk_filter.c --- HTTP/1.1 chunked transfer encoding filter. + */ + +#include "apr_strings.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_connection.h" +#include "http_core.h" +#include "http_protocol.h" /* For index_of_response(). Grump. */ +#include "http_request.h" + +#include "util_filter.h" +#include "util_ebcdic.h" +#include "ap_mpm.h" +#include "scoreboard.h" + +#include "mod_core.h" + +apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) +{ +#define ASCII_CRLF "\015\012" +#define ASCII_ZERO "\060" + conn_rec *c = f->r->connection; + apr_bucket_brigade *more; + apr_bucket *e; + apr_status_t rv; + + for (more = NULL; b; b = more, more = NULL) { + apr_off_t bytes = 0; + apr_bucket *eos = NULL; + apr_bucket *flush = NULL; + /* XXX: chunk_hdr must remain at this scope since it is used in a + * transient bucket. + */ + char chunk_hdr[20]; /* enough space for the snprintf below */ + + + for (e = APR_BRIGADE_FIRST(b); + e != APR_BRIGADE_SENTINEL(b); + e = APR_BUCKET_NEXT(e)) + { + if (APR_BUCKET_IS_EOS(e)) { + /* there shouldn't be anything after the eos */ + eos = e; + break; + } + if (APR_BUCKET_IS_FLUSH(e)) { + flush = e; + } + else if (e->length == (apr_size_t)-1) { + /* unknown amount of data (e.g. a pipe) */ + const char *data; + apr_size_t len; + + rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + return rv; + } + if (len > 0) { + /* + * There may be a new next bucket representing the + * rest of the data stream on which a read() may + * block so we pass down what we have so far. + */ + bytes += len; + more = apr_brigade_split(b, APR_BUCKET_NEXT(e)); + break; + } + else { + /* If there was nothing in this bucket then we can + * safely move on to the next one without pausing + * to pass down what we have counted up so far. + */ + continue; + } + } + else { + bytes += e->length; + } + } + + /* + * XXX: if there aren't very many bytes at this point it may + * be a good idea to set them aside and return for more, + * unless we haven't finished counting this brigade yet. + */ + /* if there are content bytes, then wrap them in a chunk */ + if (bytes > 0) { + apr_size_t hdr_len; + /* + * Insert the chunk header, specifying the number of bytes in + * the chunk. + */ + hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr), + "%" APR_UINT64_T_HEX_FMT CRLF, (apr_uint64_t)bytes); + ap_xlate_proto_to_ascii(chunk_hdr, hdr_len); + e = apr_bucket_transient_create(chunk_hdr, hdr_len, + c->bucket_alloc); + APR_BRIGADE_INSERT_HEAD(b, e); + + /* + * Insert the end-of-chunk CRLF before an EOS or + * FLUSH bucket, or appended to the brigade + */ + e = apr_bucket_immortal_create(ASCII_CRLF, 2, c->bucket_alloc); + if (eos != NULL) { + APR_BUCKET_INSERT_BEFORE(eos, e); + } + else if (flush != NULL) { + APR_BUCKET_INSERT_BEFORE(flush, e); + } + else { + APR_BRIGADE_INSERT_TAIL(b, e); + } + } + + /* RFC 2616, Section 3.6.1 + * + * If there is an EOS bucket, then prefix it with: + * 1) the last-chunk marker ("0" CRLF) + * 2) the trailer + * 3) the end-of-chunked body CRLF + * + * If there is no EOS bucket, then do nothing. + * + * XXX: it would be nice to combine this with the end-of-chunk + * marker above, but this is a bit more straight-forward for + * now. + */ + if (eos != NULL) { + /* XXX: (2) trailers ... does not yet exist */ + e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF + /* */ + ASCII_CRLF, 5, c->bucket_alloc); + APR_BUCKET_INSERT_BEFORE(eos, e); + } + + /* pass the brigade to the next filter. */ + rv = ap_pass_brigade(f->next, b); + if (rv != APR_SUCCESS || eos != NULL) { + return rv; + } + } + return APR_SUCCESS; +} diff --git a/trunk/modules/http/config2.m4 b/trunk/modules/http/config2.m4 new file mode 100644 index 0000000000..87a7cc8a20 --- /dev/null +++ b/trunk/modules/http/config2.m4 @@ -0,0 +1,20 @@ +dnl modules enabled in this directory by default + +APACHE_MODPATH_INIT(http) + +http_objects="http_core.lo http_protocol.lo http_request.lo http_filters.lo chunk_filter.lo byterange_filter.lo http_etag.lo" + +dnl mod_http should only be built as a static module for now. +dnl this will hopefully be "fixed" at some point in the future by +dnl refactoring mod_http and moving some things to the core and +dnl vice versa so that the core does not depend upon mod_http. +if test "$enable_http" = "yes"; then + enable_http="static" +elif test "$enable_http" = "shared"; then + AC_MSG_ERROR([mod_http can not be built as a shared DSO]) +fi + +APACHE_MODULE(http, HTTP protocol handling, $http_objects, , static) +APACHE_MODULE(mime, mapping of file-extension to MIME, , , yes) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/http/http_core.c b/trunk/modules/http/http_core.c new file mode 100644 index 0000000000..9dcee75697 --- /dev/null +++ b/trunk/modules/http/http_core.c @@ -0,0 +1,254 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_connection.h" +#include "http_core.h" +#include "http_protocol.h" /* For index_of_response(). Grump. */ +#include "http_request.h" + +#include "util_filter.h" +#include "util_ebcdic.h" +#include "ap_mpm.h" +#include "scoreboard.h" + +#include "mod_core.h" + +/* Handles for core filters */ +AP_DECLARE_DATA ap_filter_rec_t *ap_http_input_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_http_header_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_chunk_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_byterange_filter_handle; + +static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + cmd->server->keep_alive_timeout = apr_time_from_sec(atoi(arg)); + return NULL; +} + +static const char *set_keep_alive(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + /* We've changed it to On/Off, but used to use numbers + * so we accept anything but "Off" or "0" as "On" + */ + if (!strcasecmp(arg, "off") || !strcmp(arg, "0")) { + cmd->server->keep_alive = 0; + } + else { + cmd->server->keep_alive = 1; + } + return NULL; +} + +static const char *set_keep_alive_max(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + cmd->server->keep_alive_max = atoi(arg); + return NULL; +} + +static const command_rec http_cmds[] = { + AP_INIT_TAKE1("KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, + "Keep-Alive timeout duration (sec)"), + AP_INIT_TAKE1("MaxKeepAliveRequests", set_keep_alive_max, NULL, RSRC_CONF, + "Maximum number of Keep-Alive requests per connection, " + "or 0 for infinite"), + AP_INIT_TAKE1("KeepAlive", set_keep_alive, NULL, RSRC_CONF, + "Whether persistent connections should be On or Off"), + { NULL } +}; + +static const char *http_scheme(const request_rec *r) +{ + return "http"; +} + +static apr_port_t http_port(const request_rec *r) +{ + return DEFAULT_HTTP_PORT; +} + +static int ap_process_http_async_connection(conn_rec *c) +{ + request_rec *r; + conn_state_t *cs = c->cs; + + AP_DEBUG_ASSERT(cs->state == CONN_STATE_READ_REQUEST_LINE); + + while (cs->state == CONN_STATE_READ_REQUEST_LINE) { + ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL); + + if ((r = ap_read_request(c))) { + + c->keepalive = AP_CONN_UNKNOWN; + /* process the request if it was read without error */ + + ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r); + if (r->status == HTTP_OK) + ap_process_request(r); + + if (ap_extended_status) + ap_increment_counts(c->sbh, r); + + if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted + || ap_graceful_stop_signalled()) { + cs->state = CONN_STATE_LINGER; + } + else if (!c->data_in_input_filters) { + cs->state = CONN_STATE_CHECK_REQUEST_LINE_READABLE; + } + + /* else we are pipelining. Stay in READ_REQUEST_LINE state + * and stay in the loop + */ + + apr_pool_destroy(r->pool); + } + else { /* ap_read_request failed - client may have closed */ + cs->state = CONN_STATE_LINGER; + } + } + + return OK; +} + +static int ap_process_http_connection(conn_rec *c) +{ + request_rec *r; + int csd_set = 0; + apr_socket_t *csd = NULL; + + /* + * Read and process each request found on our connection + * until no requests are left or we decide to close. + */ + + ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL); + while ((r = ap_read_request(c)) != NULL) { + + c->keepalive = AP_CONN_UNKNOWN; + /* process the request if it was read without error */ + + ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r); + if (r->status == HTTP_OK) + ap_process_request(r); + + if (ap_extended_status) + ap_increment_counts(c->sbh, r); + + if (c->keepalive != AP_CONN_KEEPALIVE || c->aborted) + break; + + ap_update_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, r); + apr_pool_destroy(r->pool); + + if (ap_graceful_stop_signalled()) + break; + /* Go straight to select() to wait for the next request */ + if (!csd_set) { + csd = ap_get_module_config(c->conn_config, &core_module); + csd_set = 1; + } + apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1); + } + + return OK; +} + +static int http_create_request(request_rec *r) +{ + if (!r->main && !r->prev) { + ap_add_output_filter_handle(ap_byterange_filter_handle, + NULL, r, r->connection); + ap_add_output_filter_handle(ap_content_length_filter_handle, + NULL, r, r->connection); + ap_add_output_filter_handle(ap_http_header_filter_handle, + NULL, r, r->connection); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + /** + * If we ae using an MPM That Supports Async Connections, + * use a different processing function + */ + int async_mpm = 0; + if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm) == APR_SUCCESS + && async_mpm == 1) { + ap_hook_process_connection(ap_process_http_async_connection, NULL, + NULL, APR_HOOK_REALLY_LAST); + } + else { + ap_hook_process_connection(ap_process_http_connection, NULL, NULL, + APR_HOOK_REALLY_LAST); + } + + ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_http_scheme(http_scheme,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_default_port(http_port,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_create_request(http_create_request, NULL, NULL, APR_HOOK_REALLY_LAST); + ap_http_input_filter_handle = + ap_register_input_filter("HTTP_IN", ap_http_filter, + NULL, AP_FTYPE_PROTOCOL); + ap_http_header_filter_handle = + ap_register_output_filter("HTTP_HEADER", ap_http_header_filter, + NULL, AP_FTYPE_PROTOCOL); + ap_chunk_filter_handle = + ap_register_output_filter("CHUNK", ap_http_chunk_filter, + NULL, AP_FTYPE_TRANSCODE); + ap_byterange_filter_handle = + ap_register_output_filter("BYTERANGE", ap_byterange_filter, + NULL, AP_FTYPE_PROTOCOL); + ap_method_registry_init(p); +} + +module AP_MODULE_DECLARE_DATA http_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + http_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/http/http_etag.c b/trunk/modules/http/http_etag.c new file mode 100644 index 0000000000..765ee9704f --- /dev/null +++ b/trunk/modules/http/http_etag.c @@ -0,0 +1,221 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_connection.h" +#include "http_core.h" +#include "http_protocol.h" /* For index_of_response(). Grump. */ +#include "http_request.h" + +/* Generate the human-readable hex representation of an unsigned long + * (basically a faster version of 'sprintf("%lx")') + */ +#define HEX_DIGITS "0123456789abcdef" +static char *etag_ulong_to_hex(char *next, unsigned long u) +{ + int printing = 0; + int shift = sizeof(unsigned long) * 8 - 4; + do { + unsigned long next_digit = ((u >> shift) & (unsigned long)0xf); + if (next_digit) { + *next++ = HEX_DIGITS[next_digit]; + printing = 1; + } + else if (printing) { + *next++ = HEX_DIGITS[next_digit]; + } + shift -= 4; + } while (shift); + *next++ = HEX_DIGITS[u & (unsigned long)0xf]; + return next; +} + +#define ETAG_WEAK "W/" +#define CHARS_PER_UNSIGNED_LONG (sizeof(unsigned long) * 2) +/* + * Construct an entity tag (ETag) from resource information. If it's a real + * file, build in some of the file characteristics. If the modification time + * is newer than (request-time minus 1 second), mark the ETag as weak - it + * could be modified again in as short an interval. We rationalize the + * modification time we're given to keep it from being in the future. + */ +AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak) +{ + char *weak; + apr_size_t weak_len; + char *etag; + char *next; + core_dir_config *cfg; + etag_components_t etag_bits; + etag_components_t bits_added; + + cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add; + + /* + * If it's a file (or we wouldn't be here) and no ETags + * should be set for files, return an empty string and + * note it for the header-sender to ignore. + */ + if (etag_bits & ETAG_NONE) { + apr_table_setn(r->notes, "no-etag", "omit"); + return ""; + } + + if (etag_bits == ETAG_UNSET) { + etag_bits = ETAG_BACKWARD; + } + /* + * Make an ETag header out of various pieces of information. We use + * the last-modified date and, if we have a real file, the + * length and inode number - note that this doesn't have to match + * the content-length (i.e. includes), it just has to be unique + * for the file. + * + * If the request was made within a second of the last-modified date, + * we send a weak tag instead of a strong one, since it could + * be modified again later in the second, and the validation + * would be incorrect. + */ + if ((r->request_time - r->mtime > (1 * APR_USEC_PER_SEC)) && + !force_weak) { + weak = NULL; + weak_len = 0; + } + else { + weak = ETAG_WEAK; + weak_len = sizeof(ETAG_WEAK); + } + + if (r->finfo.filetype != 0) { + /* + * ETag gets set to [W/]"inode-size-mtime", modulo any + * FileETag keywords. + */ + etag = apr_palloc(r->pool, weak_len + sizeof("\"--\"") + + 3 * CHARS_PER_UNSIGNED_LONG + 1); + next = etag; + if (weak) { + while (*weak) { + *next++ = *weak++; + } + } + *next++ = '"'; + bits_added = 0; + if (etag_bits & ETAG_INODE) { + next = etag_ulong_to_hex(next, (unsigned long)r->finfo.inode); + bits_added |= ETAG_INODE; + } + if (etag_bits & ETAG_SIZE) { + if (bits_added != 0) { + *next++ = '-'; + } + next = etag_ulong_to_hex(next, (unsigned long)r->finfo.size); + bits_added |= ETAG_SIZE; + } + if (etag_bits & ETAG_MTIME) { + if (bits_added != 0) { + *next++ = '-'; + } + next = etag_ulong_to_hex(next, (unsigned long)r->mtime); + } + *next++ = '"'; + *next = '\0'; + } + else { + /* + * Not a file document, so just use the mtime: [W/]"mtime" + */ + etag = apr_palloc(r->pool, weak_len + sizeof("\"\"") + + CHARS_PER_UNSIGNED_LONG + 1); + next = etag; + if (weak) { + while (*weak) { + *next++ = *weak++; + } + } + *next++ = '"'; + next = etag_ulong_to_hex(next, (unsigned long)r->mtime); + *next++ = '"'; + *next = '\0'; + } + + return etag; +} + +AP_DECLARE(void) ap_set_etag(request_rec *r) +{ + char *etag; + char *variant_etag, *vlv; + int vlv_weak; + + if (!r->vlist_validator) { + etag = ap_make_etag(r, 0); + + /* If we get a blank etag back, don't set the header. */ + if (!etag[0]) { + return; + } + } + else { + /* If we have a variant list validator (vlv) due to the + * response being negotiated, then we create a structured + * entity tag which merges the variant etag with the variant + * list validator (vlv). This merging makes revalidation + * somewhat safer, ensures that caches which can deal with + * Vary will (eventually) be updated if the set of variants is + * changed, and is also a protocol requirement for transparent + * content negotiation. + */ + + /* if the variant list validator is weak, we make the whole + * structured etag weak. If we would not, then clients could + * have problems merging range responses if we have different + * variants with the same non-globally-unique strong etag. + */ + + vlv = r->vlist_validator; + vlv_weak = (vlv[0] == 'W'); + + variant_etag = ap_make_etag(r, vlv_weak); + + /* If we get a blank etag back, don't append vlv and stop now. */ + if (!variant_etag[0]) { + return; + } + + /* merge variant_etag and vlv into a structured etag */ + variant_etag[strlen(variant_etag) - 1] = '\0'; + if (vlv_weak) { + vlv += 3; + } + else { + vlv++; + } + etag = apr_pstrcat(r->pool, variant_etag, ";", vlv, NULL); + } + + apr_table_setn(r->headers_out, "ETag", etag); +} diff --git a/trunk/modules/http/http_filters.c b/trunk/modules/http/http_filters.c new file mode 100644 index 0000000000..0b28d0a703 --- /dev/null +++ b/trunk/modules/http/http_filters.c @@ -0,0 +1,1248 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_filter.c --- HTTP routines which either filters or deal with filters. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_signal.h" + +#define APR_WANT_STDIO /* for sscanf */ +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "util_filter.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_log.h" /* For errors detected in basic auth common + * support code... */ +#include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */ +#include "util_charset.h" +#include "util_ebcdic.h" +#include "util_time.h" + +#include "mod_core.h" + +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +static long get_chunk_size(char *); + +typedef struct http_filter_ctx { + apr_off_t remaining; + apr_off_t limit; + apr_off_t limit_used; + enum { + BODY_NONE, + BODY_LENGTH, + BODY_CHUNK + } state; + int eos_sent; +} http_ctx_t; + +/* This is the HTTP_INPUT filter for HTTP requests and responses from + * proxied servers (mod_proxy). It handles chunked and content-length + * bodies. This can only be inserted/used after the headers + * are successfully parsed. + */ +apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) +{ + apr_bucket *e; + http_ctx_t *ctx = f->ctx; + apr_status_t rv; + apr_off_t totalread; + + /* just get out of the way of things we don't want. */ + if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) { + return ap_get_brigade(f->next, b, mode, block, readbytes); + } + + if (!ctx) { + const char *tenc, *lenp; + f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx)); + ctx->state = BODY_NONE; + ctx->remaining = 0; + ctx->limit_used = 0; + ctx->eos_sent = 0; + + /* LimitRequestBody does not apply to proxied responses. + * Consider implementing this check in its own filter. + * Would adding a directive to limit the size of proxied + * responses be useful? + */ + if (!f->r->proxyreq) { + ctx->limit = ap_get_limit_req_body(f->r); + } + else { + ctx->limit = 0; + } + + tenc = apr_table_get(f->r->headers_in, "Transfer-Encoding"); + lenp = apr_table_get(f->r->headers_in, "Content-Length"); + + if (tenc) { + if (!strcasecmp(tenc, "chunked")) { + ctx->state = BODY_CHUNK; + } + } + else if (lenp) { + char *endstr; + + ctx->state = BODY_LENGTH; + errno = 0; + + /* Protects against over/underflow, non-digit chars in the + * string (excluding leading space) (the endstr checks) + * and a negative number. */ + if (apr_strtoff(&ctx->remaining, lenp, &endstr, 10) + || endstr == lenp || *endstr || ctx->remaining < 0) { + apr_bucket_brigade *bb; + + ctx->remaining = 0; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, + "Invalid Content-Length"); + + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, + f->r->pool, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); + } + + /* If we have a limit in effect and we know the C-L ahead of + * time, stop it here if it is invalid. + */ + if (ctx->limit && ctx->limit < ctx->remaining) { + apr_bucket_brigade *bb; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, + "Requested content-length of %" APR_OFF_T_FMT + " is larger than the configured limit" + " of %" APR_OFF_T_FMT, ctx->remaining, ctx->limit); + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, + f->r->pool, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); + } + } + + /* If we don't have a request entity indicated by the headers, EOS. + * (BODY_NONE is a valid intermediate state due to trailers, + * but it isn't a valid starting state.) + * + * RFC 2616 Section 4.4 note 5 states that connection-close + * is invalid for a request entity - request bodies must be + * denoted by C-L or T-E: chunked. + * + * Note that since the proxy uses this filter to handle the + * proxied *response*, proxy responses MUST be exempt. + */ + if (ctx->state == BODY_NONE && f->r->proxyreq != PROXYREQ_RESPONSE) { + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + ctx->eos_sent = 1; + return APR_SUCCESS; + } + + /* Since we're about to read data, send 100-Continue if needed. + * Only valid on chunked and C-L bodies where the C-L is > 0. */ + if ((ctx->state == BODY_CHUNK || + (ctx->state == BODY_LENGTH && ctx->remaining > 0)) && + f->r->expecting_100 && f->r->proto_num >= HTTP_VERSION(1,1)) { + char *tmp; + apr_bucket_brigade *bb; + + tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ", + ap_get_status_line(100), CRLF CRLF, NULL); + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + e = apr_bucket_pool_create(tmp, strlen(tmp), f->r->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_HEAD(bb, e); + e = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + + ap_pass_brigade(f->c->output_filters, bb); + } + + /* We can't read the chunk until after sending 100 if required. */ + if (ctx->state == BODY_CHUNK) { + char line[30]; + apr_bucket_brigade *bb; + apr_size_t len = 30; + apr_off_t brigade_length; + + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + + rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0); + + if (rv == APR_SUCCESS) { + /* We have to check the length of the brigade we got back. + * We will not accept partial lines. + */ + rv = apr_brigade_length(bb, 1, &brigade_length); + if (rv == APR_SUCCESS + && brigade_length > f->r->server->limit_req_line) { + rv = APR_ENOSPC; + } + if (rv == APR_SUCCESS) { + rv = apr_brigade_flatten(bb, line, &len); + if (rv == APR_SUCCESS) { + ctx->remaining = get_chunk_size(line); + } + } + } + apr_brigade_cleanup(bb); + + /* Detect chunksize error (such as overflow) */ + if (rv != APR_SUCCESS || ctx->remaining < 0) { + ctx->remaining = 0; /* Reset it in case we have to + * come back here later */ + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, + f->r->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); + } + + if (!ctx->remaining) { + /* Handle trailers by calling ap_get_mime_headers again! */ + ctx->state = BODY_NONE; + ap_get_mime_headers(f->r); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + ctx->eos_sent = 1; + return APR_SUCCESS; + } + } + } + + if (ctx->eos_sent) { + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + return APR_SUCCESS; + } + + if (!ctx->remaining) { + switch (ctx->state) { + case BODY_NONE: + break; + case BODY_LENGTH: + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + ctx->eos_sent = 1; + return APR_SUCCESS; + case BODY_CHUNK: + { + char line[30]; + apr_bucket_brigade *bb; + apr_size_t len = 30; + + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + + /* We need to read the CRLF after the chunk. */ + rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0); + apr_brigade_cleanup(bb); + + if (rv == APR_SUCCESS) { + /* Read the real chunk line. */ + rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0); + if (rv == APR_SUCCESS) { + rv = apr_brigade_flatten(bb, line, &len); + if (rv == APR_SUCCESS) { + ctx->remaining = get_chunk_size(line); + } + } + apr_brigade_cleanup(bb); + } + + /* Detect chunksize error (such as overflow) */ + if (rv != APR_SUCCESS || ctx->remaining < 0) { + ctx->remaining = 0; /* Reset it in case we have to + * come back here later */ + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, + NULL, f->r->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); + } + + if (!ctx->remaining) { + /* Handle trailers by calling ap_get_mime_headers again! */ + ctx->state = BODY_NONE; + ap_get_mime_headers(f->r); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + ctx->eos_sent = 1; + return APR_SUCCESS; + } + } + break; + } + } + + /* Ensure that the caller can not go over our boundary point. */ + if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) { + if (ctx->remaining < readbytes) { + readbytes = ctx->remaining; + } + AP_DEBUG_ASSERT(readbytes > 0); + } + + rv = ap_get_brigade(f->next, b, mode, block, readbytes); + + if (rv != APR_SUCCESS) { + return rv; + } + + /* How many bytes did we just read? */ + apr_brigade_length(b, 0, &totalread); + + /* If this happens, we have a bucket of unknown length. Die because + * it means our assumptions have changed. */ + AP_DEBUG_ASSERT(totalread >= 0); + + if (ctx->state != BODY_NONE) { + ctx->remaining -= totalread; + } + + /* If we have no more bytes remaining on a C-L request, + * save the callter a roundtrip to discover EOS. + */ + if (ctx->state == BODY_LENGTH && ctx->remaining == 0) { + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + } + + /* We have a limit in effect. */ + if (ctx->limit) { + /* FIXME: Note that we might get slightly confused on chunked inputs + * as we'd need to compensate for the chunk lengths which may not + * really count. This seems to be up for interpretation. */ + ctx->limit_used += totalread; + if (ctx->limit < ctx->limit_used) { + apr_bucket_brigade *bb; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, + "Read content-length of %" APR_OFF_T_FMT + " is larger than the configured limit" + " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit); + bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); + e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, + f->r->pool, + f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ctx->eos_sent = 1; + return ap_pass_brigade(f->r->output_filters, bb); + } + } + + return APR_SUCCESS; +} + +/** + * Parse a chunk extension, detect overflow. + * There are two error cases: + * 1) If the conversion would require too many bits, a -1 is returned. + * 2) If the conversion used the correct number of bits, but an overflow + * caused only the sign bit to flip, then that negative number is + * returned. + * In general, any negative number can be considered an overflow error. + */ +static long get_chunk_size(char *b) +{ + long chunksize = 0; + size_t chunkbits = sizeof(long) * 8; + + ap_xlate_proto_from_ascii(b, strlen(b)); + + /* Skip leading zeros */ + while (*b == '0') { + ++b; + } + + while (apr_isxdigit(*b) && (chunkbits > 0)) { + int xvalue = 0; + + if (*b >= '0' && *b <= '9') { + xvalue = *b - '0'; + } + else if (*b >= 'A' && *b <= 'F') { + xvalue = *b - 'A' + 0xa; + } + else if (*b >= 'a' && *b <= 'f') { + xvalue = *b - 'a' + 0xa; + } + + chunksize = (chunksize << 4) | xvalue; + chunkbits -= 4; + ++b; + } + if (apr_isxdigit(*b) && (chunkbits <= 0)) { + /* overflow */ + return -1; + } + + return chunksize; +} + +typedef struct header_struct { + apr_pool_t *pool; + apr_bucket_brigade *bb; +} header_struct; + +/* Send a single HTTP header field to the client. Note that this function + * is used in calls to table_do(), so their interfaces are co-dependent. + * In other words, don't change this one without checking table_do in alloc.c. + * It returns true unless there was a write error of some kind. + */ +static int form_header_field(header_struct *h, + const char *fieldname, const char *fieldval) +{ +#if APR_CHARSET_EBCDIC + char *headfield; + apr_size_t len; + apr_size_t name_len; + apr_size_t val_len; + char *next; + + name_len = strlen(fieldname); + val_len = strlen(fieldval); + len = name_len + val_len + 4; /* 4 for ": " plus CRLF */ + headfield = (char *)apr_palloc(h->pool, len + 1); + memcpy(headfield, fieldname, name_len); + next = headfield + name_len; + *next++ = ':'; + *next++ = ' '; + memcpy(next, fieldval, val_len); + next += val_len; + *next++ = CR; + *next++ = LF; + *next = 0; + ap_xlate_proto_to_ascii(headfield, len); + apr_brigade_write(h->bb, NULL, NULL, headfield, len); +#else + struct iovec vec[4]; + struct iovec *v = vec; + v->iov_base = (void *)fieldname; + v->iov_len = strlen(fieldname); + v++; + v->iov_base = ": "; + v->iov_len = sizeof(": ") - 1; + v++; + v->iov_base = (void *)fieldval; + v->iov_len = strlen(fieldval); + v++; + v->iov_base = CRLF; + v->iov_len = sizeof(CRLF) - 1; + apr_brigade_writev(h->bb, NULL, NULL, vec, 4); +#endif /* !APR_CHARSET_EBCDIC */ + return 1; +} + +/* This routine is called by apr_table_do and merges all instances of + * the passed field values into a single array that will be further + * processed by some later routine. Originally intended to help split + * and recombine multiple Vary fields, though it is generic to any field + * consisting of comma/space-separated tokens. + */ +static int uniq_field_values(void *d, const char *key, const char *val) +{ + apr_array_header_t *values; + char *start; + char *e; + char **strpp; + int i; + + values = (apr_array_header_t *)d; + + e = apr_pstrdup(values->pool, val); + + do { + /* Find a non-empty fieldname */ + + while (*e == ',' || apr_isspace(*e)) { + ++e; + } + if (*e == '\0') { + break; + } + start = e; + while (*e != '\0' && *e != ',' && !apr_isspace(*e)) { + ++e; + } + if (*e != '\0') { + *e++ = '\0'; + } + + /* Now add it to values if it isn't already represented. + * Could be replaced by a ap_array_strcasecmp() if we had one. + */ + for (i = 0, strpp = (char **) values->elts; i < values->nelts; + ++i, ++strpp) { + if (*strpp && strcasecmp(*strpp, start) == 0) { + break; + } + } + if (i == values->nelts) { /* if not found */ + *(char **)apr_array_push(values) = start; + } + } while (*e != '\0'); + + return 1; +} + +/* + * Since some clients choke violently on multiple Vary fields, or + * Vary fields with duplicate tokens, combine any multiples and remove + * any duplicates. + */ +static void fixup_vary(request_rec *r) +{ + apr_array_header_t *varies; + + varies = apr_array_make(r->pool, 5, sizeof(char *)); + + /* Extract all Vary fields from the headers_out, separate each into + * its comma-separated fieldname values, and then add them to varies + * if not already present in the array. + */ + apr_table_do((int (*)(void *, const char *, const char *))uniq_field_values, + (void *) varies, r->headers_out, "Vary", NULL); + + /* If we found any, replace old Vary fields with unique-ified value */ + + if (varies->nelts > 0) { + apr_table_setn(r->headers_out, "Vary", + apr_array_pstrcat(r->pool, varies, ',')); + } +} + +/* Send a request's HTTP response headers to the client. + */ +static apr_status_t send_all_header_fields(header_struct *h, + const request_rec *r) +{ + const apr_array_header_t *elts; + const apr_table_entry_t *t_elt; + const apr_table_entry_t *t_end; + struct iovec *vec; + struct iovec *vec_next; + + elts = apr_table_elts(r->headers_out); + if (elts->nelts == 0) { + return APR_SUCCESS; + } + t_elt = (const apr_table_entry_t *)(elts->elts); + t_end = t_elt + elts->nelts; + vec = (struct iovec *)apr_palloc(h->pool, 4 * elts->nelts * + sizeof(struct iovec)); + vec_next = vec; + + /* For each field, generate + * name ": " value CRLF + */ + do { + vec_next->iov_base = (void*)(t_elt->key); + vec_next->iov_len = strlen(t_elt->key); + vec_next++; + vec_next->iov_base = ": "; + vec_next->iov_len = sizeof(": ") - 1; + vec_next++; + vec_next->iov_base = (void*)(t_elt->val); + vec_next->iov_len = strlen(t_elt->val); + vec_next++; + vec_next->iov_base = CRLF; + vec_next->iov_len = sizeof(CRLF) - 1; + vec_next++; + t_elt++; + } while (t_elt < t_end); + +#if APR_CHARSET_EBCDIC + { + apr_size_t len; + char *tmp = apr_pstrcatv(r->pool, vec, vec_next - vec, &len); + ap_xlate_proto_to_ascii(tmp, len); + return apr_brigade_write(h->bb, NULL, NULL, tmp, len); + } +#else + return apr_brigade_writev(h->bb, NULL, NULL, vec, vec_next - vec); +#endif +} + +/* + * Determine the protocol to use for the response. Potentially downgrade + * to HTTP/1.0 in some situations and/or turn off keepalives. + * + * also prepare r->status_line. + */ +static void basic_http_header_check(request_rec *r, + const char **protocol) +{ + if (r->assbackwards) { + /* no such thing as a response protocol */ + return; + } + + if (!r->status_line) { + r->status_line = ap_get_status_line(r->status); + } + + /* Note that we must downgrade before checking for force responses. */ + if (r->proto_num > HTTP_VERSION(1,0) + && apr_table_get(r->subprocess_env, "downgrade-1.0")) { + r->proto_num = HTTP_VERSION(1,0); + } + + /* kludge around broken browsers when indicated by force-response-1.0 + */ + if (r->proto_num == HTTP_VERSION(1,0) + && apr_table_get(r->subprocess_env, "force-response-1.0")) { + *protocol = "HTTP/1.0"; + r->connection->keepalive = AP_CONN_CLOSE; + } + else { + *protocol = AP_SERVER_PROTOCOL; + } + +} + +/* fill "bb" with a barebones/initial HTTP response header */ +static void basic_http_header(request_rec *r, apr_bucket_brigade *bb, + const char *protocol) +{ + char *date; + const char *server; + header_struct h; + struct iovec vec[4]; + + if (r->assbackwards) { + /* there are no headers to send */ + return; + } + + /* Output the HTTP/1.x Status-Line and the Date and Server fields */ + + vec[0].iov_base = (void *)protocol; + vec[0].iov_len = strlen(protocol); + vec[1].iov_base = (void *)" "; + vec[1].iov_len = sizeof(" ") - 1; + vec[2].iov_base = (void *)(r->status_line); + vec[2].iov_len = strlen(r->status_line); + vec[3].iov_base = (void *)CRLF; + vec[3].iov_len = sizeof(CRLF) - 1; +#if APR_CHARSET_EBCDIC + { + char *tmp; + apr_size_t len; + tmp = apr_pstrcatv(r->pool, vec, 4, &len); + ap_xlate_proto_to_ascii(tmp, len); + apr_brigade_write(bb, NULL, NULL, tmp, len); + } +#else + apr_brigade_writev(bb, NULL, NULL, vec, 4); +#endif + + date = apr_palloc(r->pool, APR_RFC822_DATE_LEN); + ap_recent_rfc822_date(date, r->request_time); + + h.pool = r->pool; + h.bb = bb; + form_header_field(&h, "Date", date); + + /* keep the set-by-proxy server header, otherwise + * generate a new server header */ + if (r->proxyreq != PROXYREQ_NONE) { + server = apr_table_get(r->headers_out, "Server"); + if (server) { + form_header_field(&h, "Server", server); + } + } + else { + form_header_field(&h, "Server", ap_get_server_version()); + } + + /* unset so we don't send them again */ + apr_table_unset(r->headers_out, "Date"); /* Avoid bogosity */ + apr_table_unset(r->headers_out, "Server"); +} + +AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb) +{ + const char *protocol; + + basic_http_header_check(r, &protocol); + basic_http_header(r, bb, protocol); +} + +/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2 + * have a header parsing bug. If the terminating \r\n occur starting + * at offset 256, 257 or 258 of output then it will not properly parse + * the headers. Curiously it doesn't exhibit this problem at 512, 513. + * We are guessing that this is because their initial read of a new request + * uses a 256 byte buffer, and subsequent reads use a larger buffer. + * So the problem might exist at different offsets as well. + * + * This should also work on keepalive connections assuming they use the + * same small buffer for the first read of each new request. + * + * At any rate, we check the bytes written so far and, if we are about to + * tickle the bug, we instead insert a bogus padding header. Since the bug + * manifests as a broken image in Navigator, users blame the server. :( + * It is more expensive to check the User-Agent than it is to just add the + * bytes, so we haven't used the BrowserMatch feature here. + */ +static void terminate_header(apr_bucket_brigade *bb) +{ + char tmp[] = "X-Pad: avoid browser bug" CRLF; + char crlf[] = CRLF; + apr_off_t len; + apr_size_t buflen; + + (void) apr_brigade_length(bb, 1, &len); + + if (len >= 255 && len <= 257) { + buflen = strlen(tmp); + ap_xlate_proto_to_ascii(tmp, buflen); + apr_brigade_write(bb, NULL, NULL, tmp, buflen); + } + buflen = strlen(crlf); + ap_xlate_proto_to_ascii(crlf, buflen); + apr_brigade_write(bb, NULL, NULL, crlf, buflen); +} + +AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r) +{ + int rv; + apr_bucket_brigade *b; + header_struct h; + + if (r->method_number != M_TRACE) { + return DECLINED; + } + + /* Get the original request */ + while (r->prev) { + r = r->prev; + } + + if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY))) { + return rv; + } + + ap_set_content_type(r, "message/http"); + + /* Now we recreate the request, and echo it back */ + + b = apr_brigade_create(r->pool, r->connection->bucket_alloc); + apr_brigade_putstrs(b, NULL, NULL, r->the_request, CRLF, NULL); + h.pool = r->pool; + h.bb = b; + apr_table_do((int (*) (void *, const char *, const char *)) + form_header_field, (void *) &h, r->headers_in, NULL); + apr_brigade_puts(b, NULL, NULL, CRLF); + ap_pass_brigade(r->output_filters, b); + + return DONE; +} + +typedef struct header_filter_ctx { + int headers_sent; +} header_filter_ctx; + +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, + apr_bucket_brigade *b) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; + const char *clheader; + const char *protocol; + apr_bucket *e; + apr_bucket_brigade *b2; + header_struct h; + header_filter_ctx *ctx = f->ctx; + + AP_DEBUG_ASSERT(!r->main); + + if (r->header_only) { + if (!ctx) { + ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx)); + } + else if (ctx->headers_sent) { + apr_brigade_destroy(b); + return OK; + } + } + + for (e = APR_BRIGADE_FIRST(b); + e != APR_BRIGADE_SENTINEL(b); + e = APR_BUCKET_NEXT(e)) + { + if (e->type == &ap_bucket_type_error) { + ap_bucket_error *eb = e->data; + + ap_die(eb->status, r); + return AP_FILTER_ERROR; + } + } + + if (r->assbackwards) { + r->sent_bodyct = 1; + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, b); + } + + /* + * Now that we are ready to send a response, we need to combine the two + * header field tables into a single table. If we don't do this, our + * later attempts to set or unset a given fieldname might be bypassed. + */ + if (!apr_is_empty_table(r->err_headers_out)) { + r->headers_out = apr_table_overlay(r->pool, r->err_headers_out, + r->headers_out); + } + + /* + * Remove the 'Vary' header field if the client can't handle it. + * Since this will have nasty effects on HTTP/1.1 caches, force + * the response into HTTP/1.0 mode. + * + * Note: the force-response-1.0 should come before the call to + * basic_http_header_check() + */ + if (apr_table_get(r->subprocess_env, "force-no-vary") != NULL) { + apr_table_unset(r->headers_out, "Vary"); + r->proto_num = HTTP_VERSION(1,0); + apr_table_set(r->subprocess_env, "force-response-1.0", "1"); + } + else { + fixup_vary(r); + } + + /* + * Now remove any ETag response header field if earlier processing + * says so (such as a 'FileETag None' directive). + */ + if (apr_table_get(r->notes, "no-etag") != NULL) { + apr_table_unset(r->headers_out, "ETag"); + } + + /* determine the protocol and whether we should use keepalives. */ + basic_http_header_check(r, &protocol); + ap_set_keepalive(r); + + if (r->chunked) { + apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked"); + apr_table_unset(r->headers_out, "Content-Length"); + } + + apr_table_setn(r->headers_out, "Content-Type", + ap_make_content_type(r, r->content_type)); + + if (r->content_encoding) { + apr_table_setn(r->headers_out, "Content-Encoding", + r->content_encoding); + } + + if (!apr_is_empty_array(r->content_languages)) { + int i; + char **languages = (char **)(r->content_languages->elts); + for (i = 0; i < r->content_languages->nelts; ++i) { + apr_table_mergen(r->headers_out, "Content-Language", languages[i]); + } + } + + /* + * Control cachability for non-cachable responses if not already set by + * some other part of the server configuration. + */ + if (r->no_cache && !apr_table_get(r->headers_out, "Expires")) { + char *date = apr_palloc(r->pool, APR_RFC822_DATE_LEN); + ap_recent_rfc822_date(date, r->request_time); + apr_table_addn(r->headers_out, "Expires", date); + } + + /* This is a hack, but I can't find anyway around it. The idea is that + * we don't want to send out 0 Content-Lengths if it is a head request. + * This happens when modules try to outsmart the server, and return + * if they see a HEAD request. Apache 1.3 handlers were supposed to + * just return in that situation, and the core handled the HEAD. In + * 2.0, if a handler returns, then the core sends an EOS bucket down + * the filter stack, and the content-length filter computes a C-L of + * zero and that gets put in the headers, and we end up sending a + * zero C-L to the client. We can't just remove the C-L filter, + * because well behaved 2.0 handlers will send their data down the stack, + * and we will compute a real C-L for the head request. RBB + */ + if (r->header_only + && (clheader = apr_table_get(r->headers_out, "Content-Length")) + && !strcmp(clheader, "0")) { + apr_table_unset(r->headers_out, "Content-Length"); + } + + b2 = apr_brigade_create(r->pool, c->bucket_alloc); + basic_http_header(r, b2, protocol); + + h.pool = r->pool; + h.bb = b2; + + if (r->status == HTTP_NOT_MODIFIED) { + apr_table_do((int (*)(void *, const char *, const char *)) form_header_field, + (void *) &h, r->headers_out, + "Connection", + "Keep-Alive", + "ETag", + "Content-Location", + "Expires", + "Cache-Control", + "Vary", + "Warning", + "WWW-Authenticate", + "Proxy-Authenticate", + "Set-Cookie", + "Set-Cookie2", + NULL); + } + else { + send_all_header_fields(&h, r); + } + + terminate_header(b2); + + ap_pass_brigade(f->next, b2); + + if (r->header_only) { + apr_brigade_destroy(b); + ctx->headers_sent = 1; + return OK; + } + + r->sent_bodyct = 1; /* Whatever follows is real body stuff... */ + + if (r->chunked) { + /* We can't add this filter until we have already sent the headers. + * If we add it before this point, then the headers will be chunked + * as well, and that is just wrong. + */ + ap_add_output_filter("CHUNK", NULL, r, r->connection); + } + + /* Don't remove this filter until after we have added the CHUNK filter. + * Otherwise, f->next won't be the CHUNK filter and thus the first + * brigade won't be chunked properly. + */ + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, b); +} + +/* In HTTP/1.1, any method can have a body. However, most GET handlers + * wouldn't know what to do with a request body if they received one. + * This helper routine tests for and reads any message body in the request, + * simply discarding whatever it receives. We need to do this because + * failing to read the request body would cause it to be interpreted + * as the next request on a persistent connection. + * + * Since we return an error status if the request is malformed, this + * routine should be called at the beginning of a no-body handler, e.g., + * + * if ((retval = ap_discard_request_body(r)) != OK) { + * return retval; + * } + */ +AP_DECLARE(int) ap_discard_request_body(request_rec *r) +{ + apr_bucket_brigade *bb; + int rv, seen_eos; + + /* Sometimes we'll get in a state where the input handling has + * detected an error where we want to drop the connection, so if + * that's the case, don't read the data as that is what we're trying + * to avoid. + * + * This function is also a no-op on a subrequest. + */ + if (r->main || r->connection->keepalive == AP_CONN_CLOSE || + ap_status_drops_connection(r->status)) { + return OK; + } + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + seen_eos = 0; + do { + apr_bucket *bucket; + + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, HUGE_STRING_LEN); + + if (rv != APR_SUCCESS) { + /* FIXME: If we ever have a mapping from filters (apr_status_t) + * to HTTP error codes, this would be a good place for them. + * + * If we received the special case AP_FILTER_ERROR, it means + * that the filters have already handled this error. + * Otherwise, we should assume we have a bad request. + */ + if (rv == AP_FILTER_ERROR) { + apr_brigade_destroy(bb); + return rv; + } + else { + apr_brigade_destroy(bb); + return HTTP_BAD_REQUEST; + } + } + + for (bucket = APR_BRIGADE_FIRST(bb); + bucket != APR_BRIGADE_SENTINEL(bb); + bucket = APR_BUCKET_NEXT(bucket)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + /* These are metadata buckets. */ + if (bucket->length == 0) { + continue; + } + + /* We MUST read because in case we have an unknown-length + * bucket or one that morphs, we want to exhaust it. + */ + rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + apr_brigade_destroy(bb); + return HTTP_BAD_REQUEST; + } + } + apr_brigade_cleanup(bb); + } while (!seen_eos); + + return OK; +} + +/* Here we deal with getting the request message body from the client. + * Whether or not the request contains a body is signaled by the presence + * of a non-zero Content-Length or by a Transfer-Encoding: chunked. + * + * Note that this is more complicated than it was in Apache 1.1 and prior + * versions, because chunked support means that the module does less. + * + * The proper procedure is this: + * + * 1. Call ap_setup_client_block() near the beginning of the request + * handler. This will set up all the necessary properties, and will + * return either OK, or an error code. If the latter, the module should + * return that error code. The second parameter selects the policy to + * apply if the request message indicates a body, and how a chunked + * transfer-coding should be interpreted. Choose one of + * + * REQUEST_NO_BODY Send 413 error if message has any body + * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length + * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me. + * + * In order to use the last two options, the caller MUST provide a buffer + * large enough to hold a chunk-size line, including any extensions. + * + * 2. When you are ready to read a body (if any), call ap_should_client_block(). + * This will tell the module whether or not to read input. If it is 0, + * the module should assume that there is no message body to read. + * + * 3. Finally, call ap_get_client_block in a loop. Pass it a buffer and its size. + * It will put data into the buffer (not necessarily a full buffer), and + * return the length of the input block. When it is done reading, it will + * return 0 if EOF, or -1 if there was an error. + * If an error occurs on input, we force an end to keepalive. + * + * This step also sends a 100 Continue response to HTTP/1.1 clients if appropriate. + */ + +AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy) +{ + const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); + const char *lenp = apr_table_get(r->headers_in, "Content-Length"); + + r->read_body = read_policy; + r->read_chunked = 0; + r->remaining = 0; + + if (tenc) { + if (strcasecmp(tenc, "chunked")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Unknown Transfer-Encoding %s", tenc); + return HTTP_NOT_IMPLEMENTED; + } + if (r->read_body == REQUEST_CHUNKED_ERROR) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "chunked Transfer-Encoding forbidden: %s", r->uri); + return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED; + } + + r->read_chunked = 1; + } + else if (lenp) { + char *endstr; + + if (apr_strtoff(&r->remaining, lenp, &endstr, 10) + || *endstr || r->remaining < 0) { + r->remaining = 0; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid Content-Length"); + return HTTP_BAD_REQUEST; + } + } + + if ((r->read_body == REQUEST_NO_BODY) + && (r->read_chunked || (r->remaining > 0))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s with body is not allowed for %s", r->method, r->uri); + return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + +#ifdef AP_DEBUG + { + /* Make sure ap_getline() didn't leave any droppings. */ + core_request_config *req_cfg = + (core_request_config *)ap_get_module_config(r->request_config, + &core_module); + AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(req_cfg->bb)); + } +#endif + + return OK; +} + +AP_DECLARE(int) ap_should_client_block(request_rec *r) +{ + /* First check if we have already read the request body */ + + if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) { + return 0; + } + + return 1; +} + +/* get_client_block is called in a loop to get the request message body. + * This is quite simple if the client includes a content-length + * (the normal case), but gets messy if the body is chunked. Note that + * r->remaining is used to maintain state across calls and that + * r->read_length is the total number of bytes given to the caller + * across all invocations. It is messy because we have to be careful not + * to read past the data provided by the client, since these reads block. + * Returns 0 on End-of-body, -1 on error or premature chunk end. + * + */ +AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, + apr_size_t bufsiz) +{ + apr_status_t rv; + apr_bucket_brigade *bb; + + if (r->remaining < 0 || (!r->read_chunked && r->remaining == 0)) { + return 0; + } + + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + if (bb == NULL) { + r->connection->keepalive = AP_CONN_CLOSE; + return -1; + } + + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES, + APR_BLOCK_READ, bufsiz); + + /* We lose the failure code here. This is why ap_get_client_block should + * not be used. + */ + if (rv != APR_SUCCESS) { + /* if we actually fail here, we want to just return and + * stop trying to read data from the client. + */ + r->connection->keepalive = AP_CONN_CLOSE; + apr_brigade_destroy(bb); + return -1; + } + + /* If this fails, it means that a filter is written incorrectly and that + * it needs to learn how to properly handle APR_BLOCK_READ requests by + * returning data when requested. + */ + AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(bb)); + + /* Check to see if EOS in the brigade. + * + * If so, we have to leave a nugget for the *next* ap_get_client_block + * call to return 0. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + if (r->read_chunked) { + r->remaining = -1; + } + else { + r->remaining = 0; + } + } + + rv = apr_brigade_flatten(bb, buffer, &bufsiz); + if (rv != APR_SUCCESS) { + apr_brigade_destroy(bb); + return -1; + } + + /* XXX yank me? */ + r->read_length += bufsiz; + + apr_brigade_destroy(bb); + return bufsiz; +} + diff --git a/trunk/modules/http/http_protocol.c b/trunk/modules/http/http_protocol.c new file mode 100644 index 0000000000..d4b0429f52 --- /dev/null +++ b/trunk/modules/http/http_protocol.c @@ -0,0 +1,1400 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_protocol.c --- routines which directly communicate with the client. + * + * Code originally by Rob McCool; much redone by Robert S. Thau + * and the Apache Software Foundation. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_signal.h" + +#define APR_WANT_STDIO /* for sscanf */ +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "util_filter.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_log.h" /* For errors detected in basic auth common + * support code... */ +#include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */ +#include "util_charset.h" +#include "util_ebcdic.h" +#include "util_time.h" + +#include "mod_core.h" + +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +/* New Apache routine to map status codes into array indicies + * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ... + * The number of status lines must equal the value of RESPONSE_CODES (httpd.h) + * and must be listed in order. + */ + +#ifdef UTS21 +/* The second const triggers an assembler bug on UTS 2.1. + * Another workaround is to move some code out of this file into another, + * but this is easier. Dave Dykstra, 3/31/99 + */ +static const char * status_lines[RESPONSE_CODES] = +#else +static const char * const status_lines[RESPONSE_CODES] = +#endif +{ + "100 Continue", + "101 Switching Protocols", + "102 Processing", +#define LEVEL_200 3 + "200 OK", + "201 Created", + "202 Accepted", + "203 Non-Authoritative Information", + "204 No Content", + "205 Reset Content", + "206 Partial Content", + "207 Multi-Status", +#define LEVEL_300 11 + "300 Multiple Choices", + "301 Moved Permanently", + "302 Found", + "303 See Other", + "304 Not Modified", + "305 Use Proxy", + "306 unused", + "307 Temporary Redirect", +#define LEVEL_400 19 + "400 Bad Request", + "401 Authorization Required", + "402 Payment Required", + "403 Forbidden", + "404 Not Found", + "405 Method Not Allowed", + "406 Not Acceptable", + "407 Proxy Authentication Required", + "408 Request Time-out", + "409 Conflict", + "410 Gone", + "411 Length Required", + "412 Precondition Failed", + "413 Request Entity Too Large", + "414 Request-URI Too Large", + "415 Unsupported Media Type", + "416 Requested Range Not Satisfiable", + "417 Expectation Failed", + "418 unused", + "419 unused", + "420 unused", + "421 unused", + "422 Unprocessable Entity", + "423 Locked", + "424 Failed Dependency", + /* This is a hack, but it is required for ap_index_of_response + * to work with 426. + */ + "425 No code", + "426 Upgrade Required", +#define LEVEL_500 46 + "500 Internal Server Error", + "501 Method Not Implemented", + "502 Bad Gateway", + "503 Service Temporarily Unavailable", + "504 Gateway Time-out", + "505 HTTP Version Not Supported", + "506 Variant Also Negotiates", + "507 Insufficient Storage", + "508 unused", + "509 unused", + "510 Not Extended" +}; + +APR_HOOK_STRUCT( + APR_HOOK_LINK(insert_error_filter) +) + +AP_IMPLEMENT_HOOK_VOID(insert_error_filter, (request_rec *r), (r)) + +/* The index of the first bit field that is used to index into a limit + * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST. + */ +#define METHOD_NUMBER_FIRST (M_INVALID + 1) + +/* The max method number. Method numbers are used to shift bitmasks, + * so this cannot exceed 63, and all bits high is equal to -1, which is a + * special flag, so the last bit used has index 62. + */ +#define METHOD_NUMBER_LAST 62 + + +AP_DECLARE(int) ap_set_keepalive(request_rec *r) +{ + int ka_sent = 0; + int wimpy = ap_find_token(r->pool, + apr_table_get(r->headers_out, "Connection"), + "close"); + const char *conn = apr_table_get(r->headers_in, "Connection"); + + /* The following convoluted conditional determines whether or not + * the current connection should remain persistent after this response + * (a.k.a. HTTP Keep-Alive) and whether or not the output message + * body should use the HTTP/1.1 chunked transfer-coding. In English, + * + * IF we have not marked this connection as errored; + * and the response body has a defined length due to the status code + * being 304 or 204, the request method being HEAD, already + * having defined Content-Length or Transfer-Encoding: chunked, or + * the request version being HTTP/1.1 and thus capable of being set + * as chunked [we know the (r->chunked = 1) side-effect is ugly]; + * and the server configuration enables keep-alive; + * and the server configuration has a reasonable inter-request timeout; + * and there is no maximum # requests or the max hasn't been reached; + * and the response status does not require a close; + * and the response generator has not already indicated close; + * and the client did not request non-persistence (Connection: close); + * and we haven't been configured to ignore the buggy twit + * or they're a buggy twit coming through a HTTP/1.1 proxy + * and the client is requesting an HTTP/1.0-style keep-alive + * or the client claims to be HTTP/1.1 compliant (perhaps a proxy); + * THEN we can be persistent, which requires more headers be output. + * + * Note that the condition evaluation order is extremely important. + */ + if ((r->connection->keepalive != AP_CONN_CLOSE) + && ((r->status == HTTP_NOT_MODIFIED) + || (r->status == HTTP_NO_CONTENT) + || r->header_only + || apr_table_get(r->headers_out, "Content-Length") + || ap_find_last_token(r->pool, + apr_table_get(r->headers_out, + "Transfer-Encoding"), + "chunked") + || ((r->proto_num >= HTTP_VERSION(1,1)) + && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */ + && r->server->keep_alive + && (r->server->keep_alive_timeout > 0) + && ((r->server->keep_alive_max == 0) + || (r->server->keep_alive_max > r->connection->keepalives)) + && !ap_status_drops_connection(r->status) + && !wimpy + && !ap_find_token(r->pool, conn, "close") + && (!apr_table_get(r->subprocess_env, "nokeepalive") + || apr_table_get(r->headers_in, "Via")) + && ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) + || (r->proto_num >= HTTP_VERSION(1,1)))) { + int left = r->server->keep_alive_max - r->connection->keepalives; + + r->connection->keepalive = AP_CONN_KEEPALIVE; + r->connection->keepalives++; + + /* If they sent a Keep-Alive token, send one back */ + if (ka_sent) { + if (r->server->keep_alive_max) { + apr_table_setn(r->headers_out, "Keep-Alive", + apr_psprintf(r->pool, "timeout=%d, max=%d", + (int)apr_time_sec(r->server->keep_alive_timeout), + left)); + } + else { + apr_table_setn(r->headers_out, "Keep-Alive", + apr_psprintf(r->pool, "timeout=%d", + (int)apr_time_sec(r->server->keep_alive_timeout))); + } + apr_table_mergen(r->headers_out, "Connection", "Keep-Alive"); + } + + return 1; + } + + /* Otherwise, we need to indicate that we will be closing this + * connection immediately after the current response. + * + * We only really need to send "close" to HTTP/1.1 clients, but we + * always send it anyway, because a broken proxy may identify itself + * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag + * to a HTTP/1.1 client. Better safe than sorry. + */ + if (!wimpy) { + apr_table_mergen(r->headers_out, "Connection", "close"); + } + + r->connection->keepalive = AP_CONN_CLOSE; + + return 0; +} + +AP_DECLARE(int) ap_meets_conditions(request_rec *r) +{ + const char *etag; + const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch; + apr_time_t tmp_time; + apr_int64_t mtime; + int not_modified = 0; + + /* Check for conditional requests --- note that we only want to do + * this if we are successful so far and we are not processing a + * subrequest or an ErrorDocument. + * + * The order of the checks is important, since ETag checks are supposed + * to be more accurate than checks relative to the modification time. + * However, not all documents are guaranteed to *have* ETags, and some + * might have Last-Modified values w/o ETags, so this gets a little + * complicated. + */ + + if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) { + return OK; + } + + etag = apr_table_get(r->headers_out, "ETag"); + + /* All of our comparisons must be in seconds, because that's the + * highest time resolution the HTTP specification allows. + */ + /* XXX: we should define a "time unset" constant */ + tmp_time = ((r->mtime != 0) ? r->mtime : apr_time_now()); + mtime = apr_time_sec(tmp_time); + + /* If an If-Match request-header field was given + * 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 = apr_table_get(r->headers_in, "If-Match")) != NULL) { + if (if_match[0] != '*' + && (etag == NULL || etag[0] == 'W' + || !ap_find_list_item(r->pool, if_match, etag))) { + return HTTP_PRECONDITION_FAILED; + } + } + else { + /* Else if a valid If-Unmodified-Since request-header field was given + * AND the requested resource has been modified since the time + * specified in this field, then the server MUST + * respond with a status of 412 (Precondition Failed). + */ + if_unmodified = apr_table_get(r->headers_in, "If-Unmodified-Since"); + if (if_unmodified != NULL) { + apr_time_t ius = apr_date_parse_http(if_unmodified); + + if ((ius != APR_DATE_BAD) && (mtime > apr_time_sec(ius))) { + return HTTP_PRECONDITION_FAILED; + } + } + } + + /* If an If-None-Match request-header field was given + * 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 = apr_table_get(r->headers_in, "If-None-Match"); + if (if_nonematch != NULL) { + if (r->method_number == M_GET) { + if (if_nonematch[0] == '*') { + not_modified = 1; + } + else if (etag != NULL) { + if (apr_table_get(r->headers_in, "Range")) { + not_modified = etag[0] != 'W' + && ap_find_list_item(r->pool, + if_nonematch, etag); + } + else { + not_modified = ap_find_list_item(r->pool, + if_nonematch, etag); + } + } + } + else if (if_nonematch[0] == '*' + || (etag != NULL + && ap_find_list_item(r->pool, if_nonematch, etag))) { + return HTTP_PRECONDITION_FAILED; + } + } + + /* If a valid If-Modified-Since request-header field was given + * AND it is a GET or HEAD request + * AND the requested resource has not been modified since the time + * specified in this field, then the server MUST + * respond with a status of 304 (Not Modified). + * A date later than the server's current request time is invalid. + */ + if (r->method_number == M_GET + && (not_modified || !if_nonematch) + && (if_modified_since = + apr_table_get(r->headers_in, + "If-Modified-Since")) != NULL) { + apr_time_t ims_time; + apr_int64_t ims, reqtime; + + ims_time = apr_date_parse_http(if_modified_since); + ims = apr_time_sec(ims_time); + reqtime = apr_time_sec(r->request_time); + + not_modified = ims >= mtime && ims <= reqtime; + } + + if (not_modified) { + return HTTP_NOT_MODIFIED; + } + + return OK; +} + +/** + * Singleton registry of additional methods. This maps new method names + * such as "MYGET" to methnums, which are int offsets into bitmasks. + * + * This follows the same technique as standard M_GET, M_POST, etc. These + * are dynamically assigned when modules are loaded and + * directives are processed. + */ +static apr_hash_t *methods_registry = NULL; +static int cur_method_number = METHOD_NUMBER_FIRST; + +/* internal function to register one method/number pair */ +static void register_one_method(apr_pool_t *p, const char *methname, + int methnum) +{ + int *pnum = apr_palloc(p, sizeof(*pnum)); + + *pnum = methnum; + apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum); +} + +/* This internal function is used to clear the method registry + * and reset the cur_method_number counter. + */ +static apr_status_t ap_method_registry_destroy(void *notused) +{ + methods_registry = NULL; + cur_method_number = METHOD_NUMBER_FIRST; + return APR_SUCCESS; +} + +AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p) +{ + methods_registry = apr_hash_make(p); + apr_pool_cleanup_register(p, NULL, + ap_method_registry_destroy, + apr_pool_cleanup_null); + + /* put all the standard methods into the registry hash to ease the + mapping operations between name and number */ + register_one_method(p, "GET", M_GET); + register_one_method(p, "PUT", M_PUT); + register_one_method(p, "POST", M_POST); + register_one_method(p, "DELETE", M_DELETE); + register_one_method(p, "CONNECT", M_CONNECT); + register_one_method(p, "OPTIONS", M_OPTIONS); + register_one_method(p, "TRACE", M_TRACE); + register_one_method(p, "PATCH", M_PATCH); + register_one_method(p, "PROPFIND", M_PROPFIND); + register_one_method(p, "PROPPATCH", M_PROPPATCH); + register_one_method(p, "MKCOL", M_MKCOL); + register_one_method(p, "COPY", M_COPY); + register_one_method(p, "MOVE", M_MOVE); + register_one_method(p, "LOCK", M_LOCK); + register_one_method(p, "UNLOCK", M_UNLOCK); + register_one_method(p, "VERSION-CONTROL", M_VERSION_CONTROL); + register_one_method(p, "CHECKOUT", M_CHECKOUT); + register_one_method(p, "UNCHECKOUT", M_UNCHECKOUT); + register_one_method(p, "CHECKIN", M_CHECKIN); + register_one_method(p, "UPDATE", M_UPDATE); + register_one_method(p, "LABEL", M_LABEL); + register_one_method(p, "REPORT", M_REPORT); + register_one_method(p, "MKWORKSPACE", M_MKWORKSPACE); + register_one_method(p, "MKACTIVITY", M_MKACTIVITY); + register_one_method(p, "BASELINE-CONTROL", M_BASELINE_CONTROL); + register_one_method(p, "MERGE", M_MERGE); +} + +AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname) +{ + int *methnum; + + if (methods_registry == NULL) { + ap_method_registry_init(p); + } + + if (methname == NULL) { + return M_INVALID; + } + + /* Check if the method was previously registered. If it was + * return the associated method number. + */ + methnum = (int *)apr_hash_get(methods_registry, methname, + APR_HASH_KEY_STRING); + if (methnum != NULL) + return *methnum; + + if (cur_method_number > METHOD_NUMBER_LAST) { + /* The method registry has run out of dynamically + * assignable method numbers. Log this and return M_INVALID. + */ + ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, + "Maximum new request methods %d reached while " + "registering method %s.", + METHOD_NUMBER_LAST, methname); + return M_INVALID; + } + + register_one_method(p, methname, cur_method_number); + return cur_method_number++; +} + +#define UNKNOWN_METHOD (-1) + +static int lookup_builtin_method(const char *method, apr_size_t len) +{ + /* Note: the following code was generated by the "shilka" tool from + the "cocom" parsing/compilation toolkit. It is an optimized lookup + based on analysis of the input keywords. Postprocessing was done + on the shilka output, but the basic structure and analysis is + from there. Should new HTTP methods be added, then manual insertion + into this code is fine, or simply re-running the shilka tool on + the appropriate input. */ + + /* Note: it is also quite reasonable to just use our method_registry, + but I'm assuming (probably incorrectly) we want more speed here + (based on the optimizations the previous code was doing). */ + + switch (len) + { + case 3: + switch (method[0]) + { + case 'P': + return (method[1] == 'U' + && method[2] == 'T' + ? M_PUT : UNKNOWN_METHOD); + case 'G': + return (method[1] == 'E' + && method[2] == 'T' + ? M_GET : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 4: + switch (method[0]) + { + case 'H': + return (method[1] == 'E' + && method[2] == 'A' + && method[3] == 'D' + ? M_GET : UNKNOWN_METHOD); + case 'P': + return (method[1] == 'O' + && method[2] == 'S' + && method[3] == 'T' + ? M_POST : UNKNOWN_METHOD); + case 'M': + return (method[1] == 'O' + && method[2] == 'V' + && method[3] == 'E' + ? M_MOVE : UNKNOWN_METHOD); + case 'L': + return (method[1] == 'O' + && method[2] == 'C' + && method[3] == 'K' + ? M_LOCK : UNKNOWN_METHOD); + case 'C': + return (method[1] == 'O' + && method[2] == 'P' + && method[3] == 'Y' + ? M_COPY : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 5: + switch (method[2]) + { + case 'T': + return (memcmp(method, "PATCH", 5) == 0 + ? M_PATCH : UNKNOWN_METHOD); + case 'R': + return (memcmp(method, "MERGE", 5) == 0 + ? M_MERGE : UNKNOWN_METHOD); + case 'C': + return (memcmp(method, "MKCOL", 5) == 0 + ? M_MKCOL : UNKNOWN_METHOD); + case 'B': + return (memcmp(method, "LABEL", 5) == 0 + ? M_LABEL : UNKNOWN_METHOD); + case 'A': + return (memcmp(method, "TRACE", 5) == 0 + ? M_TRACE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 6: + switch (method[0]) + { + case 'U': + switch (method[5]) + { + case 'K': + return (memcmp(method, "UNLOCK", 6) == 0 + ? M_UNLOCK : UNKNOWN_METHOD); + case 'E': + return (memcmp(method, "UPDATE", 6) == 0 + ? M_UPDATE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + case 'R': + return (memcmp(method, "REPORT", 6) == 0 + ? M_REPORT : UNKNOWN_METHOD); + case 'D': + return (memcmp(method, "DELETE", 6) == 0 + ? M_DELETE : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 7: + switch (method[1]) + { + case 'P': + return (memcmp(method, "OPTIONS", 7) == 0 + ? M_OPTIONS : UNKNOWN_METHOD); + case 'O': + return (memcmp(method, "CONNECT", 7) == 0 + ? M_CONNECT : UNKNOWN_METHOD); + case 'H': + return (memcmp(method, "CHECKIN", 7) == 0 + ? M_CHECKIN : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 8: + switch (method[0]) + { + case 'P': + return (memcmp(method, "PROPFIND", 8) == 0 + ? M_PROPFIND : UNKNOWN_METHOD); + case 'C': + return (memcmp(method, "CHECKOUT", 8) == 0 + ? M_CHECKOUT : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 9: + return (memcmp(method, "PROPPATCH", 9) == 0 + ? M_PROPPATCH : UNKNOWN_METHOD); + + case 10: + switch (method[0]) + { + case 'U': + return (memcmp(method, "UNCHECKOUT", 10) == 0 + ? M_UNCHECKOUT : UNKNOWN_METHOD); + case 'M': + return (memcmp(method, "MKACTIVITY", 10) == 0 + ? M_MKACTIVITY : UNKNOWN_METHOD); + default: + return UNKNOWN_METHOD; + } + + case 11: + return (memcmp(method, "MKWORKSPACE", 11) == 0 + ? M_MKWORKSPACE : UNKNOWN_METHOD); + + case 15: + return (memcmp(method, "VERSION-CONTROL", 15) == 0 + ? M_VERSION_CONTROL : UNKNOWN_METHOD); + + case 16: + return (memcmp(method, "BASELINE-CONTROL", 16) == 0 + ? M_BASELINE_CONTROL : UNKNOWN_METHOD); + + default: + return UNKNOWN_METHOD; + } + + /* NOTREACHED */ +} + +/* Get the method number associated with the given string, assumed to + * contain an HTTP method. Returns M_INVALID if not recognized. + * + * This is the first step toward placing method names in a configurable + * list. Hopefully it (and other routines) can eventually be moved to + * something like a mod_http_methods.c, complete with config stuff. + */ +AP_DECLARE(int) ap_method_number_of(const char *method) +{ + int len = strlen(method); + int which = lookup_builtin_method(method, len); + + if (which != UNKNOWN_METHOD) + return which; + + /* check if the method has been dynamically registered */ + if (methods_registry != NULL) { + int *methnum = apr_hash_get(methods_registry, method, len); + + if (methnum != NULL) { + return *methnum; + } + } + + return M_INVALID; +} + +/* + * Turn a known method number into a name. + */ +AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum) +{ + apr_hash_index_t *hi = apr_hash_first(p, methods_registry); + + /* scan through the hash table, looking for a value that matches + the provided method number. */ + for (; hi; hi = apr_hash_next(hi)) { + const void *key; + void *val; + + apr_hash_this(hi, &key, NULL, &val); + if (*(int *)val == methnum) + return key; + } + + /* it wasn't found in the hash */ + return NULL; +} + +/* The index is found by its offset from the x00 code of each level. + * Although this is fast, it will need to be replaced if some nutcase + * decides to define a high-numbered code before the lower numbers. + * If that sad event occurs, replace the code below with a linear search + * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1]; + */ +AP_DECLARE(int) ap_index_of_response(int status) +{ + static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400, + LEVEL_500, RESPONSE_CODES}; + int i, pos; + + if (status < 100) { /* Below 100 is illegal for HTTP status */ + return LEVEL_500; + } + + for (i = 0; i < 5; i++) { + status -= 100; + if (status < 100) { + pos = (status + shortcut[i]); + if (pos < shortcut[i + 1]) { + return pos; + } + else { + return LEVEL_500; /* status unknown (falls in gap) */ + } + } + } + return LEVEL_500; /* 600 or above is also illegal */ +} + +AP_DECLARE(const char *) ap_get_status_line(int status) +{ + return status_lines[ap_index_of_response(status)]; +} + +/* Build the Allow field-value from the request handler method mask. + * Note that we always allow TRACE, since it is handled below. + */ +static char *make_allow(request_rec *r) +{ + char *list; + apr_int64_t mask; + apr_array_header_t *allow = apr_array_make(r->pool, 10, sizeof(char *)); + apr_hash_index_t *hi = apr_hash_first(r->pool, methods_registry); + + mask = r->allowed_methods->method_mask; + + for (; hi; hi = apr_hash_next(hi)) { + const void *key; + void *val; + + apr_hash_this(hi, &key, NULL, &val); + if ((mask & (AP_METHOD_BIT << *(int *)val)) != 0) { + *(const char **)apr_array_push(allow) = key; + + /* the M_GET method actually refers to two methods */ + if (*(int *)val == M_GET) + *(const char **)apr_array_push(allow) = "HEAD"; + } + } + + /* TRACE is always allowed */ + *(const char **)apr_array_push(allow) = "TRACE"; + + list = apr_array_pstrcat(r->pool, allow, ','); + + /* ### this is rather annoying. we should enforce registration of + ### these methods */ + if ((mask & (AP_METHOD_BIT << M_INVALID)) + && (r->allowed_methods->method_list != NULL) + && (r->allowed_methods->method_list->nelts != 0)) { + int i; + char **xmethod = (char **) r->allowed_methods->method_list->elts; + + /* + * Append all of the elements of r->allowed_methods->method_list + */ + for (i = 0; i < r->allowed_methods->method_list->nelts; ++i) { + list = apr_pstrcat(r->pool, list, ",", xmethod[i], NULL); + } + } + + return list; +} + +AP_DECLARE(int) ap_send_http_options(request_rec *r) +{ + if (r->assbackwards) { + return DECLINED; + } + + apr_table_setn(r->headers_out, "Allow", make_allow(r)); + + /* the request finalization will send an EOS, which will flush all + * the headers out (including the Allow header) + */ + + return OK; +} + +AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct) +{ + if (!ct) { + r->content_type = NULL; + } + else if (!r->content_type || strcmp(r->content_type, ct)) { + r->content_type = ct; + + /* Insert filters requested by the AddOutputFiltersByType + * configuration directive. Content-type filters must be + * inserted after the content handlers have run because + * only then, do we reliably know the content-type. + */ + ap_add_output_filters_by_type(r); + } +} + +static const char *add_optional_notes(request_rec *r, + const char *prefix, + const char *key, + const char *suffix) +{ + const char *notes, *result; + + if ((notes = apr_table_get(r->notes, key)) == NULL) { + result = apr_pstrcat(r->pool, prefix, suffix, NULL); + } + else { + result = apr_pstrcat(r->pool, prefix, notes, suffix, NULL); + } + + return result; +} + +/* construct and return the default error message for a given + * HTTP defined error code + */ +static const char *get_canned_error_string(int status, + request_rec *r, + const char *location) +{ + apr_pool_t *p = r->pool; + const char *error_notes, *h1, *s1; + + switch (status) { + case HTTP_MOVED_PERMANENTLY: + case HTTP_MOVED_TEMPORARILY: + case HTTP_TEMPORARY_REDIRECT: + return(apr_pstrcat(p, + "

    The document has moved pool, location), + "\">here.

    \n", + NULL)); + case HTTP_SEE_OTHER: + return(apr_pstrcat(p, + "

    The answer to your request is located " + "pool, location), + "\">here.

    \n", + NULL)); + case HTTP_USE_PROXY: + return(apr_pstrcat(p, + "

    This resource is only accessible " + "through the proxy\n", + ap_escape_html(r->pool, location), + "
    \nYou will need to configure " + "your client to use that proxy.

    \n", + NULL)); + case HTTP_PROXY_AUTHENTICATION_REQUIRED: + case HTTP_UNAUTHORIZED: + return("

    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.

    \n"); + case HTTP_BAD_REQUEST: + return(add_optional_notes(r, + "

    Your browser sent a request that " + "this server could not understand.
    \n", + "error-notes", + "

    \n")); + case HTTP_FORBIDDEN: + return(apr_pstrcat(p, + "

    You don't have permission to access ", + ap_escape_html(r->pool, r->uri), + "\non this server.

    \n", + NULL)); + case HTTP_NOT_FOUND: + return(apr_pstrcat(p, + "

    The requested URL ", + ap_escape_html(r->pool, r->uri), + " was not found on this server.

    \n", + NULL)); + case HTTP_METHOD_NOT_ALLOWED: + return(apr_pstrcat(p, + "

    The requested method ", r->method, + " is not allowed for the URL ", + ap_escape_html(r->pool, r->uri), + ".

    \n", + NULL)); + case HTTP_NOT_ACCEPTABLE: + s1 = apr_pstrcat(p, + "

    An appropriate representation of the " + "requested resource ", + ap_escape_html(r->pool, r->uri), + " could not be found on this server.

    \n", + NULL); + return(add_optional_notes(r, s1, "variant-list", "")); + case HTTP_MULTIPLE_CHOICES: + return(add_optional_notes(r, "", "variant-list", "")); + case HTTP_LENGTH_REQUIRED: + s1 = apr_pstrcat(p, + "

    A request of the requested method ", + r->method, + " requires a valid Content-length.
    \n", + NULL); + return(add_optional_notes(r, s1, "error-notes", "

    \n")); + case HTTP_PRECONDITION_FAILED: + return(apr_pstrcat(p, + "

    The precondition on the request " + "for the URL ", + ap_escape_html(r->pool, r->uri), + " evaluated to false.

    \n", + NULL)); + case HTTP_NOT_IMPLEMENTED: + s1 = apr_pstrcat(p, + "

    ", + ap_escape_html(r->pool, r->method), " to ", + ap_escape_html(r->pool, r->uri), + " not supported.
    \n", + NULL); + return(add_optional_notes(r, s1, "error-notes", "

    \n")); + case HTTP_BAD_GATEWAY: + s1 = "

    The proxy server received an invalid" CRLF + "response from an upstream server.
    " CRLF; + return(add_optional_notes(r, s1, "error-notes", "

    \n")); + case HTTP_VARIANT_ALSO_VARIES: + return(apr_pstrcat(p, + "

    A variant for the requested " + "resource\n

    \n",
    +                           ap_escape_html(r->pool, r->uri),
    +                           "\n
    \nis itself a negotiable resource. " + "This indicates a configuration error.

    \n", + NULL)); + case HTTP_REQUEST_TIME_OUT: + return("

    Server timeout waiting for the HTTP request from the client.

    \n"); + case HTTP_GONE: + return(apr_pstrcat(p, + "

    The requested resource
    ", + ap_escape_html(r->pool, r->uri), + "
    \nis no longer available on this server " + "and there is no forwarding address.\n" + "Please remove all references to this " + "resource.

    \n", + NULL)); + case HTTP_REQUEST_ENTITY_TOO_LARGE: + return(apr_pstrcat(p, + "The requested resource
    ", + ap_escape_html(r->pool, r->uri), "
    \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)); + case HTTP_REQUEST_URI_TOO_LARGE: + s1 = "

    The requested URL's length exceeds the capacity\n" + "limit for this server.
    \n"; + return(add_optional_notes(r, s1, "error-notes", "

    \n")); + case HTTP_UNSUPPORTED_MEDIA_TYPE: + return("

    The supplied request data is not in a format\n" + "acceptable for processing by this resource.

    \n"); + case HTTP_RANGE_NOT_SATISFIABLE: + return("

    None of the range-specifier values in the Range\n" + "request-header field overlap the current extent\n" + "of the selected resource.

    \n"); + case HTTP_EXPECTATION_FAILED: + return(apr_pstrcat(p, + "

    The expectation given in the Expect " + "request-header" + "\nfield could not be met by this server.

    \n" + "

    The client sent

    \n    Expect: ",
    +                           apr_table_get(r->headers_in, "Expect"),
    +                           "\n
    \n" + "but we only allow the 100-continue " + "expectation.

    \n", + NULL)); + case HTTP_UNPROCESSABLE_ENTITY: + return("

    The server understands the media type of the\n" + "request entity, but was unable to process the\n" + "contained instructions.

    \n"); + case HTTP_LOCKED: + return("

    The requested resource is currently locked.\n" + "The lock must be released or proper identification\n" + "given before the method can be applied.

    \n"); + case HTTP_FAILED_DEPENDENCY: + return("

    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"); + case HTTP_UPGRADE_REQUIRED: + return("

    The requested resource can only be retrieved\n" + "using SSL. The server is willing to upgrade the current\n" + "connection to SSL, but your client doesn't support it.\n" + "Either upgrade your client, or try requesting the page\n" + "using https://\n"); + case HTTP_INSUFFICIENT_STORAGE: + return("

    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"); + case HTTP_SERVICE_UNAVAILABLE: + return("

    The server is temporarily unable to service your\n" + "request due to maintenance downtime or capacity\n" + "problems. Please try again later.

    \n"); + case HTTP_GATEWAY_TIME_OUT: + return("

    The proxy server did not receive a timely response\n" + "from the upstream server.

    \n"); + case HTTP_NOT_EXTENDED: + return("

    A mandatory extension policy in the request is not\n" + "accepted by the server for this resource.

    \n"); + default: /* HTTP_INTERNAL_SERVER_ERROR */ + /* + * 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 = apr_table_get(r->notes, + "error-notes")) != NULL) + && (h1 = apr_table_get(r->notes, "verbose-error-to")) != NULL + && (strcmp(h1, "*") == 0)) { + return(apr_pstrcat(p, error_notes, "

    \n", NULL)); + } + else { + return(apr_pstrcat(p, + "

    The server encountered an internal " + "error or\n" + "misconfiguration and was unable to complete\n" + "your request.

    \n" + "

    Please contact the server " + "administrator,\n ", + ap_escape_html(r->pool, + r->server->server_admin), + " and inform them of the time the " + "error occurred,\n" + "and anything you might have done that " + "may have\n" + "caused the error.

    \n" + "

    More information about this error " + "may be available\n" + "in the server error log.

    \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 + * the error_log (think University sites) even though they can easily + * get this error by misconfiguring an htaccess file. However, the + * e error notes tend to include the real file pathname in this case, + * which some people consider to be a breach of privacy. Until we + * can figure out a way to remove the pathname, leave this commented. + * + * if ((error_notes = apr_table_get(r->notes, + * "error-notes")) != NULL) { + * return(apr_pstrcat(p, error_notes, "

    \n", NULL); + * } + * else { + * return ""; + * } + */ + } +} + +/* We should have named this send_canned_response, since it is used for any + * response that can be generated by the server from the request record. + * This includes all 204 (no content), 3xx (redirect), 4xx (client error), + * and 5xx (server error) messages that have not been redirected to another + * handler via the ErrorDocument feature. + */ +AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error) +{ + int status = r->status; + int idx = ap_index_of_response(status); + char *custom_response; + const char *location = apr_table_get(r->headers_out, "Location"); + + /* At this point, we are starting the response over, so we have to reset + * this value. + */ + r->eos_sent = 0; + + /* and we need to get rid of any RESOURCE filters that might be lurking + * around, thinking they are in the middle of the original request + */ + + r->output_filters = r->proto_output_filters; + + ap_run_insert_error_filter(r); + + /* + * It's possible that the Location field might be in r->err_headers_out + * instead of r->headers_out; use the latter if possible, else the + * former. + */ + if (location == NULL) { + location = apr_table_get(r->err_headers_out, "Location"); + } + /* We need to special-case the handling of 204 and 304 responses, + * since they have specific HTTP requirements and do not include a + * message body. Note that being assbackwards here is not an option. + */ + if (status == HTTP_NOT_MODIFIED) { + ap_finalize_request_protocol(r); + return; + } + + if (status == HTTP_NO_CONTENT) { + ap_finalize_request_protocol(r); + return; + } + + if (!r->assbackwards) { + apr_table_t *tmp = r->headers_out; + + /* For all HTTP/1.x responses for which we generate the message, + * we need to avoid inheriting the "normal status" header fields + * that may have been set by the request handler before the + * error or redirect, except for Location on external redirects. + */ + r->headers_out = r->err_headers_out; + r->err_headers_out = tmp; + apr_table_clear(r->err_headers_out); + + if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) { + if ((location != NULL) && *location) { + apr_table_setn(r->headers_out, "Location", location); + } + else { + location = ""; /* avoids coredump when printing, below */ + } + } + + r->content_languages = NULL; + r->content_encoding = NULL; + r->clength = 0; + + if (apr_table_get(r->subprocess_env, + "suppress-error-charset") != NULL) { + core_request_config *request_conf = + ap_get_module_config(r->request_config, &core_module); + request_conf->suppress_charset = 1; /* avoid adding default + * charset later + */ + ap_set_content_type(r, "text/html"); + } + else { + ap_set_content_type(r, "text/html; charset=iso-8859-1"); + } + + if ((status == HTTP_METHOD_NOT_ALLOWED) + || (status == HTTP_NOT_IMPLEMENTED)) { + apr_table_setn(r->headers_out, "Allow", make_allow(r)); + } + + if (r->header_only) { + ap_finalize_request_protocol(r); + return; + } + } + + if ((custom_response = ap_response_code_string(r, idx))) { + /* + * We have a custom response output. This should only be + * a text-string to write back. But if the ErrorDocument + * was a local redirect and the requested resource failed + * for any reason, the custom_response will still hold the + * redirect URL. We don't really want to output this URL + * as a text message, so first check the custom response + * string to ensure that it is a text-string (using the + * same test used in ap_die(), i.e. does it start with a "). + * + * If it's not a text string, we've got a recursive error or + * an external redirect. If it's a recursive error, ap_die passes + * us the second error code so we can write both, and has already + * backed up to the original error. If it's an external redirect, + * it hasn't happened yet; we may never know if it fails. + */ + if (custom_response[0] == '\"') { + ap_rputs(custom_response + 1, r); + ap_finalize_request_protocol(r); + return; + } + } + { + const char *title = status_lines[idx]; + const char *h1; + + /* Accept a status_line set by a module, but only if it begins + * with the 3 digit status code + */ + if (r->status_line != NULL + && strlen(r->status_line) > 4 /* long enough */ + && apr_isdigit(r->status_line[0]) + && apr_isdigit(r->status_line[1]) + && apr_isdigit(r->status_line[2]) + && apr_isspace(r->status_line[3]) + && apr_isalnum(r->status_line[4])) { + title = r->status_line; + } + + /* folks decided they didn't want the error code in the H1 text */ + h1 = &title[4]; + + /* can't count on a charset filter being in place here, + * so do ebcdic->ascii translation explicitly (if needed) + */ + + ap_rvputs_proto_in_ascii(r, + DOCTYPE_HTML_2_0 + "\n", title, + "\n\n

    ", h1, "

    \n", + NULL); + + ap_rvputs_proto_in_ascii(r, + get_canned_error_string(status, r, location), + NULL); + + if (recursive_error) { + ap_rvputs_proto_in_ascii(r, "

    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_rvputs_proto_in_ascii(r, ap_psignature("
    \n", r), NULL); + ap_rvputs_proto_in_ascii(r, "\n", NULL); + } + ap_finalize_request_protocol(r); +} + +/* + * Create a new method list with the specified number of preallocated + * extension slots. + */ +AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts) +{ + ap_method_list_t *ml; + + ml = (ap_method_list_t *) apr_palloc(p, sizeof(ap_method_list_t)); + ml->method_mask = 0; + ml->method_list = apr_array_make(p, nelts, sizeof(char *)); + return ml; +} + +/* + * Make a copy of a method list (primarily for subrequests that may + * subsequently change it; don't want them changing the parent's, too!). + */ +AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest, + ap_method_list_t *src) +{ + int i; + char **imethods; + char **omethods; + + dest->method_mask = src->method_mask; + imethods = (char **) src->method_list->elts; + for (i = 0; i < src->method_list->nelts; ++i) { + omethods = (char **) apr_array_push(dest->method_list); + *omethods = apr_pstrdup(dest->method_list->pool, imethods[i]); + } +} + +/* + * Return true if the specified HTTP method is in the provided + * method list. + */ +AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method) +{ + int methnum; + int i; + char **methods; + + /* + * If it's one of our known methods, use the shortcut and check the + * bitmask. + */ + methnum = ap_method_number_of(method); + if (methnum != M_INVALID) { + return !!(l->method_mask & (AP_METHOD_BIT << methnum)); + } + /* + * Otherwise, see if the method name is in the array or string names + */ + if ((l->method_list == NULL) || (l->method_list->nelts == 0)) { + return 0; + } + methods = (char **)l->method_list->elts; + for (i = 0; i < l->method_list->nelts; ++i) { + if (strcmp(method, methods[i]) == 0) { + return 1; + } + } + return 0; +} + +/* + * Add the specified method to a method list (if it isn't already there). + */ +AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method) +{ + int methnum; + int i; + const char **xmethod; + char **methods; + + /* + * If it's one of our known methods, use the shortcut and use the + * bitmask. + */ + methnum = ap_method_number_of(method); + l->method_mask |= (AP_METHOD_BIT << methnum); + if (methnum != M_INVALID) { + return; + } + /* + * Otherwise, see if the method name is in the array of string names. + */ + if (l->method_list->nelts != 0) { + methods = (char **)l->method_list->elts; + for (i = 0; i < l->method_list->nelts; ++i) { + if (strcmp(method, methods[i]) == 0) { + return; + } + } + } + xmethod = (const char **) apr_array_push(l->method_list); + *xmethod = method; +} + +/* + * Remove the specified method from a method list. + */ +AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l, + const char *method) +{ + int methnum; + char **methods; + + /* + * If it's a known methods, either builtin or registered + * by a module, use the bitmask. + */ + methnum = ap_method_number_of(method); + l->method_mask |= ~(AP_METHOD_BIT << methnum); + if (methnum != M_INVALID) { + return; + } + /* + * Otherwise, see if the method name is in the array of string names. + */ + if (l->method_list->nelts != 0) { + register int i, j, k; + methods = (char **)l->method_list->elts; + for (i = 0; i < l->method_list->nelts; ) { + if (strcmp(method, methods[i]) == 0) { + for (j = i, k = i + 1; k < l->method_list->nelts; ++j, ++k) { + methods[j] = methods[k]; + } + --l->method_list->nelts; + } + else { + ++i; + } + } + } +} + +/* + * Reset a method list to be completely empty. + */ +AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l) +{ + l->method_mask = 0; + l->method_list->nelts = 0; +} + diff --git a/trunk/modules/http/http_request.c b/trunk/modules/http/http_request.c new file mode 100644 index 0000000000..22c23af6da --- /dev/null +++ b/trunk/modules/http/http_request.c @@ -0,0 +1,557 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_request.c: functions to get and process requests + * + * Rob McCool 3/21/93 + * + * Thoroughly revamped by rst for Apache. NB this file reads + * best from the bottom up. + * + */ + +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_fnmatch.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "util_filter.h" +#include "util_charset.h" +#include "scoreboard.h" + +#include "mod_core.h" + +#if APR_HAVE_STDARG_H +#include +#endif + +/***************************************************************** + * + * Mainline request processing... + */ + +/* XXX A cleaner and faster way to do this might be to pass the request_rec + * down the filter chain as a parameter. It would need to change for + * subrequest vs. main request filters; perhaps the subrequest filter could + * make the switch. + */ +static void update_r_in_filters(ap_filter_t *f, + request_rec *from, + request_rec *to) +{ + while (f) { + if (f->r == from) { + f->r = to; + } + f = f->next; + } +} + +AP_DECLARE(void) ap_die(int type, request_rec *r) +{ + int error_index = ap_index_of_response(type); + char *custom_response = ap_response_code_string(r, error_index); + int recursive_error = 0; + request_rec *r_1st_err = r; + + if (type == AP_FILTER_ERROR) { + return; + } + + if (type == DONE) { + ap_finalize_request_protocol(r); + return; + } + + /* + * The following takes care of Apache redirects to custom response URLs + * Note that if we are already dealing with the response to some other + * error condition, we just report on the original error, and give up on + * any attempt to handle the other thing "intelligently"... + */ + if (r->status != HTTP_OK) { + recursive_error = type; + + while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK)) + r_1st_err = r_1st_err->prev; /* Get back to original error */ + + if (r_1st_err != r) { + /* The recursive error was caused by an ErrorDocument specifying + * an internal redirect to a bad URI. ap_internal_redirect has + * changed the filter chains to point to the ErrorDocument's + * request_rec. Back out those changes so we can safely use the + * original failing request_rec to send the canned error message. + * + * ap_send_error_response gets rid of existing resource filters + * on the output side, so we can skip those. + */ + update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err); + update_r_in_filters(r_1st_err->input_filters, r, r_1st_err); + } + + custom_response = NULL; /* Do NOT retry the custom thing! */ + } + + r->status = type; + + /* + * This test is done here so that none of the auth modules needs to know + * about proxy authentication. They treat it like normal auth, and then + * we tweak the status. + */ + if (HTTP_UNAUTHORIZED == r->status && PROXYREQ_PROXY == r->proxyreq) { + r->status = HTTP_PROXY_AUTHENTICATION_REQUIRED; + } + + /* If we don't want to keep the connection, make sure we mark that the + * connection is not eligible for keepalive. If we want to keep the + * connection, be sure that the request body (if any) has been read. + */ + if (ap_status_drops_connection(r->status)) { + r->connection->keepalive = AP_CONN_CLOSE; + } + + /* + * Two types of custom redirects --- plain text, and URLs. Plain text has + * a leading '"', so the URL code, here, is triggered on its absence + */ + + if (custom_response && custom_response[0] != '"') { + + if (ap_is_url(custom_response)) { + /* + * The URL isn't local, so lets drop through the rest of this + * apache code, and continue with the usual REDIRECT handler. + * But note that the client will ultimately see the wrong + * status... + */ + r->status = HTTP_MOVED_TEMPORARILY; + apr_table_setn(r->headers_out, "Location", custom_response); + } + else if (custom_response[0] == '/') { + const char *error_notes; + r->no_local_copy = 1; /* Do NOT send HTTP_NOT_MODIFIED for + * error documents! */ + /* + * This redirect needs to be a GET no matter what the original + * method was. + */ + apr_table_setn(r->subprocess_env, "REQUEST_METHOD", r->method); + + /* + * Provide a special method for modules to communicate + * more informative (than the plain canned) messages to us. + * Propagate them to ErrorDocuments via the ERROR_NOTES variable: + */ + if ((error_notes = apr_table_get(r->notes, + "error-notes")) != NULL) { + apr_table_setn(r->subprocess_env, "ERROR_NOTES", error_notes); + } + r->method = apr_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + ap_internal_redirect(custom_response, r); + return; + } + else { + /* + * Dumb user has given us a bad url to redirect to --- fake up + * dying with a recursive server error... + */ + recursive_error = HTTP_INTERNAL_SERVER_ERROR; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid error redirection directive: %s", + custom_response); + } + } + ap_send_error_response(r_1st_err, recursive_error); +} + +static void check_pipeline_flush(request_rec *r) +{ + apr_bucket *e; + apr_bucket_brigade *bb; + conn_rec *c = r->connection; + /* ### if would be nice if we could PEEK without a brigade. that would + ### allow us to defer creation of the brigade to when we actually + ### need to send a FLUSH. */ + bb = apr_brigade_create(r->pool, c->bucket_alloc); + + /* Flush the filter contents if: + * + * 1) the connection will be closed + * 2) there isn't a request ready to be read + */ + /* ### shouldn't this read from the connection input filters? */ + /* ### is zero correct? that means "read one line" */ + if (r->connection->keepalive != AP_CONN_CLOSE) { + if (ap_get_brigade(r->input_filters, bb, AP_MODE_EATCRLF, + APR_NONBLOCK_READ, 0) != APR_SUCCESS) { + c->data_in_input_filters = 0; /* we got APR_EOF or an error */ + } + else { + c->data_in_input_filters = 1; + return; /* don't flush */ + } + } + + e = apr_bucket_flush_create(c->bucket_alloc); + + /* We just send directly to the connection based filters. At + * this point, we know that we have seen all of the data + * (request finalization sent an EOS bucket, which empties all + * of the request filters). We just want to flush the buckets + * if something hasn't been sent to the network yet. + */ + APR_BRIGADE_INSERT_HEAD(bb, e); + ap_pass_brigade(r->connection->output_filters, bb); +} + +void ap_process_request(request_rec *r) +{ + int access_status; + + /* Give quick handlers a shot at serving the request on the fast + * path, bypassing all of the other Apache hooks. + * + * This hook was added to enable serving files out of a URI keyed + * content cache ( e.g., Mike Abbott's Quick Shortcut Cache, + * described here: http://oss.sgi.com/projects/apache/mod_qsc.html ) + * + * It may have other uses as well, such as routing requests directly to + * content handlers that have the ability to grok HTTP and do their + * own access checking, etc (e.g. servlet engines). + * + * Use this hook with extreme care and only if you know what you are + * doing. + */ + if (ap_extended_status) + ap_time_process_request(r->connection->sbh, START_PREQUEST); + access_status = ap_run_quick_handler(r, 0); /* Not a look-up request */ + if (access_status == DECLINED) { + access_status = ap_process_request_internal(r); + if (access_status == OK) { + access_status = ap_invoke_handler(r); + } + } + + if (access_status == DONE) { + /* e.g., something not in storage like TRACE */ + access_status = OK; + } + + if (access_status == OK) { + ap_finalize_request_protocol(r); + } + else { + ap_die(access_status, r); + } + + /* + * We want to flush the last packet if this isn't a pipelining connection + * *before* we start into logging. Suppose that the logging causes a DNS + * lookup to occur, which may have a high latency. If we hold off on + * this packet, then it'll appear like the link is stalled when really + * it's the application that's stalled. + */ + check_pipeline_flush(r); + ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + if (ap_extended_status) + ap_time_process_request(r->connection->sbh, STOP_PREQUEST); +} + +static apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t) +{ + const apr_array_header_t *env_arr = apr_table_elts(t); + const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts; + apr_table_t *new = apr_table_make(p, env_arr->nalloc); + int i; + + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) + continue; + apr_table_setn(new, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL), + elts[i].val); + } + + return new; +} + +static request_rec *internal_internal_redirect(const char *new_uri, + request_rec *r) { + int access_status; + request_rec *new; + + if (ap_is_recursion_limit_exceeded(r)) { + ap_die(HTTP_INTERNAL_SERVER_ERROR, r); + return NULL; + } + + new = (request_rec *) apr_pcalloc(r->pool, sizeof(request_rec)); + + new->connection = r->connection; + new->server = r->server; + new->pool = r->pool; + + /* + * A whole lot of this really ought to be shared with http_protocol.c... + * another missing cleanup. It's particularly inappropriate to be + * setting header_only, etc., here. + */ + + new->method = r->method; + new->method_number = r->method_number; + new->allowed_methods = ap_make_method_list(new->pool, 2); + ap_parse_uri(new, new_uri); + + new->request_config = ap_create_request_config(r->pool); + + new->per_dir_config = r->server->lookup_defaults; + + new->prev = r; + r->next = new; + + /* Must have prev and next pointers set before calling create_request + * hook. + */ + ap_run_create_request(new); + + /* Inherit the rest of the protocol info... */ + + new->the_request = r->the_request; + + new->allowed = r->allowed; + + new->status = r->status; + new->assbackwards = r->assbackwards; + new->header_only = r->header_only; + new->protocol = r->protocol; + new->proto_num = r->proto_num; + new->hostname = r->hostname; + new->request_time = r->request_time; + new->main = r->main; + + new->headers_in = r->headers_in; + new->headers_out = apr_table_make(r->pool, 12); + new->err_headers_out = r->err_headers_out; + new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); + new->notes = apr_table_make(r->pool, 5); + new->allowed_methods = ap_make_method_list(new->pool, 2); + + new->htaccess = r->htaccess; + new->no_cache = r->no_cache; + new->expecting_100 = r->expecting_100; + new->no_local_copy = r->no_local_copy; + new->read_length = r->read_length; /* We can only read it once */ + new->vlist_validator = r->vlist_validator; + + new->proto_output_filters = r->proto_output_filters; + new->proto_input_filters = r->proto_input_filters; + + new->output_filters = new->proto_output_filters; + new->input_filters = new->proto_input_filters; + + if (new->main) { + /* Add back the subrequest filter, which we lost when + * we set output_filters to include only the protocol + * output filters from the original request. + */ + ap_add_output_filter_handle(ap_subreq_core_filter_handle, + NULL, new, new->connection); + } + + update_r_in_filters(new->input_filters, r, new); + update_r_in_filters(new->output_filters, r, new); + + apr_table_setn(new->subprocess_env, "REDIRECT_STATUS", + apr_itoa(r->pool, r->status)); + + /* + * XXX: hmm. This is because mod_setenvif and mod_unique_id really need + * to do their thing on internal redirects as well. Perhaps this is a + * misnamed function. + */ + if ((access_status = ap_run_post_read_request(new))) { + ap_die(access_status, new); + return NULL; + } + + return new; +} + +/* XXX: Is this function is so bogus and fragile that we deep-6 it? */ +AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r) +{ + /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool + * will exist as long as r->pool. Otherwise we run into troubles because + * some values in this request will be allocated in r->pool, and others in + * rr->pool. + */ + apr_pool_join(r->pool, rr->pool); + r->proxyreq = rr->proxyreq; + r->no_cache = (r->no_cache && rr->no_cache); + r->no_local_copy = (r->no_local_copy && rr->no_local_copy); + r->mtime = rr->mtime; + r->uri = rr->uri; + r->filename = rr->filename; + r->canonical_filename = rr->canonical_filename; + r->path_info = rr->path_info; + r->args = rr->args; + r->finfo = rr->finfo; + r->handler = rr->handler; + ap_set_content_type(r, rr->content_type); + r->content_encoding = rr->content_encoding; + r->content_languages = rr->content_languages; + r->per_dir_config = rr->per_dir_config; + /* copy output headers from subrequest, but leave negotiation headers */ + r->notes = apr_table_overlay(r->pool, rr->notes, r->notes); + r->headers_out = apr_table_overlay(r->pool, rr->headers_out, + r->headers_out); + r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, + r->err_headers_out); + r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, + r->subprocess_env); + + r->output_filters = rr->output_filters; + r->input_filters = rr->input_filters; + + if (r->main) { + ap_add_output_filter_handle(ap_subreq_core_filter_handle, + NULL, r, r->connection); + } + else if (r->output_filters->frec == ap_subreq_core_filter_handle) { + ap_remove_output_filter(r->output_filters); + r->output_filters = r->output_filters->next; + } + + /* If any filters pointed at the now-defunct rr, we must point them + * at our "new" instance of r. In particular, some of rr's structures + * will now be bogus (say rr->headers_out). If a filter tried to modify + * their f->r structure when it is pointing to rr, the real request_rec + * will not get updated. Fix that here. + */ + update_r_in_filters(r->input_filters, rr, r); + update_r_in_filters(r->output_filters, rr, r); +} + +AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r) +{ + request_rec *new = internal_internal_redirect(new_uri, r); + int access_status; + + /* ap_die was already called, if an error occured */ + if (!new) { + return; + } + + access_status = ap_run_quick_handler(new, 0); /* Not a look-up request */ + if (access_status == DECLINED) { + access_status = ap_process_request_internal(new); + if (access_status == OK) { + access_status = ap_invoke_handler(new); + } + } + if (access_status == OK) { + ap_finalize_request_protocol(new); + } + else { + ap_die(access_status, new); + } +} + +/* This function is designed for things like actions or CGI scripts, when + * using AddHandler, and you want to preserve the content type across + * an internal redirect. + */ +AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r) +{ + int access_status; + request_rec *new = internal_internal_redirect(new_uri, r); + + /* ap_die was already called, if an error occured */ + if (!new) { + return; + } + + if (r->handler) + ap_set_content_type(new, r->content_type); + access_status = ap_process_request_internal(new); + if (access_status == OK) { + if ((access_status = ap_invoke_handler(new)) != 0) { + ap_die(access_status, new); + return; + } + ap_finalize_request_protocol(new); + } + else { + ap_die(access_status, new); + } +} + +AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...) +{ + const char *method; + va_list methods; + + /* + * Get rid of any current settings if requested; not just the + * well-known methods but any extensions as well. + */ + if (reset) { + ap_clear_method_list(r->allowed_methods); + } + + va_start(methods, reset); + while ((method = va_arg(methods, const char *)) != NULL) { + ap_method_list_add(r->allowed_methods, method); + } +} + +AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...) +{ + int method; + va_list methods; + apr_int64_t mask; + + /* + * Get rid of any current settings if requested; not just the + * well-known methods but any extensions as well. + */ + if (reset) { + ap_clear_method_list(r->allowed_methods); + } + + mask = 0; + va_start(methods, reset); + while ((method = va_arg(methods, int)) != -1) { + mask |= (AP_METHOD_BIT << method); + } + va_end(methods); + + r->allowed_methods->method_mask |= mask; +} diff --git a/trunk/modules/http/mod_core.h b/trunk/modules/http/mod_core.h new file mode 100644 index 0000000000..a7db95c51e --- /dev/null +++ b/trunk/modules/http/mod_core.h @@ -0,0 +1,83 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_CORE_H +#define MOD_CORE_H + +#include "apr.h" +#include "apr_buckets.h" + +#include "httpd.h" +#include "util_filter.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @package mod_core private header file + */ + +/* Handles for core filters */ +extern AP_DECLARE_DATA ap_filter_rec_t *ap_http_input_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_http_header_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_chunk_filter_handle; +extern AP_DECLARE_DATA ap_filter_rec_t *ap_byterange_filter_handle; + +/* + * These (input) filters are internal to the mod_core operation. + */ +apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes); + +/* HTTP/1.1 chunked transfer encoding filter. */ +apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b); + +char *ap_response_code_string(request_rec *r, int error_index); + +/** + * Send the minimal part of an HTTP response header. + * @param r The current request + * @param bb The brigade to add the header to. + * @warning Modules should be very careful about using this, and should + * the default behavior. Much of the HTTP/1.1 implementation + * correctness depends on the full headers. + * @deffunc void ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb) + */ +AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb); + +/** + * Send an appropriate response to an http TRACE request. + * @param r The current request + * @tip returns DONE or the HTTP status error if it handles the TRACE, + * or DECLINED if the request was not for TRACE. + * request method was not TRACE. + */ +AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r); + +/** + * Send an appropriate response to an http OPTIONS request. + * @param r The current request + */ +AP_DECLARE(int) ap_send_http_options(request_rec *r); + +#ifdef __cplusplus +} +#endif + +#endif /* !MOD_CORE_H */ diff --git a/trunk/modules/http/mod_mime.c b/trunk/modules/http/mod_mime.c new file mode 100644 index 0000000000..0937f2eab2 --- /dev/null +++ b/trunk/modules/http/mod_mime.c @@ -0,0 +1,991 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_mime.c: Sends/gets MIME headers for requests + * + * Rob McCool + * + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_hash.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" + +/* XXXX - fix me / EBCDIC + * there was a cludge here which would use its + * own version apr_isascii(). Indicating that + * on some platforms that might be needed. + * + * #define OS_ASC(c) (c) -- for mere mortals + * or + * #define OS_ASC(c) (ebcdic2ascii[c]) -- for dino's + * + * #define apr_isascii(c) ((OS_ASC(c) & 0x80) == 0) + */ + +/* XXXXX - fix me - See note with NOT_PROXY + */ + +typedef struct attrib_info { + char *name; + int offset; +} attrib_info; + +/* Information to which an extension can be mapped + */ +typedef struct extension_info { + char *forced_type; /* Additional AddTyped stuff */ + char *encoding_type; /* Added with AddEncoding... */ + char *language_type; /* Added with AddLanguage... */ + char *handler; /* Added with AddHandler... */ + char *charset_type; /* Added with AddCharset... */ + char *input_filters; /* Added with AddInputFilter... */ + char *output_filters; /* Added with AddOutputFilter... */ +} extension_info; + +#define MULTIMATCH_UNSET 0 +#define MULTIMATCH_ANY 1 +#define MULTIMATCH_NEGOTIATED 2 +#define MULTIMATCH_HANDLERS 4 +#define MULTIMATCH_FILTERS 8 + +typedef struct { + apr_hash_t *extension_mappings; /* Map from extension name to + * extension_info structure */ + + apr_array_header_t *remove_mappings; /* A simple list, walked once */ + + char *default_language; /* Language if no AddLanguage ext found */ + + int multimatch; /* Extensions to include in multiview matching + * for filenames, e.g. Filters and Handlers + */ + int use_path_info; /* If set to 0, only use filename. + * If set to 1, append PATH_INFO to filename for + * lookups. + * If set to 2, this value is unset and is + * effectively 0. + */ +} mime_dir_config; + +typedef struct param_s { + char *attr; + char *val; + struct param_s *next; +} param; + +typedef struct { + const char *type; + apr_size_t type_len; + const char *subtype; + apr_size_t subtype_len; + param *param; +} content_type; + +static char tspecial[] = { + '(', ')', '<', '>', '@', ',', ';', ':', + '\\', '"', '/', '[', ']', '?', '=', + '\0' +}; + +module AP_MODULE_DECLARE_DATA mime_module; + +static void *create_mime_dir_config(apr_pool_t *p, char *dummy) +{ + mime_dir_config *new = apr_palloc(p, sizeof(mime_dir_config)); + + new->extension_mappings = NULL; + new->remove_mappings = NULL; + + new->default_language = NULL; + + new->multimatch = MULTIMATCH_UNSET; + + new->use_path_info = 2; + + return new; +} +/* + * Overlay one hash table of extension_mappings onto another + */ +static void *overlay_extension_mappings(apr_pool_t *p, + const void *key, + apr_ssize_t klen, + const void *overlay_val, + const void *base_val, + const void *data) +{ + extension_info *new_info = apr_palloc(p, sizeof(extension_info)); + const extension_info *overlay_info = (const extension_info *)overlay_val; + const extension_info *base_info = (const extension_info *)base_val; + + memcpy(new_info, base_info, sizeof(extension_info)); + if (overlay_info->forced_type) { + new_info->forced_type = overlay_info->forced_type; + } + if (overlay_info->encoding_type) { + new_info->encoding_type = overlay_info->encoding_type; + } + if (overlay_info->language_type) { + new_info->language_type = overlay_info->language_type; + } + if (overlay_info->handler) { + new_info->handler = overlay_info->handler; + } + if (overlay_info->charset_type) { + new_info->charset_type = overlay_info->charset_type; + } + if (overlay_info->input_filters) { + new_info->input_filters = overlay_info->input_filters; + } + if (overlay_info->output_filters) { + new_info->output_filters = overlay_info->output_filters; + } + + return new_info; +} + +/* Member is the offset within an extension_info of the pointer to reset + */ +static void remove_items(apr_pool_t *p, apr_array_header_t *remove, + apr_hash_t *mappings) +{ + attrib_info *suffix = (attrib_info *) remove->elts; + int i; + for (i = 0; i < remove->nelts; i++) { + extension_info *exinfo = apr_hash_get(mappings, + suffix[i].name, + APR_HASH_KEY_STRING); + if (exinfo && *(const char**)((char *)exinfo + suffix[i].offset)) { + extension_info *copyinfo = exinfo; + exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo)); + apr_hash_set(mappings, suffix[i].name, + APR_HASH_KEY_STRING, exinfo); + memcpy(exinfo, copyinfo, sizeof(*exinfo)); + *(const char**)((char *)exinfo + suffix[i].offset) = NULL; + } + } +} + +static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + mime_dir_config *base = (mime_dir_config *)basev; + mime_dir_config *add = (mime_dir_config *)addv; + mime_dir_config *new = apr_palloc(p, sizeof(mime_dir_config)); + + if (base->extension_mappings && add->extension_mappings) { + new->extension_mappings = apr_hash_merge(p, add->extension_mappings, + base->extension_mappings, + overlay_extension_mappings, + NULL); + } + else { + if (base->extension_mappings == NULL) { + new->extension_mappings = add->extension_mappings; + } + else { + new->extension_mappings = base->extension_mappings; + } + /* We may not be merging the tables, but if we potentially will change + * an exinfo member, then we are about to trounce it anyways. + * We must have a copy for safety. + */ + if (new->extension_mappings && add->remove_mappings) { + new->extension_mappings = + apr_hash_copy(p, new->extension_mappings); + } + } + + if (new->extension_mappings) { + if (add->remove_mappings) + remove_items(p, add->remove_mappings, new->extension_mappings); + } + new->remove_mappings = NULL; + + new->default_language = add->default_language ? + add->default_language : base->default_language; + + new->multimatch = (add->multimatch != MULTIMATCH_UNSET) ? + add->multimatch : base->multimatch; + + if ((add->use_path_info & 2) == 0) { + new->use_path_info = add->use_path_info; + } + else { + new->use_path_info = base->use_path_info; + } + + return new; +} + +static const char *add_extension_info(cmd_parms *cmd, void *m_, + const char *value_, const char* ext) +{ + mime_dir_config *m=m_; + extension_info *exinfo; + int offset = (int) (long) cmd->info; + char *key = apr_pstrdup(cmd->temp_pool, ext); + char *value = apr_pstrdup(cmd->pool, value_); + ap_str_tolower(value); + ap_str_tolower(key); + + if (*key == '.') { + ++key; + } + if (!m->extension_mappings) { + m->extension_mappings = apr_hash_make(cmd->pool); + exinfo = NULL; + } + else { + exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key, + APR_HASH_KEY_STRING); + } + if (!exinfo) { + exinfo = apr_pcalloc(cmd->pool, sizeof(extension_info)); + key = apr_pstrdup(cmd->pool, key); + apr_hash_set(m->extension_mappings, key, APR_HASH_KEY_STRING, exinfo); + } + *(const char**)((char *)exinfo + offset) = value; + return NULL; +} + +/* + * Note handler names are un-added with each per_dir_config merge. + * This keeps the association from being inherited, but not + * from being re-added at a subordinate level. + */ +static const char *remove_extension_info(cmd_parms *cmd, void *m_, + const char *ext) +{ + mime_dir_config *m = (mime_dir_config *) m_; + attrib_info *suffix; + if (*ext == '.') { + ++ext; + } + if (!m->remove_mappings) { + m->remove_mappings = apr_array_make(cmd->pool, 4, sizeof(*suffix)); + } + suffix = (attrib_info *)apr_array_push(m->remove_mappings); + suffix->name = apr_pstrdup(cmd->pool, ext); + ap_str_tolower(suffix->name); + suffix->offset = (int) (long) cmd->info; + return NULL; +} + +/* The sole bit of server configuration that the MIME module has is + * the name of its config file, so... + */ + +static const char *set_types_config(cmd_parms *cmd, void *dummy, + const char *arg) +{ + ap_set_module_config(cmd->server->module_config, &mime_module, + (void *)arg); + return NULL; +} + +static const char *multiviews_match(cmd_parms *cmd, void *m_, + const char *include) +{ + mime_dir_config *m = (mime_dir_config *) m_; + + if (strcasecmp(include, "Any") == 0) { + if (m->multimatch && (m->multimatch & ~MULTIMATCH_ANY)) { + return "Any is incompatible with NegotiatedOnly, " + "Filters and Handlers"; + } + m->multimatch |= MULTIMATCH_ANY; + } + else if (strcasecmp(include, "NegotiatedOnly") == 0) { + if (m->multimatch && (m->multimatch & ~MULTIMATCH_NEGOTIATED)) { + return "NegotiatedOnly is incompatible with Any, " + "Filters and Handlers"; + } + m->multimatch |= MULTIMATCH_NEGOTIATED; + } + else if (strcasecmp(include, "Filters") == 0) { + if (m->multimatch && (m->multimatch & (MULTIMATCH_NEGOTIATED + | MULTIMATCH_ANY))) { + return "Filters is incompatible with Any and NegotiatedOnly"; + } + m->multimatch |= MULTIMATCH_FILTERS; + } + else if (strcasecmp(include, "Handlers") == 0) { + if (m->multimatch && (m->multimatch & (MULTIMATCH_NEGOTIATED + | MULTIMATCH_ANY))) { + return "Handlers is incompatible with Any and NegotiatedOnly"; + } + m->multimatch |= MULTIMATCH_HANDLERS; + } + else { + return apr_psprintf(cmd->pool, "Unrecognized option '%s'", include); + } + + return NULL; +} + +static const command_rec mime_cmds[] = +{ + AP_INIT_ITERATE2("AddCharset", add_extension_info, + (void *)APR_OFFSETOF(extension_info, charset_type), OR_FILEINFO, + "a charset (e.g., iso-2022-jp), followed by one or more " + "file extensions"), + AP_INIT_ITERATE2("AddEncoding", add_extension_info, + (void *)APR_OFFSETOF(extension_info, encoding_type), OR_FILEINFO, + "an encoding (e.g., gzip), followed by one or more file extensions"), + AP_INIT_ITERATE2("AddHandler", add_extension_info, + (void *)APR_OFFSETOF(extension_info, handler), OR_FILEINFO, + "a handler name followed by one or more file extensions"), + AP_INIT_ITERATE2("AddInputFilter", add_extension_info, + (void *)APR_OFFSETOF(extension_info, input_filters), OR_FILEINFO, + "input filter name (or ; delimited names) followed by one or " + "more file extensions"), + AP_INIT_ITERATE2("AddLanguage", add_extension_info, + (void *)APR_OFFSETOF(extension_info, language_type), OR_FILEINFO, + "a language (e.g., fr), followed by one or more file extensions"), + AP_INIT_ITERATE2("AddOutputFilter", add_extension_info, + (void *)APR_OFFSETOF(extension_info, output_filters), OR_FILEINFO, + "output filter name (or ; delimited names) followed by one or " + "more file extensions"), + AP_INIT_ITERATE2("AddType", add_extension_info, + (void *)APR_OFFSETOF(extension_info, forced_type), OR_FILEINFO, + "a mime type followed by one or more file extensions"), + AP_INIT_TAKE1("DefaultLanguage", ap_set_string_slot, + (void*)APR_OFFSETOF(mime_dir_config, default_language), OR_FILEINFO, + "language to use for documents with no other language file extension"), + AP_INIT_ITERATE("MultiviewsMatch", multiviews_match, NULL, OR_FILEINFO, + "NegotiatedOnly (default), Handlers and/or Filters, or Any"), + AP_INIT_ITERATE("RemoveCharset", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, charset_type), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveEncoding", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, encoding_type), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveHandler", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, handler), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveInputFilter", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, input_filters), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveLanguage", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, language_type), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveOutputFilter", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, output_filters), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_ITERATE("RemoveType", remove_extension_info, + (void *)APR_OFFSETOF(extension_info, forced_type), OR_FILEINFO, + "one or more file extensions"), + AP_INIT_TAKE1("TypesConfig", set_types_config, NULL, RSRC_CONF, + "the MIME types config file"), + AP_INIT_FLAG("ModMimeUsePathInfo", ap_set_flag_slot, + (void *)APR_OFFSETOF(mime_dir_config, use_path_info), ACCESS_CONF, + "Set to 'yes' to allow mod_mime to use path info for type checking"), + {NULL} +}; + +static apr_hash_t *mime_type_extensions; + +static int mime_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + ap_configfile_t *f; + char l[MAX_STRING_LEN]; + const char *types_confname = ap_get_module_config(s->module_config, + &mime_module); + apr_status_t status; + + if (!types_confname) { + types_confname = AP_TYPES_CONFIG_FILE; + } + + types_confname = ap_server_root_relative(p, types_confname); + if (!types_confname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + "Invalid mime types config path %s", + (const char *)ap_get_module_config(s->module_config, + &mime_module)); + return HTTP_INTERNAL_SERVER_ERROR; + } + if ((status = ap_pcfg_openfile(&f, ptemp, types_confname)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, s, + "could not open mime types config file %s.", + types_confname); + return HTTP_INTERNAL_SERVER_ERROR; + } + + mime_type_extensions = apr_hash_make(p); + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) { + const char *ll = l, *ct; + + if (l[0] == '#') { + continue; + } + ct = ap_getword_conf(p, &ll); + + while (ll[0]) { + char *ext = ap_getword_conf(p, &ll); + ap_str_tolower(ext); + apr_hash_set(mime_type_extensions, ext, APR_HASH_KEY_STRING, ct); + } + } + ap_cfg_closefile(f); + return OK; +} + +static const char *zap_sp(const char *s) +{ + if (s == NULL) { + return (NULL); + } + if (*s == '\0') { + return (s); + } + + /* skip prefixed white space */ + for (; *s == ' ' || *s == '\t' || *s == '\n'; s++) + ; + + return (s); +} + +static char *zap_sp_and_dup(apr_pool_t *p, const char *start, + const char *end, apr_size_t *len) +{ + while ((start < end) && apr_isspace(*start)) { + start++; + } + while ((end > start) && apr_isspace(*(end - 1))) { + end--; + } + if (len) { + *len = end - start; + } + return apr_pstrmemdup(p, start, end - start); +} + +static int is_token(char c) +{ + int res; + + res = (apr_isascii(c) && apr_isgraph(c) + && (strchr(tspecial, c) == NULL)) ? 1 : -1; + return res; +} + +static int is_qtext(char c) +{ + int res; + + res = (apr_isascii(c) && (c != '"') && (c != '\\') && (c != '\n')) + ? 1 : -1; + return res; +} + +static int is_quoted_pair(const char *s) +{ + int res = -1; + int c; + + if (((s + 1) != NULL) && (*s == '\\')) { + c = (int) *(s + 1); + if (apr_isascii(c)) { + res = 1; + } + } + return (res); +} + +static content_type *analyze_ct(request_rec *r, const char *s) +{ + const char *cp, *mp; + char *attribute, *value; + int quoted = 0; + server_rec * ss = r->server; + apr_pool_t * p = r->pool; + + content_type *ctp; + param *pp, *npp; + + /* initialize ctp */ + ctp = (content_type *)apr_palloc(p, sizeof(content_type)); + ctp->type = NULL; + ctp->subtype = NULL; + ctp->param = NULL; + + mp = s; + + /* getting a type */ + cp = mp; + while (apr_isspace(*cp)) { + cp++; + } + if (!*cp) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "mod_mime: analyze_ct: cannot get media type from '%s'", + (const char *) mp); + return (NULL); + } + ctp->type = cp; + do { + cp++; + } while (*cp && (*cp != '/') && !apr_isspace(*cp) && (*cp != ';')); + if (!*cp || (*cp == ';')) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media type from '%s'", + (const char *) mp); + return (NULL); + } + while (apr_isspace(*cp)) { + cp++; + } + if (*cp != '/') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "mod_mime: analyze_ct: cannot get media type from '%s'", + (const char *) mp); + return (NULL); + } + ctp->type_len = cp - ctp->type; + + cp++; /* skip the '/' */ + + /* getting a subtype */ + while (apr_isspace(*cp)) { + cp++; + } + if (!*cp) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media subtype."); + return (NULL); + } + ctp->subtype = cp; + do { + cp++; + } while (*cp && !apr_isspace(*cp) && (*cp != ';')); + ctp->subtype_len = cp - ctp->subtype; + while (apr_isspace(*cp)) { + cp++; + } + + if (*cp == '\0') { + return (ctp); + } + + /* getting parameters */ + cp++; /* skip the ';' */ + cp = zap_sp(cp); + if (cp == NULL || *cp == '\0') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + mp = cp; + attribute = NULL; + value = NULL; + + while (cp != NULL && *cp != '\0') { + if (attribute == NULL) { + if (is_token(*cp) > 0) { + cp++; + continue; + } + else if (*cp == ' ' || *cp == '\t' || *cp == '\n') { + cp++; + continue; + } + else if (*cp == '=') { + attribute = zap_sp_and_dup(p, mp, cp, NULL); + if (attribute == NULL || *attribute == '\0') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + cp++; + cp = zap_sp(cp); + if (cp == NULL || *cp == '\0') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + mp = cp; + continue; + } + else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + } + else { + if (mp == cp) { + if (*cp == '"') { + quoted = 1; + cp++; + } + else { + quoted = 0; + } + } + if (quoted > 0) { + while (quoted && *cp != '\0') { + if (is_qtext(*cp) > 0) { + cp++; + } + else if (is_quoted_pair(cp) > 0) { + cp += 2; + } + else if (*cp == '"') { + cp++; + while (*cp == ' ' || *cp == '\t' || *cp == '\n') { + cp++; + } + if (*cp != ';' && *cp != '\0') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return(NULL); + } + quoted = 0; + } + else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + } + } + else { + while (1) { + if (is_token(*cp) > 0) { + cp++; + } + else if (*cp == '\0' || *cp == ';') { + break; + } + else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + } + } + value = zap_sp_and_dup(p, mp, cp, NULL); + if (value == NULL || *value == '\0') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss, + "Cannot get media parameter."); + return (NULL); + } + + pp = apr_palloc(p, sizeof(param)); + pp->attr = attribute; + pp->val = value; + pp->next = NULL; + + if (ctp->param == NULL) { + ctp->param = pp; + } + else { + npp = ctp->param; + while (npp->next) { + npp = npp->next; + } + npp->next = pp; + } + quoted = 0; + attribute = NULL; + value = NULL; + if (*cp == '\0') { + break; + } + cp++; + mp = cp; + } + } + return (ctp); +} + +/* + * find_ct is the hook routine for determining content-type and other + * MIME-related metadata. It assumes that r->filename has already been + * set and stat has been called for r->finfo. It also assumes that the + * non-path base file name is not the empty string unless it is a dir. + */ +static int find_ct(request_rec *r) +{ + mime_dir_config *conf; + apr_array_header_t *exception_list; + char *ext; + const char *fn, *type, *charset = NULL, *resource_name; + int found_metadata = 0; + + if (r->finfo.filetype == APR_DIR) { + ap_set_content_type(r, DIR_MAGIC_TYPE); + return OK; + } + + if (!r->filename) { + return DECLINED; + } + + conf = (mime_dir_config *)ap_get_module_config(r->per_dir_config, + &mime_module); + exception_list = apr_array_make(r->pool, 2, sizeof(char *)); + + /* If use_path_info is explicitly set to on (value & 1 == 1), append. */ + if (conf->use_path_info & 1) { + resource_name = apr_pstrcat(r->pool, r->filename, r->path_info, NULL); + } + else { + resource_name = r->filename; + } + + /* Always drop the path leading up to the file name. + */ + if ((fn = ap_strrchr_c(resource_name, '/')) == NULL) { + fn = resource_name; + } + else { + ++fn; + } + + /* The exception list keeps track of those filename components that + * are not associated with extensions indicating metadata. + * The base name is always the first exception (i.e., "txt.html" has + * a basename of "txt" even though it might look like an extension). + */ + ext = ap_getword(r->pool, &fn, '.'); + *((const char **)apr_array_push(exception_list)) = ext; + + /* Parse filename extensions which can be in any order + */ + while (*fn && (ext = ap_getword(r->pool, &fn, '.'))) { + const extension_info *exinfo = NULL; + int found; + + if (*ext == '\0') { /* ignore empty extensions "bad..html" */ + continue; + } + + found = 0; + + ap_str_tolower(ext); + + if (conf->extension_mappings != NULL) { + exinfo = (extension_info*)apr_hash_get(conf->extension_mappings, + ext, APR_HASH_KEY_STRING); + } + + if (exinfo == NULL || !exinfo->forced_type) { + if ((type = apr_hash_get(mime_type_extensions, ext, + APR_HASH_KEY_STRING)) != NULL) { + ap_set_content_type(r, (char*) type); + found = 1; + } + } + + if (exinfo != NULL) { + + if (exinfo->forced_type) { + ap_set_content_type(r, exinfo->forced_type); + found = 1; + } + + if (exinfo->charset_type) { + charset = exinfo->charset_type; + found = 1; + } + if (exinfo->language_type) { + if (!r->content_languages) { + r->content_languages = apr_array_make(r->pool, 2, + sizeof(char *)); + } + *((const char **)apr_array_push(r->content_languages)) + = exinfo->language_type; + found = 1; + } + if (exinfo->encoding_type) { + if (!r->content_encoding) { + r->content_encoding = exinfo->encoding_type; + } + else { + /* XXX should eliminate duplicate entities + * + * ah no. Order is important and double encoding is neither + * forbidden nor impossible. -- nd + */ + r->content_encoding = apr_pstrcat(r->pool, + r->content_encoding, + ", ", + exinfo->encoding_type, + NULL); + } + found = 1; + } + /* The following extensions are not 'Found'. That is, they don't + * make any contribution to metadata negotation, so they must have + * been explicitly requested by name. + */ + if (exinfo->handler && r->proxyreq == PROXYREQ_NONE) { + r->handler = exinfo->handler; + if (conf->multimatch & MULTIMATCH_HANDLERS) { + found = 1; + } + } + /* XXX Two significant problems; 1, we don't check to see if we are + * setting redundant filters. 2, we insert these in the types config + * hook, which may be too early (dunno.) + */ + if (exinfo->input_filters && r->proxyreq == PROXYREQ_NONE) { + const char *filter, *filters = exinfo->input_filters; + while (*filters + && (filter = ap_getword(r->pool, &filters, ';'))) { + ap_add_input_filter(filter, NULL, r, r->connection); + } + if (conf->multimatch & MULTIMATCH_FILTERS) { + found = 1; + } + } + if (exinfo->output_filters && r->proxyreq == PROXYREQ_NONE) { + const char *filter, *filters = exinfo->output_filters; + while (*filters + && (filter = ap_getword(r->pool, &filters, ';'))) { + ap_add_output_filter(filter, NULL, r, r->connection); + } + if (conf->multimatch & MULTIMATCH_FILTERS) { + found = 1; + } + } + } + + if (found || (conf->multimatch & MULTIMATCH_ANY)) { + found_metadata = 1; + } + else { + *((const char **) apr_array_push(exception_list)) = ext; + } + } + + /* + * Need to set a notes entry on r for unrecognized elements. + * Somebody better claim them! If we did absolutely nothing, + * skip the notes to alert mod_negotiation we are clueless. + */ + if (found_metadata) { + apr_table_setn(r->notes, "ap-mime-exceptions-list", + (void *)exception_list); + } + + if (r->content_type) { + content_type *ctp; + int override = 0; + + if ((ctp = analyze_ct(r, r->content_type))) { + param *pp = ctp->param; + char *base_content_type = apr_palloc(r->pool, ctp->type_len + + ctp->subtype_len + + sizeof("/")); + char *tmp = base_content_type; + memcpy(tmp, ctp->type, ctp->type_len); + tmp += ctp->type_len; + *tmp++ = '/'; + memcpy(tmp, ctp->subtype, ctp->subtype_len); + tmp += ctp->subtype_len; + *tmp = 0; + ap_set_content_type(r, base_content_type); + while (pp != NULL) { + if (charset && !strcmp(pp->attr, "charset")) { + if (!override) { + ap_set_content_type(r, + apr_pstrcat(r->pool, + r->content_type, + "; charset=", + charset, + NULL)); + override = 1; + } + } + else { + ap_set_content_type(r, + apr_pstrcat(r->pool, + r->content_type, + "; ", pp->attr, + "=", pp->val, + NULL)); + } + pp = pp->next; + } + if (charset && !override) { + ap_set_content_type(r, apr_pstrcat(r->pool, r->content_type, + "; charset=", charset, + NULL)); + } + } + } + + /* Set default language, if none was specified by the extensions + * and we have a DefaultLanguage setting in force + */ + + if (!r->content_languages && conf->default_language) { + const char **new; + + if (!r->content_languages) { + r->content_languages = apr_array_make(r->pool, 2, sizeof(char *)); + } + new = (const char **)apr_array_push(r->content_languages); + *new = conf->default_language; + } + + if (!r->content_type) { + return DECLINED; + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_post_config(mime_post_config,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_type_checker(find_ct,NULL,NULL,APR_HOOK_MIDDLE); + /* + * this hook seems redundant ... is there any reason a type checker isn't + * allowed to do this already? I'd think that fixups in general would be + * the last opportunity to get the filters right. + * ap_hook_insert_filter(mime_insert_filters,NULL,NULL,APR_HOOK_MIDDLE); + */ +} + +module AP_MODULE_DECLARE_DATA mime_module = { + STANDARD20_MODULE_STUFF, + create_mime_dir_config, /* create per-directory config structure */ + merge_mime_dir_configs, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + mime_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/http/mod_mime.dsp b/trunk/modules/http/mod_mime.dsp new file mode 100644 index 0000000000..a7ea861350 --- /dev/null +++ b/trunk/modules/http/mod_mime.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_mime" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_mime - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_mime.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_mime.mak" CFG="mod_mime - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_mime - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_mime - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_mime - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_mime_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_mime - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_mime_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_mime.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime.so + +!ENDIF + +# Begin Target + +# Name "mod_mime - Win32 Release" +# Name "mod_mime - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_mime.c +# End Source File +# Begin Source File + +SOURCE=.\mod_mime.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_mime - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mime.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mime.so "mime_module for Apache" ../../include/ap_release.h > .\mod_mime.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_mime - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mime.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mime.so "mime_module for Apache" ../../include/ap_release.h > .\mod_mime.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/http/mod_mime.exp b/trunk/modules/http/mod_mime.exp new file mode 100644 index 0000000000..f2e38dbdda --- /dev/null +++ b/trunk/modules/http/mod_mime.exp @@ -0,0 +1 @@ +mime_module diff --git a/trunk/modules/ldap/Makefile.in b/trunk/modules/ldap/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/ldap/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/ldap/NWGNUmakefile b/trunk/modules/ldap/NWGNUmakefile new file mode 100644 index 0000000000..7001dc980e --- /dev/null +++ b/trunk/modules/ldap/NWGNUmakefile @@ -0,0 +1,266 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(LDAPSDK)/inc \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +#LDAP client requires the use of Winsock +# +ifdef USE_STDSOCKETS +XDEFINES += -DUSE_WINSOCK \ + $(EOLIST) +endif + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = utilldap + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) LDAP Authentication Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = UtilLDAP Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/utilldap.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/util_ldap.o \ + $(OBJDIR)/util_ldap_cache.o \ + $(OBJDIR)/util_ldap_cache_mgr.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + lldapsdk \ + lldapssl \ + lldapx \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + @$(LDAPSDK)/imports/lldapsdk.imp \ + @$(LDAPSDK)/imports/lldapssl.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + ldap_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/ldap/README.ldap b/trunk/modules/ldap/README.ldap new file mode 100644 index 0000000000..30ec5cc7f6 --- /dev/null +++ b/trunk/modules/ldap/README.ldap @@ -0,0 +1,47 @@ +Quick installation instructions (UNIX): + +- Building on generic Unix: + + Add generic ldap support and the TWO ldap modules to the build, like this: + + ./configure --with-ldap --enable-ldap --enable-authnz-ldap + + The --with-ldap switches on LDAP library linking in apr-util. Make + sure that you have an LDAP client library available such as those + from Netscape/iPlanet/Sun One or the OpenLDAP project. + + The --enable-ldap option switches on the LDAP caching module. This + module is a support module for other LDAP modules, and is not useful + on its own. This module is required, but caching can be disabled + via the configuration directive LDAPCacheEntries. + + The --enable-auth-ldap option switches on the LDAP authentication + module. + +- Building on AIX: + + The following ./configure line is reported to work for AIX: + + CC=cc_r; export CC + CPPFLAGS=-qcpluscmt;export CPPFLAGS + ./configure --with-mpm=worker --prefix=/usr/local/apache \ + --enable-dav=static --enable-dav_fs=static --enable-ssl=static + --with-ldap=yes --with-ldap-include=/usr/local/include + --with-ldap-lib=/usr/local/lib --enable-ldap=static + --enable-authnz-ldap=static + + +Quick installation instructions (win32): + +1. copy the file srclib\apr-util\include\apr_ldap.hw to apr_ldap.h +2. the netscape/iplanet ldap libraries are installed in srclib\ldap +3. Compile the two modules util_ldap and mod_authnz_ldap using the dsp files +4. You get a mod_authnz_ldap.so and a mod_ldap.so module +5. Put them in the modules directory, don't forget to copy the + nsldap32v50.dll somewhere where apache.exe will find it +6. Load the two modules in your httpd.conf, like below: + LoadModule ldap_module modules/mod_ldap.so + LoadModule authnz_ldap_module modules/mod_authnz_ldap.so +7. Configure the directories as described in the docus. + + diff --git a/trunk/modules/ldap/config.m4 b/trunk/modules/ldap/config.m4 new file mode 100644 index 0000000000..25a92af473 --- /dev/null +++ b/trunk/modules/ldap/config.m4 @@ -0,0 +1,9 @@ + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(ldap) + +ldap_objects="util_ldap.lo util_ldap_cache.lo util_ldap_cache_mgr.lo" +APACHE_MODULE(ldap, LDAP caching and connection pooling services, $ldap_objects, , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/ldap/mod_ldap.dsp b/trunk/modules/ldap/mod_ldap.dsp new file mode 100644 index 0000000000..7d815788a1 --- /dev/null +++ b/trunk/modules/ldap/mod_ldap.dsp @@ -0,0 +1,140 @@ +# Microsoft Developer Studio Project File - Name="mod_ldap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_ldap - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_ldap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_ldap.mak" CFG="mod_ldap - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_ldap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_ldap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_ldap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Release\mod_ldap_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so +# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_ldap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Debug\mod_ldap_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so +# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ldap.so + +!ENDIF + +# Begin Target + +# Name "mod_ldap - Win32 Release" +# Name "mod_ldap - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_ldap.rc +# End Source File +# Begin Source File + +SOURCE=.\util_ldap.c +# End Source File +# Begin Source File + +SOURCE=.\util_ldap_cache.c +# End Source File +# Begin Source File + +SOURCE=.\util_ldap_cache.h +# End Source File +# Begin Source File + +SOURCE=.\util_ldap_cache_mgr.c +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_ldap - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ldap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ldap.so "LDAP Utility Module for Apache" ../../include/ap_release.h > .\mod_ldap.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ldap - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ldap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ldap.so "LDAP Utility Module for Apache" ../../include/ap_release.h > .\mod_ldap.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/ldap/util_ldap.c b/trunk/modules/ldap/util_ldap.c new file mode 100644 index 0000000000..0ea9a9a147 --- /dev/null +++ b/trunk/modules/ldap/util_ldap.c @@ -0,0 +1,2100 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * util_ldap.c: LDAP things + * + * Original code from auth_ldap module for Apache v1.3: + * Copyright 1998, 1999 Enbridge Pipelines Inc. + * Copyright 1999-2001 Dave Carrigan + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_request.h" +#include "util_ldap.h" +#include "util_ldap_cache.h" + +#include + +#if APR_HAVE_UNISTD_H +#include +#endif + +#if !APR_HAS_LDAP +#error mod_ldap requires APR-util to have LDAP support built in +#endif + +#ifdef AP_NEED_SET_MUTEX_PERMS +#include "unixd.h" +#endif + + /* defines for certificate file types + */ +#define LDAP_CA_TYPE_UNKNOWN 0 +#define LDAP_CA_TYPE_DER 1 +#define LDAP_CA_TYPE_BASE64 2 +#define LDAP_CA_TYPE_CERT7_DB 3 + + +module AP_MODULE_DECLARE_DATA ldap_module; + +static int util_ldap_handler(request_rec *r); +static void *util_ldap_create_config(apr_pool_t *p, server_rec *s); + + +/* + * Some definitions to help between various versions of apache. + */ + +#ifndef DOCTYPE_HTML_2_0 +#define DOCTYPE_HTML_2_0 "\n" +#endif + +#ifndef DOCTYPE_HTML_3_2 +#define DOCTYPE_HTML_3_2 "\n" +#endif + +#ifndef DOCTYPE_HTML_4_0S +#define DOCTYPE_HTML_4_0S "\n" +#endif + +#ifndef DOCTYPE_HTML_4_0T +#define DOCTYPE_HTML_4_0T "\n" +#endif + +#ifndef DOCTYPE_HTML_4_0F +#define DOCTYPE_HTML_4_0F "\n" +#endif + +#define LDAP_CACHE_LOCK() \ + if (st->util_ldap_cache_lock) \ + apr_global_mutex_lock(st->util_ldap_cache_lock) +#define LDAP_CACHE_UNLOCK() \ + if (st->util_ldap_cache_lock) \ + apr_global_mutex_unlock(st->util_ldap_cache_lock) + + +static void util_ldap_strdup (char **str, const char *newstr) +{ + if (*str) { + free(*str); + *str = NULL; + } + + if (newstr) { + *str = calloc(1, strlen(newstr)+1); + strcpy (*str, newstr); + } +} + +/* + * Status Handler + * -------------- + * + * This handler generates a status page about the current performance of + * the LDAP cache. It is enabled as follows: + * + * + * SetHandler ldap-status + * + * + */ +static int util_ldap_handler(request_rec *r) +{ + util_ldap_state_t *st = (util_ldap_state_t *) + ap_get_module_config(r->server->module_config, + &ldap_module); + + r->allowed |= (1 << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + if (strcmp(r->handler, "ldap-status")) { + return DECLINED; + } + + r->content_type = "text/html"; + if (r->header_only) + return OK; + + ap_rputs(DOCTYPE_HTML_3_2 + "LDAP Cache Information\n", r); + ap_rputs("

    LDAP Cache Information" + "

    \n", r); + + util_ald_cache_display(r, st); + + return OK; +} + +/* ------------------------------------------------------------------ */ + + +/* + * Closes an LDAP connection by unlocking it. The next time + * uldap_connection_find() is called this connection will be + * available for reuse. + */ +static void uldap_connection_close(util_ldap_connection_t *ldc) +{ + + /* + * QUESTION: + * + * Is it safe leaving bound connections floating around between the + * different modules? Keeping the user bound is a performance boost, + * but it is also a potential security problem - maybe. + * + * For now we unbind the user when we finish with a connection, but + * we don't have to... + */ + + /* mark our connection as available for reuse */ + +#if APR_HAS_THREADS + apr_thread_mutex_unlock(ldc->lock); +#endif +} + + +/* + * Destroys an LDAP connection by unbinding and closing the connection to + * the LDAP server. It is used to bring the connection back to a known + * state after an error, and during pool cleanup. + */ +static apr_status_t uldap_connection_unbind(void *param) +{ + util_ldap_connection_t *ldc = param; + + if (ldc) { + if (ldc->ldap) { + ldap_unbind_s(ldc->ldap); + ldc->ldap = NULL; + } + ldc->bound = 0; + } + + return APR_SUCCESS; +} + + +/* + * Clean up an LDAP connection by unbinding and unlocking the connection. + * This function is registered with the pool cleanup function - causing + * the LDAP connections to be shut down cleanly on graceful restart. + */ +static apr_status_t uldap_connection_cleanup(void *param) +{ + util_ldap_connection_t *ldc = param; + + if (ldc) { + + /* unbind and disconnect from the LDAP server */ + uldap_connection_unbind(ldc); + + /* free the username and password */ + if (ldc->bindpw) { + free((void*)ldc->bindpw); + } + if (ldc->binddn) { + free((void*)ldc->binddn); + } + + /* unlock this entry */ + uldap_connection_close(ldc); + + } + + return APR_SUCCESS; +} + + +/* + * Connect to the LDAP server and binds. Does not connect if already + * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound. + * + * Returns LDAP_SUCCESS on success; and an error code on failure + */ +static int uldap_connection_open(request_rec *r, + util_ldap_connection_t *ldc) +{ + int rc = 0; + int failures = 0; + int version = LDAP_VERSION3; + apr_ldap_err_t *result = NULL; + struct timeval timeOut = {10,0}; /* 10 second connection timeout */ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(r->server->module_config, + &ldap_module); + + /* sanity check for NULL */ + if (!ldc) { + return -1; + } + + /* If the connection is already bound, return + */ + if (ldc->bound) + { + ldc->reason = "LDAP: connection open successful (already bound)"; + return LDAP_SUCCESS; + } + + /* create the ldap session handle + */ + if (NULL == ldc->ldap) + { + /* Since the host will include a port if the default port is not used, + * always specify the default ports for the port parameter. This will + * allow a host string that contains multiple hosts the ability to mix + * some hosts with ports and some without. All hosts which do not + * specify a port will use the default port. + */ + apr_ldap_init(ldc->pool, &(ldc->ldap), + ldc->host, + APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT, + APR_LDAP_NONE, + &(result)); + + + if (result != NULL && result->rc) { + ldc->reason = result->reason; + } + + if (NULL == ldc->ldap) + { + ldc->bound = 0; + if (NULL == ldc->reason) { + ldc->reason = "LDAP: ldap initialization failed"; + } + else { + ldc->reason = result->reason; + } + return(result->rc); + } + + /* set client certificates */ + if (!apr_is_empty_array(ldc->client_certs)) { + apr_ldap_set_option(ldc->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT, + ldc->client_certs, &(result)); + if (LDAP_SUCCESS != result->rc) { + ldap_unbind_s(ldc->ldap); + ldc->ldap = NULL; + ldc->bound = 0; + ldc->reason = result->reason; + return(result->rc); + } + } + + /* switch on SSL/TLS */ + if (APR_LDAP_NONE != ldc->secure) { + apr_ldap_set_option(ldc->pool, ldc->ldap, + APR_LDAP_OPT_TLS, &ldc->secure, &(result)); + if (LDAP_SUCCESS != result->rc) { + ldap_unbind_s(ldc->ldap); + ldc->ldap = NULL; + ldc->bound = 0; + ldc->reason = result->reason; + return(result->rc); + } + } + + /* Set the alias dereferencing option */ + ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &(ldc->deref)); + + /* always default to LDAP V3 */ + ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); + +/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */ +#ifdef APR_LDAP_OPT_VERIFY_CERT + apr_ldap_set_option(ldc->pool, ldc->ldap, + APR_LDAP_OPT_VERIFY_CERT, &(st->verify_svr_cert), &(result)); +#else +#if defined(LDAPSSL_VERIFY_SERVER) + if (st->verify_svr_cert) { + result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER); + } + else { + result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE); + } +#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT) + /* This is not a per-connection setting so just pass NULL for the + Ldap connection handle */ + if (st->verify_svr_cert) { + int i = LDAP_OPT_X_TLS_DEMAND; + result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i); + } + else { + int i = LDAP_OPT_X_TLS_NEVER; + result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i); + } +#endif +#endif + +#ifdef LDAP_OPT_NETWORK_TIMEOUT + if (st->connectionTimeout > 0) { + timeOut.tv_sec = st->connectionTimeout; + } + + if (st->connectionTimeout >= 0) { + rc = apr_ldap_set_option(ldc->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT, + (void *)&timeOut, &(result)); + if (APR_SUCCESS != rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "LDAP: Could not set the connection timeout"); + } + } +#endif + + + } + + + /* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is + * returned. Break out of the loop on Success or any other error. + * + * NOTE: Looping is probably not a great idea. If the server isn't + * responding the chances it will respond after a few tries are poor. + * However, the original code looped and it only happens on + * the error condition. + */ + for (failures=0; failures<10; failures++) + { + rc = ldap_simple_bind_s(ldc->ldap, + (char *)ldc->binddn, + (char *)ldc->bindpw); + if (LDAP_SERVER_DOWN != rc) { + break; + } + } + + /* free the handle if there was an error + */ + if (LDAP_SUCCESS != rc) + { + ldap_unbind_s(ldc->ldap); + ldc->ldap = NULL; + ldc->bound = 0; + ldc->reason = "LDAP: ldap_simple_bind_s() failed"; + } + else { + ldc->bound = 1; + ldc->reason = "LDAP: connection open successful"; + } + + return(rc); +} + + +/* + * Compare client certificate arrays. + * + * Returns 1 on compare failure, 0 otherwise. + */ +static int compare_client_certs(apr_array_header_t *srcs, + apr_array_header_t *dests) +{ + int i = 0; + struct apr_ldap_opt_tls_cert_t *src, *dest; + + /* arrays both NULL? if so, then equal */ + if (srcs == NULL && dests == NULL) { + return 0; + } + + /* arrays different length or either NULL? If so, then not equal */ + if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) { + return 1; + } + + /* run an actual comparison */ + src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts; + dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts; + for (i = 0; i < srcs->nelts; i++) { + if (apr_strnatcmp(src[i].path, dest[i].path) || + apr_strnatcmp(src[i].password, dest[i].password) || + src[i].type != dest[i].type) { + return 1; + } + } + + /* if we got here, the cert arrays were identical */ + return 0; + +} + + +/* + * Find an existing ldap connection struct that matches the + * provided ldap connection parameters. + * + * If not found in the cache, a new ldc structure will be allocated + * from st->pool and returned to the caller. If found in the cache, + * a pointer to the existing ldc structure will be returned. + */ +static util_ldap_connection_t * + uldap_connection_find(request_rec *r, + const char *host, int port, + const char *binddn, const char *bindpw, + deref_options deref, int secure) +{ + struct util_ldap_connection_t *l, *p; /* To traverse the linked list */ + int secureflag = secure; + + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(r->server->module_config, + &ldap_module); + + +#if APR_HAS_THREADS + /* mutex lock this function */ + if (!st->mutex) { + apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, + st->pool); + } + apr_thread_mutex_lock(st->mutex); +#endif + + if (secure < APR_LDAP_NONE) { + secureflag = st->secure; + } + + /* Search for an exact connection match in the list that is not + * being used. + */ + for (l=st->connections,p=NULL; l; l=l->next) { +#if APR_HAS_THREADS + if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) { +#endif + if ( (l->port == port) && (strcmp(l->host, host) == 0) + && ((!l->binddn && !binddn) || (l->binddn && binddn + && !strcmp(l->binddn, binddn))) + && ((!l->bindpw && !bindpw) || (l->bindpw && bindpw + && !strcmp(l->bindpw, bindpw))) + && (l->deref == deref) && (l->secure == secureflag) + && !compare_client_certs(st->client_certs, l->client_certs)) + { + break; + } +#if APR_HAS_THREADS + /* If this connection didn't match the criteria, then we + * need to unlock the mutex so it is available to be reused. + */ + apr_thread_mutex_unlock(l->lock); + } +#endif + p = l; + } + + /* If nothing found, search again, but we don't care about the + * binddn and bindpw this time. + */ + if (!l) { + for (l=st->connections,p=NULL; l; l=l->next) { +#if APR_HAS_THREADS + if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) { + +#endif + if ((l->port == port) && (strcmp(l->host, host) == 0) && + (l->deref == deref) && (l->secure == secureflag) && + !compare_client_certs(st->client_certs, l->client_certs)) + { + /* the bind credentials have changed */ + l->bound = 0; + util_ldap_strdup((char**)&(l->binddn), binddn); + util_ldap_strdup((char**)&(l->bindpw), bindpw); + break; + } +#if APR_HAS_THREADS + /* If this connection didn't match the criteria, then we + * need to unlock the mutex so it is available to be reused. + */ + apr_thread_mutex_unlock(l->lock); + } +#endif + p = l; + } + } + +/* artificially disable cache */ +/* l = NULL; */ + + /* If no connection what found after the second search, we + * must create one. + */ + if (!l) { + + /* + * Add the new connection entry to the linked list. Note that we + * don't actually establish an LDAP connection yet; that happens + * the first time authentication is requested. + */ + /* create the details to the pool in st */ + l = apr_pcalloc(st->pool, sizeof(util_ldap_connection_t)); +#if APR_HAS_THREADS + apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, st->pool); + apr_thread_mutex_lock(l->lock); +#endif + l->pool = st->pool; + l->bound = 0; + l->host = apr_pstrdup(st->pool, host); + l->port = port; + l->deref = deref; + util_ldap_strdup((char**)&(l->binddn), binddn); + util_ldap_strdup((char**)&(l->bindpw), bindpw); + + /* The security mode after parsing the URL will always be either + * APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://). + * If the security setting is NONE, override it to the security + * setting optionally supplied by the admin using LDAPTrustedMode + */ + l->secure = secureflag; + + /* save away a copy of the client cert list that is presently valid */ + l->client_certs = apr_array_copy_hdr(l->pool, st->client_certs); + + /* add the cleanup to the pool */ + apr_pool_cleanup_register(l->pool, l, + uldap_connection_cleanup, + apr_pool_cleanup_null); + + if (p) { + p->next = l; + } + else { + st->connections = l; + } + } + +#if APR_HAS_THREADS + apr_thread_mutex_unlock(st->mutex); +#endif + return l; +} + +/* ------------------------------------------------------------------ */ + +/* + * Compares two DNs to see if they're equal. The only way to do this correctly + * is to search for the dn and then do ldap_get_dn() on the result. This should + * match the initial dn, since it would have been also retrieved with + * ldap_get_dn(). This is expensive, so if the configuration value + * compare_dn_on_server is false, just does an ordinary strcmp. + * + * The lock for the ldap cache should already be acquired. + */ +static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *dn, + const char *reqdn, int compare_dn_on_server) +{ + int result = 0; + util_url_node_t *curl; + util_url_node_t curnode; + util_dn_compare_node_t *node; + util_dn_compare_node_t newnode; + int failures = 0; + LDAPMessage *res, *entry; + char *searchdn; + + util_ldap_state_t *st = (util_ldap_state_t *) + ap_get_module_config(r->server->module_config, + &ldap_module); + + /* get cache entry (or create one) */ + LDAP_CACHE_LOCK(); + + curnode.url = url; + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl == NULL) { + curl = util_ald_create_caches(st, url); + } + LDAP_CACHE_UNLOCK(); + + /* a simple compare? */ + if (!compare_dn_on_server) { + /* unlock this read lock */ + if (strcmp(dn, reqdn)) { + ldc->reason = "DN Comparison FALSE (direct strcmp())"; + return LDAP_COMPARE_FALSE; + } + else { + ldc->reason = "DN Comparison TRUE (direct strcmp())"; + return LDAP_COMPARE_TRUE; + } + } + + if (curl) { + /* no - it's a server side compare */ + LDAP_CACHE_LOCK(); + + /* is it in the compare cache? */ + newnode.reqdn = (char *)reqdn; + node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); + if (node != NULL) { + /* If it's in the cache, it's good */ + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + ldc->reason = "DN Comparison TRUE (cached)"; + return LDAP_COMPARE_TRUE; + } + + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + } + +start_over: + if (failures++ > 10) { + /* too many failures */ + return result; + } + + /* make a server connection */ + if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) { + /* connect to server failed */ + return result; + } + + /* search for reqdn */ + if ((result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE, + "(objectclass=*)", NULL, 1, + NULL, NULL, NULL, -1, &res)) + == LDAP_SERVER_DOWN) + { + ldc->reason = "DN Comparison ldap_search_ext_s() " + "failed with server down"; + uldap_connection_unbind(ldc); + goto start_over; + } + if (result != LDAP_SUCCESS) { + /* search for reqdn failed - no match */ + ldc->reason = "DN Comparison ldap_search_ext_s() failed"; + return result; + } + + entry = ldap_first_entry(ldc->ldap, res); + searchdn = ldap_get_dn(ldc->ldap, entry); + + ldap_msgfree(res); + if (strcmp(dn, searchdn) != 0) { + /* compare unsuccessful */ + ldc->reason = "DN Comparison FALSE (checked on server)"; + result = LDAP_COMPARE_FALSE; + } + else { + if (curl) { + /* compare successful - add to the compare cache */ + LDAP_CACHE_LOCK(); + newnode.reqdn = (char *)reqdn; + newnode.dn = (char *)dn; + + node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); + if ( (node == NULL) + || (strcmp(reqdn, node->reqdn) != 0) + || (strcmp(dn, node->dn) != 0)) + { + util_ald_cache_insert(curl->dn_compare_cache, &newnode); + } + LDAP_CACHE_UNLOCK(); + } + ldc->reason = "DN Comparison TRUE (checked on server)"; + result = LDAP_COMPARE_TRUE; + } + ldap_memfree(searchdn); + return result; + +} + +/* + * Does an generic ldap_compare operation. It accepts a cache that it will use + * to lookup the compare in the cache. We cache two kinds of compares + * (require group compares) and (require user compares). Each compare has a different + * cache node: require group includes the DN; require user does not because the + * require user cache is owned by the + * + */ +static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *dn, + const char *attrib, const char *value) +{ + int result = 0; + util_url_node_t *curl; + util_url_node_t curnode; + util_compare_node_t *compare_nodep; + util_compare_node_t the_compare_node; + apr_time_t curtime = 0; /* silence gcc -Wall */ + int failures = 0; + + util_ldap_state_t *st = (util_ldap_state_t *) + ap_get_module_config(r->server->module_config, + &ldap_module); + + /* get cache entry (or create one) */ + LDAP_CACHE_LOCK(); + curnode.url = url; + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl == NULL) { + curl = util_ald_create_caches(st, url); + } + LDAP_CACHE_UNLOCK(); + + if (curl) { + /* make a comparison to the cache */ + LDAP_CACHE_LOCK(); + curtime = apr_time_now(); + + the_compare_node.dn = (char *)dn; + the_compare_node.attrib = (char *)attrib; + the_compare_node.value = (char *)value; + the_compare_node.result = 0; + + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + + if (compare_nodep != NULL) { + /* found it... */ + if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) { + /* ...but it is too old */ + util_ald_cache_remove(curl->compare_cache, compare_nodep); + } + else { + /* ...and it is good */ + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + if (LDAP_COMPARE_TRUE == compare_nodep->result) { + ldc->reason = "Comparison true (cached)"; + return compare_nodep->result; + } + else if (LDAP_COMPARE_FALSE == compare_nodep->result) { + ldc->reason = "Comparison false (cached)"; + return compare_nodep->result; + } + else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) { + ldc->reason = "Comparison no such attribute (cached)"; + return compare_nodep->result; + } + else { + ldc->reason = "Comparison undefined (cached)"; + return compare_nodep->result; + } + } + } + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + } + +start_over: + if (failures++ > 10) { + /* too many failures */ + return result; + } + if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) { + /* connect failed */ + return result; + } + + if ((result = ldap_compare_s(ldc->ldap, + (char *)dn, + (char *)attrib, + (char *)value)) + == LDAP_SERVER_DOWN) { + /* connection failed - try again */ + ldc->reason = "ldap_compare_s() failed with server down"; + uldap_connection_unbind(ldc); + goto start_over; + } + + ldc->reason = "Comparison complete"; + if ((LDAP_COMPARE_TRUE == result) || + (LDAP_COMPARE_FALSE == result) || + (LDAP_NO_SUCH_ATTRIBUTE == result)) { + if (curl) { + /* compare completed; caching result */ + LDAP_CACHE_LOCK(); + the_compare_node.lastcompare = curtime; + the_compare_node.result = result; + + /* If the node doesn't exist then insert it, otherwise just update + * it with the last results + */ + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + if ( (compare_nodep == NULL) + || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) + || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0) + || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) + { + util_ald_cache_insert(curl->compare_cache, &the_compare_node); + } + else { + compare_nodep->lastcompare = curtime; + compare_nodep->result = result; + } + LDAP_CACHE_UNLOCK(); + } + if (LDAP_COMPARE_TRUE == result) { + ldc->reason = "Comparison true (adding to cache)"; + return LDAP_COMPARE_TRUE; + } + else if (LDAP_COMPARE_FALSE == result) { + ldc->reason = "Comparison false (adding to cache)"; + return LDAP_COMPARE_FALSE; + } + else { + ldc->reason = "Comparison no such attribute (adding to cache)"; + return LDAP_NO_SUCH_ATTRIBUTE; + } + } + return result; +} + +static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *basedn, + int scope, char **attrs, const char *filter, + const char *bindpw, const char **binddn, + const char ***retvals) +{ + const char **vals = NULL; + int numvals = 0; + int result = 0; + LDAPMessage *res, *entry; + char *dn; + int count; + int failures = 0; + util_url_node_t *curl; /* Cached URL node */ + util_url_node_t curnode; + util_search_node_t *search_nodep; /* Cached search node */ + util_search_node_t the_search_node; + apr_time_t curtime; + + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(r->server->module_config, + &ldap_module); + + /* Get the cache node for this url */ + LDAP_CACHE_LOCK(); + curnode.url = url; + curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, + &curnode); + if (curl == NULL) { + curl = util_ald_create_caches(st, url); + } + LDAP_CACHE_UNLOCK(); + + if (curl) { + LDAP_CACHE_LOCK(); + the_search_node.username = filter; + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if (search_nodep != NULL) { + + /* found entry in search cache... */ + curtime = apr_time_now(); + + /* + * Remove this item from the cache if its expired. If the sent + * password doesn't match the storepassword, the entry will + * be removed and readded later if the credentials pass + * authentication. + */ + if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) { + /* ...but entry is too old */ + util_ald_cache_remove(curl->search_cache, search_nodep); + } + else if ( (search_nodep->bindpw) + && (search_nodep->bindpw[0] != '\0') + && (strcmp(search_nodep->bindpw, bindpw) == 0)) + { + /* ...and entry is valid */ + *binddn = search_nodep->dn; + *retvals = search_nodep->vals; + LDAP_CACHE_UNLOCK(); + ldc->reason = "Authentication successful (cached)"; + return LDAP_SUCCESS; + } + } + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + } + + /* + * At this point, there is no valid cached search, so lets do the search. + */ + + /* + * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here. + */ +start_over: + if (failures++ > 10) { + return result; + } + if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) { + return result; + } + + /* try do the search */ + if ((result = ldap_search_ext_s(ldc->ldap, + (char *)basedn, scope, + (char *)filter, attrs, 0, + NULL, NULL, NULL, -1, &res)) + == LDAP_SERVER_DOWN) + { + ldc->reason = "ldap_search_ext_s() for user failed with server down"; + uldap_connection_unbind(ldc); + goto start_over; + } + + /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */ + if (result != LDAP_SUCCESS) { + ldc->reason = "ldap_search_ext_s() for user failed"; + return result; + } + + /* + * We should have found exactly one entry; to find a different + * number is an error. + */ + count = ldap_count_entries(ldc->ldap, res); + if (count != 1) + { + if (count == 0 ) + ldc->reason = "User not found"; + else + ldc->reason = "User is not unique (search found two " + "or more matches)"; + ldap_msgfree(res); + return LDAP_NO_SUCH_OBJECT; + } + + entry = ldap_first_entry(ldc->ldap, res); + + /* Grab the dn, copy it into the pool, and free it again */ + dn = ldap_get_dn(ldc->ldap, entry); + *binddn = apr_pstrdup(r->pool, dn); + ldap_memfree(dn); + + /* + * A bind to the server with an empty password always succeeds, so + * we check to ensure that the password is not empty. This implies + * that users who actually do have empty passwords will never be + * able to authenticate with this module. I don't see this as a big + * problem. + */ + if (!bindpw || strlen(bindpw) <= 0) { + ldap_msgfree(res); + ldc->reason = "Empty password not allowed"; + return LDAP_INVALID_CREDENTIALS; + } + + /* + * Attempt to bind with the retrieved dn and the password. If the bind + * fails, it means that the password is wrong (the dn obviously + * exists, since we just retrieved it) + */ + if ((result = ldap_simple_bind_s(ldc->ldap, + (char *)*binddn, + (char *)bindpw)) == LDAP_SERVER_DOWN) { + ldc->reason = "ldap_simple_bind_s() to check user credentials " + "failed with server down"; + ldap_msgfree(res); + uldap_connection_unbind(ldc); + goto start_over; + } + + /* failure? if so - return */ + if (result != LDAP_SUCCESS) { + ldc->reason = "ldap_simple_bind_s() to check user credentials failed"; + ldap_msgfree(res); + uldap_connection_unbind(ldc); + return result; + } + else { + /* + * We have just bound the connection to a different user and password + * combination, which might be reused unintentionally next time this + * connection is used from the connection pool. To ensure no confusion, + * we mark the connection as unbound. + */ + ldc->bound = 0; + } + + /* + * Get values for the provided attributes. + */ + if (attrs) { + int k = 0; + int i = 0; + while (attrs[k++]); + vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1)); + numvals = k; + while (attrs[i]) { + char **values; + int j = 0; + char *str = NULL; + /* get values */ + values = ldap_get_values(ldc->ldap, entry, attrs[i]); + while (values && values[j]) { + str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL) + : apr_pstrdup(r->pool, values[j]); + j++; + } + ldap_value_free(values); + vals[i] = str; + i++; + } + *retvals = vals; + } + + /* + * Add the new username to the search cache. + */ + if (curl) { + LDAP_CACHE_LOCK(); + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = bindpw; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { + + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else if ((!search_nodep->bindpw) || + (strcmp(bindpw, search_nodep->bindpw) != 0)) { + + /* Entry in cache is invalid, remove it and insert new one */ + util_ald_cache_remove(curl->search_cache, search_nodep); + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } + LDAP_CACHE_UNLOCK(); + } + ldap_msgfree(res); + + ldc->reason = "Authentication successful"; + return LDAP_SUCCESS; +} + +/* + * This function will return the DN of the entry matching userid. + * It is used to get the DN in case some other module than mod_auth_ldap + * has authenticated the user. + * The function is basically a copy of uldap_cache_checkuserid + * with password checking removed. + */ +static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, + const char *url, const char *basedn, + int scope, char **attrs, const char *filter, + const char **binddn, const char ***retvals) +{ + const char **vals = NULL; + int numvals = 0; + int result = 0; + LDAPMessage *res, *entry; + char *dn; + int count; + int failures = 0; + util_url_node_t *curl; /* Cached URL node */ + util_url_node_t curnode; + util_search_node_t *search_nodep; /* Cached search node */ + util_search_node_t the_search_node; + apr_time_t curtime; + + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(r->server->module_config, + &ldap_module); + + /* Get the cache node for this url */ + LDAP_CACHE_LOCK(); + curnode.url = url; + curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, + &curnode); + if (curl == NULL) { + curl = util_ald_create_caches(st, url); + } + LDAP_CACHE_UNLOCK(); + + if (curl) { + LDAP_CACHE_LOCK(); + the_search_node.username = filter; + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if (search_nodep != NULL) { + + /* found entry in search cache... */ + curtime = apr_time_now(); + + /* + * Remove this item from the cache if its expired. + */ + if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) { + /* ...but entry is too old */ + util_ald_cache_remove(curl->search_cache, search_nodep); + } + else { + /* ...and entry is valid */ + *binddn = search_nodep->dn; + *retvals = search_nodep->vals; + LDAP_CACHE_UNLOCK(); + ldc->reason = "Search successful (cached)"; + return LDAP_SUCCESS; + } + } + /* unlock this read lock */ + LDAP_CACHE_UNLOCK(); + } + + /* + * At this point, there is no valid cached search, so lets do the search. + */ + + /* + * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here. + */ +start_over: + if (failures++ > 10) { + return result; + } + if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) { + return result; + } + + /* try do the search */ + if ((result = ldap_search_ext_s(ldc->ldap, + (char *)basedn, scope, + (char *)filter, attrs, 0, + NULL, NULL, NULL, -1, &res)) + == LDAP_SERVER_DOWN) + { + ldc->reason = "ldap_search_ext_s() for user failed with server down"; + uldap_connection_unbind(ldc); + goto start_over; + } + + /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */ + if (result != LDAP_SUCCESS) { + ldc->reason = "ldap_search_ext_s() for user failed"; + return result; + } + + /* + * We should have found exactly one entry; to find a different + * number is an error. + */ + count = ldap_count_entries(ldc->ldap, res); + if (count != 1) + { + if (count == 0 ) + ldc->reason = "User not found"; + else + ldc->reason = "User is not unique (search found two " + "or more matches)"; + ldap_msgfree(res); + return LDAP_NO_SUCH_OBJECT; + } + + entry = ldap_first_entry(ldc->ldap, res); + + /* Grab the dn, copy it into the pool, and free it again */ + dn = ldap_get_dn(ldc->ldap, entry); + *binddn = apr_pstrdup(st->pool, dn); + ldap_memfree(dn); + + /* + * Get values for the provided attributes. + */ + if (attrs) { + int k = 0; + int i = 0; + while (attrs[k++]); + vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1)); + numvals = k; + while (attrs[i]) { + char **values; + int j = 0; + char *str = NULL; + /* get values */ + values = ldap_get_values(ldc->ldap, entry, attrs[i]); + while (values && values[j]) { + str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL) + : apr_pstrdup(r->pool, values[j]); + j++; + } + ldap_value_free(values); + vals[i] = str; + i++; + } + *retvals = vals; + } + + /* + * Add the new username to the search cache. + */ + if (curl) { + LDAP_CACHE_LOCK(); + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = NULL; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { + + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + /* + * Don't update lastbind on entries with bindpw because + * we haven't verified that password. It's OK to update + * the entry if there is no password in it. + */ + else if (!search_nodep->bindpw) { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } + LDAP_CACHE_UNLOCK(); + } + + ldap_msgfree(res); + + ldc->reason = "Search successful"; + return LDAP_SUCCESS; +} + +/* + * Reports if ssl support is enabled + * + * 1 = enabled, 0 = not enabled + */ +static int uldap_ssl_supported(request_rec *r) +{ + util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( + r->server->module_config, &ldap_module); + + return(st->ssl_supported); +} + + +/* ---------------------------------------- */ +/* config directives */ + + +static const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy, + const char *bytes) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + st->cache_bytes = atol(bytes); + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%" APR_PID_T_FMT "] ldap cache: Setting shared memory " + " cache size to %" APR_SIZE_T_FMT " bytes.", + getpid(), st->cache_bytes); + + return NULL; +} + +static const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy, + const char *file) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + if (file) { + st->cache_file = ap_server_root_relative(st->pool, file); + } + else { + st->cache_file = NULL; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP cache: Setting shared memory cache file to %s bytes.", + st->cache_file); + + return NULL; +} + +static const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, + const char *ttl) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + st->search_cache_ttl = atol(ttl) * 1000000; + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%d] ldap cache: Setting cache TTL to %ld microseconds.", + getpid(), st->search_cache_ttl); + + return NULL; +} + +static const char *util_ldap_set_cache_entries(cmd_parms *cmd, void *dummy, + const char *size) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + + st->search_cache_size = atol(size); + if (st->search_cache_size < 0) { + st->search_cache_size = 0; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%d] ldap cache: Setting search cache size to %ld entries.", + getpid(), st->search_cache_size); + + return NULL; +} + +static const char *util_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy, + const char *ttl) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + st->compare_cache_ttl = atol(ttl) * 1000000; + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%d] ldap cache: Setting operation cache TTL to %ld microseconds.", + getpid(), st->compare_cache_ttl); + + return NULL; +} + +static const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy, + const char *size) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + st->compare_cache_size = atol(size); + if (st->compare_cache_size < 0) { + st->compare_cache_size = 0; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%d] ldap cache: Setting operation cache size to %ld " + "entries.", getpid(), st->compare_cache_size); + + return NULL; +} + + +/** + * Parse the certificate type. + * + * The type can be one of the following: + * CA_DER, CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64, + * CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, KEY_BASE64 + * + * If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned. + */ +static const int util_ldap_parse_cert_type(const char *type) { + + /* Authority file in binary DER format */ + if (0 == strcasecmp("CA_DER", type)) { + return APR_LDAP_CA_TYPE_DER; + } + + /* Authority file in Base64 format */ + else if (0 == strcasecmp("CA_BASE64", type)) { + return APR_LDAP_CA_TYPE_BASE64; + } + + /* Netscape certificate database file/directory */ + else if (0 == strcasecmp("CA_CERT7_DB", type)) { + return APR_LDAP_CA_TYPE_CERT7_DB; + } + + /* Netscape secmod file/directory */ + else if (0 == strcasecmp("CA_SECMOD", type)) { + return APR_LDAP_CA_TYPE_SECMOD; + } + + /* Client cert file in DER format */ + else if (0 == strcasecmp("CERT_DER", type)) { + return APR_LDAP_CERT_TYPE_DER; + } + + /* Client cert file in Base64 format */ + else if (0 == strcasecmp("CERT_BASE64", type)) { + return APR_LDAP_CERT_TYPE_BASE64; + } + + /* Client cert file in PKCS#12 format */ + else if (0 == strcasecmp("CERT_PFX", type)) { + return APR_LDAP_CERT_TYPE_PFX; + } + + /* Netscape client cert database file/directory */ + else if (0 == strcasecmp("CERT_KEY3_DB", type)) { + return APR_LDAP_CERT_TYPE_KEY3_DB; + } + + /* Netscape client cert nickname */ + else if (0 == strcasecmp("CERT_NICKNAME", type)) { + return APR_LDAP_CERT_TYPE_NICKNAME; + } + + /* Client cert key file in DER format */ + else if (0 == strcasecmp("KEY_DER", type)) { + return APR_LDAP_KEY_TYPE_DER; + } + + /* Client cert key file in Base64 format */ + else if (0 == strcasecmp("KEY_BASE64", type)) { + return APR_LDAP_KEY_TYPE_BASE64; + } + + /* Client cert key file in PKCS#12 format */ + else if (0 == strcasecmp("KEY_PFX", type)) { + return APR_LDAP_KEY_TYPE_PFX; + } + + else { + return APR_LDAP_CA_TYPE_UNKNOWN; + } + +} + + +/** + * Set LDAPTrustedGlobalCert. + * + * This directive takes either two or three arguments: + * - certificate type + * - certificate file / directory / nickname + * - certificate password (optional) + * + * This directive may only be used globally. + */ +static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd, + void *dummy, + const char *type, + const char *file, + const char *password) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + apr_finfo_t finfo; + apr_status_t rv; + int cert_type = 0; + apr_ldap_opt_tls_cert_t *cert; + + if (err != NULL) { + return err; + } + + /* handle the certificate type */ + if (type) { + cert_type = util_ldap_parse_cert_type(type); + if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) { + return apr_psprintf(cmd->pool, "The certificate type %s is " + "not recognised. It should be one " + "of CA_DER, CA_BASE64, CA_CERT7_DB, " + "CA_SECMOD, CERT_DER, CERT_BASE64, " + "CERT_KEY3_DB, CERT_NICKNAME, " + "KEY_DER, KEY_BASE64", type); + } + } + else { + return "Certificate type was not specified."; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP: SSL trusted global cert - %s (type %s)", + file, type); + + /* add the certificate to the global array */ + cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs); + cert->type = cert_type; + cert->path = file; + cert->password = password; + + /* if file is a file or path, fix the path */ + if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN && + cert_type != APR_LDAP_CERT_TYPE_NICKNAME) { + + cert->path = ap_server_root_relative(cmd->pool, file); + if (cert->path && + ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool)) + != APR_SUCCESS)) + { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server, + "LDAP: Could not open SSL trusted certificate " + "authority file - %s", + cert->path == NULL ? file : cert->path); + return "Invalid global certificate file path"; + } + } + + return(NULL); +} + + +/** + * Set LDAPTrustedClientCert. + * + * This directive takes either two or three arguments: + * - certificate type + * - certificate file / directory / nickname + * - certificate password (optional) + */ +static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd, + void *config, + const char *type, + const char *file, + const char *password) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + apr_finfo_t finfo; + apr_status_t rv; + int cert_type = 0; + apr_ldap_opt_tls_cert_t *cert; + + /* handle the certificate type */ + if (type) { + cert_type = util_ldap_parse_cert_type(type); + if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) { + return apr_psprintf(cmd->pool, "The certificate type \"%s\" is " + "not recognised. It should be one " + "of CERT_DER, CERT_BASE64, " + "CERT_NICKNAME, CERT_PFX," + "KEY_DER, KEY_BASE64, KEY_PFX", + type); + } + else if (APR_LDAP_CA_TYPE_DER == cert_type || + APR_LDAP_CA_TYPE_BASE64 == cert_type || + APR_LDAP_CA_TYPE_CERT7_DB == cert_type || + APR_LDAP_CA_TYPE_SECMOD == cert_type || + APR_LDAP_CERT_TYPE_PFX == cert_type || + APR_LDAP_CERT_TYPE_KEY3_DB == cert_type) { + return apr_psprintf(cmd->pool, "The certificate type \"%s\" is " + "only valid within a " + "LDAPTrustedGlobalCert directive. " + "Only CERT_DER, CERT_BASE64, " + "CERT_NICKNAME, KEY_DER, and " + "KEY_BASE64 may be used.", type); + } + } + else { + return "Certificate type was not specified."; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP: SSL trusted client cert - %s (type %s)", + file, type); + + /* add the certificate to the global array */ + cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs); + cert->type = cert_type; + cert->path = file; + cert->password = password; + + /* if file is a file or path, fix the path */ + if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN && + cert_type != APR_LDAP_CERT_TYPE_NICKNAME) { + + cert->path = ap_server_root_relative(cmd->pool, file); + if (cert->path && + ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool)) + != APR_SUCCESS)) + { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server, + "LDAP: Could not open SSL client certificate " + "file - %s", + cert->path == NULL ? file : cert->path); + return "Invalid client certificate file path"; + } + + } + + return(NULL); +} + + +/** + * Set LDAPTrustedMode. + * + * This directive sets what encryption mode to use on a connection: + * - None (No encryption) + * - SSL (SSL encryption) + * - STARTTLS (TLS encryption) + */ +static const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy, + const char *mode) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP: SSL trusted mode - %s", + mode); + + if (0 == strcasecmp("NONE", mode)) { + st->secure = APR_LDAP_NONE; + } + else if (0 == strcasecmp("SSL", mode)) { + st->secure = APR_LDAP_SSL; + } + else if ( (0 == strcasecmp("TLS", mode)) + || (0 == strcasecmp("STARTTLS", mode))) { + st->secure = APR_LDAP_STARTTLS; + } + else { + return "Invalid LDAPTrustedMode setting: must be one of NONE, " + "SSL, or TLS/STARTTLS"; + } + + st->secure_set = 1; + return(NULL); +} + +static const char *util_ldap_set_verify_srv_cert(cmd_parms *cmd, + void *dummy, + int mode) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "LDAP: SSL verify server certificate - %s", + mode?"TRUE":"FALSE"); + + st->verify_svr_cert = mode; + + return(NULL); +} + + +static const char *util_ldap_set_connection_timeout(cmd_parms *cmd, + void *dummy, + const char *ttl) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, + &ldap_module); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + +#ifdef LDAP_OPT_NETWORK_TIMEOUT + st->connectionTimeout = atol(ttl); + + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, + "[%d] ldap connection: Setting connection timeout to " + "%ld seconds.", getpid(), st->connectionTimeout); +#else + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, + "LDAP: Connection timout option not supported by the " + "LDAP SDK in use." ); +#endif + + return NULL; +} + + +static void *util_ldap_create_config(apr_pool_t *p, server_rec *s) +{ + util_ldap_state_t *st = + (util_ldap_state_t *)apr_pcalloc(p, sizeof(util_ldap_state_t)); + + st->pool = p; + + st->cache_bytes = 100000; + st->search_cache_ttl = 600000000; + st->search_cache_size = 1024; + st->compare_cache_ttl = 600000000; + st->compare_cache_size = 1024; + st->connections = NULL; + st->ssl_supported = 0; + st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t)); + st->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t)); + st->secure = APR_LDAP_NONE; + st->secure_set = 0; + st->connectionTimeout = 10; + st->verify_svr_cert = 1; + + return st; +} + +static void *util_ldap_merge_config(apr_pool_t *p, void *basev, + void *overridesv) +{ + util_ldap_state_t *st = apr_pcalloc(p, sizeof(util_ldap_state_t)); + util_ldap_state_t *base = (util_ldap_state_t *) basev; + util_ldap_state_t *overrides = (util_ldap_state_t *) overridesv; + + st->pool = p; + + st->cache_bytes = base->cache_bytes; + st->search_cache_ttl = base->search_cache_ttl; + st->search_cache_size = base->search_cache_size; + st->compare_cache_ttl = base->compare_cache_ttl; + st->compare_cache_size = base->compare_cache_size; + st->connections = base->connections; + st->ssl_supported = base->ssl_supported; + st->global_certs = apr_array_append(p, base->global_certs, + overrides->global_certs); + st->client_certs = apr_array_append(p, base->client_certs, + overrides->client_certs); + st->secure = (overrides->secure_set == 0) ? base->secure + : overrides->secure; + + return st; +} + +static apr_status_t util_ldap_cleanup_module(void *data) +{ + + server_rec *s = data; + util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( + s->module_config, &ldap_module); + + if (st->ssl_supported) { + apr_ldap_ssl_deinit(); + } + + return APR_SUCCESS; + +} + +static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t result; + char buf[MAX_STRING_LEN]; + server_rec *s_vhost; + util_ldap_state_t *st_vhost; + + util_ldap_state_t *st = (util_ldap_state_t *) + ap_get_module_config(s->module_config, + &ldap_module); + + void *data; + const char *userdata_key = "util_ldap_init"; + apr_ldap_err_t *result_err = NULL; + int rc; + + /* util_ldap_post_config() will be called twice. Don't bother + * going through all of the initialization on the first call + * because it will just be thrown away.*/ + apr_pool_userdata_get(&data, userdata_key, s->process->pool); + if (!data) { + apr_pool_userdata_set((const void *)1, userdata_key, + apr_pool_cleanup_null, s->process->pool); + +#if APR_HAS_SHARED_MEMORY + /* If the cache file already exists then delete it. Otherwise we are + * going to run into problems creating the shared memory. */ + if (st->cache_file) { + char *lck_file = apr_pstrcat(st->pool, st->cache_file, ".lck", + NULL); + apr_file_remove(st->cache_file, ptemp); + apr_file_remove(lck_file, ptemp); + } +#endif + return OK; + } + +#if APR_HAS_SHARED_MEMORY + /* initializing cache if shared memory size is not zero and we already + * don't have shm address + */ + if (!st->cache_shm && st->cache_bytes > 0) { +#endif + result = util_ldap_cache_init(p, st); + if (result != APR_SUCCESS) { + apr_strerror(result, buf, sizeof(buf)); + ap_log_error(APLOG_MARK, APLOG_ERR, result, s, + "LDAP cache: error while creating a shared memory " + "segment: %s", buf); + } + + +#if APR_HAS_SHARED_MEMORY + if (st->cache_file) { + st->lock_file = apr_pstrcat(st->pool, st->cache_file, ".lck", + NULL); + } + else +#endif + st->lock_file = ap_server_root_relative(st->pool, tmpnam(NULL)); + + result = apr_global_mutex_create(&st->util_ldap_cache_lock, + st->lock_file, APR_LOCK_DEFAULT, + st->pool); + if (result != APR_SUCCESS) { + return result; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + result = unixd_set_global_mutex_perms(st->util_ldap_cache_lock); + if (result != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, result, s, + "LDAP cache: failed to set mutex permissions"); + return result; + } +#endif + + /* merge config in all vhost */ + s_vhost = s->next; + while (s_vhost) { + st_vhost = (util_ldap_state_t *) + ap_get_module_config(s_vhost->module_config, + &ldap_module); + +#if APR_HAS_SHARED_MEMORY + st_vhost->cache_shm = st->cache_shm; + st_vhost->cache_rmm = st->cache_rmm; + st_vhost->cache_file = st->cache_file; + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, + "LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp " + "for VHOST: %s", st->cache_shm, st->cache_rmm, + s_vhost->server_hostname); +#endif + st_vhost->lock_file = st->lock_file; + s_vhost = s_vhost->next; + } +#if APR_HAS_SHARED_MEMORY + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "LDAP cache: LDAPSharedCacheSize is zero, disabling " + "shared memory cache"); + } +#endif + + /* log the LDAP SDK used + */ + { + apr_ldap_err_t *result = NULL; + apr_ldap_info(p, &(result)); + if (result != NULL) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, "%s", result->reason); + } + } + + apr_pool_cleanup_register(p, s, util_ldap_cleanup_module, + util_ldap_cleanup_module); + + /* + * Initialize SSL support, and log the result for the benefit of the admin. + * + * If SSL is not supported it is not necessarily an error, as the + * application may not want to use it. + */ + rc = apr_ldap_ssl_init(p, + NULL, + 0, + &(result_err)); + if (APR_SUCCESS == rc) { + rc = apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, + (void *)st->global_certs, &(result_err)); + } + + if (APR_SUCCESS == rc) { + st->ssl_supported = 1; + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "LDAP: SSL support available" ); + } + else { + st->ssl_supported = 0; + if (NULL != result_err) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "%s", + result_err->reason); + } + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "LDAP: SSL support unavailable" ); + } + + return(OK); +} + +static void util_ldap_child_init(apr_pool_t *p, server_rec *s) +{ + apr_status_t sts; + util_ldap_state_t *st = ap_get_module_config(s->module_config, + &ldap_module); + + if (!st->util_ldap_cache_lock) return; + + sts = apr_global_mutex_child_init(&st->util_ldap_cache_lock, + st->lock_file, p); + if (sts != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s, + "Failed to initialise global mutex %s in child process %" + APR_PID_T_FMT ".", + st->lock_file, getpid()); + return; + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, s, + "Initialisation of global mutex %s in child process %" + APR_PID_T_FMT + " successful.", + st->lock_file, getpid()); + } +} + +command_rec util_ldap_cmds[] = { + AP_INIT_TAKE1("LDAPSharedCacheSize", util_ldap_set_cache_bytes, + NULL, RSRC_CONF, + "Set the size of the shared memory cache (in bytes). Use " + "0 to disable the shared memory cache. (default: 100000)"), + + AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file, + NULL, RSRC_CONF, + "Set the file name for the shared memory cache."), + + AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries, + NULL, RSRC_CONF, + "Set the maximum number of entries that are possible in the " + "LDAP search cache. Use 0 for no limit. " + "-1 disables the cache. (default: 1024)"), + + AP_INIT_TAKE1("LDAPCacheTTL", util_ldap_set_cache_ttl, + NULL, RSRC_CONF, + "Set the maximum time (in seconds) that an item can be " + "cached in the LDAP search cache. Use 0 for no limit. " + "(default 600)"), + + AP_INIT_TAKE1("LDAPOpCacheEntries", util_ldap_set_opcache_entries, + NULL, RSRC_CONF, + "Set the maximum number of entries that are possible " + "in the LDAP compare cache. Use 0 for no limit. " + "Use -1 to disable the cache. (default: 1024)"), + + AP_INIT_TAKE1("LDAPOpCacheTTL", util_ldap_set_opcache_ttl, + NULL, RSRC_CONF, + "Set the maximum time (in seconds) that an item is cached " + "in the LDAP operation cache. Use 0 for no limit. " + "(default: 600)"), + + AP_INIT_TAKE23("LDAPTrustedGlobalCert", util_ldap_set_trusted_global_cert, + NULL, RSRC_CONF, + "Takes three args; the file and/or directory containing " + "the trusted CA certificates (and global client certs " + "for Netware) used to validate the LDAP server. Second " + "arg is the cert type for the first arg, one of CA_DER, " + "CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64, " + "CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, or KEY_BASE64. " + "Third arg is an optional passphrase if applicable."), + + AP_INIT_TAKE23("LDAPTrustedClientCert", util_ldap_set_trusted_client_cert, + NULL, RSRC_CONF, + "Takes three args; the file and/or directory containing " + "the client certificate, or certificate ID used to " + "validate this LDAP client. Second arg is the cert type " + "for the first arg, one of CA_DER, CA_BASE64, CA_CERT7_DB, " + "CA_SECMOD, CERT_DER, CERT_BASE64, CERT_KEY3_DB, " + "CERT_NICKNAME, KEY_DER, or KEY_BASE64. Third arg is an " + "optional passphrase if applicable."), + + AP_INIT_TAKE1("LDAPTrustedMode", util_ldap_set_trusted_mode, + NULL, RSRC_CONF, + "Specify the type of security that should be applied to " + "an LDAP connection. One of; NONE, SSL or STARTTLS."), + + AP_INIT_FLAG("LDAPVerifyServerCert", util_ldap_set_verify_srv_cert, + NULL, RSRC_CONF, + "Set to 'ON' requires that the server certificate be verified " + "before a secure LDAP connection can be establish. Default 'ON'"), + + AP_INIT_TAKE1("LDAPConnectionTimeout", util_ldap_set_connection_timeout, + NULL, RSRC_CONF, + "Specify the LDAP socket connection timeout in seconds " + "(default: 10)"), + + {NULL} +}; + +static void util_ldap_register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(uldap_connection_open); + APR_REGISTER_OPTIONAL_FN(uldap_connection_close); + APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind); + APR_REGISTER_OPTIONAL_FN(uldap_connection_cleanup); + APR_REGISTER_OPTIONAL_FN(uldap_connection_find); + APR_REGISTER_OPTIONAL_FN(uldap_cache_comparedn); + APR_REGISTER_OPTIONAL_FN(uldap_cache_compare); + APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid); + APR_REGISTER_OPTIONAL_FN(uldap_cache_getuserdn); + APR_REGISTER_OPTIONAL_FN(uldap_ssl_supported); + + ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(util_ldap_child_init, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA ldap_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create dir config */ + NULL, /* merge dir config */ + util_ldap_create_config, /* create server config */ + util_ldap_merge_config, /* merge server config */ + util_ldap_cmds, /* command table */ + util_ldap_register_hooks, /* set up request processing hooks */ +}; diff --git a/trunk/modules/ldap/util_ldap_cache.c b/trunk/modules/ldap/util_ldap_cache.c new file mode 100644 index 0000000000..e8feca84e6 --- /dev/null +++ b/trunk/modules/ldap/util_ldap_cache.c @@ -0,0 +1,441 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * util_ldap_cache.c: LDAP cache things + * + * Original code from auth_ldap module for Apache v1.3: + * Copyright 1998, 1999 Enbridge Pipelines Inc. + * Copyright 1999-2001 Dave Carrigan + */ + +#include "httpd.h" +#include "util_ldap.h" +#include "util_ldap_cache.h" +#include + +#if APR_HAS_LDAP + +#if APR_HAS_SHARED_MEMORY +#define MODLDAP_SHMEM_CACHE "/tmp/mod_ldap_cache" +#endif + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_url_node_hash(void *n) +{ + util_url_node_t *node = (util_url_node_t *)n; + return util_ald_hash_string(1, node->url); +} + +int util_ldap_url_node_compare(void *a, void *b) +{ + util_url_node_t *na = (util_url_node_t *)a; + util_url_node_t *nb = (util_url_node_t *)b; + + return(strcmp(na->url, nb->url) == 0); +} + +void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c) +{ + util_url_node_t *n = (util_url_node_t *)c; + util_url_node_t *node = (util_url_node_t *)util_ald_alloc(cache, sizeof(util_url_node_t)); + + if (node) { + if (!(node->url = util_ald_strdup(cache, n->url))) { + util_ald_free(cache, node->url); + return NULL; + } + node->search_cache = n->search_cache; + node->compare_cache = n->compare_cache; + node->dn_compare_cache = n->dn_compare_cache; + return node; + } + else { + return NULL; + } +} + +void util_ldap_url_node_free(util_ald_cache_t *cache, void *n) +{ + util_url_node_t *node = (util_url_node_t *)n; + + util_ald_free(cache, node->url); + util_ald_destroy_cache(node->search_cache); + util_ald_destroy_cache(node->compare_cache); + util_ald_destroy_cache(node->dn_compare_cache); + util_ald_free(cache, node); +} + +void util_ldap_url_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_url_node_t *node = (util_url_node_t *)n; + char date_str[APR_CTIME_LEN+1]; + char *buf; + const char *type_str; + util_ald_cache_t *cache_node; + int x; + + for (x=0;x<3;x++) { + switch (x) { + case 0: + cache_node = node->search_cache; + type_str = "Searches"; + break; + case 1: + cache_node = node->compare_cache; + type_str = "Compares"; + break; + case 2: + default: + cache_node = node->dn_compare_cache; + type_str = "DN Compares"; + break; + } + + if (cache_node->marktime) { + apr_ctime(date_str, cache_node->marktime); + } + else + date_str[0] = 0; + + buf = apr_psprintf(r->pool, + "" + "%s (%s)" + "%ld" + "%ld" + "%ld" + "%ld" + "%s" + "", + node->url, + type_str, + cache_node->size, + cache_node->maxentries, + cache_node->numentries, + cache_node->fullmark, + date_str); + + ap_rputs(buf, r); + } + +} + +/* ------------------------------------------------------------------ */ + +/* Cache functions for search nodes */ +unsigned long util_ldap_search_node_hash(void *n) +{ + util_search_node_t *node = (util_search_node_t *)n; + return util_ald_hash_string(1, ((util_search_node_t *)(node))->username); +} + +int util_ldap_search_node_compare(void *a, void *b) +{ + return(strcmp(((util_search_node_t *)a)->username, + ((util_search_node_t *)b)->username) == 0); +} + +void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c) +{ + util_search_node_t *node = (util_search_node_t *)c; + util_search_node_t *newnode = util_ald_alloc(cache, sizeof(util_search_node_t)); + + /* safety check */ + if (newnode) { + + /* copy vals */ + if (node->vals) { + int k = node->numvals; + int i = 0; + if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + newnode->numvals = node->numvals; + for (;k;k--) { + if (node->vals[i]) { + if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + } + else + newnode->vals[i] = NULL; + i++; + } + } + else { + newnode->vals = NULL; + } + if (!(newnode->username = util_ald_strdup(cache, node->username)) || + !(newnode->dn = util_ald_strdup(cache, node->dn)) ) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + if(node->bindpw) { + if(!(newnode->bindpw = util_ald_strdup(cache, node->bindpw))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + } else { + newnode->bindpw = NULL; + } + newnode->lastbind = node->lastbind; + + } + return (void *)newnode; +} + +void util_ldap_search_node_free(util_ald_cache_t *cache, void *n) +{ + int i = 0; + util_search_node_t *node = (util_search_node_t *)n; + int k = node->numvals; + if (node->vals) { + for (;k;k--,i++) { + if (node->vals[i]) { + util_ald_free(cache, node->vals[i]); + } + } + util_ald_free(cache, node->vals); + } + util_ald_free(cache, node->username); + util_ald_free(cache, node->dn); + util_ald_free(cache, node->bindpw); + util_ald_free(cache, node); +} + +void util_ldap_search_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_search_node_t *node = (util_search_node_t *)n; + char date_str[APR_CTIME_LEN+1]; + char *buf; + + apr_ctime(date_str, node->lastbind); + + buf = apr_psprintf(r->pool, + "" + "%s" + "%s" + "%s" + "", + node->username, + node->dn, + date_str); + + ap_rputs(buf, r); +} + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_compare_node_hash(void *n) +{ + util_compare_node_t *node = (util_compare_node_t *)n; + return util_ald_hash_string(3, node->dn, node->attrib, node->value); +} + +int util_ldap_compare_node_compare(void *a, void *b) +{ + util_compare_node_t *na = (util_compare_node_t *)a; + util_compare_node_t *nb = (util_compare_node_t *)b; + return (strcmp(na->dn, nb->dn) == 0 && + strcmp(na->attrib, nb->attrib) == 0 && + strcmp(na->value, nb->value) == 0); +} + +void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c) +{ + util_compare_node_t *n = (util_compare_node_t *)c; + util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(cache, sizeof(util_compare_node_t)); + + if (node) { + if (!(node->dn = util_ald_strdup(cache, n->dn)) || + !(node->attrib = util_ald_strdup(cache, n->attrib)) || + !(node->value = util_ald_strdup(cache, n->value))) { + util_ldap_compare_node_free(cache, node); + return NULL; + } + node->lastcompare = n->lastcompare; + node->result = n->result; + return node; + } + else { + return NULL; + } +} + +void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n) +{ + util_compare_node_t *node = (util_compare_node_t *)n; + util_ald_free(cache, node->dn); + util_ald_free(cache, node->attrib); + util_ald_free(cache, node->value); + util_ald_free(cache, node); +} + +void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_compare_node_t *node = (util_compare_node_t *)n; + char date_str[APR_CTIME_LEN+1]; + char *buf, *cmp_result; + + apr_ctime(date_str, node->lastcompare); + + if (node->result == LDAP_COMPARE_TRUE) { + cmp_result = "LDAP_COMPARE_TRUE"; + } + else if (node->result == LDAP_COMPARE_FALSE) { + cmp_result = "LDAP_COMPARE_FALSE"; + } + else { + cmp_result = apr_itoa(r->pool, node->result); + } + + buf = apr_psprintf(r->pool, + "" + "%s" + "%s" + "%s" + "%s" + "%s" + "", + node->dn, + node->attrib, + node->value, + date_str, + cmp_result); + + ap_rputs(buf, r); +} + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_dn_compare_node_hash(void *n) +{ + return util_ald_hash_string(1, ((util_dn_compare_node_t *)n)->reqdn); +} + +int util_ldap_dn_compare_node_compare(void *a, void *b) +{ + return (strcmp(((util_dn_compare_node_t *)a)->reqdn, + ((util_dn_compare_node_t *)b)->reqdn) == 0); +} + +void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c) +{ + util_dn_compare_node_t *n = (util_dn_compare_node_t *)c; + util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(cache, sizeof(util_dn_compare_node_t)); + if (node) { + if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) || + !(node->dn = util_ald_strdup(cache, n->dn))) { + util_ldap_dn_compare_node_free(cache, node); + return NULL; + } + return node; + } + else { + return NULL; + } +} + +void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n) +{ + util_dn_compare_node_t *node = (util_dn_compare_node_t *)n; + util_ald_free(cache, node->reqdn); + util_ald_free(cache, node->dn); + util_ald_free(cache, node); +} + +void util_ldap_dn_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_dn_compare_node_t *node = (util_dn_compare_node_t *)n; + char *buf; + + buf = apr_psprintf(r->pool, + "" + "%s" + "%s" + "", + node->reqdn, + node->dn); + + ap_rputs(buf, r); +} + + +/* ------------------------------------------------------------------ */ +apr_status_t util_ldap_cache_child_kill(void *data); +apr_status_t util_ldap_cache_module_kill(void *data); + +apr_status_t util_ldap_cache_module_kill(void *data) +{ + util_ldap_state_t *st = (util_ldap_state_t *)data; + + util_ald_destroy_cache(st->util_ldap_cache); +#if APR_HAS_SHARED_MEMORY + if (st->cache_rmm != NULL) { + apr_rmm_destroy (st->cache_rmm); + st->cache_rmm = NULL; + } + if (st->cache_shm != NULL) { + apr_status_t result = apr_shm_destroy(st->cache_shm); + st->cache_shm = NULL; + if (st->cache_file) { + apr_file_remove(st->cache_file, st->pool); + } + return result; + } +#endif + return APR_SUCCESS; +} + +apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st) +{ +#if APR_HAS_SHARED_MEMORY + apr_status_t result; + + result = apr_shm_create(&st->cache_shm, st->cache_bytes, st->cache_file, st->pool); + if (result == APR_EEXIST) { + /* + * The cache could have already been created (i.e. we may be a child process). See + * if we can attach to the existing shared memory + */ + result = apr_shm_attach(&st->cache_shm, st->cache_file, st->pool); + } + if (result != APR_SUCCESS) { + return result; + } + + /* This will create a rmm "handler" to get into the shared memory area */ + apr_rmm_init(&st->cache_rmm, NULL, (void *)apr_shm_baseaddr_get(st->cache_shm), st->cache_bytes, st->pool); +#endif + + apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null); + + st->util_ldap_cache = + util_ald_create_cache(st, + st->search_cache_size, + util_ldap_url_node_hash, + util_ldap_url_node_compare, + util_ldap_url_node_copy, + util_ldap_url_node_free, + util_ldap_url_node_display); + return APR_SUCCESS; +} + + +#endif /* APR_HAS_LDAP */ diff --git a/trunk/modules/ldap/util_ldap_cache.h b/trunk/modules/ldap/util_ldap_cache.h new file mode 100644 index 0000000000..9ba722c7e9 --- /dev/null +++ b/trunk/modules/ldap/util_ldap_cache.h @@ -0,0 +1,191 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APU_LDAP_CACHE_H +#define APU_LDAP_CACHE_H + +/* + * This switches LDAP support on or off. + */ + +/* this whole thing disappears if LDAP is not enabled */ +#if APR_HAS_LDAP + + +/* + * LDAP Cache Manager + */ + +#include "util_ldap.h" + +typedef struct util_cache_node_t { + void *payload; /* Pointer to the payload */ + apr_time_t add_time; /* Time node was added to cache */ + struct util_cache_node_t *next; +} util_cache_node_t; + +typedef struct util_ald_cache util_ald_cache_t; + +struct util_ald_cache { + unsigned long size; /* Size of cache array */ + unsigned long maxentries; /* Maximum number of cache entries */ + unsigned long numentries; /* Current number of cache entries */ + unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */ + apr_time_t marktime; /* Time that the cache became 3/4 full */ + unsigned long (*hash)(void *); /* Func to hash the payload */ + int (*compare)(void *, void *); /* Func to compare two payloads */ + void * (*copy)(util_ald_cache_t *cache, void *); /* Func to alloc mem and copy payload to new mem */ + void (*free)(util_ald_cache_t *cache, void *); /* Func to free mem used by the payload */ + void (*display)(request_rec *r, util_ald_cache_t *cache, void *); /* Func to display the payload contents */ + util_cache_node_t **nodes; + + unsigned long numpurges; /* No. of times the cache has been purged */ + double avg_purgetime; /* Average time to purge the cache */ + apr_time_t last_purge; /* Time of the last purge */ + unsigned long npurged; /* Number of elements purged in last purge. This is not + obvious: it won't be 3/4 the size of the cache if + there were a lot of expired entries. */ + + unsigned long fetches; /* Number of fetches */ + unsigned long hits; /* Number of cache hits */ + unsigned long inserts; /* Number of inserts */ + unsigned long removes; /* Number of removes */ + +#if APR_HAS_SHARED_MEMORY + apr_shm_t *shm_addr; + apr_rmm_t *rmm_addr; +#endif + +}; + +#ifndef WIN32 +#define ALD_MM_FILE_MODE ( S_IRUSR|S_IWUSR ) +#else +#define ALD_MM_FILE_MODE ( _S_IREAD|_S_IWRITE ) +#endif + + +/* + * LDAP Cache + */ + +/* + * Maintain a cache of LDAP URLs that the server handles. Each node in + * the cache contains the search cache for that URL, and a compare cache + * for the URL. The compare cash is populated when doing require group + * compares. + */ +typedef struct util_url_node_t { + const char *url; + util_ald_cache_t *search_cache; + util_ald_cache_t *compare_cache; + util_ald_cache_t *dn_compare_cache; +} util_url_node_t; + +/* + * We cache every successful search and bind operation, using the username + * as the key. Each node in the cache contains the returned DN, plus the + * password used to bind. + */ +typedef struct util_search_node_t { + const char *username; /* Cache key */ + const char *dn; /* DN returned from search */ + const char *bindpw; /* The most recently used bind password; + NULL if the bind failed */ + apr_time_t lastbind; /* Time of last successful bind */ + const char **vals; /* Values of queried attributes */ + int numvals; /* Number of queried attributes */ +} util_search_node_t; + +/* + * We cache every successful compare operation, using the DN, attrib, and + * value as the key. + */ +typedef struct util_compare_node_t { + const char *dn; /* DN, attrib and value combine to be the key */ + const char *attrib; + const char *value; + apr_time_t lastcompare; + int result; +} util_compare_node_t; + +/* + * We cache every successful compare dn operation, using the dn in the require + * statement and the dn fetched based on the client-provided username. + */ +typedef struct util_dn_compare_node_t { + const char *reqdn; /* The DN in the require dn statement */ + const char *dn; /* The DN found in the search */ +} util_dn_compare_node_t; + + +/* + * Function prototypes for LDAP cache + */ + +/* util_ldap_cache.c */ +unsigned long util_ldap_url_node_hash(void *n); +int util_ldap_url_node_compare(void *a, void *b); +void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_url_node_free(util_ald_cache_t *cache, void *n); +void util_ldap_url_node_display(request_rec *r, util_ald_cache_t *cache, void *n); + +unsigned long util_ldap_search_node_hash(void *n); +int util_ldap_search_node_compare(void *a, void *b); +void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_search_node_free(util_ald_cache_t *cache, void *n); +void util_ldap_search_node_display(request_rec *r, util_ald_cache_t *cache, void *n); + +unsigned long util_ldap_compare_node_hash(void *n); +int util_ldap_compare_node_compare(void *a, void *b); +void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n); +void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n); + +unsigned long util_ldap_dn_compare_node_hash(void *n); +int util_ldap_dn_compare_node_compare(void *a, void *b); +void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c); +void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n); +void util_ldap_dn_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n); + + +/* util_ldap_cache_mgr.c */ + +/* Cache alloc and free function, dealing or not with shm */ +void util_ald_free(util_ald_cache_t *cache, const void *ptr); +void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size); +const char *util_ald_strdup(util_ald_cache_t *cache, const char *s); + +/* Cache managing function */ +unsigned long util_ald_hash_string(int nstr, ...); +void util_ald_cache_purge(util_ald_cache_t *cache); +util_url_node_t *util_ald_create_caches(util_ldap_state_t *s, const char *url); +util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st, + long cache_size, + unsigned long (*hashfunc)(void *), + int (*comparefunc)(void *, void *), + void * (*copyfunc)(util_ald_cache_t *cache, void *), + void (*freefunc)(util_ald_cache_t *cache, void *), + void (*displayfunc)(request_rec *r, util_ald_cache_t *cache, void *)); + +void util_ald_destroy_cache(util_ald_cache_t *cache); +void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload); +void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload); +void util_ald_cache_remove(util_ald_cache_t *cache, void *payload); +char *util_ald_cache_display_stats(request_rec *r, util_ald_cache_t *cache, char *name, char *id); + +#endif /* APR_HAS_LDAP */ +#endif /* APU_LDAP_CACHE_H */ diff --git a/trunk/modules/ldap/util_ldap_cache_mgr.c b/trunk/modules/ldap/util_ldap_cache_mgr.c new file mode 100644 index 0000000000..54021a9f37 --- /dev/null +++ b/trunk/modules/ldap/util_ldap_cache_mgr.c @@ -0,0 +1,759 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * util_ldap_cache_mgr.c: LDAP cache manager things + * + * Original code from auth_ldap module for Apache v1.3: + * Copyright 1998, 1999 Enbridge Pipelines Inc. + * Copyright 1999-2001 Dave Carrigan + */ + +#include "httpd.h" +#include "util_ldap.h" +#include "util_ldap_cache.h" +#include + +#if APR_HAS_LDAP + +/* only here until strdup is gone */ +#include + +/* here till malloc is gone */ +#include + +static const unsigned long primes[] = +{ + 11, + 19, + 37, + 73, + 109, + 163, + 251, + 367, + 557, + 823, + 1237, + 1861, + 2777, + 4177, + 6247, + 9371, + 14057, + 21089, + 31627, + 47431, + 71143, + 106721, + 160073, + 240101, + 360163, + 540217, + 810343, + 1215497, + 1823231, + 2734867, + 4102283, + 6153409, + 9230113, + 13845163, + 0 +}; + +void util_ald_free(util_ald_cache_t *cache, const void *ptr) +{ +#if APR_HAS_SHARED_MEMORY + if (cache->rmm_addr) { + if (ptr) + /* Free in shared memory */ + apr_rmm_free(cache->rmm_addr, apr_rmm_offset_get(cache->rmm_addr, (void *)ptr)); + } + else { + if (ptr) + /* Cache shm is not used */ + free((void *)ptr); + } +#else + if (ptr) + free((void *)ptr); +#endif +} + +void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size) +{ + if (0 == size) + return NULL; +#if APR_HAS_SHARED_MEMORY + if (cache->rmm_addr) { + /* allocate from shared memory */ + apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, size); + return block ? (void *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL; + } + else { + /* Cache shm is not used */ + return (void *)calloc(sizeof(char), size); + } +#else + return (void *)calloc(sizeof(char), size); +#endif +} + +const char *util_ald_strdup(util_ald_cache_t *cache, const char *s) +{ +#if APR_HAS_SHARED_MEMORY + if (cache->rmm_addr) { + /* allocate from shared memory */ + apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, strlen(s)+1); + char *buf = block ? (char *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL; + if (buf) { + strcpy(buf, s); + return buf; + } + else { + return NULL; + } + } else { + /* Cache shm is not used */ + return strdup(s); + } +#else + return strdup(s); +#endif +} + + +/* + * Computes the hash on a set of strings. The first argument is the number + * of strings to hash, the rest of the args are strings. + * Algorithm taken from glibc. + */ +unsigned long util_ald_hash_string(int nstr, ...) +{ + int i; + va_list args; + unsigned long h=0, g; + char *str, *p; + + va_start(args, nstr); + for (i=0; i < nstr; ++i) { + str = va_arg(args, char *); + for (p = str; *p; ++p) { + h = ( h << 4 ) + *p; + if ( ( g = h & 0xf0000000 ) ) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + } + va_end(args); + + return h; +} + + +/* + Purges a cache that has gotten full. We keep track of the time that we + added the entry that made the cache 3/4 full, then delete all entries + that were added before that time. It's pretty simplistic, but time to + purge is only O(n), which is more important. +*/ +void util_ald_cache_purge(util_ald_cache_t *cache) +{ + unsigned long i; + util_cache_node_t *p, *q, **pp; + apr_time_t t; + + if (!cache) + return; + + cache->last_purge = apr_time_now(); + cache->npurged = 0; + cache->numpurges++; + + for (i=0; i < cache->size; ++i) { + pp = cache->nodes + i; + p = *pp; + while (p != NULL) { + if (p->add_time < cache->marktime) { + q = p->next; + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); + cache->numentries--; + cache->npurged++; + p = *pp = q; + } + else { + pp = &(p->next); + p = *pp; + } + } + } + + t = apr_time_now(); + cache->avg_purgetime = + ((t - cache->last_purge) + (cache->avg_purgetime * (cache->numpurges-1))) / + cache->numpurges; +} + + +/* + * create caches + */ +util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url) +{ + util_url_node_t curl, *newcurl = NULL; + util_ald_cache_t *search_cache; + util_ald_cache_t *compare_cache; + util_ald_cache_t *dn_compare_cache; + + /* create the three caches */ + search_cache = util_ald_create_cache(st, + st->search_cache_size, + util_ldap_search_node_hash, + util_ldap_search_node_compare, + util_ldap_search_node_copy, + util_ldap_search_node_free, + util_ldap_search_node_display); + compare_cache = util_ald_create_cache(st, + st->compare_cache_size, + util_ldap_compare_node_hash, + util_ldap_compare_node_compare, + util_ldap_compare_node_copy, + util_ldap_compare_node_free, + util_ldap_compare_node_display); + dn_compare_cache = util_ald_create_cache(st, + st->compare_cache_size, + util_ldap_dn_compare_node_hash, + util_ldap_dn_compare_node_compare, + util_ldap_dn_compare_node_copy, + util_ldap_dn_compare_node_free, + util_ldap_dn_compare_node_display); + + /* check that all the caches initialised successfully */ + if (search_cache && compare_cache && dn_compare_cache) { + + /* The contents of this structure will be duplicated in shared + memory during the insert. So use stack memory rather than + pool memory to avoid a memory leak. */ + memset (&curl, 0, sizeof(util_url_node_t)); + curl.url = url; + curl.search_cache = search_cache; + curl.compare_cache = compare_cache; + curl.dn_compare_cache = dn_compare_cache; + + newcurl = util_ald_cache_insert(st->util_ldap_cache, &curl); + + } + + return newcurl; +} + + +util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st, + long cache_size, + unsigned long (*hashfunc)(void *), + int (*comparefunc)(void *, void *), + void * (*copyfunc)(util_ald_cache_t *cache, void *), + void (*freefunc)(util_ald_cache_t *cache, void *), + void (*displayfunc)(request_rec *r, util_ald_cache_t *cache, void *)) +{ + util_ald_cache_t *cache; + unsigned long i; + + if (cache_size <= 0) + return NULL; + +#if APR_HAS_SHARED_MEMORY + if (!st->cache_rmm) { + return NULL; + } + else { + apr_rmm_off_t block = apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t)); + cache = block ? (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, block) : NULL; + } +#else + cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1); +#endif + if (!cache) + return NULL; + +#if APR_HAS_SHARED_MEMORY + cache->rmm_addr = st->cache_rmm; + cache->shm_addr = st->cache_shm; +#endif + cache->maxentries = cache_size; + cache->numentries = 0; + cache->size = cache_size / 3; + if (cache->size < 64) cache->size = 64; + for (i = 0; primes[i] && primes[i] < cache->size; ++i) ; + cache->size = primes[i]? primes[i] : primes[i-1]; + + cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *)); + if (!cache->nodes) { + util_ald_free(cache, cache); + return NULL; + } + + for (i=0; i < cache->size; ++i) + cache->nodes[i] = NULL; + + cache->hash = hashfunc; + cache->compare = comparefunc; + cache->copy = copyfunc; + cache->free = freefunc; + cache->display = displayfunc; + + cache->fullmark = cache->maxentries / 4 * 3; + cache->marktime = 0; + cache->avg_purgetime = 0.0; + cache->numpurges = 0; + cache->last_purge = 0; + cache->npurged = 0; + + cache->fetches = 0; + cache->hits = 0; + cache->inserts = 0; + cache->removes = 0; + + return cache; +} + +void util_ald_destroy_cache(util_ald_cache_t *cache) +{ + unsigned long i; + util_cache_node_t *p, *q; + + if (cache == NULL) + return; + + for (i = 0; i < cache->size; ++i) { + p = cache->nodes[i]; + q = NULL; + while (p != NULL) { + q = p->next; + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); + p = q; + } + } + util_ald_free(cache, cache->nodes); + util_ald_free(cache, cache); +} + +void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload) +{ + int hashval; + util_cache_node_t *p; + + if (cache == NULL) + return NULL; + + cache->fetches++; + + hashval = (*cache->hash)(payload) % cache->size; + for (p = cache->nodes[hashval]; + p && !(*cache->compare)(p->payload, payload); + p = p->next) ; + + if (p != NULL) { + cache->hits++; + return p->payload; + } + else { + return NULL; + } +} + +/* + * Insert an item into the cache. + * *** Does not catch duplicates!!! *** + */ +void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload) +{ + int hashval; + util_cache_node_t *node; + + /* sanity check */ + if (cache == NULL || payload == NULL) { + return NULL; + } + + /* check if we are full - if so, try purge */ + if (cache->numentries >= cache->maxentries) { + util_ald_cache_purge(cache); + if (cache->numentries >= cache->maxentries) { + /* if the purge was not effective, we leave now to avoid an overflow */ + return NULL; + } + } + + /* should be safe to add an entry */ + if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) { + return NULL; + } + + /* populate the entry */ + cache->inserts++; + hashval = (*cache->hash)(payload) % cache->size; + node->add_time = apr_time_now(); + node->payload = (*cache->copy)(cache, payload); + node->next = cache->nodes[hashval]; + cache->nodes[hashval] = node; + + /* if we reach the full mark, note the time we did so + * for the benefit of the purge function + */ + if (++cache->numentries == cache->fullmark) { + cache->marktime=apr_time_now(); + } + + return node->payload; +} + +void util_ald_cache_remove(util_ald_cache_t *cache, void *payload) +{ + int hashval; + util_cache_node_t *p, *q; + + if (cache == NULL) + return; + + cache->removes++; + hashval = (*cache->hash)(payload) % cache->size; + for (p = cache->nodes[hashval], q=NULL; + p && !(*cache->compare)(p->payload, payload); + p = p->next) { + q = p; + } + + /* If p is null, it means that we couldn't find the node, so just return */ + if (p == NULL) + return; + + if (q == NULL) { + /* We found the node, and it's the first in the list */ + cache->nodes[hashval] = p->next; + } + else { + /* We found the node and it's not the first in the list */ + q->next = p->next; + } + (*cache->free)(cache, p->payload); + util_ald_free(cache, p); + cache->numentries--; +} + +char *util_ald_cache_display_stats(request_rec *r, util_ald_cache_t *cache, char *name, char *id) +{ + unsigned long i; + int totchainlen = 0; + int nchains = 0; + double chainlen; + util_cache_node_t *n; + char *buf, *buf2; + apr_pool_t *p = r->pool; + + if (cache == NULL) { + return ""; + } + + for (i=0; i < cache->size; ++i) { + if (cache->nodes[i] != NULL) { + nchains++; + for (n = cache->nodes[i]; + n != NULL && n != n->next; + n = n->next) { + totchainlen++; + } + } + } + chainlen = nchains? (double)totchainlen / (double)nchains : 0; + + if (id) { + buf2 = apr_psprintf(p, + "%s", + r->uri, + id, + name); + } + else { + buf2 = name; + } + + buf = apr_psprintf(p, + "" + "%s" + "%lu (%.0f%% full)" + "%.1f" + "%lu/%lu" + "%.0f%%" + "%lu/%lu", + buf2, + cache->numentries, + (double)cache->numentries / (double)cache->maxentries * 100.0, + chainlen, + cache->hits, + cache->fetches, + (cache->fetches > 0 ? (double)(cache->hits) / (double)(cache->fetches) * 100.0 : 100.0), + cache->inserts, + cache->removes); + + if (cache->numpurges) { + char str_ctime[APR_CTIME_LEN]; + + apr_ctime(str_ctime, cache->last_purge); + buf = apr_psprintf(p, + "%s" + "%lu\n" + "%s\n", + buf, + cache->numpurges, + str_ctime); + } + else { + buf = apr_psprintf(p, + "%s(none)\n", + buf); + } + + buf = apr_psprintf(p, "%s%.2gms\n", buf, cache->avg_purgetime); + + return buf; +} + +char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st) +{ + unsigned long i,j; + char *buf, *t1, *t2, *t3; + char *id1, *id2, *id3; + char *argfmt = "cache=%s&id=%d&off=%d"; + char *scanfmt = "cache=%4s&id=%u&off=%u%1s"; + apr_pool_t *pool = r->pool; + util_cache_node_t *p = NULL; + util_url_node_t *n = NULL; + + util_ald_cache_t *util_ldap_cache = st->util_ldap_cache; + + + if (!util_ldap_cache) { + return "Cache has not been enabled/initialised."; + } + + if (r->args && strlen(r->args)) { + char cachetype[5], lint[2]; + unsigned int id, off; + char date_str[APR_CTIME_LEN+1]; + + if ((3 == sscanf(r->args, scanfmt, cachetype, &id, &off, lint)) && + (id < util_ldap_cache->size)) { + + if ((p = util_ldap_cache->nodes[id]) != NULL) { + n = (util_url_node_t *)p->payload; + buf = (char*)n->url; + } + else { + buf = ""; + } + + ap_rputs(apr_psprintf(r->pool, + "

    \n" + "\n" + "\n" + "" + "" + "\n" + "
    Cache Name:%s (%s)
    \n

    \n", + buf, + cachetype[0] == 'm'? "Main" : + (cachetype[0] == 's' ? "Search" : + (cachetype[0] == 'c' ? "Compares" : "DNCompares"))), r); + + switch (cachetype[0]) { + case 'm': + if (util_ldap_cache->marktime) { + apr_ctime(date_str, util_ldap_cache->marktime); + } + else + date_str[0] = 0; + + ap_rputs(apr_psprintf(r->pool, + "

    \n" + "\n" + "\n" + "" + "" + "\n" + "\n" + "" + "" + "\n" + "\n" + "" + "" + "\n" + "\n" + "" + "" + "\n" + "\n" + "" + "" + "\n" + "
    Size:%ld
    Max Entries:%ld
    # Entries:%ld
    Full Mark:%ld
    Full Mark Time:%s
    \n

    \n", + util_ldap_cache->size, + util_ldap_cache->maxentries, + util_ldap_cache->numentries, + util_ldap_cache->fullmark, + date_str), r); + + ap_rputs("

    \n" + "\n" + "\n" + "" + "" + "" + "" + "" + "" + "\n", r + ); + for (i=0; i < util_ldap_cache->size; ++i) { + for (p = util_ldap_cache->nodes[i]; p != NULL; p = p->next) { + + (*util_ldap_cache->display)(r, util_ldap_cache, p->payload); + } + } + ap_rputs("
    LDAP URLSizeMax Entries# EntriesFull MarkFull Mark Time
    \n

    \n", r); + + + break; + case 's': + ap_rputs("

    \n" + "\n" + "\n" + "" + "" + "" + "\n", r + ); + if (n) { + for (i=0; i < n->search_cache->size; ++i) { + for (p = n->search_cache->nodes[i]; p != NULL; p = p->next) { + + (*n->search_cache->display)(r, n->search_cache, p->payload); + } + } + } + ap_rputs("
    LDAP FilterUser NameLast Bind
    \n

    \n", r); + break; + case 'c': + ap_rputs("

    \n" + "\n" + "\n" + "" + "" + "" + "" + "" + "\n", r + ); + if (n) { + for (i=0; i < n->compare_cache->size; ++i) { + for (p = n->compare_cache->nodes[i]; p != NULL; p = p->next) { + + (*n->compare_cache->display)(r, n->compare_cache, p->payload); + } + } + } + ap_rputs("
    DNAttributeValueLast CompareResult
    \n

    \n", r); + break; + case 'd': + ap_rputs("

    \n" + "\n" + "\n" + "" + "" + "\n", r + ); + if (n) { + for (i=0; i < n->dn_compare_cache->size; ++i) { + for (p = n->dn_compare_cache->nodes[i]; p != NULL; p = p->next) { + + (*n->dn_compare_cache->display)(r, n->dn_compare_cache, p->payload); + } + } + } + ap_rputs("
    Require DNActual DN
    \n

    \n", r); + break; + default: + break; + } + + } + else { + buf = ""; + } + } + else { + ap_rputs("

    \n" + "\n" + "\n" + "" + "" + "" + "" + "" + "" + "" + "\n", r + ); + + + id1 = apr_psprintf(pool, argfmt, "main", 0, 0); + buf = util_ald_cache_display_stats(r, st->util_ldap_cache, "LDAP URL Cache", id1); + + for (i=0; i < util_ldap_cache->size; ++i) { + for (p = util_ldap_cache->nodes[i],j=0; p != NULL; p = p->next,j++) { + + n = (util_url_node_t *)p->payload; + + t1 = apr_psprintf(pool, "%s (Searches)", n->url); + t2 = apr_psprintf(pool, "%s (Compares)", n->url); + t3 = apr_psprintf(pool, "%s (DNCompares)", n->url); + id1 = apr_psprintf(pool, argfmt, "srch", i, j); + id2 = apr_psprintf(pool, argfmt, "cmpr", i, j); + id3 = apr_psprintf(pool, argfmt, "dncp", i, j); + + buf = apr_psprintf(pool, "%s\n\n" + "%s\n\n" + "%s\n\n" + "%s\n\n", + buf, + util_ald_cache_display_stats(r, n->search_cache, t1, id1), + util_ald_cache_display_stats(r, n->compare_cache, t2, id2), + util_ald_cache_display_stats(r, n->dn_compare_cache, t3, id3) + ); + } + } + ap_rputs(buf, r); + ap_rputs("
    Cache NameEntriesAvg. Chain Len.HitsIns/RemPurgesAvg Purge Time
    \n

    \n", r); + } + + return buf; +} + +#endif /* APR_HAS_LDAP */ diff --git a/trunk/modules/loggers/.indent.pro b/trunk/modules/loggers/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/loggers/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/loggers/Makefile.in b/trunk/modules/loggers/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/loggers/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/loggers/NWGNUforensic b/trunk/modules/loggers/NWGNUforensic new file mode 100644 index 0000000000..58bbbcee43 --- /dev/null +++ b/trunk/modules/loggers/NWGNUforensic @@ -0,0 +1,261 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = forensic + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Forensic Logging Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Forensic Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/forensic.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_log_forensic.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + log_forensic_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/loggers/NWGNUmakefile b/trunk/modules/loggers/NWGNUmakefile new file mode 100644 index 0000000000..9c42c52fd0 --- /dev/null +++ b/trunk/modules/loggers/NWGNUmakefile @@ -0,0 +1,247 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/modlogio.nlm \ + $(OBJDIR)/forensic.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/loggers/NWGNUmodlogio b/trunk/modules/loggers/NWGNUmodlogio new file mode 100644 index 0000000000..77f42d52ef --- /dev/null +++ b/trunk/modules/loggers/NWGNUmodlogio @@ -0,0 +1,261 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = logio + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) IO Logging Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Logio Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/modlogio.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_logio.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + logio_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/loggers/config.m4 b/trunk/modules/loggers/config.m4 new file mode 100644 index 0000000000..2d1d142b0c --- /dev/null +++ b/trunk/modules/loggers/config.m4 @@ -0,0 +1,17 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(loggers) + +APACHE_MODULE(log_config, logging configuration, , , yes) +APACHE_MODULE(log_forensic, forensic logging) + +if test "x$enable_log_forensic" != "xno"; then + # mod_log_forensic needs test_char.h + APR_ADDTO(INCLUDES, [-I\$(top_builddir)/server]) +fi + +APACHE_MODULE(logio, input and output logging, , , most) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/loggers/mod_log_config.c b/trunk/modules/loggers/mod_log_config.c new file mode 100644 index 0000000000..1845999e33 --- /dev/null +++ b/trunk/modules/loggers/mod_log_config.c @@ -0,0 +1,1522 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Modified by djm@va.pubnix.com: + * If no TransferLog is given explicitly, decline to log. + * + * This is module implements the TransferLog directive (same as the + * common log module), and additional directives, LogFormat and CustomLog. + * + * + * Syntax: + * + * TransferLog fn Logs transfers to fn in standard log format, unless + * a custom format is set with LogFormat + * LogFormat format Set a log format from TransferLog files + * CustomLog fn format + * Log to file fn with format given by the format + * argument + * + * CookieLog fn For backwards compatability with old Cookie + * logging module - now deprecated. + * + * There can be any number of TransferLog and CustomLog + * commands. Each request will be logged to _ALL_ the + * named files, in the appropriate format. + * + * If no TransferLog or CustomLog directive appears in a VirtualHost, + * the request will be logged to the log file(s) defined outside + * the virtual host section. If a TransferLog or CustomLog directive + * appears in the VirtualHost section, the log files defined outside + * the VirtualHost will _not_ be used. This makes this module compatable + * with the CLF and config log modules, where the use of TransferLog + * inside the VirtualHost section overrides its use outside. + * + * Examples: + * + * TransferLog logs/access_log + * + * LogFormat "... custom format ..." + * TransferLog log/virtual_only + * CustomLog log/virtual_useragents "%t %{user-agent}i" + * + * + * This will log using CLF to access_log any requests handled by the + * main server, while any requests to the virtual host will be logged + * with the "... custom format..." to virtual_only _AND_ using + * the custom user-agent log to virtual_useragents. + * + * Note that the NCSA referer and user-agent logs are easily added with + * CustomLog: + * CustomLog logs/referer "%{referer}i -> %U" + * CustomLog logs/agent "%{user-agent}i" + * + * RefererIgnore functionality can be obtained with conditional + * logging (SetEnvIf and CustomLog ... env=!VAR). + * + * But using this method allows much easier modification of the + * log format, e.g. to log hosts along with UA: + * CustomLog logs/referer "%{referer}i %U %h" + * + * The argument to LogFormat and CustomLog is a string, which can include + * literal characters copied into the log files, and '%' directives as + * follows: + * + * %...B: bytes sent, excluding HTTP headers. + * %...b: bytes sent, excluding HTTP headers in CLF format, i.e. a '-' + * when no bytes where sent (rather than a '0'. + * %...{FOOBAR}C: The contents of the HTTP cookie FOOBAR + * %...{FOOBAR}e: The contents of the environment variable FOOBAR + * %...f: filename + * %...h: remote host + * %...a: remote IP-address + * %...A: local IP-address + * %...{Foobar}i: The contents of Foobar: header line(s) in the request + * sent to the client. + * %...l: remote logname (from identd, if supplied) + * %...{Foobar}n: The contents of note "Foobar" from another module. + * %...{Foobar}o: The contents of Foobar: header line(s) in the reply. + * %...p: the port the request was served to + * %...P: the process ID of the child that serviced the request. + * %...{format}P: the process ID or thread ID of the child/thread that + * serviced the request + * %...r: first line of request + * %...s: status. For requests that got internally redirected, this + * is status of the *original* request --- %...>s for the last. + * %...t: time, in common log format time format + * %...{format}t: The time, in the form given by format, which should + * be in strftime(3) format. + * %...T: the time taken to serve the request, in seconds. + * %...D: the time taken to serve the request, in micro seconds. + * %...u: remote user (from auth; may be bogus if return status (%s) is 401) + * %...U: the URL path requested. + * %...v: the configured name of the server (i.e. which virtual host?) + * %...V: the server name according to the UseCanonicalName setting + * %...m: the request method + * %...H: the request protocol + * %...q: the query string prepended by "?", or empty if no query string + * %...X: Status of the connection. + * 'X' = connection aborted before the response completed. + * '+' = connection may be kept alive after the response is sent. + * '-' = connection will be closed after the response is sent. + (This directive was %...c in late versions of Apache 1.3, but + this conflicted with the historical ssl %...{var}c syntax.) +* + * The '...' can be nothing at all (e.g. "%h %u %r %s %b"), or it can + * indicate conditions for inclusion of the item (which will cause it + * to be replaced with '-' if the condition is not met). Note that + * there is no escaping performed on the strings from %r, %...i and + * %...o; some with long memories may remember that I thought this was + * a bad idea, once upon a time, and I'm still not comfortable with + * it, but it is difficult to see how to "do the right thing" with all + * of '%..i', unless we URL-escape everything and break with CLF. + * + * The forms of condition are a list of HTTP status codes, which may + * or may not be preceded by '!'. Thus, '%400,501{User-agent}i' logs + * User-agent: on 400 errors and 501 errors (Bad Request, Not + * Implemented) only; '%!200,304,302{Referer}i' logs Referer: on all + * requests which did *not* return some sort of normal status. + * + * The default LogFormat reproduces CLF; see below. + * + * The way this is supposed to work with virtual hosts is as follows: + * a virtual host can have its own LogFormat, or its own TransferLog. + * If it doesn't have its own LogFormat, it inherits from the main + * server. If it doesn't have its own TransferLog, it writes to the + * same descriptor (meaning the same process for "| ..."). + * + * --- rst */ + +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_hash.h" +#include "apr_optional.h" +#include "apr_anylock.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "mod_log_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" /* For REMOTE_NAME */ +#include "http_log.h" +#include "http_protocol.h" +#include "util_time.h" +#include "ap_mpm.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_LIMITS_H +#include +#endif + +#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" + +module AP_MODULE_DECLARE_DATA log_config_module; + + +static int xfer_flags = (APR_WRITE | APR_APPEND | APR_CREATE | APR_LARGEFILE); +static apr_fileperms_t xfer_perms = APR_OS_DEFAULT; +static apr_hash_t *log_hash; +static apr_status_t ap_default_log_writer(request_rec *r, + void *handle, + const char **strs, + int *strl, + int nelts, + apr_size_t len); +static apr_status_t ap_buffered_log_writer(request_rec *r, + void *handle, + const char **strs, + int *strl, + int nelts, + apr_size_t len); +static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, + const char* name); +static void *ap_buffered_log_writer_init(apr_pool_t *p, server_rec *s, + const char* name); + +static ap_log_writer_init* ap_log_set_writer_init(ap_log_writer_init *handle); +static ap_log_writer* ap_log_set_writer(ap_log_writer *handle); +static ap_log_writer *log_writer = ap_default_log_writer; +static ap_log_writer_init *log_writer_init = ap_default_log_writer_init; +static int buffered_logs = 0; /* default unbuffered */ +static apr_array_header_t *all_buffered_logs = NULL; + +/* POSIX.1 defines PIPE_BUF as the maximum number of bytes that is + * guaranteed to be atomic when writing a pipe. And PIPE_BUF >= 512 + * is guaranteed. So we'll just guess 512 in the event the system + * doesn't have this. Now, for file writes there is actually no limit, + * the entire write is atomic. Whether all systems implement this + * correctly is another question entirely ... so we'll just use PIPE_BUF + * because it's probably a good guess as to what is implemented correctly + * everywhere. + */ +#ifdef PIPE_BUF +#define LOG_BUFSIZE PIPE_BUF +#else +#define LOG_BUFSIZE (512) +#endif + +/* + * multi_log_state is our per-(virtual)-server configuration. We store + * an array of the logs we are going to use, each of type config_log_state. + * If a default log format is given by LogFormat, store in default_format + * (backward compat. with mod_log_config). We also store for each virtual + * server a pointer to the logs specified for the main server, so that if this + * vhost has no logs defined, we can use the main server's logs instead. + * + * So, for the main server, config_logs contains a list of the log files + * and server_config_logs is empty. For a vhost, server_config_logs + * points to the same array as config_logs in the main server, and + * config_logs points to the array of logs defined inside this vhost, + * which might be empty. + */ + +typedef struct { + const char *default_format_string; + apr_array_header_t *default_format; + apr_array_header_t *config_logs; + apr_array_header_t *server_config_logs; + apr_table_t *formats; +} multi_log_state; + +/* + * config_log_state holds the status of a single log file. fname might + * be NULL, which means this module does no logging for this + * request. format might be NULL, in which case the default_format + * from the multi_log_state should be used, or if that is NULL as + * well, use the CLF. + * log_writer is NULL before the log file is opened and is + * set to a opaque structure (usually a fd) after it is opened. + + */ +typedef struct { + apr_file_t *handle; + apr_size_t outcnt; + char outbuf[LOG_BUFSIZE]; + apr_anylock_t mutex; +} buffered_log; + +typedef struct { + const char *fname; + const char *format_string; + apr_array_header_t *format; + void *log_writer; + char *condition_var; +} config_log_state; + +/* + * Format items... + * Note that many of these could have ap_sprintfs replaced with static buffers. + */ + +typedef struct { + ap_log_handler_fn_t *func; + char *arg; + int condition_sense; + int want_orig; + apr_array_header_t *conditions; +} log_format_item; + +static char *format_integer(apr_pool_t *p, int i) +{ + return apr_itoa(p, i); +} + +static char *pfmt(apr_pool_t *p, int i) +{ + if (i <= 0) { + return "-"; + } + else { + return format_integer(p, i); + } +} + +static const char *constant_item(request_rec *dummy, char *stuff) +{ + return stuff; +} + +static const char *log_remote_host(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, ap_get_remote_host(r->connection, + r->per_dir_config, + REMOTE_NAME, NULL)); +} + +static const char *log_remote_address(request_rec *r, char *a) +{ + return r->connection->remote_ip; +} + +static const char *log_local_address(request_rec *r, char *a) +{ + return r->connection->local_ip; +} + +static const char *log_remote_logname(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, ap_get_remote_logname(r)); +} + +static const char *log_remote_user(request_rec *r, char *a) +{ + char *rvalue = r->user; + + if (rvalue == NULL) { + rvalue = "-"; + } + else if (strlen(rvalue) == 0) { + rvalue = "\"\""; + } + else { + rvalue = ap_escape_logitem(r->pool, rvalue); + } + + return rvalue; +} + +static const char *log_request_line(request_rec *r, char *a) +{ + /* NOTE: If the original request contained a password, we + * re-write the request line here to contain XXXXXX instead: + * (note the truncation before the protocol string for HTTP/0.9 requests) + * (note also that r->the_request contains the unmodified request) + */ + return ap_escape_logitem(r->pool, + (r->parsed_uri.password) + ? apr_pstrcat(r->pool, r->method, " ", + apr_uri_unparse(r->pool, + &r->parsed_uri, 0), + r->assbackwards ? NULL : " ", + r->protocol, NULL) + : r->the_request); +} + +static const char *log_request_file(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, r->filename); +} +static const char *log_request_uri(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, r->uri); +} +static const char *log_request_method(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, r->method); +} +static const char *log_request_protocol(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, r->protocol); +} +static const char *log_request_query(request_rec *r, char *a) +{ + return (r->args) ? apr_pstrcat(r->pool, "?", + ap_escape_logitem(r->pool, r->args), NULL) + : ""; +} +static const char *log_status(request_rec *r, char *a) +{ + return pfmt(r->pool, r->status); +} + +static const char *clf_log_bytes_sent(request_rec *r, char *a) +{ + if (!r->sent_bodyct || !r->bytes_sent) { + return "-"; + } + else { + return apr_off_t_toa(r->pool, r->bytes_sent); + } +} + +static const char *log_bytes_sent(request_rec *r, char *a) +{ + if (!r->sent_bodyct || !r->bytes_sent) { + return "0"; + } + else { + return apr_off_t_toa(r->pool, r->bytes_sent); + } +} + + +static const char *log_header_in(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a)); +} + +static APR_INLINE char *find_multiple_headers(apr_pool_t *pool, + const apr_table_t *table, + const char *key) +{ + const apr_array_header_t *elts; + const apr_table_entry_t *t_elt; + const apr_table_entry_t *t_end; + apr_size_t len; + struct sle { + struct sle *next; + const char *value; + apr_size_t len; + } *result_list, *rp; + + elts = apr_table_elts(table); + + if (!elts->nelts) { + return NULL; + } + + t_elt = (const apr_table_entry_t *)elts->elts; + t_end = t_elt + elts->nelts; + len = 1; /* \0 */ + result_list = rp = NULL; + + do { + if (!strcasecmp(t_elt->key, key)) { + if (!result_list) { + result_list = rp = apr_palloc(pool, sizeof(*rp)); + } + else { + rp = rp->next = apr_palloc(pool, sizeof(*rp)); + len += 2; /* ", " */ + } + + rp->next = NULL; + rp->value = t_elt->val; + rp->len = strlen(rp->value); + + len += rp->len; + } + ++t_elt; + } while (t_elt < t_end); + + if (result_list) { + char *result = apr_palloc(pool, len); + char *cp = result; + + rp = result_list; + while (rp) { + if (rp != result_list) { + *cp++ = ','; + *cp++ = ' '; + } + memcpy(cp, rp->value, rp->len); + cp += rp->len; + rp = rp->next; + } + *cp = '\0'; + + return result; + } + + return NULL; +} + +static const char *log_header_out(request_rec *r, char *a) +{ + const char *cp = NULL; + + if (!strcasecmp(a, "Content-type") && r->content_type) { + cp = ap_field_noparam(r->pool, r->content_type); + } + else if (!strcasecmp(a, "Set-Cookie")) { + cp = find_multiple_headers(r->pool, r->headers_out, a); + } + else { + cp = apr_table_get(r->headers_out, a); + } + + return ap_escape_logitem(r->pool, cp); +} + +static const char *log_note(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, apr_table_get(r->notes, a)); +} +static const char *log_env_var(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, apr_table_get(r->subprocess_env, a)); +} + +static const char *log_cookie(request_rec *r, char *a) +{ + const char *cookies; + const char *start_cookie; + + if ((cookies = apr_table_get(r->headers_in, "Cookie"))) { + if ((start_cookie = ap_strstr_c(cookies,a))) { + char *cookie, *end_cookie; + start_cookie += strlen(a) + 1; /* cookie_name + '=' */ + cookie = apr_pstrdup(r->pool, start_cookie); + /* kill everything in cookie after ';' */ + end_cookie = strchr(cookie, ';'); + if (end_cookie) { + *end_cookie = '\0'; + } + return ap_escape_logitem(r->pool, cookie); + } + } + return NULL; +} + +static const char *log_request_time_custom(request_rec *r, char *a, + apr_time_exp_t *xt) +{ + apr_size_t retcode; + char tstr[MAX_STRING_LEN]; + apr_strftime(tstr, &retcode, sizeof(tstr), a, xt); + return apr_pstrdup(r->pool, tstr); +} + +#define DEFAULT_REQUEST_TIME_SIZE 32 +typedef struct { + unsigned t; + char timestr[DEFAULT_REQUEST_TIME_SIZE]; + unsigned t_validate; +} cached_request_time; + +#define TIME_CACHE_SIZE 4 +#define TIME_CACHE_MASK 3 +static cached_request_time request_time_cache[TIME_CACHE_SIZE]; + +static const char *log_request_time(request_rec *r, char *a) +{ + apr_time_exp_t xt; + + /* ### I think getting the time again at the end of the request + * just for logging is dumb. i know it's "required" for CLF. + * folks writing log parsing tools don't realise that out of order + * times have always been possible (consider what happens if one + * process calculates the time to log, but then there's a context + * switch before it writes and before that process is run again the + * log rotation occurs) and they should just fix their tools rather + * than force the server to pay extra cpu cycles. if you've got + * a problem with this, you can set the define. -djg + */ + if (a && *a) { /* Custom format */ + /* The custom time formatting uses a very large temp buffer + * on the stack. To avoid using so much stack space in the + * common case where we're not using a custom format, the code + * for the custom format in a separate function. (That's why + * log_request_time_custom is not inlined right here.) + */ +#ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE + ap_explode_recent_localtime(&xt, apr_time_now()); +#else + ap_explode_recent_localtime(&xt, r->request_time); +#endif + return log_request_time_custom(r, a, &xt); + } + else { /* CLF format */ + /* This code uses the same technique as ap_explode_recent_localtime(): + * optimistic caching with logic to detect and correct race conditions. + * See the comments in server/util_time.c for more information. + */ + cached_request_time* cached_time = apr_palloc(r->pool, + sizeof(*cached_time)); +#ifdef I_INSIST_ON_EXTRA_CYCLES_FOR_CLF_COMPLIANCE + apr_time_t request_time = apr_time_now(); +#else + apr_time_t request_time = r->request_time; +#endif + unsigned t_seconds = (unsigned)apr_time_sec(request_time); + unsigned i = t_seconds & TIME_CACHE_MASK; + memcpy(cached_time, &(request_time_cache[i]), sizeof(*cached_time)); + if ((t_seconds != cached_time->t) || + (t_seconds != cached_time->t_validate)) { + + /* Invalid or old snapshot, so compute the proper time string + * and store it in the cache + */ + char sign; + int timz; + + ap_explode_recent_localtime(&xt, request_time); + timz = xt.tm_gmtoff; + if (timz < 0) { + timz = -timz; + sign = '-'; + } + else { + sign = '+'; + } + cached_time->t = t_seconds; + apr_snprintf(cached_time->timestr, DEFAULT_REQUEST_TIME_SIZE, + "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]", + xt.tm_mday, apr_month_snames[xt.tm_mon], + xt.tm_year+1900, xt.tm_hour, xt.tm_min, xt.tm_sec, + sign, timz / (60*60), (timz % (60*60)) / 60); + cached_time->t_validate = t_seconds; + memcpy(&(request_time_cache[i]), cached_time, + sizeof(*cached_time)); + } + return cached_time->timestr; + } +} + +static const char *log_request_duration(request_rec *r, char *a) +{ + apr_time_t duration = apr_time_now() - r->request_time; + return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, apr_time_sec(duration)); +} + +static const char *log_request_duration_microseconds(request_rec *r, char *a) +{ + return apr_psprintf(r->pool, "%" APR_TIME_T_FMT, + (apr_time_now() - r->request_time)); +} + +/* These next two routines use the canonical name:port so that log + * parsers don't need to duplicate all the vhost parsing crud. + */ +static const char *log_virtual_host(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, r->server->server_hostname); +} + +static const char *log_server_port(request_rec *r, char *a) +{ + return apr_psprintf(r->pool, "%u", + r->server->port ? r->server->port : ap_default_port(r)); +} + +/* This respects the setting of UseCanonicalName so that + * the dynamic mass virtual hosting trick works better. + */ +static const char *log_server_name(request_rec *r, char *a) +{ + return ap_escape_logitem(r->pool, ap_get_server_name(r)); +} + +static const char *log_pid_tid(request_rec *r, char *a) +{ + if (*a == '\0' || !strcmp(a, "pid")) { + return apr_psprintf(r->pool, "%" APR_PID_T_FMT, getpid()); + } + else if (!strcmp(a, "tid")) { +#if APR_HAS_THREADS + apr_os_thread_t tid = apr_os_thread_current(); +#else + int tid = 0; /* APR will format "0" anyway but an arg is needed */ +#endif + return apr_psprintf(r->pool, "%pT", &tid); + } + /* bogus format */ + return a; +} + +static const char *log_connection_status(request_rec *r, char *a) +{ + if (r->connection->aborted) + return "X"; + + if (r->connection->keepalive == AP_CONN_KEEPALIVE && + (!r->server->keep_alive_max || + (r->server->keep_alive_max - r->connection->keepalives) > 0)) { + return "+"; + } + return "-"; +} + +/***************************************************************** + * + * Parsing the log format string + */ + +static char *parse_log_misc_string(apr_pool_t *p, log_format_item *it, + const char **sa) +{ + const char *s; + char *d; + + it->func = constant_item; + it->conditions = NULL; + + s = *sa; + while (*s && *s != '%') { + s++; + } + /* + * This might allocate a few chars extra if there's a backslash + * escape in the format string. + */ + it->arg = apr_palloc(p, s - *sa + 1); + + d = it->arg; + s = *sa; + while (*s && *s != '%') { + if (*s != '\\') { + *d++ = *s++; + } + else { + s++; + switch (*s) { + case '\\': + *d++ = '\\'; + s++; + break; + case 'r': + *d++ = '\r'; + s++; + break; + case 'n': + *d++ = '\n'; + s++; + break; + case 't': + *d++ = '\t'; + s++; + break; + default: + /* copy verbatim */ + *d++ = '\\'; + /* + * Allow the loop to deal with this *s in the normal + * fashion so that it handles end of string etc. + * properly. + */ + break; + } + } + } + *d = '\0'; + + *sa = s; + return NULL; +} + +static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) +{ + const char *s = *sa; + ap_log_handler *handler; + + if (*s != '%') { + return parse_log_misc_string(p, it, sa); + } + + ++s; + it->condition_sense = 0; + it->conditions = NULL; + + if (*s == '%') { + it->arg = "%"; + it->func = constant_item; + *sa = ++s; + + return NULL; + } + + it->want_orig = -1; + it->arg = ""; /* For safety's sake... */ + + while (*s) { + int i; + + switch (*s) { + case '!': + ++s; + it->condition_sense = !it->condition_sense; + break; + + case '<': + ++s; + it->want_orig = 1; + break; + + case '>': + ++s; + it->want_orig = 0; + break; + + case ',': + ++s; + break; + + case '{': + ++s; + it->arg = ap_getword(p, &s, '}'); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + i = *s - '0'; + while (apr_isdigit(*++s)) { + i = i * 10 + (*s) - '0'; + } + if (!it->conditions) { + it->conditions = apr_array_make(p, 4, sizeof(int)); + } + *(int *) apr_array_push(it->conditions) = i; + break; + + default: + handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); + if (!handler) { + char dummy[2]; + + dummy[0] = s[-1]; + dummy[1] = '\0'; + return apr_pstrcat(p, "Unrecognized LogFormat directive %", + dummy, NULL); + } + it->func = handler->func; + if (it->want_orig == -1) { + it->want_orig = handler->want_orig_default; + } + *sa = s; + return NULL; + } + } + + return "Ran off end of LogFormat parsing args to some directive"; +} + +static apr_array_header_t *parse_log_string(apr_pool_t *p, const char *s, const char **err) +{ + apr_array_header_t *a = apr_array_make(p, 30, sizeof(log_format_item)); + char *res; + + while (*s) { + if ((res = parse_log_item(p, (log_format_item *) apr_array_push(a), &s))) { + *err = res; + return NULL; + } + } + + s = APR_EOL_STR; + parse_log_item(p, (log_format_item *) apr_array_push(a), &s); + return a; +} + +/***************************************************************** + * + * Actually logging. + */ + +static const char *process_item(request_rec *r, request_rec *orig, + log_format_item *item) +{ + const char *cp; + + /* First, see if we need to process this thing at all... */ + + if (item->conditions && item->conditions->nelts != 0) { + int i; + int *conds = (int *) item->conditions->elts; + int in_list = 0; + + for (i = 0; i < item->conditions->nelts; ++i) { + if (r->status == conds[i]) { + in_list = 1; + break; + } + } + + if ((item->condition_sense && in_list) + || (!item->condition_sense && !in_list)) { + return "-"; + } + } + + /* We do. Do it... */ + + cp = (*item->func) (item->want_orig ? orig : r, item->arg); + return cp ? cp : "-"; +} + +static void flush_log(buffered_log *buf) +{ + if (buf->outcnt && buf->handle != NULL) { + apr_file_write(buf->handle, buf->outbuf, &buf->outcnt); + buf->outcnt = 0; + } +} + + +static int config_log_transaction(request_rec *r, config_log_state *cls, + apr_array_header_t *default_format) +{ + log_format_item *items; + const char **strs; + int *strl; + request_rec *orig; + int i; + apr_size_t len = 0; + apr_array_header_t *format; + char *envar; + apr_status_t rv; + + if (cls->fname == NULL) { + return DECLINED; + } + + /* + * See if we've got any conditional envariable-controlled logging decisions + * to make. + */ + if (cls->condition_var != NULL) { + envar = cls->condition_var; + if (*envar != '!') { + if (apr_table_get(r->subprocess_env, envar) == NULL) { + return DECLINED; + } + } + else { + if (apr_table_get(r->subprocess_env, &envar[1]) != NULL) { + return DECLINED; + } + } + } + + format = cls->format ? cls->format : default_format; + + strs = apr_palloc(r->pool, sizeof(char *) * (format->nelts)); + strl = apr_palloc(r->pool, sizeof(int) * (format->nelts)); + items = (log_format_item *) format->elts; + + orig = r; + while (orig->prev) { + orig = orig->prev; + } + while (r->next) { + r = r->next; + } + + for (i = 0; i < format->nelts; ++i) { + strs[i] = process_item(r, orig, &items[i]); + } + + for (i = 0; i < format->nelts; ++i) { + len += strl[i] = strlen(strs[i]); + } + if (!log_writer) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, + "log writer isn't correctly setup"); + return HTTP_INTERNAL_SERVER_ERROR; + } + rv = log_writer(r, cls->log_writer, strs, strl, format->nelts, len); + /* xxx: do we return an error on log_writer? */ + return OK; +} + +static int multi_log_transaction(request_rec *r) +{ + multi_log_state *mls = ap_get_module_config(r->server->module_config, + &log_config_module); + config_log_state *clsarray; + int i; + + /* + * Log this transaction.. + */ + if (mls->config_logs->nelts) { + clsarray = (config_log_state *) mls->config_logs->elts; + for (i = 0; i < mls->config_logs->nelts; ++i) { + config_log_state *cls = &clsarray[i]; + + config_log_transaction(r, cls, mls->default_format); + } + } + else if (mls->server_config_logs) { + clsarray = (config_log_state *) mls->server_config_logs->elts; + for (i = 0; i < mls->server_config_logs->nelts; ++i) { + config_log_state *cls = &clsarray[i]; + + config_log_transaction(r, cls, mls->default_format); + } + } + + return OK; +} + +/***************************************************************** + * + * Module glue... + */ + +static void *make_config_log_state(apr_pool_t *p, server_rec *s) +{ + multi_log_state *mls; + + mls = (multi_log_state *) apr_palloc(p, sizeof(multi_log_state)); + mls->config_logs = apr_array_make(p, 1, sizeof(config_log_state)); + mls->default_format_string = NULL; + mls->default_format = NULL; + mls->server_config_logs = NULL; + mls->formats = apr_table_make(p, 4); + apr_table_setn(mls->formats, "CLF", DEFAULT_LOG_FORMAT); + + return mls; +} + +/* + * Use the merger to simply add a pointer from the vhost log state + * to the log of logs specified for the non-vhost configuration. Make sure + * vhosts inherit any globally-defined format names. + */ + +static void *merge_config_log_state(apr_pool_t *p, void *basev, void *addv) +{ + multi_log_state *base = (multi_log_state *) basev; + multi_log_state *add = (multi_log_state *) addv; + + add->server_config_logs = base->config_logs; + if (!add->default_format) { + add->default_format_string = base->default_format_string; + add->default_format = base->default_format; + } + add->formats = apr_table_overlay(p, base->formats, add->formats); + + return add; +} + +/* + * Set the default logfile format, or define a nickname for a format string. + */ +static const char *log_format(cmd_parms *cmd, void *dummy, const char *fmt, + const char *name) +{ + const char *err_string = NULL; + multi_log_state *mls = ap_get_module_config(cmd->server->module_config, + &log_config_module); + + /* + * If we were given two arguments, the second is a name to be given to the + * format. This syntax just defines the nickname - it doesn't actually + * make the format the default. + */ + if (name != NULL) { + parse_log_string(cmd->pool, fmt, &err_string); + if (err_string == NULL) { + apr_table_setn(mls->formats, name, fmt); + } + } + else { + mls->default_format_string = fmt; + mls->default_format = parse_log_string(cmd->pool, fmt, &err_string); + } + return err_string; +} + + +static const char *add_custom_log(cmd_parms *cmd, void *dummy, const char *fn, + const char *fmt, const char *envclause) +{ + const char *err_string = NULL; + multi_log_state *mls = ap_get_module_config(cmd->server->module_config, + &log_config_module); + config_log_state *cls; + + cls = (config_log_state *) apr_array_push(mls->config_logs); + cls->condition_var = NULL; + if (envclause != NULL) { + if (strncasecmp(envclause, "env=", 4) != 0) { + return "error in condition clause"; + } + if ((envclause[4] == '\0') + || ((envclause[4] == '!') && (envclause[5] == '\0'))) { + return "missing environment variable name"; + } + cls->condition_var = apr_pstrdup(cmd->pool, &envclause[4]); + } + + cls->fname = fn; + cls->format_string = fmt; + if (fmt == NULL) { + cls->format = NULL; + } + else { + cls->format = parse_log_string(cmd->pool, fmt, &err_string); + } + cls->log_writer = NULL; + + return err_string; +} + +static const char *set_transfer_log(cmd_parms *cmd, void *dummy, + const char *fn) +{ + return add_custom_log(cmd, dummy, fn, NULL, NULL); +} + +static const char *set_cookie_log(cmd_parms *cmd, void *dummy, const char *fn) +{ + return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t", NULL); +} + +static const char *set_buffered_logs_on(cmd_parms *parms, void *dummy, int flag) +{ + buffered_logs = flag; + if (buffered_logs) { + ap_log_set_writer_init(ap_buffered_log_writer_init); + ap_log_set_writer(ap_buffered_log_writer); + } + return NULL; +} +static const command_rec config_log_cmds[] = +{ +AP_INIT_TAKE23("CustomLog", add_custom_log, NULL, RSRC_CONF, + "a file name, a custom log format string or format name, " + "and an optional \"env=\" clause (see docs)"), +AP_INIT_TAKE1("TransferLog", set_transfer_log, NULL, RSRC_CONF, + "the filename of the access log"), +AP_INIT_TAKE12("LogFormat", log_format, NULL, RSRC_CONF, + "a log format string (see docs) and an optional format name"), +AP_INIT_TAKE1("CookieLog", set_cookie_log, NULL, RSRC_CONF, + "the filename of the cookie log"), +AP_INIT_FLAG("BufferedLogs", set_buffered_logs_on, NULL, RSRC_CONF, + "Enable Buffered Logging (experimental)"), + {NULL} +}; + +static config_log_state *open_config_log(server_rec *s, apr_pool_t *p, + config_log_state *cls, + apr_array_header_t *default_format) +{ + if (cls->log_writer != NULL) { + return cls; /* virtual config shared w/main server */ + } + + if (cls->fname == NULL) { + return cls; /* Leave it NULL to decline. */ + } + + cls->log_writer = log_writer_init(p, s, cls->fname); + if (cls->log_writer == NULL) + return NULL; + + return cls; +} + +static int open_multi_logs(server_rec *s, apr_pool_t *p) +{ + int i; + multi_log_state *mls = ap_get_module_config(s->module_config, + &log_config_module); + config_log_state *clsarray; + const char *dummy; + const char *format; + + if (mls->default_format_string) { + format = apr_table_get(mls->formats, mls->default_format_string); + if (format) { + mls->default_format = parse_log_string(p, format, &dummy); + } + } + + if (!mls->default_format) { + mls->default_format = parse_log_string(p, DEFAULT_LOG_FORMAT, &dummy); + } + + if (mls->config_logs->nelts) { + clsarray = (config_log_state *) mls->config_logs->elts; + for (i = 0; i < mls->config_logs->nelts; ++i) { + config_log_state *cls = &clsarray[i]; + + if (cls->format_string) { + format = apr_table_get(mls->formats, cls->format_string); + if (format) { + cls->format = parse_log_string(p, format, &dummy); + } + } + + if (!open_config_log(s, p, cls, mls->default_format)) { + /* Failure already logged by open_config_log */ + return DONE; + } + } + } + else if (mls->server_config_logs) { + clsarray = (config_log_state *) mls->server_config_logs->elts; + for (i = 0; i < mls->server_config_logs->nelts; ++i) { + config_log_state *cls = &clsarray[i]; + + if (cls->format_string) { + format = apr_table_get(mls->formats, cls->format_string); + if (format) { + cls->format = parse_log_string(p, format, &dummy); + } + } + + if (!open_config_log(s, p, cls, mls->default_format)) { + /* Failure already logged by open_config_log */ + return DONE; + } + } + } + + return OK; +} + + +static apr_status_t flush_all_logs(void *data) +{ + server_rec *s = data; + multi_log_state *mls; + apr_array_header_t *log_list; + config_log_state *clsarray; + buffered_log *buf; + int i; + + if (!buffered_logs) + return APR_SUCCESS; + + for (; s; s = s->next) { + mls = ap_get_module_config(s->module_config, &log_config_module); + log_list = NULL; + if (mls->config_logs->nelts) { + log_list = mls->config_logs; + } + else if (mls->server_config_logs) { + log_list = mls->server_config_logs; + } + if (log_list) { + clsarray = (config_log_state *) log_list->elts; + for (i = 0; i < log_list->nelts; ++i) { + buf = clsarray[i].log_writer; + flush_log(buf); + } + } + } + return APR_SUCCESS; +} + + +static int init_config_log(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s) +{ + int res; + + /* First init the buffered logs array, which is needed when opening the logs. */ + if (buffered_logs) { + all_buffered_logs = apr_array_make(p, 5, sizeof(buffered_log *)); + } + + /* Next, do "physical" server, which gets default log fd and format + * for the virtual servers, if they don't override... + */ + res = open_multi_logs(s, p); + + /* Then, virtual servers */ + + for (s = s->next; (res == OK) && s; s = s->next) { + res = open_multi_logs(s, p); + } + + return res; +} + +static void init_child(apr_pool_t *p, server_rec *s) +{ + int mpm_threads; + + ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads); + + /* Now register the last buffer flush with the cleanup engine */ + if (buffered_logs) { + int i; + buffered_log **array = (buffered_log **)all_buffered_logs->elts; + + apr_pool_cleanup_register(p, s, flush_all_logs, flush_all_logs); + + for (i = 0; i < all_buffered_logs->nelts; i++) { + buffered_log *this = array[i]; + +#if APR_HAS_THREADS + if (mpm_threads > 1) { + apr_status_t rv; + + this->mutex.type = apr_anylock_threadmutex; + rv = apr_thread_mutex_create(&this->mutex.lock.tm, + APR_THREAD_MUTEX_DEFAULT, + p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "could not initialize buffered log mutex, " + "transfer log may become corrupted"); + this->mutex.type = apr_anylock_none; + } + } + else +#endif + { + this->mutex.type = apr_anylock_none; + } + } + } +} + +static void ap_register_log_handler(apr_pool_t *p, char *tag, + ap_log_handler_fn_t *handler, int def) +{ + ap_log_handler *log_struct = apr_palloc(p, sizeof(*log_struct)); + log_struct->func = handler; + log_struct->want_orig_default = def; + + apr_hash_set(log_hash, tag, 1, (const void *)log_struct); +} +static ap_log_writer_init* ap_log_set_writer_init(ap_log_writer_init *handle) +{ + ap_log_writer_init *old = log_writer_init; + log_writer_init = handle; + + return old; + +} +static ap_log_writer *ap_log_set_writer(ap_log_writer *handle) +{ + ap_log_writer *old = log_writer; + log_writer = handle; + + return old; +} + +static apr_status_t ap_default_log_writer( request_rec *r, + void *handle, + const char **strs, + int *strl, + int nelts, + apr_size_t len) + +{ + char *str; + char *s; + int i; + apr_status_t rv; + + str = apr_palloc(r->pool, len + 1); + + for (i = 0, s = str; i < nelts; ++i) { + memcpy(s, strs[i], strl[i]); + s += strl[i]; + } + + rv = apr_file_write((apr_file_t*)handle, str, &len); + + return rv; +} +static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, + const char* name) +{ + if (*name == '|') { + piped_log *pl; + + pl = ap_open_piped_log(p, name + 1); + if (pl == NULL) { + return NULL;; + } + return ap_piped_log_write_fd(pl); + } + else { + const char *fname = ap_server_root_relative(p, name); + apr_file_t *fd; + apr_status_t rv; + + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + "invalid transfer log path %s.", name); + return NULL; + } + rv = apr_file_open(&fd, fname, xfer_flags, xfer_perms, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "could not open transfer log file %s.", fname); + return NULL; + } + return fd; + } +} +static void *ap_buffered_log_writer_init(apr_pool_t *p, server_rec *s, + const char* name) +{ + buffered_log *b; + b = apr_pcalloc(p, sizeof(buffered_log)); + b->handle = ap_default_log_writer_init(p, s, name); + + if (b->handle) { + *(buffered_log **)apr_array_push(all_buffered_logs) = b; + return b; + } + else + return NULL; +} +static apr_status_t ap_buffered_log_writer(request_rec *r, + void *handle, + const char **strs, + int *strl, + int nelts, + apr_size_t len) + +{ + char *str; + char *s; + int i; + apr_status_t rv; + buffered_log *buf = (buffered_log*)handle; + + if ((rv = APR_ANYLOCK_LOCK(&buf->mutex)) != APR_SUCCESS) { + return rv; + } + + if (len + buf->outcnt > LOG_BUFSIZE) { + flush_log(buf); + } + if (len >= LOG_BUFSIZE) { + apr_size_t w; + + str = apr_palloc(r->pool, len + 1); + for (i = 0, s = str; i < nelts; ++i) { + memcpy(s, strs[i], strl[i]); + s += strl[i]; + } + w = len; + rv = apr_file_write(buf->handle, str, &w); + + } + else { + for (i = 0, s = &buf->outbuf[buf->outcnt]; i < nelts; ++i) { + memcpy(s, strs[i], strl[i]); + s += strl[i]; + } + buf->outcnt += len; + rv = APR_SUCCESS; + } + + APR_ANYLOCK_UNLOCK(&buf->mutex); + return rv; +} + +static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register; + + log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler); + + if (log_pfn_register) { + log_pfn_register(p, "h", log_remote_host, 0); + log_pfn_register(p, "a", log_remote_address, 0 ); + log_pfn_register(p, "A", log_local_address, 0 ); + log_pfn_register(p, "l", log_remote_logname, 0); + log_pfn_register(p, "u", log_remote_user, 0); + log_pfn_register(p, "t", log_request_time, 0); + log_pfn_register(p, "f", log_request_file, 0); + log_pfn_register(p, "b", clf_log_bytes_sent, 0); + log_pfn_register(p, "B", log_bytes_sent, 0); + log_pfn_register(p, "i", log_header_in, 0); + log_pfn_register(p, "o", log_header_out, 0); + log_pfn_register(p, "n", log_note, 0); + log_pfn_register(p, "e", log_env_var, 0); + log_pfn_register(p, "V", log_server_name, 0); + log_pfn_register(p, "v", log_virtual_host, 0); + log_pfn_register(p, "p", log_server_port, 0); + log_pfn_register(p, "P", log_pid_tid, 0); + log_pfn_register(p, "H", log_request_protocol, 0); + log_pfn_register(p, "m", log_request_method, 0); + log_pfn_register(p, "q", log_request_query, 0); + log_pfn_register(p, "X", log_connection_status, 0); + log_pfn_register(p, "C", log_cookie, 0); + log_pfn_register(p, "r", log_request_line, 1); + log_pfn_register(p, "D", log_request_duration_microseconds, 1); + log_pfn_register(p, "T", log_request_duration, 1); + log_pfn_register(p, "U", log_request_uri, 1); + log_pfn_register(p, "s", log_status, 1); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_pre_config(log_pre_config,NULL,NULL,APR_HOOK_REALLY_FIRST); + ap_hook_child_init(init_child,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_open_logs(init_config_log,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_log_transaction(multi_log_transaction,NULL,NULL,APR_HOOK_MIDDLE); + + /* Init log_hash before we register the optional function. It is + * possible for the optional function, ap_register_log_handler, + * to be called before any other mod_log_config hooks are called. + * As a policy, we should init everything required by an optional function + * before calling APR_REGISTER_OPTIONAL_FN. + */ + log_hash = apr_hash_make(p); + APR_REGISTER_OPTIONAL_FN(ap_register_log_handler); + APR_REGISTER_OPTIONAL_FN(ap_log_set_writer_init); + APR_REGISTER_OPTIONAL_FN(ap_log_set_writer); +} + +module AP_MODULE_DECLARE_DATA log_config_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config */ + NULL, /* merge per-dir config */ + make_config_log_state, /* server config */ + merge_config_log_state, /* merge server config */ + config_log_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + diff --git a/trunk/modules/loggers/mod_log_config.dsp b/trunk/modules/loggers/mod_log_config.dsp new file mode 100644 index 0000000000..978ae5824c --- /dev/null +++ b/trunk/modules/loggers/mod_log_config.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_log_config" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_log_config - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_log_config.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_log_config.mak" CFG="mod_log_config - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_log_config - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_log_config - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_log_config - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_log_config_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_log_config - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_log_config_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_log_config.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_config.so + +!ENDIF + +# Begin Target + +# Name "mod_log_config - Win32 Release" +# Name "mod_log_config - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_log_config.c +# End Source File +# Begin Source File + +SOURCE=.\mod_log_config.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_log_config - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_log_config.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_log_config.so "log_config_module for Apache" ../../include/ap_release.h > .\mod_log_config.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_log_config - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_log_config.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_log_config.so "log_config_module for Apache" ../../include/ap_release.h > .\mod_log_config.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/loggers/mod_log_config.exp b/trunk/modules/loggers/mod_log_config.exp new file mode 100644 index 0000000000..0749e52704 --- /dev/null +++ b/trunk/modules/loggers/mod_log_config.exp @@ -0,0 +1 @@ +log_config_module diff --git a/trunk/modules/loggers/mod_log_config.h b/trunk/modules/loggers/mod_log_config.h new file mode 100644 index 0000000000..73acd17d95 --- /dev/null +++ b/trunk/modules/loggers/mod_log_config.h @@ -0,0 +1,63 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_optional.h" +#include "httpd.h" +#include "scoreboard.h" + +#ifndef _MOD_LOG_CONFIG_H +#define _MOD_LOG_CONFIG_H 1 + +/** + * callback function prototype for a external log handler + */ +typedef const char *ap_log_handler_fn_t(request_rec *r, char *a); + +/** + * callback function prototype for external writer initialization. + */ +typedef void *ap_log_writer_init(apr_pool_t *p, server_rec *s, + const char *name); +/** + * callback which gets called where there is a log line to write. + */ +typedef apr_status_t ap_log_writer( + request_rec *r, + void *handle, + const char **portions, + int *lengths, + int nelts, + apr_size_t len); + +typedef struct ap_log_handler { + ap_log_handler_fn_t *func; + int want_orig_default; +} ap_log_handler; + +APR_DECLARE_OPTIONAL_FN(void, ap_register_log_handler, + (apr_pool_t *p, char *tag, ap_log_handler_fn_t *func, + int def)); +/** + * you will need to set your init handler *BEFORE* the open_logs + * in mod_log_config gets executed + */ +APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writer_init *func)); +/** + * you should probably set the writer at the same time (ie..before open_logs) + */ +APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func)); + +#endif /* MOD_LOG_CONFIG */ diff --git a/trunk/modules/loggers/mod_log_forensic.c b/trunk/modules/loggers/mod_log_forensic.c new file mode 100644 index 0000000000..34387d7127 --- /dev/null +++ b/trunk/modules/loggers/mod_log_forensic.c @@ -0,0 +1,288 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * See also support/check_forensic. + * Relate the forensic log to the transfer log by including + * %{forensic-id}n in the custom log format, for example: + * CustomLog logs/custom "%h %l %u %t \"%r\" %>s %b %{forensic-id}n" + * + * Credit is due to Tina Bird , whose + * idea this module was. + * + * Ben Laurie 29/12/2003 + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "apr_strings.h" +#include "apr_atomic.h" +#include "http_protocol.h" +#include "test_char.h" +#if APR_HAVE_UNISTD_H +#include +#endif + +module AP_MODULE_DECLARE_DATA log_forensic_module; + +typedef struct fcfg { + const char *logname; + apr_file_t *fd; +} fcfg; + +static apr_uint32_t next_id; + +static void *make_forensic_log_scfg(apr_pool_t *p, server_rec *s) +{ + fcfg *cfg = apr_pcalloc(p, sizeof *cfg); + + cfg->logname = NULL; + cfg->fd = NULL; + + return cfg; +} + +static void *merge_forensic_log_scfg(apr_pool_t *p, void *parent, void *new) +{ + fcfg *cfg = apr_pcalloc(p, sizeof *cfg); + fcfg *pc = parent; + fcfg *nc = new; + + cfg->logname = apr_pstrdup(p, nc->logname ? nc->logname : pc->logname); + cfg->fd = NULL; + + return cfg; +} + +static int open_log(server_rec *s, apr_pool_t *p) +{ + fcfg *cfg = ap_get_module_config(s->module_config, &log_forensic_module); + + if (!cfg->logname || cfg->fd) + return 1; + + if (*cfg->logname == '|') { + piped_log *pl; + const char *pname = ap_server_root_relative(p, cfg->logname + 1); + + pl = ap_open_piped_log(p, pname); + if (pl == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "couldn't spawn forensic log pipe %s", cfg->logname); + return 0; + } + cfg->fd = ap_piped_log_write_fd(pl); + } + else { + const char *fname = ap_server_root_relative(p, cfg->logname); + apr_status_t rv; + + if ((rv = apr_file_open(&cfg->fd, fname, + APR_WRITE | APR_APPEND | APR_CREATE, + APR_OS_DEFAULT, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "could not open forensic log file %s.", fname); + return 0; + } + } + + return 1; +} + +static int log_init(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, + server_rec *s) +{ + for ( ; s ; s = s->next) { + if (!open_log(s, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + return OK; +} + + +/* e is the first _invalid_ location in q + N.B. returns the terminating NUL. + */ +static char *log_escape(char *q, const char *e, const char *p) +{ + for ( ; *p ; ++p) { + ap_assert(q < e); + if (test_char_table[*(unsigned char *)p]&T_ESCAPE_FORENSIC) { + ap_assert(q+2 < e); + *q++ = '%'; + sprintf(q, "%02x", *(unsigned char *)p); + q += 2; + } + else + *q++ = *p; + } + ap_assert(q < e); + *q = '\0'; + + return q; +} + +typedef struct hlog { + char *log; + char *pos; + char *end; + apr_pool_t *p; + apr_size_t count; +} hlog; + +static int count_string(const char *p) +{ + int n; + + for (n = 0 ; *p ; ++p, ++n) + if (test_char_table[*(unsigned char *)p]&T_ESCAPE_FORENSIC) + n += 2; + return n; +} + +static int count_headers(void *h_, const char *key, const char *value) +{ + hlog *h = h_; + + h->count += count_string(key)+count_string(value)+2; + + return 1; +} + +static int log_headers(void *h_, const char *key, const char *value) +{ + hlog *h = h_; + + /* note that we don't have to check h->pos here, coz its been done + for us by log_escape */ + *h->pos++ = '|'; + h->pos = log_escape(h->pos, h->end, key); + *h->pos++ = ':'; + h->pos = log_escape(h->pos, h->end, value); + + return 1; +} + +static int log_before(request_rec *r) +{ + fcfg *cfg = ap_get_module_config(r->server->module_config, + &log_forensic_module); + const char *id; + hlog h; + apr_size_t n; + apr_status_t rv; + + if (!cfg->fd || r->prev) { + return DECLINED; + } + + if (!(id = apr_table_get(r->subprocess_env, "UNIQUE_ID"))) { + /* we make the assumption that we can't go through all the PIDs in + under 1 second */ + id = apr_psprintf(r->pool, "%x:%lx:%x", getpid(), time(NULL), + apr_atomic_inc32(&next_id)); + } + ap_set_module_config(r->request_config, &log_forensic_module, (char *)id); + + h.p = r->pool; + h.count = 0; + + apr_table_do(count_headers, &h, r->headers_in, NULL); + + h.count += 1+strlen(id)+1+count_string(r->the_request)+1+1; + h.log = apr_palloc(r->pool, h.count); + h.pos = h.log; + h.end = h.log+h.count; + + *h.pos++ = '+'; + strcpy(h.pos, id); + h.pos += strlen(h.pos); + *h.pos++ = '|'; + h.pos = log_escape(h.pos, h.end, r->the_request); + + apr_table_do(log_headers, &h, r->headers_in, NULL); + + ap_assert(h.pos < h.end); + *h.pos++ = '\n'; + + n = h.count-1; + rv = apr_file_write(cfg->fd, h.log, &n); + ap_assert(rv == APR_SUCCESS && n == h.count-1); + + apr_table_setn(r->notes, "forensic-id", id); + + return OK; +} + +static int log_after(request_rec *r) +{ + fcfg *cfg = ap_get_module_config(r->server->module_config, + &log_forensic_module); + const char *id = ap_get_module_config(r->request_config, + &log_forensic_module); + char *s; + apr_size_t l, n; + apr_status_t rv; + + if (!cfg->fd) { + return DECLINED; + } + + s = apr_pstrcat(r->pool, "-", id, "\n", NULL); + l = n = strlen(s); + rv = apr_file_write(cfg->fd, s, &n); + ap_assert(rv == APR_SUCCESS && n == l); + + return OK; +} + +static const char *set_forensic_log(cmd_parms *cmd, void *dummy, const char *fn) +{ + fcfg *cfg = ap_get_module_config(cmd->server->module_config, + &log_forensic_module); + + cfg->logname = fn; + return NULL; +} + +static const command_rec forensic_log_cmds[] = +{ + AP_INIT_TAKE1("ForensicLog", set_forensic_log, NULL, RSRC_CONF, + "the filename of the forensic log"), + { NULL } +}; + +static void register_hooks(apr_pool_t *p) +{ + static const char * const pre[] = { "mod_unique_id.c", NULL }; + + ap_hook_open_logs(log_init,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_post_read_request(log_before,pre,NULL,APR_HOOK_REALLY_FIRST); + ap_hook_log_transaction(log_after,NULL,NULL,APR_HOOK_REALLY_LAST); +} + +module AP_MODULE_DECLARE_DATA log_forensic_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config */ + NULL, /* merge per-dir config */ + make_forensic_log_scfg, /* server config */ + merge_forensic_log_scfg, /* merge server config */ + forensic_log_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/loggers/mod_log_forensic.dsp b/trunk/modules/loggers/mod_log_forensic.dsp new file mode 100644 index 0000000000..92643eba63 --- /dev/null +++ b/trunk/modules/loggers/mod_log_forensic.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_log_forensic" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_log_forensic - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_log_forensic.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_log_forensic.mak" CFG="mod_log_forensic - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_log_forensic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_log_forensic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_log_forensic - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_log_forensic_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_log_forensic - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_log_forensic_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_log_forensic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_log_forensic.so + +!ENDIF + +# Begin Target + +# Name "mod_log_forensic - Win32 Release" +# Name "mod_log_forensic - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_log_forensic.c +# End Source File +# Begin Source File + +SOURCE=.\mod_log_forensic.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_log_forensic - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_log_forensic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_log_forensic.so "log_forensic_module for Apache" ../../include/ap_release.h > .\mod_log_forensic.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_log_forensic - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_log_forensic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_log_forensic.so "log_forensic_module for Apache" ../../include/ap_release.h > .\mod_log_forensic.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/loggers/mod_log_forensic.exp b/trunk/modules/loggers/mod_log_forensic.exp new file mode 100644 index 0000000000..92f5075b4e --- /dev/null +++ b/trunk/modules/loggers/mod_log_forensic.exp @@ -0,0 +1 @@ +log_forensic_module diff --git a/trunk/modules/loggers/mod_logio.c b/trunk/modules/loggers/mod_logio.c new file mode 100644 index 0000000000..a5290c0704 --- /dev/null +++ b/trunk/modules/loggers/mod_logio.c @@ -0,0 +1,192 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Written by Bojan Smojver : + * + * The argument to LogFormat and CustomLog is a string, which can include + * literal characters copied into the log files, and '%' directives as + * follows: + * + * %...I: bytes received, including request and headers, cannot be zero + * %...O: bytes sent, including headers, cannot be zero + * + */ + +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_hash.h" +#include "apr_optional.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "mod_log_config.h" +#include "httpd.h" +#include "http_core.h" +#include "http_config.h" +#include "http_connection.h" +#include "http_protocol.h" + +module AP_MODULE_DECLARE_DATA logio_module; + +static const char logio_filter_name[] = "LOG_INPUT_OUTPUT"; + +/* + * Logging of input and output config... + */ + +typedef struct logio_config_t { + apr_off_t bytes_in; + apr_off_t bytes_out; +} logio_config_t; + +/* + * Optional function for the core to add to bytes_out + */ + +static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){ + logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module); + + cf->bytes_out += bytes; +} + +/* + * Format items... + */ + +static const char *log_bytes_in(request_rec *r, char *a) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + return apr_off_t_toa(r->pool, cf->bytes_in); +} + +static const char *log_bytes_out(request_rec *r, char *a) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + return apr_off_t_toa(r->pool, cf->bytes_out); +} + +/* + * Reset counters after logging... + */ + +static int logio_transaction(request_rec *r) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + cf->bytes_in = cf->bytes_out = 0; + + return OK; +} + +/* + * Logging of input and output filters... + */ + +static apr_status_t logio_in_filter(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) { + apr_off_t length; + apr_status_t status; + logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module); + + status = ap_get_brigade(f->next, bb, mode, block, readbytes); + + apr_brigade_length (bb, 0, &length); + + if (length > 0) + cf->bytes_in += length; + + return status; +} + +static apr_status_t logio_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) { + apr_bucket *b = APR_BRIGADE_LAST(bb); + + /* End of data, make sure we flush */ + if (APR_BUCKET_IS_EOS(b)) { + APR_BUCKET_INSERT_BEFORE(b, + apr_bucket_flush_create(f->c->bucket_alloc)); + } + + return ap_pass_brigade(f->next, bb); +} + +/* + * The hooks... + */ + +static int logio_pre_conn(conn_rec *c, void *csd) { + logio_config_t *cf = apr_pcalloc(c->pool, sizeof(*cf)); + + ap_set_module_config(c->conn_config, &logio_module, cf); + + ap_add_input_filter(logio_filter_name, NULL, NULL, c); + ap_add_output_filter(logio_filter_name, NULL, NULL, c); + + return OK; +} + +static int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register; + + log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler); + + if (log_pfn_register) { + log_pfn_register(p, "I", log_bytes_in, 0); + log_pfn_register(p, "O", log_bytes_out, 0); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char *pre[] = { "mod_log_config.c", NULL }; + + ap_hook_pre_connection(logio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_config(logio_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); + ap_hook_log_transaction(logio_transaction, pre, NULL, APR_HOOK_MIDDLE); + + ap_register_input_filter(logio_filter_name, logio_in_filter, NULL, + AP_FTYPE_NETWORK - 1); + ap_register_output_filter(logio_filter_name, logio_out_filter, NULL, + AP_FTYPE_NETWORK - 1); + + APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_out); +} + +module AP_MODULE_DECLARE_DATA logio_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config */ + NULL, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + NULL, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/loggers/mod_logio.dsp b/trunk/modules/loggers/mod_logio.dsp new file mode 100644 index 0000000000..9462c1e2b4 --- /dev/null +++ b/trunk/modules/loggers/mod_logio.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_logio" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_logio - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_logio.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_logio.mak" CFG="mod_logio - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_logio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_logio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_logio - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_logio_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_logio - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_logio_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_logio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_logio.so + +!ENDIF + +# Begin Target + +# Name "mod_logio - Win32 Release" +# Name "mod_logio - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_logio.c +# End Source File +# Begin Source File + +SOURCE=.\mod_logio.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_logio - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_logio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_logio.so "logio_module for Apache" ../../include/ap_release.h > .\mod_logio.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_logio - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_logio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_logio.so "logio_module for Apache" ../../include/ap_release.h > .\mod_logio.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/.indent.pro b/trunk/modules/mappers/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/mappers/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/mappers/Makefile.in b/trunk/modules/mappers/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/mappers/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/mappers/NWGNUactions b/trunk/modules/mappers/NWGNUactions new file mode 100644 index 0000000000..479e4ff21c --- /dev/null +++ b/trunk/modules/mappers/NWGNUactions @@ -0,0 +1,249 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = actions + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Actions Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Actions Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/actions.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_actions.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + actions_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/NWGNUimagemap b/trunk/modules/mappers/NWGNUimagemap new file mode 100644 index 0000000000..dbce0cb180 --- /dev/null +++ b/trunk/modules/mappers/NWGNUimagemap @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/http \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = imagemap + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Image Map Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Image Map Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/imagemap.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_imagemap.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + imagemap_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/NWGNUmakefile b/trunk/modules/mappers/NWGNUmakefile new file mode 100644 index 0000000000..ba7b3903a3 --- /dev/null +++ b/trunk/modules/mappers/NWGNUmakefile @@ -0,0 +1,250 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/actions.nlm \ + $(OBJDIR)/imagemap.nlm \ + $(OBJDIR)/rewrite.nlm \ + $(OBJDIR)/speling.nlm \ + $(OBJDIR)/userdir.nlm \ + $(OBJDIR)/vhost.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + diff --git a/trunk/modules/mappers/NWGNUrewrite b/trunk/modules/mappers/NWGNUrewrite new file mode 100644 index 0000000000..153a2410b5 --- /dev/null +++ b/trunk/modules/mappers/NWGNUrewrite @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/ssl \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = rewrite + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Rewrite Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Rewrite Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/rewrite.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_rewrite.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + rewrite_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/NWGNUspeling b/trunk/modules/mappers/NWGNUspeling new file mode 100644 index 0000000000..16c6677d6f --- /dev/null +++ b/trunk/modules/mappers/NWGNUspeling @@ -0,0 +1,249 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = speling + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Speling Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Speling Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/speling.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_speling.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + speling_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/NWGNUuserdir b/trunk/modules/mappers/NWGNUuserdir new file mode 100644 index 0000000000..a8abfdd398 --- /dev/null +++ b/trunk/modules/mappers/NWGNUuserdir @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/http \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = userdir + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) User Dir Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = UserDir Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/userdir.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_userdir.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + userdir_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/NWGNUvhost b/trunk/modules/mappers/NWGNUvhost new file mode 100644 index 0000000000..9f0bad4f64 --- /dev/null +++ b/trunk/modules/mappers/NWGNUvhost @@ -0,0 +1,249 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = vhost + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Vhost Alias Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Vhost Alias Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/vhost.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_vhost_alias.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + vhost_alias_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/mappers/config9.m4 b/trunk/modules/mappers/config9.m4 new file mode 100644 index 0000000000..49bcd680db --- /dev/null +++ b/trunk/modules/mappers/config9.m4 @@ -0,0 +1,61 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(mappers) + +APACHE_MODULE(vhost_alias, mass virtual hosting module, , , most) +APACHE_MODULE(negotiation, content negotiation, , , yes) +APACHE_MODULE(dir, directory request handling, , , yes) +APACHE_MODULE(imagemap, server-side imagemaps, , , most) +APACHE_MODULE(actions, Action triggering on requests, , , yes) +APACHE_MODULE(speling, correct common URL misspellings, , , most) +APACHE_MODULE(userdir, mapping of requests to user-specific directories, , , yes) +APACHE_MODULE(alias, mapping of requests to different filesystem parts, , , yes) + +APACHE_MODULE(rewrite, rule based URL manipulation, , , most) + + +APR_CHECK_APR_DEFINE(APR_HAS_DSO) + +case "x$enable_so" in + "xyes") + if test $ac_cv_define_APR_HAS_DSO = "no"; then + AC_MSG_ERROR([mod_so has been requested but cannot be built on your system]) + fi + ;; + "xshared") + AC_MSG_ERROR([mod_so can not be built as a shared DSO]) + ;; + "xno") + ;; + "x") + enable_so=$ac_cv_define_APR_HAS_DSO + ;; +esac + +dnl mod_so can only be built statically. If the user wants modules to +dnl be built as DSOs by default (eg. ./configure --enable-mods-shared=most) +dnl then we must override the default here. +if test "x$enable_so" = "xyes"; then + enable_so="static" +fi + +if test "x$enable_so" = "xstatic"; then + APR_ADDTO(HTTPD_LDFLAGS, [-export-dynamic]) +fi + +if test "$sharedobjs" = "yes"; then + if test $ac_cv_define_APR_HAS_DSO = "no"; then + AC_MSG_ERROR([shared objects have been requested but cannot be built since mod_so cannot be built]) + elif test $enable_so = "no"; then + AC_MSG_ERROR([shared objects have been requested but cannot be built since mod_so was disabled]) + fi +fi + +APACHE_MODULE(so, DSO capability, , , $enable_so) + +dnl ### why save the cache? +AC_CACHE_SAVE + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/mappers/mod_actions.c b/trunk/modules/mappers/mod_actions.c new file mode 100644 index 0000000000..473a9681ed --- /dev/null +++ b/trunk/modules/mappers/mod_actions.c @@ -0,0 +1,221 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_actions.c: executes scripts based on MIME type or HTTP method + * + * by Alexei Kosut; based on mod_cgi.c, mod_mime.c and mod_includes.c, + * adapted by rst from original NCSA code by Rob McCool + * + * Usage instructions: + * + * Action mime/type /cgi-bin/script + * + * will activate /cgi-bin/script when a file of content type mime/type is + * requested. It sends the URL and file path of the requested document using + * the standard CGI PATH_INFO and PATH_TRANSLATED environment variables. + * + * Script PUT /cgi-bin/script + * + * will activate /cgi-bin/script when a request is received with the + * HTTP method "PUT". The available method names are defined in httpd.h. + * If the method is GET, the script will only be activated if the requested + * URI includes query information (stuff after a ?-mark). + */ + +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#include "util_script.h" + +typedef struct { + apr_table_t *action_types; /* Added with Action... */ + const char *scripted[METHODS]; /* Added with Script... */ + int configured; /* True if Action or Script has been + * called at least once + */ +} action_dir_config; + +module AP_MODULE_DECLARE_DATA actions_module; + +static void *create_action_dir_config(apr_pool_t *p, char *dummy) +{ + action_dir_config *new = + (action_dir_config *) apr_pcalloc(p, sizeof(action_dir_config)); + + new->action_types = apr_table_make(p, 4); + + return new; +} + +static void *merge_action_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + action_dir_config *base = (action_dir_config *) basev; + action_dir_config *add = (action_dir_config *) addv; + action_dir_config *new = (action_dir_config *) apr_palloc(p, + sizeof(action_dir_config)); + int i; + + new->action_types = apr_table_overlay(p, add->action_types, + base->action_types); + + for (i = 0; i < METHODS; ++i) { + new->scripted[i] = add->scripted[i] ? add->scripted[i] + : base->scripted[i]; + } + + new->configured = (base->configured || add->configured); + return new; +} + +static const char *add_action(cmd_parms *cmd, void *m_v, + const char *type, const char *script, + const char *option) +{ + action_dir_config *m = (action_dir_config *)m_v; + + if (option && strcasecmp(option, "virtual")) { + return apr_pstrcat(cmd->pool, + "unrecognized option '", option, "'", NULL); + } + + apr_table_setn(m->action_types, type, + apr_pstrcat(cmd->pool, option ? "1" : "0", script, NULL)); + m->configured = 1; + + return NULL; +} + +static const char *set_script(cmd_parms *cmd, void *m_v, + const char *method, const char *script) +{ + action_dir_config *m = (action_dir_config *)m_v; + + /* ap_method_register recognizes already registered methods, + * so don't bother to check its previous existence explicitely. + */ + int methnum = ap_method_register(cmd->pool, method); + + if (methnum == M_TRACE) { + return "TRACE not allowed for Script"; + } + else if (methnum == M_INVALID) { + return apr_pstrcat(cmd->pool, "Could not register method '", method, + "' for Script", NULL); + } + + m->scripted[methnum] = script; + m->configured = 1; + + return NULL; +} + +static const command_rec action_cmds[] = +{ + AP_INIT_TAKE23("Action", add_action, NULL, OR_FILEINFO, + "a media type followed by a script name"), + AP_INIT_TAKE2("Script", set_script, NULL, ACCESS_CONF | RSRC_CONF, + "a method followed by a script name"), + {NULL} +}; + +static int action_handler(request_rec *r) +{ + action_dir_config *conf = (action_dir_config *) + ap_get_module_config(r->per_dir_config, &actions_module); + const char *t, *action; + const char *script; + int i; + + if (!conf->configured) { + return DECLINED; + } + + /* Note that this handler handles _all_ types, so handler is unchecked */ + + /* Set allowed stuff */ + for (i = 0; i < METHODS; ++i) { + if (conf->scripted[i]) + r->allowed |= (AP_METHOD_BIT << i); + } + + /* First, check for the method-handling scripts */ + if (r->method_number == M_GET) { + if (r->args) + script = conf->scripted[M_GET]; + else + script = NULL; + } + else { + script = conf->scripted[r->method_number]; + } + + /* Check for looping, which can happen if the CGI script isn't */ + if (script && r->prev && r->prev->prev) + return DECLINED; + + /* Second, check for actions (which override the method scripts) */ + action = r->handler ? r->handler : + ap_field_noparam(r->pool, r->content_type); + action = action ? action : ap_default_type(r); + + if ((t = apr_table_get(conf->action_types, action))) { + if (*t++ == '0' && r->finfo.filetype == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "File does not exist: %s", r->filename); + return HTTP_NOT_FOUND; + } + + script = t; + /* propagate the handler name to the script + * (will be REDIRECT_HANDLER there) + */ + apr_table_setn(r->subprocess_env, "HANDLER", action); + } + + if (script == NULL) + return DECLINED; + + ap_internal_redirect_handler(apr_pstrcat(r->pool, script, + ap_escape_uri(r->pool, r->uri), + r->args ? "?" : NULL, + r->args, NULL), r); + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(action_handler,NULL,NULL,APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA actions_module = +{ + STANDARD20_MODULE_STUFF, + create_action_dir_config, /* dir config creater */ + merge_action_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + action_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_actions.dsp b/trunk/modules/mappers/mod_actions.dsp new file mode 100644 index 0000000000..cf97698f85 --- /dev/null +++ b/trunk/modules/mappers/mod_actions.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_actions" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_actions - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_actions.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_actions.mak" CFG="mod_actions - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_actions - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_actions - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_actions - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_actions_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_actions - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_actions_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_actions.so" /base:@..\..\os\win32\BaseAddr.ref,mod_actions.so + +!ENDIF + +# Begin Target + +# Name "mod_actions - Win32 Release" +# Name "mod_actions - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_actions.c +# End Source File +# Begin Source File + +SOURCE=.\mod_actions.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_actions - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_actions.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_actions.so "actions_module for Apache" ../../include/ap_release.h > .\mod_actions.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_actions - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_actions.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_actions.so "actions_module for Apache" ../../include/ap_release.h > .\mod_actions.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_actions.exp b/trunk/modules/mappers/mod_actions.exp new file mode 100644 index 0000000000..8cc6cdb102 --- /dev/null +++ b/trunk/modules/mappers/mod_actions.exp @@ -0,0 +1 @@ +actions_module diff --git a/trunk/modules/mappers/mod_alias.c b/trunk/modules/mappers/mod_alias.c new file mode 100644 index 0000000000..2ddbf95255 --- /dev/null +++ b/trunk/modules/mappers/mod_alias.c @@ -0,0 +1,484 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_alias.c: Stuff for dealing with directory aliases + * + * Original by Rob McCool, rewritten in succession by David Robinson + * and rst. + * + */ + +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_core.h" +#include "http_config.h" +#include "http_request.h" +#include "http_log.h" + + +typedef struct { + const char *real; + const char *fake; + char *handler; + ap_regex_t *regexp; + int redir_status; /* 301, 302, 303, 410, etc */ +} alias_entry; + +typedef struct { + apr_array_header_t *aliases; + apr_array_header_t *redirects; +} alias_server_conf; + +typedef struct { + apr_array_header_t *redirects; +} alias_dir_conf; + +module AP_MODULE_DECLARE_DATA alias_module; + +static void *create_alias_config(apr_pool_t *p, server_rec *s) +{ + alias_server_conf *a = + (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf)); + + a->aliases = apr_array_make(p, 20, sizeof(alias_entry)); + a->redirects = apr_array_make(p, 20, sizeof(alias_entry)); + return a; +} + +static void *create_alias_dir_config(apr_pool_t *p, char *d) +{ + alias_dir_conf *a = + (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf)); + a->redirects = apr_array_make(p, 2, sizeof(alias_entry)); + return a; +} + +static void *merge_alias_config(apr_pool_t *p, void *basev, void *overridesv) +{ + alias_server_conf *a = + (alias_server_conf *) apr_pcalloc(p, sizeof(alias_server_conf)); + alias_server_conf *base = (alias_server_conf *) basev; + alias_server_conf *overrides = (alias_server_conf *) overridesv; + + a->aliases = apr_array_append(p, overrides->aliases, base->aliases); + a->redirects = apr_array_append(p, overrides->redirects, base->redirects); + return a; +} + +static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv) +{ + alias_dir_conf *a = + (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf)); + alias_dir_conf *base = (alias_dir_conf *) basev; + alias_dir_conf *overrides = (alias_dir_conf *) overridesv; + a->redirects = apr_array_append(p, overrides->redirects, base->redirects); + return a; +} + +/* need prototype for overlap check */ +static int alias_matches(const char *uri, const char *alias_fakename); + +static const char *add_alias_internal(cmd_parms *cmd, void *dummy, + const char *f, const char *r, + int use_regex) +{ + server_rec *s = cmd->server; + alias_server_conf *conf = ap_get_module_config(s->module_config, + &alias_module); + alias_entry *new = apr_array_push(conf->aliases); + alias_entry *entries = (alias_entry *)conf->aliases->elts; + int i; + + /* XX r can NOT be relative to DocumentRoot here... compat bug. */ + + if (use_regex) { + new->regexp = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); + if (new->regexp == NULL) + return "Regular expression could not be compiled."; + new->real = r; + } + else { + /* XXX This may be optimized, but we must know that new->real + * exists. If so, we can dir merge later, trusing new->real + * and just canonicalizing the remainder. Not till I finish + * cleaning out the old ap_canonical stuff first. + */ + new->real = r; + } + new->fake = f; + new->handler = cmd->info; + + /* check for overlapping (Script)Alias directives + * and throw a warning if found one + */ + if (!use_regex) { + for (i = 0; i < conf->aliases->nelts - 1; ++i) { + alias_entry *p = &entries[i]; + + if ( (!p->regexp && alias_matches(f, p->fake) > 0) + || (p->regexp && !ap_regexec(p->regexp, f, 0, NULL, 0))) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "The %s directive in %s at line %d will probably " + "never match because it overlaps an earlier " + "%sAlias%s.", + cmd->cmd->name, cmd->directive->filename, + cmd->directive->line_num, + p->handler ? "Script" : "", + p->regexp ? "Match" : ""); + + break; /* one warning per alias should be sufficient */ + } + } + } + + return NULL; +} + +static const char *add_alias(cmd_parms *cmd, void *dummy, const char *f, + const char *r) +{ + return add_alias_internal(cmd, dummy, f, r, 0); +} + +static const char *add_alias_regex(cmd_parms *cmd, void *dummy, const char *f, + const char *r) +{ + return add_alias_internal(cmd, dummy, f, r, 1); +} + +static const char *add_redirect_internal(cmd_parms *cmd, + alias_dir_conf *dirconf, + const char *arg1, const char *arg2, + const char *arg3, int use_regex) +{ + alias_entry *new; + server_rec *s = cmd->server; + alias_server_conf *serverconf = ap_get_module_config(s->module_config, + &alias_module); + int status = (int) (long) cmd->info; + ap_regex_t *r = NULL; + const char *f = arg2; + const char *url = arg3; + + if (!strcasecmp(arg1, "gone")) + status = HTTP_GONE; + else if (!strcasecmp(arg1, "permanent")) + status = HTTP_MOVED_PERMANENTLY; + else if (!strcasecmp(arg1, "temp")) + status = HTTP_MOVED_TEMPORARILY; + else if (!strcasecmp(arg1, "seeother")) + status = HTTP_SEE_OTHER; + else if (apr_isdigit(*arg1)) + status = atoi(arg1); + else { + f = arg1; + url = arg2; + } + + if (use_regex) { + r = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); + if (r == NULL) + return "Regular expression could not be compiled."; + } + + if (ap_is_HTTP_REDIRECT(status)) { + if (!url) + return "URL to redirect to is missing"; + if (!use_regex && !ap_is_url(url)) + return "Redirect to non-URL"; + } + else { + if (url) + return "Redirect URL not valid for this status"; + } + + if (cmd->path) + new = apr_array_push(dirconf->redirects); + else + new = apr_array_push(serverconf->redirects); + + new->fake = f; + new->real = url; + new->regexp = r; + new->redir_status = status; + return NULL; +} + +static const char *add_redirect(cmd_parms *cmd, void *dirconf, + const char *arg1, const char *arg2, + const char *arg3) +{ + return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 0); +} + +static const char *add_redirect2(cmd_parms *cmd, void *dirconf, + const char *arg1, const char *arg2) +{ + return add_redirect_internal(cmd, dirconf, arg1, arg2, NULL, 0); +} + +static const char *add_redirect_regex(cmd_parms *cmd, void *dirconf, + const char *arg1, const char *arg2, + const char *arg3) +{ + return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1); +} + +static const command_rec alias_cmds[] = +{ + AP_INIT_TAKE2("Alias", add_alias, NULL, RSRC_CONF, + "a fakename and a realname"), + AP_INIT_TAKE2("ScriptAlias", add_alias, "cgi-script", RSRC_CONF, + "a fakename and a realname"), + AP_INIT_TAKE23("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY, + OR_FILEINFO, + "an optional status, then document to be redirected and " + "destination URL"), + AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF, + "a regular expression and a filename"), + AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF, + "a regular expression and a filename"), + AP_INIT_TAKE23("RedirectMatch", add_redirect_regex, + (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, + "an optional status, then a regular expression and " + "destination URL"), + AP_INIT_TAKE2("RedirectTemp", add_redirect2, + (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, + "a document to be redirected, then the destination URL"), + AP_INIT_TAKE2("RedirectPermanent", add_redirect2, + (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO, + "a document to be redirected, then the destination URL"), + {NULL} +}; + +static int alias_matches(const char *uri, const char *alias_fakename) +{ + const char *aliasp = alias_fakename, *urip = uri; + + while (*aliasp) { + if (*aliasp == '/') { + /* any number of '/' in the alias matches any number in + * the supplied URI, but there must be at least one... + */ + if (*urip != '/') + return 0; + + do { + ++aliasp; + } while (*aliasp == '/'); + do { + ++urip; + } while (*urip == '/'); + } + else { + /* Other characters are compared literally */ + if (*urip++ != *aliasp++) + return 0; + } + } + + /* Check last alias path component matched all the way */ + + if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/') + return 0; + + /* Return number of characters from URI which matched (may be + * greater than length of alias, since we may have matched + * doubled slashes) + */ + + return urip - uri; +} + +static char *try_alias_list(request_rec *r, apr_array_header_t *aliases, + int doesc, int *status) +{ + alias_entry *entries = (alias_entry *) aliases->elts; + ap_regmatch_t regm[AP_MAX_REG_MATCH]; + char *found = NULL; + int i; + + for (i = 0; i < aliases->nelts; ++i) { + alias_entry *p = &entries[i]; + int l; + + if (p->regexp) { + if (!ap_regexec(p->regexp, r->uri, AP_MAX_REG_MATCH, regm, 0)) { + if (p->real) { + found = ap_pregsub(r->pool, p->real, r->uri, + AP_MAX_REG_MATCH, regm); + if (found && doesc) { + apr_uri_t uri; + apr_uri_parse(r->pool, found, &uri); + /* Do not escape the query string or fragment. */ + found = apr_uri_unparse(r->pool, &uri, + APR_URI_UNP_OMITQUERY); + found = ap_escape_uri(r->pool, found); + if (uri.query) { + found = apr_pstrcat(r->pool, found, "?", + uri.query, NULL); + } + if (uri.fragment) { + found = apr_pstrcat(r->pool, found, "#", + uri.fragment, NULL); + } + } + } + else { + /* need something non-null */ + found = apr_pstrdup(r->pool, ""); + } + } + } + else { + l = alias_matches(r->uri, p->fake); + + if (l > 0) { + if (doesc) { + char *escurl; + escurl = ap_os_escape_path(r->pool, r->uri + l, 1); + + found = apr_pstrcat(r->pool, p->real, escurl, NULL); + } + else + found = apr_pstrcat(r->pool, p->real, r->uri + l, NULL); + } + } + + if (found) { + if (p->handler) { /* Set handler, and leave a note for mod_cgi */ + r->handler = p->handler; + apr_table_setn(r->notes, "alias-forced-type", r->handler); + } + /* XXX This is as SLOW as can be, next step, we optimize + * and merge to whatever part of the found path was already + * canonicalized. After I finish eliminating os canonical. + * Better fail test for ap_server_root_relative needed here. + */ + if (!doesc) { + found = ap_server_root_relative(r->pool, found); + } + if (found) { + *status = p->redir_status; + } + return found; + } + + } + + return NULL; +} + +static int translate_alias_redir(request_rec *r) +{ + ap_conf_vector_t *sconf = r->server->module_config; + alias_server_conf *serverconf = ap_get_module_config(sconf, &alias_module); + char *ret; + int status; + + if (r->uri[0] != '/' && r->uri[0] != '\0') { + return DECLINED; + } + + if ((ret = try_alias_list(r, serverconf->redirects, 1, &status)) != NULL) { + if (ap_is_HTTP_REDIRECT(status)) { + /* include QUERY_STRING if any */ + if (r->args) { + ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); + } + apr_table_setn(r->headers_out, "Location", ret); + } + return status; + } + + if ((ret = try_alias_list(r, serverconf->aliases, 0, &status)) != NULL) { + r->filename = ret; + return OK; + } + + return DECLINED; +} + +static int fixup_redir(request_rec *r) +{ + void *dconf = r->per_dir_config; + alias_dir_conf *dirconf = + (alias_dir_conf *) ap_get_module_config(dconf, &alias_module); + char *ret; + int status; + + /* It may have changed since last time, so try again */ + + if ((ret = try_alias_list(r, dirconf->redirects, 1, &status)) != NULL) { + if (ap_is_HTTP_REDIRECT(status)) { + if (ret[0] == '/') { + char *orig_target = ret; + + ret = ap_construct_url(r->pool, ret, r); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "incomplete redirection target of '%s' for " + "URI '%s' modified to '%s'", + orig_target, r->uri, ret); + } + if (!ap_is_url(ret)) { + status = HTTP_INTERNAL_SERVER_ERROR; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "cannot redirect '%s' to '%s'; " + "target is not a valid absoluteURI or abs_path", + r->uri, ret); + } + else { + /* append requested query only, if the config didn't + * supply its own. + */ + if (r->args && !ap_strchr(ret, '?')) { + ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); + } + apr_table_setn(r->headers_out, "Location", ret); + } + } + return status; + } + + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszSucc[]={ "mod_userdir.c", + "mod_vhost_alias.c",NULL }; + + ap_hook_translate_name(translate_alias_redir,NULL,aszSucc,APR_HOOK_MIDDLE); + ap_hook_fixups(fixup_redir,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA alias_module = +{ + STANDARD20_MODULE_STUFF, + create_alias_dir_config, /* dir config creater */ + merge_alias_dir_config, /* dir merger --- default is to override */ + create_alias_config, /* server config */ + merge_alias_config, /* merge server configs */ + alias_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_alias.dsp b/trunk/modules/mappers/mod_alias.dsp new file mode 100644 index 0000000000..c5d3c35787 --- /dev/null +++ b/trunk/modules/mappers/mod_alias.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_alias" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_alias - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_alias.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_alias.mak" CFG="mod_alias - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_alias - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_alias - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_alias - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_alias_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_alias - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_alias_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_alias.so + +!ENDIF + +# Begin Target + +# Name "mod_alias - Win32 Release" +# Name "mod_alias - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_alias.c +# End Source File +# Begin Source File + +SOURCE=.\mod_alias.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_alias - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_alias.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_alias.so "alias_module for Apache" ../../include/ap_release.h > .\mod_alias.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_alias - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_alias.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_alias.so "alias_module for Apache" ../../include/ap_release.h > .\mod_alias.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_alias.exp b/trunk/modules/mappers/mod_alias.exp new file mode 100644 index 0000000000..ac386ec3fa --- /dev/null +++ b/trunk/modules/mappers/mod_alias.exp @@ -0,0 +1 @@ +alias_module diff --git a/trunk/modules/mappers/mod_dir.c b/trunk/modules/mappers/mod_dir.c new file mode 100644 index 0000000000..b0bc39a7dd --- /dev/null +++ b/trunk/modules/mappers/mod_dir.c @@ -0,0 +1,247 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_dir.c: handle default index files, and trailing-/ redirects + */ + +#include "apr_strings.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "util_script.h" + +module AP_MODULE_DECLARE_DATA dir_module; + +typedef enum { + SLASH_OFF = 0, + SLASH_ON, + SLASH_UNSET +} slash_cfg; + +typedef struct dir_config_struct { + apr_array_header_t *index_names; + slash_cfg do_slash; +} dir_config_rec; + +#define DIR_CMD_PERMS OR_INDEXES + +static const char *add_index(cmd_parms *cmd, void *dummy, const char *arg) +{ + dir_config_rec *d = dummy; + + if (!d->index_names) { + d->index_names = apr_array_make(cmd->pool, 2, sizeof(char *)); + } + *(const char **)apr_array_push(d->index_names) = arg; + return NULL; +} + +static const char *configure_slash(cmd_parms *cmd, void *d_, int arg) +{ + dir_config_rec *d = d_; + + d->do_slash = arg ? SLASH_ON : SLASH_OFF; + return NULL; +} + +static const command_rec dir_cmds[] = +{ + AP_INIT_ITERATE("DirectoryIndex", add_index, NULL, DIR_CMD_PERMS, + "a list of file names"), + AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS, + "On or Off"), + {NULL} +}; + +static void *create_dir_config(apr_pool_t *p, char *dummy) +{ + dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec)); + + new->index_names = NULL; + new->do_slash = SLASH_UNSET; + return (void *) new; +} + +static void *merge_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec)); + dir_config_rec *base = (dir_config_rec *)basev; + dir_config_rec *add = (dir_config_rec *)addv; + + new->index_names = add->index_names ? add->index_names : base->index_names; + new->do_slash = + (add->do_slash == SLASH_UNSET) ? base->do_slash : add->do_slash; + return new; +} + +static int fixup_dir(request_rec *r) +{ + dir_config_rec *d; + char *dummy_ptr[1]; + char **names_ptr; + int num_names; + int error_notfound = 0; + + /* only handle requests against directories */ + if (r->finfo.filetype != APR_DIR) { + return DECLINED; + } + + /* In case mod_mime wasn't present, and no handler was assigned. */ + if (!r->handler) { + r->handler = DIR_MAGIC_TYPE; + } + + /* Never tolerate path_info on dir requests */ + if (r->path_info && *r->path_info) { + return DECLINED; + } + + d = (dir_config_rec *)ap_get_module_config(r->per_dir_config, + &dir_module); + + /* Redirect requests that are not '/' terminated */ + if (r->uri[0] == '\0' || r->uri[strlen(r->uri) - 1] != '/') + { + char *ifile; + + if (!d->do_slash) { + return DECLINED; + } + + /* Only redirect non-get requests if we have no note to warn + * that this browser cannot handle redirs on non-GET requests + * (such as Microsoft's WebFolders). + */ + if ((r->method_number != M_GET) + && apr_table_get(r->subprocess_env, "redirect-carefully")) { + return DECLINED; + } + + if (r->args != NULL) { + ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri), + "/", "?", r->args, NULL); + } + else { + ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri), + "/", NULL); + } + + apr_table_setn(r->headers_out, "Location", + ap_construct_url(r->pool, ifile, r)); + return HTTP_MOVED_PERMANENTLY; + } + + if (strcmp(r->handler, DIR_MAGIC_TYPE)) { + return DECLINED; + } + + if (d->index_names) { + names_ptr = (char **)d->index_names->elts; + num_names = d->index_names->nelts; + } + else { + dummy_ptr[0] = AP_DEFAULT_INDEX; + names_ptr = dummy_ptr; + num_names = 1; + } + + for (; num_names; ++names_ptr, --num_names) { + /* XXX: Is this name_ptr considered escaped yet, or not??? */ + char *name_ptr = *names_ptr; + request_rec *rr; + + /* Once upon a time args were handled _after_ the successful redirect. + * But that redirect might then _refuse_ the given r->args, creating + * a nasty tangle. It seems safer to consider the r->args while we + * determine if name_ptr is our viable index, and therefore set them + * up correctly on redirect. + */ + if (r->args != NULL) { + name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL); + } + + rr = ap_sub_req_lookup_uri(name_ptr, r, NULL); + + /* XXX: (filetype == APR_REG) - we can't use a non-file index??? */ + if ( rr->status == HTTP_OK + && ( (rr->handler && !strcmp(rr->handler, "proxy-server")) + || rr->finfo.filetype == APR_REG)) { + ap_internal_fast_redirect(rr, r); + return OK; + } + + /* If the request returned a redirect, propagate it to the client */ + + if (ap_is_HTTP_REDIRECT(rr->status) + || (rr->status == HTTP_NOT_ACCEPTABLE && num_names == 1) + || (rr->status == HTTP_UNAUTHORIZED && num_names == 1)) { + + apr_pool_join(r->pool, rr->pool); + error_notfound = rr->status; + r->notes = apr_table_overlay(r->pool, r->notes, rr->notes); + r->headers_out = apr_table_overlay(r->pool, r->headers_out, + rr->headers_out); + r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out, + rr->err_headers_out); + return error_notfound; + } + + /* If the request returned something other than 404 (or 200), + * it means the module encountered some sort of problem. To be + * secure, we should return the error, rather than allow autoindex + * to create a (possibly unsafe) directory index. + * + * So we store the error, and if none of the listed files + * exist, we return the last error response we got, instead + * of a directory listing. + */ + if (rr->status && rr->status != HTTP_NOT_FOUND + && rr->status != HTTP_OK) { + error_notfound = rr->status; + } + + ap_destroy_sub_req(rr); + } + + if (error_notfound) { + return error_notfound; + } + + /* nothing for us to do, pass on through */ + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(fixup_dir,NULL,NULL,APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA dir_module = { + STANDARD20_MODULE_STUFF, + create_dir_config, /* create per-directory config structure */ + merge_dir_configs, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + dir_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_dir.dsp b/trunk/modules/mappers/mod_dir.dsp new file mode 100644 index 0000000000..fe3b174d35 --- /dev/null +++ b/trunk/modules/mappers/mod_dir.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_dir" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_dir - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_dir.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_dir.mak" CFG="mod_dir - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_dir - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_dir - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_dir - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_dir_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_dir - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_dir_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dir.so + +!ENDIF + +# Begin Target + +# Name "mod_dir - Win32 Release" +# Name "mod_dir - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_dir.c +# End Source File +# Begin Source File + +SOURCE=.\mod_dir.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_dir - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_dir.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_dir.so "dir_module for Apache" ../../include/ap_release.h > .\mod_dir.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_dir - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_dir.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_dir.so "dir_module for Apache" ../../include/ap_release.h > .\mod_dir.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_dir.exp b/trunk/modules/mappers/mod_dir.exp new file mode 100644 index 0000000000..5fbf772991 --- /dev/null +++ b/trunk/modules/mappers/mod_dir.exp @@ -0,0 +1 @@ +dir_module diff --git a/trunk/modules/mappers/mod_imagemap.c b/trunk/modules/mappers/mod_imagemap.c new file mode 100644 index 0000000000..eada55e440 --- /dev/null +++ b/trunk/modules/mappers/mod_imagemap.c @@ -0,0 +1,894 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This imagemap module started as a port of the original imagemap.c + * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu). + * This version includes the mapping algorithms found in version 1.3 + * of imagemap.c. + * + * Contributors to this code include: + * + * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu + * + * Eric Haines, erich@eye.com + * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com + * + * Randy Terbush, randy@zyzzyva.com + * port to Apache module format, "base_uri" and support for relative URLs + * + * James H. Cloos, Jr., cloos@jhcloos.com + * Added point datatype, using code in NCSA's version 1.8 imagemap.c + * program, as distributed with version 1.4.1 of their server. + * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu + * + * Nathan Kurz, nate@tripod.com + * Rewrite/reorganization. New handling of default, base and relative URLs. + * New Configuration directives: + * ImapMenu {none, formatted, semiformatted, unformatted} + * ImapDefault {error, nocontent, referer, menu, URL} + * ImapBase {map, referer, URL} + * Support for creating non-graphical menu added. (backwards compatible): + * Old: directive URL [x,y ...] + * New: directive URL "Menu text" [x,y ...] + * or: directive URL x,y ... "Menu text" + * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca. + * + * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STDIO /* for sscanf() */ +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#include "util_script.h" +#include "mod_core.h" + + +#define IMAP_MAGIC_TYPE "application/x-httpd-imap" +#define MAXVERTS 100 +#define X 0 +#define Y 1 + +#define IMAP_MENU_DEFAULT "formatted" +#define IMAP_DEFAULT_DEFAULT "nocontent" +#define IMAP_BASE_DEFAULT "map" + +#ifdef SUNOS4 +double strtod(); /* SunOS needed this */ +#endif + +module AP_MODULE_DECLARE_DATA imagemap_module; + +typedef struct { + char *imap_menu; + char *imap_default; + char *imap_base; +} imap_conf_rec; + +static void *create_imap_dir_config(apr_pool_t *p, char *dummy) +{ + imap_conf_rec *icr = + (imap_conf_rec *) apr_palloc(p, sizeof(imap_conf_rec)); + + icr->imap_menu = NULL; + icr->imap_default = NULL; + icr->imap_base = NULL; + + return icr; +} + +static void *merge_imap_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + imap_conf_rec *new = (imap_conf_rec *) apr_pcalloc(p, sizeof(imap_conf_rec)); + imap_conf_rec *base = (imap_conf_rec *) basev; + imap_conf_rec *add = (imap_conf_rec *) addv; + + new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu; + new->imap_default = add->imap_default ? add->imap_default + : base->imap_default; + new->imap_base = add->imap_base ? add->imap_base : base->imap_base; + + return new; +} + + +static const command_rec imap_cmds[] = +{ + AP_INIT_TAKE1("ImapMenu", ap_set_string_slot, + (void *)APR_OFFSETOF(imap_conf_rec, imap_menu), OR_INDEXES, + "the type of menu generated: none, formatted, semiformatted, " + "unformatted"), + AP_INIT_TAKE1("ImapDefault", ap_set_string_slot, + (void *)APR_OFFSETOF(imap_conf_rec, imap_default), OR_INDEXES, + "the action taken if no match: error, nocontent, referer, " + "menu, URL"), + AP_INIT_TAKE1("ImapBase", ap_set_string_slot, + (void *)APR_OFFSETOF(imap_conf_rec, imap_base), OR_INDEXES, + "the base for all URL's: map, referer, URL (or start of)"), + {NULL} +}; + +static int pointinrect(const double point[2], double coords[MAXVERTS][2]) +{ + double max[2], min[2]; + if (coords[0][X] > coords[1][X]) { + max[0] = coords[0][X]; + min[0] = coords[1][X]; + } + else { + max[0] = coords[1][X]; + min[0] = coords[0][X]; + } + + if (coords[0][Y] > coords[1][Y]) { + max[1] = coords[0][Y]; + min[1] = coords[1][Y]; + } + else { + max[1] = coords[1][Y]; + min[1] = coords[0][Y]; + } + + return ((point[X] >= min[0] && point[X] <= max[0]) && + (point[Y] >= min[1] && point[Y] <= max[1])); +} + +static int pointincircle(const double point[2], double coords[MAXVERTS][2]) +{ + double radius1, radius2; + + radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y])) + + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X])); + + radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y])) + + ((coords[0][X] - point[X]) * (coords[0][X] - point[X])); + + return (radius2 <= radius1); +} + +#define fmin(a,b) (((a)>(b))?(b):(a)) +#define fmax(a,b) (((a)>(b))?(a):(b)) + +static int pointinpoly(const double point[2], double pgon[MAXVERTS][2]) +{ + int i, numverts, crossings = 0; + double x = point[X], y = point[Y]; + + for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS; + numverts++) { + /* just counting the vertexes */ + } + + for (i = 0; i < numverts; i++) { + double x1=pgon[i][X]; + double y1=pgon[i][Y]; + double x2=pgon[(i + 1) % numverts][X]; + double y2=pgon[(i + 1) % numverts][Y]; + double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1); + + if ((y1 >= y) != (y2 >= y)) { + crossings +=y2 - y1 >= 0 ? d >= 0 : d <= 0; + } + if (!d && fmin(x1,x2) <= x && x <= fmax(x1,x2) + && fmin(y1,y2) <= y && y <= fmax(y1,y2)) { + return 1; + } + } + return crossings & 0x01; +} + + +static int is_closer(const double point[2], double coords[MAXVERTS][2], + double *closest) +{ + double dist_squared = ((point[X] - coords[0][X]) + * (point[X] - coords[0][X])) + + ((point[Y] - coords[0][Y]) + * (point[Y] - coords[0][Y])); + + if (point[X] < 0 || point[Y] < 0) { + return (0); /* don't mess around with negative coordinates */ + } + + if (*closest < 0 || dist_squared < *closest) { + *closest = dist_squared; + return (1); /* if this is the first point or is the closest yet + set 'closest' equal to this distance^2 */ + } + + return (0); /* if it's not the first or closest */ + +} + +static double get_x_coord(const char *args) +{ + char *endptr; /* we want it non-null */ + double x_coord = -1; /* -1 is returned if no coordinate is given */ + + if (args == NULL) { + return (-1); /* in case we aren't passed anything */ + } + + while (*args && !apr_isdigit(*args) && *args != ',') { + args++; /* jump to the first digit, but not past + a comma or end */ + } + + x_coord = strtod(args, &endptr); + + if (endptr > args) { /* if a conversion was made */ + return (x_coord); + } + + return (-1); /* else if no conversion was made, + or if no args was given */ +} + +static double get_y_coord(const char *args) +{ + char *endptr; /* we want it non-null */ + const char *start_of_y = NULL; + double y_coord = -1; /* -1 is returned on error */ + + if (args == NULL) { + return (-1); /* in case we aren't passed anything */ + } + + start_of_y = ap_strchr_c(args, ','); /* the comma */ + + if (start_of_y) { + + start_of_y++; /* start looking at the character after + the comma */ + + while (*start_of_y && !apr_isdigit(*start_of_y)) { + start_of_y++; /* jump to the first digit, but not + past the end */ + } + + y_coord = strtod(start_of_y, &endptr); + + if (endptr > start_of_y) { + return (y_coord); + } + } + + return (-1); /* if no conversion was made, or + no comma was found in args */ +} + + +/* See if string has a "quoted part", and if so set *quoted_part to + * the first character of the quoted part, then hammer a \0 onto the + * trailing quote, and set *string to point at the first character + * past the second quote. + * + * Otherwise set *quoted_part to NULL, and leave *string alone. + */ +static void read_quoted(char **string, char **quoted_part) +{ + char *strp = *string; + + /* assume there's no quoted part */ + *quoted_part = NULL; + + while (apr_isspace(*strp)) { + strp++; /* go along string until non-whitespace */ + } + + if (*strp == '"') { /* if that character is a double quote */ + strp++; /* step over it */ + *quoted_part = strp; /* note where the quoted part begins */ + + while (*strp && *strp != '"') { + ++strp; /* skip the quoted portion */ + } + + *strp = '\0'; /* end the string with a NUL */ + + strp++; /* step over the last double quote */ + *string = strp; + } +} + +/* + * returns the mapped URL or NULL. + */ +static char *imap_url(request_rec *r, const char *base, const char *value) +{ +/* translates a value into a URL. */ + int slen, clen; + char *string_pos = NULL; + const char *string_pos_const = NULL; + char *directory = NULL; + const char *referer = NULL; + char *my_base; + + if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) { + return ap_construct_url(r->pool, r->uri, r); + } + + if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) { + return apr_pstrdup(r->pool, value); /* these are handled elsewhere, + so just copy them */ + } + + if (!strcasecmp(value, "referer")) { + referer = apr_table_get(r->headers_in, "Referer"); + if (referer && *referer) { + return apr_pstrdup(r->pool, referer); + } + else { + /* XXX: This used to do *value = '\0'; ... which is totally bogus + * because it hammers the passed in value, which can be a string + * constant, or part of a config, or whatever. Total garbage. + * This works around that without changing the rest of this + * code much + */ + value = ""; /* if 'referer' but no referring page, + null the value */ + } + } + + string_pos_const = value; + while (apr_isalpha(*string_pos_const)) { + string_pos_const++; /* go along the URL from the map + until a non-letter */ + } + if (*string_pos_const == ':') { + /* if letters and then a colon (like http:) */ + /* it's an absolute URL, so use it! */ + return apr_pstrdup(r->pool, value); + } + + if (!base || !*base) { + if (value && *value) { + return apr_pstrdup(r->pool, value); /* no base: use what is given */ + } + /* no base, no value: pick a simple default */ + return ap_construct_url(r->pool, "/", r); + } + + /* must be a relative URL to be combined with base */ + if (ap_strchr_c(base, '/') == NULL && (!strncmp(value, "../", 3) + || !strcmp(value, ".."))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "invalid base directive in map file: %s", r->uri); + return NULL; + } + my_base = apr_pstrdup(r->pool, base); + string_pos = my_base; + while (*string_pos) { + if (*string_pos == '/' && *(string_pos + 1) == '/') { + string_pos += 2; /* if there are two slashes, jump over them */ + continue; + } + if (*string_pos == '/') { /* the first single slash */ + if (value[0] == '/') { + *string_pos = '\0'; + } /* if the URL from the map starts from root, + end the base URL string at the first single + slash */ + else { + directory = string_pos; /* save the start of + the directory portion */ + + string_pos = strrchr(string_pos, '/'); /* now reuse + string_pos */ + string_pos++; /* step over that last slash */ + *string_pos = '\0'; + } /* but if the map url is relative, leave the + slash on the base (if there is one) */ + break; + } + string_pos++; /* until we get to the end of my_base without + finding a slash by itself */ + } + + while (!strncmp(value, "../", 3) || !strcmp(value, "..")) { + + if (directory && (slen = strlen(directory))) { + + /* for each '..', knock a directory off the end + by ending the string right at the last slash. + But only consider the directory portion: don't eat + into the server name. And only try if a directory + portion was found */ + + clen = slen - 1; + + while ((slen - clen) == 1) { + + if ((string_pos = strrchr(directory, '/'))) { + *string_pos = '\0'; + } + clen = strlen(directory); + if (clen == 0) { + break; + } + } + + value += 2; /* jump over the '..' that we found in the + value */ + } + else if (directory) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "invalid directory name in map file: %s", r->uri); + return NULL; + } + + if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) { + value++; /* step over the '/' if there are more '..' + to do. This way, we leave the starting + '/' on value after the last '..', but get + rid of it otherwise */ + } + + } /* by this point, value does not start + with '..' */ + + if (value && *value) { + return apr_pstrcat(r->pool, my_base, value, NULL); + } + return my_base; +} + +static int imap_reply(request_rec *r, char *redirect) +{ + if (!strcasecmp(redirect, "error")) { + /* they actually requested an error! */ + return HTTP_INTERNAL_SERVER_ERROR; + } + if (!strcasecmp(redirect, "nocontent")) { + /* tell the client to keep the page it has */ + return HTTP_NO_CONTENT; + } + if (redirect && *redirect) { + /* must be a URL, so redirect to it */ + apr_table_setn(r->headers_out, "Location", redirect); + return HTTP_MOVED_TEMPORARILY; + } + return HTTP_INTERNAL_SERVER_ERROR; +} + +static void menu_header(request_rec *r, char *menu) +{ + ap_set_content_type(r, "text/html"); + + ap_rvputs(r, DOCTYPE_HTML_3_2, "\nMenu for ", r->uri, + "\n\n", NULL); + + if (!strcasecmp(menu, "formatted")) { + ap_rvputs(r, "

    Menu for ", r->uri, "

    \n
    \n\n", NULL); + } + + return; +} + +static void menu_blank(request_rec *r, char *menu) +{ + if (!strcasecmp(menu, "formatted")) { + ap_rputs("\n", r); + } + if (!strcasecmp(menu, "semiformatted")) { + ap_rputs("
    \n", r); + } + if (!strcasecmp(menu, "unformatted")) { + ap_rputs("\n", r); + } + return; +} + +static void menu_comment(request_rec *r, char *menu, char *comment) +{ + if (!strcasecmp(menu, "formatted")) { + ap_rputs("\n", r); /* print just a newline if 'formatted' */ + } + if (!strcasecmp(menu, "semiformatted") && *comment) { + ap_rvputs(r, comment, "\n", NULL); + } + if (!strcasecmp(menu, "unformatted") && *comment) { + ap_rvputs(r, comment, "\n", NULL); + } + return; /* comments are ignored in the + 'formatted' form */ +} + +static void menu_default(request_rec *r, char *menu, char *href, char *text) +{ + if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) { + return; /* don't print such lines, these aren't + really href's */ + } + if (!strcasecmp(menu, "formatted")) { + ap_rvputs(r, "
    (Default) ", text,
    +               "
    \n", NULL); + } + if (!strcasecmp(menu, "semiformatted")) { + ap_rvputs(r, "
    (Default) ", text,
    +               "
    \n", NULL); + } + if (!strcasecmp(menu, "unformatted")) { + ap_rvputs(r, "", text, "", NULL); + } + return; +} + +static void menu_directive(request_rec *r, char *menu, char *href, char *text) +{ + if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) { + return; /* don't print such lines, as this isn't + really an href */ + } + if (!strcasecmp(menu, "formatted")) { + ap_rvputs(r, "
              ", text,
    +               "
    \n", NULL); + } + if (!strcasecmp(menu, "semiformatted")) { + ap_rvputs(r, "
              ", text,
    +               "
    \n", NULL); + } + if (!strcasecmp(menu, "unformatted")) { + ap_rvputs(r, "", text, "", NULL); + } + return; +} + +static void menu_footer(request_rec *r) +{ + ap_rputs("\n\n\n\n", r); /* finish the menu */ +} + +static int imap_handler_internal(request_rec *r) +{ + char input[MAX_STRING_LEN]; + char *directive; + char *value; + char *href_text; + char *base; + char *redirect; + char *mapdflt; + char *closest = NULL; + double closest_yet = -1; + apr_status_t status; + + double testpoint[2]; + double pointarray[MAXVERTS + 1][2]; + int vertex; + + char *string_pos; + int showmenu = 0; + + imap_conf_rec *icr; + + char *imap_menu; + char *imap_default; + char *imap_base; + + ap_configfile_t *imap; + + icr = ap_get_module_config(r->per_dir_config, &imagemap_module); + + imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT; + imap_default = icr->imap_default + ? icr->imap_default : IMAP_DEFAULT_DEFAULT; + imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT; + + status = ap_pcfg_openfile(&imap, r->pool, r->filename); + + if (status != APR_SUCCESS) { + return HTTP_NOT_FOUND; + } + + base = imap_url(r, NULL, imap_base); /* set base according + to default */ + if (!base) { + return HTTP_INTERNAL_SERVER_ERROR; + } + mapdflt = imap_url(r, NULL, imap_default); /* and default to + global default */ + if (!mapdflt) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + testpoint[X] = get_x_coord(r->args); + testpoint[Y] = get_y_coord(r->args); + + if ((testpoint[X] == -1 || testpoint[Y] == -1) || + (testpoint[X] == 0 && testpoint[Y] == 0)) { + /* if either is -1 or if both are zero (new Lynx) */ + /* we don't have valid coordinates */ + testpoint[X] = -1; + testpoint[Y] = -1; + if (strncasecmp(imap_menu, "none", 2)) { + showmenu = 1; /* show the menu _unless_ ImapMenu is + 'none' or 'no' */ + } + } + + if (showmenu) { /* send start of imagemap menu if + we're going to */ + menu_header(r, imap_menu); + } + + while (!ap_cfg_getline(input, sizeof(input), imap)) { + if (!input[0]) { + if (showmenu) { + menu_blank(r, imap_menu); + } + continue; + } + + if (input[0] == '#') { + if (showmenu) { + menu_comment(r, imap_menu, input + 1); + } + continue; + } /* blank lines and comments are ignored + if we aren't printing a menu */ + + /* find the first two space delimited fields, recall that + * ap_cfg_getline has removed leading/trailing whitespace. + * + * note that we're tokenizing as we go... if we were to use the + * ap_getword() class of functions we would end up allocating extra + * memory for every line of the map file + */ + string_pos = input; + if (!*string_pos) { /* need at least two fields */ + goto need_2_fields; + } + + directive = string_pos; + while (*string_pos && !apr_isspace(*string_pos)) { /* past directive */ + ++string_pos; + } + if (!*string_pos) { /* need at least two fields */ + goto need_2_fields; + } + *string_pos++ = '\0'; + + if (!*string_pos) { /* need at least two fields */ + goto need_2_fields; + } + while(*string_pos && apr_isspace(*string_pos)) { /* past whitespace */ + ++string_pos; + } + + value = string_pos; + while (*string_pos && !apr_isspace(*string_pos)) { /* past value */ + ++string_pos; + } + if (apr_isspace(*string_pos)) { + *string_pos++ = '\0'; + } + else { + /* end of input, don't advance past it */ + *string_pos = '\0'; + } + + if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */ + base = imap_url(r, NULL, value); + if (!base) { + goto menu_bail; + } + continue; /* base is never printed to a menu */ + } + + read_quoted(&string_pos, &href_text); + + if (!strcasecmp(directive, "default")) { /* default */ + mapdflt = imap_url(r, NULL, value); + if (!mapdflt) { + goto menu_bail; + } + if (showmenu) { /* print the default if there's a menu */ + redirect = imap_url(r, base, mapdflt); + if (!redirect) { + goto menu_bail; + } + menu_default(r, imap_menu, redirect, + href_text ? href_text : mapdflt); + } + continue; + } + + vertex = 0; + while (vertex < MAXVERTS && + sscanf(string_pos, "%lf%*[, ]%lf", + &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) { + /* Now skip what we just read... we can't use ANSIism %n */ + while (apr_isspace(*string_pos)) { /* past whitespace */ + string_pos++; + } + while (apr_isdigit(*string_pos)) { /* and the 1st number */ + string_pos++; + } + string_pos++; /* skip the ',' */ + while (apr_isspace(*string_pos)) { /* past any more whitespace */ + string_pos++; + } + while (apr_isdigit(*string_pos)) { /* 2nd number */ + string_pos++; + } + vertex++; + } /* so long as there are more vertices to + read, and we have room, read them in. + We start where we left off of the last + sscanf, not at the beginning. */ + + pointarray[vertex][X] = -1; /* signals the end of vertices */ + + if (showmenu) { + if (!href_text) { + read_quoted(&string_pos, &href_text); /* href text could + be here instead */ + } + redirect = imap_url(r, base, value); + if (!redirect) { + goto menu_bail; + } + menu_directive(r, imap_menu, redirect, + href_text ? href_text : value); + continue; + } + /* note that we don't make it past here if we are making a menu */ + + if (testpoint[X] == -1 || pointarray[0][X] == -1) { + continue; /* don't try the following tests if testpoints + are invalid, or if there are no + coordinates */ + } + + if (!strcasecmp(directive, "poly")) { /* poly */ + + if (pointinpoly(testpoint, pointarray)) { + ap_cfg_closefile(imap); + redirect = imap_url(r, base, value); + if (!redirect) { + return HTTP_INTERNAL_SERVER_ERROR; + } + return (imap_reply(r, redirect)); + } + continue; + } + + if (!strcasecmp(directive, "circle")) { /* circle */ + + if (pointincircle(testpoint, pointarray)) { + ap_cfg_closefile(imap); + redirect = imap_url(r, base, value); + if (!redirect) { + return HTTP_INTERNAL_SERVER_ERROR; + } + return (imap_reply(r, redirect)); + } + continue; + } + + if (!strcasecmp(directive, "rect")) { /* rect */ + + if (pointinrect(testpoint, pointarray)) { + ap_cfg_closefile(imap); + redirect = imap_url(r, base, value); + if (!redirect) { + return HTTP_INTERNAL_SERVER_ERROR; + } + return (imap_reply(r, redirect)); + } + continue; + } + + if (!strcasecmp(directive, "point")) { /* point */ + + if (is_closer(testpoint, pointarray, &closest_yet)) { + closest = apr_pstrdup(r->pool, value); + } + + continue; + } /* move on to next line whether it's + closest or not */ + + } /* nothing matched, so we get another line! */ + + ap_cfg_closefile(imap); /* we are done with the map file; close it */ + + if (showmenu) { + menu_footer(r); /* finish the menu and we are done */ + return OK; + } + + if (closest) { /* if a 'point' directive has been seen */ + redirect = imap_url(r, base, closest); + if (!redirect) { + return HTTP_INTERNAL_SERVER_ERROR; + } + return (imap_reply(r, redirect)); + } + + if (mapdflt) { /* a default should be defined, even if + only 'nocontent' */ + redirect = imap_url(r, base, mapdflt); + if (!redirect) { + return HTTP_INTERNAL_SERVER_ERROR; + } + return (imap_reply(r, redirect)); + } + + return HTTP_INTERNAL_SERVER_ERROR; /* If we make it this far, + we failed. They lose! */ + +need_2_fields: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "map file %s, line %d syntax error: requires at " + "least two fields", r->uri, imap->line_number); + /* fall through */ +menu_bail: + ap_cfg_closefile(imap); + if (showmenu) { + /* There's not much else we can do ... we've already sent the headers + * to the client. + */ + ap_rputs("\n\n[an internal server error occured]\n", r); + menu_footer(r); + return OK; + } + return HTTP_INTERNAL_SERVER_ERROR; +} + +static int imap_handler(request_rec *r) +{ + /* Optimization: skip the allocation of large local variables on the + * stack (in imap_handler_internal()) on requests that aren't using + * imagemaps + */ + if (r->method_number != M_GET || (strcmp(r->handler,IMAP_MAGIC_TYPE) + && strcmp(r->handler, "imap-file"))) { + return DECLINED; + } + else { + return imap_handler_internal(r); + } +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_handler(imap_handler,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA imagemap_module = +{ + STANDARD20_MODULE_STUFF, + create_imap_dir_config, /* dir config creater */ + merge_imap_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + imap_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_imagemap.dsp b/trunk/modules/mappers/mod_imagemap.dsp new file mode 100644 index 0000000000..e2d1e5dfab --- /dev/null +++ b/trunk/modules/mappers/mod_imagemap.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_imagemap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_imagemap - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_imagemap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_imagemap.mak" CFG="mod_imagemap - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_imagemap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_imagemap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_imagemap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_imagemap_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_imagemap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_imagemap_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_imagemap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_imagemap.so + +!ENDIF + +# Begin Target + +# Name "mod_imagemap - Win32 Release" +# Name "mod_imagemap - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_imagemap.c +# End Source File +# Begin Source File + +SOURCE=.\mod_imagemap.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_imagemap - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_imagemap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_imagemap.so "imagemap_module for Apache" ../../include/ap_release.h > .\mod_imagemap.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_imagemap - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_imagemap.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_imagemap.so "imagemap_module for Apache" ../../include/ap_release.h > .\mod_imagemap.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_imagemap.exp b/trunk/modules/mappers/mod_imagemap.exp new file mode 100644 index 0000000000..1e0e0b83d0 --- /dev/null +++ b/trunk/modules/mappers/mod_imagemap.exp @@ -0,0 +1 @@ +imap_module diff --git a/trunk/modules/mappers/mod_negotiation.c b/trunk/modules/mappers/mod_negotiation.c new file mode 100644 index 0000000000..0e94210bf4 --- /dev/null +++ b/trunk/modules/mappers/mod_negotiation.c @@ -0,0 +1,3212 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_negotiation.c: keeps track of MIME types the client is willing to + * accept, and contains code to handle type arbitration. + * + * rst + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_protocol.h" +#include "http_core.h" +#include "http_log.h" +#include "util_script.h" + + +#define MAP_FILE_MAGIC_TYPE "application/x-type-map" + +/* Commands --- configuring document caching on a per (virtual?) + * server basis... + */ + +typedef struct { + int forcelangpriority; + apr_array_header_t *language_priority; +} neg_dir_config; + +/* forcelangpriority flags + */ +#define FLP_UNDEF 0 /* Same as FLP_DEFAULT, but base overrides */ +#define FLP_NONE 1 /* Return 406, HTTP_NOT_ACCEPTABLE */ +#define FLP_PREFER 2 /* Use language_priority rather than MC */ +#define FLP_FALLBACK 4 /* Use language_priority rather than NA */ + +#define FLP_DEFAULT FLP_PREFER + +/* env evaluation + */ +#define DISCARD_ALL_ENCODINGS 1 /* no-gzip */ +#define DISCARD_ALL_BUT_HTML 2 /* gzip-only-text/html */ + +module AP_MODULE_DECLARE_DATA negotiation_module; + +static void *create_neg_dir_config(apr_pool_t *p, char *dummy) +{ + neg_dir_config *new = (neg_dir_config *) apr_palloc(p, + sizeof(neg_dir_config)); + + new->forcelangpriority = FLP_UNDEF; + new->language_priority = NULL; + return new; +} + +static void *merge_neg_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + neg_dir_config *base = (neg_dir_config *) basev; + neg_dir_config *add = (neg_dir_config *) addv; + neg_dir_config *new = (neg_dir_config *) apr_palloc(p, + sizeof(neg_dir_config)); + + /* give priority to the config in the subdirectory */ + new->forcelangpriority = (add->forcelangpriority != FLP_UNDEF) + ? add->forcelangpriority + : base->forcelangpriority; + new->language_priority = add->language_priority + ? add->language_priority + : base->language_priority; + return new; +} + +static const char *set_language_priority(cmd_parms *cmd, void *n_, + const char *lang) +{ + neg_dir_config *n = n_; + const char **langp; + + if (!n->language_priority) + n->language_priority = apr_array_make(cmd->pool, 4, sizeof(char *)); + + langp = (const char **) apr_array_push(n->language_priority); + *langp = lang; + return NULL; +} + +static const char *set_force_priority(cmd_parms *cmd, void *n_, const char *w) +{ + neg_dir_config *n = n_; + + if (!strcasecmp(w, "None")) { + if (n->forcelangpriority & ~FLP_NONE) { + return "Cannot combine ForceLanguagePriority options with None"; + } + n->forcelangpriority = FLP_NONE; + } + else if (!strcasecmp(w, "Prefer")) { + if (n->forcelangpriority & FLP_NONE) { + return "Cannot combine ForceLanguagePriority options None and " + "Prefer"; + } + n->forcelangpriority |= FLP_PREFER; + } + else if (!strcasecmp(w, "Fallback")) { + if (n->forcelangpriority & FLP_NONE) { + return "Cannot combine ForceLanguagePriority options None and " + "Fallback"; + } + n->forcelangpriority |= FLP_FALLBACK; + } + else { + return apr_pstrcat(cmd->pool, "Invalid ForceLanguagePriority option ", + w, NULL); + } + + return NULL; +} + +static const char *cache_negotiated_docs(cmd_parms *cmd, void *dummy, + int arg) +{ + ap_set_module_config(cmd->server->module_config, &negotiation_module, + (arg ? "Cache" : NULL)); + return NULL; +} + +static int do_cache_negotiated_docs(server_rec *s) +{ + return (ap_get_module_config(s->module_config, + &negotiation_module) != NULL); +} + +static const command_rec negotiation_cmds[] = +{ + AP_INIT_FLAG("CacheNegotiatedDocs", cache_negotiated_docs, NULL, RSRC_CONF, + "Either 'on' or 'off' (default)"), + AP_INIT_ITERATE("LanguagePriority", set_language_priority, NULL, + OR_FILEINFO, + "space-delimited list of MIME language abbreviations"), + AP_INIT_ITERATE("ForceLanguagePriority", set_force_priority, NULL, + OR_FILEINFO, + "Force LanguagePriority elections, either None, or " + "Fallback and/or Prefer"), + {NULL} +}; + +/* + * Record of available info on a media type specified by the client + * (we also use 'em for encodings and languages) + */ + +typedef struct accept_rec { + char *name; /* MUST be lowercase */ + float quality; + float level; + char *charset; /* for content-type only */ +} accept_rec; + +/* + * Record of available info on a particular variant + * + * Note that a few of these fields are updated by the actual negotiation + * code. These are: + * + * level_matched --- initialized to zero. Set to the value of level + * if the client actually accepts this media type at that + * level (and *not* if it got in on a wildcard). See level_cmp + * below. + * mime_stars -- initialized to zero. Set to the number of stars + * present in the best matching Accept header element. + * 1 for star/star, 2 for type/star and 3 for + * type/subtype. + * + * definite -- initialized to 1. Set to 0 if there is a match which + * makes the variant non-definite according to the rules + * in rfc2296. + */ + +typedef struct var_rec { + request_rec *sub_req; /* May be NULL (is, for map files) */ + const char *mime_type; /* MUST be lowercase */ + const char *file_name; /* Set to 'this' (for map file body content) */ + apr_off_t body; /* Only for map file body content */ + const char *content_encoding; + apr_array_header_t *content_languages; /* list of lang. for this variant */ + const char *content_charset; + const char *description; + + /* The next five items give the quality values for the dimensions + * of negotiation for this variant. They are obtained from the + * appropriate header lines, except for source_quality, which + * is obtained from the variant itself (the 'qs' parameter value + * from the variant's mime-type). Apart from source_quality, + * these values are set when we find the quality for each variant + * (see best_match()). source_quality is set from the 'qs' parameter + * of the variant description or mime type: see set_mime_fields(). + */ + float lang_quality; /* quality of this variant's language */ + float encoding_quality; /* ditto encoding */ + float charset_quality; /* ditto charset */ + float mime_type_quality; /* ditto media type */ + float source_quality; /* source quality for this variant */ + + /* Now some special values */ + float level; /* Auxiliary to content-type... */ + apr_off_t bytes; /* content length, if known */ + int lang_index; /* Index into LanguagePriority list */ + int is_pseudo_html; /* text/html, *or* the INCLUDES_MAGIC_TYPEs */ + + /* Above are all written-once properties of the variant. The + * three fields below are changed during negotiation: + */ + + float level_matched; + int mime_stars; + int definite; +} var_rec; + +/* Something to carry around the state of negotiation (and to keep + * all of this thread-safe)... + */ + +typedef struct { + apr_pool_t *pool; + request_rec *r; + neg_dir_config *conf; + char *dir_name; + int accept_q; /* 1 if an Accept item has a q= param */ + float default_lang_quality; /* fiddle lang q for variants with no lang */ + + /* the array pointers below are NULL if the corresponding accept + * headers are not present + */ + apr_array_header_t *accepts; /* accept_recs */ + apr_array_header_t *accept_encodings; /* accept_recs */ + apr_array_header_t *accept_charsets; /* accept_recs */ + apr_array_header_t *accept_langs; /* accept_recs */ + + apr_array_header_t *avail_vars; /* available variants */ + + int count_multiviews_variants; /* number of variants found on disk */ + + int is_transparent; /* 1 if this resource is trans. negotiable */ + + int dont_fiddle_headers; /* 1 if we may not fiddle with accept hdrs */ + int ua_supports_trans; /* 1 if ua supports trans negotiation */ + int send_alternates; /* 1 if we want to send an Alternates header */ + int may_choose; /* 1 if we may choose a variant for the client */ + int use_rvsa; /* 1 if we must use RVSA/1.0 negotiation algo */ +} negotiation_state; + +/* A few functions to manipulate var_recs. + * Cleaning out the fields... + */ + +static void clean_var_rec(var_rec *mime_info) +{ + mime_info->sub_req = NULL; + mime_info->mime_type = ""; + mime_info->file_name = ""; + mime_info->body = 0; + mime_info->content_encoding = NULL; + mime_info->content_languages = NULL; + mime_info->content_charset = ""; + mime_info->description = ""; + + mime_info->is_pseudo_html = 0; + mime_info->level = 0.0f; + mime_info->level_matched = 0.0f; + mime_info->bytes = -1; + mime_info->lang_index = -1; + mime_info->mime_stars = 0; + mime_info->definite = 1; + + mime_info->charset_quality = 1.0f; + mime_info->encoding_quality = 1.0f; + mime_info->lang_quality = 1.0f; + mime_info->mime_type_quality = 1.0f; + mime_info->source_quality = 0.0f; +} + +/* Initializing the relevant fields of a variant record from the + * accept_info read out of its content-type, one way or another. + */ + +static void set_mime_fields(var_rec *var, accept_rec *mime_info) +{ + var->mime_type = mime_info->name; + var->source_quality = mime_info->quality; + var->level = mime_info->level; + var->content_charset = mime_info->charset; + + var->is_pseudo_html = (!strcmp(var->mime_type, "text/html") + || !strcmp(var->mime_type, INCLUDES_MAGIC_TYPE) + || !strcmp(var->mime_type, INCLUDES_MAGIC_TYPE3)); +} + +/* Create a variant list validator in r using info from vlistr. */ + +static void set_vlist_validator(request_rec *r, request_rec *vlistr) +{ + /* Calculating the variant list validator is similar to + * calculating an etag for the source of the variant list + * information, so we use ap_make_etag(). Note that this + * validator can be 'weak' in extreme case. + */ + ap_update_mtime(vlistr, vlistr->finfo.mtime); + r->vlist_validator = ap_make_etag(vlistr, 0); + + /* ap_set_etag will later take r->vlist_validator into account + * when creating the etag header + */ +} + + +/***************************************************************** + * + * Parsing (lists of) media types and their parameters, as seen in + * HTTPD header lines and elsewhere. + */ + +/* + * parse quality value. atof(3) is not well-usable here, because it + * depends on the locale (argh). + * + * However, RFC 2616 states: + * 3.9 Quality Values + * + * [...] HTTP/1.1 applications MUST NOT generate more than three digits + * after the decimal point. User configuration of these values SHOULD also + * be limited in this fashion. + * + * qvalue = ( "0" [ "." 0*3DIGIT ] ) + * | ( "1" [ "." 0*3("0") ] ) + * + * This is quite easy. If the supplied string doesn't match the above + * definition (loosely), we simply return 1 (same as if there's no qvalue) + */ + +static float atoq(const char *string) +{ + if (!string || !*string) { + return 1.0f; + } + + while (*string && apr_isspace(*string)) { + ++string; + } + + /* be tolerant and accept qvalues without leading zero + * (also for backwards compat, where atof() was in use) + */ + if (*string != '.' && *string++ != '0') { + return 1.0f; + } + + if (*string == '.') { + /* better only one division later, than dealing with fscking + * IEEE format 0.1 factors ... + */ + int i = 0; + + if (*++string >= '0' && *string <= '9') { + i += (*string - '0') * 100; + + if (*++string >= '0' && *string <= '9') { + i += (*string - '0') * 10; + + if (*++string > '0' && *string <= '9') { + i += (*string - '0'); + } + } + } + + return (float)i / 1000.0f; + } + + return 0.0f; +} + +/* + * Get a single mime type entry --- one media type and parameters; + * enter the values we recognize into the argument accept_rec + */ + +static const char *get_entry(apr_pool_t *p, accept_rec *result, + const char *accept_line) +{ + result->quality = 1.0f; + result->level = 0.0f; + result->charset = ""; + + /* + * Note that this handles what I gather is the "old format", + * + * Accept: text/html text/plain moo/zot + * + * without any compatibility kludges --- if the token after the + * MIME type begins with a semicolon, we know we're looking at parms, + * otherwise, we know we aren't. (So why all the pissing and moaning + * in the CERN server code? I must be missing something). + */ + + result->name = ap_get_token(p, &accept_line, 0); + ap_str_tolower(result->name); /* You want case insensitive, + * you'll *get* case insensitive. + */ + + /* KLUDGE!!! Default HTML to level 2.0 unless the browser + * *explicitly* says something else. + */ + + if (!strcmp(result->name, "text/html") && (result->level == 0.0)) { + result->level = 2.0f; + } + else if (!strcmp(result->name, INCLUDES_MAGIC_TYPE)) { + result->level = 2.0f; + } + else if (!strcmp(result->name, INCLUDES_MAGIC_TYPE3)) { + result->level = 3.0f; + } + + while (*accept_line == ';') { + /* Parameters ... */ + + char *parm; + char *cp; + char *end; + + ++accept_line; + parm = ap_get_token(p, &accept_line, 1); + + /* Look for 'var = value' --- and make sure the var is in lcase. */ + + for (cp = parm; (*cp && !apr_isspace(*cp) && *cp != '='); ++cp) { + *cp = apr_tolower(*cp); + } + + if (!*cp) { + continue; /* No '='; just ignore it. */ + } + + *cp++ = '\0'; /* Delimit var */ + while (*cp && (apr_isspace(*cp) || *cp == '=')) { + ++cp; + } + + if (*cp == '"') { + ++cp; + for (end = cp; + (*end && *end != '\n' && *end != '\r' && *end != '\"'); + end++); + } + else { + for (end = cp; (*end && !apr_isspace(*end)); end++); + } + if (*end) { + *end = '\0'; /* strip ending quote or return */ + } + ap_str_tolower(cp); + + if (parm[0] == 'q' + && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) { + result->quality = atoq(cp); + } + else if (parm[0] == 'l' && !strcmp(&parm[1], "evel")) { + result->level = (float)atoi(cp); + } + else if (!strcmp(parm, "charset")) { + result->charset = cp; + } + } + + if (*accept_line == ',') { + ++accept_line; + } + + return accept_line; +} + +/***************************************************************** + * + * Dealing with header lines ... + * + * Accept, Accept-Charset, Accept-Language and Accept-Encoding + * are handled by do_header_line() - they all have the same + * basic structure of a list of items of the format + * name; q=N; charset=TEXT + * + * where charset is only valid in Accept. + */ + +static apr_array_header_t *do_header_line(apr_pool_t *p, + const char *accept_line) +{ + apr_array_header_t *accept_recs; + + if (!accept_line) { + return NULL; + } + + accept_recs = apr_array_make(p, 40, sizeof(accept_rec)); + + while (*accept_line) { + accept_rec *new = (accept_rec *) apr_array_push(accept_recs); + accept_line = get_entry(p, new, accept_line); + } + + return accept_recs; +} + +/* Given the text of the Content-Languages: line from the var map file, + * return an array containing the languages of this variant + */ + +static apr_array_header_t *do_languages_line(apr_pool_t *p, + const char **lang_line) +{ + apr_array_header_t *lang_recs = apr_array_make(p, 2, sizeof(char *)); + + if (!lang_line) { + return lang_recs; + } + + while (**lang_line) { + char **new = (char **) apr_array_push(lang_recs); + *new = ap_get_token(p, lang_line, 0); + ap_str_tolower(*new); + if (**lang_line == ',' || **lang_line == ';') { + ++(*lang_line); + } + } + + return lang_recs; +} + +/***************************************************************** + * + * Handling header lines from clients... + */ + +static negotiation_state *parse_accept_headers(request_rec *r) +{ + negotiation_state *new = + (negotiation_state *) apr_pcalloc(r->pool, sizeof(negotiation_state)); + accept_rec *elts; + apr_table_t *hdrs = r->headers_in; + int i; + + new->pool = r->pool; + new->r = r; + new->conf = (neg_dir_config *)ap_get_module_config(r->per_dir_config, + &negotiation_module); + + new->dir_name = ap_make_dirstr_parent(r->pool, r->filename); + + new->accepts = do_header_line(r->pool, apr_table_get(hdrs, "Accept")); + + /* calculate new->accept_q value */ + if (new->accepts) { + elts = (accept_rec *) new->accepts->elts; + + for (i = 0; i < new->accepts->nelts; ++i) { + if (elts[i].quality < 1.0) { + new->accept_q = 1; + } + } + } + + new->accept_encodings = + do_header_line(r->pool, apr_table_get(hdrs, "Accept-Encoding")); + new->accept_langs = + do_header_line(r->pool, apr_table_get(hdrs, "Accept-Language")); + new->accept_charsets = + do_header_line(r->pool, apr_table_get(hdrs, "Accept-Charset")); + + /* This is possibly overkill for some servers, heck, we have + * only 33 index.html variants in docs/docroot (today). + * Make this configurable? + */ + new->avail_vars = apr_array_make(r->pool, 40, sizeof(var_rec)); + + return new; +} + + +static void parse_negotiate_header(request_rec *r, negotiation_state *neg) +{ + const char *negotiate = apr_table_get(r->headers_in, "Negotiate"); + char *tok; + + /* 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; + + if (!negotiate) + return; + + 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 = apr_table_get(r->headers_in, "User-Agent"); + + if (ua && (strncmp(ua, "Lynx", 4) == 0)) + return; + } + + neg->may_choose = 0; /* An empty Negotiate would require 300 response */ + + while ((tok = ap_get_list_item(neg->pool, &negotiate)) != NULL) { + + if (strcmp(tok, "trans") == 0 || + strcmp(tok, "vlist") == 0 || + strcmp(tok, "guess-small") == 0 || + apr_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 (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 + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "dont_fiddle_headers=%d use_rvsa=%d ua_supports_trans=%d " + "send_alternates=%d, may_choose=%d", + neg->dont_fiddle_headers, neg->use_rvsa, + neg->ua_supports_trans, neg->send_alternates, neg->may_choose); +#endif + +} + +/* Sometimes clients will give us no Accept info at all; this routine sets + * up the standard default for that case, and also arranges for us to be + * willing to run a CGI script if we find one. (In fact, we set up to + * dramatically prefer CGI scripts in cases where that's appropriate, + * e.g., POST or when URI includes query args or extra path info). + */ +static void maybe_add_default_accepts(negotiation_state *neg, + int prefer_scripts) +{ + accept_rec *new_accept; + + if (!neg->accepts) { + neg->accepts = apr_array_make(neg->pool, 4, sizeof(accept_rec)); + + new_accept = (accept_rec *) apr_array_push(neg->accepts); + + new_accept->name = "*/*"; + new_accept->quality = 1.0f; + new_accept->level = 0.0f; + } + + new_accept = (accept_rec *) apr_array_push(neg->accepts); + + new_accept->name = CGI_MAGIC_TYPE; + if (neg->use_rvsa) { + new_accept->quality = 0; + } + else { + new_accept->quality = prefer_scripts ? 2.0f : 0.001f; + } + new_accept->level = 0.0f; +} + +/***************************************************************** + * + * Parsing type-map files, in Roy's meta/http format augmented with + * #-comments. + */ + +/* Reading RFC822-style header lines, ignoring #-comments and + * handling continuations. + */ + +enum header_state { + header_eof, header_seen, header_sep +}; + +static enum header_state get_header_line(char *buffer, int len, apr_file_t *map) +{ + char *buf_end = buffer + len; + char *cp; + char c; + + /* Get a noncommented line */ + + do { + if (apr_file_gets(buffer, MAX_STRING_LEN, map) != APR_SUCCESS) { + return header_eof; + } + } while (buffer[0] == '#'); + + /* If blank, just return it --- this ends information on this variant */ + + for (cp = buffer; (*cp && apr_isspace(*cp)); ++cp) { + continue; + } + + if (*cp == '\0') { + return header_sep; + } + + /* If non-blank, go looking for header lines, but note that we still + * have to treat comments specially... + */ + + cp += strlen(cp); + + /* We need to shortcut the rest of this block following the Body: + * tag - we will not look for continutation after this line. + */ + if (!strncasecmp(buffer, "Body:", 5)) + return header_seen; + + while (apr_file_getc(&c, map) != APR_EOF) { + if (c == '#') { + /* Comment line */ + while (apr_file_getc(&c, map) != APR_EOF && c != '\n') { + continue; + } + } + else if (apr_isspace(c)) { + /* Leading whitespace. POSSIBLE continuation line + * Also, possibly blank --- if so, we ungetc() the final newline + * so that we will pick up the blank line the next time 'round. + */ + + while (c != '\n' && apr_isspace(c)) { + if(apr_file_getc(&c, map) != APR_SUCCESS) + break; + } + + apr_file_ungetc(c, map); + + if (c == '\n') { + return header_seen; /* Blank line */ + } + + /* Continuation */ + + while ( cp < buf_end - 2 + && (apr_file_getc(&c, map)) != APR_EOF + && c != '\n') { + *cp++ = c; + } + + *cp++ = '\n'; + *cp = '\0'; + } + else { + + /* Line beginning with something other than whitespace */ + + apr_file_ungetc(c, map); + return header_seen; + } + } + + return header_seen; +} + +static apr_off_t get_body(char *buffer, apr_size_t *len, const char *tag, + apr_file_t *map) +{ + char *endbody; + int bodylen; + int taglen; + apr_off_t pos; + + taglen = strlen(tag); + *len -= taglen; + + /* We are at the first character following a body:tag\n entry + * Suck in the body, then backspace to the first char after the + * closing tag entry. If we fail to read, find the tag or back + * up then we have a hosed file, so give up already + */ + if (apr_file_read(map, buffer, len) != APR_SUCCESS) { + return -1; + } + + /* put a copy of the tag *after* the data read from the file + * so that strstr() will find something with no reliance on + * terminating '\0' + */ + memcpy(buffer + *len, tag, taglen); + endbody = strstr(buffer, tag); + if (endbody == buffer + *len) { + return -1; + } + bodylen = endbody - buffer; + endbody += strlen(tag); + /* Skip all the trailing cruft after the end tag to the next line */ + while (*endbody) { + if (*endbody == '\n') { + ++endbody; + break; + } + ++endbody; + } + + pos = -(apr_off_t)(*len - (endbody - buffer)); + if (apr_file_seek(map, APR_CUR, &pos) != APR_SUCCESS) { + return -1; + } + + /* Give the caller back the actual body's file offset and length */ + *len = bodylen; + return pos - (endbody - buffer); +} + + +/* Stripping out RFC822 comments */ + +static void strip_paren_comments(char *hdr) +{ + /* Hmmm... is this correct? In Roy's latest draft, (comments) can nest! */ + /* Nope, it isn't correct. Fails to handle backslash escape as well. */ + + while (*hdr) { + if (*hdr == '"') { + hdr = strchr(hdr, '"'); + if (hdr == NULL) { + return; + } + ++hdr; + } + else if (*hdr == '(') { + while (*hdr && *hdr != ')') { + *hdr++ = ' '; + } + + if (*hdr) { + *hdr++ = ' '; + } + } + else { + ++hdr; + } + } +} + +/* Getting to a header body from the header */ + +static char *lcase_header_name_return_body(char *header, request_rec *r) +{ + char *cp = header; + + for ( ; *cp && *cp != ':' ; ++cp) { + *cp = apr_tolower(*cp); + } + + if (!*cp) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Syntax error in type map, no ':' in %s for header %s", + r->filename, header); + return NULL; + } + + do { + ++cp; + } while (*cp && apr_isspace(*cp)); + + if (!*cp) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Syntax error in type map --- no header body: %s for %s", + r->filename, header); + return NULL; + } + + return cp; +} + +static int read_type_map(apr_file_t **map, negotiation_state *neg, + request_rec *rr) +{ + request_rec *r = neg->r; + apr_file_t *map_ = NULL; + apr_status_t status; + char buffer[MAX_STRING_LEN]; + enum header_state hstate; + struct var_rec mime_info; + int has_content; + + if (!map) + map = &map_; + + /* We are not using multiviews */ + neg->count_multiviews_variants = 0; + + if ((status = apr_file_open(map, rr->filename, APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, neg->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "cannot access type map file: %s", rr->filename); + return APR_STATUS_IS_ENOENT(status) ? HTTP_NOT_FOUND : HTTP_FORBIDDEN; + } + + clean_var_rec(&mime_info); + has_content = 0; + + do { + hstate = get_header_line(buffer, MAX_STRING_LEN, *map); + + if (hstate == header_seen) { + char *body1 = lcase_header_name_return_body(buffer, neg->r); + const char *body; + + if (body1 == NULL) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + strip_paren_comments(body1); + body = body1; + + if (!strncmp(buffer, "uri:", 4)) { + mime_info.file_name = ap_get_token(neg->pool, &body, 0); + } + else if (!strncmp(buffer, "content-type:", 13)) { + struct accept_rec accept_info; + + get_entry(neg->pool, &accept_info, body); + set_mime_fields(&mime_info, &accept_info); + has_content = 1; + } + else if (!strncmp(buffer, "content-length:", 15)) { + char *errp; + apr_off_t number; + + if (apr_strtoff(&number, body, &errp, 10) + || *errp || number < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Parse error in type map, Content-Length: " + "'%s' in %s is invalid.", + body, r->filename); + break; + } + mime_info.bytes = number; + has_content = 1; + } + else if (!strncmp(buffer, "content-language:", 17)) { + mime_info.content_languages = do_languages_line(neg->pool, + &body); + has_content = 1; + } + else if (!strncmp(buffer, "content-encoding:", 17)) { + mime_info.content_encoding = ap_get_token(neg->pool, &body, 0); + has_content = 1; + } + else if (!strncmp(buffer, "description:", 12)) { + char *desc = apr_pstrdup(neg->pool, body); + char *cp; + + for (cp = desc; *cp; ++cp) { + if (*cp=='\n') *cp=' '; + } + if (cp>desc) *(cp-1)=0; + mime_info.description = desc; + } + else if (!strncmp(buffer, "body:", 5)) { + char *tag = apr_pstrdup(neg->pool, body); + char *eol = strchr(tag, '\0'); + apr_size_t len = MAX_STRING_LEN; + while (--eol >= tag && apr_isspace(*eol)) + *eol = '\0'; + if ((mime_info.body = get_body(buffer, &len, tag, *map)) < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Syntax error in type map, no end tag '%s'" + "found in %s for Body: content.", + tag, r->filename); + break; + } + mime_info.bytes = len; + mime_info.file_name = apr_filepath_name_get(rr->filename); + } + } + else { + if (*mime_info.file_name && has_content) { + void *new_var = apr_array_push(neg->avail_vars); + + memcpy(new_var, (void *) &mime_info, sizeof(var_rec)); + } + + clean_var_rec(&mime_info); + has_content = 0; + } + } while (hstate != header_eof); + + if (map_) + apr_file_close(map_); + + set_vlist_validator(r, rr); + + return OK; +} + + +/* Sort function used by read_types_multi. */ +static int variantsortf(var_rec *a, var_rec *b) { + + /* First key is the source quality, sort in descending order. */ + + /* XXX: note that we currently implement no method of setting the + * source quality for multiviews variants, so we are always comparing + * 1.0 to 1.0 for now + */ + if (a->source_quality < b->source_quality) + return 1; + if (a->source_quality > b->source_quality) + return -1; + + /* Second key is the variant name */ + return strcmp(a->file_name, b->file_name); +} + +/***************************************************************** + * + * Same as read_type_map, except we use a filtered directory listing + * as the map... + */ + +static int read_types_multi(negotiation_state *neg) +{ + request_rec *r = neg->r; + + char *filp; + int prefix_len; + apr_dir_t *dirp; + apr_finfo_t dirent; + apr_status_t status; + struct var_rec mime_info; + struct accept_rec accept_info; + void *new_var; + int anymatch = 0; + + clean_var_rec(&mime_info); + + if (r->proxyreq || !r->filename + || !ap_os_is_path_absolute(neg->pool, r->filename)) { + return DECLINED; + } + + /* Only absolute paths here */ + if (!(filp = strrchr(r->filename, '/'))) { + return DECLINED; + } + ++filp; + prefix_len = strlen(filp); + + if ((status = apr_dir_open(&dirp, neg->dir_name, + neg->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "cannot read directory for multi: %s", neg->dir_name); + return HTTP_FORBIDDEN; + } + + while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { + apr_array_header_t *exception_list; + request_rec *sub_req; + + /* Do we have a match? */ +#ifdef CASE_BLIND_FILESYSTEM + if (strncasecmp(dirent.name, filp, prefix_len)) { +#else + if (strncmp(dirent.name, filp, prefix_len)) { +#endif + continue; + } + if (dirent.name[prefix_len] != '.') { + continue; + } + + /* Don't negotiate directories and other unusual files + * Really shouldn't see anything but DIR/LNK/REG here, + * and we aught to discover if the LNK was interesting. + * + * Of course, this only helps platforms that capture the + * the filetype in apr_dir_read(), which most can once + * they are optimized with some magic [it's known to the + * dirent, not associated to the inode, on most FS's.] + */ + if ((dirent.valid & APR_FINFO_TYPE) && (dirent.filetype == APR_DIR)) + continue; + + /* Ok, something's here. Maybe nothing useful. Remember that + * we tried, if we completely fail, so we can reject the request! + */ + anymatch = 1; + + /* See if it's something which we have access to, and which + * has a known type and encoding (as opposed to something + * which we'll be slapping default_type on later). + */ + sub_req = ap_sub_req_lookup_dirent(&dirent, r, AP_SUBREQ_MERGE_ARGS, + NULL); + + /* Double check, we still don't multi-resolve non-ordinary files + */ + if (sub_req->finfo.filetype != APR_REG) + continue; + + /* If it has a handler, we'll pretend it's a CGI script, + * since that's a good indication of the sort of thing it + * might be doing. + */ + if (sub_req->handler && !sub_req->content_type) { + ap_set_content_type(sub_req, CGI_MAGIC_TYPE); + } + + /* + * mod_mime will _always_ provide us the base name in the + * ap-mime-exception-list, if it processed anything. If + * this list is empty, give up immediately, there was + * nothing interesting. For example, looking at the files + * readme.txt and readme.foo, we will throw away .foo if + * it's an insignificant file (e.g. did not identify a + * language, charset, encoding, content type or handler,) + */ + exception_list = + (apr_array_header_t *)apr_table_get(sub_req->notes, + "ap-mime-exceptions-list"); + + if (!exception_list) { + ap_destroy_sub_req(sub_req); + continue; + } + + /* Each unregonized bit better match our base name, in sequence. + * A test of index.html.foo will match index.foo or index.html.foo, + * but it will never transpose the segments and allow index.foo.html + * because that would introduce too much CPU consumption. Better that + * we don't attempt a many-to-many match here. + */ + { + int nexcept = exception_list->nelts; + char **cur_except = (char**)exception_list->elts; + char *segstart = filp, *segend, saveend; + + while (*segstart && nexcept) { + if (!(segend = strchr(segstart, '.'))) + segend = strchr(segstart, '\0'); + saveend = *segend; + *segend = '\0'; + +#ifdef CASE_BLIND_FILESYSTEM + if (strcasecmp(segstart, *cur_except) == 0) { +#else + if (strcmp(segstart, *cur_except) == 0) { +#endif + --nexcept; + ++cur_except; + } + + if (!saveend) + break; + + *segend = saveend; + segstart = segend + 1; + } + + if (nexcept) { + /* Something you don't know is, something you don't know... + */ + ap_destroy_sub_req(sub_req); + continue; + } + } + + /* + * ###: be warned, the _default_ content type is already + * picked up here! If we failed the subrequest, or don't + * know what we are serving, then continue. + */ + if (sub_req->status != HTTP_OK || (!sub_req->content_type)) { + ap_destroy_sub_req(sub_req); + continue; + } + + /* If it's a map file, we use that instead of the map + * we're building... + */ + if (((sub_req->content_type) && + !strcmp(sub_req->content_type, MAP_FILE_MAGIC_TYPE)) || + ((sub_req->handler) && + !strcmp(sub_req->handler, "type-map"))) { + + apr_dir_close(dirp); + neg->avail_vars->nelts = 0; + if (sub_req->status != HTTP_OK) { + return sub_req->status; + } + return read_type_map(NULL, neg, sub_req); + } + + /* Have reasonable variant --- gather notes. */ + + mime_info.sub_req = sub_req; + mime_info.file_name = apr_pstrdup(neg->pool, dirent.name); + if (sub_req->content_encoding) { + mime_info.content_encoding = sub_req->content_encoding; + } + if (sub_req->content_languages) { + mime_info.content_languages = sub_req->content_languages; + } + + get_entry(neg->pool, &accept_info, sub_req->content_type); + set_mime_fields(&mime_info, &accept_info); + + new_var = apr_array_push(neg->avail_vars); + memcpy(new_var, (void *) &mime_info, sizeof(var_rec)); + + neg->count_multiviews_variants++; + + clean_var_rec(&mime_info); + } + + apr_dir_close(dirp); + + /* We found some file names that matched. None could be served. + * Rather than fall out to autoindex or some other mapper, this + * request must die. + */ + if (anymatch && !neg->avail_vars->nelts) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Negotiation: discovered file(s) matching request: %s" + " (None could be negotiated).", + r->filename); + return HTTP_NOT_FOUND; + } + + set_vlist_validator(r, r); + + /* Sort the variants into a canonical order. The negotiation + * result sometimes depends on the order of the variants. By + * sorting the variants into a canonical order, rather than using + * the order in which readdir() happens to return them, we ensure + * that the negotiation result will be consistent over filesystem + * backup/restores and over all mirror sites. + */ + + qsort((void *) neg->avail_vars->elts, neg->avail_vars->nelts, + sizeof(var_rec), (int (*)(const void *, const void *)) variantsortf); + + return OK; +} + + +/***************************************************************** + * And now for the code you've been waiting for... actually + * finding a match to the client's requirements. + */ + +/* Matching MIME types ... the star/star and foo/star commenting conventions + * are implemented here. (You know what I mean by star/star, but just + * try mentioning those three characters in a C comment). Using strcmp() + * is legit, because everything has already been smashed to lowercase. + * + * Note also that if we get an exact match on the media type, we update + * level_matched for use in level_cmp below... + * + * We also give a value for mime_stars, which is used later. It should + * be 1 for star/star, 2 for type/star and 3 for type/subtype. + */ + +static int mime_match(accept_rec *accept_r, var_rec *avail) +{ + const char *accept_type = accept_r->name; + const char *avail_type = avail->mime_type; + int len = strlen(accept_type); + + if (accept_type[0] == '*') { /* Anything matches star/star */ + if (avail->mime_stars < 1) { + avail->mime_stars = 1; + } + return 1; + } + else if ((accept_type[len - 1] == '*') && + !strncmp(accept_type, avail_type, len - 2)) { + if (avail->mime_stars < 2) { + avail->mime_stars = 2; + } + return 1; + } + else if (!strcmp(accept_type, avail_type) + || (!strcmp(accept_type, "text/html") + && (!strcmp(avail_type, INCLUDES_MAGIC_TYPE) + || !strcmp(avail_type, INCLUDES_MAGIC_TYPE3)))) { + if (accept_r->level >= avail->level) { + avail->level_matched = avail->level; + avail->mime_stars = 3; + return 1; + } + } + + return OK; +} + +/* This code implements a piece of the tie-breaking algorithm between + * variants of equal quality. This piece is the treatment of variants + * of the same base media type, but different levels. What we want to + * return is the variant at the highest level that the client explicitly + * claimed to accept. + * + * If all the variants available are at a higher level than that, or if + * the client didn't say anything specific about this media type at all + * and these variants just got in on a wildcard, we prefer the lowest + * level, on grounds that that's the one that the client is least likely + * to choke on. + * + * (This is all motivated by treatment of levels in HTML --- we only + * want to give level 3 to browsers that explicitly ask for it; browsers + * that don't, including HTTP/0.9 browsers that only get the implicit + * "Accept: * / *" [space added to avoid confusing cpp --- no, that + * syntax doesn't really work] should get HTML2 if available). + * + * (Note that this code only comes into play when we are choosing among + * variants of equal quality, where the draft standard gives us a fair + * bit of leeway about what to do. It ain't specified by the standard; + * rather, it is a choice made by this server about what to do in cases + * where the standard does not specify a unique course of action). + */ + +static int level_cmp(var_rec *var1, var_rec *var2) +{ + /* Levels are only comparable between matching media types */ + + if (var1->is_pseudo_html && !var2->is_pseudo_html) { + return 0; + } + + if (!var1->is_pseudo_html && strcmp(var1->mime_type, var2->mime_type)) { + return 0; + } + /* The result of the above if statements is that, if we get to + * here, both variants have the same mime_type or both are + * pseudo-html. + */ + + /* Take highest level that matched, if either did match. */ + + if (var1->level_matched > var2->level_matched) { + return 1; + } + if (var1->level_matched < var2->level_matched) { + return -1; + } + + /* Neither matched. Take lowest level, if there's a difference. */ + + if (var1->level < var2->level) { + return 1; + } + if (var1->level > var2->level) { + return -1; + } + + /* Tied */ + + return 0; +} + +/* Finding languages. The main entry point is set_language_quality() + * which is called for each variant. It sets two elements in the + * variant record: + * language_quality - the 'q' value of the 'best' matching language + * from Accept-Language: header (HTTP/1.1) + * lang_index - Non-negotiated language priority, using + * position of language on the Accept-Language: + * header, if present, else LanguagePriority + * directive order. + * + * When we do the variant checking for best variant, we use language + * quality first, and if a tie, language_index next (this only applies + * when _not_ using the RVSA/1.0 algorithm). If using the RVSA/1.0 + * algorithm, lang_index is never used. + * + * set_language_quality() calls find_lang_index() and find_default_index() + * to set lang_index. + */ + +static int find_lang_index(apr_array_header_t *accept_langs, char *lang) +{ + const char **alang; + int i; + + if (!lang || !accept_langs) { + return -1; + } + + alang = (const char **) accept_langs->elts; + + for (i = 0; i < accept_langs->nelts; ++i) { + if (!strncmp(lang, *alang, strlen(*alang))) { + return i; + } + alang += (accept_langs->elt_size / sizeof(char*)); + } + + return -1; +} + +/* set_default_lang_quality() sets the quality we apply to variants + * which have no language assigned to them. If none of the variants + * have a language, we are not negotiating on language, so all are + * acceptable, and we set the default q value to 1.0. However if + * some of the variants have languages, we set this default to 0.0001. + * The value of this default will be applied to all variants with + * no explicit language -- which will have the effect of making them + * acceptable, but only if no variants with an explicit language + * are acceptable. The default q value set here is assigned to variants + * with no language type in set_language_quality(). + * + * Note that if using the RVSA/1.0 algorithm, we don't use this + * fiddle. + */ + +static void set_default_lang_quality(negotiation_state *neg) +{ + var_rec *avail_recs = (var_rec *) neg->avail_vars->elts; + int j; + + if (!neg->dont_fiddle_headers) { + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + if (variant->content_languages && + variant->content_languages->nelts) { + neg->default_lang_quality = 0.0001f; + return; + } + } + } + + neg->default_lang_quality = 1.0f; +} + +/* Set the language_quality value in the variant record. Also + * assigns lang_index for ForceLanguagePriority. + * + * To find the language_quality value, we look for the 'q' value + * of the 'best' matching language on the Accept-Language + * header. The 'best' match is the language on Accept-Language + * header which matches the language of this variant either fully, + * or as far as the prefix marker (-). If two or more languages + * match, use the longest string from the Accept-Language header + * (see HTTP/1.1 [14.4]) + * + * When a variant has multiple languages, we find the 'best' + * match for each variant language tag as above, then select the + * one with the highest q value. Because both the accept-header + * and variant can have multiple languages, we now have a hairy + * loop-within-a-loop here. + * + * If the variant has no language and we have no Accept-Language + * items, leave the quality at 1.0 and return. + * + * If the variant has no language, we use the default as set by + * set_default_lang_quality() (1.0 if we are not negotiating on + * language, 0.001 if we are). + * + * Following the setting of the language quality, we drop through to + * set the old 'lang_index'. This is set based on either the order + * of the languages on the Accept-Language header, or the + * order on the LanguagePriority directive. This is only used + * in the negotiation if the language qualities tie. + */ + +static void set_language_quality(negotiation_state *neg, var_rec *variant) +{ + int forcepriority = neg->conf->forcelangpriority; + if (forcepriority == FLP_UNDEF) { + forcepriority = FLP_DEFAULT; + } + + if (!variant->content_languages || !variant->content_languages->nelts) { + /* This variant has no content-language, so use the default + * quality factor for variants with no content-language + * (previously set by set_default_lang_quality()). + * Leave the factor alone (it remains at 1.0) when we may not fiddle + * with the headers. + */ + if (!neg->dont_fiddle_headers) { + variant->lang_quality = neg->default_lang_quality; + } + if (!neg->accept_langs) { + return; /* no accept-language header */ + } + return; + } + else { + /* Variant has one (or more) languages. Look for the best + * match. We do this by going through each language on the + * variant description looking for a match on the + * Accept-Language header. The best match is the longest + * matching language on the header. The final result is the + * best q value from all the languages on the variant + * description. + */ + + if (!neg->accept_langs) { + /* no accept-language header makes the variant indefinite */ + variant->definite = 0; + } + else { /* There is an accept-language with 0 or more items */ + accept_rec *accs = (accept_rec *) neg->accept_langs->elts; + accept_rec *best = NULL, *star = NULL; + accept_rec *bestthistag; + char *lang, *p; + float fiddle_q = 0.0f; + int any_match_on_star = 0; + int i, j; + apr_size_t alen, longest_lang_range_len; + + for (j = 0; j < variant->content_languages->nelts; ++j) { + p = NULL; + bestthistag = NULL; + longest_lang_range_len = 0; + alen = 0; + + /* lang is the variant's language-tag, which is the one + * we are allowed to use the prefix of in HTTP/1.1 + */ + lang = ((char **) (variant->content_languages->elts))[j]; + + /* now find the best (i.e. longest) matching + * Accept-Language header language. We put the best match + * for this tag in bestthistag. We cannot update the + * overall best (based on q value) because the best match + * for this tag is the longest language item on the accept + * header, not necessarily the highest q. + */ + for (i = 0; i < neg->accept_langs->nelts; ++i) { + if (!strcmp(accs[i].name, "*")) { + if (!star) { + star = &accs[i]; + } + continue; + } + /* Find language. We match if either the variant + * language tag exactly matches the language range + * from the accept header, or a prefix of the variant + * language tag up to a '-' character matches the + * whole of the language range in the Accept-Language + * header. Note that HTTP/1.x allows any number of + * '-' characters in a tag or range, currently only + * tags with zero or one '-' characters are defined + * for general use (see rfc1766). + * + * We only use language range in the Accept-Language + * header the best match for the variant language tag + * if it is longer than the previous best match. + */ + + alen = strlen(accs[i].name); + + if ((strlen(lang) >= alen) && + !strncmp(lang, accs[i].name, alen) && + ((lang[alen] == 0) || (lang[alen] == '-')) ) { + + if (alen > longest_lang_range_len) { + longest_lang_range_len = alen; + bestthistag = &accs[i]; + } + } + + if (!bestthistag && !neg->dont_fiddle_headers) { + /* The next bit is a fiddle. Some browsers might + * be configured to send more specific language + * ranges than desirable. For example, an + * Accept-Language of en-US should never match + * variants with languages en or en-GB. But US + * English speakers might pick en-US as their + * language choice. So this fiddle checks if the + * language range has a prefix, and if so, it + * matches variants which match that prefix with a + * priority of 0.001. So a request for en-US would + * match variants of types en and en-GB, but at + * much lower priority than matches of en-US + * directly, or of any other language listed on + * the Accept-Language header. Note that this + * fiddle does not handle multi-level prefixes. + */ + if ((p = strchr(accs[i].name, '-'))) { + int plen = p - accs[i].name; + + if (!strncmp(lang, accs[i].name, plen)) { + fiddle_q = 0.001f; + } + } + } + } + /* Finished looking at Accept-Language headers, the best + * (longest) match is in bestthistag, or NULL if no match + */ + if (!best || + (bestthistag && bestthistag->quality > best->quality)) { + best = bestthistag; + } + + /* See if the tag matches on a * in the Accept-Language + * header. If so, record this fact for later use + */ + if (!bestthistag && star) { + any_match_on_star = 1; + } + } + + /* If one of the language tags of the variant matched on *, we + * need to see if its q is better than that of any non-* match + * on any other tag of the variant. If so the * match takes + * precedence and the overall match is not definite. + */ + if ( any_match_on_star && + ((best && star->quality > best->quality) || + (!best)) ) { + best = star; + variant->definite = 0; + } + + variant->lang_quality = best ? best->quality : fiddle_q; + } + } + + /* Handle the ForceDefaultLanguage overrides, based on the best match + * to LanguagePriority order. The best match is the lowest index of + * any LanguagePriority match. + */ + if (((forcepriority & FLP_PREFER) + && (variant->lang_index < 0)) + || ((forcepriority & FLP_FALLBACK) + && !variant->lang_quality)) + { + int bestidx = -1; + int j; + + for (j = 0; j < variant->content_languages->nelts; ++j) + { + /* lang is the variant's language-tag, which is the one + * we are allowed to use the prefix of in HTTP/1.1 + */ + char *lang = ((char **) (variant->content_languages->elts))[j]; + int idx = -1; + + /* If we wish to fallback or + * we use our own LanguagePriority index. + */ + idx = find_lang_index(neg->conf->language_priority, lang); + if ((idx >= 0) && ((bestidx == -1) || (idx < bestidx))) { + bestidx = idx; + } + } + + if (bestidx >= 0) { + if (variant->lang_quality) { + if (forcepriority & FLP_PREFER) { + variant->lang_index = bestidx; + } + } + else { + if (forcepriority & FLP_FALLBACK) { + variant->lang_index = bestidx; + variant->lang_quality = .0001f; + variant->definite = 0; + } + } + } + } + return; +} + +/* Determining the content length --- if the map didn't tell us, + * we have to do a stat() and remember for next time. + */ + +static apr_off_t find_content_length(negotiation_state *neg, var_rec *variant) +{ + apr_finfo_t statb; + + if (variant->bytes < 0) { + if ( variant->sub_req + && (variant->sub_req->finfo.valid & APR_FINFO_SIZE)) { + variant->bytes = variant->sub_req->finfo.size; + } + else { + char *fullname = ap_make_full_path(neg->pool, neg->dir_name, + variant->file_name); + + if (apr_stat(&statb, fullname, + APR_FINFO_SIZE, neg->pool) == APR_SUCCESS) { + variant->bytes = statb.size; + } + } + } + + return variant->bytes; +} + +/* For a given variant, find the best matching Accept: header + * and assign the Accept: header's quality value to the + * mime_type_quality field of the variant, for later use in + * determining the best matching variant. + */ + +static void set_accept_quality(negotiation_state *neg, var_rec *variant) +{ + int i; + accept_rec *accept_recs; + float q = 0.0f; + int q_definite = 1; + + /* if no Accept: header, leave quality alone (will + * remain at the default value of 1) + * + * XXX: This if is currently never true because of the effect of + * maybe_add_default_accepts(). + */ + if (!neg->accepts) { + if (variant->mime_type && *variant->mime_type) + variant->definite = 0; + return; + } + + accept_recs = (accept_rec *) neg->accepts->elts; + + /* + * Go through each of the ranges on the Accept: header, + * looking for the 'best' match with this variant's + * content-type. We use the best match's quality + * value (from the Accept: header) for this variant's + * mime_type_quality field. + * + * The best match is determined like this: + * type/type is better than type/ * is better than * / * + * if match is type/type, use the level mime param if available + */ + for (i = 0; i < neg->accepts->nelts; ++i) { + + accept_rec *type = &accept_recs[i]; + int prev_mime_stars; + + prev_mime_stars = variant->mime_stars; + + if (!mime_match(type, variant)) { + continue; /* didn't match the content type at all */ + } + else { + /* did match - see if there were less or more stars than + * in previous match + */ + if (prev_mime_stars == variant->mime_stars) { + continue; /* more stars => not as good a match */ + } + } + + /* If we are allowed to mess with the q-values + * and have no explicit q= parameters in the accept header, + * make wildcards very low, so we have a low chance + * of ending up with them if there's something better. + */ + + if (!neg->dont_fiddle_headers && !neg->accept_q && + variant->mime_stars == 1) { + q = 0.01f; + } + else if (!neg->dont_fiddle_headers && !neg->accept_q && + variant->mime_stars == 2) { + q = 0.02f; + } + else { + q = type->quality; + } + + q_definite = (variant->mime_stars == 3); + } + variant->mime_type_quality = q; + variant->definite = variant->definite && q_definite; + +} + +/* For a given variant, find the 'q' value of the charset given + * 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) +{ + int i; + accept_rec *accept_recs; + const char *charset = variant->content_charset; + accept_rec *star = NULL; + + /* if no Accept-Charset: header, leave quality alone (will + * remain at the default value of 1) + */ + if (!neg->accept_charsets) { + if (charset && *charset) + variant->definite = 0; + return; + } + + accept_recs = (accept_rec *) neg->accept_charsets->elts; + + if (charset == NULL || !*charset) { + /* Charset of variant not known */ + + /* if not a text / * type, leave quality alone */ + if (!(!strncmp(variant->mime_type, "text/", 5) + || !strcmp(variant->mime_type, INCLUDES_MAGIC_TYPE) + || !strcmp(variant->mime_type, INCLUDES_MAGIC_TYPE3) + )) + return; + + /* Don't go guessing if we are in strict header mode, + * e.g. when running the rvsa, as any guess won't be reflected + * in the variant list or content-location headers. + */ + if (neg->dont_fiddle_headers) + return; + + charset = "iso-8859-1"; /* The default charset for HTTP text types */ + } + + /* + * Go through each of the items on the Accept-Charset header, + * looking for a match with this variant's charset. If none + * match, charset is unacceptable, so set quality to 0. + */ + for (i = 0; i < neg->accept_charsets->nelts; ++i) { + + accept_rec *type = &accept_recs[i]; + + if (!strcmp(type->name, charset)) { + variant->charset_quality = type->quality; + return; + } + else if (strcmp(type->name, "*") == 0) { + star = type; + } + } + /* No explicit match */ + if (star) { + variant->charset_quality = star->quality; + variant->definite = 0; + return; + } + /* If this variant is in charset iso-8859-1, the default is 1.0 */ + if (strcmp(charset, "iso-8859-1") == 0) { + variant->charset_quality = 1.0f; + } + else { + variant->charset_quality = 0.0f; + } +} + + +/* is_identity_encoding is included for back-compat, but does anyone + * use 7bit, 8bin or binary in their var files?? + */ + +static int is_identity_encoding(const char *enc) +{ + return (!enc || !enc[0] || !strcmp(enc, "7bit") || !strcmp(enc, "8bit") + || !strcmp(enc, "binary")); +} + +/* + * set_encoding_quality determines whether the encoding for a particular + * variant is acceptable for the user-agent. + * + * The rules for encoding are that if the user-agent does not supply + * any Accept-Encoding header, then all encodings are allowed but a + * variant with no encoding should be preferred. + * If there is an empty Accept-Encoding header, then no encodings are + * acceptable. If there is a non-empty Accept-Encoding header, then + * any of the listed encodings are acceptable, as well as no encoding + * unless the "identity" encoding is specifically excluded. + */ +static void set_encoding_quality(negotiation_state *neg, var_rec *variant) +{ + accept_rec *accept_recs; + const char *enc = variant->content_encoding; + accept_rec *star = NULL; + float value_if_not_found = 0.0f; + int i; + + if (!neg->accept_encodings) { + /* We had no Accept-Encoding header, assume that all + * encodings are acceptable with a low quality, + * but we prefer no encoding if available. + */ + if (!enc || is_identity_encoding(enc)) + variant->encoding_quality = 1.0f; + else + variant->encoding_quality = 0.5f; + + return; + } + + if (!enc || is_identity_encoding(enc)) { + enc = "identity"; + value_if_not_found = 0.0001f; + } + + accept_recs = (accept_rec *) neg->accept_encodings->elts; + + /* Go through each of the encodings on the Accept-Encoding: header, + * looking for a match with our encoding. x- prefixes are ignored. + */ + if (enc[0] == 'x' && enc[1] == '-') { + enc += 2; + } + for (i = 0; i < neg->accept_encodings->nelts; ++i) { + + char *name = accept_recs[i].name; + + if (name[0] == 'x' && name[1] == '-') { + name += 2; + } + + if (!strcmp(name, enc)) { + variant->encoding_quality = accept_recs[i].quality; + return; + } + + if (strcmp(name, "*") == 0) { + star = &accept_recs[i]; + } + + } + /* No explicit match */ + if (star) { + variant->encoding_quality = star->quality; + return; + } + + /* Encoding not found on Accept-Encoding: header, so it is + * _not_ acceptable unless it is the identity (no encoding) + */ + variant->encoding_quality = value_if_not_found; +} + +/************************************************************* + * Possible results of the variant selection algorithm + */ +enum algorithm_results { + alg_choice = 1, /* choose variant */ + alg_list /* list variants */ +}; + +/* Below is the 'best_match' function. It returns an int, which has + * one of the two values alg_choice or alg_list, which give the result + * of the variant selection algorithm. alg_list means that no best + * variant was found by the algorithm, alg_choice means that a best + * variant was found and should be returned. The list/choice + * terminology comes from TCN (rfc2295), but is used in a more generic + * way here. The best variant is returned in *pbest. best_match has + * two possible algorithms for determining the best variant: the + * RVSA/1.0 algorithm (from RFC2296), and the standard Apache + * algorithm. These are split out into separate functions + * (is_variant_better_rvsa() and is_variant_better()). Selection of + * one is through the neg->use_rvsa flag. + * + * The call to best_match also creates full information, including + * language, charset, etc quality for _every_ variant. This is needed + * for generating a correct Vary header, and can be used for the + * Alternates header, the human-readable list responses and 406 errors. + */ + +/* Firstly, the RVSA/1.0 (HTTP Remote Variant Selection Algorithm + * v1.0) from rfc2296. This is the algorithm that goes together with + * transparent content negotiation (TCN). + */ +static int is_variant_better_rvsa(negotiation_state *neg, var_rec *variant, + var_rec *best, float *p_bestq) +{ + float bestq = *p_bestq, q; + + /* TCN does not cover negotiation on content-encoding. For now, + * we ignore the encoding unless it was explicitly excluded. + */ + if (variant->encoding_quality == 0.0f) + return 0; + + q = variant->mime_type_quality * + variant->source_quality * + variant->charset_quality * + variant->lang_quality; + + /* 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. + */ + +#ifdef NEG_DEBUG + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Variant: file=%s type=%s lang=%s sourceq=%1.3f " + "mimeq=%1.3f langq=%1.3f charq=%1.3f encq=%1.3f " + "q=%1.5f definite=%d", + (variant->file_name ? variant->file_name : ""), + (variant->mime_type ? variant->mime_type : ""), + (variant->content_languages + ? apr_array_pstrcat(neg->pool, variant->content_languages, ',') + : ""), + variant->source_quality, + variant->mime_type_quality, + variant->lang_quality, + variant->charset_quality, + variant->encoding_quality, + q, + variant->definite); +#endif + + if (q <= 0.0f) { + return 0; + } + if (q > bestq) { + *p_bestq = q; + return 1; + } + if (q == bestq) { + /* If the best variant's encoding is of lesser quality than + * this variant, then we prefer this variant + */ + if (variant->encoding_quality > best->encoding_quality) { + *p_bestq = q; + return 1; + } + } + return 0; +} + +/* Negotiation algorithm as used by previous versions of Apache + * (just about). + */ + +static int is_variant_better(negotiation_state *neg, var_rec *variant, + var_rec *best, float *p_bestq) +{ + float bestq = *p_bestq, q; + int levcmp; + + /* 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 encoding, content length. + * + * For each check, we have three possible outcomes: + * This variant is worse than current best: return 0 + * This variant is better than the current best: + * assign this variant's q to *p_bestq, and return 1 + * This variant is just as desirable as the current best: + * drop through to the next test. + * + * This code is written in this long-winded way to allow future + * customisation, either by the addition of additional + * checks, or to allow the order of the checks to be determined + * by configuration options (e.g. we might prefer to check + * language quality _before_ content type). + */ + + /* First though, eliminate this variant if it is not + * acceptable by type, charset, encoding or language. + */ + +#ifdef NEG_DEBUG + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Variant: file=%s type=%s lang=%s sourceq=%1.3f " + "mimeq=%1.3f langq=%1.3f langidx=%d charq=%1.3f encq=%1.3f ", + (variant->file_name ? variant->file_name : ""), + (variant->mime_type ? variant->mime_type : ""), + (variant->content_languages + ? apr_array_pstrcat(neg->pool, variant->content_languages, ',') + : ""), + variant->source_quality, + variant->mime_type_quality, + variant->lang_quality, + variant->lang_index, + variant->charset_quality, + variant->encoding_quality); +#endif + + if (variant->encoding_quality == 0.0f || + variant->lang_quality == 0.0f || + variant->source_quality == 0.0f || + variant->charset_quality == 0.0f || + variant->mime_type_quality == 0.0f) { + return 0; /* don't consider unacceptables */ + } + + q = variant->mime_type_quality * variant->source_quality; + if (q == 0.0 || q < bestq) { + return 0; + } + if (q > bestq || !best) { + *p_bestq = q; + return 1; + } + + /* language */ + if (variant->lang_quality < best->lang_quality) { + return 0; + } + if (variant->lang_quality > best->lang_quality) { + *p_bestq = q; + return 1; + } + + /* 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 && + (best->lang_index == -1 || variant->lang_index < best->lang_index)) { + *p_bestq = q; + return 1; + } + + /* content-type level (sometimes used with text/html, though we + * support it on other types too) + */ + levcmp = level_cmp(variant, best); + if (levcmp == -1) { + return 0; + } + if (levcmp == 1) { + *p_bestq = q; + return 1; + } + + /* charset */ + if (variant->charset_quality < best->charset_quality) { + return 0; + } + /* 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; + } + + /* Prefer the highest value for encoding_quality. + */ + if (variant->encoding_quality < best->encoding_quality) { + return 0; + } + if (variant->encoding_quality > best->encoding_quality) { + *p_bestq = q; + return 1; + } + + /* content length if all else equal */ + if (find_content_length(neg, variant) >= find_content_length(neg, best)) { + return 0; + } + + /* ok, to get here means every thing turned out equal, except + * we have a shorter content length, so use this variant + */ + *p_bestq = q; + return 1; +} + +/* figure out, whether a variant is in a specific language + * it returns also false, if the variant has no language. + */ +static int variant_has_language(var_rec *variant, const char *lang) +{ + int j, max; + + /* fast exit */ + if ( !lang + || !variant->content_languages + || !(max = variant->content_languages->nelts)) { + return 0; + } + + for (j = 0; j < max; ++j) { + if (!strcmp(lang, + ((char **) (variant->content_languages->elts))[j])) { + return 1; + } + } + + return 0; +} + +/* check for environment variables 'no-gzip' and + * 'gzip-only-text/html' to get a behaviour similiar + * to mod_deflate + */ +static int discard_variant_by_env(var_rec *variant, int discard) +{ + if ( is_identity_encoding(variant->content_encoding) + || !strcmp(variant->content_encoding, "identity")) { + return 0; + } + + return ( (discard == DISCARD_ALL_ENCODINGS) + || (discard == DISCARD_ALL_BUT_HTML + && (!variant->mime_type + || strncmp(variant->mime_type, "text/html", 9)))); +} + +static int best_match(negotiation_state *neg, var_rec **pbest) +{ + int j; + var_rec *best; + float bestq = 0.0f; + enum algorithm_results algorithm_result; + int may_discard = 0; + + var_rec *avail_recs = (var_rec *) neg->avail_vars->elts; + + /* fetch request dependent variables + * prefer-language: prefer a certain language. + */ + const char *preferred_language = apr_table_get(neg->r->subprocess_env, + "prefer-language"); + + /* no-gzip: do not send encoded documents */ + if (apr_table_get(neg->r->subprocess_env, "no-gzip")) { + may_discard = DISCARD_ALL_ENCODINGS; + } + + /* gzip-only-text/html: send encoded documents only + * if they are text/html. (no-gzip has a higher priority). + */ + else { + const char *env_value = apr_table_get(neg->r->subprocess_env, + "gzip-only-text/html"); + + if (env_value && !strcmp(env_value, "1")) { + may_discard = DISCARD_ALL_BUT_HTML; + } + } + + set_default_lang_quality(neg); + + /* + * Find the 'best' variant + * We run the loop possibly twice: if "prefer-language" + * environment variable is set but we did not find an appropriate + * best variant. In that case forget the preferred language and + * negotiate over all variants. + */ + + do { + best = NULL; + + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + + /* if this variant is encoded somehow and there are special + * variables set, we do not negotiate it. see above. + */ + if ( may_discard + && discard_variant_by_env(variant, may_discard)) { + continue; + } + + /* if a language is preferred, but the current variant + * is not in that language, then drop it for now + */ + if ( preferred_language + && !variant_has_language(variant, preferred_language)) { + continue; + } + + /* Find all the relevant 'quality' values from the + * Accept... headers, and store in the variant. This also + * prepares for sending an Alternates header etc so we need to + * do it even if we do not actually plan to find a best + * variant. + */ + set_accept_quality(neg, variant); + /* accept the preferred language, even when it's not listed within + * the Accept-Language header + */ + if (preferred_language) { + variant->lang_quality = 1.0f; + variant->definite = 1; + } + else { + set_language_quality(neg, variant); + } + set_encoding_quality(neg, variant); + set_charset_quality(neg, variant); + + /* Only do variant selection if we may actually choose a + * variant for the client + */ + if (neg->may_choose) { + + /* Now find out if this variant is better than the current + * best, either using the RVSA/1.0 algorithm, or Apache's + * internal server-driven algorithm. Presumably other + * server-driven algorithms are possible, and could be + * implemented here. + */ + + if (neg->use_rvsa) { + if (is_variant_better_rvsa(neg, variant, best, &bestq)) { + best = variant; + } + } + else { + if (is_variant_better(neg, variant, best, &bestq)) { + best = variant; + } + } + } + } + + /* We now either have a best variant, or no best variant */ + + if (neg->use_rvsa) { + /* calculate result for RVSA/1.0 algorithm: + * only a choice response if the best variant has q>0 + * and is definite + */ + algorithm_result = (best && best->definite) && (bestq > 0) ? + alg_choice : alg_list; + } + else { + /* calculate result for Apache negotiation algorithm */ + algorithm_result = bestq > 0 ? alg_choice : alg_list; + } + + /* run the loop again, if the "prefer-language" got no clear result */ + if (preferred_language && (!best || algorithm_result != alg_choice)) { + preferred_language = NULL; + continue; + } + + break; + } while (1); + + /* Returning a choice response with a non-neighboring variant is a + * protocol security error in TCN (see rfc2295). We do *not* + * verify here that the variant and URI are neighbors, even though + * we may return alg_choice. We depend on the environment (the + * caller) to only declare the resource transparently negotiable if + * all variants are neighbors. + */ + *pbest = best; + return algorithm_result; +} + +/* Sets response headers for a negotiated response. + * neg->is_transparent determines whether a transparently negotiated + * response or a plain `server driven negotiation' response is + * created. Applicable headers are Alternates, Vary, and TCN. + * + * The Vary header we create is sometimes longer than is required for + * the correct caching of negotiated results by HTTP/1.1 caches. For + * example if we have 3 variants x.html, x.ps.en and x.ps.nl, and if + * the Accept: header assigns a 0 quality to .ps, then the results of + * the two server-side negotiation algorithms we currently implement + * will never depend on Accept-Language so we could return `Vary: + * negotiate, accept' instead of the longer 'Vary: negotiate, accept, + * accept-language' which the code below will return. A routine for + * computing the exact minimal Vary header would be a huge pain to code + * and maintain though, especially because we need to take all possible + * twiddles in the server-side negotiation algorithms into account. + */ +static void set_neg_headers(request_rec *r, negotiation_state *neg, + int alg_result) +{ + apr_table_t *hdrs; + var_rec *avail_recs = (var_rec *) neg->avail_vars->elts; + const char *sample_type = NULL; + const char *sample_language = NULL; + const char *sample_encoding = NULL; + const char *sample_charset = NULL; + char *lang; + char *qstr; + apr_off_t len; + apr_array_header_t *arr; + int max_vlist_array = (neg->avail_vars->nelts * 21); + int first_variant = 1; + int vary_by_type = 0; + int vary_by_language = 0; + int vary_by_charset = 0; + int vary_by_encoding = 0; + int j; + + /* In order to avoid O(n^2) memory copies in building Alternates, + * we preallocate a apr_table_t with the maximum substrings possible, + * fill it with the variant list, and then concatenate the entire array. + * Note that if you change the number of substrings pushed, you also + * need to change the calculation of max_vlist_array above. + */ + if (neg->send_alternates && neg->avail_vars->nelts) + arr = apr_array_make(r->pool, max_vlist_array, sizeof(char *)); + else + arr = NULL; + + /* Put headers into err_headers_out, since send_http_header() + * outputs both headers_out and err_headers_out. + */ + hdrs = r->err_headers_out; + + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + + if (variant->content_languages && variant->content_languages->nelts) { + lang = apr_array_pstrcat(r->pool, variant->content_languages, ','); + } + else { + lang = NULL; + } + + /* Calculate Vary by looking for any difference between variants */ + + if (first_variant) { + sample_type = variant->mime_type; + sample_charset = variant->content_charset; + sample_language = lang; + sample_encoding = variant->content_encoding; + } + else { + if (!vary_by_type && + strcmp(sample_type ? sample_type : "", + variant->mime_type ? variant->mime_type : "")) { + vary_by_type = 1; + } + if (!vary_by_charset && + strcmp(sample_charset ? sample_charset : "", + variant->content_charset ? + variant->content_charset : "")) { + vary_by_charset = 1; + } + if (!vary_by_language && + strcmp(sample_language ? sample_language : "", + lang ? lang : "")) { + vary_by_language = 1; + } + if (!vary_by_encoding && + strcmp(sample_encoding ? sample_encoding : "", + variant->content_encoding ? + variant->content_encoding : "")) { + vary_by_encoding = 1; + } + } + first_variant = 0; + + if (!neg->send_alternates) + continue; + + /* Generate the string components for this Alternates entry */ + + *((const char **) apr_array_push(arr)) = "{\""; + *((const char **) apr_array_push(arr)) = variant->file_name; + *((const char **) apr_array_push(arr)) = "\" "; + + qstr = (char *) apr_palloc(r->pool, 6); + apr_snprintf(qstr, 6, "%1.3f", variant->source_quality); + + /* Strip trailing zeros (saves those valuable network bytes) */ + if (qstr[4] == '0') { + qstr[4] = '\0'; + if (qstr[3] == '0') { + qstr[3] = '\0'; + if (qstr[2] == '0') { + qstr[1] = '\0'; + } + } + } + *((const char **) apr_array_push(arr)) = qstr; + + if (variant->mime_type && *variant->mime_type) { + *((const char **) apr_array_push(arr)) = " {type "; + *((const char **) apr_array_push(arr)) = variant->mime_type; + *((const char **) apr_array_push(arr)) = "}"; + } + if (variant->content_charset && *variant->content_charset) { + *((const char **) apr_array_push(arr)) = " {charset "; + *((const char **) apr_array_push(arr)) = variant->content_charset; + *((const char **) apr_array_push(arr)) = "}"; + } + if (lang) { + *((const char **) apr_array_push(arr)) = " {language "; + *((const char **) apr_array_push(arr)) = lang; + *((const char **) apr_array_push(arr)) = "}"; + } + if (variant->content_encoding && *variant->content_encoding) { + /* Strictly speaking, this is non-standard, but so is TCN */ + + *((const char **) apr_array_push(arr)) = " {encoding "; + *((const char **) apr_array_push(arr)) = variant->content_encoding; + *((const char **) apr_array_push(arr)) = "}"; + } + + /* Note that the Alternates specification (in rfc2295) does + * not require that we include {length x}, so we could omit it + * if determining the length is too expensive. We currently + * always include it though. + * + * If the variant is a CGI script, find_content_length would + * return the length of the script, not the output it + * produces, so we check for the presence of a handler and if + * there is one we don't add a length. + * + * XXX: TODO: This check does not detect a CGI script if we + * get the variant from a type map. This needs to be fixed + * (without breaking things if the type map specifies a + * content-length, which currently leads to the correct result). + */ + if (!(variant->sub_req && variant->sub_req->handler) + && (len = find_content_length(neg, variant)) >= 0) { + + *((const char **) apr_array_push(arr)) = " {length "; + *((const char **) apr_array_push(arr)) = apr_off_t_toa(r->pool, + len); + *((const char **) apr_array_push(arr)) = "}"; + } + + *((const char **) apr_array_push(arr)) = "}"; + *((const char **) apr_array_push(arr)) = ", "; /* trimmed below */ + } + + if (neg->send_alternates && neg->avail_vars->nelts) { + arr->nelts--; /* remove last comma */ + apr_table_mergen(hdrs, "Alternates", + apr_array_pstrcat(r->pool, arr, '\0')); + } + + if (neg->is_transparent || vary_by_type || vary_by_language || + vary_by_language || vary_by_charset || vary_by_encoding) { + + apr_table_mergen(hdrs, "Vary", 2 + apr_pstrcat(r->pool, + neg->is_transparent ? ", negotiate" : "", + vary_by_type ? ", accept" : "", + vary_by_language ? ", accept-language" : "", + vary_by_charset ? ", accept-charset" : "", + vary_by_encoding ? ", accept-encoding" : "", NULL)); + } + + if (neg->is_transparent) { /* Create TCN response header */ + apr_table_setn(hdrs, "TCN", + alg_result == alg_list ? "list" : "choice"); + } +} + +/********************************************************************** + * + * Return an HTML list of variants. This is output as part of the + * choice response or 406 status body. + */ + +static char *make_variant_list(request_rec *r, negotiation_state *neg) +{ + apr_array_header_t *arr; + int i; + int max_vlist_array = (neg->avail_vars->nelts * 15) + 2; + + /* In order to avoid O(n^2) memory copies in building the list, + * we preallocate a apr_table_t with the maximum substrings possible, + * fill it with the variant list, and then concatenate the entire array. + */ + arr = apr_array_make(r->pool, max_vlist_array, sizeof(char *)); + + *((const char **) apr_array_push(arr)) = "Available variants:\n
      \n"; + + for (i = 0; i < neg->avail_vars->nelts; ++i) { + var_rec *variant = &((var_rec *) neg->avail_vars->elts)[i]; + const char *filename = variant->file_name ? variant->file_name : ""; + apr_array_header_t *languages = variant->content_languages; + const char *description = variant->description + ? variant->description + : ""; + + /* The format isn't very neat, and it would be nice to make + * the tags human readable (eg replace 'language en' with 'English'). + * Note that if you change the number of substrings pushed, you also + * need to change the calculation of max_vlist_array above. + */ + *((const char **) apr_array_push(arr)) = "
    • "; + *((const char **) apr_array_push(arr)) = filename; + *((const char **) apr_array_push(arr)) = " "; + *((const char **) apr_array_push(arr)) = description; + + if (variant->mime_type && *variant->mime_type) { + *((const char **) apr_array_push(arr)) = ", type "; + *((const char **) apr_array_push(arr)) = variant->mime_type; + } + if (languages && languages->nelts) { + *((const char **) apr_array_push(arr)) = ", language "; + *((const char **) apr_array_push(arr)) = apr_array_pstrcat(r->pool, + languages, ','); + } + if (variant->content_charset && *variant->content_charset) { + *((const char **) apr_array_push(arr)) = ", charset "; + *((const char **) apr_array_push(arr)) = variant->content_charset; + } + if (variant->content_encoding) { + *((const char **) apr_array_push(arr)) = ", encoding "; + *((const char **) apr_array_push(arr)) = variant->content_encoding; + } + *((const char **) apr_array_push(arr)) = "
    • \n"; + } + *((const char **) apr_array_push(arr)) = "
    \n"; + + return apr_array_pstrcat(r->pool, arr, '\0'); +} + +static void store_variant_list(request_rec *r, negotiation_state *neg) +{ + if (r->main == NULL) { + apr_table_setn(r->notes, "variant-list", make_variant_list(r, neg)); + } + else { + apr_table_setn(r->main->notes, "variant-list", + make_variant_list(r->main, neg)); + } +} + +/* Called if we got a "Choice" response from the variant selection algorithm. + * It checks the result of the chosen variant to see if it + * is itself negotiated (if so, return error HTTP_VARIANT_ALSO_VARIES). + * Otherwise, add the appropriate headers to the current response. + */ + +static int setup_choice_response(request_rec *r, negotiation_state *neg, + var_rec *variant) +{ + request_rec *sub_req; + const char *sub_vary; + + if (!variant->sub_req) { + int status; + + sub_req = ap_sub_req_lookup_file(variant->file_name, r, NULL); + status = sub_req->status; + + if (status != HTTP_OK && + !apr_table_get(sub_req->err_headers_out, "TCN")) { + ap_destroy_sub_req(sub_req); + return status; + } + variant->sub_req = sub_req; + } + else { + sub_req = variant->sub_req; + } + + /* The variant selection algorithm told us to return a "Choice" + * response. This is the normal variant response, with + * some extra headers. First, ensure that the chosen + * variant did or will not itself engage in transparent negotiation. + * If not, set the appropriate headers, and fall through to + * the normal variant handling + */ + + /* This catches the error that a transparent type map selects a + * transparent multiviews resource as the best variant. + * + * XXX: We do not signal an error if a transparent type map + * selects a _non_transparent multiviews resource as the best + * variant, because we can generate a legal negotiation response + * in this case. In this case, the vlist_validator of the + * nontransparent subrequest will be lost however. This could + * lead to cases in which a change in the set of variants or the + * negotiation algorithm of the nontransparent resource is never + * propagated up to a HTTP/1.1 cache which interprets Vary. To be + * completely on the safe side we should return HTTP_VARIANT_ALSO_VARIES + * for this type of recursive negotiation too. + */ + if (neg->is_transparent && + apr_table_get(sub_req->err_headers_out, "TCN")) { + return HTTP_VARIANT_ALSO_VARIES; + } + + /* This catches the error that a transparent type map recursively + * selects, as the best variant, another type map which itself + * causes transparent negotiation to be done. + * + * XXX: Actually, we catch this error by catching all cases of + * type map recursion. There are some borderline recursive type + * map arrangements which would not produce transparent + * negotiation protocol errors or lack of cache propagation + * problems, but such arrangements are very hard to detect at this + * point in the control flow, so we do not bother to single them + * out. + * + * Recursive type maps imply a recursive arrangement of negotiated + * resources which is visible to outside clients, and this is not + * supported by the transparent negotiation caching protocols, so + * if we are to have generic support for recursive type maps, we + * have to create some configuration setting which makes all type + * maps non-transparent when recursion is enabled. Also, if we + * want recursive type map support which ensures propagation of + * type map changes into HTTP/1.1 caches that handle Vary, we + * would have to extend the current mechanism for generating + * variant list validators. + */ + if (sub_req->handler && strcmp(sub_req->handler, "type-map") == 0) { + return HTTP_VARIANT_ALSO_VARIES; + } + + /* This adds an appropriate Variant-Vary header if the subrequest + * is a multiviews resource. + * + * XXX: TODO: Note that this does _not_ handle any Vary header + * returned by a CGI if sub_req is a CGI script, because we don't + * see that Vary header yet at this point in the control flow. + * This won't cause any cache consistency problems _unless_ the + * CGI script also returns a Cache-Control header marking the + * response as cachable. This needs to be fixed, also there are + * problems if a CGI returns an Etag header which also need to be + * fixed. + */ + if ((sub_vary = apr_table_get(sub_req->err_headers_out, "Vary")) != NULL) { + apr_table_setn(r->err_headers_out, "Variant-Vary", sub_vary); + + /* Move the subreq Vary header into the main request to + * prevent having two Vary headers in the response, which + * would be legal but strange. + */ + apr_table_setn(r->err_headers_out, "Vary", sub_vary); + apr_table_unset(sub_req->err_headers_out, "Vary"); + } + + apr_table_setn(r->err_headers_out, "Content-Location", + apr_pstrdup(r->pool, variant->file_name)); + + set_neg_headers(r, neg, alg_choice); /* add Alternates and Vary */ + + /* Still to do by caller: add Expires */ + + return 0; +} + +/**************************************************************** + * + * Executive... + */ + +static int do_negotiation(request_rec *r, negotiation_state *neg, + var_rec **bestp, int prefer_scripts) +{ + var_rec *avail_recs = (var_rec *) neg->avail_vars->elts; + int alg_result; /* result of variant selection algorithm */ + int res; + int j; + + /* Decide if resource is transparently negotiable */ + + /* GET or HEAD? (HEAD has same method number as GET) */ + if (r->method_number == M_GET) { + + /* maybe this should be configurable, see also the comment + * about recursive type maps in setup_choice_response() + */ + neg->is_transparent = 1; + + /* We can't be transparent if we are a map file in the middle + * of the request URI. + */ + if (r->path_info && *r->path_info) + neg->is_transparent = 0; + + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + + /* We can't be transparent, because of internal + * assumptions in best_match(), if there is a + * non-neighboring variant. We can have a non-neighboring + * variant when processing a type map. + */ + if (ap_strchr_c(variant->file_name, '/')) + neg->is_transparent = 0; + + /* We can't be transparent, because of the behavior + * of variant typemap bodies. + */ + if (variant->body) { + neg->is_transparent = 0; + } + } + } + + if (neg->is_transparent) { + parse_negotiate_header(r, neg); + } + else { /* configure negotiation on non-transparent resource */ + neg->may_choose = 1; + } + + maybe_add_default_accepts(neg, prefer_scripts); + + alg_result = best_match(neg, bestp); + + /* alg_result is one of + * alg_choice: a best variant is chosen + * alg_list: no best variant is chosen + */ + + if (alg_result == alg_list) { + /* send a list response or HTTP_NOT_ACCEPTABLE error response */ + + neg->send_alternates = 1; /* always include Alternates header */ + set_neg_headers(r, neg, alg_result); + store_variant_list(r, neg); + + if (neg->is_transparent && neg->ua_supports_trans) { + /* XXX todo: expires? cachability? */ + + /* Some HTTP/1.0 clients are known to choke when they get + * a 300 (multiple choices) response without a Location + * header. However the 300 code response we are are about + * to generate will only reach 1.0 clients which support + * transparent negotiation, and they should be OK. The + * response should never reach older 1.0 clients, even if + * we have CacheNegotiatedDocs enabled, because no 1.0 + * proxy cache (we know of) will cache and return 300 + * responses (they certainly won't if they conform to the + * HTTP/1.0 specification). + */ + return HTTP_MULTIPLE_CHOICES; + } + + if (!*bestp) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "no acceptable variant: %s", r->filename); + return HTTP_NOT_ACCEPTABLE; + } + } + + /* Variant selection chose a variant */ + + /* XXX todo: merge the two cases in the if statement below */ + if (neg->is_transparent) { + + if ((res = setup_choice_response(r, neg, *bestp)) != 0) { + return res; /* return if error */ + } + } + else { + set_neg_headers(r, neg, alg_result); + } + + /* Make sure caching works - Vary should handle HTTP/1.1, but for + * HTTP/1.0, we can't allow caching at all. + */ + + /* XXX: Note that we only set r->no_cache to 1, which causes + * Expires: to be added, when responding to a HTTP/1.0 + * client. If we return the response to a 1.1 client, we do not + * add Expires , because doing so would degrade 1.1 cache + * performance by preventing re-use of the response without prior + * revalidation. On the other hand, if the 1.1 client is a proxy + * which was itself contacted by a 1.0 client, or a proxy cache + * which can be contacted later by 1.0 clients, then we currently + * rely on this 1.1 proxy to add the Expires: when it + * forwards the response. + * + * XXX: TODO: Find out if the 1.1 spec requires proxies and + * tunnels to add Expires: when forwarding the response to + * 1.0 clients. I (kh) recall it is rather vague on this point. + * Testing actual 1.1 proxy implementations would also be nice. If + * Expires: is not added by proxies then we need to always + * include Expires: ourselves to ensure correct caching, but + * this would degrade HTTP/1.1 cache efficiency unless we also add + * Cache-Control: max-age=N, which we currently don't. + * + * Roy: No, we are not going to screw over HTTP future just to + * ensure that people who can't be bothered to upgrade their + * clients will always receive perfect server-side negotiation. + * Hell, those clients are sending bogus accept headers anyway. + * + * Manual setting of cache-control/expires always overrides this + * automated kluge, on purpose. + */ + + if ((!do_cache_negotiated_docs(r->server) + && (r->proto_num < HTTP_VERSION(1,1))) + && neg->count_multiviews_variants != 1) { + r->no_cache = 1; + } + + return OK; +} + +static int handle_map_file(request_rec *r) +{ + negotiation_state *neg; + apr_file_t *map; + var_rec *best; + int res; + char *udir; + + if(strcmp(r->handler,MAP_FILE_MAGIC_TYPE) && strcmp(r->handler,"type-map")) + return DECLINED; + + neg = parse_accept_headers(r); + if ((res = read_type_map(&map, neg, r))) { + return res; + } + + res = do_negotiation(r, neg, &best, 0); + if (res != 0) return res; + + if (best->body) + { + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *e; + + ap_allow_standard_methods(r, REPLACE_ALLOW, M_GET, M_OPTIONS, + M_POST, -1); + /* XXX: ? + * if (r->method_number == M_OPTIONS) { + * return ap_send_http_options(r); + *} + */ + if (r->method_number != M_GET && r->method_number != M_POST) { + return HTTP_METHOD_NOT_ALLOWED; + } + + /* ### These may be implemented by adding some 'extra' info + * of the file offset onto the etag + * ap_update_mtime(r, r->finfo.mtime); + * ap_set_last_modified(r); + * ap_set_etag(r); + */ + apr_table_setn(r->headers_out, "Accept-Ranges", "bytes"); + ap_set_content_length(r, best->bytes); + + /* set MIME type and charset as negotiated */ + if (best->mime_type && *best->mime_type) { + if (best->content_charset && *best->content_charset) { + ap_set_content_type(r, apr_pstrcat(r->pool, + best->mime_type, + "; charset=", + best->content_charset, + NULL)); + } + else { + ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type)); + } + } + + /* set Content-language(s) as negotiated */ + if (best->content_languages && best->content_languages->nelts) { + r->content_languages = apr_array_copy(r->pool, + best->content_languages); + } + + /* set Content-Encoding as negotiated */ + if (best->content_encoding && *best->content_encoding) { + r->content_encoding = apr_pstrdup(r->pool, + best->content_encoding); + } + + if ((res = ap_meets_conditions(r)) != OK) { + return res; + } + + if ((res = ap_discard_request_body(r)) != OK) { + return res; + } + bb = apr_brigade_create(r->pool, c->bucket_alloc); + e = apr_bucket_file_create(map, best->body, + (apr_size_t)best->bytes, r->pool, + c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + e = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + + return ap_pass_brigade(r->output_filters, bb); + } + + if (r->path_info && *r->path_info) { + /* remove any path_info from the end of the uri before trying + * to change the filename. r->path_info from the original + * request is passed along on the redirect. + */ + r->uri[ap_find_path_info(r->uri, r->path_info)] = '\0'; + } + udir = ap_make_dirstr_parent(r->pool, r->uri); + udir = ap_escape_uri(r->pool, udir); + ap_internal_redirect(apr_pstrcat(r->pool, udir, best->file_name, + r->path_info, NULL), r); + return OK; +} + +static int handle_multi(request_rec *r) +{ + negotiation_state *neg; + var_rec *best, *avail_recs; + request_rec *sub_req; + int res; + int j; + + if (r->finfo.filetype != APR_NOFILE + || !(ap_allow_options(r) & OPT_MULTI)) { + return DECLINED; + } + + neg = parse_accept_headers(r); + + if ((res = read_types_multi(neg))) { + return_from_multi: + /* free all allocated memory from subrequests */ + avail_recs = (var_rec *) neg->avail_vars->elts; + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + if (variant->sub_req) { + ap_destroy_sub_req(variant->sub_req); + } + } + return res; + } + if (neg->avail_vars->nelts == 0) { + return DECLINED; + } + + res = do_negotiation(r, neg, &best, + (r->method_number != M_GET) || r->args || + (r->path_info && *r->path_info)); + if (res != 0) + goto return_from_multi; + + if (!(sub_req = best->sub_req)) { + /* We got this out of a map file, so we don't actually have + * a sub_req structure yet. Get one now. + */ + + sub_req = ap_sub_req_lookup_file(best->file_name, r, NULL); + if (sub_req->status != HTTP_OK) { + res = sub_req->status; + ap_destroy_sub_req(sub_req); + goto return_from_multi; + } + } + + /* now do a "fast redirect" ... promotes the sub_req into the main req */ + ap_internal_fast_redirect(sub_req, r); + + /* give no advise for time on this subrequest. Perhaps we + * should tally the last mtime amoung all variants, and date + * the most recent, but that could confuse the proxies. + */ + r->mtime = 0; + + /* clean up all but our favorite variant, since that sub_req + * is now merged into the main request! + */ + avail_recs = (var_rec *) neg->avail_vars->elts; + for (j = 0; j < neg->avail_vars->nelts; ++j) { + var_rec *variant = &avail_recs[j]; + if (variant != best && variant->sub_req) { + ap_destroy_sub_req(variant->sub_req); + } + } + return OK; +} + +/********************************************************************** + * There is a problem with content-encoding, as some clients send and + * expect an x- token (e.g. x-gzip) while others expect the plain token + * (i.e. gzip). To try and deal with this as best as possible we do + * the following: if the client sent an Accept-Encoding header and it + * contains a plain token corresponding to the content encoding of the + * response, then set content encoding using the plain token. Else if + * the A-E header contains the x- token use the x- token in the C-E + * header. Else don't do anything. + * + * Note that if no A-E header was sent, or it does not contain a token + * compatible with the final content encoding, then the token in the + * C-E header will be whatever was specified in the AddEncoding + * directive. + */ +static int fix_encoding(request_rec *r) +{ + const char *enc = r->content_encoding; + char *x_enc = NULL; + apr_array_header_t *accept_encodings; + accept_rec *accept_recs; + int i; + + if (!enc || !*enc) { + return DECLINED; + } + + if (enc[0] == 'x' && enc[1] == '-') { + enc += 2; + } + + if ((accept_encodings = do_header_line(r->pool, + apr_table_get(r->headers_in, "Accept-Encoding"))) == NULL) { + return DECLINED; + } + + accept_recs = (accept_rec *) accept_encodings->elts; + + for (i = 0; i < accept_encodings->nelts; ++i) { + char *name = accept_recs[i].name; + + if (!strcmp(name, enc)) { + r->content_encoding = name; + return OK; + } + + if (name[0] == 'x' && name[1] == '-' && !strcmp(name+2, enc)) { + x_enc = name; + } + } + + if (x_enc) { + r->content_encoding = x_enc; + return OK; + } + + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(fix_encoding,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_type_checker(handle_multi,NULL,NULL,APR_HOOK_FIRST); + ap_hook_handler(handle_map_file,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA negotiation_module = +{ + STANDARD20_MODULE_STUFF, + create_neg_dir_config, /* dir config creator */ + merge_neg_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + negotiation_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_negotiation.dsp b/trunk/modules/mappers/mod_negotiation.dsp new file mode 100644 index 0000000000..1b8101039b --- /dev/null +++ b/trunk/modules/mappers/mod_negotiation.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_negotiation" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_negotiation - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_negotiation.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_negotiation.mak" CFG="mod_negotiation - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_negotiation - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_negotiation - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_negotiation - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_negotiation_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_negotiation - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_negotiation_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_negotiation.so" /base:@..\..\os\win32\BaseAddr.ref,mod_negotiation.so + +!ENDIF + +# Begin Target + +# Name "mod_negotiation - Win32 Release" +# Name "mod_negotiation - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_negotiation.c +# End Source File +# Begin Source File + +SOURCE=.\mod_negotiation.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_negotiation - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_negotiation.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_negotiation.so "negotiation_module for Apache" ../../include/ap_release.h > .\mod_negotiation.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_negotiation - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_negotiation.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_negotiation.so "negotiation_module for Apache" ../../include/ap_release.h > .\mod_negotiation.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_negotiation.exp b/trunk/modules/mappers/mod_negotiation.exp new file mode 100644 index 0000000000..a7c18da1de --- /dev/null +++ b/trunk/modules/mappers/mod_negotiation.exp @@ -0,0 +1 @@ +negotiation_module diff --git a/trunk/modules/mappers/mod_rewrite.c b/trunk/modules/mappers/mod_rewrite.c new file mode 100644 index 0000000000..0baad43800 --- /dev/null +++ b/trunk/modules/mappers/mod_rewrite.c @@ -0,0 +1,4826 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ _ + * _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___ + * | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \ + * | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/ + * |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___| + * |_____| + * + * URL Rewriting Module + * + * This module uses a rule-based rewriting engine (based on a + * regular-expression parser) to rewrite requested URLs on the fly. + * + * It supports an unlimited number of additional rule conditions (which can + * operate on a lot of variables, even on HTTP headers) for granular + * matching and even external database lookups (either via plain text + * tables, DBM hash files or even external processes) for advanced URL + * substitution. + * + * It operates on the full URLs (including the PATH_INFO part) both in + * per-server context (httpd.conf) and per-dir context (.htaccess) and even + * can generate QUERY_STRING parts on result. The rewriting result finally + * can lead to internal subprocessing, external request redirection or even + * to internal proxy throughput. + * + * This module was originally written in April 1996 and + * gifted exclusively to the The Apache Software Foundation in July 1997 by + * + * Ralf S. Engelschall + * rse engelschall.com + * www.engelschall.com + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "apr_user.h" +#include "apr_lib.h" +#include "apr_signal.h" +#include "apr_global_mutex.h" +#include "apr_dbm.h" + +#if APR_HAS_THREADS +#include "apr_thread_mutex.h" +#endif + +#define APR_WANT_MEMFUNC +#define APR_WANT_STRFUNC +#define APR_WANT_IOVEC +#include "apr_want.h" + +/* XXX: Do we really need these headers? */ +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_TYPES_H +#include +#endif +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_CTYPE_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_vhost.h" + +#include "mod_ssl.h" + +#include "mod_rewrite.h" + +#ifdef AP_NEED_SET_MUTEX_PERMS +#include "unixd.h" +#endif + +/* + * in order to improve performance on running production systems, you + * may strip all rewritelog code entirely from mod_rewrite by using the + * -DREWRITELOG_DISABLED compiler option. + * + * DO NOT USE THIS OPTION FOR PUBLIC BINARY RELEASES. Otherwise YOU are + * responsible for answering all the mod_rewrite questions out there. + */ +#ifndef REWRITELOG_DISABLED + +#define rewritelog(x) do_rewritelog x +#define REWRITELOG_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) +#define REWRITELOG_FLAGS ( APR_WRITE | APR_APPEND | APR_CREATE ) + +#else /* !REWRITELOG_DISABLED */ + +#define rewritelog(x) + +#endif /* REWRITELOG_DISABLED */ + +/* remembered mime-type for [T=...] */ +#define REWRITE_FORCED_MIMETYPE_NOTEVAR "rewrite-forced-mimetype" +#define REWRITE_FORCED_HANDLER_NOTEVAR "rewrite-forced-handler" + +#define ENVVAR_SCRIPT_URL "SCRIPT_URL" +#define REDIRECT_ENVVAR_SCRIPT_URL "REDIRECT_" ENVVAR_SCRIPT_URL +#define ENVVAR_SCRIPT_URI "SCRIPT_URI" + +#define CONDFLAG_NONE 1<<0 +#define CONDFLAG_NOCASE 1<<1 +#define CONDFLAG_NOTMATCH 1<<2 +#define CONDFLAG_ORNEXT 1<<3 + +#define RULEFLAG_NONE 1<<0 +#define RULEFLAG_FORCEREDIRECT 1<<1 +#define RULEFLAG_LASTRULE 1<<2 +#define RULEFLAG_NEWROUND 1<<3 +#define RULEFLAG_CHAIN 1<<4 +#define RULEFLAG_IGNOREONSUBREQ 1<<5 +#define RULEFLAG_NOTMATCH 1<<6 +#define RULEFLAG_PROXY 1<<7 +#define RULEFLAG_PASSTHROUGH 1<<8 +#define RULEFLAG_QSAPPEND 1<<9 +#define RULEFLAG_NOCASE 1<<10 +#define RULEFLAG_NOESCAPE 1<<11 +#define RULEFLAG_NOSUB 1<<12 +#define RULEFLAG_STATUS 1<<13 + +/* return code of the rewrite rule + * the result may be escaped - or not + */ +#define ACTION_NORMAL 1<<0 +#define ACTION_NOESCAPE 1<<1 +#define ACTION_STATUS 1<<2 + + +#define MAPTYPE_TXT 1<<0 +#define MAPTYPE_DBM 1<<1 +#define MAPTYPE_PRG 1<<2 +#define MAPTYPE_INT 1<<3 +#define MAPTYPE_RND 1<<4 + +#define ENGINE_DISABLED 1<<0 +#define ENGINE_ENABLED 1<<1 + +#define OPTION_NONE 1<<0 +#define OPTION_INHERIT 1<<1 + +#ifndef RAND_MAX +#define RAND_MAX 32767 +#endif + +/* max cookie size in rfc 2109 */ +/* XXX: not used at all. We should do a check somewhere and/or cut the cookie */ +#define MAX_COOKIE_LEN 4096 + +/* max line length (incl.\n) in text rewrite maps */ +#ifndef REWRITE_MAX_TXT_MAP_LINE +#define REWRITE_MAX_TXT_MAP_LINE 1024 +#endif + +/* buffer length for prg rewrite maps */ +#ifndef REWRITE_PRG_MAP_BUF +#define REWRITE_PRG_MAP_BUF 1024 +#endif + +/* for better readbility */ +#define LEFT_CURLY '{' +#define RIGHT_CURLY '}' + +/* + * expansion result items on the stack to save some cycles + * + * (5 == about 2 variables like "foo%{var}bar%{var}baz") + */ +#define SMALL_EXPANSION 5 + +/* + * check that a subrequest won't cause infinite recursion + * + * either not in a subrequest, or in a subrequest + * and URIs aren't NULL and sub/main URIs differ + */ +#define subreq_ok(r) (!r->main || \ + (r->main->uri && r->uri && strcmp(r->main->uri, r->uri))) + + +/* + * +-------------------------------------------------------+ + * | | + * | Types and Structures + * | | + * +-------------------------------------------------------+ + */ + +typedef struct { + const char *datafile; /* filename for map data files */ + const char *dbmtype; /* dbm type for dbm map data files */ + const char *checkfile; /* filename to check for map existence */ + const char *cachename; /* for cached maps (txt/rnd/dbm) */ + int type; /* the type of the map */ + apr_file_t *fpin; /* in file pointer for program maps */ + apr_file_t *fpout; /* out file pointer for program maps */ + apr_file_t *fperr; /* err file pointer for program maps */ + char *(*func)(request_rec *, /* function pointer for internal maps */ + char *); + char **argv; /* argv of the external rewrite map */ +} rewritemap_entry; + +/* special pattern types for RewriteCond */ +typedef enum { + CONDPAT_REGEX = 0, + CONDPAT_FILE_EXISTS, + CONDPAT_FILE_SIZE, + CONDPAT_FILE_LINK, + CONDPAT_FILE_DIR, + CONDPAT_FILE_XBIT, + CONDPAT_LU_URL, + CONDPAT_LU_FILE, + CONDPAT_STR_GT, + CONDPAT_STR_LT, + CONDPAT_STR_EQ +} pattern_type; + +typedef struct { + char *input; /* Input string of RewriteCond */ + char *pattern; /* the RegExp pattern string */ + ap_regex_t *regexp; /* the precompiled regexp */ + int flags; /* Flags which control the match */ + pattern_type ptype; /* pattern type */ +} rewritecond_entry; + +/* single linked list for env vars and cookies */ +typedef struct data_item { + struct data_item *next; + char *data; +} data_item; + +typedef struct { + apr_array_header_t *rewriteconds;/* the corresponding RewriteCond entries */ + char *pattern; /* the RegExp pattern string */ + ap_regex_t *regexp; /* the RegExp pattern compilation */ + char *output; /* the Substitution string */ + int flags; /* Flags which control the substitution */ + char *forced_mimetype; /* forced MIME type of substitution */ + char *forced_handler; /* forced content handler of subst. */ + int forced_responsecode; /* forced HTTP response status */ + data_item *env; /* added environment variables */ + data_item *cookie; /* added cookies */ + int skip; /* number of next rules to skip */ +} rewriterule_entry; + +typedef struct { + int state; /* the RewriteEngine state */ + int options; /* the RewriteOption state */ +#ifndef REWRITELOG_DISABLED + const char *rewritelogfile; /* the RewriteLog filename */ + apr_file_t *rewritelogfp; /* the RewriteLog open filepointer */ + int rewriteloglevel; /* the RewriteLog level of verbosity */ +#endif + apr_hash_t *rewritemaps; /* the RewriteMap entries */ + apr_array_header_t *rewriteconds; /* the RewriteCond entries (temp.) */ + apr_array_header_t *rewriterules; /* the RewriteRule entries */ + server_rec *server; /* the corresponding server indicator */ +} rewrite_server_conf; + +typedef struct { + int state; /* the RewriteEngine state */ + int options; /* the RewriteOption state */ + apr_array_header_t *rewriteconds; /* the RewriteCond entries (temp.) */ + apr_array_header_t *rewriterules; /* the RewriteRule entries */ + char *directory; /* the directory where it applies */ + const char *baseurl; /* the base-URL where it applies */ +} rewrite_perdir_conf; + +/* the (per-child) cache structures. + */ +typedef struct cache { + apr_pool_t *pool; + apr_hash_t *maps; +#if APR_HAS_THREADS + apr_thread_mutex_t *lock; +#endif +} cache; + +/* cached maps contain an mtime for the whole map and live in a subpool + * of the cachep->pool. That makes it easy to forget them if necessary. + */ +typedef struct { + apr_time_t mtime; + apr_pool_t *pool; + apr_hash_t *entries; +} cachedmap; + +/* the regex structure for the + * substitution of backreferences + */ +typedef struct backrefinfo { + char *source; + int nsub; + ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; +} backrefinfo; + +/* single linked list used for + * variable expansion + */ +typedef struct result_list { + struct result_list *next; + apr_size_t len; + const char *string; +} result_list; + +/* context structure for variable lookup and expansion + */ +typedef struct { + request_rec *r; + const char *uri; + const char *vary_this; + const char *vary; + char *perdir; + backrefinfo briRR; + backrefinfo briRC; +} rewrite_ctx; + +/* + * +-------------------------------------------------------+ + * | | + * | static module data + * | | + * +-------------------------------------------------------+ + */ + +/* the global module structure */ +module AP_MODULE_DECLARE_DATA rewrite_module; + +/* rewritemap int: handler function registry */ +static apr_hash_t *mapfunc_hash; + +/* the cache */ +static cache *cachep; + +/* whether proxy module is available or not */ +static int proxy_available; + +/* whether random seed can be reaped */ +static int rewrite_rand_init_done = 0; + +/* Locks/Mutexes */ +static const char *lockname; +static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL; + +#ifndef REWRITELOG_DISABLED +static apr_global_mutex_t *rewrite_log_lock = NULL; +#endif + +/* Optional functions imported from mod_ssl when loaded: */ +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL; +static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL; + +/* + * +-------------------------------------------------------+ + * | | + * | rewriting logfile support + * | | + * +-------------------------------------------------------+ + */ + +#ifndef REWRITELOG_DISABLED +static char *current_logtime(request_rec *r) +{ + apr_time_exp_t t; + char tstr[80]; + apr_size_t len; + + apr_time_exp_lt(&t, apr_time_now()); + + apr_strftime(tstr, &len, sizeof(tstr), "[%d/%b/%Y:%H:%M:%S ", &t); + apr_snprintf(tstr+len, sizeof(tstr)-len, "%c%.2d%.2d]", + t.tm_gmtoff < 0 ? '-' : '+', + t.tm_gmtoff / (60*60), t.tm_gmtoff % (60*60)); + + return apr_pstrdup(r->pool, tstr); +} + +static int open_rewritelog(server_rec *s, apr_pool_t *p) +{ + rewrite_server_conf *conf; + const char *fname; + + conf = ap_get_module_config(s->module_config, &rewrite_module); + + /* - no logfile configured + * - logfilename empty + * - virtual log shared w/ main server + */ + if (!conf->rewritelogfile || !*conf->rewritelogfile || conf->rewritelogfp) { + return 1; + } + + if (*conf->rewritelogfile == '|') { + piped_log *pl; + + fname = ap_server_root_relative(p, conf->rewritelogfile+1); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + "mod_rewrite: Invalid RewriteLog " + "path %s", conf->rewritelogfile+1); + return 0; + } + + if ((pl = ap_open_piped_log(p, fname)) == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "mod_rewrite: could not open reliable pipe " + "to RewriteLog filter %s", fname); + return 0; + } + conf->rewritelogfp = ap_piped_log_write_fd(pl); + } + else { + apr_status_t rc; + + fname = ap_server_root_relative(p, conf->rewritelogfile); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + "mod_rewrite: Invalid RewriteLog " + "path %s", conf->rewritelogfile); + return 0; + } + + if ((rc = apr_file_open(&conf->rewritelogfp, fname, + REWRITELOG_FLAGS, REWRITELOG_MODE, p)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, + "mod_rewrite: could not open RewriteLog " + "file %s", fname); + return 0; + } + } + + return 1; +} + +static void do_rewritelog(request_rec *r, int level, char *perdir, + const char *fmt, ...) +{ + rewrite_server_conf *conf; + char *logline, *text; + const char *rhost, *rname; + apr_size_t nbytes; + int redir; + apr_status_t rv; + request_rec *req; + va_list ap; + + conf = ap_get_module_config(r->server->module_config, &rewrite_module); + + if (!conf->rewritelogfp || level > conf->rewriteloglevel) { + return; + } + + rhost = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NOLOOKUP, NULL); + rname = ap_get_remote_logname(r); + + for (redir=0, req=r; req->prev; req = req->prev) { + ++redir; + } + + va_start(ap, fmt); + text = apr_pvsprintf(r->pool, fmt, ap); + va_end(ap); + + logline = apr_psprintf(r->pool, "%s %s %s %s [%s/sid#%pp][rid#%pp/%s%s%s] " + "(%d) %s%s%s%s" APR_EOL_STR, + rhost ? rhost : "UNKNOWN-HOST", + rname ? rname : "-", + r->user ? (*r->user ? r->user : "\"\"") : "-", + current_logtime(r), + ap_get_server_name(r), + (void *)(r->server), + (void *)r, + r->main ? "subreq" : "initial", + redir ? "/redir#" : "", + redir ? apr_itoa(r->pool, redir) : "", + level, + perdir ? "[perdir " : "", + perdir ? perdir : "", + perdir ? "] ": "", + text); + + rv = apr_global_mutex_lock(rewrite_log_lock); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_global_mutex_lock(rewrite_log_lock) failed"); + /* XXX: Maybe this should be fatal? */ + } + + nbytes = strlen(logline); + apr_file_write(conf->rewritelogfp, logline, &nbytes); + + rv = apr_global_mutex_unlock(rewrite_log_lock); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_global_mutex_unlock(rewrite_log_lock) failed"); + /* XXX: Maybe this should be fatal? */ + } + + return; +} +#endif /* !REWRITELOG_DISABLED */ + + +/* + * +-------------------------------------------------------+ + * | | + * | URI and path functions + * | | + * +-------------------------------------------------------+ + */ + +/* return number of chars of the scheme (incl. '://') + * if the URI is absolute (includes a scheme etc.) + * otherwise 0. + * + * NOTE: If you add new schemes here, please have a + * look at escape_absolute_uri and splitout_queryargs. + * Not every scheme takes query strings and some schemes + * may be handled in a special way. + * + * XXX: we may consider a scheme registry, perhaps with + * appropriate escape callbacks to allow other modules + * to extend mod_rewrite at runtime. + */ +static unsigned is_absolute_uri(char *uri) +{ + /* fast exit */ + if (*uri == '/' || strlen(uri) <= 5) { + return 0; + } + + switch (*uri++) { + case 'a': + case 'A': + if (!strncasecmp(uri, "jp://", 5)) { /* ajp:// */ + return 6; + } + + case 'b': + case 'B': + if (!strncasecmp(uri, "alancer://", 10)) { /* balancer:// */ + return 11; + } + break; + + case 'f': + case 'F': + if (!strncasecmp(uri, "tp://", 5)) { /* ftp:// */ + return 6; + } + break; + + case 'g': + case 'G': + if (!strncasecmp(uri, "opher://", 8)) { /* gopher:// */ + return 9; + } + break; + + case 'h': + case 'H': + if (!strncasecmp(uri, "ttp://", 6)) { /* http:// */ + return 7; + } + else if (!strncasecmp(uri, "ttps://", 7)) { /* https:// */ + return 8; + } + break; + + case 'l': + case 'L': + if (!strncasecmp(uri, "dap://", 6)) { /* ldap:// */ + return 7; + } + break; + + case 'm': + case 'M': + if (!strncasecmp(uri, "ailto:", 6)) { /* mailto: */ + return 7; + } + break; + + case 'n': + case 'N': + if (!strncasecmp(uri, "ews:", 4)) { /* news: */ + return 5; + } + else if (!strncasecmp(uri, "ntp://", 6)) { /* nntp:// */ + return 7; + } + break; + } + + return 0; +} + +/* + * escape absolute uri, which may or may not be path oriented. + * So let's handle them differently. + */ +static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme) +{ + char *cp; + + /* be safe. + * NULL should indicate elsewhere, that something's wrong + */ + if (!scheme || strlen(uri) < scheme) { + return NULL; + } + + cp = uri + scheme; + + /* scheme with authority part? */ + if (cp[-1] == '/') { + /* skip host part */ + while (*cp && *cp != '/') { + ++cp; + } + + /* nothing after the hostpart. ready! */ + if (!*cp || !*++cp) { + return apr_pstrdup(p, uri); + } + + /* remember the hostname stuff */ + scheme = cp - uri; + + /* special thing for ldap. + * The parts are separated by question marks. From RFC 2255: + * ldapurl = scheme "://" [hostport] ["/" + * [dn ["?" [attributes] ["?" [scope] + * ["?" [filter] ["?" extensions]]]]]] + */ + if (!strncasecmp(uri, "ldap", 4)) { + char *token[5]; + int c = 0; + + token[0] = cp = apr_pstrdup(p, cp); + while (*cp && c < 5) { + if (*cp == '?') { + token[++c] = cp + 1; + *cp = '\0'; + } + ++cp; + } + + return apr_pstrcat(p, apr_pstrndup(p, uri, scheme), + ap_escape_uri(p, token[0]), + (c >= 1) ? "?" : NULL, + (c >= 1) ? ap_escape_uri(p, token[1]) : NULL, + (c >= 2) ? "?" : NULL, + (c >= 2) ? ap_escape_uri(p, token[2]) : NULL, + (c >= 3) ? "?" : NULL, + (c >= 3) ? ap_escape_uri(p, token[3]) : NULL, + (c >= 4) ? "?" : NULL, + (c >= 4) ? ap_escape_uri(p, token[4]) : NULL, + NULL); + } + } + + /* Nothing special here. Apply normal escaping. */ + return apr_pstrcat(p, apr_pstrndup(p, uri, scheme), + ap_escape_uri(p, cp), NULL); +} + +/* + * split out a QUERY_STRING part from + * the current URI string + */ +static void splitout_queryargs(request_rec *r, int qsappend) +{ + char *q; + + /* don't touch, unless it's an http or mailto URL. + * See RFC 1738 and RFC 2368. + */ + if (is_absolute_uri(r->filename) + && strncasecmp(r->filename, "ajp", 3) + && strncasecmp(r->filename, "balancer", 8) + && strncasecmp(r->filename, "http", 4) + && strncasecmp(r->filename, "mailto", 6)) { + r->args = NULL; /* forget the query that's still flying around */ + return; + } + + q = ap_strchr(r->filename, '?'); + if (q != NULL) { + char *olduri; + apr_size_t len; + + olduri = apr_pstrdup(r->pool, r->filename); + *q++ = '\0'; + if (qsappend) { + r->args = apr_pstrcat(r->pool, q, "&", r->args, NULL); + } + else { + r->args = apr_pstrdup(r->pool, q); + } + + len = strlen(r->args); + if (!len) { + r->args = NULL; + } + else if (r->args[len-1] == '&') { + r->args[len-1] = '\0'; + } + + rewritelog((r, 3, NULL, "split uri=%s -> uri=%s, args=%s", olduri, + r->filename, r->args ? r->args : "")); + } + + return; +} + +/* + * strip 'http[s]://ourhost/' from URI + */ +static void reduce_uri(request_rec *r) +{ + char *cp; + apr_size_t l; + + cp = (char *)ap_http_scheme(r); + l = strlen(cp); + if ( strlen(r->filename) > l+3 + && strncasecmp(r->filename, cp, l) == 0 + && r->filename[l] == ':' + && r->filename[l+1] == '/' + && r->filename[l+2] == '/' ) { + + unsigned short port; + char *portp, *host, *url, *scratch; + + scratch = apr_pstrdup(r->pool, r->filename); /* our scratchpad */ + + /* cut the hostname and port out of the URI */ + cp = host = scratch + l + 3; /* 3 == strlen("://") */ + while (*cp && *cp != '/' && *cp != ':') { + ++cp; + } + + if (*cp == ':') { /* additional port given */ + *cp++ = '\0'; + portp = cp; + while (*cp && *cp != '/') { + ++cp; + } + *cp = '\0'; + + port = atoi(portp); + url = r->filename + (cp - scratch); + if (!*url) { + url = "/"; + } + } + else if (*cp == '/') { /* default port */ + *cp = '\0'; + + port = ap_default_port(r); + url = r->filename + (cp - scratch); + } + else { + port = ap_default_port(r); + url = "/"; + } + + /* now check whether we could reduce it to a local path... */ + if (ap_matches_request_vhost(r, host, port)) { + rewritelog((r, 3, NULL, "reduce %s -> %s", r->filename, url)); + r->filename = apr_pstrdup(r->pool, url); + } + } + + return; +} + +/* + * add 'http[s]://ourhost[:ourport]/' to URI + * if URI is still not fully qualified + */ +static void fully_qualify_uri(request_rec *r) +{ + if (!is_absolute_uri(r->filename)) { + const char *thisserver; + char *thisport; + int port; + + thisserver = ap_get_server_name(r); + port = ap_get_server_port(r); + thisport = ap_is_default_port(port, r) + ? "" + : apr_psprintf(r->pool, ":%u", port); + + r->filename = apr_psprintf(r->pool, "%s://%s%s%s%s", + ap_http_scheme(r), thisserver, thisport, + (*r->filename == '/') ? "" : "/", + r->filename); + } + + return; +} + +/* + * stat() only the first segment of a path + */ +static int prefix_stat(const char *path, apr_pool_t *pool) +{ + const char *curpath = path; + const char *root; + const char *slash; + char *statpath; + apr_status_t rv; + + rv = apr_filepath_root(&root, &curpath, APR_FILEPATH_TRUENAME, pool); + + if (rv != APR_SUCCESS) { + return 0; + } + + /* let's recognize slashes only, the mod_rewrite semantics are opaque + * enough. + */ + if ((slash = ap_strchr_c(curpath, '/')) != NULL) { + rv = apr_filepath_merge(&statpath, root, + apr_pstrndup(pool, curpath, + (apr_size_t)(slash - curpath)), + APR_FILEPATH_NOTABOVEROOT | + APR_FILEPATH_NOTRELATIVE, pool); + } + else { + rv = apr_filepath_merge(&statpath, root, curpath, + APR_FILEPATH_NOTABOVEROOT | + APR_FILEPATH_NOTRELATIVE, pool); + } + + if (rv == APR_SUCCESS) { + apr_finfo_t sb; + + if (apr_stat(&sb, statpath, APR_FINFO_MIN, pool) == APR_SUCCESS) { + return 1; + } + } + + return 0; +} + +/* + * substitute the prefix path 'match' in 'input' with 'subst' (RewriteBase) + */ +static char *subst_prefix_path(request_rec *r, char *input, char *match, + const char *subst) +{ + apr_size_t len = strlen(match); + + if (len && match[len - 1] == '/') { + --len; + } + + if (!strncmp(input, match, len) && input[len++] == '/') { + apr_size_t slen, outlen; + char *output; + + rewritelog((r, 5, NULL, "strip matching prefix: %s -> %s", input, + input+len)); + + slen = strlen(subst); + if (slen && subst[slen - 1] != '/') { + ++slen; + } + + outlen = strlen(input) + slen - len; + output = apr_palloc(r->pool, outlen + 1); /* don't forget the \0 */ + + memcpy(output, subst, slen); + if (slen && !output[slen-1]) { + output[slen-1] = '/'; + } + memcpy(output+slen, input+len, outlen - slen); + output[outlen] = '\0'; + + rewritelog((r, 4, NULL, "add subst prefix: %s -> %s", input+len, + output)); + + return output; + } + + /* prefix didn't match */ + return input; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | caching support + * | | + * +-------------------------------------------------------+ + */ + +static void set_cache_value(const char *name, apr_time_t t, char *key, + char *val) +{ + cachedmap *map; + + if (cachep) { +#if APR_HAS_THREADS + apr_thread_mutex_lock(cachep->lock); +#endif + map = apr_hash_get(cachep->maps, name, APR_HASH_KEY_STRING); + + if (!map) { + apr_pool_t *p; + + if (apr_pool_create(&p, cachep->pool) != APR_SUCCESS) { +#if APR_HAS_THREADS + apr_thread_mutex_unlock(cachep->lock); +#endif + return; + } + + map = apr_palloc(cachep->pool, sizeof(cachedmap)); + map->pool = p; + map->entries = apr_hash_make(map->pool); + map->mtime = t; + + apr_hash_set(cachep->maps, name, APR_HASH_KEY_STRING, map); + } + else if (map->mtime != t) { + apr_pool_clear(map->pool); + map->entries = apr_hash_make(map->pool); + map->mtime = t; + } + + /* Now we should have a valid map->entries hash, where we + * can store our value. + * + * We need to copy the key and the value into OUR pool, + * so that we don't leave it during the r->pool cleanup. + */ + apr_hash_set(map->entries, + apr_pstrdup(map->pool, key), APR_HASH_KEY_STRING, + apr_pstrdup(map->pool, val)); + +#if APR_HAS_THREADS + apr_thread_mutex_unlock(cachep->lock); +#endif + } + + return; +} + +static char *get_cache_value(const char *name, apr_time_t t, char *key, + apr_pool_t *p) +{ + cachedmap *map; + char *val = NULL; + + if (cachep) { +#if APR_HAS_THREADS + apr_thread_mutex_lock(cachep->lock); +#endif + map = apr_hash_get(cachep->maps, name, APR_HASH_KEY_STRING); + + if (map) { + /* if this map is outdated, forget it. */ + if (map->mtime != t) { + apr_pool_clear(map->pool); + map->entries = apr_hash_make(map->pool); + map->mtime = t; + } + else { + val = apr_hash_get(map->entries, key, APR_HASH_KEY_STRING); + if (val) { + /* copy the cached value into the supplied pool, + * where it belongs (r->pool usually) + */ + val = apr_pstrdup(p, val); + } + } + } + +#if APR_HAS_THREADS + apr_thread_mutex_unlock(cachep->lock); +#endif + } + + return val; +} + +static int init_cache(apr_pool_t *p) +{ + cachep = apr_palloc(p, sizeof(cache)); + if (apr_pool_create(&cachep->pool, p) != APR_SUCCESS) { + cachep = NULL; /* turns off cache */ + return 0; + } + + cachep->maps = apr_hash_make(cachep->pool); +#if APR_HAS_THREADS + (void)apr_thread_mutex_create(&(cachep->lock), APR_THREAD_MUTEX_DEFAULT, p); +#endif + + return 1; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Map Functions + * | | + * +-------------------------------------------------------+ + */ + +/* + * General Note: key is already a fresh string, created (expanded) just + * for the purpose to be passed in here. So one can modify key itself. + */ + +static char *rewrite_mapfunc_toupper(request_rec *r, char *key) +{ + char *p; + + for (p = key; *p; ++p) { + *p = apr_toupper(*p); + } + + return key; +} + +static char *rewrite_mapfunc_tolower(request_rec *r, char *key) +{ + char *p; + + for (p = key; *p; ++p) { + *p = apr_tolower(*p); + } + + return key; +} + +static char *rewrite_mapfunc_escape(request_rec *r, char *key) +{ + return ap_escape_uri(r->pool, key); +} + +static char *rewrite_mapfunc_unescape(request_rec *r, char *key) +{ + ap_unescape_url(key); + + return key; +} + +static char *select_random_value_part(request_rec *r, char *value) +{ + char *p = value; + unsigned n = 1; + + /* count number of distinct values */ + while ((p = ap_strchr(p, '|')) != NULL) { + ++n; + ++p; + } + + if (n > 1) { + /* initialize random generator + * + * XXX: Probably this should be wrapped into a thread mutex, + * shouldn't it? Is it worth the effort? + */ + if (!rewrite_rand_init_done) { + srand((unsigned)(getpid())); + rewrite_rand_init_done = 1; + } + + /* select a random subvalue */ + n = (int)(((double)(rand() % RAND_MAX) / RAND_MAX) * n + 1); + + /* extract it from the whole string */ + while (--n && (value = ap_strchr(value, '|')) != NULL) { + ++value; + } + + if (value) { /* should not be NULL, but ... */ + p = ap_strchr(value, '|'); + if (p) { + *p = '\0'; + } + } + } + + return value; +} + +/* child process code */ +static void rewrite_child_errfn(apr_pool_t *p, apr_status_t err, + const char *desc) +{ + ap_log_error(APLOG_MARK, APLOG_ERR, err, NULL, "%s", desc); +} + +static apr_status_t rewritemap_program_child(apr_pool_t *p, + const char *progname, char **argv, + apr_file_t **fpout, + apr_file_t **fpin) +{ + apr_status_t rc; + apr_procattr_t *procattr; + apr_proc_t *procnew; + + if ( APR_SUCCESS == (rc=apr_procattr_create(&procattr, p)) + && APR_SUCCESS == (rc=apr_procattr_io_set(procattr, APR_FULL_BLOCK, + APR_FULL_BLOCK, APR_NO_PIPE)) + && APR_SUCCESS == (rc=apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(p, argv[0]))) + && APR_SUCCESS == (rc=apr_procattr_cmdtype_set(procattr, APR_PROGRAM)) + && APR_SUCCESS == (rc=apr_procattr_child_errfn_set(procattr, + rewrite_child_errfn)) + && APR_SUCCESS == (rc=apr_procattr_error_check_set(procattr, 1))) { + + procnew = apr_pcalloc(p, sizeof(*procnew)); + rc = apr_proc_create(procnew, argv[0], (const char **)argv, NULL, + procattr, p); + + if (rc == APR_SUCCESS) { + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + + if (fpin) { + (*fpin) = procnew->in; + } + + if (fpout) { + (*fpout) = procnew->out; + } + } + } + + return (rc); +} + +static apr_status_t run_rewritemap_programs(server_rec *s, apr_pool_t *p) +{ + rewrite_server_conf *conf; + apr_hash_index_t *hi; + apr_status_t rc; + int lock_warning_issued = 0; + + conf = ap_get_module_config(s->module_config, &rewrite_module); + + /* If the engine isn't turned on, + * don't even try to do anything. + */ + if (conf->state == ENGINE_DISABLED) { + return APR_SUCCESS; + } + + for (hi = apr_hash_first(p, conf->rewritemaps); hi; hi = apr_hash_next(hi)){ + apr_file_t *fpin = NULL; + apr_file_t *fpout = NULL; + rewritemap_entry *map; + void *val; + + apr_hash_this(hi, NULL, NULL, &val); + map = val; + + if (map->type != MAPTYPE_PRG) { + continue; + } + if (!(map->argv[0]) || !*(map->argv[0]) || map->fpin || map->fpout) { + continue; + } + + if (!lock_warning_issued && (!lockname || !*lockname)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "mod_rewrite: Running external rewrite maps " + "without defining a RewriteLock is DANGEROUS!"); + ++lock_warning_issued; + } + + rc = rewritemap_program_child(p, map->argv[0], map->argv, + &fpout, &fpin); + if (rc != APR_SUCCESS || fpin == NULL || fpout == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, + "mod_rewrite: could not start RewriteMap " + "program %s", map->checkfile); + return rc; + } + map->fpin = fpin; + map->fpout = fpout; + } + + return APR_SUCCESS; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Lookup functions + * | | + * +-------------------------------------------------------+ + */ + +static char *lookup_map_txtfile(request_rec *r, const char *file, char *key) +{ + apr_file_t *fp = NULL; + char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */ + char *value, *keylast; + + if (apr_file_open(&fp, file, APR_READ|APR_BUFFERED, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS) { + return NULL; + } + + keylast = key + strlen(key); + value = NULL; + while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) { + char *p, *c; + + /* ignore comments and lines starting with whitespaces */ + if (*line == '#' || apr_isspace(*line)) { + continue; + } + + p = line; + c = key; + while (c < keylast && *p == *c && !apr_isspace(*p)) { + ++p; + ++c; + } + + /* key doesn't match - ignore. */ + if (c != keylast || !apr_isspace(*p)) { + continue; + } + + /* jump to the value */ + while (*p && apr_isspace(*p)) { + ++p; + } + + /* no value? ignore */ + if (!*p) { + continue; + } + + /* extract the value and return. */ + c = p; + while (*p && !apr_isspace(*p)) { + ++p; + } + value = apr_pstrmemdup(r->pool, c, p - c); + break; + } + apr_file_close(fp); + + return value; +} + +static char *lookup_map_dbmfile(request_rec *r, const char *file, + const char *dbmtype, char *key) +{ + apr_dbm_t *dbmfp = NULL; + apr_datum_t dbmkey; + apr_datum_t dbmval; + char *value; + + if (apr_dbm_open_ex(&dbmfp, dbmtype, file, APR_DBM_READONLY, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS) { + return NULL; + } + + dbmkey.dptr = key; + dbmkey.dsize = strlen(key); + + if (apr_dbm_fetch(dbmfp, dbmkey, &dbmval) == APR_SUCCESS && dbmval.dptr) { + value = apr_pstrmemdup(r->pool, dbmval.dptr, dbmval.dsize); + } + else { + value = NULL; + } + + apr_dbm_close(dbmfp); + + return value; +} + +static char *lookup_map_program(request_rec *r, apr_file_t *fpin, + apr_file_t *fpout, char *key) +{ + char *buf; + char c; + apr_size_t i, nbytes, combined_len = 0; + apr_status_t rv; + const char *eol = APR_EOL_STR; + apr_size_t eolc = 0; + int found_nl = 0; + result_list *buflist = NULL, *curbuf = NULL; + +#ifndef NO_WRITEV + struct iovec iova[2]; + apr_size_t niov; +#endif + + /* when `RewriteEngine off' was used in the per-server + * context then the rewritemap-programs were not spawned. + * In this case using such a map (usually in per-dir context) + * is useless because it is not available. + * + * newlines in the key leave bytes in the pipe and cause + * bad things to happen (next map lookup will use the chars + * after the \n instead of the new key etc etc - in other words, + * the Rewritemap falls out of sync with the requests). + */ + if (fpin == NULL || fpout == NULL || ap_strchr(key, '\n')) { + return NULL; + } + + /* take the lock */ + if (rewrite_mapr_lock_acquire) { + rv = apr_global_mutex_lock(rewrite_mapr_lock_acquire); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_global_mutex_lock(rewrite_mapr_lock_acquire) " + "failed"); + return NULL; /* Maybe this should be fatal? */ + } + } + + /* write out the request key */ +#ifdef NO_WRITEV + nbytes = strlen(key); + apr_file_write(fpin, key, &nbytes); + nbytes = 1; + apr_file_write(fpin, "\n", &nbytes); +#else + iova[0].iov_base = key; + iova[0].iov_len = strlen(key); + iova[1].iov_base = "\n"; + iova[1].iov_len = 1; + + niov = 2; + apr_file_writev(fpin, iova, niov, &nbytes); +#endif + + buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF + 1); + + /* read in the response value */ + nbytes = 1; + apr_file_read(fpout, &c, &nbytes); + do { + i = 0; + while (nbytes == 1 && (i < REWRITE_PRG_MAP_BUF)) { + if (c == eol[eolc]) { + if (!eol[++eolc]) { + /* remove eol from the buffer */ + --eolc; + if (i < eolc) { + curbuf->len -= eolc-i; + i = 0; + } + else { + i -= eolc; + } + ++found_nl; + break; + } + } + + /* only partial (invalid) eol sequence -> reset the counter */ + else if (eolc) { + eolc = 0; + } + + /* catch binary mode, e.g. on Win32 */ + else if (c == '\n') { + ++found_nl; + break; + } + + buf[i++] = c; + apr_file_read(fpout, &c, &nbytes); + } + + /* well, if there wasn't a newline yet, we need to read further */ + if (buflist || (nbytes == 1 && !found_nl)) { + if (!buflist) { + curbuf = buflist = apr_palloc(r->pool, sizeof(*buflist)); + } + else if (i) { + curbuf->next = apr_palloc(r->pool, sizeof(*buflist)); + curbuf = curbuf->next; + + } + curbuf->next = NULL; + + if (i) { + curbuf->string = buf; + curbuf->len = i; + combined_len += i; + buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF); + } + + if (nbytes == 1 && !found_nl) { + i = 0; + continue; + } + } + + break; + } while (1); + + /* concat the stuff */ + if (buflist) { + char *p; + + p = buf = apr_palloc(r->pool, combined_len + 1); /* \0 */ + while (buflist) { + if (buflist->len) { + memcpy(p, buflist->string, buflist->len); + p += buflist->len; + } + buflist = buflist->next; + } + *p = '\0'; + i = combined_len; + } + else { + buf[i] = '\0'; + } + + /* give the lock back */ + if (rewrite_mapr_lock_acquire) { + rv = apr_global_mutex_unlock(rewrite_mapr_lock_acquire); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_global_mutex_unlock(rewrite_mapr_lock_acquire) " + "failed"); + return NULL; /* Maybe this should be fatal? */ + } + } + + /* catch the "failed" case */ + if (i == 4 && !strcasecmp(buf, "NULL")) { + return NULL; + } + + return buf; +} + +/* + * generic map lookup + */ +static char *lookup_map(request_rec *r, char *name, char *key) +{ + rewrite_server_conf *conf; + rewritemap_entry *s; + char *value; + apr_finfo_t st; + apr_status_t rv; + + /* get map configuration */ + conf = ap_get_module_config(r->server->module_config, &rewrite_module); + s = apr_hash_get(conf->rewritemaps, name, APR_HASH_KEY_STRING); + + /* map doesn't exist */ + if (!s) { + return NULL; + } + + switch (s->type) { + /* + * Text file map (perhaps random) + */ + case MAPTYPE_RND: + case MAPTYPE_TXT: + rv = apr_stat(&st, s->checkfile, APR_FINFO_MIN, r->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "mod_rewrite: can't access text RewriteMap file %s", + s->checkfile); + rewritelog((r, 1, NULL, + "can't open RewriteMap file, see error log")); + return NULL; + } + + value = get_cache_value(s->cachename, st.mtime, key, r->pool); + if (!value) { + rewritelog((r, 6, NULL, + "cache lookup FAILED, forcing new map lookup")); + + value = lookup_map_txtfile(r, s->datafile, key); + if (!value) { + rewritelog((r, 5, NULL, "map lookup FAILED: map=%s[txt] key=%s", + name, key)); + set_cache_value(s->cachename, st.mtime, key, ""); + return NULL; + } + + rewritelog((r, 5, NULL,"map lookup OK: map=%s[txt] key=%s -> val=%s", + name, key, value)); + set_cache_value(s->cachename, st.mtime, key, value); + } + else { + rewritelog((r,5,NULL,"cache lookup OK: map=%s[txt] key=%s -> val=%s", + name, key, value)); + } + + if (s->type == MAPTYPE_RND && *value) { + value = select_random_value_part(r, value); + rewritelog((r, 5, NULL, "randomly chosen the subvalue `%s'",value)); + } + + return *value ? value : NULL; + + /* + * DBM file map + */ + case MAPTYPE_DBM: + rv = apr_stat(&st, s->checkfile, APR_FINFO_MIN, r->pool); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "mod_rewrite: can't access DBM RewriteMap file %s", + s->checkfile); + rewritelog((r, 1, NULL, + "can't open DBM RewriteMap file, see error log")); + return NULL; + } + + value = get_cache_value(s->cachename, st.mtime, key, r->pool); + if (!value) { + rewritelog((r, 6, NULL, + "cache lookup FAILED, forcing new map lookup")); + + value = lookup_map_dbmfile(r, s->datafile, s->dbmtype, key); + if (!value) { + rewritelog((r, 5, NULL, "map lookup FAILED: map=%s[dbm] key=%s", + name, key)); + set_cache_value(s->cachename, st.mtime, key, ""); + return NULL; + } + + rewritelog((r, 5, NULL, "map lookup OK: map=%s[dbm] key=%s -> " + "val=%s", name, key, value)); + + set_cache_value(s->cachename, st.mtime, key, value); + return value; + } + + rewritelog((r, 5, NULL, "cache lookup OK: map=%s[dbm] key=%s -> val=%s", + name, key, value)); + return *value ? value : NULL; + + /* + * Program file map + */ + case MAPTYPE_PRG: + value = lookup_map_program(r, s->fpin, s->fpout, key); + if (!value) { + rewritelog((r, 5,NULL,"map lookup FAILED: map=%s key=%s", name, + key)); + return NULL; + } + + rewritelog((r, 5, NULL, "map lookup OK: map=%s key=%s -> val=%s", + name, key, value)); + return value; + + /* + * Internal Map + */ + case MAPTYPE_INT: + value = s->func(r, key); + if (!value) { + rewritelog((r, 5,NULL,"map lookup FAILED: map=%s key=%s", name, + key)); + return NULL; + } + + rewritelog((r, 5, NULL, "map lookup OK: map=%s key=%s -> val=%s", + name, key, value)); + return value; + } + + return NULL; +} + +/* + * lookup a HTTP header and set VARY note + */ +static const char *lookup_header(const char *name, rewrite_ctx *ctx) +{ + const char *val = apr_table_get(ctx->r->headers_in, name); + + if (val) { + ctx->vary_this = ctx->vary_this + ? apr_pstrcat(ctx->r->pool, ctx->vary_this, ", ", + name, NULL) + : apr_pstrdup(ctx->r->pool, name); + } + + return val; +} + +/* + * lookahead helper function + * Determine the correct URI path in perdir context + */ +static APR_INLINE const char *la_u(rewrite_ctx *ctx) +{ + rewrite_perdir_conf *conf; + + if (*ctx->uri == '/') { + return ctx->uri; + } + + conf = ap_get_module_config(ctx->r->per_dir_config, &rewrite_module); + + return apr_pstrcat(ctx->r->pool, conf->baseurl + ? conf->baseurl : conf->directory, + ctx->uri, NULL); +} + +/* + * generic variable lookup + */ +static char *lookup_variable(char *var, rewrite_ctx *ctx) +{ + const char *result; + request_rec *r = ctx->r; + apr_size_t varlen = strlen(var); + + /* fast exit */ + if (varlen < 4) { + return apr_pstrdup(r->pool, ""); + } + + result = NULL; + + /* fast tests for variable length variables (sic) first */ + if (var[3] == ':') { + if (var[4] && !strncasecmp(var, "ENV", 3)) { + var += 4; + result = apr_table_get(r->notes, var); + + if (!result) { + result = apr_table_get(r->subprocess_env, var); + } + if (!result) { + result = getenv(var); + } + } + else if (var[4] && !strncasecmp(var, "SSL", 3) && rewrite_ssl_lookup) { + result = rewrite_ssl_lookup(r->pool, r->server, r->connection, r, + var + 4); + } + } + else if (var[4] == ':') { + if (var[5]) { + request_rec *rr; + const char *path; + + if (!strncasecmp(var, "HTTP", 4)) { + result = lookup_header(var+5, ctx); + } + else if (!strncasecmp(var, "LA-U", 4)) { + if (ctx->uri && subreq_ok(r)) { + path = ctx->perdir ? la_u(ctx) : ctx->uri; + rr = ap_sub_req_lookup_uri(path, r, NULL); + ctx->r = rr; + result = apr_pstrdup(r->pool, lookup_variable(var+5, ctx)); + ctx->r = r; + ap_destroy_sub_req(rr); + + rewritelog((r, 5, ctx->perdir, "lookahead: path=%s var=%s " + "-> val=%s", path, var+5, result)); + + return (char *)result; + } + } + else if (!strncasecmp(var, "LA-F", 4)) { + if (ctx->uri && subreq_ok(r)) { + path = ctx->uri; + if (ctx->perdir && *path == '/') { + /* sigh, the user wants a file based subrequest, but + * we can't do one, since we don't know what the file + * path is! In this case behave like LA-U. + */ + rr = ap_sub_req_lookup_uri(path, r, NULL); + } + else { + if (ctx->perdir) { + rewrite_perdir_conf *conf; + + conf = ap_get_module_config(r->per_dir_config, + &rewrite_module); + + path = apr_pstrcat(r->pool, conf->directory, path, + NULL); + } + + rr = ap_sub_req_lookup_file(path, r, NULL); + } + + ctx->r = rr; + result = apr_pstrdup(r->pool, lookup_variable(var+5, ctx)); + ctx->r = r; + ap_destroy_sub_req(rr); + + rewritelog((r, 5, ctx->perdir, "lookahead: path=%s var=%s " + "-> val=%s", path, var+5, result)); + + return (char *)result; + } + } + } + } + + /* well, do it the hard way */ + else { + char *p; + apr_time_exp_t tm; + + /* can't do this above, because of the getenv call */ + for (p = var; *p; ++p) { + *p = apr_toupper(*p); + } + + switch (varlen) { + case 4: + if (!strcmp(var, "TIME")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(r->pool, "%04d%02d%02d%02d%02d%02d", + tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + rewritelog((r, 1, ctx->perdir, "RESULT='%s'", result)); + return (char *)result; + } + break; + + case 5: + if (!strcmp(var, "HTTPS")) { + int flag = rewrite_is_https && rewrite_is_https(r->connection); + return apr_pstrdup(r->pool, flag ? "on" : "off"); + } + break; + + case 8: + switch (var[6]) { + case 'A': + if (!strcmp(var, "TIME_DAY")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%02d", tm.tm_mday); + } + break; + + case 'E': + if (!strcmp(var, "TIME_SEC")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%02d", tm.tm_sec); + } + break; + + case 'I': + if (!strcmp(var, "TIME_MIN")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%02d", tm.tm_min); + } + break; + + case 'O': + if (!strcmp(var, "TIME_MON")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%02d", tm.tm_mon+1); + } + break; + } + break; + + case 9: + switch (var[7]) { + case 'A': + if (var[8] == 'Y' && !strcmp(var, "TIME_WDAY")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%d", tm.tm_wday); + } + else if (!strcmp(var, "TIME_YEAR")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%04d", tm.tm_year+1900); + } + break; + + case 'E': + if (!strcmp(var, "IS_SUBREQ")) { + result = (r->main ? "true" : "false"); + } + break; + + case 'F': + if (!strcmp(var, "PATH_INFO")) { + result = r->path_info; + } + break; + + case 'P': + if (!strcmp(var, "AUTH_TYPE")) { + result = r->ap_auth_type; + } + break; + + case 'S': + if (!strcmp(var, "HTTP_HOST")) { + result = lookup_header("Host", ctx); + } + break; + + case 'U': + if (!strcmp(var, "TIME_HOUR")) { + apr_time_exp_lt(&tm, apr_time_now()); + return apr_psprintf(r->pool, "%02d", tm.tm_hour); + } + break; + } + break; + + case 11: + switch (var[8]) { + case 'A': + if (!strcmp(var, "SERVER_NAME")) { + result = ap_get_server_name(r); + } + break; + + case 'D': + if (*var == 'R' && !strcmp(var, "REMOTE_ADDR")) { + result = r->connection->remote_ip; + } + else if (!strcmp(var, "SERVER_ADDR")) { + result = r->connection->local_ip; + } + break; + + case 'E': + if (*var == 'H' && !strcmp(var, "HTTP_ACCEPT")) { + result = lookup_header("Accept", ctx); + } + else if (!strcmp(var, "THE_REQUEST")) { + result = r->the_request; + } + break; + + case 'I': + if (!strcmp(var, "API_VERSION")) { + return apr_psprintf(r->pool, "%d:%d", + MODULE_MAGIC_NUMBER_MAJOR, + MODULE_MAGIC_NUMBER_MINOR); + } + break; + + case 'K': + if (!strcmp(var, "HTTP_COOKIE")) { + result = lookup_header("Cookie", ctx); + } + break; + + case 'O': + if (*var == 'S' && !strcmp(var, "SERVER_PORT")) { + return apr_psprintf(r->pool, "%u", ap_get_server_port(r)); + } + else if (var[7] == 'H' && !strcmp(var, "REMOTE_HOST")) { + result = ap_get_remote_host(r->connection,r->per_dir_config, + REMOTE_NAME, NULL); + } + else if (!strcmp(var, "REMOTE_PORT")) { + return apr_itoa(r->pool, r->connection->remote_addr->port); + } + break; + + case 'S': + if (*var == 'R' && !strcmp(var, "REMOTE_USER")) { + result = r->user; + } + else if (!strcmp(var, "SCRIPT_USER")) { + result = ""; + if (r->finfo.valid & APR_FINFO_USER) { + apr_uid_name_get((char **)&result, r->finfo.user, + r->pool); + } + } + break; + + case 'U': + if (!strcmp(var, "REQUEST_URI")) { + result = r->uri; + } + break; + } + break; + + case 12: + switch (var[3]) { + case 'I': + if (!strcmp(var, "SCRIPT_GROUP")) { + result = ""; + if (r->finfo.valid & APR_FINFO_GROUP) { + apr_gid_name_get((char **)&result, r->finfo.group, + r->pool); + } + } + break; + + case 'O': + if (!strcmp(var, "REMOTE_IDENT")) { + result = ap_get_remote_logname(r); + } + break; + + case 'P': + if (!strcmp(var, "HTTP_REFERER")) { + result = lookup_header("Referer", ctx); + } + break; + + case 'R': + if (!strcmp(var, "QUERY_STRING")) { + result = r->args; + } + break; + + case 'V': + if (!strcmp(var, "SERVER_ADMIN")) { + result = r->server->server_admin; + } + break; + } + break; + + case 13: + if (!strcmp(var, "DOCUMENT_ROOT")) { + result = ap_document_root(r); + } + break; + + case 14: + if (*var == 'H' && !strcmp(var, "HTTP_FORWARDED")) { + result = lookup_header("Forwarded", ctx); + } + else if (!strcmp(var, "REQUEST_METHOD")) { + result = r->method; + } + break; + + case 15: + switch (var[7]) { + case 'E': + if (!strcmp(var, "HTTP_USER_AGENT")) { + result = lookup_header("User-Agent", ctx); + } + break; + + case 'F': + if (!strcmp(var, "SCRIPT_FILENAME")) { + result = r->filename; /* same as request_filename (16) */ + } + break; + + case 'P': + if (!strcmp(var, "SERVER_PROTOCOL")) { + result = r->protocol; + } + break; + + case 'S': + if (!strcmp(var, "SERVER_SOFTWARE")) { + result = ap_get_server_version(); + } + break; + } + break; + + case 16: + if (!strcmp(var, "REQUEST_FILENAME")) { + result = r->filename; /* same as script_filename (15) */ + } + break; + + case 21: + if (!strcmp(var, "HTTP_PROXY_CONNECTION")) { + result = lookup_header("Proxy-Connection", ctx); + } + break; + } + } + + return apr_pstrdup(r->pool, result ? result : ""); +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Expansion functions + * | | + * +-------------------------------------------------------+ + */ + +/* + * Bracketed expression handling + * s points after the opening bracket + */ +static APR_INLINE char *find_closing_curly(char *s) +{ + unsigned depth; + + for (depth = 1; *s; ++s) { + if (*s == RIGHT_CURLY && --depth == 0) { + return s; + } + else if (*s == LEFT_CURLY) { + ++depth; + } + } + + return NULL; +} + +static APR_INLINE char *find_char_in_curlies(char *s, int c) +{ + unsigned depth; + + for (depth = 1; *s; ++s) { + if (*s == c && depth == 1) { + return s; + } + else if (*s == RIGHT_CURLY && --depth == 0) { + return NULL; + } + else if (*s == LEFT_CURLY) { + ++depth; + } + } + + return NULL; +} + +/* perform all the expansions on the input string + * putting the result into a new string + * + * for security reasons this expansion must be performed in a + * single pass, otherwise an attacker can arrange for the result + * of an earlier expansion to include expansion specifiers that + * are interpreted by a later expansion, producing results that + * were not intended by the administrator. + */ +static char *do_expand(char *input, rewrite_ctx *ctx) +{ + result_list *result, *current; + result_list sresult[SMALL_EXPANSION]; + unsigned spc = 0; + apr_size_t span, inputlen, outlen; + char *p, *c; + apr_pool_t *pool = ctx->r->pool; + + span = strcspn(input, "\\$%"); + inputlen = strlen(input); + + /* fast exit */ + if (inputlen == span) { + return apr_pstrdup(pool, input); + } + + /* well, actually something to do */ + result = current = &(sresult[spc++]); + + p = input + span; + current->next = NULL; + current->string = input; + current->len = span; + outlen = span; + + /* loop for specials */ + do { + /* prepare next entry */ + if (current->len) { + current->next = (spc < SMALL_EXPANSION) + ? &(sresult[spc++]) + : (result_list *)apr_palloc(pool, + sizeof(result_list)); + current = current->next; + current->next = NULL; + current->len = 0; + } + + /* escaped character */ + if (*p == '\\') { + current->len = 1; + ++outlen; + if (!p[1]) { + current->string = p; + break; + } + else { + current->string = ++p; + ++p; + } + } + + /* variable or map lookup */ + else if (p[1] == '{') { + char *endp; + + endp = find_closing_curly(p+2); + if (!endp) { + current->len = 2; + current->string = p; + outlen += 2; + p += 2; + } + + /* variable lookup */ + else if (*p == '%') { + p = lookup_variable(apr_pstrmemdup(pool, p+2, endp-p-2), ctx); + + span = strlen(p); + current->len = span; + current->string = p; + outlen += span; + p = endp + 1; + } + + /* map lookup */ + else { /* *p == '$' */ + char *key; + + /* + * To make rewrite maps useful, the lookup key and + * default values must be expanded, so we make + * recursive calls to do the work. For security + * reasons we must never expand a string that includes + * verbatim data from the network. The recursion here + * isn't a problem because the result of expansion is + * only passed to lookup_map() so it cannot be + * re-expanded, only re-looked-up. Another way of + * looking at it is that the recursion is entirely + * driven by the syntax of the nested curly brackets. + */ + + key = find_char_in_curlies(p+2, ':'); + if (!key) { + current->len = 2; + current->string = p; + outlen += 2; + p += 2; + } + else { + char *map, *dflt; + + map = apr_pstrmemdup(pool, p+2, endp-p-2); + key = map + (key-p-2); + *key++ = '\0'; + dflt = find_char_in_curlies(key, '|'); + if (dflt) { + *dflt++ = '\0'; + } + + /* reuse of key variable as result */ + key = lookup_map(ctx->r, map, do_expand(key, ctx)); + + if (!key && dflt && *dflt) { + key = do_expand(dflt, ctx); + } + + if (key) { + span = strlen(key); + current->len = span; + current->string = key; + outlen += span; + } + + p = endp + 1; + } + } + } + + /* backreference */ + else if (apr_isdigit(p[1])) { + int n = p[1] - '0'; + backrefinfo *bri = (*p == '$') ? &ctx->briRR : &ctx->briRC; + + /* see ap_pregsub() in server/util.c */ + if (bri->source && n < AP_MAX_REG_MATCH + && bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so) { + span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so; + + current->len = span; + current->string = bri->source + bri->regmatch[n].rm_so; + outlen += span; + } + + p += 2; + } + + /* not for us, just copy it */ + else { + current->len = 1; + current->string = p++; + ++outlen; + } + + /* check the remainder */ + if (*p && (span = strcspn(p, "\\$%")) > 0) { + if (current->len) { + current->next = (spc < SMALL_EXPANSION) + ? &(sresult[spc++]) + : (result_list *)apr_palloc(pool, + sizeof(result_list)); + current = current->next; + current->next = NULL; + } + + current->len = span; + current->string = p; + p += span; + outlen += span; + } + + } while (p < input+inputlen); + + /* assemble result */ + c = p = apr_palloc(pool, outlen + 1); /* don't forget the \0 */ + do { + if (result->len) { + ap_assert(c+result->len <= p+outlen); /* XXX: can be removed after + * extensive testing and + * review + */ + memcpy(c, result->string, result->len); + c += result->len; + } + result = result->next; + } while (result); + + p[outlen] = '\0'; + + return p; +} + +/* + * perform all the expansions on the environment variables + */ +static void do_expand_env(data_item *env, rewrite_ctx *ctx) +{ + char *name, *val; + + while (env) { + name = do_expand(env->data, ctx); + if ((val = ap_strchr(name, ':')) != NULL) { + *val++ = '\0'; + + apr_table_set(ctx->r->subprocess_env, name, val); + rewritelog((ctx->r, 5, NULL, "setting env variable '%s' to '%s'", + name, val)); + } + + env = env->next; + } + + return; +} + +/* + * perform all the expansions on the cookies + * + * TODO: use cached time similar to how logging does it + */ +static void add_cookie(request_rec *r, char *s) +{ + char *var; + char *val; + char *domain; + char *expires; + char *path; + + char *tok_cntx; + char *cookie; + + var = apr_strtok(s, ":", &tok_cntx); + val = apr_strtok(NULL, ":", &tok_cntx); + domain = apr_strtok(NULL, ":", &tok_cntx); + + if (var && val && domain) { + request_rec *rmain = r; + char *notename; + void *data; + + while (rmain->main) { + rmain = rmain->main; + } + + notename = apr_pstrcat(rmain->pool, var, "_rewrite", NULL); + apr_pool_userdata_get(&data, notename, rmain->pool); + if (!data) { + char *exp_time = NULL; + + expires = apr_strtok(NULL, ":", &tok_cntx); + path = expires ? apr_strtok(NULL, ":", &tok_cntx) : NULL; + + if (expires) { + apr_time_exp_t tms; + apr_time_exp_gmt(&tms, r->request_time + + apr_time_from_sec((60 * atol(expires)))); + exp_time = apr_psprintf(r->pool, "%s, %.2d-%s-%.4d " + "%.2d:%.2d:%.2d GMT", + apr_day_snames[tms.tm_wday], + tms.tm_mday, + apr_month_snames[tms.tm_mon], + tms.tm_year+1900, + tms.tm_hour, tms.tm_min, tms.tm_sec); + } + + cookie = apr_pstrcat(rmain->pool, + var, "=", val, + "; path=", path ? path : "/", + "; domain=", domain, + expires ? "; expires=" : NULL, + expires ? exp_time : NULL, + NULL); + + apr_table_addn(rmain->err_headers_out, "Set-Cookie", cookie); + apr_pool_userdata_set("set", notename, NULL, rmain->pool); + rewritelog((rmain, 5, NULL, "setting cookie '%s'", cookie)); + } + else { + rewritelog((rmain, 5, NULL, "skipping already set cookie '%s'", + var)); + } + } + + return; +} + +static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx) +{ + while (cookie) { + add_cookie(ctx->r, do_expand(cookie->data, ctx)); + cookie = cookie->next; + } + + return; +} + +#if APR_HAS_USER +/* + * Expand tilde-paths (/~user) through Unix /etc/passwd + * database information (or other OS-specific database) + */ +static char *expand_tildepaths(request_rec *r, char *uri) +{ + if (uri && *uri == '/' && uri[1] == '~') { + char *p, *user; + + p = user = uri + 2; + while (*p && *p != '/') { + ++p; + } + + if (p > user) { + char *homedir; + + user = apr_pstrmemdup(r->pool, user, p-user); + if (apr_uid_homepath_get(&homedir, user, r->pool) == APR_SUCCESS) { + if (*p) { + /* reuse of user variable */ + user = homedir + strlen(homedir) - 1; + if (user >= homedir && *user == '/') { + *user = '\0'; + } + + return apr_pstrcat(r->pool, homedir, p, NULL); + } + else { + return homedir; + } + } + } + } + + return uri; +} +#endif /* if APR_HAS_USER */ + + +/* + * +-------------------------------------------------------+ + * | | + * | rewriting lockfile support + * | | + * +-------------------------------------------------------+ + */ + +static apr_status_t rewritelock_create(server_rec *s, apr_pool_t *p) +{ + apr_status_t rc; + + /* only operate if a lockfile is used */ + if (lockname == NULL || *(lockname) == '\0') { + return APR_SUCCESS; + } + + /* create the lockfile */ + rc = apr_global_mutex_create(&rewrite_mapr_lock_acquire, lockname, + APR_LOCK_DEFAULT, p); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, + "mod_rewrite: Parent could not create RewriteLock " + "file %s", lockname); + return rc; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + rc = unixd_set_global_mutex_perms(rewrite_mapr_lock_acquire); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, + "mod_rewrite: Parent could not set permissions " + "on RewriteLock; check User and Group directives"); + return rc; + } +#endif + + return APR_SUCCESS; +} + +static apr_status_t rewritelock_remove(void *data) +{ + /* only operate if a lockfile is used */ + if (lockname == NULL || *(lockname) == '\0') { + return APR_SUCCESS; + } + + /* destroy the rewritelock */ + apr_global_mutex_destroy (rewrite_mapr_lock_acquire); + rewrite_mapr_lock_acquire = NULL; + lockname = NULL; + return(0); +} + + +/* + * +-------------------------------------------------------+ + * | | + * | configuration directive handling + * | | + * +-------------------------------------------------------+ + */ + +/* + * own command line parser for RewriteRule and RewriteCond, + * which doesn't have the '\\' problem. + * (returns true on error) + * + * XXX: what an inclined parser. Seems we have to leave it so + * for backwards compat. *sigh* + */ +static int parseargline(char *str, char **a1, char **a2, char **a3) +{ + char quote; + + while (apr_isspace(*str)) { + ++str; + } + + /* + * determine first argument + */ + quote = (*str == '"' || *str == '\'') ? *str++ : '\0'; + *a1 = str; + + for (; *str; ++str) { + if ((apr_isspace(*str) && !quote) || (*str == quote)) { + break; + } + if (*str == '\\' && apr_isspace(str[1])) { + ++str; + continue; + } + } + + if (!*str) { + return 1; + } + *str++ = '\0'; + + while (apr_isspace(*str)) { + ++str; + } + + /* + * determine second argument + */ + quote = (*str == '"' || *str == '\'') ? *str++ : '\0'; + *a2 = str; + + for (; *str; ++str) { + if ((apr_isspace(*str) && !quote) || (*str == quote)) { + break; + } + if (*str == '\\' && apr_isspace(str[1])) { + ++str; + continue; + } + } + + if (!*str) { + *a3 = NULL; /* 3rd argument is optional */ + return 0; + } + *str++ = '\0'; + + while (apr_isspace(*str)) { + ++str; + } + + if (!*str) { + *a3 = NULL; /* 3rd argument is still optional */ + return 0; + } + + /* + * determine third argument + */ + quote = (*str == '"' || *str == '\'') ? *str++ : '\0'; + *a3 = str; + for (; *str; ++str) { + if ((apr_isspace(*str) && !quote) || (*str == quote)) { + break; + } + if (*str == '\\' && apr_isspace(str[1])) { + ++str; + continue; + } + } + *str = '\0'; + + return 0; +} + +static void *config_server_create(apr_pool_t *p, server_rec *s) +{ + rewrite_server_conf *a; + + a = (rewrite_server_conf *)apr_pcalloc(p, sizeof(rewrite_server_conf)); + + a->state = ENGINE_DISABLED; + a->options = OPTION_NONE; +#ifndef REWRITELOG_DISABLED + a->rewritelogfile = NULL; + a->rewritelogfp = NULL; + a->rewriteloglevel = 0; +#endif + a->rewritemaps = apr_hash_make(p); + a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry)); + a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry)); + a->server = s; + + return (void *)a; +} + +static void *config_server_merge(apr_pool_t *p, void *basev, void *overridesv) +{ + rewrite_server_conf *a, *base, *overrides; + + a = (rewrite_server_conf *)apr_pcalloc(p, + sizeof(rewrite_server_conf)); + base = (rewrite_server_conf *)basev; + overrides = (rewrite_server_conf *)overridesv; + + a->state = overrides->state; + a->options = overrides->options; + a->server = overrides->server; + + if (a->options & OPTION_INHERIT) { + /* + * local directives override + * and anything else is inherited + */ +#ifndef REWRITELOG_DISABLED + a->rewriteloglevel = overrides->rewriteloglevel != 0 + ? overrides->rewriteloglevel + : base->rewriteloglevel; + a->rewritelogfile = overrides->rewritelogfile != NULL + ? overrides->rewritelogfile + : base->rewritelogfile; + a->rewritelogfp = overrides->rewritelogfp != NULL + ? overrides->rewritelogfp + : base->rewritelogfp; +#endif + a->rewritemaps = apr_hash_overlay(p, overrides->rewritemaps, + base->rewritemaps); + a->rewriteconds = apr_array_append(p, overrides->rewriteconds, + base->rewriteconds); + a->rewriterules = apr_array_append(p, overrides->rewriterules, + base->rewriterules); + } + else { + /* + * local directives override + * and anything else gets defaults + */ +#ifndef REWRITELOG_DISABLED + a->rewriteloglevel = overrides->rewriteloglevel; + a->rewritelogfile = overrides->rewritelogfile; + a->rewritelogfp = overrides->rewritelogfp; +#endif + a->rewritemaps = overrides->rewritemaps; + a->rewriteconds = overrides->rewriteconds; + a->rewriterules = overrides->rewriterules; + } + + return (void *)a; +} + +static void *config_perdir_create(apr_pool_t *p, char *path) +{ + rewrite_perdir_conf *a; + + a = (rewrite_perdir_conf *)apr_pcalloc(p, sizeof(rewrite_perdir_conf)); + + a->state = ENGINE_DISABLED; + a->options = OPTION_NONE; + a->baseurl = NULL; + a->rewriteconds = apr_array_make(p, 2, sizeof(rewritecond_entry)); + a->rewriterules = apr_array_make(p, 2, sizeof(rewriterule_entry)); + + if (path == NULL) { + a->directory = NULL; + } + else { + /* make sure it has a trailing slash */ + if (path[strlen(path)-1] == '/') { + a->directory = apr_pstrdup(p, path); + } + else { + a->directory = apr_pstrcat(p, path, "/", NULL); + } + } + + return (void *)a; +} + +static void *config_perdir_merge(apr_pool_t *p, void *basev, void *overridesv) +{ + rewrite_perdir_conf *a, *base, *overrides; + + a = (rewrite_perdir_conf *)apr_pcalloc(p, + sizeof(rewrite_perdir_conf)); + base = (rewrite_perdir_conf *)basev; + overrides = (rewrite_perdir_conf *)overridesv; + + a->state = overrides->state; + a->options = overrides->options; + a->directory = overrides->directory; + a->baseurl = overrides->baseurl; + + if (a->options & OPTION_INHERIT) { + a->rewriteconds = apr_array_append(p, overrides->rewriteconds, + base->rewriteconds); + a->rewriterules = apr_array_append(p, overrides->rewriterules, + base->rewriterules); + } + else { + a->rewriteconds = overrides->rewriteconds; + a->rewriterules = overrides->rewriterules; + } + + return (void *)a; +} + +static const char *cmd_rewriteengine(cmd_parms *cmd, + void *in_dconf, int flag) +{ + rewrite_perdir_conf *dconf = in_dconf; + rewrite_server_conf *sconf; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + + if (cmd->path == NULL) { /* is server command */ + sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED); + } + else /* is per-directory command */ { + dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED); + } + + return NULL; +} + +static const char *cmd_rewriteoptions(cmd_parms *cmd, + void *in_dconf, const char *option) +{ + int options = 0; + char *w; + + while (*option) { + w = ap_getword_conf(cmd->pool, &option); + + if (!strcasecmp(w, "inherit")) { + options |= OPTION_INHERIT; + } + else if (!strncasecmp(w, "MaxRedirects=", 13)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "RewriteOptions: MaxRedirects option has been " + "removed in favor of the global " + "LimitInternalRecursion directive and will be " + "ignored."); + } + else { + return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '", + w, "'", NULL); + } + } + + /* put it into the appropriate config */ + if (cmd->path == NULL) { /* is server command */ + rewrite_server_conf *conf = + ap_get_module_config(cmd->server->module_config, + &rewrite_module); + + conf->options |= options; + } + else { /* is per-directory command */ + rewrite_perdir_conf *conf = in_dconf; + + conf->options |= options; + } + + return NULL; +} + +#ifndef REWRITELOG_DISABLED +static const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, const char *a1) +{ + rewrite_server_conf *sconf; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + sconf->rewritelogfile = a1; + + return NULL; +} + +static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, + const char *a1) +{ + rewrite_server_conf *sconf; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + sconf->rewriteloglevel = atoi(a1); + + return NULL; +} +#endif /* rewritelog */ + +static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1, + const char *a2) +{ + rewrite_server_conf *sconf; + rewritemap_entry *newmap; + apr_finfo_t st; + const char *fname; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + + newmap = apr_palloc(cmd->pool, sizeof(rewritemap_entry)); + newmap->func = NULL; + + if (strncasecmp(a2, "txt:", 4) == 0) { + if ((fname = ap_server_root_relative(cmd->pool, a2+4)) == NULL) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad path to txt map: ", + a2+4, NULL); + } + + newmap->type = MAPTYPE_TXT; + newmap->datafile = fname; + newmap->checkfile = fname; + newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s", + (void *)cmd->server, a1); + } + else if (strncasecmp(a2, "rnd:", 4) == 0) { + if ((fname = ap_server_root_relative(cmd->pool, a2+4)) == NULL) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad path to rnd map: ", + a2+4, NULL); + } + + newmap->type = MAPTYPE_RND; + newmap->datafile = fname; + newmap->checkfile = fname; + newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s", + (void *)cmd->server, a1); + } + else if (strncasecmp(a2, "dbm", 3) == 0) { + const char *ignored_fname; + apr_status_t rv; + + newmap->type = MAPTYPE_DBM; + fname = NULL; + newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s", + (void *)cmd->server, a1); + + if (a2[3] == ':') { + newmap->dbmtype = "default"; + fname = a2+4; + } + else if (a2[3] == '=') { + const char *colon = ap_strchr_c(a2 + 4, ':'); + + if (colon) { + newmap->dbmtype = apr_pstrndup(cmd->pool, a2 + 4, + colon - (a2 + 3) - 1); + fname = colon + 1; + } + } + + if (!fname) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad map:", + a2, NULL); + } + + if ((newmap->datafile = ap_server_root_relative(cmd->pool, + fname)) == NULL) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad path to dbm map: ", + fname, NULL); + } + + rv = apr_dbm_get_usednames_ex(cmd->pool, newmap->dbmtype, + newmap->datafile, &newmap->checkfile, + &ignored_fname); + if (rv != APR_SUCCESS) { + return apr_pstrcat(cmd->pool, "RewriteMap: dbm type ", + newmap->dbmtype, " is invalid", NULL); + } + } + else if (strncasecmp(a2, "prg:", 4) == 0) { + apr_tokenize_to_argv(a2 + 4, &newmap->argv, cmd->pool); + + fname = newmap->argv[0]; + if ((newmap->argv[0] = ap_server_root_relative(cmd->pool, + fname)) == NULL) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad path to prg map: ", + fname, NULL); + } + + newmap->type = MAPTYPE_PRG; + newmap->datafile = NULL; + newmap->checkfile = newmap->argv[0]; + newmap->cachename = NULL; + } + else if (strncasecmp(a2, "int:", 4) == 0) { + newmap->type = MAPTYPE_INT; + newmap->datafile = NULL; + newmap->checkfile = NULL; + newmap->cachename = NULL; + newmap->func = (char *(*)(request_rec *,char *)) + apr_hash_get(mapfunc_hash, a2+4, strlen(a2+4)); + if ((sconf->state == ENGINE_ENABLED) && (newmap->func == NULL)) { + return apr_pstrcat(cmd->pool, "RewriteMap: internal map not found:", + a2+4, NULL); + } + } + else { + if ((fname = ap_server_root_relative(cmd->pool, a2)) == NULL) { + return apr_pstrcat(cmd->pool, "RewriteMap: bad path to txt map: ", + a2, NULL); + } + + newmap->type = MAPTYPE_TXT; + newmap->datafile = fname; + newmap->checkfile = fname; + newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s", + (void *)cmd->server, a1); + } + newmap->fpin = NULL; + newmap->fpout = NULL; + + if (newmap->checkfile && (sconf->state == ENGINE_ENABLED) + && (apr_stat(&st, newmap->checkfile, APR_FINFO_MIN, + cmd->pool) != APR_SUCCESS)) { + return apr_pstrcat(cmd->pool, + "RewriteMap: file for map ", a1, + " not found:", newmap->checkfile, NULL); + } + + apr_hash_set(sconf->rewritemaps, a1, APR_HASH_KEY_STRING, newmap); + + return NULL; +} + +static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, const char *a1) +{ + const char *error; + + if ((error = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL) + return error; + + /* fixup the path, especially for rewritelock_remove() */ + lockname = ap_server_root_relative(cmd->pool, a1); + + if (!lockname) { + return apr_pstrcat(cmd->pool, "Invalid RewriteLock path ", a1); + } + + return NULL; +} + +static const char *cmd_rewritebase(cmd_parms *cmd, void *in_dconf, + const char *a1) +{ + rewrite_perdir_conf *dconf = in_dconf; + + if (cmd->path == NULL || dconf == NULL) { + return "RewriteBase: only valid in per-directory config files"; + } + if (a1[0] == '\0') { + return "RewriteBase: empty URL not allowed"; + } + if (a1[0] != '/') { + return "RewriteBase: argument is not a valid URL"; + } + + dconf->baseurl = a1; + + return NULL; +} + +/* + * generic lexer for RewriteRule and RewriteCond flags. + * The parser will be passed in as a function pointer + * and called if a flag was found + */ +static const char *cmd_parseflagfield(apr_pool_t *p, void *cfg, char *key, + const char *(*parse)(apr_pool_t *, + void *, + char *, char *)) +{ + char *val, *nextp, *endp; + const char *err; + + endp = key + strlen(key) - 1; + if (*key != '[' || *endp != ']') { + return "RewriteCond: bad flag delimiters"; + } + + *endp = ','; /* for simpler parsing */ + ++key; + + while (*key) { + /* skip leading spaces */ + while (apr_isspace(*key)) { + ++key; + } + + if (!*key || (nextp = ap_strchr(key, ',')) == NULL) { /* NULL should not + * happen, but ... + */ + break; + } + + /* strip trailing spaces */ + endp = nextp - 1; + while (apr_isspace(*endp)) { + --endp; + } + *++endp = '\0'; + + /* split key and val */ + val = ap_strchr(key, '='); + if (val) { + *val++ = '\0'; + } + else { + val = endp; + } + + err = parse(p, cfg, key, val); + if (err) { + return err; + } + + key = nextp + 1; + } + + return NULL; +} + +static const char *cmd_rewritecond_setflag(apr_pool_t *p, void *_cfg, + char *key, char *val) +{ + rewritecond_entry *cfg = _cfg; + + if ( strcasecmp(key, "nocase") == 0 + || strcasecmp(key, "NC") == 0 ) { + cfg->flags |= CONDFLAG_NOCASE; + } + else if ( strcasecmp(key, "ornext") == 0 + || strcasecmp(key, "OR") == 0 ) { + cfg->flags |= CONDFLAG_ORNEXT; + } + else { + return apr_pstrcat(p, "RewriteCond: unknown flag '", key, "'", NULL); + } + return NULL; +} + +static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf, + const char *in_str) +{ + rewrite_perdir_conf *dconf = in_dconf; + char *str = apr_pstrdup(cmd->pool, in_str); + rewrite_server_conf *sconf; + rewritecond_entry *newcond; + ap_regex_t *regexp; + char *a1; + char *a2; + char *a3; + const char *err; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + + /* make a new entry in the internal temporary rewrite rule list */ + if (cmd->path == NULL) { /* is server command */ + newcond = apr_array_push(sconf->rewriteconds); + } + else { /* is per-directory command */ + newcond = apr_array_push(dconf->rewriteconds); + } + + /* parse the argument line ourself + * a1 .. a3 are substrings of str, which is a fresh copy + * of the argument line. So we can use a1 .. a3 without + * copying them again. + */ + if (parseargline(str, &a1, &a2, &a3)) { + return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str, + "'", NULL); + } + + /* arg1: the input string */ + newcond->input = a1; + + /* arg3: optional flags field + * (this has to be parsed first, because we need to + * know if the regex should be compiled with ICASE!) + */ + newcond->flags = CONDFLAG_NONE; + if (a3 != NULL) { + if ((err = cmd_parseflagfield(cmd->pool, newcond, a3, + cmd_rewritecond_setflag)) != NULL) { + return err; + } + } + + /* arg2: the pattern */ + if (*a2 == '!') { + newcond->flags |= CONDFLAG_NOTMATCH; + ++a2; + } + + /* determine the pattern type */ + newcond->ptype = 0; + if (*a2 && a2[1]) { + if (!a2[2] && *a2 == '-') { + switch (a2[1]) { + case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break; + case 's': newcond->ptype = CONDPAT_FILE_SIZE; break; + case 'l': newcond->ptype = CONDPAT_FILE_LINK; break; + case 'd': newcond->ptype = CONDPAT_FILE_DIR; break; + case 'x': newcond->ptype = CONDPAT_FILE_XBIT; break; + case 'U': newcond->ptype = CONDPAT_LU_URL; break; + case 'F': newcond->ptype = CONDPAT_LU_FILE; break; + } + } + else { + switch (*a2) { + case '>': newcond->ptype = CONDPAT_STR_GT; break; + case '<': newcond->ptype = CONDPAT_STR_LT; break; + case '=': newcond->ptype = CONDPAT_STR_EQ; + /* "" represents an empty string */ + if (*++a2 == '"' && a2[1] == '"' && !a2[2]) { + a2 += 2; + } + break; + } + } + } + + if (newcond->ptype && newcond->ptype != CONDPAT_STR_EQ && + (newcond->flags & CONDFLAG_NOCASE)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "RewriteCond: NoCase option for non-regex pattern '%s' " + "is not supported and will be ignored.", a2); + newcond->flags &= ~CONDFLAG_NOCASE; + } + + newcond->pattern = a2; + + if (!newcond->ptype) { + regexp = ap_pregcomp(cmd->pool, a2, + AP_REG_EXTENDED | ((newcond->flags & CONDFLAG_NOCASE) + ? AP_REG_ICASE : 0)); + if (!regexp) { + return apr_pstrcat(cmd->pool, "RewriteCond: cannot compile regular " + "expression '", a2, "'", NULL); + } + + newcond->regexp = regexp; + } + + return NULL; +} + +static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg, + char *key, char *val) +{ + rewriterule_entry *cfg = _cfg; + int error = 0; + + switch (*key++) { + case 'c': + case 'C': + if (!*key || !strcasecmp(key, "hain")) { /* chain */ + cfg->flags |= RULEFLAG_CHAIN; + } + else if (((*key == 'O' || *key == 'o') && !key[1]) + || !strcasecmp(key, "ookie")) { /* cookie */ + data_item *cp = cfg->cookie; + + if (!cp) { + cp = cfg->cookie = apr_palloc(p, sizeof(*cp)); + } + else { + while (cp->next) { + cp = cp->next; + } + cp->next = apr_palloc(p, sizeof(*cp)); + cp = cp->next; + } + + cp->next = NULL; + cp->data = val; + } + else { + ++error; + } + break; + + case 'e': + case 'E': + if (!*key || !strcasecmp(key, "nv")) { /* env */ + data_item *cp = cfg->env; + + if (!cp) { + cp = cfg->env = apr_palloc(p, sizeof(*cp)); + } + else { + while (cp->next) { + cp = cp->next; + } + cp->next = apr_palloc(p, sizeof(*cp)); + cp = cp->next; + } + + cp->next = NULL; + cp->data = val; + } + else { + ++error; + } + break; + + case 'f': + case 'F': + if (!*key || !strcasecmp(key, "orbidden")) { /* forbidden */ + cfg->flags |= (RULEFLAG_STATUS | RULEFLAG_NOSUB); + cfg->forced_responsecode = HTTP_FORBIDDEN; + } + else { + ++error; + } + break; + + case 'g': + case 'G': + if (!*key || !strcasecmp(key, "one")) { /* gone */ + cfg->flags |= (RULEFLAG_STATUS | RULEFLAG_NOSUB); + cfg->forced_responsecode = HTTP_GONE; + } + else { + ++error; + } + break; + + case 'h': + case 'H': + if (!*key || !strcasecmp(key, "andler")) { /* handler */ + cfg->forced_handler = val; + } + else { + ++error; + } + break; + + case 'l': + case 'L': + if (!*key || !strcasecmp(key, "ast")) { /* last */ + cfg->flags |= RULEFLAG_LASTRULE; + } + else { + ++error; + } + break; + + case 'n': + case 'N': + if (((*key == 'E' || *key == 'e') && !key[1]) + || !strcasecmp(key, "oescape")) { /* noescape */ + cfg->flags |= RULEFLAG_NOESCAPE; + } + else if (!*key || !strcasecmp(key, "ext")) { /* next */ + cfg->flags |= RULEFLAG_NEWROUND; + } + else if (((*key == 'S' || *key == 's') && !key[1]) + || !strcasecmp(key, "osubreq")) { /* nosubreq */ + cfg->flags |= RULEFLAG_IGNOREONSUBREQ; + } + else if (((*key == 'C' || *key == 'c') && !key[1]) + || !strcasecmp(key, "ocase")) { /* nocase */ + cfg->flags |= RULEFLAG_NOCASE; + } + else { + ++error; + } + break; + + case 'p': + case 'P': + if (!*key || !strcasecmp(key, "roxy")) { /* proxy */ + cfg->flags |= RULEFLAG_PROXY; + } + else if (((*key == 'T' || *key == 't') && !key[1]) + || !strcasecmp(key, "assthrough")) { /* passthrough */ + cfg->flags |= RULEFLAG_PASSTHROUGH; + } + else { + ++error; + } + break; + + case 'q': + case 'Q': + if ( !strcasecmp(key, "SA") + || !strcasecmp(key, "sappend")) { /* qsappend */ + cfg->flags |= RULEFLAG_QSAPPEND; + } + else { + ++error; + } + break; + + case 'r': + case 'R': + if (!*key || !strcasecmp(key, "edirect")) { /* redirect */ + int status = 0; + + cfg->flags |= RULEFLAG_FORCEREDIRECT; + if (strlen(val) > 0) { + if (strcasecmp(val, "permanent") == 0) { + status = HTTP_MOVED_PERMANENTLY; + } + else if (strcasecmp(val, "temp") == 0) { + status = HTTP_MOVED_TEMPORARILY; + } + else if (strcasecmp(val, "seeother") == 0) { + status = HTTP_SEE_OTHER; + } + else if (apr_isdigit(*val)) { + status = atoi(val); + if (status != HTTP_INTERNAL_SERVER_ERROR) { + int idx = + ap_index_of_response(HTTP_INTERNAL_SERVER_ERROR); + + if (ap_index_of_response(status) == idx) { + return apr_psprintf(p, "RewriteRule: invalid HTTP " + "response code '%s' for " + "flag 'R'", + val); + } + } + if (!ap_is_HTTP_REDIRECT(status)) { + cfg->flags |= (RULEFLAG_STATUS | RULEFLAG_NOSUB); + } + } + cfg->forced_responsecode = status; + } + } + else { + ++error; + } + break; + + case 's': + case 'S': + if (!*key || !strcasecmp(key, "kip")) { /* skip */ + cfg->skip = atoi(val); + } + else { + ++error; + } + break; + + case 't': + case 'T': + if (!*key || !strcasecmp(key, "ype")) { /* type */ + cfg->forced_mimetype = val; + } + else { + ++error; + } + break; + + default: + ++error; + break; + } + + if (error) { + return apr_pstrcat(p, "RewriteRule: unknown flag '", --key, "'", NULL); + } + + return NULL; +} + +static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf, + const char *in_str) +{ + rewrite_perdir_conf *dconf = in_dconf; + char *str = apr_pstrdup(cmd->pool, in_str); + rewrite_server_conf *sconf; + rewriterule_entry *newrule; + ap_regex_t *regexp; + char *a1; + char *a2; + char *a3; + const char *err; + + sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); + + /* make a new entry in the internal rewrite rule list */ + if (cmd->path == NULL) { /* is server command */ + newrule = apr_array_push(sconf->rewriterules); + } + else { /* is per-directory command */ + newrule = apr_array_push(dconf->rewriterules); + } + + /* parse the argument line ourself */ + if (parseargline(str, &a1, &a2, &a3)) { + return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str, + "'", NULL); + } + + /* arg3: optional flags field */ + newrule->forced_mimetype = NULL; + newrule->forced_handler = NULL; + newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY; + newrule->flags = RULEFLAG_NONE; + newrule->env = NULL; + newrule->cookie = NULL; + newrule->skip = 0; + if (a3 != NULL) { + if ((err = cmd_parseflagfield(cmd->pool, newrule, a3, + cmd_rewriterule_setflag)) != NULL) { + return err; + } + } + + /* arg1: the pattern + * try to compile the regexp to test if is ok + */ + if (*a1 == '!') { + newrule->flags |= RULEFLAG_NOTMATCH; + ++a1; + } + + regexp = ap_pregcomp(cmd->pool, a1, AP_REG_EXTENDED | + ((newrule->flags & RULEFLAG_NOCASE) + ? AP_REG_ICASE : 0)); + if (!regexp) { + return apr_pstrcat(cmd->pool, + "RewriteRule: cannot compile regular expression '", + a1, "'", NULL); + } + + newrule->pattern = a1; + newrule->regexp = regexp; + + /* arg2: the output string */ + newrule->output = a2; + if (*a2 == '-' && !a2[1]) { + newrule->flags |= RULEFLAG_NOSUB; + } + + /* now, if the server or per-dir config holds an + * array of RewriteCond entries, we take it for us + * and clear the array + */ + if (cmd->path == NULL) { /* is server command */ + newrule->rewriteconds = sconf->rewriteconds; + sconf->rewriteconds = apr_array_make(cmd->pool, 2, + sizeof(rewritecond_entry)); + } + else { /* is per-directory command */ + newrule->rewriteconds = dconf->rewriteconds; + dconf->rewriteconds = apr_array_make(cmd->pool, 2, + sizeof(rewritecond_entry)); + } + + return NULL; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | the rewriting engine + * | | + * +-------------------------------------------------------+ + */ + +/* Lexicographic Compare */ +static APR_INLINE int compare_lexicography(char *a, char *b) +{ + apr_size_t i, lena, lenb; + + lena = strlen(a); + lenb = strlen(b); + + if (lena == lenb) { + for (i = 0; i < lena; ++i) { + if (a[i] != b[i]) { + return ((unsigned char)a[i] > (unsigned char)b[i]) ? 1 : -1; + } + } + + return 0; + } + + return ((lena > lenb) ? 1 : -1); +} + +/* + * Apply a single rewriteCond + */ +static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx) +{ + char *input = do_expand(p->input, ctx); + apr_finfo_t sb; + request_rec *rsub, *r = ctx->r; + ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; + int rc = 0; + + switch (p->ptype) { + case CONDPAT_FILE_EXISTS: + if ( apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS + && sb.filetype == APR_REG) { + rc = 1; + } + break; + + case CONDPAT_FILE_SIZE: + if ( apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS + && sb.filetype == APR_REG && sb.size > 0) { + rc = 1; + } + break; + + case CONDPAT_FILE_LINK: +#if !defined(OS2) + if ( apr_stat(&sb, input, APR_FINFO_MIN | APR_FINFO_LINK, + r->pool) == APR_SUCCESS + && sb.filetype == APR_LNK) { + rc = 1; + } +#endif + break; + + case CONDPAT_FILE_DIR: + if ( apr_stat(&sb, input, APR_FINFO_MIN, r->pool) == APR_SUCCESS + && sb.filetype == APR_DIR) { + rc = 1; + } + break; + + case CONDPAT_FILE_XBIT: + if ( apr_stat(&sb, input, APR_FINFO_PROT, r->pool) == APR_SUCCESS + && (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) { + rc = 1; + } + break; + + case CONDPAT_LU_URL: + if (*input && subreq_ok(r)) { + rsub = ap_sub_req_lookup_uri(input, r, NULL); + if (rsub->status < 400) { + rc = 1; + } + rewritelog((r, 5, NULL, "RewriteCond URI (-U) check: " + "path=%s -> status=%d", input, rsub->status)); + ap_destroy_sub_req(rsub); + } + break; + + case CONDPAT_LU_FILE: + if (*input && subreq_ok(r)) { + rsub = ap_sub_req_lookup_file(input, r, NULL); + if (rsub->status < 300 && + /* double-check that file exists since default result is 200 */ + apr_stat(&sb, rsub->filename, APR_FINFO_MIN, + r->pool) == APR_SUCCESS) { + rc = 1; + } + rewritelog((r, 5, NULL, "RewriteCond file (-F) check: path=%s " + "-> file=%s status=%d", input, rsub->filename, + rsub->status)); + ap_destroy_sub_req(rsub); + } + break; + + case CONDPAT_STR_GT: + rc = (compare_lexicography(input, p->pattern+1) == 1) ? 1 : 0; + break; + + case CONDPAT_STR_LT: + rc = (compare_lexicography(input, p->pattern+1) == -1) ? 1 : 0; + break; + + case CONDPAT_STR_EQ: + if (p->flags & CONDFLAG_NOCASE) { + rc = !strcasecmp(input, p->pattern); + } + else { + rc = !strcmp(input, p->pattern); + } + break; + + default: + /* it is really a regexp pattern, so apply it */ + rc = !ap_regexec(p->regexp, input, AP_MAX_REG_MATCH, regmatch, 0); + + /* update briRC backref info */ + if (rc && !(p->flags & CONDFLAG_NOTMATCH)) { + ctx->briRC.source = input; + ctx->briRC.nsub = p->regexp->re_nsub; + memcpy(ctx->briRC.regmatch, regmatch, sizeof(regmatch)); + } + break; + } + + if (p->flags & CONDFLAG_NOTMATCH) { + rc = !rc; + } + + rewritelog((r, 4, ctx->perdir, "RewriteCond: input='%s' pattern='%s%s%s'%s " + "=> %s", input, (p->flags & CONDFLAG_NOTMATCH) ? "!" : "", + (p->ptype == CONDPAT_STR_EQ) ? "=" : "", p->pattern, + (p->flags & CONDFLAG_NOCASE) ? " [NC]" : "", + rc ? "matched" : "not-matched")); + + return rc; +} + +/* check for forced type and handler */ +static APR_INLINE void force_type_handler(rewriterule_entry *p, + rewrite_ctx *ctx) +{ + char *expanded; + + if (p->forced_mimetype) { + expanded = do_expand(p->forced_mimetype, ctx); + + if (*expanded) { + ap_str_tolower(expanded); + + rewritelog((ctx->r, 2, ctx->perdir, "remember %s to have MIME-type " + "'%s'", ctx->r->filename, expanded)); + + apr_table_setn(ctx->r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR, + expanded); + } + } + + if (p->forced_handler) { + expanded = do_expand(p->forced_handler, ctx); + + if (*expanded) { + ap_str_tolower(expanded); + + rewritelog((ctx->r, 2, ctx->perdir, "remember %s to have " + "Content-handler '%s'", ctx->r->filename, expanded)); + + apr_table_setn(ctx->r->notes, REWRITE_FORCED_HANDLER_NOTEVAR, + expanded); + } + } +} + +/* + * Apply a single RewriteRule + */ +static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) +{ + ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; + apr_array_header_t *rewriteconds; + rewritecond_entry *conds; + int i, rc; + char *newuri = NULL; + request_rec *r = ctx->r; + int is_proxyreq = 0; + + ctx->uri = r->filename; + + if (ctx->perdir) { + apr_size_t dirlen = strlen(ctx->perdir); + + /* + * Proxy request? + */ + is_proxyreq = ( r->proxyreq && r->filename + && !strncmp(r->filename, "proxy:", 6)); + + /* Since we want to match against the (so called) full URL, we have + * to re-add the PATH_INFO postfix + */ + if (r->path_info && *r->path_info) { + rewritelog((r, 3, ctx->perdir, "add path info postfix: %s -> %s%s", + ctx->uri, ctx->uri, r->path_info)); + ctx->uri = apr_pstrcat(r->pool, ctx->uri, r->path_info, NULL); + } + + /* Additionally we strip the physical path from the url to match + * it independent from the underlaying filesystem. + */ + if (!is_proxyreq && strlen(ctx->uri) >= dirlen && + !strncmp(ctx->uri, ctx->perdir, dirlen)) { + + rewritelog((r, 3, ctx->perdir, "strip per-dir prefix: %s -> %s", + ctx->uri, ctx->uri + dirlen)); + ctx->uri = ctx->uri + dirlen; + } + } + + /* Try to match the URI against the RewriteRule pattern + * and exit immediately if it didn't apply. + */ + rewritelog((r, 3, ctx->perdir, "applying pattern '%s' to uri '%s'", + p->pattern, ctx->uri)); + + rc = !ap_regexec(p->regexp, ctx->uri, AP_MAX_REG_MATCH, regmatch, 0); + if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) || + (!rc && (p->flags & RULEFLAG_NOTMATCH)) ) ) { + return 0; + } + + /* It matched, wow! Now it's time to prepare the context structure for + * further processing + */ + ctx->vary_this = NULL; + ctx->briRC.source = NULL; + + if (p->flags & RULEFLAG_NOTMATCH) { + ctx->briRR.source = NULL; + } + else { + ctx->briRR.source = apr_pstrdup(r->pool, ctx->uri); + ctx->briRR.nsub = p->regexp->re_nsub; + memcpy(ctx->briRR.regmatch, regmatch, sizeof(regmatch)); + } + + /* Ok, we already know the pattern has matched, but we now + * additionally have to check for all existing preconditions + * (RewriteCond) which have to be also true. We do this at + * this very late stage to avoid unnessesary checks which + * would slow down the rewriting engine. + */ + rewriteconds = p->rewriteconds; + conds = (rewritecond_entry *)rewriteconds->elts; + + for (i = 0; i < rewriteconds->nelts; ++i) { + rewritecond_entry *c = &conds[i]; + + rc = apply_rewrite_cond(c, ctx); + if (c->flags & CONDFLAG_ORNEXT) { + if (!rc) { + /* One condition is false, but another can be still true. */ + ctx->vary_this = NULL; + continue; + } + else { + /* skip the rest of the chained OR conditions */ + while ( i < rewriteconds->nelts + && c->flags & CONDFLAG_ORNEXT) { + c = &conds[++i]; + } + continue; + } + } + else if (!rc) { + return 0; + } + + /* If some HTTP header was involved in the condition, remember it + * for later use + */ + if (ctx->vary_this) { + ctx->vary = ctx->vary + ? apr_pstrcat(r->pool, ctx->vary, ", ", ctx->vary_this, + NULL) + : ctx->vary_this; + ctx->vary_this = NULL; + } + } + + /* expand the result */ + if (!(p->flags & RULEFLAG_NOSUB)) { + newuri = do_expand(p->output, ctx); + rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri, + newuri)); + } + + /* expand [E=var:val] and [CO=] */ + do_expand_env(p->env, ctx); + do_expand_cookie(p->cookie, ctx); + + /* non-substitution rules ('RewriteRule -') end here. */ + if (p->flags & RULEFLAG_NOSUB) { + force_type_handler(p, ctx); + + if (p->flags & RULEFLAG_STATUS) { + rewritelog((r, 2, ctx->perdir, "forcing responsecode %d for %s", + p->forced_responsecode, r->filename)); + + r->status = p->forced_responsecode; + } + + return 2; + } + + /* Now adjust API's knowledge about r->filename and r->args */ + r->filename = newuri; + splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND); + + /* Add the previously stripped per-directory location prefix, unless + * (1) it's an absolute URL path and + * (2) it's a full qualified URL + */ + if ( ctx->perdir && !is_proxyreq && *r->filename != '/' + && !is_absolute_uri(r->filename)) { + rewritelog((r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s", + r->filename, ctx->perdir, r->filename)); + + r->filename = apr_pstrcat(r->pool, ctx->perdir, r->filename, NULL); + } + + /* If this rule is forced for proxy throughput + * (`RewriteRule ... ... [P]') then emulate mod_proxy's + * URL-to-filename handler to be sure mod_proxy is triggered + * for this URL later in the Apache API. But make sure it is + * a fully-qualified URL. (If not it is qualified with + * ourself). + */ + if (p->flags & RULEFLAG_PROXY) { + fully_qualify_uri(r); + + rewritelog((r, 2, ctx->perdir, "forcing proxy-throughput with %s", + r->filename)); + + r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL); + return 1; + } + + /* If this rule is explicitly forced for HTTP redirection + * (`RewriteRule .. .. [R]') then force an external HTTP + * redirect. But make sure it is a fully-qualified URL. (If + * not it is qualified with ourself). + */ + if (p->flags & RULEFLAG_FORCEREDIRECT) { + fully_qualify_uri(r); + + rewritelog((r, 2, ctx->perdir, "explicitly forcing redirect with %s", + r->filename)); + + r->status = p->forced_responsecode; + return 1; + } + + /* Special Rewriting Feature: Self-Reduction + * We reduce the URL by stripping a possible + * http[s]://[:] prefix, i.e. a prefix which + * corresponds to ourself. This is to simplify rewrite maps + * and to avoid recursion, etc. When this prefix is not a + * coincidence then the user has to use [R] explicitly (see + * above). + */ + reduce_uri(r); + + /* If this rule is still implicitly forced for HTTP + * redirection (`RewriteRule .. ://...') then + * directly force an external HTTP redirect. + */ + if (is_absolute_uri(r->filename)) { + rewritelog((r, 2, ctx->perdir, "implicitly forcing redirect (rc=%d) " + "with %s", p->forced_responsecode, r->filename)); + + r->status = p->forced_responsecode; + return 1; + } + + /* Finally remember the forced mime-type */ + force_type_handler(p, ctx); + + /* Puuhhhhhhhh... WHAT COMPLICATED STUFF ;_) + * But now we're done for this particular rule. + */ + return 1; +} + +/* + * Apply a complete rule set, + * i.e. a list of rewrite rules + */ +static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules, + char *perdir) +{ + rewriterule_entry *entries; + rewriterule_entry *p; + int i; + int changed; + int rc; + int s; + rewrite_ctx *ctx; + + ctx = apr_palloc(r->pool, sizeof(*ctx)); + ctx->perdir = perdir; + ctx->r = r; + + /* + * Iterate over all existing rules + */ + entries = (rewriterule_entry *)rewriterules->elts; + changed = 0; + loop: + for (i = 0; i < rewriterules->nelts; i++) { + p = &entries[i]; + + /* + * Ignore this rule on subrequests if we are explicitly + * asked to do so or this is a proxy-throughput or a + * forced redirect rule. + */ + if (r->main != NULL && + (p->flags & RULEFLAG_IGNOREONSUBREQ || + p->flags & RULEFLAG_FORCEREDIRECT )) { + continue; + } + + /* + * Apply the current rule. + */ + ctx->vary = NULL; + rc = apply_rewrite_rule(p, ctx); + + if (rc) { + /* Regardless of what we do next, we've found a match. Check to see + * if any of the request header fields were involved, and add them + * to the Vary field of the response. + */ + if (ctx->vary) { + apr_table_merge(r->headers_out, "Vary", ctx->vary); + } + + /* + * The rule sets the response code (implies match-only) + */ + if (p->flags & RULEFLAG_STATUS) { + return ACTION_STATUS; + } + + /* + * Indicate a change if this was not a match-only rule. + */ + if (rc != 2) { + changed = ((p->flags & RULEFLAG_NOESCAPE) + ? ACTION_NOESCAPE : ACTION_NORMAL); + } + + /* + * Pass-Through Feature (`RewriteRule .. .. [PT]'): + * Because the Apache 1.x API is very limited we + * need this hack to pass the rewritten URL to other + * modules like mod_alias, mod_userdir, etc. + */ + if (p->flags & RULEFLAG_PASSTHROUGH) { + rewritelog((r, 2, perdir, "forcing '%s' to get passed through " + "to next API URI-to-filename handler", r->filename)); + r->filename = apr_pstrcat(r->pool, "passthrough:", + r->filename, NULL); + changed = ACTION_NORMAL; + break; + } + + /* + * Stop processing also on proxy pass-through and + * last-rule and new-round flags. + */ + if (p->flags & (RULEFLAG_PROXY | RULEFLAG_LASTRULE)) { + break; + } + + /* + * On "new-round" flag we just start from the top of + * the rewriting ruleset again. + */ + if (p->flags & RULEFLAG_NEWROUND) { + goto loop; + } + + /* + * If we are forced to skip N next rules, do it now. + */ + if (p->skip > 0) { + s = p->skip; + while ( i < rewriterules->nelts + && s > 0) { + i++; + p = &entries[i]; + s--; + } + } + } + else { + /* + * If current rule is chained with next rule(s), + * skip all this next rule(s) + */ + while ( i < rewriterules->nelts + && p->flags & RULEFLAG_CHAIN) { + i++; + p = &entries[i]; + } + } + } + return changed; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Module Initialization Hooks + * | | + * +-------------------------------------------------------+ + */ + +static int pre_config(apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp) +{ + APR_OPTIONAL_FN_TYPE(ap_register_rewrite_mapfunc) *map_pfn_register; + + /* register int: rewritemap handlers */ + mapfunc_hash = apr_hash_make(pconf); + map_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_rewrite_mapfunc); + if (map_pfn_register) { + map_pfn_register("tolower", rewrite_mapfunc_tolower); + map_pfn_register("toupper", rewrite_mapfunc_toupper); + map_pfn_register("escape", rewrite_mapfunc_escape); + map_pfn_register("unescape", rewrite_mapfunc_unescape); + } + return OK; +} + +static int post_config(apr_pool_t *p, + apr_pool_t *plog, + apr_pool_t *ptemp, + server_rec *s) +{ + apr_status_t rv; + void *data; + int first_time = 0; + const char *userdata_key = "rewrite_init_module"; + + apr_pool_userdata_get(&data, userdata_key, s->process->pool); + if (!data) { + first_time = 1; + apr_pool_userdata_set((const void *)1, userdata_key, + apr_pool_cleanup_null, s->process->pool); + } + + /* check if proxy module is available */ + proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL); + +#ifndef REWRITELOG_DISABLED + /* create the rewriting lockfiles in the parent */ + if ((rv = apr_global_mutex_create(&rewrite_log_lock, NULL, + APR_LOCK_DEFAULT, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_rewrite: could not create rewrite_log_lock"); + return HTTP_INTERNAL_SERVER_ERROR; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + rv = unixd_set_global_mutex_perms(rewrite_log_lock); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_rewrite: Could not set permissions on " + "rewrite_log_lock; check User and Group directives"); + return HTTP_INTERNAL_SERVER_ERROR; + } +#endif /* perms */ +#endif /* rewritelog */ + + rv = rewritelock_create(s, p); + if (rv != APR_SUCCESS) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + apr_pool_cleanup_register(p, (void *)s, rewritelock_remove, + apr_pool_cleanup_null); + + /* step through the servers and + * - open each rewriting logfile + * - open the RewriteMap prg:xxx programs + */ + for (; s; s = s->next) { +#ifndef REWRITELOG_DISABLED + if (!open_rewritelog(s, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } +#endif + + if (!first_time) { + if (run_rewritemap_programs(s, p) != APR_SUCCESS) { + return HTTP_INTERNAL_SERVER_ERROR; + } + } + } + + rewrite_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); + rewrite_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https); + + return OK; +} + +static void init_child(apr_pool_t *p, server_rec *s) +{ + apr_status_t rv = 0; /* get a rid of gcc warning (REWRITELOG_DISABLED) */ + + if (lockname != NULL && *(lockname) != '\0') { + rv = apr_global_mutex_child_init(&rewrite_mapr_lock_acquire, + lockname, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_rewrite: could not init rewrite_mapr_lock_acquire" + " in child"); + } + } + +#ifndef REWRITELOG_DISABLED + rv = apr_global_mutex_child_init(&rewrite_log_lock, NULL, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_rewrite: could not init rewrite log lock in child"); + } +#endif + + /* create the lookup cache */ + if (!init_cache(p)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_rewrite: could not init map cache in child"); + } +} + + +/* + * +-------------------------------------------------------+ + * | | + * | runtime hooks + * | | + * +-------------------------------------------------------+ + */ + +/* + * URI-to-filename hook + * [deals with RewriteRules in server context] + */ +static int hook_uri2file(request_rec *r) +{ + rewrite_server_conf *conf; + const char *saved_rulestatus; + const char *var; + const char *thisserver; + char *thisport; + const char *thisurl; + unsigned int port; + int rulestatus; + + /* + * retrieve the config structures + */ + conf = ap_get_module_config(r->server->module_config, &rewrite_module); + + /* + * only do something under runtime if the engine is really enabled, + * else return immediately! + */ + if (conf->state == ENGINE_DISABLED) { + return DECLINED; + } + + /* + * check for the ugly API case of a virtual host section where no + * mod_rewrite directives exists. In this situation we became no chance + * by the API to setup our default per-server config so we have to + * on-the-fly assume we have the default config. But because the default + * config has a disabled rewriting engine we are lucky because can + * just stop operating now. + */ + if (conf->server != r->server) { + return DECLINED; + } + + /* + * add the SCRIPT_URL variable to the env. this is a bit complicated + * due to the fact that apache uses subrequests and internal redirects + */ + + if (r->main == NULL) { + var = apr_table_get(r->subprocess_env, REDIRECT_ENVVAR_SCRIPT_URL); + if (var == NULL) { + apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, r->uri); + } + else { + apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var); + } + } + else { + var = apr_table_get(r->main->subprocess_env, ENVVAR_SCRIPT_URL); + apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URL, var); + } + + /* + * create the SCRIPT_URI variable for the env + */ + + /* add the canonical URI of this URL */ + thisserver = ap_get_server_name(r); + port = ap_get_server_port(r); + if (ap_is_default_port(port, r)) { + thisport = ""; + } + else { + thisport = apr_psprintf(r->pool, ":%u", port); + } + thisurl = apr_table_get(r->subprocess_env, ENVVAR_SCRIPT_URL); + + /* set the variable */ + var = apr_pstrcat(r->pool, ap_http_scheme(r), "://", thisserver, thisport, + thisurl, NULL); + apr_table_setn(r->subprocess_env, ENVVAR_SCRIPT_URI, var); + + if (!(saved_rulestatus = apr_table_get(r->notes,"mod_rewrite_rewritten"))) { + /* if filename was not initially set, + * we start with the requested URI + */ + if (r->filename == NULL) { + r->filename = apr_pstrdup(r->pool, r->uri); + rewritelog((r, 2, NULL, "init rewrite engine with requested uri %s", + r->filename)); + } + else { + rewritelog((r, 2, NULL, "init rewrite engine with passed filename " + "%s. Original uri = %s", r->filename, r->uri)); + } + + /* + * now apply the rules ... + */ + rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL); + apr_table_set(r->notes,"mod_rewrite_rewritten", + apr_psprintf(r->pool,"%d",rulestatus)); + } + else { + rewritelog((r, 2, NULL, "uri already rewritten. Status %s, Uri %s, " + "r->filename %s", saved_rulestatus, r->uri, r->filename)); + + rulestatus = atoi(saved_rulestatus); + } + + if (rulestatus) { + unsigned skip; + apr_size_t flen; + + if (ACTION_STATUS == rulestatus) { + int n = r->status; + + r->status = HTTP_OK; + return n; + } + + flen = r->filename ? strlen(r->filename) : 0; + if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + /* it should be go on as an internal proxy request */ + + /* check if the proxy module is enabled, so + * we can actually use it! + */ + if (!proxy_available) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "attempt to make remote request from mod_rewrite " + "without proxy enabled: %s", r->filename); + return HTTP_FORBIDDEN; + } + + /* make sure the QUERY_STRING and + * PATH_INFO parts get incorporated + */ + if (r->path_info != NULL) { + r->filename = apr_pstrcat(r->pool, r->filename, + r->path_info, NULL); + } + if (r->args != NULL && + r->uri == r->unparsed_uri) { + /* see proxy_http:proxy_http_canon() */ + r->filename = apr_pstrcat(r->pool, r->filename, + "?", r->args, NULL); + } + + /* now make sure the request gets handled by the proxy handler */ + if (PROXYREQ_NONE == r->proxyreq) { + r->proxyreq = PROXYREQ_REVERSE; + } + r->handler = "proxy-server"; + + rewritelog((r, 1, NULL, "go-ahead with proxy request %s [OK]", + r->filename)); + return OK; + } + else if ((skip = is_absolute_uri(r->filename)) > 0) { + int n; + + /* it was finally rewritten to a remote URL */ + + if (rulestatus != ACTION_NOESCAPE) { + rewritelog((r, 1, NULL, "escaping %s for redirect", + r->filename)); + r->filename = escape_absolute_uri(r->pool, r->filename, skip); + } + + /* append the QUERY_STRING part */ + if (r->args) { + r->filename = apr_pstrcat(r->pool, r->filename, "?", + (rulestatus == ACTION_NOESCAPE) + ? r->args + : ap_escape_uri(r->pool, r->args), + NULL); + } + + /* determine HTTP redirect response code */ + if (ap_is_HTTP_REDIRECT(r->status)) { + n = r->status; + r->status = HTTP_OK; /* make Apache kernel happy */ + } + else { + n = HTTP_MOVED_TEMPORARILY; + } + + /* now do the redirection */ + apr_table_setn(r->headers_out, "Location", r->filename); + rewritelog((r, 1, NULL, "redirect to %s [REDIRECT/%d]", r->filename, + n)); + + return n; + } + else if (flen > 12 && strncmp(r->filename, "passthrough:", 12) == 0) { + /* + * Hack because of underpowered API: passing the current + * rewritten filename through to other URL-to-filename handlers + * just as it were the requested URL. This is to enable + * post-processing by mod_alias, etc. which always act on + * r->uri! The difference here is: We do not try to + * add the document root + */ + r->uri = apr_pstrdup(r->pool, r->filename+12); + return DECLINED; + } + else { + /* it was finally rewritten to a local path */ + + /* expand "/~user" prefix */ +#if APR_HAS_USER + r->filename = expand_tildepaths(r, r->filename); +#endif + rewritelog((r, 2, NULL, "local path result: %s", r->filename)); + + /* the filename must be either an absolute local path or an + * absolute local URL. + */ + if ( *r->filename != '/' + && !ap_os_is_path_absolute(r->pool, r->filename)) { + return HTTP_BAD_REQUEST; + } + + /* if there is no valid prefix, we call + * the translator from the core and + * prefix the filename with document_root + * + * NOTICE: + * We cannot leave out the prefix_stat because + * - when we always prefix with document_root + * then no absolute path can be created, e.g. via + * emulating a ScriptAlias directive, etc. + * - when we always NOT prefix with document_root + * then the files under document_root have to + * be references directly and document_root + * gets never used and will be a dummy parameter - + * this is also bad + * + * BUT: + * Under real Unix systems this is no problem, + * because we only do stat() on the first directory + * and this gets cached by the kernel for along time! + */ + if (!prefix_stat(r->filename, r->pool)) { + int res; + char *tmp = r->uri; + + r->uri = r->filename; + res = ap_core_translate(r); + r->uri = tmp; + + if (res != OK) { + rewritelog((r, 1, NULL, "prefixing with document_root of %s" + " FAILED", r->filename)); + + return res; + } + + rewritelog((r, 2, NULL, "prefixed with document_root to %s", + r->filename)); + } + + rewritelog((r, 1, NULL, "go-ahead with %s [OK]", r->filename)); + return OK; + } + } + else { + rewritelog((r, 1, NULL, "pass through %s", r->filename)); + return DECLINED; + } +} + +/* + * Fixup hook + * [RewriteRules in directory context] + */ +static int hook_fixup(request_rec *r) +{ + rewrite_perdir_conf *dconf; + char *cp; + char *cp2; + const char *ccp; + apr_size_t l; + int rulestatus; + int n; + char *ofilename; + int is_proxyreq; + + dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config, + &rewrite_module); + + /* if there is no per-dir config we return immediately */ + if (dconf == NULL) { + return DECLINED; + } + + /* if there are no real (i.e. no RewriteRule directives!) + per-dir config of us, we return also immediately */ + if (dconf->directory == NULL) { + return DECLINED; + } + + /* + * Proxy request? + */ + is_proxyreq = ( r->proxyreq && r->filename + && !strncmp(r->filename, "proxy:", 6)); + + /* + * .htaccess file is called before really entering the directory, i.e.: + * URL: http://localhost/foo and .htaccess is located in foo directory + * Ignore such attempts, since they may lead to undefined behaviour. + */ + if (!is_proxyreq) { + l = strlen(dconf->directory) - 1; + if (r->filename && strlen(r->filename) == l && + (dconf->directory)[l] == '/' && + !strncmp(r->filename, dconf->directory, l)) { + return DECLINED; + } + } + + /* + * only do something under runtime if the engine is really enabled, + * for this directory, else return immediately! + */ + if (dconf->state == ENGINE_DISABLED) { + return DECLINED; + } + + /* + * Do the Options check after engine check, so + * the user is able to explicitely turn RewriteEngine Off. + */ + if (!(ap_allow_options(r) & (OPT_SYM_LINKS | OPT_SYM_OWNER))) { + /* FollowSymLinks is mandatory! */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Options FollowSymLinks or SymLinksIfOwnerMatch is off " + "which implies that RewriteRule directive is forbidden: " + "%s", r->filename); + return HTTP_FORBIDDEN; + } + + /* + * remember the current filename before rewriting for later check + * to prevent deadlooping because of internal redirects + * on final URL/filename which can be equal to the inital one. + * also, we'll restore original r->filename if we decline this + * request + */ + ofilename = r->filename; + + if (r->filename == NULL) { + r->filename = apr_pstrdup(r->pool, r->uri); + rewritelog((r, 2, "init rewrite engine with requested uri %s", + r->filename)); + } + + /* + * now apply the rules ... + */ + rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory); + if (rulestatus) { + unsigned skip; + + if (ACTION_STATUS == rulestatus) { + int n = r->status; + + r->status = HTTP_OK; + return n; + } + + l = strlen(r->filename); + if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + /* it should go on as an internal proxy request */ + + /* make sure the QUERY_STRING and + * PATH_INFO parts get incorporated + * (r->path_info was already appended by the + * rewriting engine because of the per-dir context!) + */ + if (r->args != NULL) { + r->filename = apr_pstrcat(r->pool, r->filename, + "?", r->args, NULL); + } + + /* now make sure the request gets handled by the proxy handler */ + if (PROXYREQ_NONE == r->proxyreq) { + r->proxyreq = PROXYREQ_REVERSE; + } + r->handler = "proxy-server"; + + rewritelog((r, 1, dconf->directory, "go-ahead with proxy request " + "%s [OK]", r->filename)); + return OK; + } + else if ((skip = is_absolute_uri(r->filename)) > 0) { + /* it was finally rewritten to a remote URL */ + + /* because we are in a per-dir context + * first try to replace the directory with its base-URL + * if there is a base-URL available + */ + if (dconf->baseurl != NULL) { + /* skip 'scheme://' */ + cp = r->filename + skip; + + if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) { + rewritelog((r, 2, dconf->directory, + "trying to replace prefix %s with %s", + dconf->directory, dconf->baseurl)); + + /* I think, that hack needs an explanation: + * well, here is it: + * mod_rewrite was written for unix systems, were + * absolute file-system paths start with a slash. + * URL-paths _also_ start with slashes, so they + * can be easily compared with system paths. + * + * the following assumes, that the actual url-path + * may be prefixed by the current directory path and + * tries to replace the system path with the RewriteBase + * URL. + * That assumption is true if we use a RewriteRule like + * + * RewriteRule ^foo bar [R] + * + * (see apply_rewrite_rule function) + * However on systems that don't have a / as system + * root this will never match, so we skip the / after the + * hostname and compare/substitute only the stuff after it. + * + * (note that cp was already increased to the right value) + */ + cp2 = subst_prefix_path(r, cp, (*dconf->directory == '/') + ? dconf->directory + 1 + : dconf->directory, + dconf->baseurl + 1); + if (strcmp(cp2, cp) != 0) { + *cp = '\0'; + r->filename = apr_pstrcat(r->pool, r->filename, + cp2, NULL); + } + } + } + + /* now prepare the redirect... */ + if (rulestatus != ACTION_NOESCAPE) { + rewritelog((r, 1, dconf->directory, "escaping %s for redirect", + r->filename)); + r->filename = escape_absolute_uri(r->pool, r->filename, skip); + } + + /* append the QUERY_STRING part */ + if (r->args) { + r->filename = apr_pstrcat(r->pool, r->filename, "?", + (rulestatus == ACTION_NOESCAPE) + ? r->args + : ap_escape_uri(r->pool, r->args), + NULL); + } + + /* determine HTTP redirect response code */ + if (ap_is_HTTP_REDIRECT(r->status)) { + n = r->status; + r->status = HTTP_OK; /* make Apache kernel happy */ + } + else { + n = HTTP_MOVED_TEMPORARILY; + } + + /* now do the redirection */ + apr_table_setn(r->headers_out, "Location", r->filename); + rewritelog((r, 1, dconf->directory, "redirect to %s [REDIRECT/%d]", + r->filename, n)); + return n; + } + else { + /* it was finally rewritten to a local path */ + + /* if someone used the PASSTHROUGH flag in per-dir + * context we just ignore it. It is only useful + * in per-server context + */ + if (l > 12 && strncmp(r->filename, "passthrough:", 12) == 0) { + r->filename = apr_pstrdup(r->pool, r->filename+12); + } + + /* the filename must be either an absolute local path or an + * absolute local URL. + */ + if ( *r->filename != '/' + && !ap_os_is_path_absolute(r->pool, r->filename)) { + return HTTP_BAD_REQUEST; + } + + /* Check for deadlooping: + * At this point we KNOW that at least one rewriting + * rule was applied, but when the resulting URL is + * the same as the initial URL, we are not allowed to + * use the following internal redirection stuff because + * this would lead to a deadloop. + */ + if (ofilename != NULL && strcmp(r->filename, ofilename) == 0) { + rewritelog((r, 1, dconf->directory, "initial URL equal rewritten" + " URL: %s [IGNORING REWRITE]", r->filename)); + return OK; + } + + /* if there is a valid base-URL then substitute + * the per-dir prefix with this base-URL if the + * current filename still is inside this per-dir + * context. If not then treat the result as a + * plain URL + */ + if (dconf->baseurl != NULL) { + rewritelog((r, 2, dconf->directory, "trying to replace prefix " + "%s with %s", dconf->directory, dconf->baseurl)); + + r->filename = subst_prefix_path(r, r->filename, + dconf->directory, + dconf->baseurl); + } + else { + /* if no explicit base-URL exists we assume + * that the directory prefix is also a valid URL + * for this webserver and only try to remove the + * document_root if it is prefix + */ + if ((ccp = ap_document_root(r)) != NULL) { + /* strip trailing slash */ + l = strlen(ccp); + if (ccp[l-1] == '/') { + --l; + } + if (!strncmp(r->filename, ccp, l) && + r->filename[l] == '/') { + rewritelog((r, 2,dconf->directory, "strip document_root" + " prefix: %s -> %s", r->filename, + r->filename+l)); + + r->filename = apr_pstrdup(r->pool, r->filename+l); + } + } + } + + /* now initiate the internal redirect */ + rewritelog((r, 1, dconf->directory, "internal redirect with %s " + "[INTERNAL REDIRECT]", r->filename)); + r->filename = apr_pstrcat(r->pool, "redirect:", r->filename, NULL); + r->handler = "redirect-handler"; + return OK; + } + } + else { + rewritelog((r, 1, dconf->directory, "pass through %s", r->filename)); + r->filename = ofilename; + return DECLINED; + } +} + +/* + * MIME-type hook + * [T=...,H=...] execution + */ +static int hook_mimetype(request_rec *r) +{ + const char *t; + + /* type */ + t = apr_table_get(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR); + if (t && *t) { + rewritelog((r, 1, NULL, "force filename %s to have MIME-type '%s'", + r->filename, t)); + + ap_set_content_type(r, t); + } + + /* handler */ + t = apr_table_get(r->notes, REWRITE_FORCED_HANDLER_NOTEVAR); + if (t && *t) { + rewritelog((r, 1, NULL, "force filename %s to have the " + "Content-handler '%s'", r->filename, t)); + + r->handler = t; + } + + return OK; +} + + +/* + * "content" handler for internal redirects + */ +static int handler_redirect(request_rec *r) +{ + if (strcmp(r->handler, "redirect-handler")) { + return DECLINED; + } + + /* just make sure that we are really meant! */ + if (strncmp(r->filename, "redirect:", 9) != 0) { + return DECLINED; + } + + /* now do the internal redirect */ + ap_internal_redirect(apr_pstrcat(r->pool, r->filename+9, + r->args ? "?" : NULL, r->args, NULL), r); + + /* and return gracefully */ + return OK; +} + + +/* + * +-------------------------------------------------------+ + * | | + * | Module paraphernalia + * | | + * +-------------------------------------------------------+ + */ + +#ifdef REWRITELOG_DISABLED +static const char *fake_rewritelog(cmd_parms *cmd, void *dummy, const char *a1) +{ + return "RewriteLog and RewriteLogLevel are not supported by this build " + "of mod_rewrite because it was compiled using the " + "-DREWRITELOG_DISABLED compiler option. You have to recompile " + "mod_rewrite WITHOUT this option in order to use the rewrite log."; +} +#endif + +static const command_rec command_table[] = { + AP_INIT_FLAG( "RewriteEngine", cmd_rewriteengine, NULL, OR_FILEINFO, + "On or Off to enable or disable (default) the whole " + "rewriting engine"), + AP_INIT_ITERATE( "RewriteOptions", cmd_rewriteoptions, NULL, OR_FILEINFO, + "List of option strings to set"), + AP_INIT_TAKE1( "RewriteBase", cmd_rewritebase, NULL, OR_FILEINFO, + "the base URL of the per-directory context"), + AP_INIT_RAW_ARGS("RewriteCond", cmd_rewritecond, NULL, OR_FILEINFO, + "an input string and a to be applied regexp-pattern"), + AP_INIT_RAW_ARGS("RewriteRule", cmd_rewriterule, NULL, OR_FILEINFO, + "an URL-applied regexp-pattern and a substitution URL"), + AP_INIT_TAKE2( "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, + "a mapname and a filename"), + AP_INIT_TAKE1( "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, + "the filename of a lockfile used for inter-process " + "synchronization"), +#ifndef REWRITELOG_DISABLED + AP_INIT_TAKE1( "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, + "the filename of the rewriting logfile"), + AP_INIT_TAKE1( "RewriteLogLevel", cmd_rewriteloglevel, NULL, RSRC_CONF, + "the level of the rewriting logfile verbosity " + "(0=none, 1=std, .., 9=max)"), +#else + AP_INIT_TAKE1( "RewriteLog", fake_rewritelog, NULL, RSRC_CONF, + "[DISABLED] the filename of the rewriting logfile"), + AP_INIT_TAKE1( "RewriteLogLevel", fake_rewritelog, NULL, RSRC_CONF, + "[DISABLED] the level of the rewriting logfile verbosity"), +#endif + { NULL } +}; + +static void ap_register_rewrite_mapfunc(char *name, rewrite_mapfunc_t *func) +{ + apr_hash_set(mapfunc_hash, name, strlen(name), (const void *)func); +} + +static void register_hooks(apr_pool_t *p) +{ + /* fixup after mod_proxy, so that the proxied url will not + * escaped accidentally by mod_proxy's fixup. + */ + static const char * const aszPre[]={ "mod_proxy.c", NULL }; + + APR_REGISTER_OPTIONAL_FN(ap_register_rewrite_mapfunc); + + ap_hook_handler(handler_redirect, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(init_child, NULL, NULL, APR_HOOK_MIDDLE); + + ap_hook_fixups(hook_fixup, aszPre, NULL, APR_HOOK_FIRST); + ap_hook_fixups(hook_mimetype, NULL, NULL, APR_HOOK_LAST); + ap_hook_translate_name(hook_uri2file, NULL, NULL, APR_HOOK_FIRST); +} + + /* the main config structure */ +module AP_MODULE_DECLARE_DATA rewrite_module = { + STANDARD20_MODULE_STUFF, + config_perdir_create, /* create per-dir config structures */ + config_perdir_merge, /* merge per-dir config structures */ + config_server_create, /* create per-server config structures */ + config_server_merge, /* merge per-server config structures */ + command_table, /* table of config file commands */ + register_hooks /* register hooks */ +}; + +/*EOF*/ diff --git a/trunk/modules/mappers/mod_rewrite.dsp b/trunk/modules/mappers/mod_rewrite.dsp new file mode 100644 index 0000000000..5daec345a5 --- /dev/null +++ b/trunk/modules/mappers/mod_rewrite.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_rewrite" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_rewrite - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_rewrite.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_rewrite.mak" CFG="mod_rewrite - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_rewrite - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_rewrite - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_rewrite - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_rewrite_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_rewrite - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_rewrite_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_rewrite.so" /base:@..\..\os\win32\BaseAddr.ref,mod_rewrite.so + +!ENDIF + +# Begin Target + +# Name "mod_rewrite - Win32 Release" +# Name "mod_rewrite - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_rewrite.c +# End Source File +# Begin Source File + +SOURCE=.\mod_rewrite.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_rewrite - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_rewrite.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_rewrite.so "rewrite_module for Apache" ../../include/ap_release.h > .\mod_rewrite.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_rewrite - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_rewrite.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_rewrite.so "rewrite_module for Apache" ../../include/ap_release.h > .\mod_rewrite.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_rewrite.exp b/trunk/modules/mappers/mod_rewrite.exp new file mode 100644 index 0000000000..8f2165bfe0 --- /dev/null +++ b/trunk/modules/mappers/mod_rewrite.exp @@ -0,0 +1 @@ +rewrite_module diff --git a/trunk/modules/mappers/mod_rewrite.h b/trunk/modules/mappers/mod_rewrite.h new file mode 100644 index 0000000000..08f8735854 --- /dev/null +++ b/trunk/modules/mappers/mod_rewrite.h @@ -0,0 +1,30 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_REWRITE_H +#define MOD_REWRITE_H 1 + +#include "apr_optional.h" +#include "httpd.h" + +/* rewrite map function prototype */ +typedef char *(rewrite_mapfunc_t)(request_rec *r, char *key); + +/* optional function declaration */ +APR_DECLARE_OPTIONAL_FN(void, ap_register_rewrite_mapfunc, + (char *name, rewrite_mapfunc_t *func)); + +#endif /* MOD_REWRITE_H */ diff --git a/trunk/modules/mappers/mod_so.c b/trunk/modules/mappers/mod_so.c new file mode 100644 index 0000000000..58e1a4444d --- /dev/null +++ b/trunk/modules/mappers/mod_so.c @@ -0,0 +1,431 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This module is used to load Apache modules at runtime. This means that the + * server functionality can be extended without recompiling and even without + * taking the server down at all. Only a HUP or AP_SIG_GRACEFUL signal + * needs to be sent to the server to reload the dynamically loaded modules. + * + * To use, you'll first need to build your module as a shared library, then + * update your configuration (httpd.conf) to get the Apache core to load the + * module at start-up. + * + * The easiest way to build a module as a shared library is to use the + * `SharedModule' command in the Configuration file, instead of `AddModule'. + * You should also change the file extension from `.o' to `.so'. So, for + * example, to build the status module as a shared library edit Configuration + * and change + * AddModule modules/standard/mod_status.o + * to + * SharedModule modules/standard/mod_status.so + * + * Run Configure and make. Now Apache's httpd binary will _not_ include + * mod_status. Instead a shared object called mod_status.so will be build, in + * the modules/standard directory. You can build most of the modules as shared + * libraries like this. + * + * To use the shared module, move the .so file(s) into an appropriate + * directory. You might like to create a directory called "modules" under you + * server root for this (e.g. /usr/local/httpd/modules). + * + * Then edit your conf/httpd.conf file, and add LoadModule lines. For + * example + * LoadModule status_module modules/mod_status.so + * + * The first argument is the module's structure name (look at the end of the + * module source to find this). The second option is the path to the module + * file, relative to the server root. Put these directives right at the top + * of your httpd.conf file. + * + * Now you can start Apache. A message will be logged at "debug" level to your + * error_log to confirm that the module(s) are loaded (use "LogLevel debug" + * directive to get these log messages). + * + * If you edit the LoadModule directives while the server is live you can get + * Apache to re-load the modules by sending it a HUP or AP_SIG_GRACEFUL + * signal as normal. You can use this to dynamically change the capability + * of your server without bringing it down. + * + * Because currently there is only limited builtin support in the Configure + * script for creating the shared library files (`.so'), please consult your + * vendors cc(1), ld(1) and dlopen(3) manpages to find out the appropriate + * compiler and linker flags and insert them manually into the Configuration + * file under CFLAGS_SHLIB, LDFLAGS_SHLIB and LDFLAGS_SHLIB_EXPORT. + * + * If you still have problems figuring out the flags both try the paper + * http://developer.netscape.com/library/documentation/enterprise + * /unix/svrplug.htm#1013807 + * or install a Perl 5 interpreter on your platform and then run the command + * + * $ perl -V:usedl -V:ccdlflags -V:cccdlflags -V:lddlflags + * + * This gives you what type of dynamic loading Perl 5 uses on your platform + * and which compiler and linker flags Perl 5 uses to create the shared object + * files. + * + * Another location where you can find useful hints is the `ltconfig' script + * of the GNU libtool 1.2 package. Search for your platform name inside the + * various "case" constructs. + * + */ + +#include "apr.h" +#include "apr_dso.h" +#include "apr_strings.h" +#include "apr_errno.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_core.h" + +#include "mod_so.h" + +module AP_MODULE_DECLARE_DATA so_module; + + +/* + * Server configuration to keep track of actually + * loaded modules and the corresponding module name. + */ + +typedef struct so_server_conf { + apr_array_header_t *loaded_modules; +} so_server_conf; + +static void *so_sconf_create(apr_pool_t *p, server_rec *s) +{ + so_server_conf *soc; + + soc = (so_server_conf *)apr_pcalloc(p, sizeof(so_server_conf)); + soc->loaded_modules = apr_array_make(p, DYNAMIC_MODULE_LIMIT, + sizeof(ap_module_symbol_t)); + + return (void *)soc; +} + +#ifndef NO_DLOPEN + +/* + * This is the cleanup for a loaded shared object. It unloads the module. + * This is called as a cleanup function from the core. + */ + +static apr_status_t unload_module(void *data) +{ + ap_module_symbol_t *modi = (ap_module_symbol_t*)data; + + /* only unload if module information is still existing */ + if (modi->modp == NULL) + return APR_SUCCESS; + + /* remove the module pointer from the core structure */ + ap_remove_loaded_module(modi->modp); + + /* destroy the module information */ + modi->modp = NULL; + modi->name = NULL; + return APR_SUCCESS; +} + +/* + * This is called for the directive LoadModule and actually loads + * a shared object file into the address space of the server process. + */ + +static const char *load_module(cmd_parms *cmd, void *dummy, + const char *modname, const char *filename) +{ + apr_dso_handle_t *modhandle; + apr_dso_handle_sym_t modsym; + module *modp; + const char *szModuleFile = ap_server_root_relative(cmd->pool, filename); + so_server_conf *sconf; + ap_module_symbol_t *modi; + ap_module_symbol_t *modie; + int i; + const char *error; + + /* we need to setup this value for dummy to make sure that we don't try + * to add a non-existant tree into the build when we return to + * execute_now. + */ + *(ap_directive_t **)dummy = NULL; + + if (!szModuleFile) { + return apr_pstrcat(cmd->pool, "Invalid LoadModule path ", + filename, NULL); + } + + /* + * check for already existing module + * If it already exists, we have nothing to do + * Check both dynamically-loaded modules and statically-linked modules. + */ + sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config, + &so_module); + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; + for (i = 0; i < sconf->loaded_modules->nelts; i++) { + modi = &modie[i]; + if (modi->name != NULL && strcmp(modi->name, modname) == 0) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, + cmd->pool, "module %s is already loaded, skipping", + modname); + return NULL; + } + } + + for (i = 0; ap_preloaded_modules[i]; i++) { + const char *preload_name; + apr_size_t preload_len; + apr_size_t thismod_len; + + modp = ap_preloaded_modules[i]; + + /* make sure we're comparing apples with apples + * make sure name of preloaded module is mod_FOO.c + * make sure name of structure being loaded is FOO_module + */ + + if (memcmp(modp->name, "mod_", 4)) { + continue; + } + + preload_name = modp->name + strlen("mod_"); + preload_len = strlen(preload_name) - 2; + + if (strlen(modname) <= strlen("_module")) { + continue; + } + thismod_len = strlen(modname) - strlen("_module"); + if (strcmp(modname + thismod_len, "_module")) { + continue; + } + + if (thismod_len != preload_len) { + continue; + } + + if (!memcmp(modname, preload_name, preload_len)) { + return apr_pstrcat(cmd->pool, "module ", modname, + " is built-in and can't be loaded", + NULL); + } + } + + modi = apr_array_push(sconf->loaded_modules); + modi->name = modname; + + /* + * Load the file into the Apache address space + */ + if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) { + char my_error[256]; + + return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile, + " into server: ", + apr_dso_error(modhandle, my_error, sizeof(my_error)), + NULL); + } + ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, + "loaded module %s", modname); + + /* + * Retrieve the pointer to the module structure through the module name: + * First with the hidden variant (prefix `AP_') and then with the plain + * symbol name. + */ + if (apr_dso_sym(&modsym, modhandle, modname) != APR_SUCCESS) { + char my_error[256]; + + return apr_pstrcat(cmd->pool, "Can't locate API module structure `", + modname, "' in file ", szModuleFile, ": ", + apr_dso_error(modhandle, my_error, sizeof(my_error)), + NULL); + } + modp = (module*) modsym; + modp->dynamic_load_handle = (apr_dso_handle_t *)modhandle; + modi->modp = modp; + + /* + * Make sure the found module structure is really a module structure + * + */ + if (modp->magic != MODULE_MAGIC_COOKIE) { + return apr_pstrcat(cmd->pool, "API module structure `", modname, + "' in file ", szModuleFile, " is garbled -" + " perhaps this is not an Apache module DSO?", NULL); + } + + /* + * Add this module to the Apache core structures + */ + error = ap_add_loaded_module(modp, cmd->pool); + if (error) { + return error; + } + + /* + * Register a cleanup in the config apr_pool_t (normally pconf). When + * we do a restart (or shutdown) this cleanup will cause the + * shared object to be unloaded. + */ + apr_pool_cleanup_register(cmd->pool, modi, unload_module, apr_pool_cleanup_null); + + /* + * Finally we need to run the configuration process for the module + */ + ap_single_module_configure(cmd->pool, cmd->server, modp); + + return NULL; +} + +/* + * This implements the LoadFile directive and loads an arbitrary + * shared object file into the adress space of the server process. + */ + +static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) +{ + apr_dso_handle_t *handle; + const char *file; + + file = ap_server_root_relative(cmd->pool, filename); + + if (!file) { + return apr_pstrcat(cmd->pool, "Invalid LoadFile path ", + filename, NULL); + } + + if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) { + char my_error[256]; + + return apr_pstrcat(cmd->pool, "Cannot load ", filename, + " into server: ", + apr_dso_error(handle, my_error, sizeof(my_error)), + NULL); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "loaded file %s", filename); + + return NULL; +} + +static module *ap_find_loaded_module_symbol(server_rec *s, const char *modname) +{ + so_server_conf *sconf; + ap_module_symbol_t *modi; + ap_module_symbol_t *modie; + int i; + + sconf = (so_server_conf *)ap_get_module_config(s->module_config, + &so_module); + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; + + for (i = 0; i < sconf->loaded_modules->nelts; i++) { + modi = &modie[i]; + if (modi->name != NULL && strcmp(modi->name, modname) == 0) { + return modi->modp; + } + } + return NULL; +} + +static void dump_loaded_modules(apr_pool_t *p, server_rec *s) +{ + ap_module_symbol_t *modie; + ap_module_symbol_t *modi; + so_server_conf *sconf; + int i; + apr_file_t *out = NULL; + + if (!ap_exists_config_define("DUMP_MODULES")) { + return; + } + + apr_file_open_stderr(&out, p); + + apr_file_printf(out, "Loaded Modules:\n"); + + sconf = (so_server_conf *)ap_get_module_config(s->module_config, + &so_module); + for (i = 0; ; i++) { + modi = &ap_prelinked_module_symbols[i]; + if (modi->name != NULL) { + apr_file_printf(out, " %s (static)\n", modi->name); + } + else { + break; + } + } + + modie = (ap_module_symbol_t *)sconf->loaded_modules->elts; + for (i = 0; i < sconf->loaded_modules->nelts; i++) { + modi = &modie[i]; + if (modi->name != NULL) { + apr_file_printf(out, " %s (shared)\n", modi->name); + } + } +} + +#else /* not NO_DLOPEN */ + +static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) +{ + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, + "WARNING: LoadFile not supported on this platform"); + return NULL; +} + +static const char *load_module(cmd_parms *cmd, void *dummy, + const char *modname, const char *filename) +{ + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, cmd->pool, + "WARNING: LoadModule not supported on this platform"); + return NULL; +} + +#endif /* NO_DLOPEN */ + +static void register_hooks(apr_pool_t *p) +{ +#ifndef NO_DLOPEN + APR_REGISTER_OPTIONAL_FN(ap_find_loaded_module_symbol); + ap_hook_test_config(dump_loaded_modules, NULL, NULL, APR_HOOK_MIDDLE); +#endif +} + +static const command_rec so_cmds[] = { + AP_INIT_TAKE2("LoadModule", load_module, NULL, RSRC_CONF | EXEC_ON_READ, + "a module name and the name of a shared object file to load it from"), + AP_INIT_ITERATE("LoadFile", load_file, NULL, RSRC_CONF | EXEC_ON_READ, + "shared object file or library to load into the server at runtime"), + { NULL } +}; + +module AP_MODULE_DECLARE_DATA so_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config */ + NULL, /* merge per-dir config */ + so_sconf_create, /* server config */ + NULL, /* merge server config */ + so_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_so.h b/trunk/modules/mappers/mod_so.h new file mode 100644 index 0000000000..514ba6c932 --- /dev/null +++ b/trunk/modules/mappers/mod_so.h @@ -0,0 +1,27 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_SO_H +#define MOD_SO_H 1 + +#include "apr_optional.h" +#include "httpd.h" + +/* optional function declaration */ +APR_DECLARE_OPTIONAL_FN(module *, ap_find_loaded_module_symbol, + (server_rec *s, const char *modname)); + +#endif /* MOD_SO_H */ + diff --git a/trunk/modules/mappers/mod_speling.c b/trunk/modules/mappers/mod_speling.c new file mode 100644 index 0000000000..a89bf449ee --- /dev/null +++ b/trunk/modules/mappers/mod_speling.c @@ -0,0 +1,533 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_file_io.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define WANT_BASENAME_MATCH + +#include "httpd.h" +#include "http_core.h" +#include "http_config.h" +#include "http_request.h" +#include "http_log.h" + +/* mod_speling.c - by Alexei Kosut June, 1996 + * + * This module is transparent, and simple. It attempts to correct + * misspellings of URLs that users might have entered, namely by checking + * capitalizations. If it finds a match, it sends a redirect. + * + * 08-Aug-1997 + * o Upgraded module interface to apache_1.3a2-dev API (more NULL's in + * speling_module). + * o Integrated tcsh's "spelling correction" routine which allows one + * misspelling (character insertion/omission/typo/transposition). + * Rewrote it to ignore case as well. This ought to catch the majority + * of misspelled requests. + * o Commented out the second pass where files' suffixes are stripped. + * Given the better hit rate of the first pass, this rather ugly + * (request index.html, receive index.db ?!?!) solution can be + * omitted. + * o wrote a "kind of" html page for mod_speling + * + * Activate it with "CheckSpelling On" + */ + +module AP_MODULE_DECLARE_DATA speling_module; + +typedef struct { + int enabled; +} spconfig; + +/* + * Create a configuration specific to this module for a server or directory + * location, and fill it with the default settings. + * + * The API says that in the absence of a merge function, the record for the + * closest ancestor is used exclusively. That's what we want, so we don't + * bother to have such a function. + */ + +static void *mkconfig(apr_pool_t *p) +{ + spconfig *cfg = apr_pcalloc(p, sizeof(spconfig)); + + cfg->enabled = 0; + return cfg; +} + +/* + * Respond to a callback to create configuration record for a server or + * vhost environment. + */ +static void *create_mconfig_for_server(apr_pool_t *p, server_rec *s) +{ + return mkconfig(p); +} + +/* + * Respond to a callback to create a config record for a specific directory. + */ +static void *create_mconfig_for_directory(apr_pool_t *p, char *dir) +{ + return mkconfig(p); +} + +/* + * Handler for the CheckSpelling directive, which is FLAG. + */ +static const char *set_speling(cmd_parms *cmd, void *mconfig, int arg) +{ + spconfig *cfg = (spconfig *) mconfig; + + cfg->enabled = arg; + return NULL; +} + +/* + * Define the directives specific to this module. This structure is referenced + * later by the 'module' structure. + */ +static const command_rec speling_cmds[] = +{ + AP_INIT_FLAG("CheckSpelling", set_speling, NULL, OR_OPTIONS, + "whether or not to fix miscapitalized/misspelled requests"), + { NULL } +}; + +typedef enum { + SP_IDENTICAL = 0, + SP_MISCAPITALIZED = 1, + SP_TRANSPOSITION = 2, + SP_MISSINGCHAR = 3, + SP_EXTRACHAR = 4, + SP_SIMPLETYPO = 5, + SP_VERYDIFFERENT = 6 +} sp_reason; + +static const char *sp_reason_str[] = +{ + "identical", + "miscapitalized", + "transposed characters", + "character missing", + "extra character", + "mistyped character", + "common basename", +}; + +typedef struct { + const char *name; + sp_reason quality; +} misspelled_file; + +/* + * spdist() is taken from Kernighan & Pike, + * _The_UNIX_Programming_Environment_ + * and adapted somewhat to correspond better to psychological reality. + * (Note the changes to the return values) + * + * According to Pollock and Zamora, CACM April 1984 (V. 27, No. 4), + * page 363, the correct order for this is: + * OMISSION = TRANSPOSITION > INSERTION > SUBSTITUTION + * thus, it was exactly backwards in the old version. -- PWP + * + * This routine was taken out of tcsh's spelling correction code + * (tcsh-6.07.04) and re-converted to apache data types ("char" type + * instead of tcsh's NLS'ed "Char"). Plus it now ignores the case + * during comparisons, so is a "approximate strcasecmp()". + * NOTE that is still allows only _one_ real "typo", + * it does NOT try to correct multiple errors. + */ + +static sp_reason spdist(const char *s, const char *t) +{ + for (; apr_tolower(*s) == apr_tolower(*t); t++, s++) { + if (*t == '\0') { + return SP_MISCAPITALIZED; /* exact match (sans case) */ + } + } + if (*s) { + if (*t) { + if (s[1] && t[1] && apr_tolower(*s) == apr_tolower(t[1]) + && apr_tolower(*t) == apr_tolower(s[1]) + && strcasecmp(s + 2, t + 2) == 0) { + return SP_TRANSPOSITION; /* transposition */ + } + if (strcasecmp(s + 1, t + 1) == 0) { + return SP_SIMPLETYPO; /* 1 char mismatch */ + } + } + if (strcasecmp(s + 1, t) == 0) { + return SP_EXTRACHAR; /* extra character */ + } + } + if (*t && strcasecmp(s, t + 1) == 0) { + return SP_MISSINGCHAR; /* missing character */ + } + return SP_VERYDIFFERENT; /* distance too large to fix. */ +} + +static int sort_by_quality(const void *left, const void *rite) +{ + return (int) (((misspelled_file *) left)->quality) + - (int) (((misspelled_file *) rite)->quality); +} + +static int check_speling(request_rec *r) +{ + spconfig *cfg; + char *good, *bad, *postgood, *url; + apr_finfo_t dirent; + int filoc, dotloc, urlen, pglen; + apr_array_header_t *candidates = NULL; + apr_dir_t *dir; + + cfg = ap_get_module_config(r->per_dir_config, &speling_module); + if (!cfg->enabled) { + return DECLINED; + } + + /* We only want to worry about GETs */ + if (r->method_number != M_GET) { + return DECLINED; + } + + /* We've already got a file of some kind or another */ + if (r->proxyreq || (r->finfo.filetype != 0)) { + return DECLINED; + } + + /* This is a sub request - don't mess with it */ + if (r->main) { + return DECLINED; + } + + /* we default to reject path info (same as core handler) */ + if ((r->used_path_info != AP_REQ_ACCEPT_PATH_INFO) && + r->path_info && *r->path_info) { + return DECLINED; + } + + /* + * The request should end up looking like this: + * r->uri: /correct-url/mispelling/more + * r->filename: /correct-file/mispelling r->path_info: /more + * + * So we do this in steps. First break r->filename into two pieces + */ + + filoc = ap_rind(r->filename, '/'); + /* + * Don't do anything if the request doesn't contain a slash, or + * requests "/" + */ + if (filoc == -1 || strcmp(r->uri, "/") == 0) { + return DECLINED; + } + + /* good = /correct-file */ + good = apr_pstrndup(r->pool, r->filename, filoc); + /* bad = mispelling */ + bad = apr_pstrdup(r->pool, r->filename + filoc + 1); + /* postgood = mispelling/more */ + postgood = apr_pstrcat(r->pool, bad, r->path_info, NULL); + + urlen = strlen(r->uri); + pglen = strlen(postgood); + + /* Check to see if the URL pieces add up */ + if (strcmp(postgood, r->uri + (urlen - pglen))) { + return DECLINED; + } + + /* url = /correct-url */ + url = apr_pstrndup(r->pool, r->uri, (urlen - pglen)); + + /* Now open the directory and do ourselves a check... */ + if (apr_dir_open(&dir, good, r->pool) != APR_SUCCESS) { + /* Oops, not a directory... */ + return DECLINED; + } + + candidates = apr_array_make(r->pool, 2, sizeof(misspelled_file)); + + dotloc = ap_ind(bad, '.'); + if (dotloc == -1) { + dotloc = strlen(bad); + } + + while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS) { + sp_reason q; + + /* + * If we end up with a "fixed" URL which is identical to the + * requested one, we must have found a broken symlink or some such. + * Do _not_ try to redirect this, it causes a loop! + */ + if (strcmp(bad, dirent.name) == 0) { + apr_dir_close(dir); + return OK; + } + + /* + * miscapitalization errors are checked first (like, e.g., lower case + * file, upper case request) + */ + else if (strcasecmp(bad, dirent.name) == 0) { + misspelled_file *sp_new; + + sp_new = (misspelled_file *) apr_array_push(candidates); + sp_new->name = apr_pstrdup(r->pool, dirent.name); + sp_new->quality = SP_MISCAPITALIZED; + } + + /* + * simple typing errors are checked next (like, e.g., + * missing/extra/transposed char) + */ + else if ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT) { + misspelled_file *sp_new; + + sp_new = (misspelled_file *) apr_array_push(candidates); + sp_new->name = apr_pstrdup(r->pool, dirent.name); + sp_new->quality = q; + } + + /* + * The spdist() should have found the majority of the misspelled + * requests. It is of questionable use to continue looking for + * files with the same base name, but potentially of totally wrong + * type (index.html <-> index.db). + * I would propose to not set the WANT_BASENAME_MATCH define. + * 08-Aug-1997 + * + * However, Alexei replied giving some reasons to add it anyway: + * > Oh, by the way, I remembered why having the + * > extension-stripping-and-matching stuff is a good idea: + * > + * > If you're using MultiViews, and have a file named foobar.html, + * > which you refer to as "foobar", and someone tried to access + * > "Foobar", mod_speling won't find it, because it won't find + * > anything matching that spelling. With the extension-munging, + * > it would locate "foobar.html". Not perfect, but I ran into + * > that problem when I first wrote the module. + */ + else { +#ifdef WANT_BASENAME_MATCH + /* + * Okay... we didn't find anything. Now we take out the hard-core + * power tools. There are several cases here. Someone might have + * entered a wrong extension (.htm instead of .html or vice + * versa) or the document could be negotiated. At any rate, now + * we just compare stuff before the first dot. If it matches, we + * figure we got us a match. This can result in wrong things if + * there are files of different content types but the same prefix + * (e.g. foo.gif and foo.html) This code will pick the first one + * it finds. Better than a Not Found, though. + */ + int entloc = ap_ind(dirent.name, '.'); + if (entloc == -1) { + entloc = strlen(dirent.name); + } + + if ((dotloc == entloc) + && !strncasecmp(bad, dirent.name, dotloc)) { + misspelled_file *sp_new; + + sp_new = (misspelled_file *) apr_array_push(candidates); + sp_new->name = apr_pstrdup(r->pool, dirent.name); + sp_new->quality = SP_VERYDIFFERENT; + } +#endif + } + } + apr_dir_close(dir); + + if (candidates->nelts != 0) { + /* Wow... we found us a mispelling. Construct a fixed url */ + char *nuri; + const char *ref; + misspelled_file *variant = (misspelled_file *) candidates->elts; + int i; + + ref = apr_table_get(r->headers_in, "Referer"); + + qsort((void *) candidates->elts, candidates->nelts, + sizeof(misspelled_file), sort_by_quality); + + /* + * Conditions for immediate redirection: + * a) the first candidate was not found by stripping the suffix + * AND b) there exists only one candidate OR the best match is not + * ambiguous + * then return a redirection right away. + */ + if (variant[0].quality != SP_VERYDIFFERENT + && (candidates->nelts == 1 + || variant[0].quality != variant[1].quality)) { + + nuri = ap_escape_uri(r->pool, apr_pstrcat(r->pool, url, + variant[0].name, + r->path_info, NULL)); + if (r->parsed_uri.query) + nuri = apr_pstrcat(r->pool, nuri, "?", r->parsed_uri.query, NULL); + + apr_table_setn(r->headers_out, "Location", + ap_construct_url(r->pool, nuri, r)); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, + r, + ref ? "Fixed spelling: %s to %s from %s" + : "Fixed spelling: %s to %s", + r->uri, nuri, ref); + + return HTTP_MOVED_PERMANENTLY; + } + /* + * Otherwise, a "[300] Multiple Choices" list with the variants is + * returned. + */ + else { + apr_pool_t *p; + apr_table_t *notes; + apr_pool_t *sub_pool; + apr_array_header_t *t; + apr_array_header_t *v; + + + if (r->main == NULL) { + p = r->pool; + notes = r->notes; + } + else { + p = r->main->pool; + notes = r->main->notes; + } + + if (apr_pool_create(&sub_pool, p) != APR_SUCCESS) + return DECLINED; + + t = apr_array_make(sub_pool, candidates->nelts * 8 + 8, + sizeof(char *)); + v = apr_array_make(sub_pool, candidates->nelts * 5, + sizeof(char *)); + + /* Generate the response text. */ + + *(const char **)apr_array_push(t) = + "The document name you requested ("; + *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, r->uri); + *(const char **)apr_array_push(t) = + ") could not be found on this server.\n" + "However, we found documents with names similar " + "to the one you requested.

    " + "Available documents:\n

      \n"; + + for (i = 0; i < candidates->nelts; ++i) { + char *vuri; + const char *reason; + + reason = sp_reason_str[(int) (variant[i].quality)]; + /* The format isn't very neat... */ + vuri = apr_pstrcat(sub_pool, url, variant[i].name, r->path_info, + (r->parsed_uri.query != NULL) ? "?" : "", + (r->parsed_uri.query != NULL) + ? r->parsed_uri.query : "", + NULL); + *(const char **)apr_array_push(v) = "\""; + *(const char **)apr_array_push(v) = ap_escape_uri(sub_pool, vuri); + *(const char **)apr_array_push(v) = "\";\""; + *(const char **)apr_array_push(v) = reason; + *(const char **)apr_array_push(v) = "\""; + + *(const char **)apr_array_push(t) = "
    • "; + *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, vuri); + *(const char **)apr_array_push(t) = " ("; + *(const char **)apr_array_push(t) = reason; + *(const char **)apr_array_push(t) = ")\n"; + + /* + * when we have printed the "close matches" and there are + * more "distant matches" (matched by stripping the suffix), + * then we insert an additional separator text to suggest + * that the user LOOK CLOSELY whether these are really the + * files she wanted. + */ + if (i > 0 && i < candidates->nelts - 1 + && variant[i].quality != SP_VERYDIFFERENT + && variant[i + 1].quality == SP_VERYDIFFERENT) { + *(const char **)apr_array_push(t) = + "
    \nFurthermore, the following related " + "documents were found:\n
      \n"; + } + } + *(const char **)apr_array_push(t) = "
    \n"; + + /* If we know there was a referring page, add a note: */ + if (ref != NULL) { + *(const char **)apr_array_push(t) = + "Please consider informing the owner of the " + "referring page " + "about the broken link.\n"; + } + + + /* Pass our apr_table_t to http_protocol.c (see mod_negotiation): */ + apr_table_setn(notes, "variant-list", apr_array_pstrcat(p, t, 0)); + + apr_table_mergen(r->subprocess_env, "VARIANTS", + apr_array_pstrcat(p, v, ',')); + + apr_pool_destroy(sub_pool); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + ref ? "Spelling fix: %s: %d candidates from %s" + : "Spelling fix: %s: %d candidates", + r->uri, candidates->nelts, ref); + + return HTTP_MULTIPLE_CHOICES; + } + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(check_speling,NULL,NULL,APR_HOOK_LAST); +} + +module AP_MODULE_DECLARE_DATA speling_module = +{ + STANDARD20_MODULE_STUFF, + create_mconfig_for_directory, /* create per-dir config */ + NULL, /* merge per-dir config */ + create_mconfig_for_server, /* server config */ + NULL, /* merge server config */ + speling_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_speling.dsp b/trunk/modules/mappers/mod_speling.dsp new file mode 100644 index 0000000000..035b420394 --- /dev/null +++ b/trunk/modules/mappers/mod_speling.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_speling" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_speling - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_speling.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_speling.mak" CFG="mod_speling - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_speling - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_speling - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_speling - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_speling_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_speling - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_speling_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_speling.so" /base:@..\..\os\win32\BaseAddr.ref,mod_speling.so + +!ENDIF + +# Begin Target + +# Name "mod_speling - Win32 Release" +# Name "mod_speling - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_speling.c +# End Source File +# Begin Source File + +SOURCE=.\mod_speling.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_speling - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_speling.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_speling.so "speling_module for Apache" ../../include/ap_release.h > .\mod_speling.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_speling - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_speling.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_speling.so "speling_module for Apache" ../../include/ap_release.h > .\mod_speling.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_speling.exp b/trunk/modules/mappers/mod_speling.exp new file mode 100644 index 0000000000..a6ee8b5034 --- /dev/null +++ b/trunk/modules/mappers/mod_speling.exp @@ -0,0 +1 @@ +speling_module diff --git a/trunk/modules/mappers/mod_userdir.c b/trunk/modules/mappers/mod_userdir.c new file mode 100644 index 0000000000..495f34054a --- /dev/null +++ b/trunk/modules/mappers/mod_userdir.c @@ -0,0 +1,369 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_userdir... implement the UserDir command. Broken away from the + * Alias stuff for a couple of good and not-so-good reasons: + * + * 1) It shows a real minimal working example of how to do something like + * this. + * 2) I know people who are actually interested in changing this *particular* + * aspect of server functionality without changing the rest of it. That's + * what this whole modular arrangement is supposed to be good at... + * + * Modified by Alexei Kosut to support the following constructs + * (server running at www.foo.com, request for /~bar/one/two.html) + * + * UserDir public_html -> ~bar/public_html/one/two.html + * UserDir /usr/web -> /usr/web/bar/one/two.html + * UserDir /home/ * /www -> /home/bar/www/one/two.html + * NOTE: theses ^ ^ space only added allow it to work in a comment, ignore + * UserDir http://x/users -> (302) http://x/users/bar/one/two.html + * UserDir http://x/ * /y -> (302) http://x/bar/y/one/two.html + * NOTE: here also ^ ^ + * + * In addition, you can use multiple entries, to specify alternate + * user directories (a la Directory Index). For example: + * + * UserDir public_html /usr/web http://www.xyz.com/users + * + * Modified by Ken Coar to provide for the following: + * + * UserDir disable[d] username ... + * UserDir enable[d] username ... + * + * If "disabled" has no other arguments, *all* ~ references are + * disabled, except those explicitly turned on with the "enabled" keyword. + */ + +#include "apr_strings.h" +#include "apr_user.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" + +#if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE) +#define HAVE_UNIX_SUEXEC +#endif + +#ifdef HAVE_UNIX_SUEXEC +#include "unixd.h" /* Contains the suexec_identity hook used on Unix */ +#endif + + +/* + * The default directory in user's home dir + * In the default install, the module is disabled + */ +#ifndef DEFAULT_USER_DIR +#define DEFAULT_USER_DIR NULL +#endif + +module AP_MODULE_DECLARE_DATA userdir_module; + +typedef struct { + int globally_disabled; + char *userdir; + apr_table_t *enabled_users; + apr_table_t *disabled_users; +} userdir_config; + +/* + * Server config for this module: global disablement flag, a list of usernames + * ineligible for UserDir access, a list of those immune to global (but not + * explicit) disablement, and the replacement string for all others. + */ + +static void *create_userdir_config(apr_pool_t *p, server_rec *s) +{ + userdir_config *newcfg = apr_pcalloc(p, sizeof(*newcfg)); + + newcfg->globally_disabled = 0; + newcfg->userdir = DEFAULT_USER_DIR; + newcfg->enabled_users = apr_table_make(p, 4); + newcfg->disabled_users = apr_table_make(p, 4); + + return newcfg; +} + +#define O_DEFAULT 0 +#define O_ENABLE 1 +#define O_DISABLE 2 + +static const char *set_user_dir(cmd_parms *cmd, void *dummy, const char *arg) +{ + userdir_config *s_cfg = ap_get_module_config(cmd->server->module_config, + &userdir_module); + char *username; + const char *usernames = arg; + char *kw = ap_getword_conf(cmd->pool, &usernames); + apr_table_t *usertable; + + /* Since we are a raw argument, it is possible for us to be called with + * zero arguments. So that we aren't ambiguous, flat out reject this. + */ + if (*kw == '\0') { + return "UserDir requires an argument."; + } + + /* + * Let's do the comparisons once. + */ + if ((!strcasecmp(kw, "disable")) || (!strcasecmp(kw, "disabled"))) { + /* + * If there are no usernames specified, this is a global disable - we + * need do no more at this point than record the fact. + */ + if (strlen(usernames) == 0) { + s_cfg->globally_disabled = 1; + return NULL; + } + usertable = s_cfg->disabled_users; + } + else if ((!strcasecmp(kw, "enable")) || (!strcasecmp(kw, "enabled"))) { + /* + * The "disable" keyword can stand alone or take a list of names, but + * the "enable" keyword requires the list. Whinge if it doesn't have + * it. + */ + if (strlen(usernames) == 0) { + return "UserDir \"enable\" keyword requires a list of usernames"; + } + usertable = s_cfg->enabled_users; + } + else { + /* + * If the first (only?) value isn't one of our keywords, just copy + * the string to the userdir string. + */ + s_cfg->userdir = apr_pstrdup(cmd->pool, arg); + return NULL; + } + /* + * Now we just take each word in turn from the command line and add it to + * the appropriate table. + */ + while (*usernames) { + username = ap_getword_conf(cmd->pool, &usernames); + apr_table_setn(usertable, username, kw); + } + return NULL; +} + +static const command_rec userdir_cmds[] = { + AP_INIT_RAW_ARGS("UserDir", set_user_dir, NULL, RSRC_CONF, + "the public subdirectory in users' home directories, or " + "'disabled', or 'disabled username username...', or " + "'enabled username username...'"), + {NULL} +}; + +static int translate_userdir(request_rec *r) +{ + ap_conf_vector_t *server_conf; + const userdir_config *s_cfg; + char *name = r->uri; + const char *userdirs; + const char *w, *dname; + char *redirect; + apr_finfo_t statbuf; + + /* + * If the URI doesn't match our basic pattern, we've nothing to do with + * it. + */ + if (name[0] != '/' || name[1] != '~') { + return DECLINED; + } + server_conf = r->server->module_config; + s_cfg = ap_get_module_config(server_conf, &userdir_module); + userdirs = s_cfg->userdir; + if (userdirs == NULL) { + return DECLINED; + } + + dname = name + 2; + w = ap_getword(r->pool, &dname, '/'); + + /* + * The 'dname' funny business involves backing it up to capture the '/' + * delimiting the "/~user" part from the rest of the URL, in case there + * was one (the case where there wasn't being just "GET /~user HTTP/1.0", + * for which we don't want to tack on a '/' onto the filename). + */ + + if (dname[-1] == '/') { + --dname; + } + + /* + * If there's no username, it's not for us. Ignore . and .. as well. + */ + if (w[0] == '\0' || (w[1] == '.' && (w[2] == '\0' || (w[2] == '.' && w[3] == '\0')))) { + return DECLINED; + } + /* + * Nor if there's an username but it's in the disabled list. + */ + if (apr_table_get(s_cfg->disabled_users, w) != NULL) { + return DECLINED; + } + /* + * If there's a global interdiction on UserDirs, check to see if this + * name is one of the Blessed. + */ + if (s_cfg->globally_disabled + && apr_table_get(s_cfg->enabled_users, w) == NULL) { + return DECLINED; + } + + /* + * Special cases all checked, onward to normal substitution processing. + */ + + while (*userdirs) { + const char *userdir = ap_getword_conf(r->pool, &userdirs); + char *filename = NULL, *x = NULL; + apr_status_t rv; + int is_absolute = ap_os_is_path_absolute(r->pool, userdir); + + if (ap_strchr_c(userdir, '*')) + x = ap_getword(r->pool, &userdir, '*'); + + if (userdir[0] == '\0' || is_absolute) { + if (x) { +#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 + * know of no protocols that are a single letter, ignore + * a : as the first or second character, and assume a file + * was specified + */ + if (strchr(x + 2, ':')) +#else + if (strchr(x, ':') && !is_absolute) +#endif /* HAVE_DRIVE_LETTERS */ + { + redirect = apr_pstrcat(r->pool, x, w, userdir, dname, NULL); + apr_table_setn(r->headers_out, "Location", redirect); + return HTTP_MOVED_TEMPORARILY; + } + else + filename = apr_pstrcat(r->pool, x, w, userdir, NULL); + } + else + filename = apr_pstrcat(r->pool, userdir, "/", w, NULL); + } + else if (x && ap_strchr_c(x, ':')) { + redirect = apr_pstrcat(r->pool, x, w, dname, NULL); + apr_table_setn(r->headers_out, "Location", redirect); + return HTTP_MOVED_TEMPORARILY; + } + else { +#if APR_HAS_USER + char *homedir; + + if (apr_uid_homepath_get(&homedir, w, r->pool) == APR_SUCCESS) { + filename = apr_pstrcat(r->pool, homedir, "/", userdir, NULL); + } +#else + return DECLINED; +#endif + } + + /* + * Now see if it exists, or we're at the last entry. If we are at the + * last entry, then use the filename generated (if there is one) + * anyway, in the hope that some handler might handle it. This can be + * used, for example, to run a CGI script for the user. + */ + if (filename && (!*userdirs + || ((rv = apr_stat(&statbuf, filename, APR_FINFO_MIN, + r->pool)) == APR_SUCCESS + || rv == APR_INCOMPLETE))) { + r->filename = apr_pstrcat(r->pool, filename, dname, NULL); + /* XXX: Does this walk us around FollowSymLink rules? + * When statbuf contains info on r->filename we can save a syscall + * by copying it to r->finfo + */ + if (*userdirs && dname[0] == 0) + r->finfo = statbuf; + + /* For use in the get_suexec_identity phase */ + apr_table_setn(r->notes, "mod_userdir_user", w); + + return OK; + } + } + + return DECLINED; +} + +#ifdef HAVE_UNIX_SUEXEC +static ap_unix_identity_t *get_suexec_id_doer(const request_rec *r) +{ + ap_unix_identity_t *ugid = NULL; +#if APR_HAS_USER + const char *username = apr_table_get(r->notes, "mod_userdir_user"); + + if (username == NULL) { + return NULL; + } + + if ((ugid = apr_palloc(r->pool, sizeof(*ugid))) == NULL) { + return NULL; + } + + if (apr_uid_get(&ugid->uid, &ugid->gid, username, r->pool) != APR_SUCCESS) { + return NULL; + } + + ugid->userdir = 1; +#endif + return ugid; +} +#endif /* HAVE_UNIX_SUEXEC */ + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[]={ "mod_alias.c",NULL }; + static const char * const aszSucc[]={ "mod_vhost_alias.c",NULL }; + + ap_hook_translate_name(translate_userdir,aszPre,aszSucc,APR_HOOK_MIDDLE); +#ifdef HAVE_UNIX_SUEXEC + ap_hook_get_suexec_identity(get_suexec_id_doer,NULL,NULL,APR_HOOK_FIRST); +#endif +} + +module AP_MODULE_DECLARE_DATA userdir_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_userdir_config, /* server config */ + NULL, /* merge server config */ + userdir_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/mappers/mod_userdir.dsp b/trunk/modules/mappers/mod_userdir.dsp new file mode 100644 index 0000000000..3bcadf6295 --- /dev/null +++ b/trunk/modules/mappers/mod_userdir.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_userdir" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_userdir - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_userdir.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_userdir.mak" CFG="mod_userdir - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_userdir - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_userdir - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_userdir - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_userdir_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_userdir - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_userdir_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_userdir.so" /base:@..\..\os\win32\BaseAddr.ref,mod_userdir.so + +!ENDIF + +# Begin Target + +# Name "mod_userdir - Win32 Release" +# Name "mod_userdir - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_userdir.c +# End Source File +# Begin Source File + +SOURCE=.\mod_userdir.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_userdir - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_userdir.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_userdir.so "userdir_module for Apache" ../../include/ap_release.h > .\mod_userdir.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_userdir - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_userdir.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_userdir.so "userdir_module for Apache" ../../include/ap_release.h > .\mod_userdir.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_userdir.exp b/trunk/modules/mappers/mod_userdir.exp new file mode 100644 index 0000000000..6b8b81d5c3 --- /dev/null +++ b/trunk/modules/mappers/mod_userdir.exp @@ -0,0 +1 @@ +userdir_module diff --git a/trunk/modules/mappers/mod_vhost_alias.c b/trunk/modules/mappers/mod_vhost_alias.c new file mode 100644 index 0000000000..c05860a3db --- /dev/null +++ b/trunk/modules/mappers/mod_vhost_alias.c @@ -0,0 +1,457 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_vhost_alias.c: support for dynamically configured mass virtual hosting + * + * Copyright (c) 1998-1999 Demon Internet Ltd. + * + * This software was submitted by Demon Internet to the Apache Software Foundation + * in May 1999. Future revisions and derivatives of this source code + * must acknowledge Demon Internet as the original contributor of + * this module. All other licensing and usage conditions are those + * of the Apache Software Foundation. + * + * Originally written by Tony Finch . + * + * Implementation ideas were taken from mod_alias.c. The overall + * concept is derived from the OVERRIDE_DOC_ROOT/OVERRIDE_CGIDIR + * patch to Apache 1.3b3 and a similar feature in Demon's thttpd, + * both written by James Grinter . + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_hooks.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" /* for ap_hook_translate_name */ + + +module AP_MODULE_DECLARE_DATA vhost_alias_module; + + +/* + * basic configuration things + * we abbreviate "mod_vhost_alias" to "mva" for shorter names + */ + +typedef enum { + VHOST_ALIAS_UNSET, VHOST_ALIAS_NONE, VHOST_ALIAS_NAME, VHOST_ALIAS_IP +} mva_mode_e; + +/* + * Per-server module config record. + */ +typedef struct mva_sconf_t { + const char *doc_root; + const char *cgi_root; + mva_mode_e doc_root_mode; + mva_mode_e cgi_root_mode; +} mva_sconf_t; + +static void *mva_create_server_config(apr_pool_t *p, server_rec *s) +{ + mva_sconf_t *conf; + + conf = (mva_sconf_t *) apr_pcalloc(p, sizeof(mva_sconf_t)); + conf->doc_root = NULL; + conf->cgi_root = NULL; + conf->doc_root_mode = VHOST_ALIAS_UNSET; + conf->cgi_root_mode = VHOST_ALIAS_UNSET; + return conf; +} + +static void *mva_merge_server_config(apr_pool_t *p, void *parentv, void *childv) +{ + mva_sconf_t *parent = (mva_sconf_t *) parentv; + mva_sconf_t *child = (mva_sconf_t *) childv; + mva_sconf_t *conf; + + conf = (mva_sconf_t *) apr_pcalloc(p, sizeof(*conf)); + if (child->doc_root_mode == VHOST_ALIAS_UNSET) { + conf->doc_root_mode = parent->doc_root_mode; + conf->doc_root = parent->doc_root; + } + else { + conf->doc_root_mode = child->doc_root_mode; + conf->doc_root = child->doc_root; + } + if (child->cgi_root_mode == VHOST_ALIAS_UNSET) { + conf->cgi_root_mode = parent->cgi_root_mode; + conf->cgi_root = parent->cgi_root; + } + else { + conf->cgi_root_mode = child->cgi_root_mode; + conf->cgi_root = child->cgi_root; + } + return conf; +} + + +/* + * These are just here to tell us what vhost_alias_set should do. + * We don't put anything into them; we just use the cell addresses. + */ +static int vhost_alias_set_doc_root_ip, + vhost_alias_set_cgi_root_ip, + vhost_alias_set_doc_root_name, + vhost_alias_set_cgi_root_name; + +static const char *vhost_alias_set(cmd_parms *cmd, void *dummy, const char *map) +{ + mva_sconf_t *conf; + mva_mode_e mode, *pmode; + const char **pmap; + const char *p; + + conf = (mva_sconf_t *) ap_get_module_config(cmd->server->module_config, + &vhost_alias_module); + /* there ought to be a better way of doing this */ + if (&vhost_alias_set_doc_root_ip == cmd->info) { + mode = VHOST_ALIAS_IP; + pmap = &conf->doc_root; + pmode = &conf->doc_root_mode; + } + else if (&vhost_alias_set_cgi_root_ip == cmd->info) { + mode = VHOST_ALIAS_IP; + pmap = &conf->cgi_root; + pmode = &conf->cgi_root_mode; + } + else if (&vhost_alias_set_doc_root_name == cmd->info) { + mode = VHOST_ALIAS_NAME; + pmap = &conf->doc_root; + pmode = &conf->doc_root_mode; + } + else if (&vhost_alias_set_cgi_root_name == cmd->info) { + mode = VHOST_ALIAS_NAME; + pmap = &conf->cgi_root; + pmode = &conf->cgi_root_mode; + } + else { + return "INTERNAL ERROR: unknown command info"; + } + + if (!ap_os_is_path_absolute(cmd->pool, map)) { + if (strcasecmp(map, "none")) { + return "format string must be an absolute path, or 'none'"; + } + *pmap = NULL; + *pmode = VHOST_ALIAS_NONE; + return NULL; + } + + /* sanity check */ + p = map; + while (*p != '\0') { + if (*p++ != '%') { + continue; + } + /* we just found a '%' */ + if (*p == 'p' || *p == '%') { + ++p; + continue; + } + /* optional dash */ + if (*p == '-') { + ++p; + } + /* digit N */ + if (apr_isdigit(*p)) { + ++p; + } + else { + return "syntax error in format string"; + } + /* optional plus */ + if (*p == '+') { + ++p; + } + /* do we end here? */ + if (*p != '.') { + continue; + } + ++p; + /* optional dash */ + if (*p == '-') { + ++p; + } + /* digit M */ + if (apr_isdigit(*p)) { + ++p; + } + else { + return "syntax error in format string"; + } + /* optional plus */ + if (*p == '+') { + ++p; + } + } + *pmap = map; + *pmode = mode; + return NULL; +} + +static const command_rec mva_commands[] = +{ + AP_INIT_TAKE1("VirtualScriptAlias", vhost_alias_set, + &vhost_alias_set_cgi_root_name, RSRC_CONF, + "how to create a ScriptAlias based on the host"), + AP_INIT_TAKE1("VirtualDocumentRoot", vhost_alias_set, + &vhost_alias_set_doc_root_name, RSRC_CONF, + "how to create the DocumentRoot based on the host"), + AP_INIT_TAKE1("VirtualScriptAliasIP", vhost_alias_set, + &vhost_alias_set_cgi_root_ip, RSRC_CONF, + "how to create a ScriptAlias based on the host"), + AP_INIT_TAKE1("VirtualDocumentRootIP", vhost_alias_set, + &vhost_alias_set_doc_root_ip, RSRC_CONF, + "how to create the DocumentRoot based on the host"), + { NULL } +}; + + +/* + * This really wants to be a nested function + * but C is too feeble to support them. + */ +static APR_INLINE void vhost_alias_checkspace(request_rec *r, char *buf, + char **pdest, int size) +{ + /* XXX: what if size > HUGE_STRING_LEN? */ + if (*pdest + size > buf + HUGE_STRING_LEN) { + **pdest = '\0'; + if (r->filename) { + r->filename = apr_pstrcat(r->pool, r->filename, buf, NULL); + } + else { + r->filename = apr_pstrdup(r->pool, buf); + } + *pdest = buf; + } +} + +static void vhost_alias_interpolate(request_rec *r, const char *name, + const char *map, const char *uri) +{ + /* 0..9 9..0 */ + enum { MAXDOTS = 19 }; + const char *dots[MAXDOTS+1]; + int ndots; + + char buf[HUGE_STRING_LEN]; + char *dest, last; + + int N, M, Np, Mp, Nd, Md; + const char *start, *end; + + const char *p; + + ndots = 0; + dots[ndots++] = name-1; /* slightly naughty */ + for (p = name; *p; ++p){ + if (*p == '.' && ndots < MAXDOTS) { + dots[ndots++] = p; + } + } + dots[ndots] = p; + + r->filename = NULL; + + dest = buf; + last = '\0'; + while (*map) { + if (*map != '%') { + /* normal characters */ + vhost_alias_checkspace(r, buf, &dest, 1); + last = *dest++ = *map++; + continue; + } + /* we are in a format specifier */ + ++map; + /* can't be a slash */ + last = '\0'; + /* %% -> % */ + if (*map == '%') { + ++map; + vhost_alias_checkspace(r, buf, &dest, 1); + *dest++ = '%'; + continue; + } + /* port number */ + if (*map == 'p') { + ++map; + /* no. of decimal digits in a short plus one */ + vhost_alias_checkspace(r, buf, &dest, 7); + dest += apr_snprintf(dest, 7, "%d", ap_get_server_port(r)); + continue; + } + /* deal with %-N+.-M+ -- syntax is already checked */ + N = M = 0; /* value */ + Np = Mp = 0; /* is there a plus? */ + Nd = Md = 0; /* is there a dash? */ + if (*map == '-') ++map, Nd = 1; + N = *map++ - '0'; + if (*map == '+') ++map, Np = 1; + if (*map == '.') { + ++map; + if (*map == '-') { + ++map, Md = 1; + } + M = *map++ - '0'; + if (*map == '+') { + ++map, Mp = 1; + } + } + /* note that N and M are one-based indices, not zero-based */ + start = dots[0]+1; /* ptr to the first character */ + end = dots[ndots]; /* ptr to the character after the last one */ + if (N != 0) { + if (N > ndots) { + start = "_"; + end = start+1; + } + else if (!Nd) { + start = dots[N-1]+1; + if (!Np) { + end = dots[N]; + } + } + else { + if (!Np) { + start = dots[ndots-N]+1; + } + end = dots[ndots-N+1]; + } + } + if (M != 0) { + if (M > end - start) { + start = "_"; + end = start+1; + } + else if (!Md) { + start = start+M-1; + if (!Mp) { + end = start+1; + } + } + else { + if (!Mp) { + start = end-M; + } + end = end-M+1; + } + } + vhost_alias_checkspace(r, buf, &dest, end - start); + for (p = start; p < end; ++p) { + *dest++ = apr_tolower(*p); + } + } + *dest = '\0'; + /* no double slashes */ + if (last == '/') { + ++uri; + } + + if (r->filename) { + r->filename = apr_pstrcat(r->pool, r->filename, buf, uri, NULL); + } + else { + r->filename = apr_pstrcat(r->pool, buf, uri, NULL); + } +} + +static int mva_translate(request_rec *r) +{ + mva_sconf_t *conf; + const char *name, *map, *uri; + mva_mode_e mode; + const char *cgi; + + conf = (mva_sconf_t *) ap_get_module_config(r->server->module_config, + &vhost_alias_module); + cgi = NULL; + if (conf->cgi_root) { + cgi = strstr(r->uri, "cgi-bin/"); + if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) { + cgi = NULL; + } + } + if (cgi) { + mode = conf->cgi_root_mode; + map = conf->cgi_root; + uri = cgi + strlen("cgi-bin"); + } + else if (r->uri[0] == '/') { + mode = conf->doc_root_mode; + map = conf->doc_root; + uri = r->uri; + } + else { + return DECLINED; + } + + if (mode == VHOST_ALIAS_NAME) { + name = ap_get_server_name(r); + } + else if (mode == VHOST_ALIAS_IP) { + name = r->connection->local_ip; + } + else { + return DECLINED; + } + + /* ### There is an optimization available here to determine the + * absolute portion of the path from the server config phase, + * through the first % segment, and note that portion of the path + * canonical_path buffer. + */ + r->canonical_filename = ""; + vhost_alias_interpolate(r, name, map, uri); + + if (cgi) { + /* see is_scriptaliased() in mod_cgi */ + r->handler = "cgi-script"; + apr_table_setn(r->notes, "alias-forced-type", r->handler); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[]={ "mod_alias.c","mod_userdir.c",NULL }; + + ap_hook_translate_name(mva_translate, aszPre, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA vhost_alias_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + mva_create_server_config, /* server config */ + mva_merge_server_config, /* merge server configs */ + mva_commands, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + diff --git a/trunk/modules/mappers/mod_vhost_alias.dsp b/trunk/modules/mappers/mod_vhost_alias.dsp new file mode 100644 index 0000000000..fece4f046c --- /dev/null +++ b/trunk/modules/mappers/mod_vhost_alias.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_vhost_alias" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_vhost_alias - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_vhost_alias.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_vhost_alias.mak" CFG="mod_vhost_alias - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_vhost_alias - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_vhost_alias - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_vhost_alias - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_vhost_alias_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_vhost_alias - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_vhost_alias_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_vhost_alias.so" /base:@..\..\os\win32\BaseAddr.ref,mod_vhost_alias.so + +!ENDIF + +# Begin Target + +# Name "mod_vhost_alias - Win32 Release" +# Name "mod_vhost_alias - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_vhost_alias.c +# End Source File +# Begin Source File + +SOURCE=.\mod_vhost_alias.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_vhost_alias - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_vhost_alias.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_vhost_alias.so "vhost_alias_module for Apache" ../../include/ap_release.h > .\mod_vhost_alias.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_vhost_alias - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_vhost_alias.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_vhost_alias.so "vhost_alias_module for Apache" ../../include/ap_release.h > .\mod_vhost_alias.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/mappers/mod_vhost_alias.exp b/trunk/modules/mappers/mod_vhost_alias.exp new file mode 100644 index 0000000000..b17666fc86 --- /dev/null +++ b/trunk/modules/mappers/mod_vhost_alias.exp @@ -0,0 +1 @@ +vhost_alias_module diff --git a/trunk/modules/metadata/.indent.pro b/trunk/modules/metadata/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/metadata/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/metadata/Makefile.in b/trunk/modules/metadata/Makefile.in new file mode 100644 index 0000000000..167b343d0d --- /dev/null +++ b/trunk/modules/metadata/Makefile.in @@ -0,0 +1,3 @@ + +include $(top_srcdir)/build/special.mk + diff --git a/trunk/modules/metadata/NWGNUcernmeta b/trunk/modules/metadata/NWGNUcernmeta new file mode 100644 index 0000000000..ffcd42a239 --- /dev/null +++ b/trunk/modules/metadata/NWGNUcernmeta @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = cernmeta + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) CERN Meta Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = CERN Meta Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/cernmeta.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_cern_meta.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + cern_meta_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUexpires b/trunk/modules/metadata/NWGNUexpires new file mode 100644 index 0000000000..5dff127faf --- /dev/null +++ b/trunk/modules/metadata/NWGNUexpires @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = expires + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Expires Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Expires Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/expires.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_expires.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + expires_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUheaders b/trunk/modules/metadata/NWGNUheaders new file mode 100644 index 0000000000..5c788a2f1c --- /dev/null +++ b/trunk/modules/metadata/NWGNUheaders @@ -0,0 +1,251 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/ssl \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = headers + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Headers Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Headers Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/headers.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_headers.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + headers_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUmakefile b/trunk/modules/metadata/NWGNUmakefile new file mode 100644 index 0000000000..58d1a19856 --- /dev/null +++ b/trunk/modules/metadata/NWGNUmakefile @@ -0,0 +1,253 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/cernmeta.nlm \ + $(OBJDIR)/expires.nlm \ + $(OBJDIR)/headers.nlm \ + $(OBJDIR)/mimemagi.nlm \ + $(OBJDIR)/modident.nlm \ + $(OBJDIR)/uniqueid.nlm \ + $(OBJDIR)/usertrk.nlm \ + $(OBJDIR)/modversion.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + diff --git a/trunk/modules/metadata/NWGNUmimemagi b/trunk/modules/metadata/NWGNUmimemagi new file mode 100644 index 0000000000..3c5f11a430 --- /dev/null +++ b/trunk/modules/metadata/NWGNUmimemagi @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mimemagi + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Mime Magic Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = CERN Meta Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mimemagi.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_mime_magic.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + mime_magic_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUmodident b/trunk/modules/metadata/NWGNUmodident new file mode 100644 index 0000000000..0677b43102 --- /dev/null +++ b/trunk/modules/metadata/NWGNUmodident @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = modident + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Remote User Identity Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Mod_Ident Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/modident.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_ident.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + ident_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUmodversion b/trunk/modules/metadata/NWGNUmodversion new file mode 100644 index 0000000000..9f97d64926 --- /dev/null +++ b/trunk/modules/metadata/NWGNUmodversion @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = modversion + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Version Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Version Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/$(NLM_NAME).nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_version.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + version_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUuniqueid b/trunk/modules/metadata/NWGNUuniqueid new file mode 100644 index 0000000000..699ac227c6 --- /dev/null +++ b/trunk/modules/metadata/NWGNUuniqueid @@ -0,0 +1,259 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = uniqueid + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Unique ID Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Unique ID Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/uniqueid.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_unique_id.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + unique_id_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/NWGNUusertrk b/trunk/modules/metadata/NWGNUusertrk new file mode 100644 index 0000000000..0249a0f929 --- /dev/null +++ b/trunk/modules/metadata/NWGNUusertrk @@ -0,0 +1,250 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = usertrk + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) User Track Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = User Track Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/usertrk.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_usertrack.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + usertrack_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/metadata/config.m4 b/trunk/modules/metadata/config.m4 new file mode 100644 index 0000000000..c970a71723 --- /dev/null +++ b/trunk/modules/metadata/config.m4 @@ -0,0 +1,23 @@ +dnl modules enabled in this directory by default + +dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + +APACHE_MODPATH_INIT(metadata) + +APACHE_MODULE(env, clearing/setting of ENV vars, , , yes) +APACHE_MODULE(mime_magic, automagically determining MIME type) +APACHE_MODULE(cern_meta, CERN-type meta files) +APACHE_MODULE(expires, Expires header control, , , most) +APACHE_MODULE(headers, HTTP header control, , , most) +APACHE_MODULE(ident, RFC 1413 identity check, , , most) + +APACHE_MODULE(usertrack, user-session tracking, , , , [ + AC_CHECK_HEADERS(sys/times.h) + AC_CHECK_FUNCS(times) +]) + +APACHE_MODULE(unique_id, per-request unique ids) +APACHE_MODULE(setenvif, basing ENV vars on headers, , , yes) +APACHE_MODULE(version, determining httpd version in config files) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/metadata/mod_cern_meta.c b/trunk/modules/metadata/mod_cern_meta.c new file mode 100644 index 0000000000..ebe5933154 --- /dev/null +++ b/trunk/modules/metadata/mod_cern_meta.c @@ -0,0 +1,371 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_cern_meta.c + * version 0.1.0 + * status beta + * + * Andrew Wilson 25.Jan.96 + * + * *** IMPORTANT *** + * This version of mod_cern_meta.c controls Meta File behaviour on a + * per-directory basis. Previous versions of the module defined behaviour + * on a per-server basis. The upshot is that you'll need to revisit your + * configuration files in order to make use of the new module. + * *** + * + * Emulate the CERN HTTPD Meta file semantics. Meta files are HTTP + * headers that can be output in addition to the normal range of + * headers for each file accessed. They appear rather like the Apache + * .asis files, and are able to provide a crude way of influencing + * the Expires: header, as well as providing other curiosities. + * There are many ways to manage meta information, this one was + * chosen because there is already a large number of CERN users + * who can exploit this module. It should be noted that there are probably + * more sensitive ways of managing the Expires: header specifically. + * + * The module obeys the following directives, which can appear + * in the server's .conf files and in .htaccess files. + * + * MetaFiles + * + * turns on|off meta file processing for any directory. + * Default value is off + * + * # turn on MetaFiles in this directory + * MetaFiles on + * + * MetaDir + * + * specifies the name of the directory in which Apache can find + * meta information files. The directory is usually a 'hidden' + * subdirectory of the directory that contains the file being + * accessed. eg: + * + * # .meta files are in the *same* directory as the + * # file being accessed + * MetaDir . + * + * the default is to look in a '.web' subdirectory. This is the + * same as for CERN 3.+ webservers and behaviour is the same as + * for the directive: + * + * MetaDir .web + * + * MetaSuffix + * + * specifies the file name suffix for the file containing the + * meta information. eg: + * + * # our meta files are suffixed with '.cern_meta' + * MetaSuffix .cern_meta + * + * the default is to look for files with the suffix '.meta'. This + * behaviour is the same as for the directive: + * + * MetaSuffix .meta + * + * When accessing the file + * + * DOCUMENT_ROOT/somedir/index.html + * + * this module will look for the file + * + * DOCUMENT_ROOT/somedir/.web/index.html.meta + * + * and will use its contents to generate additional MIME header + * information. + * + * For more information on the CERN Meta file semantics see: + * + * http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir + * + * Change-log: + * 29.Jan.96 pfopen/pfclose instead of fopen/fclose + * DECLINE when real file not found, we may be checking each + * of the index.html/index.shtml/index.htm variants and don't + * need to report missing ones as spurious errors. + * 31.Jan.96 log_error reports about a malformed .meta file, rather + * than a script error. + * 20.Jun.96 MetaFiles default off, added, so that module + * can be configured per-directory. Prior to this the module + * was running for each request anywhere on the server, naughty.. + * 29.Jun.96 All directives made per-directory. + */ + +#include "apr.h" +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_SYS_TYPES_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "util_script.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" +#include "apr_lib.h" + +#define DIR_CMD_PERMS OR_INDEXES + +#define DEFAULT_METADIR ".web" +#define DEFAULT_METASUFFIX ".meta" +#define DEFAULT_METAFILES 0 + +module AP_MODULE_DECLARE_DATA cern_meta_module; + +typedef struct { + const char *metadir; + const char *metasuffix; + int metafiles; +} cern_meta_dir_config; + +static void *create_cern_meta_dir_config(apr_pool_t *p, char *dummy) +{ + cern_meta_dir_config *new = + (cern_meta_dir_config *) apr_palloc(p, sizeof(cern_meta_dir_config)); + + new->metadir = NULL; + new->metasuffix = NULL; + new->metafiles = DEFAULT_METAFILES; + + return new; +} + +static void *merge_cern_meta_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + cern_meta_dir_config *base = (cern_meta_dir_config *) basev; + cern_meta_dir_config *add = (cern_meta_dir_config *) addv; + cern_meta_dir_config *new = + (cern_meta_dir_config *) apr_palloc(p, sizeof(cern_meta_dir_config)); + + new->metadir = add->metadir ? add->metadir : base->metadir; + new->metasuffix = add->metasuffix ? add->metasuffix : base->metasuffix; + new->metafiles = add->metafiles; + + return new; +} + +static const char *set_metadir(cmd_parms *parms, void *in_dconf, const char *arg) +{ + cern_meta_dir_config *dconf = in_dconf; + + dconf->metadir = arg; + return NULL; +} + +static const char *set_metasuffix(cmd_parms *parms, void *in_dconf, const char *arg) +{ + cern_meta_dir_config *dconf = in_dconf; + + dconf->metasuffix = arg; + return NULL; +} + +static const char *set_metafiles(cmd_parms *parms, void *in_dconf, int arg) +{ + cern_meta_dir_config *dconf = in_dconf; + + dconf->metafiles = arg; + return NULL; +} + + +static const command_rec cern_meta_cmds[] = +{ + AP_INIT_FLAG("MetaFiles", set_metafiles, NULL, DIR_CMD_PERMS, + "Limited to 'on' or 'off'"), + AP_INIT_TAKE1("MetaDir", set_metadir, NULL, DIR_CMD_PERMS, + "the name of the directory containing meta files"), + AP_INIT_TAKE1("MetaSuffix", set_metasuffix, NULL, DIR_CMD_PERMS, + "the filename suffix for meta files"), + {NULL} +}; + +/* XXX: this is very similar to ap_scan_script_header_err_core... + * are the differences deliberate, or just a result of bit rot? + */ +static int scan_meta_file(request_rec *r, apr_file_t *f) +{ + char w[MAX_STRING_LEN]; + char *l; + int p; + apr_table_t *tmp_headers; + + tmp_headers = apr_table_make(r->pool, 5); + while (apr_file_gets(w, MAX_STRING_LEN - 1, f) == APR_SUCCESS) { + + /* Delete terminal (CR?)LF */ + p = strlen(w); + if (p > 0 && w[p - 1] == '\n') { + if (p > 1 && w[p - 2] == '\015') + w[p - 2] = '\0'; + else + w[p - 1] = '\0'; + } + + if (w[0] == '\0') { + return OK; + } + + /* if we see a bogus header don't ignore it. Shout and scream */ + + if (!(l = strchr(w, ':'))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "malformed header in meta file: %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + *l++ = '\0'; + while (*l && apr_isspace(*l)) + ++l; + + if (!strcasecmp(w, "Content-type")) { + char *tmp; + /* Nuke trailing whitespace */ + + char *endp = l + strlen(l) - 1; + while (endp > l && apr_isspace(*endp)) + *endp-- = '\0'; + + tmp = apr_pstrdup(r->pool, l); + ap_content_type_tolower(tmp); + ap_set_content_type(r, tmp); + } + else if (!strcasecmp(w, "Status")) { + sscanf(l, "%d", &r->status); + r->status_line = apr_pstrdup(r->pool, l); + } + else { + apr_table_set(tmp_headers, w, l); + } + } + apr_table_overlap(r->headers_out, tmp_headers, APR_OVERLAP_TABLES_SET); + return OK; +} + +static int add_cern_meta_data(request_rec *r) +{ + char *metafilename; + char *leading_slash; + char *last_slash; + char *real_file; + char *scrap_book; + apr_file_t *f = NULL; + apr_status_t retcode; + cern_meta_dir_config *dconf; + int rv; + request_rec *rr; + + dconf = ap_get_module_config(r->per_dir_config, &cern_meta_module); + + if (!dconf->metafiles) { + return DECLINED; + }; + + /* if ./.web/$1.meta exists then output 'asis' */ + + if (r->finfo.filetype == 0) { + return DECLINED; + }; + + /* is this a directory? */ + if (r->finfo.filetype == APR_DIR || r->uri[strlen(r->uri) - 1] == '/') { + return DECLINED; + }; + + /* what directory is this file in? */ + scrap_book = apr_pstrdup(r->pool, r->filename); + + leading_slash = strchr(scrap_book, '/'); + last_slash = strrchr(scrap_book, '/'); + if ((last_slash != NULL) && (last_slash != leading_slash)) { + /* skip over last slash */ + real_file = last_slash; + real_file++; + *last_slash = '\0'; + } + else { + /* no last slash, buh?! */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "internal error in mod_cern_meta: %s", r->filename); + /* should really barf, but hey, let's be friends... */ + return DECLINED; + }; + + metafilename = apr_pstrcat(r->pool, scrap_book, "/", + dconf->metadir ? dconf->metadir : DEFAULT_METADIR, + "/", real_file, + dconf->metasuffix ? dconf->metasuffix : DEFAULT_METASUFFIX, + NULL); + + /* It sucks to require this subrequest to complete, because this + * means people must leave their meta files accessible to the world. + * A better solution might be a "safe open" feature of pfopen to avoid + * pipes, symlinks, and crap like that. + * + * In fact, this doesn't suck. Because blocks are never run + * against sub_req_lookup_file, the meta can be somewhat protected by + * either masking it with a directive or alias, or stowing + * the file outside of the web document tree, while providing the + * appropriate directory blocks to allow access to it as a file. + */ + rr = ap_sub_req_lookup_file(metafilename, r, NULL); + if (rr->status != HTTP_OK) { + ap_destroy_sub_req(rr); + return DECLINED; + } + ap_destroy_sub_req(rr); + + retcode = apr_file_open(&f, metafilename, APR_READ, APR_OS_DEFAULT, r->pool); + if (retcode != APR_SUCCESS) { + if (APR_STATUS_IS_ENOENT(retcode)) { + return DECLINED; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "meta file permissions deny server access: %s", metafilename); + return HTTP_FORBIDDEN; + }; + + /* read the headers in */ + rv = scan_meta_file(r, f); + apr_file_close(f); + + return rv; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(add_cern_meta_data,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA cern_meta_module = +{ + STANDARD20_MODULE_STUFF, + create_cern_meta_dir_config, /* dir config creater */ + merge_cern_meta_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + cern_meta_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_cern_meta.dsp b/trunk/modules/metadata/mod_cern_meta.dsp new file mode 100644 index 0000000000..91f32bb6cf --- /dev/null +++ b/trunk/modules/metadata/mod_cern_meta.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_cern_meta" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_cern_meta - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_cern_meta.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_cern_meta.mak" CFG="mod_cern_meta - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_cern_meta - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_cern_meta - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_cern_meta - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_cern_meta_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_cern_meta - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_cern_meta_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_cern_meta.so" /base:@..\..\os\win32\BaseAddr.ref,mod_cern_meta.so + +!ENDIF + +# Begin Target + +# Name "mod_cern_meta - Win32 Release" +# Name "mod_cern_meta - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_cern_meta.c +# End Source File +# Begin Source File + +SOURCE=.\mod_cern_meta.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_cern_meta - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cern_meta.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cern_meta.so "cern_meta_module for Apache" ../../include/ap_release.h > .\mod_cern_meta.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_cern_meta - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_cern_meta.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_cern_meta.so "cern_meta_module for Apache" ../../include/ap_release.h > .\mod_cern_meta.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_cern_meta.exp b/trunk/modules/metadata/mod_cern_meta.exp new file mode 100644 index 0000000000..d36e2be6a8 --- /dev/null +++ b/trunk/modules/metadata/mod_cern_meta.exp @@ -0,0 +1 @@ +cern_meta_module diff --git a/trunk/modules/metadata/mod_env.c b/trunk/modules/metadata/mod_env.c new file mode 100644 index 0000000000..abaed0192d --- /dev/null +++ b/trunk/modules/metadata/mod_env.c @@ -0,0 +1,179 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" + +#if APR_HAVE_STDLIB_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_log.h" + +typedef struct { + apr_table_t *vars; + apr_table_t *unsetenv; +} env_dir_config_rec; + +module AP_MODULE_DECLARE_DATA env_module; + +static void *create_env_dir_config(apr_pool_t *p, char *dummy) +{ + env_dir_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->vars = apr_table_make(p, 10); + conf->unsetenv = apr_table_make(p, 10); + + return conf; +} + +static void *merge_env_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + env_dir_config_rec *base = basev; + env_dir_config_rec *add = addv; + env_dir_config_rec *res = apr_palloc(p, sizeof(*res)); + + const apr_table_entry_t *elts; + const apr_array_header_t *arr; + + int i; + + /* + * res->vars = copy_table( p, base->vars ); + * foreach $unsetenv ( @add->unsetenv ) + * table_unset( res->vars, $unsetenv ); + * foreach $element ( @add->vars ) + * table_set( res->vars, $element.key, $element.val ); + * + * add->unsetenv already removed the vars from add->vars, + * if they preceeded the UnsetEnv directive. + */ + res->vars = apr_table_copy(p, base->vars); + res->unsetenv = NULL; + + arr = apr_table_elts(add->unsetenv); + if (arr) { + elts = (const apr_table_entry_t *)arr->elts; + + for (i = 0; i < arr->nelts; ++i) { + apr_table_unset(res->vars, elts[i].key); + } + } + + arr = apr_table_elts(add->vars); + if (arr) { + elts = (const apr_table_entry_t *)arr->elts; + + for (i = 0; i < arr->nelts; ++i) { + apr_table_setn(res->vars, elts[i].key, elts[i].val); + } + } + + return res; +} + +static const char *add_env_module_vars_passed(cmd_parms *cmd, void *sconf_, + const char *arg) +{ + env_dir_config_rec *sconf = sconf_; + apr_table_t *vars = sconf->vars; + const char *env_var; + + env_var = getenv(arg); + if (env_var != NULL) { + apr_table_setn(vars, arg, apr_pstrdup(cmd->pool, env_var)); + } + else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "PassEnv variable %s was undefined", arg); + } + + return NULL; +} + +static const char *add_env_module_vars_set(cmd_parms *cmd, void *sconf_, + const char *name, const char *value) +{ + env_dir_config_rec *sconf = sconf_; + + /* name is mandatory, value is optional. no value means + * set the variable to an empty string + */ + apr_table_setn(sconf->vars, name, value ? value : ""); + + return NULL; +} + +static const char *add_env_module_vars_unset(cmd_parms *cmd, void *sconf_, + const char *arg) +{ + env_dir_config_rec *sconf = sconf_; + + /* Always UnsetEnv FOO in the same context as {Set,Pass}Env FOO + * only if this UnsetEnv follows the {Set,Pass}Env. The merge + * will only apply unsetenv to the parent env (main server). + */ + apr_table_set(sconf->unsetenv, arg, NULL); + apr_table_unset(sconf->vars, arg); + + return NULL; +} + +static const command_rec env_module_cmds[] = +{ +AP_INIT_ITERATE("PassEnv", add_env_module_vars_passed, NULL, + OR_FILEINFO, "a list of environment variables to pass to CGI."), +AP_INIT_TAKE12("SetEnv", add_env_module_vars_set, NULL, + OR_FILEINFO, "an environment variable name and optional value to pass to CGI."), +AP_INIT_ITERATE("UnsetEnv", add_env_module_vars_unset, NULL, + OR_FILEINFO, "a list of variables to remove from the CGI environment."), + {NULL}, +}; + +static int fixup_env_module(request_rec *r) +{ + apr_table_t *e = r->subprocess_env; + env_dir_config_rec *sconf = ap_get_module_config(r->per_dir_config, + &env_module); + apr_table_t *vars = sconf->vars; + + if (!apr_table_elts(sconf->vars)->nelts) + return DECLINED; + + r->subprocess_env = apr_table_overlay(r->pool, e, vars); + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(fixup_env_module, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA env_module = +{ + STANDARD20_MODULE_STUFF, + create_env_dir_config, /* dir config creater */ + merge_env_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + env_module_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_env.dsp b/trunk/modules/metadata/mod_env.dsp new file mode 100644 index 0000000000..549cb6d830 --- /dev/null +++ b/trunk/modules/metadata/mod_env.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_env" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_env - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_env.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_env.mak" CFG="mod_env - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_env - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_env - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_env - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_env_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_env - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_env_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_env.so" /base:@..\..\os\win32\BaseAddr.ref,mod_env.so + +!ENDIF + +# Begin Target + +# Name "mod_env - Win32 Release" +# Name "mod_env - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_env.c +# End Source File +# Begin Source File + +SOURCE=.\mod_env.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_env - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_env.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_env.so "env_module for Apache" ../../include/ap_release.h > .\mod_env.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_env - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_env.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_env.so "env_module for Apache" ../../include/ap_release.h > .\mod_env.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_env.exp b/trunk/modules/metadata/mod_env.exp new file mode 100644 index 0000000000..b487bf09c8 --- /dev/null +++ b/trunk/modules/metadata/mod_env.exp @@ -0,0 +1 @@ +env_module diff --git a/trunk/modules/metadata/mod_expires.c b/trunk/modules/metadata/mod_expires.c new file mode 100644 index 0000000000..510136e99a --- /dev/null +++ b/trunk/modules/metadata/mod_expires.c @@ -0,0 +1,563 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_expires.c + * version 0.0.11 + * status beta + * + * Andrew Wilson 26.Jan.96 + * + * This module allows you to control the form of the Expires: header + * that Apache issues for each access. Directives can appear in + * configuration files or in .htaccess files so expiry semantics can + * be defined on a per-directory basis. + * + * DIRECTIVE SYNTAX + * + * Valid directives are: + * + * ExpiresActive on | off + * ExpiresDefault + * ExpiresByType type/encoding + * + * Valid values for are: + * + * 'M' expires header shows file modification date + + * 'A' expires header shows access time + + * + * [I'm not sure which of these is best under different + * circumstances, I guess it's for other people to explore. + * The effects may be indistinguishable for a number of cases] + * + * should be an integer value [acceptable to atoi()] + * + * There is NO space between the and . + * + * For example, a directory which contains information which changes + * frequently might contain: + * + * # reports generated by cron every hour. don't let caches + * # hold onto stale information + * ExpiresDefault M3600 + * + * Another example, our html pages can change all the time, the gifs + * tend not to change often: + * + * # pages are hot (1 week), images are cold (1 month) + * ExpiresByType text/html A604800 + * ExpiresByType image/gif A2592000 + * + * Expires can be turned on for all URLs on the server by placing the + * following directive in a conf file: + * + * ExpiresActive on + * + * ExpiresActive can also appear in .htaccess files, enabling the + * behaviour to be turned on or off for each chosen directory. + * + * # turn off Expires behaviour in this directory + * # and subdirectories + * ExpiresActive off + * + * Directives defined for a directory are valid in subdirectories + * unless explicitly overridden by new directives in the subdirectory + * .htaccess files. + * + * ALTERNATIVE DIRECTIVE SYNTAX + * + * Directives can also be defined in a more readable syntax of the form: + * + * ExpiresDefault " [plus] { }*" + * ExpiresByType type/encoding " [plus] { }*" + * + * where is one of: + * access + * now equivalent to 'access' + * modification + * + * where the 'plus' keyword is optional + * + * where should be an integer value [acceptable to atoi()] + * + * where is one of: + * years + * months + * weeks + * days + * hours + * minutes + * seconds + * + * For example, any of the following directives can be used to make + * documents expire 1 month after being accessed, by default: + * + * ExpiresDefault "access plus 1 month" + * ExpiresDefault "access plus 4 weeks" + * ExpiresDefault "access plus 30 days" + * + * The expiry time can be fine-tuned by adding several ' ' + * clauses: + * + * ExpiresByType text/html "access plus 1 month 15 days 2 hours" + * ExpiresByType image/gif "modification plus 5 hours 3 minutes" + * + * --- + * + * Change-log: + * 29.Jan.96 Hardened the add_* functions. Server will now bail out + * if bad directives are given in the conf files. + * 02.Feb.96 Returns DECLINED if not 'ExpiresActive on', giving other + * expires-aware modules a chance to play with the same + * directives. [Michael Rutman] + * 03.Feb.96 Call tzset() before localtime(). Trying to get the module + * to work properly in non GMT timezones. + * 12.Feb.96 Modified directive syntax to allow more readable commands: + * ExpiresDefault "now plus 10 days 20 seconds" + * ExpiresDefault "access plus 30 days" + * ExpiresDefault "modification plus 1 year 10 months 30 days" + * 13.Feb.96 Fix call to table_get() with NULL 2nd parameter [Rob Hartill] + * 19.Feb.96 Call gm_timestr_822() to get time formatted correctly, can't + * rely on presence of HTTP_TIME_FORMAT in Apache 1.1+. + * 21.Feb.96 This version (0.0.9) reverses assumptions made in 0.0.8 + * about star/star handlers. Reverting to 0.0.7 behaviour. + * 08.Jun.96 allows ExpiresDefault to be used with responses that use + * the DefaultType by not DECLINING, but instead skipping + * the table_get check and then looking for an ExpiresDefault. + * [Rob Hartill] + * 04.Nov.96 'const' definitions added. + * + * TODO + * add support for Cache-Control: max-age=20 from the HTTP/1.1 + * proposal (in this case, a ttl of 20 seconds) [ask roy] + * add per-file expiry and explicit expiry times - duplicates some + * of the mod_cern_meta.c functionality. eg: + * ExpiresExplicit index.html "modification plus 30 days" + * + * BUGS + * Hi, welcome to the internet. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_request.h" +#include "http_protocol.h" + +typedef struct { + int active; + int wildcards; + char *expiresdefault; + apr_table_t *expiresbytype; +} expires_dir_config; + +/* from mod_dir, why is this alias used? + */ +#define DIR_CMD_PERMS OR_INDEXES + +#define ACTIVE_ON 1 +#define ACTIVE_OFF 0 +#define ACTIVE_DONTCARE 2 + +module AP_MODULE_DECLARE_DATA expires_module; + +static void *create_dir_expires_config(apr_pool_t *p, char *dummy) +{ + expires_dir_config *new = + (expires_dir_config *) apr_pcalloc(p, sizeof(expires_dir_config)); + new->active = ACTIVE_DONTCARE; + new->wildcards = 0; + new->expiresdefault = NULL; + new->expiresbytype = apr_table_make(p, 4); + return (void *) new; +} + +static const char *set_expiresactive(cmd_parms *cmd, void *in_dir_config, int arg) +{ + expires_dir_config *dir_config = in_dir_config; + + /* if we're here at all it's because someone explicitly + * set the active flag + */ + dir_config->active = ACTIVE_ON; + if (arg == 0) { + dir_config->active = ACTIVE_OFF; + } + return NULL; +} + +/* check_code() parse 'code' and return NULL or an error response + * string. If we return NULL then real_code contains code converted + * to the cnnnn format. + */ +static char *check_code(apr_pool_t *p, const char *code, char **real_code) +{ + char *word; + char base = 'X'; + int modifier = 0; + int num = 0; + int factor = 0; + + /* 0.0.4 compatibility? + */ + if ((code[0] == 'A') || (code[0] == 'M')) { + *real_code = (char *)code; + return NULL; + } + + /* [plus] { }* + */ + + /* + */ + word = ap_getword_conf(p, &code); + if (!strncasecmp(word, "now", 1) || + !strncasecmp(word, "access", 1)) { + base = 'A'; + } + else if (!strncasecmp(word, "modification", 1)) { + base = 'M'; + } + else { + return apr_pstrcat(p, "bad expires code, unrecognised '", + word, "'", NULL); + } + + /* [plus] + */ + word = ap_getword_conf(p, &code); + if (!strncasecmp(word, "plus", 1)) { + word = ap_getword_conf(p, &code); + } + + /* { }* + */ + while (word[0]) { + /* + */ + if (apr_isdigit(word[0])) { + num = atoi(word); + } + else { + return apr_pstrcat(p, "bad expires code, numeric value expected '", + word, "'", NULL); + } + + /* + */ + word = ap_getword_conf(p, &code); + if (word[0]) { + /* do nothing */ + } + else { + return apr_pstrcat(p, "bad expires code, missing ", NULL); + } + + factor = 0; + if (!strncasecmp(word, "years", 1)) { + factor = 60 * 60 * 24 * 365; + } + else if (!strncasecmp(word, "months", 2)) { + factor = 60 * 60 * 24 * 30; + } + else if (!strncasecmp(word, "weeks", 1)) { + factor = 60 * 60 * 24 * 7; + } + else if (!strncasecmp(word, "days", 1)) { + factor = 60 * 60 * 24; + } + else if (!strncasecmp(word, "hours", 1)) { + factor = 60 * 60; + } + else if (!strncasecmp(word, "minutes", 2)) { + factor = 60; + } + else if (!strncasecmp(word, "seconds", 1)) { + factor = 1; + } + else { + return apr_pstrcat(p, "bad expires code, unrecognised ", + "'", word, "'", NULL); + } + + modifier = modifier + factor * num; + + /* next + */ + word = ap_getword_conf(p, &code); + } + + *real_code = apr_psprintf(p, "%c%d", base, modifier); + + return NULL; +} + +static const char *set_expiresbytype(cmd_parms *cmd, void *in_dir_config, + const char *mime, const char *code) +{ + expires_dir_config *dir_config = in_dir_config; + char *response, *real_code; + const char *check; + + check = ap_strrchr_c(mime, '/'); + if ((strlen(++check) == 1) && (*check == '*')) { + dir_config->wildcards = 1; + } + + if ((response = check_code(cmd->pool, code, &real_code)) == NULL) { + apr_table_setn(dir_config->expiresbytype, mime, real_code); + return NULL; + } + return apr_pstrcat(cmd->pool, + "'ExpiresByType ", mime, " ", code, "': ", response, NULL); +} + +static const char *set_expiresdefault(cmd_parms *cmd, void *in_dir_config, + const char *code) +{ + expires_dir_config * dir_config = in_dir_config; + char *response, *real_code; + + if ((response = check_code(cmd->pool, code, &real_code)) == NULL) { + dir_config->expiresdefault = real_code; + return NULL; + } + return apr_pstrcat(cmd->pool, + "'ExpiresDefault ", code, "': ", response, NULL); +} + +static const command_rec expires_cmds[] = +{ + AP_INIT_FLAG("ExpiresActive", set_expiresactive, NULL, DIR_CMD_PERMS, + "Limited to 'on' or 'off'"), + AP_INIT_TAKE2("ExpiresByType", set_expiresbytype, NULL, DIR_CMD_PERMS, + "a MIME type followed by an expiry date code"), + AP_INIT_TAKE1("ExpiresDefault", set_expiresdefault, NULL, DIR_CMD_PERMS, + "an expiry date code"), + {NULL} +}; + +static void *merge_expires_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + expires_dir_config *new = (expires_dir_config *) apr_pcalloc(p, sizeof(expires_dir_config)); + expires_dir_config *base = (expires_dir_config *) basev; + expires_dir_config *add = (expires_dir_config *) addv; + + if (add->active == ACTIVE_DONTCARE) { + new->active = base->active; + } + else { + new->active = add->active; + } + + if (add->expiresdefault != NULL) { + new->expiresdefault = add->expiresdefault; + } + else { + new->expiresdefault = base->expiresdefault; + } + new->wildcards = add->wildcards; + new->expiresbytype = apr_table_overlay(p, add->expiresbytype, + base->expiresbytype); + return new; +} + +/* + * Handle the setting of the expiration response header fields according + * to our criteria. + */ + +static int set_expiration_fields(request_rec *r, const char *code, + apr_table_t *t) +{ + apr_time_t base; + apr_time_t additional; + apr_time_t expires; + int additional_sec; + char *timestr; + + switch (code[0]) { + case 'M': + if (r->finfo.filetype == 0) { + /* file doesn't exist on disk, so we can't do anything based on + * modification time. Note that this does _not_ log an error. + */ + return DECLINED; + } + base = r->finfo.mtime; + additional_sec = atoi(&code[1]); + additional = apr_time_from_sec(additional_sec); + break; + case 'A': + /* there's been some discussion and it's possible that + * 'access time' will be stored in request structure + */ + base = r->request_time; + additional_sec = atoi(&code[1]); + additional = apr_time_from_sec(additional_sec); + break; + default: + /* expecting the add_* routines to be case-hardened this + * is just a reminder that module is beta + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "internal error: bad expires code: %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + expires = base + additional; + apr_table_mergen(t, "Cache-Control", + apr_psprintf(r->pool, "max-age=%" APR_TIME_T_FMT, + apr_time_sec(expires - r->request_time))); + timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN); + apr_rfc822_date(timestr, expires); + apr_table_setn(t, "Expires", timestr); + return OK; +} + +/* + * Output filter to set the Expires response header field + * according to the content-type of the response -- if it hasn't + * already been set. + */ +static apr_status_t expires_filter(ap_filter_t *f, + apr_bucket_brigade *b) +{ + request_rec *r; + expires_dir_config *conf; + const char *expiry; + apr_table_t *t; + + r = f->r; + conf = (expires_dir_config *) ap_get_module_config(r->per_dir_config, + &expires_module); + + /* + * Check to see which output header table we should use; + * mod_cgi loads script fields into r->err_headers_out, + * for instance. + */ + expiry = apr_table_get(r->err_headers_out, "Expires"); + if (expiry != NULL) { + t = r->err_headers_out; + } + else { + expiry = apr_table_get(r->headers_out, "Expires"); + t = r->headers_out; + } + if (expiry == NULL) { + /* + * No expiration has been set, so we can apply any managed by + * this module. First, check to see if there is an applicable + * ExpiresByType directive. + */ + expiry = apr_table_get(conf->expiresbytype, + ap_field_noparam(r->pool, r->content_type)); + if (expiry == NULL) { + int usedefault = 1; + /* + * See if we have a wildcard entry for the major type. + */ + if (conf->wildcards) { + char *checkmime; + char *spos; + checkmime = apr_pstrdup(r->pool, r->content_type); + spos = checkmime ? ap_strchr(checkmime, '/') : NULL; + if (spos != NULL) { + /* + * Without a '/' character, nothing we have will match. + * However, we have one. + */ + if (strlen(++spos) > 0) { + *spos++ = '*'; + *spos = '\0'; + } + else { + checkmime = apr_pstrcat(r->pool, checkmime, "*", NULL); + } + expiry = apr_table_get(conf->expiresbytype, checkmime); + usedefault = (expiry == NULL); + } + } + if (usedefault) { + /* + * Use the ExpiresDefault directive + */ + expiry = conf->expiresdefault; + } + } + if (expiry != NULL) { + set_expiration_fields(r, expiry, t); + } + } + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, b); +} + +static void expires_insert_filter(request_rec *r) +{ + expires_dir_config *conf; + + /* Don't add Expires headers to errors */ + if (ap_is_HTTP_ERROR(r->status)) { + return; + } + /* Say no to subrequests */ + if (r->main != NULL) { + return; + } + conf = (expires_dir_config *) ap_get_module_config(r->per_dir_config, + &expires_module); + + /* Check to see if the filter is enabled and if there are any applicable + * config directives for this directory scope + */ + if (conf->active != ACTIVE_ON || + (apr_is_empty_table(conf->expiresbytype) && !conf->expiresdefault)) { + return; + } + ap_add_output_filter("MOD_EXPIRES", NULL, r, r->connection); + return; +} +static void register_hooks(apr_pool_t *p) +{ + /* mod_expires needs to run *before* the cache save filter which is + * AP_FTYPE_CONTENT_SET-1. Otherwise, our expires won't be honored. + */ + ap_register_output_filter("MOD_EXPIRES", expires_filter, NULL, + AP_FTYPE_CONTENT_SET-2); + ap_hook_insert_error_filter(expires_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter(expires_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA expires_module = +{ + STANDARD20_MODULE_STUFF, + create_dir_expires_config, /* dir config creater */ + merge_expires_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + expires_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_expires.dsp b/trunk/modules/metadata/mod_expires.dsp new file mode 100644 index 0000000000..89da9d2eec --- /dev/null +++ b/trunk/modules/metadata/mod_expires.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_expires" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_expires - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_expires.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_expires.mak" CFG="mod_expires - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_expires - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_expires - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_expires - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_expires_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_expires - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_expires_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_expires.so" /base:@..\..\os\win32\BaseAddr.ref,mod_expires.so + +!ENDIF + +# Begin Target + +# Name "mod_expires - Win32 Release" +# Name "mod_expires - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_expires.c +# End Source File +# Begin Source File + +SOURCE=.\mod_expires.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_expires - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_expires.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_expires.so "expires_module for Apache" ../../include/ap_release.h > .\mod_expires.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_expires - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_expires.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_expires.so "expires_module for Apache" ../../include/ap_release.h > .\mod_expires.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_expires.exp b/trunk/modules/metadata/mod_expires.exp new file mode 100644 index 0000000000..863a96878e --- /dev/null +++ b/trunk/modules/metadata/mod_expires.exp @@ -0,0 +1 @@ +expires_module diff --git a/trunk/modules/metadata/mod_headers.c b/trunk/modules/metadata/mod_headers.c new file mode 100644 index 0000000000..82f29938bf --- /dev/null +++ b/trunk/modules/metadata/mod_headers.c @@ -0,0 +1,748 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_headers.c: Add/append/remove HTTP response headers + * Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996 + * + * The Header directive can be used to add/replace/remove HTTP headers + * within the response message. The RequestHeader directive can be used + * to add/replace/remove HTTP headers before a request message is processed. + * Valid in both per-server and per-dir configurations. + * + * Syntax is: + * + * Header action header value + * RequestHeader action header value + * + * Where action is one of: + * set - set this header, replacing any old value + * add - add this header, possible resulting in two or more + * headers with the same name + * append - append this text onto any existing header of this same + * unset - remove this header + * + * Where action is unset, the third argument (value) should not be given. + * The header name can include the colon, or not. + * + * The Header and RequestHeader directives can only be used where allowed + * by the FileInfo override. + * + * When the request is processed, the header directives are processed in + * this order: firstly, the main server, then the virtual server handling + * this request (if any), then any sections (working downwards + * from the root dir), then an sections (working down from + * shortest URL component), the any sections. This order is + * important if any 'set' or 'unset' actions are used. For example, + * the following two directives have different effect if applied in + * the reverse order: + * + * Header append Author "John P. Doe" + * Header unset Author + * + * Examples: + * + * To set the "Author" header, use + * Header add Author "John P. Doe" + * + * To remove a header: + * Header unset Author + * + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_buckets.h" + +#include "apr_hash.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_log.h" +#include "util_filter.h" +#include "http_protocol.h" + +#include "mod_ssl.h" /* for the ssl_var_lookup optional function defn */ + +/* format_tag_hash is initialized during pre-config */ +static apr_hash_t *format_tag_hash; + +typedef enum { + hdr_add = 'a', /* add header (could mean multiple hdrs) */ + hdr_set = 's', /* set (replace old value) */ + hdr_append = 'm', /* append (merge into any old value) */ + hdr_unset = 'u', /* unset header */ + hdr_echo = 'e' /* echo headers from request to response */ +} hdr_actions; + +/* + * magic cmd->info values + */ +static char hdr_in = '0'; /* RequestHeader */ +static char hdr_out = '1'; /* Header onsuccess */ +static char hdr_err = '2'; /* Header always */ + +/* + * There is an array of struct format_tag per Header/RequestHeader + * config directive + */ +typedef struct { + const char* (*func)(request_rec *r,char *arg); + char *arg; +} format_tag; + +/* 'Magic' condition_var value to run action in post_read_request */ +static const char* condition_early = "early"; +/* + * There is one "header_entry" per Header/RequestHeader config directive + */ +typedef struct { + hdr_actions action; + const char *header; + apr_array_header_t *ta; /* Array of format_tag structs */ + ap_regex_t *regex; + const char *condition_var; +} header_entry; + +/* echo_do is used for Header echo to iterate through the request headers*/ +typedef struct { + request_rec *r; + header_entry *hdr; +} echo_do; + +/* + * headers_conf is our per-module configuration. This is used as both + * a per-dir and per-server config + */ +typedef struct { + apr_array_header_t *fixup_in; + apr_array_header_t *fixup_out; + apr_array_header_t *fixup_err; +} headers_conf; + +module AP_MODULE_DECLARE_DATA headers_module; + +/* Pointer to ssl_var_lookup, if available. */ +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *header_ssl_lookup = NULL; + +/* + * Tag formatting functions + */ +static const char *constant_item(request_rec *r, char *stuff) +{ + return stuff; +} +static const char *header_request_duration(request_rec *r, char *a) +{ + return apr_psprintf(r->pool, "D=%" APR_TIME_T_FMT, + (apr_time_now() - r->request_time)); +} +static const char *header_request_time(request_rec *r, char *a) +{ + return apr_psprintf(r->pool, "t=%" APR_TIME_T_FMT, r->request_time); +} + +/* unwrap_header returns HDR with any newlines converted into + * whitespace if necessary. */ +static const char *unwrap_header(apr_pool_t *p, const char *hdr) +{ + if (ap_strchr_c(hdr, APR_ASCII_LF) || ap_strchr_c(hdr, APR_ASCII_CR)) { + char *ptr; + + hdr = ptr = apr_pstrdup(p, hdr); + + do { + if (*ptr == APR_ASCII_LF || *ptr == APR_ASCII_CR) + *ptr = APR_ASCII_BLANK; + } while (*ptr++); + } + return hdr; +} + +static const char *header_request_env_var(request_rec *r, char *a) +{ + const char *s = apr_table_get(r->subprocess_env,a); + + if (s) + return unwrap_header(r->pool, s); + else + return "(null)"; +} + +static const char *header_request_ssl_var(request_rec *r, char *name) +{ + if (header_ssl_lookup) { + const char *val = header_ssl_lookup(r->pool, r->server, + r->connection, r, name); + if (val && val[0]) + return unwrap_header(r->pool, val); + else + return "(null)"; + } + else { + return "(null)"; + } +} + +/* + * Config routines + */ + +static void *create_headers_dir_config(apr_pool_t *p, char *d) +{ + headers_conf *conf = apr_pcalloc(p, sizeof(*conf)); + + conf->fixup_in = apr_array_make(p, 2, sizeof(header_entry)); + conf->fixup_out = apr_array_make(p, 2, sizeof(header_entry)); + conf->fixup_err = apr_array_make(p, 2, sizeof(header_entry)); + + return conf; +} + +static void *merge_headers_config(apr_pool_t *p, void *basev, void *overridesv) +{ + headers_conf *newconf = apr_pcalloc(p, sizeof(*newconf)); + headers_conf *base = basev; + headers_conf *overrides = overridesv; + + newconf->fixup_in = apr_array_append(p, base->fixup_in, + overrides->fixup_in); + newconf->fixup_out = apr_array_append(p, base->fixup_out, + overrides->fixup_out); + newconf->fixup_err = apr_array_append(p, base->fixup_err, + overrides->fixup_err); + + return newconf; +} + +static char *parse_misc_string(apr_pool_t *p, format_tag *tag, const char **sa) +{ + const char *s; + char *d; + + tag->func = constant_item; + + s = *sa; + while (*s && *s != '%') { + s++; + } + /* + * This might allocate a few chars extra if there's a backslash + * escape in the format string. + */ + tag->arg = apr_palloc(p, s - *sa + 1); + + d = tag->arg; + s = *sa; + while (*s && *s != '%') { + if (*s != '\\') { + *d++ = *s++; + } + else { + s++; + switch (*s) { + case '\\': + *d++ = '\\'; + s++; + break; + case 'r': + *d++ = '\r'; + s++; + break; + case 'n': + *d++ = '\n'; + s++; + break; + case 't': + *d++ = '\t'; + s++; + break; + default: + /* copy verbatim */ + *d++ = '\\'; + /* + * Allow the loop to deal with this *s in the normal + * fashion so that it handles end of string etc. + * properly. + */ + break; + } + } + } + *d = '\0'; + + *sa = s; + return NULL; +} + +static char *parse_format_tag(apr_pool_t *p, format_tag *tag, const char **sa) +{ + const char *s = *sa; + const char * (*tag_handler)(request_rec *,char *); + + /* Handle string literal/conditionals */ + if (*s != '%') { + return parse_misc_string(p, tag, sa); + } + s++; /* skip the % */ + + /* Pass through %% as % */ + if (*s == '%') { + tag->func = constant_item; + tag->arg = "%"; + *sa = ++s; + return NULL; + } + + tag->arg = '\0'; + /* grab the argument if there is one */ + if (*s == '{') { + ++s; + tag->arg = ap_getword(p,&s,'}'); + } + + tag_handler = (const char * (*)(request_rec *,char *))apr_hash_get(format_tag_hash, s++, 1); + + if (!tag_handler) { + char dummy[2]; + dummy[0] = s[-1]; + dummy[1] = '\0'; + return apr_pstrcat(p, "Unrecognized header format %", dummy, NULL); + } + tag->func = tag_handler; + + *sa = s; + return NULL; +} + +/* + * A format string consists of white space, text and optional format + * tags in any order. E.g., + * + * Header add MyHeader "Free form text %D %t more text" + * + * Decompose the format string into its tags. Each tag (struct format_tag) + * contains a pointer to the function used to format the tag. Then save each + * tag in the tag array anchored in the header_entry. + */ +static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s) +{ + char *res; + + /* No string to parse with unset and echo commands */ + if (hdr->action == hdr_unset || + hdr->action == hdr_echo) { + return NULL; + } + + hdr->ta = apr_array_make(p, 10, sizeof(format_tag)); + + while (*s) { + if ((res = parse_format_tag(p, (format_tag *) apr_array_push(hdr->ta), &s))) { + return res; + } + } + return NULL; +} + +/* handle RequestHeader and Header directive */ +static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd, + void *indirconf, + const char *action, + const char *hdr, + const char *value, + const char* envclause) +{ + headers_conf *dirconf = indirconf; + const char *condition_var = NULL; + const char *colon; + header_entry *new; + + apr_array_header_t *fixup = (cmd->info == &hdr_in) + ? dirconf->fixup_in : (cmd->info == &hdr_err) + ? dirconf->fixup_err + : dirconf->fixup_out; + + new = (header_entry *) apr_array_push(fixup); + + if (!strcasecmp(action, "set")) + new->action = hdr_set; + else if (!strcasecmp(action, "add")) + new->action = hdr_add; + else if (!strcasecmp(action, "append")) + new->action = hdr_append; + else if (!strcasecmp(action, "unset")) + new->action = hdr_unset; + else if (!strcasecmp(action, "echo")) + new->action = hdr_echo; + else + return "first argument must be 'add', 'set', 'append', 'unset' or " + "'echo'."; + + if (new->action == hdr_unset) { + if (value) { + if (envclause) { + return "header unset takes two arguments"; + } + envclause = value; + value = NULL; + } + } + else if (new->action == hdr_echo) { + ap_regex_t *regex; + + if (value) { + if (envclause) { + return "Header echo takes two arguments"; + } + envclause = value; + value = NULL; + } + if (cmd->info != &hdr_out && cmd->info != &hdr_err) + return "Header echo only valid on Header " + "directives"; + else { + regex = ap_pregcomp(cmd->pool, hdr, AP_REG_EXTENDED | AP_REG_NOSUB); + if (regex == NULL) { + return "Header echo regex could not be compiled"; + } + } + new->regex = regex; + } + else if (!value) + return "Header requires three arguments"; + + /* Handle the envclause on Header */ + if (envclause != NULL) { + if (strcasecmp(envclause, "early") == 0) { + condition_var = condition_early; + } + else { + if (strncasecmp(envclause, "env=", 4) != 0) { + return "error: envclause should be in the form env=envar"; + } + if ((envclause[4] == '\0') + || ((envclause[4] == '!') && (envclause[5] == '\0'))) { + return "error: missing environment variable name. " + "envclause should be in the form env=envar "; + } + condition_var = envclause + 4; + } + } + + if ((colon = ap_strchr_c(hdr, ':'))) { + hdr = apr_pstrmemdup(cmd->pool, hdr, colon-hdr); + } + + new->header = hdr; + new->condition_var = condition_var; + + return parse_format_string(cmd->pool, new, value); +} + +/* Handle all (xxx)Header directives */ +static const char *header_cmd(cmd_parms *cmd, void *indirconf, + const char *args) +{ + const char *action; + const char *hdr; + const char *val; + const char *envclause; + + action = ap_getword_conf(cmd->pool, &args); + if (cmd->info == &hdr_out) { + if (!strcasecmp(action, "always")) { + cmd->info = &hdr_err; + action = ap_getword_conf(cmd->pool, &args); + } + else if (!strcasecmp(action, "onsuccess")) { + action = ap_getword_conf(cmd->pool, &args); + } + } + hdr = ap_getword_conf(cmd->pool, &args); + val = *args ? ap_getword_conf(cmd->pool, &args) : NULL; + envclause = *args ? ap_getword_conf(cmd->pool, &args) : NULL; + + if (*args) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + " has too many arguments", NULL); + } + + return header_inout_cmd(cmd, indirconf, action, hdr, val, envclause); +} + +/* + * Process the tags in the format string. Tags may be format specifiers + * (%D, %t, etc.), whitespace or text strings. For each tag, run the handler + * (formatter) specific to the tag. Handlers return text strings. + * Concatenate the return from each handler into one string that is + * returned from this call. + */ +static char* process_tags(header_entry *hdr, request_rec *r) +{ + int i; + const char *s; + char *str = NULL; + + format_tag *tag = (format_tag*) hdr->ta->elts; + + for (i = 0; i < hdr->ta->nelts; i++) { + s = tag[i].func(r, tag[i].arg); + if (str == NULL) + str = apr_pstrdup(r->pool, s); + else + str = apr_pstrcat(r->pool, str, s, NULL); + } + return str ? str : ""; +} + +static int echo_header(echo_do *v, const char *key, const char *val) +{ + /* If the input header (key) matches the regex, echo it intact to + * r->headers_out. + */ + if (!ap_regexec(v->hdr->regex, key, 0, NULL, 0)) { + apr_table_add(v->r->headers_out, key, val); + } + + return 1; +} + +static void do_headers_fixup(request_rec *r, apr_table_t *headers, + apr_array_header_t *fixup, int early) +{ + int i; + + for (i = 0; i < fixup->nelts; ++i) { + header_entry *hdr = &((header_entry *) (fixup->elts))[i]; + const char *envar = hdr->condition_var; + + /* ignore early headers in late calls */ + if (!early && (envar == condition_early)) { + continue; + } + /* ignore late headers in early calls */ + else if (early && (envar != condition_early)) { + continue; + } + /* Have any conditional envar-controlled Header processing to do? */ + else if (envar && !early) { + if (*envar != '!') { + if (apr_table_get(r->subprocess_env, envar) == NULL) + continue; + } + else { + if (apr_table_get(r->subprocess_env, &envar[1]) != NULL) + continue; + } + } + + switch (hdr->action) { + case hdr_add: + apr_table_addn(headers, hdr->header, process_tags(hdr, r)); + break; + case hdr_append: + apr_table_mergen(headers, hdr->header, process_tags(hdr, r)); + break; + case hdr_set: + apr_table_setn(headers, hdr->header, process_tags(hdr, r)); + break; + case hdr_unset: + apr_table_unset(headers, hdr->header); + break; + case hdr_echo: + { + echo_do v; + v.r = r; + v.hdr = hdr; + apr_table_do((int (*) (void *, const char *, const char *)) + echo_header, (void *) &v, r->headers_in, NULL); + break; + } + } + } +} + +static void ap_headers_insert_output_filter(request_rec *r) +{ + headers_conf *dirconf = ap_get_module_config(r->per_dir_config, + &headers_module); + + if (dirconf->fixup_out->nelts || dirconf->fixup_err->nelts) { + ap_add_output_filter("FIXUP_HEADERS_OUT", NULL, r, r->connection); + } +} + +/* + * Make sure our error-path filter is in place. + */ +static void ap_headers_insert_error_filter(request_rec *r) +{ + headers_conf *dirconf = ap_get_module_config(r->per_dir_config, + &headers_module); + + if (dirconf->fixup_err->nelts) { + ap_add_output_filter("FIXUP_HEADERS_ERR", NULL, r, r->connection); + } +} + +static apr_status_t ap_headers_output_filter(ap_filter_t *f, + apr_bucket_brigade *in) +{ + headers_conf *dirconf = ap_get_module_config(f->r->per_dir_config, + &headers_module); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server, + "headers: ap_headers_output_filter()"); + + /* do the fixup */ + do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0); + do_headers_fixup(f->r, f->r->headers_out, dirconf->fixup_out, 0); + + /* remove ourselves from the filter chain */ + ap_remove_output_filter(f); + + /* send the data up the stack */ + return ap_pass_brigade(f->next,in); +} + +/* + * Make sure we propagate any "Header always" settings on the error + * path through http_protocol.c. + */ +static apr_status_t ap_headers_error_filter(ap_filter_t *f, + apr_bucket_brigade *in) +{ + headers_conf *dirconf; + + dirconf = ap_get_module_config(f->r->per_dir_config, + &headers_module); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server, + "headers: ap_headers_error_filter()"); + + /* + * Add any header fields defined by "Header always" to r->err_headers_out. + * Server-wide first, then per-directory to allow overriding. + */ + do_headers_fixup(f->r, f->r->err_headers_out, dirconf->fixup_err, 0); + + /* + * We've done our bit; remove ourself from the filter chain so there's + * no possibility we'll be called again. + */ + ap_remove_output_filter(f); + + /* + * Pass the buck. (euro?) + */ + return ap_pass_brigade(f->next, in); +} + +static apr_status_t ap_headers_fixup(request_rec *r) +{ + headers_conf *dirconf = ap_get_module_config(r->per_dir_config, + &headers_module); + + /* do the fixup */ + if (dirconf->fixup_in->nelts) { + do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 0); + } + + return DECLINED; +} +static apr_status_t ap_headers_early(request_rec *r) +{ + headers_conf *dirconf = ap_get_module_config(r->per_dir_config, + &headers_module); + + /* do the fixup */ + if (dirconf->fixup_in->nelts) { + do_headers_fixup(r, r->headers_in, dirconf->fixup_in, 1); + } + if (dirconf->fixup_err->nelts) { + do_headers_fixup(r, r->err_headers_out, dirconf->fixup_err, 1); + } + if (dirconf->fixup_out->nelts) { + do_headers_fixup(r, r->headers_out, dirconf->fixup_out, 1); + } + + return DECLINED; +} + +static const command_rec headers_cmds[] = +{ + AP_INIT_RAW_ARGS("Header", header_cmd, &hdr_out, OR_FILEINFO, + "an optional condition, an action, header and value " + "followed by optional env clause"), + AP_INIT_RAW_ARGS("RequestHeader", header_cmd, &hdr_in, OR_FILEINFO, + "an action, header and value followed by optional env " + "clause"), + {NULL} +}; + +static void register_format_tag_handler(const char *tag, + const void *tag_handler) +{ + apr_hash_set(format_tag_hash, tag, 1, tag_handler); +} + +static int header_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + format_tag_hash = apr_hash_make(p); + register_format_tag_handler("D", (const void *)header_request_duration); + register_format_tag_handler("t", (const void *)header_request_time); + register_format_tag_handler("e", (const void *)header_request_env_var); + register_format_tag_handler("s", (const void *)header_request_ssl_var); + + return OK; +} + +static int header_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + header_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_register_output_filter("FIXUP_HEADERS_OUT", ap_headers_output_filter, + NULL, AP_FTYPE_CONTENT_SET); + ap_register_output_filter("FIXUP_HEADERS_ERR", ap_headers_error_filter, + NULL, AP_FTYPE_CONTENT_SET); + ap_hook_pre_config(header_pre_config,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_post_config(header_post_config,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_insert_filter(ap_headers_insert_output_filter, NULL, NULL, APR_HOOK_LAST); + ap_hook_insert_error_filter(ap_headers_insert_error_filter, + NULL, NULL, APR_HOOK_LAST); + ap_hook_fixups(ap_headers_fixup, NULL, NULL, APR_HOOK_LAST); + ap_hook_post_read_request(ap_headers_early, NULL, NULL, APR_HOOK_FIRST); +} + +module AP_MODULE_DECLARE_DATA headers_module = +{ + STANDARD20_MODULE_STUFF, + create_headers_dir_config, /* dir config creater */ + merge_headers_config, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + headers_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_headers.dsp b/trunk/modules/metadata/mod_headers.dsp new file mode 100644 index 0000000000..0ab36f7184 --- /dev/null +++ b/trunk/modules/metadata/mod_headers.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_headers" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_headers - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_headers.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_headers.mak" CFG="mod_headers - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_headers - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_headers - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_headers - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_headers_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Release/mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_headers - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_headers_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_headers.so" /base:@..\..\os\win32\BaseAddr.ref,mod_headers.so + +!ENDIF + +# Begin Target + +# Name "mod_headers - Win32 Release" +# Name "mod_headers - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_headers.c +# End Source File +# Begin Source File + +SOURCE=.\mod_headers.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_headers - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_headers.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_headers.so "headers_module for Apache" ../../include/ap_release.h > .\mod_headers.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_headers - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_headers.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_headers.so "headers_module for Apache" ../../include/ap_release.h > .\mod_headers.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_headers.exp b/trunk/modules/metadata/mod_headers.exp new file mode 100644 index 0000000000..3f3063808a --- /dev/null +++ b/trunk/modules/metadata/mod_headers.exp @@ -0,0 +1 @@ +headers_module diff --git a/trunk/modules/metadata/mod_ident.c b/trunk/modules/metadata/mod_ident.c new file mode 100644 index 0000000000..ccce9b0b3b --- /dev/null +++ b/trunk/modules/metadata/mod_ident.c @@ -0,0 +1,352 @@ +/* Copyright 2003-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_ident: Handle RFC 1413 ident request + * obtained from rfc1413.c + * + * rfc1413() speaks a common subset of the RFC 1413, AUTH, TAP and IDENT + * protocols. The code queries an RFC 1413 etc. compatible daemon on a remote + * host to look up the owner of a connection. The information should not be + * used for authentication purposes. This routine intercepts alarm signals. + * + * Author: Wietse Venema, Eindhoven University of Technology, + * The Netherlands. + */ + +/* Some small additions for Apache --- ditch the "sccsid" var if + * compiling with gcc (it *has* changed), include ap_config.h for the + * prototypes it defines on at least one system (SunlOSs) which has + * them missing from the standard header files, and one minor change + * below (extra parens around assign "if (foo = bar) ..." to shut up + * gcc -Wall). + */ + +/* Rewritten by David Robinson */ + +#include "apr.h" +#include "apr_network_io.h" +#include "apr_strings.h" +#include "apr_optional.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" /* for server_rec, conn_rec, etc. */ +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" /* for aplog_error */ +#include "util_ebcdic.h" + +/* Whether we should enable rfc1413 identity checking */ +#ifndef DEFAULT_RFC1413 +#define DEFAULT_RFC1413 0 +#endif + +#define RFC1413_UNSET 2 + +/* request timeout (sec) */ +#ifndef RFC1413_TIMEOUT +#define RFC1413_TIMEOUT 30 +#endif + +/* Local stuff. */ + +/* Semi-well-known port */ +#define RFC1413_PORT 113 + +/* maximum allowed length of userid */ +#define RFC1413_USERLEN 512 + +/* rough limit on the amount of data we accept. */ +#define RFC1413_MAXDATA 1000 + +/* default username, if it could not determined */ +#define FROM_UNKNOWN "unknown" + +typedef struct { + int do_rfc1413; + int timeout_unset; + apr_time_t timeout; +} ident_config_rec; + +static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, + server_rec *srv, apr_time_t timeout) +{ + apr_status_t rv; + apr_sockaddr_t *localsa, *destsa; + + if ((rv = apr_sockaddr_info_get(&localsa, conn->local_ip, APR_UNSPEC, + 0, /* ephemeral port */ + 0, conn->pool)) != APR_SUCCESS) { + /* This should not fail since we have a numeric address string + * as the host. */ + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + "rfc1413: apr_sockaddr_info_get(%s) failed", + conn->local_ip); + return rv; + } + + if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip, + localsa->family, /* has to match */ + RFC1413_PORT, 0, conn->pool)) != APR_SUCCESS) { + /* This should not fail since we have a numeric address string + * as the host. */ + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + "rfc1413: apr_sockaddr_info_get(%s) failed", + conn->remote_ip); + return rv; + } + + if ((rv = apr_socket_create(newsock, + localsa->family, /* has to match */ + SOCK_STREAM, 0, conn->pool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + "rfc1413: error creating query socket"); + return rv; + } + + if ((rv = apr_socket_timeout_set(*newsock, timeout)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + "rfc1413: error setting query socket timeout"); + apr_socket_close(*newsock); + return rv; + } + +/* + * Bind the local and remote ends of the query socket to the same + * IP addresses as the connection under investigation. We go + * through all this trouble because the local or remote system + * might have more than one network address. The RFC1413 etc. + * client sends only port numbers; the server takes the IP + * addresses from the query socket. + */ + + if ((rv = apr_socket_bind(*newsock, localsa)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + "rfc1413: Error binding query socket to local port"); + apr_socket_close(*newsock); + return rv; + } + +/* + * errors from connect usually imply the remote machine doesn't support + * the service; don't log such an error + */ + if ((rv = apr_socket_connect(*newsock, destsa)) != APR_SUCCESS) { + apr_socket_close(*newsock); + return rv; + } + + return APR_SUCCESS; +} + +static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, + server_rec *srv) +{ + apr_port_t rmt_port, our_port; + apr_port_t sav_rmt_port, sav_our_port; + apr_size_t i; + char *cp; + char buffer[RFC1413_MAXDATA + 1]; + char user[RFC1413_USERLEN + 1]; /* XXX */ + apr_size_t buflen; + + sav_our_port = conn->local_addr->port; + sav_rmt_port = conn->remote_addr->port; + + /* send the data */ + buflen = apr_snprintf(buffer, sizeof(buffer), "%hu,%hu\r\n", sav_rmt_port, + sav_our_port); + ap_xlate_proto_to_ascii(buffer, buflen); + + /* send query to server. Handle short write. */ + i = 0; + while (i < buflen) { + apr_size_t j = strlen(buffer + i); + apr_status_t status; + status = apr_socket_send(sock, buffer+i, &j); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, + "write: rfc1413: error sending request"); + return status; + } + else if (j > 0) { + i+=j; + } + } + + /* + * Read response from server. - the response should be newline + * terminated according to rfc - make sure it doesn't stomp its + * way out of the buffer. + */ + + i = 0; + memset(buffer, '\0', sizeof(buffer)); + /* + * Note that the strchr function below checks for \012 instead of '\n' + * this allows it to work on both ASCII and EBCDIC machines. + */ + while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) { + apr_size_t j = sizeof(buffer) - 1 - i; + apr_status_t status; + status = apr_socket_recv(sock, buffer+i, &j); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, + "read: rfc1413: error reading response"); + return status; + } + else if (j > 0) { + i+=j; + } + else if (status == APR_SUCCESS && j == 0) { + /* Oops... we ran out of data before finding newline */ + return APR_EINVAL; + } + } + +/* RFC1413_USERLEN = 512 */ + ap_xlate_proto_from_ascii(buffer, i); + if (sscanf(buffer, "%hu , %hu : USERID :%*[^:]:%512s", &rmt_port, &our_port, + user) != 3 || sav_rmt_port != rmt_port + || sav_our_port != our_port) + return APR_EINVAL; + + /* + * Strip trailing carriage return. It is part of the + * protocol, not part of the data. + */ + + if ((cp = strchr(user, '\r'))) + *cp = '\0'; + + conn->remote_logname = apr_pstrdup(conn->pool, user); + + return APR_SUCCESS; +} + +static const char *set_idcheck(cmd_parms *cmd, void *d_, int arg) +{ + ident_config_rec *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (!err) { + d->do_rfc1413 = arg ? 1 : 0; + } + + return err; +} + +static const char *set_timeout(cmd_parms *cmd, void *d_, const char *arg) +{ + ident_config_rec *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (!err) { + d->timeout = apr_time_from_sec(atoi(arg)); + d->timeout_unset = 0; + } + + return err; +} + +static void *create_ident_dir_config(apr_pool_t *p, char *d) +{ + ident_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->do_rfc1413 = DEFAULT_RFC1413 | RFC1413_UNSET; + conf->timeout = apr_time_from_sec(RFC1413_TIMEOUT); + conf->timeout_unset = 1; + + return (void *)conf; +} + +static void *merge_ident_dir_config(apr_pool_t *p, void *old_, void *new_) +{ + ident_config_rec *conf = (ident_config_rec *)apr_pcalloc(p, sizeof(*conf)); + ident_config_rec *old = (ident_config_rec *) old_; + ident_config_rec *new = (ident_config_rec *) new_; + + conf->timeout = new->timeout_unset + ? old->timeout + : new->timeout; + + conf->do_rfc1413 = new->do_rfc1413 & RFC1413_UNSET + ? old->do_rfc1413 + : new->do_rfc1413; + + return (void *)conf; +} + +static const command_rec ident_cmds[] = +{ + AP_INIT_FLAG("IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, + "Enable identd (RFC 1413) user lookups - SLOW"), + AP_INIT_TAKE1("IdentityCheckTimeout", set_timeout, NULL, + RSRC_CONF|ACCESS_CONF, + "Identity check (RFC 1413) timeout duration (sec)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA ident_module; + +/* + * Optional function for the core to to the actual ident request + */ +static const char *ap_ident_lookup(request_rec *r) +{ + ident_config_rec *conf; + apr_socket_t *sock; + apr_status_t rv; + conn_rec *conn = r->connection; + server_rec *srv = r->server; + + conf = ap_get_module_config(r->per_dir_config, &ident_module); + + /* return immediately if ident requests are disabled */ + if (!(conf->do_rfc1413 & ~RFC1413_UNSET)) { + return NULL; + } + + rv = rfc1413_connect(&sock, conn, srv, conf->timeout); + if (rv == APR_SUCCESS) { + rv = rfc1413_query(sock, conn, srv); + apr_socket_close(sock); + } + if (rv != APR_SUCCESS) { + conn->remote_logname = FROM_UNKNOWN; + } + + return (const char *)conn->remote_logname; +} + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_ident_lookup); +} + +module AP_MODULE_DECLARE_DATA ident_module = +{ + STANDARD20_MODULE_STUFF, + create_ident_dir_config, /* dir config creater */ + merge_ident_dir_config, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + ident_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_ident.dsp b/trunk/modules/metadata/mod_ident.dsp new file mode 100644 index 0000000000..5a2b55f75f --- /dev/null +++ b/trunk/modules/metadata/mod_ident.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_ident" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_ident - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_ident.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_ident.mak" CFG="mod_ident - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_ident - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_ident - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_ident - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_ident_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_ident - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_ident_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ident.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ident.so + +!ENDIF + +# Begin Target + +# Name "mod_ident - Win32 Release" +# Name "mod_ident - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_ident.c +# End Source File +# Begin Source File + +SOURCE=.\mod_ident.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_ident - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ident.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ident.so "ident_module for Apache" ../../include/ap_release.h > .\mod_ident.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ident - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ident.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ident.so "ident_module for Apache" ../../include/ap_release.h > .\mod_ident.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_ident.exp b/trunk/modules/metadata/mod_ident.exp new file mode 100644 index 0000000000..26fe353de8 --- /dev/null +++ b/trunk/modules/metadata/mod_ident.exp @@ -0,0 +1 @@ +ident_module diff --git a/trunk/modules/metadata/mod_mime_magic.c b/trunk/modules/metadata/mod_mime_magic.c new file mode 100644 index 0000000000..f4ca7207b2 --- /dev/null +++ b/trunk/modules/metadata/mod_mime_magic.c @@ -0,0 +1,2477 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_mime_magic: MIME type lookup via file magic numbers + * Copyright (c) 1996-1997 Cisco Systems, Inc. + * + * This software was submitted by Cisco Systems to the Apache Software Foundation in July + * 1997. Future revisions and derivatives of this source code must + * acknowledge Cisco Systems as the original contributor of this module. + * All other licensing and usage conditions are those of the Apache Software Foundation. + * + * Some of this code is derived from the free version of the file command + * originally posted to comp.sources.unix. Copyright info for that program + * is included below as required. + * --------------------------------------------------------------------------- + * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin. + * + * This software is not subject to any license of the American Telephone and + * Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on any + * computer system, and to alter it and redistribute it freely, subject to + * the following restrictions: + * + * 1. The author is not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, credits + * must appear in the documentation. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users ever read + * sources, credits must appear in the documentation. + * + * 4. This notice may not be removed or altered. + * ------------------------------------------------------------------------- + * + * For compliance with Mr Darwin's terms: this has been very significantly + * modified from the free "file" command. + * - all-in-one file for compilation convenience when moving from one + * version of Apache to the next. + * - Memory allocation is done through the Apache API's apr_pool_t structure. + * - All functions have had necessary Apache API request or server + * structures passed to them where necessary to call other Apache API + * routines. (i.e. usually for logging, files, or memory allocation in + * itself or a called function.) + * - struct magic has been converted from an array to a single-ended linked + * list because it only grows one record at a time, it's only accessed + * sequentially, and the Apache API has no equivalent of realloc(). + * - Functions have been changed to get their parameters from the server + * configuration instead of globals. (It should be reentrant now but has + * not been tested in a threaded environment.) + * - Places where it used to print results to stdout now saves them in a + * list where they're used to set the MIME type in the Apache request + * record. + * - Command-line flags have been removed since they will never be used here. + * + * Ian Kluft + * Engineering Information Framework + * Central Engineering + * Cisco Systems, Inc. + * San Jose, CA, USA + * + * Initial installation July/August 1996 + * Misc bug fixes May 1997 + * Submission to Apache Software Foundation July 1997 + * + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" +#include "util_script.h" + +/* ### this isn't set by configure? does anybody set this? */ +#ifdef HAVE_UTIME_H +#include +#endif + +/* + * data structures and related constants + */ + +#define MODNAME "mod_mime_magic" +#define MIME_MAGIC_DEBUG 0 + +#define MIME_BINARY_UNKNOWN "application/octet-stream" +#define MIME_TEXT_UNKNOWN "text/plain" + +#define MAXMIMESTRING 256 + +/* HOWMANY must be at least 4096 to make gzip -dcq work */ +#define HOWMANY 4096 +/* SMALL_HOWMANY limits how much work we do to figure out text files */ +#define SMALL_HOWMANY 1024 +#define MAXDESC 50 /* max leng of text description */ +#define MAXstring 64 /* max leng of "string" types */ + +struct magic { + struct magic *next; /* link to next entry */ + int lineno; /* line number from magic file */ + + short flag; +#define INDIR 1 /* if '>(...)' appears, */ +#define UNSIGNED 2 /* comparison is unsigned */ + short cont_level; /* level of ">" */ + struct { + char type; /* byte short long */ + long offset; /* offset from indirection */ + } in; + long offset; /* offset to magic number */ + unsigned char reln; /* relation (0=eq, '>'=gt, etc) */ + char type; /* int, short, long or string. */ + char vallen; /* length of string value, if any */ +#define BYTE 1 +#define SHORT 2 +#define LONG 4 +#define STRING 5 +#define DATE 6 +#define BESHORT 7 +#define BELONG 8 +#define BEDATE 9 +#define LESHORT 10 +#define LELONG 11 +#define LEDATE 12 + union VALUETYPE { + unsigned char b; + unsigned short h; + unsigned long l; + char s[MAXstring]; + unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */ + unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */ + } value; /* either number or string */ + unsigned long mask; /* mask before comparison with value */ + char nospflag; /* supress space character */ + + /* NOTE: this string is suspected of overrunning - find it! */ + char desc[MAXDESC]; /* description */ +}; + +/* + * data structures for tar file recognition + * -------------------------------------------------------------------------- + * Header file for public domain tar (tape archive) program. + * + * @(#)tar.h 1.20 86/10/29 Public Domain. Created 25 August 1985 by John + * Gilmore, ihnp4!hoptoad!gnu. + * + * Header block on tape. + * + * I'm going to use traditional DP naming conventions here. A "block" is a big + * chunk of stuff that we do I/O on. A "record" is a piece of info that we + * care about. Typically many "record"s fit into a "block". + */ +#define RECORDSIZE 512 +#define NAMSIZ 100 +#define TUNMLEN 32 +#define TGNMLEN 32 + +union record { + char charptr[RECORDSIZE]; + struct header { + char name[NAMSIZ]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char linkflag; + char linkname[NAMSIZ]; + char magic[8]; + char uname[TUNMLEN]; + char gname[TGNMLEN]; + char devmajor[8]; + char devminor[8]; + } header; +}; + +/* The magic field is filled with this if uname and gname are valid. */ +#define TMAGIC "ustar " /* 7 chars and a null */ + +/* + * file-function prototypes + */ +static int ascmagic(request_rec *, unsigned char *, apr_size_t); +static int is_tar(unsigned char *, apr_size_t); +static int softmagic(request_rec *, unsigned char *, apr_size_t); +static int tryit(request_rec *, unsigned char *, apr_size_t, int); +static int zmagic(request_rec *, unsigned char *, apr_size_t); + +static int getvalue(server_rec *, struct magic *, char **); +static int hextoint(int); +static char *getstr(server_rec *, char *, char *, int, int *); +static int parse(server_rec *, apr_pool_t *p, char *, int); + +static int match(request_rec *, unsigned char *, apr_size_t); +static int mget(request_rec *, union VALUETYPE *, unsigned char *, + struct magic *, apr_size_t); +static int mcheck(request_rec *, union VALUETYPE *, struct magic *); +static void mprint(request_rec *, union VALUETYPE *, struct magic *); + +static int uncompress(request_rec *, int, + unsigned char **, apr_size_t); +static long from_oct(int, char *); +static int fsmagic(request_rec *r, const char *fn); + +/* + * includes for ASCII substring recognition formerly "names.h" in file + * command + * + * Original notes: names and types used by ascmagic in file(1). These tokens are + * here because they can appear anywhere in the first HOWMANY bytes, while + * tokens in /etc/magic must appear at fixed offsets into the file. Don't + * make HOWMANY too high unless you have a very fast CPU. + */ + +/* these types are used to index the apr_table_t 'types': keep em in sync! */ +/* HTML inserted in first because this is a web server module now */ +#define L_HTML 0 /* HTML */ +#define L_C 1 /* first and foremost on UNIX */ +#define L_FORT 2 /* the oldest one */ +#define L_MAKE 3 /* Makefiles */ +#define L_PLI 4 /* PL/1 */ +#define L_MACH 5 /* some kinda assembler */ +#define L_ENG 6 /* English */ +#define L_PAS 7 /* Pascal */ +#define L_MAIL 8 /* Electronic mail */ +#define L_NEWS 9 /* Usenet Netnews */ + +static char *types[] = +{ + "text/html", /* HTML */ + "text/plain", /* "c program text", */ + "text/plain", /* "fortran program text", */ + "text/plain", /* "make commands text", */ + "text/plain", /* "pl/1 program text", */ + "text/plain", /* "assembler program text", */ + "text/plain", /* "English text", */ + "text/plain", /* "pascal program text", */ + "message/rfc822", /* "mail text", */ + "message/news", /* "news text", */ + "application/binary", /* "can't happen error on names.h/types", */ + 0 +}; + +static struct names { + char *name; + short type; +} names[] = { + + /* These must be sorted by eye for optimal hit rate */ + /* Add to this list only after substantial meditation */ + { + "", L_HTML + }, + { + "", L_HTML + }, + { + "", L_HTML + }, + { + "", L_HTML + }, + { + "", L_HTML + }, + { + "<TITLE>", L_HTML + }, + { + "<h1>", L_HTML + }, + { + "<H1>", L_HTML + }, + { + "<!--", L_HTML + }, + { + "<!DOCTYPE HTML", L_HTML + }, + { + "/*", L_C + }, /* must precede "The", "the", etc. */ + { + "#include", L_C + }, + { + "char", L_C + }, + { + "The", L_ENG + }, + { + "the", L_ENG + }, + { + "double", L_C + }, + { + "extern", L_C + }, + { + "float", L_C + }, + { + "real", L_C + }, + { + "struct", L_C + }, + { + "union", L_C + }, + { + "CFLAGS", L_MAKE + }, + { + "LDFLAGS", L_MAKE + }, + { + "all:", L_MAKE + }, + { + ".PRECIOUS", L_MAKE + }, + /* + * Too many files of text have these words in them. Find another way to + * recognize Fortrash. + */ +#ifdef NOTDEF + { + "subroutine", L_FORT + }, + { + "function", L_FORT + }, + { + "block", L_FORT + }, + { + "common", L_FORT + }, + { + "dimension", L_FORT + }, + { + "integer", L_FORT + }, + { + "data", L_FORT + }, +#endif /* NOTDEF */ + { + ".ascii", L_MACH + }, + { + ".asciiz", L_MACH + }, + { + ".byte", L_MACH + }, + { + ".even", L_MACH + }, + { + ".globl", L_MACH + }, + { + "clr", L_MACH + }, + { + "(input,", L_PAS + }, + { + "dcl", L_PLI + }, + { + "Received:", L_MAIL + }, + { + ">From", L_MAIL + }, + { + "Return-Path:", L_MAIL + }, + { + "Cc:", L_MAIL + }, + { + "Newsgroups:", L_NEWS + }, + { + "Path:", L_NEWS + }, + { + "Organization:", L_NEWS + }, + { + NULL, 0 + } +}; + +#define NNAMES ((sizeof(names)/sizeof(struct names)) - 1) + +/* + * Result String List (RSL) + * + * The file(1) command prints its output. Instead, we store the various + * "printed" strings in a list (allocating memory as we go) and concatenate + * them at the end when we finally know how much space they'll need. + */ + +typedef struct magic_rsl_s { + char *str; /* string, possibly a fragment */ + struct magic_rsl_s *next; /* pointer to next fragment */ +} magic_rsl; + +/* + * Apache module configuration structures + */ + +/* per-server info */ +typedef struct { + const char *magicfile; /* where magic be found */ + struct magic *magic; /* head of magic config list */ + struct magic *last; +} magic_server_config_rec; + +/* per-request info */ +typedef struct { + magic_rsl *head; /* result string list */ + magic_rsl *tail; + unsigned suf_recursion; /* recursion depth in suffix check */ +} magic_req_rec; + +/* + * configuration functions - called by Apache API routines + */ + +module AP_MODULE_DECLARE_DATA mime_magic_module; + +static void *create_magic_server_config(apr_pool_t *p, server_rec *d) +{ + /* allocate the config - use pcalloc because it needs to be zeroed */ + return apr_pcalloc(p, sizeof(magic_server_config_rec)); +} + +static void *merge_magic_server_config(apr_pool_t *p, void *basev, void *addv) +{ + magic_server_config_rec *base = (magic_server_config_rec *) basev; + magic_server_config_rec *add = (magic_server_config_rec *) addv; + magic_server_config_rec *new = (magic_server_config_rec *) + apr_palloc(p, sizeof(magic_server_config_rec)); + + new->magicfile = add->magicfile ? add->magicfile : base->magicfile; + new->magic = NULL; + new->last = NULL; + return new; +} + +static const char *set_magicfile(cmd_parms *cmd, void *dummy, const char *arg) +{ + magic_server_config_rec *conf = (magic_server_config_rec *) + ap_get_module_config(cmd->server->module_config, + &mime_magic_module); + + if (!conf) { + return MODNAME ": server structure not allocated"; + } + conf->magicfile = arg; + return NULL; +} + +/* + * configuration file commands - exported to Apache API + */ + +static const command_rec mime_magic_cmds[] = +{ + AP_INIT_TAKE1("MimeMagicFile", set_magicfile, NULL, RSRC_CONF, + "Path to MIME Magic file (in file(1) format)"), + {NULL} +}; + +/* + * RSL (result string list) processing routines + * + * These collect strings that would have been printed in fragments by file(1) + * into a list of magic_rsl structures with the strings. When complete, + * they're concatenated together to become the MIME content and encoding + * types. + * + * return value conventions for these functions: functions which return int: + * failure = -1, other = result functions which return pointers: failure = 0, + * other = result + */ + +/* allocate a per-request structure and put it in the request record */ +static magic_req_rec *magic_set_config(request_rec *r) +{ + magic_req_rec *req_dat = (magic_req_rec *) apr_palloc(r->pool, + sizeof(magic_req_rec)); + + req_dat->head = req_dat->tail = (magic_rsl *) NULL; + ap_set_module_config(r->request_config, &mime_magic_module, req_dat); + return req_dat; +} + +/* add a string to the result string list for this request */ +/* it is the responsibility of the caller to allocate "str" */ +static int magic_rsl_add(request_rec *r, char *str) +{ + magic_req_rec *req_dat = (magic_req_rec *) + ap_get_module_config(r->request_config, &mime_magic_module); + magic_rsl *rsl; + + /* make sure we have a list to put it in */ + if (!req_dat) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, r, + MODNAME ": request config should not be NULL"); + if (!(req_dat = magic_set_config(r))) { + /* failure */ + return -1; + } + } + + /* allocate the list entry */ + rsl = (magic_rsl *) apr_palloc(r->pool, sizeof(magic_rsl)); + + /* fill it */ + rsl->str = str; + rsl->next = (magic_rsl *) NULL; + + /* append to the list */ + if (req_dat->head && req_dat->tail) { + req_dat->tail->next = rsl; + req_dat->tail = rsl; + } + else { + req_dat->head = req_dat->tail = rsl; + } + + /* success */ + return 0; +} + +/* RSL hook for puts-type functions */ +static int magic_rsl_puts(request_rec *r, char *str) +{ + return magic_rsl_add(r, str); +} + +/* RSL hook for printf-type functions */ +static int magic_rsl_printf(request_rec *r, char *str,...) +{ + va_list ap; + + char buf[MAXMIMESTRING]; + + /* assemble the string into the buffer */ + va_start(ap, str); + apr_vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + + /* add the buffer to the list */ + return magic_rsl_add(r, apr_pstrdup(r->pool, buf)); +} + +/* RSL hook for putchar-type functions */ +static int magic_rsl_putchar(request_rec *r, char c) +{ + char str[2]; + + /* high overhead for 1 char - just hope they don't do this much */ + str[0] = c; + str[1] = '\0'; + return magic_rsl_add(r, str); +} + +/* allocate and copy a contiguous string from a result string list */ +static char *rsl_strdup(request_rec *r, int start_frag, int start_pos, int len) +{ + char *result; /* return value */ + int cur_frag, /* current fragment number/counter */ + cur_pos, /* current position within fragment */ + res_pos; /* position in result string */ + magic_rsl *frag; /* list-traversal pointer */ + magic_req_rec *req_dat = (magic_req_rec *) + ap_get_module_config(r->request_config, &mime_magic_module); + + /* allocate the result string */ + result = (char *) apr_palloc(r->pool, len + 1); + + /* loop through and collect the string */ + res_pos = 0; + for (frag = req_dat->head, cur_frag = 0; + frag->next; + frag = frag->next, cur_frag++) { + /* loop to the first fragment */ + if (cur_frag < start_frag) + continue; + + /* loop through and collect chars */ + for (cur_pos = (cur_frag == start_frag) ? start_pos : 0; + frag->str[cur_pos]; + cur_pos++) { + if (cur_frag >= start_frag + && cur_pos >= start_pos + && res_pos <= len) { + result[res_pos++] = frag->str[cur_pos]; + if (res_pos > len) { + break; + } + } + } + } + + /* clean up and return */ + result[res_pos] = 0; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": rsl_strdup() %d chars: %s", res_pos - 1, result); +#endif + return result; +} + +/* states for the state-machine algorithm in magic_rsl_to_request() */ +typedef enum { + rsl_leading_space, rsl_type, rsl_subtype, rsl_separator, rsl_encoding +} rsl_states; + +/* process the RSL and set the MIME info in the request record */ +static int magic_rsl_to_request(request_rec *r) +{ + int cur_frag, /* current fragment number/counter */ + cur_pos, /* current position within fragment */ + type_frag, /* content type starting point: fragment */ + type_pos, /* content type starting point: position */ + type_len, /* content type length */ + encoding_frag, /* content encoding starting point: fragment */ + encoding_pos, /* content encoding starting point: position */ + encoding_len; /* content encoding length */ + + magic_rsl *frag; /* list-traversal pointer */ + rsl_states state; + + magic_req_rec *req_dat = (magic_req_rec *) + ap_get_module_config(r->request_config, &mime_magic_module); + + /* check if we have a result */ + if (!req_dat || !req_dat->head) { + /* empty - no match, we defer to other Apache modules */ + return DECLINED; + } + + /* start searching for the type and encoding */ + state = rsl_leading_space; + type_frag = type_pos = type_len = 0; + encoding_frag = encoding_pos = encoding_len = 0; + for (frag = req_dat->head, cur_frag = 0; + frag && frag->next; + frag = frag->next, cur_frag++) { + /* loop through the characters in the fragment */ + for (cur_pos = 0; frag->str[cur_pos]; cur_pos++) { + if (apr_isspace(frag->str[cur_pos])) { + /* process whitespace actions for each state */ + if (state == rsl_leading_space) { + /* eat whitespace in this state */ + continue; + } + else if (state == rsl_type) { + /* whitespace: type has no slash! */ + return DECLINED; + } + else if (state == rsl_subtype) { + /* whitespace: end of MIME type */ + state++; + continue; + } + else if (state == rsl_separator) { + /* eat whitespace in this state */ + continue; + } + else if (state == rsl_encoding) { + /* whitespace: end of MIME encoding */ + /* we're done */ + frag = req_dat->tail; + break; + } + else { + /* should not be possible */ + /* abandon malfunctioning module */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": bad state %d (ws)", state); + return DECLINED; + } + /* NOTREACHED */ + } + else if (state == rsl_type && + frag->str[cur_pos] == '/') { + /* copy the char and go to rsl_subtype state */ + type_len++; + state++; + } + else { + /* process non-space actions for each state */ + if (state == rsl_leading_space) { + /* non-space: begin MIME type */ + state++; + type_frag = cur_frag; + type_pos = cur_pos; + type_len = 1; + continue; + } + else if (state == rsl_type || + state == rsl_subtype) { + /* non-space: adds to type */ + type_len++; + continue; + } + else if (state == rsl_separator) { + /* non-space: begin MIME encoding */ + state++; + encoding_frag = cur_frag; + encoding_pos = cur_pos; + encoding_len = 1; + continue; + } + else if (state == rsl_encoding) { + /* non-space: adds to encoding */ + encoding_len++; + continue; + } + else { + /* should not be possible */ + /* abandon malfunctioning module */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": bad state %d (ns)", state); + return DECLINED; + } + /* NOTREACHED */ + } + /* NOTREACHED */ + } + } + + /* if we ended prior to state rsl_subtype, we had incomplete info */ + if (state != rsl_subtype && state != rsl_separator && + state != rsl_encoding) { + /* defer to other modules */ + return DECLINED; + } + + /* save the info in the request record */ + if (state == rsl_subtype || state == rsl_encoding || + state == rsl_encoding) { + char *tmp; + tmp = rsl_strdup(r, type_frag, type_pos, type_len); + /* XXX: this could be done at config time I'm sure... but I'm + * confused by all this magic_rsl stuff. -djg */ + ap_content_type_tolower(tmp); + ap_set_content_type(r, tmp); + } + if (state == rsl_encoding) { + char *tmp; + tmp = rsl_strdup(r, encoding_frag, + encoding_pos, encoding_len); + /* XXX: this could be done at config time I'm sure... but I'm + * confused by all this magic_rsl stuff. -djg */ + ap_str_tolower(tmp); + r->content_encoding = tmp; + } + + /* detect memory allocation or other errors */ + if (!r->content_type || + (state == rsl_encoding && !r->content_encoding)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": unexpected state %d; could be caused by bad " + "data in magic file", + state); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* success! */ + return OK; +} + +/* + * magic_process - process input file r Apache API request record + * (formerly called "process" in file command, prefix added for clarity) Opens + * the file and reads a fixed-size buffer to begin processing the contents. + */ +static int magic_process(request_rec *r) +{ + apr_file_t *fd = NULL; + unsigned char buf[HOWMANY + 1]; /* one extra for terminating '\0' */ + apr_size_t nbytes = 0; /* number of bytes read from a datafile */ + int result; + + /* + * first try judging the file based on its filesystem status + */ + switch ((result = fsmagic(r, r->filename))) { + case DONE: + magic_rsl_putchar(r, '\n'); + return OK; + case OK: + break; + default: + /* fatal error, bail out */ + return result; + } + + if (apr_file_open(&fd, r->filename, APR_READ, APR_OS_DEFAULT, r->pool) != APR_SUCCESS) { + /* We can't open it, but we were able to stat it. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": can't read `%s'", r->filename); + /* let some other handler decide what the problem is */ + return DECLINED; + } + + /* + * try looking at the first HOWMANY bytes + */ + nbytes = sizeof(buf) - 1; + if ((result = apr_file_read(fd, (char *) buf, &nbytes)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, result, r, + MODNAME ": read failed: %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (nbytes == 0) { + return DECLINED; + } + else { + buf[nbytes++] = '\0'; /* null-terminate it */ + result = tryit(r, buf, nbytes, 1); + if (result != OK) { + return result; + } + } + + (void) apr_file_close(fd); + (void) magic_rsl_putchar(r, '\n'); + + return OK; +} + + +static int tryit(request_rec *r, unsigned char *buf, apr_size_t nb, + int checkzmagic) +{ + /* + * Try compression stuff + */ + if (checkzmagic == 1) { + if (zmagic(r, buf, nb) == 1) + return OK; + } + + /* + * try tests in /etc/magic (or surrogate magic file) + */ + if (softmagic(r, buf, nb) == 1) + return OK; + + /* + * try known keywords, check for ascii-ness too. + */ + if (ascmagic(r, buf, nb) == 1) + return OK; + + /* + * abandon hope, all ye who remain here + */ + return DECLINED; +} + +#define EATAB {while (apr_isspace(*l)) ++l;} + +/* + * apprentice - load configuration from the magic file r + * API request record + */ +static int apprentice(server_rec *s, apr_pool_t *p) +{ + apr_file_t *f = NULL; + apr_status_t result; + char line[BUFSIZ + 1]; + int errs = 0; + int lineno; +#if MIME_MAGIC_DEBUG + int rule = 0; + struct magic *m, *prevm; +#endif + magic_server_config_rec *conf = (magic_server_config_rec *) + ap_get_module_config(s->module_config, &mime_magic_module); + const char *fname = ap_server_root_relative(p, conf->magicfile); + + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, + MODNAME ": Invalid magic file path %s", conf->magicfile); + return -1; + } + if ((result = apr_file_open(&f, fname, APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, p) != APR_SUCCESS)) { + ap_log_error(APLOG_MARK, APLOG_ERR, result, s, + MODNAME ": can't read magic file %s", fname); + return -1; + } + + /* set up the magic list (empty) */ + conf->magic = conf->last = NULL; + + /* parse it */ + for (lineno = 1; apr_file_gets(line, BUFSIZ, f) == APR_SUCCESS; lineno++) { + int ws_offset; + char *last = line + strlen(line) - 1; /* guaranteed that len >= 1 */ + + /* delete newline and potential carriage return */ + if (*last == '\n') { + *last = '\0'; + --last; + } + if (*last == '\r') { + *last = '\0'; + } + + /* skip leading whitespace */ + ws_offset = 0; + while (line[ws_offset] && apr_isspace(line[ws_offset])) { + ws_offset++; + } + + /* skip blank lines */ + if (line[ws_offset] == 0) { + continue; + } + + /* comment, do not parse */ + if (line[ws_offset] == '#') + continue; + +#if MIME_MAGIC_DEBUG + /* if we get here, we're going to use it so count it */ + rule++; +#endif + + /* parse it */ + if (parse(s, p, line + ws_offset, lineno) != 0) + ++errs; + } + + (void) apr_file_close(f); + +#if MIME_MAGIC_DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": apprentice conf=%x file=%s m=%s m->next=%s last=%s", + conf, + conf->magicfile ? conf->magicfile : "NULL", + conf->magic ? "set" : "NULL", + (conf->magic && conf->magic->next) ? "set" : "NULL", + conf->last ? "set" : "NULL"); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": apprentice read %d lines, %d rules, %d errors", + lineno, rule, errs); +#endif + +#if MIME_MAGIC_DEBUG + prevm = 0; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": apprentice test"); + for (m = conf->magic; m; m = m->next) { + if (apr_isprint((((unsigned long) m) >> 24) & 255) && + apr_isprint((((unsigned long) m) >> 16) & 255) && + apr_isprint((((unsigned long) m) >> 8) & 255) && + apr_isprint(((unsigned long) m) & 255)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": apprentice: POINTER CLOBBERED! " + "m=\"%c%c%c%c\" line=%d", + (((unsigned long) m) >> 24) & 255, + (((unsigned long) m) >> 16) & 255, + (((unsigned long) m) >> 8) & 255, + ((unsigned long) m) & 255, + prevm ? prevm->lineno : -1); + break; + } + prevm = m; + } +#endif + + return (errs ? -1 : 0); +} + +/* + * extend the sign bit if the comparison is to be signed + */ +static unsigned long signextend(server_rec *s, struct magic *m, unsigned long v) +{ + if (!(m->flag & UNSIGNED)) + switch (m->type) { + /* + * Do not remove the casts below. They are vital. When later + * compared with the data, the sign extension must have happened. + */ + case BYTE: + v = (char) v; + break; + case SHORT: + case BESHORT: + case LESHORT: + v = (short) v; + break; + case DATE: + case BEDATE: + case LEDATE: + case LONG: + case BELONG: + case LELONG: + v = (long) v; + break; + case STRING: + break; + default: + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + MODNAME ": can't happen: m->type=%d", m->type); + return -1; + } + return v; +} + +/* + * parse one line from magic file, put into magic[index++] if valid + */ +static int parse(server_rec *serv, apr_pool_t *p, char *l, int lineno) +{ + struct magic *m; + char *t, *s; + magic_server_config_rec *conf = (magic_server_config_rec *) + ap_get_module_config(serv->module_config, &mime_magic_module); + + /* allocate magic structure entry */ + m = (struct magic *) apr_pcalloc(p, sizeof(struct magic)); + + /* append to linked list */ + m->next = NULL; + if (!conf->magic || !conf->last) { + conf->magic = conf->last = m; + } + else { + conf->last->next = m; + conf->last = m; + } + + /* set values in magic structure */ + m->flag = 0; + m->cont_level = 0; + m->lineno = lineno; + + while (*l == '>') { + ++l; /* step over */ + m->cont_level++; + } + + if (m->cont_level != 0 && *l == '(') { + ++l; /* step over */ + m->flag |= INDIR; + } + + /* get offset, then skip over it */ + m->offset = (int) strtol(l, &t, 0); + if (l == t) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv, + MODNAME ": offset %s invalid", l); + } + l = t; + + if (m->flag & INDIR) { + m->in.type = LONG; + m->in.offset = 0; + /* + * read [.lbs][+-]nnnnn) + */ + if (*l == '.') { + switch (*++l) { + case 'l': + m->in.type = LONG; + break; + case 's': + m->in.type = SHORT; + break; + case 'b': + m->in.type = BYTE; + break; + default: + ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv, + MODNAME ": indirect offset type %c invalid", *l); + break; + } + l++; + } + s = l; + if (*l == '+' || *l == '-') + l++; + if (apr_isdigit((unsigned char) *l)) { + m->in.offset = strtol(l, &t, 0); + if (*s == '-') + m->in.offset = -m->in.offset; + } + else + t = l; + if (*t++ != ')') { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv, + MODNAME ": missing ')' in indirect offset"); + } + l = t; + } + + + while (apr_isdigit((unsigned char) *l)) + ++l; + EATAB; + +#define NBYTE 4 +#define NSHORT 5 +#define NLONG 4 +#define NSTRING 6 +#define NDATE 4 +#define NBESHORT 7 +#define NBELONG 6 +#define NBEDATE 6 +#define NLESHORT 7 +#define NLELONG 6 +#define NLEDATE 6 + + if (*l == 'u') { + ++l; + m->flag |= UNSIGNED; + } + + /* get type, skip it */ + if (strncmp(l, "byte", NBYTE) == 0) { + m->type = BYTE; + l += NBYTE; + } + else if (strncmp(l, "short", NSHORT) == 0) { + m->type = SHORT; + l += NSHORT; + } + else if (strncmp(l, "long", NLONG) == 0) { + m->type = LONG; + l += NLONG; + } + else if (strncmp(l, "string", NSTRING) == 0) { + m->type = STRING; + l += NSTRING; + } + else if (strncmp(l, "date", NDATE) == 0) { + m->type = DATE; + l += NDATE; + } + else if (strncmp(l, "beshort", NBESHORT) == 0) { + m->type = BESHORT; + l += NBESHORT; + } + else if (strncmp(l, "belong", NBELONG) == 0) { + m->type = BELONG; + l += NBELONG; + } + else if (strncmp(l, "bedate", NBEDATE) == 0) { + m->type = BEDATE; + l += NBEDATE; + } + else if (strncmp(l, "leshort", NLESHORT) == 0) { + m->type = LESHORT; + l += NLESHORT; + } + else if (strncmp(l, "lelong", NLELONG) == 0) { + m->type = LELONG; + l += NLELONG; + } + else if (strncmp(l, "ledate", NLEDATE) == 0) { + m->type = LEDATE; + l += NLEDATE; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv, + MODNAME ": type %s invalid", l); + return -1; + } + /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ + if (*l == '&') { + ++l; + m->mask = signextend(serv, m, strtol(l, &l, 0)); + } + else + m->mask = ~0L; + EATAB; + + switch (*l) { + case '>': + case '<': + /* Old-style anding: "0 byte &0x80 dynamically linked" */ + case '&': + case '^': + case '=': + m->reln = *l; + ++l; + break; + case '!': + if (m->type != STRING) { + m->reln = *l; + ++l; + break; + } + /* FALL THROUGH */ + default: + if (*l == 'x' && apr_isspace(l[1])) { + m->reln = *l; + ++l; + goto GetDesc; /* Bill The Cat */ + } + m->reln = '='; + break; + } + EATAB; + + if (getvalue(serv, m, &l)) + return -1; + /* + * now get last part - the description + */ + GetDesc: + EATAB; + if (l[0] == '\b') { + ++l; + m->nospflag = 1; + } + else if ((l[0] == '\\') && (l[1] == 'b')) { + ++l; + ++l; + m->nospflag = 1; + } + else + m->nospflag = 0; + strncpy(m->desc, l, sizeof(m->desc) - 1); + m->desc[sizeof(m->desc) - 1] = '\0'; + +#if MIME_MAGIC_DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, serv, + MODNAME ": parse line=%d m=%x next=%x cont=%d desc=%s", + lineno, m, m->next, m->cont_level, m->desc); +#endif /* MIME_MAGIC_DEBUG */ + + return 0; +} + +/* + * Read a numeric value from a pointer, into the value union of a magic + * pointer, according to the magic type. Update the string pointer to point + * just after the number read. Return 0 for success, non-zero for failure. + */ +static int getvalue(server_rec *s, struct magic *m, char **p) +{ + int slen; + + if (m->type == STRING) { + *p = getstr(s, *p, m->value.s, sizeof(m->value.s), &slen); + m->vallen = slen; + } + else if (m->reln != 'x') + m->value.l = signextend(s, m, strtol(*p, p, 0)); + return 0; +} + +/* + * Convert a string containing C character escapes. Stop at an unescaped + * space or tab. Copy the converted version to "p", returning its length in + * *slen. Return updated scan pointer as function result. + */ +static char *getstr(server_rec *serv, register char *s, register char *p, + int plen, int *slen) +{ + char *origs = s, *origp = p; + char *pmax = p + plen - 1; + register int c; + register int val; + + while ((c = *s++) != '\0') { + if (apr_isspace(c)) + break; + if (p >= pmax) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv, + MODNAME ": string too long: %s", origs); + break; + } + if (c == '\\') { + switch (c = *s++) { + + case '\0': + goto out; + + default: + *p++ = (char) c; + break; + + case 'n': + *p++ = '\n'; + break; + + case 'r': + *p++ = '\r'; + break; + + case 'b': + *p++ = '\b'; + break; + + case 't': + *p++ = '\t'; + break; + + case 'f': + *p++ = '\f'; + break; + + case 'v': + *p++ = '\v'; + break; + + /* \ and up to 3 octal digits */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + val = c - '0'; + c = *s++; /* try for 2 */ + if (c >= '0' && c <= '7') { + val = (val << 3) | (c - '0'); + c = *s++; /* try for 3 */ + if (c >= '0' && c <= '7') + val = (val << 3) | (c - '0'); + else + --s; + } + else + --s; + *p++ = (char) val; + break; + + /* \x and up to 3 hex digits */ + case 'x': + val = 'x'; /* Default if no digits */ + c = hextoint(*s++); /* Get next char */ + if (c >= 0) { + val = c; + c = hextoint(*s++); + if (c >= 0) { + val = (val << 4) + c; + c = hextoint(*s++); + if (c >= 0) { + val = (val << 4) + c; + } + else + --s; + } + else + --s; + } + else + --s; + *p++ = (char) val; + break; + } + } + else + *p++ = (char) c; + } + out: + *p = '\0'; + *slen = p - origp; + return s; +} + + +/* Single hex char to int; -1 if not a hex char. */ +static int hextoint(int c) +{ + if (apr_isdigit(c)) + return c - '0'; + if ((c >= 'a') && (c <= 'f')) + return c + 10 - 'a'; + if ((c >= 'A') && (c <= 'F')) + return c + 10 - 'A'; + return -1; +} + + +/* + * return DONE to indicate it's been handled + * return OK to indicate it's a regular file still needing handling + * other returns indicate a failure of some sort + */ +static int fsmagic(request_rec *r, const char *fn) +{ + switch (r->finfo.filetype) { + case APR_DIR: + magic_rsl_puts(r, DIR_MAGIC_TYPE); + return DONE; + case APR_CHR: + /* + * (void) magic_rsl_printf(r,"character special (%d/%d)", + * major(sb->st_rdev), minor(sb->st_rdev)); + */ + (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN); + return DONE; + case APR_BLK: + /* + * (void) magic_rsl_printf(r,"block special (%d/%d)", + * major(sb->st_rdev), minor(sb->st_rdev)); + */ + (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN); + return DONE; + /* TODO add code to handle V7 MUX and Blit MUX files */ + case APR_PIPE: + /* + * magic_rsl_puts(r,"fifo (named pipe)"); + */ + (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN); + return DONE; + case APR_LNK: + /* We used stat(), the only possible reason for this is that the + * symlink is broken. + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": broken symlink (%s)", fn); + return HTTP_INTERNAL_SERVER_ERROR; + case APR_SOCK: + magic_rsl_puts(r, MIME_BINARY_UNKNOWN); + return DONE; + case APR_REG: + break; + default: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": invalid file type %d.", r->finfo.filetype); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* + * regular file, check next possibility + */ + if (r->finfo.size == 0) { + magic_rsl_puts(r, MIME_TEXT_UNKNOWN); + return DONE; + } + return OK; +} + +/* + * softmagic - lookup one file in database (already read from /etc/magic by + * apprentice.c). Passed the name and FILE * of one file to be typed. + */ + /* ARGSUSED1 *//* nbytes passed for regularity, maybe need later */ +static int softmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes) +{ + if (match(r, buf, nbytes)) + return 1; + + return 0; +} + +/* + * Go through the whole list, stopping if you find a match. Process all the + * continuations of that match before returning. + * + * We support multi-level continuations: + * + * At any time when processing a successful top-level match, there is a current + * continuation level; it represents the level of the last successfully + * matched continuation. + * + * Continuations above that level are skipped as, if we see one, it means that + * the continuation that controls them - i.e, the lower-level continuation + * preceding them - failed to match. + * + * Continuations below that level are processed as, if we see one, it means + * we've finished processing or skipping higher-level continuations under the + * control of a successful or unsuccessful lower-level continuation, and are + * now seeing the next lower-level continuation and should process it. The + * current continuation level reverts to the level of the one we're seeing. + * + * Continuations at the current level are processed as, if we see one, there's + * no lower-level continuation that may have failed. + * + * If a continuation matches, we bump the current continuation level so that + * higher-level continuations are processed. + */ +static int match(request_rec *r, unsigned char *s, apr_size_t nbytes) +{ +#if MIME_MAGIC_DEBUG + int rule_counter = 0; +#endif + int cont_level = 0; + int need_separator = 0; + union VALUETYPE p; + magic_server_config_rec *conf = (magic_server_config_rec *) + ap_get_module_config(r->server->module_config, &mime_magic_module); + struct magic *m; + +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": match conf=%x file=%s m=%s m->next=%s last=%s", + conf, + conf->magicfile ? conf->magicfile : "NULL", + conf->magic ? "set" : "NULL", + (conf->magic && conf->magic->next) ? "set" : "NULL", + conf->last ? "set" : "NULL"); +#endif + +#if MIME_MAGIC_DEBUG + for (m = conf->magic; m; m = m->next) { + if (apr_isprint((((unsigned long) m) >> 24) & 255) && + apr_isprint((((unsigned long) m) >> 16) & 255) && + apr_isprint((((unsigned long) m) >> 8) & 255) && + apr_isprint(((unsigned long) m) & 255)) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": match: POINTER CLOBBERED! " + "m=\"%c%c%c%c\"", + (((unsigned long) m) >> 24) & 255, + (((unsigned long) m) >> 16) & 255, + (((unsigned long) m) >> 8) & 255, + ((unsigned long) m) & 255); + break; + } + } +#endif + + for (m = conf->magic; m; m = m->next) { +#if MIME_MAGIC_DEBUG + rule_counter++; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": line=%d desc=%s", m->lineno, m->desc); +#endif + + /* check if main entry matches */ + if (!mget(r, &p, s, m, nbytes) || + !mcheck(r, &p, m)) { + struct magic *m_cont; + + /* + * main entry didn't match, flush its continuations + */ + if (!m->next || (m->next->cont_level == 0)) { + continue; + } + + m_cont = m->next; + while (m_cont && (m_cont->cont_level != 0)) { +#if MIME_MAGIC_DEBUG + rule_counter++; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": line=%d mc=%x mc->next=%x cont=%d desc=%s", + m_cont->lineno, m_cont, + m_cont->next, m_cont->cont_level, + m_cont->desc); +#endif + /* + * this trick allows us to keep *m in sync when the continue + * advances the pointer + */ + m = m_cont; + m_cont = m_cont->next; + } + continue; + } + + /* if we get here, the main entry rule was a match */ + /* this will be the last run through the loop */ +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": rule matched, line=%d type=%d %s", + m->lineno, m->type, + (m->type == STRING) ? m->value.s : ""); +#endif + + /* print the match */ + mprint(r, &p, m); + + /* + * If we printed something, we'll need to print a blank before we + * print something else. + */ + if (m->desc[0]) + need_separator = 1; + /* and any continuations that match */ + cont_level++; + /* + * while (m && m->next && m->next->cont_level != 0 && ( m = m->next + * )) + */ + m = m->next; + while (m && (m->cont_level != 0)) { +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": match line=%d cont=%d type=%d %s", + m->lineno, m->cont_level, m->type, + (m->type == STRING) ? m->value.s : ""); +#endif + if (cont_level >= m->cont_level) { + if (cont_level > m->cont_level) { + /* + * We're at the end of the level "cont_level" + * continuations. + */ + cont_level = m->cont_level; + } + if (mget(r, &p, s, m, nbytes) && + mcheck(r, &p, m)) { + /* + * This continuation matched. Print its message, with a + * blank before it if the previous item printed and this + * item isn't empty. + */ + /* space if previous printed */ + if (need_separator + && (m->nospflag == 0) + && (m->desc[0] != '\0') + ) { + (void) magic_rsl_putchar(r, ' '); + need_separator = 0; + } + mprint(r, &p, m); + if (m->desc[0]) + need_separator = 1; + + /* + * If we see any continuations at a higher level, process + * them. + */ + cont_level++; + } + } + + /* move to next continuation record */ + m = m->next; + } +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": matched after %d rules", rule_counter); +#endif + return 1; /* all through */ + } +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": failed after %d rules", rule_counter); +#endif + return 0; /* no match at all */ +} + +static void mprint(request_rec *r, union VALUETYPE *p, struct magic *m) +{ + char *pp; + unsigned long v; + char time_str[APR_CTIME_LEN]; + + switch (m->type) { + case BYTE: + v = p->b; + break; + + case SHORT: + case BESHORT: + case LESHORT: + v = p->h; + break; + + case LONG: + case BELONG: + case LELONG: + v = p->l; + break; + + case STRING: + if (m->reln == '=') { + (void) magic_rsl_printf(r, m->desc, m->value.s); + } + else { + (void) magic_rsl_printf(r, m->desc, p->s); + } + return; + + case DATE: + case BEDATE: + case LEDATE: + apr_ctime(time_str, apr_time_from_sec(*(time_t *)&p->l)); + pp = time_str; + (void) magic_rsl_printf(r, m->desc, pp); + return; + default: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": invalid m->type (%d) in mprint().", + m->type); + return; + } + + v = signextend(r->server, m, v) & m->mask; + (void) magic_rsl_printf(r, m->desc, (unsigned long) v); +} + +/* + * Convert the byte order of the data we are looking at + */ +static int mconvert(request_rec *r, union VALUETYPE *p, struct magic *m) +{ + char *rt; + + switch (m->type) { + case BYTE: + case SHORT: + case LONG: + case DATE: + return 1; + case STRING: + /* Null terminate and eat the return */ + p->s[sizeof(p->s) - 1] = '\0'; + if ((rt = strchr(p->s, '\n')) != NULL) + *rt = '\0'; + return 1; + case BESHORT: + p->h = (short) ((p->hs[0] << 8) | (p->hs[1])); + return 1; + case BELONG: + case BEDATE: + p->l = (long) + ((p->hl[0] << 24) | (p->hl[1] << 16) | (p->hl[2] << 8) | (p->hl[3])); + return 1; + case LESHORT: + p->h = (short) ((p->hs[1] << 8) | (p->hs[0])); + return 1; + case LELONG: + case LEDATE: + p->l = (long) + ((p->hl[3] << 24) | (p->hl[2] << 16) | (p->hl[1] << 8) | (p->hl[0])); + return 1; + default: + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": invalid type %d in mconvert().", m->type); + return 0; + } +} + + +static int mget(request_rec *r, union VALUETYPE *p, unsigned char *s, + struct magic *m, apr_size_t nbytes) +{ + long offset = m->offset; + + if (offset + sizeof(union VALUETYPE) > nbytes) + return 0; + + memcpy(p, s + offset, sizeof(union VALUETYPE)); + + if (!mconvert(r, p, m)) + return 0; + + if (m->flag & INDIR) { + + switch (m->in.type) { + case BYTE: + offset = p->b + m->in.offset; + break; + case SHORT: + offset = p->h + m->in.offset; + break; + case LONG: + offset = p->l + m->in.offset; + break; + } + + if (offset + sizeof(union VALUETYPE) > nbytes) + return 0; + + memcpy(p, s + offset, sizeof(union VALUETYPE)); + + if (!mconvert(r, p, m)) + return 0; + } + return 1; +} + +static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m) +{ + register unsigned long l = m->value.l; + register unsigned long v; + int matched; + + if ((m->value.s[0] == 'x') && (m->value.s[1] == '\0')) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": BOINK"); + return 1; + } + + switch (m->type) { + case BYTE: + v = p->b; + break; + + case SHORT: + case BESHORT: + case LESHORT: + v = p->h; + break; + + case LONG: + case BELONG: + case LELONG: + case DATE: + case BEDATE: + case LEDATE: + v = p->l; + break; + + case STRING: + l = 0; + /* + * What we want here is: v = strncmp(m->value.s, p->s, m->vallen); + * but ignoring any nulls. bcmp doesn't give -/+/0 and isn't + * universally available anyway. + */ + v = 0; + { + register unsigned char *a = (unsigned char *) m->value.s; + register unsigned char *b = (unsigned char *) p->s; + register int len = m->vallen; + + while (--len >= 0) + if ((v = *b++ - *a++) != 0) + break; + } + break; + default: + /* bogosity, pretend that it just wasn't a match */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": invalid type %d in mcheck().", m->type); + return 0; + } + + v = signextend(r->server, m, v) & m->mask; + + switch (m->reln) { + case 'x': +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%lu == *any* = 1", v); +#endif + matched = 1; + break; + + case '!': + matched = v != l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%lu != %lu = %d", v, l, matched); +#endif + break; + + case '=': + matched = v == l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%lu == %lu = %d", v, l, matched); +#endif + break; + + case '>': + if (m->flag & UNSIGNED) { + matched = v > l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%lu > %lu = %d", v, l, matched); +#endif + } + else { + matched = (long) v > (long) l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%ld > %ld = %d", v, l, matched); +#endif + } + break; + + case '<': + if (m->flag & UNSIGNED) { + matched = v < l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%lu < %lu = %d", v, l, matched); +#endif + } + else { + matched = (long) v < (long) l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "%ld < %ld = %d", v, l, matched); +#endif + } + break; + + case '&': + matched = (v & l) == l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "((%lx & %lx) == %lx) = %d", v, l, l, matched); +#endif + break; + + case '^': + matched = (v & l) != l; +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "((%lx & %lx) != %lx) = %d", v, l, l, matched); +#endif + break; + + default: + /* bogosity, pretend it didn't match */ + matched = 0; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + MODNAME ": mcheck: can't happen: invalid relation %d.", + m->reln); + break; + } + + return matched; +} + +/* an optimization over plain strcmp() */ +#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) + +static int ascmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes) +{ + int has_escapes = 0; + unsigned char *s; + char nbuf[HOWMANY + 1]; /* one extra for terminating '\0' */ + char *token; + register struct names *p; + int small_nbytes; + char *strtok_state; + + /* these are easy, do them first */ + + /* + * for troff, look for . + letter + letter or .\"; this must be done to + * disambiguate tar archives' ./file and other trash from real troff + * input. + */ + if (*buf == '.') { + unsigned char *tp = buf + 1; + + while (apr_isspace(*tp)) + ++tp; /* skip leading whitespace */ + if ((apr_isalnum(*tp) || *tp == '\\') && + (apr_isalnum(*(tp + 1)) || *tp == '"')) { + magic_rsl_puts(r, "application/x-troff"); + return 1; + } + } + if ((*buf == 'c' || *buf == 'C') && apr_isspace(*(buf + 1))) { + /* Fortran */ + magic_rsl_puts(r, "text/plain"); + return 1; + } + + /* look for tokens from names.h - this is expensive!, so we'll limit + * ourselves to only SMALL_HOWMANY bytes */ + small_nbytes = (nbytes > SMALL_HOWMANY) ? SMALL_HOWMANY : nbytes; + /* make a copy of the buffer here because apr_strtok() will destroy it */ + s = (unsigned char *) memcpy(nbuf, buf, small_nbytes); + s[small_nbytes] = '\0'; + has_escapes = (memchr(s, '\033', small_nbytes) != NULL); + while ((token = apr_strtok((char *) s, " \t\n\r\f", &strtok_state)) != NULL) { + s = NULL; /* make apr_strtok() keep on tokin' */ + for (p = names; p < names + NNAMES; p++) { + if (STREQ(p->name, token)) { + magic_rsl_puts(r, types[p->type]); + if (has_escapes) + magic_rsl_puts(r, " (with escape sequences)"); + return 1; + } + } + } + + switch (is_tar(buf, nbytes)) { + case 1: + /* V7 tar archive */ + magic_rsl_puts(r, "application/x-tar"); + return 1; + case 2: + /* POSIX tar archive */ + magic_rsl_puts(r, "application/x-tar"); + return 1; + } + + /* all else fails, but it is ascii... */ + return 0; +} + + +/* + * compress routines: zmagic() - returns 0 if not recognized, uncompresses + * and prints information if recognized uncompress(s, method, old, n, newch) + * - uncompress old into new, using method, return sizeof new + */ + +static struct { + char *magic; + apr_size_t maglen; + char *argv[3]; + int silent; + char *encoding; /* MUST be lowercase */ +} compr[] = { + + /* we use gzip here rather than uncompress because we have to pass + * it a full filename -- and uncompress only considers filenames + * ending with .Z + */ + { + "\037\235", 2, { + "gzip", "-dcq", NULL + }, 0, "x-compress" + }, + { + "\037\213", 2, { + "gzip", "-dcq", NULL + }, 1, "x-gzip" + }, + /* + * XXX pcat does not work, cause I don't know how to make it read stdin, + * so we use gzip + */ + { + "\037\036", 2, { + "gzip", "-dcq", NULL + }, 0, "x-gzip" + }, +}; + +static int ncompr = sizeof(compr) / sizeof(compr[0]); + +static int zmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes) +{ + unsigned char *newbuf; + int newsize; + int i; + + for (i = 0; i < ncompr; i++) { + if (nbytes < compr[i].maglen) + continue; + if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0) + break; + } + + if (i == ncompr) + return 0; + + if ((newsize = uncompress(r, i, &newbuf, nbytes)) > 0) { + if (tryit(r, newbuf, newsize, 0) != OK) { + return 0; + } + + /* set encoding type in the request record */ + r->content_encoding = compr[i].encoding; + } + return 1; +} + + +struct uncompress_parms { + request_rec *r; + int method; +}; + +static int create_uncompress_child(struct uncompress_parms *parm, apr_pool_t *cntxt, + apr_file_t **pipe_in) +{ + int rc = 1; + const char *new_argv[4]; + const char *const *env; + request_rec *r = parm->r; + apr_pool_t *child_context = cntxt; + apr_procattr_t *procattr; + apr_proc_t *procnew; + + /* XXX missing 1.3 logic: + * + * what happens when !compr[parm->method].silent? + * Should we create the err pipe, read it, and copy to the log? + */ + + env = (const char *const *)ap_create_environment(child_context, r->subprocess_env); + + if ((apr_procattr_create(&procattr, child_context) != APR_SUCCESS) || + (apr_procattr_io_set(procattr, APR_FULL_BLOCK, + APR_FULL_BLOCK, APR_NO_PIPE) != APR_SUCCESS) || + (apr_procattr_dir_set(procattr, r->filename) != APR_SUCCESS) || + (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)) { + /* Something bad happened, tell the world. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r, + "couldn't setup child process: %s", r->filename); + } + else { + new_argv[0] = compr[parm->method].argv[0]; + new_argv[1] = compr[parm->method].argv[1]; + new_argv[2] = r->filename; + new_argv[3] = NULL; + + procnew = apr_pcalloc(child_context, sizeof(*procnew)); + rc = apr_proc_create(procnew, compr[parm->method].argv[0], + new_argv, env, procattr, child_context); + + if (rc != APR_SUCCESS) { + /* Bad things happened. Everyone should have cleaned up. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r, + MODNAME ": could not execute `%s'.", + compr[parm->method].argv[0]); + } + else { + apr_pool_note_subprocess(child_context, procnew, APR_KILL_AFTER_TIMEOUT); + *pipe_in = procnew->out; + } + } + + return (rc); +} + +static int uncompress(request_rec *r, int method, + unsigned char **newch, apr_size_t n) +{ + struct uncompress_parms parm; + apr_file_t *pipe_out = NULL; + apr_pool_t *sub_context; + apr_status_t rv; + + parm.r = r; + parm.method = method; + + /* We make a sub_pool so that we can collect our child early, otherwise + * there are cases (i.e. generating directory indicies with mod_autoindex) + * where we would end up with LOTS of zombies. + */ + if (apr_pool_create(&sub_context, r->pool) != APR_SUCCESS) + return -1; + + if ((rv = create_uncompress_child(&parm, sub_context, &pipe_out)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + MODNAME ": couldn't spawn uncompress process: %s", r->uri); + return -1; + } + + *newch = (unsigned char *) apr_palloc(r->pool, n); + rv = apr_file_read(pipe_out, *newch, &n); + if (n == 0) { + apr_pool_destroy(sub_context); + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + MODNAME ": read failed from uncompress of %s", r->filename); + return -1; + } + apr_pool_destroy(sub_context); + return n; +} + +/* + * is_tar() -- figure out whether file is a tar archive. + * + * Stolen (by author of file utility) from the public domain tar program: Public + * Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). + * + * @(#)list.c 1.18 9/23/86 Public Domain - gnu $Id: mod_mime_magic.c,v 1.7 + * 1997/06/24 00:41:02 ikluft Exp ikluft $ + * + * Comments changed and some code/comments reformatted for file command by Ian + * Darwin. + */ + +#define isodigit(c) (((unsigned char)(c) >= '0') && ((unsigned char)(c) <= '7')) + +/* + * Return 0 if the checksum is bad (i.e., probably not a tar archive), 1 for + * old UNIX tar file, 2 for Unix Std (POSIX) tar file. + */ + +static int is_tar(unsigned char *buf, apr_size_t nbytes) +{ + register union record *header = (union record *) buf; + register int i; + register long sum, recsum; + register char *p; + + if (nbytes < sizeof(union record)) + return 0; + + recsum = from_oct(8, header->header.chksum); + + sum = 0; + p = header->charptr; + for (i = sizeof(union record); --i >= 0;) { + /* + * We can't use unsigned char here because of old compilers, e.g. V7. + */ + sum += 0xFF & *p++; + } + + /* Adjust checksum to count the "chksum" field as blanks. */ + for (i = sizeof(header->header.chksum); --i >= 0;) + sum -= 0xFF & header->header.chksum[i]; + sum += ' ' * sizeof header->header.chksum; + + if (sum != recsum) + return 0; /* Not a tar archive */ + + if (0 == strcmp(header->header.magic, TMAGIC)) + return 2; /* Unix Standard tar archive */ + + return 1; /* Old fashioned tar archive */ +} + + +/* + * Quick and dirty octal conversion. + * + * Result is -1 if the field is invalid (all blank, or nonoctal). + */ +static long from_oct(int digs, char *where) +{ + register long value; + + while (apr_isspace(*where)) { /* Skip spaces */ + where++; + if (--digs <= 0) + return -1; /* All blank field */ + } + value = 0; + while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */ + value = (value << 3) | (*where++ - '0'); + --digs; + } + + if (digs > 0 && *where && !apr_isspace(*where)) + return -1; /* Ended on non-space/nul */ + + return value; +} + +/* + * Check for file-revision suffix + * + * This is for an obscure document control system used on an intranet. + * The web representation of each file's revision has an @1, @2, etc + * appended with the revision number. This needs to be stripped off to + * find the file suffix, which can be recognized by sending the name back + * through a sub-request. The base file name (without the @num suffix) + * must exist because its type will be used as the result. + */ +static int revision_suffix(request_rec *r) +{ + int suffix_pos, result; + char *sub_filename; + request_rec *sub; + +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": revision_suffix checking %s", r->filename); +#endif /* MIME_MAGIC_DEBUG */ + + /* check for recognized revision suffix */ + suffix_pos = strlen(r->filename) - 1; + if (!apr_isdigit(r->filename[suffix_pos])) { + return 0; + } + while (suffix_pos >= 0 && apr_isdigit(r->filename[suffix_pos])) + suffix_pos--; + if (suffix_pos < 0 || r->filename[suffix_pos] != '@') { + return 0; + } + + /* perform sub-request for the file name without the suffix */ + result = 0; + sub_filename = apr_pstrndup(r->pool, r->filename, suffix_pos); +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": subrequest lookup for %s", sub_filename); +#endif /* MIME_MAGIC_DEBUG */ + sub = ap_sub_req_lookup_file(sub_filename, r, NULL); + + /* extract content type/encoding/language from sub-request */ + if (sub->content_type) { + ap_set_content_type(r, apr_pstrdup(r->pool, sub->content_type)); +#if MIME_MAGIC_DEBUG + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + MODNAME ": subrequest %s got %s", + sub_filename, r->content_type); +#endif /* MIME_MAGIC_DEBUG */ + if (sub->content_encoding) + r->content_encoding = + apr_pstrdup(r->pool, sub->content_encoding); + if (sub->content_languages) { + int n; + r->content_languages = apr_array_copy(r->pool, + sub->content_languages); + for (n = 0; n < r->content_languages->nelts; ++n) { + char **lang = ((char **)r->content_languages->elts) + n; + *lang = apr_pstrdup(r->pool, *lang); + } + } + result = 1; + } + + /* clean up */ + ap_destroy_sub_req(sub); + + return result; +} + +/* + * initialize the module + */ +static int magic_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server) +{ + int result; + magic_server_config_rec *conf; + magic_server_config_rec *main_conf; + server_rec *s; +#if MIME_MAGIC_DEBUG + struct magic *m, *prevm; +#endif /* MIME_MAGIC_DEBUG */ + + main_conf = ap_get_module_config(main_server->module_config, &mime_magic_module); + for (s = main_server; s; s = s->next) { + conf = ap_get_module_config(s->module_config, &mime_magic_module); + if (conf->magicfile == NULL && s != main_server) { + /* inherits from the parent */ + *conf = *main_conf; + } + else if (conf->magicfile) { + result = apprentice(s, p); + if (result == -1) + return OK; +#if MIME_MAGIC_DEBUG + prevm = 0; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": magic_init 1 test"); + for (m = conf->magic; m; m = m->next) { + if (apr_isprint((((unsigned long) m) >> 24) & 255) && + apr_isprint((((unsigned long) m) >> 16) & 255) && + apr_isprint((((unsigned long) m) >> 8) & 255) && + apr_isprint(((unsigned long) m) & 255)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + MODNAME ": magic_init 1: POINTER CLOBBERED! " + "m=\"%c%c%c%c\" line=%d", + (((unsigned long) m) >> 24) & 255, + (((unsigned long) m) >> 16) & 255, + (((unsigned long) m) >> 8) & 255, + ((unsigned long) m) & 255, + prevm ? prevm->lineno : -1); + break; + } + prevm = m; + } +#endif + } + } + return OK; +} + +/* + * Find the Content-Type from any resource this module has available + */ + +static int magic_find_ct(request_rec *r) +{ + int result; + magic_server_config_rec *conf; + + /* the file has to exist */ + if (r->finfo.filetype == 0 || !r->filename) { + return DECLINED; + } + + /* was someone else already here? */ + if (r->content_type) { + return DECLINED; + } + + conf = ap_get_module_config(r->server->module_config, &mime_magic_module); + if (!conf || !conf->magic) { + return DECLINED; + } + + /* initialize per-request info */ + if (!magic_set_config(r)) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* try excluding file-revision suffixes */ + if (revision_suffix(r) != 1) { + /* process it based on the file contents */ + if ((result = magic_process(r)) != OK) { + return result; + } + } + + /* if we have any results, put them in the request structure */ + return magic_rsl_to_request(r); +} + +static void register_hooks(apr_pool_t *p) +{ + static const char * const aszPre[]={ "mod_mime.c", NULL }; + + /* mod_mime_magic should be run after mod_mime, if at all. */ + + ap_hook_type_checker(magic_find_ct, aszPre, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(magic_init, NULL, NULL, APR_HOOK_FIRST); +} + +/* + * Apache API module interface + */ + +module AP_MODULE_DECLARE_DATA mime_magic_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creator */ + NULL, /* dir merger --- default is to override */ + create_magic_server_config, /* server config */ + merge_magic_server_config, /* merge server config */ + mime_magic_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + + diff --git a/trunk/modules/metadata/mod_mime_magic.dsp b/trunk/modules/metadata/mod_mime_magic.dsp new file mode 100644 index 0000000000..8206a1bbfb --- /dev/null +++ b/trunk/modules/metadata/mod_mime_magic.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_mime_magic" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_mime_magic - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_mime_magic.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_mime_magic.mak" CFG="mod_mime_magic - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_mime_magic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_mime_magic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_mime_magic - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_mime_magic_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so +# ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_mime_magic - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_mime_magic_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so +# ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_mime_magic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_mime_magic.so + +!ENDIF + +# Begin Target + +# Name "mod_mime_magic - Win32 Release" +# Name "mod_mime_magic - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_mime_magic.c +# End Source File +# Begin Source File + +SOURCE=.\mod_mime_magic.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_mime_magic - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mime_magic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mime_magic.so "mime_magic_module for Apache" ../../include/ap_release.h > .\mod_mime_magic.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_mime_magic - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_mime_magic.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_mime_magic.so "mime_magic_module for Apache" ../../include/ap_release.h > .\mod_mime_magic.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_mime_magic.exp b/trunk/modules/metadata/mod_mime_magic.exp new file mode 100644 index 0000000000..42068a4342 --- /dev/null +++ b/trunk/modules/metadata/mod_mime_magic.exp @@ -0,0 +1 @@ +mime_magic_module diff --git a/trunk/modules/metadata/mod_setenvif.c b/trunk/modules/metadata/mod_setenvif.c new file mode 100644 index 0000000000..f07a9f5925 --- /dev/null +++ b/trunk/modules/metadata/mod_setenvif.c @@ -0,0 +1,586 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_setenvif.c + * Set environment variables based on matching request headers or + * attributes against regex strings + * + * Paul Sutton <paul@ukweb.com> 27 Oct 1996 + * Based on mod_browser by Alexei Kosut <akosut@organic.com> + */ + +/* + * Used to set environment variables based on the incoming request headers, + * or some selected other attributes of the request (e.g., the remote host + * name). + * + * Usage: + * + * SetEnvIf name regex var ... + * + * where name is either a HTTP request header name, or one of the + * special values (see below). 'name' may be a regex when it is used + * to specify an HTTP request header name. The 'value' of the header + & (or the value of the special value from below) are compared against + * the regex argument. If this is a simple string, a simple sub-string + * match is performed. Otherwise, a request expression match is + * done. If the value matches the string or regular expression, the + * environment variables listed as var ... are set. Each var can + * be in one of three formats: var, which sets the named variable + * (the value value "1"); var=value, which sets the variable to + * the given value; or !var, which unsets the variable is it has + * been previously set. + * + * Normally the strings are compared with regard to case. To ignore + * case, use the directive SetEnvIfNoCase instead. + * + * Special values for 'name' are: + * + * server_addr IP address of interface on which request arrived + * (analogous to SERVER_ADDR set in ap_add_common_vars()) + * remote_host Remote host name (if available) + * remote_addr Remote IP address + * request_method Request method (GET, POST, etc) + * request_uri Requested URI + * + * Examples: + * + * To set the enviroment variable LOCALHOST if the client is the local + * machine: + * + * SetEnvIf remote_addr 127.0.0.1 LOCALHOST + * + * To set LOCAL if the client is the local host, or within our company's + * domain (192.168.10): + * + * SetEnvIf remote_addr 192.168.10. LOCAL + * SetEnvIf remote_addr 127.0.0.1 LOCALHOST + * + * This could be written as: + * + * SetEnvIf remote_addr (127.0.0.1|192.168.10.) LOCAL + * + * To set HAVE_TS if the client request contains any header beginning + * with "TS" with a value beginning with a lower case alphabet: + * + * SetEnvIf ^TS* ^[a-z].* HAVE_TS + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_strmatch.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_protocol.h" + + +enum special { + SPECIAL_NOT, + SPECIAL_REMOTE_ADDR, + SPECIAL_REMOTE_HOST, + SPECIAL_REQUEST_URI, + SPECIAL_REQUEST_METHOD, + SPECIAL_REQUEST_PROTOCOL, + SPECIAL_SERVER_ADDR +}; +typedef struct { + char *name; /* header name */ + ap_regex_t *pnamereg; /* compiled header name regex */ + char *regex; /* regex to match against */ + ap_regex_t *preg; /* compiled regex */ + const apr_strmatch_pattern *pattern; /* non-regex pattern to match */ + apr_table_t *features; /* env vars to set (or unset) */ + enum special special_type; /* is it a "special" header ? */ + int icase; /* ignoring case? */ +} sei_entry; + +typedef struct { + apr_array_header_t *conditionals; +} sei_cfg_rec; + +module AP_MODULE_DECLARE_DATA setenvif_module; + +/* + * These routines, the create- and merge-config functions, are called + * for both the server-wide and the per-directory contexts. This is + * because the different definitions are used at different times; the + * server-wide ones are used in the post-read-request phase, and the + * per-directory ones are used during the header-parse phase (after + * the URI has been mapped to a file and we have anything from the + * .htaccess file and <Directory> and <Files> containers). + */ +static void *create_setenvif_config(apr_pool_t *p) +{ + sei_cfg_rec *new = (sei_cfg_rec *) apr_palloc(p, sizeof(sei_cfg_rec)); + + new->conditionals = apr_array_make(p, 20, sizeof(sei_entry)); + return (void *) new; +} + +static void *create_setenvif_config_svr(apr_pool_t *p, server_rec *dummy) +{ + return create_setenvif_config(p); +} + +static void *create_setenvif_config_dir(apr_pool_t *p, char *dummy) +{ + return create_setenvif_config(p); +} + +static void *merge_setenvif_config(apr_pool_t *p, void *basev, void *overridesv) +{ + sei_cfg_rec *a = apr_pcalloc(p, sizeof(sei_cfg_rec)); + sei_cfg_rec *base = basev, *overrides = overridesv; + + a->conditionals = apr_array_append(p, base->conditionals, + overrides->conditionals); + return a; +} + +/* + * any non-NULL magic constant will do... used to indicate if AP_REG_ICASE should + * be used + */ +#define ICASE_MAGIC ((void *)(&setenvif_module)) +#define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag" + +static int is_header_regex(apr_pool_t *p, const char* name) +{ + /* If a Header name contains characters other than: + * -,_,[A-Z\, [a-z] and [0-9]. + * assume the header name is a regular expression. + */ + ap_regex_t *preg = ap_pregcomp(p, "^[-A-Za-z0-9_]*$", + (AP_REG_EXTENDED | AP_REG_NOSUB )); + ap_assert(preg != NULL); + + if (ap_regexec(preg, name, 0, NULL, 0)) { + return 1; + } + + return 0; +} + +/* If the input string does not take advantage of regular + * expression metacharacters, return a pointer to an equivalent + * string that can be searched using apr_strmatch(). (The + * returned string will often be the input string. But if + * the input string contains escaped characters, the returned + * string will be a copy with the escapes removed.) + */ +static const char *non_regex_pattern(apr_pool_t *p, const char *s) +{ + const char *src = s; + int escapes_found = 0; + int in_escape = 0; + + while (*src) { + switch (*src) { + case '^': + case '.': + case '$': + case '|': + case '(': + case ')': + case '[': + case ']': + case '*': + case '+': + case '?': + case '{': + case '}': + if (!in_escape) { + return NULL; + } + in_escape = 0; + break; + case '\\': + if (!in_escape) { + in_escape = 1; + escapes_found = 1; + } + else { + in_escape = 0; + } + break; + default: + if (in_escape) { + return NULL; + } + break; + } + src++; + } + if (!escapes_found) { + return s; + } + else { + char *unescaped = (char *)apr_palloc(p, src - s + 1); + char *dst = unescaped; + src = s; + do { + if (*src == '\\') { + src++; + } + } while ((*dst++ = *src++)); + return unescaped; + } +} + +static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, + char *fname, const char *args) +{ + char *regex; + const char *simple_pattern; + const char *feature; + sei_cfg_rec *sconf; + sei_entry *new; + sei_entry *entries; + char *var; + int i; + int beenhere = 0; + int icase; + + /* + * Determine from our context into which record to put the entry. + * cmd->path == NULL means we're in server-wide context; otherwise, + * we're dealing with a per-directory setting. + */ + sconf = (cmd->path != NULL) + ? (sei_cfg_rec *) mconfig + : (sei_cfg_rec *) ap_get_module_config(cmd->server->module_config, + &setenvif_module); + entries = (sei_entry *) sconf->conditionals->elts; + /* get regex */ + regex = ap_getword_conf(cmd->pool, &args); + if (!*regex) { + return apr_pstrcat(cmd->pool, "Missing regular expression for ", + cmd->cmd->name, NULL); + } + + /* + * If we've already got a sei_entry with the same name we want to + * just copy the name pointer... so that later on we can compare + * two header names just by comparing the pointers. + */ + for (i = 0; i < sconf->conditionals->nelts; ++i) { + new = &entries[i]; + if (!strcasecmp(new->name, fname)) { + fname = new->name; + break; + } + } + + /* if the last entry has an identical headername and regex then + * merge with it + */ + i = sconf->conditionals->nelts - 1; + icase = cmd->info == ICASE_MAGIC; + if (i < 0 + || entries[i].name != fname + || entries[i].icase != icase + || strcmp(entries[i].regex, regex)) { + + /* no match, create a new entry */ + new = apr_array_push(sconf->conditionals); + new->name = fname; + new->regex = regex; + new->icase = icase; + if ((simple_pattern = non_regex_pattern(cmd->pool, regex))) { + new->pattern = apr_strmatch_precompile(cmd->pool, + simple_pattern, !icase); + if (new->pattern == NULL) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + " pattern could not be compiled.", NULL); + } + new->preg = NULL; + } + else { + new->preg = ap_pregcomp(cmd->pool, regex, + (AP_REG_EXTENDED | (icase ? AP_REG_ICASE : 0))); + if (new->preg == NULL) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + " regex could not be compiled.", NULL); + } + new->pattern = NULL; + } + new->features = apr_table_make(cmd->pool, 2); + + if (!strcasecmp(fname, "remote_addr")) { + new->special_type = SPECIAL_REMOTE_ADDR; + } + else if (!strcasecmp(fname, "remote_host")) { + new->special_type = SPECIAL_REMOTE_HOST; + } + else if (!strcasecmp(fname, "request_uri")) { + new->special_type = SPECIAL_REQUEST_URI; + } + else if (!strcasecmp(fname, "request_method")) { + new->special_type = SPECIAL_REQUEST_METHOD; + } + else if (!strcasecmp(fname, "request_protocol")) { + new->special_type = SPECIAL_REQUEST_PROTOCOL; + } + else if (!strcasecmp(fname, "server_addr")) { + new->special_type = SPECIAL_SERVER_ADDR; + } + else { + new->special_type = SPECIAL_NOT; + /* Handle fname as a regular expression. + * If fname a simple header string, identify as such + * (new->pnamereg = NULL) to avoid the overhead of searching + * through headers_in for a regex match. + */ + if (is_header_regex(cmd->pool, fname)) { + new->pnamereg = ap_pregcomp(cmd->pool, fname, + (AP_REG_EXTENDED | AP_REG_NOSUB + | (icase ? AP_REG_ICASE : 0))); + if (new->pnamereg == NULL) + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "Header name regex could not be " + "compiled.", NULL); + } + else { + new->pnamereg = NULL; + } + } + } + else { + new = &entries[i]; + } + + for ( ; ; ) { + feature = ap_getword_conf(cmd->pool, &args); + if (!*feature) { + break; + } + beenhere++; + + var = ap_getword(cmd->pool, &feature, '='); + if (*feature) { + apr_table_setn(new->features, var, feature); + } + else if (*var == '!') { + apr_table_setn(new->features, var + 1, "!"); + } + else { + apr_table_setn(new->features, var, "1"); + } + } + + if (!beenhere) { + return apr_pstrcat(cmd->pool, "Missing envariable expression for ", + cmd->cmd->name, NULL); + } + + return NULL; +} + +static const char *add_setenvif(cmd_parms *cmd, void *mconfig, + const char *args) +{ + char *fname; + + /* get header name */ + fname = ap_getword_conf(cmd->pool, &args); + if (!*fname) { + return apr_pstrcat(cmd->pool, "Missing header-field name for ", + cmd->cmd->name, NULL); + } + return add_setenvif_core(cmd, mconfig, fname, args); +} + +/* + * This routine handles the BrowserMatch* directives. It simply turns around + * and feeds them, with the appropriate embellishments, to the general-purpose + * command handler. + */ +static const char *add_browser(cmd_parms *cmd, void *mconfig, const char *args) +{ + return add_setenvif_core(cmd, mconfig, "User-Agent", args); +} + +static const command_rec setenvif_module_cmds[] = +{ + AP_INIT_RAW_ARGS("SetEnvIf", add_setenvif, NULL, OR_FILEINFO, + "A header-name, regex and a list of variables."), + AP_INIT_RAW_ARGS("SetEnvIfNoCase", add_setenvif, ICASE_MAGIC, OR_FILEINFO, + "a header-name, regex and a list of variables."), + AP_INIT_RAW_ARGS("BrowserMatch", add_browser, NULL, OR_FILEINFO, + "A browser regex and a list of variables."), + AP_INIT_RAW_ARGS("BrowserMatchNoCase", add_browser, ICASE_MAGIC, + OR_FILEINFO, + "A browser regex and a list of variables."), + { NULL }, +}; + +/* + * This routine gets called at two different points in request processing: + * once before the URI has been translated (during the post-read-request + * phase) and once after (during the header-parse phase). We use different + * config records for the two different calls to reduce overhead (by not + * re-doing the server-wide settings during directory processing), and + * signal which call it is by having the earlier one pass a flag to the + * later one. + */ +static int match_headers(request_rec *r) +{ + sei_cfg_rec *sconf; + sei_entry *entries; + const apr_table_entry_t *elts; + const char *val; + apr_size_t val_len = 0; + int i, j; + char *last_name; + ap_regmatch_t regm[AP_MAX_REG_MATCH]; + + if (!ap_get_module_config(r->request_config, &setenvif_module)) { + ap_set_module_config(r->request_config, &setenvif_module, + SEI_MAGIC_HEIRLOOM); + sconf = (sei_cfg_rec *) ap_get_module_config(r->server->module_config, + &setenvif_module); + } + else { + sconf = (sei_cfg_rec *) ap_get_module_config(r->per_dir_config, + &setenvif_module); + } + entries = (sei_entry *) sconf->conditionals->elts; + last_name = NULL; + val = NULL; + for (i = 0; i < sconf->conditionals->nelts; ++i) { + sei_entry *b = &entries[i]; + + /* Optimize the case where a bunch of directives in a row use the + * same header. Remember we don't need to strcmp the two header + * names because we made sure the pointers were equal during + * configuration. + */ + if (b->name != last_name) { + last_name = b->name; + switch (b->special_type) { + case SPECIAL_REMOTE_ADDR: + val = r->connection->remote_ip; + break; + case SPECIAL_SERVER_ADDR: + val = r->connection->local_ip; + break; + case SPECIAL_REMOTE_HOST: + val = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME, NULL); + break; + case SPECIAL_REQUEST_URI: + val = r->uri; + break; + case SPECIAL_REQUEST_METHOD: + val = r->method; + break; + case SPECIAL_REQUEST_PROTOCOL: + val = r->protocol; + break; + case SPECIAL_NOT: + if (b->pnamereg) { + /* Matching headers_in against a regex. Iterate through + * the headers_in until we find a match or run out of + * headers. + */ + const apr_array_header_t + *arr = apr_table_elts(r->headers_in); + + elts = (const apr_table_entry_t *) arr->elts; + val = NULL; + for (j = 0; j < arr->nelts; ++j) { + if (!ap_regexec(b->pnamereg, elts[j].key, 0, NULL, 0)) { + val = elts[j].val; + } + } + } + else { + /* Not matching against a regex */ + val = apr_table_get(r->headers_in, b->name); + if (val == NULL) { + val = apr_table_get(r->subprocess_env, b->name); + } + } + } + val_len = val ? strlen(val) : 0; + } + + /* + * A NULL value indicates that the header field or special entity + * wasn't present or is undefined. Represent that as an empty string + * so that REs like "^$" will work and allow envariable setting + * based on missing or empty field. + */ + if (val == NULL) { + val = ""; + val_len = 0; + } + + if ((b->pattern && apr_strmatch(b->pattern, val, val_len)) || + (!b->pattern && !ap_regexec(b->preg, val, AP_MAX_REG_MATCH, regm, + 0))) { + const apr_array_header_t *arr = apr_table_elts(b->features); + elts = (const apr_table_entry_t *) arr->elts; + + for (j = 0; j < arr->nelts; ++j) { + if (*(elts[j].val) == '!') { + apr_table_unset(r->subprocess_env, elts[j].key); + } + else { + if (!b->pattern) { + char *replaced = ap_pregsub(r->pool, elts[j].val, val, + AP_MAX_REG_MATCH, regm); + if (replaced) { + apr_table_setn(r->subprocess_env, elts[j].key, + replaced); + } + } + else { + apr_table_setn(r->subprocess_env, elts[j].key, + elts[j].val); + } + } + } + } + } + + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_header_parser(match_headers, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA setenvif_module = +{ + STANDARD20_MODULE_STUFF, + create_setenvif_config_dir, /* dir config creater */ + merge_setenvif_config, /* dir merger --- default is to override */ + create_setenvif_config_svr, /* server config */ + merge_setenvif_config, /* merge server configs */ + setenvif_module_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_setenvif.dsp b/trunk/modules/metadata/mod_setenvif.dsp new file mode 100644 index 0000000000..c27140f0c0 --- /dev/null +++ b/trunk/modules/metadata/mod_setenvif.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_setenvif" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_setenvif - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_setenvif.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_setenvif.mak" CFG="mod_setenvif - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_setenvif - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_setenvif - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_setenvif - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_setenvif_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_setenvif - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_setenvif_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_setenvif.so" /base:@..\..\os\win32\BaseAddr.ref,mod_setenvif.so + +!ENDIF + +# Begin Target + +# Name "mod_setenvif - Win32 Release" +# Name "mod_setenvif - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_setenvif.c +# End Source File +# Begin Source File + +SOURCE=.\mod_setenvif.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_setenvif - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_setenvif.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_setenvif.so "setenvif_module for Apache" ../../include/ap_release.h > .\mod_setenvif.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_setenvif - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_setenvif.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_setenvif.so "setenvif_module for Apache" ../../include/ap_release.h > .\mod_setenvif.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_setenvif.exp b/trunk/modules/metadata/mod_setenvif.exp new file mode 100644 index 0000000000..4f3800e3a8 --- /dev/null +++ b/trunk/modules/metadata/mod_setenvif.exp @@ -0,0 +1 @@ +setenvif_module diff --git a/trunk/modules/metadata/mod_unique_id.c b/trunk/modules/metadata/mod_unique_id.c new file mode 100644 index 0000000000..7783b3cfe0 --- /dev/null +++ b/trunk/modules/metadata/mod_unique_id.c @@ -0,0 +1,367 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_unique_id.c: generate a unique identifier for each request + * + * Original author: Dean Gaudet <dgaudet@arctic.org> + * UUencoding modified by: Alvaro Martinez Echevarria <alvaro@lander.es> + */ + +#define APR_WANT_BYTEFUNC /* for htons() et al */ +#include "apr_want.h" +#include "apr_general.h" /* for APR_OFFSETOF */ +#include "apr_network_io.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_protocol.h" /* for ap_hook_post_read_request */ + +#if APR_HAVE_UNISTD_H +#include <unistd.h> /* for getpid() */ +#endif + +typedef struct { + unsigned int stamp; + unsigned int in_addr; + unsigned int pid; + unsigned short counter; + unsigned int thread_index; +} unique_id_rec; + +/* We are using thread_index (the index into the scoreboard), because we + * cannot guarantee the thread_id will be an integer. + * + * This code looks like it won't give a unique ID with the new thread logic. + * It will. The reason is, we don't increment the counter in a thread_safe + * manner. Because the thread_index is also in the unique ID now, this does + * not matter. In order for the id to not be unique, the same thread would + * have to get the same counter twice in the same second. + */ + +/* Comments: + * + * We want an identifier which is unique across all hits, everywhere. + * "everywhere" includes multiple httpd instances on the same machine, or on + * multiple machines. Essentially "everywhere" should include all possible + * httpds across all servers at a particular "site". We make some assumptions + * that if the site has a cluster of machines then their time is relatively + * synchronized. We also assume that the first address returned by a + * gethostbyname (gethostname()) is unique across all the machines at the + * "site". + * + * We also further assume that pids fit in 32-bits. If something uses more + * than 32-bits, the fix is trivial, but it requires the unrolled uuencoding + * loop to be extended. * A similar fix is needed to support multithreaded + * servers, using a pid/tid combo. + * + * Together, the in_addr and pid are assumed to absolutely uniquely identify + * this one child from all other currently running children on all servers + * (including this physical server if it is running multiple httpds) from each + * other. + * + * The stamp and counter are used to distinguish all hits for a particular + * (in_addr,pid) pair. The stamp is updated using r->request_time, + * saving cpu cycles. The counter is never reset, and is used to permit up to + * 64k requests in a single second by a single child. + * + * The 112-bits of unique_id_rec are encoded using the alphabet + * [A-Za-z0-9@-], resulting in 19 bytes of printable characters. That is then + * stuffed into the environment variable UNIQUE_ID so that it is available to + * other modules. The alphabet choice differs from normal base64 encoding + * [A-Za-z0-9+/] because + and / are special characters in URLs and we want to + * make it easy to use UNIQUE_ID in URLs. + * + * Note that UNIQUE_ID should be considered an opaque token by other + * applications. No attempt should be made to dissect its internal components. + * It is an abstraction that may change in the future as the needs of this + * module change. + * + * It is highly desirable that identifiers exist for "eternity". But future + * needs (such as much faster webservers, moving to 64-bit pids, or moving to a + * multithreaded server) may dictate a need to change the contents of + * unique_id_rec. Such a future implementation should ensure that the first + * field is still a time_t stamp. By doing that, it is possible for a site to + * have a "flag second" in which they stop all of their old-format servers, + * wait one entire second, and then start all of their new-servers. This + * procedure will ensure that the new space of identifiers is completely unique + * from the old space. (Since the first four unencoded bytes always differ.) + */ +/* + * Sun Jun 7 05:43:49 CEST 1998 -- Alvaro + * More comments: + * 1) The UUencoding prodecure is now done in a general way, avoiding the problems + * with sizes and paddings that can arise depending on the architecture. Now the + * offsets and sizes of the elements of the unique_id_rec structure are calculated + * in unique_id_global_init; and then used to duplicate the structure without the + * paddings that might exist. The multithreaded server fix should be now very easy: + * just add a new "tid" field to the unique_id_rec structure, and increase by one + * UNIQUE_ID_REC_MAX. + * 2) unique_id_rec.stamp has been changed from "time_t" to "unsigned int", because + * its size is 64bits on some platforms (linux/alpha), and this caused problems with + * htonl/ntohl. Well, this shouldn't be a problem till year 2106. + */ + +static unsigned global_in_addr; + +static unique_id_rec cur_unique_id; + +/* + * Number of elements in the structure unique_id_rec. + */ +#define UNIQUE_ID_REC_MAX 5 + +static unsigned short unique_id_rec_offset[UNIQUE_ID_REC_MAX], + unique_id_rec_size[UNIQUE_ID_REC_MAX], + unique_id_rec_total_size, + unique_id_rec_size_uu; + +static int unique_id_global_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server) +{ + char str[APRMAXHOSTLEN + 1]; + apr_status_t rv; + char *ipaddrstr; + apr_sockaddr_t *sockaddr; + + /* + * Calculate the sizes and offsets in cur_unique_id. + */ + unique_id_rec_offset[0] = APR_OFFSETOF(unique_id_rec, stamp); + unique_id_rec_size[0] = sizeof(cur_unique_id.stamp); + unique_id_rec_offset[1] = APR_OFFSETOF(unique_id_rec, in_addr); + unique_id_rec_size[1] = sizeof(cur_unique_id.in_addr); + unique_id_rec_offset[2] = APR_OFFSETOF(unique_id_rec, pid); + unique_id_rec_size[2] = sizeof(cur_unique_id.pid); + unique_id_rec_offset[3] = APR_OFFSETOF(unique_id_rec, counter); + unique_id_rec_size[3] = sizeof(cur_unique_id.counter); + unique_id_rec_offset[4] = APR_OFFSETOF(unique_id_rec, thread_index); + unique_id_rec_size[4] = sizeof(cur_unique_id.thread_index); + unique_id_rec_total_size = unique_id_rec_size[0] + unique_id_rec_size[1] + + unique_id_rec_size[2] + unique_id_rec_size[3] + + unique_id_rec_size[4]; + + /* + * Calculate the size of the structure when encoded. + */ + unique_id_rec_size_uu = (unique_id_rec_total_size*8+5)/6; + + /* + * Now get the global in_addr. Note that it is not sufficient to use one + * of the addresses from the main_server, since those aren't as likely to + * be unique as the physical address of the machine + */ + if ((rv = apr_gethostname(str, sizeof(str) - 1, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, + "mod_unique_id: unable to find hostname of the server"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if ((rv = apr_sockaddr_info_get(&sockaddr, str, AF_INET, 0, 0, p)) == APR_SUCCESS) { + global_in_addr = sockaddr->sa.sin.sin_addr.s_addr; + } + else { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, + "mod_unique_id: unable to find IPv4 address of \"%s\"", str); +#if APR_HAVE_IPV6 + if ((rv = apr_sockaddr_info_get(&sockaddr, str, AF_INET6, 0, 0, p)) == APR_SUCCESS) { + memcpy(&global_in_addr, + (char *)sockaddr->ipaddr_ptr + sockaddr->ipaddr_len - sizeof(global_in_addr), + sizeof(global_in_addr)); + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, + "mod_unique_id: using low-order bits of IPv6 address " + "as if they were unique"); + } + else +#endif + return HTTP_INTERNAL_SERVER_ERROR; + } + + apr_sockaddr_ip_get(&ipaddrstr, sockaddr); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server, + "mod_unique_id: using ip addr %s", + ipaddrstr); + + /* + * If the server is pummelled with restart requests we could possibly end + * up in a situation where we're starting again during the same second + * that has been used in previous identifiers. Avoid that situation. + * + * In truth, for this to actually happen not only would it have to restart + * in the same second, but it would have to somehow get the same pids as + * one of the other servers that was running in that second. Which would + * mean a 64k wraparound on pids ... not very likely at all. + * + * But protecting against it is relatively cheap. We just sleep into the + * next second. + */ + apr_sleep(apr_time_from_sec(1) - apr_time_usec(apr_time_now())); + return OK; +} + +static void unique_id_child_init(apr_pool_t *p, server_rec *s) +{ + pid_t pid; + apr_time_t tv; + + /* + * Note that we use the pid because it's possible that on the same + * physical machine there are multiple servers (i.e. using Listen). But + * it's guaranteed that none of them will share the same pids between + * children. + * + * XXX: for multithread this needs to use a pid/tid combo and probably + * needs to be expanded to 32 bits + */ + pid = getpid(); + cur_unique_id.pid = pid; + + /* + * Test our assumption that the pid is 32-bits. It's possible that + * 64-bit machines will declare pid_t to be 64 bits but only use 32 + * of them. It would have been really nice to test this during + * global_init ... but oh well. + */ + if ((pid_t)cur_unique_id.pid != pid) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, + "oh no! pids are greater than 32-bits! I'm broken!"); + } + + cur_unique_id.in_addr = global_in_addr; + + /* + * If we use 0 as the initial counter we have a little less protection + * against restart problems, and a little less protection against a clock + * going backwards in time. + */ + tv = apr_time_now(); + /* Some systems have very low variance on the low end of their system + * counter, defend against that. + */ + cur_unique_id.counter = (unsigned short)(apr_time_usec(tv) / 10); + + /* + * We must always use network ordering for these bytes, so that + * identifiers are comparable between machines of different byte + * orderings. Note in_addr is already in network order. + */ + cur_unique_id.pid = htonl(cur_unique_id.pid); + cur_unique_id.counter = htons(cur_unique_id.counter); +} + +/* NOTE: This is *NOT* the same encoding used by base64encode ... the last two + * characters should be + and /. But those two characters have very special + * meanings in URLs, and we want to make it easy to use identifiers in + * URLs. So we replace them with @ and -. + */ +static const char uuencoder[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-', +}; + +static int gen_unique_id(request_rec *r) +{ + char *str; + /* + * Buffer padded with two final bytes, used to copy the unique_id_red + * structure without the internal paddings that it could have. + */ + unique_id_rec new_unique_id; + struct { + unique_id_rec foo; + unsigned char pad[2]; + } paddedbuf; + unsigned char *x,*y; + unsigned short counter; + const char *e; + int i,j,k; + + /* copy the unique_id if this is an internal redirect (we're never + * actually called for sub requests, so we don't need to test for + * them) */ + if (r->prev && (e = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID"))) { + apr_table_setn(r->subprocess_env, "UNIQUE_ID", e); + return DECLINED; + } + + new_unique_id.in_addr = cur_unique_id.in_addr; + new_unique_id.pid = cur_unique_id.pid; + new_unique_id.counter = cur_unique_id.counter; + + new_unique_id.stamp = htonl((unsigned int)r->request_time); + new_unique_id.thread_index = htonl((unsigned int)r->connection->id); + + /* we'll use a temporal buffer to avoid uuencoding the possible internal + * paddings of the original structure */ + x = (unsigned char *) &paddedbuf; + y = (unsigned char *) &new_unique_id; + k = 0; + for (i = 0; i < UNIQUE_ID_REC_MAX; i++) { + y = ((unsigned char *) &new_unique_id) + unique_id_rec_offset[i]; + for (j = 0; j < unique_id_rec_size[i]; j++, k++) { + x[k] = y[j]; + } + } + /* + * We reset two more bytes just in case padding is needed for the uuencoding. + */ + x[k++] = '\0'; + x[k++] = '\0'; + + /* alloc str and do the uuencoding */ + str = (char *)apr_palloc(r->pool, unique_id_rec_size_uu + 1); + k = 0; + for (i = 0; i < unique_id_rec_total_size; i += 3) { + y = x + i; + str[k++] = uuencoder[y[0] >> 2]; + str[k++] = uuencoder[((y[0] & 0x03) << 4) | ((y[1] & 0xf0) >> 4)]; + if (k == unique_id_rec_size_uu) break; + str[k++] = uuencoder[((y[1] & 0x0f) << 2) | ((y[2] & 0xc0) >> 6)]; + if (k == unique_id_rec_size_uu) break; + str[k++] = uuencoder[y[2] & 0x3f]; + } + str[k++] = '\0'; + + /* set the environment variable */ + apr_table_setn(r->subprocess_env, "UNIQUE_ID", str); + + /* and increment the identifier for the next call */ + + counter = ntohs(new_unique_id.counter) + 1; + cur_unique_id.counter = htons(counter); + + return DECLINED; +} + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_post_config(unique_id_global_init, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_child_init(unique_id_child_init, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_read_request(gen_unique_id, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA unique_id_module = { + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + NULL, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_unique_id.dsp b/trunk/modules/metadata/mod_unique_id.dsp new file mode 100644 index 0000000000..5ef7be09f7 --- /dev/null +++ b/trunk/modules/metadata/mod_unique_id.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_unique_id" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_unique_id - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_unique_id.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_unique_id.mak" CFG="mod_unique_id - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_unique_id - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_unique_id - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_unique_id - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_unique_id_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so +# ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_unique_id - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_unique_id_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so +# ADD LINK32 kernel32.lib ws2_32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_unique_id.so" /base:@..\..\os\win32\BaseAddr.ref,mod_unique_id.so + +!ENDIF + +# Begin Target + +# Name "mod_unique_id - Win32 Release" +# Name "mod_unique_id - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_unique_id.c +# End Source File +# Begin Source File + +SOURCE=.\mod_unique_id.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_unique_id - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_unique_id.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_unique_id.so "unique_id_module for Apache" ../../include/ap_release.h > .\mod_unique_id.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_unique_id - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_unique_id.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_unique_id.so "unique_id_module for Apache" ../../include/ap_release.h > .\mod_unique_id.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_unique_id.exp b/trunk/modules/metadata/mod_unique_id.exp new file mode 100644 index 0000000000..93000f1ee6 --- /dev/null +++ b/trunk/modules/metadata/mod_unique_id.exp @@ -0,0 +1 @@ +unique_id_module diff --git a/trunk/modules/metadata/mod_usertrack.c b/trunk/modules/metadata/mod_usertrack.c new file mode 100644 index 0000000000..0f5afdc4c0 --- /dev/null +++ b/trunk/modules/metadata/mod_usertrack.c @@ -0,0 +1,453 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* User Tracking Module (Was mod_cookies.c) + * + * *** IMPORTANT NOTE: This module is not designed to generate + * *** cryptographically secure cookies. This means you should not + * *** use cookies generated by this module for authentication purposes + * + * This Apache module is designed to track users paths through a site. + * It uses the client-side state ("Cookie") protocol developed by Netscape. + * It is known to work on most browsers. + * + * Each time a page is requested we look to see if the browser is sending + * us a Cookie: header that we previously generated. + * + * If we don't find one then the user hasn't been to this site since + * starting their browser or their browser doesn't support cookies. So + * we generate a unique Cookie for the transaction and send it back to + * the browser (via a "Set-Cookie" header) + * Future requests from the same browser should keep the same Cookie line. + * + * By matching up all the requests with the same cookie you can + * work out exactly what path a user took through your site. To log + * the cookie use the " %{Cookie}n " directive in a custom access log; + * + * Example 1 : If you currently use the standard Log file format (CLF) + * and use the command "TransferLog somefilename", add the line + * LogFormat "%h %l %u %t \"%r\" %s %b %{Cookie}n" + * to your config file. + * + * Example 2 : If you used to use the old "CookieLog" directive, you + * can emulate it by adding the following command to your config file + * CustomLog filename "%{Cookie}n \"%r\" %t" + * + * Mark Cox, mjc@apache.org, 6 July 95 + * + * This file replaces mod_cookies.c + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_request.h" + + +module AP_MODULE_DECLARE_DATA usertrack_module; + +typedef struct { + int always; + int expires; +} cookie_log_state; + +typedef enum { + CT_UNSET, + CT_NETSCAPE, + CT_COOKIE, + CT_COOKIE2 +} cookie_type_e; + +typedef struct { + int enabled; + cookie_type_e style; + char *cookie_name; + char *cookie_domain; + char *regexp_string; /* used to compile regexp; save for debugging */ + ap_regex_t *regexp; /* used to find usertrack cookie in cookie header */ +} cookie_dir_rec; + +/* Make Cookie: Now we have to generate something that is going to be + * pretty unique. We can base it on the pid, time, hostip */ + +#define COOKIE_NAME "Apache" + +static void make_cookie(request_rec *r) +{ + cookie_log_state *cls = ap_get_module_config(r->server->module_config, + &usertrack_module); + /* 1024 == hardcoded constant */ + char cookiebuf[1024]; + char *new_cookie; + const char *rname = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME, NULL); + cookie_dir_rec *dcfg; + + dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); + + /* XXX: hmm, this should really tie in with mod_unique_id */ + apr_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%" APR_TIME_T_FMT, rname, + apr_time_now()); + + if (cls->expires) { + + /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ + new_cookie = apr_psprintf(r->pool, "%s=%s; path=/", + dcfg->cookie_name, cookiebuf); + + if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) { + apr_time_exp_t tms; + apr_time_exp_gmt(&tms, r->request_time + + apr_time_from_sec(cls->expires)); + new_cookie = apr_psprintf(r->pool, + "%s; expires=%s, " + "%.2d-%s-%.2d %.2d:%.2d:%.2d GMT", + new_cookie, apr_day_snames[tms.tm_wday], + tms.tm_mday, + apr_month_snames[tms.tm_mon], + tms.tm_year % 100, + tms.tm_hour, tms.tm_min, tms.tm_sec); + } + else { + new_cookie = apr_psprintf(r->pool, "%s; max-age=%d", + new_cookie, cls->expires); + } + } + else { + new_cookie = apr_psprintf(r->pool, "%s=%s; path=/", + dcfg->cookie_name, cookiebuf); + } + if (dcfg->cookie_domain != NULL) { + new_cookie = apr_pstrcat(r->pool, new_cookie, "; domain=", + dcfg->cookie_domain, + (dcfg->style == CT_COOKIE2 + ? "; version=1" + : ""), + NULL); + } + + apr_table_addn(r->headers_out, + (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"), + new_cookie); + apr_table_setn(r->notes, "cookie", apr_pstrdup(r->pool, cookiebuf)); /* log first time */ + return; +} + +/* dcfg->regexp is "^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)", + * which has three subexpressions, $0..$2 */ +#define NUM_SUBS 3 + +static void set_and_comp_regexp(cookie_dir_rec *dcfg, + apr_pool_t *p, + const char *cookie_name) +{ + int danger_chars = 0; + const char *sp = cookie_name; + + /* The goal is to end up with this regexp, + * ^cookie_name=([^;,]+)|[;,][ \t]+cookie_name=([^;,]+) + * with cookie_name obviously substituted either + * with the real cookie name set by the user in httpd.conf, or with the + * default COOKIE_NAME. */ + + /* Anyway, we need to escape the cookie_name before pasting it + * into the regex + */ + while (*sp) { + if (!apr_isalnum(*sp)) { + ++danger_chars; + } + ++sp; + } + + if (danger_chars) { + char *cp; + cp = apr_palloc(p, sp - cookie_name + danger_chars + 1); /* 1 == \0 */ + sp = cookie_name; + cookie_name = cp; + while (*sp) { + if (!apr_isalnum(*sp)) { + *cp++ = '\\'; + } + *cp++ = *sp++; + } + *cp = '\0'; + } + + dcfg->regexp_string = apr_pstrcat(p, "^", + cookie_name, + "=([^;,]+)|[;,][ \t]*", + cookie_name, + "=([^;,]+)", NULL); + + dcfg->regexp = ap_pregcomp(p, dcfg->regexp_string, AP_REG_EXTENDED); + ap_assert(dcfg->regexp != NULL); +} + +static int spot_cookie(request_rec *r) +{ + cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config, + &usertrack_module); + const char *cookie_header; + ap_regmatch_t regm[NUM_SUBS]; + + /* Do not run in subrequests */ + if (!dcfg->enabled || r->main) { + return DECLINED; + } + + if ((cookie_header = apr_table_get(r->headers_in, "Cookie"))) { + if (!ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0)) { + char *cookieval = NULL; + /* Our regexp, + * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+) + * only allows for $1 or $2 to be available. ($0 is always + * filled with the entire matched expression, not just + * the part in parentheses.) So just check for either one + * and assign to cookieval if present. */ + if (regm[1].rm_so != -1) { + cookieval = ap_pregsub(r->pool, "$1", cookie_header, + NUM_SUBS, regm); + } + if (regm[2].rm_so != -1) { + cookieval = ap_pregsub(r->pool, "$2", cookie_header, + NUM_SUBS, regm); + } + /* Set the cookie in a note, for logging */ + apr_table_setn(r->notes, "cookie", cookieval); + + return DECLINED; /* There's already a cookie, no new one */ + } + } + make_cookie(r); + return OK; /* We set our cookie */ +} + +static void *make_cookie_log_state(apr_pool_t *p, server_rec *s) +{ + cookie_log_state *cls = + (cookie_log_state *) apr_palloc(p, sizeof(cookie_log_state)); + + cls->expires = 0; + + return (void *) cls; +} + +static void *make_cookie_dir(apr_pool_t *p, char *d) +{ + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) apr_pcalloc(p, sizeof(cookie_dir_rec)); + dcfg->cookie_name = COOKIE_NAME; + dcfg->cookie_domain = NULL; + dcfg->style = CT_UNSET; + dcfg->enabled = 0; + + /* In case the user does not use the CookieName directive, + * we need to compile the regexp for the default cookie name. */ + set_and_comp_regexp(dcfg, p, COOKIE_NAME); + + return dcfg; +} + +static const char *set_cookie_enable(cmd_parms *cmd, void *mconfig, int arg) +{ + cookie_dir_rec *dcfg = mconfig; + + dcfg->enabled = arg; + return NULL; +} + +static const char *set_cookie_exp(cmd_parms *parms, void *dummy, + const char *arg) +{ + cookie_log_state *cls; + time_t factor, modifier = 0; + time_t num = 0; + char *word; + + cls = ap_get_module_config(parms->server->module_config, + &usertrack_module); + /* The simple case first - all numbers (we assume) */ + if (apr_isdigit(arg[0]) && apr_isdigit(arg[strlen(arg) - 1])) { + cls->expires = atol(arg); + return NULL; + } + + /* + * The harder case - stolen from mod_expires + * + * CookieExpires "[plus] {<num> <type>}*" + */ + + word = ap_getword_conf(parms->pool, &arg); + if (!strncasecmp(word, "plus", 1)) { + word = ap_getword_conf(parms->pool, &arg); + }; + + /* {<num> <type>}* */ + while (word[0]) { + /* <num> */ + if (apr_isdigit(word[0])) + num = atoi(word); + else + return "bad expires code, numeric value expected."; + + /* <type> */ + word = ap_getword_conf(parms->pool, &arg); + if (!word[0]) + return "bad expires code, missing <type>"; + + factor = 0; + if (!strncasecmp(word, "years", 1)) + factor = 60 * 60 * 24 * 365; + else if (!strncasecmp(word, "months", 2)) + factor = 60 * 60 * 24 * 30; + else if (!strncasecmp(word, "weeks", 1)) + factor = 60 * 60 * 24 * 7; + else if (!strncasecmp(word, "days", 1)) + factor = 60 * 60 * 24; + else if (!strncasecmp(word, "hours", 1)) + factor = 60 * 60; + else if (!strncasecmp(word, "minutes", 2)) + factor = 60; + else if (!strncasecmp(word, "seconds", 1)) + factor = 1; + else + return "bad expires code, unrecognized type"; + + modifier = modifier + factor * num; + + /* next <num> */ + word = ap_getword_conf(parms->pool, &arg); + } + + cls->expires = modifier; + + return NULL; +} + +static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, + const char *name) +{ + cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + + dcfg->cookie_name = apr_pstrdup(cmd->pool, name); + + set_and_comp_regexp(dcfg, cmd->pool, name); + + if (dcfg->regexp == NULL) { + return "Regular expression could not be compiled."; + } + if (dcfg->regexp->re_nsub + 1 != NUM_SUBS) { + return apr_pstrcat(cmd->pool, "Invalid cookie name \"", + name, "\"", NULL); + } + + return NULL; +} + +/* + * Set the value for the 'Domain=' attribute. + */ +static const char *set_cookie_domain(cmd_parms *cmd, void *mconfig, + const char *name) +{ + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) mconfig; + + /* + * Apply the restrictions on cookie domain attributes. + */ + if (strlen(name) == 0) { + return "CookieDomain values may not be null"; + } + if (name[0] != '.') { + return "CookieDomain values must begin with a dot"; + } + if (ap_strchr_c(&name[1], '.') == NULL) { + return "CookieDomain values must contain at least one embedded dot"; + } + + dcfg->cookie_domain = apr_pstrdup(cmd->pool, name); + return NULL; +} + +/* + * Make a note of the cookie style we should use. + */ +static const char *set_cookie_style(cmd_parms *cmd, void *mconfig, + const char *name) +{ + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) mconfig; + + if (strcasecmp(name, "Netscape") == 0) { + dcfg->style = CT_NETSCAPE; + } + else if ((strcasecmp(name, "Cookie") == 0) + || (strcasecmp(name, "RFC2109") == 0)) { + dcfg->style = CT_COOKIE; + } + else if ((strcasecmp(name, "Cookie2") == 0) + || (strcasecmp(name, "RFC2965") == 0)) { + dcfg->style = CT_COOKIE2; + } + else { + return apr_psprintf(cmd->pool, "Invalid %s keyword: '%s'", + cmd->cmd->name, name); + } + + return NULL; +} + +static const command_rec cookie_log_cmds[] = { + AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO, + "an expiry date code"), + AP_INIT_TAKE1("CookieDomain", set_cookie_domain, NULL, OR_FILEINFO, + "domain to which this cookie applies"), + AP_INIT_TAKE1("CookieStyle", set_cookie_style, NULL, OR_FILEINFO, + "'Netscape', 'Cookie' (RFC2109), or 'Cookie2' (RFC2965)"), + AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, + "whether or not to enable cookies"), + AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO, + "name of the tracking cookie"), + {NULL} +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_hook_fixups(spot_cookie,NULL,NULL,APR_HOOK_FIRST); +} + +module AP_MODULE_DECLARE_DATA usertrack_module = { + STANDARD20_MODULE_STUFF, + make_cookie_dir, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + make_cookie_log_state, /* server config */ + NULL, /* merge server configs */ + cookie_log_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_usertrack.dsp b/trunk/modules/metadata/mod_usertrack.dsp new file mode 100644 index 0000000000..6262f37377 --- /dev/null +++ b/trunk/modules/metadata/mod_usertrack.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_usertrack" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_usertrack - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_usertrack.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_usertrack.mak" CFG="mod_usertrack - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_usertrack - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_usertrack - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_usertrack - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_usertrack_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_usertrack - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_usertrack_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_usertrack.so" /base:@..\..\os\win32\BaseAddr.ref,mod_usertrack.so + +!ENDIF + +# Begin Target + +# Name "mod_usertrack - Win32 Release" +# Name "mod_usertrack - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_usertrack.c +# End Source File +# Begin Source File + +SOURCE=.\mod_usertrack.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_usertrack - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_usertrack.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_usertrack.so "usertrack_module for Apache" ../../include/ap_release.h > .\mod_usertrack.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_usertrack - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_usertrack.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_usertrack.so "usertrack_module for Apache" ../../include/ap_release.h > .\mod_usertrack.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_usertrack.exp b/trunk/modules/metadata/mod_usertrack.exp new file mode 100644 index 0000000000..234a5f759d --- /dev/null +++ b/trunk/modules/metadata/mod_usertrack.exp @@ -0,0 +1 @@ +usertrack_module diff --git a/trunk/modules/metadata/mod_version.c b/trunk/modules/metadata/mod_version.c new file mode 100644 index 0000000000..4a583bc87f --- /dev/null +++ b/trunk/modules/metadata/mod_version.c @@ -0,0 +1,311 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * mod_version.c + * Allow conditional configuration depending on the httpd version + * + * André Malo (nd/perlig.de), January 2004 + * + * Some stuff coded here is heavily based on the core <IfModule> + * containers. + * + * The module makes the following confgurations possible: + * + * <IfVersion op major.minor.patch> + * # conditional config here ... + *</IfVersion> + * + * where "op" is one of: + * = / == equal + * > greater than + * >= greater or equal + * < less than + * <= less or equal + * + * If minor version and patch level are omitted they are assumed to be 0. + * + * Alternatively you can match the whole version (including some vendor-added + * string of the CORE version, see ap_release.h) against a regular expression: + * + * <IfVersion op regex> + * # conditional config here ... + *</IfVersion> + * + * where "op" is one of: + * = / == match; regex must be surrounded by slashes + * ~ match; regex MAY NOT be surrounded by slashes + * + * Note that all operators may be preceeded by an exclamation mark + * (without spaces) in order to reverse their meaning. + * + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" + + +/* module structure */ +module AP_MODULE_DECLARE_DATA version_module; + +/* queried httpd version */ +static ap_version_t httpd_version; + + +/* + * compare the supplied version with the core one + */ +static int compare_version(char *version_string, const char **error) +{ + char *p = version_string, *ep; + int version[3] = {0, 0, 0}; + int c = 0; + + *error = "Version appears to be invalid. It must have the format " + "major[.minor[.patch]] where major, minor and patch are " + "numbers."; + + if (!apr_isdigit(*p)) { + return 0; + } + + /* parse supplied version */ + ep = version_string + strlen(version_string); + while (p <= ep && c < 3) { + if (*p == '.') { + *p = '\0'; + } + + if (!*p) { + version[c++] = atoi(version_string); + version_string = ++p; + continue; + } + + if (!apr_isdigit(*p)) { + break; + } + + ++p; + } + + if (p < ep) { /* syntax error */ + return 0; + } + + *error = NULL; + + if (httpd_version.major > version[0]) { + return 1; + } + else if (httpd_version.major < version[0]) { + return -1; + } + else if (httpd_version.minor > version[1]) { + return 1; + } + else if (httpd_version.minor < version[1]) { + return -1; + } + else if (httpd_version.patch > version[2]) { + return 1; + } + else if (httpd_version.patch < version[2]) { + return -1; + } + + /* seems to be the same */ + return 0; +} + +/* + * match version against a regular expression + */ +static int match_version(apr_pool_t *pool, char *version_string, + const char **error) +{ + ap_regex_t *compiled; + const char *to_match; + int rc; + + compiled = ap_pregcomp(pool, version_string, AP_REG_EXTENDED); + if (!compiled) { + *error = "Unable to compile regular expression"; + return 0; + } + + *error = NULL; + + to_match = apr_psprintf(pool, "%d.%d.%d%s", + httpd_version.major, + httpd_version.minor, + httpd_version.patch, + httpd_version.add_string); + + rc = !ap_regexec(compiled, to_match, 0, NULL, 0); + + ap_pregfree(pool, compiled); + return rc; +} + +/* + * Implements the <IfVersion> container + */ +static const char *start_ifversion(cmd_parms *cmd, void *mconfig, + const char *arg1, const char *arg2, + const char *arg3) +{ + const char *endp; + int reverse = 0, done = 0, match = 0, compare; + const char *p, *error; + char c; + + /* supplying one argument is possible, we assume an equality check then */ + if (!arg2) { + arg2 = arg1; + arg1 = "="; + } + + /* surrounding quotes without operator */ + if (!arg3 && *arg2 == '>' && !arg2[1]) { + arg3 = ">"; + arg2 = arg1; + arg1 = "="; + } + + /* the third argument makes version surrounding quotes plus operator + * possible. + */ + endp = arg2 + strlen(arg2); + if ( endp == arg2 + || (!(arg3 && *arg3 == '>' && !arg3[1]) && *--endp != '>')) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive missing closing '>'", NULL); + } + + p = arg1; + if (*p == '!') { + reverse = 1; + if (p[1]) { + ++p; + } + } + + c = *p++; + if (!*p || (*p == '=' && !p[1] && c != '~')) { + if (!httpd_version.major) { + ap_get_server_revision(&httpd_version); + } + + done = 1; + switch (c) { + case '=': + /* normal comparison */ + if (*arg2 != '/') { + compare = compare_version(apr_pstrmemdup(cmd->pool, arg2, + endp-arg2), + &error); + if (error) { + return error; + } + + match = !compare; + break; + } + + /* regexp otherwise */ + if (endp == ++arg2 || *--endp != '/') { + return "Missing delimiting / of regular expression."; + } + + case '~': + /* regular expression */ + match = match_version(cmd->pool, apr_pstrmemdup(cmd->pool, arg2, + endp-arg2), + &error); + if (error) { + return error; + } + break; + + case '<': + compare = compare_version(apr_pstrmemdup(cmd->pool, arg2, + endp-arg2), + &error); + if (error) { + return error; + } + + match = ((-1 == compare) || (*p && !compare)); + break; + + case '>': + compare = compare_version(apr_pstrmemdup(cmd->pool, arg2, + endp-arg2), + &error); + if (error) { + return error; + } + + match = ((1 == compare) || (*p && !compare)); + break; + + default: + done = 0; + break; + } + } + + if (!done) { + return apr_pstrcat(cmd->pool, "unrecognized operator '", arg1, "'", + NULL); + } + + if ((!reverse && match) || (reverse && !match)) { + ap_directive_t *parent = NULL; + ap_directive_t *current = NULL; + const char *retval; + + retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, + ¤t, &parent, "<IfVersion"); + *(ap_directive_t **)mconfig = current; + return retval; + } + + *(ap_directive_t **)mconfig = NULL; + return ap_soak_end_container(cmd, "<IfVersion"); +} + +static const command_rec version_cmds[] = { + AP_INIT_TAKE123("<IfVersion", start_ifversion, NULL, EXEC_ON_READ | OR_ALL, + "a comparison operator, a version (and a delimiter)"), + { NULL } +}; + +module AP_MODULE_DECLARE_DATA version_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ + version_cmds, /* command apr_table_t */ + NULL, /* register hooks */ +}; diff --git a/trunk/modules/metadata/mod_version.dsp b/trunk/modules/metadata/mod_version.dsp new file mode 100644 index 0000000000..e0096cd87f --- /dev/null +++ b/trunk/modules/metadata/mod_version.dsp @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Project File - Name="mod_version" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_version - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_version.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_version.mak" CFG="mod_version - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_version - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_version - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_version - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_version_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_version - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_version_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so +# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_version.so" /base:@..\..\os\win32\BaseAddr.ref,mod_version.so + +!ENDIF + +# Begin Target + +# Name "mod_version - Win32 Release" +# Name "mod_version - Win32 Debug" +# Begin Source File + +SOURCE=.\mod_version.c +# End Source File +# Begin Source File + +SOURCE=.\mod_version.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_version - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_version.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_version.so "version_module for Apache" ../../include/ap_release.h > .\mod_version.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_version - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_version.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_version.so "version_module for Apache" ../../include/ap_release.h > .\mod_version.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/metadata/mod_version.exp b/trunk/modules/metadata/mod_version.exp new file mode 100644 index 0000000000..3dce845626 --- /dev/null +++ b/trunk/modules/metadata/mod_version.exp @@ -0,0 +1 @@ +version_module diff --git a/trunk/modules/proxy/.indent.pro b/trunk/modules/proxy/.indent.pro new file mode 100644 index 0000000000..e2cd357ae5 --- /dev/null +++ b/trunk/modules/proxy/.indent.pro @@ -0,0 +1,58 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tapr_bucket_brigade +-Tapr_pool_t +-Tap_filter_t +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int +-Tproxy_server_conf diff --git a/trunk/modules/proxy/CHANGES b/trunk/modules/proxy/CHANGES new file mode 100644 index 0000000000..cca99a90ab --- /dev/null +++ b/trunk/modules/proxy/CHANGES @@ -0,0 +1,223 @@ +****************************************** +* PLEASE NOTE: Now that development for * +* mod_proxy has been folded back into * +* the httpd-2.1 tree, this file has * +* been depreciated. Proxy changes should * +* be noted in httpd-2.1's CHANGES file. * +* This file exists for historical * +* purposes. * +****************************************** + +mod_proxy changes for httpd 2.0.29-dev + *) don't do keepalives for sub-requests. [Ian Holsman] + + *) fix up proxypass handling [Ian Holsman] + + *) don't send If-Modified-Since, Cache-Control, or If-None-Match on + a subrequest [Ian Holsman] + +mod_proxy changes for httpd 2.0.26-dev + *) Add New option 'HTTPProxyOverrideReturnedErrors'. By Turning the + Flag on, you will mask the error pages returned by the proxied + server, and will it will be handled as if your server generated + the error. This change was put in so that a 404 on a included + r-proxied component will act in the same manner as a 404 on a + included file. [Ian Holsman <ianh@cnet.com>] + +mod_proxy changes for httpd 2.0.25-dev + + *) Split proxy: space using <Proxy[Match] > directive blocks from + the <Directory[Match] > and <Files[Match] > blocks. Mod_proxy + now bypasses the directory and files testing phase (and skips + the http TRACE default handler on it's own, as well). Note that + <Location > blocks continue to be processed for proxy: requests. + [William Rowe <wrowe@covalent.net>] + + *) apr_uri type/function namespace changes in apr_uri functions + [Doug MacEachern <dougm@covalent.net>] + +mod_proxy changes for httpd 2.0.23-dev + + *) break the proxy_http_handler into multiple smaller functions. + [John Barbee <barbee@veribox.net>] + + *) Fix the proxy when the origin server sends back a 100 + Continue response. [John Barbee <barbee@veribox.net>] + + *) Change 'readbytes' from apr_size_t to apr_off_t due to change + in ap_get_brigade's parameters [John Barbee <barbee@veribox.net>] + +mod_proxy changes for httpd 2.0.20-dev + *) Timeout added for backend connections. + [Victor Orlikowski <v.j.orlikowski@gte.net>] + + *) Fix abort code path in proxy_http.c, similar to FTP fix. + [Chuck Murcko <chuck@topsail.org>] + + *) Fix FTP ABOR command execution path. + [Victor Orlikowski <v.j.orlikowski@gte.net>] + + *) FTP return code variable cleanup; fixed problem in login + [Chuck Murcko <chuck@topsail.org>] + + *) Get PORT working again in the ftp proxy. + [Victor Orlikowski <v.j.orlikowski@gte.net>] + + *) Return result code check for FTP QUIT, after fixing + problems with passive connection handling. + [Victor Orlikowski <v.j.orlikowski@gte.net>] + + *) Reorganize ap_proxy_string_read() internally to not process eos + buckets. + [Chuck Murcko <chuck@topsail.org>] + [Victor Orlikowski <v.j.orlikowski@gte.net>] + + *) Remove result code check for FTP QUIT command. Some servers send + nothing at all back in response to QUIT. + [Chuck Murcko <chuck@topsail.org>] + [Victor Orlikowski <v.j.orlikowski@gte.net>] + +mod_proxy changes for httpd 2.0.19 + + *) Reverse previous patch since the core reverted. + [Chuck Murcko <chuck@topsail.org>] + + *) Remove indirection on number of bytes to read for input filters. + [Chuck Murcko <chuck@topsail.org>] + + *) Fixed a problem with directory listing corruption in the + PROXY_DIR filter. + [Graham Leggett <minfrin@sharp.fm>] + + *) mod_proxy and the proxy submodules now build properly as DSOs. + [Graham Leggett <minfrin@sharp.fm>] + + *) Stopped the HTTP proxy from trying to read entity bodies when there + wasn't one (response was 1xx, 204, 205 or 304). + [Graham Leggett <minfrin@sharp.fm>] + + *) Made sure dates were canonicalised correctly when passed to the client + browser through the HTTP proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) Split each individual proxy protocol into separate modules. + [Graham Leggett <minfrin@sharp.fm>] + + *) Added Max-Forwards support for all request types so as to prevent + loops. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fix warnings about byte count type on Darwin (connect handler). + [Chuck Murcko <chuck@topsail.org>] + +mod_proxy changes for httpd 2.0.18 + + *) IPV6 EPSV support for IPV6 in FTP proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) FTP directory filter works now. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fixed some thread-safety issues with the HTTP proxy in mod_proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) PASV FTP works now. + [Graham Leggett <minfrin@sharp.fm>] + + *) Reworked the line-at-a-time read from the control connection to + workaround a stray empty bucket returned by the HTTP_IN filter. + [Graham Leggett <minfrin@sharp.fm>] + + *) Stopped the CORE filter from sending off an HTTP response when a + CONNECT tunnel was closed. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fixed the poll() loop in proxy_connect.c -> it works now!!! + [Graham Leggett <minfrin@sharp.fm>] + + *) Converted send_dir() to ap_proxy_send_dir_filter() in proxy_ftp.c. + [Graham Leggett <minfrin@sharp.fm>] + +mod_proxy changes for httpd 2.0.17 + + *) Major rework of ap_proxy_ftp_handler() to use filters (begone foul + BUFF!!!). It compiles, but is untested, and the build environment needs + to be fixed to include proxy_ftp.c. + [Graham Leggett <minfrin@sharp.fm>] + + *) Cleanup of dead functions within proxy_util.c. + [Graham Leggett <minfrin@sharp.fm>] + + *) Reworked the storage of the client socket between keepalive connections + to fix some nasty problems with the socket lasting longer than the + memory pool it was allocated from. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fixed bug where a hostname without a "." in it (such as "localhost") + would not trigger an IP address check with ProxyBlock. + [Graham Leggett <minfrin@sharp.fm>] + +mod_proxy changes for httpd 2.0.16 + + *) Fixed ProxyBlock bugs with ap_proxy_http_handler() and + ap_proxy_connect_handler(). + [Graham Leggett <minfrin@sharp.fm>] + + *) Updated ap_proxy_connect_handler() to support APR, while + moving some common code between http_handler and connect_handler + to proxy_util.c. + [Graham Leggett <minfrin@sharp.fm>] + + *) Updated mod_proxy.html docs to include v2.0 configuration. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fixed problem where responses without entity bodies would cause + the directly following proxy keepalive request to fail. + [Graham Leggett <minfrin@sharp.fm>] + +mod_proxy changes for httpd 2.0.15 + + *) Added support for downstream keepalives in mod_proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) Changed mod_proxy ap_proxy_http_handler() to support APR properly. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fix problem where incoming response headers were not being returned + to the client in mod_proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) Added X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Server to + reverse proxied request headers in mod_proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) replace INADDR_NONE with APR_INADDR_NONE [Ian Holsman <IanH@cnet.com>] + + *) Fix problem with proxy configuration where globally set + configuration options were overridden inside virtual hosts. + [Graham Leggett <minfrin@sharp.fm>] + + *) Fix ProxyReceiveBufferSize where default value was left + uninitialised. + [Graham Leggett <minfrin@sharp.fm>] + + *) Some small changes: + - Ensured hop-by-hop headers were stripped as per + RFC2616 13.5.1. + - Upgraded version code to HTTP/1.1. + - Added Connection: close until Keepalives come. + - Some cosmetic fixes and commenting. + [Graham Leggett <minfrin@sharp.fm>] + +mod_proxy changes for httpd 2.0.14 + + *) removed ProxyNoCache and ProxyCacheForceCompletion config directives, + since we no longer directly cache from this module + [Chuck Murcko <chuck@topsail.org>] + + *) removed cache + [Chuck Murcko <chuck@topsail.org>] + + *) initial rerebuild for 2.0 + [Chuck Murcko <chuck@topsail.org>] + diff --git a/trunk/modules/proxy/Makefile.in b/trunk/modules/proxy/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/proxy/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/proxy/NWGNUmakefile b/trunk/modules/proxy/NWGNUmakefile new file mode 100644 index 0000000000..841673e473 --- /dev/null +++ b/trunk/modules/proxy/NWGNUmakefile @@ -0,0 +1,249 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxy.nlm \ + $(OBJDIR)/proxycon.nlm \ + $(OBJDIR)/proxyftp.nlm \ + $(OBJDIR)/proxyhtp.nlm \ + $(OBJDIR)/proxybalancer.nlm \ + $(OBJDIR)/proxyajp.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxy b/trunk/modules/proxy/NWGNUproxy new file mode 100644 index 0000000000..ac36e50bea --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxy @@ -0,0 +1,272 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/ssl \ + $(AP_WORK)/modules/generators \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxy + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Proxy Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxy.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy.o \ + $(OBJDIR)/proxy_util.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + proxy_hook_pre_request \ + proxy_hook_post_request \ + ap_proxy_ssl_enable \ + ap_proxy_ssl_disable \ + ap_proxy_conn_is_https \ + ap_proxy_ssl_val \ + proxy_run_fixups \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxyajp b/trunk/modules/proxy/NWGNUproxyajp new file mode 100644 index 0000000000..3d65d706c4 --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxyajp @@ -0,0 +1,273 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -relax_pointers \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxyajp + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy AJP Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Proxy AJP Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxyajp.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy_ajp.o \ + $(OBJDIR)/proxy_util.o \ + $(OBJDIR)/ajp_header.o \ + $(OBJDIR)/ajp_msg.o \ + $(OBJDIR)/ajp_link.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + proxy \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + proxy_run_fixups \ + ap_proxy_ssl_enable \ + ap_proxy_ssl_disable \ + ap_proxy_conn_is_https \ + ap_proxy_ssl_val \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_ajp_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxybalancer b/trunk/modules/proxy/NWGNUproxybalancer new file mode 100644 index 0000000000..5b93cac894 --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxybalancer @@ -0,0 +1,270 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxybalancer + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy Balancer Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Prxy Blncr Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxybalancer.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy_balancer.o \ + $(OBJDIR)/proxy_util.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + proxy \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + proxy_hook_pre_request \ + proxy_hook_post_request \ + proxy_run_fixups \ + ap_proxy_ssl_enable \ + ap_proxy_ssl_disable \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_balancer_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxycon b/trunk/modules/proxy/NWGNUproxycon new file mode 100644 index 0000000000..1e044b68a0 --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxycon @@ -0,0 +1,256 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxycon + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy Connection Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Proxy Conn Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxycon.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy_connect.o \ + $(OBJDIR)/proxy_util.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + proxy \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_connect_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxyftp b/trunk/modules/proxy/NWGNUproxyftp new file mode 100644 index 0000000000..c8a1bd846d --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxyftp @@ -0,0 +1,267 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxyftp + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy FTP Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Proxy FTP Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxyftp.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy_ftp.o \ + $(OBJDIR)/proxy_util.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + proxy \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + ap_proxy_ssl_enable \ + ap_proxy_ssl_disable \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_ftp_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/NWGNUproxyhtp b/trunk/modules/proxy/NWGNUproxyhtp new file mode 100644 index 0000000000..bf4f870123 --- /dev/null +++ b/trunk/modules/proxy/NWGNUproxyhtp @@ -0,0 +1,268 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/include \ + $(NWOS) \ + $(AP_WORK)/modules/http \ + $(AP_WORK)/modules/arch/netware \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -prefix pre_nw.h \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = proxyhtp + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy HTTP Sub-Module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = Proxy HTTP Module + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/proxyhtp.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/mod_proxy_http.o \ + $(OBJDIR)/proxy_util.o \ + $(OBJDIR)/libprews.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + proxy \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @$(NWOS)/httpd.imp \ + @libc.imp \ + proxy_module \ + proxy_hook_scheme_handler \ + proxy_hook_canon_handler \ + proxy_run_fixups \ + ap_proxy_ssl_enable \ + ap_proxy_ssl_disable \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + proxy_http_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +vpath %.c ../arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/modules/proxy/ajp.h b/trunk/modules/proxy/ajp.h new file mode 100644 index 0000000000..94246dbaab --- /dev/null +++ b/trunk/modules/proxy/ajp.h @@ -0,0 +1,462 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AJP_H +#define AJP_H + +#include "apr_version.h" +#include "apr.h" + +#include "apr_hooks.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_md5.h" +#include "apr_network_io.h" +#include "apr_pools.h" +#include "apr_strings.h" +#include "apr_uri.h" +#include "apr_date.h" +#include "apr_fnmatch.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#if APR_HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif + +#define AJP13_DEF_HOST "127.0.0.1" +#ifdef NETWARE +#define AJP13_DEF_PORT 9009 /* default to 9009 since 8009 is used by OS */ +#else +#define AJP13_DEF_PORT 8009 +#endif + +/* The following environment variables match mod_ssl! */ +#define AJP13_HTTPS_INDICATOR "HTTPS" +#define AJP13_SSL_CLIENT_CERT_INDICATOR "SSL_CLIENT_CERT" +#define AJP13_SSL_CIPHER_INDICATOR "SSL_CIPHER" +#define AJP13_SSL_SESSION_INDICATOR "SSL_SESSION_ID" +#define AJP13_SSL_KEY_SIZE_INDICATOR "SSL_CIPHER_USEKEYSIZE" + +#if APR_CHARSET_EBCDIC + +#define USE_CHARSET_EBCDIC +#define ajp_xlate_to_ascii(b, l) ap_xlate_proto_to_ascii(b, l) +#define ajp_xlate_from_ascii(b, l) ap_xlate_proto_from_ascii(b, l) + +#else /* APR_CHARSET_EBCDIC */ + +#define ajp_xlate_to_ascii(b, l) +#define ajp_xlate_from_ascii(b, l) + +#endif + +#ifdef AJP_USE_HTTPD_WRAP +#include "httpd_wrap.h" +#else +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_log.h" +#endif + +#include "mod_proxy.h" + + +/** AJP Specific error codes + */ +/** Buffer overflow exception */ +#define AJP_EOVERFLOW (APR_OS_START_USERERR + 1) +/** Destination Buffer is to small */ +#define AJP_ETOSMALL (APR_OS_START_USERERR + 2) +/** Invalid input parameters */ +#define AJP_EINVAL (APR_OS_START_USERERR + 3) +/** Bad message signature */ +#define AJP_EBAD_SIGNATURE (APR_OS_START_USERERR + 4) +/** Incoming message too bg */ +#define AJP_ETOBIG (APR_OS_START_USERERR + 5) +/** Missing message header */ +#define AJP_ENO_HEADER (APR_OS_START_USERERR + 6) +/** Bad message header */ +#define AJP_EBAD_HEADER (APR_OS_START_USERERR + 7) +/** Bad message */ +#define AJP_EBAD_MESSAGE (APR_OS_START_USERERR + 8) +/** Cant log via AJP14 */ +#define AJP_ELOGFAIL (APR_OS_START_USERERR + 9) +/** Bad request method */ +#define AJP_EBAD_METHOD (APR_OS_START_USERERR + 10) + + +/** A structure that represents ajp message */ +typedef struct ajp_msg ajp_msg_t; + +/** A structure that represents ajp message */ +struct ajp_msg +{ + /** The buffer holding a AJP message */ + apr_byte_t *buf; + /** The length of AJP message header (defaults to AJP_HEADER_LEN) */ + apr_size_t header_len; + /** The length of AJP message */ + apr_size_t len; + /** The current read position */ + apr_size_t pos; + /** Flag indicating the origing of the message */ + int server_side; +}; + +/** + * @defgroup AJP_defines AJP definitions + * @{ + */ +/** + * Signature for the messages sent from Apache to tomcat + */ +#define AJP13_WS_HEADER 0x1234 +#define AJP_HEADER_LEN 4 +#define AJP_HEADER_SZ_LEN 2 +#define AJP_MSG_BUFFER_SZ (8*1024) +#define AJP13_MAX_SEND_BODY_SZ (AJP_MSG_BUFFER_SZ - 6) + +/** Send a request from web server to container*/ +#define CMD_AJP13_FORWARD_REQUEST (unsigned char)2 +/** Write a body chunk from the servlet container to the web server */ +#define CMD_AJP13_SEND_BODY_CHUNK (unsigned char)3 +/** Send response headers from the servlet container to the web server. */ +#define CMD_AJP13_SEND_HEADERS (unsigned char)4 +/** Marks the end of response. */ +#define CMD_AJP13_END_RESPONSE (unsigned char)5 +/** Get further data from the web server if it hasn't all been transferred yet. */ +#define CMD_AJP13_GET_BODY_CHUNK (unsigned char)6 +/** The web server asks the container to shut itself down. */ +#define CMD_AJP13_SHUTDOWN (unsigned char)7 +/** Webserver ask container to take control (logon phase) */ +#define CMD_AJP13_PING (unsigned char)8 +/** Container response to cping request */ +#define CMD_AJP13_CPONG (unsigned char)9 +/** Webserver check if container is alive, since container should respond by cpong */ +#define CMD_AJP13_CPING (unsigned char)10 + +/** @} */ + +/** + * @defgroup AJP_api AJP API functions + * @{ + */ +/** + * Check a new AJP Message by looking at signature and return its size + * + * @param msg AJP Message to check + * @param len Pointer to returned len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len); + +/** + * Reset an AJP Message + * + * @param msg AJP Message to reset + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_reset(ajp_msg_t *msg); + +/** + * Mark the end of an AJP Message + * + * @param msg AJP Message to end + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_end(ajp_msg_t *msg); + +/** + * Add an unsigned 32bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value); + +/** + * Add an unsigned 16bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value); + +/** + * Add an unsigned 8bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value); + +/** + * Add a String in AJP message, and transform the String in ASCII + * if convert is set and we're on an EBCDIC machine + * + * @param msg AJP Message to get value from + * @param value Pointer to String + * @param convert When set told to convert String to ASCII + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, + int convert); +/** + * Add a String in AJP message, and transform + * the String in ASCII if we're on an EBCDIC machine + */ +#define ajp_msg_append_string(m, v) ajp_msg_append_string_ex(m, v, 1) + +/** + * Add a String in AJP message. + */ +#define ajp_msg_append_string_ascii(m, v) ajp_msg_append_string_ex(m, v, 0) + +/** + * Add a Byte array to AJP Message + * + * @param msg AJP Message to get value from + * @param value Pointer to Byte array + * @param valuelen Byte array len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value, + apr_size_t valuelen); + +/** + * Get a 32bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue); + +/** + * Get a 16bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue); + +/** + * Peek a 16bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue); + +/** + * Get a 8bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue); + +/** + * Peek a 8bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue); + +/** + * Get a String value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue); + + +/** + * Get a Byte array from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @param rvalueLen Pointer where Byte array len will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, + apr_size_t *rvalue_len); + +/** + * Create an AJP Message from pool + * + * @param pool memory pool to allocate AJP message from + * @param rmsg Pointer to newly created AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg); + +/** + * Recopy an AJP Message to another + * + * @param smsg source AJP message + * @param dmsg destination AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg); + +/** + * Serialize in an AJP Message a PING command + * + * +-----------------------+ + * | PING CMD (1 byte) | + * +-----------------------+ + * + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg); + +/** + * Serialize in an AJP Message a CPING command + * + * +-----------------------+ + * | CPING CMD (1 byte) | + * +-----------------------+ + * + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg); + +/** + * Dump up to the first 1024 bytes on an AJP Message + * + * @param pool pool to allocate from + * @param msg AJP Message to dump + * @param err error string to display + * @return dump message + */ +char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err); + +/** + * Send an AJP message to backend + * + * @param soct backend socket + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg); + +/** + * Receive an AJP message from backend + * + * @param sock backend socket + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg); + +/** + * Build the ajp header message and send it + * @param sock backend socket + * @param r current request + * @uri uri requested uri + * @return APR_SUCCESS or error + */ +apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, + apr_uri_t *uri); + +/** + * Read the ajp message and return the type of the message. + * @param sock backend socket + * @param r current request + * @param msg returned AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_read_header(apr_socket_t *sock, + request_rec *r, + ajp_msg_t **msg); + +/** + * Allocate a msg to send data + * @param pool pool to allocate from + * @param ptr data buffer + * @param len the length of allocated data buffer + * @param msg returned AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, + apr_size_t *len, ajp_msg_t **msg); + +/** + * Send the data message + * @param sock backend socket + * @param msg AJP message to send + * @param len AJP message length + * @return APR_SUCCESS or error + */ +apr_status_t ajp_send_data_msg(apr_socket_t *sock, + ajp_msg_t *msg, apr_size_t len); + +/** + * Parse the message type + * @param r current request + * @param msg AJP message + * @return AJP message type. + */ +int ajp_parse_type(request_rec *r, ajp_msg_t *msg); + +/** + * Parse the header message from container + * @param r current request + * @param msg AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_header(request_rec *r, proxy_server_conf *conf, + ajp_msg_t *msg); + +/** + * Parse the message body and return data address and length + * @param r current request + * @param msg AJP message + * @param len returned AJP message length + * @param ptr returned data + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, + apr_uint16_t *len, char **ptr); + +/** @} */ + +#endif /* AJP_H */ + diff --git a/trunk/modules/proxy/ajp_header.c b/trunk/modules/proxy/ajp_header.c new file mode 100644 index 0000000000..b1766f8860 --- /dev/null +++ b/trunk/modules/proxy/ajp_header.c @@ -0,0 +1,719 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ajp_header.h" +#include "ajp.h" + +static const char *response_trans_headers[] = { + "Content-Type", + "Content-Language", + "Content-Length", + "Date", + "Last-Modified", + "Location", + "Set-Cookie", + "Set-Cookie2", + "Servlet-Engine", + "Status", + "WWW-Authenticate" +}; + +static const char *long_res_header_for_sc(int sc) +{ + const char *rc = NULL; + sc = sc & 0X00FF; + if(sc <= SC_RES_HEADERS_NUM && sc > 0) { + rc = response_trans_headers[sc - 1]; + } + + return rc; +} + +#define UNKNOWN_METHOD (-1) + +static int sc_for_req_header(const char *header_name) +{ + char header[16]; + apr_size_t len = strlen(header_name); + const char *p = header_name; + int i = 0; + + /* ACCEPT-LANGUAGE is the longest headeer + * that is of interest. + */ + if (len < 4 || len > 15) + return UNKNOWN_METHOD; + + while (*p) + header[i++] = apr_toupper(*p++); + header[i] = '\0'; + p = &header[1]; + + switch (header[0]) { + case 'A': + if (memcmp(p, "CCEPT", 5) == 0) { + if (!header[6]) + return SC_ACCEPT; + else if (header[6] == '-') { + p += 6; + if (memcmp(p, "CHARSET", 7) == 0) + return SC_ACCEPT_CHARSET; + else if (memcmp(p, "ENCODING", 8) == 0) + return SC_ACCEPT_ENCODING; + else if (memcmp(p, "LANGUAGE", 8) == 0) + return SC_ACCEPT_LANGUAGE; + else + return UNKNOWN_METHOD; + } + else + return UNKNOWN_METHOD; + } + else if (memcmp(p, "UTHORIZATION", 12) == 0) + return SC_AUTHORIZATION; + else + return UNKNOWN_METHOD; + break; + case 'C': + if (memcmp(p, "OOKIE", 5) == 0) + return SC_COOKIE; + else if(memcmp(p, "ONNECTION", 9) == 0) + return SC_CONNECTION; + else if(memcmp(p, "ONTENT-TYPE", 11) == 0) + return SC_CONTENT_TYPE; + else if(memcmp(p, "ONTENT-LENGTH", 13) == 0) + return SC_CONTENT_LENGTH; + else if(memcmp(p, "OOKIE2", 6) == 0) + return SC_COOKIE2; + else + return UNKNOWN_METHOD; + break; + case 'H': + if(memcmp(p, "OST", 3) == 0) + return SC_HOST; + else + return UNKNOWN_METHOD; + break; + case 'P': + if(memcmp(p, "RAGMA", 5) == 0) + return SC_PRAGMA; + else + return UNKNOWN_METHOD; + break; + case 'R': + if(memcmp(p, "EFERER", 6) == 0) + return SC_REFERER; + else + return UNKNOWN_METHOD; + break; + case 'U': + if(memcmp(p, "SER-AGENT", 9) == 0) + return SC_USER_AGENT; + else + return UNKNOWN_METHOD; + break; + default: + return UNKNOWN_METHOD; + } + + /* NOTREACHED */ +} + +/* Apache method number to SC methods transform table */ +static const unsigned char sc_for_req_method_table[] = { + SC_M_GET, + SC_M_PUT, + SC_M_POST, + SC_M_DELETE, + 0, /* M_DELETE */ + SC_M_OPTIONS, + SC_M_TRACE, + 0, /* M_PATCH */ + SC_M_PROPFIND, + SC_M_PROPPATCH, + SC_M_MKCOL, + SC_M_COPY, + SC_M_MOVE, + SC_M_LOCK, + SC_M_UNLOCK, + SC_M_VERSION_CONTROL, + SC_M_CHECKOUT, + SC_M_UNCHECKOUT, + SC_M_CHECKIN, + SC_M_UPDATE, + SC_M_LABEL, + SC_M_REPORT, + SC_M_MKWORKSPACE, + SC_M_MKACTIVITY, + SC_M_BASELINE_CONTROL, + SC_M_MERGE, + 0 /* M_INVALID */ +}; + +static int sc_for_req_method_by_id(int method_id) +{ + if (method_id < 0 || method_id > M_INVALID) + return UNKNOWN_METHOD; + else + return sc_for_req_method_table[method_id] ? + sc_for_req_method_table[method_id] : UNKNOWN_METHOD; +} + +/* + * Message structure + * + * +AJPV13_REQUEST/AJPV14_REQUEST= + request_prefix (1) (byte) + method (byte) + protocol (string) + req_uri (string) + remote_addr (string) + remote_host (string) + server_name (string) + server_port (short) + is_ssl (boolean) + num_headers (short) + num_headers*(req_header_name header_value) + + ?context (byte)(string) + ?servlet_path (byte)(string) + ?remote_user (byte)(string) + ?auth_type (byte)(string) + ?query_string (byte)(string) + ?jvm_route (byte)(string) + ?ssl_cert (byte)(string) + ?ssl_cipher (byte)(string) + ?ssl_session (byte)(string) + ?ssl_key_size (byte)(int) via JkOptions +ForwardKeySize + request_terminator (byte) + ?body content_length*(var binary) + + */ + +static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg, + request_rec *r, + apr_uri_t *uri) +{ + int method; + apr_uint32_t i, num_headers = 0; + apr_byte_t is_ssl; + char *remote_host; + const char *session_route, *envvar; + const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); + const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Into ajp_marshal_into_msgb"); + + if ((method = sc_for_req_method_by_id(r->method_number)) == UNKNOWN_METHOD) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb - No such method %s", + r->method); + return AJP_EBAD_METHOD; + } + + is_ssl = (apr_byte_t) ap_proxy_conn_is_https(r->connection); + + if (r->headers_in && apr_table_elts(r->headers_in)) { + const apr_array_header_t *t = apr_table_elts(r->headers_in); + num_headers = t->nelts; + } + + remote_host = (char *)ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, NULL); + + ajp_msg_reset(msg); + + if (ajp_msg_append_uint8(msg, CMD_AJP13_FORWARD_REQUEST) || + ajp_msg_append_uint8(msg, method) || + ajp_msg_append_string(msg, r->protocol) || + ajp_msg_append_string(msg, uri->path) || + ajp_msg_append_string(msg, r->connection->remote_ip) || + ajp_msg_append_string(msg, remote_host) || + ajp_msg_append_string(msg, ap_get_server_name(r)) || + ajp_msg_append_uint16(msg, (apr_uint16_t)r->connection->local_addr->port) || + ajp_msg_append_uint8(msg, is_ssl) || + ajp_msg_append_uint16(msg, (apr_uint16_t) num_headers)) { + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the message begining"); + return APR_EGENERAL; + } + + for (i = 0 ; i < num_headers ; i++) { + int sc; + const apr_array_header_t *t = apr_table_elts(r->headers_in); + const apr_table_entry_t *elts = (apr_table_entry_t *)t->elts; + + if ((sc = sc_for_req_header(elts[i].key)) != UNKNOWN_METHOD) { + if (ajp_msg_append_uint16(msg, (apr_uint16_t)sc)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the header name"); + return AJP_EOVERFLOW; + } + } + else { + if (ajp_msg_append_string(msg, elts[i].key)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the header name"); + return AJP_EOVERFLOW; + } + } + + if (ajp_msg_append_string(msg, elts[i].val)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the header value"); + return AJP_EOVERFLOW; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_marshal_into_msgb: Header[%d] [%s] = [%s]", + i, elts[i].key, elts[i].val); + } + +/* XXXX need to figure out how to do this + if (s->secret) { + if (ajp_msg_append_uint8(msg, SC_A_SECRET) || + ajp_msg_append_string(msg, s->secret)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error ajp_marshal_into_msgb - " + "Error appending secret"); + return APR_EGENERAL; + } + } + */ + + if (r->user) { + if (ajp_msg_append_uint8(msg, SC_A_REMOTE_USER) || + ajp_msg_append_string(msg, r->user)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the remote user"); + return AJP_EOVERFLOW; + } + } + if (r->ap_auth_type) { + if (ajp_msg_append_uint8(msg, SC_A_AUTH_TYPE) || + ajp_msg_append_string(msg, r->ap_auth_type)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the auth type"); + return AJP_EOVERFLOW; + } + } + /* XXXX ebcdic (args converted?) */ + if (uri->query) { + if (ajp_msg_append_uint8(msg, SC_A_QUERY_STRING) || + ajp_msg_append_string(msg, uri->query)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the query string"); + return AJP_EOVERFLOW; + } + } + if ((session_route = apr_table_get(r->notes, "session-route"))) { + if (ajp_msg_append_uint8(msg, SC_A_JVM_ROUTE) || + ajp_msg_append_string(msg, session_route)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the jvm route"); + return AJP_EOVERFLOW; + } + } +/* XXX: Is the subprocess_env a right place? + * <Location /examples> + * ProxyPass ajp://remote:8009/servlets-examples + * SetEnv SSL_SESSION_ID CUSTOM_SSL_SESSION_ID + * </Location> + */ + if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, + AJP13_SSL_CLIENT_CERT_INDICATOR))) { + if (ajp_msg_append_uint8(msg, SC_A_SSL_CERT) || + ajp_msg_append_string(msg, envvar)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the SSL certificates"); + return AJP_EOVERFLOW; + } + } + + if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, + AJP13_SSL_CIPHER_INDICATOR))) { + if (ajp_msg_append_uint8(msg, SC_A_SSL_CIPHER) || + ajp_msg_append_string(msg, envvar)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the SSL ciphers"); + return AJP_EOVERFLOW; + } + } + + if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, + AJP13_SSL_SESSION_INDICATOR))) { + if (ajp_msg_append_uint8(msg, SC_A_SSL_SESSION) || + ajp_msg_append_string(msg, envvar)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the SSL session"); + return AJP_EOVERFLOW; + } + } + + /* + * ssl_key_size is required by Servlet 2.3 API + * added support only in ajp14 mode + * JFC removed: ae->proto == AJP14_PROTO + */ + /* XXXX ignored for the moment + if (s->ssl_key_size != -1) { + if (ajp_msg_append_uint8(msg, SC_A_SSL_KEY_SIZE) || + ajp_msg_append_uint16(msg, (unsigned short) s->ssl_key_size)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error ajp_marshal_into_msgb - " + "Error appending the SSL key size"); + return APR_EGENERAL; + } + } + */ + /* Use the environment vars prefixed with AJP_ + * and pass it to the header striping that prefix. + */ + for (i = 0; i < (apr_uint32_t)arr->nelts; i++) { + if (!strncmp(elts[i].key, "AJP_", 4)) { + if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) || + ajp_msg_append_string(msg, elts[i].key + 4) || + ajp_msg_append_string(msg, elts[i].val)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending attribute %s=%s", + elts[i].key, elts[i].val); + return AJP_EOVERFLOW; + } + } + } + + if (ajp_msg_append_uint8(msg, SC_A_ARE_DONE)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_marshal_into_msgb: " + "Error appending the message end"); + return AJP_EOVERFLOW; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_marshal_into_msgb: Done"); + return APR_SUCCESS; +} + +/* +AJPV13_RESPONSE/AJPV14_RESPONSE:= + response_prefix (2) + status (short) + status_msg (short) + num_headers (short) + num_headers*(res_header_name header_value) + *body_chunk + terminator boolean <! -- recycle connection or not --> + +req_header_name := + sc_req_header_name | (string) + +res_header_name := + sc_res_header_name | (string) + +header_value := + (string) + +body_chunk := + length (short) + body length*(var binary) + + */ + + +static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg, + request_rec *r, + proxy_server_conf *conf) +{ + apr_uint16_t status; + apr_status_t rc; + const char *ptr; + apr_uint16_t num_headers; + int i; + + rc = ajp_msg_get_uint16(msg, &status); + + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_unmarshal_response: Null status"); + return rc; + } + r->status = status; + + rc = ajp_msg_get_string(msg, &ptr); + if (rc == APR_SUCCESS) { + r->status_line = apr_psprintf(r->pool, "%d %s", status, ptr); +#if defined(AS400) || defined(_OSD_POSIX) + ap_xlate_proto_from_ascii(r->status_line, strlen(r->status_line)); +#endif + } else { + r->status_line = NULL; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_unmarshal_response: status = %d", status); + + rc = ajp_msg_get_uint16(msg, &num_headers); + if (rc == APR_SUCCESS) { + r->headers_out = apr_table_make(r->pool, num_headers); + } else { + r->headers_out = NULL; + num_headers = 0; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_unmarshal_response: Number of headers is = %d", + num_headers); + + for(i = 0 ; i < (int) num_headers ; i++) { + apr_uint16_t name; + const char *stringname; + const char *value; + rc = ajp_msg_peek_uint16(msg, &name); + if (rc != APR_SUCCESS) { + return rc; + } + + if ((name & 0XFF00) == 0XA000) { + ajp_msg_peek_uint16(msg, &name); + stringname = long_res_header_for_sc(name); + if (stringname == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_unmarshal_response: " + "No such sc (%08x)", + name); + return AJP_EBAD_HEADER; + } + } else { + name = 0; + rc = ajp_msg_get_string(msg, &stringname); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_unmarshal_response: " + "Null header name"); + return rc; + } +#if defined(AS400) || defined(_OSD_POSIX) + ap_xlate_proto_from_ascii(stringname, strlen(stringname)); +#endif + } + + rc = ajp_msg_get_string(msg, &value); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_unmarshal_response: " + "Null header value"); + return rc; + } + + /* Set-Cookie need additional processing */ + if (!strcasecmp(stringname, "Set-Cookie")) { + value = ap_proxy_cookie_reverse_map(r, conf, value); + } + /* Location, Content-Location, URI and Destination need additional + * processing */ + else if (!strcasecmp(stringname, "Location") + || !strcasecmp(stringname, "Content-Location") + || !strcasecmp(stringname, "URI") + || !strcasecmp(stringname, "Destination")) + { + value = ap_proxy_location_reverse_map(r, conf, value); + } + +#if defined(AS400) || defined(_OSD_POSIX) + ap_xlate_proto_from_ascii(value, strlen(value)); +#endif + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_unmarshal_response: Header[%d] [%s] = [%s]", + i, stringname, value); + + apr_table_add(r->headers_out, stringname, value); + + /* Content-type needs an additional handling */ + if (memcmp(stringname, "Content-Type", 12) == 0) { + /* add corresponding filter */ + ap_set_content_type(r, apr_pstrdup(r->pool, value)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_unmarshal_response: ap_set_content_type done"); + } + } + + return APR_SUCCESS; +} + +/* + * Build the ajp header message and send it + */ +apr_status_t ajp_send_header(apr_socket_t *sock, + request_rec *r, + apr_uri_t *uri) +{ + ajp_msg_t *msg; + apr_status_t rc; + + rc = ajp_msg_create(r->pool, &msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_send_header: ajp_msg_create failed"); + return rc; + } + + rc = ajp_marshal_into_msgb(msg, r, uri); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_send_header: ajp_marshal_into_msgb failed"); + return rc; + } + + rc = ajp_ilink_send(sock, msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_send_header: ajp_ilink_send failed"); + return rc; + } + + return APR_SUCCESS; +} + +/* + * Read the ajp message and return the type of the message. + */ +apr_status_t ajp_read_header(apr_socket_t *sock, + request_rec *r, + ajp_msg_t **msg) +{ + apr_byte_t result; + apr_status_t rc; + + rc = ajp_msg_create(r->pool, msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_read_header: ajp_msg_create failed"); + return rc; + } + ajp_msg_reset(*msg); + rc = ajp_ilink_receive(sock, *msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_read_header: ajp_ilink_receive failed"); + return rc; + } + rc = ajp_msg_peek_uint8(*msg, &result); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_read_header: ajp_ilink_received %02x", result); + return APR_SUCCESS; +} + +/* parse the msg to read the type */ +int ajp_parse_type(request_rec *r, ajp_msg_t *msg) +{ + apr_byte_t result; + ajp_msg_peek_uint8(msg, &result); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_parse_type: got %02x", result); + return (int) result; +} + +/* parse the header */ +apr_status_t ajp_parse_header(request_rec *r, proxy_server_conf *conf, + ajp_msg_t *msg) +{ + apr_byte_t result; + apr_status_t rc; + + rc = ajp_msg_get_uint8(msg, &result); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_headers: ajp_msg_get_byte failed"); + return rc; + } + if (result != CMD_AJP13_SEND_HEADERS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_headers: wrong type %02x expecting 0x04", result); + return AJP_EBAD_HEADER; + } + return ajp_unmarshal_response(msg, r, conf); +} + +/* parse the body and return data address and length */ +apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, + apr_uint16_t *len, char **ptr) +{ + apr_byte_t result; + apr_status_t rc; + + rc = ajp_msg_get_uint8(msg, &result); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_data: ajp_msg_get_byte failed"); + return rc; + } + if (result != CMD_AJP13_SEND_BODY_CHUNK) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_data: wrong type %02x expecting 0x03", result); + return AJP_EBAD_HEADER; + } + rc = ajp_msg_get_uint16(msg, len); + if (rc != APR_SUCCESS) { + return rc; + } + *ptr = (char *)&(msg->buf[msg->pos]); + return APR_SUCCESS; +} + +/* + * Allocate a msg to send data + */ +apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, apr_size_t *len, + ajp_msg_t **msg) +{ + apr_status_t rc; + + if ((rc = ajp_msg_create(pool, msg)) != APR_SUCCESS) + return rc; + ajp_msg_reset(*msg); + *ptr = (char *)&((*msg)->buf[6]); + *len = AJP_MSG_BUFFER_SZ-6; + + return APR_SUCCESS; +} + +/* + * Send the data message + */ +apr_status_t ajp_send_data_msg(apr_socket_t *sock, + ajp_msg_t *msg, apr_size_t len) +{ + + msg->buf[4] = (apr_byte_t)((len >> 8) & 0xFF); + msg->buf[5] = (apr_byte_t)(len & 0xFF); + + msg->len += len + 2; /* + 1 XXXX where is '\0' */ + + return ajp_ilink_send(sock, msg); + +} diff --git a/trunk/modules/proxy/ajp_header.h b/trunk/modules/proxy/ajp_header.h new file mode 100644 index 0000000000..35ac2e50f5 --- /dev/null +++ b/trunk/modules/proxy/ajp_header.h @@ -0,0 +1,165 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef AJP_HEADER_H +#define AJP_HEADER_H + +/* + * Conditional request attributes + * + */ +#define SC_A_CONTEXT (unsigned char)1 +#define SC_A_SERVLET_PATH (unsigned char)2 +#define SC_A_REMOTE_USER (unsigned char)3 +#define SC_A_AUTH_TYPE (unsigned char)4 +#define SC_A_QUERY_STRING (unsigned char)5 +#define SC_A_JVM_ROUTE (unsigned char)6 +#define SC_A_SSL_CERT (unsigned char)7 +#define SC_A_SSL_CIPHER (unsigned char)8 +#define SC_A_SSL_SESSION (unsigned char)9 +#define SC_A_REQ_ATTRIBUTE (unsigned char)10 +#define SC_A_SSL_KEY_SIZE (unsigned char)11 /* only in if JkOptions +ForwardKeySize */ +#define SC_A_SECRET (unsigned char)12 +#define SC_A_ARE_DONE (unsigned char)0xFF + +/* + * Request methods, coded as numbers instead of strings. + * The list of methods was taken from Section 5.1.1 of RFC 2616, + * RFC 2518, the ACL IETF draft, and the DeltaV IESG Proposed Standard. + * Method = "OPTIONS" + * | "GET" + * | "HEAD" + * | "POST" + * | "PUT" + * | "DELETE" + * | "TRACE" + * | "PROPFIND" + * | "PROPPATCH" + * | "MKCOL" + * | "COPY" + * | "MOVE" + * | "LOCK" + * | "UNLOCK" + * | "ACL" + * | "REPORT" + * | "VERSION-CONTROL" + * | "CHECKIN" + * | "CHECKOUT" + * | "UNCHECKOUT" + * | "SEARCH" + * | "MKWORKSPACE" + * | "UPDATE" + * | "LABEL" + * | "MERGE" + * | "BASELINE-CONTROL" + * | "MKACTIVITY" + * + */ +#define SC_M_OPTIONS (unsigned char)1 +#define SC_M_GET (unsigned char)2 +#define SC_M_HEAD (unsigned char)3 +#define SC_M_POST (unsigned char)4 +#define SC_M_PUT (unsigned char)5 +#define SC_M_DELETE (unsigned char)6 +#define SC_M_TRACE (unsigned char)7 +#define SC_M_PROPFIND (unsigned char)8 +#define SC_M_PROPPATCH (unsigned char)9 +#define SC_M_MKCOL (unsigned char)10 +#define SC_M_COPY (unsigned char)11 +#define SC_M_MOVE (unsigned char)12 +#define SC_M_LOCK (unsigned char)13 +#define SC_M_UNLOCK (unsigned char)14 +#define SC_M_ACL (unsigned char)15 +#define SC_M_REPORT (unsigned char)16 +#define SC_M_VERSION_CONTROL (unsigned char)17 +#define SC_M_CHECKIN (unsigned char)18 +#define SC_M_CHECKOUT (unsigned char)19 +#define SC_M_UNCHECKOUT (unsigned char)20 +#define SC_M_SEARCH (unsigned char)21 +#define SC_M_MKWORKSPACE (unsigned char)22 +#define SC_M_UPDATE (unsigned char)23 +#define SC_M_LABEL (unsigned char)24 +#define SC_M_MERGE (unsigned char)25 +#define SC_M_BASELINE_CONTROL (unsigned char)26 +#define SC_M_MKACTIVITY (unsigned char)27 + + +/* + * Frequent request headers, these headers are coded as numbers + * instead of strings. + * + * Accept + * Accept-Charset + * Accept-Encoding + * Accept-Language + * Authorization + * Connection + * Content-Type + * Content-Length + * Cookie + * Cookie2 + * Host + * Pragma + * Referer + * User-Agent + * + */ + +#define SC_ACCEPT (unsigned short)0xA001 +#define SC_ACCEPT_CHARSET (unsigned short)0xA002 +#define SC_ACCEPT_ENCODING (unsigned short)0xA003 +#define SC_ACCEPT_LANGUAGE (unsigned short)0xA004 +#define SC_AUTHORIZATION (unsigned short)0xA005 +#define SC_CONNECTION (unsigned short)0xA006 +#define SC_CONTENT_TYPE (unsigned short)0xA007 +#define SC_CONTENT_LENGTH (unsigned short)0xA008 +#define SC_COOKIE (unsigned short)0xA009 +#define SC_COOKIE2 (unsigned short)0xA00A +#define SC_HOST (unsigned short)0xA00B +#define SC_PRAGMA (unsigned short)0xA00C +#define SC_REFERER (unsigned short)0xA00D +#define SC_USER_AGENT (unsigned short)0xA00E + +/* + * Frequent response headers, these headers are coded as numbers + * instead of strings. + * + * Content-Type + * Content-Language + * Content-Length + * Date + * Last-Modified + * Location + * Set-Cookie + * Servlet-Engine + * Status + * WWW-Authenticate + * + */ + +#define SC_RESP_CONTENT_TYPE (unsigned short)0xA001 +#define SC_RESP_CONTENT_LANGUAGE (unsigned short)0xA002 +#define SC_RESP_CONTENT_LENGTH (unsigned short)0xA003 +#define SC_RESP_DATE (unsigned short)0xA004 +#define SC_RESP_LAST_MODIFIED (unsigned short)0xA005 +#define SC_RESP_LOCATION (unsigned short)0xA006 +#define SC_RESP_SET_COOKIE (unsigned short)0xA007 +#define SC_RESP_SET_COOKIE2 (unsigned short)0xA008 +#define SC_RESP_SERVLET_ENGINE (unsigned short)0xA009 +#define SC_RESP_STATUS (unsigned short)0xA00A +#define SC_RESP_WWW_AUTHENTICATE (unsigned short)0xA00B +#define SC_RES_HEADERS_NUM 11 + +#endif /* AJP_HEADER_H */ diff --git a/trunk/modules/proxy/ajp_link.c b/trunk/modules/proxy/ajp_link.c new file mode 100644 index 0000000000..b6e98b4ebd --- /dev/null +++ b/trunk/modules/proxy/ajp_link.c @@ -0,0 +1,126 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ajp.h" + + +apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg) +{ + char *buf; + apr_status_t status; + apr_size_t length; + + if (sock == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_ilink_send(): NULL socket provided"); + return AJP_EINVAL; + } + + ajp_msg_end(msg); + + length = msg->len; + buf = (char *)msg->buf; + + do { + apr_size_t written = length; + + status = apr_socket_send(sock, buf, &written); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, + "ajp_ilink_send(): send failed"); + return status; + } + length -= written; + buf += written; + } while (length); + + return APR_SUCCESS; +} + + +static apr_status_t ilink_read(apr_socket_t *sock, char * buf, + apr_size_t len) +{ + apr_size_t length = len; + apr_size_t rdlen = 0; + apr_status_t status; + + while (rdlen < len) { + + status = apr_socket_recv(sock, buf + rdlen, &length); + + if (status == APR_EOF) + return status; /* socket closed. */ + else if (APR_STATUS_IS_EAGAIN(status)) + continue; + else if (status != APR_SUCCESS) + return status; /* any error. */ + + rdlen += length; + length = len - rdlen; + } + return APR_SUCCESS; +} + + +apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg) +{ + apr_status_t status; + apr_size_t hlen; + apr_size_t blen; + + if (sock == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_ilink_receive(): NULL socket provided"); + return AJP_EINVAL; + } + + hlen = msg->header_len; + + status = ilink_read(sock, msg->buf, hlen); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, + "ajp_ilink_receive() can't receive header"); + return AJP_ENO_HEADER; + } + + status = ajp_msg_check_header(msg, &blen); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_ilink_receive() received bad header"); + return AJP_EBAD_HEADER; + } + + status = ilink_read(sock, msg->buf + hlen, blen); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, + "ajp_ilink_receive() error while receiving message body " + "of length %" APR_SIZE_T_FMT, + hlen); + return AJP_EBAD_MESSAGE; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "ajp_ilink_receive() received packet len=%" APR_SIZE_T_FMT + "type=%d", + blen, (int)msg->buf[hlen]); + + return APR_SUCCESS; +} + diff --git a/trunk/modules/proxy/ajp_msg.c b/trunk/modules/proxy/ajp_msg.c new file mode 100644 index 0000000000..0696f9c7fd --- /dev/null +++ b/trunk/modules/proxy/ajp_msg.c @@ -0,0 +1,584 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ajp.h" + + +static char *hex_table = "0123456789ABCDEF"; + +/** + * Dump up to the first 1024 bytes on an AJP Message + * + * @param pool pool to allocate from + * @param msg AJP Message to dump + * @param err error string to display + * @return dump message + */ +char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err) +{ + apr_size_t i, j; + char line[80]; + char *current; + char *rv, *p; + apr_size_t bl = 8192; + apr_byte_t x; + apr_size_t len = msg->len; + + /* Display only first 1024 bytes */ + if (len > 1024) + len = 1024; + rv = apr_palloc(pool, bl); + apr_snprintf(rv, bl, + "ajp_msg_dump(): %s pos=%" APR_SIZE_T_FMT + " len=%" APR_SIZE_T_FMT " max=%d\n", + err, msg->pos, msg->len, AJP_MSG_BUFFER_SZ); + bl -= strlen(rv); + p = rv + strlen(rv); + for (i = 0; i < len; i += 16) { + current = line; + + for (j = 0; j < 16; j++) { + x = msg->buf[i + j]; + + *current++ = hex_table[x >> 4]; + *current++ = hex_table[x & 0x0f]; + *current++ = ' '; + } + *current++ = ' '; + *current++ = '-'; + *current++ = ' '; + for (j = 0; j < 16; j++) { + x = msg->buf[i + j]; + + if (x > 0x20 && x < 0x7F) { + *current++ = x; + } + else { + *current++ = '.'; + } + } + + *current++ = '\0'; + apr_snprintf(p, bl, + "ajp_msg_dump(): %.4lx %s\n", + (unsigned long)i, line); + bl -= strlen(rv); + p = rv + strlen(rv); + + } + + return rv; +} + + +/** + * Check a new AJP Message by looking at signature and return its size + * + * @param msg AJP Message to check + * @param len Pointer to returned len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len) +{ + apr_byte_t *head = msg->buf; + apr_size_t msglen; + + if (!((head[0] == 0x41 && head[1] == 0x42) || + (head[0] == 0x12 && head[1] == 0x34))) { + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_check_msg_header() got bad signature %x%x", + head[0], head[1]); + + return AJP_EBAD_SIGNATURE; + } + + msglen = ((head[2] & 0xff) << 8); + msglen += (head[3] & 0xFF); + + if (msglen > AJP_MSG_BUFFER_SZ) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_check_msg_header() incoming message is " + "too big %" APR_SIZE_T_FMT ", max is %d", + msglen, AJP_MSG_BUFFER_SZ); + return AJP_ETOBIG; + } + + msg->len = msglen + AJP_HEADER_LEN; + msg->pos = AJP_HEADER_LEN; + *len = msglen; + + return APR_SUCCESS; +} + +/** + * Reset an AJP Message + * + * @param msg AJP Message to reset + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_reset(ajp_msg_t *msg) +{ + msg->len = AJP_HEADER_LEN; + msg->pos = AJP_HEADER_LEN; + + return APR_SUCCESS; +} + +/** + * Mark the end of an AJP Message + * + * @param msg AJP Message to end + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_end(ajp_msg_t *msg) +{ + apr_size_t len = msg->len - AJP_HEADER_LEN; + + if (msg->server_side) { + msg->buf[0] = 0x41; + msg->buf[1] = 0x42; + } + else { + msg->buf[0] = 0x12; + msg->buf[1] = 0x34; + } + + msg->buf[2] = (apr_byte_t)((len >> 8) & 0xFF); + msg->buf[3] = (apr_byte_t)(len & 0xFF); + + return APR_SUCCESS; +} + +static APR_INLINE int ajp_log_overflow(ajp_msg_t *msg, const char *context) +{ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "%s(): BufferOverflowException %" APR_SIZE_T_FMT + " %" APR_SIZE_T_FMT, + context, msg->pos, msg->len); + return AJP_EOVERFLOW; +} + +/** + * Add an unsigned 32bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value) +{ + apr_size_t len = msg->len; + + if ((len + 4) > AJP_MSG_BUFFER_SZ) { + return ajp_log_overflow(msg, "ajp_msg_append_uint32"); + } + + msg->buf[len] = (apr_byte_t)((value >> 24) & 0xFF); + msg->buf[len + 1] = (apr_byte_t)((value >> 16) & 0xFF); + msg->buf[len + 2] = (apr_byte_t)((value >> 8) & 0xFF); + msg->buf[len + 3] = (apr_byte_t)(value & 0xFF); + + msg->len += 4; + + return APR_SUCCESS; +} + +/** + * Add an unsigned 16bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value) +{ + apr_size_t len = msg->len; + + if ((len + 2) > AJP_MSG_BUFFER_SZ) { + return ajp_log_overflow(msg, "ajp_msg_append_uint16"); + } + + msg->buf[len] = (apr_byte_t)((value >> 8) & 0xFF); + msg->buf[len + 1] = (apr_byte_t)(value & 0xFF); + + msg->len += 2; + + return APR_SUCCESS; +} + +/** + * Add an unsigned 8bits value to AJP Message + * + * @param msg AJP Message to get value from + * @param value value to add to AJP Message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value) +{ + apr_size_t len = msg->len; + + if ((len + 1) > AJP_MSG_BUFFER_SZ) { + return ajp_log_overflow(msg, "ajp_msg_append_uint8"); + } + + msg->buf[len] = value; + msg->len += 1; + + return APR_SUCCESS; +} + +/** + * Add a String in AJP message, and transform the String in ASCII + * if convert is set and we're on an EBCDIC machine + * + * @param msg AJP Message to get value from + * @param value Pointer to String + * @param convert When set told to convert String to ASCII + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, + int convert) +{ + size_t len; + + if (value == NULL) { + return(ajp_msg_append_uint16(msg, 0xFFFF)); + } + + len = strlen(value); + if ((msg->len + len + 2) > AJP_MSG_BUFFER_SZ) { + return ajp_log_overflow(msg, "ajp_msg_append_cvt_string"); + } + + /* ignore error - we checked once */ + ajp_msg_append_uint16(msg, (apr_uint16_t)len); + + /* We checked for space !! */ + memcpy(msg->buf + msg->len, value, len + 1); /* including \0 */ + + if (convert) /* convert from EBCDIC if needed */ + ajp_xlate_to_ascii((char *)msg->buf + msg->len, len + 1); + + msg->len += len + 1; + + return APR_SUCCESS; +} + +/** + * Add a Byte array to AJP Message + * + * @param msg AJP Message to get value from + * @param value Pointer to Byte array + * @param valuelen Byte array len + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value, + apr_size_t valuelen) +{ + if (! valuelen) { + return APR_SUCCESS; /* Shouldn't we indicate an error ? */ + } + + if ((msg->len + valuelen) > AJP_MSG_BUFFER_SZ) { + return ajp_log_overflow(msg, "ajp_msg_append_bytes"); + } + + /* We checked for space !! */ + memcpy(msg->buf + msg->len, value, valuelen); + msg->len += valuelen; + + return APR_SUCCESS; +} + +/** + * Get a 32bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue) +{ + apr_uint32_t value; + + if ((msg->pos + 3) > msg->len) { + return ajp_log_overflow(msg, "ajp_msg_get_uint32"); + } + + value = ((msg->buf[(msg->pos++)] & 0xFF) << 24); + value |= ((msg->buf[(msg->pos++)] & 0xFF) << 16); + value |= ((msg->buf[(msg->pos++)] & 0xFF) << 8); + value |= ((msg->buf[(msg->pos++)] & 0xFF)); + + *rvalue = value; + return APR_SUCCESS; +} + + +/** + * Get a 16bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue) +{ + apr_uint16_t value; + + if ((msg->pos + 1) > msg->len) { + return ajp_log_overflow(msg, "ajp_msg_get_uint16"); + } + + value = ((msg->buf[(msg->pos++)] & 0xFF) << 8); + value += ((msg->buf[(msg->pos++)] & 0xFF)); + + *rvalue = value; + return APR_SUCCESS; +} + +/** + * Peek a 16bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue) +{ + apr_uint16_t value; + + if ((msg->pos + 1) > msg->len) { + return ajp_log_overflow(msg, "ajp_msg_peek_uint16"); + } + + value = ((msg->buf[(msg->pos)] & 0xFF) << 8); + value += ((msg->buf[(msg->pos + 1)] & 0xFF)); + + *rvalue = value; + return APR_SUCCESS; +} + +/** + * Peek a 8bits unsigned value from AJP Message, position in message + * is not updated + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue) +{ + if (msg->pos > msg->len) { + return ajp_log_overflow(msg, "ajp_msg_peek_uint8"); + } + + *rvalue = msg->buf[msg->pos]; + return APR_SUCCESS; +} + +/** + * Get a 8bits unsigned value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue) +{ + + if (msg->pos > msg->len) { + return ajp_log_overflow(msg, "ajp_msg_get_uint8"); + } + + *rvalue = msg->buf[msg->pos++]; + return APR_SUCCESS; +} + + +/** + * Get a String value from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue) +{ + apr_uint16_t size; + apr_size_t start; + apr_status_t status; + + status = ajp_msg_get_uint16(msg, &size); + start = msg->pos; + + if ((status != APR_SUCCESS) || (size + start > AJP_MSG_BUFFER_SZ)) { + return ajp_log_overflow(msg, "ajp_msg_get_string"); + } + + msg->pos += (apr_size_t)size; + msg->pos++; /* a String in AJP is NULL terminated */ + + *rvalue = (const char *)(msg->buf + start); + return APR_SUCCESS; +} + + +/** + * Get a Byte array from AJP Message + * + * @param msg AJP Message to get value from + * @param rvalue Pointer where value will be returned + * @param rvalueLen Pointer where Byte array len will be returned + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, + apr_size_t *rvalue_len) +{ + apr_uint16_t size; + apr_size_t start; + apr_status_t status; + + status = ajp_msg_get_uint16(msg, &size); + /* save the current position */ + start = msg->pos; + + if ((status != APR_SUCCESS) || (size + start > AJP_MSG_BUFFER_SZ)) { + return ajp_log_overflow(msg, "ajp_msg_get_bytes"); + } + msg->pos += (apr_size_t)size; /* only bytes, no trailer */ + + *rvalue = msg->buf + start; + *rvalue_len = size; + + return APR_SUCCESS; +} + + +/** + * Create an AJP Message from pool + * + * @param pool memory pool to allocate AJP message from + * @param rmsg Pointer to newly created AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg) +{ + ajp_msg_t *msg = (ajp_msg_t *)apr_pcalloc(pool, sizeof(ajp_msg_t)); + + if (!msg) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_msg_create(): can't allocate AJP message memory"); + return APR_ENOPOOL; + } + + msg->server_side = 0; + + msg->buf = (apr_byte_t *)apr_palloc(pool, AJP_MSG_BUFFER_SZ); + + /* XXX: This should never happen + * In case if the OS cannont allocate 8K of data + * we are in serious trouble + * No need to check the alloc return value, cause the + * core dump is probably the best solution anyhow. + */ + if (msg->buf == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_msg_create(): can't allocate AJP message memory"); + return APR_ENOPOOL; + } + + msg->len = 0; + msg->header_len = AJP_HEADER_LEN; + *rmsg = msg; + + return APR_SUCCESS; +} + +/** + * Recopy an AJP Message to another + * + * @param smsg source AJP message + * @param dmsg destination AJP message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg) +{ + if (dmsg == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_msg_copy(): destination msg is null"); + return AJP_EINVAL; + } + + if (smsg->len > AJP_MSG_BUFFER_SZ) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "ajp_msg_copy(): destination buffer too " + "small %" APR_SIZE_T_FMT ", max size is %d", + smsg->len, AJP_MSG_BUFFER_SZ); + return AJP_ETOSMALL; + } + + memcpy(dmsg->buf, smsg->buf, smsg->len); + dmsg->len = smsg->len; + dmsg->pos = smsg->pos; + + return APR_SUCCESS; +} + + +/** + * Serialize in an AJP Message a PING command + * + * +-----------------------+ + * | PING CMD (1 byte) | + * +-----------------------+ + * + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg) +{ + apr_status_t rc; + ajp_msg_reset(msg); + + if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_PING)) != APR_SUCCESS) + return rc; + + return APR_SUCCESS; +} + +/** + * Serialize in an AJP Message a CPING command + * + * +-----------------------+ + * | CPING CMD (1 byte) | + * +-----------------------+ + * + * @param smsg AJP message to put serialized message + * @return APR_SUCCESS or error + */ +apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg) +{ + apr_status_t rc; + ajp_msg_reset(msg); + + if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_CPING)) != APR_SUCCESS) + return rc; + + return APR_SUCCESS; +} diff --git a/trunk/modules/proxy/config.m4 b/trunk/modules/proxy/config.m4 new file mode 100644 index 0000000000..f131ee6611 --- /dev/null +++ b/trunk/modules/proxy/config.m4 @@ -0,0 +1,42 @@ +dnl modules enabled in this directory by default + +APACHE_MODPATH_INIT(proxy) + +if test "$enable_proxy" = "shared"; then + proxy_mods_enable=shared +elif test "$enable_proxy" = "yes"; then + proxy_mods_enable=yes +else + proxy_mods_enable=no +fi + +proxy_objs="mod_proxy.lo proxy_util.lo" +APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , $proxy_mods_enable) + +proxy_connect_objs="mod_proxy_connect.lo" +proxy_ftp_objs="mod_proxy_ftp.lo" +proxy_http_objs="mod_proxy_http.lo" +proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo" +proxy_balancer_objs="mod_proxy_balancer.lo" + +case "$host" in + *os2*) + # OS/2 DLLs must resolve all symbols at build time and + # these sub-modules need some from the main proxy module + proxy_connect_objs="$proxy_connect_objs mod_proxy.la" + proxy_ftp_objs="$proxy_ftp_objs mod_proxy.la" + proxy_http_objs="$proxy_http_objs mod_proxy.la" + proxy_ajp_objs="$proxy_ajp_objs mod_proxy.la" + proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la" + ;; +esac + +APACHE_MODULE(proxy_connect, Apache proxy CONNECT module, $proxy_connect_objs, , $proxy_mods_enable) +APACHE_MODULE(proxy_ftp, Apache proxy FTP module, $proxy_ftp_objs, , $proxy_mods_enable) +APACHE_MODULE(proxy_http, Apache proxy HTTP module, $proxy_http_objs, , $proxy_mods_enable) +APACHE_MODULE(proxy_ajp, Apache proxy AJP module, $proxy_ajp_objs, , $proxy_mods_enable) +APACHE_MODULE(proxy_balancer, Apache proxy BALANCER module, $proxy_balancer_objs, , $proxy_mods_enable) + +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current/../generators]) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/proxy/libproxy.exp b/trunk/modules/proxy/libproxy.exp new file mode 100644 index 0000000000..a20f2378f5 --- /dev/null +++ b/trunk/modules/proxy/libproxy.exp @@ -0,0 +1 @@ +proxy_module diff --git a/trunk/modules/proxy/mod_proxy.c b/trunk/modules/proxy/mod_proxy.c new file mode 100644 index 0000000000..7f09042957 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy.c @@ -0,0 +1,1874 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE + +#include "mod_proxy.h" +#include "mod_core.h" +#include "apr_optional.h" +#include "scoreboard.h" +#include "mod_status.h" + +#if (MODULE_MAGIC_NUMBER_MAJOR > 20020903) +#include "mod_ssl.h" +#else +APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); +APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); +APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, char *)); +#endif + +#ifndef MAX +#define MAX(x,y) ((x) >= (y) ? (x) : (y)) +#endif + +/* + * A Web proxy module. Stages: + * + * translate_name: set filename to proxy:<URL> + * map_to_storage: run proxy_walk (rather than directory_walk/file_walk) + * can't trust directory_walk/file_walk since these are + * not in our filesystem. Prevents mod_http from serving + * the TRACE request we will set aside to handle later. + * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy: + * fix_ups: convert the URL stored in the filename to the + * canonical form. + * handler: handle proxy requests + */ + +/* -------------------------------------------------------------- */ +/* Translate the URL into a 'filename' */ + +#define PROXY_COPY_CONF_PARAMS(w, c) \ + do { \ + (w)->timeout = (c)->timeout; \ + (w)->timeout_set = (c)->timeout_set; \ + (w)->recv_buffer_size = (c)->recv_buffer_size; \ + (w)->recv_buffer_size_set = (c)->recv_buffer_size_set; \ + (w)->io_buffer_size = (c)->io_buffer_size; \ + (w)->io_buffer_size_set = (c)->io_buffer_size_set; \ + } while (0) + +static const char *set_worker_param(apr_pool_t *p, + proxy_worker *worker, + const char *key, + const char *val) +{ + + int ival; + if (!strcasecmp(key, "loadfactor")) { + /* Normalized load factor. Used with BalancerMamber, + * it is a number between 1 and 100. + */ + worker->lbfactor = atoi(val); + if (worker->lbfactor < 1 || worker->lbfactor > 100) + return "LoadFactor must be number between 1..100"; + } + else if (!strcasecmp(key, "retry")) { + /* If set it will give the retry timeout for the worker + * The default value is 60 seconds, meaning that if + * in error state, it will be retried after that timeout. + */ + ival = atoi(val); + if (ival < 1) + return "Retry must be at least one second"; + worker->retry = apr_time_from_sec(ival); + } + else if (!strcasecmp(key, "ttl")) { + /* Time in seconds that will destroy all the connections + * that exced the smax + */ + ival = atoi(val); + if (ival < 1) + return "TTL must be at least one second"; + worker->ttl = apr_time_from_sec(ival); + } + else if (!strcasecmp(key, "min")) { + /* Initial number of connections to remote + */ + ival = atoi(val); + if (ival < 0) + return "Min must be a positive number"; + worker->min = ival; + } + else if (!strcasecmp(key, "max")) { + /* Maximum number of connections to remote + */ + ival = atoi(val); + if (ival < 0) + return "Max must be a positive number"; + worker->hmax = ival; + } + /* XXX: More inteligent naming needed */ + else if (!strcasecmp(key, "smax")) { + /* Maximum number of connections to remote that + * will not be destroyed + */ + ival = atoi(val); + if (ival < 0) + return "Smax must be a positive number"; + worker->smax = ival; + } + else if (!strcasecmp(key, "acquire")) { + /* Acquire timeout in milliseconds. + * If set this will be the maximum time to + * wait for a free connection. + */ + ival = atoi(val); + if (ival < 1) + return "Acquire must be at least one mili second"; + worker->acquire = apr_time_make(0, ival * 1000); + worker->acquire_set = 1; + } + else if (!strcasecmp(key, "timeout")) { + /* Connection timeout in seconds. + * Defaults to server timeout. + */ + ival = atoi(val); + if (ival < 1) + return "Timeout must be at least one second"; + worker->timeout = apr_time_from_sec(ival); + worker->timeout_set = 1; + } + else if (!strcasecmp(key, "iobuffersize")) { + long s = atol(val); + worker->io_buffer_size = ((s > AP_IOBUFSIZE) ? s : AP_IOBUFSIZE); + worker->io_buffer_size_set = 1; + } + else if (!strcasecmp(key, "receivebuffersize")) { + ival = atoi(val); + if (ival < 512 && ival != 0) { + return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default."; + } + worker->recv_buffer_size = ival; + worker->recv_buffer_size_set = 1; + } + else if (!strcasecmp(key, "keepalive")) { + if (!strcasecmp(val, "on")) + worker->keepalive = 1; + else if (!strcasecmp(val, "off")) + worker->keepalive = 0; + else + return "KeepAlive must be On|Off"; + worker->keepalive_set = 1; + } + else if (!strcasecmp(key, "route")) { + /* Worker route. + */ + if (strlen(val) > PROXY_WORKER_MAX_ROUTE_SIZ) + return "Route length must be < 64 characters"; + worker->route = apr_pstrdup(p, val); + } + else if (!strcasecmp(key, "redirect")) { + /* Worker redirection route. + */ + if (strlen(val) > PROXY_WORKER_MAX_ROUTE_SIZ) + return "Redirect length must be < 64 characters"; + worker->redirect = apr_pstrdup(p, val); + } + else { + return "unknown Worker parameter"; + } + return NULL; +} + +static const char *set_balancer_param(apr_pool_t *p, + proxy_balancer *balancer, + const char *key, + const char *val) +{ + + int ival; + if (!strcasecmp(key, "stickysession")) { + /* Balancer sticky session name. + * Set to something like JSESSIONID or + * PHPSESSIONID, etc.., + */ + balancer->sticky = apr_pstrdup(p, val); + } + else if (!strcasecmp(key, "nofailover")) { + /* If set to 'on' the session will break + * if the worker is in error state or + * disabled. + */ + if (!strcasecmp(val, "on")) + balancer->sticky_force = 1; + else if (!strcasecmp(val, "off")) + balancer->sticky_force = 0; + else + return "failover must be On|Off"; + } + else if (!strcasecmp(key, "timeout")) { + /* Balancer timeout in seconds. + * If set this will be the maximum time to + * wait for a free worker. + * Default is not to wait. + */ + ival = atoi(val); + if (ival < 1) + return "timeout must be at least one second"; + balancer->timeout = apr_time_from_sec(ival); + } + else if (!strcasecmp(key, "maxattempts")) { + /* Maximum number of failover attempts before + * giving up. + */ + ival = atoi(val); + if (ival < 0) + return "maximum number of attempts must be a positive number"; + balancer->max_attempts = ival; + balancer->max_attempts_set = 1; + } + else if (!strcasecmp(key, "lbmethod")) { + /* Which LB scheduler method */ + if (!strcasecmp(val, "traffic")) + balancer->lbmethod = lbmethod_traffic; + else if (!strcasecmp(val, "requests")) + balancer->lbmethod = lbmethod_requests; + else + return "lbmethod must be Traffic|Requests"; + } + else { + return "unknown Balancer parameter"; + } + return NULL; +} + +static int alias_match(const char *uri, const char *alias_fakename) +{ + const char *end_fakename = alias_fakename + strlen(alias_fakename); + const char *aliasp = alias_fakename, *urip = uri; + const char *end_uri = uri + strlen(uri); + + while (aliasp < end_fakename && urip < end_uri) { + if (*aliasp == '/') { + /* any number of '/' in the alias matches any number in + * the supplied URI, but there must be at least one... + */ + if (*urip != '/') + return 0; + + while (*aliasp == '/') + ++aliasp; + while (*urip == '/') + ++urip; + } + else { + /* Other characters are compared literally */ + if (*urip++ != *aliasp++) + return 0; + } + } + + /* fixup badly encoded stuff (e.g. % as last character) */ + if (aliasp > end_fakename) { + aliasp = end_fakename; + } + if (urip > end_uri) { + urip = end_uri; + } + + /* We reach the end of the uri before the end of "alias_fakename" + * for example uri is "/" and alias_fakename "/examples" + */ + if (urip == end_uri && aliasp!=end_fakename) { + return 0; + } + + /* Check last alias path component matched all the way */ + if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/') + return 0; + + /* Return number of characters from URI which matched (may be + * greater than length of alias, since we may have matched + * doubled slashes) + */ + + return urip - uri; +} + +/* Detect if an absoluteURI should be proxied or not. Note that we + * have to do this during this phase because later phases are + * "short-circuiting"... i.e. translate_names will end when the first + * module returns OK. So for example, if the request is something like: + * + * GET http://othervhost/cgi-bin/printenv HTTP/1.0 + * + * mod_alias will notice the /cgi-bin part and ScriptAlias it and + * short-circuit the proxy... just because of the ordering in the + * configuration file. + */ +static int proxy_detect(request_rec *r) +{ + void *sconf = r->server->module_config; + proxy_server_conf *conf = + (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + + /* Ick... msvc (perhaps others) promotes ternary short results to int */ + + if (conf->req && r->parsed_uri.scheme) { + /* but it might be something vhosted */ + if (!(r->parsed_uri.hostname + && !strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r)) + && ap_matches_request_vhost(r, r->parsed_uri.hostname, + (apr_port_t)(r->parsed_uri.port_str ? r->parsed_uri.port + : ap_default_port(r))))) { + r->proxyreq = PROXYREQ_PROXY; + r->uri = r->unparsed_uri; + r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); + r->handler = "proxy-server"; + } + } + /* We need special treatment for CONNECT proxying: it has no scheme part */ + else if (conf->req && r->method_number == M_CONNECT + && r->parsed_uri.hostname + && r->parsed_uri.port_str) { + r->proxyreq = PROXYREQ_PROXY; + r->uri = r->unparsed_uri; + r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); + r->handler = "proxy-server"; + } + return DECLINED; +} + +static int proxy_trans(request_rec *r) +{ + void *sconf = r->server->module_config; + proxy_server_conf *conf = + (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + int i, len; + struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts; + + if (r->proxyreq) { + /* someone has already set up the proxy, it was possibly ourselves + * in proxy_detect + */ + return OK; + } + + /* XXX: since r->uri has been manipulated already we're not really + * compliant with RFC1945 at this point. But this probably isn't + * an issue because this is a hybrid proxy/origin server. + */ + + for (i = 0; i < conf->aliases->nelts; i++) { + len = alias_match(r->uri, ent[i].fake); + + if (len > 0) { + if ((ent[i].real[0] == '!') && (ent[i].real[1] == 0)) { + return DECLINED; + } + + r->filename = apr_pstrcat(r->pool, "proxy:", ent[i].real, + r->uri + len, NULL); + r->handler = "proxy-server"; + r->proxyreq = PROXYREQ_REVERSE; + return OK; + } + } + return DECLINED; +} + +static int proxy_walk(request_rec *r) +{ + proxy_server_conf *sconf = ap_get_module_config(r->server->module_config, + &proxy_module); + ap_conf_vector_t *per_dir_defaults = r->server->lookup_defaults; + ap_conf_vector_t **sec_proxy = (ap_conf_vector_t **) sconf->sec_proxy->elts; + ap_conf_vector_t *entry_config; + proxy_dir_conf *entry_proxy; + int num_sec = sconf->sec_proxy->nelts; + /* XXX: shouldn't we use URI here? Canonicalize it first? + * Pass over "proxy:" prefix + */ + const char *proxyname = r->filename + 6; + int j; + + for (j = 0; j < num_sec; ++j) + { + entry_config = sec_proxy[j]; + entry_proxy = ap_get_module_config(entry_config, &proxy_module); + + /* XXX: What about case insensitive matching ??? + * Compare regex, fnmatch or string as appropriate + * If the entry doesn't relate, then continue + */ + if (entry_proxy->r + ? ap_regexec(entry_proxy->r, proxyname, 0, NULL, 0) + : (entry_proxy->p_is_fnmatch + ? apr_fnmatch(entry_proxy->p, proxyname, 0) + : strncmp(proxyname, entry_proxy->p, + strlen(entry_proxy->p)))) { + continue; + } + per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults, + entry_config); + } + + r->per_dir_config = per_dir_defaults; + + return OK; +} + +static int proxy_map_location(request_rec *r) +{ + int access_status; + + if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) + return DECLINED; + + /* Don't let the core or mod_http map_to_storage hooks handle this, + * We don't need directory/file_walk, and we want to TRACE on our own. + */ + if ((access_status = proxy_walk(r))) { + ap_die(access_status, r); + return access_status; + } + + return OK; +} +/* -------------------------------------------------------------- */ +/* Fixup the filename */ + +/* + * Canonicalise the URL + */ +static int proxy_fixup(request_rec *r) +{ + char *url, *p; + int access_status; + + if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) + return DECLINED; + + /* XXX: Shouldn't we try this before we run the proxy_walk? */ + url = &r->filename[6]; + + /* canonicalise each specific scheme */ + if ((access_status = proxy_run_canon_handler(r, url))) { + return access_status; + } + + p = strchr(url, ':'); + if (p == NULL || p == url) + return HTTP_BAD_REQUEST; + + return OK; /* otherwise; we've done the best we can */ +} +/* Send a redirection if the request contains a hostname which is not */ +/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ +/* servers like Netscape's allow this and access hosts from the local */ +/* domain in this case. I think it is better to redirect to a FQDN, since */ +/* these will later be found in the bookmarks files. */ +/* The "ProxyDomain" directive determines what domain will be appended */ +static int proxy_needsdomain(request_rec *r, const char *url, const char *domain) +{ + char *nuri; + const char *ref; + + /* We only want to worry about GETs */ + if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname) + return DECLINED; + + /* If host does contain a dot already, or it is "localhost", decline */ + if (strchr(r->parsed_uri.hostname, '.') != NULL + || strcasecmp(r->parsed_uri.hostname, "localhost") == 0) + return DECLINED; /* host name has a dot already */ + + ref = apr_table_get(r->headers_in, "Referer"); + + /* Reassemble the request, but insert the domain after the host name */ + /* Note that the domain name always starts with a dot */ + r->parsed_uri.hostname = apr_pstrcat(r->pool, r->parsed_uri.hostname, + domain, NULL); + nuri = apr_uri_unparse(r->pool, + &r->parsed_uri, + APR_URI_UNP_REVEALPASSWORD); + + apr_table_set(r->headers_out, "Location", nuri); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "Domain missing: %s sent to %s%s%s", r->uri, + apr_uri_unparse(r->pool, &r->parsed_uri, + APR_URI_UNP_OMITUSERINFO), + ref ? " from " : "", ref ? ref : ""); + + return HTTP_MOVED_PERMANENTLY; +} + +/* -------------------------------------------------------------- */ +/* Invoke handler */ + +static int proxy_handler(request_rec *r) +{ + char *uri, *scheme, *p; + const char *p2; + void *sconf = r->server->module_config; + proxy_server_conf *conf = (proxy_server_conf *) + ap_get_module_config(sconf, &proxy_module); + apr_array_header_t *proxies = conf->proxies; + struct proxy_remote *ents = (struct proxy_remote *) proxies->elts; + int i, rc, access_status; + int direct_connect = 0; + const char *str; + long maxfwd; + proxy_balancer *balancer = NULL; + proxy_worker *worker = NULL; + int attempts = 0, max_attempts = 0; + struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts; + + /* is this for us? */ + if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) + return DECLINED; + + /* handle max-forwards / OPTIONS / TRACE */ + if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) { + maxfwd = strtol(str, NULL, 10); + if (maxfwd < 1) { + switch (r->method_number) { + case M_TRACE: { + int access_status; + r->proxyreq = PROXYREQ_NONE; + if ((access_status = ap_send_http_trace(r))) + ap_die(access_status, r); + else + ap_finalize_request_protocol(r); + return OK; + } + case M_OPTIONS: { + int access_status; + r->proxyreq = PROXYREQ_NONE; + if ((access_status = ap_send_http_options(r))) + ap_die(access_status, r); + else + ap_finalize_request_protocol(r); + return OK; + } + default: { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Max-Forwards has reached zero - proxy loop?"); + } + } + } + maxfwd = (maxfwd > 0) ? maxfwd - 1 : 0; + } + else { + /* set configured max-forwards */ + maxfwd = conf->maxfwd; + } + apr_table_set(r->headers_in, "Max-Forwards", + apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd : 0)); + + uri = r->filename + 6; + p = strchr(uri, ':'); + if (p == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy_handler no URL in %s", r->filename); + return HTTP_BAD_REQUEST; + } + + /* If the host doesn't have a domain name, add one and redirect. */ + if (conf->domain != NULL) { + rc = proxy_needsdomain(r, uri, conf->domain); + if (ap_is_HTTP_REDIRECT(rc)) + return HTTP_MOVED_PERMANENTLY; + } + + scheme = apr_pstrndup(r->pool, uri, p - uri); + /* Check URI's destination host against NoProxy hosts */ + /* Bypass ProxyRemote server lookup if configured as NoProxy */ + for (direct_connect = i = 0; i < conf->dirconn->nelts && + !direct_connect; i++) { + direct_connect = list[i].matcher(&list[i], r); + } +#if DEBUGGING + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + (direct_connect) ? "NoProxy for %s" : "UseProxy for %s", + r->uri); +#endif + + do { + char *url = uri; + /* Try to obtain the most suitable worker */ + access_status = ap_proxy_pre_request(&worker, &balancer, r, conf, &url); + if (access_status != OK) + return access_status; + if (balancer && balancer->max_attempts_set && !max_attempts) + max_attempts = balancer->max_attempts; + /* firstly, try a proxy, unless a NoProxy directive is active */ + if (!direct_connect) { + for (i = 0; i < proxies->nelts; i++) { + p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */ + if (strcmp(ents[i].scheme, "*") == 0 || + (ents[i].use_regex && + ap_regexec(ents[i].regexp, url, 0, NULL, 0) == 0) || + (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) || + (p2 != NULL && + strncasecmp(url, ents[i].scheme, + strlen(ents[i].scheme)) == 0)) { + + /* handle the scheme */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Trying to run scheme_handler against proxy"); + access_status = proxy_run_scheme_handler(r, worker, + conf, url, + ents[i].hostname, + ents[i].port); + + /* an error or success */ + if (access_status != DECLINED && + access_status != HTTP_BAD_GATEWAY) { + goto cleanup; + } + /* we failed to talk to the upstream proxy */ + } + } + } + + /* otherwise, try it direct */ + /* N.B. what if we're behind a firewall, where we must use a proxy or + * give up?? + */ + + /* handle the scheme */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Running scheme %s handler (attempt %d)", + scheme, attempts); + access_status = proxy_run_scheme_handler(r, worker, conf, + url, NULL, 0); + if (access_status == OK) + break; + else if (access_status == HTTP_INTERNAL_SERVER_ERROR) { + /* Unrecoverable server error. + * We can not failover to another worker. + * Mark the worker as unusable if member of load balancer + */ + if (balancer) + worker->s->status |= PROXY_WORKER_IN_ERROR; + break; + } + else if (access_status == HTTP_SERVICE_UNAVAILABLE) { + /* Recoverable server error. + * We can failover to another worker + * Mark the worker as unusable if member of load balancer + */ + if (balancer) { + worker->s->status |= PROXY_WORKER_IN_ERROR; + } + } + else { + /* Unrecoverable error. + * Return the origin status code to the client. + */ + break; + } + /* Try again if the worker is unusable and the service is + * unavailable. + */ + } while (!PROXY_WORKER_IS_USABLE(worker) && + max_attempts > attempts++); + + if (DECLINED == access_status) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: No protocol handler was valid for the URL %s. " + "If you are using a DSO version of mod_proxy, make sure " + "the proxy submodules are included in the configuration " + "using LoadModule.", r->uri); + access_status = HTTP_FORBIDDEN; + goto cleanup; + } +cleanup: + if (balancer) { + int post_status = proxy_run_post_request(worker, balancer, r, conf); + if (post_status == DECLINED) { + post_status = OK; /* no post_request handler available */ + /* TODO: reclycle direct worker */ + } + } + return access_status; +} + +/* -------------------------------------------------------------- */ +/* Setup configurable data */ + +static void * create_proxy_config(apr_pool_t *p, server_rec *s) +{ + proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); + + ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *)); + ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote)); + ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); + ps->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); + ps->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias)); + ps->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias)); + ps->cookie_path_str = apr_strmatch_precompile(p, "path=", 0); + ps->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0); + ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry)); + ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry)); + ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int)); + ps->workers = apr_array_make(p, 10, sizeof(proxy_worker)); + ps->balancers = apr_array_make(p, 10, sizeof(proxy_balancer)); + ps->forward = NULL; + ps->reverse = NULL; + ps->domain = NULL; + ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ + ps->viaopt_set = 0; /* 0 means default */ + ps->req = 0; + ps->req_set = 0; + ps->recv_buffer_size = 0; /* this default was left unset for some reason */ + ps->recv_buffer_size_set = 0; + ps->io_buffer_size = AP_IOBUFSIZE; + ps->io_buffer_size_set = 0; + ps->maxfwd = DEFAULT_MAX_FORWARDS; + ps->maxfwd_set = 0; + ps->error_override = 0; + ps->error_override_set = 0; + ps->preserve_host_set = 0; + ps->preserve_host = 0; + ps->timeout = 0; + ps->timeout_set = 0; + ps->badopt = bad_error; + ps->badopt_set = 0; + ps->pool = p; + return ps; +} + +static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) +{ + proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); + proxy_server_conf *base = (proxy_server_conf *) basev; + proxy_server_conf *overrides = (proxy_server_conf *) overridesv; + + ps->proxies = apr_array_append(p, base->proxies, overrides->proxies); + ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy); + ps->aliases = apr_array_append(p, base->aliases, overrides->aliases); + ps->raliases = apr_array_append(p, base->raliases, overrides->raliases); + ps->cookie_paths + = apr_array_append(p, base->cookie_paths, overrides->cookie_paths); + ps->cookie_domains + = apr_array_append(p, base->cookie_domains, overrides->cookie_domains); + ps->cookie_path_str = base->cookie_path_str; + ps->cookie_domain_str = base->cookie_domain_str; + ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies); + ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn); + ps->allowed_connect_ports = apr_array_append(p, base->allowed_connect_ports, overrides->allowed_connect_ports); + ps->workers = apr_array_append(p, base->workers, overrides->workers); + ps->balancers = apr_array_append(p, base->balancers, overrides->balancers); + ps->forward = overrides->forward ? overrides->forward : base->forward; + ps->reverse = overrides->reverse ? overrides->reverse : base->reverse; + + ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain; + ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt; + ps->req = (overrides->req_set == 0) ? base->req : overrides->req; + ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size; + ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size; + ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd; + ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override; + ps->preserve_host = (overrides->preserve_host_set == 0) ? base->preserve_host : overrides->preserve_host; + ps->timeout= (overrides->timeout_set == 0) ? base->timeout : overrides->timeout; + ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt; + ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status; + ps->pool = p; + return ps; +} + +static void *create_proxy_dir_config(apr_pool_t *p, char *dummy) +{ + proxy_dir_conf *new = + (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); + + /* Filled in by proxysection, when applicable */ + + return (void *) new; +} + +static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv) +{ + proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); + proxy_dir_conf *add = (proxy_dir_conf *) addv; + + new->p = add->p; + new->p_is_fnmatch = add->p_is_fnmatch; + new->r = add->r; + return new; +} + + +static const char * + add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf = + (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); + struct proxy_remote *new; + char *p, *q; + char *r, *f, *scheme; + ap_regex_t *reg = NULL; + int port; + + r = apr_pstrdup(cmd->pool, r1); + scheme = apr_pstrdup(cmd->pool, r1); + f = apr_pstrdup(cmd->pool, f1); + p = strchr(r, ':'); + if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { + if (regex) + return "ProxyRemoteMatch: Bad syntax for a remote proxy server"; + else + return "ProxyRemote: Bad syntax for a remote proxy server"; + } + else { + scheme[p-r] = 0; + } + q = strchr(p + 3, ':'); + if (q != NULL) { + if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { + if (regex) + return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)"; + else + return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)"; + } + *q = '\0'; + } + else + port = -1; + *p = '\0'; + if (regex) { + reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); + if (!reg) + return "Regular expression for ProxyRemoteMatch could not be compiled."; + } + else + if (strchr(f, ':') == NULL) + ap_str_tolower(f); /* lowercase scheme */ + ap_str_tolower(p + 3); /* lowercase hostname */ + + if (port == -1) { + port = apr_uri_port_of_scheme(scheme); + } + + new = apr_array_push(conf->proxies); + new->scheme = f; + new->protocol = r; + new->hostname = p + 3; + new->port = port; + new->regexp = reg; + new->use_regex = regex; + return NULL; +} + +static const char * + add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) +{ + return add_proxy(cmd, dummy, f1, r1, 0); +} + +static const char * + add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) +{ + return add_proxy(cmd, dummy, f1, r1, 1); +} + +static const char * + add_pass(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf = + (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); + struct proxy_alias *new; + char *f = cmd->path; + char *r = NULL; + char *word; + apr_table_t *params = apr_table_make(cmd->pool, 5); + const apr_array_header_t *arr; + const apr_table_entry_t *elts; + int i; + + while (*arg) { + word = ap_getword_conf(cmd->pool, &arg); + if (!f) + f = word; + else if (!r) + r = word; + else { + char *val = strchr(word, '='); + if (!val) { + if (cmd->path) + return "Invalid ProxyPass parameter. Parameter must be " + "in the form 'key=value'"; + else + return "ProxyPass can not have a path when defined in a location"; + } + else + *val++ = '\0'; + apr_table_setn(params, word, val); + } + }; + + if (r == NULL) + return "ProxyPass needs a path when not defined in a location"; + + new = apr_array_push(conf->aliases); + new->fake = apr_pstrdup(cmd->pool, f); + new->real = apr_pstrdup(cmd->pool, r); + if (r[0] == '!' && r[1] == '\0') + return NULL; + + arr = apr_table_elts(params); + elts = (const apr_table_entry_t *)arr->elts; + /* Distinguish the balancer from woker */ + if (strncasecmp(r, "balancer:", 9) == 0) { + proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r); + if (!balancer) { + const char *err = ap_proxy_add_balancer(&balancer, + cmd->pool, + conf, r); + if (err) + return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); + } + for (i = 0; i < arr->nelts; i++) { + const char *err = set_balancer_param(cmd->pool, balancer, elts[i].key, + elts[i].val); + if (err) + return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); + } + } + else { + proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, conf, r); + if (!worker) { + const char *err = ap_proxy_add_worker(&worker, cmd->pool, conf, r); + if (err) + return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); + } + PROXY_COPY_CONF_PARAMS(worker, conf); + + for (i = 0; i < arr->nelts; i++) { + const char *err = set_worker_param(cmd->pool, worker, elts[i].key, + elts[i].val); + if (err) + return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); + } + } + return NULL; +} + +static const char * + add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf; + struct proxy_alias *new; + + conf = (proxy_server_conf *)ap_get_module_config(s->module_config, + &proxy_module); + if (r!=NULL && cmd->path == NULL ) { + new = apr_array_push(conf->raliases); + new->fake = f; + new->real = r; + } else if (r==NULL && cmd->path != NULL) { + new = apr_array_push(conf->raliases); + new->fake = cmd->path; + new->real = f; + } else { + if ( r == NULL) + return "ProxyPassReverse needs a path when not defined in a location"; + else + return "ProxyPassReverse can not have a path when defined in a location"; + } + + return NULL; +} +static const char* + cookie_path(cmd_parms *cmd, void *dummy, const char *f, const char *r) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf; + struct proxy_alias *new; + + conf = (proxy_server_conf *)ap_get_module_config(s->module_config, + &proxy_module); + new = apr_array_push(conf->cookie_paths); + new->fake = f; + new->real = r; + + return NULL; +} +static const char* + cookie_domain(cmd_parms *cmd, void *dummy, const char *f, const char *r) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf; + struct proxy_alias *new; + + conf = (proxy_server_conf *)ap_get_module_config(s->module_config, + &proxy_module); + new = apr_array_push(conf->cookie_domains); + new->fake = f; + new->real = r; + + return NULL; +} + +static const char * + set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg) +{ + server_rec *s = parms->server; + proxy_server_conf *conf = + ap_get_module_config(s->module_config, &proxy_module); + struct noproxy_entry *new; + struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts; + struct apr_sockaddr_t *addr; + int found = 0; + int i; + + /* Don't duplicate entries */ + for (i = 0; i < conf->noproxies->nelts; i++) { + if (apr_strnatcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */ + found = 1; + } + } + + if (!found) { + new = apr_array_push(conf->noproxies); + new->name = arg; + if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) { + new->addr = addr; + } + else { + new->addr = NULL; + } + } + return NULL; +} + +/* + * Set the ports CONNECT can use + */ +static const char * + set_allowed_ports(cmd_parms *parms, void *dummy, const char *arg) +{ + server_rec *s = parms->server; + proxy_server_conf *conf = + ap_get_module_config(s->module_config, &proxy_module); + int *New; + + if (!apr_isdigit(arg[0])) + return "AllowCONNECT: port number must be numeric"; + + New = apr_array_push(conf->allowed_connect_ports); + *New = atoi(arg); + return NULL; +} + +/* Similar to set_proxy_exclude(), but defining directly connected hosts, + * which should never be accessed via the configured ProxyRemote servers + */ +static const char * + set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg) +{ + server_rec *s = parms->server; + proxy_server_conf *conf = + ap_get_module_config(s->module_config, &proxy_module); + struct dirconn_entry *New; + struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; + int found = 0; + int i; + + /* Don't duplicate entries */ + for (i = 0; i < conf->dirconn->nelts; i++) { + if (strcasecmp(arg, list[i].name) == 0) + found = 1; + } + + if (!found) { + New = apr_array_push(conf->dirconn); + New->name = apr_pstrdup(parms->pool, arg); + New->hostaddr = NULL; + + if (ap_proxy_is_ipaddr(New, parms->pool)) { +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Parsed addr %s", inet_ntoa(New->addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Parsed mask %s", inet_ntoa(New->mask)); +#endif + } + else if (ap_proxy_is_domainname(New, parms->pool)) { + ap_str_tolower(New->name); +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Parsed domain %s", New->name); +#endif + } + else if (ap_proxy_is_hostname(New, parms->pool)) { + ap_str_tolower(New->name); +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Parsed host %s", New->name); +#endif + } + else { + ap_proxy_is_word(New, parms->pool); +#if DEBUGGING + fprintf(stderr, "Parsed word %s\n", New->name); +#endif + } + } + return NULL; +} + +static const char * + set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + if (arg[0] != '.') + return "ProxyDomain: domain name must start with a dot."; + + psf->domain = arg; + return NULL; +} + +static const char * + set_proxy_req(cmd_parms *parms, void *dummy, int flag) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + psf->req = flag; + psf->req_set = 1; + + if (flag && !psf->forward) { + psf->forward = ap_proxy_create_worker(parms->pool); + psf->forward->name = "proxy:forward"; + psf->forward->hostname = "*"; + psf->forward->scheme = "*"; + } + return NULL; +} + +static const char * + set_proxy_error_override(cmd_parms *parms, void *dummy, int flag) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + psf->error_override = flag; + psf->error_override_set = 1; + return NULL; +} +static const char * + set_preserve_host(cmd_parms *parms, void *dummy, int flag) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + psf->preserve_host = flag; + psf->preserve_host_set = 1; + return NULL; +} + +static const char * + set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + int s = atoi(arg); + if (s < 512 && s != 0) { + return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default."; + } + + psf->recv_buffer_size = s; + psf->recv_buffer_size_set = 1; + return NULL; +} + +static const char * + set_io_buffer_size(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + long s = atol(arg); + + psf->io_buffer_size = ((s > AP_IOBUFSIZE) ? s : AP_IOBUFSIZE); + psf->io_buffer_size_set = 1; + return NULL; +} + +static const char * + set_max_forwards(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + long s = atol(arg); + if (s < 0) { + return "ProxyMaxForwards must be greater or equal to zero.."; + } + + psf->maxfwd = s; + psf->maxfwd_set = 1; + return NULL; +} +static const char* + set_proxy_timeout(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + int timeout; + + timeout=atoi(arg); + if (timeout<1) { + return "Proxy Timeout must be at least 1 second."; + } + psf->timeout_set=1; + psf->timeout=apr_time_from_sec(timeout); + + return NULL; +} + +static const char* + set_via_opt(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + if (strcasecmp(arg, "Off") == 0) + psf->viaopt = via_off; + else if (strcasecmp(arg, "On") == 0) + psf->viaopt = via_on; + else if (strcasecmp(arg, "Block") == 0) + psf->viaopt = via_block; + else if (strcasecmp(arg, "Full") == 0) + psf->viaopt = via_full; + else { + return "ProxyVia must be one of: " + "off | on | full | block"; + } + + psf->viaopt_set = 1; + return NULL; +} + +static const char* + set_bad_opt(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + if (strcasecmp(arg, "IsError") == 0) + psf->badopt = bad_error; + else if (strcasecmp(arg, "Ignore") == 0) + psf->badopt = bad_ignore; + else if (strcasecmp(arg, "StartBody") == 0) + psf->badopt = bad_body; + else { + return "ProxyBadHeader must be one of: " + "IsError | Ignore | StartBody"; + } + + psf->badopt_set = 1; + return NULL; +} + +static const char* + set_status_opt(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + if (strcasecmp(arg, "Off") == 0) + psf->proxy_status = status_off; + else if (strcasecmp(arg, "On") == 0) + psf->proxy_status = status_on; + else if (strcasecmp(arg, "Full") == 0) + psf->proxy_status = status_full; + else { + return "ProxyStatus must be one of: " + "off | on | block"; + } + + psf->proxy_status_set = 1; + return NULL; +} + +static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf = + ap_get_module_config(s->module_config, &proxy_module); + proxy_balancer *balancer; + proxy_worker *worker; + char *path = cmd->path; + char *name = NULL; + char *word; + apr_table_t *params = apr_table_make(cmd->pool, 5); + const apr_array_header_t *arr; + const apr_table_entry_t *elts; + int i; + + if (cmd->path) + path = apr_pstrdup(cmd->pool, cmd->path); + while (*arg) { + word = ap_getword_conf(cmd->pool, &arg); + if (!path) + path = word; + else if (!name) + name = word; + else { + char *val = strchr(word, '='); + if (!val) + if (cmd->path) + return "BalancerMember can not have a balancer name when defined in a location"; + else + return "Invalid BalancerMember parameter. Parameter must " + "be in the form 'key=value'"; + else + *val++ = '\0'; + apr_table_setn(params, word, val); + } + } + if (!path) + return "BalancerMember must define balancer name when outside <Proxy > section"; + if (!name) + return "BalancerMember must define remote proxy server"; + + ap_str_tolower(path); /* lowercase scheme://hostname */ + ap_str_tolower(name); /* lowercase scheme://hostname */ + + /* Try to find existing worker */ + worker = ap_proxy_get_worker(cmd->temp_pool, conf, name); + if (!worker) { + const char *err; + if ((err = ap_proxy_add_worker(&worker, cmd->pool, conf, name)) != NULL) + return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL); + } + PROXY_COPY_CONF_PARAMS(worker, conf); + + arr = apr_table_elts(params); + elts = (const apr_table_entry_t *)arr->elts; + for (i = 0; i < arr->nelts; i++) { + const char *err = set_worker_param(cmd->pool, worker, elts[i].key, + elts[i].val); + if (err) + return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL); + } + /* Try to find the balancer */ + balancer = ap_proxy_get_balancer(cmd->temp_pool, conf, path); + if (!balancer) { + const char *err = ap_proxy_add_balancer(&balancer, + cmd->pool, + conf, path); + if (err) + return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL); + } + /* Add the worker to the load balancer */ + ap_proxy_add_worker_to_balancer(cmd->pool, balancer, worker); + return NULL; +} + +static const char * + set_proxy_param(cmd_parms *cmd, void *dummy, const char *arg) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf = + (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); + char *name = NULL; + char *word, *val; + proxy_balancer *balancer = NULL; + proxy_worker *worker = NULL; + const char *err; + + if (cmd->directive->parent && + strncasecmp(cmd->directive->parent->directive, + "<Proxy", 6) == 0) { + const char *pargs = cmd->directive->parent->args; + /* Directive inside <Proxy section + * Parent directive arg is the worker/balancer name. + */ + name = ap_getword_conf(cmd->temp_pool, &pargs); + if ((word = ap_strchr(name, '>'))) + *word = '\0'; + } + else { + /* Standard set directive with worker/balancer + * name as first param. + */ + name = ap_getword_conf(cmd->temp_pool, &arg); + } + + if (strncasecmp(name, "balancer:", 9) == 0) { + balancer = ap_proxy_get_balancer(cmd->pool, conf, name); + if (!balancer) { + return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '", + name, "' Balancer.", NULL); + } + } + else { + worker = ap_proxy_get_worker(cmd->temp_pool, conf, name); + if (!worker) { + return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '", + name, "' Worker.", NULL); + } + } + + while (*arg) { + word = ap_getword_conf(cmd->pool, &arg); + val = strchr(word, '='); + if (!val) { + return "Invalid ProxySet parameter. Parameter must be " + "in the form 'key=value'"; + } + else + *val++ = '\0'; + if (worker) + err = set_worker_param(cmd->pool, worker, word, val); + else + err = set_balancer_param(cmd->pool, balancer, word, val); + + if (err) + return apr_pstrcat(cmd->temp_pool, "ProxySet ", err, " ", word, " ", name, NULL); + } + + return NULL; +} + +static void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config) +{ + proxy_server_conf *sconf = ap_get_module_config(s->module_config, + &proxy_module); + void **new_space = (void **)apr_array_push(sconf->sec_proxy); + + *new_space = dir_config; +} + +static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg) +{ + const char *errmsg; + const char *endp = ap_strrchr_c(arg, '>'); + int old_overrides = cmd->override; + char *old_path = cmd->path; + proxy_dir_conf *conf; + ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool); + ap_regex_t *r = NULL; + const command_rec *thiscmd = cmd->cmd; + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive missing closing '>'", NULL); + } + + arg=apr_pstrndup(cmd->pool, arg, endp-arg); + + if (!arg) { + if (thiscmd->cmd_data) + return "<ProxyMatch > block must specify a path"; + else + return "<Proxy > block must specify a path"; + } + + cmd->path = ap_getword_conf(cmd->pool, &arg); + cmd->override = OR_ALL|ACCESS_CONF; + + if (!strncasecmp(cmd->path, "proxy:", 6)) + cmd->path += 6; + + /* XXX Ignore case? What if we proxy a case-insensitive server?!? + * While we are at it, shouldn't we also canonicalize the entire + * scheme? See proxy_fixup() + */ + if (thiscmd->cmd_data) { /* <ProxyMatch> */ + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED); + if (!r) { + return "Regex could not be compiled"; + } + } + else if (!strcmp(cmd->path, "~")) { + cmd->path = ap_getword_conf(cmd->pool, &arg); + if (!cmd->path) + return "<Proxy ~ > block must specify a path"; + if (strncasecmp(cmd->path, "proxy:", 6)) + cmd->path += 6; + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED); + if (!r) { + return "Regex could not be compiled"; + } + } + + /* initialize our config and fetch it */ + conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path, + &proxy_module, cmd->pool); + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf); + if (errmsg != NULL) + return errmsg; + + conf->r = r; + conf->p = cmd->path; + conf->p_is_fnmatch = apr_fnmatch_test(conf->p); + + ap_add_per_proxy_conf(cmd->server, new_dir_conf); + + if (*arg != '\0') { + return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, + "> arguments not (yet) supported.", NULL); + } + + cmd->path = old_path; + cmd->override = old_overrides; + + return NULL; +} + +static const command_rec proxy_cmds[] = +{ + AP_INIT_RAW_ARGS("<Proxy", proxysection, NULL, RSRC_CONF, + "Container for directives affecting resources located in the proxied " + "location"), + AP_INIT_RAW_ARGS("<ProxyMatch", proxysection, (void*)1, RSRC_CONF, + "Container for directives affecting resources located in the proxied " + "location, in regular expression syntax"), + AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF, + "on if the true proxy requests should be accepted"), + AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF, + "a scheme, partial URL or '*' and a proxy server"), + AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF, + "a regex pattern and a proxy server"), + AP_INIT_RAW_ARGS("ProxyPass", add_pass, NULL, RSRC_CONF|ACCESS_CONF, + "a virtual path and a URL"), + AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF, + "a virtual path and a URL for reverse proxy behaviour"), + AP_INIT_TAKE2("ProxyPassReverseCookiePath", cookie_path, NULL, + RSRC_CONF|ACCESS_CONF, "Path rewrite rule for proxying cookies"), + AP_INIT_TAKE2("ProxyPassReverseCookieDomain", cookie_domain, NULL, + RSRC_CONF|ACCESS_CONF, "Domain rewrite rule for proxying cookies"), + AP_INIT_ITERATE("ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, + "A list of names, hosts or domains to which the proxy will not connect"), + AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, + "Receive buffer size for outgoing HTTP and FTP connections in bytes"), + AP_INIT_TAKE1("ProxyIOBufferSize", set_io_buffer_size, NULL, RSRC_CONF, + "IO buffer size for outgoing HTTP and FTP connections in bytes"), + AP_INIT_TAKE1("ProxyMaxForwards", set_max_forwards, NULL, RSRC_CONF, + "The maximum number of proxies a request may be forwarded through."), + AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, + "A list of domains, hosts, or subnets to which the proxy will connect directly"), + AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF, + "The default intranet domain name (in absence of a domain in the URL)"), + AP_INIT_ITERATE("AllowCONNECT", set_allowed_ports, NULL, RSRC_CONF, + "A list of ports which CONNECT may connect to"), + AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF, + "Configure Via: proxy header header to one of: on | off | block | full"), + AP_INIT_FLAG("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF, + "use our error handling pages instead of the servers' we are proxying"), + AP_INIT_FLAG("ProxyPreserveHost", set_preserve_host, NULL, RSRC_CONF, + "on if we should preserve host header while proxying"), + AP_INIT_TAKE1("ProxyTimeout", set_proxy_timeout, NULL, RSRC_CONF, + "Set the timeout (in seconds) for a proxied connection. " + "This overrides the server timeout"), + AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF, + "How to handle bad header line in response: IsError | Ignore | StartBody"), + AP_INIT_RAW_ARGS("BalancerMember", add_member, NULL, RSRC_CONF|ACCESS_CONF, + "A balancer name and scheme with list of params"), + AP_INIT_TAKE1("ProxyStatus", set_status_opt, NULL, RSRC_CONF, + "Configure Status: proxy status to one of: on | off | full"), + AP_INIT_RAW_ARGS("ProxySet", set_proxy_param, NULL, RSRC_CONF|ACCESS_CONF, + "A balancer or worker name with list of params"), + {NULL} +}; + +static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable = NULL; +static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable = NULL; +static APR_OPTIONAL_FN_TYPE(ssl_is_https) *proxy_is_https = NULL; +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *proxy_ssl_val = NULL; + +PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c) +{ + /* + * if c == NULL just check if the optional function was imported + * else run the optional function so ssl filters are inserted + */ + if (proxy_ssl_enable) { + return c ? proxy_ssl_enable(c) : 1; + } + + return 0; +} + +PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c) +{ + if (proxy_ssl_disable) { + return proxy_ssl_disable(c); + } + + return 0; +} + +PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c) +{ + if (proxy_is_https) { + return proxy_is_https(c); + } + else + return 0; +} + +PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r, + const char *var) +{ + if (proxy_ssl_val) { + /* XXX Perhaps the casting useless */ + return (const char *)proxy_ssl_val(p, s, c, r, (char *)var); + } + else + return NULL; +} + +static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + + proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable); + proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable); + proxy_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https); + proxy_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); + + return OK; +} + +/* + * proxy Extension to mod_status + */ +static int proxy_status_hook(request_rec *r, int flags) +{ + int i, n; + void *sconf = r->server->module_config; + proxy_server_conf *conf = (proxy_server_conf *) + ap_get_module_config(sconf, &proxy_module); + proxy_balancer *balancer = NULL; + proxy_worker *worker = NULL; + + if (flags & AP_STATUS_SHORT || conf->balancers->nelts == 0 || + conf->proxy_status == status_off) + return OK; + + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++) { + ap_rputs("<hr />\n<h1>Proxy LoadBalancer Status for ", r); + ap_rvputs(r, balancer->name, "</h1>\n\n", NULL); + ap_rputs("\n\n<table border=\"0\"><tr>" + "<th>SSes</th><th>Timeout</th><th>Method</th>" + "</tr>\n<tr>", r); + ap_rvputs(r, "<td>", balancer->sticky, NULL); + ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>", + apr_time_sec(balancer->timeout)); + ap_rprintf(r, "<td>%s</td>\n", + balancer->lbmethod == lbmethod_requests ? "Requests" : + balancer->lbmethod == lbmethod_traffic ? "Traffic" : + "Unknown"); + ap_rputs("</table>\n", r); + ap_rputs("\n\n<table border=\"0\"><tr>" + "<th>Sch</th><th>Host</th><th>Stat</th>" + "<th>Route</th><th>Redir</th>" + "<th>F</th><th>Acc</th><th>Wr</th><th>Rd</th>" + "</tr>\n", r); + + worker = (proxy_worker *)balancer->workers->elts; + for (n = 0; n < balancer->workers->nelts; n++) { + char fbuf[50]; + ap_rvputs(r, "<tr>\n<td>", worker->scheme, "</td>", NULL); + ap_rvputs(r, "<td>", worker->hostname, "</td><td>", NULL); + if (worker->s->status & PROXY_WORKER_DISABLED) + ap_rputs("Dis", r); + else if (worker->s->status & PROXY_WORKER_IN_ERROR) + ap_rputs("Err", r); + else if (worker->s->status & PROXY_WORKER_INITIALIZED) + ap_rputs("Ok", r); + else + ap_rputs("-", r); + ap_rvputs(r, "</td><td>", worker->s->route, NULL); + ap_rvputs(r, "</td><td>", worker->s->redirect, NULL); + ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor); + ap_rprintf(r, "<td>%d</td><td>", (int)(worker->s->elected)); + ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r); + ap_rputs("</td><td>", r); + ap_rputs(apr_strfsize(worker->s->read, fbuf), r); + ap_rputs("</td>\n", r); + + /* TODO: Add the rest of dynamic worker data */ + ap_rputs("</tr>\n", r); + + ++worker; + } + ap_rputs("</table>\n", r); + ++balancer; + } + ap_rputs("<hr /><table>\n" + "<tr><th>SSes</th><td>Sticky session name</td></tr>\n" + "<tr><th>Timeout</th><td>Balancer Timeout</td></tr>\n" + "<tr><th>Sch</th><td>Connection scheme</td></tr>\n" + "<tr><th>Host</th><td>Backend Hostname</td></tr>\n" + "<tr><th>Stat</th><td>Worker status</td></tr>\n" + "<tr><th>Route</th><td>Session Route</td></tr>\n" + "<tr><th>Redir</th><td>Session Route Redirection</td></tr>\n" + "<tr><th>F</th><td>Load Balancer Factor in %</td></tr>\n" + "<tr><th>Acc</th><td>Number of requests</td></tr>\n" + "<tr><th>Wr</th><td>Number of bytes transferred</td></tr>\n" + "<tr><th>Rd</th><td>Number of bytes read</td></tr>\n" + "</table>", r); + + return OK; +} + +static void child_init(apr_pool_t *p, server_rec *s) +{ + proxy_worker *reverse = NULL; + + while (s) { + void *sconf = s->module_config; + proxy_server_conf *conf; + proxy_worker *worker; + int i; + + conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); + /* Initialize worker's shared scoreboard data */ + worker = (proxy_worker *)conf->workers->elts; + for (i = 0; i < conf->workers->nelts; i++) { + ap_proxy_initialize_worker_share(conf, worker, s); + ap_proxy_initialize_worker(worker, s); + worker++; + } + /* Initialize forward worker if defined */ + if (conf->forward) { + ap_proxy_initialize_worker_share(conf, conf->forward, s); + ap_proxy_initialize_worker(conf->forward, s); + /* Do not disable worker in case of errors */ + conf->forward->s->status |= PROXY_WORKER_IGNORE_ERRORS; + /* Disable address cache for generic forward worker */ + conf->forward->is_address_reusable = 0; + } + if (!reverse) { + reverse = ap_proxy_create_worker(p); + reverse->name = "proxy:reverse"; + reverse->hostname = "*"; + reverse->scheme = "*"; + ap_proxy_initialize_worker_share(conf, reverse, s); + ap_proxy_initialize_worker(reverse, s); + /* Do not disable worker in case of errors */ + reverse->s->status |= PROXY_WORKER_IGNORE_ERRORS; + /* Disable address cache for generic reverse worker */ + reverse->is_address_reusable = 0; + } + conf->reverse = reverse; + s = s->next; + } +} + +/* + * This routine is called before the server processes the configuration + * files. There is no return value. + */ +static int proxy_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + APR_OPTIONAL_HOOK(ap, status_hook, proxy_status_hook, NULL, NULL, + APR_HOOK_MIDDLE); + /* Reset workers count on gracefull restart */ + proxy_lb_workers = 0; + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + /* fixup before mod_rewrite, so that the proxied url will not + * escaped accidentally by our fixup. + */ + static const char * const aszSucc[]={ "mod_rewrite.c", NULL }; + /* Only the mpm_winnt has child init hook handler. + * make sure that we are called after the mpm + * initializes. + */ + static const char *const aszPred[] = { "mpm_winnt.c", NULL}; + + APR_REGISTER_OPTIONAL_FN(ap_proxy_lb_workers); + /* handler */ + ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); + /* filename-to-URI translation */ + ap_hook_translate_name(proxy_trans, aszSucc, NULL, APR_HOOK_FIRST); + /* walk <Proxy > entries and suppress default TRACE behavior */ + ap_hook_map_to_storage(proxy_map_location, NULL,NULL, APR_HOOK_FIRST); + /* fixups */ + ap_hook_fixups(proxy_fixup, NULL, aszSucc, APR_HOOK_FIRST); + /* post read_request handling */ + ap_hook_post_read_request(proxy_detect, NULL, NULL, APR_HOOK_FIRST); + /* pre config handling */ + ap_hook_pre_config(proxy_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + /* post config handling */ + ap_hook_post_config(proxy_post_config, NULL, NULL, APR_HOOK_MIDDLE); + /* child init handling */ + ap_hook_child_init(child_init, aszPred, NULL, APR_HOOK_MIDDLE); + +} + +module AP_MODULE_DECLARE_DATA proxy_module = +{ + STANDARD20_MODULE_STUFF, + create_proxy_dir_config, /* create per-directory config structure */ + merge_proxy_dir_config, /* merge per-directory config structures */ + create_proxy_config, /* create per-server config structure */ + merge_proxy_config, /* merge per-server config structures */ + proxy_cmds, /* command table */ + register_hooks +}; + +APR_HOOK_STRUCT( + APR_HOOK_LINK(scheme_handler) + APR_HOOK_LINK(canon_handler) + APR_HOOK_LINK(pre_request) + APR_HOOK_LINK(post_request) +) + +APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler, + (request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, + char *url, const char *proxyhost, + apr_port_t proxyport),(r,worker,conf, + url,proxyhost,proxyport),DECLINED) +APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler, + (request_rec *r, char *url),(r, + url),DECLINED) +APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, pre_request, ( + proxy_worker **worker, + proxy_balancer **balancer, + request_rec *r, + proxy_server_conf *conf, + char **url),(worker,balancer, + r,conf,url),DECLINED) +APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, post_request, + (proxy_worker *worker, + proxy_balancer *balancer, + request_rec *r, + proxy_server_conf *conf),(worker, + balancer,r,conf),DECLINED) +APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups, + (request_rec *r), (r), + OK, DECLINED) diff --git a/trunk/modules/proxy/mod_proxy.dsp b/trunk/modules/proxy/mod_proxy.dsp new file mode 100644 index 0000000000..b684cd6eb2 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy.dsp @@ -0,0 +1,140 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy.mak" CFG="mod_proxy - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Release/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy - Win32 Release" +# Name "mod_proxy - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy.c +# End Source File +# Begin Source File + +SOURCE=.\proxy_util.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy.so "proxy_module for Apache" ../../include/ap_release.h > .\mod_proxy.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy.so "proxy_module for Apache" ../../include/ap_release.h > .\mod_proxy.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/mod_proxy.h b/trunk/modules/proxy/mod_proxy.h new file mode 100644 index 0000000000..8ea9e2b409 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy.h @@ -0,0 +1,656 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_PROXY_H +#define MOD_PROXY_H + +/* + * Main include file for the Apache proxy + */ + +/* + + Also note numerous FIXMEs and CHECKMEs which should be eliminated. + + This code is once again experimental! + + Things to do: + + 1. Make it completely work (for FTP too) + + 2. HTTP/1.1 + + Chuck Murcko <chuck@topsail.org> 02-06-01 + + */ + +#define CORE_PRIVATE + +#include "apr_hooks.h" +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_md5.h" +#include "apr_network_io.h" +#include "apr_pools.h" +#include "apr_strings.h" +#include "apr_uri.h" +#include "apr_date.h" +#include "apr_strmatch.h" +#include "apr_fnmatch.h" +#include "apr_reslist.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "ap_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_main.h" +#include "http_log.h" +#include "http_connection.h" +#include "util_filter.h" +#include "util_ebcdic.h" + +#if APR_HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#if APR_HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif + +/* for proxy_canonenc() */ +enum enctype { + enc_path, enc_search, enc_user, enc_fpath, enc_parm +}; + +#if APR_CHARSET_EBCDIC +#define CRLF "\r\n" +#else /*APR_CHARSET_EBCDIC*/ +#define CRLF "\015\012" +#endif /*APR_CHARSET_EBCDIC*/ + +/* default Max-Forwards header setting */ +#define DEFAULT_MAX_FORWARDS 10 + +/* static information about a remote proxy */ +struct proxy_remote { + const char *scheme; /* the schemes handled by this proxy, or '*' */ + const char *protocol; /* the scheme used to talk to this proxy */ + const char *hostname; /* the hostname of this proxy */ + apr_port_t port; /* the port for this proxy */ + ap_regex_t *regexp; /* compiled regex (if any) for the remote */ + int use_regex; /* simple boolean. True if we have a regex pattern */ +}; + +struct proxy_alias { + const char *real; + const char *fake; +}; + +struct dirconn_entry { + char *name; + struct in_addr addr, mask; + struct apr_sockaddr_t *hostaddr; + int (*matcher) (struct dirconn_entry * This, request_rec *r); +}; + +struct noproxy_entry { + const char *name; + struct apr_sockaddr_t *addr; +}; + +typedef struct proxy_balancer proxy_balancer; +typedef struct proxy_worker proxy_worker; +typedef struct proxy_conn_pool proxy_conn_pool; + +typedef struct { + apr_array_header_t *proxies; + apr_array_header_t *sec_proxy; + apr_array_header_t *aliases; + apr_array_header_t *raliases; + apr_array_header_t *noproxies; + apr_array_header_t *dirconn; + apr_array_header_t *allowed_connect_ports; + apr_array_header_t *workers; + apr_array_header_t *balancers; + proxy_worker *forward; /* forward proxy worker */ + proxy_worker *reverse; /* reverse "module-driven" proxy worker */ + const char *domain; /* domain name to use in absence of a domain name in the request */ + int req; /* true if proxy requests are enabled */ + char req_set; + enum { + via_off, + via_on, + via_block, + via_full + } viaopt; /* how to deal with proxy Via: headers */ + char viaopt_set; + apr_size_t recv_buffer_size; + char recv_buffer_size_set; + apr_size_t io_buffer_size; + char io_buffer_size_set; + long maxfwd; + char maxfwd_set; + /** + * the following setting masks the error page + * returned from the 'proxied server' and just + * forwards the status code upwards. + * This allows the main server (us) to generate + * the error page, (so it will look like a error + * returned from the rest of the system + */ + int error_override; + int error_override_set; + int preserve_host; + int preserve_host_set; + apr_interval_time_t timeout; + char timeout_set; + enum { + bad_error, + bad_ignore, + bad_body + } badopt; /* how to deal with bad headers */ + char badopt_set; +/* putting new stuff on the end maximises binary back-compatibility. + * the strmatch_patterns are really a const just to have a + * case-independent strstr. + */ + apr_array_header_t* cookie_paths; + apr_array_header_t* cookie_domains; + const apr_strmatch_pattern* cookie_path_str; + const apr_strmatch_pattern* cookie_domain_str; + enum { + status_off, + status_on, + status_full + } proxy_status; /* Status display options */ + char proxy_status_set; + apr_pool_t *pool; /* Pool used for allocating this struct */ +} proxy_server_conf; + + +typedef struct { + const char *p; /* The path */ + int p_is_fnmatch; /* Is this path an fnmatch candidate? */ + ap_regex_t *r; /* Is this a regex? */ +} proxy_dir_conf; + +typedef struct { + conn_rec *connection; + const char *hostname; + apr_port_t port; + int is_ssl; + apr_pool_t *pool; /* Subpool used for creating socket */ + apr_socket_t *sock; /* Connection socket */ + apr_sockaddr_t *addr; /* Preparsed remote address info */ + apr_uint32_t flags; /* Conection flags */ + int close; /* Close 'this' connection */ + int close_on_recycle; /* Close the connection when returning to pool */ + proxy_worker *worker; /* Connection pool this connection belogns to */ + void *data; /* per scheme connection data */ +} proxy_conn_rec; + +typedef struct { + float cache_completion; /* completion percentage */ + int content_length; /* length of the content */ +} proxy_completion; + +/* Connection pool */ +struct proxy_conn_pool { + apr_pool_t *pool; /* The pool used in constructor and destructor calls */ + apr_sockaddr_t *addr; /* Preparsed remote address info */ +#if APR_HAS_THREADS + apr_reslist_t *res; /* Connection resource list */ +#endif + proxy_conn_rec *conn; /* Single connection for prefork mpm's */ +}; + +/* woker status flags */ +#define PROXY_WORKER_INITIALIZED 0x0001 +#define PROXY_WORKER_IGNORE_ERRORS 0x0002 +#define PROXY_WORKER_IN_SHUTDOWN 0x0010 +#define PROXY_WORKER_DISABLED 0x0020 +#define PROXY_WORKER_IN_ERROR 0x0040 + +#define PROXY_WORKER_IS_USABLE(f) (!((f)->s->status & 0x00F0)) + +/* default worker retry timeout in seconds */ +#define PROXY_WORKER_DEFAULT_RETRY 60 +#define PROXY_WORKER_MAX_ROUTE_SIZ 63 + +/* Runtime worker status informations. Shared in scoreboard */ +typedef struct { + int status; + apr_time_t error_time; /* time of the last error */ + int retries; /* number of retries on this worker */ + int lbstatus; /* Current lbstatus */ + int lbfactor; /* dynamic lbfactor */ + apr_off_t transferred;/* Number of bytes transferred to remote */ + apr_off_t read; /* Number of bytes read from remote */ + apr_size_t elected; /* Number of times the worker was elected */ + char route[PROXY_WORKER_MAX_ROUTE_SIZ+1]; + char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1]; +} proxy_worker_stat; + +/* Worker configuration */ +struct proxy_worker { + int id; /* scoreboard id */ + apr_interval_time_t retry; /* retry interval */ + int lbfactor; /* initial load balancing factor */ + const char *name; + const char *scheme; /* scheme to use ajp|http|https */ + const char *hostname; /* remote backend address */ + const char *route; /* balancing route */ + const char *redirect; /* temporary balancing redirection route */ + apr_port_t port; + int min; /* Desired minimum number of available connections */ + int smax; /* Soft maximum on the total number of connections */ + int hmax; /* Hard maximum on the total number of connections */ + apr_interval_time_t ttl; /* maximum amount of time in seconds a connection + * may be available while exceeding the soft limit */ + apr_interval_time_t timeout; /* connection timeout */ + char timeout_set; + apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */ + char acquire_set; + apr_size_t recv_buffer_size; + char recv_buffer_size_set; + apr_size_t io_buffer_size; + char io_buffer_size_set; + char keepalive; + char keepalive_set; + proxy_conn_pool *cp; /* Connection pool to use */ + proxy_worker_stat *s; /* Shared data */ + void *opaque; /* per scheme worker data */ + int is_address_reusable; +#if APR_HAS_THREADS + apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */ +#endif +}; + +struct proxy_balancer { + apr_array_header_t *workers; /* array of proxy_workers */ + const char *name; /* name of the load balancer */ + const char *sticky; /* sticky session identifier */ + int sticky_force; /* Disable failover for sticky sessions */ + apr_interval_time_t timeout; /* Timeout for waiting on free connection */ + int max_attempts; /* Number of attempts before failing */ + char max_attempts_set; + enum { + lbmethod_requests = 1, + lbmethod_traffic = 2 + } lbmethod; + + /* XXX: Perhaps we will need the proc mutex too. + * Altrough we are only using arithmetic operations + * it may lead to a incorrect calculations. + * For now use only the thread mutex. + */ +#if APR_HAS_THREADS + apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */ +#endif +}; + +#if APR_HAS_THREADS +#define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex) +#define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex) +#else +#define PROXY_THREAD_LOCK(x) APR_SUCCESS +#define PROXY_THREAD_UNLOCK(x) APR_SUCCESS +#endif + +/* hooks */ + +/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and + * PROXY_DECLARE_DATA with appropriate export and import tags for the platform + */ +#if !defined(WIN32) +#define PROXY_DECLARE(type) type +#define PROXY_DECLARE_NONSTD(type) type +#define PROXY_DECLARE_DATA +#elif defined(PROXY_DECLARE_STATIC) +#define PROXY_DECLARE(type) type __stdcall +#define PROXY_DECLARE_NONSTD(type) type +#define PROXY_DECLARE_DATA +#elif defined(PROXY_DECLARE_EXPORT) +#define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall +#define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type +#define PROXY_DECLARE_DATA __declspec(dllexport) +#else +#define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall +#define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type +#define PROXY_DECLARE_DATA __declspec(dllimport) +#endif + +/** + * Hook an optional proxy hook. Unlike static hooks, this uses a macro + * instead of a function. + */ +#define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \ + APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order) + +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r, + proxy_worker *worker, proxy_server_conf *conf, char *url, + const char *proxyhost, apr_port_t proxyport)) +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r, + char *url)) + +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr)) +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r)) + +/** + * pre request hook. + * It will return the most suitable worker at the moment + * and coresponding balancer. + * The url is rewritten from balancer://cluster/uri to scheme://host:port/uri + * and then the scheme_handler is called. + * + */ +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker, + proxy_balancer **balancer, + request_rec *r, + proxy_server_conf *conf, char **url)) +/** + * post request hook. + * It is called after request for updating runtime balancer status. + */ +APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker, + proxy_balancer *balancer, request_rec *r, + proxy_server_conf *conf)) + + +/* proxy_util.c */ + +PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r); +PROXY_DECLARE(int) ap_proxy_hex2c(const char *x); +PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x); +PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, + int forcedec, int proxyreq); +PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, + char **passwordp, char **hostp, apr_port_t *port); +PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x); +PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val); +PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val); +PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x); +PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y); +PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message); +PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p); +PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p); +PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p); +PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p); +PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr); +PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r); +PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos); +PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key); +/* DEPRECATED (will be replaced with ap_proxy_connect_backend */ +PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, server_rec *, apr_pool_t *); +PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c); +PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c); +PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c); +PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var); + +/* Header mapping functions, and a typedef of their signature */ +PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url); +PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_server_conf *conf, const char *str); + +#if !defined(WIN32) +typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *, + proxy_server_conf *, const char *); +#elif defined(PROXY_DECLARE_STATIC) +typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, + proxy_server_conf *, const char *); +#elif defined(PROXY_DECLARE_EXPORT) +typedef __declspec(dllexport) const char * + (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, + proxy_server_conf *, const char *); +#else +typedef __declspec(dllimport) const char * + (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, + proxy_server_conf *, const char *); +#endif + + +/* Connection pool API */ +/** + * Get the worker from proxy configuration + * @param p memory pool used for finding worker + * @param conf current proxy server configuration + * @param url url to find the worker from + * @return proxy_worker or NULL if not found + */ +PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, + proxy_server_conf *conf, + const char *url); +/** + * Add the worker to proxy configuration + * @param worker the new worker + * @param p memory pool to allocate worker from + * @param conf current proxy server configuration + * @param url url containing worker name + * @return error message or NULL if successfull + */ +PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker, + apr_pool_t *p, + proxy_server_conf *conf, + const char *url); + +/** + * Create new worker + * @param p memory pool to allocate worker from + * @return new worker + */ +PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p); + +/** + * Initize the worker's shared data + * @param conf current proxy server configuration + * @param worker worker to initialize + * @param s current server record + * @param worker worker to initialize + */ +PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, + proxy_worker *worker, + server_rec *s); + + +/** + * Initize the worker + * @param worker worker to initialize + * @param s current server record + * @return APR_SUCCESS or error code + */ +PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, + server_rec *s); +/** + * Get the balancer from proxy configuration + * @param p memory pool used for finding balancer + * @param conf current proxy server configuration + * @param url url to find the worker from. Has to have balancer:// prefix + * @return proxy_balancer or NULL if not found + */ +PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p, + proxy_server_conf *conf, + const char *url); +/** + * Add the balancer to proxy configuration + * @param balancer the new balancer + * @param p memory pool to allocate balancer from + * @param conf current proxy server configuration + * @param url url containing balancer name + * @return error message or NULL if successfull + */ +PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer, + apr_pool_t *p, + proxy_server_conf *conf, + const char *url); + +/** + * Add the worker to the balancer + * @param pool memory pool for adding worker + * @param balancer balancer to add to + * @param balancer worker to add + * @note Single worker can be added to multiple balancers. + */ +PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool, + proxy_balancer *balancer, + proxy_worker *worker); +/** + * Get the most suitable worker and(or) balancer for the request + * @param worker worker used for processing request + * @param balancer balancer used for processing request + * @param r current request + * @param conf current proxy server configuration + * @param url request url that balancer can rewrite. + * @return OK or HTTP_XXX error + * @note It calls balancer pre_request hook if the url starts with balancer:// + * The balancer then rewrites the url to particular worker, like http://host:port + */ +PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, + proxy_balancer **balancer, + request_rec *r, + proxy_server_conf *conf, + char **url); +/** + * Post request worker and balancer cleanup + * @param worker worker used for processing request + * @param balancer balancer used for processing request + * @param r current request + * @param conf current proxy server configuration + * @return OK or HTTP_XXX error + * @note When ever the pre_request is called, the post_request has to be + * called too. + */ +PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker, + proxy_balancer *balancer, + request_rec *r, + proxy_server_conf *conf); +/** + * Deternime backend hostname and port + * @param p memory pool used for processing + * @param r current request + * @param conf current proxy server configuration + * @param worker worker used for processing request + * @param conn proxy connection struct + * @param uri processed uri + * @param url request url + * @param proxyname are we connecting directly or via s proxy + * @param proxyport proxy host port + * @param server_portstr Via headers server port + * @param server_portstr_size size of the server_portstr buffer + * @return OK or HTTP_XXX error + */ +PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + proxy_server_conf *conf, + proxy_worker *worker, + proxy_conn_rec *conn, + apr_uri_t *uri, + char **url, + const char *proxyname, + apr_port_t proxyport, + char *server_portstr, + int server_portstr_size); +/** + * Mark a worker for retry + * @param proxy_function calling proxy scheme (http, ajp, ...) + * @param conf current proxy server configuration + * @param worker worker used for retrying + * @param s current server record + * @return OK if marked for retry, DECLINED otherwise + * @note Worker will be marker for retry if the time of the last retry + * has been ellapsed. In case there is no retry option set, defaults to + * number_of_retries seconds. + */ +PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function, + proxy_worker *worker, + server_rec *s); +/** + * Acquire a connection from workers connection pool + * @param proxy_function calling proxy scheme (http, ajp, ...) + * @param conn acquired connection + * @param worker worker used for obtaining connection + * @param s current server record + * @return OK or HTTP_XXX error + * @note If the number of connections is exhaused the function will + * block untill the timeout is reached. + */ +PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, + proxy_conn_rec **conn, + proxy_worker *worker, + server_rec *s); +/** + * Release a connection back to worker connection pool + * @param proxy_function calling proxy scheme (http, ajp, ...) + * @param conn acquired connection + * @param s current server record + * @return OK or HTTP_XXX error + * @note The connection will be closed if conn->close_on_release is set + */ +PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, + proxy_conn_rec *conn, + server_rec *s); +/** + * Make a connection to the backend + * @param proxy_function calling proxy scheme (http, ajp, ...) + * @param conn acquired connection + * @param worker connection worker + * @param s current server record + * @return OK or HTTP_XXX error + * @note In case the socket already exists for conn, just check the link + * status. + */ +PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + proxy_conn_rec *conn, + proxy_worker *worker, + server_rec *s); +/** + * Make a connection record for backend connection + * @param proxy_function calling proxy scheme (http, ajp, ...) + * @param conn acquired connection + * @param c client connection record + * @param s current server record + * @return OK or HTTP_XXX error + */ +PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, + proxy_conn_rec *conn, + conn_rec *c, server_rec *s); + +/* Scoreboard */ +#if MODULE_MAGIC_NUMBER_MAJOR > 20020903 +#define PROXY_HAS_SCOREBOARD 1 +#else +#define PROXY_HAS_SCOREBOARD 0 +#endif + +/* The number of dynamic workers that can be added when reconfiguring. + * If this limit is reached you must stop and restart the server. + */ +#define PROXY_DYNAMIC_BALANCER_LIMIT 16 +/** + * Calculate number of maximum number of workers in scoreboard. + * @return number of workers to allocate in the scoreboard + */ +int ap_proxy_lb_workers(void); + +/* For proxy_util */ +extern module PROXY_DECLARE_DATA proxy_module; + +extern int PROXY_DECLARE_DATA proxy_lb_workers; + +#endif /*MOD_PROXY_H*/ diff --git a/trunk/modules/proxy/mod_proxy_ajp.c b/trunk/modules/proxy/mod_proxy_ajp.c new file mode 100644 index 0000000000..e0f4ecfbc3 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_ajp.c @@ -0,0 +1,469 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* AJP routines for Apache proxy */ + +#include "mod_proxy.h" +#include "ajp.h" + +module AP_MODULE_DECLARE_DATA proxy_ajp_module; +/* + * Canonicalise http-like URLs. + * scheme is the scheme for the URL + * url is the URL starting with the first '/' + * def_port is the default port for this scheme. + */ +static int proxy_ajp_canon(request_rec *r, char *url) +{ + char *host, *path, *search, sport[7]; + const char *err; + apr_port_t port = AJP13_DEF_PORT; + + /* ap_port_of_scheme() */ + if (strncasecmp(url, "ajp:", 4) == 0) { + url += 4; + } + else { + return DECLINED; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: AJP: canonicalising URL %s", url); + + /* do syntatic check. + * We break the URL into host, port, path, search + */ + err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); + if (err) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "error parsing URL %s: %s", + url, err); + return HTTP_BAD_REQUEST; + } + + /* now parse path/search args, according to rfc1738 */ + /* N.B. if this isn't a true proxy request, then the URL _path_ + * has already been decoded. True proxy requests have r->uri + * == r->unparsed_uri, and no others have that property. + */ + if (r->uri == r->unparsed_uri) { + search = strchr(url, '?'); + if (search != NULL) + *(search++) = '\0'; + } + else + search = r->args; + + /* process path */ + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); + if (path == NULL) + return HTTP_BAD_REQUEST; + + apr_snprintf(sport, sizeof(sport), ":%d", port); + + if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ + host = apr_pstrcat(r->pool, "[", host, "]", NULL); + } + r->filename = apr_pstrcat(r->pool, "proxy:ajp://", host, sport, + "/", path, (search) ? "?" : "", (search) ? search : "", NULL); + return OK; +} + +/* + * process the request and write the respnse. + */ +static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, + proxy_conn_rec *conn, + conn_rec *origin, + proxy_server_conf *conf, + apr_uri_t *uri, + char *url, char *server_portstr) +{ + apr_status_t status; + int result; + apr_bucket *e; + apr_bucket_brigade *input_brigade; + apr_bucket_brigade *output_brigade; + ajp_msg_t *msg; + apr_size_t bufsiz; + char *buff; + apr_uint16_t size; + const char *tenc; + int havebody = 1; + int isok = 1; + apr_off_t bb_len; + + /* + * Send the AJP request to the remote server + */ + + /* send request headers */ + status = ajp_send_header(conn->sock, r, uri); + if (status != APR_SUCCESS) { + conn->close++; + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: AJP: request failed to %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + if (status == AJP_EOVERFLOW) + return HTTP_BAD_REQUEST; + else + return HTTP_SERVICE_UNAVAILABLE; + } + + /* allocate an AJP message to store the data of the buckets */ + status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: ajp_alloc_data_msg failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + /* read the first bloc of data */ + input_brigade = apr_brigade_create(p, r->connection->bucket_alloc); + tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); + if (tenc && strcasecmp(tenc, "chunked")==0) { + /* The AJP protocol does not want body data yet */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: request is chunked"); + } else { + status = ap_get_brigade(r->input_filters, input_brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + AJP13_MAX_SEND_BODY_SZ); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: ap_get_brigade failed"); + apr_brigade_destroy(input_brigade); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* have something */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: APR_BUCKET_IS_EOS"); + } + + /* Try to send something */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: data to read (max %" APR_SIZE_T_FMT + " at %" APR_SIZE_T_FMT ")", bufsiz, msg->pos); + + status = apr_brigade_flatten(input_brigade, buff, &bufsiz); + if (status != APR_SUCCESS) { + apr_brigade_destroy(input_brigade); + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: apr_brigade_flatten"); + return HTTP_INTERNAL_SERVER_ERROR; + } + apr_brigade_cleanup(input_brigade); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: got %" APR_SIZE_T_FMT " bytes of data", bufsiz); + if (bufsiz > 0) { + status = ajp_send_data_msg(conn->sock, msg, bufsiz); + if (status != APR_SUCCESS) { + apr_brigade_destroy(input_brigade); + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: send failed to %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + conn->worker->s->transferred += bufsiz; + } + } + + /* read the response */ + status = ajp_read_header(conn->sock, r, + (ajp_msg_t **)&(conn->data)); + if (status != APR_SUCCESS) { + apr_brigade_destroy(input_brigade); + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: read response failed from %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + /* parse the reponse */ + result = ajp_parse_type(r, conn->data); + output_brigade = apr_brigade_create(p, r->connection->bucket_alloc); + + bufsiz = AJP13_MAX_SEND_BODY_SZ; + while (isok) { + switch (result) { + case CMD_AJP13_GET_BODY_CHUNK: + if (havebody) { + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { + /* That is the end */ + bufsiz = 0; + havebody = 0; + ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, + "proxy: APR_BUCKET_IS_EOS"); + } else { + status = ap_get_brigade(r->input_filters, input_brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + AJP13_MAX_SEND_BODY_SZ); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, + "ap_get_brigade failed"); + break; + } + bufsiz = AJP13_MAX_SEND_BODY_SZ; + status = apr_brigade_flatten(input_brigade, buff, &bufsiz); + apr_brigade_cleanup(input_brigade); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, + "apr_brigade_flatten failed"); + break; + } + } + + ajp_msg_reset(msg); /* will go in ajp_send_data_msg */ + status = ajp_send_data_msg(conn->sock, msg, bufsiz); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, + "ajp_send_data_msg failed"); + break; + } + conn->worker->s->transferred += bufsiz; + } else { + /* something is wrong TC asks for more body but we are + * already at the end of the body data + */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ap_proxy_ajp_request error read after end"); + isok = 0; + } + break; + case CMD_AJP13_SEND_HEADERS: + /* AJP13_SEND_HEADERS: process them */ + status = ajp_parse_header(r, conf, conn->data); + if (status != APR_SUCCESS) { + isok=0; + } + break; + case CMD_AJP13_SEND_BODY_CHUNK: + /* AJP13_SEND_BODY_CHUNK: piece of data */ + status = ajp_parse_data(r, conn->data, &size, &buff); + e = apr_bucket_transient_create(buff, size, + r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(output_brigade, e); + if (status != APR_SUCCESS) + isok = 0; + break; + case CMD_AJP13_END_RESPONSE: + e = apr_bucket_eos_create(r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(output_brigade, e); + if (ap_pass_brigade(r->output_filters, output_brigade) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: error processing body"); + isok=0; + } + break; + default: + isok=0; + break; + } + if (!isok) + break; + + if (result == CMD_AJP13_END_RESPONSE) + break; + + /* read the response */ + status = ajp_read_header(conn->sock, r, + (ajp_msg_t **)&(conn->data)); + if (status != APR_SUCCESS) { + isok=0; + ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, + "ajp_read_header failed"); + break; + } + result = ajp_parse_type(r, conn->data); + } + apr_brigade_destroy(input_brigade); + + apr_brigade_length(output_brigade, 0, &bb_len); + if (bb_len != -1) + conn->worker->s->read += bb_len; + + if (!isok) + apr_brigade_destroy(output_brigade); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: send body failed to %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + + /* Nice we have answer to send to the client */ + if (result == CMD_AJP13_END_RESPONSE && isok) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: got response from %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + return OK; + } + + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: got bad response (%d) from %pI (%s)", + result, + conn->worker->cp->addr, + conn->worker->hostname); + + return HTTP_SERVICE_UNAVAILABLE; +} + +/* + * This handles ajp:// URLs, and other URLs using a remote proxy over http + * If proxyhost is NULL, then contact the server directly, otherwise + * go via the proxy. + * Note that if a proxy is used, then URLs other than http: can be accessed, + * also, if we have trouble which is clearly specific to the proxy, then + * we return DECLINED so that we can try another proxy. (Or the direct + * route.) + */ +static int proxy_ajp_handler(request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, + char *url, const char *proxyname, + apr_port_t proxyport) +{ + int status; + char server_portstr[32]; + conn_rec *origin = NULL; + proxy_conn_rec *backend = NULL; + const char *scheme = "AJP"; + + /* Note: Memory pool allocation. + * A downstream keepalive connection is always connected to the existence + * (or not) of an upstream keepalive connection. If this is not done then + * load balancing against multiple backend servers breaks (one backend + * server ends up taking 100% of the load), and the risk is run of + * downstream keepalive connections being kept open unnecessarily. This + * keeps webservers busy and ties up resources. + * + * As a result, we allocate all sockets out of the upstream connection + * pool, and when we want to reuse a socket, we check first whether the + * connection ID of the current upstream connection is the same as that + * of the connection when the socket was opened. + */ + apr_pool_t *p = r->connection->pool; +#if 0 + conn_rec *c = r->connection; +#endif + apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri)); + + + if (strncasecmp(url, "ajp:", 4) != 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: AJP: declining URL %s", url); + return DECLINED; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: AJP: serving URL %s", url); + + + /* only use stored info for top-level pages. Sub requests don't share + * in keepalives + */ +#if 0 + if (!r->main) { + backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, + &proxy_ajp_module); + } +#endif + /* create space for state information */ + if (!backend) { + status = ap_proxy_acquire_connection(scheme, &backend, worker, r->server); + if (status != OK) { + if (backend) { + backend->close_on_recycle = 1; + ap_proxy_release_connection(scheme, backend, r->server); + } + return status; + } +#if 0 + if (!r->main) { + ap_set_module_config(c->conn_config, &proxy_ajp_module, backend); + } +#endif + } + + backend->is_ssl = 0; + backend->close_on_recycle = 0; + + /* Step One: Determine Who To Connect To */ + status = ap_proxy_determine_connection(p, r, conf, worker, backend, + uri, &url, proxyname, proxyport, + server_portstr, + sizeof(server_portstr)); + + if (status != OK) + goto cleanup; + /* Step Two: Make the Connection */ + if (ap_proxy_connect_backend(scheme, backend, worker, r->server)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "proxy: AJP: failed to make connection to backend: %s", + backend->hostname); + status = HTTP_SERVICE_UNAVAILABLE; + goto cleanup; + } +#if 0 + /* XXX: we don't need to create the bound client connection */ + + /* Step Three: Create conn_rec */ + if (!backend->connection) { + status = ap_proxy_connection_create(scheme, backend, c, r->server); + if (status != OK) + goto cleanup; + } +#endif + + + /* Step Four: Process the Request */ + status = ap_proxy_ajp_request(p, r, backend, origin, conf, uri, url, + server_portstr); + if (status != OK) + goto cleanup; + +cleanup: +#if 0 + /* Clear the module config */ + ap_set_module_config(c->conn_config, &proxy_ajp_module, NULL); +#endif + /* Do not close the socket */ + ap_proxy_release_connection(scheme, backend, r->server); + return status; +} + +static void ap_proxy_http_register_hook(apr_pool_t *p) +{ + proxy_hook_scheme_handler(proxy_ajp_handler, NULL, NULL, APR_HOOK_FIRST); + proxy_hook_canon_handler(proxy_ajp_canon, NULL, NULL, APR_HOOK_FIRST); +} + +module AP_MODULE_DECLARE_DATA proxy_ajp_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_proxy_http_register_hook/* register hooks */ +}; + diff --git a/trunk/modules/proxy/mod_proxy_ajp.dsp b/trunk/modules/proxy/mod_proxy_ajp.dsp new file mode 100644 index 0000000000..212502c6fd --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_ajp.dsp @@ -0,0 +1,160 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy_ajp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy_ajp - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_ajp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_ajp.mak" CFG="mod_proxy_ajp - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy_ajp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy_ajp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy_ajp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_ajp_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Release/mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy_ajp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_ajp_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_ajp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ajp.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy_ajp - Win32 Release" +# Name "mod_proxy_ajp - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy_ajp.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Group "Ajp Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ajp.h +# End Source File +# Begin Source File + +SOURCE=.\ajp_header.c +# End Source File +# Begin Source File + +SOURCE=.\ajp_header.h +# End Source File +# Begin Source File + +SOURCE=.\ajp_link.c +# End Source File +# Begin Source File + +SOURCE=.\ajp_msg.c +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy_ajp - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_ajp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_ajp.so "proxy_ajp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ajp.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy_ajp - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_ajp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_ajp.so "proxy_ajp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ajp.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/mod_proxy_balancer.c b/trunk/modules/proxy/mod_proxy_balancer.c new file mode 100644 index 0000000000..ab122892f7 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_balancer.c @@ -0,0 +1,897 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Load balancer module for Apache proxy */ + +#define CORE_PRIVATE + +#include "mod_proxy.h" +#include "ap_mpm.h" +#include "apr_version.h" + +module AP_MODULE_DECLARE_DATA proxy_balancer_module; + +static int proxy_balancer_canon(request_rec *r, char *url) +{ + char *host, *path, *search; + const char *err; + apr_port_t port = 0; + + if (strncasecmp(url, "balancer:", 9) == 0) { + url += 9; + } + else { + return DECLINED; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: BALANCER: canonicalising URL %s", url); + + /* do syntatic check. + * We break the URL into host, port, path, search + */ + err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); + if (err) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "error parsing URL %s: %s", + url, err); + return HTTP_BAD_REQUEST; + } + /* now parse path/search args, according to rfc1738 */ + /* N.B. if this isn't a true proxy request, then the URL _path_ + * has already been decoded. True proxy requests have r->uri + * == r->unparsed_uri, and no others have that property. + */ + if (r->uri == r->unparsed_uri) { + search = strchr(url, '?'); + if (search != NULL) + *(search++) = '\0'; + } + else + search = r->args; + + /* process path */ + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); + if (path == NULL) + return HTTP_BAD_REQUEST; + + r->filename = apr_pstrcat(r->pool, "proxy:balancer://", host, + "/", path, (search) ? "?" : "", (search) ? search : "", NULL); + return OK; +} + +static int init_balancer_members(proxy_server_conf *conf, server_rec *s, + proxy_balancer *balancer) +{ + int i; + proxy_worker *workers; + + workers = (proxy_worker *)balancer->workers->elts; + + for (i = 0; i < balancer->workers->nelts; i++) { + ap_proxy_initialize_worker_share(conf, workers, s); + workers->s->status = PROXY_WORKER_INITIALIZED; + ++workers; + } + + workers = (proxy_worker *)balancer->workers->elts; + for (i = 0; i < balancer->workers->nelts; i++) { + /* Set to the original configuration */ + workers[i].s->lbstatus = workers[i].s->lbfactor = + (workers[i].lbfactor ? workers[i].lbfactor : 1); + } + /* Set default number of attempts to the number of + * workers. + */ + if (!balancer->max_attempts_set && balancer->workers->nelts > 1) { + balancer->max_attempts = balancer->workers->nelts - 1; + balancer->max_attempts_set = 1; + } + return 0; +} + +/* Retrieve the parameter with the given name + * Something like 'JSESSIONID=12345...N' + */ +static char *get_path_param(apr_pool_t *pool, char *url, + const char *name) +{ + char *path = NULL; + + for (path = strstr(url, name); path; path = strstr(path + 1, name)) { + path += (strlen(name) + 1); + if (*path == '=') { + /* + * Session path was found, get it's value + */ + ++path; + if (strlen(path)) { + char *q; + path = apr_pstrdup(pool, path); + if ((q = strchr(path, '?'))) + *q = '\0'; + return path; + } + } + } + return NULL; +} + +static char *get_cookie_param(request_rec *r, const char *name) +{ + const char *cookies; + const char *start_cookie; + + if ((cookies = apr_table_get(r->headers_in, "Cookie"))) { + for (start_cookie = ap_strstr_c(cookies, name); start_cookie; + start_cookie = ap_strstr_c(start_cookie + 1, name)) { + if (start_cookie == cookies || + start_cookie[-1] == ';' || + start_cookie[-1] == ',' || + isspace(start_cookie[-1])) { + + start_cookie += strlen(name); + while(*start_cookie && isspace(*start_cookie)) + ++start_cookie; + if (*start_cookie == '=' && start_cookie[1]) { + /* + * Session cookie was found, get it's value + */ + char *end_cookie, *cookie; + ++start_cookie; + cookie = apr_pstrdup(r->pool, start_cookie); + if ((end_cookie = strchr(cookie, ';')) != NULL) + *end_cookie = '\0'; + if((end_cookie = strchr(cookie, ',')) != NULL) + *end_cookie = '\0'; + return cookie; + } + } + } + } + return NULL; +} + +/* Find the worker that has the 'route' defined + */ +static proxy_worker *find_route_worker(proxy_balancer *balancer, + const char *route) +{ + int i; + proxy_worker *worker = (proxy_worker *)balancer->workers->elts; + for (i = 0; i < balancer->workers->nelts; i++) { + if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) { + return worker; + } + worker++; + } + return NULL; +} + +static proxy_worker *find_session_route(proxy_balancer *balancer, + request_rec *r, + char **route, + char **url) +{ + if (!balancer->sticky) + return NULL; + /* Try to find the sticky route inside url */ + *route = get_path_param(r->pool, *url, balancer->sticky); + if (!*route) + *route = get_cookie_param(r, balancer->sticky); + if (*route) { + /* We have a route in path or in cookie + * Find the worker that has this route defined. + */ + proxy_worker *worker = find_route_worker(balancer, *route); + if (worker && !PROXY_WORKER_IS_USABLE(worker)) { + /* We have a worker that is unusable. + * It can be in error or disabled, but in case + * it has a redirection set use that redirection worker. + * This enables to safely remove the member from the + * balancer. Of course you will need a some kind of + * session replication between those two remote. + */ + if (*worker->s->redirect) + worker = find_route_worker(balancer, worker->s->redirect); + /* Check if the redirect worker is usable */ + if (worker && !PROXY_WORKER_IS_USABLE(worker)) + worker = NULL; + } + return worker; + } + else + return NULL; +} + +/* + * The idea behind the find_best_byrequests scheduler is the following: + * + * lbfactor is "how much we expect this worker to work", or "the worker's + * normalized work quota". + * + * lbstatus is "how urgent this worker has to work to fulfill its quota + * of work". + * + * We distribute each worker's work quota to the worker, and then look + * which of them needs to work most urgently (biggest lbstatus). This + * worker is then selected for work, and its lbstatus reduced by the + * total work quota we distributed to all workers. Thus the sum of all + * lbstatus does not change.(*) + * + * If some workers are disabled, the others will + * still be scheduled correctly. + * + * If a balancer is configured as follows: + * + * worker a b c d + * lbfactor 25 25 25 25 + * + * And b gets disabled, the following schedule is produced: + * + * a c d a c d a c d ... + * + * Note that the above lbfactor setting is the *exact* same as: + * + * worker a b c d + * lbfactor 1 1 1 1 + * + * Asymmetric configurations work as one would expect. For + * example: + * + * worker a b c d + * lbfactor 1 1 1 2 + * + * would have a, b and c all handling about the same + * amount of load with d handling twice what a or b + * or c handles individually. So we could see: + * + * b a d c d a c d b d ... + * + */ +static proxy_worker *find_best_byrequests(proxy_balancer *balancer, + request_rec *r) +{ + int i; + int total_factor = 0; + proxy_worker *worker = (proxy_worker *)balancer->workers->elts; + proxy_worker *candidate = NULL; + + /* First try to see if we have available candidate */ + for (i = 0; i < balancer->workers->nelts; i++) { + /* If the worker is in error state run + * retry on that worker. It will be marked as + * operational if the retry timeout is elapsed. + * The worker might still be unusable, but we try + * anyway. + */ + if (!PROXY_WORKER_IS_USABLE(worker)) + ap_proxy_retry_worker("BALANCER", worker, r->server); + /* Take into calculation only the workers that are + * not in error state or not disabled. + */ + if (PROXY_WORKER_IS_USABLE(worker)) { + worker->s->lbstatus += worker->s->lbfactor; + total_factor += worker->s->lbfactor; + if (!candidate || worker->s->lbstatus > candidate->s->lbstatus) + candidate = worker; + } + worker++; + } + + if (candidate) { + candidate->s->lbstatus -= total_factor; + candidate->s->elected++; + } + + return candidate; +} + +/* + * The idea behind the find_best_bytraffic scheduler is the following: + * + * We know the amount of traffic (bytes in and out) handled by each + * worker. We normalize that traffic by each workers' weight. So assuming + * a setup as below: + * + * worker a b c + * lbfactor 1 1 3 + * + * the scheduler will allow worker c to handle 3 times the + * traffic of a and b. If each request/response results in the + * same amount of traffic, then c would be accessed 3 times as + * often as a or b. If, for example, a handled a request that + * resulted in a large i/o bytecount, then b and c would be + * chosen more often, to even things out. + */ +static proxy_worker *find_best_bytraffic(proxy_balancer *balancer, + request_rec *r) +{ + int i; + apr_off_t mytraffic = 0; + apr_off_t curmin = 0; + proxy_worker *worker = (proxy_worker *)balancer->workers->elts; + proxy_worker *candidate = NULL; + + /* First try to see if we have available candidate */ + for (i = 0; i < balancer->workers->nelts; i++) { + /* If the worker is in error state run + * retry on that worker. It will be marked as + * operational if the retry timeout is elapsed. + * The worker might still be unusable, but we try + * anyway. + */ + if (!PROXY_WORKER_IS_USABLE(worker)) + ap_proxy_retry_worker("BALANCER", worker, r->server); + /* Take into calculation only the workers that are + * not in error state or not disabled. + */ + if (PROXY_WORKER_IS_USABLE(worker)) { + mytraffic = (worker->s->transferred/worker->s->lbfactor) + + (worker->s->read/worker->s->lbfactor); + if (!candidate || mytraffic < curmin) { + candidate = worker; + curmin = mytraffic; + } + } + worker++; + } + + if (candidate) { + candidate->s->elected++; + } + + return candidate; +} + +static proxy_worker *find_best_worker(proxy_balancer *balancer, + request_rec *r) +{ + proxy_worker *candidate = NULL; + + if (PROXY_THREAD_LOCK(balancer) != APR_SUCCESS) + return NULL; + + if (balancer->lbmethod == lbmethod_requests) { + candidate = find_best_byrequests(balancer, r); + } else if (balancer->lbmethod == lbmethod_traffic) { + candidate = find_best_bytraffic(balancer, r); + } else { + PROXY_THREAD_UNLOCK(balancer); + return NULL; + } + + PROXY_THREAD_UNLOCK(balancer); + + if (candidate == NULL) { + /* All the workers are in error state or disabled. + * If the balancer has a timeout sleep for a while + * and try again to find the worker. The chances are + * that some other thread will release a connection. + * By default the timeout is not set, and the server + * returns SERVER_BUSY. + */ +#if APR_HAS_THREADS + if (balancer->timeout) { + /* XXX: This can perhaps be build using some + * smarter mechanism, like tread_cond. + * But since the statuses can came from + * different childs, use the provided algo. + */ + apr_interval_time_t timeout = balancer->timeout; + apr_interval_time_t step, tval = 0; + /* Set the timeout to 0 so that we don't + * end in infinite loop + */ + balancer->timeout = 0; + step = timeout / 100; + while (tval < timeout) { + apr_sleep(step); + /* Try again */ + if ((candidate = find_best_worker(balancer, r))) + break; + tval += step; + } + /* restore the timeout */ + balancer->timeout = timeout; + } +#endif + } + return candidate; +} + +static int rewrite_url(request_rec *r, proxy_worker *worker, + char **url) +{ + const char *scheme = strstr(*url, "://"); + const char *path = NULL; + + if (scheme) + path = ap_strchr_c(scheme + 3, '/'); + + /* we break the URL into host, port, uri */ + if (!worker) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r->pool, + "missing worker. URI cannot be parsed: ", *url, + NULL)); + } + + *url = apr_pstrcat(r->pool, worker->name, path, NULL); + + return OK; +} + +static int proxy_balancer_pre_request(proxy_worker **worker, + proxy_balancer **balancer, + request_rec *r, + proxy_server_conf *conf, char **url) +{ + int access_status; + proxy_worker *runtime; + char *route; + apr_status_t rv; + + *worker = NULL; + /* Step 1: check if the url is for us + * The url we can handle starts with 'balancer://' + * If balancer is already provided skip the search + * for balancer, because this is failover attempt. + */ + if (!*balancer && + !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url))) + return DECLINED; + + /* Step 2: find the session route */ + + runtime = find_session_route(*balancer, r, &route, url); + /* Lock the LoadBalancer + * XXX: perhaps we need the process lock here + */ + if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "proxy: BALANCER: lock"); + return DECLINED; + } + if (runtime) { + int i, total_factor = 0; + proxy_worker *workers; + /* We have a sticky load balancer + * Update the workers status + * so that even session routes get + * into account. + */ + workers = (proxy_worker *)(*balancer)->workers->elts; + for (i = 0; i < (*balancer)->workers->nelts; i++) { + /* Take into calculation only the workers that are + * not in error state or not disabled. + */ + if (PROXY_WORKER_IS_USABLE(workers)) { + workers->s->lbstatus += workers->s->lbfactor; + total_factor += workers->s->lbfactor; + } + workers++; + } + runtime->s->lbstatus -= total_factor; + runtime->s->elected++; + + *worker = runtime; + } + else if (route && (*balancer)->sticky_force) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "proxy: BALANCER: (%s). All workers are in error state for route (%s)", + (*balancer)->name, route); + PROXY_THREAD_UNLOCK(*balancer); + return HTTP_SERVICE_UNAVAILABLE; + } + + PROXY_THREAD_UNLOCK(*balancer); + if (!*worker) { + runtime = find_best_worker(*balancer, r); + if (!runtime) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "proxy: BALANCER: (%s). All workers are in error state", + (*balancer)->name); + + return HTTP_SERVICE_UNAVAILABLE; + } + *worker = runtime; + } + + /* Rewrite the url from 'balancer://url' + * to the 'worker_scheme://worker_hostname[:worker_port]/url' + * This replaces the balancers fictional name with the + * real hostname of the elected worker. + */ + access_status = rewrite_url(r, *worker, url); + /* Add the session route to request notes if present */ + if (route) { + apr_table_setn(r->notes, "session-sticky", (*balancer)->sticky); + apr_table_setn(r->notes, "session-route", route); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: BALANCER (%s) worker (%s) rewritten to %s", + (*balancer)->name, (*worker)->name, *url); + + return access_status; +} + +static int proxy_balancer_post_request(proxy_worker *worker, + proxy_balancer *balancer, + request_rec *r, + proxy_server_conf *conf) +{ + apr_status_t rv; + + if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "proxy: BALANCER: lock"); + return HTTP_INTERNAL_SERVER_ERROR; + } + /* TODO: calculate the bytes transferred + * This will enable to elect the worker that has + * the lowest load. + * The bytes transferred depends on the protocol + * used, so each protocol handler should keep the + * track on that. + */ + + PROXY_THREAD_UNLOCK(balancer); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy_balancer_post_request for (%s)", balancer->name); + + return OK; +} + +static void recalc_factors(proxy_balancer *balancer) +{ + int i; + proxy_worker *workers; + + + /* Recalculate lbfactors */ + workers = (proxy_worker *)balancer->workers->elts; + /* Special case if there is only one worker it's + * load factor will always be 1 + */ + if (balancer->workers->nelts == 1) { + workers->s->lbstatus = workers->s->lbfactor = 1; + return; + } + for (i = 0; i < balancer->workers->nelts; i++) { + /* Update the status entries */ + workers[i].s->lbstatus = workers[i].s->lbfactor; + } +} + +/* Manages the loadfactors and member status + */ +static int balancer_handler(request_rec *r) +{ + void *sconf = r->server->module_config; + proxy_server_conf *conf = (proxy_server_conf *) + ap_get_module_config(sconf, &proxy_module); + proxy_balancer *balancer, *bsel = NULL; + proxy_worker *worker, *wsel = NULL; + apr_table_t *params = apr_table_make(r->pool, 10); + int access_status; + int i, n; + const char *name; + + /* is this for us? */ + if (strcmp(r->handler, "balancer-manager")) + return DECLINED; + r->allowed = (AP_METHOD_BIT << M_GET); + if (r->method_number != M_GET) + return DECLINED; + + if (r->args) { + char *args = apr_pstrdup(r->pool, r->args); + char *tok, *val; + while (args && *args) { + if ((val = ap_strchr(args, '='))) { + *val++ = '\0'; + if ((tok = ap_strchr(val, '&'))) + *tok++ = '\0'; + if ((access_status = ap_unescape_url(val)) != OK) + return access_status; + apr_table_setn(params, args, val); + args = tok; + } + else + return HTTP_BAD_REQUEST; + } + } + if ((name = apr_table_get(params, "b"))) + bsel = ap_proxy_get_balancer(r->pool, conf, + apr_pstrcat(r->pool, "balancer://", name, NULL)); + if ((name = apr_table_get(params, "w"))) { + const char *sc = apr_table_get(params, "s"); + char *asname = NULL; + proxy_worker *ws = NULL; + if (sc) { + asname = apr_pstrcat(r->pool, sc, "://", name, NULL); + ws = ap_proxy_get_worker(r->pool, conf, asname); + } + if (ws) { + worker = (proxy_worker *)bsel->workers->elts; + for (n = 0; n < bsel->workers->nelts; n++) { + if (strcasecmp(worker->name, ws->name) == 0) { + wsel = worker; + break; + } + ++worker; + } + } + } + /* First set the params */ + if (bsel) { + const char *val; + if ((val = apr_table_get(params, "ss"))) { + if (strlen(val)) + bsel->sticky = apr_pstrdup(conf->pool, val); + else + bsel->sticky = NULL; + } + if ((val = apr_table_get(params, "tm"))) { + int ival = atoi(val); + if (ival >= 0) + bsel->timeout = apr_time_from_sec(ival); + } + if ((val = apr_table_get(params, "fa"))) { + int ival = atoi(val); + if (ival >= 0) + bsel->max_attempts = ival; + bsel->max_attempts_set = 1; + } + if ((val = apr_table_get(params, "lm"))) { + int ival = atoi(val); + switch(ival) { + case 0: + break; + case lbmethod_traffic: + bsel->lbmethod = lbmethod_traffic; + break; + case lbmethod_requests: + bsel->lbmethod = lbmethod_requests; + break; + default: + break; + } + } + } + if (wsel) { + const char *val; + if ((val = apr_table_get(params, "lf"))) { + int ival = atoi(val); + if (ival >= 1 && ival <= 100) { + wsel->s->lbfactor = ival; + if (bsel) + recalc_factors(bsel); + } + } + if ((val = apr_table_get(params, "wr"))) { + if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ) + strcpy(wsel->s->route, val); + else + *wsel->s->route = '\0'; + } + if ((val = apr_table_get(params, "rr"))) { + if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ) + strcpy(wsel->s->redirect, val); + else + *wsel->s->redirect = '\0'; + } + if ((val = apr_table_get(params, "dw"))) + wsel->s->status |= PROXY_WORKER_DISABLED; + else + wsel->s->status &= ~PROXY_WORKER_DISABLED; + + } + if (apr_table_get(params, "xml")) { + ap_set_content_type(r, "text/xml"); + ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r); + ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r); + ap_rputs(" <httpd:balancers>\n", r); + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++) { + ap_rputs(" <httpd:balancer>\n", r); + ap_rvputs(r, " <httpd:name>", balancer->name, "</httpd:name>\n", NULL); + ap_rputs(" <httpd:workers>\n", r); + worker = (proxy_worker *)balancer->workers->elts; + for (n = 0; n < balancer->workers->nelts; n++) { + ap_rputs(" <httpd:worker>\n", r); + ap_rvputs(r, " <httpd:scheme>", worker->scheme, + "</httpd:scheme>\n", NULL); + ap_rvputs(r, " <httpd:hostname>", worker->hostname, + "</httpd:hostname>\n", NULL); + ap_rprintf(r, " <httpd:loadfactor>%d</httpd:loadfactor>\n", + worker->s->lbfactor); + ap_rputs(" </httpd:worker>\n", r); + ++worker; + } + ap_rputs(" </httpd:workers>\n", r); + ap_rputs(" </httpd:balancer>\n", r); + ++balancer; + } + ap_rputs(" </httpd:balancers>\n", r); + ap_rputs("</httpd:manager>", r); + } + else { + ap_set_content_type(r, "text/html"); + ap_rputs(DOCTYPE_HTML_3_2 + "<html><head><title>Balancer Manager\n", r); + ap_rputs("

    Load Balancer Manager for ", r); + ap_rvputs(r, ap_get_server_name(r), "

    \n\n", NULL); + ap_rvputs(r, "
    Server Version: ", + ap_get_server_version(), "
    \n", NULL); + ap_rvputs(r, "
    Server Built: ", + ap_get_server_built(), "\n
    \n", NULL); + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++) { + + ap_rputs("
    \n

    LoadBalancer Status for ", r); + ap_rvputs(r, "uri, "?b=", + balancer->name + sizeof("balancer://") - 1, + "\">", NULL); + ap_rvputs(r, balancer->name, "

    \n\n", NULL); + ap_rputs("\n\n" + "" + "\n", r); + ap_rvputs(r, "", + apr_time_sec(balancer->timeout)); + ap_rprintf(r, "\n", balancer->max_attempts); + ap_rprintf(r, "\n", + balancer->lbmethod == lbmethod_requests ? "Requests" : + balancer->lbmethod == lbmethod_traffic ? "Traffic" : "Unknown"); + ap_rputs("
    StickySessionTimeoutFailoverAttemptsMethod
    ", balancer->sticky, NULL); + ap_rprintf(r, "%" APR_TIME_T_FMT "%d%s
    \n", r); + ap_rputs("\n\n" + "" + "" + "" + "\n", r); + + worker = (proxy_worker *)balancer->workers->elts; + for (n = 0; n < balancer->workers->nelts; n++) { + + ap_rvputs(r, "\n", NULL); + ap_rvputs(r, "\n", r); + + ++worker; + } + ap_rputs("
    SchemeHostRouteRouteRedirFactorStatus
    ", worker->scheme, "", NULL); + ap_rvputs(r, "uri, "?b=", + balancer->name + sizeof("balancer://") - 1, + "&s=", worker->scheme, "&w=", worker->hostname, + "\">", NULL); + ap_rvputs(r, worker->hostname, "", worker->s->route, NULL); + ap_rvputs(r, "", worker->s->redirect, NULL); + ap_rprintf(r, "%d", worker->s->lbfactor); + if (worker->s->status & PROXY_WORKER_DISABLED) + ap_rputs("Dis", r); + else if (worker->s->status & PROXY_WORKER_IN_ERROR) + ap_rputs("Err", r); + else if (worker->s->status & PROXY_WORKER_INITIALIZED) + ap_rputs("Ok", r); + else + ap_rputs("-", r); + ap_rputs("
    \n", r); + ++balancer; + } + ap_rputs("
    \n", r); + if (wsel && bsel) { + ap_rputs("

    Edit worker settings for ", r); + ap_rvputs(r, wsel->name, "

    \n", NULL); + ap_rvputs(r, "
    uri, "\">\n
    ", NULL); + ap_rputs("\n", wsel->s->lbfactor); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rvputs(r, "
    Load factor:
    Route:route, NULL); + ap_rputs("\">
    Route Redirect:redirect, NULL); + ap_rputs("\">
    Disabled:s->status & PROXY_WORKER_DISABLED) + ap_rputs(" checked", r); + ap_rputs(">
    \nscheme, "\">\n", NULL); + ap_rvputs(r, "hostname, "\">\n", NULL); + ap_rvputs(r, "name + sizeof("balancer://") - 1, + "\">\n\n", NULL); + ap_rputs("
    \n", r); + } + else if (bsel) { + ap_rputs("

    Edit balancer settings for ", r); + ap_rvputs(r, bsel->name, "

    \n", NULL); + ap_rvputs(r, "
    uri, "\">\n
    ", NULL); + ap_rputs("\n\n", + apr_time_sec(bsel->timeout)); + ap_rputs("\n", + bsel->max_attempts); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rvputs(r, "
    StickySession Identifier:sticky) + ap_rvputs(r, "value=\"", bsel->sticky, "\"", NULL); + ap_rputs(">
    Timeout:
    Failover Attempts:
    LB Method:
    \nname + sizeof("balancer://") - 1, + "\">\n\n", NULL); + ap_rputs("
    \n", r); + } + ap_rputs(ap_psignature("",r), r); + ap_rputs("\n", r); + } + return OK; +} + +static void child_init(apr_pool_t *p, server_rec *s) +{ + while (s) { + void *sconf = s->module_config; + proxy_server_conf *conf; + proxy_balancer *balancer; + int i; + conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); + + /* Initialize shared scoreboard data */ + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++) { + init_balancer_members(conf, s, balancer); + balancer++; + } + s = s->next; + } + +} + +static void ap_proxy_balancer_register_hook(apr_pool_t *p) +{ + /* Only the mpm_winnt has child init hook handler. + * make sure that we are called after the mpm + * initializes and after the mod_proxy + */ + static const char *const aszPred[] = { "mpm_winnt.c", "mod_proxy.c", NULL}; + /* manager handler */ + ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST); + ap_hook_child_init(child_init, aszPred, NULL, APR_HOOK_MIDDLE); + proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST); + proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST); + proxy_hook_canon_handler(proxy_balancer_canon, NULL, NULL, APR_HOOK_FIRST); +} + +module AP_MODULE_DECLARE_DATA proxy_balancer_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_proxy_balancer_register_hook /* register hooks */ +}; diff --git a/trunk/modules/proxy/mod_proxy_balancer.dsp b/trunk/modules/proxy/mod_proxy_balancer.dsp new file mode 100644 index 0000000000..43e4d5a1ca --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_balancer.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy_balancer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy_balancer - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_balancer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy_balancer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy_balancer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy_balancer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_balancer_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy_balancer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_balancer_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy_balancer - Win32 Release" +# Name "mod_proxy_balancer - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy_balancer.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy_balancer - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_balancer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_balancer.so "proxy_balancer_module for Apache" ../../include/ap_release.h > .\mod_proxy_balancer.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy_balancer - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_balancer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_balancer.so "proxy_balancer_module for Apache" ../../include/ap_release.h > .\mod_proxy_balancer.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/mod_proxy_connect.c b/trunk/modules/proxy/mod_proxy_connect.c new file mode 100644 index 0000000000..a42bb7eaca --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_connect.c @@ -0,0 +1,399 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* CONNECT method for Apache proxy */ + +#define CORE_PRIVATE + +#include "mod_proxy.h" +#include "apr_poll.h" + +module AP_MODULE_DECLARE_DATA proxy_connect_module; + +/* + * This handles Netscape CONNECT method secure proxy requests. + * A connection is opened to the specified host and data is + * passed through between the WWW site and the browser. + * + * This code is based on the INTERNET-DRAFT document + * "Tunneling SSL Through a WWW Proxy" currently at + * http://www.mcom.com/newsref/std/tunneling_ssl.html. + * + * If proxyhost and proxyport are set, we send a CONNECT to + * the specified proxy.. + * + * FIXME: this doesn't log the number of bytes sent, but + * that may be okay, since the data is supposed to + * be transparent. In fact, this doesn't log at all + * yet. 8^) + * FIXME: doesn't check any headers initally sent from the + * client. + * FIXME: should allow authentication, but hopefully the + * generic proxy authentication is good enough. + * FIXME: no check for r->assbackwards, whatever that is. + */ + +static int allowed_port(proxy_server_conf *conf, int port) +{ + int i; + int *list = (int *) conf->allowed_connect_ports->elts; + + for(i = 0; i < conf->allowed_connect_ports->nelts; i++) { + if(port == list[i]) + return 1; + } + return 0; +} + +/* canonicalise CONNECT URLs. */ +static int proxy_connect_canon(request_rec *r, char *url) +{ + + if (r->method_number != M_CONNECT) { + return DECLINED; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: canonicalising URL %s", url); + + return OK; +} + +/* CONNECT handler */ +static int proxy_connect_handler(request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, + char *url, const char *proxyname, + apr_port_t proxyport) +{ + apr_pool_t *p = r->pool; + apr_socket_t *sock; + apr_status_t err, rv; + apr_size_t i, o, nbytes; + char buffer[HUGE_STRING_LEN]; + apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module); + int failed; + apr_pollset_t *pollset; + apr_pollfd_t pollfd; + const apr_pollfd_t *signalled; + apr_int32_t pollcnt, pi; + apr_int16_t pollevent; + apr_sockaddr_t *uri_addr, *connect_addr; + + apr_uri_t uri; + const char *connectname; + int connectport = 0; + + /* is this for us? */ + if (r->method_number != M_CONNECT) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: declining URL %s", url); + return DECLINED; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: serving URL %s", url); + + + /* + * Step One: Determine Who To Connect To + * + * Break up the URL to determine the host to connect to + */ + + /* we break the URL into host, port, uri */ + if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, + apr_pstrcat(p, "URI cannot be parsed: ", url, NULL)); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: connecting %s to %s:%d", url, uri.hostname, uri.port); + + /* do a DNS lookup for the destination host */ + err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p); + + /* are we connecting directly, or via a proxy? */ + if (proxyname) { + connectname = proxyname; + connectport = proxyport; + err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p); + } + else { + connectname = uri.hostname; + connectport = uri.port; + connect_addr = uri_addr; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: connecting to remote proxy %s on port %d", connectname, connectport); + + /* check if ProxyBlock directive on this host */ + if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) { + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); + } + + /* Check if it is an allowed port */ + if (conf->allowed_connect_ports->nelts == 0) { + /* Default setting if not overridden by AllowCONNECT */ + switch (uri.port) { + case APR_URI_HTTPS_DEFAULT_PORT: + case APR_URI_SNEWS_DEFAULT_PORT: + break; + default: + /* XXX can we call ap_proxyerror() here to get a nice log message? */ + return HTTP_FORBIDDEN; + } + } else if(!allowed_port(conf, uri.port)) { + /* XXX can we call ap_proxyerror() here to get a nice log message? */ + return HTTP_FORBIDDEN; + } + + /* + * Step Two: Make the Connection + * + * We have determined who to connect to. Now make the connection. + */ + + /* get all the possible IP addresses for the destname and loop through them + * until we get a successful connection + */ + if (APR_SUCCESS != err) { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, + "DNS lookup failure for: ", + connectname, NULL)); + } + + /* + * At this point we have a list of one or more IP addresses of + * the machine to connect to. If configured, reorder this + * list so that the "best candidate" is first try. "best + * candidate" could mean the least loaded server, the fastest + * responding server, whatever. + * + * For now we do nothing, ie we get DNS round robin. + * XXX FIXME + */ + failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr, + connectname, conf, r->server, + r->pool); + + /* handle a permanent error from the above loop */ + if (failed) { + if (proxyname) { + return DECLINED; + } + else { + return HTTP_BAD_GATEWAY; + } + } + + /* + * Step Three: Send the Request + * + * Send the HTTP/1.1 CONNECT request to the remote server + */ + + /* we are acting as a tunnel - the output filter stack should + * be completely empty, because when we are done here we are done completely. + * We add the NULL filter to the stack to do this... + */ + r->output_filters = NULL; + r->connection->output_filters = NULL; + + + /* If we are connecting through a remote proxy, we need to pass + * the CONNECT request on to it. + */ + if (proxyport) { + /* FIXME: Error checking ignored. + */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: sending the CONNECT request to the remote proxy"); + nbytes = apr_snprintf(buffer, sizeof(buffer), + "CONNECT %s HTTP/1.0" CRLF, r->uri); + apr_socket_send(sock, buffer, &nbytes); + nbytes = apr_snprintf(buffer, sizeof(buffer), + "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); + apr_socket_send(sock, buffer, &nbytes); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: Returning 200 OK Status"); + nbytes = apr_snprintf(buffer, sizeof(buffer), + "HTTP/1.0 200 Connection Established" CRLF); + ap_xlate_proto_to_ascii(buffer, nbytes); + apr_socket_send(client_socket, buffer, &nbytes); + nbytes = apr_snprintf(buffer, sizeof(buffer), + "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); + ap_xlate_proto_to_ascii(buffer, nbytes); + apr_socket_send(client_socket, buffer, &nbytes); +#if 0 + /* This is safer code, but it doesn't work yet. I'm leaving it + * here so that I can fix it later. + */ + r->status = HTTP_OK; + r->header_only = 1; + apr_table_set(r->headers_out, "Proxy-agent: %s", ap_get_server_version()); + ap_rflush(r); +#endif + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: setting up poll()"); + + /* + * Step Four: Handle Data Transfer + * + * Handle two way transfer of data over the socket (this is a tunnel). + */ + +/* r->sent_bodyct = 1;*/ + + if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) + { + apr_socket_close(sock); + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: CONNECT: error apr_pollset_create()"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Add client side to the poll */ + pollfd.p = r->pool; + pollfd.desc_type = APR_POLL_SOCKET; + pollfd.reqevents = APR_POLLIN; + pollfd.desc.s = client_socket; + pollfd.client_data = NULL; + apr_pollset_add(pollset, &pollfd); + + /* Add the server side to the poll */ + pollfd.desc.s = sock; + apr_pollset_add(pollset, &pollfd); + + while (1) { /* Infinite loop until error (one side closes the connection) */ + if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { + apr_socket_close(sock); + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()"); + return HTTP_INTERNAL_SERVER_ERROR; + } +#ifdef DEBUGGING + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: woke from select(), i=%d", pollcnt); +#endif + + for (pi = 0; pi < pollcnt; pi++) { + const apr_pollfd_t *cur = &signalled[pi]; + + if (cur->desc.s == sock) { + pollevent = cur->rtnevents; + if (pollevent & APR_POLLIN) { +#ifdef DEBUGGING + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: sock was set"); +#endif + nbytes = sizeof(buffer); + rv = apr_socket_recv(sock, buffer, &nbytes); + if (rv == APR_SUCCESS) { + o = 0; + i = nbytes; + while(i > 0) + { + nbytes = i; + /* This is just plain wrong. No module should ever write directly + * to the client. For now, this works, but this is high on my list of + * things to fix. The correct line is: + * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0) + * rbb + */ + rv = apr_socket_send(client_socket, buffer + o, &nbytes); + if (rv != APR_SUCCESS) + break; + o += nbytes; + i -= nbytes; + } + } + else + break; + } + else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) + break; + } + else if (cur->desc.s == client_socket) { + pollevent = cur->rtnevents; + if (pollevent & APR_POLLIN) { +#ifdef DEBUGGING + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: client was set"); +#endif + nbytes = sizeof(buffer); + rv = apr_socket_recv(client_socket, buffer, &nbytes); + if (rv == APR_SUCCESS) { + o = 0; + i = nbytes; +#ifdef DEBUGGING + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: read %d from client", i); +#endif + while(i > 0) + { + nbytes = i; + rv = apr_socket_send(sock, buffer + o, &nbytes); + if (rv != APR_SUCCESS) + break; + o += nbytes; + i -= nbytes; + } + } + else + break; + } + else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) + break; + } + else + break; + } + if (rv != APR_SUCCESS) { + break; + } + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: CONNECT: finished with poll() - cleaning up"); + + /* + * Step Five: Clean Up + * + * Close the socket and clean up + */ + + apr_socket_close(sock); + + return OK; +} + +static void ap_proxy_connect_register_hook(apr_pool_t *p) +{ + proxy_hook_scheme_handler(proxy_connect_handler, NULL, NULL, APR_HOOK_MIDDLE); + proxy_hook_canon_handler(proxy_connect_canon, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA proxy_connect_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_proxy_connect_register_hook /* register hooks */ +}; diff --git a/trunk/modules/proxy/mod_proxy_connect.dsp b/trunk/modules/proxy/mod_proxy_connect.dsp new file mode 100644 index 0000000000..48ef9860d3 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_connect.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy_connect" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy_connect - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_connect.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_connect.mak" CFG="mod_proxy_connect - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy_connect - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy_connect - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy_connect - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_connect_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy_connect - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_connect_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy_connect - Win32 Release" +# Name "mod_proxy_connect - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy_connect.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy_connect - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_connect.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_connect.so "proxy_connect_module for Apache" ../../include/ap_release.h > .\mod_proxy_connect.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy_connect - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_connect.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_connect.so "proxy_connect_module for Apache" ../../include/ap_release.h > .\mod_proxy_connect.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/mod_proxy_ftp.c b/trunk/modules/proxy/mod_proxy_ftp.c new file mode 100644 index 0000000000..2d53dea13b --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_ftp.c @@ -0,0 +1,1892 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* FTP routines for Apache proxy */ + +#include "mod_proxy.h" +#if APR_HAVE_TIME_H +#include +#endif +#include "apr_version.h" + +#if (APR_MAJOR_VERSION < 1) +#undef apr_socket_create +#define apr_socket_create apr_socket_create_ex +#endif + +#define AUTODETECT_PWD +/* Automatic timestamping (Last-Modified header) based on MDTM is used if: + * 1) the FTP server supports the MDTM command and + * 2) HAVE_TIMEGM (preferred) or HAVE_GMTOFF is available at compile time + */ +#define USE_MDTM + + +module AP_MODULE_DECLARE_DATA proxy_ftp_module; + +/* + * Decodes a '%' escaped string, and returns the number of characters + */ +static int decodeenc(char *x) +{ + int i, j, ch; + + if (x[0] == '\0') + return 0; /* special case for no characters */ + for (i = 0, j = 0; x[i] != '\0'; i++, j++) { + /* decode it if not already done */ + ch = x[i]; + if (ch == '%' && apr_isxdigit(x[i + 1]) && apr_isxdigit(x[i + 2])) { + ch = ap_proxy_hex2c(&x[i + 1]); + i += 2; + } + x[j] = ch; + } + x[j] = '\0'; + return j; +} + +/* + * Escape the globbing characters in a path used as argument to + * the FTP commands (SIZE, CWD, RETR, MDTM, ...). + * ftpd assumes '\\' as a quoting character to escape special characters. + * Returns: escaped string + */ +#define FTP_GLOBBING_CHARS "*?[{~" +static char *ftp_escape_globbingchars(apr_pool_t *p, const char *path) +{ + char *ret = apr_palloc(p, 2*strlen(path)+sizeof("")); + char *d; + for (d = ret; *path; ++path) { + if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) + *d++ = '\\'; + *d++ = *path; + } + *d = '\0'; + return ret; +} + +/* + * Check for globbing characters in a path used as argument to + * the FTP commands (SIZE, CWD, RETR, MDTM, ...). + * ftpd assumes '\\' as a quoting character to escape special characters. + * Returns: 0 (no globbing chars, or all globbing chars escaped), 1 (globbing chars) + */ +static int ftp_check_globbingchars(const char *path) +{ + for ( ; *path; ++path) { + if (*path == '\\') + ++path; + if (*path != '\0' && strchr(FTP_GLOBBING_CHARS, *path) != NULL) + return TRUE; + } + return FALSE; +} + +/* + * checks an encoded ftp string for bad characters, namely, CR, LF or + * non-ascii character + */ +static int ftp_check_string(const char *x) +{ + int i, ch = 0; +#if APR_CHARSET_EBCDIC + char buf[1]; +#endif + + for (i = 0; x[i] != '\0'; i++) { + ch = x[i]; + if (ch == '%' && apr_isxdigit(x[i + 1]) && apr_isxdigit(x[i + 2])) { + ch = ap_proxy_hex2c(&x[i + 1]); + i += 2; + } +#if !APR_CHARSET_EBCDIC + if (ch == '\015' || ch == '\012' || (ch & 0x80)) +#else /* APR_CHARSET_EBCDIC */ + if (ch == '\r' || ch == '\n') + return 0; + buf[0] = ch; + ap_xlate_proto_to_ascii(buf, 1); + if (buf[0] & 0x80) +#endif /* APR_CHARSET_EBCDIC */ + return 0; + } + return 1; +} + +/* + * Canonicalise ftp URLs. + */ +static int proxy_ftp_canon(request_rec *r, char *url) +{ + char *user, *password, *host, *path, *parms, *strp, sport[7]; + apr_pool_t *p = r->pool; + const char *err; + apr_port_t port, def_port; + + /* */ + if (strncasecmp(url, "ftp:", 4) == 0) { + url += 4; + } + else { + return DECLINED; + } + def_port = apr_uri_port_of_scheme("ftp"); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: canonicalising URL %s", url); + + port = def_port; + err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port); + if (err) + return HTTP_BAD_REQUEST; + if (user != NULL && !ftp_check_string(user)) + return HTTP_BAD_REQUEST; + if (password != NULL && !ftp_check_string(password)) + return HTTP_BAD_REQUEST; + + /* now parse path/parameters args, according to rfc1738 */ + /* + * N.B. if this isn't a true proxy request, then the URL path (but not + * query args) has already been decoded. This gives rise to the problem + * of a ; being decoded into the path. + */ + strp = strchr(url, ';'); + if (strp != NULL) { + *(strp++) = '\0'; + parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm, 0, + r->proxyreq); + if (parms == NULL) + return HTTP_BAD_REQUEST; + } + else + parms = ""; + + path = ap_proxy_canonenc(p, url, strlen(url), enc_path, 0, r->proxyreq); + if (path == NULL) + return HTTP_BAD_REQUEST; + if (!ftp_check_string(path)) + return HTTP_BAD_REQUEST; + + if (r->proxyreq && r->args != NULL) { + if (strp != NULL) { + strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, 1, r->proxyreq); + if (strp == NULL) + return HTTP_BAD_REQUEST; + parms = apr_pstrcat(p, parms, "?", strp, NULL); + } + else { + strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, 1, r->proxyreq); + if (strp == NULL) + return HTTP_BAD_REQUEST; + path = apr_pstrcat(p, path, "?", strp, NULL); + } + r->args = NULL; + } + +/* now, rebuild URL */ + + if (port != def_port) + apr_snprintf(sport, sizeof(sport), ":%d", port); + else + sport[0] = '\0'; + + if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ + host = apr_pstrcat(p, "[", host, "]", NULL); + } + r->filename = apr_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "", + (password != NULL) ? ":" : "", + (password != NULL) ? password : "", + (user != NULL) ? "@" : "", host, sport, "/", path, + (parms[0] != '\0') ? ";" : "", parms, NULL); + + return OK; +} + +/* we chop lines longer than 80 characters */ +#define MAX_LINE_LEN 80 + +/* + * Reads response lines, returns both the ftp status code and + * remembers the response message in the supplied buffer + */ +static int ftp_getrc_msg(conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char *msgbuf, int msglen) +{ + int status; + char response[MAX_LINE_LEN]; + char buff[5]; + char *mb = msgbuf, *me = &msgbuf[msglen]; + apr_status_t rv; + int eos; + + if (APR_SUCCESS != (rv = ap_proxy_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) { + return -1; + } +/* + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "proxy: r; + conn_rec *c = r->connection; + apr_pool_t *p = r->pool; + apr_bucket_brigade *out = apr_brigade_create(p, c->bucket_alloc); + apr_status_t rv; + + register int n; + char *dir, *path, *reldir, *site, *str, *type; + + const char *pwd = apr_table_get(r->notes, "Directory-PWD"); + const char *readme = apr_table_get(r->notes, "Directory-README"); + + proxy_dir_ctx_t *ctx = f->ctx; + + if (!ctx) { + f->ctx = ctx = apr_pcalloc(p, sizeof(*ctx)); + ctx->in = apr_brigade_create(p, c->bucket_alloc); + ctx->buffer[0] = 0; + ctx->state = HEADER; + } + + /* combine the stored and the new */ + APR_BRIGADE_CONCAT(ctx->in, in); + + if (HEADER == ctx->state) { + + /* basedir is either "", or "/%2f" for the "squid %2f hack" */ + const char *basedir = ""; /* By default, path is relative to the $HOME dir */ + char *wildcard = NULL; + + /* Save "scheme://site" prefix without password */ + site = apr_uri_unparse(p, &f->r->parsed_uri, APR_URI_UNP_OMITPASSWORD | APR_URI_UNP_OMITPATHINFO); + /* ... and path without query args */ + path = apr_uri_unparse(p, &f->r->parsed_uri, APR_URI_UNP_OMITSITEPART | APR_URI_UNP_OMITQUERY); + + /* If path began with /%2f, change the basedir */ + if (strncasecmp(path, "/%2f", 4) == 0) { + basedir = "/%2f"; + } + + /* Strip off a type qualifier. It is ignored for dir listings */ + if ((type = strstr(path, ";type=")) != NULL) + *type++ = '\0'; + + (void)decodeenc(path); + + while (path[1] == '/') /* collapse multiple leading slashes to one */ + ++path; + + reldir = strrchr(path, '/'); + if (reldir != NULL && ftp_check_globbingchars(reldir)) { + wildcard = &reldir[1]; + reldir[0] = '\0'; /* strip off the wildcard suffix */ + } + + /* Copy path, strip (all except the last) trailing slashes */ + /* (the trailing slash is needed for the dir component loop below) */ + path = dir = apr_pstrcat(p, path, "/", NULL); + for (n = strlen(path); n > 1 && path[n - 1] == '/' && path[n - 2] == '/'; --n) + path[n - 1] = '\0'; + + /* Add a link to the root directory (if %2f hack was used) */ + str = (basedir[0] != '\0') ? "%2f/" : ""; + + /* print "ftp://host/" */ + str = apr_psprintf(p, DOCTYPE_HTML_3_2 + "\n \n %s%s%s\n" + " \n \n" + " \n

    Directory of " + "%s/%s", + site, basedir, ap_escape_html(p, path), + site, basedir, ap_escape_uri(p, path), + site, str); + + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), + p, c->bucket_alloc)); + + for (dir = path+1; (dir = strchr(dir, '/')) != NULL; ) + { + *dir = '\0'; + if ((reldir = strrchr(path+1, '/'))==NULL) { + reldir = path+1; + } + else + ++reldir; + /* print "path/" component */ + str = apr_psprintf(p, "%s/", basedir, + ap_escape_uri(p, path), + ap_escape_html(p, reldir)); + *dir = '/'; + while (*dir == '/') + ++dir; + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, + strlen(str), p, + c->bucket_alloc)); + } + if (wildcard != NULL) { + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(wildcard, + strlen(wildcard), p, + c->bucket_alloc)); + } + + /* If the caller has determined the current directory, and it differs */ + /* from what the client requested, then show the real name */ + if (pwd == NULL || strncmp(pwd, path, strlen(pwd)) == 0) { + str = apr_psprintf(p, "

    \n\n
    \n\n
    ");
    +        }
    +        else {
    +            str = apr_psprintf(p, "\n\n(%s)\n\n  
    \n\n
    ",
    +                               ap_escape_html(p, pwd));
    +        }
    +        APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str),
    +                                                           p, c->bucket_alloc));
    +
    +        /* print README */
    +        if (readme) {
    +            str = apr_psprintf(p, "%s\n
    \n\n
    \n\n
    \n",
    +                               ap_escape_html(p, readme));
    +
    +            APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str,
    +                                                           strlen(str), p,
    +                                                           c->bucket_alloc));
    +        }
    +
    +        /* make sure page intro gets sent out */
    +        APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc));
    +        if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) {
    +            return rv;
    +        }
    +        apr_brigade_cleanup(out);
    +
    +        ctx->state = BODY;
    +    }
    +
    +    /* loop through each line of directory */
    +    while (BODY == ctx->state) {
    +        char *filename;
    +        int found = 0;
    +        int eos = 0;
    +
    +        ap_regex_t *re = NULL;
    +        ap_regmatch_t re_result[LS_REG_MATCH];
    +
    +        /* Compile the output format of "ls -s1" as a fallback for non-unix ftp listings */
    +        re = ap_pregcomp(p, LS_REG_PATTERN, AP_REG_EXTENDED);
    +        ap_assert(re != NULL);
    +
    +        /* get a complete line */
    +        /* if the buffer overruns - throw data away */
    +        while (!found && !APR_BRIGADE_EMPTY(ctx->in)) {
    +            char *pos, *response;
    +            apr_size_t len, max;
    +            apr_bucket *e;
    +
    +            e = APR_BRIGADE_FIRST(ctx->in);
    +            if (APR_BUCKET_IS_EOS(e)) {
    +                eos = 1;
    +                break;
    +            }
    +            if (APR_SUCCESS != (rv = apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ))) {
    +                return rv;
    +            }
    +            pos = memchr(response, APR_ASCII_LF, len);
    +            if (pos != NULL) {
    +                if ((response + len) != (pos + 1)) {
    +                    len = pos - response + 1;
    +                    apr_bucket_split(e, pos - response + 1);
    +                }
    +                found = 1;
    +            }
    +            max = sizeof(ctx->buffer) - strlen(ctx->buffer) - 1;
    +            if (len > max) {
    +                len = max;
    +            }
    +
    +            /* len+1 to leave space for the trailing nil char */
    +            apr_cpystrn(ctx->buffer+strlen(ctx->buffer), response, len+1);
    +
    +            APR_BUCKET_REMOVE(e);
    +            apr_bucket_destroy(e);
    +        }
    +
    +        /* EOS? jump to footer */
    +        if (eos) {
    +            ctx->state = FOOTER;
    +            break;
    +        }
    +
    +        /* not complete? leave and try get some more */
    +        if (!found) {
    +            return APR_SUCCESS;
    +        }
    +
    +        {
    +            apr_size_t n = strlen(ctx->buffer);
    +            if (ctx->buffer[n-1] == CRLF[1])  /* strip trailing '\n' */
    +                ctx->buffer[--n] = '\0';
    +            if (ctx->buffer[n-1] == CRLF[0])  /* strip trailing '\r' if present */
    +                ctx->buffer[--n] = '\0';
    +        }
    +
    +        /* a symlink? */
    +        if (ctx->buffer[0] == 'l' && (filename = strstr(ctx->buffer, " -> ")) != NULL) {
    +            char *link_ptr = filename;
    +
    +            do {
    +                filename--;
    +            } while (filename[0] != ' ' && filename > ctx->buffer);
    +            if (filename > ctx->buffer)
    +                *(filename++) = '\0';
    +            *(link_ptr++) = '\0';
    +            str = apr_psprintf(p, "%s %s %s\n",
    +                               ap_escape_html(p, ctx->buffer),
    +                               ap_escape_uri(p, filename),
    +                               ap_escape_html(p, filename),
    +                               ap_escape_html(p, link_ptr));
    +        }
    +
    +        /* a directory/file? */
    +        else if (ctx->buffer[0] == 'd' || ctx->buffer[0] == '-' || ctx->buffer[0] == 'l' || apr_isdigit(ctx->buffer[0])) {
    +            int searchidx = 0;
    +            char *searchptr = NULL;
    +            int firstfile = 1;
    +            if (apr_isdigit(ctx->buffer[0])) {  /* handle DOS dir */
    +                searchptr = strchr(ctx->buffer, '<');
    +                if (searchptr != NULL)
    +                    *searchptr = '[';
    +                searchptr = strchr(ctx->buffer, '>');
    +                if (searchptr != NULL)
    +                    *searchptr = ']';
    +            }
    +
    +            filename = strrchr(ctx->buffer, ' ');
    +            *(filename++) = '\0';
    +
    +            /* handle filenames with spaces in 'em */
    +            if (!strcmp(filename, ".") || !strcmp(filename, "..") || firstfile) {
    +                firstfile = 0;
    +                searchidx = filename - ctx->buffer;
    +            }
    +            else if (searchidx != 0 && ctx->buffer[searchidx] != 0) {
    +                *(--filename) = ' ';
    +                ctx->buffer[searchidx - 1] = '\0';
    +                filename = &ctx->buffer[searchidx];
    +            }
    +
    +            /* Append a slash to the HREF link for directories */
    +            if (!strcmp(filename, ".") || !strcmp(filename, "..") || ctx->buffer[0] == 'd') {
    +                str = apr_psprintf(p, "%s %s\n",
    +                                   ap_escape_html(p, ctx->buffer),
    +                                   ap_escape_uri(p, filename),
    +                                   ap_escape_html(p, filename));
    +            }
    +            else {
    +                str = apr_psprintf(p, "%s %s\n",
    +                                   ap_escape_html(p, ctx->buffer),
    +                                   ap_escape_uri(p, filename),
    +                                   ap_escape_html(p, filename));
    +            }
    +        }
    +        /* Try a fallback for listings in the format of "ls -s1" */
    +        else if (0 == ap_regexec(re, ctx->buffer, LS_REG_MATCH, re_result, 0)) {
    +
    +            filename = apr_pstrndup(p, &ctx->buffer[re_result[2].rm_so], re_result[2].rm_eo - re_result[2].rm_so);
    +
    +            str = apr_pstrcat(p, ap_escape_html(p, apr_pstrndup(p, ctx->buffer, re_result[2].rm_so)),
    +                              "",
    +                              ap_escape_html(p, filename), "\n", NULL);
    +        }
    +        else {
    +            strcat(ctx->buffer, "\n"); /* re-append the newline */
    +            str = ap_escape_html(p, ctx->buffer);
    +        }
    +
    +        /* erase buffer for next time around */
    +        ctx->buffer[0] = 0;
    +
    +        APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), p,
    +                                                            c->bucket_alloc));
    +        APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc));
    +        if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) {
    +            return rv;
    +        }
    +        apr_brigade_cleanup(out);
    +
    +    }
    +
    +    if (FOOTER == ctx->state) {
    +        str = apr_psprintf(p, "
    \n\n
    \n\n %s\n\n \n\n", ap_psignature("", r)); + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), p, + c->bucket_alloc)); + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc)); + APR_BRIGADE_INSERT_TAIL(out, apr_bucket_eos_create(c->bucket_alloc)); + if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) { + return rv; + } + apr_brigade_destroy(out); + } + + return APR_SUCCESS; +} + +/* + * Generic "send FTP command to server" routine, using the control socket. + * Returns the FTP returncode (3 digit code) + * Allows for tracing the FTP protocol (in LogLevel debug) + */ +static int +proxy_ftp_command(const char *cmd, request_rec *r, conn_rec *ftp_ctrl, + apr_bucket_brigade *bb, char **pmessage) +{ + char *crlf; + int rc; + char message[HUGE_STRING_LEN]; + + /* If cmd == NULL, we retrieve the next ftp response line */ + if (cmd != NULL) { + conn_rec *c = r->connection; + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(cmd, strlen(cmd), r->pool, c->bucket_alloc)); + APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc)); + ap_pass_brigade(ftp_ctrl->output_filters, bb); + + /* strip off the CRLF for logging */ + apr_cpystrn(message, cmd, sizeof(message)); + if ((crlf = strchr(message, '\r')) != NULL || + (crlf = strchr(message, '\n')) != NULL) + *crlf = '\0'; + if (strncmp(message,"PASS ", 5) == 0) + strcpy(&message[5], "****"); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy:>FTP: %s", message); + } + + rc = ftp_getrc_msg(ftp_ctrl, bb, message, sizeof message); + if (rc == -1 || rc == 421) + strcpy(message,""); + if ((crlf = strchr(message, '\r')) != NULL || + (crlf = strchr(message, '\n')) != NULL) + *crlf = '\0'; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy:pool, message); + + return rc; +} + +/* Set ftp server to TYPE {A,I,E} before transfer of a directory or file */ +static int ftp_set_TYPE(char xfer_type, request_rec *r, conn_rec *ftp_ctrl, + apr_bucket_brigade *bb, char **pmessage) +{ + char old_type[2] = { 'A', '\0' }; /* After logon, mode is ASCII */ + int ret = HTTP_OK; + int rc; + + /* set desired type */ + old_type[0] = xfer_type; + + rc = proxy_ftp_command(apr_pstrcat(r->pool, "TYPE ", old_type, CRLF, NULL), + r, ftp_ctrl, bb, pmessage); +/* responses: 200, 421, 500, 501, 504, 530 */ + /* 200 Command okay. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 504 Command not implemented for that parameter. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + ret = ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + else if (rc != 200 && rc != 504) { + ret = ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Unable to set transfer type"); + } +/* Allow not implemented */ + else if (rc == 504) + /* ignore it silently */; + + return ret; +} + + +/* Return the current directory which we have selected on the FTP server, or NULL */ +static char *ftp_get_PWD(request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb) +{ + char *cwd = NULL; + char *ftpmessage = NULL; + + /* responses: 257, 500, 501, 502, 421, 550 */ + /* 257 "" */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 550 Requested action not taken. */ + switch (proxy_ftp_command("PWD" CRLF, r, ftp_ctrl, bb, &ftpmessage)) { + case -1: + case 421: + case 550: + ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Failed to read PWD on ftp server"); + break; + + case 257: { + const char *dirp = ftpmessage; + cwd = ap_getword_conf(r->pool, &dirp); + } + } + return cwd; +} + + +/* Common routine for failed authorization (i.e., missing or wrong password) + * to an ftp service. This causes most browsers to retry the request + * with username and password (which was presumably queried from the user) + * supplied in the Authorization: header. + * Note that we "invent" a realm name which consists of the + * ftp://user@host part of the reqest (sans password -if supplied but invalid-) + */ +static int ftp_unauthorized(request_rec *r, int log_it) +{ + r->proxyreq = PROXYREQ_NONE; + /* + * Log failed requests if they supplied a password (log username/password + * guessing attempts) + */ + if (log_it) + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "proxy: missing or failed auth to %s", + apr_uri_unparse(r->pool, + &r->parsed_uri, APR_URI_UNP_OMITPATHINFO)); + + apr_table_setn(r->err_headers_out, "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", + apr_uri_unparse(r->pool, &r->parsed_uri, + APR_URI_UNP_OMITPASSWORD | APR_URI_UNP_OMITPATHINFO), + "\"", NULL)); + + return HTTP_UNAUTHORIZED; +} + +static +apr_status_t proxy_ftp_cleanup(request_rec *r, proxy_conn_rec *backend) +{ + + backend->close_on_recycle = 1; + ap_set_module_config(r->connection->conn_config, &proxy_ftp_module, NULL); + ap_proxy_release_connection("FTP", backend, r->server); + + return OK; +} + +static +int ftp_proxyerror(request_rec *r, proxy_conn_rec *conn, int statuscode, const char *message) +{ + proxy_ftp_cleanup(r, conn); + return ap_proxyerror(r, statuscode, message); +} +/* + * Handles direct access of ftp:// URLs + * Original (Non-PASV) version from + * Troy Morrison + * PASV added by Chuck + * Filters by [Graham Leggett ] + */ +static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, char *url, + const char *proxyhost, apr_port_t proxyport) +{ + apr_pool_t *p = r->pool; + conn_rec *c = r->connection; + proxy_conn_rec *backend; + apr_socket_t *sock, *local_sock, *data_sock = NULL; + apr_sockaddr_t *connect_addr = NULL; + apr_status_t rv; + conn_rec *origin, *data = NULL; + apr_status_t err = APR_SUCCESS; + apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); + char *buf, *connectname; + apr_port_t connectport; + char buffer[MAX_STRING_LEN]; + char *ftpmessage = NULL; + char *path, *strp, *type_suffix, *cwd = NULL; + apr_uri_t uri; + char *user = NULL; +/* char *account = NULL; how to supply an account in a URL? */ + const char *password = NULL; + int len, rc; + int one = 1; + char *size = NULL; + char xfer_type = 'A'; /* after ftp login, the default is ASCII */ + int dirlisting = 0; +#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) + apr_time_t mtime = 0L; +#endif + + /* stuff for PASV mode */ + int connect = 0, use_port = 0; + char dates[APR_RFC822_DATE_LEN]; + int status; + apr_pool_t *address_pool; + + /* is this for us? */ + if (proxyhost) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: declining URL %s - proxyhost %s specified:", url, proxyhost); + return DECLINED; /* proxy connections are via HTTP */ + } + if (strncasecmp(url, "ftp:", 4)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: declining URL %s - not ftp:", url); + return DECLINED; /* only interested in FTP */ + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: serving URL %s", url); + + + /* + * I: Who Do I Connect To? ----------------------- + * + * Break up the URL to determine the host to connect to + */ + + /* we only support GET and HEAD */ + if (r->method_number != M_GET) + return HTTP_NOT_IMPLEMENTED; + + /* We break the URL into host, port, path-search */ + if (r->parsed_uri.hostname == NULL) { + if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, + apr_psprintf(p, "URI cannot be parsed: %s", url)); + } + connectname = uri.hostname; + connectport = uri.port; + path = apr_pstrdup(p, uri.path); + } + else { + connectname = r->parsed_uri.hostname; + connectport = r->parsed_uri.port; + path = apr_pstrdup(p, r->parsed_uri.path); + } + if (connectport == 0) { + connectport = apr_uri_port_of_scheme("ftp"); + } + path = (path != NULL && path[0] != '\0') ? &path[1] : ""; + + type_suffix = strchr(path, ';'); + if (type_suffix != NULL) + *(type_suffix++) = '\0'; + + if (type_suffix != NULL && strncmp(type_suffix, "type=", 5) == 0 + && apr_isalpha(type_suffix[5])) { + /* "type=d" forces a dir listing. + * The other types (i|a|e) are directly used for the ftp TYPE command + */ + if ( ! (dirlisting = (apr_tolower(type_suffix[5]) == 'd'))) + xfer_type = apr_toupper(type_suffix[5]); + + /* Check valid types, rather than ignoring invalid types silently: */ + if (strchr("AEI", xfer_type) == NULL) + return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r->pool, + "ftp proxy supports only types 'a', 'i', or 'e': \"", + type_suffix, "\" is invalid.", NULL)); + } + else { + /* make binary transfers the default */ + xfer_type = 'I'; + } + + + /* + * The "Authorization:" header must be checked first. We allow the user + * to "override" the URL-coded user [ & password ] in the Browsers' + * User&Password Dialog. NOTE that this is only marginally more secure + * than having the password travel in plain as part of the URL, because + * Basic Auth simply uuencodes the plain text password. But chances are + * still smaller that the URL is logged regularly. + */ + if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL + && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0 + && (password = ap_pbase64decode(r->pool, password))[0] != ':') { + /* + * Note that this allocation has to be made from r->connection->pool + * because it has the lifetime of the connection. The other + * allocations are temporary and can be tossed away any time. + */ + user = ap_getword_nulls(r->connection->pool, &password, ':'); + r->ap_auth_type = "Basic"; + r->user = r->parsed_uri.user = user; + } + else if ((user = r->parsed_uri.user) != NULL) { + user = apr_pstrdup(p, user); + decodeenc(user); + if ((password = r->parsed_uri.password) != NULL) { + char *tmp = apr_pstrdup(p, password); + decodeenc(tmp); + password = tmp; + } + } + else { + user = "anonymous"; + password = "apache-proxy@"; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: connecting %s to %s:%d", url, connectname, connectport); + + if (worker->is_address_reusable) { + if (!worker->cp->addr) { + if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, + "proxy: FTP: lock"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + connect_addr = worker->cp->addr; + address_pool = worker->cp->pool; + } + else + address_pool = r->pool; + + /* do a DNS lookup for the destination host */ + if (!connect_addr) + err = apr_sockaddr_info_get(&(connect_addr), + connectname, APR_UNSPEC, + connectport, 0, + address_pool); + if (worker->is_address_reusable && !worker->cp->addr) { + worker->cp->addr = connect_addr; + PROXY_THREAD_UNLOCK(worker); + } + /* + * get all the possible IP addresses for the destname and loop through + * them until we get a successful connection + */ + if (APR_SUCCESS != err) { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, + "DNS lookup failure for: ", + connectname, NULL)); + } + + /* check if ProxyBlock directive on this host */ + if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) { + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); + } + + /* create space for state information */ + backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, &proxy_ftp_module); + if (!backend) { + status = ap_proxy_acquire_connection("FTP", &backend, worker, r->server); + if (status != OK) { + if (backend) { + backend->close_on_recycle = 1; + ap_proxy_release_connection("FTP", backend, r->server); + } + return status; + } + /* TODO: see if ftp could use determine_connection */ + backend->addr = connect_addr; + ap_set_module_config(c->conn_config, &proxy_ftp_module, backend); + } + + + /* + * II: Make the Connection ----------------------- + * + * We have determined who to connect to. Now make the connection. + */ + + + if (ap_proxy_connect_backend("FTP", backend, worker, r->server)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: an error occurred creating a new connection to %pI (%s)", + connect_addr, connectname); + proxy_ftp_cleanup(r, backend); + return HTTP_SERVICE_UNAVAILABLE; + } + + if (!backend->connection) { + status = ap_proxy_connection_create("FTP", backend, c, r->server); + if (status != OK) { + proxy_ftp_cleanup(r, backend); + return status; + } + } + + /* Use old naming */ + origin = backend->connection; + sock = backend->sock; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: control connection complete"); + + + /* + * III: Send Control Request ------------------------- + * + * Log into the ftp server, send the username & password, change to the + * correct directory... + */ + + + /* possible results: */ + /* 120 Service ready in nnn minutes. */ + /* 220 Service ready for new user. */ + /* 421 Service not available, closing control connection. */ + rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage); + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, "Error reading from remote server"); + } + if (rc == 120) { + /* + * RFC2616 states: 14.37 Retry-After + * + * The Retry-After response-header field can be used with a 503 (Service + * Unavailable) response to indicate how long the service is expected + * to be unavailable to the requesting client. [...] The value of + * this field can be either an HTTP-date or an integer number of + * seconds (in decimal) after the time of the response. Retry-After + * = "Retry-After" ":" ( HTTP-date | delta-seconds ) + */ + char *secs_str = ftpmessage; + time_t secs; + + /* Look for a number, preceded by whitespace */ + while (*secs_str) + if ((secs_str==ftpmessage || apr_isspace(secs_str[-1])) && + apr_isdigit(secs_str[0])) + break; + if (*secs_str != '\0') { + secs = atol(secs_str); + apr_table_add(r->headers_out, "Retry-After", + apr_psprintf(p, "%lu", (unsigned long)(60 * secs))); + } + return ftp_proxyerror(r, backend, HTTP_SERVICE_UNAVAILABLE, ftpmessage); + } + if (rc != 220) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + + rc = proxy_ftp_command(apr_pstrcat(p, "USER ", user, CRLF, NULL), + r, origin, bb, &ftpmessage); + /* possible results; 230, 331, 332, 421, 500, 501, 530 */ + /* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */ + /* 230 User logged in, proceed. */ + /* 331 User name okay, need password. */ + /* 332 Need account for login. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* (This may include errors such as command line too long.) */ + /* 501 Syntax error in parameters or arguments. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, "Error reading from remote server"); + } + if (rc == 530) { + proxy_ftp_cleanup(r, backend); + return ftp_unauthorized(r, 1); /* log it: user name guessing + * attempt? */ + } + if (rc != 230 && rc != 331) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + + if (rc == 331) { /* send password */ + if (password == NULL) { + proxy_ftp_cleanup(r, backend); + return ftp_unauthorized(r, 0); + } + + rc = proxy_ftp_command(apr_pstrcat(p, "PASS ", password, CRLF, NULL), + r, origin, bb, &ftpmessage); + /* possible results 202, 230, 332, 421, 500, 501, 503, 530 */ + /* 230 User logged in, proceed. */ + /* 332 Need account for login. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 503 Bad sequence of commands. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc == 332) { + return ftp_proxyerror(r, backend, HTTP_UNAUTHORIZED, + apr_pstrcat(p, "Need account for login: ", ftpmessage, NULL)); + } + /* @@@ questionable -- we might as well return a 403 Forbidden here */ + if (rc == 530) { + proxy_ftp_cleanup(r, backend); + return ftp_unauthorized(r, 1); /* log it: passwd guessing + * attempt? */ + } + if (rc != 230 && rc != 202) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + } + apr_table_set(r->notes, "Directory-README", ftpmessage); + + + /* Special handling for leading "%2f": this enforces a "cwd /" + * out of the $HOME directory which was the starting point after login + */ + if (strncasecmp(path, "%2f", 3) == 0) { + path += 3; + while (*path == '/') /* skip leading '/' (after root %2f) */ + ++path; + + rc = proxy_ftp_command("CWD /" CRLF, r, origin, bb, &ftpmessage); + if (rc == -1 || rc == 421) + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + + /* + * set the directory (walk directory component by component): this is + * what we must do if we don't know the OS type of the remote machine + */ + for (;;) { + strp = strchr(path, '/'); + if (strp == NULL) + break; + *strp = '\0'; + + len = decodeenc(path); /* Note! This decodes a %2f -> "/" */ + + if (strchr(path, '/')) { /* are there now any '/' characters? */ + return ftp_proxyerror(r, backend, HTTP_BAD_REQUEST, + "Use of /%2f is only allowed at the base directory"); + } + + /* NOTE: FTP servers do globbing on the path. + * So we need to escape the URI metacharacters. + * We use a special glob-escaping routine to escape globbing chars. + * We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH + */ + rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", + ftp_escape_globbingchars(p, path), CRLF, NULL), + r, origin, bb, &ftpmessage); + *strp = '/'; + /* responses: 250, 421, 500, 501, 502, 530, 550 */ + /* 250 Requested file action okay, completed. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + /* 550 Requested action not taken. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc == 550) { + return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage); + } + if (rc != 250) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + + path = strp + 1; + } + + /* + * IV: Make Data Connection? ------------------------- + * + * Try EPSV, if that fails... try PASV, if that fails... try PORT. + */ +/* this temporarily switches off EPSV/PASV */ +/*goto bypass;*/ + + /* set up data connection - EPSV */ + { + apr_sockaddr_t *data_addr; + char *data_ip; + apr_port_t data_port; + + /* + * The EPSV command replaces PASV where both IPV4 and IPV6 is + * supported. Only the port is returned, the IP address is always the + * same as that on the control connection. Example: Entering Extended + * Passive Mode (|||6446|) + */ + rc = proxy_ftp_command("EPSV" CRLF, + r, origin, bb, &ftpmessage); + /* possible results: 227, 421, 500, 501, 502, 530 */ + /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc != 229 && rc != 500 && rc != 501 && rc != 502) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + else if (rc == 229) { + char *pstr; + char *tok_cntx; + + pstr = ftpmessage; + pstr = apr_strtok(pstr, " ", &tok_cntx); /* separate result code */ + if (pstr != NULL) { + if (*(pstr + strlen(pstr) + 1) == '=') { + pstr += strlen(pstr) + 2; + } + else { + pstr = apr_strtok(NULL, "(", &tok_cntx); /* separate address & + * port params */ + if (pstr != NULL) + pstr = apr_strtok(NULL, ")", &tok_cntx); + } + } + + if (pstr) { + apr_sockaddr_t *epsv_addr; + data_port = atoi(pstr + 3); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: EPSV contacting remote host on port %d", + data_port); + + if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error creating EPSV socket"); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + +#if !defined (TPF) && !defined(BEOS) + if (conf->recv_buffer_size > 0 + && (rv = apr_socket_opt_set(data_sock, APR_SO_RCVBUF, + conf->recv_buffer_size))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); + } +#endif + + /* make the connection */ + apr_socket_addr_get(&data_addr, APR_REMOTE, sock); + apr_sockaddr_ip_get(&data_ip, data_addr); + apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p); + rv = apr_socket_connect(data_sock, epsv_addr); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "proxy: FTP: EPSV attempt to connect to %pI failed - Firewall/NAT?", epsv_addr); + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, apr_psprintf(r->pool, + "EPSV attempt to connect to %pI failed - firewall/NAT?", epsv_addr)); + } + else { + connect = 1; + } + } + else { + /* and try the regular way */ + apr_socket_close(data_sock); + } + } + } + + /* set up data connection - PASV */ + if (!connect) { + rc = proxy_ftp_command("PASV" CRLF, + r, origin, bb, &ftpmessage); + /* possible results: 227, 421, 500, 501, 502, 530 */ + /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc != 227 && rc != 502) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + else if (rc == 227) { + unsigned int h0, h1, h2, h3, p0, p1; + char *pstr; + char *tok_cntx; + +/* FIXME: Check PASV against RFC1123 */ + + pstr = ftpmessage; + pstr = apr_strtok(pstr, " ", &tok_cntx); /* separate result code */ + if (pstr != NULL) { + if (*(pstr + strlen(pstr) + 1) == '=') { + pstr += strlen(pstr) + 2; + } + else { + pstr = apr_strtok(NULL, "(", &tok_cntx); /* separate address & + * port params */ + if (pstr != NULL) + pstr = apr_strtok(NULL, ")", &tok_cntx); + } + } + +/* FIXME: Only supports IPV4 - fix in RFC2428 */ + + if (pstr != NULL && (sscanf(pstr, + "%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) { + + apr_sockaddr_t *pasv_addr; + apr_port_t pasvport = (p1 << 8) + p0; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d", + h3, h2, h1, h0, pasvport); + + if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: error creating PASV socket"); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + +#if !defined (TPF) && !defined(BEOS) + if (conf->recv_buffer_size > 0 + && (rv = apr_socket_opt_set(data_sock, APR_SO_RCVBUF, + conf->recv_buffer_size))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); + } +#endif + + /* make the connection */ + apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), connect_addr->family, pasvport, 0, p); + rv = apr_socket_connect(data_sock, pasv_addr); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, + "proxy: FTP: PASV attempt to connect to %pI failed - Firewall/NAT?", pasv_addr); + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, apr_psprintf(r->pool, + "PASV attempt to connect to %pI failed - firewall/NAT?", pasv_addr)); + } + else { + connect = 1; + } + } + else { + /* and try the regular way */ + apr_socket_close(data_sock); + } + } + } +/*bypass:*/ + + /* set up data connection - PORT */ + if (!connect) { + apr_sockaddr_t *local_addr; + char *local_ip; + apr_port_t local_port; + unsigned int h0, h1, h2, h3, p0, p1; + + if ((rv = apr_socket_create(&local_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error creating local socket"); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + apr_socket_addr_get(&local_addr, APR_LOCAL, sock); + local_port = local_addr->port; + apr_sockaddr_ip_get(&local_ip, local_addr); + + if ((rv = apr_socket_opt_set(local_sock, APR_SO_REUSEADDR, one)) + != APR_SUCCESS) { +#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error setting reuseaddr option"); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; +#endif /* _OSD_POSIX */ + } + + apr_sockaddr_info_get(&local_addr, local_ip, APR_UNSPEC, local_port, 0, r->pool); + + if ((rv = apr_socket_bind(local_sock, local_addr)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error binding to ftp data socket %pI", local_addr); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* only need a short queue */ + if ((rv = apr_socket_listen(local_sock, 2)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error listening to ftp data socket %pI", local_addr); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + +/* FIXME: Sent PORT here */ + + if (local_ip && (sscanf(local_ip, + "%d.%d.%d.%d", &h3, &h2, &h1, &h0) == 4)) { + p1 = (local_port >> 8); + p0 = (local_port & 0xFF); + + rc = proxy_ftp_command(apr_psprintf(p, "PORT %d,%d,%d,%d,%d,%d" CRLF, h3, h2, h1, h0, p1, p0), + r, origin, bb, &ftpmessage); + /* possible results: 200, 421, 500, 501, 502, 530 */ + /* 200 Command okay. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc != 200) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, buffer); + } + + /* signal that we must use the EPRT/PORT loop */ + use_port = 1; + } + else { +/* IPV6 FIXME: + * The EPRT command replaces PORT where both IPV4 and IPV6 is supported. The first + * number (1,2) indicates the protocol type. Examples: + * EPRT |1|132.235.1.2|6275| + * EPRT |2|1080::8:800:200C:417A|5282| + */ + return ftp_proxyerror(r, backend, HTTP_NOT_IMPLEMENTED, + "Connect to IPV6 ftp server using EPRT not supported. Enable EPSV."); + } + } + + + /* + * V: Set The Headers ------------------- + * + * Get the size of the request, set up the environment for HTTP. + */ + + /* set request; "path" holds last path component */ + len = decodeenc(path); + + if (strchr(path, '/')) { /* are there now any '/' characters? */ + return ftp_proxyerror(r, backend, HTTP_BAD_REQUEST, + "Use of /%2f is only allowed at the base directory"); + } + + /* If len == 0 then it must be a directory (you can't RETR nothing) + * Also, don't allow to RETR by wildcard. Instead, create a dirlisting + */ + if (len == 0 || ftp_check_globbingchars(path)) { + dirlisting = 1; + } + else { + /* (from FreeBSD ftpd): + * SIZE is not in RFC959, but Postel has blessed it and + * it will be in the updated RFC. + * + * Return size of file in a format suitable for + * using with RESTART (we just count bytes). + */ + /* from draft-ietf-ftpext-mlst-14.txt: + * This value will + * change depending on the current STRUcture, MODE and TYPE of the data + * connection, or a data connection which would be created were one + * created now. Thus, the result of the SIZE command is dependent on + * the currently established STRU, MODE and TYPE parameters. + */ + /* Therefore: switch to binary if the user did not specify ";type=a" */ + ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); + rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", + ftp_escape_globbingchars(p, path), CRLF, NULL), + r, origin, bb, &ftpmessage); + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + else if (rc == 213) {/* Size command ok */ + int j; + for (j = 0; apr_isdigit(ftpmessage[j]); j++) + ; + ftpmessage[j] = '\0'; + if (ftpmessage[0] != '\0') + size = ftpmessage; /* already pstrdup'ed: no copy necessary */ + } + else if (rc == 550) { /* Not a regular file */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: SIZE shows this is a directory"); + dirlisting = 1; + rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", + ftp_escape_globbingchars(p, path), CRLF, NULL), + r, origin, bb, &ftpmessage); + /* possible results: 250, 421, 500, 501, 502, 530, 550 */ + /* 250 Requested file action okay, completed. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + /* 550 Requested action not taken. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc == 550) { + return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage); + } + if (rc != 250) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + path = ""; + len = 0; + } + } + + cwd = ftp_get_PWD(r, origin, bb); + if (cwd != NULL) { + apr_table_set(r->notes, "Directory-PWD", cwd); + } + + if (dirlisting) { + ftp_set_TYPE('A', r, origin, bb, NULL); + /* If the current directory contains no slash, we are talking to + * a non-unix ftp system. Try LIST instead of "LIST -lag", it + * should return a long listing anyway (unlike NLST). + * Some exotic FTP servers might choke on the "-lag" switch. + */ + /* Note that we do not escape the path here, to allow for + * queries like: ftp://user@host/apache/src/server/http_*.c + */ + if (len != 0) + buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL); + else if (cwd == NULL || strchr(cwd, '/') != NULL) + buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL); + else + buf = "LIST" CRLF; + } + else { + /* switch to binary if the user did not specify ";type=a" */ + ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); +#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) + /* from draft-ietf-ftpext-mlst-14.txt: + * The FTP command, MODIFICATION TIME (MDTM), can be used to determine + * when a file in the server NVFS was last modified. <..> + * The syntax of a time value is: + * time-val = 14DIGIT [ "." 1*DIGIT ] <..> + * Symbolically, a time-val may be viewed as + * YYYYMMDDHHMMSS.sss + * The "." and subsequent digits ("sss") are optional. <..> + * Time values are always represented in UTC (GMT) + */ + rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path), CRLF, NULL), + r, origin, bb, &ftpmessage); + /* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ + if (rc == 213) { + struct { + char YYYY[4+1]; + char MM[2+1]; + char DD[2+1]; + char hh[2+1]; + char mm[2+1]; + char ss[2+1]; + } time_val; + if (6 == sscanf(ftpmessage, "%4[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]", + time_val.YYYY, time_val.MM, time_val.DD, time_val.hh, time_val.mm, time_val.ss)) { + struct tm tms; + memset (&tms, '\0', sizeof tms); + tms.tm_year = atoi(time_val.YYYY) - 1900; + tms.tm_mon = atoi(time_val.MM) - 1; + tms.tm_mday = atoi(time_val.DD); + tms.tm_hour = atoi(time_val.hh); + tms.tm_min = atoi(time_val.mm); + tms.tm_sec = atoi(time_val.ss); +#ifdef HAVE_TIMEGM /* Does system have timegm()? */ + mtime = timegm(&tms); + mtime *= APR_USEC_PER_SEC; +#elif HAVE_GMTOFF /* does struct tm have a member tm_gmtoff? */ + /* mktime will subtract the local timezone, which is not what we want. + * Add it again because the MDTM string is GMT + */ + mtime = mktime(&tms); + mtime += tms.tm_gmtoff; + mtime *= APR_USEC_PER_SEC; +#else + mtime = 0L; +#endif + } + } +#endif /* USE_MDTM */ +/* FIXME: Handle range requests - send REST */ + buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path), CRLF, NULL); + } + rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); + /* rc is an intermediate response for the LIST or RETR commands */ + + /* + * RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, + * 550 NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, + * 530 + */ + /* 110 Restart marker reply. */ + /* 125 Data connection already open; transfer starting. */ + /* 150 File status okay; about to open data connection. */ + /* 226 Closing data connection. */ + /* 250 Requested file action okay, completed. */ + /* 421 Service not available, closing control connection. */ + /* 425 Can't open data connection. */ + /* 426 Connection closed; transfer aborted. */ + /* 450 Requested file action not taken. */ + /* 451 Requested action aborted. Local error in processing. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 530 Not logged in. */ + /* 550 Requested action not taken. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc == 550) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: RETR failed, trying LIST instead"); + + /* Directory Listings should always be fetched in ASCII mode */ + dirlisting = 1; + ftp_set_TYPE('A', r, origin, bb, NULL); + + rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", + ftp_escape_globbingchars(p, path), CRLF, NULL), + r, origin, bb, &ftpmessage); + /* possible results: 250, 421, 500, 501, 502, 530, 550 */ + /* 250 Requested file action okay, completed. */ + /* 421 Service not available, closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + /* 501 Syntax error in parameters or arguments. */ + /* 502 Command not implemented. */ + /* 530 Not logged in. */ + /* 550 Requested action not taken. */ + if (rc == -1 || rc == 421) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc == 550) { + return ftp_proxyerror(r, backend, HTTP_NOT_FOUND, ftpmessage); + } + if (rc != 250) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + + /* Update current directory after CWD */ + cwd = ftp_get_PWD(r, origin, bb); + if (cwd != NULL) { + apr_table_set(r->notes, "Directory-PWD", cwd); + } + + /* See above for the "LIST" vs. "LIST -lag" discussion. */ + rc = proxy_ftp_command((cwd == NULL || strchr(cwd, '/') != NULL) + ? "LIST -lag" CRLF : "LIST" CRLF, + r, origin, bb, &ftpmessage); + + /* rc is an intermediate response for the LIST command (125 transfer starting, 150 opening data connection) */ + if (rc == -1 || rc == 421) + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + if (rc != 125 && rc != 150 && rc != 226 && rc != 250) { + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + + r->status = HTTP_OK; + r->status_line = "200 OK"; + + apr_rfc822_date(dates, r->request_time); + apr_table_setn(r->headers_out, "Date", dates); + apr_table_setn(r->headers_out, "Server", ap_get_server_version()); + + /* set content-type */ + if (dirlisting) { + ap_set_content_type(r, "text/html"); + } + else { + if (r->content_type) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: Content-Type set to %s", r->content_type); + } + else { + ap_set_content_type(r, ap_default_type(r)); + } + if (xfer_type != 'A' && size != NULL) { + /* We "trust" the ftp server to really serve (size) bytes... */ + apr_table_setn(r->headers_out, "Content-Length", size); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: Content-Length set to %s", size); + } + } + apr_table_setn(r->headers_out, "Content-Type", r->content_type); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: Content-Type set to %s", r->content_type); + +#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) + if (mtime != 0L) { + char datestr[APR_RFC822_DATE_LEN]; + apr_rfc822_date(datestr, mtime); + apr_table_set(r->headers_out, "Last-Modified", datestr); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: Last-Modified set to %s", datestr); + } +#endif /* USE_MDTM */ + + /* If an encoding has been set by mistake, delete it. + * @@@ FIXME (e.g., for ftp://user@host/file*.tar.gz, + * @@@ the encoding is currently set to x-gzip) + */ + if (dirlisting && r->content_encoding != NULL) + r->content_encoding = NULL; + + /* set content-encoding (not for dir listings, they are uncompressed)*/ + if (r->content_encoding != NULL && r->content_encoding[0] != '\0') { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: Content-Encoding set to %s", r->content_encoding); + apr_table_setn(r->headers_out, "Content-Encoding", r->content_encoding); + } + + /* wait for connection */ + if (use_port) { + for (;;) { + rv = apr_socket_accept(&data_sock, local_sock, r->pool); + if (rv == APR_EINTR) { + continue; + } + else if (rv == APR_SUCCESS) { + break; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: failed to accept data connection"); + proxy_ftp_cleanup(r, backend); + return HTTP_BAD_GATEWAY; + } + } + } + + /* the transfer socket is now open, create a new connection */ + data = ap_run_create_connection(p, r->server, data_sock, r->connection->id, + r->connection->sbh, c->bucket_alloc); + if (!data) { + /* + * the peer reset the connection already; ap_run_create_connection() closed + * the socket + */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: an error occurred creating the transfer connection"); + proxy_ftp_cleanup(r, backend); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* set up the connection filters */ + rc = ap_run_pre_connection(data, data_sock); + if (rc != OK && rc != DONE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: pre_connection setup failed (%d)", + rc); + data->aborted = 1; + proxy_ftp_cleanup(r, backend); + return rc; + } + + /* + * VI: Receive the Response ------------------------ + * + * Get response from the remote ftp socket, and pass it up the filter chain. + */ + + /* send response */ + r->sent_bodyct = 1; + + if (dirlisting) { + /* insert directory filter */ + ap_add_output_filter("PROXY_SEND_DIR", NULL, r, r->connection); + } + + /* send body */ + if (!r->header_only) { + apr_bucket *e; + int finish = FALSE; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: start body send"); + + /* read the body, pass it to the output filters */ + while (ap_get_brigade(data->input_filters, + bb, + AP_MODE_READBYTES, + APR_BLOCK_READ, + conf->io_buffer_size) == APR_SUCCESS) { +#if DEBUGGING + { + apr_off_t readbytes; + apr_brigade_length(bb, 0, &readbytes); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + r->server, "proxy (PID %d): readbytes: %#x", + getpid(), readbytes); + } +#endif + /* sanity check */ + if (APR_BRIGADE_EMPTY(bb)) { + apr_brigade_cleanup(bb); + break; + } + + /* found the last brigade? */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + /* if this is the last brigade, cleanup the + * backend connection first to prevent the + * backend server from hanging around waiting + * for a slow client to eat these bytes + */ + ap_flush_conn(data); + apr_socket_close(data_sock); + data_sock = NULL; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: data connection closed"); + /* signal that we must leave */ + finish = TRUE; + } + + /* if no EOS yet, then we must flush */ + if (FALSE == finish) { + e = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + } + + /* try send what we read */ + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS + || c->aborted) { + /* Ack! Phbtt! Die! User aborted! */ + finish = TRUE; + } + + /* make sure we always clean up after ourselves */ + apr_brigade_cleanup(bb); + + /* if we are done, leave */ + if (TRUE == finish) { + break; + } + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: end body send"); + + } + if (data_sock) { + ap_flush_conn(data); + apr_socket_close(data_sock); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: data connection closed"); + } + + /* Retrieve the final response for the RETR or LIST commands */ + rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage); + apr_brigade_cleanup(bb); + + /* + * VII: Clean Up ------------- + * + * If there are no KeepAlives, or if the connection has been signalled to + * close, close the socket and clean up + */ + + /* finish */ + rc = proxy_ftp_command("QUIT" CRLF, + r, origin, bb, &ftpmessage); + /* responses: 221, 500 */ + /* 221 Service closing control connection. */ + /* 500 Syntax error, command unrecognized. */ + ap_flush_conn(origin); + proxy_ftp_cleanup(r, backend); + + apr_brigade_destroy(bb); + return OK; +} + +static void ap_proxy_ftp_register_hook(apr_pool_t *p) +{ + /* hooks */ + proxy_hook_scheme_handler(proxy_ftp_handler, NULL, NULL, APR_HOOK_MIDDLE); + proxy_hook_canon_handler(proxy_ftp_canon, NULL, NULL, APR_HOOK_MIDDLE); + /* filters */ + ap_register_output_filter("PROXY_SEND_DIR", proxy_send_dir_filter, + NULL, AP_FTYPE_RESOURCE); +} + +module AP_MODULE_DECLARE_DATA proxy_ftp_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_proxy_ftp_register_hook /* register hooks */ +}; diff --git a/trunk/modules/proxy/mod_proxy_ftp.dsp b/trunk/modules/proxy/mod_proxy_ftp.dsp new file mode 100644 index 0000000000..5cf3689e50 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_ftp.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy_ftp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy_ftp - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_ftp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_ftp.mak" CFG="mod_proxy_ftp - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy_ftp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy_ftp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy_ftp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_ftp_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy_ftp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_ftp_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy_ftp - Win32 Release" +# Name "mod_proxy_ftp - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy_ftp.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy_ftp - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_ftp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_ftp.so "proxy_ftp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ftp.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy_ftp - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_ftp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_ftp.so "proxy_ftp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ftp.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/mod_proxy_http.c b/trunk/modules/proxy/mod_proxy_http.c new file mode 100644 index 0000000000..24ad9ced99 --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_http.c @@ -0,0 +1,1550 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* HTTP routines for Apache proxy */ + +#include "mod_proxy.h" + +module AP_MODULE_DECLARE_DATA proxy_http_module; + +static apr_status_t ap_proxy_http_cleanup(const char *scheme, + request_rec *r, + proxy_conn_rec *backend); + +/* + * Canonicalise http-like URLs. + * scheme is the scheme for the URL + * url is the URL starting with the first '/' + * def_port is the default port for this scheme. + */ +static int proxy_http_canon(request_rec *r, char *url) +{ + char *host, *path, *search, sport[7]; + const char *err; + const char *scheme; + apr_port_t port, def_port; + + /* ap_port_of_scheme() */ + if (strncasecmp(url, "http:", 5) == 0) { + url += 5; + scheme = "http"; + } + else if (strncasecmp(url, "https:", 6) == 0) { + url += 6; + scheme = "https"; + } + else { + return DECLINED; + } + def_port = apr_uri_port_of_scheme(scheme); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: HTTP: canonicalising URL %s", url); + + /* do syntatic check. + * We break the URL into host, port, path, search + */ + port = def_port; + err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); + if (err) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "error parsing URL %s: %s", + url, err); + return HTTP_BAD_REQUEST; + } + + /* now parse path/search args, according to rfc1738 */ + /* N.B. if this isn't a true proxy request, then the URL _path_ + * has already been decoded. True proxy requests have r->uri + * == r->unparsed_uri, and no others have that property. + */ + if (r->uri == r->unparsed_uri) { + search = strchr(url, '?'); + if (search != NULL) + *(search++) = '\0'; + } + else + search = r->args; + + /* process path */ + path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq); + if (path == NULL) + return HTTP_BAD_REQUEST; + + if (port != def_port) + apr_snprintf(sport, sizeof(sport), ":%d", port); + else + sport[0] = '\0'; + + if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ + host = apr_pstrcat(r->pool, "[", host, "]", NULL); + } + r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, + "/", path, (search) ? "?" : "", (search) ? search : "", NULL); + return OK; +} + +/* Clear all connection-based headers from the incoming headers table */ +static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers) +{ + const char *name; + char *next = apr_pstrdup(p, apr_table_get(headers, "Connection")); + + apr_table_unset(headers, "Proxy-Connection"); + if (!next) + return; + + while (*next) { + name = next; + while (*next && !apr_isspace(*next) && (*next != ',')) { + ++next; + } + while (*next && (apr_isspace(*next) || (*next == ','))) { + *next = '\0'; + ++next; + } + apr_table_unset(headers, name); + } + apr_table_unset(headers, "Connection"); +} + +static void add_te_chunked(apr_pool_t *p, + apr_bucket_alloc_t *bucket_alloc, + apr_bucket_brigade *header_brigade) +{ + apr_bucket *e; + char *buf; + const char te_hdr[] = "Transfer-Encoding: chunked" CRLF; + + buf = apr_pmemdup(p, te_hdr, sizeof(te_hdr)-1); + ap_xlate_proto_to_ascii(buf, sizeof(te_hdr)-1); + + e = apr_bucket_pool_create(buf, sizeof(te_hdr)-1, p, bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); +} + +static void add_cl(apr_pool_t *p, + apr_bucket_alloc_t *bucket_alloc, + apr_bucket_brigade *header_brigade, + const char *cl_val) +{ + apr_bucket *e; + char *buf; + + buf = apr_pstrcat(p, "Content-Length: ", + cl_val, + CRLF, + NULL); + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); +} + +#define ASCII_CRLF "\015\012" +#define ASCII_ZERO "\060" + +static void terminate_headers(apr_bucket_alloc_t *bucket_alloc, + apr_bucket_brigade *header_brigade) +{ + apr_bucket *e; + + /* add empty line at the end of the headers */ + e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); +} + +static apr_status_t pass_brigade(apr_bucket_alloc_t *bucket_alloc, + request_rec *r, proxy_conn_rec *conn, + conn_rec *origin, apr_bucket_brigade *b, + int flush) +{ + apr_status_t status; + apr_off_t transferred; + + if (flush) { + apr_bucket *e = apr_bucket_flush_create(bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + } + apr_brigade_length(b, 0, &transferred); + if (transferred != -1) + conn->worker->s->transferred += transferred; + status = ap_pass_brigade(origin->output_filters, b); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: pass request data failed to %pI (%s)", + conn->addr, conn->hostname); + return status; + } + apr_brigade_cleanup(b); + return APR_SUCCESS; +} + +static apr_status_t stream_reqbody_chunked(apr_pool_t *p, + request_rec *r, + proxy_conn_rec *conn, + conn_rec *origin, + apr_bucket_brigade *header_brigade) +{ + int seen_eos = 0; + apr_size_t hdr_len; + apr_off_t bytes; + apr_status_t status; + apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; + apr_bucket_brigade *b, *input_brigade; + apr_bucket *e; + + input_brigade = apr_brigade_create(p, bucket_alloc); + + do { + char chunk_hdr[20]; /* must be here due to transient bucket. */ + + status = ap_get_brigade(r->input_filters, input_brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + HUGE_STRING_LEN); + + if (status != APR_SUCCESS) { + return status; + } + + /* If this brigade contains EOS, either stop or remove it. */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { + seen_eos = 1; + + /* As a shortcut, if this brigade is simply an EOS bucket, + * don't send anything down the filter chain. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) { + break; + } + + /* We can't pass this EOS to the output_filters. */ + e = APR_BRIGADE_LAST(input_brigade); + apr_bucket_delete(e); + } + + apr_brigade_length(input_brigade, 1, &bytes); + + hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr), + "%" APR_UINT64_T_HEX_FMT CRLF, + (apr_uint64_t)bytes); + + ap_xlate_proto_to_ascii(chunk_hdr, hdr_len); + e = apr_bucket_transient_create(chunk_hdr, hdr_len, + bucket_alloc); + APR_BRIGADE_INSERT_HEAD(input_brigade, e); + + /* + * Append the end-of-chunk CRLF + */ + e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc); + APR_BRIGADE_INSERT_TAIL(input_brigade, e); + + if (header_brigade) { + /* we never sent the header brigade, so go ahead and + * take care of that now + */ + add_te_chunked(p, bucket_alloc, header_brigade); + terminate_headers(bucket_alloc, header_brigade); + b = header_brigade; + APR_BRIGADE_CONCAT(b, input_brigade); + header_brigade = NULL; + } + else { + b = input_brigade; + } + + status = pass_brigade(bucket_alloc, r, conn, origin, b, 0); + if (status != APR_SUCCESS) { + return status; + } + } while (!seen_eos); + + if (header_brigade) { + /* we never sent the header brigade because there was no request body; + * send it now without T-E + */ + terminate_headers(bucket_alloc, header_brigade); + b = header_brigade; + } + else { + if (!APR_BRIGADE_EMPTY(input_brigade)) { + /* input brigade still has an EOS which we can't pass to the output_filters. */ + e = APR_BRIGADE_LAST(input_brigade); + AP_DEBUG_ASSERT(APR_BUCKET_IS_EOS(e)); + apr_bucket_delete(e); + } + e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF + /* */ + ASCII_CRLF, + 5, bucket_alloc); + APR_BRIGADE_INSERT_TAIL(input_brigade, e); + b = input_brigade; + } + + status = pass_brigade(bucket_alloc, r, conn, origin, b, 1); + return status; +} + +static apr_status_t stream_reqbody_cl(apr_pool_t *p, + request_rec *r, + proxy_conn_rec *conn, + conn_rec *origin, + apr_bucket_brigade *header_brigade, + const char *old_cl_val) +{ + int seen_eos = 0; + apr_status_t status; + apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; + apr_bucket_brigade *b, *input_brigade; + apr_bucket *e; + + input_brigade = apr_brigade_create(p, bucket_alloc); + + do { + status = ap_get_brigade(r->input_filters, input_brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + HUGE_STRING_LEN); + + if (status != APR_SUCCESS) { + return status; + } + + /* If this brigade contains EOS, either stop or remove it. */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { + seen_eos = 1; + + /* As a shortcut, if this brigade is simply an EOS bucket, + * don't send anything down the filter chain. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) { + break; + } + + /* We can't pass this EOS to the output_filters. */ + e = APR_BRIGADE_LAST(input_brigade); + apr_bucket_delete(e); + } + + if (header_brigade) { + /* we never sent the header brigade, so go ahead and + * take care of that now + */ + add_cl(p, bucket_alloc, header_brigade, old_cl_val); + terminate_headers(bucket_alloc, header_brigade); + b = header_brigade; + APR_BRIGADE_CONCAT(b, input_brigade); + header_brigade = NULL; + } + else { + b = input_brigade; + } + + status = pass_brigade(bucket_alloc, r, conn, origin, b, 0); + if (status != APR_SUCCESS) { + return status; + } + } while (!seen_eos); + + if (header_brigade) { + /* we never sent the header brigade since there was no request + * body; send it now, and only specify C-L if client specified + * C-L: 0 + */ + if (!strcmp(old_cl_val, "0")) { + add_cl(p, bucket_alloc, header_brigade, old_cl_val); + } + terminate_headers(bucket_alloc, header_brigade); + b = header_brigade; + } + else { + /* need to flush any pending data */ + b = input_brigade; /* empty now; pass_brigade() will add flush */ + } + if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) { + e = apr_bucket_immortal_create(ASCII_CRLF, 2, + r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(input_brigade, e); + } + + status = pass_brigade(bucket_alloc, r, conn, origin, b, 1); + return status; +} + +#define MAX_MEM_SPOOL 16384 + +static apr_status_t spool_reqbody_cl(apr_pool_t *p, + request_rec *r, + proxy_conn_rec *conn, + conn_rec *origin, + apr_bucket_brigade *header_brigade) +{ + int seen_eos = 0; + apr_status_t status; + apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; + apr_bucket_brigade *body_brigade, *input_brigade; + apr_bucket *e; + apr_off_t bytes, bytes_spooled = 0, fsize = 0; + apr_file_t *tmpfile = NULL; + + body_brigade = apr_brigade_create(p, bucket_alloc); + input_brigade = apr_brigade_create(p, bucket_alloc); + + do { + status = ap_get_brigade(r->input_filters, input_brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + HUGE_STRING_LEN); + + if (status != APR_SUCCESS) { + return status; + } + + /* If this brigade contains EOS, either stop or remove it. */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { + seen_eos = 1; + + /* As a shortcut, if this brigade is simply an EOS bucket, + * don't send anything down the filter chain. + */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) { + break; + } + + /* We can't pass this EOS to the output_filters. */ + e = APR_BRIGADE_LAST(input_brigade); + apr_bucket_delete(e); + } + + apr_brigade_length(input_brigade, 1, &bytes); + + if (bytes_spooled + bytes > MAX_MEM_SPOOL) { + /* can't spool any more in memory; write latest brigade to disk; + * what we read into memory before reaching our threshold will + * remain there; we just write this and any subsequent data to disk + */ + if (tmpfile == NULL) { + const char *temp_dir; + char *template; + + status = apr_temp_dir_get(&temp_dir, p); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: search for temporary directory failed"); + return status; + } + apr_filepath_merge(&template, temp_dir, + "modproxy.tmp.XXXXXX", + APR_FILEPATH_NATIVE, p); + status = apr_file_mktemp(&tmpfile, template, 0, p); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: creation of temporary file in directory %s failed", + temp_dir); + return status; + } + } + for (e = APR_BRIGADE_FIRST(input_brigade); + e != APR_BRIGADE_SENTINEL(input_brigade); + e = APR_BUCKET_NEXT(e)) { + const char *data; + apr_size_t bytes_read, bytes_written; + + apr_bucket_read(e, &data, &bytes_read, APR_BLOCK_READ); + status = apr_file_write_full(tmpfile, data, bytes_read, &bytes_written); + if (status != APR_SUCCESS) { + const char *tmpfile_name; + + if (apr_file_name_get(&tmpfile_name, tmpfile) != APR_SUCCESS) { + tmpfile_name = "(unknown)"; + } + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: write to temporary file %s failed", + tmpfile_name); + return status; + } + AP_DEBUG_ASSERT(bytes_read == bytes_written); + fsize += bytes_written; + } + apr_brigade_cleanup(input_brigade); + } + else { + APR_BRIGADE_CONCAT(body_brigade, input_brigade); + } + + bytes_spooled += bytes; + + } while (!seen_eos); + + if (bytes_spooled) { + add_cl(p, bucket_alloc, header_brigade, apr_off_t_toa(p, bytes_spooled)); + } + terminate_headers(bucket_alloc, header_brigade); + APR_BRIGADE_CONCAT(header_brigade, body_brigade); + if (tmpfile) { + /* For platforms where the size of the file may be larger than + * that which can be stored in a single bucket (where the + * length field is an apr_size_t), split it into several + * buckets: */ + if (sizeof(apr_off_t) > sizeof(apr_size_t) + && fsize > AP_MAX_SENDFILE) { + e = apr_bucket_file_create(tmpfile, 0, AP_MAX_SENDFILE, p, + bucket_alloc); + while (fsize > AP_MAX_SENDFILE) { + apr_bucket *ce; + apr_bucket_copy(e, &ce); + APR_BRIGADE_INSERT_TAIL(header_brigade, ce); + e->start += AP_MAX_SENDFILE; + fsize -= AP_MAX_SENDFILE; + } + e->length = (apr_size_t)fsize; /* Resize just the last bucket */ + } + else { + e = apr_bucket_file_create(tmpfile, 0, (apr_size_t)fsize, p, + bucket_alloc); + } + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + if (apr_table_get(r->subprocess_env, "proxy-sendextracrlf")) { + e = apr_bucket_immortal_create(ASCII_CRLF, 2, + r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + status = pass_brigade(bucket_alloc, r, conn, origin, header_brigade, 1); + return status; +} + +static apr_status_t send_request_body(apr_pool_t *p, + request_rec *r, + proxy_conn_rec *conn, + conn_rec *origin, + apr_bucket_brigade *header_brigade, + int force10) +{ + enum {RB_INIT, RB_STREAM_CL, RB_STREAM_CHUNKED, RB_SPOOL_CL} rb_method = RB_INIT; + const char *old_cl_val, *te_val; + int cl_zero; /* client sent "Content-Length: 0", which we forward on to server */ + apr_status_t status; + + /* send CL or use chunked encoding? + * + * . CL is the most friendly to the origin server since it is the + * most widely supported + * . CL stinks if we don't know the length since we have to buffer + * the data in memory or on disk until we get the entire data + * + * special cases to check for: + * . if we're using HTTP/1.0 to origin server, then we must send CL + * . if client sent C-L and there are no input resource filters, the + * the body size can't change so we send the same CL and stream the + * body + * . if client used chunked or proxy-sendchunks is set, we'll use + * chunked + * + * normal case: + * we have to compute content length by reading the entire request + * body; if request body is not small, we'll spool the remaining input + * to a temporary file + * + * special envvars to override the normal decision: + * . proxy-sendchunks + * use chunked encoding; not compatible with force-proxy-request-1.0 + * . proxy-sendcl + * spool the request body to compute C-L + * . proxy-sendunchangedcl + * use C-L from client and spool the request body + */ + old_cl_val = apr_table_get(r->headers_in, "Content-Length"); + cl_zero = old_cl_val && !strcmp(old_cl_val, "0"); + + if (!force10 + && !cl_zero + && apr_table_get(r->subprocess_env, "proxy-sendchunks")) { + rb_method = RB_STREAM_CHUNKED; + } + else if (!cl_zero + && apr_table_get(r->subprocess_env, "proxy-sendcl")) { + rb_method = RB_SPOOL_CL; + } + else { + if (old_cl_val && + (r->input_filters == r->proto_input_filters + || cl_zero + || apr_table_get(r->subprocess_env, "proxy-sendunchangedcl"))) { + rb_method = RB_STREAM_CL; + } + else if (force10) { + rb_method = RB_SPOOL_CL; + } + else if ((te_val = apr_table_get(r->headers_in, "Transfer-Encoding")) + && !strcasecmp(te_val, "chunked")) { + rb_method = RB_STREAM_CHUNKED; + } + else { + rb_method = RB_SPOOL_CL; + } + } + + switch(rb_method) { + case RB_STREAM_CHUNKED: + status = stream_reqbody_chunked(p, r, conn, origin, header_brigade); + break; + case RB_STREAM_CL: + status = stream_reqbody_cl(p, r, conn, origin, header_brigade, old_cl_val); + break; + case RB_SPOOL_CL: + status = spool_reqbody_cl(p, r, conn, origin, header_brigade); + break; + default: + ap_assert(1 != 1); + } + + return status; +} + +static +apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, + proxy_conn_rec *conn, conn_rec *origin, + proxy_server_conf *conf, + apr_uri_t *uri, + char *url, char *server_portstr) +{ + conn_rec *c = r->connection; + char *buf; + apr_bucket *e; + const apr_array_header_t *headers_in_array; + const apr_table_entry_t *headers_in; + int counter; + apr_status_t status; + apr_bucket_brigade *header_brigade; + int force10; + + header_brigade = apr_brigade_create(p, origin->bucket_alloc); + + /* + * Send the HTTP/1.1 request to the remote server + */ + + /* strip connection listed hop-by-hop headers from the request */ + /* even though in theory a connection: close coming from the client + * should not affect the connection to the server, it's unlikely + * that subsequent client requests will hit this thread/process, so + * we cancel server keepalive if the client does. + */ + conn->close += ap_proxy_liststr(apr_table_get(r->headers_in, + "Connection"), "close"); + + /* sub-requests never use keepalives */ + if (r->main) { + conn->close++; + } + + ap_proxy_clear_connection(p, r->headers_in); + if (conn->close) { + apr_table_setn(r->headers_in, "Connection", "close"); + origin->keepalive = AP_CONN_CLOSE; + } + + /* By default, we can not send chunks. That means we must buffer + * the entire request before sending it along to ensure we have + * the correct Content-Length attached. A special case is when + * the client specifies Content-Length and there are no filters + * which muck with the request body. In that situation, we don't + * have to buffer the entire request and can still send the + * Content-Length. Another special case is when the client + * specifies a C-L of 0. Pass that through as well. + */ + + if (apr_table_get(r->subprocess_env, "force-proxy-request-1.0")) { + buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL); + force10 = 1; + } else { + buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" CRLF, NULL); + force10 = 0; + } + if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) { + apr_table_unset(r->headers_in, "Connection"); + origin->keepalive = AP_CONN_CLOSE; + } + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + if (conf->preserve_host == 0) { + if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { + buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", uri->port_str, + CRLF, NULL); + } else { + buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL); + } + } + else { + /* don't want to use r->hostname, as the incoming header might have a + * port attached + */ + const char* hostname = apr_table_get(r->headers_in,"Host"); + if (!hostname) { + hostname = r->server->server_hostname; + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "proxy: no HTTP 0.9 request (with no host line) " + "on incoming request and preserve host set " + "forcing hostname to be %s for uri %s", + hostname, + r->uri ); + } + buf = apr_pstrcat(p, "Host: ", hostname, CRLF, NULL); + } + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + + /* handle Via */ + if (conf->viaopt == via_block) { + /* Block all outgoing Via: headers */ + apr_table_unset(r->headers_in, "Via"); + } else if (conf->viaopt != via_off) { + const char *server_name = ap_get_server_name(r); + /* If USE_CANONICAL_NAME_OFF was configured for the proxy virtual host, + * then the server name returned by ap_get_server_name() is the + * origin server name (which does make too much sense with Via: headers) + * so we use the proxy vhost's name instead. + */ + if (server_name == r->hostname) + server_name = r->server->server_hostname; + /* Create a "Via:" request header entry and merge it */ + /* Generate outgoing Via: header with/without server comment: */ + apr_table_mergen(r->headers_in, "Via", + (conf->viaopt == via_full) + ? apr_psprintf(p, "%d.%d %s%s (%s)", + HTTP_VERSION_MAJOR(r->proto_num), + HTTP_VERSION_MINOR(r->proto_num), + server_name, server_portstr, + AP_SERVER_BASEVERSION) + : apr_psprintf(p, "%d.%d %s%s", + HTTP_VERSION_MAJOR(r->proto_num), + HTTP_VERSION_MINOR(r->proto_num), + server_name, server_portstr) + ); + } + + /* X-Forwarded-*: handling + * + * XXX Privacy Note: + * ----------------- + * + * These request headers are only really useful when the mod_proxy + * is used in a reverse proxy configuration, so that useful info + * about the client can be passed through the reverse proxy and on + * to the backend server, which may require the information to + * function properly. + * + * In a forward proxy situation, these options are a potential + * privacy violation, as information about clients behind the proxy + * are revealed to arbitrary servers out there on the internet. + * + * The HTTP/1.1 Via: header is designed for passing client + * information through proxies to a server, and should be used in + * a forward proxy configuation instead of X-Forwarded-*. See the + * ProxyVia option for details. + */ + + if (PROXYREQ_REVERSE == r->proxyreq) { + const char *buf; + + /* Add X-Forwarded-For: so that the upstream has a chance to + * determine, where the original request came from. + */ + apr_table_mergen(r->headers_in, "X-Forwarded-For", + r->connection->remote_ip); + + /* Add X-Forwarded-Host: so that upstream knows what the + * original request hostname was. + */ + if ((buf = apr_table_get(r->headers_in, "Host"))) { + apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf); + } + + /* Add X-Forwarded-Server: so that upstream knows what the + * name of this proxy server is (if there are more than one) + * XXX: This duplicates Via: - do we strictly need it? + */ + apr_table_mergen(r->headers_in, "X-Forwarded-Server", + r->server->server_hostname); + } + + /* send request headers */ + proxy_run_fixups(r); + headers_in_array = apr_table_elts(r->headers_in); + headers_in = (const apr_table_entry_t *) headers_in_array->elts; + for (counter = 0; counter < headers_in_array->nelts; counter++) { + if (headers_in[counter].key == NULL || headers_in[counter].val == NULL + + /* Clear out hop-by-hop request headers not to send + * RFC2616 13.5.1 says we should strip these headers + */ + /* Already sent */ + || !apr_strnatcasecmp(headers_in[counter].key, "Host") + + || !apr_strnatcasecmp(headers_in[counter].key, "Keep-Alive") + || !apr_strnatcasecmp(headers_in[counter].key, "TE") + || !apr_strnatcasecmp(headers_in[counter].key, "Trailer") + || !apr_strnatcasecmp(headers_in[counter].key, "Transfer-Encoding") + || !apr_strnatcasecmp(headers_in[counter].key, "Upgrade") + + /* We'll add appropriate Content-Length later, if appropriate. + */ + || !apr_strnatcasecmp(headers_in[counter].key, "Content-Length") + /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be + * suppressed if THIS server requested the authentication, + * not when a frontend proxy requested it! + * + * The solution to this problem is probably to strip out + * the Proxy-Authorisation header in the authorisation + * code itself, not here. This saves us having to signal + * somehow whether this request was authenticated or not. + */ + || !apr_strnatcasecmp(headers_in[counter].key,"Proxy-Authorization") + || !apr_strnatcasecmp(headers_in[counter].key,"Proxy-Authenticate")) { + continue; + } + /* for sub-requests, ignore freshness/expiry headers */ + if (r->main) { + if (headers_in[counter].key == NULL || headers_in[counter].val == NULL + || !apr_strnatcasecmp(headers_in[counter].key, "If-Match") + || !apr_strnatcasecmp(headers_in[counter].key, "If-Modified-Since") + || !apr_strnatcasecmp(headers_in[counter].key, "If-Range") + || !apr_strnatcasecmp(headers_in[counter].key, "If-Unmodified-Since") + || !apr_strnatcasecmp(headers_in[counter].key, "If-None-Match")) { + continue; + } + } + + + buf = apr_pstrcat(p, headers_in[counter].key, ": ", + headers_in[counter].val, CRLF, + NULL); + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + + /* send the request data, if any. */ + status = send_request_body(p, r, conn, origin, header_brigade, force10); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: pass request data failed to %pI (%s)", + conn->addr, conn->hostname); + return status; + } + return APR_SUCCESS; +} + +static void process_proxy_header(request_rec* r, proxy_server_conf* c, + const char* key, const char* value) +{ + static const char* date_hdrs[] + = { "Date", "Expires", "Last-Modified", NULL } ; + static const struct { + const char* name; + ap_proxy_header_reverse_map_fn func; + } transform_hdrs[] = { + { "Location", ap_proxy_location_reverse_map } , + { "Content-Location", ap_proxy_location_reverse_map } , + { "URI", ap_proxy_location_reverse_map } , + { "Destination", ap_proxy_location_reverse_map } , + { "Set-Cookie", ap_proxy_cookie_reverse_map } , + { NULL, NULL } + } ; + int i ; + for ( i = 0 ; date_hdrs[i] ; ++i ) { + if ( !strcasecmp(date_hdrs[i], key) ) { + apr_table_add(r->headers_out, key, + ap_proxy_date_canon(r->pool, value)) ; + return ; + } + } + for ( i = 0 ; transform_hdrs[i].name ; ++i ) { + if ( !strcasecmp(transform_hdrs[i].name, key) ) { + apr_table_add(r->headers_out, key, + (*transform_hdrs[i].func)(r, c, value)) ; + return ; + } + } + apr_table_add(r->headers_out, key, value) ; + return ; +} + +/* + * Note: pread_len is the length of the response that we've mistakenly + * read (assuming that we don't consider that an error via + * ProxyBadHeader StartBody). This depends on buffer actually being + * local storage to the calling code in order for pread_len to make + * any sense at all, since we depend on buffer still containing + * what was read by ap_getline() upon return. + */ +static void ap_proxy_read_headers(request_rec *r, request_rec *rr, + char *buffer, int size, + conn_rec *c, int *pread_len) +{ + int len; + char *value, *end; + char field[MAX_STRING_LEN]; + int saw_headers = 0; + void *sconf = r->server->module_config; + proxy_server_conf *psc; + + psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + + r->headers_out = apr_table_make(r->pool, 20); + *pread_len = 0; + + /* + * Read header lines until we get the empty separator line, a read error, + * the connection closes (EOF), or we timeout. + */ + while ((len = ap_getline(buffer, size, rr, 1)) > 0) { + + if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */ + + /* We may encounter invalid headers, usually from buggy + * MS IIS servers, so we need to determine just how to handle + * them. We can either ignore them, assume that they mark the + * start-of-body (eg: a missing CRLF) or (the default) mark + * the headers as totally bogus and return a 500. The sole + * exception is an extra "HTTP/1.0 200, OK" line sprinkled + * in between the usual MIME headers, which is a favorite + * IIS bug. + */ + /* XXX: The mask check is buggy if we ever see an HTTP/1.10 */ + + if (!apr_date_checkmask(buffer, "HTTP/#.# ###*")) { + if (psc->badopt == bad_error) { + /* Nope, it wasn't even an extra HTTP header. Give up. */ + r->headers_out = NULL; + return ; + } + else if (psc->badopt == bad_body) { + /* if we've already started loading headers_out, then + * return what we've accumulated so far, in the hopes + * that they are useful; also note that we likely pre-read + * the first line of the response. + */ + if (saw_headers) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: Starting body due to bogus non-header in headers " + "returned by %s (%s)", r->uri, r->method); + *pread_len = len; + return ; + } else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: No HTTP headers " + "returned by %s (%s)", r->uri, r->method); + return ; + } + } + } + /* this is the psc->badopt == bad_ignore case */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: Ignoring bogus HTTP header " + "returned by %s (%s)", r->uri, r->method); + continue; + } + + *value = '\0'; + ++value; + /* XXX: RFC2068 defines only SP and HT as whitespace, this test is + * wrong... and so are many others probably. + */ + while (apr_isspace(*value)) + ++value; /* Skip to start of value */ + + /* should strip trailing whitespace as well */ + for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); -- +end) + *end = '\0'; + + /* make sure we add so as not to destroy duplicated headers + * Modify headers requiring canonicalisation and/or affected + * by ProxyPassReverse and family with process_proxy_header + */ + process_proxy_header(r, psc, buffer, value) ; + saw_headers = 1; + + /* the header was too long; at the least we should skip extra data */ + if (len >= size - 1) { + while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1)) + >= MAX_STRING_LEN - 1) { + /* soak up the extra data */ + } + if (len == 0) /* time to exit the larger loop as well */ + break; + } + } +} + + + +static int addit_dammit(void *v, const char *key, const char *val) +{ + apr_table_addn(v, key, val); + return 1; +} + +static +apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, + proxy_conn_rec *backend, + conn_rec *origin, + proxy_server_conf *conf, + char *server_portstr) { + conn_rec *c = r->connection; + char buffer[HUGE_STRING_LEN]; + char keepchar; + request_rec *rp; + apr_bucket *e; + apr_bucket_brigade *bb; + int len, backasswards; + int interim_response; /* non-zero whilst interim 1xx responses + * are being read. */ + int pread_len = 0; + apr_table_t *save_table; + + bb = apr_brigade_create(p, c->bucket_alloc); + + /* Get response from the remote server, and pass it up the + * filter chain + */ + + rp = ap_proxy_make_fake_req(origin, r); + /* In case anyone needs to know, this is a fake request that is really a + * response. + */ + rp->proxyreq = PROXYREQ_RESPONSE; + do { + apr_brigade_cleanup(bb); + + len = ap_getline(buffer, sizeof(buffer), rp, 0); + if (len == 0) { + /* handle one potential stray CRLF */ + len = ap_getline(buffer, sizeof(buffer), rp, 0); + } + if (len <= 0) { + ap_proxy_http_cleanup(NULL, r, backend); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: error reading status line from remote " + "server %s", backend->hostname); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } + /* XXX: Is this a real headers length send from remote? */ + backend->worker->s->read += len; + + /* Is it an HTTP/1 response? + * This is buggy if we ever see an HTTP/1.10 + */ + if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) { + int major, minor; + + if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) { + major = 1; + minor = 1; + } + /* If not an HTTP/1 message or + * if the status line was > 8192 bytes + */ + else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) { + ap_proxy_http_cleanup(NULL, r, backend); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + apr_pstrcat(p, "Corrupt status line returned by remote " + "server: ", buffer, NULL)); + } + backasswards = 0; + + keepchar = buffer[12]; + buffer[12] = '\0'; + r->status = atoi(&buffer[9]); + + if (keepchar != '\0') { + buffer[12] = keepchar; + } else { + /* 2616 requires the space in Status-Line; the origin + * server may have sent one but ap_rgetline_core will + * have stripped it. */ + buffer[12] = ' '; + buffer[13] = '\0'; + } + r->status_line = apr_pstrdup(p, &buffer[9]); + + + /* read the headers. */ + /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers*/ + /* Also, take care with headers with multiple occurences. */ + + /* First, tuck away all already existing cookies */ + save_table = apr_table_make(r->pool, 2); + apr_table_do(addit_dammit, save_table, r->headers_out, + "Set-Cookie", NULL); + + /* shove the headers direct into r->headers_out */ + ap_proxy_read_headers(r, rp, buffer, sizeof(buffer), origin, + &pread_len); + + if (r->headers_out == NULL) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + r->server, "proxy: bad HTTP/%d.%d header " + "returned by %s (%s)", major, minor, r->uri, + r->method); + backend->close += 1; + /* + * ap_send_error relies on a headers_out to be present. we + * are in a bad position here.. so force everything we send out + * to have nothing to do with the incoming packet + */ + r->headers_out = apr_table_make(r->pool,1); + r->status = HTTP_BAD_GATEWAY; + r->status_line = "bad gateway"; + return r->status; + + } else { + const char *buf; + + /* Now, add in the just read cookies */ + apr_table_do(addit_dammit, save_table, r->headers_out, + "Set-Cookie", NULL); + + /* and now load 'em all in */ + if (!apr_is_empty_table(save_table)) { + apr_table_unset(r->headers_out, "Set-Cookie"); + r->headers_out = apr_table_overlay(r->pool, + r->headers_out, + save_table); + } + + /* strip connection listed hop-by-hop headers from response */ + backend->close += ap_proxy_liststr(apr_table_get(r->headers_out, + "Connection"), + "close"); + ap_proxy_clear_connection(p, r->headers_out); + if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { + ap_set_content_type(r, apr_pstrdup(p, buf)); + } + ap_proxy_pre_http_request(origin,rp); + } + + /* handle Via header in response */ + if (conf->viaopt != via_off && conf->viaopt != via_block) { + const char *server_name = ap_get_server_name(r); + /* If USE_CANONICAL_NAME_OFF was configured for the proxy virtual host, + * then the server name returned by ap_get_server_name() is the + * origin server name (which does make too much sense with Via: headers) + * so we use the proxy vhost's name instead. + */ + if (server_name == r->hostname) + server_name = r->server->server_hostname; + /* create a "Via:" response header entry and merge it */ + apr_table_mergen(r->headers_out, "Via", + (conf->viaopt == via_full) + ? apr_psprintf(p, "%d.%d %s%s (%s)", + HTTP_VERSION_MAJOR(r->proto_num), + HTTP_VERSION_MINOR(r->proto_num), + server_name, + server_portstr, + AP_SERVER_BASEVERSION) + : apr_psprintf(p, "%d.%d %s%s", + HTTP_VERSION_MAJOR(r->proto_num), + HTTP_VERSION_MINOR(r->proto_num), + server_name, + server_portstr) + ); + } + + /* cancel keepalive if HTTP/1.0 or less */ + if ((major < 1) || (minor < 1)) { + backend->close += 1; + origin->keepalive = AP_CONN_CLOSE; + } + } else { + /* an http/0.9 response */ + backasswards = 1; + r->status = 200; + r->status_line = "200 OK"; + backend->close += 1; + } + + interim_response = ap_is_HTTP_INFO(r->status); + if (interim_response) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "proxy: HTTP: received interim %d response", + r->status); + } + /* Moved the fixups of Date headers and those affected by + * ProxyPassReverse/etc from here to ap_proxy_read_headers + */ + + if ((r->status == 401) && (conf->error_override != 0)) { + const char *buf; + const char *wa = "WWW-Authenticate"; + if ((buf = apr_table_get(r->headers_out, wa))) { + apr_table_set(r->err_headers_out, wa, buf); + } else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: origin server sent 401 without WWW-Authenticate header"); + } + } + + r->sent_bodyct = 1; + /* + * Is it an HTTP/0.9 response or did we maybe preread the 1st line of + * the response? If so, load the extra data. These are 2 mutually + * exclusive possibilities, that just happen to require very + * similar behavior. + */ + if (backasswards || pread_len) { + apr_ssize_t cntr = (apr_ssize_t)pread_len; + if (backasswards) { + /*@@@FIXME: + * At this point in response processing of a 0.9 response, + * we don't know yet whether data is binary or not. + * mod_charset_lite will get control later on, so it cannot + * decide on the conversion of this buffer full of data. + * However, chances are that we are not really talking to an + * HTTP/0.9 server, but to some different protocol, therefore + * the best guess IMHO is to always treat the buffer as "text/x": + */ + ap_xlate_proto_to_ascii(buffer, len); + cntr = (apr_ssize_t)len; + } + e = apr_bucket_heap_create(buffer, cntr, NULL, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + } + + /* send body - but only if a body is expected */ + if ((!r->header_only) && /* not HEAD request */ + !interim_response && /* not any 1xx response */ + (r->status != HTTP_NO_CONTENT) && /* not 204 */ + (r->status != HTTP_NOT_MODIFIED)) { /* not 304 */ + + /* We need to copy the output headers and treat them as input + * headers as well. BUT, we need to do this before we remove + * TE, so that they are preserved accordingly for + * ap_http_filter to know where to end. + */ + rp->headers_in = apr_table_copy(r->pool, r->headers_out); + + apr_table_unset(r->headers_out,"Transfer-Encoding"); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: start body send"); + + /* + * if we are overriding the errors, we can't put the content + * of the page into the brigade + */ + if (conf->error_override == 0 || ap_is_HTTP_SUCCESS(r->status)) { + /* read the body, pass it to the output filters */ + apr_read_type_e mode = APR_NONBLOCK_READ; + int finish = FALSE; + + do { + apr_off_t readbytes; + apr_status_t rv; + + rv = ap_get_brigade(rp->input_filters, bb, + AP_MODE_READBYTES, mode, + conf->io_buffer_size); + + /* ap_get_brigade will return success with an empty brigade + * for a non-blocking read which would block: */ + if (APR_STATUS_IS_EAGAIN(rv) + || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) { + /* flush to the client and switch to blocking mode */ + e = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + if (ap_pass_brigade(r->output_filters, bb) + || c->aborted) { + backend->close = 1; + break; + } + apr_brigade_cleanup(bb); + mode = APR_BLOCK_READ; + continue; + } + else if (rv == APR_EOF) { + break; + } + else if (rv != APR_SUCCESS) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, + "proxy: error reading response"); + break; + } + /* next time try a non-blocking read */ + mode = APR_NONBLOCK_READ; + + apr_brigade_length(bb, 0, &readbytes); + backend->worker->s->read += readbytes; +#if DEBUGGING + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + r->server, "proxy (PID %d): readbytes: %#x", + getpid(), readbytes); + } +#endif + /* sanity check */ + if (APR_BRIGADE_EMPTY(bb)) { + apr_brigade_cleanup(bb); + break; + } + + /* found the last brigade? */ + if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { + /* if this is the last brigade, cleanup the + * backend connection first to prevent the + * backend server from hanging around waiting + * for a slow client to eat these bytes + */ + backend->close = 1; + /* signal that we must leave */ + finish = TRUE; + } + + /* try send what we read */ + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS + || c->aborted) { + /* Ack! Phbtt! Die! User aborted! */ + backend->close = 1; /* this causes socket close below */ + finish = TRUE; + } + + /* make sure we always clean up after ourselves */ + apr_brigade_cleanup(bb); + + } while (!finish); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: end body send"); + } + else if (!interim_response) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: header only"); + + /* Pass EOS bucket down the filter chain. */ + e = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS + || c->aborted) { + /* Ack! Phbtt! Die! User aborted! */ + backend->close = 1; /* this causes socket close below */ + } + + apr_brigade_cleanup(bb); + } + } while (interim_response); + + if (conf->error_override) { + /* the code above this checks for 'OK' which is what the hook expects */ + if (ap_is_HTTP_SUCCESS(r->status)) + return OK; + else { + /* clear r->status for override error, otherwise ErrorDocument + * thinks that this is a recursive error, and doesn't find the + * custom error page + */ + int status = r->status; + r->status = HTTP_OK; + /* Discard body, if one is expected */ + if ((status != HTTP_NO_CONTENT) && /* not 204 */ + (status != HTTP_NOT_MODIFIED)) { /* not 304 */ + ap_discard_request_body(rp); + } + return status; + } + } else + return OK; +} + +static +apr_status_t ap_proxy_http_cleanup(const char *scheme, request_rec *r, + proxy_conn_rec *backend) +{ + /* If there are no KeepAlives, or if the connection has been signalled + * to close, close the socket and clean up + */ + + /* if the connection is < HTTP/1.1, or Connection: close, + * we close the socket, otherwise we leave it open for KeepAlive support + */ + if (backend->close || (r->proto_num < HTTP_VERSION(1,1))) { + backend->close_on_recycle = 1; + ap_set_module_config(r->connection->conn_config, &proxy_http_module, NULL); + ap_proxy_release_connection(scheme, backend, r->server); + } + return OK; +} + +/* + * This handles http:// URLs, and other URLs using a remote proxy over http + * If proxyhost is NULL, then contact the server directly, otherwise + * go via the proxy. + * Note that if a proxy is used, then URLs other than http: can be accessed, + * also, if we have trouble which is clearly specific to the proxy, then + * we return DECLINED so that we can try another proxy. (Or the direct + * route.) + */ +static int proxy_http_handler(request_rec *r, proxy_worker *worker, + proxy_server_conf *conf, + char *url, const char *proxyname, + apr_port_t proxyport) +{ + int status; + char server_portstr[32]; + char *scheme; + const char *proxy_function; + const char *u; + proxy_conn_rec *backend = NULL; + int is_ssl = 0; + + /* Note: Memory pool allocation. + * A downstream keepalive connection is always connected to the existence + * (or not) of an upstream keepalive connection. If this is not done then + * load balancing against multiple backend servers breaks (one backend + * server ends up taking 100% of the load), and the risk is run of + * downstream keepalive connections being kept open unnecessarily. This + * keeps webservers busy and ties up resources. + * + * As a result, we allocate all sockets out of the upstream connection + * pool, and when we want to reuse a socket, we check first whether the + * connection ID of the current upstream connection is the same as that + * of the connection when the socket was opened. + */ + apr_pool_t *p = r->connection->pool; + conn_rec *c = r->connection; + apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri)); + + /* find the scheme */ + u = strchr(url, ':'); + if (u == NULL || u[1] != '/' || u[2] != '/' || u[3] == '\0') + return DECLINED; + if ((u - url) > 14) + return HTTP_BAD_REQUEST; + scheme = apr_pstrndup(c->pool, url, u - url); + /* scheme is lowercase */ + ap_str_tolower(scheme); + /* is it for us? */ + if (strcmp(scheme, "https") == 0) { + if (!ap_proxy_ssl_enable(NULL)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: HTTPS: declining URL %s" + " (mod_ssl not configured?)", url); + return DECLINED; + } + is_ssl = 1; + proxy_function = "HTTPS"; + } + else if (!(strcmp(scheme, "http") == 0 || (strcmp(scheme, "ftp") == 0 && proxyname))) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: HTTP: declining URL %s", url); + return DECLINED; /* only interested in HTTP, or FTP via proxy */ + } + else { + if (*scheme == 'h') + proxy_function = "HTTP"; + else + proxy_function = "FTP"; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: HTTP: serving URL %s", url); + + + /* only use stored info for top-level pages. Sub requests don't share + * in keepalives + */ + if (!r->main) { + backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, + &proxy_http_module); + } + /* create space for state information */ + if (!backend) { + if ((status = ap_proxy_acquire_connection(proxy_function, &backend, + worker, r->server)) != OK) + goto cleanup; + + if (!r->main) { + ap_set_module_config(c->conn_config, &proxy_http_module, backend); + } + } + + backend->is_ssl = is_ssl; + backend->close_on_recycle = 1; + + /* Step One: Determine Who To Connect To */ + if ((status = ap_proxy_determine_connection(p, r, conf, worker, backend, + uri, &url, proxyname, + proxyport, server_portstr, + sizeof(server_portstr))) != OK) + goto cleanup; + + /* Step Two: Make the Connection */ + if (ap_proxy_connect_backend(proxy_function, backend, worker, r->server)) { + if (r->proxyreq == PROXYREQ_PROXY) + status = HTTP_NOT_FOUND; + else + status = HTTP_SERVICE_UNAVAILABLE; + goto cleanup; + } + + /* Step Three: Create conn_rec */ + if (!backend->connection) { + if ((status = ap_proxy_connection_create(proxy_function, backend, + c, r->server)) != OK) + goto cleanup; + } + + /* Step Four: Send the Request */ + if ((status = ap_proxy_http_request(p, r, backend, backend->connection, + conf, uri, url, server_portstr)) != OK) + goto cleanup; + + /* Step Five: Receive the Response */ + if ((status = ap_proxy_http_process_response(p, r, backend, + backend->connection, + conf, server_portstr)) != OK) + goto cleanup; + + /* Step Six: Clean Up */ + +cleanup: + if (backend) { + if (status != OK) { + backend->close = 1; + backend->close_on_recycle = 1; + } + ap_proxy_http_cleanup(proxy_function, r, backend); + } + return status; +} + +static void ap_proxy_http_register_hook(apr_pool_t *p) +{ + proxy_hook_scheme_handler(proxy_http_handler, NULL, NULL, APR_HOOK_FIRST); + proxy_hook_canon_handler(proxy_http_canon, NULL, NULL, APR_HOOK_FIRST); +} + +module AP_MODULE_DECLARE_DATA proxy_http_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + NULL, /* command apr_table_t */ + ap_proxy_http_register_hook/* register hooks */ +}; + diff --git a/trunk/modules/proxy/mod_proxy_http.dsp b/trunk/modules/proxy/mod_proxy_http.dsp new file mode 100644 index 0000000000..c55daa0afa --- /dev/null +++ b/trunk/modules/proxy/mod_proxy_http.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="mod_proxy_http" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_proxy_http - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_http.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_proxy_http.mak" CFG="mod_proxy_http - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_proxy_http - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_proxy_http - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_proxy_http - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_http_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_proxy_http - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_http_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so +# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so + +!ENDIF + +# Begin Target + +# Name "mod_proxy_http - Win32 Release" +# Name "mod_proxy_http - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\mod_proxy_http.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\mod_proxy.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_proxy_http - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_http.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_http.so "proxy_http_module for Apache" ../../include/ap_release.h > .\mod_proxy_http.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_proxy_http - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_proxy_http.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_proxy_http.so "proxy_http_module for Apache" ../../include/ap_release.h > .\mod_proxy_http.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/proxy/proxy_util.c b/trunk/modules/proxy/proxy_util.c new file mode 100644 index 0000000000..86335b44ac --- /dev/null +++ b/trunk/modules/proxy/proxy_util.c @@ -0,0 +1,2055 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Utility routines for Apache proxy */ +#include "mod_proxy.h" +#include "ap_mpm.h" +#include "scoreboard.h" +#include "apr_version.h" + +#if APR_HAVE_UNISTD_H +#include /* for getpid() */ +#endif + +#if (APR_MAJOR_VERSION < 1) +#undef apr_socket_create +#define apr_socket_create apr_socket_create_ex +#endif + +/* Global balancer counter */ +int PROXY_DECLARE_DATA proxy_lb_workers = 0; +static int lb_workers_limit = 0; + +static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); +static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r); +static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r); +static int proxy_match_word(struct dirconn_entry *This, request_rec *r); + +APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req, + (request_rec *r, request_rec *pr), (r, pr), + OK, DECLINED) + +/* already called in the knowledge that the characters are hex digits */ +PROXY_DECLARE(int) ap_proxy_hex2c(const char *x) +{ + int i, ch; + +#if !APR_CHARSET_EBCDIC + ch = x[0]; + if (apr_isdigit(ch)) + i = ch - '0'; + else if (apr_isupper(ch)) + i = ch - ('A' - 10); + else + i = ch - ('a' - 10); + i <<= 4; + + ch = x[1]; + if (apr_isdigit(ch)) + i += ch - '0'; + else if (apr_isupper(ch)) + i += ch - ('A' - 10); + else + i += ch - ('a' - 10); + return i; +#else /*APR_CHARSET_EBCDIC*/ + /* we assume that the hex value refers to an ASCII character + * so convert to EBCDIC so that it makes sense locally; + * + * example: + * + * client specifies %20 in URL to refer to a space char; + * at this point we're called with EBCDIC "20"; after turning + * EBCDIC "20" into binary 0x20, we then need to assume that 0x20 + * represents an ASCII char and convert 0x20 to EBCDIC, yielding + * 0x40 + */ + char buf[1]; + + if (1 == sscanf(x, "%2x", &i)) { + buf[0] = i & 0xFF; + ap_xlate_proto_from_ascii(buf, 1); + return buf[0]; + } + else { + return 0; + } +#endif /*APR_CHARSET_EBCDIC*/ +} + +PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x) +{ +#if !APR_CHARSET_EBCDIC + int i; + + x[0] = '%'; + i = (ch & 0xF0) >> 4; + if (i >= 10) + x[1] = ('A' - 10) + i; + else + x[1] = '0' + i; + + i = ch & 0x0F; + if (i >= 10) + x[2] = ('A' - 10) + i; + else + x[2] = '0' + i; +#else /*APR_CHARSET_EBCDIC*/ + static const char ntoa[] = { "0123456789ABCDEF" }; + char buf[1]; + + ch &= 0xFF; + + buf[0] = ch; + ap_xlate_proto_to_ascii(buf, 1); + + x[0] = '%'; + x[1] = ntoa[(buf[0] >> 4) & 0x0F]; + x[2] = ntoa[buf[0] & 0x0F]; + x[3] = '\0'; +#endif /*APR_CHARSET_EBCDIC*/ +} + +/* + * canonicalise a URL-encoded string + */ + +/* + * Convert a URL-encoded string to canonical form. + * It decodes characters which need not be encoded, + * and encodes those which must be encoded, and does not touch + * those which must not be touched. + */ +PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, + int forcedec, int proxyreq) +{ + int i, j, ch; + char *y; + char *allowed; /* characters which should not be encoded */ + char *reserved; /* characters which much not be en/de-coded */ + +/* N.B. in addition to :@&=, this allows ';' in an http path + * and '?' in an ftp path -- this may be revised + * + * Also, it makes a '+' character in a search string reserved, as + * it may be form-encoded. (Although RFC 1738 doesn't allow this - + * it only permits ; / ? : @ = & as reserved chars.) + */ + if (t == enc_path) + allowed = "$-_.+!*'(),;:@&="; + else if (t == enc_search) + allowed = "$-_.!*'(),;:@&="; + else if (t == enc_user) + allowed = "$-_.+!*'(),;@&="; + else if (t == enc_fpath) + allowed = "$-_.+!*'(),?:@&="; + else /* if (t == enc_parm) */ + allowed = "$-_.+!*'(),?/:@&="; + + if (t == enc_path) + reserved = "/"; + else if (t == enc_search) + reserved = "+"; + else + reserved = ""; + + y = apr_palloc(p, 3 * len + 1); + + for (i = 0, j = 0; i < len; i++, j++) { +/* always handle '/' first */ + ch = x[i]; + if (strchr(reserved, ch)) { + y[j] = ch; + continue; + } +/* + * decode it if not already done. do not decode reverse proxied URLs + * unless specifically forced + */ + if ((forcedec || (proxyreq && proxyreq != PROXYREQ_REVERSE)) && ch == '%') { + if (!apr_isxdigit(x[i + 1]) || !apr_isxdigit(x[i + 2])) + return NULL; + ch = ap_proxy_hex2c(&x[i + 1]); + i += 2; + if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */ + ap_proxy_c2hex(ch, &y[j]); + j += 2; + continue; + } + } +/* recode it, if necessary */ + if (!apr_isalnum(ch) && !strchr(allowed, ch)) { + ap_proxy_c2hex(ch, &y[j]); + j += 2; + } + else + y[j] = ch; + } + y[j] = '\0'; + return y; +} + +/* + * Parses network-location. + * urlp on input the URL; on output the path, after the leading / + * user NULL if no user/password permitted + * password holder for password + * host holder for host + * port port number; only set if one is supplied. + * + * Returns an error string. + */ +PROXY_DECLARE(char *) + ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, + char **passwordp, char **hostp, apr_port_t *port) +{ + char *addr, *scope_id, *strp, *host, *url = *urlp; + char *user = NULL, *password = NULL; + apr_port_t tmp_port; + apr_status_t rv; + + if (url[0] != '/' || url[1] != '/') + return "Malformed URL"; + host = url + 2; + url = strchr(host, '/'); + if (url == NULL) + url = ""; + else + *(url++) = '\0'; /* skip seperating '/' */ + + /* find _last_ '@' since it might occur in user/password part */ + strp = strrchr(host, '@'); + + if (strp != NULL) { + *strp = '\0'; + user = host; + host = strp + 1; + +/* find password */ + strp = strchr(user, ':'); + if (strp != NULL) { + *strp = '\0'; + password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1, 0); + if (password == NULL) + return "Bad %-escape in URL (password)"; + } + + user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1, 0); + if (user == NULL) + return "Bad %-escape in URL (username)"; + } + if (userp != NULL) { + *userp = user; + } + if (passwordp != NULL) { + *passwordp = password; + } + + /* Parse the host string to separate host portion from optional port. + * Perform range checking on port. + */ + rv = apr_parse_addr_port(&addr, &scope_id, &tmp_port, host, p); + if (rv != APR_SUCCESS || addr == NULL || scope_id != NULL) { + return "Invalid host/port"; + } + if (tmp_port != 0) { /* only update caller's port if port was specified */ + *port = tmp_port; + } + + ap_str_tolower(addr); /* DNS names are case-insensitive */ + + *urlp = url; + *hostp = addr; + + return NULL; +} + +static const char * const lwday[7] = +{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + +/* + * If the date is a valid RFC 850 date or asctime() date, then it + * is converted to the RFC 1123 format, otherwise it is not modified. + * This routine is not very fast at doing conversions, as it uses + * sscanf and sprintf. However, if the date is already correctly + * formatted, then it exits very quickly. + */ +PROXY_DECLARE(const char *) + ap_proxy_date_canon(apr_pool_t *p, const char *x1) +{ + char *x = apr_pstrdup(p, x1); + int wk, mday, year, hour, min, sec, mon; + char *q, month[4], zone[4], week[4]; + + q = strchr(x, ','); + /* check for RFC 850 date */ + if (q != NULL && q - x > 3 && q[1] == ' ') { + *q = '\0'; + for (wk = 0; wk < 7; wk++) + if (strcmp(x, lwday[wk]) == 0) + break; + *q = ','; + if (wk == 7) + return x; /* not a valid date */ + if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' || + q[17] != ':' || strcmp(&q[20], " GMT") != 0) + return x; + if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year, + &hour, &min, &sec, zone) != 7) + return x; + if (year < 70) + year += 2000; + else + year += 1900; + } + else { +/* check for acstime() date */ + if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' || + x[16] != ':' || x[19] != ' ' || x[24] != '\0') + return x; + if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour, + &min, &sec, &year) != 7) + return x; + for (wk = 0; wk < 7; wk++) + if (strcmp(week, apr_day_snames[wk]) == 0) + break; + if (wk == 7) + return x; + } + +/* check date */ + for (mon = 0; mon < 12; mon++) + if (strcmp(month, apr_month_snames[mon]) == 0) + break; + if (mon == 12) + return x; + + q = apr_palloc(p, 30); + apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", apr_day_snames[wk], + mday, apr_month_snames[mon], year, hour, min, sec); + return q; +} + +PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r) +{ + request_rec *rp = apr_pcalloc(c->pool, sizeof(*r)); + + rp->pool = c->pool; + rp->status = HTTP_OK; + + rp->headers_in = apr_table_make(c->pool, 50); + rp->subprocess_env = apr_table_make(c->pool, 50); + rp->headers_out = apr_table_make(c->pool, 12); + rp->err_headers_out = apr_table_make(c->pool, 5); + rp->notes = apr_table_make(c->pool, 5); + + rp->server = r->server; + rp->proxyreq = r->proxyreq; + rp->request_time = r->request_time; + rp->connection = c; + rp->output_filters = c->output_filters; + rp->input_filters = c->input_filters; + rp->proto_output_filters = c->output_filters; + rp->proto_input_filters = c->input_filters; + + rp->request_config = ap_create_request_config(c->pool); + proxy_run_create_req(r, rp); + + return rp; +} + + +/* + * list is a comma-separated list of case-insensitive tokens, with + * optional whitespace around the tokens. + * The return returns 1 if the token val is found in the list, or 0 + * otherwise. + */ +PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val) +{ + int len, i; + const char *p; + + len = strlen(val); + + while (list != NULL) { + p = ap_strchr_c(list, ','); + if (p != NULL) { + i = p - list; + do + p++; + while (apr_isspace(*p)); + } + else + i = strlen(list); + + while (i > 0 && apr_isspace(list[i - 1])) + i--; + if (i == len && strncasecmp(list, val, len) == 0) + return 1; + list = p; + } + return 0; +} + +/* + * list is a comma-separated list of case-insensitive tokens, with + * optional whitespace around the tokens. + * if val appears on the list of tokens, it is removed from the list, + * and the new list is returned. + */ +PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val) +{ + int len, i; + const char *p; + char *new = NULL; + + len = strlen(val); + + while (list != NULL) { + p = ap_strchr_c(list, ','); + if (p != NULL) { + i = p - list; + do + p++; + while (apr_isspace(*p)); + } + else + i = strlen(list); + + while (i > 0 && apr_isspace(list[i - 1])) + i--; + if (i == len && strncasecmp(list, val, len) == 0) { + /* do nothing */ + } + else { + if (new) + new = apr_pstrcat(pool, new, ",", apr_pstrndup(pool, list, i), NULL); + else + new = apr_pstrndup(pool, list, i); + } + list = p; + } + return new; +} + +/* + * Converts 8 hex digits to a time integer + */ +PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x) +{ + int i, ch; + unsigned int j; + + for (i = 0, j = 0; i < 8; i++) { + ch = x[i]; + j <<= 4; + if (apr_isdigit(ch)) + j |= ch - '0'; + else if (apr_isupper(ch)) + j |= ch - ('A' - 10); + else + j |= ch - ('a' - 10); + } + if (j == 0xffffffff) + return -1; /* so that it works with 8-byte ints */ + else + return j; +} + +/* + * Converts a time integer to 8 hex digits + */ +PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y) +{ + int i, ch; + unsigned int j = t; + + for (i = 7; i >= 0; i--) { + ch = j & 0xF; + j >>= 4; + if (ch >= 10) + y[i] = ch + ('A' - 10); + else + y[i] = ch + '0'; + } + y[8] = '\0'; +} + +PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message) +{ + apr_table_setn(r->notes, "error-notes", + apr_pstrcat(r->pool, + "The proxy server could not handle the request " + "pool, r->uri), + "\">", ap_escape_html(r->pool, r->method), + " ", + ap_escape_html(r->pool, r->uri), ".

    \n" + "Reason: ", + ap_escape_html(r->pool, message), + "

    ", NULL)); + + /* Allow "error-notes" string to be printed by ap_send_error_response() */ + apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*")); + + r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: %s returned by %s", message, r->uri); + return statuscode; +} + +static const char * + proxy_get_host_of_request(request_rec *r) +{ + char *url, *user = NULL, *password = NULL, *err, *host; + apr_port_t port; + + if (r->hostname != NULL) + return r->hostname; + + /* Set url to the first char after "scheme://" */ + if ((url = strchr(r->uri, ':')) == NULL + || url[1] != '/' || url[2] != '/') + return NULL; + + url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */ + + err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port); + + if (err != NULL) + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "%s", err); + + r->hostname = host; + + return host; /* ought to return the port, too */ +} + +/* Return TRUE if addr represents an IP address (or an IP network address) */ +PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p) +{ + const char *addr = This->name; + long ip_addr[4]; + int i, quads; + long bits; + + /* if the address is given with an explicit netmask, use that */ + /* Due to a deficiency in apr_inet_addr(), it is impossible to parse */ + /* "partial" addresses (with less than 4 quads) correctly, i.e. */ + /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */ + /* I therefore have to parse the IP address manually: */ + /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */ + /* addr and mask were set by proxy_readmask() */ + /*return 1; */ + + /* Parse IP addr manually, optionally allowing */ + /* abbreviated net addresses like 192.168. */ + + /* Iterate over up to 4 (dotted) quads. */ + for (quads = 0; quads < 4 && *addr != '\0'; ++quads) { + char *tmp; + + if (*addr == '/' && quads > 0) /* netmask starts here. */ + break; + + if (!apr_isdigit(*addr)) + return 0; /* no digit at start of quad */ + + ip_addr[quads] = strtol(addr, &tmp, 0); + + if (tmp == addr) /* expected a digit, found something else */ + return 0; + + if (ip_addr[quads] < 0 || ip_addr[quads] > 255) { + /* invalid octet */ + return 0; + } + + addr = tmp; + + if (*addr == '.' && quads != 3) + ++addr; /* after the 4th quad, a dot would be illegal */ + } + + for (This->addr.s_addr = 0, i = 0; i < quads; ++i) + This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); + + if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */ + char *tmp; + + ++addr; + + bits = strtol(addr, &tmp, 0); + + if (tmp == addr) /* expected a digit, found something else */ + return 0; + + addr = tmp; + + if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */ + return 0; + + } + else { + /* Determine (i.e., "guess") netmask by counting the */ + /* number of trailing .0's; reduce #quads appropriately */ + /* (so that 192.168.0.0 is equivalent to 192.168.) */ + while (quads > 0 && ip_addr[quads - 1] == 0) + --quads; + + /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */ + if (quads < 1) + return 0; + + /* every zero-byte counts as 8 zero-bits */ + bits = 8 * quads; + + if (bits != 32) /* no warning for fully qualified IP address */ + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld", + inet_ntoa(This->addr), bits); + } + + This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits)); + + if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Warning: NetMask and IP-Addr disagree in %s/%ld", + inet_ntoa(This->addr), bits); + This->addr.s_addr &= This->mask.s_addr; + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " Set to %s/%ld", + inet_ntoa(This->addr), bits); + } + + if (*addr == '\0') { + This->matcher = proxy_match_ipaddr; + return 1; + } + else + return (*addr == '\0'); /* okay iff we've parsed the whole string */ +} + +/* Return TRUE if addr represents an IP address (or an IP network address) */ +static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r) +{ + int i, ip_addr[4]; + struct in_addr addr, *ip; + const char *host = proxy_get_host_of_request(r); + + if (host == NULL) /* oops! */ + return 0; + + memset(&addr, '\0', sizeof addr); + memset(ip_addr, '\0', sizeof ip_addr); + + if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) { + for (addr.s_addr = 0, i = 0; i < 4; ++i) + addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); + + if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) { +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s/", inet_ntoa(This->addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s", inet_ntoa(This->mask)); +#endif + return 1; + } +#if DEBUGGING + else { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s/", inet_ntoa(This->addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s", inet_ntoa(This->mask)); + } +#endif + } + else { + struct apr_sockaddr_t *reqaddr; + + if (apr_sockaddr_info_get(&reqaddr, host, APR_UNSPEC, 0, 0, r->pool) + != APR_SUCCESS) { +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "2)IP-NoMatch: hostname=%s msg=Host not found", + host); +#endif + return 0; + } + + /* Try to deal with multiple IP addr's for a host */ + /* FIXME: This needs to be able to deal with IPv6 */ + while (reqaddr) { + ip = (struct in_addr *) reqaddr->ipaddr_ptr; + if (This->addr.s_addr == (ip->s_addr & This->mask.s_addr)) { +#if DEBUGGING + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "3)IP-Match: %s[%s] <-> ", host, + inet_ntoa(*ip)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s/", inet_ntoa(This->addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s", inet_ntoa(This->mask)); +#endif + return 1; + } +#if DEBUGGING + else { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "3)IP-NoMatch: %s[%s] <-> ", host, + inet_ntoa(*ip)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s/", inet_ntoa(This->addr)); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s", inet_ntoa(This->mask)); + } +#endif + reqaddr = reqaddr->next; + } + } + + return 0; +} + +/* Return TRUE if addr represents a domain name */ +PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p) +{ + char *addr = This->name; + int i; + + /* Domain name must start with a '.' */ + if (addr[0] != '.') + return 0; + + /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */ + for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i) + continue; + +#if 0 + if (addr[i] == ':') { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "@@@@ handle optional port in proxy_is_domainname()"); + /* @@@@ handle optional port */ + } +#endif + + if (addr[i] != '\0') + return 0; + + /* Strip trailing dots */ + for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i) + addr[i] = '\0'; + + This->matcher = proxy_match_domainname; + return 1; +} + +/* Return TRUE if host "host" is in domain "domain" */ +static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r) +{ + const char *host = proxy_get_host_of_request(r); + int d_len = strlen(This->name), h_len; + + if (host == NULL) /* some error was logged already */ + return 0; + + h_len = strlen(host); + + /* @@@ do this within the setup? */ + /* Ignore trailing dots in domain comparison: */ + while (d_len > 0 && This->name[d_len - 1] == '.') + --d_len; + while (h_len > 0 && host[h_len - 1] == '.') + --h_len; + return h_len > d_len + && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0; +} + +/* Return TRUE if host represents a host name */ +PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p) +{ + struct apr_sockaddr_t *addr; + char *host = This->name; + int i; + + /* Host names must not start with a '.' */ + if (host[0] == '.') + return 0; + + /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */ + for (i = 0; apr_isalnum(host[i]) || host[i] == '-' || host[i] == '.'; ++i); + + if (host[i] != '\0' || apr_sockaddr_info_get(&addr, host, APR_UNSPEC, 0, 0, p) != APR_SUCCESS) + return 0; + + This->hostaddr = addr; + + /* Strip trailing dots */ + for (i = strlen(host) - 1; i > 0 && host[i] == '.'; --i) + host[i] = '\0'; + + This->matcher = proxy_match_hostname; + return 1; +} + +/* Return TRUE if host "host" is equal to host2 "host2" */ +static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r) +{ + char *host = This->name; + const char *host2 = proxy_get_host_of_request(r); + int h2_len; + int h1_len; + + if (host == NULL || host2 == NULL) + return 0; /* oops! */ + + h2_len = strlen(host2); + h1_len = strlen(host); + +#if 0 + struct apr_sockaddr_t *addr = *This->hostaddr; + + /* Try to deal with multiple IP addr's for a host */ + while (addr) { + if (addr->ipaddr_ptr == ? ? ? ? ? ? ? ? ? ? ? ? ?) + return 1; + addr = addr->next; + } +#endif + + /* Ignore trailing dots in host2 comparison: */ + while (h2_len > 0 && host2[h2_len - 1] == '.') + --h2_len; + while (h1_len > 0 && host[h1_len - 1] == '.') + --h1_len; + return h1_len == h2_len + && strncasecmp(host, host2, h1_len) == 0; +} + +/* Return TRUE if addr is to be matched as a word */ +PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p) +{ + This->matcher = proxy_match_word; + return 1; +} + +/* Return TRUE if string "str2" occurs literally in "str1" */ +static int proxy_match_word(struct dirconn_entry *This, request_rec *r) +{ + const char *host = proxy_get_host_of_request(r); + return host != NULL && ap_strstr_c(host, This->name) != NULL; +} + +/* checks whether a host in uri_addr matches proxyblock */ +PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, + apr_sockaddr_t *uri_addr) +{ + int j; + apr_sockaddr_t * src_uri_addr = uri_addr; + /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */ + for (j = 0; j < conf->noproxies->nelts; j++) { + struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; + struct apr_sockaddr_t *conf_addr = npent[j].addr; + uri_addr = src_uri_addr; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: checking remote machine [%s] against [%s]", uri_addr->hostname, npent[j].name); + if ((npent[j].name && ap_strstr_c(uri_addr->hostname, npent[j].name)) + || npent[j].name[0] == '*') { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: connect to remote machine %s blocked: name %s matched", uri_addr->hostname, npent[j].name); + return HTTP_FORBIDDEN; + } + while (conf_addr) { + while (uri_addr) { + char *conf_ip; + char *uri_ip; + apr_sockaddr_ip_get(&conf_ip, conf_addr); + apr_sockaddr_ip_get(&uri_ip, uri_addr); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: ProxyBlock comparing %s and %s", conf_ip, uri_ip); + if (!apr_strnatcasecmp(conf_ip, uri_ip)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: connect to remote machine %s blocked: IP %s matched", uri_addr->hostname, conf_ip); + return HTTP_FORBIDDEN; + } + uri_addr = uri_addr->next; + } + conf_addr = conf_addr->next; + } + } + return OK; +} + +/* set up the minimal filter set */ +PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r) +{ + ap_add_input_filter("HTTP_IN", NULL, r, c); + return OK; +} + +/* converts a series of buckets into a string + * XXX: BillS says this function performs essentially the same function as + * ap_rgetline() in protocol.c. Deprecate this function and use ap_rgetline() + * instead? I think ap_proxy_string_read() will not work properly on non ASCII + * (EBCDIC) machines either. + */ +PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, + char *buff, apr_size_t bufflen, int *eos) +{ + apr_bucket *e; + apr_status_t rv; + char *pos = buff; + char *response; + int found = 0; + apr_size_t len; + + /* start with an empty string */ + buff[0] = 0; + *eos = 0; + + /* loop through each brigade */ + while (!found) { + /* get brigade from network one line at a time */ + if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb, + AP_MODE_GETLINE, + APR_BLOCK_READ, + 0))) { + return rv; + } + /* loop through each bucket */ + while (!found) { + if (*eos || APR_BRIGADE_EMPTY(bb)) { + /* The connection aborted or timed out */ + return APR_ECONNABORTED; + } + e = APR_BRIGADE_FIRST(bb); + if (APR_BUCKET_IS_EOS(e)) { + *eos = 1; + } + else { + if (APR_SUCCESS != apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ)) { + return rv; + } + /* is string LF terminated? + * XXX: This check can be made more efficient by simply checking + * if the last character in the 'response' buffer is an ASCII_LF. + * See ap_rgetline() for an example. + */ + if (memchr(response, APR_ASCII_LF, len)) { + found = 1; + } + /* concat strings until buff is full - then throw the data away */ + if (len > ((bufflen-1)-(pos-buff))) { + len = (bufflen-1)-(pos-buff); + } + if (len > 0) { + pos = apr_cpystrn(pos, response, len); + } + } + APR_BUCKET_REMOVE(e); + apr_bucket_destroy(e); + } + } + + return APR_SUCCESS; +} + +/* unmerge an element in the table */ +PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key) +{ + apr_off_t offset = 0; + apr_off_t count = 0; + char *value = NULL; + + /* get the value to unmerge */ + const char *initial = apr_table_get(t, key); + if (!initial) { + return; + } + value = apr_pstrdup(p, initial); + + /* remove the value from the headers */ + apr_table_unset(t, key); + + /* find each comma */ + while (value[count]) { + if (value[count] == ',') { + value[count] = 0; + apr_table_add(t, key, value + offset); + offset = count + 1; + } + count++; + } + apr_table_add(t, key, value + offset); +} + +PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, + proxy_server_conf *conf, const char *url) +{ + struct proxy_alias *ent; + int i, l1, l2; + char *u; + + /* XXX FIXME: Make sure this handled the ambiguous case of the : + * after the hostname */ + + l1 = strlen(url); + ent = (struct proxy_alias *)conf->raliases->elts; + for (i = 0; i < conf->raliases->nelts; i++) { + l2 = strlen(ent[i].real); + if (l1 >= l2 && strncasecmp(ent[i].real, url, l2) == 0) { + u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); + return ap_construct_url(r->pool, u, r); + } + } + + return url; +} + +/* Cookies are a bit trickier to match: we've got two substrings to worry + * about, and we can't just find them with strstr 'cos of case. Regexp + * matching would be an easy fix, but for better consistency with all the + * other matches we'll refrain and use apr_strmatch to find path=/domain= + * and stick to plain strings for the config values. + */ +PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, + proxy_server_conf *conf, const char *str) +{ + struct proxy_alias *ent; + size_t len = strlen(str); + const char *newpath = NULL; + const char *newdomain = NULL; + const char *pathp; + const char *domainp; + const char *pathe = NULL; + const char *domaine = NULL; + size_t l1, l2, poffs = 0, doffs = 0; + int i; + int ddiff = 0; + int pdiff = 0; + char *ret; + + /* Find the match and replacement, but save replacing until we've done + * both path and domain so we know the new strlen + */ + if (pathp = apr_strmatch(conf->cookie_path_str, str, len) ,pathp) { + pathp += 5 ; + poffs = pathp - str; + pathe = ap_strchr_c(pathp, ';'); + l1 = pathe ? (pathe - pathp) : strlen(pathp); + pathe = pathp + l1 ; + ent = (struct proxy_alias *)conf->cookie_paths->elts; + for (i = 0; i < conf->cookie_paths->nelts; i++) { + l2 = strlen(ent[i].fake); + if (l1 >= l2 && strncmp(ent[i].fake, pathp, l2) == 0) { + newpath = ent[i].real; + pdiff = strlen(newpath) - l1; + break; + } + } + } + + if (domainp = apr_strmatch(conf->cookie_domain_str, str, len), domainp) { + domainp += 7; + doffs = domainp - str; + domaine = ap_strchr_c(domainp, ';'); + l1 = domaine ? (domaine - domainp) : strlen(domainp); + domaine = domainp + l1; + ent = (struct proxy_alias *)conf->cookie_domains->elts; + for (i = 0; i < conf->cookie_domains->nelts; i++) { + l2 = strlen(ent[i].fake); + if (l1 >= l2 && strncasecmp(ent[i].fake, domainp, l2) == 0) { + newdomain = ent[i].real; + ddiff = strlen(newdomain) - l1; + break; + } + } + } + + if (newpath) { + ret = apr_palloc(r->pool, len + pdiff + ddiff + 1); + l1 = strlen(newpath); + if (newdomain) { + l2 = strlen(newdomain); + if (doffs > poffs) { + memcpy(ret, str, poffs); + memcpy(ret + poffs, newpath, l1); + memcpy(ret + poffs + l1, pathe, domainp - pathe); + memcpy(ret + doffs + pdiff, newdomain, l2); + strcpy(ret + doffs + pdiff + l2, domaine); + } + else { + memcpy(ret, str, doffs) ; + memcpy(ret + doffs, newdomain, l2); + memcpy(ret + doffs + l2, domaine, pathp - domaine); + memcpy(ret + poffs + ddiff, newpath, l1); + strcpy(ret + poffs + ddiff + l1, pathe); + } + } + else { + memcpy(ret, str, poffs); + memcpy(ret + poffs, newpath, l1); + strcpy(ret + poffs + l1, pathe); + } + } + else { + if (newdomain) { + ret = apr_palloc(r->pool, len + pdiff + ddiff + 1); + l2 = strlen(newdomain); + memcpy(ret, str, doffs); + memcpy(ret + doffs, newdomain, l2); + strcpy(ret + doffs+l2, domaine); + } + else { + ret = (char *)str; /* no change */ + } + } + + return ret; +} + +PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p, + proxy_server_conf *conf, + const char *url) +{ + proxy_balancer *balancer; + char *c, *uri = apr_pstrdup(p, url); + int i; + + c = strchr(uri, ':'); + if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') + return NULL; + /* remove path from uri */ + if ((c = strchr(c + 3, '/'))) + *c = '\0'; + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++) { + if (strcasecmp(balancer->name, uri) == 0) + return balancer; + balancer++; + } + return NULL; +} + +PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer, + apr_pool_t *p, + proxy_server_conf *conf, + const char *url) +{ + char *c, *q, *uri = apr_pstrdup(p, url); + + c = strchr(uri, ':'); + if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') + return "Bad syntax for a balancer name"; + /* remove path from uri */ + if ((q = strchr(c + 3, '/'))) + *q = '\0'; + + ap_str_tolower(uri); + *balancer = apr_array_push(conf->balancers); + memset(*balancer, 0, sizeof(proxy_balancer)); + + (*balancer)->name = uri; + (*balancer)->lbmethod = lbmethod_requests; + (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker)); + /* XXX Is this a right place to create mutex */ +#if APR_HAS_THREADS + if (apr_thread_mutex_create(&((*balancer)->mutex), + APR_THREAD_MUTEX_DEFAULT, p) != APR_SUCCESS) { + /* XXX: Do we need to log something here */ + return "can not create thread mutex"; + } +#endif + + return NULL; +} + +PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, + proxy_server_conf *conf, + const char *url) +{ + proxy_worker *worker; + char *c, *uri = apr_pstrdup(p, url); + int i; + + c = strchr(uri, ':'); + if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') + return NULL; + /* remove path from uri */ + if ((c = strchr(c + 3, '/'))) + *c = '\0'; + + worker = (proxy_worker *)conf->workers->elts; + for (i = 0; i < conf->workers->nelts; i++) { + if (strcasecmp(worker->name, uri) == 0) { + return worker; + } + worker++; + } + return NULL; +} + +#if APR_HAS_THREADS +static apr_status_t conn_pool_cleanup(void *theworker) +{ + proxy_worker *worker = (proxy_worker *)theworker; + if (worker->cp->res) { + worker->cp->pool = NULL; + apr_reslist_destroy(worker->cp->res); + } + return APR_SUCCESS; +} +#endif + +static void init_conn_pool(apr_pool_t *p, proxy_worker *worker) +{ + apr_pool_t *pool; + proxy_conn_pool *cp; + + /* Create a connection pool's subpool. + * This pool is used for connection recycling. + * Once the worker is added it is never removed but + * it can be disabled. + */ + apr_pool_create(&pool, p); + /* Alloc from the same pool as worker. + * proxy_conn_pool is permanently attached to the worker. + */ + cp = (proxy_conn_pool *)apr_pcalloc(p, sizeof(proxy_conn_pool)); + cp->pool = pool; + worker->cp = cp; +} + +PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker, + apr_pool_t *p, + proxy_server_conf *conf, + const char *url) +{ + int rv; + apr_uri_t uri; + + rv = apr_uri_parse(p, url, &uri); + + if (rv != APR_SUCCESS) { + return "Unable to parse URL"; + } + + ap_str_tolower(uri.hostname); + *worker = apr_array_push(conf->workers); + memset(*worker, 0, sizeof(proxy_worker)); + (*worker)->name = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD); + (*worker)->scheme = uri.scheme; + (*worker)->hostname = uri.hostname; + (*worker)->port = uri.port; + (*worker)->id = proxy_lb_workers; + /* Increase the total worker count */ + proxy_lb_workers++; + init_conn_pool(p, *worker); +#if APR_HAS_THREADS + if (apr_thread_mutex_create(&((*worker)->mutex), + APR_THREAD_MUTEX_DEFAULT, p) != APR_SUCCESS) { + /* XXX: Do we need to log something here */ + return "can not create thread mutex"; + } +#endif + + return NULL; +} + +PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p) +{ + + proxy_worker *worker; + worker = (proxy_worker *)apr_pcalloc(p, sizeof(proxy_worker)); + worker->id = proxy_lb_workers; + /* Increase the total worker count */ + proxy_lb_workers++; + init_conn_pool(p, worker); + + return worker; +} + +PROXY_DECLARE(void) +ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, + proxy_worker *worker) +{ + proxy_worker *runtime; + + runtime = apr_array_push(balancer->workers); + memcpy(runtime, worker, sizeof(proxy_worker)); + runtime->id = proxy_lb_workers; + /* Increase the total runtime count */ + proxy_lb_workers++; + +} + +PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, + proxy_balancer **balancer, + request_rec *r, + proxy_server_conf *conf, char **url) +{ + int access_status; + + access_status = proxy_run_pre_request(worker, balancer, r, conf, url); + if (access_status == DECLINED && *balancer == NULL) { + *worker = ap_proxy_get_worker(r->pool, conf, *url); + if (*worker) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy: %s: found worker %s for %s", + (*worker)->scheme, (*worker)->name, *url); + + *balancer = NULL; + access_status = OK; + } + else if (r->proxyreq == PROXYREQ_PROXY) { + if (conf->forward) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy: *: found forward proxy worker for %s", + *url); + *balancer = NULL; + *worker = conf->forward; + access_status = OK; + } + } + else if (r->proxyreq == PROXYREQ_REVERSE) { + if (conf->reverse) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy: *: found reverse proxy worker for %s", + *url); + *balancer = NULL; + *worker = conf->reverse; + access_status = OK; + } + } + } + else if (access_status == DECLINED && balancer != NULL) { + /* All the workers are busy */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: all workers are busy. Unable to serve %s", + *url); + access_status = HTTP_SERVICE_UNAVAILABLE; + } + return access_status; +} + +PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker, + proxy_balancer *balancer, + request_rec *r, + proxy_server_conf *conf) +{ + int access_status; + if (balancer) + access_status = proxy_run_post_request(worker, balancer, r, conf); + else { + + + access_status = OK; + } + + return access_status; +} + +/* DEPRECATED */ +PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **newsock, + const char *proxy_function, + apr_sockaddr_t *backend_addr, + const char *backend_name, + proxy_server_conf *conf, + server_rec *s, + apr_pool_t *p) +{ + apr_status_t rv; + int connected = 0; + int loglevel; + + while (backend_addr && !connected) { + if ((rv = apr_socket_create(newsock, backend_addr->family, + SOCK_STREAM, 0, p)) != APR_SUCCESS) { + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, + "proxy: %s: error creating fam %d socket for target %s", + proxy_function, + backend_addr->family, + backend_name); + /* this could be an IPv6 address from the DNS but the + * local machine won't give us an IPv6 socket; hopefully the + * DNS returned an additional address to try + */ + backend_addr = backend_addr->next; + continue; + } + +#if !defined(TPF) && !defined(BEOS) + if (conf->recv_buffer_size > 0 && + (rv = apr_socket_opt_set(*newsock, APR_SO_RCVBUF, + conf->recv_buffer_size))) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "apr_socket_opt_set(SO_RCVBUF): Failed to set " + "ProxyReceiveBufferSize, using default"); + } +#endif + + /* Set a timeout on the socket */ + if (conf->timeout_set == 1) { + apr_socket_timeout_set(*newsock, conf->timeout); + } + else { + apr_socket_timeout_set(*newsock, s->timeout); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: fam %d socket created to connect to %s", + proxy_function, backend_addr->family, backend_name); + + /* make the connection out of the socket */ + rv = apr_socket_connect(*newsock, backend_addr); + + /* if an error occurred, loop round and try again */ + if (rv != APR_SUCCESS) { + apr_socket_close(*newsock); + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, + "proxy: %s: attempt to connect to %pI (%s) failed", + proxy_function, + backend_addr, + backend_name); + backend_addr = backend_addr->next; + continue; + } + connected = 1; + } + return connected ? 0 : 1; +} + +static apr_status_t connection_cleanup(void *theconn) +{ + proxy_conn_rec *conn = (proxy_conn_rec *)theconn; + proxy_worker *worker = conn->worker; + + /* If the connection pool is NULL the worker + * cleanup has been run. Just return. + */ + if (!worker->cp) + return APR_SUCCESS; + + /* deterimine if the connection need to be closed */ + if (conn->close_on_recycle || conn->close) { + apr_pool_t *p = conn->pool; + apr_pool_clear(conn->pool); + memset(conn, 0, sizeof(proxy_conn_rec)); + conn->pool = p; + conn->worker = worker; + } +#if APR_HAS_THREADS + if (worker->hmax && worker->cp->res) { + apr_reslist_release(worker->cp->res, (void *)conn); + } + else +#endif + { + worker->cp->conn = conn; + } + + /* Allways return the SUCCESS */ + return APR_SUCCESS; +} + +/* reslist constructor */ +static apr_status_t connection_constructor(void **resource, void *params, + apr_pool_t *pool) +{ + apr_pool_t *ctx; + proxy_conn_rec *conn; + proxy_worker *worker = (proxy_worker *)params; + + /* Create the subpool for each connection + * This keeps the memory consumption constant + * when disconnecting from backend. + */ + apr_pool_create(&ctx, pool); + conn = apr_pcalloc(pool, sizeof(proxy_conn_rec)); + + conn->pool = ctx; + conn->worker = worker; + *resource = conn; + + return APR_SUCCESS; +} + +/* reslist destructor */ +static apr_status_t connection_destructor(void *resource, void *params, + apr_pool_t *pool) +{ + proxy_conn_rec *conn = (proxy_conn_rec *)resource; + + /* Destroy the pool only if not called from reslist_destroy */ + if (conn->worker->cp->pool) + apr_pool_destroy(conn->pool); + + return APR_SUCCESS; +} + +PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, + proxy_worker *worker, + server_rec *s) +{ +#if PROXY_HAS_SCOREBOARD + lb_score *score = NULL; +#else + void *score = NULL; +#endif + + if (worker->s && worker->s->status & PROXY_WORKER_INITIALIZED) { + /* The worker share is already initialized */ + return; + } +#if PROXY_HAS_SCOREBOARD + /* Get scoreboard slot */ + if (ap_scoreboard_image) { + score = ap_get_scoreboard_lb(worker->id); + if (!score) + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "proxy: ap_get_scoreboard_lb(%d) failed for worker %s", + worker->id, worker->name); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: initialized scoreboard slot %d for worker %s", + worker->id, worker->name); + } +#endif + if (!score) { + score = apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: initialized plain memory for worker %s", + worker->name); + } + worker->s = (proxy_worker_stat *)score; + if (worker->route) + strcpy(worker->s->route, worker->route); + else + *worker->s->route = '\0'; + if (worker->redirect) + strcpy(worker->s->redirect, worker->redirect); + else + *worker->s->redirect = '\0'; + /* Set default parameters */ + if (!worker->retry) + worker->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY); + /* By default address is reusable */ + worker->is_address_reusable = 1; + +} + +PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s) +{ + apr_status_t rv; + +#if APR_HAS_THREADS + int mpm_threads; +#endif + + if (worker->s->status & PROXY_WORKER_INITIALIZED) { + /* The worker is already initialized */ + return APR_SUCCESS; + } + +#if APR_HAS_THREADS + ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads); + if (mpm_threads > 1) { + /* Set hard max to no more then mpm_threads */ + if (worker->hmax == 0 || worker->hmax > mpm_threads) + worker->hmax = mpm_threads; + if (worker->smax == 0 || worker->smax > worker->hmax) + worker->smax = worker->hmax; + /* Set min to be lower then smax */ + if (worker->min > worker->smax) + worker->min = worker->smax; + } + else { + /* This will supress the apr_reslist creation */ + worker->min = worker->smax = worker->hmax = 0; + } + if (worker->hmax) { + rv = apr_reslist_create(&(worker->cp->res), + worker->min, worker->smax, + worker->hmax, worker->ttl, + connection_constructor, connection_destructor, + worker, worker->cp->pool); + + apr_pool_cleanup_register(worker->cp->pool, (void *)worker, + conn_pool_cleanup, + apr_pool_cleanup_null); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: initialized worker %d in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d", + worker->id, getpid(), worker->hostname, worker->min, + worker->hmax, worker->smax); + +#if (APR_MAJOR_VERSION > 0) + /* Set the acquire timeout */ + if (rv == APR_SUCCESS && worker->acquire_set) + apr_reslist_timeout_set(worker->cp->res, worker->acquire); +#endif + } + else +#endif + { + + rv = connection_constructor((void **)&(worker->cp->conn), worker, worker->cp->pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: initialized single connection worker %d in child %" APR_PID_T_FMT " for (%s)", + worker->id, getpid(), worker->hostname); + } + if (rv == APR_SUCCESS) + worker->s->status |= PROXY_WORKER_INITIALIZED; + return rv; +} + +PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function, + proxy_worker *worker, + server_rec *s) +{ + if (worker->s->status & PROXY_WORKER_IN_ERROR) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: retrying the worker for (%s)", + proxy_function, worker->hostname); + if (apr_time_now() > worker->s->error_time + worker->retry) { + ++worker->s->retries; + worker->s->status &= ~PROXY_WORKER_IN_ERROR; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: worker for (%s) has been marked for retry", + proxy_function, worker->hostname); + return OK; + } + else + return DECLINED; + } + else + return OK; +} + +PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, + proxy_conn_rec **conn, + proxy_worker *worker, + server_rec *s) +{ + apr_status_t rv; + + if (!PROXY_WORKER_IS_USABLE(worker)) { + /* Retry the worker */ + ap_proxy_retry_worker(proxy_function, worker, s); + + if (!PROXY_WORKER_IS_USABLE(worker)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "proxy: %s: disabled connection for (%s)", + proxy_function, worker->hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + } +#if APR_HAS_THREADS + if (worker->hmax && worker->cp->res) { + rv = apr_reslist_acquire(worker->cp->res, (void **)conn); + } + else +#endif + { + /* create the new connection if the previous was destroyed */ + if (!worker->cp->conn) + connection_constructor((void **)conn, worker, worker->cp->pool); + else { + *conn = worker->cp->conn; + worker->cp->conn = NULL; + } + rv = APR_SUCCESS; + } + + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "proxy: %s: failed to acquire connection for (%s)", + proxy_function, worker->hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: has acquired connection for (%s)", + proxy_function, worker->hostname); + + (*conn)->worker = worker; + (*conn)->close = 0; + (*conn)->close_on_recycle = 0; + + return OK; +} + +PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, + proxy_conn_rec *conn, + server_rec *s) +{ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: has released connection for (%s)", + proxy_function, conn->worker->hostname); + /* If there is a connection kill it's cleanup */ + if (conn->connection) { + apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup); + conn->connection = NULL; + } + connection_cleanup(conn); + + return OK; +} + +PROXY_DECLARE(int) +ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + proxy_server_conf *conf, + proxy_worker *worker, + proxy_conn_rec *conn, + apr_uri_t *uri, + char **url, + const char *proxyname, + apr_port_t proxyport, + char *server_portstr, + int server_portstr_size) +{ + int server_port; + apr_status_t err = APR_SUCCESS; + + /* + * Break up the URL to determine the host to connect to + */ + + /* we break the URL into host, port, uri */ + if (APR_SUCCESS != apr_uri_parse(p, *url, uri)) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, + apr_pstrcat(p,"URI cannot be parsed: ", *url, + NULL)); + } + if (!uri->port) { + uri->port = apr_uri_port_of_scheme(uri->scheme); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: connecting %s to %s:%d", *url, uri->hostname, + uri->port); + + /* allocate these out of the specified connection pool + * The scheme handler decides if this is permanent or + * short living pool. + */ + /* are we connecting directly, or via a proxy? */ + if (!proxyname) { + *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "", + uri->query ? uri->query : "", + uri->fragment ? "#" : "", + uri->fragment ? uri->fragment : "", NULL); + } + if (!worker->is_address_reusable) { + if (proxyname) { + conn->hostname = proxyname; + conn->port = proxyport; + } else { + conn->hostname = uri->hostname; + conn->port = uri->port; + } + } + else if (!conn->hostname) { + if (proxyname) { + conn->hostname = apr_pstrdup(conn->pool, proxyname); + conn->port = proxyport; + } else { + conn->hostname = apr_pstrdup(conn->pool, uri->hostname); + conn->port = uri->port; + } + } + /* TODO: add address cache for generic forward proxies. + * At least level 0 -> compare with previous hostname:port + */ + if (r->proxyreq == PROXYREQ_PROXY || r->proxyreq == PROXYREQ_REVERSE || + !worker->is_address_reusable) { + /* TODO: Check if the connection can be reused + */ + if (conn->connection) { + if (conn->sock) { + apr_socket_close(conn->sock); + conn->sock = NULL; + } + apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup); + conn->connection = NULL; + } + err = apr_sockaddr_info_get(&(conn->addr), + conn->hostname, APR_UNSPEC, + conn->port, 0, + conn->pool); + } + else if (!worker->cp->addr) { + if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, + "proxy: lock"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Worker can have the single constant backend adress. + * The single DNS lookup is used once per worker. + * If dynamic change is needed then set the addr to NULL + * inside dynamic config to force the lookup. + */ + err = apr_sockaddr_info_get(&(worker->cp->addr), + conn->hostname, APR_UNSPEC, + conn->port, 0, + worker->cp->pool); + conn->addr = worker->cp->addr; + PROXY_THREAD_UNLOCK(worker); + } + else + conn->addr = worker->cp->addr; + + if (err != APR_SUCCESS) { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + apr_pstrcat(p, "DNS lookup failure for: ", + conn->hostname, NULL)); + } + + /* Get the server port for the Via headers */ + { + server_port = ap_get_server_port(r); + if (ap_is_default_port(server_port, r)) { + strcpy(server_portstr,""); + } else { + apr_snprintf(server_portstr, server_portstr_size, ":%d", + server_port); + } + } + /* check if ProxyBlock directive on this host */ + if (OK != ap_proxy_checkproxyblock(r, conf, conn->addr)) { + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: connected %s to %s:%d", *url, conn->hostname, + conn->port); + return OK; +} + +static int is_socket_connected(apr_socket_t *sock) + +{ + apr_size_t buffer_len = 1; + char test_buffer[1]; + apr_status_t socket_status; + apr_interval_time_t current_timeout; + + /* save timeout */ + apr_socket_timeout_get(sock, ¤t_timeout); + /* set no timeout */ + apr_socket_timeout_set(sock, 0); + socket_status = apr_socket_recv(sock, test_buffer, &buffer_len); + /* put back old timeout */ + apr_socket_timeout_set(sock, current_timeout); + if (APR_STATUS_IS_EOF(socket_status)) + return 0; + else + return 1; +} + +PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + proxy_conn_rec *conn, + proxy_worker *worker, + server_rec *s) +{ + apr_status_t rv; + int connected = 0; + int loglevel; + apr_sockaddr_t *backend_addr = conn->addr; + apr_socket_t *newsock; + + if (conn->sock) { + /* This increases the connection pool size + * but the number of dropped connections is + * relatively small compared to connection lifetime + */ + if (!(connected = is_socket_connected(conn->sock))) { + apr_socket_close(conn->sock); + conn->sock = NULL; + } + } + while (backend_addr && !connected) { + if ((rv = apr_socket_create(&newsock, backend_addr->family, + SOCK_STREAM, APR_PROTO_TCP, + conn->pool)) != APR_SUCCESS) { + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, + "proxy: %s: error creating fam %d socket for target %s", + proxy_function, + backend_addr->family, + worker->hostname); + /* this could be an IPv6 address from the DNS but the + * local machine won't give us an IPv6 socket; hopefully the + * DNS returned an additional address to try + */ + backend_addr = backend_addr->next; + continue; + } + +#if !defined(TPF) && !defined(BEOS) + if (worker->recv_buffer_size > 0 && + (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF, + worker->recv_buffer_size))) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "apr_socket_opt_set(SO_RCVBUF): Failed to set " + "ProxyReceiveBufferSize, using default"); + } +#endif + + /* Set a timeout on the socket */ + if (worker->timeout_set == 1) { + apr_socket_timeout_set(newsock, worker->timeout); + } + else { + apr_socket_timeout_set(newsock, s->timeout); + } + /* Set a keepalive option */ + if (worker->keepalive) { + if ((rv = apr_socket_opt_set(newsock, + APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "apr_socket_opt_set(SO_KEEPALIVE): Failed to set" + " Keepalive"); + } + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: fam %d socket created to connect to %s", + proxy_function, backend_addr->family, worker->hostname); + + /* make the connection out of the socket */ + rv = apr_socket_connect(newsock, backend_addr); + + /* if an error occurred, loop round and try again */ + if (rv != APR_SUCCESS) { + apr_socket_close(newsock); + loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; + ap_log_error(APLOG_MARK, loglevel, rv, s, + "proxy: %s: attempt to connect to %pI (%s) failed", + proxy_function, + backend_addr, + worker->hostname); + backend_addr = backend_addr->next; + continue; + } + + conn->sock = newsock; + connected = 1; + } + /* Put the entire worker to error state if + * the PROXY_WORKER_IGNORE_ERRORS flag is not set. + * Altrough some connections may be alive + * no further connections to the worker could be made + */ + if (!connected && PROXY_WORKER_IS_USABLE(worker) && + !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { + worker->s->status |= PROXY_WORKER_IN_ERROR; + worker->s->error_time = apr_time_now(); + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "ap_proxy_connect_backend disabling worker for (%s)", + worker->hostname); + } + else { + worker->s->error_time = 0; + worker->s->retries = 0; + } + return connected ? OK : DECLINED; +} + +PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, + proxy_conn_rec *conn, + conn_rec *c, + server_rec *s) +{ + apr_sockaddr_t *backend_addr = conn->addr; + int rc; + + /* The socket is now open, create a new backend server connection + * + */ + conn->connection = ap_run_create_connection(c->pool, s, conn->sock, + c->id, c->sbh, + c->bucket_alloc); + + if (!conn->connection) { + /* the peer reset the connection already; ap_run_create_connection() + * closed the socket + */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + s, "proxy: %s: an error occurred creating a " + "new connection to %pI (%s)", proxy_function, + backend_addr, conn->hostname); + /* XXX: Will be closed when proxy_conn is closed */ + apr_socket_close(conn->sock); + conn->sock = NULL; + return HTTP_INTERNAL_SERVER_ERROR; + } + /* register the connection cleanup to client connection + * so that the connection can be closed or reused + */ + apr_pool_cleanup_register(c->pool, (void *)conn, + connection_cleanup, + apr_pool_cleanup_null); + + /* For ssl connection to backend */ + if (conn->is_ssl) { + if (!ap_proxy_ssl_enable(conn->connection)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + s, "proxy: %s: failed to enable ssl support " + "for %pI (%s)", proxy_function, + backend_addr, conn->hostname); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + else { + /* TODO: See if this will break FTP */ + ap_proxy_ssl_disable(conn->connection); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: connection complete to %pI (%s)", + proxy_function, backend_addr, conn->hostname); + + /* set up the connection filters */ + rc = ap_run_pre_connection(conn->connection, conn->sock); + if (rc != OK && rc != DONE) { + conn->connection->aborted = 1; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: pre_connection setup failed (%d)", + proxy_function, rc); + return rc; + } + + return OK; +} + +int ap_proxy_lb_workers(void) +{ + /* Since we can't resize the scoreboard when reconfiguring, we + * have to impose a limit on the number of workers, we are + * able to reconfigure to. + */ + if (!lb_workers_limit) + lb_workers_limit = proxy_lb_workers + PROXY_DYNAMIC_BALANCER_LIMIT; + return lb_workers_limit; +} diff --git a/trunk/modules/ssl/Makefile.in b/trunk/modules/ssl/Makefile.in new file mode 100644 index 0000000000..2a64d5b380 --- /dev/null +++ b/trunk/modules/ssl/Makefile.in @@ -0,0 +1,38 @@ +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# standard stuff +# + +include $(top_srcdir)/build/special.mk + +# +# developer stuff +# (we really don't expect end users to use these targets!) +# + +ssl_expr_scan.c: $(top_srcdir)/modules/ssl/ssl_expr_scan.l ssl_expr_parse.h + flex -Pssl_expr_yy -s -B $(top_srcdir)/modules/ssl/ssl_expr_scan.l + sed -e '/$$Header:/d' ssl_expr_scan.c && rm -f lex.ssl_expr_yy.c + +ssl_expr_parse.c ssl_expr_parse.h: $(top_srcdir)/modules/ssl/ssl_expr_parse.y + yacc -d $(top_srcdir)/modules/ssl/ssl_expr_parse.y + sed -e 's;yy;ssl_expr_yy;g' \ + -e '/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d' \ + ssl_expr_parse.c && rm -f y.tab.c + sed -e 's;yy;ssl_expr_yy;g' \ + ssl_expr_parse.h && rm -f y.tab.h + diff --git a/trunk/modules/ssl/NWGNUmakefile b/trunk/modules/ssl/NWGNUmakefile new file mode 100644 index 0000000000..dd62f6df62 --- /dev/null +++ b/trunk/modules/ssl/NWGNUmakefile @@ -0,0 +1,289 @@ +# +# This Makefile requires the environment var OSSLSDK +# pointing to the base directory of your OpenSSL SDK. +# + +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files +# +# Make sure all needed macro's are defined +# + +OSSLINC = $(OSSLSDK)/outinc_nw_libc +OSSLLIB = $(OSSLSDK)/out_nw_libc + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(OSSLINC) \ + $(OSSLINC)/openssl \ + $(AP_WORK)/include \ + $(AP_WORK)/server/mpm/NetWare \ + $(AP_WORK)/modules/arch/netware \ + $(AP_WORK)/modules/generators \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR) \ + $(NWOS) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + -relax_pointers \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + -DHAVE_OPENSSL \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + -l $(OSSLLIB) \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = mod_ssl + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) SSL module + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = mod_ssl + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/mod_ssl.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs := $(patsubst %.c,$(OBJDIR)/%.o,$(wildcard *.c)) + + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(OSSLLIB)/crypto.lib \ + $(OSSLLIB)/ssl.lib \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Apache2 \ + Libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + @$(APR)/aprlib.imp \ + @httpd.imp \ + GetProcessSwitchCount \ + RunningProcess \ + GetSuperHighResolutionTimer \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + ssl_module \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\mod_ssl.nlm $(INSTALL)\Apache2\modules\*.* + +# +# Any specialized rules here +# +vpath %.c $(AP_WORK)/modules/arch/netware + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + + diff --git a/trunk/modules/ssl/README b/trunk/modules/ssl/README new file mode 100644 index 0000000000..5f9421cf50 --- /dev/null +++ b/trunk/modules/ssl/README @@ -0,0 +1,107 @@ +SYNOPSIS + + This Apache module provides strong cryptography for the Apache 2 webserver + via the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS + v1) protocols by the help of the SSL/TLS implementation library OpenSSL which + is based on SSLeay from Eric A. Young and Tim J. Hudson. + + The mod_ssl package was created in April 1998 by Ralf S. Engelschall + and was originally derived from software developed by Ben Laurie for + use in the Apache-SSL HTTP server project. The mod_ssl implementation + for Apache 1.3 continues to be supported by the modssl project + . + +SOURCES + + See the top-level LAYOUT file in httpd-2.1 for file descriptions. + + The source files are written in clean ANSI C and pass the ``gcc -O -g + -ggdb3 -Wall -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes + -Wmissing-declarations -Wnested-externs -Winline'' compiler test + (assuming `gcc' is GCC 2.95.2 or newer) without any complains. When + you make changes or additions make sure the source still passes this + compiler test. + +FUNCTIONS + + Inside the source code you will be confronted with the following types of + functions which can be identified by their prefixes: + + ap_xxxx() ............... Apache API function + ssl_xxxx() .............. mod_ssl function + SSL_xxxx() .............. OpenSSL function (SSL library) + OpenSSL_xxxx() .......... OpenSSL function (SSL library) + X509_xxxx() ............. OpenSSL function (Crypto library) + PEM_xxxx() .............. OpenSSL function (Crypto library) + EVP_xxxx() .............. OpenSSL function (Crypto library) + RSA_xxxx() .............. OpenSSL function (Crypto library) + +DATA STRUCTURES + + Inside the source code you will be confronted with the following + data structures: + + server_rec .............. Apache (Virtual) Server + conn_rec ................ Apache Connection + request_rec ............. Apache Request + SSLModConfig ............ mod_ssl (Global) Module Configuration + SSLSrvConfig ............ mod_ssl (Virtual) Server Configuration + SSLDirConfig ............ mod_ssl Directory Configuration + SSLConnConfig ........... mod_ssl Connection Configuration + SSLFilterRec ............ mod_ssl Filter Context + SSL_CTX ................. OpenSSL Context + SSL_METHOD .............. OpenSSL Protocol Method + SSL_CIPHER .............. OpenSSL Cipher + SSL_SESSION ............. OpenSSL Session + SSL ..................... OpenSSL Connection + BIO ..................... OpenSSL Connection Buffer + + For an overview how these are related and chained together have a look at the + page in README.dsov.{fig,ps}. It contains overview diagrams for those data + structures. It's designed for DIN A4 paper size, but you can easily generate + a smaller version inside XFig by specifing a magnification on the Export + panel. + +INCOMPATIBILITIES + + The following intentional incompatibilities exist between mod_ssl 2.x + from Apache 1.3 and this mod_ssl version for Apache 2: + + o The complete EAPI-based SSL_VENDOR stuff was removed. + o The complete EAPI-based SSL_COMPAT stuff was removed. + o The variable MOD_SSL is no longer provided automatically + +MAJOR CHANGES + + For a complete history of changes for Apache 2 mod_ssl, see the + CHANGES file in the top-level httpd-2.1 directory. The following + is a condensed summary of the major changes were made between + mod_ssl 2.x from Apache 1.3 and this mod_ssl version for Apache 2: + + o The DBM based session cache is now based on APR's DBM API only. + o The shared memory based session cache is now based on APR's APIs. + o SSL I/O is now implemented in terms of filters rather than BUFF + o Eliminated ap_global_ctx. Storing Persistant information in + process_rec->pool->user_data. The ssl_pphrase_Handle_CB() and + ssl_config_global_* () functions have an extra parameter now - + "server_rec *" - which is used to retrieve the SSLModConfigRec. + o Properly support restarts, allowing mod_ssl to be added to a server + that is already running and to change server certs/keys on restart + o Various performance enhancements + o proxy support is no longer an "extension", much of the mod_ssl core + was re-written (ssl_engine_{init,kernel,config}.c) to be generic so + it could be re-used in proxy mode. + - the optional function ssl_proxy_enable is provide for mod_proxy + to enable proxy support + - proxy support now requires 'SSLProxyEngine on' to be configured + - proxy now supports SSLProxyCARevocation{Path,File} in addition to + the original SSLProxy* directives + o per-directory SSLCACertificate{File,Path} is now thread-safe but + requires SSL_set_cert_store patch to OpenSSL + o RSA sslc is supported via ssl_toolkit_compat.h + o the ssl_engine_{ds,ext}.c source files are obsolete and no longer + exist + +TODO + + See the top-level STATUS file in httpd-2.1 for current efforts and goals. diff --git a/trunk/modules/ssl/README.dsov.fig b/trunk/modules/ssl/README.dsov.fig new file mode 100644 index 0000000000..d8d03db247 --- /dev/null +++ b/trunk/modules/ssl/README.dsov.fig @@ -0,0 +1,346 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +0 32 #616561 +0 33 #b6b2b6 +0 34 #f7f3f7 +0 35 #cfcfcf +0 36 #ffffff +6 6345 2835 7155 3150 +6 6345 2970 7110 3150 +4 0 0 200 0 20 8 0.0000 4 120 585 6345 3105 "ssl_module")\001 +-6 +4 0 0 200 0 20 8 0.0000 4 120 660 6345 2970 ap_ctx_get(...,\001 +-6 +6 10800 2610 12240 3060 +4 0 0 200 0 20 8 0.0000 4 120 1170 10800 2745 ap_get_module_config(...\001 +4 0 0 200 0 20 8 0.0000 4 120 795 10800 2880 ->per_dir_config,\001 +4 0 0 200 0 20 8 0.0000 4 120 585 10800 3015 &ssl_module)\001 +-6 +6 7920 4770 9135 4995 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 9135 4995 7920 4995 7920 4770 9135 4770 9135 4995 +4 0 0 100 0 18 12 0.0000 4 180 1065 8010 4950 request_rec\001 +-6 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6975 3330 7425 2520 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7200 4230 9450 2520 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7875 4905 7200 5220 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6750 5130 6750 4545 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6705 5445 7155 6120 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7875 4815 7200 4590 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9585 2565 11475 4230 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 10170 5130 11835 4545 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7920 6075 9855 5400 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9990 5445 10935 5625 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 10215 5310 10935 5310 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 11925 4590 11925 5085 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9810 5490 9810 6840 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9945 5445 10935 6030 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 8865 4725 10800 2565 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 675 6075 5850 6075 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 675 6525 675 6075 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 5850 6075 5850 6525 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 900 5625 5625 5625 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 1125 5175 5400 5175 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 1350 4725 5175 4725 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 1575 4275 4950 4275 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 1800 3825 4725 3825 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 2025 3375 4500 3375 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 2250 2925 4275 2925 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 2475 2475 4050 2475 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 2700 2025 3825 2025 +2 1 0 3 0 34 200 0 20 0.000 0 0 -1 0 0 2 + 2925 1575 3600 1575 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 900 6075 900 5625 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1125 6525 1125 5175 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1350 5175 1350 4725 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1575 4725 1575 4275 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1800 6525 1800 3825 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2025 3825 2025 3375 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2250 3375 2250 2925 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2475 2925 2475 2475 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 5625 5625 5625 6075 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 5400 5175 5400 6525 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 5175 4725 5175 5175 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 4950 4275 4950 4725 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 4725 3825 4725 6525 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 4500 3375 4500 3825 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 4275 2925 4275 3375 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 4050 2475 4050 2925 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 6525 2700 2025 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 3825 2025 3825 6525 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 0 1.00 60.00 120.00 + 3600 1575 3600 2025 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2925 2025 2925 1575 +2 1 0 4 0 0 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 4.00 60.00 120.00 + 540 6525 6300 6525 +2 3 0 1 7 7 800 0 20 0.000 0 0 -1 0 0 9 + 675 6525 5850 6525 5850 6075 5625 6075 5625 5625 900 5625 + 900 6075 675 6075 675 6525 +2 3 0 1 34 34 700 0 20 0.000 0 0 -1 0 0 13 + 1125 6525 5355 6525 5400 5175 5175 5175 5175 4725 4950 4725 + 4950 4275 1575 4275 1575 4725 1350 4725 1350 5175 1125 5175 + 1125 6525 +2 3 0 1 35 35 500 0 20 0.000 0 0 -1 0 0 17 + 1800 6525 4725 6525 4725 3825 4500 3825 4500 3375 4275 3375 + 4275 2925 4050 2925 4050 2475 2475 2475 2475 2925 2250 2925 + 2250 3375 2025 3375 2025 3825 1800 3825 1800 6525 +2 3 0 1 33 33 400 0 20 0.000 0 0 -1 0 0 9 + 2700 6525 3825 6525 3825 2025 3600 2025 3600 1575 2925 1575 + 2925 2025 2700 2025 2700 6525 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2 + 2 0 1.00 60.00 120.00 + 2 0 1.00 60.00 120.00 + 2700 6750 3825 6750 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2 + 2 0 1.00 60.00 120.00 + 2 0 1.00 60.00 120.00 + 1125 7200 5400 7200 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2 + 2 0 1.00 60.00 120.00 + 2 0 1.00 60.00 120.00 + 1800 6975 4725 6975 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 1 2 + 2 0 1.00 60.00 120.00 + 2 0 1.00 60.00 120.00 + 675 7425 5850 7425 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 675 6570 675 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 1125 6570 1125 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 1800 6570 1800 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 2700 6570 2700 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 3825 6570 3825 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 4725 6570 4725 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 5400 6570 5400 7650 +2 1 2 1 0 34 200 0 20 3.000 0 1 -1 0 0 2 + 5850 6570 5850 7650 +2 4 0 2 0 7 100 0 -1 0.000 0 0 20 0 0 5 + 12600 8550 450 8550 450 225 12600 225 12600 8550 +2 4 0 1 0 34 200 0 20 0.000 0 0 20 0 0 5 + 12600 1350 450 1350 450 225 12600 225 12600 1350 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 10170 2475 8775 2475 8775 2250 10170 2250 10170 2475 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 11925 2475 10575 2475 10575 2250 11925 2250 11925 2475 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 12375 4500 11430 4500 11430 4275 12375 4275 12375 4500 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 12375 5400 10980 5400 10980 5175 12375 5175 12375 5400 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 10170 5400 9675 5400 9675 5175 10170 5175 10170 5400 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 7875 6300 7200 6300 7200 6075 7875 6075 7875 6300 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 8190 2475 6750 2475 6750 2250 8190 2250 8190 2475 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 7605 3600 6300 3600 6300 3375 7605 3375 7605 3600 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 7335 4500 6300 4500 6300 4275 7335 4275 7335 4500 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 7200 5400 6300 5400 6300 5175 7200 5175 7200 5400 +2 1 0 6 7 7 600 0 -1 0.000 0 0 -1 0 0 2 + 9450 4500 6075 1935 +2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2 + 9450 4500 12465 2205 +2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2 + 9450 4500 9450 7785 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9630 5310 7245 5310 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 11385 4365 7380 4365 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 12240 5805 10980 5805 10980 5580 12240 5580 12240 5805 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 12375 6210 10980 6210 10980 5985 12375 5985 12375 6210 +2 1 0 1 0 34 200 0 20 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 11205 6885 9900 5445 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 12285 7155 10530 7155 10530 6930 12285 6930 12285 7155 +2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 + 10170 7155 9630 7155 9630 6930 10170 6930 10170 7155 +2 1 0 6 7 7 600 0 -1 0.000 0 0 4 0 0 2 + 12510 6435 9450 6435 +2 1 0 1 0 34 300 0 20 0.000 0 0 7 1 0 4 + 1 1 1.00 60.00 120.00 + 12375 4455 12510 4635 12510 6210 11970 6885 +2 1 2 1 0 34 200 0 20 1.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 9850 5143 9175 4918 +3 1 0 1 34 34 800 0 20 0.000 0 0 0 41 + 7380 1710 6390 2115 5535 2115 6075 3015 5670 3465 6165 3915 + 5715 4410 6030 5040 6030 5310 6480 5715 6390 6255 6975 6300 + 7065 6975 7965 6750 8100 7560 8955 7290 9360 7740 9720 7560 + 10755 8145 12060 8280 12375 7650 12420 7200 12510 7065 12330 6660 + 12510 6390 12420 5940 12375 5400 12510 5220 12510 4725 12600 4275 + 12375 3645 12105 3240 12150 2745 12375 2700 12330 1980 11790 1575 + 11250 1935 10125 1485 8955 2070 7785 1620 7695 1575 + 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 + 1.000 +4 0 0 100 0 0 12 0.0000 4 180 1440 10575 675 Ralf S. Engelschall\001 +4 0 0 100 0 18 20 0.0000 4 270 3840 4275 675 Apache+mod_ssl+OpenSSL\001 +4 0 0 100 0 0 10 0.0000 4 135 1320 10575 855 rse@engelschall.com\001 +4 0 0 100 0 0 10 0.0000 4 135 1410 10575 1035 www.engelschall.com\001 +4 0 0 100 0 0 12 0.0000 4 135 870 900 675 Version 1.3\001 +4 0 0 100 0 0 12 0.0000 4 180 1035 900 855 12-Apr-1999\001 +4 0 0 200 0 20 8 0.0000 4 60 390 6210 4680 ->server\001 +4 0 0 200 0 20 8 0.0000 4 120 855 8280 6120 ap_ctx_get(...,"ssl")\001 +4 0 0 200 0 20 8 0.0000 4 120 1170 7740 2700 ap_get_module_config(...\001 +4 0 0 200 0 20 8 0.0000 4 120 810 7740 2835 ->module_config,\001 +4 0 0 200 0 20 8 0.0000 4 120 585 7740 2970 &ssl_module)\001 +4 0 0 100 0 18 20 0.0000 4 270 1200 9000 8100 Chaining\001 +4 0 0 100 0 18 20 0.0000 4 210 1095 2745 8100 Lifetime\001 +4 0 0 100 0 18 12 0.0000 4 180 1215 810 6255 ap_global_ctx\001 +4 0 0 100 0 18 12 0.0000 4 180 1305 990 5805 SSLModConfig\001 +4 0 0 100 0 18 12 0.0000 4 180 840 4050 4455 SSL_CTX\001 +4 0 0 100 0 18 12 0.0000 4 150 975 4455 5355 server_rec\001 +4 0 0 100 0 18 12 0.0000 4 180 1260 3870 4905 SSLSrvConfig\001 +4 0 0 100 0 18 12 0.0000 4 135 480 1845 4005 BUFF\001 +4 0 0 100 0 18 12 0.0000 4 150 810 2070 3555 conn_rec\001 +4 0 0 100 0 18 12 0.0000 4 135 345 2295 3105 BIO\001 +4 0 0 100 0 18 12 0.0000 4 135 375 2565 2655 SSL\001 +4 0 0 100 0 18 12 0.0000 4 180 1185 3645 1620 SSLDirConfig\001 +4 0 0 100 0 18 12 0.0000 4 180 1065 3915 2070 request_rec\001 +4 0 0 200 0 0 8 0.0000 4 120 1440 900 7560 Startup, Runtime, Shutdown\001 +4 0 0 200 0 0 8 0.0000 4 105 975 1350 7335 Configuration Time\001 +4 0 0 200 0 0 8 0.0000 4 90 1050 2025 7110 Connection Duration\001 +4 0 0 200 0 0 8 0.0000 4 120 885 2835 6885 Request Duration\001 +4 0 0 200 0 18 20 0.0000 4 195 90 6345 6795 t\001 +4 0 0 200 0 20 8 0.0000 4 90 345 7110 5985 ->client\001 +4 0 0 100 0 18 12 0.0000 4 180 1305 6795 2430 SSLModConfig\001 +4 0 0 100 0 18 12 0.0000 4 180 1260 8865 2430 SSLSrvConfig\001 +4 0 0 100 0 18 12 0.0000 4 180 1215 6345 3555 ap_global_ctx\001 +4 0 0 100 0 18 12 0.0000 4 150 975 6345 4455 server_rec\001 +4 0 0 100 0 18 12 0.0000 4 150 810 6345 5355 conn_rec\001 +4 0 0 100 0 18 12 0.0000 4 135 375 9720 5355 SSL\001 +4 0 0 100 0 18 12 0.0000 4 180 1185 10665 2430 SSLDirConfig\001 +4 0 0 100 0 18 12 0.0000 4 135 480 7290 6255 BUFF\001 +4 0 0 100 0 18 12 0.0000 4 180 1305 11025 5355 SSL_METHOD\001 +4 0 0 100 0 18 12 0.0000 4 180 840 11475 4455 SSL_CTX\001 +4 0 0 100 0 18 24 0.0000 4 285 4365 3915 1080 Data Structure Overview\001 +4 0 0 200 0 20 8 0.0000 4 90 615 7065 5085 ->connection\001 +4 0 0 200 0 20 8 0.0000 4 60 390 7065 4770 ->server\001 +4 0 0 200 0 20 8 0.0000 4 120 960 8010 5445 SSL_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 510 10530 4050 ->pSSLCtx\001 +4 0 0 200 0 20 8 0.0000 4 120 1215 7875 4275 SSL_CTX_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 1155 10305 5535 SSL_get_current_cipher()\001 +4 0 0 100 0 18 12 0.0000 4 180 1170 11025 5760 SSL_CIPHER\001 +4 0 0 100 0 18 12 0.0000 4 180 1350 10980 6165 SSL_SESSION\001 +4 0 0 200 0 20 8 0.0000 4 120 840 10440 5940 SSL_get_session()\001 +4 0 0 100 0 18 12 0.0000 4 180 1665 10575 7110 X509_STORE_CTX\001 +4 0 0 100 0 18 12 0.0000 4 135 345 9720 7110 BIO\001 +4 0 0 200 0 20 8 0.0000 4 120 840 9540 7335 SSL_get_{r,w}bio()\001 +4 0 0 100 0 18 20 0.0000 4 270 1170 8730 3465 mod_ssl\001 +4 0 0 100 0 18 20 0.0000 4 270 1050 8145 6750 Apache\001 +4 0 0 200 0 20 8 0.0000 4 120 945 10125 4680 SSL_get_SSL_CTX()\001 +4 0 0 200 0 20 8 0.0000 4 120 1170 10350 5175 SSL_get_SSL_METHOD()\001 +4 0 0 200 0 20 8 0.0000 4 90 465 11745 4770 ->method\001 +4 0 0 200 0 20 8 0.0000 4 120 1665 9945 6480 X509_STORE_CTX_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 1215 10980 6705 SSL_CTX_get_cert_store()\001 +4 0 0 200 0 20 8 0.0000 4 120 1020 8280 5130 SSL_get_app_data2()\001 +4 0 0 100 0 18 20 0.0000 4 270 1290 10710 7605 OpenSSL\001 +4 0 0 100 0 18 12 0.0000 4 180 720 10710 7785 [Crypto]\001 +4 0 0 100 0 18 20 0.0000 4 270 1290 10935 3645 OpenSSL\001 +4 0 0 100 0 18 12 0.0000 4 180 495 10935 3825 [SSL]\001 diff --git a/trunk/modules/ssl/README.dsov.ps b/trunk/modules/ssl/README.dsov.ps new file mode 100644 index 0000000000..def19dbecf --- /dev/null +++ b/trunk/modules/ssl/README.dsov.ps @@ -0,0 +1,1138 @@ +%!PS-Adobe-2.0 +%%Title: README.dsov.ps +%%Creator: fig2dev Version 3.2 Patchlevel 1 +%%CreationDate: Mon Apr 12 17:09:11 1999 +%%For: rse@en1.engelschall.com (Ralf S. Engelschall) +%%Orientation: Landscape +%%BoundingBox: 59 37 553 755 +%%Pages: 1 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%Magnification: 0.9340 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def +/col32 {0.380 0.396 0.380 srgb} bind def +/col33 {0.714 0.698 0.714 srgb} bind def +/col34 {0.969 0.953 0.969 srgb} bind def +/col35 {0.812 0.812 0.812 srgb} bind def +/col36 {1.000 1.000 1.000 srgb} bind def + +end +save +48.0 12.0 translate + 90 rotate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/reencdict 12 dict def /ReEncode { reencdict begin +/newcodesandnames exch def /newfontname exch def /basefontname exch def +/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def +basefontdict { exch dup /FID ne { dup /Encoding eq +{ exch dup length array copy newfont 3 1 roll put } +{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall +newfont /FontName newfontname put newcodesandnames aload pop +128 1 255 { newfont /Encoding get exch /.notdef put } for +newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat +newfontname newfont definefont pop end } def +/isovec [ +8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde +8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis +8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron +8#220 /dotlessi 8#230 /oe 8#231 /OE +8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling +8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis +8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot +8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus +8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph +8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine +8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf +8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute +8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring +8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute +8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute +8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve +8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply +8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex +8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave +8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring +8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute +8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute +8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve +8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide +8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex +8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def +/Times-Roman /Times-Roman-iso isovec ReEncode +/Helvetica-Bold /Helvetica-Bold-iso isovec ReEncode +/Helvetica-Narrow /Helvetica-Narrow-iso isovec ReEncode +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit +n -1000 9572 m -1000 -1000 l 13622 -1000 l 13622 9572 l cp clip + 0.05883 0.05883 sc +%%Page: 1 1 +% Polyline +7.500 slw +n 6413 2048 m 6380 2054 l 6348 2061 l 6315 2067 l 6283 2073 l 6250 2079 l + 6217 2084 l 6185 2090 l 6152 2095 l 6120 2101 l 6088 2107 l + 6057 2113 l 6027 2120 l 5998 2126 l 5970 2134 l 5943 2141 l + 5918 2149 l 5894 2158 l 5873 2167 l 5853 2177 l 5835 2187 l + 5819 2198 l 5805 2210 l 5793 2222 l 5782 2235 l 5774 2250 l + 5768 2265 l 5763 2281 l 5760 2299 l 5759 2318 l 5759 2339 l + 5761 2360 l 5764 2383 l 5768 2408 l 5774 2433 l 5780 2460 l + 5788 2488 l 5797 2516 l 5806 2546 l 5815 2575 l 5825 2606 l + 5836 2636 l 5846 2666 l 5856 2696 l 5866 2726 l 5875 2755 l + 5884 2784 l 5892 2812 l 5899 2839 l 5905 2866 l 5910 2891 l + 5915 2916 l 5918 2940 l 5919 2968 l 5920 2995 l 5919 3022 l + 5916 3048 l 5912 3075 l 5908 3101 l 5902 3127 l 5895 3153 l + 5887 3179 l 5880 3205 l 5871 3230 l 5863 3254 l 5855 3278 l + 5848 3302 l 5841 3324 l 5834 3346 l 5829 3367 l 5824 3388 l + 5821 3408 l 5819 3427 l 5819 3446 l 5820 3465 l 5823 3484 l + 5827 3503 l 5833 3522 l 5840 3542 l 5848 3562 l 5858 3582 l + 5868 3603 l 5880 3625 l 5891 3647 l 5904 3669 l 5916 3691 l + 5929 3713 l 5941 3736 l 5953 3758 l 5964 3779 l 5974 3801 l + 5983 3822 l 5991 3843 l 5997 3863 l 6002 3883 l 6006 3903 l + 6008 3923 l 6008 3942 l 6006 3962 l 6003 3983 l 5998 4004 l + 5992 4025 l 5985 4048 l 5977 4070 l 5968 4094 l 5958 4118 l + 5947 4142 l 5936 4167 l 5925 4192 l 5913 4216 l 5902 4241 l + 5892 4266 l 5882 4291 l 5872 4315 l 5864 4339 l 5857 4362 l + 5851 4386 l 5846 4409 l 5843 4433 l 5840 4456 l 5840 4480 l + 5840 4505 l 5842 4530 l 5845 4556 l 5849 4582 l 5854 4609 l + 5860 4636 l 5867 4664 l 5875 4692 l 5883 4720 l 5892 4747 l + 5901 4774 l 5910 4801 l 5920 4827 l 5929 4852 l 5938 4875 l + 5947 4898 l 5955 4920 l 5963 4941 l 5971 4961 l 5978 4980 l + 5985 5002 l 5992 5024 l 5999 5046 l 6005 5067 l 6010 5088 l + 6016 5109 l 6022 5129 l 6027 5150 l 6033 5170 l 6039 5190 l + 6045 5209 l 6052 5228 l 6059 5246 l 6067 5264 l 6075 5281 l + 6084 5298 l 6094 5315 l 6105 5333 l 6115 5347 l 6125 5361 l + 6137 5376 l 6149 5392 l 6162 5408 l 6176 5425 l 6191 5443 l + 6206 5461 l 6221 5480 l 6237 5499 l 6253 5519 l 6269 5539 l + 6284 5559 l 6299 5579 l 6313 5599 l 6327 5619 l 6340 5639 l + 6352 5659 l 6363 5679 l 6373 5698 l 6382 5718 l 6390 5738 l + 6398 5759 l 6404 5782 l 6410 5805 l 6415 5828 l 6420 5852 l + 6424 5877 l 6428 5902 l 6431 5927 l 6435 5952 l 6438 5977 l + 6442 6001 l 6446 6025 l 6450 6048 l 6455 6069 l 6461 6090 l + 6467 6109 l 6474 6127 l 6483 6143 l 6492 6159 l 6503 6173 l + 6515 6185 l 6528 6197 l 6543 6209 l 6560 6220 l 6578 6230 l + 6598 6240 l 6619 6250 l 6641 6260 l 6663 6270 l 6687 6281 l + 6710 6291 l 6733 6302 l 6757 6312 l 6779 6324 l 6801 6335 l + 6821 6348 l 6841 6361 l 6859 6374 l 6876 6389 l 6893 6405 l + 6906 6421 l 6919 6437 l 6932 6455 l 6944 6475 l 6955 6495 l + 6967 6516 l 6979 6538 l 6991 6561 l 7003 6584 l 7015 6608 l + 7027 6631 l 7040 6654 l 7053 6677 l 7067 6699 l 7081 6720 l + 7096 6739 l 7111 6758 l 7127 6774 l 7144 6789 l 7161 6803 l + 7180 6815 l 7200 6825 l 7220 6833 l 7240 6840 l 7263 6845 l + 7286 6850 l 7311 6854 l 7338 6857 l 7365 6859 l 7394 6861 l + 7424 6862 l 7454 6864 l 7485 6865 l 7516 6866 l 7547 6867 l + 7578 6868 l 7609 6870 l 7639 6872 l 7668 6875 l 7696 6879 l + 7723 6883 l 7748 6889 l 7773 6895 l 7795 6903 l 7817 6912 l + 7838 6923 l 7857 6934 l 7875 6948 l 7892 6963 l 7909 6980 l + 7926 6998 l 7941 7017 l 7957 7038 l 7972 7060 l 7987 7083 l + 8002 7106 l 8017 7130 l 8031 7154 l 8046 7178 l 8061 7202 l + 8075 7225 l 8090 7247 l 8105 7269 l 8120 7289 l 8135 7308 l + 8151 7326 l 8167 7342 l 8184 7356 l 8202 7369 l 8220 7380 l + 8239 7390 l 8260 7397 l 8282 7404 l 8305 7409 l 8330 7413 l + 8356 7416 l 8383 7418 l 8412 7420 l 8441 7420 l 8471 7419 l + 8502 7418 l 8534 7417 l 8565 7415 l 8597 7413 l 8629 7411 l + 8660 7409 l 8690 7407 l 8720 7405 l 8749 7404 l 8777 7404 l + 8804 7404 l 8830 7405 l 8856 7407 l 8880 7410 l 8906 7414 l + 8931 7420 l 8956 7427 l 8981 7435 l 9005 7444 l 9029 7455 l + 9053 7466 l 9077 7478 l 9100 7491 l 9123 7504 l 9146 7517 l + 9168 7531 l 9190 7544 l 9210 7557 l 9230 7570 l 9250 7582 l + 9268 7593 l 9286 7604 l 9304 7613 l 9320 7621 l 9336 7629 l + 9353 7635 l 9370 7641 l 9388 7645 l 9406 7648 l 9425 7650 l + 9444 7652 l 9464 7653 l 9485 7653 l 9508 7653 l 9531 7653 l + 9555 7653 l 9579 7653 l 9605 7654 l 9631 7655 l 9658 7656 l + 9685 7659 l 9713 7662 l 9742 7666 l 9771 7672 l 9801 7679 l + 9833 7688 l 9853 7694 l 9874 7700 l 9895 7708 l 9918 7716 l + 9941 7725 l 9966 7734 l 9991 7745 l 10017 7755 l 10045 7767 l + 10073 7779 l 10102 7791 l 10132 7804 l 10163 7818 l 10194 7831 l + 10227 7845 l 10259 7860 l 10293 7874 l 10326 7889 l 10360 7903 l + 10394 7918 l 10429 7932 l 10463 7947 l 10497 7961 l 10531 7974 l + 10565 7988 l 10599 8001 l 10633 8013 l 10667 8025 l 10700 8037 l + 10733 8049 l 10767 8059 l 10800 8070 l 10834 8080 l 10868 8090 l + 10902 8099 l 10937 8108 l 10973 8117 l 11009 8125 l 11045 8133 l + 11083 8141 l 11120 8148 l 11158 8155 l 11197 8161 l 11236 8167 l + 11275 8172 l 11313 8177 l 11352 8181 l 11391 8184 l 11429 8187 l + 11467 8190 l 11504 8191 l 11540 8192 l 11576 8192 l 11610 8192 l + 11644 8191 l 11676 8189 l 11707 8187 l 11738 8184 l 11767 8180 l + 11794 8176 l 11821 8171 l 11847 8165 l 11871 8159 l 11895 8153 l + 11923 8143 l 11950 8133 l 11976 8122 l 12001 8109 l 12025 8096 l + 12048 8081 l 12071 8065 l 12092 8048 l 12113 8031 l 12133 8012 l + 12153 7992 l 12171 7972 l 12188 7951 l 12205 7930 l 12220 7909 l + 12235 7887 l 12248 7865 l 12260 7843 l 12272 7822 l 12282 7800 l + 12292 7779 l 12301 7759 l 12309 7739 l 12316 7719 l 12323 7699 l + 12330 7680 l 12338 7655 l 12345 7631 l 12352 7607 l 12359 7582 l + 12365 7558 l 12371 7533 l 12377 7508 l 12382 7484 l 12388 7460 l + 12392 7436 l 12397 7414 l 12401 7391 l 12405 7370 l 12409 7350 l + 12412 7331 l 12415 7313 l 12418 7297 l 12421 7281 l 12424 7266 l + 12428 7253 l 12432 7234 l 12437 7216 l 12442 7199 l 12446 7183 l + 12451 7166 l 12456 7150 l 12460 7134 l 12463 7117 l 12466 7101 l + 12468 7086 l 12469 7070 l 12469 7054 l 12467 7037 l 12465 7020 l + 12462 7006 l 12459 6991 l 12455 6975 l 12450 6958 l 12445 6940 l + 12440 6921 l 12434 6901 l 12428 6880 l 12422 6859 l 12416 6838 l + 12411 6817 l 12406 6796 l 12401 6776 l 12397 6756 l 12394 6736 l + 12392 6718 l 12390 6700 l 12390 6683 l 12390 6665 l 12392 6649 l + 12394 6631 l 12397 6614 l 12401 6597 l 12406 6579 l 12411 6561 l + 12416 6542 l 12422 6524 l 12428 6505 l 12434 6487 l 12440 6468 l + 12445 6450 l 12450 6432 l 12455 6414 l 12459 6396 l 12462 6378 l + 12465 6360 l 12467 6343 l 12468 6326 l 12469 6308 l 12469 6289 l + 12468 6269 l 12468 6249 l 12466 6227 l 12464 6205 l 12462 6182 l + 12460 6159 l 12457 6135 l 12454 6111 l 12451 6087 l 12447 6063 l + 12444 6040 l 12441 6016 l 12437 5993 l 12434 5970 l 12431 5948 l + 12428 5925 l 12424 5902 l 12421 5879 l 12419 5855 l 12416 5831 l + 12413 5806 l 12411 5781 l 12408 5755 l 12406 5729 l 12404 5702 l + 12403 5676 l 12401 5651 l 12400 5625 l 12400 5601 l 12399 5578 l + 12399 5555 l 12400 5534 l 12401 5514 l 12402 5495 l 12403 5477 l + 12405 5460 l 12408 5440 l 12411 5421 l 12416 5402 l 12420 5384 l + 12426 5365 l 12431 5347 l 12437 5329 l 12444 5311 l 12450 5293 l + 12456 5275 l 12462 5258 l 12468 5240 l 12474 5222 l 12479 5205 l + 12483 5186 l 12488 5168 l 12490 5152 l 12493 5135 l 12496 5117 l + 12498 5099 l 12500 5079 l 12502 5058 l 12504 5036 l 12506 5014 l + 12507 4990 l 12509 4966 l 12510 4942 l 12512 4918 l 12513 4893 l + 12515 4869 l 12516 4845 l 12518 4822 l 12520 4799 l 12521 4776 l + 12523 4754 l 12525 4733 l 12527 4713 l 12529 4693 l 12531 4673 l + 12534 4653 l 12536 4632 l 12539 4610 l 12541 4588 l 12543 4566 l + 12546 4543 l 12548 4520 l 12550 4497 l 12552 4473 l 12553 4450 l + 12554 4426 l 12555 4403 l 12555 4380 l 12555 4357 l 12555 4334 l + 12554 4312 l 12552 4290 l 12550 4267 l 12548 4245 l 12545 4224 l + 12541 4203 l 12537 4181 l 12533 4159 l 12528 4136 l 12523 4112 l + 12517 4088 l 12510 4064 l 12503 4038 l 12496 4013 l 12488 3987 l + 12479 3961 l 12471 3935 l 12462 3909 l 12452 3884 l 12443 3859 l + 12434 3835 l 12424 3811 l 12415 3788 l 12405 3766 l 12396 3744 l + 12386 3723 l 12377 3702 l 12368 3683 l 12357 3661 l 12347 3640 l + 12336 3619 l 12325 3598 l 12314 3576 l 12303 3555 l 12291 3533 l + 12280 3511 l 12269 3489 l 12257 3467 l 12246 3446 l 12235 3424 l + 12225 3402 l 12215 3381 l 12206 3360 l 12197 3340 l 12189 3320 l + 12181 3301 l 12174 3281 l 12168 3262 l 12162 3244 l 12158 3225 l + 12153 3204 l 12149 3183 l 12145 3162 l 12142 3139 l 12140 3117 l + 12138 3094 l 12137 3071 l 12137 3047 l 12138 3024 l 12139 3001 l + 12141 2978 l 12143 2956 l 12146 2935 l 12150 2915 l 12154 2896 l + 12158 2879 l 12163 2862 l 12168 2847 l 12174 2833 l 12180 2820 l + 12188 2805 l 12197 2792 l 12206 2779 l 12216 2766 l 12227 2754 l + 12238 2742 l 12249 2730 l 12260 2717 l 12272 2704 l 12282 2691 l + 12292 2676 l 12302 2661 l 12310 2645 l 12318 2627 l 12324 2608 l + 12330 2588 l 12334 2571 l 12336 2553 l 12339 2534 l 12341 2513 l + 12342 2491 l 12343 2467 l 12343 2442 l 12342 2416 l 12340 2389 l + 12338 2360 l 12335 2332 l 12331 2303 l 12326 2273 l 12320 2244 l + 12314 2215 l 12307 2187 l 12299 2159 l 12290 2132 l 12280 2106 l + 12270 2081 l 12259 2056 l 12248 2033 l 12236 2011 l 12224 1990 l + 12210 1970 l 12196 1949 l 12181 1929 l 12164 1910 l 12147 1890 l + 12129 1871 l 12110 1853 l 12090 1835 l 12070 1818 l 12049 1802 l + 12027 1787 l 12005 1773 l 11983 1761 l 11961 1749 l 11939 1739 l + 11917 1730 l 11895 1722 l 11874 1716 l 11852 1710 l 11831 1707 l + 11811 1704 l 11790 1703 l 11769 1702 l 11748 1703 l 11727 1705 l + 11706 1708 l 11683 1711 l 11660 1716 l 11636 1721 l 11612 1727 l + 11587 1733 l 11560 1740 l 11534 1747 l 11506 1754 l 11479 1761 l + 11450 1768 l 11422 1774 l 11393 1780 l 11364 1786 l 11334 1791 l + 11305 1795 l 11275 1798 l 11245 1800 l 11215 1801 l 11184 1801 l + 11153 1800 l 11128 1798 l 11104 1796 l 11078 1793 l 11052 1790 l + 11025 1785 l 10997 1781 l 10968 1776 l 10939 1770 l 10908 1764 l + 10877 1758 l 10844 1751 l 10811 1744 l 10778 1737 l 10743 1730 l + 10708 1722 l 10673 1715 l 10637 1708 l 10601 1701 l 10565 1695 l + 10530 1688 l 10494 1682 l 10458 1677 l 10422 1672 l 10387 1668 l + 10352 1664 l 10318 1661 l 10284 1658 l 10250 1657 l 10216 1656 l + 10183 1655 l 10150 1656 l 10118 1658 l 10087 1660 l 10055 1663 l + 10024 1666 l 9992 1671 l 9960 1676 l 9927 1682 l 9894 1688 l + 9861 1695 l 9827 1703 l 9792 1711 l 9757 1720 l 9721 1729 l + 9685 1738 l 9649 1748 l 9613 1757 l 9576 1767 l 9539 1778 l + 9502 1788 l 9465 1798 l 9429 1807 l 9392 1817 l 9356 1826 l + 9320 1835 l 9285 1844 l 9250 1852 l 9216 1860 l 9182 1867 l + 9148 1873 l 9115 1879 l 9082 1884 l 9050 1889 l 9018 1892 l + 8987 1895 l 8955 1898 l 8919 1899 l 8883 1900 l 8847 1899 l + 8811 1898 l 8774 1896 l 8737 1893 l 8699 1889 l 8661 1884 l + 8623 1878 l 8585 1872 l 8546 1865 l 8508 1857 l 8470 1849 l + 8432 1840 l 8395 1830 l 8358 1821 l 8322 1811 l 8287 1801 l + 8254 1790 l 8221 1780 l 8189 1770 l 8159 1760 l 8130 1750 l + 8102 1740 l 8076 1730 l 8051 1721 l 8028 1712 l 8006 1703 l + 7985 1695 l 7965 1688 l 7931 1674 l 7899 1662 l 7871 1650 l + 7844 1640 l 7820 1631 l 7798 1623 l 7778 1617 l 7760 1611 l + 7743 1607 l 7728 1603 l 7715 1601 l 7702 1600 l 7691 1600 l + 7680 1601 l 7669 1603 l 7658 1605 l 7648 1607 l 7638 1610 l + 7627 1613 l 7615 1617 l 7601 1621 l 7587 1626 l 7571 1632 l + 7554 1638 l 7536 1645 l 7517 1653 l 7496 1661 l 7474 1670 l + 7452 1679 l 7428 1689 l 7403 1699 l 7378 1709 l 7352 1720 l + 7325 1731 l 7297 1743 l 7268 1755 l 7247 1763 l 7226 1772 l + 7204 1781 l 7182 1790 l 7158 1800 l 7133 1810 l 7108 1820 l + 7081 1831 l 7053 1842 l 7025 1853 l 6996 1864 l 6966 1875 l + 6935 1886 l 6904 1898 l 6873 1909 l 6841 1921 l 6809 1932 l + 6776 1943 l 6744 1954 l 6712 1964 l 6680 1974 l 6649 1984 l + 6618 1994 l 6587 2003 l 6557 2011 l 6527 2019 l 6498 2027 l + 6469 2034 l 6441 2041 l cp gs col34 1.00 shd ef gr gs col34 s gr +% Polyline +n 675 6525 m 5850 6525 l 5850 6075 l 5625 6075 l 5625 5625 l 900 5625 l + 900 6075 l 675 6075 l cp gs col7 1.00 shd ef gr gs col7 s gr +% Polyline +n 1125 6525 m 5355 6525 l 5400 5175 l 5175 5175 l 5175 4725 l 4950 4725 l + 4950 4275 l 1575 4275 l 1575 4725 l 1350 4725 l 1350 5175 l + 1125 5175 l cp gs col34 1.00 shd ef gr gs col34 s gr +% Polyline +75.000 slw +n 9450 4500 m 12465 2205 l gs col7 s gr +% Polyline +n 9450 4500 m 9450 7785 l gs col7 s gr +% Polyline +n 9450 4500 m 6075 1935 l gs col7 s gr +% Polyline +n 12510 6435 m 9450 6435 l gs col7 s gr +% Polyline +7.500 slw +n 1800 6525 m 4725 6525 l 4725 3825 l 4500 3825 l 4500 3375 l 4275 3375 l + 4275 2925 l 4050 2925 l 4050 2475 l 2475 2475 l 2475 2925 l + 2250 2925 l 2250 3375 l 2025 3375 l 2025 3825 l 1800 3825 l + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 2700 6525 m 3825 6525 l 3825 2025 l 3600 2025 l 3600 1575 l 2925 1575 l + 2925 2025 l 2700 2025 l cp gs col33 1.00 shd ef gr gs col33 s gr +% Polyline +gs clippath +12068 6810 m 11970 6885 l 12022 6773 l 11937 6878 l 11984 6915 l cp +clip +n 12375 4455 m 12510 4635 l 12510 6210 l 11970 6885 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 12068 6810 m 11970 6885 l 12022 6773 l 12045 6791 l 12068 6810 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7113 6004 m 7155 6120 l 7063 6037 l 7138 6149 l 7188 6116 l cp +clip +n 6705 5445 m 7155 6120 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7113 6004 m 7155 6120 l 7063 6037 l 7088 6020 l 7113 6004 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7304 4656 m 7200 4590 l 7323 4599 l 7195 4557 l 7176 4614 l cp +clip +n 7875 4815 m 7200 4590 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7304 4656 m 7200 4590 l 7323 4599 l 7314 4628 l 7304 4656 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +11405 4128 m 11475 4230 l 11365 4173 l 11466 4262 l 11506 4217 l cp +clip +n 9585 2565 m 11475 4230 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 11405 4128 m 11475 4230 l 11365 4173 l 11385 4151 l 11405 4128 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +11712 4556 m 11835 4545 l 11732 4613 l 11859 4568 l 11839 4512 l cp +clip +n 10170 5130 m 11835 4545 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 11712 4556 m 11835 4545 l 11732 4613 l 11722 4585 l 11712 4556 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +9732 5411 m 9855 5400 l 9752 5468 l 9879 5423 l 9859 5367 l cp +clip +n 7920 6075 m 9855 5400 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 9732 5411 m 9855 5400 l 9752 5468 l 9742 5440 l 9732 5411 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +10823 5573 m 10935 5625 l 10812 5632 l 10944 5657 l 10955 5598 l cp +clip +n 9990 5445 m 10935 5625 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 10823 5573 m 10935 5625 l 10812 5632 l 10817 5603 l 10823 5573 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +10815 5280 m 10935 5310 l 10815 5340 l 10950 5340 l 10950 5280 l cp +clip +n 10215 5310 m 10935 5310 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 10815 5280 m 10935 5310 l 10815 5340 l 10815 5310 l 10815 5280 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +11955 4965 m 11925 5085 l 11895 4965 l 11895 5100 l 11955 5100 l cp +clip +n 11925 4590 m 11925 5085 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 11955 4965 m 11925 5085 l 11895 4965 l 11925 4965 l 11955 4965 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +9840 6720 m 9810 6840 l 9780 6720 l 9780 6855 l 9840 6855 l cp +clip +n 9810 5490 m 9810 6840 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 9840 6720 m 9810 6840 l 9780 6720 l 9810 6720 l 9840 6720 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +10847 5943 m 10935 6030 l 10816 5995 l 10933 6063 l 10963 6012 l cp +clip +n 9945 5445 m 10935 6030 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 10847 5943 m 10935 6030 l 10816 5995 l 10832 5969 l 10847 5943 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +10698 2634 m 10800 2565 l 10742 2674 l 10832 2574 l 10788 2534 l cp +clip +n 8865 4725 m 10800 2565 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 10698 2634 m 10800 2565 l 10742 2674 l 10720 2654 l 10698 2634 l cp gs 0.00 setgray ef gr col0 s +% Polyline +30.000 slw +n 675 6075 m 5850 6075 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +7.500 slw + [15 15] 15 sd +gs clippath +645 6195 m 675 6075 l 705 6195 l 705 6060 l 645 6060 l cp +clip +n 675 6525 m 675 6075 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 645 6195 m 675 6075 l 705 6195 l 675 6195 l 645 6195 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +5880 6405 m 5850 6525 l 5820 6405 l 5820 6540 l 5880 6540 l cp +clip +n 5850 6075 m 5850 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 5880 6405 m 5850 6525 l 5820 6405 l 5850 6405 l 5880 6405 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +30.000 slw +n 900 5625 m 5625 5625 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 1125 5175 m 5400 5175 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 1350 4725 m 5175 4725 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 1575 4275 m 4950 4275 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 1800 3825 m 4725 3825 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 2025 3375 m 4500 3375 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 2250 2925 m 4275 2925 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 2475 2475 m 4050 2475 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 2700 2025 m 3825 2025 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 2925 1575 m 3600 1575 l gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +7.500 slw + [15 15] 15 sd +gs clippath +870 5745 m 900 5625 l 930 5745 l 930 5610 l 870 5610 l cp +clip +n 900 6075 m 900 5625 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 870 5745 m 900 5625 l 930 5745 l 900 5745 l 870 5745 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +1095 5295 m 1125 5175 l 1155 5295 l 1155 5160 l 1095 5160 l cp +clip +n 1125 6525 m 1125 5175 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 1095 5295 m 1125 5175 l 1155 5295 l 1125 5295 l 1095 5295 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +1320 4845 m 1350 4725 l 1380 4845 l 1380 4710 l 1320 4710 l cp +clip +n 1350 5175 m 1350 4725 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 1320 4845 m 1350 4725 l 1380 4845 l 1350 4845 l 1320 4845 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +1545 4395 m 1575 4275 l 1605 4395 l 1605 4260 l 1545 4260 l cp +clip +n 1575 4725 m 1575 4275 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 1545 4395 m 1575 4275 l 1605 4395 l 1575 4395 l 1545 4395 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +1770 3945 m 1800 3825 l 1830 3945 l 1830 3810 l 1770 3810 l cp +clip +n 1800 6525 m 1800 3825 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 1770 3945 m 1800 3825 l 1830 3945 l 1800 3945 l 1770 3945 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +1995 3495 m 2025 3375 l 2055 3495 l 2055 3360 l 1995 3360 l cp +clip +n 2025 3825 m 2025 3375 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 1995 3495 m 2025 3375 l 2055 3495 l 2025 3495 l 1995 3495 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +2220 3045 m 2250 2925 l 2280 3045 l 2280 2910 l 2220 2910 l cp +clip +n 2250 3375 m 2250 2925 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 2220 3045 m 2250 2925 l 2280 3045 l 2250 3045 l 2220 3045 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +2445 2595 m 2475 2475 l 2505 2595 l 2505 2460 l 2445 2460 l cp +clip +n 2475 2925 m 2475 2475 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 2445 2595 m 2475 2475 l 2505 2595 l 2475 2595 l 2445 2595 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +5655 5955 m 5625 6075 l 5595 5955 l 5595 6090 l 5655 6090 l cp +clip +n 5625 5625 m 5625 6075 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 5655 5955 m 5625 6075 l 5595 5955 l 5625 5955 l 5655 5955 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +5430 6405 m 5400 6525 l 5370 6405 l 5370 6540 l 5430 6540 l cp +clip +n 5400 5175 m 5400 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 5430 6405 m 5400 6525 l 5370 6405 l 5400 6405 l 5430 6405 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +5205 5055 m 5175 5175 l 5145 5055 l 5145 5190 l 5205 5190 l cp +clip +n 5175 4725 m 5175 5175 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 5205 5055 m 5175 5175 l 5145 5055 l 5175 5055 l 5205 5055 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +4980 4605 m 4950 4725 l 4920 4605 l 4920 4740 l 4980 4740 l cp +clip +n 4950 4275 m 4950 4725 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 4980 4605 m 4950 4725 l 4920 4605 l 4950 4605 l 4980 4605 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +4755 6405 m 4725 6525 l 4695 6405 l 4695 6540 l 4755 6540 l cp +clip +n 4725 3825 m 4725 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 4755 6405 m 4725 6525 l 4695 6405 l 4725 6405 l 4755 6405 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +4530 3705 m 4500 3825 l 4470 3705 l 4470 3840 l 4530 3840 l cp +clip +n 4500 3375 m 4500 3825 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 4530 3705 m 4500 3825 l 4470 3705 l 4500 3705 l 4530 3705 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +4305 3255 m 4275 3375 l 4245 3255 l 4245 3390 l 4305 3390 l cp +clip +n 4275 2925 m 4275 3375 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 4305 3255 m 4275 3375 l 4245 3255 l 4275 3255 l 4305 3255 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +4080 2805 m 4050 2925 l 4020 2805 l 4020 2940 l 4080 2940 l cp +clip +n 4050 2475 m 4050 2925 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 4080 2805 m 4050 2925 l 4020 2805 l 4050 2805 l 4080 2805 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +2670 2145 m 2700 2025 l 2730 2145 l 2730 2010 l 2670 2010 l cp +clip +n 2700 6525 m 2700 2025 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 2670 2145 m 2700 2025 l 2730 2145 l 2700 2145 l 2670 2145 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +3855 6405 m 3825 6525 l 3795 6405 l 3795 6540 l 3855 6540 l cp +clip +n 3825 2025 m 3825 6525 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 3855 6405 m 3825 6525 l 3795 6405 l 3825 6405 l 3855 6405 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +3630 1905 m 3600 2025 l 3570 1905 l 3570 2040 l 3630 2040 l cp +clip +n 3600 1575 m 3600 2025 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 3630 1905 m 3600 2025 l 3570 1905 l 3600 1905 l 3630 1905 l cp gs col7 1.00 shd ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +2895 1695 m 2925 1575 l 2955 1695 l 2955 1560 l 2895 1560 l cp +clip +n 2925 2025 m 2925 1575 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 2895 1695 m 2925 1575 l 2955 1695 l 2925 1695 l 2895 1695 l cp gs 0.00 setgray ef gr col0 s +% Polyline +45.000 slw +gs clippath +6087 6495 m 6207 6525 l 6087 6555 l 6360 6555 l 6360 6495 l cp +clip +n 540 6525 m 6300 6525 l gs 0.00 setgray ef gr gs col0 s gr gr + +% arrowhead +n 6087 6495 m 6207 6525 l 6087 6555 l 6087 6525 l 6087 6495 l cp gs 0.00 setgray ef gr col0 s +% Polyline +7.500 slw +gs clippath +3681 6720 m 3825 6750 l 3681 6780 l 3840 6780 l 3840 6720 l cp +2844 6780 m 2700 6750 l 2844 6720 l 2685 6720 l 2685 6780 l cp +clip +n 2700 6750 m 3825 6750 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 2844 6780 m 2700 6750 l 2844 6720 l 2820 6750 l 2844 6780 l cp gs col7 1.00 shd ef gr col0 s +% arrowhead +n 3681 6720 m 3825 6750 l 3681 6780 l 3705 6750 l 3681 6720 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +gs clippath +5256 7170 m 5400 7200 l 5256 7230 l 5415 7230 l 5415 7170 l cp +1269 7230 m 1125 7200 l 1269 7170 l 1110 7170 l 1110 7230 l cp +clip +n 1125 7200 m 5400 7200 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 1269 7230 m 1125 7200 l 1269 7170 l 1245 7200 l 1269 7230 l cp gs col7 1.00 shd ef gr col0 s +% arrowhead +n 5256 7170 m 5400 7200 l 5256 7230 l 5280 7200 l 5256 7170 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +gs clippath +4581 6945 m 4725 6975 l 4581 7005 l 4740 7005 l 4740 6945 l cp +1944 7005 m 1800 6975 l 1944 6945 l 1785 6945 l 1785 7005 l cp +clip +n 1800 6975 m 4725 6975 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 1944 7005 m 1800 6975 l 1944 6945 l 1920 6975 l 1944 7005 l cp gs col7 1.00 shd ef gr col0 s +% arrowhead +n 4581 6945 m 4725 6975 l 4581 7005 l 4605 6975 l 4581 6945 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +gs clippath +5706 7395 m 5850 7425 l 5706 7455 l 5865 7455 l 5865 7395 l cp +819 7455 m 675 7425 l 819 7395 l 660 7395 l 660 7455 l cp +clip +n 675 7425 m 5850 7425 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 819 7455 m 675 7425 l 819 7395 l 795 7425 l 819 7455 l cp gs col7 1.00 shd ef gr col0 s +% arrowhead +n 5706 7395 m 5850 7425 l 5706 7455 l 5730 7425 l 5706 7395 l cp gs col7 1.00 shd ef gr col0 s +% Polyline +1 slc + [15 45] 45 sd +n 675 6570 m 675 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 1125 6570 m 1125 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 1800 6570 m 1800 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 2700 6570 m 2700 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 3825 6570 m 3825 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 4725 6570 m 4725 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 5400 6570 m 5400 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline + [15 45] 45 sd +n 5850 6570 m 5850 7650 l gs col34 1.00 shd ef gr gs col0 s gr [] 0 sd +% Polyline +0 slc +n 750 225 m 450 225 450 1050 300 arcto 4 {pop} repeat + 450 1350 12300 1350 300 arcto 4 {pop} repeat + 12600 1350 12600 525 300 arcto 4 {pop} repeat + 12600 225 750 225 300 arcto 4 {pop} repeat + cp gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 8835 2250 m 8775 2250 8775 2415 60 arcto 4 {pop} repeat + 8775 2475 10110 2475 60 arcto 4 {pop} repeat + 10170 2475 10170 2310 60 arcto 4 {pop} repeat + 10170 2250 8835 2250 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 10635 2250 m 10575 2250 10575 2415 60 arcto 4 {pop} repeat + 10575 2475 11865 2475 60 arcto 4 {pop} repeat + 11925 2475 11925 2310 60 arcto 4 {pop} repeat + 11925 2250 10635 2250 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 11490 4275 m 11430 4275 11430 4440 60 arcto 4 {pop} repeat + 11430 4500 12315 4500 60 arcto 4 {pop} repeat + 12375 4500 12375 4335 60 arcto 4 {pop} repeat + 12375 4275 11490 4275 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 11040 5175 m 10980 5175 10980 5340 60 arcto 4 {pop} repeat + 10980 5400 12315 5400 60 arcto 4 {pop} repeat + 12375 5400 12375 5235 60 arcto 4 {pop} repeat + 12375 5175 11040 5175 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 9735 5175 m 9675 5175 9675 5340 60 arcto 4 {pop} repeat + 9675 5400 10110 5400 60 arcto 4 {pop} repeat + 10170 5400 10170 5235 60 arcto 4 {pop} repeat + 10170 5175 9735 5175 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 7260 6075 m 7200 6075 7200 6240 60 arcto 4 {pop} repeat + 7200 6300 7815 6300 60 arcto 4 {pop} repeat + 7875 6300 7875 6135 60 arcto 4 {pop} repeat + 7875 6075 7260 6075 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 6810 2250 m 6750 2250 6750 2415 60 arcto 4 {pop} repeat + 6750 2475 8130 2475 60 arcto 4 {pop} repeat + 8190 2475 8190 2310 60 arcto 4 {pop} repeat + 8190 2250 6810 2250 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 6360 3375 m 6300 3375 6300 3540 60 arcto 4 {pop} repeat + 6300 3600 7545 3600 60 arcto 4 {pop} repeat + 7605 3600 7605 3435 60 arcto 4 {pop} repeat + 7605 3375 6360 3375 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 6360 4275 m 6300 4275 6300 4440 60 arcto 4 {pop} repeat + 6300 4500 7275 4500 60 arcto 4 {pop} repeat + 7335 4500 7335 4335 60 arcto 4 {pop} repeat + 7335 4275 6360 4275 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 6360 5175 m 6300 5175 6300 5340 60 arcto 4 {pop} repeat + 6300 5400 7140 5400 60 arcto 4 {pop} repeat + 7200 5400 7200 5235 60 arcto 4 {pop} repeat + 7200 5175 6360 5175 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +gs clippath +7365 5340 m 7245 5310 l 7365 5280 l 7230 5280 l 7230 5340 l cp +clip +n 9630 5310 m 7245 5310 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7365 5340 m 7245 5310 l 7365 5280 l 7365 5310 l 7365 5340 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7500 4395 m 7380 4365 l 7500 4335 l 7365 4335 l 7365 4395 l cp +clip +n 11385 4365 m 7380 4365 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7500 4395 m 7380 4365 l 7500 4335 l 7500 4365 l 7500 4395 l cp gs 0.00 setgray ef gr col0 s +% Polyline +n 11040 5580 m 10980 5580 10980 5745 60 arcto 4 {pop} repeat + 10980 5805 12180 5805 60 arcto 4 {pop} repeat + 12240 5805 12240 5640 60 arcto 4 {pop} repeat + 12240 5580 11040 5580 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 11040 5985 m 10980 5985 10980 6150 60 arcto 4 {pop} repeat + 10980 6210 12315 6210 60 arcto 4 {pop} repeat + 12375 6210 12375 6045 60 arcto 4 {pop} repeat + 12375 5985 11040 5985 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +gs clippath +9958 5554 m 9900 5445 l 10003 5514 l 9912 5414 l 9868 5454 l cp +clip +n 11205 6885 m 9900 5445 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 9958 5554 m 9900 5445 l 10003 5514 l 9981 5534 l 9958 5554 l cp gs 0.00 setgray ef gr col0 s +% Polyline +n 10590 6930 m 10530 6930 10530 7095 60 arcto 4 {pop} repeat + 10530 7155 12225 7155 60 arcto 4 {pop} repeat + 12285 7155 12285 6990 60 arcto 4 {pop} repeat + 12285 6930 10590 6930 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +n 9690 6930 m 9630 6930 9630 7095 60 arcto 4 {pop} repeat + 9630 7155 10110 7155 60 arcto 4 {pop} repeat + 10170 7155 10170 6990 60 arcto 4 {pop} repeat + 10170 6930 9690 6930 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +/Times-Roman-iso ff 120.00 scf sf +900 7560 m +gs 1 -1 sc (Startup, Runtime, Shutdown) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +6345 2970 m +gs 1 -1 sc (ap_ctx_get\(...,) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10800 2745 m +gs 1 -1 sc (ap_get_module_config\(...) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10800 2880 m +gs 1 -1 sc (->per_dir_config,) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10800 3015 m +gs 1 -1 sc (&ssl_module\)) col0 sh gr +% Polyline +n 7980 4770 m 7920 4770 7920 4935 60 arcto 4 {pop} repeat + 7920 4995 9075 4995 60 arcto 4 {pop} repeat + 9135 4995 9135 4830 60 arcto 4 {pop} repeat + 9135 4770 7980 4770 60 arcto 4 {pop} repeat + cp gs col35 1.00 shd ef gr gs col35 s gr +% Polyline +gs clippath +7340 2610 m 7425 2520 l 7393 2639 l 7459 2521 l 7406 2492 l cp +clip +n 6975 3330 m 7425 2520 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7340 2610 m 7425 2520 l 7393 2639 l 7367 2625 l 7340 2610 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +9336 2569 m 9450 2520 l 9373 2616 l 9480 2535 l 9444 2487 l cp +clip +n 7200 4230 m 9450 2520 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 9336 2569 m 9450 2520 l 9373 2616 l 9354 2593 l 9336 2569 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +7321 5196 m 7200 5220 l 7296 5142 l 7174 5199 l 7199 5254 l cp +clip +n 7875 4905 m 7200 5220 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 7321 5196 m 7200 5220 l 7296 5142 l 7309 5169 l 7321 5196 l cp gs 0.00 setgray ef gr col0 s +% Polyline +gs clippath +6720 4665 m 6750 4545 l 6780 4665 l 6780 4530 l 6720 4530 l cp +clip +n 6750 5130 m 6750 4545 l gs col34 1.00 shd ef gr gs col0 s gr gr + +% arrowhead +n 6720 4665 m 6750 4545 l 6780 4665 l 6750 4665 l 6720 4665 l cp gs 0.00 setgray ef gr col0 s +% Polyline + [15 15] 15 sd +gs clippath +9279 4984 m 9175 4918 l 9298 4927 l 9170 4885 l 9151 4942 l cp +clip +n 9850 5143 m 9175 4918 l gs col34 1.00 shd ef gr gs col0 s gr gr + [] 0 sd +% arrowhead +n 9279 4984 m 9175 4918 l 9298 4927 l 9289 4956 l 9279 4984 l cp gs 0.00 setgray ef gr col0 s +/Helvetica-Narrow-iso ff 120.00 scf sf +6210 4680 m +gs 1 -1 sc (->server) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +8280 6120 m +gs 1 -1 sc (ap_ctx_get\(...,"ssl"\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7740 2700 m +gs 1 -1 sc (ap_get_module_config\(...) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7740 2835 m +gs 1 -1 sc (->module_config,) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7740 2970 m +gs 1 -1 sc (&ssl_module\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +6345 3105 m +gs 1 -1 sc ("ssl_module"\)) col0 sh gr +/Times-Roman-iso ff 120.00 scf sf +1350 7335 m +gs 1 -1 sc (Configuration Time) col0 sh gr +/Times-Roman-iso ff 120.00 scf sf +2025 7110 m +gs 1 -1 sc (Connection Duration) col0 sh gr +/Times-Roman-iso ff 120.00 scf sf +2835 6885 m +gs 1 -1 sc (Request Duration) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +6345 6795 m +gs 1 -1 sc (t) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7110 5985 m +gs 1 -1 sc (->client) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7065 5085 m +gs 1 -1 sc (->connection) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7065 4770 m +gs 1 -1 sc (->server) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +8010 5445 m +gs 1 -1 sc (SSL_get_app_data\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10530 4050 m +gs 1 -1 sc (->pSSLCtx) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +7875 4275 m +gs 1 -1 sc (SSL_CTX_get_app_data\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10305 5535 m +gs 1 -1 sc (SSL_get_current_cipher\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10440 5940 m +gs 1 -1 sc (SSL_get_session\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +9540 7335 m +gs 1 -1 sc (SSL_get_{r,w}bio\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10125 4680 m +gs 1 -1 sc (SSL_get_SSL_CTX\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10350 5175 m +gs 1 -1 sc (SSL_get_SSL_METHOD\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +11745 4770 m +gs 1 -1 sc (->method) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +9945 6480 m +gs 1 -1 sc (X509_STORE_CTX_get_app_data\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +10980 6705 m +gs 1 -1 sc (SSL_CTX_get_cert_store\(\)) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +8280 5130 m +gs 1 -1 sc (SSL_get_app_data2\(\)) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +3645 1620 m +gs 1 -1 sc (SSLDirConfig) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +10935 3645 m +gs 1 -1 sc (OpenSSL) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +10935 3825 m +gs 1 -1 sc ([SSL]) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +11025 5760 m +gs 1 -1 sc (SSL_CIPHER) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +10980 6165 m +gs 1 -1 sc (SSL_SESSION) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +10710 7605 m +gs 1 -1 sc (OpenSSL) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +10575 7110 m +gs 1 -1 sc (X509_STORE_CTX) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +6795 2430 m +gs 1 -1 sc (SSLModConfig) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +8865 2430 m +gs 1 -1 sc (SSLSrvConfig) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +6345 3555 m +gs 1 -1 sc (ap_global_ctx) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +6345 4455 m +gs 1 -1 sc (server_rec) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +6345 5355 m +gs 1 -1 sc (conn_rec) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +9720 5355 m +gs 1 -1 sc (SSL) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +10665 2430 m +gs 1 -1 sc (SSLDirConfig) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +7290 6255 m +gs 1 -1 sc (BUFF) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +11025 5355 m +gs 1 -1 sc (SSL_METHOD) col0 sh gr +% Polyline +15.000 slw +n 750 225 m 450 225 450 8250 300 arcto 4 {pop} repeat + 450 8550 12300 8550 300 arcto 4 {pop} repeat + 12600 8550 12600 525 300 arcto 4 {pop} repeat + 12600 225 750 225 300 arcto 4 {pop} repeat + cp gs col0 s gr +/Helvetica-Bold-iso ff 180.00 scf sf +11475 4455 m +gs 1 -1 sc (SSL_CTX) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +8010 4950 m +gs 1 -1 sc (request_rec) col0 sh gr +/Times-Roman-iso ff 180.00 scf sf +10575 675 m +gs 1 -1 sc (Ralf S. Engelschall) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +4275 675 m +gs 1 -1 sc (Apache+mod_ssl+OpenSSL) col0 sh gr +/Times-Roman-iso ff 150.00 scf sf +10575 855 m +gs 1 -1 sc (rse@engelschall.com) col0 sh gr +/Times-Roman-iso ff 150.00 scf sf +10575 1035 m +gs 1 -1 sc (www.engelschall.com) col0 sh gr +/Times-Roman-iso ff 180.00 scf sf +900 675 m +gs 1 -1 sc (Version 1.3) col0 sh gr +/Times-Roman-iso ff 180.00 scf sf +900 855 m +gs 1 -1 sc (12-Apr-1999) col0 sh gr +/Helvetica-Bold-iso ff 360.00 scf sf +3915 1080 m +gs 1 -1 sc (Data Structure Overview) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +9720 7110 m +gs 1 -1 sc (BIO) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +10710 7785 m +gs 1 -1 sc ([Crypto]) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +8730 3465 m +gs 1 -1 sc (mod_ssl) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +8145 6750 m +gs 1 -1 sc (Apache) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +9000 8100 m +gs 1 -1 sc (Chaining) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +2745 8100 m +gs 1 -1 sc (Lifetime) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +810 6255 m +gs 1 -1 sc (ap_global_ctx) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +990 5805 m +gs 1 -1 sc (SSLModConfig) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +4050 4455 m +gs 1 -1 sc (SSL_CTX) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +4455 5355 m +gs 1 -1 sc (server_rec) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +3870 4905 m +gs 1 -1 sc (SSLSrvConfig) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +1845 4005 m +gs 1 -1 sc (BUFF) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +2070 3555 m +gs 1 -1 sc (conn_rec) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +2295 3105 m +gs 1 -1 sc (BIO) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +2565 2655 m +gs 1 -1 sc (SSL) col0 sh gr +/Helvetica-Bold-iso ff 180.00 scf sf +3915 2070 m +gs 1 -1 sc (request_rec) col0 sh gr +$F2psEnd +rs +showpage diff --git a/trunk/modules/ssl/config.m4 b/trunk/modules/ssl/config.m4 new file mode 100644 index 0000000000..7242f76ed9 --- /dev/null +++ b/trunk/modules/ssl/config.m4 @@ -0,0 +1,131 @@ +dnl Copyright 2001-2004 The Apache Software Foundation +dnl Licensed under the Apache License, Version 2.0 (the "License"); +dnl you may not use this file except in compliance with the License. +dnl You may obtain a copy of the License at +dnl +dnl http://www.apache.org/licenses/LICENSE-2.0 +dnl +dnl Unless required by applicable law or agreed to in writing, software +dnl distributed under the License is distributed on an "AS IS" BASIS, +dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +dnl See the License for the specific language governing permissions and +dnl limitations under the License. + +AC_DEFUN([CHECK_DISTCACHE], [ + AC_MSG_CHECKING(whether Distcache is required) + ap_ssltk_dc="no" + tmp_nomessage="" + tmp_forced="no" + AC_ARG_ENABLE(distcache, + APACHE_HELP_STRING(--enable-distcache,Select distcache support in mod_ssl), + ap_ssltk_dc="$enableval" + tmp_nomessage="" + tmp_forced="yes" + if test "x$ap_ssltk_dc" = "x"; then + ap_ssltk_dc="yes" + dnl our "error"s become "tests revealed that..." + tmp_forced="no" + fi + if test "$ap_ssltk_dc" != "yes" -a "$ap_ssltk_dc" != "no"; then + tmp_nomessage="--enable-distcache had illegal syntax - disabling" + ap_ssltk_dc="no" + fi) + if test "$tmp_forced" = "no"; then + AC_MSG_RESULT($ap_ssltk_dc (default)) + else + AC_MSG_RESULT($ap_ssltk_dc (specified)) + fi + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno" -a "x$tmp_nomessage" != "x"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_CHECK_HEADER( + [distcache/dc_client.h], + [], + [tmp_nomessage="can't include distcache headers" + ap_ssltk_dc="no"]) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_MSG_CHECKING(for Distcache version) + AC_TRY_COMPILE( +[#include ], +[#if DISTCACHE_CLIENT_API != 0x0001 +#error "distcache API version is unrecognised" +#endif], +[], +[tmp_nomessage="distcache has an unsupported API version" +ap_ssltk_dc="no"]) + AC_MSG_RESULT($ap_ssltk_dc) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_MSG_CHECKING(for Distcache libraries) + save_libs=$LIBS + LIBS="$LIBS -ldistcache -lnal" + AC_TRY_LINK( + [#include ], + [DC_CTX *foo = DC_CTX_new((const char *)0,0);], + [], + [tmp_no_message="failed to link with distcache libraries" + ap_ssltk_dc="no"]) + LIBS=$save_libs + AC_MSG_RESULT($ap_ssltk_dc) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + else + APR_ADDTO(MOD_SSL_LDADD, [-ldistcache -lnal]) + AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled]) + fi + fi +]) + +dnl # start of module specific part +APACHE_MODPATH_INIT(ssl) + +dnl # list of module object files +ssl_objs="dnl +mod_ssl.lo dnl +ssl_engine_config.lo dnl +ssl_engine_dh.lo dnl +ssl_engine_init.lo dnl +ssl_engine_io.lo dnl +ssl_engine_kernel.lo dnl +ssl_engine_log.lo dnl +ssl_engine_mutex.lo dnl +ssl_engine_pphrase.lo dnl +ssl_engine_rand.lo dnl +ssl_engine_vars.lo dnl +ssl_expr.lo dnl +ssl_expr_eval.lo dnl +ssl_expr_parse.lo dnl +ssl_expr_scan.lo dnl +ssl_scache.lo dnl +ssl_scache_dbm.lo dnl +ssl_scache_shmcb.lo dnl +ssl_scache_dc.lo dnl +ssl_util.lo dnl +ssl_util_ssl.lo dnl +" +dnl # hook module into the Autoconf mechanism (--enable-ssl option) +APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , no, [ + APACHE_CHECK_SSL_TOOLKIT + APR_SETVAR(MOD_SSL_LDADD, [\$(SSL_LIBS)]) + CHECK_DISTCACHE + if test "x$enable_ssl" = "xshared"; then + # The only symbol which needs to be exported is the module + # structure, so ask libtool to hide everything else: + APR_ADDTO(MOD_SSL_LDADD, [-export-symbols-regex ssl_module]) + fi +]) + +# Ensure that other modules can pick up mod_ssl.h +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) + +dnl # end of module specific part +APACHE_MODPATH_FINISH + diff --git a/trunk/modules/ssl/mod_ssl.c b/trunk/modules/ssl/mod_ssl.c new file mode 100644 index 0000000000..146f7e7a66 --- /dev/null +++ b/trunk/modules/ssl/mod_ssl.c @@ -0,0 +1,516 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * mod_ssl.c + * Apache API interface structures + */ + +#include "ssl_private.h" +#include "mod_ssl.h" +#include "util_md5.h" +#include + +/* + * the table of configuration directives we provide + */ + +#define SSL_CMD_ALL(name, args, desc) \ + AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \ + NULL, RSRC_CONF|OR_AUTHCFG, desc), + +#define SSL_CMD_SRV(name, args, desc) \ + AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \ + NULL, RSRC_CONF, desc), + +#define SSL_CMD_DIR(name, type, args, desc) \ + AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \ + NULL, OR_##type, desc), + +#define AP_END_CMD { NULL } + +const char ssl_valid_ssl_mutex_string[] = + "Valid SSLMutex mechanisms are: `none', `default'" +#if APR_HAS_FLOCK_SERIALIZE + ", `flock:/path/to/file'" +#endif +#if APR_HAS_FCNTL_SERIALIZE + ", `fcntl:/path/to/file'" +#endif +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) + ", `sysvsem'" +#endif +#if APR_HAS_POSIXSEM_SERIALIZE + ", `posixsem'" +#endif +#if APR_HAS_PROC_PTHREAD_SERIALIZE + ", `pthread'" +#endif +#if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE + ", `file:/path/to/file'" +#endif +#if (APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)) || APR_HAS_POSIXSEM_SERIALIZE + ", `sem'" +#endif + " "; + +static const command_rec ssl_config_cmds[] = { + /* + * Global (main-server) context configuration directives + */ + SSL_CMD_SRV(Mutex, TAKE1, ssl_valid_ssl_mutex_string) + SSL_CMD_SRV(PassPhraseDialog, TAKE1, + "SSL dialog mechanism for the pass phrase query " + "(`builtin', `|/path/to/pipe_program`, " + "or `exec:/path/to/cgi_program')") + SSL_CMD_SRV(SessionCache, TAKE1, + "SSL Session Cache storage " + "(`none', `dbm:/path/to/file')") +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + SSL_CMD_SRV(CryptoDevice, TAKE1, + "SSL external Crypto Device usage " + "(`builtin', `...')") +#endif + SSL_CMD_SRV(RandomSeed, TAKE23, + "SSL Pseudo Random Number Generator (PRNG) seeding source " + "(`startup|connect builtin|file:/path|exec:/path [bytes]')") + + /* + * Per-server context configuration directives + */ + SSL_CMD_SRV(Engine, TAKE1, + "SSL switch for the protocol engine " + "(`on', `off')") + SSL_CMD_ALL(CipherSuite, TAKE1, + "Colon-delimited list of permitted SSL Ciphers " + "(`XXX:...:XXX' - see manual)") + SSL_CMD_SRV(CertificateFile, TAKE1, + "SSL Server Certificate file " + "(`/path/to/file' - PEM or DER encoded)") + SSL_CMD_SRV(CertificateKeyFile, TAKE1, + "SSL Server Private Key file " + "(`/path/to/file' - PEM or DER encoded)") + SSL_CMD_SRV(CertificateChainFile, TAKE1, + "SSL Server CA Certificate Chain file " + "(`/path/to/file' - PEM encoded)") + SSL_CMD_ALL(CACertificatePath, TAKE1, + "SSL CA Certificate path " + "(`/path/to/dir' - contains PEM encoded files)") + SSL_CMD_ALL(CACertificateFile, TAKE1, + "SSL CA Certificate file " + "(`/path/to/file' - PEM encoded)") + SSL_CMD_SRV(CADNRequestPath, TAKE1, + "SSL CA Distinguished Name path " + "(`/path/to/dir' - symlink hashes to PEM of acceptable CA names to request)") + SSL_CMD_SRV(CADNRequestFile, TAKE1, + "SSL CA Distinguished Name file " + "(`/path/to/file' - PEM encoded to derive acceptable CA names to request)") + SSL_CMD_SRV(CARevocationPath, TAKE1, + "SSL CA Certificate Revocation List (CRL) path " + "(`/path/to/dir' - contains PEM encoded files)") + SSL_CMD_SRV(CARevocationFile, TAKE1, + "SSL CA Certificate Revocation List (CRL) file " + "(`/path/to/file' - PEM encoded)") + SSL_CMD_ALL(VerifyClient, TAKE1, + "SSL Client verify type " + "(`none', `optional', `require', `optional_no_ca')") + SSL_CMD_ALL(VerifyDepth, TAKE1, + "SSL Client verify depth " + "(`N' - number of intermediate certificates)") + SSL_CMD_SRV(SessionCacheTimeout, TAKE1, + "SSL Session Cache object lifetime " + "(`N' - number of seconds)") + SSL_CMD_SRV(Protocol, RAW_ARGS, + "Enable or disable various SSL protocols" + "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)") + SSL_CMD_SRV(HonorCipherOrder, FLAG, + "Use the server's cipher ordering preference") + SSL_CMD_ALL(UserName, TAKE1, + "Set user name to SSL variable value") + + /* + * Proxy configuration for remote SSL connections + */ + SSL_CMD_SRV(ProxyEngine, FLAG, + "SSL switch for the proxy protocol engine " + "(`on', `off')") + SSL_CMD_SRV(ProxyProtocol, RAW_ARGS, + "SSL Proxy: enable or disable SSL protocol flavors " + "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)") + SSL_CMD_SRV(ProxyCipherSuite, TAKE1, + "SSL Proxy: colon-delimited list of permitted SSL ciphers " + "(`XXX:...:XXX' - see manual)") + SSL_CMD_SRV(ProxyVerify, TAKE1, + "SSL Proxy: whether to verify the remote certificate " + "(`on' or `off')") + SSL_CMD_SRV(ProxyVerifyDepth, TAKE1, + "SSL Proxy: maximum certificate verification depth " + "(`N' - number of intermediate certificates)") + SSL_CMD_SRV(ProxyCACertificateFile, TAKE1, + "SSL Proxy: file containing server certificates " + "(`/path/to/file' - PEM encoded certificates)") + SSL_CMD_SRV(ProxyCACertificatePath, TAKE1, + "SSL Proxy: directory containing server certificates " + "(`/path/to/dir' - contains PEM encoded certificates)") + SSL_CMD_SRV(ProxyCARevocationPath, TAKE1, + "SSL Proxy: CA Certificate Revocation List (CRL) path " + "(`/path/to/dir' - contains PEM encoded files)") + SSL_CMD_SRV(ProxyCARevocationFile, TAKE1, + "SSL Proxy: CA Certificate Revocation List (CRL) file " + "(`/path/to/file' - PEM encoded)") + SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1, + "SSL Proxy: file containing client certificates " + "(`/path/to/file' - PEM encoded certificates)") + SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1, + "SSL Proxy: directory containing client certificates " + "(`/path/to/dir' - contains PEM encoded certificates)") + + /* + * Per-directory context configuration directives + */ + SSL_CMD_DIR(Options, OPTIONS, RAW_ARGS, + "Set one or more options to configure the SSL engine" + "(`[+-]option[=value] ...' - see manual)") + SSL_CMD_DIR(RequireSSL, AUTHCFG, NO_ARGS, + "Require the SSL protocol for the per-directory context " + "(no arguments)") + SSL_CMD_DIR(Require, AUTHCFG, RAW_ARGS, + "Require a boolean expression to evaluate to true for granting access" + "(arbitrary complex boolean expression - see manual)") + + /* Deprecated directives. */ + AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL, + "SSLLog directive is no longer supported - use ErrorLog."), + AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL, + "SSLLogLevel directive is no longer supported - use LogLevel."), + + AP_END_CMD +}; + +/* + * the various processing hooks + */ +static apr_status_t ssl_cleanup_pre_config(void *data) +{ + /* + * Try to kill the internals of the SSL library. + */ +#ifdef HAVE_OPENSSL +#if OPENSSL_VERSION_NUMBER >= 0x00907001 + /* Corresponds to OPENSSL_load_builtin_modules(): + * XXX: borrowed from apps.h, but why not CONF_modules_free() + * which also invokes CONF_modules_finish()? + */ + CONF_modules_unload(1); +#endif +#endif + /* Corresponds to SSL_library_init: */ + EVP_cleanup(); +#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES + ENGINE_cleanup(); +#endif +#ifdef HAVE_OPENSSL +#if OPENSSL_VERSION_NUMBER >= 0x00907001 + CRYPTO_cleanup_all_ex_data(); +#endif +#endif + ERR_remove_state(0); + + /* Don't call ERR_free_strings here; ERR_load_*_strings only + * actually load the error strings once per process due to static + * variable abuse in OpenSSL. */ + + /* + * TODO: determine somewhere we can safely shove out diagnostics + * (when enabled) at this late stage in the game: + * CRYPTO_mem_leaks_fp(stderr); + */ + return APR_SUCCESS; +} + +static int ssl_hook_pre_config(apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp) +{ + /* We must register the library in full, to ensure our configuration + * code can successfully test the SSL environment. + */ + CRYPTO_malloc_init(); +#ifdef HAVE_OPENSSL + ERR_load_crypto_strings(); +#endif + SSL_load_error_strings(); + SSL_library_init(); +#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES + ENGINE_load_builtin_engines(); +#endif +#ifdef HAVE_OPENSSL +#if OPENSSL_VERSION_NUMBER >= 0x00907001 + OPENSSL_load_builtin_modules(); +#endif +#endif + + /* + * Let us cleanup the ssl library when the module is unloaded + */ + apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config, + apr_pool_cleanup_null); + + /* Register us to handle mod_log_config %c/%x variables */ + ssl_var_log_config_register(pconf); + + /* Register to handle mod_status status page generation */ + ssl_scache_status_register(pconf); + + return OK; +} + +static SSLConnRec *ssl_init_connection_ctx(conn_rec *c) +{ + SSLConnRec *sslconn = myConnConfig(c); + + if (sslconn) { + return sslconn; + } + + sslconn = apr_pcalloc(c->pool, sizeof(*sslconn)); + + myConnConfigSet(c, sslconn); + + return sslconn; +} + +int ssl_proxy_enable(conn_rec *c) +{ + SSLSrvConfigRec *sc = mySrvConfig(c->base_server); + + SSLConnRec *sslconn = ssl_init_connection_ctx(c); + + if (!sc->proxy_enabled) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, + "SSL Proxy requested for %s but not enabled " + "[Hint: SSLProxyEngine]", sc->vhost_id); + + return 0; + } + + sslconn->is_proxy = 1; + sslconn->disabled = 0; + + return 1; +} + +int ssl_engine_disable(conn_rec *c) +{ + SSLSrvConfigRec *sc = mySrvConfig(c->base_server); + + SSLConnRec *sslconn; + + if (sc->enabled == SSL_ENABLED_FALSE) { + return 0; + } + + sslconn = ssl_init_connection_ctx(c); + + sslconn->disabled = 1; + + return 1; +} + +int ssl_init_ssl_connection(conn_rec *c) +{ + SSLSrvConfigRec *sc = mySrvConfig(c->base_server); + SSL *ssl; + SSLConnRec *sslconn = myConnConfig(c); + char *vhost_md5; + modssl_ctx_t *mctx; + + /* + * Seed the Pseudo Random Number Generator (PRNG) + */ + ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, ""); + + if (!sslconn) { + sslconn = ssl_init_connection_ctx(c); + } + + mctx = sslconn->is_proxy ? sc->proxy : sc->server; + + /* + * Create a new SSL connection with the configured server SSL context and + * attach this to the socket. Additionally we register this attachment + * so we can detach later. + */ + if (!(ssl = SSL_new(mctx->ssl_ctx))) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, + "Unable to create a new SSL connection from the SSL " + "context"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server); + + c->aborted = 1; + + return DECLINED; /* XXX */ + } + + vhost_md5 = ap_md5_binary(c->pool, (unsigned char *)sc->vhost_id, + sc->vhost_id_len); + + if (!SSL_set_session_id_context(ssl, (unsigned char *)vhost_md5, + APR_MD5_DIGESTSIZE*2)) + { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, + "Unable to set session id context to `%s'", vhost_md5); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server); + + c->aborted = 1; + + return DECLINED; /* XXX */ + } + + SSL_set_app_data(ssl, c); + SSL_set_app_data2(ssl, NULL); /* will be request_rec */ + + sslconn->ssl = ssl; + + /* + * Configure callbacks for SSL connection + */ + SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA); + SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH); + + SSL_set_verify_result(ssl, X509_V_OK); + + ssl_io_filter_init(c, ssl); + + return APR_SUCCESS; +} + +static const char *ssl_hook_http_scheme(const request_rec *r) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + + if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) { + return NULL; + } + + return "https"; +} + +static apr_port_t ssl_hook_default_port(const request_rec *r) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + + if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) { + return 0; + } + + return 443; +} + +static int ssl_hook_pre_connection(conn_rec *c, void *csd) +{ + SSLSrvConfigRec *sc = mySrvConfig(c->base_server); + SSLConnRec *sslconn = myConnConfig(c); + + /* + * Immediately stop processing if SSL is disabled for this connection + */ + if (!(sc && (sc->enabled == SSL_ENABLED_TRUE || + (sslconn && sslconn->is_proxy)))) + { + return DECLINED; + } + + /* + * Create SSL context + */ + if (!sslconn) { + sslconn = ssl_init_connection_ctx(c); + } + + if (sslconn->disabled) { + return DECLINED; + } + + /* + * Remember the connection information for + * later access inside callback functions + */ + + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "Connection to child %ld established " + "(server %s)", c->id, sc->vhost_id); + + return ssl_init_ssl_connection(c); +} + + +static void ssl_hook_Insert_Filter(request_rec *r) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + + if (sc->enabled == SSL_ENABLED_OPTIONAL) { + ap_add_output_filter("UPGRADE_FILTER", NULL, r, r->connection); + } +} + +/* + * the module registration phase + */ + +static void ssl_register_hooks(apr_pool_t *p) +{ + /* ssl_hook_ReadReq needs to use the BrowserMatch settings so must + * run after mod_setenvif's post_read_request hook. */ + static const char *pre_prr[] = { "mod_setenvif.c", NULL }; + + ssl_io_filter_register(p); + + ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_test_config (ssl_hook_ConfigTest, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_post_config (ssl_init_Module, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_http_scheme (ssl_hook_http_scheme, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_default_port (ssl_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_pre_config (ssl_hook_pre_config, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_child_init (ssl_init_Child, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_check_user_id (ssl_hook_UserCheck, NULL,NULL, APR_HOOK_FIRST); + ap_hook_fixups (ssl_hook_Fixup, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_access_checker(ssl_hook_Access, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_auth_checker (ssl_hook_Auth, NULL,NULL, APR_HOOK_MIDDLE); + ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE); + ap_hook_insert_filter (ssl_hook_Insert_Filter, NULL,NULL, APR_HOOK_MIDDLE); +/* ap_hook_handler (ssl_hook_Upgrade, NULL,NULL, APR_HOOK_MIDDLE); */ + + ssl_var_register(); + + APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); + APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); +} + +module AP_MODULE_DECLARE_DATA ssl_module = { + STANDARD20_MODULE_STUFF, + ssl_config_perdir_create, /* create per-dir config structures */ + ssl_config_perdir_merge, /* merge per-dir config structures */ + ssl_config_server_create, /* create per-server config structures */ + ssl_config_server_merge, /* merge per-server config structures */ + ssl_config_cmds, /* table of configuration directives */ + ssl_register_hooks /* register hooks */ +}; diff --git a/trunk/modules/ssl/mod_ssl.dsp b/trunk/modules/ssl/mod_ssl.dsp new file mode 100644 index 0000000000..27eb31bed8 --- /dev/null +++ b/trunk/modules/ssl/mod_ssl.dsp @@ -0,0 +1,328 @@ +# Microsoft Developer Studio Project File - Name="mod_ssl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=mod_ssl - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mod_ssl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mod_ssl.mak" CFG="mod_ssl - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mod_ssl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "mod_ssl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mod_ssl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE=1" /Fd"Release\mod_ssl_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_ssl.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so +# ADD LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_ssl.so" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref + +!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE=1" /Fd"Debug\mod_ssl_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ssl.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so +# ADD LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_ssl.so" /libpath:"../../srclib/openssl/out32dll.dbg" /libpath:"../../srclib/openssl/out32.dbg" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so + +!ENDIF + +# Begin Target + +# Name "mod_ssl - Win32 Release" +# Name "mod_ssl - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "*.c" +# Begin Source File + +SOURCE=.\mod_ssl.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_config.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_dh.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_init.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_io.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_kernel.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_log.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_mutex.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_pphrase.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_rand.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_engine_vars.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr_eval.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr_parse.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr_scan.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_scache.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_scache_dbm.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_scache_shmcb.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_scache_dc.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_util.c +# End Source File +# Begin Source File + +SOURCE=.\ssl_util_ssl.c +# End Source File +# End Group + # Begin Group "Header Files" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\mod_ssl.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_private.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr_parse.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_toolkit_compat.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_util_ssl.h +# End Source File +# Begin Source File + +SOURCE=.\ssl_util_table.h +# End Source File +# End Group +# Begin Group "Generated Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ssl_expr_parse.y + +!IF "$(CFG)" == "mod_ssl - Win32 Release" + +# Begin Custom Build - Generating ssl_expr_parse.c/.h from ssl_expr_parse.y +InputPath=.\ssl_expr_parse.y + +BuildCmds= \ + bison -y -d ssl_expr_parse.y \ + sed -e "s;yy;ssl_expr_yy;g" -e "/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d" ssl_expr_parse.c \ + del y.tab.c \ + sed -e "s;yy;ssl_expr_yy;g" ssl_expr_parse.h \ + del y.tab.h \ + + +"ssl_expr_parse.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"ssl_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug" + +# Begin Custom Build - Generating ssl_expr_parse.c/.h from ssl_expr_parse.y +InputPath=.\ssl_expr_parse.y + +BuildCmds= \ + bison -y -d ssl_expr_parse.y \ + sed -e "s;yy;ssl_expr_yy;g" -e "/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d" ssl_expr_parse.c \ + del y.tab.c \ + sed -e "s;yy;ssl_expr_yy;g" ssl_expr_parse.h \ + del y.tab.h \ + + +"ssl_expr_parse.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"ssl_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\ssl_expr_scan.l + +!IF "$(CFG)" == "mod_ssl - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Generating ssl_expr_scan.c from ssl_expr_scan.l +InputPath=.\ssl_expr_scan.l + +"ssl_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + flex -Pssl_expr_yy -s -B ssl_expr_scan.l + sed -e "/$$Header:/d" ssl_expr_scan.c + del lex.ssl_expr_yy.c + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Generating ssl_expr_scan.c from ssl_expr_scan.l +InputPath=.\ssl_expr_scan.l + +"ssl_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + flex -Pssl_expr_yy -s -B ssl_expr_scan.l + sed -e "/$$Header:/d" ssl_expr_scan.c + del lex.ssl_expr_yy.c + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\mod_ssl.rc +# End Source File +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "mod_ssl - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ssl.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ssl.so "ssl_module for Apache" ../../include/ap_release.h > .\mod_ssl.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\mod_ssl.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk mod_ssl.so "ssl_module for Apache" ../../include/ap_release.h > .\mod_ssl.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/modules/ssl/mod_ssl.h b/trunk/modules/ssl/mod_ssl.h new file mode 100644 index 0000000000..fdde641196 --- /dev/null +++ b/trunk/modules/ssl/mod_ssl.h @@ -0,0 +1,52 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MOD_SSL_H__ +#define __MOD_SSL_H__ + +#include "httpd.h" +#include "apr_optional.h" + +/* The ssl_var_lookup() optional function retrieves SSL environment + * variables. */ +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, + char *)); + +/* The ssl_ext_lookup() optional function retrieves the value of a SSL + * certificate X.509 extension. The client certificate is used if + * peer is non-zero; the server certificate is used otherwise. The + * oidnum parameter specifies the numeric OID (e.g. "1.2.3.4") of the + * desired extension. The string value of the extension is returned, + * or NULL on error. */ +APR_DECLARE_OPTIONAL_FN(const char *, ssl_ext_lookup, + (apr_pool_t *p, conn_rec *c, int peer, + const char *oidnum)); + +/* An optional function which returns non-zero if the given connection + * is using SSL/TLS. */ +APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); + +/* The ssl_proxy_enable() and ssl_engine_disable() optional functions + * are used by mod_proxy to enable use of SSL for outgoing + * connections. */ + +APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); + +APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); + +#endif /* __MOD_SSL_H__ */ diff --git a/trunk/modules/ssl/ssl_engine_config.c b/trunk/modules/ssl/ssl_engine_config.c new file mode 100644 index 0000000000..c6572216e2 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_config.c @@ -0,0 +1,1433 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_config.c + * Apache Configuration Directives + */ + /* ``Damned if you do, + damned if you don't.'' + -- Unknown */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Support for Global Configuration +** _________________________________________________________________ +*/ + +#define SSL_MOD_CONFIG_KEY "ssl_module" + +SSLModConfigRec *ssl_config_global_create(server_rec *s) +{ + apr_pool_t *pool = s->process->pool; + SSLModConfigRec *mc; + void *vmc; + + apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool); + if (vmc) { + return vmc; /* reused for lifetime of the server */ + } + + /* + * allocate an own subpool which survives server restarts + */ + mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc)); + mc->pPool = pool; + mc->bFixed = FALSE; + + /* + * initialize per-module configuration + */ + mc->nSessionCacheMode = SSL_SCMODE_UNSET; + mc->szSessionCacheDataFile = NULL; + mc->nSessionCacheDataSize = 0; + mc->pSessionCacheDataMM = NULL; + mc->pSessionCacheDataRMM = NULL; + mc->tSessionCacheDataTable = NULL; + mc->nMutexMode = SSL_MUTEXMODE_UNSET; + mc->nMutexMech = APR_LOCK_DEFAULT; + mc->szMutexFile = NULL; + mc->pMutex = NULL; + mc->aRandSeed = apr_array_make(pool, 4, + sizeof(ssl_randseed_t)); + mc->tVHostKeys = apr_hash_make(pool); + mc->tPrivateKey = apr_hash_make(pool); + mc->tPublicCert = apr_hash_make(pool); +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + mc->szCryptoDevice = NULL; +#endif + + memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); + + apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, + apr_pool_cleanup_null, + pool); + + return mc; +} + +void ssl_config_global_fix(SSLModConfigRec *mc) +{ + mc->bFixed = TRUE; +} + +BOOL ssl_config_global_isfixed(SSLModConfigRec *mc) +{ + return mc->bFixed; +} + +/* _________________________________________________________________ +** +** Configuration handling +** _________________________________________________________________ +*/ + +static void modssl_ctx_init(modssl_ctx_t *mctx) +{ + mctx->sc = NULL; /* set during module init */ + + mctx->ssl_ctx = NULL; /* set during module init */ + + mctx->pks = NULL; + mctx->pkp = NULL; + + mctx->protocol = SSL_PROTOCOL_ALL; + + mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; + mctx->pphrase_dialog_path = NULL; + + mctx->cert_chain = NULL; + + mctx->crl_path = NULL; + mctx->crl_file = NULL; + mctx->crl = NULL; /* set during module init */ + + mctx->auth.ca_cert_path = NULL; + mctx->auth.ca_cert_file = NULL; + mctx->auth.cipher_suite = NULL; + mctx->auth.verify_depth = UNSET; + mctx->auth.verify_mode = SSL_CVERIFY_UNSET; +} + +static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, + apr_pool_t *p) +{ + modssl_ctx_t *mctx; + + mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy)); + + modssl_ctx_init(mctx); + + mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp)); + + mctx->pkp->cert_file = NULL; + mctx->pkp->cert_path = NULL; + mctx->pkp->certs = NULL; +} + +static void modssl_ctx_init_server(SSLSrvConfigRec *sc, + apr_pool_t *p) +{ + modssl_ctx_t *mctx; + + mctx = sc->server = apr_palloc(p, sizeof(*sc->server)); + + modssl_ctx_init(mctx); + + mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks)); + + /* mctx->pks->... certs/keys are set during module init */ +} + +static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) +{ + SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc)); + + sc->mc = NULL; + sc->enabled = SSL_ENABLED_FALSE; + sc->proxy_enabled = UNSET; + sc->vhost_id = NULL; /* set during module init */ + sc->vhost_id_len = 0; /* set during module init */ + sc->session_cache_timeout = UNSET; + sc->cipher_server_pref = UNSET; + + modssl_ctx_init_proxy(sc, p); + + modssl_ctx_init_server(sc, p); + + return sc; +} + +/* + * Create per-server SSL configuration + */ +void *ssl_config_server_create(apr_pool_t *p, server_rec *s) +{ + SSLSrvConfigRec *sc = ssl_config_server_new(p); + + sc->mc = ssl_config_global_create(s); + + return sc; +} + +#define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el +#define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el) +#define cfgMergeString(el) cfgMerge(el, NULL) +#define cfgMergeBool(el) cfgMerge(el, UNSET) +#define cfgMergeInt(el) cfgMerge(el, UNSET) + +static void modssl_ctx_cfg_merge(modssl_ctx_t *base, + modssl_ctx_t *add, + modssl_ctx_t *mrg) +{ + cfgMerge(protocol, SSL_PROTOCOL_ALL); + + cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET); + cfgMergeString(pphrase_dialog_path); + + cfgMergeString(cert_chain); + + cfgMerge(crl_path, NULL); + cfgMerge(crl_file, NULL); + + cfgMergeString(auth.ca_cert_path); + cfgMergeString(auth.ca_cert_file); + cfgMergeString(auth.cipher_suite); + cfgMergeInt(auth.verify_depth); + cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET); +} + +static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base, + modssl_ctx_t *add, + modssl_ctx_t *mrg) +{ + modssl_ctx_cfg_merge(base, add, mrg); + + cfgMergeString(pkp->cert_file); + cfgMergeString(pkp->cert_path); +} + +static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base, + modssl_ctx_t *add, + modssl_ctx_t *mrg) +{ + int i; + + modssl_ctx_cfg_merge(base, add, mrg); + + for (i = 0; i < SSL_AIDX_MAX; i++) { + cfgMergeString(pks->cert_files[i]); + cfgMergeString(pks->key_files[i]); + } + + cfgMergeString(pks->ca_name_path); + cfgMergeString(pks->ca_name_file); +} + +/* + * Merge per-server SSL configurations + */ +void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) +{ + SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev; + SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv; + SSLSrvConfigRec *mrg = ssl_config_server_new(p); + + cfgMerge(mc, NULL); + cfgMerge(enabled, SSL_ENABLED_UNSET); + cfgMergeBool(proxy_enabled); + cfgMergeInt(session_cache_timeout); + cfgMergeBool(cipher_server_pref); + + modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); + + modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server); + + return mrg; +} + +/* + * Create per-directory SSL configuration + */ +void *ssl_config_perdir_create(apr_pool_t *p, char *dir) +{ + SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc)); + + dc->bSSLRequired = FALSE; + dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t)); + dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET; + dc->nOptionsAdd = SSL_OPT_NONE; + dc->nOptionsDel = SSL_OPT_NONE; + + dc->szCipherSuite = NULL; + dc->nVerifyClient = SSL_CVERIFY_UNSET; + dc->nVerifyDepth = UNSET; + + dc->szCACertificatePath = NULL; + dc->szCACertificateFile = NULL; + dc->szUserName = NULL; + + return dc; +} + +/* + * Merge per-directory SSL configurations + */ +void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv) +{ + SSLDirConfigRec *base = (SSLDirConfigRec *)basev; + SSLDirConfigRec *add = (SSLDirConfigRec *)addv; + SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg)); + + cfgMerge(bSSLRequired, FALSE); + cfgMergeArray(aRequirement); + + if (add->nOptions & SSL_OPT_RELSET) { + mrg->nOptionsAdd = + (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd; + mrg->nOptionsDel = + (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel; + mrg->nOptions = + (base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd; + } + else { + mrg->nOptions = add->nOptions; + mrg->nOptionsAdd = add->nOptionsAdd; + mrg->nOptionsDel = add->nOptionsDel; + } + + cfgMergeString(szCipherSuite); + cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET); + cfgMergeInt(nVerifyDepth); + + cfgMergeString(szCACertificatePath); + cfgMergeString(szCACertificateFile); + cfgMergeString(szUserName); + + return mrg; +} + +/* + * Configuration functions for particular directives + */ + +const char *ssl_cmd_SSLMutex(cmd_parms *cmd, + void *dcfg, + const char *arg_) +{ + const char *err; + SSLModConfigRec *mc = myModConfig(cmd->server); + /* Split arg_ into meth and file */ + char *meth = apr_pstrdup(cmd->temp_pool, arg_); + char *file = strchr(meth, ':'); + if (file) { + *(file++) = '\0'; + if (!*file) { + file = NULL; + } + } + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + if (ssl_config_global_isfixed(mc)) { + return NULL; + } + if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) { + mc->nMutexMode = SSL_MUTEXMODE_NONE; + return NULL; + } + + /* APR determines temporary filename unless overridden below, + * we presume file indicates an szMutexFile is a file path + * unless the method sets szMutexFile=file and NULLs file + */ + mc->nMutexMode = SSL_MUTEXMODE_USED; + mc->szMutexFile = NULL; + + /* NOTE: previously, 'yes' implied 'sem' */ + if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) { + mc->nMutexMech = APR_LOCK_DEFAULT; + } +#if APR_HAS_FCNTL_SERIALIZE + else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) { + mc->nMutexMech = APR_LOCK_FCNTL; + } +#endif +#if APR_HAS_FLOCK_SERIALIZE + else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) { + mc->nMutexMech = APR_LOCK_FLOCK; + } +#endif +#if APR_HAS_POSIXSEM_SERIALIZE + else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) { + mc->nMutexMech = APR_LOCK_POSIXSEM; + /* Posix/SysV semaphores aren't file based, use the literal name + * if provided and fall back on APR's default if not. Today, APR + * will ignore it, but once supported it has an absurdly short limit. + */ + if (file) { + mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file); + + file = NULL; + } + } +#endif +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) + else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) { + mc->nMutexMech = APR_LOCK_SYSVSEM; + } +#endif +#if APR_HAS_PROC_PTHREAD_SERIALIZE + else if (!strcasecmp(meth, "pthread")) { + mc->nMutexMech = APR_LOCK_PROC_PTHREAD; + } +#endif + else { + return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_, + " (", ssl_valid_ssl_mutex_string, ")", NULL); + } + + /* Unless the method above assumed responsibility for setting up + * mc->szMutexFile and NULLing out file, presume it is a file we + * are looking to use + */ + if (file) { + mc->szMutexFile = ap_server_root_relative(cmd->server->process->pool, file); + if (!mc->szMutexFile) { + return apr_pstrcat(cmd->pool, "Invalid SSLMutex ", meth, + ": filepath ", file, NULL); + } + } + + return NULL; +} + +const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + int arglen = strlen(arg); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + if (strcEQ(arg, "builtin")) { + sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN; + sc->server->pphrase_dialog_path = NULL; + } + else if ((arglen > 5) && strEQn(arg, "exec:", 5)) { + sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER; + sc->server->pphrase_dialog_path = + ap_server_root_relative(cmd->pool, arg+5); + if (!sc->server->pphrase_dialog_path) { + return apr_pstrcat(cmd->pool, + "Invalid SSLPassPhraseDialog exec: path ", + arg+5, NULL); + } + if (!ssl_util_path_check(SSL_PCM_EXISTS, + sc->server->pphrase_dialog_path, + cmd->pool)) + { + return apr_pstrcat(cmd->pool, + "SSLPassPhraseDialog: file '", + sc->server->pphrase_dialog_path, + "' does not exist", NULL); + } + + } + else if ((arglen > 1) && (arg[0] == '|')) { + sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE; + sc->server->pphrase_dialog_path = arg + 1; + } + else { + return "SSLPassPhraseDialog: Invalid argument"; + } + + return NULL; +} + +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) +const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLModConfigRec *mc = myModConfig(cmd->server); + const char *err; + ENGINE *e; + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + if (strcEQ(arg, "builtin")) { + mc->szCryptoDevice = NULL; + } + else if ((e = ENGINE_by_id(arg))) { + mc->szCryptoDevice = arg; + ENGINE_free(e); + } + else { + err = "SSLCryptoDevice: Invalid argument; must be one of: " + "'builtin' (none)"; + e = ENGINE_get_first(); + while (e) { + ENGINE *en; + err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e), + "' (", ENGINE_get_name(e), ")", NULL); + en = ENGINE_get_next(e); + ENGINE_free(e); + e = en; + } + return err; + } + + return NULL; +} +#endif + +const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd, + void *dcfg, + const char *arg1, + const char *arg2, + const char *arg3) +{ + SSLModConfigRec *mc = myModConfig(cmd->server); + const char *err; + ssl_randseed_t *seed; + int arg2len = strlen(arg2); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + if (ssl_config_global_isfixed(mc)) { + return NULL; + } + + seed = apr_array_push(mc->aRandSeed); + + if (strcEQ(arg1, "startup")) { + seed->nCtx = SSL_RSCTX_STARTUP; + } + else if (strcEQ(arg1, "connect")) { + seed->nCtx = SSL_RSCTX_CONNECT; + } + else { + return apr_pstrcat(cmd->pool, "SSLRandomSeed: " + "invalid context: `", arg1, "'", + NULL); + } + + if ((arg2len > 5) && strEQn(arg2, "file:", 5)) { + seed->nSrc = SSL_RSSRC_FILE; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); + } + else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) { + seed->nSrc = SSL_RSSRC_EXEC; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); + } + else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) { +#ifdef HAVE_SSL_RAND_EGD + seed->nSrc = SSL_RSSRC_EGD; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4); +#else + return "egd not supported with this SSL toolkit"; +#endif + } + else if (strcEQ(arg2, "builtin")) { + seed->nSrc = SSL_RSSRC_BUILTIN; + seed->cpPath = NULL; + } + else { + seed->nSrc = SSL_RSSRC_FILE; + seed->cpPath = ap_server_root_relative(mc->pPool, arg2); + } + + if (seed->nSrc != SSL_RSSRC_BUILTIN) { + if (!seed->cpPath) { + return apr_pstrcat(cmd->pool, + "Invalid SSLRandomSeed path ", + arg2, NULL); + } + if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) { + return apr_pstrcat(cmd->pool, + "SSLRandomSeed: source path '", + seed->cpPath, "' does not exist", NULL); + } + } + + if (!arg3) { + seed->nBytes = 0; /* read whole file */ + } + else { + if (seed->nSrc == SSL_RSSRC_BUILTIN) { + return "SSLRandomSeed: byte specification not " + "allowed for builtin seed source"; + } + + seed->nBytes = atoi(arg3); + + if (seed->nBytes < 0) { + return "SSLRandomSeed: invalid number of bytes specified"; + } + } + + return NULL; +} + +const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + if (!strcasecmp(arg, "On")) { + sc->enabled = SSL_ENABLED_TRUE; + return NULL; + } + else if (!strcasecmp(arg, "Off")) { + sc->enabled = SSL_ENABLED_FALSE; + return NULL; + } + else if (!strcasecmp(arg, "Optional")) { + sc->enabled = SSL_ENABLED_OPTIONAL; + return NULL; + } + + return "Argument must be On, Off, or Optional"; +} + +const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + + if (cmd->path) { + dc->szCipherSuite = arg; + } + else { + sc->server->auth.cipher_suite = arg; + } + + return NULL; +} + +#define SSL_FLAGS_CHECK_FILE \ + (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO) + +#define SSL_FLAGS_CHECK_DIR \ + (SSL_PCM_EXISTS|SSL_PCM_ISDIR) + +static const char *ssl_cmd_check_file(cmd_parms *parms, + const char **file) +{ + const char *filepath = ap_server_root_relative(parms->pool, *file); + + if (!filepath) { + return apr_pstrcat(parms->pool, parms->cmd->name, + ": Invalid file path ", *file, NULL); + } + *file = filepath; + + if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) { + return NULL; + } + + return apr_pstrcat(parms->pool, parms->cmd->name, + ": file '", *file, + "' does not exist or is empty", NULL); + +} + +const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag) +{ +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + sc->cipher_server_pref = flag?TRUE:FALSE; + return NULL; +#else + return "SSLHonorCiperOrder unsupported; not implemented by the SSL library"; +#endif +} + +static const char *ssl_cmd_check_dir(cmd_parms *parms, + const char **dir) +{ + const char *dirpath = ap_server_root_relative(parms->pool, *dir); + + if (!dirpath) { + return apr_pstrcat(parms->pool, parms->cmd->name, + ": Invalid dir path ", *dir, NULL); + } + *dir = dirpath; + + if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) { + return NULL; + } + + return apr_pstrcat(parms->pool, parms->cmd->name, + ": directory '", *dir, + "' does not exist", NULL); + +} + +#define SSL_AIDX_CERTS 1 +#define SSL_AIDX_KEYS 2 + +static const char *ssl_cmd_check_aidx_max(cmd_parms *parms, + const char *arg, + int idx) +{ + SSLSrvConfigRec *sc = mySrvConfig(parms->server); + const char *err, *desc=NULL, **files=NULL; + int i; + + if ((err = ssl_cmd_check_file(parms, &arg))) { + return err; + } + + switch (idx) { + case SSL_AIDX_CERTS: + desc = "certificates"; + files = sc->server->pks->cert_files; + break; + case SSL_AIDX_KEYS: + desc = "private keys"; + files = sc->server->pks->key_files; + break; + } + + for (i = 0; i < SSL_AIDX_MAX; i++) { + if (!files[i]) { + files[i] = arg; + return NULL; + } + } + + return apr_psprintf(parms->pool, + "%s: only up to %d " + "different %s per virtual host allowed", + parms->cmd->name, SSL_AIDX_MAX, desc); +} + +const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + + const char *err; + + if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) { + return err; + } + + return NULL; +} + +const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + const char *err; + + if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) { + return err; + } + + return NULL; +} + +const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->server->cert_chain = arg; + + return NULL; +} + +#define NO_PER_DIR_SSL_CA \ + "Your ssl library does not have support for per-directory CA" + +#ifdef HAVE_SSL_SET_CERT_STORE +# define MODSSL_HAVE_SSL_SET_CERT_STORE 1 +#else +# define MODSSL_HAVE_SSL_SET_CERT_STORE 0 +#endif + +#define MODSSL_SET_CA(f) \ + if (cmd->path) \ + if (MODSSL_HAVE_SSL_SET_CERT_STORE) \ + dc->f = arg; \ + else \ + return NO_PER_DIR_SSL_CA; \ + else \ + sc->f = arg \ + +const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + /* XXX: bring back per-dir */ + sc->server->auth.ca_cert_path = arg; + + return NULL; +} + +const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + /* XXX: bring back per-dir */ + sc->server->auth.ca_cert_file = arg; + + return NULL; +} + +const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + sc->server->pks->ca_name_path = arg; + + return NULL; +} + +const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->server->pks->ca_name_file = arg; + + return NULL; +} + +const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + sc->server->crl_path = arg; + + return NULL; +} + +const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->server->crl_file = arg; + + return NULL; +} + +static const char *ssl_cmd_verify_parse(cmd_parms *parms, + const char *arg, + ssl_verify_t *id) +{ + if (strcEQ(arg, "none") || strcEQ(arg, "off")) { + *id = SSL_CVERIFY_NONE; + } + else if (strcEQ(arg, "optional")) { + *id = SSL_CVERIFY_OPTIONAL; + } + else if (strcEQ(arg, "require") || strcEQ(arg, "on")) { + *id = SSL_CVERIFY_REQUIRE; + } + else if (strcEQ(arg, "optional_no_ca")) { + *id = SSL_CVERIFY_OPTIONAL_NO_CA; + } + else { + return apr_pstrcat(parms->temp_pool, parms->cmd->name, + ": Invalid argument '", arg, "'", + NULL); + } + + return NULL; +} + +const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + ssl_verify_t mode; + const char *err; + + if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) { + return err; + } + + if (cmd->path) { + dc->nVerifyClient = mode; + } + else { + sc->server->auth.verify_mode = mode; + } + + return NULL; +} + +static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms, + const char *arg, + int *depth) +{ + if ((*depth = atoi(arg)) >= 0) { + return NULL; + } + + return apr_pstrcat(parms->temp_pool, parms->cmd->name, + ": Invalid argument '", arg, "'", + NULL); +} + +const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + int depth; + const char *err; + + if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) { + return err; + } + + if (cmd->path) { + dc->nVerifyDepth = depth; + } + else { + sc->server->auth.verify_depth = depth; + } + + return NULL; +} + +#define MODSSL_NO_SHARED_MEMORY_ERROR \ + "SSLSessionCache: shared memory cache not useable on this platform" + +const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLModConfigRec *mc = myModConfig(cmd->server); + const char *err, *colon; + char *cp, *cp2; + int arglen = strlen(arg); + + if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { + return err; + } + + if (ssl_config_global_isfixed(mc)) { + return NULL; + } + + if (strcEQ(arg, "none")) { + mc->nSessionCacheMode = SSL_SCMODE_NONE; + mc->szSessionCacheDataFile = NULL; + } + else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) { + mc->nSessionCacheMode = SSL_SCMODE_DBM; + mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4); + if (!mc->szSessionCacheDataFile) { + return apr_psprintf(cmd->pool, + "SSLSessionCache: Invalid cache file path %s", + arg+4); + } + } + else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) || + ((arglen > 6) && strcEQn(arg, "shmht:", 6)) || + ((arglen > 6) && strcEQn(arg, "shmcb:", 6))) { +#if !APR_HAS_SHARED_MEMORY + return MODSSL_NO_SHARED_MEMORY_ERROR; +#endif + mc->nSessionCacheMode = SSL_SCMODE_SHMCB; + colon = ap_strchr_c(arg, ':'); + mc->szSessionCacheDataFile = + ap_server_root_relative(mc->pPool, colon+1); + if (!mc->szSessionCacheDataFile) { + return apr_psprintf(cmd->pool, + "SSLSessionCache: Invalid cache file path %s", + colon+1); + } + mc->tSessionCacheDataTable = NULL; + mc->nSessionCacheDataSize = 1024*512; /* 512KB */ + + if ((cp = strchr(mc->szSessionCacheDataFile, '('))) { + *cp++ = NUL; + + if (!(cp2 = strchr(cp, ')'))) { + return "SSLSessionCache: Invalid argument: " + "no closing parenthesis"; + } + + *cp2 = NUL; + + mc->nSessionCacheDataSize = atoi(cp); + + if (mc->nSessionCacheDataSize < 8192) { + return "SSLSessionCache: Invalid argument: " + "size has to be >= 8192 bytes"; + + } + + if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) { + return apr_psprintf(cmd->pool, + "SSLSessionCache: Invalid argument: " + "size has to be < %d bytes on this " + "platform", APR_SHM_MAXSIZE); + + } + } + } + else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) { +#ifdef HAVE_DISTCACHE + mc->nSessionCacheMode = SSL_SCMODE_DC; + mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3); + if (!mc->szSessionCacheDataFile) { + return apr_pstrcat(cmd->pool, + "SSLSessionCache: Invalid cache file path: ", + arg+3, NULL); + } +#else + return "SSLSessionCache: distcache support disabled"; +#endif + } + else { + return "SSLSessionCache: Invalid argument"; + } + + return NULL; +} + +const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + sc->session_cache_timeout = atoi(arg); + + if (sc->session_cache_timeout < 0) { + return "SSLSessionCacheTimeout: Invalid argument"; + } + + return NULL; +} + +const char *ssl_cmd_SSLOptions(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + ssl_opt_t opt; + int first = TRUE; + char action, *w; + + while (*arg) { + w = ap_getword_conf(cmd->pool, &arg); + action = NUL; + + if ((*w == '+') || (*w == '-')) { + action = *(w++); + } + else if (first) { + dc->nOptions = SSL_OPT_NONE; + first = FALSE; + } + + if (strcEQ(w, "StdEnvVars")) { + opt = SSL_OPT_STDENVVARS; + } + else if (strcEQ(w, "ExportCertData")) { + opt = SSL_OPT_EXPORTCERTDATA; + } + else if (strcEQ(w, "FakeBasicAuth")) { + opt = SSL_OPT_FAKEBASICAUTH; + } + else if (strcEQ(w, "StrictRequire")) { + opt = SSL_OPT_STRICTREQUIRE; + } + else if (strcEQ(w, "OptRenegotiate")) { + opt = SSL_OPT_OPTRENEGOTIATE; + } + else { + return apr_pstrcat(cmd->pool, + "SSLOptions: Illegal option '", w, "'", + NULL); + } + + if (action == '-') { + dc->nOptionsAdd &= ~opt; + dc->nOptionsDel |= opt; + dc->nOptions &= ~opt; + } + else if (action == '+') { + dc->nOptionsAdd |= opt; + dc->nOptionsDel &= ~opt; + dc->nOptions |= opt; + } + else { + dc->nOptions = opt; + dc->nOptionsAdd = opt; + dc->nOptionsDel = SSL_OPT_NONE; + } + } + + return NULL; +} + +const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + + dc->bSSLRequired = TRUE; + + return NULL; +} + +const char *ssl_cmd_SSLRequire(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + ssl_expr *expr; + ssl_require_t *require; + + if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) { + return apr_pstrcat(cmd->pool, "SSLRequire: ", + ssl_expr_get_error(), NULL); + } + + require = apr_array_push(dc->aRequirement); + require->cpExpr = apr_pstrdup(cmd->pool, arg); + require->mpExpr = expr; + + return NULL; +} + +static const char *ssl_cmd_protocol_parse(cmd_parms *parms, + const char *arg, + ssl_proto_t *options) +{ + ssl_proto_t thisopt; + + *options = SSL_PROTOCOL_NONE; + + while (*arg) { + char *w = ap_getword_conf(parms->temp_pool, &arg); + char action = '\0'; + + if ((*w == '+') || (*w == '-')) { + action = *(w++); + } + + if (strcEQ(w, "SSLv2")) { + thisopt = SSL_PROTOCOL_SSLV2; + } + else if (strcEQ(w, "SSLv3")) { + thisopt = SSL_PROTOCOL_SSLV3; + } + else if (strcEQ(w, "TLSv1")) { + thisopt = SSL_PROTOCOL_TLSV1; + } + else if (strcEQ(w, "all")) { + thisopt = SSL_PROTOCOL_ALL; + } + else { + return apr_pstrcat(parms->temp_pool, + parms->cmd->name, + ": Illegal protocol '", + w, "'", NULL); + } + + if (action == '-') { + *options &= ~thisopt; + } + else if (action == '+') { + *options |= thisopt; + } + else { + *options = thisopt; + } + } + + return NULL; +} + +const char *ssl_cmd_SSLProtocol(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol); +} + +const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + sc->proxy_enabled = flag ? TRUE : FALSE; + + return NULL; +} + +const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol); +} + +const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + sc->proxy->auth.cipher_suite = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + ssl_verify_t mode; + const char *err; + + if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) { + return err; + } + + sc->proxy->auth.verify_mode = mode; + + return NULL; +} + +const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + int depth; + const char *err; + + if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) { + return err; + } + + sc->proxy->auth.verify_depth = depth; + + return NULL; +} + +const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->proxy->auth.ca_cert_file = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + sc->proxy->auth.ca_cert_path = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + sc->proxy->crl_path = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->proxy->crl_file = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_file(cmd, &arg))) { + return err; + } + + sc->proxy->pkp->cert_file = arg; + + return NULL; +} + +const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd, + void *dcfg, + const char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + const char *err; + + if ((err = ssl_cmd_check_dir(cmd, &arg))) { + return err; + } + + sc->proxy->pkp->cert_path = arg; + + return NULL; +} + + +const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg, + const char *arg) +{ + SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; + dc->szUserName = arg; + return NULL; +} + +void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) +{ + if (!ap_exists_config_define("DUMP_CERTS")) { + return; + } + + /* Dump the filenames of all configured server certificates to + * stdout. */ + while (s) { + SSLSrvConfigRec *sc = mySrvConfig(s); + + if (sc && sc->server && sc->server->pks) { + modssl_pk_server_t *const pks = sc->server->pks; + int i; + + for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) { + printf("%s\n", pks->cert_files[i]); + } + } + + s = s->next; + } + +} diff --git a/trunk/modules/ssl/ssl_engine_dh.c b/trunk/modules/ssl/ssl_engine_dh.c new file mode 100644 index 0000000000..48884d241b --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_dh.c @@ -0,0 +1,208 @@ +#if 0 +=pod +#endif + +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_dh.c + * Diffie-Hellman Built-in Temporary Parameters + */ + +#include "ssl_private.h" + +/* ----BEGIN GENERATED SECTION-------- */ + +/* +** Diffie-Hellman-Parameters: (512 bit) +** prime: +** 00:d4:bc:d5:24:06:f6:9b:35:99:4b:88:de:5d:b8: +** 96:82:c8:15:7f:62:d8:f3:36:33:ee:57:72:f1:1f: +** 05:ab:22:d6:b5:14:5b:9f:24:1e:5a:cc:31:ff:09: +** 0a:4b:c7:11:48:97:6f:76:79:50:94:e7:1e:79:03: +** 52:9f:5a:82:4b +** generator: 2 (0x2) +** Diffie-Hellman-Parameters: (1024 bit) +** prime: +** 00:e6:96:9d:3d:49:5b:e3:2c:7c:f1:80:c3:bd:d4: +** 79:8e:91:b7:81:82:51:bb:05:5e:2a:20:64:90:4a: +** 79:a7:70:fa:15:a2:59:cb:d5:23:a6:a6:ef:09:c4: +** 30:48:d5:a2:2f:97:1f:3c:20:12:9b:48:00:0e:6e: +** dd:06:1c:bc:05:3e:37:1d:79:4e:53:27:df:61:1e: +** bb:be:1b:ac:9b:5c:60:44:cf:02:3d:76:e0:5e:ea: +** 9b:ad:99:1b:13:a6:3c:97:4e:9e:f1:83:9e:b5:db: +** 12:51:36:f7:26:2e:56:a8:87:15:38:df:d8:23:c6: +** 50:50:85:e2:1f:0d:d5:c8:6b +** generator: 2 (0x2) +*/ + +static unsigned char dh512_p[] = +{ + 0xD4, 0xBC, 0xD5, 0x24, 0x06, 0xF6, 0x9B, 0x35, 0x99, 0x4B, 0x88, 0xDE, + 0x5D, 0xB8, 0x96, 0x82, 0xC8, 0x15, 0x7F, 0x62, 0xD8, 0xF3, 0x36, 0x33, + 0xEE, 0x57, 0x72, 0xF1, 0x1F, 0x05, 0xAB, 0x22, 0xD6, 0xB5, 0x14, 0x5B, + 0x9F, 0x24, 0x1E, 0x5A, 0xCC, 0x31, 0xFF, 0x09, 0x0A, 0x4B, 0xC7, 0x11, + 0x48, 0x97, 0x6F, 0x76, 0x79, 0x50, 0x94, 0xE7, 0x1E, 0x79, 0x03, 0x52, + 0x9F, 0x5A, 0x82, 0x4B, +}; +static unsigned char dh512_g[] = +{ + 0x02, +}; + +static DH *get_dh512(void) +{ + return modssl_dh_configure(dh512_p, sizeof(dh512_p), + dh512_g, sizeof(dh512_g)); +} + +static unsigned char dh1024_p[] = +{ + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, +}; +static unsigned char dh1024_g[] = +{ + 0x02, +}; + +static DH *get_dh1024(void) +{ + return modssl_dh_configure(dh1024_p, sizeof(dh1024_p), + dh1024_g, sizeof(dh1024_g)); +} +/* ----END GENERATED SECTION---------- */ + +DH *ssl_dh_GetTmpParam(int nKeyLen) +{ + DH *dh; + + if (nKeyLen == 512) + dh = get_dh512(); + else if (nKeyLen == 1024) + dh = get_dh1024(); + else + dh = get_dh1024(); + return dh; +} + +DH *ssl_dh_GetParamFromFile(char *file) +{ + DH *dh = NULL; + BIO *bio; + + if ((bio = BIO_new_file(file, "r")) == NULL) + return NULL; +#if SSL_LIBRARY_VERSION < 0x00904000 + dh = PEM_read_bio_DHparams(bio, NULL, NULL); +#else + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); +#endif + BIO_free(bio); + return (dh); +} + +/* +=cut +## +## Embedded Perl script for generating the temporary DH parameters +## + +require 5.003; +use strict; + +# configuration +my $file = $0; +my $begin = '----BEGIN GENERATED SECTION--------'; +my $end = '----END GENERATED SECTION----------'; + +# read ourself and keep a backup +open(FP, "<$file") || die; +my $source = ''; +$source .= $_ while (); +close(FP); +open(FP, ">$file.bak") || die; +print FP $source; +close(FP); + +# generate the DH parameters +print "1. Generate 512 and 1024 bit Diffie-Hellman parameters (p, g)\n"; +my $rand = ''; +foreach $file (qw(/var/log/messages /var/adm/messages + /kernel /vmunix /vmlinuz /etc/hosts /etc/resolv.conf)) { + if (-f $file) { + $rand = $file if ($rand eq ''); + $rand .= ":$file" if ($rand ne ''); + } +} +$rand = "-rand $rand" if ($rand ne ''); +system("openssl gendh $rand -out dh512.pem 512"); +system("openssl gendh $rand -out dh1024.pem 1024"); + +# generate DH param info +my $dhinfo = ''; +open(FP, "openssl dh -noout -text -in dh512.pem |") || die; +$dhinfo .= $_ while (); +close(FP); +open(FP, "openssl dh -noout -text -in dh1024.pem |") || die; +$dhinfo .= $_ while (); +close(FP); +$dhinfo =~ s|^|** |mg; +$dhinfo = "\n\/\*\n$dhinfo\*\/\n\n"; + +# generate C source from DH params +my $dhsource = ''; +open(FP, "openssl dh -noout -C -in dh512.pem | indent | expand |") || die; +$dhsource .= $_ while (); +close(FP); +open(FP, "openssl dh -noout -C -in dh1024.pem | indent | expand |") || die; +$dhsource .= $_ while (); +close(FP); +$dhsource =~ s|(DH\s+\*get_dh)|static $1|sg; + +# generate output +my $o = $dhinfo . $dhsource; + +# insert the generated code at the target location +$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s; + +# and update the source on disk +print "Updating file `$file'\n"; +open(FP, ">$file") || die; +print FP $source; +close(FP); + +# cleanup +unlink("dh512.pem"); +unlink("dh1024.pem"); + +=pod +*/ diff --git a/trunk/modules/ssl/ssl_engine_init.c b/trunk/modules/ssl/ssl_engine_init.c new file mode 100644 index 0000000000..90094df44f --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_init.c @@ -0,0 +1,1264 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_init.c + * Initialization of Servers + */ + /* ``Recursive, adj.; + see Recursive.'' + -- Unknown */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Module Initialization +** _________________________________________________________________ +*/ + +static char *ssl_add_version_component(apr_pool_t *p, + server_rec *s, + char *name) +{ + char *val = ssl_var_lookup(p, s, NULL, NULL, name); + + if (val && *val) { + ap_add_version_component(p, val); + } + + return val; +} + +static char *version_components[] = { + "SSL_VERSION_PRODUCT", + "SSL_VERSION_INTERFACE", + "SSL_VERSION_LIBRARY", + NULL +}; + +static void ssl_add_version_components(apr_pool_t *p, + server_rec *s) +{ + char *vals[sizeof(version_components)/sizeof(char *)]; + int i; + + for (i=0; version_components[i]; i++) { + vals[i] = ssl_add_version_component(p, s, + version_components[i]); + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Server: %s, Interface: %s, Library: %s", + AP_SERVER_BASEVERSION, + vals[1], /* SSL_VERSION_INTERFACE */ + vals[2]); /* SSL_VERSION_LIBRARY */ +} + + +/* + * Handle the Temporary RSA Keys and DH Params + */ + +#define MODSSL_TMP_KEY_FREE(mc, type, idx) \ + if (mc->pTmpKeys[idx]) { \ + type##_free((type *)mc->pTmpKeys[idx]); \ + mc->pTmpKeys[idx] = NULL; \ + } + +#define MODSSL_TMP_KEYS_FREE(mc, type) \ + MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \ + MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024) + +static void ssl_tmp_keys_free(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + + MODSSL_TMP_KEYS_FREE(mc, RSA); + MODSSL_TMP_KEYS_FREE(mc, DH); +} + +static int ssl_tmp_key_init_rsa(server_rec *s, + int bits, int idx) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (!(mc->pTmpKeys[idx] = + RSA_generate_key(bits, RSA_F4, NULL, NULL))) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Failed to generate temporary " + "%d bit RSA private key", bits); + return !OK; + } + + return OK; +} + +static int ssl_tmp_key_init_dh(server_rec *s, + int bits, int idx) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (!(mc->pTmpKeys[idx] = + ssl_dh_GetTmpParam(bits))) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Failed to generate temporary " + "%d bit DH parameters", bits); + return !OK; + } + + return OK; +} + +#define MODSSL_TMP_KEY_INIT_RSA(s, bits) \ + ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits) + +#define MODSSL_TMP_KEY_INIT_DH(s, bits) \ + ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits) + +static int ssl_tmp_keys_init(server_rec *s) +{ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Generating temporary RSA private keys (512/1024 bits)"); + + if (MODSSL_TMP_KEY_INIT_RSA(s, 512) || + MODSSL_TMP_KEY_INIT_RSA(s, 1024)) { + return !OK; + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Generating temporary DH parameters (512/1024 bits)"); + + if (MODSSL_TMP_KEY_INIT_DH(s, 512) || + MODSSL_TMP_KEY_INIT_DH(s, 1024)) { + return !OK; + } + + return OK; +} + +/* + * Per-module initialization + */ +int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, + server_rec *base_server) +{ + SSLModConfigRec *mc = myModConfig(base_server); + SSLSrvConfigRec *sc; + server_rec *s; + + /* We initialize mc->pid per-process in the child init, + * but it should be initialized for startup before we + * call ssl_rand_seed() below. + */ + mc->pid = getpid(); + + /* + * Let us cleanup on restarts and exists + */ + apr_pool_cleanup_register(p, base_server, + ssl_init_ModuleKill, + apr_pool_cleanup_null); + + /* + * Any init round fixes the global config + */ + ssl_config_global_create(base_server); /* just to avoid problems */ + ssl_config_global_fix(mc); + + /* + * try to fix the configuration and open the dedicated SSL + * logfile as early as possible + */ + for (s = base_server; s; s = s->next) { + sc = mySrvConfig(s); + + if (sc->server) { + sc->server->sc = sc; + } + + if (sc->proxy) { + sc->proxy->sc = sc; + } + + /* + * Create the server host:port string because we need it a lot + */ + sc->vhost_id = ssl_util_vhostid(p, s); + sc->vhost_id_len = strlen(sc->vhost_id); + + /* If sc->enabled is UNSET, then SSL is optional on this vhost */ + /* Fix up stuff that may not have been set */ + if (sc->enabled == SSL_ENABLED_UNSET) { + sc->enabled = SSL_ENABLED_FALSE; + } + if (sc->proxy_enabled == UNSET) { + sc->proxy_enabled = FALSE; + } + + if (sc->session_cache_timeout == UNSET) { + sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT; + } + + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) { + sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN; + } + + } + + /* + * SSL external crypto device ("engine") support + */ +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + ssl_init_Engine(base_server, p); +#endif + +#if APR_HAS_THREADS + ssl_util_thread_setup(p); +#endif + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Initialized %s library", SSL_LIBRARY_NAME); + + /* + * Seed the Pseudo Random Number Generator (PRNG) + * only need ptemp here; nothing inside allocated from the pool + * needs to live once we return from ssl_rand_seed(). + */ + ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: "); + + /* + * read server private keys/public certs into memory. + * decrypting any encrypted keys via configured SSLPassPhraseDialogs + * anything that needs to live longer than ptemp needs to also survive + * restarts, in which case they'll live inside s->process->pool. + */ + ssl_pphrase_Handle(base_server, ptemp); + + if (ssl_tmp_keys_init(base_server)) { + return !OK; + } + + /* + * initialize the mutex handling + */ + if (!ssl_mutex_init(base_server, p)) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* + * initialize session caching + */ + ssl_scache_init(base_server, p); + + /* + * initialize servers + */ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, + "Init: Initializing (virtual) servers for SSL"); + + for (s = base_server; s; s = s->next) { + sc = mySrvConfig(s); + /* + * Either now skip this server when SSL is disabled for + * it or give out some information about what we're + * configuring. + */ + + /* + * Read the server certificate and key + */ + ssl_init_ConfigureServer(s, p, ptemp, sc); + } + + /* + * Configuration consistency checks + */ + ssl_init_CheckServers(base_server, ptemp); + + /* + * Announce mod_ssl and SSL library in HTTP Server field + * as ``mod_ssl/X.X.X OpenSSL/X.X.X'' + */ + ssl_add_version_components(p, base_server); + + SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ + + return OK; +} + +/* + * Support for external a Crypto Device ("engine"), usually + * a hardware accellerator card for crypto operations. + */ +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) +void ssl_init_Engine(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + ENGINE *e; + + if (mc->szCryptoDevice) { + if (!(e = ENGINE_by_id(mc->szCryptoDevice))) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Failed to load Crypto Device API `%s'", + mc->szCryptoDevice); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + if (strEQ(mc->szCryptoDevice, "chil")) { + ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); + } + + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Failed to enable Crypto Device API `%s'", + mc->szCryptoDevice); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + ENGINE_free(e); + } +} +#endif + +static void ssl_init_server_check(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + /* + * check for important parameters and the + * possibility that the user forgot to set them. + */ + if (!mctx->pks->cert_files[0]) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "No SSL Certificate set [hint: SSLCertificateFile]"); + ssl_die(); + } + + /* + * Check for problematic re-initializations + */ + if (mctx->pks->certs[SSL_AIDX_RSA] || + mctx->pks->certs[SSL_AIDX_DSA]) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Illegal attempt to re-initialise SSL for server " + "(theoretically shouldn't happen!)"); + ssl_die(); + } +} + +static void ssl_init_ctx_protocol(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSL_CTX *ctx = NULL; + SSL_METHOD *method = NULL; + char *cp; + int protocol = mctx->protocol; + + /* + * Create the new per-server SSL context + */ + if (protocol == SSL_PROTOCOL_NONE) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "No SSL protocols available [hint: SSLProtocol]"); + ssl_die(); + } + + cp = apr_pstrcat(p, + (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""), + (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), + (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), + NULL); + cp[strlen(cp)-2] = NUL; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Creating new SSL context (protocols: %s)", cp); + + if (protocol == SSL_PROTOCOL_SSLV2) { + method = mctx->pkp ? + SSLv2_client_method() : /* proxy */ + SSLv2_server_method(); /* server */ + ctx = SSL_CTX_new(method); /* only SSLv2 is left */ + } + else { + method = mctx->pkp ? + SSLv23_client_method() : /* proxy */ + SSLv23_server_method(); /* server */ + ctx = SSL_CTX_new(method); /* be more flexible */ + } + + mctx->ssl_ctx = ctx; + + SSL_CTX_set_options(ctx, SSL_OP_ALL); + + if (!(protocol & SSL_PROTOCOL_SSLV2)) { + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); + } + + if (!(protocol & SSL_PROTOCOL_SSLV3)) { + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); + } + + if (!(protocol & SSL_PROTOCOL_TLSV1)) { + SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); + } + +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + { + SSLSrvConfigRec *sc = mySrvConfig(s); + if (sc->cipher_server_pref == TRUE) { + SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + } +#endif + + SSL_CTX_set_app_data(ctx, s); + + /* + * Configure additional context ingredients + */ + SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); + +#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + /* + * Disallow a session from being resumed during a renegotiation, + * so that an acceptable cipher suite can be negotiated. + */ + SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); +#endif +} + +static void ssl_init_ctx_session_cache(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSL_CTX *ctx = mctx->ssl_ctx; + SSLModConfigRec *mc = myModConfig(s); + long cache_mode = SSL_SESS_CACHE_OFF; + + if (mc->nSessionCacheMode != SSL_SCMODE_NONE) { + /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL + * to ignore process local-caching and + * to always get/set/delete sessions using mod_ssl's callbacks. + */ + cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL; + } + + SSL_CTX_set_session_cache_mode(ctx, cache_mode); + + SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry); + SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry); + SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry); +} + +static void ssl_init_ctx_callbacks(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSL_CTX *ctx = mctx->ssl_ctx; + + SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); + + if (s->loglevel >= APLOG_DEBUG) { + /* this callback only logs if LogLevel >= info */ + SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); + } +} + +static void ssl_init_ctx_verify(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSL_CTX *ctx = mctx->ssl_ctx; + + int verify = SSL_VERIFY_NONE; + STACK_OF(X509_NAME) *ca_list; + + if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) { + mctx->auth.verify_mode = SSL_CVERIFY_NONE; + } + + if (mctx->auth.verify_depth == UNSET) { + mctx->auth.verify_depth = 1; + } + + /* + * Configure callbacks for SSL context + */ + if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) { + verify |= SSL_VERIFY_PEER_STRICT; + } + + if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) || + (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) + { + verify |= SSL_VERIFY_PEER; + } + + SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify); + + /* + * Configure Client Authentication details + */ + if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring client authentication"); + + if (!SSL_CTX_load_verify_locations(ctx, + MODSSL_PCHAR_CAST mctx->auth.ca_cert_file, + MODSSL_PCHAR_CAST mctx->auth.ca_cert_path)) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to configure verify locations " + "for client authentication"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { + ca_list = ssl_init_FindCAList(s, ptemp, + mctx->pks->ca_name_file, + mctx->pks->ca_name_path); + } else + ca_list = ssl_init_FindCAList(s, ptemp, + mctx->auth.ca_cert_file, + mctx->auth.ca_cert_path); + if (!ca_list) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to determine list of acceptable " + "CA certificates for client authentication"); + ssl_die(); + } + + SSL_CTX_set_client_CA_list(ctx, (STACK *)ca_list); + } + + /* + * Give a warning when no CAs were configured but client authentication + * should take place. This cannot work. + */ + if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) { + ca_list = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx); + + if (sk_X509_NAME_num(ca_list) == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Init: Oops, you want to request client " + "authentication, but no CAs are known for " + "verification!? [Hint: SSLCACertificate*]"); + } + } +} + +static void ssl_init_ctx_cipher_suite(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + SSL_CTX *ctx = mctx->ssl_ctx; + const char *suite = mctx->auth.cipher_suite; + + /* + * Configure SSL Cipher Suite + */ + if (!suite) { + return; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring permitted SSL ciphers [%s]", + suite); + + if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to configure permitted SSL ciphers"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } +} + +static void ssl_init_ctx_crl(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + /* + * Configure Certificate Revocation List (CRL) Details + */ + + if (!(mctx->crl_file || mctx->crl_path)) { + return; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring certificate revocation facility"); + + mctx->crl = + SSL_X509_STORE_create((char *)mctx->crl_file, + (char *)mctx->crl_path); + + if (!mctx->crl) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to configure X.509 CRL storage " + "for certificate revocation"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } +} + +static void ssl_init_ctx_cert_chain(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + BOOL skip_first = FALSE; + int i, n; + const char *chain = mctx->cert_chain; + + /* + * Optionally configure extra server certificate chain certificates. + * This is usually done by OpenSSL automatically when one of the + * server cert issuers are found under SSLCACertificatePath or in + * SSLCACertificateFile. But because these are intended for client + * authentication it can conflict. For instance when you use a + * Global ID server certificate you've to send out the intermediate + * CA certificate, too. When you would just configure this with + * SSLCACertificateFile and also use client authentication mod_ssl + * would accept all clients also issued by this CA. Obviously this + * isn't what we want in this situation. So this feature here exists + * to allow one to explicity configure CA certificates which are + * used only for the server certificate chain. + */ + if (!chain) { + return; + } + + for (i = 0; (i < SSL_AIDX_MAX) && mctx->pks->cert_files[i]; i++) { + if (strEQ(mctx->pks->cert_files[i], chain)) { + skip_first = TRUE; + break; + } + } + + n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx, + (char *)chain, + skip_first, NULL); + if (n < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Failed to configure CA certificate chain!"); + ssl_die(); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring server certificate chain " + "(%d CA certificate%s)", + n, n == 1 ? "" : "s"); +} + +static void ssl_init_ctx(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + ssl_init_ctx_protocol(s, p, ptemp, mctx); + + ssl_init_ctx_session_cache(s, p, ptemp, mctx); + + ssl_init_ctx_callbacks(s, p, ptemp, mctx); + + ssl_init_ctx_verify(s, p, ptemp, mctx); + + ssl_init_ctx_cipher_suite(s, p, ptemp, mctx); + + ssl_init_ctx_crl(s, p, ptemp, mctx); + + if (mctx->pks) { + /* XXX: proxy support? */ + ssl_init_ctx_cert_chain(s, p, ptemp, mctx); + } +} + +static int ssl_server_import_cert(server_rec *s, + modssl_ctx_t *mctx, + const char *id, + int idx) +{ + SSLModConfigRec *mc = myModConfig(s); + ssl_asn1_t *asn1; + unsigned char *ptr; + const char *type = ssl_asn1_keystr(idx); + X509 *cert; + + if (!(asn1 = ssl_asn1_table_get(mc->tPublicCert, id))) { + return FALSE; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring %s server certificate", type); + + ptr = asn1->cpData; + if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to import %s server certificate", type); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to configure %s server certificate", type); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + mctx->pks->certs[idx] = cert; + + return TRUE; +} + +static int ssl_server_import_key(server_rec *s, + modssl_ctx_t *mctx, + const char *id, + int idx) +{ + SSLModConfigRec *mc = myModConfig(s); + ssl_asn1_t *asn1; + unsigned char *ptr; + const char *type = ssl_asn1_keystr(idx); + int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA; + EVP_PKEY *pkey; + + if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) { + return FALSE; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring %s server private key", type); + + ptr = asn1->cpData; + if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData))) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to import %s server private key", type); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to configure %s server private key", type); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + /* + * XXX: wonder if this is still needed, this is old todo doc. + * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html) + */ + if ((pkey_type == EVP_PKEY_DSA) && mctx->pks->certs[idx]) { + EVP_PKEY *pubkey = X509_get_pubkey(mctx->pks->certs[idx]); + + if (pubkey && EVP_PKEY_missing_parameters(pubkey)) { + EVP_PKEY_copy_parameters(pubkey, pkey); + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Copying DSA parameters from private key to certificate"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + EVP_PKEY_free(pubkey); + } + } + + mctx->pks->keys[idx] = pkey; + + return TRUE; +} + +static void ssl_check_public_cert(server_rec *s, + apr_pool_t *ptemp, + X509 *cert, + int type) +{ + int is_ca, pathlen; + char *cn; + + if (!cert) { + return; + } + + /* + * Some information about the certificate(s) + */ + + if (SSL_X509_isSGC(cert)) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "%s server certificate enables " + "Server Gated Cryptography (SGC)", + ssl_asn1_keystr(type)); + } + + if (SSL_X509_getBC(cert, &is_ca, &pathlen)) { + if (is_ca) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "%s server certificate is a CA certificate " + "(BasicConstraints: CA == TRUE !?)", + ssl_asn1_keystr(type)); + } + + if (pathlen > 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "%s server certificate is not a leaf certificate " + "(BasicConstraints: pathlen == %d > 0 !?)", + ssl_asn1_keystr(type), pathlen); + } + } + + if (SSL_X509_getCN(ptemp, cert, &cn)) { + int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND; + + if (apr_fnmatch_test(cn) && + (apr_fnmatch(cn, s->server_hostname, + fnm_flags) == APR_FNM_NOMATCH)) + { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "%s server certificate wildcard CommonName (CN) `%s' " + "does NOT match server name!?", + ssl_asn1_keystr(type), cn); + } + else if (strNE(s->server_hostname, cn)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "%s server certificate CommonName (CN) `%s' " + "does NOT match server name!?", + ssl_asn1_keystr(type), cn); + } + } +} + +static void ssl_init_server_certs(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + const char *rsa_id, *dsa_id; + const char *vhost_id = mctx->sc->vhost_id; + int i; + int have_rsa, have_dsa; + + rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA); + dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA); + + have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA); + have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA); + + if (!(have_rsa || have_dsa)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Oops, no RSA or DSA server certificate found?!"); + ssl_die(); + } + + for (i = 0; i < SSL_AIDX_MAX; i++) { + ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i); + } + + have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA); + have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA); + + if (!(have_rsa || have_dsa)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Oops, no RSA or DSA server private key found?!"); + ssl_die(); + } +} + +static void ssl_init_proxy_certs(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + int n, ncerts = 0; + STACK_OF(X509_INFO) *sk; + modssl_pk_proxy_t *pkp = mctx->pkp; + + SSL_CTX_set_client_cert_cb(mctx->ssl_ctx, + ssl_callback_proxy_cert); + + if (!(pkp->cert_file || pkp->cert_path)) { + return; + } + + sk = sk_X509_INFO_new_null(); + + if (pkp->cert_file) { + SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file); + } + + if (pkp->cert_path) { + SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path); + } + + if ((ncerts = sk_X509_INFO_num(sk)) <= 0) { + sk_X509_INFO_free(sk); + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "no client certs found for SSL proxy"); + return; + } + + /* Check that all client certs have got certificates and private + * keys. */ + for (n = 0; n < ncerts; n++) { + X509_INFO *inf = sk_X509_INFO_value(sk, n); + + if (!inf->x509 || !inf->x_pkey) { + sk_X509_INFO_free(sk); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, + "incomplete client cert configured for SSL proxy " + "(missing or encrypted private key?)"); + ssl_die(); + return; + } + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "loaded %d client certs for SSL proxy", + ncerts); + pkp->certs = sk; +} + +static void ssl_init_proxy_ctx(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + SSLSrvConfigRec *sc) +{ + ssl_init_ctx(s, p, ptemp, sc->proxy); + + ssl_init_proxy_certs(s, p, ptemp, sc->proxy); +} + +static void ssl_init_server_ctx(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + SSLSrvConfigRec *sc) +{ + ssl_init_server_check(s, p, ptemp, sc->server); + + ssl_init_ctx(s, p, ptemp, sc->server); + + ssl_init_server_certs(s, p, ptemp, sc->server); +} + +/* + * Configure a particular server + */ +void ssl_init_ConfigureServer(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + SSLSrvConfigRec *sc) +{ + /* Initialize the server if SSL is enabled or optional. + */ + if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Configuring server for SSL protocol"); + ssl_init_server_ctx(s, p, ptemp, sc); + } + + if (sc->proxy_enabled) { + ssl_init_proxy_ctx(s, p, ptemp, sc); + } +} + +void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) +{ + server_rec *s, *ps; + SSLSrvConfigRec *sc; + apr_hash_t *table; + const char *key; + apr_ssize_t klen; + + BOOL conflict = FALSE; + + /* + * Give out warnings when a server has HTTPS configured + * for the HTTP port or vice versa + */ + for (s = base_server; s; s = s->next) { + sc = mySrvConfig(s); + + if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + base_server, + "Init: (%s) You configured HTTPS(%d) " + "on the standard HTTP(%d) port!", + ssl_util_vhostid(p, s), + DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT); + } + + if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + base_server, + "Init: (%s) You configured HTTP(%d) " + "on the standard HTTPS(%d) port!", + ssl_util_vhostid(p, s), + DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); + } + } + + /* + * Give out warnings when more than one SSL-aware virtual server uses the + * same IP:port. This doesn't work because mod_ssl then will always use + * just the certificate/keys of one virtual host (which one cannot be said + * easily - but that doesn't matter here). + */ + table = apr_hash_make(p); + + for (s = base_server; s; s = s->next) { + sc = mySrvConfig(s); + + if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) { + continue; + } + + key = apr_psprintf(p, "%pA:%u", + &s->addrs->host_addr, s->addrs->host_port); + klen = strlen(key); + + if ((ps = (server_rec *)apr_hash_get(table, key, klen))) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + base_server, + "Init: SSL server IP/port conflict: " + "%s (%s:%d) vs. %s (%s:%d)", + ssl_util_vhostid(p, s), + (s->defn_name ? s->defn_name : "unknown"), + s->defn_line_number, + ssl_util_vhostid(p, ps), + (ps->defn_name ? ps->defn_name : "unknown"), + ps->defn_line_number); + conflict = TRUE; + continue; + } + + apr_hash_set(table, key, klen, s); + } + + if (conflict) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, + "Init: You should not use name-based " + "virtual hosts in conjunction with SSL!!"); + } +} + +#ifdef SSLC_VERSION_NUMBER +static int ssl_init_FindCAList_X509NameCmp(char **a, char **b) +{ + return(X509_NAME_cmp((void*)*a, (void*)*b)); +} +#else +static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b) +{ + return(X509_NAME_cmp(*a, *b)); +} +#endif + +static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list, + server_rec *s, const char *file) +{ + int n; + STACK_OF(X509_NAME) *sk; + + sk = (STACK_OF(X509_NAME) *) + SSL_load_client_CA_file(MODSSL_PCHAR_CAST file); + + if (!sk) { + return; + } + + for (n = 0; n < sk_X509_NAME_num(sk); n++) { + char name_buf[256]; + X509_NAME *name = sk_X509_NAME_value(sk, n); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "CA certificate: %s", + X509_NAME_oneline(name, name_buf, sizeof(name_buf))); + + /* + * note that SSL_load_client_CA_file() checks for duplicates, + * but since we call it multiple times when reading a directory + * we must also check for duplicates ourselves. + */ + + if (sk_X509_NAME_find(ca_list, name) < 0) { + /* this will be freed when ca_list is */ + sk_X509_NAME_push(ca_list, name); + } + else { + /* need to free this ourselves, else it will leak */ + X509_NAME_free(name); + } + } + + sk_X509_NAME_free(sk); +} + +STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, + apr_pool_t *ptemp, + const char *ca_file, + const char *ca_path) +{ + STACK_OF(X509_NAME) *ca_list; + + /* + * Start with a empty stack/list where new + * entries get added in sorted order. + */ + ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); + + /* + * Process CA certificate bundle file + */ + if (ca_file) { + ssl_init_PushCAList(ca_list, s, ca_file); + } + + /* + * Process CA certificate path files + */ + if (ca_path) { + apr_dir_t *dir; + apr_finfo_t direntry; + apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME; + apr_status_t rv; + + if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Failed to open Certificate Path `%s'", + ca_path); + ssl_die(); + } + + while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) { + const char *file; + if (direntry.filetype == APR_DIR) { + continue; /* don't try to load directories */ + } + file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL); + ssl_init_PushCAList(ca_list, s, file); + } + + apr_dir_close(dir); + } + + /* + * Cleanup + */ + sk_X509_NAME_set_cmp_func(ca_list, NULL); + + return ca_list; +} + +void ssl_init_Child(apr_pool_t *p, server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + mc->pid = getpid(); /* only call getpid() once per-process */ + + /* XXX: there should be an ap_srand() function */ + srand((unsigned int)time(NULL)); + + /* open the mutex lockfile */ + ssl_mutex_reinit(s, p); +} + +#define MODSSL_CFG_ITEM_FREE(func, item) \ + if (item) { \ + func(item); \ + item = NULL; \ + } + +static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx) +{ + MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl); + + MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx); +} + +static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx) +{ + ssl_init_ctx_cleanup(mctx); + + if (mctx->pkp->certs) { + sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free); + } +} + +static void ssl_init_ctx_cleanup_server(modssl_ctx_t *mctx) +{ + int i; + + ssl_init_ctx_cleanup(mctx); + + for (i=0; i < SSL_AIDX_MAX; i++) { + MODSSL_CFG_ITEM_FREE(X509_free, + mctx->pks->certs[i]); + + MODSSL_CFG_ITEM_FREE(EVP_PKEY_free, + mctx->pks->keys[i]); + } +} + +apr_status_t ssl_init_ModuleKill(void *data) +{ + SSLSrvConfigRec *sc; + server_rec *base_server = (server_rec *)data; + server_rec *s; + + /* + * Drop the session cache and mutex + */ + ssl_scache_kill(base_server); + + /* + * Destroy the temporary keys and params + */ + ssl_tmp_keys_free(base_server); + + /* + * Free the non-pool allocated structures + * in the per-server configurations + */ + for (s = base_server; s; s = s->next) { + sc = mySrvConfig(s); + + ssl_init_ctx_cleanup_proxy(sc->proxy); + + ssl_init_ctx_cleanup_server(sc->server); + } + + return APR_SUCCESS; +} + diff --git a/trunk/modules/ssl/ssl_engine_io.c b/trunk/modules/ssl/ssl_engine_io.c new file mode 100644 index 0000000000..1699897470 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_io.c @@ -0,0 +1,1608 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_io.c + * I/O Functions + */ + /* ``MY HACK: This universe. + Just one little problem: + core keeps dumping.'' + -- Unknown */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** I/O Hooks +** _________________________________________________________________ +*/ + +/* This file is designed to be the bridge between OpenSSL and httpd. + * However, we really don't expect anyone (let alone ourselves) to + * remember what is in this file. So, first, a quick overview. + * + * In this file, you will find: + * - ssl_io_filter_input (Apache input filter) + * - ssl_io_filter_output (Apache output filter) + * + * - bio_filter_in_* (OpenSSL input filter) + * - bio_filter_out_* (OpenSSL output filter) + * + * The input chain is roughly: + * + * ssl_io_filter_input->ssl_io_input_read->SSL_read->... + * ...->bio_filter_in_read->ap_get_brigade/next-httpd-filter + * + * In mortal terminology, we do the following: + * - Receive a request for data to the SSL input filter + * - Call a helper function once we know we should perform a read + * - Call OpenSSL's SSL_read() + * - SSL_read() will then call bio_filter_in_read + * - bio_filter_in_read will then try to fetch data from the next httpd filter + * - bio_filter_in_read will flatten that data and return it to SSL_read + * - SSL_read will then decrypt the data + * - ssl_io_input_read will then receive decrypted data as a char* and + * ensure that there were no read errors + * - The char* is placed in a brigade and returned + * + * Since connection-level input filters in httpd need to be able to + * handle AP_MODE_GETLINE calls (namely identifying LF-terminated strings), + * ssl_io_input_getline which will handle this special case. + * + * Due to AP_MODE_GETLINE and AP_MODE_SPECULATIVE, we may sometimes have + * 'leftover' decoded data which must be setaside for the next read. That + * is currently handled by the char_buffer_{read|write} functions. So, + * ssl_io_input_read may be able to fulfill reads without invoking + * SSL_read(). + * + * Note that the filter context of ssl_io_filter_input and bio_filter_in_* + * are shared as bio_filter_in_ctx_t. + * + * Note that the filter is by choice limited to reading at most + * AP_IOBUFSIZE (8192 bytes) per call. + * + */ + +/* this custom BIO allows us to hook SSL_write directly into + * an apr_bucket_brigade and use transient buckets with the SSL + * malloc-ed buffer, rather than copying into a mem BIO. + * also allows us to pass the brigade as data is being written + * rather than buffering up the entire response in the mem BIO. + * + * when SSL needs to flush (e.g. SSL_accept()), it will call BIO_flush() + * which will trigger a call to bio_filter_out_ctrl() -> bio_filter_out_flush(). + * so we only need to flush the output ourselves if we receive an + * EOS or FLUSH bucket. this was not possible with the mem BIO where we + * had to flush all over the place not really knowing when it was required + * to do so. + */ + +typedef struct { + SSL *pssl; + BIO *pbioRead; + BIO *pbioWrite; + ap_filter_t *pInputFilter; + ap_filter_t *pOutputFilter; + int nobuffer; /* non-zero to prevent buffering */ +} ssl_filter_ctx_t; + +typedef struct { + ssl_filter_ctx_t *filter_ctx; + conn_rec *c; + apr_bucket_brigade *bb; + apr_size_t length; + char buffer[AP_IOBUFSIZE]; + apr_size_t blen; + apr_status_t rc; +} bio_filter_out_ctx_t; + +static bio_filter_out_ctx_t *bio_filter_out_ctx_new(ssl_filter_ctx_t *filter_ctx, + conn_rec *c) +{ + bio_filter_out_ctx_t *outctx = apr_palloc(c->pool, sizeof(*outctx)); + + outctx->filter_ctx = filter_ctx; + outctx->c = c; + outctx->bb = apr_brigade_create(c->pool, c->bucket_alloc); + outctx->blen = 0; + outctx->length = 0; + + return outctx; +} + +static int bio_filter_out_flush(BIO *bio) +{ + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + apr_bucket *e; + + if (!(outctx->blen || outctx->length)) { + outctx->rc = APR_SUCCESS; + return 1; + } + + if (outctx->blen) { + e = apr_bucket_transient_create(outctx->buffer, outctx->blen, + outctx->bb->bucket_alloc); + /* we filled this buffer first so add it to the + * head of the brigade + */ + APR_BRIGADE_INSERT_HEAD(outctx->bb, e); + outctx->blen = 0; + } + + outctx->length = 0; + e = apr_bucket_flush_create(outctx->bb->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(outctx->bb, e); + + outctx->rc = ap_pass_brigade(outctx->filter_ctx->pOutputFilter->next, + outctx->bb); + /* Fail if the connection was reset: */ + if (outctx->rc == APR_SUCCESS && outctx->c->aborted) { + outctx->rc = APR_ECONNRESET; + } + return (outctx->rc == APR_SUCCESS) ? 1 : -1; +} + +static int bio_filter_create(BIO *bio) +{ + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + bio->ptr = NULL; + + return 1; +} + +static int bio_filter_destroy(BIO *bio) +{ + if (bio == NULL) { + return 0; + } + + /* nothing to free here. + * apache will destroy the bucket brigade for us + */ + return 1; +} + +static int bio_filter_out_read(BIO *bio, char *out, int outl) +{ + /* this is never called */ + return -1; +} + +static int bio_filter_out_write(BIO *bio, const char *in, int inl) +{ + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + + /* when handshaking we'll have a small number of bytes. + * max size SSL will pass us here is about 16k. + * (16413 bytes to be exact) + */ + BIO_clear_retry_flags(bio); + + if (!outctx->length && (inl + outctx->blen < sizeof(outctx->buffer)) && + !outctx->filter_ctx->nobuffer) { + /* the first two SSL_writes (of 1024 and 261 bytes) + * need to be in the same packet (vec[0].iov_base) + */ + /* XXX: could use apr_brigade_write() to make code look cleaner + * but this way we avoid the malloc(APR_BUCKET_BUFF_SIZE) + * and free() of it later + */ + memcpy(&outctx->buffer[outctx->blen], in, inl); + outctx->blen += inl; + } + else { + /* pass along the encrypted data + * need to flush since we're using SSL's malloc-ed buffer + * which will be overwritten once we leave here + */ + apr_bucket *bucket = apr_bucket_transient_create(in, inl, + outctx->bb->bucket_alloc); + + outctx->length += inl; + APR_BRIGADE_INSERT_TAIL(outctx->bb, bucket); + + if (bio_filter_out_flush(bio) < 0) { + return -1; + } + } + + return inl; +} + +static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + char **pptr; + + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + + switch (cmd) { + case BIO_CTRL_RESET: + outctx->blen = outctx->length = 0; + break; + case BIO_CTRL_EOF: + ret = (long)((outctx->blen + outctx->length) == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + outctx->blen = outctx->length = (apr_size_t)num; + break; + case BIO_CTRL_INFO: + ret = (long)(outctx->blen + outctx->length); + if (ptr) { + pptr = (char **)ptr; + *pptr = (char *)&(outctx->buffer[0]); + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)(outctx->blen + outctx->length); + break; + case BIO_CTRL_FLUSH: + ret = bio_filter_out_flush(bio); + break; + case BIO_CTRL_DUP: + ret = 1; + break; + /* N/A */ + case BIO_C_SET_BUF_MEM: + case BIO_C_GET_BUF_MEM_PTR: + /* we don't care */ + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + + return ret; +} + +static int bio_filter_out_gets(BIO *bio, char *buf, int size) +{ + /* this is never called */ + return -1; +} + +static int bio_filter_out_puts(BIO *bio, const char *str) +{ + /* this is never called */ + return -1; +} + +static BIO_METHOD bio_filter_out_method = { + BIO_TYPE_MEM, + "APR output filter", + bio_filter_out_write, + bio_filter_out_read, /* read is never called */ + bio_filter_out_puts, /* puts is never called */ + bio_filter_out_gets, /* gets is never called */ + bio_filter_out_ctrl, + bio_filter_create, + bio_filter_destroy, +#ifdef OPENSSL_VERSION_NUMBER + NULL /* sslc does not have the callback_ctrl field */ +#endif +}; + +typedef struct { + int length; + char *value; +} char_buffer_t; + +typedef struct { + SSL *ssl; + BIO *bio_out; + ap_filter_t *f; + apr_status_t rc; + ap_input_mode_t mode; + apr_read_type_e block; + apr_bucket_brigade *bb; + char_buffer_t cbuf; + apr_pool_t *pool; + char buffer[AP_IOBUFSIZE]; + ssl_filter_ctx_t *filter_ctx; +} bio_filter_in_ctx_t; + +/* + * this char_buffer api might seem silly, but we don't need to copy + * any of this data and we need to remember the length. + */ +static int char_buffer_read(char_buffer_t *buffer, char *in, int inl) +{ + if (!buffer->length) { + return 0; + } + + if (buffer->length > inl) { + /* we have have enough to fill the caller's buffer */ + memcpy(in, buffer->value, inl); + buffer->value += inl; + buffer->length -= inl; + } + else { + /* swallow remainder of the buffer */ + memcpy(in, buffer->value, buffer->length); + inl = buffer->length; + buffer->value = NULL; + buffer->length = 0; + } + + return inl; +} + +static int char_buffer_write(char_buffer_t *buffer, char *in, int inl) +{ + buffer->value = in; + buffer->length = inl; + return inl; +} + +/* This function will read from a brigade and discard the read buckets as it + * proceeds. It will read at most *len bytes. + */ +static apr_status_t brigade_consume(apr_bucket_brigade *bb, + apr_read_type_e block, + char *c, apr_size_t *len) +{ + apr_size_t actual = 0; + apr_status_t status = APR_SUCCESS; + + while (!APR_BRIGADE_EMPTY(bb)) { + apr_bucket *b = APR_BRIGADE_FIRST(bb); + const char *str; + apr_size_t str_len; + apr_size_t consume; + + /* Justin points out this is an http-ism that might + * not fit if brigade_consume is added to APR. Perhaps + * apr_bucket_read(eos_bucket) should return APR_EOF? + * Then this becomes mainline instead of a one-off. + */ + if (APR_BUCKET_IS_EOS(b)) { + status = APR_EOF; + break; + } + + /* The reason I'm not offering brigade_consume yet + * across to apr-util is that the following call + * illustrates how borked that API really is. For + * this sort of case (caller provided buffer) it + * would be much more trivial for apr_bucket_consume + * to do all the work that follows, based on the + * particular characteristics of the bucket we are + * consuming here. + */ + status = apr_bucket_read(b, &str, &str_len, block); + + if (status != APR_SUCCESS) { + if (APR_STATUS_IS_EOF(status)) { + /* This stream bucket was consumed */ + apr_bucket_delete(b); + continue; + } + break; + } + + if (str_len > 0) { + /* Do not block once some data has been consumed */ + block = APR_NONBLOCK_READ; + + /* Assure we don't overflow. */ + consume = (str_len + actual > *len) ? *len - actual : str_len; + + memcpy(c, str, consume); + + c += consume; + actual += consume; + + if (consume >= b->length) { + /* This physical bucket was consumed */ + apr_bucket_delete(b); + } + else { + /* Only part of this physical bucket was consumed */ + b->start += consume; + b->length -= consume; + } + } + else if (b->length == 0) { + apr_bucket_delete(b); + } + + /* This could probably be actual == *len, but be safe from stray + * photons. */ + if (actual >= *len) { + break; + } + } + + *len = actual; + return status; +} + +/* + * this is the function called by SSL_read() + */ +static int bio_filter_in_read(BIO *bio, char *in, int inlen) +{ + apr_size_t inl = inlen; + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *)(bio->ptr); + apr_read_type_e block = inctx->block; + SSLConnRec *sslconn = myConnConfig(inctx->f->c); + + inctx->rc = APR_SUCCESS; + + /* OpenSSL catches this case, so should we. */ + if (!in) + return 0; + + /* XXX: flush here only required for SSLv2; + * OpenSSL calls BIO_flush() at the appropriate times for + * the other protocols. + */ + if ((SSL_version(inctx->ssl) == SSL2_VERSION) || sslconn->is_proxy) { + if (bio_filter_out_flush(inctx->bio_out) < 0) { + bio_filter_out_ctx_t *outctx = + (bio_filter_out_ctx_t *)(inctx->bio_out->ptr); + inctx->rc = outctx->rc; + return -1; + } + } + + BIO_clear_retry_flags(bio); + + if (!inctx->bb) { + inctx->rc = APR_EOF; + return -1; + } + + if (APR_BRIGADE_EMPTY(inctx->bb)) { + + inctx->rc = ap_get_brigade(inctx->f->next, inctx->bb, + AP_MODE_READBYTES, block, + inl); + + /* If the read returns EAGAIN or success with an empty + * brigade, return an error after setting the retry flag; + * SSL_read() will then return -1, and SSL_get_error() will + * indicate SSL_ERROR_WANT_READ. */ + if (APR_STATUS_IS_EAGAIN(inctx->rc) || APR_STATUS_IS_EINTR(inctx->rc) + || (inctx->rc == APR_SUCCESS && APR_BRIGADE_EMPTY(inctx->bb))) { + BIO_set_retry_read(bio); + return -1; + } + + if (inctx->rc != APR_SUCCESS) { + /* Unexpected errors discard the brigade */ + apr_brigade_cleanup(inctx->bb); + inctx->bb = NULL; + return -1; + } + } + + inctx->rc = brigade_consume(inctx->bb, block, in, &inl); + + if (inctx->rc == APR_SUCCESS) { + return (int)inl; + } + + if (APR_STATUS_IS_EAGAIN(inctx->rc) + || APR_STATUS_IS_EINTR(inctx->rc)) { + BIO_set_retry_read(bio); + return (int)inl; + } + + /* Unexpected errors and APR_EOF clean out the brigade. + * Subsequent calls will return APR_EOF. + */ + apr_brigade_cleanup(inctx->bb); + inctx->bb = NULL; + + if (APR_STATUS_IS_EOF(inctx->rc) && inl) { + /* Provide the results of this read pass, + * without resetting the BIO retry_read flag + */ + return (int)inl; + } + + return -1; +} + + +static BIO_METHOD bio_filter_in_method = { + BIO_TYPE_MEM, + "APR input filter", + NULL, /* write is never called */ + bio_filter_in_read, + NULL, /* puts is never called */ + NULL, /* gets is never called */ + NULL, /* ctrl is never called */ + bio_filter_create, + bio_filter_destroy, +#ifdef OPENSSL_VERSION_NUMBER + NULL /* sslc does not have the callback_ctrl field */ +#endif +}; + + +static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx, + char *buf, + apr_size_t *len) +{ + apr_size_t wanted = *len; + apr_size_t bytes = 0; + int rc; + + *len = 0; + + /* If we have something leftover from last time, try that first. */ + if ((bytes = char_buffer_read(&inctx->cbuf, buf, wanted))) { + *len = bytes; + if (inctx->mode == AP_MODE_SPECULATIVE) { + /* We want to rollback this read. */ + if (inctx->cbuf.length > 0) { + inctx->cbuf.value -= bytes; + inctx->cbuf.length += bytes; + } else { + char_buffer_write(&inctx->cbuf, buf, (int)bytes); + } + return APR_SUCCESS; + } + /* This could probably be *len == wanted, but be safe from stray + * photons. + */ + if (*len >= wanted) { + return APR_SUCCESS; + } + if (inctx->mode == AP_MODE_GETLINE) { + if (memchr(buf, APR_ASCII_LF, *len)) { + return APR_SUCCESS; + } + } + else { + /* Down to a nonblock pattern as we have some data already + */ + inctx->block = APR_NONBLOCK_READ; + } + } + + while (1) { + + if (!inctx->filter_ctx->pssl) { + /* Ensure a non-zero error code is returned */ + if (inctx->rc == APR_SUCCESS) { + inctx->rc = APR_EGENERAL; + } + break; + } + + /* SSL_read may not read because we haven't taken enough data + * from the stack. This is where we want to consider all of + * the blocking and SPECULATIVE semantics + */ + rc = SSL_read(inctx->filter_ctx->pssl, buf + bytes, wanted - bytes); + + if (rc > 0) { + *len += rc; + if (inctx->mode == AP_MODE_SPECULATIVE) { + /* We want to rollback this read. */ + char_buffer_write(&inctx->cbuf, buf, rc); + } + return inctx->rc; + } + else if (rc == 0) { + /* If EAGAIN, we will loop given a blocking read, + * otherwise consider ourselves at EOF. + */ + if (APR_STATUS_IS_EAGAIN(inctx->rc) + || APR_STATUS_IS_EINTR(inctx->rc)) { + /* Already read something, return APR_SUCCESS instead. + * On win32 in particular, but perhaps on other kernels, + * a blocking call isn't 'always' blocking. + */ + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } + } + else { + if (*len > 0) { + inctx->rc = APR_SUCCESS; + } + else { + inctx->rc = APR_EOF; + } + break; + } + } + else /* (rc < 0) */ { + int ssl_err = SSL_get_error(inctx->filter_ctx->pssl, rc); + conn_rec *c = (conn_rec*)SSL_get_app_data(inctx->filter_ctx->pssl); + + if (ssl_err == SSL_ERROR_WANT_READ) { + /* + * If OpenSSL wants to read more, and we were nonblocking, + * report as an EAGAIN. Otherwise loop, pulling more + * data from network filter. + * + * (This is usually the case when the client forces an SSL + * renegotation which is handled implicitly by OpenSSL.) + */ + inctx->rc = APR_EAGAIN; + + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } + continue; /* Blocking and nothing yet? Try again. */ + } + else if (ssl_err == SSL_ERROR_SYSCALL) { + if (APR_STATUS_IS_EAGAIN(inctx->rc) + || APR_STATUS_IS_EINTR(inctx->rc)) { + /* Already read something, return APR_SUCCESS instead. */ + if (*len > 0) { + inctx->rc = APR_SUCCESS; + break; + } + if (inctx->block == APR_NONBLOCK_READ) { + break; + } + continue; /* Blocking and nothing yet? Try again. */ + } + else { + ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, + "SSL input filter read failed."); + } + } + else /* if (ssl_err == SSL_ERROR_SSL) */ { + /* + * Log SSL errors and any unexpected conditions. + */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, + "SSL library error %d reading data", ssl_err); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + + } + if (inctx->rc == APR_SUCCESS) { + inctx->rc = APR_EGENERAL; + } + break; + } + } + return inctx->rc; +} + +static apr_status_t ssl_io_input_getline(bio_filter_in_ctx_t *inctx, + char *buf, + apr_size_t *len) +{ + const char *pos = NULL; + apr_status_t status; + apr_size_t tmplen = *len, buflen = *len, offset = 0; + + *len = 0; + + /* + * in most cases we get all the headers on the first SSL_read. + * however, in certain cases SSL_read will only get a partial + * chunk of the headers, so we try to read until LF is seen. + */ + + while (tmplen > 0) { + status = ssl_io_input_read(inctx, buf + offset, &tmplen); + + if (status != APR_SUCCESS) { + return status; + } + + *len += tmplen; + + if ((pos = memchr(buf, APR_ASCII_LF, *len))) { + break; + } + + offset += tmplen; + tmplen = buflen - offset; + } + + if (pos) { + char *value; + int length; + apr_size_t bytes = pos - buf; + + bytes += 1; + value = buf + bytes; + length = *len - bytes; + + char_buffer_write(&inctx->cbuf, value, length); + + *len = bytes; + } + + return APR_SUCCESS; +} + + +static apr_status_t ssl_filter_write(ap_filter_t *f, + const char *data, + apr_size_t len) +{ + ssl_filter_ctx_t *filter_ctx = f->ctx; + bio_filter_out_ctx_t *outctx; + int res; + + /* write SSL */ + if (filter_ctx->pssl == NULL) { + return APR_EGENERAL; + } + + outctx = (bio_filter_out_ctx_t *)filter_ctx->pbioWrite->ptr; + res = SSL_write(filter_ctx->pssl, (unsigned char *)data, len); + + if (res < 0) { + int ssl_err = SSL_get_error(filter_ctx->pssl, res); + conn_rec *c = (conn_rec*)SSL_get_app_data(outctx->filter_ctx->pssl); + + if (ssl_err == SSL_ERROR_WANT_WRITE) { + /* + * If OpenSSL wants to write more, and we were nonblocking, + * report as an EAGAIN. Otherwise loop, pushing more + * data at the network filter. + * + * (This is usually the case when the client forces an SSL + * renegotation which is handled implicitly by OpenSSL.) + */ + outctx->rc = APR_EAGAIN; + } + else if (ssl_err == SSL_ERROR_SYSCALL) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, + "SSL output filter write failed."); + } + else /* if (ssl_err == SSL_ERROR_SSL) */ { + /* + * Log SSL errors + */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, + "SSL library error %d writing data", ssl_err); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + } + if (outctx->rc == APR_SUCCESS) { + outctx->rc = APR_EGENERAL; + } + } + else if ((apr_size_t)res != len) { + conn_rec *c = f->c; + char *reason = "reason unknown"; + + /* XXX: probably a better way to determine this */ + if (SSL_total_renegotiations(filter_ctx->pssl)) { + reason = "likely due to failed renegotiation"; + } + + ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, + "failed to write %" APR_SSIZE_T_FMT + " of %" APR_SIZE_T_FMT " bytes (%s)", + len - (apr_size_t)res, len, reason); + + outctx->rc = APR_EGENERAL; + } + return outctx->rc; +} + +/* Just use a simple request. Any request will work for this, because + * we use a flag in the conn_rec->conn_vector now. The fake request just + * gets the request back to the Apache core so that a response can be sent. + * + * To avoid calling back for more data from the socket, use an HTTP/0.9 + * request, and tack on an EOS bucket. + */ +#define HTTP_ON_HTTPS_PORT \ + "GET /" CRLF + +#define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \ + apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \ + sizeof(HTTP_ON_HTTPS_PORT) - 1, \ + alloc) + +static void ssl_io_filter_disable(SSLConnRec *sslconn, ap_filter_t *f) +{ + bio_filter_in_ctx_t *inctx = f->ctx; + SSL_free(inctx->ssl); + sslconn->ssl = NULL; + inctx->ssl = NULL; + inctx->filter_ctx->pssl = NULL; +} + +static apr_status_t ssl_io_filter_error(ap_filter_t *f, + apr_bucket_brigade *bb, + apr_status_t status) +{ + SSLConnRec *sslconn = myConnConfig(f->c); + apr_bucket *bucket; + + switch (status) { + case HTTP_BAD_REQUEST: + /* log the situation */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, + "SSL handshake failed: HTTP spoken on HTTPS port; " + "trying to send HTML error page"); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, f->c->base_server); + + sslconn->non_ssl_request = 1; + ssl_io_filter_disable(sslconn, f); + + /* fake the request line */ + bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); + break; + + default: + return status; + } + + APR_BRIGADE_INSERT_TAIL(bb, bucket); + bucket = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + + return APR_SUCCESS; +} + +static const char ssl_io_filter[] = "SSL/TLS Filter"; + +/* + * Close the SSL part of the socket connection + * (called immediately _before_ the socket is closed) + * or called with + */ +static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx, + conn_rec *c, + int abortive) +{ + SSL *ssl = filter_ctx->pssl; + const char *type = ""; + SSLConnRec *sslconn = myConnConfig(c); + int shutdown_type; + + if (!ssl) { + return APR_SUCCESS; + } + + /* + * Now close the SSL layer of the connection. We've to take + * the TLSv1 standard into account here: + * + * | 7.2.1. Closure alerts + * | + * | The client and the server must share knowledge that the connection is + * | ending in order to avoid a truncation attack. Either party may + * | initiate the exchange of closing messages. + * | + * | close_notify + * | This message notifies the recipient that the sender will not send + * | any more messages on this connection. The session becomes + * | unresumable if any connection is terminated without proper + * | close_notify messages with level equal to warning. + * | + * | Either party may initiate a close by sending a close_notify alert. + * | Any data received after a closure alert is ignored. + * | + * | Each party is required to send a close_notify alert before closing + * | the write side of the connection. It is required that the other party + * | respond with a close_notify alert of its own and close down the + * | connection immediately, discarding any pending writes. It is not + * | required for the initiator of the close to wait for the responding + * | close_notify alert before closing the read side of the connection. + * + * This means we've to send a close notify message, but haven't to wait + * for the close notify of the client. Actually we cannot wait for the + * close notify of the client because some clients (including Netscape + * 4.x) don't send one, so we would hang. + */ + + /* + * exchange close notify messages, but allow the user + * to force the type of handshake via SetEnvIf directive + */ + if (abortive) { + shutdown_type = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN; + type = "abortive"; + } + else switch (sslconn->shutdown_type) { + case SSL_SHUTDOWN_TYPE_UNCLEAN: + /* perform no close notify handshake at all + (violates the SSL/TLS standard!) */ + shutdown_type = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN; + type = "unclean"; + break; + case SSL_SHUTDOWN_TYPE_ACCURATE: + /* send close notify and wait for clients close notify + (standard compliant, but usually causes connection hangs) */ + shutdown_type = 0; + type = "accurate"; + break; + default: + /* + * case SSL_SHUTDOWN_TYPE_UNSET: + * case SSL_SHUTDOWN_TYPE_STANDARD: + */ + /* send close notify, but don't wait for clients close notify + (standard compliant and safe, so it's the DEFAULT!) */ + shutdown_type = SSL_RECEIVED_SHUTDOWN; + type = "standard"; + break; + } + + SSL_set_shutdown(ssl, shutdown_type); + SSL_smart_shutdown(ssl); + + /* and finally log the fact that we've closed the connection */ + if (c->base_server->loglevel >= APLOG_INFO) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "Connection closed to child %ld with %s shutdown " + "(server %s)", + c->id, type, ssl_util_vhostid(c->pool, c->base_server)); + } + + /* deallocate the SSL connection */ + if (sslconn->client_cert) { + X509_free(sslconn->client_cert); + sslconn->client_cert = NULL; + } + SSL_free(ssl); + sslconn->ssl = NULL; + filter_ctx->pssl = NULL; /* so filters know we've been shutdown */ + + if (abortive) { + /* prevent any further I/O */ + c->aborted = 1; + } + + return APR_SUCCESS; +} + +static apr_status_t ssl_io_filter_cleanup(void *data) +{ + ssl_filter_ctx_t *filter_ctx = data; + + if (filter_ctx->pssl) { + conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl); + SSLConnRec *sslconn = myConnConfig(c); + + SSL_free(filter_ctx->pssl); + sslconn->ssl = filter_ctx->pssl = NULL; + } + + return APR_SUCCESS; +} + +/* + * The hook is NOT registered with ap_hook_process_connection. Instead, it is + * called manually from the churn () before it tries to read any data. + * There is some problem if I accept conn_rec *. Still investigating.. + * Adv. if conn_rec * can be accepted is we can hook this function using the + * ap_hook_process_connection hook. + */ +static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx) +{ + conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl); + SSLConnRec *sslconn = myConnConfig(c); + SSLSrvConfigRec *sc = mySrvConfig(c->base_server); + X509 *cert; + int n; + int ssl_err; + long verify_result; + + if (SSL_is_init_finished(filter_ctx->pssl)) { + return APR_SUCCESS; + } + + if (sslconn->is_proxy) { + if ((n = SSL_connect(filter_ctx->pssl)) <= 0) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "SSL Proxy connect failed"); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + /* ensure that the SSL structures etc are freed, etc: */ + ssl_filter_io_shutdown(filter_ctx, c, 1); + return HTTP_BAD_GATEWAY; + } + + return APR_SUCCESS; + } + + if ((n = SSL_accept(filter_ctx->pssl)) <= 0) { + bio_filter_in_ctx_t *inctx = (bio_filter_in_ctx_t *) + (filter_ctx->pbioRead->ptr); + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *) + (filter_ctx->pbioWrite->ptr); + apr_status_t rc = inctx->rc ? inctx->rc : outctx->rc ; + ssl_err = SSL_get_error(filter_ctx->pssl, n); + + if (ssl_err == SSL_ERROR_ZERO_RETURN) { + /* + * The case where the connection was closed before any data + * was transferred. That's not a real error and can occur + * sporadically with some clients. + */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, + "SSL handshake stopped: connection was closed"); + } + else if (ssl_err == SSL_ERROR_WANT_READ) { + /* + * This is in addition to what was present earlier. It is + * borrowed from openssl_state_machine.c [mod_tls]. + * TBD. + */ + outctx->rc = APR_EAGAIN; + return SSL_ERROR_WANT_READ; + } + else if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL && + ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { + /* + * The case where OpenSSL has recognized a HTTP request: + * This means the client speaks plain HTTP on our HTTPS port. + * ssl_io_filter_error will disable the ssl filters when it + * sees this status code. + */ + return HTTP_BAD_REQUEST; + } + else if (ssl_err == SSL_ERROR_SYSCALL) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, + "SSL handshake interrupted by system " + "[Hint: Stop button pressed in browser?!]"); + } + else /* if (ssl_err == SSL_ERROR_SSL) */ { + /* + * Log SSL errors and any unexpected conditions. + */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, + "SSL library error %d in handshake " + "(server %s)", ssl_err, + ssl_util_vhostid(c->pool, c->base_server)); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + + } + if (inctx->rc == APR_SUCCESS) { + inctx->rc = APR_EGENERAL; + } + + return ssl_filter_io_shutdown(filter_ctx, c, 1); + } + + /* + * Check for failed client authentication + */ + verify_result = SSL_get_verify_result(filter_ctx->pssl); + + if ((verify_result != X509_V_OK) || + sslconn->verify_error) + { + if (ssl_verify_error_is_optional(verify_result) && + (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) + { + /* leaving this log message as an error for the moment, + * according to the mod_ssl docs: + * "level optional_no_ca is actually against the idea + * of authentication (but can be used to establish + * SSL test pages, etc.)" + * optional_no_ca doesn't appear to work as advertised + * in 1.x + */ + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "SSL client authentication failed, " + "accepting certificate based on " + "\"SSLVerifyClient optional_no_ca\" " + "configuration"); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + } + else { + const char *error = sslconn->verify_error ? + sslconn->verify_error : + X509_verify_cert_error_string(verify_result); + + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "SSL client authentication failed: %s", + error ? error : "unknown"); + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); + + return ssl_filter_io_shutdown(filter_ctx, c, 1); + } + } + + /* + * Remember the peer certificate's DN + */ + if ((cert = SSL_get_peer_certificate(filter_ctx->pssl))) { + if (sslconn->client_cert) { + X509_free(sslconn->client_cert); + } + sslconn->client_cert = cert; + sslconn->client_dn = NULL; + } + + /* + * Make really sure that when a peer certificate + * is required we really got one... (be paranoid) + */ + if ((sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE) && + !sslconn->client_cert) + { + ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, + "No acceptable peer certificate available"); + + return ssl_filter_io_shutdown(filter_ctx, c, 1); + } + + return APR_SUCCESS; +} + +#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols" +#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1" +#define CONNECTION_HEADER "Connection: Upgrade" + +static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + const char *upgrade; + apr_bucket_brigade *upgradebb; + request_rec *r = f->r; + SSLConnRec *sslconn; + apr_status_t rv; + apr_bucket *b; + SSL *ssl; + + /* Just remove the filter, if it doesn't work the first time, it won't + * work at all for this request. + */ + ap_remove_output_filter(f); + + /* No need to ensure that this is a server with optional SSL, the filter + * is only inserted if that is true. + */ + + upgrade = apr_table_get(r->headers_in, "Upgrade"); + if (upgrade == NULL + || strcmp(ap_getword(r->pool, &upgrade, ','), "TLS/1.0")) { + /* "Upgrade: TLS/1.0, ..." header not found, don't do Upgrade */ + return ap_pass_brigade(f->next, bb); + } + + apr_table_unset(r->headers_out, "Upgrade"); + + /* Send the interim 101 response. */ + upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc); + + ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF, + UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL); + + b = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(upgradebb, b); + + rv = ap_pass_brigade(f->next, upgradebb); + if (rv) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "could not send interim 101 Upgrade response"); + return AP_FILTER_ERROR; + } + + ssl_init_ssl_connection(f->c); + + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "Awaiting re-negotiation handshake"); + + sslconn = myConnConfig(f->c); + ssl = sslconn->ssl; + + /* XXX: Should replace SSL_set_state with SSL_renegotiate(ssl); + * However, this causes failures in perl-framework currently, + * perhaps pre-test if we have already negotiated? + */ + SSL_set_accept_state(ssl); + SSL_do_handshake(ssl); + + if (SSL_get_state(ssl) != SSL_ST_OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "TLS Upgrade handshake failed: " + "Not accepted by client!?"); + + return AP_FILTER_ERROR; + } + + /* Now that we have initialized the ssl connection which added the ssl_io_filter, + pass the brigade off to the connection based output filters so that the + request can complete encrypted */ + return ap_pass_brigade(f->c->output_filters, bb); + +} + +static apr_status_t ssl_io_filter_input(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + apr_status_t status; + bio_filter_in_ctx_t *inctx = f->ctx; + + apr_size_t len = sizeof(inctx->buffer); + int is_init = (mode == AP_MODE_INIT); + + if (f->c->aborted) { + /* XXX: Ok, if we aborted, we ARE at the EOS. We also have + * aborted. This 'double protection' is probably redundant, + * but also effective against just about anything. + */ + apr_bucket *bucket = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + return APR_ECONNABORTED; + } + + if (!inctx->ssl) { + return ap_get_brigade(f->next, bb, mode, block, readbytes); + } + + /* XXX: we don't currently support anything other than these modes. */ + if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE && + mode != AP_MODE_SPECULATIVE && mode != AP_MODE_INIT) { + return APR_ENOTIMPL; + } + + inctx->mode = mode; + inctx->block = block; + + /* XXX: we could actually move ssl_io_filter_connect to an + * ap_hook_process_connection but would still need to call it for + * AP_MODE_INIT for protocols that may upgrade the connection + * rather than have SSLEngine On configured. + */ + if ((status = ssl_io_filter_connect(inctx->filter_ctx)) != APR_SUCCESS) { + return ssl_io_filter_error(f, bb, status); + } + + if (is_init) { + /* protocol module needs to handshake before sending + * data to client (e.g. NNTP or FTP) + */ + return APR_SUCCESS; + } + + if (inctx->mode == AP_MODE_READBYTES || + inctx->mode == AP_MODE_SPECULATIVE) { + /* Protected from truncation, readbytes < MAX_SIZE_T + * FIXME: No, it's *not* protected. -- jre */ + if (readbytes < len) { + len = (apr_size_t)readbytes; + } + status = ssl_io_input_read(inctx, inctx->buffer, &len); + } + else if (inctx->mode == AP_MODE_GETLINE) { + status = ssl_io_input_getline(inctx, inctx->buffer, &len); + } + else { + /* We have no idea what you are talking about, so return an error. */ + return APR_ENOTIMPL; + } + + if (status != APR_SUCCESS) { + return ssl_io_filter_error(f, bb, status); + } + + /* Create a transient bucket out of the decrypted data. */ + if (len > 0) { + apr_bucket *bucket = + apr_bucket_transient_create(inctx->buffer, len, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + } + + return APR_SUCCESS; +} + +static apr_status_t ssl_io_filter_output(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + apr_status_t status = APR_SUCCESS; + ssl_filter_ctx_t *filter_ctx = f->ctx; + bio_filter_in_ctx_t *inctx; + bio_filter_out_ctx_t *outctx; + apr_read_type_e rblock = APR_NONBLOCK_READ; + + if (f->c->aborted) { + apr_brigade_cleanup(bb); + return APR_ECONNABORTED; + } + + if (!filter_ctx->pssl) { + /* ssl_filter_io_shutdown was called */ + return ap_pass_brigade(f->next, bb); + } + + inctx = (bio_filter_in_ctx_t *)filter_ctx->pbioRead->ptr; + outctx = (bio_filter_out_ctx_t *)filter_ctx->pbioWrite->ptr; + + /* When we are the writer, we must initialize the inctx + * mode so that we block for any required ssl input, because + * output filtering is always nonblocking. + */ + inctx->mode = AP_MODE_READBYTES; + inctx->block = APR_BLOCK_READ; + + if ((status = ssl_io_filter_connect(filter_ctx)) != APR_SUCCESS) { + return ssl_io_filter_error(f, bb, status); + } + + while (!APR_BRIGADE_EMPTY(bb)) { + apr_bucket *bucket = APR_BRIGADE_FIRST(bb); + + /* If it is a flush or EOS, we need to pass this down. + * These types do not require translation by OpenSSL. + */ + if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) { + if (bio_filter_out_flush(filter_ctx->pbioWrite) < 0) { + status = outctx->rc; + break; + } + + if (APR_BUCKET_IS_EOS(bucket)) { + /* + * By definition, nothing can come after EOS. + * which also means we can pass the rest of this brigade + * without creating a new one since it only contains the + * EOS bucket. + */ + + if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { + return status; + } + break; + } + else { + /* bio_filter_out_flush() already passed down a flush bucket + * if there was any data to be flushed. + */ + apr_bucket_delete(bucket); + } + } + else if (AP_BUCKET_IS_EOC(bucket)) { + /* The special "EOC" bucket means a shutdown is needed; + * - turn off buffering in bio_filter_out_write + * - issue the SSL_shutdown + */ + filter_ctx->nobuffer = 1; + status = ssl_filter_io_shutdown(filter_ctx, f->c, 0); + if (status != APR_SUCCESS) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, status, f->c, + "SSL filter error shutting down I/O"); + } + if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { + return status; + } + break; + } + else { + /* filter output */ + const char *data; + apr_size_t len; + + status = apr_bucket_read(bucket, &data, &len, rblock); + + if (APR_STATUS_IS_EAGAIN(status)) { + /* No data available: flush... */ + if (bio_filter_out_flush(filter_ctx->pbioWrite) < 0) { + status = outctx->rc; + break; + } + rblock = APR_BLOCK_READ; + continue; /* and try again with a blocking read. */ + } + + rblock = APR_NONBLOCK_READ; + + if (!APR_STATUS_IS_EOF(status) && (status != APR_SUCCESS)) { + break; + } + + status = ssl_filter_write(f, data, len); + apr_bucket_delete(bucket); + + if (status != APR_SUCCESS) { + break; + } + } + } + + return status; +} + +static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c, + SSL *ssl) +{ + bio_filter_in_ctx_t *inctx; + + inctx = apr_palloc(c->pool, sizeof(*inctx)); + + filter_ctx->pInputFilter = ap_add_input_filter(ssl_io_filter, inctx, NULL, c); + + filter_ctx->pbioRead = BIO_new(&bio_filter_in_method); + filter_ctx->pbioRead->ptr = (void *)inctx; + + inctx->ssl = ssl; + inctx->bio_out = filter_ctx->pbioWrite; + inctx->f = filter_ctx->pInputFilter; + inctx->rc = APR_SUCCESS; + inctx->mode = AP_MODE_READBYTES; + inctx->cbuf.length = 0; + inctx->bb = apr_brigade_create(c->pool, c->bucket_alloc); + inctx->block = APR_BLOCK_READ; + inctx->pool = c->pool; + inctx->filter_ctx = filter_ctx; +} + +void ssl_io_filter_init(conn_rec *c, SSL *ssl) +{ + ssl_filter_ctx_t *filter_ctx; + + filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t)); + + filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, + filter_ctx, NULL, c); + + filter_ctx->pbioWrite = BIO_new(&bio_filter_out_method); + filter_ctx->pbioWrite->ptr = (void *)bio_filter_out_ctx_new(filter_ctx, c); + + ssl_io_input_add_filter(filter_ctx, c, ssl); + + SSL_set_bio(ssl, filter_ctx->pbioRead, filter_ctx->pbioWrite); + filter_ctx->pssl = ssl; + + apr_pool_cleanup_register(c->pool, (void*)filter_ctx, + ssl_io_filter_cleanup, apr_pool_cleanup_null); + + if (c->base_server->loglevel >= APLOG_DEBUG) { + BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb); + BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl); + } + + return; +} + +void ssl_io_filter_register(apr_pool_t *p) +{ + /* This filter MUST be after the HTTP_HEADER filter, but it also must be + * a resource-level filter so it has the request_rec. + */ + ap_register_output_filter ("UPGRADE_FILTER", ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); + + ap_register_input_filter (ssl_io_filter, ssl_io_filter_input, NULL, AP_FTYPE_CONNECTION + 5); + ap_register_output_filter (ssl_io_filter, ssl_io_filter_output, NULL, AP_FTYPE_CONNECTION + 5); + return; +} + +/* _________________________________________________________________ +** +** I/O Data Debugging +** _________________________________________________________________ +*/ + +#define DUMP_WIDTH 16 + +static void ssl_io_data_dump(server_rec *srvr, + MODSSL_BIO_CB_ARG_TYPE *s, + long len) +{ + char buf[256]; + char tmp[64]; + int i, j, rows, trunc; + unsigned char ch; + + trunc = 0; + for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--) + trunc++; + rows = (len / DUMP_WIDTH); + if ((rows * DUMP_WIDTH) < len) + rows++; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr, + "+-------------------------------------------------------------------------+"); + for(i = 0 ; i< rows; i++) { + apr_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH); + apr_cpystrn(buf, tmp, sizeof(buf)); + for (j = 0; j < DUMP_WIDTH; j++) { + if (((i * DUMP_WIDTH) + j) >= len) + apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); + else { + ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff; + apr_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' '); + apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf)); + } + } + apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); + for (j = 0; j < DUMP_WIDTH; j++) { + if (((i * DUMP_WIDTH) + j) >= len) + apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf)); + else { + ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff; + apr_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.'); + apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf)); + } + } + apr_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr, + "%s", buf); + } + if (trunc > 0) + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr, + "| %04ld - ", len + trunc); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr, + "+-------------------------------------------------------------------------+"); + return; +} + +long ssl_io_data_cb(BIO *bio, int cmd, + MODSSL_BIO_CB_ARG_TYPE *argp, + int argi, long argl, long rc) +{ + SSL *ssl; + conn_rec *c; + server_rec *s; + + if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL) + return rc; + if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL) + return rc; + s = c->base_server; + + if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN) + || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) { + if (rc >= 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: %s %ld/%d bytes %s BIO#%pp [mem: %pp] %s", + SSL_LIBRARY_NAME, + (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), + rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), + bio, argp, + (argp != NULL ? "(BIO dump follows)" : "(Oops, no memory buffer?)")); + if (argp != NULL) + ssl_io_data_dump(s, argp, rc); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: I/O error, %d bytes expected to %s on BIO#%pp [mem: %pp]", + SSL_LIBRARY_NAME, argi, + (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), + bio, argp); + } + } + return rc; +} diff --git a/trunk/modules/ssl/ssl_engine_kernel.c b/trunk/modules/ssl/ssl_engine_kernel.c new file mode 100644 index 0000000000..03b1e88ce9 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_kernel.c @@ -0,0 +1,1846 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_kernel.c + * The SSL engine kernel + */ + /* ``It took me fifteen years to discover + I had no talent for programming, but + I couldn't give it up because by that + time I was too famous.'' + -- Unknown */ +#include "ssl_private.h" + +static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); + +/* + * Post Read Request Handler + */ +int ssl_hook_ReadReq(request_rec *r) +{ + SSLConnRec *sslconn = myConnConfig(r->connection); + SSL *ssl; + + if (!sslconn) { + return DECLINED; + } + + if (sslconn->non_ssl_request) { + const char *errmsg; + char *thisurl; + char *thisport = ""; + int port = ap_get_server_port(r); + + if (!ap_is_default_port(port, r)) { + thisport = apr_psprintf(r->pool, ":%u", port); + } + + thisurl = ap_escape_html(r->pool, + apr_psprintf(r->pool, "https://%s%s/", + ap_get_server_name(r), + thisport)); + + errmsg = apr_psprintf(r->pool, + "Reason: You're speaking plain HTTP " + "to an SSL-enabled server port.
    \n" + "Instead use the HTTPS scheme to access " + "this URL, please.
    \n" + "
    Hint: " + "%s
    ", + thisurl, thisurl); + + apr_table_setn(r->notes, "error-notes", errmsg); + + /* Now that we have caught this error, forget it. we are done + * with using SSL on this request. + */ + sslconn->non_ssl_request = 0; + + + return HTTP_BAD_REQUEST; + } + + /* + * Get the SSL connection structure and perform the + * delayed interlinking from SSL back to request_rec + */ + ssl = sslconn->ssl; + if (!ssl) { + return DECLINED; + } + SSL_set_app_data2(ssl, r); + + /* + * Log information about incoming HTTPS requests + */ + if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "%s HTTPS request received for child %ld (server %s)", + (r->connection->keepalives <= 0 ? + "Initial (No.1)" : + apr_psprintf(r->pool, "Subsequent (No.%d)", + r->connection->keepalives+1)), + r->connection->id, + ssl_util_vhostid(r->pool, r->server)); + } + + /* SetEnvIf ssl-*-shutdown flags can only be per-server, + * so they won't change across keepalive requests + */ + if (sslconn->shutdown_type == SSL_SHUTDOWN_TYPE_UNSET) { + ssl_configure_env(r, sslconn); + } + + return DECLINED; +} + +/* + * Move SetEnvIf information from request_rec to conn_rec/BUFF + * to allow the close connection handler to use them. + */ + +static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn) +{ + int i; + const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); + const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; + + sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD; + + for (i = 0; i < arr->nelts; i++) { + const char *key = elts[i].key; + + switch (*key) { + case 's': + /* being case-sensitive here. + * and not checking for the -shutdown since these are the only + * SetEnvIf "flags" we support + */ + if (!strncmp(key+1, "sl-", 3)) { + key += 4; + if (!strncmp(key, "unclean", 7)) { + sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; + } + else if (!strncmp(key, "accurate", 8)) { + sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_ACCURATE; + } + return; /* should only ever be one ssl-*-shutdown */ + } + break; + } + } +} + +/* + * Access Handler + */ +int ssl_hook_Access(request_rec *r) +{ + SSLDirConfigRec *dc = myDirConfig(r); + SSLSrvConfigRec *sc = mySrvConfig(r->server); + SSLConnRec *sslconn = myConnConfig(r->connection); + SSL *ssl = sslconn ? sslconn->ssl : NULL; + SSL_CTX *ctx = NULL; + apr_array_header_t *requires; + ssl_require_t *ssl_requires; + char *cp; + int ok, i; + BOOL renegotiate = FALSE, renegotiate_quick = FALSE; + X509 *cert; + X509 *peercert; + X509_STORE *cert_store = NULL; + X509_STORE_CTX cert_store_ctx; + STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL; + SSL_CIPHER *cipher = NULL; + int depth, verify_old, verify, n; + + if (ssl) { + ctx = SSL_get_SSL_CTX(ssl); + } + + /* + * Support for SSLRequireSSL directive + */ + if (dc->bSSLRequired && !ssl) { + if (sc->enabled == SSL_ENABLED_OPTIONAL) { + /* This vhost was configured for optional SSL, just tell the + * client that we need to upgrade. + */ + apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1"); + apr_table_setn(r->err_headers_out, "Connection", "Upgrade"); + + return HTTP_UPGRADE_REQUIRED; + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: %s", + r->filename, "SSL connection required"); + + /* remember forbidden access for strict require option */ + apr_table_setn(r->notes, "ssl-access-forbidden", "1"); + + return HTTP_FORBIDDEN; + } + + /* + * Check to see if SSL protocol is on + */ + if (!((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL) || ssl)) { + return DECLINED; + } + /* + * Support for per-directory reconfigured SSL connection parameters. + * + * This is implemented by forcing an SSL renegotiation with the + * reconfigured parameter suite. But Apache's internal API processing + * makes our life very hard here, because when internal sub-requests occur + * we nevertheless should avoid multiple unnecessary SSL handshakes (they + * require extra network I/O and especially time to perform). + * + * But the optimization for filtering out the unnecessary handshakes isn't + * obvious and trivial. Especially because while Apache is in its + * sub-request processing the client could force additional handshakes, + * too. And these take place perhaps without our notice. So the only + * possibility is to explicitly _ask_ OpenSSL whether the renegotiation + * has to be performed or not. It has to performed when some parameters + * which were previously known (by us) are not those we've now + * reconfigured (as known by OpenSSL) or (in optimized way) at least when + * the reconfigured parameter suite is stronger (more restrictions) than + * the currently active one. + */ + + /* + * Override of SSLCipherSuite + * + * We provide two options here: + * + * o The paranoid and default approach where we force a renegotiation when + * the cipher suite changed in _any_ way (which is straight-forward but + * often forces renegotiations too often and is perhaps not what the + * user actually wanted). + * + * o The optimized and still secure way where we force a renegotiation + * only if the currently active cipher is no longer contained in the + * reconfigured/new cipher suite. Any other changes are not important + * because it's the servers choice to select a cipher from the ones the + * client supports. So as long as the current cipher is still in the new + * cipher suite we're happy. Because we can assume we would have + * selected it again even when other (better) ciphers exists now in the + * new cipher suite. This approach is fine because the user explicitly + * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no + * implicit optimizations. + */ + if (dc->szCipherSuite) { + /* remember old state */ + + if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { + cipher = SSL_get_current_cipher(ssl); + } + else { + cipher_list_old = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); + + if (cipher_list_old) { + cipher_list_old = sk_SSL_CIPHER_dup(cipher_list_old); + } + } + + /* configure new state */ + if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + r->server, + "Unable to reconfigure (per-directory) " + "permitted SSL ciphers"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); + + if (cipher_list_old) { + sk_SSL_CIPHER_free(cipher_list_old); + } + + return HTTP_FORBIDDEN; + } + + /* determine whether a renegotiation has to be forced */ + cipher_list = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); + + if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { + /* optimized way */ + if ((!cipher && cipher_list) || + (cipher && !cipher_list)) + { + renegotiate = TRUE; + } + else if (cipher && cipher_list && + (sk_SSL_CIPHER_find(cipher_list, cipher) < 0)) + { + renegotiate = TRUE; + } + } + else { + /* paranoid way */ + if ((!cipher_list_old && cipher_list) || + (cipher_list_old && !cipher_list)) + { + renegotiate = TRUE; + } + else if (cipher_list_old && cipher_list) { + for (n = 0; + !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list)); + n++) + { + SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n); + + if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) { + renegotiate = TRUE; + } + } + + for (n = 0; + !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old)); + n++) + { + SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n); + + if (sk_SSL_CIPHER_find(cipher_list, value) < 0) { + renegotiate = TRUE; + } + } + } + } + + /* cleanup */ + if (cipher_list_old) { + sk_SSL_CIPHER_free(cipher_list_old); + } + + /* tracing */ + if (renegotiate) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Reconfigured cipher suite will force renegotiation"); + } + } + + /* + * override of SSLVerifyDepth + * + * The depth checks are handled by us manually inside the verify callback + * function and not by OpenSSL internally (and our function is aware of + * both the per-server and per-directory contexts). So we cannot ask + * OpenSSL about the currently verify depth. Instead we remember it in our + * ap_ctx attached to the SSL* of OpenSSL. We've to force the + * renegotiation if the reconfigured/new verify depth is less than the + * currently active/remembered verify depth (because this means more + * restriction on the certificate chain). + */ + if (dc->nVerifyDepth != UNSET) { + /* XXX: doesnt look like sslconn->verify_depth is actually used */ + if (!(n = sslconn->verify_depth)) { + sslconn->verify_depth = n = sc->server->auth.verify_depth; + } + + /* determine whether a renegotiation has to be forced */ + if (dc->nVerifyDepth < n) { + renegotiate = TRUE; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Reduced client verification depth will force " + "renegotiation"); + } + } + + /* + * override of SSLVerifyClient + * + * We force a renegotiation if the reconfigured/new verify type is + * stronger than the currently active verify type. + * + * The order is: none << optional_no_ca << optional << require + * + * Additionally the following optimization is possible here: When the + * currently active verify type is "none" but a client certificate is + * already known/present, it's enough to manually force a client + * verification but at least skip the I/O-intensive renegotation + * handshake. + */ + if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { + /* remember old state */ + verify_old = SSL_get_verify_mode(ssl); + /* configure new state */ + verify = SSL_VERIFY_NONE; + + if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { + verify |= SSL_VERIFY_PEER_STRICT; + } + + if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || + (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) + { + verify |= SSL_VERIFY_PEER; + } + + modssl_set_verify(ssl, verify, ssl_callback_SSLVerify); + SSL_set_verify_result(ssl, X509_V_OK); + + /* determine whether we've to force a renegotiation */ + if (!renegotiate && verify != verify_old) { + if (((verify_old == SSL_VERIFY_NONE) && + (verify != SSL_VERIFY_NONE)) || + + (!(verify_old & SSL_VERIFY_PEER) && + (verify & SSL_VERIFY_PEER)) || + + (!(verify_old & SSL_VERIFY_PEER_STRICT) && + (verify & SSL_VERIFY_PEER_STRICT))) + { + renegotiate = TRUE; + /* optimization */ + + if ((dc->nOptions & SSL_OPT_OPTRENEGOTIATE) && + (verify_old == SSL_VERIFY_NONE) && + ((peercert = SSL_get_peer_certificate(ssl)) != NULL)) + { + renegotiate_quick = TRUE; + X509_free(peercert); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + r->server, + "Changed client verification type will force " + "%srenegotiation", + renegotiate_quick ? "quick " : ""); + } + } + } + + /* + * override SSLCACertificateFile & SSLCACertificatePath + * This is only enabled if the SSL_set_cert_store() function + * is available in the ssl library. the 1.x based mod_ssl + * used SSL_CTX_set_cert_store which is not thread safe. + */ + +#ifdef HAVE_SSL_SET_CERT_STORE + /* + * check if per-dir and per-server config field are not the same. + * if f is defined in per-dir and not defined in per-server + * or f is defined in both but not the equal ... + */ +#define MODSSL_CFG_NE(f) \ + (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f)))) + +#define MODSSL_CFG_CA(f) \ + (dc->f ? dc->f : sc->f) + + if (MODSSL_CFG_NE(szCACertificateFile) || + MODSSL_CFG_NE(szCACertificatePath)) + { + STACK_OF(X509_NAME) *ca_list; + const char *ca_file = MODSSL_CFG_CA(szCACertificateFile); + const char *ca_path = MODSSL_CFG_CA(szCACertificatePath); + + cert_store = X509_STORE_new(); + + if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Unable to reconfigure verify locations " + "for client authentication"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); + + X509_STORE_free(cert_store); + + return HTTP_FORBIDDEN; + } + + /* SSL_free will free cert_store */ + SSL_set_cert_store(ssl, cert_store); + + if (!(ca_list = ssl_init_FindCAList(r->server, r->pool, + ca_file, ca_path))) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Unable to determine list of available " + "CA certificates for client authentication"); + + return HTTP_FORBIDDEN; + } + + SSL_set_client_CA_list(ssl, ca_list); + renegotiate = TRUE; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Changed client verification locations will force " + "renegotiation"); + } +#endif /* HAVE_SSL_SET_CERT_STORE */ + + /* + * SSL renegotiations in conjunction with HTTP + * requests using the POST method are not supported. + * + * Background: + * + * 1. When the client sends a HTTP/HTTPS request, Apache's core code + * reads only the request line ("METHOD /path HTTP/x.y") and the + * attached MIME headers ("Foo: bar") up to the terminating line ("CR + * LF"). An attached request body (for instance the data of a POST + * method) is _NOT_ read. Instead it is read by mod_cgi's content + * handler and directly passed to the CGI script. + * + * 2. mod_ssl supports per-directory re-configuration of SSL parameters. + * This is implemented by performing an SSL renegotiation of the + * re-configured parameters after the request is read, but before the + * response is sent. In more detail: the renegotiation happens after the + * request line and MIME headers were read, but _before_ the attached + * request body is read. The reason simply is that in the HTTP protocol + * usually there is no acknowledgment step between the headers and the + * body (there is the 100-continue feature and the chunking facility + * only), so Apache has no API hook for this step. + * + * 3. the problem now occurs when the client sends a POST request for + * URL /foo via HTTPS the server and the server has SSL parameters + * re-configured on a per-URL basis for /foo. Then mod_ssl has to + * perform an SSL renegotiation after the request was read and before + * the response is sent. But the problem is the pending POST body data + * in the receive buffer of SSL (which Apache still has not read - it's + * pending until mod_cgi sucks it in). When mod_ssl now tries to perform + * the renegotiation the pending data leads to an I/O error. + * + * Solution Idea: + * + * There are only two solutions: Either to simply state that POST + * requests to URLs with SSL re-configurations are not allowed, or to + * renegotiate really after the _complete_ request (i.e. including + * the POST body) was read. Obviously the latter would be preferred, + * but it cannot be done easily inside Apache, because as already + * mentioned, there is no API step between the body reading and the body + * processing. And even when we mod_ssl would hook directly into the + * loop of mod_cgi, we wouldn't solve the problem for other handlers, of + * course. So the only general solution is to suck in the pending data + * of the request body from the OpenSSL BIO into the Apache BUFF. Then + * the renegotiation can be done and after this step Apache can proceed + * processing the request as before. + * + * Solution Implementation: + * + * We cannot simply suck in the data via an SSL_read-based loop because of + * HTTP chunking. Instead we _have_ to use the Apache API for this step which + * is aware of HTTP chunking. So the trick is to suck in the pending request + * data via the Apache API (which uses Apache's BUFF code and in the + * background mod_ssl's I/O glue code) and re-inject it later into the Apache + * BUFF code again. This way the data flows twice through the Apache BUFF, of + * course. But this way the solution doesn't depend on any Apache specifics + * and is fully transparent to Apache modules. + * + * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !! + */ + if (renegotiate && !renegotiate_quick && (r->method_number == M_POST)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "SSL Re-negotiation in conjunction " + "with POST method not supported! " + "hint: try SSLOptions +OptRenegotiate"); + + return HTTP_METHOD_NOT_ALLOWED; + } + + /* + * now do the renegotiation if anything was actually reconfigured + */ + if (renegotiate) { + /* + * Now we force the SSL renegotation by sending the Hello Request + * message to the client. Here we have to do a workaround: Actually + * OpenSSL returns immediately after sending the Hello Request (the + * intent AFAIK is because the SSL/TLS protocol says it's not a must + * that the client replies to a Hello Request). But because we insist + * on a reply (anything else is an error for us) we have to go to the + * ACCEPT state manually. Using SSL_set_accept_state() doesn't work + * here because it resets too much of the connection. So we set the + * state explicitly and continue the handshake manually. + */ + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Requesting connection re-negotiation"); + + if (renegotiate_quick) { + STACK_OF(X509) *cert_stack; + + /* perform just a manual re-verification of the peer */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Performing quick renegotiation: " + "just re-verifying the peer"); + + cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl); + + cert = SSL_get_peer_certificate(ssl); + + if (!cert_stack && cert) { + /* client cert is in the session cache, but there is + * no chain, since ssl3_get_client_certificate() + * sk_X509_shift-ed the peer cert out of the chain. + * we put it back here for the purpose of quick_renegotiation. + */ + cert_stack = sk_new_null(); + sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert); + } + + if (!cert_stack || (sk_X509_num(cert_stack) == 0)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Cannot find peer certificate chain"); + + return HTTP_FORBIDDEN; + } + + if (!(cert_store || + (cert_store = SSL_CTX_get_cert_store(ctx)))) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Cannot find certificate storage"); + + return HTTP_FORBIDDEN; + } + + if (!cert) { + cert = sk_X509_value(cert_stack, 0); + } + + X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack); + depth = SSL_get_verify_depth(ssl); + + if (depth >= 0) { + X509_STORE_CTX_set_depth(&cert_store_ctx, depth); + } + + X509_STORE_CTX_set_ex_data(&cert_store_ctx, + SSL_get_ex_data_X509_STORE_CTX_idx(), + (char *)ssl); + + if (!modssl_X509_verify_cert(&cert_store_ctx)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation verification step failed"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); + } + + SSL_set_verify_result(ssl, cert_store_ctx.error); + X509_STORE_CTX_cleanup(&cert_store_ctx); + + if (cert_stack != SSL_get_peer_cert_chain(ssl)) { + /* we created this ourselves, so free it */ + sk_X509_pop_free(cert_stack, X509_free); + } + } + else { + request_rec *id = r->main ? r->main : r; + + /* do a full renegotiation */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Performing full renegotiation: " + "complete handshake protocol"); + + SSL_set_session_id_context(ssl, + (unsigned char *)&id, + sizeof(id)); + + SSL_renegotiate(ssl); + SSL_do_handshake(ssl); + + if (SSL_get_state(ssl) != SSL_ST_OK) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation request failed"); + + r->connection->aborted = 1; + return HTTP_FORBIDDEN; + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Awaiting re-negotiation handshake"); + + /* XXX: Should replace SSL_set_state with SSL_renegotiate(ssl); + * However, this causes failures in perl-framework currently, + * perhaps pre-test if we have already negotiated? + */ + SSL_set_state(ssl, SSL_ST_ACCEPT); + SSL_do_handshake(ssl); + + if (SSL_get_state(ssl) != SSL_ST_OK) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation handshake failed: " + "Not accepted by client!?"); + + r->connection->aborted = 1; + return HTTP_FORBIDDEN; + } + } + + /* + * Remember the peer certificate's DN + */ + if ((cert = SSL_get_peer_certificate(ssl))) { + if (sslconn->client_cert) { + X509_free(sslconn->client_cert); + } + sslconn->client_cert = cert; + sslconn->client_dn = NULL; + } + + /* + * Finally check for acceptable renegotiation results + */ + if (dc->nVerifyClient != SSL_CVERIFY_NONE) { + BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); + + if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation handshake failed: " + "Client verification failed"); + + return HTTP_FORBIDDEN; + } + + if (do_verify) { + if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation handshake failed: " + "Client certificate missing"); + + return HTTP_FORBIDDEN; + } + + X509_free(peercert); + } + } + + /* + * Also check that SSLCipherSuite has been enforced as expected. + */ + if (cipher_list) { + cipher = SSL_get_current_cipher(ssl); + if (sk_SSL_CIPHER_find(cipher_list, cipher) < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "SSL cipher suite not renegotiated: " + "access to %s denied using cipher %s", + r->filename, + SSL_CIPHER_get_name(cipher)); + return HTTP_FORBIDDEN; + } + } + } + + /* If we're trying to have the user name set from a client + * certificate then we need to set it here. This should be safe as + * the user name probably isn't important from an auth checking point + * of view as the certificate supplied acts in that capacity. + * However, if FakeAuth is being used then this isn't the case so + * we need to postpone setting the username until later. + */ + if ((dc->nOptions & SSL_OPT_FAKEBASICAUTH) == 0 && dc->szUserName) { + char *val = ssl_var_lookup(r->pool, r->server, r->connection, + r, (char *)dc->szUserName); + if (val && val[0]) + r->user = val; + } + + /* + * Check SSLRequire boolean expressions + */ + requires = dc->aRequirement; + ssl_requires = (ssl_require_t *)requires->elts; + + for (i = 0; i < requires->nelts; i++) { + ssl_require_t *req = &ssl_requires[i]; + ok = ssl_expr_exec(r, req->mpExpr); + + if (ok < 0) { + cp = apr_psprintf(r->pool, + "Failed to execute " + "SSL requirement expression: %s", + ssl_expr_get_error()); + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: %s", + r->filename, cp); + + /* remember forbidden access for strict require option */ + apr_table_setn(r->notes, "ssl-access-forbidden", "1"); + + return HTTP_FORBIDDEN; + } + + if (ok != 1) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Access to %s denied for %s " + "(requirement expression not fulfilled)", + r->filename, r->connection->remote_ip); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Failed expression: %s", req->cpExpr); + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "access to %s failed, reason: %s", + r->filename, + "SSL requirement expression not fulfilled " + "(see SSL logfile for more details)"); + + /* remember forbidden access for strict require option */ + apr_table_setn(r->notes, "ssl-access-forbidden", "1"); + + return HTTP_FORBIDDEN; + } + } + + /* + * Else access is granted from our point of view (except vendor + * handlers override). But we have to return DECLINED here instead + * of OK, because mod_auth and other modules still might want to + * deny access. + */ + + return DECLINED; +} + +/* + * Authentication Handler: + * Fake a Basic authentication from the X509 client certificate. + * + * This must be run fairly early on to prevent a real authentication from + * occuring, in particular it must be run before anything else that + * authenticates a user. This means that the Module statement for this + * module should be LAST in the Configuration file. + */ +int ssl_hook_UserCheck(request_rec *r) +{ + SSLConnRec *sslconn = myConnConfig(r->connection); + SSLSrvConfigRec *sc = mySrvConfig(r->server); + SSLDirConfigRec *dc = myDirConfig(r); + char *clientdn; + const char *auth_line, *username, *password; + + /* + * Additionally forbid access (again) + * when strict require option is used. + */ + if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && + (apr_table_get(r->notes, "ssl-access-forbidden"))) + { + return HTTP_FORBIDDEN; + } + + /* + * We decline when we are in a subrequest. The Authorization header + * would already be present if it was added in the main request. + */ + if (!ap_is_initial_req(r)) { + return DECLINED; + } + + /* + * Make sure the user is not able to fake the client certificate + * based authentication by just entering an X.509 Subject DN + * ("/XX=YYY/XX=YYY/..") as the username and "password" as the + * password. + */ + if ((auth_line = apr_table_get(r->headers_in, "Authorization"))) { + if (strcEQ(ap_getword(r->pool, &auth_line, ' '), "Basic")) { + while ((*auth_line == ' ') || (*auth_line == '\t')) { + auth_line++; + } + + auth_line = ap_pbase64decode(r->pool, auth_line); + username = ap_getword_nulls(r->pool, &auth_line, ':'); + password = auth_line; + + if ((username[0] == '/') && strEQ(password, "password")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Encountered FakeBasicAuth spoof: %s", username); + return HTTP_FORBIDDEN; + } + } + } + + /* + * We decline operation in various situations... + * - SSLOptions +FakeBasicAuth not configured + * - r->user already authenticated + * - ssl not enabled + * - client did not present a certificate + */ + if (!((sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) + && sslconn && sslconn->ssl && sslconn->client_cert) || + !(dc->nOptions & SSL_OPT_FAKEBASICAUTH) || r->user) + { + return DECLINED; + } + + if (!sslconn->client_dn) { + X509_NAME *name = X509_get_subject_name(sslconn->client_cert); + char *cp = X509_NAME_oneline(name, NULL, 0); + sslconn->client_dn = apr_pstrdup(r->connection->pool, cp); + modssl_free(cp); + } + + clientdn = (char *)sslconn->client_dn; + + /* + * Fake a password - which one would be immaterial, as, it seems, an empty + * password in the users file would match ALL incoming passwords, if only + * we were using the standard crypt library routine. Unfortunately, OpenSSL + * "fixes" a "bug" in crypt and thus prevents blank passwords from + * working. (IMHO what they really fix is a bug in the users of the code + * - failing to program correctly for shadow passwords). We need, + * therefore, to provide a password. This password can be matched by + * adding the string "xxj31ZMTZzkVA" as the password in the user file. + * This is just the crypted variant of the word "password" ;-) + */ + auth_line = apr_pstrcat(r->pool, "Basic ", + ap_pbase64encode(r->pool, + apr_pstrcat(r->pool, clientdn, + ":password", NULL)), + NULL); + apr_table_set(r->headers_in, "Authorization", auth_line); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Faking HTTP Basic Auth header: \"Authorization: %s\"", + auth_line); + + return DECLINED; +} + +/* authorization phase */ +int ssl_hook_Auth(request_rec *r) +{ + SSLDirConfigRec *dc = myDirConfig(r); + + /* + * Additionally forbid access (again) + * when strict require option is used. + */ + if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && + (apr_table_get(r->notes, "ssl-access-forbidden"))) + { + return HTTP_FORBIDDEN; + } + + return DECLINED; +} + +/* + * Fixup Handler + */ + +static const char *ssl_hook_Fixup_vars[] = { + "SSL_VERSION_INTERFACE", + "SSL_VERSION_LIBRARY", + "SSL_PROTOCOL", + "SSL_CIPHER", + "SSL_CIPHER_EXPORT", + "SSL_CIPHER_USEKEYSIZE", + "SSL_CIPHER_ALGKEYSIZE", + "SSL_CLIENT_VERIFY", + "SSL_CLIENT_M_VERSION", + "SSL_CLIENT_M_SERIAL", + "SSL_CLIENT_V_START", + "SSL_CLIENT_V_END", + "SSL_CLIENT_V_REMAIN", + "SSL_CLIENT_S_DN", + "SSL_CLIENT_S_DN_C", + "SSL_CLIENT_S_DN_ST", + "SSL_CLIENT_S_DN_L", + "SSL_CLIENT_S_DN_O", + "SSL_CLIENT_S_DN_OU", + "SSL_CLIENT_S_DN_CN", + "SSL_CLIENT_S_DN_T", + "SSL_CLIENT_S_DN_I", + "SSL_CLIENT_S_DN_G", + "SSL_CLIENT_S_DN_S", + "SSL_CLIENT_S_DN_D", + "SSL_CLIENT_S_DN_UID", + "SSL_CLIENT_S_DN_Email", + "SSL_CLIENT_I_DN", + "SSL_CLIENT_I_DN_C", + "SSL_CLIENT_I_DN_ST", + "SSL_CLIENT_I_DN_L", + "SSL_CLIENT_I_DN_O", + "SSL_CLIENT_I_DN_OU", + "SSL_CLIENT_I_DN_CN", + "SSL_CLIENT_I_DN_T", + "SSL_CLIENT_I_DN_I", + "SSL_CLIENT_I_DN_G", + "SSL_CLIENT_I_DN_S", + "SSL_CLIENT_I_DN_D", + "SSL_CLIENT_I_DN_UID", + "SSL_CLIENT_I_DN_Email", + "SSL_CLIENT_A_KEY", + "SSL_CLIENT_A_SIG", + "SSL_SERVER_M_VERSION", + "SSL_SERVER_M_SERIAL", + "SSL_SERVER_V_START", + "SSL_SERVER_V_END", + "SSL_SERVER_S_DN", + "SSL_SERVER_S_DN_C", + "SSL_SERVER_S_DN_ST", + "SSL_SERVER_S_DN_L", + "SSL_SERVER_S_DN_O", + "SSL_SERVER_S_DN_OU", + "SSL_SERVER_S_DN_CN", + "SSL_SERVER_S_DN_T", + "SSL_SERVER_S_DN_I", + "SSL_SERVER_S_DN_G", + "SSL_SERVER_S_DN_S", + "SSL_SERVER_S_DN_D", + "SSL_SERVER_S_DN_UID", + "SSL_SERVER_S_DN_Email", + "SSL_SERVER_I_DN", + "SSL_SERVER_I_DN_C", + "SSL_SERVER_I_DN_ST", + "SSL_SERVER_I_DN_L", + "SSL_SERVER_I_DN_O", + "SSL_SERVER_I_DN_OU", + "SSL_SERVER_I_DN_CN", + "SSL_SERVER_I_DN_T", + "SSL_SERVER_I_DN_I", + "SSL_SERVER_I_DN_G", + "SSL_SERVER_I_DN_S", + "SSL_SERVER_I_DN_D", + "SSL_SERVER_I_DN_UID", + "SSL_SERVER_I_DN_Email", + "SSL_SERVER_A_KEY", + "SSL_SERVER_A_SIG", + "SSL_SESSION_ID", + NULL +}; + +int ssl_hook_Fixup(request_rec *r) +{ + SSLConnRec *sslconn = myConnConfig(r->connection); + SSLSrvConfigRec *sc = mySrvConfig(r->server); + SSLDirConfigRec *dc = myDirConfig(r); + apr_table_t *env = r->subprocess_env; + char *var, *val = ""; + STACK_OF(X509) *peer_certs; + SSL *ssl; + int i; + + if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)) { + apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1"); + } + + /* + * Check to see if SSL is on + */ + if (!(((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) && sslconn && (ssl = sslconn->ssl))) { + return DECLINED; + } + + /* + * Annotate the SSI/CGI environment with standard SSL information + */ + /* the always present HTTPS (=HTTP over SSL) flag! */ + apr_table_setn(env, "HTTPS", "on"); + + /* standard SSL environment variables */ + if (dc->nOptions & SSL_OPT_STDENVVARS) { + for (i = 0; ssl_hook_Fixup_vars[i]; i++) { + var = (char *)ssl_hook_Fixup_vars[i]; + val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); + if (!strIsEmpty(val)) { + apr_table_setn(env, var, val); + } + } + } + + /* + * On-demand bloat up the SSI/CGI environment with certificate data + */ + if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) { + val = ssl_var_lookup(r->pool, r->server, r->connection, + r, "SSL_SERVER_CERT"); + + apr_table_setn(env, "SSL_SERVER_CERT", val); + + val = ssl_var_lookup(r->pool, r->server, r->connection, + r, "SSL_CLIENT_CERT"); + + apr_table_setn(env, "SSL_CLIENT_CERT", val); + + if ((peer_certs = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl))) { + for (i = 0; i < sk_X509_num(peer_certs); i++) { + var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i); + val = ssl_var_lookup(r->pool, r->server, r->connection, + r, var); + if (val) { + apr_table_setn(env, var, val); + } + } + } + } + + return DECLINED; +} + +/* _________________________________________________________________ +** +** OpenSSL Callback Functions +** _________________________________________________________________ +*/ + +/* + * Handle out temporary RSA private keys on demand + * + * The background of this as the TLSv1 standard explains it: + * + * | D.1. Temporary RSA keys + * | + * | US Export restrictions limit RSA keys used for encryption to 512 + * | bits, but do not place any limit on lengths of RSA keys used for + * | signing operations. Certificates often need to be larger than 512 + * | bits, since 512-bit RSA keys are not secure enough for high-value + * | transactions or for applications requiring long-term security. Some + * | certificates are also designated signing-only, in which case they + * | cannot be used for key exchange. + * | + * | When the public key in the certificate cannot be used for encryption, + * | the server signs a temporary RSA key, which is then exchanged. In + * | exportable applications, the temporary RSA key should be the maximum + * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are + * | relatively insecure, they should be changed often. For typical + * | electronic commerce applications, it is suggested that keys be + * | changed daily or every 500 transactions, and more often if possible. + * | Note that while it is acceptable to use the same temporary key for + * | multiple transactions, it must be signed each time it is used. + * | + * | RSA key generation is a time-consuming process. In many cases, a + * | low-priority process can be assigned the task of key generation. + * | Whenever a new key is completed, the existing temporary key can be + * | replaced with the new one. + * + * XXX: base on comment above, if thread support is enabled, + * we should spawn a low-priority thread to generate new keys + * on the fly. + * + * So we generated 512 and 1024 bit temporary keys on startup + * which we now just hand out on demand.... + */ + +RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen) +{ + conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); + SSLModConfigRec *mc = myModConfig(c->base_server); + int idx; + + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, + "handing out temporary %d bit RSA key", keylen); + + /* doesn't matter if export flag is on, + * we won't be asked for keylen > 512 in that case. + * if we are asked for a keylen > 1024, it is too expensive + * to generate on the fly. + * XXX: any reason not to generate 2048 bit keys at startup? + */ + + switch (keylen) { + case 512: + idx = SSL_TMP_KEY_RSA_512; + break; + + case 1024: + default: + idx = SSL_TMP_KEY_RSA_1024; + } + + return (RSA *)mc->pTmpKeys[idx]; +} + +/* + * Hand out the already generated DH parameters... + */ +DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) +{ + conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); + SSLModConfigRec *mc = myModConfig(c->base_server); + int idx; + + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, + "handing out temporary %d bit DH key", keylen); + + switch (keylen) { + case 512: + idx = SSL_TMP_KEY_DH_512; + break; + + case 1024: + default: + idx = SSL_TMP_KEY_DH_1024; + } + + return (DH *)mc->pTmpKeys[idx]; +} + +/* + * This OpenSSL callback function is called when OpenSSL + * does client authentication and verifies the certificate chain. + */ +int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) +{ + /* Get Apache context back through OpenSSL context */ + SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, + SSL_get_ex_data_X509_STORE_CTX_idx()); + conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); + server_rec *s = conn->base_server; + request_rec *r = (request_rec *)SSL_get_app_data2(ssl); + + SSLSrvConfigRec *sc = mySrvConfig(s); + SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; + SSLConnRec *sslconn = myConnConfig(conn); + modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); + + /* Get verify ingredients */ + int errnum = X509_STORE_CTX_get_error(ctx); + int errdepth = X509_STORE_CTX_get_error_depth(ctx); + int depth, verify; + + /* + * Log verification information + */ + if (s->loglevel >= APLOG_DEBUG) { + X509 *cert = X509_STORE_CTX_get_current_cert(ctx); + char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); + char *iname = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Certificate Verification: " + "depth: %d, subject: %s, issuer: %s", + errdepth, + sname ? sname : "-unknown-", + iname ? iname : "-unknown-"); + + if (sname) { + modssl_free(sname); + } + + if (iname) { + modssl_free(iname); + } + } + + /* + * Check for optionally acceptable non-verifiable issuer situation + */ + if (dc && (dc->nVerifyClient != SSL_CVERIFY_UNSET)) { + verify = dc->nVerifyClient; + } + else { + verify = mctx->auth.verify_mode; + } + + if (verify == SSL_CVERIFY_NONE) { + /* + * SSLProxyVerify is either not configured or set to "none". + * (this callback doesn't happen in the server context if SSLVerify + * is not configured or set to "none") + */ + return TRUE; + } + + if (ssl_verify_error_is_optional(errnum) && + (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Certificate Verification: Verifiable Issuer is " + "configured as optional, therefore we're accepting " + "the certificate"); + + sslconn->verify_info = "GENEROUS"; + ok = TRUE; + } + + /* + * Additionally perform CRL-based revocation checks + */ + if (ok) { + if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) { + errnum = X509_STORE_CTX_get_error(ctx); + } + } + + /* + * If we already know it's not ok, log the real reason + */ + if (!ok) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Certificate Verification: Error (%d): %s", + errnum, X509_verify_cert_error_string(errnum)); + + if (sslconn->client_cert) { + X509_free(sslconn->client_cert); + sslconn->client_cert = NULL; + } + sslconn->client_dn = NULL; + sslconn->verify_error = X509_verify_cert_error_string(errnum); + } + + /* + * Finally check the depth of the certificate verification + */ + if (dc && (dc->nVerifyDepth != UNSET)) { + depth = dc->nVerifyDepth; + } + else { + depth = mctx->auth.verify_depth; + } + + if (errdepth > depth) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Certificate Verification: Certificate Chain too long " + "(chain has %d certificates, but maximum allowed are " + "only %d)", + errdepth, depth); + + errnum = X509_V_ERR_CERT_CHAIN_TOO_LONG; + sslconn->verify_error = X509_verify_cert_error_string(errnum); + + ok = FALSE; + } + + /* + * And finally signal OpenSSL the (perhaps changed) state + */ + return ok; +} + +int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) +{ + server_rec *s = c->base_server; + SSLSrvConfigRec *sc = mySrvConfig(s); + SSLConnRec *sslconn = myConnConfig(c); + modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); + X509_OBJECT obj; + X509_NAME *subject, *issuer; + X509 *cert; + X509_CRL *crl; + EVP_PKEY *pubkey; + int i, n, rc; + + /* + * Unless a revocation store for CRLs was created we + * cannot do any CRL-based verification, of course. + */ + if (!mctx->crl) { + return ok; + } + + /* + * Determine certificate ingredients in advance + */ + cert = X509_STORE_CTX_get_current_cert(ctx); + subject = X509_get_subject_name(cert); + issuer = X509_get_issuer_name(cert); + + /* + * OpenSSL provides the general mechanism to deal with CRLs but does not + * use them automatically when verifying certificates, so we do it + * explicitly here. We will check the CRL for the currently checked + * certificate, if there is such a CRL in the store. + * + * We come through this procedure for each certificate in the certificate + * chain, starting with the root-CA's certificate. At each step we've to + * both verify the signature on the CRL (to make sure it's a valid CRL) + * and it's revocation list (to make sure the current certificate isn't + * revoked). But because to check the signature on the CRL we need the + * public key of the issuing CA certificate (which was already processed + * one round before), we've a little problem. But we can both solve it and + * at the same time optimize the processing by using the following + * verification scheme (idea and code snippets borrowed from the GLOBUS + * project): + * + * 1. We'll check the signature of a CRL in each step when we find a CRL + * through the _subject_ name of the current certificate. This CRL + * itself will be needed the first time in the next round, of course. + * But we do the signature processing one round before this where the + * public key of the CA is available. + * + * 2. We'll check the revocation list of a CRL in each step when + * we find a CRL through the _issuer_ name of the current certificate. + * This CRLs signature was then already verified one round before. + * + * This verification scheme allows a CA to revoke its own certificate as + * well, of course. + */ + + /* + * Try to retrieve a CRL corresponding to the _subject_ of + * the current certificate in order to verify it's integrity. + */ + memset((char *)&obj, 0, sizeof(obj)); + rc = SSL_X509_STORE_lookup(mctx->crl, + X509_LU_CRL, subject, &obj); + crl = obj.data.crl; + + if ((rc > 0) && crl) { + /* + * Log information about CRL + * (A little bit complicated because of ASN.1 and BIOs...) + */ + if (s->loglevel >= APLOG_DEBUG) { + char buff[512]; /* should be plenty */ + BIO *bio = BIO_new(BIO_s_mem()); + + BIO_printf(bio, "CA CRL: Issuer: "); + X509_NAME_print(bio, issuer, 0); + + BIO_printf(bio, ", lastUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); + + BIO_printf(bio, ", nextUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); + + n = BIO_read(bio, buff, sizeof(buff) - 1); + buff[n] = '\0'; + + BIO_free(bio); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", buff); + } + + /* + * Verify the signature on this CRL + */ + pubkey = X509_get_pubkey(cert); + rc = X509_CRL_verify(crl, pubkey); +#ifdef OPENSSL_VERSION_NUMBER + /* Only refcounted in OpenSSL */ + if (pubkey) + EVP_PKEY_free(pubkey); +#endif + if (rc <= 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Invalid signature on CRL"); + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + + /* + * Check date of CRL to make sure it's not expired + */ + i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); + + if (i == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Found CRL has invalid nextUpdate field"); + + X509_STORE_CTX_set_error(ctx, + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + + if (i < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Found CRL is expired - " + "revoking all certificates until you get updated CRL"); + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + + X509_OBJECT_free_contents(&obj); + } + + /* + * Try to retrieve a CRL corresponding to the _issuer_ of + * the current certificate in order to check for revocation. + */ + memset((char *)&obj, 0, sizeof(obj)); + rc = SSL_X509_STORE_lookup(mctx->crl, + X509_LU_CRL, issuer, &obj); + + crl = obj.data.crl; + if ((rc > 0) && crl) { + /* + * Check if the current certificate is revoked by this CRL + */ + n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); + + for (i = 0; i < n; i++) { + X509_REVOKED *revoked = + sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); + + ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked); + + if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { + if (s->loglevel >= APLOG_DEBUG) { + char *cp = X509_NAME_oneline(issuer, NULL, 0); + long serial = ASN1_INTEGER_get(sn); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Certificate with serial %ld (0x%lX) " + "revoked per CRL from issuer %s", + serial, serial, cp); + modssl_free(cp); + } + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + } + + X509_OBJECT_free_contents(&obj); + } + + return ok; +} + +#define SSLPROXY_CERT_CB_LOG_FMT \ + "Proxy client certificate callback: (%s) " + +static void modssl_proxy_info_log(server_rec *s, + X509_INFO *info, + const char *msg) +{ + SSLSrvConfigRec *sc = mySrvConfig(s); + char name_buf[256]; + X509_NAME *name; + char *dn; + + if (s->loglevel < APLOG_DEBUG) { + return; + } + + name = X509_get_subject_name(info->x509); + dn = X509_NAME_oneline(name, name_buf, sizeof(name_buf)); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + SSLPROXY_CERT_CB_LOG_FMT "%s, sending %s", + sc->vhost_id, msg, dn ? dn : "-uknown-"); +} + +/* + * caller will decrement the cert and key reference + * so we need to increment here to prevent them from + * being freed. + */ +#define modssl_set_cert_info(info, cert, pkey) \ + *cert = info->x509; \ + X509_reference_inc(*cert); \ + *pkey = info->x_pkey->dec_pkey; \ + EVP_PKEY_reference_inc(*pkey) + +int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey) +{ + conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); + server_rec *s = c->base_server; + SSLSrvConfigRec *sc = mySrvConfig(s); + X509_NAME *ca_name, *issuer; + X509_INFO *info; + STACK_OF(X509_NAME) *ca_list; + STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs; + int i, j; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + SSLPROXY_CERT_CB_LOG_FMT "entered", + sc->vhost_id); + + if (!certs || (sk_X509_INFO_num(certs) <= 0)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + SSLPROXY_CERT_CB_LOG_FMT + "downstream server wanted client certificate " + "but none are configured", sc->vhost_id); + return FALSE; + } + + ca_list = SSL_get_client_CA_list(ssl); + + if (!ca_list || (sk_X509_NAME_num(ca_list) <= 0)) { + /* + * downstream server didn't send us a list of acceptable CA certs, + * so we send the first client cert in the list. + */ + info = sk_X509_INFO_value(certs, 0); + + modssl_proxy_info_log(s, info, "no acceptable CA list"); + + modssl_set_cert_info(info, x509, pkey); + + return TRUE; + } + + for (i = 0; i < sk_X509_NAME_num(ca_list); i++) { + ca_name = sk_X509_NAME_value(ca_list, i); + + for (j = 0; j < sk_X509_INFO_num(certs); j++) { + info = sk_X509_INFO_value(certs, j); + issuer = X509_get_issuer_name(info->x509); + + if (X509_NAME_cmp(issuer, ca_name) == 0) { + modssl_proxy_info_log(s, info, "found acceptable cert"); + + modssl_set_cert_info(info, x509, pkey); + + return TRUE; + } + } + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + SSLPROXY_CERT_CB_LOG_FMT + "no client certificate found!?", sc->vhost_id); + + return FALSE; +} + +static void ssl_session_log(server_rec *s, + const char *request, + unsigned char *id, + unsigned int idlen, + const char *status, + const char *result, + long timeout) +{ + char buf[SSL_SESSION_ID_STRING_LEN]; + char timeout_str[56] = {'\0'}; + + if (s->loglevel < APLOG_DEBUG) { + return; + } + + if (timeout) { + apr_snprintf(timeout_str, sizeof(timeout_str), + "timeout=%lds ", (timeout - time(NULL))); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Inter-Process Session Cache: " + "request=%s status=%s id=%s %s(session %s)", + request, status, + SSL_SESSION_id2sz(id, idlen, buf, sizeof(buf)), + timeout_str, result); +} + +/* + * This callback function is executed by OpenSSL whenever a new SSL_SESSION is + * added to the internal OpenSSL session cache. We use this hook to spread the + * SSL_SESSION also to the inter-process disk-cache to make share it with our + * other Apache pre-forked server processes. + */ +int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *session) +{ + /* Get Apache context back through OpenSSL context */ + conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); + server_rec *s = conn->base_server; + SSLSrvConfigRec *sc = mySrvConfig(s); + long timeout = sc->session_cache_timeout; + BOOL rc; + unsigned char *id; + unsigned int idlen; + + /* + * Set the timeout also for the internal OpenSSL cache, because this way + * our inter-process cache is consulted only when it's really necessary. + */ + SSL_set_timeout(session, timeout); + + /* + * Store the SSL_SESSION in the inter-process cache with the + * same expire time, so it expires automatically there, too. + */ + id = SSL_SESSION_get_session_id(session); + idlen = SSL_SESSION_get_session_id_length(session); + + timeout += modssl_session_get_time(session); + + rc = ssl_scache_store(s, id, idlen, timeout, session); + + ssl_session_log(s, "SET", id, idlen, + rc == TRUE ? "OK" : "BAD", + "caching", timeout); + + /* + * return 0 which means to OpenSSL that the session is still + * valid and was not freed by us with SSL_SESSION_free(). + */ + return 0; +} + +/* + * This callback function is executed by OpenSSL whenever a + * SSL_SESSION is looked up in the internal OpenSSL cache and it + * was not found. We use this to lookup the SSL_SESSION in the + * inter-process disk-cache where it was perhaps stored by one + * of our other Apache pre-forked server processes. + */ +SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *ssl, + unsigned char *id, + int idlen, int *do_copy) +{ + /* Get Apache context back through OpenSSL context */ + conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); + server_rec *s = conn->base_server; + SSL_SESSION *session; + + /* + * Try to retrieve the SSL_SESSION from the inter-process cache + */ + session = ssl_scache_retrieve(s, id, idlen); + + ssl_session_log(s, "GET", id, idlen, + session ? "FOUND" : "MISSED", + session ? "reuse" : "renewal", 0); + + /* + * Return NULL or the retrieved SSL_SESSION. But indicate (by + * setting do_copy to 0) that the reference count on the + * SSL_SESSION should not be incremented by the SSL library, + * because we will no longer hold a reference to it ourself. + */ + *do_copy = 0; + + return session; +} + +/* + * This callback function is executed by OpenSSL whenever a + * SSL_SESSION is removed from the the internal OpenSSL cache. + * We use this to remove the SSL_SESSION in the inter-process + * disk-cache, too. + */ +void ssl_callback_DelSessionCacheEntry(SSL_CTX *ctx, + SSL_SESSION *session) +{ + server_rec *s; + SSLSrvConfigRec *sc; + unsigned char *id; + unsigned int idlen; + + /* + * Get Apache context back through OpenSSL context + */ + if (!(s = (server_rec *)SSL_CTX_get_app_data(ctx))) { + return; /* on server shutdown Apache is already gone */ + } + + sc = mySrvConfig(s); + + /* + * Remove the SSL_SESSION from the inter-process cache + */ + id = SSL_SESSION_get_session_id(session); + idlen = SSL_SESSION_get_session_id_length(session); + + ssl_scache_remove(s, id, idlen); + + ssl_session_log(s, "REM", id, idlen, + "OK", "dead", 0); + + return; +} + +/* + * This callback function is executed while OpenSSL processes the + * SSL handshake and does SSL record layer stuff. We use it to + * trace OpenSSL's processing in out SSL logfile. + */ +void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) +{ + conn_rec *c; + server_rec *s; + SSLSrvConfigRec *sc; + + /* + * find corresponding server + */ + if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { + return; + } + + s = c->base_server; + if (!(sc = mySrvConfig(s))) { + return; + } + + /* + * create the various trace messages + */ + if (s->loglevel >= APLOG_DEBUG) { + if (where & SSL_CB_HANDSHAKE_START) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Handshake: start", SSL_LIBRARY_NAME); + } + else if (where & SSL_CB_HANDSHAKE_DONE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Handshake: done", SSL_LIBRARY_NAME); + } + else if (where & SSL_CB_LOOP) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Loop: %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } + else if (where & SSL_CB_READ) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Read: %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } + else if (where & SSL_CB_WRITE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Write: %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } + else if (where & SSL_CB_ALERT) { + char *str = (where & SSL_CB_READ) ? "read" : "write"; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Alert: %s:%s:%s", + SSL_LIBRARY_NAME, str, + SSL_alert_type_string_long(rc), + SSL_alert_desc_string_long(rc)); + } + else if (where & SSL_CB_EXIT) { + if (rc == 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Exit: failed in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } + else if (rc < 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "%s: Exit: error in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } + } + } + + /* + * Because SSL renegotations can happen at any time (not only after + * SSL_accept()), the best way to log the current connection details is + * right after a finished handshake. + */ + if (where & SSL_CB_HANDSHAKE_DONE) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Connection: Client IP: %s, Protocol: %s, " + "Cipher: %s (%s/%s bits)", + ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"), + ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"), + ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"), + ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"), + ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE")); + } +} + diff --git a/trunk/modules/ssl/ssl_engine_log.c b/trunk/modules/ssl/ssl_engine_log.c new file mode 100644 index 0000000000..0c1d1cc2d0 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_log.c @@ -0,0 +1,101 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_log.c + * Logging Facility + */ + /* ``The difference between a computer + industry job and open-source software + hacking is about 30 hours a week.'' + -- Ralf S. Engelschall */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Logfile Support +** _________________________________________________________________ +*/ + +static const struct { + const char *cpPattern; + const char *cpAnnotation; +} ssl_log_annotate[] = { + { "*envelope*bad*decrypt*", "wrong pass phrase!?" }, + { "*CLIENT_HELLO*unknown*protocol*", "speaking not SSL to HTTPS port!?" }, + { "*CLIENT_HELLO*http*request*", "speaking HTTP to HTTPS port!?" }, + { "*SSL3_READ_BYTES:sslv3*alert*bad*certificate*", "Subject CN in certificate not server name or identical to CA!?" }, + { "*self signed certificate in certificate chain*", "Client certificate signed by CA not known to server?" }, + { "*peer did not return a certificate*", "No CAs known to server for verification?" }, + { "*no shared cipher*", "Too restrictive SSLCipherSuite or using DSA server certificate?" }, + { "*no start line*", "Bad file contents or format - or even just a forgotten SSLCertificateKeyFile?" }, + { "*bad password read*", "You entered an incorrect pass phrase!?" }, + { "*bad mac decode*", "Browser still remembered details of a re-created server certificate?" }, + { NULL, NULL } +}; + +static const char *ssl_log_annotation(const char *error) +{ + int i = 0; + + while (ssl_log_annotate[i].cpPattern != NULL + && ap_strcmp_match(error, ssl_log_annotate[i].cpPattern) != 0) + i++; + + return ssl_log_annotate[i].cpAnnotation; +} + +void ssl_die(void) +{ + /* + * This is used for fatal errors and here + * it is common module practice to really + * exit from the complete program. + */ + exit(1); +} + +/* + * Prints the SSL library error information. + */ +void ssl_log_ssl_error(const char *file, int line, int level, server_rec *s) +{ + unsigned long e; + + while ((e = ERR_get_error())) { + const char *annotation; + char err[256]; + + ERR_error_string_n(e, err, sizeof err); + annotation = ssl_log_annotation(err); + + if (annotation) { + ap_log_error(file, line, level, 0, s, + "SSL Library Error: %lu %s %s", + e, err, annotation); + } + else { + ap_log_error(file, line, level, 0, s, + "SSL Library Error: %lu %s", + e, err); + } + } +} diff --git a/trunk/modules/ssl/ssl_engine_mutex.c b/trunk/modules/ssl/ssl_engine_mutex.c new file mode 100644 index 0000000000..65924d269e --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_mutex.c @@ -0,0 +1,124 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_mutex.c + * Semaphore for Mutual Exclusion + */ + /* ``Real programmers confuse + Christmas and Halloween + because DEC 25 = OCT 31.'' + -- Unknown */ + +#include "ssl_private.h" + +#ifdef AP_NEED_SET_MUTEX_PERMS +#include "unixd.h" +#endif + +int ssl_mutex_init(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_status_t rv; + + if (mc->nMutexMode == SSL_MUTEXMODE_NONE) + return TRUE; + + if (mc->pMutex) { + return TRUE; + } + if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile, + mc->nMutexMech, s->process->pool)) + != APR_SUCCESS) { + if (mc->szMutexFile) + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot create SSLMutex with file `%s'", + mc->szMutexFile); + else + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot create SSLMutex"); + return FALSE; + } + +#ifdef AP_NEED_SET_MUTEX_PERMS + rv = unixd_set_global_mutex_perms(mc->pMutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Could not set permissions on ssl_mutex; check User " + "and Group directives"); + return FALSE; + } +#endif + return TRUE; +} + +int ssl_mutex_reinit(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_status_t rv; + + if (mc->nMutexMode == SSL_MUTEXMODE_NONE) + return TRUE; + + if ((rv = apr_global_mutex_child_init(&mc->pMutex, + mc->szMutexFile, p)) != APR_SUCCESS) { + if (mc->szMutexFile) + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot reinit SSLMutex with file `%s'", + mc->szMutexFile); + else + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, + "Cannot reinit SSLMutex"); + return FALSE; + } + return TRUE; +} + +int ssl_mutex_on(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_status_t rv; + + if (mc->nMutexMode == SSL_MUTEXMODE_NONE) + return TRUE; + if ((rv = apr_global_mutex_lock(mc->pMutex)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, + "Failed to acquire SSL session cache lock"); + return FALSE; + } + return TRUE; +} + +int ssl_mutex_off(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_status_t rv; + + if (mc->nMutexMode == SSL_MUTEXMODE_NONE) + return TRUE; + if ((rv = apr_global_mutex_unlock(mc->pMutex)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, + "Failed to release SSL session cache lock"); + return FALSE; + } + return TRUE; +} + diff --git a/trunk/modules/ssl/ssl_engine_pphrase.c b/trunk/modules/ssl/ssl_engine_pphrase.c new file mode 100644 index 0000000000..7f0e4b6949 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_pphrase.c @@ -0,0 +1,789 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_pphrase.c + * Pass Phrase Dialog + */ + /* ``Treat your password like your + toothbrush. Don't let anybody + else use it, and get a new one + every six months.'' + -- Clifford Stoll */ +#include "ssl_private.h" + +/* + * Return true if the named file exists and is readable + */ + +static apr_status_t exists_and_readable(char *fname, apr_pool_t *pool, apr_time_t *mtime) +{ + apr_status_t stat; + apr_finfo_t sbuf; + apr_file_t *fd; + + if ((stat = apr_stat(&sbuf, fname, APR_FINFO_MIN, pool)) != APR_SUCCESS) + return stat; + + if (sbuf.filetype != APR_REG) + return APR_EGENERAL; + + if ((stat = apr_file_open(&fd, fname, APR_READ, 0, pool)) != APR_SUCCESS) + return stat; + + if (mtime) { + *mtime = sbuf.mtime; + } + + apr_file_close(fd); + return APR_SUCCESS; +} + +/* + * reuse vhost keys for asn1 tables where keys are allocated out + * of s->process->pool to prevent "leaking" each time we format + * a vhost key. since the key is stored in a table with lifetime + * of s->process->pool, the key needs to have the same lifetime. + * + * XXX: probably seems silly to use a hash table with keys and values + * being the same, but it is easier than doing a linear search + * and will make it easier to remove keys if needed in the future. + * also have the problem with apr_array_header_t that if we + * underestimate the number of vhost keys when we apr_array_make(), + * the array will get resized when we push past the initial number + * of elts. this resizing in the s->process->pool means "leaking" + * since apr_array_push() will apr_alloc arr->nalloc * 2 elts, + * leaving the original arr->elts to waste. + */ +static char *asn1_table_vhost_key(SSLModConfigRec *mc, apr_pool_t *p, + char *id, char *an) +{ + /* 'p' pool used here is cleared on restarts (or sooner) */ + char *key = apr_psprintf(p, "%s:%s", id, an); + void *keyptr = apr_hash_get(mc->tVHostKeys, key, + APR_HASH_KEY_STRING); + + if (!keyptr) { + /* make a copy out of s->process->pool */ + keyptr = apr_pstrdup(mc->pPool, key); + apr_hash_set(mc->tVHostKeys, keyptr, + APR_HASH_KEY_STRING, keyptr); + } + + return (char *)keyptr; +} + +/* _________________________________________________________________ +** +** Pass Phrase and Private Key Handling +** _________________________________________________________________ +*/ + +#define BUILTIN_DIALOG_BACKOFF 2 +#define BUILTIN_DIALOG_RETRIES 5 + +static apr_file_t *writetty = NULL; +static apr_file_t *readtty = NULL; + +/* + * sslc has a nasty flaw where its + * PEM_read_bio_PrivateKey does not take a callback arg. + */ +static server_rec *ssl_pphrase_server_rec = NULL; + +#ifdef SSLC_VERSION_NUMBER +int ssl_pphrase_Handle_CB(char *, int, int); +#else +int ssl_pphrase_Handle_CB(char *, int, int, void *); +#endif + +static char *pphrase_array_get(apr_array_header_t *arr, int idx) +{ + if ((idx < 0) || (idx >= arr->nelts)) { + return NULL; + } + + return ((char **)arr->elts)[idx]; +} + +static void pphrase_array_clear(apr_array_header_t *arr) +{ + if (arr->nelts > 0) { + memset(arr->elts, 0, arr->elt_size * arr->nelts); + } + arr->nelts = 0; +} + +void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + SSLSrvConfigRec *sc; + server_rec *pServ; + char *cpVHostID; + char szPath[MAX_STRING_LEN]; + EVP_PKEY *pPrivateKey; + ssl_asn1_t *asn1; + unsigned char *ucp; + long int length; + X509 *pX509Cert; + BOOL bReadable; + apr_array_header_t *aPassPhrase; + int nPassPhrase; + int nPassPhraseCur; + char *cpPassPhraseCur; + int nPassPhraseRetry; + int nPassPhraseDialog; + int nPassPhraseDialogCur; + BOOL bPassPhraseDialogOnce; + char **cpp; + int i, j; + ssl_algo_t algoCert, algoKey, at; + char *an; + char *cp; + apr_time_t pkey_mtime = 0; + int isterm = 1; + apr_status_t rv; + /* + * Start with a fresh pass phrase array + */ + aPassPhrase = apr_array_make(p, 2, sizeof(char *)); + nPassPhrase = 0; + nPassPhraseDialog = 0; + + /* + * Walk through all configured servers + */ + for (pServ = s; pServ != NULL; pServ = pServ->next) { + sc = mySrvConfig(pServ); + + if (!sc->enabled) + continue; + + cpVHostID = ssl_util_vhostid(p, pServ); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, pServ, + "Loading certificate & private key of SSL-aware server"); + + /* + * Read in server certificate(s): This is the easy part + * because this file isn't encrypted in any way. + */ + if (sc->server->pks->cert_files[0] == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, pServ, + "Server should be SSL-aware but has no certificate " + "configured [Hint: SSLCertificateFile]"); + ssl_die(); + } + algoCert = SSL_ALGO_UNKNOWN; + algoKey = SSL_ALGO_UNKNOWN; + for (i = 0, j = 0; i < SSL_AIDX_MAX && sc->server->pks->cert_files[i] != NULL; i++) { + + apr_cpystrn(szPath, sc->server->pks->cert_files[i], sizeof(szPath)); + if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Init: Can't open server certificate file %s", + szPath); + ssl_die(); + } + if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Unable to read server certificate from file %s", szPath); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + /* + * check algorithm type of certificate and make + * sure only one certificate per type is used. + */ + at = ssl_util_algotypeof(pX509Cert, NULL); + an = ssl_util_algotypestr(at); + if (algoCert & at) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Multiple %s server certificates not " + "allowed", an); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + algoCert |= at; + + /* + * Insert the certificate into global module configuration to let it + * survive the processing between the 1st Apache API init round (where + * we operate here) and the 2nd Apache init round (where the + * certificate is actually used to configure mod_ssl's per-server + * configuration structures). + */ + cp = asn1_table_vhost_key(mc, p, cpVHostID, an); + length = i2d_X509(pX509Cert, NULL); + ucp = ssl_asn1_table_set(mc->tPublicCert, cp, length); + (void)i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */ + + /* + * Free the X509 structure + */ + X509_free(pX509Cert); + + /* + * Read in the private key: This is the non-trivial part, because the + * key is typically encrypted, so a pass phrase dialog has to be used + * to request it from the user (or it has to be alternatively gathered + * from a dialog program). The important point here is that ISPs + * usually have hundrets of virtual servers configured and a lot of + * them use SSL, so really we have to minimize the pass phrase + * dialogs. + * + * The idea is this: When N virtual hosts are configured and all of + * them use encrypted private keys with different pass phrases, we + * have no chance and have to pop up N pass phrase dialogs. But + * usually the admin is clever enough and uses the same pass phrase + * for more private key files (typically he even uses one single pass + * phrase for all). When this is the case we can minimize the dialogs + * by trying to re-use already known/entered pass phrases. + */ + if (sc->server->pks->key_files[j] != NULL) + apr_cpystrn(szPath, sc->server->pks->key_files[j++], sizeof(szPath)); + + /* + * Try to read the private key file with the help of + * the callback function which serves the pass + * phrases to OpenSSL + */ + myCtxVarSet(mc, 1, pServ); + myCtxVarSet(mc, 2, p); + myCtxVarSet(mc, 3, aPassPhrase); + myCtxVarSet(mc, 4, &nPassPhraseCur); + myCtxVarSet(mc, 5, &cpPassPhraseCur); + myCtxVarSet(mc, 6, cpVHostID); + myCtxVarSet(mc, 7, an); + myCtxVarSet(mc, 8, &nPassPhraseDialog); + myCtxVarSet(mc, 9, &nPassPhraseDialogCur); + myCtxVarSet(mc, 10, &bPassPhraseDialogOnce); + + nPassPhraseCur = 0; + nPassPhraseRetry = 0; + nPassPhraseDialogCur = 0; + bPassPhraseDialogOnce = TRUE; + + pPrivateKey = NULL; + + for (;;) { + /* + * Try to read the private key file with the help of + * the callback function which serves the pass + * phrases to OpenSSL + */ + if ((rv = exists_and_readable(szPath, p, + &pkey_mtime)) != APR_SUCCESS ) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Init: Can't open server private key file " + "%s",szPath); + ssl_die(); + } + + /* + * if the private key is encrypted and SSLPassPhraseDialog + * is configured to "builtin" it isn't possible to prompt for + * a password after httpd has detached from the tty. + * in this case if we already have a private key and the + * file name/mtime hasn't changed, then reuse the existing key. + * we also reuse existing private keys that were encrypted for + * exec: and pipe: dialogs to minimize chances to snoop the + * password. that and pipe: dialogs might prompt the user + * for password, which on win32 for example could happen 4 + * times at startup. twice for each child and twice within + * each since apache "restarts itself" on startup. + * of course this will not work for the builtin dialog if + * the server was started without LoadModule ssl_module + * configured, then restarted with it configured. + * but we fall through with a chance of success if the key + * is not encrypted or can be handled via exec or pipe dialog. + * and in the case of fallthrough, pkey_mtime and isatty() + * are used to give a better idea as to what failed. + */ + if (pkey_mtime) { + int i; + + for (i=0; i < SSL_AIDX_MAX; i++) { + const char *key_id = + ssl_asn1_table_keyfmt(p, cpVHostID, i); + ssl_asn1_t *asn1 = + ssl_asn1_table_get(mc->tPrivateKey, key_id); + + if (asn1 && (asn1->source_mtime == pkey_mtime)) { + ap_log_error(APLOG_MARK, APLOG_INFO, + 0, pServ, + "%s reusing existing " + "%s private key on restart", + cpVHostID, ssl_asn1_keystr(i)); + return; + } + } + } + + cpPassPhraseCur = NULL; + ssl_pphrase_server_rec = s; /* to make up for sslc flaw */ + + /* Ensure that the error stack is empty; some SSL + * functions will fail spuriously if the error stack + * is not empty. */ + ERR_clear_error(); + + bReadable = ((pPrivateKey = SSL_read_PrivateKey(szPath, NULL, + ssl_pphrase_Handle_CB, s)) != NULL ? TRUE : FALSE); + + /* + * when the private key file now was readable, + * it's fine and we go out of the loop + */ + if (bReadable) + break; + + /* + * when we have more remembered pass phrases + * try to reuse these first. + */ + if (nPassPhraseCur < nPassPhrase) { + nPassPhraseCur++; + continue; + } + + /* + * else it's not readable and we have no more + * remembered pass phrases. Then this has to mean + * that the callback function popped up the dialog + * but a wrong pass phrase was entered. We give the + * user (but not the dialog program) a few more + * chances... + */ +#ifndef WIN32 + if ((sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN + || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) +#else + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE +#endif + && cpPassPhraseCur != NULL + && nPassPhraseRetry < BUILTIN_DIALOG_RETRIES ) { + apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase incorrect " + "(%d more retr%s permitted).\n", + (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry), + (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry) == 1 ? "y" : "ies"); + nPassPhraseRetry++; + if (nPassPhraseRetry > BUILTIN_DIALOG_BACKOFF) + apr_sleep((nPassPhraseRetry-BUILTIN_DIALOG_BACKOFF) + * 5 * APR_USEC_PER_SEC); + continue; + } +#ifdef WIN32 + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: SSLPassPhraseDialog builtin is not " + "supported on Win32 (key file " + "%s)", szPath); + ssl_die(); + } +#endif /* WIN32 */ + + /* + * Ok, anything else now means a fatal error. + */ + if (cpPassPhraseCur == NULL) { + if (nPassPhraseDialogCur && pkey_mtime && + !(isterm = isatty(fileno(stdout)))) /* XXX: apr_isatty() */ + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + pServ, + "Init: Unable to read pass phrase " + "[Hint: key introduced or changed " + "before restart?]"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + pServ, "Init: Private key not found"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ); + } + if (writetty) { + apr_file_printf(writetty, "Apache:mod_ssl:Error: Private key not found.\n"); + apr_file_printf(writetty, "**Stopped\n"); + } + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + pServ, "Init: Pass phrase incorrect"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ); + + if (writetty) { + apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase incorrect.\n"); + apr_file_printf(writetty, "**Stopped\n"); + } + } + ssl_die(); + } + + if (pPrivateKey == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Unable to read server private key from " + "file %s [Hint: Perhaps it is in a separate file? " + " See SSLCertificateKeyFile]", szPath); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + + /* + * check algorithm type of private key and make + * sure only one private key per type is used. + */ + at = ssl_util_algotypeof(NULL, pPrivateKey); + an = ssl_util_algotypestr(at); + if (algoKey & at) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Multiple %s server private keys not " + "allowed", an); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } + algoKey |= at; + + /* + * Log the type of reading + */ + if (nPassPhraseDialogCur == 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServ, + "unencrypted %s private key - pass phrase not " + "required", an); + } + else { + if (cpPassPhraseCur != NULL) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + pServ, + "encrypted %s private key - pass phrase " + "requested", an); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + pServ, + "encrypted %s private key - pass phrase" + " reused", an); + } + } + + /* + * Ok, when we have one more pass phrase store it + */ + if (cpPassPhraseCur != NULL) { + cpp = (char **)apr_array_push(aPassPhrase); + *cpp = cpPassPhraseCur; + nPassPhrase++; + } + + /* + * Insert private key into the global module configuration + * (we convert it to a stand-alone DER byte sequence + * because the SSL library uses static variables inside a + * RSA structure which do not survive DSO reloads!) + */ + cp = asn1_table_vhost_key(mc, p, cpVHostID, an); + length = i2d_PrivateKey(pPrivateKey, NULL); + ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length); + (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ + + if (nPassPhraseDialogCur != 0) { + /* remember mtime of encrypted keys */ + asn1 = ssl_asn1_table_get(mc->tPrivateKey, cp); + asn1->source_mtime = pkey_mtime; + } + + /* + * Free the private key structure + */ + EVP_PKEY_free(pPrivateKey); + } + } + + /* + * Let the user know when we're successful. + */ + if (nPassPhraseDialog > 0) { + sc = mySrvConfig(s); + if (writetty) { + apr_file_printf(writetty, "\n" + "OK: Pass Phrase Dialog successful.\n"); + } + } + + /* + * Wipe out the used memory from the + * pass phrase array and then deallocate it + */ + if (aPassPhrase->nelts) { + pphrase_array_clear(aPassPhrase); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Wiped out the queried pass phrases from memory"); + } + + /* Close the pipes if they were opened + */ + if (readtty) { + apr_file_close(readtty); + apr_file_close(writetty); + readtty = writetty = NULL; + } + return; +} + +static apr_status_t ssl_pipe_child_create(apr_pool_t *p, const char *progname) +{ + /* Child process code for 'ErrorLog "|..."'; + * may want a common framework for this, since I expect it will + * be common for other foo-loggers to want this sort of thing... + */ + apr_status_t rc; + apr_procattr_t *procattr; + apr_proc_t *procnew; + + if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) && + ((rc = apr_procattr_io_set(procattr, + APR_FULL_BLOCK, + APR_FULL_BLOCK, + APR_NO_PIPE)) == APR_SUCCESS)) { + char **args; + const char *pname; + + apr_tokenize_to_argv(progname, &args, p); + pname = apr_pstrdup(p, args[0]); + procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew)); + rc = apr_proc_create(procnew, pname, (const char * const *)args, + NULL, procattr, p); + if (rc == APR_SUCCESS) { + /* XXX: not sure if we aught to... + * apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + */ + writetty = procnew->in; + readtty = procnew->out; + } + } + + return rc; +} + +static int pipe_get_passwd_cb(char *buf, int length, char *prompt, int verify) +{ + apr_status_t rc; + char *p; + + apr_file_puts(prompt, writetty); + + buf[0]='\0'; + rc = apr_file_gets(buf, length, readtty); + apr_file_puts(APR_EOL_STR, writetty); + + if (rc != APR_SUCCESS || apr_file_eof(readtty)) { + memset(buf, 0, length); + return 1; /* failure */ + } + if ((p = strchr(buf, '\n')) != NULL) { + *p = '\0'; + } +#ifdef WIN32 + /* XXX: apr_sometest */ + if ((p = strchr(buf, '\r')) != NULL) { + *p = '\0'; + } +#endif + return 0; +} + +#ifdef SSLC_VERSION_NUMBER +int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify) +{ + void *srv = ssl_pphrase_server_rec; +#else +int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv) +{ +#endif + SSLModConfigRec *mc; + server_rec *s; + apr_pool_t *p; + apr_array_header_t *aPassPhrase; + SSLSrvConfigRec *sc; + int *pnPassPhraseCur; + char **cppPassPhraseCur; + char *cpVHostID; + char *cpAlgoType; + int *pnPassPhraseDialog; + int *pnPassPhraseDialogCur; + BOOL *pbPassPhraseDialogOnce; + char *cpp; + int len = -1; + + mc = myModConfig((server_rec *)srv); + + /* + * Reconnect to the context of ssl_phrase_Handle() + */ + s = myCtxVarGet(mc, 1, server_rec *); + p = myCtxVarGet(mc, 2, apr_pool_t *); + aPassPhrase = myCtxVarGet(mc, 3, apr_array_header_t *); + pnPassPhraseCur = myCtxVarGet(mc, 4, int *); + cppPassPhraseCur = myCtxVarGet(mc, 5, char **); + cpVHostID = myCtxVarGet(mc, 6, char *); + cpAlgoType = myCtxVarGet(mc, 7, char *); + pnPassPhraseDialog = myCtxVarGet(mc, 8, int *); + pnPassPhraseDialogCur = myCtxVarGet(mc, 9, int *); + pbPassPhraseDialogOnce = myCtxVarGet(mc, 10, BOOL *); + sc = mySrvConfig(s); + + (*pnPassPhraseDialog)++; + (*pnPassPhraseDialogCur)++; + + /* + * When remembered pass phrases are available use them... + */ + if ((cpp = pphrase_array_get(aPassPhrase, *pnPassPhraseCur)) != NULL) { + apr_cpystrn(buf, cpp, bufsize); + len = strlen(buf); + return len; + } + + /* + * Builtin or Pipe dialog + */ + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN + || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { + char *prompt; + int i; + + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { + if (!readtty) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Creating pass phrase dialog pipe child " + "'%s'", sc->server->pphrase_dialog_path); + if (ssl_pipe_child_create(p, sc->server->pphrase_dialog_path) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Init: Failed to create pass phrase pipe '%s'", + sc->server->pphrase_dialog_path); + PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, (unsigned int)bufsize); + return (-1); + } + } + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Requesting pass phrase via piped dialog"); + } + else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */ +#ifdef WIN32 + PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, (unsigned int)bufsize); + return (-1); +#else + /* + * stderr has already been redirected to the error_log. + * rather than attempting to temporarily rehook it to the terminal, + * we print the prompt to stdout before EVP_read_pw_string turns + * off tty echo + */ + apr_file_open_stdout(&writetty, p); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Requesting pass phrase via builtin terminal " + "dialog"); +#endif + } + + /* + * The first time display a header to inform the user about what + * program he actually speaks to, which module is responsible for + * this terminal dialog and why to the hell he has to enter + * something... + */ + if (*pnPassPhraseDialog == 1) { + apr_file_printf(writetty, "%s mod_ssl/%s (Pass Phrase Dialog)\n", + AP_SERVER_BASEVERSION, MOD_SSL_VERSION); + apr_file_printf(writetty, "Some of your private key files are encrypted for security reasons.\n"); + apr_file_printf(writetty, "In order to read them you have to provide the pass phrases.\n"); + } + if (*pbPassPhraseDialogOnce) { + *pbPassPhraseDialogOnce = FALSE; + apr_file_printf(writetty, "\n"); + apr_file_printf(writetty, "Server %s (%s)\n", cpVHostID, cpAlgoType); + } + + /* + * Emulate the OpenSSL internal pass phrase dialog + * (see crypto/pem/pem_lib.c:def_callback() for details) + */ + prompt = "Enter pass phrase:"; + + for (;;) { + apr_file_puts(prompt, writetty); + if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { + i = pipe_get_passwd_cb(buf, bufsize, "", FALSE); + } + else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */ + i = EVP_read_pw_string(buf, bufsize, "", FALSE); + } + if (i != 0) { + PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, (unsigned int)bufsize); + return (-1); + } + len = strlen(buf); + if (len < 1) + apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase empty (needs to be at least 1 character).\n"); + else + break; + } + } + + /* + * Filter program + */ + else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) { + const char *cmd = sc->server->pphrase_dialog_path; + const char **argv = apr_palloc(p, sizeof(char *) * 4); + char *result; + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Init: Requesting pass phrase from dialog filter " + "program (%s)", cmd); + + argv[0] = cmd; + argv[1] = cpVHostID; + argv[2] = cpAlgoType; + argv[3] = NULL; + + result = ssl_util_readfilter(s, p, cmd, argv); + apr_cpystrn(buf, result, bufsize); + len = strlen(buf); + } + + /* + * Ok, we now have the pass phrase, so give it back + */ + *cppPassPhraseCur = apr_pstrdup(p, buf); + + /* + * And return it's length to OpenSSL... + */ + return (len); +} + diff --git a/trunk/modules/ssl/ssl_engine_rand.c b/trunk/modules/ssl/ssl_engine_rand.c new file mode 100644 index 0000000000..486759c702 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_rand.c @@ -0,0 +1,179 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_rand.c + * Random Number Generator Seeding + */ + /* ``The generation of random + numbers is too important + to be left to chance.'' */ + +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Support for better seeding of SSL library's RNG +** _________________________________________________________________ +*/ + +static int ssl_rand_choosenum(int, int); +static int ssl_rand_feedfp(apr_pool_t *, apr_file_t *, int); + +int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix) +{ + SSLModConfigRec *mc; + apr_array_header_t *apRandSeed; + ssl_randseed_t *pRandSeeds; + ssl_randseed_t *pRandSeed; + unsigned char stackdata[256]; + int nReq, nDone; + apr_file_t *fp; + int i, n, l; + + mc = myModConfig(s); + nReq = 0; + nDone = 0; + apRandSeed = mc->aRandSeed; + pRandSeeds = (ssl_randseed_t *)apRandSeed->elts; + for (i = 0; i < apRandSeed->nelts; i++) { + pRandSeed = &pRandSeeds[i]; + if (pRandSeed->nCtx == nCtx) { + nReq += pRandSeed->nBytes; + if (pRandSeed->nSrc == SSL_RSSRC_FILE) { + /* + * seed in contents of an external file + */ + if (apr_file_open(&fp, pRandSeed->cpPath, + APR_READ, APR_OS_DEFAULT, p) != APR_SUCCESS) + continue; + nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes); + apr_file_close(fp); + } + else if (pRandSeed->nSrc == SSL_RSSRC_EXEC) { + const char *cmd = pRandSeed->cpPath; + const char **argv = apr_palloc(p, sizeof(char *) * 3); + /* + * seed in contents generated by an external program + */ + argv[0] = cmd; + argv[1] = apr_itoa(p, pRandSeed->nBytes); + argv[2] = NULL; + + if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL) + continue; + nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes); + ssl_util_ppclose(s, p, fp); + } +#ifdef HAVE_SSL_RAND_EGD + else if (pRandSeed->nSrc == SSL_RSSRC_EGD) { + /* + * seed in contents provided by the external + * Entropy Gathering Daemon (EGD) + */ + if ((n = RAND_egd(pRandSeed->cpPath)) == -1) + continue; + nDone += n; + } +#endif + else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) { + struct { + time_t t; + pid_t pid; + } my_seed; + + /* + * seed in the current time (usually just 4 bytes) + */ + my_seed.t = time(NULL); + + /* + * seed in the current process id (usually just 4 bytes) + */ + my_seed.pid = mc->pid; + + l = sizeof(my_seed); + RAND_seed((unsigned char *)&my_seed, l); + nDone += l; + + /* + * seed in some current state of the run-time stack (128 bytes) + */ + n = ssl_rand_choosenum(0, sizeof(stackdata)-128-1); + RAND_seed(stackdata+n, 128); + nDone += 128; + + } + } + } + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "%sSeeding PRNG with %d bytes of entropy", prefix, nDone); + + if (RAND_status() == 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "%sPRNG still contains insufficient entropy!", prefix); + + return nDone; +} + +#define BUFSIZE 8192 + +static int ssl_rand_feedfp(apr_pool_t *p, apr_file_t *fp, int nReq) +{ + apr_size_t nDone; + unsigned char caBuf[BUFSIZE]; + apr_size_t nBuf; + apr_size_t nRead; + apr_size_t nTodo; + + nDone = 0; + nRead = BUFSIZE; + nTodo = nReq; + while (1) { + if (nReq > 0) + nRead = (nTodo < BUFSIZE ? nTodo : BUFSIZE); + nBuf = nRead; + if (apr_file_read(fp, caBuf, &nBuf) != APR_SUCCESS) + break; + RAND_seed(caBuf, nBuf); + nDone += nBuf; + if (nReq > 0) { + nTodo -= nBuf; + if (nTodo <= 0) + break; + } + } + return nDone; +} + +static int ssl_rand_choosenum(int l, int h) +{ + int i; + char buf[50]; + + apr_snprintf(buf, sizeof(buf), "%.0f", + (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l))); + i = atoi(buf)+1; + if (i < l) i = l; + if (i > h) i = h; + return i; +} + diff --git a/trunk/modules/ssl/ssl_engine_vars.c b/trunk/modules/ssl/ssl_engine_vars.c new file mode 100644 index 0000000000..69d4b098c3 --- /dev/null +++ b/trunk/modules/ssl/ssl_engine_vars.c @@ -0,0 +1,784 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_engine_vars.c + * Variable Lookup Facility + */ + /* ``Those of you who think they + know everything are very annoying + to those of us who do.'' + -- Unknown */ +#include "ssl_private.h" +#include "mod_ssl.h" + +#include "apr_time.h" + +/* _________________________________________________________________ +** +** Variable Lookup +** _________________________________________________________________ +*/ + +static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var); +static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var); +static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var); +static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm); +static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm); +static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs); +static char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, char *var); +static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs); +static char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, conn_rec *c); +static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, conn_rec *c, char *var); +static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); +static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); + +static int ssl_is_https(conn_rec *c) +{ + SSLConnRec *sslconn = myConnConfig(c); + return sslconn && sslconn->ssl; +} + +void ssl_var_register(void) +{ + APR_REGISTER_OPTIONAL_FN(ssl_is_https); + APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); + APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup); + return; +} + +/* This function must remain safe to use for a non-SSL connection. */ +char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, char *var) +{ + SSLModConfigRec *mc = myModConfig(s); + const char *result; + BOOL resdup; + apr_time_exp_t tm; + + result = NULL; + resdup = TRUE; + + /* + * When no pool is given try to find one + */ + if (p == NULL) { + if (r != NULL) + p = r->pool; + else if (c != NULL) + p = c->pool; + else + p = mc->pPool; + } + + /* + * Request dependent stuff + */ + if (r != NULL) { + switch (var[0]) { + case 'H': + case 'h': + if (strcEQ(var, "HTTP_USER_AGENT")) + result = apr_table_get(r->headers_in, "User-Agent"); + else if (strcEQ(var, "HTTP_REFERER")) + result = apr_table_get(r->headers_in, "Referer"); + else if (strcEQ(var, "HTTP_COOKIE")) + result = apr_table_get(r->headers_in, "Cookie"); + else if (strcEQ(var, "HTTP_FORWARDED")) + result = apr_table_get(r->headers_in, "Forwarded"); + else if (strcEQ(var, "HTTP_HOST")) + result = apr_table_get(r->headers_in, "Host"); + else if (strcEQ(var, "HTTP_PROXY_CONNECTION")) + result = apr_table_get(r->headers_in, "Proxy-Connection"); + else if (strcEQ(var, "HTTP_ACCEPT")) + result = apr_table_get(r->headers_in, "Accept"); + else if (strlen(var) > 5 && strcEQn(var, "HTTP:", 5)) + /* all other headers from which we are still not know about */ + result = apr_table_get(r->headers_in, var+5); + break; + + case 'R': + case 'r': + if (strcEQ(var, "REQUEST_METHOD")) + result = r->method; + else if (strcEQ(var, "REQUEST_SCHEME")) + result = ap_http_scheme(r); + else if (strcEQ(var, "REQUEST_URI")) + result = r->uri; + else if (strcEQ(var, "REQUEST_FILENAME")) + result = r->filename; + else if (strcEQ(var, "REMOTE_HOST")) + result = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME, NULL); + else if (strcEQ(var, "REMOTE_IDENT")) + result = ap_get_remote_logname(r); + else if (strcEQ(var, "REMOTE_USER")) + result = r->user; + break; + + case 'S': + case 's': + if (strcEQn(var, "SSL", 3)) break; /* shortcut common case */ + + if (strcEQ(var, "SERVER_ADMIN")) + result = r->server->server_admin; + else if (strcEQ(var, "SERVER_NAME")) + result = ap_get_server_name(r); + else if (strcEQ(var, "SERVER_PORT")) + result = apr_psprintf(p, "%u", ap_get_server_port(r)); + else if (strcEQ(var, "SERVER_PROTOCOL")) + result = r->protocol; + else if (strcEQ(var, "SCRIPT_FILENAME")) + result = r->filename; + break; + + default: + if (strcEQ(var, "PATH_INFO")) + result = r->path_info; + else if (strcEQ(var, "QUERY_STRING")) + result = r->args; + else if (strcEQ(var, "IS_SUBREQ")) + result = (r->main != NULL ? "true" : "false"); + else if (strcEQ(var, "DOCUMENT_ROOT")) + result = ap_document_root(r); + else if (strcEQ(var, "AUTH_TYPE")) + result = r->ap_auth_type; + else if (strcEQ(var, "THE_REQUEST")) + result = r->the_request; + break; + } + } + + /* + * Connection stuff + */ + if (result == NULL && c != NULL) { + SSLConnRec *sslconn = myConnConfig(c); + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4) + && sslconn && sslconn->ssl) + result = ssl_var_lookup_ssl(p, c, var+4); + else if (strcEQ(var, "REMOTE_ADDR")) + result = c->remote_ip; + else if (strcEQ(var, "HTTPS")) { + if (sslconn && sslconn->ssl) + result = "on"; + else + result = "off"; + } + } + + /* + * Totally independent stuff + */ + if (result == NULL) { + if (strlen(var) > 12 && strcEQn(var, "SSL_VERSION_", 12)) + result = ssl_var_lookup_ssl_version(p, var+12); + else if (strcEQ(var, "SERVER_SOFTWARE")) + result = ap_get_server_version(); + else if (strcEQ(var, "API_VERSION")) { + result = apr_itoa(p, MODULE_MAGIC_NUMBER); + resdup = FALSE; + } + else if (strcEQ(var, "TIME_YEAR")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, "%02d%02d", + (tm.tm_year / 100) + 19, tm.tm_year % 100); + resdup = FALSE; + } +#define MKTIMESTR(format, tmfield) \ + apr_time_exp_lt(&tm, apr_time_now()); \ + result = apr_psprintf(p, format, tm.tmfield); \ + resdup = FALSE; + else if (strcEQ(var, "TIME_MON")) { + MKTIMESTR("%02d", tm_mon+1) + } + else if (strcEQ(var, "TIME_DAY")) { + MKTIMESTR("%02d", tm_mday) + } + else if (strcEQ(var, "TIME_HOUR")) { + MKTIMESTR("%02d", tm_hour) + } + else if (strcEQ(var, "TIME_MIN")) { + MKTIMESTR("%02d", tm_min) + } + else if (strcEQ(var, "TIME_SEC")) { + MKTIMESTR("%02d", tm_sec) + } + else if (strcEQ(var, "TIME_WDAY")) { + MKTIMESTR("%d", tm_wday) + } + else if (strcEQ(var, "TIME")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, + "%02d%02d%02d%02d%02d%02d%02d", (tm.tm_year / 100) + 19, + (tm.tm_year % 100), tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + resdup = FALSE; + } + /* all other env-variables from the parent Apache process */ + else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) { + result = apr_table_get(r->notes, var+4); + if (result == NULL) + result = apr_table_get(r->subprocess_env, var+4); + if (result == NULL) + result = getenv(var+4); + } + } + + if (result != NULL && resdup) + result = apr_pstrdup(p, result); + if (result == NULL) + result = ""; + return (char *)result; +} + +static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var) +{ + SSLConnRec *sslconn = myConnConfig(c); + char *result; + X509 *xs; + STACK_OF(X509) *sk; + SSL *ssl; + + result = NULL; + + ssl = sslconn->ssl; + if (strlen(var) > 8 && strcEQn(var, "VERSION_", 8)) { + result = ssl_var_lookup_ssl_version(p, var+8); + } + else if (ssl != NULL && strcEQ(var, "PROTOCOL")) { + result = (char *)SSL_get_version(ssl); + } + else if (ssl != NULL && strcEQ(var, "SESSION_ID")) { + char buf[SSL_SESSION_ID_STRING_LEN]; + SSL_SESSION *pSession = SSL_get_session(ssl); + if (pSession) { + result = apr_pstrdup(p, SSL_SESSION_id2sz( + SSL_SESSION_get_session_id(pSession), + SSL_SESSION_get_session_id_length(pSession), + buf, sizeof(buf))); + } + } + else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) { + result = ssl_var_lookup_ssl_cipher(p, c, var+6); + } + else if (ssl != NULL && strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) { + sk = SSL_get_peer_cert_chain(ssl); + result = ssl_var_lookup_ssl_cert_chain(p, sk, var+18); + } + else if (ssl != NULL && strcEQ(var, "CLIENT_VERIFY")) { + result = ssl_var_lookup_ssl_cert_verify(p, c); + } + else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) { + if ((xs = SSL_get_peer_certificate(ssl)) != NULL) { + result = ssl_var_lookup_ssl_cert(p, xs, var+7); + X509_free(xs); + } + } + else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) { + if ((xs = SSL_get_certificate(ssl)) != NULL) + result = ssl_var_lookup_ssl_cert(p, xs, var+7); + } + return result; +} + +static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var) +{ + char *result; + BOOL resdup; + X509_NAME *xsname; + int nid; + char *cp; + + result = NULL; + resdup = TRUE; + + if (strcEQ(var, "M_VERSION")) { + result = apr_psprintf(p, "%lu", X509_get_version(xs)+1); + resdup = FALSE; + } + else if (strcEQ(var, "M_SERIAL")) { + result = ssl_var_lookup_ssl_cert_serial(p, xs); + } + else if (strcEQ(var, "V_START")) { + result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notBefore(xs)); + } + else if (strcEQ(var, "V_END")) { + result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs)); + } + else if (strcEQ(var, "V_REMAIN")) { + result = ssl_var_lookup_ssl_cert_remain(p, X509_get_notAfter(xs)); + resdup = FALSE; + } + else if (strcEQ(var, "S_DN")) { + xsname = X509_get_subject_name(xs); + cp = X509_NAME_oneline(xsname, NULL, 0); + result = apr_pstrdup(p, cp); + modssl_free(cp); + resdup = FALSE; + } + else if (strlen(var) > 5 && strcEQn(var, "S_DN_", 5)) { + xsname = X509_get_subject_name(xs); + result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5); + resdup = FALSE; + } + else if (strcEQ(var, "I_DN")) { + xsname = X509_get_issuer_name(xs); + cp = X509_NAME_oneline(xsname, NULL, 0); + result = apr_pstrdup(p, cp); + modssl_free(cp); + resdup = FALSE; + } + else if (strlen(var) > 5 && strcEQn(var, "I_DN_", 5)) { + xsname = X509_get_issuer_name(xs); + result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5); + resdup = FALSE; + } + else if (strcEQ(var, "A_SIG")) { + nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_signature_algorithm(xs)); + result = apr_pstrdup(p, + (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); + resdup = FALSE; + } + else if (strcEQ(var, "A_KEY")) { + nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_key_algorithm(xs)); + result = apr_pstrdup(p, + (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); + resdup = FALSE; + } + else if (strcEQ(var, "CERT")) { + result = ssl_var_lookup_ssl_cert_PEM(p, xs); + } + + if (result != NULL && resdup) + result = apr_pstrdup(p, result); + return result; +} + +static const struct { + char *name; + int nid; +} ssl_var_lookup_ssl_cert_dn_rec[] = { + { "C", NID_countryName }, + { "ST", NID_stateOrProvinceName }, /* officially (RFC2156) */ + { "SP", NID_stateOrProvinceName }, /* compatibility (SSLeay) */ + { "L", NID_localityName }, + { "O", NID_organizationName }, + { "OU", NID_organizationalUnitName }, + { "CN", NID_commonName }, + { "T", NID_title }, + { "I", NID_initials }, + { "G", NID_givenName }, + { "S", NID_surname }, + { "D", NID_description }, +#ifdef NID_x500UniqueIdentifier /* new name as of Openssl 0.9.7 */ + { "UID", NID_x500UniqueIdentifier }, +#else /* old name, OpenSSL < 0.9.7 */ + { "UID", NID_uniqueIdentifier }, +#endif + { "Email", NID_pkcs9_emailAddress }, + { NULL, 0 } +}; + +static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var) +{ + char *result, *ptr; + X509_NAME_ENTRY *xsne; + int i, j, n, idx = 0; + apr_size_t varlen; + + /* if an _N suffix is used, find the Nth attribute of given name */ + ptr = strchr(var, '_'); + if (ptr != NULL && strspn(ptr + 1, "0123456789") == strlen(ptr + 1)) { + idx = atoi(ptr + 1); + varlen = ptr - var; + } else { + varlen = strlen(var); + } + + result = NULL; + + for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) { + if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen) + && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) { + for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *) + X509_NAME_get_entries(xsname)); + j++) { + xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *) + X509_NAME_get_entries(xsname), j); + + n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); + + if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) { + result = apr_pstrmemdup(p, + X509_NAME_ENTRY_get_data_ptr(xsne), + X509_NAME_ENTRY_get_data_len(xsne)); +#if APR_CHARSET_EBCDIC + ap_xlate_proto_from_ascii(result, X509_NAME_ENTRY_get_data_len(xsne)); +#endif /* APR_CHARSET_EBCDIC */ + break; + } + } + break; + } + } + return result; +} + +static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm) +{ + char *result; + BIO* bio; + int n; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return NULL; + ASN1_UTCTIME_print(bio, tm); + n = BIO_pending(bio); + result = apr_pcalloc(p, n+1); + n = BIO_read(bio, result, n); + result[n] = NUL; + BIO_free(bio); + return result; +} + +#define DIGIT2NUM(x) (((x)[0] - '0') * 10 + (x)[1] - '0') + +/* Return a string giving the number of days remaining until 'tm', or + * "0" if this can't be determined. */ +static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm) +{ + apr_time_t then, now = apr_time_now(); + apr_time_exp_t exp = {0}; + long diff; + + /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates + * that the seconds digits are present even though ASN.1 + * doesn't. */ + if (tm->length < 11 || !ASN1_UTCTIME_check(tm)) { + return apr_pstrdup(p, "0"); + } + + exp.tm_year = DIGIT2NUM(tm->data); + exp.tm_mon = DIGIT2NUM(tm->data + 2) - 1; + exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1; + exp.tm_hour = DIGIT2NUM(tm->data + 6); + exp.tm_min = DIGIT2NUM(tm->data + 8); + exp.tm_sec = DIGIT2NUM(tm->data + 10); + + if (exp.tm_year <= 50) exp.tm_year += 100; + + if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS) { + return apr_pstrdup(p, "0"); + } + + diff = (long)((apr_time_sec(then) - apr_time_sec(now)) / (60*60*24)); + + return diff > 0 ? apr_ltoa(p, diff) : apr_pstrdup(p, "0"); +} + +static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs) +{ + char *result; + BIO *bio; + int n; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return NULL; + i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs)); + n = BIO_pending(bio); + result = apr_pcalloc(p, n+1); + n = BIO_read(bio, result, n); + result[n] = NUL; + BIO_free(bio); + return result; +} + +static char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, char *var) +{ + char *result; + X509 *xs; + int n; + + result = NULL; + + if (strspn(var, "0123456789") == strlen(var)) { + n = atoi(var); + if (n < sk_X509_num(sk)) { + xs = sk_X509_value(sk, n); + result = ssl_var_lookup_ssl_cert_PEM(p, xs); + } + } + + return result; +} + +static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs) +{ + char *result; + BIO *bio; + int n; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) + return NULL; + PEM_write_bio_X509(bio, xs); + n = BIO_pending(bio); + result = apr_pcalloc(p, n+1); + n = BIO_read(bio, result, n); + result[n] = NUL; + BIO_free(bio); + return result; +} + +static char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, conn_rec *c) +{ + SSLConnRec *sslconn = myConnConfig(c); + char *result; + long vrc; + const char *verr; + const char *vinfo; + SSL *ssl; + X509 *xs; + + result = NULL; + ssl = sslconn->ssl; + verr = sslconn->verify_error; + vinfo = sslconn->verify_info; + vrc = SSL_get_verify_result(ssl); + xs = SSL_get_peer_certificate(ssl); + + if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL) + /* no client verification done at all */ + result = "NONE"; + else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL) + /* client verification done successful */ + result = "SUCCESS"; + else if (vrc == X509_V_OK && vinfo != NULL && strEQ(vinfo, "GENEROUS")) + /* client verification done in generous way */ + result = "GENEROUS"; + else + /* client verification failed */ + result = apr_psprintf(p, "FAILED:%s", verr); + + if (xs) + X509_free(xs); + return result; +} + +static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, conn_rec *c, char *var) +{ + SSLConnRec *sslconn = myConnConfig(c); + char *result; + BOOL resdup; + int usekeysize, algkeysize; + SSL *ssl; + + result = NULL; + resdup = TRUE; + + ssl = sslconn->ssl; + ssl_var_lookup_ssl_cipher_bits(ssl, &usekeysize, &algkeysize); + + if (ssl && strEQ(var, "")) { + SSL_CIPHER *cipher = SSL_get_current_cipher(ssl); + result = (cipher != NULL ? (char *)SSL_CIPHER_get_name(cipher) : NULL); + } + else if (strcEQ(var, "_EXPORT")) + result = (usekeysize < 56 ? "true" : "false"); + else if (strcEQ(var, "_USEKEYSIZE")) { + result = apr_itoa(p, usekeysize); + resdup = FALSE; + } + else if (strcEQ(var, "_ALGKEYSIZE")) { + result = apr_itoa(p, algkeysize); + resdup = FALSE; + } + + if (result != NULL && resdup) + result = apr_pstrdup(p, result); + return result; +} + +static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize) +{ + SSL_CIPHER *cipher; + + *usekeysize = 0; + *algkeysize = 0; + if (ssl != NULL) + if ((cipher = SSL_get_current_cipher(ssl)) != NULL) + *usekeysize = SSL_CIPHER_get_bits(cipher, algkeysize); + return; +} + +static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var) +{ + char *result; + char *cp, *cp2; + + result = NULL; + + if (strEQ(var, "PRODUCT")) { +#if defined(SSL_PRODUCT_NAME) && defined(SSL_PRODUCT_VERSION) + result = apr_psprintf(p, "%s/%s", SSL_PRODUCT_NAME, SSL_PRODUCT_VERSION); +#else + result = NULL; +#endif + } + else if (strEQ(var, "INTERFACE")) { + result = apr_psprintf(p, "mod_ssl/%s", MOD_SSL_VERSION); + } + else if (strEQ(var, "LIBRARY")) { + result = apr_pstrdup(p, SSLeay_version(SSLEAY_VERSION)); + if ((cp = strchr(result, ' ')) != NULL) { + *cp = '/'; + if ((cp2 = strchr(cp, ' ')) != NULL) + *cp2 = NUL; + } + } + return result; +} + +const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, + const char *oidnum) +{ + SSLConnRec *sslconn = myConnConfig(c); + SSL *ssl; + X509 *xs = NULL; + ASN1_OBJECT *oid; + int count = 0, j; + char *result = NULL; + + if (!sslconn || !sslconn->ssl) { + return NULL; + } + ssl = sslconn->ssl; + + oid = OBJ_txt2obj(oidnum, 1); + if (!oid) { + ERR_clear_error(); + return NULL; + } + + xs = peer ? SSL_get_peer_certificate(ssl) : SSL_get_certificate(ssl); + if (xs == NULL) { + return NULL; + } + + count = X509_get_ext_count(xs); + + for (j = 0; j < count; j++) { + X509_EXTENSION *ext = X509_get_ext(xs, j); + + if (OBJ_cmp(ext->object, oid) == 0) { + BIO *bio = BIO_new(BIO_s_mem()); + + if (X509V3_EXT_print(bio, ext, 0, 0) == 1) { + BUF_MEM *buf; + + BIO_get_mem_ptr(bio, &buf); + result = apr_pstrmemdup(p, buf->data, buf->length); + } + + BIO_vfree(bio); + break; + } + } + + if (peer) { + /* only SSL_get_peer_certificate raises the refcount */ + X509_free(xs); + } + + ERR_clear_error(); + return result; +} + +/* _________________________________________________________________ +** +** SSL Extension to mod_log_config +** _________________________________________________________________ +*/ + +#include "../../modules/loggers/mod_log_config.h" + +static const char *ssl_var_log_handler_c(request_rec *r, char *a); +static const char *ssl_var_log_handler_x(request_rec *r, char *a); + +/* + * register us for the mod_log_config function registering phase + * to establish %{...}c and to be able to expand %{...}x variables. + */ +void ssl_var_log_config_register(apr_pool_t *p) +{ + static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register; + + log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler); + + if (log_pfn_register) { + log_pfn_register(p, "c", ssl_var_log_handler_c, 0); + log_pfn_register(p, "x", ssl_var_log_handler_x, 0); + } + return; +} + +/* + * implement the %{..}c log function + * (we are the only function) + */ +static const char *ssl_var_log_handler_c(request_rec *r, char *a) +{ + SSLConnRec *sslconn = myConnConfig(r->connection); + char *result; + + if (sslconn == NULL || sslconn->ssl == NULL) + return NULL; + result = NULL; + if (strEQ(a, "version")) + result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_PROTOCOL"); + else if (strEQ(a, "cipher")) + result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); + else if (strEQ(a, "subjectdn") || strEQ(a, "clientcert")) + result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_S_DN"); + else if (strEQ(a, "issuerdn") || strEQ(a, "cacert")) + result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_I_DN"); + else if (strEQ(a, "errcode")) + result = "-"; + else if (strEQ(a, "errstr")) + result = (char *)sslconn->verify_error; + if (result != NULL && result[0] == NUL) + result = NULL; + return result; +} + +/* + * extend the implementation of the %{..}x log function + * (there can be more functions) + */ +static const char *ssl_var_log_handler_x(request_rec *r, char *a) +{ + char *result; + + result = ssl_var_lookup(r->pool, r->server, r->connection, r, a); + if (result != NULL && result[0] == NUL) + result = NULL; + return result; +} + diff --git a/trunk/modules/ssl/ssl_expr.c b/trunk/modules/ssl/ssl_expr.c new file mode 100644 index 0000000000..f45d959d67 --- /dev/null +++ b/trunk/modules/ssl/ssl_expr.c @@ -0,0 +1,82 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_expr.c + * Expression Handling + */ + /* ``It is hard to fly with + the eagles when you work + with the turkeys.'' + -- Unknown */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Expression Handling +** _________________________________________________________________ +*/ + +ssl_expr_info_type ssl_expr_info; +char *ssl_expr_error; + +ssl_expr *ssl_expr_comp(apr_pool_t *p, char *expr) +{ + ssl_expr_info.pool = p; + ssl_expr_info.inputbuf = expr; + ssl_expr_info.inputlen = strlen(expr); + ssl_expr_info.inputptr = ssl_expr_info.inputbuf; + ssl_expr_info.expr = FALSE; + + ssl_expr_error = NULL; + if (ssl_expr_yyparse()) + return NULL; + return ssl_expr_info.expr; +} + +char *ssl_expr_get_error(void) +{ + if (ssl_expr_error == NULL) + return ""; + return ssl_expr_error; +} + +ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *a1, void *a2) +{ + ssl_expr *node; + + node = (ssl_expr *)apr_palloc(ssl_expr_info.pool, sizeof(ssl_expr)); + node->node_op = op; + node->node_arg1 = (char *)a1; + node->node_arg2 = (char *)a2; + return node; +} + +int ssl_expr_exec(request_rec *r, ssl_expr *expr) +{ + BOOL rc; + + rc = ssl_expr_eval(r, expr); + if (ssl_expr_error != NULL) + return (-1); + else + return (rc ? 1 : 0); +} diff --git a/trunk/modules/ssl/ssl_expr.h b/trunk/modules/ssl/ssl_expr.h new file mode 100644 index 0000000000..55f2e18230 --- /dev/null +++ b/trunk/modules/ssl/ssl_expr.h @@ -0,0 +1,104 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_expr.h + * Expression Handling (Header) + */ + /* ``May all your PUSHes be POPed.'' */ + +#ifndef __SSL_EXPR_H__ +#define __SSL_EXPR_H__ + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE !FALSE +#endif + +#ifndef YY_NULL +#define YY_NULL 0 +#endif + +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef BOOL +#define BOOL unsigned int +#endif + +#ifndef NULL +#define NULL (void *)0 +#endif + +#ifndef NUL +#define NUL '\0' +#endif + +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif + +typedef enum { + op_NOP, op_ListElement, + op_True, op_False, op_Not, op_Or, op_And, op_Comp, + op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE, + op_Digit, op_String, op_Regex, op_Var, op_Func +} ssl_expr_node_op; + +typedef struct { + ssl_expr_node_op node_op; + void *node_arg1; + void *node_arg2; + apr_pool_t *p; +} ssl_expr_node; + +typedef ssl_expr_node ssl_expr; + +typedef struct { + apr_pool_t *pool; + char *inputbuf; + int inputlen; + char *inputptr; + ssl_expr *expr; +} ssl_expr_info_type; + +extern ssl_expr_info_type ssl_expr_info; +extern char *ssl_expr_error; + +#define yylval ssl_expr_yylval +#define yyerror ssl_expr_yyerror +#define yyinput ssl_expr_yyinput + +extern int ssl_expr_yyparse(void); +extern int ssl_expr_yyerror(char *); +extern int ssl_expr_yylex(void); + +extern ssl_expr *ssl_expr_comp(apr_pool_t *, char *); +extern int ssl_expr_exec(request_rec *, ssl_expr *); +extern char *ssl_expr_get_error(void); +extern ssl_expr *ssl_expr_make(ssl_expr_node_op, void *, void *); +extern BOOL ssl_expr_eval(request_rec *, ssl_expr *); + +#endif /* __SSL_EXPR_H__ */ diff --git a/trunk/modules/ssl/ssl_expr_eval.c b/trunk/modules/ssl/ssl_expr_eval.c new file mode 100644 index 0000000000..2b3adc8402 --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_eval.c @@ -0,0 +1,254 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_expr_eval.c + * Expression Evaluation + */ + /* ``Make love, + not software!'' + -- Unknown */ +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Expression Evaluation +** _________________________________________________________________ +*/ + +static BOOL ssl_expr_eval_comp(request_rec *, ssl_expr *); +static char *ssl_expr_eval_word(request_rec *, ssl_expr *); +static char *ssl_expr_eval_func_file(request_rec *, char *); +static int ssl_expr_eval_strcmplex(char *, char *); + +BOOL ssl_expr_eval(request_rec *r, ssl_expr *node) +{ + switch (node->node_op) { + case op_True: { + return TRUE; + } + case op_False: { + return FALSE; + } + case op_Not: { + ssl_expr *e = (ssl_expr *)node->node_arg1; + return (!ssl_expr_eval(r, e)); + } + case op_Or: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval(r, e1) || ssl_expr_eval(r, e2)); + } + case op_And: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval(r, e1) && ssl_expr_eval(r, e2)); + } + case op_Comp: { + ssl_expr *e = (ssl_expr *)node->node_arg1; + return ssl_expr_eval_comp(r, e); + } + default: { + ssl_expr_error = "Internal evaluation error: Unknown expression node"; + return FALSE; + } + } +} + +static BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node) +{ + switch (node->node_op) { + case op_EQ: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) == 0); + } + case op_NE: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) != 0); + } + case op_LT: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) < 0); + } + case op_LE: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) <= 0); + } + case op_GT: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) > 0); + } + case op_GE: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) >= 0); + } + case op_IN: { + ssl_expr *e1 = (ssl_expr *)node->node_arg1; + ssl_expr *e2 = (ssl_expr *)node->node_arg2; + ssl_expr *e3; + char *w1 = ssl_expr_eval_word(r, e1); + BOOL found = FALSE; + do { + e3 = (ssl_expr *)e2->node_arg1; + e2 = (ssl_expr *)e2->node_arg2; + if (strcmp(w1, ssl_expr_eval_word(r, e3)) == 0) { + found = TRUE; + break; + } + } while (e2 != NULL); + return found; + } + case op_REG: { + ssl_expr *e1; + ssl_expr *e2; + char *word; + ap_regex_t *regex; + + e1 = (ssl_expr *)node->node_arg1; + e2 = (ssl_expr *)node->node_arg2; + word = ssl_expr_eval_word(r, e1); + regex = (ap_regex_t *)(e2->node_arg1); + return (ap_regexec(regex, word, 0, NULL, 0) == 0); + } + case op_NRE: { + ssl_expr *e1; + ssl_expr *e2; + char *word; + ap_regex_t *regex; + + e1 = (ssl_expr *)node->node_arg1; + e2 = (ssl_expr *)node->node_arg2; + word = ssl_expr_eval_word(r, e1); + regex = (ap_regex_t *)(e2->node_arg1); + return !(ap_regexec(regex, word, 0, NULL, 0) == 0); + } + default: { + ssl_expr_error = "Internal evaluation error: Unknown expression node"; + return FALSE; + } + } +} + +static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node) +{ + switch (node->node_op) { + case op_Digit: { + char *string = (char *)node->node_arg1; + return string; + } + case op_String: { + char *string = (char *)node->node_arg1; + return string; + } + case op_Var: { + char *var = (char *)node->node_arg1; + char *val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); + return (val == NULL ? "" : val); + } + case op_Func: { + char *name = (char *)node->node_arg1; + ssl_expr *args = (ssl_expr *)node->node_arg2; + if (strEQ(name, "file")) + return ssl_expr_eval_func_file(r, (char *)(args->node_arg1)); + else { + ssl_expr_error = "Internal evaluation error: Unknown function name"; + return ""; + } + } + default: { + ssl_expr_error = "Internal evaluation error: Unknown expression node"; + return FALSE; + } + } +} + +static char *ssl_expr_eval_func_file(request_rec *r, char *filename) +{ + apr_file_t *fp; + char *buf; + apr_off_t offset; + apr_size_t len; + apr_finfo_t finfo; + + if (apr_file_open(&fp, filename, APR_READ|APR_BUFFERED, + APR_OS_DEFAULT, r->pool) != APR_SUCCESS) { + ssl_expr_error = "Cannot open file"; + return ""; + } + apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); + if ((finfo.size + 1) != ((apr_size_t)finfo.size + 1)) { + ssl_expr_error = "Huge file cannot be read"; + apr_file_close(fp); + return ""; + } + len = (apr_size_t)finfo.size; + if (len == 0) { + buf = (char *)apr_palloc(r->pool, sizeof(char) * 1); + *buf = NUL; + } + else { + if ((buf = (char *)apr_palloc(r->pool, sizeof(char)*(len+1))) == NULL) { + ssl_expr_error = "Cannot allocate memory"; + apr_file_close(fp); + return ""; + } + offset = 0; + apr_file_seek(fp, APR_SET, &offset); + if (apr_file_read(fp, buf, &len) != APR_SUCCESS) { + ssl_expr_error = "Cannot read from file"; + apr_file_close(fp); + return ""; + } + buf[len] = NUL; + } + apr_file_close(fp); + return buf; +} + +/* a variant of strcmp(3) which works correctly also for number strings */ +static int ssl_expr_eval_strcmplex(char *cpNum1, char *cpNum2) +{ + int i, n1, n2; + + if (cpNum1 == NULL) + return -1; + if (cpNum2 == NULL) + return +1; + n1 = strlen(cpNum1); + n2 = strlen(cpNum2); + if (n1 > n2) + return 1; + if (n1 < n2) + return -1; + for (i = 0; i < n1; i++) { + if (cpNum1[i] > cpNum2[i]) + return 1; + if (cpNum1[i] < cpNum2[i]) + return -1; + } + return 0; +} diff --git a/trunk/modules/ssl/ssl_expr_parse.c b/trunk/modules/ssl/ssl_expr_parse.c new file mode 100644 index 0000000000..6abb56fdfd --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_parse.c @@ -0,0 +1,1081 @@ + +/* A Bison parser, made from ssl_expr_parse.y + by GNU Bison version 1.28 */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define T_TRUE 257 +#define T_FALSE 258 +#define T_DIGIT 259 +#define T_ID 260 +#define T_STRING 261 +#define T_REGEX 262 +#define T_REGEX_I 263 +#define T_FUNC_FILE 264 +#define T_OP_EQ 265 +#define T_OP_NE 266 +#define T_OP_LT 267 +#define T_OP_LE 268 +#define T_OP_GT 269 +#define T_OP_GE 270 +#define T_OP_REG 271 +#define T_OP_NRE 272 +#define T_OP_IN 273 +#define T_OP_OR 274 +#define T_OP_AND 275 +#define T_OP_NOT 276 + +#line 68 "ssl_expr_parse.y" + +#include "ssl_private.h" + +#line 72 "ssl_expr_parse.y" +typedef union { + char *cpVal; + ssl_expr *exVal; +} YYSTYPE; +#include + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 53 +#define YYFLAG -32768 +#define YYNTBASE 29 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? ssl_expr_yytranslate[x] : 36) + +static const char ssl_expr_yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 28, 2, 2, 23, + 24, 2, 2, 27, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 25, 2, 26, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22 +}; + +#if YYDEBUG != 0 +static const short ssl_expr_yyprhs[] = { 0, + 0, 2, 4, 6, 9, 13, 17, 19, 23, 27, + 31, 35, 39, 43, 47, 53, 57, 61, 63, 67, + 69, 71, 76, 78, 80, 82 +}; + +static const short ssl_expr_yyrhs[] = { 30, + 0, 3, 0, 4, 0, 22, 30, 0, 30, 20, + 30, 0, 30, 21, 30, 0, 31, 0, 23, 30, + 24, 0, 33, 11, 33, 0, 33, 12, 33, 0, + 33, 13, 33, 0, 33, 14, 33, 0, 33, 15, + 33, 0, 33, 16, 33, 0, 33, 19, 25, 32, + 26, 0, 33, 17, 34, 0, 33, 18, 34, 0, + 33, 0, 32, 27, 33, 0, 5, 0, 7, 0, + 28, 25, 6, 26, 0, 35, 0, 8, 0, 9, + 0, 10, 23, 7, 24, 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short ssl_expr_yyrline[] = { 0, + 115, 118, 119, 120, 121, 122, 123, 124, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 138, 139, 142, + 143, 144, 145, 148, 158, 170 +}; +#endif + + +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const ssl_expr_yytname[] = { "$","error","$undefined.","T_TRUE", +"T_FALSE","T_DIGIT","T_ID","T_STRING","T_REGEX","T_REGEX_I","T_FUNC_FILE","T_OP_EQ", +"T_OP_NE","T_OP_LT","T_OP_LE","T_OP_GT","T_OP_GE","T_OP_REG","T_OP_NRE","T_OP_IN", +"T_OP_OR","T_OP_AND","T_OP_NOT","'('","')'","'{'","'}'","','","'%'","root","expr", +"comparison","words","word","regex","funccall", NULL +}; +#endif + +static const short ssl_expr_yyr1[] = { 0, + 29, 30, 30, 30, 30, 30, 30, 30, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 32, 32, 33, + 33, 33, 33, 34, 34, 35 +}; + +static const short ssl_expr_yyr2[] = { 0, + 1, 1, 1, 2, 3, 3, 1, 3, 3, 3, + 3, 3, 3, 3, 5, 3, 3, 1, 3, 1, + 1, 4, 1, 1, 1, 4 +}; + +static const short ssl_expr_yydefact[] = { 0, + 2, 3, 20, 21, 0, 0, 0, 0, 1, 7, + 0, 23, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 5, 6, 9, 10, 11, 12, 13, 14, 24, 25, + 16, 17, 0, 26, 22, 0, 18, 15, 0, 19, + 0, 0, 0 +}; + +static const short ssl_expr_yydefgoto[] = { 51, + 9, 10, 46, 11, 41, 12 +}; + +static const short ssl_expr_yypact[] = { 3, +-32768,-32768,-32768,-32768, -11, 3, 3, -10, 0,-32768, + 22,-32768, 16,-32768, -2, 23, 3, 3, 4, 4, + 4, 4, 4, 4, 34, 34, 21, 24,-32768, 25, + 26,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, 4,-32768,-32768, 18,-32768,-32768, 4,-32768, + 49, 50,-32768 +}; + +static const short ssl_expr_yypgoto[] = {-32768, + 10,-32768,-32768, -19, 27,-32768 +}; + + +#define YYLAST 53 + + +static const short ssl_expr_yytable[] = { 33, + 34, 35, 36, 37, 38, 1, 2, 3, 3, 4, + 4, 13, 5, 5, 16, 14, 15, 17, 18, 17, + 18, 29, 28, 47, 6, 7, 31, 32, 30, 50, + 8, 8, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 39, 40, 48, 49, 43, 18, 44, 52, 53, + 45, 0, 42 +}; + +static const short ssl_expr_yycheck[] = { 19, + 20, 21, 22, 23, 24, 3, 4, 5, 5, 7, + 7, 23, 10, 10, 25, 6, 7, 20, 21, 20, + 21, 24, 7, 43, 22, 23, 17, 18, 6, 49, + 28, 28, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 8, 9, 26, 27, 25, 21, 24, 0, 0, + 26, -1, 26 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/local/share/bison.simple" +/* This file comes from bison-1.28. */ + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +#ifndef YYSTACK_USE_ALLOCA +#ifdef alloca +#define YYSTACK_USE_ALLOCA +#else /* alloca not defined */ +#ifdef __GNUC__ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) +#define YYSTACK_USE_ALLOCA +#include +#else /* not sparc */ +/* We think this test detects Watcom and Microsoft C. */ +/* This used to test MSDOS, but that is a bad idea + since that symbol is in the user namespace. */ +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) +#if 0 /* No need for malloc.h, which pollutes the namespace; + instead, just don't use alloca. */ +#include +#endif +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +/* I don't know what this was needed for, but it pollutes the namespace. + So I turned it off. rms, 2 May 1997. */ +/* #include */ +#pragma alloca +#define YYSTACK_USE_ALLOCA +#else /* not MSDOS, or __TURBOC__, or _AIX */ +#if 0 +#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, + and on HPUX 10. Eventually we can turn this on. */ +#define YYSTACK_USE_ALLOCA +#define alloca __builtin_alloca +#endif /* __hpux */ +#endif +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc */ +#endif /* not GNU C */ +#endif /* alloca not defined */ +#endif /* YYSTACK_USE_ALLOCA not defined */ + +#ifdef YYSTACK_USE_ALLOCA +#define YYSTACK_ALLOC alloca +#else +#define YYSTACK_ALLOC malloc +#endif + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define ssl_expr_yyerrok (ssl_expr_yyerrstatus = 0) +#define ssl_expr_yyclearin (ssl_expr_yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT goto ssl_expr_yyacceptlab +#define YYABORT goto ssl_expr_yyabortlab +#define YYERROR goto ssl_expr_yyerrlab1 +/* Like YYERROR except do call ssl_expr_yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto ssl_expr_yyerrlab +#define YYRECOVERING() (!!ssl_expr_yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (ssl_expr_yychar == YYEMPTY && ssl_expr_yylen == 1) \ + { ssl_expr_yychar = (token), ssl_expr_yylval = (value); \ + ssl_expr_yychar1 = YYTRANSLATE (ssl_expr_yychar); \ + YYPOPSTACK; \ + goto ssl_expr_yybackup; \ + } \ + else \ + { ssl_expr_yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX ssl_expr_yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX ssl_expr_yylex(&ssl_expr_yylval, &ssl_expr_yylloc, YYLEX_PARAM) +#else +#define YYLEX ssl_expr_yylex(&ssl_expr_yylval, &ssl_expr_yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX ssl_expr_yylex(&ssl_expr_yylval, YYLEX_PARAM) +#else +#define YYLEX ssl_expr_yylex(&ssl_expr_yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int ssl_expr_yychar; /* the lookahead symbol */ +YYSTYPE ssl_expr_yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE ssl_expr_yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int ssl_expr_yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int ssl_expr_yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Define __ssl_expr_yy_memcpy. Note that the size argument + should be passed with type unsigned int, because that is what the non-GCC + definitions require. With GCC, __builtin_memcpy takes an arg + of type size_t, but it can handle unsigned int. */ + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __ssl_expr_yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__ssl_expr_yy_memcpy (to, from, count) + char *to; + char *from; + unsigned int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__ssl_expr_yy_memcpy (char *to, char *from, unsigned int count) +{ + register char *t = to; + register char *f = from; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 217 "/usr/local/share/bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into ssl_expr_yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +#ifdef YYPARSE_PARAM +int ssl_expr_yyparse (void *); +#else +int ssl_expr_yyparse (void); +#endif +#endif + +int +ssl_expr_yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int ssl_expr_yystate; + register int ssl_expr_yyn; + register short *ssl_expr_yyssp; + register YYSTYPE *ssl_expr_yyvsp; + int ssl_expr_yyerrstatus; /* number of tokens to shift before error messages enabled */ + int ssl_expr_yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short ssl_expr_yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE ssl_expr_yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *ssl_expr_yyss = ssl_expr_yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *ssl_expr_yyvs = ssl_expr_yyvsa; /* to allow ssl_expr_yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE ssl_expr_yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *ssl_expr_yyls = ssl_expr_yylsa; + YYLTYPE *ssl_expr_yylsp; + +#define YYPOPSTACK (ssl_expr_yyvsp--, ssl_expr_yyssp--, ssl_expr_yylsp--) +#else +#define YYPOPSTACK (ssl_expr_yyvsp--, ssl_expr_yyssp--) +#endif + + int ssl_expr_yystacksize = YYINITDEPTH; + int ssl_expr_yyfree_stacks = 0; + +#ifdef YYPURE + int ssl_expr_yychar; + YYSTYPE ssl_expr_yylval; + int ssl_expr_yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE ssl_expr_yylloc; +#endif +#endif + + YYSTYPE ssl_expr_yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int ssl_expr_yylen; + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + ssl_expr_yystate = 0; + ssl_expr_yyerrstatus = 0; + ssl_expr_yynerrs = 0; + ssl_expr_yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + ssl_expr_yyssp = ssl_expr_yyss - 1; + ssl_expr_yyvsp = ssl_expr_yyvs; +#ifdef YYLSP_NEEDED + ssl_expr_yylsp = ssl_expr_yyls; +#endif + +/* Push a new state, which is found in ssl_expr_yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +ssl_expr_yynewstate: + + *++ssl_expr_yyssp = ssl_expr_yystate; + + if (ssl_expr_yyssp >= ssl_expr_yyss + ssl_expr_yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *ssl_expr_yyvs1 = ssl_expr_yyvs; + short *ssl_expr_yyss1 = ssl_expr_yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *ssl_expr_yyls1 = ssl_expr_yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = ssl_expr_yyssp - ssl_expr_yyss + 1; + +#ifdef ssl_expr_yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if ssl_expr_yyoverflow is a macro. */ + ssl_expr_yyoverflow("parser stack overflow", + &ssl_expr_yyss1, size * sizeof (*ssl_expr_yyssp), + &ssl_expr_yyvs1, size * sizeof (*ssl_expr_yyvsp), + &ssl_expr_yyls1, size * sizeof (*ssl_expr_yylsp), + &ssl_expr_yystacksize); +#else + ssl_expr_yyoverflow("parser stack overflow", + &ssl_expr_yyss1, size * sizeof (*ssl_expr_yyssp), + &ssl_expr_yyvs1, size * sizeof (*ssl_expr_yyvsp), + &ssl_expr_yystacksize); +#endif + + ssl_expr_yyss = ssl_expr_yyss1; ssl_expr_yyvs = ssl_expr_yyvs1; +#ifdef YYLSP_NEEDED + ssl_expr_yyls = ssl_expr_yyls1; +#endif +#else /* no ssl_expr_yyoverflow */ + /* Extend the stack our own way. */ + if (ssl_expr_yystacksize >= YYMAXDEPTH) + { + ssl_expr_yyerror("parser stack overflow"); + if (ssl_expr_yyfree_stacks) + { + free (ssl_expr_yyss); + free (ssl_expr_yyvs); +#ifdef YYLSP_NEEDED + free (ssl_expr_yyls); +#endif + } + return 2; + } + ssl_expr_yystacksize *= 2; + if (ssl_expr_yystacksize > YYMAXDEPTH) + ssl_expr_yystacksize = YYMAXDEPTH; +#ifndef YYSTACK_USE_ALLOCA + ssl_expr_yyfree_stacks = 1; +#endif + ssl_expr_yyss = (short *) YYSTACK_ALLOC (ssl_expr_yystacksize * sizeof (*ssl_expr_yyssp)); + __ssl_expr_yy_memcpy ((char *)ssl_expr_yyss, (char *)ssl_expr_yyss1, + size * (unsigned int) sizeof (*ssl_expr_yyssp)); + ssl_expr_yyvs = (YYSTYPE *) YYSTACK_ALLOC (ssl_expr_yystacksize * sizeof (*ssl_expr_yyvsp)); + __ssl_expr_yy_memcpy ((char *)ssl_expr_yyvs, (char *)ssl_expr_yyvs1, + size * (unsigned int) sizeof (*ssl_expr_yyvsp)); +#ifdef YYLSP_NEEDED + ssl_expr_yyls = (YYLTYPE *) YYSTACK_ALLOC (ssl_expr_yystacksize * sizeof (*ssl_expr_yylsp)); + __ssl_expr_yy_memcpy ((char *)ssl_expr_yyls, (char *)ssl_expr_yyls1, + size * (unsigned int) sizeof (*ssl_expr_yylsp)); +#endif +#endif /* no ssl_expr_yyoverflow */ + + ssl_expr_yyssp = ssl_expr_yyss + size - 1; + ssl_expr_yyvsp = ssl_expr_yyvs + size - 1; +#ifdef YYLSP_NEEDED + ssl_expr_yylsp = ssl_expr_yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Stack size increased to %d\n", ssl_expr_yystacksize); +#endif + + if (ssl_expr_yyssp >= ssl_expr_yyss + ssl_expr_yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Entering state %d\n", ssl_expr_yystate); +#endif + + goto ssl_expr_yybackup; + ssl_expr_yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* ssl_expr_yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + ssl_expr_yyn = ssl_expr_yypact[ssl_expr_yystate]; + if (ssl_expr_yyn == YYFLAG) + goto ssl_expr_yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* ssl_expr_yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (ssl_expr_yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Reading a token: "); +#endif + ssl_expr_yychar = YYLEX; + } + + /* Convert token to internal form (in ssl_expr_yychar1) for indexing tables with */ + + if (ssl_expr_yychar <= 0) /* This means end of input. */ + { + ssl_expr_yychar1 = 0; + ssl_expr_yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + ssl_expr_yychar1 = YYTRANSLATE(ssl_expr_yychar); + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + { + fprintf (stderr, "Next token is %d (%s", ssl_expr_yychar, ssl_expr_yytname[ssl_expr_yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, ssl_expr_yychar, ssl_expr_yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + ssl_expr_yyn += ssl_expr_yychar1; + if (ssl_expr_yyn < 0 || ssl_expr_yyn > YYLAST || ssl_expr_yycheck[ssl_expr_yyn] != ssl_expr_yychar1) + goto ssl_expr_yydefault; + + ssl_expr_yyn = ssl_expr_yytable[ssl_expr_yyn]; + + /* ssl_expr_yyn is what to do for this token type in this state. + Negative => reduce, -ssl_expr_yyn is rule number. + Positive => shift, ssl_expr_yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (ssl_expr_yyn < 0) + { + if (ssl_expr_yyn == YYFLAG) + goto ssl_expr_yyerrlab; + ssl_expr_yyn = -ssl_expr_yyn; + goto ssl_expr_yyreduce; + } + else if (ssl_expr_yyn == 0) + goto ssl_expr_yyerrlab; + + if (ssl_expr_yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Shifting token %d (%s), ", ssl_expr_yychar, ssl_expr_yytname[ssl_expr_yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (ssl_expr_yychar != YYEOF) + ssl_expr_yychar = YYEMPTY; + + *++ssl_expr_yyvsp = ssl_expr_yylval; +#ifdef YYLSP_NEEDED + *++ssl_expr_yylsp = ssl_expr_yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (ssl_expr_yyerrstatus) ssl_expr_yyerrstatus--; + + ssl_expr_yystate = ssl_expr_yyn; + goto ssl_expr_yynewstate; + +/* Do the default action for the current state. */ +ssl_expr_yydefault: + + ssl_expr_yyn = ssl_expr_yydefact[ssl_expr_yystate]; + if (ssl_expr_yyn == 0) + goto ssl_expr_yyerrlab; + +/* Do a reduction. ssl_expr_yyn is the number of a rule to reduce with. */ +ssl_expr_yyreduce: + ssl_expr_yylen = ssl_expr_yyr2[ssl_expr_yyn]; + if (ssl_expr_yylen > 0) + ssl_expr_yyval = ssl_expr_yyvsp[1-ssl_expr_yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + ssl_expr_yyn, ssl_expr_yyrline[ssl_expr_yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = ssl_expr_yyprhs[ssl_expr_yyn]; ssl_expr_yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", ssl_expr_yytname[ssl_expr_yyrhs[i]]); + fprintf (stderr, " -> %s\n", ssl_expr_yytname[ssl_expr_yyr1[ssl_expr_yyn]]); + } +#endif + + + switch (ssl_expr_yyn) { + +case 1: +#line 115 "ssl_expr_parse.y" +{ ssl_expr_info.expr = ssl_expr_yyvsp[0].exVal; ; + break;} +case 2: +#line 118 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_True, NULL, NULL); ; + break;} +case 3: +#line 119 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_False, NULL, NULL); ; + break;} +case 4: +#line 120 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_Not, ssl_expr_yyvsp[0].exVal, NULL); ; + break;} +case 5: +#line 121 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_Or, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 6: +#line 122 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_And, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 7: +#line 123 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_Comp, ssl_expr_yyvsp[0].exVal, NULL); ; + break;} +case 8: +#line 124 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[-1].exVal; ; + break;} +case 9: +#line 127 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_EQ, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 10: +#line 128 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_NE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 11: +#line 129 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_LT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 12: +#line 130 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_LE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 13: +#line 131 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_GT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 14: +#line 132 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_GE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 15: +#line 133 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_IN, ssl_expr_yyvsp[-4].exVal, ssl_expr_yyvsp[-1].exVal); ; + break;} +case 16: +#line 134 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_REG, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 17: +#line 135 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_NRE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); ; + break;} +case 18: +#line 138 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, NULL); ; + break;} +case 19: +#line 139 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, ssl_expr_yyvsp[-2].exVal); ; + break;} +case 20: +#line 142 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_Digit, ssl_expr_yyvsp[0].cpVal, NULL); ; + break;} +case 21: +#line 143 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_String, ssl_expr_yyvsp[0].cpVal, NULL); ; + break;} +case 22: +#line 144 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_make(op_Var, ssl_expr_yyvsp[-1].cpVal, NULL); ; + break;} +case 23: +#line 145 "ssl_expr_parse.y" +{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[0].exVal; ; + break;} +case 24: +#line 148 "ssl_expr_parse.y" +{ + ap_regex_t *regex; + if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal, + AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) { + ssl_expr_error = "Failed to compile regular expression"; + YYERROR; + regex = NULL; + } + ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL); + ; + break;} +case 25: +#line 158 "ssl_expr_parse.y" +{ + ap_regex_t *regex; + if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal, + AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) { + ssl_expr_error = "Failed to compile regular expression"; + YYERROR; + regex = NULL; + } + ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL); + ; + break;} +case 26: +#line 170 "ssl_expr_parse.y" +{ + ssl_expr *args = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[-1].cpVal, NULL); + ssl_expr_yyval.exVal = ssl_expr_make(op_Func, "file", args); + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 543 "/usr/local/share/bison.simple" + + ssl_expr_yyvsp -= ssl_expr_yylen; + ssl_expr_yyssp -= ssl_expr_yylen; +#ifdef YYLSP_NEEDED + ssl_expr_yylsp -= ssl_expr_yylen; +#endif + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + { + short *ssp1 = ssl_expr_yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != ssl_expr_yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++ssl_expr_yyvsp = ssl_expr_yyval; + +#ifdef YYLSP_NEEDED + ssl_expr_yylsp++; + if (ssl_expr_yylen == 0) + { + ssl_expr_yylsp->first_line = ssl_expr_yylloc.first_line; + ssl_expr_yylsp->first_column = ssl_expr_yylloc.first_column; + ssl_expr_yylsp->last_line = (ssl_expr_yylsp-1)->last_line; + ssl_expr_yylsp->last_column = (ssl_expr_yylsp-1)->last_column; + ssl_expr_yylsp->text = 0; + } + else + { + ssl_expr_yylsp->last_line = (ssl_expr_yylsp+ssl_expr_yylen-1)->last_line; + ssl_expr_yylsp->last_column = (ssl_expr_yylsp+ssl_expr_yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + ssl_expr_yyn = ssl_expr_yyr1[ssl_expr_yyn]; + + ssl_expr_yystate = ssl_expr_yypgoto[ssl_expr_yyn - YYNTBASE] + *ssl_expr_yyssp; + if (ssl_expr_yystate >= 0 && ssl_expr_yystate <= YYLAST && ssl_expr_yycheck[ssl_expr_yystate] == *ssl_expr_yyssp) + ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yystate]; + else + ssl_expr_yystate = ssl_expr_yydefgoto[ssl_expr_yyn - YYNTBASE]; + + goto ssl_expr_yynewstate; + +ssl_expr_yyerrlab: /* here on detecting error */ + + if (! ssl_expr_yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++ssl_expr_yynerrs; + +#ifdef YYERROR_VERBOSE + ssl_expr_yyn = ssl_expr_yypact[ssl_expr_yystate]; + + if (ssl_expr_yyn > YYFLAG && ssl_expr_yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -ssl_expr_yyn if nec to avoid negative indexes in ssl_expr_yycheck. */ + for (x = (ssl_expr_yyn < 0 ? -ssl_expr_yyn : 0); + x < (sizeof(ssl_expr_yytname) / sizeof(char *)); x++) + if (ssl_expr_yycheck[x + ssl_expr_yyn] == x) + size += strlen(ssl_expr_yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (ssl_expr_yyn < 0 ? -ssl_expr_yyn : 0); + x < (sizeof(ssl_expr_yytname) / sizeof(char *)); x++) + if (ssl_expr_yycheck[x + ssl_expr_yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, ssl_expr_yytname[x]); + strcat(msg, "'"); + count++; + } + } + ssl_expr_yyerror(msg); + free(msg); + } + else + ssl_expr_yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + ssl_expr_yyerror("parse error"); + } + + goto ssl_expr_yyerrlab1; +ssl_expr_yyerrlab1: /* here on error raised explicitly by an action */ + + if (ssl_expr_yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (ssl_expr_yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", ssl_expr_yychar, ssl_expr_yytname[ssl_expr_yychar1]); +#endif + + ssl_expr_yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + ssl_expr_yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto ssl_expr_yyerrhandle; + +ssl_expr_yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + ssl_expr_yyn = ssl_expr_yydefact[ssl_expr_yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (ssl_expr_yyn) goto ssl_expr_yydefault; +#endif + +ssl_expr_yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (ssl_expr_yyssp == ssl_expr_yyss) YYABORT; + ssl_expr_yyvsp--; + ssl_expr_yystate = *--ssl_expr_yyssp; +#ifdef YYLSP_NEEDED + ssl_expr_yylsp--; +#endif + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + { + short *ssp1 = ssl_expr_yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != ssl_expr_yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +ssl_expr_yyerrhandle: + + ssl_expr_yyn = ssl_expr_yypact[ssl_expr_yystate]; + if (ssl_expr_yyn == YYFLAG) + goto ssl_expr_yyerrdefault; + + ssl_expr_yyn += YYTERROR; + if (ssl_expr_yyn < 0 || ssl_expr_yyn > YYLAST || ssl_expr_yycheck[ssl_expr_yyn] != YYTERROR) + goto ssl_expr_yyerrdefault; + + ssl_expr_yyn = ssl_expr_yytable[ssl_expr_yyn]; + if (ssl_expr_yyn < 0) + { + if (ssl_expr_yyn == YYFLAG) + goto ssl_expr_yyerrpop; + ssl_expr_yyn = -ssl_expr_yyn; + goto ssl_expr_yyreduce; + } + else if (ssl_expr_yyn == 0) + goto ssl_expr_yyerrpop; + + if (ssl_expr_yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (ssl_expr_yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++ssl_expr_yyvsp = ssl_expr_yylval; +#ifdef YYLSP_NEEDED + *++ssl_expr_yylsp = ssl_expr_yylloc; +#endif + + ssl_expr_yystate = ssl_expr_yyn; + goto ssl_expr_yynewstate; + + ssl_expr_yyacceptlab: + /* YYACCEPT comes here. */ + if (ssl_expr_yyfree_stacks) + { + free (ssl_expr_yyss); + free (ssl_expr_yyvs); +#ifdef YYLSP_NEEDED + free (ssl_expr_yyls); +#endif + } + return 0; + + ssl_expr_yyabortlab: + /* YYABORT comes here. */ + if (ssl_expr_yyfree_stacks) + { + free (ssl_expr_yyss); + free (ssl_expr_yyvs); +#ifdef YYLSP_NEEDED + free (ssl_expr_yyls); +#endif + } + return 1; +} +#line 176 "ssl_expr_parse.y" + + +int ssl_expr_yyerror(char *s) +{ + ssl_expr_error = s; + return 2; +} + diff --git a/trunk/modules/ssl/ssl_expr_parse.h b/trunk/modules/ssl/ssl_expr_parse.h new file mode 100644 index 0000000000..5378e2874c --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_parse.h @@ -0,0 +1,27 @@ +typedef union { + char *cpVal; + ssl_expr *exVal; +} YYSTYPE; +#define T_TRUE 257 +#define T_FALSE 258 +#define T_DIGIT 259 +#define T_ID 260 +#define T_STRING 261 +#define T_REGEX 262 +#define T_REGEX_I 263 +#define T_FUNC_FILE 264 +#define T_OP_EQ 265 +#define T_OP_NE 266 +#define T_OP_LT 267 +#define T_OP_LE 268 +#define T_OP_GT 269 +#define T_OP_GE 270 +#define T_OP_REG 271 +#define T_OP_NRE 272 +#define T_OP_IN 273 +#define T_OP_OR 274 +#define T_OP_AND 275 +#define T_OP_NOT 276 + + +extern YYSTYPE ssl_expr_yylval; diff --git a/trunk/modules/ssl/ssl_expr_parse.y b/trunk/modules/ssl/ssl_expr_parse.y new file mode 100644 index 0000000000..3daf31ac4e --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_parse.y @@ -0,0 +1,147 @@ +/* Copyright 2001-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | + * | '_ ` _ \ / _ \ / _` | / __/ __| | + * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL + * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ + * |_____| + * ssl_expr_parse.y + * Expression LR(1) Parser + */ + /* ``What you see is all you get.'' + -- Brian Kernighan */ + +/* _________________________________________________________________ +** +** Expression Parser +** _________________________________________________________________ +*/ + +%{ +#include "ssl_private.h" +%} + +%union { + char *cpVal; + ssl_expr *exVal; +} + +%token T_TRUE +%token T_FALSE + +%token T_DIGIT +%token T_ID +%token T_STRING +%token T_REGEX +%token T_REGEX_I + +%token T_FUNC_FILE + +%token T_OP_EQ +%token T_OP_NE +%token T_OP_LT +%token T_OP_LE +%token T_OP_GT +%token T_OP_GE +%token T_OP_REG +%token T_OP_NRE +%token T_OP_IN + +%token T_OP_OR +%token T_OP_AND +%token T_OP_NOT + +%left T_OP_OR +%left T_OP_AND +%left T_OP_NOT + +%type expr +%type comparison +%type funccall +%type regex +%type words +%type word + +%% + +root : expr { ssl_expr_info.expr = $1; } + ; + +expr : T_TRUE { $$ = ssl_expr_make(op_True, NULL, NULL); } + | T_FALSE { $$ = ssl_expr_make(op_False, NULL, NULL); } + | T_OP_NOT expr { $$ = ssl_expr_make(op_Not, $2, NULL); } + | expr T_OP_OR expr { $$ = ssl_expr_make(op_Or, $1, $3); } + | expr T_OP_AND expr { $$ = ssl_expr_make(op_And, $1, $3); } + | comparison { $$ = ssl_expr_make(op_Comp, $1, NULL); } + | '(' expr ')' { $$ = $2; } + ; + +comparison: word T_OP_EQ word { $$ = ssl_expr_make(op_EQ, $1, $3); } + | word T_OP_NE word { $$ = ssl_expr_make(op_NE, $1, $3); } + | word T_OP_LT word { $$ = ssl_expr_make(op_LT, $1, $3); } + | word T_OP_LE word { $$ = ssl_expr_make(op_LE, $1, $3); } + | word T_OP_GT word { $$ = ssl_expr_make(op_GT, $1, $3); } + | word T_OP_GE word { $$ = ssl_expr_make(op_GE, $1, $3); } + | word T_OP_IN '{' words '}' { $$ = ssl_expr_make(op_IN, $1, $4); } + | word T_OP_REG regex { $$ = ssl_expr_make(op_REG, $1, $3); } + | word T_OP_NRE regex { $$ = ssl_expr_make(op_NRE, $1, $3); } + ; + +words : word { $$ = ssl_expr_make(op_ListElement, $1, NULL); } + | words ',' word { $$ = ssl_expr_make(op_ListElement, $3, $1); } + ; + +word : T_DIGIT { $$ = ssl_expr_make(op_Digit, $1, NULL); } + | T_STRING { $$ = ssl_expr_make(op_String, $1, NULL); } + | '%' '{' T_ID '}' { $$ = ssl_expr_make(op_Var, $3, NULL); } + | funccall { $$ = $1; } + ; + +regex : T_REGEX { + ap_regex_t *regex; + if ((regex = ap_pregcomp(ssl_expr_info.pool, $1, + AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) { + ssl_expr_error = "Failed to compile regular expression"; + YYERROR; + } + $$ = ssl_expr_make(op_Regex, regex, NULL); + } + | T_REGEX_I { + ap_regex_t *regex; + if ((regex = ap_pregcomp(ssl_expr_info.pool, $1, + AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) { + ssl_expr_error = "Failed to compile regular expression"; + YYERROR; + } + $$ = ssl_expr_make(op_Regex, regex, NULL); + } + ; + +funccall : T_FUNC_FILE '(' T_STRING ')' { + ssl_expr *args = ssl_expr_make(op_ListElement, $3, NULL); + $$ = ssl_expr_make(op_Func, "file", args); + } + ; + +%% + +int yyerror(char *s) +{ + ssl_expr_error = s; + return 2; +} + diff --git a/trunk/modules/ssl/ssl_expr_scan.c b/trunk/modules/ssl/ssl_expr_scan.c new file mode 100644 index 0000000000..d535c07b13 --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_scan.c @@ -0,0 +1,1970 @@ +#define yy_create_buffer ssl_expr_yy_create_buffer +#define yy_delete_buffer ssl_expr_yy_delete_buffer +#define yy_scan_buffer ssl_expr_yy_scan_buffer +#define yy_scan_string ssl_expr_yy_scan_string +#define yy_scan_bytes ssl_expr_yy_scan_bytes +#define yy_flex_debug ssl_expr_yy_flex_debug +#define yy_init_buffer ssl_expr_yy_init_buffer +#define yy_flush_buffer ssl_expr_yy_flush_buffer +#define yy_load_buffer_state ssl_expr_yy_load_buffer_state +#define yy_switch_to_buffer ssl_expr_yy_switch_to_buffer +#define yyin ssl_expr_yyin +#define yyleng ssl_expr_yyleng +#define yylex ssl_expr_yylex +#define yyout ssl_expr_yyout +#define yyrestart ssl_expr_yyrestart +#define yytext ssl_expr_yytext + +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/striker/cvs2svn/dumps/httpd-2.0/../../httpd-2.0/modules/ssl/ssl_expr_scan.c,v 1.19 2004/02/28 18:06:35 jorton Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ +#pragma warn -rch +#pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define yywrap() 1 +#define YY_SKIP_YYWRAP +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 46 +#define YY_END_OF_BUFFER 47 +static yyconst short int yy_accept[86] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 45, + 1, 38, 2, 45, 43, 24, 45, 28, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, + 13, 4, 3, 14, 16, 18, 17, 1, 22, 32, + 34, 43, 26, 20, 31, 30, 44, 44, 19, 44, + 44, 29, 27, 39, 25, 23, 15, 15, 21, 44, + 35, 44, 36, 13, 12, 5, 6, 10, 11, 7, + 8, 9, 33, 44, 44, 37, 44, 5, 6, 44, + 40, 41, 5, 42, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 1, 1, 6, 1, 1, + 1, 1, 1, 1, 7, 1, 1, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 7, 1, 10, + 11, 12, 1, 1, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 14, 1, 1, 7, 1, 15, 16, 13, 17, + + 18, 19, 20, 13, 21, 13, 13, 22, 23, 24, + 25, 13, 26, 27, 28, 29, 30, 13, 13, 13, + 13, 13, 1, 31, 1, 32, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[33] = + { 0, + 1, 1, 2, 1, 3, 1, 4, 4, 4, 1, + 1, 1, 4, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1 + } ; + +static yyconst short int yy_base[93] = + { 0, + 0, 0, 30, 31, 0, 0, 82, 81, 101, 142, + 35, 28, 142, 94, 32, 88, 31, 87, 0, 69, + 66, 28, 28, 67, 29, 63, 30, 63, 62, 57, + 0, 142, 142, 88, 142, 142, 142, 48, 142, 142, + 142, 44, 142, 142, 142, 142, 0, 70, 0, 64, + 63, 0, 0, 0, 0, 0, 142, 0, 0, 55, + 0, 46, 142, 0, 142, 53, 62, 142, 142, 142, + 142, 142, 0, 44, 48, 0, 41, 70, 72, 38, + 0, 0, 74, 0, 142, 117, 121, 125, 50, 129, + 133, 137 + + } ; + +static yyconst short int yy_def[93] = + { 0, + 85, 1, 86, 86, 87, 87, 88, 88, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 89, 89, + 89, 89, 89, 89, 89, 90, 89, 89, 89, 85, + 91, 85, 85, 92, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 85, 89, 89, 89, + 89, 89, 85, 91, 85, 85, 85, 85, 85, 85, + 85, 85, 89, 89, 89, 89, 89, 85, 85, 89, + 89, 89, 85, 89, 0, 85, 85, 85, 85, 85, + 85, 85 + + } ; + +static yyconst short int yy_nxt[175] = + { 0, + 10, 11, 11, 12, 13, 14, 10, 15, 15, 16, + 17, 18, 19, 10, 20, 19, 19, 21, 22, 23, + 24, 25, 26, 27, 28, 19, 19, 19, 29, 19, + 30, 10, 32, 32, 33, 33, 38, 38, 39, 42, + 42, 44, 50, 34, 34, 52, 55, 59, 51, 38, + 38, 42, 42, 47, 60, 84, 53, 56, 82, 40, + 78, 79, 45, 57, 57, 81, 57, 57, 57, 79, + 79, 80, 57, 57, 57, 77, 57, 83, 79, 79, + 79, 79, 79, 76, 75, 74, 73, 63, 62, 61, + 54, 49, 48, 57, 57, 66, 67, 46, 43, 41, + + 85, 37, 37, 68, 85, 85, 69, 85, 85, 85, + 85, 70, 85, 85, 71, 85, 72, 31, 31, 31, + 31, 35, 35, 35, 35, 36, 36, 36, 36, 58, + 85, 58, 58, 64, 85, 85, 64, 65, 65, 65, + 65, 9, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85 + } ; + +static yyconst short int yy_chk[175] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 4, 3, 4, 11, 11, 12, 15, + 15, 17, 22, 3, 4, 23, 25, 27, 22, 38, + 38, 42, 42, 89, 27, 80, 23, 25, 77, 12, + 66, 66, 17, 26, 26, 75, 26, 26, 26, 67, + 67, 74, 26, 26, 26, 62, 26, 78, 78, 79, + 79, 83, 83, 60, 51, 50, 48, 30, 29, 28, + 24, 21, 20, 26, 26, 34, 34, 18, 16, 14, + + 9, 8, 7, 34, 0, 0, 34, 0, 0, 0, + 0, 34, 0, 0, 34, 0, 34, 86, 86, 86, + 86, 87, 87, 87, 87, 88, 88, 88, 88, 90, + 0, 90, 90, 91, 0, 0, 91, 92, 92, 92, + 92, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "ssl_expr_scan.l" +#define INITIAL 0 +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | + * | '_ ` _ \ / _ \ / _` | / __/ __| | + * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL + * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ + * |_____| + * ssl_expr_scan.l + * Expression Scanner + */ + /* ``Killing for peace is + like fucking for virginity.'' + -- Unknown */ + +/* _________________________________________________________________ +** +** Expression Scanner +** _________________________________________________________________ +*/ +#line 38 "ssl_expr_scan.l" +#include "ssl_private.h" + +#include "ssl_expr_parse.h" + +#define YY_NO_UNPUT 1 +int yyinput(char *buf, int max_size); + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + (result = yyinput(buf, max_size)) + +#define MAX_STR_LEN 2048 +/* %option stack */ +#define YY_NEVER_INTERACTIVE 1 +#define str 1 + +#define regex 2 +#define regex_flags 3 + +#line 535 "lex.ssl_expr_yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 91 "ssl_expr_scan.l" + + + char caStr[MAX_STR_LEN]; + char *cpStr = NULL; + char caRegex[MAX_STR_LEN]; + char *cpRegex = NULL; + char cRegexDel = NUL; + + /* + * Whitespaces + */ +#line 698 "lex.ssl_expr_yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 85 ); + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 102 "ssl_expr_scan.l" +{ + /* NOP */ +} + YY_BREAK +/* + * C-style strings ("...") + */ +case 2: +YY_RULE_SETUP +#line 109 "ssl_expr_scan.l" +{ + cpStr = caStr; + BEGIN(str); +} + YY_BREAK +case 3: +YY_RULE_SETUP +#line 113 "ssl_expr_scan.l" +{ + BEGIN(INITIAL); + *cpStr = NUL; + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caStr); + return T_STRING; +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 119 "ssl_expr_scan.l" +{ + yyerror("Unterminated string"); +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 122 "ssl_expr_scan.l" +{ + int result; + + (void)sscanf(yytext+1, "%o", &result); + if (result > 0xff) + yyerror("Escape sequence out of bound"); + else + *cpStr++ = result; +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 131 "ssl_expr_scan.l" +{ + yyerror("Bad escape sequence"); +} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 134 "ssl_expr_scan.l" +{ *cpStr++ = '\n'; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 135 "ssl_expr_scan.l" +{ *cpStr++ = '\r'; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 136 "ssl_expr_scan.l" +{ *cpStr++ = '\t'; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 137 "ssl_expr_scan.l" +{ *cpStr++ = '\b'; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 138 "ssl_expr_scan.l" +{ *cpStr++ = '\f'; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 139 "ssl_expr_scan.l" +{ + *cpStr++ = yytext[1]; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 142 "ssl_expr_scan.l" +{ + char *cp = yytext; + while (*cp != NUL) + *cpStr++ = *cp++; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 147 "ssl_expr_scan.l" +{ + *cpStr++ = yytext[1]; +} + YY_BREAK +/* + * Regular Expression + */ +case 15: +YY_RULE_SETUP +#line 154 "ssl_expr_scan.l" +{ + cRegexDel = yytext[1]; + cpRegex = caRegex; + BEGIN(regex); +} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 159 "ssl_expr_scan.l" +{ + if (yytext[0] == cRegexDel) { + *cpRegex = NUL; + BEGIN(regex_flags); + } + else { + *cpRegex++ = yytext[0]; + } +} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 168 "ssl_expr_scan.l" +{ + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX_I; +} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 173 "ssl_expr_scan.l" +{ + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + yyless(0); + BEGIN(INITIAL); + return T_REGEX; +} + YY_BREAK +case YY_STATE_EOF(regex_flags): +#line 179 "ssl_expr_scan.l" +{ + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX; +} + YY_BREAK +/* + * Operators + */ +case 19: +YY_RULE_SETUP +#line 188 "ssl_expr_scan.l" +{ return T_OP_EQ; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 189 "ssl_expr_scan.l" +{ return T_OP_EQ; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 190 "ssl_expr_scan.l" +{ return T_OP_NE; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 191 "ssl_expr_scan.l" +{ return T_OP_NE; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 192 "ssl_expr_scan.l" +{ return T_OP_LT; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 193 "ssl_expr_scan.l" +{ return T_OP_LT; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 194 "ssl_expr_scan.l" +{ return T_OP_LE; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 195 "ssl_expr_scan.l" +{ return T_OP_LE; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 196 "ssl_expr_scan.l" +{ return T_OP_GT; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 197 "ssl_expr_scan.l" +{ return T_OP_GT; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 198 "ssl_expr_scan.l" +{ return T_OP_GE; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 199 "ssl_expr_scan.l" +{ return T_OP_GE; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 200 "ssl_expr_scan.l" +{ return T_OP_REG; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 201 "ssl_expr_scan.l" +{ return T_OP_NRE; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 202 "ssl_expr_scan.l" +{ return T_OP_AND; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 203 "ssl_expr_scan.l" +{ return T_OP_AND; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 204 "ssl_expr_scan.l" +{ return T_OP_OR; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 205 "ssl_expr_scan.l" +{ return T_OP_OR; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 206 "ssl_expr_scan.l" +{ return T_OP_NOT; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 207 "ssl_expr_scan.l" +{ return T_OP_NOT; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 208 "ssl_expr_scan.l" +{ return T_OP_IN; } + YY_BREAK +/* + * Functions + */ +case 40: +YY_RULE_SETUP +#line 213 "ssl_expr_scan.l" +{ return T_FUNC_FILE; } + YY_BREAK +/* + * Specials + */ +case 41: +YY_RULE_SETUP +#line 218 "ssl_expr_scan.l" +{ return T_TRUE; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 219 "ssl_expr_scan.l" +{ return T_FALSE; } + YY_BREAK +/* + * Digits + */ +case 43: +YY_RULE_SETUP +#line 224 "ssl_expr_scan.l" +{ + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext); + return T_DIGIT; +} + YY_BREAK +/* + * Identifiers + */ +case 44: +YY_RULE_SETUP +#line 232 "ssl_expr_scan.l" +{ + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext); + return T_ID; +} + YY_BREAK +/* + * Anything else is returned as is... + */ +case 45: +YY_RULE_SETUP +#line 240 "ssl_expr_scan.l" +{ + return yytext[0]; +} + YY_BREAK +case 46: +YY_RULE_SETUP +#line 244 "ssl_expr_scan.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 1098 "lex.ssl_expr_yy.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(str): +case YY_STATE_EOF(regex): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 85); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 244 "ssl_expr_scan.l" + + +int yyinput(char *buf, int max_size) +{ + int n; + + if ((n = MIN(max_size, ssl_expr_info.inputbuf + + ssl_expr_info.inputlen + - ssl_expr_info.inputptr)) <= 0) + return YY_NULL; + memcpy(buf, ssl_expr_info.inputptr, n); + ssl_expr_info.inputptr += n; + return n; +} + diff --git a/trunk/modules/ssl/ssl_expr_scan.l b/trunk/modules/ssl/ssl_expr_scan.l new file mode 100644 index 0000000000..da172fd3a5 --- /dev/null +++ b/trunk/modules/ssl/ssl_expr_scan.l @@ -0,0 +1,224 @@ +/* Copyright 2001-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | + * | '_ ` _ \ / _ \ / _` | / __/ __| | + * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL + * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ + * |_____| + * ssl_expr_scan.l + * Expression Scanner + */ + /* ``Killing for peace is + like fucking for virginity.'' + -- Unknown */ + +/* _________________________________________________________________ +** +** Expression Scanner +** _________________________________________________________________ +*/ + +%{ +#include "ssl_private.h" + +#include "ssl_expr_parse.h" + +#define YY_NO_UNPUT 1 +int yyinput(char *buf, int max_size); + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + (result = yyinput(buf, max_size)) + +#define MAX_STR_LEN 2048 +%} + +%pointer +/* %option stack */ +%option never-interactive +%option noyywrap +%x str +%x regex regex_flags + +%% + + char caStr[MAX_STR_LEN]; + char *cpStr = NULL; + char caRegex[MAX_STR_LEN]; + char *cpRegex = NULL; + char cRegexDel = NUL; + + /* + * Whitespaces + */ +[ \t\n]+ { + /* NOP */ +} + + /* + * C-style strings ("...") + */ +\" { + cpStr = caStr; + BEGIN(str); +} +\" { + BEGIN(INITIAL); + *cpStr = NUL; + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caStr); + return T_STRING; +} +\n { + yyerror("Unterminated string"); +} +\\[0-7]{1,3} { + int result; + + (void)sscanf(yytext+1, "%o", &result); + if (result > 0xff) + yyerror("Escape sequence out of bound"); + else + *cpStr++ = result; +} +\\[0-9]+ { + yyerror("Bad escape sequence"); +} +\\n { *cpStr++ = '\n'; } +\\r { *cpStr++ = '\r'; } +\\t { *cpStr++ = '\t'; } +\\b { *cpStr++ = '\b'; } +\\f { *cpStr++ = '\f'; } +\\(.|\n) { + *cpStr++ = yytext[1]; +} +[^\\\n\"]+ { + char *cp = yytext; + while (*cp != NUL) + *cpStr++ = *cp++; +} +. { + *cpStr++ = yytext[1]; +} + + /* + * Regular Expression + */ +"m". { + cRegexDel = yytext[1]; + cpRegex = caRegex; + BEGIN(regex); +} +.|\n { + if (yytext[0] == cRegexDel) { + *cpRegex = NUL; + BEGIN(regex_flags); + } + else { + *cpRegex++ = yytext[0]; + } +} +i { + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX_I; +} +.|\n { + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + yyless(0); + BEGIN(INITIAL); + return T_REGEX; +} +<> { + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX; +} + + /* + * Operators + */ +"eq" { return T_OP_EQ; } +"==" { return T_OP_EQ; } +"ne" { return T_OP_NE; } +"!=" { return T_OP_NE; } +"lt" { return T_OP_LT; } +"<" { return T_OP_LT; } +"le" { return T_OP_LE; } +"<=" { return T_OP_LE; } +"gt" { return T_OP_GT; } +">" { return T_OP_GT; } +"ge" { return T_OP_GE; } +">=" { return T_OP_GE; } +"=~" { return T_OP_REG; } +"!~" { return T_OP_NRE; } +"and" { return T_OP_AND; } +"&&" { return T_OP_AND; } +"or" { return T_OP_OR; } +"||" { return T_OP_OR; } +"not" { return T_OP_NOT; } +"!" { return T_OP_NOT; } +"in" { return T_OP_IN; } + + /* + * Functions + */ +"file" { return T_FUNC_FILE; } + + /* + * Specials + */ +"true" { return T_TRUE; } +"false" { return T_FALSE; } + + /* + * Digits + */ +[0-9]+ { + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext); + return T_DIGIT; +} + + /* + * Identifiers + */ +[a-zA-Z][a-zA-Z0-9_:-]* { + yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext); + return T_ID; +} + + /* + * Anything else is returned as is... + */ +.|\n { + return yytext[0]; +} + +%% + +int yyinput(char *buf, int max_size) +{ + int n; + + if ((n = MIN(max_size, ssl_expr_info.inputbuf + + ssl_expr_info.inputlen + - ssl_expr_info.inputptr)) <= 0) + return YY_NULL; + memcpy(buf, ssl_expr_info.inputptr, n); + ssl_expr_info.inputptr += n; + return n; +} + diff --git a/trunk/modules/ssl/ssl_private.h b/trunk/modules/ssl/ssl_private.h new file mode 100644 index 0000000000..71db2d1fd5 --- /dev/null +++ b/trunk/modules/ssl/ssl_private.h @@ -0,0 +1,649 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SSL_PRIVATE_H +#define SSL_PRIVATE_H + +/* + * Internal interfaces private to mod_ssl. + */ + +/* Apache headers */ +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_connection.h" +#include "http_request.h" +#include "http_protocol.h" +#include "util_script.h" +#include "util_filter.h" +#include "util_ebcdic.h" +#include "mpm.h" +#include "apr.h" +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_tables.h" +#include "apr_lib.h" +#include "apr_fnmatch.h" +#include "apr_strings.h" +#include "apr_dbm.h" +#include "apr_rmm.h" +#include "apr_shm.h" +#include "apr_global_mutex.h" +#include "apr_optional.h" + +#define MOD_SSL_VERSION AP_SERVER_BASEREVISION + +/* mod_ssl headers */ +#include "ssl_toolkit_compat.h" +#include "ssl_expr.h" +#include "ssl_util_ssl.h" + +/* The #ifdef macros are only defined AFTER including the above + * therefore we cannot include these system files at the top :-( + */ +#if APR_HAVE_SYS_TIME_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include /* needed for STDIN_FILENO et.al., at least on FreeBSD */ +#endif + +/* + * Provide reasonable default for some defines + */ +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif +#ifndef PFALSE +#define PFALSE ((void *)FALSE) +#endif +#ifndef PTRUE +#define PTRUE ((void *)TRUE) +#endif +#ifndef UNSET +#define UNSET (-1) +#endif +#ifndef NUL +#define NUL '\0' +#endif +#ifndef RAND_MAX +#include +#define RAND_MAX INT_MAX +#endif + +/* + * Provide reasonable defines for some types + */ +#ifndef BOOL +#define BOOL unsigned int +#endif +#ifndef UCHAR +#define UCHAR unsigned char +#endif + +/* + * Provide useful shorthands + */ +#define strEQ(s1,s2) (strcmp(s1,s2) == 0) +#define strNE(s1,s2) (strcmp(s1,s2) != 0) +#define strEQn(s1,s2,n) (strncmp(s1,s2,n) == 0) +#define strNEn(s1,s2,n) (strncmp(s1,s2,n) != 0) + +#define strcEQ(s1,s2) (strcasecmp(s1,s2) == 0) +#define strcNE(s1,s2) (strcasecmp(s1,s2) != 0) +#define strcEQn(s1,s2,n) (strncasecmp(s1,s2,n) == 0) +#define strcNEn(s1,s2,n) (strncasecmp(s1,s2,n) != 0) + +#define strIsEmpty(s) (s == NULL || s[0] == NUL) + +#define myConnConfig(c) \ +(SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module) +#define myCtxConfig(sslconn, sc) (sslconn->is_proxy ? sc->proxy : sc->server) +#define myConnConfigSet(c, val) \ +ap_set_module_config(c->conn_config, &ssl_module, val) +#define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config, &ssl_module) +#define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module) +#define myModConfig(srv) (mySrvConfig((srv)))->mc + +#define myCtxVarSet(mc,num,val) mc->rCtx.pV##num = val +#define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num) + +/* + * Defaults for the configuration + */ +#ifndef SSL_SESSION_CACHE_TIMEOUT +#define SSL_SESSION_CACHE_TIMEOUT 300 +#endif + +/* + * Support for MM library + */ +#define SSL_MM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) + +/* + * Support for DBM library + */ +#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) + +#if !defined(SSL_DBM_FILE_SUFFIX_DIR) && !defined(SSL_DBM_FILE_SUFFIX_PAG) +#if defined(DBM_SUFFIX) +#define SSL_DBM_FILE_SUFFIX_DIR DBM_SUFFIX +#define SSL_DBM_FILE_SUFFIX_PAG DBM_SUFFIX +#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) +#define SSL_DBM_FILE_SUFFIX_DIR ".db" +#define SSL_DBM_FILE_SUFFIX_PAG ".db" +#else +#define SSL_DBM_FILE_SUFFIX_DIR ".dir" +#define SSL_DBM_FILE_SUFFIX_PAG ".pag" +#endif +#endif + +/* + * Define the certificate algorithm types + */ + +typedef int ssl_algo_t; + +#define SSL_ALGO_UNKNOWN (0) +#define SSL_ALGO_RSA (1<<0) +#define SSL_ALGO_DSA (1<<1) +#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA) + +#define SSL_AIDX_RSA (0) +#define SSL_AIDX_DSA (1) +#define SSL_AIDX_MAX (2) + + +/* + * Define IDs for the temporary RSA keys and DH params + */ + +#define SSL_TMP_KEY_RSA_512 (0) +#define SSL_TMP_KEY_RSA_1024 (1) +#define SSL_TMP_KEY_DH_512 (2) +#define SSL_TMP_KEY_DH_1024 (3) +#define SSL_TMP_KEY_MAX (4) + +/* + * Define the SSL options + */ +#define SSL_OPT_NONE (0) +#define SSL_OPT_RELSET (1<<0) +#define SSL_OPT_STDENVVARS (1<<1) +#define SSL_OPT_EXPORTCERTDATA (1<<3) +#define SSL_OPT_FAKEBASICAUTH (1<<4) +#define SSL_OPT_STRICTREQUIRE (1<<5) +#define SSL_OPT_OPTRENEGOTIATE (1<<6) +#define SSL_OPT_ALL (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE) +typedef int ssl_opt_t; + +/* + * Define the SSL Protocol options + */ +#define SSL_PROTOCOL_NONE (0) +#define SSL_PROTOCOL_SSLV2 (1<<0) +#define SSL_PROTOCOL_SSLV3 (1<<1) +#define SSL_PROTOCOL_TLSV1 (1<<2) +#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1) +typedef int ssl_proto_t; + +/* + * Define the SSL verify levels + */ +typedef enum { + SSL_CVERIFY_UNSET = UNSET, + SSL_CVERIFY_NONE = 0, + SSL_CVERIFY_OPTIONAL = 1, + SSL_CVERIFY_REQUIRE = 2, + SSL_CVERIFY_OPTIONAL_NO_CA = 3 +} ssl_verify_t; + +#define SSL_VERIFY_PEER_STRICT \ + (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT) + +#ifndef X509_V_ERR_CERT_UNTRUSTED +#define X509_V_ERR_CERT_UNTRUSTED 27 +#endif + +#define ssl_verify_error_is_optional(errnum) \ + ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) \ + || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) \ + || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) \ + || (errnum == X509_V_ERR_CERT_UNTRUSTED) \ + || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) + +/* + * Define the SSL pass phrase dialog types + */ +typedef enum { + SSL_PPTYPE_UNSET = UNSET, + SSL_PPTYPE_BUILTIN = 0, + SSL_PPTYPE_FILTER = 1, + SSL_PPTYPE_PIPE = 2 +} ssl_pphrase_t; + +/* + * Define the Path Checking modes + */ +#define SSL_PCM_EXISTS 1 +#define SSL_PCM_ISREG 2 +#define SSL_PCM_ISDIR 4 +#define SSL_PCM_ISNONZERO 8 +typedef unsigned int ssl_pathcheck_t; + +/* + * Define the SSL session cache modes and structures + */ +typedef enum { + SSL_SCMODE_UNSET = UNSET, + SSL_SCMODE_NONE = 0, + SSL_SCMODE_DBM = 1, + SSL_SCMODE_SHMCB = 3, + SSL_SCMODE_DC = 4 +} ssl_scmode_t; + +/* + * Define the SSL mutex modes + */ +typedef enum { + SSL_MUTEXMODE_UNSET = UNSET, + SSL_MUTEXMODE_NONE = 0, + SSL_MUTEXMODE_USED = 1 +} ssl_mutexmode_t; + +/* + * Define the SSL enabled state + */ +typedef enum { + SSL_ENABLED_UNSET = UNSET, + SSL_ENABLED_FALSE = 0, + SSL_ENABLED_TRUE = 1, + SSL_ENABLED_OPTIONAL = 3 +} ssl_enabled_t; + +/* + * Define the SSL requirement structure + */ +typedef struct { + char *cpExpr; + ssl_expr *mpExpr; +} ssl_require_t; + +/* + * Define the SSL random number generator seeding source + */ +typedef enum { + SSL_RSCTX_STARTUP = 1, + SSL_RSCTX_CONNECT = 2 +} ssl_rsctx_t; +typedef enum { + SSL_RSSRC_BUILTIN = 1, + SSL_RSSRC_FILE = 2, + SSL_RSSRC_EXEC = 3, + SSL_RSSRC_EGD = 4 +} ssl_rssrc_t; +typedef struct { + ssl_rsctx_t nCtx; + ssl_rssrc_t nSrc; + char *cpPath; + int nBytes; +} ssl_randseed_t; + +/* + * Define the structure of an ASN.1 anything + */ +typedef struct { + long int nData; + unsigned char *cpData; + apr_time_t source_mtime; +} ssl_asn1_t; + +/* + * Define the mod_ssl per-module configuration structure + * (i.e. the global configuration for each httpd process) + */ + +typedef enum { + SSL_SHUTDOWN_TYPE_UNSET, + SSL_SHUTDOWN_TYPE_STANDARD, + SSL_SHUTDOWN_TYPE_UNCLEAN, + SSL_SHUTDOWN_TYPE_ACCURATE +} ssl_shutdown_type_e; + +typedef struct { + SSL *ssl; + const char *client_dn; + X509 *client_cert; + ssl_shutdown_type_e shutdown_type; + const char *verify_info; + const char *verify_error; + int verify_depth; + int is_proxy; + int disabled; + int non_ssl_request; +} SSLConnRec; + +typedef struct { + pid_t pid; + apr_pool_t *pPool; + BOOL bFixed; + int nSessionCacheMode; + char *szSessionCacheDataFile; + int nSessionCacheDataSize; + apr_shm_t *pSessionCacheDataMM; + apr_rmm_t *pSessionCacheDataRMM; + void *tSessionCacheDataTable; + ssl_mutexmode_t nMutexMode; + apr_lockmech_e nMutexMech; + const char *szMutexFile; + apr_global_mutex_t *pMutex; + apr_array_header_t *aRandSeed; + apr_hash_t *tVHostKeys; + void *pTmpKeys[SSL_TMP_KEY_MAX]; + apr_hash_t *tPublicCert; + apr_hash_t *tPrivateKey; +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) + const char *szCryptoDevice; +#endif + struct { + void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10; + } rCtx; +} SSLModConfigRec; + +/* public cert/private key */ +typedef struct { + /* + * server only has 1-2 certs/keys + * 1 RSA and/or 1 DSA + */ + const char *cert_files[SSL_AIDX_MAX]; + const char *key_files[SSL_AIDX_MAX]; + X509 *certs[SSL_AIDX_MAX]; + EVP_PKEY *keys[SSL_AIDX_MAX]; + + /* Certificates which specify the set of CA names which should be + * sent in the CertificateRequest message: */ + const char *ca_name_path; + const char *ca_name_file; +} modssl_pk_server_t; + +typedef struct { + /* proxy can have any number of cert/key pairs */ + const char *cert_file; + const char *cert_path; + STACK_OF(X509_INFO) *certs; +} modssl_pk_proxy_t; + +/* stuff related to authentication that can also be per-dir */ +typedef struct { + /* known/trusted CAs */ + const char *ca_cert_path; + const char *ca_cert_file; + + const char *cipher_suite; + + /* for client or downstream server authentication */ + int verify_depth; + ssl_verify_t verify_mode; +} modssl_auth_ctx_t; + +typedef struct SSLSrvConfigRec SSLSrvConfigRec; + +typedef struct { + SSLSrvConfigRec *sc; /* pointer back to server config */ + SSL_CTX *ssl_ctx; + + /* we are one or the other */ + modssl_pk_server_t *pks; + modssl_pk_proxy_t *pkp; + + ssl_proto_t protocol; + + /* config for handling encrypted keys */ + ssl_pphrase_t pphrase_dialog_type; + const char *pphrase_dialog_path; + + const char *cert_chain; + + /* certificate revocation list */ + const char *crl_path; + const char *crl_file; + X509_STORE *crl; + + modssl_auth_ctx_t auth; +} modssl_ctx_t; + +struct SSLSrvConfigRec { + SSLModConfigRec *mc; + ssl_enabled_t enabled; + BOOL proxy_enabled; + const char *vhost_id; + int vhost_id_len; + int session_cache_timeout; + BOOL cipher_server_pref; + modssl_ctx_t *server; + modssl_ctx_t *proxy; +}; + +/* + * Define the mod_ssl per-directory configuration structure + * (i.e. the local configuration for all + * and .htaccess contexts) + */ +typedef struct { + BOOL bSSLRequired; + apr_array_header_t *aRequirement; + ssl_opt_t nOptions; + ssl_opt_t nOptionsAdd; + ssl_opt_t nOptionsDel; + const char *szCipherSuite; + ssl_verify_t nVerifyClient; + int nVerifyDepth; + const char *szCACertificatePath; + const char *szCACertificateFile; + const char *szUserName; +} SSLDirConfigRec; + +/* + * function prototypes + */ + +/* API glue structures */ +extern module AP_MODULE_DECLARE_DATA ssl_module; + +/* "global" stuff */ +extern const char ssl_valid_ssl_mutex_string[]; + +/* configuration handling */ +SSLModConfigRec *ssl_config_global_create(server_rec *); +void ssl_config_global_fix(SSLModConfigRec *); +BOOL ssl_config_global_isfixed(SSLModConfigRec *); +void *ssl_config_server_create(apr_pool_t *, server_rec *); +void *ssl_config_server_merge(apr_pool_t *, void *, void *); +void *ssl_config_perdir_create(apr_pool_t *, char *); +void *ssl_config_perdir_merge(apr_pool_t *, void *, void *); +const char *ssl_cmd_SSLMutex(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *); +const char *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag); +const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProtocol(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLOptions(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLRequireSSL(cmd_parms *, void *); +const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); + +const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); +const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyVerify(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *); + +/* module initialization */ +int ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *); +void ssl_init_Engine(server_rec *, apr_pool_t *); +void ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *); +void ssl_init_CheckServers(server_rec *, apr_pool_t *); +STACK_OF(X509_NAME) + *ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *); +void ssl_init_Child(apr_pool_t *, server_rec *); +apr_status_t ssl_init_ModuleKill(void *data); + +/* Apache API hooks */ +int ssl_hook_Auth(request_rec *); +int ssl_hook_UserCheck(request_rec *); +int ssl_hook_Access(request_rec *); +int ssl_hook_Fixup(request_rec *); +int ssl_hook_ReadReq(request_rec *); +int ssl_hook_Upgrade(request_rec *); +void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s); + +/* OpenSSL callbacks */ +RSA *ssl_callback_TmpRSA(SSL *, int, int); +DH *ssl_callback_TmpDH(SSL *, int, int); +int ssl_callback_SSLVerify(int, X509_STORE_CTX *); +int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *); +int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey); +int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); +SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); +void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); +void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); + +/* Session Cache Support */ +void ssl_scache_init(server_rec *, apr_pool_t *); +void ssl_scache_status_register(apr_pool_t *p); +void ssl_scache_kill(server_rec *); +BOOL ssl_scache_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *); +SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int); +void ssl_scache_remove(server_rec *, UCHAR *, int); + +char *ssl_scache_id2sz(UCHAR *, int); +void ssl_scache_dbm_init(server_rec *, apr_pool_t *); +void ssl_scache_dbm_kill(server_rec *); +BOOL ssl_scache_dbm_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *); +SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *, UCHAR *, int); +void ssl_scache_dbm_remove(server_rec *, UCHAR *, int); +void ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *pool); + +void ssl_scache_shmcb_init(server_rec *, apr_pool_t *); +void ssl_scache_shmcb_kill(server_rec *); +BOOL ssl_scache_shmcb_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *); +SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *, UCHAR *, int); +void ssl_scache_shmcb_remove(server_rec *, UCHAR *, int); +void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *pool); + +void ssl_scache_dc_init(server_rec *, apr_pool_t *); +void ssl_scache_dc_kill(server_rec *); +BOOL ssl_scache_dc_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *); +SSL_SESSION *ssl_scache_dc_retrieve(server_rec *, UCHAR *, int); +void ssl_scache_dc_remove(server_rec *, UCHAR *, int); +void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool); + +/* Proxy Support */ +int ssl_proxy_enable(conn_rec *c); +int ssl_engine_disable(conn_rec *c); + +/* I/O */ +void ssl_io_filter_init(conn_rec *, SSL *); +void ssl_io_filter_register(apr_pool_t *); +long ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long); + +/* PRNG */ +int ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *); + +/* Utility Functions */ +char *ssl_util_vhostid(apr_pool_t *, server_rec *); +apr_file_t *ssl_util_ppopen(server_rec *, apr_pool_t *, const char *, + const char * const *); +void ssl_util_ppclose(server_rec *, apr_pool_t *, apr_file_t *); +char *ssl_util_readfilter(server_rec *, apr_pool_t *, const char *, + const char * const *); +BOOL ssl_util_path_check(ssl_pathcheck_t, const char *, apr_pool_t *); +ssl_algo_t ssl_util_algotypeof(X509 *, EVP_PKEY *); +char *ssl_util_algotypestr(ssl_algo_t); +void ssl_util_thread_setup(apr_pool_t *); +int ssl_init_ssl_connection(conn_rec *c); + +/* Pass Phrase Support */ +void ssl_pphrase_Handle(server_rec *, apr_pool_t *); + +/* Diffie-Hellman Parameter Support */ +DH *ssl_dh_GetTmpParam(int); +DH *ssl_dh_GetParamFromFile(char *); + +unsigned char *ssl_asn1_table_set(apr_hash_t *table, + const char *key, + long int length); + +ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, + const char *key); + +void ssl_asn1_table_unset(apr_hash_t *table, + const char *key); + +const char *ssl_asn1_keystr(int keytype); + +const char *ssl_asn1_table_keyfmt(apr_pool_t *p, + const char *id, + int keytype); +/* Mutex Support */ +int ssl_mutex_init(server_rec *, apr_pool_t *); +int ssl_mutex_reinit(server_rec *, apr_pool_t *); +int ssl_mutex_on(server_rec *); +int ssl_mutex_off(server_rec *); + +/* Logfile Support */ +void ssl_die(void); +void ssl_log_ssl_error(const char *, int, int, server_rec *); + +/* Variables */ +void ssl_var_register(void); +char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *); +const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, const char *oid); + +void ssl_var_log_config_register(apr_pool_t *p); + +#define APR_SHM_MAXSIZE (64 * 1024 * 1024) + +#endif /* SSL_PRIVATE_H */ diff --git a/trunk/modules/ssl/ssl_scache.c b/trunk/modules/ssl/ssl_scache.c new file mode 100644 index 0000000000..877dc0779d --- /dev/null +++ b/trunk/modules/ssl/ssl_scache.c @@ -0,0 +1,176 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_scache.c + * Session Cache Abstraction + */ + /* ``Open-Source Software: generous + programmers from around the world all + join forces to help you shoot + yourself in the foot for free.'' + -- Unknown */ +#include "ssl_private.h" +#include "mod_status.h" + +/* _________________________________________________________________ +** +** Session Cache: Common Abstraction Layer +** _________________________________________________________________ +*/ + +void ssl_scache_init(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + + /* + * Warn the user that he should use the session cache. + * But we can operate without it, of course. + */ + if (mc->nSessionCacheMode == SSL_SCMODE_UNSET) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Init: Session Cache is not configured " + "[hint: SSLSessionCache]"); + mc->nSessionCacheMode = SSL_SCMODE_NONE; + return; + } + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_init(s, p); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_init(s, p); +#endif + else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) { + void *data; + const char *userdata_key = "ssl_scache_init"; + + apr_pool_userdata_get(&data, userdata_key, s->process->pool); + if (!data) { + apr_pool_userdata_set((const void *)1, userdata_key, + apr_pool_cleanup_null, s->process->pool); + return; + } + ssl_scache_shmcb_init(s, p); + } +} + +void ssl_scache_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_kill(s); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) + ssl_scache_shmcb_kill(s); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_kill(s); +#endif + return; +} + +BOOL ssl_scache_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess) +{ + SSLModConfigRec *mc = myModConfig(s); + BOOL rv = FALSE; + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + rv = ssl_scache_dbm_store(s, id, idlen, expiry, sess); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) + rv = ssl_scache_shmcb_store(s, id, idlen, expiry, sess); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + rv = ssl_scache_dc_store(s, id, idlen, expiry, sess); +#endif + return rv; +} + +SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + SSL_SESSION *sess = NULL; + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + sess = ssl_scache_dbm_retrieve(s, id, idlen); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) + sess = ssl_scache_shmcb_retrieve(s, id, idlen); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + sess = ssl_scache_dc_retrieve(s, id, idlen); +#endif + return sess; +} + +void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_remove(s, id, idlen); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) + ssl_scache_shmcb_remove(s, id, idlen); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_remove(s, id, idlen); +#endif + return; +} + +/* _________________________________________________________________ +** +** SSL Extension to mod_status +** _________________________________________________________________ +*/ +static int ssl_ext_status_hook(request_rec *r, int flags) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + + if (sc == NULL || flags & AP_STATUS_SHORT) + return OK; + + ap_rputs("
    \n", r); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rputs("\n", r); + ap_rputs("
    \n", r); + ap_rputs("SSL/TLS Session Cache Status:\r", r); + ap_rputs("
    \n", r); + + if (sc->mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_status(r, flags, r->pool); + else if (sc->mc->nSessionCacheMode == SSL_SCMODE_SHMCB) + ssl_scache_shmcb_status(r, flags, r->pool); +#ifdef HAVE_DISTCACHE + else if (sc->mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_status(r, flags, r->pool); +#endif + + ap_rputs("
    \n", r); + return OK; +} + +void ssl_scache_status_register(apr_pool_t *p) +{ + APR_OPTIONAL_HOOK(ap, status_hook, ssl_ext_status_hook, NULL, NULL, + APR_HOOK_MIDDLE); +} + diff --git a/trunk/modules/ssl/ssl_scache_dbm.c b/trunk/modules/ssl/ssl_scache_dbm.c new file mode 100644 index 0000000000..aa345b5711 --- /dev/null +++ b/trunk/modules/ssl/ssl_scache_dbm.c @@ -0,0 +1,463 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_scache_dbm.c + * Session Cache via DBM + */ + +#include "ssl_private.h" + +static void ssl_scache_dbm_expire(server_rec *s); + +void ssl_scache_dbm_init(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_dbm_t *dbm; + apr_status_t rv; + + /* for the DBM we need the data file */ + if (mc->szSessionCacheDataFile == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "SSLSessionCache required"); + ssl_die(); + } + + /* open it once to create it and to make sure it _can_ be created */ + ssl_mutex_on(s); + if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot create SSLSessionCache DBM file `%s'", + mc->szSessionCacheDataFile); + ssl_mutex_off(s); + return; + } + apr_dbm_close(dbm); + +#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) + /* + * We have to make sure the Apache child processes have access to + * the DBM file. But because there are brain-dead platforms where we + * cannot exactly determine the suffixes we try all possibilities. + */ + if (geteuid() == 0 /* is superuser */) { + chown(mc->szSessionCacheDataFile, unixd_config.user_id, -1 /* no gid change */); + if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL), + unixd_config.user_id, -1) == -1) { + if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + unixd_config.user_id, -1) == -1) + chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL), + unixd_config.user_id, -1); + } + if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL), + unixd_config.user_id, -1) == -1) { + if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + unixd_config.user_id, -1) == -1) + chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL), + unixd_config.user_id, -1); + } + } +#endif + ssl_mutex_off(s); + ssl_scache_dbm_expire(s); + return; +} + +void ssl_scache_dbm_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_pool_t *p; + + apr_pool_create_ex(&p, mc->pPool, NULL, NULL); + if (p != NULL) { + /* the correct way */ + unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL)); + unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL)); + /* the additional ways to be sure */ + unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL)); + unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL)); + unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL)); + unlink(mc->szSessionCacheDataFile); + apr_pool_destroy(p); + } + return; +} + +BOOL ssl_scache_dbm_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_dbm_t *dbm; + apr_datum_t dbmkey; + apr_datum_t dbmval; + UCHAR ucaData[SSL_SESSION_MAX_DER]; + int nData; + UCHAR *ucp; + apr_status_t rv; + + /* streamline session data */ + if ((nData = i2d_SSL_SESSION(sess, NULL)) > sizeof(ucaData)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "streamline session data size too large: %d > " + "%" APR_SIZE_T_FMT, + nData, sizeof(ucaData)); + return FALSE; + } + ucp = ucaData; + i2d_SSL_SESSION(sess, &ucp); + + /* be careful: do not try to store too much bytes in a DBM file! */ +#ifdef PAIRMAX + if ((idlen + nData) >= PAIRMAX) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "data size too large for DBM session cache: %d >= %d", + (idlen + nData), PAIRMAX); + return FALSE; + } +#else + if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "data size too large for DBM session cache: %d >= %d", + (idlen + nData), 950); + return FALSE; + } +#endif + + /* create DBM key */ + dbmkey.dptr = (char *)id; + dbmkey.dsize = idlen; + + /* create DBM value */ + dbmval.dsize = sizeof(time_t) + nData; + dbmval.dptr = (char *)malloc(dbmval.dsize); + if (dbmval.dptr == NULL) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "malloc error creating DBM value"); + return FALSE; + } + memcpy((char *)dbmval.dptr, &expiry, sizeof(time_t)); + memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData); + + /* and store it to the DBM file */ + ssl_mutex_on(s); + if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot open SSLSessionCache DBM file `%s' for writing " + "(store)", + mc->szSessionCacheDataFile); + ssl_mutex_off(s); + free(dbmval.dptr); + return FALSE; + } + if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot store SSL session to DBM file `%s'", + mc->szSessionCacheDataFile); + apr_dbm_close(dbm); + ssl_mutex_off(s); + free(dbmval.dptr); + return FALSE; + } + apr_dbm_close(dbm); + ssl_mutex_off(s); + + /* free temporary buffers */ + free(dbmval.dptr); + + /* allow the regular expiring to occur */ + ssl_scache_dbm_expire(s); + + return TRUE; +} + +SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_dbm_t *dbm; + apr_datum_t dbmkey; + apr_datum_t dbmval; + SSL_SESSION *sess = NULL; + UCHAR *ucpData; + int nData; + time_t expiry; + time_t now; + apr_status_t rc; + + /* allow the regular expiring to occur */ + ssl_scache_dbm_expire(s); + + /* create DBM key and values */ + dbmkey.dptr = (char *)id; + dbmkey.dsize = idlen; + + /* and fetch it from the DBM file + * XXX: Should we open the dbm against r->pool so the cleanup will + * do the apr_dbm_close? This would make the code a bit cleaner. + */ + ssl_mutex_on(s); + if ((rc = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, + "Cannot open SSLSessionCache DBM file `%s' for reading " + "(fetch)", + mc->szSessionCacheDataFile); + ssl_mutex_off(s); + return NULL; + } + rc = apr_dbm_fetch(dbm, dbmkey, &dbmval); + if (rc != APR_SUCCESS) { + apr_dbm_close(dbm); + ssl_mutex_off(s); + return NULL; + } + if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) { + apr_dbm_close(dbm); + ssl_mutex_off(s); + return NULL; + } + + /* parse resulting data */ + nData = dbmval.dsize-sizeof(time_t); + ucpData = (UCHAR *)malloc(nData); + if (ucpData == NULL) { + apr_dbm_close(dbm); + ssl_mutex_off(s); + return NULL; + } + memcpy(ucpData, (char *)dbmval.dptr+sizeof(time_t), nData); + memcpy(&expiry, dbmval.dptr, sizeof(time_t)); + + apr_dbm_close(dbm); + ssl_mutex_off(s); + + /* make sure the stuff is still not expired */ + now = time(NULL); + if (expiry <= now) { + ssl_scache_dbm_remove(s, id, idlen); + return NULL; + } + + /* unstreamed SSL_SESSION */ + sess = d2i_SSL_SESSION(NULL, &ucpData, nData); + + return sess; +} + +void ssl_scache_dbm_remove(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + apr_dbm_t *dbm; + apr_datum_t dbmkey; + apr_status_t rv; + + /* create DBM key and values */ + dbmkey.dptr = (char *)id; + dbmkey.dsize = idlen; + + /* and delete it from the DBM file */ + ssl_mutex_on(s); + if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot open SSLSessionCache DBM file `%s' for writing " + "(delete)", + mc->szSessionCacheDataFile); + ssl_mutex_off(s); + return; + } + apr_dbm_delete(dbm, dbmkey); + apr_dbm_close(dbm); + ssl_mutex_off(s); + + return; +} + +static void ssl_scache_dbm_expire(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + SSLSrvConfigRec *sc = mySrvConfig(s); + static time_t tLast = 0; + apr_dbm_t *dbm; + apr_datum_t dbmkey; + apr_datum_t dbmval; + apr_pool_t *p; + time_t tExpiresAt; + int nElements = 0; + int nDeleted = 0; + int bDelete; + apr_datum_t *keylist; + int keyidx; + int i; + time_t tNow; + apr_status_t rv; + + /* + * make sure the expiration for still not-accessed session + * cache entries is done only from time to time + */ + tNow = time(NULL); + if (tNow < tLast+sc->session_cache_timeout) + return; + tLast = tNow; + + /* + * Here we have to be very carefully: Not all DBM libraries are + * smart enough to allow one to iterate over the elements and at the + * same time delete expired ones. Some of them get totally crazy + * while others have no problems. So we have to do it the slower but + * more safe way: we first iterate over all elements and remember + * those which have to be expired. Then in a second pass we delete + * all those expired elements. Additionally we reopen the DBM file + * to be really safe in state. + */ + +#define KEYMAX 1024 + + ssl_mutex_on(s); + for (;;) { + /* allocate the key array in a memory sub pool */ + apr_pool_create_ex(&p, mc->pPool, NULL, NULL); + if (p == NULL) + break; + if ((keylist = apr_palloc(p, sizeof(dbmkey)*KEYMAX)) == NULL) { + apr_pool_destroy(p); + break; + } + + /* pass 1: scan DBM database */ + keyidx = 0; + if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, + p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot open SSLSessionCache DBM file `%s' for " + "scanning", + mc->szSessionCacheDataFile); + apr_pool_destroy(p); + break; + } + apr_dbm_firstkey(dbm, &dbmkey); + while (dbmkey.dptr != NULL) { + nElements++; + bDelete = FALSE; + apr_dbm_fetch(dbm, dbmkey, &dbmval); + if (dbmval.dsize <= sizeof(time_t) || dbmval.dptr == NULL) + bDelete = TRUE; + else { + memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t)); + if (tExpiresAt <= tNow) + bDelete = TRUE; + } + if (bDelete) { + if ((keylist[keyidx].dptr = apr_palloc(p, dbmkey.dsize)) != NULL) { + memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize); + keylist[keyidx].dsize = dbmkey.dsize; + keyidx++; + if (keyidx == KEYMAX) + break; + } + } + apr_dbm_nextkey(dbm, &dbmkey); + } + apr_dbm_close(dbm); + + /* pass 2: delete expired elements */ + if (apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, p) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "Cannot re-open SSLSessionCache DBM file `%s' for " + "expiring", + mc->szSessionCacheDataFile); + apr_pool_destroy(p); + break; + } + for (i = 0; i < keyidx; i++) { + apr_dbm_delete(dbm, keylist[i]); + nDeleted++; + } + apr_dbm_close(dbm); + + /* destroy temporary pool */ + apr_pool_destroy(p); + + if (keyidx < KEYMAX) + break; + } + ssl_mutex_off(s); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Inter-Process Session Cache (DBM) Expiry: " + "old: %d, new: %d, removed: %d", + nElements, nElements-nDeleted, nDeleted); + return; +} + +void ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(r->server); + apr_dbm_t *dbm; + apr_datum_t dbmkey; + apr_datum_t dbmval; + int nElem; + int nSize; + int nAverage; + apr_status_t rv; + + nElem = 0; + nSize = 0; + ssl_mutex_on(r->server); + /* + * XXX - Check what pool is to be used - TBD + */ + if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, + APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, + mc->pPool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Cannot open SSLSessionCache DBM file `%s' for status " + "retrival", + mc->szSessionCacheDataFile); + ssl_mutex_off(r->server); + return; + } + /* + * XXX - Check the return value of apr_dbm_firstkey, apr_dbm_fetch - TBD + */ + apr_dbm_firstkey(dbm, &dbmkey); + for ( ; dbmkey.dptr != NULL; apr_dbm_nextkey(dbm, &dbmkey)) { + apr_dbm_fetch(dbm, dbmkey, &dbmval); + if (dbmval.dptr == NULL) + continue; + nElem += 1; + nSize += dbmval.dsize; + } + apr_dbm_close(dbm); + ssl_mutex_off(r->server); + if (nSize > 0 && nElem > 0) + nAverage = nSize / nElem; + else + nAverage = 0; + ap_rprintf(r, "cache type: DBM, maximum size: unlimited
    "); + ap_rprintf(r, "current sessions: %d, current size: %d bytes
    ", nElem, nSize); + ap_rprintf(r, "average session size: %d bytes
    ", nAverage); + return; +} + diff --git a/trunk/modules/ssl/ssl_scache_dc.c b/trunk/modules/ssl/ssl_scache_dc.c new file mode 100644 index 0000000000..d8aa1eb2a9 --- /dev/null +++ b/trunk/modules/ssl/ssl_scache_dc.c @@ -0,0 +1,176 @@ +/* Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_scache_dc.c + * Distributed Session Cache (client support) + */ + +#include "ssl_private.h" + +/* Only build this code if it's enabled at configure-time. */ +#ifdef HAVE_DISTCACHE + +#include "distcache/dc_client.h" + +#if !defined(DISTCACHE_CLIENT_API) || (DISTCACHE_CLIENT_API < 0x0001) +#error "You must compile with a more recent version of the distcache-base package" +#endif + +/* + * This cache implementation allows modssl to access 'distcache' servers (or + * proxies) to facilitate distributed session caching. It is based on code + * released as open source by Cryptographic Appliances Inc, and was developed by + * Geoff Thorpe, Steve Robb, and Chris Zimmerman. + */ + +/* +** +** High-Level "handlers" as per ssl_scache.c +** +*/ + +void ssl_scache_dc_init(server_rec *s, apr_pool_t *p) +{ + DC_CTX *ctx; + SSLModConfigRec *mc = myModConfig(s); + /* + * Create a session context + */ + if (mc->szSessionCacheDataFile == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); + ssl_die(); + } +#if 0 + /* If a "persistent connection" mode of operation is preferred, you *must* + * also use the PIDCHECK flag to ensure fork()'d processes don't interlace + * comms on the same connection as each other. */ +#define SESSION_CTX_FLAGS SESSION_CTX_FLAG_PERSISTENT | \ + SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \ + SESSION_CTX_FLAG_PERSISTENT_RETRY | \ + SESSION_CTX_FLAG_PERSISTENT_LATE +#else + /* This mode of operation will open a temporary connection to the 'target' + * for each cache operation - this makes it safe against fork() + * automatically. This mode is preferred when running a local proxy (over + * unix domain sockets) because overhead is negligable and it reduces the + * performance/stability danger of file-descriptor bloatage. */ +#define SESSION_CTX_FLAGS 0 +#endif + ctx = DC_CTX_new(mc->szSessionCacheDataFile, SESSION_CTX_FLAGS); + if (!ctx) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache failed to obtain context"); + ssl_die(); + } + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "distributed scache context initialised"); + /* + * Success ... + */ + mc->tSessionCacheDataTable = ctx; + return; +} + +void ssl_scache_dc_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (mc->tSessionCacheDataTable) + DC_CTX_free(mc->tSessionCacheDataTable); + mc->tSessionCacheDataTable = NULL; +} + +BOOL ssl_scache_dc_store(server_rec *s, UCHAR *id, int idlen, + time_t timeout, SSL_SESSION * pSession) +{ + unsigned char der[SSL_SESSION_MAX_DER]; + int der_len; + unsigned char *pder = der; + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Serialise the SSL_SESSION object */ + if ((der_len = i2d_SSL_SESSION(pSession, NULL)) > SSL_SESSION_MAX_DER) + return FALSE; + i2d_SSL_SESSION(pSession, &pder); + /* !@#$%^ - why do we deal with *absolute* time anyway??? */ + timeout -= time(NULL); + /* Send the serialised session to the distributed cache context */ + if (!DC_CTX_add_session(ctx, id, idlen, der, der_len, + (unsigned long)timeout * 1000)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed"); + return FALSE; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'add_session' successful"); + return TRUE; +} + +SSL_SESSION *ssl_scache_dc_retrieve(server_rec *s, UCHAR *id, int idlen) +{ + unsigned char der[SSL_SESSION_MAX_DER]; + unsigned int der_len; + SSL_SESSION *pSession; + unsigned char *pder = der; + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Retrieve any corresponding session from the distributed cache context */ + if (!DC_CTX_get_session(ctx, id, idlen, der, SSL_SESSION_MAX_DER, + &der_len)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS"); + return NULL; + } + if (der_len > SSL_SESSION_MAX_DER) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW"); + return NULL; + } + pSession = d2i_SSL_SESSION(NULL, &pder, der_len); + if (!pSession) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' CORRUPT"); + return NULL; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT"); + return pSession; +} + +void ssl_scache_dc_remove(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Remove any corresponding session from the distributed cache context */ + if (!DC_CTX_remove_session(ctx, id, idlen)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' MISS"); + } else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' HIT"); + } +} + +void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool) +{ + SSLModConfigRec *mc = myModConfig(r->server); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "distributed scache 'ssl_scache_dc_status'"); + ap_rprintf(r, "cache type: DC (Distributed Cache), " + " target: %s
    ", mc->szSessionCacheDataFile); +} + +#endif + diff --git a/trunk/modules/ssl/ssl_scache_shmcb.c b/trunk/modules/ssl/ssl_scache_shmcb.c new file mode 100644 index 0000000000..45ca10002e --- /dev/null +++ b/trunk/modules/ssl/ssl_scache_shmcb.c @@ -0,0 +1,1343 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_scache_shmcb.c + * Session Cache via Shared Memory (Cyclic Buffer Variant) + */ + +#include "ssl_private.h" + +/* + * This shared memory based SSL session cache implementation was + * originally written by Geoff Thorpe for C2Net + * Europe as a contribution to Ralf Engelschall's mod_ssl project. + */ + +/* + * The shared-memory segment header can be cast to and from the + * SHMCBHeader type, all other structures need to be initialised by + * utility functions. + * + * The "header" looks like this; + * + * data applying to the overall structure: + * - division_offset (unsigned int): + * how far into the shared memory segment the first division is. + * - division_size (unsigned int): + * how many bytes each division occupies. + * (NB: This includes the queue and the cache) + * - division_mask (unsigned char): + * the "mask" in the next line. Add one to this, + * and that's the number of divisions. + * + * data applying to within each division: + * - queue_size (unsigned int): + * how big each "queue" is. NB: The queue is the first block in each + * division and is followed immediately by the cache itself so so + * there's no cache_offset value. + * + * data applying to within each queue: + * - index_num (unsigned char): + * how many indexes in each cache's queue + * - index_offset (unsigned char): + * how far into the queue the first index is. + * - index_size: + * how big each index is. + * + * data applying to within each cache: + * - cache_data_offset (unsigned int): + * how far into the cache the session-data array is stored. + * - cache_data_size (unsigned int): + * how big each cache's data block is. + * + * statistics data (this will eventually be per-division but right now + * there's only one mutex): + * - stores (unsigned long): + * how many stores have been performed in the cache. + * - expiries (unsigned long): + * how many session have been expired from the cache. + * - scrolled (unsigned long): + * how many sessions have been scrolled out of full cache during a + * "store" operation. This is different to the "removes" stats as + * they are requested by mod_ssl/Apache, these are done because of + * cache logistics. (NB: Also, this value should be deducible from + * the others if my code has no bugs, but I count it anyway - plus + * it helps debugging :-). + * - retrieves_hit (unsigned long): + * how many session-retrieves have succeeded. + * - retrieves_miss (unsigned long): + * how many session-retrieves have failed. + * - removes_hit (unsigned long): + * - removes_miss (unsigned long): + * + * Following immediately after the header is an array of "divisions". + * Each division is simply a "queue" immediately followed by its + * corresponding "cache". Each division handles some pre-defined band + * of sessions by using the "division_mask" in the header. Eg. if + * division_mask=0x1f then there are 32 divisions, the first of which + * will store sessions whose least-significant 5 bits are 0, the second + * stores session whose LS 5 bits equal 1, etc. A queue is an indexing + * structure referring to its corresponding cache. + * + * A "queue" looks like this; + * + * - first_pos (unsigned int): + * the location within the array of indexes where the virtual + * "left-hand-edge" of the cyclic buffer is. + * - pos_count (unsigned int): + * the number of indexes occupied from first_pos onwards. + * + * ...followed by an array of indexes, each of which can be + * memcpy'd to and from an SHMCBIndex, and look like this; + * + * - expires (time_t): + * the time() value at which this session expires. + * - offset (unsigned int): + * the offset within the cache data block where the corresponding + * session is stored. + * - s_id2 (unsigned char): + * the second byte of the session_id, stored as an optimisation to + * reduce the number of d2i_SSL_SESSION calls that are made when doing + * a lookup. + * - removed (unsigned char): + * a byte used to indicate whether a session has been "passively" + * removed. Ie. it is still in the cache but is to be disregarded by + * any "retrieve" operation. + * + * A "cache" looks like this; + * + * - first_pos (unsigned int): + * the location within the data block where the virtual + * "left-hand-edge" of the cyclic buffer is. + * - pos_count (unsigned int): + * the number of bytes used in the data block from first_pos onwards. + * + * ...followed by the data block in which actual DER-encoded SSL + * sessions are stored. + */ + +/* + * Header - can be memcpy'd to and from the front of the shared + * memory segment. NB: The first copy (commented out) has the + * elements in a meaningful order, but due to data-alignment + * braindeadness, the second (uncommented) copy has the types grouped + * so as to decrease "struct-bloat". sigh. + */ +typedef struct { + unsigned long num_stores; + unsigned long num_expiries; + unsigned long num_scrolled; + unsigned long num_retrieves_hit; + unsigned long num_retrieves_miss; + unsigned long num_removes_hit; + unsigned long num_removes_miss; + unsigned int division_offset; + unsigned int division_size; + unsigned int queue_size; + unsigned int cache_data_offset; + unsigned int cache_data_size; + unsigned char division_mask; + unsigned int index_num; + unsigned int index_offset; + unsigned int index_size; +} SHMCBHeader; + +/* + * Index - can be memcpy'd to and from an index inside each + * queue's index array. + */ +typedef struct { + time_t expires; + unsigned int offset; + unsigned char s_id2; + unsigned char removed; +} SHMCBIndex; + +/* + * Queue - must be populated by a call to shmcb_get_division + * and the structure's pointers are used for updating (ie. + * the structure doesn't need any "set" to update values). + */ +typedef struct { + SHMCBHeader *header; + unsigned int *first_pos; + unsigned int *pos_count; + SHMCBIndex *indexes; +} SHMCBQueue; + +/* + * Cache - same comment as for Queue. 'Queue's are in a 1-1 + * correspondance with 'Cache's and are usually carried round + * in a pair, they are only seperated for clarity. + */ +typedef struct { + SHMCBHeader *header; + unsigned int *first_pos; + unsigned int *pos_count; + unsigned char *data; +} SHMCBCache; + +/* + * Forward function prototypes. + */ + +/* Functions for working around data-alignment-picky systems (sparcs, + Irix, etc). These use "memcpy" as a way of foxing these systems into + treating the composite types as byte-arrays rather than higher-level + primitives that it prefers to have 4-(or 8-)byte aligned. I don't + envisage this being a performance issue as a couple of 2 or 4 byte + memcpys can hardly make a dent on the massive memmove operations this + cache technique avoids, nor the overheads of ASN en/decoding. */ +static unsigned int shmcb_get_safe_uint(unsigned int *); +static void shmcb_set_safe_uint_ex(unsigned char *, const unsigned char *); +#define shmcb_set_safe_uint(pdest, src) \ + do { \ + unsigned int tmp_uint = src; \ + shmcb_set_safe_uint_ex((unsigned char *)pdest, \ + (const unsigned char *)(&tmp_uint)); \ + } while(0) +#if 0 /* Unused so far */ +static unsigned long shmcb_get_safe_ulong(unsigned long *); +static void shmcb_set_safe_ulong_ex(unsigned char *, const unsigned char *); +#define shmcb_set_safe_ulong(pdest, src) \ + do { \ + unsigned long tmp_ulong = src; \ + shmcb_set_safe_ulong_ex((unsigned char *)pdest, \ + (const unsigned char *)(&tmp_ulong)); \ + } while(0) +#endif +static time_t shmcb_get_safe_time(time_t *); +static void shmcb_set_safe_time_ex(unsigned char *, const unsigned char *); +#define shmcb_set_safe_time(pdest, src) \ + do { \ + time_t tmp_time = src; \ + shmcb_set_safe_time_ex((unsigned char *)pdest, \ + (const unsigned char *)(&tmp_time)); \ + } while(0) + +/* This is necessary simply so that the size passed to memset() is not a + * compile-time constant, preventing the compiler from optimising it. */ +static void shmcb_safe_clear(void *ptr, size_t size) +{ + memset(ptr, 0, size); +} + +/* Underlying functions for session-caching */ +static BOOL shmcb_init_memory(server_rec *, void *, unsigned int); +static BOOL shmcb_store_session(server_rec *, void *, UCHAR *, int, SSL_SESSION *, time_t); +static SSL_SESSION *shmcb_retrieve_session(server_rec *, void *, UCHAR *, int); +static BOOL shmcb_remove_session(server_rec *, void *, UCHAR *, int); + +/* Utility functions for manipulating the structures */ +static void shmcb_get_header(void *, SHMCBHeader **); +static BOOL shmcb_get_division(SHMCBHeader *, SHMCBQueue *, SHMCBCache *, unsigned int); +static SHMCBIndex *shmcb_get_index(const SHMCBQueue *, unsigned int); +static unsigned int shmcb_expire_division(server_rec *, SHMCBQueue *, SHMCBCache *); +static BOOL shmcb_insert_encoded_session(server_rec *, SHMCBQueue *, SHMCBCache *, unsigned char *, unsigned int, unsigned char *, time_t); +static SSL_SESSION *shmcb_lookup_session_id(server_rec *, SHMCBQueue *, SHMCBCache *, UCHAR *, unsigned int); +static BOOL shmcb_remove_session_id(server_rec *, SHMCBQueue *, SHMCBCache *, UCHAR *, unsigned int); + +/* + * Data-alignment functions (a.k.a. avoidance tactics) + * + * NB: On HPUX (and possibly others) there is a *very* mischievous little + * "optimisation" in the compilers where it will convert the following; + * memcpy(dest_ptr, &source, sizeof(unsigned int)); + * (where dest_ptr is of type (unsigned int *) and source is (unsigned int)) + * into; + * *dest_ptr = source; (or *dest_ptr = *(&source), not sure). + * Either way, it completely destroys the whole point of these _safe_ + * functions, because the assignment operation will fall victim to the + * architecture's byte-alignment dictations, whereas the memcpy (as a + * byte-by-byte copy) should not. sigh. So, if you're wondering about the + * apparently unnecessary conversions to (unsigned char *) in these + * functions, you now have an explanation. Don't just revert them back and + * say "ooh look, it still works" - if you try it on HPUX (well, 32-bit + * HPUX 11.00 at least) you may find it fails with a SIGBUS. :-( + */ + +static unsigned int shmcb_get_safe_uint(unsigned int *ptr) +{ + unsigned int ret; + shmcb_set_safe_uint_ex((unsigned char *)(&ret), + (const unsigned char *)ptr); + return ret; +} + +static void shmcb_set_safe_uint_ex(unsigned char *dest, + const unsigned char *src) +{ + memcpy(dest, src, sizeof(unsigned int)); +} + +#if 0 /* Unused so far */ +static unsigned long shmcb_get_safe_ulong(unsigned long *ptr) +{ + unsigned long ret; + shmcb_set_safe_ulong_ex((unsigned char *)(&ret), + (const unsigned char *)ptr); + return ret; +} + +static void shmcb_set_safe_ulong_ex(unsigned char *dest, + const unsigned char *src) +{ + memcpy(dest, src, sizeof(unsigned long)); +} +#endif + +static time_t shmcb_get_safe_time(time_t * ptr) +{ + time_t ret; + shmcb_set_safe_time_ex((unsigned char *)(&ret), + (const unsigned char *)ptr); + return ret; +} + +static void shmcb_set_safe_time_ex(unsigned char *dest, + const unsigned char *src) +{ + memcpy(dest, src, sizeof(time_t)); +} +/* +** +** High-Level "handlers" as per ssl_scache.c +** +*/ + +void ssl_scache_shmcb_init(server_rec *s, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(s); + void *shm_segment; + apr_size_t shm_segsize; + apr_status_t rv; + + /* + * Create shared memory segment + */ + if (mc->szSessionCacheDataFile == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "SSLSessionCache required"); + ssl_die(); + } + + /* Use anonymous shm by default, fall back on name-based. */ + rv = apr_shm_create(&(mc->pSessionCacheDataMM), + mc->nSessionCacheDataSize, + NULL, mc->pPool); + + if (APR_STATUS_IS_ENOTIMPL(rv)) { + /* For a name-based segment, remove it first in case of a + * previous unclean shutdown. */ + apr_shm_remove(mc->szSessionCacheDataFile, mc->pPool); + + rv = apr_shm_create(&(mc->pSessionCacheDataMM), + mc->nSessionCacheDataSize, + mc->szSessionCacheDataFile, + mc->pPool); + } + + if (rv != APR_SUCCESS) { + char buf[100]; + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Cannot allocate shared memory: (%d)%s", rv, + apr_strerror(rv, buf, sizeof(buf))); + ssl_die(); + } + shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM); + shm_segsize = apr_shm_size_get(mc->pSessionCacheDataMM); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "shmcb_init allocated %" APR_SIZE_T_FMT + " bytes of shared memory", + shm_segsize); + if (!shmcb_init_memory(s, shm_segment, shm_segsize)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Failure initialising 'shmcb' shared memory"); + ssl_die(); + } + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Shared memory session cache initialised"); + + /* + * Success ... + */ + mc->tSessionCacheDataTable = shm_segment; + return; +} + +void ssl_scache_shmcb_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (mc->pSessionCacheDataMM != NULL) { + apr_shm_destroy(mc->pSessionCacheDataMM); + mc->pSessionCacheDataMM = NULL; + } + return; +} + +BOOL ssl_scache_shmcb_store(server_rec *s, UCHAR *id, int idlen, + time_t timeout, SSL_SESSION * pSession) +{ + SSLModConfigRec *mc = myModConfig(s); + BOOL to_return = FALSE; + + ssl_mutex_on(s); + if (!shmcb_store_session(s, mc->tSessionCacheDataTable, id, idlen, + pSession, timeout)) + /* in this cache engine, "stores" should never fail. */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "'shmcb' code was unable to store a " + "session in the cache."); + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "shmcb_store successful"); + to_return = TRUE; + } + ssl_mutex_off(s); + return to_return; +} + +SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + SSL_SESSION *pSession; + + ssl_mutex_on(s); + pSession = shmcb_retrieve_session(s, mc->tSessionCacheDataTable, id, idlen); + ssl_mutex_off(s); + if (pSession) + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "shmcb_retrieve had a hit"); + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "shmcb_retrieve had a miss"); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Client requested a 'session-resume' but " + "we have no such session."); + } + return pSession; +} + +void ssl_scache_shmcb_remove(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + + ssl_mutex_on(s); + shmcb_remove_session(s, mc->tSessionCacheDataTable, id, idlen); + ssl_mutex_off(s); +} + +void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *p) +{ + SSLModConfigRec *mc = myModConfig(r->server); + SHMCBHeader *header; + SHMCBQueue queue; + SHMCBCache cache; + SHMCBIndex *idx; + unsigned int loop, total, cache_total, non_empty_divisions; + int index_pct, cache_pct; + double expiry_total; + time_t average_expiry, now, max_expiry, min_expiry, idxexpiry; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "inside shmcb_status"); + + /* Get the header structure. */ + shmcb_get_header(mc->tSessionCacheDataTable, &header); + total = cache_total = non_empty_divisions = 0; + average_expiry = max_expiry = min_expiry = 0; + expiry_total = 0; + + /* It may seem strange to grab "now" at this point, but in theory + * we should never have a negative threshold but grabbing "now" after + * the loop (which performs expiries) could allow that chance. */ + now = time(NULL); + for (loop = 0; loop <= header->division_mask; loop++) { + if (shmcb_get_division(header, &queue, &cache, loop)) { + shmcb_expire_division(r->server, &queue, &cache); + total += shmcb_get_safe_uint(queue.pos_count); + cache_total += shmcb_get_safe_uint(cache.pos_count); + if (shmcb_get_safe_uint(queue.pos_count) > 0) { + idx = shmcb_get_index(&queue, + shmcb_get_safe_uint(queue.first_pos)); + non_empty_divisions++; + idxexpiry = shmcb_get_safe_time(&(idx->expires)); + expiry_total += (double) idxexpiry; + max_expiry = (idxexpiry > max_expiry ? idxexpiry : + max_expiry); + if (min_expiry == 0) + min_expiry = idxexpiry; + else + min_expiry = (idxexpiry < min_expiry ? idxexpiry : + min_expiry); + } + } + } + index_pct = (100 * total) / (header->index_num * (header->division_mask + 1)); + cache_pct = (100 * cache_total) / (header->cache_data_size * (header->division_mask + 1)); + ap_rprintf(r, "cache type: SHMCB, shared memory: %d " + "bytes, current sessions: %d
    ", + mc->nSessionCacheDataSize, total); + ap_rprintf(r, "sub-caches: %d, indexes per sub-cache: " + "%d
    ", (int) header->division_mask + 1, + (int) header->index_num); + if (non_empty_divisions != 0) { + average_expiry = (time_t)(expiry_total / (double)non_empty_divisions); + ap_rprintf(r, "time left on oldest entries' SSL sessions: "); + if (now < average_expiry) + ap_rprintf(r, "avg: %d seconds, (range: %d...%d)
    ", + (int)(average_expiry - now), (int) (min_expiry - now), + (int)(max_expiry - now)); + else + ap_rprintf(r, "expiry threshold: Calculation Error!" + "
    "); + + } + ap_rprintf(r, "index usage: %d%%, cache usage: %d%%" + "
    ", index_pct, cache_pct); + ap_rprintf(r, "total sessions stored since starting: %lu
    ", + header->num_stores); + ap_rprintf(r, "total sessions expired since starting: %lu
    ", + header->num_expiries); + ap_rprintf(r, "total (pre-expiry) sessions scrolled out of the " + "cache: %lu
    ", header->num_scrolled); + ap_rprintf(r, "total retrieves since starting: %lu hit, " + "%lu miss
    ", header->num_retrieves_hit, + header->num_retrieves_miss); + ap_rprintf(r, "total removes since starting: %lu hit, " + "%lu miss
    ", header->num_removes_hit, + header->num_removes_miss); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status"); + return; +} + +/* +** +** Memory manipulation and low-level cache operations +** +*/ + +static BOOL shmcb_init_memory( + server_rec *s, void *shm_mem, + unsigned int shm_mem_size) +{ + SHMCBHeader *header; + SHMCBQueue queue; + SHMCBCache cache; + unsigned int temp, loop, granularity; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "entered shmcb_init_memory()"); + + /* Calculate some sizes... */ + temp = sizeof(SHMCBHeader); + + /* If the segment is ridiculously too small, bail out */ + if (shm_mem_size < (2*temp)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shared memory segment too small"); + return FALSE; + } + + /* Make temp the amount of memory without the header */ + temp = shm_mem_size - temp; + + /* Work on the basis that you need 10 bytes index for each session + * (approx 150 bytes), which is to divide temp by 160 - and then + * make sure we err on having too index space to burn even when + * the cache is full, which is a lot less stupid than having + * having not enough index space to utilise the whole cache!. */ + temp /= 120; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "for %u bytes, recommending %u indexes", + shm_mem_size, temp); + + /* We should divide these indexes evenly amongst the queues. Try + * to get it so that there are roughly half the number of divisions + * as there are indexes in each division. */ + granularity = 256; + while ((temp / granularity) < (2 * granularity)) + granularity /= 2; + + /* So we have 'granularity' divisions, set 'temp' equal to the + * number of indexes in each division. */ + temp /= granularity; + + /* Too small? Bail ... */ + if (temp < 5) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shared memory segment too small"); + return FALSE; + } + + /* OK, we're sorted - from here on in, the return should be TRUE */ + header = (SHMCBHeader *)shm_mem; + header->division_mask = (unsigned char)(granularity - 1); + header->division_offset = sizeof(SHMCBHeader); + header->index_num = temp; + header->index_offset = (2 * sizeof(unsigned int)); + header->index_size = sizeof(SHMCBIndex); + header->queue_size = header->index_offset + + (header->index_num * header->index_size); + + /* Now calculate the space for each division */ + temp = shm_mem_size - header->division_offset; + header->division_size = temp / granularity; + + /* Calculate the space left in each division for the cache */ + temp -= header->queue_size; + header->cache_data_offset = (2 * sizeof(unsigned int)); + header->cache_data_size = header->division_size - + header->queue_size - header->cache_data_offset; + + /* Output trace info */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "shmcb_init_memory choices follow"); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "division_mask = 0x%02X", header->division_mask); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "division_offset = %u", header->division_offset); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "division_size = %u", header->division_size); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "queue_size = %u", header->queue_size); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "index_num = %u", header->index_num); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "index_offset = %u", header->index_offset); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "index_size = %u", header->index_size); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "cache_data_offset = %u", header->cache_data_offset); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "cache_data_size = %u", header->cache_data_size); + + /* The header is done, make the caches empty */ + for (loop = 0; loop < granularity; loop++) { + if (!shmcb_get_division(header, &queue, &cache, loop)) + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shmcb_init_memory, " "internal error"); + shmcb_set_safe_uint(cache.first_pos, 0); + shmcb_set_safe_uint(cache.pos_count, 0); + shmcb_set_safe_uint(queue.first_pos, 0); + shmcb_set_safe_uint(queue.pos_count, 0); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_init_memory()"); + return TRUE; +} + +static BOOL shmcb_store_session( + server_rec *s, void *shm_segment, UCHAR *id, + int idlen, SSL_SESSION * pSession, + time_t timeout) +{ + SHMCBHeader *header; + SHMCBQueue queue; + SHMCBCache cache; + unsigned char masked_index; + unsigned char encoded[SSL_SESSION_MAX_DER]; + unsigned char *ptr_encoded; + unsigned int len_encoded; + time_t expiry_time; + unsigned char *session_id = SSL_SESSION_get_session_id(pSession); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "inside shmcb_store_session"); + + /* Get the header structure, which division this session will fall into etc. */ + shmcb_get_header(shm_segment, &header); + masked_index = session_id[0] & header->division_mask; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "session_id[0]=%u, masked index=%u", + session_id[0], masked_index); + if (!shmcb_get_division(header, &queue, &cache, (unsigned int)masked_index)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_store_session internal error"); + return FALSE; + } + + /* Serialise the session, work out how much we're dealing + * with. NB: This check could be removed if we're not paranoid + * or we find some assurance that it will never be necessary. */ + len_encoded = i2d_SSL_SESSION(pSession, NULL); + if (len_encoded > SSL_SESSION_MAX_DER) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "session is too big (%u bytes)", len_encoded); + return FALSE; + } + ptr_encoded = encoded; + len_encoded = i2d_SSL_SESSION(pSession, &ptr_encoded); + expiry_time = timeout; + if (!shmcb_insert_encoded_session(s, &queue, &cache, encoded, + len_encoded, session_id, + expiry_time)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "can't store a session!"); + return FALSE; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_store successfully"); + header->num_stores++; + return TRUE; +} + +static SSL_SESSION *shmcb_retrieve_session( + server_rec *s, void *shm_segment, + UCHAR *id, int idlen) +{ + SHMCBHeader *header; + SHMCBQueue queue; + SHMCBCache cache; + unsigned char masked_index; + SSL_SESSION *pSession; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "inside shmcb_retrieve_session"); + if (idlen < 2) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided " + "(%u bytes)", idlen); + return FALSE; + } + + /* Get the header structure, which division this session lookup + * will come from etc. */ + shmcb_get_header(shm_segment, &header); + masked_index = id[0] & header->division_mask; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "id[0]=%u, masked index=%u", id[0], masked_index); + if (!shmcb_get_division(header, &queue, &cache, (unsigned int) masked_index)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_retrieve_session internal error"); + header->num_retrieves_miss++; + return FALSE; + } + + /* Get the session corresponding to the session_id or NULL if it + * doesn't exist (or is flagged as "removed"). */ + pSession = shmcb_lookup_session_id(s, &queue, &cache, id, idlen); + if (pSession) + header->num_retrieves_hit++; + else + header->num_retrieves_miss++; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_retrieve_session"); + return pSession; +} + +static BOOL shmcb_remove_session( + server_rec *s, void *shm_segment, + UCHAR *id, int idlen) +{ + SHMCBHeader *header; + SHMCBQueue queue; + SHMCBCache cache; + unsigned char masked_index; + BOOL res; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "inside shmcb_remove_session"); + if (id == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "remove called with NULL session_id!"); + return FALSE; + } + + /* Get the header structure, which division this session remove + * will happen in etc. */ + shmcb_get_header(shm_segment, &header); + masked_index = id[0] & header->division_mask; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "id[0]=%u, masked index=%u", id[0], masked_index); + if (!shmcb_get_division(header, &queue, &cache, (unsigned int)masked_index)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "shmcb_remove_session, internal error"); + header->num_removes_miss++; + return FALSE; + } + res = shmcb_remove_session_id(s, &queue, &cache, id, idlen); + if (res) + header->num_removes_hit++; + else + header->num_removes_miss++; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_remove_session"); + return res; +} + + +/* +** +** Weirdo cyclic buffer functions +** +*/ + +/* This gets used in the cyclic "index array" (in the 'Queue's) and + * in the cyclic 'Cache's too ... you provide the "width" of the + * cyclic store, the starting position and how far to move (with + * wrapping if necessary). Basically it's addition modulo buf_size. */ +static unsigned int shmcb_cyclic_increment( + unsigned int buf_size, + unsigned int start_pos, + unsigned int to_add) +{ + start_pos += to_add; + while (start_pos >= buf_size) + start_pos -= buf_size; + return start_pos; +} + +/* Given two positions in a cyclic buffer, calculate the "distance". + * This is to cover the case ("non-trivial") where the 'next' offset + * is to the left of the 'start' offset. NB: This calculates the + * space inclusive of one end-point but not the other. There is an + * ambiguous case (which is why we use the + * coordinate system rather than one) when 'start' + * is the same as 'next'. It could indicate the buffer is full or it + * can indicate the buffer is empty ... I choose the latter as it's + * easier and usually necessary to check if the buffer is full anyway + * before doing incremental logic (which is this useful for), but we + * definitely need the empty case handled - in fact it's our starting + * state!! */ +static unsigned int shmcb_cyclic_space( + unsigned int buf_size, + unsigned int start_offset, + unsigned int next_offset) +{ + /* Is it the trivial case? */ + if (start_offset <= next_offset) + return (next_offset - start_offset); /* yes */ + else + return ((buf_size - start_offset) + next_offset); /* no */ +} + +/* A "normal-to-cyclic" memcpy ... this takes a linear block of + * memory and copies it onto a cyclic buffer. The purpose and + * function of this is pretty obvious, you need to cover the case + * that the destination (cyclic) buffer has to wrap round. */ +static void shmcb_cyclic_ntoc_memcpy( + unsigned int buf_size, + unsigned char *data, + unsigned int dest_offset, + unsigned char *src, unsigned int src_len) +{ + /* Cover the case that src_len > buf_size */ + if (src_len > buf_size) + src_len = buf_size; + + /* Can it be copied all in one go? */ + if (dest_offset + src_len < buf_size) + /* yes */ + memcpy(data + dest_offset, src, src_len); + else { + /* no */ + memcpy(data + dest_offset, src, buf_size - dest_offset); + memcpy(data, src + buf_size - dest_offset, + src_len + dest_offset - buf_size); + } + return; +} + +/* A "cyclic-to-normal" memcpy ... given the last function, this + * one's purpose is clear, it copies out of a cyclic buffer handling + * wrapping. */ +static void shmcb_cyclic_cton_memcpy( + unsigned int buf_size, + unsigned char *dest, + unsigned char *data, + unsigned int src_offset, + unsigned int src_len) +{ + /* Cover the case that src_len > buf_size */ + if (src_len > buf_size) + src_len = buf_size; + + /* Can it be copied all in one go? */ + if (src_offset + src_len < buf_size) + /* yes */ + memcpy(dest, data + src_offset, src_len); + else { + /* no */ + memcpy(dest, data + src_offset, buf_size - src_offset); + memcpy(dest + buf_size - src_offset, data, + src_len + src_offset - buf_size); + } + return; +} + +/* Here's the cool hack that makes it all work ... by simply + * making the first collection of bytes *be* our header structure + * (casting it into the C structure), we have the perfect way to + * maintain state in a shared-memory session cache from one call + * (and process) to the next, use the shared memory itself! The + * original mod_ssl shared-memory session cache uses variables + * inside the context, but we simply use that for storing the + * pointer to the shared memory itself. And don't forget, after + * Apache's initialisation, this "header" is constant/read-only + * so we can read it outside any locking. + * - sometimes I just *love* coding y'know?! */ +static void shmcb_get_header(void *shm_mem, SHMCBHeader **header) +{ + *header = (SHMCBHeader *)shm_mem; + return; +} + +/* This is what populates our "interesting" structures. Given a + * pointer to the header, and an index into the appropriate + * division (this must have already been masked using the + * division_mask by the caller!), we can populate the provided + * SHMCBQueue and SHMCBCache structures with values and + * pointers to the underlying shared memory. Upon returning + * (if not FALSE), the caller can meddle with the pointer + * values and they will map into the shared-memory directly, + * as such there's no need to "free" or "set" the Queue or + * Cache values, they were themselves references to the *real* + * data. */ +static BOOL shmcb_get_division( + SHMCBHeader *header, SHMCBQueue *queue, + SHMCBCache *cache, unsigned int idx) +{ + unsigned char *pQueue; + unsigned char *pCache; + + /* bounds check */ + if (idx > (unsigned int) header->division_mask) + return FALSE; + + /* Locate the blocks of memory storing the corresponding data */ + pQueue = ((unsigned char *) header) + header->division_offset + + (idx * header->division_size); + pCache = pQueue + header->queue_size; + + /* Populate the structures with appropriate pointers */ + queue->first_pos = (unsigned int *) pQueue; + + /* Our structures stay packed, no matter what the system's + * data-alignment regime is. */ + queue->pos_count = (unsigned int *) (pQueue + sizeof(unsigned int)); + queue->indexes = (SHMCBIndex *) (pQueue + (2 * sizeof(unsigned int))); + cache->first_pos = (unsigned int *) pCache; + cache->pos_count = (unsigned int *) (pCache + sizeof(unsigned int)); + cache->data = (unsigned char *) (pCache + (2 * sizeof(unsigned int))); + queue->header = cache->header = header; + + return TRUE; +} + +/* This returns a pointer to the piece of shared memory containing + * a specified 'Index'. SHMCBIndex, like SHMCBHeader, is a fixed + * width non-referencing structure of primitive types that can be + * cast onto the corresponding block of shared memory. Thus, by + * returning a cast pointer to that section of shared memory, the + * caller can read and write values to and from the "structure" and + * they are actually reading and writing the underlying shared + * memory. */ +static SHMCBIndex *shmcb_get_index( + const SHMCBQueue *queue, unsigned int idx) +{ + /* bounds check */ + if (idx > queue->header->index_num) + return NULL; + + /* Return a pointer to the index. NB: I am being horribly pendantic + * here so as to avoid any potential data-alignment assumptions being + * placed on the pointer arithmetic by the compiler (sigh). */ + return (SHMCBIndex *)(((unsigned char *) queue->indexes) + + (idx * sizeof(SHMCBIndex))); +} + +/* This functions rolls expired cache (and index) entries off the front + * of the cyclic buffers in a division. The function returns the number + * of expired sessions. */ +static unsigned int shmcb_expire_division( + server_rec *s, SHMCBQueue *queue, SHMCBCache *cache) +{ + SHMCBIndex *idx; + time_t now; + unsigned int loop, index_num, pos_count, new_pos; + SHMCBHeader *header; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "entering shmcb_expire_division"); + + /* We must calculate num and space ourselves based on expiry times. */ + now = time(NULL); + loop = 0; + new_pos = shmcb_get_safe_uint(queue->first_pos); + + /* Cache useful values */ + header = queue->header; + index_num = header->index_num; + pos_count = shmcb_get_safe_uint(queue->pos_count); + while (loop < pos_count) { + idx = shmcb_get_index(queue, new_pos); + if (shmcb_get_safe_time(&(idx->expires)) > now) + /* it hasn't expired yet, we're done iterating */ + break; + /* This one should be expired too. Shift to the next entry. */ + loop++; + new_pos = shmcb_cyclic_increment(index_num, new_pos, 1); + } + + /* Find the new_offset and make the expiries happen. */ + if (loop > 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "will be expiring %u sessions", loop); + /* We calculate the new_offset by "peeking" (or in the + * case it's the last entry, "sneaking" ;-). */ + if (loop == pos_count) { + /* We are expiring everything! This is easy to do... */ + shmcb_set_safe_uint(queue->pos_count, 0); + shmcb_set_safe_uint(cache->pos_count, 0); + } + else { + /* The Queue is easy to adjust */ + shmcb_set_safe_uint(queue->pos_count, + shmcb_get_safe_uint(queue->pos_count) - loop); + shmcb_set_safe_uint(queue->first_pos, new_pos); + /* peek to the start of the next session */ + idx = shmcb_get_index(queue, new_pos); + /* We can use shmcb_cyclic_space because we've guaranteed + * we don't fit the ambiguous full/empty case. */ + shmcb_set_safe_uint(cache->pos_count, + shmcb_get_safe_uint(cache->pos_count) - + shmcb_cyclic_space(header->cache_data_size, + shmcb_get_safe_uint(cache->first_pos), + shmcb_get_safe_uint(&(idx->offset)))); + shmcb_set_safe_uint(cache->first_pos, shmcb_get_safe_uint(&(idx->offset))); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "we now have %u sessions", + shmcb_get_safe_uint(queue->pos_count)); + } + header->num_expiries += loop; + return loop; +} + +/* Inserts a new encoded session into a queue/cache pair - expiring + * (early or otherwise) any leading sessions as necessary to ensure + * there is room. An error return (FALSE) should only happen in the + * event of surreal values being passed on, or ridiculously small + * cache sizes. NB: For tracing purposes, this function is also given + * the server_rec to allow "ssl_log()". */ +static BOOL shmcb_insert_encoded_session( + server_rec *s, SHMCBQueue * queue, + SHMCBCache * cache, + unsigned char *encoded, + unsigned int encoded_len, + unsigned char *session_id, + time_t expiry_time) +{ + SHMCBHeader *header; + SHMCBIndex *idx = NULL; + unsigned int gap, new_pos, loop, new_offset; + int need; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "entering shmcb_insert_encoded_session, " + "*queue->pos_count = %u", + shmcb_get_safe_uint(queue->pos_count)); + + /* If there's entries to expire, ditch them first thing. */ + shmcb_expire_division(s, queue, cache); + header = cache->header; + gap = header->cache_data_size - shmcb_get_safe_uint(cache->pos_count); + if (gap < encoded_len) { + new_pos = shmcb_get_safe_uint(queue->first_pos); + loop = 0; + need = (int) encoded_len - (int) gap; + while ((need > 0) && (loop + 1 < shmcb_get_safe_uint(queue->pos_count))) { + new_pos = shmcb_cyclic_increment(header->index_num, new_pos, 1); + loop += 1; + idx = shmcb_get_index(queue, new_pos); + need = (int) encoded_len - (int) gap - + shmcb_cyclic_space(header->cache_data_size, + shmcb_get_safe_uint(cache->first_pos), + shmcb_get_safe_uint(&(idx->offset))); + } + if (loop > 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "about to scroll %u sessions from %u", + loop, shmcb_get_safe_uint(queue->pos_count)); + /* We are removing "loop" items from the cache. */ + shmcb_set_safe_uint(cache->pos_count, + shmcb_get_safe_uint(cache->pos_count) - + shmcb_cyclic_space(header->cache_data_size, + shmcb_get_safe_uint(cache->first_pos), + shmcb_get_safe_uint(&(idx->offset)))); + shmcb_set_safe_uint(cache->first_pos, shmcb_get_safe_uint(&(idx->offset))); + shmcb_set_safe_uint(queue->pos_count, shmcb_get_safe_uint(queue->pos_count) - loop); + shmcb_set_safe_uint(queue->first_pos, new_pos); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "now only have %u sessions", + shmcb_get_safe_uint(queue->pos_count)); + /* Update the stats!!! */ + header->num_scrolled += loop; + } + } + + /* probably unecessary checks, but I'll leave them until this code + * is verified. */ + if (shmcb_get_safe_uint(cache->pos_count) + encoded_len > + header->cache_data_size) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_insert_encoded_session internal error"); + return FALSE; + } + if (shmcb_get_safe_uint(queue->pos_count) == header->index_num) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_insert_encoded_session internal error"); + return FALSE; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "we have %u bytes and %u indexes free - enough", + header->cache_data_size - + shmcb_get_safe_uint(cache->pos_count), header->index_num - + shmcb_get_safe_uint(queue->pos_count)); + + + /* HERE WE ASSUME THAT THE NEW SESSION SHOULD GO ON THE END! I'M NOT + * CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE. + * + * We either fix that, or find out at a "higher" (read "mod_ssl") + * level whether it is possible to have distinct session caches for + * any attempted tomfoolery to do with different session timeouts. + * Knowing in advance that we can have a cache-wide constant timeout + * would make this stuff *MUCH* more efficient. Mind you, it's very + * efficient right now because I'm ignoring this problem!!! + */ + + /* Increment to the first unused byte */ + new_offset = shmcb_cyclic_increment(header->cache_data_size, + shmcb_get_safe_uint(cache->first_pos), + shmcb_get_safe_uint(cache->pos_count)); + /* Copy the DER-encoded session into place */ + shmcb_cyclic_ntoc_memcpy(header->cache_data_size, cache->data, + new_offset, encoded, encoded_len); + /* Get the new index that this session is stored in. */ + new_pos = shmcb_cyclic_increment(header->index_num, + shmcb_get_safe_uint(queue->first_pos), + shmcb_get_safe_uint(queue->pos_count)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "storing in index %u, at offset %u", + new_pos, new_offset); + idx = shmcb_get_index(queue, new_pos); + if (idx == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_insert_encoded_session internal error"); + return FALSE; + } + shmcb_safe_clear(idx, sizeof(SHMCBIndex)); + shmcb_set_safe_time(&(idx->expires), expiry_time); + shmcb_set_safe_uint(&(idx->offset), new_offset); + + /* idx->removed = (unsigned char)0; */ /* Not needed given the memset above. */ + idx->s_id2 = session_id[1]; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "session_id[0]=%u, idx->s_id2=%u", + session_id[0], session_id[1]); + + /* All that remains is to adjust the cache's and queue's "pos_count"s. */ + shmcb_set_safe_uint(cache->pos_count, + shmcb_get_safe_uint(cache->pos_count) + encoded_len); + shmcb_set_safe_uint(queue->pos_count, + shmcb_get_safe_uint(queue->pos_count) + 1); + + /* And just for good debugging measure ... */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving now with %u bytes in the cache and %u indexes", + shmcb_get_safe_uint(cache->pos_count), + shmcb_get_safe_uint(queue->pos_count)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_insert_encoded_session"); + return TRUE; +} + +/* Performs a lookup into a queue/cache pair for a + * session_id. If found, the session is deserialised + * and returned, otherwise NULL. */ +static SSL_SESSION *shmcb_lookup_session_id( + server_rec *s, SHMCBQueue *queue, + SHMCBCache *cache, UCHAR *id, + unsigned int idlen) +{ + unsigned char tempasn[SSL_SESSION_MAX_DER]; + SHMCBIndex *idx; + SHMCBHeader *header; + SSL_SESSION *pSession = NULL; + unsigned int curr_pos, loop, count; + unsigned char *ptr; + time_t now; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "entering shmcb_lookup_session_id"); + + /* If there are entries to expire, ditch them first thing. */ + shmcb_expire_division(s, queue, cache); + now = time(NULL); + curr_pos = shmcb_get_safe_uint(queue->first_pos); + count = shmcb_get_safe_uint(queue->pos_count); + header = queue->header; + for (loop = 0; loop < count; loop++) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "loop=%u, count=%u, curr_pos=%u", + loop, count, curr_pos); + idx = shmcb_get_index(queue, curr_pos); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "idx->s_id2=%u, id[1]=%u, offset=%u", + idx->s_id2, id[1], shmcb_get_safe_uint(&(idx->offset))); + /* Only look into the session further if; + * (a) the second byte of the session_id matches, + * (b) the "removed" flag isn't set, + * (c) the session hasn't expired yet. + * We do (c) like this so that it saves us having to + * do natural expiries ... naturally expired sessions + * scroll off the front anyway when the cache is full and + * "rotating", the only real issue that remains is the + * removal or disabling of forcibly killed sessions. */ + if ((idx->s_id2 == id[1]) && !idx->removed && + (shmcb_get_safe_time(&(idx->expires)) > now)) { + unsigned int session_id_length; + unsigned char *session_id; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "at index %u, found possible session match", + curr_pos); + shmcb_cyclic_cton_memcpy(header->cache_data_size, + tempasn, cache->data, + shmcb_get_safe_uint(&(idx->offset)), + SSL_SESSION_MAX_DER); + ptr = tempasn; + pSession = d2i_SSL_SESSION(NULL, &ptr, SSL_SESSION_MAX_DER); + session_id_length = SSL_SESSION_get_session_id_length(pSession); + session_id = SSL_SESSION_get_session_id(pSession); + + if (pSession == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "scach2_lookup_session_id internal error"); + return NULL; + } + if ((session_id_length == idlen) && + (memcmp(session_id, id, idlen) == 0)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "a match!"); + return pSession; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "not a match"); + SSL_SESSION_free(pSession); + pSession = NULL; + } + curr_pos = shmcb_cyclic_increment(header->index_num, curr_pos, 1); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "no matching sessions were found"); + return NULL; +} + +static BOOL shmcb_remove_session_id( + server_rec *s, SHMCBQueue *queue, + SHMCBCache *cache, UCHAR *id, unsigned int idlen) +{ + unsigned char tempasn[SSL_SESSION_MAX_DER]; + SSL_SESSION *pSession = NULL; + SHMCBIndex *idx; + SHMCBHeader *header; + unsigned int curr_pos, loop, count; + unsigned char *ptr; + BOOL to_return = FALSE; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "entering shmcb_remove_session_id"); + + /* If there's entries to expire, ditch them first thing. */ + /* shmcb_expire_division(s, queue, cache); */ + + /* Regarding the above ... hmmm ... I know my expiry code is slightly + * "faster" than all this remove stuff ... but if the higher level + * code calls a "remove" operation (and this *only* seems to happen + * when it has spotted an expired session before we had a chance to) + * then it should get credit for a remove (stats-wise). Also, in the + * off-chance that the server *requests* a renegotiate and wants to + * wipe the session clean we should give that priority over our own + * routine expiry handling. So I've moved the expiry check to *after* + * this general remove stuff. */ + curr_pos = shmcb_get_safe_uint(queue->first_pos); + count = shmcb_get_safe_uint(queue->pos_count); + header = cache->header; + for (loop = 0; loop < count; loop++) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "loop=%u, count=%u, curr_pos=%u", + loop, count, curr_pos); + idx = shmcb_get_index(queue, curr_pos); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "idx->s_id2=%u, id[1]=%u", idx->s_id2, + id[1]); + /* Only look into the session further if the second byte of the + * session_id matches. */ + if (idx->s_id2 == id[1]) { + unsigned int session_id_length; + unsigned char *session_id; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "at index %u, found possible " + "session match", curr_pos); + shmcb_cyclic_cton_memcpy(header->cache_data_size, + tempasn, cache->data, + shmcb_get_safe_uint(&(idx->offset)), + SSL_SESSION_MAX_DER); + ptr = tempasn; + pSession = d2i_SSL_SESSION(NULL, &ptr, SSL_SESSION_MAX_DER); + if (pSession == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "shmcb_remove_session_id, internal error"); + goto end; + } + session_id_length = SSL_SESSION_get_session_id_length(pSession); + session_id = SSL_SESSION_get_session_id(pSession); + + if ((session_id_length == idlen) + && (memcmp(id, session_id, idlen) == 0)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "a match!"); + /* Scrub out this session "quietly" */ + idx->removed = (unsigned char) 1; + SSL_SESSION_free(pSession); + to_return = TRUE; + goto end; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "not a match"); + SSL_SESSION_free(pSession); + pSession = NULL; + } + curr_pos = shmcb_cyclic_increment(header->index_num, curr_pos, 1); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "no matching sessions were found"); + + /* If there's entries to expire, ditch them now. */ + shmcb_expire_division(s, queue, cache); +end: + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "leaving shmcb_remove_session_id"); + return to_return; +} diff --git a/trunk/modules/ssl/ssl_toolkit_compat.h b/trunk/modules/ssl/ssl_toolkit_compat.h new file mode 100644 index 0000000000..80b38cc4d9 --- /dev/null +++ b/trunk/modules/ssl/ssl_toolkit_compat.h @@ -0,0 +1,231 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SSL_TOOLKIT_COMPAT_H +#define SSL_TOOLKIT_COMPAT_H + +/* + * this header file provides a compatiblity layer + * between OpenSSL and RSA sslc + */ + +#ifdef HAVE_OPENSSL + +/* OpenSSL headers */ +#include +#include +#include +#include +#include +#include +#include +#include +/* Avoid tripping over an engine build installed globally and detected + * when the user points at an explicit non-engine flavor of OpenSSL + */ +#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) +#include +#endif + +/* + * rsa sslc uses incomplete types for most structures + * so we macroize for OpenSSL those which cannot be dereferenced + * using the same sames as the sslc functions + */ + +#define EVP_PKEY_key_type(k) (EVP_PKEY_type(k->type)) + +#define X509_NAME_get_entries(xs) (xs->entries) +#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber) + +#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm) +#define X509_get_key_algorithm(xs) (xs->cert_info->key->algor->algorithm) + +#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data) +#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length) + +#define SSL_CTX_get_extra_certs(ctx) (ctx->extra_certs) +#define SSL_CTX_set_extra_certs(ctx,value) {ctx->extra_certs = value;} + +#define SSL_CIPHER_get_name(s) (s->name) +#define SSL_CIPHER_get_valid(s) (s->valid) + +#define SSL_SESSION_get_session_id(s) (s->session_id) +#define SSL_SESSION_get_session_id_length(s) (s->session_id_length) + +/* + * Support for retrieving/overriding states + */ +#ifndef SSL_get_state +#define SSL_get_state(ssl) SSL_state(ssl) +#endif + +#define SSL_set_state(ssl,val) (ssl)->state = val + +#define MODSSL_BIO_CB_ARG_TYPE const char +#define MODSSL_CRYPTO_CB_ARG_TYPE const char +#if (OPENSSL_VERSION_NUMBER < 0x00907000) +#define MODSSL_INFO_CB_ARG_TYPE SSL* +#else +#define MODSSL_INFO_CB_ARG_TYPE const SSL* +#endif +#define MODSSL_CLIENT_CERT_CB_ARG_TYPE X509 +#define MODSSL_PCHAR_CAST + +#define modssl_X509_verify_cert X509_verify_cert + +typedef int (modssl_read_bio_cb_fn)(char*,int,int,void*); + +#if (OPENSSL_VERSION_NUMBER < 0x00904000) +#define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb) +#else +#define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb, arg) +#endif + +#define modssl_PEM_X509_INFO_read_bio PEM_X509_INFO_read_bio + +#define modssl_PEM_read_bio_PrivateKey PEM_read_bio_PrivateKey + +#define modssl_set_cipher_list SSL_set_cipher_list + +#define modssl_free OPENSSL_free + +#define EVP_PKEY_reference_inc(pkey) \ + CRYPTO_add(&((pkey)->references), +1, CRYPTO_LOCK_X509_PKEY) + +#define X509_reference_inc(cert) \ + CRYPTO_add(&((cert)->references), +1, CRYPTO_LOCK_X509) + +#define HAVE_SSL_RAND_EGD /* since 9.5.1 */ + +#define HAVE_SSL_X509V3_EXT_d2i + +#elif defined(HAVE_SSLC) + +#include +#include +#include +#include +#include +#include +#include +#include + +/* sslc does not support this function, OpenSSL has since 9.5.1 */ +#define RAND_status() 1 + +/* sslc names this function a bit differently */ +#define CRYPTO_num_locks() CRYPTO_get_num_locks() + +#ifndef STACK_OF +#define STACK_OF(type) STACK +#endif + +#define MODSSL_BIO_CB_ARG_TYPE char +#define MODSSL_CRYPTO_CB_ARG_TYPE char +#define MODSSL_INFO_CB_ARG_TYPE SSL* +#define MODSSL_CLIENT_CERT_CB_ARG_TYPE void +#define MODSSL_PCHAR_CAST (char *) + +typedef int (modssl_read_bio_cb_fn)(char*,int,int); + +#define modssl_X509_verify_cert(c) X509_verify_cert(c, NULL) + +#define modssl_PEM_read_bio_X509(b, x, cb, arg) \ + PEM_read_bio_X509(b, x, cb) + +#define modssl_PEM_X509_INFO_read_bio(b, x, cb, arg)\ + PEM_X509_INFO_read_bio(b, x, cb) + +#define modssl_PEM_read_bio_PrivateKey(b, k, cb, arg) \ + PEM_read_bio_PrivateKey(b, k, cb) + +#ifndef HAVE_SSL_SET_STATE +#define SSL_set_state(ssl, state) /* XXX: should throw an error */ +#endif + +#define modssl_set_cipher_list(ssl, l) \ + SSL_set_cipher_list(ssl, (char *)l) + +#define modssl_free free + +#ifndef PEM_F_DEF_CALLBACK +#define PEM_F_DEF_CALLBACK PEM_F_DEF_CB +#endif + +#if SSLC_VERSION_NUMBER < 0x2000 + +#define X509_STORE_CTX_set_depth(st, d) +#define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +#define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) +#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber) + +#define modssl_set_verify(ssl, verify, cb) \ + SSL_set_verify(ssl, verify) + +#else /* SSLC_VERSION_NUMBER >= 0x2000 */ + +#define CRYPTO_malloc_init R_malloc_init + +#define EVP_cleanup() + +#endif /* SSLC_VERSION_NUMBER >= 0x2000 */ + +typedef void (*modssl_popfree_fn)(char *data); + +#define sk_SSL_CIPHER_dup sk_dup +#define sk_SSL_CIPHER_find(st, data) sk_find(st, (void *)data) +#define sk_SSL_CIPHER_free sk_free +#define sk_SSL_CIPHER_num sk_num +#define sk_SSL_CIPHER_value (SSL_CIPHER *)sk_value +#define sk_X509_num sk_num +#define sk_X509_push sk_push +#define sk_X509_pop_free(st, free) sk_pop_free((STACK*)(st), (modssl_popfree_fn)(free)) +#define sk_X509_value (X509 *)sk_value +#define sk_X509_INFO_free sk_free +#define sk_X509_INFO_pop_free(st, free) sk_pop_free((STACK*)(st), (modssl_popfree_fn)(free)) +#define sk_X509_INFO_num sk_num +#define sk_X509_INFO_new_null sk_new_null +#define sk_X509_INFO_value (X509_INFO *)sk_value +#define sk_X509_NAME_find(st, data) sk_find(st, (void *)data) +#define sk_X509_NAME_free sk_free +#define sk_X509_NAME_new sk_new +#define sk_X509_NAME_num sk_num +#define sk_X509_NAME_push(st, data) sk_push(st, (void *)data) +#define sk_X509_NAME_value (X509_NAME *)sk_value +#define sk_X509_NAME_ENTRY_num sk_num +#define sk_X509_NAME_ENTRY_value (X509_NAME_ENTRY *)sk_value +#define sk_X509_NAME_set_cmp_func sk_set_cmp_func +#define sk_X509_REVOKED_num sk_num +#define sk_X509_REVOKED_value (X509_REVOKED *)sk_value + +#else /* ! HAVE_OPENSSL && ! HAVE_SSLC */ + +#error "Unrecognized SSL Toolkit!" + +#endif /* ! HAVE_OPENSSL && ! HAVE_SSLC */ + +#ifndef modssl_set_verify +#define modssl_set_verify(ssl, verify, cb) \ + SSL_set_verify(ssl, verify, cb) +#endif + +#ifndef SSL_SESS_CACHE_NO_INTERNAL +#define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP +#endif + +#endif /* SSL_TOOLKIT_COMPAT_H */ diff --git a/trunk/modules/ssl/ssl_util.c b/trunk/modules/ssl/ssl_util.c new file mode 100644 index 0000000000..bd6c2c8e81 --- /dev/null +++ b/trunk/modules/ssl/ssl_util.c @@ -0,0 +1,348 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_util.c + * Utility Functions + */ + /* ``Every day of my life + I am forced to add another + name to the list of people + who piss me off!'' + -- Calvin */ + +#include "ssl_private.h" +#include "ap_mpm.h" +#include "apr_thread_mutex.h" + +/* _________________________________________________________________ +** +** Utility Functions +** _________________________________________________________________ +*/ + +char *ssl_util_vhostid(apr_pool_t *p, server_rec *s) +{ + char *id; + SSLSrvConfigRec *sc; + char *host; + apr_port_t port; + + host = s->server_hostname; + if (s->port != 0) + port = s->port; + else { + sc = mySrvConfig(s); + if (sc->enabled == TRUE) + port = DEFAULT_HTTPS_PORT; + else + port = DEFAULT_HTTP_PORT; + } + id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port); + return id; +} + +apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd, + const char * const *argv) +{ + apr_procattr_t *procattr; + apr_proc_t *proc; + + if (apr_procattr_create(&procattr, p) != APR_SUCCESS) + return NULL; + if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, + APR_FULL_BLOCK) != APR_SUCCESS) + return NULL; + if (apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) + return NULL; + if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) + return NULL; + if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL) + return NULL; + if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) + return NULL; + return proc->out; +} + +void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp) +{ + apr_file_close(fp); + return; +} + +/* + * Run a filter program and read the first line of its stdout output + */ +char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd, + const char * const *argv) +{ + static char buf[MAX_STRING_LEN]; + apr_file_t *fp; + apr_size_t nbytes = 1; + char c; + int k; + + if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL) + return NULL; + /* XXX: we are reading 1 byte at a time here */ + for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS + && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) { + if (c == '\n' || c == '\r') + break; + buf[k++] = c; + } + buf[k] = NUL; + ssl_util_ppclose(s, p, fp); + + return buf; +} + +BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p) +{ + apr_finfo_t finfo; + + if (path == NULL) + return FALSE; + if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path, + APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0) + return FALSE; + if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG) + return FALSE; + if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR) + return FALSE; + if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0) + return FALSE; + return TRUE; +} + +ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey) +{ + ssl_algo_t t; + + t = SSL_ALGO_UNKNOWN; + if (pCert != NULL) + pKey = X509_get_pubkey(pCert); + if (pKey != NULL) { + switch (EVP_PKEY_key_type(pKey)) { + case EVP_PKEY_RSA: + t = SSL_ALGO_RSA; + break; + case EVP_PKEY_DSA: + t = SSL_ALGO_DSA; + break; + default: + break; + } + } + return t; +} + +char *ssl_util_algotypestr(ssl_algo_t t) +{ + char *cp; + + cp = "UNKNOWN"; + switch (t) { + case SSL_ALGO_RSA: + cp = "RSA"; + break; + case SSL_ALGO_DSA: + cp = "DSA"; + break; + default: + break; + } + return cp; +} + +/* + * certain key and cert data needs to survive restarts, + * which are stored in the user data table of s->process->pool. + * to prevent "leaking" of this data, we use malloc/free + * rather than apr_palloc and these wrappers to help make sure + * we do not leak the malloc-ed data. + */ +unsigned char *ssl_asn1_table_set(apr_hash_t *table, + const char *key, + long int length) +{ + apr_ssize_t klen = strlen(key); + ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); + + /* + * if a value for this key already exists, + * reuse as much of the already malloc-ed data + * as possible. + */ + if (asn1) { + if (asn1->nData != length) { + free(asn1->cpData); /* XXX: realloc? */ + asn1->cpData = NULL; + } + } + else { + asn1 = malloc(sizeof(*asn1)); + asn1->source_mtime = 0; /* used as a note for encrypted private keys */ + asn1->cpData = NULL; + } + + asn1->nData = length; + if (!asn1->cpData) { + asn1->cpData = malloc(length); + } + + apr_hash_set(table, key, klen, asn1); + + return asn1->cpData; /* caller will assign a value to this */ +} + +ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, + const char *key) +{ + return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING); +} + +void ssl_asn1_table_unset(apr_hash_t *table, + const char *key) +{ + apr_ssize_t klen = strlen(key); + ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); + + if (!asn1) { + return; + } + + if (asn1->cpData) { + free(asn1->cpData); + } + free(asn1); + + apr_hash_set(table, key, klen, NULL); +} + +static const char *ssl_asn1_key_types[] = {"RSA", "DSA"}; + +const char *ssl_asn1_keystr(int keytype) +{ + if (keytype >= SSL_AIDX_MAX) { + return NULL; + } + + return ssl_asn1_key_types[keytype]; +} + +const char *ssl_asn1_table_keyfmt(apr_pool_t *p, + const char *id, + int keytype) +{ + const char *keystr = ssl_asn1_keystr(keytype); + + return apr_pstrcat(p, id, ":", keystr, NULL); +} + + +#if APR_HAS_THREADS +/* + * To ensure thread-safetyness in OpenSSL - work in progress + */ + +static apr_thread_mutex_t **lock_cs; +static int lock_num_locks; + +#ifdef HAVE_SSLC +#if SSLC_VERSION_NUMBER >= 0x2000 +static int ssl_util_thr_lock(int mode, int type, + char *file, int line) +#else +static void ssl_util_thr_lock(int mode, int type, + char *file, int line) +#endif +#else +static void ssl_util_thr_lock(int mode, int type, + const char *file, int line) +#endif +{ + if (type < lock_num_locks) { + if (mode & CRYPTO_LOCK) { + apr_thread_mutex_lock(lock_cs[type]); + } + else { + apr_thread_mutex_unlock(lock_cs[type]); + } +#ifdef HAVE_SSLC +#if SSLC_VERSION_NUMBER >= 0x2000 + return 1; + } + else { + return -1; +#endif +#endif + } +} + +static unsigned long ssl_util_thr_id(void) +{ + /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread + * id is a structure twice that big. Use the TCB pointer instead as a + * unique unsigned long. + */ +#ifdef __MVS__ + struct PSA { + char unmapped[540]; + unsigned long PSATOLD; + } *psaptr = 0; + + return psaptr->PSATOLD; +#else + return (unsigned long) apr_os_thread_current(); +#endif +} + +static apr_status_t ssl_util_thread_cleanup(void *data) +{ + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + + /* Let the registered mutex cleanups do their own thing + */ + return APR_SUCCESS; +} + +void ssl_util_thread_setup(apr_pool_t *p) +{ + int i; + + lock_num_locks = CRYPTO_num_locks(); + lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs)); + + for (i = 0; i < lock_num_locks; i++) { + apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p); + } + + CRYPTO_set_id_callback(ssl_util_thr_id); + + CRYPTO_set_locking_callback(ssl_util_thr_lock); + + apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup, + apr_pool_cleanup_null); +} +#endif diff --git a/trunk/modules/ssl/ssl_util_ssl.c b/trunk/modules/ssl/ssl_util_ssl.c new file mode 100644 index 0000000000..ef8eb6668b --- /dev/null +++ b/trunk/modules/ssl/ssl_util_ssl.c @@ -0,0 +1,572 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_util_ssl.c + * Additional Utility Functions for OpenSSL + */ + +#include "ssl_private.h" + +/* _________________________________________________________________ +** +** Additional High-Level Functions for OpenSSL +** _________________________________________________________________ +*/ + +/* we initialize this index at startup time + * and never write to it at request time, + * so this static is thread safe. + * also note that OpenSSL increments at static variable when + * SSL_get_ex_new_index() is called, so we _must_ do this at startup. + */ +static int SSL_app_data2_idx = -1; + +void SSL_init_app_data2_idx(void) +{ + int i; + + if (SSL_app_data2_idx > -1) { + return; + } + + /* we _do_ need to call this twice */ + for (i=0; i<=1; i++) { + SSL_app_data2_idx = + SSL_get_ex_new_index(0, + "Second Application Data for SSL", + NULL, NULL, NULL); + } +} + +void *SSL_get_app_data2(SSL *ssl) +{ + return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx); +} + +void SSL_set_app_data2(SSL *ssl, void *arg) +{ + SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg); + return; +} + +/* _________________________________________________________________ +** +** High-Level Certificate / Private Key Loading +** _________________________________________________________________ +*/ + +X509 *SSL_read_X509(char* filename, X509 **x509, modssl_read_bio_cb_fn *cb) +{ + X509 *rc; + BIO *bioS; + BIO *bioF; + + /* 1. try PEM (= DER+Base64+headers) */ + if ((bioS=BIO_new_file(filename, "r")) == NULL) + return NULL; + rc = modssl_PEM_read_bio_X509 (bioS, x509, cb, NULL); + BIO_free(bioS); + + if (rc == NULL) { + /* 2. try DER+Base64 */ + if ((bioS=BIO_new_file(filename, "r")) == NULL) + return NULL; + + if ((bioF = BIO_new(BIO_f_base64())) == NULL) { + BIO_free(bioS); + return NULL; + } + bioS = BIO_push(bioF, bioS); + rc = d2i_X509_bio(bioS, NULL); + BIO_free_all(bioS); + + if (rc == NULL) { + /* 3. try plain DER */ + if ((bioS=BIO_new_file(filename, "r")) == NULL) + return NULL; + rc = d2i_X509_bio(bioS, NULL); + BIO_free(bioS); + } + } + if (rc != NULL && x509 != NULL) { + if (*x509 != NULL) + X509_free(*x509); + *x509 = rc; + } + return rc; +} + +#if SSL_LIBRARY_VERSION <= 0x00904100 +static EVP_PKEY *d2i_PrivateKey_bio(BIO *bio, EVP_PKEY **key) +{ + return ((EVP_PKEY *)ASN1_d2i_bio( + (char *(*)())EVP_PKEY_new, + (char *(*)())d2i_PrivateKey, + (bio), (unsigned char **)(key))); +} +#endif + +EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, modssl_read_bio_cb_fn *cb, void *s) +{ + EVP_PKEY *rc; + BIO *bioS; + BIO *bioF; + + /* 1. try PEM (= DER+Base64+headers) */ + if ((bioS=BIO_new_file(filename, "r")) == NULL) + return NULL; + rc = modssl_PEM_read_bio_PrivateKey(bioS, key, cb, s); + BIO_free(bioS); + + if (rc == NULL) { + /* 2. try DER+Base64 */ + if ((bioS = BIO_new_file(filename, "r")) == NULL) + return NULL; + + if ((bioF = BIO_new(BIO_f_base64())) == NULL) { + BIO_free(bioS); + return NULL; + } + bioS = BIO_push(bioF, bioS); + rc = d2i_PrivateKey_bio(bioS, NULL); + BIO_free_all(bioS); + + if (rc == NULL) { + /* 3. try plain DER */ + if ((bioS = BIO_new_file(filename, "r")) == NULL) + return NULL; + rc = d2i_PrivateKey_bio(bioS, NULL); + BIO_free(bioS); + } + } + if (rc != NULL && key != NULL) { + if (*key != NULL) + EVP_PKEY_free(*key); + *key = rc; + } + return rc; +} + +/* _________________________________________________________________ +** +** Smart shutdown +** _________________________________________________________________ +*/ + +int SSL_smart_shutdown(SSL *ssl) +{ + int i; + int rc; + + /* + * Repeat the calls, because SSL_shutdown internally dispatches through a + * little state machine. Usually only one or two interation should be + * needed, so we restrict the total number of restrictions in order to + * avoid process hangs in case the client played bad with the socket + * connection and OpenSSL cannot recognize it. + */ + rc = 0; + for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) { + if ((rc = SSL_shutdown(ssl))) + break; + } + return rc; +} + +/* _________________________________________________________________ +** +** Certificate Revocation List (CRL) Storage +** _________________________________________________________________ +*/ + +X509_STORE *SSL_X509_STORE_create(char *cpFile, char *cpPath) +{ + X509_STORE *pStore; + X509_LOOKUP *pLookup; + + if (cpFile == NULL && cpPath == NULL) + return NULL; + if ((pStore = X509_STORE_new()) == NULL) + return NULL; + if (cpFile != NULL) { + pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()); + if (pLookup == NULL) { + X509_STORE_free(pStore); + return NULL; + } + X509_LOOKUP_load_file(pLookup, cpFile, X509_FILETYPE_PEM); + } + if (cpPath != NULL) { + pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir()); + if (pLookup == NULL) { + X509_STORE_free(pStore); + return NULL; + } + X509_LOOKUP_add_dir(pLookup, cpPath, X509_FILETYPE_PEM); + } + return pStore; +} + +int SSL_X509_STORE_lookup(X509_STORE *pStore, int nType, + X509_NAME *pName, X509_OBJECT *pObj) +{ + X509_STORE_CTX pStoreCtx; + int rc; + + X509_STORE_CTX_init(&pStoreCtx, pStore, NULL, NULL); + rc = X509_STORE_get_by_subject(&pStoreCtx, nType, pName, pObj); + X509_STORE_CTX_cleanup(&pStoreCtx); + return rc; +} + +/* _________________________________________________________________ +** +** Cipher Suite Spec String Creation +** _________________________________________________________________ +*/ + +char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl) +{ + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *c; + int i; + int l; + char *cpCipherSuite; + char *cp; + + if (ssl == NULL) + return ""; + if ((sk = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl)) == NULL) + return ""; + l = 0; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + l += strlen(SSL_CIPHER_get_name(c))+2+1; + } + if (l == 0) + return ""; + cpCipherSuite = (char *)apr_palloc(p, l+1); + cp = cpCipherSuite; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + l = strlen(SSL_CIPHER_get_name(c)); + memcpy(cp, SSL_CIPHER_get_name(c), l); + cp += l; + *cp++ = '/'; + *cp++ = (SSL_CIPHER_get_valid(c) == 1 ? '1' : '0'); + *cp++ = ':'; + } + *(cp-1) = NUL; + return cpCipherSuite; +} + +/* _________________________________________________________________ +** +** Certificate Checks +** _________________________________________________________________ +*/ + +/* check whether cert contains extended key usage with a SGC tag */ +BOOL SSL_X509_isSGC(X509 *cert) +{ +#ifdef HAVE_SSL_X509V3_EXT_d2i + X509_EXTENSION *ext; + int ext_nid; + STACK *sk; + BOOL is_sgc; + int idx; + int i; + + is_sgc = FALSE; + idx = X509_get_ext_by_NID(cert, NID_ext_key_usage, -1); + if (idx >= 0) { + ext = X509_get_ext(cert, idx); + if ((sk = (STACK *)X509V3_EXT_d2i(ext)) != NULL) { + for (i = 0; i < sk_num(sk); i++) { + ext_nid = OBJ_obj2nid((ASN1_OBJECT *)sk_value(sk, i)); + if (ext_nid == NID_ms_sgc || ext_nid == NID_ns_sgc) { + is_sgc = TRUE; + break; + } + } + } + } + return is_sgc; +#else + return FALSE; +#endif +} + +/* retrieve basic constraints ingredients */ +BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen) +{ +#ifdef HAVE_SSL_X509V3_EXT_d2i + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *bc; + int idx; + BIGNUM *bn = NULL; + char *cp; + + if ((idx = X509_get_ext_by_NID(cert, NID_basic_constraints, -1)) < 0) + return FALSE; + ext = X509_get_ext(cert, idx); + if (ext == NULL) + return FALSE; + if ((bc = (BASIC_CONSTRAINTS *)X509V3_EXT_d2i(ext)) == NULL) + return FALSE; + *ca = bc->ca; + *pathlen = -1 /* unlimited */; + if (bc->pathlen != NULL) { + if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL) + return FALSE; + if ((cp = BN_bn2dec(bn)) == NULL) + return FALSE; + *pathlen = atoi(cp); + free(cp); + BN_free(bn); + } + BASIC_CONSTRAINTS_free(bc); + return TRUE; +#else + return FALSE; +#endif +} + +/* retrieve subject CommonName of certificate */ +BOOL SSL_X509_getCN(apr_pool_t *p, X509 *xs, char **cppCN) +{ + X509_NAME *xsn; + X509_NAME_ENTRY *xsne; + int i, nid; + unsigned char *data_ptr; + int data_len; + + xsn = X509_get_subject_name(xs); + for (i = 0; i < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *) + X509_NAME_get_entries(xsn)); i++) { + xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *) + X509_NAME_get_entries(xsn), i); + nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); + if (nid == NID_commonName) { + data_ptr = X509_NAME_ENTRY_get_data_ptr(xsne); + data_len = X509_NAME_ENTRY_get_data_len(xsne); + *cppCN = apr_palloc(p, data_len+1); + apr_cpystrn(*cppCN, (char *)data_ptr, data_len+1); + (*cppCN)[data_len] = NUL; + ap_xlate_proto_from_ascii(*cppCN, data_len); + return TRUE; + } + } + return FALSE; +} + +/* _________________________________________________________________ +** +** Low-Level CA Certificate Loading +** _________________________________________________________________ +*/ + +BOOL SSL_X509_INFO_load_file(apr_pool_t *ptemp, + STACK_OF(X509_INFO) *sk, + const char *filename) +{ + BIO *in; + + if (!(in = BIO_new(BIO_s_file()))) { + return FALSE; + } + + if (BIO_read_filename(in, MODSSL_PCHAR_CAST filename) <= 0) { + BIO_free(in); + return FALSE; + } + + ERR_clear_error(); + + modssl_PEM_X509_INFO_read_bio(in, sk, NULL, NULL); + + BIO_free(in); + + return TRUE; +} + +BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp, + STACK_OF(X509_INFO) *sk, + const char *pathname) +{ + /* XXX: this dir read code is exactly the same as that in + * ssl_engine_init.c, only the call to handle the fullname is different, + * should fold the duplication. + */ + apr_dir_t *dir; + apr_finfo_t dirent; + apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME; + const char *fullname; + BOOL ok = FALSE; + + if (apr_dir_open(&dir, pathname, ptemp) != APR_SUCCESS) { + return FALSE; + } + + while ((apr_dir_read(&dirent, finfo_flags, dir)) == APR_SUCCESS) { + if (dirent.filetype == APR_DIR) { + continue; /* don't try to load directories */ + } + + fullname = apr_pstrcat(ptemp, + pathname, "/", dirent.name, + NULL); + + if (SSL_X509_INFO_load_file(ptemp, sk, fullname)) { + ok = TRUE; + } + } + + apr_dir_close(dir); + + return ok; +} + +/* _________________________________________________________________ +** +** Extra Server Certificate Chain Support +** _________________________________________________________________ +*/ + +/* + * Read a file that optionally contains the server certificate in PEM + * format, possibly followed by a sequence of CA certificates that + * should be sent to the peer in the SSL Certificate message. + */ +int SSL_CTX_use_certificate_chain( + SSL_CTX *ctx, char *file, int skipfirst, modssl_read_bio_cb_fn *cb) +{ + BIO *bio; + X509 *x509; + unsigned long err; + int n; + STACK *extra_certs; + + if ((bio = BIO_new(BIO_s_file_internal())) == NULL) + return -1; + if (BIO_read_filename(bio, file) <= 0) { + BIO_free(bio); + return -1; + } + /* optionally skip a leading server certificate */ + if (skipfirst) { + if ((x509 = modssl_PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) { + BIO_free(bio); + return -1; + } + X509_free(x509); + } + /* free a perhaps already configured extra chain */ + extra_certs=SSL_CTX_get_extra_certs(ctx); + if (extra_certs != NULL) { + sk_X509_pop_free((STACK_OF(X509) *)extra_certs, X509_free); + SSL_CTX_set_extra_certs(ctx,NULL); + } + /* create new extra chain by loading the certs */ + n = 0; + while ((x509 = modssl_PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) { + if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) { + X509_free(x509); + BIO_free(bio); + return -1; + } + n++; + } + /* Make sure that only the error is just an EOF */ + if ((err = ERR_peek_error()) > 0) { + if (!( ERR_GET_LIB(err) == ERR_LIB_PEM + && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { + BIO_free(bio); + return -1; + } + while (ERR_get_error() > 0) ; + } + BIO_free(bio); + return n; +} + +/* _________________________________________________________________ +** +** Session Stuff +** _________________________________________________________________ +*/ + +char *SSL_SESSION_id2sz(unsigned char *id, int idlen, + char *str, int strsize) +{ + char *cp; + int n; + + cp = str; + for (n = 0; n < idlen && n < SSL_MAX_SSL_SESSION_ID_LENGTH; n++) { + apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]); + cp += 2; + } + *cp = NUL; + return str; +} + +/* sslc+OpenSSL compat */ + +int modssl_session_get_time(SSL_SESSION *session) +{ +#ifdef OPENSSL_VERSION_NUMBER + return SSL_SESSION_get_time(session); +#else /* assume sslc */ + CRYPTO_TIME_T ct; + SSL_SESSION_get_time(session, &ct); + return CRYPTO_time_to_int(&ct); +#endif +} + +#ifndef SSLC_VERSION_NUMBER +#define SSLC_VERSION_NUMBER 0x0000 +#endif + +DH *modssl_dh_configure(unsigned char *p, int plen, + unsigned char *g, int glen) +{ + DH *dh; + + if (!(dh = DH_new())) { + return NULL; + } + +#if defined(OPENSSL_VERSION_NUMBER) || (SSLC_VERSION_NUMBER < 0x2000) + dh->p = BN_bin2bn(p, plen, NULL); + dh->g = BN_bin2bn(g, glen, NULL); + if (!(dh->p && dh->g)) { + DH_free(dh); + return NULL; + } +#else + R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_P, 0, p, plen, R_EITEMS_PF_COPY); + R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_G, 0, g, glen, R_EITEMS_PF_COPY); +#endif + + return dh; +} diff --git a/trunk/modules/ssl/ssl_util_ssl.h b/trunk/modules/ssl/ssl_util_ssl.h new file mode 100644 index 0000000000..a4bdd85856 --- /dev/null +++ b/trunk/modules/ssl/ssl_util_ssl.h @@ -0,0 +1,80 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* _ _ + * _ __ ___ ___ __| | ___ ___| | mod_ssl + * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + * | | | | | | (_) | (_| | \__ \__ \ | + * |_| |_| |_|\___/ \__,_|___|___/___/_| + * |_____| + * ssl_util_ssl.h + * Additional Utility Functions for OpenSSL + */ + +#ifndef __SSL_UTIL_SSL_H__ +#define __SSL_UTIL_SSL_H__ + +/* + * Determine SSL library version number + */ +#ifdef OPENSSL_VERSION_NUMBER +#define SSL_LIBRARY_VERSION OPENSSL_VERSION_NUMBER +#define SSL_LIBRARY_NAME "OpenSSL" +#define SSL_LIBRARY_TEXT OPENSSL_VERSION_TEXT +#elif !defined(SSL_LIBRARY_VERSION) +#define SSL_LIBRARY_VERSION 0x0000 +#define SSL_LIBRARY_NAME "OtherSSL" +#define SSL_LIBRARY_TEXT "OtherSSL 0.0.0 00 XXX 0000" +#endif + +/* + * Maximum length of a DER encoded session. + * FIXME: There is no define in OpenSSL, but OpenSSL uses 1024*10, + * so this value should be ok. Although we have no warm feeling. + */ +#define SSL_SESSION_MAX_DER 1024*10 + +/* max length for SSL_SESSION_id2sz */ +#define SSL_SESSION_ID_STRING_LEN \ + ((SSL_MAX_SSL_SESSION_ID_LENGTH + 1) * 2) + +/* + * Additional Functions + */ +void SSL_init_app_data2_idx(void); +void *SSL_get_app_data2(SSL *); +void SSL_set_app_data2(SSL *, void *); +X509 *SSL_read_X509(char *, X509 **, modssl_read_bio_cb_fn *); +EVP_PKEY *SSL_read_PrivateKey(char *, EVP_PKEY **, modssl_read_bio_cb_fn *, void *); +int SSL_smart_shutdown(SSL *ssl); +X509_STORE *SSL_X509_STORE_create(char *, char *); +int SSL_X509_STORE_lookup(X509_STORE *, int, X509_NAME *, X509_OBJECT *); +char *SSL_make_ciphersuite(apr_pool_t *, SSL *); +BOOL SSL_X509_isSGC(X509 *); +BOOL SSL_X509_getBC(X509 *, int *, int *); +BOOL SSL_X509_getCN(apr_pool_t *, X509 *, char **); +BOOL SSL_X509_INFO_load_file(apr_pool_t *, STACK_OF(X509_INFO) *, const char *); +BOOL SSL_X509_INFO_load_path(apr_pool_t *, STACK_OF(X509_INFO) *, const char *); +int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, modssl_read_bio_cb_fn *); +char *SSL_SESSION_id2sz(unsigned char *, int, char *, int); + +/* util functions for OpenSSL+sslc compat */ +int modssl_session_get_time(SSL_SESSION *session); + +DH *modssl_dh_configure(unsigned char *p, int plen, + unsigned char *g, int glen); + +#endif /* __SSL_UTIL_SSL_H__ */ diff --git a/trunk/modules/test/.indent.pro b/trunk/modules/test/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/modules/test/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/modules/test/Makefile.in b/trunk/modules/test/Makefile.in new file mode 100644 index 0000000000..7c5c149d85 --- /dev/null +++ b/trunk/modules/test/Makefile.in @@ -0,0 +1,3 @@ +# a modules Makefile has no explicit targets -- they will be defined by +# whatever modules are enabled. just grab special.mk to deal with this. +include $(top_srcdir)/build/special.mk diff --git a/trunk/modules/test/README b/trunk/modules/test/README new file mode 100644 index 0000000000..f122368a7f --- /dev/null +++ b/trunk/modules/test/README @@ -0,0 +1 @@ +test modules have moved to httpd-test/perl-framework/c-modules diff --git a/trunk/modules/test/config.m4 b/trunk/modules/test/config.m4 new file mode 100644 index 0000000000..01bc0fa971 --- /dev/null +++ b/trunk/modules/test/config.m4 @@ -0,0 +1,9 @@ + +APACHE_MODPATH_INIT(test) + +APACHE_MODULE(optional_hook_export, example optional hook exporter, , , no) +APACHE_MODULE(optional_hook_import, example optional hook importer, , , no) +APACHE_MODULE(optional_fn_import, example optional function importer, , , no) +APACHE_MODULE(optional_fn_export, example optional function exporter, , , no) + +APACHE_MODPATH_FINISH diff --git a/trunk/modules/test/mod_optional_fn_export.c b/trunk/modules/test/mod_optional_fn_export.c new file mode 100644 index 0000000000..c03224d820 --- /dev/null +++ b/trunk/modules/test/mod_optional_fn_export.c @@ -0,0 +1,48 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "mod_optional_fn_export.h" + +/* The alert will note a strange mirror-image style resemblance to + * mod_optional_hook_import.c. Yes, I _did_ mean import. Think about it. + */ + +static int TestOptionalFn(const char *szStr) +{ + ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL, + "Optional function test said: %s",szStr); + + return OK; +} + +static void ExportRegisterHooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(TestOptionalFn); +} + +module AP_MODULE_DECLARE_DATA optional_fn_export_module= +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + NULL, + NULL, + NULL, + ExportRegisterHooks +}; diff --git a/trunk/modules/test/mod_optional_fn_export.h b/trunk/modules/test/mod_optional_fn_export.h new file mode 100644 index 0000000000..fd3a59d7c1 --- /dev/null +++ b/trunk/modules/test/mod_optional_fn_export.h @@ -0,0 +1,19 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_optional.h" + +APR_DECLARE_OPTIONAL_FN(int,TestOptionalFn,(const char *)); diff --git a/trunk/modules/test/mod_optional_fn_import.c b/trunk/modules/test/mod_optional_fn_import.c new file mode 100644 index 0000000000..9346d1a270 --- /dev/null +++ b/trunk/modules/test/mod_optional_fn_import.c @@ -0,0 +1,55 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "mod_optional_fn_export.h" +#include "http_protocol.h" + +/* The alert will note a strange mirror-image style resemblance to + * mod_optional_hook_export.c. Yes, I _did_ mean export. Think about it. + */ + +static APR_OPTIONAL_FN_TYPE(TestOptionalFn) *pfn; + +static int ImportLogTransaction(request_rec *r) +{ + if(pfn) + return pfn(r->the_request); + return DECLINED; +} + +static void ImportFnRetrieve(void) +{ + pfn=APR_RETRIEVE_OPTIONAL_FN(TestOptionalFn); +} + +static void ImportRegisterHooks(apr_pool_t *p) +{ + ap_hook_log_transaction(ImportLogTransaction,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_optional_fn_retrieve(ImportFnRetrieve,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA optional_fn_import_module = +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + NULL, + NULL, + NULL, + ImportRegisterHooks +}; diff --git a/trunk/modules/test/mod_optional_hook_export.c b/trunk/modules/test/mod_optional_hook_export.c new file mode 100644 index 0000000000..896ad52cca --- /dev/null +++ b/trunk/modules/test/mod_optional_hook_export.c @@ -0,0 +1,44 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "mod_optional_hook_export.h" +#include "http_protocol.h" + +AP_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(int,optional_hook_test,(const char *szStr), + (szStr),OK,DECLINED) + +static int ExportLogTransaction(request_rec *r) +{ + return ap_run_optional_hook_test(r->the_request); +} + +static void ExportRegisterHooks(apr_pool_t *p) +{ + ap_hook_log_transaction(ExportLogTransaction,NULL,NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA optional_hook_export_module = +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + NULL, + NULL, + NULL, + ExportRegisterHooks +}; diff --git a/trunk/modules/test/mod_optional_hook_export.h b/trunk/modules/test/mod_optional_hook_export.h new file mode 100644 index 0000000000..4dd40db78f --- /dev/null +++ b/trunk/modules/test/mod_optional_hook_export.h @@ -0,0 +1,24 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOD_OPTIONAL_HOOK_EXPORT_H +#define MOD_OPTOPNAL_HOOK_EXPORT_H + +#include "ap_config.h" + +AP_DECLARE_HOOK(int,optional_hook_test,(const char *)) + +#endif /* def MOD_OPTIONAL_HOOK_EXPORT_H */ diff --git a/trunk/modules/test/mod_optional_hook_import.c b/trunk/modules/test/mod_optional_hook_import.c new file mode 100644 index 0000000000..7bca53a679 --- /dev/null +++ b/trunk/modules/test/mod_optional_hook_import.c @@ -0,0 +1,45 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "mod_optional_hook_export.h" + +static int ImportOptionalHookTestHook(const char *szStr) +{ + ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL,"Optional hook test said: %s", + szStr); + + return OK; +} + +static void ImportRegisterHooks(apr_pool_t *p) +{ + AP_OPTIONAL_HOOK(optional_hook_test,ImportOptionalHookTestHook,NULL, + NULL,APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA optional_hook_import_module= +{ + STANDARD20_MODULE_STUFF, + NULL, + NULL, + NULL, + NULL, + NULL, + ImportRegisterHooks +}; diff --git a/trunk/os/.indent.pro b/trunk/os/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/os/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/os/Makefile.in b/trunk/os/Makefile.in new file mode 100644 index 0000000000..9b35d49198 --- /dev/null +++ b/trunk/os/Makefile.in @@ -0,0 +1,4 @@ + +SUBDIRS = $(OS_DIR) + +include $(top_builddir)/build/rules.mk diff --git a/trunk/os/beos/Makefile.in b/trunk/os/beos/Makefile.in new file mode 100644 index 0000000000..66272ecc46 --- /dev/null +++ b/trunk/os/beos/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libos.la +LTLIBRARY_SOURCES = os.c beosd.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/os/beos/beosd.c b/trunk/os/beos/beosd.c new file mode 100644 index 0000000000..901c9a66de --- /dev/null +++ b/trunk/os/beos/beosd.c @@ -0,0 +1,166 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "httpd.h" +#include "http_config.h" +#include "http_main.h" +#include "http_log.h" +#include "beosd.h" +#include "mpm_common.h" + +beosd_config_rec beosd_config; + +/* Set group privileges. + * + * Note that until we get the multi-user situation sorted on beos, + * this is just a no-op to allow common configuration files! + */ + +#if B_BEOS_VERSION < 0x0460 +static int set_group_privs(void) +{ + /* no-op */ + return 0; +} +#endif + + +int beosd_setup_child(void) +{ + /* TODO: revisit the whole issue of users/groups for BeOS as + * R5 and below doesn't really have much concept of them. + */ + + return 0; +} + + +AP_DECLARE(const char *) beosd_set_user(cmd_parms *cmd, + void *dummy, const char *arg) +{ + /* no-op */ + return NULL; +} + +AP_DECLARE(const char *) beosd_set_group(cmd_parms *cmd, + void *dummy, const char *arg) +{ + /* no-op */ + return NULL; +} + +void beosd_pre_config(void) +{ + /* Until the multi-user situation on BeOS is fixed, + simply have a no-op here to allow for common conf files + */ +} + +AP_DECLARE(apr_status_t) beosd_accept(void **accepted, ap_listen_rec *lr, + apr_pool_t *ptrans) +{ + apr_socket_t *csd; + apr_status_t status; + int sockdes; + + status = apr_socket_accept(&csd, lr->sd, ptrans); + if (status == APR_SUCCESS) { + *accepted = csd; + apr_os_sock_get(&sockdes, csd); + if (sockdes >= FD_SETSIZE) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "new file descriptor %d is too large; you probably need " + "to rebuild Apache with a larger FD_SETSIZE " + "(currently %d)", + sockdes, FD_SETSIZE); + apr_socket_close(csd); + return APR_EINTR; + } + return status; + } + + if (APR_STATUS_IS_EINTR(status)) { + return status; + } + /* Our old behaviour here was to continue after accept() + * errors. But this leads us into lots of troubles + * because most of the errors are quite fatal. For + * example, EMFILE can be caused by slow descriptor + * leaks (say in a 3rd party module, or libc). It's + * foolish for us to continue after an EMFILE. We also + * seem to tickle kernel bugs on some platforms which + * lead to never-ending loops here. So it seems best + * to just exit in most cases. + */ + switch (status) { +#ifdef EPROTO + /* EPROTO on certain older kernels really means + * ECONNABORTED, so we need to ignore it for them. + * See discussion in new-httpd archives nh.9701 + * search for EPROTO. + * + * Also see nh.9603, search for EPROTO: + * There is potentially a bug in Solaris 2.x x<6, + * and other boxes that implement tcp sockets in + * userland (i.e. on top of STREAMS). On these + * systems, EPROTO can actually result in a fatal + * loop. See PR#981 for example. It's hard to + * handle both uses of EPROTO. + */ + case EPROTO: +#endif +#ifdef ECONNABORTED + case ECONNABORTED: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif +#ifdef ENETUNREACH + case ENETUNREACH: +#endif + break; +#ifdef ENETDOWN + case ENETDOWN: + /* + * When the network layer has been shut down, there + * is not much use in simply exiting: the parent + * would simply re-create us (and we'd fail again). + * Use the CHILDFATAL code to tear the server down. + * @@@ Martin's idea for possible improvement: + * A different approach would be to define + * a new APEXIT_NETDOWN exit code, the reception + * of which would make the parent shutdown all + * children, then idle-loop until it detected that + * the network is up again, and restart the children. + * Ben Hyde noted that temporary ENETDOWN situations + * occur in mobile IP. + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "apr_socket_accept: giving up."); + return APR_EGENERAL; +#endif /*ENETDOWN*/ + + default: + ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, + "apr_socket_accept: (client socket)"); + return APR_EGENERAL; + } + return status; +} diff --git a/trunk/os/beos/beosd.h b/trunk/os/beos/beosd.h new file mode 100644 index 0000000000..9d1f0dfe38 --- /dev/null +++ b/trunk/os/beos/beosd.h @@ -0,0 +1,60 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BEOSD_H +#define BEOSD_H + +#include "httpd.h" +#include "ap_listen.h" +/* common stuff that beos MPMs will want */ + +/* Default user name and group name. These may be specified as numbers by + * placing a # before a number */ + +#ifndef DEFAULT_USER +#define DEFAULT_USER "#-1" +#endif +#ifndef DEFAULT_GROUP +#define DEFAULT_GROUP "#" +#endif + +typedef struct { + char *user_name; + uid_t user_id; + gid_t group_id; +} beosd_config_rec; +extern beosd_config_rec beosd_config; + +void beosd_detach(void); +int beosd_setup_child(void); +void beosd_pre_config(void); +AP_DECLARE(const char *) beosd_set_user (cmd_parms *cmd, void *dummy, + const char *arg); +AP_DECLARE(const char *) beosd_set_group(cmd_parms *cmd, void *dummy, + const char *arg); +AP_DECLARE(apr_status_t) beosd_accept(void **accepted, ap_listen_rec *lr, + apr_pool_t *ptrans); + +#define beosd_killpg(x, y) (kill (-(x), (y))) +#define ap_os_killpg(x, y) (kill (-(x), (y))) + +#define BEOS_DAEMON_COMMANDS \ +AP_INIT_TAKE1("User", beosd_set_user, NULL, RSRC_CONF, \ + "Effective user id for this server (NO-OP)"), \ +AP_INIT_TAKE1("Group", beosd_set_group, NULL, RSRC_CONF, \ + "Effective group id for this server (NO-OP)") + +#endif /* BEOSD_H */ diff --git a/trunk/os/beos/config.m4 b/trunk/os/beos/config.m4 new file mode 100644 index 0000000000..4fe95b7509 --- /dev/null +++ b/trunk/os/beos/config.m4 @@ -0,0 +1,3 @@ +if test "$OS" = "beos" ; then + APR_ADDTO(CFLAGS,-DBEOS) +fi diff --git a/trunk/os/beos/os.c b/trunk/os/beos/os.c new file mode 100644 index 0000000000..57ef38657c --- /dev/null +++ b/trunk/os/beos/os.c @@ -0,0 +1,37 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file will include OS specific functions which are not inlineable. + * Any inlineable functions should be defined in os-inline.c instead. + */ + +#include "ap_config.h" +#include "os.h" +#include "httpd.h" +#include "apr_thread_proc.h" +#include "ap_mpm.h" /* needed for definition of + * ap_os_create_privileged_process */ + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + return apr_proc_create(newproc, progname, args, env, attr, p); +} diff --git a/trunk/os/beos/os.h b/trunk/os/beos/os.h new file mode 100644 index 0000000000..8d09f1ad02 --- /dev/null +++ b/trunk/os/beos/os.h @@ -0,0 +1,30 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_OS_H +#define APACHE_OS_H + +#include "ap_config.h" + +#ifndef PLATFORM +# ifdef BONE_VERSION +# define PLATFORM "BeOS BONE" +# else +# define PLATFORM "BeOS R5" +# endif +#endif + +#endif /* !APACHE_OS_H */ diff --git a/trunk/os/bs2000/ebcdic.c b/trunk/os/bs2000/ebcdic.c new file mode 100644 index 0000000000..8bdde8bf3e --- /dev/null +++ b/trunk/os/bs2000/ebcdic.c @@ -0,0 +1,210 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" +#if APR_CHARSET_EBCDIC +#include "ebcdic.h" +/* + Initial Port for Apache-1.3 by + +"BS2000 OSD" is a POSIX on a main frame. It is made by Siemens AG, Germany. +Within the POSIX subsystem, the same character set was chosen as in +"native BS2000", namely EBCDIC. + +EBCDIC Table. (Yes, in EBCDIC, the letters 'a'..'z' are not contiguous!) +This apr_table_t is bijective, i.e. there are no ambigous or duplicate characters +00 00 01 02 03 85 09 86 7f 87 8d 8e 0b 0c 0d 0e 0f *................* +10 10 11 12 13 8f 0a 08 97 18 19 9c 9d 1c 1d 1e 1f *................* +20 80 81 82 83 84 92 17 1b 88 89 8a 8b 8c 05 06 07 *................* +30 90 91 16 93 94 95 96 04 98 99 9a 9b 14 15 9e 1a *................* +40 20 a0 e2 e4 e0 e1 e3 e5 e7 f1 60 2e 3c 28 2b 7c * .........`.<(+|* +50 26 e9 ea eb e8 ed ee ef ec df 21 24 2a 29 3b 9f *&.........!$*);.* +60 2d 2f c2 c4 c0 c1 c3 c5 c7 d1 5e 2c 25 5f 3e 3f *-/........^,%_>?* +70 f8 c9 ca cb c8 cd ce cf cc a8 3a 23 40 27 3d 22 *..........:#@'="* +80 d8 61 62 63 64 65 66 67 68 69 ab bb f0 fd fe b1 *.abcdefghi......* +90 b0 6a 6b 6c 6d 6e 6f 70 71 72 aa ba e6 b8 c6 a4 *.jklmnopqr......* +a0 b5 af 73 74 75 76 77 78 79 7a a1 bf d0 dd de ae *..stuvwxyz......* +b0 a2 a3 a5 b7 a9 a7 b6 bc bd be ac 5b 5c 5d b4 d7 *...........[\]..* +c0 f9 41 42 43 44 45 46 47 48 49 ad f4 f6 f2 f3 f5 *.ABCDEFGHI......* +d0 a6 4a 4b 4c 4d 4e 4f 50 51 52 b9 fb fc db fa ff *.JKLMNOPQR......* +e0 d9 f7 53 54 55 56 57 58 59 5a b2 d4 d6 d2 d3 d5 *..STUVWXYZ......* +f0 30 31 32 33 34 35 36 37 38 39 b3 7b dc 7d da 7e *0123456789.{.}.~* +*/ + +/* The bijective ebcdic-to-ascii table: */ +const unsigned char os_toascii_strictly[256] = { +/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/ +/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/ +/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/ +/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/ +/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/ +/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/ +/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, + 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/ +/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/ +/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/ +/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/ +/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/ +/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, + 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/ +/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/ +/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/ +/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/ +/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~*/ +}; + +/* This apr_table_t is (almost) identical to the previous one. The only difference + * is the fact that it maps every EBCDIC *except 0x0A* to its ASCII + * equivalent. The reason for this apr_table_t is simple: Throughout the + * server, protocol strings are used in the form + * "Content-Type: text/plain\015\012". Now all the characters in the string + * are stored as EBCDIC, only the semantics of \012 is completely + * different from LF (look it up in the apr_table_t above). \015 happens to be + * mapped to \015 anyway, so there's no special case for it. + * + * In THIS table, EBCDIC-\012 is mapped to ASCII-\012. + * This apr_table_t is therefore used wherever an EBCDIC to ASCII conversion is + * needed in the server. + */ +/* ebcdic-to-ascii with \012 mapped to ASCII-\n */ +const unsigned char os_toascii[256] = { +/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, + 0x87, 0x8d, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/ +/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/ +/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/ +/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/ +/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/ +/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/ +/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, + 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/ +/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/ +/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/ +/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/ +/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/ +/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, + 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/ +/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/ +/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/ +/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/ +/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~*/ +}; + +/* The ascii-to-ebcdic table: +00 00 01 02 03 37 2d 2e 2f 16 05 15 0b 0c 0d 0e 0f *................* +10 10 11 12 13 3c 3d 32 26 18 19 3f 27 1c 1d 1e 1f *................* +20 40 5a 7f 7b 5b 6c 50 7d 4d 5d 5c 4e 6b 60 4b 61 * !"#$%&'()*+,-./ +30 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 7a 5e 4c 7e 6e 6f *0123456789:;<=>?* +40 7c c1 c2 c3 c4 c5 c6 c7 c8 c9 d1 d2 d3 d4 d5 d6 *@ABCDEFGHIJKLMNO* +50 d7 d8 d9 e2 e3 e4 e5 e6 e7 e8 e9 bb bc bd 6a 6d *PQRSTUVWXYZ[\]^_* +60 4a 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 *`abcdefghijklmno* +70 97 98 99 a2 a3 a4 a5 a6 a7 a8 a9 fb 4f fd ff 07 *pqrstuvwxyz{|}~.* +80 20 21 22 23 24 04 06 08 28 29 2a 2b 2c 09 0a 14 *................* +90 30 31 25 33 34 35 36 17 38 39 3a 3b 1a 1b 3e 5f *................* +a0 41 aa b0 b1 9f b2 d0 b5 79 b4 9a 8a ba ca af a1 *................* +b0 90 8f ea fa be a0 b6 b3 9d da 9b 8b b7 b8 b9 ab *................* +c0 64 65 62 66 63 67 9e 68 74 71 72 73 78 75 76 77 *................* +d0 ac 69 ed ee eb ef ec bf 80 e0 fe dd fc ad ae 59 *................* +e0 44 45 42 46 43 47 9c 48 54 51 52 53 58 55 56 57 *................* +f0 8c 49 cd ce cb cf cc e1 70 c0 de db dc 8d 8e df *................* +*/ +const unsigned char os_toebcdic[256] = { +/*00*/ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/ +/*10*/ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/ +/*20*/ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ +/*30*/ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /*0123456789:;<=>?*/ +/*40*/ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /*@ABCDEFGHIJKLMNO*/ +/*50*/ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /*PQRSTUVWXYZ[\]^_*/ +/*60*/ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /*`abcdefghijklmno*/ +/*70*/ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, + 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /*pqrstuvwxyz{|}~.*/ +/*80*/ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /*................*/ +/*90*/ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /*................*/ +/*a0*/ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5, + 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /*................*/ +/*b0*/ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /*................*/ +/*c0*/ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /*................*/ +/*d0*/ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, + 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /*................*/ +/*e0*/ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /*................*/ +/*f0*/ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, + 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /*................*/ +}; + +/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset) + * dest and srce may be identical, or separate memory blocks, but + * should not overlap. + */ +void +ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count) +{ + while (count-- != 0) { + *dest++ = os_toascii[*srce++]; + } +} +void +ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count) +{ + while (count-- != 0) { + *dest++ = os_toascii_strictly[*srce++]; + } +} +void +ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count) +{ + while (count-- != 0) { + *dest++ = os_toebcdic[*srce++]; + } +} +#endif /*APR_CHARSET_EBCDIC*/ diff --git a/trunk/os/bs2000/ebcdic.h b/trunk/os/bs2000/ebcdic.h new file mode 100644 index 0000000000..b094feef53 --- /dev/null +++ b/trunk/os/bs2000/ebcdic.h @@ -0,0 +1,24 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count); +void ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count); +void ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count); + diff --git a/trunk/os/bs2000/os.c b/trunk/os/bs2000/os.c new file mode 100644 index 0000000000..cd2407f8d9 --- /dev/null +++ b/trunk/os/bs2000/os.c @@ -0,0 +1,143 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file will include OS specific functions which are not inlineable. + * Any inlineable functions should be defined in os-inline.c instead. + */ + +#ifdef _OSD_POSIX + +#include "os.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "apr_lib.h" + +#define USER_LEN 8 + +typedef enum +{ + bs2_unknown, /* not initialized yet. */ + bs2_noFORK, /* no fork() because -X flag was specified */ + bs2_FORK, /* only fork() because uid != 0 */ + bs2_UFORK /* Normally, ufork() is used to switch identities. */ +} bs2_ForkType; + +static bs2_ForkType forktype = bs2_unknown; + + +static void ap_str_toupper(char *str) +{ + while (*str) { + *str = apr_toupper(*str); + ++str; + } +} + +/* Determine the method for forking off a child in such a way as to + * set both the POSIX and BS2000 user id's to the unprivileged user. + */ +static bs2_ForkType os_forktype(int one_process) +{ + /* have we checked the OS version before? If yes return the previous + * result - the OS release isn't going to change suddenly! + */ + if (forktype == bs2_unknown) { + /* not initialized yet */ + + /* No fork if the one_process option was set */ + if (one_process) { + forktype = bs2_noFORK; + } + /* If the user is unprivileged, use the normal fork() only. */ + else if (getuid() != 0) { + forktype = bs2_FORK; + } + else + forktype = bs2_UFORK; + } + return forktype; +} + + + +/* This routine complements the setuid() call: it causes the BS2000 job + * environment to be switched to the target user's user id. + * That is important if CGI scripts try to execute native BS2000 commands. + */ +int os_init_job_environment(server_rec *server, const char *user_name, int one_process) +{ + bs2_ForkType type = os_forktype(one_process); + + /* We can be sure that no change to uid==0 is possible because of + * the checks in http_core.c:set_user() + */ + + if (one_process) { + + type = forktype = bs2_noFORK; + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, + "The debug mode of Apache should only " + "be started by an unprivileged user!"); + return 0; + } + + return 0; +} + +/* BS2000 requires a "special" version of fork() before a setuid() call */ +pid_t os_fork(const char *user) +{ + pid_t pid; + char username[USER_LEN+1]; + + switch (os_forktype(0)) { + + case bs2_FORK: + pid = fork(); + break; + + case bs2_UFORK: + apr_cpystrn(username, user, sizeof username); + + /* Make user name all upper case - for some versions of ufork() */ + ap_str_toupper(username); + + pid = ufork(username); + if (pid == -1 && errno == EPERM) { + ap_log_error(APLOG_MARK, APLOG_EMERG, errno, + NULL, "ufork: Possible mis-configuration " + "for user %s - Aborting.", user); + exit(1); + } + break; + + default: + pid = 0; + break; + } + + return pid; +} + +#else /* _OSD_POSIX */ +void bs2000_os_is_not_here() +{ +} +#endif /* _OSD_POSIX */ diff --git a/trunk/os/bs2000/os.h b/trunk/os/bs2000/os.h new file mode 100644 index 0000000000..48692b7b78 --- /dev/null +++ b/trunk/os/bs2000/os.h @@ -0,0 +1,34 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_OS_BS2000_H +#define APACHE_OS_BS2000_H + +#define PLATFORM "BS2000" + +#include "../unix/os.h" + +/* + * This file in included in all Apache source code. It contains definitions + * of facilities available on _this_ operating system (HAVE_* macros), + * and prototypes of OS specific functions defined in os.c or os-inline.c + */ + +/* Other ap_os_ routines not used by this platform */ + +extern pid_t os_fork(const char *user); + +#endif /* APACHE_OS_BS2000_H */ diff --git a/trunk/os/config.m4 b/trunk/os/config.m4 new file mode 100644 index 0000000000..336f360d75 --- /dev/null +++ b/trunk/os/config.m4 @@ -0,0 +1,26 @@ +AC_MSG_CHECKING(for target platform) + +case $host in +*beos*) + OS="beos" + OS_DIR=$OS + ;; +*pc-os2-emx*) + OS="os2" + OS_DIR=$OS + ;; +bs2000*) + OS="unix" + OS_DIR=$OS + ;; +*cygwin*) + OS="cygwin" + OS_DIR="unix" + ;; +*) + OS="unix" + OS_DIR=$OS;; +esac + +AC_MSG_RESULT($OS) +APACHE_FAST_OUTPUT(os/${OS_DIR}/Makefile) diff --git a/trunk/os/netware/Apache.def b/trunk/os/netware/Apache.def new file mode 100644 index 0000000000..6d8bf9f41e --- /dev/null +++ b/trunk/os/netware/Apache.def @@ -0,0 +1,5 @@ +MODULE APRLIB.NLM +MODULE LIBC.NLM +MODULE WS2_32.NLM +EXPORT @HTTPD.IMP +IMPORT GetCurrentAddressSpace diff --git a/trunk/os/netware/apache.xdc b/trunk/os/netware/apache.xdc new file mode 100644 index 0000000000000000000000000000000000000000..12a7f6ba2df41eccb047c2884088c022f9395540 GIT binary patch literal 128 zcmZ>Aba!K7U|?VbVr&2;2Lb{>% + +AP_DECLARE_DATA extern int hold_screen_on_exit; /* Indicates whether the screen should be held open on exit*/ + +#define CASE_BLIND_FILESYSTEM +#define NO_WRITEV + +#define APACHE_MPM_DIR "server/mpm/netware" /* generated on unix */ + +#define getpid NXThreadGetId + +/* Hold the screen open if there is an exit code and the hold_screen_on_exit flag >= 0 or the + hold_screen_on_exit > 0. If the hold_screen_on_exit flag is < 0 then close the screen no + matter what the exit code is. */ +#define exit(s) {if((s||hold_screen_on_exit)&&(hold_screen_on_exit>=0)){pressanykey();}apr_terminate();exit(s);} + +#endif /* ! APACHE_OS_H */ diff --git a/trunk/os/netware/pre_nw.h b/trunk/os/netware/pre_nw.h new file mode 100644 index 0000000000..899a7b4399 --- /dev/null +++ b/trunk/os/netware/pre_nw.h @@ -0,0 +1,70 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __pre_nw__ +#define __pre_nw__ + +#include + +#ifndef __GNUC__ +#pragma precompile_target "precomp.mch" +#endif + +#define NETWARE + +#define N_PLAT_NLM + +/* hint for MSL C++ that we're on NetWare platform */ +#define __NETWARE__ + +/* the FAR keyword has no meaning in a 32-bit environment + but is used in the SDK headers so we take it out */ +#define FAR +#define far + +/* no-op for Codewarrior C compiler; a functions are cdecl + by default */ +#define cdecl + +/* if we have wchar_t enabled in C++, predefine this type to avoid + a conflict in Novell's header files */ +#ifndef __GNUC__ +#if (__option(cplusplus) && __option(wchar_type)) +#define _WCHAR_T +#endif +#endif + +/* C9X defintion used by MSL C++ library */ +#define DECIMAL_DIG 17 + +/* some code may want to use the MS convention for long long */ +#ifndef __int64 +#define __int64 long long +#endif + +/* Don't use the DBM rewrite map for mod_rewrite */ +#define NO_DBM_REWRITEMAP + +/* Allow MOD_AUTH_DBM to use APR */ +#define AP_AUTH_DBM_USE_APR + +/* Restrict the number of nested includes */ +#define AP_MAX_INCLUDE_DEPTH 48 + +#endif + + + diff --git a/trunk/os/netware/util_nw.c b/trunk/os/netware/util_nw.c new file mode 100644 index 0000000000..02f574bf67 --- /dev/null +++ b/trunk/os/netware/util_nw.c @@ -0,0 +1,105 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_log.h" + +#include +#include + +int nlmUnloadSignaled(int wait); +event_handle_t eh; +Warn_t ref; +Report_t dum; + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + return apr_proc_create(newproc, progname, args, env, attr, p); +} + +int _NonAppCheckUnload( void ) +{ + return nlmUnloadSignaled(1); +} + +// down server event callback +void ap_down_server_cb(void *, void *) +{ + nlmUnloadSignaled(0); + return; +} + +// Required place holder event callback +void ap_dummy_cb(void *, void *) +{ + return; +} + +// destroy callback resources +void ap_cb_destroy(void *) +{ + // cleanup down event notification + UnRegisterEventNotification(eh); + NX_UNWRAP_INTERFACE(ref); + NX_UNWRAP_INTERFACE(dum); +} + +int _NonAppStart +( + void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)( int conn, void *fileHandle, size_t offset, + size_t nbytes, size_t *bytesRead, void *buffer ), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages +) +{ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) + + // register for down server event + rtag_t rt = AllocateResourceTag(NLMHandle, "Apache2 Down Server Callback", + EventSignature); + + NX_WRAP_INTERFACE((void *)ap_down_server_cb, 2, (void **)&ref); + NX_WRAP_INTERFACE((void *)ap_dummy_cb, 2, (void **)&dum); + eh = RegisterForEventNotification(rt, EVENT_DOWN_SERVER, + EVENT_PRIORITY_APPLICATION, + ref, dum, NULL); + + // clean-up + NXVmRegisterExitHandler(ap_cb_destroy, NULL); + +} + diff --git a/trunk/os/os2/Makefile.in b/trunk/os/os2/Makefile.in new file mode 100644 index 0000000000..fba497279b --- /dev/null +++ b/trunk/os/os2/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libos.la +LTLIBRARY_SOURCES = util_os2.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/os/os2/config.m4 b/trunk/os/os2/config.m4 new file mode 100644 index 0000000000..b62d214e1d --- /dev/null +++ b/trunk/os/os2/config.m4 @@ -0,0 +1,3 @@ +if test "$OS" = "os2" ; then + APR_ADDTO(CFLAGS, [-DOS2 -O2]) +fi diff --git a/trunk/os/os2/core.mk b/trunk/os/os2/core.mk new file mode 100644 index 0000000000..639417e8e7 --- /dev/null +++ b/trunk/os/os2/core.mk @@ -0,0 +1,7 @@ +# Some rules for making a shared core dll on OS/2 + +os2core: httpd.dll $(CORE_IMPLIB) + $(LIBTOOL) --mode=link gcc -Zstack 512 $(LDFLAGS) $(EXTRA_LDFLAGS) -o httpd $(CORE_IMPLIB) + +httpd.dll: $(PROGRAM_DEPENDENCIES) $(CORE_IMPLIB) + $(LINK) -Zdll $(EXTRA_LDFLAGS) -s -o $@ server/exports.lo modules.lo $(PROGRAM_DEPENDENCIES) $(AP_LIBS) server/ApacheCoreOS2.def diff --git a/trunk/os/os2/core_header.def b/trunk/os/os2/core_header.def new file mode 100644 index 0000000000..ec3703a669 --- /dev/null +++ b/trunk/os/os2/core_header.def @@ -0,0 +1,19 @@ +LIBRARY httpd INITINSTANCE +DESCRIPTION "Apache Server Core" +DATA NONSHARED + +EXPORTS + "main" + +; One for mod_dav from socket library + "_swaps" + +; And some more for mod_unique_id + "gethostname" + "gethostbyname" + "_swapl" + "h_errno" + "inet_ntoa" + +; mod_proxy needs this one + "inet_addr" diff --git a/trunk/os/os2/os.h b/trunk/os/os2/os.h new file mode 100644 index 0000000000..3b7b596751 --- /dev/null +++ b/trunk/os/os2/os.h @@ -0,0 +1,33 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_OS_H +#define APACHE_OS_H + +#define PLATFORM "OS/2" + +/* going away shortly... */ +#define HAVE_DRIVE_LETTERS +#define HAVE_UNC_PATHS +#define CASE_BLIND_FILESYSTEM + +/* + * This file in included in all Apache source code. It contains definitions + * of facilities available on _this_ operating system (HAVE_* macros), + * and prototypes of OS specific functions defined in os.c or os-inline.c + */ + +#endif /* ! APACHE_OS_H */ diff --git a/trunk/os/os2/util_os2.c b/trunk/os/os2/util_os2.c new file mode 100644 index 0000000000..e8d402d4e7 --- /dev/null +++ b/trunk/os/os2/util_os2.c @@ -0,0 +1,39 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define INCL_DOS +#define INCL_DOSERRORS +#include +#include "ap_config.h" +#include "httpd.h" +#include "http_log.h" +#include "os.h" +#include +#include +#include +#include +#include "apr_strings.h" + + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + return apr_proc_create(newproc, progname, args, env, attr, p); +} diff --git a/trunk/os/tpf/TPFExport b/trunk/os/tpf/TPFExport new file mode 100644 index 0000000000..449ebf2f93 --- /dev/null +++ b/trunk/os/tpf/TPFExport @@ -0,0 +1,7 @@ +#!/bin/sh +echo " Setting TPF/c89 environment variables" +export _C89_CCMODE=1 +# replace the following with the location of your TPF include files +export _C89_INCDIRS="/u/tpf41/currentmaint/include /u/tpf41/currentmaint/include/oco" +export TPF=YES +echo "Done" diff --git a/trunk/os/tpf/ebcdic.c b/trunk/os/tpf/ebcdic.c new file mode 100644 index 0000000000..e71928eeda --- /dev/null +++ b/trunk/os/tpf/ebcdic.c @@ -0,0 +1,179 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" +#if APR_CHARSET_EBCDIC +#include "ebcdic.h" +/* +This code does basic character mapping for IBM's TPF operating system. +It is a modified version of 's code for +the BS2000 (apache/src/os/bs2000/ebcdic.c). +*/ + +/* +Bijective EBCDIC (character set IBM-1047) to US-ASCII table: +This apr_table_t is bijective - there are no ambigous or duplicate characters. +*/ +const unsigned char os_toascii_strictly[256] = { + 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */ + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */ + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */ + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */ + 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */ + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */ + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */ + 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */ + 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */ + 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */ + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */ + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */ + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */ + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */ + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */ + 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */ + 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */ + 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */ + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */ + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */ + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */ + 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */ + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */ + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */ +}; + +/* +Server EBCDIC (character set IBM-1047) to US-ASCII table: +This apr_table_t is a copy of the os_toascii_strictly bijective apr_table_t above. +The only change is that hex 0a (\012 octal) is mapped to hex 0a +(ASCII's line feed) instead of hex 8e. This is done because throughout +Apache, protocol string definitions hardcode the linefeed as \012 (octal): +"Content-Type: text/plain\015\012". Without this kludge all protocol +string definitions would need to be changed from ...\012 to ...\025. +*/ +const unsigned char os_toascii[256] = { + 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */ + 0x87, 0x8d, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */ + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */ + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */ + 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */ + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */ + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */ + 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */ + 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */ + 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */ + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */ + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */ + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */ + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */ + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */ + 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */ + 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */ + 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */ + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */ + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */ + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */ + 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */ + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */ + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */ +}; + +/* +The US-ASCII to EBCDIC (character set IBM-1047) table: +This apr_table_t is bijective (no ambiguous or duplicate characters) +*/ +const unsigned char os_toebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */ + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */ + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */ + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */ + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ + 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */ + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ + 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */ + 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ + 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */ + 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ + 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */ + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */ + 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */ + 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */ + 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */ + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ + 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */ + 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ + 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */ + 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ +}; + +/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset) + * dest and srce may be identical, or separate memory blocks, but + * should not overlap. + */ +void +ebcdic2ascii(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + while (count-- != 0) { + *udest++ = os_toascii[*usrce++]; + } +} +void +ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count) +{ + while (count-- != 0) { + *dest++ = os_toascii_strictly[*srce++]; + } +} +void +ascii2ebcdic(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + + while (count-- != 0) { + *udest++ = os_toebcdic[*usrce++]; + } +} +#endif /*APR_CHARSET_EBCDIC*/ + diff --git a/trunk/os/tpf/ebcdic.h b/trunk/os/tpf/ebcdic.h new file mode 100644 index 0000000000..2c6036b874 --- /dev/null +++ b/trunk/os/tpf/ebcdic.h @@ -0,0 +1,24 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void ebcdic2ascii(void *dest, const void *srce, size_t count); +void ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count); +void ascii2ebcdic(void *dest, const void *srce, size_t count); + diff --git a/trunk/os/tpf/os.c b/trunk/os/tpf/os.c new file mode 100644 index 0000000000..9b9bacc1c7 --- /dev/null +++ b/trunk/os/tpf/os.c @@ -0,0 +1,132 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file will include OS specific functions which are not inlineable. + * Any inlineable functions should be defined in os-inline.c instead. + */ + +#include "httpd.h" +#include "http_core.h" +#include "os.h" +#include "scoreboard.h" +#include "http_log.h" + +static FILE *sock_fp; + +#ifndef __PIPE_ +int pipe(int fildes[2]) +{ + errno = ENOSYS; + return(-1); +} +#endif + +/* fork and exec functions are not defined on + TPF due to the implementation of tpf_fork() */ + +pid_t fork(void) +{ + errno = ENOSYS; + return(-1); +} + +int execl(const char *path, const char *arg0, ...) +{ + errno = ENOSYS; + return(-1); +} + +int execle(const char *path, const char *arg0, ...) +{ + errno = ENOSYS; + return(-1); +} + +int execve(const char *path, char *const argv[], char *const envp[]) +{ + errno = ENOSYS; + return(-1); +} + +int execvp(const char *file, char *const argv[]) +{ + errno = ENOSYS; + return(-1); +} + + +pid_t os_fork(server_rec *s, int slot) +{ + struct tpf_fork_input fork_input; + APACHE_TPF_INPUT input_parms; + int count; + listen_rec *lr; + + fflush(stdin); + if (dup2(fileno(sock_fp), STDIN_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s, + "unable to replace stdin with sock device driver"); + fflush(stdout); + if (dup2(fileno(sock_fp), STDOUT_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s, + "unable to replace stdout with sock device driver"); + input_parms.generation = ap_my_generation; + input_parms.scoreboard_heap = ap_scoreboard_image; + + lr = ap_listeners; + count = 0; + do { + input_parms.listeners[count] = lr->fd; + lr = lr->next; + count++; + } while(lr != ap_listeners); + + input_parms.slot = slot; + input_parms.restart_time = ap_restart_time; + fork_input.ebw_data = &input_parms; + fork_input.program = ap_server_argv0; + fork_input.prog_type = TPF_FORK_NAME; + fork_input.istream = TPF_FORK_IS_BALANCE; + fork_input.ebw_data_length = sizeof(input_parms); + fork_input.parm_data = "-x"; + return tpf_fork(&fork_input); +} + +int os_check_server(char *server) { +#ifndef USE_TPF_DAEMON + int rv; + int *current_acn; + if((rv = inetd_getServerStatus(server)) == INETD_SERVER_STATUS_INACTIVE) + return 1; + else { + current_acn = (int *)cinfc_fast(CINFC_CMMACNUM); + if(ecbp2()->ce2acn != *current_acn) + return 1; + } +#endif + return 0; +} + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + return apr_proc_create(newproc, progname, args, env, attr, p); +} diff --git a/trunk/os/tpf/os.h b/trunk/os/tpf/os.h new file mode 100644 index 0000000000..10d5874aee --- /dev/null +++ b/trunk/os/tpf/os.h @@ -0,0 +1,87 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_OS_H +#define APACHE_OS_H + +#define PLATFORM "TPF" + +#ifdef errno +#undef errno +#endif + +/* + * This file in included in all Apache source code. It contains definitions + * of facilities available on _this_ operating system (HAVE_* macros), + * and prototypes of OS specific functions defined in os.c or os-inline.c + */ + +#include "apr.h" +#include "ap_config.h" +#include +#ifndef __strings_h + +#define FD_SETSIZE 2048 + +typedef long fd_mask; + +#define NBBY 8 /* number of bits in a byte */ +#define NFDBITS (sizeof(fd_mask) * NBBY) +#define howmany(x, y) (((x)+((y)-1))/(y)) + +typedef struct fd_set { + fd_mask fds_bits [howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +#define FD_CLR(n, p)((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p)((p)->fds_bits[(n)/NFDBITS] & (1 <<((n) % NFDBITS))) +#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) +#endif + +#ifdef FD_SET +#undef FD_SET +#define FD_SET(n, p) (0) +#endif + +#include +struct apache_input { + INETD_SERVER_INPUT inetd_server; + void *scoreboard_heap; /* scoreboard system heap address */ + int scoreboard_fd; /* scoreboard file descriptor */ + int slot; /* child number */ + int generation; /* server generation number */ + int listeners[10]; + time_t restart_time; +}; + +typedef struct apache_input APACHE_TPF_INPUT; + +extern int tpf_child; + +struct server_rec; +pid_t os_fork(struct server_rec *s, int slot); +int os_check_server(char *server); + +extern char *ap_server_argv0; +extern int scoreboard_fd; +#include +#ifndef SIGPIPE +#define SIGPIPE 14 +#endif +#ifdef NSIG +#undef NSIG +#endif +#endif /*! APACHE_OS_H*/ diff --git a/trunk/os/tpf/samples/linkdll.jcl b/trunk/os/tpf/samples/linkdll.jcl new file mode 100644 index 0000000000..16524bf3c9 --- /dev/null +++ b/trunk/os/tpf/samples/linkdll.jcl @@ -0,0 +1,121 @@ +//APACH JOB MSGLEVEL=(1,1),CLASS=A,MSGCLASS=A +/*ROUTE PRINT XXXXXX.XXXXXX +/*ROUTE PUNCH XXXXXX.XXXXXX +/*NOTIFY XXXXXX.XXXXXX +//CCLE JCLLIB ORDER=(SYS1.CBC.SCBCPRC,SYS1.CEE.SCEEPROC) +//PRELINK EXEC EDCPL,COND.LKED=(0,NE), +// PPARM='OMVS,DLLNAME(pppp)', +// LREGSIZ='2048K', +// LPARM='AMODE=31,RMODE=ANY,LIST,XREF' +//PLKED.SYSLIB DD DISP=SHR,DSN=FSE0000.DEVP.STUB.OB +// DD DISP=SHR,DSN=FSE0000.DEVP.CLIB.OB +// DD DISP=SHR,DSN=ACP.CLIB.RLSE46.WEB +// DD DISP=SHR,DSN=ACP.STUB.RLSE46.WEB +// DD DISP=SHR,DSN=ACP.CLIB.RLSE40 +// DD DISP=SHR,DSN=ACP.STUB.RLSE40 +//PLKED.SYSDEFSD DD DSN=APA0000.DEVP.IMPORTS.DSD(ppppvv),DISP=SHR +//PLKED.DSD DD DSN=APA0000.DEVP.IMPORTS.DSD,DISP=SHR +//PLKED.OBJLIB DD DISP=SHR,DSN=FSE0000.DEVP.TEST.OB +// DD DISP=SHR,DSN=ACP.OBJ.RLSE46.WEB +// DD DISP=SHR,DSN=ACP.OBJ.INTG98.NBS +// DD DISP=SHR,DSN=ACP.MAIN.SYST.OBBSS +// DD DISP=SHR,DSN=ACP.DF.MAIN.SYST.OBBSS +// DD DISP=SHR,DSN=ACP.OBJ.RLSE40.BSS +//PLKED.OBJ1 DD PATH='/usr/local/apache/src/ap/ap_cpystrn.o' +//PLKED.OBJ2 DD PATH='/usr/local/apache/src/ap/ap_execve.o' +//PLKED.OBJ3 DD PATH='/usr/local/apache/src/ap/ap_signal.o' +//PLKED.OBJ4 DD PATH='/usr/local/apache/src/ap/ap_slack.o' +//PLKED.OBJ5 DD PATH='/usr/local/apache/src/ap/ap_snprintf.o' +//PLKED.OBJ6 DD PATH='/usr/local/apache/src/ap/ap_strings.o' +//PLKED.OBJ7 DD PATH='/usr/local/apache/src/os/tpf/ebcdic.o' +//PLKED.OBJ8 DD PATH='/usr/local/apache/src/os/tpf/os.o' +//PLKED.OBJ9 DD PATH='/usr/local/apache/src/os/tpf/os-inline.o' +//PLKED.OBJ10 DD PATH='/usr/local/apache/src/regex/regcomp.o' +//PLKED.OBJ11 DD PATH='/usr/local/apache/src/regex/regerror.o' +//PLKED.OBJ12 DD PATH='/usr/local/apache/src/regex/regexec.o' +//PLKED.OBJ13 DD PATH='/usr/local/apache/src/regex/regfree.o' +//PLKED.OBJ14 DD PATH='/usr/local/apache/src/main/alloc.o' +//PLKED.OBJ15 DD PATH='/usr/local/apache/src/main/buff.o' +//PLKED.OBJ16 DD PATH='/usr/local/apache/src/main/fnmatch.o' +//PLKED.OBJ17 DD PATH='/usr/local/apache/src/main/http_config.o' +//PLKED.OBJ18 DD PATH='/usr/local/apache/src/main/http_core.o' +//PLKED.OBJ19 DD PATH='/usr/local/apache/src/main/http_log.o' +//PLKED.OBJ20 DD PATH='/usr/local/apache/src/main/http_main.o' +//PLKED.OBJ21 DD PATH='/usr/local/apache/src/main/http_protocol.o' +//PLKED.OBJ22 DD PATH='/usr/local/apache/src/main/http_request.o' +//PLKED.OBJ23 DD PATH='/usr/local/apache/src/main/http_vhost.o' +//PLKED.OBJ24 DD PATH='/usr/local/apache/src/main/md5c.o' +//PLKED.OBJ25 DD PATH='/usr/local/apache/src/main/rfc1413.o' +//PLKED.OBJ26 DD PATH='/usr/local/apache/src/main/util.o' +//PLKED.OBJ27 DD PATH='/usr/local/apache/src/main/util_date.o' +//PLKED.OBJ28 DD PATH='/usr/local/apache/src/main/util_md5.o' +//PLKED.OBJ29 DD PATH='/usr/local/apache/src/main/util_script.o' +//PLKED.OBJ30 DD PATH='/usr/local/apache/src/main/util_uri.o' +//PLKED.OBJ31 DD PATH='/usr/local/apache/src/modules.o' +//PLKED.OBJ32 DD PATH='/usr/local/apache/src/buildmark.o' +//PLKED.OBJ33 DD PATH='/usr/local/apache/src/modules/standard/mod_auto\ +// index.o' +//PLKED.OBJ34 DD PATH='/usr/local/apache/src/modules/standard/mod_dir.\ +// o' +//PLKED.OBJ35 DD PATH='/usr/local/apache/src/modules/standard/mod_mime\ +// .o' +//PLKED.OBJ36 DD PATH='/usr/local/apache/src/modules/standard/mod_sete\ +// nvif.o' +//PLKED.OBJ37 DD PATH='/usr/local/apache/src/modules/standard/mod_alia\ +// s.o' +//PLKED.OBJ38 DD PATH='/usr/local/apache/src/modules/standard/mod_acce\ +// ss.o' +//PLKED.OBJ39 DD PATH='/usr/local/apache/src/modules/standard/mod_user\ +// dir.o' +//PLKED.OBJ40 DD PATH='/usr/local/apache/src/modules/standard/mod_spel\ +// ing.o' +//PLKED.OBJ41 DD PATH='/usr/local/apache/src/modules/standard/mod_nego\ +// tiation.o' +//PLKED.SYSIN DD * + ORDER @@DLMHDR + INCLUDE OBJLIB(CSTRTD40) + INCLUDE OBJ1 + INCLUDE OBJ2 + INCLUDE OBJ3 + INCLUDE OBJ4 + INCLUDE OBJ5 + INCLUDE OBJ6 + INCLUDE OBJ7 + INCLUDE OBJ8 + INCLUDE OBJ9 + INCLUDE OBJ10 + INCLUDE OBJ11 + INCLUDE OBJ12 + INCLUDE OBJ13 + INCLUDE OBJ14 + INCLUDE OBJ15 + INCLUDE OBJ16 + INCLUDE OBJ17 + INCLUDE OBJ18 + INCLUDE OBJ19 + INCLUDE OBJ20 + INCLUDE OBJ21 + INCLUDE OBJ22 + INCLUDE OBJ23 + INCLUDE OBJ24 + INCLUDE OBJ25 + INCLUDE OBJ26 + INCLUDE OBJ27 + INCLUDE OBJ28 + INCLUDE OBJ29 + INCLUDE OBJ30 + INCLUDE OBJ31 + INCLUDE OBJ32 + INCLUDE OBJ33 + INCLUDE OBJ34 + INCLUDE OBJ35 + INCLUDE OBJ36 + INCLUDE OBJ37 + INCLUDE OBJ38 + INCLUDE OBJ39 + INCLUDE OBJ40 + INCLUDE OBJ41 +/* +//*** WARNING *** NEVER change .LK to .OB in SYSLMOD!!! +//LKED.SYSLMOD DD DISP=OLD,DSN=xxxxxx.xxxx(ppppvv) +// diff --git a/trunk/os/tpf/samples/loadset.jcl b/trunk/os/tpf/samples/loadset.jcl new file mode 100644 index 0000000000..405af82847 --- /dev/null +++ b/trunk/os/tpf/samples/loadset.jcl @@ -0,0 +1,58 @@ +//OLDRWEB JOB MSGLEVEL=1,CLASS=A,MSGCLASS=S +//JOBCAT DD DSN=ICFCAT.ESAWK2,DISP=SHR +/*ROUTE PRINT xxxxxx.xxxxxxx +/*ROUTE PUNCH xxxxxx.xxxxxxx +//TLDR EXEC PGM=TPFLDRCA,REGION=8M, +// PARM='OLDR,SYS=ACP,CLMSIZE=8000000' +//STEPLIB DD DSN=ACP.LINK.RLSE46.WEB,DISP=SHR +// DD DSN=ACP.LINK.RLSE40.BSS,DISP=SHR +// DD DSN=VIS0000.DEVP.TEST.LK,DISP=SHR +// DD DSN=SYS1.CEE.SCEERUN,DISP=SHR +//SALTB DD DSN=ACP.SALTBL.RLSE46.WEB,DISP=SHR +// DD DSN=ACP.SALTBL.INTG46.WEB,DISP=SHR +//OBJLIB DD DSN=FSE0000.DEVP.TEST.OB,DISP=SHR +// DD DSN=APA0000.DEVP.TEST.OB,DISP=SHR +// DD DSN=ACP.DRVE.TEST.OB,DISP=SHR +// DD DSN=ACP.OBJ.RLSE46.WEB,DISP=SHR +// DD DSN=ACP.OBJ.INTG36.DRV,DISP=SHR +// DD DSN=ACP.OBJ.INTG46.WEB,DISP=SHR +// DD DSN=ACP.OBJ.INTG40.BSS,DISP=SHR +//LOADMOD DD DSN=FSE0000.DEVP.TEST.LK,DISP=SHR +// DD DSN=APA0000.DEVP.TEST.LK,DISP=SHR +// DD DSN=CWEISS.LINK,DISP=SHR +// DD DSN=ACP.DRVE.TEST.LK,DISP=SHR +// DD DSN=ACP.LINK.RLSE46.WEB,DISP=SHR +// DD DSN=ACP.LINK.INTG98.NBS,DISP=SHR +// DD DSN=ACP.LINK.INTG46.WEB,DISP=SHR +// DD DSN=ACP.LINK.INTG36.DRV,DISP=SHR +// DD DSN=ACP.LINK.INTG40.BSS,DISP=SHR +//LOADSUM DD DSN=&&LOADSUM,DISP=(NEW,PASS),UNIT=SYSDA, +// LRECL=133,SPACE=(TRK,(10,10)),RECFM=FBA +//CPRTEMP DD UNIT=SYSDA, +// DSN=&&CPRTEMP,SPACE=(TRK,(100,20)), +// DCB=(RECFM=FB,BLKSIZE=4095,LRECL=4095), +// DISP=(NEW,DELETE) +//PROGTEMP DD UNIT=SYSDA, +// DSN=&&PRTEMP,SPACE=(TRK,(100,20)), +// DCB=(RECFM=FB,BLKSIZE=4095,LRECL=4095), +// DISP=(NEW,DELETE) +//OUTPUT DD DSN=&&VRDROUT,DISP=(NEW,PASS),UNIT=SYSDA, +// DCB=(RECFM=F,BLKSIZE=4095,LRECL=4095) +//SYSUDUMP DD DUMMY +//SYSABEND DD DUMMY +//SYSOUT DD SYSOUT=A +//SYSPRINT DD SYSOUT=A +//PRINTER DD SYSOUT=A +//CEEDUMP DD SYSOUT=A +//SYSIN DD * +SYSID=BSS +PATVERS=NONE +SALVERS=40 +LOADER LOADSET lllllll +LOADER CALL PROG ppppvv +/* +//TRANSMIT EXEC PGM=IKJEFT01, +// PARM='TRANSMIT xxxxxx.xxxxxx DDNAME(SYSTSIN) NOLOG NONOTIFY SEQ' +//SYSTSIN DD UNIT=SYSDA, +// DSN=&&VRDROUT,DISP=(OLD,DELETE) +//SYSTSPRT DD DUMMY diff --git a/trunk/os/unix/Makefile.in b/trunk/os/unix/Makefile.in new file mode 100644 index 0000000000..eddb2c2644 --- /dev/null +++ b/trunk/os/unix/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libos.la +LTLIBRARY_SOURCES = unixd.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/os/unix/config.m4 b/trunk/os/unix/config.m4 new file mode 100644 index 0000000000..dacbf6b539 --- /dev/null +++ b/trunk/os/unix/config.m4 @@ -0,0 +1,7 @@ +if test "$OS" = "unix" ; then + APACHE_TYPE_RLIM_T + + AC_CHECK_HEADERS(sys/time.h sys/resource.h sys/sem.h sys/ipc.h) + + AC_CHECK_FUNCS(setsid killpg) +fi diff --git a/trunk/os/unix/os.h b/trunk/os/unix/os.h new file mode 100644 index 0000000000..4370c22931 --- /dev/null +++ b/trunk/os/unix/os.h @@ -0,0 +1,36 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_OS_H +#define APACHE_OS_H + +#include "apr.h" +#include "ap_config.h" + +#ifndef PLATFORM +#define PLATFORM "Unix" +#endif + +/* On platforms where AP_NEED_SET_MUTEX_PERMS is defined, modules + * should call unixd_set_*_mutex_perms on mutexes created in the + * parent process. */ +#define AP_NEED_SET_MUTEX_PERMS + +#ifdef _OSD_POSIX +pid_t os_fork(const char *user); +#endif + +#endif /* !APACHE_OS_H */ diff --git a/trunk/os/unix/unixd.c b/trunk/os/unix/unixd.c new file mode 100644 index 0000000000..b2f65e30a3 --- /dev/null +++ b/trunk/os/unix/unixd.c @@ -0,0 +1,718 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" +#include "http_main.h" +#include "http_log.h" +#include "unixd.h" +#include "mpm_common.h" +#include "os.h" +#include "ap_mpm.h" +#include "apr_thread_proc.h" +#include "apr_strings.h" +#include "apr_portable.h" +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif +/* XXX */ +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif +#ifdef HAVE_SYS_SEM_H +#include +#endif +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + +unixd_config_rec unixd_config; + +/* Set group privileges. + * + * Note that we use the username as set in the config files, rather than + * the lookup of to uid --- the same uid may have multiple passwd entries, + * with different sets of groups for each. + */ + +static int set_group_privs(void) +{ + if (!geteuid()) { + const char *name; + + /* Get username if passed as a uid */ + + if (unixd_config.user_name[0] == '#') { + struct passwd *ent; + uid_t uid = atoi(&unixd_config.user_name[1]); + + if ((ent = getpwuid(uid)) == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "getpwuid: couldn't determine user name from uid %u, " + "you probably need to modify the User directive", + (unsigned)uid); + return -1; + } + + name = ent->pw_name; + } + else + name = unixd_config.user_name; + +#if !defined(OS2) && !defined(TPF) + /* OS/2 and TPF don't support groups. */ + + /* + * Set the GID before initgroups(), since on some platforms + * setgid() is known to zap the group list. + */ + if (setgid(unixd_config.group_id) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setgid: unable to set group id to Group %u", + (unsigned)unixd_config.group_id); + return -1; + } + + /* Reset `groups' attributes. */ + + if (initgroups(name, unixd_config.group_id) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "initgroups: unable to set groups for User %s " + "and Group %u", name, (unsigned)unixd_config.group_id); + return -1; + } +#endif /* !defined(OS2) && !defined(TPF) */ + } + return 0; +} + + +AP_DECLARE(int) unixd_setup_child(void) +{ + if (set_group_privs()) { + return -1; + } +#ifdef MPE + /* Only try to switch if we're running as MANAGER.SYS */ + if (geteuid() == 1 && unixd_config.user_id > 1) { + GETPRIVMODE(); + if (setuid(unixd_config.user_id) == -1) { + GETUSERMODE(); + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setuid: unable to change to uid: %ld", + (long) unixd_config.user_id); + exit(1); + } + GETUSERMODE(); + } +#else + /* Only try to switch if we're running as root */ + if (!geteuid() && ( +#ifdef _OSD_POSIX + os_init_job_environment(NULL, unixd_config.user_name, ap_exists_config_define("DEBUG")) != 0 || +#endif + setuid(unixd_config.user_id) == -1)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setuid: unable to change to uid: %ld", + (long) unixd_config.user_id); + return -1; + } +#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* this applies to Linux 2.4+ */ +#ifdef AP_MPM_WANT_SET_COREDUMPDIR + if (ap_coredumpdir_configured) { + if (prctl(PR_SET_DUMPABLE, 1)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "set dumpable failed - this child will not coredump" + " after software errors"); + } + } +#endif +#endif +#endif + return 0; +} + + +AP_DECLARE(const char *) unixd_set_user(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + unixd_config.user_name = arg; + unixd_config.user_id = ap_uname2id(arg); +#if !defined (BIG_SECURITY_HOLE) && !defined (OS2) + if (unixd_config.user_id == 0) { + return "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" + "\tIf you still desire to serve pages as root then\n" + "\tadd -DBIG_SECURITY_HOLE to the CFLAGS env variable\n" + "\tand then rebuild the server.\n" + "\tIt is strongly suggested that you instead modify the User\n" + "\tdirective in your httpd.conf file to list a non-root\n" + "\tuser.\n"; + } +#endif + + return NULL; +} + +AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + unixd_config.group_id = ap_gname2id(arg); + + return NULL; +} + +AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp) +{ + apr_finfo_t wrapper; + + unixd_config.user_name = DEFAULT_USER; + unixd_config.user_id = ap_uname2id(DEFAULT_USER); + unixd_config.group_id = ap_gname2id(DEFAULT_GROUP); + + /* Check for suexec */ + unixd_config.suexec_enabled = 0; + if ((apr_stat(&wrapper, SUEXEC_BIN, + APR_FINFO_NORM, ptemp)) != APR_SUCCESS) { + return; + } + + if ((wrapper.protection & APR_USETID) && wrapper.user == 0) { + unixd_config.suexec_enabled = 1; + } +} + + +AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, + const char *arg, const char * arg2, int type) +{ +#if (defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS)) && APR_HAVE_STRUCT_RLIMIT && APR_HAVE_GETRLIMIT + char *str; + struct rlimit *limit; + /* If your platform doesn't define rlim_t then typedef it in ap_config.h */ + rlim_t cur = 0; + rlim_t max = 0; + + *plimit = (struct rlimit *)apr_pcalloc(cmd->pool, sizeof(**plimit)); + limit = *plimit; + if ((getrlimit(type, limit)) != 0) { + *plimit = NULL; + ap_log_error(APLOG_MARK, APLOG_ERR, errno, cmd->server, + "%s: getrlimit failed", cmd->cmd->name); + return; + } + + if ((str = ap_getword_conf(cmd->pool, &arg))) { + if (!strcasecmp(str, "max")) { + cur = limit->rlim_max; + } + else { + cur = atol(str); + } + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, + "Invalid parameters for %s", cmd->cmd->name); + return; + } + + if (arg2 && (str = ap_getword_conf(cmd->pool, &arg2))) { + max = atol(str); + } + + /* if we aren't running as root, cannot increase max */ + if (geteuid()) { + limit->rlim_cur = cur; + if (max) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, + "Must be uid 0 to raise maximum %s", cmd->cmd->name); + } + } + else { + if (cur) { + limit->rlim_cur = cur; + } + if (max) { + limit->rlim_max = max; + } + } +#else + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, + "Platform does not support rlimit for %s", cmd->cmd->name); +#endif +} + +APR_HOOK_STRUCT( + APR_HOOK_LINK(get_suexec_identity) +) + +AP_IMPLEMENT_HOOK_RUN_FIRST(ap_unix_identity_t *, get_suexec_identity, + (const request_rec *r), (r), NULL) + +static apr_status_t ap_unix_create_privileged_process( + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, ap_unix_identity_t *ugid, + apr_pool_t *p) +{ + int i = 0; + const char **newargs; + char *newprogname; + char *execuser, *execgroup; + const char *argv0; + + if (!unixd_config.suexec_enabled) { + return apr_proc_create(newproc, progname, args, env, attr, p); + } + + argv0 = ap_strrchr_c(progname, '/'); + /* Allow suexec's "/" check to succeed */ + if (argv0 != NULL) { + argv0++; + } + else { + argv0 = progname; + } + + + if (ugid->userdir) { + execuser = apr_psprintf(p, "~%ld", (long) ugid->uid); + } + else { + execuser = apr_psprintf(p, "%ld", (long) ugid->uid); + } + execgroup = apr_psprintf(p, "%ld", (long) ugid->gid); + + if (!execuser || !execgroup) { + return APR_ENOMEM; + } + + i = 0; + if (args) { + while (args[i]) { + i++; + } + } + /* allocate space for 4 new args, the input args, and a null terminator */ + newargs = apr_palloc(p, sizeof(char *) * (i + 4)); + newprogname = SUEXEC_BIN; + newargs[0] = SUEXEC_BIN; + newargs[1] = execuser; + newargs[2] = execgroup; + newargs[3] = apr_pstrdup(p, argv0); + + /* + ** using a shell to execute suexec makes no sense thus + ** we force everything to be APR_PROGRAM, and never + ** APR_SHELLCMD + */ + if(apr_procattr_cmdtype_set(attr, APR_PROGRAM) != APR_SUCCESS) { + return APR_EGENERAL; + } + + i = 1; + do { + newargs[i + 3] = args[i]; + } while (args[i++]); + + return apr_proc_create(newproc, newprogname, newargs, env, attr, p); +} + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + ap_unix_identity_t *ugid = ap_run_get_suexec_identity(r); + + if (ugid == NULL) { + return apr_proc_create(newproc, progname, args, env, attr, p); + } + + return ap_unix_create_privileged_process(newproc, progname, args, env, + attr, ugid, p); +} + +/* XXX move to APR and externalize (but implement differently :) ) */ +static apr_lockmech_e proc_mutex_mech(apr_proc_mutex_t *pmutex) +{ + const char *mechname = apr_proc_mutex_name(pmutex); + + if (!strcmp(mechname, "sysvsem")) { + return APR_LOCK_SYSVSEM; + } + else if (!strcmp(mechname, "flock")) { + return APR_LOCK_FLOCK; + } + return APR_LOCK_DEFAULT; +} + +AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) +{ + if (!geteuid()) { + apr_lockmech_e mech = proc_mutex_mech(pmutex); + + switch(mech) { +#if APR_HAS_SYSVSEM_SERIALIZE + case APR_LOCK_SYSVSEM: + { + apr_os_proc_mutex_t ospmutex; +#if !APR_HAVE_UNION_SEMUN + union semun { + long val; + struct semid_ds *buf; + unsigned short *array; + }; +#endif + union semun ick; + struct semid_ds buf; + + apr_os_proc_mutex_get(&ospmutex, pmutex); + buf.sem_perm.uid = unixd_config.user_id; + buf.sem_perm.gid = unixd_config.group_id; + buf.sem_perm.mode = 0600; + ick.buf = &buf; + if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) { + return errno; + } + } + break; +#endif +#if APR_HAS_FLOCK_SERIALIZE + case APR_LOCK_FLOCK: + { + const char *lockfile = apr_proc_mutex_lockfile(pmutex); + + if (lockfile) { + if (chown(lockfile, unixd_config.user_id, + -1 /* no gid change */) < 0) { + return errno; + } + } + } + break; +#endif + default: + /* do nothing */ + break; + } + } + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex) +{ +#if !APR_PROC_MUTEX_IS_GLOBAL + apr_os_global_mutex_t osgmutex; + apr_os_global_mutex_get(&osgmutex, gmutex); + return unixd_set_proc_mutex_perms(osgmutex.proc_mutex); +#else /* APR_PROC_MUTEX_IS_GLOBAL */ + /* In this case, apr_proc_mutex_t and apr_global_mutex_t are the same. */ + return unixd_set_proc_mutex_perms(gmutex); +#endif /* APR_PROC_MUTEX_IS_GLOBAL */ +} + +AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, + apr_pool_t *ptrans) +{ + apr_socket_t *csd; + apr_status_t status; +#ifdef _OSD_POSIX + int sockdes; +#endif + + *accepted = NULL; + status = apr_socket_accept(&csd, lr->sd, ptrans); + if (status == APR_SUCCESS) { + *accepted = csd; +#ifdef _OSD_POSIX + apr_os_sock_get(&sockdes, csd); + if (sockdes >= FD_SETSIZE) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "new file descriptor %d is too large; you probably need " + "to rebuild Apache with a larger FD_SETSIZE " + "(currently %d)", + sockdes, FD_SETSIZE); + apr_socket_close(csd); + return APR_EINTR; + } +#endif + return APR_SUCCESS; + } + + if (APR_STATUS_IS_EINTR(status)) { + return status; + } + /* Our old behaviour here was to continue after accept() + * errors. But this leads us into lots of troubles + * because most of the errors are quite fatal. For + * example, EMFILE can be caused by slow descriptor + * leaks (say in a 3rd party module, or libc). It's + * foolish for us to continue after an EMFILE. We also + * seem to tickle kernel bugs on some platforms which + * lead to never-ending loops here. So it seems best + * to just exit in most cases. + */ + switch (status) { +#if defined(HPUX11) && defined(ENOBUFS) + /* On HPUX 11.x, the 'ENOBUFS, No buffer space available' + * error occurs because the accept() cannot complete. + * You will not see ENOBUFS with 10.20 because the kernel + * hides any occurrence from being returned to user space. + * ENOBUFS with 11.x's TCP/IP stack is possible, and could + * occur intermittently. As a work-around, we are going to + * ignore ENOBUFS. + */ + case ENOBUFS: +#endif + +#ifdef EPROTO + /* EPROTO on certain older kernels really means + * ECONNABORTED, so we need to ignore it for them. + * See discussion in new-httpd archives nh.9701 + * search for EPROTO. + * + * Also see nh.9603, search for EPROTO: + * There is potentially a bug in Solaris 2.x x<6, + * and other boxes that implement tcp sockets in + * userland (i.e. on top of STREAMS). On these + * systems, EPROTO can actually result in a fatal + * loop. See PR#981 for example. It's hard to + * handle both uses of EPROTO. + */ + case EPROTO: +#endif +#ifdef ECONNABORTED + case ECONNABORTED: +#endif + /* Linux generates the rest of these, other tcp + * stacks (i.e. bsd) tend to hide them behind + * getsockopt() interfaces. They occur when + * the net goes sour or the client disconnects + * after the three-way handshake has been done + * in the kernel but before userland has picked + * up the socket. + */ +#ifdef ECONNRESET + case ECONNRESET: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif +#ifdef ENETUNREACH + case ENETUNREACH: +#endif + /* EAGAIN/EWOULDBLOCK can be returned on BSD-derived + * TCP stacks when the connection is aborted before + * we call connect, but only because our listener + * sockets are non-blocking (AP_NONBLOCK_WHEN_MULTI_LISTEN) + */ +#ifdef EAGAIN + case EAGAIN: +#endif +#ifdef EWOULDBLOCK +#if !defined(EAGAIN) || EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: +#endif +#endif + break; +#ifdef ENETDOWN + case ENETDOWN: + /* + * When the network layer has been shut down, there + * is not much use in simply exiting: the parent + * would simply re-create us (and we'd fail again). + * Use the CHILDFATAL code to tear the server down. + * @@@ Martin's idea for possible improvement: + * A different approach would be to define + * a new APEXIT_NETDOWN exit code, the reception + * of which would make the parent shutdown all + * children, then idle-loop until it detected that + * the network is up again, and restart the children. + * Ben Hyde noted that temporary ENETDOWN situations + * occur in mobile IP. + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "apr_socket_accept: giving up."); + return APR_EGENERAL; +#endif /*ENETDOWN*/ + +#ifdef TPF + case EINACT: + ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "offload device inactive"); + return APR_EGENERAL; + break; + default: + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "select/accept error (%d)", status); + return APR_EGENERAL; +#else + default: + ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, + "apr_socket_accept: (client socket)"); + return APR_EGENERAL; +#endif + } + return status; +} + + +#ifdef _OSD_POSIX + +#include "apr_lib.h" + +#define USER_LEN 8 + +typedef enum +{ + bs2_unknown, /* not initialized yet. */ + bs2_noFORK, /* no fork() because -X flag was specified */ + bs2_FORK, /* only fork() because uid != 0 */ + bs2_UFORK /* Normally, ufork() is used to switch identities. */ +} bs2_ForkType; + +static bs2_ForkType forktype = bs2_unknown; + + +static void ap_str_toupper(char *str) +{ + while (*str) { + *str = apr_toupper(*str); + ++str; + } +} + +/* Determine the method for forking off a child in such a way as to + * set both the POSIX and BS2000 user id's to the unprivileged user. + */ +static bs2_ForkType os_forktype(int one_process) +{ + /* have we checked the OS version before? If yes return the previous + * result - the OS release isn't going to change suddenly! + */ + if (forktype == bs2_unknown) { + /* not initialized yet */ + + /* No fork if the one_process option was set */ + if (one_process) { + forktype = bs2_noFORK; + } + /* If the user is unprivileged, use the normal fork() only. */ + else if (getuid() != 0) { + forktype = bs2_FORK; + } + else + forktype = bs2_UFORK; + } + return forktype; +} + + + +/* This routine complements the setuid() call: it causes the BS2000 job + * environment to be switched to the target user's user id. + * That is important if CGI scripts try to execute native BS2000 commands. + */ +int os_init_job_environment(server_rec *server, const char *user_name, int one_process) +{ + bs2_ForkType type = os_forktype(one_process); + + /* We can be sure that no change to uid==0 is possible because of + * the checks in http_core.c:set_user() + */ + + if (one_process) { + + type = forktype = bs2_noFORK; + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, + "The debug mode of Apache should only " + "be started by an unprivileged user!"); + return 0; + } + + return 0; +} + +/* BS2000 requires a "special" version of fork() before a setuid() call */ +pid_t os_fork(const char *user) +{ + pid_t pid; + char username[USER_LEN+1]; + + switch (os_forktype(0)) { + + case bs2_FORK: + pid = fork(); + break; + + case bs2_UFORK: + apr_cpystrn(username, user, sizeof username); + + /* Make user name all upper case - for some versions of ufork() */ + ap_str_toupper(username); + + pid = ufork(username); + if (pid == -1 && errno == EPERM) { + ap_log_error(APLOG_MARK, APLOG_EMERG, errno, + NULL, "ufork: Possible mis-configuration " + "for user %s - Aborting.", user); + exit(1); + } + break; + + default: + pid = 0; + break; + } + + return pid; +} + +#endif /* _OSD_POSIX */ + diff --git a/trunk/os/unix/unixd.h b/trunk/os/unix/unixd.h new file mode 100644 index 0000000000..483a101057 --- /dev/null +++ b/trunk/os/unix/unixd.h @@ -0,0 +1,109 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UNIXD_H +#define UNIXD_H + +#include "httpd.h" +#include "http_config.h" +#include "ap_listen.h" +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif +#include "apr_hooks.h" +#include "apr_thread_proc.h" +#include "apr_proc_mutex.h" +#include "apr_global_mutex.h" + +#include +#include +#ifdef APR_HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_IPC_H +#include +#endif + +typedef struct { + uid_t uid; + gid_t gid; + int userdir; +} ap_unix_identity_t; + +AP_DECLARE_HOOK(ap_unix_identity_t *, get_suexec_identity,(const request_rec *r)) + +/* common stuff that unix MPMs will want */ + +/* Default user name and group name. These may be specified as numbers by + * placing a # before a number */ + +#ifndef DEFAULT_USER +#define DEFAULT_USER "#-1" +#endif +#ifndef DEFAULT_GROUP +#define DEFAULT_GROUP "#-1" +#endif + +typedef struct { + const char *user_name; + uid_t user_id; + gid_t group_id; + int suexec_enabled; +} unixd_config_rec; +AP_DECLARE_DATA extern unixd_config_rec unixd_config; + +AP_DECLARE(int) unixd_setup_child(void); +AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp); +AP_DECLARE(const char *) unixd_set_user(cmd_parms *cmd, void *dummy, + const char *arg); +AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, + const char *arg); +#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS) +AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, + const char *arg, const char * arg2, int type); +#endif + +/** + * One of the functions to set mutex permissions should be called in + * the parent process on platforms that switch identity when the + * server is started as root. + * If the child init logic is performed before switching identity + * (e.g., MPM setup for an accept mutex), it should only be called + * for SysV semaphores. Otherwise, it is safe to call it for all + * mutex types. + */ +AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex); +AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex); +AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans); + +#ifdef HAVE_KILLPG +#define unixd_killpg(x, y) (killpg ((x), (y))) +#define ap_os_killpg(x, y) (killpg ((x), (y))) +#else /* HAVE_KILLPG */ +#define unixd_killpg(x, y) (kill (-(x), (y))) +#define ap_os_killpg(x, y) (kill (-(x), (y))) +#endif /* HAVE_KILLPG */ + +#define UNIX_DAEMON_COMMANDS \ +AP_INIT_TAKE1("User", unixd_set_user, NULL, RSRC_CONF, \ + "Effective user id for this server"), \ +AP_INIT_TAKE1("Group", unixd_set_group, NULL, RSRC_CONF, \ + "Effective group id for this server") + +#endif diff --git a/trunk/os/win32/BaseAddr.ref b/trunk/os/win32/BaseAddr.ref new file mode 100644 index 0000000000..4a9adb298f --- /dev/null +++ b/trunk/os/win32/BaseAddr.ref @@ -0,0 +1,73 @@ +; os/win32/BaseAddr.ref contains the central repository +; of all module base addresses +; to avoid relocation + +; WARNING: Update this file by reviewing the image size +; of the debug-generated dll files; release images +; should fit in the larger debug-sized space. + +; module name base-address max-size + +libhttpd.dll 0x6FF00000 0x000A0000 +mod_auth_basic.so 0x6FEF0000 0x00010000 +mod_auth_digest.so 0x6FED0000 0x00020000 +mod_cern_meta.so 0x6FEC0000 0x00010000 +mod_expires.so 0x6FEB0000 0x00010000 +mod_headers.so 0x6FEA0000 0x00010000 +mod_info.so 0x6FE90000 0x00010000 +mod_rewrite.so 0x6FE70000 0x00020000 +mod_speling.so 0x6FE60000 0x00010000 +mod_status.so 0x6FE50000 0x00010000 +mod_usertrack.so 0x6FE40000 0x00010000 +mod_file_cache.so 0x6FE20000 0x00020000 +mod_unique_id.so 0x6FE00000 0x00010000 +mod_vhost_alias.so 0x6FDF0000 0x00010000 +mod_mime_magic.so 0x6FDE0000 0x00010000 +mod_dav.so 0x6FDC0000 0x00020000 +mod_dav_fs.so 0x6FDB0000 0x00010000 +mod_proxy.so 0x6FDA0000 0x00010000 +mod_proxy_connect.so 0x6FD90000 0x00010000 +mod_proxy_ftp.so 0x6FD80000 0x00010000 +mod_proxy_http.so 0x6FD70000 0x00010000 +mod_ssl.so 0x6FD00000 0x00070000 +mod_actions.so 0x6FCE0000 0x00010000 +mod_alias.so 0x6FCD0000 0x00010000 +mod_asis.so 0x6FCC0000 0x00010000 +mod_autoindex.so 0x6FCA0000 0x00010000 +mod_cgi.so 0x6FC90000 0x00010000 +mod_dir.so 0x6FC80000 0x00010000 +mod_env.so 0x6FC70000 0x00010000 +mod_imagemap.so 0x6FC60000 0x00010000 +mod_include.so 0x6FC50000 0x00010000 +mod_isapi.so 0x6FC40000 0x00010000 +mod_log_config.so 0x6FC30000 0x00010000 +mod_mime.so 0x6FC20000 0x00010000 +mod_negotiation.so 0x6FC10000 0x00010000 +mod_setenvif.so 0x6FC00000 0x00010000 +mod_userdir.so 0x6FBF0000 0x00010000 +mod_cache.so 0x6FBE0000 0x00010000 +mod_disk_cache.so 0x6FBD0000 0x00010000 +mod_mem_cache.so 0x6FBC0000 0x00010000 +mod_deflate.so 0x6FBA0000 0x00020000 +mod_ext_filter.so 0x6FB90000 0x00010000 +mod_charset_lite.so 0x6FB80000 0x00010000 +mod_authn_anon.so 0x6FB70000 0x00010000 +mod_authn_dbm.so 0x6FB60000 0x00010000 +mod_authn_default.so 0x6FB50000 0x00010000 +mod_authn_file.so 0x6FB40000 0x00010000 +mod_authz_dbm.so 0x6FB30000 0x00010000 +mod_authz_default.so 0x6FB20000 0x00010000 +mod_authz_groupfile.so 0x6FB10000 0x00010000 +mod_authz_host.so 0x6FB00000 0x00010000 +mod_authz_user.so 0x6FAF0000 0x00010000 +mod_logio.so 0x6FAE0000 0x00010000 +mod_ldap.so 0x6FAD0000 0x00010000 +mod_authnz_ldap.so 0x6FAC0000 0x00010000 +mod_ident.so 0x6FAB0000 0x00010000 +mod_proxy_ajp.so 0x6FAA0000 0x00010000 +mod_proxy_balancer.so 0x6FA90000 0x00010000 +mod_log_forensic.so 0x6FA80000 0x00010000 +mod_version.so 0x6FA70000 0x00010000 +mod_bucketeer.so 0x6FA60000 0x00010000 +mod_dumpio.so 0x6FA50000 0x00010000 +mod_echo.so 0x6FA40000 0x00010000 diff --git a/trunk/os/win32/ap_regkey.c b/trunk/os/win32/ap_regkey.c new file mode 100644 index 0000000000..4f3a5061e2 --- /dev/null +++ b/trunk/os/win32/ap_regkey.c @@ -0,0 +1,644 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +#include "apr.h" +#include "arch/win32/apr_arch_file_io.h" +#include "arch/win32/apr_arch_misc.h" +#include "ap_regkey.h" + +struct ap_regkey_t { + apr_pool_t *pool; + HKEY hkey; +}; + + +AP_DECLARE(const ap_regkey_t *) ap_regkey_const(int i) +{ + static struct ap_regkey_t ap_regkey_consts[7] = + { + {NULL, HKEY_CLASSES_ROOT}, + {NULL, HKEY_CURRENT_CONFIG}, + {NULL, HKEY_CURRENT_USER}, + {NULL, HKEY_LOCAL_MACHINE}, + {NULL, HKEY_USERS}, + {NULL, HKEY_PERFORMANCE_DATA}, + {NULL, HKEY_DYN_DATA} + }; + return ap_regkey_consts + i; +} + + +apr_status_t regkey_cleanup(void *key) +{ + ap_regkey_t *regkey = key; + + if (regkey->hkey && regkey->hkey != INVALID_HANDLE_VALUE) { + RegCloseKey(regkey->hkey); + regkey->hkey = INVALID_HANDLE_VALUE; + } + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_open(ap_regkey_t **newkey, + const ap_regkey_t *parentkey, + const char *keyname, + apr_int32_t flags, + apr_pool_t *pool) +{ + DWORD access = KEY_QUERY_VALUE; + DWORD exists; + HKEY hkey; + LONG rc; + + if (flags & APR_READ) + access |= KEY_READ; + if (flags & APR_WRITE) + access |= KEY_WRITE; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t keylen = strlen(keyname) + 1; + apr_size_t wkeylen = 256; + apr_wchar_t wkeyname[256]; + apr_status_t rv = apr_conv_utf8_to_ucs2(keyname, &keylen, wkeyname, &wkeylen); + if (rv != APR_SUCCESS) + return rv; + else if (keylen) + return APR_ENAMETOOLONG; + + if (flags & APR_CREATE) + rc = RegCreateKeyExW(parentkey->hkey, wkeyname, 0, NULL, 0, + access, NULL, &hkey, &exists); + else + rc = RegOpenKeyExW(parentkey->hkey, wkeyname, 0, access, &hkey); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + if (flags & APR_CREATE) + rc = RegCreateKeyEx(parentkey->hkey, keyname, 0, NULL, 0, + access, NULL, &hkey, &exists); + else + rc = RegOpenKeyEx(parentkey->hkey, keyname, 0, access, &hkey); + } +#endif + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + if ((flags & APR_EXCL) && (exists == REG_OPENED_EXISTING_KEY)) { + RegCloseKey(hkey); + return APR_EEXIST; + } + + *newkey = apr_palloc(pool, sizeof(**newkey)); + (*newkey)->pool = pool; + (*newkey)->hkey = hkey; + apr_pool_cleanup_register((*newkey)->pool, (void *)(*newkey), + regkey_cleanup, apr_pool_cleanup_null); + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_close(ap_regkey_t *regkey) +{ + apr_status_t stat; + if ((stat = regkey_cleanup(regkey)) == APR_SUCCESS) { + apr_pool_cleanup_kill(regkey->pool, regkey, regkey_cleanup); + } + return stat; +} + + +AP_DECLARE(apr_status_t) ap_regkey_remove(const ap_regkey_t *parent, + const char *keyname, + apr_pool_t *pool) +{ + LONG rc; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t keylen = strlen(keyname) + 1; + apr_size_t wkeylen = 256; + apr_wchar_t wkeyname[256]; + apr_status_t rv = apr_conv_utf8_to_ucs2(keyname, &keylen, wkeyname, &wkeylen); + if (rv != APR_SUCCESS) + return rv; + else if (keylen) + return APR_ENAMETOOLONG; + rc = RegDeleteKeyW(parent->hkey, wkeyname); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + /* We need to determine if subkeys exist on Win9x, to provide + * consistent behavior with NT, which returns access denied + * if subkeys exist when attempting to delete a key. + */ + DWORD subkeys; + HKEY hkey; + rc = RegOpenKeyEx(parent->hkey, keyname, 0, KEY_READ, &hkey); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + rc = RegQueryInfoKey(hkey, NULL, NULL, NULL, &subkeys, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + RegCloseKey(hkey); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + else if (subkeys) + return APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED); + rc = RegDeleteKey(parent->hkey, keyname); + } +#endif + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool) +{ + /* Retrieve a registry string value, and explode any envvars + * that the system has configured (e.g. %SystemRoot%/someapp.exe) + */ + LONG rc; + DWORD type; + apr_size_t size = 0; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t wvalname[256]; + apr_wchar_t *wvalue; + apr_status_t rv; + rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (valuelen) + return APR_ENAMETOOLONG; + /* Read to NULL buffer to determine value size */ + rc = RegQueryValueExW(key->hkey, wvalname, 0, &type, NULL, (DWORD *)&size); + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + if ((size < 2) || (type != REG_SZ && type != REG_EXPAND_SZ)) { + return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER); + } + + wvalue = apr_palloc(pool, size); + /* Read value based on size query above */ + rc = RegQueryValueExW(key->hkey, wvalname, 0, &type, + (LPBYTE)wvalue, (DWORD *)&size); + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + if (type == REG_EXPAND_SZ) { + apr_wchar_t zbuf[1]; + size = ExpandEnvironmentStringsW(wvalue, zbuf, 0); + if (size) { + apr_wchar_t *tmp = wvalue; + /* The size returned by ExpandEnvironmentStringsW is wchars */ + wvalue = apr_palloc(pool, size * 2); + size = ExpandEnvironmentStringsW(tmp, wvalue, (DWORD)size); + } + } + else { + /* count wchars from RegQueryValueExW, rather than bytes */ + size /= 2; + } + /* ###: deliberately overallocate all but the trailing null. + * We could precalculate the exact buffer here instead, the question + * is a matter of storage v.s. cpu cycles. + */ + valuelen = (size - 1) * 3 + 1; + *result = apr_palloc(pool, valuelen); + rv = apr_conv_ucs2_to_utf8(wvalue, &size, *result, &valuelen); + if (rv != APR_SUCCESS) + return rv; + else if (size) + return APR_ENAMETOOLONG; + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + /* Read to NULL buffer to determine value size */ + rc = RegQueryValueEx(key->hkey, valuename, 0, &type, NULL, (DWORD *)&size); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + + if ((size < 1) || (type != REG_SZ && type != REG_EXPAND_SZ)) { + return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER); + } + + *result = apr_palloc(pool, size); + /* Read value based on size query above */ + rc = RegQueryValueEx(key->hkey, valuename, 0, &type, *result, (DWORD *)&size); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + + if (type == REG_EXPAND_SZ) { + /* Advise ExpandEnvironmentStrings that we have a zero char + * buffer to force computation of the required length. + */ + char zbuf[1]; + size = ExpandEnvironmentStrings(*result, zbuf, 0); + if (size) { + char *tmp = *result; + *result = apr_palloc(pool, size); + size = ExpandEnvironmentStrings(tmp, *result, (DWORD)size); + } + } + } +#endif + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key, + const char *valuename, + const char *value, + apr_int32_t flags, + apr_pool_t *pool) +{ + /* Retrieve a registry string value, and explode any envvars + * that the system has configured (e.g. %SystemRoot%/someapp.exe) + */ + LONG rc; + apr_size_t size = strlen(value) + 1; + DWORD type = (flags & AP_REGKEY_EXPAND) ? REG_EXPAND_SZ : REG_SZ; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t alloclen; + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t wvalname[256]; + apr_wchar_t *wvalue; + apr_status_t rv; + rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (valuelen) + return APR_ENAMETOOLONG; + + wvallen = alloclen = size; + wvalue = apr_palloc(pool, alloclen * 2); + rv = apr_conv_utf8_to_ucs2(value, &size, wvalue, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (size) + return APR_ENAMETOOLONG; + + /* The size is the number of wchars consumed by apr_conv_utf8_to_ucs2 + * converted to bytes; the trailing L'\0' continues to be counted. + */ + size = (alloclen - wvallen) * 2; + rc = RegSetValueExW(key->hkey, wvalname, 0, type, + (LPBYTE)wvalue, (DWORD)size); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + rc = RegSetValueEx(key->hkey, valuename, 0, type, value, (DWORD)size); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + } +#endif + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result, + apr_size_t *resultsize, + apr_int32_t *resulttype, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool) +{ + /* Retrieve a registry string value, and explode any envvars + * that the system has configured (e.g. %SystemRoot%/someapp.exe) + */ + LONG rc; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t wvalname[256]; + apr_status_t rv; + rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (valuelen) + return APR_ENAMETOOLONG; + /* Read to NULL buffer to determine value size */ + rc = RegQueryValueExW(key->hkey, wvalname, 0, resulttype, + NULL, (LPDWORD)resultsize); + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + + /* Read value based on size query above */ + *result = apr_palloc(pool, *resultsize); + rc = RegQueryValueExW(key->hkey, wvalname, 0, resulttype, + (LPBYTE)*result, (LPDWORD)resultsize); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + /* Read to NULL buffer to determine value size */ + rc = RegQueryValueEx(key->hkey, valuename, 0, resulttype, + NULL, (LPDWORD)resultsize); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + + /* Read value based on size query above */ + *result = apr_palloc(pool, *resultsize); + rc = RegQueryValueEx(key->hkey, valuename, 0, resulttype, + (LPBYTE)*result, (LPDWORD)resultsize); + if (rc != ERROR_SUCCESS) + return APR_FROM_OS_ERROR(rc); + } +#endif + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key, + const char *valuename, + const void *value, + apr_size_t valuesize, + apr_int32_t valuetype, + apr_pool_t *pool) +{ + LONG rc; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t wvalname[256]; + apr_status_t rv; + rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (valuelen) + return APR_ENAMETOOLONG; + + rc = RegSetValueExW(key->hkey, wvalname, 0, valuetype, + (LPBYTE)value, (DWORD)valuesize); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + rc = RegSetValueEx(key->hkey, valuename, 0, valuetype, + (LPBYTE)value, (DWORD)valuesize); + } +#endif + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result, + ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool) +{ + /* Retrieve a registry string value, and explode any envvars + * that the system has configured (e.g. %SystemRoot%/someapp.exe) + */ + apr_status_t rv; + void *value; + char *buf; + char *tmp; + DWORD type; + apr_size_t size = 0; + + rv = ap_regkey_value_raw_get(&value, &size, &type, key, valuename, pool); + if (rv != APR_SUCCESS) { + return rv; + } + else if (type != REG_MULTI_SZ) { + return APR_EINVAL; + } + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t alloclen; + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t *wvalue = (apr_wchar_t *)value; + + /* ###: deliberately overallocate plus two extra nulls. + * We could precalculate the exact buffer here instead, the question + * is a matter of storage v.s. cpu cycles. + */ + size /= 2; + alloclen = valuelen = size * 3 + 2; + buf = apr_palloc(pool, valuelen); + rv = apr_conv_ucs2_to_utf8(value, &size, buf, &valuelen); + if (rv != APR_SUCCESS) + return rv; + else if (size) + return APR_ENAMETOOLONG; + buf[(alloclen - valuelen)] = '\0'; + buf[(alloclen - valuelen) + 1] = '\0'; + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + /* Small possiblity the array is either unterminated + * or single NULL terminated. Avert. + */ + buf = (char *)value; + if (size < 2 || buf[size - 1] != '\0' || buf[size - 2] != '\0') { + buf = apr_palloc(pool, size + 2); + memcpy(buf, value, size); + buf[size + 1] = '\0'; + buf[size] = '\0'; + } + } +#endif + + size = 0; /* Element Count */ + for (tmp = buf; *tmp; ++tmp) { + ++size; + while (*tmp) { + ++tmp; + } + } + + *result = apr_array_make(pool, (int)size, sizeof(char *)); + for (tmp = buf; *tmp; ++tmp) { + char **newelem = (char **) apr_array_push(*result); + *newelem = tmp; + while (*tmp) { + ++tmp; + } + } + + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key, + const char *valuename, + int nelts, + const char * const * elts, + apr_pool_t *pool) +{ + /* Retrieve a registry string value, and explode any envvars + * that the system has configured (e.g. %SystemRoot%/someapp.exe) + */ + int i; + const void *value; + apr_size_t bufsize; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_status_t rv; + apr_wchar_t *buf; + apr_wchar_t *tmp; + apr_size_t bufrem; + + bufsize = 1; /* For trailing second null */ + for (i = 0; i < nelts; ++i) { + bufsize += strlen(elts[i]) + 1; + } + if (!nelts) { + ++bufsize; + } + + bufrem = bufsize; + buf = apr_palloc(pool, bufsize * 2); + tmp = buf; + for (i = 0; i < nelts; ++i) { + apr_size_t eltsize = strlen(elts[i]) + 1; + apr_size_t size = eltsize; + rv = apr_conv_utf8_to_ucs2(elts[i], &size, tmp, &bufrem); + if (rv != APR_SUCCESS) + return rv; + else if (size) + return APR_ENAMETOOLONG; + tmp += eltsize; + } + if (!nelts) { + --bufrem; + (*tmp++) = L'\0'; + } + --bufrem; + *tmp = L'\0'; /* Trailing second null */ + + bufsize = (bufsize - bufrem) * 2; + value = (void*)buf; + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + char *buf; + char *tmp; + + bufsize = 1; /* For trailing second null */ + for (i = 0; i < nelts; ++i) { + bufsize += strlen(elts[i]) + 1; + } + if (!nelts) { + ++bufsize; + } + buf = apr_palloc(pool, bufsize); + tmp = buf; + for (i = 0; i < nelts; ++i) { + apr_size_t len = strlen(elts[i]) + 1; + memcpy(tmp, elts[i], len); + tmp += len; + } + if (!nelts) { + (*tmp++) = '\0'; + } + *tmp = '\0'; /* Trailing second null */ + value = buf; + } +#endif + return ap_regkey_value_raw_set(key, valuename, value, + bufsize, REG_MULTI_SZ, pool); +} + + +AP_DECLARE(apr_status_t) ap_regkey_value_remove(const ap_regkey_t *key, + const char *valuename, + apr_pool_t *pool) +{ + LONG rc; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t valuelen = strlen(valuename) + 1; + apr_size_t wvallen = 256; + apr_wchar_t wvalname[256]; + apr_status_t rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen); + if (rv != APR_SUCCESS) + return rv; + else if (valuelen) + return APR_ENAMETOOLONG; + rc = RegDeleteValueW(key->hkey, wvalname); + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + rc = RegDeleteValue(key->hkey, valuename); + } +#endif + if (rc != ERROR_SUCCESS) { + return APR_FROM_OS_ERROR(rc); + } + return APR_SUCCESS; +} + +#endif /* defined WIN32 */ diff --git a/trunk/os/win32/modules.c b/trunk/os/win32/modules.c new file mode 100644 index 0000000000..ba5f889aab --- /dev/null +++ b/trunk/os/win32/modules.c @@ -0,0 +1,57 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* modules.c --- major modules compiled into Apache for Win32. + * Only insert an entry for a module if it must be compiled into + * the core server + */ + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_config.h" + +extern module core_module; +extern module win32_module; +extern module mpm_winnt_module; +extern module http_module; +extern module so_module; + +AP_DECLARE_DATA module *ap_prelinked_modules[] = { + &core_module, + &win32_module, + &mpm_winnt_module, + &http_module, + &so_module, + NULL +}; + +ap_module_symbol_t ap_prelinked_module_symbols[] = { + {"core_module", &core_module}, + {"win32_module", &win32_module}, + {"mpm_winnt_module", &mpm_winnt_module}, + {"http_module", &http_module}, + {"so_module", &so_module}, + {NULL, NULL} +}; + +AP_DECLARE_DATA module *ap_preloaded_modules[] = { + &core_module, + &win32_module, + &mpm_winnt_module, + &http_module, + &so_module, + NULL +}; diff --git a/trunk/os/win32/os.h b/trunk/os/win32/os.h new file mode 100644 index 0000000000..b6e625d53b --- /dev/null +++ b/trunk/os/win32/os.h @@ -0,0 +1,123 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +#ifndef AP_OS_H +#define AP_OS_H +/* Delegate windows include to the apr.h header, if USER or GDI declarations + * are required (for a window rather than console application), include + * windows.h prior to any other Apache header files. + */ +#include "apr_pools.h" + +#include +#include + +#define PLATFORM "Win32" + +/* going away shortly... */ +#define HAVE_DRIVE_LETTERS +#define HAVE_UNC_PATHS +#define CASE_BLIND_FILESYSTEM + +#define APACHE_MPM_DIR "server/mpm/winnt" /* generated on unix */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* BIG RED WARNING: exit() is mapped to allow us to capture the exit + * status. This header must only be included from modules linked into + * the ApacheCore.dll - since it's a horrible behavior to exit() from + * any module outside the main() block, and we -will- assume it's a + * fatal error. + */ + +AP_DECLARE_DATA extern int ap_real_exit_code; + +#define exit(status) ((exit)((ap_real_exit_code==2) \ + ? (ap_real_exit_code = (status)) \ + : ((ap_real_exit_code = 0), (status)))) + +#ifdef AP_DECLARE_EXPORT + +/* Defined in util_win32.c and available only to the core module for + * win32 MPM design. + */ + +AP_DECLARE(apr_status_t) ap_os_proc_filepath(char **binpath, apr_pool_t *p); + +typedef enum { + AP_DLL_WINBASEAPI = 0, // kernel32 From WinBase.h + AP_DLL_WINADVAPI = 1, // advapi32 From WinBase.h + AP_DLL_WINSOCKAPI = 2, // mswsock From WinSock.h + AP_DLL_WINSOCK2API = 3, // ws2_32 From WinSock2.h + AP_DLL_defined = 4 // must define as last idx_ + 1 +} ap_dlltoken_e; + +FARPROC ap_load_dll_func(ap_dlltoken_e fnLib, char* fnName, int ordinal); + +PSECURITY_ATTRIBUTES GetNullACL(); +void CleanNullACL(void *sa); + +DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, + DWORD dwSeconds); + +int set_listeners_noninheritable(apr_pool_t *p); + + +#define AP_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \ + typedef rettype (calltype *ap_winapi_fpt_##fn) args; \ + static ap_winapi_fpt_##fn ap_winapi_pfn_##fn = NULL; \ + __inline rettype ap_winapi_##fn args \ + { if (!ap_winapi_pfn_##fn) \ + ap_winapi_pfn_##fn = (ap_winapi_fpt_##fn) ap_load_dll_func(lib, #fn, ord); \ + return (*(ap_winapi_pfn_##fn)) names; }; \ + +/* Win2K kernel only */ +AP_DECLARE_LATE_DLL_FUNC(AP_DLL_WINADVAPI, BOOL, WINAPI, ChangeServiceConfig2A, 0, ( + SC_HANDLE hService, + DWORD dwInfoLevel, + LPVOID lpInfo), + (hService, dwInfoLevel, lpInfo)); +#undef ChangeServiceConfig2 +#define ChangeServiceConfig2 ap_winapi_ChangeServiceConfig2A + +/* WinNT kernel only */ +AP_DECLARE_LATE_DLL_FUNC(AP_DLL_WINBASEAPI, BOOL, WINAPI, CancelIo, 0, ( + IN HANDLE hFile), + (hFile)); +#undef CancelIo +#define CancelIo ap_winapi_CancelIo + +/* Win9x kernel only */ +AP_DECLARE_LATE_DLL_FUNC(AP_DLL_WINBASEAPI, DWORD, WINAPI, RegisterServiceProcess, 0, ( + DWORD dwProcessId, + DWORD dwType), + (dwProcessId, dwType)); +#define RegisterServiceProcess ap_winapi_RegisterServiceProcess + +#endif /* def AP_DECLARE_EXPORT */ + +#ifdef __cplusplus +} +#endif + +#endif /* ndef AP_OS_H */ +#endif /* def WIN32 */ diff --git a/trunk/os/win32/util_win32.c b/trunk/os/win32/util_win32.c new file mode 100644 index 0000000000..36d99d6bc7 --- /dev/null +++ b/trunk/os/win32/util_win32.c @@ -0,0 +1,186 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_strings.h" +#include "arch/win32/apr_arch_file_io.h" +#include "arch/win32/apr_arch_misc.h" + +#include "httpd.h" +#include "http_log.h" + +#include +#include +#include + + +AP_DECLARE(apr_status_t) ap_os_proc_filepath(char **binpath, apr_pool_t *p) +{ + apr_wchar_t wbinpath[APR_PATH_MAX]; + +#if APR_HAS_UNICODE_FS + IF_WIN_OS_IS_UNICODE + { + apr_size_t binlen; + apr_size_t wbinlen; + apr_status_t rv; + if (!GetModuleFileNameW(NULL, wbinpath, sizeof(wbinpath) + / sizeof(apr_wchar_t))) { + return apr_get_os_error(); + } + wbinlen = wcslen(wbinpath) + 1; + binlen = (wbinlen - 1) * 3 + 1; + *binpath = apr_palloc(p, binlen); + rv = apr_conv_ucs2_to_utf8(wbinpath, &wbinlen, *binpath, &binlen); + if (rv != APR_SUCCESS) + return rv; + else if (wbinlen) + return APR_ENAMETOOLONG; + } +#endif /* APR_HAS_UNICODE_FS */ +#if APR_HAS_ANSI_FS + ELSE_WIN_OS_IS_ANSI + { + /* share the same scratch buffer */ + char *pathbuf = (char*) wbinpath; + if (!GetModuleFileName(NULL, pathbuf, sizeof(wbinpath))) { + return apr_get_os_error(); + } + *binpath = apr_pstrdup(p, pathbuf); + } +#endif + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_os_create_privileged_process( + const request_rec *r, + apr_proc_t *newproc, const char *progname, + const char * const *args, + const char * const *env, + apr_procattr_t *attr, apr_pool_t *p) +{ + return apr_proc_create(newproc, progname, args, env, attr, p); +} + + +/* This code is stolen from misc/win32/misc.c and apr_private.h + * This helper code resolves late bound entry points + * missing from one or more releases of the Win32 API... + * but it sure would be nice if we didn't duplicate this code + * from the APR ;-) + */ +static const char* const lateDllName[DLL_defined] = { + "kernel32", "advapi32", "mswsock", "ws2_32" }; +static HMODULE lateDllHandle[DLL_defined] = { + NULL, NULL, NULL, NULL }; + + +FARPROC ap_load_dll_func(ap_dlltoken_e fnLib, char* fnName, int ordinal) +{ + if (!lateDllHandle[fnLib]) { + lateDllHandle[fnLib] = LoadLibrary(lateDllName[fnLib]); + if (!lateDllHandle[fnLib]) + return NULL; + } + if (ordinal) + return GetProcAddress(lateDllHandle[fnLib], (char *) ordinal); + else + return GetProcAddress(lateDllHandle[fnLib], fnName); +} + + +/* To share the semaphores with other processes, we need a NULL ACL + * Code from MS KB Q106387 + */ +PSECURITY_ATTRIBUTES GetNullACL() +{ + PSECURITY_DESCRIPTOR pSD; + PSECURITY_ATTRIBUTES sa; + + sa = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)); + sa->nLength = sizeof(sizeof(SECURITY_ATTRIBUTES)); + + pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + sa->lpSecurityDescriptor = pSD; + + if (pSD == NULL || sa == NULL) { + return NULL; + } + apr_set_os_error(0); + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) + || apr_get_os_error()) { + LocalFree( pSD ); + LocalFree( sa ); + return NULL; + } + if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE) + || apr_get_os_error()) { + LocalFree( pSD ); + LocalFree( sa ); + return NULL; + } + + sa->bInheritHandle = FALSE; + return sa; +} + + +void CleanNullACL(void *sa) +{ + if (sa) { + LocalFree(((PSECURITY_ATTRIBUTES)sa)->lpSecurityDescriptor); + LocalFree(sa); + } +} + + +/* + * The Win32 call WaitForMultipleObjects will only allow you to wait for + * a maximum of MAXIMUM_WAIT_OBJECTS (current 64). Since the threading + * model in the multithreaded version of apache wants to use this call, + * we are restricted to a maximum of 64 threads. This is a simplistic + * routine that will increase this size. + */ +DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, + DWORD dwSeconds) +{ + time_t tStopTime; + DWORD dwRet = WAIT_TIMEOUT; + DWORD dwIndex=0; + BOOL bFirst = TRUE; + + tStopTime = time(NULL) + dwSeconds; + + do { + if (!bFirst) + Sleep(1000); + else + bFirst = FALSE; + + for (dwIndex = 0; dwIndex * MAXIMUM_WAIT_OBJECTS < nCount; dwIndex++) { + dwRet = WaitForMultipleObjects( + min(MAXIMUM_WAIT_OBJECTS, nCount - (dwIndex * MAXIMUM_WAIT_OBJECTS)), + lpHandles + (dwIndex * MAXIMUM_WAIT_OBJECTS), + 0, 0); + + if (dwRet != WAIT_TIMEOUT) { + break; + } + } + } while((time(NULL) < tStopTime) && (dwRet == WAIT_TIMEOUT)); + + return dwRet; +} diff --git a/trunk/server/.indent.pro b/trunk/server/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/server/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/server/Makefile.in b/trunk/server/Makefile.in new file mode 100644 index 0000000000..8efcb419d4 --- /dev/null +++ b/trunk/server/Makefile.in @@ -0,0 +1,86 @@ + +CLEAN_TARGETS = gen_test_char test_char.h gen_uri_delims uri_delims.h \ + ApacheCoreOS2.def httpd.exp export_files \ + exports.c export_vars.h + +SUBDIRS = mpm + +LTLIBRARY_NAME = libmain.la +LTLIBRARY_SOURCES = \ + test_char.h \ + config.c log.c main.c vhost.c util.c \ + util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \ + connection.c listen.c \ + mpm_common.c util_charset.c util_debug.c util_xml.c \ + util_filter.c util_pcre.c exports.c \ + scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \ + eoc_bucket.c core_filters.c + +TARGETS = delete-exports $(LTLIBRARY_NAME) $(CORE_IMPLIB_FILE) export_vars.h httpd.exp + +include $(top_builddir)/build/rules.mk +include $(top_srcdir)/build/library.mk + +gen_test_char_OBJECTS = gen_test_char.lo util_debug.lo +gen_test_char: $(gen_test_char_OBJECTS) + $(LINK) $(EXTRA_LDFLAGS) $(gen_test_char_OBJECTS) $(EXTRA_LIBS) + +test_char.h: gen_test_char + ./gen_test_char > test_char.h + +util.lo: test_char.h + +EXPORT_DIRS = $(top_srcdir)/include $(top_srcdir)/os/$(OS_DIR) $(top_srcdir)/modules/http +EXPORT_DIRS_APR = $(APR_INCLUDEDIR) $(APU_INCLUDEDIR) + +# If export_files is a dependency here, but we remove it during this stage, +# when exports.c is generated, make will not detect that export_files is no +# longer here and deadlock. So, export_files can't be a dependency of +# delete-exports. +delete-exports: + @if test -f exports.c; then \ + if test -f export_files; then \ + files=`cat export_files`; \ + headers="`find $$files -newer exports.c`"; \ + if test -n "$$headers"; then \ + echo Found newer headers. Will rebuild exports.c.; \ + echo rm -f exports.c export_files; \ + rm -f exports.c export_files; \ + fi; \ + else \ + rm -f exports.c; \ + fi; \ + fi + +export_files: + tmp=export_files_unsorted.txt; \ + rm -f $$tmp && touch $$tmp; \ + for dir in $(EXPORT_DIRS); do \ + ls $$dir/*.h >> $$tmp; \ + done; \ + for dir in $(EXPORT_DIRS_APR); do \ + ls $$dir/ap[ru].h >> $$tmp; \ + ls $$dir/ap[ru]_*.h >> $$tmp; \ + done; \ + sort -u $$tmp > $@; \ + rm -f $$tmp + +exports.c: export_files + $(AWK) -f $(top_srcdir)/build/make_exports.awk `cat $?` > $@ + +export_vars.h: export_files + $(AWK) -f $(top_srcdir)/build/make_var_export.awk `cat $?` > $@ + +# Rule to make def file for OS/2 core dll +ApacheCoreOS2.def: exports.c export_vars.h $(top_srcdir)/os/$(OS_DIR)/core_header.def + cat $(top_srcdir)/os/$(OS_DIR)/core_header.def > $@ + $(CPP) $< $(ALL_CPPFLAGS) $(ALL_INCLUDES) | grep "ap_hack_" | sed -e 's/^.*[)]\(.*\);$$/ "\1"/' >> $@ + $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep "^[a-z]" | sed -e 's/^\(.*\)$$/ "\1"/' >> $@ + +# Rule to make exp file for AIX DSOs +httpd.exp: exports.c export_vars.h + @echo "#! ." > $@ + @echo "* This file was AUTOGENERATED at build time." >> $@ + @echo "* Please do not edit by hand." >> $@ + $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) exports.c | grep "ap_hack_" | grep -v apr_ | sed -e 's/^.*[)]\(.*\);$$/\1/' >> $@ + $(CPP) $(ALL_CPPFLAGS) $(ALL_INCLUDES) export_vars.h | grep -v apr_ | sed -e 's/^\#[^!]*//' | sed -e '/^$$/d' >> $@ diff --git a/trunk/server/NWGNUmakefile b/trunk/server/NWGNUmakefile new file mode 100644 index 0000000000..f2f6da75f7 --- /dev/null +++ b/trunk/server/NWGNUmakefile @@ -0,0 +1,251 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + ../build \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(AP_WORK)/include \ + $(APRUTIL)/include \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = genchars + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Generate Test Characters + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = genchars + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\NWGNUNetWare.rul +# +NLM_VERSION = 1,0,0 + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM =_LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM =_LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ +$(OBJDIR)/genchars.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/gen_test_char.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/server/buildmark.c b/trunk/server/buildmark.c new file mode 100644 index 0000000000..ba727e4aba --- /dev/null +++ b/trunk/server/buildmark.c @@ -0,0 +1,29 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" +#include "httpd.h" + +#if defined(__DATE__) && defined(__TIME__) +static const char server_built[] = __DATE__ " " __TIME__; +#else +static const char server_built[] = "unknown"; +#endif + +AP_DECLARE(const char *) ap_get_server_built() +{ + return server_built; +} diff --git a/trunk/server/config.c b/trunk/server/config.c new file mode 100644 index 0000000000..e44674f9bf --- /dev/null +++ b/trunk/server/config.c @@ -0,0 +1,2166 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_config.c: once was auxillary functions for reading httpd's config + * file and converting filenames into a namespace + * + * Rob McCool + * + * Wall-to-wall rewrite for Apache... commands which are part of the + * server core can now be found next door in "http_core.c". Now contains + * general command loop, and functions which do bookkeeping for the new + * Apache config stuff (modules and configuration vectors). + * + * rst + * + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_file_io.h" +#include "apr_fnmatch.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "http_core.h" +#include "http_log.h" /* for errors in parse_htaccess */ +#include "http_request.h" /* for default_handler (see invoke_handler) */ +#include "http_main.h" +#include "http_vhost.h" +#include "util_cfgtree.h" +#include "mpm.h" + + +AP_DECLARE_DATA const char *ap_server_argv0 = NULL; + +AP_DECLARE_DATA const char *ap_server_root = NULL; + +AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL; +AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL; +AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL; + +AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL; + +APR_HOOK_STRUCT( + APR_HOOK_LINK(header_parser) + APR_HOOK_LINK(pre_config) + APR_HOOK_LINK(post_config) + APR_HOOK_LINK(open_logs) + APR_HOOK_LINK(child_init) + APR_HOOK_LINK(handler) + APR_HOOK_LINK(quick_handler) + APR_HOOK_LINK(optional_fn_retrieve) + APR_HOOK_LINK(test_config) +) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser, + (request_rec *r), (r), OK, DECLINED) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config, + (apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp), + (pconf, plog, ptemp), OK, DECLINED) + +AP_IMPLEMENT_HOOK_VOID(test_config, + (apr_pool_t *pconf, server_rec *s), + (pconf, s)) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config, + (apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s), + (pconf, plog, ptemp, s), OK, DECLINED) + +/* During the course of debugging I expanded this macro out, so + * rather than remove all the useful information there is in the + * following lines, I'm going to leave it here in case anyone + * else finds it useful. + * + * Ben has looked at it and thinks it correct :) + * +AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf, + const char * const *aszPre, + const char * const *aszSucc, + int nOrder) +{ + ap_LINK_post_config_t *pHook; + + if (!_hooks.link_post_config) { + _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1, + sizeof(ap_LINK_post_config_t)); + apr_hook_sort_register("post_config", &_hooks.link_post_config); + } + + pHook = apr_array_push(_hooks.link_post_config); + pHook->pFunc = pf; + pHook->aszPredecessors = aszPre; + pHook->aszSuccessors = aszSucc; + pHook->nOrder = nOrder; + pHook->szName = apr_hook_debug_current; + + if (apr_hook_debug_enabled) + apr_hook_debug_show("post_config", aszPre, aszSucc); +} + +AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void) { + return _hooks.link_post_config; +} + +AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf, + apr_pool_t *plog, + apr_pool_t *ptemp, + server_rec *s) +{ + ap_LINK_post_config_t *pHook; + int n; + + if(!_hooks.link_post_config) + return; + + pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts; + for (n = 0; n < _hooks.link_post_config->nelts; ++n) + pHook[n].pFunc (pconf, plog, ptemp, s); +} + */ + +AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs, + (apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s), + (pconf, plog, ptemp, s), OK, DECLINED) + +AP_IMPLEMENT_HOOK_VOID(child_init, + (apr_pool_t *pchild, server_rec *s), + (pchild, s)) + +AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r), + (r), DECLINED) + +AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup), + (r, lookup), DECLINED) + +AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ()) + +/**************************************************************** + * + * We begin with the functions which deal with the linked list + * of modules which control just about all of the server operation. + */ + +/* total_modules is the number of modules that have been linked + * into the server. + */ +static int total_modules = 0; + +/* dynamic_modules is the number of modules that have been added + * after the pre-loaded ones have been set up. It shouldn't be larger + * than DYNAMIC_MODULE_LIMIT. + */ +static int dynamic_modules = 0; + +AP_DECLARE_DATA module *ap_top_module = NULL; +AP_DECLARE_DATA module **ap_loaded_modules=NULL; + +static apr_hash_t *ap_config_hash = NULL; + +typedef int (*handler_func)(request_rec *); +typedef void *(*dir_maker_func)(apr_pool_t *, char *); +typedef void *(*merger_func)(apr_pool_t *, void *, void *); + +/* maximum nesting level for config directories */ +#ifndef AP_MAX_INCLUDE_DIR_DEPTH +#define AP_MAX_INCLUDE_DIR_DEPTH (128) +#endif + +/* Dealing with config vectors. These are associated with per-directory, + * per-server, and per-request configuration, and have a void* pointer for + * each modules. The nature of the structure pointed to is private to the + * module in question... the core doesn't (and can't) know. However, there + * are defined interfaces which allow it to create instances of its private + * per-directory and per-server structures, and to merge the per-directory + * structures of a directory and its subdirectory (producing a new one in + * which the defaults applying to the base directory have been properly + * overridden). + */ + +static ap_conf_vector_t *create_empty_config(apr_pool_t *p) +{ + void *conf_vector = apr_pcalloc(p, sizeof(void *) * + (total_modules + DYNAMIC_MODULE_LIMIT)); + return conf_vector; +} + +static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p) +{ + void **conf_vector = apr_pcalloc(p, sizeof(void *) * + (total_modules + DYNAMIC_MODULE_LIMIT)); + module *modp; + + for (modp = ap_top_module; modp; modp = modp->next) { + dir_maker_func df = modp->create_dir_config; + + if (df) + conf_vector[modp->module_index] = (*df)(p, NULL); + } + + return (ap_conf_vector_t *)conf_vector; +} + +AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p, + ap_conf_vector_t *base, + ap_conf_vector_t *new_conf) +{ + void **conf_vector = apr_palloc(p, sizeof(void *) * total_modules); + void **base_vector = (void **)base; + void **new_vector = (void **)new_conf; + module *modp; + + for (modp = ap_top_module; modp; modp = modp->next) { + int i = modp->module_index; + + if (!new_vector[i]) { + conf_vector[i] = base_vector[i]; + } + else { + merger_func df = modp->merge_dir_config; + if (df && base_vector[i]) { + conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]); + } + else + conf_vector[i] = new_vector[i]; + } + } + + return (ap_conf_vector_t *)conf_vector; +} + +static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s) +{ + void **conf_vector = apr_pcalloc(p, sizeof(void *) * + (total_modules + DYNAMIC_MODULE_LIMIT)); + module *modp; + + for (modp = ap_top_module; modp; modp = modp->next) { + if (modp->create_server_config) + conf_vector[modp->module_index] = (*modp->create_server_config)(p, s); + } + + return (ap_conf_vector_t *)conf_vector; +} + +static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base, + ap_conf_vector_t *virt) +{ + /* Can reuse the 'virt' vector for the spine of it, since we don't + * have to deal with the moral equivalent of .htaccess files here... + */ + + void **base_vector = (void **)base; + void **virt_vector = (void **)virt; + module *modp; + + for (modp = ap_top_module; modp; modp = modp->next) { + merger_func df = modp->merge_server_config; + int i = modp->module_index; + + if (!virt_vector[i]) + virt_vector[i] = base_vector[i]; + else if (df) + virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]); + } +} + +AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p) +{ + return create_empty_config(p); +} + +AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p) +{ + return create_empty_config(p); +} + +AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p) +{ + return create_empty_config(p); +} + +static int ap_invoke_filter_init(ap_filter_t *filters) +{ + while (filters) { + if (filters->frec->filter_init_func) { + int result = filters->frec->filter_init_func(filters); + if (result != OK) { + return result; + } + } + filters = filters->next; + } + return OK; +} + +AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) +{ + const char *handler; + const char *p; + int result; + const char *old_handler = r->handler; + + /* + * The new insert_filter stage makes the most sense here. We only use + * it when we are going to run the request, so we must insert filters + * if any are available. Since the goal of this phase is to allow all + * modules to insert a filter if they want to, this filter returns + * void. I just can't see any way that this filter can reasonably + * fail, either your modules inserts something or it doesn't. rbb + */ + ap_run_insert_filter(r); + + /* Before continuing, allow each filter that is in the two chains to + * run their init function to let them do any magic before we could + * start generating data. + */ + result = ap_invoke_filter_init(r->input_filters); + if (result != OK) { + return result; + } + result = ap_invoke_filter_init(r->output_filters); + if (result != OK) { + return result; + } + + if (!r->handler) { + handler = r->content_type ? r->content_type : ap_default_type(r); + if ((p=ap_strchr_c(handler, ';')) != NULL) { + char *new_handler = (char *)apr_pmemdup(r->pool, handler, + p - handler + 1); + char *p2 = new_handler + (p - handler); + handler = new_handler; + + /* MIME type arguments */ + while (p2 > handler && p2[-1] == ' ') + --p2; /* strip trailing spaces */ + + *p2='\0'; + } + + r->handler = handler; + } + + result = ap_run_handler(r); + + r->handler = old_handler; + + if (result == DECLINED && r->handler && r->filename) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "handler \"%s\" not found for: %s", r->handler, r->filename); + } + + return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result; +} + +AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method) +{ + int methnum; + + methnum = ap_method_number_of(method); + + /* + * A method number either hardcoded into apache or + * added by a module and registered. + */ + if (methnum != M_INVALID) { + return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0; + } + + return 0; /* not found */ +} + +AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p) +{ + if (m->register_hooks) { + if (getenv("SHOW_HOOKS")) { + printf("Registering hooks for %s\n", m->name); + apr_hook_debug_enabled = 1; + } + + apr_hook_debug_current = m->name; + m->register_hooks(p); + } +} + +static void ap_add_module_commands(module *m, apr_pool_t *p); + +typedef struct ap_mod_list_struct ap_mod_list; +struct ap_mod_list_struct { + struct ap_mod_list_struct *next; + module *m; + const command_rec *cmd; +}; + +static apr_status_t reload_conf_hash(void *baton) +{ + ap_config_hash = NULL; + return APR_SUCCESS; +} + +static void rebuild_conf_hash(apr_pool_t *p, int add_prelinked) +{ + module **m; + + ap_config_hash = apr_hash_make(p); + + apr_pool_cleanup_register(p, NULL, reload_conf_hash, + apr_pool_cleanup_null); + if (add_prelinked) { + for (m = ap_prelinked_modules; *m != NULL; m++) { + ap_add_module_commands(*m, p); + } + } +} + +static void ap_add_module_commands(module *m, apr_pool_t *p) +{ + apr_pool_t *tpool; + ap_mod_list *mln; + const command_rec *cmd; + char *dir; + + cmd = m->cmds; + + if (ap_config_hash == NULL) { + rebuild_conf_hash(p, 0); + } + + tpool = apr_hash_pool_get(ap_config_hash); + + while (cmd && cmd->name) { + mln = apr_palloc(tpool, sizeof(ap_mod_list)); + mln->cmd = cmd; + mln->m = m; + dir = apr_pstrdup(tpool, cmd->name); + + ap_str_tolower(dir); + + mln->next = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING); + apr_hash_set(ap_config_hash, dir, APR_HASH_KEY_STRING, mln); + ++cmd; + } +} + + +/* One-time setup for precompiled modules --- NOT to be done on restart */ + +AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p) +{ + /* This could be called from a LoadModule httpd.conf command, + * after the file has been linked and the module structure within it + * teased out... + */ + + if (m->version != MODULE_MAGIC_NUMBER_MAJOR) { + return apr_psprintf(p, "Module \"%s\" is not compatible with this " + "version of Apache (found %d, need %d). Please " + "contact the vendor for the correct version.", + m->name, m->version, MODULE_MAGIC_NUMBER_MAJOR); + } + + if (m->next == NULL) { + m->next = ap_top_module; + ap_top_module = m; + } + + if (m->module_index == -1) { + m->module_index = total_modules++; + dynamic_modules++; + + if (dynamic_modules > DYNAMIC_MODULE_LIMIT) { + return apr_psprintf(p, "Module \"%s\" could not be loaded, " + "because the dynamic module limit was " + "reached. Please increase " + "DYNAMIC_MODULE_LIMIT and recompile.", m->name); + } + } + + /* Some C compilers put a complete path into __FILE__, but we want + * only the filename (e.g. mod_includes.c). So check for path + * components (Unix and DOS), and remove them. + */ + + if (ap_strrchr_c(m->name, '/')) + m->name = 1 + ap_strrchr_c(m->name, '/'); + + if (ap_strrchr_c(m->name, '\\')) + m->name = 1 + ap_strrchr_c(m->name, '\\'); + +#ifdef _OSD_POSIX + /* __FILE__ = + * "*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" + */ + + /* We cannot fix the string in-place, because it's const */ + if (m->name[strlen(m->name)-1] == ')') { + char *tmp = strdup(m->name); /* FIXME: memory leak, albeit a small one */ + tmp[strlen(tmp)-1] = '\0'; + m->name = tmp; + } +#endif /*_OSD_POSIX*/ + + ap_add_module_commands(m, p); + /* FIXME: is this the right place to call this? + * It doesn't appear to be + */ + ap_register_hooks(m, p); + + return NULL; +} + +/* + * remove_module undoes what add_module did. There are some caveats: + * when the module is removed, its slot is lost so all the current + * per-dir and per-server configurations are invalid. So we should + * only ever call this function when you are invalidating almost + * all our current data. I.e. when doing a restart. + */ + +AP_DECLARE(void) ap_remove_module(module *m) +{ + module *modp; + + modp = ap_top_module; + if (modp == m) { + /* We are the top module, special case */ + ap_top_module = modp->next; + m->next = NULL; + } + else { + /* Not the top module, find use. When found modp will + * point to the module _before_ us in the list + */ + + while (modp && modp->next != m) { + modp = modp->next; + } + + if (!modp) { + /* Uh-oh, this module doesn't exist */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Cannot remove module %s: not found in module list", + m->name); + return; + } + + /* Eliminate us from the module list */ + modp->next = modp->next->next; + } + + m->module_index = -1; /* simulate being unloaded, should + * be unnecessary */ + dynamic_modules--; + total_modules--; +} + +AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p) +{ + module **m; + const char *error; + + /* + * Add module pointer to top of chained module list + */ + error = ap_add_module(mod, p); + if (error) { + return error; + } + + /* + * And module pointer to list of loaded modules + * + * Notes: 1. ap_add_module() would already complain if no more space + * exists for adding a dynamically loaded module + * 2. ap_add_module() accepts double inclusion, so we have + * to accept this, too. + */ + for (m = ap_loaded_modules; *m != NULL; m++) + ; + *m++ = mod; + *m = NULL; + + return NULL; +} + +AP_DECLARE(void) ap_remove_loaded_module(module *mod) +{ + module **m; + module **m2; + int done; + + /* + * Remove module pointer from chained module list + */ + ap_remove_module(mod); + + /* + * Remove module pointer from list of loaded modules + * + * Note: 1. We cannot determine if the module was successfully + * removed by ap_remove_module(). + * 2. We have not to complain explicity when the module + * is not found because ap_remove_module() did it + * for us already. + */ + for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) { + if (*m2 == mod && done == 0) + done = 1; + else + *m++ = *m2; + } + + *m = NULL; +} + +AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process) +{ + module **m; + module **m2; + const char *error; + + apr_hook_global_pool=process->pconf; + + rebuild_conf_hash(process->pconf, 0); + + /* + * Initialise total_modules variable and module indices + */ + total_modules = 0; + for (m = ap_preloaded_modules; *m != NULL; m++) + (*m)->module_index = total_modules++; + + /* + * Initialise list of loaded modules + */ + ap_loaded_modules = (module **)apr_palloc(process->pool, + sizeof(module *) * (total_modules + DYNAMIC_MODULE_LIMIT + 1)); + + if (ap_loaded_modules == NULL) { + return "Ouch! Out of memory in ap_setup_prelinked_modules()!"; + } + + for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; ) + *m2++ = *m++; + + *m2 = NULL; + + /* + * Initialize chain of linked (=activate) modules + */ + for (m = ap_prelinked_modules; *m != NULL; m++) { + error = ap_add_module(*m, process->pconf); + if (error) { + return error; + } + } + + apr_hook_sort_all(); + + return NULL; +} + +AP_DECLARE(const char *) ap_find_module_name(module *m) +{ + return m->name; +} + +AP_DECLARE(module *) ap_find_linked_module(const char *name) +{ + module *modp; + + for (modp = ap_top_module; modp; modp = modp->next) { + if (strcmp(modp->name, name) == 0) + return modp; + } + + return NULL; +} + +/***************************************************************** + * + * Resource, access, and .htaccess config files now parsed by a common + * command loop. + * + * Let's begin with the basics; parsing the line and + * invoking the function... + */ + +#define AP_MAX_ARGC 64 + +static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms, + void *mconfig, const char *args) +{ + char *w, *w2, *w3; + const char *errmsg = NULL; + + if ((parms->override & cmd->req_override) == 0) + return apr_pstrcat(parms->pool, cmd->name, " not allowed here", NULL); + + parms->info = cmd->cmd_data; + parms->cmd = cmd; + + switch (cmd->args_how) { + case RAW_ARGS: +#ifdef RESOLVE_ENV_PER_TOKEN + args = ap_resolve_env(parms->pool,args); +#endif + return cmd->AP_RAW_ARGS(parms, mconfig, args); + + case TAKE_ARGV: + { + char *argv[AP_MAX_ARGC]; + int argc = 0; + + do { + w = ap_getword_conf(parms->pool, &args); + if (*w == '\0' && *args == '\0') { + break; + } + argv[argc] = w; + argc++; + } while (argc < AP_MAX_ARGC && *args != '\0'); + + return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv); + } + + case NO_ARGS: + if (*args != 0) + return apr_pstrcat(parms->pool, cmd->name, " takes no arguments", + NULL); + + return cmd->AP_NO_ARGS(parms, mconfig); + + case TAKE1: + w = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, " takes one argument", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE1(parms, mconfig, w); + + case TAKE2: + w = ap_getword_conf(parms->pool, &args); + w2 = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || *w2 == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, " takes two arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE2(parms, mconfig, w, w2); + + case TAKE12: + w = ap_getword_conf(parms->pool, &args); + w2 = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL); + + case TAKE3: + w = ap_getword_conf(parms->pool, &args); + w2 = ap_getword_conf(parms->pool, &args); + w3 = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, " takes three arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); + + case TAKE23: + w = ap_getword_conf(parms->pool, &args); + w2 = ap_getword_conf(parms->pool, &args); + w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; + + if (*w == '\0' || *w2 == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, + " takes two or three arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); + + case TAKE123: + w = ap_getword_conf(parms->pool, &args); + w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL; + w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; + + if (*w == '\0' || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, + " takes one, two or three arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); + + case TAKE13: + w = ap_getword_conf(parms->pool, &args); + w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL; + w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL; + + if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0) + return apr_pstrcat(parms->pool, cmd->name, + " takes one or three arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return cmd->AP_TAKE3(parms, mconfig, w, w2, w3); + + case ITERATE: + while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') { + + errmsg = cmd->AP_TAKE1(parms, mconfig, w); + + if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0) + return errmsg; + } + + return errmsg; + + case ITERATE2: + w = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || *args == 0) + return apr_pstrcat(parms->pool, cmd->name, + " requires at least two arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') { + + errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2); + + if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0) + return errmsg; + } + + return errmsg; + + case FLAG: + w = ap_getword_conf(parms->pool, &args); + + if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off"))) + return apr_pstrcat(parms->pool, cmd->name, " must be On or Off", + NULL); + + return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0); + + default: + return apr_pstrcat(parms->pool, cmd->name, + " is improperly configured internally (server bug)", + NULL); + } +} + +AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name, + const command_rec *cmds) +{ + while (cmds->name) { + if (!strcasecmp(name, cmds->name)) + return cmds; + + ++cmds; + } + + return NULL; +} + +AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules( + const char *cmd_name, module **mod) +{ + const command_rec *cmdp; + module *modp; + + for (modp = *mod; modp; modp = modp->next) { + if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) { + *mod = modp; + return cmdp; + } + } + + return NULL; +} + +AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server, + ap_conf_vector_t *section_vector, + const char *section, + module *mod, apr_pool_t *pconf) +{ + void *section_config = ap_get_module_config(section_vector, mod); + void *server_config = ap_get_module_config(server->module_config, mod); + + if (!section_config && mod->create_dir_config) { + /* ### need to fix the create_dir_config functions' prototype... */ + section_config = (*mod->create_dir_config)(pconf, (char *)section); + ap_set_module_config(section_vector, mod, section_config); + } + + if (!server_config && mod->create_server_config) { + server_config = (*mod->create_server_config)(pconf, server); + ap_set_module_config(server->module_config, mod, server_config); + } + + return section_config; +} + +static const char *execute_now(char *cmd_line, const char *args, + cmd_parms *parms, + apr_pool_t *p, apr_pool_t *ptemp, + ap_directive_t **sub_tree, + ap_directive_t *parent); + +static const char *ap_build_config_sub(apr_pool_t *p, apr_pool_t *temp_pool, + const char *l, cmd_parms *parms, + ap_directive_t **current, + ap_directive_t **curr_parent, + ap_directive_t **conftree) +{ + const char *retval = NULL; + const char *args; + char *cmd_name; + ap_directive_t *newdir; + module *mod = ap_top_module; + const command_rec *cmd; + + if (*l == '#' || *l == '\0') + return NULL; + +#if RESOLVE_ENV_PER_TOKEN + args = l; +#else + args = ap_resolve_env(temp_pool, l); +#endif + + cmd_name = ap_getword_conf(p, &args); + if (*cmd_name == '\0') { + /* Note: this branch should not occur. An empty line should have + * triggered the exit further above. + */ + return NULL; + } + + if (cmd_name[1] != '/') { + char *lastc = cmd_name + strlen(cmd_name) - 1; + if (*lastc == '>') { + *lastc = '\0' ; + } + if (cmd_name[0] == '<' && *args == '\0') { + args = ">"; + } + } + + newdir = apr_pcalloc(p, sizeof(ap_directive_t)); + newdir->filename = parms->config_file->name; + newdir->line_num = parms->config_file->line_number; + newdir->directive = cmd_name; + newdir->args = apr_pstrdup(p, args); + + if ((cmd = ap_find_command_in_modules(cmd_name, &mod)) != NULL) { + if (cmd->req_override & EXEC_ON_READ) { + ap_directive_t *sub_tree = NULL; + + parms->err_directive = newdir; + retval = execute_now(cmd_name, args, parms, p, temp_pool, + &sub_tree, *curr_parent); + if (*current) { + (*current)->next = sub_tree; + } + else { + *current = sub_tree; + if (*curr_parent) { + (*curr_parent)->first_child = (*current); + } + if (*current) { + (*current)->parent = (*curr_parent); + } + } + if (*current) { + if (!*conftree) { + /* Before walking *current to the end of the list, + * set the head to *current. + */ + *conftree = *current; + } + while ((*current)->next != NULL) { + (*current) = (*current)->next; + (*current)->parent = (*curr_parent); + } + } + return retval; + } + } + + if (cmd_name[0] == '<') { + if (cmd_name[1] != '/') { + (*current) = ap_add_node(curr_parent, *current, newdir, 1); + } + else if (*curr_parent == NULL) { + parms->err_directive = newdir; + return apr_pstrcat(p, cmd_name, + " without matching <", cmd_name + 2, + " section", NULL); + } + else { + char *bracket = cmd_name + strlen(cmd_name) - 1; + + if (*bracket != '>') { + parms->err_directive = newdir; + return apr_pstrcat(p, cmd_name, + "> directive missing closing '>'", NULL); + } + + *bracket = '\0'; + + if (strcasecmp(cmd_name + 2, + (*curr_parent)->directive + 1) != 0) { + parms->err_directive = newdir; + return apr_pstrcat(p, "Expected directive + 1, "> but saw ", + cmd_name, ">", NULL); + } + + *bracket = '>'; + + /* done with this section; move up a level */ + *current = *curr_parent; + *curr_parent = (*current)->parent; + } + } + else { + *current = ap_add_node(curr_parent, *current, newdir, 0); + } + + return retval; +} + +AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p, + apr_pool_t *temp_pool, + cmd_parms *parms, + ap_directive_t **current, + ap_directive_t **curr_parent, + char *orig_directive) +{ + char *l; + char *bracket; + const char *retval; + ap_directive_t *sub_tree = NULL; + + /* Since this function can be called recursively, allocate + * the temporary 8k string buffer from the temp_pool rather + * than the stack to avoid over-running a fixed length stack. + */ + l = apr_palloc(temp_pool, MAX_STRING_LEN); + + bracket = apr_pstrcat(p, orig_directive + 1, ">", NULL); + while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { + if (!memcmp(l, "pool, current->directive); + + ap_str_tolower(dir); + + ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING); + + if (ml == NULL) { + parms->err_directive = current; + return apr_pstrcat(parms->pool, "Invalid command '", + current->directive, + "', perhaps misspelled or defined by a module " + "not included in the server configuration", + NULL); + } + + for ( ; ml != NULL; ml = ml->next) { + void *dir_config = ap_set_config_vectors(parms->server, + section_vector, + parms->path, + ml->m, + parms->pool); + const char *retval; + cmd = ml->cmd; + + /* Once was enough? */ + if (cmd->req_override & EXEC_ON_READ) { + continue; + } + + retval = invoke_cmd(cmd, parms, dir_config, current->args); + + if (retval != NULL && strcmp(retval, DECLINE_CMD) != 0) { + /* If the directive in error has already been set, don't + * replace it. Otherwise, an error inside a container + * will be reported as occuring on the first line of the + * container. + */ + if (!parms->err_directive) { + parms->err_directive = current; + } + return retval; + } + } + + return NULL; +} + +AP_DECLARE(const char *) ap_walk_config(ap_directive_t *current, + cmd_parms *parms, + ap_conf_vector_t *section_vector) +{ + ap_conf_vector_t *oldconfig = parms->context; + + parms->context = section_vector; + + /* scan through all directives, executing each one */ + for (; current != NULL; current = current->next) { + const char *errmsg; + + parms->directive = current; + + /* actually parse the command and execute the correct function */ + errmsg = ap_walk_config_sub(current, parms, section_vector); + if (errmsg != NULL) { + /* restore the context (just in case) */ + parms->context = oldconfig; + return errmsg; + } + } + + parms->context = oldconfig; + return NULL; +} + +AP_DECLARE(const char *) ap_build_config(cmd_parms *parms, + apr_pool_t *p, apr_pool_t *temp_pool, + ap_directive_t **conftree) +{ + ap_directive_t *current = *conftree; + ap_directive_t *curr_parent = NULL; + char *l = apr_palloc (temp_pool, MAX_STRING_LEN); + const char *errmsg; + + if (current != NULL) { + while (current->next) { + current = current->next; + } + } + + while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { + errmsg = ap_build_config_sub(p, temp_pool, l, parms, + ¤t, &curr_parent, conftree); + if (errmsg != NULL) + return errmsg; + + if (*conftree == NULL && curr_parent != NULL) { + *conftree = curr_parent; + } + + if (*conftree == NULL && current != NULL) { + *conftree = current; + } + } + + if (curr_parent != NULL) { + errmsg = ""; + + while (curr_parent != NULL) { + errmsg = apr_psprintf(p, "%s%s%s:%u: %s> was not closed.", + errmsg, + *errmsg == '\0' ? "" : APR_EOL_STR, + curr_parent->filename, + curr_parent->line_num, + curr_parent->directive); + + parms->err_directive = curr_parent; + curr_parent = curr_parent->parent; + } + + return errmsg; + } + + return NULL; +} + +/* + * Generic command functions... + */ + +AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, + void *struct_ptr, + const char *arg) +{ + int offset = (int)(long)cmd->info; + + *(const char **)((char *)struct_ptr + offset) = arg; + + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd, + void *struct_ptr, + const char *arg) +{ + char *endptr; + char *error_str = NULL; + int offset = (int)(long)cmd->info; + + *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10); + + if ((*arg == '\0') || (*endptr != '\0')) { + error_str = apr_psprintf(cmd->pool, + "Invalid value for directive %s, expected integer", + cmd->directive->directive); + } + + return error_str; +} + +AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd, + void *struct_ptr, + const char *arg_) +{ + char *arg = apr_pstrdup(cmd->pool,arg_); + int offset = (int)(long)cmd->info; + + ap_str_tolower(arg); + *(char **)((char *)struct_ptr + offset) = arg; + + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd, + void *struct_ptr_v, int arg) +{ + int offset = (int)(long)cmd->info; + char *struct_ptr = (char *)struct_ptr_v; + + *(int *)(struct_ptr + offset) = arg ? 1 : 0; + + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr, + const char *arg) +{ + /* Prepend server_root to relative arg. + * This allows most args to be independent of server_root, + * so the server can be moved or mirrored with less pain. + */ + const char *path; + int offset = (int)(long)cmd->info; + + path = ap_server_root_relative(cmd->pool, arg); + + if (!path) { + return apr_pstrcat(cmd->pool, "Invalid file path ", + arg, NULL); + } + + *(const char **) ((char*)struct_ptr + offset) = path; + + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd, + void *struct_ptr, + const char *arg) +{ + return cmd->cmd->errmsg; +} + +/***************************************************************** + * + * Reading whole config files... + */ + +static cmd_parms default_parms = +{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file) +{ + char *newpath = NULL; + apr_status_t rv; + rv = apr_filepath_merge(&newpath, ap_server_root, file, + APR_FILEPATH_TRUENAME, p); + if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv) + || APR_STATUS_IS_ENOENT(rv) + || APR_STATUS_IS_ENOTDIR(rv))) { + return newpath; + } + else { + return NULL; + } +} + +AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive) +{ + char l[MAX_STRING_LEN]; + const char *args; + char *cmd_name; + + while(!(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) { +#if RESOLVE_ENV_PER_TOKEN + args = l; +#else + args = ap_resolve_env(cmd->temp_pool, l); +#endif + + cmd_name = ap_getword_conf(cmd->pool, &args); + if (cmd_name[0] == '<') { + if (cmd_name[1] == '/') { + cmd_name[strlen(cmd_name) - 1] = '\0'; + + if (strcasecmp(cmd_name + 2, directive + 1) != 0) { + return apr_pstrcat(cmd->pool, "Expected but saw ", + cmd_name, ">", NULL); + } + + return NULL; /* found end of container */ + } + else { + const char *msg; + + if (*args == '\0' && cmd_name[strlen(cmd_name) - 1] == '>') { + cmd_name[strlen(cmd_name) - 1] = '\0'; + } + + if ((msg = ap_soak_end_container(cmd, cmd_name)) != NULL) { + return msg; + } + } + } + } + + return apr_pstrcat(cmd->pool, "Expected before end of configuration", + NULL); +} + +static const char *execute_now(char *cmd_line, const char *args, + cmd_parms *parms, + apr_pool_t *p, apr_pool_t *ptemp, + ap_directive_t **sub_tree, + ap_directive_t *parent) +{ + const command_rec *cmd; + ap_mod_list *ml; + char *dir = apr_pstrdup(parms->pool, cmd_line); + + ap_str_tolower(dir); + + ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING); + + if (ml == NULL) { + return apr_pstrcat(parms->pool, "Invalid command '", + cmd_line, + "', perhaps misspelled or defined by a module " + "not included in the server configuration", + NULL); + } + + for ( ; ml != NULL; ml = ml->next) { + const char *retval; + cmd = ml->cmd; + + retval = invoke_cmd(cmd, parms, sub_tree, args); + + if (retval != NULL) { + return retval; + } + } + + return NULL; +} + +/* This structure and the following functions are needed for the + * table-based config file reading. They are passed to the + * cfg_open_custom() routine. + */ + +/* Structure to be passed to cfg_open_custom(): it contains an + * index which is incremented from 0 to nelts on each call to + * cfg_getline() (which in turn calls arr_elts_getstr()) + * and an apr_array_header_t pointer for the string array. + */ +typedef struct { + apr_array_header_t *array; + int curr_idx; +} arr_elts_param_t; + + +/* arr_elts_getstr() returns the next line from the string array. */ +static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param) +{ + arr_elts_param_t *arr_param = (arr_elts_param_t *)param; + + /* End of array reached? */ + if (++arr_param->curr_idx > arr_param->array->nelts) + return NULL; + + /* return the line */ + apr_cpystrn(buf, + ((char **)arr_param->array->elts)[arr_param->curr_idx - 1], + bufsiz); + + return buf; +} + + +/* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */ +static int arr_elts_close(void *param) +{ + arr_elts_param_t *arr_param = (arr_elts_param_t *)param; + + arr_param->curr_idx = arr_param->array->nelts; + + return 0; +} + +static const char *process_command_config(server_rec *s, + apr_array_header_t *arr, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp) +{ + const char *errmsg; + cmd_parms parms; + arr_elts_param_t arr_parms; + + arr_parms.curr_idx = 0; + arr_parms.array = arr; + + if (ap_config_hash == NULL) { + rebuild_conf_hash(s->process->pconf, 1); + } + + parms = default_parms; + parms.pool = p; + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); + parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + + parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives", + &arr_parms, NULL, + arr_elts_getstr, arr_elts_close); + + errmsg = ap_build_config(&parms, p, ptemp, conftree); + ap_cfg_closefile(parms.config_file); + + if (errmsg) { + return apr_pstrcat(p, "Syntax error in -C/-c directive: ", errmsg, + NULL); + } + + return NULL; +} + +typedef struct { + char *fname; +} fnames; + +static int fname_alphasort(const void *fn1, const void *fn2) +{ + const fnames *f1 = fn1; + const fnames *f2 = fn2; + + return strcmp(f1->fname,f2->fname); +} + +static const char *process_resource_config_nofnmatch(server_rec *s, + const char *fname, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp, + unsigned depth) +{ + cmd_parms parms; + ap_configfile_t *cfp; + const char *error; + apr_status_t rv; + + if (ap_is_directory(p, fname)) { + apr_dir_t *dirp; + apr_finfo_t dirent; + int current; + apr_array_header_t *candidates = NULL; + fnames *fnew; + char *path = apr_pstrdup(p, fname); + + if (++depth > AP_MAX_INCLUDE_DIR_DEPTH) { + return apr_psprintf(p, "Directory %s exceeds the maximum include " + "directory nesting level of %u. You have " + "probably a recursion somewhere.", path, + AP_MAX_INCLUDE_DIR_DEPTH); + } + + /* + * first course of business is to grok all the directory + * entries here and store 'em away. Recall we need full pathnames + * for this. + */ + rv = apr_dir_open(&dirp, path, p); + if (rv != APR_SUCCESS) { + char errmsg[120]; + return apr_psprintf(p, "Could not open config directory %s: %s", + path, apr_strerror(rv, errmsg, sizeof errmsg)); + } + + candidates = apr_array_make(p, 1, sizeof(fnames)); + while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { + /* strip out '.' and '..' */ + if (strcmp(dirent.name, ".") + && strcmp(dirent.name, "..")) { + fnew = (fnames *) apr_array_push(candidates); + fnew->fname = ap_make_full_path(p, path, dirent.name); + } + } + + apr_dir_close(dirp); + if (candidates->nelts != 0) { + qsort((void *) candidates->elts, candidates->nelts, + sizeof(fnames), fname_alphasort); + + /* + * Now recurse these... we handle errors and subdirectories + * via the recursion, which is nice + */ + for (current = 0; current < candidates->nelts; ++current) { + fnew = &((fnames *) candidates->elts)[current]; + error = process_resource_config_nofnmatch(s, fnew->fname, + conftree, p, ptemp, + depth); + if (error) { + return error; + } + } + } + + return NULL; + } + + /* GCC's initialization extensions are soooo nice here... */ + parms = default_parms; + parms.pool = p; + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); + parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + + rv = ap_pcfg_openfile(&cfp, p, fname); + if (rv != APR_SUCCESS) { + char errmsg[120]; + return apr_psprintf(p, "Could not open configuration file %s: %s", + fname, apr_strerror(rv, errmsg, sizeof errmsg)); + } + + parms.config_file = cfp; + error = ap_build_config(&parms, p, ptemp, conftree); + ap_cfg_closefile(cfp); + + if (error) { + return apr_psprintf(p, "Syntax error on line %d of %s: %s", + parms.err_directive->line_num, + parms.err_directive->filename, error); + } + + return NULL; +} + +AP_DECLARE(const char *) ap_process_resource_config(server_rec *s, + const char *fname, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp) +{ + /* XXX: lstat() won't work on the wildcard pattern... + */ + + /* don't require conf/httpd.conf if we have a -C or -c switch */ + if ((ap_server_pre_read_config->nelts + || ap_server_post_read_config->nelts) + && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) { + apr_finfo_t finfo; + + if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, p) != APR_SUCCESS) + return NULL; + } + + if (!apr_fnmatch_test(fname)) { + return process_resource_config_nofnmatch(s, fname, conftree, p, ptemp, + 0); + } + else { + apr_dir_t *dirp; + apr_finfo_t dirent; + int current; + apr_array_header_t *candidates = NULL; + fnames *fnew; + apr_status_t rv; + char *path = apr_pstrdup(p, fname), *pattern = NULL; + + pattern = ap_strrchr(path, '/'); + + AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */ + + *pattern++ = '\0'; + + if (apr_fnmatch_test(path)) { + return apr_pstrcat(p, "Wildcard patterns not allowed in Include ", + fname, NULL); + } + + if (!ap_is_directory(p, path)){ + return apr_pstrcat(p, "Include directory '", path, "' not found", + NULL); + } + + if (!apr_fnmatch_test(pattern)) { + return apr_pstrcat(p, "Must include a wildcard pattern for " + "Include ", fname, NULL); + } + + /* + * first course of business is to grok all the directory + * entries here and store 'em away. Recall we need full pathnames + * for this. + */ + rv = apr_dir_open(&dirp, path, p); + if (rv != APR_SUCCESS) { + char errmsg[120]; + return apr_psprintf(p, "Could not open config directory %s: %s", + path, apr_strerror(rv, errmsg, sizeof errmsg)); + } + + candidates = apr_array_make(p, 1, sizeof(fnames)); + while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { + /* strip out '.' and '..' */ + if (strcmp(dirent.name, ".") + && strcmp(dirent.name, "..") + && (apr_fnmatch(pattern, dirent.name, + APR_FNM_PERIOD) == APR_SUCCESS)) { + fnew = (fnames *) apr_array_push(candidates); + fnew->fname = ap_make_full_path(p, path, dirent.name); + } + } + + apr_dir_close(dirp); + if (candidates->nelts != 0) { + const char *error; + + qsort((void *) candidates->elts, candidates->nelts, + sizeof(fnames), fname_alphasort); + + /* + * Now recurse these... we handle errors and subdirectories + * via the recursion, which is nice + */ + for (current = 0; current < candidates->nelts; ++current) { + fnew = &((fnames *) candidates->elts)[current]; + error = process_resource_config_nofnmatch(s, fnew->fname, + conftree, p, + ptemp, 0); + if (error) { + return error; + } + } + } + } + + return NULL; +} + +AP_DECLARE(int) ap_process_config_tree(server_rec *s, + ap_directive_t *conftree, + apr_pool_t *p, + apr_pool_t *ptemp) +{ + const char *errmsg; + cmd_parms parms; + + parms = default_parms; + parms.pool = p; + parms.temp_pool = ptemp; + parms.server = s; + parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); + parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + parms.limited = -1; + + errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults); + if (errmsg) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, + "Syntax error on line %d of %s:", + parms.err_directive->line_num, + parms.err_directive->filename); + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, + "%s", errmsg); + return HTTP_INTERNAL_SERVER_ERROR; + } + + return OK; +} + +AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, + request_rec *r, int override, + int override_opts, + const char *d, const char *access_name) +{ + ap_configfile_t *f = NULL; + cmd_parms parms; + char *filename = NULL; + const struct htaccess_result *cache; + struct htaccess_result *new; + ap_conf_vector_t *dc = NULL; + apr_status_t status; + + /* firstly, search cache */ + for (cache = r->htaccess; cache != NULL; cache = cache->next) { + if (cache->override == override && strcmp(cache->dir, d) == 0) { + *result = cache->htaccess; + return OK; + } + } + + parms = default_parms; + parms.override = override; + parms.override_opts = override_opts; + parms.pool = r->pool; + parms.temp_pool = r->pool; + parms.server = r->server; + parms.path = apr_pstrdup(r->pool, d); + + /* loop through the access names and find the first one */ + while (access_name[0]) { + /* AFAICT; there is no use of the actual 'filename' against + * any canonicalization, so we will simply take the given + * name, ignoring case sensitivity and aliases + */ + filename = ap_make_full_path(r->pool, d, + ap_getword_conf(r->pool, &access_name)); + status = ap_pcfg_openfile(&f, r->pool, filename); + + if (status == APR_SUCCESS) { + const char *errmsg; + ap_directive_t *temptree = NULL; + + dc = ap_create_per_dir_config(r->pool); + + parms.config_file = f; + errmsg = ap_build_config(&parms, r->pool, r->pool, &temptree); + if (errmsg == NULL) + errmsg = ap_walk_config(temptree, &parms, dc); + + ap_cfg_closefile(f); + + if (errmsg) { + ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, + "%s: %s", filename, errmsg); + return HTTP_INTERNAL_SERVER_ERROR; + } + + *result = dc; + break; + } + else { + if (!APR_STATUS_IS_ENOENT(status) + && !APR_STATUS_IS_ENOTDIR(status)) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, + "%s pcfg_openfile: unable to check htaccess file, " + "ensure it is readable", + filename); + apr_table_setn(r->notes, "error-notes", + "Server unable to read htaccess file, denying " + "access to be safe"); + return HTTP_FORBIDDEN; + } + } + } + + /* cache it */ + new = apr_palloc(r->pool, sizeof(struct htaccess_result)); + new->dir = parms.path; + new->override = override; + new->override_opts = override_opts; + new->htaccess = dc; + + /* add to head of list */ + new->next = r->htaccess; + r->htaccess = new; + + return OK; +} + +AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p, + const char *hostname, + server_rec *main_server, + server_rec **ps) +{ + server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec)); + + /* TODO: this crap belongs in http_core */ + s->process = main_server->process; + s->server_admin = NULL; + s->server_hostname = NULL; + s->error_fname = NULL; + s->timeout = 0; + s->keep_alive_timeout = 0; + s->keep_alive = -1; + s->keep_alive_max = -1; + s->error_log = main_server->error_log; + s->loglevel = main_server->loglevel; + /* useful default, otherwise we get a port of 0 on redirects */ + s->port = main_server->port; + s->next = NULL; + + s->is_virtual = 1; + s->names = apr_array_make(p, 4, sizeof(char **)); + s->wild_names = apr_array_make(p, 4, sizeof(char **)); + + s->module_config = create_empty_config(p); + s->lookup_defaults = ap_create_per_dir_config(p); + + s->limit_req_line = main_server->limit_req_line; + s->limit_req_fieldsize = main_server->limit_req_fieldsize; + s->limit_req_fields = main_server->limit_req_fields; + + *ps = s; + + return ap_parse_vhost_addrs(p, hostname, s); +} + + +AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server) +{ + server_rec *virt; + + for (virt = main_server->next; virt; virt = virt->next) { + merge_server_configs(p, main_server->module_config, + virt->module_config); + + virt->lookup_defaults = + ap_merge_per_dir_configs(p, main_server->lookup_defaults, + virt->lookup_defaults); + + if (virt->server_admin == NULL) + virt->server_admin = main_server->server_admin; + + if (virt->timeout == 0) + virt->timeout = main_server->timeout; + + if (virt->keep_alive_timeout == 0) + virt->keep_alive_timeout = main_server->keep_alive_timeout; + + if (virt->keep_alive == -1) + virt->keep_alive = main_server->keep_alive; + + if (virt->keep_alive_max == -1) + virt->keep_alive_max = main_server->keep_alive_max; + + /* XXX: this is really something that should be dealt with by a + * post-config api phase + */ + ap_core_reorder_directories(p, virt); + } + + ap_core_reorder_directories(p, main_server); +} + +/***************************************************************** + * + * Getting *everything* configured... + */ + +static void init_config_globals(apr_pool_t *p) +{ + /* Global virtual host hash bucket pointers. Init to null. */ + ap_init_vhost_config(p); +} + +static server_rec *init_server_config(process_rec *process, apr_pool_t *p) +{ + apr_status_t rv; + server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec)); + + apr_file_open_stderr(&s->error_log, p); + s->process = process; + s->port = 0; + s->server_admin = DEFAULT_ADMIN; + s->server_hostname = NULL; + s->error_fname = DEFAULT_ERRORLOG; + s->loglevel = DEFAULT_LOGLEVEL; + s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE; + s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE; + s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS; + s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT); + s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT); + s->keep_alive_max = DEFAULT_KEEPALIVE; + s->keep_alive = 1; + s->next = NULL; + s->addrs = apr_pcalloc(p, sizeof(server_addr_rec)); + + /* NOT virtual host; don't match any real network interface */ + rv = apr_sockaddr_info_get(&s->addrs->host_addr, + NULL, APR_INET, 0, 0, p); + ap_assert(rv == APR_SUCCESS); /* otherwise: bug or no storage */ + + s->addrs->host_port = 0; /* matches any port */ + s->addrs->virthost = ""; /* must be non-NULL */ + s->names = s->wild_names = NULL; + + s->module_config = create_server_config(p, s); + s->lookup_defaults = create_default_per_dir_config(p); + + return s; +} + + +AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp, + const char *filename, + ap_directive_t **conftree) +{ + const char *confname, *error; + apr_pool_t *p = process->pconf; + server_rec *s = init_server_config(process, p); + + init_config_globals(p); + + /* All server-wide config files now have the SAME syntax... */ + error = process_command_config(s, ap_server_pre_read_config, conftree, + p, ptemp); + if (error) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s", + ap_server_argv0, error); + return NULL; + } + + /* process_command_config may change the ServerRoot so + * compute this config file name afterwards. + */ + confname = ap_server_root_relative(p, filename); + + if (!confname) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, + APR_EBADPATH, NULL, "Invalid config file path %s", + filename); + return NULL; + } + + error = ap_process_resource_config(s, confname, conftree, p, ptemp); + if (error) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, + "%s: %s", ap_server_argv0, error); + return NULL; + } + + error = process_command_config(s, ap_server_post_read_config, conftree, + p, ptemp); + + if (error) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s", + ap_server_argv0, error); + return NULL; + } + + return s; +} + +AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s, + module *m) +{ + if (m->create_server_config) + ap_set_module_config(s->module_config, m, + (*m->create_server_config)(p, s)); + + if (m->create_dir_config) + ap_set_module_config(s->lookup_defaults, m, + (*m->create_dir_config)(p, NULL)); +} + +AP_DECLARE(void) ap_run_rewrite_args(process_rec *process) +{ + module *m; + + for (m = ap_top_module; m; m = m->next) { + if (m->rewrite_args) { + (*m->rewrite_args)(process); + } + } +} + +/******************************************************************** + * Configuration directives are restricted in terms of where they may + * appear in the main configuration files and/or .htaccess files according + * to the bitmask req_override in the command_rec structure. + * If any of the overrides set in req_override are also allowed in the + * context in which the command is read, then the command is allowed. + * The context is determined as follows: + * + * inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT); + * within or --> override = OR_ALL|ACCESS_CONF; + * within .htaccess --> override = AllowOverride for current directory; + * + * the result is, well, a rather confusing set of possibilities for when + * a particular directive is allowed to be used. This procedure prints + * in English where the given (pc) directive can be used. + */ +static void show_overrides(const command_rec *pc, module *pm) +{ + int n = 0; + + printf("\tAllowed in *.conf "); + if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES)) + || ((pc->req_override & RSRC_CONF) + && ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT))))) { + printf("anywhere"); + } + else if (pc->req_override & RSRC_CONF) { + printf("only outside , or "); + } + else { + printf("only inside , or "); + } + + /* Warn if the directive is allowed inside or .htaccess + * but module doesn't support per-dir configuration + */ + if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config) + printf(" [no per-dir config]"); + + if (pc->req_override & OR_ALL) { + printf(" and in .htaccess\n\twhen AllowOverride"); + + if ((pc->req_override & OR_ALL) == OR_ALL) { + printf(" isn't None"); + } + else { + printf(" includes "); + + if (pc->req_override & OR_AUTHCFG) { + if (n++) + printf(" or "); + + printf("AuthConfig"); + } + + if (pc->req_override & OR_LIMIT) { + if (n++) + printf(" or "); + + printf("Limit"); + } + + if (pc->req_override & OR_OPTIONS) { + if (n++) + printf(" or "); + + printf("Options"); + } + + if (pc->req_override & OR_FILEINFO) { + if (n++) + printf(" or "); + + printf("FileInfo"); + } + + if (pc->req_override & OR_INDEXES) { + if (n++) + printf(" or "); + + printf("Indexes"); + } + } + } + + printf("\n"); +} + +/* Show the preloaded configuration directives, the help string explaining + * the directive arguments, in what module they are handled, and in + * what parts of the configuration they are allowed. Used for httpd -L. + */ +AP_DECLARE(void) ap_show_directives(void) +{ + const command_rec *pc; + int n; + + for (n = 0; ap_loaded_modules[n]; ++n) { + for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) { + printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name); + + if (pc->errmsg) + printf("\t%s\n", pc->errmsg); + + show_overrides(pc, ap_loaded_modules[n]); + } + } +} + +/* Show the preloaded module names. Used for httpd -l. */ +AP_DECLARE(void) ap_show_modules(void) +{ + int n; + + printf("Compiled in modules:\n"); + for (n = 0; ap_loaded_modules[n]; ++n) + printf(" %s\n", ap_loaded_modules[n]->name); +} + +AP_DECLARE(const char *) ap_show_mpm(void) +{ + return MPM_NAME; +} diff --git a/trunk/server/config.m4 b/trunk/server/config.m4 new file mode 100644 index 0000000000..85fa4d1791 --- /dev/null +++ b/trunk/server/config.m4 @@ -0,0 +1,15 @@ +dnl ## Check for libraries + +dnl ## Check for header files + +AC_CHECK_HEADERS(bstring.h unistd.h) + +dnl ## Check for typedefs, structures, and compiler characteristics. + +dnl ## Check for library functions + +AC_CHECK_FUNCS(syslog) + +dnl Obsolete scoreboard code uses this. + AC_CHECK_HEADERS(sys/times.h) + AC_CHECK_FUNCS(times) diff --git a/trunk/server/connection.c b/trunk/server/connection.c new file mode 100644 index 0000000000..9f59497910 --- /dev/null +++ b/trunk/server/connection.c @@ -0,0 +1,179 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_connection.h" +#include "http_request.h" +#include "http_protocol.h" +#include "ap_mpm.h" +#include "mpm_default.h" +#include "http_config.h" +#include "http_core.h" +#include "http_vhost.h" +#include "scoreboard.h" +#include "http_log.h" +#include "util_filter.h" + +APR_HOOK_STRUCT( + APR_HOOK_LINK(create_connection) + APR_HOOK_LINK(process_connection) + APR_HOOK_LINK(pre_connection) +) +AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, + (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc), + (p, server, csd, conn_id, sbh, alloc), NULL) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) +AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED) +/* + * More machine-dependent networking gooo... on some systems, + * you've got to be *really* sure that all the packets are acknowledged + * before closing the connection, since the client will not be able + * to see the last response if their TCP buffer is flushed by a RST + * packet from us, which is what the server's TCP stack will send + * if it receives any request data after closing the connection. + * + * In an ideal world, this function would be accomplished by simply + * setting the socket option SO_LINGER and handling it within the + * server's TCP stack while the process continues on to the next request. + * Unfortunately, it seems that most (if not all) operating systems + * block the server process on close() when SO_LINGER is used. + * For those that don't, see USE_SO_LINGER below. For the rest, + * we have created a home-brew lingering_close. + * + * Many operating systems tend to block, puke, or otherwise mishandle + * calls to shutdown only half of the connection. You should define + * NO_LINGCLOSE in ap_config.h if such is the case for your system. + */ +#ifndef MAX_SECS_TO_LINGER +#define MAX_SECS_TO_LINGER 30 +#endif + +AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c) +{ + apr_bucket_brigade *bb; + apr_bucket *b; + + bb = apr_brigade_create(c->pool, c->bucket_alloc); + + /* FLUSH bucket */ + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + /* End Of Connection bucket */ + b = ap_bucket_eoc_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + ap_pass_brigade(c->output_filters, bb); +} + +/* we now proceed to read from the client until we get EOF, or until + * MAX_SECS_TO_LINGER has passed. the reasons for doing this are + * documented in a draft: + * + * http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt + * + * in a nutshell -- if we don't make this effort we risk causing + * TCP RST packets to be sent which can tear down a connection before + * all the response data has been sent to the client. + */ +#define SECONDS_TO_LINGER 2 +AP_DECLARE(void) ap_lingering_close(conn_rec *c) +{ + char dummybuf[512]; + apr_size_t nbytes = sizeof(dummybuf); + apr_status_t rc; + apr_int32_t timeout; + apr_int32_t total_linger_time = 0; + apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module); + + if (!csd) { + return; + } + + ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); + +#ifdef NO_LINGCLOSE + ap_flush_conn(c); /* just close it */ + apr_socket_close(csd); + return; +#endif + + /* Close the connection, being careful to send out whatever is still + * in our buffers. If possible, try to avoid a hard close until the + * client has ACKed our FIN and/or has stopped sending us data. + */ + + /* Send any leftover data to the client, but never try to again */ + ap_flush_conn(c); + + if (c->aborted) { + apr_socket_close(csd); + return; + } + + /* Shut down the socket for write, which will send a FIN + * to the peer. + */ + if (apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS + || c->aborted) { + apr_socket_close(csd); + return; + } + + /* Read all data from the peer until we reach "end-of-file" (FIN + * from peer) or we've exceeded our overall timeout. If the client does + * not send us bytes within 2 seconds (a value pulled from Apache 1.3 + * which seems to work well), close the connection. + */ + timeout = apr_time_from_sec(SECONDS_TO_LINGER); + apr_socket_timeout_set(csd, timeout); + apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1); + while (1) { + nbytes = sizeof(dummybuf); + rc = apr_socket_recv(csd, dummybuf, &nbytes); + if (rc != APR_SUCCESS || nbytes == 0) + break; + + total_linger_time += SECONDS_TO_LINGER; + if (total_linger_time >= MAX_SECS_TO_LINGER) { + break; + } + } + + apr_socket_close(csd); + return; +} + +AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd) +{ + int rc; + ap_update_vhost_given_ip(c); + + rc = ap_run_pre_connection(c, csd); + if (rc != OK && rc != DONE) { + c->aborted = 1; + } + + if (!c->aborted) { + ap_run_process_connection(c); + } +} + diff --git a/trunk/server/core.c b/trunk/server/core.c new file mode 100644 index 0000000000..34acc9922c --- /dev/null +++ b/trunk/server/core.c @@ -0,0 +1,3807 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_fnmatch.h" +#include "apr_hash.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ +#include "apr_hooks.h" + +#define APR_WANT_IOVEC +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" /* For index_of_response(). Grump. */ +#include "http_request.h" +#include "http_vhost.h" +#include "http_main.h" /* For the default_handler below... */ +#include "http_log.h" +#include "util_md5.h" +#include "http_connection.h" +#include "apr_buckets.h" +#include "util_filter.h" +#include "util_ebcdic.h" +#include "mpm.h" +#include "mpm_common.h" +#include "scoreboard.h" +#include "mod_core.h" +#include "mod_proxy.h" +#include "ap_listen.h" + +#include "mod_so.h" /* for ap_find_loaded_module_symbol */ + +/* LimitRequestBody handling */ +#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) +#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) + +/* LimitXMLRequestBody handling */ +#define AP_LIMIT_UNSET ((long) -1) +#define AP_DEFAULT_LIMIT_XML_BODY ((size_t)1000000) + +#define AP_MIN_SENDFILE_BYTES (256) + +/* maximum include nesting level */ +#ifndef AP_MAX_INCLUDE_DEPTH +#define AP_MAX_INCLUDE_DEPTH (128) +#endif + +APR_HOOK_STRUCT( + APR_HOOK_LINK(get_mgmt_items) +) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, + (apr_pool_t *p, const char *val, apr_hash_t *ht), + (p, val, ht), OK, DECLINED) + +/* Server core module... This module provides support for really basic + * server operations, including options and commands which control the + * operation of other modules. Consider this the bureaucracy module. + * + * The core module also defines handlers, etc., do handle just enough + * to allow a server with the core module ONLY to actually serve documents + * (though it slaps DefaultType on all of 'em); this was useful in testing, + * but may not be worth preserving. + * + * This file could almost be mod_core.c, except for the stuff which affects + * the http_conf_globals. + */ + +/* Handles for core filters */ +AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; + +/* magic pointer for ErrorDocument xxx "default" */ +static char errordocument_default; + +static void *create_core_dir_config(apr_pool_t *a, char *dir) +{ + core_dir_config *conf; + int i; + + conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config)); + + /* conf->r and conf->d[_*] are initialized by dirsection() or left NULL */ + + conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL; + conf->opts_add = conf->opts_remove = OPT_NONE; + conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL; + conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER + | OPT_MULTI; + + conf->content_md5 = 2; + conf->accept_path_info = 3; + + conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; + + conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; + conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); + for (i = 0; i < METHODS; ++i) { + conf->satisfy[i] = SATISFY_NOSPEC; + } + +#ifdef RLIMIT_CPU + conf->limit_cpu = NULL; +#endif +#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + conf->limit_mem = NULL; +#endif +#ifdef RLIMIT_NPROC + conf->limit_nproc = NULL; +#endif + + conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET; + conf->limit_xml_body = AP_LIMIT_UNSET; + conf->sec_file = apr_array_make(a, 2, sizeof(ap_conf_vector_t *)); + + conf->server_signature = srv_sig_unset; + + conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET; + conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; + + /* Overriding all negotiation + */ + conf->mime_type = NULL; + conf->handler = NULL; + conf->output_filters = NULL; + conf->input_filters = NULL; + + /* + * Flag for use of inodes in ETags. + */ + conf->etag_bits = ETAG_UNSET; + conf->etag_add = ETAG_UNSET; + conf->etag_remove = ETAG_UNSET; + + conf->enable_mmap = ENABLE_MMAP_UNSET; + conf->enable_sendfile = ENABLE_SENDFILE_UNSET; + conf->allow_encoded_slashes = 0; + + return (void *)conf; +} + +/* + * Overlay one hash table of ct_output_filters onto another + */ +static void *merge_ct_filters(apr_pool_t *p, + const void *key, + apr_ssize_t klen, + const void *overlay_val, + const void *base_val, + const void *data) +{ + ap_filter_rec_t *cur; + const ap_filter_rec_t *overlay_info = (const ap_filter_rec_t *)overlay_val; + const ap_filter_rec_t *base_info = (const ap_filter_rec_t *)base_val; + + cur = NULL; + + while (overlay_info) { + ap_filter_rec_t *new; + + new = apr_pcalloc(p, sizeof(ap_filter_rec_t)); + new->name = apr_pstrdup(p, overlay_info->name); + new->next = cur; + cur = new; + overlay_info = overlay_info->next; + } + + while (base_info) { + ap_filter_rec_t *f; + int found = 0; + + /* We can't have dups. */ + f = cur; + while (f) { + if (!strcasecmp(base_info->name, f->name)) { + found = 1; + break; + } + + f = f->next; + } + + if (!found) { + f = apr_pcalloc(p, sizeof(ap_filter_rec_t)); + f->name = apr_pstrdup(p, base_info->name); + f->next = cur; + cur = f; + } + + base_info = base_info->next; + } + + return cur; +} + +static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) +{ + core_dir_config *base = (core_dir_config *)basev; + core_dir_config *new = (core_dir_config *)newv; + core_dir_config *conf; + int i; + + /* Create this conf by duplicating the base, replacing elements + * (or creating copies for merging) where new-> values exist. + */ + conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config)); + memcpy(conf, base, sizeof(core_dir_config)); + + conf->d = new->d; + conf->d_is_fnmatch = new->d_is_fnmatch; + conf->d_components = new->d_components; + conf->r = new->r; + + if (new->opts & OPT_UNSET) { + /* there was no explicit setting of new->opts, so we merge + * preserve the invariant (opts_add & opts_remove) == 0 + */ + conf->opts_add = (conf->opts_add & ~new->opts_remove) | new->opts_add; + conf->opts_remove = (conf->opts_remove & ~new->opts_add) + | new->opts_remove; + conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add; + if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) { + conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES; + } + } + else { + /* otherwise we just copy, because an explicit opts setting + * overrides all earlier +/- modifiers + */ + conf->opts = new->opts; + conf->opts_add = new->opts_add; + conf->opts_remove = new->opts_remove; + } + + if (!(new->override & OR_UNSET)) { + conf->override = new->override; + } + + if (!(new->override_opts & OPT_UNSET)) { + conf->override_opts = new->override_opts; + } + + if (new->ap_default_type) { + conf->ap_default_type = new->ap_default_type; + } + + if (new->ap_auth_type) { + conf->ap_auth_type = new->ap_auth_type; + } + + if (new->ap_auth_name) { + conf->ap_auth_name = new->ap_auth_name; + } + + if (new->ap_requires) { + conf->ap_requires = new->ap_requires; + } + + if (conf->response_code_strings == NULL) { + conf->response_code_strings = new->response_code_strings; + } + else if (new->response_code_strings != NULL) { + /* If we merge, the merge-result must have it's own array + */ + conf->response_code_strings = apr_palloc(a, + sizeof(*conf->response_code_strings) * RESPONSE_CODES); + memcpy(conf->response_code_strings, base->response_code_strings, + sizeof(*conf->response_code_strings) * RESPONSE_CODES); + + for (i = 0; i < RESPONSE_CODES; ++i) { + if (new->response_code_strings[i] != NULL) { + conf->response_code_strings[i] = new->response_code_strings[i]; + } + } + } + /* Otherwise we simply use the base->response_code_strings array + */ + + if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) { + conf->hostname_lookups = new->hostname_lookups; + } + + if ((new->content_md5 & 2) == 0) { + conf->content_md5 = new->content_md5; + } + + if (new->accept_path_info != 3) { + conf->accept_path_info = new->accept_path_info; + } + + if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) { + conf->use_canonical_name = new->use_canonical_name; + } + +#ifdef RLIMIT_CPU + if (new->limit_cpu) { + conf->limit_cpu = new->limit_cpu; + } +#endif + +#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) + if (new->limit_mem) { + conf->limit_mem = new->limit_mem; + } +#endif + +#ifdef RLIMIT_NPROC + if (new->limit_nproc) { + conf->limit_nproc = new->limit_nproc; + } +#endif + + if (new->limit_req_body != AP_LIMIT_REQ_BODY_UNSET) { + conf->limit_req_body = new->limit_req_body; + } + + if (new->limit_xml_body != AP_LIMIT_UNSET) + conf->limit_xml_body = new->limit_xml_body; + else + conf->limit_xml_body = base->limit_xml_body; + + if (!conf->sec_file) { + conf->sec_file = new->sec_file; + } + else if (new->sec_file) { + /* If we merge, the merge-result must have it's own array + */ + conf->sec_file = apr_array_append(a, base->sec_file, new->sec_file); + } + /* Otherwise we simply use the base->sec_file array + */ + + /* use a separate ->satisfy[] array either way */ + conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); + for (i = 0; i < METHODS; ++i) { + if (new->satisfy[i] != SATISFY_NOSPEC) { + conf->satisfy[i] = new->satisfy[i]; + } else { + conf->satisfy[i] = base->satisfy[i]; + } + } + + if (new->server_signature != srv_sig_unset) { + conf->server_signature = new->server_signature; + } + + if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) { + conf->add_default_charset = new->add_default_charset; + conf->add_default_charset_name = new->add_default_charset_name; + } + + /* Overriding all negotiation + */ + if (new->mime_type) { + conf->mime_type = new->mime_type; + } + + if (new->handler) { + conf->handler = new->handler; + } + + if (new->output_filters) { + conf->output_filters = new->output_filters; + } + + if (new->input_filters) { + conf->input_filters = new->input_filters; + } + + if (conf->ct_output_filters && new->ct_output_filters) { + conf->ct_output_filters = apr_hash_merge(a, + new->ct_output_filters, + conf->ct_output_filters, + merge_ct_filters, + NULL); + } + else if (new->ct_output_filters) { + conf->ct_output_filters = apr_hash_copy(a, new->ct_output_filters); + } + else if (conf->ct_output_filters) { + /* That memcpy above isn't enough. */ + conf->ct_output_filters = apr_hash_copy(a, base->ct_output_filters); + } + + /* + * Now merge the setting of the FileETag directive. + */ + if (new->etag_bits == ETAG_UNSET) { + conf->etag_add = + (conf->etag_add & (~ new->etag_remove)) | new->etag_add; + conf->etag_remove = + (conf->opts_remove & (~ new->etag_add)) | new->etag_remove; + conf->etag_bits = + (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add; + } + else { + conf->etag_bits = new->etag_bits; + conf->etag_add = new->etag_add; + conf->etag_remove = new->etag_remove; + } + + if (conf->etag_bits != ETAG_NONE) { + conf->etag_bits &= (~ ETAG_NONE); + } + + if (new->enable_mmap != ENABLE_MMAP_UNSET) { + conf->enable_mmap = new->enable_mmap; + } + + if (new->enable_sendfile != ENABLE_SENDFILE_UNSET) { + conf->enable_sendfile = new->enable_sendfile; + } + + conf->allow_encoded_slashes = new->allow_encoded_slashes; + + return (void*)conf; +} + +static void *create_core_server_config(apr_pool_t *a, server_rec *s) +{ + core_server_config *conf; + int is_virtual = s->is_virtual; + + conf = (core_server_config *)apr_pcalloc(a, sizeof(core_server_config)); + +#ifdef GPROF + conf->gprof_dir = NULL; +#endif + + conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME; + conf->ap_document_root = is_virtual ? NULL : DOCUMENT_LOCATION; + conf->sec_dir = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); + conf->sec_url = apr_array_make(a, 40, sizeof(ap_conf_vector_t *)); + + /* recursion stopper */ + conf->redirect_limit = 0; /* 0 == unset */ + conf->subreq_limit = 0; + + return (void *)conf; +} + +static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) +{ + core_server_config *base = (core_server_config *)basev; + core_server_config *virt = (core_server_config *)virtv; + core_server_config *conf; + + conf = (core_server_config *)apr_palloc(p, sizeof(core_server_config)); + memcpy(conf, virt, sizeof(core_server_config)); + + if (!conf->access_name) { + conf->access_name = base->access_name; + } + + if (!conf->ap_document_root) { + conf->ap_document_root = base->ap_document_root; + } + + conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir); + conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url); + + conf->redirect_limit = virt->redirect_limit + ? virt->redirect_limit + : base->redirect_limit; + + conf->subreq_limit = virt->subreq_limit + ? virt->subreq_limit + : base->subreq_limit; + + return conf; +} + +/* Add per-directory configuration entry (for section); + * these are part of the core server config. + */ + +AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config) +{ + core_server_config *sconf = ap_get_module_config(s->module_config, + &core_module); + void **new_space = (void **)apr_array_push(sconf->sec_dir); + + *new_space = dir_config; +} + +AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config) +{ + core_server_config *sconf = ap_get_module_config(s->module_config, + &core_module); + void **new_space = (void **)apr_array_push(sconf->sec_url); + + *new_space = url_config; +} + +AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config) +{ + void **new_space = (void **)apr_array_push(conf->sec_file); + + *new_space = url_config; +} + +/* We need to do a stable sort, qsort isn't stable. So to make it stable + * we'll be maintaining the original index into the list, and using it + * as the minor key during sorting. The major key is the number of + * components (where the root component is zero). + */ +struct reorder_sort_rec { + ap_conf_vector_t *elt; + int orig_index; +}; + +static int reorder_sorter(const void *va, const void *vb) +{ + const struct reorder_sort_rec *a = va; + const struct reorder_sort_rec *b = vb; + core_dir_config *core_a; + core_dir_config *core_b; + + core_a = ap_get_module_config(a->elt, &core_module); + core_b = ap_get_module_config(b->elt, &core_module); + + /* a regex always sorts after a non-regex + */ + if (!core_a->r && core_b->r) { + return -1; + } + else if (core_a->r && !core_b->r) { + return 1; + } + + /* we always sort next by the number of components + */ + if (core_a->d_components < core_b->d_components) { + return -1; + } + else if (core_a->d_components > core_b->d_components) { + return 1; + } + + /* They have the same number of components, we now have to compare + * the minor key to maintain the original order (from the config.) + */ + return a->orig_index - b->orig_index; +} + +void ap_core_reorder_directories(apr_pool_t *p, server_rec *s) +{ + core_server_config *sconf; + apr_array_header_t *sec_dir; + struct reorder_sort_rec *sortbin; + int nelts; + ap_conf_vector_t **elts; + int i; + apr_pool_t *tmp; + + sconf = ap_get_module_config(s->module_config, &core_module); + sec_dir = sconf->sec_dir; + nelts = sec_dir->nelts; + elts = (ap_conf_vector_t **)sec_dir->elts; + + if (!nelts) { + /* simple case of already being sorted... */ + /* We're not checking this condition to be fast... we're checking + * it to avoid trying to palloc zero bytes, which can trigger some + * memory debuggers to barf + */ + return; + } + + /* we have to allocate tmp space to do a stable sort */ + apr_pool_create(&tmp, p); + sortbin = apr_palloc(tmp, sec_dir->nelts * sizeof(*sortbin)); + for (i = 0; i < nelts; ++i) { + sortbin[i].orig_index = i; + sortbin[i].elt = elts[i]; + } + + qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter); + + /* and now copy back to the original array */ + for (i = 0; i < nelts; ++i) { + elts[i] = sortbin[i].elt; + } + + apr_pool_destroy(tmp); +} + +/***************************************************************** + * + * There are some elements of the core config structures in which + * other modules have a legitimate interest (this is ugly, but necessary + * to preserve NCSA back-compatibility). So, we have a bunch of accessors + * here... + */ + +AP_DECLARE(int) ap_allow_options(request_rec *r) +{ + core_dir_config *conf = + (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); + + return conf->opts; +} + +AP_DECLARE(int) ap_allow_overrides(request_rec *r) +{ + core_dir_config *conf; + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->override; +} + +AP_DECLARE(const char *) ap_auth_type(request_rec *r) +{ + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->ap_auth_type; +} + +AP_DECLARE(const char *) ap_auth_name(request_rec *r) +{ + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->ap_auth_name; +} + +AP_DECLARE(const char *) ap_default_type(request_rec *r) +{ + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->ap_default_type + ? conf->ap_default_type + : DEFAULT_CONTENT_TYPE; +} + +AP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */ +{ + core_server_config *conf; + + conf = (core_server_config *)ap_get_module_config(r->server->module_config, + &core_module); + + return conf->ap_document_root; +} + +AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r) +{ + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->ap_requires; +} + +AP_DECLARE(int) ap_satisfies(request_rec *r) +{ + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + return conf->satisfy[r->method_number]; +} + +/* Should probably just get rid of this... the only code that cares is + * part of the core anyway (and in fact, it isn't publicised to other + * modules). + */ + +char *ap_response_code_string(request_rec *r, int error_index) +{ + core_dir_config *dirconf; + core_request_config *reqconf; + + /* check for string registered via ap_custom_response() first */ + reqconf = (core_request_config *)ap_get_module_config(r->request_config, + &core_module); + if (reqconf->response_code_strings != NULL && + reqconf->response_code_strings[error_index] != NULL) { + return reqconf->response_code_strings[error_index]; + } + + /* check for string specified via ErrorDocument */ + dirconf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + if (dirconf->response_code_strings == NULL) { + return NULL; + } + + if (dirconf->response_code_strings[error_index] == &errordocument_default) { + return NULL; + } + + return dirconf->response_code_strings[error_index]; +} + + +/* Code from Harald Hanche-Olsen */ +static APR_INLINE void do_double_reverse (conn_rec *conn) +{ + apr_sockaddr_t *sa; + apr_status_t rv; + + if (conn->double_reverse) { + /* already done */ + return; + } + + if (conn->remote_host == NULL || conn->remote_host[0] == '\0') { + /* single reverse failed, so don't bother */ + conn->double_reverse = -1; + return; + } + + rv = apr_sockaddr_info_get(&sa, conn->remote_host, APR_UNSPEC, 0, 0, conn->pool); + if (rv == APR_SUCCESS) { + while (sa) { + if (apr_sockaddr_equal(sa, conn->remote_addr)) { + conn->double_reverse = 1; + return; + } + + sa = sa->next; + } + } + + conn->double_reverse = -1; +} + +AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, + int type, int *str_is_ip) +{ + int hostname_lookups; + int ignored_str_is_ip; + + if (!str_is_ip) { /* caller doesn't want to know */ + str_is_ip = &ignored_str_is_ip; + } + *str_is_ip = 0; + + /* If we haven't checked the host name, and we want to */ + if (dir_config) { + hostname_lookups = + ((core_dir_config *)ap_get_module_config(dir_config, &core_module)) + ->hostname_lookups; + + if (hostname_lookups == HOSTNAME_LOOKUP_UNSET) { + hostname_lookups = HOSTNAME_LOOKUP_OFF; + } + } + else { + /* the default */ + hostname_lookups = HOSTNAME_LOOKUP_OFF; + } + + if (type != REMOTE_NOLOOKUP + && conn->remote_host == NULL + && (type == REMOTE_DOUBLE_REV + || hostname_lookups != HOSTNAME_LOOKUP_OFF)) { + + if (apr_getnameinfo(&conn->remote_host, conn->remote_addr, 0) + == APR_SUCCESS) { + ap_str_tolower(conn->remote_host); + + if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) { + do_double_reverse(conn); + if (conn->double_reverse != 1) { + conn->remote_host = NULL; + } + } + } + + /* if failed, set it to the NULL string to indicate error */ + if (conn->remote_host == NULL) { + conn->remote_host = ""; + } + } + + if (type == REMOTE_DOUBLE_REV) { + do_double_reverse(conn); + if (conn->double_reverse == -1) { + return NULL; + } + } + + /* + * Return the desired information; either the remote DNS name, if found, + * or either NULL (if the hostname was requested) or the IP address + * (if any identifier was requested). + */ + if (conn->remote_host != NULL && conn->remote_host[0] != '\0') { + return conn->remote_host; + } + else { + if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) { + return NULL; + } + else { + *str_is_ip = 1; + return conn->remote_ip; + } + } +} + +/* + * Optional function coming from mod_ident, used for looking up ident user + */ +static APR_OPTIONAL_FN_TYPE(ap_ident_lookup) *ident_lookup; + +AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r) +{ + if (r->connection->remote_logname != NULL) { + return r->connection->remote_logname; + } + + if (ident_lookup) { + return ident_lookup(r); + } + + return NULL; +} + +/* There are two options regarding what the "name" of a server is. The + * "canonical" name as defined by ServerName and Port, or the "client's + * name" as supplied by a possible Host: header or full URI. We never + * trust the port passed in the client's headers, we always use the + * port of the actual socket. + * + * The DNS option to UseCanonicalName causes this routine to do a + * reverse lookup on the local IP address of the connection and use + * that for the ServerName. This makes its value more reliable while + * at the same time allowing Demon's magic virtual hosting to work. + * The assumption is that DNS lookups are sufficiently quick... + * -- fanf 1998-10-03 + */ +AP_DECLARE(const char *) ap_get_server_name(request_rec *r) +{ + conn_rec *conn = r->connection; + core_dir_config *d; + + d = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + if (d->use_canonical_name == USE_CANONICAL_NAME_ON) { + return r->server->server_hostname; + } + + if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + if (conn->local_host == NULL) { + if (apr_getnameinfo(&conn->local_host, + conn->local_addr, 0) != APR_SUCCESS) + conn->local_host = apr_pstrdup(conn->pool, + r->server->server_hostname); + else { + ap_str_tolower(conn->local_host); + } + } + + return conn->local_host; + } + + /* default */ + return r->hostname ? r->hostname : r->server->server_hostname; +} + +/* + * Get the current server name from the request for the purposes + * of using in a URL. If the server name is an IPv6 literal + * address, it will be returned in URL format (e.g., "[fe80::1]"). + */ +static const char *get_server_name_for_url(request_rec *r) +{ + const char *plain_server_name = ap_get_server_name(r); + +#if APR_HAVE_IPV6 + if (ap_strchr_c(plain_server_name, ':')) { /* IPv6 literal? */ + return apr_psprintf(r->pool, "[%s]", plain_server_name); + } +#endif + return plain_server_name; +} + +AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r) +{ + apr_port_t port; + core_dir_config *d = + (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); + + if (d->use_canonical_name == USE_CANONICAL_NAME_OFF + || d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + + /* With UseCanonicalName off Apache will form self-referential + * URLs using the hostname and port supplied by the client if + * any are supplied (otherwise it will use the canonical name). + */ + port = r->parsed_uri.port_str ? r->parsed_uri.port : + r->connection->local_addr->port ? r->connection->local_addr->port : + r->server->port ? r->server->port : + ap_default_port(r); + } + else { /* d->use_canonical_name == USE_CANONICAL_NAME_ON */ + + /* With UseCanonicalName on (and in all versions prior to 1.3) + * Apache will use the hostname and port specified in the + * ServerName directive to construct a canonical name for the + * server. (If no port was specified in the ServerName + * directive, Apache uses the port supplied by the client if + * any is supplied, and finally the default port for the protocol + * used. + */ + port = r->server->port ? r->server->port : + r->connection->local_addr->port ? r->connection->local_addr->port : + ap_default_port(r); + } + + /* default */ + return port; +} + +AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, + request_rec *r) +{ + unsigned port = ap_get_server_port(r); + const char *host = get_server_name_for_url(r); + + if (ap_is_default_port(port, r)) { + return apr_pstrcat(p, ap_http_scheme(r), "://", host, uri, NULL); + } + + return apr_psprintf(p, "%s://%s:%u%s", ap_http_scheme(r), host, port, uri); +} + +AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r) +{ + core_dir_config *d = + (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); + + if (d->limit_req_body == AP_LIMIT_REQ_BODY_UNSET) { + return AP_DEFAULT_LIMIT_REQ_BODY; + } + + return d->limit_req_body; +} + + +/***************************************************************** + * + * Commands... this module handles almost all of the NCSA httpd.conf + * commands, but most of the old srm.conf is in the the modules. + */ + + +/* returns a parent if it matches the given directive */ +static const ap_directive_t * find_parent(const ap_directive_t *dirp, + const char *what) +{ + while (dirp->parent != NULL) { + dirp = dirp->parent; + + /* ### it would be nice to have atom-ized directives */ + if (strcasecmp(dirp->directive, what) == 0) + return dirp; + } + + return NULL; +} + +AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd, + unsigned forbidden) +{ + const char *gt = (cmd->cmd->name[0] == '<' + && cmd->cmd->name[strlen(cmd->cmd->name)-1] != '>') + ? ">" : ""; + const ap_directive_t *found; + + if ((forbidden & NOT_IN_VIRTUALHOST) && cmd->server->is_virtual) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, + " cannot occur within section", NULL); + } + + if ((forbidden & NOT_IN_LIMIT) && cmd->limited != -1) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, + " cannot occur within section", NULL); + } + + if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE) { + if (cmd->path != NULL) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, + " cannot occur within " + "section", NULL); + } + if (cmd->cmd->req_override & EXEC_ON_READ) { + /* EXEC_ON_READ must be NOT_IN_DIR_LOC_FILE, if not, it will + * (deliberately) segfault below in the individual tests... + */ + return NULL; + } + } + + if (((forbidden & NOT_IN_DIRECTORY) + && ((found = find_parent(cmd->directive, "directive, "directive, "directive, "directive, "directive, "pool, cmd->cmd->name, gt, + " cannot occur within ", found->directive, + "> section", NULL); + } + + return NULL; +} + +static const char *set_access_name(cmd_parms *cmd, void *dummy, + const char *arg) +{ + void *sconf = cmd->server->module_config; + core_server_config *conf = ap_get_module_config(sconf, &core_module); + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + conf->access_name = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +#ifdef GPROF +static const char *set_gprof_dir(cmd_parms *cmd, void *dummy, const char *arg) +{ + void *sconf = cmd->server->module_config; + core_server_config *conf = ap_get_module_config(sconf, &core_module); + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + conf->gprof_dir = apr_pstrdup(cmd->pool, arg); + return NULL; +} +#endif /*GPROF*/ + +static const char *set_add_default_charset(cmd_parms *cmd, + void *d_, const char *arg) +{ + core_dir_config *d = d_; + + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if (!strcasecmp(arg, "Off")) { + d->add_default_charset = ADD_DEFAULT_CHARSET_OFF; + } + else if (!strcasecmp(arg, "On")) { + d->add_default_charset = ADD_DEFAULT_CHARSET_ON; + d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; + } + else { + d->add_default_charset = ADD_DEFAULT_CHARSET_ON; + d->add_default_charset_name = arg; + } + + return NULL; +} + +static const char *set_document_root(cmd_parms *cmd, void *dummy, + const char *arg) +{ + void *sconf = cmd->server->module_config; + core_server_config *conf = ap_get_module_config(sconf, &core_module); + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + /* Make it absolute, relative to ServerRoot */ + arg = ap_server_root_relative(cmd->pool, arg); + + /* TODO: ap_configtestonly && ap_docrootcheck && */ + if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg, + APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS + || !ap_is_directory(cmd->pool, arg)) { + if (cmd->server->is_virtual) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, + cmd->pool, + "Warning: DocumentRoot [%s] does not exist", + arg); + conf->ap_document_root = arg; + } + else { + return "DocumentRoot must be a directory"; + } + } + return NULL; +} + +AP_DECLARE(void) ap_custom_response(request_rec *r, int status, + const char *string) +{ + core_request_config *conf = + ap_get_module_config(r->request_config, &core_module); + int idx; + + if (conf->response_code_strings == NULL) { + conf->response_code_strings = + apr_pcalloc(r->pool, + sizeof(*conf->response_code_strings) * RESPONSE_CODES); + } + + idx = ap_index_of_response(status); + + conf->response_code_strings[idx] = + ((ap_is_url(string) || (*string == '/')) && (*string != '"')) ? + apr_pstrdup(r->pool, string) : apr_pstrcat(r->pool, "\"", string, NULL); +} + +static const char *set_error_document(cmd_parms *cmd, void *conf_, + const char *errno_str, const char *msg) +{ + core_dir_config *conf = conf_; + int error_number, index_number, idx500; + enum { MSG, LOCAL_PATH, REMOTE_PATH } what = MSG; + + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + /* 1st parameter should be a 3 digit number, which we recognize; + * convert it into an array index + */ + error_number = atoi(errno_str); + idx500 = ap_index_of_response(HTTP_INTERNAL_SERVER_ERROR); + + if (error_number == HTTP_INTERNAL_SERVER_ERROR) { + index_number = idx500; + } + else if ((index_number = ap_index_of_response(error_number)) == idx500) { + return apr_pstrcat(cmd->pool, "Unsupported HTTP response code ", + errno_str, NULL); + } + + /* Heuristic to determine second argument. */ + if (ap_strchr_c(msg,' ')) + what = MSG; + else if (msg[0] == '/') + what = LOCAL_PATH; + else if (ap_is_url(msg)) + what = REMOTE_PATH; + else + what = MSG; + + /* The entry should be ignored if it is a full URL for a 401 error */ + + if (error_number == 401 && what == REMOTE_PATH) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, + "cannot use a full URL in a 401 ErrorDocument " + "directive --- ignoring!"); + } + else { /* Store it... */ + if (conf->response_code_strings == NULL) { + conf->response_code_strings = + apr_pcalloc(cmd->pool, + sizeof(*conf->response_code_strings) * + RESPONSE_CODES); + } + + if (strcmp(msg, "default") == 0) { + /* special case: ErrorDocument 404 default restores the + * canned server error response + */ + conf->response_code_strings[index_number] = &errordocument_default; + } + else { + /* hack. Prefix a " if it is a msg; as that is what + * http_protocol.c relies on to distinguish between + * a msg and a (local) path. + */ + conf->response_code_strings[index_number] = (what == MSG) ? + apr_pstrcat(cmd->pool, "\"",msg,NULL) : + apr_pstrdup(cmd->pool, msg); + } + } + + return NULL; +} + +static const char *set_allow_opts(cmd_parms *cmd, allow_options_t *opts, + const char *l) +{ + allow_options_t opt; + int first = 1; + + char *w, *p = (char *) l; + char *tok_state; + + while ((w = apr_strtok(p, ",", &tok_state)) != NULL) { + + if (first) { + p = NULL; + *opts = OPT_NONE; + first = 0; + } + + if (!strcasecmp(w, "Indexes")) { + opt = OPT_INDEXES; + } + else if (!strcasecmp(w, "Includes")) { + opt = OPT_INCLUDES; + } + else if (!strcasecmp(w, "IncludesNOEXEC")) { + opt = (OPT_INCLUDES | OPT_INCNOEXEC); + } + else if (!strcasecmp(w, "FollowSymLinks")) { + opt = OPT_SYM_LINKS; + } + else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) { + opt = OPT_SYM_OWNER; + } + else if (!strcasecmp(w, "ExecCGI")) { + opt = OPT_EXECCGI; + } + else if (!strcasecmp(w, "MultiViews")) { + opt = OPT_MULTI; + } + else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ + opt = OPT_MULTI|OPT_EXECCGI; + } + else if (!strcasecmp(w, "None")) { + opt = OPT_NONE; + } + else if (!strcasecmp(w, "All")) { + opt = OPT_ALL; + } + else { + return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL); + } + + *opts |= opt; + } + + (*opts) &= (~OPT_UNSET); + + return NULL; +} + +static const char *set_override(cmd_parms *cmd, void *d_, const char *l) +{ + core_dir_config *d = d_; + char *w; + char *k, *v; + + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + /* Throw a warning if we're in or */ + if (ap_check_cmd_context(cmd, NOT_IN_LOCATION | NOT_IN_FILES)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "Useless use of AllowOverride in line %d.", + cmd->directive->line_num); + } + + d->override = OR_NONE; + while (l[0]) { + w = ap_getword_conf(cmd->pool, &l); + + k = w; + v = strchr(k, '='); + if (v) { + *v++ = '\0'; + } + + if (!strcasecmp(w, "Limit")) { + d->override |= OR_LIMIT; + } + else if (!strcasecmp(k, "Options")) { + d->override |= OR_OPTIONS; + if (v) + set_allow_opts(cmd, &(d->override_opts), v); + else + d->override_opts = OPT_ALL; + } + else if (!strcasecmp(w, "FileInfo")) { + d->override |= OR_FILEINFO; + } + else if (!strcasecmp(w, "AuthConfig")) { + d->override |= OR_AUTHCFG; + } + else if (!strcasecmp(w, "Indexes")) { + d->override |= OR_INDEXES; + } + else if (!strcasecmp(w, "None")) { + d->override = OR_NONE; + } + else if (!strcasecmp(w, "All")) { + d->override = OR_ALL; + } + else { + return apr_pstrcat(cmd->pool, "Illegal override option ", w, NULL); + } + + d->override &= ~OR_UNSET; + } + + return NULL; +} + +static const char *set_options(cmd_parms *cmd, void *d_, const char *l) +{ + core_dir_config *d = d_; + allow_options_t opt; + int first = 1; + char action; + + while (l[0]) { + char *w = ap_getword_conf(cmd->pool, &l); + action = '\0'; + + if (*w == '+' || *w == '-') { + action = *(w++); + } + else if (first) { + d->opts = OPT_NONE; + first = 0; + } + + if (!strcasecmp(w, "Indexes")) { + opt = OPT_INDEXES; + } + else if (!strcasecmp(w, "Includes")) { + opt = OPT_INCLUDES; + } + else if (!strcasecmp(w, "IncludesNOEXEC")) { + opt = (OPT_INCLUDES | OPT_INCNOEXEC); + } + else if (!strcasecmp(w, "FollowSymLinks")) { + opt = OPT_SYM_LINKS; + } + else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) { + opt = OPT_SYM_OWNER; + } + else if (!strcasecmp(w, "ExecCGI")) { + opt = OPT_EXECCGI; + } + else if (!strcasecmp(w, "MultiViews")) { + opt = OPT_MULTI; + } + else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */ + opt = OPT_MULTI|OPT_EXECCGI; + } + else if (!strcasecmp(w, "None")) { + opt = OPT_NONE; + } + else if (!strcasecmp(w, "All")) { + opt = OPT_ALL; + } + else { + return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL); + } + + if (!(cmd->override_opts & opt) && opt != OPT_NONE) { + return apr_pstrcat(cmd->pool, "Option ", w, " not allowed here", NULL); + } + else if (action == '-') { + /* we ensure the invariant (d->opts_add & d->opts_remove) == 0 */ + d->opts_remove |= opt; + d->opts_add &= ~opt; + d->opts &= ~opt; + } + else if (action == '+') { + d->opts_add |= opt; + d->opts_remove &= ~opt; + d->opts |= opt; + } + else { + d->opts |= opt; + } + } + + return NULL; +} + +/* + * Note what data should be used when forming file ETag values. + * It would be nicer to do this as an ITERATE, but then we couldn't + * remember the +/- state properly. + */ +static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, + const char *args_p) +{ + core_dir_config *cfg; + etag_components_t bit; + char action; + char *token; + const char *args; + int valid; + int first; + int explicit; + + cfg = (core_dir_config *)mconfig; + + args = args_p; + first = 1; + explicit = 0; + while (args[0] != '\0') { + action = '*'; + bit = ETAG_UNSET; + valid = 1; + token = ap_getword_conf(cmd->pool, &args); + if ((*token == '+') || (*token == '-')) { + action = *token; + token++; + } + else { + /* + * The occurrence of an absolute setting wipes + * out any previous relative ones. The first such + * occurrence forgets any inherited ones, too. + */ + if (first) { + cfg->etag_bits = ETAG_UNSET; + cfg->etag_add = ETAG_UNSET; + cfg->etag_remove = ETAG_UNSET; + first = 0; + } + } + + if (strcasecmp(token, "None") == 0) { + if (action != '*') { + valid = 0; + } + else { + cfg->etag_bits = bit = ETAG_NONE; + explicit = 1; + } + } + else if (strcasecmp(token, "All") == 0) { + if (action != '*') { + valid = 0; + } + else { + explicit = 1; + cfg->etag_bits = bit = ETAG_ALL; + } + } + else if (strcasecmp(token, "Size") == 0) { + bit = ETAG_SIZE; + } + else if ((strcasecmp(token, "LMTime") == 0) + || (strcasecmp(token, "MTime") == 0) + || (strcasecmp(token, "LastModified") == 0)) { + bit = ETAG_MTIME; + } + else if (strcasecmp(token, "INode") == 0) { + bit = ETAG_INODE; + } + else { + return apr_pstrcat(cmd->pool, "Unknown keyword '", + token, "' for ", cmd->cmd->name, + " directive", NULL); + } + + if (! valid) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, " keyword '", + token, "' cannot be used with '+' or '-'", + NULL); + } + + if (action == '+') { + /* + * Make sure it's in the 'add' list and absent from the + * 'subtract' list. + */ + cfg->etag_add |= bit; + cfg->etag_remove &= (~ bit); + } + else if (action == '-') { + cfg->etag_remove |= bit; + cfg->etag_add &= (~ bit); + } + else { + /* + * Non-relative values wipe out any + or - values + * accumulated so far. + */ + cfg->etag_bits |= bit; + cfg->etag_add = ETAG_UNSET; + cfg->etag_remove = ETAG_UNSET; + explicit = 1; + } + } + + /* + * Any setting at all will clear the 'None' and 'Unset' bits. + */ + + if (cfg->etag_add != ETAG_UNSET) { + cfg->etag_add &= (~ ETAG_UNSET); + } + + if (cfg->etag_remove != ETAG_UNSET) { + cfg->etag_remove &= (~ ETAG_UNSET); + } + + if (explicit) { + cfg->etag_bits &= (~ ETAG_UNSET); + + if ((cfg->etag_bits & ETAG_NONE) != ETAG_NONE) { + cfg->etag_bits &= (~ ETAG_NONE); + } + } + + return NULL; +} + +static const char *set_enable_mmap(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + if (strcasecmp(arg, "on") == 0) { + d->enable_mmap = ENABLE_MMAP_ON; + } + else if (strcasecmp(arg, "off") == 0) { + d->enable_mmap = ENABLE_MMAP_OFF; + } + else { + return "parameter must be 'on' or 'off'"; + } + + return NULL; +} + +static const char *set_enable_sendfile(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + if (strcasecmp(arg, "on") == 0) { + d->enable_sendfile = ENABLE_SENDFILE_ON; + } + else if (strcasecmp(arg, "off") == 0) { + d->enable_sendfile = ENABLE_SENDFILE_OFF; + } + else { + return "parameter must be 'on' or 'off'"; + } + + return NULL; +} + +static const char *satisfy(cmd_parms *cmd, void *c_, const char *arg) +{ + core_dir_config *c = c_; + int satisfy = SATISFY_NOSPEC; + int i; + + if (!strcasecmp(arg, "all")) { + satisfy = SATISFY_ALL; + } + else if (!strcasecmp(arg, "any")) { + satisfy = SATISFY_ANY; + } + else { + return "Satisfy either 'any' or 'all'."; + } + + for (i = 0; i < METHODS; ++i) { + if (cmd->limited & (AP_METHOD_BIT << i)) { + c->satisfy[i] = satisfy; + } + } + + return NULL; +} + +static const char *require(cmd_parms *cmd, void *c_, const char *arg) +{ + require_line *r; + core_dir_config *c = c_; + + if (!c->ap_requires) { + c->ap_requires = apr_array_make(cmd->pool, 2, sizeof(require_line)); + } + + r = (require_line *)apr_array_push(c->ap_requires); + r->requirement = apr_pstrdup(cmd->pool, arg); + r->method_mask = cmd->limited; + + return NULL; +} + +/* + * Report a missing-'>' syntax error. + */ +static char *unclosed_directive(cmd_parms *cmd) +{ + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive missing closing '>'", NULL); +} + +/* + * Report a missing args in '' syntax error. + */ +static char *missing_container_arg(cmd_parms *cmd) +{ + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive requires additional arguments", NULL); +} + +AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + const char *endp = ap_strrchr_c(arg, '>'); + const char *limited_methods; + void *tog = cmd->cmd->cmd_data; + apr_int64_t limited = 0; + const char *errmsg; + + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + limited_methods = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!limited_methods[0]) { + return missing_container_arg(cmd); + } + + while (limited_methods[0]) { + char *method = ap_getword_conf(cmd->pool, &limited_methods); + int methnum; + + /* check for builtin or module registered method number */ + methnum = ap_method_number_of(method); + + if (methnum == M_TRACE && !tog) { + return "TRACE cannot be controlled by "; + } + else if (methnum == M_INVALID) { + /* method has not been registered yet, but resorce restriction + * is always checked before method handling, so register it. + */ + methnum = ap_method_register(cmd->pool, method); + } + + limited |= (AP_METHOD_BIT << methnum); + } + + /* Killing two features with one function, + * if (tog == NULL) , else + */ + cmd->limited = tog ? ~limited : limited; + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context); + + cmd->limited = -1; + + return errmsg; +} + +/* XXX: Bogus - need to do this differently (at least OS2/Netware suffer + * the same problem!!! + * We use this in and , to ensure that + * people don't get bitten by wrong-cased regex matches + */ + +#ifdef WIN32 +#define USE_ICASE AP_REG_ICASE +#else +#define USE_ICASE 0 +#endif + +static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg) +{ + const char *errmsg; + const char *endp = ap_strrchr_c(arg, '>'); + int old_overrides = cmd->override; + char *old_path = cmd->path; + core_dir_config *conf; + ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool); + ap_regex_t *r = NULL; + const command_rec *thiscmd = cmd->cmd; + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + if (!arg) { + if (thiscmd->cmd_data) + return " block must specify a path"; + else + return " block must specify a path"; + } + + cmd->path = ap_getword_conf(cmd->pool, &arg); + cmd->override = OR_ALL|ACCESS_CONF; + + if (!strcmp(cmd->path, "~")) { + cmd->path = ap_getword_conf(cmd->pool, &arg); + if (!cmd->path) + return " block must specify a path"; + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE); + if (!r) { + return "Regex could not be compiled"; + } + } + else if (thiscmd->cmd_data) { /* */ + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE); + if (!r) { + return "Regex could not be compiled"; + } + } + else if (!strcmp(cmd->path, "/") == 0) + { + char *newpath; + + /* + * Ensure that the pathname is canonical, and append the trailing / + */ + apr_status_t rv = apr_filepath_merge(&newpath, NULL, cmd->path, + APR_FILEPATH_TRUENAME, cmd->pool); + if (rv != APR_SUCCESS && rv != APR_EPATHWILD) { + return apr_pstrcat(cmd->pool, "path, + "\"> path is invalid.", NULL); + } + + cmd->path = newpath; + if (cmd->path[strlen(cmd->path) - 1] != '/') + cmd->path = apr_pstrcat(cmd->pool, cmd->path, "/", NULL); + } + + /* initialize our config and fetch it */ + conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path, + &core_module, cmd->pool); + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf); + if (errmsg != NULL) + return errmsg; + + conf->r = r; + conf->d = cmd->path; + conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0); + + /* Make this explicit - the "/" root has 0 elements, that is, we + * will always merge it, and it will always sort and merge first. + * All others are sorted and tested by the number of slashes. + */ + if (strcmp(conf->d, "/") == 0) + conf->d_components = 0; + else + conf->d_components = ap_count_dirs(conf->d); + + ap_add_per_dir_conf(cmd->server, new_dir_conf); + + if (*arg != '\0') { + return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, + "> arguments not (yet) supported.", NULL); + } + + cmd->path = old_path; + cmd->override = old_overrides; + + return NULL; +} + +static const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg) +{ + const char *errmsg; + const char *endp = ap_strrchr_c(arg, '>'); + int old_overrides = cmd->override; + char *old_path = cmd->path; + core_dir_config *conf; + ap_regex_t *r = NULL; + const command_rec *thiscmd = cmd->cmd; + ap_conf_vector_t *new_url_conf = ap_create_per_dir_config(cmd->pool); + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + cmd->path = ap_getword_conf(cmd->pool, &arg); + cmd->override = OR_ALL|ACCESS_CONF; + + if (thiscmd->cmd_data) { /* */ + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED); + if (!r) { + return "Regex could not be compiled"; + } + } + else if (!strcmp(cmd->path, "~")) { + cmd->path = ap_getword_conf(cmd->pool, &arg); + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED); + if (!r) { + return "Regex could not be compiled"; + } + } + + /* initialize our config and fetch it */ + conf = ap_set_config_vectors(cmd->server, new_url_conf, cmd->path, + &core_module, cmd->pool); + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_url_conf); + if (errmsg != NULL) + return errmsg; + + conf->d = apr_pstrdup(cmd->pool, cmd->path); /* No mangling, please */ + conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0; + conf->r = r; + + ap_add_per_url_conf(cmd->server, new_url_conf); + + if (*arg != '\0') { + return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, + "> arguments not (yet) supported.", NULL); + } + + cmd->path = old_path; + cmd->override = old_overrides; + + return NULL; +} + +static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg) +{ + const char *errmsg; + const char *endp = ap_strrchr_c(arg, '>'); + int old_overrides = cmd->override; + char *old_path = cmd->path; + core_dir_config *conf; + ap_regex_t *r = NULL; + const command_rec *thiscmd = cmd->cmd; + core_dir_config *c = mconfig; + ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool); + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_LOCATION); + + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + cmd->path = ap_getword_conf(cmd->pool, &arg); + /* Only if not an .htaccess file */ + if (!old_path) { + cmd->override = OR_ALL|ACCESS_CONF; + } + + if (thiscmd->cmd_data) { /* */ + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE); + if (!r) { + return "Regex could not be compiled"; + } + } + else if (!strcmp(cmd->path, "~")) { + cmd->path = ap_getword_conf(cmd->pool, &arg); + r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE); + if (!r) { + return "Regex could not be compiled"; + } + } + else { + char *newpath; + /* Ensure that the pathname is canonical, but we + * can't test the case/aliases without a fixed path */ + if (apr_filepath_merge(&newpath, "", cmd->path, + 0, cmd->pool) != APR_SUCCESS) + return apr_pstrcat(cmd->pool, "path, + "\"> is invalid.", NULL); + cmd->path = newpath; + } + + /* initialize our config and fetch it */ + conf = ap_set_config_vectors(cmd->server, new_file_conf, cmd->path, + &core_module, cmd->pool); + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_file_conf); + if (errmsg != NULL) + return errmsg; + + conf->d = cmd->path; + conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0; + conf->r = r; + + ap_add_file_conf(c, new_file_conf); + + if (*arg != '\0') { + return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, + "> arguments not (yet) supported.", NULL); + } + + cmd->path = old_path; + cmd->override = old_overrides; + + return NULL; +} + +static const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg) +{ + const char *endp = ap_strrchr_c(arg, '>'); + int not = (arg[0] == '!'); + module *found; + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (not) { + arg++; + } + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + found = ap_find_linked_module(arg); + + /* search prelinked stuff */ + if (!found) { + ap_module_symbol_t *current = ap_prelinked_module_symbols; + + for (; current->name; ++current) { + if (!strcmp(current->name, arg)) { + found = current->modp; + break; + } + } + } + + /* search dynamic stuff */ + if (!found) { + APR_OPTIONAL_FN_TYPE(ap_find_loaded_module_symbol) *check_symbol = + APR_RETRIEVE_OPTIONAL_FN(ap_find_loaded_module_symbol); + + if (check_symbol) { + found = check_symbol(cmd->server, arg); + } + } + + if ((!not && found) || (not && !found)) { + ap_directive_t *parent = NULL; + ap_directive_t *current = NULL; + const char *retval; + + retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, + ¤t, &parent, "elts; + for (i = 0; i < ap_server_config_defines->nelts; i++) { + if (strcmp(defines[i], name) == 0) { + return 1; + } + } + + return 0; +} + +static const char *start_ifdefine(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *endp; + int defined; + int not = 0; + + endp = ap_strrchr_c(arg, '>'); + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (arg[0] == '!') { + not = 1; + arg++; + } + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + defined = ap_exists_config_define(arg); + if ((!not && defined) || (not && !defined)) { + ap_directive_t *parent = NULL; + ap_directive_t *current = NULL; + const char *retval; + + retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, + ¤t, &parent, " business */ + +static const char *virtualhost_section(cmd_parms *cmd, void *dummy, + const char *arg) +{ + server_rec *main_server = cmd->server, *s; + const char *errmsg; + const char *endp = ap_strrchr_c(arg, '>'); + apr_pool_t *p = cmd->pool; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (endp == NULL) { + return unclosed_directive(cmd); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!arg[0]) { + return missing_container_arg(cmd); + } + + /* FIXME: There's another feature waiting to happen here -- since you + can now put multiple addresses/names on a single + you might want to use it to group common definitions and then + define other "subhosts" with their individual differences. But + personally I'd rather just do it with a macro preprocessor. -djg */ + if (main_server->is_virtual) { + return " doesn't nest!"; + } + + errmsg = ap_init_virtual_host(p, arg, main_server, &s); + if (errmsg) { + return errmsg; + } + + s->next = main_server->next; + main_server->next = s; + + s->defn_name = cmd->directive->filename; + s->defn_line_number = cmd->directive->line_num; + + cmd->server = s; + + errmsg = ap_walk_config(cmd->directive->first_child, cmd, + s->lookup_defaults); + + cmd->server = main_server; + + return errmsg; +} + +static const char *set_server_alias(cmd_parms *cmd, void *dummy, + const char *arg) +{ + if (!cmd->server->names) { + return "ServerAlias only used in "; + } + + while (*arg) { + char **item, *name = ap_getword_conf(cmd->pool, &arg); + + if (ap_is_matchexp(name)) { + item = (char **)apr_array_push(cmd->server->wild_names); + } + else { + item = (char **)apr_array_push(cmd->server->names); + } + + *item = name; + } + + return NULL; +} + +static const char *set_server_string_slot(cmd_parms *cmd, void *dummy, + const char *arg) +{ + /* This one's pretty generic... */ + + int offset = (int)(long)cmd->info; + char *struct_ptr = (char *)cmd->server; + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + *(const char **)(struct_ptr + offset) = arg; + return NULL; +} + +static const char *server_hostname_port(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + const char *portstr; + int port; + + if (err != NULL) { + return err; + } + + portstr = ap_strchr_c(arg, ':'); + if (portstr) { + cmd->server->server_hostname = apr_pstrndup(cmd->pool, arg, + portstr - arg); + portstr++; + port = atoi(portstr); + if (port <= 0 || port >= 65536) { /* 65536 == 1<<16 */ + return apr_pstrcat(cmd->temp_pool, "The port number \"", arg, + "\" is outside the appropriate range " + "(i.e., 1..65535).", NULL); + } + } + else { + cmd->server->server_hostname = apr_pstrdup(cmd->pool, arg); + port = 0; + } + + cmd->server->port = port; + return NULL; +} + +static const char *set_signature_flag(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + if (strcasecmp(arg, "On") == 0) { + d->server_signature = srv_sig_on; + } + else if (strcasecmp(arg, "Off") == 0) { + d->server_signature = srv_sig_off; + } + else if (strcasecmp(arg, "EMail") == 0) { + d->server_signature = srv_sig_withmail; + } + else { + return "ServerSignature: use one of: off | on | email"; + } + + return NULL; +} + +static const char *set_server_root(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + if ((apr_filepath_merge((char**)&ap_server_root, NULL, arg, + APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS) + || !ap_is_directory(cmd->pool, ap_server_root)) { + return "ServerRoot must be a valid directory"; + } + + return NULL; +} + +static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + cmd->server->timeout = apr_time_from_sec(atoi(arg)); + return NULL; +} + +static const char *set_allow2f(cmd_parms *cmd, void *d_, int arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + d->allow_encoded_slashes = arg != 0; + return NULL; +} + +static const char *set_hostname_lookups(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + if (!strcasecmp(arg, "on")) { + d->hostname_lookups = HOSTNAME_LOOKUP_ON; + } + else if (!strcasecmp(arg, "off")) { + d->hostname_lookups = HOSTNAME_LOOKUP_OFF; + } + else if (!strcasecmp(arg, "double")) { + d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE; + } + else { + return "parameter must be 'on', 'off', or 'double'"; + } + + return NULL; +} + +static const char *set_serverpath(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + cmd->server->path = arg; + cmd->server->pathlen = (int)strlen(arg); + return NULL; +} + +static const char *set_content_md5(cmd_parms *cmd, void *d_, int arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + d->content_md5 = arg != 0; + return NULL; +} + +static const char *set_accept_path_info(cmd_parms *cmd, void *d_, const char *arg) +{ + core_dir_config *d = d_; + + if (strcasecmp(arg, "on") == 0) { + d->accept_path_info = AP_REQ_ACCEPT_PATH_INFO; + } + else if (strcasecmp(arg, "off") == 0) { + d->accept_path_info = AP_REQ_REJECT_PATH_INFO; + } + else if (strcasecmp(arg, "default") == 0) { + d->accept_path_info = AP_REQ_DEFAULT_PATH_INFO; + } + else { + return "AcceptPathInfo must be set to on, off or default"; + } + + return NULL; +} + +static const char *set_use_canonical_name(cmd_parms *cmd, void *d_, + const char *arg) +{ + core_dir_config *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + if (strcasecmp(arg, "on") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_ON; + } + else if (strcasecmp(arg, "off") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_OFF; + } + else if (strcasecmp(arg, "dns") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_DNS; + } + else { + return "parameter must be 'on', 'off', or 'dns'"; + } + + return NULL; +} + + +static const char *include_config (cmd_parms *cmd, void *dummy, + const char *name) +{ + ap_directive_t *conftree = NULL; + const char* conffile, *error; + unsigned *recursion; + void *data; + + apr_pool_userdata_get(&data, "ap_include_sentinel", cmd->pool); + if (data) { + recursion = data; + } + else { + data = recursion = apr_palloc(cmd->pool, sizeof(*recursion)); + *recursion = 0; + apr_pool_userdata_setn(data, "ap_include_sentinel", NULL, cmd->pool); + } + + if (++*recursion > AP_MAX_INCLUDE_DEPTH) { + *recursion = 0; + return apr_psprintf(cmd->pool, "Exceeded maximum include depth of %u. " + "You have probably a recursion somewhere.", + AP_MAX_INCLUDE_DEPTH); + } + + conffile = ap_server_root_relative(cmd->pool, name); + if (!conffile) { + *recursion = 0; + return apr_pstrcat(cmd->pool, "Invalid Include path ", + name, NULL); + } + + error = ap_process_resource_config(cmd->server, conffile, + &conftree, cmd->pool, cmd->temp_pool); + if (error) { + *recursion = 0; + return error; + } + + *(ap_directive_t **)dummy = conftree; + + /* recursion level done */ + if (*recursion) { + --*recursion; + } + + return NULL; +} + +static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg) +{ + char *str; + + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + + if ((str = ap_getword_conf(cmd->pool, &arg))) { + if (!strcasecmp(str, "emerg")) { + cmd->server->loglevel = APLOG_EMERG; + } + else if (!strcasecmp(str, "alert")) { + cmd->server->loglevel = APLOG_ALERT; + } + else if (!strcasecmp(str, "crit")) { + cmd->server->loglevel = APLOG_CRIT; + } + else if (!strcasecmp(str, "error")) { + cmd->server->loglevel = APLOG_ERR; + } + else if (!strcasecmp(str, "warn")) { + cmd->server->loglevel = APLOG_WARNING; + } + else if (!strcasecmp(str, "notice")) { + cmd->server->loglevel = APLOG_NOTICE; + } + else if (!strcasecmp(str, "info")) { + cmd->server->loglevel = APLOG_INFO; + } + else if (!strcasecmp(str, "debug")) { + cmd->server->loglevel = APLOG_DEBUG; + } + else { + return "LogLevel requires level keyword: one of " + "emerg/alert/crit/error/warn/notice/info/debug"; + } + } + else { + return "LogLevel requires level keyword"; + } + + return NULL; +} + +AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r) +{ + char sport[20]; + core_dir_config *conf; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + if ((conf->server_signature == srv_sig_off) + || (conf->server_signature == srv_sig_unset)) { + return ""; + } + + apr_snprintf(sport, sizeof sport, "%u", (unsigned) ap_get_server_port(r)); + + if (conf->server_signature == srv_sig_withmail) { + return apr_pstrcat(r->pool, prefix, "
    ", + ap_get_server_version(), + " Server at server->server_admin) ? "" : "mailto:", + ap_escape_html(r->pool, r->server->server_admin), + "\">", + ap_escape_html(r->pool, ap_get_server_name(r)), + " Port ", sport, + "
    \n", NULL); + } + + return apr_pstrcat(r->pool, prefix, "
    ", ap_get_server_version(), + " Server at ", + ap_escape_html(r->pool, ap_get_server_name(r)), + " Port ", sport, + "
    \n", NULL); +} + +/* + * Load an authorisation realm into our location configuration, applying the + * usual rules that apply to realms. + */ +static const char *set_authname(cmd_parms *cmd, void *mconfig, + const char *word1) +{ + core_dir_config *aconfig = (core_dir_config *)mconfig; + + aconfig->ap_auth_name = ap_escape_quotes(cmd->pool, word1); + return NULL; +} + +/* + * Handle a request to include the server's OS platform in the Server + * response header field (the ServerTokens directive). Unfortunately + * this requires a new global in order to communicate the setting back to + * http_main so it can insert the information in the right place in the + * string. + */ + +static char *server_version = NULL; +static int version_locked = 0; + +enum server_token_type { + SrvTk_MAJOR, /* eg: Apache/2 */ + SrvTk_MINOR, /* eg. Apache/2.0 */ + SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ + SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ + SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ + SrvTk_PRODUCT_ONLY /* eg: Apache */ +}; +static enum server_token_type ap_server_tokens = SrvTk_FULL; + +static apr_status_t reset_version(void *dummy) +{ + version_locked = 0; + ap_server_tokens = SrvTk_FULL; + server_version = NULL; + return APR_SUCCESS; +} + +AP_DECLARE(void) ap_get_server_revision(ap_version_t *version) +{ + version->major = AP_SERVER_MAJORVERSION_NUMBER; + version->minor = AP_SERVER_MINORVERSION_NUMBER; + version->patch = AP_SERVER_PATCHLEVEL_NUMBER; + version->add_string = AP_SERVER_ADD_STRING; +} + +AP_DECLARE(const char *) ap_get_server_version(void) +{ + return (server_version ? server_version : AP_SERVER_BASEVERSION); +} + +AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component) +{ + if (! version_locked) { + /* + * If the version string is null, register our cleanup to reset the + * pointer on pool destruction. We also know that, if NULL, + * we are adding the original SERVER_BASEVERSION string. + */ + if (server_version == NULL) { + apr_pool_cleanup_register(pconf, NULL, reset_version, + apr_pool_cleanup_null); + server_version = apr_pstrdup(pconf, component); + } + else { + /* + * Tack the given component identifier to the end of + * the existing string. + */ + server_version = apr_pstrcat(pconf, server_version, " ", + component, NULL); + } + } +} + +/* + * This routine adds the real server base identity to the version string, + * and then locks out changes until the next reconfig. + */ +static void ap_set_version(apr_pool_t *pconf) +{ + if (ap_server_tokens == SrvTk_PRODUCT_ONLY) { + ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT); + } + else if (ap_server_tokens == SrvTk_MINIMAL) { + ap_add_version_component(pconf, AP_SERVER_BASEVERSION); + } + else if (ap_server_tokens == SrvTk_MINOR) { + ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MINORREVISION); + } + else if (ap_server_tokens == SrvTk_MAJOR) { + ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION); + } + else { + ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")"); + } + + /* + * Lock the server_version string if we're not displaying + * the full set of tokens + */ + if (ap_server_tokens != SrvTk_FULL) { + version_locked++; + } +} + +static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + if (!strcasecmp(arg, "OS")) { + ap_server_tokens = SrvTk_OS; + } + else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) { + ap_server_tokens = SrvTk_MINIMAL; + } + else if (!strcasecmp(arg, "Major")) { + ap_server_tokens = SrvTk_MAJOR; + } + else if (!strcasecmp(arg, "Minor") ) { + ap_server_tokens = SrvTk_MINOR; + } + else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) { + ap_server_tokens = SrvTk_PRODUCT_ONLY; + } + else { + ap_server_tokens = SrvTk_FULL; + } + + return NULL; +} + +static const char *set_limit_req_line(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + int lim; + + if (err != NULL) { + return err; + } + + lim = atoi(arg); + if (lim < 0) { + return apr_pstrcat(cmd->temp_pool, "LimitRequestLine \"", arg, + "\" must be a non-negative integer", NULL); + } + + cmd->server->limit_req_line = lim; + return NULL; +} + +static const char *set_limit_req_fieldsize(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + int lim; + + if (err != NULL) { + return err; + } + + lim = atoi(arg); + if (lim < 0) { + return apr_pstrcat(cmd->temp_pool, "LimitRequestFieldsize \"", arg, + "\" must be a non-negative integer", + NULL); + } + + cmd->server->limit_req_fieldsize = lim; + return NULL; +} + +static const char *set_limit_req_fields(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + int lim; + + if (err != NULL) { + return err; + } + + lim = atoi(arg); + if (lim < 0) { + return apr_pstrcat(cmd->temp_pool, "LimitRequestFields \"", arg, + "\" must be a non-negative integer (0 = no limit)", + NULL); + } + + cmd->server->limit_req_fields = lim; + return NULL; +} + +static const char *set_limit_req_body(cmd_parms *cmd, void *conf_, + const char *arg) +{ + core_dir_config *conf = conf_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + char *errp; + + if (err != NULL) { + return err; + } + + if (APR_SUCCESS != apr_strtoff(&conf->limit_req_body, arg, &errp, 10)) { + return "LimitRequestBody argument is not parsable."; + } + if (*errp || conf->limit_req_body < 0) { + return "LimitRequestBody requires a non-negative integer."; + } + + return NULL; +} + +static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, + const char *arg) +{ + core_dir_config *conf = conf_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (err != NULL) { + return err; + } + + conf->limit_xml_body = atol(arg); + if (conf->limit_xml_body < 0) + return "LimitXMLRequestBody requires a non-negative integer."; + + return NULL; +} + +AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r) +{ + core_dir_config *conf; + + conf = ap_get_module_config(r->per_dir_config, &core_module); + if (conf->limit_xml_body == AP_LIMIT_UNSET) + return AP_DEFAULT_LIMIT_XML_BODY; + + return (size_t)conf->limit_xml_body; +} + +#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC) +static const char *no_set_limit(cmd_parms *cmd, void *conf_, + const char *arg, const char *arg2) +{ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, + "%s not supported on this platform", cmd->cmd->name); + + return NULL; +} +#endif + +#ifdef RLIMIT_CPU +static const char *set_limit_cpu(cmd_parms *cmd, void *conf_, + const char *arg, const char *arg2) +{ + core_dir_config *conf = conf_; + + unixd_set_rlimit(cmd, &conf->limit_cpu, arg, arg2, RLIMIT_CPU); + return NULL; +} +#endif + +#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) +static const char *set_limit_mem(cmd_parms *cmd, void *conf_, + const char *arg, const char * arg2) +{ + core_dir_config *conf = conf_; + +#if defined(RLIMIT_AS) + unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2 ,RLIMIT_AS); +#elif defined(RLIMIT_DATA) + unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_DATA); +#elif defined(RLIMIT_VMEM) + unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_VMEM); +#endif + + return NULL; +} +#endif + +#ifdef RLIMIT_NPROC +static const char *set_limit_nproc(cmd_parms *cmd, void *conf_, + const char *arg, const char * arg2) +{ + core_dir_config *conf = conf_; + + unixd_set_rlimit(cmd, &conf->limit_nproc, arg, arg2, RLIMIT_NPROC); + return NULL; +} +#endif + +static const char *set_recursion_limit(cmd_parms *cmd, void *dummy, + const char *arg1, const char *arg2) +{ + core_server_config *conf = ap_get_module_config(cmd->server->module_config, + &core_module); + int limit = atoi(arg1); + + if (limit <= 0) { + return "The recursion limit must be greater than zero."; + } + if (limit < 4) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "Limiting internal redirects to very low numbers may " + "cause normal requests to fail."); + } + + conf->redirect_limit = limit; + + if (arg2) { + limit = atoi(arg2); + + if (limit <= 0) { + return "The recursion limit must be greater than zero."; + } + if (limit < 4) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, + "Limiting the subrequest depth to a very low level may" + " cause normal requests to fail."); + } + } + + conf->subreq_limit = limit; + + return NULL; +} + +static void log_backtrace(const request_rec *r) +{ + const request_rec *top = r; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "r->uri = %s", r->uri ? r->uri : "(unexpectedly NULL)"); + + while (top && (top->prev || top->main)) { + if (top->prev) { + top = top->prev; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "redirected from r->uri = %s", + top->uri ? top->uri : "(unexpectedly NULL)"); + } + + if (!top->prev && top->main) { + top = top->main; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "subrequested from r->uri = %s", + top->uri ? top->uri : "(unexpectedly NULL)"); + } + } +} + +/* + * check whether redirect limit is reached + */ +AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r) +{ + core_server_config *conf = ap_get_module_config(r->server->module_config, + &core_module); + const request_rec *top = r; + int redirects = 0, subreqs = 0; + int rlimit = conf->redirect_limit + ? conf->redirect_limit + : AP_DEFAULT_MAX_INTERNAL_REDIRECTS; + int slimit = conf->subreq_limit + ? conf->subreq_limit + : AP_DEFAULT_MAX_SUBREQ_DEPTH; + + + while (top->prev || top->main) { + if (top->prev) { + if (++redirects >= rlimit) { + /* uuh, too much. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Request exceeded the limit of %d internal " + "redirects due to probable configuration error. " + "Use 'LimitInternalRecursion' to increase the " + "limit if necessary. Use 'LogLevel debug' to get " + "a backtrace.", rlimit); + + /* post backtrace */ + log_backtrace(r); + + /* return failure */ + return 1; + } + + top = top->prev; + } + + if (!top->prev && top->main) { + if (++subreqs >= slimit) { + /* uuh, too much. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Request exceeded the limit of %d subrequest " + "nesting levels due to probable confguration " + "error. Use 'LimitInternalRecursion' to increase " + "the limit if necessary. Use 'LogLevel debug' to " + "get a backtrace.", slimit); + + /* post backtrace */ + log_backtrace(r); + + /* return failure */ + return 1; + } + + top = top->main; + } + } + + /* recursion state: ok */ + return 0; +} + +static const char *add_ct_output_filters(cmd_parms *cmd, void *conf_, + const char *arg, const char *arg2) +{ + core_dir_config *conf = conf_; + ap_filter_rec_t *old, *new = NULL; + const char *filter_name; + + if (!conf->ct_output_filters) { + conf->ct_output_filters = apr_hash_make(cmd->pool); + old = NULL; + } + else { + old = (ap_filter_rec_t*) apr_hash_get(conf->ct_output_filters, arg2, + APR_HASH_KEY_STRING); + /* find last entry */ + if (old) { + while (old->next) { + old = old->next; + } + } + } + + while (*arg && + (filter_name = ap_getword(cmd->pool, &arg, ';')) && + strcmp(filter_name, "")) { + new = apr_pcalloc(cmd->pool, sizeof(ap_filter_rec_t)); + new->name = filter_name; + + /* We found something, so let's append it. */ + if (old) { + old->next = new; + } + else { + apr_hash_set(conf->ct_output_filters, arg2, + APR_HASH_KEY_STRING, new); + } + old = new; + } + + if (!new) { + return "invalid filter name"; + } + + return NULL; +} +/* + * Insert filters requested by the AddOutputFilterByType + * configuration directive. We cannot add filters based + * on content-type until after the handler has started + * to run. Only then do we reliably know the content-type. + */ +void ap_add_output_filters_by_type(request_rec *r) +{ + core_dir_config *conf; + const char *ctype; + + conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + /* We can't do anything with proxy requests, no content-types or if + * we don't have a filter configured. + */ + if (r->proxyreq != PROXYREQ_NONE || !r->content_type || + !conf->ct_output_filters) { + return; + } + + /* remove c-t decoration */ + ctype = ap_field_noparam(r->pool, r->content_type); + if (ctype) { + ap_filter_rec_t *ct_filter; + ct_filter = apr_hash_get(conf->ct_output_filters, ctype, + APR_HASH_KEY_STRING); + while (ct_filter) { + ap_add_output_filter(ct_filter->name, NULL, r, r->connection); + ct_filter = ct_filter->next; + } + } + + return; +} + +/* Note --- ErrorDocument will now work from .htaccess files. + * The AllowOverride of Fileinfo allows webmasters to turn it off + */ + +static const command_rec core_cmds[] = { + +/* Old access config file commands */ + +AP_INIT_RAW_ARGS("server->module_config; + core_server_config *conf = ap_get_module_config(sconf, &core_module); + apr_status_t rv; + + /* XXX this seems too specific, this should probably become + * some general-case test + */ + if (r->proxyreq) { + return HTTP_FORBIDDEN; + } + if (!r->uri || ((r->uri[0] != '/') && strcmp(r->uri, "*"))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid URI in request %s", r->the_request); + return HTTP_BAD_REQUEST; + } + + if (r->server->path + && !strncmp(r->uri, r->server->path, r->server->pathlen) + && (r->server->path[r->server->pathlen - 1] == '/' + || r->uri[r->server->pathlen] == '/' + || r->uri[r->server->pathlen] == '\0')) + { + /* skip all leading /'s (e.g. http://localhost///foo) + * so we are looking at only the relative path. + */ + char *path = r->uri + r->server->pathlen; + while (*path == '/') { + ++path; + } + if ((rv = apr_filepath_merge(&r->filename, conf->ap_document_root, path, + APR_FILEPATH_TRUENAME + | APR_FILEPATH_SECUREROOT, r->pool)) + != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Cannot map %s to file", r->the_request); + return HTTP_FORBIDDEN; + } + r->canonical_filename = r->filename; + } + else { + /* + * Make sure that we do not mess up the translation by adding two + * /'s in a row. This happens under windows when the document + * root ends with a / + */ + /* skip all leading /'s (e.g. http://localhost///foo) + * so we are looking at only the relative path. + */ + char *path = r->uri; + while (*path == '/') { + ++path; + } + if ((rv = apr_filepath_merge(&r->filename, conf->ap_document_root, path, + APR_FILEPATH_TRUENAME + | APR_FILEPATH_SECUREROOT, r->pool)) + != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "Cannot map %s to file", r->the_request); + return HTTP_FORBIDDEN; + } + r->canonical_filename = r->filename; + } + + return OK; +} + +/***************************************************************** + * + * Test the filesystem name through directory_walk and file_walk + */ +static int core_map_to_storage(request_rec *r) +{ + int access_status; + + if ((access_status = ap_directory_walk(r))) { + return access_status; + } + + if ((access_status = ap_file_walk(r))) { + return access_status; + } + + return OK; +} + + +static int do_nothing(request_rec *r) { return OK; } + + +static int core_override_type(request_rec *r) +{ + core_dir_config *conf = + (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + /* Check for overrides with ForceType / SetHandler + */ + if (conf->mime_type && strcmp(conf->mime_type, "none")) + ap_set_content_type(r, (char*) conf->mime_type); + + if (conf->handler && strcmp(conf->handler, "none")) + r->handler = conf->handler; + + /* Deal with the poor soul who is trying to force path_info to be + * accepted within the core_handler, where they will let the subreq + * address its contents. This is toggled by the user in the very + * beginning of the fixup phase, so modules should override the user's + * discretion in their own module fixup phase. It is tristate, if + * the user doesn't specify, the result is 2 (which the module may + * interpret to its own customary behavior.) It won't be touched + * if the value is no longer undefined (2), so any module changing + * the value prior to the fixup phase OVERRIDES the user's choice. + */ + if ((r->used_path_info == AP_REQ_DEFAULT_PATH_INFO) + && (conf->accept_path_info != 3)) { + r->used_path_info = conf->accept_path_info; + } + + return OK; +} + +static int default_handler(request_rec *r) +{ + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *e; + core_dir_config *d; + int errstatus; + apr_file_t *fd = NULL; + apr_status_t status; + /* XXX if/when somebody writes a content-md5 filter we either need to + * remove this support or coordinate when to use the filter vs. + * when to use this code + * The current choice of when to compute the md5 here matches the 1.3 + * support fairly closely (unlike 1.3, we don't handle computing md5 + * when the charset is translated). + */ + int bld_content_md5; + + d = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + bld_content_md5 = (d->content_md5 & 1) + && r->output_filters->frec->ftype != AP_FTYPE_RESOURCE; + + ap_allow_standard_methods(r, MERGE_ALLOW, M_GET, M_OPTIONS, M_POST, -1); + + /* If filters intend to consume the request body, they must + * register an InputFilter to slurp the contents of the POST + * data from the POST input stream. It no longer exists when + * the output filters are invoked by the default handler. + */ + if ((errstatus = ap_discard_request_body(r)) != OK) { + return errstatus; + } + + if (r->method_number == M_GET || r->method_number == M_POST) { + if (r->finfo.filetype == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "File does not exist: %s", r->filename); + return HTTP_NOT_FOUND; + } + + /* Don't try to serve a dir. Some OSs do weird things with + * raw I/O on a dir. + */ + if (r->finfo.filetype == APR_DIR) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Attempt to serve directory: %s", r->filename); + return HTTP_NOT_FOUND; + } + + if ((r->used_path_info != AP_REQ_ACCEPT_PATH_INFO) && + r->path_info && *r->path_info) + { + /* default to reject */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "File does not exist: %s", + apr_pstrcat(r->pool, r->filename, r->path_info, NULL)); + return HTTP_NOT_FOUND; + } + + /* We understood the (non-GET) method, but it might not be legal for + this particular resource. Check to see if the 'deliver_script' + flag is set. If so, then we go ahead and deliver the file since + it isn't really content (only GET normally returns content). + + Note: based on logic further above, the only possible non-GET + method at this point is POST. In the future, we should enable + script delivery for all methods. */ + if (r->method_number != M_GET) { + core_request_config *req_cfg; + + req_cfg = ap_get_module_config(r->request_config, &core_module); + if (!req_cfg->deliver_script) { + /* The flag hasn't been set for this request. Punt. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "This resource does not accept the %s method.", + r->method); + return HTTP_METHOD_NOT_ALLOWED; + } + } + + + if ((status = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY +#if APR_HAS_SENDFILE + | ((d->enable_sendfile == ENABLE_SENDFILE_OFF) + ? 0 : APR_SENDFILE_ENABLED) +#endif + , 0, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "file permissions deny server access: %s", r->filename); + return HTTP_FORBIDDEN; + } + + ap_update_mtime(r, r->finfo.mtime); + ap_set_last_modified(r); + ap_set_etag(r); + apr_table_setn(r->headers_out, "Accept-Ranges", "bytes"); + ap_set_content_length(r, r->finfo.size); + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + + if ((errstatus = ap_meets_conditions(r)) != OK) { + apr_file_close(fd); + r->status = errstatus; + } + else { + if (bld_content_md5) { + apr_table_setn(r->headers_out, "Content-MD5", + ap_md5digest(r->pool, fd)); + } + + /* For platforms where the size of the file may be larger than + * that which can be stored in a single bucket (where the + * length field is an apr_size_t), split it into several + * buckets: */ + if (sizeof(apr_off_t) > sizeof(apr_size_t) + && r->finfo.size > AP_MAX_SENDFILE) { + apr_off_t fsize = r->finfo.size; + e = apr_bucket_file_create(fd, 0, AP_MAX_SENDFILE, r->pool, + c->bucket_alloc); + while (fsize > AP_MAX_SENDFILE) { + apr_bucket *ce; + apr_bucket_copy(e, &ce); + APR_BRIGADE_INSERT_TAIL(bb, ce); + e->start += AP_MAX_SENDFILE; + fsize -= AP_MAX_SENDFILE; + } + e->length = (apr_size_t)fsize; /* Resize just the last bucket */ + } + else { + e = apr_bucket_file_create(fd, 0, (apr_size_t)r->finfo.size, + r->pool, c->bucket_alloc); + } + +#if APR_HAS_MMAP + if (d->enable_mmap == ENABLE_MMAP_OFF) { + (void)apr_bucket_file_enable_mmap(e, 0); + } +#endif + APR_BRIGADE_INSERT_TAIL(bb, e); + } + + e = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + + return ap_pass_brigade(r->output_filters, bb); + } + else { /* unusual method (not GET or POST) */ + if (r->method_number == M_INVALID) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Invalid method in request %s", r->the_request); + return HTTP_NOT_IMPLEMENTED; + } + + if (r->method_number == M_OPTIONS) { + return ap_send_http_options(r); + } + return HTTP_METHOD_NOT_ALLOWED; + } +} + +/* Optional function coming from mod_logio, used for logging of output + * traffic + */ +APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out; + +static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out); + ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup); + + ap_set_version(pconf); + ap_setup_make_content_type(pconf); + return OK; +} + +static void core_insert_filter(request_rec *r) +{ + core_dir_config *conf = (core_dir_config *) + ap_get_module_config(r->per_dir_config, + &core_module); + const char *filter, *filters = conf->output_filters; + + if (filters) { + while (*filters && (filter = ap_getword(r->pool, &filters, ';'))) { + ap_add_output_filter(filter, NULL, r, r->connection); + } + } + + filters = conf->input_filters; + if (filters) { + while (*filters && (filter = ap_getword(r->pool, &filters, ';'))) { + ap_add_input_filter(filter, NULL, r, r->connection); + } + } +} + +static apr_size_t num_request_notes = AP_NUM_STD_NOTES; + +static apr_status_t reset_request_notes(void *dummy) +{ + num_request_notes = AP_NUM_STD_NOTES; + return APR_SUCCESS; +} + +AP_DECLARE(apr_size_t) ap_register_request_note(void) +{ + apr_pool_cleanup_register(apr_hook_global_pool, NULL, reset_request_notes, + apr_pool_cleanup_null); + return num_request_notes++; +} + +AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num) +{ + core_request_config *req_cfg; + + if (note_num >= num_request_notes) { + return NULL; + } + + req_cfg = (core_request_config *) + ap_get_module_config(r->request_config, &core_module); + + if (!req_cfg) { + return NULL; + } + + return &(req_cfg->notes[note_num]); +} + +static int core_create_req(request_rec *r) +{ + /* Alloc the config struct and the array of request notes in + * a single block for efficiency + */ + core_request_config *req_cfg; + + req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config) + + sizeof(void *) * num_request_notes); + req_cfg->notes = (void **)((char *)req_cfg + sizeof(core_request_config)); + + /* ### temporarily enable script delivery as the default */ + req_cfg->deliver_script = 1; + + if (r->main) { + core_request_config *main_req_cfg = (core_request_config *) + ap_get_module_config(r->main->request_config, &core_module); + req_cfg->bb = main_req_cfg->bb; + } + else { + req_cfg->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + if (!r->prev) { + ap_add_input_filter_handle(ap_net_time_filter_handle, + NULL, r, r->connection); + } + } + + ap_set_module_config(r->request_config, &core_module, req_cfg); + + /* Begin by presuming any module can make its own path_info assumptions, + * until some module interjects and changes the value. + */ + r->used_path_info = AP_REQ_DEFAULT_PATH_INFO; + + return OK; +} + +static int core_create_proxy_req(request_rec *r, request_rec *pr) +{ + return core_create_req(pr); +} + +static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, + apr_socket_t *csd, long id, void *sbh, + apr_bucket_alloc_t *alloc) +{ + apr_status_t rv; + conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); + + c->sbh = sbh; + (void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL); + + /* Got a connection structure, so initialize what fields we can + * (the rest are zeroed out by pcalloc). + */ + c->conn_config = ap_create_conn_config(ptrans); + c->notes = apr_table_make(ptrans, 5); + + c->pool = ptrans; + if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_LOCAL)"); + apr_socket_close(csd); + return NULL; + } + + apr_sockaddr_ip_get(&c->local_ip, c->local_addr); + if ((rv = apr_socket_addr_get(&c->remote_addr, APR_REMOTE, csd)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, + "apr_socket_addr_get(APR_REMOTE)"); + apr_socket_close(csd); + return NULL; + } + + apr_sockaddr_ip_get(&c->remote_ip, c->remote_addr); + c->base_server = server; + + c->id = id; + c->bucket_alloc = alloc; + + return c; +} + +static int core_pre_connection(conn_rec *c, void *csd) +{ + core_net_rec *net = apr_palloc(c->pool, sizeof(*net)); + +#ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + apr_status_t rv; + + /* The Nagle algorithm says that we should delay sending partial + * packets in hopes of getting more data. We don't want to do + * this; we are not telnet. There are bad interactions between + * persistent connections and Nagle's algorithm that have very severe + * performance penalties. (Failing to disable Nagle is not much of a + * problem with simple HTTP.) + */ + rv = apr_socket_opt_set(csd, APR_TCP_NODELAY, 1); + if (rv != APR_SUCCESS && rv != APR_ENOTIMPL) { + /* expected cause is that the client disconnected already, + * hence the debug level + */ + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, + "apr_socket_opt_set(APR_TCP_NODELAY)"); + } +#endif + net->c = c; + net->in_ctx = NULL; + net->out_ctx = NULL; + net->client_socket = csd; + + ap_set_module_config(net->c->conn_config, &core_module, csd); + ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c); + ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c); + return DONE; +} + +static void register_hooks(apr_pool_t *p) +{ + /* create_connection and install_transport_filters are + * hooks that should always be APR_HOOK_REALLY_LAST to give other + * modules the opportunity to install alternate network transports + * and stop other functions from being run. + */ + ap_hook_create_connection(core_create_conn, NULL, NULL, + APR_HOOK_REALLY_LAST); + ap_hook_pre_connection(core_pre_connection, NULL, NULL, + APR_HOOK_REALLY_LAST); + + ap_hook_post_config(core_post_config,NULL,NULL,APR_HOOK_REALLY_FIRST); + ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_open_logs(ap_open_logs,NULL,NULL,APR_HOOK_REALLY_FIRST); + ap_hook_child_init(ap_logs_child_init,NULL,NULL,APR_HOOK_MIDDLE); + ap_hook_handler(default_handler,NULL,NULL,APR_HOOK_REALLY_LAST); + /* FIXME: I suspect we can eliminate the need for these do_nothings - Ben */ + ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_fixups(core_override_type,NULL,NULL,APR_HOOK_REALLY_FIRST); + ap_hook_access_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST); + ap_hook_create_request(core_create_req, NULL, NULL, APR_HOOK_MIDDLE); + APR_OPTIONAL_HOOK(proxy, create_req, core_create_proxy_req, NULL, NULL, + APR_HOOK_MIDDLE); + ap_hook_pre_mpm(ap_create_scoreboard, NULL, NULL, APR_HOOK_MIDDLE); + + /* register the core's insert_filter hook and register core-provided + * filters + */ + ap_hook_insert_filter(core_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); + + ap_core_input_filter_handle = + ap_register_input_filter("CORE_IN", ap_core_input_filter, + NULL, AP_FTYPE_NETWORK); + ap_net_time_filter_handle = + ap_register_input_filter("NET_TIME", ap_net_time_filter, + NULL, AP_FTYPE_PROTOCOL); + ap_content_length_filter_handle = + ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter, + NULL, AP_FTYPE_PROTOCOL); + ap_core_output_filter_handle = + ap_register_output_filter("CORE", ap_core_output_filter, + NULL, AP_FTYPE_NETWORK); + ap_subreq_core_filter_handle = + ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter, + NULL, AP_FTYPE_CONTENT_SET); + ap_old_write_func = + ap_register_output_filter("OLD_WRITE", ap_old_write_filter, + NULL, AP_FTYPE_RESOURCE - 10); +} + +AP_DECLARE_DATA module core_module = { + STANDARD20_MODULE_STUFF, + create_core_dir_config, /* create per-directory config structure */ + merge_core_dir_configs, /* merge per-directory config structures */ + create_core_server_config, /* create per-server config structure */ + merge_core_server_configs, /* merge per-server config structures */ + core_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + diff --git a/trunk/server/core_filters.c b/trunk/server/core_filters.c new file mode 100644 index 0000000000..e17a1806c4 --- /dev/null +++ b/trunk/server/core_filters.c @@ -0,0 +1,960 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * core_filters.c --- Core input/output network filters. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_fnmatch.h" +#include "apr_hash.h" +#include "apr_thread_proc.h" /* for RLIMIT stuff */ +#include "apr_hooks.h" + +#define APR_WANT_IOVEC +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" /* For index_of_response(). Grump. */ +#include "http_request.h" +#include "http_vhost.h" +#include "http_main.h" /* For the default_handler below... */ +#include "http_log.h" +#include "util_md5.h" +#include "http_connection.h" +#include "apr_buckets.h" +#include "util_filter.h" +#include "util_ebcdic.h" +#include "mpm.h" +#include "mpm_common.h" +#include "scoreboard.h" +#include "mod_core.h" +#include "mod_proxy.h" +#include "ap_listen.h" + +#include "mod_so.h" /* for ap_find_loaded_module_symbol */ + +#define AP_MIN_SENDFILE_BYTES (256) + +typedef struct net_time_filter_ctx { + apr_socket_t *csd; + int first_line; +} net_time_filter_ctx_t; + +int ap_net_time_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) +{ + net_time_filter_ctx_t *ctx = f->ctx; + int keptalive = f->c->keepalive == AP_CONN_KEEPALIVE; + + if (!ctx) { + f->ctx = ctx = apr_palloc(f->r->pool, sizeof(*ctx)); + ctx->first_line = 1; + ctx->csd = ap_get_module_config(f->c->conn_config, &core_module); + } + + if (mode != AP_MODE_INIT && mode != AP_MODE_EATCRLF) { + if (ctx->first_line) { + apr_socket_timeout_set(ctx->csd, + keptalive + ? f->c->base_server->keep_alive_timeout + : f->c->base_server->timeout); + ctx->first_line = 0; + } + else { + if (keptalive) { + apr_socket_timeout_set(ctx->csd, f->c->base_server->timeout); + } + } + } + return ap_get_brigade(f->next, b, mode, block, readbytes); +} + +/** + * Remove all zero length buckets from the brigade. + */ +#define BRIGADE_NORMALIZE(b) \ +do { \ + apr_bucket *e = APR_BRIGADE_FIRST(b); \ + do { \ + if (e->length == 0 && !APR_BUCKET_IS_METADATA(e)) { \ + apr_bucket *d; \ + d = APR_BUCKET_NEXT(e); \ + apr_bucket_delete(e); \ + e = d; \ + } \ + else { \ + e = APR_BUCKET_NEXT(e); \ + } \ + } while (!APR_BRIGADE_EMPTY(b) && (e != APR_BRIGADE_SENTINEL(b))); \ +} while (0) + + +/** + * Split the contents of a brigade after bucket 'e' to an existing brigade + * + * XXXX: Should this function be added to APR-Util? + */ +static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a, + apr_bucket *e) +{ + apr_bucket *f; + + if (e != APR_BRIGADE_SENTINEL(b)) { + f = APR_RING_LAST(&b->list); + APR_RING_UNSPLICE(e, f, link); + APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link); + } + + APR_BRIGADE_CHECK_CONSISTENCY(a); + APR_BRIGADE_CHECK_CONSISTENCY(b); +} + +int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) +{ + apr_bucket *e; + apr_status_t rv; + core_net_rec *net = f->ctx; + core_ctx_t *ctx = net->in_ctx; + const char *str; + apr_size_t len; + + if (mode == AP_MODE_INIT) { + /* + * this mode is for filters that might need to 'initialize' + * a connection before reading request data from a client. + * NNTP over SSL for example needs to handshake before the + * server sends the welcome message. + * such filters would have changed the mode before this point + * is reached. however, protocol modules such as NNTP should + * not need to know anything about SSL. given the example, if + * SSL is not in the filter chain, AP_MODE_INIT is a noop. + */ + return APR_SUCCESS; + } + + if (!ctx) + { + ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); + ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); + ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc); + /* seed the brigade with the client socket. */ + e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(ctx->b, e); + net->in_ctx = ctx; + } + else if (APR_BRIGADE_EMPTY(ctx->b)) { + return APR_EOF; + } + + /* ### This is bad. */ + BRIGADE_NORMALIZE(ctx->b); + + /* check for empty brigade again *AFTER* BRIGADE_NORMALIZE() + * If we have lost our socket bucket (see above), we are EOF. + * + * Ideally, this should be returning SUCCESS with EOS bucket, but + * some higher-up APIs (spec. read_request_line via ap_rgetline) + * want an error code. */ + if (APR_BRIGADE_EMPTY(ctx->b)) { + return APR_EOF; + } + + if (mode == AP_MODE_GETLINE) { + /* we are reading a single LF line, e.g. the HTTP headers */ + rv = apr_brigade_split_line(b, ctx->b, block, HUGE_STRING_LEN); + /* We should treat EAGAIN here the same as we do for EOF (brigade is + * empty). We do this by returning whatever we have read. This may + * or may not be bogus, but is consistent (for now) with EOF logic. + */ + if (APR_STATUS_IS_EAGAIN(rv)) { + rv = APR_SUCCESS; + } + return rv; + } + + /* ### AP_MODE_PEEK is a horrific name for this mode because we also + * eat any CRLFs that we see. That's not the obvious intention of + * this mode. Determine whether anyone actually uses this or not. */ + if (mode == AP_MODE_EATCRLF) { + apr_bucket *e; + const char *c; + + /* The purpose of this loop is to ignore any CRLF (or LF) at the end + * of a request. Many browsers send extra lines at the end of POST + * requests. We use the PEEK method to determine if there is more + * data on the socket, so that we know if we should delay sending the + * end of one request until we have served the second request in a + * pipelined situation. We don't want to actually delay sending a + * response if the server finds a CRLF (or LF), becuause that doesn't + * mean that there is another request, just a blank line. + */ + while (1) { + if (APR_BRIGADE_EMPTY(ctx->b)) + return APR_EOF; + + e = APR_BRIGADE_FIRST(ctx->b); + + rv = apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ); + + if (rv != APR_SUCCESS) + return rv; + + c = str; + while (c < str + len) { + if (*c == APR_ASCII_LF) + c++; + else if (*c == APR_ASCII_CR && *(c + 1) == APR_ASCII_LF) + c += 2; + else + return APR_SUCCESS; + } + + /* If we reach here, we were a bucket just full of CRLFs, so + * just toss the bucket. */ + /* FIXME: Is this the right thing to do in the core? */ + apr_bucket_delete(e); + } + return APR_SUCCESS; + } + + /* If mode is EXHAUSTIVE, we want to just read everything until the end + * of the brigade, which in this case means the end of the socket. + * To do this, we attach the brigade that has currently been setaside to + * the brigade that was passed down, and send that brigade back. + * + * NOTE: This is VERY dangerous to use, and should only be done with + * extreme caution. However, the Perchild MPM needs this feature + * if it is ever going to work correctly again. With this, the Perchild + * MPM can easily request the socket and all data that has been read, + * which means that it can pass it to the correct child process. + */ + if (mode == AP_MODE_EXHAUSTIVE) { + apr_bucket *e; + + /* Tack on any buckets that were set aside. */ + APR_BRIGADE_CONCAT(b, ctx->b); + + /* Since we've just added all potential buckets (which will most + * likely simply be the socket bucket) we know this is the end, + * so tack on an EOS too. */ + /* We have read until the brigade was empty, so we know that we + * must be EOS. */ + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + return APR_SUCCESS; + } + + /* read up to the amount they specified. */ + if (mode == AP_MODE_READBYTES || mode == AP_MODE_SPECULATIVE) { + apr_bucket *e; + + AP_DEBUG_ASSERT(readbytes > 0); + + e = APR_BRIGADE_FIRST(ctx->b); + rv = apr_bucket_read(e, &str, &len, block); + + if (APR_STATUS_IS_EAGAIN(rv)) { + return APR_SUCCESS; + } + else if (rv != APR_SUCCESS) { + return rv; + } + else if (block == APR_BLOCK_READ && len == 0) { + /* We wanted to read some bytes in blocking mode. We read + * 0 bytes. Hence, we now assume we are EOS. + * + * When we are in normal mode, return an EOS bucket to the + * caller. + * When we are in speculative mode, leave ctx->b empty, so + * that the next call returns an EOS bucket. + */ + apr_bucket_delete(e); + + if (mode == AP_MODE_READBYTES) { + e = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(b, e); + } + return APR_SUCCESS; + } + + /* We can only return at most what we read. */ + if (len < readbytes) { + readbytes = len; + } + + rv = apr_brigade_partition(ctx->b, readbytes, &e); + if (rv != APR_SUCCESS) { + return rv; + } + + /* Must do move before CONCAT */ + brigade_move(ctx->b, ctx->tmpbb, e); + + if (mode == AP_MODE_READBYTES) { + APR_BRIGADE_CONCAT(b, ctx->b); + } + else if (mode == AP_MODE_SPECULATIVE) { + apr_bucket *copy_bucket; + + for (e = APR_BRIGADE_FIRST(ctx->b); + e != APR_BRIGADE_SENTINEL(ctx->b); + e = APR_BUCKET_NEXT(e)) + { + rv = apr_bucket_copy(e, ©_bucket); + if (rv != APR_SUCCESS) { + return rv; + } + APR_BRIGADE_INSERT_TAIL(b, copy_bucket); + } + } + + /* Take what was originally there and place it back on ctx->b */ + APR_BRIGADE_CONCAT(ctx->b, ctx->tmpbb); + } + return APR_SUCCESS; +} + +static apr_status_t writev_it_all(apr_socket_t *s, + struct iovec *vec, int nvec, + apr_size_t len, apr_size_t *nbytes) +{ + apr_size_t bytes_written = 0; + apr_status_t rv; + apr_size_t n = len; + int i = 0; + + *nbytes = 0; + + /* XXX handle checking for non-blocking socket */ + while (bytes_written != len) { + rv = apr_socket_sendv(s, vec + i, nvec - i, &n); + *nbytes += n; + bytes_written += n; + if (rv != APR_SUCCESS) + return rv; + + /* If the write did not complete, adjust the iovecs and issue + * apr_socket_sendv again + */ + if (bytes_written < len) { + /* Skip over the vectors that have already been written */ + apr_size_t cnt = vec[i].iov_len; + while (n >= cnt && i + 1 < nvec) { + i++; + cnt += vec[i].iov_len; + } + + if (n < cnt) { + /* Handle partial write of vec i */ + vec[i].iov_base = (char *) vec[i].iov_base + + (vec[i].iov_len - (cnt - n)); + vec[i].iov_len = cnt -n; + } + } + + n = len - bytes_written; + } + + return APR_SUCCESS; +} + +/* sendfile_it_all() + * send the entire file using sendfile() + * handle partial writes + * return only when all bytes have been sent or an error is encountered. + */ + +#if APR_HAS_SENDFILE +static apr_status_t sendfile_it_all(core_net_rec *c, + apr_file_t *fd, + apr_hdtr_t *hdtr, + apr_off_t file_offset, + apr_size_t file_bytes_left, + apr_size_t total_bytes_left, + apr_size_t *bytes_sent, + apr_int32_t flags) +{ + apr_status_t rv; +#ifdef AP_DEBUG + apr_interval_time_t timeout = 0; +#endif + + AP_DEBUG_ASSERT((apr_socket_timeout_get(c->client_socket, &timeout) + == APR_SUCCESS) + && timeout > 0); /* socket must be in timeout mode */ + + /* Reset the bytes_sent field */ + *bytes_sent = 0; + + do { + apr_size_t tmplen = file_bytes_left; + + rv = apr_socket_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen, + flags); + *bytes_sent += tmplen; + total_bytes_left -= tmplen; + if (!total_bytes_left || rv != APR_SUCCESS) { + return rv; /* normal case & error exit */ + } + + AP_DEBUG_ASSERT(total_bytes_left > 0 && tmplen > 0); + + /* partial write, oooh noooo... + * Skip over any header data which was written + */ + while (tmplen && hdtr->numheaders) { + if (tmplen >= hdtr->headers[0].iov_len) { + tmplen -= hdtr->headers[0].iov_len; + --hdtr->numheaders; + ++hdtr->headers; + } + else { + char *iov_base = (char *)hdtr->headers[0].iov_base; + + hdtr->headers[0].iov_len -= tmplen; + iov_base += tmplen; + hdtr->headers[0].iov_base = iov_base; + tmplen = 0; + } + } + + /* Skip over any file data which was written */ + + if (tmplen <= file_bytes_left) { + file_offset += tmplen; + file_bytes_left -= tmplen; + continue; + } + + tmplen -= file_bytes_left; + file_bytes_left = 0; + file_offset = 0; + + /* Skip over any trailer data which was written */ + + while (tmplen && hdtr->numtrailers) { + if (tmplen >= hdtr->trailers[0].iov_len) { + tmplen -= hdtr->trailers[0].iov_len; + --hdtr->numtrailers; + ++hdtr->trailers; + } + else { + char *iov_base = (char *)hdtr->trailers[0].iov_base; + + hdtr->trailers[0].iov_len -= tmplen; + iov_base += tmplen; + hdtr->trailers[0].iov_base = iov_base; + tmplen = 0; + } + } + } while (1); +} +#endif + +/* + * emulate_sendfile() + * Sends the contents of file fd along with header/trailer bytes, if any, + * to the network. emulate_sendfile will return only when all the bytes have been + * sent (i.e., it handles partial writes) or on a network error condition. + */ +static apr_status_t emulate_sendfile(core_net_rec *c, apr_file_t *fd, + apr_hdtr_t *hdtr, apr_off_t offset, + apr_size_t length, apr_size_t *nbytes) +{ + apr_status_t rv = APR_SUCCESS; + apr_size_t togo; /* Remaining number of bytes in the file to send */ + apr_size_t sendlen = 0; + apr_size_t bytes_sent; + apr_int32_t i; + apr_off_t o; /* Track the file offset for partial writes */ + char buffer[8192]; + + *nbytes = 0; + + /* Send the headers + * writev_it_all handles partial writes. + * XXX: optimization... if headers are less than MIN_WRITE_SIZE, copy + * them into buffer + */ + if (hdtr && hdtr->numheaders > 0 ) { + for (i = 0; i < hdtr->numheaders; i++) { + sendlen += hdtr->headers[i].iov_len; + } + + rv = writev_it_all(c->client_socket, hdtr->headers, hdtr->numheaders, + sendlen, &bytes_sent); + *nbytes += bytes_sent; /* track total bytes sent */ + } + + /* Seek the file to 'offset' */ + if (offset >= 0 && rv == APR_SUCCESS) { + rv = apr_file_seek(fd, APR_SET, &offset); + } + + /* Send the file, making sure to handle partial writes */ + togo = length; + while (rv == APR_SUCCESS && togo) { + sendlen = togo > sizeof(buffer) ? sizeof(buffer) : togo; + o = 0; + rv = apr_file_read(fd, buffer, &sendlen); + while (rv == APR_SUCCESS && sendlen) { + bytes_sent = sendlen; + rv = apr_socket_send(c->client_socket, &buffer[o], &bytes_sent); + *nbytes += bytes_sent; + if (rv == APR_SUCCESS) { + sendlen -= bytes_sent; /* sendlen != bytes_sent ==> partial write */ + o += bytes_sent; /* o is where we are in the buffer */ + togo -= bytes_sent; /* track how much of the file we've sent */ + } + } + } + + /* Send the trailers + * XXX: optimization... if it will fit, send this on the last send in the + * loop above + */ + sendlen = 0; + if ( rv == APR_SUCCESS && hdtr && hdtr->numtrailers > 0 ) { + for (i = 0; i < hdtr->numtrailers; i++) { + sendlen += hdtr->trailers[i].iov_len; + } + rv = writev_it_all(c->client_socket, hdtr->trailers, hdtr->numtrailers, + sendlen, &bytes_sent); + *nbytes += bytes_sent; + } + + return rv; +} + +#ifndef APR_MAX_IOVEC_SIZE +#define MAX_IOVEC_TO_WRITE 16 +#else +#if APR_MAX_IOVEC_SIZE > 16 +#define MAX_IOVEC_TO_WRITE 16 +#else +#define MAX_IOVEC_TO_WRITE APR_MAX_IOVEC_SIZE +#endif +#endif + +/* Optional function coming from mod_logio, used for logging of output + * traffic + */ +extern APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out; + +apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) +{ + apr_status_t rv; + apr_bucket_brigade *more; + conn_rec *c = f->c; + core_net_rec *net = f->ctx; + core_output_filter_ctx_t *ctx = net->out_ctx; + apr_read_type_e eblock = APR_NONBLOCK_READ; + apr_pool_t *input_pool = b->p; + + if (ctx == NULL) { + ctx = apr_pcalloc(c->pool, sizeof(*ctx)); + net->out_ctx = ctx; + } + + /* If we have a saved brigade, concatenate the new brigade to it */ + if (ctx->b) { + APR_BRIGADE_CONCAT(ctx->b, b); + b = ctx->b; + ctx->b = NULL; + } + + /* Perform multiple passes over the brigade, sending batches of output + to the connection. */ + while (b && !APR_BRIGADE_EMPTY(b)) { + apr_size_t nbytes = 0; + apr_bucket *last_e = NULL; /* initialized for debugging */ + apr_bucket *e; + + /* one group of iovecs per pass over the brigade */ + apr_size_t nvec = 0; + apr_size_t nvec_trailers = 0; + struct iovec vec[MAX_IOVEC_TO_WRITE]; + struct iovec vec_trailers[MAX_IOVEC_TO_WRITE]; + + /* one file per pass over the brigade */ + apr_file_t *fd = NULL; + apr_size_t flen = 0; + apr_off_t foffset = 0; + + /* keep track of buckets that we've concatenated + * to avoid small writes + */ + apr_bucket *last_merged_bucket = NULL; + + /* tail of brigade if we need another pass */ + more = NULL; + + /* Iterate over the brigade: collect iovecs and/or a file */ + for (e = APR_BRIGADE_FIRST(b); + e != APR_BRIGADE_SENTINEL(b); + e = APR_BUCKET_NEXT(e)) + { + /* keep track of the last bucket processed */ + last_e = e; + if (APR_BUCKET_IS_EOS(e) || AP_BUCKET_IS_EOC(e)) { + break; + } + else if (APR_BUCKET_IS_FLUSH(e)) { + if (e != APR_BRIGADE_LAST(b)) { + more = apr_brigade_split(b, APR_BUCKET_NEXT(e)); + } + break; + } + + /* It doesn't make any sense to use sendfile for a file bucket + * that represents 10 bytes. + */ + else if (APR_BUCKET_IS_FILE(e) + && (e->length >= AP_MIN_SENDFILE_BYTES)) { + apr_bucket_file *a = e->data; + + /* We can't handle more than one file bucket at a time + * so we split here and send the file we have already + * found. + */ + if (fd) { + more = apr_brigade_split(b, e); + break; + } + + fd = a->fd; + flen = e->length; + foffset = e->start; + } + else { + const char *str; + apr_size_t n; + + rv = apr_bucket_read(e, &str, &n, eblock); + if (APR_STATUS_IS_EAGAIN(rv)) { + /* send what we have so far since we shouldn't expect more + * output for a while... next time we read, block + */ + more = apr_brigade_split(b, e); + eblock = APR_BLOCK_READ; + break; + } + eblock = APR_NONBLOCK_READ; + if (n) { + if (!fd) { + if (nvec == MAX_IOVEC_TO_WRITE) { + /* woah! too many. buffer them up, for use later. */ + apr_bucket *temp, *next; + apr_bucket_brigade *temp_brig; + + if (nbytes >= AP_MIN_BYTES_TO_WRITE) { + /* We have enough data in the iovec + * to justify doing a writev + */ + more = apr_brigade_split(b, e); + break; + } + + /* Create a temporary brigade as a means + * of concatenating a bunch of buckets together + */ + if (last_merged_bucket) { + /* If we've concatenated together small + * buckets already in a previous pass, + * the initial buckets in this brigade + * are heap buckets that may have extra + * space left in them (because they + * were created by apr_brigade_write()). + * We can take advantage of this by + * building the new temp brigade out of + * these buckets, so that the content + * in them doesn't have to be copied again. + */ + apr_bucket_brigade *bb; + bb = apr_brigade_split(b, + APR_BUCKET_NEXT(last_merged_bucket)); + temp_brig = b; + b = bb; + } + else { + temp_brig = apr_brigade_create(f->c->pool, + f->c->bucket_alloc); + } + + temp = APR_BRIGADE_FIRST(b); + while (temp != e) { + apr_bucket *d; + rv = apr_bucket_read(temp, &str, &n, APR_BLOCK_READ); + apr_brigade_write(temp_brig, NULL, NULL, str, n); + d = temp; + temp = APR_BUCKET_NEXT(temp); + apr_bucket_delete(d); + } + + nvec = 0; + nbytes = 0; + temp = APR_BRIGADE_FIRST(temp_brig); + APR_BUCKET_REMOVE(temp); + APR_BRIGADE_INSERT_HEAD(b, temp); + apr_bucket_read(temp, &str, &n, APR_BLOCK_READ); + vec[nvec].iov_base = (char*) str; + vec[nvec].iov_len = n; + nvec++; + + /* Just in case the temporary brigade has + * multiple buckets, recover the rest of + * them and put them in the brigade that + * we're sending. + */ + for (next = APR_BRIGADE_FIRST(temp_brig); + next != APR_BRIGADE_SENTINEL(temp_brig); + next = APR_BRIGADE_FIRST(temp_brig)) { + APR_BUCKET_REMOVE(next); + APR_BUCKET_INSERT_AFTER(temp, next); + temp = next; + apr_bucket_read(next, &str, &n, + APR_BLOCK_READ); + vec[nvec].iov_base = (char*) str; + vec[nvec].iov_len = n; + nvec++; + } + + apr_brigade_destroy(temp_brig); + + last_merged_bucket = temp; + e = temp; + last_e = e; + } + else { + vec[nvec].iov_base = (char*) str; + vec[nvec].iov_len = n; + nvec++; + } + } + else { + /* The bucket is a trailer to a file bucket */ + + if (nvec_trailers == MAX_IOVEC_TO_WRITE) { + /* woah! too many. stop now. */ + more = apr_brigade_split(b, e); + break; + } + + vec_trailers[nvec_trailers].iov_base = (char*) str; + vec_trailers[nvec_trailers].iov_len = n; + nvec_trailers++; + } + + nbytes += n; + } + } + } + + + /* Completed iterating over the brigade, now determine if we want + * to buffer the brigade or send the brigade out on the network. + * + * Save if we haven't accumulated enough bytes to send, the connection + * is not about to be closed, and: + * + * 1) we didn't see a file, we don't have more passes over the + * brigade to perform, AND we didn't stop at a FLUSH bucket. + * (IOW, we will save plain old bytes such as HTTP headers) + * or + * 2) we hit the EOS and have a keep-alive connection + * (IOW, this response is a bit more complex, but we save it + * with the hope of concatenating with another response) + */ + if (nbytes + flen < AP_MIN_BYTES_TO_WRITE + && !AP_BUCKET_IS_EOC(last_e) + && ((!fd && !more && !APR_BUCKET_IS_FLUSH(last_e)) + || (APR_BUCKET_IS_EOS(last_e) + && c->keepalive == AP_CONN_KEEPALIVE))) { + + /* NEVER save an EOS in here. If we are saving a brigade with + * an EOS bucket, then we are doing keepalive connections, and + * we want to process to second request fully. + */ + if (APR_BUCKET_IS_EOS(last_e)) { + apr_bucket *bucket; + int file_bucket_saved = 0; + apr_bucket_delete(last_e); + for (bucket = APR_BRIGADE_FIRST(b); + bucket != APR_BRIGADE_SENTINEL(b); + bucket = APR_BUCKET_NEXT(bucket)) { + + /* Do a read on each bucket to pull in the + * data from pipe and socket buckets, so + * that we don't leave their file descriptors + * open indefinitely. Do the same for file + * buckets, with one exception: allow the + * first file bucket in the brigade to remain + * a file bucket, so that we don't end up + * doing an mmap+memcpy every time a client + * requests a <8KB file over a keepalive + * connection. + */ + if (APR_BUCKET_IS_FILE(bucket) && !file_bucket_saved) { + file_bucket_saved = 1; + } + else { + const char *buf; + apr_size_t len = 0; + rv = apr_bucket_read(bucket, &buf, &len, + APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, + c, "core_output_filter:" + " Error reading from bucket."); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + } + } + if (!ctx->deferred_write_pool) { + apr_pool_create(&ctx->deferred_write_pool, c->pool); + apr_pool_tag(ctx->deferred_write_pool, "deferred_write"); + } + ap_save_brigade(f, &ctx->b, &b, ctx->deferred_write_pool); + + return APR_SUCCESS; + } + + if (fd) { + apr_hdtr_t hdtr; + apr_size_t bytes_sent; + +#if APR_HAS_SENDFILE + apr_int32_t flags = 0; +#endif + + memset(&hdtr, '\0', sizeof(hdtr)); + if (nvec) { + hdtr.numheaders = nvec; + hdtr.headers = vec; + } + + if (nvec_trailers) { + hdtr.numtrailers = nvec_trailers; + hdtr.trailers = vec_trailers; + } + +#if APR_HAS_SENDFILE + if (apr_file_flags_get(fd) & APR_SENDFILE_ENABLED) { + + if (c->keepalive == AP_CONN_CLOSE && APR_BUCKET_IS_EOS(last_e)) { + /* Prepare the socket to be reused */ + flags |= APR_SENDFILE_DISCONNECT_SOCKET; + } + + rv = sendfile_it_all(net, /* the network information */ + fd, /* the file to send */ + &hdtr, /* header and trailer iovecs */ + foffset, /* offset in the file to begin + sending from */ + flen, /* length of file */ + nbytes + flen, /* total length including + headers */ + &bytes_sent, /* how many bytes were + sent */ + flags); /* apr_sendfile flags */ + } + else +#endif + { + rv = emulate_sendfile(net, fd, &hdtr, foffset, flen, + &bytes_sent); + } + + if (logio_add_bytes_out && bytes_sent > 0) + logio_add_bytes_out(c, bytes_sent); + + fd = NULL; + } + else { + apr_size_t bytes_sent; + + rv = writev_it_all(net->client_socket, + vec, nvec, + nbytes, &bytes_sent); + + if (logio_add_bytes_out && bytes_sent > 0) + logio_add_bytes_out(c, bytes_sent); + } + + apr_brigade_destroy(b); + + /* drive cleanups for resources which were set aside + * this may occur before or after termination of the request which + * created the resource + */ + if (ctx->deferred_write_pool) { + if (more && more->p == ctx->deferred_write_pool) { + /* "more" belongs to the deferred_write_pool, + * which is about to be cleared. + */ + if (APR_BRIGADE_EMPTY(more)) { + more = NULL; + } + else { + /* uh oh... change more's lifetime + * to the input brigade's lifetime + */ + apr_bucket_brigade *tmp_more = more; + more = NULL; + ap_save_brigade(f, &more, &tmp_more, input_pool); + } + } + apr_pool_clear(ctx->deferred_write_pool); + } + + if (rv != APR_SUCCESS) { + ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, + "core_output_filter: writing data to the network"); + + if (more) + apr_brigade_destroy(more); + + /* No need to check for SUCCESS, we did that above. */ + if (!APR_STATUS_IS_EAGAIN(rv)) { + c->aborted = 1; + } + + /* The client has aborted, but the request was successful. We + * will report success, and leave it to the access and error + * logs to note that the connection was aborted. + */ + return APR_SUCCESS; + } + + b = more; + more = NULL; + } /* end while () */ + + return APR_SUCCESS; +} diff --git a/trunk/server/eoc_bucket.c b/trunk/server/eoc_bucket.c new file mode 100644 index 0000000000..047e9c8b05 --- /dev/null +++ b/trunk/server/eoc_bucket.c @@ -0,0 +1,55 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "http_connection.h" + +static apr_status_t eoc_bucket_read(apr_bucket *b, const char **str, + apr_size_t *len, apr_read_type_e block) +{ + *str = NULL; + *len = 0; + return APR_SUCCESS; +} + +AP_DECLARE(apr_bucket *) ap_bucket_eoc_make(apr_bucket *b) +{ + b->length = 0; + b->start = 0; + b->data = NULL; + b->type = &ap_bucket_type_eoc; + + return b; +} + +AP_DECLARE(apr_bucket *) ap_bucket_eoc_create(apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + return ap_bucket_eoc_make(b); +} + +AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_eoc = { + "EOC", 5, APR_BUCKET_METADATA, + apr_bucket_destroy_noop, + eoc_bucket_read, + apr_bucket_setaside_noop, + apr_bucket_split_notimpl, + apr_bucket_simple_copy +}; diff --git a/trunk/server/error_bucket.c b/trunk/server/error_bucket.c new file mode 100644 index 0000000000..280750a895 --- /dev/null +++ b/trunk/server/error_bucket.c @@ -0,0 +1,74 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "http_protocol.h" +#include "apr_buckets.h" +#include "apr_strings.h" +#if APR_HAVE_STRINGS_H +#include +#endif + +static apr_status_t error_bucket_read(apr_bucket *b, const char **str, + apr_size_t *len, apr_read_type_e block) +{ + *str = NULL; + *len = 0; + return APR_SUCCESS; +} + +static void error_bucket_destroy(void *data) +{ + ap_bucket_error *h = data; + + if (apr_bucket_shared_destroy(h)) { + apr_bucket_free(h); + } +} + +AP_DECLARE(apr_bucket *) ap_bucket_error_make(apr_bucket *b, int error, + const char *buf, apr_pool_t *p) +{ + ap_bucket_error *h; + + h = apr_bucket_alloc(sizeof(*h), b->list); + h->status = error; + h->data = (buf) ? apr_pstrdup(p, buf) : NULL; + + b = apr_bucket_shared_make(b, h, 0, 0); + b->type = &ap_bucket_type_error; + return b; +} + +AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf, + apr_pool_t *p, + apr_bucket_alloc_t *list) +{ + apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); + + APR_BUCKET_INIT(b); + b->free = apr_bucket_free; + b->list = list; + return ap_bucket_error_make(b, error, buf, p); +} + +AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_error = { + "ERROR", 5, APR_BUCKET_METADATA, + error_bucket_destroy, + error_bucket_read, + apr_bucket_setaside_notimpl, + apr_bucket_split_notimpl, + apr_bucket_shared_copy +}; diff --git a/trunk/server/gen_test_char.c b/trunk/server/gen_test_char.c new file mode 100644 index 0000000000..81c67f55ef --- /dev/null +++ b/trunk/server/gen_test_char.c @@ -0,0 +1,121 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_lib.h" + +#if APR_HAVE_STDIO_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif + +/* A bunch of functions in util.c scan strings looking for certain characters. + * To make that more efficient we encode a lookup table. + */ +#define T_ESCAPE_SHELL_CMD (0x01) +#define T_ESCAPE_PATH_SEGMENT (0x02) +#define T_OS_ESCAPE_PATH (0x04) +#define T_HTTP_TOKEN_STOP (0x08) +#define T_ESCAPE_LOGITEM (0x10) +#define T_ESCAPE_FORENSIC (0x20) + +int main(int argc, char *argv[]) +{ + unsigned c; + unsigned char flags; + + printf("/* this file is automatically generated by gen_test_char, " + "do not edit */\n" + "#define T_ESCAPE_SHELL_CMD (%u)\n" + "#define T_ESCAPE_PATH_SEGMENT (%u)\n" + "#define T_OS_ESCAPE_PATH (%u)\n" + "#define T_HTTP_TOKEN_STOP (%u)\n" + "#define T_ESCAPE_LOGITEM (%u)\n" + "#define T_ESCAPE_FORENSIC (%u)\n" + "\n" + "static const unsigned char test_char_table[256] = {", + T_ESCAPE_SHELL_CMD, + T_ESCAPE_PATH_SEGMENT, + T_OS_ESCAPE_PATH, + T_HTTP_TOKEN_STOP, + T_ESCAPE_LOGITEM, + T_ESCAPE_FORENSIC); + + for (c = 0; c < 256; ++c) { + flags = 0; + if (c % 20 == 0) + printf("\n "); + + /* escape_shell_cmd */ +#if defined(WIN32) || defined(OS2) + /* Win32/OS2 have many of the same vulnerable characters + * as Unix sh, plus the carriage return and percent char. + * The proper escaping of these characters varies from unix + * since Win32/OS2 use carets or doubled-double quotes, + * and neither lf nor cr can be escaped. We escape unix + * specific as well, to assure that cross-compiled unix + * applications behave similiarly when invoked on win32/os2. + * + * Rem please keep in-sync with apr's list in win32/filesys.c + */ + if (c && strchr("&;`'\"|*?~<>^()[]{}$\\\n\r%", c)) { + flags |= T_ESCAPE_SHELL_CMD; + } +#else + if (c && strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) { + flags |= T_ESCAPE_SHELL_CMD; + } +#endif + + if (!apr_isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) { + flags |= T_ESCAPE_PATH_SEGMENT; + } + + if (!apr_isalnum(c) && !strchr("$-_.+!*'(),:@&=/~", c)) { + flags |= T_OS_ESCAPE_PATH; + } + + /* these are the "tspecials" from RFC2068 */ + if (c && (apr_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c))) { + flags |= T_HTTP_TOKEN_STOP; + } + + /* For logging, escape all control characters, + * double quotes (because they delimit the request in the log file) + * backslashes (because we use backslash for escaping) + * and 8-bit chars with the high bit set + */ + if (c && (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c))) { + flags |= T_ESCAPE_LOGITEM; + } + + /* For forensic logging, escape all control characters, top bit set, + * :, | (used as delimiters) and % (used for escaping). + */ + if (!apr_isprint(c) || c == ':' || c == '|' || c == '%' + || apr_iscntrl(c) || !c) { + flags |= T_ESCAPE_FORENSIC; + } + + printf("%u%c", flags, (c < 255) ? ',' : ' '); + } + + printf("\n};\n"); + + return 0; +} diff --git a/trunk/server/gen_test_char.dsp b/trunk/server/gen_test_char.dsp new file mode 100644 index 0000000000..44475a190e --- /dev/null +++ b/trunk/server/gen_test_char.dsp @@ -0,0 +1,94 @@ +# Microsoft Developer Studio Project File - Name="gen_test_char" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gen_test_char - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gen_test_char.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gen_test_char.mak" CFG="gen_test_char - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gen_test_char - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gen_test_char - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gen_test_char - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\gen_test_char" /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\gen_test_char.pdb" /machine:I386 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\gen_test_char.pdb" /machine:I386 /opt:ref +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "gen_test_char - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\include" /I "..\srclib\apr\include" /I "..\srclib\apr-util\include" /I "..\os\win32" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\gen_test_char" /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_test_char.pdb" /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\gen_test_char.pdb" /debug /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "gen_test_char - Win32 Release" +# Name "gen_test_char - Win32 Debug" +# Begin Source File + +SOURCE=.\gen_test_char.c +# End Source File +# End Target +# End Project diff --git a/trunk/server/listen.c b/trunk/server/listen.c new file mode 100644 index 0000000000..64b7505484 --- /dev/null +++ b/trunk/server/listen.c @@ -0,0 +1,565 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_network_io.h" +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "ap_listen.h" +#include "http_log.h" +#include "mpm.h" +#include "mpm_common.h" + +AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL; + +static ap_listen_rec *old_listeners; +static int ap_listenbacklog; +static int send_buffer_size; +static int receive_buffer_size; + +/* TODO: make_sock is just begging and screaming for APR abstraction */ +static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) +{ + apr_socket_t *s = server->sd; + int one = 1; +#if APR_HAVE_IPV6 +#ifdef AP_ENABLE_V4_MAPPED + int v6only_setting = 0; +#else + int v6only_setting = 1; +#endif +#endif + apr_status_t stat; + +#ifndef WIN32 + stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, + "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", + server->bind_addr); + apr_socket_close(s); + return stat; + } +#endif + + stat = apr_socket_opt_set(s, APR_SO_KEEPALIVE, one); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, + "make_sock: for address %pI, apr_socket_opt_set: (SO_KEEPALIVE)", + server->bind_addr); + apr_socket_close(s); + return stat; + } + +#if APR_HAVE_IPV6 + if (server->bind_addr->family == APR_INET6) { + stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, + "make_sock: for address %pI, apr_socket_opt_set: " + "(IPV6_V6ONLY)", + server->bind_addr); + apr_socket_close(s); + return stat; + } + } +#endif + + /* + * To send data over high bandwidth-delay connections at full + * speed we must force the TCP window to open wide enough to keep the + * pipe full. The default window size on many systems + * is only 4kB. Cross-country WAN connections of 100ms + * at 1Mb/s are not impossible for well connected sites. + * If we assume 100ms cross-country latency, + * a 4kB buffer limits throughput to 40kB/s. + * + * To avoid this problem I've added the SendBufferSize directive + * to allow the web master to configure send buffer size. + * + * The trade-off of larger buffers is that more kernel memory + * is consumed. YMMV, know your customers and your network! + * + * -John Heidemann 25-Oct-96 + * + * If no size is specified, use the kernel default. + */ + if (send_buffer_size) { + stat = apr_socket_opt_set(s, APR_SO_SNDBUF, send_buffer_size); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, + "make_sock: failed to set SendBufferSize for " + "address %pI, using default", + server->bind_addr); + /* not a fatal error */ + } + } + if (receive_buffer_size) { + stat = apr_socket_opt_set(s, APR_SO_RCVBUF, receive_buffer_size); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, + "make_sock: failed to set ReceiveBufferSize for " + "address %pI, using default", + server->bind_addr); + strerror(errno); + /* not a fatal error */ + } + } + +#if APR_TCP_NODELAY_INHERITED + ap_sock_disable_nagle(s); +#endif + + if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, + "make_sock: could not bind to address %pI", + server->bind_addr); + apr_socket_close(s); + return stat; + } + + if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, + "make_sock: unable to listen for connections " + "on address %pI", + server->bind_addr); + apr_socket_close(s); + return stat; + } + +#ifdef WIN32 + /* I seriously doubt that this would work on Unix; I have doubts that + * it entirely solves the problem on Win32. However, since setting + * reuseaddr on the listener -prior- to binding the socket has allowed + * us to attach to the same port as an already running instance of + * Apache, or even another web server, we cannot identify that this + * port was exclusively granted to this instance of Apache. + * + * So set reuseaddr, but do not attempt to do so until we have the + * parent listeners successfully bound. + */ + stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one); + if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, + "make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)", + server->bind_addr); + apr_socket_close(s); + return stat; + } +#endif + +#if APR_HAS_SO_ACCEPTFILTER +#ifndef ACCEPT_FILTER_NAME +#define ACCEPT_FILTER_NAME "httpready" +#ifdef __FreeBSD_version +#if __FreeBSD_version < 411000 /* httpready broken before 4.1.1 */ +#undef ACCEPT_FILTER_NAME +#define ACCEPT_FILTER_NAME "dataready" +#endif +#endif +#endif + stat = apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, ""); + if (stat != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(stat)) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, + "Failed to enable the '%s' Accept Filter", + ACCEPT_FILTER_NAME); + } +#else +#ifdef APR_TCP_DEFER_ACCEPT + stat = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 1); + if (stat != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(stat)) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p, + "Failed to enable APR_TCP_DEFER_ACCEPT"); + } +#endif +#endif + + server->sd = s; + server->active = 1; + +#ifdef MPM_ACCEPT_FUNC + server->accept_func = MPM_ACCEPT_FUNC; +#else + server->accept_func = NULL; +#endif + + return APR_SUCCESS; +} + +static apr_status_t close_listeners_on_exec(void *v) +{ + ap_listen_rec *lr; + + for (lr = ap_listeners; lr; lr = lr->next) { + apr_socket_close(lr->sd); + lr->active = 0; + } + + return APR_SUCCESS; +} + + +static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port) +{ + ap_listen_rec **walk, *last; + apr_status_t status; + apr_sockaddr_t *sa; + int found_listener = 0; + + /* see if we've got an old listener for this address:port */ + for (walk = &old_listeners; *walk;) { + sa = (*walk)->bind_addr; + /* Some listeners are not real so they will not have a bind_addr. */ + if (sa) { + ap_listen_rec *new; + apr_port_t oldport; + + oldport = sa->port; + /* If both ports are equivalent, then if their names are equivalent, + * then we will re-use the existing record. + */ + if (port == oldport && + ((!addr && !sa->hostname) || + ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { + new = *walk; + *walk = new->next; + new->next = ap_listeners; + ap_listeners = new; + found_listener = 1; + continue; + } + } + + walk = &(*walk)->next; + } + + if (found_listener) { + return NULL; + } + + if ((status = apr_sockaddr_info_get(&sa, addr, APR_UNSPEC, port, 0, + process->pool)) + != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, + "alloc_listener: failed to set up sockaddr for %s", + addr); + return "Listen setup failed"; + } + + /* Initialize to our last configured ap_listener. */ + last = ap_listeners; + while (last && last->next) { + last = last->next; + } + + while (sa) { + ap_listen_rec *new; + + /* this has to survive restarts */ + new = apr_palloc(process->pool, sizeof(ap_listen_rec)); + new->active = 0; + new->next = 0; + new->bind_addr = sa; + + /* Go to the next sockaddr. */ + sa = sa->next; + + status = apr_socket_create(&new->sd, new->bind_addr->family, + SOCK_STREAM, 0, process->pool); + +#if APR_HAVE_IPV6 + /* What could happen is that we got an IPv6 address, but this system + * doesn't actually support IPv6. Try the next address. + */ + if (status != APR_SUCCESS && !addr && + new->bind_addr->family == APR_INET6) { + continue; + } +#endif + if (status != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, + "alloc_listener: failed to get a socket for %s", + addr); + return "Listen setup failed"; + } + + /* We need to preserve the order returned by getaddrinfo() */ + if (last == NULL) { + ap_listeners = last = new; + } else { + last->next = new; + last = new; + } + } + + return NULL; +} + +/** + * Create, open, listen, and bind all sockets. + * @param process The process record for the currently running server + * @return The number of open sockets + */ +static int open_listeners(apr_pool_t *pool) +{ + ap_listen_rec *lr; + ap_listen_rec *next; + ap_listen_rec *previous; + int num_open; + const char *userdata_key = "ap_open_listeners"; + void *data; + + /* Don't allocate a default listener. If we need to listen to a + * port, then the user needs to have a Listen directive in their + * config file. + */ + num_open = 0; + previous = NULL; + for (lr = ap_listeners; lr; previous = lr, lr = lr->next) { + if (lr->active) { + ++num_open; + } + else { +#if APR_HAVE_IPV6 + int v6only_setting; + /* If we are trying to bind to 0.0.0.0 and the previous listener + * was :: on the same port and in turn that socket does not have + * the IPV6_V6ONLY flag set; we must skip the current attempt to + * listen (which would generate an error). IPv4 will be handled + * on the established IPv6 socket. + */ + if (previous != NULL && + lr->bind_addr->family == APR_INET && + lr->bind_addr->sa.sin.sin_addr.s_addr == INADDR_ANY && + lr->bind_addr->port == previous->bind_addr->port && + previous->bind_addr->family == APR_INET6 && + IN6_IS_ADDR_UNSPECIFIED( + &previous->bind_addr->sa.sin6.sin6_addr) && + apr_socket_opt_get(previous->sd, APR_IPV6_V6ONLY, + &v6only_setting) == APR_SUCCESS && + v6only_setting == 0) { + + /* Remove the current listener from the list */ + previous->next = lr->next; + continue; + } +#endif + if (make_sock(pool, lr) == APR_SUCCESS) { + ++num_open; + lr->active = 1; + } + else { +#if APR_HAVE_IPV6 + /* If we tried to bind to ::, and the next listener is + * on 0.0.0.0 with the same port, don't give a fatal + * error. The user will still get a warning from make_sock + * though. + */ + if (lr->next != NULL && lr->bind_addr->family == APR_INET6 && + IN6_IS_ADDR_UNSPECIFIED( + &lr->bind_addr->sa.sin6.sin6_addr) && + lr->bind_addr->port == lr->next->bind_addr->port && + lr->next->bind_addr->family == APR_INET && + lr->next->bind_addr->sa.sin.sin_addr.s_addr == INADDR_ANY) { + + /* Remove the current listener from the list */ + if (previous) { + previous->next = lr->next; + } + else { + ap_listeners = lr->next; + } + + /* Although we've removed ourselves from the list, + * we need to make sure that the next iteration won't + * consider "previous" a working IPv6 '::' socket. + * Changing the family is enough to make sure the + * conditions before make_sock() fail. + */ + lr->bind_addr->family = AF_INET; + + continue; + } +#endif + /* fatal error */ + return -1; + } + } + } + + /* close the old listeners */ + for (lr = old_listeners; lr; lr = next) { + apr_socket_close(lr->sd); + lr->active = 0; + next = lr->next; + } + old_listeners = NULL; + +#if AP_NONBLOCK_WHEN_MULTI_LISTEN + /* if multiple listening sockets, make them non-blocking so that + * if select()/poll() reports readability for a reset connection that + * is already forgotten about by the time we call accept, we won't + * be hung until another connection arrives on that port + */ + if (ap_listeners && ap_listeners->next) { + for (lr = ap_listeners; lr; lr = lr->next) { + apr_status_t status; + + status = apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, 1); + if (status != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, status, pool, + "unable to make listening socket non-blocking"); + return -1; + } + } + } +#endif /* AP_NONBLOCK_WHEN_MULTI_LISTEN */ + + /* we come through here on both passes of the open logs phase + * only register the cleanup once... otherwise we try to close + * listening sockets twice when cleaning up prior to exec + */ + apr_pool_userdata_get(&data, userdata_key, pool); + if (!data) { + apr_pool_userdata_set((const void *)1, userdata_key, + apr_pool_cleanup_null, pool); + apr_pool_cleanup_register(pool, NULL, apr_pool_cleanup_null, + close_listeners_on_exec); + } + + return num_open ? 0 : -1; +} + +AP_DECLARE(int) ap_setup_listeners(server_rec *s) +{ + ap_listen_rec *lr; + int num_listeners = 0; + + if (open_listeners(s->process->pool)) { + return 0; + } + + for (lr = ap_listeners; lr; lr = lr->next) { + num_listeners++; + } + + return num_listeners; +} + +AP_DECLARE(void) ap_listen_pre_config(void) +{ + old_listeners = ap_listeners; + ap_listeners = NULL; + ap_listenbacklog = DEFAULT_LISTENBACKLOG; +} + + +AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + const char *ips) +{ + char *host, *scope_id; + apr_port_t port; + apr_status_t rv; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool); + if (rv != APR_SUCCESS) { + return "Invalid address or port"; + } + + if (host && !strcmp(host, "*")) { + host = NULL; + } + + if (scope_id) { + /* XXX scope id support is useful with link-local IPv6 addresses */ + return "Scope id is not supported"; + } + + if (!port) { + return "Port must be specified"; + } + + return alloc_listener(cmd->server->process, host, port); +} + +AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + int b; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + b = atoi(arg); + if (b < 1) { + return "ListenBacklog must be > 0"; + } + + ap_listenbacklog = b; + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + int s = atoi(arg); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + if (s < 512 && s != 0) { + return "SendBufferSize must be >= 512 bytes, or 0 for system default."; + } + + send_buffer_size = s; + return NULL; +} + +AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + int s = atoi(arg); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + if (s < 512 && s != 0) { + return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default."; + } + + receive_buffer_size = s; + return NULL; +} diff --git a/trunk/server/log.c b/trunk/server/log.c new file mode 100644 index 0000000000..12c8dc9d0f --- /dev/null +++ b/trunk/server/log.c @@ -0,0 +1,987 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_log.c: Dealing with the logs and errors + * + * Rob McCool + * + */ + +#include "apr.h" +#include "apr_general.h" /* for signal stuff */ +#include "apr_strings.h" +#include "apr_errno.h" +#include "apr_thread_proc.h" +#include "apr_lib.h" +#include "apr_signal.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "util_time.h" +#include "ap_mpm.h" + +typedef struct { + char *t_name; + int t_val; +} TRANS; + +APR_HOOK_STRUCT( + APR_HOOK_LINK(error_log) +) + +int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL; + +#ifdef HAVE_SYSLOG + +static const TRANS facilities[] = { + {"auth", LOG_AUTH}, +#ifdef LOG_AUTHPRIV + {"authpriv",LOG_AUTHPRIV}, +#endif +#ifdef LOG_CRON + {"cron", LOG_CRON}, +#endif +#ifdef LOG_DAEMON + {"daemon", LOG_DAEMON}, +#endif +#ifdef LOG_FTP + {"ftp", LOG_FTP}, +#endif +#ifdef LOG_KERN + {"kern", LOG_KERN}, +#endif +#ifdef LOG_LPR + {"lpr", LOG_LPR}, +#endif +#ifdef LOG_MAIL + {"mail", LOG_MAIL}, +#endif +#ifdef LOG_NEWS + {"news", LOG_NEWS}, +#endif +#ifdef LOG_SYSLOG + {"syslog", LOG_SYSLOG}, +#endif +#ifdef LOG_USER + {"user", LOG_USER}, +#endif +#ifdef LOG_UUCP + {"uucp", LOG_UUCP}, +#endif +#ifdef LOG_LOCAL0 + {"local0", LOG_LOCAL0}, +#endif +#ifdef LOG_LOCAL1 + {"local1", LOG_LOCAL1}, +#endif +#ifdef LOG_LOCAL2 + {"local2", LOG_LOCAL2}, +#endif +#ifdef LOG_LOCAL3 + {"local3", LOG_LOCAL3}, +#endif +#ifdef LOG_LOCAL4 + {"local4", LOG_LOCAL4}, +#endif +#ifdef LOG_LOCAL5 + {"local5", LOG_LOCAL5}, +#endif +#ifdef LOG_LOCAL6 + {"local6", LOG_LOCAL6}, +#endif +#ifdef LOG_LOCAL7 + {"local7", LOG_LOCAL7}, +#endif + {NULL, -1}, +}; +#endif + +static const TRANS priorities[] = { + {"emerg", APLOG_EMERG}, + {"alert", APLOG_ALERT}, + {"crit", APLOG_CRIT}, + {"error", APLOG_ERR}, + {"warn", APLOG_WARNING}, + {"notice", APLOG_NOTICE}, + {"info", APLOG_INFO}, + {"debug", APLOG_DEBUG}, + {NULL, -1}, +}; + +static apr_file_t *stderr_log = NULL; + +/* track pipe handles to close in child process */ +typedef struct read_handle_t { + struct read_handle_t *next; + apr_file_t *handle; +} read_handle_t; + +static read_handle_t *read_handles; + +/* clear_handle_list() is called when plog is cleared; at that + * point we need to forget about our old list of pipe read + * handles + */ +static apr_status_t clear_handle_list(void *v) +{ + read_handles = NULL; + return APR_SUCCESS; +} + +/* remember to close this handle in the child process */ +static void close_handle_in_child(apr_pool_t *p, apr_file_t *f) +{ + read_handle_t *new_handle; + + new_handle = apr_pcalloc(p, sizeof(read_handle_t)); + new_handle->next = read_handles; + new_handle->handle = f; + read_handles = new_handle; +} + +void ap_logs_child_init(apr_pool_t *p, server_rec *s) +{ + read_handle_t *cur = read_handles; + + while (cur) { + apr_file_close(cur->handle); + cur = cur->next; + } +} + +AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p) +{ + apr_file_open_stderr(&stderr_log, p); +} + +AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p, + const char *fname) +{ + apr_file_t *stderr_file; + apr_status_t rc; + char *filename = ap_server_root_relative(p, fname); + if (!filename) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, + APR_EBADPATH, NULL, "Invalid -E error log file %s", + fname); + return APR_EBADPATH; + } + if ((rc = apr_file_open(&stderr_file, filename, + APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE, + APR_OS_DEFAULT, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, + "%s: could not open error log file %s.", + ap_server_argv0, fname); + return rc; + } + if ((rc = apr_file_open_stderr(&stderr_log, p)) == APR_SUCCESS) { + apr_file_flush(stderr_log); + if ((rc = apr_file_dup2(stderr_log, stderr_file, p)) == APR_SUCCESS) { + apr_file_close(stderr_file); + } + } + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, NULL, + "unable to replace stderr with error_log"); + } + return rc; +} + +static void log_child_errfn(apr_pool_t *pool, apr_status_t err, + const char *description) +{ + ap_log_error(APLOG_MARK, APLOG_ERR, err, NULL, + "%s", description); +} + +static int log_child(apr_pool_t *p, const char *progname, + apr_file_t **fpin) +{ + /* Child process code for 'ErrorLog "|..."'; + * may want a common framework for this, since I expect it will + * be common for other foo-loggers to want this sort of thing... + */ + apr_status_t rc; + apr_procattr_t *procattr; + apr_proc_t *procnew; + + if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) + && ((rc = apr_procattr_cmdtype_set(procattr, + APR_SHELLCMD_ENV)) == APR_SUCCESS) + && ((rc = apr_procattr_io_set(procattr, + APR_FULL_BLOCK, + APR_NO_PIPE, + APR_NO_PIPE)) == APR_SUCCESS) + && ((rc = apr_procattr_error_check_set(procattr, 1)) == APR_SUCCESS) + && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS)) { + char **args; + const char *pname; + + apr_tokenize_to_argv(progname, &args, p); + pname = apr_pstrdup(p, args[0]); + procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew)); + rc = apr_proc_create(procnew, pname, (const char * const *)args, + NULL, procattr, p); + + if (rc == APR_SUCCESS) { + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + (*fpin) = procnew->in; + /* read handle to pipe not kept open, so no need to call + * close_handle_in_child() + */ + } + } + + return rc; +} + +static int open_error_log(server_rec *s, apr_pool_t *p) +{ + const char *fname; + int rc; + + if (*s->error_fname == '|') { + apr_file_t *dummy = NULL; + + /* This starts a new process... */ + rc = log_child (p, s->error_fname + 1, &dummy); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, + "Couldn't start ErrorLog process"); + return DONE; + } + + s->error_log = dummy; + } + +#ifdef HAVE_SYSLOG + else if (!strncasecmp(s->error_fname, "syslog", 6)) { + if ((fname = strchr(s->error_fname, ':'))) { + const TRANS *fac; + + fname++; + for (fac = facilities; fac->t_name; fac++) { + if (!strcasecmp(fname, fac->t_name)) { + openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, + fac->t_val); + s->error_log = NULL; + return OK; + } + } + } + else { + openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7); + } + + s->error_log = NULL; + } +#endif + else { + fname = ap_server_root_relative(p, s->error_fname); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, APR_EBADPATH, NULL, + "%s: Invalid error log path %s.", + ap_server_argv0, s->error_fname); + return DONE; + } + if ((rc = apr_file_open(&s->error_log, fname, + APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE, + APR_OS_DEFAULT, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, + "%s: could not open error log file %s.", + ap_server_argv0, fname); + return DONE; + } + } + + return OK; +} + +int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, + apr_pool_t *ptemp, server_rec *s_main) +{ + apr_status_t rc = APR_SUCCESS; + server_rec *virt, *q; + int replace_stderr; + apr_file_t *errfile = NULL; + + apr_pool_cleanup_register(p, NULL, clear_handle_list, + apr_pool_cleanup_null); + if (open_error_log(s_main, p) != OK) { + return DONE; + } + + replace_stderr = 1; + if (s_main->error_log) { + /* replace stderr with this new log */ + apr_file_flush(s_main->error_log); + if ((rc = apr_file_open_stderr(&errfile, p)) == APR_SUCCESS) { + rc = apr_file_dup2(errfile, s_main->error_log, p); + } + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s_main, + "unable to replace stderr with error_log"); + } + else { + replace_stderr = 0; + } + } + /* note that stderr may still need to be replaced with something + * because it points to the old error log, or back to the tty + * of the submitter. + * XXX: This is BS - /dev/null is non-portable + */ + if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) { + ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main, + "unable to replace stderr with /dev/null"); + } + + for (virt = s_main->next; virt; virt = virt->next) { + if (virt->error_fname) { + for (q=s_main; q != virt; q = q->next) { + if (q->error_fname != NULL + && strcmp(q->error_fname, virt->error_fname) == 0) { + break; + } + } + + if (q == virt) { + if (open_error_log(virt, p) != OK) { + return DONE; + } + } + else { + virt->error_log = q->error_log; + } + } + else { + virt->error_log = s_main->error_log; + } + } + return OK; +} + +AP_DECLARE(void) ap_error_log2stderr(server_rec *s) { + apr_file_t *errfile = NULL; + + apr_file_open_stderr(&errfile, s->process->pool); + if (s->error_log != NULL) { + apr_file_dup2(s->error_log, errfile, s->process->pool); + } +} + +static void log_error_core(const char *file, int line, int level, + apr_status_t status, const server_rec *s, + const conn_rec *c, + const request_rec *r, apr_pool_t *pool, + const char *fmt, va_list args) +{ + char errstr[MAX_STRING_LEN]; +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + char scratch[MAX_STRING_LEN]; +#endif + apr_size_t len, errstrlen; + apr_file_t *logf = NULL; + const char *referer; + int level_and_mask = level & APLOG_LEVELMASK; + + if (r && r->connection) { + c = r->connection; + } + + if (s == NULL) { + /* + * If we are doing stderr logging (startup), don't log messages that are + * above the default server log level unless it is a startup/shutdown + * notice + */ + if ((level_and_mask != APLOG_NOTICE) + && (level_and_mask > ap_default_loglevel)) { + return; + } + + logf = stderr_log; + } + else if (s->error_log) { + /* + * If we are doing normal logging, don't log messages that are + * above the server log level unless it is a startup/shutdown notice + */ + if ((level_and_mask != APLOG_NOTICE) + && (level_and_mask > s->loglevel)) { + return; + } + + logf = s->error_log; + } +#ifdef TPF + else if (tpf_child) { + /* + * If we are doing normal logging, don't log messages that are + * above the server log level unless it is a startup/shutdown notice + */ + if ((level_and_mask != APLOG_NOTICE) + && (level_and_mask > s->loglevel)) { + return; + } + + logf = stderr; + } +#endif /* TPF */ + else { + /* + * If we are doing syslog logging, don't log messages that are + * above the server log level (including a startup/shutdown notice) + */ + if (level_and_mask > s->loglevel) { + return; + } + } + + if (logf && ((level & APLOG_STARTUP) != APLOG_STARTUP)) { + errstr[0] = '['; + ap_recent_ctime(errstr + 1, apr_time_now()); + errstr[1 + APR_CTIME_LEN - 1] = ']'; + errstr[1 + APR_CTIME_LEN ] = ' '; + len = 1 + APR_CTIME_LEN + 1; + } else { + len = 0; + } + + if ((level & APLOG_STARTUP) != APLOG_STARTUP) { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "[%s] ", priorities[level_and_mask].t_name); + } + +#ifndef TPF + if (file && level_and_mask == APLOG_DEBUG) { +#if defined(_OSD_POSIX) || defined(WIN32) || defined(__MVS__) + char tmp[256]; + char *e = strrchr(file, '/'); +#ifdef WIN32 + if (!e) { + e = strrchr(file, '\\'); + } +#endif + + /* In OSD/POSIX, the compiler returns for __FILE__ + * a string like: __FILE__="*POSIX(/usr/include/stdio.h)" + * (it even returns an absolute path for sources in + * the current directory). Here we try to strip this + * down to the basename. + */ + if (e != NULL && e[1] != '\0') { + apr_snprintf(tmp, sizeof(tmp), "%s", &e[1]); + e = &tmp[strlen(tmp)-1]; + if (*e == ')') { + *e = '\0'; + } + file = tmp; + } +#else /* _OSD_POSIX || WIN32 */ + const char *p; + /* On Unix, __FILE__ may be an absolute path in a + * VPATH build. */ + if (file[0] == '/' && (p = ap_strrchr_c(file, '/')) != NULL) { + file = p + 1; + } +#endif /*_OSD_POSIX || WIN32 */ + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "%s(%d): ", file, line); + } +#endif /* TPF */ + + if (c) { + /* XXX: TODO: add a method of selecting whether logged client + * addresses are in dotted quad or resolved form... dotted + * quad is the most secure, which is why I'm implementing it + * first. -djg + */ + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "[client %s] ", c->remote_ip); + } + if (status != 0) { + if (status < APR_OS_START_EAIERR) { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "(%d)", status); + } + else if (status < APR_OS_START_SYSERR) { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "(EAI %d)", status - APR_OS_START_EAIERR); + } + else if (status < 100000 + APR_OS_START_SYSERR) { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "(OS %d)", status - APR_OS_START_SYSERR); + } + else { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + "(os 0x%08x)", status - APR_OS_START_SYSERR); + } + apr_strerror(status, errstr + len, MAX_STRING_LEN - len); + len += strlen(errstr + len); + if (MAX_STRING_LEN - len > 2) { + errstr[len++] = ':'; + errstr[len++] = ' '; + errstr[len] = '\0'; + } + } + + errstrlen = len; +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + if (apr_vsnprintf(scratch, MAX_STRING_LEN - len, fmt, args)) { + len += ap_escape_errorlog_item(errstr + len, scratch, + MAX_STRING_LEN - len); + } +#else + len += apr_vsnprintf(errstr + len, MAX_STRING_LEN - len, fmt, args); +#endif + + if ( r && (referer = apr_table_get(r->headers_in, "Referer")) +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + && ap_escape_errorlog_item(scratch, referer, MAX_STRING_LEN - len) +#endif + ) { + len += apr_snprintf(errstr + len, MAX_STRING_LEN - len, + ", referer: %s", +#ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED + scratch +#else + referer +#endif + ); + } + + /* NULL if we are logging to syslog */ + if (logf) { + /* Truncate for the terminator (as apr_snprintf does) */ + if (len > MAX_STRING_LEN - sizeof(APR_EOL_STR)) { + len = MAX_STRING_LEN - sizeof(APR_EOL_STR); + } + strcpy(errstr + len, APR_EOL_STR); + apr_file_puts(errstr, logf); + apr_file_flush(logf); + } +#ifdef HAVE_SYSLOG + else { + syslog(level_and_mask, "%s", errstr); + } +#endif + + ap_run_error_log(file, line, level, status, s, r, pool, errstr + errstrlen); +} + +AP_DECLARE(void) ap_log_error(const char *file, int line, int level, + apr_status_t status, const server_rec *s, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + log_error_core(file, line, level, status, s, NULL, NULL, NULL, fmt, args); + va_end(args); +} + +AP_DECLARE(void) ap_log_perror(const char *file, int line, int level, + apr_status_t status, apr_pool_t *p, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + log_error_core(file, line, level, status, NULL, NULL, NULL, p, fmt, args); + va_end(args); +} + +AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level, + apr_status_t status, const request_rec *r, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + log_error_core(file, line, level, status, r->server, NULL, r, NULL, fmt, + args); + + /* + * IF APLOG_TOCLIENT is set, + * AND the error level is 'warning' or more severe, + * AND there isn't already error text associated with this request, + * THEN make the message text available to ErrorDocument and + * other error processors. + */ + va_end(args); + va_start(args,fmt); + if ((level & APLOG_TOCLIENT) + && ((level & APLOG_LEVELMASK) <= APLOG_WARNING) + && (apr_table_get(r->notes, "error-notes") == NULL)) { + apr_table_setn(r->notes, "error-notes", + ap_escape_html(r->pool, apr_pvsprintf(r->pool, fmt, + args))); + } + va_end(args); +} + +AP_DECLARE(void) ap_log_cerror(const char *file, int line, int level, + apr_status_t status, const conn_rec *c, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + log_error_core(file, line, level, status, c->base_server, c, NULL, NULL, + fmt, args); + va_end(args); +} + +AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename) +{ + apr_file_t *pid_file = NULL; + apr_finfo_t finfo; + static pid_t saved_pid = -1; + pid_t mypid; + apr_status_t rv; + const char *fname; + + if (!filename) { + return; + } + + fname = ap_server_root_relative(p, filename); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, + NULL, "Invalid PID file path %s, ignoring.", filename); + return; + } + + mypid = getpid(); + if (mypid != saved_pid + && apr_stat(&finfo, fname, APR_FINFO_MTIME, p) == APR_SUCCESS) { + /* AP_SIG_GRACEFUL and HUP call this on each restart. + * Only warn on first time through for this pid. + * + * XXX: Could just write first time through too, although + * that may screw up scripts written to do something + * based on the last modification time of the pid file. + */ + ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p, + "pid file %s overwritten -- Unclean " + "shutdown of previous Apache run?", + fname); + } + + if ((rv = apr_file_open(&pid_file, fname, + APR_WRITE | APR_CREATE | APR_TRUNCATE, + APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "could not create %s", fname); + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "%s: could not log pid to file %s", + ap_server_argv0, fname); + exit(1); + } + apr_file_printf(pid_file, "%ld" APR_EOL_STR, (long)mypid); + apr_file_close(pid_file); + saved_pid = mypid; +} + +AP_DECLARE(apr_status_t) ap_read_pid(apr_pool_t *p, const char *filename, + pid_t *mypid) +{ + const apr_size_t BUFFER_SIZE = sizeof(long) * 3 + 2; /* see apr_ltoa */ + apr_file_t *pid_file = NULL; + apr_status_t rv; + const char *fname; + char *buf, *endptr; + apr_size_t bytes_read; + + if (!filename) { + return APR_EGENERAL; + } + + fname = ap_server_root_relative(p, filename); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, APR_EBADPATH, + NULL, "Invalid PID file path %s, ignoring.", filename); + return APR_EGENERAL; + } + + rv = apr_file_open(&pid_file, fname, APR_READ, APR_OS_DEFAULT, p); + if (rv != APR_SUCCESS) { + return rv; + } + + buf = apr_palloc(p, BUFFER_SIZE); + + rv = apr_file_read_full(pid_file, buf, BUFFER_SIZE - 1, &bytes_read); + if (rv != APR_SUCCESS && rv != APR_EOF) { + return rv; + } + + /* If we fill the buffer, we're probably reading a corrupt pid file. + * To be nice, let's also ensure the first char is a digit. */ + if (bytes_read == 0 || bytes_read == BUFFER_SIZE - 1 || !apr_isdigit(*buf)) { + return APR_EGENERAL; + } + + buf[bytes_read] = '\0'; + *mypid = strtol(buf, &endptr, 10); + + apr_file_close(pid_file); + return APR_SUCCESS; +} + +AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, + int nLine) +{ + char time_str[APR_CTIME_LEN]; + + apr_ctime(time_str, apr_time_now()); + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, + "[%s] file %s, line %d, assertion \"%s\" failed", + time_str, szFile, nLine, szExp); +#if defined(WIN32) + DebugBreak(); +#else + /* unix assert does an abort leading to a core dump */ + abort(); +#endif +} + +/* piped log support */ + +#ifdef AP_HAVE_RELIABLE_PIPED_LOGS +/* forward declaration */ +static void piped_log_maintenance(int reason, void *data, apr_wait_t status); + +/* Spawn the piped logger process pl->program. */ +static apr_status_t piped_log_spawn(piped_log *pl) +{ + apr_procattr_t *procattr; + apr_proc_t *procnew = NULL; + apr_status_t status; + + if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) || + ((status = apr_procattr_cmdtype_set(procattr, + APR_SHELLCMD_ENV)) != APR_SUCCESS) || + ((status = apr_procattr_child_in_set(procattr, + ap_piped_log_read_fd(pl), + ap_piped_log_write_fd(pl))) + != APR_SUCCESS) || + ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn)) + != APR_SUCCESS) || + ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) { + char buf[120]; + /* Something bad happened, give up and go away. */ + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "piped_log_spawn: unable to setup child process '%s': %s", + pl->program, apr_strerror(status, buf, sizeof(buf))); + } + else { + char **args; + const char *pname; + + apr_tokenize_to_argv(pl->program, &args, pl->p); + pname = apr_pstrdup(pl->p, args[0]); + procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t)); + status = apr_proc_create(procnew, pname, (const char * const *) args, + NULL, procattr, pl->p); + + if (status == APR_SUCCESS) { + pl->pid = procnew; + /* procnew->in was dup2'd from ap_piped_log_write_fd(pl); + * since the original fd is still valid, close the copy to + * avoid a leak. */ + apr_file_close(procnew->in); + procnew->in = NULL; + apr_proc_other_child_register(procnew, piped_log_maintenance, pl, + ap_piped_log_write_fd(pl), pl->p); + close_handle_in_child(pl->p, ap_piped_log_read_fd(pl)); + } + else { + char buf[120]; + /* Something bad happened, give up and go away. */ + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "unable to start piped log program '%s': %s", + pl->program, apr_strerror(status, buf, sizeof(buf))); + } + } + + return status; +} + + +static void piped_log_maintenance(int reason, void *data, apr_wait_t status) +{ + piped_log *pl = data; + apr_status_t stats; + int mpm_state; + + switch (reason) { + case APR_OC_REASON_DEATH: + case APR_OC_REASON_LOST: + pl->pid = NULL; /* in case we don't get it going again, this + * tells other logic not to try to kill it + */ + apr_proc_other_child_unregister(pl); + stats = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state); + if (stats != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "can't query MPM state; not restarting " + "piped log program '%s'", + pl->program); + } + else if (mpm_state != AP_MPMQ_STOPPING) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "piped log program '%s' failed unexpectedly", + pl->program); + if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { + /* what can we do? This could be the error log we're having + * problems opening up... */ + char buf[120]; + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "piped_log_maintenance: unable to respawn '%s': %s", + pl->program, apr_strerror(stats, buf, sizeof(buf))); + } + } + break; + + case APR_OC_REASON_UNWRITABLE: + /* We should not kill off the pipe here, since it may only be full. + * If it really is locked, we should kill it off manually. */ + break; + + case APR_OC_REASON_RESTART: + if (pl->pid != NULL) { + apr_proc_kill(pl->pid, SIGTERM); + pl->pid = NULL; + } + break; + + case APR_OC_REASON_UNREGISTER: + break; + } +} + + +static apr_status_t piped_log_cleanup_for_exec(void *data) +{ + piped_log *pl = data; + + apr_file_close(ap_piped_log_read_fd(pl)); + apr_file_close(ap_piped_log_write_fd(pl)); + return APR_SUCCESS; +} + + +static apr_status_t piped_log_cleanup(void *data) +{ + piped_log *pl = data; + + if (pl->pid != NULL) { + apr_proc_kill(pl->pid, SIGTERM); + } + return piped_log_cleanup_for_exec(data); +} + + +AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) +{ + piped_log *pl; + + pl = apr_palloc(p, sizeof (*pl)); + pl->p = p; + pl->program = apr_pstrdup(p, program); + pl->pid = NULL; + if (apr_file_pipe_create(&ap_piped_log_read_fd(pl), + &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) { + return NULL; + } + apr_pool_cleanup_register(p, pl, piped_log_cleanup, + piped_log_cleanup_for_exec); + if (piped_log_spawn(pl) != APR_SUCCESS) { + apr_pool_cleanup_kill(p, pl, piped_log_cleanup); + apr_file_close(ap_piped_log_read_fd(pl)); + apr_file_close(ap_piped_log_write_fd(pl)); + return NULL; + } + return pl; +} + +#else /* !AP_HAVE_RELIABLE_PIPED_LOGS */ + +static apr_status_t piped_log_cleanup(void *data) +{ + piped_log *pl = data; + + apr_file_close(ap_piped_log_write_fd(pl)); + return APR_SUCCESS; +} + +AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) +{ + piped_log *pl; + apr_file_t *dummy = NULL; + int rc; + + rc = log_child(p, program, &dummy); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, + "Couldn't start piped log process"); + return NULL; + } + + pl = apr_palloc(p, sizeof (*pl)); + pl->p = p; + ap_piped_log_read_fd(pl) = NULL; + ap_piped_log_write_fd(pl) = dummy; + apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup); + + return pl; +} + +#endif + +AP_DECLARE(void) ap_close_piped_log(piped_log *pl) +{ + apr_pool_cleanup_run(pl->p, pl, piped_log_cleanup); +} + +AP_IMPLEMENT_HOOK_VOID(error_log, + (const char *file, int line, int level, + apr_status_t status, const server_rec *s, + const request_rec *r, apr_pool_t *pool, + const char *errstr), (file, line, level, + status, s, r, pool, errstr)) + diff --git a/trunk/server/main.c b/trunk/server/main.c new file mode 100644 index 0000000000..732b10097b --- /dev/null +++ b/trunk/server/main.c @@ -0,0 +1,729 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_getopt.h" +#include "apr_general.h" +#include "apr_lib.h" +#include "apr_md5.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" +#include "http_core.h" +#include "http_vhost.h" +#include "apr_uri.h" +#include "util_ebcdic.h" +#include "ap_mpm.h" +#include "mpm_common.h" + +/* WARNING: Win32 binds http_main.c dynamically to the server. Please place + * extern functions and global data in another appropriate module. + * + * Most significant main() global data can be found in http_config.c + */ + +static void show_mpm_settings(void) +{ + int mpm_query_info; + apr_status_t retval; + + printf("Server MPM: %s\n", ap_show_mpm()); + + retval = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info); + + if (retval == APR_SUCCESS) { + printf(" threaded: "); + + if (mpm_query_info == AP_MPMQ_DYNAMIC) { + printf("yes (variable thread count)\n"); + } + else if (mpm_query_info == AP_MPMQ_STATIC) { + printf("yes (fixed thread count)\n"); + } + else { + printf("no\n"); + } + } + + retval = ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_query_info); + + if (retval == APR_SUCCESS) { + printf(" forked: "); + + if (mpm_query_info == AP_MPMQ_DYNAMIC) { + printf("yes (variable process count)\n"); + } + else if (mpm_query_info == AP_MPMQ_STATIC) { + printf("yes (fixed process count)\n"); + } + else { + printf("no\n"); + } + } +} + +static void show_compile_settings(void) +{ + printf("Server version: %s\n", ap_get_server_version()); + printf("Server built: %s\n", ap_get_server_built()); + printf("Server's Module Magic Number: %u:%u\n", + MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR); + + /* sizeof(foo) is long on some platforms so we might as well + * make it long everywhere to keep the printf format + * consistent + */ + printf("Architecture: %ld-bit\n", 8 * (long)sizeof(void *)); + + show_mpm_settings(); + + printf("Server compiled with....\n"); +#ifdef BIG_SECURITY_HOLE + printf(" -D BIG_SECURITY_HOLE\n"); +#endif + +#ifdef SECURITY_HOLE_PASS_AUTHORIZATION + printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n"); +#endif + +#ifdef OS + printf(" -D OS=\"" OS "\"\n"); +#endif + +#ifdef APACHE_MPM_DIR + printf(" -D APACHE_MPM_DIR=\"" APACHE_MPM_DIR "\"\n"); +#endif + +#ifdef HAVE_SHMGET + printf(" -D HAVE_SHMGET\n"); +#endif + +#if APR_FILE_BASED_SHM + printf(" -D APR_FILE_BASED_SHM\n"); +#endif + +#if APR_HAS_SENDFILE + printf(" -D APR_HAS_SENDFILE\n"); +#endif + +#if APR_HAS_MMAP + printf(" -D APR_HAS_MMAP\n"); +#endif + +#ifdef NO_WRITEV + printf(" -D NO_WRITEV\n"); +#endif + +#ifdef NO_LINGCLOSE + printf(" -D NO_LINGCLOSE\n"); +#endif + +#if APR_HAVE_IPV6 + printf(" -D APR_HAVE_IPV6 (IPv4-mapped addresses "); +#ifdef AP_ENABLE_V4_MAPPED + printf("enabled)\n"); +#else + printf("disabled)\n"); +#endif +#endif + +#if APR_USE_FLOCK_SERIALIZE + printf(" -D APR_USE_FLOCK_SERIALIZE\n"); +#endif + +#if APR_USE_SYSVSEM_SERIALIZE + printf(" -D APR_USE_SYSVSEM_SERIALIZE\n"); +#endif + +#if APR_USE_POSIXSEM_SERIALIZE + printf(" -D APR_USE_POSIXSEM_SERIALIZE\n"); +#endif + +#if APR_USE_FCNTL_SERIALIZE + printf(" -D APR_USE_FCNTL_SERIALIZE\n"); +#endif + +#if APR_USE_PROC_PTHREAD_SERIALIZE + printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n"); +#endif + +#if APR_USE_PTHREAD_SERIALIZE + printf(" -D APR_USE_PTHREAD_SERIALIZE\n"); +#endif + +#if APR_PROCESS_LOCK_IS_GLOBAL + printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n"); +#endif + +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT + printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n"); +#endif + +#if APR_HAS_OTHER_CHILD + printf(" -D APR_HAS_OTHER_CHILD\n"); +#endif + +#ifdef AP_HAVE_RELIABLE_PIPED_LOGS + printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n"); +#endif + +#ifdef BUFFERED_LOGS + printf(" -D BUFFERED_LOGS\n"); +#ifdef PIPE_BUF + printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF); +#endif +#endif + +#if APR_CHARSET_EBCDIC + printf(" -D APR_CHARSET_EBCDIC\n"); +#endif + +#ifdef NEED_HASHBANG_EMUL + printf(" -D NEED_HASHBANG_EMUL\n"); +#endif + +#ifdef SHARED_CORE + printf(" -D SHARED_CORE\n"); +#endif + +/* This list displays the compiled in default paths: */ +#ifdef HTTPD_ROOT + printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n"); +#endif + +#ifdef SUEXEC_BIN + printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n"); +#endif + +#if defined(SHARED_CORE) && defined(SHARED_CORE_DIR) + printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n"); +#endif + +#ifdef DEFAULT_PIDLOG + printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n"); +#endif + +#ifdef DEFAULT_SCOREBOARD + printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n"); +#endif + +#ifdef DEFAULT_LOCKFILE + printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n"); +#endif + +#ifdef DEFAULT_ERRORLOG + printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n"); +#endif + +#ifdef AP_TYPES_CONFIG_FILE + printf(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n"); +#endif + +#ifdef SERVER_CONFIG_FILE + printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n"); +#endif +} + +static void destroy_and_exit_process(process_rec *process, + int process_exit_value) +{ + apr_pool_destroy(process->pool); /* and destroy all descendent pools */ + apr_terminate(); + exit(process_exit_value); +} + +static process_rec *create_process(int argc, const char * const *argv) +{ + process_rec *process; + apr_pool_t *cntx; + apr_status_t stat; + + stat = apr_pool_create(&cntx, NULL); + if (stat != APR_SUCCESS) { + /* XXX From the time that we took away the NULL pool->malloc mapping + * we have been unable to log here without segfaulting. + */ + ap_log_error(APLOG_MARK, APLOG_ERR, stat, NULL, + "apr_pool_create() failed to create " + "initial context"); + apr_terminate(); + exit(1); + } + + apr_pool_tag(cntx, "process"); + ap_open_stderr_log(cntx); + + process = apr_palloc(cntx, sizeof(process_rec)); + process->pool = cntx; + + apr_pool_create(&process->pconf, process->pool); + apr_pool_tag(process->pconf, "pconf"); + process->argc = argc; + process->argv = argv; + process->short_name = apr_filepath_name_get(argv[0]); + return process; +} + +static void usage(process_rec *process) +{ + const char *bin = process->argv[0]; + char pad[MAX_STRING_LEN]; + unsigned i; + + for (i = 0; i < strlen(bin); i++) { + pad[i] = ' '; + } + + pad[i] = '\0'; + +#ifdef SHARED_CORE + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL , + "Usage: %s [-R directory] [-D name] [-d directory] [-f file]", + bin); +#else + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Usage: %s [-D name] [-d directory] [-f file]", bin); +#endif + + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " %s [-C \"directive\"] [-c \"directive\"]", pad); + +#ifdef WIN32 + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " %s [-w] [-k start|restart|stop|shutdown]", pad); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " %s [-k install|config|uninstall] [-n service_name]", + pad); +#endif +#ifdef AP_MPM_WANT_SIGNAL_SERVER + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " %s [-k start|restart|graceful|stop]", + pad); +#endif + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " %s [-v] [-V] [-h] [-l] [-L] [-t] [-S]", pad); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Options:"); + +#ifdef SHARED_CORE + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -R directory : specify an alternate location for " + "shared object files"); +#endif + + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -D name : define a name for use in " + " directives"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -d directory : specify an alternate initial " + "ServerRoot"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -f file : specify an alternate ServerConfigFile"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -C \"directive\" : process directive before reading " + "config files"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -c \"directive\" : process directive after reading " + "config files"); + +#ifdef NETWARE + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -n name : set screen name"); +#endif +#ifdef WIN32 + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -n name : set service name and use its " + "ServerConfigFile"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k start : tell Apache to start"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k restart : tell running Apache to do a graceful " + "restart"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k stop|shutdown : tell running Apache to shutdown"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k install : install an Apache service"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k config : change startup Options of an Apache " + "service"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -k uninstall : uninstall an Apache service"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -w : hold open the console window on error"); +#endif + + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -e level : show startup errors of level " + "(see LogLevel)"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -E file : log startup errors to file"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -v : show version number"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -V : show compile settings"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -h : list available command line options " + "(this page)"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -l : list compiled in modules"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -L : list available configuration " + "directives"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -t -D DUMP_VHOSTS : show parsed settings (currently only " + "vhost settings)"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -S : a synonym for -t -D DUMP_VHOSTS"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -t -D DUMP_MODULES : show all loaded modules "); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -M : a synonym for -t -D DUMP_MODULES"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -t : run syntax check for config files"); + + destroy_and_exit_process(process, 1); +} + +int main(int argc, const char * const argv[]) +{ + char c; + int configtestonly = 0; + const char *confname = SERVER_CONFIG_FILE; + const char *def_server_root = HTTPD_ROOT; + const char *temp_error_log = NULL; + const char *error; + process_rec *process; + server_rec *server_conf; + apr_pool_t *pglobal; + apr_pool_t *pconf; + apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */ + apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */ + apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */ + apr_getopt_t *opt; + apr_status_t rv; + module **mod; + const char *optarg; + APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server; + + AP_MONCONTROL(0); /* turn off profiling of startup */ + + apr_app_initialize(&argc, &argv, NULL); + + process = create_process(argc, argv); + pglobal = process->pool; + pconf = process->pconf; + ap_server_argv0 = process->short_name; + +#if APR_CHARSET_EBCDIC + if (ap_init_ebcdic(pglobal) != APR_SUCCESS) { + destroy_and_exit_process(process, 1); + } +#endif + + apr_pool_create(&pcommands, pglobal); + apr_pool_tag(pcommands, "pcommands"); + ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *)); + ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *)); + ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *)); + + error = ap_setup_prelinked_modules(process); + if (error) { + ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, "%s: %s", + ap_server_argv0, error); + destroy_and_exit_process(process, 1); + } + + ap_run_rewrite_args(process); + + /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM + * to safely pass on our args from its rewrite_args() handler. + */ + apr_getopt_init(&opt, pcommands, process->argc, process->argv); + + while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg)) + == APR_SUCCESS) { + char **new; + + switch (c) { + case 'c': + new = (char **)apr_array_push(ap_server_post_read_config); + *new = apr_pstrdup(pcommands, optarg); + break; + + case 'C': + new = (char **)apr_array_push(ap_server_pre_read_config); + *new = apr_pstrdup(pcommands, optarg); + break; + + case 'd': + def_server_root = optarg; + break; + + case 'D': + new = (char **)apr_array_push(ap_server_config_defines); + *new = apr_pstrdup(pcommands, optarg); + /* Setting -D DUMP_VHOSTS is equivalent to setting -S */ + if (strcmp(optarg, "DUMP_VHOSTS") == 0) + configtestonly = 1; + /* Setting -D DUMP_MODULES is equivalent to setting -M */ + if (strcmp(optarg, "DUMP_MODULES") == 0) + configtestonly = 1; + break; + + case 'e': + if (strcasecmp(optarg, "emerg") == 0) { + ap_default_loglevel = APLOG_EMERG; + } + else if (strcasecmp(optarg, "alert") == 0) { + ap_default_loglevel = APLOG_ALERT; + } + else if (strcasecmp(optarg, "crit") == 0) { + ap_default_loglevel = APLOG_CRIT; + } + else if (strncasecmp(optarg, "err", 3) == 0) { + ap_default_loglevel = APLOG_ERR; + } + else if (strncasecmp(optarg, "warn", 4) == 0) { + ap_default_loglevel = APLOG_WARNING; + } + else if (strcasecmp(optarg, "notice") == 0) { + ap_default_loglevel = APLOG_NOTICE; + } + else if (strcasecmp(optarg, "info") == 0) { + ap_default_loglevel = APLOG_INFO; + } + else if (strcasecmp(optarg, "debug") == 0) { + ap_default_loglevel = APLOG_DEBUG; + } + else { + usage(process); + } + break; + + case 'E': + temp_error_log = apr_pstrdup(process->pool, optarg); + break; + + case 'X': + new = (char **)apr_array_push(ap_server_config_defines); + *new = "DEBUG"; + break; + + case 'f': + confname = optarg; + break; + + case 'v': + printf("Server version: %s\n", ap_get_server_version()); + printf("Server built: %s\n", ap_get_server_built()); + destroy_and_exit_process(process, 0); + + case 'V': + show_compile_settings(); + destroy_and_exit_process(process, 0); + + case 'l': + ap_show_modules(); + destroy_and_exit_process(process, 0); + + case 'L': + ap_show_directives(); + destroy_and_exit_process(process, 0); + + case 't': + configtestonly = 1; + break; + + case 'S': + configtestonly = 1; + new = (char **)apr_array_push(ap_server_config_defines); + *new = "DUMP_VHOSTS"; + break; + + case 'M': + configtestonly = 1; + new = (char **)apr_array_push(ap_server_config_defines); + *new = "DUMP_MODULES"; + break; + + case 'h': + case '?': + usage(process); + } + } + + /* bad cmdline option? then we die */ + if (rv != APR_EOF || opt->ind < opt->argc) { + usage(process); + } + + apr_pool_create(&plog, pglobal); + apr_pool_tag(plog, "plog"); + apr_pool_create(&ptemp, pconf); + apr_pool_tag(ptemp, "ptemp"); + + /* Note that we preflight the config file once + * before reading it _again_ in the main loop. + * This allows things, log files configuration + * for example, to settle down. + */ + + ap_server_root = def_server_root; + if (temp_error_log) { + ap_replace_stderr_log(process->pool, temp_error_log); + } + server_conf = ap_read_config(process, ptemp, confname, &ap_conftree); + if (!server_conf) { + destroy_and_exit_process(process, 1); + } + + if (ap_run_pre_config(pconf, plog, ptemp) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0, + NULL, "Pre-configuration failed"); + destroy_and_exit_process(process, 1); + } + + rv = ap_process_config_tree(server_conf, ap_conftree, + process->pconf, ptemp); + if (rv == OK) { + ap_fixup_virtual_hosts(pconf, server_conf); + ap_fini_vhost_config(pconf, server_conf); + apr_hook_sort_all(); + + if (configtestonly) { + ap_run_test_config(pconf, server_conf); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK"); + destroy_and_exit_process(process, 0); + } + } + + signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server); + if (signal_server) { + int exit_status; + + if (signal_server(&exit_status, pconf) != 0) { + destroy_and_exit_process(process, exit_status); + } + } + + /* If our config failed, deal with that here. */ + if (rv != OK) { + destroy_and_exit_process(process, 1); + } + + apr_pool_clear(plog); + + if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, + 0, NULL, "Unable to open logs"); + destroy_and_exit_process(process, 1); + } + + if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0, + NULL, "Configuration Failed"); + destroy_and_exit_process(process, 1); + } + + apr_pool_destroy(ptemp); + + for (;;) { + apr_hook_deregister_all(); + apr_pool_clear(pconf); + + for (mod = ap_prelinked_modules; *mod != NULL; mod++) { + ap_register_hooks(*mod, pconf); + } + + /* This is a hack until we finish the code so that it only reads + * the config file once and just operates on the tree already in + * memory. rbb + */ + ap_conftree = NULL; + apr_pool_create(&ptemp, pconf); + apr_pool_tag(ptemp, "ptemp"); + ap_server_root = def_server_root; + server_conf = ap_read_config(process, ptemp, confname, &ap_conftree); + if (!server_conf) { + destroy_and_exit_process(process, 1); + } + + if (ap_run_pre_config(pconf, plog, ptemp) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, + 0, NULL, "Pre-configuration failed"); + destroy_and_exit_process(process, 1); + } + + if (ap_process_config_tree(server_conf, ap_conftree, process->pconf, + ptemp) != OK) { + destroy_and_exit_process(process, 1); + } + ap_fixup_virtual_hosts(pconf, server_conf); + ap_fini_vhost_config(pconf, server_conf); + apr_hook_sort_all(); + apr_pool_clear(plog); + if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, + 0, NULL, "Unable to open logs"); + destroy_and_exit_process(process, 1); + } + + if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) { + ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, + 0, NULL, "Configuration Failed"); + destroy_and_exit_process(process, 1); + } + + apr_pool_destroy(ptemp); + apr_pool_lock(pconf, 1); + + ap_run_optional_fn_retrieve(); + + if (ap_mpm_run(pconf, plog, server_conf)) + break; + + apr_pool_lock(pconf, 0); + } + + apr_pool_lock(pconf, 0); + destroy_and_exit_process(process, 0); + + return 0; /* Termination 'ok' */ +} + +#ifdef AP_USING_AUTOCONF +/* This ugly little hack pulls any function referenced in exports.c into + * the web server. exports.c is generated during the build, and it + * has all of the APR functions specified by the apr/apr.exports and + * apr-util/aprutil.exports files. + */ +const void *suck_in_APR(void); +const void *suck_in_APR(void) +{ + extern const void *ap_ugly_hack; + + return ap_ugly_hack; +} +#endif diff --git a/trunk/server/mpm/MPM.NAMING b/trunk/server/mpm/MPM.NAMING new file mode 100644 index 0000000000..83c0694d11 --- /dev/null +++ b/trunk/server/mpm/MPM.NAMING @@ -0,0 +1,15 @@ + +The following MPMs currently exist: + + prefork ....... Multi Process Model with Preforking (Apache 1.3) + perchild ...... Multi Process Model with Threading. + Constant number of processes, variable number of threads + each child process can have a different uid/gid. + mpmt_os2 ...... Multi Process Model with Threading on OS/2 + Constant number of processes, variable number of threads. + One acceptor thread per process, multiple workers threads. + winnt ......... Single Process Model with Threading on Windows NT + worker ........ Multi Process model with threads. One acceptor thread, + multiple worker threads. + netware ....... Multi-threaded MPM for Netware + beos .......... Single Process Model with Threading on BeOS diff --git a/trunk/server/mpm/Makefile.in b/trunk/server/mpm/Makefile.in new file mode 100644 index 0000000000..2decbde60f --- /dev/null +++ b/trunk/server/mpm/Makefile.in @@ -0,0 +1,4 @@ + +SUBDIRS = $(MPM_SUBDIR_NAME) + +include $(top_builddir)/build/rules.mk diff --git a/trunk/server/mpm/beos/Makefile.in b/trunk/server/mpm/beos/Makefile.in new file mode 100644 index 0000000000..3f88b0415f --- /dev/null +++ b/trunk/server/mpm/beos/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libbeos.la +LTLIBRARY_SOURCES = beos.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/beos/beos.c b/trunk/server/mpm/beos/beos.c new file mode 100644 index 0000000000..d8be566172 --- /dev/null +++ b/trunk/server/mpm/beos/beos.c @@ -0,0 +1,1207 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The BeOS MPM! + * + * This is a single process, with multiple worker threads. + * + * Under testing I found that given the inability of BeOS to handle threads + * and forks it didn't make sense to try and have a set of "children" threads + * that spawned the "worker" threads, so just missed out the middle mand and + * somehow arrived here. + * + * For 2.1 this has been rewritten to have simpler logic, though there is still + * some simplification that can be done. It's still a work in progress! + * + * TODO Items + * + * - on exit most worker threads segfault trying to access a kernel page. + */ + +#define CORE_PRIVATE + +#include +#include +#include +#include + +#include "apr_strings.h" +#include "apr_portable.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "ap_mpm.h" +#include "beosd.h" +#include "ap_listen.h" +#include "scoreboard.h" +#include "mpm_common.h" +#include "mpm.h" +#include "mpm_default.h" +#include "apr_thread_mutex.h" +#include "apr_poll.h" + +extern int _kset_fd_limit_(int num); + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons: + * 1) in case something goes seriously wrong, we want to stop the server starting + * threads ad infinitum and crashing the server (remember that BeOS has a 192 + * thread per team limit). + * 2) it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ + +/* we only ever have 1 main process running... */ +#define HARD_SERVER_LIMIT 1 + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifdef NO_THREADS +#define HARD_THREAD_LIMIT 1 +#endif +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 50 +#endif + +/* + * Actual definitions of config globals + */ + +static int ap_threads_to_start=0; +static int ap_max_requests_per_thread = 0; +static int min_spare_threads=0; +static int max_spare_threads=0; +static int ap_thread_limit=0; +static int num_listening_sockets = 0; +static int mpm_state = AP_MPMQ_STARTING; +apr_thread_mutex_t *accept_mutex = NULL; + +static apr_pool_t *pconf; /* Pool for config stuff */ + +static int server_pid; + + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We use + * this value to optimize routines that have to scan the entire scoreboard. + */ +int ap_max_child_assigned = -1; +int ap_max_threads_limit = -1; + +static apr_socket_t *udp_sock; +static apr_sockaddr_t *udp_sa; + +server_rec *ap_server_conf; + +/* one_process */ +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static void check_restart(void *data); + +/* When a worker thread gets to the end of it's life it dies with an + * exit value of the code supplied to this function. The thread has + * already had check_restart() registered to be called when dying, so + * we don't concern ourselves with restarting at all here. We do however + * mark the scoreboard slot as belonging to a dead server and zero out + * it's thread_id. + * + * TODO - use the status we set to determine if we need to restart the + * thread. + */ +static void clean_child_exit(int code, int slot) +{ + (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD, + (request_rec*)NULL); + ap_scoreboard_image->servers[0][slot].tid = 0; + exit_thread(code); +} + + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static int volatile child_fatal; +ap_generation_t volatile ap_my_generation = 0; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + /* If the user tries to shut us down twice in quick succession then we + * may well get triggered while we are working through previous attempt + * to shutdown. We won't worry about even reporting it as it seems a little + * pointless. + */ + if (shutdown_pending == 1) + return; + + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +/* sig_coredump attempts to handle all the potential signals we + * may get that should result in a core dump. This is called from + * the signal handler routine, so when we enter we are essentially blocked + * on the signal. Once we exit we will allow the signal to be processed by + * system, which may or may not produce a .core file. All this function does + * is try and respect the users wishes about where that file should be + * located (chdir) and then signal the parent with the signal. + * + * If we called abort() the parent would only see SIGABRT which doesn't provide + * as much information. + */ +static void sig_coredump(int sig) +{ + chdir(ap_coredump_dir); + signal(sig, SIG_DFL); + kill(server_pid, sig); +} + +static void sig_term(int sig) +{ + ap_start_shutdown(); +} + +static void restart(int sig) +{ + ap_start_restart(sig == AP_SIG_GRACEFUL); +} + +/* Handle queries about our inner workings... */ +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_child_assigned; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_NOT_SUPPORTED; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = HARD_SERVER_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = HARD_THREAD_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = HARD_THREAD_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_thread; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = HARD_SERVER_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* This accepts a connection and allows us to handle the error codes better than + * the previous code, while also making it more obvious. + */ +static apr_status_t beos_accept(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans) +{ + apr_socket_t *csd; + apr_status_t status; + int sockdes; + + *accepted = NULL; + status = apr_socket_accept(&csd, lr->sd, ptrans); + if (status == APR_SUCCESS) { + *accepted = csd; + apr_os_sock_get(&sockdes, csd); + return status; + } + + if (APR_STATUS_IS_EINTR(status)) { + return status; + } + /* This switch statement provides us with better error details. */ + switch (status) { +#ifdef ECONNABORTED + case ECONNABORTED: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif +#ifdef ENETUNREACH + case ENETUNREACH: +#endif + break; +#ifdef ENETDOWN + case ENETDOWN: + /* + * When the network layer has been shut down, there + * is not much use in simply exiting: the parent + * would simply re-create us (and we'd fail again). + * Use the CHILDFATAL code to tear the server down. + * @@@ Martin's idea for possible improvement: + * A different approach would be to define + * a new APEXIT_NETDOWN exit code, the reception + * of which would make the parent shutdown all + * children, then idle-loop until it detected that + * the network is up again, and restart the children. + * Ben Hyde noted that temporary ENETDOWN situations + * occur in mobile IP. + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "apr_socket_accept: giving up."); + return APR_EGENERAL; +#endif /*ENETDOWN*/ + + default: + ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, + "apr_socket_accept: (client socket)"); + return APR_EGENERAL; + } + return status; +} + +static void tell_workers_to_exit(void) +{ + apr_size_t len; + int i = 0; + for (i = 0 ; i < ap_max_child_assigned; i++){ + len = 4; + if (apr_socket_sendto(udp_sock, udp_sa, 0, "die!", &len) != APR_SUCCESS) + break; + } +} + +static void set_signals(void) +{ + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + /* The first batch get handled by sig_coredump */ + if (!one_process) { + sa.sa_handler = sig_coredump; + + if (sigaction(SIGSEGV, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)"); + if (sigaction(SIGBUS, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)"); + if (sigaction(SIGABRT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)"); + if (sigaction(SIGILL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)"); + sa.sa_flags = 0; + } + + /* These next two are handled by sig_term */ + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); + + /* We ignore SIGPIPE */ + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)"); + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) +{ + return is_graceful; +} + +/* This is the thread that actually does all the work. */ +static int32 worker_thread(void *dummy) +{ + int worker_slot = (int)dummy; + apr_allocator_t *allocator; + apr_bucket_alloc_t *bucket_alloc; + apr_status_t rv = APR_EINIT; + int last_poll_idx = 0; + sigset_t sig_mask; + int requests_this_child = 0; + apr_pollset_t *pollset = NULL; + ap_listen_rec *lr = NULL; + ap_sb_handle_t *sbh = NULL; + int i; + /* each worker thread is in control of its own destiny...*/ + int this_worker_should_exit = 0; + /* We have 2 pools that we create/use throughout the lifetime of this + * worker. The first and longest lived is the pworker pool. From + * this we create the ptrans pool, the lifetime of which is the same + * as each connection and is reset prior to each attempt to + * process a connection. + */ + apr_pool_t *ptrans = NULL; + apr_pool_t *pworker = NULL; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + + on_exit_thread(check_restart, (void*)worker_slot); + + /* block the signals for this thread only if we're not running as a + * single process. + */ + if (!one_process) { + sigfillset(&sig_mask); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); + } + + /* Each worker thread is fully in control of it's destinay and so + * to allow each thread to handle the lifetime of it's own resources + * we create and use a subcontext for every thread. + * The subcontext is a child of the pconf pool. + */ + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&pworker, pconf, NULL, allocator); + apr_allocator_owner_set(allocator, pworker); + + apr_pool_create(&ptrans, pworker); + apr_pool_tag(ptrans, "transaction"); + + ap_create_sb_handle(&sbh, pworker, 0, worker_slot); + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + /* We add an extra socket here as we add the udp_sock we use for signalling + * death. This gets added after the others. + */ + apr_pollset_create(&pollset, num_listening_sockets + 1, pworker, 0); + + for (lr = ap_listeners, i = num_listening_sockets; i--; lr = lr->next) { + apr_pollfd_t pfd = {0}; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + apr_pollset_add(pollset, &pfd); + } + { + apr_pollfd_t pfd = {0}; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = udp_sock; + pfd.reqevents = APR_POLLIN; + + apr_pollset_add(pollset, &pfd); + } + + bucket_alloc = apr_bucket_alloc_create(pworker); + + mpm_state = AP_MPMQ_RUNNING; + + while (!this_worker_should_exit) { + conn_rec *current_conn; + void *csd; + + /* (Re)initialize this child to a pre-connection state. */ + apr_pool_clear(ptrans); + + if ((ap_max_requests_per_thread > 0 + && requests_this_child++ >= ap_max_requests_per_thread)) + clean_child_exit(0, worker_slot); + + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + apr_thread_mutex_lock(accept_mutex); + + /* We always (presently) have at least 2 sockets we listen on, so + * we don't have the ability for a fast path for a single socket + * as some MPM's allow :( + */ + for (;;) { + apr_int32_t numdesc = 0; + const apr_pollfd_t *pdesc = NULL; + + rv = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (rv != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rv)) { + if (one_process && shutdown_pending) + return; + continue; + } + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + ap_server_conf, "apr_pollset_poll: (listen)"); + clean_child_exit(1, worker_slot); + } + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + + lr = pdesc[last_poll_idx++].client_data; + + /* The only socket we add without client_data is the first, the UDP socket + * we listen on for restart signals. If we've therefore gotten a hit on that + * listener lr will be NULL here and we know we've been told to die. + * Before we jump to the end of the while loop with this_worker_should_exit + * set to 1 (causing us to exit normally we hope) we release the accept_mutex + * as we want every thread to go through this same routine :) + * Bit of a hack, but compared to what I had before... + */ + if (lr == NULL) { + this_worker_should_exit = 1; + apr_thread_mutex_unlock(accept_mutex); + goto got_a_black_spot; + } + goto got_fd; + } +got_fd: + /* Run beos_accept to accept the connection and set things up to + * allow us to process it. We always release the accept_lock here, + * even if we failt o accept as otherwise we'll starve other workers + * which would be bad. + */ + rv = beos_accept(&csd, lr, ptrans); + apr_thread_mutex_unlock(accept_mutex); + + if (rv == APR_EGENERAL) { + /* resource shortage or should-not-occur occured */ + clean_child_exit(1, worker_slot); + } else if (rv != APR_SUCCESS) + continue; + + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, worker_slot, sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, csd); + ap_lingering_close(current_conn); + } + + if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { /* restart? */ + /* yeah, this could be non-graceful restart, in which case the + * parent will kill us soon enough, but why bother checking? + */ + this_worker_should_exit = 1; + } +got_a_black_spot: + } + + apr_pool_destroy(ptrans); + apr_pool_destroy(pworker); + + clean_child_exit(0, worker_slot); +} + +static int make_worker(int slot) +{ + thread_id tid; + + if (slot + 1 > ap_max_child_assigned) + ap_max_child_assigned = slot + 1; + + (void) ap_update_child_status_from_indexes(0, slot, SERVER_STARTING, (request_rec*)NULL); + + if (one_process) { + set_signals(); + ap_scoreboard_image->parent[0].pid = getpid(); + ap_scoreboard_image->servers[0][slot].tid = find_thread(NULL); + return 0; + } + + tid = spawn_thread(worker_thread, "apache_worker", B_NORMAL_PRIORITY, + (void *)slot); + if (tid < B_NO_ERROR) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, + "spawn_thread: Unable to start a new thread"); + /* In case system resources are maxed out, we don't want + * Apache running away with the CPU trying to fork over and + * over and over again. + */ + (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD, + (request_rec*)NULL); + + sleep(10); + return -1; + } + resume_thread(tid); + + ap_scoreboard_image->servers[0][slot].tid = tid; + return 0; +} + +/* When a worker thread exits, this function is called. If we are not in + * a shutdown situation then we restart the worker in the slot that was + * just vacated. + */ +static void check_restart(void *data) +{ + if (!restart_pending && !shutdown_pending) { + int slot = (int)data; + make_worker(slot); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, + "spawning a new worker thread in slot %d", slot); + } +} + +/* Start number_to_start children. This is used to start both the + * initial 'pool' of workers but also to replace existing workers who + * have reached the end of their time. It walks through the scoreboard to find + * an empty slot and starts the worker thread in that slot. + */ +static void startup_threads(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_thread_limit; ++i) { + if (ap_scoreboard_image->servers[0][i].tid) + continue; + + if (make_worker(i) < 0) + break; + + --number_to_start; + } +} + + +/* + * spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(void) +{ + int i; + int free_length; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead = -1; + + /* initialize the free_list */ + free_length = 0; + + for (i = 0; i < ap_thread_limit; ++i) { + if (ap_scoreboard_image->servers[0][i].tid == 0) { + if (free_length < spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } + } + else { + last_non_dead = i; + } + + if (i >= ap_max_child_assigned && free_length >= spawn_rate) { + break; + } + } + ap_max_child_assigned = last_non_dead + 1; + + if (free_length > 0) { + for (i = 0; i < free_length; ++i) { + make_worker(free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } else if (spawn_rate < MAX_SPAWN_RATE) { + spawn_rate *= 2; + } + } else { + spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_threads_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid >= 0) { + if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = -1; + for (i = 0; i < ap_max_child_assigned; ++i) { + if (ap_scoreboard_image->servers[0][i].tid == pid.pid) { + child_slot = i; + break; + } + } + if (child_slot >= 0) { + ap_scoreboard_image->servers[0][child_slot].tid = 0; + (void) ap_update_child_status_from_indexes(0, child_slot, + SERVER_DEAD, + (request_rec*)NULL); + + if (remaining_threads_to_start + && child_slot < ap_thread_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_worker(child_slot); + --remaining_threads_to_start; + } +/* TODO +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_refresh(&pid, status) == 0) { +#endif +*/ + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this + * child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, + "long lost child came home! (pid %ld)", pid.pid); + } + + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_threads_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_threads(remaining_threads_to_start); + remaining_threads_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + perform_idle_server_maintenance(); + } +} + +/* This is called to not only setup and run for the initial time, but also + * when we've asked for a restart. This means it must be able to handle both + * situations. It also means that when we exit here we should have tidied + * up after ourselves fully. + */ +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int remaining_threads_to_start, i,j; + apr_status_t rv; + ap_listen_rec *lr; + pconf = _pconf; + ap_server_conf = s; + + /* Increase the available pool of fd's. This code from + * Joe Kloss + */ + if( FD_SETSIZE > 128 && (i = _kset_fd_limit_( 128 )) < 0 ){ + ap_log_error(APLOG_MARK, APLOG_ERR, i, s, + "could not set FD_SETSIZE (_kset_fd_limit_ failed)"); + } + + /* BeOS R5 doesn't support pipes on select() calls, so we use a + * UDP socket as these are supported in both R5 and BONE. If we only cared + * about BONE we'd use a pipe, but there it is. + * As we have UDP support in APR, now use the APR functions and check all the + * return values... + */ + if (apr_sockaddr_info_get(&udp_sa, "127.0.0.1", APR_UNSPEC, 7772, 0, _pconf) + != APR_SUCCESS){ + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, + "couldn't create control socket information, shutting down"); + return 1; + } + if (apr_socket_create(&udp_sock, udp_sa->family, SOCK_DGRAM, 0, + _pconf) != APR_SUCCESS){ + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, + "couldn't create control socket, shutting down"); + return 1; + } + if (apr_socket_bind(udp_sock, udp_sa) != APR_SUCCESS){ + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s, + "couldn't bind UDP socket!"); + return 1; + } + + if ((num_listening_sockets = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, + "no listening sockets available, shutting down"); + return 1; + } + + ap_log_pid(pconf, ap_pid_fname); + + /* + * Create our locks... + */ + + /* accept_mutex + * used to lock around select so we only have one thread + * in select at a time + */ + rv = apr_thread_mutex_create(&accept_mutex, 0, pconf); + if (rv != APR_SUCCESS) { + /* tsch tsch, can't have more than one thread in the accept loop + at a time so we need to fall on our sword... */ + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create accept lock"); + return 1; + } + + /* + * Startup/shutdown... + */ + + if (!is_graceful) { + /* setup the scoreboard shared memory */ + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + return 1; + } + + for (i = 0; i < HARD_SERVER_LIMIT; i++) { + ap_scoreboard_image->parent[i].pid = 0; + for (j = 0;j < HARD_THREAD_LIMIT; j++) + ap_scoreboard_image->servers[i][j].tid = 0; + } + } + + if (HARD_SERVER_LIMIT == 1) + ap_scoreboard_image->parent[0].pid = getpid(); + + set_signals(); + + /* Sanity checks to avoid thrashing... */ + if (max_spare_threads < min_spare_threads ) + max_spare_threads = min_spare_threads; + + /* If we're doing a graceful_restart then we're going to see a lot + * of threads exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens + * pretty rapidly... and for each one that exits we'll start a new one + * until we reach at least threads_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_threads_to_start = ap_threads_to_start; + /* sanity check on the number to start... */ + if (remaining_threads_to_start > ap_thread_limit) { + remaining_threads_to_start = ap_thread_limit; + } + + /* If we're doing the single process thing or we're in a graceful_restart + * then we don't start threads here. + * if we're in one_process mode we don't want to start threads + * do we?? + */ + if (!is_graceful && !one_process) { + startup_threads(remaining_threads_to_start); + remaining_threads_to_start = 0; + } else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + /* + * record that we've entered the world ! + */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); + + restart_pending = shutdown_pending = 0; + + mpm_state = AP_MPMQ_RUNNING; + + /* We sit in the server_main_loop() until we somehow manage to exit. When + * we do, we need to kill the workers we have, so we start by using the + * tell_workers_to_exit() function, but as it sometimes takes a short while + * to accomplish this we have a pause builtin to allow them the chance to + * gracefully exit. + */ + if (!one_process) { + server_main_loop(remaining_threads_to_start); + tell_workers_to_exit(); + snooze(1000000); + } else { + worker_thread((void*)0); + } + mpm_state = AP_MPMQ_STOPPING; + + /* close the UDP socket we've been using... */ + apr_socket_close(udp_sock); + + if ((one_process || shutdown_pending) && !child_fatal) { + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if ( pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "removed PID file %s (pid=%ld)", pidfile, + (long)getpid()); + } + + if (one_process) { + return 1; + } + + /* + * If we get here we're shutting down... + */ + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + */ + if (beosd_killpg(getpgrp(), SIGTERM) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "killpg SIGTERM"); + + /* use ap_reclaim_child_processes starting with SIGTERM */ + ap_reclaim_child_processes(1); + + if (!child_fatal) { /* already recorded */ + /* record the shutdown in the log */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught SIGTERM, shutting down"); + } + + return 1; + } + + /* we've been told to restart */ + signal(SIGHUP, SIG_IGN); + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); + } else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + /* just before we go, tidy up the lock we created to prevent a + * potential leak of semaphores... + */ + apr_thread_mutex_destroy(accept_mutex); + + return 0; +} + +static int beos_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else + { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + server_pid = getpid(); + } + + beosd_pre_config(); + ap_listen_pre_config(); + ap_threads_to_start = DEFAULT_START_THREADS; + min_spare_threads = DEFAULT_MIN_FREE_THREADS; + max_spare_threads = DEFAULT_MAX_FREE_THREADS; + ap_thread_limit = HARD_THREAD_LIMIT; + ap_pid_fname = DEFAULT_PIDLOG; + ap_max_requests_per_thread = DEFAULT_MAX_REQUESTS_PER_THREAD; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void beos_hooks(apr_pool_t *p) +{ + one_process = 0; + + ap_hook_pre_config(beos_pre_config, NULL, NULL, APR_HOOK_MIDDLE); +} + +static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_to_start = atoi(arg); + if (ap_threads_to_start < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "StartThreads set to a value less than 0, reset to 1"); + ap_threads_to_start = 1; + } + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + return NULL; +} + +static const char *set_threads_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_thread_limit = atoi(arg); + if (ap_thread_limit > HARD_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d exceeds compile time limit " + "of %d servers,", ap_thread_limit, HARD_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering MaxClients to %d. To increase, please " + "see the", HARD_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " HARD_THREAD_LIMIT define in server/mpm/beos/mpm_default.h."); + ap_thread_limit = HARD_THREAD_LIMIT; + } + else if (ap_thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to %d", HARD_THREAD_LIMIT); + ap_thread_limit = HARD_THREAD_LIMIT; + } + return NULL; +} + +static const char *set_max_requests_per_thread (cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_max_requests_per_thread = atoi(arg); + if (ap_max_requests_per_thread < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxRequestsPerThread was set below 0" + "reset to 0, but this may not be what you want."); + ap_max_requests_per_thread = 0; + } + + return NULL; +} + +static const command_rec beos_cmds[] = { +BEOS_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1( "StartThreads", set_threads_to_start, NULL, RSRC_CONF, + "Number of threads to launch at server startup"), +AP_INIT_TAKE1( "MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), +AP_INIT_TAKE1( "MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle children" ), +AP_INIT_TAKE1( "MaxClients", set_threads_limit, NULL, RSRC_CONF, + "Maximum number of children alive at the same time (max threads)" ), +AP_INIT_TAKE1( "MaxRequestsPerThread", set_max_requests_per_thread, NULL, RSRC_CONF, + "Maximum number of requests served by a thread" ), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_beos_module = { + MPM20_MODULE_STUFF, + NULL, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + beos_cmds, /* command apr_table_t */ + beos_hooks /* register_hooks */ +}; + diff --git a/trunk/server/mpm/beos/beos.h b/trunk/server/mpm/beos/beos.h new file mode 100644 index 0000000000..9f6b1caffc --- /dev/null +++ b/trunk/server/mpm/beos/beos.h @@ -0,0 +1,26 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_BEOS_H +#define APACHE_MPM_BEOS_H + +extern int ap_threads_per_child; +extern int ap_pipe_of_death[2]; +extern int ap_extended_status; +extern void clean_child_exit(int); +extern int max_daemons_limit; + +#endif /* APACHE_MPM_BEOS_H */ diff --git a/trunk/server/mpm/beos/config5.m4 b/trunk/server/mpm/beos/config5.m4 new file mode 100644 index 0000000000..4f201408d6 --- /dev/null +++ b/trunk/server/mpm/beos/config5.m4 @@ -0,0 +1,7 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "beos" ; then + apache_apr_flags="--enable-threads" + + APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) +fi diff --git a/trunk/server/mpm/beos/mpm.h b/trunk/server/mpm/beos/mpm.h new file mode 100644 index 0000000000..99704e6108 --- /dev/null +++ b/trunk/server/mpm/beos/mpm.h @@ -0,0 +1,40 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_BEOS_H +#define APACHE_MPM_BEOS_H + +#define BEOS_MPM +#include "scoreboard.h" + +#define MPM_NAME "Beos" +#define MPM_CHILD_PID(i) (ap_scoreboard_image->servers[0][i].tid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_MAX_MEM_FREE + +extern int ap_max_child_assigned; +extern server_rec *ap_server_conf; +extern int ap_threads_per_child; + +#endif /* APACHE_MPM_BEOS_H */ diff --git a/trunk/server/mpm/beos/mpm_default.h b/trunk/server/mpm/beos/mpm_default.h new file mode 100644 index 0000000000..03d4233c18 --- /dev/null +++ b/trunk/server/mpm/beos/mpm_default.h @@ -0,0 +1,76 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* we use the child (c) as zero in our code... */ +#define AP_ID_FROM_CHILD_THREAD(c, t) t +/* as the child is always zero, just return the id... */ +#define AP_CHILD_THREAD_FROM_ID(i) 0 , i + +/* Number of threads to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_THREADS +#define DEFAULT_START_THREADS 10 +#endif + +#ifdef NO_THREADS +#define DEFAULT_THREADS 1 +#endif +#ifndef DEFAULT_THREADS +#define DEFAULT_THREADS 10 +#endif + +/* The following 2 settings are used to control the number of threads + * we have available. Normally the DEFAULT_MAX_FREE_THREADS is set + * to the same as the HARD_THREAD_LIMIT to avoid churning of starting + * new threads to replace threads killed off... + */ + +/* Maximum number of *free* threads --- more than this, and + * they will die off. + */ +#ifndef DEFAULT_MAX_FREE_THREADS +#define DEFAULT_MAX_FREE_THREADS HARD_THREAD_LIMIT +#endif + +/* Minimum --- fewer than this, and more will be created */ +#ifndef DEFAULT_MIN_FREE_THREADS +#define DEFAULT_MIN_FREE_THREADS 1 +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If == 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_THREAD +#define DEFAULT_MAX_REQUESTS_PER_THREAD 0 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/config.m4 b/trunk/server/mpm/config.m4 new file mode 100644 index 0000000000..f8b2022cdd --- /dev/null +++ b/trunk/server/mpm/config.m4 @@ -0,0 +1,63 @@ +AC_MSG_CHECKING(which MPM to use) +AC_ARG_WITH(mpm, +APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use. + MPM={beos|event|worker|prefork|mpmt_os2|perchild|leader|threadpool}),[ + APACHE_MPM=$withval +],[ + if test "x$APACHE_MPM" = "x"; then + APACHE_MPM=prefork + fi +]) +AC_MSG_RESULT($APACHE_MPM) + +apache_cv_mpm=$APACHE_MPM + +ap_mpm_is_threaded () +{ + if test "$apache_cv_mpm" = "worker" -o "$apache_cv_mpm" = "event" -o "$apache_cv_mpm" = "perchild" -o "$apache_cv_mpm" = "leader" -o "$apache_cv_mpm" = "threadpool" ; then + return 0 + else + return 1 + fi +} + +ap_mpm_is_experimental () +{ + if test "$apache_cv_mpm" = "event" -o "$apache_cv_mpm" = "perchild" -o "$apache_cv_mpm" = "leader" -o "$apache_cv_mpm" = "threadpool" ; then + return 0 + else + return 1 + fi +} + +if ap_mpm_is_threaded; then + APR_CHECK_APR_DEFINE(APR_HAS_THREADS) + + if test "x$ac_cv_define_APR_HAS_THREADS" = "xno"; then + AC_MSG_RESULT(The currently selected MPM requires threads which your system seems to lack) + AC_MSG_CHECKING(checking for replacement) + AC_MSG_RESULT(prefork selected) + apache_cv_mpm=prefork + fi +fi + +APACHE_FAST_OUTPUT(server/mpm/Makefile) + +MPM_NAME=$apache_cv_mpm +if ap_mpm_is_experimental; then + AC_MSG_WARN(You have selected an EXPERIMENTAL MPM. Be warned!) + MPM_SUBDIR_NAME=experimental/$MPM_NAME +else + MPM_SUBDIR_NAME=$MPM_NAME +fi +MPM_DIR=server/mpm/$MPM_SUBDIR_NAME +MPM_LIB=$MPM_DIR/lib${MPM_NAME}.la + +if test ! -f "$abs_srcdir/$MPM_DIR/mpm.h"; then + AC_MSG_ERROR(the selected mpm -- $apache_cv_mpm -- is not supported) +fi + +APACHE_SUBST(MPM_NAME) +APACHE_SUBST(MPM_SUBDIR_NAME) +MODLIST="$MODLIST mpm_${MPM_NAME}" + diff --git a/trunk/server/mpm/experimental/event/Makefile.in b/trunk/server/mpm/experimental/event/Makefile.in new file mode 100644 index 0000000000..7c2a1a7a6d --- /dev/null +++ b/trunk/server/mpm/experimental/event/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libevent.la +LTLIBRARY_SOURCES = event.c fdqueue.c pod.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/experimental/event/config5.m4 b/trunk/server/mpm/experimental/event/config5.m4 new file mode 100644 index 0000000000..5e1db5398b --- /dev/null +++ b/trunk/server/mpm/experimental/event/config5.m4 @@ -0,0 +1,6 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "event" ; then + AC_CHECK_FUNCS(pthread_kill) + APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi diff --git a/trunk/server/mpm/experimental/event/event.c b/trunk/server/mpm/experimental/event/event.c new file mode 100644 index 0000000000..45d8458290 --- /dev/null +++ b/trunk/server/mpm/experimental/event/event.c @@ -0,0 +1,2385 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This MPM tries to fix the 'keep alive problem' in HTTP. + * + * After a client completes the first request, the client can keep the + * connection open to send more requests with the same socket. This can save + * signifigant overhead in creating TCP connections. However, the major + * disadvantage is that Apache traditionally keeps an entire child + * process/thread waiting for data from the client. To solve this problem, + * this MPM has a dedicated thread for handling both the Listenting sockets, + * and all sockets that are in a Keep Alive status. + * + * The MPM assumes the underlying apr_pollset implmentation is somewhat + * threadsafe. This currently is only compatible with KQueue and EPoll. This + * enables the MPM to avoid extra high level locking or having to wake up the + * listener thread when a keep-alive socket needs to be sent to it. + * + * This MPM not preform well on older platforms that do not have very good + * threading, like Linux with a 2.4 kernel, but this does not matter, since we + * require EPoll or KQueue. + * + * For FreeBSD, use 5.3. It is possible to run this MPM on FreeBSD 5.2.1, if + * you use libkse (see `man libmap.conf`). + * + * For NetBSD, use at least 2.0. + * + * For Linux, you should use a 2.6 kernel, and make sure your glibc has epoll + * support compiled in. + * + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_thread_mutex.h" +#include "apr_proc_mutex.h" +#include "apr_poll.h" +#include "apr_ring.h" +#include "apr_queue.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#if APR_HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +#if !APR_HAS_THREADS +#error The Event MPM requires APR threads, but they are unavailable. +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "ap_mpm.h" +#include "pod.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "scoreboard.h" +#include "fdqueue.h" +#include "mpm_default.h" +#include "http_vhost.h" + +#include +#include /* for INT_MAX */ + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 16 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 20000 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 64 +#endif + +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 100000 +#endif + +/* + * Actual definitions of config globals + */ + +int ap_threads_per_child = 0; /* Worker threads per child */ +static int ap_daemons_to_start = 0; +static int min_spare_threads = 0; +static int max_spare_threads = 0; +static int ap_daemons_limit = 0; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit; +static int changed_limit_at_restart; +static int dying = 0; +static int workers_may_exit = 0; +static int start_thread_may_exit = 0; +static int listener_may_exit = 0; +static int requests_this_child; +static int num_listensocks = 0; +static int resource_shortage = 0; +static fd_queue_t *worker_queue; +static fd_queue_info_t *worker_queue_info; +static int mpm_state = AP_MPMQ_STARTING; +static int sick_child_detected; + +apr_thread_mutex_t *timeout_mutex; +APR_RING_HEAD(timeout_head_t, conn_state_t); +static struct timeout_head_t timeout_head; + +static apr_pollset_t *event_pollset; + +/* The structure used to pass unique initialization info to each thread */ +typedef struct +{ + int pid; + int tid; + int sd; +} proc_info; + +/* Structure used to pass information to the thread responsible for + * creating the rest of the threads. + */ +typedef struct +{ + apr_thread_t **threads; + apr_thread_t *listener; + int child_num_arg; + apr_threadattr_t *threadattr; +} thread_starter; + +typedef enum +{ + PT_CSD, + PT_ACCEPT +} poll_type_e; + +typedef struct +{ + poll_type_e type; + int status; /*XXX what is this for? 0 and 1 don't make it clear */ + void *baton; +} listener_poll_type; + +#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire + * scoreboard. + */ +int ap_max_daemons_limit = -1; + +static ap_pod_t *pod; + +/* *Non*-shared http_main globals... */ + +server_rec *ap_server_conf; + +/* The worker MPM respects a couple of runtime flags that can aid + * in debugging. Setting the -DNO_DETACH flag will prevent the root process + * from detaching from its controlling terminal. Additionally, setting + * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the + * child_main loop running in the process which originally started up. + * This gives you a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main + thread. Use this instead */ +static pid_t parent_pid; +static apr_os_thread_t *listener_os_thread; + +/* The LISTENER_SIGNAL signal will be sent from the main thread to the + * listener thread to wake it up for graceful termination (what a child + * process from an old generation does when the admin does "apachectl + * graceful"). This signal will be blocked in all threads of a child + * process except for the listener thread. + */ +#define LISTENER_SIGNAL SIGHUP + +/* An array of socket descriptors in use by each thread used to + * perform a non-graceful (forced) shutdown of the server. + */ +static apr_socket_t **worker_sockets; + +static void close_worker_sockets(void) +{ + int i; + for (i = 0; i < ap_threads_per_child; i++) { + if (worker_sockets[i]) { + apr_socket_close(worker_sockets[i]); + worker_sockets[i] = NULL; + } + } +} + +static void wakeup_listener(void) +{ + listener_may_exit = 1; + if (!listener_os_thread) { + /* XXX there is an obscure path that this doesn't handle perfectly: + * right after listener thread is created but before + * listener_os_thread is set, the first worker thread hits an + * error and starts graceful termination + */ + return; + } + /* + * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all + * platforms and wake up the listener thread since it is the only thread + * with SIGHUP unblocked, but that doesn't work on Linux + */ +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, LISTENER_SIGNAL); +#else + kill(ap_my_pid, LISTENER_SIGNAL); +#endif +} + +#define ST_INIT 0 +#define ST_GRACEFUL 1 +#define ST_UNGRACEFUL 2 + +static int terminate_mode = ST_INIT; + +static void signal_threads(int mode) +{ + if (terminate_mode == mode) { + return; + } + terminate_mode = mode; + mpm_state = AP_MPMQ_STOPPING; + + /* in case we weren't called from the listener thread, wake up the + * listener thread + */ + wakeup_listener(); + + /* for ungraceful termination, let the workers exit now; + * for graceful termination, the listener thread will notify the + * workers to exit once it has stopped accepting new connections + */ + if (mode == ST_UNGRACEFUL) { + workers_may_exit = 1; + ap_queue_interrupt_all(worker_queue); + ap_queue_info_term(worker_queue_info); + close_worker_sockets(); /* forcefully kill all current connections */ + } +} + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch (query_code) { + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_IS_ASYNC: + *result = 1; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_per_child; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = ap_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + mpm_state = AP_MPMQ_STOPPING; + if (pchild) { + apr_pool_destroy(pchild); + } + exit(code); +} + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static volatile int child_fatal; +ap_generation_t volatile ap_my_generation; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + mpm_state = AP_MPMQ_STOPPING; + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + mpm_state = AP_MPMQ_STOPPING; + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +static void sig_term(int sig) +{ + ap_start_shutdown(); +} + +static void restart(int sig) +{ + ap_start_restart(sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, + "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) + /* XXX this is really a bad confusing obsolete name + * maybe it should be ap_mpm_process_exiting? + */ +{ + /* note: for a graceful termination, listener_may_exit will be set before + * workers_may_exit, so check listener_may_exit + */ + return listener_may_exit; +} + +/***************************************************************** + * Child process main loop. + */ + +static int process_socket(apr_pool_t * p, apr_socket_t * sock, + conn_state_t * cs, int my_child_num, + int my_thread_num) +{ + conn_rec *c; + listener_poll_type *pt; + long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); + int csd; + int rc; + apr_time_t time_now = 0; + ap_sb_handle_t *sbh; + + ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); + apr_os_sock_get(&csd, sock); + + time_now = apr_time_now(); + + if (cs == NULL) { /* This is a new connection */ + + cs = apr_pcalloc(p, sizeof(conn_state_t)); + + pt = apr_pcalloc(p, sizeof(*pt)); + + cs->bucket_alloc = apr_bucket_alloc_create(p); + c = ap_run_create_connection(p, ap_server_conf, sock, + conn_id, sbh, cs->bucket_alloc); + cs->c = c; + c->cs = cs; + cs->p = p; + cs->pfd.desc_type = APR_POLL_SOCKET; + cs->pfd.reqevents = APR_POLLIN; + cs->pfd.desc.s = sock; + pt->type = PT_CSD; + pt->status = 1; + pt->baton = cs; + cs->pfd.client_data = pt; + + ap_update_vhost_given_ip(c); + + rc = ap_run_pre_connection(c, sock); + if (rc != OK && rc != DONE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "process_socket: connection aborted"); + c->aborted = 1; + } + + /** + * XXX If the platform does not have a usable way of bundling + * accept() with a socket readability check, like Win32, + * and there are measurable delays before the + * socket is readable due to the first data packet arriving, + * it might be better to create the cs on the listener thread, + * set the state to CONN_STATE_CHECK_REQUEST_LINE_READABLE, + * and give it to the event thread. + * + * FreeBSD users will want to enable the HTTP accept filter + * module in their kernel for the highest performance + * When the accept filter is active, sockets are kept in the + * kernel until a HTTP request is received. + */ + cs->state = CONN_STATE_READ_REQUEST_LINE; + + } + else { + c = cs->c; + c->sbh = sbh; + } + + if (cs->state == CONN_STATE_READ_REQUEST_LINE) { + if (!c->aborted) { + ap_run_process_connection(c); + + /* state will be updated upon return + * fall thru to either wait for readability/timeout or + * do lingering close + */ + } + else { + cs->state = CONN_STATE_LINGER; + } + } + + if (cs->state == CONN_STATE_LINGER) { + ap_lingering_close(c); + apr_bucket_alloc_destroy(cs->bucket_alloc); + apr_pool_clear(p); + ap_push_pool(worker_queue_info, p); + return 1; + } + else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) { + apr_status_t rc; + listener_poll_type *pt = (listener_poll_type *) cs->pfd.client_data; + + /* It greatly simplifies the logic to use a single timeout value here + * because the new element can just be added to the end of the list and + * it will stay sorted in expiration time sequence. If brand new + * sockets are sent to the event thread for a readability check, this + * will be a slight behavior change - they use the non-keepalive + * timeout today. With a normal client, the socket will be readable in + * a few milliseconds anyway. + */ + cs->expiration_time = ap_server_conf->keep_alive_timeout + time_now; + apr_thread_mutex_lock(timeout_mutex); + APR_RING_INSERT_TAIL(&timeout_head, cs, conn_state_t, timeout_list); + + pt->status = 0; + /* Add work to pollset. These are always read events */ + rc = apr_pollset_add(event_pollset, &cs->pfd); + + apr_thread_mutex_unlock(timeout_mutex); + + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, + "process_socket: apr_pollset_add failure"); + AP_DEBUG_ASSERT(rc == APR_SUCCESS); + } + } + return 0; +} + +/* requests_this_child has gone to zero or below. See if the admin coded + "MaxRequestsPerChild 0", and keep going in that case. Doing it this way + simplifies the hot path in worker_thread */ +static void check_infinite_requests(void) +{ + if (ap_max_requests_per_child) { + signal_threads(ST_GRACEFUL); + } + else { + /* wow! if you're executing this code, you may have set a record. + * either this child process has served over 2 billion requests, or + * you're running a threaded 2.0 on a 16 bit machine. + * + * I'll buy pizza and beers at Apachecon for the first person to do + * the former without cheating (dorking with INT_MAX, or running with + * uncommitted performance patches, for example). + * + * for the latter case, you probably deserve a beer too. Greg Ames + */ + + requests_this_child = INT_MAX; /* keep going */ + } +} + +static void unblock_signal(int sig) +{ + sigset_t sig_mask; + + sigemptyset(&sig_mask); + sigaddset(&sig_mask, sig); +#if defined(SIGPROCMASK_SETS_THREAD_MASK) + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); +#else + pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); +#endif +} + +static void dummy_signal_handler(int sig) +{ + /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall, + * then we don't need this goofy function. + */ +} + +static apr_status_t push2worker(const apr_pollfd_t * pfd, + apr_pollset_t * pollset) +{ + listener_poll_type *pt = (listener_poll_type *) pfd->client_data; + conn_state_t *cs = (conn_state_t *) pt->baton; + apr_status_t rc; + + if (pt->status == 1) { + return 0; + } + + pt->status = 1; + + rc = apr_pollset_remove(pollset, pfd); + + /* + * Some of the pollset backends, like KQueue or Epoll + * automagically remove the FD if the socket is closed, + * therefore, we can accept _SUCCESS or _NOTFOUND, + * and we still want to keep going + */ + if (rc != APR_SUCCESS && rc != APR_NOTFOUND) { + cs->state = CONN_STATE_LINGER; + } + + rc = ap_queue_push(worker_queue, cs->pfd.desc.s, cs, cs->p); + if (rc != APR_SUCCESS) { + /* trash the connection; we couldn't queue the connected + * socket to a worker + */ + apr_bucket_alloc_destroy(cs->bucket_alloc); + apr_socket_close(cs->pfd.desc.s); + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, + ap_server_conf, "push2worker: ap_queue_push failed"); + apr_pool_clear(cs->p); + ap_push_pool(worker_queue_info, cs->p); + } + + return APR_SUCCESS; +} + +/* get_worker: + * reserve a worker thread, block if all are currently busy. + * this prevents the worker queue from overflowing and lets + * other processes accept new connections in the mean time. + */ +static int get_worker(int *have_idle_worker_p) +{ + apr_status_t rc; + + if (!*have_idle_worker_p) { + rc = ap_queue_info_wait_for_idler(worker_queue_info); + + if (rc == APR_SUCCESS) { + *have_idle_worker_p = 1; + return 1; + } + else { + if (!APR_STATUS_IS_EOF(rc)) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, + "ap_queue_info_wait_for_idler failed. " + "Attempting to shutdown process gracefully"); + signal_threads(ST_GRACEFUL); + } + return 0; + } + } + else { + /* already reserved a worker thread - must have hit a + * transient error on a previous pass + */ + return 1; + } +} + +static void *listener_thread(apr_thread_t * thd, void *dummy) +{ + apr_status_t rc; + proc_info *ti = dummy; + int process_slot = ti->pid; + apr_pool_t *tpool = apr_thread_pool_get(thd); + void *csd = NULL; + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + ap_listen_rec *lr; + int have_idle_worker = 0; + conn_state_t *cs; + const apr_pollfd_t *out_pfd; + apr_int32_t num = 0; + apr_time_t time_now = 0; + apr_interval_time_t timeout_interval; + apr_time_t timeout_time; + listener_poll_type *pt; + + free(ti); + + /* We set this to force apr_pollset to wakeup if there hasn't been any IO + * on any of its sockets. This allows sockets to have been added + * when no other keepalive operations where going on. + * + * current value is 1 second + */ + timeout_interval = 1000000; + + /* the following times out events that are really close in the future + * to prevent extra poll calls + * + * current value is .1 second + */ +#define TIMEOUT_FUDGE_FACTOR 100000 + + /* POLLSET_SCALE_FACTOR * ap_threads_per_child sets the size of + * the pollset. I've seen 15 connections per active worker thread + * running SPECweb99. + * + * However, with the newer apr_pollset, this is the number of sockets that + * we will return to any *one* call to poll(). Therefore, there is no + * reason to make it more than ap_threads_per_child. + */ +#define POLLSET_SCALE_FACTOR 1 + + rc = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT, + tpool); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, + "creation of the timeout mutex failed. Attempting to " + "shutdown process gracefully"); + signal_threads(ST_GRACEFUL); + return NULL; + } + + APR_RING_INIT(&timeout_head, conn_state_t, timeout_list); + + /* Create the main pollset */ + rc = apr_pollset_create(&event_pollset, + ap_threads_per_child * POLLSET_SCALE_FACTOR, + tpool, APR_POLLSET_THREADSAFE); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, + "apr_pollset_create with Thread Safety failed. " + "Attempting to shutdown process gracefully"); + signal_threads(ST_GRACEFUL); + return NULL; + } + + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + pt = apr_pcalloc(tpool, sizeof(*pt)); + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + + pt->type = PT_ACCEPT; + pt->baton = lr; + + pfd.client_data = pt; + + apr_socket_opt_set(pfd.desc.s, APR_SO_NONBLOCK, 1); + apr_pollset_add(event_pollset, &pfd); + } + + /* Unblock the signal used to wake this thread up, and set a handler for + * it. + */ + unblock_signal(LISTENER_SIGNAL); + apr_signal(LISTENER_SIGNAL, dummy_signal_handler); + + while (!listener_may_exit) { + + if (requests_this_child <= 0) { + check_infinite_requests(); + } + + rc = apr_pollset_poll(event_pollset, timeout_interval, &num, + &out_pfd); + + if (rc != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rc)) { + continue; + } + if (!APR_STATUS_IS_TIMEUP(rc)) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, + "apr_pollset_poll failed. Attempting to " + "shutdown process gracefully"); + signal_threads(ST_GRACEFUL); + } + } + + if (listener_may_exit) + break; + + while (num && get_worker(&have_idle_worker)) { + pt = (listener_poll_type *) out_pfd->client_data; + if (pt->type == PT_CSD) { + /* one of the sockets is readable */ + cs = (conn_state_t *) pt->baton; + switch (cs->state) { + case CONN_STATE_CHECK_REQUEST_LINE_READABLE: + cs->state = CONN_STATE_READ_REQUEST_LINE; + break; + default: + ap_log_error(APLOG_MARK, APLOG_ERR, rc, + ap_server_conf, + "event_loop: unexpected state %d", + cs->state); + AP_DEBUG_ASSERT(0); + } + + apr_thread_mutex_lock(timeout_mutex); + APR_RING_REMOVE(cs, timeout_list); + apr_thread_mutex_unlock(timeout_mutex); + + rc = push2worker(out_pfd, event_pollset); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, + ap_server_conf, "push2worker failed"); + } + else { + have_idle_worker = 0; + } + } + else { + /* A Listener Socket is ready for an accept() */ + apr_pool_t *recycled_pool = NULL; + + lr = (ap_listen_rec *) pt->baton; + + ap_pop_pool(&recycled_pool, worker_queue_info); + + if (recycled_pool == NULL) { + /* create a new transaction pool for each accepted socket */ + apr_allocator_t *allocator; + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, + ap_max_mem_free); + apr_pool_create_ex(&ptrans, pconf, NULL, allocator); + apr_allocator_owner_set(allocator, ptrans); + if (ptrans == NULL) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, + ap_server_conf, + "Failed to create transaction pool"); + signal_threads(ST_GRACEFUL); + return NULL; + } + } + else { + ptrans = recycled_pool; + } + + apr_pool_tag(ptrans, "transaction"); + + rc = lr->accept_func(&csd, lr, ptrans); + + /* later we trash rv and rely on csd to indicate + * success/failure + */ + AP_DEBUG_ASSERT(rc == APR_SUCCESS || !csd); + + if (rc == APR_EGENERAL) { + /* E[NM]FILE, ENOMEM, etc */ + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + } + + if (csd != NULL) { + rc = ap_queue_push(worker_queue, csd, NULL, ptrans); + if (rc != APR_SUCCESS) { + /* trash the connection; we couldn't queue the connected + * socket to a worker + */ + apr_socket_close(csd); + ap_log_error(APLOG_MARK, APLOG_CRIT, rc, + ap_server_conf, + "ap_queue_push failed"); + apr_pool_clear(ptrans); + ap_push_pool(worker_queue_info, ptrans); + } + else { + have_idle_worker = 0; + } + } + else { + apr_pool_clear(ptrans); + ap_push_pool(worker_queue_info, ptrans); + } + } /* if:else on pt->type */ + out_pfd++; + num--; + } /* while for processing poll */ + + /* XXX possible optimization: stash the current time for use as + * r->request_time for new requests + */ + time_now = apr_time_now(); + + /* handle timed out sockets */ + apr_thread_mutex_lock(timeout_mutex); + + cs = APR_RING_FIRST(&timeout_head); + timeout_time = time_now + TIMEOUT_FUDGE_FACTOR; + while (!APR_RING_EMPTY(&timeout_head, conn_state_t, timeout_list) + && cs->expiration_time < timeout_time + && get_worker(&have_idle_worker)) { + + cs->state = CONN_STATE_LINGER; + + APR_RING_REMOVE(cs, timeout_list); + + rc = push2worker(&cs->pfd, event_pollset); + + if (rc != APR_SUCCESS) { + return NULL; + /* XXX return NULL looks wrong - not an init failure + * that bypasses all the cleanup outside the main loop + * break seems more like it + * need to evaluate seriousness of push2worker failures + */ + } + have_idle_worker = 0; + cs = APR_RING_FIRST(&timeout_head); + } + apr_thread_mutex_unlock(timeout_mutex); + + } /* listener main loop */ + + ap_queue_term(worker_queue); + dying = 1; + ap_scoreboard_image->parent[process_slot].quiescing = 1; + + /* wake up the main thread */ + kill(ap_my_pid, SIGTERM); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +/* XXX For ungraceful termination/restart, we definitely don't want to + * wait for active connections to finish but we may want to wait + * for idle workers to get out of the queue code and release mutexes, + * since those mutexes are cleaned up pretty soon and some systems + * may not react favorably (i.e., segfault) if operations are attempted + * on cleaned-up mutexes. + */ +static void *APR_THREAD_FUNC worker_thread(apr_thread_t * thd, void *dummy) +{ + proc_info *ti = dummy; + int process_slot = ti->pid; + int thread_slot = ti->tid; + apr_socket_t *csd = NULL; + conn_state_t *cs; + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_status_t rv; + int is_idle = 0; + + free(ti); + + ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid; + ap_scoreboard_image->servers[process_slot][thread_slot].generation = ap_my_generation; + ap_update_child_status_from_indexes(process_slot, thread_slot, + SERVER_STARTING, NULL); + + while (!workers_may_exit) { + if (!is_idle) { + rv = ap_queue_info_set_idle(worker_queue_info, NULL); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "ap_queue_info_set_idle failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + break; + } + is_idle = 1; + } + + ap_update_child_status_from_indexes(process_slot, thread_slot, + SERVER_READY, NULL); + worker_pop: + if (workers_may_exit) { + break; + } + rv = ap_queue_pop(worker_queue, &csd, &cs, &ptrans); + + if (rv != APR_SUCCESS) { + /* We get APR_EOF during a graceful shutdown once all the + * connections accepted by this server process have been handled. + */ + if (APR_STATUS_IS_EOF(rv)) { + break; + } + /* We get APR_EINTR whenever ap_queue_pop() has been interrupted + * from an explicit call to ap_queue_interrupt_all(). This allows + * us to unblock threads stuck in ap_queue_pop() when a shutdown + * is pending. + * + * If workers_may_exit is set and this is ungraceful termination/ + * restart, we are bound to get an error on some systems (e.g., + * AIX, which sanity-checks mutex operations) since the queue + * may have already been cleaned up. Don't log the "error" if + * workers_may_exit is set. + */ + else if (APR_STATUS_IS_EINTR(rv)) { + goto worker_pop; + } + /* We got some other error. */ + else if (!workers_may_exit) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "ap_queue_pop failed"); + } + continue; + } + is_idle = 0; + worker_sockets[thread_slot] = csd; + rv = process_socket(ptrans, csd, cs, process_slot, thread_slot); + if (!rv) { + requests_this_child--; + } + worker_sockets[thread_slot] = NULL; + } + + ap_update_child_status_from_indexes(process_slot, thread_slot, + (dying) ? SERVER_DEAD : + SERVER_GRACEFUL, + (request_rec *) NULL); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static int check_signal(int signum) +{ + switch (signum) { + case SIGTERM: + case SIGINT: + return 1; + } + return 0; +} + + + +static void create_listener_thread(thread_starter * ts) +{ + int my_child_num = ts->child_num_arg; + apr_threadattr_t *thread_attr = ts->threadattr; + proc_info *my_info; + apr_status_t rv; + + my_info = (proc_info *) malloc(sizeof(proc_info)); + my_info->pid = my_child_num; + my_info->tid = -1; /* listener thread doesn't have a thread slot */ + my_info->sd = 0; + rv = apr_thread_create(&ts->listener, thread_attr, listener_thread, + my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create listener thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + apr_os_thread_get(&listener_os_thread, ts->listener); +} + +/* XXX under some circumstances not understood, children can get stuck + * in start_threads forever trying to take over slots which will + * never be cleaned up; for now there is an APLOG_DEBUG message issued + * every so often when this condition occurs + */ +static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) +{ + thread_starter *ts = dummy; + apr_thread_t **threads = ts->threads; + apr_threadattr_t *thread_attr = ts->threadattr; + int child_num_arg = ts->child_num_arg; + int my_child_num = child_num_arg; + proc_info *my_info; + apr_status_t rv; + int i; + int threads_created = 0; + int listener_started = 0; + int loops; + int prev_threads_created; + + /* We must create the fd queues before we start up the listener + * and worker threads. */ + worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue)); + rv = ap_queue_init(worker_queue, ap_threads_per_child, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "ap_queue_init() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + rv = ap_queue_info_create(&worker_queue_info, pchild, + ap_threads_per_child); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "ap_queue_info_create() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + worker_sockets = apr_pcalloc(pchild, ap_threads_per_child + * sizeof(apr_socket_t *)); + + loops = prev_threads_created = 0; + while (1) { + /* ap_threads_per_child does not include the listener thread */ + for (i = 0; i < ap_threads_per_child; i++) { + int status = + ap_scoreboard_image->servers[child_num_arg][i].status; + + if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { + continue; + } + + my_info = (proc_info *) malloc(sizeof(proc_info)); + if (my_info == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + my_info->pid = my_child_num; + my_info->tid = i; + my_info->sd = 0; + + /* We are creating threads right now */ + ap_update_child_status_from_indexes(my_child_num, i, + SERVER_STARTING, NULL); + /* We let each thread update its own scoreboard entry. This is + * done because it lets us deal with tid better. + */ + rv = apr_thread_create(&threads[i], thread_attr, + worker_thread, my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + threads_created++; + } + + /* Start the listener only when there are workers available */ + if (!listener_started && threads_created) { + create_listener_thread(ts); + listener_started = 1; + } + + + if (start_thread_may_exit || threads_created == ap_threads_per_child) { + break; + } + /* wait for previous generation to clean up an entry */ + apr_sleep(apr_time_from_sec(1)); + ++loops; + if (loops % 120 == 0) { /* every couple of minutes */ + if (prev_threads_created == threads_created) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "child %" APR_PID_T_FMT " isn't taking over " + "slots very quickly (%d of %d)", + ap_my_pid, threads_created, + ap_threads_per_child); + } + prev_threads_created = threads_created; + } + } + + /* What state should this child_main process be listed as in the + * scoreboard...? + * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, + * (request_rec *) NULL); + * + * This state should be listed separately in the scoreboard, in some kind + * of process_status, not mixed in with the worker threads' status. + * "life_status" is almost right, but it's in the worker's structure, and + * the name could be clearer. gla + */ + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static void join_workers(apr_thread_t * listener, apr_thread_t ** threads) +{ + int i; + apr_status_t rv, thread_rv; + + if (listener) { + int iter; + + /* deal with a rare timing window which affects waking up the + * listener thread... if the signal sent to the listener thread + * is delivered between the time it verifies that the + * listener_may_exit flag is clear and the time it enters a + * blocking syscall, the signal didn't do any good... work around + * that by sleeping briefly and sending it again + */ + + iter = 0; + while (iter < 10 && +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, 0) +#else + kill(ap_my_pid, 0) +#endif + == 0) { + /* listener not dead yet */ + apr_sleep(apr_time_make(0, 500000)); + wakeup_listener(); + ++iter; + } + if (iter >= 10) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "the listener thread didn't exit"); + } + else { + rv = apr_thread_join(&thread_rv, listener); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join listener thread"); + } + } + } + + for (i = 0; i < ap_threads_per_child; i++) { + if (threads[i]) { /* if we ever created this thread */ + rv = apr_thread_join(&thread_rv, threads[i]); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join worker " + "thread %d", i); + } + } + } +} + +static void join_start_thread(apr_thread_t * start_thread_id) +{ + apr_status_t rv, thread_rv; + + start_thread_may_exit = 1; /* tell it to give up in case it is still + * trying to take over slots from a + * previous generation + */ + rv = apr_thread_join(&thread_rv, start_thread_id); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join the start " "thread"); + } +} + +static void child_main(int child_num_arg) +{ + apr_thread_t **threads; + apr_status_t rv; + thread_starter *ts; + apr_threadattr_t *thread_attr; + apr_thread_t *start_thread_id; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); + apr_pool_create(&pchild, pconf); + + /*stuff to do before we switch id's, so we have permissions. */ + ap_reopen_scoreboard(pchild, NULL, 0); + + if (unixd_setup_child()) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + /* done with init critical section */ + + /* Just use the standard apr_setup_signal_thread to block all signals + * from being received. The child processes no longer use signals for + * any communication with the parent process. + */ + rv = apr_setup_signal_thread(); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize signal thread"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (ap_max_requests_per_child) { + requests_this_child = ap_max_requests_per_child; + } + else { + /* coding a value of zero means infinity */ + requests_this_child = INT_MAX; + } + + /* Setup worker threads */ + + /* clear the storage; we may not create all our threads immediately, + * and we want a 0 entry to indicate a thread which was not created + */ + threads = (apr_thread_t **) calloc(1, + sizeof(apr_thread_t *) * + ap_threads_per_child); + if (threads == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ts = (thread_starter *) apr_palloc(pchild, sizeof(*ts)); + + apr_threadattr_create(&thread_attr, pchild); + /* 0 means PTHREAD_CREATE_JOINABLE */ + apr_threadattr_detach_set(thread_attr, 0); + + if (ap_thread_stacksize != 0) { + apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize); + } + + ts->threads = threads; + ts->listener = NULL; + ts->child_num_arg = child_num_arg; + ts->threadattr = thread_attr; + + rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, + ts, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + + mpm_state = AP_MPMQ_RUNNING; + + /* If we are only running in one_process mode, we will want to + * still handle signals. */ + if (one_process) { + /* Block until we get a terminating signal. */ + apr_signal_thread(check_signal); + /* make sure the start thread has finished; signal_threads() + * and join_workers() depend on that + */ + /* XXX join_start_thread() won't be awakened if one of our + * threads encounters a critical error and attempts to + * shutdown this child + */ + join_start_thread(start_thread_id); + + /* helps us terminate a little more quickly than the dispatch of the + * signal thread; beats the Pipe of Death and the browsers + */ + signal_threads(ST_UNGRACEFUL); + + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + else { /* !one_process */ + /* remove SIGTERM from the set of blocked signals... if one of + * the other threads in the process needs to take us down + * (e.g., for MaxRequestsPerChild) it will send us SIGTERM + */ + unblock_signal(SIGTERM); + apr_signal(SIGTERM, dummy_signal_handler); + /* Watch for any messages from the parent over the POD */ + while (1) { + rv = ap_mpm_pod_check(pod); + if (rv == AP_NORESTART) { + /* see if termination was triggered while we slept */ + switch (terminate_mode) { + case ST_GRACEFUL: + rv = AP_GRACEFUL; + break; + case ST_UNGRACEFUL: + rv = AP_RESTART; + break; + } + } + if (rv == AP_GRACEFUL || rv == AP_RESTART) { + /* make sure the start thread has finished; + * signal_threads() and join_workers depend on that + */ + join_start_thread(start_thread_id); + signal_threads(rv == + AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); + break; + } + } + + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + + free(threads); + + clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); +} + +static int make_child(server_rec * s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + set_signals(); + ap_scoreboard_image->parent[slot].pid = getpid(); + child_main(slot); + } + + if ((pid = fork()) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, + "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); + + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again. */ + apr_sleep(apr_time_from_sec(10)); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* By default, AIX binds to a single processor. This bit unbinds + * children which will then bind to another CPU. + */ + int status = bindprocessor(BINDPROCESS, (int) getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, + "processor unbind failed %d", status); +#endif + RAISE_SIGSTOP(MAKE_CHILD); + + apr_signal(SIGTERM, just_die); + child_main(slot); + + clean_child_exit(0); + } + /* else */ + ap_scoreboard_image->parent[slot].quiescing = 0; + ap_scoreboard_image->parent[slot].pid = pid; + return 0; +} + +/* start up a bunch of children */ +static void startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { + if (ap_scoreboard_image->parent[i].pid != 0) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(void) +{ + int i, j; + int idle_thread_count; + worker_score *ws; + process_score *ps; + int free_length; + int totally_free_length = 0; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + int active_thread_count = 0; + + /* initialize the free_list */ + free_length = 0; + + idle_thread_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_daemons_limit; ++i) { + /* Initialization to satisfy the compiler. It doesn't know + * that ap_threads_per_child is always > 0 */ + int status = SERVER_DEAD; + int any_dying_threads = 0; + int any_dead_threads = 0; + int all_dead_threads = 1; + + if (i >= ap_max_daemons_limit + && totally_free_length == idle_spawn_rate) + break; + ps = &ap_scoreboard_image->parent[i]; + for (j = 0; j < ap_threads_per_child; j++) { + ws = &ap_scoreboard_image->servers[i][j]; + status = ws->status; + + /* XXX any_dying_threads is probably no longer needed GLA */ + any_dying_threads = any_dying_threads || + (status == SERVER_GRACEFUL); + any_dead_threads = any_dead_threads || (status == SERVER_DEAD); + all_dead_threads = all_dead_threads && + (status == SERVER_DEAD || status == SERVER_GRACEFUL); + + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (ps->pid != 0) { /* XXX just set all_dead_threads in outer + for loop if no pid? not much else matters */ + if (status <= SERVER_READY && status != SERVER_DEAD && + !ps->quiescing && ps->generation == ap_my_generation) { + ++idle_thread_count; + } + if (status >= SERVER_READY && status < SERVER_GRACEFUL) { + ++active_thread_count; + } + } + } + if (any_dead_threads + && totally_free_length < idle_spawn_rate + && free_length < MAX_SPAWN_RATE + && (!ps->pid /* no process in the slot */ + || ps->quiescing)) { /* or at least one is going away */ + if (all_dead_threads) { + /* great! we prefer these, because the new process can + * start more threads sooner. So prioritize this slot + * by putting it ahead of any slots with active threads. + * + * first, make room by moving a slot that's potentially still + * in use to the end of the array + */ + free_slots[free_length] = free_slots[totally_free_length]; + free_slots[totally_free_length++] = i; + } + else { + /* slot is still in use - back of the bus + */ + free_slots[free_length] = i; + } + ++free_length; + } + /* XXX if (!ps->quiescing) is probably more reliable GLA */ + if (!any_dying_threads) { + last_non_dead = i; + ++total_non_dead; + } + } + + if (sick_child_detected) { + if (active_thread_count > 0) { + /* some child processes appear to be working. don't kill the + * whole server. + */ + sick_child_detected = 0; + } + else { + /* looks like a basket case. give up. + */ + shutdown_pending = 1; + child_fatal = 1; + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, + ap_server_conf, + "No active workers found..." + " Apache is exiting!"); + /* the child already logged the failure details */ + return; + } + } + + ap_max_daemons_limit = last_non_dead + 1; + + if (idle_thread_count > max_spare_threads) { + /* Kill off one child */ + ap_mpm_pod_signal(pod, TRUE); + idle_spawn_rate = 1; + } + else if (idle_thread_count < min_spare_threads) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (free_length > idle_spawn_rate) { + free_length = idle_spawn_rate; + } + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, ThreadsPerChild " + "or Min/MaxSpareThreads), " + "spawning %d children, there are around %d idle " + "threads, and %d total children", free_length, + idle_thread_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_children_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + else if (processed_status == APEXIT_CHILDSICK) { + /* tell perform_idle_server_maintenance to check into this + * on the next timer pop + */ + sick_child_detected = 1; + } + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + for (i = 0; i < ap_threads_per_child; i++) + ap_update_child_status_from_indexes(child_slot, i, + SERVER_DEAD, + (request_rec *) NULL); + + ap_scoreboard_image->parent[child_slot].pid = 0; + ap_scoreboard_image->parent[child_slot].quiescing = 0; + if (processed_status == APEXIT_CHILDSICK) { + /* resource shortage, minimize the fork rate */ + idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, + status) == 0) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + ap_server_conf, + "long lost child came home! (pid %ld)", + (long) pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_idle_server_maintenance(); + } +} + +int ap_mpm_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) +{ + int remaining_children_to_start; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + first_thread_limit = thread_limit; + + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit or ThreadLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + + set_signals(); + /* Don't thrash... */ + if (max_spare_threads < min_spare_threads + ap_threads_per_child) + max_spare_threads = min_spare_threads + ap_threads_per_child; + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty + * rapidly... and for each one that exits we'll start a new one until + * we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = ap_daemons_to_start; + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } + if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } + else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); + + restart_pending = shutdown_pending = 0; + mpm_state = AP_MPMQ_RUNNING; + + server_main_loop(remaining_children_to_start); + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + * (By "gracefully" we don't mean graceful in the same sense as + * "apachectl graceful" where we allow old connections to finish.) + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ + const char *pidfile = NULL; + pidfile = ap_server_root_relative(pconf, ap_pid_fname); + if (pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long) getpid()); + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "caught SIGTERM, shutting down"); + } + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + + if (one_process) { + /* not worth thinking about */ + return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + AP_SIG_GRACEFUL_STRING + " received. Doing graceful restart"); + /* wake up the children...time to die. But we'll have more soon */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE); + + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. + */ + + } + else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int worker_open_logs(apr_pool_t * p, apr_pool_t * plog, + apr_pool_t * ptemp, server_rec * s) +{ + apr_status_t rv; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT | APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + if (!one_process) { + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT | APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + } + return OK; +} + +static int worker_pre_config(apr_pool_t * pconf, apr_pool_t * plog, + apr_pool_t * ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + ap_directive_t *pdir; + ap_directive_t *max_clients = NULL; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { + if (!max_clients) { + /* we're in the clear, got ThreadsPerChild first */ + break; + } + else { + /* now to swap the data */ + ap_directive_t temp; + + temp.directive = pdir->directive; + temp.args = pdir->args; + /* Make sure you don't change 'next', or you may get loops! */ + /* XXX: first_child, parent, and data can never be set + * for these directives, right? -aaron */ + temp.filename = pdir->filename; + temp.line_num = pdir->line_num; + + pdir->directive = max_clients->directive; + pdir->args = max_clients->args; + pdir->filename = max_clients->filename; + pdir->line_num = max_clients->line_num; + + max_clients->directive = temp.directive; + max_clients->args = temp.args; + max_clients->filename = temp.filename; + max_clients->line_num = temp.line_num; + break; + } + } + else if (!max_clients + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + max_clients = pdir; + } + } + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + rv = apr_pollset_create(&event_pollset, 1, plog, + APR_POLLSET_THREADSAFE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "Couldn't create a Thread Safe Pollset. " + "Is it supported on your platform?"); + return HTTP_INTERNAL_SERVER_ERROR; + } + apr_pollset_destroy(event_pollset); + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + parent_pid = ap_my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + ap_daemons_limit = server_limit; + ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void event_hooks(apr_pool_t * p) +{ + /* The worker open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = { "core.c", NULL }; + one_process = 0; + + ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms * cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms * cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + return NULL; +} + +static const char *set_max_clients(cmd_parms * cmd, void *dummy, + const char *arg) +{ + int max_clients; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + /* It is ok to use ap_threads_per_child here because we are + * sure that it gets set before MaxClients in the pre_config stage. */ + max_clients = atoi(arg); + if (max_clients < ap_threads_per_child) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) must be at least as large", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " as ThreadsPerChild (%d). Automatically", + ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " increasing MaxClients to %d.", ap_threads_per_child); + max_clients = ap_threads_per_child; + } + ap_daemons_limit = max_clients / ap_threads_per_child; + if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) is not an integer multiple", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " of ThreadsPerChild (%d), lowering MaxClients to %d", + ap_threads_per_child, + ap_daemons_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " for a maximum of %d child processes,", + ap_daemons_limit); + max_clients = ap_daemons_limit * ap_threads_per_child; + } + if (ap_daemons_limit > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d would require %d servers,", + max_clients, ap_daemons_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " and would exceed the ServerLimit value of %d.", + server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " Automatically lowering MaxClients to %d. To increase,", + server_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " please see the ServerLimit directive."); + ap_daemons_limit = server_limit; + } + else if (ap_daemons_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; + } + return NULL; +} + +static const char *set_threads_per_child(cmd_parms * cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_per_child = atoi(arg); + if (ap_threads_per_child > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " + "value of %d", ap_threads_per_child, thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "threads, lowering ThreadsPerChild to %d. To increase, " + "please see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + ap_threads_per_child = thread_limit; + } + else if (ap_threads_per_child < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadsPerChild > 0, setting to 1"); + ap_threads_per_child = 1; + } + return NULL; +} +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const char *set_thread_limit(cmd_parms * cmd, void *dummy, + const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d servers,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} + +static const command_rec event_cmds[] = { + UNIX_DAEMON_COMMANDS, + LISTEN_COMMANDS, + AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), + AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum number of child processes for this run of Apache"), + AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle threads, to handle request spikes"), + AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle threads"), + AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, + "Maximum number of threads alive at the same time"), + AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, + "Number of threads each child creates"), + AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum number of worker threads per child process for this " + "run of Apache - Upper limit for ThreadsPerChild"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA mpm_event_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + event_cmds, /* command apr_table_t */ + event_hooks /* register_hooks */ +}; diff --git a/trunk/server/mpm/experimental/event/fdqueue.c b/trunk/server/mpm/experimental/event/fdqueue.c new file mode 100644 index 0000000000..b016d7e969 --- /dev/null +++ b/trunk/server/mpm/experimental/event/fdqueue.c @@ -0,0 +1,420 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdqueue.h" +#include "apr_atomic.h" + +typedef struct recycled_pool +{ + apr_pool_t *pool; + struct recycled_pool *next; +} recycled_pool; + +struct fd_queue_info_t +{ + apr_int32_t idlers; /** + * 0 or positive: number of idle worker threads + * negative: number of threads blocked waiting + * for an idle worker + */ + apr_thread_mutex_t *idlers_mutex; + apr_thread_cond_t *wait_for_idler; + int terminated; + int max_idlers; + recycled_pool *recycled_pools; +}; + +static apr_status_t queue_info_cleanup(void *data_) +{ + fd_queue_info_t *qi = data_; + apr_thread_cond_destroy(qi->wait_for_idler); + apr_thread_mutex_destroy(qi->idlers_mutex); + + /* Clean up any pools in the recycled list */ + for (;;) { + struct recycled_pool *first_pool = qi->recycled_pools; + if (first_pool == NULL) { + break; + } + if (apr_atomic_casptr + ((volatile void **) &(qi->recycled_pools), first_pool->next, + first_pool) == first_pool) { + apr_pool_destroy(first_pool->pool); + } + } + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_create(fd_queue_info_t ** queue_info, + apr_pool_t * pool, int max_idlers) +{ + apr_status_t rv; + fd_queue_info_t *qi; + + qi = apr_palloc(pool, sizeof(*qi)); + memset(qi, 0, sizeof(*qi)); + + rv = apr_thread_mutex_create(&qi->idlers_mutex, APR_THREAD_MUTEX_DEFAULT, + pool); + if (rv != APR_SUCCESS) { + return rv; + } + rv = apr_thread_cond_create(&qi->wait_for_idler, pool); + if (rv != APR_SUCCESS) { + return rv; + } + qi->recycled_pools = NULL; + qi->max_idlers = max_idlers; + apr_pool_cleanup_register(pool, qi, queue_info_cleanup, + apr_pool_cleanup_null); + + *queue_info = qi; + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_set_idle(fd_queue_info_t * queue_info, + apr_pool_t * pool_to_recycle) +{ + apr_status_t rv; + int prev_idlers; + + ap_push_pool(queue_info, pool_to_recycle); + + /* Atomically increment the count of idle workers */ + prev_idlers = apr_atomic_inc32(&(queue_info->idlers)); + + /* If other threads are waiting on a worker, wake one up */ + if (prev_idlers < 0) { + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + AP_DEBUG_ASSERT(0); + return rv; + } + rv = apr_thread_cond_signal(queue_info->wait_for_idler); + if (rv != APR_SUCCESS) { + apr_thread_mutex_unlock(queue_info->idlers_mutex); + return rv; + } + rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + } + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t * queue_info) +{ + apr_status_t rv; + int prev_idlers; + + /* Atomically decrement the idle worker count, saving the old value */ + prev_idlers = apr_atomic_add32(&(queue_info->idlers), -1); + + /* Block if there weren't any idle workers */ + if (prev_idlers <= 0) { + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + AP_DEBUG_ASSERT(0); + apr_atomic_inc32(&(queue_info->idlers)); /* back out dec */ + return rv; + } + /* Re-check the idle worker count to guard against a + * race condition. Now that we're in the mutex-protected + * region, one of two things may have happened: + * - If the idle worker count is still negative, the + * workers are all still busy, so it's safe to + * block on a condition variable. + * - If the idle worker count is non-negative, then a + * worker has become idle since the first check + * of queue_info->idlers above. It's possible + * that the worker has also signaled the condition + * variable--and if so, the listener missed it + * because it wasn't yet blocked on the condition + * variable. But if the idle worker count is + * now non-negative, it's safe for this function to + * return immediately. + * + * A negative value in queue_info->idlers tells how many + * threads are waiting on an idle worker. + */ + if (queue_info->idlers < 0) { + rv = apr_thread_cond_wait(queue_info->wait_for_idler, + queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + apr_status_t rv2; + AP_DEBUG_ASSERT(0); + rv2 = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv2 != APR_SUCCESS) { + return rv2; + } + return rv; + } + } + rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + } + + if (queue_info->terminated) { + return APR_EOF; + } + else { + return APR_SUCCESS; + } +} + + +void ap_push_pool(fd_queue_info_t * queue_info, + apr_pool_t * pool_to_recycle) +{ + /* If we have been given a pool to recycle, atomically link + * it into the queue_info's list of recycled pools + */ + if (pool_to_recycle) { + struct recycled_pool *new_recycle; + new_recycle = (struct recycled_pool *) apr_palloc(pool_to_recycle, + sizeof + (*new_recycle)); + new_recycle->pool = pool_to_recycle; + for (;;) { + new_recycle->next = queue_info->recycled_pools; + if (apr_atomic_casptr + ((volatile void **) &(queue_info->recycled_pools), + new_recycle, new_recycle->next) == new_recycle->next) { + break; + } + } + } +} + +void ap_pop_pool(apr_pool_t ** recycled_pool, fd_queue_info_t * queue_info) +{ + /* Atomically pop a pool from the recycled list */ + + /* This function is safe only as long as it is single threaded because + * it reaches into the queue and accesses "next" which can change. + * We are OK today because it is only called from the listener thread. + * cas-based pushes do not have the same limitation - any number can + * happen concurrently with a single cas-based pop. + */ + + *recycled_pool = NULL; + + + /* Atomically pop a pool from the recycled list */ + for (;;) { + struct recycled_pool *first_pool = queue_info->recycled_pools; + if (first_pool == NULL) { + break; + } + if (apr_atomic_casptr + ((volatile void **) &(queue_info->recycled_pools), + first_pool->next, first_pool) == first_pool) { + *recycled_pool = first_pool->pool; + break; + } + } +} + +apr_status_t ap_queue_info_term(fd_queue_info_t * queue_info) +{ + apr_status_t rv; + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + queue_info->terminated = 1; + apr_thread_cond_broadcast(queue_info->wait_for_idler); + return apr_thread_mutex_unlock(queue_info->idlers_mutex); +} + +/** + * Detects when the fd_queue_t is full. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +#define ap_queue_full(queue) ((queue)->nelts == (queue)->bounds) + +/** + * Detects when the fd_queue_t is empty. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +#define ap_queue_empty(queue) ((queue)->nelts == 0) + +/** + * Callback routine that is called to destroy this + * fd_queue_t when its pool is destroyed. + */ +static apr_status_t ap_queue_destroy(void *data) +{ + fd_queue_t *queue = data; + + /* Ignore errors here, we can't do anything about them anyway. + * XXX: We should at least try to signal an error here, it is + * indicative of a programmer error. -aaron */ + apr_thread_cond_destroy(queue->not_empty); + apr_thread_mutex_destroy(queue->one_big_mutex); + + return APR_SUCCESS; +} + +/** + * Initialize the fd_queue_t. + */ +apr_status_t ap_queue_init(fd_queue_t * queue, int queue_capacity, + apr_pool_t * a) +{ + int i; + apr_status_t rv; + + if ((rv = apr_thread_mutex_create(&queue->one_big_mutex, + APR_THREAD_MUTEX_DEFAULT, + a)) != APR_SUCCESS) { + return rv; + } + if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) { + return rv; + } + + queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t)); + queue->bounds = queue_capacity; + queue->nelts = 0; + + /* Set all the sockets in the queue to NULL */ + for (i = 0; i < queue_capacity; ++i) + queue->data[i].sd = NULL; + + apr_pool_cleanup_register(a, queue, ap_queue_destroy, + apr_pool_cleanup_null); + + return APR_SUCCESS; +} + +/** + * Push a new socket onto the queue. + * + * precondition: ap_queue_info_wait_for_idler has already been called + * to reserve an idle worker thread + */ +apr_status_t ap_queue_push(fd_queue_t * queue, apr_socket_t * sd, + conn_state_t * cs, apr_pool_t * p) +{ + fd_queue_elem_t *elem; + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + AP_DEBUG_ASSERT(!queue->terminated); + AP_DEBUG_ASSERT(!ap_queue_full(queue)); + + elem = &queue->data[queue->nelts]; + elem->sd = sd; + elem->cs = cs; + elem->p = p; + queue->nelts++; + + apr_thread_cond_signal(queue->not_empty); + + if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + return APR_SUCCESS; +} + +/** + * Retrieves the next available socket from the queue. If there are no + * sockets available, it will block until one becomes available. + * Once retrieved, the socket is placed into the address specified by + * 'sd'. + */ +apr_status_t ap_queue_pop(fd_queue_t * queue, apr_socket_t ** sd, + conn_state_t ** cs, apr_pool_t ** p) +{ + fd_queue_elem_t *elem; + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + /* Keep waiting until we wake up and find that the queue is not empty. */ + if (ap_queue_empty(queue)) { + if (!queue->terminated) { + apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); + } + /* If we wake up and it's still empty, then we were interrupted */ + if (ap_queue_empty(queue)) { + rv = apr_thread_mutex_unlock(queue->one_big_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + if (queue->terminated) { + return APR_EOF; /* no more elements ever again */ + } + else { + return APR_EINTR; + } + } + } + + elem = &queue->data[--queue->nelts]; + *sd = elem->sd; + *cs = elem->cs; + *p = elem->p; +#ifdef AP_DEBUG + elem->sd = NULL; + elem->p = NULL; +#endif /* AP_DEBUG */ + + rv = apr_thread_mutex_unlock(queue->one_big_mutex); + return rv; +} + +apr_status_t ap_queue_interrupt_all(fd_queue_t * queue) +{ + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + apr_thread_cond_broadcast(queue->not_empty); + return apr_thread_mutex_unlock(queue->one_big_mutex); +} + +apr_status_t ap_queue_term(fd_queue_t * queue) +{ + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + /* we must hold one_big_mutex when setting this... otherwise, + * we could end up setting it and waking everybody up just after a + * would-be popper checks it but right before they block + */ + queue->terminated = 1; + if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + return ap_queue_interrupt_all(queue); +} diff --git a/trunk/server/mpm/experimental/event/fdqueue.h b/trunk/server/mpm/experimental/event/fdqueue.h new file mode 100644 index 0000000000..5c9a021524 --- /dev/null +++ b/trunk/server/mpm/experimental/event/fdqueue.h @@ -0,0 +1,73 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FDQUEUE_H +#define FDQUEUE_H +#include "httpd.h" +#include +#if APR_HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#include + +typedef struct fd_queue_info_t fd_queue_info_t; + +apr_status_t ap_queue_info_create(fd_queue_info_t ** queue_info, + apr_pool_t * pool, int max_idlers); +apr_status_t ap_queue_info_set_idle(fd_queue_info_t * queue_info, + apr_pool_t * pool_to_recycle); +apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t * queue_info); +apr_status_t ap_queue_info_term(fd_queue_info_t * queue_info); + +struct fd_queue_elem_t +{ + apr_socket_t *sd; + apr_pool_t *p; + conn_state_t *cs; +}; +typedef struct fd_queue_elem_t fd_queue_elem_t; + +struct fd_queue_t +{ + fd_queue_elem_t *data; + int nelts; + int bounds; + apr_thread_mutex_t *one_big_mutex; + apr_thread_cond_t *not_empty; + int terminated; +}; +typedef struct fd_queue_t fd_queue_t; + +void ap_pop_pool(apr_pool_t ** recycled_pool, fd_queue_info_t * queue_info); +void ap_push_pool(fd_queue_info_t * queue_info, + apr_pool_t * pool_to_recycle); + +apr_status_t ap_queue_init(fd_queue_t * queue, int queue_capacity, + apr_pool_t * a); +apr_status_t ap_queue_push(fd_queue_t * queue, apr_socket_t * sd, + conn_state_t * cs, apr_pool_t * p); +apr_status_t ap_queue_pop(fd_queue_t * queue, apr_socket_t ** sd, + conn_state_t ** cs, apr_pool_t ** p); +apr_status_t ap_queue_interrupt_all(fd_queue_t * queue); +apr_status_t ap_queue_term(fd_queue_t * queue); + +#endif /* FDQUEUE_H */ diff --git a/trunk/server/mpm/experimental/event/mpm.h b/trunk/server/mpm/experimental/event/mpm.h new file mode 100644 index 0000000000..67f544eb06 --- /dev/null +++ b/trunk/server/mpm/experimental/event/mpm.h @@ -0,0 +1,51 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoreboard.h" +#include "unixd.h" + +#ifndef APACHE_MPM_EVENT_H +#define APACHE_MPM_EVENT_H + +#define EVENT_MPM + +#define MPM_NAME "Event" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; +extern char ap_coredump_dir[MAX_STRING_LEN]; + +#endif /* APACHE_MPM_EVENT_H */ diff --git a/trunk/server/mpm/experimental/event/mpm_default.h b/trunk/server/mpm/experimental/event/mpm_default.h new file mode 100644 index 0000000000..cb93433208 --- /dev/null +++ b/trunk/server/mpm/experimental/event/mpm_default.h @@ -0,0 +1,69 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 3 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 3 +#endif + +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 25 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/experimental/event/pod.c b/trunk/server/mpm/experimental/event/pod.c new file mode 100644 index 0000000000..7b635d4f8d --- /dev/null +++ b/trunk/server/mpm/experimental/event/pod.c @@ -0,0 +1,109 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pod.h" + +#if APR_HAVE_UNISTD_H +#include +#endif + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t * p, ap_pod_t ** pod) +{ + apr_status_t rv; + + *pod = apr_palloc(p, sizeof(**pod)); + rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); + if (rv != APR_SUCCESS) { + return rv; + } +/* + apr_file_pipe_timeout_set((*pod)->pod_in, 0); +*/ + (*pod)->p = p; + + /* close these before exec. */ + apr_file_inherit_unset((*pod)->pod_in); + apr_file_inherit_unset((*pod)->pod_out); + + return APR_SUCCESS; +} + +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t * pod) +{ + char c; + apr_os_file_t fd; + int rc; + + /* we need to surface EINTR so we'll have to grab the + * native file descriptor and do the OS read() ourselves + */ + apr_os_file_get(&fd, pod->pod_in); + rc = read(fd, &c, 1); + if (rc == 1) { + switch (c) { + case RESTART_CHAR: + return AP_RESTART; + case GRACEFUL_CHAR: + return AP_GRACEFUL; + } + } + return AP_NORESTART; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t * pod) +{ + apr_status_t rv; + + rv = apr_file_close(pod->pod_out); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_file_close(pod->pod_in); + if (rv != APR_SUCCESS) { + return rv; + } + return rv; +} + +static apr_status_t pod_signal_internal(ap_pod_t * pod, int graceful) +{ + apr_status_t rv; + char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; + apr_size_t one = 1; + + rv = apr_file_write(pod->pod_out, &char_of_death, &one); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } + return rv; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t * pod, int graceful) +{ + return pod_signal_internal(pod, graceful); +} + +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t * pod, int num, int graceful) +{ + int i; + apr_status_t rv = APR_SUCCESS; + + for (i = 0; i < num && rv == APR_SUCCESS; i++) { + rv = pod_signal_internal(pod, graceful); + } +} diff --git a/trunk/server/mpm/experimental/event/pod.h b/trunk/server/mpm/experimental/event/pod.h new file mode 100644 index 0000000000..ce9b97e8ea --- /dev/null +++ b/trunk/server/mpm/experimental/event/pod.h @@ -0,0 +1,51 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_main.h" +#include "mpm.h" +#include "mpm_common.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "mpm_default.h" + +#define RESTART_CHAR '$' +#define GRACEFUL_CHAR '!' + +#define AP_RESTART 0 +#define AP_GRACEFUL 1 + +typedef struct ap_pod_t ap_pod_t; + +struct ap_pod_t +{ + apr_file_t *pod_in; + apr_file_t *pod_out; + apr_pool_t *p; +}; + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t * p, ap_pod_t ** pod); +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t * pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t * pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t * pod, int graceful); +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t * pod, int num, int graceful); diff --git a/trunk/server/mpm/experimental/leader/Makefile.in b/trunk/server/mpm/experimental/leader/Makefile.in new file mode 100644 index 0000000000..03f1765edd --- /dev/null +++ b/trunk/server/mpm/experimental/leader/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libleader.la +LTLIBRARY_SOURCES = leader.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/experimental/leader/README b/trunk/server/mpm/experimental/leader/README new file mode 100644 index 0000000000..1981a5beed --- /dev/null +++ b/trunk/server/mpm/experimental/leader/README @@ -0,0 +1,15 @@ +Leader MPM: +This is an experimental variant of the standard worker MPM. +It uses a Leader/Followers design pattern to coordinate work among threads: +http://deuce.doc.wustl.edu/doc/pspdfs/lf.pdf + +To use the leader MPM, add "--with-mpm=leader" to the configure +script's arguments when building the httpd. + +This MPM depends on APR's atomic compare-and-swap operations for +thread synchronization. If you are compiling for an x86 target +and you don't need to support 386s, or you're compiling for a +SPARC and you don't need to run on pre-UltraSPARC chips, add +"--enable-nonportable-atomics=yes" to the configure script's +arguments. This will cause APR to implement atomic operations +using efficient opcodes not available in older CPUs. diff --git a/trunk/server/mpm/experimental/leader/config5.m4 b/trunk/server/mpm/experimental/leader/config5.m4 new file mode 100644 index 0000000000..9a915abf1b --- /dev/null +++ b/trunk/server/mpm/experimental/leader/config5.m4 @@ -0,0 +1,6 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "leader" ; then + AC_CHECK_FUNCS(pthread_kill) + APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi diff --git a/trunk/server/mpm/experimental/leader/leader.c b/trunk/server/mpm/experimental/leader/leader.c new file mode 100644 index 0000000000..fb21911889 --- /dev/null +++ b/trunk/server/mpm/experimental/leader/leader.c @@ -0,0 +1,1998 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_thread_cond.h" +#include "apr_thread_mutex.h" +#include "apr_proc_mutex.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#if APR_HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +#if !APR_HAS_THREADS +#error The Leader/Follower MPM requires APR threads, but they are unavailable. +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "ap_mpm.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "scoreboard.h" +#include "mpm_default.h" +#include "apr_poll.h" + +#include +#include /* for INT_MAX */ + +#include "apr_atomic.h" + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 16 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 20000 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * server_limit are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 64 +#endif + +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 20000 +#endif + +/* + * Actual definitions of config globals + */ + +int ap_threads_per_child = 0; /* Worker threads per child */ +static int ap_daemons_to_start = 0; +static int min_spare_threads = 0; +static int max_spare_threads = 0; +static int ap_daemons_limit = 0; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit; +static int changed_limit_at_restart; +static int dying = 0; +static int workers_may_exit = 0; +static int start_thread_may_exit = 0; +static int requests_this_child; +static int num_listensocks = 0; +static int resource_shortage = 0; +static int mpm_state = AP_MPMQ_STARTING; + +typedef struct worker_wakeup_info worker_wakeup_info; + +/* The structure used to pass unique initialization info to each thread */ +typedef struct { + int pid; + int tid; + int sd; +} proc_info; + + +/* Structure used to pass information to the thread responsible for + * creating the rest of the threads. + */ +typedef struct { + apr_thread_t **threads; + int child_num_arg; + apr_threadattr_t *threadattr; +} thread_starter; + +#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire + * scoreboard. + */ +int ap_max_daemons_limit = -1; + +static ap_pod_t *pod; + +/* *Non*-shared http_main globals... */ + +server_rec *ap_server_conf; + +/* This MPM respects a couple of runtime flags that can aid in debugging. + * Setting the -DNO_DETACH flag will prevent the root process from + * detaching from its controlling terminal. Additionally, setting + * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the + * child_main loop running in the process which originally started up. + * This gives you a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main + thread. Use this instead */ +static pid_t parent_pid; + +/* Locks for accept serialization */ +static apr_proc_mutex_t *accept_mutex; + +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT +#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) +#else +#define SAFE_ACCEPT(stmt) (stmt) +#endif + + +/* Structure used to wake up an idle worker thread + */ +struct worker_wakeup_info { + apr_uint32_t next; /* index into worker_wakeups array, + * used to build a linked list + */ + apr_thread_cond_t *cond; + apr_thread_mutex_t *mutex; +}; + +static worker_wakeup_info *worker_wakeup_create(apr_pool_t *pool) +{ + apr_status_t rv; + worker_wakeup_info *wakeup; + + wakeup = (worker_wakeup_info *)apr_palloc(pool, sizeof(*wakeup)); + if ((rv = apr_thread_cond_create(&wakeup->cond, pool)) != APR_SUCCESS) { + return NULL; + } + if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT, + pool)) != APR_SUCCESS) { + return NULL; + } + /* The wakeup's mutex will be unlocked automatically when + * the worker blocks on the condition variable + */ + apr_thread_mutex_lock(wakeup->mutex); + return wakeup; +} + + +/* Structure used to hold a stack of idle worker threads + */ +typedef struct { + /* 'state' consists of several fields concatenated into a + * single 32-bit int for use with the apr_atomic_cas32() API: + * state & STACK_FIRST is the thread ID of the first thread + * in a linked list of idle threads + * state & STACK_TERMINATED indicates whether the proc is shutting down + * state & STACK_NO_LISTENER indicates whether the process has + * no current listener thread + */ + apr_uint32_t state; +} worker_stack; + +#define STACK_FIRST 0xffff +#define STACK_LIST_END 0xffff +#define STACK_TERMINATED 0x10000 +#define STACK_NO_LISTENER 0x20000 + +static worker_wakeup_info **worker_wakeups = NULL; + +static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max) +{ + worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack)); + stack->state = STACK_NO_LISTENER | STACK_LIST_END; + return stack; +} + +static apr_status_t worker_stack_wait(worker_stack *stack, + apr_uint32_t worker_id) +{ + worker_wakeup_info *wakeup = worker_wakeups[worker_id]; + + while (1) { + apr_uint32_t state = stack->state; + if (state & (STACK_TERMINATED | STACK_NO_LISTENER)) { + if (state & STACK_TERMINATED) { + return APR_EINVAL; + } + if (apr_atomic_cas32(&(stack->state), STACK_LIST_END, state) != + state) { + continue; + } + else { + return APR_SUCCESS; + } + } + wakeup->next = state; + if (apr_atomic_cas32(&(stack->state), worker_id, state) != state) { + continue; + } + else { + return apr_thread_cond_wait(wakeup->cond, wakeup->mutex); + } + } +} + +static apr_status_t worker_stack_awaken_next(worker_stack *stack) +{ + + while (1) { + apr_uint32_t state = stack->state; + apr_uint32_t first = state & STACK_FIRST; + if (first == STACK_LIST_END) { + if (apr_atomic_cas32(&(stack->state), state | STACK_NO_LISTENER, + state) != state) { + continue; + } + else { + return APR_SUCCESS; + } + } + else { + worker_wakeup_info *wakeup = worker_wakeups[first]; + if (apr_atomic_cas32(&(stack->state), (state ^ first) | wakeup->next, + state) != state) { + continue; + } + else { + /* Acquire and release the idle worker's mutex to ensure + * that it's actually waiting on its condition variable + */ + apr_status_t rv; + if ((rv = apr_thread_mutex_lock(wakeup->mutex)) != + APR_SUCCESS) { + return rv; + } + if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) != + APR_SUCCESS) { + return rv; + } + return apr_thread_cond_signal(wakeup->cond); + } + } + } +} + +static apr_status_t worker_stack_term(worker_stack *stack) +{ + int i; + apr_status_t rv; + + while (1) { + apr_uint32_t state = stack->state; + if (apr_atomic_cas32(&(stack->state), state | STACK_TERMINATED, + state) == state) { + break; + } + } + for (i = 0; i < ap_threads_per_child; i++) { + if ((rv = worker_stack_awaken_next(stack)) != APR_SUCCESS) { + return rv; + } + } + return APR_SUCCESS; +} + +static worker_stack *idle_worker_stack; + +#define ST_INIT 0 +#define ST_GRACEFUL 1 +#define ST_UNGRACEFUL 2 + +static int terminate_mode = ST_INIT; + +static void signal_threads(int mode) +{ + if (terminate_mode == mode) { + return; + } + terminate_mode = mode; + mpm_state = AP_MPMQ_STOPPING; + workers_may_exit = 1; + + worker_stack_term(idle_worker_stack); +} + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_per_child; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = ap_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + mpm_state = AP_MPMQ_STOPPING; + if (pchild) { + apr_pool_destroy(pchild); + } + ap_mpm_pod_close(pod); + exit(code); +} + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static volatile int child_fatal; +ap_generation_t volatile ap_my_generation; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + mpm_state = AP_MPMQ_STOPPING; + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + mpm_state = AP_MPMQ_STOPPING; + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +static void sig_term(int sig) +{ + if (ap_my_pid == parent_pid) { + ap_start_shutdown(); + } + else { + signal_threads(ST_GRACEFUL); + } +} + +static void restart(int sig) +{ + ap_start_restart(sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, + "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) + /* XXX this is really a bad confusing obsolete name + * maybe it should be ap_mpm_process_exiting? + */ +{ + return workers_may_exit; +} + +/***************************************************************** + * Child process main loop. + */ + +static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, + int my_thread_num, apr_bucket_alloc_t *bucket_alloc) +{ + conn_rec *current_conn; + long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); + int csd; + ap_sb_handle_t *sbh; + + ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); + apr_os_sock_get(&csd, sock); + + current_conn = ap_run_create_connection(p, ap_server_conf, sock, + conn_id, sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, sock); + ap_lingering_close(current_conn); + } +} + +/* requests_this_child has gone to zero or below. See if the admin coded + "MaxRequestsPerChild 0", and keep going in that case. Doing it this way + simplifies the hot path in worker_thread */ +static void check_infinite_requests(void) +{ + if (ap_max_requests_per_child) { + signal_threads(ST_GRACEFUL); + } + else { + /* wow! if you're executing this code, you may have set a record. + * either this child process has served over 2 billion requests, or + * you're running a threaded 2.0 on a 16 bit machine. + * + * I'll buy pizza and beers at Apachecon for the first person to do + * the former without cheating (dorking with INT_MAX, or running with + * uncommitted performance patches, for example). + * + * for the latter case, you probably deserve a beer too. Greg Ames + */ + + requests_this_child = INT_MAX; /* keep going */ + } +} + +static void unblock_signal(int sig) +{ + sigset_t sig_mask; + + sigemptyset(&sig_mask); + sigaddset(&sig_mask, sig); +#if defined(SIGPROCMASK_SETS_THREAD_MASK) + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); +#else + pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); +#endif +} + +static void *worker_thread(apr_thread_t *thd, void * dummy) +{ + proc_info * ti = dummy; + int process_slot = ti->pid; + int thread_slot = ti->tid; + apr_uint32_t my_worker_num = (apr_uint32_t)(ti->tid); + apr_pool_t *tpool = apr_thread_pool_get(thd); + void *csd = NULL; + apr_allocator_t *allocator; + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_bucket_alloc_t *bucket_alloc; + int numdesc; + apr_pollset_t *pollset; + apr_status_t rv; + ap_listen_rec *lr; + int is_listener; + int last_poll_idx = 0; + + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); + + free(ti); + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + /* XXX: why is ptrans's parent not tpool? --jcw 08/2003 */ + apr_pool_create_ex(&ptrans, NULL, NULL, allocator); + apr_allocator_owner_set(allocator, ptrans); + bucket_alloc = apr_bucket_alloc_create_ex(allocator); + + apr_pollset_create(&pollset, num_listensocks, tpool, 0); + for (lr = ap_listeners ; lr != NULL ; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + /* ### check the status */ + (void) apr_pollset_add(pollset, &pfd); + } + + /* TODO: Switch to a system where threads reuse the results from earlier + poll calls - manoj */ + is_listener = 0; + while (!workers_may_exit) { + + ap_update_child_status_from_indexes(process_slot, thread_slot, + SERVER_READY, NULL); + if (!is_listener) { + /* Wait until it's our turn to become the listener */ + if ((rv = worker_stack_wait(idle_worker_stack, my_worker_num)) != + APR_SUCCESS) { + if (rv != APR_EINVAL) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "worker_stack_wait failed. Shutting down"); + } + break; + } + if (workers_may_exit) { + break; + } + is_listener = 1; + } + + /* TODO: requests_this_child should be synchronized - aaron */ + if (requests_this_child <= 0) { + check_infinite_requests(); + } + if (workers_may_exit) break; + + if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (workers_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_lock failed. Attempting to shutdown " + "process gracefully."); + signal_threads(ST_GRACEFUL); + break; /* skip the lock release */ + } + + if (!ap_listeners->next) { + /* Only one listener, so skip the poll */ + lr = ap_listeners; + } + else { + while (!workers_may_exit) { + apr_status_t ret; + const apr_pollfd_t *pdesc; + + ret = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (ret != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(ret)) { + continue; + } + + /* apr_pollset_poll() will only return errors in catastrophic + * circumstances. Let's try exiting gracefully, for now. */ + ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) + ap_server_conf, "apr_pollset_poll: (listen)"); + signal_threads(ST_GRACEFUL); + } + + if (workers_may_exit) break; + + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + lr = pdesc[last_poll_idx++].client_data; + goto got_fd; + } + } + got_fd: + if (!workers_may_exit) { + rv = lr->accept_func(&csd, lr, ptrans); + /* later we trash rv and rely on csd to indicate success/failure */ + AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); + + if (rv == APR_EGENERAL) { + /* E[NM]FILE, ENOMEM, etc */ + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + } + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (workers_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + if (csd != NULL) { + is_listener = 0; + worker_stack_awaken_next(idle_worker_stack); + process_socket(ptrans, csd, process_slot, + thread_slot, bucket_alloc); + apr_pool_clear(ptrans); + requests_this_child--; + } + if ((ap_mpm_pod_check(pod) == APR_SUCCESS) || + (ap_my_generation != + ap_scoreboard_image->global->running_generation)) { + signal_threads(ST_GRACEFUL); + break; + } + } + else { + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + break; + } + } + + dying = 1; + ap_scoreboard_image->parent[process_slot].quiescing = 1; + + worker_stack_term(idle_worker_stack); + + ap_update_child_status_from_indexes(process_slot, thread_slot, + (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); + + apr_bucket_alloc_destroy(bucket_alloc); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static int check_signal(int signum) +{ + switch (signum) { + case SIGTERM: + case SIGINT: + return 1; + } + return 0; +} + +/* XXX under some circumstances not understood, children can get stuck + * in start_threads forever trying to take over slots which will + * never be cleaned up; for now there is an APLOG_DEBUG message issued + * every so often when this condition occurs + */ +static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) +{ + thread_starter *ts = dummy; + apr_thread_t **threads = ts->threads; + apr_threadattr_t *thread_attr = ts->threadattr; + int child_num_arg = ts->child_num_arg; + int my_child_num = child_num_arg; + proc_info *my_info; + apr_status_t rv; + int i; + int threads_created = 0; + int loops; + int prev_threads_created; + + idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child); + if (idle_worker_stack == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, + "worker_stack_create() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + worker_wakeups = (worker_wakeup_info **) + apr_palloc(pchild, sizeof(worker_wakeup_info *) * + ap_threads_per_child); + + loops = prev_threads_created = 0; + while (1) { + for (i = 0; i < ap_threads_per_child; i++) { + int status = ap_scoreboard_image->servers[child_num_arg][i].status; + worker_wakeup_info *wakeup; + + if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { + continue; + } + + wakeup = worker_wakeup_create(pchild); + if (wakeup == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, + ap_server_conf, "worker_wakeup_create failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + worker_wakeups[threads_created] = wakeup; + my_info = (proc_info *)malloc(sizeof(proc_info)); + if (my_info == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + my_info->pid = my_child_num; + my_info->tid = i; + my_info->sd = 0; + + /* We are creating threads right now */ + ap_update_child_status_from_indexes(my_child_num, i, + SERVER_STARTING, NULL); + /* We let each thread update its own scoreboard entry. This is + * done because it lets us deal with tid better. + */ + rv = apr_thread_create(&threads[i], thread_attr, + worker_thread, my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again if we exit. */ + apr_sleep(10 * APR_USEC_PER_SEC); + clean_child_exit(APEXIT_CHILDFATAL); + } + threads_created++; + } + if (start_thread_may_exit || threads_created == ap_threads_per_child) { + break; + } + /* wait for previous generation to clean up an entry */ + apr_sleep(1 * APR_USEC_PER_SEC); + ++loops; + if (loops % 120 == 0) { /* every couple of minutes */ + if (prev_threads_created == threads_created) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "child %" APR_PID_T_FMT " isn't taking over " + "slots very quickly (%d of %d)", + ap_my_pid, threads_created, ap_threads_per_child); + } + prev_threads_created = threads_created; + } + } + + /* What state should this child_main process be listed as in the + * scoreboard...? + * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, + * (request_rec *) NULL); + * + * This state should be listed separately in the scoreboard, in some kind + * of process_status, not mixed in with the worker threads' status. + * "life_status" is almost right, but it's in the worker's structure, and + * the name could be clearer. gla + */ + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static void join_workers(apr_thread_t **threads) +{ + int i; + apr_status_t rv, thread_rv; + + for (i = 0; i < ap_threads_per_child; i++) { + if (threads[i]) { /* if we ever created this thread */ + rv = apr_thread_join(&thread_rv, threads[i]); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join worker " + "thread %d", + i); + } + } + } +} + +static void join_start_thread(apr_thread_t *start_thread_id) +{ + apr_status_t rv, thread_rv; + + start_thread_may_exit = 1; /* tell it to give up in case it is still + * trying to take over slots from a + * previous generation + */ + rv = apr_thread_join(&thread_rv, start_thread_id); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join the start " + "thread"); + } +} + +static void child_main(int child_num_arg) +{ + apr_thread_t **threads; + apr_status_t rv; + thread_starter *ts; + apr_threadattr_t *thread_attr; + apr_thread_t *start_thread_id; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + + ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); + apr_pool_create(&pchild, pconf); + + /*stuff to do before we switch id's, so we have permissions.*/ + ap_reopen_scoreboard(pchild, NULL, 0); + + rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, + pchild)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize cross-process lock in child"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (unixd_setup_child()) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + /* done with init critical section */ + + /* Just use the standard apr_setup_signal_thread to block all signals + * from being received. The child processes no longer use signals for + * any communication with the parent process. + */ + rv = apr_setup_signal_thread(); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize signal thread"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (ap_max_requests_per_child) { + requests_this_child = ap_max_requests_per_child; + } + else { + /* coding a value of zero means infinity */ + requests_this_child = INT_MAX; + } + + /* Setup worker threads */ + + /* clear the storage; we may not create all our threads immediately, + * and we want a 0 entry to indicate a thread which was not created + */ + threads = (apr_thread_t **)calloc(1, + sizeof(apr_thread_t *) * ap_threads_per_child); + if (threads == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); + + apr_threadattr_create(&thread_attr, pchild); + /* 0 means PTHREAD_CREATE_JOINABLE */ + apr_threadattr_detach_set(thread_attr, 0); + if (ap_thread_stacksize != 0) { + apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize); + } + + ts->threads = threads; + ts->child_num_arg = child_num_arg; + ts->threadattr = thread_attr; + + rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, + ts, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again if we exit. */ + apr_sleep(10 * APR_USEC_PER_SEC); + clean_child_exit(APEXIT_CHILDFATAL); + } + + mpm_state = AP_MPMQ_RUNNING; + + /* If we are only running in one_process mode, we will want to + * still handle signals. */ + if (one_process) { + /* Block until we get a terminating signal. */ + apr_signal_thread(check_signal); + /* make sure the start thread has finished; signal_threads() + * and join_workers() depend on that + */ + /* XXX join_start_thread() won't be awakened if one of our + * threads encounters a critical error and attempts to + * shutdown this child + */ + join_start_thread(start_thread_id); + signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more + * quickly than the dispatch of the signal thread + * beats the Pipe of Death and the browsers + */ + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(threads); + } + else { /* !one_process */ + /* remove SIGTERM from the set of blocked signals... if one of + * the other threads in the process needs to take us down + * (e.g., for MaxRequestsPerChild) it will send us SIGTERM + */ + unblock_signal(SIGTERM); + join_start_thread(start_thread_id); + join_workers(threads); + } + + free(threads); + + clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); +} + +static int make_child(server_rec *s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + set_signals(); + ap_scoreboard_image->parent[slot].pid = getpid(); + child_main(slot); + } + + if ((pid = fork()) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, + "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); + + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again. */ + apr_sleep(10 * APR_USEC_PER_SEC); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* By default, AIX binds to a single processor. This bit unbinds + * children which will then bind to another CPU. + */ + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, + "processor unbind failed %d", status); +#endif + RAISE_SIGSTOP(MAKE_CHILD); + + apr_signal(SIGTERM, just_die); + child_main(slot); + + clean_child_exit(0); + } + /* else */ + ap_scoreboard_image->parent[slot].quiescing = 0; + ap_scoreboard_image->parent[slot].pid = pid; + return 0; +} + +/* start up a bunch of children */ +static void startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { + if (ap_scoreboard_image->parent[i].pid != 0) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(void) +{ + int i, j; + int idle_thread_count; + worker_score *ws; + process_score *ps; + int free_length; + int totally_free_length = 0; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + + /* initialize the free_list */ + free_length = 0; + + idle_thread_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_daemons_limit; ++i) { + /* Initialization to satisfy the compiler. It doesn't know + * that ap_threads_per_child is always > 0 */ + int status = SERVER_DEAD; + int any_dying_threads = 0; + int any_dead_threads = 0; + int all_dead_threads = 1; + + if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) + break; + ps = &ap_scoreboard_image->parent[i]; + for (j = 0; j < ap_threads_per_child; j++) { + ws = &ap_scoreboard_image->servers[i][j]; + status = ws->status; + + /* XXX any_dying_threads is probably no longer needed GLA */ + any_dying_threads = any_dying_threads || + (status == SERVER_GRACEFUL); + any_dead_threads = any_dead_threads || (status == SERVER_DEAD); + all_dead_threads = all_dead_threads && + (status == SERVER_DEAD || + status == SERVER_GRACEFUL); + + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (status <= SERVER_READY && status != SERVER_DEAD && + !ps->quiescing && + ps->generation == ap_my_generation && + /* XXX the following shouldn't be necessary if we clean up + * properly after seg faults, but we're not yet GLA + */ + ps->pid != 0) { + ++idle_thread_count; + } + } + if (any_dead_threads && totally_free_length < idle_spawn_rate + && (!ps->pid /* no process in the slot */ + || ps->quiescing)) { /* or at least one is going away */ + if (all_dead_threads) { + /* great! we prefer these, because the new process can + * start more threads sooner. So prioritize this slot + * by putting it ahead of any slots with active threads. + * + * first, make room by moving a slot that's potentially still + * in use to the end of the array + */ + free_slots[free_length] = free_slots[totally_free_length]; + free_slots[totally_free_length++] = i; + } + else { + /* slot is still in use - back of the bus + */ + free_slots[free_length] = i; + } + ++free_length; + } + /* XXX if (!ps->quiescing) is probably more reliable GLA */ + if (!any_dying_threads) { + last_non_dead = i; + ++total_non_dead; + } + } + ap_max_daemons_limit = last_non_dead + 1; + + if (idle_thread_count > max_spare_threads) { + /* Kill off one child */ + ap_mpm_pod_signal(pod); + idle_spawn_rate = 1; + } + else if (idle_thread_count < min_spare_threads) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (free_length > idle_spawn_rate) { + free_length = idle_spawn_rate; + } + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, ThreadsPerChild " + "or Min/MaxSpareThreads), " + "spawning %d children, there are around %d idle " + "threads, and %d total children", free_length, + idle_thread_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_children_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + for (i = 0; i < ap_threads_per_child; i++) + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); + + ap_scoreboard_image->parent[child_slot].pid = 0; + ap_scoreboard_image->parent[child_slot].quiescing = 0; + if (processed_status == APEXIT_CHILDSICK) { + /* resource shortage, minimize the fork rate */ + idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, + status) == 0) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + ap_server_conf, + "long lost child came home! (pid %ld)", + (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_idle_server_maintenance(); + } +} + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int remaining_children_to_start; + apr_status_t rv; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + first_thread_limit = thread_limit; + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit or ThreadLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + /* Initialize cross-process accept lock */ + ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, + ap_server_root_relative(_pconf, ap_lock_fname), + ap_my_pid); + + rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, + ap_accept_lock_mech, _pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create accept lock"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_proc_mutex_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock; " + "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + + set_signals(); + /* Don't thrash... */ + if (max_spare_threads < min_spare_threads + ap_threads_per_child) + max_spare_threads = min_spare_threads + ap_threads_per_child; + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty + * rapidly... and for each one that exits we'll start a new one until + * we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = ap_daemons_to_start; + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } + if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } + else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + mpm_state = AP_MPMQ_RUNNING; + + server_main_loop(remaining_children_to_start); + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + * (By "gracefully" we don't mean graceful in the same sense as + * "apachectl graceful" where we allow old connections to finish.) + */ + if (unixd_killpg(getpgrp(), SIGTERM) < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); + } + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if ( pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long)getpid()); + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "caught SIGTERM, shutting down"); + } + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + + if (one_process) { + /* not worth thinking about */ + return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); + /* wake up the children...time to die. But we'll have more soon */ + ap_mpm_pod_killpg(pod, ap_daemons_limit); + + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. + */ + + } + else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit); + + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int leader_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + if (!one_process) { + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + } + return OK; +} + +static int leader_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + ap_directive_t *pdir; + ap_directive_t *max_clients = NULL; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { + if (!max_clients) { + break; /* we're in the clear, got ThreadsPerChild first */ + } + else { + /* now to swap the data */ + ap_directive_t temp; + + temp.directive = pdir->directive; + temp.args = pdir->args; + /* Make sure you don't change 'next', or you may get loops! */ + /* XXX: first_child, parent, and data can never be set + * for these directives, right? -aaron */ + temp.filename = pdir->filename; + temp.line_num = pdir->line_num; + + pdir->directive = max_clients->directive; + pdir->args = max_clients->args; + pdir->filename = max_clients->filename; + pdir->line_num = max_clients->line_num; + + max_clients->directive = temp.directive; + max_clients->args = temp.args; + max_clients->filename = temp.filename; + max_clients->line_num = temp.line_num; + break; + } + } + else if (!max_clients + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + max_clients = pdir; + } + } + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + parent_pid = ap_my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + ap_daemons_limit = server_limit; + ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void leader_hooks(apr_pool_t *p) +{ + /* The leader open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + one_process = 0; + + ap_hook_open_logs(leader_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(leader_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + return NULL; +} + +static const char *set_max_clients (cmd_parms *cmd, void *dummy, + const char *arg) +{ + int max_clients; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + /* It is ok to use ap_threads_per_child here because we are + * sure that it gets set before MaxClients in the pre_config stage. */ + max_clients = atoi(arg); + if (max_clients < ap_threads_per_child) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) must be at least as large", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " large as ThreadsPerChild (%d). Automatically", + ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " increasing MaxClients to %d.", + ap_threads_per_child); + max_clients = ap_threads_per_child; + } + ap_daemons_limit = max_clients / ap_threads_per_child; + if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) is not an integer multiple", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " of ThreadsPerChild (%d), lowering MaxClients to %d", + ap_threads_per_child, + ap_daemons_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " for a maximum of %d child processes,", + ap_daemons_limit); + max_clients = ap_daemons_limit * ap_threads_per_child; + } + if (ap_daemons_limit > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d would require %d servers,", + max_clients, ap_daemons_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " and would exceed the ServerLimit value of %d.", + server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " Automatically lowering MaxClients to %d. To increase,", + server_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " please see the ServerLimit directive."); + ap_daemons_limit = server_limit; + } + else if (ap_daemons_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; + } + return NULL; +} + +static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_per_child = atoi(arg); + if (ap_threads_per_child > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " + "value of %d", ap_threads_per_child, + thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "threads, lowering ThreadsPerChild to %d. To increase, please" + " see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + ap_threads_per_child = thread_limit; + } + else if (ap_threads_per_child < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadsPerChild > 0, setting to 1"); + ap_threads_per_child = 1; + } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && + tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d servers,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} + +static const command_rec leader_cmds[] = { +UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), +AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle children"), +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, + "Maximum number of children alive at the same time"), +AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, + "Number of threads each child creates"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum value of MaxClients for this run of Apache"), +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum worker threads in a server for this run of Apache"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_leader_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + leader_cmds, /* command apr_table_t */ + leader_hooks /* register_hooks */ +}; + diff --git a/trunk/server/mpm/experimental/leader/mpm.h b/trunk/server/mpm/experimental/leader/mpm.h new file mode 100644 index 0000000000..78b1048e84 --- /dev/null +++ b/trunk/server/mpm/experimental/leader/mpm.h @@ -0,0 +1,52 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoreboard.h" +#include "unixd.h" + +#ifndef APACHE_MPM_LEADER_H +#define APACHE_MPM_LEADER_H + +#define LEADER_MPM + +#define MPM_NAME "Leader-Follower" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + +#define AP_MPM_USES_POD 1 +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; +extern char ap_coredump_dir[MAX_STRING_LEN]; + +#endif /* APACHE_MPM_LEADER_H */ diff --git a/trunk/server/mpm/experimental/leader/mpm_default.h b/trunk/server/mpm/experimental/leader/mpm_default.h new file mode 100644 index 0000000000..c35cf09da1 --- /dev/null +++ b/trunk/server/mpm/experimental/leader/mpm_default.h @@ -0,0 +1,69 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 3 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 3 +#endif + +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 25 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/experimental/perchild/Makefile.in b/trunk/server/mpm/experimental/perchild/Makefile.in new file mode 100644 index 0000000000..374f130646 --- /dev/null +++ b/trunk/server/mpm/experimental/perchild/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libperchild.la +LTLIBRARY_SOURCES = perchild.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/experimental/perchild/config5.m4 b/trunk/server/mpm/experimental/perchild/config5.m4 new file mode 100644 index 0000000000..368052f59f --- /dev/null +++ b/trunk/server/mpm/experimental/perchild/config5.m4 @@ -0,0 +1,6 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "perchild" ; then + AC_CHECK_FUNCS(pthread_kill) + APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi diff --git a/trunk/server/mpm/experimental/perchild/mpm.h b/trunk/server/mpm/experimental/perchild/mpm.h new file mode 100644 index 0000000000..87734a575f --- /dev/null +++ b/trunk/server/mpm/experimental/perchild/mpm.h @@ -0,0 +1,60 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "mpm_default.h" +#include "unixd.h" + +#ifndef APACHE_MPM_PERCHILD_H +#define APACHE_MPM_PERCHILD_H + +#define PERCHILD_MPM + +#define MPM_NAME "Perchild" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_USES_POD + +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +/* Table of child status */ +#define SERVER_DEAD 0 +#define SERVER_DYING 1 +#define SERVER_ALIVE 2 + +typedef struct ap_ctable{ + pid_t pid; + unsigned char status; +} ap_ctable; + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; + +#endif /* APACHE_MPM_PERCHILD_H */ diff --git a/trunk/server/mpm/experimental/perchild/mpm_default.h b/trunk/server/mpm/experimental/perchild/mpm_default.h new file mode 100644 index 0000000000..cc79f7f038 --- /dev/null +++ b/trunk/server/mpm/experimental/perchild/mpm_default.h @@ -0,0 +1,71 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of threads to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_THREAD +#define DEFAULT_START_THREAD 5 +#endif + +/* Maximum number of *free* server threads --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_SPARE_THREAD +#define DEFAULT_MAX_SPARE_THREAD 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_SPARE_THREAD +#define DEFAULT_MIN_SPARE_THREAD 5 +#endif + +/* Number of servers to spawn off by default + */ +#ifndef DEFAULT_NUM_DAEMON +#define DEFAULT_NUM_DAEMON 2 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/experimental/perchild/perchild.c b/trunk/server/mpm/experimental/perchild/perchild.c new file mode 100644 index 0000000000..bf38a7c5fc --- /dev/null +++ b/trunk/server/mpm/experimental/perchild/perchild.c @@ -0,0 +1,2051 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_hash.h" +#include "apr_strings.h" +#include "apr_pools.h" +#include "apr_portable.h" +#include "apr_file_io.h" +#include "apr_signal.h" + +#define APR_WANT_IOVEC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif + +#if !APR_HAS_THREADS +#error The perchild MPM requires APR threads, but they are unavailable. +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_protocol.h" +#include "http_connection.h" +#include "ap_mpm.h" +#include "unixd.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "mpm_default.h" +#include "mpm.h" +#include "scoreboard.h" +#include "util_filter.h" +#include "apr_poll.h" + +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_SYS_POLL_H +#include +#endif + +/* ### should be APR-ized */ +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +/* + * Define some magic numbers that we use for the state of the incomming + * request. These must be < 0 so they don't collide with a file descriptor. + */ +#define AP_PERCHILD_THISCHILD -1 +#define AP_PERCHILD_OTHERCHILD -2 + +/* Limit on the threads per process. Clients will be locked out if more than + * this * server_limit are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 64 +#endif + +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 20000 +#endif + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 8 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 20000 +#endif + +/* + * Actual definitions of config globals + */ + +static int threads_to_start = 0; /* Worker threads per child */ +static int min_spare_threads = 0; +static int max_spare_threads = 0; +static int max_threads = 0; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit; +static int changed_limit_at_restart; +static int num_daemons = 0; +static int curr_child_num = 0; +static int workers_may_exit = 0; +static int requests_this_child; +static int num_listensocks = 0; +static ap_pod_t *pod; +static jmp_buf *jmpbuffers; + +struct child_info_t { + uid_t uid; + gid_t gid; + int input; /* The socket descriptor */ + int output; /* The socket descriptor */ +}; + +typedef struct { + const char *sockname; /* The base name for the socket */ + const char *fullsockname; /* socket base name + extension */ + int input; /* The socket descriptor */ + int output; /* The socket descriptor */ +} perchild_server_conf; + +typedef struct child_info_t child_info_t; + +/* Tables used to determine the user and group each child process should + * run as. The hash table is used to correlate a server name with a child + * process. + */ +static child_info_t *child_info_table; +static int *thread_socket_table; +struct ap_ctable *ap_child_table; + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with NumServers changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire child + * table. + * + * XXX - It might not be worth keeping this code in. There aren't very + * many child processes in this MPM. + */ +int ap_max_daemons_limit = -1; +int ap_threads_per_child; /* XXX not part of API! axe it! */ + +module AP_MODULE_DECLARE_DATA mpm_perchild_module; + +static apr_file_t *pipe_of_death_in = NULL; +static apr_file_t *pipe_of_death_out = NULL; +static apr_thread_mutex_t *pipe_of_death_mutex; + +/* *Non*-shared http_main globals... */ + +server_rec *ap_server_conf; + +/* one_process --- debugging mode variable; can be set from the command line + * with the -X flag. If set, this gets you the child_main loop running + * in the process which originally started up (no detach, no make_child), + * which is a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ +static apr_pool_t *thread_pool_parent; /* Parent of per-thread pools */ +static apr_thread_mutex_t *thread_pool_parent_mutex; + +static int child_num; +static unsigned int my_pid; /* Linux getpid() doesn't work except in + main thread. Use this instead */ +/* Keep track of the number of worker threads currently active */ +static int worker_thread_count; +static apr_thread_mutex_t *worker_thread_count_mutex; +static int *worker_thread_free_ids; +static apr_threadattr_t *worker_thread_attr; + +/* Keep track of the number of idle worker threads */ +static int idle_thread_count; +static apr_thread_mutex_t *idle_thread_count_mutex; + +/* Locks for accept serialization */ +#ifdef NO_SERIALIZED_ACCEPT +#define SAFE_ACCEPT(stmt) APR_SUCCESS +#else +#define SAFE_ACCEPT(stmt) (stmt) +static apr_proc_mutex_t *process_accept_mutex; +#endif /* NO_SERIALIZED_ACCEPT */ +static apr_thread_mutex_t *thread_accept_mutex; + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = max_threads; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = num_daemons; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) +{ + if (pchild) { + apr_pool_destroy(pchild); + } + exit(code); +} + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static int volatile child_fatal; +/* we don't currently track ap_my_generation, but mod_status + * references it so it must be defined */ +ap_generation_t volatile ap_my_generation=0; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +static void sig_term(int sig) +{ + ap_start_shutdown(); +} + +static void restart(int sig) +{ +#ifndef WIN32 + ap_start_restart(sig == AP_SIG_GRACEFUL); +#else + ap_start_restart(1); +#endif +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, + "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) +{ + /* XXX - Does this really work? - Manoj */ + return is_graceful; +} + +/***************************************************************** + * Child process main loop. + */ + +static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id, + apr_bucket_alloc_t *bucket_alloc) +{ + conn_rec *current_conn; + int csd; + apr_status_t rv; + int thread_num = conn_id % thread_limit; + ap_sb_handle_t *sbh; + + if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get"); + } + + if (thread_socket_table[thread_num] < 0) { + ap_sock_disable_nagle(sock); + } + + ap_create_sb_handle(&sbh, p, conn_id / thread_limit, thread_num); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, + sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, sock); + ap_lingering_close(current_conn); + } +} + +static int perchild_process_connection(conn_rec *c) +{ + ap_filter_t *f; + apr_bucket_brigade *bb; + core_net_rec *net; + + apr_pool_userdata_get((void **)&bb, "PERCHILD_SOCKETS", c->pool); + if (bb != NULL) { + for (f = c->output_filters; f != NULL; f = f->next) { + if (!strcmp(f->frec->name, "core")) { + break; + } + } + if (f != NULL) { + net = f->ctx; + net->in_ctx = apr_palloc(c->pool, sizeof(*net->in_ctx)); + net->in_ctx->b = bb; + } + } + return DECLINED; +} + + +static void *worker_thread(apr_thread_t *, void *); + +/* Starts a thread as long as we're below max_threads */ +static int start_thread(void) +{ + apr_thread_t *thread; + int rc; + + apr_thread_mutex_lock(worker_thread_count_mutex); + if (worker_thread_count < max_threads - 1) { + rc = apr_thread_create(&thread, worker_thread_attr, worker_thread, + &worker_thread_free_ids[worker_thread_count], pchild); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rc, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again if we exit. */ + sleep(10); + workers_may_exit = 1; + apr_thread_mutex_unlock(worker_thread_count_mutex); + return 0; + } + else { + worker_thread_count++; + } + } + else { + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, + "server reached MaxThreadsPerChild setting, " + "consider raising the MaxThreadsPerChild or " + "NumServers settings"); + reported = 1; + } + apr_thread_mutex_unlock(worker_thread_count_mutex); + return 0; + } + apr_thread_mutex_unlock(worker_thread_count_mutex); + return 1; + +} + +/* Sets workers_may_exit if we received a character on the pipe_of_death */ +static apr_status_t check_pipe_of_death(void **csd, ap_listen_rec *lr, + apr_pool_t *ptrans) +{ + apr_thread_mutex_lock(pipe_of_death_mutex); + if (!workers_may_exit) { + int ret; + char pipe_read_char; + apr_size_t n = 1; + + ret = apr_socket_recv(lr->sd, &pipe_read_char, &n); + if (APR_STATUS_IS_EAGAIN(ret)) { + /* It lost the lottery. It must continue to suffer + * through a life of servitude. */ + } + else { + /* It won the lottery (or something else is very + * wrong). Embrace death with open arms. */ + workers_may_exit = 1; + } + } + apr_thread_mutex_unlock(pipe_of_death_mutex); + return APR_SUCCESS; +} + +static apr_status_t receive_from_other_child(void **csd, ap_listen_rec *lr, + apr_pool_t *ptrans) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + char buffer[HUGE_STRING_LEN * 2], *headers, *body; + int headerslen, bodylen; + struct iovec iov; + int ret, dp; + apr_os_sock_t sd; + apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(ptrans); + apr_bucket_brigade *bb = apr_brigade_create(ptrans, alloc); + apr_bucket *bucket; + + apr_os_sock_get(&sd, lr->sd); + + iov.iov_base = buffer; + iov.iov_len = sizeof(buffer); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + cmsg = apr_palloc(ptrans, sizeof(*cmsg) + sizeof(sd)); + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sd); + msg.msg_control = cmsg; + msg.msg_controllen = cmsg->cmsg_len; + + ret = recvmsg(sd, &msg, 0); + + memcpy(&dp, CMSG_DATA(cmsg), sizeof(dp)); + + *csd = NULL; /* tell apr_os_sock_put() to allocate new apr_socket_t */ + apr_os_sock_put((apr_socket_t **)csd, &dp, ptrans); + + bucket = apr_bucket_eos_create(alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); + bucket = apr_bucket_socket_create(*csd, alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); + + body = strchr(iov.iov_base, 0); + if (!body) { + return 1; + } + + body++; + bodylen = strlen(body); + + headers = iov.iov_base; + headerslen = body - headers; + + bucket = apr_bucket_heap_create(body, bodylen, NULL, alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); + bucket = apr_bucket_heap_create(headers, headerslen, NULL, alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); + + apr_pool_userdata_set(bb, "PERCHILD_SOCKETS", NULL, ptrans); + + return 0; +} + +/* idle_thread_count should be incremented before starting a worker_thread */ + +static void *worker_thread(apr_thread_t *thd, void *arg) +{ + void *csd; + apr_pool_t *tpool; /* Pool for this thread */ + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + volatile int thread_just_started = 1; + int srv; + int thread_num = *((int *) arg); + long conn_id = child_num * thread_limit + thread_num; + apr_pollfd_t *pollset; + apr_status_t rv; + ap_listen_rec *lr, *last_lr = ap_listeners; + int n; + apr_bucket_alloc_t *bucket_alloc; + + apr_thread_mutex_lock(thread_pool_parent_mutex); + apr_pool_create(&tpool, thread_pool_parent); + apr_thread_mutex_unlock(thread_pool_parent_mutex); + apr_pool_create(&ptrans, tpool); + + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_STARTING, + (request_rec *) NULL); + + bucket_alloc = apr_bucket_alloc_create(apr_thread_pool_get(thd)); + + apr_poll_setup(&pollset, num_listensocks, tpool); + for(lr = ap_listeners; lr != NULL; lr = lr->next) { + int fd; + apr_poll_socket_add(pollset, lr->sd, APR_POLLIN); + + apr_os_sock_get(&fd, lr->sd); + } + + while (!workers_may_exit) { + workers_may_exit |= ((ap_max_requests_per_child != 0) + && (requests_this_child <= 0)); + if (workers_may_exit) break; + if (!thread_just_started) { + apr_thread_mutex_lock(idle_thread_count_mutex); + if (idle_thread_count < max_spare_threads) { + idle_thread_count++; + apr_thread_mutex_unlock(idle_thread_count_mutex); + } + else { + apr_thread_mutex_unlock(idle_thread_count_mutex); + break; + } + } + else { + thread_just_started = 0; + } + + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_READY, + (request_rec *) NULL); + + apr_thread_mutex_lock(thread_accept_mutex); + if (workers_may_exit) { + apr_thread_mutex_unlock(thread_accept_mutex); + break; + } + if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(process_accept_mutex))) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_proc_mutex_lock failed. Attempting to shutdown " + "process gracefully."); + workers_may_exit = 1; + } + + while (!workers_may_exit) { + apr_int16_t event; + srv = apr_poll(pollset, num_listensocks, &n, -1); + + if (srv != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(srv)) { + continue; + } + + /* apr_poll() will only return errors in catastrophic + * circumstances. Let's try exiting gracefully, for now. */ + ap_log_error(APLOG_MARK, APLOG_ERR, srv, (const server_rec *) + ap_server_conf, "apr_poll: (listen)"); + workers_may_exit = 1; + } + if (workers_may_exit) break; + + /* find a listener */ + lr = last_lr; + do { + lr = lr->next; + if (lr == NULL) { + lr = ap_listeners; + } + /* XXX: Should we check for POLLERR? */ + apr_poll_revents_get(&event, lr->sd, pollset); + if (event & (APR_POLLIN)) { + last_lr = lr; + goto got_fd; + } + } while (lr != last_lr); + } + got_fd: + if (!workers_may_exit) { + rv = lr->accept_func(&csd, lr, ptrans); + if (rv == APR_EGENERAL) { + /* E[NM]FILE, ENOMEM, etc */ + workers_may_exit = 1; + } + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex))) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to shutdown " + "process gracefully."); + workers_may_exit = 1; + } + apr_thread_mutex_unlock(thread_accept_mutex); + apr_thread_mutex_lock(idle_thread_count_mutex); + if (idle_thread_count > min_spare_threads) { + idle_thread_count--; + } + else { + if (!start_thread()) { + idle_thread_count--; + } + } + apr_thread_mutex_unlock(idle_thread_count_mutex); + if (setjmp(jmpbuffers[thread_num]) != 1) { + process_socket(ptrans, csd, conn_id, bucket_alloc); + } + else { + thread_socket_table[thread_num] = AP_PERCHILD_THISCHILD; + } + requests_this_child--; + } + else { + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(process_accept_mutex))) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to shutdown " + "process gracefully."); + workers_may_exit = 1; + } + apr_thread_mutex_unlock(thread_accept_mutex); + apr_thread_mutex_lock(idle_thread_count_mutex); + idle_thread_count--; + apr_thread_mutex_unlock(idle_thread_count_mutex); + break; + } + apr_pool_clear(ptrans); + } + + apr_thread_mutex_lock(thread_pool_parent_mutex); + ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD, + (request_rec *) NULL); + apr_pool_destroy(tpool); + apr_thread_mutex_unlock(thread_pool_parent_mutex); + apr_thread_mutex_lock(worker_thread_count_mutex); + worker_thread_count--; + worker_thread_free_ids[worker_thread_count] = thread_num; + if (worker_thread_count == 0) { + /* All the threads have exited, now finish the shutdown process + * by signalling the sigwait thread */ + kill(my_pid, SIGTERM); + } + apr_thread_mutex_unlock(worker_thread_count_mutex); + + apr_bucket_alloc_destroy(bucket_alloc); + + return NULL; +} + + + +/* Set group privileges. + * + * Note that we use the username as set in the config files, rather than + * the lookup of to uid --- the same uid may have multiple passwd entries, + * with different sets of groups for each. + */ + +static int set_group_privs(uid_t uid, gid_t gid) +{ + if (!geteuid()) { + const char *name; + + /* Get username if passed as a uid */ + + struct passwd *ent; + + if ((ent = getpwuid(uid)) == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "getpwuid: couldn't determine user name from uid %u, " + "you probably need to modify the User directive", + (unsigned)uid); + return -1; + } + + name = ent->pw_name; + + /* + * Set the GID before initgroups(), since on some platforms + * setgid() is known to zap the group list. + */ + if (setgid(gid) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setgid: unable to set group id to Group %u", + (unsigned)gid); + return -1; + } + + /* Reset `groups' attributes. */ + + if (initgroups(name, gid) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "initgroups: unable to set groups for User %s " + "and Group %u", name, (unsigned)gid); + return -1; + } + } + return 0; +} + + +static int perchild_setup_child(int childnum) +{ + child_info_t *ug = &child_info_table[childnum]; + + if (ug->uid == -1 && ug->gid == -1) { + return unixd_setup_child(); + } + if (set_group_privs(ug->uid, ug->gid)) { + return -1; + } + /* Only try to switch if we're running as root */ + if (!geteuid() + && ( +#ifdef _OSD_POSIX + os_init_job_environment(server_conf, unixd_config.user_name, + one_process) != 0 || +#endif + setuid(ug->uid) == -1)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setuid: unable to change to uid: %ld", + (long) ug->uid); + return -1; + } + return 0; +} + +static int check_signal(int signum) +{ + switch (signum) { + case SIGTERM: + case SIGINT: + just_die(signum); + return 1; + } + return 0; +} + +typedef struct perchild_header { + char *headers; + apr_pool_t *p; +} perchild_header; + +/* Send a single HTTP header field to the client. Note that this function + * is used in calls to table_do(), so their interfaces are co-dependent. + * In other words, don't change this one without checking table_do in alloc.c. + * It returns true unless there was a write error of some kind. + */ +static int perchild_header_field(perchild_header *h, + const char *fieldname, const char *fieldval) +{ + apr_pstrcat(h->p, h->headers, fieldname, ": ", fieldval, CRLF, NULL); + return 1; +} + + +static void child_main(int child_num_arg) +{ + int i; + apr_status_t rv; + apr_socket_t *sock = NULL; + ap_listen_rec *lr; + + my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); + child_num = child_num_arg; + apr_pool_create(&pchild, pconf); + + for (lr = ap_listeners ; lr->next != NULL; lr = lr->next) { + continue; + } + + apr_os_sock_put(&sock, &child_info_table[child_num].input, pconf); + lr->next = apr_palloc(pconf, sizeof(*lr)); + lr->next->sd = sock; + lr->next->active = 1; + lr->next->accept_func = receive_from_other_child; + lr->next->next = NULL; + lr = lr->next; + num_listensocks++; + + /*stuff to do before we switch id's, so we have permissions.*/ + + rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&process_accept_mutex, + ap_lock_fname, pchild)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize cross-process lock in child"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (perchild_setup_child(child_num)) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + /*done with init critical section */ + + apr_setup_signal_thread(); + + requests_this_child = ap_max_requests_per_child; + + + /* Setup worker threads */ + + if (threads_to_start > max_threads) { + threads_to_start = max_threads; + } + idle_thread_count = threads_to_start; + worker_thread_count = 0; + worker_thread_free_ids = (int *)apr_pcalloc(pchild, thread_limit * sizeof(int)); + for (i = 0; i < max_threads; i++) { + worker_thread_free_ids[i] = i; + } + apr_pool_create(&thread_pool_parent, pchild); + apr_thread_mutex_create(&thread_pool_parent_mutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&idle_thread_count_mutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&worker_thread_count_mutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&pipe_of_death_mutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&thread_accept_mutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + + apr_threadattr_create(&worker_thread_attr, pchild); + apr_threadattr_detach_set(worker_thread_attr, 1); + if (ap_thread_stacksize != 0) { + apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize); + } + + /* We are creating worker threads right now */ + for (i=0; i < threads_to_start; i++) { + /* start_thread shouldn't fail here */ + if (!start_thread()) { + break; + } + } + + apr_signal_thread(check_signal); +} + +static int make_child(server_rec *s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + set_signals(); + ap_child_table[slot].pid = getpid(); + ap_child_table[slot].status = SERVER_ALIVE; + child_main(slot); + } + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, + (request_rec *) NULL); + + if ((pid = fork()) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, + "fork: Unable to fork new process"); + /* In case system resources are maxxed out, we don't want + * Apache running away with the CPU trying to fork over and + * over and over again. */ + sleep(10); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* By default, AIX binds to a single processor. This bit unbinds + * children which will then bind to another CPU. + */ + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, "processor unbind failed %d", status); + } +#endif + + RAISE_SIGSTOP(MAKE_CHILD); + + /* XXX - For an unthreaded server, a signal handler will be necessary + * apr_signal(SIGTERM, just_die); + */ + child_main(slot); + clean_child_exit(0); + } + /* else */ + ap_child_table[slot].pid = pid; + ap_child_table[slot].status = SERVER_ALIVE; + + return 0; +} + +/* start up a bunch of children */ +static int startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < num_daemons; ++i) { + if (ap_child_table[i].pid) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } + return number_to_start; +} + + +/* + * spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_child_maintenance(void) +{ + int i; + int free_length; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead = -1; + + /* initialize the free_list */ + free_length = 0; + + for (i = 0; i < num_daemons; ++i) { + if (ap_child_table[i].pid == 0) { + if (free_length < spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } + } + else { + last_non_dead = i; + } + + if (i >= ap_max_daemons_limit && free_length >= spawn_rate) { + break; + } + } + ap_max_daemons_limit = last_non_dead + 1; + + if (free_length > 0) { + for (i = 0; i < free_length; ++i) { + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (spawn_rate < MAX_SPAWN_RATE) { + spawn_rate *= 2; + } + } + else { + spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_children_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid != -1) { + if (ap_process_child_status(&pid, exitwhy, status) + == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + /* non-fatal death... note that it's gone in the child table and + * clean out the status table. */ + child_slot = -1; + for (i = 0; i < ap_max_daemons_limit; ++i) { + if (ap_child_table[i].pid == pid.pid) { + child_slot = i; + break; + } + } + if (child_slot >= 0) { + ap_child_table[child_slot].pid = 0; + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); + + + if (remaining_children_to_start + && child_slot < num_daemons) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, + status) == 0) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * child table. Somehow we don't know about this + * child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + ap_server_conf, + "long lost child came home! (pid %ld)", + (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + remaining_children_to_start = \ + startup_children(remaining_children_to_start); + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_child_maintenance(); + } +} + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int remaining_children_to_start; + int i; + apr_status_t rv; + apr_size_t one = 1; + ap_listen_rec *lr; + apr_socket_t *sock = NULL; + int fd; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + first_thread_limit = thread_limit; + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit or ThreadLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + ap_server_conf = s; + + if ((ap_accept_lock_mech == APR_LOCK_SYSVSEM) || + (ap_accept_lock_mech == APR_LOCK_POSIXSEM)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Server configured for an accept lock mechanism that " + "cannot be used with perchild. Falling back to FCNTL."); + ap_accept_lock_mech = APR_LOCK_FCNTL; + } + + /* Initialize cross-process accept lock */ + ap_lock_fname = apr_psprintf(_pconf, "%s.%u", + ap_server_root_relative(_pconf, ap_lock_fname), + my_pid); + rv = SAFE_ACCEPT(apr_proc_mutex_create(&process_accept_mutex, + ap_lock_fname, ap_accept_lock_mech, + _pconf)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create cross-process lock"); + return 1; + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + return 1; + } + } + /* Initialize the child table */ + if (!is_graceful) { + for (i = 0; i < server_limit; i++) { + ap_child_table[i].pid = 0; + } + } + + /* We need to put the new listeners at the end of the ap_listeners + * list. If we don't, then the pool will be cleared before the + * open_logs phase is called for the second time, and ap_listeners + * will have only invalid data. If that happens, then the sockets + * that we opened using make_sock() will be lost, and the server + * won't start. + */ + for (lr = ap_listeners ; lr->next != NULL; lr = lr->next) { + continue; + } + + apr_os_file_get(&fd, pipe_of_death_in); + apr_os_sock_put(&sock, &fd, pconf); + lr->next = apr_palloc(pconf, sizeof(*lr)); + lr->next->sd = sock; + lr->next->active = 1; + lr->next->accept_func = check_pipe_of_death; + lr->next->next = NULL; + lr = lr->next; + num_listensocks++; + + set_signals(); + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens + * pretty rapidly... and for each one that exits we'll start a new one + * until we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = num_daemons; + if (!is_graceful) { + remaining_children_to_start = \ + startup_children(remaining_children_to_start); + } + else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(process_accept_mutex), + apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + + server_main_loop(remaining_children_to_start); + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + */ + if (unixd_killpg(getpgrp(), SIGTERM) < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "killpg SIGTERM"); + } + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if (pidfile != NULL && unlink(pidfile) == 0) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long)getpid()); + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "caught SIGTERM, shutting down"); + } + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + + if (one_process) { + /* not worth thinking about */ + return 1; + } + + if (is_graceful) { + char char_of_death = '!'; + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, AP_SIG_GRACEFUL_STRING " received. " + "Doing graceful restart"); + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. + */ + + for (i = 0; i < num_daemons; ++i) { + if (ap_child_table[i].pid) { + ap_child_table[i].status = SERVER_DYING; + } + } + /* give the children the signal to die */ + for (i = 0; i < num_daemons;) { + if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, + &one)) != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rv)) continue; + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } + i++; + } + } + else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + if (unixd_killpg(getpgrp(), SIGTERM) < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "killpg SIGTERM"); + } + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "SIGHUP received. Attempting to restart"); + } + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int perchild_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + ap_log_pid(pconf, ap_pid_fname); + + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + + if ((rv = apr_file_pipe_create(&pipe_of_death_in, &pipe_of_death_out, + pconf)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + (const server_rec*) ap_server_conf, + "apr_file_pipe_create (pipe_of_death)"); + exit(1); + } + if ((rv = apr_file_pipe_timeout_set(pipe_of_death_in, 0)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + (const server_rec*) ap_server_conf, + "apr_file_pipe_timeout_set (pipe_of_death)"); + exit(1); + } + + return OK; +} + +static int perchild_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + ap_directive_t *pdir; + int i; + int tmp_server_limit = DEFAULT_SERVER_LIMIT; + int tmp_thread_limit = DEFAULT_THREAD_LIMIT; + apr_status_t rv; + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + num_daemons = DEFAULT_NUM_DAEMON; + threads_to_start = DEFAULT_START_THREAD; + min_spare_threads = DEFAULT_MIN_SPARE_THREAD; + max_spare_threads = DEFAULT_MAX_SPARE_THREAD; + max_threads = thread_limit; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + curr_child_num = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + /* we need to know ServerLimit and ThreadLimit before we start processing + * the tree because we need to already have allocated child_info_table + */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (!strcasecmp(pdir->directive, "ServerLimit")) { + if (atoi(pdir->args) > tmp_server_limit) { + tmp_server_limit = atoi(pdir->args); + if (tmp_server_limit > MAX_SERVER_LIMIT) { + tmp_server_limit = MAX_SERVER_LIMIT; + } + } + } + else if (!strcasecmp(pdir->directive, "ThreadLimit")) { + if (atoi(pdir->args) > tmp_thread_limit) { + tmp_thread_limit = atoi(pdir->args); + if (tmp_thread_limit > MAX_THREAD_LIMIT) { + tmp_thread_limit = MAX_THREAD_LIMIT; + } + } + } + } + + child_info_table = (child_info_t *)apr_pcalloc(p, tmp_server_limit * sizeof(child_info_t)); + for (i = 0; i < tmp_server_limit; i++) { + child_info_table[i].uid = -1; + child_info_table[i].gid = -1; + child_info_table[i].input = -1; + child_info_table[i].output = -1; + } + + return OK; +} + +static int pass_request(request_rec *r) +{ + int rv; + apr_socket_t *thesock = ap_get_module_config(r->connection->conn_config, &core_module); + struct msghdr msg; + struct cmsghdr *cmsg; + int sfd; + struct iovec iov[2]; + conn_rec *c = r->connection; + apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); + apr_bucket_brigade *sockbb; + char request_body[HUGE_STRING_LEN] = "\0"; + apr_size_t l = sizeof(request_body); + perchild_header h; + apr_bucket *sockbuck; + perchild_server_conf *sconf = (perchild_server_conf *) + ap_get_module_config(r->server->module_config, + &mpm_perchild_module); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "passing request to another child. Vhost: %s, child %d %d", + apr_table_get(r->headers_in, "Host"), child_num, sconf->output); + ap_get_brigade(r->connection->input_filters, bb, AP_MODE_EXHAUSTIVE, APR_NONBLOCK_READ, + 0); + + for (sockbuck = APR_BRIGADE_FIRST(bb); sockbuck != APR_BRIGADE_SENTINEL(bb); + sockbuck = APR_BUCKET_NEXT(sockbuck)) { + if (APR_BUCKET_IS_SOCKET(sockbuck)) { + break; + } + } + + if (!sockbuck) { + } + sockbb = apr_brigade_split(bb, sockbuck); + + if (apr_brigade_flatten(bb, request_body, &l) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Unable to flatten brigade, declining request"); + return DECLINED; + } + + apr_os_sock_get(&sfd, thesock); + + h.p = r->pool; + h.headers = apr_pstrcat(h.p, r->the_request, CRLF, "Host: ", r->hostname, + CRLF, NULL); + apr_table_do((int (*) (void *, const char *, const char *)) + perchild_header_field, (void *) &h, r->headers_in, NULL); + h.headers = apr_pstrcat(h.p, h.headers, CRLF, NULL); + + iov[0].iov_base = h.headers; + iov[0].iov_len = strlen(h.headers) + 1; + iov[1].iov_base = request_body; + iov[1].iov_len = l + 1; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 2; + + cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sfd)); + cmsg->cmsg_len = sizeof(*cmsg) + sizeof(sfd); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + + memcpy(CMSG_DATA(cmsg), &sfd, sizeof(sfd)); + + msg.msg_control = cmsg; + msg.msg_controllen = cmsg->cmsg_len; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Writing message to %d, passing sd: %d", sconf->output, sfd); + + if ((rv = sendmsg(sconf->output, &msg, 0)) == -1) { + apr_pool_destroy(r->pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Writing message failed %d %d", rv, errno); + return -1; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Writing message succeeded %d", rv); + + apr_pool_destroy(r->pool); + return 1; +} + +static char *make_perchild_socket(const char *fullsockname, int sd[2]) +{ + socketpair(PF_UNIX, SOCK_STREAM, 0, sd); + return NULL; +} + +static int perchild_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + int i; + server_rec *sr; + perchild_server_conf *sconf; + int def_sd[2]; + + def_sd[0] = -1; + def_sd[1] = -1; + + for (sr = s; sr; sr = sr->next) { + sconf = (perchild_server_conf *)ap_get_module_config(sr->module_config, + &mpm_perchild_module); + + if (sconf->input == -1) { + sconf->fullsockname = apr_pstrcat(sr->process->pool, + sconf->sockname, ".DEFAULT", NULL); + if (def_sd[0] == -1) { + if (!make_perchild_socket(sconf->fullsockname, def_sd)) { + /* log error */ + } + } + sconf->input = def_sd[0]; + sconf->output = def_sd[1]; + } + } + + for (i = 0; i < num_daemons; i++) { + if (child_info_table[i].uid == -1) { + child_info_table[i].input = def_sd[0]; + child_info_table[i].output = def_sd[1]; + } + } + + thread_socket_table = (int *)apr_pcalloc(p, thread_limit * sizeof(int)); + for (i = 0; i < thread_limit; i++) { + thread_socket_table[i] = AP_PERCHILD_THISCHILD; + } + ap_child_table = (ap_ctable *)apr_pcalloc(p, server_limit * sizeof(ap_ctable)); + + jmpbuffers = (jmp_buf *)apr_palloc(p, thread_limit * sizeof(jmp_buf)); + + return OK; +} + +static int perchild_post_read(request_rec *r) +{ + int thread_num = r->connection->id % thread_limit; + perchild_server_conf *sconf = (perchild_server_conf *) + ap_get_module_config(r->server->module_config, + &mpm_perchild_module); + + if (thread_socket_table[thread_num] != AP_PERCHILD_THISCHILD) { + apr_socket_t *csd = NULL; + + apr_os_sock_put(&csd, &thread_socket_table[thread_num], + r->connection->pool); + ap_sock_disable_nagle(csd); + ap_set_module_config(r->connection->conn_config, &core_module, csd); + return OK; + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Determining if request should be passed. " + "Child Num: %d, SD: %d, sd from table: %d, hostname from server: %s", child_num, + sconf->input, child_info_table[child_num].input, + r->server->server_hostname); + /* sconf is the server config for this vhost, so if our socket + * is not the same that was set in the config, then the request + * needs to be passed to another child. */ + if (sconf->input != child_info_table[child_num].input) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Passing request."); + if (pass_request(r) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, "Could not pass request to proper " + "child, request will not be honored."); + } + longjmp(jmpbuffers[thread_num], 1); + } + return OK; + } + return OK; +} + +static void perchild_hooks(apr_pool_t *p) +{ + /* The perchild open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + one_process = 0; + + ap_hook_open_logs(perchild_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + ap_hook_pre_config(perchild_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(perchild_post_config, NULL, NULL, APR_HOOK_MIDDLE); + + /* Both of these must be run absolutely first. If this request isn't for + * this server then we need to forward it to the proper child. No sense + * tying up this server running more post_read request hooks if it is + * just going to be forwarded along. The process_connection hook allows + * perchild to receive the passed request correctly, by automatically + * filling in the core_input_filter's ctx pointer. + */ + ap_hook_post_read_request(perchild_post_read, NULL, NULL, + APR_HOOK_REALLY_FIRST); + ap_hook_process_connection(perchild_process_connection, NULL, NULL, + APR_HOOK_REALLY_FIRST); +} + +static const char *set_num_daemons(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + num_daemons = atoi(arg); + if (num_daemons > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: NumServers of %d exceeds ServerLimit value " + "of %d servers,", num_daemons, server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering NumServers to %d. To increase, please " + "see the", server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ServerLimit directive."); + num_daemons = server_limit; + } + else if (num_daemons < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require NumServers > 0, setting to 1"); + num_daemons = 1; + } + return NULL; +} + +static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + threads_to_start = atoi(arg); + if (threads_to_start > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: StartThreads of %d exceeds ThreadLimit value" + " of %d threads,", threads_to_start, + thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering StartThreads to %d. To increase, please" + " see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + } + else if (threads_to_start < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require StartThreads > 0, setting to 1"); + threads_to_start = 1; + } + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + if (max_spare_threads >= thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set higher than"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "ThreadLimit. Resetting to %d", thread_limit); + max_spare_threads = thread_limit; + } + return NULL; +} + +static const char *set_max_threads(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_threads = atoi(arg); + if (max_threads > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MaxThreadsPerChild set higher than"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "ThreadLimit. Resetting to %d", thread_limit); + max_threads = thread_limit; + } + return NULL; +} + +static const char *set_child_per_uid(cmd_parms *cmd, void *dummy, const char *u, + const char *g, const char *num) +{ + int i; + int max_this_time = atoi(num) + curr_child_num; + + + for (i = curr_child_num; i < max_this_time; i++, curr_child_num++) { + if (i > num_daemons) { + return "Trying to use more child ID's than NumServers. Increase " + "NumServers in your config file."; + } + + child_info_table[i].uid = ap_uname2id(u); + child_info_table[i].gid = ap_gname2id(g); + +#ifndef BIG_SECURITY_HOLE + if (child_info_table[i].uid == 0 || child_info_table[i].gid == 0) { + return "Assigning root user/group to a child."; + } +#endif + } + return NULL; +} + +static const char *assign_childuid(cmd_parms *cmd, void *dummy, const char *uid, + const char *gid) +{ + int i; + int matching = 0; + int u = ap_uname2id(uid); + int g = ap_gname2id(gid); + const char *errstr; + int socks[2]; + perchild_server_conf *sconf = (perchild_server_conf *) + ap_get_module_config(cmd->server->module_config, + &mpm_perchild_module); + + sconf->fullsockname = apr_pstrcat(cmd->pool, sconf->sockname, ".", uid, + ":", gid, NULL); + + if ((errstr = make_perchild_socket(sconf->fullsockname, socks))) { + return errstr; + } + + sconf->input = socks[0]; + sconf->output = socks[1]; + + for (i = 0; i < num_daemons; i++) { + if (u == child_info_table[i].uid && g == child_info_table[i].gid) { + child_info_table[i].input = sconf->input; + child_info_table[i].output = sconf->output; + matching++; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, + "filling out child_info_table; UID: %d, GID: %d, " + "SD: %d %d, OUTPUT: %d %d, Child Num: %d", + child_info_table[i].uid, child_info_table[i].gid, + sconf->input, child_info_table[i].input, sconf->output, + child_info_table[i].output, i); + } + } + + if (!matching) { + return "Unable to find process with matching uid/gid."; + } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && + tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d servers,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} + +static const command_rec perchild_cmds[] = { +UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("NumServers", set_num_daemons, NULL, RSRC_CONF, + "Number of children alive at the same time"), +AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF, + "Number of threads each child creates"), +AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle threads per child, to handle " + "request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle threads per child"), +AP_INIT_TAKE1("MaxThreadsPerChild", set_max_threads, NULL, RSRC_CONF, + "Maximum number of threads per child"), +AP_INIT_TAKE3("ChildperUserID", set_child_per_uid, NULL, RSRC_CONF, + "Specify a User and Group for a specific child process."), +AP_INIT_TAKE2("AssignUserID", assign_childuid, NULL, RSRC_CONF, + "Tie a virtual host to a specific child process."), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum value of NumServers for this run of Apache"), +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum worker threads in a server for this run of Apache"), +{ NULL } +}; + +static void *perchild_create_config(apr_pool_t *p, server_rec *s) +{ + perchild_server_conf *c = (perchild_server_conf *) + apr_pcalloc(p, sizeof(perchild_server_conf)); + + c->input = -1; + c->output = -1; + return c; +} + +module AP_MODULE_DECLARE_DATA mpm_perchild_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + perchild_create_config, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + perchild_cmds, /* command apr_table_t */ + perchild_hooks /* register_hooks */ +}; + diff --git a/trunk/server/mpm/experimental/threadpool/Makefile.in b/trunk/server/mpm/experimental/threadpool/Makefile.in new file mode 100644 index 0000000000..ea0acb693b --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libthreadpool.la +LTLIBRARY_SOURCES = threadpool.c pod.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/experimental/threadpool/README b/trunk/server/mpm/experimental/threadpool/README new file mode 100644 index 0000000000..86e8524cb6 --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/README @@ -0,0 +1,12 @@ +Threadpool MPM: +This is an experimental variant of the standard worker MPM. +Rather than queuing connections like the worker MPM, the threadpool +MPM queues idle worker threads and hands each accepted connection +to the next available worker. + +The threadpool MPM can't match the performance of the worker MPM +in benchmark testing. As of 2.0.39, some of the key load-throtting +concepts from the threadpool MPM have been incorporated into the +worker MPM. The threadpool code is useful primarily as a research +platform; for general-purpose use, and for any production environments, +use worker instead. diff --git a/trunk/server/mpm/experimental/threadpool/config5.m4 b/trunk/server/mpm/experimental/threadpool/config5.m4 new file mode 100644 index 0000000000..667b534a6d --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/config5.m4 @@ -0,0 +1,6 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "threadpool" ; then + AC_CHECK_FUNCS(pthread_kill) + APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi diff --git a/trunk/server/mpm/experimental/threadpool/mpm.h b/trunk/server/mpm/experimental/threadpool/mpm.h new file mode 100644 index 0000000000..d7853f29be --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/mpm.h @@ -0,0 +1,51 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoreboard.h" +#include "unixd.h" + +#ifndef APACHE_MPM_THREADPOOL_H +#define APACHE_MPM_THREADPOOL_H + +#define THREADPOOL_MPM + +#define MPM_NAME "ThreadPool" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; +extern char ap_coredump_dir[MAX_STRING_LEN]; + +#endif /* APACHE_MPM_THREADPOOL_H */ diff --git a/trunk/server/mpm/experimental/threadpool/mpm_default.h b/trunk/server/mpm/experimental/threadpool/mpm_default.h new file mode 100644 index 0000000000..c35cf09da1 --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/mpm_default.h @@ -0,0 +1,69 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 3 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 3 +#endif + +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 25 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/experimental/threadpool/pod.c b/trunk/server/mpm/experimental/threadpool/pod.c new file mode 100644 index 0000000000..0da8bba157 --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/pod.c @@ -0,0 +1,108 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pod.h" + +#if APR_HAVE_UNISTD_H +#include +#endif + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) +{ + apr_status_t rv; + + *pod = apr_palloc(p, sizeof(**pod)); + rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); + if (rv != APR_SUCCESS) { + return rv; + } +/* + apr_file_pipe_timeout_set((*pod)->pod_in, 0); +*/ + (*pod)->p = p; + + return APR_SUCCESS; +} + +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod) +{ + char c; + apr_os_file_t fd; + int rc; + + /* we need to surface EINTR so we'll have to grab the + * native file descriptor and do the OS read() ourselves + */ + apr_os_file_get(&fd, pod->pod_in); + rc = read(fd, &c, 1); + if (rc == 1) { + switch(c) { + case RESTART_CHAR: + return AP_RESTART; + case GRACEFUL_CHAR: + return AP_GRACEFUL; + } + } + return AP_NORESTART; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) +{ + apr_status_t rv; + + rv = apr_file_close(pod->pod_out); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_file_close(pod->pod_in); + if (rv != APR_SUCCESS) { + return rv; + } + return rv; +} + +static apr_status_t pod_signal_internal(ap_pod_t *pod, int graceful) +{ + apr_status_t rv; + char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; + apr_size_t one = 1; + + do { + rv = apr_file_write(pod->pod_out, &char_of_death, &one); + } while (APR_STATUS_IS_EINTR(rv)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } + return rv; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful) +{ + return pod_signal_internal(pod, graceful); +} + +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful) +{ + int i; + apr_status_t rv = APR_SUCCESS; + + for (i = 0; i < num && rv == APR_SUCCESS; i++) { + rv = pod_signal_internal(pod, graceful); + } +} + diff --git a/trunk/server/mpm/experimental/threadpool/pod.h b/trunk/server/mpm/experimental/threadpool/pod.h new file mode 100644 index 0000000000..04a2359e59 --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/pod.h @@ -0,0 +1,50 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_main.h" +#include "mpm.h" +#include "mpm_common.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "mpm_default.h" + +#define RESTART_CHAR '$' +#define GRACEFUL_CHAR '!' + +#define AP_RESTART 0 +#define AP_GRACEFUL 1 + +typedef struct ap_pod_t ap_pod_t; + +struct ap_pod_t { + apr_file_t *pod_in; + apr_file_t *pod_out; + apr_pool_t *p; +}; + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod); +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful); +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful); diff --git a/trunk/server/mpm/experimental/threadpool/threadpool.c b/trunk/server/mpm/experimental/threadpool/threadpool.c new file mode 100644 index 0000000000..1b6031dc7e --- /dev/null +++ b/trunk/server/mpm/experimental/threadpool/threadpool.c @@ -0,0 +1,2252 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The purpose of this MPM is to fix the design flaws in the threaded + * model. Because of the way that pthreads and mutex locks interact, + * it is basically impossible to cleanly gracefully shutdown a child + * process if multiple threads are all blocked in accept. This model + * fixes those problems. + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_poll.h" +#include "apr_thread_mutex.h" +#include "apr_thread_cond.h" +#include "apr_proc_mutex.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#if APR_HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +#if !APR_HAS_THREADS +#error The Worker MPM requires APR threads, but they are unavailable. +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "ap_mpm.h" +#include "pod.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "scoreboard.h" +#include "mpm_default.h" + +#include +#include /* for INT_MAX */ + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 16 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 20000 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * server_limit are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 64 +#endif + +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 20000 +#endif + +/* + * Actual definitions of config globals + */ + +int ap_threads_per_child = 0; /* Worker threads per child */ +static int ap_daemons_to_start = 0; +static int min_spare_threads = 0; +static int max_spare_threads = 0; +static int ap_daemons_limit = 0; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit; +static int changed_limit_at_restart; +static int dying = 0; +static int workers_may_exit = 0; +static int start_thread_may_exit = 0; +static int listener_may_exit = 0; +static int requests_this_child; +static int num_listensocks = 0; +static int resource_shortage = 0; +static int mpm_state = AP_MPMQ_STARTING; + +/* The structure used to pass unique initialization info to each thread */ +typedef struct { + int pid; + int tid; + int sd; +} proc_info; + +/* Structure used to pass information to the thread responsible for + * creating the rest of the threads. + */ +typedef struct { + apr_thread_t **threads; + apr_thread_t *listener; + int child_num_arg; + apr_threadattr_t *threadattr; +} thread_starter; + +#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire + * scoreboard. + */ +int ap_max_daemons_limit = -1; + +static ap_pod_t *pod; + +/* *Non*-shared http_main globals... */ + +server_rec *ap_server_conf; + +/* The worker MPM respects a couple of runtime flags that can aid + * in debugging. Setting the -DNO_DETACH flag will prevent the root process + * from detaching from its controlling terminal. Additionally, setting + * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the + * child_main loop running in the process which originally started up. + * This gives you a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main + thread. Use this instead */ +static pid_t parent_pid; +static apr_os_thread_t *listener_os_thread; + +/* Locks for accept serialization */ +static apr_proc_mutex_t *accept_mutex; + +#if APR_O_NONBLOCK_INHERITED +#undef SINGLE_LISTEN_UNSERIALIZED_ACCEPT +#endif /* APR_O_NONBLOCK_INHERITED */ + +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT +#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) +#else +#define SAFE_ACCEPT(stmt) (stmt) +#endif + +/* The LISTENER_SIGNAL signal will be sent from the main thread to the + * listener thread to wake it up for graceful termination (what a child + * process from an old generation does when the admin does "apachectl + * graceful"). This signal will be blocked in all threads of a child + * process except for the listener thread. + */ +#define LISTENER_SIGNAL SIGHUP + + +/* Possible states of a worker thread. */ +typedef enum { + WORKER_IDLE, + WORKER_BUSY, + WORKER_TERMINATED +} worker_state_e; + +/* Structure used to wake up an idle worker thread + */ +typedef struct { + apr_pool_t *pool; + apr_socket_t *csd; + worker_state_e state; + apr_thread_cond_t *cond; + apr_thread_mutex_t *mutex; +} worker_wakeup_info; + +/* Structure used to hold a stack of idle worker threads + */ +typedef struct { + apr_thread_mutex_t *mutex; + apr_thread_cond_t *cond; + worker_wakeup_info **stack; + apr_size_t nelts; + apr_size_t nalloc; + int terminated; +} worker_stack; + +static worker_stack* worker_stack_create(apr_pool_t *pool, apr_size_t max) +{ + apr_status_t rv; + worker_stack *stack = (worker_stack *)apr_palloc(pool, sizeof(*stack)); + + if ((rv = apr_thread_mutex_create(&stack->mutex, APR_THREAD_MUTEX_DEFAULT, + pool)) != APR_SUCCESS) { + return NULL; + } + if ((rv = apr_thread_cond_create(&stack->cond, pool)) != APR_SUCCESS) { + return NULL; + } + stack->nelts = 0; + stack->nalloc = max; + stack->stack = + (worker_wakeup_info **)apr_palloc(pool, stack->nalloc * + sizeof(worker_wakeup_info *)); + stack->terminated = 0; + return stack; +} + +static apr_status_t worker_stack_wait(worker_stack *stack, + worker_wakeup_info *wakeup) +{ + apr_status_t rv; + + wakeup->state = WORKER_IDLE; + + if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + if (stack->terminated) { + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_EOF; + } + if (stack->nelts == stack->nalloc) { + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_ENOSPC; + } + stack->stack[stack->nelts] = wakeup; + /* Signal a blocking listener thread only if we just made the + * stack non-empty. */ + if (stack->nelts++ == 0) { + (void)apr_thread_cond_signal(stack->cond); + } + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + + /* At this point we've already added this worker to the stack, now + * we just wait until the listener has accept()ed a connection + * for us. */ + if ((rv = apr_thread_mutex_lock(wakeup->mutex)) != APR_SUCCESS) { + return rv; + } + while (wakeup->state == WORKER_IDLE) { + if ((rv = apr_thread_cond_wait(wakeup->cond, wakeup->mutex)) != + APR_SUCCESS) { + return rv; + } + } + if ((rv = apr_thread_mutex_unlock(wakeup->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; +} + +static apr_status_t worker_stack_pop(worker_stack *stack, + worker_wakeup_info **worker) +{ + apr_status_t rv; + if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + AP_DEBUG_ASSERT(stack->nelts >= 0); + while ((stack->nelts == 0) && (!stack->terminated)) { + rv = apr_thread_cond_wait(stack->cond, stack->mutex); + if (rv != APR_SUCCESS) { + apr_status_t rv2; + rv2 = apr_thread_mutex_unlock(stack->mutex); + if (rv2 != APR_SUCCESS) { + return rv2; + } + return rv; + } + } + if (stack->terminated) { + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_EOF; + } + *worker = stack->stack[--stack->nelts]; + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; +} + +static apr_status_t worker_stack_terminate(worker_stack *stack) +{ + apr_status_t rv; + worker_wakeup_info *worker; + + if ((rv = apr_thread_mutex_lock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + stack->terminated = 1; + /* Wake up the listener thread. Although there will never be + * more than one thread blocking on this condition, broadcast + * just in case. */ + apr_thread_cond_broadcast(stack->cond); + while (stack->nelts) { + worker = stack->stack[--stack->nelts]; + apr_thread_mutex_lock(worker->mutex); + worker->csd = 0; + worker->state = WORKER_TERMINATED; + apr_thread_cond_signal(worker->cond); + apr_thread_mutex_unlock(worker->mutex); + } + if ((rv = apr_thread_mutex_unlock(stack->mutex)) != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; +} + +static worker_stack *idle_worker_stack; + +static void wakeup_listener(void) +{ + apr_status_t rv; + + listener_may_exit = 1; + if (!idle_worker_stack) { + return; + } + if ((rv = apr_thread_mutex_lock(idle_worker_stack->mutex)) != APR_SUCCESS) { + return; + } + if ((rv = apr_thread_cond_signal(idle_worker_stack->cond)) != + APR_SUCCESS) { + return; + } + if ((rv = apr_thread_mutex_unlock(idle_worker_stack->mutex)) != APR_SUCCESS) { + return; + } + if (!listener_os_thread) { + /* XXX there is an obscure path that this doesn't handle perfectly: + * right after listener thread is created but before + * listener_os_thread is set, the first worker thread hits an + * error and starts graceful termination + */ + return; + } + /* + * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all + * platforms and wake up the listener thread since it is the only thread + * with SIGHUP unblocked, but that doesn't work on Linux + */ +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, LISTENER_SIGNAL); +#else + kill(ap_my_pid, LISTENER_SIGNAL); +#endif +} + +#define ST_INIT 0 +#define ST_GRACEFUL 1 +#define ST_UNGRACEFUL 2 + +static int terminate_mode = ST_INIT; + +static void signal_threads(int mode) +{ + if (terminate_mode == mode) { + return; + } + terminate_mode = mode; + mpm_state = AP_MPMQ_STOPPING; + + /* in case we weren't called from the listener thread, wake up the + * listener thread + */ + wakeup_listener(); + + /* for ungraceful termination, let the workers exit now; + * for graceful termination, the listener thread will notify the + * workers to exit once it has stopped accepting new connections + */ + if (mode == ST_UNGRACEFUL) { + workers_may_exit = 1; + worker_stack_terminate(idle_worker_stack); + } +} + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_per_child; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = ap_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + mpm_state = AP_MPMQ_STOPPING; + if (pchild) { + apr_pool_destroy(pchild); + } + exit(code); +} + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static volatile int child_fatal; +ap_generation_t volatile ap_my_generation; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + mpm_state = AP_MPMQ_STOPPING; + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + mpm_state = AP_MPMQ_STOPPING; + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +static void sig_term(int sig) +{ + ap_start_shutdown(); +} + +static void restart(int sig) +{ + ap_start_restart(sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, + "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) + /* XXX this is really a bad confusing obsolete name + * maybe it should be ap_mpm_process_exiting? + */ +{ + /* note: for a graceful termination, listener_may_exit will be set before + * workers_may_exit, so check listener_may_exit + */ + return listener_may_exit; +} + +/***************************************************************** + * Child process main loop. + */ + +static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, + int my_thread_num, apr_bucket_alloc_t *bucket_alloc) +{ + conn_rec *current_conn; + long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); + int csd; + ap_sb_handle_t *sbh; + + ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); + apr_os_sock_get(&csd, sock); + + current_conn = ap_run_create_connection(p, ap_server_conf, sock, + conn_id, sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, sock); + ap_lingering_close(current_conn); + } +} + +/* requests_this_child has gone to zero or below. See if the admin coded + "MaxRequestsPerChild 0", and keep going in that case. Doing it this way + simplifies the hot path in worker_thread */ +static void check_infinite_requests(void) +{ + if (ap_max_requests_per_child) { + signal_threads(ST_GRACEFUL); + } + else { + /* wow! if you're executing this code, you may have set a record. + * either this child process has served over 2 billion requests, or + * you're running a threaded 2.0 on a 16 bit machine. + * + * I'll buy pizza and beers at Apachecon for the first person to do + * the former without cheating (dorking with INT_MAX, or running with + * uncommitted performance patches, for example). + * + * for the latter case, you probably deserve a beer too. Greg Ames + */ + + requests_this_child = INT_MAX; /* keep going */ + } +} + +static void unblock_signal(int sig) +{ + sigset_t sig_mask; + + sigemptyset(&sig_mask); + sigaddset(&sig_mask, sig); +#if defined(SIGPROCMASK_SETS_THREAD_MASK) + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); +#else + pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); +#endif +} + +static void dummy_signal_handler(int sig) +{ + /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall, + * then we don't need this goofy function. + */ +} + +static void *listener_thread(apr_thread_t *thd, void * dummy) +{ + proc_info * ti = dummy; + int process_slot = ti->pid; + apr_pool_t *tpool = apr_thread_pool_get(thd); + void *csd = NULL; + apr_pool_t *ptrans = NULL; /* Pool for per-transaction stuff */ + apr_pollset_t *pollset; + apr_status_t rv; + ap_listen_rec *lr; + worker_wakeup_info *worker = NULL; + int last_poll_idx = 0; + + free(ti); + + /* ### check the status */ + (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0); + + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + /* ### check the status */ + (void) apr_pollset_add(pollset, &pfd); + } + + /* Unblock the signal used to wake this thread up, and set a handler for + * it. + */ + unblock_signal(LISTENER_SIGNAL); + apr_signal(LISTENER_SIGNAL, dummy_signal_handler); + + /* TODO: Switch to a system where threads reuse the results from earlier + poll calls - manoj */ + while (1) { + /* TODO: requests_this_child should be synchronized - aaron */ + if (requests_this_child <= 0) { + check_infinite_requests(); + } + if (listener_may_exit) break; + + if (worker == NULL) { + rv = worker_stack_pop(idle_worker_stack, &worker); + if (APR_STATUS_IS_EOF(rv)) { + break; + } + else if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "worker_stack_pop failed"); + break; + } + ptrans = worker->pool; + } + AP_DEBUG_ASSERT(worker->state == WORKER_IDLE); + + if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (listener_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_lock failed. Attempting to shutdown " + "process gracefully."); + signal_threads(ST_GRACEFUL); + break; /* skip the lock release */ + } + + if (!APR_O_NONBLOCK_INHERITED && !ap_listeners->next) { + /* Only one listener, so skip the poll */ + lr = ap_listeners; + } + else { + while (!listener_may_exit) { + apr_status_t ret; + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + + ret = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (ret != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(ret)) { + continue; + } + + /* apr_pollset_poll() will only return errors in catastrophic + * circumstances. Let's try exiting gracefully, for now. */ + ap_log_error(APLOG_MARK, APLOG_ERR, ret, (const server_rec *) + ap_server_conf, "apr_pollset_poll: (listen)"); + signal_threads(ST_GRACEFUL); + } + + if (listener_may_exit) break; + + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + lr = pdesc[last_poll_idx++].client_data; + break; + } + } + if (!listener_may_exit) { + rv = lr->accept_func(&csd, lr, ptrans); + /* later we trash rv and rely on csd to indicate success/failure */ + AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); + + if (rv == APR_EGENERAL) { + /* E[NM]FILE, ENOMEM, etc */ + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + } + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (listener_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + if (csd != NULL) { + /* Wake up the sleeping worker. */ + apr_thread_mutex_lock(worker->mutex); + worker->csd = (apr_socket_t *)csd; + worker->state = WORKER_BUSY; + /* Posix allows us to signal this condition without + * owning the associated mutex, but in that case it can + * not guarantee predictable scheduling. See + * _UNIX Network Programming: Interprocess Communication_ + * by W. Richard Stevens, Vol 2, 2nd Ed, pp. 170-171. */ + apr_thread_cond_signal(worker->cond); + apr_thread_mutex_unlock(worker->mutex); + worker = NULL; + } + } + else { + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + break; + } + } + + workers_may_exit = 1; + if (worker) { + apr_thread_mutex_lock(worker->mutex); + worker->state = WORKER_TERMINATED; + /* Posix allows us to signal this condition without + * owning the associated mutex, but in that case it can + * not guarantee predictable scheduling. See + * _UNIX Network Programming: Interprocess Communication_ + * by W. Richard Stevens, Vol 2, 2nd Ed, pp. 170-171. */ + apr_thread_cond_signal(worker->cond); + apr_thread_mutex_unlock(worker->mutex); + } + worker_stack_terminate(idle_worker_stack); + dying = 1; + ap_scoreboard_image->parent[process_slot].quiescing = 1; + + /* wake up the main thread */ + kill(ap_my_pid, SIGTERM); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +/* XXX For ungraceful termination/restart, we definitely don't want to + * wait for active connections to finish but we may want to wait + * for idle workers to get out of the queue code and release mutexes, + * since those mutexes are cleaned up pretty soon and some systems + * may not react favorably (i.e., segfault) if operations are attempted + * on cleaned-up mutexes. + */ +static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) +{ + proc_info * ti = dummy; + int process_slot = ti->pid; + int thread_slot = ti->tid; + apr_bucket_alloc_t *bucket_alloc; + apr_pool_t *tpool = apr_thread_pool_get(thd); + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_allocator_t *allocator; + apr_status_t rv; + worker_wakeup_info *wakeup; + + free(ti); + + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + /* XXX: why is ptrans's parent not tpool? --jcw 08/2003 */ + apr_pool_create_ex(&ptrans, NULL, NULL, allocator); + apr_allocator_owner_set(allocator, ptrans); + bucket_alloc = apr_bucket_alloc_create_ex(allocator); + + wakeup = (worker_wakeup_info *)apr_palloc(tpool, sizeof(*wakeup)); + wakeup->pool = ptrans; + if ((rv = apr_thread_cond_create(&wakeup->cond, tpool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_thread_cond_create failed. Attempting to shutdown " + "process gracefully."); + signal_threads(ST_GRACEFUL); + apr_thread_exit(thd, rv); + } + if ((rv = apr_thread_mutex_create(&wakeup->mutex, APR_THREAD_MUTEX_DEFAULT, + tpool)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_thread_mutex_create failed. Attempting to shutdown " + "process gracefully."); + signal_threads(ST_GRACEFUL); + apr_thread_exit(thd, rv); + } + + while (!workers_may_exit) { + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); + rv = worker_stack_wait(idle_worker_stack, wakeup); + if (APR_STATUS_IS_EOF(rv)) { + break; /* The queue has been terminated. */ + } + else if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "worker_stack_wait failed"); + break; /* Treat all other errors as fatal. */ + } + else if (wakeup->state == WORKER_TERMINATED) { + break; /* They told us to quit. */ + } + AP_DEBUG_ASSERT(wakeup->state != WORKER_IDLE); + process_socket(ptrans, wakeup->csd, + process_slot, thread_slot, bucket_alloc); + requests_this_child--; /* FIXME: should be synchronized - aaron */ + apr_pool_clear(ptrans); + } + + ap_update_child_status_from_indexes(process_slot, thread_slot, + (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); + + apr_bucket_alloc_destroy(bucket_alloc); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static int check_signal(int signum) +{ + switch (signum) { + case SIGTERM: + case SIGINT: + return 1; + } + return 0; +} + +static void create_listener_thread(thread_starter *ts) +{ + int my_child_num = ts->child_num_arg; + apr_threadattr_t *thread_attr = ts->threadattr; + proc_info *my_info; + apr_status_t rv; + + my_info = (proc_info *)malloc(sizeof(proc_info)); + my_info->pid = my_child_num; + my_info->tid = -1; /* listener thread doesn't have a thread slot */ + my_info->sd = 0; + rv = apr_thread_create(&ts->listener, thread_attr, listener_thread, + my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create listener thread"); + /* In case system resources are maxxed out, we don't want + * Apache running away with the CPU trying to fork over and + * over and over again if we exit. + * XXX Jeff doesn't see how Apache is going to try to fork again since + * the exit code is APEXIT_CHILDFATAL + */ + apr_sleep(10 * APR_USEC_PER_SEC); + clean_child_exit(APEXIT_CHILDFATAL); + } + apr_os_thread_get(&listener_os_thread, ts->listener); +} + +/* XXX under some circumstances not understood, children can get stuck + * in start_threads forever trying to take over slots which will + * never be cleaned up; for now there is an APLOG_DEBUG message issued + * every so often when this condition occurs + */ +static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) +{ + thread_starter *ts = dummy; + apr_thread_t **threads = ts->threads; + apr_threadattr_t *thread_attr = ts->threadattr; + int child_num_arg = ts->child_num_arg; + int my_child_num = child_num_arg; + proc_info *my_info; + apr_status_t rv; + int i; + int threads_created = 0; + int loops; + int prev_threads_created; + + idle_worker_stack = worker_stack_create(pchild, ap_threads_per_child); + if (idle_worker_stack == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, + "worker_stack_create() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + loops = prev_threads_created = 0; + while (1) { + /* ap_threads_per_child does not include the listener thread */ + for (i = 0; i < ap_threads_per_child; i++) { + int status = ap_scoreboard_image->servers[child_num_arg][i].status; + + if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { + continue; + } + + my_info = (proc_info *)malloc(sizeof(proc_info)); + if (my_info == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + my_info->pid = my_child_num; + my_info->tid = i; + my_info->sd = 0; + + /* We are creating threads right now */ + ap_update_child_status_from_indexes(my_child_num, i, + SERVER_STARTING, NULL); + /* We let each thread update its own scoreboard entry. This is + * done because it lets us deal with tid better. + */ + rv = apr_thread_create(&threads[i], thread_attr, + worker_thread, my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again if we exit. */ + apr_sleep(10 * APR_USEC_PER_SEC); + clean_child_exit(APEXIT_CHILDFATAL); + } + threads_created++; + if (threads_created == 1) { + /* now that we have a worker thread, it makes sense to create + * a listener thread (we don't want a listener without a worker!) + */ + create_listener_thread(ts); + } + } + if (start_thread_may_exit || threads_created == ap_threads_per_child) { + break; + } + /* wait for previous generation to clean up an entry */ + apr_sleep(1 * APR_USEC_PER_SEC); + ++loops; + if (loops % 120 == 0) { /* every couple of minutes */ + if (prev_threads_created == threads_created) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "child %" APR_PID_T_FMT " isn't taking over " + "slots very quickly (%d of %d)", + ap_my_pid, threads_created, ap_threads_per_child); + } + prev_threads_created = threads_created; + } + } + + /* What state should this child_main process be listed as in the + * scoreboard...? + * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, + * (request_rec *) NULL); + * + * This state should be listed separately in the scoreboard, in some kind + * of process_status, not mixed in with the worker threads' status. + * "life_status" is almost right, but it's in the worker's structure, and + * the name could be clearer. gla + */ + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static void join_workers(apr_thread_t *listener, apr_thread_t **threads) +{ + int i; + apr_status_t rv, thread_rv; + + if (listener) { + int iter; + + /* deal with a rare timing window which affects waking up the + * listener thread... if the signal sent to the listener thread + * is delivered between the time it verifies that the + * listener_may_exit flag is clear and the time it enters a + * blocking syscall, the signal didn't do any good... work around + * that by sleeping briefly and sending it again + */ + + iter = 0; + while (iter < 10 && +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, 0) +#else + kill(ap_my_pid, 0) +#endif + == 0) { + /* listener not dead yet */ + apr_sleep(APR_USEC_PER_SEC / 2); + wakeup_listener(); + ++iter; + } + if (iter >= 10) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "the listener thread didn't exit"); + } + else { + rv = apr_thread_join(&thread_rv, listener); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join listener thread"); + } + } + } + + for (i = 0; i < ap_threads_per_child; i++) { + if (threads[i]) { /* if we ever created this thread */ + rv = apr_thread_join(&thread_rv, threads[i]); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join worker " + "thread %d", + i); + } + } + } +} + +static void join_start_thread(apr_thread_t *start_thread_id) +{ + apr_status_t rv, thread_rv; + + start_thread_may_exit = 1; /* tell it to give up in case it is still + * trying to take over slots from a + * previous generation + */ + rv = apr_thread_join(&thread_rv, start_thread_id); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join the start " + "thread"); + } +} + +static void child_main(int child_num_arg) +{ + apr_thread_t **threads; + apr_status_t rv; + thread_starter *ts; + apr_threadattr_t *thread_attr; + apr_thread_t *start_thread_id; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); + apr_pool_create(&pchild, pconf); + + /*stuff to do before we switch id's, so we have permissions.*/ + ap_reopen_scoreboard(pchild, NULL, 0); + + rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, + pchild)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize cross-process lock in child"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (unixd_setup_child()) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + /* done with init critical section */ + + /* Just use the standard apr_setup_signal_thread to block all signals + * from being received. The child processes no longer use signals for + * any communication with the parent process. + */ + rv = apr_setup_signal_thread(); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize signal thread"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (ap_max_requests_per_child) { + requests_this_child = ap_max_requests_per_child; + } + else { + /* coding a value of zero means infinity */ + requests_this_child = INT_MAX; + } + + /* Setup worker threads */ + + /* clear the storage; we may not create all our threads immediately, + * and we want a 0 entry to indicate a thread which was not created + */ + threads = (apr_thread_t **)calloc(1, + sizeof(apr_thread_t *) * ap_threads_per_child); + if (threads == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); + + apr_threadattr_create(&thread_attr, pchild); + /* 0 means PTHREAD_CREATE_JOINABLE */ + apr_threadattr_detach_set(thread_attr, 0); + if (ap_thread_stacksize != 0) { + apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize); + } + + ts->threads = threads; + ts->listener = NULL; + ts->child_num_arg = child_num_arg; + ts->threadattr = thread_attr; + + rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, + ts, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again if we exit. */ + apr_sleep(10 * APR_USEC_PER_SEC); + clean_child_exit(APEXIT_CHILDFATAL); + } + + mpm_state = AP_MPMQ_RUNNING; + + /* If we are only running in one_process mode, we will want to + * still handle signals. */ + if (one_process) { + /* Block until we get a terminating signal. */ + apr_signal_thread(check_signal); + /* make sure the start thread has finished; signal_threads() + * and join_workers() depend on that + */ + /* XXX join_start_thread() won't be awakened if one of our + * threads encounters a critical error and attempts to + * shutdown this child + */ + join_start_thread(start_thread_id); + signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more + * quickly than the dispatch of the signal thread + * beats the Pipe of Death and the browsers + */ + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + else { /* !one_process */ + /* remove SIGTERM from the set of blocked signals... if one of + * the other threads in the process needs to take us down + * (e.g., for MaxRequestsPerChild) it will send us SIGTERM + */ + unblock_signal(SIGTERM); + apr_signal(SIGTERM, dummy_signal_handler); + /* Watch for any messages from the parent over the POD */ + while (1) { + rv = ap_mpm_pod_check(pod); + if (rv == AP_NORESTART) { + /* see if termination was triggered while we slept */ + switch(terminate_mode) { + case ST_GRACEFUL: + rv = AP_GRACEFUL; + break; + case ST_UNGRACEFUL: + rv = AP_RESTART; + break; + } + } + if (rv == AP_GRACEFUL || rv == AP_RESTART) { + /* make sure the start thread has finished; + * signal_threads() and join_workers depend on that + */ + join_start_thread(start_thread_id); + signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); + break; + } + } + + if (rv == AP_GRACEFUL) { + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + } + + free(threads); + + clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); +} + +static int make_child(server_rec *s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + set_signals(); + ap_scoreboard_image->parent[slot].pid = getpid(); + child_main(slot); + } + + if ((pid = fork()) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, + "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); + + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again. */ + apr_sleep(10 * APR_USEC_PER_SEC); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* By default, AIX binds to a single processor. This bit unbinds + * children which will then bind to another CPU. + */ + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, + "processor unbind failed %d", status); +#endif + RAISE_SIGSTOP(MAKE_CHILD); + + apr_signal(SIGTERM, just_die); + child_main(slot); + + clean_child_exit(0); + } + /* else */ + ap_scoreboard_image->parent[slot].quiescing = 0; + ap_scoreboard_image->parent[slot].pid = pid; + return 0; +} + +/* start up a bunch of children */ +static void startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { + if (ap_scoreboard_image->parent[i].pid != 0) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(void) +{ + int i, j; + int idle_thread_count; + worker_score *ws; + process_score *ps; + int free_length; + int totally_free_length = 0; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + + /* initialize the free_list */ + free_length = 0; + + idle_thread_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_daemons_limit; ++i) { + /* Initialization to satisfy the compiler. It doesn't know + * that ap_threads_per_child is always > 0 */ + int status = SERVER_DEAD; + int any_dying_threads = 0; + int any_dead_threads = 0; + int all_dead_threads = 1; + + if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) + break; + ps = &ap_scoreboard_image->parent[i]; + for (j = 0; j < ap_threads_per_child; j++) { + ws = &ap_scoreboard_image->servers[i][j]; + status = ws->status; + + /* XXX any_dying_threads is probably no longer needed GLA */ + any_dying_threads = any_dying_threads || + (status == SERVER_GRACEFUL); + any_dead_threads = any_dead_threads || (status == SERVER_DEAD); + all_dead_threads = all_dead_threads && + (status == SERVER_DEAD || + status == SERVER_GRACEFUL); + + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (status <= SERVER_READY && status != SERVER_DEAD && + !ps->quiescing && + ps->generation == ap_my_generation && + /* XXX the following shouldn't be necessary if we clean up + * properly after seg faults, but we're not yet GLA + */ + ps->pid != 0) { + ++idle_thread_count; + } + } + if (any_dead_threads && totally_free_length < idle_spawn_rate + && (!ps->pid /* no process in the slot */ + || ps->quiescing)) { /* or at least one is going away */ + if (all_dead_threads) { + /* great! we prefer these, because the new process can + * start more threads sooner. So prioritize this slot + * by putting it ahead of any slots with active threads. + * + * first, make room by moving a slot that's potentially still + * in use to the end of the array + */ + free_slots[free_length] = free_slots[totally_free_length]; + free_slots[totally_free_length++] = i; + } + else { + /* slot is still in use - back of the bus + */ + free_slots[free_length] = i; + } + ++free_length; + } + /* XXX if (!ps->quiescing) is probably more reliable GLA */ + if (!any_dying_threads) { + last_non_dead = i; + ++total_non_dead; + } + } + ap_max_daemons_limit = last_non_dead + 1; + + if (idle_thread_count > max_spare_threads) { + /* Kill off one child */ + ap_mpm_pod_signal(pod, TRUE); + idle_spawn_rate = 1; + } + else if (idle_thread_count < min_spare_threads) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (free_length > idle_spawn_rate) { + free_length = idle_spawn_rate; + } + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, ThreadsPerChild " + "or Min/MaxSpareThreads), " + "spawning %d children, there are around %d idle " + "threads, and %d total children", free_length, + idle_thread_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_children_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + for (i = 0; i < ap_threads_per_child; i++) + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); + + ap_scoreboard_image->parent[child_slot].pid = 0; + ap_scoreboard_image->parent[child_slot].quiescing = 0; + if (processed_status == APEXIT_CHILDSICK) { + /* resource shortage, minimize the fork rate */ + idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, + status) == 0) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + ap_server_conf, + "long lost child came home! (pid %ld)", + (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_idle_server_maintenance(); + } +} + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int remaining_children_to_start; + apr_status_t rv; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + first_thread_limit = thread_limit; + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit or ThreadLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + /* Initialize cross-process accept lock */ + ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, + ap_server_root_relative(_pconf, ap_lock_fname), + ap_my_pid); + + rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, + ap_accept_lock_mech, _pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create accept lock"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_proc_mutex_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock; " + "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + + set_signals(); + /* Don't thrash... */ + if (max_spare_threads < min_spare_threads + ap_threads_per_child) + max_spare_threads = min_spare_threads + ap_threads_per_child; + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty + * rapidly... and for each one that exits we'll start a new one until + * we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = ap_daemons_to_start; + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } + if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } + else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + mpm_state = AP_MPMQ_RUNNING; + + server_main_loop(remaining_children_to_start); + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + * (By "gracefully" we don't mean graceful in the same sense as + * "apachectl graceful" where we allow old connections to finish.) + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if ( pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long)getpid()); + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "caught SIGTERM, shutting down"); + } + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + + if (one_process) { + /* not worth thinking about */ + return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); + /* wake up the children...time to die. But we'll have more soon */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE); + + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. + */ + + } + else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + ap_listen_rec *lr; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + +#if APR_O_NONBLOCK_INHERITED + for(lr = ap_listeners ; lr != NULL ; lr = lr->next) { + apr_socket_opt_set(lr->sd, APR_SO_NONBLOCK, 1); + } +#endif /* APR_O_NONBLOCK_INHERITED */ + + if (!one_process) { + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + } + return OK; +} + +static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + ap_directive_t *pdir; + ap_directive_t *max_clients = NULL; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { + if (!max_clients) { + break; /* we're in the clear, got ThreadsPerChild first */ + } + else { + /* now to swap the data */ + ap_directive_t temp; + + temp.directive = pdir->directive; + temp.args = pdir->args; + /* Make sure you don't change 'next', or you may get loops! */ + /* XXX: first_child, parent, and data can never be set + * for these directives, right? -aaron */ + temp.filename = pdir->filename; + temp.line_num = pdir->line_num; + + pdir->directive = max_clients->directive; + pdir->args = max_clients->args; + pdir->filename = max_clients->filename; + pdir->line_num = max_clients->line_num; + + max_clients->directive = temp.directive; + max_clients->args = temp.args; + max_clients->filename = temp.filename; + max_clients->line_num = temp.line_num; + break; + } + } + else if (!max_clients + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + max_clients = pdir; + } + } + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + parent_pid = ap_my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + ap_daemons_limit = server_limit; + ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void threadpool_hooks(apr_pool_t *p) +{ + /* The worker open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + one_process = 0; + + ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + return NULL; +} + +static const char *set_max_clients (cmd_parms *cmd, void *dummy, + const char *arg) +{ + int max_clients; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + /* It is ok to use ap_threads_per_child here because we are + * sure that it gets set before MaxClients in the pre_config stage. */ + max_clients = atoi(arg); + if (max_clients < ap_threads_per_child) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) must be at least as large", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " large as ThreadsPerChild (%d). Automatically", + ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " increasing MaxClients to %d.", + ap_threads_per_child); + max_clients = ap_threads_per_child; + } + ap_daemons_limit = max_clients / ap_threads_per_child; + if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) is not an integer multiple", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " of ThreadsPerChild (%d), lowering MaxClients to %d", + ap_threads_per_child, + ap_daemons_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " for a maximum of %d child processes,", + ap_daemons_limit); + max_clients = ap_daemons_limit * ap_threads_per_child; + } + if (ap_daemons_limit > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d would require %d servers,", + max_clients, ap_daemons_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " and would exceed the ServerLimit value of %d.", + server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " Automatically lowering MaxClients to %d. To increase,", + server_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " please see the ServerLimit directive."); + ap_daemons_limit = server_limit; + } + else if (ap_daemons_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; + } + return NULL; +} + +static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_per_child = atoi(arg); + if (ap_threads_per_child > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " + "value of %d", ap_threads_per_child, + thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "threads, lowering ThreadsPerChild to %d. To increase, please" + " see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + ap_threads_per_child = thread_limit; + } + else if (ap_threads_per_child < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadsPerChild > 0, setting to 1"); + ap_threads_per_child = 1; + } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && + tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d servers,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} + +static const command_rec threadpool_cmds[] = { +UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), +AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle children"), +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, + "Maximum number of children alive at the same time"), +AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, + "Number of threads each child creates"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum value of MaxClients for this run of Apache"), +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum worker threads in a server for this run of Apache"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_threadpool_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + threadpool_cmds, /* command apr_table_t */ + threadpool_hooks /* register_hooks */ +}; + diff --git a/trunk/server/mpm/mpmt_os2/Makefile.in b/trunk/server/mpm/mpmt_os2/Makefile.in new file mode 100644 index 0000000000..38e598edf3 --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libmpmt_os2.la +LTLIBRARY_SOURCES = mpmt_os2.c mpmt_os2_child.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/mpmt_os2/config5.m4 b/trunk/server/mpm/mpmt_os2/config5.m4 new file mode 100644 index 0000000000..b27c296d2a --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/config5.m4 @@ -0,0 +1,5 @@ +if test "$MPM_NAME" = "mpmt_os2" ; then + AC_CACHE_SAVE + APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) + APR_ADDTO(CFLAGS,-Zmt) +fi diff --git a/trunk/server/mpm/mpmt_os2/mpm.h b/trunk/server/mpm/mpmt_os2/mpm.h new file mode 100644 index 0000000000..a5b3973069 --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/mpm.h @@ -0,0 +1,34 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_MPMT_OS2_H +#define APACHE_MPM_MPMT_OS2_H + +#define MPMT_OS2_MPM + +#include "httpd.h" +#include "mpm_default.h" +#include "scoreboard.h" + +#define MPM_NAME "MPMT_OS2" + +extern server_rec *ap_server_conf; +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK +#define AP_MPM_WANT_SET_MAX_MEM_FREE + +#endif /* APACHE_MPM_MPMT_OS2_H */ diff --git a/trunk/server/mpm/mpmt_os2/mpm_default.h b/trunk/server/mpm/mpmt_os2/mpm_default.h new file mode 100644 index 0000000000..24a98ad9b9 --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/mpm_default.h @@ -0,0 +1,59 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers processes to spawn off by default + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 2 +#endif + +/* Maximum number of *free* server threads --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_SPARE_THREAD +#define DEFAULT_MAX_SPARE_THREAD 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_SPARE_THREAD +#define DEFAULT_MIN_SPARE_THREAD 5 +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/mpmt_os2/mpmt_os2.c b/trunk/server/mpm/mpmt_os2/mpmt_os2.c new file mode 100644 index 0000000000..3c8a57e87c --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/mpmt_os2.c @@ -0,0 +1,577 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Multi-process, multi-threaded MPM for OS/2 + * + * Server consists of + * - a main, parent process + * - a small, static number of child processes + * + * The parent process's job is to manage the child processes. This involves + * spawning children as required to ensure there are always ap_daemons_to_start + * processes accepting connections. + * + * Each child process consists of a a pool of worker threads and a + * main thread that accepts connections & passes them to the workers via + * a work queue. The worker thread pool is dynamic, managed by a maintanence + * thread so that the number of idle threads is kept between + * min_spare_threads & max_spare_threads. + * + */ + +/* + Todo list + - Enforce MaxClients somehow +*/ +#define CORE_PRIVATE +#define INCL_NOPMAPI +#define INCL_DOS +#define INCL_DOSERRORS + +#include "ap_config.h" +#include "httpd.h" +#include "mpm_default.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "mpm.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "apr_portable.h" +#include "mpm_common.h" +#include "apr_strings.h" +#include +#include + +/* We don't need many processes, + * they're only for redundancy in the event of a crash + */ +#define HARD_SERVER_LIMIT 10 + +/* Limit on the total number of threads per process + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 256 +#endif + +server_rec *ap_server_conf; +static apr_pool_t *pconf = NULL; /* Pool for config stuff */ +static const char *ap_pid_fname=NULL; + +/* Config globals */ +static int one_process = 0; +static int ap_daemons_to_start = 0; +static int ap_thread_limit = 0; +static int ap_max_requests_per_child = 0; +int ap_min_spare_threads = 0; +int ap_max_spare_threads = 0; + +/* Keep track of a few interesting statistics */ +int ap_max_daemons_limit = -1; + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful = 0; +ap_generation_t volatile ap_my_generation=0; /* Used by the scoreboard */ +static int is_parent_process=TRUE; +HMTX ap_mpm_accept_mutex = 0; + +/* An array of these is stored in a shared memory area for passing + * sockets from the parent to child processes + */ +typedef struct { + struct sockaddr_in name; + apr_os_sock_t listen_fd; +} listen_socket_t; + +typedef struct { + HMTX accept_mutex; + listen_socket_t listeners[1]; +} parent_info_t; + +static char master_main(); +static void spawn_child(int slot); +void ap_mpm_child_main(apr_pool_t *pconf); +static void set_signals(); + + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) +{ + char *listener_shm_name; + parent_info_t *parent_info; + ULONG rc; + pconf = _pconf; + ap_server_conf = s; + restart_pending = 0; + + DosSetMaxFH(ap_thread_limit * 2); + listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getppid()); + rc = DosGetNamedSharedMem((PPVOID)&parent_info, listener_shm_name, PAG_READ); + is_parent_process = rc != 0; + ap_scoreboard_fname = apr_psprintf(pconf, "/sharemem/httpd/scoreboard.%d", is_parent_process ? getpid() : getppid()); + + if (rc == 0) { + /* Child process */ + ap_listen_rec *lr; + int num_listeners = 0; + + ap_mpm_accept_mutex = parent_info->accept_mutex; + + /* Set up a default listener if necessary */ + if (ap_listeners == NULL) { + ap_listen_rec *lr = apr_pcalloc(s->process->pool, sizeof(ap_listen_rec)); + ap_listeners = lr; + apr_sockaddr_info_get(&lr->bind_addr, "0.0.0.0", APR_UNSPEC, + DEFAULT_HTTP_PORT, 0, s->process->pool); + apr_socket_create(&lr->sd, lr->bind_addr->family, + SOCK_STREAM, 0, s->process->pool); + } + + for (lr = ap_listeners; lr; lr = lr->next) { + apr_sockaddr_t *sa; + apr_os_sock_put(&lr->sd, &parent_info->listeners[num_listeners].listen_fd, pconf); + apr_socket_addr_get(&sa, APR_LOCAL, lr->sd); + num_listeners++; + } + + DosFreeMem(parent_info); + + /* Do the work */ + ap_mpm_child_main(pconf); + + /* Outta here */ + return 1; + } + else { + /* Parent process */ + char restart; + is_parent_process = TRUE; + + if (ap_setup_listeners(ap_server_conf) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, + "no listening sockets available, shutting down"); + return 1; + } + + ap_log_pid(pconf, ap_pid_fname); + + restart = master_main(); + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (!restart) { + const char *pidfile = ap_server_root_relative(pconf, ap_pid_fname); + + if (pidfile != NULL && remove(pidfile) == 0) { + ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, + ap_server_conf, "removed PID file %s (pid=%d)", + pidfile, getpid()); + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught SIGTERM, shutting down"); + return 1; + } + } /* Parent process */ + + return 0; /* Restart */ +} + + + +/* Main processing of the parent process + * returns TRUE if restarting + */ +static char master_main() +{ + server_rec *s = ap_server_conf; + ap_listen_rec *lr; + parent_info_t *parent_info; + char *listener_shm_name; + int listener_num, num_listeners, slot; + ULONG rc; + + printf("%s \n", ap_get_server_version()); + set_signals(); + + if (ap_setup_listeners(ap_server_conf) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, + "no listening sockets available, shutting down"); + return FALSE; + } + + /* Allocate a shared memory block for the array of listeners */ + for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) { + num_listeners++; + } + + listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid()); + rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name, + sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t), + PAG_READ|PAG_WRITE|PAG_COMMIT); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s, + "failure allocating shared memory, shutting down"); + return FALSE; + } + + /* Store the listener sockets in the shared memory area for our children to see */ + for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) { + apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd); + } + + /* Create mutex to prevent multiple child processes from detecting + * a connection with apr_poll() + */ + + rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s, + "failure creating accept mutex, shutting down"); + return FALSE; + } + + parent_info->accept_mutex = ap_mpm_accept_mutex; + + /* Allocate shared memory for scoreboard */ + if (ap_scoreboard_image == NULL) { + void *sb_mem; + rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname, + ap_calc_scoreboard_size(), + PAG_COMMIT|PAG_READ|PAG_WRITE); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "unable to allocate shared memory for scoreboard , exiting"); + return FALSE; + } + + ap_init_scoreboard(sb_mem); + } + + ap_scoreboard_image->global->restart_time = apr_time_now(); + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + if (one_process) { + ap_scoreboard_image->parent[0].pid = getpid(); + ap_mpm_child_main(pconf); + return FALSE; + } + + while (!restart_pending && !shutdown_pending) { + RESULTCODES proc_rc; + PID child_pid; + int active_children = 0; + + /* Count number of active children */ + for (slot=0; slot < HARD_SERVER_LIMIT; slot++) { + active_children += ap_scoreboard_image->parent[slot].pid != 0 && + !ap_scoreboard_image->parent[slot].quiescing; + } + + /* Spawn children if needed */ + for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) { + if (ap_scoreboard_image->parent[slot].pid == 0) { + spawn_child(slot); + active_children++; + } + } + + rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0); + + if (rc == 0) { + /* A child has terminated, remove its scoreboard entry & terminate if necessary */ + for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++); + + if (slot < HARD_SERVER_LIMIT) { + ap_scoreboard_image->parent[slot].pid = 0; + ap_scoreboard_image->parent[slot].quiescing = 0; + + if (proc_rc.codeTerminate == TC_EXIT) { + /* Child terminated normally, check its exit code and + * terminate server if child indicates a fatal error + */ + if (proc_rc.codeResult == APEXIT_CHILDFATAL) + break; + } + } + } else if (rc == ERROR_CHILD_NOT_COMPLETE) { + /* No child exited, lets sleep for a while.... */ + apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); + } + } + + /* Signal children to shut down, either gracefully or immediately */ + for (slot=0; slotparent[slot].pid, is_graceful ? SIGHUP : SIGTERM); + } + + DosFreeMem(parent_info); + return restart_pending; +} + + + +static void spawn_child(int slot) +{ + PPIB ppib; + PTIB ptib; + char fail_module[100]; + char progname[CCHMAXPATH]; + RESULTCODES proc_rc; + ULONG rc; + + ap_scoreboard_image->parent[slot].generation = ap_my_generation; + DosGetInfoBlocks(&ptib, &ppib); + DosQueryModuleName(ppib->pib_hmte, sizeof(progname), progname); + rc = DosExecPgm(fail_module, sizeof(fail_module), EXEC_ASYNCRESULT, + ppib->pib_pchcmd, NULL, &proc_rc, progname); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "error spawning child, slot %d", slot); + } + + if (ap_max_daemons_limit < slot) { + ap_max_daemons_limit = slot; + } + + ap_scoreboard_image->parent[slot].pid = proc_rc.codeTerminate; +} + + + +/* Signal handling routines */ + +static void sig_term(int sig) +{ + shutdown_pending = 1; + signal(SIGTERM, SIG_DFL); +} + + + +static void sig_restart(int sig) +{ + if (sig == SIGUSR1) { + is_graceful = 1; + } + + restart_pending = 1; +} + + + +static void set_signals() +{ + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sig_term; + + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); + + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); + + sa.sa_handler = sig_restart; + + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); + if (sigaction(SIGUSR1, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGUSR1)"); +} + + + +/* Enquiry functions used get MPM status info */ + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch (query_code) { + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_NOT_SUPPORTED; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = HARD_SERVER_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = HARD_THREAD_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + + + +int ap_graceful_stop_signalled(void) +{ + return is_graceful; +} + + + +/* Configuration handling stuff */ + +static int mpmt_os2_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) +{ + one_process = ap_exists_config_define("ONE_PROCESS") || + ap_exists_config_define("DEBUG"); + is_graceful = 0; + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + ap_thread_limit = HARD_THREAD_LIMIT; + ap_pid_fname = DEFAULT_PIDLOG; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; + ap_min_spare_threads = DEFAULT_MIN_SPARE_THREAD; + ap_max_spare_threads = DEFAULT_MAX_SPARE_THREAD; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + return OK; +} + + + +static void mpmt_os2_hooks(apr_pool_t *p) +{ + ap_hook_pre_config(mpmt_os2_pre_config, NULL, NULL, APR_HOOK_MIDDLE); +} + + + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + + + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + ap_min_spare_threads = atoi(arg); + + if (ap_min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + ap_min_spare_threads = 1; + } + + return NULL; +} + + + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { + return err; + } + + ap_max_spare_threads = atoi(arg); + return NULL; +} + + + +static const char *ignore_cmd(cmd_parms *cmd, void *dummy, const char *arg) +{ + return NULL; +} + + + +static const command_rec mpmt_os2_cmds[] = { +LISTEN_COMMANDS, +AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup" ), +AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle children"), +AP_INIT_TAKE1("User", ignore_cmd, NULL, RSRC_CONF, + "Not applicable on this platform"), +AP_INIT_TAKE1("Group", ignore_cmd, NULL, RSRC_CONF, + "Not applicable on this platform"), +AP_INIT_TAKE1("ScoreBoardFile", ignore_cmd, NULL, RSRC_CONF, \ + "Not applicable on this platform"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_mpmt_os2_module = { + MPM20_MODULE_STUFF, + NULL, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + mpmt_os2_cmds, /* command apr_table_t */ + mpmt_os2_hooks, /* register_hooks */ +}; diff --git a/trunk/server/mpm/mpmt_os2/mpmt_os2_child.c b/trunk/server/mpm/mpmt_os2/mpmt_os2_child.c new file mode 100644 index 0000000000..95dd515fc9 --- /dev/null +++ b/trunk/server/mpm/mpmt_os2/mpmt_os2_child.c @@ -0,0 +1,480 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE +#define INCL_NOPMAPI +#define INCL_DOS +#define INCL_DOSERRORS + +#include "ap_config.h" +#include "httpd.h" +#include "mpm_default.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "mpm.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "apr_portable.h" +#include "apr_poll.h" +#include "mpm_common.h" +#include "apr_strings.h" +#include +#include + +/* XXXXXX move these to header file private to this MPM */ + +/* We don't need many processes, + * they're only for redundancy in the event of a crash + */ +#define HARD_SERVER_LIMIT 10 + +/* Limit on the total number of threads per process + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 256 +#endif + +#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) + +typedef struct { + apr_pool_t *pconn; + apr_socket_t *conn_sd; +} worker_args_t; + +#define WORKTYPE_CONN 0 +#define WORKTYPE_EXIT 1 + +static apr_pool_t *pchild = NULL; +static int child_slot; +static int shutdown_pending = 0; +extern int ap_my_generation; +static int volatile is_graceful = 1; +HEV shutdown_event; /* signaled when this child is shutting down */ + +/* grab some MPM globals */ +extern int ap_min_spare_threads; +extern int ap_max_spare_threads; +extern HMTX ap_mpm_accept_mutex; + +static void worker_main(void *vpArg); +static void clean_child_exit(int code); +static void set_signals(); +static void server_maintenance(void *vpArg); + + +static void clean_child_exit(int code) +{ + if (pchild) { + apr_pool_destroy(pchild); + } + + exit(code); +} + + + +void ap_mpm_child_main(apr_pool_t *pconf) +{ + ap_listen_rec *lr = NULL; + int requests_this_child = 0; + int rv = 0; + unsigned long ulTimes; + int my_pid = getpid(); + ULONG rc, c; + HQUEUE workq; + apr_pollset_t *pollset; + int num_listeners; + TID server_maint_tid; + void *sb_mem; + + /* Stop Ctrl-C/Ctrl-Break signals going to child processes */ + DosSetSignalExceptionFocus(0, &ulTimes); + set_signals(); + + /* Create pool for child */ + apr_pool_create(&pchild, pconf); + + ap_run_child_init(pchild, ap_server_conf); + + /* Create an event semaphore used to trigger other threads to shutdown */ + rc = DosCreateEventSem(NULL, &shutdown_event, 0, FALSE); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "unable to create shutdown semaphore, exiting"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + /* Gain access to the scoreboard. */ + rc = DosGetNamedSharedMem(&sb_mem, ap_scoreboard_fname, + PAG_READ|PAG_WRITE); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "scoreboard not readable in child, exiting"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_calc_scoreboard_size(); + ap_init_scoreboard(sb_mem); + + /* Gain access to the accpet mutex */ + rc = DosOpenMutexSem(NULL, &ap_mpm_accept_mutex); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "accept mutex couldn't be accessed in child, exiting"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + /* Find our pid in the scoreboard so we know what slot our parent allocated us */ + for (child_slot = 0; ap_scoreboard_image->parent[child_slot].pid != my_pid && child_slot < HARD_SERVER_LIMIT; child_slot++); + + if (child_slot == HARD_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "child pid not found in scoreboard, exiting"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_my_generation = ap_scoreboard_image->parent[child_slot].generation; + memset(ap_scoreboard_image->servers[child_slot], 0, sizeof(worker_score) * HARD_THREAD_LIMIT); + + /* Set up an OS/2 queue for passing connections & termination requests + * to worker threads + */ + rc = DosCreateQueue(&workq, QUE_FIFO, apr_psprintf(pchild, "/queues/httpd/work.%d", my_pid)); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "unable to create work queue, exiting"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + /* Create initial pool of worker threads */ + for (c = 0; c < ap_min_spare_threads; c++) { +// ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c); + } + + /* Start maintenance thread */ + server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL); + + /* Set up poll */ + for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) { + num_listeners++; + } + + apr_pollset_create(&pollset, num_listeners, pchild, 0); + + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + apr_pollset_add(pollset, &pfd); + } + + /* Main connection accept loop */ + do { + apr_pool_t *pconn; + worker_args_t *worker_args; + int last_poll_idx = 0; + + apr_pool_create(&pconn, pchild); + worker_args = apr_palloc(pconn, sizeof(worker_args_t)); + worker_args->pconn = pconn; + + if (num_listeners == 1) { + rv = apr_socket_accept(&worker_args->conn_sd, ap_listeners->sd, pconn); + } else { + const apr_pollfd_t *poll_results; + apr_int32_t num_poll_results; + + rc = DosRequestMutexSem(ap_mpm_accept_mutex, SEM_INDEFINITE_WAIT); + + if (shutdown_pending) { + DosReleaseMutexSem(ap_mpm_accept_mutex); + break; + } + + rv = APR_FROM_OS_ERROR(rc); + + if (rv == APR_SUCCESS) { + rv = apr_pollset_poll(pollset, -1, &num_poll_results, &poll_results); + DosReleaseMutexSem(ap_mpm_accept_mutex); + } + + if (rv == APR_SUCCESS) { + if (last_poll_idx >= num_listeners) { + last_poll_idx = 0; + } + + lr = poll_results[last_poll_idx++].client_data; + rv = apr_socket_accept(&worker_args->conn_sd, lr->sd, pconn); + last_poll_idx++; + } + } + + if (rv != APR_SUCCESS) { + if (!APR_STATUS_IS_EINTR(rv)) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, + "apr_socket_accept"); + clean_child_exit(APEXIT_CHILDFATAL); + } + } else { + DosWriteQueue(workq, WORKTYPE_CONN, sizeof(worker_args_t), worker_args, 0); + requests_this_child++; + } + + if (ap_max_requests_per_child != 0 && requests_this_child >= ap_max_requests_per_child) + break; + } while (!shutdown_pending && ap_my_generation == ap_scoreboard_image->global->running_generation); + + ap_scoreboard_image->parent[child_slot].quiescing = 1; + DosPostEventSem(shutdown_event); + DosWaitThread(&server_maint_tid, DCWW_WAIT); + + if (is_graceful) { + char someleft; + + /* tell our worker threads to exit */ + for (c=0; cservers[child_slot][c].status != SERVER_DEAD) { + DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); + } + } + + do { + someleft = 0; + + for (c=0; cservers[child_slot][c].status != SERVER_DEAD) { + someleft = 1; + DosSleep(1000); + break; + } + } + } while (someleft); + } else { + DosPurgeQueue(workq); + + for (c=0; cservers[child_slot][c].status != SERVER_DEAD) { + DosKillThread(ap_scoreboard_image->servers[child_slot][c].tid); + } + } + } + + apr_pool_destroy(pchild); +} + + + +void add_worker() +{ + int thread_slot; + + /* Find a free thread slot */ + for (thread_slot=0; thread_slot < HARD_THREAD_LIMIT; thread_slot++) { + if (ap_scoreboard_image->servers[child_slot][thread_slot].status == SERVER_DEAD) { + ap_scoreboard_image->servers[child_slot][thread_slot].status = SERVER_STARTING; + ap_scoreboard_image->servers[child_slot][thread_slot].tid = + _beginthread(worker_main, NULL, 128*1024, (void *)thread_slot); + break; + } + } +} + + + +ULONG APIENTRY thread_exception_handler(EXCEPTIONREPORTRECORD *pReportRec, + EXCEPTIONREGISTRATIONRECORD *pRegRec, + CONTEXTRECORD *pContext, + PVOID p) +{ + int c; + + if (pReportRec->fHandlerFlags & EH_NESTED_CALL) { + return XCPT_CONTINUE_SEARCH; + } + + if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION || + pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "caught exception in worker thread, initiating child shutdown pid=%d", getpid()); + for (c=0; cservers[child_slot][c].tid == _gettid()) { + ap_scoreboard_image->servers[child_slot][c].status = SERVER_DEAD; + break; + } + } + + /* Shut down process ASAP, it could be quite unhealthy & leaking resources */ + shutdown_pending = 1; + ap_scoreboard_image->parent[child_slot].quiescing = 1; + kill(getpid(), SIGHUP); + DosUnwindException(UNWIND_ALL, 0, 0); + } + + return XCPT_CONTINUE_SEARCH; +} + + + +static void worker_main(void *vpArg) +{ + long conn_id; + conn_rec *current_conn; + apr_pool_t *pconn; + apr_allocator_t *allocator; + apr_bucket_alloc_t *bucket_alloc; + worker_args_t *worker_args; + HQUEUE workq; + PID owner; + int rc; + REQUESTDATA rd; + ULONG len; + BYTE priority; + int thread_slot = (int)vpArg; + EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler }; + ap_sb_handle_t *sbh; + + /* Trap exceptions in this thread so we don't take down the whole process */ + DosSetExceptionHandler( ®_rec ); + + rc = DosOpenQueue(&owner, &workq, + apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "unable to open work queue, exiting"); + ap_scoreboard_image->servers[child_slot][thread_slot].tid = 0; + } + + conn_id = ID_FROM_CHILD_THREAD(child_slot, thread_slot); + ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY, + NULL); + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + bucket_alloc = apr_bucket_alloc_create_ex(allocator); + + while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE), + rc == 0 && rd.ulData != WORKTYPE_EXIT) { + pconn = worker_args->pconn; + ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); + current_conn = ap_run_create_connection(pconn, ap_server_conf, + worker_args->conn_sd, conn_id, + sbh, bucket_alloc); + + if (current_conn) { + ap_process_connection(current_conn, worker_args->conn_sd); + ap_lingering_close(current_conn); + } + + apr_pool_destroy(pconn); + ap_update_child_status_from_indexes(child_slot, thread_slot, + SERVER_READY, NULL); + } + + ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD, + NULL); + + apr_bucket_alloc_destroy(bucket_alloc); + apr_allocator_destroy(allocator); +} + + + +static void server_maintenance(void *vpArg) +{ + int num_idle, num_needed; + ULONG num_pending = 0; + int threadnum; + HQUEUE workq; + ULONG rc; + PID owner; + + rc = DosOpenQueue(&owner, &workq, + apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); + + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, + "unable to open work queue in maintenance thread"); + return; + } + + do { + for (num_idle=0, threadnum=0; threadnum < HARD_THREAD_LIMIT; threadnum++) { + num_idle += ap_scoreboard_image->servers[child_slot][threadnum].status == SERVER_READY; + } + + DosQueryQueue(workq, &num_pending); + num_needed = ap_min_spare_threads - num_idle + num_pending; + + if (num_needed > 0) { + for (threadnum=0; threadnum < num_needed; threadnum++) { + add_worker(); + } + } + + if (num_idle - num_pending > ap_max_spare_threads) { + DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); + } + } while (DosWaitEventSem(shutdown_event, 500) == ERROR_TIMEOUT); +} + + + +/* Signal handling routines */ + +static void sig_term(int sig) +{ + shutdown_pending = 1; + is_graceful = 0; + signal(SIGTERM, SIG_DFL); +} + + + +static void sig_hup(int sig) +{ + shutdown_pending = 1; + is_graceful = 1; +} + + + +static void set_signals() +{ + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sig_term; + + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); + + sa.sa_handler = sig_hup; + + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); +} diff --git a/trunk/server/mpm/netware/mpm.h b/trunk/server/mpm/netware/mpm.h new file mode 100644 index 0000000000..98f15c774c --- /dev/null +++ b/trunk/server/mpm/netware/mpm.h @@ -0,0 +1,48 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoreboard.h" + +#ifndef APACHE_MPM_THREADED_H +#define APACHE_MPM_THREADED_H + +#define THREADED_MPM + +#define MPM_NAME "NetWare_Threaded" + +/*#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES + #define AP_MPM_WANT_WAIT_OR_TIMEOUT + #define AP_MPM_WANT_PROCESS_CHILD_STATUS + #define AP_MPM_WANT_SET_PIDFILE + #define AP_MPM_WANT_SET_SCOREBOARD + #define AP_MPM_WANT_SET_LOCKFILE +*/ +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK +/*#define AP_MPM_WANT_SET_COREDUMPDIR + #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +*/ + +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) + +extern int ap_threads_per_child; +extern int ap_max_workers_limit; +extern server_rec *ap_server_conf; + +#endif /* APACHE_MPM_THREADED_H */ diff --git a/trunk/server/mpm/netware/mpm_default.h b/trunk/server/mpm/netware/mpm_default.h new file mode 100644 index 0000000000..c5fb9e8ead --- /dev/null +++ b/trunk/server/mpm/netware/mpm_default.h @@ -0,0 +1,114 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 1 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 1 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 1 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 2048 +#endif + +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 50 +#endif + +/* Number of threads to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_THREADS +#define DEFAULT_START_THREADS DEFAULT_THREADS_PER_CHILD +#endif + +/* Maximum number of *free* threads --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_THREADS +#define DEFAULT_MAX_FREE_THREADS 100 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_THREADS +#define DEFAULT_MIN_FREE_THREADS 10 +#endif + +/* Check for definition of DEFAULT_REL_RUNTIMEDIR */ +#ifndef DEFAULT_REL_RUNTIMEDIR +#define DEFAULT_REL_RUNTIMEDIR "logs" +#endif + +/* File used for accept locking, when we use a file */ +/*#ifndef DEFAULT_LOCKFILE + #define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" + #endif +*/ + +/* Where the main/parent process's pid is logged */ +/*#ifndef DEFAULT_PIDLOG + #define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" + #endif +*/ + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 0 +#endif + +/* Default stack size allocated for each worker thread. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 65536 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/netware/mpm_netware.c b/trunk/server/mpm/netware/mpm_netware.c new file mode 100644 index 0000000000..65b37b99a9 --- /dev/null +++ b/trunk/server/mpm/netware/mpm_netware.c @@ -0,0 +1,1291 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * httpd.c: simple http daemon for answering WWW file requests + * + * + * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3) + * + * 03-06-95 blong + * changed server number for child-alone processes to 0 and changed name + * of processes + * + * 03-10-95 blong + * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu) + * including set group before fork, and call gettime before to fork + * to set up libraries. + * + * 04-14-95 rst / rh + * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the + * Apache server, and also to have child processes do accept() directly. + * + * April-July '95 rst + * Extensive rework for Apache. + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_tables.h" +#include "apr_getopt.h" +#include "apr_thread_mutex.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_TYPES_H +#include +#endif + +#ifndef USE_WINSOCK +#include +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "mpm_default.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "scoreboard.h" +#include "ap_mpm.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "ap_mmn.h" + +#ifdef HAVE_TIME_H +#include +#endif + +#include + +#include +#include +#include +#include + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 1 +#endif + +#define WORKER_DEAD SERVER_DEAD +#define WORKER_STARTING SERVER_STARTING +#define WORKER_READY SERVER_READY +#define WORKER_IDLE_KILL SERVER_IDLE_KILL + +/* config globals */ + +int ap_threads_per_child=0; /* Worker threads per child */ +static int ap_threads_to_start=0; +static int ap_threads_min_free=0; +static int ap_threads_max_free=0; +static int ap_threads_limit=0; +static int mpm_state = AP_MPMQ_STARTING; + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across SIGWINCH restarts. We use this + * value to optimize routines that have to scan the entire scoreboard. + */ +int ap_max_workers_limit = -1; +server_rec *ap_server_conf; + +/* *Non*-shared http_main globals... */ + +int hold_screen_on_exit = 0; /* Indicates whether the screen should be held open */ + +static fd_set listenfds; +static int listenmaxfd; + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pmain; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ +static char *ap_my_addrspace = NULL; + +static int die_now = 0; + +/* Keep track of the number of worker threads currently active */ +static unsigned long worker_thread_count; +static int request_count; + +/* Structure used to register/deregister a console handler with the OS */ +static int InstallConsoleHandler(void); +static void RemoveConsoleHandler(void); +static int CommandLineInterpreter(scr_t screenID, const char *commandLine); +static CommandParser_t ConsoleHandler = {0, NULL, 0}; +#define HANDLEDCOMMAND 0 +#define NOTMYCOMMAND 1 + +static int show_settings = 0; + +//#define DBINFO_ON +//#define DBPRINT_ON +#ifdef DBPRINT_ON +#define DBPRINT0(s) printf(s) +#define DBPRINT1(s,v1) printf(s,v1) +#define DBPRINT2(s,v1,v2) printf(s,v1,v2) +#else +#define DBPRINT0(s) +#define DBPRINT1(s,v1) +#define DBPRINT2(s,v1,v2) +#endif + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static int volatile wait_to_finish=1; +ap_generation_t volatile ap_my_generation=0; + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, + apr_bucket_alloc_t *bucket_alloc) __attribute__ ((noreturn)); +static void clean_child_exit(int code, int worker_num, apr_pool_t *ptrans, + apr_bucket_alloc_t *bucket_alloc) +{ + apr_bucket_alloc_destroy(bucket_alloc); + if (!shutdown_pending) { + apr_pool_destroy(ptrans); + } + + atomic_dec (&worker_thread_count); + if (worker_num >=0) + ap_update_child_status_from_indexes(0, worker_num, WORKER_DEAD, + (request_rec *) NULL); + NXThreadExit((void*)&code); +} + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = 1; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_NOT_SUPPORTED; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = HARD_SERVER_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = HARD_THREAD_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_limit; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = ap_threads_min_free; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = ap_threads_max_free; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = 1; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + + +/***************************************************************** + * Connection structures and accounting... + */ + +static void mpm_term(void) +{ + RemoveConsoleHandler(); + wait_to_finish = 0; + NXThreadYield(); +} + +static void sig_term(int sig) +{ + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; + + DBPRINT0 ("waiting for threads\n"); + while (wait_to_finish) { + apr_thread_yield(); + } + DBPRINT0 ("goodbye\n"); +} + +/* restart() is the signal handler for SIGHUP and SIGWINCH + * in the parent process, unless running in ONE_PROCESS mode + */ +static void restart(void) +{ + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = 1; +} + +static void set_signals(void) +{ + apr_signal(SIGTERM, sig_term); + apr_signal(SIGABRT, sig_term); +} + +int nlmUnloadSignaled(int wait) +{ + shutdown_pending = 1; + + if (wait) { + while (wait_to_finish) { + NXThreadYield(); + } + } + + return 0; +} + +/***************************************************************** + * Child process main loop. + * The following vars are static to avoid getting clobbered by longjmp(); + * they are really private to child_main. + */ + + +int ap_graceful_stop_signalled(void) +{ + /* not ever called anymore... */ + return 0; +} + +#define MAX_WB_RETRIES 3 +#ifdef DBINFO_ON +static int would_block = 0; +static int retry_success = 0; +static int retry_fail = 0; +static int avg_retries = 0; +#endif + +/*static */ +void worker_main(void *arg) +{ + ap_listen_rec *lr, *first_lr, *last_lr = NULL; + apr_pool_t *ptrans; + apr_pool_t *pbucket; + apr_allocator_t *allocator; + apr_bucket_alloc_t *bucket_alloc; + conn_rec *current_conn; + apr_status_t stat = APR_EINIT; + ap_sb_handle_t *sbh; + + int my_worker_num = (int)arg; + apr_socket_t *csd = NULL; + int requests_this_child = 0; + apr_socket_t *sd = NULL; + fd_set main_fds; + + int sockdes; + int srv; + struct timeval tv; + int wouldblock_retry; + + tv.tv_sec = 1; + tv.tv_usec = 0; + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + + apr_pool_create_ex(&ptrans, pmain, NULL, allocator); + apr_allocator_owner_set(allocator, ptrans); + apr_pool_tag(ptrans, "transaction"); + + bucket_alloc = apr_bucket_alloc_create_ex(allocator); + + atomic_inc (&worker_thread_count); + + while (!die_now) { + /* + * (Re)initialize this child to a pre-connection state. + */ + current_conn = NULL; + apr_pool_clear(ptrans); + + if ((ap_max_requests_per_child > 0 + && requests_this_child++ >= ap_max_requests_per_child)) { + DBPRINT1 ("\n**Thread slot %d is shutting down", my_worker_num); + clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); + } + + ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY, + (request_rec *) NULL); + + /* + * Wait for an acceptable connection to arrive. + */ + + for (;;) { + if (shutdown_pending || restart_pending || (ap_scoreboard_image->servers[0][my_worker_num].status == WORKER_IDLE_KILL)) { + DBPRINT1 ("\nThread slot %d is shutting down\n", my_worker_num); + clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); + } + + /* Check the listen queue on all sockets for requests */ + memcpy(&main_fds, &listenfds, sizeof(fd_set)); + srv = select(listenmaxfd + 1, &main_fds, NULL, NULL, &tv); + + if (srv <= 0) { + if (srv < 0) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "select() failed on listen socket"); + apr_thread_yield(); + } + continue; + } + + /* remember the last_lr we searched last time around so that + we don't end up starving any particular listening socket */ + if (last_lr == NULL) { + lr = ap_listeners; + } + else { + lr = last_lr->next; + if (!lr) + lr = ap_listeners; + } + first_lr = lr; + do { + apr_os_sock_get(&sockdes, lr->sd); + if (FD_ISSET(sockdes, &main_fds)) + goto got_listener; + lr = lr->next; + if (!lr) + lr = ap_listeners; + } while (lr != first_lr); + /* if we get here, something unexpected happened. Go back + into the select state and try again. + */ + continue; + got_listener: + last_lr = lr; + sd = lr->sd; + + wouldblock_retry = MAX_WB_RETRIES; + + while (wouldblock_retry) { + if ((stat = apr_socket_accept(&csd, sd, ptrans)) == APR_SUCCESS) { + break; + } + else { + /* if the error is a wouldblock then maybe we were too + quick try to pull the next request from the listen + queue. Try a few more times then return to our idle + listen state. */ + if (!APR_STATUS_IS_EAGAIN(stat)) { + break; + } + + if (wouldblock_retry--) { + apr_thread_yield(); + } + } + } + + /* If we got a new socket, set it to non-blocking mode and process + it. Otherwise handle the error. */ + if (stat == APR_SUCCESS) { + apr_socket_opt_set(csd, APR_SO_NONBLOCK, 0); +#ifdef DBINFO_ON + if (wouldblock_retry < MAX_WB_RETRIES) { + retry_success++; + avg_retries += (MAX_WB_RETRIES-wouldblock_retry); + } +#endif + break; /* We have a socket ready for reading */ + } + else { +#ifdef DBINFO_ON + if (APR_STATUS_IS_EAGAIN(stat)) { + would_block++; + retry_fail++; + } + else if ( +#else + if (APR_STATUS_IS_EAGAIN(stat) || +#endif + APR_STATUS_IS_ECONNRESET(stat) || + APR_STATUS_IS_ETIMEDOUT(stat) || + APR_STATUS_IS_EHOSTUNREACH(stat) || + APR_STATUS_IS_ENETUNREACH(stat)) { + ; + } +#ifdef USE_WINSOCK + else if (APR_STATUS_IS_ENETDOWN(stat)) { + /* + * When the network layer has been shut down, there + * is not much use in simply exiting: the parent + * would simply re-create us (and we'd fail again). + * Use the CHILDFATAL code to tear the server down. + * @@@ Martin's idea for possible improvement: + * A different approach would be to define + * a new APEXIT_NETDOWN exit code, the reception + * of which would make the parent shutdown all + * children, then idle-loop until it detected that + * the network is up again, and restart the children. + * Ben Hyde noted that temporary ENETDOWN situations + * occur in mobile IP. + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf, + "apr_socket_accept: giving up."); + clean_child_exit(APEXIT_CHILDFATAL, my_worker_num, ptrans, + bucket_alloc); + } +#endif + else { + ap_log_error(APLOG_MARK, APLOG_ERR, stat, ap_server_conf, + "apr_socket_accept: (client socket)"); + clean_child_exit(1, my_worker_num, ptrans, bucket_alloc); + } + } + } + + ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num); + /* + * We now have a connection, so set it up with the appropriate + * socket options, file descriptors, and read/write buffers. + */ + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, + my_worker_num, sbh, + bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, csd); + ap_lingering_close(current_conn); + } + request_count++; + } + clean_child_exit(0, my_worker_num, ptrans, bucket_alloc); +} + + +static int make_child(server_rec *s, int slot) +{ + int tid; + int err=0; + NXContext_t ctx; + + if (slot + 1 > ap_max_workers_limit) { + ap_max_workers_limit = slot + 1; + } + + ap_update_child_status_from_indexes(0, slot, WORKER_STARTING, + (request_rec *) NULL); + + if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stacksize, NX_CTX_NORMAL, &err)) { + char threadName[32]; + + sprintf (threadName, "Apache_Worker %d", slot); + NXContextSetName(ctx, threadName); + err = NXThreadCreate(ctx, NX_THR_BIND_CONTEXT, &tid); + if (err) { + NXContextFree (ctx); + } + } + + if (err) { + /* create thread didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + ap_update_child_status_from_indexes(0, slot, WORKER_DEAD, + (request_rec *) NULL); + + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again. */ + apr_thread_yield(); + + return -1; + } + + ap_scoreboard_image->servers[0][slot].tid = tid; + + return 0; +} + + +/* start up a bunch of worker threads */ +static void startup_workers(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_threads_limit; ++i) { + if (ap_scoreboard_image->servers[0][i].status != WORKER_DEAD) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (64) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(apr_pool_t *p) +{ + int i; + int to_kill; + int idle_count; + worker_score *ws; + int free_length; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + + /* initialize the free_list */ + free_length = 0; + + to_kill = -1; + idle_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_threads_limit; ++i) { + int status; + + if (i >= ap_max_workers_limit && free_length == idle_spawn_rate) + break; + ws = &ap_scoreboard_image->servers[0][i]; + status = ws->status; + if (status == WORKER_DEAD) { + /* try to keep children numbers as low as possible */ + if (free_length < idle_spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } + } + else if (status == WORKER_IDLE_KILL) { + /* If it is already marked to die, skip it */ + continue; + } + else { + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (status <= WORKER_READY) { + ++ idle_count; + /* always kill the highest numbered child if we have to... + * no really well thought out reason ... other than observing + * the server behaviour under linux where lower numbered children + * tend to service more hits (and hence are more likely to have + * their data in cpu caches). + */ + to_kill = i; + } + + ++total_non_dead; + last_non_dead = i; + } + } + DBPRINT2("Total: %d Idle Count: %d \r", total_non_dead, idle_count); + ap_max_workers_limit = last_non_dead + 1; + if (idle_count > ap_threads_max_free) { + /* kill off one child... we use the pod because that'll cause it to + * shut down gracefully, in case it happened to pick up a request + * while we were counting + */ + idle_spawn_rate = 1; + ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL, + (request_rec *) NULL); + DBPRINT1("\nKilling idle thread: %d\n", last_non_dead); + } + else if (idle_count < ap_threads_min_free) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, or Min/MaxSpareServers), " + "spawning %d children, there are %d idle, and " + "%d total children", idle_spawn_rate, + idle_count, total_non_dead); + } + DBPRINT0("\n"); + for (i = 0; i < free_length; ++i) { + DBPRINT1("Spawning additional thread slot: %d\n", free_slots[i]); + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +static void display_settings () +{ + int status_array[SERVER_NUM_STATUS]; + int i, status, total=0; + int reqs = request_count; +#ifdef DBINFO_ON + int wblock = would_block; + + would_block = 0; +#endif + + request_count = 0; + + ClearScreen (getscreenhandle()); + printf("%s \n", ap_get_server_version()); + + for (i=0;iservers[0][i]).status; + status_array[status]++; + } + + for (i=0;ibind_addr->port); + lr = lr->next; + } while(lr && lr != ap_listeners); + + /* Display dynamic modules loaded */ + printf("\n"); + for (m = ap_loaded_modules; *m != NULL; m++) { + if (((module*)*m)->dynamic_load_handle) { + printf(" Loaded dynamic module %s\n", ((module*)*m)->name); + } + } +} + + +static int setup_listeners(server_rec *s) +{ + ap_listen_rec *lr; + int sockdes; + + if (ap_setup_listeners(s) < 1 ) { + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s, + "no listening sockets available, shutting down"); + return -1; + } + + listenmaxfd = -1; + FD_ZERO(&listenfds); + for (lr = ap_listeners; lr; lr = lr->next) { + apr_os_sock_get(&sockdes, lr->sd); + FD_SET(sockdes, &listenfds); + if (sockdes > listenmaxfd) { + listenmaxfd = sockdes; + } + } + return 0; +} + +static int shutdown_listeners() +{ + ap_listen_rec *lr; + + for (lr = ap_listeners; lr; lr = lr->next) { + apr_socket_close(lr->sd); + } + ap_listeners = NULL; + return 0; +} + +/***************************************************************** + * Executive routines. + */ + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + apr_status_t status=0; + + pconf = _pconf; + ap_server_conf = s; + + if (setup_listeners(s)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, status, s, + "no listening sockets available, shutting down"); + return -1; + } + + restart_pending = shutdown_pending = 0; + worker_thread_count = 0; + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_NOT_SHARED) != OK) { + return 1; + } + } + + /* Only set slot 0 since that is all NetWare will ever have. */ + ap_scoreboard_image->parent[0].pid = getpid(); + + set_signals(); + + apr_pool_create(&pmain, pconf); + ap_run_child_init(pmain, ap_server_conf); + + if (ap_threads_max_free < ap_threads_min_free + 1) /* Don't thrash... */ + ap_threads_max_free = ap_threads_min_free + 1; + request_count = 0; + + startup_workers(ap_threads_to_start); + + /* Allow the Apache screen to be closed normally on exit() only if it + has not been explicitly forced to close on exit(). (ie. the -E flag + was specified at startup) */ + if (hold_screen_on_exit > 0) { + hold_screen_on_exit = 0; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + show_server_data(); + + mpm_state = AP_MPMQ_RUNNING; + while (!restart_pending && !shutdown_pending) { + perform_idle_server_maintenance(pconf); + if (show_settings) + display_settings(); + apr_thread_yield(); + apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); + } + mpm_state = AP_MPMQ_STOPPING; + + + /* Shutdown the listen sockets so that we don't get stuck in a blocking call. + shutdown_listeners();*/ + + if (shutdown_pending) { /* Got an unload from the console */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught SIGTERM, shutting down"); + + while (worker_thread_count > 0) { + printf ("\rShutdown pending. Waiting for %d thread(s) to terminate...", + worker_thread_count); + apr_thread_yield(); + } + + return 1; + } + else { /* the only other way out is a restart */ + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Graceful restart requested, doing restart"); + + /* Wait for all of the threads to terminate before initiating the restart */ + while (worker_thread_count > 0) { + printf ("\rRestart pending. Waiting for %d thread(s) to terminate...", + worker_thread_count); + apr_thread_yield(); + } + printf ("\nRestarting...\n"); + } + + return 0; +} + +static int netware_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + int debug; + char *addrname = NULL; + + mpm_state = AP_MPMQ_STARTING; + + debug = ap_exists_config_define("DEBUG"); + + is_graceful = 0; + ap_my_pid = getpid(); + addrname = getaddressspacename (NULL, NULL); + if (addrname) { + ap_my_addrspace = apr_pstrdup (p, addrname); + free (addrname); + } + +#ifndef USE_WINSOCK + /* The following call has been moved to the mod_nw_ssl pre-config handler */ + ap_listen_pre_config(); +#endif + + ap_threads_to_start = DEFAULT_START_THREADS; + ap_threads_min_free = DEFAULT_MIN_FREE_THREADS; + ap_threads_max_free = DEFAULT_MAX_FREE_THREADS; + ap_threads_limit = HARD_THREAD_LIMIT; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; + ap_thread_stacksize = DEFAULT_THREAD_STACKSIZE; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + return OK; +} + +static void netware_mpm_hooks(apr_pool_t *p) +{ + ap_hook_pre_config(netware_pre_config, NULL, NULL, APR_HOOK_MIDDLE); +} + +void netware_rewrite_args(process_rec *process) +{ + char *def_server_root; + char optbuf[3]; + const char *opt_arg; + apr_getopt_t *opt; + apr_array_header_t *mpm_new_argv; + + + atexit (mpm_term); + InstallConsoleHandler(); + + /* Make sure to hold the Apache screen open if exit() is called */ + hold_screen_on_exit = 1; + + /* Rewrite process->argv[]; + * + * add default -d serverroot from the path of this executable + * + * The end result will look like: + * The -d serverroot default from the running executable + */ + if (process->argc > 0) { + char *s = apr_pstrdup (process->pconf, process->argv[0]); + if (s) { + int i, len = strlen(s); + + for (i=len; i; i--) { + if (s[i] == '\\' || s[i] == '/') { + s[i] = '\0'; + apr_filepath_merge(&def_server_root, NULL, s, + APR_FILEPATH_TRUENAME, process->pool); + break; + } + } + /* Use process->pool so that the rewritten argv + * lasts for the lifetime of the server process, + * because pconf will be destroyed after the + * initial pre-flight of the config parser. + */ + mpm_new_argv = apr_array_make(process->pool, process->argc + 2, + sizeof(const char *)); + *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; + *(const char **)apr_array_push(mpm_new_argv) = "-d"; + *(const char **)apr_array_push(mpm_new_argv) = def_server_root; + + optbuf[0] = '-'; + optbuf[2] = '\0'; + apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv); + while (apr_getopt(opt, AP_SERVER_BASEARGS"n:", optbuf + 1, &opt_arg) == APR_SUCCESS) { + switch (optbuf[1]) { + case 'n': + if (opt_arg) { + renamescreen(opt_arg); + } + break; + case 'E': + /* Don't need to hold the screen open if the output is going to a file */ + hold_screen_on_exit = -1; + default: + *(const char **)apr_array_push(mpm_new_argv) = + apr_pstrdup(process->pool, optbuf); + + if (opt_arg) { + *(const char **)apr_array_push(mpm_new_argv) = opt_arg; + } + break; + } + } + process->argc = mpm_new_argv->nelts; + process->argv = (const char * const *) mpm_new_argv->elts; + } + } +} + +static int CommandLineInterpreter(scr_t screenID, const char *commandLine) +{ + char *szCommand = "APACHE2 "; + int iCommandLen = 8; + char szcommandLine[256]; + char *pID; + screenID = screenID; + + + if (commandLine == NULL) + return NOTMYCOMMAND; + if (strlen(commandLine) <= strlen(szCommand)) + return NOTMYCOMMAND; + + strncpy (szcommandLine, commandLine, sizeof(szcommandLine)-1); + + /* All added commands begin with "APACHE2 " */ + + if (!strnicmp(szCommand, szcommandLine, iCommandLen)) { + ActivateScreen (getscreenhandle()); + + /* If an instance id was not given but the nlm is loaded in + protected space, then the the command belongs to the + OS address space instance to pass it on. */ + pID = strstr (szcommandLine, "-p"); + if ((pID == NULL) && nlmisloadedprotected()) + return NOTMYCOMMAND; + + /* If we got an instance id but it doesn't match this + instance of the nlm, pass it on. */ + if (pID) { + pID = &pID[2]; + while (*pID && (*pID == ' ')) + pID++; + } + if (pID && ap_my_addrspace && strnicmp(pID, ap_my_addrspace, strlen(ap_my_addrspace))) + return NOTMYCOMMAND; + + /* If we have determined that this command belongs to this + instance of the nlm, then handle it. */ + if (!strnicmp("RESTART",&szcommandLine[iCommandLen],3)) { + printf("Restart Requested...\n"); + restart(); + } + else if (!strnicmp("VERSION",&szcommandLine[iCommandLen],3)) { + printf("Server version: %s\n", ap_get_server_version()); + printf("Server built: %s\n", ap_get_server_built()); + } + else if (!strnicmp("MODULES",&szcommandLine[iCommandLen],3)) { + ap_show_modules(); + } + else if (!strnicmp("DIRECTIVES",&szcommandLine[iCommandLen],3)) { + ap_show_directives(); + } + else if (!strnicmp("SHUTDOWN",&szcommandLine[iCommandLen],3)) { + printf("Shutdown Requested...\n"); + shutdown_pending = 1; + } + else if (!strnicmp("SETTINGS",&szcommandLine[iCommandLen],3)) { + if (show_settings) { + show_settings = 0; + ClearScreen (getscreenhandle()); + show_server_data(); + } + else { + show_settings = 1; + display_settings(); + } + } + else { + show_settings = 0; + if (strnicmp("HELP",&szcommandLine[iCommandLen],3)) + printf("Unknown APACHE2 command %s\n", &szcommandLine[iCommandLen]); + printf("Usage: APACHE2 [command] [-p ]\n"); + printf("Commands:\n"); + printf("\tDIRECTIVES - Show directives\n"); + printf("\tHELP - Display this help information\n"); + printf("\tMODULES - Show a list of the loaded modules\n"); + printf("\tRESTART - Reread the configuration file and restart Apache\n"); + printf("\tSETTINGS - Show current thread status\n"); + printf("\tSHUTDOWN - Shutdown Apache\n"); + printf("\tVERSION - Display the server version information\n"); + } + + /* Tell NetWare we handled the command */ + return HANDLEDCOMMAND; + } + + /* Tell NetWare that the command isn't mine */ + return NOTMYCOMMAND; +} + +static int InstallConsoleHandler(void) +{ + /* Our command line handler interfaces the system operator + with this NLM */ + + NX_WRAP_INTERFACE(CommandLineInterpreter, 2, (void*)&(ConsoleHandler.parser)); + + ConsoleHandler.rTag = AllocateResourceTag(getnlmhandle(), "Command Line Processor", + ConsoleCommandSignature); + if (!ConsoleHandler.rTag) + { + printf("Error on allocate resource tag\n"); + return 1; + } + + RegisterConsoleCommand(&ConsoleHandler); + + /* The Remove procedure unregisters the console handler */ + + return 0; +} + +static void RemoveConsoleHandler(void) +{ + UnRegisterConsoleCommand(&ConsoleHandler); + NX_UNWRAP_INTERFACE(ConsoleHandler.parser); +} + +static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_free_threads(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_min_free = atoi(arg); + if (ap_threads_min_free <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareServers set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + ap_threads_min_free = 1; + } + + return NULL; +} + +static const char *set_max_free_threads(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_max_free = atoi(arg); + return NULL; +} + +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_limit = atoi(arg); + if (ap_threads_limit > HARD_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxThreads of %d exceeds compile time limit " + "of %d threads,", ap_threads_limit, HARD_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering MaxThreads to %d. To increase, please " + "see the", HARD_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " HARD_THREAD_LIMIT define in %s.", + AP_MPM_HARD_LIMITS_FILE); + ap_threads_limit = HARD_THREAD_LIMIT; + } + else if (ap_threads_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxThreads > 0, setting to 1"); + ap_threads_limit = 1; + } + return NULL; +} + +static const command_rec netware_mpm_cmds[] = { +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF, + "Number of worker threads launched at server startup"), +AP_INIT_TAKE1("MinSpareThreads", set_min_free_threads, NULL, RSRC_CONF, + "Minimum number of idle threads, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_free_threads, NULL, RSRC_CONF, + "Maximum number of idle threads"), +AP_INIT_TAKE1("MaxThreads", set_thread_limit, NULL, RSRC_CONF, + "Maximum number of worker threads alive at the same time"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_netware_module = { + MPM20_MODULE_STUFF, + netware_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + netware_mpm_cmds, /* command apr_table_t */ + netware_mpm_hooks, /* register hooks */ +}; diff --git a/trunk/server/mpm/prefork/Makefile.in b/trunk/server/mpm/prefork/Makefile.in new file mode 100644 index 0000000000..034bf5ce84 --- /dev/null +++ b/trunk/server/mpm/prefork/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libprefork.la +LTLIBRARY_SOURCES = prefork.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/prefork/config.m4 b/trunk/server/mpm/prefork/config.m4 new file mode 100644 index 0000000000..9c189a8642 --- /dev/null +++ b/trunk/server/mpm/prefork/config.m4 @@ -0,0 +1,3 @@ +if test "$MPM_NAME" = "prefork" ; then + APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) +fi diff --git a/trunk/server/mpm/prefork/mpm.h b/trunk/server/mpm/prefork/mpm.h new file mode 100644 index 0000000000..811703b160 --- /dev/null +++ b/trunk/server/mpm/prefork/mpm.h @@ -0,0 +1,51 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "httpd.h" +#include "mpm_default.h" +#include "scoreboard.h" +#include "unixd.h" + +#ifndef APACHE_MPM_PREFORK_H +#define APACHE_MPM_PREFORK_H + +#define PREFORK_MPM + +#define MPM_NAME "Prefork" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + +#define AP_MPM_USES_POD 1 +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; +#endif /* APACHE_MPM_PREFORK_H */ diff --git a/trunk/server/mpm/prefork/mpm_default.h b/trunk/server/mpm/prefork/mpm_default.h new file mode 100644 index 0000000000..46cd2018d4 --- /dev/null +++ b/trunk/server/mpm/prefork/mpm_default.h @@ -0,0 +1,65 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 5 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 5 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/prefork/prefork.c b/trunk/server/mpm/prefork/prefork.c new file mode 100644 index 0000000000..0afe6f0bdd --- /dev/null +++ b/trunk/server/mpm/prefork/prefork.c @@ -0,0 +1,1377 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_TYPES_H +#include +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "mpm_default.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "scoreboard.h" +#include "ap_mpm.h" +#include "unixd.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "ap_mmn.h" +#include "apr_poll.h" + +#ifdef HAVE_BSTRING_H +#include /* for IRIX, FD_SET calls bzero() */ +#endif +#ifdef HAVE_TIME_H +#include +#endif +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +#include +#include + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 256 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 200000 +#endif + +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 1 +#endif + +/* config globals */ + +int ap_threads_per_child=0; /* Worker threads per child */ +static apr_proc_mutex_t *accept_mutex; +static int ap_daemons_to_start=0; +static int ap_daemons_min_free=0; +static int ap_daemons_max_free=0; +static int ap_daemons_limit=0; /* MaxClients */ +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int changed_limit_at_restart; +static int mpm_state = AP_MPMQ_STARTING; +static ap_pod_t *pod; + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire scoreboard. + */ +int ap_max_daemons_limit = -1; +server_rec *ap_server_conf; + +/* one_process --- debugging mode variable; can be set from the command line + * with the -X flag. If set, this gets you the child_main loop running + * in the process which originally started up (no detach, no make_child), + * which is a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ +static pid_t parent_pid; +#ifndef MULTITHREAD +static int my_child_num; +#endif +ap_generation_t volatile ap_my_generation=0; + +#ifdef TPF +int tpf_child = 0; +char tpf_server_name[INETD_SERVNAME_LENGTH+1]; +#endif /* TPF */ + +static int die_now = 0; + +#ifdef GPROF +/* + * change directory for gprof to plop the gmon.out file + * configure in httpd.conf: + * GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out + * GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out + */ +static void chdir_for_gprof(void) +{ + core_server_config *sconf = + ap_get_module_config(ap_server_conf->module_config, &core_module); + char *dir = sconf->gprof_dir; + const char *use_dir; + + if(dir) { + apr_status_t res; + char buf[512]; + int len = strlen(sconf->gprof_dir) - 1; + if(*(dir + len) == '%') { + dir[len] = '\0'; + apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid()); + } + else { + buf[0] = '\0'; + } + use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir); + res = apr_dir_make(use_dir, + APR_UREAD | APR_UWRITE | APR_UEXECUTE | + APR_GREAD | APR_GEXECUTE | + APR_WREAD | APR_WEXECUTE, pconf); + if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) { + ap_log_error(APLOG_MARK, APLOG_ERR, res, ap_server_conf, + "gprof: error creating directory %s", dir); + } + } + else { + use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR); + } + + chdir(use_dir); +} +#else +#define chdir_for_gprof() +#endif + +/* XXX - I don't know if TPF will ever use this module or not, so leave + * the ap_check_signals calls in but disable them - manoj */ +#define ap_check_signals() + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + mpm_state = AP_MPMQ_STOPPING; + + if (pchild) { + apr_pool_destroy(pchild); + } + ap_mpm_pod_close(pod); + chdir_for_gprof(); + exit(code); +} + +static void accept_mutex_on(void) +{ + apr_status_t rv = apr_proc_mutex_lock(accept_mutex); + if (rv != APR_SUCCESS) { + const char *msg = "couldn't grab the accept mutex"; + + if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg); + clean_child_exit(0); + } + else { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg); + exit(APEXIT_CHILDFATAL); + } + } +} + +static void accept_mutex_off(void) +{ + apr_status_t rv = apr_proc_mutex_unlock(accept_mutex); + if (rv != APR_SUCCESS) { + const char *msg = "couldn't release the accept mutex"; + + if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg); + /* don't exit here... we have a connection to + * process, after which point we'll see that the + * generation changed and we'll exit cleanly + */ + } + else { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg); + exit(APEXIT_CHILDFATAL); + } + } +} + +/* On some architectures it's safe to do unserialized accept()s in the single + * Listen case. But it's never safe to do it in the case where there's + * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT + * when it's safe in the single Listen case. + */ +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT +#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0) +#else +#define SAFE_ACCEPT(stmt) do {stmt;} while(0) +#endif + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_NOT_SUPPORTED; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = HARD_THREAD_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = ap_daemons_min_free; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = ap_daemons_max_free; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +#if defined(NEED_WAITPID) +/* + Systems without a real waitpid sometimes lose a child's exit while waiting + for another. Search through the scoreboard for missing children. + */ +int reap_children(int *exitcode, apr_exit_why_e *status) +{ + int n, pid; + + for (n = 0; n < ap_max_daemons_limit; ++n) { + if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && + kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { + ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); + /* just mark it as having a successful exit status */ + *status = APR_PROC_EXIT; + *exitcode = 0; + return(pid); + } + } + return 0; +} +#endif + +/***************************************************************** + * Connection structures and accounting... + */ + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; + +static void sig_term(int sig) +{ + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL + * in the parent process, unless running in ONE_PROCESS mode + */ +static void restart(int sig) +{ + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = (sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one + */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Child process main loop. + * The following vars are static to avoid getting clobbered by longjmp(); + * they are really private to child_main. + */ + +static int requests_this_child; +static int num_listensocks = 0; + + +int ap_graceful_stop_signalled(void) +{ + /* not ever called anymore... */ + return 0; +} + + +static void child_main(int child_num_arg) +{ + apr_pool_t *ptrans; + apr_allocator_t *allocator; + apr_status_t status; + int i; + ap_listen_rec *lr; + apr_pollset_t *pollset; + ap_sb_handle_t *sbh; + apr_bucket_alloc_t *bucket_alloc; + int last_poll_idx = 0; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + + my_child_num = child_num_arg; + ap_my_pid = getpid(); + requests_this_child = 0; + + ap_fatal_signal_child_setup(ap_server_conf); + + /* Get a sub context for global allocations in this child, so that + * we can have cleanups occur when the child exits. + */ + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&pchild, pconf, NULL, allocator); + apr_allocator_owner_set(allocator, pchild); + + apr_pool_create(&ptrans, pchild); + apr_pool_tag(ptrans, "transaction"); + + /* needs to be done before we switch UIDs so we have permissions */ + ap_reopen_scoreboard(pchild, NULL, 0); + status = apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "Couldn't initialize cross-process lock in child " + "(%s) (%d)", ap_lock_fname, ap_accept_lock_mech); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (unixd_setup_child()) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + ap_create_sb_handle(&sbh, pchild, my_child_num, 0); + + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + /* Set up the pollfd array */ + /* ### check the status */ + (void) apr_pollset_create(&pollset, num_listensocks, pchild, 0); + + for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + /* ### check the status */ + (void) apr_pollset_add(pollset, &pfd); + } + + mpm_state = AP_MPMQ_RUNNING; + + bucket_alloc = apr_bucket_alloc_create(pchild); + + while (!die_now) { + conn_rec *current_conn; + void *csd; + + /* + * (Re)initialize this child to a pre-connection state. + */ + + apr_pool_clear(ptrans); + + if ((ap_max_requests_per_child > 0 + && requests_this_child++ >= ap_max_requests_per_child)) { + clean_child_exit(0); + } + + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + /* + * Wait for an acceptable connection to arrive. + */ + + /* Lock around "accept", if necessary */ + SAFE_ACCEPT(accept_mutex_on()); + + if (num_listensocks == 1) { + /* There is only one listener record, so refer to that one. */ + lr = ap_listeners; + } + else { + /* multiple listening sockets - need to poll */ + for (;;) { + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + + /* timeout == -1 == wait forever */ + status = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (status != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(status)) { + if (one_process && shutdown_pending) { + return; + } + continue; + } + /* Single Unix documents select as returning errnos + * EBADF, EINTR, and EINVAL... and in none of those + * cases does it make sense to continue. In fact + * on Linux 2.0.x we seem to end up with EFAULT + * occasionally, and we'd loop forever due to it. + */ + ap_log_error(APLOG_MARK, APLOG_ERR, status, + ap_server_conf, "apr_pollset_poll: (listen)"); + clean_child_exit(1); + } + + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + lr = pdesc[last_poll_idx++].client_data; + goto got_fd; + } + } + got_fd: + /* if we accept() something we don't want to die, so we have to + * defer the exit + */ + status = lr->accept_func(&csd, lr, ptrans); + + SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ + + if (status == APR_EGENERAL) { + /* resource shortage or should-not-occur occured */ + clean_child_exit(1); + } + else if (status != APR_SUCCESS) { + continue; + } + + /* + * We now have a connection, so set it up with the appropriate + * socket options, file descriptors, and read/write buffers. + */ + + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, csd); + ap_lingering_close(current_conn); + } + + /* Check the pod and the generation number after processing a + * connection so that we'll go away if a graceful restart occurred + * while we were processing the connection or we are the lucky + * idle server process that gets to die. + */ + if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */ + die_now = 1; + } + else if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { /* restart? */ + /* yeah, this could be non-graceful restart, in which case the + * parent will kill us soon enough, but why bother checking? + */ + die_now = 1; + } + } + clean_child_exit(0); +} + + +static int make_child(server_rec *s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + apr_signal(SIGHUP, sig_term); + /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */ + apr_signal(SIGINT, sig_term); +#ifdef SIGQUIT + apr_signal(SIGQUIT, SIG_DFL); +#endif + apr_signal(SIGTERM, sig_term); + child_main(slot); + return 0; + } + + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, + (request_rec *) NULL); + + +#ifdef _OSD_POSIX + /* BS2000 requires a "special" version of fork() before a setuid() call */ + if ((pid = os_fork(unixd_config.user_name)) == -1) { +#elif defined(TPF) + if ((pid = os_fork(s, slot)) == -1) { +#else + if ((pid = fork()) == -1) { +#endif + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, + (request_rec *) NULL); + + /* In case system resources are maxxed out, we don't want + * Apache running away with the CPU trying to fork over and + * over and over again. + */ + sleep(10); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* by default AIX binds to a single processor + * this bit unbinds children which will then bind to another cpu + */ + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, "processor unbind failed %d", status); + } +#endif + RAISE_SIGSTOP(MAKE_CHILD); + AP_MONCONTROL(1); + /* Disable the parent's signal handlers and set up proper handling in + * the child. + */ + apr_signal(SIGHUP, just_die); + apr_signal(SIGTERM, just_die); + /* The child process doesn't do anything for AP_SIG_GRACEFUL. + * Instead, the pod is used for signalling graceful restart. + */ + apr_signal(AP_SIG_GRACEFUL, SIG_IGN); + child_main(slot); + } + + ap_scoreboard_image->parent[slot].pid = pid; + + return 0; +} + + +/* start up a bunch of children */ +static void startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { + if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(apr_pool_t *p) +{ + int i; + int to_kill; + int idle_count; + worker_score *ws; + int free_length; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + + /* initialize the free_list */ + free_length = 0; + + to_kill = -1; + idle_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_daemons_limit; ++i) { + int status; + + if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) + break; + ws = &ap_scoreboard_image->servers[i][0]; + status = ws->status; + if (status == SERVER_DEAD) { + /* try to keep children numbers as low as possible */ + if (free_length < idle_spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } + } + else { + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (status <= SERVER_READY) { + ++ idle_count; + /* always kill the highest numbered child if we have to... + * no really well thought out reason ... other than observing + * the server behaviour under linux where lower numbered children + * tend to service more hits (and hence are more likely to have + * their data in cpu caches). + */ + to_kill = i; + } + + ++total_non_dead; + last_non_dead = i; + } + } + ap_max_daemons_limit = last_non_dead + 1; + if (idle_count > ap_daemons_max_free) { + /* kill off one child... we use the pod because that'll cause it to + * shut down gracefully, in case it happened to pick up a request + * while we were counting + */ + ap_mpm_pod_signal(pod); + idle_spawn_rate = 1; + } + else if (idle_count < ap_daemons_min_free) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, or Min/MaxSpareServers), " + "spawning %d children, there are %d idle, and " + "%d total children", idle_spawn_rate, + idle_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { +#ifdef TPF + if (make_child(ap_server_conf, free_slots[i]) == -1) { + if(free_length == 1) { + shutdown_pending = 1; + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, ap_server_conf, + "No active child processes: shutting down"); + } + } +#else + make_child(ap_server_conf, free_slots[i]); +#endif /* TPF */ + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +/***************************************************************** + * Executive routines. + */ + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int index; + int remaining_children_to_start; + apr_status_t rv; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + /* Initialize cross-process accept lock */ + ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, + ap_server_root_relative(_pconf, ap_lock_fname), + ap_my_pid); + + rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, + ap_accept_lock_mech, _pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create accept lock (%s) (%d)", + ap_lock_fname, ap_accept_lock_mech); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_proc_mutex_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock; " + "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + + set_signals(); + + if (one_process) { + AP_MONCONTROL(1); + make_child(ap_server_conf, 0); + } + else { + if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */ + ap_daemons_max_free = ap_daemons_min_free + 1; + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty + * rapidly... and for each one that exits we'll start a new one until + * we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = ap_daemons_to_start; + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } + if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } + else { + /* give the system some time to recover before kicking into + * exponential mode + */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + + mpm_state = AP_MPMQ_RUNNING; + + while (!restart_pending && !shutdown_pending) { + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; + /* this is a memory leak, but I'll fix it later. */ + apr_proc_t pid; + + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + /* XXX: if it takes longer than 1 second for all our children + * to start up and get into IDLE state then we may spawn an + * extra child + */ + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD, + (request_rec *) NULL); + if (processed_status == APEXIT_CHILDSICK) { + /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) + * cut the fork rate to the minimum + */ + idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, status) == APR_SUCCESS) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this + * child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, ap_server_conf, + "long lost child came home! (pid %ld)", (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_idle_server_maintenance(pconf); +#ifdef TPF + shutdown_pending = os_check_server(tpf_server_name); + ap_check_signals(); + sleep(1); +#endif /*TPF */ + } + } /* one_process */ + + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + */ + if (unixd_killpg(getpgrp(), SIGTERM) < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); + } + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + /* cleanup pid file on normal shutdown */ + { + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if ( pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, + 0, ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long)getpid()); + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught SIGTERM, shutting down"); + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + if (one_process) { + /* not worth thinking about */ + return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Graceful restart requested, doing restart"); + + /* kill off the idle ones */ + ap_mpm_pod_killpg(pod, ap_max_daemons_limit); + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. This will break + * in a very nasty way if we ever have the scoreboard totally + * file-based (no shared memory) + */ + for (index = 0; index < ap_daemons_limit; ++index) { + if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) { + ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL; + } + } + } + else { + /* Kill 'em off */ + if (unixd_killpg(getpgrp(), SIGHUP) < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP"); + } + ap_reclaim_child_processes(0); /* Not when just starting up */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + return OK; +} + +static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else + { + no_detach = ap_exists_config_define("NO_DETACH"); + one_process = ap_exists_config_define("ONE_PROCESS"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + parent_pid = ap_my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON; + ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON; + ap_daemons_limit = server_limit; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void prefork_hooks(apr_pool_t *p) +{ + /* The prefork open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + +#ifdef AUX3 + (void) set42sig(); +#endif + + ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_min_free = atoi(arg); + if (ap_daemons_min_free <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareServers set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + ap_daemons_min_free = 1; + } + + return NULL; +} + +static const char *set_max_free_servers(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_max_free = atoi(arg); + return NULL; +} + +static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_limit = atoi(arg); + if (ap_daemons_limit > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d exceeds ServerLimit value " + "of %d servers,", ap_daemons_limit, server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering MaxClients to %d. To increase, please " + "see the ServerLimit", server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " directive."); + ap_daemons_limit = server_limit; + } + else if (ap_daemons_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; + } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const command_rec prefork_cmds[] = { +UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), +AP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, + "Maximum number of idle children"), +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, + "Maximum number of children alive at the same time"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum value of MaxClients for this run of Apache"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_prefork_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + prefork_cmds, /* command apr_table_t */ + prefork_hooks, /* register hooks */ +}; diff --git a/trunk/server/mpm/winnt/Win9xConHook.c b/trunk/server/mpm/winnt/Win9xConHook.c new file mode 100644 index 0000000000..8a07801059 --- /dev/null +++ b/trunk/server/mpm/winnt/Win9xConHook.c @@ -0,0 +1,697 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +/* + * Win9xConHook.dll - a hook proc to clean up Win95/98 console behavior. + * + * It is well(?) documented by Microsoft that the Win9x HandlerRoutine + * hooked by the SetConsoleCtrlHandler never receives the CTRL_CLOSE_EVENT, + * CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT signals. + * + * It is possible to have a second window to monitor the WM_ENDSESSION + * message, but the close button still fails.. + * + * There is a 16bit polling method for the close window option, but this + * is CPU intensive and requires thunking. + * + * Attempts to subclass the 'tty' console fail, since that message thread + * is actually owned by the 16 bit winoldap.mod process, although the + * window reports it is owned by the process/thread of the console app. + * + * Win9xConHook is thunks the WM_CLOSE and WM_ENDSESSION messages, + * first through a window hook procedure in the winoldap context, into + * a subclass WndProc, and on to a second hidden monitor window in the + * console application's context that dispatches them to the console app's + * registered HandlerRoutine. + */ + +/* This debugging define turns on output to COM1, although you better init + * the port first (even using hyperterm). It's the only way to catch the + * goings on within system logoff/shutdown. + * #define DBG 1 + */ + +#include + +/* Variables used within any process context: + * hookwndmsg is a shared message to send Win9xConHook signals + * origwndprop is a wndprop atom to store the orig wndproc of the tty + * hookwndprop is a wndprop atom to store the hwnd of the hidden child + * is_service reminds us to unmark this process on the way out + */ +static UINT hookwndmsg = 0; +static LPCTSTR origwndprop; +static LPCTSTR hookwndprop; +static BOOL is_service = 0; +//static HMODULE hmodThis = NULL; + +/* Variables used within the tty processes' context: + * is_tty flags this process; -1 == unknown, 1 == if tty, 0 == if not + * hw_tty is the handle of the top level tty in this process context + * is_subclassed is toggled to assure DllMain removes the subclass on unload + * hmodLock is there to try and prevent this dll from being unloaded if the + * hook is removed while we are subclassed + */ +static int is_tty = -1; +static HWND hwtty = NULL; +static BOOL is_subclassed = 0; + +// This simply causes a gpfault the moment it tries to FreeLibrary within +// the subclass procedure ... not good. +//static HMODULE hmodLock = NULL; + +/* Variables used within the service or console app's context: + * hmodHook is the instance handle of this module for registering the hooks + * hhkGetMessage is the hook handle for catching Posted messages + * hhkGetMessage is the hook handle for catching Sent messages + * monitor_hwnd is the invisible window that handles our tty messages + * the tty_info strucure is used to pass args into the hidden window's thread + */ +static HMODULE hmodHook = NULL; +static HHOOK hhkGetMessage; +//static HHOOK hhkCallWndProc; +static HWND monitor_hwnd = NULL; + +typedef struct { + PHANDLER_ROUTINE phandler; + HINSTANCE instance; + HWND parent; + INT type; + LPCSTR name; +} tty_info; + +/* These are the GetWindowLong offsets for the hidden window's internal info + * gwltty_phandler is the address of the app's HandlerRoutine + * gwltty_ttywnd is the tty this hidden window will handle messages from + */ +#define gwltty_phandler 0 +#define gwltty_ttywnd 4 + +/* Forward declaration prototypes for internal functions + */ +static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd); +static LRESULT WINAPI RegisterWindows9xService(BOOL set_service); +static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam); +static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty); +static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam); +static int HookProc(int hc, HWND *hwnd, UINT *msg, + WPARAM *wParam, LPARAM *lParam); +#ifdef DBG +static VOID DbgPrintf(LPTSTR fmt, ...); +#endif + + +/* DllMain is invoked by every process in the entire system that is hooked + * by our window hooks, notably the tty processes' context, and by the user + * who wants tty messages (the app). Keep it light and simple. + */ +BOOL __declspec(dllexport) APIENTRY DllMain(HINSTANCE hModule, ULONG ulReason, + LPVOID pctx) +{ + if (ulReason == DLL_PROCESS_ATTACH) + { + //hmodThis = hModule; + if (!hookwndmsg) { + origwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookOrigProc")); + hookwndprop = MAKEINTATOM(GlobalAddAtom("Win9xConHookThunkWnd")); + hookwndmsg = RegisterWindowMessage("Win9xConHookMsg"); + } +#ifdef DBG +// DbgPrintf("H ProcessAttach:%8.8x\r\n", +// GetCurrentProcessId()); +#endif + } + else if ( ulReason == DLL_PROCESS_DETACH ) + { +#ifdef DBG +// DbgPrintf("H ProcessDetach:%8.8x\r\n", GetCurrentProcessId()); +#endif + if (monitor_hwnd) + SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); + if (is_subclassed) + SendMessage(hwtty, hookwndmsg, 0, (LPARAM)hwtty); + if (hmodHook) + { + if (hhkGetMessage) { + UnhookWindowsHookEx(hhkGetMessage); + hhkGetMessage = NULL; + } + //if (hhkCallWndProc) { + // UnhookWindowsHookEx(hhkCallWndProc); + // hhkCallWndProc = NULL; + //} + FreeLibrary(hmodHook); + hmodHook = NULL; + } + if (is_service) + RegisterWindows9xService(FALSE); + if (hookwndmsg) { + GlobalDeleteAtom((ATOM)origwndprop); + GlobalDeleteAtom((ATOM)hookwndprop); + hookwndmsg = 0; + } + } + return TRUE; +} + + +/* This group of functions are provided for the service/console app + * to register itself a HandlerRoutine to accept tty or service messages + */ + + +/* Exported function that creates a Win9x 'service' via a hidden window, + * that notifies the process via the HandlerRoutine messages. + */ +BOOL __declspec(dllexport) WINAPI Windows9xServiceCtrlHandler( + PHANDLER_ROUTINE phandler, + LPCSTR name) +{ + /* If we have not yet done so */ + FreeConsole(); + + if (name) + { + DWORD tid; + HANDLE hThread; + /* NOTE: this is static so the module can continue to + * access these args while we go on to other things + */ + static tty_info tty; + tty.instance = GetModuleHandle(NULL); + tty.phandler = phandler; + tty.parent = NULL; + tty.name = name; + tty.type = 2; + RegisterWindows9xService(TRUE); + hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread, + (LPVOID)&tty, 0, &tid); + if (hThread) + { + CloseHandle(hThread); + return TRUE; + } + } + else /* remove */ + { + if (monitor_hwnd) + SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); + RegisterWindows9xService(FALSE); + return TRUE; + } + return FALSE; +} + + +/* Exported function that registers a HandlerRoutine to accept missing + * Win9x CTRL_EVENTs from the tty window, as NT does without a hassle. + * If add is 1 or 2, register the handler, if 2 also mark it as a service. + * If add is 0 deregister the handler, and unmark if a service + */ +BOOL __declspec(dllexport) WINAPI FixConsoleCtrlHandler( + PHANDLER_ROUTINE phandler, + INT add) +{ + HWND parent; + + if (add) + { + HANDLE hThread; + DWORD tid; + /* NOTE: this is static so the module can continue to + * access these args while we go on to other things + */ + static tty_info tty; + EnumWindows(EnumttyWindow, (LPARAM)&parent); + if (!parent) { +#ifdef DBG + DbgPrintf("A EnumttyWindow failed (%d)\r\n", GetLastError()); +#endif + return FALSE; + } + tty.instance = GetModuleHandle(NULL); + tty.phandler = phandler; + tty.parent = parent; + tty.type = add; + if (add == 2) { + tty.name = "ttyService"; + RegisterWindows9xService(TRUE); + } + else + tty.name = "ttyMonitor"; + hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread, + (LPVOID)&tty, 0, &tid); + if (!hThread) + return FALSE; + CloseHandle(hThread); + hmodHook = LoadLibrary("Win9xConHook.dll"); + if (hmodHook) + { + hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE, + (HOOKPROC)GetProcAddress(hmodHook, "GetMsgProc"), hmodHook, 0); + //hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC, + // (HOOKPROC)GetProcAddress(hmodHook, "CallWndProc"), hmodHook, 0); + } + return TRUE; + } + else /* remove */ + { + if (monitor_hwnd) { + SendMessage(monitor_hwnd, WM_DESTROY, 0, 0); + } + if (hmodHook) + { + if (hhkGetMessage) { + UnhookWindowsHookEx(hhkGetMessage); + hhkGetMessage = NULL; + } + //if (hhkCallWndProc) { + // UnhookWindowsHookEx(hhkCallWndProc); + // hhkCallWndProc = NULL; + //} + FreeLibrary(hmodHook); + hmodHook = NULL; + } + if (is_service) + RegisterWindows9xService(FALSE); + return TRUE; + } + return FALSE; +} + + +/* The following internal helpers are only used within the app's context + */ + +/* ttyConsoleCreateThread is the process that runs within the user app's + * context. It creates and pumps the messages of a hidden monitor window, + * watching for messages from the system, or the associated subclassed tty + * window. Things can happen in our context that can't be done from the + * tty's context, and visa versa, so the subclass procedure and this hidden + * window work together to make it all happen. + */ +static DWORD WINAPI ttyConsoleCtrlThread(LPVOID tty) +{ + WNDCLASS wc; + MSG msg; + wc.style = CS_GLOBALCLASS; + wc.lpfnWndProc = ttyConsoleCtrlWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 8; + wc.hInstance = NULL; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + if (((tty_info*)tty)->parent) + wc.lpszClassName = "ttyConHookChild"; + else + wc.lpszClassName = "ApacheWin95ServiceMonitor"; + + if (!RegisterClass(&wc)) { +#ifdef DBG + DbgPrintf("A proc %8.8x Error creating class %s (%d)\r\n", + GetCurrentProcessId(), wc.lpszClassName, GetLastError()); +#endif + return 0; + } + + /* Create an invisible window */ + monitor_hwnd = CreateWindow(wc.lpszClassName, ((tty_info*)tty)->name, + WS_OVERLAPPED & ~WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, + ((tty_info*)tty)->instance, tty); + + if (!monitor_hwnd) { +#ifdef DBG + DbgPrintf("A proc %8.8x Error creating window %s %s (%d)\r\n", + GetCurrentProcessId(), wc.lpszClassName, + ((tty_info*)tty)->name, GetLastError()); +#endif + return 0; + } + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + /* Tag again as deleted, just in case we missed WM_DESTROY */ + monitor_hwnd = NULL; + return 0; +} + + +/* This is the WndProc procedure for our invisible window. + * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION, + * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden + * window (this message process), and we call the installed HandlerRoutine + * that was registered by the app. + */ +static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_CREATE) + { + tty_info *tty = (tty_info*)(((LPCREATESTRUCT)lParam)->lpCreateParams); + SetWindowLong(hwnd, gwltty_phandler, (LONG)tty->phandler); + SetWindowLong(hwnd, gwltty_ttywnd, (LONG)tty->parent); +#ifdef DBG + DbgPrintf("A proc %8.8x created %8.8x %s for tty wnd %8.8x\r\n", + GetCurrentProcessId(), hwnd, + tty->name, tty->parent); +#endif + if (tty->parent) { + SetProp(tty->parent, hookwndprop, hwnd); + PostMessage(tty->parent, hookwndmsg, + tty->type, (LPARAM)tty->parent); + } + return 0; + } + else if (msg == WM_DESTROY) + { + HWND parent = (HWND)GetWindowLong(hwnd, gwltty_ttywnd); +#ifdef DBG + DbgPrintf("A proc %8.8x destroyed %8.8x ttyConHookChild\r\n", + GetCurrentProcessId(), hwnd); +#endif + if (parent) { + RemoveProp(parent, hookwndprop); + SendMessage(parent, hookwndmsg, 0, (LPARAM)parent); + } + monitor_hwnd = NULL; + } + else if (msg == WM_CLOSE) + { + PHANDLER_ROUTINE phandler = + (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); + LRESULT rv = phandler(CTRL_CLOSE_EVENT); +#ifdef DBG + DbgPrintf("A proc %8.8x invoked CTRL_CLOSE_EVENT " + "returning %d\r\n", + GetCurrentProcessId(), rv); +#endif + if (rv) + return !rv; + } + else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) + { + if (lParam & ENDSESSION_LOGOFF) + { + PHANDLER_ROUTINE phandler = + (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); + LRESULT rv = phandler(CTRL_LOGOFF_EVENT); +#ifdef DBG + DbgPrintf("A proc %8.8x invoked CTRL_LOGOFF_EVENT " + "returning %d\r\n", + GetCurrentProcessId(), rv); +#endif + if (rv) + return ((msg == WM_QUERYENDSESSION) ? rv : !rv); + } + else + { + PHANDLER_ROUTINE phandler = + (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); + LRESULT rv = phandler(CTRL_SHUTDOWN_EVENT); +#ifdef DBG + DbgPrintf("A proc %8.8x invoked CTRL_SHUTDOWN_EVENT " + "returning %d\r\n", GetCurrentProcessId(), rv); +#endif + if (rv) + return ((msg == WM_QUERYENDSESSION) ? rv : !rv); + } + } + return (DefWindowProc(hwnd, msg, wParam, lParam)); +} + + +/* The following internal helpers are invoked by the hooked tty and our app + */ + + +/* Register or deregister the current process as a Windows9x style service. + * Experience shows this call is ignored across processes, so the second + * arg to RegisterServiceProcess (process group id) is effectively useless. + */ +static LRESULT WINAPI RegisterWindows9xService(BOOL set_service) +{ + static HINSTANCE hkernel; + static DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL; + BOOL rv; + + if (set_service == is_service) + return 1; + +#ifdef DBG + DbgPrintf("R %s proc %8.8x as a service\r\n", + set_service ? "installing" : "removing", + GetCurrentProcessId()); +#endif + + if (!register_service_process) + { + /* Obtain a handle to the kernel library */ + hkernel = LoadLibrary("KERNEL32.DLL"); + if (!hkernel) + return 0; + + /* Find the RegisterServiceProcess function */ + register_service_process = (DWORD (WINAPI *)(DWORD, DWORD)) + GetProcAddress(hkernel, "RegisterServiceProcess"); + if (register_service_process == NULL) { + FreeLibrary(hkernel); + return 0; + } + } + + /* Register this process as a service */ + rv = register_service_process(0, set_service != FALSE); + if (rv) + is_service = set_service; + + if (!is_service) + { + /* Unload the kernel library */ + FreeLibrary(hkernel); + register_service_process = NULL; + } + return rv; +} + + +/* + * This function only works when this process is the active process + * (e.g. once it is running a child process, it can no longer determine + * which console window is its own.) + */ +static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd) +{ + char tmp[8]; + if (GetClassName(wnd, tmp, sizeof(tmp)) && !strcmp(tmp, "tty")) + { + DWORD wndproc, thisproc = GetCurrentProcessId(); + GetWindowThreadProcessId(wnd, &wndproc); + if (wndproc == thisproc) { + *((HWND*)retwnd) = wnd; + return FALSE; + } + } + return TRUE; +} + + +/* The remaining code all executes --in the tty's own process context-- + * + * That means special attention must be paid to what it's doing... + */ + +/* Subclass message process for the tty window + * + * This code -handles- WM_CLOSE, WM_ENDSESSION and WM_QUERYENDSESSION + * by dispatching them to the window identified by the hookwndprop + * property atom set against our window. Messages are then dispatched + * to origwndprop property atom we set against the window when we + * injected this subclass. This trick did not work with simply a hook. + */ +static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + WNDPROC origproc = (WNDPROC) GetProp(hwnd, origwndprop); + if (!origproc) + return 0; + + if (msg == WM_NCDESTROY + || (msg == hookwndmsg && !LOWORD(wParam) && (HWND)lParam == hwnd)) + { + if (is_subclassed) { +#ifdef DBG + DbgPrintf("W proc %08x hwnd:%08x Subclass removed\r\n", + GetCurrentProcessId(), hwnd); +#endif + if (is_service) + RegisterWindows9xService(FALSE); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG)origproc); + RemoveProp(hwnd, origwndprop); + RemoveProp(hwnd, hookwndprop); + is_subclassed = FALSE; + //if (hmodLock) + // FreeLibrary(hmodLock); + //hmodLock = NULL; + } + } + else if (msg == WM_CLOSE || msg == WM_ENDSESSION + || msg == WM_QUERYENDSESSION) + { + HWND child = (HWND)GetProp(hwnd, hookwndprop); + if (child) { +#ifdef DBG + DbgPrintf("W proc %08x hwnd:%08x forwarded msg:%d\r\n", + GetCurrentProcessId(), hwnd, msg); +#endif + return SendMessage(child, msg, wParam, lParam); + } + } + return CallWindowProc(origproc, hwnd, msg, wParam, lParam); +} + + +/* HookProc, once installed, is responsible for subclassing the system + * tty windows. It generally does nothing special itself, since + * research indicates that it cannot deal well with the messages we are + * interested in, that is, WM_CLOSE, WM_QUERYSHUTDOWN and WM_SHUTDOWN + * of the tty process. + * + * Respond and subclass only when a WM_NULL is received by the window. + */ +int HookProc(int hc, HWND *hwnd, UINT *msg, WPARAM *wParam, LPARAM *lParam) +{ + if (is_tty == -1 && *hwnd) + { + char ttybuf[8]; + HWND htty; + hwtty = *hwnd; + while (htty = GetParent(hwtty)) + hwtty = htty; + is_tty = (GetClassName(hwtty, ttybuf, sizeof(ttybuf)) + && !strcmp(ttybuf, "tty")); +#ifdef DBG + if (is_tty) + DbgPrintf("H proc %08x tracking hwnd %08x\r\n", + GetCurrentProcessId(), hwtty); +#endif + } + + if (*msg == hookwndmsg && *wParam && *lParam == (LPARAM)hwtty && is_tty) + { + WNDPROC origproc = (WNDPROC)GetWindowLong(hwtty, GWL_WNDPROC); + //char myname[MAX_PATH]; + //if (GetModuleFileName(hmodThis, myname, sizeof(myname))) + // hmodLock = LoadLibrary(myname); + SetProp(hwtty, origwndprop, origproc); + SetWindowLong(hwtty, GWL_WNDPROC, (LONG)WndProc); + is_subclassed = TRUE; +#ifdef DBG + DbgPrintf("H proc %08x hwnd:%08x Subclassed\r\n", + GetCurrentProcessId(), hwtty); +#endif + if (LOWORD(*wParam) == 2) + RegisterWindows9xService(TRUE); + } + + return -1; +} + + +/* + * PostMessage Hook: + */ +LRESULT __declspec(dllexport) CALLBACK GetMsgProc(INT hc, WPARAM wParam, + LPARAM lParam) +{ + PMSG pmsg; + + pmsg = (PMSG)lParam; + + if (pmsg) { + int rv = HookProc(hc, &pmsg->hwnd, &pmsg->message, + &pmsg->wParam, &pmsg->lParam); + if (rv != -1) + return rv; + } + /* + * CallNextHookEx apparently ignores the hhook argument, so pass NULL + */ + return CallNextHookEx(NULL, hc, wParam, lParam); +} + + +/* + * SendMessage Hook: + */ +LRESULT __declspec(dllexport) CALLBACK CallWndProc(INT hc, WPARAM wParam, + LPARAM lParam) +{ + PCWPSTRUCT pcwps = (PCWPSTRUCT)lParam; + + if (pcwps) { + int rv = HookProc(hc, &pcwps->hwnd, &pcwps->message, + &pcwps->wParam, &pcwps->lParam); + if (rv != -1) + return rv; + } + /* + * CallNextHookEx apparently ignores the hhook argument, so pass NULL + */ + return CallNextHookEx(NULL, hc, wParam, lParam); +} + + +#ifdef DBG +VOID DbgPrintf( + LPTSTR fmt, + ... + ) +{ + static HANDLE mutex; + va_list marker; + TCHAR szBuf[256]; + DWORD t; + HANDLE gDbgOut; + + va_start(marker, fmt); + wvsprintf(szBuf, fmt, marker); + va_end(marker); + + if (!mutex) + mutex = CreateMutex(NULL, FALSE, "Win9xConHookDbgOut"); + WaitForSingleObject(mutex, INFINITE); + gDbgOut = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); + WriteFile(gDbgOut, szBuf, strlen(szBuf), &t, NULL); + CloseHandle(gDbgOut); + ReleaseMutex(mutex); +} +#endif + +#endif /* WIN32 */ diff --git a/trunk/server/mpm/winnt/Win9xConHook.def b/trunk/server/mpm/winnt/Win9xConHook.def new file mode 100644 index 0000000000..85ec166404 --- /dev/null +++ b/trunk/server/mpm/winnt/Win9xConHook.def @@ -0,0 +1,10 @@ +LIBRARY Win9xConHook + +EXETYPE WINDOWS + +EXPORTS + DllMain + GetMsgProc + CallWndProc + FixConsoleCtrlHandler + Windows9xServiceCtrlHandler diff --git a/trunk/server/mpm/winnt/Win9xConHook.dsp b/trunk/server/mpm/winnt/Win9xConHook.dsp new file mode 100644 index 0000000000..d5446c89a5 --- /dev/null +++ b/trunk/server/mpm/winnt/Win9xConHook.dsp @@ -0,0 +1,103 @@ +# Microsoft Developer Studio Project File - Name="Win9xConHook" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Win9xConHook - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Win9xConHook.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Win9xConHook.mak" CFG="Win9xConHook - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win9xConHook - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Win9xConHook - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Win9xConHook - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /Fd"Release\Win9xConHook" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /machine:I386 /base:"0x1c0f0000" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /machine:I386 /base:"0x1c0f0000" /opt:ref + +!ELSEIF "$(CFG)" == "Win9xConHook - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /Fd"Debug\Win9xConHook" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /base:"0x1c0f0000" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /base:"0x1c0f0000" + +!ENDIF + +# Begin Target + +# Name "Win9xConHook - Win32 Release" +# Name "Win9xConHook - Win32 Debug" +# Begin Source File + +SOURCE=.\Win9xConHook.c +# End Source File +# Begin Source File + +SOURCE=.\Win9xConHook.def +# End Source File +# Begin Source File + +SOURCE=.\Win9xConHook.h +# End Source File +# End Target +# End Project diff --git a/trunk/server/mpm/winnt/Win9xConHook.h b/trunk/server/mpm/winnt/Win9xConHook.h new file mode 100644 index 0000000000..0fc8c1231c --- /dev/null +++ b/trunk/server/mpm/winnt/Win9xConHook.h @@ -0,0 +1,57 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AP_WIN9XCONHOOK_H +#define AP_WIN9XCONHOOK_H + +#ifdef WIN32 + +/* Windows9xServiceCtrlHandler registers a handler routine, frees the + * console window, and registers this process as a service in Win9x. + * It creats a hidden window of class "ApacheWin95ServiceMonitor" + * and titled by the name passed, which passes the WM_SHUTDOWN message + * through the given HandlerRoutine's CTRL_SHUTDOWN event. + * Call with name of NULL to remove the Service handler. + */ +BOOL WINAPI Windows9xServiceCtrlHandler(PHANDLER_ROUTINE phandler, LPCSTR name); + + +/* FixConsoleControlHandler registers a handler routine with the + * Win9xConHook.dll, creating a hidden window and forwarding the + * WM_ENDSESSION and WM_CLOSE messages to the given HandlerRoutine + * as CTRL_SHUTDOWN_EVENT, CTRL_LOGOFF_EVENT and CTRL_CLOSE_EVENT. + * The application should still use SetConsoleCtrlHandler to grab + * the CTRL_BREAK_EVENT and CTRL_C_EVENT, if desired. + */ +BOOL WINAPI FixConsoleCtrlHandler(PHANDLER_ROUTINE phandler, BOOL add); + + +/* + * Exported PostMessage Hook, never use this directly: + * + * LRESULT CALLBACK GetMsgProc(INT hc, WPARAM wParam, LPARAM lParam); + */ + + +/* + * Exported SendMessage Hook, never use this directly: + * + * LRESULT CALLBACK CallWndProc(INT hc, WPARAM wParam, LPARAM lParam); + */ + +#endif /* WIN32 */ + +#endif AP_WIN9XCONHOOK_H diff --git a/trunk/server/mpm/winnt/child.c b/trunk/server/mpm/winnt/child.c new file mode 100644 index 0000000000..d560187b39 --- /dev/null +++ b/trunk/server/mpm/winnt/child.c @@ -0,0 +1,1157 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "apr_portable.h" +#include "apr_thread_proc.h" +#include "apr_getopt.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_shm.h" +#include "apr_thread_mutex.h" +#include "ap_mpm.h" +#include "ap_config.h" +#include "ap_listen.h" +#include "mpm_default.h" +#include "mpm_winnt.h" +#include "mpm_common.h" +#include +#include "apr_atomic.h" + +/* shared with mpm_winnt.c */ +extern DWORD my_pid; + +/* used by parent to signal the child to start and exit */ +/* shared with mpm_winnt.c, but should be private to child.c */ +apr_proc_mutex_t *start_mutex; +HANDLE exit_event; + +/* child_main() should never need to modify is_graceful!?! */ +extern int volatile is_graceful; + +/* Queue for managing the passing of COMP_CONTEXTs between + * the accept and worker threads. + */ +static apr_pool_t *pchild; +static int shutdown_in_progress = 0; +static int workers_may_exit = 0; +static unsigned int g_blocked_threads = 0; +static HANDLE max_requests_per_child_event; + +static apr_thread_mutex_t *child_lock; +static apr_thread_mutex_t *qlock; +static PCOMP_CONTEXT qhead = NULL; +static PCOMP_CONTEXT qtail = NULL; +static int num_completion_contexts = 0; +static int max_num_completion_contexts = 0; +static HANDLE ThreadDispatchIOCP = NULL; +static HANDLE qwait_event = NULL; + + +void mpm_recycle_completion_context(PCOMP_CONTEXT context) +{ + /* Recycle the completion context. + * - clear the ptrans pool + * - put the context on the queue to be consumed by the accept thread + * Note: + * context->accept_socket may be in a disconnected but reusable + * state so -don't- close it. + */ + if (context) { + apr_pool_clear(context->ptrans); + context->next = NULL; + ResetEvent(context->Overlapped.hEvent); + apr_thread_mutex_lock(qlock); + if (qtail) { + qtail->next = context; + } else { + qhead = context; + SetEvent(qwait_event); + } + qtail = context; + apr_thread_mutex_unlock(qlock); + } +} + +PCOMP_CONTEXT mpm_get_completion_context(void) +{ + apr_status_t rv; + PCOMP_CONTEXT context = NULL; + + while (1) { + /* Grab a context off the queue */ + apr_thread_mutex_lock(qlock); + if (qhead) { + context = qhead; + qhead = qhead->next; + if (!qhead) + qtail = NULL; + } else { + ResetEvent(qwait_event); + } + apr_thread_mutex_unlock(qlock); + + if (!context) { + /* We failed to grab a context off the queue, consider allocating + * a new one out of the child pool. There may be up to + * (ap_threads_per_child + num_listeners) contexts in the system + * at once. + */ + if (num_completion_contexts >= max_num_completion_contexts) { + /* All workers are busy, need to wait for one */ + static int reported = 0; + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, + "Server ran out of threads to serve requests. Consider " + "raising the ThreadsPerChild setting"); + reported = 1; + } + + /* Wait for a worker to free a context. Once per second, give + * the caller a chance to check for shutdown. If the wait + * succeeds, get the context off the queue. It must be available, + * since there's only one consumer. + */ + rv = WaitForSingleObject(qwait_event, 1000); + if (rv == WAIT_OBJECT_0) + continue; + else /* Hopefully, WAIT_TIMEOUT */ + return NULL; + } else { + /* Allocate another context. + * Note: + * Multiple failures in the next two steps will cause the pchild pool + * to 'leak' storage. I don't think this is worth fixing... + */ + apr_allocator_t *allocator; + + apr_thread_mutex_lock(child_lock); + context = (PCOMP_CONTEXT) apr_pcalloc(pchild, sizeof(COMP_CONTEXT)); + + context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (context->Overlapped.hEvent == NULL) { + /* Hopefully this is a temporary condition ... */ + ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_os_error(), ap_server_conf, + "mpm_get_completion_context: CreateEvent failed."); + + apr_thread_mutex_unlock(child_lock); + return NULL; + } + + /* Create the tranaction pool */ + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + rv = apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_WARNING, rv, ap_server_conf, + "mpm_get_completion_context: Failed to create the transaction pool."); + CloseHandle(context->Overlapped.hEvent); + + apr_thread_mutex_unlock(child_lock); + return NULL; + } + apr_allocator_owner_set(allocator, context->ptrans); + apr_pool_tag(context->ptrans, "transaction"); + + context->accept_socket = INVALID_SOCKET; + context->ba = apr_bucket_alloc_create(pchild); + apr_atomic_inc32(&num_completion_contexts); + + apr_thread_mutex_unlock(child_lock); + break; + } + } else { + /* Got a context from the queue */ + break; + } + } + + return context; +} + +apr_status_t mpm_post_completion_context(PCOMP_CONTEXT context, + io_state_e state) +{ + LPOVERLAPPED pOverlapped; + if (context) + pOverlapped = &context->Overlapped; + else + pOverlapped = NULL; + + PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, state, pOverlapped); + return APR_SUCCESS; +} + + +/* + * find_ready_listener() + * Only used by Win9* and should go away when the win9*_accept() function is + * reimplemented using apr_poll(). + */ +static ap_listen_rec *head_listener; + +static APR_INLINE ap_listen_rec *find_ready_listener(fd_set * main_fds) +{ + ap_listen_rec *lr; + SOCKET nsd; + + lr = head_listener; + do { + apr_os_sock_get(&nsd, lr->sd); + if (FD_ISSET(nsd, main_fds)) { + head_listener = lr->next; + if (!head_listener) { + head_listener = ap_listeners; + } + return lr; + } + lr = lr->next; + if (!lr) { + lr = ap_listeners; + } + } while (lr != head_listener); + return NULL; +} + + +/* Windows 9x specific code... + * Accept processing for on Windows 95/98 uses a producer/consumer queue + * model. A single thread accepts connections and queues the accepted socket + * to the accept queue for consumption by a pool of worker threads. + * + * win9x_accept() + * The accept threads runs this function, which accepts connections off + * the network and calls add_job() to queue jobs to the accept_queue. + * add_job()/remove_job() + * Add or remove an accepted socket from the list of sockets + * connected to clients. allowed_globals.jobmutex protects + * against multiple concurrent access to the linked list of jobs. + * win9x_get_connection() + * Calls remove_job() to pull a job from the accept queue. All the worker + * threads block on remove_job. + */ + +typedef struct joblist_s { + struct joblist_s *next; + SOCKET sock; +} joblist; + +typedef struct globals_s { + HANDLE jobsemaphore; + joblist *jobhead; + joblist *jobtail; + apr_thread_mutex_t *jobmutex; + int jobcount; +} globals; + +globals allowed_globals = {NULL, NULL, NULL, NULL, 0}; + +#define MAX_SELECT_ERRORS 100 + + +static void add_job(SOCKET sock) +{ + joblist *new_job; + + new_job = (joblist *) malloc(sizeof(joblist)); + if (new_job == NULL) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Ouch! Out of memory in add_job()!"); + return; + } + new_job->next = NULL; + new_job->sock = sock; + + apr_thread_mutex_lock(allowed_globals.jobmutex); + + if (allowed_globals.jobtail != NULL) + allowed_globals.jobtail->next = new_job; + allowed_globals.jobtail = new_job; + if (!allowed_globals.jobhead) + allowed_globals.jobhead = new_job; + allowed_globals.jobcount++; + ReleaseSemaphore(allowed_globals.jobsemaphore, 1, NULL); + + apr_thread_mutex_unlock(allowed_globals.jobmutex); +} + + +static SOCKET remove_job(void) +{ + joblist *job; + SOCKET sock; + + WaitForSingleObject(allowed_globals.jobsemaphore, INFINITE); + apr_thread_mutex_lock(allowed_globals.jobmutex); + + if (shutdown_in_progress && !allowed_globals.jobhead) { + apr_thread_mutex_unlock(allowed_globals.jobmutex); + return (INVALID_SOCKET); + } + job = allowed_globals.jobhead; + ap_assert(job); + allowed_globals.jobhead = job->next; + if (allowed_globals.jobhead == NULL) + allowed_globals.jobtail = NULL; + apr_thread_mutex_unlock(allowed_globals.jobmutex); + sock = job->sock; + free(job); + + return (sock); +} + + +static unsigned int __stdcall win9x_accept(void * dummy) +{ + struct timeval tv; + fd_set main_fds; + int wait_time = 1; + SOCKET csd; + SOCKET nsd = INVALID_SOCKET; + int count_select_errors = 0; + int rc; + int clen; + ap_listen_rec *lr; + struct fd_set listenfds; +#if APR_HAVE_IPV6 + struct sockaddr_in6 sa_client; +#else + struct sockaddr_in sa_client; +#endif + + /* Setup the listeners + * ToDo: Use apr_poll() + */ + FD_ZERO(&listenfds); + for (lr = ap_listeners; lr; lr = lr->next) { + if (lr->sd != NULL) { + apr_os_sock_get(&nsd, lr->sd); + FD_SET(nsd, &listenfds); + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Child %d: Listening on port %d.", my_pid, lr->bind_addr->port); + } + } + + head_listener = ap_listeners; + + while (!shutdown_in_progress) { + tv.tv_sec = wait_time; + tv.tv_usec = 0; + memcpy(&main_fds, &listenfds, sizeof(fd_set)); + + /* First parameter of select() is ignored on Windows */ + rc = select(0, &main_fds, NULL, NULL, &tv); + + if (rc == 0 || (rc == SOCKET_ERROR && APR_STATUS_IS_EINTR(apr_get_netos_error()))) { + count_select_errors = 0; /* reset count of errors */ + continue; + } + else if (rc == SOCKET_ERROR) { + /* A "real" error occurred, log it and increment the count of + * select errors. This count is used to ensure we don't go into + * a busy loop of continuous errors. + */ + ap_log_error(APLOG_MARK, APLOG_INFO, apr_get_netos_error(), ap_server_conf, + "select failed with error %d", apr_get_netos_error()); + count_select_errors++; + if (count_select_errors > MAX_SELECT_ERRORS) { + shutdown_in_progress = 1; + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), ap_server_conf, + "Too many errors in select loop. Child process exiting."); + break; + } + } else { + ap_listen_rec *lr; + + lr = find_ready_listener(&main_fds); + if (lr != NULL) { + /* fetch the native socket descriptor */ + apr_os_sock_get(&nsd, lr->sd); + } + } + + do { + clen = sizeof(sa_client); + csd = accept(nsd, (struct sockaddr *) &sa_client, &clen); + } while (csd < 0 && APR_STATUS_IS_EINTR(apr_get_netos_error())); + + if (csd < 0) { + if (APR_STATUS_IS_ECONNABORTED(apr_get_netos_error())) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_netos_error(), ap_server_conf, + "accept: (client socket)"); + } + } + else { + add_job(csd); + } + } + SetEvent(exit_event); + return 0; +} + + +static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context) +{ + apr_os_sock_info_t sockinfo; + int len, salen; +#if APR_HAVE_IPV6 + salen = sizeof(struct sockaddr_in6); +#else + salen = sizeof(struct sockaddr_in); +#endif + + + if (context == NULL) { + /* allocate the completion context and the transaction pool */ + apr_allocator_t *allocator; + apr_thread_mutex_lock(child_lock); + context = apr_pcalloc(pchild, sizeof(COMP_CONTEXT)); + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator); + apr_allocator_owner_set(allocator, context->ptrans); + apr_pool_tag(context->ptrans, "transaction"); + context->ba = apr_bucket_alloc_create(pchild); + apr_thread_mutex_unlock(child_lock); + } + + while (1) { + apr_pool_clear(context->ptrans); + context->accept_socket = remove_job(); + if (context->accept_socket == INVALID_SOCKET) { + return NULL; + } + len = salen; + context->sa_server = apr_palloc(context->ptrans, len); + if (getsockname(context->accept_socket, + context->sa_server, &len)== SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, + "getsockname failed"); + continue; + } + len = salen; + context->sa_client = apr_palloc(context->ptrans, len); + if ((getpeername(context->accept_socket, + context->sa_client, &len)) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, + "getpeername failed"); + memset(&context->sa_client, '\0', sizeof(context->sa_client)); + } + sockinfo.os_sock = &context->accept_socket; + sockinfo.local = context->sa_server; + sockinfo.remote = context->sa_client; + sockinfo.family = context->sa_server->sa_family; + sockinfo.type = SOCK_STREAM; + apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); + + return context; + } +} + + +/* Windows NT/2000 specific code... + * Accept processing for on Windows NT uses a producer/consumer queue + * model. An accept thread accepts connections off the network then issues + * PostQueuedCompletionStatus() to awake a thread blocked on the ThreadDispatch + * IOCompletionPort. + * + * winnt_accept() + * One or more accept threads run in this function, each of which accepts + * connections off the network and calls PostQueuedCompletionStatus() to + * queue an io completion packet to the ThreadDispatch IOCompletionPort. + * winnt_get_connection() + * Worker threads block on the ThreadDispatch IOCompletionPort awaiting + * connections to service. + */ +#define MAX_ACCEPTEX_ERR_COUNT 100 +static unsigned int __stdcall winnt_accept(void *lr_) +{ + ap_listen_rec *lr = (ap_listen_rec *)lr_; + apr_os_sock_info_t sockinfo; + PCOMP_CONTEXT context = NULL; + DWORD BytesRead; + SOCKET nlsd; + int rv, err_count = 0; +#if APR_HAVE_IPV6 + SOCKADDR_STORAGE ss_listen; + int namelen = sizeof(ss_listen); +#endif + + apr_os_sock_get(&nlsd, lr->sd); + +#if APR_HAVE_IPV6 + if (getsockname(nlsd, (struct sockaddr *)&ss_listen, &namelen) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_netos_error(), ap_server_conf, + "winnt_accept: getsockname error on listening socket, is IPv6 available?"); + return 1; + } +#endif + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Child %d: Starting thread to listen on port %d.", my_pid, lr->bind_addr->port); + while (!shutdown_in_progress) { + if (!context) { + context = mpm_get_completion_context(); + if (!context) { + /* Temporary resource constraint? */ + Sleep(0); + continue; + } + } + + /* Create and initialize the accept socket */ +#if APR_HAVE_IPV6 + if (context->accept_socket == INVALID_SOCKET) { + context->accept_socket = socket(ss_listen.ss_family, SOCK_STREAM, IPPROTO_TCP); + context->socket_family = ss_listen.ss_family; + } + else if (context->socket_family != ss_listen.ss_family) { + closesocket(context->accept_socket); + context->accept_socket = socket(ss_listen.ss_family, SOCK_STREAM, IPPROTO_TCP); + context->socket_family = ss_listen.ss_family; + } + + if (context->accept_socket == INVALID_SOCKET) { + ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_netos_error(), ap_server_conf, + "winnt_accept: Failed to allocate an accept socket. " + "Temporary resource constraint? Try again."); + Sleep(100); + continue; + } +#else + if (context->accept_socket == INVALID_SOCKET) { + context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (context->accept_socket == INVALID_SOCKET) { + /* Another temporary condition? */ + ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_netos_error(), ap_server_conf, + "winnt_accept: Failed to allocate an accept socket. " + "Temporary resource constraint? Try again."); + Sleep(100); + continue; + } + } +#endif + /* AcceptEx on the completion context. The completion context will be + * signaled when a connection is accepted. + */ + if (!AcceptEx(nlsd, context->accept_socket, + context->buff, + 0, + PADDED_ADDR_SIZE, + PADDED_ADDR_SIZE, + &BytesRead, + &context->Overlapped)) { + rv = apr_get_netos_error(); + if ((rv == APR_FROM_OS_ERROR(WSAEINVAL)) || + (rv == APR_FROM_OS_ERROR(WSAENOTSOCK))) { + /* We can get here when: + * 1) the client disconnects early + * 2) TransmitFile does not properly recycle the accept socket (typically + * because the client disconnected) + * 3) there is VPN or Firewall software installed with buggy AcceptEx implementation + * 4) the webserver is using a dynamic address that has changed + */ + ++err_count; + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + if (err_count > MAX_ACCEPTEX_ERR_COUNT) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, + "Child %d: Encountered too many errors accepting client connections. " + "Possible causes: dynamic address renewal, or incompatible VPN or firewall software. " + "Try using the Win32DisableAcceptEx directive.", my_pid); + err_count = 0; + } + continue; + } + else if ((rv != APR_FROM_OS_ERROR(ERROR_IO_PENDING)) && + (rv != APR_FROM_OS_ERROR(WSA_IO_PENDING))) { + ++err_count; + if (err_count > MAX_ACCEPTEX_ERR_COUNT) { + ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, + "Child %d: Encountered too many errors accepting client connections. " + "Possible causes: Unknown. " + "Try using the Win32DisableAcceptEx directive.", my_pid); + err_count = 0; + } + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + continue; + } + err_count = 0; + + /* Wait for pending i/o. + * Wake up once per second to check for shutdown . + * XXX: We should be waiting on exit_event instead of polling + */ + while (1) { + rv = WaitForSingleObject(context->Overlapped.hEvent, 1000); + if (rv == WAIT_OBJECT_0) { + if (context->accept_socket == INVALID_SOCKET) { + /* socket already closed */ + break; + } + if (!GetOverlappedResult((HANDLE)context->accept_socket, + &context->Overlapped, + &BytesRead, FALSE)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, + apr_get_os_error(), ap_server_conf, + "winnt_accept: Asynchronous AcceptEx failed."); + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + } + break; + } + /* WAIT_TIMEOUT */ + if (shutdown_in_progress) { + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + break; + } + } + if (context->accept_socket == INVALID_SOCKET) { + continue; + } + } + err_count = 0; + /* Inherit the listen socket settings. Required for + * shutdown() to work + */ + if (setsockopt(context->accept_socket, SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, (char *)&nlsd, + sizeof(nlsd))) { + ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, + "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed."); + /* Not a failure condition. Keep running. */ + } + + /* Get the local & remote address */ + GetAcceptExSockaddrs(context->buff, + 0, + PADDED_ADDR_SIZE, + PADDED_ADDR_SIZE, + &context->sa_server, + &context->sa_server_len, + &context->sa_client, + &context->sa_client_len); + + sockinfo.os_sock = &context->accept_socket; + sockinfo.local = context->sa_server; + sockinfo.remote = context->sa_client; + sockinfo.family = context->sa_server->sa_family; + sockinfo.type = SOCK_STREAM; + apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); + + /* When a connection is received, send an io completion notification to + * the ThreadDispatchIOCP. This function could be replaced by + * mpm_post_completion_context(), but why do an extra function call... + */ + PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_CONNECTION_ACCEPTED, + &context->Overlapped); + context = NULL; + } + if (!shutdown_in_progress) { + /* Yow, hit an irrecoverable error! Tell the child to die. */ + SetEvent(exit_event); + } + ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, + "Child %d: Accept thread exiting.", my_pid); + return 0; +} + + +static PCOMP_CONTEXT winnt_get_connection(PCOMP_CONTEXT context) +{ + int rc; + DWORD BytesRead; + LPOVERLAPPED pol; +#ifdef _WIN64 + ULONG_PTR CompKey; +#else + DWORD CompKey; +#endif + + mpm_recycle_completion_context(context); + + apr_atomic_inc32(&g_blocked_threads); + while (1) { + if (workers_may_exit) { + apr_atomic_dec32(&g_blocked_threads); + return NULL; + } + rc = GetQueuedCompletionStatus(ThreadDispatchIOCP, &BytesRead, &CompKey, + &pol, INFINITE); + if (!rc) { + rc = apr_get_os_error(); + ap_log_error(APLOG_MARK,APLOG_DEBUG, rc, ap_server_conf, + "Child %d: GetQueuedComplationStatus returned %d", my_pid, rc); + continue; + } + + switch (CompKey) { + case IOCP_CONNECTION_ACCEPTED: + context = CONTAINING_RECORD(pol, COMP_CONTEXT, Overlapped); + break; + case IOCP_SHUTDOWN: + apr_atomic_dec32(&g_blocked_threads); + return NULL; + default: + apr_atomic_dec32(&g_blocked_threads); + return NULL; + } + break; + } + apr_atomic_dec32(&g_blocked_threads); + + return context; +} + + +/* + * worker_main() + * Main entry point for the worker threads. Worker threads block in + * win*_get_connection() awaiting a connection to service. + */ +static unsigned int __stdcall worker_main(void *thread_num_val) +{ + static int requests_this_child = 0; + PCOMP_CONTEXT context = NULL; + int thread_num = (int)thread_num_val; + ap_sb_handle_t *sbh; + + while (1) { + conn_rec *c; + apr_int32_t disconnected; + + ap_update_child_status_from_indexes(0, thread_num, SERVER_READY, NULL); + + /* Grab a connection off the network */ + if (use_acceptex) { + context = winnt_get_connection(context); + } + else { + context = win9x_get_connection(context); + } + + if (!context) { + /* Time for the thread to exit */ + break; + } + + /* Have we hit MaxRequestPerChild connections? */ + if (ap_max_requests_per_child) { + requests_this_child++; + if (requests_this_child > ap_max_requests_per_child) { + SetEvent(max_requests_per_child_event); + } + } + + ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num); + c = ap_run_create_connection(context->ptrans, ap_server_conf, + context->sock, thread_num, sbh, + context->ba); + + if (c) { + ap_process_connection(c, context->sock); + apr_socket_opt_get(context->sock, APR_SO_DISCONNECTED, + &disconnected); + if (!disconnected) { + context->accept_socket = INVALID_SOCKET; + ap_lingering_close(c); + } + else if (!use_acceptex) { + /* If the socket is disconnected but we are not using acceptex, + * we cannot reuse the socket. Disconnected sockets are removed + * from the apr_socket_t struct by apr_sendfile() to prevent the + * socket descriptor from being inadvertently closed by a call + * to apr_socket_close(), so close it directly. + */ + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + } + } + else { + /* ap_run_create_connection closes the socket on failure */ + context->accept_socket = INVALID_SOCKET; + } + } + + ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, + (request_rec *) NULL); + + return 0; +} + + +static void cleanup_thread(HANDLE *handles, int *thread_cnt, int thread_to_clean) +{ + int i; + + CloseHandle(handles[thread_to_clean]); + for (i = thread_to_clean; i < ((*thread_cnt) - 1); i++) + handles[i] = handles[i + 1]; + (*thread_cnt)--; +} + + +/* + * child_main() + * Entry point for the main control thread for the child process. + * This thread creates the accept thread, worker threads and + * monitors the child process for maintenance and shutdown + * events. + */ +static void create_listener_thread() +{ + int tid; + int num_listeners = 0; + if (!use_acceptex) { + _beginthreadex(NULL, 0, win9x_accept, + NULL, 0, &tid); + } else { + /* Start an accept thread per listener + * XXX: Why would we have a NULL sd in our listeners? + */ + ap_listen_rec *lr; + + /* Number of completion_contexts allowed in the system is + * (ap_threads_per_child + num_listeners). We need the additional + * completion contexts to prevent server hangs when ThreadsPerChild + * is configured to something less than or equal to the number + * of listeners. This is not a usual case, but people have + * encountered it. + * */ + for (lr = ap_listeners; lr ; lr = lr->next) { + num_listeners++; + } + max_num_completion_contexts = ap_threads_per_child + num_listeners; + + /* Now start a thread per listener */ + for (lr = ap_listeners; lr; lr = lr->next) { + if (lr->sd != NULL) { + _beginthreadex(NULL, 1000, winnt_accept, + (void *) lr, 0, &tid); + } + } + } +} + + +void child_main(apr_pool_t *pconf) +{ + apr_status_t status; + apr_hash_t *ht; + ap_listen_rec *lr; + HANDLE child_events[2]; + int threads_created = 0; + int listener_started = 0; + int tid; + HANDLE *child_handles; + int rv; + time_t end_time; + int i; + int cld; + + apr_pool_create(&pchild, pconf); + apr_pool_tag(pchild, "pchild"); + + ap_run_child_init(pchild, ap_server_conf); + ht = apr_hash_make(pchild); + + /* Initialize the child_events */ + max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!max_requests_per_child_event) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Failed to create a max_requests event.", my_pid); + exit(APEXIT_CHILDINIT); + } + child_events[0] = exit_event; + child_events[1] = max_requests_per_child_event; + + allowed_globals.jobsemaphore = CreateSemaphore(NULL, 0, 1000000, NULL); + apr_thread_mutex_create(&allowed_globals.jobmutex, + APR_THREAD_MUTEX_DEFAULT, pchild); + + /* + * Wait until we have permission to start accepting connections. + * start_mutex is used to ensure that only one child ever + * goes into the listen/accept loop at once. + */ + status = apr_proc_mutex_lock(start_mutex); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_ERR, status, ap_server_conf, + "Child %d: Failed to acquire the start_mutex. Process will exit.", my_pid); + exit(APEXIT_CHILDINIT); + } + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Acquired the start mutex.", my_pid); + + /* + * Create the worker thread dispatch IOCompletionPort + * on Windows NT/2000 + */ + if (use_acceptex) { + /* Create the worker thread dispatch IOCP */ + ThreadDispatchIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, + 0, + 0); /* CONCURRENT ACTIVE THREADS */ + apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, pchild); + qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!qwait_event) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Failed to create a qwait event.", my_pid); + exit(APEXIT_CHILDINIT); + } + } + + /* + * Create the pool of worker threads + */ + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Starting %d worker threads.", my_pid, ap_threads_per_child); + child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(HANDLE)); + apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild); + + while (1) { + for (i = 0; i < ap_threads_per_child; i++) { + int *score_idx; + int status = ap_scoreboard_image->servers[0][i].status; + if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { + continue; + } + ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL); + child_handles[i] = (HANDLE) _beginthreadex(NULL, (unsigned)ap_thread_stacksize, + worker_main, (void *) i, 0, &tid); + if (child_handles[i] == 0) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: _beginthreadex failed. Unable to create all worker threads. " + "Created %d of the %d threads requested with the ThreadsPerChild configuration directive.", + my_pid, threads_created, ap_threads_per_child); + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + goto shutdown; + } + threads_created++; + /* Save the score board index in ht keyed to the thread handle. We need this + * when cleaning up threads down below... + */ + apr_thread_mutex_lock(child_lock); + score_idx = apr_pcalloc(pchild, sizeof(int)); + *score_idx = i; + apr_hash_set(ht, &child_handles[i], sizeof(HANDLE), score_idx); + apr_thread_mutex_unlock(child_lock); + } + /* Start the listener only when workers are available */ + if (!listener_started && threads_created) { + create_listener_thread(); + listener_started = 1; + winnt_mpm_state = AP_MPMQ_RUNNING; + } + if (threads_created == ap_threads_per_child) { + break; + } + /* Check to see if the child has been told to exit */ + if (WaitForSingleObject(exit_event, 0) != WAIT_TIMEOUT) { + break; + } + /* wait for previous generation to clean up an entry in the scoreboard */ + apr_sleep(1 * APR_USEC_PER_SEC); + } + + /* Wait for one of three events: + * exit_event: + * The exit_event is signaled by the parent process to notify + * the child that it is time to exit. + * + * max_requests_per_child_event: + * This event is signaled by the worker threads to indicate that + * the process has handled MaxRequestsPerChild connections. + * + * TIMEOUT: + * To do periodic maintenance on the server (check for thread exits, + * number of completion contexts, etc.) + * + * XXX: thread exits *aren't* being checked. + * + * XXX: other_child - we need the process handles to the other children + * in order to map them to apr_proc_other_child_read (which is not + * named well, it's more like a_p_o_c_died.) + * + * XXX: however - if we get a_p_o_c handle inheritance working, and + * the parent process creates other children and passes the pipes + * to our worker processes, then we have no business doing such + * things in the child_main loop, but should happen in master_main. + */ + while (1) { +#if !APR_HAS_OTHER_CHILD + rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, INFINITE); + cld = rv - WAIT_OBJECT_0; +#else + rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, 1000); + cld = rv - WAIT_OBJECT_0; + if (rv == WAIT_TIMEOUT) { + apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); + } + else +#endif + if (rv == WAIT_FAILED) { + /* Something serious is wrong */ + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: WAIT_FAILED -- shutting down server", my_pid); + break; + } + else if (cld == 0) { + /* Exit event was signaled */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Exit event signaled. Child process is ending.", my_pid); + break; + } + else { + /* MaxRequestsPerChild event set by the worker threads. + * Signal the parent to restart + */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Process exiting because it reached " + "MaxRequestsPerChild. Signaling the parent to " + "restart a new child process.", my_pid); + ap_signal_parent(SIGNAL_PARENT_RESTART); + break; + } + } + + /* + * Time to shutdown the child process + */ + + shutdown: + + winnt_mpm_state = AP_MPMQ_STOPPING; + /* Setting is_graceful will cause threads handling keep-alive connections + * to close the connection after handling the current request. + */ + is_graceful = 1; + + /* Close the listening sockets. Note, we must close the listeners + * before closing any accept sockets pending in AcceptEx to prevent + * memory leaks in the kernel. + */ + for (lr = ap_listeners; lr ; lr = lr->next) { + apr_socket_close(lr->sd); + } + + /* Shutdown listener threads and pending AcceptEx socksts + * but allow the worker threads to continue consuming from + * the queue of accepted connections. + */ + shutdown_in_progress = 1; + + Sleep(1000); + + /* Tell the worker threads to exit */ + workers_may_exit = 1; + + /* Release the start_mutex to let the new process (in the restart + * scenario) a chance to begin accepting and servicing requests + */ + rv = apr_proc_mutex_unlock(start_mutex); + if (rv == APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_NOTICE, rv, ap_server_conf, + "Child %d: Released the start mutex", my_pid); + } + else { + ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, + "Child %d: Failure releasing the start mutex", my_pid); + } + + /* Shutdown the worker threads */ + if (!use_acceptex) { + for (i = 0; i < threads_created; i++) { + add_job(INVALID_SOCKET); + } + } + else { /* Windows NT/2000 */ + /* Post worker threads blocked on the ThreadDispatch IOCompletion port */ + while (g_blocked_threads > 0) { + ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, ap_server_conf, + "Child %d: %d threads blocked on the completion port", my_pid, g_blocked_threads); + for (i=g_blocked_threads; i > 0; i--) { + PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_SHUTDOWN, NULL); + } + Sleep(1000); + } + /* Empty the accept queue of completion contexts */ + apr_thread_mutex_lock(qlock); + while (qhead) { + CloseHandle(qhead->Overlapped.hEvent); + closesocket(qhead->accept_socket); + qhead = qhead->next; + } + apr_thread_mutex_unlock(qlock); + } + + /* Give busy worker threads a chance to service their connections */ + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Waiting for %d worker threads to exit.", my_pid, threads_created); + end_time = time(NULL) + 180; + while (threads_created) { + rv = wait_for_many_objects(threads_created, child_handles, (DWORD)(end_time - time(NULL))); + if (rv != WAIT_TIMEOUT) { + rv = rv - WAIT_OBJECT_0; + ap_assert((rv >= 0) && (rv < threads_created)); + cleanup_thread(child_handles, &threads_created, rv); + continue; + } + break; + } + + /* Kill remaining threads off the hard way */ + if (threads_created) { + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Terminating %d threads that failed to exit.", + my_pid, threads_created); + } + for (i = 0; i < threads_created; i++) { + int *score_idx; + TerminateThread(child_handles[i], 1); + CloseHandle(child_handles[i]); + /* Reset the scoreboard entry for the thread we just whacked */ + score_idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE)); + ap_update_child_status_from_indexes(0, *score_idx, SERVER_DEAD, NULL); + } + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: All worker threads have exited.", my_pid); + + CloseHandle(allowed_globals.jobsemaphore); + apr_thread_mutex_destroy(allowed_globals.jobmutex); + apr_thread_mutex_destroy(child_lock); + + if (use_acceptex) { + apr_thread_mutex_destroy(qlock); + CloseHandle(qwait_event); + } + + apr_pool_destroy(pchild); + CloseHandle(exit_event); +} + +#endif /* def WIN32 */ diff --git a/trunk/server/mpm/winnt/mpm.h b/trunk/server/mpm/winnt/mpm.h new file mode 100644 index 0000000000..50417bb8bd --- /dev/null +++ b/trunk/server/mpm/winnt/mpm.h @@ -0,0 +1,40 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_H +#define APACHE_MPM_H + +/* mpm.h is the place to make declarations that are MPM specific but that must be + * shared with non-mpm specific code in the server. Hummm, perhaps we can + * move most of this stuff to mpm_common.h? + */ + +#include "scoreboard.h" + +#define MPM_NAME "WinNT" + +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE + +extern int ap_threads_per_child; +extern int ap_thread_limit; +extern server_rec *ap_server_conf; + +#endif /* APACHE_MPM_H */ diff --git a/trunk/server/mpm/winnt/mpm_default.h b/trunk/server/mpm/winnt/mpm_default.h new file mode 100644 index 0000000000..e70283de06 --- /dev/null +++ b/trunk/server/mpm/winnt/mpm_default.h @@ -0,0 +1,80 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Default limit on the maximum setting of the ThreadsPerChild configuration + * directive. This limit can be overridden with the ThreadLimit directive. + * This limit directly influences the amount of shared storage that is allocated + * for the scoreboard. DEFAULT_THREAD_LIMIT represents a good compromise + * between scoreboard size and the ability of the server to handle the most + * common installation requirements. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 1920 +#endif + +/* The ThreadLimit directive can be used to override the DEFAULT_THREAD_LIMIT. + * ThreadLimit cannot be tuned larger than MAX_THREAD_LIMIT. + * This is a sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 15000 +#endif + +/* Number of threads started in the child process in the absence + * of a ThreadsPerChild configuration directive + */ +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 64 +#endif + +/* Max number of child processes allowed. + */ +#define HARD_SERVER_LIMIT 1 + +/* Number of servers to spawn off by default + */ +#ifndef DEFAULT_NUM_DAEMON +#define DEFAULT_NUM_DAEMON 1 +#endif + +/* Check for definition of DEFAULT_REL_RUNTIMEDIR */ +#ifndef DEFAULT_REL_RUNTIMEDIR +#define DEFAULT_REL_RUNTIMEDIR "logs" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 0 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/winnt/mpm_winnt.c b/trunk/server/mpm/winnt/mpm_winnt.c new file mode 100644 index 0000000000..565edb3ac9 --- /dev/null +++ b/trunk/server/mpm/winnt/mpm_winnt.c @@ -0,0 +1,1724 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 + +#define CORE_PRIVATE +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "apr_portable.h" +#include "apr_thread_proc.h" +#include "apr_getopt.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_shm.h" +#include "apr_thread_mutex.h" +#include "ap_mpm.h" +#include "ap_config.h" +#include "ap_listen.h" +#include "mpm_default.h" +#include "mpm_winnt.h" +#include "mpm_common.h" +#include +#include "apr_atomic.h" + + +/* scoreboard.c does the heavy lifting; all we do is create the child + * score by moving a handle down the pipe into the child's stdin. + */ +extern apr_shm_t *ap_scoreboard_shm; +server_rec *ap_server_conf; + +/* Definitions of WINNT MPM specific config globals */ +static HANDLE shutdown_event; /* used to signal the parent to shutdown */ +static HANDLE restart_event; /* used to signal the parent to restart */ + +static char ap_coredump_dir[MAX_STRING_LEN]; + +static int one_process = 0; +static char const* signal_arg = NULL; + +OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */ + +static DWORD parent_pid; +DWORD my_pid; + +int ap_threads_per_child = 0; +int use_acceptex = 1; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit = 0; +static int changed_limit_at_restart; +int winnt_mpm_state = AP_MPMQ_STARTING; + +/* ap_my_generation are used by the scoreboard code */ +ap_generation_t volatile ap_my_generation=0; + + +/* shared by service.c as global, although + * perhaps it should be private. + */ +apr_pool_t *pconf; + + +/* definitions from child.c */ +void child_main(apr_pool_t *pconf); + +/* used by parent to signal the child to start and exit + * NOTE: these are not sophisticated enough for multiple children + * so they ultimately should not be shared with child.c + */ +extern apr_proc_mutex_t *start_mutex; +extern HANDLE exit_event; + + +/* Stub functions until this MPM supports the connection status API */ + +AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, \ + const char *value) +{ + /* NOP */ +} + +AP_DECLARE(void) ap_reset_connection_status(long conn_id) +{ + /* NOP */ +} + +AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p) +{ + /* NOP */ + return NULL; +} + +/* + * Command processors + */ + +static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_per_child = atoi(arg); + if (ap_threads_per_child > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " + "value of %d threads,", ap_threads_per_child, + thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadsPerChild to %d. To increase, please" + " see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + ap_threads_per_child = thread_limit; + } + else if (ap_threads_per_child < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadsPerChild > 0, setting to 1"); + ap_threads_per_child = 1; + } + return NULL; +} +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && + tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d threads,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} +static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy, char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + if (use_acceptex) { + use_acceptex = 0; + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, + "Disabled use of AcceptEx() WinSock2 API"); + } + return NULL; +} + +static const command_rec winnt_cmds[] = { +LISTEN_COMMANDS, +AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, + "Number of threads each child creates" ), +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum worker threads in a server for this run of Apache"), +AP_INIT_NO_ARGS("Win32DisableAcceptEx", set_disable_acceptex, NULL, RSRC_CONF, + "Disable use of the high performance AcceptEx WinSock2 API to work around buggy VPN or Firewall software"), + +{ NULL } +}; + + +/* + * Signalling Apache on NT. + * + * Under Unix, Apache can be told to shutdown or restart by sending various + * signals (HUP, USR, TERM). On NT we don't have easy access to signals, so + * we use "events" instead. The parent apache process goes into a loop + * where it waits forever for a set of events. Two of those events are + * called + * + * apPID_shutdown + * apPID_restart + * + * (where PID is the PID of the apache parent process). When one of these + * is signalled, the Apache parent performs the appropriate action. The events + * can become signalled through internal Apache methods (e.g. if the child + * finds a fatal error and needs to kill its parent), via the service + * control manager (the control thread will signal the shutdown event when + * requested to stop the Apache service), from the -k Apache command line, + * or from any external program which finds the Apache PID from the + * httpd.pid file. + * + * The signal_parent() function, below, is used to signal one of these events. + * It can be called by any child or parent process, since it does not + * rely on global variables. + * + * On entry, type gives the event to signal. 0 means shutdown, 1 means + * graceful restart. + */ +/* + * Initialise the signal names, in the global variables signal_name_prefix, + * signal_restart_name and signal_shutdown_name. + */ +#define MAX_SIGNAL_NAME 30 /* Long enough for apPID_shutdown, where PID is an int */ +char signal_name_prefix[MAX_SIGNAL_NAME]; +char signal_restart_name[MAX_SIGNAL_NAME]; +char signal_shutdown_name[MAX_SIGNAL_NAME]; +void setup_signal_names(char *prefix) +{ + apr_snprintf(signal_name_prefix, sizeof(signal_name_prefix), prefix); + apr_snprintf(signal_shutdown_name, sizeof(signal_shutdown_name), + "%s_shutdown", signal_name_prefix); + apr_snprintf(signal_restart_name, sizeof(signal_restart_name), + "%s_restart", signal_name_prefix); +} + +int volatile is_graceful = 0; + +AP_DECLARE(int) ap_graceful_stop_signalled(void) +{ + return is_graceful; +} + +AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type) +{ + HANDLE e; + char *signal_name; + + if (parent_pid == my_pid) { + switch(type) { + case SIGNAL_PARENT_SHUTDOWN: + { + SetEvent(shutdown_event); + break; + } + /* This MPM supports only graceful restarts right now */ + case SIGNAL_PARENT_RESTART: + case SIGNAL_PARENT_RESTART_GRACEFUL: + { + is_graceful = 1; + SetEvent(restart_event); + break; + } + } + return; + } + + switch(type) { + case SIGNAL_PARENT_SHUTDOWN: + { + signal_name = signal_shutdown_name; + break; + } + /* This MPM supports only graceful restarts right now */ + case SIGNAL_PARENT_RESTART: + case SIGNAL_PARENT_RESTART_GRACEFUL: + { + signal_name = signal_restart_name; + is_graceful = 1; + break; + } + default: + return; + } + + e = OpenEvent(EVENT_MODIFY_STATE, FALSE, signal_name); + if (!e) { + /* Um, problem, can't signal the parent, which means we can't + * signal ourselves to die. Ignore for now... + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf, + "OpenEvent on %s event", signal_name); + return; + } + if (SetEvent(e) == 0) { + /* Same problem as above */ + ap_log_error(APLOG_MARK, APLOG_EMERG, apr_get_os_error(), ap_server_conf, + "SetEvent on %s event", signal_name); + CloseHandle(e); + return; + } + CloseHandle(e); +} + + +/* + * Passed the following handles [in sync with send_handles_to_child()] + * + * ready event [signal the parent immediately, then close] + * exit event [save to poll later] + * start mutex [signal from the parent to begin accept()] + * scoreboard shm handle [to recreate the ap_scoreboard] + */ +void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event, + apr_proc_mutex_t **child_start_mutex, + apr_shm_t **scoreboard_shm) +{ + HANDLE pipe; + HANDLE hScore; + HANDLE ready_event; + HANDLE os_start; + DWORD BytesRead; + void *sb_shared; + apr_status_t rv; + + pipe = GetStdHandle(STD_INPUT_HANDLE); + if (!ReadFile(pipe, &ready_event, sizeof(HANDLE), + &BytesRead, (LPOVERLAPPED) NULL) + || (BytesRead != sizeof(HANDLE))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Unable to retrieve the ready event from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + + SetEvent(ready_event); + CloseHandle(ready_event); + + if (!ReadFile(pipe, child_exit_event, sizeof(HANDLE), + &BytesRead, (LPOVERLAPPED) NULL) + || (BytesRead != sizeof(HANDLE))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Unable to retrieve the exit event from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + + if (!ReadFile(pipe, &os_start, sizeof(os_start), + &BytesRead, (LPOVERLAPPED) NULL) + || (BytesRead != sizeof(os_start))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Unable to retrieve the start_mutex from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + *child_start_mutex = NULL; + if ((rv = apr_os_proc_mutex_put(child_start_mutex, &os_start, s->process->pool)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Child %d: Unable to access the start_mutex from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + + if (!ReadFile(pipe, &hScore, sizeof(hScore), + &BytesRead, (LPOVERLAPPED) NULL) + || (BytesRead != sizeof(hScore))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Child %d: Unable to retrieve the scoreboard from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + *scoreboard_shm = NULL; + if ((rv = apr_os_shm_put(scoreboard_shm, &hScore, s->process->pool)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Child %d: Unable to access the scoreboard from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + + rv = ap_reopen_scoreboard(s->process->pool, scoreboard_shm, 1); + if (rv || !(sb_shared = apr_shm_baseaddr_get(*scoreboard_shm))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "Child %d: Unable to reopen the scoreboard from the parent", my_pid); + exit(APEXIT_CHILDINIT); + } + /* We must 'initialize' the scoreboard to relink all the + * process-local pointer arrays into the shared memory block. + */ + ap_init_scoreboard(sb_shared); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Child %d: Retrieved our scoreboard from the parent.", my_pid); +} + + +static int send_handles_to_child(apr_pool_t *p, + HANDLE child_ready_event, + HANDLE child_exit_event, + apr_proc_mutex_t *child_start_mutex, + apr_shm_t *scoreboard_shm, + HANDLE hProcess, + apr_file_t *child_in) +{ + apr_status_t rv; + HANDLE hCurrentProcess = GetCurrentProcess(); + HANDLE hDup; + HANDLE os_start; + HANDLE hScore; + apr_size_t BytesWritten; + + if (!DuplicateHandle(hCurrentProcess, child_ready_event, hProcess, &hDup, + EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to duplicate the ready event handle for the child"); + return -1; + } + if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to send the exit event handle to the child"); + return -1; + } + if (!DuplicateHandle(hCurrentProcess, child_exit_event, hProcess, &hDup, + EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to duplicate the exit event handle for the child"); + return -1; + } + if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to send the exit event handle to the child"); + return -1; + } + if ((rv = apr_os_proc_mutex_get(&os_start, child_start_mutex)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to retrieve the start mutex for the child"); + return -1; + } + if (!DuplicateHandle(hCurrentProcess, os_start, hProcess, &hDup, + SYNCHRONIZE, FALSE, 0)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to duplicate the start mutex to the child"); + return -1; + } + if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to send the start mutex to the child"); + return -1; + } + if ((rv = apr_os_shm_get(&hScore, scoreboard_shm)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to retrieve the scoreboard handle for the child"); + return -1; + } + if (!DuplicateHandle(hCurrentProcess, hScore, hProcess, &hDup, + FILE_MAP_READ | FILE_MAP_WRITE, FALSE, 0)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Unable to duplicate the scoreboard handle to the child"); + return -1; + } + if ((rv = apr_file_write_full(child_in, &hDup, sizeof(hDup), &BytesWritten)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to send the scoreboard handle to the child"); + return -1; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Parent: Sent the scoreboard to the child"); + return 0; +} + + +/* + * get_listeners_from_parent() + * The listen sockets are opened in the parent. This function, which runs + * exclusively in the child process, receives them from the parent and + * makes them availeble in the child. + */ +void get_listeners_from_parent(server_rec *s) +{ + WSAPROTOCOL_INFO WSAProtocolInfo; + HANDLE pipe; + ap_listen_rec *lr; + DWORD BytesRead; + int lcnt = 0; + SOCKET nsd; + + /* Set up a default listener if necessary */ + if (ap_listeners == NULL) { + ap_listen_rec *lr; + lr = apr_palloc(s->process->pool, sizeof(ap_listen_rec)); + lr->sd = NULL; + lr->next = ap_listeners; + ap_listeners = lr; + } + + /* Open the pipe to the parent process to receive the inherited socket + * data. The sockets have been set to listening in the parent process. + */ + pipe = GetStdHandle(STD_INPUT_HANDLE); + + for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) { + if (!ReadFile(pipe, &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO), + &BytesRead, (LPOVERLAPPED) NULL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "setup_inherited_listeners: Unable to read socket data from parent"); + exit(APEXIT_CHILDINIT); + } + nsd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, + &WSAProtocolInfo, 0, 0); + if (nsd == INVALID_SOCKET) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, + "Child %d: setup_inherited_listeners(), WSASocket failed to open the inherited socket.", my_pid); + exit(APEXIT_CHILDINIT); + } + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + HANDLE hProcess = GetCurrentProcess(); + HANDLE dup; + if (DuplicateHandle(hProcess, (HANDLE) nsd, hProcess, &dup, + 0, FALSE, DUPLICATE_SAME_ACCESS)) { + closesocket(nsd); + nsd = (SOCKET) dup; + } + } + else { + /* A different approach. Many users report errors such as + * (32538)An operation was attempted on something that is not + * a socket. : Parent: WSADuplicateSocket failed... + * + * This appears that the duplicated handle is no longer recognized + * as a socket handle. SetHandleInformation should overcome that + * problem by not altering the handle identifier. But this won't + * work on 9x - it's unsupported. + */ + if (!SetHandleInformation((HANDLE)nsd, HANDLE_FLAG_INHERIT, 0)) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf, + "set_listeners_noninheritable: SetHandleInformation failed."); + } + } + apr_os_sock_put(&lr->sd, &nsd, s->process->pool); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Child %d: retrieved %d listeners from parent", my_pid, lcnt); +} + + +static int send_listeners_to_child(apr_pool_t *p, DWORD dwProcessId, + apr_file_t *child_in) +{ + apr_status_t rv; + int lcnt = 0; + ap_listen_rec *lr; + LPWSAPROTOCOL_INFO lpWSAProtocolInfo; + apr_size_t BytesWritten; + + /* Run the chain of open sockets. For each socket, duplicate it + * for the target process then send the WSAPROTOCOL_INFO + * (returned by dup socket) to the child. + */ + for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) { + apr_os_sock_t nsd; + lpWSAProtocolInfo = apr_pcalloc(p, sizeof(WSAPROTOCOL_INFO)); + apr_os_sock_get(&nsd,lr->sd); + ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, + "Parent: Duplicating socket %d and sending it to child process %d", + nsd, dwProcessId); + if (WSADuplicateSocket(nsd, dwProcessId, + lpWSAProtocolInfo) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_netos_error(), ap_server_conf, + "Parent: WSADuplicateSocket failed for socket %d. Check the FAQ.", lr->sd ); + return -1; + } + + if ((rv = apr_file_write_full(child_in, lpWSAProtocolInfo, + sizeof(WSAPROTOCOL_INFO), &BytesWritten)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to write duplicated socket %d to the child.", lr->sd ); + return -1; + } + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Parent: Sent %d listeners to child %d", lcnt, dwProcessId); + return 0; +} + +enum waitlist_e { + waitlist_ready = 0, + waitlist_term = 1 +}; + +static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_event, + DWORD *child_pid) +{ + /* These NEVER change for the lifetime of this parent + */ + static char **args = NULL; + static char **env = NULL; + static char pidbuf[28]; + + apr_status_t rv; + apr_pool_t *ptemp; + apr_procattr_t *attr; + apr_file_t *child_out; + apr_file_t *child_err; + apr_proc_t new_child; + HANDLE hExitEvent; + HANDLE waitlist[2]; /* see waitlist_e */ + char *cmd; + char *cwd; + + apr_pool_create_ex(&ptemp, p, NULL, NULL); + + /* Build the command line. Should look something like this: + * C:/apache/bin/apache.exe -f ap_server_confname + * First, get the path to the executable... + */ + apr_procattr_create(&attr, ptemp); + apr_procattr_cmdtype_set(attr, APR_PROGRAM); + apr_procattr_detach_set(attr, 1); + if (((rv = apr_filepath_get(&cwd, 0, ptemp)) != APR_SUCCESS) + || ((rv = apr_procattr_dir_set(attr, cwd)) != APR_SUCCESS)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Failed to get the current path"); + } + + if (!args) { + /* Build the args array, only once since it won't change + * for the lifetime of this parent process. + */ + if ((rv = ap_os_proc_filepath(&cmd, ptemp)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, ERROR_BAD_PATHNAME, ap_server_conf, + "Parent: Failed to get full path of %s", + ap_server_conf->process->argv[0]); + apr_pool_destroy(ptemp); + return -1; + } + + args = malloc((ap_server_conf->process->argc + 1) * sizeof (char*)); + memcpy(args + 1, ap_server_conf->process->argv + 1, + (ap_server_conf->process->argc - 1) * sizeof (char*)); + args[0] = malloc(strlen(cmd) + 1); + strcpy(args[0], cmd); + args[ap_server_conf->process->argc] = NULL; + } + else { + cmd = args[0]; + } + + /* Create a pipe to send handles to the child */ + if ((rv = apr_procattr_io_set(attr, APR_FULL_BLOCK, + APR_NO_PIPE, APR_NO_PIPE)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to create child stdin pipe."); + apr_pool_destroy(ptemp); + return -1; + } + + /* Open a null handle to soak info from the child */ + if (((rv = apr_file_open(&child_out, "NUL", APR_READ | APR_WRITE, + APR_OS_DEFAULT, ptemp)) != APR_SUCCESS) + || ((rv = apr_procattr_child_out_set(attr, child_out, NULL)) + != APR_SUCCESS)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to connect child stdout to NUL."); + apr_pool_destroy(ptemp); + return -1; + } + + /* Connect the child's initial stderr to our main server error log + * or share our own stderr handle. + */ + if (ap_server_conf->error_log) { + child_err = ap_server_conf->error_log; + } + else { + rv = apr_file_open_stderr(&child_err, ptemp); + } + if (rv == APR_SUCCESS) { + if ((rv = apr_procattr_child_err_set(attr, child_err, NULL)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Unable to connect child stderr."); + apr_pool_destroy(ptemp); + return -1; + } + } + + /* Create the child_ready_event */ + waitlist[waitlist_ready] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!waitlist[waitlist_ready]) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Could not create ready event for child process"); + apr_pool_destroy (ptemp); + return -1; + } + + /* Create the child_exit_event */ + hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!hExitEvent) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Could not create exit event for child process"); + apr_pool_destroy(ptemp); + CloseHandle(waitlist[waitlist_ready]); + return -1; + } + + if (!env) + { + /* Build the env array, only once since it won't change + * for the lifetime of this parent process. + */ + int envc; + for (envc = 0; _environ[envc]; ++envc) { + ; + } + env = malloc((envc + 2) * sizeof (char*)); + memcpy(env, _environ, envc * sizeof (char*)); + apr_snprintf(pidbuf, sizeof(pidbuf), "AP_PARENT_PID=%i", parent_pid); + env[envc] = pidbuf; + env[envc + 1] = NULL; + } + + rv = apr_proc_create(&new_child, cmd, args, env, attr, ptemp); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "Parent: Failed to create the child process."); + apr_pool_destroy(ptemp); + CloseHandle(hExitEvent); + CloseHandle(waitlist[waitlist_ready]); + CloseHandle(new_child.hproc); + return -1; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Parent: Created child process %d", new_child.pid); + + if (send_handles_to_child(ptemp, waitlist[waitlist_ready], hExitEvent, + start_mutex, ap_scoreboard_shm, + new_child.hproc, new_child.in)) { + /* + * This error is fatal, mop up the child and move on + * We toggle the child's exit event to cause this child + * to quit even as it is attempting to start. + */ + SetEvent(hExitEvent); + apr_pool_destroy(ptemp); + CloseHandle(hExitEvent); + CloseHandle(waitlist[waitlist_ready]); + CloseHandle(new_child.hproc); + return -1; + } + + /* Important: + * Give the child process a chance to run before dup'ing the sockets. + * We have already set the listening sockets noninheritable, but if + * WSADuplicateSocket runs before the child process initializes + * the listeners will be inherited anyway. + */ + waitlist[waitlist_term] = new_child.hproc; + rv = WaitForMultipleObjects(2, waitlist, FALSE, INFINITE); + CloseHandle(waitlist[waitlist_ready]); + if (rv != WAIT_OBJECT_0) { + /* + * Outch... that isn't a ready signal. It's dead, Jim! + */ + SetEvent(hExitEvent); + apr_pool_destroy(ptemp); + CloseHandle(hExitEvent); + CloseHandle(new_child.hproc); + return -1; + } + + if (send_listeners_to_child(ptemp, new_child.pid, new_child.in)) { + /* + * This error is fatal, mop up the child and move on + * We toggle the child's exit event to cause this child + * to quit even as it is attempting to start. + */ + SetEvent(hExitEvent); + apr_pool_destroy(ptemp); + CloseHandle(hExitEvent); + CloseHandle(new_child.hproc); + return -1; + } + + *child_exit_event = hExitEvent; + *child_proc = new_child.hproc; + *child_pid = new_child.pid; + + return 0; +} + +/*********************************************************************** + * master_main() + * master_main() runs in the parent process. It creates the child + * process which handles HTTP requests then waits on one of three + * events: + * + * restart_event + * ------------- + * The restart event causes master_main to start a new child process and + * tells the old child process to exit (by setting the child_exit_event). + * The restart event is set as a result of one of the following: + * 1. An apache -k restart command on the command line + * 2. A command received from Windows service manager which gets + * translated into an ap_signal_parent(SIGNAL_PARENT_RESTART) + * call by code in service.c. + * 3. The child process calling ap_signal_parent(SIGNAL_PARENT_RESTART) + * as a result of hitting MaxRequestsPerChild. + * + * shutdown_event + * -------------- + * The shutdown event causes master_main to tell the child process to + * exit and that the server is shutting down. The shutdown event is + * set as a result of one of the following: + * 1. An apache -k shutdown command on the command line + * 2. A command received from Windows service manager which gets + * translated into an ap_signal_parent(SIGNAL_PARENT_SHUTDOWN) + * call by code in service.c. + * + * child process handle + * -------------------- + * The child process handle will be signaled if the child process + * exits for any reason. In a normal running server, the signaling + * of this event means that the child process has exited prematurely + * due to a seg fault or other irrecoverable error. For server + * robustness, master_main will restart the child process under this + * condtion. + * + * master_main uses the child_exit_event to signal the child process + * to exit. + **********************************************************************/ +#define NUM_WAIT_HANDLES 3 +#define CHILD_HANDLE 0 +#define SHUTDOWN_HANDLE 1 +#define RESTART_HANDLE 2 +static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_event) +{ + int rv, cld; + int restart_pending; + int shutdown_pending; + HANDLE child_exit_event; + HANDLE event_handles[NUM_WAIT_HANDLES]; + DWORD child_pid; + + restart_pending = shutdown_pending = 0; + + event_handles[SHUTDOWN_HANDLE] = shutdown_event; + event_handles[RESTART_HANDLE] = restart_event; + + /* Create a single child process */ + rv = create_process(pconf, &event_handles[CHILD_HANDLE], + &child_exit_event, &child_pid); + if (rv < 0) + { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "master_main: create child process failed. Exiting."); + shutdown_pending = 1; + goto die_now; + } + if (!strcasecmp(signal_arg, "runservice")) { + mpm_service_started(); + } + + /* Update the scoreboard. Note that there is only a single active + * child at once. + */ + ap_scoreboard_image->parent[0].quiescing = 0; + ap_scoreboard_image->parent[0].pid = child_pid; + + /* Wait for shutdown or restart events or for child death */ + winnt_mpm_state = AP_MPMQ_RUNNING; + rv = WaitForMultipleObjects(NUM_WAIT_HANDLES, (HANDLE *) event_handles, FALSE, INFINITE); + cld = rv - WAIT_OBJECT_0; + if (rv == WAIT_FAILED) { + /* Something serious is wrong */ + ap_log_error(APLOG_MARK,APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "master_main: WaitForMultipeObjects WAIT_FAILED -- doing server shutdown"); + shutdown_pending = 1; + } + else if (rv == WAIT_TIMEOUT) { + /* Hey, this cannot happen */ + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, + "master_main: WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT"); + shutdown_pending = 1; + } + else if (cld == SHUTDOWN_HANDLE) { + /* shutdown_event signalled */ + shutdown_pending = 1; + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, s, + "Parent: Received shutdown signal -- Shutting down the server."); + if (ResetEvent(shutdown_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, + "ResetEvent(shutdown_event)"); + } + } + else if (cld == RESTART_HANDLE) { + /* Received a restart event. Prepare the restart_event to be reused + * then signal the child process to exit. + */ + restart_pending = 1; + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, + "Parent: Received restart signal -- Restarting the server."); + if (ResetEvent(restart_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, + "Parent: ResetEvent(restart_event) failed."); + } + if (SetEvent(child_exit_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, + "Parent: SetEvent for child process %d failed.", + event_handles[CHILD_HANDLE]); + } + /* Don't wait to verify that the child process really exits, + * just move on with the restart. + */ + CloseHandle(event_handles[CHILD_HANDLE]); + event_handles[CHILD_HANDLE] = NULL; + } + else { + /* The child process exited prematurely due to a fatal error. */ + DWORD exitcode; + if (!GetExitCodeProcess(event_handles[CHILD_HANDLE], &exitcode)) { + /* HUH? We did exit, didn't we? */ + exitcode = APEXIT_CHILDFATAL; + } + if ( exitcode == APEXIT_CHILDFATAL + || exitcode == APEXIT_CHILDINIT + || exitcode == APEXIT_INIT) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, + "Parent: child process exited with status %u -- Aborting.", exitcode); + shutdown_pending = 1; + } + else { + int i; + restart_pending = 1; + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Parent: child process exited with status %u -- Restarting.", exitcode); + for (i = 0; i < ap_threads_per_child; i++) { + ap_update_child_status_from_indexes(0, i, SERVER_DEAD, NULL); + } + } + CloseHandle(event_handles[CHILD_HANDLE]); + event_handles[CHILD_HANDLE] = NULL; + } + if (restart_pending) { + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + } +die_now: + if (shutdown_pending) + { + int timeout = 30000; /* Timeout is milliseconds */ + winnt_mpm_state = AP_MPMQ_STOPPING; + + /* This shutdown is only marginally graceful. We will give the + * child a bit of time to exit gracefully. If the time expires, + * the child will be wacked. + */ + if (!strcasecmp(signal_arg, "runservice")) { + mpm_service_stopping(); + } + /* Signal the child processes to exit */ + if (SetEvent(child_exit_event) == 0) { + ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), ap_server_conf, + "Parent: SetEvent for child process %d failed", event_handles[CHILD_HANDLE]); + } + if (event_handles[CHILD_HANDLE]) { + rv = WaitForSingleObject(event_handles[CHILD_HANDLE], timeout); + if (rv == WAIT_OBJECT_0) { + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Parent: Child process exited successfully."); + CloseHandle(event_handles[CHILD_HANDLE]); + event_handles[CHILD_HANDLE] = NULL; + } + else { + ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Parent: Forcing termination of child process %d ", event_handles[CHILD_HANDLE]); + TerminateProcess(event_handles[CHILD_HANDLE], 1); + CloseHandle(event_handles[CHILD_HANDLE]); + event_handles[CHILD_HANDLE] = NULL; + } + } + return 0; /* Tell the caller we do not want to restart */ + } + winnt_mpm_state = AP_MPMQ_STARTING; + return 1; /* Tell the caller we want a restart */ +} + +/* service_nt_main_fn needs to append the StartService() args + * outside of our call stack and thread as the service starts... + */ +apr_array_header_t *mpm_new_argv; + +/* Remember service_to_start failures to log and fail in pre_config. + * Remember inst_argc and inst_argv for installing or starting the + * service after we preflight the config. + */ + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = MAXIMUM_WAIT_OBJECTS; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_NOT_SUPPORTED; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = HARD_SERVER_LIMIT; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_per_child; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = winnt_mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +#define SERVICE_UNSET (-1) +static apr_status_t service_set = SERVICE_UNSET; +static apr_status_t service_to_start_success; +static int inst_argc; +static const char * const *inst_argv; +static char *service_name = NULL; + +void winnt_rewrite_args(process_rec *process) +{ + /* Handle the following SCM aspects in this phase: + * + * -k runservice [transition for WinNT, nothing for Win9x] + * -k install + * -k config + * -k uninstall + * -k stop + * -k shutdown (same as -k stop). Maintained for backward compatability. + * + * We can't leave this phase until we know our identity + * and modify the command arguments appropriately. + * + * We do not care if the .conf file exists or is parsable when + * attempting to stop or uninstall a service. + */ + apr_status_t rv; + char *def_server_root; + char *binpath; + char optbuf[3]; + const char *optarg; + int fixed_args; + char *pid; + apr_getopt_t *opt; + int running_as_service = 1; + int errout = 0; + + pconf = process->pconf; + + osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osver); + + /* AP_PARENT_PID is only valid in the child */ + pid = getenv("AP_PARENT_PID"); + if (pid) + { + /* This is the child */ + my_pid = GetCurrentProcessId(); + parent_pid = (DWORD) atol(pid); + + /* Prevent holding open the (nonexistant) console */ + ap_real_exit_code = 0; + + /* The parent is responsible for providing the + * COMPLETE ARGUMENTS REQUIRED to the child. + * + * No further argument parsing is needed, but + * for good measure we will provide a simple + * signal string for later testing. + */ + signal_arg = "runchild"; + return; + } + + /* This is the parent, we have a long way to go :-) */ + parent_pid = my_pid = GetCurrentProcessId(); + + /* This behavior is voided by setting real_exit_code to 0 */ + atexit(hold_console_open_on_error); + + /* Rewrite process->argv[]; + * + * strip out -k signal into signal_arg + * strip out -n servicename and set the names + * add default -d serverroot from the path of this executable + * + * The end result will look like: + * + * The invocation command (%0) + * The -d serverroot default from the running executable + * The requested service's (-n) registry ConfigArgs + * The WinNT SCM's StartService() args + */ + if ((rv = ap_os_proc_filepath(&binpath, process->pconf)) + != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_CRIT, rv, NULL, + "Failed to get the full path of %s", process->argv[0]); + exit(APEXIT_INIT); + } + /* WARNING: There is an implict assumption here that the + * executable resides in ServerRoot or ServerRoot\bin + */ + def_server_root = (char *) apr_filepath_name_get(binpath); + if (def_server_root > binpath) { + *(def_server_root - 1) = '\0'; + def_server_root = (char *) apr_filepath_name_get(binpath); + if (!strcasecmp(def_server_root, "bin")) + *(def_server_root - 1) = '\0'; + } + apr_filepath_merge(&def_server_root, NULL, binpath, + APR_FILEPATH_TRUENAME, process->pool); + + /* Use process->pool so that the rewritten argv + * lasts for the lifetime of the server process, + * because pconf will be destroyed after the + * initial pre-flight of the config parser. + */ + mpm_new_argv = apr_array_make(process->pool, process->argc + 2, + sizeof(const char *)); + *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; + *(const char **)apr_array_push(mpm_new_argv) = "-d"; + *(const char **)apr_array_push(mpm_new_argv) = def_server_root; + + fixed_args = mpm_new_argv->nelts; + + optbuf[0] = '-'; + optbuf[2] = '\0'; + apr_getopt_init(&opt, process->pool, process->argc, (char**) process->argv); + opt->errfn = NULL; + while ((rv = apr_getopt(opt, "wn:k:" AP_SERVER_BASEARGS, + optbuf + 1, &optarg)) == APR_SUCCESS) { + switch (optbuf[1]) { + + /* Shortcuts; include the -w option to hold the window open on error. + * This must not be toggled once we reset ap_real_exit_code to 0! + */ + case 'w': + if (ap_real_exit_code) + ap_real_exit_code = 2; + break; + + case 'n': + service_set = mpm_service_set_name(process->pool, &service_name, + optarg); + break; + + case 'k': + signal_arg = optarg; + break; + + case 'E': + errout = 1; + /* Fall through so the Apache main() handles the 'E' arg */ + default: + *(const char **)apr_array_push(mpm_new_argv) = + apr_pstrdup(process->pool, optbuf); + + if (optarg) { + *(const char **)apr_array_push(mpm_new_argv) = optarg; + } + break; + } + } + + /* back up to capture the bad argument */ + if (rv == APR_BADCH || rv == APR_BADARG) { + opt->ind--; + } + + while (opt->ind < opt->argc) { + *(const char **)apr_array_push(mpm_new_argv) = + apr_pstrdup(process->pool, opt->argv[opt->ind++]); + } + + /* Track the number of args actually entered by the user */ + inst_argc = mpm_new_argv->nelts - fixed_args; + + /* Provide a default 'run' -k arg to simplify signal_arg tests */ + if (!signal_arg) + { + signal_arg = "run"; + running_as_service = 0; + } + + if (!strcasecmp(signal_arg, "runservice")) + { + /* Start the NT Service _NOW_ because the WinNT SCM is + * expecting us to rapidly assume control of our own + * process, the SCM will tell us our service name, and + * may have extra StartService() command arguments to + * add for us. + * + * The SCM will generally invoke the executable with + * the c:\win\system32 default directory. This is very + * lethal if folks use ServerRoot /foopath on windows + * without a drive letter. Change to the default root + * (path to apache root, above /bin) for safety. + */ + apr_filepath_set(def_server_root, process->pool); + + /* Any other process has a console, so we don't to begin + * a Win9x service until the configuration is parsed and + * any command line errors are reported. + * + * We hold the return value so that we can die in pre_config + * after logging begins, and the failure can land in the log. + */ + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + if (!errout) { + mpm_nt_eventlog_stderr_open(service_name, process->pool); + } + service_to_start_success = mpm_service_to_start(&service_name, + process->pool); + if (service_to_start_success == APR_SUCCESS) { + service_set = APR_SUCCESS; + } + } + } + + /* Get the default for any -k option, except run */ + if (service_set == SERVICE_UNSET && strcasecmp(signal_arg, "run")) { + service_set = mpm_service_set_name(process->pool, &service_name, + AP_DEFAULT_SERVICE_NAME); + } + + if (!strcasecmp(signal_arg, "install")) /* -k install */ + { + if (service_set == APR_SUCCESS) + { + ap_log_error(APLOG_MARK,APLOG_ERR, 0, NULL, + "%s: Service is already installed.", service_name); + exit(APEXIT_INIT); + } + } + else if (running_as_service) + { + if (service_set == APR_SUCCESS) + { + /* Attempt to Uninstall, or stop, before + * we can read the arguments or .conf files + */ + if (!strcasecmp(signal_arg, "uninstall")) { + rv = mpm_service_uninstall(); + exit(rv); + } + + if ((!strcasecmp(signal_arg, "stop")) || + (!strcasecmp(signal_arg, "shutdown"))) { + mpm_signal_service(process->pool, 0); + exit(0); + } + + rv = mpm_merge_service_args(process->pool, mpm_new_argv, + fixed_args); + if (rv == APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_INFO, 0, NULL, + "Using ConfigArgs of the installed service " + "\"%s\".", service_name); + } + else { + ap_log_error(APLOG_MARK,APLOG_WARNING, rv, NULL, + "No installed ConfigArgs for the service " + "\"%s\", using Apache defaults.", service_name); + } + } + else + { + ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL, + "No installed service named \"%s\".", service_name); + exit(APEXIT_INIT); + } + } + if (strcasecmp(signal_arg, "install") && service_set && service_set != SERVICE_UNSET) + { + ap_log_error(APLOG_MARK,APLOG_ERR, service_set, NULL, + "No installed service named \"%s\".", service_name); + exit(APEXIT_INIT); + } + + /* Track the args actually entered by the user. + * These will be used for the -k install parameters, as well as + * for the -k start service override arguments. + */ + inst_argv = (const char * const *)mpm_new_argv->elts + + mpm_new_argv->nelts - inst_argc; + + /* Now, do service install or reconfigure then proceed to + * post_config to test the installed configuration. + */ + if (!strcasecmp(signal_arg, "config")) { /* -k config */ + /* Reconfigure the service */ + rv = mpm_service_install(process->pool, inst_argc, inst_argv, 1); + if (rv != APR_SUCCESS) { + exit(rv); + } + + fprintf(stderr,"Testing httpd.conf....\n"); + fprintf(stderr,"Errors reported here must be corrected before the " + "service can be started.\n"); + } + else if (!strcasecmp(signal_arg, "install")) { /* -k install */ + /* Install the service */ + rv = mpm_service_install(process->pool, inst_argc, inst_argv, 0); + if (rv != APR_SUCCESS) { + exit(rv); + } + + fprintf(stderr,"Testing httpd.conf....\n"); + fprintf(stderr,"Errors reported here must be corrected before the " + "service can be started.\n"); + } + + process->argc = mpm_new_argv->nelts; + process->argv = (const char * const *) mpm_new_argv->elts; +} + + +static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *ptemp) +{ + /* Handle the following SCM aspects in this phase: + * + * -k runservice [WinNT errors logged from rewrite_args] + */ + + /* Initialize shared static objects. + * TODO: Put config related statics into an sconf structure. + */ + pconf = pconf_; + + if (ap_exists_config_define("ONE_PROCESS") || + ap_exists_config_define("DEBUG")) + one_process = -1; + + if (!strcasecmp(signal_arg, "runservice") + && (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + && (service_to_start_success != APR_SUCCESS)) { + ap_log_error(APLOG_MARK,APLOG_CRIT, service_to_start_success, NULL, + "%s: Unable to start the service manager.", + service_name); + exit(APEXIT_INIT); + } + + /* Win9x: disable AcceptEx */ + if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + use_acceptex = 0; + } + + ap_listen_pre_config(); + ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; + ap_pid_fname = DEFAULT_PIDLOG; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + /* use_acceptex which is enabled by default is not available on Win9x. + */ + if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + use_acceptex = 0; + } + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec* s) +{ + static int restart_num = 0; + apr_status_t rv = 0; + + /* Handle the following SCM aspects in this phase: + * + * -k install (catch and exit as install was handled in rewrite_args) + * -k config (catch and exit as config was handled in rewrite_args) + * -k start + * -k restart + * -k runservice [Win95, only once - after we parsed the config] + * + * because all of these signals are useful _only_ if there + * is a valid conf\httpd.conf environment to start. + * + * We reached this phase by avoiding errors that would cause + * these options to fail unexpectedly in another process. + */ + + if (!strcasecmp(signal_arg, "install")) { + /* Service install happens in the rewrite_args hooks. If we + * made it this far, the server configuration is clean and the + * service will successfully start. + */ + apr_pool_destroy(s->process->pool); + apr_terminate(); + exit(0); + } + if (!strcasecmp(signal_arg, "config")) { + /* Service reconfiguration happens in the rewrite_args hooks. If we + * made it this far, the server configuration is clean and the + * service will successfully start. + */ + apr_pool_destroy(s->process->pool); + apr_terminate(); + exit(0); + } + + if (!strcasecmp(signal_arg, "start")) { + ap_listen_rec *lr; + + /* Close the listening sockets. */ + for (lr = ap_listeners; lr; lr = lr->next) { + apr_socket_close(lr->sd); + lr->active = 0; + } + rv = mpm_service_start(ptemp, inst_argc, inst_argv); + apr_pool_destroy(s->process->pool); + apr_terminate(); + exit (rv); + } + + if (!strcasecmp(signal_arg, "restart")) { + mpm_signal_service(ptemp, 1); + apr_pool_destroy(s->process->pool); + apr_terminate(); + exit (rv); + } + + if (parent_pid == my_pid) + { + if (restart_num++ == 1) + { + /* This code should be run once in the parent and not run + * across a restart + */ + PSECURITY_ATTRIBUTES sa = GetNullACL(); /* returns NULL if invalid (Win95?) */ + setup_signal_names(apr_psprintf(pconf,"ap%d", parent_pid)); + + ap_log_pid(pconf, ap_pid_fname); + + /* Create shutdown event, apPID_shutdown, where PID is the parent + * Apache process ID. Shutdown is signaled by 'apache -k shutdown'. + */ + shutdown_event = CreateEvent(sa, FALSE, FALSE, signal_shutdown_name); + if (!shutdown_event) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Cannot create shutdown event %s", signal_shutdown_name); + CleanNullACL((void *)sa); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Create restart event, apPID_restart, where PID is the parent + * Apache process ID. Restart is signaled by 'apache -k restart'. + */ + restart_event = CreateEvent(sa, FALSE, FALSE, signal_restart_name); + if (!restart_event) { + CloseHandle(shutdown_event); + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, + "Parent: Cannot create restart event %s", signal_restart_name); + CleanNullACL((void *)sa); + return HTTP_INTERNAL_SERVER_ERROR; + } + CleanNullACL((void *)sa); + + /* Now that we are flying at 15000 feet... + * wipe out the Win95 service console, + * signal the SCM the WinNT service started, or + * if not a service, setup console handlers instead. + */ + if (!strcasecmp(signal_arg, "runservice")) + { + if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT) + { + rv = mpm_service_to_start(&service_name, + s->process->pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, + "%s: Unable to start the service manager.", + service_name); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + } + else /* ! -k runservice */ + { + mpm_start_console_handler(); + } + + /* Create the start mutex, as an unnamed object for security. + * Ths start mutex is used during a restart to prevent more than + * one child process from entering the accept loop at once. + */ + rv = apr_proc_mutex_create(&start_mutex, NULL, + APR_LOCK_DEFAULT, + ap_server_conf->process->pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, + "%s: Unable to create the start_mutex.", + service_name); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + } + else /* parent_pid != my_pid */ + { + mpm_start_child_console_handler(); + } + return OK; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int winnt_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + /* Initialize shared static objects. + */ + ap_server_conf = s; + + if (parent_pid != my_pid) { + return OK; + } + + /* We cannot initialize our listeners if we are restarting + * (the parent process already has glomed on to them) + * nor should we do so for service reconfiguration + * (since the service may already be running.) + */ + if (!strcasecmp(signal_arg, "restart") + || !strcasecmp(signal_arg, "config")) { + return OK; + } + + if (ap_setup_listeners(s) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + return OK; +} + +static void winnt_child_init(apr_pool_t *pchild, struct server_rec *s) +{ + apr_status_t rv; + + setup_signal_names(apr_psprintf(pchild,"ap%d", parent_pid)); + + /* This is a child process, not in single process mode */ + if (!one_process) { + /* Set up events and the scoreboard */ + get_handles_from_parent(s, &exit_event, &start_mutex, + &ap_scoreboard_shm); + + /* Set up the listeners */ + get_listeners_from_parent(s); + + ap_my_generation = ap_scoreboard_image->global->running_generation; + } + else { + /* Single process mode - this lock doesn't even need to exist */ + rv = apr_proc_mutex_create(&start_mutex, signal_name_prefix, + APR_LOCK_DEFAULT, s->process->pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, + "%s child %d: Unable to init the start_mutex.", + service_name, my_pid); + exit(APEXIT_CHILDINIT); + } + + /* Borrow the shutdown_even as our _child_ loop exit event */ + exit_event = shutdown_event; + } +} + + +AP_DECLARE(int) ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) +{ + static int restart = 0; /* Default is "not a restart" */ + + if (!restart) { + first_thread_limit = thread_limit; + } + + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, APR_SUCCESS, ap_server_conf, + "WARNING: Attempt to change ThreadLimit ignored " + "during restart"); + changed_limit_at_restart = 0; + } + + /* ### If non-graceful restarts are ever introduced - we need to rerun + * the pre_mpm hook on subsequent non-graceful restarts. But Win32 + * has only graceful style restarts - and we need this hook to act + * the same on Win32 as on Unix. + */ + if (!restart && ((parent_pid == my_pid) || one_process)) { + /* Set up the scoreboard. */ + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + return 1; + } + } + + if ((parent_pid != my_pid) || one_process) + { + /* The child process or in one_process (debug) mode + */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Child process is running", my_pid); + + child_main(pconf); + + ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, + "Child %d: Child process is exiting", my_pid); + return 1; + } + else + { + /* A real-honest to goodness parent */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); + + restart = master_main(ap_server_conf, shutdown_event, restart_event); + + if (!restart) + { + /* Shutting down. Clean up... */ + const char *pidfile = ap_server_root_relative (pconf, ap_pid_fname); + + if (pidfile != NULL && unlink(pidfile) == 0) { + ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, + ap_server_conf, "removed PID file %s (pid=%ld)", + pidfile, GetCurrentProcessId()); + } + apr_proc_mutex_destroy(start_mutex); + + CloseHandle(restart_event); + CloseHandle(shutdown_event); + + return 1; + } + } + + return 0; /* Restart */ +} + +static void winnt_hooks(apr_pool_t *p) +{ + /* The prefork open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + + ap_hook_pre_config(winnt_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(winnt_post_config, NULL, NULL, 0); + ap_hook_child_init(winnt_child_init, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_open_logs(winnt_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); +} + +AP_MODULE_DECLARE_DATA module mpm_winnt_module = { + MPM20_MODULE_STUFF, + winnt_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + winnt_cmds, /* command apr_table_t */ + winnt_hooks /* register_hooks */ +}; + +#endif /* def WIN32 */ diff --git a/trunk/server/mpm/winnt/mpm_winnt.h b/trunk/server/mpm/winnt/mpm_winnt.h new file mode 100644 index 0000000000..dce956c39a --- /dev/null +++ b/trunk/server/mpm/winnt/mpm_winnt.h @@ -0,0 +1,121 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_WINNT_H +#define APACHE_MPM_WINNT_H + +#include "ap_listen.h" + +/* From service.c: */ + +#define SERVICE_APACHE_RESTART 128 + +#ifndef AP_DEFAULT_SERVICE_NAME +#define AP_DEFAULT_SERVICE_NAME "Apache2" +#endif + +#define SERVICECONFIG9X "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices" +#define SERVICECONFIG "System\\CurrentControlSet\\Services\\%s" +#define SERVICEPARAMS "System\\CurrentControlSet\\Services\\%s\\Parameters" + +apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, + const char *set_name); +apr_status_t mpm_merge_service_args(apr_pool_t *p, apr_array_header_t *args, + int fixed_args); + +apr_status_t mpm_service_to_start(const char **display_name, apr_pool_t *p); +apr_status_t mpm_service_started(void); +apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, + char const* const* argv, int reconfig); +apr_status_t mpm_service_uninstall(void); + +apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, + char const* const* argv); + +void mpm_signal_service(apr_pool_t *ptemp, int signal); + +void mpm_service_stopping(void); + +void mpm_start_console_handler(void); +void mpm_start_child_console_handler(void); + +/* From nt_eventlog.c: */ + +void mpm_nt_eventlog_stderr_open(char *display_name, apr_pool_t *p); +void mpm_nt_eventlog_stderr_flush(void); + +/* From winnt.c: */ + +extern int use_acceptex; +extern int winnt_mpm_state; +extern OSVERSIONINFO osver; +extern void clean_child_exit(int); + +void setup_signal_names(char *prefix); + +typedef enum { + SIGNAL_PARENT_SHUTDOWN, + SIGNAL_PARENT_RESTART, + SIGNAL_PARENT_RESTART_GRACEFUL +} ap_signal_parent_e; +AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type); + +/* + * The Windoes MPM uses a queue of completion contexts that it passes + * between the accept threads and the worker threads. Declare the + * functions to access the queue and the structures passed on the + * queue in the header file to enable modules to access them + * if necessary. The queue resides in the MPM. + */ +#ifdef CONTAINING_RECORD +#undef CONTAINING_RECORD +#endif +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (PCHAR)(address) - \ + (PCHAR)(&((type *)0)->field))) +#if APR_HAVE_IPV6 +#define PADDED_ADDR_SIZE (sizeof(SOCKADDR_IN6)+16) +#else +#define PADDED_ADDR_SIZE (sizeof(SOCKADDR_IN)+16) +#endif + +typedef struct CompContext { + struct CompContext *next; + OVERLAPPED Overlapped; + apr_socket_t *sock; + SOCKET accept_socket; + char buff[2*PADDED_ADDR_SIZE]; + struct sockaddr *sa_server; + int sa_server_len; + struct sockaddr *sa_client; + int sa_client_len; + apr_pool_t *ptrans; + apr_bucket_alloc_t *ba; + short socket_family; +} COMP_CONTEXT, *PCOMP_CONTEXT; + +typedef enum { + IOCP_CONNECTION_ACCEPTED = 1, + IOCP_WAIT_FOR_RECEIVE = 2, + IOCP_WAIT_FOR_TRANSMITFILE = 3, + IOCP_SHUTDOWN = 4 +} io_state_e; + +PCOMP_CONTEXT mpm_get_completion_context(void); +void mpm_recycle_completion_context(PCOMP_CONTEXT pCompContext); +apr_status_t mpm_post_completion_context(PCOMP_CONTEXT pCompContext, io_state_e state); +void hold_console_open_on_error(void); +#endif /* APACHE_MPM_WINNT_H */ diff --git a/trunk/server/mpm/winnt/nt_eventlog.c b/trunk/server/mpm/winnt/nt_eventlog.c new file mode 100644 index 0000000000..1bfedb383c --- /dev/null +++ b/trunk/server/mpm/winnt/nt_eventlog.c @@ -0,0 +1,189 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE + +#include "httpd.h" +#include "http_log.h" +#include "mpm_winnt.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "ap_regkey.h" + +static char *display_name = NULL; +static HANDLE stderr_thread = NULL; +static HANDLE stderr_ready; + +static DWORD WINAPI service_stderr_thread(LPVOID hPipe) +{ + HANDLE hPipeRead = (HANDLE) hPipe; + HANDLE hEventSource; + char errbuf[256]; + char *errmsg = errbuf; + const char *errarg[9]; + DWORD errres; + ap_regkey_t *regkey; + apr_status_t rv; + apr_pool_t *p; + + apr_pool_create_ex(&p, NULL, NULL, NULL); + + errarg[0] = "The Apache service named"; + errarg[1] = display_name; + errarg[2] = "reported the following error:\r\n>>>"; + errarg[3] = errbuf; + errarg[4] = NULL; + errarg[5] = NULL; + errarg[6] = NULL; + errarg[7] = NULL; + errarg[8] = NULL; + + /* What are we going to do in here, bail on the user? not. */ + if ((rv = ap_regkey_open(®key, AP_REGKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\" + "EventLog\\Application\\Apache Service", + APR_READ | APR_WRITE | APR_CREATE, p)) + == APR_SUCCESS) + { + DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | + EVENTLOG_INFORMATION_TYPE; + + /* The stock message file */ + ap_regkey_value_set(regkey, "EventMessageFile", + "%SystemRoot%\\System32\\netmsg.dll", + AP_REGKEY_EXPAND, p); + + ap_regkey_value_raw_set(regkey, "TypesSupported", &dwData, + sizeof(dwData), REG_DWORD, p); + ap_regkey_close(regkey); + } + + hEventSource = RegisterEventSourceW(NULL, L"Apache Service"); + + SetEvent(stderr_ready); + + while (ReadFile(hPipeRead, errmsg, 1, &errres, NULL) && (errres == 1)) + { + if ((errmsg > errbuf) || !apr_isspace(*errmsg)) + { + ++errmsg; + if ((*(errmsg - 1) == '\n') + || (errmsg >= errbuf + sizeof(errbuf) - 1)) + { + while ((errmsg > errbuf) && apr_isspace(*(errmsg - 1))) { + --errmsg; + } + *errmsg = '\0'; + + /* Generic message: '%1 %2 %3 %4 %5 %6 %7 %8 %9' + * The event code in netmsg.dll is 3299 + */ + ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, + 3299, NULL, 9, 0, errarg, NULL); + errmsg = errbuf; + } + } + } + + if ((errres = GetLastError()) != ERROR_BROKEN_PIPE) { + apr_snprintf(errbuf, sizeof(errbuf), + "Win32 error %d reading stderr pipe stream\r\n", + GetLastError()); + + ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, + 3299, NULL, 9, 0, errarg, NULL); + } + + CloseHandle(hPipeRead); + DeregisterEventSource(hEventSource); + CloseHandle(stderr_thread); + stderr_thread = NULL; + apr_pool_destroy(p); + return 0; +} + + +void mpm_nt_eventlog_stderr_flush(void) +{ + HANDLE cleanup_thread = stderr_thread; + + if (cleanup_thread) { + HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE); + fclose(stderr); + CloseHandle(hErr); + WaitForSingleObject(cleanup_thread, 30000); + CloseHandle(cleanup_thread); + } +} + + +void mpm_nt_eventlog_stderr_open(char *argv0, apr_pool_t *p) +{ + SECURITY_ATTRIBUTES sa; + HANDLE hProc = GetCurrentProcess(); + HANDLE hPipeRead = NULL; + HANDLE hPipeWrite = NULL; + HANDLE hDup = NULL; + DWORD threadid; + int fd; + + display_name = argv0; + + /* Create a pipe to send stderr messages to the system error log. + * + * _dup2() duplicates the write handle inheritable for us. + */ + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = FALSE; + CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0); + ap_assert(hPipeRead && hPipeWrite); + + stderr_ready = CreateEvent(NULL, FALSE, FALSE, NULL); + stderr_thread = CreateThread(NULL, 0, service_stderr_thread, + (LPVOID) hPipeRead, 0, &threadid); + ap_assert(stderr_ready && stderr_thread); + + WaitForSingleObject(stderr_ready, INFINITE); + + /* Flush stderr and unset its buffer, then commit and replace stderr. + * This is typically a noop for Win2K/XP since services with NULL std + * handles [but valid FILE *'s, oddly enough], but is required + * for NT 4.0 and to use this code outside of services. + */ + fflush(stderr); + setvbuf(stderr, NULL, _IONBF, 0); + _commit(2 /* stderr */); + fd = _open_osfhandle((long) hPipeWrite, + _O_WRONLY | _O_BINARY); + _dup2(fd, 2); + _close(fd); + _setmode(2, _O_BINARY); + + /* hPipeWrite was _close()'ed above, and _dup2()'ed + * to fd 2 creating a new, inherited Win32 handle. + * Recover that real handle from fd 2. + */ + hPipeWrite = (HANDLE)_get_osfhandle(2); + + SetStdHandle(STD_ERROR_HANDLE, hPipeWrite); + + /* The code above _will_ corrupt the StdHandle... + * and we must do so anyways. We set this up only + * after we initialized the posix stderr API. + */ + ap_open_stderr_log(p); +} diff --git a/trunk/server/mpm/winnt/service.c b/trunk/server/mpm/winnt/service.c new file mode 100644 index 0000000000..4d24891146 --- /dev/null +++ b/trunk/server/mpm/winnt/service.c @@ -0,0 +1,1346 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This module ALONE requires the window message API from user.h + * and the default APR include of windows.h will omit it, so + * preload the API symbols now... + */ + +#define CORE_PRIVATE +#define _WINUSER_ + +#include "httpd.h" +#include "http_log.h" +#include "mpm_winnt.h" +#include "apr_strings.h" +#include "apr_lib.h" +#include "ap_regkey.h" + +#ifdef NOUSER +#undef NOUSER +#endif +#undef _WINUSER_ +#include + +static char *mpm_service_name = NULL; +static char *mpm_display_name = NULL; + +static struct +{ + HANDLE mpm_thread; /* primary thread handle of the apache server */ + HANDLE service_thread; /* thread service/monitor handle */ + DWORD service_thread_id;/* thread service/monitor ID */ + HANDLE service_init; /* controller thread init mutex */ + HANDLE service_term; /* NT service thread kill signal */ + SERVICE_STATUS ssStatus; + SERVICE_STATUS_HANDLE hServiceStatus; +} globdat; + +static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); + + +#define PRODREGKEY "SOFTWARE\\" AP_SERVER_BASEVENDOR "\\" \ + AP_SERVER_BASEPRODUCT "\\" AP_SERVER_BASEREVISION + +/* + * Get the server root from the registry into 'dir' which is + * size bytes long. Returns 0 if the server root was found + * or if the serverroot key does not exist (in which case + * dir will contain an empty string), or -1 if there was + * an error getting the key. + */ +apr_status_t ap_registry_get_server_root(apr_pool_t *p, char **buf) +{ + apr_status_t rv; + ap_regkey_t *key; + + if ((rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, PRODREGKEY, + APR_READ, p)) == APR_SUCCESS) { + rv = ap_regkey_value_get(buf, key, "ServerRoot", p); + ap_regkey_close(key); + if (rv == APR_SUCCESS) + return rv; + } + + if ((rv = ap_regkey_open(&key, AP_REGKEY_CURRENT_USER, PRODREGKEY, + APR_READ, p)) == APR_SUCCESS) { + rv = ap_regkey_value_get(buf, key, "ServerRoot", p); + ap_regkey_close(key); + if (rv == APR_SUCCESS) + return rv; + } + + *buf = NULL; + return rv; +} + + +/* The service configuration's is stored under the following trees: + * + * HKLM\System\CurrentControlSet\Services\[service name] + * + * \DisplayName + * \ImagePath + * \Parameters\ConfigArgs + * + * For Win9x, the launch service command is stored under: + * + * HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices\[service name] + */ + + +/* exit() for Win32 is macro mapped (horrible, we agree) that allows us + * to catch the non-zero conditions and inform the console process that + * the application died, and hang on to the console a bit longer. + * + * The macro only maps for http_main.c and other sources that include + * the service.h header, so we best assume it's an error to exit from + * _any_ other module. + * + * If ap_real_exit_code is reset to 0, it will not be set or trigger this + * behavior on exit. All service and child processes are expected to + * reset this flag to zero to avoid undesireable side effects. + */ +AP_DECLARE_DATA int ap_real_exit_code = 1; + +void hold_console_open_on_error(void) +{ + HANDLE hConIn; + HANDLE hConErr; + DWORD result; + time_t start; + time_t remains; + char *msg = "Note the errors or messages above, " + "and press the key to exit. "; + CONSOLE_SCREEN_BUFFER_INFO coninfo; + INPUT_RECORD in; + char count[16]; + + if (!ap_real_exit_code) + return; + hConIn = GetStdHandle(STD_INPUT_HANDLE); + hConErr = GetStdHandle(STD_ERROR_HANDLE); + if ((hConIn == INVALID_HANDLE_VALUE) || (hConErr == INVALID_HANDLE_VALUE)) + return; + if (!WriteConsole(hConErr, msg, (DWORD)strlen(msg), &result, NULL) || !result) + return; + if (!GetConsoleScreenBufferInfo(hConErr, &coninfo)) + return; + if (!SetConsoleMode(hConIn, ENABLE_MOUSE_INPUT | 0x80)) + return; + + start = time(NULL); + do + { + while (PeekConsoleInput(hConIn, &in, 1, &result) && result) + { + if (!ReadConsoleInput(hConIn, &in, 1, &result) || !result) + return; + if ((in.EventType == KEY_EVENT) && in.Event.KeyEvent.bKeyDown + && (in.Event.KeyEvent.uChar.AsciiChar == 27)) + return; + if (in.EventType == MOUSE_EVENT + && (in.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)) + return; + } + remains = ((start + 30) - time(NULL)); + sprintf (count, "%d...", remains); + if (!SetConsoleCursorPosition(hConErr, coninfo.dwCursorPosition)) + return; + if (!WriteConsole(hConErr, count, (DWORD)strlen(count), &result, NULL) + || !result) + return; + } + while ((remains > 0) && WaitForSingleObject(hConIn, 1000) != WAIT_FAILED); +} + +static BOOL die_on_logoff = FALSE; + +static LRESULT CALLBACK monitor_service_9x_proc(HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ +/* This is the WndProc procedure for our invisible window. + * When the user shuts down the system, this window is sent + * a signal WM_ENDSESSION. We clean up by signaling Apache + * to shut down, and idle until Apache's primary thread quits. + */ + if ((msg == WM_ENDSESSION) + && (die_on_logoff || (lParam != ENDSESSION_LOGOFF))) + { + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + if (wParam) + /* Don't leave this message until we are dead! */ + WaitForSingleObject(globdat.mpm_thread, 30000); + return 0; + } + return (DefWindowProc(hWnd, msg, wParam, lParam)); +} + +static DWORD WINAPI monitor_service_9x_thread(void *service_name) +{ + /* When running as a service under Windows 9x, there is no console + * window present, and no ConsoleCtrlHandler to call when the system + * is shutdown. If the WatchWindow thread is created with a NULL + * service_name argument, then the ...SystemMonitor window class is + * used to create the "Apache" window to watch for logoff and shutdown. + * If the service_name is provided, the ...ServiceMonitor window class + * is used to create the window named by the service_name argument, + * and the logoff message is ignored. + */ + WNDCLASS wc; + HWND hwndMain; + MSG msg; + + wc.style = CS_GLOBALCLASS; + wc.lpfnWndProc = monitor_service_9x_proc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = NULL; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + if (service_name) + wc.lpszClassName = "ApacheWin95ServiceMonitor"; + else + wc.lpszClassName = "ApacheWin95SystemMonitor"; + + die_on_logoff = service_name ? FALSE : TRUE; + + if (!RegisterClass(&wc)) + { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), + NULL, "Could not register window class for WatchWindow"); + globdat.service_thread_id = 0; + return 0; + } + + /* Create an invisible window */ + hwndMain = CreateWindow(wc.lpszClassName, + service_name ? (char *) service_name : "Apache", + WS_OVERLAPPEDWINDOW & ~WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, NULL, NULL, NULL, NULL); + + if (!hwndMain) + { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), + NULL, "Could not create WatchWindow"); + globdat.service_thread_id = 0; + return 0; + } + + /* If we succeed, eliminate the console window. + * Signal the parent we are all set up, and + * watch the message queue while the window lives. + */ + FreeConsole(); + SetEvent(globdat.service_init); + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (msg.message == WM_CLOSE) + DestroyWindow(hwndMain); + else { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + globdat.service_thread_id = 0; + return 0; +} + + +static BOOL CALLBACK console_control_handler(DWORD ctrl_type) +{ + switch (ctrl_type) + { + case CTRL_BREAK_EVENT: + fprintf(stderr, "Apache server restarting...\n"); + ap_signal_parent(SIGNAL_PARENT_RESTART); + return TRUE; + case CTRL_C_EVENT: + fprintf(stderr, "Apache server interrupted...\n"); + /* for Interrupt signals, shut down the server. + * Tell the system we have dealt with the signal + * without waiting for Apache to terminate. + */ + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + return TRUE; + + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + /* for Terminate signals, shut down the server. + * Wait for Apache to terminate, but respond + * after a reasonable time to tell the system + * that we did attempt to shut ourself down. + * THESE EVENTS WILL NOT OCCUR UNDER WIN9x! + */ + fprintf(stderr, "Apache server shutdown initiated...\n"); + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + Sleep(30000); + return TRUE; + } + + /* We should never get here, but this is (mostly) harmless */ + return FALSE; +} + + +static void stop_console_handler(void) +{ + SetConsoleCtrlHandler(console_control_handler, FALSE); +} + + +void mpm_start_console_handler(void) +{ + SetConsoleCtrlHandler(console_control_handler, TRUE); + atexit(stop_console_handler); +} + + +/* Special situation - children of services need to mind their + * P's & Q's and wait quietly, ignoring the mean OS signaling + * shutdown and other horrors, to kill them gracefully... + */ + +static BOOL CALLBACK child_control_handler(DWORD ctrl_type) +{ + switch (ctrl_type) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + /* for Interrupt signals, ignore them. + * The system will also signal the parent process, + * which will terminate Apache. + */ + return TRUE; + + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + /* for Shutdown signals, ignore them, but... . + * The system will also signal the parent process, + * which will terminate Apache, so we need to wait. + */ + Sleep(30000); + return TRUE; + } + + /* We should never get here, but this is (mostly) harmless */ + return FALSE; +} + + +static void stop_child_console_handler(void) +{ + SetConsoleCtrlHandler(child_control_handler, FALSE); +} + + +void mpm_start_child_console_handler(void) +{ + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { + FreeConsole(); + } + else + { + SetConsoleCtrlHandler(child_control_handler, TRUE); + atexit(stop_child_console_handler); + } +} + + +/********************************** + WinNT service control management + **********************************/ + +static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint) +{ + static int checkPoint = 1; + int rv = APR_SUCCESS; + + if (globdat.hServiceStatus) + { + if (currentState == SERVICE_RUNNING) { + globdat.ssStatus.dwWaitHint = 0; + globdat.ssStatus.dwCheckPoint = 0; + globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + } + else if (currentState == SERVICE_STOPPED) { + globdat.ssStatus.dwWaitHint = 0; + globdat.ssStatus.dwCheckPoint = 0; + if (!exitCode && globdat.ssStatus.dwCurrentState + != SERVICE_STOP_PENDING) { + /* An unexpected exit? Better to error! */ + exitCode = 1; + } + if (exitCode) { + globdat.ssStatus.dwWin32ExitCode =ERROR_SERVICE_SPECIFIC_ERROR; + globdat.ssStatus.dwServiceSpecificExitCode = exitCode; + } + } + else { + globdat.ssStatus.dwCheckPoint = ++checkPoint; + globdat.ssStatus.dwControlsAccepted = 0; + if(waitHint) + globdat.ssStatus.dwWaitHint = waitHint; + } + + globdat.ssStatus.dwCurrentState = currentState; + + rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus); + } + return(rv); +} + +/* Set the service description regardless of platform. + * We revert to set_service_description on NT/9x, the + * very long way so any Apache management program can grab the + * description. This would be bad on Win2000, since it wouldn't + * notify the service control manager of the name change. + */ + +/* borrowed from mpm_winnt.c */ +extern apr_pool_t *pconf; + +/* Windows 2000 alone supports ChangeServiceConfig2 in order to + * register our server_version string... so we need some fixups + * to avoid binding to that function if we are on WinNT/9x. + */ +static void set_service_description(void) +{ + const char *full_description; + SC_HANDLE schSCManager; + BOOL ret = 0; + + /* Nothing to do if we are a console + */ + if (!mpm_service_name) + return; + + /* Time to fix up the description, upon each successful restart + */ + full_description = ap_get_server_version(); + + if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + && (osver.dwMajorVersion > 4) + && (ChangeServiceConfig2) + && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) + { + SC_HANDLE schService = OpenService(schSCManager, mpm_service_name, + SERVICE_CHANGE_CONFIG); + if (schService) { + /* Cast is necessary, ChangeServiceConfig2 handles multiple + * object types, some volatile, some not. + */ + /* ###: utf-ize */ + if (ChangeServiceConfig2(schService, + 1 /* SERVICE_CONFIG_DESCRIPTION */, + (LPVOID) &full_description)) { + full_description = NULL; + } + CloseServiceHandle(schService); + } + CloseServiceHandle(schSCManager); + } + + if (full_description) + { + char szPath[MAX_PATH]; + ap_regkey_t *svckey; + apr_status_t rv; + + /* Find the Service key that Monitor Applications iterate */ + apr_snprintf(szPath, sizeof(szPath), + "SYSTEM\\CurrentControlSet\\Services\\%s", + mpm_service_name); + rv = ap_regkey_open(&svckey, AP_REGKEY_LOCAL_MACHINE, szPath, + APR_READ | APR_WRITE, pconf); + if (rv != APR_SUCCESS) { + return; + } + /* Attempt to set the Description value for our service */ + ap_regkey_value_set(svckey, "Description", full_description, 0, pconf); + ap_regkey_close(svckey); + } +} + +/* handle the SCM's ControlService() callbacks to our service */ + +static VOID WINAPI service_nt_ctrl(DWORD dwCtrlCode) +{ + if (dwCtrlCode == SERVICE_CONTROL_STOP) + { + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 30000); + return; + } + if (dwCtrlCode == SERVICE_APACHE_RESTART) + { + ap_signal_parent(SIGNAL_PARENT_RESTART); + ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); + return; + } + + ReportStatusToSCMgr(globdat.ssStatus.dwCurrentState, NO_ERROR, 0); +} + + +/* service_nt_main_fn is outside of the call stack and outside of the + * primary server thread... so now we _really_ need a placeholder! + * The winnt_rewrite_args has created and shared mpm_new_argv with us. + */ +extern apr_array_header_t *mpm_new_argv; + +/* ###: utf-ize */ +static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) +{ + const char *ignored; + + /* args and service names live in the same pool */ + mpm_service_set_name(mpm_new_argv->pool, &ignored, argv[0]); + + memset(&globdat.ssStatus, 0, sizeof(globdat.ssStatus)); + globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; + globdat.ssStatus.dwCheckPoint = 1; + + /* ###: utf-ize */ + if (!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], service_nt_ctrl))) + { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), + NULL, "Failure registering service handler"); + return; + } + + /* Report status, no errors, and buy 3 more seconds */ + ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); + + /* We need to append all the command arguments passed via StartService() + * to our running service... which just got here via the SCM... + * but we hvae no interest in argv[0] for the mpm_new_argv list. + */ + if (argc > 1) + { + char **cmb_data; + + mpm_new_argv->nalloc = mpm_new_argv->nelts + argc - 1; + cmb_data = malloc(mpm_new_argv->nalloc * sizeof(const char *)); + + /* mpm_new_argv remains first (of lower significance) */ + memcpy (cmb_data, mpm_new_argv->elts, + mpm_new_argv->elt_size * mpm_new_argv->nelts); + + /* Service args follow from StartService() invocation */ + memcpy (cmb_data + mpm_new_argv->nelts, argv + 1, + mpm_new_argv->elt_size * (argc - 1)); + + /* The replacement arg list is complete */ + mpm_new_argv->elts = (char *)cmb_data; + mpm_new_argv->nelts = mpm_new_argv->nalloc; + } + + /* Let the main thread continue now... but hang on to the + * signal_monitor event so we can take further action + */ + SetEvent(globdat.service_init); + + WaitForSingleObject(globdat.service_term, INFINITE); +} + + +DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) +{ + apr_status_t rv = APR_SUCCESS; + + SERVICE_TABLE_ENTRY dispatchTable[] = + { + { "", service_nt_main_fn }, + { NULL, NULL } + }; + + /* ###: utf-ize */ + if (!StartServiceCtrlDispatcher(dispatchTable)) + { + /* This is a genuine failure of the SCM. */ + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "Error starting service control dispatcher"); + } + + return (rv); +} + + +apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, + const char *set_name) +{ + char key_name[MAX_PATH]; + ap_regkey_t *key; + apr_status_t rv; + + /* ### Needs improvement, on Win2K the user can _easily_ + * change the display name to a string that doesn't reflect + * the internal service name + whitespace! + */ + mpm_service_name = apr_palloc(p, strlen(set_name) + 1); + apr_collapse_spaces((char*) mpm_service_name, set_name); + apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); + if (rv == APR_SUCCESS) { + rv = ap_regkey_value_get(&mpm_display_name, key, "DisplayName", pconf); + ap_regkey_close(key); + } + if (rv != APR_SUCCESS) { + /* Take the given literal name if there is no service entry */ + mpm_display_name = apr_pstrdup(p, set_name); + } + *display_name = mpm_display_name; + return rv; +} + + +apr_status_t mpm_merge_service_args(apr_pool_t *p, + apr_array_header_t *args, + int fixed_args) +{ + apr_array_header_t *svc_args = NULL; + char conf_key[MAX_PATH]; + char **cmb_data; + apr_status_t rv; + ap_regkey_t *key; + + apr_snprintf(conf_key, sizeof(conf_key), SERVICEPARAMS, mpm_service_name); + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, conf_key, APR_READ, p); + if (rv == APR_SUCCESS) { + rv = ap_regkey_value_array_get(&svc_args, key, "ConfigArgs", p); + ap_regkey_close(key); + } + if (rv != APR_SUCCESS) { + if (rv == ERROR_FILE_NOT_FOUND) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, + "No ConfigArgs registered for %s, perhaps " + "this service is not installed?", + mpm_service_name); + return APR_SUCCESS; + } + else + return (rv); + } + + if (!svc_args || svc_args->nelts == 0) { + return (APR_SUCCESS); + } + + /* Now we have the mpm_service_name arg, and the mpm_runservice_nt() + * call appended the arguments passed by StartService(), so it's + * time to _prepend_ the default arguments for the server from + * the service's default arguments (all others override them)... + */ + args->nalloc = args->nelts + svc_args->nelts; + cmb_data = malloc(args->nalloc * sizeof(const char *)); + + /* First three args (argv[0], -f, path) remain first */ + memcpy(cmb_data, args->elts, args->elt_size * fixed_args); + + /* Service args follow from service registry array */ + memcpy(cmb_data + fixed_args, svc_args->elts, + svc_args->elt_size * svc_args->nelts); + + /* Remaining new args follow */ + memcpy(cmb_data + fixed_args + svc_args->nelts, + (const char **)args->elts + fixed_args, + args->elt_size * (args->nelts - fixed_args)); + + args->elts = (char *)cmb_data; + args->nelts = args->nalloc; + + return APR_SUCCESS; +} + + +void service_stopped(void) +{ + /* Still have a thread & window to clean up, so signal now */ + if (globdat.service_thread) + { + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + /* Stop logging to the event log */ + mpm_nt_eventlog_stderr_flush(); + + /* Cause the service_nt_main_fn to complete */ + ReleaseMutex(globdat.service_term); + + ReportStatusToSCMgr(SERVICE_STOPPED, // service state + NO_ERROR, // exit code + 0); // wait hint + } + else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ + { + RegisterServiceProcess(0, 0); + PostThreadMessage(globdat.service_thread_id, WM_CLOSE, 0, 0); + } + + WaitForSingleObject(globdat.service_thread, 5000); + CloseHandle(globdat.service_thread); + } +} + + +apr_status_t mpm_service_to_start(const char **display_name, apr_pool_t *p) +{ + HANDLE hProc = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + HANDLE waitfor[2]; + + /* Prevent holding open the (hidden) console */ + ap_real_exit_code = 0; + + /* GetCurrentThread returns a psuedo-handle, we need + * a real handle for another thread to wait upon. + */ + if (!DuplicateHandle(hProc, hThread, hProc, &(globdat.mpm_thread), + 0, FALSE, DUPLICATE_SAME_ACCESS)) { + return APR_ENOTHREAD; + } + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); + globdat.service_term = CreateMutex(NULL, TRUE, NULL); + if (!globdat.service_init || !globdat.service_term) { + return APR_EGENERAL; + } + + globdat.service_thread = CreateThread(NULL, 0, service_nt_dispatch_thread, + NULL, 0, &globdat.service_thread_id); + } + else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ + { + if (!RegisterServiceProcess(0, 1)) + return GetLastError(); + + globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!globdat.service_init) { + return APR_EGENERAL; + } + + globdat.service_thread = CreateThread(NULL, 0, monitor_service_9x_thread, + (LPVOID) mpm_service_name, 0, + &globdat.service_thread_id); + } + + if (!globdat.service_thread) { + return APR_ENOTHREAD; + } + + waitfor[0] = globdat.service_init; + waitfor[1] = globdat.service_thread; + + /* Wait for controlling thread init or termination */ + if (WaitForMultipleObjects(2, waitfor, FALSE, 10000) != WAIT_OBJECT_0) { + return APR_ENOTHREAD; + } + + atexit(service_stopped); + *display_name = mpm_display_name; + return APR_SUCCESS; +} + + +apr_status_t mpm_service_started(void) +{ + set_service_description(); + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + ReportStatusToSCMgr(SERVICE_RUNNING, // service state + NO_ERROR, // exit code + 0); // wait hint + } + return APR_SUCCESS; +} + + +void mpm_service_stopping(void) +{ + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + ReportStatusToSCMgr(SERVICE_STOP_PENDING, // service state + NO_ERROR, // exit code + 30000); // wait hint +} + + +apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, + const char * const * argv, int reconfig) +{ + char key_name[MAX_PATH]; + char exe_path[MAX_PATH]; + char *launch_cmd; + ap_regkey_t *key; + apr_status_t rv; + + fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" + : "Installing the %s service\n", mpm_display_name); + + /* ###: utf-ize */ + if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) + { + apr_status_t rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "GetModuleFileName failed"); + return rv; + } + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ + SC_MANAGER_CREATE_SERVICE); + if (!schSCManager) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "Failed to open the WinNT service manager"); + return (rv); + } + + launch_cmd = apr_psprintf(ptemp, "\"%s\" -k runservice", exe_path); + + if (reconfig) { + /* ###: utf-ize */ + schService = OpenService(schSCManager, mpm_service_name, + SERVICE_CHANGE_CONFIG); + if (!schService) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, + apr_get_os_error(), NULL, + "OpenService failed"); + } + /* ###: utf-ize */ + else if (!ChangeServiceConfig(schService, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + launch_cmd, NULL, NULL, + "Tcpip\0Afd\0", NULL, NULL, + mpm_display_name)) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, + apr_get_os_error(), NULL, + "ChangeServiceConfig failed"); + /* !schService aborts configuration below */ + CloseServiceHandle(schService); + schService = NULL; + } + } + else { + /* RPCSS is the Remote Procedure Call (RPC) Locator required + * for DCOM communication pipes. I am far from convinced we + * should add this to the default service dependencies, but + * be warned that future apache modules or ISAPI dll's may + * depend on it. + */ + /* ###: utf-ize */ + schService = CreateService(schSCManager, // SCManager database + mpm_service_name, // name of service + mpm_display_name, // name to display + SERVICE_ALL_ACCESS, // access required + SERVICE_WIN32_OWN_PROCESS, // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + launch_cmd, // service's binary + NULL, // no load svc group + NULL, // no tag identifier + "Tcpip\0Afd\0", // dependencies + NULL, // use SYSTEM account + NULL); // no password + + if (!schService) + { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "Failed to create WinNT Service Profile"); + CloseServiceHandle(schSCManager); + return (rv); + } + } + + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + } + else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ + { + /* Store the launch command in the registry */ + launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", + exe_path, mpm_service_name); + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, SERVICECONFIG9X, + APR_READ | APR_WRITE | APR_CREATE, pconf); + if (rv == APR_SUCCESS) { + rv = ap_regkey_value_set(key, mpm_service_name, + launch_cmd, 0, pconf); + ap_regkey_close(key); + } + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to add the RunServices registry entry.", + mpm_display_name); + return (rv); + } + + apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, + APR_READ | APR_WRITE | APR_CREATE, pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to create the registry service key.", + mpm_display_name); + return (rv); + } + rv = ap_regkey_value_set(key, "ImagePath", launch_cmd, 0, pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to store ImagePath in the registry.", + mpm_display_name); + ap_regkey_close(key); + return (rv); + } + rv = ap_regkey_value_set(key, "DisplayName", + mpm_display_name, 0, pconf); + ap_regkey_close(key); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to store DisplayName in the registry.", + mpm_display_name); + return (rv); + } + } + + set_service_description(); + + /* For both WinNT & Win9x store the service ConfigArgs in the registry... + */ + apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, mpm_service_name); + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, + APR_READ | APR_WRITE | APR_CREATE, pconf); + if (rv == APR_SUCCESS) { + rv = ap_regkey_value_array_set(key, "ConfigArgs", argc, argv, pconf); + ap_regkey_close(key); + } + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to store the ConfigArgs in the registry.", + mpm_display_name); + return (rv); + } + fprintf(stderr,"The %s service is successfully installed.\n", mpm_display_name); + return APR_SUCCESS; +} + + +apr_status_t mpm_service_uninstall(void) +{ + char key_name[MAX_PATH]; + apr_status_t rv; + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + SC_HANDLE schService; + SC_HANDLE schSCManager; + + fprintf(stderr,"Removing the %s service\n", mpm_display_name); + + schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ + SC_MANAGER_CONNECT); + if (!schSCManager) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "Failed to open the WinNT service manager."); + return (rv); + } + + /* ###: utf-ize */ + schService = OpenService(schSCManager, mpm_service_name, DELETE); + + if (!schService) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: OpenService failed", mpm_display_name); + return (rv); + } + + /* assure the service is stopped before continuing + * + * This may be out of order... we might not be able to be + * granted all access if the service is running anyway. + * + * And do we want to make it *this easy* for them + * to uninstall their service unintentionally? + */ + // ap_stop_service(schService); + + if (DeleteService(schService) == 0) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to delete the service.", mpm_display_name); + return (rv); + } + + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + } + else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ + { + apr_status_t rv2, rv3; + ap_regkey_t *key; + fprintf(stderr,"Removing the %s service\n", mpm_display_name); + + /* TODO: assure the service is stopped before continuing */ + + rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, SERVICECONFIG9X, + APR_READ | APR_WRITE | APR_CREATE, pconf); + if (rv == APR_SUCCESS) { + rv = ap_regkey_value_remove(key, mpm_service_name, pconf); + ap_regkey_close(key); + } + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to remove the RunServices registry " + "entry.", mpm_display_name); + } + + /* we blast Services/us, not just the Services/us/Parameters branch */ + apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, mpm_service_name); + rv2 = ap_regkey_remove(AP_REGKEY_LOCAL_MACHINE, key_name, pconf); + apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); + rv3 = ap_regkey_remove(AP_REGKEY_LOCAL_MACHINE, key_name, pconf); + rv2 = (rv2 != APR_SUCCESS) ? rv2 : rv3; + if (rv2 != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv2, NULL, + "%s: Failed to remove the service config from the " + "registry.", mpm_display_name); + } + rv = (rv != APR_SUCCESS) ? rv : rv2; + if (rv != APR_SUCCESS) + return rv; + } + fprintf(stderr,"The %s service has been removed successfully.\n", mpm_display_name); + return APR_SUCCESS; +} + + +/* signal_service_transition is a simple thunk to signal the service + * and monitor its successful transition. If the signal passed is 0, + * then the caller is assumed to already have performed some service + * operation to be monitored (such as StartService), and no actual + * ControlService signal is sent. + */ + +static int signal_service_transition(SC_HANDLE schService, DWORD signal, DWORD pending, DWORD complete) +{ + if (signal && !ControlService(schService, signal, &globdat.ssStatus)) + return FALSE; + + do { + Sleep(1000); + if (!QueryServiceStatus(schService, &globdat.ssStatus)) + return FALSE; + } while (globdat.ssStatus.dwCurrentState == pending); + + return (globdat.ssStatus.dwCurrentState == complete); +} + + +apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, + const char * const * argv) +{ + apr_status_t rv; + + fprintf(stderr,"Starting the %s service\n", mpm_display_name); + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + char **start_argv; + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ + SC_MANAGER_CONNECT); + if (!schSCManager) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "Failed to open the WinNT service manager"); + return (rv); + } + + /* ###: utf-ize */ + schService = OpenService(schSCManager, mpm_service_name, + SERVICE_START | SERVICE_QUERY_STATUS); + if (!schService) { + rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "%s: Failed to open the service.", mpm_display_name); + CloseServiceHandle(schSCManager); + return (rv); + } + + if (QueryServiceStatus(schService, &globdat.ssStatus) + && (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING)) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL, + "Service %s is already started!", mpm_display_name); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return 0; + } + + start_argv = malloc((argc + 1) * sizeof(const char **)); + memcpy(start_argv, argv, argc * sizeof(const char **)); + start_argv[argc] = NULL; + + rv = APR_EINIT; + /* ###: utf-ize */ + if (StartService(schService, argc, start_argv) + && signal_service_transition(schService, 0, /* test only */ + SERVICE_START_PENDING, + SERVICE_RUNNING)) + rv = APR_SUCCESS; + + if (rv != APR_SUCCESS) + rv = apr_get_os_error(); + + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + } + else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ + { + STARTUPINFO si; /* Filled in prior to call to CreateProcess */ + PROCESS_INFORMATION pi; /* filled in on call to CreateProcess */ + char exe_path[MAX_PATH]; + char exe_cmd[MAX_PATH * 4]; + char *next_arg; + int i; + + /* Locate the active top level window named service_name + * provided the class is ApacheWin95ServiceMonitor + */ + if (FindWindow("ApacheWin95ServiceMonitor", mpm_service_name)) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL, + "Service %s is already started!", mpm_display_name); + return 0; + } + + /* This may not appear intuitive, but Win9x will not allow a process + * to detach from the console without releasing the entire console. + * Ergo, we must spawn a new process for the service to get back our + * console window. + * The config is pre-flighted, so there should be no danger of failure. + */ + + if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) + { + apr_status_t rv = apr_get_os_error(); + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, + "GetModuleFileName failed"); + return rv; + } + + apr_snprintf(exe_cmd, sizeof(exe_cmd), + "\"%s\" -n %s -k runservice", + exe_path, mpm_service_name); + next_arg = strchr(exe_cmd, '\0'); + for (i = 0; i < argc; ++i) { + apr_snprintf(next_arg, sizeof(exe_cmd) - (next_arg - exe_cmd), + " \"%s\"", argv[i]); + next_arg = strchr(exe_cmd, '\0'); + } + + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; /* This might be redundant */ + + rv = APR_EINIT; + if (CreateProcess(NULL, exe_cmd, NULL, NULL, FALSE, + DETACHED_PROCESS, /* Creation flags */ + NULL, NULL, &si, &pi)) + { + DWORD code; + while (GetExitCodeProcess(pi.hProcess, &code) == STILL_ACTIVE) { + if (FindWindow("ApacheWin95ServiceMonitor", mpm_service_name)) { + rv = APR_SUCCESS; + break; + } + Sleep (1000); + } + } + + if (rv != APR_SUCCESS) + rv = apr_get_os_error(); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + if (rv == APR_SUCCESS) + fprintf(stderr,"The %s service is running.\n", mpm_display_name); + else + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "%s: Failed to start the service process.", + mpm_display_name); + + return rv; +} + + +/* signal is zero to stop, non-zero for restart */ + +void mpm_signal_service(apr_pool_t *ptemp, int signal) +{ + int success = FALSE; + + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, NULL, // default machine & database + SC_MANAGER_CONNECT); + + if (!schSCManager) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, + "Failed to open the NT Service Manager"); + return; + } + + /* ###: utf-ize */ + schService = OpenService(schSCManager, mpm_service_name, + SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | + SERVICE_USER_DEFINED_CONTROL | + SERVICE_START | SERVICE_STOP); + + if (schService == NULL) { + /* Could not open the service */ + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, + "Failed to open the %s Service", mpm_display_name); + CloseServiceHandle(schSCManager); + return; + } + + if (!QueryServiceStatus(schService, &globdat.ssStatus)) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, + "Query of Service %s failed", mpm_display_name); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return; + } + + if (!signal && (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED)) { + fprintf(stderr,"The %s service is not started.\n", mpm_display_name); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return; + } + + fprintf(stderr,"The %s service is %s.\n", mpm_display_name, + signal ? "restarting" : "stopping"); + + if (!signal) + success = signal_service_transition(schService, + SERVICE_CONTROL_STOP, + SERVICE_STOP_PENDING, + SERVICE_STOPPED); + else if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) { + mpm_service_start(ptemp, 0, NULL); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return; + } + else + success = signal_service_transition(schService, + SERVICE_APACHE_RESTART, + SERVICE_START_PENDING, + SERVICE_RUNNING); + + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + } + else /* !isWindowsNT() */ + { + DWORD service_pid; + HANDLE hwnd; + char prefix[20]; + /* Locate the active top level window named service_name + * provided the class is ApacheWin95ServiceMonitor + */ + hwnd = FindWindow("ApacheWin95ServiceMonitor", mpm_service_name); + if (hwnd && GetWindowThreadProcessId(hwnd, &service_pid)) + globdat.ssStatus.dwCurrentState = SERVICE_RUNNING; + else + { + globdat.ssStatus.dwCurrentState = SERVICE_STOPPED; + if (!signal) { + fprintf(stderr,"The %s service is not started.\n", mpm_display_name); + return; + } + } + + fprintf(stderr,"The %s service is %s.\n", mpm_display_name, + signal ? "restarting" : "stopping"); + + apr_snprintf(prefix, sizeof(prefix), "ap%ld", (long)service_pid); + setup_signal_names(prefix); + + if (!signal) + { + int ticks = 60; + ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); + while (--ticks) + { + if (!IsWindow(hwnd)) { + success = TRUE; + break; + } + Sleep(1000); + } + } + else /* !stop */ + { + /* TODO: Aught to add a little test to the restart logic, and + * store the restart counter in the window's user dword. + * Then we can hang on and report a successful restart. But + * that's a project for another day. + */ + if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) { + mpm_service_start(ptemp, 0, NULL); + return; + } + else { + success = TRUE; + ap_signal_parent(SIGNAL_PARENT_RESTART); + } + } + } + + if (success) + fprintf(stderr,"The %s service has %s.\n", mpm_display_name, + signal ? "restarted" : "stopped"); + else + fprintf(stderr,"Failed to %s the %s service.\n", + signal ? "restart" : "stop", mpm_display_name); +} diff --git a/trunk/server/mpm/worker/Makefile.in b/trunk/server/mpm/worker/Makefile.in new file mode 100644 index 0000000000..b45b848341 --- /dev/null +++ b/trunk/server/mpm/worker/Makefile.in @@ -0,0 +1,5 @@ + +LTLIBRARY_NAME = libworker.la +LTLIBRARY_SOURCES = worker.c fdqueue.c pod.c + +include $(top_srcdir)/build/ltlib.mk diff --git a/trunk/server/mpm/worker/config5.m4 b/trunk/server/mpm/worker/config5.m4 new file mode 100644 index 0000000000..cc13134845 --- /dev/null +++ b/trunk/server/mpm/worker/config5.m4 @@ -0,0 +1,6 @@ +dnl ## XXX - Need a more thorough check of the proper flags to use + +if test "$MPM_NAME" = "worker" ; then + AC_CHECK_FUNCS(pthread_kill) + APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) +fi diff --git a/trunk/server/mpm/worker/fdqueue.c b/trunk/server/mpm/worker/fdqueue.c new file mode 100644 index 0000000000..155e3ec734 --- /dev/null +++ b/trunk/server/mpm/worker/fdqueue.c @@ -0,0 +1,384 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdqueue.h" +#include "apr_atomic.h" + +typedef struct recycled_pool { + apr_pool_t *pool; + struct recycled_pool *next; +} recycled_pool; + +struct fd_queue_info_t { + apr_uint32_t idlers; + apr_thread_mutex_t *idlers_mutex; + apr_thread_cond_t *wait_for_idler; + int terminated; + int max_idlers; + recycled_pool *recycled_pools; +}; + +static apr_status_t queue_info_cleanup(void *data_) +{ + fd_queue_info_t *qi = data_; + apr_thread_cond_destroy(qi->wait_for_idler); + apr_thread_mutex_destroy(qi->idlers_mutex); + + /* Clean up any pools in the recycled list */ + for (;;) { + struct recycled_pool *first_pool = qi->recycled_pools; + if (first_pool == NULL) { + break; + } + if (apr_atomic_casptr((volatile void**)&(qi->recycled_pools), first_pool->next, + first_pool) == first_pool) { + apr_pool_destroy(first_pool->pool); + } + } + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_create(fd_queue_info_t **queue_info, + apr_pool_t *pool, int max_idlers) +{ + apr_status_t rv; + fd_queue_info_t *qi; + + qi = apr_palloc(pool, sizeof(*qi)); + memset(qi, 0, sizeof(*qi)); + + rv = apr_thread_mutex_create(&qi->idlers_mutex, APR_THREAD_MUTEX_DEFAULT, + pool); + if (rv != APR_SUCCESS) { + return rv; + } + rv = apr_thread_cond_create(&qi->wait_for_idler, pool); + if (rv != APR_SUCCESS) { + return rv; + } + qi->recycled_pools = NULL; + qi->max_idlers = max_idlers; + apr_pool_cleanup_register(pool, qi, queue_info_cleanup, + apr_pool_cleanup_null); + + *queue_info = qi; + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_set_idle(fd_queue_info_t *queue_info, + apr_pool_t *pool_to_recycle) +{ + apr_status_t rv; + int prev_idlers; + + /* If we have been given a pool to recycle, atomically link + * it into the queue_info's list of recycled pools + */ + if (pool_to_recycle) { + struct recycled_pool *new_recycle; + new_recycle = (struct recycled_pool *)apr_palloc(pool_to_recycle, + sizeof(*new_recycle)); + new_recycle->pool = pool_to_recycle; + for (;;) { + new_recycle->next = queue_info->recycled_pools; + if (apr_atomic_casptr((volatile void**)&(queue_info->recycled_pools), + new_recycle, new_recycle->next) == + new_recycle->next) { + break; + } + } + } + + /* Atomically increment the count of idle workers */ + for (;;) { + prev_idlers = queue_info->idlers; + if (apr_atomic_cas32(&(queue_info->idlers), prev_idlers + 1, + prev_idlers) == prev_idlers) { + break; + } + } + + /* If this thread just made the idle worker count nonzero, + * wake up the listener. */ + if (prev_idlers == 0) { + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + rv = apr_thread_cond_signal(queue_info->wait_for_idler); + if (rv != APR_SUCCESS) { + apr_thread_mutex_unlock(queue_info->idlers_mutex); + return rv; + } + rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + } + + return APR_SUCCESS; +} + +apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, + apr_pool_t **recycled_pool) +{ + apr_status_t rv; + + *recycled_pool = NULL; + + /* Block if the count of idle workers is zero */ + if (queue_info->idlers == 0) { + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + /* Re-check the idle worker count to guard against a + * race condition. Now that we're in the mutex-protected + * region, one of two things may have happened: + * - If the idle worker count is still zero, the + * workers are all still busy, so it's safe to + * block on a condition variable. + * - If the idle worker count is nonzero, then a + * worker has become idle since the first check + * of queue_info->idlers above. It's possible + * that the worker has also signaled the condition + * variable--and if so, the listener missed it + * because it wasn't yet blocked on the condition + * variable. But if the idle worker count is + * now nonzero, it's safe for this function to + * return immediately. + */ + if (queue_info->idlers == 0) { + rv = apr_thread_cond_wait(queue_info->wait_for_idler, + queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + apr_status_t rv2; + rv2 = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv2 != APR_SUCCESS) { + return rv2; + } + return rv; + } + } + rv = apr_thread_mutex_unlock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + } + + /* Atomically decrement the idle worker count */ + apr_atomic_dec32(&(queue_info->idlers)); + + /* Atomically pop a pool from the recycled list */ + for (;;) { + struct recycled_pool *first_pool = queue_info->recycled_pools; + if (first_pool == NULL) { + break; + } + if (apr_atomic_casptr((volatile void**)&(queue_info->recycled_pools), first_pool->next, + first_pool) == first_pool) { + *recycled_pool = first_pool->pool; + break; + } + } + + if (queue_info->terminated) { + return APR_EOF; + } + else { + return APR_SUCCESS; + } +} + +apr_status_t ap_queue_info_term(fd_queue_info_t *queue_info) +{ + apr_status_t rv; + rv = apr_thread_mutex_lock(queue_info->idlers_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + queue_info->terminated = 1; + apr_thread_cond_broadcast(queue_info->wait_for_idler); + return apr_thread_mutex_unlock(queue_info->idlers_mutex); +} + +/** + * Detects when the fd_queue_t is full. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +#define ap_queue_full(queue) ((queue)->nelts == (queue)->bounds) + +/** + * Detects when the fd_queue_t is empty. This utility function is expected + * to be called from within critical sections, and is not threadsafe. + */ +#define ap_queue_empty(queue) ((queue)->nelts == 0) + +/** + * Callback routine that is called to destroy this + * fd_queue_t when its pool is destroyed. + */ +static apr_status_t ap_queue_destroy(void *data) +{ + fd_queue_t *queue = data; + + /* Ignore errors here, we can't do anything about them anyway. + * XXX: We should at least try to signal an error here, it is + * indicative of a programmer error. -aaron */ + apr_thread_cond_destroy(queue->not_empty); + apr_thread_mutex_destroy(queue->one_big_mutex); + + return APR_SUCCESS; +} + +/** + * Initialize the fd_queue_t. + */ +apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a) +{ + int i; + apr_status_t rv; + + if ((rv = apr_thread_mutex_create(&queue->one_big_mutex, + APR_THREAD_MUTEX_DEFAULT, a)) != APR_SUCCESS) { + return rv; + } + if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) { + return rv; + } + + queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t)); + queue->bounds = queue_capacity; + queue->nelts = 0; + + /* Set all the sockets in the queue to NULL */ + for (i = 0; i < queue_capacity; ++i) + queue->data[i].sd = NULL; + + apr_pool_cleanup_register(a, queue, ap_queue_destroy, apr_pool_cleanup_null); + + return APR_SUCCESS; +} + +/** + * Push a new socket onto the queue. + * + * precondition: ap_queue_info_wait_for_idler has already been called + * to reserve an idle worker thread + */ +apr_status_t ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p) +{ + fd_queue_elem_t *elem; + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + AP_DEBUG_ASSERT(!queue->terminated); + AP_DEBUG_ASSERT(!ap_queue_full(queue)); + + elem = &queue->data[queue->nelts]; + elem->sd = sd; + elem->p = p; + queue->nelts++; + + apr_thread_cond_signal(queue->not_empty); + + if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + return APR_SUCCESS; +} + +/** + * Retrieves the next available socket from the queue. If there are no + * sockets available, it will block until one becomes available. + * Once retrieved, the socket is placed into the address specified by + * 'sd'. + */ +apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p) +{ + fd_queue_elem_t *elem; + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + + /* Keep waiting until we wake up and find that the queue is not empty. */ + if (ap_queue_empty(queue)) { + if (!queue->terminated) { + apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); + } + /* If we wake up and it's still empty, then we were interrupted */ + if (ap_queue_empty(queue)) { + rv = apr_thread_mutex_unlock(queue->one_big_mutex); + if (rv != APR_SUCCESS) { + return rv; + } + if (queue->terminated) { + return APR_EOF; /* no more elements ever again */ + } + else { + return APR_EINTR; + } + } + } + + elem = &queue->data[--queue->nelts]; + *sd = elem->sd; + *p = elem->p; +#ifdef AP_DEBUG + elem->sd = NULL; + elem->p = NULL; +#endif /* AP_DEBUG */ + + rv = apr_thread_mutex_unlock(queue->one_big_mutex); + return rv; +} + +apr_status_t ap_queue_interrupt_all(fd_queue_t *queue) +{ + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + apr_thread_cond_broadcast(queue->not_empty); + return apr_thread_mutex_unlock(queue->one_big_mutex); +} + +apr_status_t ap_queue_term(fd_queue_t *queue) +{ + apr_status_t rv; + + if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + /* we must hold one_big_mutex when setting this... otherwise, + * we could end up setting it and waking everybody up just after a + * would-be popper checks it but right before they block + */ + queue->terminated = 1; + if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) { + return rv; + } + return ap_queue_interrupt_all(queue); +} diff --git a/trunk/server/mpm/worker/fdqueue.h b/trunk/server/mpm/worker/fdqueue.h new file mode 100644 index 0000000000..9dd8c582f5 --- /dev/null +++ b/trunk/server/mpm/worker/fdqueue.h @@ -0,0 +1,64 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FDQUEUE_H +#define FDQUEUE_H +#include "httpd.h" +#include +#if APR_HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#include + +typedef struct fd_queue_info_t fd_queue_info_t; + +apr_status_t ap_queue_info_create(fd_queue_info_t **queue_info, + apr_pool_t *pool, int max_idlers); +apr_status_t ap_queue_info_set_idle(fd_queue_info_t *queue_info, + apr_pool_t *pool_to_recycle); +apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, + apr_pool_t **recycled_pool); +apr_status_t ap_queue_info_term(fd_queue_info_t *queue_info); + +struct fd_queue_elem_t { + apr_socket_t *sd; + apr_pool_t *p; +}; +typedef struct fd_queue_elem_t fd_queue_elem_t; + +struct fd_queue_t { + fd_queue_elem_t *data; + int nelts; + int bounds; + apr_thread_mutex_t *one_big_mutex; + apr_thread_cond_t *not_empty; + int terminated; +}; +typedef struct fd_queue_t fd_queue_t; + +apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a); +apr_status_t ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p); +apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p); +apr_status_t ap_queue_interrupt_all(fd_queue_t *queue); +apr_status_t ap_queue_term(fd_queue_t *queue); + +#endif /* FDQUEUE_H */ diff --git a/trunk/server/mpm/worker/mpm.h b/trunk/server/mpm/worker/mpm.h new file mode 100644 index 0000000000..29c9f452fe --- /dev/null +++ b/trunk/server/mpm/worker/mpm.h @@ -0,0 +1,51 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoreboard.h" +#include "unixd.h" + +#ifndef APACHE_MPM_WORKER_H +#define APACHE_MPM_WORKER_H + +#define WORKER_MPM + +#define MPM_NAME "Worker" + +#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES +#define AP_MPM_WANT_WAIT_OR_TIMEOUT +#define AP_MPM_WANT_PROCESS_CHILD_STATUS +#define AP_MPM_WANT_SET_PIDFILE +#define AP_MPM_WANT_SET_SCOREBOARD +#define AP_MPM_WANT_SET_LOCKFILE +#define AP_MPM_WANT_SET_MAX_REQUESTS +#define AP_MPM_WANT_SET_COREDUMPDIR +#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +#define AP_MPM_WANT_SIGNAL_SERVER +#define AP_MPM_WANT_SET_MAX_MEM_FREE +#define AP_MPM_WANT_SET_STACKSIZE +#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER +#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK + +#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) +#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +#define MPM_ACCEPT_FUNC unixd_accept + +extern int ap_threads_per_child; +extern int ap_max_daemons_limit; +extern server_rec *ap_server_conf; +extern char ap_coredump_dir[MAX_STRING_LEN]; + +#endif /* APACHE_MPM_WORKER_H */ diff --git a/trunk/server/mpm/worker/mpm_default.h b/trunk/server/mpm/worker/mpm_default.h new file mode 100644 index 0000000000..cb93433208 --- /dev/null +++ b/trunk/server/mpm/worker/mpm_default.h @@ -0,0 +1,69 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APACHE_MPM_DEFAULT_H +#define APACHE_MPM_DEFAULT_H + +/* Number of servers to spawn off by default --- also, if fewer than + * this free when the caretaker checks, it will spawn more. + */ +#ifndef DEFAULT_START_DAEMON +#define DEFAULT_START_DAEMON 3 +#endif + +/* Maximum number of *free* server processes --- more than this, and + * they will die off. + */ + +#ifndef DEFAULT_MAX_FREE_DAEMON +#define DEFAULT_MAX_FREE_DAEMON 10 +#endif + +/* Minimum --- fewer than this, and more will be created */ + +#ifndef DEFAULT_MIN_FREE_DAEMON +#define DEFAULT_MIN_FREE_DAEMON 3 +#endif + +#ifndef DEFAULT_THREADS_PER_CHILD +#define DEFAULT_THREADS_PER_CHILD 25 +#endif + +/* File used for accept locking, when we use a file */ +#ifndef DEFAULT_LOCKFILE +#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" +#endif + +/* Where the main/parent process's pid is logged */ +#ifndef DEFAULT_PIDLOG +#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" +#endif + +/* + * Interval, in microseconds, between scoreboard maintenance. + */ +#ifndef SCOREBOARD_MAINTENANCE_INTERVAL +#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 +#endif + +/* Number of requests to try to handle in a single process. If <= 0, + * the children don't die off. + */ +#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD +#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 +#endif + +#endif /* AP_MPM_DEFAULT_H */ diff --git a/trunk/server/mpm/worker/pod.c b/trunk/server/mpm/worker/pod.c new file mode 100644 index 0000000000..5c7cceee33 --- /dev/null +++ b/trunk/server/mpm/worker/pod.c @@ -0,0 +1,110 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pod.h" + +#if APR_HAVE_UNISTD_H +#include +#endif + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) +{ + apr_status_t rv; + + *pod = apr_palloc(p, sizeof(**pod)); + rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); + if (rv != APR_SUCCESS) { + return rv; + } +/* + apr_file_pipe_timeout_set((*pod)->pod_in, 0); +*/ + (*pod)->p = p; + + /* close these before exec. */ + apr_file_inherit_unset((*pod)->pod_in); + apr_file_inherit_unset((*pod)->pod_out); + + return APR_SUCCESS; +} + +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod) +{ + char c; + apr_os_file_t fd; + int rc; + + /* we need to surface EINTR so we'll have to grab the + * native file descriptor and do the OS read() ourselves + */ + apr_os_file_get(&fd, pod->pod_in); + rc = read(fd, &c, 1); + if (rc == 1) { + switch(c) { + case RESTART_CHAR: + return AP_RESTART; + case GRACEFUL_CHAR: + return AP_GRACEFUL; + } + } + return AP_NORESTART; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) +{ + apr_status_t rv; + + rv = apr_file_close(pod->pod_out); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_file_close(pod->pod_in); + if (rv != APR_SUCCESS) { + return rv; + } + return rv; +} + +static apr_status_t pod_signal_internal(ap_pod_t *pod, int graceful) +{ + apr_status_t rv; + char char_of_death = graceful ? GRACEFUL_CHAR : RESTART_CHAR; + apr_size_t one = 1; + + rv = apr_file_write(pod->pod_out, &char_of_death, &one); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } + return rv; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful) +{ + return pod_signal_internal(pod, graceful); +} + +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful) +{ + int i; + apr_status_t rv = APR_SUCCESS; + + for (i = 0; i < num && rv == APR_SUCCESS; i++) { + rv = pod_signal_internal(pod, graceful); + } +} + diff --git a/trunk/server/mpm/worker/pod.h b/trunk/server/mpm/worker/pod.h new file mode 100644 index 0000000000..04a2359e59 --- /dev/null +++ b/trunk/server/mpm/worker/pod.h @@ -0,0 +1,50 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_main.h" +#include "mpm.h" +#include "mpm_common.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "mpm_default.h" + +#define RESTART_CHAR '$' +#define GRACEFUL_CHAR '!' + +#define AP_RESTART 0 +#define AP_GRACEFUL 1 + +typedef struct ap_pod_t ap_pod_t; + +struct ap_pod_t { + apr_file_t *pod_in; + apr_file_t *pod_out; + apr_pool_t *p; +}; + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod); +AP_DECLARE(int) ap_mpm_pod_check(ap_pod_t *pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod); +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int graceful); +AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num, int graceful); diff --git a/trunk/server/mpm/worker/worker.c b/trunk/server/mpm/worker/worker.c new file mode 100644 index 0000000000..1380ee23b5 --- /dev/null +++ b/trunk/server/mpm/worker/worker.c @@ -0,0 +1,2165 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The purpose of this MPM is to fix the design flaws in the threaded + * model. Because of the way that pthreads and mutex locks interact, + * it is basically impossible to cleanly gracefully shutdown a child + * process if multiple threads are all blocked in accept. This model + * fixes those problems. + */ + +#include "apr.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_thread_mutex.h" +#include "apr_proc_mutex.h" +#include "apr_poll.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#if APR_HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SYS_PROCESSOR_H +#include /* for bindprocessor() */ +#endif + +#if !APR_HAS_THREADS +#error The Worker MPM requires APR threads, but they are unavailable. +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_config.h" /* for read_config */ +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" +#include "ap_mpm.h" +#include "pod.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "scoreboard.h" +#include "fdqueue.h" +#include "mpm_default.h" + +#include +#include /* for INT_MAX */ + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_SERVER_LIMIT +#define DEFAULT_SERVER_LIMIT 16 +#endif + +/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_SERVER_LIMIT +#define MAX_SERVER_LIMIT 20000 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * server_limit are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef DEFAULT_THREAD_LIMIT +#define DEFAULT_THREAD_LIMIT 64 +#endif + +/* Admin can't tune ThreadLimit beyond MAX_THREAD_LIMIT. We want + * some sort of compile-time limit to help catch typos. + */ +#ifndef MAX_THREAD_LIMIT +#define MAX_THREAD_LIMIT 20000 +#endif + +/* + * Actual definitions of config globals + */ + +int ap_threads_per_child = 0; /* Worker threads per child */ +static int ap_daemons_to_start = 0; +static int min_spare_threads = 0; +static int max_spare_threads = 0; +static int ap_daemons_limit = 0; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int thread_limit = DEFAULT_THREAD_LIMIT; +static int first_thread_limit; +static int changed_limit_at_restart; +static int dying = 0; +static int workers_may_exit = 0; +static int start_thread_may_exit = 0; +static int listener_may_exit = 0; +static int requests_this_child; +static int num_listensocks = 0; +static int resource_shortage = 0; +static fd_queue_t *worker_queue; +static fd_queue_info_t *worker_queue_info; +static int mpm_state = AP_MPMQ_STARTING; +static int sick_child_detected; + +/* The structure used to pass unique initialization info to each thread */ +typedef struct { + int pid; + int tid; + int sd; +} proc_info; + +/* Structure used to pass information to the thread responsible for + * creating the rest of the threads. + */ +typedef struct { + apr_thread_t **threads; + apr_thread_t *listener; + int child_num_arg; + apr_threadattr_t *threadattr; +} thread_starter; + +#define ID_FROM_CHILD_THREAD(c, t) ((c * thread_limit) + t) + +/* + * The max child slot ever assigned, preserved across restarts. Necessary + * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We + * use this value to optimize routines that have to scan the entire + * scoreboard. + */ +int ap_max_daemons_limit = -1; + +static ap_pod_t *pod; + +/* *Non*-shared http_main globals... */ + +server_rec *ap_server_conf; + +/* The worker MPM respects a couple of runtime flags that can aid + * in debugging. Setting the -DNO_DETACH flag will prevent the root process + * from detaching from its controlling terminal. Additionally, setting + * the -DONE_PROCESS flag (which implies -DNO_DETACH) will get you the + * child_main loop running in the process which originally started up. + * This gives you a pretty nice debugging environment. (You'll get a SIGHUP + * early in standalone_main; just continue through. This is the server + * trying to kill off any child processes which it might have lying + * around --- Apache doesn't keep track of their pids, it just sends + * SIGHUP to the process group, ignoring it in the root process. + * Continue through and you'll be fine.). + */ + +static int one_process = 0; + +#ifdef DEBUG_SIGSTOP +int raise_sigstop_flags; +#endif + +static apr_pool_t *pconf; /* Pool for config stuff */ +static apr_pool_t *pchild; /* Pool for httpd child stuff */ + +static pid_t ap_my_pid; /* Linux getpid() doesn't work except in main + thread. Use this instead */ +static pid_t parent_pid; +static apr_os_thread_t *listener_os_thread; + +/* Locks for accept serialization */ +static apr_proc_mutex_t *accept_mutex; + +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT +#define SAFE_ACCEPT(stmt) (ap_listeners->next ? (stmt) : APR_SUCCESS) +#else +#define SAFE_ACCEPT(stmt) (stmt) +#endif + +/* The LISTENER_SIGNAL signal will be sent from the main thread to the + * listener thread to wake it up for graceful termination (what a child + * process from an old generation does when the admin does "apachectl + * graceful"). This signal will be blocked in all threads of a child + * process except for the listener thread. + */ +#define LISTENER_SIGNAL SIGHUP + +/* An array of socket descriptors in use by each thread used to + * perform a non-graceful (forced) shutdown of the server. */ +static apr_socket_t **worker_sockets; + +static void close_worker_sockets(void) +{ + int i; + for (i = 0; i < ap_threads_per_child; i++) { + if (worker_sockets[i]) { + apr_socket_close(worker_sockets[i]); + worker_sockets[i] = NULL; + } + } +} + +static void wakeup_listener(void) +{ + listener_may_exit = 1; + if (!listener_os_thread) { + /* XXX there is an obscure path that this doesn't handle perfectly: + * right after listener thread is created but before + * listener_os_thread is set, the first worker thread hits an + * error and starts graceful termination + */ + return; + } + /* + * we should just be able to "kill(ap_my_pid, LISTENER_SIGNAL)" on all + * platforms and wake up the listener thread since it is the only thread + * with SIGHUP unblocked, but that doesn't work on Linux + */ +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, LISTENER_SIGNAL); +#else + kill(ap_my_pid, LISTENER_SIGNAL); +#endif +} + +#define ST_INIT 0 +#define ST_GRACEFUL 1 +#define ST_UNGRACEFUL 2 + +static int terminate_mode = ST_INIT; + +static void signal_threads(int mode) +{ + if (terminate_mode == mode) { + return; + } + terminate_mode = mode; + mpm_state = AP_MPMQ_STOPPING; + + /* in case we weren't called from the listener thread, wake up the + * listener thread + */ + wakeup_listener(); + + /* for ungraceful termination, let the workers exit now; + * for graceful termination, the listener thread will notify the + * workers to exit once it has stopped accepting new connections + */ + if (mode == ST_UNGRACEFUL) { + workers_may_exit = 1; + ap_queue_interrupt_all(worker_queue); + ap_queue_info_term(worker_queue_info); + close_worker_sockets(); /* forcefully kill all current connections */ + } +} + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_max_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_STATIC; + return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; + return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = thread_limit; + return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: + *result = ap_threads_per_child; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = min_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = 0; + return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = max_spare_threads; + return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; + return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: + *result = ap_daemons_limit; + return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; + return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); +static void clean_child_exit(int code) +{ + mpm_state = AP_MPMQ_STOPPING; + if (pchild) { + apr_pool_destroy(pchild); + } + exit(code); +} + +static void just_die(int sig) +{ + clean_child_exit(0); +} + +/***************************************************************** + * Connection structures and accounting... + */ + +/* volatile just in case */ +static int volatile shutdown_pending; +static int volatile restart_pending; +static int volatile is_graceful; +static volatile int child_fatal; +ap_generation_t volatile ap_my_generation; + +/* + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at + * functions to initiate shutdown or restart without relying on signals. + * Previously this was initiated in sig_term() and restart() signal handlers, + * but we want to be able to start a shutdown/restart from other sources -- + * e.g. on Win32, from the service manager. Now the service manager can + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. + * + * These should only be called from the parent process itself, since the + * parent process will use the shutdown_pending and restart_pending variables + * to determine whether to shutdown or restart. The child process should + * call signal_parent() directly to tell the parent to die -- this will + * cause neither of those variable to be set, which the parent will + * assume means something serious is wrong (which it will be, for the + * child to force an exit) and so do an exit anyway. + */ + +static void ap_start_shutdown(void) +{ + mpm_state = AP_MPMQ_STOPPING; + if (shutdown_pending == 1) { + /* Um, is this _probably_ not an error, if the user has + * tried to do a shutdown twice quickly, so we won't + * worry about reporting it. + */ + return; + } + shutdown_pending = 1; +} + +/* do a graceful restart if graceful == 1 */ +static void ap_start_restart(int graceful) +{ + mpm_state = AP_MPMQ_STOPPING; + if (restart_pending == 1) { + /* Probably not an error - don't bother reporting it */ + return; + } + restart_pending = 1; + is_graceful = graceful; +} + +static void sig_term(int sig) +{ + ap_start_shutdown(); +} + +static void restart(int sig) +{ + ap_start_restart(sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; +#endif + + if (!one_process) { + ap_fatal_signal_setup(ap_server_conf, pconf); + } + +#ifndef NO_USE_SIGACTION + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_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, errno, ap_server_conf, + "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy + * processing one */ + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ + apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + + apr_signal(SIGTERM, sig_term); +#ifdef SIGHUP + apr_signal(SIGHUP, restart); +#endif /* SIGHUP */ +#ifdef AP_SIG_GRACEFUL + apr_signal(AP_SIG_GRACEFUL, restart); +#endif /* AP_SIG_GRACEFUL */ +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + +#endif +} + +/***************************************************************** + * Here follows a long bunch of generic server bookkeeping stuff... + */ + +int ap_graceful_stop_signalled(void) + /* XXX this is really a bad confusing obsolete name + * maybe it should be ap_mpm_process_exiting? + */ +{ + /* note: for a graceful termination, listener_may_exit will be set before + * workers_may_exit, so check listener_may_exit + */ + return listener_may_exit; +} + +/***************************************************************** + * Child process main loop. + */ + +static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, + int my_thread_num, apr_bucket_alloc_t *bucket_alloc) +{ + conn_rec *current_conn; + long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); + int csd; + ap_sb_handle_t *sbh; + + ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); + apr_os_sock_get(&csd, sock); + + current_conn = ap_run_create_connection(p, ap_server_conf, sock, + conn_id, sbh, bucket_alloc); + if (current_conn) { + ap_process_connection(current_conn, sock); + ap_lingering_close(current_conn); + } +} + +/* requests_this_child has gone to zero or below. See if the admin coded + "MaxRequestsPerChild 0", and keep going in that case. Doing it this way + simplifies the hot path in worker_thread */ +static void check_infinite_requests(void) +{ + if (ap_max_requests_per_child) { + signal_threads(ST_GRACEFUL); + } + else { + /* wow! if you're executing this code, you may have set a record. + * either this child process has served over 2 billion requests, or + * you're running a threaded 2.0 on a 16 bit machine. + * + * I'll buy pizza and beers at Apachecon for the first person to do + * the former without cheating (dorking with INT_MAX, or running with + * uncommitted performance patches, for example). + * + * for the latter case, you probably deserve a beer too. Greg Ames + */ + + requests_this_child = INT_MAX; /* keep going */ + } +} + +static void unblock_signal(int sig) +{ + sigset_t sig_mask; + + sigemptyset(&sig_mask); + sigaddset(&sig_mask, sig); +#if defined(SIGPROCMASK_SETS_THREAD_MASK) + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); +#else + pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL); +#endif +} + +static void dummy_signal_handler(int sig) +{ + /* XXX If specifying SIG_IGN is guaranteed to unblock a syscall, + * then we don't need this goofy function. + */ +} + +static void *listener_thread(apr_thread_t *thd, void * dummy) +{ + proc_info * ti = dummy; + int process_slot = ti->pid; + apr_pool_t *tpool = apr_thread_pool_get(thd); + void *csd = NULL; + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_pool_t *recycled_pool = NULL; + apr_pollset_t *pollset; + apr_status_t rv; + ap_listen_rec *lr; + int have_idle_worker = 0; + int last_poll_idx = 0; + + free(ti); + + /* ### check the status */ + (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0); + + for (lr = ap_listeners; lr != NULL; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; + + pfd.desc_type = APR_POLL_SOCKET; + pfd.desc.s = lr->sd; + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + + /* ### check the status */ + (void) apr_pollset_add(pollset, &pfd); + } + + /* Unblock the signal used to wake this thread up, and set a handler for + * it. + */ + unblock_signal(LISTENER_SIGNAL); + apr_signal(LISTENER_SIGNAL, dummy_signal_handler); + + /* TODO: Switch to a system where threads reuse the results from earlier + poll calls - manoj */ + while (1) { + /* TODO: requests_this_child should be synchronized - aaron */ + if (requests_this_child <= 0) { + check_infinite_requests(); + } + if (listener_may_exit) break; + + if (!have_idle_worker) { + rv = ap_queue_info_wait_for_idler(worker_queue_info, + &recycled_pool); + if (APR_STATUS_IS_EOF(rv)) { + break; /* we've been signaled to die now */ + } + else if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_queue_info_wait failed. Attempting to " + " shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + break; + } + have_idle_worker = 1; + } + + /* We've already decremented the idle worker count inside + * ap_queue_info_wait_for_idler. */ + + if ((rv = SAFE_ACCEPT(apr_proc_mutex_lock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (listener_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_lock failed. Attempting to shutdown " + "process gracefully."); + signal_threads(ST_GRACEFUL); + break; /* skip the lock release */ + } + + if (!ap_listeners->next) { + /* Only one listener, so skip the poll */ + lr = ap_listeners; + } + else { + while (!listener_may_exit) { + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + + rv = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (rv != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rv)) { + continue; + } + + /* apr_pollset_poll() will only return errors in catastrophic + * circumstances. Let's try exiting gracefully, for now. */ + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + (const server_rec *) ap_server_conf, + "apr_pollset_poll: (listen)"); + signal_threads(ST_GRACEFUL); + } + + if (listener_may_exit) break; + + /* We can always use pdesc[0], but sockets at position N + * could end up completely starved of attention in a very + * busy server. Therefore, we round-robin across the + * returned set of descriptors. While it is possible that + * the returned set of descriptors might flip around and + * continue to starve some sockets, we happen to know the + * internal pollset implementation retains ordering + * stability of the sockets. Thus, the round-robin should + * ensure that a socket will eventually be serviced. + */ + if (last_poll_idx >= numdesc) + last_poll_idx = 0; + + /* Grab a listener record from the client_data of the poll + * descriptor, and advance our saved index to round-robin + * the next fetch. + * + * ### hmm... this descriptor might have POLLERR rather + * ### than POLLIN + */ + lr = pdesc[last_poll_idx++].client_data; + break; + + } /* while */ + + } /* if/else */ + + if (!listener_may_exit) { + /* create a new transaction pool for each accepted socket */ + if (recycled_pool == NULL) { + apr_allocator_t *allocator; + + apr_allocator_create(&allocator); + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&ptrans, pconf, NULL, allocator); + apr_allocator_owner_set(allocator, ptrans); + } + else { + ptrans = recycled_pool; + } + apr_pool_tag(ptrans, "transaction"); + rv = lr->accept_func(&csd, lr, ptrans); + /* later we trash rv and rely on csd to indicate success/failure */ + AP_DEBUG_ASSERT(rv == APR_SUCCESS || !csd); + + if (rv == APR_EGENERAL) { + /* E[NM]FILE, ENOMEM, etc */ + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + } + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (listener_may_exit) { + break; + } + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + if (csd != NULL) { + rv = ap_queue_push(worker_queue, csd, ptrans); + if (rv) { + /* trash the connection; we couldn't queue the connected + * socket to a worker + */ + apr_socket_close(csd); + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "ap_queue_push failed"); + } + else { + have_idle_worker = 0; + } + } + } + else { + if ((rv = SAFE_ACCEPT(apr_proc_mutex_unlock(accept_mutex))) + != APR_SUCCESS) { + int level = APLOG_EMERG; + + if (ap_scoreboard_image->parent[process_slot].generation != + ap_scoreboard_image->global->running_generation) { + level = APLOG_DEBUG; /* common to get these at restart time */ + } + ap_log_error(APLOG_MARK, level, rv, ap_server_conf, + "apr_proc_mutex_unlock failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + } + break; + } + } + + ap_queue_term(worker_queue); + dying = 1; + ap_scoreboard_image->parent[process_slot].quiescing = 1; + + /* wake up the main thread */ + kill(ap_my_pid, SIGTERM); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +/* XXX For ungraceful termination/restart, we definitely don't want to + * wait for active connections to finish but we may want to wait + * for idle workers to get out of the queue code and release mutexes, + * since those mutexes are cleaned up pretty soon and some systems + * may not react favorably (i.e., segfault) if operations are attempted + * on cleaned-up mutexes. + */ +static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) +{ + proc_info * ti = dummy; + int process_slot = ti->pid; + int thread_slot = ti->tid; + apr_socket_t *csd = NULL; + apr_bucket_alloc_t *bucket_alloc; + apr_pool_t *last_ptrans = NULL; + apr_pool_t *ptrans; /* Pool for per-transaction stuff */ + apr_status_t rv; + int is_idle = 0; + + free(ti); + + ap_scoreboard_image->servers[process_slot][thread_slot].pid = ap_my_pid; + ap_scoreboard_image->servers[process_slot][thread_slot].generation = ap_my_generation; + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); + + while (!workers_may_exit) { + if (!is_idle) { + rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); + last_ptrans = NULL; + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "ap_queue_info_set_idle failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + break; + } + is_idle = 1; + } + + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); +worker_pop: + if (workers_may_exit) { + break; + } + rv = ap_queue_pop(worker_queue, &csd, &ptrans); + + if (rv != APR_SUCCESS) { + /* We get APR_EOF during a graceful shutdown once all the connections + * accepted by this server process have been handled. + */ + if (APR_STATUS_IS_EOF(rv)) { + break; + } + /* We get APR_EINTR whenever ap_queue_pop() has been interrupted + * from an explicit call to ap_queue_interrupt_all(). This allows + * us to unblock threads stuck in ap_queue_pop() when a shutdown + * is pending. + * + * If workers_may_exit is set and this is ungraceful termination/ + * restart, we are bound to get an error on some systems (e.g., + * AIX, which sanity-checks mutex operations) since the queue + * may have already been cleaned up. Don't log the "error" if + * workers_may_exit is set. + */ + else if (APR_STATUS_IS_EINTR(rv)) { + goto worker_pop; + } + /* We got some other error. */ + else if (!workers_may_exit) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "ap_queue_pop failed"); + } + continue; + } + is_idle = 0; + worker_sockets[thread_slot] = csd; + bucket_alloc = apr_bucket_alloc_create(ptrans); + process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc); + worker_sockets[thread_slot] = NULL; + requests_this_child--; /* FIXME: should be synchronized - aaron */ + apr_pool_clear(ptrans); + last_ptrans = ptrans; + } + + ap_update_child_status_from_indexes(process_slot, thread_slot, + (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); + + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static int check_signal(int signum) +{ + switch (signum) { + case SIGTERM: + case SIGINT: + return 1; + } + return 0; +} + +static void create_listener_thread(thread_starter *ts) +{ + int my_child_num = ts->child_num_arg; + apr_threadattr_t *thread_attr = ts->threadattr; + proc_info *my_info; + apr_status_t rv; + + my_info = (proc_info *)malloc(sizeof(proc_info)); + my_info->pid = my_child_num; + my_info->tid = -1; /* listener thread doesn't have a thread slot */ + my_info->sd = 0; + rv = apr_thread_create(&ts->listener, thread_attr, listener_thread, + my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create listener thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + apr_os_thread_get(&listener_os_thread, ts->listener); +} + +/* XXX under some circumstances not understood, children can get stuck + * in start_threads forever trying to take over slots which will + * never be cleaned up; for now there is an APLOG_DEBUG message issued + * every so often when this condition occurs + */ +static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) +{ + thread_starter *ts = dummy; + apr_thread_t **threads = ts->threads; + apr_threadattr_t *thread_attr = ts->threadattr; + int child_num_arg = ts->child_num_arg; + int my_child_num = child_num_arg; + proc_info *my_info; + apr_status_t rv; + int i; + int threads_created = 0; + int listener_started = 0; + int loops; + int prev_threads_created; + + /* We must create the fd queues before we start up the listener + * and worker threads. */ + worker_queue = apr_pcalloc(pchild, sizeof(*worker_queue)); + rv = ap_queue_init(worker_queue, ap_threads_per_child, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "ap_queue_init() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + rv = ap_queue_info_create(&worker_queue_info, pchild, + ap_threads_per_child); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "ap_queue_info_create() failed"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + worker_sockets = apr_pcalloc(pchild, ap_threads_per_child + * sizeof(apr_socket_t *)); + + loops = prev_threads_created = 0; + while (1) { + /* ap_threads_per_child does not include the listener thread */ + for (i = 0; i < ap_threads_per_child; i++) { + int status = ap_scoreboard_image->servers[child_num_arg][i].status; + + if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { + continue; + } + + my_info = (proc_info *)malloc(sizeof(proc_info)); + if (my_info == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + my_info->pid = my_child_num; + my_info->tid = i; + my_info->sd = 0; + + /* We are creating threads right now */ + ap_update_child_status_from_indexes(my_child_num, i, + SERVER_STARTING, NULL); + /* We let each thread update its own scoreboard entry. This is + * done because it lets us deal with tid better. + */ + rv = apr_thread_create(&threads[i], thread_attr, + worker_thread, my_info, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + threads_created++; + } + /* Start the listener only when there are workers available */ + if (!listener_started && threads_created) { + create_listener_thread(ts); + listener_started = 1; + } + if (start_thread_may_exit || threads_created == ap_threads_per_child) { + break; + } + /* wait for previous generation to clean up an entry */ + apr_sleep(apr_time_from_sec(1)); + ++loops; + if (loops % 120 == 0) { /* every couple of minutes */ + if (prev_threads_created == threads_created) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "child %" APR_PID_T_FMT " isn't taking over " + "slots very quickly (%d of %d)", + ap_my_pid, threads_created, ap_threads_per_child); + } + prev_threads_created = threads_created; + } + } + + /* What state should this child_main process be listed as in the + * scoreboard...? + * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, + * (request_rec *) NULL); + * + * This state should be listed separately in the scoreboard, in some kind + * of process_status, not mixed in with the worker threads' status. + * "life_status" is almost right, but it's in the worker's structure, and + * the name could be clearer. gla + */ + apr_thread_exit(thd, APR_SUCCESS); + return NULL; +} + +static void join_workers(apr_thread_t *listener, apr_thread_t **threads) +{ + int i; + apr_status_t rv, thread_rv; + + if (listener) { + int iter; + + /* deal with a rare timing window which affects waking up the + * listener thread... if the signal sent to the listener thread + * is delivered between the time it verifies that the + * listener_may_exit flag is clear and the time it enters a + * blocking syscall, the signal didn't do any good... work around + * that by sleeping briefly and sending it again + */ + + iter = 0; + while (iter < 10 && +#ifdef HAVE_PTHREAD_KILL + pthread_kill(*listener_os_thread, 0) +#else + kill(ap_my_pid, 0) +#endif + == 0) { + /* listener not dead yet */ + apr_sleep(apr_time_make(0, 500000)); + wakeup_listener(); + ++iter; + } + if (iter >= 10) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "the listener thread didn't exit"); + } + else { + rv = apr_thread_join(&thread_rv, listener); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join listener thread"); + } + } + } + + for (i = 0; i < ap_threads_per_child; i++) { + if (threads[i]) { /* if we ever created this thread */ + rv = apr_thread_join(&thread_rv, threads[i]); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join worker " + "thread %d", + i); + } + } + } +} + +static void join_start_thread(apr_thread_t *start_thread_id) +{ + apr_status_t rv, thread_rv; + + start_thread_may_exit = 1; /* tell it to give up in case it is still + * trying to take over slots from a + * previous generation + */ + rv = apr_thread_join(&thread_rv, start_thread_id); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, + "apr_thread_join: unable to join the start " + "thread"); + } +} + +static void child_main(int child_num_arg) +{ + apr_thread_t **threads; + apr_status_t rv; + thread_starter *ts; + apr_threadattr_t *thread_attr; + apr_thread_t *start_thread_id; + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + ap_my_pid = getpid(); + ap_fatal_signal_child_setup(ap_server_conf); + apr_pool_create(&pchild, pconf); + + /*stuff to do before we switch id's, so we have permissions.*/ + ap_reopen_scoreboard(pchild, NULL, 0); + + rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, + pchild)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize cross-process lock in child"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (unixd_setup_child()) { + clean_child_exit(APEXIT_CHILDFATAL); + } + + ap_run_child_init(pchild, ap_server_conf); + + /* done with init critical section */ + + /* Just use the standard apr_setup_signal_thread to block all signals + * from being received. The child processes no longer use signals for + * any communication with the parent process. + */ + rv = apr_setup_signal_thread(); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "Couldn't initialize signal thread"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + if (ap_max_requests_per_child) { + requests_this_child = ap_max_requests_per_child; + } + else { + /* coding a value of zero means infinity */ + requests_this_child = INT_MAX; + } + + /* Setup worker threads */ + + /* clear the storage; we may not create all our threads immediately, + * and we want a 0 entry to indicate a thread which was not created + */ + threads = (apr_thread_t **)calloc(1, + sizeof(apr_thread_t *) * ap_threads_per_child); + if (threads == NULL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, + "malloc: out of memory"); + clean_child_exit(APEXIT_CHILDFATAL); + } + + ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts)); + + apr_threadattr_create(&thread_attr, pchild); + /* 0 means PTHREAD_CREATE_JOINABLE */ + apr_threadattr_detach_set(thread_attr, 0); + + if (ap_thread_stacksize != 0) { + apr_threadattr_stacksize_set(thread_attr, ap_thread_stacksize); + } + + ts->threads = threads; + ts->listener = NULL; + ts->child_num_arg = child_num_arg; + ts->threadattr = thread_attr; + + rv = apr_thread_create(&start_thread_id, thread_attr, start_threads, + ts, pchild); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, + "apr_thread_create: unable to create worker thread"); + /* let the parent decide how bad this really is */ + clean_child_exit(APEXIT_CHILDSICK); + } + + mpm_state = AP_MPMQ_RUNNING; + + /* If we are only running in one_process mode, we will want to + * still handle signals. */ + if (one_process) { + /* Block until we get a terminating signal. */ + apr_signal_thread(check_signal); + /* make sure the start thread has finished; signal_threads() + * and join_workers() depend on that + */ + /* XXX join_start_thread() won't be awakened if one of our + * threads encounters a critical error and attempts to + * shutdown this child + */ + join_start_thread(start_thread_id); + signal_threads(ST_UNGRACEFUL); /* helps us terminate a little more + * quickly than the dispatch of the signal thread + * beats the Pipe of Death and the browsers + */ + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + else { /* !one_process */ + /* remove SIGTERM from the set of blocked signals... if one of + * the other threads in the process needs to take us down + * (e.g., for MaxRequestsPerChild) it will send us SIGTERM + */ + unblock_signal(SIGTERM); + apr_signal(SIGTERM, dummy_signal_handler); + /* Watch for any messages from the parent over the POD */ + while (1) { + rv = ap_mpm_pod_check(pod); + if (rv == AP_NORESTART) { + /* see if termination was triggered while we slept */ + switch(terminate_mode) { + case ST_GRACEFUL: + rv = AP_GRACEFUL; + break; + case ST_UNGRACEFUL: + rv = AP_RESTART; + break; + } + } + if (rv == AP_GRACEFUL || rv == AP_RESTART) { + /* make sure the start thread has finished; + * signal_threads() and join_workers depend on that + */ + join_start_thread(start_thread_id); + signal_threads(rv == AP_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL); + break; + } + } + + /* A terminating signal was received. Now join each of the + * workers to clean them up. + * If the worker already exited, then the join frees + * their resources and returns. + * If the worker hasn't exited, then this blocks until + * they have (then cleans up). + */ + join_workers(ts->listener, threads); + } + + free(threads); + + clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0); +} + +static int make_child(server_rec *s, int slot) +{ + int pid; + + if (slot + 1 > ap_max_daemons_limit) { + ap_max_daemons_limit = slot + 1; + } + + if (one_process) { + set_signals(); + ap_scoreboard_image->parent[slot].pid = getpid(); + child_main(slot); + } + + if ((pid = fork()) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, + "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever + */ + ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); + + /* In case system resources are maxxed out, we don't want + Apache running away with the CPU trying to fork over and + over and over again. */ + apr_sleep(apr_time_from_sec(10)); + + return -1; + } + + if (!pid) { +#ifdef HAVE_BINDPROCESSOR + /* By default, AIX binds to a single processor. This bit unbinds + * children which will then bind to another CPU. + */ + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, + ap_server_conf, + "processor unbind failed %d", status); +#endif + RAISE_SIGSTOP(MAKE_CHILD); + + apr_signal(SIGTERM, just_die); + child_main(slot); + + clean_child_exit(0); + } + /* else */ + if (ap_scoreboard_image->parent[slot].pid != 0) { + /* This new child process is squatting on the scoreboard + * entry owned by an exiting child process, which cannot + * exit until all active requests complete. + * Don't forget about this exiting child process, or we + * won't be able to kill it if it doesn't exit by the + * time the server is shut down. + */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "taking over scoreboard slot from %" APR_PID_T_FMT "%s", + ap_scoreboard_image->parent[slot].pid, + ap_scoreboard_image->parent[slot].quiescing ? + " (quiescing)" : ""); + ap_register_extra_mpm_process(ap_scoreboard_image->parent[slot].pid); + } + ap_scoreboard_image->parent[slot].quiescing = 0; + ap_scoreboard_image->parent[slot].pid = pid; + return 0; +} + +/* start up a bunch of children */ +static void startup_children(int number_to_start) +{ + int i; + + for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { + if (ap_scoreboard_image->parent[i].pid != 0) { + continue; + } + if (make_child(ap_server_conf, i) < 0) { + break; + } + --number_to_start; + } +} + + +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is + * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by + * without the need to spawn. + */ +static int idle_spawn_rate = 1; +#ifndef MAX_SPAWN_RATE +#define MAX_SPAWN_RATE (32) +#endif +static int hold_off_on_exponential_spawning; + +static void perform_idle_server_maintenance(void) +{ + int i, j; + int idle_thread_count; + worker_score *ws; + process_score *ps; + int free_length; + int totally_free_length = 0; + int free_slots[MAX_SPAWN_RATE]; + int last_non_dead; + int total_non_dead; + int active_thread_count = 0; + + /* initialize the free_list */ + free_length = 0; + + idle_thread_count = 0; + last_non_dead = -1; + total_non_dead = 0; + + for (i = 0; i < ap_daemons_limit; ++i) { + /* Initialization to satisfy the compiler. It doesn't know + * that ap_threads_per_child is always > 0 */ + int status = SERVER_DEAD; + int any_dying_threads = 0; + int any_dead_threads = 0; + int all_dead_threads = 1; + + if (i >= ap_max_daemons_limit && totally_free_length == idle_spawn_rate) + break; + ps = &ap_scoreboard_image->parent[i]; + for (j = 0; j < ap_threads_per_child; j++) { + ws = &ap_scoreboard_image->servers[i][j]; + status = ws->status; + + /* XXX any_dying_threads is probably no longer needed GLA */ + any_dying_threads = any_dying_threads || + (status == SERVER_GRACEFUL); + any_dead_threads = any_dead_threads || (status == SERVER_DEAD); + all_dead_threads = all_dead_threads && + (status == SERVER_DEAD || + status == SERVER_GRACEFUL); + + /* We consider a starting server as idle because we started it + * at least a cycle ago, and if it still hasn't finished starting + * then we're just going to swamp things worse by forking more. + * So we hopefully won't need to fork more if we count it. + * This depends on the ordering of SERVER_READY and SERVER_STARTING. + */ + if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for + loop if no pid? not much else matters */ + if (status <= SERVER_READY && status != SERVER_DEAD && + !ps->quiescing && + ps->generation == ap_my_generation) { + ++idle_thread_count; + } + if (status >= SERVER_READY && status < SERVER_GRACEFUL) { + ++active_thread_count; + } + } + } + if (any_dead_threads && totally_free_length < idle_spawn_rate + && free_length < MAX_SPAWN_RATE + && (!ps->pid /* no process in the slot */ + || ps->quiescing)) { /* or at least one is going away */ + if (all_dead_threads) { + /* great! we prefer these, because the new process can + * start more threads sooner. So prioritize this slot + * by putting it ahead of any slots with active threads. + * + * first, make room by moving a slot that's potentially still + * in use to the end of the array + */ + free_slots[free_length] = free_slots[totally_free_length]; + free_slots[totally_free_length++] = i; + } + else { + /* slot is still in use - back of the bus + */ + free_slots[free_length] = i; + } + ++free_length; + } + /* XXX if (!ps->quiescing) is probably more reliable GLA */ + if (!any_dying_threads) { + last_non_dead = i; + ++total_non_dead; + } + } + + if (sick_child_detected) { + if (active_thread_count > 0) { + /* some child processes appear to be working. don't kill the + * whole server. + */ + sick_child_detected = 0; + } + else { + /* looks like a basket case. give up. + */ + shutdown_pending = 1; + child_fatal = 1; + ap_log_error(APLOG_MARK, APLOG_ALERT, 0, + ap_server_conf, + "No active workers found..." + " Apache is exiting!"); + /* the child already logged the failure details */ + return; + } + } + + ap_max_daemons_limit = last_non_dead + 1; + + if (idle_thread_count > max_spare_threads) { + /* Kill off one child */ + ap_mpm_pod_signal(pod, TRUE); + idle_spawn_rate = 1; + } + else if (idle_thread_count < min_spare_threads) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ + static int reported = 0; + + if (!reported) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + ap_server_conf, + "server reached MaxClients setting, consider" + " raising the MaxClients setting"); + reported = 1; + } + idle_spawn_rate = 1; + } + else { + if (free_length > idle_spawn_rate) { + free_length = idle_spawn_rate; + } + if (idle_spawn_rate >= 8) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, ThreadsPerChild " + "or Min/MaxSpareThreads), " + "spawning %d children, there are around %d idle " + "threads, and %d total children", free_length, + idle_thread_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { + make_child(ap_server_conf, free_slots[i]); + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ + if (hold_off_on_exponential_spawning) { + --hold_off_on_exponential_spawning; + } + else if (idle_spawn_rate < MAX_SPAWN_RATE) { + idle_spawn_rate *= 2; + } + } + } + else { + idle_spawn_rate = 1; + } +} + +static void server_main_loop(int remaining_children_to_start) +{ + int child_slot; + apr_exit_why_e exitwhy; + int status, processed_status; + apr_proc_t pid; + int i; + + while (!restart_pending && !shutdown_pending) { + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + shutdown_pending = 1; + child_fatal = 1; + return; + } + else if (processed_status == APEXIT_CHILDSICK) { + /* tell perform_idle_server_maintenance to check into this + * on the next timer pop + */ + sick_child_detected = 1; + } + /* non-fatal death... note that it's gone in the scoreboard. */ + child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + for (i = 0; i < ap_threads_per_child; i++) + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); + + ap_scoreboard_image->parent[child_slot].pid = 0; + ap_scoreboard_image->parent[child_slot].quiescing = 0; + if (processed_status == APEXIT_CHILDSICK) { + /* resource shortage, minimize the fork rate */ + idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { + /* we're still doing a 1-for-1 replacement of dead + * children with new children + */ + make_child(ap_server_conf, child_slot); + --remaining_children_to_start; + } + } + else if (ap_unregister_extra_mpm_process(pid.pid) == 1) { + /* handled */ +#if APR_HAS_OTHER_CHILD + } + else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, + status) == 0) { + /* handled */ +#endif + } + else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, + ap_server_conf, + "long lost child came home! (pid %ld)", + (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ + continue; + } + else if (remaining_children_to_start) { + /* we hit a 1 second timeout in which none of the previous + * generation of children needed to be reaped... so assume + * they're all done, and pick up the slack if any is left. + */ + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + /* In any event we really shouldn't do the code below because + * few of the servers we just started are in the IDLE state + * yet, so we'd mistakenly create an extra server. + */ + continue; + } + + perform_idle_server_maintenance(); + } +} + +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int remaining_children_to_start; + apr_status_t rv; + + ap_log_pid(pconf, ap_pid_fname); + + first_server_limit = server_limit; + first_thread_limit = thread_limit; + if (changed_limit_at_restart) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "WARNING: Attempt to change ServerLimit or ThreadLimit " + "ignored during restart"); + changed_limit_at_restart = 0; + } + + /* Initialize cross-process accept lock */ + ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, + ap_server_root_relative(_pconf, ap_lock_fname), + ap_my_pid); + + rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, + ap_accept_lock_mech, _pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't create accept lock"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_proc_mutex_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock; " + "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + } + + if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + + set_signals(); + /* Don't thrash... */ + if (max_spare_threads < min_spare_threads + ap_threads_per_child) + max_spare_threads = min_spare_threads + ap_threads_per_child; + + /* If we're doing a graceful_restart then we're going to see a lot + * of children exiting immediately when we get into the main loop + * below (because we just sent them AP_SIG_GRACEFUL). This happens pretty + * rapidly... and for each one that exits we'll start a new one until + * we reach at least daemons_min_free. But we may be permitted to + * start more than that, so we'll just keep track of how many we're + * supposed to start up without the 1 second penalty between each fork. + */ + remaining_children_to_start = ap_daemons_to_start; + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } + if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } + else { + /* give the system some time to recover before kicking into + * exponential mode */ + hold_off_on_exponential_spawning = 10; + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_version()); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + mpm_state = AP_MPMQ_RUNNING; + + server_main_loop(remaining_children_to_start); + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + * (By "gracefully" we don't mean graceful in the same sense as + * "apachectl graceful" where we allow old connections to finish.) + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + if (!child_fatal) { + /* cleanup pid file on normal shutdown */ + const char *pidfile = NULL; + pidfile = ap_server_root_relative (pconf, ap_pid_fname); + if ( pidfile != NULL && unlink(pidfile) == 0) + ap_log_error(APLOG_MARK, APLOG_INFO, 0, + ap_server_conf, + "removed PID file %s (pid=%ld)", + pidfile, (long)getpid()); + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, + ap_server_conf, "caught SIGTERM, shutting down"); + } + return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + + if (one_process) { + /* not worth thinking about */ + return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; + + if (is_graceful) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + AP_SIG_GRACEFUL_STRING " received. Doing graceful restart"); + /* wake up the children...time to die. But we'll have more soon */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE); + + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. + */ + + } + else { + /* Kill 'em all. Since the child acts the same on the parents SIGTERM + * and a SIGHUP, we may as well use the same signal, because some user + * pthreads are stealing signals from us left and right. + */ + ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE); + + ap_reclaim_child_processes(1); /* Start with SIGTERM */ + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + + return 0; +} + +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ +static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + + pconf = p; + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, + NULL, "no listening sockets available, shutting down"); + return DONE; + } + + if (!one_process) { + if ((rv = ap_mpm_pod_open(pconf, &pod))) { + ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, + "Could not open pipe-of-death."); + return DONE; + } + } + return OK; +} + +static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + static int restart_num = 0; + int no_detach, debug, foreground; + ap_directive_t *pdir; + ap_directive_t *max_clients = NULL; + apr_status_t rv; + + mpm_state = AP_MPMQ_STARTING; + + /* make sure that "ThreadsPerChild" gets set before "MaxClients" */ + for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { + if (strncasecmp(pdir->directive, "ThreadsPerChild", 15) == 0) { + if (!max_clients) { + break; /* we're in the clear, got ThreadsPerChild first */ + } + else { + /* now to swap the data */ + ap_directive_t temp; + + temp.directive = pdir->directive; + temp.args = pdir->args; + /* Make sure you don't change 'next', or you may get loops! */ + /* XXX: first_child, parent, and data can never be set + * for these directives, right? -aaron */ + temp.filename = pdir->filename; + temp.line_num = pdir->line_num; + + pdir->directive = max_clients->directive; + pdir->args = max_clients->args; + pdir->filename = max_clients->filename; + pdir->line_num = max_clients->line_num; + + max_clients->directive = temp.directive; + max_clients->args = temp.args; + max_clients->filename = temp.filename; + max_clients->line_num = temp.line_num; + break; + } + } + else if (!max_clients + && strncasecmp(pdir->directive, "MaxClients", 10) == 0) { + max_clients = pdir; + } + } + + debug = ap_exists_config_define("DEBUG"); + + if (debug) { + foreground = one_process = 1; + no_detach = 0; + } + else { + one_process = ap_exists_config_define("ONE_PROCESS"); + no_detach = ap_exists_config_define("NO_DETACH"); + foreground = ap_exists_config_define("FOREGROUND"); + } + + /* sigh, want this only the second time around */ + if (restart_num++ == 1) { + is_graceful = 0; + + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + parent_pid = ap_my_pid = getpid(); + } + + unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + min_spare_threads = DEFAULT_MIN_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + max_spare_threads = DEFAULT_MAX_FREE_DAEMON * DEFAULT_THREADS_PER_CHILD; + ap_daemons_limit = server_limit; + ap_threads_per_child = DEFAULT_THREADS_PER_CHILD; + ap_pid_fname = DEFAULT_PIDLOG; + ap_lock_fname = DEFAULT_LOCKFILE; + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE + ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} + +static void worker_hooks(apr_pool_t *p) +{ + /* The worker open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + one_process = 0; + + ap_hook_open_logs(worker_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + +static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_daemons_to_start = atoi(arg); + return NULL; +} + +static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + min_spare_threads = atoi(arg); + if (min_spare_threads <= 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: detected MinSpareThreads set to non-positive."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Resetting to 1 to avoid almost certain Apache failure."); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Please read the documentation."); + min_spare_threads = 1; + } + + return NULL; +} + +static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + max_spare_threads = atoi(arg); + return NULL; +} + +static const char *set_max_clients (cmd_parms *cmd, void *dummy, + const char *arg) +{ + int max_clients; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + /* It is ok to use ap_threads_per_child here because we are + * sure that it gets set before MaxClients in the pre_config stage. */ + max_clients = atoi(arg); + if (max_clients < ap_threads_per_child) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) must be at least as large", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " as ThreadsPerChild (%d). Automatically", + ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " increasing MaxClients to %d.", + ap_threads_per_child); + max_clients = ap_threads_per_child; + } + ap_daemons_limit = max_clients / ap_threads_per_child; + if ((max_clients > 0) && (max_clients % ap_threads_per_child)) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients (%d) is not an integer multiple", + max_clients); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " of ThreadsPerChild (%d), lowering MaxClients to %d", + ap_threads_per_child, + ap_daemons_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " for a maximum of %d child processes,", + ap_daemons_limit); + max_clients = ap_daemons_limit * ap_threads_per_child; + } + if (ap_daemons_limit > server_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: MaxClients of %d would require %d servers,", + max_clients, ap_daemons_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " and would exceed the ServerLimit value of %d.", + server_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " Automatically lowering MaxClients to %d. To increase,", + server_limit * ap_threads_per_child); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " please see the ServerLimit directive."); + ap_daemons_limit = server_limit; + } + else if (ap_daemons_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); + ap_daemons_limit = 1; + } + return NULL; +} + +static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_threads_per_child = atoi(arg); + if (ap_threads_per_child > thread_limit) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadsPerChild of %d exceeds ThreadLimit " + "value of %d", ap_threads_per_child, + thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "threads, lowering ThreadsPerChild to %d. To increase, please" + " see the", thread_limit); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " ThreadLimit directive."); + ap_threads_per_child = thread_limit; + } + else if (ap_threads_per_child < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadsPerChild > 0, setting to 1"); + ap_threads_per_child = 1; + } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_server_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ + if (first_server_limit && + tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + server_limit = tmp_server_limit; + + if (server_limit > MAX_SERVER_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ServerLimit of %d exceeds compile time limit " + "of %d servers,", server_limit, MAX_SERVER_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); + server_limit = MAX_SERVER_LIMIT; + } + else if (server_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); + server_limit = 1; + } + return NULL; +} + +static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ + int tmp_thread_limit; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_thread_limit = atoi(arg); + /* you cannot change ThreadLimit across a restart; ignore + * any such attempts + */ + if (first_thread_limit && + tmp_thread_limit != thread_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later + */ + changed_limit_at_restart = 1; + return NULL; + } + thread_limit = tmp_thread_limit; + + if (thread_limit > MAX_THREAD_LIMIT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: ThreadLimit of %d exceeds compile time limit " + "of %d servers,", thread_limit, MAX_THREAD_LIMIT); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " lowering ThreadLimit to %d.", MAX_THREAD_LIMIT); + thread_limit = MAX_THREAD_LIMIT; + } + else if (thread_limit < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ThreadLimit > 0, setting to 1"); + thread_limit = 1; + } + return NULL; +} + +static const command_rec worker_cmds[] = { +UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), +AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF, + "Minimum number of idle threads, to handle request spikes"), +AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF, + "Maximum number of idle threads"), +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, + "Maximum number of threads alive at the same time"), +AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, + "Number of threads each child creates"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, + "Maximum number of child processes for this run of Apache"), +AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, + "Maximum number of worker threads per child process for this run of Apache - Upper limit for ThreadsPerChild"), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA mpm_worker_module = { + MPM20_MODULE_STUFF, + ap_mpm_rewrite_args, /* hook to run before apache parses args */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + NULL, /* create per-server config structure */ + NULL, /* merge per-server config structures */ + worker_cmds, /* command apr_table_t */ + worker_hooks /* register_hooks */ +}; + diff --git a/trunk/server/mpm_common.c b/trunk/server/mpm_common.c new file mode 100644 index 0000000000..2d502b47a6 --- /dev/null +++ b/trunk/server/mpm_common.c @@ -0,0 +1,1153 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The purpose of this file is to store the code that MOST mpm's will need + * this does not mean a function only goes into this file if every MPM needs + * it. It means that if a function is needed by more than one MPM, and + * future maintenance would be served by making the code common, then the + * function belongs here. + * + * This is going in src/main because it is not platform specific, it is + * specific to multi-process servers, but NOT to Unix. Which is why it + * does not belong in src/os/unix + */ + +#include "apr.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_strings.h" +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_getopt.h" +#include "apr_optional.h" +#include "apr_allocator.h" + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_main.h" +#include "mpm.h" +#include "mpm_common.h" +#include "ap_mpm.h" +#include "ap_listen.h" +#include "mpm_default.h" + +#ifdef AP_MPM_WANT_SET_SCOREBOARD +#include "scoreboard.h" +#endif + +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +#ifdef AP_MPM_WANT_RECLAIM_CHILD_PROCESSES + +typedef enum {DO_NOTHING, SEND_SIGTERM, SEND_SIGKILL, GIVEUP} action_t; + +typedef struct extra_process_t { + struct extra_process_t *next; + pid_t pid; +} extra_process_t; + +static extra_process_t *extras; + +void ap_register_extra_mpm_process(pid_t pid) +{ + extra_process_t *p = (extra_process_t *)malloc(sizeof(extra_process_t)); + + p->next = extras; + p->pid = pid; + extras = p; +} + +int ap_unregister_extra_mpm_process(pid_t pid) +{ + extra_process_t *cur = extras; + extra_process_t *prev = NULL; + + while (cur && cur->pid != pid) { + prev = cur; + cur = cur->next; + } + + if (cur) { + if (prev) { + prev->next = cur->next; + } + else { + extras = cur->next; + } + free(cur); + return 1; /* found */ + } + else { + /* we don't know about any such process */ + return 0; + } +} + +static int reclaim_one_pid(pid_t pid, action_t action) +{ + apr_proc_t proc; + apr_status_t waitret; + + proc.pid = pid; + waitret = apr_proc_wait(&proc, NULL, NULL, APR_NOWAIT); + if (waitret != APR_CHILD_NOTDONE) { + return 1; + } + + switch(action) { + case DO_NOTHING: + break; + + case SEND_SIGTERM: + /* ok, now it's being annoying */ + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, ap_server_conf, + "child process %" APR_PID_T_FMT + " still did not exit, " + "sending a SIGTERM", + pid); + kill(pid, SIGTERM); + break; + + case SEND_SIGKILL: + ap_log_error(APLOG_MARK, APLOG_ERR, + 0, ap_server_conf, + "child process %" APR_PID_T_FMT + " still did not exit, " + "sending a SIGKILL", + pid); +#ifndef BEOS + kill(pid, SIGKILL); +#else + /* sending a SIGKILL kills the entire team on BeOS, and as + * httpd thread is part of that team it removes any chance + * of ever doing a restart. To counter this I'm changing to + * use a kinder, gentler way of killing a specific thread + * that is just as effective. + */ + kill_thread(pid); +#endif + break; + + case GIVEUP: + /* gave it our best shot, but alas... If this really + * is a child we are trying to kill and it really hasn't + * exited, we will likely fail to bind to the port + * after the restart. + */ + ap_log_error(APLOG_MARK, APLOG_ERR, + 0, ap_server_conf, + "could not make child process %" APR_PID_T_FMT + " exit, " + "attempting to continue anyway", + pid); + break; + } + + return 0; +} + +void ap_reclaim_child_processes(int terminate) +{ + apr_time_t waittime = 1024 * 16; + int i; + extra_process_t *cur_extra; + int not_dead_yet; + int max_daemons; + apr_time_t starttime = apr_time_now(); + /* this table of actions and elapsed times tells what action is taken + * at which elapsed time from starting the reclaim + */ + struct { + action_t action; + apr_time_t action_time; + } action_table[] = { + {DO_NOTHING, 0}, /* dummy entry for iterations where we reap + * children but take no action against + * stragglers + */ + {SEND_SIGTERM, apr_time_from_sec(3)}, + {SEND_SIGTERM, apr_time_from_sec(5)}, + {SEND_SIGTERM, apr_time_from_sec(7)}, + {SEND_SIGKILL, apr_time_from_sec(9)}, + {GIVEUP, apr_time_from_sec(10)} + }; + int cur_action; /* index of action we decided to take this + * iteration + */ + int next_action = 1; /* index of first real action */ + + ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_daemons); + + do { + apr_sleep(waittime); + /* don't let waittime get longer than 1 second; otherwise, we don't + * react quickly to the last child exiting, and taking action can + * be delayed + */ + waittime = waittime * 4; + if (waittime > apr_time_from_sec(1)) { + waittime = apr_time_from_sec(1); + } + + /* see what action to take, if any */ + if (action_table[next_action].action_time <= apr_time_now() - starttime) { + cur_action = next_action; + ++next_action; + } + else { + cur_action = 0; /* nothing to do */ + } + + /* now see who is done */ + not_dead_yet = 0; + for (i = 0; i < max_daemons; ++i) { + pid_t pid = MPM_CHILD_PID(i); + + if (pid == 0) { + continue; /* not every scoreboard entry is in use */ + } + + if (reclaim_one_pid(pid, action_table[cur_action].action)) { + MPM_NOTE_CHILD_KILLED(i); + } + else { + ++not_dead_yet; + } + } + + cur_extra = extras; + while (cur_extra) { + extra_process_t *next = cur_extra->next; + + if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) { + AP_DEBUG_ASSERT(1 == ap_unregister_extra_mpm_process(cur_extra->pid)); + } + else { + ++not_dead_yet; + } + cur_extra = next; + } +#if APR_HAS_OTHER_CHILD + apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART); +#endif + + } while (not_dead_yet > 0 && + action_table[cur_action].action != GIVEUP); +} +#endif /* AP_MPM_WANT_RECLAIM_CHILD_PROCESSES */ + +#ifdef AP_MPM_WANT_WAIT_OR_TIMEOUT + +/* number of calls to wait_or_timeout between writable probes */ +#ifndef INTERVAL_OF_WRITABLE_PROBES +#define INTERVAL_OF_WRITABLE_PROBES 10 +#endif +static int wait_or_timeout_counter; + +void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret, + apr_pool_t *p) +{ + apr_status_t rv; + + ++wait_or_timeout_counter; + if (wait_or_timeout_counter == INTERVAL_OF_WRITABLE_PROBES) { + wait_or_timeout_counter = 0; + } + + rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p); + if (APR_STATUS_IS_EINTR(rv)) { + ret->pid = -1; + return; + } + + if (APR_STATUS_IS_CHILD_DONE(rv)) { + return; + } + +#ifdef NEED_WAITPID + if ((ret = reap_children(exitcode, status)) > 0) { + return; + } +#endif + + apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL); + ret->pid = -1; + return; +} +#endif /* AP_MPM_WANT_WAIT_OR_TIMEOUT */ + +#ifdef AP_MPM_WANT_PROCESS_CHILD_STATUS +int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status) +{ + int signum = status; + const char *sigdesc = apr_signal_description_get(signum); + + /* Child died... if it died due to a fatal error, + * we should simply bail out. The caller needs to + * check for bad rc from us and exit, running any + * appropriate cleanups. + * + * If the child died due to a resource shortage, + * the parent should limit the rate of forking + */ + if (APR_PROC_CHECK_EXIT(why)) { + if (status == APEXIT_CHILDSICK) { + return status; + } + + if (status == APEXIT_CHILDFATAL) { + ap_log_error(APLOG_MARK, APLOG_ALERT, + 0, ap_server_conf, + "Child %" APR_PID_T_FMT + " returned a Fatal error... Apache is exiting!", + pid->pid); + return APEXIT_CHILDFATAL; + } + + return 0; + } + + if (APR_PROC_CHECK_SIGNALED(why)) { + switch (signum) { + case SIGTERM: + case SIGHUP: + case AP_SIG_GRACEFUL: + case SIGKILL: + break; + + default: + if (APR_PROC_CHECK_CORE_DUMP(why)) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, + 0, ap_server_conf, + "child pid %ld exit signal %s (%d), " + "possible coredump in %s", + (long)pid->pid, sigdesc, signum, + ap_coredump_dir); + } + else { + ap_log_error(APLOG_MARK, APLOG_NOTICE, + 0, ap_server_conf, + "child pid %ld exit signal %s (%d)", + (long)pid->pid, sigdesc, signum); + } + } + } + return 0; +} +#endif /* AP_MPM_WANT_PROCESS_CHILD_STATUS */ + +#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF) +void ap_sock_disable_nagle(apr_socket_t *s) +{ + /* The Nagle algorithm says that we should delay sending partial + * packets in hopes of getting more data. We don't want to do + * this; we are not telnet. There are bad interactions between + * persistent connections and Nagle's algorithm that have very severe + * performance penalties. (Failing to disable Nagle is not much of a + * problem with simple HTTP.) + * + * In spite of these problems, failure here is not a shooting offense. + */ + apr_status_t status = apr_socket_opt_set(s, APR_TCP_NODELAY, 1); + + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, status, ap_server_conf, + "apr_socket_opt_set: (TCP_NODELAY)"); + } +} +#endif + +#ifdef HAVE_GETPWNAM +AP_DECLARE(uid_t) ap_uname2id(const char *name) +{ + struct passwd *ent; + + if (name[0] == '#') + return (atoi(&name[1])); + + if (!(ent = getpwnam(name))) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s: bad user name %s", ap_server_argv0, name); + exit(1); + } + + return (ent->pw_uid); +} +#endif + +#ifdef HAVE_GETGRNAM +AP_DECLARE(gid_t) ap_gname2id(const char *name) +{ + struct group *ent; + + if (name[0] == '#') + return (atoi(&name[1])); + + if (!(ent = getgrnam(name))) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "%s: bad group name %s", ap_server_argv0, name); + exit(1); + } + + return (ent->gr_gid); +} +#endif + +#ifndef HAVE_INITGROUPS +int initgroups(const char *name, gid_t basegid) +{ +#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX) || defined(TPF) || defined(__TANDEM) || defined(OS2) || defined(WIN32) || defined(NETWARE) +/* QNX, MPE and BeOS do not appear to support supplementary groups. */ + return 0; +#else /* ndef QNX */ + gid_t groups[NGROUPS_MAX]; + struct group *g; + int index = 0; + + setgrent(); + + groups[index++] = basegid; + + while (index < NGROUPS_MAX && ((g = getgrent()) != NULL)) { + if (g->gr_gid != basegid) { + char **names; + + for (names = g->gr_mem; *names != NULL; ++names) { + if (!strcmp(*names, name)) + groups[index++] = g->gr_gid; + } + } + } + + endgrent(); + + return setgroups(index, groups); +#endif /* def QNX */ +} +#endif /* def NEED_INITGROUPS */ + +#ifdef AP_MPM_USES_POD + +AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod) +{ + apr_status_t rv; + + *pod = apr_palloc(p, sizeof(**pod)); + rv = apr_file_pipe_create(&((*pod)->pod_in), &((*pod)->pod_out), p); + if (rv != APR_SUCCESS) { + return rv; + } + + apr_file_pipe_timeout_set((*pod)->pod_in, 0); + (*pod)->p = p; + + /* close these before exec. */ + apr_file_inherit_unset((*pod)->pod_in); + apr_file_inherit_unset((*pod)->pod_out); + + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_check(ap_pod_t *pod) +{ + char c; + apr_size_t len = 1; + apr_status_t rv; + + rv = apr_file_read(pod->pod_in, &c, &len); + + if ((rv == APR_SUCCESS) && (len == 1)) { + return APR_SUCCESS; + } + + if (rv != APR_SUCCESS) { + return rv; + } + + return AP_NORESTART; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod) +{ + apr_status_t rv; + + rv = apr_file_close(pod->pod_out); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_file_close(pod->pod_in); + if (rv != APR_SUCCESS) { + return rv; + } + + return APR_SUCCESS; +} + +static apr_status_t pod_signal_internal(ap_pod_t *pod) +{ + apr_status_t rv; + char char_of_death = '!'; + apr_size_t one = 1; + + rv = apr_file_write(pod->pod_out, &char_of_death, &one); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } + + return rv; +} + +/* This function connects to the server, then immediately closes the connection. + * This permits the MPM to skip the poll when there is only one listening + * socket, because it provides a alternate way to unblock an accept() when + * the pod is used. + */ +static apr_status_t dummy_connection(ap_pod_t *pod) +{ + apr_status_t rv; + apr_socket_t *sock; + apr_pool_t *p; + + /* create a temporary pool for the socket. pconf stays around too long */ + rv = apr_pool_create(&p, pod->p); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_create(&sock, ap_listeners->bind_addr->family, + SOCK_STREAM, 0, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "get socket to connect to listener"); + apr_pool_destroy(p); + return rv; + } + + /* on some platforms (e.g., FreeBSD), the kernel won't accept many + * queued connections before it starts blocking local connects... + * we need to keep from blocking too long and instead return an error, + * because the MPM won't want to hold up a graceful restart for a + * long time + */ + rv = apr_socket_timeout_set(sock, apr_time_from_sec(3)); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "set timeout on socket to connect to listener"); + apr_socket_close(sock); + apr_pool_destroy(p); + return rv; + } + + rv = apr_socket_connect(sock, ap_listeners->bind_addr); + if (rv != APR_SUCCESS) { + int log_level = APLOG_WARNING; + + if (APR_STATUS_IS_TIMEUP(rv)) { + /* probably some server processes bailed out already and there + * is nobody around to call accept and clear out the kernel + * connection queue; usually this is not worth logging + */ + log_level = APLOG_DEBUG; + } + + ap_log_error(APLOG_MARK, log_level, rv, ap_server_conf, + "connect to listener on %pI", ap_listeners->bind_addr); + } + + apr_socket_close(sock); + apr_pool_destroy(p); + + return rv; +} + +AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod) +{ + apr_status_t rv; + + rv = pod_signal_internal(pod); + if (rv != APR_SUCCESS) { + return rv; + } + + return dummy_connection(pod); +} + +void ap_mpm_pod_killpg(ap_pod_t *pod, int num) +{ + int i; + apr_status_t rv = APR_SUCCESS; + + /* we don't write anything to the pod here... we assume + * that the would-be reader of the pod has another way to + * see that it is time to die once we wake it up + * + * writing lots of things to the pod at once is very + * problematic... we can fill the kernel pipe buffer and + * be blocked until somebody consumes some bytes or + * we hit a timeout... if we hit a timeout we can't just + * keep trying because maybe we'll never successfully + * write again... but then maybe we'll leave would-be + * readers stranded (a number of them could be tied up for + * a while serving time-consuming requests) + */ + for (i = 0; i < num && rv == APR_SUCCESS; i++) { + rv = dummy_connection(pod); + } +} +#endif /* #ifdef AP_MPM_USES_POD */ + +/* standard mpm configuration handling */ +#ifdef AP_MPM_WANT_SET_PIDFILE +const char *ap_pid_fname = NULL; + +const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (cmd->server->is_virtual) { + return "PidFile directive not allowed in "; + } + + ap_pid_fname = arg; + return NULL; +} +#endif + +#ifdef AP_MPM_WANT_SET_SCOREBOARD +const char * ap_mpm_set_scoreboard(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_scoreboard_fname = arg; + return NULL; +} +#endif + +#ifdef AP_MPM_WANT_SET_LOCKFILE +const char *ap_lock_fname = NULL; + +const char *ap_mpm_set_lockfile(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_lock_fname = arg; + return NULL; +} +#endif + +#ifdef AP_MPM_WANT_SET_MAX_REQUESTS +int ap_max_requests_per_child = 0; + +const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_max_requests_per_child = atoi(arg); + + return NULL; +} +#endif + +#ifdef AP_MPM_WANT_SET_COREDUMPDIR +char ap_coredump_dir[MAX_STRING_LEN]; +int ap_coredumpdir_configured; + +const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy, + const char *arg) +{ + apr_status_t rv; + apr_finfo_t finfo; + const char *fname; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + fname = ap_server_root_relative(cmd->pool, arg); + if (!fname) { + return apr_pstrcat(cmd->pool, "Invalid CoreDumpDirectory path ", + arg, NULL); + } + if ((rv = apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool)) != APR_SUCCESS) { + return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, + " does not exist", NULL); + } + if (finfo.filetype != APR_DIR) { + return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, + " is not a directory", NULL); + } + apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir)); + ap_coredumpdir_configured = 1; + return NULL; +} +#endif + +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH +apr_lockmech_e ap_accept_lock_mech = APR_LOCK_DEFAULT; + +const char ap_valid_accept_mutex_string[] = + "Valid accept mutexes for this platform and MPM are: default" +#if APR_HAS_FLOCK_SERIALIZE + ", flock" +#endif +#if APR_HAS_FCNTL_SERIALIZE + ", fcntl" +#endif +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) + ", sysvsem" +#endif +#if APR_HAS_POSIXSEM_SERIALIZE + ", posixsem" +#endif +#if APR_HAS_PROC_PTHREAD_SERIALIZE + ", pthread" +#endif + "."; + +AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (!strcasecmp(arg, "default")) { + ap_accept_lock_mech = APR_LOCK_DEFAULT; + } +#if APR_HAS_FLOCK_SERIALIZE + else if (!strcasecmp(arg, "flock")) { + ap_accept_lock_mech = APR_LOCK_FLOCK; + } +#endif +#if APR_HAS_FCNTL_SERIALIZE + else if (!strcasecmp(arg, "fcntl")) { + ap_accept_lock_mech = APR_LOCK_FCNTL; + } +#endif + + /* perchild can't use SysV sems because the permissions on the accept + * mutex can't be set to allow all processes to use the mutex and + * at the same time keep all users from being able to dink with the + * mutex + */ +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) + else if (!strcasecmp(arg, "sysvsem")) { + ap_accept_lock_mech = APR_LOCK_SYSVSEM; + } +#endif +#if APR_HAS_POSIXSEM_SERIALIZE + else if (!strcasecmp(arg, "posixsem")) { + ap_accept_lock_mech = APR_LOCK_POSIXSEM; + } +#endif +#if APR_HAS_PROC_PTHREAD_SERIALIZE + else if (!strcasecmp(arg, "pthread")) { + ap_accept_lock_mech = APR_LOCK_PROC_PTHREAD; + } +#endif + else { + return apr_pstrcat(cmd->pool, arg, " is an invalid mutex mechanism; ", + ap_valid_accept_mutex_string, NULL); + } + return NULL; +} + +#endif + +#ifdef AP_MPM_WANT_SIGNAL_SERVER + +static const char *dash_k_arg; + +static int send_signal(pid_t pid, int sig) +{ + if (kill(pid, sig) < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL, + "sending signal to server"); + return 1; + } + return 0; +} + +int ap_signal_server(int *exit_status, apr_pool_t *pconf) +{ + apr_status_t rv; + pid_t otherpid; + int running = 0; + int have_pid_file = 0; + const char *status; + + *exit_status = 0; + + rv = ap_read_pid(pconf, ap_pid_fname, &otherpid); + if (rv != APR_SUCCESS) { + if (rv != APR_ENOENT) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL, + "Error retrieving pid file %s", ap_pid_fname); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "Remove it before continuing if it is corrupted."); + *exit_status = 1; + return 1; + } + status = "httpd (no pid file) not running"; + } + else { + have_pid_file = 1; + if (kill(otherpid, 0) == 0) { + running = 1; + status = apr_psprintf(pconf, + "httpd (pid %" APR_PID_T_FMT ") already " + "running", otherpid); + } + else { + status = apr_psprintf(pconf, + "httpd (pid %" APR_PID_T_FMT "?) not running", + otherpid); + } + } + + if (!strcmp(dash_k_arg, "start")) { + if (running) { + printf("%s\n", status); + return 1; + } + } + + if (!strcmp(dash_k_arg, "stop")) { + if (!running) { + printf("%s\n", status); + } + else { + send_signal(otherpid, SIGTERM); + } + return 1; + } + + if (!strcmp(dash_k_arg, "restart")) { + if (!running) { + printf("httpd not running, trying to start\n"); + } + else { + *exit_status = send_signal(otherpid, SIGHUP); + return 1; + } + } + + if (!strcmp(dash_k_arg, "graceful")) { + if (!running) { + printf("httpd not running, trying to start\n"); + } + else { + *exit_status = send_signal(otherpid, SIGUSR1); + return 1; + } + } + + return 0; +} + +void ap_mpm_rewrite_args(process_rec *process) +{ + apr_array_header_t *mpm_new_argv; + apr_status_t rv; + apr_getopt_t *opt; + char optbuf[3]; + const char *optarg; + int fixed_args; + + mpm_new_argv = apr_array_make(process->pool, process->argc, + sizeof(const char **)); + *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; + fixed_args = mpm_new_argv->nelts; + apr_getopt_init(&opt, process->pool, process->argc, process->argv); + opt->errfn = NULL; + optbuf[0] = '-'; + /* option char returned by apr_getopt() will be stored in optbuf[1] */ + optbuf[2] = '\0'; + while ((rv = apr_getopt(opt, "k:" AP_SERVER_BASEARGS, + optbuf + 1, &optarg)) == APR_SUCCESS) { + switch(optbuf[1]) { + case 'k': + if (!dash_k_arg) { + if (!strcmp(optarg, "start") || !strcmp(optarg, "stop") || + !strcmp(optarg, "restart") || !strcmp(optarg, "graceful")) { + dash_k_arg = optarg; + break; + } + } + default: + *(const char **)apr_array_push(mpm_new_argv) = + apr_pstrdup(process->pool, optbuf); + if (optarg) { + *(const char **)apr_array_push(mpm_new_argv) = optarg; + } + } + } + + /* back up to capture the bad argument */ + if (rv == APR_BADCH || rv == APR_BADARG) { + opt->ind--; + } + + while (opt->ind < opt->argc) { + *(const char **)apr_array_push(mpm_new_argv) = + apr_pstrdup(process->pool, opt->argv[opt->ind++]); + } + + process->argc = mpm_new_argv->nelts; + process->argv = (const char * const *)mpm_new_argv->elts; + + if (dash_k_arg) { + APR_REGISTER_OPTIONAL_FN(ap_signal_server); + } +} + +#endif /* AP_MPM_WANT_SIGNAL_SERVER */ + +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE +apr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; + +const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, + const char *arg) +{ + long value; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + value = strtol(arg, NULL, 0); + if (value < 0 || errno == ERANGE) + return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ", + arg, NULL); + + ap_max_mem_free = (apr_uint32_t)value * 1024; + + return NULL; +} + +#endif /* AP_MPM_WANT_SET_MAX_MEM_FREE */ + +#ifdef AP_MPM_WANT_SET_STACKSIZE +apr_size_t ap_thread_stacksize = 0; /* use system default */ + +const char *ap_mpm_set_thread_stacksize(cmd_parms *cmd, void *dummy, + const char *arg) +{ + long value; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + value = strtol(arg, NULL, 0); + if (value < 0 || errno == ERANGE) + return apr_pstrcat(cmd->pool, "Invalid ThreadStackSize value: ", + arg, NULL); + + ap_thread_stacksize = (apr_size_t)value; + + return NULL; +} + +#endif /* AP_MPM_WANT_SET_STACKSIZE */ + +#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER + +static pid_t parent_pid, my_pid; +apr_pool_t *pconf; + +#if AP_ENABLE_EXCEPTION_HOOK + +static int exception_hook_enabled; + +const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + if (cmd->server->is_virtual) { + return "EnableExceptionHook directive not allowed in "; + } + + if (strcasecmp(arg, "on") == 0) { + exception_hook_enabled = 1; + } + else if (strcasecmp(arg, "off") == 0) { + exception_hook_enabled = 0; + } + else { + return "parameter must be 'on' or 'off'"; + } + + return NULL; +} + +APR_HOOK_STRUCT( + APR_HOOK_LINK(fatal_exception) +) + +AP_IMPLEMENT_HOOK_RUN_ALL(int, fatal_exception, + (ap_exception_info_t *ei), (ei), OK, DECLINED) + +static void run_fatal_exception_hook(int sig) +{ + ap_exception_info_t ei = {0}; + + if (exception_hook_enabled && + geteuid() != 0 && + my_pid != parent_pid) { + ei.sig = sig; + ei.pid = my_pid; + ap_run_fatal_exception(&ei); + } +} +#endif /* AP_ENABLE_EXCEPTION_HOOK */ + +/* handle all varieties of core dumping signals */ +static void sig_coredump(int sig) +{ + apr_filepath_set(ap_coredump_dir, pconf); + apr_signal(sig, SIG_DFL); +#if AP_ENABLE_EXCEPTION_HOOK + run_fatal_exception_hook(sig); +#endif + /* linuxthreads issue calling getpid() here: + * This comparison won't match if the crashing thread is + * some module's thread that runs in the parent process. + * The fallout, which is limited to linuxthreads: + * The special log message won't be written when such a + * thread in the parent causes the parent to crash. + */ + if (getpid() == parent_pid) { + ap_log_error(APLOG_MARK, APLOG_NOTICE, + 0, ap_server_conf, + "seg fault or similar nasty error detected " + "in the parent process"); + /* XXX we can probably add some rudimentary cleanup code here, + * like getting rid of the pid file. If any additional bad stuff + * happens, we are protected from recursive errors taking down the + * system since this function is no longer the signal handler GLA + */ + } + kill(getpid(), sig); + /* At this point we've got sig blocked, because we're still inside + * the signal handler. When we leave the signal handler it will + * be unblocked, and we'll take the signal... and coredump or whatever + * is appropriate for this particular Unix. In addition the parent + * will see the real signal we received -- whereas if we called + * abort() here, the parent would only see SIGABRT. + */ +} + +apr_status_t ap_fatal_signal_child_setup(server_rec *s) +{ + my_pid = getpid(); + return APR_SUCCESS; +} + +apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf) +{ +#ifndef NO_USE_SIGACTION + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + +#if defined(SA_ONESHOT) + sa.sa_flags = SA_ONESHOT; +#elif defined(SA_RESETHAND) + sa.sa_flags = SA_RESETHAND; +#else + sa.sa_flags = 0; +#endif + + sa.sa_handler = sig_coredump; + if (sigaction(SIGSEGV, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGSEGV)"); +#ifdef SIGBUS + if (sigaction(SIGBUS, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGBUS)"); +#endif +#ifdef SIGABORT + if (sigaction(SIGABORT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABORT)"); +#endif +#ifdef SIGABRT + if (sigaction(SIGABRT, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGABRT)"); +#endif +#ifdef SIGILL + if (sigaction(SIGILL, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, s, "sigaction(SIGILL)"); +#endif + +#else /* NO_USE_SIGACTION */ + + apr_signal(SIGSEGV, sig_coredump); +#ifdef SIGBUS + apr_signal(SIGBUS, sig_coredump); +#endif /* SIGBUS */ +#ifdef SIGABORT + apr_signal(SIGABORT, sig_coredump); +#endif /* SIGABORT */ +#ifdef SIGABRT + apr_signal(SIGABRT, sig_coredump); +#endif /* SIGABRT */ +#ifdef SIGILL + apr_signal(SIGILL, sig_coredump); +#endif /* SIGILL */ + +#endif /* NO_USE_SIGACTION */ + + pconf = in_pconf; + parent_pid = my_pid = getpid(); + + return APR_SUCCESS; +} + +#endif /* AP_MPM_WANT_FATAL_SIGNAL_HANDLER */ diff --git a/trunk/server/protocol.c b/trunk/server/protocol.c new file mode 100644 index 0000000000..8fa995d59a --- /dev/null +++ b/trunk/server/protocol.c @@ -0,0 +1,1580 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_protocol.c --- routines which directly communicate with the client. + * + * Code originally by Rob McCool; much redone by Robert S. Thau + * and the Apache Software Foundation. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_lib.h" +#include "apr_signal.h" +#include "apr_strmatch.h" + +#define APR_WANT_STDIO /* for sscanf */ +#define APR_WANT_STRFUNC +#define APR_WANT_MEMFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "util_filter.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_main.h" +#include "http_request.h" +#include "http_vhost.h" +#include "http_log.h" /* For errors detected in basic auth common + * support code... */ +#include "mod_core.h" +#include "util_charset.h" +#include "util_ebcdic.h" +#include "scoreboard.h" + +#if APR_HAVE_STDARG_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + + +APR_HOOK_STRUCT( + APR_HOOK_LINK(post_read_request) + APR_HOOK_LINK(log_transaction) + APR_HOOK_LINK(http_scheme) + APR_HOOK_LINK(default_port) +) + +AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL; + + +/* Patterns to match in ap_make_content_type() */ +static const char *needcset[] = { + "text/plain", + "text/html", + NULL +}; +static const apr_strmatch_pattern **needcset_patterns; +static const apr_strmatch_pattern *charset_pattern; + +AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool) +{ + int i; + for (i = 0; needcset[i]; i++) { + continue; + } + needcset_patterns = (const apr_strmatch_pattern **) + apr_palloc(pool, (i + 1) * sizeof(apr_strmatch_pattern *)); + for (i = 0; needcset[i]; i++) { + needcset_patterns[i] = apr_strmatch_precompile(pool, needcset[i], 0); + } + needcset_patterns[i] = NULL; + charset_pattern = apr_strmatch_precompile(pool, "charset=", 0); +} + +/* + * Builds the content-type that should be sent to the client from the + * content-type specified. The following rules are followed: + * - if type is NULL, type is set to ap_default_type(r) + * - if charset adding is disabled, stop processing and return type. + * - then, if there are no parameters on type, add the default charset + * - return type + */ +AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type) +{ + const apr_strmatch_pattern **pcset; + core_dir_config *conf = + (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + core_request_config *request_conf; + apr_size_t type_len; + + if (!type) { + type = ap_default_type(r); + } + + if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) { + return type; + } + + request_conf = + ap_get_module_config(r->request_config, &core_module); + if (request_conf->suppress_charset) { + return type; + } + + type_len = strlen(type); + + if (apr_strmatch(charset_pattern, type, type_len) != NULL) { + /* already has parameter, do nothing */ + /* XXX we don't check the validity */ + ; + } + else { + /* see if it makes sense to add the charset. At present, + * we only add it if the Content-type is one of needcset[] + */ + for (pcset = needcset_patterns; *pcset ; pcset++) { + if (apr_strmatch(*pcset, type, type_len) != NULL) { + struct iovec concat[3]; + concat[0].iov_base = (void *)type; + concat[0].iov_len = type_len; + concat[1].iov_base = (void *)"; charset="; + concat[1].iov_len = sizeof("; charset=") - 1; + concat[2].iov_base = (void *)(conf->add_default_charset_name); + concat[2].iov_len = strlen(conf->add_default_charset_name); + type = apr_pstrcatv(r->pool, concat, 3, NULL); + break; + } + } + } + + return type; +} + +AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t clength) +{ + r->clength = clength; + apr_table_setn(r->headers_out, "Content-Length", + apr_off_t_toa(r->pool, clength)); +} + +/* + * Return the latest rational time from a request/mtime (modification time) + * pair. We return the mtime unless it's in the future, in which case we + * return the current time. We use the request time as a reference in order + * to limit the number of calls to time(). We don't check for futurosity + * unless the mtime is at least as new as the reference. + */ +AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime) +{ + apr_time_t now; + + /* For all static responses, it's almost certain that the file was + * last modified before the beginning of the request. So there's + * no reason to call time(NULL) again. But if the response has been + * created on demand, then it might be newer than the time the request + * started. In this event we really have to call time(NULL) again + * so that we can give the clients the most accurate Last-Modified. If we + * were given a time in the future, we return the current time - the + * Last-Modified can't be in the future. + */ + now = (mtime < r->request_time) ? r->request_time : apr_time_now(); + return (mtime > now) ? now : mtime; +} + +/* Min # of bytes to allocate when reading a request line */ +#define MIN_LINE_ALLOC 80 + +/* Get a line of protocol input, including any continuation lines + * caused by MIME folding (or broken clients) if fold != 0, and place it + * in the buffer s, of size n bytes, without the ending newline. + * + * If s is NULL, ap_rgetline_core will allocate necessary memory from r->pool. + * + * Returns APR_SUCCESS if there are no problems and sets *read to be + * the full length of s. + * + * APR_ENOSPC is returned if there is not enough buffer space. + * Other errors may be returned on other errors. + * + * The LF is *not* returned in the buffer. Therefore, a *read of 0 + * indicates that an empty line was read. + * + * Notes: Because the buffer uses 1 char for NUL, the most we can return is + * (n - 1) actual characters. + * + * If no LF is detected on the last line due to a dropped connection + * or a full buffer, that's considered an error. + */ +AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n, + apr_size_t *read, request_rec *r, + int fold, apr_bucket_brigade *bb) +{ + apr_status_t rv; + apr_bucket *e; + apr_size_t bytes_handled = 0, current_alloc = 0; + char *pos, *last_char = *s; + int do_alloc = (*s == NULL), saw_eos = 0; + + for (;;) { + apr_brigade_cleanup(bb); + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_GETLINE, + APR_BLOCK_READ, 0); + if (rv != APR_SUCCESS) { + return rv; + } + + /* Something horribly wrong happened. Someone didn't block! */ + if (APR_BRIGADE_EMPTY(bb)) { + return APR_EGENERAL; + } + + for (e = APR_BRIGADE_FIRST(bb); + e != APR_BRIGADE_SENTINEL(bb); + e = APR_BUCKET_NEXT(e)) + { + const char *str; + apr_size_t len; + + /* If we see an EOS, don't bother doing anything more. */ + if (APR_BUCKET_IS_EOS(e)) { + saw_eos = 1; + break; + } + + rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + return rv; + } + + if (len == 0) { + /* no use attempting a zero-byte alloc (hurts when + * using --with-efence --enable-pool-debug) or + * doing any of the other logic either + */ + continue; + } + + /* Would this overrun our buffer? If so, we'll die. */ + if (n < bytes_handled + len) { + *read = bytes_handled; + if (*s) { + /* ensure this string is NUL terminated */ + if (bytes_handled > 0) { + (*s)[bytes_handled-1] = '\0'; + } + else { + (*s)[0] = '\0'; + } + } + return APR_ENOSPC; + } + + /* Do we have to handle the allocation ourselves? */ + if (do_alloc) { + /* We'll assume the common case where one bucket is enough. */ + if (!*s) { + current_alloc = len; + if (current_alloc < MIN_LINE_ALLOC) { + current_alloc = MIN_LINE_ALLOC; + } + *s = apr_palloc(r->pool, current_alloc); + } + else if (bytes_handled + len > current_alloc) { + /* Increase the buffer size */ + apr_size_t new_size = current_alloc * 2; + char *new_buffer; + + if (bytes_handled + len > new_size) { + new_size = (bytes_handled + len) * 2; + } + + new_buffer = apr_palloc(r->pool, new_size); + + /* Copy what we already had. */ + memcpy(new_buffer, *s, bytes_handled); + current_alloc = new_size; + *s = new_buffer; + } + } + + /* Just copy the rest of the data to the end of the old buffer. */ + pos = *s + bytes_handled; + memcpy(pos, str, len); + last_char = pos + len - 1; + + /* We've now processed that new data - update accordingly. */ + bytes_handled += len; + } + + /* If we got a full line of input, stop reading */ + if (last_char && (*last_char == APR_ASCII_LF)) { + break; + } + } + + /* Now NUL-terminate the string at the end of the line; + * if the last-but-one character is a CR, terminate there */ + if (last_char > *s && last_char[-1] == APR_ASCII_CR) { + last_char--; + } + *last_char = '\0'; + bytes_handled = last_char - *s; + + /* If we're folding, we have more work to do. + * + * Note that if an EOS was seen, we know we can't have another line. + */ + if (fold && bytes_handled && !saw_eos) { + for (;;) { + const char *str; + apr_size_t len; + char c; + + /* Clear the temp brigade for this filter read. */ + apr_brigade_cleanup(bb); + + /* We only care about the first byte. */ + rv = ap_get_brigade(r->input_filters, bb, AP_MODE_SPECULATIVE, + APR_BLOCK_READ, 1); + if (rv != APR_SUCCESS) { + return rv; + } + + if (APR_BRIGADE_EMPTY(bb)) { + break; + } + + e = APR_BRIGADE_FIRST(bb); + + /* If we see an EOS, don't bother doing anything more. */ + if (APR_BUCKET_IS_EOS(e)) { + break; + } + + rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ); + if (rv != APR_SUCCESS) { + apr_brigade_cleanup(bb); + return rv; + } + + /* Found one, so call ourselves again to get the next line. + * + * FIXME: If the folding line is completely blank, should we + * stop folding? Does that require also looking at the next + * char? + */ + /* When we call destroy, the buckets are deleted, so save that + * one character we need. This simplifies our execution paths + * at the cost of one character read. + */ + c = *str; + if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) { + /* Do we have enough space? We may be full now. */ + if (bytes_handled >= n) { + *read = n; + /* ensure this string is terminated */ + (*s)[n-1] = '\0'; + return APR_ENOSPC; + } + else { + apr_size_t next_size, next_len; + char *tmp; + + /* If we're doing the allocations for them, we have to + * give ourselves a NULL and copy it on return. + */ + if (do_alloc) { + tmp = NULL; + } else { + /* We're null terminated. */ + tmp = last_char; + } + + next_size = n - bytes_handled; + + rv = ap_rgetline_core(&tmp, next_size, + &next_len, r, 0, bb); + if (rv != APR_SUCCESS) { + return rv; + } + + if (do_alloc && next_len > 0) { + char *new_buffer; + apr_size_t new_size = bytes_handled + next_len + 1; + + /* we need to alloc an extra byte for a null */ + new_buffer = apr_palloc(r->pool, new_size); + + /* Copy what we already had. */ + memcpy(new_buffer, *s, bytes_handled); + + /* copy the new line, including the trailing null */ + memcpy(new_buffer + bytes_handled, tmp, next_len + 1); + *s = new_buffer; + } + + last_char += next_len; + bytes_handled += next_len; + } + } + else { /* next character is not tab or space */ + break; + } + } + } + + *read = bytes_handled; + return APR_SUCCESS; +} + +#if APR_CHARSET_EBCDIC +AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n, + apr_size_t *read, request_rec *r, + int fold, apr_bucket_brigade *bb) +{ + /* on ASCII boxes, ap_rgetline is a macro which simply invokes + * ap_rgetline_core with the same parms + * + * on EBCDIC boxes, each complete http protocol input line needs to be + * translated into the code page used by the compiler. Since + * ap_rgetline_core uses recursion, we do the translation in a wrapper + * function to insure that each input character gets translated only once. + */ + apr_status_t rv; + + rv = ap_rgetline_core(s, n, read, r, fold, bb); + if (rv == APR_SUCCESS) { + ap_xlate_proto_from_ascii(*s, *read); + } + return rv; +} +#endif + +AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int fold) +{ + char *tmp_s = s; + apr_status_t rv; + apr_size_t len; + apr_bucket_brigade *tmp_bb; + + tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + rv = ap_rgetline(&tmp_s, n, &len, r, fold, tmp_bb); + apr_brigade_destroy(tmp_bb); + + /* Map the out-of-space condition to the old API. */ + if (rv == APR_ENOSPC) { + return n; + } + + /* Anything else is just bad. */ + if (rv != APR_SUCCESS) { + return -1; + } + + return (int)len; +} + +/* parse_uri: break apart the uri + * Side Effects: + * - sets r->args to rest after '?' (or NULL if no '?') + * - sets r->uri to request uri (without r->args part) + * - sets r->hostname (if not set already) from request (scheme://host:port) + */ +AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri) +{ + int status = HTTP_OK; + + r->unparsed_uri = apr_pstrdup(r->pool, uri); + + /* http://issues.apache.org/bugzilla/show_bug.cgi?id=31875 + * http://issues.apache.org/bugzilla/show_bug.cgi?id=28450 + * + * This is not in fact a URI, it's a path. That matters in the + * case of a leading double-slash. We need to resolve the issue + * by normalising that out before treating it as a URI. + */ + while ((uri[0] == '/') && (uri[1] == '/')) { + ++uri ; + } + if (r->method_number == M_CONNECT) { + status = apr_uri_parse_hostinfo(r->pool, uri, &r->parsed_uri); + } + else { + /* Simple syntax Errors in URLs are trapped by + * parse_uri_components(). + */ + status = apr_uri_parse(r->pool, uri, &r->parsed_uri); + } + + if (status == APR_SUCCESS) { + /* if it has a scheme we may need to do absoluteURI vhost stuff */ + if (r->parsed_uri.scheme + && !strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r))) { + r->hostname = r->parsed_uri.hostname; + } + else if (r->method_number == M_CONNECT) { + r->hostname = r->parsed_uri.hostname; + } + + r->args = r->parsed_uri.query; + r->uri = r->parsed_uri.path ? r->parsed_uri.path + : apr_pstrdup(r->pool, "/"); + +#if defined(OS2) || defined(WIN32) + /* Handle path translations for OS/2 and plug security hole. + * This will prevent "http://www.wherever.com/..\..\/" from + * returning a directory for the root drive. + */ + { + char *x; + + for (x = r->uri; (x = strchr(x, '\\')) != NULL; ) + *x = '/'; + } +#endif /* OS2 || WIN32 */ + } + else { + r->args = NULL; + r->hostname = NULL; + r->status = HTTP_BAD_REQUEST; /* set error status */ + r->uri = apr_pstrdup(r->pool, uri); + } +} + +static int read_request_line(request_rec *r, apr_bucket_brigade *bb) +{ + const char *ll; + const char *uri; + const char *pro; + +#if 0 + conn_rec *conn = r->connection; +#endif + int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */ + char http[5]; + apr_size_t len; + int num_blank_lines = 0; + int max_blank_lines = r->server->limit_req_fields; + + if (max_blank_lines <= 0) { + max_blank_lines = DEFAULT_LIMIT_REQUEST_FIELDS; + } + + /* Read past empty lines until we get a real request line, + * a read error, the connection closes (EOF), or we timeout. + * + * We skip empty lines because browsers have to tack a CRLF on to the end + * of POSTs to support old CERN webservers. But note that we may not + * have flushed any previous response completely to the client yet. + * We delay the flush as long as possible so that we can improve + * performance for clients that are pipelining requests. If a request + * is pipelined then we won't block during the (implicit) read() below. + * If the requests aren't pipelined, then the client is still waiting + * for the final buffer flush from us, and we will block in the implicit + * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will + * have to block during a read. + */ + + do { + apr_status_t rv; + + /* insure ap_rgetline allocates memory each time thru the loop + * if there are empty lines + */ + r->the_request = NULL; + rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2), + &len, r, 0, bb); + + if (rv != APR_SUCCESS) { + r->request_time = apr_time_now(); + + /* ap_rgetline returns APR_ENOSPC if it fills up the + * buffer before finding the end-of-line. This is only going to + * happen if it exceeds the configured limit for a request-line. + */ + if (rv == APR_ENOSPC) { + r->status = HTTP_REQUEST_URI_TOO_LARGE; + r->proto_num = HTTP_VERSION(1,0); + r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); + } + return 0; + } + } while ((len <= 0) && (++num_blank_lines < max_blank_lines)); + + /* we've probably got something to do, ignore graceful restart requests */ + + r->request_time = apr_time_now(); + ll = r->the_request; + r->method = ap_getword_white(r->pool, &ll); + +#if 0 +/* XXX If we want to keep track of the Method, the protocol module should do + * it. That support isn't in the scoreboard yet. Hopefully next week + * sometime. rbb */ + ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", + r->method); +#endif + + uri = ap_getword_white(r->pool, &ll); + + /* Provide quick information about the request method as soon as known */ + + r->method_number = ap_method_number_of(r->method); + if (r->method_number == M_GET && r->method[0] == 'H') { + r->header_only = 1; + } + + ap_parse_uri(r, uri); + + if (ll[0]) { + r->assbackwards = 0; + pro = ll; + len = strlen(ll); + } else { + r->assbackwards = 1; + pro = "HTTP/0.9"; + len = 8; + } + r->protocol = apr_pstrmemdup(r->pool, pro, len); + + /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */ + + /* Avoid sscanf in the common case */ + if (len == 8 + && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' + && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' + && apr_isdigit(pro[7])) { + r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0'); + } + else if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor) + && (strcasecmp("http", http) == 0) + && (minor < HTTP_VERSION(1, 0)) ) /* don't allow HTTP/0.1000 */ + r->proto_num = HTTP_VERSION(major, minor); + else + r->proto_num = HTTP_VERSION(1, 0); + + return 1; +} + +AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb) +{ + char *last_field = NULL; + apr_size_t last_len = 0; + apr_size_t alloc_len = 0; + char *field; + char *value; + apr_size_t len; + int fields_read = 0; + char *tmp_field; + + /* + * Read header lines until we get the empty separator line, a read error, + * the connection closes (EOF), reach the server limit, or we timeout. + */ + while(1) { + apr_status_t rv; + int folded = 0; + + field = NULL; + rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2, + &len, r, 0, bb); + + if (rv != APR_SUCCESS) { + r->status = HTTP_BAD_REQUEST; + + /* ap_rgetline returns APR_ENOSPC if it fills up the buffer before + * finding the end-of-line. This is only going to happen if it + * exceeds the configured limit for a field size. + */ + if (rv == APR_ENOSPC && field) { + /* insure ap_escape_html will terminate correctly */ + field[len - 1] = '\0'; + apr_table_setn(r->notes, "error-notes", + apr_pstrcat(r->pool, + "Size of a request header field " + "exceeds server limit.
    \n" + "
    \n",
    +                                           ap_escape_html(r->pool, field),
    +                                           "
    \n", NULL)); + } + return; + } + + if (last_field != NULL) { + if ((len > 0) && ((*field == '\t') || *field == ' ')) { + /* This line is a continuation of the preceding line(s), + * so append it to the line that we've set aside. + * Note: this uses a power-of-two allocator to avoid + * doing O(n) allocs and using O(n^2) space for + * continuations that span many many lines. + */ + apr_size_t fold_len = last_len + len + 1; /* trailing null */ + + if (fold_len >= (apr_size_t)(r->server->limit_req_fieldsize)) { + r->status = HTTP_BAD_REQUEST; + /* report what we have accumulated so far before the + * overflow (last_field) as the field with the problem + */ + apr_table_setn(r->notes, "error-notes", + apr_pstrcat(r->pool, + "Size of a request header field " + "after folding " + "exceeds server limit.
    \n" + "
    \n",
    +                                               ap_escape_html(r->pool, last_field),
    +                                               "
    \n", NULL)); + return; + } + + if (fold_len > alloc_len) { + char *fold_buf; + alloc_len += alloc_len; + if (fold_len > alloc_len) { + alloc_len = fold_len; + } + fold_buf = (char *)apr_palloc(r->pool, alloc_len); + memcpy(fold_buf, last_field, last_len); + last_field = fold_buf; + } + memcpy(last_field + last_len, field, len +1); /* +1 for nul */ + last_len += len; + folded = 1; + } + else /* not a continuation line */ { + + if (r->server->limit_req_fields + && (++fields_read > r->server->limit_req_fields)) { + r->status = HTTP_BAD_REQUEST; + apr_table_setn(r->notes, "error-notes", + "The number of request header fields " + "exceeds this server's limit."); + return; + } + + if (!(value = strchr(last_field, ':'))) { /* Find ':' or */ + r->status = HTTP_BAD_REQUEST; /* abort bad request */ + apr_table_setn(r->notes, "error-notes", + apr_pstrcat(r->pool, + "Request header field is " + "missing ':' separator.
    \n" + "
    \n",
    +                                               ap_escape_html(r->pool,
    +                                                              last_field),
    +                                               "
    \n", NULL)); + return; + } + + tmp_field = value - 1; /* last character of field-name */ + + *value++ = '\0'; /* NUL-terminate at colon */ + + while (*value == ' ' || *value == '\t') { + ++value; /* Skip to start of value */ + } + + /* Strip LWS after field-name: */ + while (tmp_field > last_field + && (*tmp_field == ' ' || *tmp_field == '\t')) { + *tmp_field-- = '\0'; + } + + /* Strip LWS after field-value: */ + tmp_field = last_field + last_len - 1; + while (tmp_field > value + && (*tmp_field == ' ' || *tmp_field == '\t')) { + *tmp_field-- = '\0'; + } + + apr_table_addn(r->headers_in, last_field, value); + + /* reset the alloc_len so that we'll allocate a new + * buffer if we have to do any more folding: we can't + * use the previous buffer because its contents are + * now part of r->headers_in + */ + alloc_len = 0; + + } /* end if current line is not a continuation starting with tab */ + } + + /* Found a blank line, stop. */ + if (len == 0) { + break; + } + + /* Keep track of this line so that we can parse it on + * the next loop iteration. (In the folded case, last_field + * has been updated already.) + */ + if (!folded) { + last_field = field; + last_len = len; + } + } + + apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE); +} + +AP_DECLARE(void) ap_get_mime_headers(request_rec *r) +{ + apr_bucket_brigade *tmp_bb; + tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + ap_get_mime_headers_core(r, tmp_bb); + apr_brigade_destroy(tmp_bb); +} + +request_rec *ap_read_request(conn_rec *conn) +{ + request_rec *r; + apr_pool_t *p; + const char *expect; + int access_status; + apr_bucket_brigade *tmp_bb; + + apr_pool_create(&p, conn->pool); + apr_pool_tag(p, "request"); + r = apr_pcalloc(p, sizeof(request_rec)); + r->pool = p; + r->connection = conn; + r->server = conn->base_server; + + r->user = NULL; + r->ap_auth_type = NULL; + + r->allowed_methods = ap_make_method_list(p, 2); + + r->headers_in = apr_table_make(r->pool, 25); + r->subprocess_env = apr_table_make(r->pool, 25); + r->headers_out = apr_table_make(r->pool, 12); + r->err_headers_out = apr_table_make(r->pool, 5); + r->notes = apr_table_make(r->pool, 5); + + r->request_config = ap_create_request_config(r->pool); + /* Must be set before we run create request hook */ + + r->proto_output_filters = conn->output_filters; + r->output_filters = r->proto_output_filters; + r->proto_input_filters = conn->input_filters; + r->input_filters = r->proto_input_filters; + ap_run_create_request(r); + r->per_dir_config = r->server->lookup_defaults; + + r->sent_bodyct = 0; /* bytect isn't for body */ + + r->read_length = 0; + r->read_body = REQUEST_NO_BODY; + + r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */ + r->the_request = NULL; + + tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + + /* Get the request... */ + if (!read_request_line(r, tmp_bb)) { + if (r->status == HTTP_REQUEST_URI_TOO_LARGE) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "request failed: URI too long (longer than %d)", r->server->limit_req_line); + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + apr_brigade_destroy(tmp_bb); + return r; + } + + apr_brigade_destroy(tmp_bb); + return NULL; + } + + if (!r->assbackwards) { + ap_get_mime_headers_core(r, tmp_bb); + if (r->status != HTTP_REQUEST_TIME_OUT) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "request failed: error reading the headers"); + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + apr_brigade_destroy(tmp_bb); + return r; + } + } + else { + if (r->header_only) { + /* + * Client asked for headers only with HTTP/0.9, which doesn't send + * headers! Have to dink things just to make sure the error message + * comes through... + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "client sent invalid HTTP/0.9 request: HEAD %s", + r->uri); + r->header_only = 0; + r->status = HTTP_BAD_REQUEST; + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + apr_brigade_destroy(tmp_bb); + return r; + } + } + + apr_brigade_destroy(tmp_bb); + + r->status = HTTP_OK; /* Until further notice. */ + + /* update what we think the virtual host is based on the headers we've + * now read. may update status. + */ + ap_update_vhost_from_headers(r); + + /* we may have switched to another server */ + r->per_dir_config = r->server->lookup_defaults; + + if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1))) + || ((r->proto_num == HTTP_VERSION(1, 1)) + && !apr_table_get(r->headers_in, "Host"))) { + /* + * Client sent us an HTTP/1.1 or later request without telling us the + * hostname, either with a full URL or a Host: header. We therefore + * need to (as per the 1.1 spec) send an error. As a special case, + * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain + * a Host: header, and the server MUST respond with 400 if it doesn't. + */ + r->status = HTTP_BAD_REQUEST; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "client sent HTTP/1.1 request without hostname " + "(see RFC2616 section 14.23): %s", r->uri); + } + + if (r->status != HTTP_OK) { + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + return r; + } + + if ((access_status = ap_run_post_read_request(r))) { + ap_die(access_status, r); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + return NULL; + } + + if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) + && (expect[0] != '\0')) { + /* + * The Expect header field was added to HTTP/1.1 after RFC 2068 + * as a means to signal when a 100 response is desired and, + * unfortunately, to signal a poor man's mandatory extension that + * the server must understand or return 417 Expectation Failed. + */ + if (strcasecmp(expect, "100-continue") == 0) { + r->expecting_100 = 1; + } + else { + r->status = HTTP_EXPECTATION_FAILED; + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "client sent an unrecognized expectation value of " + "Expect: %s", expect); + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + return r; + } + } + + ap_add_input_filter_handle(ap_http_input_filter_handle, + NULL, r, r->connection); + + return r; +} + +/* if a request with a body creates a subrequest, clone the original request's + * input headers minus any headers pertaining to the body which has already + * been read. out-of-line helper function for ap_set_sub_req_protocol. + */ + +static void clone_headers_no_body(request_rec *rnew, + const request_rec *r) +{ + rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); + apr_table_unset(rnew->headers_in, "Content-Encoding"); + apr_table_unset(rnew->headers_in, "Content-Language"); + apr_table_unset(rnew->headers_in, "Content-Length"); + apr_table_unset(rnew->headers_in, "Content-Location"); + apr_table_unset(rnew->headers_in, "Content-MD5"); + apr_table_unset(rnew->headers_in, "Content-Range"); + apr_table_unset(rnew->headers_in, "Content-Type"); + apr_table_unset(rnew->headers_in, "Expires"); + apr_table_unset(rnew->headers_in, "Last-Modified"); + apr_table_unset(rnew->headers_in, "Transfer-Encoding"); +} + +/* + * A couple of other functions which initialize some of the fields of + * a request structure, as appropriate for adjuncts of one kind or another + * to a request in progress. Best here, rather than elsewhere, since + * *someone* has to set the protocol-specific fields... + */ + +AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, + const request_rec *r) +{ + rnew->the_request = r->the_request; /* Keep original request-line */ + + rnew->assbackwards = 1; /* Don't send headers from this. */ + rnew->no_local_copy = 1; /* Don't try to send HTTP_NOT_MODIFIED for a + * fragment. */ + rnew->method = "GET"; + rnew->method_number = M_GET; + rnew->protocol = "INCLUDED"; + + rnew->status = HTTP_OK; + + /* did the original request have a body? (e.g. POST w/SSI tags) + * if so, make sure the subrequest doesn't inherit body headers + */ + if (apr_table_get(r->headers_in, "Content-Length") + || apr_table_get(r->headers_in, "Transfer-Encoding")) { + clone_headers_no_body(rnew, r); + } else { + /* no body (common case). clone headers the cheap way */ + rnew->headers_in = r->headers_in; + } + rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); + rnew->headers_out = apr_table_make(rnew->pool, 5); + rnew->err_headers_out = apr_table_make(rnew->pool, 5); + rnew->notes = apr_table_make(rnew->pool, 5); + + rnew->expecting_100 = r->expecting_100; + rnew->read_length = r->read_length; + rnew->read_body = REQUEST_NO_BODY; + + rnew->main = (request_rec *) r; +} + +static void end_output_stream(request_rec *r) +{ + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *b; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(r->output_filters, bb); +} + +AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub) +{ + /* tell the filter chain there is no more content coming */ + if (!sub->eos_sent) { + end_output_stream(sub); + } +} + +/* finalize_request_protocol is called at completion of sending the + * response. Its sole purpose is to send the terminating protocol + * information for any wrappers around the response message body + * (i.e., transfer encodings). It should have been named finalize_response. + */ +AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) +{ + (void) ap_discard_request_body(r); + + /* tell the filter chain there is no more content coming */ + if (!r->eos_sent) { + end_output_stream(r); + } +} + +/* + * Support for the Basic authentication protocol, and a bit for Digest. + */ +AP_DECLARE(void) ap_note_auth_failure(request_rec *r) +{ + const char *type = ap_auth_type(r); + if (type) { + if (!strcasecmp(type, "Basic")) + ap_note_basic_auth_failure(r); + else if (!strcasecmp(type, "Digest")) + ap_note_digest_auth_failure(r); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, + 0, r, "need AuthType to note auth failure: %s", r->uri); + } +} + +AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r) +{ + const char *type = ap_auth_type(r); + + /* if there is no AuthType configure or it is something other than + * Basic, let ap_note_auth_failure() deal with it + */ + if (!type || strcasecmp(type, "Basic")) + ap_note_auth_failure(r); + else + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); +} + +AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r) +{ + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"" + "%" APR_UINT64_T_HEX_FMT "\"", + ap_auth_name(r), (apr_uint64_t)r->request_time)); +} + +AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) +{ + const char *auth_line = apr_table_get(r->headers_in, + (PROXYREQ_PROXY == r->proxyreq) + ? "Proxy-Authorization" + : "Authorization"); + const char *t; + + if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic")) + return DECLINED; + + if (!ap_auth_name(r)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, + 0, r, "need AuthName: %s", r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (!auth_line) { + ap_note_basic_auth_failure(r); + return HTTP_UNAUTHORIZED; + } + + if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) { + /* Client tried to authenticate using wrong auth scheme */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "client used wrong authentication scheme: %s", r->uri); + ap_note_basic_auth_failure(r); + return HTTP_UNAUTHORIZED; + } + + while (*auth_line == ' ' || *auth_line == '\t') { + auth_line++; + } + + t = ap_pbase64decode(r->pool, auth_line); + r->user = ap_getword_nulls (r->pool, &t, ':'); + r->ap_auth_type = "Basic"; + + *pw = t; + + return OK; +} + +struct content_length_ctx { + int data_sent; /* true if the C-L filter has already sent at + * least one bucket on to the next output filter + * for this request + */ +}; + +/* This filter computes the content length, but it also computes the number + * of bytes sent to the client. This means that this filter will always run + * through all of the buckets in all brigades + */ +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter( + ap_filter_t *f, + apr_bucket_brigade *b) +{ + request_rec *r = f->r; + struct content_length_ctx *ctx; + apr_bucket *e; + int eos = 0; + apr_read_type_e eblock = APR_NONBLOCK_READ; + + ctx = f->ctx; + if (!ctx) { + f->ctx = ctx = apr_palloc(r->pool, sizeof(*ctx)); + ctx->data_sent = 0; + } + + /* Loop through this set of buckets to compute their length + */ + e = APR_BRIGADE_FIRST(b); + while (e != APR_BRIGADE_SENTINEL(b)) { + if (APR_BUCKET_IS_EOS(e)) { + eos = 1; + break; + } + if (e->length == (apr_size_t)-1) { + apr_size_t len; + const char *ignored; + apr_status_t rv; + + /* This is probably a pipe bucket. Send everything + * prior to this, and then read the data for this bucket. + */ + rv = apr_bucket_read(e, &ignored, &len, eblock); + if (rv == APR_SUCCESS) { + /* Attempt a nonblocking read next time through */ + eblock = APR_NONBLOCK_READ; + r->bytes_sent += len; + } + else if (APR_STATUS_IS_EAGAIN(rv)) { + /* Output everything prior to this bucket, and then + * do a blocking read on the next batch. + */ + if (e != APR_BRIGADE_FIRST(b)) { + apr_bucket_brigade *split = apr_brigade_split(b, e); + apr_bucket *flush = apr_bucket_flush_create(r->connection->bucket_alloc); + + APR_BRIGADE_INSERT_TAIL(b, flush); + rv = ap_pass_brigade(f->next, b); + if (rv != APR_SUCCESS || f->c->aborted) { + apr_brigade_destroy(split); + return rv; + } + b = split; + e = APR_BRIGADE_FIRST(b); + + ctx->data_sent = 1; + } + eblock = APR_BLOCK_READ; + continue; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "ap_content_length_filter: " + "apr_bucket_read() failed"); + return rv; + } + } + else { + r->bytes_sent += e->length; + } + e = APR_BUCKET_NEXT(e); + } + + /* If we've now seen the entire response and it's otherwise + * okay to set the C-L in the response header, then do so now. + * + * We can only set a C-L in the response header if we haven't already + * sent any buckets on to the next output filter for this request. + */ + if (ctx->data_sent == 0 && eos) { + ap_set_content_length(r, r->bytes_sent); + } + + ctx->data_sent = 1; + return ap_pass_brigade(f->next, b); +} + +/* + * Send the body of a response to the client. + */ +AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, + apr_off_t offset, apr_size_t len, + apr_size_t *nbytes) +{ + conn_rec *c = r->connection; + apr_bucket_brigade *bb = NULL; + apr_bucket *b; + apr_status_t rv; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_file_create(fd, offset, len, r->pool, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + rv = ap_pass_brigade(r->output_filters, bb); + if (rv != APR_SUCCESS) { + *nbytes = 0; /* no way to tell how many were actually sent */ + } + else { + *nbytes = len; + } + + return rv; +} + +#if APR_HAS_MMAP +/* send data from an in-memory buffer */ +AP_DECLARE(size_t) ap_send_mmap(apr_mmap_t *mm, request_rec *r, size_t offset, + size_t length) +{ + conn_rec *c = r->connection; + apr_bucket_brigade *bb = NULL; + apr_bucket *b; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_mmap_create(mm, offset, length, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + ap_pass_brigade(r->output_filters, bb); + + return mm->size; /* XXX - change API to report apr_status_t? */ +} +#endif /* APR_HAS_MMAP */ + +typedef struct { + apr_bucket_brigade *bb; +} old_write_filter_ctx; + +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_old_write_filter( + ap_filter_t *f, apr_bucket_brigade *bb) +{ + old_write_filter_ctx *ctx = f->ctx; + + AP_DEBUG_ASSERT(ctx); + + if (ctx->bb != 0) { + /* whatever is coming down the pipe (we don't care), we + * can simply insert our buffered data at the front and + * pass the whole bundle down the chain. + */ + APR_BRIGADE_CONCAT(ctx->bb, bb); + bb = ctx->bb; + ctx->bb = NULL; + } + + return ap_pass_brigade(f->next, bb); +} + +static apr_status_t buffer_output(request_rec *r, + const char *str, apr_size_t len) +{ + conn_rec *c = r->connection; + ap_filter_t *f; + old_write_filter_ctx *ctx; + + if (len == 0) + return APR_SUCCESS; + + /* future optimization: record some flags in the request_rec to + * say whether we've added our filter, and whether it is first. + */ + + /* this will typically exit on the first test */ + for (f = r->output_filters; f != NULL; f = f->next) { + if (ap_old_write_func == f->frec) + break; + } + + if (f == NULL) { + /* our filter hasn't been added yet */ + ctx = apr_pcalloc(r->pool, sizeof(*ctx)); + ap_add_output_filter("OLD_WRITE", ctx, r, r->connection); + f = r->output_filters; + } + + /* if the first filter is not our buffering filter, then we have to + * deliver the content through the normal filter chain + */ + if (f != r->output_filters) { + apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); + apr_bucket *b = apr_bucket_transient_create(str, len, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + + return ap_pass_brigade(r->output_filters, bb); + } + + /* grab the context from our filter */ + ctx = r->output_filters->ctx; + + if (ctx->bb == NULL) { + ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc); + } + + return ap_fwrite(f->next, ctx->bb, str, len); +} + +AP_DECLARE(int) ap_rputc(int c, request_rec *r) +{ + char c2 = (char)c; + + if (r->connection->aborted) { + return -1; + } + + if (buffer_output(r, &c2, 1) != APR_SUCCESS) + return -1; + + return c; +} + +AP_DECLARE(int) ap_rputs(const char *str, request_rec *r) +{ + apr_size_t len; + + if (r->connection->aborted) + return -1; + + if (buffer_output(r, str, len = strlen(str)) != APR_SUCCESS) + return -1; + + return len; +} + +AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) +{ + if (r->connection->aborted) + return -1; + + if (buffer_output(r, buf, nbyte) != APR_SUCCESS) + return -1; + + return nbyte; +} + +struct ap_vrprintf_data { + apr_vformatter_buff_t vbuff; + request_rec *r; + char *buff; +}; + +static apr_status_t r_flush(apr_vformatter_buff_t *buff) +{ + /* callback function passed to ap_vformatter to be called when + * vformatter needs to write into buff and buff.curpos > buff.endpos */ + + /* ap_vrprintf_data passed as a apr_vformatter_buff_t, which is then + * "downcast" to an ap_vrprintf_data */ + struct ap_vrprintf_data *vd = (struct ap_vrprintf_data*)buff; + + if (vd->r->connection->aborted) + return -1; + + /* r_flush is called when vbuff is completely full */ + if (buffer_output(vd->r, vd->buff, AP_IOBUFSIZE)) { + return -1; + } + + /* reset the buffer position */ + vd->vbuff.curpos = vd->buff; + vd->vbuff.endpos = vd->buff + AP_IOBUFSIZE; + + return APR_SUCCESS; +} + +AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va) +{ + apr_size_t written; + struct ap_vrprintf_data vd; + char vrprintf_buf[AP_IOBUFSIZE]; + + vd.vbuff.curpos = vrprintf_buf; + vd.vbuff.endpos = vrprintf_buf + AP_IOBUFSIZE; + vd.r = r; + vd.buff = vrprintf_buf; + + if (r->connection->aborted) + return -1; + + written = apr_vformatter(r_flush, &vd.vbuff, fmt, va); + + /* tack on null terminator on remaining string */ + *(vd.vbuff.curpos) = '\0'; + + if (written != -1) { + int n = vd.vbuff.curpos - vrprintf_buf; + + /* last call to buffer_output, to finish clearing the buffer */ + if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS) + return -1; + + written += n; + } + + return written; +} + +AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt, ...) +{ + va_list va; + int n; + + if (r->connection->aborted) + return -1; + + va_start(va, fmt); + n = ap_vrprintf(r, fmt, va); + va_end(va); + + return n; +} + +AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r, ...) +{ + va_list va; + const char *s; + apr_size_t len; + apr_size_t written = 0; + + if (r->connection->aborted) + return -1; + + /* ### TODO: if the total output is large, put all the strings + * ### into a single brigade, rather than flushing each time we + * ### fill the buffer + */ + va_start(va, r); + while (1) { + s = va_arg(va, const char *); + if (s == NULL) + break; + + len = strlen(s); + if (buffer_output(r, s, len) != APR_SUCCESS) { + return -1; + } + + written += len; + } + va_end(va); + + return written; +} + +AP_DECLARE(int) ap_rflush(request_rec *r) +{ + conn_rec *c = r->connection; + apr_bucket_brigade *bb; + apr_bucket *b; + + bb = apr_brigade_create(r->pool, c->bucket_alloc); + b = apr_bucket_flush_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) + return -1; + + return 0; +} + +/* + * This function sets the Last-Modified output header field to the value + * of the mtime field in the request structure - rationalized to keep it from + * being in the future. + */ +AP_DECLARE(void) ap_set_last_modified(request_rec *r) +{ + if (!r->assbackwards) { + apr_time_t mod_time = ap_rationalize_mtime(r, r->mtime); + char *datestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN); + + apr_rfc822_date(datestr, mod_time); + apr_table_setn(r->headers_out, "Last-Modified", datestr); + } +} + +AP_IMPLEMENT_HOOK_RUN_ALL(int,post_read_request, + (request_rec *r), (r), OK, DECLINED) +AP_IMPLEMENT_HOOK_RUN_ALL(int,log_transaction, + (request_rec *r), (r), OK, DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,http_scheme, + (const request_rec *r), (r), NULL) +AP_IMPLEMENT_HOOK_RUN_FIRST(unsigned short,default_port, + (const request_rec *r), (r), 0) diff --git a/trunk/server/provider.c b/trunk/server/provider.c new file mode 100644 index 0000000000..97d2a0f9f4 --- /dev/null +++ b/trunk/server/provider.c @@ -0,0 +1,98 @@ +/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_pools.h" +#include "apr_hash.h" + +#include "ap_provider.h" + +static apr_hash_t *global_providers = NULL; + +static apr_status_t cleanup_global_providers(void *ctx) +{ + global_providers = NULL; + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool, + const char *provider_group, + const char *provider_name, + const char *provider_version, + const void *provider) +{ + apr_hash_t *provider_group_hash; + apr_hash_t *provider_version_hash; + + if (global_providers == NULL) { + global_providers = apr_hash_make(pool); + apr_pool_cleanup_register(pool, NULL, cleanup_global_providers, + apr_pool_cleanup_null); + } + + provider_group_hash = apr_hash_get(global_providers, provider_group, + APR_HASH_KEY_STRING); + + if (!provider_group_hash) { + provider_group_hash = apr_hash_make(pool); + apr_hash_set(global_providers, provider_group, APR_HASH_KEY_STRING, + provider_group_hash); + + } + + provider_version_hash = apr_hash_get(provider_group_hash, provider_name, + APR_HASH_KEY_STRING); + + if (!provider_version_hash) { + provider_version_hash = apr_hash_make(pool); + apr_hash_set(provider_group_hash, provider_name, APR_HASH_KEY_STRING, + provider_version_hash); + + } + + /* just set it. no biggy if it was there before. */ + apr_hash_set(provider_version_hash, provider_version, APR_HASH_KEY_STRING, + provider); + + return APR_SUCCESS; +} + +AP_DECLARE(void *) ap_lookup_provider(const char *provider_group, + const char *provider_name, + const char *provider_version) +{ + apr_hash_t *provider_group_hash, *provider_name_hash; + + if (global_providers == NULL) { + return NULL; + } + + provider_group_hash = apr_hash_get(global_providers, provider_group, + APR_HASH_KEY_STRING); + + if (provider_group_hash == NULL) { + return NULL; + } + + provider_name_hash = apr_hash_get(provider_group_hash, provider_name, + APR_HASH_KEY_STRING); + + if (provider_name_hash == NULL) { + return NULL; + } + + return apr_hash_get(provider_name_hash, provider_version, + APR_HASH_KEY_STRING); +} diff --git a/trunk/server/request.c b/trunk/server/request.c new file mode 100644 index 0000000000..1a1b5f118f --- /dev/null +++ b/trunk/server/request.c @@ -0,0 +1,1898 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_request.c: functions to get and process requests + * + * Rob McCool 3/21/93 + * + * Thoroughly revamped by rst for Apache. NB this file reads + * best from the bottom up. + * + */ + +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_fnmatch.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_request.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "util_filter.h" +#include "util_charset.h" +#include "util_script.h" + +#include "mod_core.h" + +#if APR_HAVE_STDARG_H +#include +#endif + +APR_HOOK_STRUCT( + APR_HOOK_LINK(translate_name) + APR_HOOK_LINK(map_to_storage) + APR_HOOK_LINK(check_user_id) + APR_HOOK_LINK(fixups) + APR_HOOK_LINK(type_checker) + APR_HOOK_LINK(access_checker) + APR_HOOK_LINK(auth_checker) + APR_HOOK_LINK(insert_filter) + APR_HOOK_LINK(create_request) +) + +AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, + (request_rec *r), (r), DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,map_to_storage, + (request_rec *r), (r), DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id, + (request_rec *r), (r), DECLINED) +AP_IMPLEMENT_HOOK_RUN_ALL(int,fixups, + (request_rec *r), (r), OK, DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,type_checker, + (request_rec *r), (r), DECLINED) +AP_IMPLEMENT_HOOK_RUN_ALL(int,access_checker, + (request_rec *r), (r), OK, DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_checker, + (request_rec *r), (r), DECLINED) +AP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r)) +AP_IMPLEMENT_HOOK_RUN_ALL(int, create_request, + (request_rec *r), (r), OK, DECLINED) + + +static int decl_die(int status, char *phase, request_rec *r) +{ + if (status == DECLINED) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, + "configuration error: couldn't %s: %s", phase, r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + else { + return status; + } +} + +/* This is the master logic for processing requests. Do NOT duplicate + * this logic elsewhere, or the security model will be broken by future + * API changes. Each phase must be individually optimized to pick up + * redundant/duplicate calls by subrequests, and redirects. + */ +AP_DECLARE(int) ap_process_request_internal(request_rec *r) +{ + int file_req = (r->main && r->filename); + int access_status; + + /* Ignore embedded %2F's in path for proxy requests */ + if (!r->proxyreq && r->parsed_uri.path) { + core_dir_config *d; + d = ap_get_module_config(r->per_dir_config, &core_module); + if (d->allow_encoded_slashes) { + access_status = ap_unescape_url_keep2f(r->parsed_uri.path); + } + else { + access_status = ap_unescape_url(r->parsed_uri.path); + } + if (access_status) { + if (access_status == HTTP_NOT_FOUND) { + if (! d->allow_encoded_slashes) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "found %%2f (encoded '/') in URI " + "(decoded='%s'), returning 404", + r->parsed_uri.path); + } + } + return access_status; + } + } + + ap_getparents(r->uri); /* OK --- shrinking transformations... */ + + /* All file subrequests are a huge pain... they cannot bubble through the + * next several steps. Only file subrequests are allowed an empty uri, + * otherwise let translate_name kill the request. + */ + if (!file_req) { + if ((access_status = ap_location_walk(r))) { + return access_status; + } + + if ((access_status = ap_run_translate_name(r))) { + return decl_die(access_status, "translate", r); + } + } + + /* Reset to the server default config prior to running map_to_storage + */ + r->per_dir_config = r->server->lookup_defaults; + + if ((access_status = ap_run_map_to_storage(r))) { + /* This request wasn't in storage (e.g. TRACE) */ + return access_status; + } + + /* Excluding file-specific requests with no 'true' URI... + */ + if (!file_req) { + /* Rerun the location walk, which overrides any map_to_storage config. + */ + if ((access_status = ap_location_walk(r))) { + return access_status; + } + } + + /* Only on the main request! */ + if (r->main == NULL) { + if ((access_status = ap_run_header_parser(r))) { + return access_status; + } + } + + /* Skip authn/authz if the parent or prior request passed the authn/authz, + * and that configuration didn't change (this requires optimized _walk() + * functions in map_to_storage that use the same merge results given + * identical input.) If the config changes, we must re-auth. + */ + if (r->main && (r->main->per_dir_config == r->per_dir_config)) { + r->user = r->main->user; + r->ap_auth_type = r->main->ap_auth_type; + } + else if (r->prev && (r->prev->per_dir_config == r->per_dir_config)) { + r->user = r->prev->user; + r->ap_auth_type = r->prev->ap_auth_type; + } + else { + switch (ap_satisfies(r)) { + case SATISFY_ALL: + case SATISFY_NOSPEC: + if ((access_status = ap_run_access_checker(r)) != 0) { + return decl_die(access_status, "check access", r); + } + + if (ap_some_auth_required(r)) { + if (((access_status = ap_run_check_user_id(r)) != 0) + || !ap_auth_type(r)) { + return decl_die(access_status, ap_auth_type(r) + ? "check user. No user file?" + : "perform authentication. AuthType not set!", + r); + } + + if (((access_status = ap_run_auth_checker(r)) != 0) + || !ap_auth_type(r)) { + return decl_die(access_status, ap_auth_type(r) + ? "check access. No groups file?" + : "perform authentication. AuthType not set!", + r); + } + } + break; + + case SATISFY_ANY: + if (((access_status = ap_run_access_checker(r)) != 0)) { + if (!ap_some_auth_required(r)) { + return decl_die(access_status, "check access", r); + } + + if (((access_status = ap_run_check_user_id(r)) != 0) + || !ap_auth_type(r)) { + return decl_die(access_status, ap_auth_type(r) + ? "check user. No user file?" + : "perform authentication. AuthType not set!", + r); + } + + if (((access_status = ap_run_auth_checker(r)) != 0) + || !ap_auth_type(r)) { + return decl_die(access_status, ap_auth_type(r) + ? "check access. No groups file?" + : "perform authentication. AuthType not set!", + r); + } + } + break; + } + } + /* XXX Must make certain the ap_run_type_checker short circuits mime + * in mod-proxy for r->proxyreq && r->parsed_uri.scheme + * && !strcmp(r->parsed_uri.scheme, "http") + */ + if ((access_status = ap_run_type_checker(r)) != 0) { + return decl_die(access_status, "find types", r); + } + + if ((access_status = ap_run_fixups(r)) != 0) { + return access_status; + } + + return OK; +} + + +/* Useful caching structures to repeat _walk/merge sequences as required + * when a subrequest or redirect reuses substantially the same config. + * + * Directive order in the httpd.conf file and its Includes significantly + * impact this optimization. Grouping common blocks at the front of the + * config that are less likely to change between a request and + * its subrequests, or between a request and its redirects reduced + * the work of these functions significantly. + */ + +typedef struct walk_walked_t { + ap_conf_vector_t *matched; /* A dir_conf sections we matched */ + ap_conf_vector_t *merged; /* The dir_conf merged result */ +} walk_walked_t; + +typedef struct walk_cache_t { + const char *cached; /* The identifier we matched */ + ap_conf_vector_t **dir_conf_tested; /* The sections we matched against */ + ap_conf_vector_t *dir_conf_merged; /* Base per_dir_config */ + ap_conf_vector_t *per_dir_result; /* per_dir_config += walked result */ + apr_array_header_t *walked; /* The list of walk_walked_t results */ +} walk_cache_t; + +static walk_cache_t *prep_walk_cache(apr_size_t t, request_rec *r) +{ + walk_cache_t *cache; + void **note; + + /* Find the most relevant, recent entry to work from. That would be + * this request (on the second call), or the parent request of a + * subrequest, or the prior request of an internal redirect. Provide + * this _walk()er with a copy it is allowed to munge. If there is no + * parent or prior cached request, then create a new walk cache. + */ + note = ap_get_request_note(r, t); + if (!note) { + return NULL; + } + + if (!(cache = *note)) { + void **inherit_note; + + if ((r->main + && ((inherit_note = ap_get_request_note(r->main, t))) + && *inherit_note) + || (r->prev + && ((inherit_note = ap_get_request_note(r->prev, t))) + && *inherit_note)) { + cache = apr_pmemdup(r->pool, *inherit_note, + sizeof(*cache)); + cache->walked = apr_array_copy(r->pool, cache->walked); + } + else { + cache = apr_pcalloc(r->pool, sizeof(*cache)); + cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t)); + } + + *note = cache; + } + return cache; +} + +/***************************************************************** + * + * Getting and checking directory configuration. Also checks the + * FollowSymlinks and FollowSymOwner stuff, since this is really the + * only place that can happen (barring a new mid_dir_walk callout). + * + * We can't do it as an access_checker module function which gets + * called with the final per_dir_config, since we could have a directory + * with FollowSymLinks disabled, which contains a symlink to another + * with a .htaccess file which turns FollowSymLinks back on --- and + * access in such a case must be denied. So, whatever it is that + * checks FollowSymLinks needs to know the state of the options as + * they change, all the way down. + */ + + +/* + * resolve_symlink must _always_ be called on an APR_LNK file type! + * It will resolve the actual target file type, modification date, etc, + * and provide any processing required for symlink evaluation. + * Path must already be cleaned, no trailing slash, no multi-slashes, + * and don't call this on the root! + * + * Simply, the number of times we deref a symlink are minimal compared + * to the number of times we had an extra lstat() since we 'weren't sure'. + * + * To optimize, we stat() anything when given (opts & OPT_SYM_LINKS), otherwise + * we start off with an lstat(). Every lstat() must be dereferenced in case + * it points at a 'nasty' - we must always rerun check_safe_file (or similar.) + */ +static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p) +{ + apr_finfo_t fi; + int res; + const char *savename; + + if (!(opts & (OPT_SYM_OWNER | OPT_SYM_LINKS))) { + return HTTP_FORBIDDEN; + } + + /* Save the name from the valid bits. */ + savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL; + + if (opts & OPT_SYM_LINKS) { + if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME + | APR_FINFO_LINK), p)) + != APR_SUCCESS) { + return HTTP_FORBIDDEN; + } + + /* Give back the target */ + memcpy(lfi, &fi, sizeof(fi)); + if (savename) { + lfi->name = savename; + lfi->valid |= APR_FINFO_NAME; + } + + return OK; + } + + /* OPT_SYM_OWNER only works if we can get the owner of + * both the file and symlink. First fill in a missing + * owner of the symlink, then get the info of the target. + */ + if (!(lfi->valid & APR_FINFO_OWNER)) { + if ((res = apr_stat(&fi, d, + lfi->valid | APR_FINFO_LINK | APR_FINFO_OWNER, p)) + != APR_SUCCESS) { + return HTTP_FORBIDDEN; + } + } + + if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p)) + != APR_SUCCESS) { + return HTTP_FORBIDDEN; + } + + if (apr_uid_compare(fi.user, lfi->user) != APR_SUCCESS) { + return HTTP_FORBIDDEN; + } + + /* Give back the target */ + memcpy(lfi, &fi, sizeof(fi)); + if (savename) { + lfi->name = savename; + lfi->valid |= APR_FINFO_NAME; + } + + return OK; +} + + +/* + * As we walk the directory configuration, the merged config won't + * be 'rooted' to a specific vhost until the very end of the merge. + * + * We need a very fast mini-merge to a real, vhost-rooted merge + * of core.opts and core.override, the only options tested within + * directory_walk itself. + * + * See core.c::merge_core_dir_configs() for explanation. + */ + +typedef struct core_opts_t { + allow_options_t opts; + allow_options_t add; + allow_options_t remove; + overrides_t override; + overrides_t override_opts; +} core_opts_t; + +static void core_opts_merge(const ap_conf_vector_t *sec, core_opts_t *opts) +{ + core_dir_config *this_dir = ap_get_module_config(sec, &core_module); + + if (!this_dir) { + return; + } + + if (this_dir->opts & OPT_UNSET) { + opts->add = (opts->add & ~this_dir->opts_remove) + | this_dir->opts_add; + opts->remove = (opts->remove & ~this_dir->opts_add) + | this_dir->opts_remove; + opts->opts = (opts->opts & ~opts->remove) | opts->add; + } + else { + opts->opts = this_dir->opts; + opts->add = this_dir->opts_add; + opts->remove = this_dir->opts_remove; + } + + if (!(this_dir->override & OR_UNSET)) { + opts->override = this_dir->override; + } + if (!(this_dir->override_opts & OR_UNSET)) { + opts->override_opts = this_dir->override_opts; + } +} + + +/***************************************************************** + * + * Getting and checking directory configuration. Also checks the + * FollowSymlinks and FollowSymOwner stuff, since this is really the + * only place that can happen (barring a new mid_dir_walk callout). + * + * We can't do it as an access_checker module function which gets + * called with the final per_dir_config, since we could have a directory + * with FollowSymLinks disabled, which contains a symlink to another + * with a .htaccess file which turns FollowSymLinks back on --- and + * access in such a case must be denied. So, whatever it is that + * checks FollowSymLinks needs to know the state of the options as + * they change, all the way down. + */ + +AP_DECLARE(int) ap_directory_walk(request_rec *r) +{ + ap_conf_vector_t *now_merged = NULL; + core_server_config *sconf = ap_get_module_config(r->server->module_config, + &core_module); + ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) sconf->sec_dir->elts; + int num_sec = sconf->sec_dir->nelts; + walk_cache_t *cache; + char *entry_dir; + apr_status_t rv; + + /* XXX: Better (faster) tests needed!!! + * + * "OK" as a response to a real problem is not _OK_, but to allow broken + * modules to proceed, we will permit the not-a-path filename to pass the + * following two tests. This behavior may be revoked in future versions + * of Apache. We still must catch it later if it's heading for the core + * handler. Leave INFO notes here for module debugging. + */ + if (r->filename == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "Module bug? Request filename is missing for URI %s", + r->uri); + return OK; + } + + /* Canonicalize the file path without resolving filename case or aliases + * so we can begin by checking the cache for a recent directory walk. + * This call will ensure we have an absolute path in the same pass. + */ + if ((rv = apr_filepath_merge(&entry_dir, NULL, r->filename, + APR_FILEPATH_NOTRELATIVE, r->pool)) + != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "Module bug? Request filename path %s is invalid or " + "or not absolute for uri %s", + r->filename, r->uri); + return OK; + } + + /* XXX Notice that this forces path_info to be canonical. That might + * not be desired by all apps. However, some of those same apps likely + * have significant security holes. + */ + r->filename = entry_dir; + + cache = prep_walk_cache(AP_NOTE_DIRECTORY_WALK, r); + + /* If this is not a dirent subrequest with a preconstructed + * r->finfo value, then we can simply stat the filename to + * save burning mega-cycles with unneeded stats - if this is + * an exact file match. We don't care about failure... we + * will stat by component failing this meager attempt. + * + * It would be nice to distinguish APR_ENOENT from other + * types of failure, such as APR_ENOTDIR. We can do something + * with APR_ENOENT, knowing that the path is good. + */ + if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) { + rv = apr_stat(&r->finfo, r->filename, APR_FINFO_MIN, r->pool); + + /* some OSs will return APR_SUCCESS/APR_REG if we stat + * a regular file but we have '/' at the end of the name; + * + * other OSs will return APR_ENOTDIR for that situation; + * + * handle it the same everywhere by simulating a failure + * if it looks like a directory but really isn't + * + * Also reset if the stat failed, just for safety. + */ + if ((rv != APR_SUCCESS) || + (r->finfo.filetype && + (r->finfo.filetype != APR_DIR) && + (r->filename[strlen(r->filename) - 1] == '/'))) { + r->finfo.filetype = 0; /* forget what we learned */ + } + } + + if (r->finfo.filetype == APR_REG) { + entry_dir = ap_make_dirstr_parent(r->pool, entry_dir); + } + else if (r->filename[strlen(r->filename) - 1] != '/') { + entry_dir = apr_pstrcat(r->pool, r->filename, "/", NULL); + } + + /* If we have a file already matches the path of r->filename, + * and the vhost's list of directory sections hasn't changed, + * we can skip rewalking the directory_walk entries. + */ + if (cache->cached + && ((r->finfo.filetype == APR_REG) + || ((r->finfo.filetype == APR_DIR) + && (!r->path_info || !*r->path_info))) + && (cache->dir_conf_tested == sec_ent) + && (strcmp(entry_dir, cache->cached) == 0)) { + /* Well this looks really familiar! If our end-result (per_dir_result) + * didn't change, we have absolutely nothing to do :) + * Otherwise (as is the case with most dir_merged/file_merged requests) + * we must merge our dir_conf_merged onto this new r->per_dir_config. + */ + if (r->per_dir_config == cache->per_dir_result) { + return OK; + } + + if (r->per_dir_config == cache->dir_conf_merged) { + r->per_dir_config = cache->per_dir_result; + return OK; + } + + if (cache->walked->nelts) { + now_merged = ((walk_walked_t*)cache->walked->elts) + [cache->walked->nelts - 1].merged; + } + } + else { + /* We start now_merged from NULL since we want to build + * a locations list that can be merged to any vhost. + */ + int sec_idx; + int matches = cache->walked->nelts; + walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; + core_dir_config *this_dir; + core_opts_t opts; + apr_finfo_t thisinfo; + char *save_path_info; + apr_size_t buflen; + char *buf; + unsigned int seg, startseg; + + /* Invariant: from the first time filename_len is set until + * it goes out of scope, filename_len==strlen(r->filename) + */ + apr_size_t filename_len; +#ifdef CASE_BLIND_FILESYSTEM + apr_size_t canonical_len; +#endif + + /* + * We must play our own mini-merge game here, for the few + * running dir_config values we care about within dir_walk. + * We didn't start the merge from r->per_dir_config, so we + * accumulate opts and override as we merge, from the globals. + */ + this_dir = ap_get_module_config(r->per_dir_config, &core_module); + opts.opts = this_dir->opts; + opts.add = this_dir->opts_add; + opts.remove = this_dir->opts_remove; + opts.override = this_dir->override; + + /* Set aside path_info to merge back onto path_info later. + * If r->filename is a directory, we must remerge the path_info, + * before we continue! [Directories cannot, by defintion, have + * path info. Either the next segment is not-found, or a file.] + * + * r->path_info tracks the unconsumed source path. + * r->filename tracks the path as we process it + */ + if ((r->finfo.filetype == APR_DIR) && r->path_info && *r->path_info) + { + if ((rv = apr_filepath_merge(&r->path_info, r->filename, + r->path_info, + APR_FILEPATH_NOTABOVEROOT, r->pool)) + != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "dir_walk error, path_info %s is not relative " + "to the filename path %s for uri %s", + r->path_info, r->filename, r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + + save_path_info = NULL; + } + else { + save_path_info = r->path_info; + r->path_info = r->filename; + } + +#ifdef CASE_BLIND_FILESYSTEM + + canonical_len = 0; + while (r->canonical_filename && r->canonical_filename[canonical_len] + && (r->canonical_filename[canonical_len] + == r->path_info[canonical_len])) { + ++canonical_len; + } + + while (canonical_len + && ((r->canonical_filename[canonical_len - 1] != '/' + && r->canonical_filename[canonical_len - 1]) + || (r->path_info[canonical_len - 1] != '/' + && r->path_info[canonical_len - 1]))) { + --canonical_len; + } + + /* + * Now build r->filename component by component, starting + * with the root (on Unix, simply "/"). We will make a huge + * assumption here for efficiency, that any canonical path + * already given included a canonical root. + */ + rv = apr_filepath_root((const char **)&r->filename, + (const char **)&r->path_info, + canonical_len ? 0 : APR_FILEPATH_TRUENAME, + r->pool); + filename_len = strlen(r->filename); + + /* + * Bad assumption above? If the root's length is longer + * than the canonical length, then it cannot be trusted as + * a truename. So try again, this time more seriously. + */ + if ((rv == APR_SUCCESS) && canonical_len + && (filename_len > canonical_len)) { + rv = apr_filepath_root((const char **)&r->filename, + (const char **)&r->path_info, + APR_FILEPATH_TRUENAME, r->pool); + filename_len = strlen(r->filename); + canonical_len = 0; + } + +#else /* ndef CASE_BLIND_FILESYSTEM, really this simple for Unix today; */ + + rv = apr_filepath_root((const char **)&r->filename, + (const char **)&r->path_info, + 0, r->pool); + filename_len = strlen(r->filename); + +#endif + + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "dir_walk error, could not determine the root " + "path of filename %s%s for uri %s", + r->filename, r->path_info, r->uri); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Working space for terminating null and an extra / is required. + */ + buflen = filename_len + strlen(r->path_info) + 2; + buf = apr_palloc(r->pool, buflen); + memcpy(buf, r->filename, filename_len + 1); + r->filename = buf; + thisinfo.valid = APR_FINFO_TYPE; + thisinfo.filetype = APR_DIR; /* It's the root, of course it's a dir */ + + /* + * seg keeps track of which segment we've copied. + * sec_idx keeps track of which section we're on, since sections are + * ordered by number of segments. See core_reorder_directories + * startseg tells us how many segments describe the root path + * e.g. the complete path "//host/foo/" to a UNC share (4) + */ + startseg = seg = ap_count_dirs(r->filename); + sec_idx = 0; + + /* + * Go down the directory hierarchy. Where we have to check for + * symlinks, do so. Where a .htaccess file has permission to + * override anything, try to find one. + */ + do { + int res; + char *seg_name; + char *delim; + int temp_slash=0; + + /* We have no trailing slash, but we sure would appreciate one. + * However, we don't want to append a / our first time through. + */ + if ((seg > startseg) && r->filename[filename_len-1] != '/') { + r->filename[filename_len++] = '/'; + r->filename[filename_len] = 0; + temp_slash=1; + } + + /* Begin *this* level by looking for matching sections + * from the server config. + */ + for (; sec_idx < num_sec; ++sec_idx) { + + ap_conf_vector_t *entry_config = sec_ent[sec_idx]; + core_dir_config *entry_core; + entry_core = ap_get_module_config(entry_config, &core_module); + + /* No more possible matches for this many segments? + * We are done when we find relative/regex/longer components. + */ + if (entry_core->r || entry_core->d_components > seg) { + break; + } + + /* We will never skip '0' element components, e.g. plain old + * , and are classified as zero + * so that Win32/Netware/OS2 etc all pick them up. + * Otherwise, skip over the mismatches. + */ + if (entry_core->d_components + && ((entry_core->d_components < seg) + || (entry_core->d_is_fnmatch + ? (apr_fnmatch(entry_core->d, r->filename, + APR_FNM_PATHNAME) != APR_SUCCESS) + : (strcmp(r->filename, entry_core->d) != 0)))) { + continue; + } + + /* If we haven't continue'd above, we have a match. + * + * Calculate our full-context core opts & override. + */ + core_opts_merge(sec_ent[sec_idx], &opts); + + /* If we merged this same section last time, reuse it + */ + if (matches) { + if (last_walk->matched == sec_ent[sec_idx]) { + now_merged = last_walk->merged; + ++last_walk; + --matches; + continue; + } + + /* We fell out of sync. This is our own copy of walked, + * so truncate the remaining matches and reset remaining. + */ + cache->walked->nelts -= matches; + matches = 0; + } + + if (now_merged) { + now_merged = ap_merge_per_dir_configs(r->pool, + now_merged, + sec_ent[sec_idx]); + } + else { + now_merged = sec_ent[sec_idx]; + } + + last_walk = (walk_walked_t*)apr_array_push(cache->walked); + last_walk->matched = sec_ent[sec_idx]; + last_walk->merged = now_merged; + } + + /* If .htaccess files are enabled, check for one, provided we + * have reached a real path. + */ + do { /* Not really a loop, just a break'able code block */ + + ap_conf_vector_t *htaccess_conf = NULL; + + /* No htaccess in an incomplete root path, + * nor if it's disabled + */ + if (seg < startseg || !opts.override) { + break; + } + + res = ap_parse_htaccess(&htaccess_conf, r, opts.override, + opts.override_opts, + apr_pstrdup(r->pool, r->filename), + sconf->access_name); + if (res) { + return res; + } + + if (!htaccess_conf) { + break; + } + + /* If we are still here, we found our htaccess. + * + * Calculate our full-context core opts & override. + */ + core_opts_merge(htaccess_conf, &opts); + + /* If we merged this same htaccess last time, reuse it... + * this wouldn't work except that we cache the htaccess + * sections for the lifetime of the request, so we match + * the same conf. Good planning (no, pure luck ;) + */ + if (matches) { + if (last_walk->matched == htaccess_conf) { + now_merged = last_walk->merged; + ++last_walk; + --matches; + break; + } + + /* We fell out of sync. This is our own copy of walked, + * so truncate the remaining matches and reset + * remaining. + */ + cache->walked->nelts -= matches; + matches = 0; + } + + if (now_merged) { + now_merged = ap_merge_per_dir_configs(r->pool, + now_merged, + htaccess_conf); + } + else { + now_merged = htaccess_conf; + } + + last_walk = (walk_walked_t*)apr_array_push(cache->walked); + last_walk->matched = htaccess_conf; + last_walk->merged = now_merged; + + } while (0); /* Only one htaccess, not a real loop */ + + /* That temporary trailing slash was useful, now drop it. + */ + if (temp_slash) { + r->filename[--filename_len] = '\0'; + } + + /* Time for all good things to come to an end? + */ + if (!r->path_info || !*r->path_info) { + break; + } + + /* Now it's time for the next segment... + * We will assume the next element is an end node, and fix it up + * below as necessary... + */ + + seg_name = r->filename + filename_len; + delim = strchr(r->path_info + (*r->path_info == '/' ? 1 : 0), '/'); + if (delim) { + size_t path_info_len = delim - r->path_info; + *delim = '\0'; + memcpy(seg_name, r->path_info, path_info_len + 1); + filename_len += path_info_len; + r->path_info = delim; + *delim = '/'; + } + else { + size_t path_info_len = strlen(r->path_info); + memcpy(seg_name, r->path_info, path_info_len + 1); + filename_len += path_info_len; + r->path_info += path_info_len; + } + if (*seg_name == '/') + ++seg_name; + + /* If nothing remained but a '/' string, we are finished + * XXX: NO WE ARE NOT!!! Now process this puppy!!! */ + if (!*seg_name) { + break; + } + + /* First optimization; + * If...we knew r->filename was a file, and + * if...we have strict (case-sensitive) filenames, or + * we know the canonical_filename matches to _this_ name, and + * if...we have allowed symlinks + * skip the lstat and dummy up an APR_DIR value for thisinfo. + */ + if (r->finfo.filetype +#ifdef CASE_BLIND_FILESYSTEM + && (filename_len <= canonical_len) +#endif + && ((opts.opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS)) + { + + thisinfo.filetype = APR_DIR; + ++seg; + continue; + } + + /* We choose apr_stat with flag APR_FINFO_LINK here, rather that + * plain apr_stat, so that we capture this path object rather than + * its target. We will replace the info with our target's info + * below. We especially want the name of this 'link' object, not + * the name of its target, if we are fixing the filename + * case/resolving aliases. + */ + rv = apr_stat(&thisinfo, r->filename, + APR_FINFO_MIN | APR_FINFO_NAME | APR_FINFO_LINK, + r->pool); + + if (APR_STATUS_IS_ENOENT(rv)) { + /* Nothing? That could be nice. But our directory + * walk is done. + */ + thisinfo.filetype = APR_NOFILE; + break; + } + else if (APR_STATUS_IS_EACCES(rv)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "access to %s denied", r->uri); + return r->status = HTTP_FORBIDDEN; + } + else if ((rv != APR_SUCCESS && rv != APR_INCOMPLETE) + || !(thisinfo.valid & APR_FINFO_TYPE)) { + /* If we hit ENOTDIR, we must have over-optimized, deny + * rather than assume not found. + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "access to %s failed", r->uri); + return r->status = HTTP_FORBIDDEN; + } + + /* Fix up the path now if we have a name, and they don't agree + */ + if ((thisinfo.valid & APR_FINFO_NAME) + && strcmp(seg_name, thisinfo.name)) { + /* TODO: provide users an option that an internal/external + * redirect is required here? We need to walk the URI and + * filename in tandem to properly correlate these. + */ + strcpy(seg_name, thisinfo.name); + filename_len = strlen(r->filename); + } + + if (thisinfo.filetype == APR_LNK) { + /* Is this a possibly acceptable symlink? + */ + if ((res = resolve_symlink(r->filename, &thisinfo, + opts.opts, r->pool)) != OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Symbolic link not allowed: %s", + r->filename); + return r->status = res; + } + } + + /* Ok, we are done with the link's info, test the real target + */ + if (thisinfo.filetype == APR_REG || + thisinfo.filetype == APR_NOFILE) { + /* That was fun, nothing left for us here + */ + break; + } + else if (thisinfo.filetype != APR_DIR) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Forbidden: %s doesn't point to " + "a file or directory", + r->filename); + return r->status = HTTP_FORBIDDEN; + } + + ++seg; + } while (thisinfo.filetype == APR_DIR); + + /* If we have _not_ optimized, this is the time to recover + * the final stat result. + */ + if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) { + r->finfo = thisinfo; + } + + /* Now splice the saved path_info back onto any new path_info + */ + if (save_path_info) { + if (r->path_info && *r->path_info) { + r->path_info = ap_make_full_path(r->pool, r->path_info, + save_path_info); + } + else { + r->path_info = save_path_info; + } + } + + /* + * Now we'll deal with the regexes, note we pick up sec_idx + * where we left off (we gave up after we hit entry_core->r) + */ + for (; sec_idx < num_sec; ++sec_idx) { + + core_dir_config *entry_core; + entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); + + if (!entry_core->r) { + continue; + } + + if (ap_regexec(entry_core->r, r->filename, 0, NULL, AP_REG_NOTEOL)) { + continue; + } + + /* If we haven't already continue'd above, we have a match. + * + * Calculate our full-context core opts & override. + */ + core_opts_merge(sec_ent[sec_idx], &opts); + + /* If we merged this same section last time, reuse it + */ + if (matches) { + if (last_walk->matched == sec_ent[sec_idx]) { + now_merged = last_walk->merged; + ++last_walk; + --matches; + continue; + } + + /* We fell out of sync. This is our own copy of walked, + * so truncate the remaining matches and reset remaining. + */ + cache->walked->nelts -= matches; + matches = 0; + } + + if (now_merged) { + now_merged = ap_merge_per_dir_configs(r->pool, + now_merged, + sec_ent[sec_idx]); + } + else { + now_merged = sec_ent[sec_idx]; + } + + last_walk = (walk_walked_t*)apr_array_push(cache->walked); + last_walk->matched = sec_ent[sec_idx]; + last_walk->merged = now_merged; + } + + /* Whoops - everything matched in sequence, but the original walk + * found some additional matches. Truncate them. + */ + if (matches) { + cache->walked->nelts -= matches; + } + } + +/* It seems this shouldn't be needed anymore. We translated the + x symlink above into a real resource, and should have died up there. + x Even if we keep this, it needs more thought (maybe an r->file_is_symlink) + x perhaps it should actually happen in file_walk, so we catch more + x obscure cases in autoindex subrequests, etc. + x + x * Symlink permissions are determined by the parent. If the request is + x * for a directory then applying the symlink test here would use the + x * permissions of the directory as opposed to its parent. Consider a + x * symlink pointing to a dir with a .htaccess disallowing symlinks. If + x * you access /symlink (or /symlink/) you would get a 403 without this + x * APR_DIR test. But if you accessed /symlink/index.html, for example, + x * you would *not* get the 403. + x + x if (r->finfo.filetype != APR_DIR + x && (res = resolve_symlink(r->filename, r->info, ap_allow_options(r), + x r->pool))) { + x ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + x "Symbolic link not allowed: %s", r->filename); + x return res; + x } + */ + + /* Save future sub-requestors much angst in processing + * this subrequest. If dir_walk couldn't canonicalize + * the file path, nothing can. + */ + r->canonical_filename = r->filename; + + if (r->finfo.filetype == APR_DIR) { + cache->cached = r->filename; + } + else { + cache->cached = ap_make_dirstr_parent(r->pool, r->filename); + } + + cache->dir_conf_tested = sec_ent; + cache->dir_conf_merged = r->per_dir_config; + + /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, + * and note the end result to (potentially) skip this step next time. + */ + if (now_merged) { + r->per_dir_config = ap_merge_per_dir_configs(r->pool, + r->per_dir_config, + now_merged); + } + cache->per_dir_result = r->per_dir_config; + + return OK; +} + + +AP_DECLARE(int) ap_location_walk(request_rec *r) +{ + ap_conf_vector_t *now_merged = NULL; + core_server_config *sconf = ap_get_module_config(r->server->module_config, + &core_module); + ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)sconf->sec_url->elts; + int num_sec = sconf->sec_url->nelts; + walk_cache_t *cache; + const char *entry_uri; + + /* No tricks here, there are no to parse in this vhost. + * We won't destroy the cache, just in case _this_ redirect is later + * redirected again to a vhost with blocks to optimize. + */ + if (!num_sec) { + return OK; + } + + cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); + + /* Location and LocationMatch differ on their behaviour w.r.t. multiple + * slashes. Location matches multiple slashes with a single slash, + * LocationMatch doesn't. An exception, for backwards brokenness is + * absoluteURIs... in which case neither match multiple slashes. + */ + if (r->uri[0] != '/') { + entry_uri = r->uri; + } + else { + char *uri = apr_pstrdup(r->pool, r->uri); + ap_no2slash(uri); + entry_uri = uri; + } + + /* If we have an cache->cached location that matches r->uri, + * and the vhost's list of locations hasn't changed, we can skip + * rewalking the location_walk entries. + */ + if (cache->cached + && (cache->dir_conf_tested == sec_ent) + && (strcmp(entry_uri, cache->cached) == 0)) { + /* Well this looks really familiar! If our end-result (per_dir_result) + * didn't change, we have absolutely nothing to do :) + * Otherwise (as is the case with most dir_merged/file_merged requests) + * we must merge our dir_conf_merged onto this new r->per_dir_config. + */ + if (r->per_dir_config == cache->per_dir_result) { + return OK; + } + + if (r->per_dir_config == cache->dir_conf_merged) { + r->per_dir_config = cache->per_dir_result; + return OK; + } + + if (cache->walked->nelts) { + now_merged = ((walk_walked_t*)cache->walked->elts) + [cache->walked->nelts - 1].merged; + } + } + else { + /* We start now_merged from NULL since we want to build + * a locations list that can be merged to any vhost. + */ + int len, sec_idx; + int matches = cache->walked->nelts; + walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; + cache->cached = entry_uri; + + /* Go through the location entries, and check for matches. + * We apply the directive sections in given order, we should + * really try them with the most general first. + */ + for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) { + + core_dir_config *entry_core; + entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); + + /* ### const strlen can be optimized in location config parsing */ + len = strlen(entry_core->d); + + /* Test the regex, fnmatch or string as appropriate. + * If it's a strcmp, and the pattern was + * not slash terminated, then this uri must be slash + * terminated (or at the end of the string) to match. + */ + if (entry_core->r + ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0) + : (entry_core->d_is_fnmatch + ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) + : (strncmp(entry_core->d, cache->cached, len) + || (entry_core->d[len - 1] != '/' + && cache->cached[len] != '/' + && cache->cached[len] != '\0')))) { + continue; + } + + /* If we merged this same section last time, reuse it + */ + if (matches) { + if (last_walk->matched == sec_ent[sec_idx]) { + now_merged = last_walk->merged; + ++last_walk; + --matches; + continue; + } + + /* We fell out of sync. This is our own copy of walked, + * so truncate the remaining matches and reset remaining. + */ + cache->walked->nelts -= matches; + matches = 0; + } + + if (now_merged) { + now_merged = ap_merge_per_dir_configs(r->pool, + now_merged, + sec_ent[sec_idx]); + } + else { + now_merged = sec_ent[sec_idx]; + } + + last_walk = (walk_walked_t*)apr_array_push(cache->walked); + last_walk->matched = sec_ent[sec_idx]; + last_walk->merged = now_merged; + } + + /* Whoops - everything matched in sequence, but the original walk + * found some additional matches. Truncate them. + */ + if (matches) { + cache->walked->nelts -= matches; + } + } + + cache->dir_conf_tested = sec_ent; + cache->dir_conf_merged = r->per_dir_config; + + /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, + * and note the end result to (potentially) skip this step next time. + */ + if (now_merged) { + r->per_dir_config = ap_merge_per_dir_configs(r->pool, + r->per_dir_config, + now_merged); + } + cache->per_dir_result = r->per_dir_config; + + return OK; +} + +AP_DECLARE(int) ap_file_walk(request_rec *r) +{ + ap_conf_vector_t *now_merged = NULL; + core_dir_config *dconf = ap_get_module_config(r->per_dir_config, + &core_module); + ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)dconf->sec_file->elts; + int num_sec = dconf->sec_file->nelts; + walk_cache_t *cache; + const char *test_file; + + /* To allow broken modules to proceed, we allow missing filenames to pass. + * We will catch it later if it's heading for the core handler. + * directory_walk already posted an INFO note for module debugging. + */ + if (r->filename == NULL) { + return OK; + } + + cache = prep_walk_cache(AP_NOTE_FILE_WALK, r); + + /* No tricks here, there are just no to parse in this context. + * We won't destroy the cache, just in case _this_ redirect is later + * redirected again to a context containing the same or similar . + */ + if (!num_sec) { + return OK; + } + + /* Get the basename .. and copy for the cache just + * in case r->filename is munged by another module + */ + test_file = strrchr(r->filename, '/'); + if (test_file == NULL) { + test_file = apr_pstrdup(r->pool, r->filename); + } + else { + test_file = apr_pstrdup(r->pool, ++test_file); + } + + /* If we have an cache->cached file name that matches test_file, + * and the directory's list of file sections hasn't changed, we + * can skip rewalking the file_walk entries. + */ + if (cache->cached + && (cache->dir_conf_tested == sec_ent) + && (strcmp(test_file, cache->cached) == 0)) { + /* Well this looks really familiar! If our end-result (per_dir_result) + * didn't change, we have absolutely nothing to do :) + * Otherwise (as is the case with most dir_merged requests) + * we must merge our dir_conf_merged onto this new r->per_dir_config. + */ + if (r->per_dir_config == cache->per_dir_result) { + return OK; + } + + if (r->per_dir_config == cache->dir_conf_merged) { + r->per_dir_config = cache->per_dir_result; + return OK; + } + + if (cache->walked->nelts) { + now_merged = ((walk_walked_t*)cache->walked->elts) + [cache->walked->nelts - 1].merged; + } + } + else { + /* We start now_merged from NULL since we want to build + * a file section list that can be merged to any dir_walk. + */ + int sec_idx; + int matches = cache->walked->nelts; + walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts; + cache->cached = test_file; + + /* Go through the location entries, and check for matches. + * We apply the directive sections in given order, we should + * really try them with the most general first. + */ + for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) { + + core_dir_config *entry_core; + entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module); + + if (entry_core->r + ? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0) + : (entry_core->d_is_fnmatch + ? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) + : strcmp(entry_core->d, cache->cached))) { + continue; + } + + /* If we merged this same section last time, reuse it + */ + if (matches) { + if (last_walk->matched == sec_ent[sec_idx]) { + now_merged = last_walk->merged; + ++last_walk; + --matches; + continue; + } + + /* We fell out of sync. This is our own copy of walked, + * so truncate the remaining matches and reset remaining. + */ + cache->walked->nelts -= matches; + matches = 0; + } + + if (now_merged) { + now_merged = ap_merge_per_dir_configs(r->pool, + now_merged, + sec_ent[sec_idx]); + } + else { + now_merged = sec_ent[sec_idx]; + } + + last_walk = (walk_walked_t*)apr_array_push(cache->walked); + last_walk->matched = sec_ent[sec_idx]; + last_walk->merged = now_merged; + } + + /* Whoops - everything matched in sequence, but the original walk + * found some additional matches. Truncate them. + */ + if (matches) { + cache->walked->nelts -= matches; + } + } + + cache->dir_conf_tested = sec_ent; + cache->dir_conf_merged = r->per_dir_config; + + /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs, + * and note the end result to (potentially) skip this step next time. + */ + if (now_merged) { + r->per_dir_config = ap_merge_per_dir_configs(r->pool, + r->per_dir_config, + now_merged); + } + cache->per_dir_result = r->per_dir_config; + + return OK; +} + +/***************************************************************** + * + * The sub_request mechanism. + * + * Fns to look up a relative URI from, e.g., a map file or SSI document. + * These do all access checks, etc., but don't actually run the transaction + * ... use run_sub_req below for that. Also, be sure to use destroy_sub_req + * as appropriate if you're likely to be creating more than a few of these. + * (An early Apache version didn't destroy the sub_reqs used in directory + * indexing. The result, when indexing a directory with 800-odd files in + * it, was massively excessive storage allocation). + * + * Note more manipulation of protocol-specific vars in the request + * structure... + */ + +static request_rec *make_sub_request(const request_rec *r, + ap_filter_t *next_filter) +{ + apr_pool_t *rrp; + request_rec *rnew; + + apr_pool_create(&rrp, r->pool); + apr_pool_tag(rrp, "subrequest"); + rnew = apr_pcalloc(rrp, sizeof(request_rec)); + rnew->pool = rrp; + + rnew->hostname = r->hostname; + rnew->request_time = r->request_time; + rnew->connection = r->connection; + rnew->server = r->server; + + rnew->request_config = ap_create_request_config(rnew->pool); + + /* Start a clean config from this subrequest's vhost. Optimization in + * Location/File/Dir walks from the parent request assure that if the + * config blocks of the subrequest match the parent request, no merges + * will actually occur (and generally a minimal number of merges are + * required, even if the parent and subrequest aren't quite identical.) + */ + rnew->per_dir_config = r->server->lookup_defaults; + + rnew->htaccess = r->htaccess; + rnew->allowed_methods = ap_make_method_list(rnew->pool, 2); + + /* make a copy of the allowed-methods list */ + ap_copy_method_list(rnew->allowed_methods, r->allowed_methods); + + /* start with the same set of output filters */ + if (next_filter) { + /* while there are no input filters for a subrequest, we will + * try to insert some, so if we don't have valid data, the code + * will seg fault. + */ + rnew->input_filters = r->input_filters; + rnew->proto_input_filters = r->proto_input_filters; + rnew->output_filters = next_filter; + rnew->proto_output_filters = r->proto_output_filters; + ap_add_output_filter_handle(ap_subreq_core_filter_handle, + NULL, rnew, rnew->connection); + } + else { + /* If NULL - we are expecting to be internal_fast_redirect'ed + * to this subrequest - or this request will never be invoked. + * Ignore the original request filter stack entirely, and + * drill the input and output stacks back to the connection. + */ + rnew->proto_input_filters = r->proto_input_filters; + rnew->proto_output_filters = r->proto_output_filters; + + rnew->input_filters = r->proto_input_filters; + rnew->output_filters = r->proto_output_filters; + } + + /* no input filters for a subrequest */ + + ap_set_sub_req_protocol(rnew, r); + + /* We have to run this after we fill in sub req vars, + * or the r->main pointer won't be setup + */ + ap_run_create_request(rnew); + + return rnew; +} + +AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + apr_bucket *e = APR_BRIGADE_LAST(bb); + + if (APR_BUCKET_IS_EOS(e)) { + apr_bucket_delete(e); + } + + if (!APR_BRIGADE_EMPTY(bb)) { + return ap_pass_brigade(f->next, bb); + } + + return APR_SUCCESS; +} + + +AP_DECLARE(int) ap_some_auth_required(request_rec *r) +{ + /* Is there a require line configured for the type of *this* req? */ + + const apr_array_header_t *reqs_arr = ap_requires(r); + require_line *reqs; + int i; + + if (!reqs_arr) { + return 0; + } + + reqs = (require_line *) reqs_arr->elts; + + for (i = 0; i < reqs_arr->nelts; ++i) { + if (reqs[i].method_mask & (AP_METHOD_BIT << r->method_number)) { + return 1; + } + } + + return 0; +} + + +AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_uri, + const request_rec *r, + ap_filter_t *next_filter) +{ + request_rec *rnew; + int res; + char *udir; + + rnew = make_sub_request(r, next_filter); + + /* 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_uri[0] == '/') { + ap_parse_uri(rnew, new_uri); + } + else { + udir = ap_make_dirstr_parent(rnew->pool, r->uri); + udir = ap_escape_uri(rnew->pool, udir); /* re-escape it */ + ap_parse_uri(rnew, ap_make_full_path(rnew->pool, udir, new_uri)); + } + + /* We cannot return NULL without violating the API. So just turn this + * subrequest into a 500 to indicate the failure. */ + if (ap_is_recursion_limit_exceeded(r)) { + rnew->status = HTTP_INTERNAL_SERVER_ERROR; + return rnew; + } + + /* lookup_uri + * If the content can be served by the quick_handler, we can + * safely bypass request_internal processing. + */ + res = ap_run_quick_handler(rnew, 1); + + if (res != OK) { + if ((res = ap_process_request_internal(rnew))) { + rnew->status = res; + } + } + + return rnew; +} + +AP_DECLARE(request_rec *) ap_sub_req_lookup_uri(const char *new_uri, + const request_rec *r, + ap_filter_t *next_filter) +{ + return ap_sub_req_method_uri("GET", new_uri, r, next_filter); +} + +AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *dirent, + const request_rec *r, + int subtype, + ap_filter_t *next_filter) +{ + request_rec *rnew; + int res; + char *fdir; + char *udir; + + rnew = make_sub_request(r, next_filter); + + /* Special case: we are looking at a relative lookup in the same directory. + * This is 100% safe, since dirent->name just came from the filesystem. + */ + if (r->path_info && *r->path_info) { + /* strip path_info off the end of the uri to keep it in sync + * with r->filename, which has already been stripped by directory_walk, + * merge the dirent->name, and then, if the caller wants us to remerge + * the original path info, do so. Note we never fix the path_info back + * to r->filename, since dir_walk would do so (but we don't expect it + * to happen in the usual cases) + */ + udir = apr_pstrdup(rnew->pool, r->uri); + udir[ap_find_path_info(udir, r->path_info)] = '\0'; + udir = ap_make_dirstr_parent(rnew->pool, udir); + + rnew->uri = ap_make_full_path(rnew->pool, udir, dirent->name); + if (subtype == AP_SUBREQ_MERGE_ARGS) { + rnew->uri = ap_make_full_path(rnew->pool, rnew->uri, r->path_info + 1); + rnew->path_info = apr_pstrdup(rnew->pool, r->path_info); + } + rnew->uri = ap_escape_uri(rnew->pool, rnew->uri); + } + else { + udir = ap_make_dirstr_parent(rnew->pool, r->uri); + rnew->uri = ap_escape_uri(rnew->pool, ap_make_full_path(rnew->pool, + udir, + dirent->name)); + } + + fdir = ap_make_dirstr_parent(rnew->pool, r->filename); + rnew->filename = ap_make_full_path(rnew->pool, fdir, dirent->name); + if (r->canonical_filename == r->filename) { + rnew->canonical_filename = rnew->filename; + } + + /* XXX This is now less relevant; we will do a full location walk + * these days for this case. Preserve the apr_stat results, and + * perhaps we also tag that symlinks were tested and/or found for + * r->filename. + */ + rnew->per_dir_config = r->server->lookup_defaults; + + if ((dirent->valid & APR_FINFO_MIN) != APR_FINFO_MIN) { + /* + * apr_dir_read isn't very complete on this platform, so + * we need another apr_stat (with or without APR_FINFO_LINK + * depending on whether we allow all symlinks here.) If this + * is an APR_LNK that resolves to an APR_DIR, then we will rerun + * everything anyways... this should be safe. + */ + apr_status_t rv; + if (ap_allow_options(rnew) & OPT_SYM_LINKS) { + if (((rv = apr_stat(&rnew->finfo, rnew->filename, + APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) + && (rv != APR_INCOMPLETE)) { + rnew->finfo.filetype = 0; + } + } + else { + if (((rv = apr_stat(&rnew->finfo, rnew->filename, + APR_FINFO_LINK | APR_FINFO_MIN, + rnew->pool)) != APR_SUCCESS) + && (rv != APR_INCOMPLETE)) { + rnew->finfo.filetype = 0; + } + } + } + else { + memcpy(&rnew->finfo, dirent, sizeof(apr_finfo_t)); + } + + if (rnew->finfo.filetype == APR_LNK) { + /* + * Resolve this symlink. We should tie this back to dir_walk's cache + */ + if ((res = resolve_symlink(rnew->filename, &rnew->finfo, + ap_allow_options(rnew), rnew->pool)) + != OK) { + rnew->status = res; + return rnew; + } + } + + if (rnew->finfo.filetype == APR_DIR) { + /* ap_make_full_path overallocated the buffers + * by one character to help us out here. + */ + strcpy(rnew->filename + strlen(rnew->filename), "/"); + if (!rnew->path_info || !*rnew->path_info) { + strcpy(rnew->uri + strlen(rnew->uri ), "/"); + } + } + + /* fill in parsed_uri values + */ + if (r->args && *r->args && (subtype == AP_SUBREQ_MERGE_ARGS)) { + ap_parse_uri(rnew, apr_pstrcat(r->pool, rnew->uri, "?", + r->args, NULL)); + } + else { + ap_parse_uri(rnew, rnew->uri); + } + + /* We cannot return NULL without violating the API. So just turn this + * subrequest into a 500. */ + if (ap_is_recursion_limit_exceeded(r)) { + rnew->status = HTTP_INTERNAL_SERVER_ERROR; + return rnew; + } + + if ((res = ap_process_request_internal(rnew))) { + rnew->status = res; + } + + return rnew; +} + +AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file, + const request_rec *r, + ap_filter_t *next_filter) +{ + request_rec *rnew; + int res; + char *fdir; + apr_size_t fdirlen; + + rnew = make_sub_request(r, next_filter); + + fdir = ap_make_dirstr_parent(rnew->pool, r->filename); + fdirlen = strlen(fdir); + + /* Translate r->filename, if it was canonical, it stays canonical + */ + if (r->canonical_filename == r->filename) { + rnew->canonical_filename = (char*)(1); + } + + if (apr_filepath_merge(&rnew->filename, fdir, new_file, + APR_FILEPATH_TRUENAME, rnew->pool) != APR_SUCCESS) { + rnew->status = HTTP_FORBIDDEN; + return rnew; + } + + if (rnew->canonical_filename) { + rnew->canonical_filename = rnew->filename; + } + + /* + * Check for a special case... if there are no '/' characters in new_file + * at all, and the path was the same, then we are looking at a relative + * lookup in the same directory. Fixup the URI to match. + */ + + if (strncmp(rnew->filename, fdir, fdirlen) == 0 + && rnew->filename[fdirlen] + && ap_strchr_c(rnew->filename + fdirlen, '/') == NULL) { + apr_status_t rv; + if (ap_allow_options(rnew) & OPT_SYM_LINKS) { + if (((rv = apr_stat(&rnew->finfo, rnew->filename, + APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) + && (rv != APR_INCOMPLETE)) { + rnew->finfo.filetype = 0; + } + } + else { + if (((rv = apr_stat(&rnew->finfo, rnew->filename, + APR_FINFO_LINK | APR_FINFO_MIN, + rnew->pool)) != APR_SUCCESS) + && (rv != APR_INCOMPLETE)) { + rnew->finfo.filetype = 0; + } + } + + if (r->uri && *r->uri) { + char *udir = ap_make_dirstr_parent(rnew->pool, r->uri); + rnew->uri = ap_make_full_path(rnew->pool, udir, + rnew->filename + fdirlen); + ap_parse_uri(rnew, rnew->uri); /* fill in parsed_uri values */ + } + else { + ap_parse_uri(rnew, new_file); /* fill in parsed_uri values */ + rnew->uri = apr_pstrdup(rnew->pool, ""); + } + } + else { + /* XXX: @@@: What should be done with the parsed_uri values? + * We would be better off stripping down to the 'common' elements + * of the path, then reassembling the URI as best as we can. + */ + ap_parse_uri(rnew, new_file); /* fill in parsed_uri values */ + /* + * XXX: this should be set properly like it is in the same-dir case + * but it's actually sometimes to impossible to do it... because the + * file may not have a uri associated with it -djg + */ + rnew->uri = apr_pstrdup(rnew->pool, ""); + } + + /* We cannot return NULL without violating the API. So just turn this + * subrequest into a 500. */ + if (ap_is_recursion_limit_exceeded(r)) { + rnew->status = HTTP_INTERNAL_SERVER_ERROR; + return rnew; + } + + if ((res = ap_process_request_internal(rnew))) { + rnew->status = res; + } + + return rnew; +} + +AP_DECLARE(int) ap_run_sub_req(request_rec *r) +{ + int retval = DECLINED; + /* Run the quick handler if the subrequest is not a dirent or file + * subrequest + */ + if (!(r->filename && r->finfo.filetype)) { + retval = ap_run_quick_handler(r, 0); + } + if (retval != OK) { + retval = ap_invoke_handler(r); + if (retval == DONE) { + retval = OK; + } + } + ap_finalize_sub_req_protocol(r); + return retval; +} + +AP_DECLARE(void) ap_destroy_sub_req(request_rec *r) +{ + /* Reclaim the space */ + apr_pool_destroy(r->pool); +} + +/* + * Function to set the r->mtime field to the specified value if it's later + * than what's already there. + */ +AP_DECLARE(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime) +{ + if (r->mtime < dependency_mtime) { + r->mtime = dependency_mtime; + } +} + +/* + * Is it the initial main request, which we only get *once* per HTTP request? + */ +AP_DECLARE(int) ap_is_initial_req(request_rec *r) +{ + return (r->main == NULL) /* otherwise, this is a sub-request */ + && (r->prev == NULL); /* otherwise, this is an internal redirect */ +} diff --git a/trunk/server/scoreboard.c b/trunk/server/scoreboard.c new file mode 100644 index 0000000000..6098837a4e --- /dev/null +++ b/trunk/server/scoreboard.c @@ -0,0 +1,498 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_SYS_TYPES_H +#include +#endif + +#include "ap_config.h" +#include "httpd.h" +#include "http_log.h" +#include "http_main.h" +#include "http_core.h" +#include "http_config.h" +#include "ap_mpm.h" + +#include "mpm.h" +#include "scoreboard.h" + +AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL; +AP_DECLARE_DATA const char *ap_scoreboard_fname = NULL; +AP_DECLARE_DATA int ap_extended_status = 0; + +#if APR_HAS_SHARED_MEMORY + +#include "apr_shm.h" + +#ifndef WIN32 +static /* but must be exported to mpm_winnt */ +#endif + apr_shm_t *ap_scoreboard_shm = NULL; + +#endif + +APR_HOOK_STRUCT( + APR_HOOK_LINK(pre_mpm) +) + +AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_mpm, + (apr_pool_t *p, ap_scoreboard_e sb_type), + (p, sb_type),OK,DECLINED) + +static APR_OPTIONAL_FN_TYPE(ap_proxy_lb_workers) + *proxy_lb_workers; + +struct ap_sb_handle_t { + int child_num; + int thread_num; +}; + +static int server_limit, thread_limit, lb_limit; +static apr_size_t scoreboard_size; + +/* + * ToDo: + * This function should be renamed to cleanup_shared + * and it should handle cleaning up a scoreboard shared + * between processes using any form of IPC (file, shared memory + * segment, etc.). Leave it as is now because it is being used + * by various MPMs. + */ +static apr_status_t ap_cleanup_shared_mem(void *d) +{ +#if APR_HAS_SHARED_MEMORY + free(ap_scoreboard_image); + ap_scoreboard_image = NULL; + apr_shm_destroy(ap_scoreboard_shm); +#endif + return APR_SUCCESS; +} + +AP_DECLARE(int) ap_calc_scoreboard_size(void) +{ + ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); + ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); + + if (!proxy_lb_workers) + proxy_lb_workers = APR_RETRIEVE_OPTIONAL_FN(ap_proxy_lb_workers); + if (proxy_lb_workers) + lb_limit = proxy_lb_workers(); + else + lb_limit = 0; + + scoreboard_size = sizeof(global_score); + scoreboard_size += sizeof(process_score) * server_limit; + scoreboard_size += sizeof(worker_score) * server_limit * thread_limit; + if (lb_limit) + scoreboard_size += sizeof(lb_score) * lb_limit; + + return scoreboard_size; +} + +void ap_init_scoreboard(void *shared_score) +{ + char *more_storage; + int i; + + ap_calc_scoreboard_size(); + ap_scoreboard_image = + calloc(1, sizeof(scoreboard) + server_limit * sizeof(worker_score *) + + server_limit * lb_limit * sizeof(lb_score *)); + more_storage = shared_score; + ap_scoreboard_image->global = (global_score *)more_storage; + more_storage += sizeof(global_score); + ap_scoreboard_image->parent = (process_score *)more_storage; + more_storage += sizeof(process_score) * server_limit; + ap_scoreboard_image->servers = + (worker_score **)((char*)ap_scoreboard_image + sizeof(scoreboard)); + for (i = 0; i < server_limit; i++) { + ap_scoreboard_image->servers[i] = (worker_score *)more_storage; + more_storage += thread_limit * sizeof(worker_score); + } + if (lb_limit) { + ap_scoreboard_image->balancers = (lb_score *)more_storage; + more_storage += lb_limit * sizeof(lb_score); + } + ap_assert(more_storage == (char*)shared_score + scoreboard_size); + ap_scoreboard_image->global->server_limit = server_limit; + ap_scoreboard_image->global->thread_limit = thread_limit; + ap_scoreboard_image->global->lb_limit = lb_limit; +} + +/** + * Create a name-based scoreboard in the given pool using the + * given filename. + */ +static apr_status_t create_namebased_scoreboard(apr_pool_t *pool, + const char *fname) +{ +#if APR_HAS_SHARED_MEMORY + apr_status_t rv; + + /* The shared memory file must not exist before we create the + * segment. */ + apr_shm_remove(fname, pool); /* ignore errors */ + + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, fname, pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "unable to create scoreboard \"%s\" " + "(name-based shared memory failure)", fname); + return rv; + } +#endif /* APR_HAS_SHARED_MEMORY */ + return APR_SUCCESS; +} + +/* ToDo: This function should be made to handle setting up + * a scoreboard shared between processes using any IPC technique, + * not just a shared memory segment + */ +static apr_status_t open_scoreboard(apr_pool_t *pconf) +{ +#if APR_HAS_SHARED_MEMORY + apr_status_t rv; + char *fname = NULL; + apr_pool_t *global_pool; + + /* We don't want to have to recreate the scoreboard after + * restarts, so we'll create a global pool and never clean it. + */ + rv = apr_pool_create(&global_pool, NULL); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "Fatal error: unable to create global pool " + "for use with by the scoreboard"); + return rv; + } + + /* The config says to create a name-based shmem */ + if (ap_scoreboard_fname) { + /* make sure it's an absolute pathname */ + fname = ap_server_root_relative(pconf, ap_scoreboard_fname); + if (!fname) { + ap_log_error(APLOG_MARK, APLOG_CRIT, APR_EBADPATH, NULL, + "Fatal error: Invalid Scoreboard path %s", + ap_scoreboard_fname); + return APR_EBADPATH; + } + return create_namebased_scoreboard(global_pool, fname); + } + else { /* config didn't specify, we get to choose shmem type */ + rv = apr_shm_create(&ap_scoreboard_shm, scoreboard_size, NULL, + global_pool); /* anonymous shared memory */ + if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "Unable to create scoreboard " + "(anonymous shared memory failure)"); + return rv; + } + /* Make up a filename and do name-based shmem */ + else if (rv == APR_ENOTIMPL) { + /* Make sure it's an absolute pathname */ + ap_scoreboard_fname = DEFAULT_SCOREBOARD; + fname = ap_server_root_relative(pconf, ap_scoreboard_fname); + + return create_namebased_scoreboard(global_pool, fname); + } + } +#endif /* APR_HAS_SHARED_MEMORY */ + return APR_SUCCESS; +} + +/* If detach is non-zero, this is a seperate child process, + * if zero, it is a forked child. + */ +apr_status_t ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached) +{ +#if APR_HAS_SHARED_MEMORY + if (!detached) { + return APR_SUCCESS; + } + if (apr_shm_size_get(ap_scoreboard_shm) < scoreboard_size) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, + "Fatal error: shared scoreboard too small for child!"); + apr_shm_detach(ap_scoreboard_shm); + ap_scoreboard_shm = NULL; + return APR_EINVAL; + } + /* everything will be cleared shortly */ + if (*shm) { + *shm = ap_scoreboard_shm; + } +#endif + return APR_SUCCESS; +} + +apr_status_t ap_cleanup_scoreboard(void *d) +{ + if (ap_scoreboard_image == NULL) { + return APR_SUCCESS; + } + if (ap_scoreboard_image->global->sb_type == SB_SHARED) { + ap_cleanup_shared_mem(NULL); + } + else { + free(ap_scoreboard_image->global); + free(ap_scoreboard_image); + ap_scoreboard_image = NULL; + } + return APR_SUCCESS; +} + +/* Create or reinit an existing scoreboard. The MPM can control whether + * the scoreboard is shared across multiple processes or not + */ +int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) +{ + int running_gen = 0; + int i; +#if APR_HAS_SHARED_MEMORY + apr_status_t rv; +#endif + + if (ap_scoreboard_image) { + running_gen = ap_scoreboard_image->global->running_generation; + ap_scoreboard_image->global->restart_time = apr_time_now(); + memset(ap_scoreboard_image->parent, 0, + sizeof(process_score) * server_limit); + for (i = 0; i < server_limit; i++) { + memset(ap_scoreboard_image->servers[i], 0, + sizeof(worker_score) * thread_limit); + } + /* Clean up the lb workers data */ + if (lb_limit) { + memset(ap_scoreboard_image->balancers, 0, + sizeof(lb_score) * lb_limit); + } + return OK; + } + + ap_calc_scoreboard_size(); +#if APR_HAS_SHARED_MEMORY + if (sb_type == SB_SHARED) { + void *sb_shared; + rv = open_scoreboard(p); + if (rv || !(sb_shared = apr_shm_baseaddr_get(ap_scoreboard_shm))) { + return HTTP_INTERNAL_SERVER_ERROR; + } + memset(sb_shared, 0, scoreboard_size); + ap_init_scoreboard(sb_shared); + } + else +#endif + { + /* A simple malloc will suffice */ + void *sb_mem = calloc(1, scoreboard_size); + if (sb_mem == NULL) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, + "(%d)%s: cannot allocate scoreboard", + errno, strerror(errno)); + return HTTP_INTERNAL_SERVER_ERROR; + } + ap_init_scoreboard(sb_mem); + } + + ap_scoreboard_image->global->sb_type = sb_type; + ap_scoreboard_image->global->running_generation = running_gen; + ap_scoreboard_image->global->restart_time = apr_time_now(); + + apr_pool_cleanup_register(p, NULL, ap_cleanup_scoreboard, apr_pool_cleanup_null); + + return OK; +} + +/* Routines called to deal with the scoreboard image + * --- note that we do *not* need write locks, since update_child_status + * only updates a *single* record in place, and only one process writes to + * a given scoreboard slot at a time (either the child process owning that + * slot, or the parent, noting that the child has died). + * + * As a final note --- setting the score entry to getpid() is always safe, + * since when the parent is writing an entry, it's only noting SERVER_DEAD + * anyway. + */ + +AP_DECLARE(int) ap_exists_scoreboard_image(void) +{ + return (ap_scoreboard_image ? 1 : 0); +} + +AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sb, request_rec *r) +{ + worker_score *ws; + + ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num]; + +#ifdef HAVE_TIMES + times(&ws->times); +#endif + ws->access_count++; + ws->my_access_count++; + ws->conn_count++; + ws->bytes_served += r->bytes_sent; + ws->my_bytes_served += r->bytes_sent; + ws->conn_bytes += r->bytes_sent; +} + +int find_child_by_pid(apr_proc_t *pid) +{ + int i; + int max_daemons_limit; + + ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons_limit); + + for (i = 0; i < max_daemons_limit; ++i) { + if (ap_scoreboard_image->parent[i].pid == pid->pid) { + return i; + } + } + + return -1; +} + +AP_DECLARE(void) ap_create_sb_handle(ap_sb_handle_t **new_sbh, apr_pool_t *p, + int child_num, int thread_num) +{ + *new_sbh = (ap_sb_handle_t *)apr_palloc(p, sizeof(ap_sb_handle_t)); + (*new_sbh)->child_num = child_num; + (*new_sbh)->thread_num = thread_num; +} + +AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, + int thread_num, + int status, + request_rec *r) +{ + int old_status; + worker_score *ws; + process_score *ps; + + if (child_num < 0) { + return -1; + } + + ws = &ap_scoreboard_image->servers[child_num][thread_num]; + old_status = ws->status; + ws->status = status; + + ps = &ap_scoreboard_image->parent[child_num]; + + if (status == SERVER_READY + && old_status == SERVER_STARTING) { + ws->thread_num = child_num * thread_limit + thread_num; + ps->generation = ap_my_generation; + } + + if (ap_extended_status) { + ws->last_used = apr_time_now(); + if (status == SERVER_READY || status == SERVER_DEAD) { + /* + * Reset individual counters + */ + if (status == SERVER_DEAD) { + ws->my_access_count = 0L; + ws->my_bytes_served = 0L; + } + ws->conn_count = 0; + ws->conn_bytes = 0; + } + if (r) { + conn_rec *c = r->connection; + apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, + REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); + if (r->the_request == NULL) { + apr_cpystrn(ws->request, "NULL", sizeof(ws->request)); + } else if (r->parsed_uri.password == NULL) { + apr_cpystrn(ws->request, r->the_request, sizeof(ws->request)); + } else { + /* Don't reveal the password in the server-status view */ + apr_cpystrn(ws->request, apr_pstrcat(r->pool, r->method, " ", + apr_uri_unparse(r->pool, &r->parsed_uri, + APR_URI_UNP_OMITPASSWORD), + r->assbackwards ? NULL : " ", r->protocol, NULL), + sizeof(ws->request)); + } + apr_cpystrn(ws->vhost, r->server->server_hostname, + sizeof(ws->vhost)); + } + } + + return old_status; +} + +AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, + request_rec *r) +{ + return ap_update_child_status_from_indexes(sbh->child_num, sbh->thread_num, + status, r); +} + +void ap_time_process_request(ap_sb_handle_t *sbh, int status) +{ + worker_score *ws; + + if (sbh->child_num < 0) { + return; + } + + ws = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num]; + + if (status == START_PREQUEST) { + ws->start_time = apr_time_now(); + } + else if (status == STOP_PREQUEST) { + ws->stop_time = apr_time_now(); + } +} + +AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y) +{ + if (((x < 0) || (server_limit < x)) || + ((y < 0) || (thread_limit < y))) { + return(NULL); /* Out of range */ + } + return &ap_scoreboard_image->servers[x][y]; +} + +AP_DECLARE(process_score *) ap_get_scoreboard_process(int x) +{ + if ((x < 0) || (server_limit < x)) { + return(NULL); /* Out of range */ + } + return &ap_scoreboard_image->parent[x]; +} + +AP_DECLARE(global_score *) ap_get_scoreboard_global() +{ + return ap_scoreboard_image->global; +} + +AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num) +{ + if (((lb_num < 0) || (lb_limit < lb_num))) { + return(NULL); /* Out of range */ + } + return &ap_scoreboard_image->balancers[lb_num]; +} diff --git a/trunk/server/util.c b/trunk/server/util.c new file mode 100644 index 0000000000..34d7ce51ae --- /dev/null +++ b/trunk/server/util.c @@ -0,0 +1,2130 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * util.c: string utility things + * + * 3/21/93 Rob McCool + * 1995-96 Many changes by the Apache Software Foundation + * + */ + +/* Debugging aid: + * #define DEBUG to trace all cfg_open*()/cfg_closefile() calls + * #define DEBUG_CFG_LINES to trace every line read from the config files + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_NETDB_H +#include /* for gethostbyname() */ +#endif + +#define CORE_PRIVATE + +#include "ap_config.h" +#include "apr_base64.h" +#include "httpd.h" +#include "http_main.h" +#include "http_log.h" +#include "http_protocol.h" +#include "http_config.h" +#include "util_ebcdic.h" + +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif + +/* A bunch of functions in util.c scan strings looking for certain characters. + * To make that more efficient we encode a lookup table. The test_char_table + * is generated automatically by gen_test_char.c. + */ +#include "test_char.h" + +/* we assume the folks using this ensure 0 <= c < 256... which means + * you need a cast to (unsigned char) first, you can't just plug a + * char in here and get it to work, because if char is signed then it + * will first be sign extended. + */ +#define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f)) + +/* Win32/NetWare/OS2 need to check for both forward and back slashes + * in ap_getparents() and ap_escape_url. + */ +#ifdef CASE_BLIND_FILESYSTEM +#define IS_SLASH(s) ((s == '/') || (s == '\\')) +#else +#define IS_SLASH(s) (s == '/') +#endif + + +/* + * Examine a field value (such as a media-/content-type) string and return + * it sans any parameters; e.g., strip off any ';charset=foo' and the like. + */ +AP_DECLARE(char *) ap_field_noparam(apr_pool_t *p, const char *intype) +{ + const char *semi; + + if (intype == NULL) return NULL; + + semi = ap_strchr_c(intype, ';'); + if (semi == NULL) { + return apr_pstrdup(p, intype); + } + else { + while ((semi > intype) && apr_isspace(semi[-1])) { + semi--; + } + return apr_pstrndup(p, intype, semi - intype); + } +} + +AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt, + int gmt) +{ + apr_size_t retcode; + char ts[MAX_STRING_LEN]; + char tf[MAX_STRING_LEN]; + apr_time_exp_t xt; + + if (gmt) { + const char *f; + char *strp; + + apr_time_exp_gmt(&xt, t); + /* Convert %Z to "GMT" and %z to "+0000"; + * on hosts that do not have a time zone string in struct tm, + * strftime must assume its argument is local time. + */ + for(strp = tf, f = fmt; strp < tf + sizeof(tf) - 6 && (*strp = *f) + ; f++, strp++) { + if (*f != '%') continue; + switch (f[1]) { + case '%': + *++strp = *++f; + break; + case 'Z': + *strp++ = 'G'; + *strp++ = 'M'; + *strp = 'T'; + f++; + break; + case 'z': /* common extension */ + *strp++ = '+'; + *strp++ = '0'; + *strp++ = '0'; + *strp++ = '0'; + *strp = '0'; + f++; + break; + } + } + *strp = '\0'; + fmt = tf; + } + else { + apr_time_exp_lt(&xt, t); + } + + /* check return code? */ + apr_strftime(ts, &retcode, MAX_STRING_LEN, fmt, &xt); + ts[MAX_STRING_LEN - 1] = '\0'; + return apr_pstrdup(p, ts); +} + +/* Roy owes Rob beer. */ +/* Rob owes Roy dinner. */ + +/* These legacy comments would make a lot more sense if Roy hadn't + * replaced the old later_than() routine with util_date.c. + * + * Well, okay, they still wouldn't make any sense. + */ + +/* Match = 0, NoMatch = 1, Abort = -1 + * Based loosely on sections of wildmat.c by Rich Salz + * Hmmm... shouldn't this really go component by component? + */ +AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected) +{ + int x, y; + + for (x = 0, y = 0; expected[y]; ++y, ++x) { + if ((!str[x]) && (expected[y] != '*')) + return -1; + if (expected[y] == '*') { + while (expected[++y] == '*'); + if (!expected[y]) + return 0; + while (str[x]) { + int ret; + if ((ret = ap_strcmp_match(&str[x++], &expected[y])) != 1) + return ret; + } + return -1; + } + else if ((expected[y] != '?') && (str[x] != expected[y])) + return 1; + } + return (str[x] != '\0'); +} + +AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected) +{ + int x, y; + + for (x = 0, y = 0; expected[y]; ++y, ++x) { + if (!str[x] && expected[y] != '*') + return -1; + if (expected[y] == '*') { + while (expected[++y] == '*'); + if (!expected[y]) + return 0; + while (str[x]) { + int ret; + if ((ret = ap_strcasecmp_match(&str[x++], &expected[y])) != 1) + return ret; + } + return -1; + } + else if (expected[y] != '?' + && apr_tolower(str[x]) != apr_tolower(expected[y])) + return 1; + } + return (str[x] != '\0'); +} + +/* We actually compare the canonical root to this root, (but we don't + * waste time checking the case), since every use of this function in + * httpd-2.1 tests if the path is 'proper', meaning we've already passed + * it through apr_filepath_merge, or we haven't. + */ +AP_DECLARE(int) ap_os_is_path_absolute(apr_pool_t *p, const char *dir) +{ + const char *newpath; + const char *ourdir = dir; + if (apr_filepath_root(&newpath, &dir, 0, p) != APR_SUCCESS + || strncmp(newpath, ourdir, strlen(newpath)) != 0) { + return 0; + } + return 1; +} + +AP_DECLARE(int) ap_is_matchexp(const char *str) +{ + register int x; + + for (x = 0; str[x]; x++) + if ((str[x] == '*') || (str[x] == '?')) + return 1; + return 0; +} + +/* + * Here's a pool-based interface to the POSIX-esque ap_regcomp(). + * Note that we return ap_regex_t instead of being passed one. + * The reason is that if you use an already-used ap_regex_t structure, + * the memory that you've already allocated gets forgotten, and + * regfree() doesn't clear it. So we don't allow it. + */ + +static apr_status_t regex_cleanup(void *preg) +{ + ap_regfree((ap_regex_t *) preg); + return APR_SUCCESS; +} + +AP_DECLARE(ap_regex_t *) ap_pregcomp(apr_pool_t *p, const char *pattern, + int cflags) +{ + ap_regex_t *preg = apr_palloc(p, sizeof *preg); + + if (ap_regcomp(preg, pattern, cflags)) { + return NULL; + } + + apr_pool_cleanup_register(p, (void *) preg, regex_cleanup, + apr_pool_cleanup_null); + + return preg; +} + +AP_DECLARE(void) ap_pregfree(apr_pool_t *p, ap_regex_t *reg) +{ + ap_regfree(reg); + apr_pool_cleanup_kill(p, (void *) reg, regex_cleanup); +} + +/* + * Similar to standard strstr() but we ignore case in this version. + * Based on the strstr() implementation further below. + */ +AP_DECLARE(char *) ap_strcasestr(const char *s1, const char *s2) +{ + char *p1, *p2; + if (*s2 == '\0') { + /* an empty s2 */ + return((char *)s1); + } + while(1) { + for ( ; (*s1 != '\0') && (apr_tolower(*s1) != apr_tolower(*s2)); s1++); + if (*s1 == '\0') { + return(NULL); + } + /* found first character of s2, see if the rest matches */ + p1 = (char *)s1; + p2 = (char *)s2; + for (++p1, ++p2; apr_tolower(*p1) == apr_tolower(*p2); ++p1, ++p2) { + if (*p1 == '\0') { + /* both strings ended together */ + return((char *)s1); + } + } + if (*p2 == '\0') { + /* second string ended, a match */ + break; + } + /* didn't find a match here, try starting at next character in s1 */ + s1++; + } + return((char *)s1); +} + +/* + * Returns an offsetted pointer in bigstring immediately after + * prefix. Returns bigstring if bigstring doesn't start with + * prefix or if prefix is longer than bigstring while still matching. + * NOTE: pointer returned is relative to bigstring, so we + * can use standard pointer comparisons in the calling function + * (eg: test if ap_stripprefix(a,b) == a) + */ +AP_DECLARE(const char *) ap_stripprefix(const char *bigstring, + const char *prefix) +{ + const char *p1; + + if (*prefix == '\0') + return bigstring; + + p1 = bigstring; + while (*p1 && *prefix) { + if (*p1++ != *prefix++) + return bigstring; + } + if (*prefix == '\0') + return p1; + + /* hit the end of bigstring! */ + return bigstring; +} + +/* This function substitutes for $0-$9, filling in regular expression + * submatches. Pass it the same nmatch and pmatch arguments that you + * passed ap_regexec(). pmatch should not be greater than the maximum number + * of subexpressions - i.e. one more than the re_nsub member of ap_regex_t. + * + * input should be the string with the $-expressions, source should be the + * string that was matched against. + * + * It returns the substituted string, or NULL on error. + * + * Parts of this code are based on Henry Spencer's regsub(), from his + * AT&T V8 regexp package. + */ + +AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input, + const char *source, size_t nmatch, + ap_regmatch_t pmatch[]) +{ + const char *src = input; + char *dest, *dst; + char c; + size_t no; + int len; + + if (!source) + return NULL; + if (!nmatch) + return apr_pstrdup(p, src); + + /* First pass, find the size */ + + len = 0; + + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '$' && apr_isdigit(*src)) + no = *src++ - '0'; + else + no = 10; + + if (no > 9) { /* Ordinary character. */ + if (c == '\\' && (*src == '$' || *src == '&')) + c = *src++; + len++; + } + else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { + len += pmatch[no].rm_eo - pmatch[no].rm_so; + } + + } + + dest = dst = apr_pcalloc(p, len + 1); + + /* Now actually fill in the string */ + + src = input; + + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '$' && apr_isdigit(*src)) + no = *src++ - '0'; + else + no = 10; + + if (no > 9) { /* Ordinary character. */ + if (c == '\\' && (*src == '$' || *src == '&')) + c = *src++; + *dst++ = c; + } + else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { + len = pmatch[no].rm_eo - pmatch[no].rm_so; + memcpy(dst, source + pmatch[no].rm_so, len); + dst += len; + } + + } + *dst = '\0'; + + return dest; +} + +/* + * Parse .. so we don't compromise security + */ +AP_DECLARE(void) ap_getparents(char *name) +{ + char *next; + int l, w, first_dot; + + /* Four paseses, as per RFC 1808 */ + /* a) remove ./ path segments */ + for (next = name; *next && (*next != '.'); next++) { + } + + l = w = first_dot = next - name; + while (name[l] != '\0') { + if (name[l] == '.' && IS_SLASH(name[l + 1]) + && (l == 0 || IS_SLASH(name[l - 1]))) + l += 2; + else + name[w++] = name[l++]; + } + + /* b) remove trailing . path, segment */ + if (w == 1 && name[0] == '.') + w--; + else if (w > 1 && name[w - 1] == '.' && IS_SLASH(name[w - 2])) + w--; + name[w] = '\0'; + + /* c) remove all xx/../ segments. (including leading ../ and /../) */ + l = first_dot; + + while (name[l] != '\0') { + if (name[l] == '.' && name[l + 1] == '.' && IS_SLASH(name[l + 2]) + && (l == 0 || IS_SLASH(name[l - 1]))) { + register int m = l + 3, n; + + l = l - 2; + if (l >= 0) { + while (l >= 0 && !IS_SLASH(name[l])) + l--; + l++; + } + else + l = 0; + n = l; + while ((name[n] = name[m])) + (++n, ++m); + } + else + ++l; + } + + /* d) remove trailing xx/.. segment. */ + if (l == 2 && name[0] == '.' && name[1] == '.') + name[0] = '\0'; + else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' + && IS_SLASH(name[l - 3])) { + l = l - 4; + if (l >= 0) { + while (l >= 0 && !IS_SLASH(name[l])) + l--; + l++; + } + else + l = 0; + name[l] = '\0'; + } +} + +AP_DECLARE(void) ap_no2slash(char *name) +{ + char *d, *s; + + s = d = name; + +#ifdef HAVE_UNC_PATHS + /* Check for UNC names. Leave leading two slashes. */ + if (s[0] == '/' && s[1] == '/') + *d++ = *s++; +#endif + + while (*s) { + if ((*d++ = *s) == '/') { + do { + ++s; + } while (*s == '/'); + } + else { + ++s; + } + } + *d = '\0'; +} + + +/* + * copy at most n leading directories of s into d + * d should be at least as large as s plus 1 extra byte + * assumes n > 0 + * the return value is the ever useful pointer to the trailing \0 of d + * + * MODIFIED FOR HAVE_DRIVE_LETTERS and NETWARE environments, + * so that if n == 0, "/" is returned in d with n == 1 + * and s == "e:/test.html", "e:/" is returned in d + * *** See also directory_walk in modules/http/http_request.c + + * examples: + * /a/b, 0 ==> / (true for all platforms) + * /a/b, 1 ==> / + * /a/b, 2 ==> /a/ + * /a/b, 3 ==> /a/b/ + * /a/b, 4 ==> /a/b/ + * + * c:/a/b 0 ==> / + * c:/a/b 1 ==> c:/ + * c:/a/b 2 ==> c:/a/ + * c:/a/b 3 ==> c:/a/b + * c:/a/b 4 ==> c:/a/b + */ +AP_DECLARE(char *) ap_make_dirstr_prefix(char *d, const char *s, int n) +{ + if (n < 1) { + *d = '/'; + *++d = '\0'; + return (d); + } + + for (;;) { + if (*s == '\0' || (*s == '/' && (--n) == 0)) { + *d = '/'; + break; + } + *d++ = *s++; + } + *++d = 0; + return (d); +} + + +/* + * return the parent directory name including trailing / of the file s + */ +AP_DECLARE(char *) ap_make_dirstr_parent(apr_pool_t *p, const char *s) +{ + const char *last_slash = ap_strrchr_c(s, '/'); + char *d; + int l; + + if (last_slash == NULL) { + return apr_pstrdup(p, ""); + } + l = (last_slash - s) + 1; + d = apr_palloc(p, l + 1); + memcpy(d, s, l); + d[l] = 0; + return (d); +} + + +AP_DECLARE(int) ap_count_dirs(const char *path) +{ + register int x, n; + + for (x = 0, n = 0; path[x]; x++) + if (path[x] == '/') + n++; + return n; +} + +AP_DECLARE(char *) ap_getword_nc(apr_pool_t *atrans, char **line, char stop) +{ + return ap_getword(atrans, (const char **) line, stop); +} + +AP_DECLARE(char *) ap_getword(apr_pool_t *atrans, const char **line, char stop) +{ + const char *pos = *line; + int len; + char *res; + + while ((*pos != stop) && *pos) { + ++pos; + } + + len = pos - *line; + res = (char *)apr_palloc(atrans, len + 1); + memcpy(res, *line, len); + res[len] = 0; + + if (stop) { + while (*pos == stop) { + ++pos; + } + } + *line = pos; + + return res; +} + +AP_DECLARE(char *) ap_getword_white_nc(apr_pool_t *atrans, char **line) +{ + return ap_getword_white(atrans, (const char **) line); +} + +AP_DECLARE(char *) ap_getword_white(apr_pool_t *atrans, const char **line) +{ + const char *pos = *line; + int len; + char *res; + + while (!apr_isspace(*pos) && *pos) { + ++pos; + } + + len = pos - *line; + res = (char *)apr_palloc(atrans, len + 1); + memcpy(res, *line, len); + res[len] = 0; + + while (apr_isspace(*pos)) { + ++pos; + } + + *line = pos; + + return res; +} + +AP_DECLARE(char *) ap_getword_nulls_nc(apr_pool_t *atrans, char **line, + char stop) +{ + return ap_getword_nulls(atrans, (const char **) line, stop); +} + +AP_DECLARE(char *) ap_getword_nulls(apr_pool_t *atrans, const char **line, + char stop) +{ + const char *pos = ap_strchr_c(*line, stop); + char *res; + + if (!pos) { + res = apr_pstrdup(atrans, *line); + *line += strlen(*line); + return res; + } + + res = apr_pstrndup(atrans, *line, pos - *line); + + ++pos; + + *line = pos; + + return res; +} + +/* Get a word, (new) config-file style --- quoted strings and backslashes + * all honored + */ + +static char *substring_conf(apr_pool_t *p, const char *start, int len, + char quote) +{ + char *result = apr_palloc(p, len + 2); + char *resp = result; + int i; + + for (i = 0; i < len; ++i) { + if (start[i] == '\\' && (start[i + 1] == '\\' + || (quote && start[i + 1] == quote))) + *resp++ = start[++i]; + else + *resp++ = start[i]; + } + + *resp++ = '\0'; +#if RESOLVE_ENV_PER_TOKEN + return (char *)ap_resolve_env(p,result); +#else + return result; +#endif +} + +AP_DECLARE(char *) ap_getword_conf_nc(apr_pool_t *p, char **line) +{ + return ap_getword_conf(p, (const char **) line); +} + +AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line) +{ + const char *str = *line, *strend; + char *res; + char quote; + + while (*str && apr_isspace(*str)) + ++str; + + if (!*str) { + *line = str; + return ""; + } + + if ((quote = *str) == '"' || quote == '\'') { + strend = str + 1; + while (*strend && *strend != quote) { + if (*strend == '\\' && strend[1] && + (strend[1] == quote || strend[1] == '\\')) { + strend += 2; + } + else { + ++strend; + } + } + res = substring_conf(p, str + 1, strend - str - 1, quote); + + if (*strend == quote) + ++strend; + } + else { + strend = str; + while (*strend && !apr_isspace(*strend)) + ++strend; + + res = substring_conf(p, str, strend - str, 0); + } + + while (*strend && apr_isspace(*strend)) + ++strend; + *line = strend; + return res; +} + +/* Check a string for any ${ENV} environment variable + * construct and replace each them by the value of + * that environment variable, if it exists. If the + * environment value does not exist, leave the ${ENV} + * construct alone; it means something else. + */ +AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word) +{ +# define SMALL_EXPANSION 5 + struct sll { + struct sll *next; + const char *string; + apr_size_t len; + } *result, *current, sresult[SMALL_EXPANSION]; + char *res_buf, *cp; + const char *s, *e, *ep; + unsigned spc; + apr_size_t outlen; + + s = ap_strchr_c(word, '$'); + if (!s) { + return word; + } + + /* well, actually something to do */ + ep = word + strlen(word); + spc = 0; + result = current = &(sresult[spc++]); + current->next = NULL; + current->string = word; + current->len = s - word; + outlen = current->len; + + do { + /* prepare next entry */ + if (current->len) { + current->next = (spc < SMALL_EXPANSION) + ? &(sresult[spc++]) + : (struct sll *)apr_palloc(p, + sizeof(*current->next)); + current = current->next; + current->next = NULL; + current->len = 0; + } + + if (*s == '$') { + if (s[1] == '{' && (e = ap_strchr_c(s, '}'))) { + word = getenv(apr_pstrndup(p, s+2, e-s-2)); + if (word) { + current->string = word; + current->len = strlen(word); + outlen += current->len; + } + else { + current->string = s; + current->len = e - s + 1; + outlen += current->len; + } + s = e + 1; + } + else { + current->string = s++; + current->len = 1; + ++outlen; + } + } + else { + word = s; + s = ap_strchr_c(s, '$'); + current->string = word; + current->len = s ? s - word : ep - word; + outlen += current->len; + } + } while (s && *s); + + /* assemble result */ + res_buf = cp = apr_palloc(p, outlen + 1); + do { + if (result->len) { + memcpy(cp, result->string, result->len); + cp += result->len; + } + result = result->next; + } while (result); + res_buf[outlen] = '\0'; + + return res_buf; +} + +AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp) +{ +#ifdef DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "Done with config file %s", cfp->name); +#endif + return (cfp->close == NULL) ? 0 : cfp->close(cfp->param); +} + +static apr_status_t cfg_close(void *param) +{ + apr_file_t *cfp = (apr_file_t *) param; + return (apr_file_close(cfp)); +} + +static int cfg_getch(void *param) +{ + char ch; + apr_file_t *cfp = (apr_file_t *) param; + if (apr_file_getc(&ch, cfp) == APR_SUCCESS) + return ch; + return (int)EOF; +} + +static void *cfg_getstr(void *buf, size_t bufsiz, void *param) +{ + apr_file_t *cfp = (apr_file_t *) param; + apr_status_t rv; + rv = apr_file_gets(buf, bufsiz, cfp); + if (rv == APR_SUCCESS) { + return buf; + } + return NULL; +} + +/* Open a ap_configfile_t as FILE, return open ap_configfile_t struct pointer */ +AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg, + apr_pool_t *p, const char *name) +{ + ap_configfile_t *new_cfg; + apr_file_t *file = NULL; + apr_finfo_t finfo; + apr_status_t status; +#ifdef DEBUG + char buf[120]; +#endif + + if (name == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Internal error: pcfg_openfile() called with NULL filename"); + return APR_EBADF; + } + + status = apr_file_open(&file, name, APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, p); +#ifdef DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "Opening config file %s (%s)", + name, (status != APR_SUCCESS) ? + apr_strerror(status, buf, sizeof(buf)) : "successful"); +#endif + if (status != APR_SUCCESS) + return status; + + status = apr_file_info_get(&finfo, APR_FINFO_TYPE, file); + if (status != APR_SUCCESS) + return status; + + if (finfo.filetype != APR_REG && +#if defined(WIN32) || defined(OS2) || defined(NETWARE) + strcasecmp(apr_filepath_name_get(name), "nul") != 0) { +#else + strcmp(name, "/dev/null") != 0) { +#endif /* WIN32 || OS2 */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Access to file %s denied by server: not a regular file", + name); + apr_file_close(file); + return APR_EBADF; + } + +#ifdef WIN32 + /* Some twisted character [no pun intended] at MS decided that a + * zero width joiner as the lead wide character would be ideal for + * describing Unicode text files. This was further convoluted to + * another MSism that the same character mapped into utf-8, EF BB BF + * would signify utf-8 text files. + * + * Since MS configuration files are all protecting utf-8 encoded + * Unicode path, file and resource names, we already have the correct + * WinNT encoding. But at least eat the stupid three bytes up front. + */ + { + unsigned char buf[4]; + apr_size_t len = 3; + status = apr_file_read(file, buf, &len); + if ((status != APR_SUCCESS) || (len < 3) + || memcmp(buf, "\xEF\xBB\xBF", 3) != 0) { + apr_off_t zero = 0; + apr_file_seek(file, APR_SET, &zero); + } + } +#endif + + new_cfg = apr_palloc(p, sizeof(*new_cfg)); + new_cfg->param = file; + new_cfg->name = apr_pstrdup(p, name); + new_cfg->getch = (int (*)(void *)) cfg_getch; + new_cfg->getstr = (void *(*)(void *, size_t, void *)) cfg_getstr; + new_cfg->close = (int (*)(void *)) cfg_close; + new_cfg->line_number = 0; + *ret_cfg = new_cfg; + return APR_SUCCESS; +} + + +/* Allocate a ap_configfile_t handle with user defined functions and params */ +AP_DECLARE(ap_configfile_t *) ap_pcfg_open_custom(apr_pool_t *p, + const char *descr, + void *param, + int(*getch)(void *param), + void *(*getstr) (void *buf, size_t bufsiz, void *param), + int(*close_func)(void *param)) +{ + ap_configfile_t *new_cfg = apr_palloc(p, sizeof(*new_cfg)); +#ifdef DEBUG + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "Opening config handler %s", descr); +#endif + new_cfg->param = param; + new_cfg->name = descr; + new_cfg->getch = getch; + new_cfg->getstr = getstr; + new_cfg->close = close_func; + new_cfg->line_number = 0; + return new_cfg; +} + +/* Read one character from a configfile_t */ +AP_DECLARE(int) ap_cfg_getc(ap_configfile_t *cfp) +{ + register int ch = cfp->getch(cfp->param); + if (ch == LF) + ++cfp->line_number; + return ch; +} + +/* Read one line from open ap_configfile_t, strip LF, increase line number */ +/* If custom handler does not define a getstr() function, read char by char */ +AP_DECLARE(int) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp) +{ + /* If a "get string" function is defined, use it */ + if (cfp->getstr != NULL) { + char *src, *dst; + char *cp; + char *cbuf = buf; + size_t cbufsize = bufsize; + + while (1) { + ++cfp->line_number; + if (cfp->getstr(cbuf, cbufsize, cfp->param) == NULL) + return 1; + + /* + * check for line continuation, + * i.e. match [^\\]\\[\r]\n only + */ + cp = cbuf; + while (cp < cbuf+cbufsize && *cp != '\0') + cp++; + if (cp > cbuf && cp[-1] == LF) { + cp--; + if (cp > cbuf && cp[-1] == CR) + cp--; + if (cp > cbuf && cp[-1] == '\\') { + cp--; + if (!(cp > cbuf && cp[-1] == '\\')) { + /* + * line continuation requested - + * then remove backslash and continue + */ + cbufsize -= (cp-cbuf); + cbuf = cp; + continue; + } + else { + /* + * no real continuation because escaped - + * then just remove escape character + */ + for ( ; cp < cbuf+cbufsize && *cp != '\0'; cp++) + cp[0] = cp[1]; + } + } + } + break; + } + + /* + * Leading and trailing white space is eliminated completely + */ + src = buf; + while (apr_isspace(*src)) + ++src; + /* blast trailing whitespace */ + dst = &src[strlen(src)]; + while (--dst >= src && apr_isspace(*dst)) + *dst = '\0'; + /* Zap leading whitespace by shifting */ + if (src != buf) + for (dst = buf; (*dst++ = *src++) != '\0'; ) + ; + +#ifdef DEBUG_CFG_LINES + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "Read config: %s", buf); +#endif + return 0; + } else { + /* No "get string" function defined; read character by character */ + register int c; + register size_t i = 0; + + buf[0] = '\0'; + /* skip leading whitespace */ + do { + c = cfp->getch(cfp->param); + } while (c == '\t' || c == ' '); + + if (c == EOF) + return 1; + + if(bufsize < 2) { + /* too small, assume caller is crazy */ + return 1; + } + + while (1) { + if ((c == '\t') || (c == ' ')) { + buf[i++] = ' '; + while ((c == '\t') || (c == ' ')) + c = cfp->getch(cfp->param); + } + if (c == CR) { + /* silently ignore CR (_assume_ that a LF follows) */ + c = cfp->getch(cfp->param); + } + if (c == LF) { + /* increase line number and return on LF */ + ++cfp->line_number; + } + if (c == EOF || c == 0x4 || c == LF || i >= (bufsize - 2)) { + /* + * check for line continuation + */ + if (i > 0 && buf[i-1] == '\\') { + i--; + if (!(i > 0 && buf[i-1] == '\\')) { + /* line is continued */ + c = cfp->getch(cfp->param); + continue; + } + /* else nothing needs be done because + * then the backslash is escaped and + * we just strip to a single one + */ + } + /* blast trailing whitespace */ + while (i > 0 && apr_isspace(buf[i - 1])) + --i; + buf[i] = '\0'; +#ifdef DEBUG_CFG_LINES + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "Read config: %s", buf); +#endif + return 0; + } + buf[i] = c; + ++i; + c = cfp->getch(cfp->param); + } + } +} + +/* 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. + */ +AP_DECLARE(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 == ',' || apr_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 = (const char *)ptr; + return NULL; + } + + /* Advance field pointer to the next non-comma, non-white byte */ + + while (*ptr == ',' || apr_isspace(*ptr)) + ++ptr; + + *field = (const char *)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. + */ +AP_DECLARE(char *) ap_get_list_item(apr_pool_t *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 = apr_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 + : apr_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. + */ +AP_DECLARE(int) ap_find_list_item(apr_pool_t *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 == ',' || apr_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++ == apr_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 + * by whitespace at the caller's option. + */ + +AP_DECLARE(char *) ap_get_token(apr_pool_t *p, const char **accept_line, + int accept_white) +{ + const char *ptr = *accept_line; + const char *tok_start; + char *token; + int tok_len; + + /* Find first non-white byte */ + + while (*ptr && apr_isspace(*ptr)) + ++ptr; + + tok_start = ptr; + + /* find token end, skipping over quoted strings. + * (comments are already gone). + */ + + while (*ptr && (accept_white || !apr_isspace(*ptr)) + && *ptr != ';' && *ptr != ',') { + if (*ptr++ == '"') + while (*ptr) + if (*ptr++ == '"') + break; + } + + tok_len = ptr - tok_start; + token = apr_pstrndup(p, tok_start, tok_len); + + /* Advance accept_line pointer to the next non-white byte */ + + while (*ptr && apr_isspace(*ptr)) + ++ptr; + + *accept_line = ptr; + return token; +} + + +/* find http tokens, see the definition of token from RFC2068 */ +AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok) +{ + const unsigned char *start_token; + const unsigned char *s; + + 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_TOKEN_STOP)) { + ++s; + } + if (!*s) { + return 0; + } + start_token = s; + /* find end of the token */ + while (*s && !TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { + ++s; + } + if (!strncasecmp((const char *)start_token, (const char *)tok, + s - start_token)) { + return 1; + } + if (!*s) { + return 0; + } + } +} + + +AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line, + const char *tok) +{ + int llen, tlen, lidx; + + if (!line) + return 0; + + llen = strlen(line); + tlen = strlen(tok); + lidx = llen - tlen; + + if (lidx < 0 || + (lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ','))) + return 0; + + return (strncasecmp(&line[lidx], tok, tlen) == 0); +} + +AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *str) +{ + char *cmd; + unsigned char *d; + const unsigned char *s; + + cmd = apr_palloc(p, 2 * strlen(str) + 1); /* Be safe */ + d = (unsigned char *)cmd; + s = (const unsigned char *)str; + for (; *s; ++s) { + +#if defined(OS2) || defined(WIN32) + /* + * Newlines to Win32/OS2 CreateProcess() are ill advised. + * Convert them to spaces since they are effectively white + * space to most applications + */ + if (*s == '\r' || *s == '\n') { + *d++ = ' '; + continue; + } +#endif + + if (TEST_CHAR(*s, T_ESCAPE_SHELL_CMD)) { + *d++ = '\\'; + } + *d++ = *s; + } + *d = '\0'; + + return cmd; +} + +static char x2c(const char *what) +{ + register char digit; + +#if !APR_CHARSET_EBCDIC + digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 + : (what[0] - '0')); + digit *= 16; + digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 + : (what[1] - '0')); +#else /*APR_CHARSET_EBCDIC*/ + char xstr[5]; + xstr[0]='0'; + xstr[1]='x'; + xstr[2]=what[0]; + xstr[3]=what[1]; + xstr[4]='\0'; + digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, + 0xFF & strtol(xstr, NULL, 16)); +#endif /*APR_CHARSET_EBCDIC*/ + return (digit); +} + +/* + * Unescapes a URL. + * Returns 0 on success, non-zero on error + * Failure is due to + * bad % escape returns HTTP_BAD_REQUEST + * + * decoding %00 -> \0 (the null character) + * decoding %2f -> / (a special character) + * returns HTTP_NOT_FOUND + */ +AP_DECLARE(int) ap_unescape_url(char *url) +{ + register int badesc, badpath; + char *x, *y; + + badesc = 0; + badpath = 0; + /* Initial scan for first '%'. Don't bother writing values before + * seeing a '%' */ + y = strchr(url, '%'); + if (y == NULL) { + return OK; + } + for (x = y; *y; ++x, ++y) { + if (*y != '%') + *x = *y; + else { + if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { + badesc = 1; + *x = '%'; + } + else { + *x = x2c(y + 1); + y += 2; + if (IS_SLASH(*x) || *x == '\0') + badpath = 1; + } + } + } + *x = '\0'; + if (badesc) + return HTTP_BAD_REQUEST; + else if (badpath) + return HTTP_NOT_FOUND; + else + return OK; +} + +AP_DECLARE(int) ap_unescape_url_keep2f(char *url) +{ + register int badesc, badpath; + char *x, *y; + + badesc = 0; + badpath = 0; + /* Initial scan for first '%'. Don't bother writing values before + * seeing a '%' */ + y = strchr(url, '%'); + if (y == NULL) { + return OK; + } + for (x = y; *y; ++x, ++y) { + if (*y != '%') { + *x = *y; + } + else { + if (!apr_isxdigit(*(y + 1)) || !apr_isxdigit(*(y + 2))) { + badesc = 1; + *x = '%'; + } + else { + char decoded; + decoded = x2c(y + 1); + if (decoded == '\0') { + badpath = 1; + } + else { + *x = decoded; + y += 2; + } + } + } + } + *x = '\0'; + if (badesc) { + return HTTP_BAD_REQUEST; + } + else if (badpath) { + return HTTP_NOT_FOUND; + } + else { + return OK; + } +} + +AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname, + apr_port_t port, const request_rec *r) +{ + if (ap_is_default_port(port, r)) { + return apr_pstrdup(p, hostname); + } + else { + return apr_psprintf(p, "%s:%u", hostname, port); + } +} + +/* c2x takes an unsigned, and expects the caller has guaranteed that + * 0 <= what < 256... which usually means that you have to cast to + * unsigned char first, because (unsigned)(char)(x) first goes through + * signed extension to an int before the unsigned cast. + * + * The reason for this assumption is to assist gcc code generation -- + * the unsigned char -> unsigned extension is already done earlier in + * both uses of this code, so there's no need to waste time doing it + * again. + */ +static const char c2x_table[] = "0123456789abcdef"; + +static APR_INLINE unsigned char *c2x(unsigned what, unsigned char *where) +{ +#if APR_CHARSET_EBCDIC + what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what); +#endif /*APR_CHARSET_EBCDIC*/ + *where++ = '%'; + *where++ = c2x_table[what >> 4]; + *where++ = c2x_table[what & 0xf]; + return where; +} + +/* + * escape_path_segment() escapes a path segment, as defined in RFC 1808. This + * routine is (should be) OS independent. + * + * os_escape_path() converts an OS path to a URL, in an OS dependent way. In all + * cases if a ':' occurs before the first '/' in the URL, the URL should be + * prefixed with "./" (or the ':' escaped). In the case of Unix, this means + * leaving '/' alone, but otherwise doing what escape_path_segment() does. For + * efficiency reasons, we don't use escape_path_segment(), which is provided for + * reference. Again, RFC 1808 is where this stuff is defined. + * + * If partial is set, os_escape_path() assumes that the path will be appended to + * something with a '/' in it (and thus does not prefix "./"). + */ + +AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *segment) +{ + char *copy = apr_palloc(p, 3 * strlen(segment) + 1); + const unsigned char *s = (const unsigned char *)segment; + unsigned char *d = (unsigned char *)copy; + unsigned c; + + while ((c = *s)) { + if (TEST_CHAR(c, T_ESCAPE_PATH_SEGMENT)) { + d = c2x(c, d); + } + else { + *d++ = c; + } + ++s; + } + *d = '\0'; + return copy; +} + +AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial) +{ + char *copy = apr_palloc(p, 3 * strlen(path) + 3); + const unsigned char *s = (const unsigned char *)path; + unsigned char *d = (unsigned char *)copy; + unsigned c; + + if (!partial) { + const char *colon = ap_strchr_c(path, ':'); + const char *slash = ap_strchr_c(path, '/'); + + if (colon && (!slash || colon < slash)) { + *d++ = '.'; + *d++ = '/'; + } + } + while ((c = *s)) { + if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) { + d = c2x(c, d); + } + else { + *d++ = c; + } + ++s; + } + *d = '\0'; + return copy; +} + +/* ap_escape_uri is now a macro for os_escape_path */ + +AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s) +{ + int i, j; + char *x; + + /* first, count the number of extra characters */ + for (i = 0, j = 0; s[i] != '\0'; i++) + if (s[i] == '<' || s[i] == '>') + j += 3; + else if (s[i] == '&') + j += 4; + + if (j == 0) + return apr_pstrmemdup(p, s, i); + + x = apr_palloc(p, i + j + 1); + for (i = 0, j = 0; s[i] != '\0'; i++, j++) + if (s[i] == '<') { + memcpy(&x[j], "<", 4); + j += 3; + } + else if (s[i] == '>') { + memcpy(&x[j], ">", 4); + j += 3; + } + else if (s[i] == '&') { + memcpy(&x[j], "&", 5); + j += 4; + } + else + x[j] = s[i]; + + x[j] = '\0'; + return x; +} + +AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str) +{ + char *ret; + unsigned char *d; + const unsigned char *s; + + if (!str) { + return NULL; + } + + ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */ + d = (unsigned char *)ret; + s = (const unsigned char *)str; + for (; *s; ++s) { + + if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) { + *d++ = '\\'; + switch(*s) { + case '\b': + *d++ = 'b'; + break; + case '\n': + *d++ = 'n'; + break; + case '\r': + *d++ = 'r'; + break; + case '\t': + *d++ = 't'; + break; + case '\v': + *d++ = 'v'; + break; + case '\\': + case '"': + *d++ = *s; + break; + default: + c2x(*s, d); + *d = 'x'; + d += 3; + } + } + else { + *d++ = *s; + } + } + *d = '\0'; + + return ret; +} + +AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source, + apr_size_t buflen) +{ + unsigned char *d, *ep; + const unsigned char *s; + + if (!source || !buflen) { /* be safe */ + return 0; + } + + d = (unsigned char *)dest; + s = (const unsigned char *)source; + ep = d + buflen - 1; + + for (; d < ep && *s; ++s) { + + if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) { + *d++ = '\\'; + if (d >= ep) { + --d; + break; + } + + switch(*s) { + case '\b': + *d++ = 'b'; + break; + case '\n': + *d++ = 'n'; + break; + case '\r': + *d++ = 'r'; + break; + case '\t': + *d++ = 't'; + break; + case '\v': + *d++ = 'v'; + break; + case '\\': + *d++ = *s; + break; + case '"': /* no need for this in error log */ + d[-1] = *s; + break; + default: + if (d >= ep - 2) { + ep = --d; /* break the for loop as well */ + break; + } + c2x(*s, d); + *d = 'x'; + d += 3; + } + } + else { + *d++ = *s; + } + } + *d = '\0'; + + return (d - (unsigned char *)dest); +} + +AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path) +{ + apr_finfo_t finfo; + + if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) + return 0; /* in error condition, just return no */ + + return (finfo.filetype == APR_DIR); +} + +AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *path) +{ + apr_finfo_t finfo; + + if (apr_stat(&finfo, path, APR_FINFO_LINK | APR_FINFO_TYPE, p) != APR_SUCCESS) + return 0; /* in error condition, just return no */ + + return (finfo.filetype == APR_DIR); +} + +AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *src1, + const char *src2) +{ + apr_size_t len1, len2; + char *path; + + len1 = strlen(src1); + len2 = strlen(src2); + /* allocate +3 for '/' delimiter, trailing NULL and overallocate + * one extra byte to allow the caller to add a trailing '/' + */ + path = (char *)apr_palloc(a, len1 + len2 + 3); + if (len1 == 0) { + *path = '/'; + memcpy(path + 1, src2, len2 + 1); + } + else { + char *next; + memcpy(path, src1, len1); + next = path + len1; + if (next[-1] != '/') { + *next++ = '/'; + } + memcpy(next, src2, len2 + 1); + } + return path; +} + +/* + * Check for an absoluteURI syntax (see section 3.2 in RFC2068). + */ +AP_DECLARE(int) ap_is_url(const char *u) +{ + register int x; + + for (x = 0; u[x] != ':'; x++) { + if ((!u[x]) || + ((!apr_isalpha(u[x])) && (!apr_isdigit(u[x])) && + (u[x] != '+') && (u[x] != '-') && (u[x] != '.'))) { + return 0; + } + } + + return (x ? 1 : 0); /* If the first character is ':', it's broken, too */ +} + +AP_DECLARE(int) ap_ind(const char *s, char c) +{ + const char *p = ap_strchr_c(s, c); + + if (p == NULL) + return -1; + return p - s; +} + +AP_DECLARE(int) ap_rind(const char *s, char c) +{ + const char *p = ap_strrchr_c(s, c); + + if (p == NULL) + return -1; + return p - s; +} + +AP_DECLARE(void) ap_str_tolower(char *str) +{ + while (*str) { + *str = apr_tolower(*str); + ++str; + } +} + +/* + * We must return a FQDN + */ +char *ap_get_local_host(apr_pool_t *a) +{ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + char str[MAXHOSTNAMELEN + 1]; + char *server_hostname = NULL; + apr_sockaddr_t *sockaddr; + char *hostname; + + if (apr_gethostname(str, sizeof(str) - 1, a) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_STARTUP | APLOG_WARNING, 0, a, + "%s: apr_gethostname() failed to determine ServerName", + ap_server_argv0); + } else { + str[sizeof(str) - 1] = '\0'; + if (apr_sockaddr_info_get(&sockaddr, str, APR_UNSPEC, 0, 0, a) == APR_SUCCESS) { + if ( (apr_getnameinfo(&hostname, sockaddr, 0) == APR_SUCCESS) && + (ap_strchr_c(hostname, '.')) ) { + server_hostname = apr_pstrdup(a, hostname); + return server_hostname; + } else if (ap_strchr_c(str, '.')) { + server_hostname = apr_pstrdup(a, str); + } else { + apr_sockaddr_ip_get(&hostname, sockaddr); + server_hostname = apr_pstrdup(a, hostname); + } + } else { + ap_log_perror(APLOG_MARK, APLOG_STARTUP | APLOG_WARNING, 0, a, + "%s: apr_sockaddr_info_get() failed for %s", + ap_server_argv0, str); + } + } + + if (!server_hostname) + server_hostname = apr_pstrdup(a, "127.0.0.1"); + + ap_log_perror(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, a, + "%s: Could not reliably determine the server's fully qualified " + "domain name, using %s for ServerName", + ap_server_argv0, server_hostname); + + return server_hostname; +} + +/* simple 'pool' alloc()ing glue to apr_base64.c + */ +AP_DECLARE(char *) ap_pbase64decode(apr_pool_t *p, const char *bufcoded) +{ + char *decoded; + int l; + + decoded = (char *) apr_palloc(p, 1 + apr_base64_decode_len(bufcoded)); + l = apr_base64_decode(decoded, bufcoded); + decoded[l] = '\0'; /* make binary sequence into string */ + + return decoded; +} + +AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string) +{ + char *encoded; + int l = strlen(string); + + encoded = (char *) apr_palloc(p, 1 + apr_base64_encode_len(l)); + l = apr_base64_encode(encoded, string, l); + encoded[l] = '\0'; /* make binary sequence into string */ + + return encoded; +} + +/* we want to downcase the type/subtype for comparison purposes + * but nothing else because ;parameter=foo values are case sensitive. + * XXX: in truth we want to downcase parameter names... but really, + * apache has never handled parameters and such correctly. You + * also need to compress spaces and such to be able to compare + * properly. -djg + */ +AP_DECLARE(void) ap_content_type_tolower(char *str) +{ + char *semi; + + semi = strchr(str, ';'); + if (semi) { + *semi = '\0'; + } + while (*str) { + *str = apr_tolower(*str); + ++str; + } + if (semi) { + *semi = ';'; + } +} + +/* + * Given a string, replace any bare " with \" . + */ +AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) +{ + int newlen = 0; + const char *inchr = instring; + char *outchr, *outstring; + + /* + * Look through the input string, jogging the length of the output + * string up by an extra byte each time we find an unescaped ". + */ + while (*inchr != '\0') { + newlen++; + if (*inchr == '"') { + newlen++; + } + /* + * If we find a slosh, and it's not the last byte in the string, + * it's escaping something - advance past both bytes. + */ + if ((*inchr == '\\') && (inchr[1] != '\0')) { + inchr++; + newlen++; + } + inchr++; + } + outstring = apr_palloc(p, newlen + 1); + inchr = instring; + outchr = outstring; + /* + * Now copy the input string to the output string, inserting a slosh + * in front of every " that doesn't already have one. + */ + while (*inchr != '\0') { + if ((*inchr == '\\') && (inchr[1] != '\0')) { + *outchr++ = *inchr++; + *outchr++ = *inchr++; + } + if (*inchr == '"') { + *outchr++ = '\\'; + } + if (*inchr != '\0') { + *outchr++ = *inchr++; + } + } + *outchr = '\0'; + return outstring; +} diff --git a/trunk/server/util_cfgtree.c b/trunk/server/util_cfgtree.c new file mode 100644 index 0000000000..b3bff04085 --- /dev/null +++ b/trunk/server/util_cfgtree.c @@ -0,0 +1,47 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CORE_PRIVATE +#include "util_cfgtree.h" +#include + +ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current, + ap_directive_t *toadd, int child) +{ + if (current == NULL) { + /* we just started a new parent */ + if (*parent != NULL) { + (*parent)->first_child = toadd; + toadd->parent = *parent; + } + if (child) { + /* First item in config file or container is a container */ + *parent = toadd; + return NULL; + } + return toadd; + } + current->next = toadd; + toadd->parent = *parent; + if (child) { + /* switch parents, navigate into child */ + *parent = toadd; + return NULL; + } + return toadd; +} + + diff --git a/trunk/server/util_charset.c b/trunk/server/util_charset.c new file mode 100644 index 0000000000..3be2a3922b --- /dev/null +++ b/trunk/server/util_charset.c @@ -0,0 +1,42 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" + +#if APR_CHARSET_EBCDIC + +#include "httpd.h" +#include "http_log.h" +#include "http_core.h" +#include "util_charset.h" + +/* ap_hdrs_to_ascii, ap_hdrs_from_ascii + * + * These are the translation handles used to translate between the network + * format of protocol headers and the local machine format. + * + * For an EBCDIC machine, these are valid handles which are set up at + * initialization to translate between ISO-8859-1 and the code page of + * the source code. + * + * For an ASCII machine, these remain NULL so that when they are stored + * in the BUFF via ap_bsetop(BO_RXLATE) it ensures that no translation is + * performed. + */ + +apr_xlate_t *ap_hdrs_to_ascii, *ap_hdrs_from_ascii; + +#endif /*APR_CHARSET_EBCDIC */ diff --git a/trunk/server/util_debug.c b/trunk/server/util_debug.c new file mode 100644 index 0000000000..7fbdc947cb --- /dev/null +++ b/trunk/server/util_debug.c @@ -0,0 +1,128 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "httpd.h" +#include "http_config.h" + +/* Possibly get rid of the macros we defined in httpd.h */ +#if defined(strchr) +#undef strchr +#endif + +#if defined (strrchr) +#undef strrchr +#endif + +#if defined (strstr) +#undef strstr +#endif + + +#if defined(ap_strchr) +#undef ap_strchr +AP_DECLARE(char *) ap_strchr(char *s, int c); +#endif + +AP_DECLARE(char *) ap_strchr(char *s, int c) +{ + return strchr(s,c); +} + +#if defined(ap_strchr_c) +#undef ap_strchr_c +AP_DECLARE(const char *) ap_strchr_c(const char *s, int c); +#endif + +AP_DECLARE(const char *) ap_strchr_c(const char *s, int c) +{ + return strchr(s,c); +} + +#if defined(ap_strrchr) +#undef ap_strrchr +AP_DECLARE(char *) ap_strrchr(char *s, int c); +#endif + +AP_DECLARE(char *) ap_strrchr(char *s, int c) +{ + return strrchr(s,c); +} + +#if defined(ap_strrchr_c) +#undef ap_strrchr_c +AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c); +#endif + +AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c) +{ + return strrchr(s,c); +} + +#if defined(ap_strstr) +#undef ap_strstr +AP_DECLARE(char *) ap_strstr(char *s, const char *c); +#endif + +AP_DECLARE(char *) ap_strstr(char *s, const char *c) +{ + return strstr(s,c); +} + +#if defined(ap_strstr_c) +#undef ap_strstr_c +AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c); +#endif + +AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c) +{ + return strstr(s,c); +} + +#if defined(ap_get_module_config) +#undef ap_get_module_config +AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, + const module *m); +#endif + +AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv, + const module *m) +{ + return ((void **)cv)[m->module_index]; +} + +/** + * Generic accessors for other modules to set at their own module-specific + * data + * @param conf_vector The vector in which the modules configuration is stored. + * usually r->per_dir_config or s->module_config + * @param m The module to set the data for. + * @param val The module-specific data to set + * @deffunc void ap_set_module_config(ap_conf_vector_t *cv, const module *m, void *val) + */ +#if defined(ap_set_module_config) +#undef ap_set_module_config +AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, + void *val); +#endif + +AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m, + void *val) +{ + ((void **)cv)[m->module_index] = val; +} diff --git a/trunk/server/util_ebcdic.c b/trunk/server/util_ebcdic.c new file mode 100644 index 0000000000..4062db051f --- /dev/null +++ b/trunk/server/util_ebcdic.c @@ -0,0 +1,112 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ap_config.h" + +#if APR_CHARSET_EBCDIC + +#include "apr_strings.h" +#include "httpd.h" +#include "http_log.h" +#include "http_core.h" +#include "util_ebcdic.h" + +apr_status_t ap_init_ebcdic(apr_pool_t *pool) +{ + apr_status_t rv; + char buf[80]; + + rv = apr_xlate_open(&ap_hdrs_to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, pool); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "apr_xlate_open() failed"); + return rv; + } + + rv = apr_xlate_open(&ap_hdrs_from_ascii, APR_DEFAULT_CHARSET, "ISO-8859-1", pool); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "apr_xlate_open() failed"); + return rv; + } + + rv = apr_MD5InitEBCDIC(ap_hdrs_to_ascii); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "apr_MD5InitEBCDIC() failed"); + return rv; + } + + rv = apr_base64init_ebcdic(ap_hdrs_to_ascii, ap_hdrs_from_ascii); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "apr_base64init_ebcdic() failed"); + return rv; + } + + rv = apr_SHA1InitEBCDIC(ap_hdrs_to_ascii); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "apr_SHA1InitEBCDIC() failed"); + return rv; + } + + return APR_SUCCESS; +} + +void ap_xlate_proto_to_ascii(char *buffer, apr_size_t len) +{ + apr_size_t inbytes_left, outbytes_left; + + inbytes_left = outbytes_left = len; + apr_xlate_conv_buffer(ap_hdrs_to_ascii, buffer, &inbytes_left, + buffer, &outbytes_left); +} + +void ap_xlate_proto_from_ascii(char *buffer, apr_size_t len) +{ + apr_size_t inbytes_left, outbytes_left; + + inbytes_left = outbytes_left = len; + apr_xlate_conv_buffer(ap_hdrs_from_ascii, buffer, &inbytes_left, + buffer, &outbytes_left); +} + +int ap_rvputs_proto_in_ascii(request_rec *r, ...) +{ + va_list va; + const char *s; + char *ascii_s; + apr_size_t len; + apr_size_t written = 0; + + va_start(va, r); + while (1) { + s = va_arg(va, const char *); + if (s == NULL) + break; + len = strlen(s); + ascii_s = apr_pstrndup(r->pool, s, len); + ap_xlate_proto_to_ascii(ascii_s, len); + if (ap_rputs(ascii_s, r) < 0) + return -1; + written += len; + } + va_end(va); + + return written; +} +#endif /* APR_CHARSET_EBCDIC */ diff --git a/trunk/server/util_filter.c b/trunk/server/util_filter.c new file mode 100644 index 0000000000..baeaf48d2a --- /dev/null +++ b/trunk/server/util_filter.c @@ -0,0 +1,622 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define APR_WANT_STRFUNC +#include "apr_want.h" +#include "apr_lib.h" +#include "apr_hash.h" +#include "apr_strings.h" + +#include "httpd.h" +#include "http_log.h" +#include "util_filter.h" + +/* NOTE: Apache's current design doesn't allow a pool to be passed thru, + so we depend on a global to hold the correct pool +*/ +#define FILTER_POOL apr_hook_global_pool +#include "apr_hooks.h" /* for apr_hook_global_pool */ + +/* +** This macro returns true/false if a given filter should be inserted BEFORE +** another filter. This will happen when one of: 1) there isn't another +** filter; 2) that filter has a higher filter type (class); 3) that filter +** corresponds to a different request. +*/ +#define INSERT_BEFORE(f, before_this) ((before_this) == NULL \ + || (before_this)->frec->ftype > (f)->frec->ftype \ + || (before_this)->r != (f)->r) + +/* Trie structure to hold the mapping from registered + * filter names to filters + */ + +typedef struct filter_trie_node filter_trie_node; + +typedef struct { + int c; + filter_trie_node *child; +} filter_trie_child_ptr; + +/* Each trie node has an array of pointers to its children. + * The array is kept in sorted order so that add_any_filter() + * can do a binary search + */ +struct filter_trie_node { + ap_filter_rec_t *frec; + filter_trie_child_ptr *children; + int nchildren; + int size; +}; + +#define TRIE_INITIAL_SIZE 4 + +/* Link a trie node to its parent + */ +static void trie_node_link(apr_pool_t *p, filter_trie_node *parent, + filter_trie_node *child, int c) +{ + int i, j; + + if (parent->nchildren == parent->size) { + filter_trie_child_ptr *new; + parent->size *= 2; + new = (filter_trie_child_ptr *)apr_palloc(p, parent->size * + sizeof(filter_trie_child_ptr)); + memcpy(new, parent->children, parent->nchildren * + sizeof(filter_trie_child_ptr)); + parent->children = new; + } + + for (i = 0; i < parent->nchildren; i++) { + if (c == parent->children[i].c) { + return; + } + else if (c < parent->children[i].c) { + break; + } + } + for (j = parent->nchildren; j > i; j--) { + parent->children[j].c = parent->children[j - 1].c; + parent->children[j].child = parent->children[j - 1].child; + } + parent->children[i].c = c; + parent->children[i].child = child; + + parent->nchildren++; +} + +/* Allocate a new node for a trie. + * If parent is non-NULL, link the new node under the parent node with + * key 'c' (or, if an existing child node matches, return that one) + */ +static filter_trie_node *trie_node_alloc(apr_pool_t *p, + filter_trie_node *parent, char c) +{ + filter_trie_node *new_node; + if (parent) { + int i; + for (i = 0; i < parent->nchildren; i++) { + if (c == parent->children[i].c) { + return parent->children[i].child; + } + else if (c < parent->children[i].c) { + break; + } + } + new_node = + (filter_trie_node *)apr_palloc(p, sizeof(filter_trie_node)); + trie_node_link(p, parent, new_node, c); + } + else { /* No parent node */ + new_node = (filter_trie_node *)apr_palloc(p, + sizeof(filter_trie_node)); + } + + new_node->frec = NULL; + new_node->nchildren = 0; + new_node->size = TRIE_INITIAL_SIZE; + new_node->children = (filter_trie_child_ptr *)apr_palloc(p, + new_node->size * sizeof(filter_trie_child_ptr)); + return new_node; +} + +static filter_trie_node *registered_output_filters = NULL; +static filter_trie_node *registered_input_filters = NULL; + + +static apr_status_t filter_cleanup(void *ctx) +{ + registered_output_filters = NULL; + registered_input_filters = NULL; + return APR_SUCCESS; +} + +static ap_filter_rec_t *get_filter_handle(const char *name, + const filter_trie_node *filter_set) +{ + if (filter_set) { + const char *n; + const filter_trie_node *node; + + node = filter_set; + for (n = name; *n; n++) { + int start, end; + start = 0; + end = node->nchildren - 1; + while (end >= start) { + int middle = (end + start) / 2; + char ch = node->children[middle].c; + if (*n == ch) { + node = node->children[middle].child; + break; + } + else if (*n < ch) { + end = middle - 1; + } + else { + start = middle + 1; + } + } + if (end < start) { + node = NULL; + break; + } + } + + if (node && node->frec) { + return node->frec; + } + } + return NULL; +} + +AP_DECLARE(ap_filter_rec_t *)ap_get_output_filter_handle(const char *name) +{ + return get_filter_handle(name, registered_output_filters); +} + +AP_DECLARE(ap_filter_rec_t *)ap_get_input_filter_handle(const char *name) +{ + return get_filter_handle(name, registered_input_filters); +} + +static ap_filter_rec_t *register_filter(const char *name, + ap_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype, + filter_trie_node **reg_filter_set) +{ + ap_filter_rec_t *frec; + char *normalized_name; + const char *n; + filter_trie_node *node; + + if (!*reg_filter_set) { + *reg_filter_set = trie_node_alloc(FILTER_POOL, NULL, 0); + } + + normalized_name = apr_pstrdup(FILTER_POOL, name); + ap_str_tolower(normalized_name); + + node = *reg_filter_set; + for (n = normalized_name; *n; n++) { + filter_trie_node *child = trie_node_alloc(FILTER_POOL, node, *n); + if (apr_isalpha(*n)) { + trie_node_link(FILTER_POOL, node, child, apr_toupper(*n)); + } + node = child; + } + if (node->frec) { + frec = node->frec; + } + else { + frec = apr_pcalloc(FILTER_POOL, sizeof(*frec)); + node->frec = frec; + frec->name = normalized_name; + } + frec->filter_func = filter_func; + frec->filter_init_func = filter_init; + frec->ftype = ftype; + + apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup, + apr_pool_cleanup_null); + return frec; +} + +AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name, + ap_in_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype) +{ + ap_filter_func f; + f.in_func = filter_func; + return register_filter(name, f, filter_init, ftype, + ®istered_input_filters); +} + +/* Prepare to make this a #define in 2.2 */ +AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name, + ap_out_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype) +{ + return ap_register_output_filter_protocol(name, filter_func, + filter_init, ftype, 0) ; +} +AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol( + const char *name, + ap_out_filter_func filter_func, + ap_init_filter_func filter_init, + ap_filter_type ftype, + unsigned int proto_flags) +{ + ap_filter_rec_t* ret ; + ap_filter_func f; + f.out_func = filter_func; + ret = register_filter(name, f, filter_init, ftype, + ®istered_output_filters); + ret->proto_flags = proto_flags ; + return ret ; +} + +static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx, + request_rec *r, conn_rec *c, + ap_filter_t **r_filters, + ap_filter_t **p_filters, + ap_filter_t **c_filters) +{ + apr_pool_t* p = r ? r->pool : c->pool; + ap_filter_t *f = apr_palloc(p, sizeof(*f)); + ap_filter_t **outf; + + if (frec->ftype < AP_FTYPE_PROTOCOL) { + if (r) { + outf = r_filters; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "a content filter was added without a request: %s", frec->name); + return NULL; + } + } + else if (frec->ftype < AP_FTYPE_CONNECTION) { + if (r) { + outf = p_filters; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "a protocol filter was added without a request: %s", frec->name); + return NULL; + } + } + else { + outf = c_filters; + } + + f->frec = frec; + f->ctx = ctx; + f->r = r; + f->c = c; + f->next = NULL; + + if (INSERT_BEFORE(f, *outf)) { + f->next = *outf; + + if (*outf) { + ap_filter_t *first = NULL; + + if (r) { + /* If we are adding our first non-connection filter, + * Then don't try to find the right location, it is + * automatically first. + */ + if (*r_filters != *c_filters) { + first = *r_filters; + while (first && (first->next != (*outf))) { + first = first->next; + } + } + } + if (first && first != (*outf)) { + first->next = f; + } + } + *outf = f; + } + else { + ap_filter_t *fscan = *outf; + while (!INSERT_BEFORE(f, fscan->next)) + fscan = fscan->next; + + f->next = fscan->next; + fscan->next = f; + } + + if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) { + *r_filters = *p_filters; + } + return f; +} + +static ap_filter_t *add_any_filter(const char *name, void *ctx, + request_rec *r, conn_rec *c, + const filter_trie_node *reg_filter_set, + ap_filter_t **r_filters, + ap_filter_t **p_filters, + ap_filter_t **c_filters) +{ + if (reg_filter_set) { + const char *n; + const filter_trie_node *node; + + node = reg_filter_set; + for (n = name; *n; n++) { + int start, end; + start = 0; + end = node->nchildren - 1; + while (end >= start) { + int middle = (end + start) / 2; + char ch = node->children[middle].c; + if (*n == ch) { + node = node->children[middle].child; + break; + } + else if (*n < ch) { + end = middle - 1; + } + else { + start = middle + 1; + } + } + if (end < start) { + node = NULL; + break; + } + } + + if (node && node->frec) { + return add_any_filter_handle(node->frec, ctx, r, c, r_filters, + p_filters, c_filters); + } + } + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "an unknown filter was not added: %s", name); + return NULL; +} + +AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, + request_rec *r, conn_rec *c) +{ + return add_any_filter(name, ctx, r, c, registered_input_filters, + r ? &r->input_filters : NULL, + r ? &r->proto_input_filters : NULL, &c->input_filters); +} + +AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c) +{ + return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL, + r ? &r->proto_input_filters : NULL, + &c->input_filters); +} + +AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, + request_rec *r, conn_rec *c) +{ + return add_any_filter(name, ctx, r, c, registered_output_filters, + r ? &r->output_filters : NULL, + r ? &r->proto_output_filters : NULL, &c->output_filters); +} + +AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, + void *ctx, + request_rec *r, + conn_rec *c) +{ + return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL, + r ? &r->proto_output_filters : NULL, + &c->output_filters); +} + +static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt, + ap_filter_t **c_filt) +{ + ap_filter_t **curr = r_filt ? r_filt : c_filt; + ap_filter_t *fscan = *curr; + + if (p_filt && *p_filt == f) + *p_filt = (*p_filt)->next; + + if (*curr == f) { + *curr = (*curr)->next; + return; + } + + while (fscan->next != f) { + if (!(fscan = fscan->next)) { + return; + } + } + + fscan->next = f->next; +} + +AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f) +{ + remove_any_filter(f, f->r ? &f->r->input_filters : NULL, + f->r ? &f->r->proto_input_filters : NULL, + &f->c->input_filters); +} + +AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f) +{ + remove_any_filter(f, f->r ? &f->r->output_filters : NULL, + f->r ? &f->r->proto_output_filters : NULL, + &f->c->output_filters); +} + +/* + * Read data from the next filter in the filter stack. Data should be + * modified in the bucket brigade that is passed in. The core allocates the + * bucket brigade, modules that wish to replace large chunks of data or to + * save data off to the side should probably create their own temporary + * brigade especially for that use. + */ +AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) +{ + if (next) { + return next->frec->filter_func.in_func(next, bb, mode, block, + readbytes); + } + return AP_NOBODY_READ; +} + +/* Pass the buckets to the next filter in the filter stack. If the + * current filter is a handler, we should get NULL passed in instead of + * the current filter. At that point, we can just call the first filter in + * the stack, or r->output_filters. + */ +AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *next, + apr_bucket_brigade *bb) +{ + if (next) { + apr_bucket *e; + if ((e = APR_BRIGADE_LAST(bb)) && APR_BUCKET_IS_EOS(e) && next->r) { + /* This is only safe because HTTP_HEADER filter is always in + * the filter stack. This ensures that there is ALWAYS a + * request-based filter that we can attach this to. If the + * HTTP_FILTER is removed, and another filter is not put in its + * place, then handlers like mod_cgi, which attach their own + * EOS bucket to the brigade will be broken, because we will + * get two EOS buckets on the same request. + */ + next->r->eos_sent = 1; + + /* remember the eos for internal redirects, too */ + if (next->r->prev) { + request_rec *prev = next->r->prev; + + while (prev) { + prev->eos_sent = 1; + prev = prev->prev; + } + } + } + return next->frec->filter_func.out_func(next, bb); + } + return AP_NOBODY_WROTE; +} + +AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, + apr_bucket_brigade **saveto, + apr_bucket_brigade **b, apr_pool_t *p) +{ + apr_bucket *e; + apr_status_t rv, srv = APR_SUCCESS; + + /* If have never stored any data in the filter, then we had better + * create an empty bucket brigade so that we can concat. + */ + if (!(*saveto)) { + *saveto = apr_brigade_create(p, f->c->bucket_alloc); + } + + for (e = APR_BRIGADE_FIRST(*b); + e != APR_BRIGADE_SENTINEL(*b); + e = APR_BUCKET_NEXT(e)) + { + rv = apr_bucket_setaside(e, p); + + /* If the bucket type does not implement setaside, then + * (hopefully) morph it into a bucket type which does, and set + * *that* aside... */ + if (rv == APR_ENOTIMPL) { + const char *s; + apr_size_t n; + + rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ); + if (rv == APR_SUCCESS) { + rv = apr_bucket_setaside(e, p); + } + } + + if (rv != APR_SUCCESS) { + srv = rv; + /* Return an error but still save the brigade if + * ->setaside() is really not implemented. */ + if (rv != APR_ENOTIMPL) { + return rv; + } + } + } + APR_BRIGADE_CONCAT(*saveto, *b); + return srv; +} + +AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, + void *ctx) +{ + ap_filter_t *f = ctx; + + return ap_pass_brigade(f, bb); +} + +AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb) +{ + apr_bucket *b; + + b = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + return ap_pass_brigade(f, bb); +} + +AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f, + apr_bucket_brigade *bb, ...) +{ + va_list args; + apr_status_t rv; + + va_start(args, bb); + rv = apr_brigade_vputstrs(bb, ap_filter_flush, f, args); + va_end(args); + return rv; +} + +AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f, + apr_bucket_brigade *bb, + const char *fmt, + ...) +{ + va_list args; + apr_status_t rv; + + va_start(args, fmt); + rv = apr_brigade_vprintf(bb, ap_filter_flush, f, fmt, args); + va_end(args); + return rv; +} +AP_DECLARE(void) ap_filter_protocol(ap_filter_t *f, unsigned int flags) +{ + f->frec->proto_flags = flags ; +} diff --git a/trunk/server/util_md5.c b/trunk/server/util_md5.c new file mode 100644 index 0000000000..744f3f283a --- /dev/null +++ b/trunk/server/util_md5.c @@ -0,0 +1,172 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/************************************************************************ + * NCSA HTTPd Server + * Software Development Group + * National Center for Supercomputing Applications + * University of Illinois at Urbana-Champaign + * 605 E. Springfield, Champaign, IL 61820 + * httpd@ncsa.uiuc.edu + * + * Copyright (C) 1995, Board of Trustees of the University of Illinois + * + ************************************************************************ + * + * md5.c: NCSA HTTPd code which uses the md5c.c RSA Code + * + * Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc. + * Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon + * University (see Copyright below). + * Portions of Content-MD5 code Copyright (C) 1991 Bell Communications + * Research, Inc. (Bellcore) (see Copyright below). + * Portions extracted from mpack, John G. Myers - jgm+@cmu.edu + * Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk) + * + */ + + + +/* md5.c --Module Interface to MD5. */ +/* Jeff Hostetler, Spyglass, Inc., 1994. */ + +#include "ap_config.h" +#include "apr_portable.h" +#include "apr_strings.h" +#include "httpd.h" +#include "util_md5.h" +#include "util_ebcdic.h" + +AP_DECLARE(char *) ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int length) +{ + const char *hex = "0123456789abcdef"; + apr_md5_ctx_t my_md5; + unsigned char hash[APR_MD5_DIGESTSIZE]; + char *r, result[33]; /* (MD5_DIGESTSIZE * 2) + 1 */ + int i; + + /* + * Take the MD5 hash of the string argument. + */ + + apr_md5_init(&my_md5); +#if APR_CHARSET_EBCDIC + apr_md5_set_xlate(&my_md5, ap_hdrs_to_ascii); +#endif + apr_md5_update(&my_md5, buf, (unsigned int)length); + apr_md5_final(hash, &my_md5); + + for (i = 0, r = result; i < APR_MD5_DIGESTSIZE; i++) { + *r++ = hex[hash[i] >> 4]; + *r++ = hex[hash[i] & 0xF]; + } + *r = '\0'; + + return apr_pstrndup(p, result, APR_MD5_DIGESTSIZE*2); +} + +AP_DECLARE(char *) ap_md5(apr_pool_t *p, const unsigned char *string) +{ + return ap_md5_binary(p, string, (int) strlen((char *)string)); +} + +/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */ + +/* (C) Copyright 1993,1994 by Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Carnegie + * Mellon University not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. Carnegie Mellon University makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore) + * + * Permission to use, copy, modify, and distribute this material + * for any purpose and without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies, and that the name of Bellcore not be + * used in advertising or publicity pertaining to this + * material without the specific, prior written permission + * of an authorized representative of Bellcore. BELLCORE + * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY + * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. + */ + +static char basis_64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +AP_DECLARE(char *) ap_md5contextTo64(apr_pool_t *a, apr_md5_ctx_t *context) +{ + unsigned char digest[18]; + char *encodedDigest; + int i; + char *p; + + encodedDigest = (char *) apr_pcalloc(a, 25 * sizeof(char)); + + apr_md5_final(digest, context); + digest[sizeof(digest) - 1] = digest[sizeof(digest) - 2] = 0; + + p = encodedDigest; + for (i = 0; i < sizeof(digest); i += 3) { + *p++ = basis_64[digest[i] >> 2]; + *p++ = basis_64[((digest[i] & 0x3) << 4) | ((int) (digest[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((digest[i + 1] & 0xF) << 2) | ((int) (digest[i + 2] & 0xC0) >> 6)]; + *p++ = basis_64[digest[i + 2] & 0x3F]; + } + *p-- = '\0'; + *p-- = '='; + *p-- = '='; + return encodedDigest; +} + +AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile) +{ + apr_md5_ctx_t context; + unsigned char buf[4096]; /* keep this a multiple of 64 */ + apr_size_t nbytes; + apr_off_t offset = 0L; + + apr_md5_init(&context); + nbytes = sizeof(buf); + while (apr_file_read(infile, buf, &nbytes) == APR_SUCCESS) { + apr_md5_update(&context, buf, nbytes); + nbytes = sizeof(buf); + } + apr_file_seek(infile, APR_SET, &offset); + return ap_md5contextTo64(p, &context); +} + diff --git a/trunk/server/util_pcre.c b/trunk/server/util_pcre.c new file mode 100644 index 0000000000..97c1b900fc --- /dev/null +++ b/trunk/server/util_pcre.c @@ -0,0 +1,224 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +This module is a wrapper that provides a POSIX API to the underlying PCRE +functions. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#include "httpd.h" +#include "apr_strings.h" +#include "pcre.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#ifndef POSIX_MALLOC_THRESHOLD +#define POSIX_MALLOC_THRESHOLD (10) +#endif + +/* Table of error strings corresponding to POSIX error codes; must be + * kept in synch with include/ap_regex.h's AP_REG_E* definitions. */ + +static const char *const pstring[] = { + "", /* Dummy for value 0 */ + "internal error", /* AP_REG_ASSERT */ + "failed to get memory", /* AP_REG_ESPACE */ + "bad argument", /* AP_REG_INVARG */ + "match failed" /* AP_REG_NOMATCH */ +}; + +AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg, + char *errbuf, apr_size_t errbuf_size) +{ +const char *message, *addmessage; +apr_size_t length, addlength; + +message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? + "unknown error code" : pstring[errcode]; +length = strlen(message) + 1; + +addmessage = " at offset "; +addlength = (preg != NULL && (int)preg->re_erroffset != -1)? + strlen(addmessage) + 6 : 0; + +if (errbuf_size > 0) + { + if (addlength > 0 && errbuf_size >= length + addlength) + apr_snprintf(errbuf, sizeof errbuf, + "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); + else + { + strncpy(errbuf, message, errbuf_size - 1); + errbuf[errbuf_size-1] = 0; + } + } + +return length + addlength; +} + + + + +/************************************************* +* Free store held by a regex * +*************************************************/ + +AP_DECLARE(void) ap_regfree(ap_regex_t *preg) +{ +(pcre_free)(preg->re_pcre); +} + + + + +/************************************************* +* Compile a regular expression * +*************************************************/ + +/* +Arguments: + preg points to a structure for recording the compiled expression + pattern the pattern to compile + cflags compilation flags + +Returns: 0 on success + various non-zero codes on failure +*/ + +AP_DECLARE(int) ap_regcomp(ap_regex_t *preg, const char *pattern, int cflags) +{ +const char *errorptr; +int erroffset; +int options = 0; + +if ((cflags & AP_REG_ICASE) != 0) options |= PCRE_CASELESS; +if ((cflags & AP_REG_NEWLINE) != 0) options |= PCRE_MULTILINE; + +preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL); +preg->re_erroffset = erroffset; + +if (preg->re_pcre == NULL) return AP_REG_INVARG; + +preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); +return 0; +} + + + + +/************************************************* +* Match a regular expression * +*************************************************/ + +/* Unfortunately, PCRE requires 3 ints of working space for each captured +substring, so we have to get and release working store instead of just using +the POSIX structures as was done in earlier releases when PCRE needed only 2 +ints. However, if the number of possible capturing brackets is small, use a +block of store on the stack, to reduce the use of malloc/free. The threshold is +in a macro that can be changed at configure time. */ + +AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string, + apr_size_t nmatch, ap_regmatch_t pmatch[], + int eflags) +{ +int rc; +int options = 0; +int *ovector = NULL; +int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; +int allocated_ovector = 0; + +if ((eflags & AP_REG_NOTBOL) != 0) options |= PCRE_NOTBOL; +if ((eflags & AP_REG_NOTEOL) != 0) options |= PCRE_NOTEOL; + +((ap_regex_t *)preg)->re_erroffset = (apr_size_t)(-1); /* Only has meaning after compile */ + +if (nmatch > 0) + { + if (nmatch <= POSIX_MALLOC_THRESHOLD) + { + ovector = &(small_ovector[0]); + } + else + { + ovector = (int *)malloc(sizeof(int) * nmatch * 3); + if (ovector == NULL) return AP_REG_ESPACE; + allocated_ovector = 1; + } + } + +rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string), + 0, options, ovector, nmatch * 3); + +if (rc == 0) rc = nmatch; /* All captured slots were filled in */ + +if (rc >= 0) + { + apr_size_t i; + for (i = 0; i < (apr_size_t)rc; i++) + { + pmatch[i].rm_so = ovector[i*2]; + pmatch[i].rm_eo = ovector[i*2+1]; + } + if (allocated_ovector) free(ovector); + for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + return 0; + } + +else + { + if (allocated_ovector) free(ovector); + switch(rc) + { + case PCRE_ERROR_NOMATCH: return AP_REG_NOMATCH; + case PCRE_ERROR_NULL: return AP_REG_INVARG; + case PCRE_ERROR_BADOPTION: return AP_REG_INVARG; + case PCRE_ERROR_BADMAGIC: return AP_REG_INVARG; + case PCRE_ERROR_UNKNOWN_NODE: return AP_REG_ASSERT; + case PCRE_ERROR_NOMEMORY: return AP_REG_ESPACE; + case PCRE_ERROR_MATCHLIMIT: return AP_REG_ESPACE; + case PCRE_ERROR_BADUTF8: return AP_REG_INVARG; + case PCRE_ERROR_BADUTF8_OFFSET: return AP_REG_INVARG; + default: return AP_REG_ASSERT; + } + } +} + +/* End of pcreposix.c */ diff --git a/trunk/server/util_script.c b/trunk/server/util_script.c new file mode 100644 index 0000000000..dcf418ddc4 --- /dev/null +++ b/trunk/server/util_script.c @@ -0,0 +1,704 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_STDLIB_H +#include +#endif + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_main.h" +#include "http_log.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" /* for sub_req_lookup_uri() */ +#include "util_script.h" +#include "apr_date.h" /* For apr_date_parse_http() */ +#include "util_ebcdic.h" + +#ifdef OS2 +#define INCL_DOS +#include +#endif + +/* + * Various utility functions which are common to a whole lot of + * script-type extensions mechanisms, and might as well be gathered + * in one place (if only to avoid creating inter-module dependancies + * where there don't have to be). + */ + +#define MALFORMED_MESSAGE "malformed header from script. Bad header=" +#define MALFORMED_HEADER_LENGTH_TO_SHOW 30 + +static char *http2env(apr_pool_t *a, const char *w) +{ + char *res = (char *)apr_palloc(a, sizeof("HTTP_") + strlen(w)); + char *cp = res; + char c; + + *cp++ = 'H'; + *cp++ = 'T'; + *cp++ = 'T'; + *cp++ = 'P'; + *cp++ = '_'; + + while ((c = *w++) != 0) { + if (!apr_isalnum(c)) { + *cp++ = '_'; + } + else { + *cp++ = apr_toupper(c); + } + } + *cp = 0; + + return res; +} + +AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t) +{ + const apr_array_header_t *env_arr = apr_table_elts(t); + const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts; + char **env = (char **) apr_palloc(p, (env_arr->nelts + 2) * sizeof(char *)); + int i, j; + char *tz; + char *whack; + + j = 0; + if (!apr_table_get(t, "TZ")) { + tz = getenv("TZ"); + if (tz != NULL) { + env[j++] = apr_pstrcat(p, "TZ=", tz, NULL); + } + } + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) { + continue; + } + env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL); + whack = env[j]; + if (apr_isdigit(*whack)) { + *whack++ = '_'; + } + while (*whack != '=') { + if (!apr_isalnum(*whack) && *whack != '_') { + *whack = '_'; + } + ++whack; + } + ++j; + } + + env[j] = NULL; + return env; +} + +AP_DECLARE(void) ap_add_common_vars(request_rec *r) +{ + apr_table_t *e; + server_rec *s = r->server; + conn_rec *c = r->connection; + const char *rem_logname; + char *env_path; +#if defined(WIN32) || defined(OS2) || defined(BEOS) + char *env_temp; +#endif + const char *host; + const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in); + const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts; + int i; + apr_port_t rport; + + /* use a temporary apr_table_t which we'll overlap onto + * r->subprocess_env later + * (exception: if r->subprocess_env is empty at the start, + * write directly into it) + */ + if (apr_is_empty_table(r->subprocess_env)) { + e = r->subprocess_env; + } + else { + e = apr_table_make(r->pool, 25 + hdrs_arr->nelts); + } + + /* First, add environment vars from headers... this is as per + * CGI specs, though other sorts of scripting interfaces see + * the same vars... + */ + + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) { + continue; + } + + /* A few headers are special cased --- Authorization to prevent + * rogue scripts from capturing passwords; content-type and -length + * for no particular reason. + */ + + if (!strcasecmp(hdrs[i].key, "Content-type")) { + apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val); + } + else if (!strcasecmp(hdrs[i].key, "Content-length")) { + apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val); + } + /* + * You really don't want to disable this check, since it leaves you + * wide open to CGIs stealing passwords and people viewing them + * in the environment with "ps -e". But, if you must... + */ +#ifndef SECURITY_HOLE_PASS_AUTHORIZATION + else if (!strcasecmp(hdrs[i].key, "Authorization") + || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) { + continue; + } +#endif + else { + apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val); + } + } + + if (!(env_path = getenv("PATH"))) { + env_path = DEFAULT_PATH; + } + apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path)); + +#ifdef WIN32 + if (env_temp = getenv("SystemRoot")) { + apr_table_addn(e, "SystemRoot", env_temp); + } + if (env_temp = getenv("COMSPEC")) { + apr_table_addn(e, "COMSPEC", env_temp); + } + if (env_temp = getenv("PATHEXT")) { + apr_table_addn(e, "PATHEXT", env_temp); + } + if (env_temp = getenv("WINDIR")) { + apr_table_addn(e, "WINDIR", env_temp); + } +#endif + +#ifdef OS2 + if ((env_temp = getenv("COMSPEC")) != NULL) { + apr_table_addn(e, "COMSPEC", env_temp); + } + if ((env_temp = getenv("ETC")) != NULL) { + apr_table_addn(e, "ETC", env_temp); + } + if ((env_temp = getenv("DPATH")) != NULL) { + apr_table_addn(e, "DPATH", env_temp); + } + if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) { + apr_table_addn(e, "PERLLIB_PREFIX", env_temp); + } +#endif + +#ifdef BEOS + if ((env_temp = getenv("LIBRARY_PATH")) != NULL) { + apr_table_addn(e, "LIBRARY_PATH", env_temp); + } +#endif + + apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); + apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); + apr_table_addn(e, "SERVER_NAME", + ap_escape_html(r->pool, ap_get_server_name(r))); + apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ + apr_table_addn(e, "SERVER_PORT", + apr_psprintf(r->pool, "%u", ap_get_server_port(r))); + host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL); + if (host) { + apr_table_addn(e, "REMOTE_HOST", host); + } + apr_table_addn(e, "REMOTE_ADDR", c->remote_ip); + apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */ + apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */ + apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ + + rport = c->remote_addr->port; + apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport)); + + if (r->user) { + apr_table_addn(e, "REMOTE_USER", r->user); + } + else if (r->prev) { + request_rec *back = r->prev; + + while (back) { + if (back->user) { + apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user); + break; + } + back = back->prev; + } + } + if (r->ap_auth_type) { + apr_table_addn(e, "AUTH_TYPE", r->ap_auth_type); + } + rem_logname = ap_get_remote_logname(r); + if (rem_logname) { + apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname)); + } + + /* Apache custom error responses. If we have redirected set two new vars */ + + if (r->prev) { + if (r->prev->args) { + apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args); + } + if (r->prev->uri) { + apr_table_addn(e, "REDIRECT_URL", r->prev->uri); + } + } + + if (e != r->subprocess_env) { + apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET); + } +} + +/* This "cute" little function comes about because the path info on + * filenames and URLs aren't always the same. So we take the two, + * and find as much of the two that match as possible. + */ + +AP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info) +{ + int lu = strlen(uri); + int lp = strlen(path_info); + + while (lu-- && lp-- && uri[lu] == path_info[lp]); + + if (lu == -1) { + lu = 0; + } + + while (uri[lu] != '\0' && uri[lu] != '/') { + lu++; + } + return lu; +} + +/* Obtain the Request-URI from the original request-line, returning + * a new string from the request pool containing the URI or "". + */ +static char *original_uri(request_rec *r) +{ + char *first, *last; + + if (r->the_request == NULL) { + return (char *) apr_pcalloc(r->pool, 1); + } + + first = r->the_request; /* use the request-line */ + + while (*first && !apr_isspace(*first)) { + ++first; /* skip over the method */ + } + while (apr_isspace(*first)) { + ++first; /* and the space(s) */ + } + + last = first; + while (*last && !apr_isspace(*last)) { + ++last; /* end at next whitespace */ + } + + return apr_pstrmemdup(r->pool, first, last - first); +} + +AP_DECLARE(void) ap_add_cgi_vars(request_rec *r) +{ + apr_table_t *e = r->subprocess_env; + + apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1"); + apr_table_setn(e, "SERVER_PROTOCOL", r->protocol); + apr_table_setn(e, "REQUEST_METHOD", r->method); + apr_table_setn(e, "QUERY_STRING", r->args ? r->args : ""); + apr_table_setn(e, "REQUEST_URI", original_uri(r)); + + /* Note that the code below special-cases scripts run from includes, + * because it "knows" that the sub_request has been hacked to have the + * args and path_info of the original request, and not any that may have + * come with the script URI in the include command. Ugh. + */ + + if (!strcmp(r->protocol, "INCLUDED")) { + apr_table_setn(e, "SCRIPT_NAME", r->uri); + if (r->path_info && *r->path_info) { + apr_table_setn(e, "PATH_INFO", r->path_info); + } + } + else if (!r->path_info || !*r->path_info) { + apr_table_setn(e, "SCRIPT_NAME", r->uri); + } + else { + int path_info_start = ap_find_path_info(r->uri, r->path_info); + + apr_table_setn(e, "SCRIPT_NAME", + apr_pstrndup(r->pool, r->uri, path_info_start)); + + apr_table_setn(e, "PATH_INFO", r->path_info); + } + + if (r->path_info && r->path_info[0]) { + /* + * To get PATH_TRANSLATED, treat PATH_INFO as a URI path. + * Need to re-escape it for this, since the entire URI was + * un-escaped before we determined where the PATH_INFO began. + */ + request_rec *pa_req; + + pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r, + NULL); + + if (pa_req->filename) { + char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info, + NULL); +#ifdef WIN32 + /* We need to make this a real Windows path name */ + apr_filepath_merge(&pt, "", pt, APR_FILEPATH_NATIVE, r->pool); +#endif + apr_table_setn(e, "PATH_TRANSLATED", pt); + } + ap_destroy_sub_req(pa_req); + } +} + + +static int set_cookie_doo_doo(void *v, const char *key, const char *val) +{ + apr_table_addn(v, key, val); + return 1; +} + +AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, + int (*getsfunc) (char *, int, void *), + void *getsfunc_data) +{ + char x[MAX_STRING_LEN]; + char *w, *l; + int p; + int cgi_status = HTTP_OK; + apr_table_t *merge; + apr_table_t *cookie_table; + + if (buffer) { + *buffer = '\0'; + } + w = buffer ? buffer : x; + + /* temporary place to hold headers to merge in later */ + merge = apr_table_make(r->pool, 10); + + /* The HTTP specification says that it is legal to merge duplicate + * headers into one. Some browsers that support Cookies don't like + * merged headers and prefer that each Set-Cookie header is sent + * separately. Lets humour those browsers by not merging. + * Oh what a pain it is. + */ + cookie_table = apr_table_make(r->pool, 2); + apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, "Set-Cookie", NULL); + + while (1) { + + if ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data) == 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "Premature end of script headers: %s", + apr_filepath_name_get(r->filename)); + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Delete terminal (CR?)LF */ + + p = strlen(w); + /* Indeed, the host's '\n': + '\012' for UNIX; '\015' for MacOS; '\025' for OS/390 + -- whatever the script generates. + */ + if (p > 0 && w[p - 1] == '\n') { + if (p > 1 && w[p - 2] == CR) { + w[p - 2] = '\0'; + } + else { + w[p - 1] = '\0'; + } + } + + /* + * If we've finished reading the headers, check to make sure any + * HTTP/1.1 conditions are met. If so, we're done; normal processing + * will handle the script's output. If not, just return the error. + * The appropriate thing to do would be to send the script process a + * SIGPIPE to let it know we're ignoring it, close the channel to the + * script process, and *then* return the failed-to-meet-condition + * error. Otherwise we'd be waiting for the script to finish + * blithering before telling the client the output was no good. + * However, we don't have the information to do that, so we have to + * leave it to an upper layer. + */ + if (w[0] == '\0') { + int cond_status = OK; + + if ((cgi_status == HTTP_OK) && (r->method_number == M_GET)) { + cond_status = ap_meets_conditions(r); + } + apr_table_overlap(r->err_headers_out, merge, + APR_OVERLAP_TABLES_MERGE); + if (!apr_is_empty_table(cookie_table)) { + /* the cookies have already been copied to the cookie_table */ + apr_table_unset(r->err_headers_out, "Set-Cookie"); + r->err_headers_out = apr_table_overlay(r->pool, + r->err_headers_out, cookie_table); + } + return cond_status; + } + + /* if we see a bogus header don't ignore it. Shout and scream */ + +#if APR_CHARSET_EBCDIC + /* Chances are that we received an ASCII header text instead of + * the expected EBCDIC header lines. Try to auto-detect: + */ + if (!(l = strchr(w, ':'))) { + int maybeASCII = 0, maybeEBCDIC = 0; + unsigned char *cp, native; + apr_size_t inbytes_left, outbytes_left; + + for (cp = w; *cp != '\0'; ++cp) { + native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp); + if (apr_isprint(*cp) && !apr_isprint(native)) + ++maybeEBCDIC; + if (!apr_isprint(*cp) && apr_isprint(native)) + ++maybeASCII; + } + if (maybeASCII > maybeEBCDIC) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)", + r->filename); + inbytes_left = outbytes_left = cp - w; + apr_xlate_conv_buffer(ap_hdrs_from_ascii, + w, &inbytes_left, w, &outbytes_left); + } + } +#endif /*APR_CHARSET_EBCDIC*/ + if (!(l = strchr(w, ':'))) { + char malformed[(sizeof MALFORMED_MESSAGE) + 1 + + MALFORMED_HEADER_LENGTH_TO_SHOW]; + + strcpy(malformed, MALFORMED_MESSAGE); + strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW); + + if (!buffer) { + /* Soak up all the script output - may save an outright kill */ + while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) { + continue; + } + } + + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "%s: %s", malformed, + apr_filepath_name_get(r->filename)); + return HTTP_INTERNAL_SERVER_ERROR; + } + + *l++ = '\0'; + while (*l && apr_isspace(*l)) { + ++l; + } + + if (!strcasecmp(w, "Content-type")) { + char *tmp; + + /* Nuke trailing whitespace */ + + char *endp = l + strlen(l) - 1; + while (endp > l && apr_isspace(*endp)) { + *endp-- = '\0'; + } + + tmp = apr_pstrdup(r->pool, l); + ap_content_type_tolower(tmp); + ap_set_content_type(r, tmp); + } + /* + * If the script returned a specific status, that's what + * we'll use - otherwise we assume 200 OK. + */ + else if (!strcasecmp(w, "Status")) { + r->status = cgi_status = atoi(l); + r->status_line = apr_pstrdup(r->pool, l); + } + else if (!strcasecmp(w, "Location")) { + apr_table_set(r->headers_out, w, l); + } + else if (!strcasecmp(w, "Content-Length")) { + apr_table_set(r->headers_out, w, l); + } + else if (!strcasecmp(w, "Content-Range")) { + apr_table_set(r->headers_out, w, l); + } + else if (!strcasecmp(w, "Transfer-Encoding")) { + apr_table_set(r->headers_out, w, l); + } + /* + * If the script gave us a Last-Modified header, we can't just + * pass it on blindly because of restrictions on future values. + */ + else if (!strcasecmp(w, "Last-Modified")) { + ap_update_mtime(r, apr_date_parse_http(l)); + ap_set_last_modified(r); + } + else if (!strcasecmp(w, "Set-Cookie")) { + apr_table_add(cookie_table, w, l); + } + else { + apr_table_add(merge, w, l); + } + } + + return OK; +} + +static int getsfunc_FILE(char *buf, int len, void *f) +{ + return apr_file_gets(buf, len, (apr_file_t *) f) == APR_SUCCESS; +} + +AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, + char *buffer) +{ + return ap_scan_script_header_err_core(r, buffer, getsfunc_FILE, f); +} + +static int getsfunc_BRIGADE(char *buf, int len, void *arg) +{ + apr_bucket_brigade *bb = (apr_bucket_brigade *)arg; + const char *dst_end = buf + len - 1; /* leave room for terminating null */ + char *dst = buf; + apr_bucket *e = APR_BRIGADE_FIRST(bb); + apr_status_t rv; + int done = 0; + + while ((dst < dst_end) && !done && !APR_BUCKET_IS_EOS(e)) { + const char *bucket_data; + apr_size_t bucket_data_len; + const char *src; + const char *src_end; + apr_bucket * next; + + rv = apr_bucket_read(e, &bucket_data, &bucket_data_len, + APR_BLOCK_READ); + if (rv != APR_SUCCESS || (bucket_data_len == 0)) { + return 0; + } + src = bucket_data; + src_end = bucket_data + bucket_data_len; + while ((src < src_end) && (dst < dst_end) && !done) { + if (*src == '\n') { + done = 1; + } + else if (*src != '\r') { + *dst++ = *src; + } + src++; + } + + if (src < src_end) { + apr_bucket_split(e, src - bucket_data); + } + next = APR_BUCKET_NEXT(e); + APR_BUCKET_REMOVE(e); + apr_bucket_destroy(e); + e = next; + } + *dst = 0; + return 1; +} + +AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, + apr_bucket_brigade *bb, + char *buffer) +{ + return ap_scan_script_header_err_core(r, buffer, getsfunc_BRIGADE, bb); +} + +struct vastrs { + va_list args; + int arg; + const char *curpos; +}; + +static int getsfunc_STRING(char *w, int len, void *pvastrs) +{ + struct vastrs *strs = (struct vastrs*) pvastrs; + const char *p; + int t; + + if (!strs->curpos || !*strs->curpos) + return 0; + p = ap_strchr_c(strs->curpos, '\n'); + if (p) + ++p; + else + p = ap_strchr_c(strs->curpos, '\0'); + t = p - strs->curpos; + if (t > len) + t = len; + strncpy (w, strs->curpos, t); + w[t] = '\0'; + if (!strs->curpos[t]) { + ++strs->arg; + strs->curpos = va_arg(strs->args, const char *); + } + else + strs->curpos += t; + return t; +} + +/* ap_scan_script_header_err_strs() accepts additional const char* args... + * each is treated as one or more header lines, and the first non-header + * character is returned to **arg, **data. (The first optional arg is + * counted as 0.) + */ +AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, + char *buffer, + const char **termch, + int *termarg, ...) +{ + struct vastrs strs; + int res; + + va_start(strs.args, termarg); + strs.arg = 0; + strs.curpos = va_arg(strs.args, char*); + res = ap_scan_script_header_err_core(r, buffer, getsfunc_STRING, (void *) &strs); + if (termch) + *termch = strs.curpos; + if (termarg) + *termarg = strs.arg; + va_end(strs.args); + return res; +} diff --git a/trunk/server/util_time.c b/trunk/server/util_time.c new file mode 100644 index 0000000000..f04e158485 --- /dev/null +++ b/trunk/server/util_time.c @@ -0,0 +1,240 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "util_time.h" + +/* Cache for exploded values of recent timestamps + */ + +struct exploded_time_cache_element { + apr_int64_t t; + apr_time_exp_t xt; + apr_int64_t t_validate; /* please see comments in cached_explode() */ +}; + +/* the "+ 1" is for the current second: */ +#define TIME_CACHE_SIZE (AP_TIME_RECENT_THRESHOLD + 1) + +/* Note that AP_TIME_RECENT_THRESHOLD is defined to + * be a power of two minus one in util_time.h, so that + * we can replace a modulo operation with a bitwise AND + * when hashing items into a cache of size + * AP_TIME_RECENT_THRESHOLD+1 + */ +#define TIME_CACHE_MASK (AP_TIME_RECENT_THRESHOLD) + +static struct exploded_time_cache_element exploded_cache_localtime[TIME_CACHE_SIZE]; +static struct exploded_time_cache_element exploded_cache_gmt[TIME_CACHE_SIZE]; + + +static apr_status_t cached_explode(apr_time_exp_t *xt, apr_time_t t, + struct exploded_time_cache_element *cache, + int use_gmt) +{ + apr_int64_t seconds = apr_time_sec(t); + struct exploded_time_cache_element *cache_element = + &(cache[seconds & TIME_CACHE_MASK]); + struct exploded_time_cache_element cache_element_snapshot; + + /* The cache is implemented as a ring buffer. Each second, + * it uses a different element in the buffer. The timestamp + * in the element indicates whether the element contains the + * exploded time for the current second (vs the time + * 'now - AP_TIME_RECENT_THRESHOLD' seconds ago). If the + * cached value is for the current time, we use it. Otherwise, + * we compute the apr_time_exp_t and store it in this + * cache element. Note that the timestamp in the cache + * element is updated only after the exploded time. Thus + * if two threads hit this cache element simultaneously + * at the start of a new second, they'll both explode the + * time and store it. I.e., the writers will collide, but + * they'll be writing the same value. + */ + if (cache_element->t >= seconds) { + /* There is an intentional race condition in this design: + * in a multithreaded app, one thread might be reading + * from this cache_element to resolve a timestamp from + * TIME_CACHE_SIZE seconds ago at the same time that + * another thread is copying the exploded form of the + * current time into the same cache_element. (I.e., the + * first thread might hit this element of the ring buffer + * just as the element is being recycled.) This can + * also happen at the start of a new second, if a + * reader accesses the cache_element after a writer + * has updated cache_element.t but before the writer + * has finished updating the whole cache_element. + * + * Rather than trying to prevent this race condition + * with locks, we allow it to happen and then detect + * and correct it. The detection works like this: + * Step 1: Take a "snapshot" of the cache element by + * copying it into a temporary buffer. + * Step 2: Check whether the snapshot contains consistent + * data: the timestamps at the start and end of + * the cache_element should both match the 'seconds' + * value that we computed from the input time. + * If these three don't match, then the snapshot + * shows the cache_element in the middle of an + * update, and its contents are invalid. + * Step 3: If the snapshot is valid, use it. Otherwise, + * just give up on the cache and explode the + * input time. + */ + memcpy(&cache_element_snapshot, cache_element, + sizeof(struct exploded_time_cache_element)); + if ((seconds != cache_element_snapshot.t) || + (seconds != cache_element_snapshot.t_validate)) { + /* Invalid snapshot */ + if (use_gmt) { + return apr_time_exp_gmt(xt, t); + } + else { + return apr_time_exp_lt(xt, t); + } + } + else { + /* Valid snapshot */ + memcpy(xt, &(cache_element_snapshot.xt), + sizeof(apr_time_exp_t)); + } + } + else { + apr_status_t r; + if (use_gmt) { + r = apr_time_exp_gmt(xt, t); + } + else { + r = apr_time_exp_lt(xt, t); + } + if (r != APR_SUCCESS) { + return r; + } + cache_element->t = seconds; + memcpy(&(cache_element->xt), xt, sizeof(apr_time_exp_t)); + cache_element->t_validate = seconds; + } + xt->tm_usec = (int)apr_time_usec(t); + return APR_SUCCESS; +} + + +AP_DECLARE(apr_status_t) ap_explode_recent_localtime(apr_time_exp_t * tm, + apr_time_t t) +{ + return cached_explode(tm, t, exploded_cache_localtime, 0); +} + +AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t * tm, + apr_time_t t) +{ + return cached_explode(tm, t, exploded_cache_gmt, 1); +} + +AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t) +{ + /* ### This code is a clone of apr_ctime(), except that it + * uses ap_explode_recent_localtime() instead of apr_time_exp_lt(). + */ + apr_time_exp_t xt; + const char *s; + int real_year; + + /* example: "Wed Jun 30 21:49:08 1993" */ + /* 123456789012345678901234 */ + + ap_explode_recent_localtime(&xt, t); + s = &apr_day_snames[xt.tm_wday][0]; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = ' '; + s = &apr_month_snames[xt.tm_mon][0]; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = ' '; + *date_str++ = xt.tm_mday / 10 + '0'; + *date_str++ = xt.tm_mday % 10 + '0'; + *date_str++ = ' '; + *date_str++ = xt.tm_hour / 10 + '0'; + *date_str++ = xt.tm_hour % 10 + '0'; + *date_str++ = ':'; + *date_str++ = xt.tm_min / 10 + '0'; + *date_str++ = xt.tm_min % 10 + '0'; + *date_str++ = ':'; + *date_str++ = xt.tm_sec / 10 + '0'; + *date_str++ = xt.tm_sec % 10 + '0'; + *date_str++ = ' '; + real_year = 1900 + xt.tm_year; + *date_str++ = real_year / 1000 + '0'; + *date_str++ = real_year % 1000 / 100 + '0'; + *date_str++ = real_year % 100 / 10 + '0'; + *date_str++ = real_year % 10 + '0'; + *date_str++ = 0; + + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_recent_rfc822_date(char *date_str, apr_time_t t) +{ + /* ### This code is a clone of apr_rfc822_date(), except that it + * uses ap_explode_recent_gmt() instead of apr_time_exp_gmt(). + */ + apr_time_exp_t xt; + const char *s; + int real_year; + + ap_explode_recent_gmt(&xt, t); + + /* example: "Sat, 08 Jan 2000 18:31:41 GMT" */ + /* 12345678901234567890123456789 */ + + s = &apr_day_snames[xt.tm_wday][0]; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = ','; + *date_str++ = ' '; + *date_str++ = xt.tm_mday / 10 + '0'; + *date_str++ = xt.tm_mday % 10 + '0'; + *date_str++ = ' '; + s = &apr_month_snames[xt.tm_mon][0]; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = *s++; + *date_str++ = ' '; + real_year = 1900 + xt.tm_year; + /* This routine isn't y10k ready. */ + *date_str++ = real_year / 1000 + '0'; + *date_str++ = real_year % 1000 / 100 + '0'; + *date_str++ = real_year % 100 / 10 + '0'; + *date_str++ = real_year % 10 + '0'; + *date_str++ = ' '; + *date_str++ = xt.tm_hour / 10 + '0'; + *date_str++ = xt.tm_hour % 10 + '0'; + *date_str++ = ':'; + *date_str++ = xt.tm_min / 10 + '0'; + *date_str++ = xt.tm_min % 10 + '0'; + *date_str++ = ':'; + *date_str++ = xt.tm_sec / 10 + '0'; + *date_str++ = xt.tm_sec % 10 + '0'; + *date_str++ = ' '; + *date_str++ = 'G'; + *date_str++ = 'M'; + *date_str++ = 'T'; + *date_str++ = 0; + return APR_SUCCESS; +} diff --git a/trunk/server/util_xml.c b/trunk/server/util_xml.c new file mode 100644 index 0000000000..e2d9fce8c8 --- /dev/null +++ b/trunk/server/util_xml.c @@ -0,0 +1,135 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_xml.h" + +#include "httpd.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_core.h" + +#include "util_charset.h" +#include "util_xml.h" + + +/* used for reading input blocks */ +#define READ_BLOCKSIZE 2048 + + +AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc) +{ + apr_xml_parser *parser; + apr_bucket_brigade *brigade; + int seen_eos; + apr_status_t status; + char errbuf[200]; + apr_size_t total_read = 0; + apr_size_t limit_xml_body = ap_get_limit_xml_body(r); + int result = HTTP_BAD_REQUEST; + + parser = apr_xml_parser_create(r->pool); + brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); + + seen_eos = 0; + total_read = 0; + + do { + apr_bucket *bucket; + + /* read the body, stuffing it into the parser */ + status = ap_get_brigade(r->input_filters, brigade, + AP_MODE_READBYTES, APR_BLOCK_READ, + READ_BLOCKSIZE); + + if (status != APR_SUCCESS) { + goto read_error; + } + + for (bucket = APR_BRIGADE_FIRST(brigade); + bucket != APR_BRIGADE_SENTINEL(brigade); + bucket = APR_BUCKET_NEXT(bucket)) + { + const char *data; + apr_size_t len; + + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + if (APR_BUCKET_IS_METADATA(bucket)) { + continue; + } + + status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + if (status != APR_SUCCESS) { + goto read_error; + } + + total_read += len; + if (limit_xml_body && total_read > limit_xml_body) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "XML request body is larger than the configured " + "limit of %lu", (unsigned long)limit_xml_body); + result = HTTP_REQUEST_ENTITY_TOO_LARGE; + goto read_error; + } + + status = apr_xml_parser_feed(parser, data, len); + if (status) { + goto parser_error; + } + } + + apr_brigade_cleanup(brigade); + } while (!seen_eos); + + apr_brigade_destroy(brigade); + + /* tell the parser that we're done */ + status = apr_xml_parser_done(parser, pdoc); + if (status) { + /* Some parsers are stupid and return an error on blank documents. */ + if (!total_read) { + *pdoc = NULL; + return OK; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "XML parser error (at end). status=%d", status); + return HTTP_BAD_REQUEST; + } + +#if APR_CHARSET_EBCDIC + apr_xml_parser_convert_doc(r->pool, *pdoc, ap_hdrs_from_ascii); +#endif + return OK; + + parser_error: + (void) apr_xml_parser_geterror(parser, errbuf, sizeof(errbuf)); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "XML Parser Error: %s", errbuf); + + /* FALLTHRU */ + + read_error: + /* make sure the parser is terminated */ + (void) apr_xml_parser_done(parser, NULL); + + apr_brigade_destroy(brigade); + + /* Apache will supply a default error, plus the error log above. */ + return result; +} diff --git a/trunk/server/vhost.c b/trunk/server/vhost.c new file mode 100644 index 0000000000..6bb27bd80a --- /dev/null +++ b/trunk/server/vhost.c @@ -0,0 +1,1065 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * http_vhost.c: functions pertaining to virtual host addresses + * (configuration and run-time) + */ + +#include "apr.h" +#include "apr_strings.h" +#include "apr_lib.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define CORE_PRIVATE +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "http_vhost.h" +#include "http_protocol.h" +#include "http_core.h" + +#if APR_HAVE_ARPA_INET_H +#include +#endif + +/* + * After all the definitions there's an explanation of how it's all put + * together. + */ + +/* meta-list of name-vhosts. Each server_rec can be in possibly multiple + * lists of name-vhosts. + */ +typedef struct name_chain name_chain; +struct name_chain { + name_chain *next; + server_addr_rec *sar; /* the record causing it to be in + * this chain (needed for port comparisons) */ + server_rec *server; /* the server to use on a match */ +}; + +/* meta-list of ip addresses. Each server_rec can be in possibly multiple + * hash chains since it can have multiple ips. + */ +typedef struct ipaddr_chain ipaddr_chain; +struct ipaddr_chain { + ipaddr_chain *next; + server_addr_rec *sar; /* the record causing it to be in + * this chain (need for both ip addr and port + * comparisons) */ + server_rec *server; /* the server to use if this matches */ + name_chain *names; /* if non-NULL then a list of name-vhosts + * sharing this address */ +}; + +/* This defines the size of the hash table used for hashing ip addresses + * of virtual hosts. It must be a power of two. + */ +#ifndef IPHASH_TABLE_SIZE +#define IPHASH_TABLE_SIZE 256 +#endif + +/* A (n) bucket hash table, each entry has a pointer to a server rec and + * a pointer to the other entries in that bucket. Each individual address, + * even for virtualhosts with multiple addresses, has an entry in this hash + * table. There are extra buckets for _default_, and name-vhost entries. + * + * Note that after config time this is constant, so it is thread-safe. + */ +static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE]; + +/* dump out statistics about the hash function */ +/* #define IPHASH_STATISTICS */ + +/* list of the _default_ servers */ +static ipaddr_chain *default_list; + +/* list of the NameVirtualHost addresses */ +static server_addr_rec *name_vhost_list; +static server_addr_rec **name_vhost_list_tail; + +/* + * How it's used: + * + * The ip address determines which chain in iphash_table is interesting, then + * a comparison is done down that chain to find the first ipaddr_chain whose + * sar matches the address:port pair. + * + * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost. + * + * Otherwise it's a name-vhost list, and the default is the server in the + * ipaddr_chain record. We tuck away the ipaddr_chain record in the + * conn_rec field vhost_lookup_data. Later on after the headers we get a + * second chance, and we use the name_chain to figure out what name-vhost + * matches the headers. + * + * If there was no ip address match in the iphash_table then do a lookup + * in the default_list. + * + * How it's put together ... well you should be able to figure that out + * from how it's used. Or something like that. + */ + + +/* called at the beginning of the config */ +AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p) +{ + memset(iphash_table, 0, sizeof(iphash_table)); + default_list = NULL; + name_vhost_list = NULL; + name_vhost_list_tail = &name_vhost_list; +} + + +/* + * Parses a host of the form
    [:port] + * paddr is used to create a list in the order of input + * **paddr is the ->next pointer of the last entry (or s->addrs) + * *paddr is the variable used to keep track of **paddr between calls + * port is the default port to assume + */ +static const char *get_addresses(apr_pool_t *p, const char *w_, + server_addr_rec ***paddr, + apr_port_t default_port) +{ + apr_sockaddr_t *my_addr; + server_addr_rec *sar; + char *w, *host, *scope_id; + int wild_port; + apr_size_t wlen; + apr_port_t port; + apr_status_t rv; + + if (*w_ == '\0') + return NULL; + + w = apr_pstrdup(p, w_); + /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */ + wlen = strlen(w); /* wlen must be > 0 at this point */ + wild_port = 0; + if (w[wlen - 1] == '*') { + if (wlen < 2) { + wild_port = 1; + } + else if (w[wlen - 2] == ':') { + w[wlen - 2] = '\0'; + wild_port = 1; + } + } + rv = apr_parse_addr_port(&host, &scope_id, &port, w, p); + /* If the string is "80", apr_parse_addr_port() will be happy and set + * host to NULL and port to 80, so watch out for that. + */ + if (rv != APR_SUCCESS) { + return "The address or port is invalid"; + } + if (!host) { + return "Missing address for VirtualHost"; + } + if (scope_id) { + return "Scope ids are not supported"; + } + if (!port && !wild_port) { + port = default_port; + } + + if (strcmp(host, "*") == 0) { + rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p); + ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */ + } + else if (strcasecmp(host, "_default_") == 0 + || strcmp(host, "255.255.255.255") == 0) { + rv = apr_sockaddr_info_get(&my_addr, "255.255.255.255", APR_INET, port, 0, p); + ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */ + } + else { + rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, + "Cannot resolve host name %s --- ignoring!", host); + return NULL; + } + } + + /* Remember all addresses for the host */ + + do { + sar = apr_pcalloc(p, sizeof(server_addr_rec)); + **paddr = sar; + *paddr = &sar->next; + sar->host_addr = my_addr; + sar->host_port = port; + sar->virthost = host; + my_addr = my_addr->next; + } while (my_addr); + + return NULL; +} + + +/* parse the addresses */ +const char *ap_parse_vhost_addrs(apr_pool_t *p, + const char *hostname, + server_rec *s) +{ + server_addr_rec **addrs; + const char *err; + + /* start the list of addreses */ + addrs = &s->addrs; + while (hostname[0]) { + err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port); + if (err) { + *addrs = NULL; + return err; + } + } + /* terminate the list */ + *addrs = NULL; + if (s->addrs) { + if (s->addrs->host_port) { + /* override the default port which is inherited from main_server */ + s->port = s->addrs->host_port; + } + } + return NULL; +} + + +const char *ap_set_name_virtual_host(cmd_parms *cmd, void *dummy, + const char *arg) +{ + /* use whatever port the main server has at this point */ + return get_addresses(cmd->pool, arg, &name_vhost_list_tail, + cmd->server->port); +} + + +/* hash table statistics, keep this in here for the beta period so + * we can find out if the hash function is ok + */ +#ifdef IPHASH_STATISTICS +static int iphash_compare(const void *a, const void *b) +{ + return (*(const int *) b - *(const int *) a); +} + + +static void dump_iphash_statistics(server_rec *main_s) +{ + unsigned count[IPHASH_TABLE_SIZE]; + int i; + ipaddr_chain *src; + unsigned total; + char buf[HUGE_STRING_LEN]; + char *p; + + total = 0; + for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { + count[i] = 0; + for (src = iphash_table[i]; src; src = src->next) { + ++count[i]; + if (i < IPHASH_TABLE_SIZE) { + /* don't count the slop buckets in the total */ + ++total; + } + } + } + qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare); + p = buf + apr_snprintf(buf, sizeof(buf), + "iphash: total hashed = %u, avg chain = %u, " + "chain lengths (count x len):", + total, total / IPHASH_TABLE_SIZE); + total = 1; + for (i = 1; i < IPHASH_TABLE_SIZE; ++i) { + if (count[i - 1] != count[i]) { + p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u", + total, count[i - 1]); + total = 1; + } + else { + ++total; + } + } + p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u", + total, count[IPHASH_TABLE_SIZE - 1]); + ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf); +} +#endif + + +/* This hashing function is designed to get good distribution in the cases + * where the server is handling entire "networks" of servers. i.e. a + * whack of /24s. This is probably the most common configuration for + * ISPs with large virtual servers. + * + * NOTE: This function is symmetric (i.e. collapses all 4 octets + * into one), so machine byte order (big/little endianness) does not matter. + * + * Hash function provided by David Hankins. + */ +static APR_INLINE unsigned hash_inaddr(unsigned key) +{ + key ^= (key >> 16); + return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE; +} + +static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa) +{ + unsigned key; + + /* The key is the last four bytes of the IP address. + * For IPv4, this is the entire address, as always. + * For IPv6, this is usually part of the MAC address. + */ + key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4); + return hash_inaddr(key); +} + +static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p, + server_rec *s, server_addr_rec *sar) +{ + ipaddr_chain *new; + + new = apr_palloc(p, sizeof(*new)); + new->names = NULL; + new->server = s; + new->sar = sar; + new->next = NULL; + return new; +} + + +static name_chain *new_name_chain(apr_pool_t *p, + server_rec *s, server_addr_rec *sar) +{ + name_chain *new; + + new = apr_palloc(p, sizeof(*new)); + new->server = s; + new->sar = sar; + new->next = NULL; + return new; +} + + +static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa) +{ + unsigned bucket; + ipaddr_chain *trav; + + /* scan the hash table for an exact match first */ + bucket = hash_addr(sa); + for (trav = iphash_table[bucket]; trav; trav = trav->next) { + server_addr_rec *sar = trav->sar; + apr_sockaddr_t *cur = sar->host_addr; + + if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) { + if (apr_sockaddr_equal(cur, sa)) { + return trav; + } + } + } + return NULL; +} + +static ipaddr_chain *find_default_server(apr_port_t port) +{ + server_addr_rec *sar; + ipaddr_chain *trav; + + for (trav = default_list; trav; trav = trav->next) { + sar = trav->sar; + if (sar->host_port == 0 || sar->host_port == port) { + /* match! */ + return trav; + } + } + return NULL; +} + +static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic) +{ + name_chain *nc; + int len; + char buf[MAX_STRING_LEN]; + apr_sockaddr_t *ha = ic->sar->host_addr; + + if (ha->family == APR_INET && + ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) { + len = apr_snprintf(buf, sizeof(buf), "_default_:%u", + ic->sar->host_port); + } + else if (ha->family == APR_INET && + ha->sa.sin.sin_addr.s_addr == INADDR_ANY) { + len = apr_snprintf(buf, sizeof(buf), "*:%u", + ic->sar->host_port); + } + else { + len = apr_snprintf(buf, sizeof(buf), "%pI", ha); + } + if (ic->sar->host_port == 0) { + buf[len-1] = '*'; + } + if (ic->names == NULL) { + apr_file_printf(f, "%-22s %s (%s:%u)\n", buf, + ic->server->server_hostname, + ic->server->defn_name, ic->server->defn_line_number); + return; + } + apr_file_printf(f, "%-22s is a NameVirtualHost\n" + "%8s default server %s (%s:%u)\n", + buf, "", ic->server->server_hostname, + ic->server->defn_name, ic->server->defn_line_number); + for (nc = ic->names; nc; nc = nc->next) { + if (nc->sar->host_port) { + apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port); + } + else { + apr_file_printf(f, "%8s port * ", ""); + } + apr_file_printf(f, "namevhost %s (%s:%u)\n", + nc->server->server_hostname, + nc->server->defn_name, nc->server->defn_line_number); + } +} + +static void dump_vhost_config(apr_file_t *f) +{ + ipaddr_chain *ic; + int i; + + apr_file_printf(f, "VirtualHost configuration:\n"); + for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { + for (ic = iphash_table[i]; ic; ic = ic->next) { + dump_a_vhost(f, ic); + } + } + if (default_list) { + apr_file_printf(f, "wildcard NameVirtualHosts and _default_ servers:\n"); + for (ic = default_list; ic; ic = ic->next) { + dump_a_vhost(f, ic); + } + } +} + +/* + * Two helper functions for ap_fini_vhost_config() + */ +static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, + server_rec *s, server_addr_rec *sar, + ipaddr_chain *ic) +{ + /* the first time we encounter a NameVirtualHost address + * ic->server will be NULL, on subsequent encounters + * ic->names will be non-NULL. + */ + if (ic->names || ic->server == NULL) { + name_chain *nc = new_name_chain(p, s, sar); + nc->next = ic->names; + ic->names = nc; + ic->server = s; + if (sar->host_port != ic->sar->host_port) { + /* one of the two is a * port, the other isn't */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_s, + "VirtualHost %s:%u -- mixing * " + "ports and non-* ports with " + "a NameVirtualHost address is not supported," + " proceeding with undefined results", + sar->virthost, sar->host_port); + } + return 1; + } + else { + /* IP-based vhosts are handled by the caller */ + return 0; + } +} + +static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic) +{ + while (*pic) { + ipaddr_chain *ic = *pic; + + if (ic->server == NULL) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_s, + "NameVirtualHost %s:%u has no VirtualHosts", + ic->sar->virthost, ic->sar->host_port); + *pic = ic->next; + } + else { + pic = &ic->next; + } + } +} + +/* compile the tables and such we need to do the run-time vhost lookups */ +AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s) +{ + server_addr_rec *sar; + int has_default_vhost_addr; + server_rec *s; + int i; + ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE]; + + /* terminate the name_vhost list */ + *name_vhost_list_tail = NULL; + + /* Main host first */ + s = main_s; + + if (!s->server_hostname) { + s->server_hostname = ap_get_local_host(p); + } + + /* initialize the tails */ + for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { + iphash_table_tail[i] = &iphash_table[i]; + } + + /* The first things to go into the hash table are the NameVirtualHosts + * Since name_vhost_list is in the same order that the directives + * occured in the config file, we'll copy it in that order. + */ + for (sar = name_vhost_list; sar; sar = sar->next) { + char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ + unsigned bucket = hash_addr(sar->host_addr); + ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar); + + if (memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, + sar->host_addr->ipaddr_len)) { /* not IN[6]ADDR_ANY */ + *iphash_table_tail[bucket] = ic; + iphash_table_tail[bucket] = &ic->next; + } + else { + /* A wildcard NameVirtualHost goes on the default_list so + * that it can catch incoming requests on any address. + */ + ic->next = default_list; + default_list = ic; + } + /* Notice that what we've done is insert an ipaddr_chain with + * both server and names NULL. This fact is used to spot name- + * based vhosts in add_name_vhost_config(). + */ + } + + /* The next things to go into the hash table are the virtual hosts + * themselves. They're listed off of main_s->next in the reverse + * order they occured in the config file, so we insert them at + * the iphash_table_tail but don't advance the tail. + */ + + for (s = main_s->next; s; s = s->next) { + has_default_vhost_addr = 0; + for (sar = s->addrs; sar; sar = sar->next) { + ipaddr_chain *ic; + char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ + + if ((sar->host_addr->family == AF_INET && + sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) + || !memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) { + ic = find_default_server(sar->host_port); + if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) { + if (ic && ic->sar->host_port != 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, main_s, "_default_ VirtualHost " + "overlap on port %u, the first has " + "precedence", sar->host_port); + } + ic = new_ipaddr_chain(p, s, sar); + ic->next = default_list; + default_list = ic; + } + has_default_vhost_addr = 1; + } + else { + /* see if it matches something we've already got */ + ic = find_ipaddr(sar->host_addr); + + if (!ic) { + unsigned bucket = hash_addr(sar->host_addr); + + ic = new_ipaddr_chain(p, s, sar); + ic->next = *iphash_table_tail[bucket]; + *iphash_table_tail[bucket] = ic; + } + else if (!add_name_vhost_config(p, main_s, s, sar, ic)) { + ap_log_error(APLOG_MARK, APLOG_WARNING, + 0, main_s, "VirtualHost %s:%u overlaps " + "with VirtualHost %s:%u, the first has " + "precedence, perhaps you need a " + "NameVirtualHost directive", + sar->virthost, sar->host_port, + ic->sar->virthost, ic->sar->host_port); + ic->sar = sar; + ic->server = s; + } + } + } + + /* Ok now we want to set up a server_hostname if the user was + * silly enough to forget one. + * XXX: This is silly we should just crash and burn. + */ + if (!s->server_hostname) { + if (has_default_vhost_addr) { + s->server_hostname = main_s->server_hostname; + } + else if (!s->addrs) { + /* what else can we do? at this point this vhost has + no configured name, probably because they used + DNS in the VirtualHost statement. It's disabled + anyhow by the host matching code. -djg */ + s->server_hostname = + apr_pstrdup(p, "bogus_host_without_forward_dns"); + } + else { + apr_status_t rv; + char *hostname; + + rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0); + if (rv == APR_SUCCESS) { + s->server_hostname = apr_pstrdup(p, hostname); + } + else { + /* again, what can we do? They didn't specify a + ServerName, and their DNS isn't working. -djg */ + char *ipaddr_str; + + apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr); + ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s, + "Failed to resolve server name " + "for %s (check DNS) -- or specify an explicit " + "ServerName", + ipaddr_str); + s->server_hostname = + apr_pstrdup(p, "bogus_host_without_reverse_dns"); + } + } + } + } + + /* now go through and delete any NameVirtualHosts that didn't have any + * hosts associated with them. Lamers. + */ + for (i = 0; i < IPHASH_TABLE_SIZE; ++i) { + remove_unused_name_vhosts(main_s, &iphash_table[i]); + } + remove_unused_name_vhosts(main_s, &default_list); + +#ifdef IPHASH_STATISTICS + dump_iphash_statistics(main_s); +#endif + if (ap_exists_config_define("DUMP_VHOSTS")) { + apr_file_t *thefile = NULL; + apr_file_open_stderr(&thefile, p); + dump_vhost_config(thefile); + } +} + + +/***************************************************************************** + * run-time vhost matching functions + */ + +/* Lowercase and remove any trailing dot and/or :port from the hostname, + * and check that it is sane. + * + * In most configurations the exact syntax of the hostname isn't + * important so strict sanity checking isn't necessary. However, in + * mass hosting setups (using mod_vhost_alias or mod_rewrite) where + * the hostname is interpolated into the filename, we need to be sure + * that the interpolation doesn't expose parts of the filesystem. + * We don't do strict RFC 952 / RFC 1123 syntax checking in order + * to support iDNS and people who erroneously use underscores. + * Instead we just check for filesystem metacharacters: directory + * separators / and \ and sequences of more than one dot. + */ +static void fix_hostname(request_rec *r) +{ + char *host, *scope_id; + char *dst; + apr_port_t port; + apr_status_t rv; + + /* According to RFC 2616, Host header field CAN be blank. */ + if (!*r->hostname) { + return; + } + + rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); + if (rv != APR_SUCCESS || scope_id) { + goto bad; + } + + if (!host && port) { + /* silly looking host ("Host: 123") but that isn't our job + * here to judge; apr_parse_addr_port() would think we had a port + * but no address + */ + host = apr_itoa(r->pool, (int)port); + } + else if (port) { + /* Don't throw the Host: header's port number away: + save it in parsed_uri -- ap_get_server_port() needs it! */ + /* @@@ XXX there should be a better way to pass the port. + * Like r->hostname, there should be a r->portno + */ + r->parsed_uri.port = port; + r->parsed_uri.port_str = apr_itoa(r->pool, (int)port); + } + + /* if the hostname is an IPv6 numeric address string, it was validated + * already; otherwise, further validation is needed + */ + if (r->hostname[0] != '[') { + for (dst = host; *dst; dst++) { + if (apr_islower(*dst)) { + /* leave char unchanged */ + } + else if (*dst == '.') { + if (*(dst + 1) == '.') { + goto bad; + } + } + else if (apr_isupper(*dst)) { + *dst = apr_tolower(*dst); + } + else if (*dst == '/' || *dst == '\\') { + goto bad; + } + } + /* strip trailing gubbins */ + if (dst > host && dst[-1] == '.') { + dst[-1] = '\0'; + } + } + r->hostname = host; + return; + +bad: + r->status = HTTP_BAD_REQUEST; + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Client sent malformed Host header"); + return; +} + + +/* return 1 if host matches ServerName or ServerAliases */ +static int matches_aliases(server_rec *s, const char *host) +{ + int i; + apr_array_header_t *names; + + /* match ServerName */ + if (!strcasecmp(host, s->server_hostname)) { + return 1; + } + + /* search all the aliases from ServerAlias directive */ + names = s->names; + if (names) { + char **name = (char **) names->elts; + for (i = 0; i < names->nelts; ++i) { + if(!name[i]) continue; + if (!strcasecmp(host, name[i])) + return 1; + } + } + names = s->wild_names; + if (names) { + char **name = (char **) names->elts; + for (i = 0; i < names->nelts; ++i) { + if(!name[i]) continue; + if (!ap_strcasecmp_match(host, name[i])) + return 1; + } + } + return 0; +} + + +/* Suppose a request came in on the same socket as this r, and included + * a header "Host: host:port", would it map to r->server? It's more + * than just that though. When we do the normal matches for each request + * we don't even bother considering Host: etc on non-namevirtualhosts, + * we just call it a match. But here we require the host:port to match + * the ServerName and/or ServerAliases. + */ +AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host, + apr_port_t port) +{ + server_rec *s; + server_addr_rec *sar; + + s = r->server; + + /* search all the values */ + /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing + * consider: + * + * NameVirtualHost 10.1.1.1 + * + * ServerName v1 + * + * + * ServerName v2 + * + * + * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say + * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1 + * it would really go to v1. + */ + for (sar = s->addrs; sar; sar = sar->next) { + if ((sar->host_port == 0 || port == sar->host_port) + && !strcasecmp(host, sar->virthost)) { + return 1; + } + } + + /* the Port has to match now, because the rest don't have ports associated + * with them. */ + if (port != s->port) { + return 0; + } + + return matches_aliases(s, host); +} + + +static void check_hostalias(request_rec *r) +{ + /* + * Even if the request has a Host: header containing a port we ignore + * that port. We always use the physical port of the socket. There + * are a few reasons for this: + * + * - the default of 80 or 443 for SSL is easier to handle this way + * - there is less of a possibility of a security problem + * - it simplifies the data structure + * - the client may have no idea that a proxy somewhere along the way + * translated the request to another ip:port + * - except for the addresses from the VirtualHost line, none of the other + * names we'll match have ports associated with them + */ + const char *host = r->hostname; + apr_port_t port; + server_rec *s; + server_rec *last_s; + name_chain *src; + + last_s = NULL; + + port = r->connection->local_addr->port; + + /* Recall that the name_chain is a list of server_addr_recs, some of + * whose ports may not match. Also each server may appear more than + * once in the chain -- specifically, it will appear once for each + * address from its VirtualHost line which matched. We only want to + * do the full ServerName/ServerAlias comparisons once for each + * server, fortunately we know that all the VirtualHost addresses for + * a single server are adjacent to each other. + */ + + for (src = r->connection->vhost_lookup_data; src; src = src->next) { + server_addr_rec *sar; + + /* We only consider addresses on the name_chain which have a matching + * port + */ + sar = src->sar; + if (sar->host_port != 0 && port != sar->host_port) { + continue; + } + + s = src->server; + + /* does it match the virthost from the sar? */ + if (!strcasecmp(host, sar->virthost)) { + goto found; + } + + if (s == last_s) { + /* we've already done ServerName and ServerAlias checks for this + * vhost + */ + continue; + } + last_s = s; + + if (matches_aliases(s, host)) { + goto found; + } + } + return; + +found: + /* s is the first matching server, we're done */ + r->server = s; +} + + +static void check_serverpath(request_rec *r) +{ + server_rec *s; + server_rec *last_s; + name_chain *src; + apr_port_t port; + + port = r->connection->local_addr->port; + + /* + * This is in conjunction with the ServerPath code in http_core, so we + * get the right host attached to a non- Host-sending request. + * + * See the comment in check_hostalias about how each vhost can be + * listed multiple times. + */ + + last_s = NULL; + for (src = r->connection->vhost_lookup_data; src; src = src->next) { + /* We only consider addresses on the name_chain which have a matching + * port + */ + if (src->sar->host_port != 0 && port != src->sar->host_port) { + continue; + } + + s = src->server; + if (s == last_s) { + continue; + } + last_s = s; + + if (s->path && !strncmp(r->uri, s->path, s->pathlen) && + (s->path[s->pathlen - 1] == '/' || + r->uri[s->pathlen] == '/' || + r->uri[s->pathlen] == '\0')) { + r->server = s; + return; + } + } +} + + +AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r) +{ + /* must set this for HTTP/1.1 support */ + if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) { + fix_hostname(r); + if (r->status != HTTP_OK) + return; + } + /* check if we tucked away a name_chain */ + if (r->connection->vhost_lookup_data) { + if (r->hostname) + check_hostalias(r); + else + check_serverpath(r); + } +} + +/** + * For every virtual host on this connection, call func_cb. + */ +AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn, + ap_vhost_iterate_conn_cb func_cb, + void* baton) +{ + server_rec *s; + server_rec *last_s; + name_chain *src; + apr_port_t port; + int rv = 0; + + if (conn->vhost_lookup_data) { + last_s = NULL; + port = conn->local_addr->port; + + for (src = conn->vhost_lookup_data; src; src = src->next) { + server_addr_rec *sar; + + /* We only consider addresses on the name_chain which have a + * matching port. + */ + sar = src->sar; + if (sar->host_port != 0 && port != sar->host_port) { + continue; + } + + s = src->server; + + if (s == last_s) { + /* we've already done a callback for this vhost. */ + continue; + } + + last_s = s; + + rv = func_cb(baton, conn, s); + + if (rv != 0) { + break; + } + } + } + else { + rv = func_cb(baton, conn, conn->base_server); + } + + return rv; +} + +/* Called for a new connection which has a known local_addr. Note that the + * new connection is assumed to have conn->server == main server. + */ +AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn) +{ + ipaddr_chain *trav; + apr_port_t port; + + /* scan the hash table for an exact match first */ + trav = find_ipaddr(conn->local_addr); + + if (trav) { + /* save the name_chain for later in case this is a name-vhost */ + conn->vhost_lookup_data = trav->names; + conn->base_server = trav->server; + return; + } + + /* maybe there's a default server or wildcard name-based vhost + * matching this port + */ + port = conn->local_addr->port; + + trav = find_default_server(port); + if (trav) { + conn->vhost_lookup_data = trav->names; + conn->base_server = trav->server; + return; + } + + /* otherwise we're stuck with just the main server + * and no name-based vhosts + */ + conn->vhost_lookup_data = NULL; +} diff --git a/trunk/srclib/Makefile.in b/trunk/srclib/Makefile.in new file mode 100644 index 0000000000..e58599f9ec --- /dev/null +++ b/trunk/srclib/Makefile.in @@ -0,0 +1,5 @@ + +BUILD_SUBDIRS = $(AP_BUILD_SRCLIB_DIRS) +CLEAN_SUBDIRS = $(AP_CLEAN_SRCLIB_DIRS) + +include $(top_builddir)/build/rules.mk diff --git a/trunk/srclib/pcre/AUTHORS b/trunk/srclib/pcre/AUTHORS new file mode 100644 index 0000000000..00bd1d0642 --- /dev/null +++ b/trunk/srclib/pcre/AUTHORS @@ -0,0 +1,6 @@ +Written by: Philip Hazel + +University of Cambridge Computing Service, +Cambridge, England. Phone: +44 1223 334714. + +Copyright (c) 1997-2004 University of Cambridge diff --git a/trunk/srclib/pcre/COPYING b/trunk/srclib/pcre/COPYING new file mode 100644 index 0000000000..1573583b6c --- /dev/null +++ b/trunk/srclib/pcre/COPYING @@ -0,0 +1,45 @@ +PCRE LICENCE +------------ + +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + +Release 5 of PCRE is distributed under the terms of the "BSD" licence, as +specified below. The documentation for PCRE, supplied in the "doc" +directory, is distributed under the same terms as the software itself. + +Written by: Philip Hazel + +University of Cambridge Computing Service, +Cambridge, England. Phone: +44 1223 334714. + +Copyright (c) 1997-2004 University of Cambridge +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. + +End diff --git a/trunk/srclib/pcre/ChangeLog b/trunk/srclib/pcre/ChangeLog new file mode 100644 index 0000000000..266cb18cea --- /dev/null +++ b/trunk/srclib/pcre/ChangeLog @@ -0,0 +1,1650 @@ +ChangeLog for PCRE +------------------ + +Version 5.0 13-Sep-04 +--------------------- + + 1. Internal change: literal characters are no longer packed up into items + containing multiple characters in a single byte-string. Each character + is now matched using a separate opcode. However, there may be more than one + byte in the character in UTF-8 mode. + + 2. The pcre_callout_block structure has two new fields: pattern_position and + next_item_length. These contain the offset in the pattern to the next match + item, and its length, respectively. + + 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic + insertion of callouts before each pattern item. Added the /C option to + pcretest to make use of this. + + 4. On the advice of a Windows user, the lines + + #if defined(_WIN32) || defined(WIN32) + _setmode( _fileno( stdout ), 0x8000 ); + #endif /* defined(_WIN32) || defined(WIN32) */ + + have been added to the source of pcretest. This apparently does useful + magic in relation to line terminators. + + 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb" + for the benefit of those environments where the "b" makes a difference. + + 6. The icc compiler has the same options as gcc, but "configure" doesn't seem + to know about it. I have put a hack into configure.in that adds in code + to set GCC=yes if CC=icc. This seems to end up at a point in the + generated configure script that is early enough to affect the setting of + compiler options, which is what is needed, but I have no means of testing + whether it really works. (The user who reported this had patched the + generated configure script, which of course I cannot do.) + + LATER: After change 22 below (new libtool files), the configure script + seems to know about icc (and also ecc). Therefore, I have commented out + this hack in configure.in. + + 7. Added support for pkg-config (2 patches were sent in). + + 8. Negated POSIX character classes that used a combination of internal tables + were completely broken. These were [[:^alpha:]], [[:^alnum:]], and + [[:^ascii]]. Typically, they would match almost any characters. The other + POSIX classes were not broken in this way. + + 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed + to find the match, as PCRE was deluded into thinking that the match had to + start at the start point or following a newline. The same bug applied to + patterns with negative forward assertions or any backward assertions + preceding ".*" at the start, unless the pattern required a fixed first + character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed. + +10. In UTF-8 mode, when moving forwards in the subject after a failed match + starting at the last subject character, bytes beyond the end of the subject + string were read. + +11. Renamed the variable "class" as "classbits" to make life easier for C++ + users. (Previously there was a macro definition, but it apparently wasn't + enough.) + +12. Added the new field "tables" to the extra data so that tables can be passed + in at exec time, or the internal tables can be re-selected. This allows + a compiled regex to be saved and re-used at a later time by a different + program that might have everything at different addresses. + +13. Modified the pcre-config script so that, when run on Solaris, it shows a + -R library as well as a -L library. + +14. The debugging options of pcretest (-d on the command line or D on a + pattern) showed incorrect output for anything following an extended class + that contained multibyte characters and which was followed by a quantifier. + +15. Added optional support for general category Unicode character properties + via the \p, \P, and \X escapes. Unicode property support implies UTF-8 + support. It adds about 90K to the size of the library. The meanings of the + inbuilt class escapes such as \d and \s have NOT been changed. + +16. Updated pcredemo.c to include calls to free() to release the memory for the + compiled pattern. + +17. The generated file chartables.c was being created in the source directory + instead of in the building directory. This caused the build to fail if the + source directory was different from the building directory, and was + read-only. + +18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE + file. No doubt somebody will tell me if they don't make sense... Also added + Dan Mooney's comments about building on OpenVMS. + +19. Added support for partial matching via the PCRE_PARTIAL option for + pcre_exec() and the \P data escape in pcretest. + +20. Extended pcretest with 3 new pattern features: + + (i) A pattern option of the form ">rest-of-line" causes pcretest to + write the compiled pattern to the file whose name is "rest-of-line". + This is a straight binary dump of the data, with the saved pointer to + the character tables forced to be NULL. The study data, if any, is + written too. After writing, pcretest reads a new pattern. + + (ii) If, instead of a pattern, ": new target + : new target + : use native compiler + : use native linker + : handle Windows platform correctly + : ditto + : ditto + copy DLL to top builddir before testing + + As part of these changes, -no-undefined was removed again. This was reported + to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea + in any case. + +3. Some tidies to get rid of compiler warnings: + + . In the match_data structure, match_limit was an unsigned long int, whereas + match_call_count was an int. I've made them both unsigned long ints. + + . In pcretest the fact that a const uschar * doesn't automatically cast to + a void * provoked a warning. + + . Turning on some more compiler warnings threw up some "shadow" variables + and a few more missing casts. + +4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8 + option, a class that contained a single character with a value between 128 + and 255 (e.g. /[\xFF]/) caused PCRE to crash. + +5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8 + option, a class that contained several characters, but with at least one + whose value was between 128 and 255 caused PCRE to crash. + + +Version 4.1 12-Mar-03 +--------------------- + +1. Compiling with gcc -pedantic found a couple of places where casts were +needed, and a string in dftables.c that was longer than standard compilers are +required to support. + +2. Compiling with Sun's compiler found a few more places where the code could +be tidied up in order to avoid warnings. + +3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the +first of these names is deprecated in the latest Autoconf in favour of the name +CC_FOR_BUILD, because "host" is typically used to mean the system on which the +compiled code will be run. I can't find a reference for HOST_CFLAGS, but by +analogy I have changed it to CFLAGS_FOR_BUILD. + +4. Added -no-undefined to the linking command in the Makefile, because this is +apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the +linking step for the pcreposix library. + +5. PCRE was failing to diagnose the case of two named groups with the same +name. + +6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a +literal character that is needed in the subject for a match, and scans along to +ensure that it is present before embarking on the full matching process. This +saves time in cases of nested unlimited repeats that are never going to match. +Problem: the scan can take a lot of time if the subject is very long (e.g. +megabytes), thus penalizing straightforward matches. It is now done only if the +amount of subject to be scanned is less than 1000 bytes. + +7. A lesser problem with the same optimization is that it was recording the +first character of an anchored pattern as "needed", thus provoking a search +right along the subject, even when the first match of the pattern was going to +fail. The "needed" character is now not set for anchored patterns, unless it +follows something in the pattern that is of non-fixed length. Thus, it still +fulfils its original purpose of finding quick non-matches in cases of nested +unlimited repeats, but isn't used for simple anchored patterns such as /^abc/. + + +Version 4.0 17-Feb-03 +--------------------- + +1. If a comment in an extended regex that started immediately after a meta-item +extended to the end of string, PCRE compiled incorrect data. This could lead to +all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not. + +2. Moved to autoconf 2.53 and libtool 1.4.2. + +3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently, +the special perltest8 script is no longer needed - all the tests can be run +from a single perltest script. + +4. From 5.004, Perl has not included the VT character (0x0b) in the set defined +by \s. It has now been removed in PCRE. This means it isn't recognized as +whitespace in /x regexes too, which is the same as Perl. Note that the POSIX +class [:space:] *does* include VT, thereby creating a mess. + +5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only +space and tab. + +6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use +its new features into the main test script, reducing the number of scripts. + +7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions +were backward compatible, and made the (?i) apply to the whole pattern, as if +/i were given. Now it behaves more logically, and applies the option setting +only to what follows. PCRE has been changed to follow suit. However, if it +finds options settings right at the start of the pattern, it extracts them into +the global options, as before. Thus, they show up in the info data. + +8. Added support for the \Q...\E escape sequence. Characters in between are +treated as literals. This is slightly different from Perl in that $ and @ are +also handled as literals inside the quotes. In Perl, they will cause variable +interpolation. Note the following examples: + + Pattern PCRE matches Perl matches + + \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz + \Qabc\$xyz\E abc\$xyz abc\$xyz + \Qabc\E\$\Qxyz\E abc$xyz abc$xyz + +For compatibility with Perl, \Q...\E sequences are recognized inside character +classes as well as outside them. + +9. Re-organized 3 code statements in pcretest to avoid "overflow in +floating-point constant arithmetic" warnings from a Microsoft compiler. Added a +(size_t) cast to one statement in pcretest and one in pcreposix to avoid +signed/unsigned warnings. + +10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o +option for pcretest, so I've replaced it by a simple function that does just +that job. + +11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or +"pcregrep -". + +12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's +Java package. This provides some syntactic sugar for simple cases of what my +documentation calls "once-only subpatterns". A pattern such as x*+ is the same +as (?>x*). In other words, if what is inside (?>...) is just a single repeated +item, you can use this simplified notation. Note that only makes sense with +greedy quantifiers. Consequently, the use of the possessive quantifier forces +greediness, whatever the setting of the PCRE_UNGREEDY option. + +13. A change of greediness default within a pattern was not taking effect at +the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized +subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option +was abstracted outside. + +14. PCRE now supports the \G assertion. It is true when the current matching +position is at the start point of the match. This differs from \A when the +starting offset is non-zero. Used with the /g option of pcretest (or similar +code), it works in the same way as it does for Perl's /g option. If all +alternatives of a regex begin with \G, the expression is anchored to the start +match position, and the "anchored" flag is set in the compiled expression. + +15. Some bugs concerning the handling of certain option changes within patterns +have been fixed. These applied to options other than (?ims). For example, +"a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have +been the other way round. Some of this was related to change 7 above. + +16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX +features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/ +and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports +POSIX classes only within a class (e.g. /[[:alpha:]]/). + +17. Added support for Perl's \C escape. This matches one byte, even in UTF8 +mode. Unlike ".", it always matches newline, whatever the setting of +PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind +assertions. Perl allows it, but it doesn't (in general) work because it can't +calculate the length of the lookbehind. At least, that's the case for Perl +5.8.0 - I've been told they are going to document that it doesn't work in +future. + +18. Added an error diagnosis for escapes that PCRE does not support: these are +\L, \l, \N, \P, \p, \U, \u, and \X. + +19. Although correctly diagnosing a missing ']' in a character class, PCRE was +reading past the end of the pattern in cases such as /[abcd/. + +20. PCRE was getting more memory than necessary for patterns with classes that +contained both POSIX named classes and other characters, e.g. /[[:space:]abc/. + +21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for +compiling PCRE for use with Virtual Pascal. + +22. Small fix to the Makefile to make it work properly if the build is done +outside the source tree. + +23. Added a new extension: a condition to go with recursion. If a conditional +subpattern starts with (?(R) the "true" branch is used if recursion has +happened, whereas the "false" branch is used only at the top level. + +24. When there was a very long string of literal characters (over 255 bytes +without UTF support, over 250 bytes with UTF support), the computation of how +much memory was required could be incorrect, leading to segfaults or other +strange effects. + +25. PCRE was incorrectly assuming anchoring (either to start of subject or to +start of line for a non-DOTALL pattern) when a pattern started with (.*) and +there was a subsequent back reference to those brackets. This meant that, for +example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't +possible to check for precisely this case. All we can do is abandon the +optimization if .* occurs inside capturing brackets when there are any back +references whatsoever. (See below for a better fix that came later.) + +26. The handling of the optimization for finding the first character of a +non-anchored pattern, and for finding a character that is required later in the +match were failing in some cases. This didn't break the matching; it just +failed to optimize when it could. The way this is done has been re-implemented. + +27. Fixed typo in error message for invalid (?R item (it said "(?p"). + +28. Added a new feature that provides some of the functionality that Perl +provides with (?{...}). The facility is termed a "callout". The way it is done +in PCRE is for the caller to provide an optional function, by setting +pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a +global variable. By default it is unset, which disables all calling out. To get +the function called, the regex must include (?C) at appropriate points. This +is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C). +This provides a means of identifying different callout points. When PCRE +reaches such a point in the regex, if pcre_callout has been set, the external +function is called. It is provided with data in a structure called +pcre_callout_block, which is defined in pcre.h. If the function returns 0, +matching continues; if it returns a non-zero value, the match at the current +point fails. However, backtracking will occur if possible. [This was changed +later and other features added - see item 49 below.] + +29. pcretest is upgraded to test the callout functionality. It provides a +callout function that displays information. By default, it shows the start of +the match and the current position in the text. There are some new data escapes +to vary what happens: + + \C+ in addition, show current contents of captured substrings + \C- do not supply a callout function + \C!n return 1 when callout number n is reached + \C!n!m return 1 when callout number n is reached for the mth time + +30. If pcregrep was called with the -l option and just a single file name, it +output "" if a match was found, instead of the file name. + +31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing +slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to +pcre_exec(). This saves a malloc/free per call. The default value of +POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold +when configuring. + +32. The default maximum size of a compiled pattern is 64K. There have been a +few cases of people hitting this limit. The code now uses macros to handle the +storing of links as offsets within the compiled pattern. It defaults to 2-byte +links, but this can be changed to 3 or 4 bytes by --with-link-size when +configuring. Tests 2 and 5 work only with 2-byte links because they output +debugging information about compiled patterns. + +33. Internal code re-arrangements: + +(a) Moved the debugging function for printing out a compiled regex into + its own source file (printint.c) and used #include to pull it into + pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two + separate copies. + +(b) Defined the list of op-code names for debugging as a macro in + internal.h so that it is next to the definition of the opcodes. + +(c) Defined a table of op-code lengths for simpler skipping along compiled + code. This is again a macro in internal.h so that it is next to the + definition of the opcodes. + +34. Added support for recursive calls to individual subpatterns, along the +lines of Robin Houston's patch (but implemented somewhat differently). + +35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to +allow it to read and process whole directories in Win32. This code was +contributed by Lionel Fourquaux; it has not been tested by me. + +36. Added support for named subpatterns. The Python syntax (?P...) is +used to name a group. Names consist of alphanumerics and underscores, and must +be unique. Back references use the syntax (?P=name) and recursive calls use +(?P>name) which is a PCRE extension to the Python extension. Groups still have +numbers. The function pcre_fullinfo() can be used after compilation to extract +a name/number map. There are three relevant calls: + + PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map + PCRE_INFO_NAMECOUNT yields the number of entries + PCRE_INFO_NAMETABLE yields a pointer to the map. + +The map is a vector of fixed-size entries. The size of each entry depends on +the length of the longest name used. The first two bytes of each entry are the +group number, most significant byte first. There follows the corresponding +name, zero terminated. The names are in alphabetical order. + +37. Make the maximum literal string in the compiled code 250 for the non-UTF-8 +case instead of 255. Making it the same both with and without UTF-8 support +means that the same test output works with both. + +38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid +calling malloc() with a zero argument. + +39. Change 25 above had to resort to a heavy-handed test for the .* anchoring +optimization. I've improved things by keeping a bitmap of backreferences with +numbers 1-31 so that if .* occurs inside capturing brackets that are not in +fact referenced, the optimization can be applied. It is unlikely that a +relevant occurrence of .* (i.e. one which might indicate anchoring or forcing +the match to follow \n) will appear inside brackets with a number greater than +31, but if it does, any back reference > 31 suppresses the optimization. + +40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect +of disabling numbered capturing parentheses. Any opening parenthesis that is +not followed by ? behaves as if it were followed by ?: but named parentheses +can still be used for capturing (and they will acquire numbers in the usual +way). + +41. Redesigned the return codes from the match() function into yes/no/error so +that errors can be passed back from deep inside the nested calls. A malloc +failure while inside a recursive subpattern call now causes the +PCRE_ERROR_NOMEMORY return instead of quietly going wrong. + +42. It is now possible to set a limit on the number of times the match() +function is called in a call to pcre_exec(). This facility makes it possible to +limit the amount of recursion and backtracking, though not in a directly +obvious way, because the match() function is used in a number of different +circumstances. The count starts from zero for each position in the subject +string (for non-anchored patterns). The default limit is, for compatibility, a +large number, namely 10 000 000. You can change this in two ways: + +(a) When configuring PCRE before making, you can use --with-match-limit=n + to set a default value for the compiled library. + +(b) For each call to pcre_exec(), you can pass a pcre_extra block in which + a different value is set. See 45 below. + +If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. + +43. Added a new function pcre_config(int, void *) to enable run-time extraction +of things that can be changed at compile time. The first argument specifies +what is wanted and the second points to where the information is to be placed. +The current list of available information is: + + PCRE_CONFIG_UTF8 + +The output is an integer that is set to one if UTF-8 support is available; +otherwise it is set to zero. + + PCRE_CONFIG_NEWLINE + +The output is an integer that it set to the value of the code that is used for +newline. It is either LF (10) or CR (13). + + PCRE_CONFIG_LINK_SIZE + +The output is an integer that contains the number of bytes used for internal +linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above. + + PCRE_CONFIG_POSIX_MALLOC_THRESHOLD + +The output is an integer that contains the threshold above which the POSIX +interface uses malloc() for output vectors. See item 31 above. + + PCRE_CONFIG_MATCH_LIMIT + +The output is an unsigned integer that contains the default limit of the number +of match() calls in a pcre_exec() execution. See 42 above. + +44. pcretest has been upgraded by the addition of the -C option. This causes it +to extract all the available output from the new pcre_config() function, and to +output it. The program then exits immediately. + +45. A need has arisen to pass over additional data with calls to pcre_exec() in +order to support additional features. One way would have been to define +pcre_exec2() (for example) with extra arguments, but this would not have been +extensible, and would also have required all calls to the original function to +be mapped to the new one. Instead, I have chosen to extend the mechanism that +is used for passing in "extra" data from pcre_study(). + +The pcre_extra structure is now exposed and defined in pcre.h. It currently +contains the following fields: + + flags a bitmap indicating which of the following fields are set + study_data opaque data from pcre_study() + match_limit a way of specifying a limit on match() calls for a specific + call to pcre_exec() + callout_data data for callouts (see 49 below) + +The flag bits are also defined in pcre.h, and are + + PCRE_EXTRA_STUDY_DATA + PCRE_EXTRA_MATCH_LIMIT + PCRE_EXTRA_CALLOUT_DATA + +The pcre_study() function now returns one of these new pcre_extra blocks, with +the actual study data pointed to by the study_data field, and the +PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as +before. That is, this change is entirely upwards-compatible and requires no +change to existing code. + +If you want to pass in additional data to pcre_exec(), you can either place it +in a pcre_extra block provided by pcre_study(), or create your own pcre_extra +block. + +46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a +data string contains the escape sequence \M, pcretest calls pcre_exec() several +times with different match limits, until it finds the minimum value needed for +pcre_exec() to complete. The value is then output. This can be instructive; for +most simple matches the number is quite small, but for pathological cases it +gets very large very quickly. + +47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It +returns the size of the data block pointed to by the study_data field in a +pcre_extra block, that is, the value that was passed as the argument to +pcre_malloc() when PCRE was getting memory in which to place the information +created by pcre_study(). The fourth argument should point to a size_t variable. +pcretest has been extended so that this information is shown after a successful +pcre_study() call when information about the compiled regex is being displayed. + +48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR) +because what follows is always an absolute path. (Later: it turns out that this +is more than cosmetic for MinGW, because it doesn't like empty path +components.) + +49. Some changes have been made to the callout feature (see 28 above): + +(i) A callout function now has three choices for what it returns: + + 0 => success, carry on matching + > 0 => failure at this point, but backtrack if possible + < 0 => serious error, return this value from pcre_exec() + + Negative values should normally be chosen from the set of PCRE_ERROR_xxx + values. In particular, returning PCRE_ERROR_NOMATCH forces a standard + "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for + use by callout functions. It will never be used by PCRE itself. + +(ii) The pcre_extra structure (see 45 above) has a void * field called + callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The + pcre_callout_block structure has a field of the same name. The contents of + the field passed in the pcre_extra structure are passed to the callout + function in the corresponding field in the callout block. This makes it + easier to use the same callout-containing regex from multiple threads. For + testing, the pcretest program has a new data escape + + \C*n pass the number n (may be negative) as callout_data + + If the callout function in pcretest receives a non-zero value as + callout_data, it returns that value. + +50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also, +there were some redundant $(CFLAGS) in commands that are now specified as +$(LINK), which already includes $(CFLAGS). + +51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE +has been compiled with UTF-8 support *and* pcre_compile() has been compiled +with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume +one-byte characters throughout. Note that case-insensitive matching applies +only to characters whose values are less than 256. PCRE doesn't support the +notion of cases for higher-valued characters. + +(i) A character class whose characters are all within 0-255 is handled as + a bit map, and the map is inverted for negative classes. Previously, a + character > 255 always failed to match such a class; however it should + match if the class was a negative one (e.g. [^ab]). This has been fixed. + +(ii) A negated character class with a single character < 255 is coded as + "not this character" (OP_NOT). This wasn't working properly when the test + character was multibyte, either singly or repeated. + +(iii) Repeats of multibyte characters are now handled correctly in UTF-8 + mode, for example: \x{100}{2,3}. + +(iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either + singly or repeated) now correctly test multibyte characters. However, + PCRE doesn't recognize any characters with values greater than 255 as + digits, spaces, or word characters. Such characters always match \D, \S, + and \W, and never match \d, \s, or \w. + +(v) Classes may now contain characters and character ranges with values + greater than 255. For example: [ab\x{100}-\x{400}]. + +(vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call + PCRE in UTF-8 mode. + +52. The info request value PCRE_INFO_FIRSTCHAR has been renamed +PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is +retained for backwards compatibility. (Note that LASTLITERAL is also a byte +value.) + +53. The single man page has become too large. I have therefore split it up into +a number of separate man pages. These also give rise to individual HTML pages; +these are now put in a separate directory, and there is an index.html page that +lists them all. Some hyperlinking between the pages has been installed. + +54. Added convenience functions for handling named capturing parentheses. + +55. Unknown escapes inside character classes (e.g. [\M]) and escapes that +aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also +true in PCRE, except when the PCRE_EXTENDED option is set, in which case they +are faulted. + +56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when +calling configure. These values are used when compiling the dftables.c program +which is run to generate the source of the default character tables. They +default to the values of CC and CFLAGS. If you are cross-compiling PCRE, +you will need to set these values. + +57. Updated the building process for Windows DLL, as provided by Fred Cox. + + +Version 3.9 02-Jan-02 +--------------------- + +1. A bit of extraneous text had somehow crept into the pcregrep documentation. + +2. If --disable-static was given, the building process failed when trying to +build pcretest and pcregrep. (For some reason it was using libtool to compile +them, which is not right, as they aren't part of the library.) + + +Version 3.8 18-Dec-01 +--------------------- + +1. The experimental UTF-8 code was completely screwed up. It was packing the +bytes in the wrong order. How dumb can you get? + + +Version 3.7 29-Oct-01 +--------------------- + +1. In updating pcretest to check change 1 of version 3.6, I screwed up. +This caused pcretest, when used on the test data, to segfault. Unfortunately, +this didn't happen under Solaris 8, where I normally test things. + +2. The Makefile had to be changed to make it work on BSD systems, where 'make' +doesn't seem to recognize that ./xxx and xxx are the same file. (This entry +isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made +this fix an hour or so after the initial 3.7 release.) + + +Version 3.6 23-Oct-01 +--------------------- + +1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if +offsets passed as NULL with zero offset count. + +2. The config.guess and config.sub files had not been updated when I moved to +the latest autoconf. + + +Version 3.5 15-Aug-01 +--------------------- + +1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that +had been forgotten. + +2. By using declared but undefined structures, we can avoid using "void" +definitions in pcre.h while keeping the internal definitions of the structures +private. + +3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a +user point of view, this means that both static and shared libraries are built +by default, but this can be individually controlled. More of the work of +handling this static/shared cases is now inside libtool instead of PCRE's make +file. + +4. The pcretest utility is now installed along with pcregrep because it is +useful for users (to test regexs) and by doing this, it automatically gets +relinked by libtool. The documentation has been turned into a man page, so +there are now .1, .txt, and .html versions in /doc. + +5. Upgrades to pcregrep: + (i) Added long-form option names like gnu grep. + (ii) Added --help to list all options with an explanatory phrase. + (iii) Added -r, --recursive to recurse into sub-directories. + (iv) Added -f, --file to read patterns from a file. + +6. pcre_exec() was referring to its "code" argument before testing that +argument for NULL (and giving an error if it was NULL). + +7. Upgraded Makefile.in to allow for compiling in a different directory from +the source directory. + +8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the +options bits, the pointer it was passed was to an int instead of to an unsigned +long int. This mattered only on 64-bit systems. + +9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is +generated) instead of pcre.in, which it its source. Also made the same change +in several of the .c files. + +10. A new release of gcc defines printf() as a macro, which broke pcretest +because it had an ifdef in the middle of a string argument for printf(). Fixed +by using separate calls to printf(). + +11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure +script, to force use of CR or LF instead of \n in the source. On non-Unix +systems, the value can be set in config.h. + +12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an +absolute limit. Changed the text of the error message to make this clear, and +likewise updated the man page. + +13. The limit of 99 on the number of capturing subpatterns has been removed. +The new limit is 65535, which I hope will not be a "real" limit. + + +Version 3.4 22-Aug-00 +--------------------- + +1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *. + +2. Diagnose condition (?(0) as an error instead of crashing on matching. + + +Version 3.3 01-Aug-00 +--------------------- + +1. If an octal character was given, but the value was greater than \377, it +was not getting masked to the least significant bits, as documented. This could +lead to crashes in some systems. + +2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats +the hyphen as a literal. PCRE used to give an error; it now behaves like Perl. + +3. Added the functions pcre_free_substring() and pcre_free_substring_list(). +These just pass their arguments on to (pcre_free)(), but they are provided +because some uses of PCRE bind it to non-C systems that can call its functions, +but cannot call free() or pcre_free() directly. + +4. Add "make test" as a synonym for "make check". Corrected some comments in +the Makefile. + +5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the +Makefile. + +6. Changed the name of pgrep to pcregrep, because Solaris has introduced a +command called pgrep for grepping around the active processes. + +7. Added the beginnings of support for UTF-8 character strings. + +8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and +RANLIB to ./ltconfig so that they are used by libtool. I think these are all +the relevant ones. (AR is not passed because ./ltconfig does its own figuring +out for the ar command.) + + +Version 3.2 12-May-00 +--------------------- + +This is purely a bug fixing release. + +1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead +of ZA. This was just one example of several cases that could provoke this bug, +which was introduced by change 9 of version 2.00. The code for breaking +infinite loops after an iteration that matches an empty string was't working +correctly. + +2. The pcretest program was not imitating Perl correctly for the pattern /a*/g +when matched against abbab (for example). After matching an empty string, it +wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this +caused it to match further down the string than it should. + +3. The code contained an inclusion of sys/types.h. It isn't clear why this +was there because it doesn't seem to be needed, and it causes trouble on some +systems, as it is not a Standard C header. It has been removed. + +4. Made 4 silly changes to the source to avoid stupid compiler warnings that +were reported on the Macintosh. The changes were from + + while ((c = *(++ptr)) != 0 && c != '\n'); +to + while ((c = *(++ptr)) != 0 && c != '\n') ; + +Totally extraordinary, but if that's what it takes... + +5. PCRE is being used in one environment where neither memmove() nor bcopy() is +available. Added HAVE_BCOPY and an autoconf test for it; if neither +HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which +assumes the way PCRE uses memmove() (always moving upwards). + +6. PCRE is being used in one environment where strchr() is not available. There +was only one use in pcre.c, and writing it out to avoid strchr() probably gives +faster code anyway. + + +Version 3.2 12-May-00 +--------------------- + +This is purely a bug fixing release. + +1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead +of ZA. This was just one example of several cases that could provoke this bug, +which was introduced by change 9 of version 2.00. The code for breaking +infinite loops after an iteration that matches an empty string was't working +correctly. + +2. The pcretest program was not imitating Perl correctly for the pattern /a*/g +when matched against abbab (for example). After matching an empty string, it +wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this +caused it to match further down the string than it should. + +3. The code contained an inclusion of sys/types.h. It isn't clear why this +was there because it doesn't seem to be needed, and it causes trouble on some +systems, as it is not a Standard C header. It has been removed. + +4. Made 4 silly changes to the source to avoid stupid compiler warnings that +were reported on the Macintosh. The changes were from + + while ((c = *(++ptr)) != 0 && c != '\n'); +to + while ((c = *(++ptr)) != 0 && c != '\n') ; + +Totally extraordinary, but if that's what it takes... + +5. PCRE is being used in one environment where neither memmove() nor bcopy() is +available. Added HAVE_BCOPY and an autoconf test for it; if neither +HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which +assumes the way PCRE uses memmove() (always moving upwards). + +6. PCRE is being used in one environment where strchr() is not available. There +was only one use in pcre.c, and writing it out to avoid strchr() probably gives +faster code anyway. + + +Version 3.1 09-Feb-00 +--------------------- + +The only change in this release is the fixing of some bugs in Makefile.in for +the "install" target: + +(1) It was failing to install pcreposix.h. + +(2) It was overwriting the pcre.3 man page with the pcreposix.3 man page. + + +Version 3.0 01-Feb-00 +--------------------- + +1. Add support for the /+ modifier to perltest (to output $` like it does in +pcretest). + +2. Add support for the /g modifier to perltest. + +3. Fix pcretest so that it behaves even more like Perl for /g when the pattern +matches null strings. + +4. Fix perltest so that it doesn't do unwanted things when fed an empty +pattern. Perl treats empty patterns specially - it reuses the most recent +pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this +effect. + +5. The POSIX interface was broken in that it was just handing over the POSIX +captured string vector to pcre_exec(), but (since release 2.00) PCRE has +required a bigger vector, with some working space on the end. This means that +the POSIX wrapper now has to get and free some memory, and copy the results. + +6. Added some simple autoconf support, placing the test data and the +documentation in separate directories, re-organizing some of the +information files, and making it build pcre-config (a GNU standard). Also added +libtool support for building PCRE as a shared library, which is now the +default. + +7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and +09 are not valid octal constants. Single digits will be used for minor values +less than 10. + +8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that +existing programs that set these in the POSIX interface can use PCRE without +modification. + +9. Added a new function, pcre_fullinfo() with an extensible interface. It can +return all that pcre_info() returns, plus additional data. The pcre_info() +function is retained for compatibility, but is considered to be obsolete. + +10. Added experimental recursion feature (?R) to handle one common case that +Perl 5.6 will be able to do with (?p{...}). + +11. Added support for POSIX character classes like [:alpha:], which Perl is +adopting. + + +Version 2.08 31-Aug-99 +---------------------- + +1. When startoffset was not zero and the pattern began with ".*", PCRE was not +trying to match at the startoffset position, but instead was moving forward to +the next newline as if a previous match had failed. + +2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G, +and could get into a loop if a null string was matched other than at the start +of the subject. + +3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can +be distinguished at compile time, and for completeness also added PCRE_DATE. + +5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL +in GnuWin32 environments. + + +Version 2.07 29-Jul-99 +---------------------- + +1. The documentation is now supplied in plain text form and HTML as well as in +the form of man page sources. + +2. C++ compilers don't like assigning (void *) values to other pointer types. +In particular this affects malloc(). Although there is no problem in Standard +C, I've put in casts to keep C++ compilers happy. + +3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call +should be (const char *). + +4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may +be useful for non-Unix systems who don't want to bother with the POSIX stuff. +However, I haven't made this a standard facility. The documentation doesn't +mention it, and the Makefile doesn't support it. + +5. The Makefile now contains an "install" target, with editable destinations at +the top of the file. The pcretest program is not installed. + +6. pgrep -V now gives the PCRE version number and date. + +7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was +causing the entire string to be ignored, instead of just the last character. + +8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a +non-matching string, it can take a very, very long time, even for strings of +quite modest length, because of the nested recursion. PCRE now does better in +some of these cases. It does this by remembering the last required literal +character in the pattern, and pre-searching the subject to ensure it is present +before running the real match. In other words, it applies a heuristic to detect +some types of certain failure quickly, and in the above example, if presented +with a string that has no trailing " it gives "no match" very quickly. + +9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored; +other alternatives are tried instead. + + +Version 2.06 09-Jun-99 +---------------------- + +1. Change pcretest's output for amount of store used to show just the code +space, because the remainder (the data block) varies in size between 32-bit and +64-bit systems. + +2. Added an extra argument to pcre_exec() to supply an offset in the subject to +start matching at. This allows lookbehinds to work when searching for multiple +occurrences in a string. + +3. Added additional options to pcretest for testing multiple occurrences: + + /+ outputs the rest of the string that follows a match + /g loops for multiple occurrences, using the new startoffset argument + /G loops for multiple occurrences by passing an incremented pointer + +4. PCRE wasn't doing the "first character" optimization for patterns starting +with \b or \B, though it was doing it for other lookbehind assertions. That is, +it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with +the letter 'x'. On long subject strings, this gives a significant speed-up. + + +Version 2.05 21-Apr-99 +---------------------- + +1. Changed the type of magic_number from int to long int so that it works +properly on 16-bit systems. + +2. Fixed a bug which caused patterns starting with .* not to work correctly +when the subject string contained newline characters. PCRE was assuming +anchoring for such patterns in all cases, which is not correct because .* will +not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if +DOTALL is set at top level; otherwise it knows that patterns starting with .* +must be retried after every newline in the subject. + + +Version 2.04 18-Feb-99 +---------------------- + +1. For parenthesized subpatterns with repeats whose minimum was zero, the +computation of the store needed to hold the pattern was incorrect (too large). +If such patterns were nested a few deep, this could multiply and become a real +problem. + +2. Added /M option to pcretest to show the memory requirement of a specific +pattern. Made -m a synonym of -s (which does this globally) for compatibility. + +3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being +compiled in such a way that the backtracking after subsequent failure was +pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of +((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size. + + +Version 2.03 02-Feb-99 +---------------------- + +1. Fixed typo and small mistake in man page. + +2. Added 4th condition (GPL supersedes if conflict) and created separate +LICENCE file containing the conditions. + +3. Updated pcretest so that patterns such as /abc\/def/ work like they do in +Perl, that is the internal \ allows the delimiter to be included in the +pattern. Locked out the use of \ as a delimiter. If \ immediately follows +the final delimiter, add \ to the end of the pattern (to test the error). + +4. Added the convenience functions for extracting substrings after a successful +match. Updated pcretest to make it able to test these functions. + + +Version 2.02 14-Jan-99 +---------------------- + +1. Initialized the working variables associated with each extraction so that +their saving and restoring doesn't refer to uninitialized store. + +2. Put dummy code into study.c in order to trick the optimizer of the IBM C +compiler for OS/2 into generating correct code. Apparently IBM isn't going to +fix the problem. + +3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution +calls, and wasn't printing the correct value for compiling calls. Increased the +default value of LOOPREPEAT, and the number of significant figures in the +times. + +4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT. + +5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid +a building problem on Windows NT with a FAT file system. + + +Version 2.01 21-Oct-98 +---------------------- + +1. Changed the API for pcre_compile() to allow for the provision of a pointer +to character tables built by pcre_maketables() in the current locale. If NULL +is passed, the default tables are used. + + +Version 2.00 24-Sep-98 +---------------------- + +1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable +it any more. + +2. Allow quantification of (?>) groups, and make it work correctly. + +3. The first character computation wasn't working for (?>) groups. + +4. Correct the implementation of \Z (it is permitted to match on the \n at the +end of the subject) and add 5.005's \z, which really does match only at the +very end of the subject. + +5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater. + +6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and +DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005 +localized options. All options to pcre_study() were also removed. + +7. Add other new features from 5.005: + + $(?<= positive lookbehind + $(?a*))*/ (a PCRE_EXTRA facility). + + +Version 1.00 18-Nov-97 +---------------------- + +1. Added compile-time macros to support systems such as SunOS4 which don't have +memmove() or strerror() but have other things that can be used instead. + +2. Arranged that "make clean" removes the executables. + + +Version 0.99 27-Oct-97 +---------------------- + +1. Fixed bug in code for optimizing classes with only one character. It was +initializing a 32-byte map regardless, which could cause it to run off the end +of the memory it had got. + +2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction. + + +Version 0.98 22-Oct-97 +---------------------- + +1. Fixed bug in code for handling temporary memory usage when there are more +back references than supplied space in the ovector. This could cause segfaults. + + +Version 0.97 21-Oct-97 +---------------------- + +1. Added the \X "cut" facility, conditional on PCRE_EXTRA. + +2. Optimized negated single characters not to use a bit map. + +3. Brought error texts together as macro definitions; clarified some of them; +fixed one that was wrong - it said "range out of order" when it meant "invalid +escape sequence". + +4. Changed some char * arguments to const char *. + +5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX). + +6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in +pcretest. + + +Version 0.96 16-Oct-97 +---------------------- + +1. Added a simple "pgrep" utility to the distribution. + +2. Fixed an incompatibility with Perl: "{" is now treated as a normal character +unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}" +where "ddd" means "one or more decimal digits". + +3. Fixed serious bug. If a pattern had a back reference, but the call to +pcre_exec() didn't supply a large enough ovector to record the related +identifying subpattern, the match always failed. PCRE now remembers the number +of the largest back reference, and gets some temporary memory in which to save +the offsets during matching if necessary, in order to ensure that +backreferences always work. + +4. Increased the compatibility with Perl in a number of ways: + + (a) . no longer matches \n by default; an option PCRE_DOTALL is provided + to request this handling. The option can be set at compile or exec time. + + (b) $ matches before a terminating newline by default; an option + PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline + mode). The option can be set at compile or exec time. + + (c) The handling of \ followed by a digit other than 0 is now supposed to be + the same as Perl's. If the decimal number it represents is less than 10 + or there aren't that many previous left capturing parentheses, an octal + escape is read. Inside a character class, it's always an octal escape, + even if it is a single digit. + + (d) An escaped but undefined alphabetic character is taken as a literal, + unless PCRE_EXTRA is set. Currently this just reserves the remaining + escapes. + + (e) {0} is now permitted. (The previous item is removed from the compiled + pattern). + +5. Changed all the names of code files so that the basic parts are no longer +than 10 characters, and abolished the teeny "globals.c" file. + +6. Changed the handling of character classes; they are now done with a 32-byte +bit map always. + +7. Added the -d and /D options to pcretest to make it possible to look at the +internals of compilation without having to recompile pcre. + + +Version 0.95 23-Sep-97 +---------------------- + +1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or +\x20 at the start of a run of normal characters. These were being treated as +real characters, instead of the source characters being re-checked. + + +Version 0.94 18-Sep-97 +---------------------- + +1. The functions are now thread-safe, with the caveat that the global variables +containing pointers to malloc() and free() or alternative functions are the +same for all threads. + +2. Get pcre_study() to generate a bitmap of initial characters for non- +anchored patterns when this is possible, and use it if passed to pcre_exec(). + + +Version 0.93 15-Sep-97 +---------------------- + +1. /(b)|(:+)/ was computing an incorrect first character. + +2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(), +but not actually doing anything yet. + +3. Treat "-" characters in classes that cannot be part of ranges as literals, +as Perl does (e.g. [-az] or [az-]). + +4. Set the anchored flag if a branch starts with .* or .*? because that tests +all possible positions. + +5. Split up into different modules to avoid including unneeded functions in a +compiled binary. However, compile and exec are still in one module. The "study" +function is split off. + +6. The character tables are now in a separate module whose source is generated +by an auxiliary program - but can then be edited by hand if required. There are +now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or +toupper() in the code. + +7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and +make them global. Abolish the function for setting them, as the caller can now +set them directly. + + +Version 0.92 11-Sep-97 +---------------------- + +1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character +(e.g. /a{1,3}/) was broken (I mis-optimized it). + +2. Caseless matching was not working in character classes if the characters in +the pattern were in upper case. + +3. Make ranges like [W-c] work in the same way as Perl for caseless matching. + +4. Make PCRE_ANCHORED public and accept as a compile option. + +5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and +PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to +pass them. + +6. Give an error if bad option bits passed at compile or run time. + +7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to +pcretest to cause it to pass that flag. + +8. Add pcre_info(), to get the number of identifying subpatterns, the stored +options, and the first character, if set. + +9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character. + + +Version 0.91 10-Sep-97 +---------------------- + +1. PCRE was failing to diagnose unlimited repeats of subpatterns that could +match the empty string as in /(a*)*/. It was looping and ultimately crashing. + +2. PCRE was looping on encountering an indefinitely repeated back reference to +a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what +Perl does - treats the match as successful. + +**** diff --git a/trunk/srclib/pcre/INSTALL b/trunk/srclib/pcre/INSTALL new file mode 100644 index 0000000000..08802812de --- /dev/null +++ b/trunk/srclib/pcre/INSTALL @@ -0,0 +1,185 @@ +Basic Installation +================== + + These are generic installation instructions that apply to systems that +can run the `configure' shell script - Unix systems and any that imitate +it. They are not specific to PCRE. There are PCRE-specific instructions +for non-Unix systems in the file NON-UNIX-USE. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/trunk/srclib/pcre/LICENCE b/trunk/srclib/pcre/LICENCE new file mode 100644 index 0000000000..1573583b6c --- /dev/null +++ b/trunk/srclib/pcre/LICENCE @@ -0,0 +1,45 @@ +PCRE LICENCE +------------ + +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + +Release 5 of PCRE is distributed under the terms of the "BSD" licence, as +specified below. The documentation for PCRE, supplied in the "doc" +directory, is distributed under the same terms as the software itself. + +Written by: Philip Hazel + +University of Cambridge Computing Service, +Cambridge, England. Phone: +44 1223 334714. + +Copyright (c) 1997-2004 University of Cambridge +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. + +End diff --git a/trunk/srclib/pcre/Makefile.in b/trunk/srclib/pcre/Makefile.in new file mode 100644 index 0000000000..22eeee7bd1 --- /dev/null +++ b/trunk/srclib/pcre/Makefile.in @@ -0,0 +1,20 @@ +LTLIBRARY_NAME = libpcre.la +LTLIBRARY_SOURCES = maketables.c get.c study.c pcre.c + +CLEAN_TARGETS = dftables chartables.c +DISTCLEAN_TARGETS = pcre.h pcre-config config.h config.log config.status $(CLEAN_TARGETS) + +include $(top_srcdir)/build/ltlib.mk + +config.h: + touch $@ + +$(LTLIBRARY_OBJECTS) dftables.lo: config.h + +dftables: dftables.lo + $(LINK) $(EXTRA_LDFLAGS) dftables.lo $(EXTRA_LIBS) + +$(srcdir)/chartables.c: dftables + ./dftables $@ + +pcre.lo: $(srcdir)/chartables.c diff --git a/trunk/srclib/pcre/NEWS b/trunk/srclib/pcre/NEWS new file mode 100644 index 0000000000..e9a5cf255e --- /dev/null +++ b/trunk/srclib/pcre/NEWS @@ -0,0 +1,201 @@ +News about PCRE releases +------------------------ + +Release 5.0 13-Sep-04 +--------------------- + +The licence under which PCRE is released has been changed to the more +conventional "BSD" licence. + +In the code, some bugs have been fixed, and there are also some major changes +in this release (which is why I've increased the number to 5.0). Some changes +are internal rearrangements, and some provide a number of new facilities. The +new features are: + +1. There's an "automatic callout" feature that inserts callouts before every + item in the regex, and there's a new callout field that gives the position + in the pattern - useful for debugging and tracing. + +2. The extra_data structure can now be used to pass in a set of character + tables at exec time. This is useful if compiled regex are saved and re-used + at a later time when the tables may not be at the same address. If the + default internal tables are used, the pointer saved with the compiled + pattern is now set to NULL, which means that you don't need to do anything + special unless you are using custom tables. + +3. It is possible, with some restrictions on the content of the regex, to + request "partial" matching. A special return code is given if all of the + subject string matched part of the regex. This could be useful for testing + an input field as it is being typed. + +4. There is now some optional support for Unicode character properties, which + means that the patterns items such as \p{Lu} and \X can now be used. Only + the general category properties are supported. If PCRE is compiled with this + support, an additional 90K data structure is include, which increases the + size of the library dramatically. + +5. There is support for saving compiled patterns and re-using them later. + +6. There is support for running regular expressions that were compiled on a + different host with the opposite endianness. + +7. The pcretest program has been extended to accommodate the new features. + +The main internal rearrangement is that sequences of literal characters are no +longer handled as strings. Instead, each character is handled on its own. This +makes some UTF-8 handling easier, and makes the support of partial matching +possible. Compiled patterns containing long literal strings will be larger as a +result of this change; I hope that performance will not be much affected. + + +Release 4.5 01-Dec-03 +--------------------- + +Again mainly a bug-fix and tidying release, with only a couple of new features: + +1. It's possible now to compile PCRE so that it does not use recursive +function calls when matching. Instead it gets memory from the heap. This slows +things down, but may be necessary on systems with limited stacks. + +2. UTF-8 string checking has been tightened to reject overlong sequences and to +check that a starting offset points to the start of a character. Failure of the +latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET. + +3. PCRE can now be compiled for systems that use EBCDIC code. + + +Release 4.4 21-Aug-03 +--------------------- + +This is mainly a bug-fix and tidying release. The only new feature is that PCRE +checks UTF-8 strings for validity by default. There is an option to suppress +this, just in case anybody wants that teeny extra bit of performance. + + +Releases 4.1 - 4.3 +------------------ + +Sorry, I forgot about updating the NEWS file for these releases. Please take a +look at ChangeLog. + + +Release 4.0 17-Feb-03 +--------------------- + +There have been a lot of changes for the 4.0 release, adding additional +functionality and mending bugs. Below is a list of the highlights of the new +functionality. For full details of these features, please consult the +documentation. For a complete list of changes, see the ChangeLog file. + +1. Support for Perl's \Q...\E escapes. + +2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java +package. They provide some syntactic sugar for simple cases of "atomic +grouping". + +3. Support for the \G assertion. It is true when the current matching position +is at the start point of the match. + +4. A new feature that provides some of the functionality that Perl provides +with (?{...}). The facility is termed a "callout". The way it is done in PCRE +is for the caller to provide an optional function, by setting pcre_callout to +its entry point. To get the function called, the regex must include (?C) at +appropriate points. + +5. Support for recursive calls to individual subpatterns. This makes it really +easy to get totally confused. + +6. Support for named subpatterns. The Python syntax (?P...) is used to +name a group. + +7. Several extensions to UTF-8 support; it is now fairly complete. There is an +option for pcregrep to make it operate in UTF-8 mode. + +8. The single man page has been split into a number of separate man pages. +These also give rise to individual HTML pages which are put in a separate +directory. There is an index.html page that lists them all. Some hyperlinking +between the pages has been installed. + + +Release 3.5 15-Aug-01 +--------------------- + +1. The configuring system has been upgraded to use later versions of autoconf +and libtool. By default it builds both a shared and a static library if the OS +supports it. You can use --disable-shared or --disable-static on the configure +command if you want only one of them. + +2. The pcretest utility is now installed along with pcregrep because it is +useful for users (to test regexs) and by doing this, it automatically gets +relinked by libtool. The documentation has been turned into a man page, so +there are now .1, .txt, and .html versions in /doc. + +3. Upgrades to pcregrep: + (i) Added long-form option names like gnu grep. + (ii) Added --help to list all options with an explanatory phrase. + (iii) Added -r, --recursive to recurse into sub-directories. + (iv) Added -f, --file to read patterns from a file. + +4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure +script, to force use of CR or LF instead of \n in the source. On non-Unix +systems, the value can be set in config.h. + +5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an +absolute limit. Changed the text of the error message to make this clear, and +likewise updated the man page. + +6. The limit of 99 on the number of capturing subpatterns has been removed. +The new limit is 65535, which I hope will not be a "real" limit. + + +Release 3.3 01-Aug-00 +--------------------- + +There is some support for UTF-8 character strings. This is incomplete and +experimental. The documentation describes what is and what is not implemented. +Otherwise, this is just a bug-fixing release. + + +Release 3.0 01-Feb-00 +--------------------- + +1. A "configure" script is now used to configure PCRE for Unix systems. It +builds a Makefile, a config.h file, and the pcre-config script. + +2. PCRE is built as a shared library by default. + +3. There is support for POSIX classes such as [:alpha:]. + +5. There is an experimental recursion feature. + +---------------------------------------------------------------------------- + IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00 + +Please note that there has been a change in the API such that a larger +ovector is required at matching time, to provide some additional workspace. +The new man page has details. This change was necessary in order to support +some of the new functionality in Perl 5.005. + + IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00 + +Another (I hope this is the last!) change has been made to the API for the +pcre_compile() function. An additional argument has been added to make it +possible to pass over a pointer to character tables built in the current +locale by pcre_maketables(). To use the default tables, this new arguement +should be passed as NULL. + + IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 + +Yet another (and again I hope this really is the last) change has been made +to the API for the pcre_exec() function. An additional argument has been +added to make it possible to start the match other than at the start of the +subject string. This is important if there are lookbehinds. The new man +page has the details, but you just want to convert existing programs, all +you need to do is to stick in a new fifth argument to pcre_exec(), with a +value of zero. For example, change + + pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize) +to + pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize) + +**** diff --git a/trunk/srclib/pcre/NON-UNIX-USE b/trunk/srclib/pcre/NON-UNIX-USE new file mode 100644 index 0000000000..f6280af6f6 --- /dev/null +++ b/trunk/srclib/pcre/NON-UNIX-USE @@ -0,0 +1,244 @@ +Compiling PCRE on non-Unix systems +---------------------------------- + +See below for comments on Cygwin or MinGW and OpenVMS usage. I (Philip Hazel) +have no knowledge of Windows or VMS sytems and how their libraries work. The +items in the PCRE Makefile that relate to anything other than Unix-like systems +have been contributed by PCRE users. There are some other comments and files in +the Contrib directory on the ftp site that you may find useful. See + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib + +If you want to compile PCRE for a non-Unix system (or perhaps, more strictly, +for a system that does not support "configure" and "make" files), note that +PCRE consists entirely of code written in Standard C, and so should compile +successfully on any system that has a Standard C compiler and library. + + +GENERIC INSTRUCTIONS + +The following are generic comments about building PCRE. The interspersed +indented commands are suggestions from Mark Tetrode as to which commands you +might use on a Windows system to build a static library. + +(1) Copy or rename the file config.in as config.h, and change the macros that +define HAVE_STRERROR and HAVE_MEMMOVE to define them as 1 rather than 0. +Unfortunately, because of the way Unix autoconf works, the default setting has +to be 0. You may also want to make changes to other macros in config.h. In +particular, if you want to force a specific value for newline, you can define +the NEWLINE macro. The default is to use '\n', thereby using whatever value +your compiler gives to '\n'. + + rem Mark Tetrode's commands + copy config.in config.h + rem Use write, because notepad cannot handle UNIX files. Change values. + write config.h + +(2) Copy or rename the file pcre.in as pcre.h, and change the macro definitions +for PCRE_MAJOR, PCRE_MINOR, and PCRE_DATE near its start to the values set in +configure.in. + + rem Mark Tetrode's commands + copy pcre.in pcre.h + rem Read values from configure.in + write configure.in + rem Change values + write pcre.h + +(3) Compile dftables.c as a stand-alone program, and then run it with +the single argument "chartables.c". This generates a set of standard +character tables and writes them to that file. + + rem Mark Tetrode's commands + rem Compile & run + cl -DSUPPORT_UTF8 dftables.c + dftables.exe > chartables.c + +(4) Compile maketables.c, get.c, study.c and pcre.c and link them all +together into an object library in whichever form your system keeps such +libraries. This is the pcre library (chartables.c is included by means of an +#include directive). If your system has static and shared libraries, you may +have to do this once for each type. + + rem Mark Tetrode's commands, for a static library + rem Compile & lib + cl -DSUPPORT_UTF8 -DPOSIX_MALLOC_THRESHOLD=10 /c maketables.c get.c study.c pcre.c + lib /OUT:pcre.lib maketables.obj get.obj study.obj pcre.obj + +(5) Similarly, compile pcreposix.c and link it (on its own) as the pcreposix +library. + + rem Mark Tetrode's commands, for a static library + rem Compile & lib + cl -DSUPPORT_UTF8 -DPOSIX_MALLOC_THRESHOLD=10 /c pcreposix.c + lib /OUT:pcreposix.lib pcreposix.obj + +(6) Compile the test program pcretest.c. This needs the functions in the +pcre and pcreposix libraries when linking. + + rem Mark Tetrode's commands + rem compile & link + cl pcretest.c pcre.lib pcreposix.lib + +(7) Run pcretest on the testinput files in the testdata directory, and check +that the output matches the corresponding testoutput files. You must use the +-i option when checking testinput2. Note that the supplied files are in Unix +format, with just LF characters as line terminators. You may need to edit them +to change this if your system uses a different convention. + + rem Mark Tetrode's commands + rem Make a change, i.e. space, backspace, and save again - do this for all + rem to change UNIX to Win, \n to \n\r + write testoutput1 + write testoutput2 + write testoutput3 + write testoutput4 + write testoutput5 + pcretest testdata\testinput1 testdata\myoutput1 + windiff testdata\testoutput1 testdata\myoutput1 + pcretest -i testdata\testinput2 testdata\myoutput2 + windiff testdata\testoutput2 testdata\myoutput2 + pcretest testdata\testinput3 testdata\myoutput3 + windiff testdata\testoutput3 testdata\myoutput3 + pcretest testdata\testinput4 testdata\myoutput4 + windiff testdata\testoutput4 testdata\myoutput4 + pcretest testdata\testinput5 testdata\myoutput5 + windiff testdata\testoutput5 testdata\myoutput5 + + +FURTHER REMARKS + +If you have a system without "configure" but where you can use a Makefile, edit +Makefile.in to create Makefile, substituting suitable values for the variables +at the head of the file. + +Some help in building a Win32 DLL of PCRE in GnuWin32 environments was +contributed by Paul Sokolovsky. These environments are Mingw32 +(http://www.xraylith.wisc.edu/~khan/software/gnu-win32/) and CygWin +(http://sourceware.cygnus.com/cygwin/). Paul comments: + + For CygWin, set CFLAGS=-mno-cygwin, and do 'make dll'. You'll get + pcre.dll (containing pcreposix also), libpcre.dll.a, and dynamically + linked pgrep and pcretest. If you have /bin/sh, run RunTest (three + main test go ok, locale not supported). + +Changes to do MinGW with autoconf 2.50 were supplied by Fred Cox +, who comments as follows: + + If you are using the PCRE DLL, the normal Unix style configure && make && + make check && make install should just work[*]. If you want to statically + link against the .a file, you must define PCRE_STATIC before including + pcre.h, otherwise the pcre_malloc and pcre_free exported functions will be + declared __declspec(dllimport), with hilarious results. See the configure.in + and pcretest.c for how it is done for the static test. + + Also, there will only be a libpcre.la, not a libpcreposix.la, as you + would expect from the Unix version. The single DLL includes the pcreposix + interface. + +[*] But note that the supplied test files are in Unix format, with just LF +characters as line terminators. You will have to edit them to change to CR LF +terminators. + +A script for building PCRE using Borland's C++ compiler for use with VPASCAL +was contributed by Alexander Tokarev. It is called makevp.bat. + +These are some further comments about Win32 builds from Mark Evans. They +were contributed before Fred Cox's changes were made, so it is possible that +they may no longer be relevant. + +"The documentation for Win32 builds is a bit shy. Under MSVC6 I +followed their instructions to the letter, but there were still +some things missing. + +(1) Must #define STATIC for entire project if linking statically. + (I see no reason to use DLLs for code this compact.) This of + course is a project setting in MSVC under Preprocessor. + +(2) Missing some #ifdefs relating to the function pointers + pcre_malloc and pcre_free. See my solution below. (The stubs + may not be mandatory but they made me feel better.)" + +========================= +#ifdef _WIN32 +#include + +void* malloc_stub(size_t N) +{ return malloc(N); } +void free_stub(void* p) +{ free(p); } +void *(*pcre_malloc)(size_t) = &malloc_stub; +void (*pcre_free)(void *) = &free_stub; + +#else + +void *(*pcre_malloc)(size_t) = malloc; +void (*pcre_free)(void *) = free; + +#endif +========================= + + +BUILDING PCRE ON OPENVMS + +Dan Mooney sent the following comments about building PCRE on OpenVMS: + +"It was quite easy to compile and link the library. I don't have a formal +make file but the attached file [reproduced below] contains the OpenVMS DCL +commands I used to build the library. I had to add #define +POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. + +The library was built on: +O/S: HP OpenVMS v7.3-1 +Compiler: Compaq C v6.5-001-48BCD +Linker: vA13-01 + +The test results did not match 100% due to the issues you mention in your +documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I +modified some of the character tables temporarily and was able to get the +results to match. Tests using the fr locale did not match since I don't have +that locale loaded. The study size was always reported to be 3 less than the +value in the standard test output files." + +========================= +$! This DCL procedure builds PCRE on OpenVMS +$! +$! I followed the instructions in the non-unix-use file in the distribution. +$! +$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES +$ COMPILE DFTABLES.C +$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ +$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C +$ COMPILE MAKETABLES.C +$ COMPILE GET.C +$ COMPILE STUDY.C +$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol +$! did not seem to be defined anywhere. +$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. +$ COMPILE PCRE.C +$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ +$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol +$! did not seem to be defined anywhere. +$ COMPILE PCREPOSIX.C +$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ +$ COMPILE PCRETEST.C +$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB +$! C programs that want access to command line arguments must be +$! defined as a symbol +$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" +$! Arguments must be enclosed in quotes. +$ PCRETEST "-C" +$! Test results: +$! +$! The test results did not match 100%. The functions isprint(), iscntrl(), +$! isgraph() and ispunct() on OpenVMS must not produce the same results +$! as the system that built the test output files provided with the +$! distribution. +$! +$! The study size did not match and was always 3 less on OpenVMS. +$! +$! Locale could not be set to fr +$! +========================= + +**** diff --git a/trunk/srclib/pcre/NWGNUmakefile b/trunk/srclib/pcre/NWGNUmakefile new file mode 100644 index 0000000000..a40897c67c --- /dev/null +++ b/trunk/srclib/pcre/NWGNUmakefile @@ -0,0 +1,267 @@ +# +# NWGNUmakefile for DfTables.nlm (Apache2) +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(APR_WORK)\build\NWGNUhead.inc + +PCRE = $(AP_WORK)/srclib/pcre + +# +# build this level's files + +FILES_prebuild_headers = \ + $(PCRE)/config.h \ + $(PCRE)/pcre.h \ + $(EOLIST) + +$(PCRE)/%.h: $(subst /,\,$(PCRE))\%.hw + @echo Creating $(subst /,\,$@) + copy $< $(subst /,\,$(PCRE))\$(@F) + +# +# Make sure all needed macro's are defined +# + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(AP_WORK)/os/netware \ + $(APR)/include/arch/netware \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = dftables + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Generate character tables + +#$(FILES_prebuild_headers) +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = dftables + +# +# If this is specified, it will override VERSION value in +# $(APR_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = 1,0,0 + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM =_LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM =_LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If this is specified it will be used by the link '-flags' directive +# +NLM_FLAGS = PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(APR)/misc/netware/apr.xdc. XDCData can +# be disabled by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# Declare all target files (you must add your files here) +# + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ +$(OBJDIR)/dftables.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(FILES_prebuild_headers) \ + $(OBJDIR)/dftables.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + Libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(APR_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(APR_WORK)\build\NWGNUtail.inc + +# End of NWGNUmakefile for DfTables.nlm (Apache2) diff --git a/trunk/srclib/pcre/README b/trunk/srclib/pcre/README new file mode 100644 index 0000000000..fc5397ecce --- /dev/null +++ b/trunk/srclib/pcre/README @@ -0,0 +1,427 @@ +README file for PCRE (Perl-compatible regular expression library) +----------------------------------------------------------------- + +The latest release of PCRE is always available from + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz + +Please read the NEWS file if you are upgrading from a previous release. + +PCRE has its own native API, but a set of "wrapper" functions that are based on +the POSIX API are also supplied in the library libpcreposix. Note that this +just provides a POSIX calling interface to PCRE: the regular expressions +themselves still follow Perl syntax and semantics. The header file +for the POSIX-style functions is called pcreposix.h. The official POSIX name is +regex.h, but I didn't want to risk possible problems with existing files of +that name by distributing it that way. To use it with an existing program that +uses the POSIX API, it will have to be renamed or pointed at by a link. + +If you are using the POSIX interface to PCRE and there is already a POSIX regex +library installed on your system, you must take care when linking programs to +ensure that they link with PCRE's libpcreposix library. Otherwise they may pick +up the "real" POSIX functions of the same name. + + +Documentation for PCRE +---------------------- + +If you install PCRE in the normal way, you will end up with an installed set of +man pages whose names all start with "pcre". The one that is called "pcre" +lists all the others. In addition to these man pages, the PCRE documentation is +supplied in two other forms; however, as there is no standard place to install +them, they are left in the doc directory of the unpacked source distribution. +These forms are: + + 1. Files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt. The + first of these is a concatenation of the text forms of all the section 3 + man pages except those that summarize individual functions. The other two + are the text forms of the section 1 man pages for the pcregrep and + pcretest commands. Text forms are provided for ease of scanning with text + editors or similar tools. + + 2. A subdirectory called doc/html contains all the documentation in HTML + form, hyperlinked in various ways, and rooted in a file called + doc/index.html. + + +Contributions by users of PCRE +------------------------------ + +You can find contributions from PCRE users in the directory + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib + +where there is also a README file giving brief descriptions of what they are. +Several of them provide support for compiling PCRE on various flavours of +Windows systems (I myself do not use Windows). Some are complete in themselves; +others are pointers to URLs containing relevant files. + + +Building PCRE on a Unix-like system +----------------------------------- + +To build PCRE on a Unix-like system, first run the "configure" command from the +PCRE distribution directory, with your current directory set to the directory +where you want the files to be created. This command is a standard GNU +"autoconf" configuration script, for which generic instructions are supplied in +INSTALL. + +Most commonly, people build PCRE within its own distribution directory, and in +this case, on many systems, just running "./configure" is sufficient, but the +usual methods of changing standard defaults are available. For example: + +CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local + +specifies that the C compiler should be run with the flags '-O2 -Wall' instead +of the default, and that "make install" should install PCRE under /opt/local +instead of the default /usr/local. + +If you want to build in a different directory, just run "configure" with that +directory as current. For example, suppose you have unpacked the PCRE source +into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: + +cd /build/pcre/pcre-xxx +/source/pcre/pcre-xxx/configure + +There are some optional features that can be included or omitted from the PCRE +library. You can read more about them in the pcrebuild man page. + +. If you want to make use of the support for UTF-8 character strings in PCRE, + you must add --enable-utf8 to the "configure" command. Without it, the code + for handling UTF-8 is not included in the library. (Even when included, it + still has to be enabled by an option at run time.) + +. If, in addition to support for UTF-8 character strings, you want to include + support for the \P, \p, and \X sequences that recognize Unicode character + properties, you must add --enable-unicode-properties to the "configure" + command. This adds about 90K to the size of the library (in the form of a + property table); only the basic two-letter properties such as Lu are + supported. + +. You can build PCRE to recognized CR or NL as the newline character, instead + of whatever your compiler uses for "\n", by adding --newline-is-cr or + --newline-is-nl to the "configure" command, respectively. Only do this if you + really understand what you are doing. On traditional Unix-like systems, the + newline character is NL. + +. When called via the POSIX interface, PCRE uses malloc() to get additional + storage for processing capturing parentheses if there are more than 10 of + them. You can increase this threshold by setting, for example, + + --with-posix-malloc-threshold=20 + + on the "configure" command. + +. PCRE has a counter which can be set to limit the amount of resources it uses. + If the limit is exceeded during a match, the match fails. The default is ten + million. You can change the default by setting, for example, + + --with-match-limit=500000 + + on the "configure" command. This is just the default; individual calls to + pcre_exec() can supply their own value. There is discussion on the pcreapi + man page. + +. The default maximum compiled pattern size is around 64K. You can increase + this by adding --with-link-size=3 to the "configure" command. You can + increase it even more by setting --with-link-size=4, but this is unlikely + ever to be necessary. If you build PCRE with an increased link size, test 2 + (and 5 if you are using UTF-8) will fail. Part of the output of these tests + is a representation of the compiled pattern, and this changes with the link + size. + +. You can build PCRE so that its match() function does not call itself + recursively. Instead, it uses blocks of data from the heap via special + functions pcre_stack_malloc() and pcre_stack_free() to save data that would + otherwise be saved on the stack. To build PCRE like this, use + + --disable-stack-for-recursion + + on the "configure" command. PCRE runs more slowly in this mode, but it may be + necessary in environments with limited stack sizes. + +The "configure" script builds seven files: + +. pcre.h is build by copying pcre.in and making substitutions +. Makefile is built by copying Makefile.in and making substitutions. +. config.h is built by copying config.in and making substitutions. +. pcre-config is built by copying pcre-config.in and making substitutions. +. libpcre.pc is data for the pkg-config command, built from libpcre.pc.in +. libtool is a script that builds shared and/or static libraries +. RunTest is a script for running tests + +Once "configure" has run, you can run "make". It builds two libraries called +libpcre and libpcreposix, a test program called pcretest, and the pcregrep +command. You can use "make install" to copy these, the public header files +pcre.h and pcreposix.h, and the man pages to appropriate live directories on +your system, in the normal way. + + +Retrieving configuration information on Unix-like systems +--------------------------------------------------------- + +Running "make install" also installs the command pcre-config, which can be used +to recall information about the PCRE configuration and installation. For +example: + + pcre-config --version + +prints the version number, and + + pcre-config --libs + +outputs information about where the library is installed. This command can be +included in makefiles for programs that use PCRE, saving the programmer from +having to remember too many details. + +The pkg-config command is another system for saving and retrieving information +about installed libraries. Instead of separate commands for each library, a +single command is used. For example: + + pkg-config --cflags pcre + +The data is held in *.pc files that are installed in a directory called +pkgconfig. + + +Shared libraries on Unix-like systems +------------------------------------- + +The default distribution builds PCRE as two shared libraries and two static +libraries, as long as the operating system supports shared libraries. Shared +library support relies on the "libtool" script which is built as part of the +"configure" process. + +The libtool script is used to compile and link both shared and static +libraries. They are placed in a subdirectory called .libs when they are newly +built. The programs pcretest and pcregrep are built to use these uninstalled +libraries (by means of wrapper scripts in the case of shared libraries). When +you use "make install" to install shared libraries, pcregrep and pcretest are +automatically re-built to use the newly installed shared libraries before being +installed themselves. However, the versions left in the source directory still +use the uninstalled libraries. + +To build PCRE using static libraries only you must use --disable-shared when +configuring it. For example: + +./configure --prefix=/usr/gnu --disable-shared + +Then run "make" in the usual way. Similarly, you can use --disable-static to +build only shared libraries. + + +Cross-compiling on a Unix-like system +------------------------------------- + +You can specify CC and CFLAGS in the normal way to the "configure" command, in +order to cross-compile PCRE for some other host. However, during the building +process, the dftables.c source file is compiled *and run* on the local host, in +order to generate the default character tables (the chartables.c file). It +therefore needs to be compiled with the local compiler, not the cross compiler. +You can do this by specifying CC_FOR_BUILD (and if necessary CFLAGS_FOR_BUILD) +when calling the "configure" command. If they are not specified, they default +to the values of CC and CFLAGS. + + +Building on non-Unix systems +---------------------------- + +For a non-Unix system, read the comments in the file NON-UNIX-USE, though if +the system supports the use of "configure" and "make" you may be able to build +PCRE in the same way as for Unix systems. + +PCRE has been compiled on Windows systems and on Macintoshes, but I don't know +the details because I don't use those systems. It should be straightforward to +build PCRE on any system that has a Standard C compiler, because it uses only +Standard C functions. + + +Testing PCRE +------------ + +To test PCRE on a Unix system, run the RunTest script that is created by the +configuring process. (This can also be run by "make runtest", "make check", or +"make test".) For other systems, see the instructions in NON-UNIX-USE. + +The script runs the pcretest test program (which is documented in its own man +page) on each of the testinput files (in the testdata directory) in turn, +and compares the output with the contents of the corresponding testoutput file. +A file called testtry is used to hold the main output from pcretest +(testsavedregex is also used as a working file). To run pcretest on just one of +the test files, give its number as an argument to RunTest, for example: + + RunTest 2 + +The first file can also be fed directly into the perltest script to check that +Perl gives the same results. The only difference you should see is in the first +few lines, where the Perl version is given instead of the PCRE version. + +The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(), +pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error +detection, and run-time flags that are specific to PCRE, as well as the POSIX +wrapper API. It also uses the debugging flag to check some of the internals of +pcre_compile(). + +If you build PCRE with a locale setting that is not the standard C locale, the +character tables may be different (see next paragraph). In some cases, this may +cause failures in the second set of tests. For example, in a locale where the +isprint() function yields TRUE for characters in the range 128-255, the use of +[:isascii:] inside a character class defines a different set of characters, and +this shows up in this test as a difference in the compiled code, which is being +listed for checking. Where the comparison test output contains [\x00-\x7f] the +test will contain [\x00-\xff], and similarly in some other cases. This is not a +bug in PCRE. + +The third set of tests checks pcre_maketables(), the facility for building a +set of character tables for a specific locale and using them instead of the +default tables. The tests make use of the "fr_FR" (French) locale. Before +running the test, the script checks for the presence of this locale by running +the "locale" command. If that command fails, or if it doesn't include "fr_FR" +in the list of available locales, the third test cannot be run, and a comment +is output to say why. If running this test produces instances of the error + + ** Failed to set locale "fr_FR" + +in the comparison output, it means that locale is not available on your system, +despite being listed by "locale". This does not mean that PCRE is broken. + +The fourth test checks the UTF-8 support. It is not run automatically unless +PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when +running "configure". This file can be also fed directly to the perltest script, +provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch, +commented in the script, can be be used.) + +The fifth test checks error handling with UTF-8 encoding, and internal UTF-8 +features of PCRE that are not relevant to Perl. + +The sixth and final test checks the support for Unicode character properties. +It it not run automatically unless PCRE is built with Unicode property support. +To to this you must set --enable-unicode-properties when running "configure". + + +Character tables +---------------- + +PCRE uses four tables for manipulating and identifying characters whose values +are less than 256. The final argument of the pcre_compile() function is a +pointer to a block of memory containing the concatenated tables. A call to +pcre_maketables() can be used to generate a set of tables in the current +locale. If the final argument for pcre_compile() is passed as NULL, a set of +default tables that is built into the binary is used. + +The source file called chartables.c contains the default set of tables. This is +not supplied in the distribution, but is built by the program dftables +(compiled from dftables.c), which uses the ANSI C character handling functions +such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table +sources. This means that the default C locale which is set for your system will +control the contents of these default tables. You can change the default tables +by editing chartables.c and then re-building PCRE. If you do this, you should +probably also edit Makefile to ensure that the file doesn't ever get +re-generated. + +The first two 256-byte tables provide lower casing and case flipping functions, +respectively. The next table consists of three 32-byte bit maps which identify +digits, "word" characters, and white space, respectively. These are used when +building 32-byte bit maps that represent character classes. + +The final 256-byte table has bits indicating various character types, as +follows: + + 1 white space character + 2 letter + 4 decimal digit + 8 hexadecimal digit + 16 alphanumeric or '_' + 128 regular expression metacharacter or binary zero + +You should not alter the set of characters that contain the 128 bit, as that +will cause PCRE to malfunction. + + +Manifest +-------- + +The distribution should contain the following files: + +(A) The actual source files of the PCRE library functions and their + headers: + + dftables.c auxiliary program for building chartables.c + + get.c ) + maketables.c ) + study.c ) source of the functions + pcre.c ) in the library + pcreposix.c ) + printint.c ) + + ucp.c ) + ucp.h ) source for the code that is used for + ucpinternal.h ) Unicode property handling + ucptable.c ) + ucptypetable.c ) + + pcre.in "source" for the header for the external API; pcre.h + is built from this by "configure" + pcreposix.h header for the external POSIX wrapper API + internal.h header for internal use + config.in template for config.h, which is built by configure + +(B) Auxiliary files: + + AUTHORS information about the author of PCRE + ChangeLog log of changes to the code + INSTALL generic installation instructions + LICENCE conditions for the use of PCRE + COPYING the same, using GNU's standard name + Makefile.in template for Unix Makefile, which is built by configure + NEWS important changes in this release + NON-UNIX-USE notes on building PCRE on non-Unix systems + README this file + RunTest.in template for a Unix shell script for running tests + config.guess ) files used by libtool, + config.sub ) used only when building a shared library + configure a configuring shell script (built by autoconf) + configure.in the autoconf input used to build configure + doc/Tech.Notes notes on the encoding + doc/*.3 man page sources for the PCRE functions + doc/*.1 man page sources for pcregrep and pcretest + doc/html/* HTML documentation + doc/pcre.txt plain text version of the man pages + doc/pcretest.txt plain text documentation of test program + doc/perltest.txt plain text documentation of Perl test program + install-sh a shell script for installing files + libpcre.pc.in "source" for libpcre.pc for pkg-config + ltmain.sh file used to build a libtool script + mkinstalldirs script for making install directories + pcretest.c comprehensive test program + pcredemo.c simple demonstration of coding calls to PCRE + perltest Perl test program + pcregrep.c source of a grep utility that uses PCRE + pcre-config.in source of script which retains PCRE information + testdata/testinput1 test data, compatible with Perl + testdata/testinput2 test data for error messages and non-Perl things + testdata/testinput3 test data for locale-specific tests + testdata/testinput4 test data for UTF-8 tests compatible with Perl + testdata/testinput5 test data for other UTF-8 tests + testdata/testinput6 test data for Unicode property support tests + testdata/testoutput1 test results corresponding to testinput1 + testdata/testoutput2 test results corresponding to testinput2 + testdata/testoutput3 test results corresponding to testinput3 + testdata/testoutput4 test results corresponding to testinput4 + testdata/testoutput5 test results corresponding to testinput5 + testdata/testoutput6 test results corresponding to testinput6 + +(C) Auxiliary files for Win32 DLL + + dll.mk + libpcre.def + libpcreposix.def + pcre.def + +(D) Auxiliary file for VPASCAL + + makevp.bat + +Philip Hazel +September 2004 diff --git a/trunk/srclib/pcre/RunTest.in b/trunk/srclib/pcre/RunTest.in new file mode 100755 index 0000000000..5e945e1baf --- /dev/null +++ b/trunk/srclib/pcre/RunTest.in @@ -0,0 +1,192 @@ +#! /bin/sh + +# This file is generated by configure from RunTest.in. Make any changes +# to that file. + +# Run PCRE tests + +cf=diff +testdata=@top_srcdir@/testdata + +# Select which tests to run; if no selection, run all + +do1=no +do2=no +do3=no +do4=no +do5=no +do6=no + +while [ $# -gt 0 ] ; do + case $1 in + 1) do1=yes;; + 2) do2=yes;; + 3) do3=yes;; + 4) do4=yes;; + 5) do5=yes;; + 6) do6=yes;; + *) echo "Unknown test number $1"; exit 1;; + esac + shift +done + +if [ "@LINK_SIZE@" != "" -a "@LINK_SIZE@" != "-DLINK_SIZE=2" ] ; then + if [ $do2 = yes ] ; then + echo "Can't run test 2 with an internal link size other than 2" + exit 1 + fi + if [ $do5 = yes ] ; then + echo "Can't run test 5 with an internal link size other than 2" + exit 1 + fi + if [ $do6 = yes ] ; then + echo "Can't run test 6 with an internal link size other than 2" + exit 1 + fi +fi + +if [ "@UTF8@" = "" ] ; then + if [ $do4 = yes ] ; then + echo "Can't run test 4 because UTF-8 support is not configured" + exit 1 + fi + if [ $do5 = yes ] ; then + echo "Can't run test 5 because UTF-8 support is not configured" + exit 1 + fi + if [ $do6 = yes ] ; then + echo "Can't run test 6 because UTF-8 support is not configured" + exit 1 + fi +fi + +if [ "@UCP@" = "" ] ; then + if [ $do6 = yes ] ; then + echo "Can't run test 6 because Unicode property support is not configured" + exit 1 + fi +fi + +if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ + $do5 = no -a $do6 = no ] ; then + do1=yes + do2=yes + do3=yes + if [ "@UTF8@" != "" ] ; then do4=yes; fi + if [ "@UTF8@" != "" ] ; then do5=yes; fi + if [ "@UTF8@" != "" -a "@UCP@" != "" ] ; then do6=yes; fi +fi + +# Show which release + +./pcretest /dev/null + +# Primary test, Perl-compatible + +if [ $do1 = yes ] ; then + echo "Test 1: main functionality (Perl compatible)" + ./pcretest $testdata/testinput1 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput1 + if [ $? != 0 ] ; then exit 1; fi + echo " " + else exit 1 + fi +fi + +# PCRE tests that are not Perl-compatible - API & error tests, mostly + +if [ $do2 = yes ] ; then + if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then + echo "Test 2: API and error handling (not Perl compatible)" + ./pcretest -i $testdata/testinput2 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput2 + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + else + echo Test 2 skipped for link size other than 2 \(@LINK_SIZE@\) + fi +fi + +if [ $do1 = yes -a $do2 = yes ] ; then + echo " " + echo "The two main tests ran OK" + echo " " +fi + +# Locale-specific tests, provided the "fr_FR" locale is available + +if [ $do3 = yes ] ; then + locale -a | grep '^fr_FR$' >/dev/null + if [ $? -eq 0 ] ; then + echo "Test 3: locale-specific features (using 'fr_FR' locale)" + ./pcretest $testdata/testinput3 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput3 + if [ $? != 0 ] ; then + echo " " + echo "Locale test did not run entirely successfully." + echo "This usually means that there is a problem with the locale" + echo "settings rather than a bug in PCRE." + else + echo "Locale test ran OK" + fi + echo " " + else exit 1 + fi + else + echo "Cannot test locale-specific features - 'fr_FR' locale not found," + echo "or the \"locale\" command is not available to check for it." + echo " " + fi +fi + +# Additional tests for UTF8 support + +if [ $do4 = yes ] ; then + echo "Test 4: UTF-8 support (Perl compatible)" + ./pcretest $testdata/testinput4 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput4 + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo "UTF8 test ran OK" + echo " " +fi + +if [ $do5 = yes ] ; then + if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then + echo "Test 5: API and internals for UTF-8 support (not Perl compatible)" + ./pcretest $testdata/testinput5 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput5 + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo "UTF8 internals test ran OK" + echo " " + else + echo Test 5 skipped for link size other than 2 \(@LINK_SIZE@\) + fi +fi + +if [ $do6 = yes ] ; then + if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then + echo "Test 6: Unicode property support" + ./pcretest $testdata/testinput6 testtry + if [ $? = 0 ] ; then + $cf testtry $testdata/testoutput6 + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo "Unicode properties test ran OK" + echo " " + else + echo Test 6 skipped for link size other than 2 \(@LINK_SIZE@\) + fi +fi + +# End diff --git a/trunk/srclib/pcre/config.hw b/trunk/srclib/pcre/config.hw new file mode 100644 index 0000000000..5427366f7f --- /dev/null +++ b/trunk/srclib/pcre/config.hw @@ -0,0 +1,107 @@ + +/* On Unix systems config.in is converted by configure into config.h. PCRE is +written in Standard C, but there are a few non-standard things it can cope +with, allowing it to run on SunOS4 and other "close to standard" systems. + +On a non-Unix system you should just copy this file into config.h, and set up +the macros the way you need them. You should normally change the definitions of +HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way autoconf +works, these cannot be made the defaults. If your system has bcopy() and not +memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE. If your +system has neither bcopy() nor memmove(), leave them both as 0; an emulation +function will be used. */ + +/* If you are compiling for a system that uses EBCDIC instead of ASCII +character codes, define this macro as 1. On systems that can use "configure", +this can be done via --enable-ebcdic. */ + +#ifndef EBCDIC +#define EBCDIC 0 +#endif + +/* If you are compiling for a system that needs some magic to be inserted +before the definition of an exported function, define this macro to contain the +relevant magic. It apears at the start of every exported function. */ + +#define EXPORT + +/* Define to empty if the "const" keyword does not work. */ + +#undef const + +/* Define to "unsigned" if doesn't define size_t. */ + +#undef size_t + +/* The following two definitions are mainly for the benefit of SunOS4, which +doesn't have the strerror() or memmove() functions that should be present in +all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should +normally be defined with the value 1 for other systems, but unfortunately we +can't make this the default because "configure" files generated by autoconf +will only change 0 to 1; they won't change 1 to 0 if the functions are not +found. */ + +#define HAVE_STRERROR 1 +#define HAVE_MEMMOVE 1 + +/* There are some non-Unix systems that don't even have bcopy(). If this macro +is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of +HAVE_BCOPY is not relevant. */ + +#define HAVE_BCOPY 0 + +/* The value of NEWLINE determines the newline character. The default is to +leave it up to the compiler, but some sites want to force a particular value. +On Unix systems, "configure" can be used to override this default. */ + +#ifndef NEWLINE +#define NEWLINE '\n' +#endif + +/* The value of LINK_SIZE determines the number of bytes used to store +links as offsets within the compiled regex. The default is 2, which allows for +compiled patterns up to 64K long. This covers the vast majority of cases. +However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for +longer patterns in extreme cases. On Unix systems, "configure" can be used to +override this default. */ + +#ifndef LINK_SIZE +#define LINK_SIZE 2 +#endif + +/* The value of MATCH_LIMIT determines the default number of times the match() +function can be called during a single execution of pcre_exec(). (There is a +runtime method of setting a different limit.) The limit exists in order to +catch runaway regular expressions that take for ever to determine that they do +not match. The default is set very large so that it does not accidentally catch +legitimate cases. On Unix systems, "configure" can be used to override this +default default. */ + +#ifndef MATCH_LIMIT +#define MATCH_LIMIT 10000000 +#endif + +/* When calling PCRE via the POSIX interface, additional working storage is +required for holding the pointers to capturing substrings because PCRE requires +three integers per substring, whereas the POSIX interface provides only two. If +the number of expected substrings is small, the wrapper function uses space on +the stack, because this is faster than using malloc() for each call. The +threshold above which the stack is no longer use is defined by POSIX_MALLOC_ +THRESHOLD. On Unix systems, "configure" can be used to override this default. +*/ + +#ifndef POSIX_MALLOC_THRESHOLD +#define POSIX_MALLOC_THRESHOLD 10 +#endif + +/* PCRE uses recursive function calls to handle backtracking while matching. +This can sometimes be a problem on systems that have stacks of limited size. +Define NO_RECURSE to get a version that doesn't use recursion in the match() +function; instead it creates its own stack by steam using pcre_recurse_malloc +to get memory. For more detail, see comments and other stuff just above the +match() function. On Unix systems, "configure" can be used to set this in the +Makefile (use --disable-stack-for-recursion). */ + +/* #define NO_RECURSE */ + +/* End */ diff --git a/trunk/srclib/pcre/config.in b/trunk/srclib/pcre/config.in new file mode 100644 index 0000000000..fc17ddd13c --- /dev/null +++ b/trunk/srclib/pcre/config.in @@ -0,0 +1,107 @@ + +/* On Unix systems config.in is converted by configure into config.h. PCRE is +written in Standard C, but there are a few non-standard things it can cope +with, allowing it to run on SunOS4 and other "close to standard" systems. + +On a non-Unix system you should just copy this file into config.h, and set up +the macros the way you need them. You should normally change the definitions of +HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way autoconf +works, these cannot be made the defaults. If your system has bcopy() and not +memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE. If your +system has neither bcopy() nor memmove(), leave them both as 0; an emulation +function will be used. */ + +/* If you are compiling for a system that uses EBCDIC instead of ASCII +character codes, define this macro as 1. On systems that can use "configure", +this can be done via --enable-ebcdic. */ + +#ifndef EBCDIC +#define EBCDIC 0 +#endif + +/* If you are compiling for a system that needs some magic to be inserted +before the definition of an exported function, define this macro to contain the +relevant magic. It apears at the start of every exported function. */ + +#define EXPORT + +/* Define to empty if the "const" keyword does not work. */ + +#undef const + +/* Define to "unsigned" if doesn't define size_t. */ + +#undef size_t + +/* The following two definitions are mainly for the benefit of SunOS4, which +doesn't have the strerror() or memmove() functions that should be present in +all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should +normally be defined with the value 1 for other systems, but unfortunately we +can't make this the default because "configure" files generated by autoconf +will only change 0 to 1; they won't change 1 to 0 if the functions are not +found. */ + +#define HAVE_STRERROR 0 +#define HAVE_MEMMOVE 0 + +/* There are some non-Unix systems that don't even have bcopy(). If this macro +is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of +HAVE_BCOPY is not relevant. */ + +#define HAVE_BCOPY 0 + +/* The value of NEWLINE determines the newline character. The default is to +leave it up to the compiler, but some sites want to force a particular value. +On Unix systems, "configure" can be used to override this default. */ + +#ifndef NEWLINE +#define NEWLINE '\n' +#endif + +/* The value of LINK_SIZE determines the number of bytes used to store +links as offsets within the compiled regex. The default is 2, which allows for +compiled patterns up to 64K long. This covers the vast majority of cases. +However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for +longer patterns in extreme cases. On Unix systems, "configure" can be used to +override this default. */ + +#ifndef LINK_SIZE +#define LINK_SIZE 2 +#endif + +/* The value of MATCH_LIMIT determines the default number of times the match() +function can be called during a single execution of pcre_exec(). (There is a +runtime method of setting a different limit.) The limit exists in order to +catch runaway regular expressions that take for ever to determine that they do +not match. The default is set very large so that it does not accidentally catch +legitimate cases. On Unix systems, "configure" can be used to override this +default default. */ + +#ifndef MATCH_LIMIT +#define MATCH_LIMIT 10000000 +#endif + +/* When calling PCRE via the POSIX interface, additional working storage is +required for holding the pointers to capturing substrings because PCRE requires +three integers per substring, whereas the POSIX interface provides only two. If +the number of expected substrings is small, the wrapper function uses space on +the stack, because this is faster than using malloc() for each call. The +threshold above which the stack is no longer use is defined by POSIX_MALLOC_ +THRESHOLD. On Unix systems, "configure" can be used to override this default. +*/ + +#ifndef POSIX_MALLOC_THRESHOLD +#define POSIX_MALLOC_THRESHOLD 10 +#endif + +/* PCRE uses recursive function calls to handle backtracking while matching. +This can sometimes be a problem on systems that have stacks of limited size. +Define NO_RECURSE to get a version that doesn't use recursion in the match() +function; instead it creates its own stack by steam using pcre_recurse_malloc +to get memory. For more detail, see comments and other stuff just above the +match() function. On Unix systems, "configure" can be used to set this in the +Makefile (use --disable-stack-for-recursion). */ + +/* #define NO_RECURSE */ + +/* End */ diff --git a/trunk/srclib/pcre/configure.in b/trunk/srclib/pcre/configure.in new file mode 100644 index 0000000000..4f8d031aaf --- /dev/null +++ b/trunk/srclib/pcre/configure.in @@ -0,0 +1,185 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl This is required at the start; the name is the name of a file +dnl it should be seeing, to verify it is in the same directory. + +AC_INIT(dftables.c) + +dnl A safety precaution + +AC_PREREQ(2.57) + +dnl Arrange to build config.h from config.in. Note that pcre.h is +dnl built differently, as it is just a "substitution" file. +dnl Manual says this macro should come right after AC_INIT. +AC_CONFIG_HEADER(config.h:config.in) + +dnl Provide the current PCRE version information. Do not use numbers +dnl with leading zeros for the minor version, as they end up in a C +dnl macro, and may be treated as octal constants. Stick to single +dnl digits for minor numbers less than 10. There are unlikely to be +dnl that many releases anyway. + +PCRE_MAJOR=5 +PCRE_MINOR=0 +PCRE_DATE=13-Sep-2004 +PCRE_VERSION=${PCRE_MAJOR}.${PCRE_MINOR} + +dnl Default values for miscellaneous macros + +POSIX_MALLOC_THRESHOLD=-DPOSIX_MALLOC_THRESHOLD=10 + +dnl Provide versioning information for libtool shared libraries that +dnl are built by default on Unix systems. + +PCRE_LIB_VERSION=0:1:0 +PCRE_POSIXLIB_VERSION=0:0:0 + +dnl Checks for programs. + +AC_PROG_CC + +dnl Checks for header files. + +AC_HEADER_STDC +AC_CHECK_HEADERS(limits.h) + +dnl Checks for typedefs, structures, and compiler characteristics. + +AC_C_CONST +AC_TYPE_SIZE_T + +dnl Checks for library functions. + +AC_CHECK_FUNCS(bcopy memmove strerror) + +dnl Handle --enable-shared-libraries + +LIBTOOL=./libtool +LIBSUFFIX=la +AC_ARG_ENABLE(shared, +[ --disable-shared build PCRE as a static library], +if test "$enableval" = "no"; then + LIBTOOL= + LIBSUFFIX=a +fi +) + +dnl Handle --enable-utf8 + +AC_ARG_ENABLE(utf8, +[ --enable-utf8 enable UTF8 support], +if test "$enableval" = "yes"; then + UTF8=-DSUPPORT_UTF8 +fi +) + +dnl Handle --enable-unicode-properties + +AC_ARG_ENABLE(unicode-properties, +[ --enable-unicode-properties enable Unicode properties support], +if test "$enableval" = "yes"; then + UCP=-DSUPPORT_UCP +fi +) + +dnl Handle --enable-newline-is-cr + +AC_ARG_ENABLE(newline-is-cr, +[ --enable-newline-is-cr use CR as the newline character], +if test "$enableval" = "yes"; then + NEWLINE=-DNEWLINE=13 +fi +) + +dnl Handle --enable-newline-is-lf + +AC_ARG_ENABLE(newline-is-lf, +[ --enable-newline-is-lf use LF as the newline character], +if test "$enableval" = "yes"; then + NEWLINE=-DNEWLINE=10 +fi +) + +dnl Handle --enable-ebcdic + +AC_ARG_ENABLE(ebcdic, +[ --enable-ebcdic assume EBCDIC coding rather than ASCII], +if test "$enableval" == "yes"; then + EBCDIC=-DEBCDIC=1 +fi +) + +dnl Handle --disable-stack-for-recursion + +AC_ARG_ENABLE(stack-for-recursion, +[ --disable-stack-for-recursion disable use of stack recursion when matching], +if test "$enableval" = "no"; then + NO_RECURSE=-DNO_RECURSE +fi +) + +dnl There doesn't seem to be a straightforward way of having parameters +dnl that set values, other than fudging the --with thing. So that's what +dnl I've done. + +dnl Handle --with-posix-malloc-threshold=n + +AC_ARG_WITH(posix-malloc-threshold, +[ --with-posix-malloc-threshold=5 threshold for POSIX malloc usage], + POSIX_MALLOC_THRESHOLD=-DPOSIX_MALLOC_THRESHOLD=$withval +) + +dnl Handle --with-link-size=n + +AC_ARG_WITH(link-size, +[ --with-link-size=2 internal link size (2, 3, or 4 allowed)], + LINK_SIZE=-DLINK_SIZE=$withval +) + +dnl Handle --with-match_limit=n + +AC_ARG_WITH(match-limit, +[ --with-match-limit=10000000 default limit on internal looping)], + MATCH_LIMIT=-DMATCH_LIMIT=$withval +) + +dnl Unicode character property support implies UTF-8 support + +if test "$UCP" != "" ; then + UTF8=-DSUPPORT_UTF8 +fi + +dnl "Export" these variables + +AC_SUBST(BUILD_EXEEXT) +AC_SUBST(BUILD_OBJEXT) +AC_SUBST(CC_FOR_BUILD) +AC_SUBST(CFLAGS_FOR_BUILD) +AC_SUBST(EBCDIC) +AC_SUBST(HAVE_MEMMOVE) +AC_SUBST(HAVE_STRERROR) +AC_SUBST(LIBTOOL) +AC_SUBST(LIBSUFFIX) +AC_SUBST(LINK_SIZE) +AC_SUBST(MATCH_LIMIT) +AC_SUBST(NEWLINE) +AC_SUBST(NO_RECURSE) +AC_SUBST(PCRE_MAJOR) +AC_SUBST(PCRE_MINOR) +AC_SUBST(PCRE_DATE) +AC_SUBST(PCRE_VERSION) +AC_SUBST(PCRE_LIB_VERSION) +AC_SUBST(PCRE_POSIXLIB_VERSION) +AC_SUBST(POSIX_MALLOC_THRESHOLD) +AC_SUBST(UCP) +AC_SUBST(UTF8) + + +if test "x$enable_shared" = "xno" ; then + AC_DEFINE([PCRE_STATIC],[1],[to link statically]) +fi + +dnl This must be last; it determines what files are written as well as config.h +AC_OUTPUT(Makefile pcre.h:pcre.in pcre-config,[chmod a+x pcre-config]) + diff --git a/trunk/srclib/pcre/dftables.c b/trunk/srclib/pcre/dftables.c new file mode 100644 index 0000000000..8458c60f1c --- /dev/null +++ b/trunk/srclib/pcre/dftables.c @@ -0,0 +1,173 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 is a support program to generate the file chartables.c, containing +character tables of various kinds. They are built according to the default C +locale and used as the default tables by PCRE. Now that pcre_maketables is +a function visible to the outside world, we make use of its code from here in +order to be consistent. */ + +#include +#include +#include + +#include "internal.h" + +#define DFTABLES /* maketables.c notices this */ +#include "maketables.c" + + +int main(int argc, char **argv) +{ +int i; +FILE *f; +const unsigned char *tables = pcre_maketables(); + +if (argc != 2) + { + fprintf(stderr, "dftables: one filename argument is required\n"); + return 1; + } + +f = fopen(argv[1], "w"); +if (f == NULL) + { + fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); + return 1; + } + +/* There are two fprintf() calls here, because gcc in pedantic mode complains +about the very long string otherwise. */ + +fprintf(f, + "/*************************************************\n" + "* Perl-Compatible Regular Expressions *\n" + "*************************************************/\n\n" + "/* This file is automatically written by the dftables auxiliary \n" + "program. If you edit it by hand, you might like to edit the Makefile to \n" + "prevent its ever being regenerated.\n\n"); +fprintf(f, + "This file is #included in the compilation of pcre.c to build the default\n" + "character tables which are used when no tables are passed to the compile\n" + "function. */\n\n" + "static unsigned char pcre_default_tables[] = {\n\n" + "/* This table is a lower casing table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, "/* This table is a case flipping table. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); + fprintf(f, "%3d", *tables++); + if (i != 255) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table contains bit maps for various character classes.\n" + "Each map is 32 bytes long and the bits run from the least\n" + "significant end of each byte. The classes that have their own\n" + "maps are: space, xdigit, digit, upper, lower, word, graph\n" + "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); + +fprintf(f, " "); +for (i = 0; i < cbit_length; i++) + { + if ((i & 7) == 0 && i != 0) + { + if ((i & 31) == 0) fprintf(f, "\n"); + fprintf(f, "\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != cbit_length - 1) fprintf(f, ","); + } +fprintf(f, ",\n\n"); + +fprintf(f, + "/* This table identifies various classes of character by individual bits:\n" + " 0x%02x white space character\n" + " 0x%02x letter\n" + " 0x%02x decimal digit\n" + " 0x%02x hexadecimal digit\n" + " 0x%02x alphanumeric or '_'\n" + " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", + ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, + ctype_meta); + +fprintf(f, " "); +for (i = 0; i < 256; i++) + { + if ((i & 7) == 0 && i != 0) + { + fprintf(f, " /* "); + if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); + if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); + fprintf(f, " */\n "); + } + fprintf(f, "0x%02x", *tables++); + if (i != 255) fprintf(f, ","); + } + +fprintf(f, "};/* "); +if (isprint(i-8)) fprintf(f, " %c -", i-8); + else fprintf(f, "%3d-", i-8); +if (isprint(i-1)) fprintf(f, " %c ", i-1); + else fprintf(f, "%3d", i-1); +fprintf(f, " */\n\n/* End of chartables.c */\n"); + +fclose(f); +return 0; +} + +/* End of dftables.c */ diff --git a/trunk/srclib/pcre/dftables.dsp b/trunk/srclib/pcre/dftables.dsp new file mode 100644 index 0000000000..3c8272b212 --- /dev/null +++ b/trunk/srclib/pcre/dftables.dsp @@ -0,0 +1,165 @@ +# Microsoft Developer Studio Project File - Name="dftables" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dftables - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dftables.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dftables.mak" CFG="dftables - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dftables - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dftables - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dftables - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\dftables" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\dftables" /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\dftables.pdb" /machine:I386 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\dftables.pdb" /machine:I386 /opt:ref +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "dftables - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\dftables" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\dftables" /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\dftables.pdb" /debug /machine:I386 /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\dftables.pdb" /debug /machine:I386 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "dftables - Win32 Release" +# Name "dftables - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\dftables.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hw" +# Begin Source File + +SOURCE=.\config.hw + +!IF "$(CFG)" == "dftables - Win32 Release" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "dftables - Win32 Debug" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\internal.h +# End Source File +# Begin Source File + +SOURCE=.\maketables.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\pcre.hw + +!IF "$(CFG)" == "dftables - Win32 Release" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "dftables - Win32 Debug" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# End Target +# End Project diff --git a/trunk/srclib/pcre/dll.mk b/trunk/srclib/pcre/dll.mk new file mode 100644 index 0000000000..d8b728e57e --- /dev/null +++ b/trunk/srclib/pcre/dll.mk @@ -0,0 +1,60 @@ +# dll.mk - auxilary Makefile to easy build dll's for mingw32 target +# ver. 0.6 of 1999-03-25 +# +# Homepage of this makefile - http://www.is.lg.ua/~paul/devel/ +# Homepage of original mingw32 project - +# http://www.fu.is.saga-u.ac.jp/~colin/gcc.html +# +# How to use: +# This makefile can: +# 1. Create automatical .def file from list of objects +# 2. Create .dll from objects and .def file, either automatical, or your +# hand-written (maybe) file, which must have same basename as dll +# WARNING! There MUST be object, which name match dll's name. Make sux. +# 3. Create import library from .def (as for .dll, only its name required, +# not dll itself) +# By convention implibs for dll have .dll.a suffix, e.g. libstuff.dll.a +# Why not just libstuff.a? 'Cos that's name for static lib, ok? +# Process divided into 3 phases because: +# 1. Pre-existent .def possible +# 2. Generating implib is enough time-consuming +# +# Variables: +# DLL_LDLIBS - libs for linking dll +# DLL_LDFLAGS - flags for linking dll +# +# By using $(DLL_SUFFIX) instead of 'dll', e.g. stuff.$(DLL_SUFFIX) +# you may help porting makefiles to other platforms +# +# Put this file in your make's include path (e.g. main include dir, for +# more information see include section in make doc). Put in the beginning +# of your own Makefile line "include dll.mk". Specify dependences, e.g.: +# +# Do all stuff in one step +# libstuff.dll.a: $(OBJECTS) stuff.def +# stuff.def: $(OBJECTS) +# +# Steps separated, pre-provided .def, link with user32 +# +# DLL_LDLIBS=-luser32 +# stuff.dll: $(OBJECTS) +# libstuff.dll.a: $(OBJECTS) + + +DLLWRAP=dllwrap +DLLTOOL=dlltool + +DLL_SUFFIX=dll + +.SUFFIXES: .o .$(DLL_SUFFIX) + +_%.def: %.o + $(DLLTOOL) --export-all --output-def $@ $^ + +%.$(DLL_SUFFIX): %.o + $(DLLWRAP) --dllname $(notdir $@) --driver-name $(CC) --def $*.def -o $@ $(filter %.o,$^) $(DLL_LDFLAGS) $(DLL_LDLIBS) + +lib%.$(DLL_SUFFIX).a:%.def + $(DLLTOOL) --dllname $(notdir $*.dll) --def $< --output-lib $@ + +# End diff --git a/trunk/srclib/pcre/doc/README_httpd b/trunk/srclib/pcre/doc/README_httpd new file mode 100644 index 0000000000..322c39c4f2 --- /dev/null +++ b/trunk/srclib/pcre/doc/README_httpd @@ -0,0 +1,6 @@ +The documentation directory has been omitted from this copy of PCRE +inside the httpd codebase because it's huge--over a megabyte of PCRE docs. + +The PCRE documentation directory is available in unmodified form in the +vendor branch. You can access it via web browser or Subversion checkout at +http://svn.apache.org/repos/asf/httpd/httpd/vendor/pcre/current/doc/ diff --git a/trunk/srclib/pcre/get.c b/trunk/srclib/pcre/get.c new file mode 100644 index 0000000000..225843e2e2 --- /dev/null +++ b/trunk/srclib/pcre/get.c @@ -0,0 +1,357 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2003 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains some convenience functions for extracting substrings +from the subject string after a regex match has succeeded. The original idea +for these functions came from Scott Wimer. */ + + +/* Include the internals header, which itself includes Standard C headers plus +the external pcre header. */ + +#include "internal.h" + + +/************************************************* +* Find number for named string * +*************************************************/ + +/* This function is used by the two extraction functions below, as well +as being generally available. + +Arguments: + code the compiled regex + stringname the name whose number is required + +Returns: the number of the named parentheses, or a negative number + (PCRE_ERROR_NOSUBSTRING) if not found +*/ + +int +pcre_get_stringnumber(const pcre *code, const char *stringname) +{ +int rc; +int entrysize; +int top, bot; +uschar *nametable; + +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; + +bot = 0; +while (top > bot) + { + int mid = (top + bot) / 2; + uschar *entry = nametable + entrysize*mid; + int c = strcmp(stringname, (char *)(entry + 2)); + if (c == 0) return (entry[0] << 8) + entry[1]; + if (c > 0) bot = mid + 1; else top = mid; + } + +return PCRE_ERROR_NOSUBSTRING; +} + + + +/************************************************* +* Copy captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer. +Note that we use memcpy() rather than strncpy() in case there are binary zeros +in the string. + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringnumber the number of the required substring + buffer where to put the substring + size the size of the buffer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) buffer too small + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +int +pcre_copy_substring(const char *subject, int *ovector, int stringcount, + int stringnumber, char *buffer, int size) +{ +int yield; +if (stringnumber < 0 || stringnumber >= stringcount) + return PCRE_ERROR_NOSUBSTRING; +stringnumber *= 2; +yield = ovector[stringnumber+1] - ovector[stringnumber]; +if (size < yield + 1) return PCRE_ERROR_NOMEMORY; +memcpy(buffer, subject + ovector[stringnumber], yield); +buffer[yield] = 0; +return yield; +} + + + +/************************************************* +* Copy named captured string to given buffer * +*************************************************/ + +/* This function copies a single captured substring into a given buffer, +identifying it by name. + +Arguments: + code the compiled regex + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringname the name of the required substring + buffer where to put the substring + size the size of the buffer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) buffer too small + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +int +pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, + int stringcount, const char *stringname, char *buffer, int size) +{ +int n = pcre_get_stringnumber(code, stringname); +if (n <= 0) return n; +return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); +} + + + +/************************************************* +* Copy all captured strings to new store * +*************************************************/ + +/* This function gets one chunk of store and builds a list of pointers and all +of the captured substrings in it. A NULL pointer is put on the end of the list. + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + listptr set to point to the list of pointers + +Returns: if successful: 0 + if not successful: + PCRE_ERROR_NOMEMORY (-6) failed to get store +*/ + +int +pcre_get_substring_list(const char *subject, int *ovector, int stringcount, + const char ***listptr) +{ +int i; +int size = sizeof(char *); +int double_count = stringcount * 2; +char **stringlist; +char *p; + +for (i = 0; i < double_count; i += 2) + size += sizeof(char *) + ovector[i+1] - ovector[i] + 1; + +stringlist = (char **)(pcre_malloc)(size); +if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; + +*listptr = (const char **)stringlist; +p = (char *)(stringlist + stringcount + 1); + +for (i = 0; i < double_count; i += 2) + { + int len = ovector[i+1] - ovector[i]; + memcpy(p, subject + ovector[i], len); + *stringlist++ = p; + p += len; + *p++ = 0; + } + +*stringlist = NULL; +return 0; +} + + + +/************************************************* +* Free store obtained by get_substring_list * +*************************************************/ + +/* This function exists for the benefit of people calling PCRE from non-C +programs that can call its functions, but not free() or (pcre_free)() directly. + +Argument: the result of a previous pcre_get_substring_list() +Returns: nothing +*/ + +void +pcre_free_substring_list(const char **pointer) +{ +(pcre_free)((void *)pointer); +} + + + +/************************************************* +* Copy captured string to new store * +*************************************************/ + +/* This function copies a single captured substring into a piece of new +store + +Arguments: + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringnumber the number of the required substring + stringptr where to put a pointer to the substring + +Returns: if successful: + the length of the string, not including the zero that + is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) failed to get store + PCRE_ERROR_NOSUBSTRING (-7) substring not present +*/ + +int +pcre_get_substring(const char *subject, int *ovector, int stringcount, + int stringnumber, const char **stringptr) +{ +int yield; +char *substring; +if (stringnumber < 0 || stringnumber >= stringcount) + return PCRE_ERROR_NOSUBSTRING; +stringnumber *= 2; +yield = ovector[stringnumber+1] - ovector[stringnumber]; +substring = (char *)(pcre_malloc)(yield + 1); +if (substring == NULL) return PCRE_ERROR_NOMEMORY; +memcpy(substring, subject + ovector[stringnumber], yield); +substring[yield] = 0; +*stringptr = substring; +return yield; +} + + + +/************************************************* +* Copy named captured string to new store * +*************************************************/ + +/* This function copies a single captured substring, identified by name, into +new store. + +Arguments: + code the compiled regex + subject the subject string that was matched + ovector pointer to the offsets table + stringcount the number of substrings that were captured + (i.e. the yield of the pcre_exec call, unless + that was zero, in which case it should be 1/3 + of the offset table size) + stringname the name of the required substring + stringptr where to put the pointer + +Returns: if successful: + the length of the copied string, not including the zero + that is put on the end; can be zero + if not successful: + PCRE_ERROR_NOMEMORY (-6) couldn't get memory + PCRE_ERROR_NOSUBSTRING (-7) no such captured substring +*/ + +int +pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, + int stringcount, const char *stringname, const char **stringptr) +{ +int n = pcre_get_stringnumber(code, stringname); +if (n <= 0) return n; +return pcre_get_substring(subject, ovector, stringcount, n, stringptr); +} + + + + +/************************************************* +* Free store obtained by get_substring * +*************************************************/ + +/* This function exists for the benefit of people calling PCRE from non-C +programs that can call its functions, but not free() or (pcre_free)() directly. + +Argument: the result of a previous pcre_get_substring() +Returns: nothing +*/ + +void +pcre_free_substring(const char *pointer) +{ +(pcre_free)((void *)pointer); +} + +/* End of get.c */ diff --git a/trunk/srclib/pcre/install-sh b/trunk/srclib/pcre/install-sh new file mode 100755 index 0000000000..e9de23842d --- /dev/null +++ b/trunk/srclib/pcre/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/trunk/srclib/pcre/internal.h b/trunk/srclib/pcre/internal.h new file mode 100644 index 0000000000..5d1433178f --- /dev/null +++ b/trunk/srclib/pcre/internal.h @@ -0,0 +1,752 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + + +/* This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file doc/Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 header contains definitions that are shared between the different +modules, but which are not relevant to the outside. */ + +/* Get the definitions provided by running "configure" */ + +#include "config.h" + +/* Standard C headers plus the external interface definition. The only time +setjmp and stdarg are used is when NO_RECURSE is set. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PCRE_SPY +#define PCRE_DEFINITION /* Win32 __declspec(export) trigger for .dll */ +#endif + +/* We need to have types that specify unsigned 16-bit and 32-bit integers. We +cannot determine these outside the compilation (e.g. by running a program as +part of "configure") because PCRE is often cross-compiled for use on other +systems. Instead we make use of the maximum sizes that are available at +preprocessor time in standard C environments. */ + +#if USHRT_MAX == 65535 + typedef unsigned short pcre_uint16; +#elif UINT_MAX == 65535 + typedef unsigned int pcre_uint16; +#else + #error Cannot determine a type for 16-bit unsigned integers +#endif + +#if UINT_MAX == 4294967295 + typedef unsigned int pcre_uint32; +#elif ULONG_MAX == 4294967295 + typedef unsigned long int pcre_uint32; +#else + #error Cannot determine a type for 32-bit unsigned integers +#endif + +/* All character handling must be done as unsigned characters. Otherwise there +are problems with top-bit-set characters and functions such as isspace(). +However, we leave the interface to the outside world as char *, because that +should make things easier for callers. We define a short type for unsigned char +to save lots of typing. I tried "uchar", but it causes problems on Digital +Unix, where it is defined in sys/types, so use "uschar" instead. */ + +typedef unsigned char uschar; + +/* Include the public PCRE header */ + +#include "pcre.h" + +/* When compiling for use with the Virtual Pascal compiler, these functions +need to have their names changed. PCRE must be compiled with the -DVPCOMPAT +option on the command line. */ + +#ifdef VPCOMPAT +#define strncmp(s1,s2,m) _strncmp(s1,s2,m) +#define memcpy(d,s,n) _memcpy(d,s,n) +#define memmove(d,s,n) _memmove(d,s,n) +#define memset(s,c,n) _memset(s,c,n) +#else /* VPCOMPAT */ + +/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), +define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY +is set. Otherwise, include an emulating function for those systems that have +neither (there some non-Unix environments where this is the case). This assumes +that all calls to memmove are moving strings upwards in store, which is the +case in PCRE. */ + +#if ! HAVE_MEMMOVE +#undef memmove /* some systems may have a macro */ +#if HAVE_BCOPY +#define memmove(a, b, c) bcopy(b, a, c) +#else /* HAVE_BCOPY */ +void * +pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n) +{ +int i; +dest += n; +src += n; +for (i = 0; i < n; ++i) *(--dest) = *(--src); +} +#define memmove(a, b, c) pcre_memmove(a, b, c) +#endif /* not HAVE_BCOPY */ +#endif /* not HAVE_MEMMOVE */ +#endif /* not VPCOMPAT */ + + +/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored +in big-endian order) by default. These are used, for example, to link from the +start of a subpattern to its alternatives and its end. The use of 2 bytes per +offset limits the size of the compiled regex to around 64K, which is big enough +for almost everybody. However, I received a request for an even bigger limit. +For this reason, and also to make the code easier to maintain, the storing and +loading of offsets from the byte string is now handled by the macros that are +defined here. + +The macros are controlled by the value of LINK_SIZE. This defaults to 2 in +the config.h file, but can be overridden by using -D on the command line. This +is automated on Unix systems via the "configure" command. */ + +#if LINK_SIZE == 2 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 8), \ + (a[(n)+1] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 8) | (a)[(n)+1]) + +#define MAX_PATTERN_SIZE (1 << 16) + + +#elif LINK_SIZE == 3 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) >> 8), \ + (a[(n)+2] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) + +#define MAX_PATTERN_SIZE (1 << 24) + + +#elif LINK_SIZE == 4 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 24), \ + (a[(n)+1] = (d) >> 16), \ + (a[(n)+2] = (d) >> 8), \ + (a[(n)+3] = (d) & 255) + +#define GET(a,n) \ + (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) + +#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ + + +#else +#error LINK_SIZE must be either 2, 3, or 4 +#endif + + +/* Convenience macro defined in terms of the others */ + +#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE + + +/* PCRE uses some other 2-byte quantities that do not change when the size of +offsets changes. There are used for repeat counts and for other things such as +capturing parenthesis numbers in back references. */ + +#define PUT2(a,n,d) \ + a[n] = (d) >> 8; \ + a[(n)+1] = (d) & 255 + +#define GET2(a,n) \ + (((a)[n] << 8) | (a)[(n)+1]) + +#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2 + + +/* In case there is no definition of offsetof() provided - though any proper +Standard C system should have one. */ + +#ifndef offsetof +#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) +#endif + + +/* These are the public options that can change during matching. */ + +#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) + +/* Private options flags start at the most significant end of the four bytes, +but skip the top bit so we can use ints for convenience without getting tangled +with negative values. The public options defined in pcre.h start at the least +significant end. Make sure they don't overlap, though now that we have expanded +to four bytes, there is plenty of space. */ + +#define PCRE_FIRSTSET 0x40000000 /* first_byte is set */ +#define PCRE_REQCHSET 0x20000000 /* req_byte is set */ +#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */ +#define PCRE_ICHANGED 0x08000000 /* i option changes within regex */ +#define PCRE_NOPARTIAL 0x04000000 /* can't use partial with this regex */ + +/* Options for the "extra" block produced by pcre_study(). */ + +#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ + +/* Masks for identifying the public options which are permitted at compile +time, run time or study time, respectively. */ + +#define PUBLIC_OPTIONS \ + (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \ + PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \ + PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT) + +#define PUBLIC_EXEC_OPTIONS \ + (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \ + PCRE_PARTIAL) + +#define PUBLIC_STUDY_OPTIONS 0 /* None defined */ + +/* Magic number to provide a small check against being handed junk. */ + +#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ + +/* Negative values for the firstchar and reqchar variables */ + +#define REQ_UNSET (-2) +#define REQ_NONE (-1) + +/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a +variable-length repeat, or a anything other than literal characters. */ + +#define REQ_CASELESS 0x0100 /* indicates caselessness */ +#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */ + +/* Miscellaneous definitions */ + +typedef int BOOL; + +#define FALSE 0 +#define TRUE 1 + +/* Escape items that are just an encoding of a particular data value. Note that +ESC_n is defined as yet another macro, which is set in config.h to either \n +(the default) or \r (which some people want). */ + +#ifndef ESC_e +#define ESC_e 27 +#endif + +#ifndef ESC_f +#define ESC_f '\f' +#endif + +#ifndef ESC_n +#define ESC_n NEWLINE +#endif + +#ifndef ESC_r +#define ESC_r '\r' +#endif + +/* We can't officially use ESC_t because it is a POSIX reserved identifier +(presumably because of all the others like size_t). */ + +#ifndef ESC_tee +#define ESC_tee '\t' +#endif + +/* These are escaped items that aren't just an encoding of a particular data +value such as \n. They must have non-zero values, as check_escape() returns +their negation. Also, they must appear in the same order as in the opcode +definitions below, up to ESC_z. There's a dummy for OP_ANY because it +corresponds to "." rather than an escape sequence. The final one must be +ESC_REF as subsequent values are used for \1, \2, \3, etc. There is are two +tests in the code for an escape greater than ESC_b and less than ESC_Z to +detect the types that may be repeated. These are the types that consume +characters. If any new escapes are put in between that don't consume a +character, that code will have to change. */ + +enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, + ESC_w, ESC_dum1, ESC_C, ESC_P, ESC_p, ESC_X, ESC_Z, ESC_z, ESC_E, + ESC_Q, ESC_REF }; + +/* Flag bits and data types for the extended class (OP_XCLASS) for classes that +contain UTF-8 characters with values greater than 255. */ + +#define XCL_NOT 0x01 /* Flag: this is a negative class */ +#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ + +#define XCL_END 0 /* Marks end of individual items */ +#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ +#define XCL_RANGE 2 /* A range (two multibyte chars) follows */ +#define XCL_PROP 3 /* Unicode property (one property code) follows */ +#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ + + +/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets +that extract substrings. Starting from 1 (i.e. after OP_END), the values up to +OP_EOD must correspond in order to the list of escapes immediately above. +Note that whenever this list is updated, the two macro definitions that follow +must also be updated to match. */ + +enum { + OP_END, /* 0 End of pattern */ + + /* Values corresponding to backslashed metacharacters */ + + OP_SOD, /* 1 Start of data: \A */ + OP_SOM, /* 2 Start of match (subject + offset): \G */ + OP_NOT_WORD_BOUNDARY, /* 3 \B */ + OP_WORD_BOUNDARY, /* 4 \b */ + OP_NOT_DIGIT, /* 5 \D */ + OP_DIGIT, /* 6 \d */ + OP_NOT_WHITESPACE, /* 7 \S */ + OP_WHITESPACE, /* 8 \s */ + OP_NOT_WORDCHAR, /* 9 \W */ + OP_WORDCHAR, /* 10 \w */ + OP_ANY, /* 11 Match any character */ + OP_ANYBYTE, /* 12 Match any byte (\C); different to OP_ANY for UTF-8 */ + OP_NOTPROP, /* 13 \P (not Unicode property) */ + OP_PROP, /* 14 \p (Unicode property) */ + OP_EXTUNI, /* 15 \X (extended Unicode sequence */ + OP_EODN, /* 16 End of data or \n at end of data: \Z. */ + OP_EOD, /* 17 End of data: \z */ + + OP_OPT, /* 18 Set runtime options */ + OP_CIRC, /* 19 Start of line - varies with multiline switch */ + OP_DOLL, /* 20 End of line - varies with multiline switch */ + OP_CHAR, /* 21 Match one character, casefully */ + OP_CHARNC, /* 22 Match one character, caselessly */ + OP_NOT, /* 23 Match anything but the following char */ + + OP_STAR, /* 24 The maximizing and minimizing versions of */ + OP_MINSTAR, /* 25 all these opcodes must come in pairs, with */ + OP_PLUS, /* 26 the minimizing one second. */ + OP_MINPLUS, /* 27 This first set applies to single characters */ + OP_QUERY, /* 28 */ + OP_MINQUERY, /* 29 */ + OP_UPTO, /* 30 From 0 to n matches */ + OP_MINUPTO, /* 31 */ + OP_EXACT, /* 32 Exactly n matches */ + + OP_NOTSTAR, /* 33 The maximizing and minimizing versions of */ + OP_NOTMINSTAR, /* 34 all these opcodes must come in pairs, with */ + OP_NOTPLUS, /* 35 the minimizing one second. */ + OP_NOTMINPLUS, /* 36 This set applies to "not" single characters */ + OP_NOTQUERY, /* 37 */ + OP_NOTMINQUERY, /* 38 */ + OP_NOTUPTO, /* 39 From 0 to n matches */ + OP_NOTMINUPTO, /* 40 */ + OP_NOTEXACT, /* 41 Exactly n matches */ + + OP_TYPESTAR, /* 42 The maximizing and minimizing versions of */ + OP_TYPEMINSTAR, /* 43 all these opcodes must come in pairs, with */ + OP_TYPEPLUS, /* 44 the minimizing one second. These codes must */ + OP_TYPEMINPLUS, /* 45 be in exactly the same order as those above. */ + OP_TYPEQUERY, /* 46 This set applies to character types such as \d */ + OP_TYPEMINQUERY, /* 47 */ + OP_TYPEUPTO, /* 48 From 0 to n matches */ + OP_TYPEMINUPTO, /* 49 */ + OP_TYPEEXACT, /* 50 Exactly n matches */ + + OP_CRSTAR, /* 51 The maximizing and minimizing versions of */ + OP_CRMINSTAR, /* 52 all these opcodes must come in pairs, with */ + OP_CRPLUS, /* 53 the minimizing one second. These codes must */ + OP_CRMINPLUS, /* 54 be in exactly the same order as those above. */ + OP_CRQUERY, /* 55 These are for character classes and back refs */ + OP_CRMINQUERY, /* 56 */ + OP_CRRANGE, /* 57 These are different to the three sets above. */ + OP_CRMINRANGE, /* 58 */ + + OP_CLASS, /* 59 Match a character class, chars < 256 only */ + OP_NCLASS, /* 60 Same, but the bitmap was created from a negative + class - the difference is relevant only when a UTF-8 + character > 255 is encountered. */ + + OP_XCLASS, /* 61 Extended class for handling UTF-8 chars within the + class. This does both positive and negative. */ + + OP_REF, /* 62 Match a back reference */ + OP_RECURSE, /* 63 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 64 Call out to external function if provided */ + + OP_ALT, /* 65 Start of alternation */ + OP_KET, /* 66 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 67 These two must remain together and in this */ + OP_KETRMIN, /* 68 order. They are for groups the repeat for ever. */ + + /* The assertions must come before ONCE and COND */ + + OP_ASSERT, /* 69 Positive lookahead */ + OP_ASSERT_NOT, /* 70 Negative lookahead */ + OP_ASSERTBACK, /* 71 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 72 Negative lookbehind */ + OP_REVERSE, /* 73 Move pointer back - used in lookbehind assertions */ + + /* ONCE and COND must come after the assertions, with ONCE first, as there's + a test for >= ONCE for a subpattern that isn't an assertion. */ + + OP_ONCE, /* 74 Once matched, don't back up into the subpattern */ + OP_COND, /* 75 Conditional group */ + OP_CREF, /* 76 Used to hold an extraction string number (cond ref) */ + + OP_BRAZERO, /* 77 These two must remain together and in this */ + OP_BRAMINZERO, /* 78 order. */ + + OP_BRANUMBER, /* 79 Used for extracting brackets whose number is greater + than can fit into an opcode. */ + + OP_BRA /* 80 This and greater values are used for brackets that + extract substrings up to EXTRACT_BASIC_MAX. After + that, use is made of OP_BRANUMBER. */ +}; + +/* WARNING WARNING WARNING: There is an implicit assumption in pcre.c and +study.c that all opcodes are less than 128 in value. This makes handling UTF-8 +character sequences easier. */ + +/* The highest extraction number before we have to start using additional +bytes. (Originally PCRE didn't have support for extraction counts highter than +this number.) The value is limited by the number of opcodes left after OP_BRA, +i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional +opcodes. */ + +#define EXTRACT_BASIC_MAX 100 + + +/* This macro defines textual names for all the opcodes. There are used only +for debugging, in pcre.c when DEBUG is defined, and also in pcretest.c. The +macro is referenced only in printint.c. */ + +#define OP_NAME_LIST \ + "End", "\\A", "\\G", "\\B", "\\b", "\\D", "\\d", \ + "\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", \ + "notprop", "prop", "extuni", \ + "\\Z", "\\z", \ + "Opt", "^", "$", "char", "charnc", "not", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*", "*?", "+", "+?", "?", "??", "{", "{", \ + "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \ + "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \ + "AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cond ref",\ + "Brazero", "Braminzero", "Branumber", "Bra" + + +/* This macro defines the length of fixed length operations in the compiled +regex. The lengths are used when searching for specific things, and also in the +debugging printing of a compiled regex. We use a macro so that it can be +incorporated both into pcre.c and pcretest.c without being publicly exposed. + +As things have been extended, some of these are no longer fixed lenths, but are +minima instead. For example, the length of a single-character repeat may vary +in UTF-8 mode. The code that uses this table must know about such things. */ + +#define OP_LENGTHS \ + 1, /* End */ \ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* \A, \G, \B, \B, \D, \d, \S, \s, \W, \w */ \ + 1, 1, /* Any, Anybyte */ \ + 2, 2, 1, /* NOTPROP, PROP, EXTUNI */ \ + 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \ + 2, /* Char - the minimum length */ \ + 2, /* Charnc - the minimum length */ \ + 2, /* not */ \ + /* Positive single-char repeats ** These are */ \ + 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ + 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \ + /* Negative single-char repeats - only for chars < 256 */ \ + 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ + 4, 4, 4, /* NOT upto, minupto, exact */ \ + /* Positive type repeats */ \ + 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ + 4, 4, 4, /* Type upto, minupto, exact */ \ + /* Character class & ref repeats */ \ + 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ + 5, 5, /* CRRANGE, CRMINRANGE */ \ + 33, /* CLASS */ \ + 33, /* NCLASS */ \ + 0, /* XCLASS - variable length */ \ + 3, /* REF */ \ + 1+LINK_SIZE, /* RECURSE */ \ + 2+2*LINK_SIZE, /* CALLOUT */ \ + 1+LINK_SIZE, /* Alt */ \ + 1+LINK_SIZE, /* Ket */ \ + 1+LINK_SIZE, /* KetRmax */ \ + 1+LINK_SIZE, /* KetRmin */ \ + 1+LINK_SIZE, /* Assert */ \ + 1+LINK_SIZE, /* Assert not */ \ + 1+LINK_SIZE, /* Assert behind */ \ + 1+LINK_SIZE, /* Assert behind not */ \ + 1+LINK_SIZE, /* Reverse */ \ + 1+LINK_SIZE, /* Once */ \ + 1+LINK_SIZE, /* COND */ \ + 3, /* CREF */ \ + 1, 1, /* BRAZERO, BRAMINZERO */ \ + 3, /* BRANUMBER */ \ + 1+LINK_SIZE /* BRA */ \ + + +/* A magic value for OP_CREF to indicate the "in recursion" condition. */ + +#define CREF_RECURSE 0xffff + +/* The texts of compile-time error messages are defined as macros here so that +they can be accessed by the POSIX wrapper and converted into error codes. Yes, +I could have used error codes in the first place, but didn't feel like changing +just to accommodate the POSIX wrapper. */ + +#define ERR1 "\\ at end of pattern" +#define ERR2 "\\c at end of pattern" +#define ERR3 "unrecognized character follows \\" +#define ERR4 "numbers out of order in {} quantifier" +#define ERR5 "number too big in {} quantifier" +#define ERR6 "missing terminating ] for character class" +#define ERR7 "invalid escape sequence in character class" +#define ERR8 "range out of order in character class" +#define ERR9 "nothing to repeat" +#define ERR10 "operand of unlimited repeat could match the empty string" +#define ERR11 "internal error: unexpected repeat" +#define ERR12 "unrecognized character after (?" +#define ERR13 "POSIX named classes are supported only within a class" +#define ERR14 "missing )" +#define ERR15 "reference to non-existent subpattern" +#define ERR16 "erroffset passed as NULL" +#define ERR17 "unknown option bit(s) set" +#define ERR18 "missing ) after comment" +#define ERR19 "parentheses nested too deeply" +#define ERR20 "regular expression too large" +#define ERR21 "failed to get memory" +#define ERR22 "unmatched parentheses" +#define ERR23 "internal error: code overflow" +#define ERR24 "unrecognized character after (?<" +#define ERR25 "lookbehind assertion is not fixed length" +#define ERR26 "malformed number after (?(" +#define ERR27 "conditional group contains more than two branches" +#define ERR28 "assertion expected after (?(" +#define ERR29 "(?R or (?digits must be followed by )" +#define ERR30 "unknown POSIX class name" +#define ERR31 "POSIX collating elements are not supported" +#define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support" +#define ERR33 "spare error" +#define ERR34 "character value in \\x{...} sequence is too large" +#define ERR35 "invalid condition (?(0)" +#define ERR36 "\\C not allowed in lookbehind assertion" +#define ERR37 "PCRE does not support \\L, \\l, \\N, \\U, or \\u" +#define ERR38 "number after (?C is > 255" +#define ERR39 "closing ) for (?C expected" +#define ERR40 "recursive call could loop indefinitely" +#define ERR41 "unrecognized character after (?P" +#define ERR42 "syntax error after (?P" +#define ERR43 "two named groups have the same name" +#define ERR44 "invalid UTF-8 string" +#define ERR45 "support for \\P, \\p, and \\X has not been compiled" +#define ERR46 "malformed \\P or \\p sequence" +#define ERR47 "unknown property name after \\P or \\p" + +/* The real format of the start of the pcre block; the index of names and the +code vector run on as long as necessary after the end. We store an explicit +offset to the name table so that if a regex is compiled on one host, saved, and +then run on another where the size of pointers is different, all might still +be well. For the case of compiled-on-4 and run-on-8, we include an extra +pointer that is always NULL. For future-proofing, we also include a few dummy +fields - even though you can never get this planning right! + +NOTE NOTE NOTE: +Because people can now save and re-use compiled patterns, any additions to this +structure should be made at the end, and something earlier (e.g. a new +flag in the options or one of the dummy fields) should indicate that the new +fields are present. Currently PCRE always sets the dummy fields to zero. +NOTE NOTE NOTE: +*/ + +typedef struct real_pcre { + pcre_uint32 magic_number; + pcre_uint32 size; /* Total that was malloced */ + pcre_uint32 options; + pcre_uint32 dummy1; /* For future use, maybe */ + + pcre_uint16 top_bracket; + pcre_uint16 top_backref; + pcre_uint16 first_byte; + pcre_uint16 req_byte; + pcre_uint16 name_table_offset; /* Offset to name table that follows */ + pcre_uint16 name_entry_size; /* Size of any name items */ + pcre_uint16 name_count; /* Number of name items */ + pcre_uint16 dummy2; /* For future use, maybe */ + + const unsigned char *tables; /* Pointer to tables or NULL for std */ + const unsigned char *nullpad; /* NULL padding */ +} real_pcre; + +/* The format of the block used to store data from pcre_study(). The same +remark (see NOTE above) about extending this structure applies. */ + +typedef struct pcre_study_data { + pcre_uint32 size; /* Total that was malloced */ + pcre_uint32 options; + uschar start_bits[32]; +} pcre_study_data; + +/* Structure for passing "static" information around between the functions +doing the compiling, so that they are thread-safe. */ + +typedef struct compile_data { + const uschar *lcc; /* Points to lower casing table */ + const uschar *fcc; /* Points to case-flipping table */ + const uschar *cbits; /* Points to character type table */ + const uschar *ctypes; /* Points to table of type maps */ + const uschar *start_code; /* The start of the compiled code */ + const uschar *start_pattern; /* The start of the pattern */ + uschar *name_table; /* The name/number table */ + int names_found; /* Number of entries so far */ + int name_entry_size; /* Size of each entry */ + int top_backref; /* Maximum back reference */ + unsigned int backref_map; /* Bitmap of low back refs */ + int req_varyopt; /* "After variable item" flag for reqbyte */ + BOOL nopartial; /* Set TRUE if partial won't work */ +} compile_data; + +/* Structure for maintaining a chain of pointers to the currently incomplete +branches, for testing for left recursion. */ + +typedef struct branch_chain { + struct branch_chain *outer; + uschar *current; +} branch_chain; + +/* Structure for items in a linked list that represents an explicit recursive +call within the pattern. */ + +typedef struct recursion_info { + struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ + int group_num; /* Number of group that was called */ + const uschar *after_call; /* "Return value": points after the call in the expr */ + const uschar *save_start; /* Old value of md->start_match */ + int *offset_save; /* Pointer to start of saved offsets */ + int saved_max; /* Number of saved offsets */ +} recursion_info; + +/* When compiling in a mode that doesn't use recursive calls to match(), +a structure is used to remember local variables on the heap. It is defined in +pcre.c, close to the match() function, so that it is easy to keep it in step +with any changes of local variable. However, the pointer to the current frame +must be saved in some "static" place over a longjmp(). We declare the +structure here so that we can put a pointer in the match_data structure. +NOTE: This isn't used for a "normal" compilation of pcre. */ + +struct heapframe; + +/* Structure for passing "static" information around between the functions +doing the matching, so that they are thread-safe. */ + +typedef struct match_data { + unsigned long int match_call_count; /* As it says */ + unsigned long int match_limit;/* As it says */ + int *offset_vector; /* Offset vector */ + int offset_end; /* One past the end */ + int offset_max; /* The maximum usable for return data */ + const uschar *lcc; /* Points to lower casing table */ + const uschar *ctypes; /* Points to table of type maps */ + BOOL offset_overflow; /* Set if too many extractions */ + BOOL notbol; /* NOTBOL flag */ + BOOL noteol; /* NOTEOL flag */ + BOOL utf8; /* UTF8 flag */ + BOOL endonly; /* Dollar not before final \n */ + BOOL notempty; /* Empty string match not wanted */ + BOOL partial; /* PARTIAL flag */ + BOOL hitend; /* Hit the end of the subject at some point */ + const uschar *start_code; /* For use when recursing */ + const uschar *start_subject; /* Start of the subject string */ + const uschar *end_subject; /* End of the subject string */ + const uschar *start_match; /* Start of this match attempt */ + const uschar *end_match_ptr; /* Subject position at end match */ + int end_offset_top; /* Highwater mark at end of match */ + int capture_last; /* Most recent capture number */ + int start_offset; /* The start offset value */ + recursion_info *recursive; /* Linked list of recursion data */ + void *callout_data; /* To pass back to callouts */ + struct heapframe *thisframe; /* Used only when compiling for no recursion */ +} match_data; + +/* Bit definitions for entries in the pcre_ctypes table. */ + +#define ctype_space 0x01 +#define ctype_letter 0x02 +#define ctype_digit 0x04 +#define ctype_xdigit 0x08 +#define ctype_word 0x10 /* alphameric or '_' */ +#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ + +/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set +of bits for a class map. Some classes are built by combining these tables. */ + +#define cbit_space 0 /* [:space:] or \s */ +#define cbit_xdigit 32 /* [:xdigit:] */ +#define cbit_digit 64 /* [:digit:] or \d */ +#define cbit_upper 96 /* [:upper:] */ +#define cbit_lower 128 /* [:lower:] */ +#define cbit_word 160 /* [:word:] or \w */ +#define cbit_graph 192 /* [:graph:] */ +#define cbit_print 224 /* [:print:] */ +#define cbit_punct 256 /* [:punct:] */ +#define cbit_cntrl 288 /* [:cntrl:] */ +#define cbit_length 320 /* Length of the cbits table */ + +/* Offsets of the various tables from the base tables pointer, and +total length. */ + +#define lcc_offset 0 +#define fcc_offset 256 +#define cbits_offset 512 +#define ctypes_offset (cbits_offset + cbit_length) +#define tables_length (ctypes_offset + 256) + +/* End of internal.h */ diff --git a/trunk/srclib/pcre/libpcre.def b/trunk/srclib/pcre/libpcre.def new file mode 100644 index 0000000000..2b35d10ba9 --- /dev/null +++ b/trunk/srclib/pcre/libpcre.def @@ -0,0 +1,19 @@ +LIBRARY libpcre +EXPORTS +pcre_malloc +pcre_free +pcre_config +pcre_callout +pcre_compile +pcre_copy_substring +pcre_exec +pcre_get_substring +pcre_get_stringnumber +pcre_get_substring_list +pcre_free_substring +pcre_free_substring_list +pcre_info +pcre_fullinfo +pcre_maketables +pcre_study +pcre_version diff --git a/trunk/srclib/pcre/libpcre.pc.in b/trunk/srclib/pcre/libpcre.pc.in new file mode 100644 index 0000000000..4784401c84 --- /dev/null +++ b/trunk/srclib/pcre/libpcre.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre +Description: PCRE - Perl compatible regular expressions C library +Version: @PCRE_VERSION@ +Libs: -L${libdir} -lpcre +Cflags: -I${includedir} diff --git a/trunk/srclib/pcre/libpcreposix.def b/trunk/srclib/pcre/libpcreposix.def new file mode 100644 index 0000000000..572344009e --- /dev/null +++ b/trunk/srclib/pcre/libpcreposix.def @@ -0,0 +1,24 @@ +LIBRARY libpcreposix +EXPORTS +pcre_malloc +pcre_free +pcre_config +pcre_callout +pcre_compile +pcre_copy_substring +pcre_exec +pcre_get_substring +pcre_get_stringnumber +pcre_get_substring_list +pcre_free_substring +pcre_free_substring_list +pcre_info +pcre_fullinfo +pcre_maketables +pcre_study +pcre_version + +regcomp +regexec +regerror +regfree diff --git a/trunk/srclib/pcre/maketables.c b/trunk/srclib/pcre/maketables.c new file mode 100644 index 0000000000..f1c7b9a5c4 --- /dev/null +++ b/trunk/srclib/pcre/maketables.c @@ -0,0 +1,146 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + +Written by: Philip Hazel + + Copyright (c) 1997-2003 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 file is compiled on its own as part of the PCRE library. However, +it is also included in the compilation of dftables.c, in which case the macro +DFTABLES is defined. */ + +#ifndef DFTABLES +#include "internal.h" +#endif + + + +/************************************************* +* Create PCRE character tables * +*************************************************/ + +/* This function builds a set of character tables for use by PCRE and returns +a pointer to them. They are build using the ctype functions, and consequently +their contents will depend upon the current locale setting. When compiled as +part of the library, the store is obtained via pcre_malloc(), but when compiled +inside dftables, use malloc(). + +Arguments: none +Returns: pointer to the contiguous block of data +*/ + +const unsigned char * +pcre_maketables(void) +{ +unsigned char *yield, *p; +int i; + +#ifndef DFTABLES +yield = (unsigned char*)(pcre_malloc)(tables_length); +#else +yield = (unsigned char*)malloc(tables_length); +#endif + +if (yield == NULL) return NULL; +p = yield; + +/* First comes the lower casing table */ + +for (i = 0; i < 256; i++) *p++ = tolower(i); + +/* Next the case-flipping table */ + +for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); + +/* Then the character class tables. Don't try to be clever and save effort +on exclusive ones - in some locales things may be different. Note that the +table for "space" includes everything "isspace" gives, including VT in the +default locale. This makes it work for the POSIX class [:space:]. */ + +memset(p, 0, cbit_length); +for (i = 0; i < 256; i++) + { + if (isdigit(i)) + { + p[cbit_digit + i/8] |= 1 << (i&7); + p[cbit_word + i/8] |= 1 << (i&7); + } + if (isupper(i)) + { + p[cbit_upper + i/8] |= 1 << (i&7); + p[cbit_word + i/8] |= 1 << (i&7); + } + if (islower(i)) + { + p[cbit_lower + i/8] |= 1 << (i&7); + p[cbit_word + i/8] |= 1 << (i&7); + } + if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); + if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); + if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); + if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); + if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); + if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); + if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); + } +p += cbit_length; + +/* Finally, the character type table. In this, we exclude VT from the white +space chars, because Perl doesn't recognize it as such for \s and for comments +within regexes. */ + +for (i = 0; i < 256; i++) + { + int x = 0; + if (i != 0x0b && isspace(i)) x += ctype_space; + if (isalpha(i)) x += ctype_letter; + if (isdigit(i)) x += ctype_digit; + if (isxdigit(i)) x += ctype_xdigit; + if (isalnum(i) || i == '_') x += ctype_word; + + /* Note: strchr includes the terminating zero in the characters it considers. + In this instance, that is ok because we want binary zero to be flagged as a + meta-character, which in this sense is any character that terminates a run + of data characters. */ + + if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta; *p++ = x; } + +return yield; +} + +/* End of maketables.c */ diff --git a/trunk/srclib/pcre/makevp.bat b/trunk/srclib/pcre/makevp.bat new file mode 100644 index 0000000000..10bd2487a4 --- /dev/null +++ b/trunk/srclib/pcre/makevp.bat @@ -0,0 +1,25 @@ +@echo off + +REM This file was contributed by Alexander Tokarev for building PCRE for use +REM with Virtual Pascal. It has not been tested with the latest PCRE release. + +REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH + +SET BORLAND=c:\usr\apps\bcc55 + +sh configure + +bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c + +dftables > chartables.c + +bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c + +tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset +tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj + +del *.obj *.exe *.tds *.bak >nul 2>nul + +echo --- +echo Now the library should be complete. Please check all messages above. +echo Don't care for warnings, it's OK. diff --git a/trunk/srclib/pcre/mkinstalldirs b/trunk/srclib/pcre/mkinstalldirs new file mode 100755 index 0000000000..6b3b5fc5d4 --- /dev/null +++ b/trunk/srclib/pcre/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/trunk/srclib/pcre/pcre-config.in b/trunk/srclib/pcre/pcre-config.in new file mode 100644 index 0000000000..30d66ced36 --- /dev/null +++ b/trunk/srclib/pcre/pcre-config.in @@ -0,0 +1,66 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage="\ +Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +libR= +case `uname -s` in + *SunOS*) + libR=" -R@libdir@" + ;; +esac + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @PCRE_VERSION@ + ;; + --cflags | --cflags-posix) + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes + ;; + --libs-posix) + echo -L@libdir@$libR -lpcreposix -lpcre + ;; + --libs) + echo -L@libdir@$libR -lpcre + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/trunk/srclib/pcre/pcre.c b/trunk/srclib/pcre/pcre.c new file mode 100644 index 0000000000..dc013faf02 --- /dev/null +++ b/trunk/srclib/pcre/pcre.c @@ -0,0 +1,9196 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + + +/* Define DEBUG to get debugging output on stdout. */ +/* #define DEBUG */ + +/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef +inline, and there are *still* stupid compilers about that don't like indented +pre-processor statements. I suppose it's only been 10 years... */ + +#ifdef DEBUG +#define DPRINTF(p) printf p +#else +#define DPRINTF(p) /*nothing*/ +#endif + +/* Include the internals header, which itself includes "config.h", the Standard +C headers, and the external pcre header. */ + +#include "internal.h" + +/* If Unicode Property support is wanted, include a private copy of the +function that does it, and the table that translates names to numbers. */ + +#ifdef SUPPORT_UCP +#include "ucp.c" +#include "ucptypetable.c" +#endif + +/* Maximum number of items on the nested bracket stacks at compile time. This +applies to the nesting of all kinds of parentheses. It does not limit +un-nested, non-capturing parentheses. This number can be made bigger if +necessary - it is used to dimension one int and one unsigned char vector at +compile time. */ + +#define BRASTACK_SIZE 200 + + +/* Maximum number of ints of offset to save on the stack for recursive calls. +If the offset vector is bigger, malloc is used. This should be a multiple of 3, +because the offset vector is always a multiple of 3 long. */ + +#define REC_STACK_SAVE_MAX 30 + + +/* The maximum remaining length of subject we are prepared to search for a +req_byte match. */ + +#define REQ_BYTE_MAX 1000 + + +/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that +the definition is next to the definition of the opcodes in internal.h. */ + +static const uschar OP_lengths[] = { OP_LENGTHS }; + +/* Min and max values for the common repeats; for the maxima, 0 => infinity */ + +static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; +static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; + +/* Table for handling escaped characters in the range '0'-'z'. Positive returns +are simple data values; negative values are for special things like \d and so +on. Zero means further processing is needed (for things like \x), or the escape +is invalid. */ + +#if !EBCDIC /* This is the "normal" table for ASCII systems */ +static const short int escapes[] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ + 0, 0, ':', ';', '<', '=', '>', '?', /* 8 - ? */ + '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, /* @ - G */ + 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ +-ESC_P, -ESC_Q, 0, -ESC_S, 0, 0, 0, -ESC_W, /* P - W */ +-ESC_X, 0, -ESC_Z, '[', '\\', ']', '^', '_', /* X - _ */ + '`', 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* ` - g */ + 0, 0, 0, 0, 0, 0, ESC_n, 0, /* h - o */ +-ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, 0, -ESC_w, /* p - w */ + 0, 0, -ESC_z /* x - z */ +}; + +#else /* This is the "abnormal" table for EBCDIC systems */ +static const short int escapes[] = { +/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|', +/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0, +/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~', +/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0, +/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?', +/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"', +/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, +/* 88 */ 0, 0, 0, '{', 0, 0, 0, 0, +/* 90 */ 0, 0, 0, 'l', 0, ESC_n, 0, -ESC_p, +/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, +/* A0 */ 0, '~', -ESC_s, ESC_tee, 0, 0, -ESC_w, 0, +/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, +/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', +/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, +/* C8 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* D0 */ '}', 0, 0, 0, 0, 0, 0, -ESC_P, +/* D8 */-ESC_Q, 0, 0, 0, 0, 0, 0, 0, +/* E0 */ '\\', 0, -ESC_S, 0, 0, 0, -ESC_W, -ESC_X, +/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, +/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, +/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0 +}; +#endif + + +/* Tables of names of POSIX character classes and their lengths. The list is +terminated by a zero length entry. The first three must be alpha, upper, lower, +as this is assumed for handling case independence. */ + +static const char *const posix_names[] = { + "alpha", "lower", "upper", + "alnum", "ascii", "blank", "cntrl", "digit", "graph", + "print", "punct", "space", "word", "xdigit" }; + +static const uschar posix_name_lengths[] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; + +/* Table of class bit maps for each POSIX class; up to three may be combined +to form the class. The table for [:blank:] is dynamically modified to remove +the vertical space characters. */ + +static const int posix_class_maps[] = { + cbit_lower, cbit_upper, -1, /* alpha */ + cbit_lower, -1, -1, /* lower */ + cbit_upper, -1, -1, /* upper */ + cbit_digit, cbit_lower, cbit_upper, /* alnum */ + cbit_print, cbit_cntrl, -1, /* ascii */ + cbit_space, -1, -1, /* blank - a GNU extension */ + cbit_cntrl, -1, -1, /* cntrl */ + cbit_digit, -1, -1, /* digit */ + cbit_graph, -1, -1, /* graph */ + cbit_print, -1, -1, /* print */ + cbit_punct, -1, -1, /* punct */ + cbit_space, -1, -1, /* space */ + cbit_word, -1, -1, /* word - a Perl extension */ + cbit_xdigit,-1, -1 /* xdigit */ +}; + +/* Table to identify digits and hex digits. This is used when compiling +patterns. Note that the tables in chartables are dependent on the locale, and +may mark arbitrary characters as digits - but the PCRE compiling code expects +to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have +a private table here. It costs 256 bytes, but it is a lot faster than doing +character value tests (at least in some simple cases I timed), and in some +applications one wants PCRE to compile efficiently as well as match +efficiently. + +For convenience, we use the same bit definitions as in chartables: + + 0x04 decimal digit + 0x08 hexadecimal digit + +Then we can use ctype_digit and ctype_xdigit in the code. */ + +#if !EBCDIC /* This is the "normal" case, for ASCII systems */ +static const unsigned char digitab[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */ + 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ + +#else /* This is the "abnormal" case, for EBCDIC systems */ +static const unsigned char digitab[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- ¬ */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ + 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ + +static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ + 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ + 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ + 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ + 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */ + 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */ + 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- ¬ */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */ + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ + 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ + 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ + 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */ + 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ + 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ + 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ + 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */ + 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ +#endif + + +/* Definition to allow mutual recursion */ + +static BOOL + compile_regex(int, int, int *, uschar **, const uschar **, const char **, + BOOL, int, int *, int *, branch_chain *, compile_data *); + +/* Structure for building a chain of data that actually lives on the +stack, for holding the values of the subject pointer at the start of each +subpattern, so as to detect when an empty string has been matched by a +subpattern - to break infinite loops. When NO_RECURSE is set, these blocks +are on the heap, not on the stack. */ + +typedef struct eptrblock { + struct eptrblock *epb_prev; + const uschar *epb_saved_eptr; +} eptrblock; + +/* Flag bits for the match() function */ + +#define match_condassert 0x01 /* Called to check a condition assertion */ +#define match_isgroup 0x02 /* Set if start of bracketed group */ + +/* Non-error returns from the match() function. Error returns are externally +defined PCRE_ERROR_xxx codes, which are all negative. */ + +#define MATCH_MATCH 1 +#define MATCH_NOMATCH 0 + + + +/************************************************* +* Global variables * +*************************************************/ + +/* PCRE is thread-clean and doesn't use any global variables in the normal +sense. However, it calls memory allocation and free functions via the four +indirections below, and it can optionally do callouts. These values can be +changed by the caller, but are shared between all threads. However, when +compiling for Virtual Pascal, things are done differently (see pcre.in). */ + +#ifndef VPCOMPAT +#ifdef __cplusplus +extern "C" void *(*pcre_malloc)(size_t) = malloc; +extern "C" void (*pcre_free)(void *) = free; +extern "C" void *(*pcre_stack_malloc)(size_t) = malloc; +extern "C" void (*pcre_stack_free)(void *) = free; +extern "C" int (*pcre_callout)(pcre_callout_block *) = NULL; +#else +void *(*pcre_malloc)(size_t) = malloc; +void (*pcre_free)(void *) = free; +void *(*pcre_stack_malloc)(size_t) = malloc; +void (*pcre_stack_free)(void *) = free; +int (*pcre_callout)(pcre_callout_block *) = NULL; +#endif +#endif + + +/************************************************* +* Macros and tables for character handling * +*************************************************/ + +/* When UTF-8 encoding is being used, a character is no longer just a single +byte. The macros for character handling generate simple sequences when used in +byte-mode, and more complicated ones for UTF-8 characters. */ + +#ifndef SUPPORT_UTF8 +#define GETCHAR(c, eptr) c = *eptr; +#define GETCHARINC(c, eptr) c = *eptr++; +#define GETCHARINCTEST(c, eptr) c = *eptr++; +#define GETCHARLEN(c, eptr, len) c = *eptr; +#define BACKCHAR(eptr) + +#else /* SUPPORT_UTF8 */ + +/* Get the next UTF-8 character, not advancing the pointer. This is called when +we know we are in UTF-8 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if ((c & 0xc0) == 0xc0) \ + { \ + int gcii; \ + int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ + int gcss = 6*gcaa; \ + c = (c & utf8_table3[gcaa]) << gcss; \ + for (gcii = 1; gcii <= gcaa; gcii++) \ + { \ + gcss -= 6; \ + c |= (eptr[gcii] & 0x3f) << gcss; \ + } \ + } + +/* Get the next UTF-8 character, advancing the pointer. This is called when we +know we are in UTF-8 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if ((c & 0xc0) == 0xc0) \ + { \ + int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ + int gcss = 6*gcaa; \ + c = (c & utf8_table3[gcaa]) << gcss; \ + while (gcaa-- > 0) \ + { \ + gcss -= 6; \ + c |= (*eptr++ & 0x3f) << gcss; \ + } \ + } + +/* Get the next character, testing for UTF-8 mode, and advancing the pointer */ + +#define GETCHARINCTEST(c, eptr) \ + c = *eptr++; \ + if (md->utf8 && (c & 0xc0) == 0xc0) \ + { \ + int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ + int gcss = 6*gcaa; \ + c = (c & utf8_table3[gcaa]) << gcss; \ + while (gcaa-- > 0) \ + { \ + gcss -= 6; \ + c |= (*eptr++ & 0x3f) << gcss; \ + } \ + } + +/* Get the next UTF-8 character, not advancing the pointer, incrementing length +if there are extra bytes. This is called when we know we are in UTF-8 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if ((c & 0xc0) == 0xc0) \ + { \ + int gcii; \ + int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ + int gcss = 6*gcaa; \ + c = (c & utf8_table3[gcaa]) << gcss; \ + for (gcii = 1; gcii <= gcaa; gcii++) \ + { \ + gcss -= 6; \ + c |= (eptr[gcii] & 0x3f) << gcss; \ + } \ + len += gcaa; \ + } + +/* If the pointer is not at the start of a character, move it back until +it is. Called only in UTF-8 mode. */ + +#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--; + +#endif + + + +/************************************************* +* Default character tables * +*************************************************/ + +/* A default set of character tables is included in the PCRE binary. Its source +is built by the maketables auxiliary program, which uses the default C ctypes +functions, and put in the file chartables.c. These tables are used by PCRE +whenever the caller of pcre_compile() does not provide an alternate set of +tables. */ + +#include "chartables.c" + + + +#ifdef SUPPORT_UTF8 +/************************************************* +* Tables for UTF-8 support * +*************************************************/ + +/* These are the breakpoints for different numbers of bytes in a UTF-8 +character. */ + +static const int utf8_table1[] = + { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; + +/* These are the indicator bits and the mask for the data bits to set in the +first byte of a character, indexed by the number of additional bytes. */ + +static const int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; +static const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +/* Table of the number of extra characters, indexed by the first character +masked with 0x3f. The highest number for a valid UTF-8 character is in fact +0x3d. */ + +static const uschar utf8_table4[] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; + + +/************************************************* +* Convert character value to UTF-8 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x7fffffff +and encodes it as a UTF-8 character in 0 to 6 bytes. + +Arguments: + cvalue the character value + buffer pointer to buffer for result - at least 6 bytes long + +Returns: number of characters placed in the buffer +*/ + +static int +ord2utf8(int cvalue, uschar *buffer) +{ +register int i, j; +for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) + if (cvalue <= utf8_table1[i]) break; +buffer += i; +for (j = i; j > 0; j--) + { + *buffer-- = 0x80 | (cvalue & 0x3f); + cvalue >>= 6; + } +*buffer = utf8_table2[i] | cvalue; +return i + 1; +} +#endif + + + +/************************************************* +* Print compiled regex * +*************************************************/ + +/* The code for doing this is held in a separate file that is also included in +pcretest.c. It defines a function called print_internals(). */ + +#ifdef DEBUG +#include "printint.c" +#endif + + + +/************************************************* +* Return version string * +*************************************************/ + +#define STRING(a) # a +#define XSTRING(s) STRING(s) + +EXPORT const char * +pcre_version(void) +{ +return XSTRING(PCRE_MAJOR) "." XSTRING(PCRE_MINOR) " " XSTRING(PCRE_DATE); +} + + + + +/************************************************* +* Flip bytes in an integer * +*************************************************/ + +/* This function is called when the magic number in a regex doesn't match in +order to flip its bytes to see if we are dealing with a pattern that was +compiled on a host of different endianness. If so, this function is used to +flip other byte values. + +Arguments: + value the number to flip + n the number of bytes to flip (assumed to be 2 or 4) + +Returns: the flipped value +*/ + +static pcre_uint16 +byteflip2(pcre_uint16 value) +{ +return ((value & 0x00ff) << 8) | + ((value & 0xff00) >> 8); +} + +static pcre_uint32 +byteflip4(pcre_uint32 value) +{ +return ((value & 0x000000ff) << 24) | + ((value & 0x0000ff00) << 8) | + ((value & 0x00ff0000) >> 8) | + ((value & 0xff000000) >> 24); +} + +/************************************************* +* Test for a byte-flipped compiled regex * +*************************************************/ + +/* This function is called from pce_exec() and also from pcre_fullinfo(). Its +job is to test whether the regex is byte-flipped - that is, it was compiled on +a system of opposite endianness. The function is called only when the native +MAGIC_NUMBER test fails. If the regex is indeed flipped, we flip all the +relevant values into a different data block, and return it. + +Arguments: + re points to the regex + study points to study data, or NULL + internal_re points to a new regex block + internal_study points to a new study block + +Returns: the new block if is is indeed a byte-flipped regex + NULL if it is not +*/ + +static real_pcre * +try_flipped(const real_pcre *re, real_pcre *internal_re, + const pcre_study_data *study, pcre_study_data *internal_study) +{ +if (byteflip4(re->magic_number) != MAGIC_NUMBER) + return NULL; + +*internal_re = *re; /* To copy other fields */ +internal_re->size = byteflip4(re->size); +internal_re->options = byteflip4(re->options); +internal_re->top_bracket = byteflip2(re->top_bracket); +internal_re->top_backref = byteflip2(re->top_backref); +internal_re->first_byte = byteflip2(re->first_byte); +internal_re->req_byte = byteflip2(re->req_byte); +internal_re->name_table_offset = byteflip2(re->name_table_offset); +internal_re->name_entry_size = byteflip2(re->name_entry_size); +internal_re->name_count = byteflip2(re->name_count); + +if (study != NULL) + { + *internal_study = *study; /* To copy other fields */ + internal_study->size = byteflip4(study->size); + internal_study->options = byteflip4(study->options); + } + +return internal_re; +} + + + +/************************************************* +* (Obsolete) Return info about compiled pattern * +*************************************************/ + +/* This is the original "info" function. It picks potentially useful data out +of the private structure, but its interface was too rigid. It remains for +backwards compatibility. The public options are passed back in an int - though +the re->options field has been expanded to a long int, all the public options +at the low end of it, and so even on 16-bit systems this will still be OK. +Therefore, I haven't changed the API for pcre_info(). + +Arguments: + argument_re points to compiled code + optptr where to pass back the options + first_byte where to pass back the first character, + or -1 if multiline and all branches start ^, + or -2 otherwise + +Returns: number of capturing subpatterns + or negative values on error +*/ + +EXPORT int +pcre_info(const pcre *argument_re, int *optptr, int *first_byte) +{ +real_pcre internal_re; +const real_pcre *re = (const real_pcre *)argument_re; +if (re == NULL) return PCRE_ERROR_NULL; +if (re->magic_number != MAGIC_NUMBER) + { + re = try_flipped(re, &internal_re, NULL, NULL); + if (re == NULL) return PCRE_ERROR_BADMAGIC; + } +if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS); +if (first_byte != NULL) + *first_byte = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : + ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; +return re->top_bracket; +} + + + +/************************************************* +* Return info about compiled pattern * +*************************************************/ + +/* This is a newer "info" function which has an extensible interface so +that additional items can be added compatibly. + +Arguments: + argument_re points to compiled code + extra_data points extra data, or NULL + what what information is required + where where to put the information + +Returns: 0 if data returned, negative on error +*/ + +EXPORT int +pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, + void *where) +{ +real_pcre internal_re; +pcre_study_data internal_study; +const real_pcre *re = (const real_pcre *)argument_re; +const pcre_study_data *study = NULL; + +if (re == NULL || where == NULL) return PCRE_ERROR_NULL; + +if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) + study = (const pcre_study_data *)extra_data->study_data; + +if (re->magic_number != MAGIC_NUMBER) + { + re = try_flipped(re, &internal_re, study, &internal_study); + if (re == NULL) return PCRE_ERROR_BADMAGIC; + if (study != NULL) study = &internal_study; + } + +switch (what) + { + case PCRE_INFO_OPTIONS: + *((unsigned long int *)where) = re->options & PUBLIC_OPTIONS; + break; + + case PCRE_INFO_SIZE: + *((size_t *)where) = re->size; + break; + + case PCRE_INFO_STUDYSIZE: + *((size_t *)where) = (study == NULL)? 0 : study->size; + break; + + case PCRE_INFO_CAPTURECOUNT: + *((int *)where) = re->top_bracket; + break; + + case PCRE_INFO_BACKREFMAX: + *((int *)where) = re->top_backref; + break; + + case PCRE_INFO_FIRSTBYTE: + *((int *)where) = + ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : + ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; + break; + + /* Make sure we pass back the pointer to the bit vector in the external + block, not the internal copy (with flipped integer fields). */ + + case PCRE_INFO_FIRSTTABLE: + *((const uschar **)where) = + (study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)? + ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; + break; + + case PCRE_INFO_LASTLITERAL: + *((int *)where) = + ((re->options & PCRE_REQCHSET) != 0)? re->req_byte : -1; + break; + + case PCRE_INFO_NAMEENTRYSIZE: + *((int *)where) = re->name_entry_size; + break; + + case PCRE_INFO_NAMECOUNT: + *((int *)where) = re->name_count; + break; + + case PCRE_INFO_NAMETABLE: + *((const uschar **)where) = (const uschar *)re + re->name_table_offset; + break; + + case PCRE_INFO_DEFAULT_TABLES: + *((const uschar **)where) = (const uschar *)pcre_default_tables; + break; + + default: return PCRE_ERROR_BADOPTION; + } + +return 0; +} + + + +/************************************************* +* Return info about what features are configured * +*************************************************/ + +/* This is function which has an extensible interface so that additional items +can be added compatibly. + +Arguments: + what what information is required + where where to put the information + +Returns: 0 if data returned, negative on error +*/ + +EXPORT int +pcre_config(int what, void *where) +{ +switch (what) + { + case PCRE_CONFIG_UTF8: +#ifdef SUPPORT_UTF8 + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + + case PCRE_CONFIG_UNICODE_PROPERTIES: +#ifdef SUPPORT_UCP + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + + case PCRE_CONFIG_NEWLINE: + *((int *)where) = NEWLINE; + break; + + case PCRE_CONFIG_LINK_SIZE: + *((int *)where) = LINK_SIZE; + break; + + case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: + *((int *)where) = POSIX_MALLOC_THRESHOLD; + break; + + case PCRE_CONFIG_MATCH_LIMIT: + *((unsigned int *)where) = MATCH_LIMIT; + break; + + case PCRE_CONFIG_STACKRECURSE: +#ifdef NO_RECURSE + *((int *)where) = 0; +#else + *((int *)where) = 1; +#endif + break; + + default: return PCRE_ERROR_BADOPTION; + } + +return 0; +} + + + +#ifdef DEBUG +/************************************************* +* Debugging function to print chars * +*************************************************/ + +/* Print a sequence of chars in printable format, stopping at the end of the +subject if the requested. + +Arguments: + p points to characters + length number to print + is_subject TRUE if printing from within md->start_subject + md pointer to matching data block, if is_subject is TRUE + +Returns: nothing +*/ + +static void +pchars(const uschar *p, int length, BOOL is_subject, match_data *md) +{ +int c; +if (is_subject && length > md->end_subject - p) length = md->end_subject - p; +while (length-- > 0) + if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c); +} +#endif + + + + +/************************************************* +* Handle escapes * +*************************************************/ + +/* This function is called when a \ has been encountered. It either returns a +positive value for a simple escape such as \n, or a negative value which +encodes one of the more complicated things such as \d. When UTF-8 is enabled, +a positive value greater than 255 may be returned. On entry, ptr is pointing at +the \. On exit, it is on the final character of the escape sequence. + +Arguments: + ptrptr points to the pattern position pointer + errorptr points to the pointer to the error message + bracount number of previous extracting brackets + options the options bits + isclass TRUE if inside a character class + +Returns: zero or positive => a data character + negative => a special escape sequence + on error, errorptr is set +*/ + +static int +check_escape(const uschar **ptrptr, const char **errorptr, int bracount, + int options, BOOL isclass) +{ +const uschar *ptr = *ptrptr; +int c, i; + +/* If backslash is at the end of the pattern, it's an error. */ + +c = *(++ptr); +if (c == 0) *errorptr = ERR1; + +/* Non-alphamerics are literals. For digits or letters, do an initial lookup in +a table. A non-zero result is something that can be returned immediately. +Otherwise further processing may be required. */ + +#if !EBCDIC /* ASCII coding */ +else if (c < '0' || c > 'z') {} /* Not alphameric */ +else if ((i = escapes[c - '0']) != 0) c = i; + +#else /* EBCDIC coding */ +else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphameric */ +else if ((i = escapes[c - 0x48]) != 0) c = i; +#endif + +/* Escapes that need further processing, or are illegal. */ + +else + { + const uschar *oldptr; + switch (c) + { + /* A number of Perl escapes are not handled by PCRE. We give an explicit + error. */ + + case 'l': + case 'L': + case 'N': + case 'u': + case 'U': + *errorptr = ERR37; + break; + + /* The handling of escape sequences consisting of a string of digits + starting with one that is not zero is not straightforward. By experiment, + the way Perl works seems to be as follows: + + Outside a character class, the digits are read as a decimal number. If the + number is less than 10, or if there are that many previous extracting + left brackets, then it is a back reference. Otherwise, up to three octal + digits are read to form an escaped byte. Thus \123 is likely to be octal + 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal + value is greater than 377, the least significant 8 bits are taken. Inside a + character class, \ followed by a digit is always an octal number. */ + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + + if (!isclass) + { + oldptr = ptr; + c -= '0'; + while ((digitab[ptr[1]] & ctype_digit) != 0) + c = c * 10 + *(++ptr) - '0'; + if (c < 10 || c <= bracount) + { + c = -(ESC_REF + c); + break; + } + ptr = oldptr; /* Put the pointer back and fall through */ + } + + /* Handle an octal number following \. If the first digit is 8 or 9, Perl + generates a binary zero byte and treats the digit as a following literal. + Thus we have to pull back the pointer by one. */ + + if ((c = *ptr) >= '8') + { + ptr--; + c = 0; + break; + } + + /* \0 always starts an octal number, but we may drop through to here with a + larger first octal digit. */ + + case '0': + c -= '0'; + while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7') + c = c * 8 + *(++ptr) - '0'; + c &= 255; /* Take least significant 8 bits */ + break; + + /* \x is complicated when UTF-8 is enabled. \x{ddd} is a character number + which can be greater than 0xff, but only if the ddd are hex digits. */ + + case 'x': +#ifdef SUPPORT_UTF8 + if (ptr[1] == '{' && (options & PCRE_UTF8) != 0) + { + const uschar *pt = ptr + 2; + register int count = 0; + c = 0; + while ((digitab[*pt] & ctype_xdigit) != 0) + { + int cc = *pt++; + count++; +#if !EBCDIC /* ASCII coding */ + if (cc >= 'a') cc -= 32; /* Convert to upper case */ + c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10)); +#else /* EBCDIC coding */ + if (cc >= 'a' && cc <= 'z') cc += 64; /* Convert to upper case */ + c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10)); +#endif + } + if (*pt == '}') + { + if (c < 0 || count > 8) *errorptr = ERR34; + ptr = pt; + break; + } + /* If the sequence of hex digits does not end with '}', then we don't + recognize this construct; fall through to the normal \x handling. */ + } +#endif + + /* Read just a single hex char */ + + c = 0; + while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0) + { + int cc; /* Some compilers don't like ++ */ + cc = *(++ptr); /* in initializers */ +#if !EBCDIC /* ASCII coding */ + if (cc >= 'a') cc -= 32; /* Convert to upper case */ + c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10)); +#else /* EBCDIC coding */ + if (cc <= 'z') cc += 64; /* Convert to upper case */ + c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10)); +#endif + } + break; + + /* Other special escapes not starting with a digit are straightforward */ + + case 'c': + c = *(++ptr); + if (c == 0) + { + *errorptr = ERR2; + return 0; + } + + /* A letter is upper-cased; then the 0x40 bit is flipped. This coding + is ASCII-specific, but then the whole concept of \cx is ASCII-specific. + (However, an EBCDIC equivalent has now been added.) */ + +#if !EBCDIC /* ASCII coding */ + if (c >= 'a' && c <= 'z') c -= 32; + c ^= 0x40; +#else /* EBCDIC coding */ + if (c >= 'a' && c <= 'z') c += 64; + c ^= 0xC0; +#endif + break; + + /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any + other alphameric following \ is an error if PCRE_EXTRA was set; otherwise, + for Perl compatibility, it is a literal. This code looks a bit odd, but + there used to be some cases other than the default, and there may be again + in future, so I haven't "optimized" it. */ + + default: + if ((options & PCRE_EXTRA) != 0) switch(c) + { + default: + *errorptr = ERR3; + break; + } + break; + } + } + +*ptrptr = ptr; +return c; +} + + + +#ifdef SUPPORT_UCP +/************************************************* +* Handle \P and \p * +*************************************************/ + +/* This function is called after \P or \p has been encountered, provided that +PCRE is compiled with support for Unicode properties. On entry, ptrptr is +pointing at the P or p. On exit, it is pointing at the final character of the +escape sequence. + +Argument: + ptrptr points to the pattern position pointer + negptr points to a boolean that is set TRUE for negation else FALSE + errorptr points to the pointer to the error message + +Returns: value from ucp_type_table, or -1 for an invalid type +*/ + +static int +get_ucp(const uschar **ptrptr, BOOL *negptr, const char **errorptr) +{ +int c, i, bot, top; +const uschar *ptr = *ptrptr; +char name[4]; + +c = *(++ptr); +if (c == 0) goto ERROR_RETURN; + +*negptr = FALSE; + +/* \P or \p can be followed by a one- or two-character name in {}, optionally +preceded by ^ for negation. */ + +if (c == '{') + { + if (ptr[1] == '^') + { + *negptr = TRUE; + ptr++; + } + for (i = 0; i <= 2; i++) + { + c = *(++ptr); + if (c == 0) goto ERROR_RETURN; + if (c == '}') break; + name[i] = c; + } + if (c !='}') /* Try to distinguish error cases */ + { + while (*(++ptr) != 0 && *ptr != '}'); + if (*ptr == '}') goto UNKNOWN_RETURN; else goto ERROR_RETURN; + } + name[i] = 0; + } + +/* Otherwise there is just one following character */ + +else + { + name[0] = c; + name[1] = 0; + } + +*ptrptr = ptr; + +/* Search for a recognized property name using binary chop */ + +bot = 0; +top = sizeof(utt)/sizeof(ucp_type_table); + +while (bot < top) + { + i = (bot + top)/2; + c = strcmp(name, utt[i].name); + if (c == 0) return utt[i].value; + if (c > 0) bot = i + 1; else top = i; + } + +UNKNOWN_RETURN: +*errorptr = ERR47; +*ptrptr = ptr; +return -1; + +ERROR_RETURN: +*errorptr = ERR46; +*ptrptr = ptr; +return -1; +} +#endif + + + + +/************************************************* +* Check for counted repeat * +*************************************************/ + +/* This function is called when a '{' is encountered in a place where it might +start a quantifier. It looks ahead to see if it really is a quantifier or not. +It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} +where the ddds are digits. + +Arguments: + p pointer to the first char after '{' + +Returns: TRUE or FALSE +*/ + +static BOOL +is_counted_repeat(const uschar *p) +{ +if ((digitab[*p++] & ctype_digit) == 0) return FALSE; +while ((digitab[*p] & ctype_digit) != 0) p++; +if (*p == '}') return TRUE; + +if (*p++ != ',') return FALSE; +if (*p == '}') return TRUE; + +if ((digitab[*p++] & ctype_digit) == 0) return FALSE; +while ((digitab[*p] & ctype_digit) != 0) p++; + +return (*p == '}'); +} + + + +/************************************************* +* Read repeat counts * +*************************************************/ + +/* Read an item of the form {n,m} and return the values. This is called only +after is_counted_repeat() has confirmed that a repeat-count quantifier exists, +so the syntax is guaranteed to be correct, but we need to check the values. + +Arguments: + p pointer to first char after '{' + minp pointer to int for min + maxp pointer to int for max + returned as -1 if no max + errorptr points to pointer to error message + +Returns: pointer to '}' on success; + current ptr on error, with errorptr set +*/ + +static const uschar * +read_repeat_counts(const uschar *p, int *minp, int *maxp, const char **errorptr) +{ +int min = 0; +int max = -1; + +while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; + +if (*p == '}') max = min; else + { + if (*(++p) != '}') + { + max = 0; + while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; + if (max < min) + { + *errorptr = ERR4; + return p; + } + } + } + +/* Do paranoid checks, then fill in the required variables, and pass back the +pointer to the terminating '}'. */ + +if (min > 65535 || max > 65535) + *errorptr = ERR5; +else + { + *minp = min; + *maxp = max; + } +return p; +} + + + +/************************************************* +* Find first significant op code * +*************************************************/ + +/* This is called by several functions that scan a compiled expression looking +for a fixed first character, or an anchoring op code etc. It skips over things +that do not influence this. For some calls, a change of option is important. +For some calls, it makes sense to skip negative forward and all backward +assertions, and also the \b assertion; for others it does not. + +Arguments: + code pointer to the start of the group + options pointer to external options + optbit the option bit whose changing is significant, or + zero if none are + skipassert TRUE if certain assertions are to be skipped + +Returns: pointer to the first significant opcode +*/ + +static const uschar* +first_significant_code(const uschar *code, int *options, int optbit, + BOOL skipassert) +{ +for (;;) + { + switch ((int)*code) + { + case OP_OPT: + if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit)) + *options = (int)code[1]; + code += 2; + break; + + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + if (!skipassert) return code; + do code += GET(code, 1); while (*code == OP_ALT); + code += OP_lengths[*code]; + break; + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + if (!skipassert) return code; + /* Fall through */ + + case OP_CALLOUT: + case OP_CREF: + case OP_BRANUMBER: + code += OP_lengths[*code]; + break; + + default: + return code; + } + } +/* Control never reaches here */ +} + + + + +/************************************************* +* Find the fixed length of a pattern * +*************************************************/ + +/* Scan a pattern and compute the fixed length of subject that will match it, +if the length is fixed. This is needed for dealing with backward assertions. +In UTF8 mode, the result is in characters rather than bytes. + +Arguments: + code points to the start of the pattern (the bracket) + options the compiling options + +Returns: the fixed length, or -1 if there is no fixed length, + or -2 if \C was encountered +*/ + +static int +find_fixedlength(uschar *code, int options) +{ +int length = -1; + +register int branchlength = 0; +register uschar *cc = code + 1 + LINK_SIZE; + +/* Scan along the opcodes for this branch. If we get to the end of the +branch, check the length against that of the other branches. */ + +for (;;) + { + int d; + register int op = *cc; + if (op >= OP_BRA) op = OP_BRA; + + switch (op) + { + case OP_BRA: + case OP_ONCE: + case OP_COND: + d = find_fixedlength(cc, options); + if (d < 0) return d; + branchlength += d; + do cc += GET(cc, 1); while (*cc == OP_ALT); + cc += 1 + LINK_SIZE; + break; + + /* Reached end of a branch; if it's a ket it is the end of a nested + call. If it's ALT it is an alternation in a nested call. If it is + END it's the end of the outer call. All can be handled by the same code. */ + + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_END: + if (length < 0) length = branchlength; + else if (length != branchlength) return -1; + if (*cc != OP_ALT) return length; + cc += 1 + LINK_SIZE; + branchlength = 0; + break; + + /* Skip over assertive subpatterns */ + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do cc += GET(cc, 1); while (*cc == OP_ALT); + /* Fall through */ + + /* Skip over things that don't match chars */ + + case OP_REVERSE: + case OP_BRANUMBER: + case OP_CREF: + case OP_OPT: + case OP_CALLOUT: + case OP_SOD: + case OP_SOM: + case OP_EOD: + case OP_EODN: + case OP_CIRC: + case OP_DOLL: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + cc += OP_lengths[*cc]; + break; + + /* Handle literal characters */ + + case OP_CHAR: + case OP_CHARNC: + branchlength++; + cc += 2; +#ifdef SUPPORT_UTF8 + if ((options & PCRE_UTF8) != 0) + { + while ((*cc & 0xc0) == 0x80) cc++; + } +#endif + break; + + /* Handle exact repetitions. The count is already in characters, but we + need to skip over a multibyte character in UTF8 mode. */ + + case OP_EXACT: + branchlength += GET2(cc,1); + cc += 4; +#ifdef SUPPORT_UTF8 + if ((options & PCRE_UTF8) != 0) + { + while((*cc & 0x80) == 0x80) cc++; + } +#endif + break; + + case OP_TYPEEXACT: + branchlength += GET2(cc,1); + cc += 4; + break; + + /* Handle single-char matchers */ + + case OP_PROP: + case OP_NOTPROP: + cc++; + /* Fall through */ + + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + branchlength++; + cc++; + break; + + /* The single-byte matcher isn't allowed */ + + case OP_ANYBYTE: + return -2; + + /* Check a class for variable quantification */ + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + cc += GET(cc, 1) - 33; + /* Fall through */ +#endif + + case OP_CLASS: + case OP_NCLASS: + cc += 33; + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + return -1; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(cc,1) != GET2(cc,3)) return -1; + branchlength += GET2(cc,1); + cc += 5; + break; + + default: + branchlength++; + } + break; + + /* Anything else is variable length */ + + default: + return -1; + } + } +/* Control never gets here */ +} + + + + +/************************************************* +* Scan compiled regex for numbered bracket * +*************************************************/ + +/* This little function scans through a compiled pattern until it finds a +capturing bracket with the given number. + +Arguments: + code points to start of expression + utf8 TRUE in UTF-8 mode + number the required bracket number + +Returns: pointer to the opcode for the bracket, or NULL if not found +*/ + +static const uschar * +find_bracket(const uschar *code, BOOL utf8, int number) +{ +#ifndef SUPPORT_UTF8 +utf8 = utf8; /* Stop pedantic compilers complaining */ +#endif + +for (;;) + { + register int c = *code; + if (c == OP_END) return NULL; + else if (c > OP_BRA) + { + int n = c - OP_BRA; + if (n > EXTRACT_BASIC_MAX) n = GET2(code, 2+LINK_SIZE); + if (n == number) return (uschar *)code; + code += OP_lengths[OP_BRA]; + } + else + { + code += OP_lengths[c]; + +#ifdef SUPPORT_UTF8 + + /* In UTF-8 mode, opcodes that are followed by a character may be followed + by a multi-byte character. The length in the table is a minimum, so we have + to scan along to skip the extra bytes. All opcodes are less than 128, so we + can use relatively efficient code. */ + + if (utf8) switch(c) + { + case OP_CHAR: + case OP_CHARNC: + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + while ((*code & 0xc0) == 0x80) code++; + break; + + /* XCLASS is used for classes that cannot be represented just by a bit + map. This includes negated single high-valued characters. The length in + the table is zero; the actual length is stored in the compiled code. */ + + case OP_XCLASS: + code += GET(code, 1) + 1; + break; + } +#endif + } + } +} + + + +/************************************************* +* Scan compiled regex for recursion reference * +*************************************************/ + +/* This little function scans through a compiled pattern until it finds an +instance of OP_RECURSE. + +Arguments: + code points to start of expression + utf8 TRUE in UTF-8 mode + +Returns: pointer to the opcode for OP_RECURSE, or NULL if not found +*/ + +static const uschar * +find_recurse(const uschar *code, BOOL utf8) +{ +#ifndef SUPPORT_UTF8 +utf8 = utf8; /* Stop pedantic compilers complaining */ +#endif + +for (;;) + { + register int c = *code; + if (c == OP_END) return NULL; + else if (c == OP_RECURSE) return code; + else if (c > OP_BRA) + { + code += OP_lengths[OP_BRA]; + } + else + { + code += OP_lengths[c]; + +#ifdef SUPPORT_UTF8 + + /* In UTF-8 mode, opcodes that are followed by a character may be followed + by a multi-byte character. The length in the table is a minimum, so we have + to scan along to skip the extra bytes. All opcodes are less than 128, so we + can use relatively efficient code. */ + + if (utf8) switch(c) + { + case OP_CHAR: + case OP_CHARNC: + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + while ((*code & 0xc0) == 0x80) code++; + break; + + /* XCLASS is used for classes that cannot be represented just by a bit + map. This includes negated single high-valued characters. The length in + the table is zero; the actual length is stored in the compiled code. */ + + case OP_XCLASS: + code += GET(code, 1) + 1; + break; + } +#endif + } + } +} + + + +/************************************************* +* Scan compiled branch for non-emptiness * +*************************************************/ + +/* This function scans through a branch of a compiled pattern to see whether it +can match the empty string or not. It is called only from could_be_empty() +below. Note that first_significant_code() skips over assertions. If we hit an +unclosed bracket, we return "empty" - this means we've struck an inner bracket +whose current branch will already have been scanned. + +Arguments: + code points to start of search + endcode points to where to stop + utf8 TRUE if in UTF8 mode + +Returns: TRUE if what is matched could be empty +*/ + +static BOOL +could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8) +{ +register int c; +for (code = first_significant_code(code + 1 + LINK_SIZE, NULL, 0, TRUE); + code < endcode; + code = first_significant_code(code + OP_lengths[c], NULL, 0, TRUE)) + { + const uschar *ccode; + + c = *code; + + if (c >= OP_BRA) + { + BOOL empty_branch; + if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ + + /* Scan a closed bracket */ + + empty_branch = FALSE; + do + { + if (!empty_branch && could_be_empty_branch(code, endcode, utf8)) + empty_branch = TRUE; + code += GET(code, 1); + } + while (*code == OP_ALT); + if (!empty_branch) return FALSE; /* All branches are non-empty */ + code += 1 + LINK_SIZE; + c = *code; + } + + else switch (c) + { + /* Check for quantifiers after a class */ + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + ccode = code + GET(code, 1); + goto CHECK_CLASS_REPEAT; +#endif + + case OP_CLASS: + case OP_NCLASS: + ccode = code + 33; + +#ifdef SUPPORT_UTF8 + CHECK_CLASS_REPEAT: +#endif + + switch (*ccode) + { + case OP_CRSTAR: /* These could be empty; continue */ + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + break; + + default: /* Non-repeat => class must match */ + case OP_CRPLUS: /* These repeats aren't empty */ + case OP_CRMINPLUS: + return FALSE; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ + break; + } + break; + + /* Opcodes that must match a character */ + + case OP_PROP: + case OP_NOTPROP: + case OP_EXTUNI: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ANYBYTE: + case OP_CHAR: + case OP_CHARNC: + case OP_NOT: + case OP_PLUS: + case OP_MINPLUS: + case OP_EXACT: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTEXACT: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEEXACT: + return FALSE; + + /* End of branch */ + + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_ALT: + return TRUE; + + /* In UTF-8 mode, STAR, MINSTAR, QUERY, MINQUERY, UPTO, and MINUPTO may be + followed by a multibyte character */ + +#ifdef SUPPORT_UTF8 + case OP_STAR: + case OP_MINSTAR: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + if (utf8) while ((code[2] & 0xc0) == 0x80) code++; + break; +#endif + } + } + +return TRUE; +} + + + +/************************************************* +* Scan compiled regex for non-emptiness * +*************************************************/ + +/* This function is called to check for left recursive calls. We want to check +the current branch of the current pattern to see if it could match the empty +string. If it could, we must look outwards for branches at other levels, +stopping when we pass beyond the bracket which is the subject of the recursion. + +Arguments: + code points to start of the recursion + endcode points to where to stop (current RECURSE item) + bcptr points to the chain of current (unclosed) branch starts + utf8 TRUE if in UTF-8 mode + +Returns: TRUE if what is matched could be empty +*/ + +static BOOL +could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr, + BOOL utf8) +{ +while (bcptr != NULL && bcptr->current >= code) + { + if (!could_be_empty_branch(bcptr->current, endcode, utf8)) return FALSE; + bcptr = bcptr->outer; + } +return TRUE; +} + + + +/************************************************* +* Check for POSIX class syntax * +*************************************************/ + +/* This function is called when the sequence "[:" or "[." or "[=" is +encountered in a character class. It checks whether this is followed by an +optional ^ and then a sequence of letters, terminated by a matching ":]" or +".]" or "=]". + +Argument: + ptr pointer to the initial [ + endptr where to return the end pointer + cd pointer to compile data + +Returns: TRUE or FALSE +*/ + +static BOOL +check_posix_syntax(const uschar *ptr, const uschar **endptr, compile_data *cd) +{ +int terminator; /* Don't combine these lines; the Solaris cc */ +terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ +if (*(++ptr) == '^') ptr++; +while ((cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; +if (*ptr == terminator && ptr[1] == ']') + { + *endptr = ptr; + return TRUE; + } +return FALSE; +} + + + + +/************************************************* +* Check POSIX class name * +*************************************************/ + +/* This function is called to check the name given in a POSIX-style class entry +such as [:alnum:]. + +Arguments: + ptr points to the first letter + len the length of the name + +Returns: a value representing the name, or -1 if unknown +*/ + +static int +check_posix_name(const uschar *ptr, int len) +{ +register int yield = 0; +while (posix_name_lengths[yield] != 0) + { + if (len == posix_name_lengths[yield] && + strncmp((const char *)ptr, posix_names[yield], len) == 0) return yield; + yield++; + } +return -1; +} + + +/************************************************* +* Adjust OP_RECURSE items in repeated group * +*************************************************/ + +/* OP_RECURSE items contain an offset from the start of the regex to the group +that is referenced. This means that groups can be replicated for fixed +repetition simply by copying (because the recursion is allowed to refer to +earlier groups that are outside the current group). However, when a group is +optional (i.e. the minimum quantifier is zero), OP_BRAZERO is inserted before +it, after it has been compiled. This means that any OP_RECURSE items within it +that refer to the group itself or any contained groups have to have their +offsets adjusted. That is the job of this function. Before it is called, the +partially compiled regex must be temporarily terminated with OP_END. + +Arguments: + group points to the start of the group + adjust the amount by which the group is to be moved + utf8 TRUE in UTF-8 mode + cd contains pointers to tables etc. + +Returns: nothing +*/ + +static void +adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd) +{ +uschar *ptr = group; +while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL) + { + int offset = GET(ptr, 1); + if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); + ptr += 1 + LINK_SIZE; + } +} + + + +/************************************************* +* Insert an automatic callout point * +*************************************************/ + +/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert +callout points before each pattern item. + +Arguments: + code current code pointer + ptr current pattern pointer + cd pointers to tables etc + +Returns: new code pointer +*/ + +static uschar * +auto_callout(uschar *code, const uschar *ptr, compile_data *cd) +{ +*code++ = OP_CALLOUT; +*code++ = 255; +PUT(code, 0, ptr - cd->start_pattern); /* Pattern offset */ +PUT(code, LINK_SIZE, 0); /* Default length */ +return code + 2*LINK_SIZE; +} + + + +/************************************************* +* Complete a callout item * +*************************************************/ + +/* A callout item contains the length of the next item in the pattern, which +we can't fill in till after we have reached the relevant point. This is used +for both automatic and manual callouts. + +Arguments: + previous_callout points to previous callout item + ptr current pattern pointer + cd pointers to tables etc + +Returns: nothing +*/ + +static void +complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd) +{ +int length = ptr - cd->start_pattern - GET(previous_callout, 2); +PUT(previous_callout, 2 + LINK_SIZE, length); +} + + + +#ifdef SUPPORT_UCP +/************************************************* +* Get othercase range * +*************************************************/ + +/* This function is passed the start and end of a class range, in UTF-8 mode +with UCP support. It searches up the characters, looking for internal ranges of +characters in the "other" case. Each call returns the next one, updating the +start address. + +Arguments: + cptr points to starting character value; updated + d end value + ocptr where to put start of othercase range + odptr where to put end of othercase range + +Yield: TRUE when range returned; FALSE when no more +*/ + +static BOOL +get_othercase_range(int *cptr, int d, int *ocptr, int *odptr) +{ +int c, chartype, othercase, next; + +for (c = *cptr; c <= d; c++) + { + if (ucp_findchar(c, &chartype, &othercase) == ucp_L && othercase != 0) break; + } + +if (c > d) return FALSE; + +*ocptr = othercase; +next = othercase + 1; + +for (++c; c <= d; c++) + { + if (ucp_findchar(c, &chartype, &othercase) != ucp_L || othercase != next) + break; + next++; + } + +*odptr = next - 1; +*cptr = c; + +return TRUE; +} +#endif /* SUPPORT_UCP */ + + +/************************************************* +* Compile one branch * +*************************************************/ + +/* Scan the pattern, compiling it into the code vector. If the options are +changed during the branch, the pointer is used to change the external options +bits. + +Arguments: + optionsptr pointer to the option bits + brackets points to number of extracting brackets used + codeptr points to the pointer to the current code point + ptrptr points to the current pattern pointer + errorptr points to pointer to error message + firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) + reqbyteptr set to the last literal character required, else < 0 + bcptr points to current branch chain + cd contains pointers to tables etc. + +Returns: TRUE on success + FALSE, with *errorptr set on error +*/ + +static BOOL +compile_branch(int *optionsptr, int *brackets, uschar **codeptr, + const uschar **ptrptr, const char **errorptr, int *firstbyteptr, + int *reqbyteptr, branch_chain *bcptr, compile_data *cd) +{ +int repeat_type, op_type; +int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ +int bravalue = 0; +int greedy_default, greedy_non_default; +int firstbyte, reqbyte; +int zeroreqbyte, zerofirstbyte; +int req_caseopt, reqvary, tempreqvary; +int condcount = 0; +int options = *optionsptr; +int after_manual_callout = 0; +register int c; +register uschar *code = *codeptr; +uschar *tempcode; +BOOL inescq = FALSE; +BOOL groupsetfirstbyte = FALSE; +const uschar *ptr = *ptrptr; +const uschar *tempptr; +uschar *previous = NULL; +uschar *previous_callout = NULL; +uschar classbits[32]; + +#ifdef SUPPORT_UTF8 +BOOL class_utf8; +BOOL utf8 = (options & PCRE_UTF8) != 0; +uschar *class_utf8data; +uschar utf8_char[6]; +#else +BOOL utf8 = FALSE; +#endif + +/* Set up the default and non-default settings for greediness */ + +greedy_default = ((options & PCRE_UNGREEDY) != 0); +greedy_non_default = greedy_default ^ 1; + +/* Initialize no first byte, no required byte. REQ_UNSET means "no char +matching encountered yet". It gets changed to REQ_NONE if we hit something that +matches a non-fixed char first char; reqbyte just remains unset if we never +find one. + +When we hit a repeat whose minimum is zero, we may have to adjust these values +to take the zero repeat into account. This is implemented by setting them to +zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual +item types that can be repeated set these backoff variables appropriately. */ + +firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET; + +/* The variable req_caseopt contains either the REQ_CASELESS value or zero, +according to the current setting of the caseless flag. REQ_CASELESS is a bit +value > 255. It is added into the firstbyte or reqbyte variables to record the +case status of the value. This is used only for ASCII characters. */ + +req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; + +/* Switch on next character until the end of the branch */ + +for (;; ptr++) + { + BOOL negate_class; + BOOL possessive_quantifier; + BOOL is_quantifier; + int class_charcount; + int class_lastchar; + int newoptions; + int recno; + int skipbytes; + int subreqbyte; + int subfirstbyte; + int mclength; + uschar mcbuffer[8]; + + /* Next byte in the pattern */ + + c = *ptr; + + /* If in \Q...\E, check for the end; if not, we have a literal */ + + if (inescq && c != 0) + { + if (c == '\\' && ptr[1] == 'E') + { + inescq = FALSE; + ptr++; + continue; + } + else + { + if (previous_callout != NULL) + { + complete_callout(previous_callout, ptr, cd); + previous_callout = NULL; + } + if ((options & PCRE_AUTO_CALLOUT) != 0) + { + previous_callout = code; + code = auto_callout(code, ptr, cd); + } + goto NORMAL_CHAR; + } + } + + /* Fill in length of a previous callout, except when the next thing is + a quantifier. */ + + is_quantifier = c == '*' || c == '+' || c == '?' || + (c == '{' && is_counted_repeat(ptr+1)); + + if (!is_quantifier && previous_callout != NULL && + after_manual_callout-- <= 0) + { + complete_callout(previous_callout, ptr, cd); + previous_callout = NULL; + } + + /* In extended mode, skip white space and comments */ + + if ((options & PCRE_EXTENDED) != 0) + { + if ((cd->ctypes[c] & ctype_space) != 0) continue; + if (c == '#') + { + /* The space before the ; is to avoid a warning on a silly compiler + on the Macintosh. */ + while ((c = *(++ptr)) != 0 && c != NEWLINE) ; + if (c != 0) continue; /* Else fall through to handle end of string */ + } + } + + /* No auto callout for quantifiers. */ + + if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) + { + previous_callout = code; + code = auto_callout(code, ptr, cd); + } + + switch(c) + { + /* The branch terminates at end of string, |, or ). */ + + case 0: + case '|': + case ')': + *firstbyteptr = firstbyte; + *reqbyteptr = reqbyte; + *codeptr = code; + *ptrptr = ptr; + return TRUE; + + /* Handle single-character metacharacters. In multiline mode, ^ disables + the setting of any following char as a first character. */ + + case '^': + if ((options & PCRE_MULTILINE) != 0) + { + if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + } + previous = NULL; + *code++ = OP_CIRC; + break; + + case '$': + previous = NULL; + *code++ = OP_DOLL; + break; + + /* There can never be a first char if '.' is first, whatever happens about + repeats. The value of reqbyte doesn't change either. */ + + case '.': + if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + zerofirstbyte = firstbyte; + zeroreqbyte = reqbyte; + previous = code; + *code++ = OP_ANY; + break; + + /* Character classes. If the included characters are all < 255 in value, we + build a 32-byte bitmap of the permitted characters, except in the special + case where there is only one such character. For negated classes, we build + the map as usual, then invert it at the end. However, we use a different + opcode so that data characters > 255 can be handled correctly. + + If the class contains characters outside the 0-255 range, a different + opcode is compiled. It may optionally have a bit map for characters < 256, + but those above are are explicitly listed afterwards. A flag byte tells + whether the bitmap is present, and whether this is a negated class or not. + */ + + case '[': + previous = code; + + /* PCRE supports POSIX class stuff inside a class. Perl gives an error if + they are encountered at the top level, so we'll do that too. */ + + if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && + check_posix_syntax(ptr, &tempptr, cd)) + { + *errorptr = (ptr[1] == ':')? ERR13 : ERR31; + goto FAILED; + } + + /* If the first character is '^', set the negation flag and skip it. */ + + if ((c = *(++ptr)) == '^') + { + negate_class = TRUE; + c = *(++ptr); + } + else + { + negate_class = FALSE; + } + + /* Keep a count of chars with values < 256 so that we can optimize the case + of just a single character (as long as it's < 256). For higher valued UTF-8 + characters, we don't yet do any optimization. */ + + class_charcount = 0; + class_lastchar = -1; + +#ifdef SUPPORT_UTF8 + class_utf8 = FALSE; /* No chars >= 256 */ + class_utf8data = code + LINK_SIZE + 34; /* For UTF-8 items */ +#endif + + /* Initialize the 32-char bit map to all zeros. We have to build the + map in a temporary bit of store, in case the class contains only 1 + character (< 256), because in that case the compiled code doesn't use the + bit map. */ + + memset(classbits, 0, 32 * sizeof(uschar)); + + /* Process characters until ] is reached. By writing this as a "do" it + means that an initial ] is taken as a data character. The first pass + through the regex checked the overall syntax, so we don't need to be very + strict here. At the start of the loop, c contains the first byte of the + character. */ + + do + { +#ifdef SUPPORT_UTF8 + if (utf8 && c > 127) + { /* Braces are required because the */ + GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ + } +#endif + + /* Inside \Q...\E everything is literal except \E */ + + if (inescq) + { + if (c == '\\' && ptr[1] == 'E') + { + inescq = FALSE; + ptr++; + continue; + } + else goto LONE_SINGLE_CHARACTER; + } + + /* Handle POSIX class names. Perl allows a negation extension of the + form [:^name:]. A square bracket that doesn't match the syntax is + treated as a literal. We also recognize the POSIX constructions + [.ch.] and [=ch=] ("collating elements") and fault them, as Perl + 5.6 and 5.8 do. */ + + if (c == '[' && + (ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && + check_posix_syntax(ptr, &tempptr, cd)) + { + BOOL local_negate = FALSE; + int posix_class, i; + register const uschar *cbits = cd->cbits; + + if (ptr[1] != ':') + { + *errorptr = ERR31; + goto FAILED; + } + + ptr += 2; + if (*ptr == '^') + { + local_negate = TRUE; + ptr++; + } + + posix_class = check_posix_name(ptr, tempptr - ptr); + if (posix_class < 0) + { + *errorptr = ERR30; + goto FAILED; + } + + /* If matching is caseless, upper and lower are converted to + alpha. This relies on the fact that the class table starts with + alpha, lower, upper as the first 3 entries. */ + + if ((options & PCRE_CASELESS) != 0 && posix_class <= 2) + posix_class = 0; + + /* Or into the map we are building up to 3 of the static class + tables, or their negations. The [:blank:] class sets up the same + chars as the [:space:] class (all white space). We remove the vertical + white space chars afterwards. */ + + posix_class *= 3; + for (i = 0; i < 3; i++) + { + BOOL blankclass = strncmp((char *)ptr, "blank", 5) == 0; + int taboffset = posix_class_maps[posix_class + i]; + if (taboffset < 0) break; + if (local_negate) + { + if (i == 0) + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+taboffset]; + else + for (c = 0; c < 32; c++) classbits[c] &= ~cbits[c+taboffset]; + if (blankclass) classbits[1] |= 0x3c; + } + else + { + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+taboffset]; + if (blankclass) classbits[1] &= ~0x3c; + } + } + + ptr = tempptr + 1; + class_charcount = 10; /* Set > 1; assumes more than 1 per class */ + continue; /* End of POSIX syntax handling */ + } + + /* Backslash may introduce a single character, or it may introduce one + of the specials, which just set a flag. Escaped items are checked for + validity in the pre-compiling pass. The sequence \b is a special case. + Inside a class (and only there) it is treated as backspace. Elsewhere + it marks a word boundary. Other escapes have preset maps ready to + or into the one we are building. We assume they have more than one + character in them, so set class_charcount bigger than one. */ + + if (c == '\\') + { + c = check_escape(&ptr, errorptr, *brackets, options, TRUE); + + if (-c == ESC_b) c = '\b'; /* \b is backslash in a class */ + else if (-c == ESC_X) c = 'X'; /* \X is literal X in a class */ + else if (-c == ESC_Q) /* Handle start of quoted string */ + { + if (ptr[1] == '\\' && ptr[2] == 'E') + { + ptr += 2; /* avoid empty string */ + } + else inescq = TRUE; + continue; + } + + if (c < 0) + { + register const uschar *cbits = cd->cbits; + class_charcount += 2; /* Greater than 1 is what matters */ + switch (-c) + { + case ESC_d: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; + continue; + + case ESC_D: + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; + continue; + + case ESC_w: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; + continue; + + case ESC_W: + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; + continue; + + case ESC_s: + for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; + classbits[1] &= ~0x08; /* Perl 5.004 onwards omits VT from \s */ + continue; + + case ESC_S: + for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; + classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ + continue; + +#ifdef SUPPORT_UCP + case ESC_p: + case ESC_P: + { + BOOL negated; + int property = get_ucp(&ptr, &negated, errorptr); + if (property < 0) goto FAILED; + class_utf8 = TRUE; + *class_utf8data++ = ((-c == ESC_p) != negated)? + XCL_PROP : XCL_NOTPROP; + *class_utf8data++ = property; + class_charcount -= 2; /* Not a < 256 character */ + } + continue; +#endif + + /* Unrecognized escapes are faulted if PCRE is running in its + strict mode. By default, for compatibility with Perl, they are + treated as literals. */ + + default: + if ((options & PCRE_EXTRA) != 0) + { + *errorptr = ERR7; + goto FAILED; + } + c = *ptr; /* The final character */ + class_charcount -= 2; /* Undo the default count from above */ + } + } + + /* Fall through if we have a single character (c >= 0). This may be + > 256 in UTF-8 mode. */ + + } /* End of backslash handling */ + + /* A single character may be followed by '-' to form a range. However, + Perl does not permit ']' to be the end of the range. A '-' character + here is treated as a literal. */ + + if (ptr[1] == '-' && ptr[2] != ']') + { + int d; + ptr += 2; + +#ifdef SUPPORT_UTF8 + if (utf8) + { /* Braces are required because the */ + GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ + } + else +#endif + d = *ptr; /* Not UTF-8 mode */ + + /* The second part of a range can be a single-character escape, but + not any of the other escapes. Perl 5.6 treats a hyphen as a literal + in such circumstances. */ + + if (d == '\\') + { + const uschar *oldptr = ptr; + d = check_escape(&ptr, errorptr, *brackets, options, TRUE); + + /* \b is backslash; \X is literal X; any other special means the '-' + was literal */ + + if (d < 0) + { + if (d == -ESC_b) d = '\b'; + else if (d == -ESC_X) d = 'X'; else + { + ptr = oldptr - 2; + goto LONE_SINGLE_CHARACTER; /* A few lines below */ + } + } + } + + /* The check that the two values are in the correct order happens in + the pre-pass. Optimize one-character ranges */ + + if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */ + + /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless + matching, we have to use an XCLASS with extra data items. Caseless + matching for characters > 127 is available only if UCP support is + available. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) + { + class_utf8 = TRUE; + + /* With UCP support, we can find the other case equivalents of + the relevant characters. There may be several ranges. Optimize how + they fit with the basic range. */ + +#ifdef SUPPORT_UCP + if ((options & PCRE_CASELESS) != 0) + { + int occ, ocd; + int cc = c; + int origd = d; + while (get_othercase_range(&cc, origd, &occ, &ocd)) + { + if (occ >= c && ocd <= d) continue; /* Skip embedded ranges */ + + if (occ < c && ocd >= c - 1) /* Extend the basic range */ + { /* if there is overlap, */ + c = occ; /* noting that if occ < c */ + continue; /* we can't have ocd > d */ + } /* because a subrange is */ + if (ocd > d && occ <= d + 1) /* always shorter than */ + { /* the basic range. */ + d = ocd; + continue; + } + + if (occ == ocd) + { + *class_utf8data++ = XCL_SINGLE; + } + else + { + *class_utf8data++ = XCL_RANGE; + class_utf8data += ord2utf8(occ, class_utf8data); + } + class_utf8data += ord2utf8(ocd, class_utf8data); + } + } +#endif /* SUPPORT_UCP */ + + /* Now record the original range, possibly modified for UCP caseless + overlapping ranges. */ + + *class_utf8data++ = XCL_RANGE; + class_utf8data += ord2utf8(c, class_utf8data); + class_utf8data += ord2utf8(d, class_utf8data); + + /* With UCP support, we are done. Without UCP support, there is no + caseless matching for UTF-8 characters > 127; we can use the bit map + for the smaller ones. */ + +#ifdef SUPPORT_UCP + continue; /* With next character in the class */ +#else + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + + /* Adjust upper limit and fall through to set up the map */ + + d = 127; + +#endif /* SUPPORT_UCP */ + } +#endif /* SUPPORT_UTF8 */ + + /* We use the bit map for all cases when not in UTF-8 mode; else + ranges that lie entirely within 0-127 when there is UCP support; else + for partial ranges without UCP support. */ + + for (; c <= d; c++) + { + classbits[c/8] |= (1 << (c&7)); + if ((options & PCRE_CASELESS) != 0) + { + int uc = cd->fcc[c]; /* flip case */ + classbits[uc/8] |= (1 << (uc&7)); + } + class_charcount++; /* in case a one-char range */ + class_lastchar = c; + } + + continue; /* Go get the next char in the class */ + } + + /* Handle a lone single character - we can get here for a normal + non-escape char, or after \ that introduces a single character or for an + apparent range that isn't. */ + + LONE_SINGLE_CHARACTER: + + /* Handle a character that cannot go in the bit map */ + +#ifdef SUPPORT_UTF8 + if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) + { + class_utf8 = TRUE; + *class_utf8data++ = XCL_SINGLE; + class_utf8data += ord2utf8(c, class_utf8data); + +#ifdef SUPPORT_UCP + if ((options & PCRE_CASELESS) != 0) + { + int chartype; + int othercase; + if (ucp_findchar(c, &chartype, &othercase) >= 0 && othercase > 0) + { + *class_utf8data++ = XCL_SINGLE; + class_utf8data += ord2utf8(othercase, class_utf8data); + } + } +#endif /* SUPPORT_UCP */ + + } + else +#endif /* SUPPORT_UTF8 */ + + /* Handle a single-byte character */ + { + classbits[c/8] |= (1 << (c&7)); + if ((options & PCRE_CASELESS) != 0) + { + c = cd->fcc[c]; /* flip case */ + classbits[c/8] |= (1 << (c&7)); + } + class_charcount++; + class_lastchar = c; + } + } + + /* Loop until ']' reached; the check for end of string happens inside the + loop. This "while" is the end of the "do" above. */ + + while ((c = *(++ptr)) != ']' || inescq); + + /* If class_charcount is 1, we saw precisely one character whose value is + less than 256. In non-UTF-8 mode we can always optimize. In UTF-8 mode, we + can optimize the negative case only if there were no characters >= 128 + because OP_NOT and the related opcodes like OP_NOTSTAR operate on + single-bytes only. This is an historical hangover. Maybe one day we can + tidy these opcodes to handle multi-byte characters. + + The optimization throws away the bit map. We turn the item into a + 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note + that OP_NOT does not support multibyte characters. In the positive case, it + can cause firstbyte to be set. Otherwise, there can be no first char if + this item is first, whatever repeat count may follow. In the case of + reqbyte, save the previous value for reinstating. */ + +#ifdef SUPPORT_UTF8 + if (class_charcount == 1 && + (!utf8 || + (!class_utf8 && (!negate_class || class_lastchar < 128)))) + +#else + if (class_charcount == 1) +#endif + { + zeroreqbyte = reqbyte; + + /* The OP_NOT opcode works on one-byte characters only. */ + + if (negate_class) + { + if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + zerofirstbyte = firstbyte; + *code++ = OP_NOT; + *code++ = class_lastchar; + break; + } + + /* For a single, positive character, get the value into mcbuffer, and + then we can handle this with the normal one-character code. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && class_lastchar > 127) + mclength = ord2utf8(class_lastchar, mcbuffer); + else +#endif + { + mcbuffer[0] = class_lastchar; + mclength = 1; + } + goto ONE_CHAR; + } /* End of 1-char optimization */ + + /* The general case - not the one-char optimization. If this is the first + thing in the branch, there can be no first char setting, whatever the + repeat count. Any reqbyte setting must remain unchanged after any kind of + repeat. */ + + if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + zerofirstbyte = firstbyte; + zeroreqbyte = reqbyte; + + /* If there are characters with values > 255, we have to compile an + extended class, with its own opcode. If there are no characters < 256, + we can omit the bitmap. */ + +#ifdef SUPPORT_UTF8 + if (class_utf8) + { + *class_utf8data++ = XCL_END; /* Marks the end of extra data */ + *code++ = OP_XCLASS; + code += LINK_SIZE; + *code = negate_class? XCL_NOT : 0; + + /* If the map is required, install it, and move on to the end of + the extra data */ + + if (class_charcount > 0) + { + *code++ |= XCL_MAP; + memcpy(code, classbits, 32); + code = class_utf8data; + } + + /* If the map is not required, slide down the extra data. */ + + else + { + int len = class_utf8data - (code + 33); + memmove(code + 1, code + 33, len); + code += len + 1; + } + + /* Now fill in the complete length of the item */ + + PUT(previous, 1, code - previous); + break; /* End of class handling */ + } +#endif + + /* If there are no characters > 255, negate the 32-byte map if necessary, + and copy it into the code vector. If this is the first thing in the branch, + there can be no first char setting, whatever the repeat count. Any reqbyte + setting must remain unchanged after any kind of repeat. */ + + if (negate_class) + { + *code++ = OP_NCLASS; + for (c = 0; c < 32; c++) code[c] = ~classbits[c]; + } + else + { + *code++ = OP_CLASS; + memcpy(code, classbits, 32); + } + code += 32; + break; + + /* Various kinds of repeat; '{' is not necessarily a quantifier, but this + has been tested above. */ + + case '{': + if (!is_quantifier) goto NORMAL_CHAR; + ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorptr); + if (*errorptr != NULL) goto FAILED; + goto REPEAT; + + case '*': + repeat_min = 0; + repeat_max = -1; + goto REPEAT; + + case '+': + repeat_min = 1; + repeat_max = -1; + goto REPEAT; + + case '?': + repeat_min = 0; + repeat_max = 1; + + REPEAT: + if (previous == NULL) + { + *errorptr = ERR9; + goto FAILED; + } + + if (repeat_min == 0) + { + firstbyte = zerofirstbyte; /* Adjust for zero repeat */ + reqbyte = zeroreqbyte; /* Ditto */ + } + + /* Remember whether this is a variable length repeat */ + + reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; + + op_type = 0; /* Default single-char op codes */ + possessive_quantifier = FALSE; /* Default not possessive quantifier */ + + /* Save start of previous item, in case we have to move it up to make space + for an inserted OP_ONCE for the additional '+' extension. */ + + tempcode = previous; + + /* If the next character is '+', we have a possessive quantifier. This + implies greediness, whatever the setting of the PCRE_UNGREEDY option. + If the next character is '?' this is a minimizing repeat, by default, + but if PCRE_UNGREEDY is set, it works the other way round. We change the + repeat type to the non-default. */ + + if (ptr[1] == '+') + { + repeat_type = 0; /* Force greedy */ + possessive_quantifier = TRUE; + ptr++; + } + else if (ptr[1] == '?') + { + repeat_type = greedy_non_default; + ptr++; + } + else repeat_type = greedy_default; + + /* If previous was a recursion, we need to wrap it inside brackets so that + it can be replicated if necessary. */ + + if (*previous == OP_RECURSE) + { + memmove(previous + 1 + LINK_SIZE, previous, 1 + LINK_SIZE); + code += 1 + LINK_SIZE; + *previous = OP_BRA; + PUT(previous, 1, code - previous); + *code = OP_KET; + PUT(code, 1, code - previous); + code += 1 + LINK_SIZE; + } + + /* If previous was a character match, abolish the item and generate a + repeat item instead. If a char item has a minumum of more than one, ensure + that it is set in reqbyte - it might not be if a sequence such as x{3} is + the first thing in a branch because the x will have gone into firstbyte + instead. */ + + if (*previous == OP_CHAR || *previous == OP_CHARNC) + { + /* Deal with UTF-8 characters that take up more than one byte. It's + easier to write this out separately than try to macrify it. Use c to + hold the length of the character in bytes, plus 0x80 to flag that it's a + length rather than a small character. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && (code[-1] & 0x80) != 0) + { + uschar *lastchar = code - 1; + while((*lastchar & 0xc0) == 0x80) lastchar--; + c = code - lastchar; /* Length of UTF-8 character */ + memcpy(utf8_char, lastchar, c); /* Save the char */ + c |= 0x80; /* Flag c as a length */ + } + else +#endif + + /* Handle the case of a single byte - either with no UTF8 support, or + with UTF-8 disabled, or for a UTF-8 character < 128. */ + + { + c = code[-1]; + if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt; + } + + goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ + } + + /* If previous was a single negated character ([^a] or similar), we use + one of the special opcodes, replacing it. The code is shared with single- + character repeats by setting opt_type to add a suitable offset into + repeat_type. OP_NOT is currently used only for single-byte chars. */ + + else if (*previous == OP_NOT) + { + op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ + c = previous[1]; + goto OUTPUT_SINGLE_REPEAT; + } + + /* If previous was a character type match (\d or similar), abolish it and + create a suitable repeat item. The code is shared with single-character + repeats by setting op_type to add a suitable offset into repeat_type. Note + the the Unicode property types will be present only when SUPPORT_UCP is + defined, but we don't wrap the little bits of code here because it just + makes it horribly messy. */ + + else if (*previous < OP_EODN) + { + uschar *oldcode; + int prop_type; + op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ + c = *previous; + + OUTPUT_SINGLE_REPEAT: + prop_type = (*previous == OP_PROP || *previous == OP_NOTPROP)? + previous[1] : -1; + + oldcode = code; + code = previous; /* Usually overwrite previous item */ + + /* If the maximum is zero then the minimum must also be zero; Perl allows + this case, so we do too - by simply omitting the item altogether. */ + + if (repeat_max == 0) goto END_REPEAT; + + /* All real repeats make it impossible to handle partial matching (maybe + one day we will be able to remove this restriction). */ + + if (repeat_max != 1) cd->nopartial = TRUE; + + /* Combine the op_type with the repeat_type */ + + repeat_type += op_type; + + /* A minimum of zero is handled either as the special case * or ?, or as + an UPTO, with the maximum given. */ + + if (repeat_min == 0) + { + if (repeat_max == -1) *code++ = OP_STAR + repeat_type; + else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; + else + { + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + + /* A repeat minimum of 1 is optimized into some special cases. If the + maximum is unlimited, we use OP_PLUS. Otherwise, the original item it + left in place and, if the maximum is greater than 1, we use OP_UPTO with + one less than the maximum. */ + + else if (repeat_min == 1) + { + if (repeat_max == -1) + *code++ = OP_PLUS + repeat_type; + else + { + code = oldcode; /* leave previous item in place */ + if (repeat_max == 1) goto END_REPEAT; + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max - 1); + } + } + + /* The case {n,n} is just an EXACT, while the general case {n,m} is + handled as an EXACT followed by an UPTO. */ + + else + { + *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ + PUT2INC(code, 0, repeat_min); + + /* If the maximum is unlimited, insert an OP_STAR. Before doing so, + we have to insert the character for the previous code. For a repeated + Unicode property match, there is an extra byte that defines the + required property. In UTF-8 mode, long characters have their length in + c, with the 0x80 bit as a flag. */ + + if (repeat_max < 0) + { +#ifdef SUPPORT_UTF8 + if (utf8 && c >= 128) + { + memcpy(code, utf8_char, c & 7); + code += c & 7; + } + else +#endif + { + *code++ = c; + if (prop_type >= 0) *code++ = prop_type; + } + *code++ = OP_STAR + repeat_type; + } + + /* Else insert an UPTO if the max is greater than the min, again + preceded by the character, for the previously inserted code. */ + + else if (repeat_max != repeat_min) + { +#ifdef SUPPORT_UTF8 + if (utf8 && c >= 128) + { + memcpy(code, utf8_char, c & 7); + code += c & 7; + } + else +#endif + *code++ = c; + if (prop_type >= 0) *code++ = prop_type; + repeat_max -= repeat_min; + *code++ = OP_UPTO + repeat_type; + PUT2INC(code, 0, repeat_max); + } + } + + /* The character or character type itself comes last in all cases. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && c >= 128) + { + memcpy(code, utf8_char, c & 7); + code += c & 7; + } + else +#endif + *code++ = c; + + /* For a repeated Unicode property match, there is an extra byte that + defines the required property. */ + +#ifdef SUPPORT_UCP + if (prop_type >= 0) *code++ = prop_type; +#endif + } + + /* If previous was a character class or a back reference, we put the repeat + stuff after it, but just skip the item if the repeat was {0,0}. */ + + else if (*previous == OP_CLASS || + *previous == OP_NCLASS || +#ifdef SUPPORT_UTF8 + *previous == OP_XCLASS || +#endif + *previous == OP_REF) + { + if (repeat_max == 0) + { + code = previous; + goto END_REPEAT; + } + + /* All real repeats make it impossible to handle partial matching (maybe + one day we will be able to remove this restriction). */ + + if (repeat_max != 1) cd->nopartial = TRUE; + + if (repeat_min == 0 && repeat_max == -1) + *code++ = OP_CRSTAR + repeat_type; + else if (repeat_min == 1 && repeat_max == -1) + *code++ = OP_CRPLUS + repeat_type; + else if (repeat_min == 0 && repeat_max == 1) + *code++ = OP_CRQUERY + repeat_type; + else + { + *code++ = OP_CRRANGE + repeat_type; + PUT2INC(code, 0, repeat_min); + if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ + PUT2INC(code, 0, repeat_max); + } + } + + /* If previous was a bracket group, we may have to replicate it in certain + cases. */ + + else if (*previous >= OP_BRA || *previous == OP_ONCE || + *previous == OP_COND) + { + register int i; + int ketoffset = 0; + int len = code - previous; + uschar *bralink = NULL; + + /* If the maximum repeat count is unlimited, find the end of the bracket + by scanning through from the start, and compute the offset back to it + from the current code pointer. There may be an OP_OPT setting following + the final KET, so we can't find the end just by going back from the code + pointer. */ + + if (repeat_max == -1) + { + register uschar *ket = previous; + do ket += GET(ket, 1); while (*ket != OP_KET); + ketoffset = code - ket; + } + + /* The case of a zero minimum is special because of the need to stick + OP_BRAZERO in front of it, and because the group appears once in the + data, whereas in other cases it appears the minimum number of times. For + this reason, it is simplest to treat this case separately, as otherwise + the code gets far too messy. There are several special subcases when the + minimum is zero. */ + + if (repeat_min == 0) + { + /* If the maximum is also zero, we just omit the group from the output + altogether. */ + + if (repeat_max == 0) + { + code = previous; + goto END_REPEAT; + } + + /* If the maximum is 1 or unlimited, we just have to stick in the + BRAZERO and do no more at this point. However, we do need to adjust + any OP_RECURSE calls inside the group that refer to the group itself or + any internal group, because the offset is from the start of the whole + regex. Temporarily terminate the pattern while doing this. */ + + if (repeat_max <= 1) + { + *code = OP_END; + adjust_recurse(previous, 1, utf8, cd); + memmove(previous+1, previous, len); + code++; + *previous++ = OP_BRAZERO + repeat_type; + } + + /* If the maximum is greater than 1 and limited, we have to replicate + in a nested fashion, sticking OP_BRAZERO before each set of brackets. + The first one has to be handled carefully because it's the original + copy, which has to be moved up. The remainder can be handled by code + that is common with the non-zero minimum case below. We have to + adjust the value or repeat_max, since one less copy is required. Once + again, we may have to adjust any OP_RECURSE calls inside the group. */ + + else + { + int offset; + *code = OP_END; + adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd); + memmove(previous + 2 + LINK_SIZE, previous, len); + code += 2 + LINK_SIZE; + *previous++ = OP_BRAZERO + repeat_type; + *previous++ = OP_BRA; + + /* We chain together the bracket offset fields that have to be + filled in later when the ends of the brackets are reached. */ + + offset = (bralink == NULL)? 0 : previous - bralink; + bralink = previous; + PUTINC(previous, 0, offset); + } + + repeat_max--; + } + + /* If the minimum is greater than zero, replicate the group as many + times as necessary, and adjust the maximum to the number of subsequent + copies that we need. If we set a first char from the group, and didn't + set a required char, copy the latter from the former. */ + + else + { + if (repeat_min > 1) + { + if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte; + for (i = 1; i < repeat_min; i++) + { + memcpy(code, previous, len); + code += len; + } + } + if (repeat_max > 0) repeat_max -= repeat_min; + } + + /* This code is common to both the zero and non-zero minimum cases. If + the maximum is limited, it replicates the group in a nested fashion, + remembering the bracket starts on a stack. In the case of a zero minimum, + the first one was set up above. In all cases the repeat_max now specifies + the number of additional copies needed. */ + + if (repeat_max >= 0) + { + for (i = repeat_max - 1; i >= 0; i--) + { + *code++ = OP_BRAZERO + repeat_type; + + /* All but the final copy start a new nesting, maintaining the + chain of brackets outstanding. */ + + if (i != 0) + { + int offset; + *code++ = OP_BRA; + offset = (bralink == NULL)? 0 : code - bralink; + bralink = code; + PUTINC(code, 0, offset); + } + + memcpy(code, previous, len); + code += len; + } + + /* Now chain through the pending brackets, and fill in their length + fields (which are holding the chain links pro tem). */ + + while (bralink != NULL) + { + int oldlinkoffset; + int offset = code - bralink + 1; + uschar *bra = code - offset; + oldlinkoffset = GET(bra, 1); + bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; + *code++ = OP_KET; + PUTINC(code, 0, offset); + PUT(bra, 1, offset); + } + } + + /* If the maximum is unlimited, set a repeater in the final copy. We + can't just offset backwards from the current code point, because we + don't know if there's been an options resetting after the ket. The + correct offset was computed above. */ + + else code[-ketoffset] = OP_KETRMAX + repeat_type; + } + + /* Else there's some kind of shambles */ + + else + { + *errorptr = ERR11; + goto FAILED; + } + + /* If the character following a repeat is '+', we wrap the entire repeated + item inside OP_ONCE brackets. This is just syntactic sugar, taken from + Sun's Java package. The repeated item starts at tempcode, not at previous, + which might be the first part of a string whose (former) last char we + repeated. However, we don't support '+' after a greediness '?'. */ + + if (possessive_quantifier) + { + int len = code - tempcode; + memmove(tempcode + 1+LINK_SIZE, tempcode, len); + code += 1 + LINK_SIZE; + len += 1 + LINK_SIZE; + tempcode[0] = OP_ONCE; + *code++ = OP_KET; + PUTINC(code, 0, len); + PUT(tempcode, 1, len); + } + + /* In all case we no longer have a previous item. We also set the + "follows varying string" flag for subsequently encountered reqbytes if + it isn't already set and we have just passed a varying length item. */ + + END_REPEAT: + previous = NULL; + cd->req_varyopt |= reqvary; + break; + + + /* Start of nested bracket sub-expression, or comment or lookahead or + lookbehind or option setting or condition. First deal with special things + that can come after a bracket; all are introduced by ?, and the appearance + of any of them means that this is not a referencing group. They were + checked for validity in the first pass over the string, so we don't have to + check for syntax errors here. */ + + case '(': + newoptions = options; + skipbytes = 0; + + if (*(++ptr) == '?') + { + int set, unset; + int *optset; + + switch (*(++ptr)) + { + case '#': /* Comment; skip to ket */ + ptr++; + while (*ptr != ')') ptr++; + continue; + + case ':': /* Non-extracting bracket */ + bravalue = OP_BRA; + ptr++; + break; + + case '(': + bravalue = OP_COND; /* Conditional group */ + + /* Condition to test for recursion */ + + if (ptr[1] == 'R') + { + code[1+LINK_SIZE] = OP_CREF; + PUT2(code, 2+LINK_SIZE, CREF_RECURSE); + skipbytes = 3; + ptr += 3; + } + + /* Condition to test for a numbered subpattern match. We know that + if a digit follows ( then there will just be digits until ) because + the syntax was checked in the first pass. */ + + else if ((digitab[ptr[1]] && ctype_digit) != 0) + { + int condref; /* Don't amalgamate; some compilers */ + condref = *(++ptr) - '0'; /* grumble at autoincrement in declaration */ + while (*(++ptr) != ')') condref = condref*10 + *ptr - '0'; + if (condref == 0) + { + *errorptr = ERR35; + goto FAILED; + } + ptr++; + code[1+LINK_SIZE] = OP_CREF; + PUT2(code, 2+LINK_SIZE, condref); + skipbytes = 3; + } + /* For conditions that are assertions, we just fall through, having + set bravalue above. */ + break; + + case '=': /* Positive lookahead */ + bravalue = OP_ASSERT; + ptr++; + break; + + case '!': /* Negative lookahead */ + bravalue = OP_ASSERT_NOT; + ptr++; + break; + + case '<': /* Lookbehinds */ + switch (*(++ptr)) + { + case '=': /* Positive lookbehind */ + bravalue = OP_ASSERTBACK; + ptr++; + break; + + case '!': /* Negative lookbehind */ + bravalue = OP_ASSERTBACK_NOT; + ptr++; + break; + } + break; + + case '>': /* One-time brackets */ + bravalue = OP_ONCE; + ptr++; + break; + + case 'C': /* Callout - may be followed by digits; */ + previous_callout = code; /* Save for later completion */ + after_manual_callout = 1; /* Skip one item before completing */ + *code++ = OP_CALLOUT; /* Already checked that the terminating */ + { /* closing parenthesis is present. */ + int n = 0; + while ((digitab[*(++ptr)] & ctype_digit) != 0) + n = n * 10 + *ptr - '0'; + if (n > 255) + { + *errorptr = ERR38; + goto FAILED; + } + *code++ = n; + PUT(code, 0, ptr - cd->start_pattern + 1); /* Pattern offset */ + PUT(code, LINK_SIZE, 0); /* Default length */ + code += 2 * LINK_SIZE; + } + previous = NULL; + continue; + + case 'P': /* Named subpattern handling */ + if (*(++ptr) == '<') /* Definition */ + { + int i, namelen; + uschar *slot = cd->name_table; + const uschar *name; /* Don't amalgamate; some compilers */ + name = ++ptr; /* grumble at autoincrement in declaration */ + + while (*ptr++ != '>'); + namelen = ptr - name - 1; + + for (i = 0; i < cd->names_found; i++) + { + int crc = memcmp(name, slot+2, namelen); + if (crc == 0) + { + if (slot[2+namelen] == 0) + { + *errorptr = ERR43; + goto FAILED; + } + crc = -1; /* Current name is substring */ + } + if (crc < 0) + { + memmove(slot + cd->name_entry_size, slot, + (cd->names_found - i) * cd->name_entry_size); + break; + } + slot += cd->name_entry_size; + } + + PUT2(slot, 0, *brackets + 1); + memcpy(slot + 2, name, namelen); + slot[2+namelen] = 0; + cd->names_found++; + goto NUMBERED_GROUP; + } + + if (*ptr == '=' || *ptr == '>') /* Reference or recursion */ + { + int i, namelen; + int type = *ptr++; + const uschar *name = ptr; + uschar *slot = cd->name_table; + + while (*ptr != ')') ptr++; + namelen = ptr - name; + + for (i = 0; i < cd->names_found; i++) + { + if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; + slot += cd->name_entry_size; + } + if (i >= cd->names_found) + { + *errorptr = ERR15; + goto FAILED; + } + + recno = GET2(slot, 0); + + if (type == '>') goto HANDLE_RECURSION; /* A few lines below */ + + /* Back reference */ + + previous = code; + *code++ = OP_REF; + PUT2INC(code, 0, recno); + cd->backref_map |= (recno < 32)? (1 << recno) : 1; + if (recno > cd->top_backref) cd->top_backref = recno; + continue; + } + + /* Should never happen */ + break; + + case 'R': /* Pattern recursion */ + ptr++; /* Same as (?0) */ + /* Fall through */ + + /* Recursion or "subroutine" call */ + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + const uschar *called; + recno = 0; + while((digitab[*ptr] & ctype_digit) != 0) + recno = recno * 10 + *ptr++ - '0'; + + /* Come here from code above that handles a named recursion */ + + HANDLE_RECURSION: + + previous = code; + + /* Find the bracket that is being referenced. Temporarily end the + regex in case it doesn't exist. */ + + *code = OP_END; + called = (recno == 0)? + cd->start_code : find_bracket(cd->start_code, utf8, recno); + + if (called == NULL) + { + *errorptr = ERR15; + goto FAILED; + } + + /* If the subpattern is still open, this is a recursive call. We + check to see if this is a left recursion that could loop for ever, + and diagnose that case. */ + + if (GET(called, 1) == 0 && could_be_empty(called, code, bcptr, utf8)) + { + *errorptr = ERR40; + goto FAILED; + } + + /* Insert the recursion/subroutine item */ + + *code = OP_RECURSE; + PUT(code, 1, called - cd->start_code); + code += 1 + LINK_SIZE; + } + continue; + + /* Character after (? not specially recognized */ + + default: /* Option setting */ + set = unset = 0; + optset = &set; + + while (*ptr != ')' && *ptr != ':') + { + switch (*ptr++) + { + case '-': optset = &unset; break; + + case 'i': *optset |= PCRE_CASELESS; break; + case 'm': *optset |= PCRE_MULTILINE; break; + case 's': *optset |= PCRE_DOTALL; break; + case 'x': *optset |= PCRE_EXTENDED; break; + case 'U': *optset |= PCRE_UNGREEDY; break; + case 'X': *optset |= PCRE_EXTRA; break; + } + } + + /* Set up the changed option bits, but don't change anything yet. */ + + newoptions = (options | set) & (~unset); + + /* If the options ended with ')' this is not the start of a nested + group with option changes, so the options change at this level. Compile + code to change the ims options if this setting actually changes any of + them. We also pass the new setting back so that it can be put at the + start of any following branches, and when this group ends (if we are in + a group), a resetting item can be compiled. + + Note that if this item is right at the start of the pattern, the + options will have been abstracted and made global, so there will be no + change to compile. */ + + if (*ptr == ')') + { + if ((options & PCRE_IMS) != (newoptions & PCRE_IMS)) + { + *code++ = OP_OPT; + *code++ = newoptions & PCRE_IMS; + } + + /* Change options at this level, and pass them back for use + in subsequent branches. Reset the greedy defaults and the case + value for firstbyte and reqbyte. */ + + *optionsptr = options = newoptions; + greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); + greedy_non_default = greedy_default ^ 1; + req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; + + previous = NULL; /* This item can't be repeated */ + continue; /* It is complete */ + } + + /* If the options ended with ':' we are heading into a nested group + with possible change of options. Such groups are non-capturing and are + not assertions of any kind. All we need to do is skip over the ':'; + the newoptions value is handled below. */ + + bravalue = OP_BRA; + ptr++; + } + } + + /* If PCRE_NO_AUTO_CAPTURE is set, all unadorned brackets become + non-capturing and behave like (?:...) brackets */ + + else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) + { + bravalue = OP_BRA; + } + + /* Else we have a referencing group; adjust the opcode. If the bracket + number is greater than EXTRACT_BASIC_MAX, we set the opcode one higher, and + arrange for the true number to follow later, in an OP_BRANUMBER item. */ + + else + { + NUMBERED_GROUP: + if (++(*brackets) > EXTRACT_BASIC_MAX) + { + bravalue = OP_BRA + EXTRACT_BASIC_MAX + 1; + code[1+LINK_SIZE] = OP_BRANUMBER; + PUT2(code, 2+LINK_SIZE, *brackets); + skipbytes = 3; + } + else bravalue = OP_BRA + *brackets; + } + + /* Process nested bracketed re. Assertions may not be repeated, but other + kinds can be. We copy code into a non-register variable in order to be able + to pass its address because some compilers complain otherwise. Pass in a + new setting for the ims options if they have changed. */ + + previous = (bravalue >= OP_ONCE)? code : NULL; + *code = bravalue; + tempcode = code; + tempreqvary = cd->req_varyopt; /* Save value before bracket */ + + if (!compile_regex( + newoptions, /* The complete new option state */ + options & PCRE_IMS, /* The previous ims option state */ + brackets, /* Extracting bracket count */ + &tempcode, /* Where to put code (updated) */ + &ptr, /* Input pointer (updated) */ + errorptr, /* Where to put an error message */ + (bravalue == OP_ASSERTBACK || + bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ + skipbytes, /* Skip over OP_COND/OP_BRANUMBER */ + &subfirstbyte, /* For possible first char */ + &subreqbyte, /* For possible last char */ + bcptr, /* Current branch chain */ + cd)) /* Tables block */ + goto FAILED; + + /* At the end of compiling, code is still pointing to the start of the + group, while tempcode has been updated to point past the end of the group + and any option resetting that may follow it. The pattern pointer (ptr) + is on the bracket. */ + + /* If this is a conditional bracket, check that there are no more than + two branches in the group. */ + + else if (bravalue == OP_COND) + { + uschar *tc = code; + condcount = 0; + + do { + condcount++; + tc += GET(tc,1); + } + while (*tc != OP_KET); + + if (condcount > 2) + { + *errorptr = ERR27; + goto FAILED; + } + + /* If there is just one branch, we must not make use of its firstbyte or + reqbyte, because this is equivalent to an empty second branch. */ + + if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE; + } + + /* Handle updating of the required and first characters. Update for normal + brackets of all kinds, and conditions with two branches (see code above). + If the bracket is followed by a quantifier with zero repeat, we have to + back off. Hence the definition of zeroreqbyte and zerofirstbyte outside the + main loop so that they can be accessed for the back off. */ + + zeroreqbyte = reqbyte; + zerofirstbyte = firstbyte; + groupsetfirstbyte = FALSE; + + if (bravalue >= OP_BRA || bravalue == OP_ONCE || bravalue == OP_COND) + { + /* If we have not yet set a firstbyte in this branch, take it from the + subpattern, remembering that it was set here so that a repeat of more + than one can replicate it as reqbyte if necessary. If the subpattern has + no firstbyte, set "none" for the whole branch. In both cases, a zero + repeat forces firstbyte to "none". */ + + if (firstbyte == REQ_UNSET) + { + if (subfirstbyte >= 0) + { + firstbyte = subfirstbyte; + groupsetfirstbyte = TRUE; + } + else firstbyte = REQ_NONE; + zerofirstbyte = REQ_NONE; + } + + /* If firstbyte was previously set, convert the subpattern's firstbyte + into reqbyte if there wasn't one, using the vary flag that was in + existence beforehand. */ + + else if (subfirstbyte >= 0 && subreqbyte < 0) + subreqbyte = subfirstbyte | tempreqvary; + + /* If the subpattern set a required byte (or set a first byte that isn't + really the first byte - see above), set it. */ + + if (subreqbyte >= 0) reqbyte = subreqbyte; + } + + /* For a forward assertion, we take the reqbyte, if set. This can be + helpful if the pattern that follows the assertion doesn't set a different + char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte + for an assertion, however because it leads to incorrect effect for patterns + such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead + of a firstbyte. This is overcome by a scan at the end if there's no + firstbyte, looking for an asserted first char. */ + + else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte; + + /* Now update the main code pointer to the end of the group. */ + + code = tempcode; + + /* Error if hit end of pattern */ + + if (*ptr != ')') + { + *errorptr = ERR14; + goto FAILED; + } + break; + + /* Check \ for being a real metacharacter; if not, fall through and handle + it as a data character at the start of a string. Escape items are checked + for validity in the pre-compiling pass. */ + + case '\\': + tempptr = ptr; + c = check_escape(&ptr, errorptr, *brackets, options, FALSE); + + /* Handle metacharacters introduced by \. For ones like \d, the ESC_ values + are arranged to be the negation of the corresponding OP_values. For the + back references, the values are ESC_REF plus the reference number. Only + back references and those types that consume a character may be repeated. + We can test for values between ESC_b and ESC_Z for the latter; this may + have to change if any new ones are ever created. */ + + if (c < 0) + { + if (-c == ESC_Q) /* Handle start of quoted string */ + { + if (ptr[1] == '\\' && ptr[2] == 'E') ptr += 2; /* avoid empty string */ + else inescq = TRUE; + continue; + } + + /* For metasequences that actually match a character, we disable the + setting of a first character if it hasn't already been set. */ + + if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z) + firstbyte = REQ_NONE; + + /* Set values to reset to if this is followed by a zero repeat. */ + + zerofirstbyte = firstbyte; + zeroreqbyte = reqbyte; + + /* Back references are handled specially */ + + if (-c >= ESC_REF) + { + int number = -c - ESC_REF; + previous = code; + *code++ = OP_REF; + PUT2INC(code, 0, number); + } + + /* So are Unicode property matches, if supported. We know that get_ucp + won't fail because it was tested in the pre-pass. */ + +#ifdef SUPPORT_UCP + else if (-c == ESC_P || -c == ESC_p) + { + BOOL negated; + int value = get_ucp(&ptr, &negated, errorptr); + previous = code; + *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP; + *code++ = value; + } +#endif + + /* For the rest, we can obtain the OP value by negating the escape + value */ + + else + { + previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; + *code++ = -c; + } + continue; + } + + /* We have a data character whose value is in c. In UTF-8 mode it may have + a value > 127. We set its representation in the length/buffer, and then + handle it as a data character. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && c > 127) + mclength = ord2utf8(c, mcbuffer); + else +#endif + + { + mcbuffer[0] = c; + mclength = 1; + } + + goto ONE_CHAR; + + /* Handle a literal character. It is guaranteed not to be whitespace or # + when the extended flag is set. If we are in UTF-8 mode, it may be a + multi-byte literal character. */ + + default: + NORMAL_CHAR: + mclength = 1; + mcbuffer[0] = c; + +#ifdef SUPPORT_UTF8 + if (utf8 && (c & 0xc0) == 0xc0) + { + while ((ptr[1] & 0xc0) == 0x80) + mcbuffer[mclength++] = *(++ptr); + } +#endif + + /* At this point we have the character's bytes in mcbuffer, and the length + in mclength. When not in UTF-8 mode, the length is always 1. */ + + ONE_CHAR: + previous = code; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR; + for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; + + /* Set the first and required bytes appropriately. If no previous first + byte, set it from this character, but revert to none on a zero repeat. + Otherwise, leave the firstbyte value alone, and don't change it on a zero + repeat. */ + + if (firstbyte == REQ_UNSET) + { + zerofirstbyte = REQ_NONE; + zeroreqbyte = reqbyte; + + /* If the character is more than one byte long, we can set firstbyte + only if it is not to be matched caselessly. */ + + if (mclength == 1 || req_caseopt == 0) + { + firstbyte = mcbuffer[0] | req_caseopt; + if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt; + } + else firstbyte = reqbyte = REQ_NONE; + } + + /* firstbyte was previously set; we can set reqbyte only the length is + 1 or the matching is caseful. */ + + else + { + zerofirstbyte = firstbyte; + zeroreqbyte = reqbyte; + if (mclength == 1 || req_caseopt == 0) + reqbyte = code[-1] | req_caseopt | cd->req_varyopt; + } + + break; /* End of literal character handling */ + } + } /* end of big loop */ + +/* Control never reaches here by falling through, only by a goto for all the +error states. Pass back the position in the pattern so that it can be displayed +to the user for diagnosing the error. */ + +FAILED: +*ptrptr = ptr; +return FALSE; +} + + + + +/************************************************* +* Compile sequence of alternatives * +*************************************************/ + +/* On entry, ptr is pointing past the bracket character, but on return +it points to the closing bracket, or vertical bar, or end of string. +The code variable is pointing at the byte into which the BRA operator has been +stored. If the ims options are changed at the start (for a (?ims: group) or +during any branch, we need to insert an OP_OPT item at the start of every +following branch to ensure they get set correctly at run time, and also pass +the new options into every subsequent branch compile. + +Argument: + options option bits, including any changes for this subpattern + oldims previous settings of ims option bits + brackets -> int containing the number of extracting brackets used + codeptr -> the address of the current code pointer + ptrptr -> the address of the current pattern pointer + errorptr -> pointer to error message + lookbehind TRUE if this is a lookbehind assertion + skipbytes skip this many bytes at start (for OP_COND, OP_BRANUMBER) + firstbyteptr place to put the first required character, or a negative number + reqbyteptr place to put the last required character, or a negative number + bcptr pointer to the chain of currently open branches + cd points to the data block with tables pointers etc. + +Returns: TRUE on success +*/ + +static BOOL +compile_regex(int options, int oldims, int *brackets, uschar **codeptr, + const uschar **ptrptr, const char **errorptr, BOOL lookbehind, int skipbytes, + int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd) +{ +const uschar *ptr = *ptrptr; +uschar *code = *codeptr; +uschar *last_branch = code; +uschar *start_bracket = code; +uschar *reverse_count = NULL; +int firstbyte, reqbyte; +int branchfirstbyte, branchreqbyte; +branch_chain bc; + +bc.outer = bcptr; +bc.current = code; + +firstbyte = reqbyte = REQ_UNSET; + +/* Offset is set zero to mark that this bracket is still open */ + +PUT(code, 1, 0); +code += 1 + LINK_SIZE + skipbytes; + +/* Loop for each alternative branch */ + +for (;;) + { + /* Handle a change of ims options at the start of the branch */ + + if ((options & PCRE_IMS) != oldims) + { + *code++ = OP_OPT; + *code++ = options & PCRE_IMS; + } + + /* Set up dummy OP_REVERSE if lookbehind assertion */ + + if (lookbehind) + { + *code++ = OP_REVERSE; + reverse_count = code; + PUTINC(code, 0, 0); + } + + /* Now compile the branch */ + + if (!compile_branch(&options, brackets, &code, &ptr, errorptr, + &branchfirstbyte, &branchreqbyte, &bc, cd)) + { + *ptrptr = ptr; + return FALSE; + } + + /* If this is the first branch, the firstbyte and reqbyte values for the + branch become the values for the regex. */ + + if (*last_branch != OP_ALT) + { + firstbyte = branchfirstbyte; + reqbyte = branchreqbyte; + } + + /* If this is not the first branch, the first char and reqbyte have to + match the values from all the previous branches, except that if the previous + value for reqbyte didn't have REQ_VARY set, it can still match, and we set + REQ_VARY for the regex. */ + + else + { + /* If we previously had a firstbyte, but it doesn't match the new branch, + we have to abandon the firstbyte for the regex, but if there was previously + no reqbyte, it takes on the value of the old firstbyte. */ + + if (firstbyte >= 0 && firstbyte != branchfirstbyte) + { + if (reqbyte < 0) reqbyte = firstbyte; + firstbyte = REQ_NONE; + } + + /* If we (now or from before) have no firstbyte, a firstbyte from the + branch becomes a reqbyte if there isn't a branch reqbyte. */ + + if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0) + branchreqbyte = branchfirstbyte; + + /* Now ensure that the reqbytes match */ + + if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY)) + reqbyte = REQ_NONE; + else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */ + } + + /* If lookbehind, check that this branch matches a fixed-length string, + and put the length into the OP_REVERSE item. Temporarily mark the end of + the branch with OP_END. */ + + if (lookbehind) + { + int length; + *code = OP_END; + length = find_fixedlength(last_branch, options); + DPRINTF(("fixed length = %d\n", length)); + if (length < 0) + { + *errorptr = (length == -2)? ERR36 : ERR25; + *ptrptr = ptr; + return FALSE; + } + PUT(reverse_count, 0, length); + } + + /* Reached end of expression, either ')' or end of pattern. Go back through + the alternative branches and reverse the chain of offsets, with the field in + the BRA item now becoming an offset to the first alternative. If there are + no alternatives, it points to the end of the group. The length in the + terminating ket is always the length of the whole bracketed item. If any of + the ims options were changed inside the group, compile a resetting op-code + following, except at the very end of the pattern. Return leaving the pointer + at the terminating char. */ + + if (*ptr != '|') + { + int length = code - last_branch; + do + { + int prev_length = GET(last_branch, 1); + PUT(last_branch, 1, length); + length = prev_length; + last_branch -= length; + } + while (length > 0); + + /* Fill in the ket */ + + *code = OP_KET; + PUT(code, 1, code - start_bracket); + code += 1 + LINK_SIZE; + + /* Resetting option if needed */ + + if ((options & PCRE_IMS) != oldims && *ptr == ')') + { + *code++ = OP_OPT; + *code++ = oldims; + } + + /* Set values to pass back */ + + *codeptr = code; + *ptrptr = ptr; + *firstbyteptr = firstbyte; + *reqbyteptr = reqbyte; + return TRUE; + } + + /* Another branch follows; insert an "or" node. Its length field points back + to the previous branch while the bracket remains open. At the end the chain + is reversed. It's done like this so that the start of the bracket has a + zero offset until it is closed, making it possible to detect recursion. */ + + *code = OP_ALT; + PUT(code, 1, code - last_branch); + bc.current = last_branch = code; + code += 1 + LINK_SIZE; + ptr++; + } +/* Control never reaches here */ +} + + + + +/************************************************* +* Check for anchored expression * +*************************************************/ + +/* Try to find out if this is an anchored regular expression. Consider each +alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket +all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then +it's anchored. However, if this is a multiline pattern, then only OP_SOD +counts, since OP_CIRC can match in the middle. + +We can also consider a regex to be anchored if OP_SOM starts all its branches. +This is the code for \G, which means "match at start of match position, taking +into account the match offset". + +A branch is also implicitly anchored if it starts with .* and DOTALL is set, +because that will try the rest of the pattern at all possible matching points, +so there is no point trying again.... er .... + +.... except when the .* appears inside capturing parentheses, and there is a +subsequent back reference to those parentheses. We haven't enough information +to catch that case precisely. + +At first, the best we could do was to detect when .* was in capturing brackets +and the highest back reference was greater than or equal to that level. +However, by keeping a bitmap of the first 31 back references, we can catch some +of the more common cases more precisely. + +Arguments: + code points to start of expression (the bracket) + options points to the options setting + bracket_map a bitmap of which brackets we are inside while testing; this + handles up to substring 31; after that we just have to take + the less precise approach + backref_map the back reference bitmap + +Returns: TRUE or FALSE +*/ + +static BOOL +is_anchored(register const uschar *code, int *options, unsigned int bracket_map, + unsigned int backref_map) +{ +do { + const uschar *scode = + first_significant_code(code + 1+LINK_SIZE, options, PCRE_MULTILINE, FALSE); + register int op = *scode; + + /* Capturing brackets */ + + if (op > OP_BRA) + { + int new_map; + op -= OP_BRA; + if (op > EXTRACT_BASIC_MAX) op = GET2(scode, 2+LINK_SIZE); + new_map = bracket_map | ((op < 32)? (1 << op) : 1); + if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; + } + + /* Other brackets */ + + else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND) + { + if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + } + + /* .* is not anchored unless DOTALL is set and it isn't in brackets that + are or may be referenced. */ + + else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR) && + (*options & PCRE_DOTALL) != 0) + { + if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; + } + + /* Check for explicit anchoring */ + + else if (op != OP_SOD && op != OP_SOM && + ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC)) + return FALSE; + code += GET(code, 1); + } +while (*code == OP_ALT); /* Loop for each alternative */ +return TRUE; +} + + + +/************************************************* +* Check for starting with ^ or .* * +*************************************************/ + +/* This is called to find out if every branch starts with ^ or .* so that +"first char" processing can be done to speed things up in multiline +matching and for non-DOTALL patterns that start with .* (which must start at +the beginning or after \n). As in the case of is_anchored() (see above), we +have to take account of back references to capturing brackets that contain .* +because in that case we can't make the assumption. + +Arguments: + code points to start of expression (the bracket) + bracket_map a bitmap of which brackets we are inside while testing; this + handles up to substring 31; after that we just have to take + the less precise approach + backref_map the back reference bitmap + +Returns: TRUE or FALSE +*/ + +static BOOL +is_startline(const uschar *code, unsigned int bracket_map, + unsigned int backref_map) +{ +do { + const uschar *scode = first_significant_code(code + 1+LINK_SIZE, NULL, 0, + FALSE); + register int op = *scode; + + /* Capturing brackets */ + + if (op > OP_BRA) + { + int new_map; + op -= OP_BRA; + if (op > EXTRACT_BASIC_MAX) op = GET2(scode, 2+LINK_SIZE); + new_map = bracket_map | ((op < 32)? (1 << op) : 1); + if (!is_startline(scode, new_map, backref_map)) return FALSE; + } + + /* Other brackets */ + + else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND) + { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } + + /* .* means "start at start or after \n" if it isn't in brackets that + may be referenced. */ + + else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR) + { + if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; + } + + /* Check for explicit circumflex */ + + else if (op != OP_CIRC) return FALSE; + + /* Move on to the next alternative */ + + code += GET(code, 1); + } +while (*code == OP_ALT); /* Loop for each alternative */ +return TRUE; +} + + + +/************************************************* +* Check for asserted fixed first char * +*************************************************/ + +/* During compilation, the "first char" settings from forward assertions are +discarded, because they can cause conflicts with actual literals that follow. +However, if we end up without a first char setting for an unanchored pattern, +it is worth scanning the regex to see if there is an initial asserted first +char. If all branches start with the same asserted char, or with a bracket all +of whose alternatives start with the same asserted char (recurse ad lib), then +we return that char, otherwise -1. + +Arguments: + code points to start of expression (the bracket) + options pointer to the options (used to check casing changes) + inassert TRUE if in an assertion + +Returns: -1 or the fixed first char +*/ + +static int +find_firstassertedchar(const uschar *code, int *options, BOOL inassert) +{ +register int c = -1; +do { + int d; + const uschar *scode = + first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE); + register int op = *scode; + + if (op >= OP_BRA) op = OP_BRA; + + switch(op) + { + default: + return -1; + + case OP_BRA: + case OP_ASSERT: + case OP_ONCE: + case OP_COND: + if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0) + return -1; + if (c < 0) c = d; else if (c != d) return -1; + break; + + case OP_EXACT: /* Fall through */ + scode += 2; + + case OP_CHAR: + case OP_CHARNC: + case OP_PLUS: + case OP_MINPLUS: + if (!inassert) return -1; + if (c < 0) + { + c = scode[1]; + if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS; + } + else if (c != scode[1]) return -1; + break; + } + + code += GET(code, 1); + } +while (*code == OP_ALT); +return c; +} + + + + +#ifdef SUPPORT_UTF8 +/************************************************* +* Validate a UTF-8 string * +*************************************************/ + +/* This function is called (optionally) at the start of compile or match, to +validate that a supposed UTF-8 string is actually valid. The early check means +that subsequent code can assume it is dealing with a valid string. The check +can be turned off for maximum performance, but then consequences of supplying +an invalid string are then undefined. + +Arguments: + string points to the string + length length of string, or -1 if the string is zero-terminated + +Returns: < 0 if the string is a valid UTF-8 string + >= 0 otherwise; the value is the offset of the bad byte +*/ + +static int +valid_utf8(const uschar *string, int length) +{ +register const uschar *p; + +if (length < 0) + { + for (p = string; *p != 0; p++); + length = p - string; + } + +for (p = string; length-- > 0; p++) + { + register int ab; + register int c = *p; + if (c < 128) continue; + if ((c & 0xc0) != 0xc0) return p - string; + ab = utf8_table4[c & 0x3f]; /* Number of additional bytes */ + if (length < ab) return p - string; + length -= ab; + + /* Check top bits in the second byte */ + if ((*(++p) & 0xc0) != 0x80) return p - string; + + /* Check for overlong sequences for each different length */ + switch (ab) + { + /* Check for xx00 000x */ + case 1: + if ((c & 0x3e) == 0) return p - string; + continue; /* We know there aren't any more bytes to check */ + + /* Check for 1110 0000, xx0x xxxx */ + case 2: + if (c == 0xe0 && (*p & 0x20) == 0) return p - string; + break; + + /* Check for 1111 0000, xx00 xxxx */ + case 3: + if (c == 0xf0 && (*p & 0x30) == 0) return p - string; + break; + + /* Check for 1111 1000, xx00 0xxx */ + case 4: + if (c == 0xf8 && (*p & 0x38) == 0) return p - string; + break; + + /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ + case 5: + if (c == 0xfe || c == 0xff || + (c == 0xfc && (*p & 0x3c) == 0)) return p - string; + break; + } + + /* Check for valid bytes after the 2nd, if any; all must start 10 */ + while (--ab > 0) + { + if ((*(++p) & 0xc0) != 0x80) return p - string; + } + } + +return -1; +} +#endif + + + +/************************************************* +* Compile a Regular Expression * +*************************************************/ + +/* This function takes a string and returns a pointer to a block of store +holding a compiled version of the expression. + +Arguments: + pattern the regular expression + options various option bits + errorptr pointer to pointer to error text + erroroffset ptr offset in pattern where error was detected + tables pointer to character tables or NULL + +Returns: pointer to compiled data block, or NULL on error, + with errorptr and erroroffset set +*/ + +EXPORT pcre * +pcre_compile(const char *pattern, int options, const char **errorptr, + int *erroroffset, const unsigned char *tables) +{ +real_pcre *re; +int length = 1 + LINK_SIZE; /* For initial BRA plus length */ +int c, firstbyte, reqbyte; +int bracount = 0; +int branch_extra = 0; +int branch_newextra; +int item_count = -1; +int name_count = 0; +int max_name_size = 0; +int lastitemlength = 0; +#ifdef SUPPORT_UTF8 +BOOL utf8; +BOOL class_utf8; +#endif +BOOL inescq = FALSE; +unsigned int brastackptr = 0; +size_t size; +uschar *code; +const uschar *codestart; +const uschar *ptr; +compile_data compile_block; +int brastack[BRASTACK_SIZE]; +uschar bralenstack[BRASTACK_SIZE]; + +/* We can't pass back an error message if errorptr is NULL; I guess the best we +can do is just return NULL. */ + +if (errorptr == NULL) return NULL; +*errorptr = NULL; + +/* However, we can give a message for this error */ + +if (erroroffset == NULL) + { + *errorptr = ERR16; + return NULL; + } +*erroroffset = 0; + +/* Can't support UTF8 unless PCRE has been compiled to include the code. */ + +#ifdef SUPPORT_UTF8 +utf8 = (options & PCRE_UTF8) != 0; +if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 && + (*erroroffset = valid_utf8((uschar *)pattern, -1)) >= 0) + { + *errorptr = ERR44; + return NULL; + } +#else +if ((options & PCRE_UTF8) != 0) + { + *errorptr = ERR32; + return NULL; + } +#endif + +if ((options & ~PUBLIC_OPTIONS) != 0) + { + *errorptr = ERR17; + return NULL; + } + +/* Set up pointers to the individual character tables */ + +if (tables == NULL) tables = pcre_default_tables; +compile_block.lcc = tables + lcc_offset; +compile_block.fcc = tables + fcc_offset; +compile_block.cbits = tables + cbits_offset; +compile_block.ctypes = tables + ctypes_offset; + +/* Maximum back reference and backref bitmap. This is updated for numeric +references during the first pass, but for named references during the actual +compile pass. The bitmap records up to 31 back references to help in deciding +whether (.*) can be treated as anchored or not. */ + +compile_block.top_backref = 0; +compile_block.backref_map = 0; + +/* Reflect pattern for debugging output */ + +DPRINTF(("------------------------------------------------------------------\n")); +DPRINTF(("%s\n", pattern)); + +/* The first thing to do is to make a pass over the pattern to compute the +amount of store required to hold the compiled code. This does not have to be +perfect as long as errors are overestimates. At the same time we can detect any +flag settings right at the start, and extract them. Make an attempt to correct +for any counted white space if an "extended" flag setting appears late in the +pattern. We can't be so clever for #-comments. */ + +ptr = (const uschar *)(pattern - 1); +while ((c = *(++ptr)) != 0) + { + int min, max; + int class_optcount; + int bracket_length; + int duplength; + + /* If we are inside a \Q...\E sequence, all chars are literal */ + + if (inescq) + { + if ((options & PCRE_AUTO_CALLOUT) != 0) length += 2 + 2*LINK_SIZE; + goto NORMAL_CHAR; + } + + /* Otherwise, first check for ignored whitespace and comments */ + + if ((options & PCRE_EXTENDED) != 0) + { + if ((compile_block.ctypes[c] & ctype_space) != 0) continue; + if (c == '#') + { + /* The space before the ; is to avoid a warning on a silly compiler + on the Macintosh. */ + while ((c = *(++ptr)) != 0 && c != NEWLINE) ; + if (c == 0) break; + continue; + } + } + + item_count++; /* Is zero for the first non-comment item */ + + /* Allow space for auto callout before every item except quantifiers. */ + + if ((options & PCRE_AUTO_CALLOUT) != 0 && + c != '*' && c != '+' && c != '?' && + (c != '{' || !is_counted_repeat(ptr + 1))) + length += 2 + 2*LINK_SIZE; + + switch(c) + { + /* A backslashed item may be an escaped data character or it may be a + character type. */ + + case '\\': + c = check_escape(&ptr, errorptr, bracount, options, FALSE); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + + lastitemlength = 1; /* Default length of last item for repeats */ + + if (c >= 0) /* Data character */ + { + length += 2; /* For a one-byte character */ + +#ifdef SUPPORT_UTF8 + if (utf8 && c > 127) + { + int i; + for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) + if (c <= utf8_table1[i]) break; + length += i; + lastitemlength += i; + } +#endif + + continue; + } + + /* If \Q, enter "literal" mode */ + + if (-c == ESC_Q) + { + inescq = TRUE; + continue; + } + + /* \X is supported only if Unicode property support is compiled */ + +#ifndef SUPPORT_UCP + if (-c == ESC_X) + { + *errorptr = ERR45; + goto PCRE_ERROR_RETURN; + } +#endif + + /* \P and \p are for Unicode properties, but only when the support has + been compiled. Each item needs 2 bytes. */ + + else if (-c == ESC_P || -c == ESC_p) + { +#ifdef SUPPORT_UCP + BOOL negated; + length += 2; + lastitemlength = 2; + if (get_ucp(&ptr, &negated, errorptr) < 0) goto PCRE_ERROR_RETURN; + continue; +#else + *errorptr = ERR45; + goto PCRE_ERROR_RETURN; +#endif + } + + /* Other escapes need one byte */ + + length++; + + /* A back reference needs an additional 2 bytes, plus either one or 5 + bytes for a repeat. We also need to keep the value of the highest + back reference. */ + + if (c <= -ESC_REF) + { + int refnum = -c - ESC_REF; + compile_block.backref_map |= (refnum < 32)? (1 << refnum) : 1; + if (refnum > compile_block.top_backref) + compile_block.top_backref = refnum; + length += 2; /* For single back reference */ + if (ptr[1] == '{' && is_counted_repeat(ptr+2)) + { + ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + if ((min == 0 && (max == 1 || max == -1)) || + (min == 1 && max == -1)) + length++; + else length += 5; + if (ptr[1] == '?') ptr++; + } + } + continue; + + case '^': /* Single-byte metacharacters */ + case '.': + case '$': + length++; + lastitemlength = 1; + continue; + + case '*': /* These repeats won't be after brackets; */ + case '+': /* those are handled separately */ + case '?': + length++; + goto POSESSIVE; /* A few lines below */ + + /* This covers the cases of braced repeats after a single char, metachar, + class, or back reference. */ + + case '{': + if (!is_counted_repeat(ptr+1)) goto NORMAL_CHAR; + ptr = read_repeat_counts(ptr+1, &min, &max, errorptr); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + + /* These special cases just insert one extra opcode */ + + if ((min == 0 && (max == 1 || max == -1)) || + (min == 1 && max == -1)) + length++; + + /* These cases might insert additional copies of a preceding character. */ + + else + { + if (min != 1) + { + length -= lastitemlength; /* Uncount the original char or metachar */ + if (min > 0) length += 3 + lastitemlength; + } + length += lastitemlength + ((max > 0)? 3 : 1); + } + + if (ptr[1] == '?') ptr++; /* Needs no extra length */ + + POSESSIVE: /* Test for possessive quantifier */ + if (ptr[1] == '+') + { + ptr++; + length += 2 + 2*LINK_SIZE; /* Allow for atomic brackets */ + } + continue; + + /* An alternation contains an offset to the next branch or ket. If any ims + options changed in the previous branch(es), and/or if we are in a + lookbehind assertion, extra space will be needed at the start of the + branch. This is handled by branch_extra. */ + + case '|': + length += 1 + LINK_SIZE + branch_extra; + continue; + + /* A character class uses 33 characters provided that all the character + values are less than 256. Otherwise, it uses a bit map for low valued + characters, and individual items for others. Don't worry about character + types that aren't allowed in classes - they'll get picked up during the + compile. A character class that contains only one single-byte character + uses 2 or 3 bytes, depending on whether it is negated or not. Notice this + where we can. (In UTF-8 mode we can do this only for chars < 128.) */ + + case '[': + if (*(++ptr) == '^') + { + class_optcount = 10; /* Greater than one */ + ptr++; + } + else class_optcount = 0; + +#ifdef SUPPORT_UTF8 + class_utf8 = FALSE; +#endif + + /* Written as a "do" so that an initial ']' is taken as data */ + + if (*ptr != 0) do + { + /* Inside \Q...\E everything is literal except \E */ + + if (inescq) + { + if (*ptr != '\\' || ptr[1] != 'E') goto GET_ONE_CHARACTER; + inescq = FALSE; + ptr += 1; + continue; + } + + /* Outside \Q...\E, check for escapes */ + + if (*ptr == '\\') + { + c = check_escape(&ptr, errorptr, bracount, options, TRUE); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + + /* \b is backspace inside a class; \X is literal */ + + if (-c == ESC_b) c = '\b'; + else if (-c == ESC_X) c = 'X'; + + /* \Q enters quoting mode */ + + else if (-c == ESC_Q) + { + inescq = TRUE; + continue; + } + + /* Handle escapes that turn into characters */ + + if (c >= 0) goto NON_SPECIAL_CHARACTER; + + /* Escapes that are meta-things. The normal ones just affect the + bit map, but Unicode properties require an XCLASS extended item. */ + + else + { + class_optcount = 10; /* \d, \s etc; make sure > 1 */ +#ifdef SUPPORT_UTF8 + if (-c == ESC_p || -c == ESC_P) + { + if (!class_utf8) + { + class_utf8 = TRUE; + length += LINK_SIZE + 2; + } + length += 2; + } +#endif + } + } + + /* Check the syntax for POSIX stuff. The bits we actually handle are + checked during the real compile phase. */ + + else if (*ptr == '[' && check_posix_syntax(ptr, &ptr, &compile_block)) + { + ptr++; + class_optcount = 10; /* Make sure > 1 */ + } + + /* Anything else increments the possible optimization count. We have to + detect ranges here so that we can compute the number of extra ranges for + caseless wide characters when UCP support is available. If there are wide + characters, we are going to have to use an XCLASS, even for single + characters. */ + + else + { + int d; + + GET_ONE_CHARACTER: + +#ifdef SUPPORT_UTF8 + if (utf8) + { + int extra = 0; + GETCHARLEN(c, ptr, extra); + ptr += extra; + } + else c = *ptr; +#else + c = *ptr; +#endif + + /* Come here from handling \ above when it escapes to a char value */ + + NON_SPECIAL_CHARACTER: + class_optcount++; + + d = -1; + if (ptr[1] == '-') + { + uschar const *hyptr = ptr++; + if (ptr[1] == '\\') + { + ptr++; + d = check_escape(&ptr, errorptr, bracount, options, TRUE); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + if (-d == ESC_b) d = '\b'; /* backspace */ + else if (-d == ESC_X) d = 'X'; /* literal X in a class */ + } + else if (ptr[1] != 0 && ptr[1] != ']') + { + ptr++; +#ifdef SUPPORT_UTF8 + if (utf8) + { + int extra = 0; + GETCHARLEN(d, ptr, extra); + ptr += extra; + } + else +#endif + d = *ptr; + } + if (d < 0) ptr = hyptr; /* go back to hyphen as data */ + } + + /* If d >= 0 we have a range. In UTF-8 mode, if the end is > 255, or > + 127 for caseless matching, we will need to use an XCLASS. */ + + if (d >= 0) + { + class_optcount = 10; /* Ensure > 1 */ + if (d < c) + { + *errorptr = ERR8; + goto PCRE_ERROR_RETURN; + } + +#ifdef SUPPORT_UTF8 + if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) + { + uschar buffer[6]; + if (!class_utf8) /* Allow for XCLASS overhead */ + { + class_utf8 = TRUE; + length += LINK_SIZE + 2; + } + +#ifdef SUPPORT_UCP + /* If we have UCP support, find out how many extra ranges are + needed to map the other case of characters within this range. We + have to mimic the range optimization here, because extending the + range upwards might push d over a boundary that makes is use + another byte in the UTF-8 representation. */ + + if ((options & PCRE_CASELESS) != 0) + { + int occ, ocd; + int cc = c; + int origd = d; + while (get_othercase_range(&cc, origd, &occ, &ocd)) + { + if (occ >= c && ocd <= d) continue; /* Skip embedded */ + + if (occ < c && ocd >= c - 1) /* Extend the basic range */ + { /* if there is overlap, */ + c = occ; /* noting that if occ < c */ + continue; /* we can't have ocd > d */ + } /* because a subrange is */ + if (ocd > d && occ <= d + 1) /* always shorter than */ + { /* the basic range. */ + d = ocd; + continue; + } + + /* An extra item is needed */ + + length += 1 + ord2utf8(occ, buffer) + + ((occ == ocd)? 0 : ord2utf8(ocd, buffer)); + } + } +#endif /* SUPPORT_UCP */ + + /* The length of the (possibly extended) range */ + + length += 1 + ord2utf8(c, buffer) + ord2utf8(d, buffer); + } +#endif /* SUPPORT_UTF8 */ + + } + + /* We have a single character. There is nothing to be done unless we + are in UTF-8 mode. If the char is > 255, or 127 when caseless, we must + allow for an XCL_SINGLE item, doubled for caselessness if there is UCP + support. */ + + else + { +#ifdef SUPPORT_UTF8 + if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) + { + uschar buffer[6]; + class_optcount = 10; /* Ensure > 1 */ + if (!class_utf8) /* Allow for XCLASS overhead */ + { + class_utf8 = TRUE; + length += LINK_SIZE + 2; + } +#ifdef SUPPORT_UCP + length += (((options & PCRE_CASELESS) != 0)? 2 : 1) * + (1 + ord2utf8(c, buffer)); +#else /* SUPPORT_UCP */ + length += 1 + ord2utf8(c, buffer); +#endif /* SUPPORT_UCP */ + } +#endif /* SUPPORT_UTF8 */ + } + } + } + while (*(++ptr) != 0 && (inescq || *ptr != ']')); /* Concludes "do" above */ + + if (*ptr == 0) /* Missing terminating ']' */ + { + *errorptr = ERR6; + goto PCRE_ERROR_RETURN; + } + + /* We can optimize when there was only one optimizable character. Repeats + for positive and negated single one-byte chars are handled by the general + code. Here, we handle repeats for the class opcodes. */ + + if (class_optcount == 1) length += 3; else + { + length += 33; + + /* A repeat needs either 1 or 5 bytes. If it is a possessive quantifier, + we also need extra for wrapping the whole thing in a sub-pattern. */ + + if (*ptr != 0 && ptr[1] == '{' && is_counted_repeat(ptr+2)) + { + ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + if ((min == 0 && (max == 1 || max == -1)) || + (min == 1 && max == -1)) + length++; + else length += 5; + if (ptr[1] == '+') + { + ptr++; + length += 2 + 2*LINK_SIZE; + } + else if (ptr[1] == '?') ptr++; + } + } + continue; + + /* Brackets may be genuine groups or special things */ + + case '(': + branch_newextra = 0; + bracket_length = 1 + LINK_SIZE; + + /* Handle special forms of bracket, which all start (? */ + + if (ptr[1] == '?') + { + int set, unset; + int *optset; + + switch (c = ptr[2]) + { + /* Skip over comments entirely */ + case '#': + ptr += 3; + while (*ptr != 0 && *ptr != ')') ptr++; + if (*ptr == 0) + { + *errorptr = ERR18; + goto PCRE_ERROR_RETURN; + } + continue; + + /* Non-referencing groups and lookaheads just move the pointer on, and + then behave like a non-special bracket, except that they don't increment + the count of extracting brackets. Ditto for the "once only" bracket, + which is in Perl from version 5.005. */ + + case ':': + case '=': + case '!': + case '>': + ptr += 2; + break; + + /* (?R) specifies a recursive call to the regex, which is an extension + to provide the facility which can be obtained by (?p{perl-code}) in + Perl 5.6. In Perl 5.8 this has become (??{perl-code}). + + From PCRE 4.00, items such as (?3) specify subroutine-like "calls" to + the appropriate numbered brackets. This includes both recursive and + non-recursive calls. (?R) is now synonymous with (?0). */ + + case 'R': + ptr++; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + ptr += 2; + if (c != 'R') + while ((digitab[*(++ptr)] & ctype_digit) != 0); + if (*ptr != ')') + { + *errorptr = ERR29; + goto PCRE_ERROR_RETURN; + } + length += 1 + LINK_SIZE; + + /* If this item is quantified, it will get wrapped inside brackets so + as to use the code for quantified brackets. We jump down and use the + code that handles this for real brackets. */ + + if (ptr[1] == '+' || ptr[1] == '*' || ptr[1] == '?' || ptr[1] == '{') + { + length += 2 + 2 * LINK_SIZE; /* to make bracketed */ + duplength = 5 + 3 * LINK_SIZE; + goto HANDLE_QUANTIFIED_BRACKETS; + } + continue; + + /* (?C) is an extension which provides "callout" - to provide a bit of + the functionality of the Perl (?{...}) feature. An optional number may + follow (default is zero). */ + + case 'C': + ptr += 2; + while ((digitab[*(++ptr)] & ctype_digit) != 0); + if (*ptr != ')') + { + *errorptr = ERR39; + goto PCRE_ERROR_RETURN; + } + length += 2 + 2*LINK_SIZE; + continue; + + /* Named subpatterns are an extension copied from Python */ + + case 'P': + ptr += 3; + if (*ptr == '<') + { + const uschar *p; /* Don't amalgamate; some compilers */ + p = ++ptr; /* grumble at autoincrement in declaration */ + while ((compile_block.ctypes[*ptr] & ctype_word) != 0) ptr++; + if (*ptr != '>') + { + *errorptr = ERR42; + goto PCRE_ERROR_RETURN; + } + name_count++; + if (ptr - p > max_name_size) max_name_size = (ptr - p); + break; + } + + if (*ptr == '=' || *ptr == '>') + { + while ((compile_block.ctypes[*(++ptr)] & ctype_word) != 0); + if (*ptr != ')') + { + *errorptr = ERR42; + goto PCRE_ERROR_RETURN; + } + break; + } + + /* Unknown character after (?P */ + + *errorptr = ERR41; + goto PCRE_ERROR_RETURN; + + /* Lookbehinds are in Perl from version 5.005 */ + + case '<': + ptr += 3; + if (*ptr == '=' || *ptr == '!') + { + branch_newextra = 1 + LINK_SIZE; + length += 1 + LINK_SIZE; /* For the first branch */ + break; + } + *errorptr = ERR24; + goto PCRE_ERROR_RETURN; + + /* Conditionals are in Perl from version 5.005. The bracket must either + be followed by a number (for bracket reference) or by an assertion + group, or (a PCRE extension) by 'R' for a recursion test. */ + + case '(': + if (ptr[3] == 'R' && ptr[4] == ')') + { + ptr += 4; + length += 3; + } + else if ((digitab[ptr[3]] & ctype_digit) != 0) + { + ptr += 4; + length += 3; + while ((digitab[*ptr] & ctype_digit) != 0) ptr++; + if (*ptr != ')') + { + *errorptr = ERR26; + goto PCRE_ERROR_RETURN; + } + } + else /* An assertion must follow */ + { + ptr++; /* Can treat like ':' as far as spacing is concerned */ + if (ptr[2] != '?' || + (ptr[3] != '=' && ptr[3] != '!' && ptr[3] != '<') ) + { + ptr += 2; /* To get right offset in message */ + *errorptr = ERR28; + goto PCRE_ERROR_RETURN; + } + } + break; + + /* Else loop checking valid options until ) is met. Anything else is an + error. If we are without any brackets, i.e. at top level, the settings + act as if specified in the options, so massage the options immediately. + This is for backward compatibility with Perl 5.004. */ + + default: + set = unset = 0; + optset = &set; + ptr += 2; + + for (;; ptr++) + { + c = *ptr; + switch (c) + { + case 'i': + *optset |= PCRE_CASELESS; + continue; + + case 'm': + *optset |= PCRE_MULTILINE; + continue; + + case 's': + *optset |= PCRE_DOTALL; + continue; + + case 'x': + *optset |= PCRE_EXTENDED; + continue; + + case 'X': + *optset |= PCRE_EXTRA; + continue; + + case 'U': + *optset |= PCRE_UNGREEDY; + continue; + + case '-': + optset = &unset; + continue; + + /* A termination by ')' indicates an options-setting-only item; if + this is at the very start of the pattern (indicated by item_count + being zero), we use it to set the global options. This is helpful + when analyzing the pattern for first characters, etc. Otherwise + nothing is done here and it is handled during the compiling + process. + + [Historical note: Up to Perl 5.8, options settings at top level + were always global settings, wherever they appeared in the pattern. + That is, they were equivalent to an external setting. From 5.8 + onwards, they apply only to what follows (which is what you might + expect).] */ + + case ')': + if (item_count == 0) + { + options = (options | set) & (~unset); + set = unset = 0; /* To save length */ + item_count--; /* To allow for several */ + } + + /* Fall through */ + + /* A termination by ':' indicates the start of a nested group with + the given options set. This is again handled at compile time, but + we must allow for compiled space if any of the ims options are + set. We also have to allow for resetting space at the end of + the group, which is why 4 is added to the length and not just 2. + If there are several changes of options within the same group, this + will lead to an over-estimate on the length, but this shouldn't + matter very much. We also have to allow for resetting options at + the start of any alternations, which we do by setting + branch_newextra to 2. Finally, we record whether the case-dependent + flag ever changes within the regex. This is used by the "required + character" code. */ + + case ':': + if (((set|unset) & PCRE_IMS) != 0) + { + length += 4; + branch_newextra = 2; + if (((set|unset) & PCRE_CASELESS) != 0) options |= PCRE_ICHANGED; + } + goto END_OPTIONS; + + /* Unrecognized option character */ + + default: + *errorptr = ERR12; + goto PCRE_ERROR_RETURN; + } + } + + /* If we hit a closing bracket, that's it - this is a freestanding + option-setting. We need to ensure that branch_extra is updated if + necessary. The only values branch_newextra can have here are 0 or 2. + If the value is 2, then branch_extra must either be 2 or 5, depending + on whether this is a lookbehind group or not. */ + + END_OPTIONS: + if (c == ')') + { + if (branch_newextra == 2 && + (branch_extra == 0 || branch_extra == 1+LINK_SIZE)) + branch_extra += branch_newextra; + continue; + } + + /* If options were terminated by ':' control comes here. Fall through + to handle the group below. */ + } + } + + /* Extracting brackets must be counted so we can process escapes in a + Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to + need an additional 3 bytes of store per extracting bracket. However, if + PCRE_NO_AUTO)CAPTURE is set, unadorned brackets become non-capturing, so we + must leave the count alone (it will aways be zero). */ + + else if ((options & PCRE_NO_AUTO_CAPTURE) == 0) + { + bracount++; + if (bracount > EXTRACT_BASIC_MAX) bracket_length += 3; + } + + /* Save length for computing whole length at end if there's a repeat that + requires duplication of the group. Also save the current value of + branch_extra, and start the new group with the new value. If non-zero, this + will either be 2 for a (?imsx: group, or 3 for a lookbehind assertion. */ + + if (brastackptr >= sizeof(brastack)/sizeof(int)) + { + *errorptr = ERR19; + goto PCRE_ERROR_RETURN; + } + + bralenstack[brastackptr] = branch_extra; + branch_extra = branch_newextra; + + brastack[brastackptr++] = length; + length += bracket_length; + continue; + + /* Handle ket. Look for subsequent max/min; for certain sets of values we + have to replicate this bracket up to that many times. If brastackptr is + 0 this is an unmatched bracket which will generate an error, but take care + not to try to access brastack[-1] when computing the length and restoring + the branch_extra value. */ + + case ')': + length += 1 + LINK_SIZE; + if (brastackptr > 0) + { + duplength = length - brastack[--brastackptr]; + branch_extra = bralenstack[brastackptr]; + } + else duplength = 0; + + /* The following code is also used when a recursion such as (?3) is + followed by a quantifier, because in that case, it has to be wrapped inside + brackets so that the quantifier works. The value of duplength must be + set before arrival. */ + + HANDLE_QUANTIFIED_BRACKETS: + + /* Leave ptr at the final char; for read_repeat_counts this happens + automatically; for the others we need an increment. */ + + if ((c = ptr[1]) == '{' && is_counted_repeat(ptr+2)) + { + ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); + if (*errorptr != NULL) goto PCRE_ERROR_RETURN; + } + else if (c == '*') { min = 0; max = -1; ptr++; } + else if (c == '+') { min = 1; max = -1; ptr++; } + else if (c == '?') { min = 0; max = 1; ptr++; } + else { min = 1; max = 1; } + + /* If the minimum is zero, we have to allow for an OP_BRAZERO before the + group, and if the maximum is greater than zero, we have to replicate + maxval-1 times; each replication acquires an OP_BRAZERO plus a nesting + bracket set. */ + + if (min == 0) + { + length++; + if (max > 0) length += (max - 1) * (duplength + 3 + 2*LINK_SIZE); + } + + /* When the minimum is greater than zero, we have to replicate up to + minval-1 times, with no additions required in the copies. Then, if there + is a limited maximum we have to replicate up to maxval-1 times allowing + for a BRAZERO item before each optional copy and nesting brackets for all + but one of the optional copies. */ + + else + { + length += (min - 1) * duplength; + if (max > min) /* Need this test as max=-1 means no limit */ + length += (max - min) * (duplength + 3 + 2*LINK_SIZE) + - (2 + 2*LINK_SIZE); + } + + /* Allow space for once brackets for "possessive quantifier" */ + + if (ptr[1] == '+') + { + ptr++; + length += 2 + 2*LINK_SIZE; + } + continue; + + /* Non-special character. It won't be space or # in extended mode, so it is + always a genuine character. If we are in a \Q...\E sequence, check for the + end; if not, we have a literal. */ + + default: + NORMAL_CHAR: + + if (inescq && c == '\\' && ptr[1] == 'E') + { + inescq = FALSE; + ptr++; + continue; + } + + length += 2; /* For a one-byte character */ + lastitemlength = 1; /* Default length of last item for repeats */ + + /* In UTF-8 mode, check for additional bytes. */ + +#ifdef SUPPORT_UTF8 + if (utf8 && (c & 0xc0) == 0xc0) + { + while ((ptr[1] & 0xc0) == 0x80) /* Can't flow over the end */ + { /* because the end is marked */ + lastitemlength++; /* by a zero byte. */ + length++; + ptr++; + } + } +#endif + + continue; + } + } + +length += 2 + LINK_SIZE; /* For final KET and END */ + +if ((options & PCRE_AUTO_CALLOUT) != 0) + length += 2 + 2*LINK_SIZE; /* For final callout */ + +if (length > MAX_PATTERN_SIZE) + { + *errorptr = ERR20; + return NULL; + } + +/* Compute the size of data block needed and get it, either from malloc or +externally provided function. */ + +size = length + sizeof(real_pcre) + name_count * (max_name_size + 3); +re = (real_pcre *)(pcre_malloc)(size); + +if (re == NULL) + { + *errorptr = ERR21; + return NULL; + } + +/* Put in the magic number, and save the sizes, options, and character table +pointer. NULL is used for the default character tables. The nullpad field is at +the end; it's there to help in the case when a regex compiled on a system with +4-byte pointers is run on another with 8-byte pointers. */ + +re->magic_number = MAGIC_NUMBER; +re->size = size; +re->options = options; +re->dummy1 = re->dummy2 = 0; +re->name_table_offset = sizeof(real_pcre); +re->name_entry_size = max_name_size + 3; +re->name_count = name_count; +re->tables = (tables == pcre_default_tables)? NULL : tables; +re->nullpad = NULL; + +/* The starting points of the name/number translation table and of the code are +passed around in the compile data block. */ + +compile_block.names_found = 0; +compile_block.name_entry_size = max_name_size + 3; +compile_block.name_table = (uschar *)re + re->name_table_offset; +codestart = compile_block.name_table + re->name_entry_size * re->name_count; +compile_block.start_code = codestart; +compile_block.start_pattern = (const uschar *)pattern; +compile_block.req_varyopt = 0; +compile_block.nopartial = FALSE; + +/* Set up a starting, non-extracting bracket, then compile the expression. On +error, *errorptr will be set non-NULL, so we don't need to look at the result +of the function here. */ + +ptr = (const uschar *)pattern; +code = (uschar *)codestart; +*code = OP_BRA; +bracount = 0; +(void)compile_regex(options, options & PCRE_IMS, &bracount, &code, &ptr, + errorptr, FALSE, 0, &firstbyte, &reqbyte, NULL, &compile_block); +re->top_bracket = bracount; +re->top_backref = compile_block.top_backref; + +if (compile_block.nopartial) re->options |= PCRE_NOPARTIAL; + +/* If not reached end of pattern on success, there's an excess bracket. */ + +if (*errorptr == NULL && *ptr != 0) *errorptr = ERR22; + +/* Fill in the terminating state and check for disastrous overflow, but +if debugging, leave the test till after things are printed out. */ + +*code++ = OP_END; + +#ifndef DEBUG +if (code - codestart > length) *errorptr = ERR23; +#endif + +/* Give an error if there's back reference to a non-existent capturing +subpattern. */ + +if (re->top_backref > re->top_bracket) *errorptr = ERR15; + +/* Failed to compile, or error while post-processing */ + +if (*errorptr != NULL) + { + (pcre_free)(re); + PCRE_ERROR_RETURN: + *erroroffset = ptr - (const uschar *)pattern; + return NULL; + } + +/* If the anchored option was not passed, set the flag if we can determine that +the pattern is anchored by virtue of ^ characters or \A or anything else (such +as starting with .* when DOTALL is set). + +Otherwise, if we know what the first character has to be, save it, because that +speeds up unanchored matches no end. If not, see if we can set the +PCRE_STARTLINE flag. This is helpful for multiline matches when all branches +start with ^. and also when all branches start with .* for non-DOTALL matches. +*/ + +if ((options & PCRE_ANCHORED) == 0) + { + int temp_options = options; + if (is_anchored(codestart, &temp_options, 0, compile_block.backref_map)) + re->options |= PCRE_ANCHORED; + else + { + if (firstbyte < 0) + firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE); + if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ + { + int ch = firstbyte & 255; + re->first_byte = ((firstbyte & REQ_CASELESS) != 0 && + compile_block.fcc[ch] == ch)? ch : firstbyte; + re->options |= PCRE_FIRSTSET; + } + else if (is_startline(codestart, 0, compile_block.backref_map)) + re->options |= PCRE_STARTLINE; + } + } + +/* For an anchored pattern, we use the "required byte" only if it follows a +variable length item in the regex. Remove the caseless flag for non-caseable +bytes. */ + +if (reqbyte >= 0 && + ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0)) + { + int ch = reqbyte & 255; + re->req_byte = ((reqbyte & REQ_CASELESS) != 0 && + compile_block.fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte; + re->options |= PCRE_REQCHSET; + } + +/* Print out the compiled data for debugging */ + +#ifdef DEBUG + +printf("Length = %d top_bracket = %d top_backref = %d\n", + length, re->top_bracket, re->top_backref); + +if (re->options != 0) + { + printf("%s%s%s%s%s%s%s%s%s%s\n", + ((re->options & PCRE_NOPARTIAL) != 0)? "nopartial " : "", + ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "", + ((re->options & PCRE_CASELESS) != 0)? "caseless " : "", + ((re->options & PCRE_ICHANGED) != 0)? "case state changed " : "", + ((re->options & PCRE_EXTENDED) != 0)? "extended " : "", + ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "", + ((re->options & PCRE_DOTALL) != 0)? "dotall " : "", + ((re->options & PCRE_DOLLAR_ENDONLY) != 0)? "endonly " : "", + ((re->options & PCRE_EXTRA) != 0)? "extra " : "", + ((re->options & PCRE_UNGREEDY) != 0)? "ungreedy " : ""); + } + +if ((re->options & PCRE_FIRSTSET) != 0) + { + int ch = re->first_byte & 255; + const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; + if (isprint(ch)) printf("First char = %c%s\n", ch, caseless); + else printf("First char = \\x%02x%s\n", ch, caseless); + } + +if ((re->options & PCRE_REQCHSET) != 0) + { + int ch = re->req_byte & 255; + const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; + if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless); + else printf("Req char = \\x%02x%s\n", ch, caseless); + } + +print_internals(re, stdout); + +/* This check is done here in the debugging case so that the code that +was compiled can be seen. */ + +if (code - codestart > length) + { + *errorptr = ERR23; + (pcre_free)(re); + *erroroffset = ptr - (uschar *)pattern; + return NULL; + } +#endif + +return (pcre *)re; +} + + + +/************************************************* +* Match a back-reference * +*************************************************/ + +/* If a back reference hasn't been set, the length that is passed is greater +than the number of characters left in the string, so the match fails. + +Arguments: + offset index into the offset vector + eptr points into the subject + length length to be matched + md points to match data block + ims the ims flags + +Returns: TRUE if matched +*/ + +static BOOL +match_ref(int offset, register const uschar *eptr, int length, match_data *md, + unsigned long int ims) +{ +const uschar *p = md->start_subject + md->offset_vector[offset]; + +#ifdef DEBUG +if (eptr >= md->end_subject) + printf("matching subject "); +else + { + printf("matching subject "); + pchars(eptr, length, TRUE, md); + } +printf(" against backref "); +pchars(p, length, FALSE, md); +printf("\n"); +#endif + +/* Always fail if not enough characters left */ + +if (length > md->end_subject - eptr) return FALSE; + +/* Separate the caselesss case for speed */ + +if ((ims & PCRE_CASELESS) != 0) + { + while (length-- > 0) + if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; + } +else + { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } + +return TRUE; +} + + +#ifdef SUPPORT_UTF8 +/************************************************* +* Match character against an XCLASS * +*************************************************/ + +/* This function is called from within the XCLASS code below, to match a +character against an extended class which might match values > 255. + +Arguments: + c the character + data points to the flag byte of the XCLASS data + +Returns: TRUE if character matches, else FALSE +*/ + +static BOOL +match_xclass(int c, const uschar *data) +{ +int t; +BOOL negated = (*data & XCL_NOT) != 0; + +/* Character values < 256 are matched against a bitmap, if one is present. If +not, we still carry on, because there may be ranges that start below 256 in the +additional data. */ + +if (c < 256) + { + if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0) + return !negated; /* char found */ + } + +/* First skip the bit map if present. Then match against the list of Unicode +properties or large chars or ranges that end with a large char. We won't ever +encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ + +if ((*data++ & XCL_MAP) != 0) data += 32; + +while ((t = *data++) != XCL_END) + { + int x, y; + if (t == XCL_SINGLE) + { + GETCHARINC(x, data); + if (c == x) return !negated; + } + else if (t == XCL_RANGE) + { + GETCHARINC(x, data); + GETCHARINC(y, data); + if (c >= x && c <= y) return !negated; + } + +#ifdef SUPPORT_UCP + else /* XCL_PROP & XCL_NOTPROP */ + { + int chartype, othercase; + int rqdtype = *data++; + int category = ucp_findchar(c, &chartype, &othercase); + if (rqdtype >= 128) + { + if ((rqdtype - 128 == category) == (t == XCL_PROP)) return !negated; + } + else + { + if ((rqdtype == chartype) == (t == XCL_PROP)) return !negated; + } + } +#endif /* SUPPORT_UCP */ + } + +return negated; /* char did not match */ +} +#endif + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +The match() function is highly recursive. Some regular expressions can cause +it to recurse thousands of times. I was writing for Unix, so I just let it +call itself recursively. This uses the stack for saving everything that has +to be saved for a recursive call. On Unix, the stack can be large, and this +works fine. + +It turns out that on non-Unix systems there are problems with programs that +use a lot of stack. (This despite the fact that every last chip has oodles +of memory these days, and techniques for extending the stack have been known +for decades.) So.... + +There is a fudge, triggered by defining NO_RECURSE, which avoids recursive +calls by keeping local variables that need to be preserved in blocks of memory +obtained from malloc instead instead of on the stack. Macros are used to +achieve this so that the actual code doesn't look very different to what it +always used to. +**************************************************************************** +***************************************************************************/ + + +/* These versions of the macros use the stack, as normal */ + +#ifndef NO_RECURSE +#define REGISTER register +#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) rx = match(ra,rb,rc,rd,re,rf,rg) +#define RRETURN(ra) return ra +#else + + +/* These versions of the macros manage a private stack on the heap. Note +that the rd argument of RMATCH isn't actually used. It's the md argument of +match(), which never changes. */ + +#define REGISTER + +#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\ + {\ + heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\ + if (setjmp(frame->Xwhere) == 0)\ + {\ + newframe->Xeptr = ra;\ + newframe->Xecode = rb;\ + newframe->Xoffset_top = rc;\ + newframe->Xims = re;\ + newframe->Xeptrb = rf;\ + newframe->Xflags = rg;\ + newframe->Xprevframe = frame;\ + frame = newframe;\ + DPRINTF(("restarting from line %d\n", __LINE__));\ + goto HEAP_RECURSE;\ + }\ + else\ + {\ + DPRINTF(("longjumped back to line %d\n", __LINE__));\ + frame = md->thisframe;\ + rx = frame->Xresult;\ + }\ + } + +#define RRETURN(ra)\ + {\ + heapframe *newframe = frame;\ + frame = newframe->Xprevframe;\ + (pcre_stack_free)(newframe);\ + if (frame != NULL)\ + {\ + frame->Xresult = ra;\ + md->thisframe = frame;\ + longjmp(frame->Xwhere, 1);\ + }\ + return ra;\ + } + + +/* Structure for remembering the local variables in a private frame */ + +typedef struct heapframe { + struct heapframe *Xprevframe; + + /* Function arguments that may change */ + + const uschar *Xeptr; + const uschar *Xecode; + int Xoffset_top; + long int Xims; + eptrblock *Xeptrb; + int Xflags; + + /* Function local variables */ + + const uschar *Xcallpat; + const uschar *Xcharptr; + const uschar *Xdata; + const uschar *Xnext; + const uschar *Xpp; + const uschar *Xprev; + const uschar *Xsaved_eptr; + + recursion_info Xnew_recursive; + + BOOL Xcur_is_word; + BOOL Xcondition; + BOOL Xminimize; + BOOL Xprev_is_word; + + unsigned long int Xoriginal_ims; + +#ifdef SUPPORT_UCP + int Xprop_type; + int Xprop_fail_result; + int Xprop_category; + int Xprop_chartype; + int Xprop_othercase; + int Xprop_test_against; + int *Xprop_test_variable; +#endif + + int Xctype; + int Xfc; + int Xfi; + int Xlength; + int Xmax; + int Xmin; + int Xnumber; + int Xoffset; + int Xop; + int Xsave_capture_last; + int Xsave_offset1, Xsave_offset2, Xsave_offset3; + int Xstacksave[REC_STACK_SAVE_MAX]; + + eptrblock Xnewptrb; + + /* Place to pass back result, and where to jump back to */ + + int Xresult; + jmp_buf Xwhere; + +} heapframe; + +#endif + + +/*************************************************************************** +***************************************************************************/ + + + +/************************************************* +* Match from current position * +*************************************************/ + +/* On entry ecode points to the first opcode, and eptr to the first character +in the subject string, while eptrb holds the value of eptr at the start of the +last bracketed group - used for breaking infinite loops matching zero-length +strings. This function is called recursively in many circumstances. Whenever it +returns a negative (error) response, the outer incarnation must also return the +same response. + +Performance note: It might be tempting to extract commonly used fields from the +md structure (e.g. utf8, end_subject) into individual variables to improve +performance. Tests using gcc on a SPARC disproved this; in the first case, it +made performance worse. + +Arguments: + eptr pointer in subject + ecode position in code + offset_top current top pointer + md pointer to "static" info for the match + ims current /i, /m, and /s options + eptrb pointer to chain of blocks containing eptr at start of + brackets - for testing for empty matches + flags can contain + match_condassert - this is an assertion condition + match_isgroup - this is the start of a bracketed group + +Returns: MATCH_MATCH if matched ) these values are >= 0 + MATCH_NOMATCH if failed to match ) + a negative PCRE_ERROR_xxx value if aborted by an error condition + (e.g. stopped by recursion limit) +*/ + +static int +match(REGISTER const uschar *eptr, REGISTER const uschar *ecode, + int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, + int flags) +{ +/* These variables do not need to be preserved over recursion in this function, +so they can be ordinary variables in all cases. Mark them with "register" +because they are used a lot in loops. */ + +register int rrc; /* Returns from recursive calls */ +register int i; /* Used for loops not involving calls to RMATCH() */ +register int c; /* Character values not kept over RMATCH() calls */ + +/* When recursion is not being used, all "local" variables that have to be +preserved over calls to RMATCH() are part of a "frame" which is obtained from +heap storage. Set up the top-level frame here; others are obtained from the +heap whenever RMATCH() does a "recursion". See the macro definitions above. */ + +#ifdef NO_RECURSE +heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe)); +frame->Xprevframe = NULL; /* Marks the top level */ + +/* Copy in the original argument variables */ + +frame->Xeptr = eptr; +frame->Xecode = ecode; +frame->Xoffset_top = offset_top; +frame->Xims = ims; +frame->Xeptrb = eptrb; +frame->Xflags = flags; + +/* This is where control jumps back to to effect "recursion" */ + +HEAP_RECURSE: + +/* Macros make the argument variables come from the current frame */ + +#define eptr frame->Xeptr +#define ecode frame->Xecode +#define offset_top frame->Xoffset_top +#define ims frame->Xims +#define eptrb frame->Xeptrb +#define flags frame->Xflags + +/* Ditto for the local variables */ + +#ifdef SUPPORT_UTF8 +#define charptr frame->Xcharptr +#endif +#define callpat frame->Xcallpat +#define data frame->Xdata +#define next frame->Xnext +#define pp frame->Xpp +#define prev frame->Xprev +#define saved_eptr frame->Xsaved_eptr + +#define new_recursive frame->Xnew_recursive + +#define cur_is_word frame->Xcur_is_word +#define condition frame->Xcondition +#define minimize frame->Xminimize +#define prev_is_word frame->Xprev_is_word + +#define original_ims frame->Xoriginal_ims + +#ifdef SUPPORT_UCP +#define prop_type frame->Xprop_type +#define prop_fail_result frame->Xprop_fail_result +#define prop_category frame->Xprop_category +#define prop_chartype frame->Xprop_chartype +#define prop_othercase frame->Xprop_othercase +#define prop_test_against frame->Xprop_test_against +#define prop_test_variable frame->Xprop_test_variable +#endif + +#define ctype frame->Xctype +#define fc frame->Xfc +#define fi frame->Xfi +#define length frame->Xlength +#define max frame->Xmax +#define min frame->Xmin +#define number frame->Xnumber +#define offset frame->Xoffset +#define op frame->Xop +#define save_capture_last frame->Xsave_capture_last +#define save_offset1 frame->Xsave_offset1 +#define save_offset2 frame->Xsave_offset2 +#define save_offset3 frame->Xsave_offset3 +#define stacksave frame->Xstacksave + +#define newptrb frame->Xnewptrb + +/* When recursion is being used, local variables are allocated on the stack and +get preserved during recursion in the normal way. In this environment, fi and +i, and fc and c, can be the same variables. */ + +#else +#define fi i +#define fc c + + +#ifdef SUPPORT_UTF8 /* Many of these variables are used ony */ +const uschar *charptr; /* small blocks of the code. My normal */ +#endif /* style of coding would have declared */ +const uschar *callpat; /* them within each of those blocks. */ +const uschar *data; /* However, in order to accommodate the */ +const uschar *next; /* version of this code that uses an */ +const uschar *pp; /* external "stack" implemented on the */ +const uschar *prev; /* heap, it is easier to declare them */ +const uschar *saved_eptr; /* all here, so the declarations can */ + /* be cut out in a block. The only */ +recursion_info new_recursive; /* declarations within blocks below are */ + /* for variables that do not have to */ +BOOL cur_is_word; /* be preserved over a recursive call */ +BOOL condition; /* to RMATCH(). */ +BOOL minimize; +BOOL prev_is_word; + +unsigned long int original_ims; + +#ifdef SUPPORT_UCP +int prop_type; +int prop_fail_result; +int prop_category; +int prop_chartype; +int prop_othercase; +int prop_test_against; +int *prop_test_variable; +#endif + +int ctype; +int length; +int max; +int min; +int number; +int offset; +int op; +int save_capture_last; +int save_offset1, save_offset2, save_offset3; +int stacksave[REC_STACK_SAVE_MAX]; + +eptrblock newptrb; +#endif + +/* These statements are here to stop the compiler complaining about unitialized +variables. */ + +#ifdef SUPPORT_UCP +prop_fail_result = 0; +prop_test_against = 0; +prop_test_variable = NULL; +#endif + +/* OK, now we can get on with the real code of the function. Recursion is +specified by the macros RMATCH and RRETURN. When NO_RECURSE is *not* defined, +these just turn into a recursive call to match() and a "return", respectively. +However, RMATCH isn't like a function call because it's quite a complicated +macro. It has to be used in one particular way. This shouldn't, however, impact +performance when true recursion is being used. */ + +if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); + +original_ims = ims; /* Save for resetting on ')' */ + +/* At the start of a bracketed group, add the current subject pointer to the +stack of such pointers, to be re-instated at the end of the group when we hit +the closing ket. When match() is called in other circumstances, we don't add to +this stack. */ + +if ((flags & match_isgroup) != 0) + { + newptrb.epb_prev = eptrb; + newptrb.epb_saved_eptr = eptr; + eptrb = &newptrb; + } + +/* Now start processing the operations. */ + +for (;;) + { + op = *ecode; + minimize = FALSE; + + /* For partial matching, remember if we ever hit the end of the subject after + matching at least one subject character. */ + + if (md->partial && + eptr >= md->end_subject && + eptr > md->start_match) + md->hitend = TRUE; + + /* Opening capturing bracket. If there is space in the offset vector, save + the current subject position in the working slot at the top of the vector. We + mustn't change the current values of the data slot, because they may be set + from a previous iteration of this group, and be referred to by a reference + inside the group. + + If the bracket fails to match, we need to restore this value and also the + values of the final offsets, in case they were set by a previous iteration of + the same bracket. + + If there isn't enough space in the offset vector, treat this as if it were a + non-capturing bracket. Don't worry about setting the flag for the error case + here; that is handled in the code for KET. */ + + if (op > OP_BRA) + { + number = op - OP_BRA; + + /* For extended extraction brackets (large number), we have to fish out the + number from a dummy opcode at the start. */ + + if (number > EXTRACT_BASIC_MAX) + number = GET2(ecode, 2+LINK_SIZE); + offset = number << 1; + +#ifdef DEBUG + printf("start bracket %d subject=", number); + pchars(eptr, 16, TRUE, md); + printf("\n"); +#endif + + if (offset < md->offset_max) + { + save_offset1 = md->offset_vector[offset]; + save_offset2 = md->offset_vector[offset+1]; + save_offset3 = md->offset_vector[md->offset_end - number]; + save_capture_last = md->capture_last; + + DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); + md->offset_vector[md->offset_end - number] = eptr - md->start_subject; + + do + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, + match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->capture_last = save_capture_last; + ecode += GET(ecode, 1); + } + while (*ecode == OP_ALT); + + DPRINTF(("bracket %d failed\n", number)); + + md->offset_vector[offset] = save_offset1; + md->offset_vector[offset+1] = save_offset2; + md->offset_vector[md->offset_end - number] = save_offset3; + + RRETURN(MATCH_NOMATCH); + } + + /* Insufficient room for saving captured contents */ + + else op = OP_BRA; + } + + /* Other types of node can be handled by a switch */ + + switch(op) + { + case OP_BRA: /* Non-capturing bracket: optimized */ + DPRINTF(("start bracket 0\n")); + do + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, + match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode, 1); + } + while (*ecode == OP_ALT); + DPRINTF(("bracket 0 failed\n")); + RRETURN(MATCH_NOMATCH); + + /* Conditional group: compilation checked that there are no more than + two branches. If the condition is false, skipping the first branch takes us + past the end if there is only one branch, but that's OK because that is + exactly what going to the ket would do. */ + + case OP_COND: + if (ecode[LINK_SIZE+1] == OP_CREF) /* Condition extract or recurse test */ + { + offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ + condition = (offset == CREF_RECURSE * 2)? + (md->recursive != NULL) : + (offset < offset_top && md->offset_vector[offset] >= 0); + RMATCH(rrc, eptr, ecode + (condition? + (LINK_SIZE + 4) : (LINK_SIZE + 1 + GET(ecode, 1))), + offset_top, md, ims, eptrb, match_isgroup); + RRETURN(rrc); + } + + /* The condition is an assertion. Call match() to evaluate it - setting + the final argument TRUE causes it to stop at the end of an assertion. */ + + else + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, + match_condassert | match_isgroup); + if (rrc == MATCH_MATCH) + { + ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE+2); + while (*ecode == OP_ALT) ecode += GET(ecode, 1); + } + else if (rrc != MATCH_NOMATCH) + { + RRETURN(rrc); /* Need braces because of following else */ + } + else ecode += GET(ecode, 1); + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, + match_isgroup); + RRETURN(rrc); + } + /* Control never reaches here */ + + /* Skip over conditional reference or large extraction number data if + encountered. */ + + case OP_CREF: + case OP_BRANUMBER: + ecode += 3; + break; + + /* End of the pattern. If we are in a recursion, we should restore the + offsets appropriately and continue from after the call. */ + + case OP_END: + if (md->recursive != NULL && md->recursive->group_num == 0) + { + recursion_info *rec = md->recursive; + DPRINTF(("Hit the end in a (?0) recursion\n")); + md->recursive = rec->prevrec; + memmove(md->offset_vector, rec->offset_save, + rec->saved_max * sizeof(int)); + md->start_match = rec->save_start; + ims = original_ims; + ecode = rec->after_call; + break; + } + + /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty + string - backtracking will then try other alternatives, if any. */ + + if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH); + md->end_match_ptr = eptr; /* Record where we ended */ + md->end_offset_top = offset_top; /* and how many extracts were taken */ + RRETURN(MATCH_MATCH); + + /* Change option settings */ + + case OP_OPT: + ims = ecode[1]; + ecode += 2; + DPRINTF(("ims set to %02lx\n", ims)); + break; + + /* Assertion brackets. Check the alternative branches in turn - the + matching won't pass the KET for an assertion. If any one branch matches, + the assertion is true. Lookbehind assertions have an OP_REVERSE item at the + start of each branch to move the current point backwards, so the code at + this level is identical to the lookahead case. */ + + case OP_ASSERT: + case OP_ASSERTBACK: + do + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, + match_isgroup); + if (rrc == MATCH_MATCH) break; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode, 1); + } + while (*ecode == OP_ALT); + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); + + /* If checking an assertion for a condition, return MATCH_MATCH. */ + + if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + + /* Continue from after the assertion, updating the offsets high water + mark, since extracts may have been taken during the assertion. */ + + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + ecode += 1 + LINK_SIZE; + offset_top = md->end_offset_top; + continue; + + /* Negative assertion: all branches must fail to match */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK_NOT: + do + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, + match_isgroup); + if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode,1); + } + while (*ecode == OP_ALT); + + if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + + ecode += 1 + LINK_SIZE; + continue; + + /* Move the subject pointer back. This occurs only at the start of + each branch of a lookbehind assertion. If we are too close to the start to + move back, this match function fails. When working with UTF-8 we move + back a number of characters, not bytes. */ + + case OP_REVERSE: +#ifdef SUPPORT_UTF8 + if (md->utf8) + { + c = GET(ecode,1); + for (i = 0; i < c; i++) + { + eptr--; + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); + BACKCHAR(eptr) + } + } + else +#endif + + /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ + + { + eptr -= GET(ecode,1); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); + } + + /* Skip to next op code */ + + ecode += 1 + LINK_SIZE; + break; + + /* The callout item calls an external function, if one is provided, passing + details of the match so far. This is mainly for debugging, though the + function is able to force a failure. */ + + case OP_CALLOUT: + if (pcre_callout != NULL) + { + pcre_callout_block cb; + cb.version = 1; /* Version 1 of the callout block */ + cb.callout_number = ecode[1]; + cb.offset_vector = md->offset_vector; + cb.subject = (const char *)md->start_subject; + cb.subject_length = md->end_subject - md->start_subject; + cb.start_match = md->start_match - md->start_subject; + cb.current_position = eptr - md->start_subject; + cb.pattern_position = GET(ecode, 2); + cb.next_item_length = GET(ecode, 2 + LINK_SIZE); + cb.capture_top = offset_top/2; + cb.capture_last = md->capture_last; + cb.callout_data = md->callout_data; + if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); + if (rrc < 0) RRETURN(rrc); + } + ecode += 2 + 2*LINK_SIZE; + break; + + /* Recursion either matches the current regex, or some subexpression. The + offset data is the offset to the starting bracket from the start of the + whole pattern. (This is so that it works from duplicated subpatterns.) + + If there are any capturing brackets started but not finished, we have to + save their starting points and reinstate them after the recursion. However, + we don't know how many such there are (offset_top records the completed + total) so we just have to save all the potential data. There may be up to + 65535 such values, which is too large to put on the stack, but using malloc + for small numbers seems expensive. As a compromise, the stack is used when + there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc + is used. A problem is what to do if the malloc fails ... there is no way of + returning to the top level with an error. Save the top REC_STACK_SAVE_MAX + values on the stack, and accept that the rest may be wrong. + + There are also other values that have to be saved. We use a chained + sequence of blocks that actually live on the stack. Thanks to Robin Houston + for the original version of this logic. */ + + case OP_RECURSE: + { + callpat = md->start_code + GET(ecode, 1); + new_recursive.group_num = *callpat - OP_BRA; + + /* For extended extraction brackets (large number), we have to fish out + the number from a dummy opcode at the start. */ + + if (new_recursive.group_num > EXTRACT_BASIC_MAX) + new_recursive.group_num = GET2(callpat, 2+LINK_SIZE); + + /* Add to "recursing stack" */ + + new_recursive.prevrec = md->recursive; + md->recursive = &new_recursive; + + /* Find where to continue from afterwards */ + + ecode += 1 + LINK_SIZE; + new_recursive.after_call = ecode; + + /* Now save the offset data. */ + + new_recursive.saved_max = md->offset_end; + if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) + new_recursive.offset_save = stacksave; + else + { + new_recursive.offset_save = + (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); + if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); + } + + memcpy(new_recursive.offset_save, md->offset_vector, + new_recursive.saved_max * sizeof(int)); + new_recursive.save_start = md->start_match; + md->start_match = eptr; + + /* OK, now we can do the recursion. For each top-level alternative we + restore the offset and recursion data. */ + + DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); + do + { + RMATCH(rrc, eptr, callpat + 1 + LINK_SIZE, offset_top, md, ims, + eptrb, match_isgroup); + if (rrc == MATCH_MATCH) + { + md->recursive = new_recursive.prevrec; + if (new_recursive.offset_save != stacksave) + (pcre_free)(new_recursive.offset_save); + RRETURN(MATCH_MATCH); + } + else if (rrc != MATCH_NOMATCH) RRETURN(rrc); + + md->recursive = &new_recursive; + memcpy(md->offset_vector, new_recursive.offset_save, + new_recursive.saved_max * sizeof(int)); + callpat += GET(callpat, 1); + } + while (*callpat == OP_ALT); + + DPRINTF(("Recursion didn't match\n")); + md->recursive = new_recursive.prevrec; + if (new_recursive.offset_save != stacksave) + (pcre_free)(new_recursive.offset_save); + RRETURN(MATCH_NOMATCH); + } + /* Control never reaches here */ + + /* "Once" brackets are like assertion brackets except that after a match, + the point in the subject string is not moved back. Thus there can never be + a move back into the brackets. Friedl calls these "atomic" subpatterns. + Check the alternative branches in turn - the matching won't pass the KET + for this kind of subpattern. If any one branch matches, we carry on as at + the end of a normal bracket, leaving the subject pointer. */ + + case OP_ONCE: + { + prev = ecode; + saved_eptr = eptr; + + do + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, + eptrb, match_isgroup); + if (rrc == MATCH_MATCH) break; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode,1); + } + while (*ecode == OP_ALT); + + /* If hit the end of the group (which could be repeated), fail */ + + if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); + + /* Continue as from after the assertion, updating the offsets high water + mark, since extracts may have been taken. */ + + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + + /* For a non-repeating ket, just continue at this level. This also + happens for a repeating ket if no characters were matched in the group. + This is the forcible breaking of infinite loops as implemented in Perl + 5.005. If there is an options reset, it will get obeyed in the normal + course of events. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + ecode += 1+LINK_SIZE; + break; + } + + /* The repeating kets try the rest of the pattern or restart from the + preceding bracket, in the appropriate order. We need to reset any options + that changed within the bracket before re-running it, so check the next + opcode. */ + + if (ecode[1+LINK_SIZE] == OP_OPT) + { + ims = (ims & ~PCRE_IMS) | ecode[4]; + DPRINTF(("ims set to %02lx at group repeat\n", ims)); + } + + if (*ecode == OP_KETRMIN) + { + RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + else /* OP_KETRMAX */ + { + RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + } + RRETURN(MATCH_NOMATCH); + + /* An alternation is the end of a branch; scan along to find the end of the + bracketed group and go to there. */ + + case OP_ALT: + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + break; + + /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating + that it may occur zero times. It may repeat infinitely, or not at all - + i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper + repeat limits are compiled as a number of copies, with the optional ones + preceded by BRAZERO or BRAMINZERO. */ + + case OP_BRAZERO: + { + next = ecode+1; + RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + do next += GET(next,1); while (*next == OP_ALT); + ecode = next + 1+LINK_SIZE; + } + break; + + case OP_BRAMINZERO: + { + next = ecode+1; + do next += GET(next,1); while (*next == OP_ALT); + RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, + match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode++; + } + break; + + /* End of a group, repeated or non-repeating. If we are at the end of + an assertion "group", stop matching and return MATCH_MATCH, but record the + current high water mark for use by positive assertions. Do this also + for the "once" (not-backup up) groups. */ + + case OP_KET: + case OP_KETRMIN: + case OP_KETRMAX: + { + prev = ecode - GET(ecode, 1); + saved_eptr = eptrb->epb_saved_eptr; + + /* Back up the stack of bracket start pointers. */ + + eptrb = eptrb->epb_prev; + + if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || + *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || + *prev == OP_ONCE) + { + md->end_match_ptr = eptr; /* For ONCE */ + md->end_offset_top = offset_top; + RRETURN(MATCH_MATCH); + } + + /* In all other cases except a conditional group we have to check the + group number back at the start and if necessary complete handling an + extraction by setting the offsets and bumping the high water mark. */ + + if (*prev != OP_COND) + { + number = *prev - OP_BRA; + + /* For extended extraction brackets (large number), we have to fish out + the number from a dummy opcode at the start. */ + + if (number > EXTRACT_BASIC_MAX) number = GET2(prev, 2+LINK_SIZE); + offset = number << 1; + +#ifdef DEBUG + printf("end bracket %d", number); + printf("\n"); +#endif + + /* Test for a numbered group. This includes groups called as a result + of recursion. Note that whole-pattern recursion is coded as a recurse + into group 0, so it won't be picked up here. Instead, we catch it when + the OP_END is reached. */ + + if (number > 0) + { + md->capture_last = number; + if (offset >= md->offset_max) md->offset_overflow = TRUE; else + { + md->offset_vector[offset] = + md->offset_vector[md->offset_end - number]; + md->offset_vector[offset+1] = eptr - md->start_subject; + if (offset_top <= offset) offset_top = offset + 2; + } + + /* Handle a recursively called group. Restore the offsets + appropriately and continue from after the call. */ + + if (md->recursive != NULL && md->recursive->group_num == number) + { + recursion_info *rec = md->recursive; + DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); + md->recursive = rec->prevrec; + md->start_match = rec->save_start; + memcpy(md->offset_vector, rec->offset_save, + rec->saved_max * sizeof(int)); + ecode = rec->after_call; + ims = original_ims; + break; + } + } + } + + /* Reset the value of the ims flags, in case they got changed during + the group. */ + + ims = original_ims; + DPRINTF(("ims reset to %02lx\n", ims)); + + /* For a non-repeating ket, just continue at this level. This also + happens for a repeating ket if no characters were matched in the group. + This is the forcible breaking of infinite loops as implemented in Perl + 5.005. If there is an options reset, it will get obeyed in the normal + course of events. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + ecode += 1 + LINK_SIZE; + break; + } + + /* The repeating kets try the rest of the pattern or restart from the + preceding bracket, in the appropriate order. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + else /* OP_KETRMAX */ + { + RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + } + + RRETURN(MATCH_NOMATCH); + + /* Start of subject unless notbol, or after internal newline if multiline */ + + case OP_CIRC: + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); + if ((ims & PCRE_MULTILINE) != 0) + { + if (eptr != md->start_subject && eptr[-1] != NEWLINE) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + } + /* ... else fall through */ + + /* Start of subject assertion */ + + case OP_SOD: + if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Start of match assertion */ + + case OP_SOM: + if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Assert before internal newline if multiline, or before a terminating + newline unless endonly is set, else end of subject unless noteol is set. */ + + case OP_DOLL: + if ((ims & PCRE_MULTILINE) != 0) + { + if (eptr < md->end_subject) + { if (*eptr != NEWLINE) RRETURN(MATCH_NOMATCH); } + else + { if (md->noteol) RRETURN(MATCH_NOMATCH); } + ecode++; + break; + } + else + { + if (md->noteol) RRETURN(MATCH_NOMATCH); + if (!md->endonly) + { + if (eptr < md->end_subject - 1 || + (eptr == md->end_subject - 1 && *eptr != NEWLINE)) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + } + } + /* ... else fall through */ + + /* End of subject assertion (\z) */ + + case OP_EOD: + if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* End of subject or ending \n assertion (\Z) */ + + case OP_EODN: + if (eptr < md->end_subject - 1 || + (eptr == md->end_subject - 1 && *eptr != NEWLINE)) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Word boundary assertions */ + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + { + + /* Find out if the previous and current characters are "word" characters. + It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to + be "non-word" characters. */ + +#ifdef SUPPORT_UTF8 + if (md->utf8) + { + if (eptr == md->start_subject) prev_is_word = FALSE; else + { + const uschar *lastptr = eptr - 1; + while((*lastptr & 0xc0) == 0x80) lastptr--; + GETCHAR(c, lastptr); + prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; + } + if (eptr >= md->end_subject) cur_is_word = FALSE; else + { + GETCHAR(c, eptr); + cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; + } + } + else +#endif + + /* More streamlined when not in UTF-8 mode */ + + { + prev_is_word = (eptr != md->start_subject) && + ((md->ctypes[eptr[-1]] & ctype_word) != 0); + cur_is_word = (eptr < md->end_subject) && + ((md->ctypes[*eptr] & ctype_word) != 0); + } + + /* Now see if the situation is what we want */ + + if ((*ecode++ == OP_WORD_BOUNDARY)? + cur_is_word == prev_is_word : cur_is_word != prev_is_word) + RRETURN(MATCH_NOMATCH); + } + break; + + /* Match a single character type; inline for speed */ + + case OP_ANY: + if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE) + RRETURN(MATCH_NOMATCH); + if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); +#ifdef SUPPORT_UTF8 + if (md->utf8) + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; +#endif + ecode++; + break; + + /* Match a single byte, even in UTF-8 mode. This opcode really does match + any byte, even newline, independent of the setting of PCRE_DOTALL. */ + + case OP_ANYBYTE: + if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_DIGIT: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c < 256 && +#endif + (md->ctypes[c] & ctype_digit) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_DIGIT: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c >= 256 || +#endif + (md->ctypes[c] & ctype_digit) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WHITESPACE: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c < 256 && +#endif + (md->ctypes[c] & ctype_space) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WHITESPACE: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c >= 256 || +#endif + (md->ctypes[c] & ctype_space) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_NOT_WORDCHAR: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c < 256 && +#endif + (md->ctypes[c] & ctype_word) != 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + + case OP_WORDCHAR: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + if ( +#ifdef SUPPORT_UTF8 + c >= 256 || +#endif + (md->ctypes[c] & ctype_word) == 0 + ) + RRETURN(MATCH_NOMATCH); + ecode++; + break; + +#ifdef SUPPORT_UCP + /* Check the next character by Unicode property. We will get here only + if the support is in the binary; otherwise a compile-time error occurs. */ + + case OP_PROP: + case OP_NOTPROP: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + { + int chartype, rqdtype; + int othercase; + int category = ucp_findchar(c, &chartype, &othercase); + + rqdtype = *(++ecode); + ecode++; + + if (rqdtype >= 128) + { + if ((rqdtype - 128 != category) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + } + else + { + if ((rqdtype != chartype) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); + } + } + break; + + /* Match an extended Unicode sequence. We will get here only if the support + is in the binary; otherwise a compile-time error occurs. */ + + case OP_EXTUNI: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + { + int chartype; + int othercase; + int category = ucp_findchar(c, &chartype, &othercase); + if (category == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) + { + int len = 1; + if (!md->utf8) c = *eptr; else + { + GETCHARLEN(c, eptr, len); + } + category = ucp_findchar(c, &chartype, &othercase); + if (category != ucp_M) break; + eptr += len; + } + } + ecode++; + break; +#endif + + + /* Match a back reference, possibly repeatedly. Look past the end of the + item to see if there is repeat information following. The code is similar + to that for character classes, but repeated for efficiency. Then obey + similar code to character type repeats - written out again for speed. + However, if the referenced string is the empty string, always treat + it as matched, any number of times (otherwise there could be infinite + loops). */ + + case OP_REF: + { + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 3; /* Advance past item */ + + /* If the reference is unset, set the length to be longer than the amount + of subject left; this ensures that every attempt at a match fails. We + can't just fail here, because of the possibility of quantifiers with zero + minima. */ + + length = (offset >= offset_top || md->offset_vector[offset] < 0)? + md->end_subject - eptr + 1 : + md->offset_vector[offset+1] - md->offset_vector[offset]; + + /* Set up for repetition, or handle the non-repeated case */ + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 3); + if (max == 0) max = INT_MAX; + ecode += 5; + break; + + default: /* No repeat follows */ + if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); + eptr += length; + continue; /* With the main loop */ + } + + /* If the length of the reference is zero, just continue with the + main loop. */ + + if (length == 0) continue; + + /* First, ensure the minimum number of matches are present. We get back + the length of the reference string explicitly rather than passing the + address of eptr, so that eptr can be a register variable. */ + + for (i = 1; i <= min; i++) + { + if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); + eptr += length; + } + + /* If min = max, continue at the same level without recursion. + They are not both allowed to be zero. */ + + if (min == max) continue; + + /* If minimizing, keep trying and advancing the pointer */ + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || !match_ref(offset, eptr, length, md, ims)) + RRETURN(MATCH_NOMATCH); + eptr += length; + } + /* Control never gets here */ + } + + /* If maximizing, find the longest string and work backwards */ + + else + { + pp = eptr; + for (i = min; i < max; i++) + { + if (!match_ref(offset, eptr, length, md, ims)) break; + eptr += length; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr -= length; + } + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + + + /* Match a bit-mapped character class, possibly repeatedly. This op code is + used when all the characters in the class have values in the range 0-255, + and either the matching is caseful, or the characters are in the range + 0-127 when UTF-8 processing is enabled. The only difference between + OP_CLASS and OP_NCLASS occurs when a data character outside the range is + encountered. + + First, look past the end of the item to see if there is repeat information + following. Then obey similar code to character type repeats - written out + again for speed. */ + + case OP_NCLASS: + case OP_CLASS: + { + data = ecode + 1; /* Save for matching */ + ecode += 33; /* Advance past the item */ + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 3); + if (max == 0) max = INT_MAX; + ecode += 5; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + { + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + c = *eptr++; + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else + { + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + c = *eptr++; + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c > 255) + { + if (op == OP_CLASS) break; + } + else + { + if ((data[c/8] & (1 << (c&7))) == 0) break; + } + eptr += len; + } + for (;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) break; + c = *eptr; + if ((data[c/8] & (1 << (c&7))) == 0) break; + eptr++; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + } + + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + + /* Match an extended character class. This opcode is encountered only + in UTF-8 mode, because that's the only time it is compiled. */ + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + { + data = ecode + 1 + LINK_SIZE; /* Save for matching */ + ecode += GET(ecode, 1); /* Advance past the item */ + + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 3); + if (max == 0) max = INT_MAX; + ecode += 5; + break; + + default: /* No repeat follows */ + min = max = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + if (!match_xclass(c, data)) RRETURN(MATCH_NOMATCH); + } + + /* If max == min we can continue with the main loop without the + need to recurse. */ + + if (min == max) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + if (!match_xclass(c, data)) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + pp = eptr; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (!match_xclass(c, data)) break; + eptr += len; + } + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr) + } + RRETURN(MATCH_NOMATCH); + } + + /* Control never gets here */ + } +#endif /* End of XCLASS */ + + /* Match a single character, casefully */ + + case OP_CHAR: +#ifdef SUPPORT_UTF8 + if (md->utf8) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); + } + else +#endif + + /* Non-UTF-8 mode */ + { + if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* Match a single character, caselessly */ + + case OP_CHARNC: +#ifdef SUPPORT_UTF8 + if (md->utf8) + { + length = 1; + ecode++; + GETCHARLEN(fc, ecode, length); + + if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + + /* If the pattern character's value is < 128, we have only one byte, and + can use the fast lookup table. */ + + if (fc < 128) + { + if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); + } + + /* Otherwise we must pick up the subject character */ + + else + { + int dc; + GETCHARINC(dc, eptr); + ecode += length; + + /* If we have Unicode property support, we can use it to test the other + case of the character, if there is one. The result of ucp_findchar() is + < 0 if the char isn't found, and othercase is returned as zero if there + isn't one. */ + + if (fc != dc) + { +#ifdef SUPPORT_UCP + int chartype; + int othercase; + if (ucp_findchar(fc, &chartype, &othercase) < 0 || dc != othercase) +#endif + RRETURN(MATCH_NOMATCH); + } + } + } + else +#endif /* SUPPORT_UTF8 */ + + /* Non-UTF-8 mode */ + { + if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); + if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); + ecode += 2; + } + break; + + /* Match a single character repeatedly; different opcodes share code. */ + + case OP_EXACT: + min = max = GET2(ecode, 1); + ecode += 3; + goto REPEATCHAR; + + case OP_UPTO: + case OP_MINUPTO: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_MINUPTO; + ecode += 3; + goto REPEATCHAR; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + c = *ecode++ - OP_STAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single-character matches. We can give + up quickly if there are fewer than the minimum number of characters left in + the subject. */ + + REPEATCHAR: +#ifdef SUPPORT_UTF8 + if (md->utf8) + { + length = 1; + charptr = ecode; + GETCHARLEN(fc, ecode, length); + if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + ecode += length; + + /* Handle multibyte character matching specially here. There is + support for caseless matching if UCP support is present. */ + + if (length > 1) + { + int oclength = 0; + uschar occhars[8]; + +#ifdef SUPPORT_UCP + int othercase; + int chartype; + if ((ims & PCRE_CASELESS) != 0 && + ucp_findchar(fc, &chartype, &othercase) >= 0 && + othercase > 0) + oclength = ord2utf8(othercase, occhars); +#endif /* SUPPORT_UCP */ + + for (i = 1; i <= min; i++) + { + if (memcmp(eptr, charptr, length) == 0) eptr += length; + /* Need braces because of following else */ + else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } + else + { + if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); + eptr += oclength; + } + } + + if (min == max) continue; + + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + if (memcmp(eptr, charptr, length) == 0) eptr += length; + /* Need braces because of following else */ + else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } + else + { + if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); + eptr += oclength; + } + } + /* Control never gets here */ + } + else + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr > md->end_subject - length) break; + if (memcmp(eptr, charptr, length) == 0) eptr += length; + else if (oclength == 0) break; + else + { + if (memcmp(eptr, occhars, oclength) != 0) break; + eptr += oclength; + } + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr -= length; + } + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* If the length of a UTF-8 character is 1, we fall through here, and + obey the code as for non-UTF-8 characters below, though in this case the + value of fc will always be < 128. */ + } + else +#endif /* SUPPORT_UTF8 */ + + /* When not in UTF-8 mode, load a single-byte character. */ + { + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + fc = *ecode++; + } + + /* The value of fc at this point is always less than 256, though we may or + may not be in UTF-8 mode. The code is duplicated for the caseless and + caseful cases, for speed, since matching characters is likely to be quite + common. First, ensure the minimum number of matches are present. If min = + max, continue at the same level without recursing. Otherwise, if + minimizing, keep trying the rest of the expression and advancing one + matching character if failing, up to the maximum. Alternatively, if + maximizing, find the maximum number of characters and work backwards. */ + + DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, + max, eptr)); + + if ((ims & PCRE_CASELESS) != 0) + { + fc = md->lcc[fc]; + for (i = 1; i <= min; i++) + if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); + if (min == max) continue; + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject || + fc != md->lcc[*eptr++]) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + else + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break; + eptr++; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* Caseful comparisons (includes all multi-byte characters) */ + + else + { + for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH); + if (min == max) continue; + if (minimize) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject || fc != *eptr++) + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + else + { + pp = eptr; + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || fc != *eptr) break; + eptr++; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + /* Match a negated single one-byte character. The character we are + checking can be multibyte. */ + + case OP_NOT: + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + ecode++; + GETCHARINCTEST(c, eptr); + if ((ims & PCRE_CASELESS) != 0) + { +#ifdef SUPPORT_UTF8 + if (c < 256) +#endif + c = md->lcc[c]; + if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); + } + else + { + if (*ecode++ == c) RRETURN(MATCH_NOMATCH); + } + break; + + /* Match a negated single one-byte character repeatedly. This is almost a + repeat of the code for a repeated single character, but I haven't found a + nice way of commoning these up that doesn't require a test of the + positive/negative option for each character match. Maybe that wouldn't add + very much to the time taken, but character matching *is* what this is all + about... */ + + case OP_NOTEXACT: + min = max = GET2(ecode, 1); + ecode += 3; + goto REPEATNOTCHAR; + + case OP_NOTUPTO: + case OP_NOTMINUPTO: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_NOTMINUPTO; + ecode += 3; + goto REPEATNOTCHAR; + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + c = *ecode++ - OP_NOTSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single-byte matches. We can give up quickly + if there are fewer than the minimum number of bytes left in the + subject. */ + + REPEATNOTCHAR: + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + fc = *ecode++; + + /* The code is duplicated for the caseless and caseful cases, for speed, + since matching characters is likely to be quite common. First, ensure the + minimum number of matches are present. If min = max, continue at the same + level without recursing. Otherwise, if minimizing, keep trying the rest of + the expression and advancing one matching character if failing, up to the + maximum. Alternatively, if maximizing, find the maximum number of + characters and work backwards. */ + + DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, + max, eptr)); + + if ((ims & PCRE_CASELESS) != 0) + { + fc = md->lcc[fc]; + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (i = 1; i <= min; i++) + { + GETCHARINC(d, eptr); + if (d < 256) d = md->lcc[d]; + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + + /* Not UTF-8 mode */ + { + for (i = 1; i <= min; i++) + if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + GETCHARINC(d, eptr); + if (d < 256) d = md->lcc[d]; + if (fi >= max || eptr >= md->end_subject || fc == d) + RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++]) + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(d, eptr, len); + if (d < 256) d = md->lcc[d]; + if (fc == d) break; + eptr += len; + } + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break; + eptr++; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + } + + /* Caseful comparisons */ + + else + { +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (i = 1; i <= min; i++) + { + GETCHARINC(d, eptr); + if (fc == d) RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (i = 1; i <= min; i++) + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); + } + + if (min == max) continue; + + if (minimize) + { +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + GETCHARINC(d, eptr); + if (fi >= max || eptr >= md->end_subject || fc == d) + RRETURN(MATCH_NOMATCH); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject || fc == *eptr++) + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + } + + /* Maximize case */ + + else + { + pp = eptr; + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + register int d; + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(d, eptr, len); + if (fc == d) break; + eptr += len; + } + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || fc == *eptr) break; + eptr++; + } + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + } + } + + RRETURN(MATCH_NOMATCH); + } + } + /* Control never gets here */ + + /* Match a single character type repeatedly; several different opcodes + share code. This is very similar to the code for single characters, but we + repeat it in the interests of efficiency. */ + + case OP_TYPEEXACT: + min = max = GET2(ecode, 1); + minimize = TRUE; + ecode += 3; + goto REPEATTYPE; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + min = 0; + max = GET2(ecode, 1); + minimize = *ecode == OP_TYPEMINUPTO; + ecode += 3; + goto REPEATTYPE; + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + c = *ecode++ - OP_TYPESTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + + /* Common code for all repeated single character type matches. Note that + in UTF-8 mode, '.' matches a character of any length, but for the other + character types, the valid characters are all one-byte long. */ + + REPEATTYPE: + ctype = *ecode++; /* Code for the character type */ + +#ifdef SUPPORT_UCP + if (ctype == OP_PROP || ctype == OP_NOTPROP) + { + prop_fail_result = ctype == OP_NOTPROP; + prop_type = *ecode++; + if (prop_type >= 128) + { + prop_test_against = prop_type - 128; + prop_test_variable = &prop_category; + } + else + { + prop_test_against = prop_type; + prop_test_variable = &prop_chartype; + } + } + else prop_type = -1; +#endif + + /* First, ensure the minimum number of matches are present. Use inline + code for maximizing the speed, and do the type test once at the start + (i.e. keep it out of the loop). Also we can test that there are at least + the minimum number of bytes before we start. This isn't as effective in + UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that + is tidier. Also separate the UCP code, which can be the same for both UTF-8 + and single-bytes. */ + + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); + if (min > 0) + { +#ifdef SUPPORT_UCP + if (prop_type > 0) + { + for (i = 1; i <= min; i++) + { + GETCHARINC(c, eptr); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if ((*prop_test_variable == prop_test_against) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = 1; i <= min; i++) + { + GETCHARINCTEST(c, eptr); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) + { + int len = 1; + if (!md->utf8) c = *eptr; else + { + GETCHARLEN(c, eptr, len); + } + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category != ucp_M) break; + eptr += len; + } + } + } + + else +#endif /* SUPPORT_UCP */ + +/* Handle all other cases when the coding is UTF-8 */ + +#ifdef SUPPORT_UTF8 + if (md->utf8) switch(ctype) + { + case OP_ANY: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + (*eptr++ == NEWLINE && (ims & PCRE_DOTALL) == 0)) + RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + } + break; + + case OP_ANYBYTE: + eptr += min; + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + } + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0)) + RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + } + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0)) + RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + } + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + { + if (eptr >= md->end_subject || + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + /* No need to skip more bytes - we know it's a 1-byte character */ + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } /* End switch(ctype) */ + + else +#endif /* SUPPORT_UTF8 */ + + /* Code for the non-UTF-8 case for minimum matching of operators other + than OP_PROP and OP_NOTPROP. */ + + switch(ctype) + { + case OP_ANY: + if ((ims & PCRE_DOTALL) == 0) + { + for (i = 1; i <= min; i++) + if (*eptr++ == NEWLINE) RRETURN(MATCH_NOMATCH); + } + else eptr += min; + break; + + case OP_ANYBYTE: + eptr += min; + break; + + case OP_NOT_DIGIT: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + for (i = 1; i <= min; i++) + if ((md->ctypes[*eptr++] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + + /* If min = max, continue at the same level without recursing */ + + if (min == max) continue; + + /* If minimizing, we have to test the rest of the pattern before each + subsequent match. Again, separate the UTF-8 case for speed, and also + separate the UCP cases. */ + + if (minimize) + { +#ifdef SUPPORT_UCP + if (prop_type > 0) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINC(c, eptr); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if ((*prop_test_variable == prop_test_against) == prop_fail_result) + RRETURN(MATCH_NOMATCH); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + GETCHARINCTEST(c, eptr); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) + { + int len = 1; + if (!md->utf8) c = *eptr; else + { + GETCHARLEN(c, eptr, len); + } + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category != ucp_M) break; + eptr += len; + } + } + } + + else +#endif /* SUPPORT_UCP */ + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + if (md->utf8) + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + + GETCHARINC(c, eptr); + switch(ctype) + { + case OP_ANY: + if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH); + break; + + case OP_ANYBYTE: + break; + + case OP_NOT_DIGIT: + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if (c < 256 && (md->ctypes[c] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + if (c < 256 && (md->ctypes[c] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if (c >= 256 && (md->ctypes[c] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + } + else +#endif + /* Not UTF-8 mode */ + { + for (fi = min;; fi++) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); + c = *eptr++; + switch(ctype) + { + case OP_ANY: + if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH); + break; + + case OP_ANYBYTE: + break; + + case OP_NOT_DIGIT: + if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_DIGIT: + if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WHITESPACE: + if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WHITESPACE: + if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_NOT_WORDCHAR: + if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); + break; + + case OP_WORDCHAR: + if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + } + } + /* Control never gets here */ + } + + /* If maximizing it is worth using inline code for speed, doing the type + test once at the start (i.e. keep it out of the loop). Again, keep the + UTF-8 and UCP stuff separate. */ + + else + { + pp = eptr; /* Remember where we started */ + +#ifdef SUPPORT_UCP + if (prop_type > 0) + { + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if ((*prop_test_variable == prop_test_against) == prop_fail_result) + break; + eptr+= len; + } + + /* eptr is now past the end of the maximum run */ + + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + + /* Match extended Unicode sequences. We will get here only if the + support is in the binary; otherwise a compile-time error occurs. */ + + else if (ctype == OP_EXTUNI) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject) break; + GETCHARINCTEST(c, eptr); + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category == ucp_M) break; + while (eptr < md->end_subject) + { + int len = 1; + if (!md->utf8) c = *eptr; else + { + GETCHARLEN(c, eptr, len); + } + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category != ucp_M) break; + eptr += len; + } + } + + /* eptr is now past the end of the maximum run */ + + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + for (;;) /* Move back over one extended */ + { + int len = 1; + BACKCHAR(eptr); + if (!md->utf8) c = *eptr; else + { + GETCHARLEN(c, eptr, len); + } + prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); + if (prop_category != ucp_M) break; + eptr--; + } + } + } + + else +#endif /* SUPPORT_UCP */ + +#ifdef SUPPORT_UTF8 + /* UTF-8 mode */ + + if (md->utf8) + { + switch(ctype) + { + case OP_ANY: + + /* Special code is required for UTF8, but when the maximum is unlimited + we don't need it, so we repeat the non-UTF8 code. This is probably + worth it, because .* is quite a common idiom. */ + + if (max < INT_MAX) + { + if ((ims & PCRE_DOTALL) == 0) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || *eptr == NEWLINE) break; + eptr++; + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + } + } + else + { + for (i = min; i < max; i++) + { + eptr++; + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + } + } + } + + /* Handle unlimited UTF-8 repeat */ + + else + { + if ((ims & PCRE_DOTALL) == 0) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || *eptr == NEWLINE) break; + eptr++; + } + break; + } + else + { + c = max - min; + if (c > md->end_subject - eptr) c = md->end_subject - eptr; + eptr += c; + } + } + break; + + /* The byte case is the same as non-UTF8 */ + + case OP_ANYBYTE: + c = max - min; + if (c > md->end_subject - eptr) c = md->end_subject - eptr; + eptr += c; + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break; + eptr+= len; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break; + eptr+= len; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break; + eptr+= len; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break; + eptr+= len; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + int len = 1; + if (eptr >= md->end_subject) break; + GETCHARLEN(c, eptr, len); + if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break; + eptr+= len; + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run */ + + for(;;) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (eptr-- == pp) break; /* Stop if tried at original pos */ + BACKCHAR(eptr); + } + } + else +#endif + + /* Not UTF-8 mode */ + { + switch(ctype) + { + case OP_ANY: + if ((ims & PCRE_DOTALL) == 0) + { + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || *eptr == NEWLINE) break; + eptr++; + } + break; + } + /* For DOTALL case, fall through and treat as \C */ + + case OP_ANYBYTE: + c = max - min; + if (c > md->end_subject - eptr) c = md->end_subject - eptr; + eptr += c; + break; + + case OP_NOT_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0) + break; + eptr++; + } + break; + + case OP_DIGIT: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0) + break; + eptr++; + } + break; + + case OP_NOT_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0) + break; + eptr++; + } + break; + + case OP_WHITESPACE: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0) + break; + eptr++; + } + break; + + case OP_NOT_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0) + break; + eptr++; + } + break; + + case OP_WORDCHAR: + for (i = min; i < max; i++) + { + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0) + break; + eptr++; + } + break; + + default: + RRETURN(PCRE_ERROR_INTERNAL); + } + + /* eptr is now past the end of the maximum run */ + + while (eptr >= pp) + { + RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); + eptr--; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + } + } + + /* Get here if we can't make it match with any permitted repetitions */ + + RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + + /* There's been some horrible disaster. Since all codes > OP_BRA are + for capturing brackets, and there shouldn't be any gaps between 0 and + OP_BRA, arrival here can only mean there is something seriously wrong + in the code above or the OP_xxx definitions. */ + + default: + DPRINTF(("Unknown opcode %d\n", *ecode)); + RRETURN(PCRE_ERROR_UNKNOWN_NODE); + } + + /* Do not stick any code in here without much thought; it is assumed + that "continue" in the code above comes out to here to repeat the main + loop. */ + + } /* End of main loop */ +/* Control never reaches here */ +} + + +/*************************************************************************** +**************************************************************************** + RECURSION IN THE match() FUNCTION + +Undefine all the macros that were defined above to handle this. */ + +#ifdef NO_RECURSE +#undef eptr +#undef ecode +#undef offset_top +#undef ims +#undef eptrb +#undef flags + +#undef callpat +#undef charptr +#undef data +#undef next +#undef pp +#undef prev +#undef saved_eptr + +#undef new_recursive + +#undef cur_is_word +#undef condition +#undef minimize +#undef prev_is_word + +#undef original_ims + +#undef ctype +#undef length +#undef max +#undef min +#undef number +#undef offset +#undef op +#undef save_capture_last +#undef save_offset1 +#undef save_offset2 +#undef save_offset3 +#undef stacksave + +#undef newptrb + +#endif + +/* These two are defined as macros in both cases */ + +#undef fc +#undef fi + +/*************************************************************************** +***************************************************************************/ + + + +/************************************************* +* Execute a Regular Expression * +*************************************************/ + +/* This function applies a compiled re to a subject string and picks out +portions of the string if it matches. Two elements in the vector are set for +each substring: the offsets to the start and end of the substring. + +Arguments: + argument_re points to the compiled expression + extra_data points to extra data or is NULL + subject points to the subject string + length length of subject string (may contain binary zeros) + start_offset where to start in the subject string + options option bits + offsets points to a vector of ints to be filled in with offsets + offsetcount the number of elements in the vector + +Returns: > 0 => success; value is the number of elements filled in + = 0 => success, but offsets is not big enough + -1 => failed to match + < -1 => some kind of unexpected problem +*/ + +EXPORT int +pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, + const char *subject, int length, int start_offset, int options, int *offsets, + int offsetcount) +{ +int rc, resetcount, ocount; +int first_byte = -1; +int req_byte = -1; +int req_byte2 = -1; +unsigned long int ims = 0; +BOOL using_temporary_offsets = FALSE; +BOOL anchored; +BOOL startline; +BOOL first_byte_caseless = FALSE; +BOOL req_byte_caseless = FALSE; +match_data match_block; +const uschar *tables; +const uschar *start_bits = NULL; +const uschar *start_match = (const uschar *)subject + start_offset; +const uschar *end_subject; +const uschar *req_byte_ptr = start_match - 1; + +pcre_study_data internal_study; +const pcre_study_data *study; + +real_pcre internal_re; +const real_pcre *external_re = (const real_pcre *)argument_re; +const real_pcre *re = external_re; + +/* Plausibility checks */ + +if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; +if (re == NULL || subject == NULL || + (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; +if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; + +/* Fish out the optional data from the extra_data structure, first setting +the default values. */ + +study = NULL; +match_block.match_limit = MATCH_LIMIT; +match_block.callout_data = NULL; + +/* The table pointer is always in native byte order. */ + +tables = external_re->tables; + +if (extra_data != NULL) + { + register unsigned int flags = extra_data->flags; + if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) + study = (const pcre_study_data *)extra_data->study_data; + if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) + match_block.match_limit = extra_data->match_limit; + if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) + match_block.callout_data = extra_data->callout_data; + if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; + } + +/* If the exec call supplied NULL for tables, use the inbuilt ones. This +is a feature that makes it possible to save compiled regex and re-use them +in other programs later. */ + +if (tables == NULL) tables = pcre_default_tables; + +/* Check that the first field in the block is the magic number. If it is not, +test for a regex that was compiled on a host of opposite endianness. If this is +the case, flipped values are put in internal_re and internal_study if there was +study data too. */ + +if (re->magic_number != MAGIC_NUMBER) + { + re = try_flipped(re, &internal_re, study, &internal_study); + if (re == NULL) return PCRE_ERROR_BADMAGIC; + if (study != NULL) study = &internal_study; + } + +/* Set up other data */ + +anchored = ((re->options | options) & PCRE_ANCHORED) != 0; +startline = (re->options & PCRE_STARTLINE) != 0; + +/* The code starts after the real_pcre block and the capture name table. */ + +match_block.start_code = (const uschar *)external_re + re->name_table_offset + + re->name_count * re->name_entry_size; + +match_block.start_subject = (const uschar *)subject; +match_block.start_offset = start_offset; +match_block.end_subject = match_block.start_subject + length; +end_subject = match_block.end_subject; + +match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; +match_block.utf8 = (re->options & PCRE_UTF8) != 0; + +match_block.notbol = (options & PCRE_NOTBOL) != 0; +match_block.noteol = (options & PCRE_NOTEOL) != 0; +match_block.notempty = (options & PCRE_NOTEMPTY) != 0; +match_block.partial = (options & PCRE_PARTIAL) != 0; +match_block.hitend = FALSE; + +match_block.recursive = NULL; /* No recursion at top level */ + +match_block.lcc = tables + lcc_offset; +match_block.ctypes = tables + ctypes_offset; + +/* Partial matching is supported only for a restricted set of regexes at the +moment. */ + +if (match_block.partial && (re->options & PCRE_NOPARTIAL) != 0) + return PCRE_ERROR_BADPARTIAL; + +/* Check a UTF-8 string if required. Unfortunately there's no way of passing +back the character offset. */ + +#ifdef SUPPORT_UTF8 +if (match_block.utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) + { + if (valid_utf8((uschar *)subject, length) >= 0) + return PCRE_ERROR_BADUTF8; + if (start_offset > 0 && start_offset < length) + { + int tb = ((uschar *)subject)[start_offset]; + if (tb > 127) + { + tb &= 0xc0; + if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET; + } + } + } +#endif + +/* The ims options can vary during the matching as a result of the presence +of (?ims) items in the pattern. They are kept in a local variable so that +restoring at the exit of a group is easy. */ + +ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); + +/* If the expression has got more back references than the offsets supplied can +hold, we get a temporary chunk of working store to use during the matching. +Otherwise, we can use the vector supplied, rounding down its size to a multiple +of 3. */ + +ocount = offsetcount - (offsetcount % 3); + +if (re->top_backref > 0 && re->top_backref >= ocount/3) + { + ocount = re->top_backref * 3 + 3; + match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); + if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY; + using_temporary_offsets = TRUE; + DPRINTF(("Got memory to hold back references\n")); + } +else match_block.offset_vector = offsets; + +match_block.offset_end = ocount; +match_block.offset_max = (2*ocount)/3; +match_block.offset_overflow = FALSE; +match_block.capture_last = -1; + +/* Compute the minimum number of offsets that we need to reset each time. Doing +this makes a huge difference to execution time when there aren't many brackets +in the pattern. */ + +resetcount = 2 + re->top_bracket * 2; +if (resetcount > offsetcount) resetcount = ocount; + +/* Reset the working variable associated with each extraction. These should +never be used unless previously set, but they get saved and restored, and so we +initialize them to avoid reading uninitialized locations. */ + +if (match_block.offset_vector != NULL) + { + register int *iptr = match_block.offset_vector + ocount; + register int *iend = iptr - resetcount/2 + 1; + while (--iptr >= iend) *iptr = -1; + } + +/* Set up the first character to match, if available. The first_byte value is +never set for an anchored regular expression, but the anchoring may be forced +at run time, so we have to test for anchoring. The first char may be unset for +an unanchored pattern, of course. If there's no first char and the pattern was +studied, there may be a bitmap of possible first characters. */ + +if (!anchored) + { + if ((re->options & PCRE_FIRSTSET) != 0) + { + first_byte = re->first_byte & 255; + if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) + first_byte = match_block.lcc[first_byte]; + } + else + if (!startline && study != NULL && + (study->options & PCRE_STUDY_MAPPED) != 0) + start_bits = study->start_bits; + } + +/* For anchored or unanchored matches, there may be a "last known required +character" set. */ + +if ((re->options & PCRE_REQCHSET) != 0) + { + req_byte = re->req_byte & 255; + req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; + req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ + } + +/* Loop for handling unanchored repeated matching attempts; for anchored regexs +the loop runs just once. */ + +do + { + /* Reset the maximum number of extractions we might see. */ + + if (match_block.offset_vector != NULL) + { + register int *iptr = match_block.offset_vector; + register int *iend = iptr + resetcount; + while (iptr < iend) *iptr++ = -1; + } + + /* Advance to a unique first char if possible */ + + if (first_byte >= 0) + { + if (first_byte_caseless) + while (start_match < end_subject && + match_block.lcc[*start_match] != first_byte) + start_match++; + else + while (start_match < end_subject && *start_match != first_byte) + start_match++; + } + + /* Or to just after \n for a multiline match if possible */ + + else if (startline) + { + if (start_match > match_block.start_subject + start_offset) + { + while (start_match < end_subject && start_match[-1] != NEWLINE) + start_match++; + } + } + + /* Or to a non-unique first char after study */ + + else if (start_bits != NULL) + { + while (start_match < end_subject) + { + register unsigned int c = *start_match; + if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break; + } + } + +#ifdef DEBUG /* Sigh. Some compilers never learn. */ + printf(">>>> Match against: "); + pchars(start_match, end_subject - start_match, TRUE, &match_block); + printf("\n"); +#endif + + /* If req_byte is set, we know that that character must appear in the subject + for the match to succeed. If the first character is set, req_byte must be + later in the subject; otherwise the test starts at the match point. This + optimization can save a huge amount of backtracking in patterns with nested + unlimited repeats that aren't going to match. Writing separate code for + cased/caseless versions makes it go faster, as does using an autoincrement + and backing off on a match. + + HOWEVER: when the subject string is very, very long, searching to its end can + take a long time, and give bad performance on quite ordinary patterns. This + showed up when somebody was matching /^C/ on a 32-megabyte string... so we + don't do this when the string is sufficiently long. + + ALSO: this processing is disabled when partial matching is requested. + */ + + if (req_byte >= 0 && + end_subject - start_match < REQ_BYTE_MAX && + !match_block.partial) + { + register const uschar *p = start_match + ((first_byte >= 0)? 1 : 0); + + /* We don't need to repeat the search if we haven't yet reached the + place we found it at last time. */ + + if (p > req_byte_ptr) + { + if (req_byte_caseless) + { + while (p < end_subject) + { + register int pp = *p++; + if (pp == req_byte || pp == req_byte2) { p--; break; } + } + } + else + { + while (p < end_subject) + { + if (*p++ == req_byte) { p--; break; } + } + } + + /* If we can't find the required character, break the matching loop */ + + if (p >= end_subject) break; + + /* If we have found the required character, save the point where we + found it, so that we don't search again next time round the loop if + the start hasn't passed this character yet. */ + + req_byte_ptr = p; + } + } + + /* When a match occurs, substrings will be set for all internal extractions; + we just need to set up the whole thing as substring 0 before returning. If + there were too many extractions, set the return code to zero. In the case + where we had to get some local store to hold offsets for backreferences, copy + those back references that we can. In this case there need not be overflow + if certain parts of the pattern were not used. */ + + match_block.start_match = start_match; + match_block.match_call_count = 0; + + rc = match(start_match, match_block.start_code, 2, &match_block, ims, NULL, + match_isgroup); + + if (rc == MATCH_NOMATCH) + { + start_match++; +#ifdef SUPPORT_UTF8 + if (match_block.utf8) + while(start_match < end_subject && (*start_match & 0xc0) == 0x80) + start_match++; +#endif + continue; + } + + if (rc != MATCH_MATCH) + { + DPRINTF((">>>> error: returning %d\n", rc)); + return rc; + } + + /* We have a match! Copy the offset information from temporary store if + necessary */ + + if (using_temporary_offsets) + { + if (offsetcount >= 4) + { + memcpy(offsets + 2, match_block.offset_vector + 2, + (offsetcount - 2) * sizeof(int)); + DPRINTF(("Copied offsets from temporary memory\n")); + } + if (match_block.end_offset_top > offsetcount) + match_block.offset_overflow = TRUE; + + DPRINTF(("Freeing temporary memory\n")); + (pcre_free)(match_block.offset_vector); + } + + rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2; + + if (offsetcount < 2) rc = 0; else + { + offsets[0] = start_match - match_block.start_subject; + offsets[1] = match_block.end_match_ptr - match_block.start_subject; + } + + DPRINTF((">>>> returning %d\n", rc)); + return rc; + } + +/* This "while" is the end of the "do" above */ + +while (!anchored && start_match <= end_subject); + +if (using_temporary_offsets) + { + DPRINTF(("Freeing temporary memory\n")); + (pcre_free)(match_block.offset_vector); + } + +if (match_block.partial && match_block.hitend) + { + DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); + return PCRE_ERROR_PARTIAL; + } +else + { + DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n")); + return PCRE_ERROR_NOMATCH; + } +} + +/* End of pcre.c */ diff --git a/trunk/srclib/pcre/pcre.def b/trunk/srclib/pcre/pcre.def new file mode 100644 index 0000000000..4f6c4bff40 --- /dev/null +++ b/trunk/srclib/pcre/pcre.def @@ -0,0 +1,22 @@ +EXPORTS + +pcre_malloc DATA +pcre_free DATA + +pcre_compile +pcre_copy_substring +pcre_exec +pcre_get_substring +pcre_get_substring_list +pcre_free_substring +pcre_free_substring_list +pcre_info +pcre_fullinfo +pcre_maketables +pcre_study +pcre_version + +regcomp +regexec +regerror +regfree diff --git a/trunk/srclib/pcre/pcre.dsp b/trunk/srclib/pcre/pcre.dsp new file mode 100644 index 0000000000..982d67923f --- /dev/null +++ b/trunk/srclib/pcre/pcre.dsp @@ -0,0 +1,193 @@ +# Microsoft Developer Studio Project File - Name="pcre" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=pcre - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pcre.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pcre.mak" CFG="pcre - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pcre - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "pcre - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pcre - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "LibR" +# PROP Intermediate_Dir "LibR" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /Zi /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibR/pcre_src" /FD /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "pcre - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "LibD" +# PROP Intermediate_Dir "LibD" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibD/pcre_src" /FD /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "pcre - Win32 Release" +# Name "pcre - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "*.c" +# Begin Source File + +SOURCE=.\dftables.exe + +!IF "$(CFG)" == "pcre - Win32 Release" + +# Begin Custom Build - Creating pcre chartables.c from dftables +InputPath=.\dftables.exe + +".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + .\dftables.exe chartables.c + +# End Custom Build + +!ELSEIF "$(CFG)" == "pcre - Win32 Debug" + +# Begin Custom Build - Creating pcre chartables.c from dftables +InputPath=.\dftables.exe + +".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + .\dftables.exe chartables.c + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\get.c +# End Source File +# Begin Source File + +SOURCE=.\maketables.c +# End Source File +# Begin Source File + +SOURCE=.\pcre.c +# End Source File +# Begin Source File + +SOURCE=.\study.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\config.hw + +!IF "$(CFG)" == "pcre - Win32 Release" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "pcre - Win32 Debug" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\internal.h +# End Source File +# Begin Source File + +SOURCE=.\pcre.hw + +!IF "$(CFG)" == "pcre - Win32 Release" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "pcre - Win32 Debug" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# End Target +# End Project diff --git a/trunk/srclib/pcre/pcre.hw b/trunk/srclib/pcre/pcre.hw new file mode 100644 index 0000000000..4534b6313a --- /dev/null +++ b/trunk/srclib/pcre/pcre.hw @@ -0,0 +1,239 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* In its original form, this is the .in file that is transformed by +"configure" into pcre.h. + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The file pcre.h is build by "configure" or copied from pcre.hw +Do not edit it; instead make changes to pcre.in and/or pcre.hw */ + +#define PCRE_MAJOR 5 +#define PCRE_MINOR 0 +#define PCRE_DATE 13-Sep-2004 + +/* Win32 uses DLL by default */ + +#ifdef _WIN32 +# ifdef PCRE_DEFINITION +# ifdef DLL_EXPORT +# define PCRE_DATA_SCOPE __declspec(dllexport) +# endif +# else +# ifndef PCRE_STATIC +# define PCRE_DATA_SCOPE extern __declspec(dllimport) +# endif +# endif +#endif +#ifndef PCRE_DATA_SCOPE +# define PCRE_DATA_SCOPE extern +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options */ + +#define PCRE_CASELESS 0x0001 +#define PCRE_MULTILINE 0x0002 +#define PCRE_DOTALL 0x0004 +#define PCRE_EXTENDED 0x0008 +#define PCRE_ANCHORED 0x0010 +#define PCRE_DOLLAR_ENDONLY 0x0020 +#define PCRE_EXTRA 0x0040 +#define PCRE_NOTBOL 0x0080 +#define PCRE_NOTEOL 0x0100 +#define PCRE_UNGREEDY 0x0200 +#define PCRE_NOTEMPTY 0x0400 +#define PCRE_UTF8 0x0800 +#define PCRE_NO_AUTO_CAPTURE 0x1000 +#define PCRE_NO_UTF8_CHECK 0x2000 +#define PCRE_AUTO_CALLOUT 0x4000 +#define PCRE_PARTIAL 0x8000 + +/* Exec-time and get/set-time error codes */ + +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_NODE (-5) +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) +#define PCRE_ERROR_BADUTF8_OFFSET (-11) +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTBYTE 4 +#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 +#define PCRE_INFO_NAMEENTRYSIZE 7 +#define PCRE_INFO_NAMECOUNT 8 +#define PCRE_INFO_NAMETABLE 9 +#define PCRE_INFO_STUDYSIZE 10 +#define PCRE_INFO_DEFAULT_TABLES 11 + +/* Request types for pcre_config() */ + +#define PCRE_CONFIG_UTF8 0 +#define PCRE_CONFIG_NEWLINE 1 +#define PCRE_CONFIG_LINK_SIZE 2 +#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 +#define PCRE_CONFIG_MATCH_LIMIT 4 +#define PCRE_CONFIG_STACKRECURSE 5 +#define PCRE_CONFIG_UNICODE_PROPERTIES 6 + +/* Bit flags for the pcre_extra structure */ + +#define PCRE_EXTRA_STUDY_DATA 0x0001 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#define PCRE_EXTRA_TABLES 0x0008 + +/* Types */ + +struct real_pcre; /* declaration; the definition is private */ +typedef struct real_pcre pcre; + +/* The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. */ + +typedef struct pcre_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ +} pcre_extra; + +/* The structure for passing out data via the pcre_callout_function. We use a +structure so that new fields can be added on the end in future versions, +without changing the API of the function, thereby allowing old clients to work +without modification. */ + +typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + const char *subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------------------------------------------------------ */ +} pcre_callout_block; + +/* Indirection for store get and free functions. These can be set to +alternative malloc/free functions if required. Special ones are used in the +non-recursive case for "frames". There is also an optional callout function +that is triggered by the (?) regex item. Some magic is required for Win32 DLL; +it is null on other OS. For Virtual Pascal, these have to be different again. +*/ + +#ifndef VPCOMPAT +PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t); +PCRE_DATA_SCOPE void (*pcre_free)(void *); +PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t); +PCRE_DATA_SCOPE void (*pcre_stack_free)(void *); +PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *); +#else /* VPCOMPAT */ +extern void *pcre_malloc(size_t); +extern void pcre_free(void *); +extern void *pcre_stack_malloc(size_t); +extern void pcre_stack_free(void *); +extern int pcre_callout(pcre_callout_block *); +#endif /* VPCOMPAT */ + +/* Exported PCRE functions */ + +extern pcre *pcre_compile(const char *, int, const char **, + int *, const unsigned char *); +extern int pcre_config(int, void *); +extern int pcre_copy_named_substring(const pcre *, const char *, + int *, int, const char *, char *, int); +extern int pcre_copy_substring(const char *, int *, int, int, + char *, int); +extern int pcre_exec(const pcre *, const pcre_extra *, + const char *, int, int, int, int *, int); +extern void pcre_free_substring(const char *); +extern void pcre_free_substring_list(const char **); +extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, + void *); +extern int pcre_get_named_substring(const pcre *, const char *, + int *, int, const char *, const char **); +extern int pcre_get_stringnumber(const pcre *, const char *); +extern int pcre_get_substring(const char *, int *, int, int, + const char **); +extern int pcre_get_substring_list(const char *, int *, int, + const char ***); +extern int pcre_info(const pcre *, int *, int *); +extern const unsigned char *pcre_maketables(void); +extern pcre_extra *pcre_study(const pcre *, int, const char **); +extern const char *pcre_version(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/trunk/srclib/pcre/pcre.in b/trunk/srclib/pcre/pcre.in new file mode 100644 index 0000000000..163cf94be2 --- /dev/null +++ b/trunk/srclib/pcre/pcre.in @@ -0,0 +1,239 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* In its original form, this is the .in file that is transformed by +"configure" into pcre.h. + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The file pcre.h is build by "configure". Do not edit it; instead +make changes to pcre.in. */ + +#define PCRE_MAJOR @PCRE_MAJOR@ +#define PCRE_MINOR @PCRE_MINOR@ +#define PCRE_DATE @PCRE_DATE@ + +/* Win32 uses DLL by default */ + +#ifdef _WIN32 +# ifdef PCRE_DEFINITION +# ifdef DLL_EXPORT +# define PCRE_DATA_SCOPE __declspec(dllexport) +# endif +# else +# ifndef PCRE_STATIC +# define PCRE_DATA_SCOPE extern __declspec(dllimport) +# endif +# endif +#endif +#ifndef PCRE_DATA_SCOPE +# define PCRE_DATA_SCOPE extern +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options */ + +#define PCRE_CASELESS 0x0001 +#define PCRE_MULTILINE 0x0002 +#define PCRE_DOTALL 0x0004 +#define PCRE_EXTENDED 0x0008 +#define PCRE_ANCHORED 0x0010 +#define PCRE_DOLLAR_ENDONLY 0x0020 +#define PCRE_EXTRA 0x0040 +#define PCRE_NOTBOL 0x0080 +#define PCRE_NOTEOL 0x0100 +#define PCRE_UNGREEDY 0x0200 +#define PCRE_NOTEMPTY 0x0400 +#define PCRE_UTF8 0x0800 +#define PCRE_NO_AUTO_CAPTURE 0x1000 +#define PCRE_NO_UTF8_CHECK 0x2000 +#define PCRE_AUTO_CALLOUT 0x4000 +#define PCRE_PARTIAL 0x8000 + +/* Exec-time and get/set-time error codes */ + +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_NODE (-5) +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) +#define PCRE_ERROR_BADUTF8_OFFSET (-11) +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTBYTE 4 +#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 +#define PCRE_INFO_NAMEENTRYSIZE 7 +#define PCRE_INFO_NAMECOUNT 8 +#define PCRE_INFO_NAMETABLE 9 +#define PCRE_INFO_STUDYSIZE 10 +#define PCRE_INFO_DEFAULT_TABLES 11 + +/* Request types for pcre_config() */ + +#define PCRE_CONFIG_UTF8 0 +#define PCRE_CONFIG_NEWLINE 1 +#define PCRE_CONFIG_LINK_SIZE 2 +#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 +#define PCRE_CONFIG_MATCH_LIMIT 4 +#define PCRE_CONFIG_STACKRECURSE 5 +#define PCRE_CONFIG_UNICODE_PROPERTIES 6 + +/* Bit flags for the pcre_extra structure */ + +#define PCRE_EXTRA_STUDY_DATA 0x0001 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#define PCRE_EXTRA_TABLES 0x0008 + +/* Types */ + +struct real_pcre; /* declaration; the definition is private */ +typedef struct real_pcre pcre; + +/* The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. */ + +typedef struct pcre_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ +} pcre_extra; + +/* The structure for passing out data via the pcre_callout_function. We use a +structure so that new fields can be added on the end in future versions, +without changing the API of the function, thereby allowing old clients to work +without modification. */ + +typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + const char *subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------------------------------------------------------ */ +} pcre_callout_block; + +/* Indirection for store get and free functions. These can be set to +alternative malloc/free functions if required. Special ones are used in the +non-recursive case for "frames". There is also an optional callout function +that is triggered by the (?) regex item. Some magic is required for Win32 DLL; +it is null on other OS. For Virtual Pascal, these have to be different again. +*/ + +#ifndef VPCOMPAT +PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t); +PCRE_DATA_SCOPE void (*pcre_free)(void *); +PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t); +PCRE_DATA_SCOPE void (*pcre_stack_free)(void *); +PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *); +#else /* VPCOMPAT */ +extern void *pcre_malloc(size_t); +extern void pcre_free(void *); +extern void *pcre_stack_malloc(size_t); +extern void pcre_stack_free(void *); +extern int pcre_callout(pcre_callout_block *); +#endif /* VPCOMPAT */ + +/* Exported PCRE functions */ + +extern pcre *pcre_compile(const char *, int, const char **, + int *, const unsigned char *); +extern int pcre_config(int, void *); +extern int pcre_copy_named_substring(const pcre *, const char *, + int *, int, const char *, char *, int); +extern int pcre_copy_substring(const char *, int *, int, int, + char *, int); +extern int pcre_exec(const pcre *, const pcre_extra *, + const char *, int, int, int, int *, int); +extern void pcre_free_substring(const char *); +extern void pcre_free_substring_list(const char **); +extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, + void *); +extern int pcre_get_named_substring(const pcre *, const char *, + int *, int, const char *, const char **); +extern int pcre_get_stringnumber(const pcre *, const char *); +extern int pcre_get_substring(const char *, int *, int, int, + const char **); +extern int pcre_get_substring_list(const char *, int *, int, + const char ***); +extern int pcre_info(const pcre *, int *, int *); +extern const unsigned char *pcre_maketables(void); +extern pcre_extra *pcre_study(const pcre *, int, const char **); +extern const char *pcre_version(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/trunk/srclib/pcre/pcredemo.c b/trunk/srclib/pcre/pcredemo.c new file mode 100644 index 0000000000..3817203b5f --- /dev/null +++ b/trunk/srclib/pcre/pcredemo.c @@ -0,0 +1,324 @@ +/************************************************* +* PCRE DEMONSTRATION PROGRAM * +*************************************************/ + +/* This is a demonstration program to illustrate the most straightforward ways +of calling the PCRE regular expression library from a C program. See the +pcresample documentation for a short discussion. + +Compile thuswise: + gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \ + -R/usr/local/lib -lpcre + +Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and +library files for PCRE are installed on your system. Only some operating +systems (e.g. Solaris) use the -R option. +*/ + + +#include +#include +#include + +#define OVECCOUNT 30 /* should be a multiple of 3 */ + + +int main(int argc, char **argv) +{ +pcre *re; +const char *error; +char *pattern; +char *subject; +unsigned char *name_table; +int erroffset; +int find_all; +int namecount; +int name_entry_size; +int ovector[OVECCOUNT]; +int subject_length; +int rc, i; + + +/************************************************************************** +* First, sort out the command line. There is only one possible option at * +* the moment, "-g" to request repeated matching to find all occurrences, * +* like Perl's /g option. We set the variable find_all to a non-zero value * +* if the -g option is present. Apart from that, there must be exactly two * +* arguments. * +**************************************************************************/ + +find_all = 0; +for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-g") == 0) find_all = 1; + else break; + } + +/* After the options, we require exactly two arguments, which are the pattern, +and the subject string. */ + +if (argc - i != 2) + { + printf("Two arguments required: a regex and a subject string\n"); + return 1; + } + +pattern = argv[i]; +subject = argv[i+1]; +subject_length = (int)strlen(subject); + + +/************************************************************************* +* Now we are going to compile the regular expression pattern, and handle * +* and errors that are detected. * +*************************************************************************/ + +re = pcre_compile( + pattern, /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ + +/* Compilation failed: print the error message and exit */ + +if (re == NULL) + { + printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); + return 1; + } + + +/************************************************************************* +* If the compilation succeeded, we call PCRE again, in order to do a * +* pattern match against the subject string. This does just ONE match. If * +* further matching is needed, it will be done below. * +*************************************************************************/ + +rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + +/* Matching failed: handle error cases */ + +if (rc < 0) + { + switch(rc) + { + case PCRE_ERROR_NOMATCH: printf("No match\n"); break; + /* + Handle other special cases if you like + */ + default: printf("Matching error %d\n", rc); break; + } + free(re); /* Release memory used for the compiled pattern */ + return 1; + } + +/* Match succeded */ + +printf("\nMatch succeeded at offset %d\n", ovector[0]); + + +/************************************************************************* +* We have found the first match within the subject string. If the output * +* vector wasn't big enough, set its size to the maximum. Then output any * +* substrings that were captured. * +*************************************************************************/ + +/* The output vector wasn't big enough */ + +if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\n", rc - 1); + } + +/* Show substrings stored in the output vector by number. Obviously, in a real +application you might want to do things other than print them. */ + +for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, substring_length, substring_start); + } + + +/************************************************************************** +* That concludes the basic part of this demonstration program. We have * +* compiled a pattern, and performed a single match. The code that follows * +* first shows how to access named substrings, and then how to code for * +* repeated matches on the same subject. * +**************************************************************************/ + +/* See if there are any named substrings, and if so, show them by name. First +we have to extract the count of named parentheses from the pattern. */ + +(void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMECOUNT, /* number of named substrings */ + &namecount); /* where to put the answer */ + +if (namecount <= 0) printf("No named substrings\n"); else + { + unsigned char *tabptr; + printf("Named substrings\n"); + + /* Before we can access the substrings, we must extract the table for + translating names to numbers, and the size of each entry in the table. */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMETABLE, /* address of the table */ + &name_table); /* where to put the answer */ + + (void)pcre_fullinfo( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ + &name_entry_size); /* where to put the answer */ + + /* Now we can scan the table and, for each entry, print the number, the name, + and the substring itself. */ + + tabptr = name_table; + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + + +/************************************************************************* +* If the "-g" option was given on the command line, we want to continue * +* to search for additional matches in the subject string, in a similar * +* way to the /g option in Perl. This turns out to be trickier than you * +* might think because of the possibility of matching an empty string. * +* What happens is as follows: * +* * +* If the previous match was NOT for an empty string, we can just start * +* the next match at the end of the previous one. * +* * +* If the previous match WAS for an empty string, we can't do that, as it * +* would lead to an infinite loop. Instead, a special call of pcre_exec() * +* is made with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set. The first * +* of these tells PCRE that an empty string is not a valid match; other * +* possibilities must be tried. The second flag restricts PCRE to one * +* match attempt at the initial string position. If this match succeeds, * +* an alternative to the empty string match has been found, and we can * +* proceed round the loop. * +*************************************************************************/ + +if (!find_all) + { + free(re); /* Release the memory used for the compiled pattern */ + return 0; /* Finish unless -g was given */ + } + +/* Loop for second and subsequent matches */ + +for (;;) + { + int options = 0; /* Normally no options */ + int start_offset = ovector[1]; /* Start at end of previous match */ + + /* If the previous match was for an empty string, we are finished if we are + at the end of the subject. Otherwise, arrange to run another match at the + same point to see if a non-empty match can be found. */ + + if (ovector[0] == ovector[1]) + { + if (ovector[0] == subject_length) break; + options = PCRE_NOTEMPTY | PCRE_ANCHORED; + } + + /* Run the next matching operation */ + + rc = pcre_exec( + re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + subject, /* the subject string */ + subject_length, /* the length of the subject */ + start_offset, /* starting offset in the subject */ + options, /* options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + + /* This time, a result of NOMATCH isn't an error. If the value in "options" + is zero, it just means we have found all possible matches, so the loop ends. + Otherwise, it means we have failed to find a non-empty-string match at a + point where there was a previous empty-string match. In this case, we do what + Perl does: advance the matching position by one, and continue. We do this by + setting the "end of previous match" offset, because that is picked up at the + top of the loop as the point at which to start again. */ + + if (rc == PCRE_ERROR_NOMATCH) + { + if (options == 0) break; + ovector[1] = start_offset + 1; + continue; /* Go round the loop again */ + } + + /* Other matching errors are not recoverable. */ + + if (rc < 0) + { + printf("Matching error %d\n", rc); + free(re); /* Release memory used for the compiled pattern */ + return 1; + } + + /* Match succeded */ + + printf("\nMatch succeeded again at offset %d\n", ovector[0]); + + /* The match succeeded, but the output vector wasn't big enough. */ + + if (rc == 0) + { + rc = OVECCOUNT/3; + printf("ovector only has room for %d captured substrings\n", rc - 1); + } + + /* As before, show substrings stored in the output vector by number, and then + also any named substrings. */ + + for (i = 0; i < rc; i++) + { + char *substring_start = subject + ovector[2*i]; + int substring_length = ovector[2*i+1] - ovector[2*i]; + printf("%2d: %.*s\n", i, substring_length, substring_start); + } + + if (namecount <= 0) printf("No named substrings\n"); else + { + unsigned char *tabptr = name_table; + printf("Named substrings\n"); + for (i = 0; i < namecount; i++) + { + int n = (tabptr[0] << 8) | tabptr[1]; + printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, + ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); + tabptr += name_entry_size; + } + } + } /* End of loop to find second and subsequent matches */ + +printf("\n"); +free(re); /* Release memory used for the compiled pattern */ +return 0; +} + +/* End of pcredemo.c */ diff --git a/trunk/srclib/pcre/pcregrep.c b/trunk/srclib/pcre/pcregrep.c new file mode 100644 index 0000000000..21b2a9bbae --- /dev/null +++ b/trunk/srclib/pcre/pcregrep.c @@ -0,0 +1,673 @@ +/************************************************* +* pcregrep program * +*************************************************/ + +/* This is a grep program that uses the PCRE regular expression library to do +its pattern matching. On a Unix or Win32 system it can recurse into +directories. + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include "config.h" +#include "pcre.h" + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; + +#define VERSION "3.0 14-Jan-2003" +#define MAX_PATTERN_COUNT 100 + + +/************************************************* +* Global variables * +*************************************************/ + +static char *pattern_filename = NULL; +static int pattern_count = 0; +static pcre **pattern_list; +static pcre_extra **hints_list; + +static BOOL count_only = FALSE; +static BOOL filenames = TRUE; +static BOOL filenames_only = FALSE; +static BOOL invert = FALSE; +static BOOL number = FALSE; +static BOOL recurse = FALSE; +static BOOL silent = FALSE; +static BOOL whole_lines = FALSE; + +/* Structure for options and list of them */ + +typedef struct option_item { + int one_char; + const char *long_name; + const char *help_text; +} option_item; + +static option_item optionlist[] = { + { -1, "help", "display this help and exit" }, + { 'c', "count", "print only a count of matching lines per FILE" }, + { 'h', "no-filename", "suppress the prefixing filename on output" }, + { 'i', "ignore-case", "ignore case distinctions" }, + { 'l', "files-with-matches", "print only FILE names containing matches" }, + { 'n', "line-number", "print line number with output lines" }, + { 'r', "recursive", "recursively scan sub-directories" }, + { 's', "no-messages", "suppress error messages" }, + { 'u', "utf-8", "use UTF-8 mode" }, + { 'V', "version", "print version information and exit" }, + { 'v', "invert-match", "select non-matching lines" }, + { 'x', "line-regex", "force PATTERN to match only whole lines" }, + { 'x', "line-regexp", "force PATTERN to match only whole lines" }, + { 0, NULL, NULL } +}; + + +/************************************************* +* Functions for directory scanning * +*************************************************/ + +/* These functions are defined so that they can be made system specific, +although at present the only ones are for Unix, Win32, and for "no directory +recursion support". */ + + +/************* Directory scanning in Unix ***********/ + +#if IS_UNIX +#include +#include +#include + +typedef DIR directory_type; + +static int +isdirectory(char *filename) +{ +struct stat statbuf; +if (stat(filename, &statbuf) < 0) + return 0; /* In the expectation that opening as a file will fail */ +return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0; +} + +static directory_type * +opendirectory(char *filename) +{ +return opendir(filename); +} + +static char * +readdirectory(directory_type *dir) +{ +for (;;) + { + struct dirent *dent = readdir(dir); + if (dent == NULL) return NULL; + if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) + return dent->d_name; + } +return NULL; /* Keep compiler happy; never executed */ +} + +static void +closedirectory(directory_type *dir) +{ +closedir(dir); +} + + +/************* Directory scanning in Win32 ***********/ + +/* I (Philip Hazel) have no means of testing this code. It was contributed by +Lionel Fourquaux. */ + + +#elif HAVE_WIN32API + +#ifndef STRICT +# define STRICT +#endif +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +typedef struct directory_type +{ +HANDLE handle; +BOOL first; +WIN32_FIND_DATA data; +} directory_type; + +int +isdirectory(char *filename) +{ +DWORD attr = GetFileAttributes(filename); +if (attr == INVALID_FILE_ATTRIBUTES) + return 0; +return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0; +} + +directory_type * +opendirectory(char *filename) +{ +size_t len; +char *pattern; +directory_type *dir; +DWORD err; +len = strlen(filename); +pattern = (char *) malloc(len + 3); +dir = (directory_type *) malloc(sizeof(*dir)); +if ((pattern == NULL) || (dir == NULL)) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + exit(2); + } +memcpy(pattern, filename, len); +memcpy(&(pattern[len]), "\\*", 3); +dir->handle = FindFirstFile(pattern, &(dir->data)); +if (dir->handle != INVALID_HANDLE_VALUE) + { + free(pattern); + dir->first = TRUE; + return dir; + } +err = GetLastError(); +free(pattern); +free(dir); +errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; +return NULL; +} + +char * +readdirectory(directory_type *dir) +{ +for (;;) + { + if (!dir->first) + { + if (!FindNextFile(dir->handle, &(dir->data))) + return NULL; + } + else + { + dir->first = FALSE; + } + if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) + return dir->data.cFileName; + } +#ifndef _MSC_VER +return NULL; /* Keep compiler happy; never executed */ +#endif +} + +void +closedirectory(directory_type *dir) +{ +FindClose(dir->handle); +free(dir); +} + + +/************* Directory scanning when we can't do it ***********/ + +/* The type is void, and apart from isdirectory(), the functions do nothing. */ + +#else + +typedef void directory_type; + +int isdirectory(char *filename) { return FALSE; } +directory_type * opendirectory(char *filename) {} +char *readdirectory(directory_type *dir) {} +void closedirectory(directory_type *dir) {} + +#endif + + + +#if ! HAVE_STRERROR +/************************************************* +* Provide strerror() for non-ANSI libraries * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +* Grep an individual file * +*************************************************/ + +static int +pcregrep(FILE *in, char *name) +{ +int rc = 1; +int linenumber = 0; +int count = 0; +int offsets[99]; +char buffer[BUFSIZ]; + +while (fgets(buffer, sizeof(buffer), in) != NULL) + { + BOOL match = FALSE; + int i; + int length = (int)strlen(buffer); + if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0; + linenumber++; + + for (i = 0; !match && i < pattern_count; i++) + { + match = pcre_exec(pattern_list[i], hints_list[i], buffer, length, 0, 0, + offsets, 99) >= 0; + if (match && whole_lines && offsets[1] != length) match = FALSE; + } + + if (match != invert) + { + if (count_only) count++; + + else if (filenames_only) + { + fprintf(stdout, "%s\n", (name == NULL)? "" : name); + return 0; + } + + else if (silent) return 0; + + else + { + if (name != NULL) fprintf(stdout, "%s:", name); + if (number) fprintf(stdout, "%d:", linenumber); + fprintf(stdout, "%s\n", buffer); + } + + rc = 0; + } + } + +if (count_only) + { + if (name != NULL) fprintf(stdout, "%s:", name); + fprintf(stdout, "%d\n", count); + } + +return rc; +} + + + + +/************************************************* +* Grep a file or recurse into a directory * +*************************************************/ + +static int +grep_or_recurse(char *filename, BOOL dir_recurse, BOOL show_filenames, + BOOL only_one_at_top) +{ +int rc = 1; +int sep; +FILE *in; + +/* If the file is a directory and we are recursing, scan each file within it. +The scanning code is localized so it can be made system-specific. */ + +if ((sep = isdirectory(filename)) != 0 && dir_recurse) + { + char buffer[1024]; + char *nextfile; + directory_type *dir = opendirectory(filename); + + if (dir == NULL) + { + fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", filename, + strerror(errno)); + return 2; + } + + while ((nextfile = readdirectory(dir)) != NULL) + { + int frc; + sprintf(buffer, "%.512s%c%.128s", filename, sep, nextfile); + frc = grep_or_recurse(buffer, dir_recurse, TRUE, FALSE); + if (frc == 0 && rc == 1) rc = 0; + } + + closedirectory(dir); + return rc; + } + +/* If the file is not a directory, or we are not recursing, scan it. If this is +the first and only argument at top level, we don't show the file name (unless +we are only showing the file name). Otherwise, control is via the +show_filenames variable. */ + +in = fopen(filename, "r"); +if (in == NULL) + { + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", filename, strerror(errno)); + return 2; + } + +rc = pcregrep(in, (filenames_only || (show_filenames && !only_one_at_top))? + filename : NULL); +fclose(in); +return rc; +} + + + + +/************************************************* +* Usage function * +*************************************************/ + +static int +usage(int rc) +{ +fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] [pattern] [file1 file2 ...]\n"); +fprintf(stderr, "Type `pcregrep --help' for more information.\n"); +return rc; +} + + + + +/************************************************* +* Help function * +*************************************************/ + +static void +help(void) +{ +option_item *op; + +printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); +printf("Search for PATTERN in each FILE or standard input.\n"); +printf("PATTERN must be present if -f is not used.\n"); +printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); + +printf("Options:\n"); + +for (op = optionlist; op->one_char != 0; op++) + { + int n; + char s[4]; + if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " "); + printf(" %s --%s%n", s, op->long_name, &n); + n = 30 - n; + if (n < 1) n = 1; + printf("%.*s%s\n", n, " ", op->help_text); + } + +printf("\n -f or --file=\n"); +printf(" Read patterns from instead of using a command line option.\n"); +printf(" Trailing white space is removed; blanks lines are ignored.\n"); +printf(" There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT); + +printf("\nWith no FILE, read standard input. If fewer than two FILEs given, assume -h.\n"); +printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); +} + + + + +/************************************************* +* Handle an option * +*************************************************/ + +static int +handle_option(int letter, int options) +{ +switch(letter) + { + case -1: help(); exit(0); + case 'c': count_only = TRUE; break; + case 'h': filenames = FALSE; break; + case 'i': options |= PCRE_CASELESS; break; + case 'l': filenames_only = TRUE; + case 'n': number = TRUE; break; + case 'r': recurse = TRUE; break; + case 's': silent = TRUE; break; + case 'u': options |= PCRE_UTF8; break; + case 'v': invert = TRUE; break; + case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; + + case 'V': + fprintf(stderr, "pcregrep version %s using ", VERSION); + fprintf(stderr, "PCRE version %s\n", pcre_version()); + exit(0); + break; + + default: + fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); + exit(usage(2)); + } + +return options; +} + + + + +/************************************************* +* Main program * +*************************************************/ + +int +main(int argc, char **argv) +{ +int i, j; +int rc = 1; +int options = 0; +int errptr; +const char *error; +BOOL only_one_at_top; + +/* Process the options */ + +for (i = 1; i < argc; i++) + { + if (argv[i][0] != '-') break; + + /* Missing options */ + + if (argv[i][1] == 0) exit(usage(2)); + + /* Long name options */ + + if (argv[i][1] == '-') + { + option_item *op; + + if (strncmp(argv[i]+2, "file=", 5) == 0) + { + pattern_filename = argv[i] + 7; + continue; + } + + for (op = optionlist; op->one_char != 0; op++) + { + if (strcmp(argv[i]+2, op->long_name) == 0) + { + options = handle_option(op->one_char, options); + break; + } + } + if (op->one_char == 0) + { + fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]); + exit(usage(2)); + } + } + + /* One-char options */ + + else + { + char *s = argv[i] + 1; + while (*s != 0) + { + if (*s == 'f') + { + pattern_filename = s + 1; + if (pattern_filename[0] == 0) + { + if (i >= argc - 1) + { + fprintf(stderr, "pcregrep: File name missing after -f\n"); + exit(usage(2)); + } + pattern_filename = argv[++i]; + } + break; + } + else options = handle_option(*s++, options); + } + } + } + +pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *)); +hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *)); + +if (pattern_list == NULL || hints_list == NULL) + { + fprintf(stderr, "pcregrep: malloc failed\n"); + return 2; + } + +/* Compile the regular expression(s). */ + +if (pattern_filename != NULL) + { + FILE *f = fopen(pattern_filename, "r"); + char buffer[BUFSIZ]; + if (f == NULL) + { + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename, + strerror(errno)); + return 2; + } + while (fgets(buffer, sizeof(buffer), f) != NULL) + { + char *s = buffer + (int)strlen(buffer); + if (pattern_count >= MAX_PATTERN_COUNT) + { + fprintf(stderr, "pcregrep: Too many patterns in file (max %d)\n", + MAX_PATTERN_COUNT); + return 2; + } + while (s > buffer && isspace((unsigned char)(s[-1]))) s--; + if (s == buffer) continue; + *s = 0; + pattern_list[pattern_count] = pcre_compile(buffer, options, &error, + &errptr, NULL); + if (pattern_list[pattern_count++] == NULL) + { + fprintf(stderr, "pcregrep: Error in regex number %d at offset %d: %s\n", + pattern_count, errptr, error); + return 2; + } + } + fclose(f); + } + +/* If no file name, a single regex must be given inline */ + +else + { + if (i >= argc) return usage(2); + pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL); + if (pattern_list[0] == NULL) + { + fprintf(stderr, "pcregrep: Error in regex at offset %d: %s\n", errptr, + error); + return 2; + } + pattern_count++; + } + +/* Study the regular expressions, as we will be running them may times */ + +for (j = 0; j < pattern_count; j++) + { + hints_list[j] = pcre_study(pattern_list[j], 0, &error); + if (error != NULL) + { + char s[16]; + if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j); + fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error); + return 2; + } + } + +/* If there are no further arguments, do the business on stdin and exit */ + +if (i >= argc) return pcregrep(stdin, NULL); + +/* Otherwise, work through the remaining arguments as files or directories. +Pass in the fact that there is only one argument at top level - this suppresses +the file name if the argument is not a directory. */ + +only_one_at_top = (i == argc - 1); +if (filenames_only) filenames = TRUE; + +for (; i < argc; i++) + { + int frc = grep_or_recurse(argv[i], recurse, filenames, only_one_at_top); + if (frc == 0 && rc == 1) rc = 0; + } + +return rc; +} + +/* End */ diff --git a/trunk/srclib/pcre/pcreposix.c b/trunk/srclib/pcre/pcreposix.c new file mode 100644 index 0000000000..1e8b6a72b1 --- /dev/null +++ b/trunk/srclib/pcre/pcreposix.c @@ -0,0 +1,316 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +This module is a wrapper that provides a POSIX API to the underlying PCRE +functions. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + +#include "internal.h" +#include "pcreposix.h" +#include "stdlib.h" + + + +/* Corresponding tables of PCRE error messages and POSIX error codes. */ + +static const char *const estring[] = { + ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, + ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, + ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR29, ERR29, ERR30, + ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, + ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47 }; + +static const int eint[] = { + REG_EESCAPE, /* "\\ at end of pattern" */ + REG_EESCAPE, /* "\\c at end of pattern" */ + REG_EESCAPE, /* "unrecognized character follows \\" */ + REG_BADBR, /* "numbers out of order in {} quantifier" */ + REG_BADBR, /* "number too big in {} quantifier" */ + REG_EBRACK, /* "missing terminating ] for character class" */ + REG_ECTYPE, /* "invalid escape sequence in character class" */ + REG_ERANGE, /* "range out of order in character class" */ + REG_BADRPT, /* "nothing to repeat" */ + REG_BADRPT, /* "operand of unlimited repeat could match the empty string" */ + REG_ASSERT, /* "internal error: unexpected repeat" */ + REG_BADPAT, /* "unrecognized character after (?" */ + REG_BADPAT, /* "POSIX named classes are supported only within a class" */ + REG_EPAREN, /* "missing )" */ + REG_ESUBREG, /* "reference to non-existent subpattern" */ + REG_INVARG, /* "erroffset passed as NULL" */ + REG_INVARG, /* "unknown option bit(s) set" */ + REG_EPAREN, /* "missing ) after comment" */ + REG_ESIZE, /* "parentheses nested too deeply" */ + REG_ESIZE, /* "regular expression too large" */ + REG_ESPACE, /* "failed to get memory" */ + REG_EPAREN, /* "unmatched brackets" */ + REG_ASSERT, /* "internal error: code overflow" */ + REG_BADPAT, /* "unrecognized character after (?<" */ + REG_BADPAT, /* "lookbehind assertion is not fixed length" */ + REG_BADPAT, /* "malformed number after (?(" */ + REG_BADPAT, /* "conditional group containe more than two branches" */ + REG_BADPAT, /* "assertion expected after (?(" */ + REG_BADPAT, /* "(?R or (?digits must be followed by )" */ + REG_ECTYPE, /* "unknown POSIX class name" */ + REG_BADPAT, /* "POSIX collating elements are not supported" */ + REG_INVARG, /* "this version of PCRE is not compiled with PCRE_UTF8 support" */ + REG_BADPAT, /* "spare error" */ + REG_BADPAT, /* "character value in \x{...} sequence is too large" */ + REG_BADPAT, /* "invalid condition (?(0)" */ + REG_BADPAT, /* "\\C not allowed in lookbehind assertion" */ + REG_EESCAPE, /* "PCRE does not support \\L, \\l, \\N, \\U, or \\u" */ + REG_BADPAT, /* "number after (?C is > 255" */ + REG_BADPAT, /* "closing ) for (?C expected" */ + REG_BADPAT, /* "recursive call could loop indefinitely" */ + REG_BADPAT, /* "unrecognized character after (?P" */ + REG_BADPAT, /* "syntax error after (?P" */ + REG_BADPAT, /* "two named groups have the same name" */ + REG_BADPAT, /* "invalid UTF-8 string" */ + REG_BADPAT, /* "support for \\P, \\p, and \\X has not been compiled" */ + REG_BADPAT, /* "malformed \\P or \\p sequence" */ + REG_BADPAT /* "unknown property name after \\P or \\p" */ +}; + +/* Table of texts corresponding to POSIX error codes */ + +static const char *const pstring[] = { + "", /* Dummy for value 0 */ + "internal error", /* REG_ASSERT */ + "invalid repeat counts in {}", /* BADBR */ + "pattern error", /* BADPAT */ + "? * + invalid", /* BADRPT */ + "unbalanced {}", /* EBRACE */ + "unbalanced []", /* EBRACK */ + "collation error - not relevant", /* ECOLLATE */ + "bad class", /* ECTYPE */ + "bad escape sequence", /* EESCAPE */ + "empty expression", /* EMPTY */ + "unbalanced ()", /* EPAREN */ + "bad range inside []", /* ERANGE */ + "expression too big", /* ESIZE */ + "failed to get memory", /* ESPACE */ + "bad back reference", /* ESUBREG */ + "bad argument", /* INVARG */ + "match failed" /* NOMATCH */ +}; + + + + +/************************************************* +* Translate PCRE text code to int * +*************************************************/ + +/* PCRE compile-time errors are given as strings defined as macros. We can just +look them up in a table to turn them into POSIX-style error codes. */ + +static int +pcre_posix_error_code(const char *s) +{ +size_t i; +for (i = 0; i < sizeof(estring)/sizeof(char *); i++) + if (strcmp(s, estring[i]) == 0) return eint[i]; +return REG_ASSERT; +} + + + +/************************************************* +* Translate error code to string * +*************************************************/ + +EXPORT size_t +regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ +const char *message, *addmessage; +size_t length, addlength; + +message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? + "unknown error code" : pstring[errcode]; +length = strlen(message) + 1; + +addmessage = " at offset "; +addlength = (preg != NULL && (int)preg->re_erroffset != -1)? + strlen(addmessage) + 6 : 0; + +if (errbuf_size > 0) + { + if (addlength > 0 && errbuf_size >= length + addlength) + sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); + else + { + strncpy(errbuf, message, errbuf_size - 1); + errbuf[errbuf_size-1] = 0; + } + } + +return length + addlength; +} + + + + +/************************************************* +* Free store held by a regex * +*************************************************/ + +EXPORT void +regfree(regex_t *preg) +{ +(pcre_free)(preg->re_pcre); +} + + + + +/************************************************* +* Compile a regular expression * +*************************************************/ + +/* +Arguments: + preg points to a structure for recording the compiled expression + pattern the pattern to compile + cflags compilation flags + +Returns: 0 on success + various non-zero codes on failure +*/ + +EXPORT int +regcomp(regex_t *preg, const char *pattern, int cflags) +{ +const char *errorptr; +int erroffset; +int options = 0; + +if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS; +if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE; + +preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL); +preg->re_erroffset = erroffset; + +if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr); + +preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); +return 0; +} + + + + +/************************************************* +* Match a regular expression * +*************************************************/ + +/* Unfortunately, PCRE requires 3 ints of working space for each captured +substring, so we have to get and release working store instead of just using +the POSIX structures as was done in earlier releases when PCRE needed only 2 +ints. However, if the number of possible capturing brackets is small, use a +block of store on the stack, to reduce the use of malloc/free. The threshold is +in a macro that can be changed at configure time. */ + +EXPORT int +regexec(const regex_t *preg, const char *string, size_t nmatch, + regmatch_t pmatch[], int eflags) +{ +int rc; +int options = 0; +int *ovector = NULL; +int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; +BOOL allocated_ovector = FALSE; + +if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL; +if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL; + +((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ + +if (nmatch > 0) + { + if (nmatch <= POSIX_MALLOC_THRESHOLD) + { + ovector = &(small_ovector[0]); + } + else + { + ovector = (int *)malloc(sizeof(int) * nmatch * 3); + if (ovector == NULL) return REG_ESPACE; + allocated_ovector = TRUE; + } + } + +rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string), + 0, options, ovector, nmatch * 3); + +if (rc == 0) rc = nmatch; /* All captured slots were filled in */ + +if (rc >= 0) + { + size_t i; + for (i = 0; i < (size_t)rc; i++) + { + pmatch[i].rm_so = ovector[i*2]; + pmatch[i].rm_eo = ovector[i*2+1]; + } + if (allocated_ovector) free(ovector); + for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + return 0; + } + +else + { + if (allocated_ovector) free(ovector); + switch(rc) + { + case PCRE_ERROR_NOMATCH: return REG_NOMATCH; + case PCRE_ERROR_NULL: return REG_INVARG; + case PCRE_ERROR_BADOPTION: return REG_INVARG; + case PCRE_ERROR_BADMAGIC: return REG_INVARG; + case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT; + case PCRE_ERROR_NOMEMORY: return REG_ESPACE; + case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; + case PCRE_ERROR_BADUTF8: return REG_INVARG; + case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; + default: return REG_ASSERT; + } + } +} + +/* End of pcreposix.c */ diff --git a/trunk/srclib/pcre/pcreposix.dsp b/trunk/srclib/pcre/pcreposix.dsp new file mode 100644 index 0000000000..cddf6b5972 --- /dev/null +++ b/trunk/srclib/pcre/pcreposix.dsp @@ -0,0 +1,154 @@ +# Microsoft Developer Studio Project File - Name="pcreposix" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=pcreposix - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pcreposix.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pcreposix.mak" CFG="pcreposix - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pcreposix - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "pcreposix - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pcreposix - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "LibR" +# PROP Intermediate_Dir "LibR" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "..\..\include" /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibR/pcreposix_src" /FD /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "pcreposix - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "LibD" +# PROP Intermediate_Dir "LibD" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\..\include" /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibD/pcreposix_src" /FD /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "pcreposix - Win32 Release" +# Name "pcreposix - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "*.c" +# Begin Source File + +SOURCE=.\pcreposix.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\config.hw + +!IF "$(CFG)" == "pcreposix - Win32 Release" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "pcreposix - Win32 Debug" + +# Begin Custom Build - Creating pcre config.h from config.hw +InputPath=.\config.hw + +".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\config.hw > .\config.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\pcre.hw + +!IF "$(CFG)" == "pcreposix - Win32 Release" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ELSEIF "$(CFG)" == "pcreposix - Win32 Debug" + +# Begin Custom Build - Creating pcre.h from pcre.hw +InputPath=.\pcre.hw + +".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + type .\pcre.hw > .\pcre.h + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\include\pcreposix.h +# End Source File +# End Group +# End Target +# End Project diff --git a/trunk/srclib/pcre/pcretest.c b/trunk/srclib/pcre/pcretest.c new file mode 100644 index 0000000000..e531cc134e --- /dev/null +++ b/trunk/srclib/pcre/pcretest.c @@ -0,0 +1,1786 @@ +/************************************************* +* PCRE testing program * +*************************************************/ + +/* This program was hacked up as a tester for PCRE. I really should have +written it more tidily in the first place. Will I ever learn? It has grown and +been extended and consequently is now rather untidy in places. + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + + +#include +#include +#include +#include +#include +#include +#include + +/* We need the internal info for displaying the results of pcre_study(). Also +for getting the opcodes for showing compiled code. */ + +#define PCRE_SPY /* For Win32 build, import data, not export */ +#include "internal.h" + +/* It is possible to compile this test program without including support for +testing the POSIX interface, though this is not available via the standard +Makefile. */ + +#if !defined NOPOSIX +#include "pcreposix.h" +#endif + +#ifndef CLOCKS_PER_SEC +#ifdef CLK_TCK +#define CLOCKS_PER_SEC CLK_TCK +#else +#define CLOCKS_PER_SEC 100 +#endif +#endif + +#define LOOPREPEAT 500000 + +#define BUFFER_SIZE 30000 +#define PBUFFER_SIZE BUFFER_SIZE +#define DBUFFER_SIZE BUFFER_SIZE + + +static FILE *outfile; +static int log_store = 0; +static int callout_count; +static int callout_extra; +static int callout_fail_count; +static int callout_fail_id; +static int first_callout; +static int show_malloc; +static int use_utf8; +static size_t gotten_store; + +static uschar *pbuffer = NULL; + + +static const int utf8_table1[] = { + 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; + +static const int utf8_table2[] = { + 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; + +static const int utf8_table3[] = { + 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + + + +/************************************************* +* Print compiled regex * +*************************************************/ + +/* The code for doing this is held in a separate file that is also included in +pcre.c when it is compiled with the debug switch. It defines a function called +print_internals(), which uses a table of opcode lengths defined by the macro +OP_LENGTHS, whose name must be OP_lengths. It also uses a table that translates +Unicode property names to numbers; this is kept in a separate file. */ + +static uschar OP_lengths[] = { OP_LENGTHS }; + +#include "ucp.h" +#include "ucptypetable.c" +#include "printint.c" + + + +/************************************************* +* Read number from string * +*************************************************/ + +/* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess +around with conditional compilation, just do the job by hand. It is only used +for unpicking the -o argument, so just keep it simple. + +Arguments: + str string to be converted + endptr where to put the end pointer + +Returns: the unsigned long +*/ + +static int +get_value(unsigned char *str, unsigned char **endptr) +{ +int result = 0; +while(*str != 0 && isspace(*str)) str++; +while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0'); +*endptr = str; +return(result); +} + + + +/************************************************* +* Convert character value to UTF-8 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x7fffffff +and encodes it as a UTF-8 character in 0 to 6 bytes. + +Arguments: + cvalue the character value + buffer pointer to buffer for result - at least 6 bytes long + +Returns: number of characters placed in the buffer + -1 if input character is negative + 0 if input character is positive but too big (only when + int is longer than 32 bits) +*/ + +static int +ord2utf8(int cvalue, unsigned char *buffer) +{ +register int i, j; +for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) + if (cvalue <= utf8_table1[i]) break; +if (i >= sizeof(utf8_table1)/sizeof(int)) return 0; +if (cvalue < 0) return -1; + +buffer += i; +for (j = i; j > 0; j--) + { + *buffer-- = 0x80 | (cvalue & 0x3f); + cvalue >>= 6; + } +*buffer = utf8_table2[i] | cvalue; +return i + 1; +} + + +/************************************************* +* Convert UTF-8 string to value * +*************************************************/ + +/* This function takes one or more bytes that represents a UTF-8 character, +and returns the value of the character. + +Argument: + buffer a pointer to the byte vector + vptr a pointer to an int to receive the value + +Returns: > 0 => the number of bytes consumed + -6 to 0 => malformed UTF-8 character at offset = (-return) +*/ + +static int +utf82ord(unsigned char *buffer, int *vptr) +{ +int c = *buffer++; +int d = c; +int i, j, s; + +for (i = -1; i < 6; i++) /* i is number of additional bytes */ + { + if ((d & 0x80) == 0) break; + d <<= 1; + } + +if (i == -1) { *vptr = c; return 1; } /* ascii character */ +if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ + +/* i now has a value in the range 1-5 */ + +s = 6*i; +d = (c & utf8_table3[i]) << s; + +for (j = 0; j < i; j++) + { + c = *buffer++; + if ((c & 0xc0) != 0x80) return -(j+1); + s -= 6; + d |= (c & 0x3f) << s; + } + +/* Check that encoding was the correct unique one */ + +for (j = 0; j < sizeof(utf8_table1)/sizeof(int); j++) + if (d <= utf8_table1[j]) break; +if (j != i) return -(i+1); + +/* Valid value */ + +*vptr = d; +return i+1; +} + + + +/************************************************* +* Print character string * +*************************************************/ + +/* Character string printing function. Must handle UTF-8 strings in utf8 +mode. Yields number of characters printed. If handed a NULL file, just counts +chars without printing. */ + +static int pchars(unsigned char *p, int length, FILE *f) +{ +int c; +int yield = 0; + +while (length-- > 0) + { + if (use_utf8) + { + int rc = utf82ord(p, &c); + + if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ + { + length -= rc - 1; + p += rc; + if (c < 256 && isprint(c)) + { + if (f != NULL) fprintf(f, "%c", c); + yield++; + } + else + { + int n; + if (f != NULL) fprintf(f, "\\x{%02x}%n", c, &n); + yield += n; + } + continue; + } + } + + /* Not UTF-8, or malformed UTF-8 */ + + if (isprint(c = *(p++))) + { + if (f != NULL) fprintf(f, "%c", c); + yield++; + } + else + { + if (f != NULL) fprintf(f, "\\x%02x", c); + yield += 4; + } + } + +return yield; +} + + + +/************************************************* +* Callout function * +*************************************************/ + +/* Called from PCRE as a result of the (?C) item. We print out where we are in +the match. Yield zero unless more callouts than the fail count, or the callout +data is not zero. */ + +static int callout(pcre_callout_block *cb) +{ +FILE *f = (first_callout | callout_extra)? outfile : NULL; +int i, pre_start, post_start, subject_length; + +if (callout_extra) + { + fprintf(f, "Callout %d: last capture = %d\n", + cb->callout_number, cb->capture_last); + + for (i = 0; i < cb->capture_top * 2; i += 2) + { + if (cb->offset_vector[i] < 0) + fprintf(f, "%2d: \n", i/2); + else + { + fprintf(f, "%2d: ", i/2); + (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i], + cb->offset_vector[i+1] - cb->offset_vector[i], f); + fprintf(f, "\n"); + } + } + } + +/* Re-print the subject in canonical form, the first time or if giving full +datails. On subsequent calls in the same match, we use pchars just to find the +printed lengths of the substrings. */ + +if (f != NULL) fprintf(f, "--->"); + +pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f); +post_start = pchars((unsigned char *)(cb->subject + cb->start_match), + cb->current_position - cb->start_match, f); + +subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL); + +(void)pchars((unsigned char *)(cb->subject + cb->current_position), + cb->subject_length - cb->current_position, f); + +if (f != NULL) fprintf(f, "\n"); + +/* Always print appropriate indicators, with callout number if not already +shown. For automatic callouts, show the pattern offset. */ + +if (cb->callout_number == 255) + { + fprintf(outfile, "%+3d ", cb->pattern_position); + if (cb->pattern_position > 99) fprintf(outfile, "\n "); + } +else + { + if (callout_extra) fprintf(outfile, " "); + else fprintf(outfile, "%3d ", cb->callout_number); + } + +for (i = 0; i < pre_start; i++) fprintf(outfile, " "); +fprintf(outfile, "^"); + +if (post_start > 0) + { + for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); + fprintf(outfile, "^"); + } + +for (i = 0; i < subject_length - pre_start - post_start + 4; i++) + fprintf(outfile, " "); + +fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, + pbuffer + cb->pattern_position); + +fprintf(outfile, "\n"); +first_callout = 0; + +if (cb->callout_data != NULL) + { + int callout_data = *((int *)(cb->callout_data)); + if (callout_data != 0) + { + fprintf(outfile, "Callout data = %d\n", callout_data); + return callout_data; + } + } + +return (cb->callout_number != callout_fail_id)? 0 : + (++callout_count >= callout_fail_count)? 1 : 0; +} + + +/************************************************* +* Local malloc functions * +*************************************************/ + +/* Alternative malloc function, to test functionality and show the size of the +compiled re. */ + +static void *new_malloc(size_t size) +{ +void *block = malloc(size); +gotten_store = size; +if (show_malloc) + fprintf(outfile, "malloc %3d %p\n", size, block); +return block; +} + +static void new_free(void *block) +{ +if (show_malloc) + fprintf(outfile, "free %p\n", block); +free(block); +} + + +/* For recursion malloc/free, to test stacking calls */ + +static void *stack_malloc(size_t size) +{ +void *block = malloc(size); +if (show_malloc) + fprintf(outfile, "stack_malloc %3d %p\n", size, block); +return block; +} + +static void stack_free(void *block) +{ +if (show_malloc) + fprintf(outfile, "stack_free %p\n", block); +free(block); +} + + +/************************************************* +* Call pcre_fullinfo() * +*************************************************/ + +/* Get one piece of information from the pcre_fullinfo() function */ + +static void new_info(pcre *re, pcre_extra *study, int option, void *ptr) +{ +int rc; +if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0) + fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option); +} + + + +/************************************************* +* Byte flipping function * +*************************************************/ + +static long int +byteflip(long int value, int n) +{ +if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); +return ((value & 0x000000ff) << 24) | + ((value & 0x0000ff00) << 8) | + ((value & 0x00ff0000) >> 8) | + ((value & 0xff000000) >> 24); +} + + + + +/************************************************* +* Main Program * +*************************************************/ + +/* Read lines from named file or stdin and write to named file or stdout; lines +consist of a regular expression, in delimiters and optionally followed by +options, followed by a set of test data, terminated by an empty line. */ + +int main(int argc, char **argv) +{ +FILE *infile = stdin; +int options = 0; +int study_options = 0; +int op = 1; +int timeit = 0; +int showinfo = 0; +int showstore = 0; +int size_offsets = 45; +int size_offsets_max; +int *offsets; +#if !defined NOPOSIX +int posix = 0; +#endif +int debug = 0; +int done = 0; + +unsigned char *buffer; +unsigned char *dbuffer; + +/* Get buffers from malloc() so that Electric Fence will check their misuse +when I am debugging. */ + +buffer = (unsigned char *)malloc(BUFFER_SIZE); +dbuffer = (unsigned char *)malloc(DBUFFER_SIZE); +pbuffer = (unsigned char *)malloc(PBUFFER_SIZE); + +/* The outfile variable is static so that new_malloc can use it. The _setmode() +stuff is some magic that I don't understand, but which apparently does good +things in Windows. It's related to line terminations. */ + +#if defined(_WIN32) || defined(WIN32) +_setmode( _fileno( stdout ), 0x8000 ); +#endif /* defined(_WIN32) || defined(WIN32) */ + +outfile = stdout; + +/* Scan options */ + +while (argc > 1 && argv[op][0] == '-') + { + unsigned char *endptr; + + if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) + showstore = 1; + else if (strcmp(argv[op], "-t") == 0) timeit = 1; + else if (strcmp(argv[op], "-i") == 0) showinfo = 1; + else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; + else if (strcmp(argv[op], "-o") == 0 && argc > 2 && + ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), + *endptr == 0)) + { + op++; + argc--; + } +#if !defined NOPOSIX + else if (strcmp(argv[op], "-p") == 0) posix = 1; +#endif + else if (strcmp(argv[op], "-C") == 0) + { + int rc; + printf("PCRE version %s\n", pcre_version()); + printf("Compiled with\n"); + (void)pcre_config(PCRE_CONFIG_UTF8, &rc); + printf(" %sUTF-8 support\n", rc? "" : "No "); + (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); + printf(" %sUnicode properties support\n", rc? "" : "No "); + (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc); + printf(" Newline character is %s\n", (rc == '\r')? "CR" : "LF"); + (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc); + printf(" Internal link size = %d\n", rc); + (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); + printf(" POSIX malloc threshold = %d\n", rc); + (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); + printf(" Default match limit = %d\n", rc); + (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); + printf(" Match recursion uses %s\n", rc? "stack" : "heap"); + exit(0); + } + else + { + printf("** Unknown or malformed option %s\n", argv[op]); + printf("Usage: pcretest [-d] [-i] [-o ] [-p] [-s] [-t] [ []]\n"); + printf(" -C show PCRE compile-time options and exit\n"); + printf(" -d debug: show compiled code; implies -i\n" + " -i show information about compiled pattern\n" + " -m output memory used information\n" + " -o set size of offsets vector to \n"); +#if !defined NOPOSIX + printf(" -p use POSIX interface\n"); +#endif + printf(" -s output store (memory) used information\n" + " -t time compilation and execution\n"); + return 1; + } + op++; + argc--; + } + +/* Get the store for the offsets vector, and remember what it was */ + +size_offsets_max = size_offsets; +offsets = (int *)malloc(size_offsets_max * sizeof(int)); +if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + size_offsets_max * sizeof(int)); + return 1; + } + +/* Sort out the input and output files */ + +if (argc > 1) + { + infile = fopen(argv[op], "rb"); + if (infile == NULL) + { + printf("** Failed to open %s\n", argv[op]); + return 1; + } + } + +if (argc > 2) + { + outfile = fopen(argv[op+1], "wb"); + if (outfile == NULL) + { + printf("** Failed to open %s\n", argv[op+1]); + return 1; + } + } + +/* Set alternative malloc function */ + +pcre_malloc = new_malloc; +pcre_free = new_free; +pcre_stack_malloc = stack_malloc; +pcre_stack_free = stack_free; + +/* Heading line, then prompt for first regex if stdin */ + +fprintf(outfile, "PCRE version %s\n\n", pcre_version()); + +/* Main loop */ + +while (!done) + { + pcre *re = NULL; + pcre_extra *extra = NULL; + +#if !defined NOPOSIX /* There are still compilers that require no indent */ + regex_t preg; + int do_posix = 0; +#endif + + const char *error; + unsigned char *p, *pp, *ppp; + unsigned char *to_file = NULL; + const unsigned char *tables = NULL; + unsigned long int true_size, true_study_size = 0; + size_t size, regex_gotten_store; + int do_study = 0; + int do_debug = debug; + int do_G = 0; + int do_g = 0; + int do_showinfo = showinfo; + int do_showrest = 0; + int do_flip = 0; + int erroroffset, len, delimiter; + + use_utf8 = 0; + + if (infile == stdin) printf(" re> "); + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break; + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + fflush(outfile); + + p = buffer; + while (isspace(*p)) p++; + if (*p == 0) continue; + + /* See if the pattern is to be loaded pre-compiled from a file. */ + + if (*p == '<' && strchr((char *)(p+1), '<') == NULL) + { + unsigned long int magic; + uschar sbuf[8]; + FILE *f; + + p++; + pp = p + (int)strlen((char *)p); + while (isspace(pp[-1])) pp--; + *pp = 0; + + f = fopen((char *)p, "rb"); + if (f == NULL) + { + fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); + continue; + } + + if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; + + true_size = + (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; + true_study_size = + (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; + + re = (real_pcre *)new_malloc(true_size); + regex_gotten_store = gotten_store; + + if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; + + magic = ((real_pcre *)re)->magic_number; + if (magic != MAGIC_NUMBER) + { + if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER) + { + do_flip = 1; + } + else + { + fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); + fclose(f); + continue; + } + } + + fprintf(outfile, "Compiled regex%s loaded from %s\n", + do_flip? " (byte-inverted)" : "", p); + + /* Need to know if UTF-8 for printing data strings */ + + new_info(re, NULL, PCRE_INFO_OPTIONS, &options); + use_utf8 = (options & PCRE_UTF8) != 0; + + /* Now see if there is any following study data */ + + if (true_study_size != 0) + { + pcre_study_data *psd; + + extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); + extra->flags = PCRE_EXTRA_STUDY_DATA; + + psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); + extra->study_data = psd; + + if (fread(psd, 1, true_study_size, f) != true_study_size) + { + FAIL_READ: + fprintf(outfile, "Failed to read data from %s\n", p); + if (extra != NULL) new_free(extra); + if (re != NULL) new_free(re); + fclose(f); + continue; + } + fprintf(outfile, "Study data loaded from %s\n", p); + do_study = 1; /* To get the data output if requested */ + } + else fprintf(outfile, "No study data\n"); + + fclose(f); + goto SHOW_INFO; + } + + /* In-line pattern (the usual case). Get the delimiter and seek the end of + the pattern; if is isn't complete, read more. */ + + delimiter = *p++; + + if (isalnum(delimiter) || delimiter == '\\') + { + fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); + goto SKIP_DATA; + } + + pp = p; + + for(;;) + { + while (*pp != 0) + { + if (*pp == '\\' && pp[1] != 0) pp++; + else if (*pp == delimiter) break; + pp++; + } + if (*pp != 0) break; + + len = BUFFER_SIZE - (pp - buffer); + if (len < 256) + { + fprintf(outfile, "** Expression too long - missing delimiter?\n"); + goto SKIP_DATA; + } + + if (infile == stdin) printf(" > "); + if (fgets((char *)pp, len, infile) == NULL) + { + fprintf(outfile, "** Unexpected EOF\n"); + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)pp); + } + + /* If the first character after the delimiter is backslash, make + the pattern end with backslash. This is purely to provide a way + of testing for the error message when a pattern ends with backslash. */ + + if (pp[1] == '\\') *pp++ = '\\'; + + /* Terminate the pattern at the delimiter, and save a copy of the pattern + for callouts. */ + + *pp++ = 0; + strcpy((char *)pbuffer, (char *)p); + + /* Look for options after final delimiter */ + + options = 0; + study_options = 0; + log_store = showstore; /* default from command line */ + + while (*pp != 0) + { + switch (*pp++) + { + case 'g': do_g = 1; break; + case 'i': options |= PCRE_CASELESS; break; + case 'm': options |= PCRE_MULTILINE; break; + case 's': options |= PCRE_DOTALL; break; + case 'x': options |= PCRE_EXTENDED; break; + + case '+': do_showrest = 1; break; + case 'A': options |= PCRE_ANCHORED; break; + case 'C': options |= PCRE_AUTO_CALLOUT; break; + case 'D': do_debug = do_showinfo = 1; break; + case 'E': options |= PCRE_DOLLAR_ENDONLY; break; + case 'F': do_flip = 1; break; + case 'G': do_G = 1; break; + case 'I': do_showinfo = 1; break; + case 'M': log_store = 1; break; + case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; + +#if !defined NOPOSIX + case 'P': do_posix = 1; break; +#endif + + case 'S': do_study = 1; break; + case 'U': options |= PCRE_UNGREEDY; break; + case 'X': options |= PCRE_EXTRA; break; + case '8': options |= PCRE_UTF8; use_utf8 = 1; break; + case '?': options |= PCRE_NO_UTF8_CHECK; break; + + case 'L': + ppp = pp; + while (*ppp != '\n' && *ppp != ' ') ppp++; + *ppp = 0; + if (setlocale(LC_CTYPE, (const char *)pp) == NULL) + { + fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); + goto SKIP_DATA; + } + tables = pcre_maketables(); + pp = ppp; + break; + + case '>': + to_file = pp; + while (*pp != 0) pp++; + while (isspace(pp[-1])) pp--; + *pp = 0; + break; + + case '\n': case ' ': break; + + default: + fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); + goto SKIP_DATA; + } + } + + /* Handle compiling via the POSIX interface, which doesn't support the + timing, showing, or debugging options, nor the ability to pass over + local character tables. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int cflags = 0; + + if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; + if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; + rc = regcomp(&preg, (char *)p, cflags); + + /* Compilation failed; go back for another re, skipping to blank line + if non-interactive. */ + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); + fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); + goto SKIP_DATA; + } + } + + /* Handle compiling via the native interface */ + + else +#endif /* !defined NOPOSIX */ + + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + { + re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + if (re != NULL) free(re); + } + time_taken = clock() - start_time; + fprintf(outfile, "Compile time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + + re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + + /* Compilation failed; go back for another re, skipping to blank line + if non-interactive. */ + + if (re == NULL) + { + fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); + SKIP_DATA: + if (infile != stdin) + { + for (;;) + { + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) + { + done = 1; + goto CONTINUE; + } + len = (int)strlen((char *)buffer); + while (len > 0 && isspace(buffer[len-1])) len--; + if (len == 0) break; + } + fprintf(outfile, "\n"); + } + goto CONTINUE; + } + + /* Compilation succeeded; print data if required. There are now two + info-returning functions. The old one has a limited interface and + returns only limited data. Check that it agrees with the newer one. */ + + if (log_store) + fprintf(outfile, "Memory allocation (code space): %d\n", + (int)(gotten_store - + sizeof(real_pcre) - + ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size)); + + /* Extract the size for possible writing before possibly flipping it, + and remember the store that was got. */ + + true_size = ((real_pcre *)re)->size; + regex_gotten_store = gotten_store; + + /* If /S was present, study the regexp to generate additional info to + help with the matching. */ + + if (do_study) + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + extra = pcre_study(re, study_options, &error); + time_taken = clock() - start_time; + if (extra != NULL) free(extra); + fprintf(outfile, " Study time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + extra = pcre_study(re, study_options, &error); + if (error != NULL) + fprintf(outfile, "Failed to study: %s\n", error); + else if (extra != NULL) + true_study_size = ((pcre_study_data *)(extra->study_data))->size; + } + + /* If the 'F' option was present, we flip the bytes of all the integer + fields in the regex data block and the study block. This is to make it + possible to test PCRE's handling of byte-flipped patterns, e.g. those + compiled on a different architecture. */ + + if (do_flip) + { + real_pcre *rre = (real_pcre *)re; + rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number)); + rre->size = byteflip(rre->size, sizeof(rre->size)); + rre->options = byteflip(rre->options, sizeof(rre->options)); + rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket)); + rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref)); + rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte)); + rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte)); + rre->name_table_offset = byteflip(rre->name_table_offset, + sizeof(rre->name_table_offset)); + rre->name_entry_size = byteflip(rre->name_entry_size, + sizeof(rre->name_entry_size)); + rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count)); + + if (extra != NULL) + { + pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); + rsd->size = byteflip(rsd->size, sizeof(rsd->size)); + rsd->options = byteflip(rsd->options, sizeof(rsd->options)); + } + } + + /* Extract information from the compiled data if required */ + + SHOW_INFO: + + if (do_showinfo) + { + unsigned long int get_options, all_options; + int old_first_char, old_options, old_count; + int count, backrefmax, first_char, need_char; + int nameentrysize, namecount; + const uschar *nametable; + + if (do_debug) + { + fprintf(outfile, "------------------------------------------------------------------\n"); + print_internals(re, outfile); + } + + new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); + new_info(re, NULL, PCRE_INFO_SIZE, &size); + new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); + new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); + new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char); + new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); + new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); + new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); + new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); + + old_count = pcre_info(re, &old_options, &old_first_char); + if (count < 0) fprintf(outfile, + "Error %d from pcre_info()\n", count); + else + { + if (old_count != count) fprintf(outfile, + "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, + old_count); + + if (old_first_char != first_char) fprintf(outfile, + "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", + first_char, old_first_char); + + if (old_options != (int)get_options) fprintf(outfile, + "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", + get_options, old_options); + } + + if (size != regex_gotten_store) fprintf(outfile, + "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", + size, regex_gotten_store); + + fprintf(outfile, "Capturing subpattern count = %d\n", count); + if (backrefmax > 0) + fprintf(outfile, "Max back reference = %d\n", backrefmax); + + if (namecount > 0) + { + fprintf(outfile, "Named capturing subpatterns:\n"); + while (namecount-- > 0) + { + fprintf(outfile, " %s %*s%3d\n", nametable + 2, + nameentrysize - 3 - (int)strlen((char *)nametable + 2), "", + GET2(nametable, 0)); + nametable += nameentrysize; + } + } + + /* The NOPARTIAL bit is a private bit in the options, so we have + to fish it out via out back door */ + + all_options = ((real_pcre *)re)->options; + if (do_flip) + { + all_options = byteflip(all_options, sizeof(all_options)); + } + + if ((all_options & PCRE_NOPARTIAL) != 0) + fprintf(outfile, "Partial matching not supported\n"); + + if (get_options == 0) fprintf(outfile, "No options\n"); + else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s\n", + ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", + ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", + ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", + ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", + ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", + ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", + ((get_options & PCRE_EXTRA) != 0)? " extra" : "", + ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", + ((get_options & PCRE_UTF8) != 0)? " utf8" : "", + ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : ""); + + if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) + fprintf(outfile, "Case state changes\n"); + + if (first_char == -1) + { + fprintf(outfile, "First char at start or follows \\n\n"); + } + else if (first_char < 0) + { + fprintf(outfile, "No first char\n"); + } + else + { + int ch = first_char & 255; + const char *caseless = ((first_char & REQ_CASELESS) == 0)? + "" : " (caseless)"; + if (isprint(ch)) + fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); + else + fprintf(outfile, "First char = %d%s\n", ch, caseless); + } + + if (need_char < 0) + { + fprintf(outfile, "No need char\n"); + } + else + { + int ch = need_char & 255; + const char *caseless = ((need_char & REQ_CASELESS) == 0)? + "" : " (caseless)"; + if (isprint(ch)) + fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); + else + fprintf(outfile, "Need char = %d%s\n", ch, caseless); + } + + /* Don't output study size; at present it is in any case a fixed + value, but it varies, depending on the computer architecture, and + so messes up the test suite. (And with the /F option, it might be + flipped.) */ + + if (do_study) + { + if (extra == NULL) + fprintf(outfile, "Study returned NULL\n"); + else + { + uschar *start_bits = NULL; + new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); + + if (start_bits == NULL) + fprintf(outfile, "No starting byte set\n"); + else + { + int i; + int c = 24; + fprintf(outfile, "Starting byte set: "); + for (i = 0; i < 256; i++) + { + if ((start_bits[i/8] & (1<<(i&7))) != 0) + { + if (c > 75) + { + fprintf(outfile, "\n "); + c = 2; + } + if (isprint(i) && i != ' ') + { + fprintf(outfile, "%c ", i); + c += 2; + } + else + { + fprintf(outfile, "\\x%02x ", i); + c += 5; + } + } + } + fprintf(outfile, "\n"); + } + } + } + } + + /* If the '>' option was present, we write out the regex to a file, and + that is all. The first 8 bytes of the file are the regex length and then + the study length, in big-endian order. */ + + if (to_file != NULL) + { + FILE *f = fopen((char *)to_file, "wb"); + if (f == NULL) + { + fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); + } + else + { + uschar sbuf[8]; + sbuf[0] = (true_size >> 24) & 255; + sbuf[1] = (true_size >> 16) & 255; + sbuf[2] = (true_size >> 8) & 255; + sbuf[3] = (true_size) & 255; + + sbuf[4] = (true_study_size >> 24) & 255; + sbuf[5] = (true_study_size >> 16) & 255; + sbuf[6] = (true_study_size >> 8) & 255; + sbuf[7] = (true_study_size) & 255; + + if (fwrite(sbuf, 1, 8, f) < 8 || + fwrite(re, 1, true_size, f) < true_size) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); + } + else + { + fprintf(outfile, "Compiled regex written to %s\n", to_file); + if (extra != NULL) + { + if (fwrite(extra->study_data, 1, true_study_size, f) < + true_study_size) + { + fprintf(outfile, "Write error on %s: %s\n", to_file, + strerror(errno)); + } + else fprintf(outfile, "Study data written to %s\n", to_file); + } + } + fclose(f); + } + continue; /* With next regex */ + } + } /* End of non-POSIX compile */ + + /* Read data lines and test them */ + + for (;;) + { + unsigned char *q; + unsigned char *bptr = dbuffer; + int *use_offsets = offsets; + int use_size_offsets = size_offsets; + int callout_data = 0; + int callout_data_set = 0; + int count, c; + int copystrings = 0; + int find_match_limit = 0; + int getstrings = 0; + int getlist = 0; + int gmatched = 0; + int start_offset = 0; + int g_notempty = 0; + + options = 0; + + pcre_callout = callout; + first_callout = 1; + callout_extra = 0; + callout_count = 0; + callout_fail_count = 999999; + callout_fail_id = -1; + show_malloc = 0; + + if (infile == stdin) printf("data> "); + if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) + { + done = 1; + goto CONTINUE; + } + if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); + + len = (int)strlen((char *)buffer); + while (len > 0 && isspace(buffer[len-1])) len--; + buffer[len] = 0; + if (len == 0) break; + + p = buffer; + while (isspace(*p)) p++; + + q = dbuffer; + while ((c = *p++) != 0) + { + int i = 0; + int n = 0; + + if (c == '\\') switch ((c = *p++)) + { + case 'a': c = 7; break; + case 'b': c = '\b'; break; + case 'e': c = 27; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c -= '0'; + while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') + c = c * 8 + *p++ - '0'; + break; + + case 'x': + + /* Handle \x{..} specially - new Perl thing for utf8 */ + + if (*p == '{') + { + unsigned char *pt = p; + c = 0; + while (isxdigit(*(++pt))) + c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); + if (*pt == '}') + { + unsigned char buff8[8]; + int ii, utn; + utn = ord2utf8(c, buff8); + for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; + c = buff8[ii]; /* Last byte */ + p = pt + 1; + break; + } + /* Not correct form; fall through */ + } + + /* Ordinary \x */ + + c = 0; + while (i++ < 2 && isxdigit(*p)) + { + c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); + p++; + } + break; + + case 0: /* \ followed by EOF allows for an empty line */ + p--; + continue; + + case '>': + while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; + continue; + + case 'A': /* Option setting */ + options |= PCRE_ANCHORED; + continue; + + case 'B': + options |= PCRE_NOTBOL; + continue; + + case 'C': + if (isdigit(*p)) /* Set copy string */ + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + copystrings |= 1 << n; + } + else if (isalnum(*p)) + { + uschar name[256]; + uschar *npp = name; + while (isalnum(*p)) *npp++ = *p++; + *npp = 0; + n = pcre_get_stringnumber(re, (char *)name); + if (n < 0) + fprintf(outfile, "no parentheses with name \"%s\"\n", name); + else copystrings |= 1 << n; + } + else if (*p == '+') + { + callout_extra = 1; + p++; + } + else if (*p == '-') + { + pcre_callout = NULL; + p++; + } + else if (*p == '!') + { + callout_fail_id = 0; + p++; + while(isdigit(*p)) + callout_fail_id = callout_fail_id * 10 + *p++ - '0'; + callout_fail_count = 0; + if (*p == '!') + { + p++; + while(isdigit(*p)) + callout_fail_count = callout_fail_count * 10 + *p++ - '0'; + } + } + else if (*p == '*') + { + int sign = 1; + callout_data = 0; + if (*(++p) == '-') { sign = -1; p++; } + while(isdigit(*p)) + callout_data = callout_data * 10 + *p++ - '0'; + callout_data *= sign; + callout_data_set = 1; + } + continue; + + case 'G': + if (isdigit(*p)) + { + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + getstrings |= 1 << n; + } + else if (isalnum(*p)) + { + uschar name[256]; + uschar *npp = name; + while (isalnum(*p)) *npp++ = *p++; + *npp = 0; + n = pcre_get_stringnumber(re, (char *)name); + if (n < 0) + fprintf(outfile, "no parentheses with name \"%s\"\n", name); + else getstrings |= 1 << n; + } + continue; + + case 'L': + getlist = 1; + continue; + + case 'M': + find_match_limit = 1; + continue; + + case 'N': + options |= PCRE_NOTEMPTY; + continue; + + case 'O': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (n > size_offsets_max) + { + size_offsets_max = n; + free(offsets); + use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); + if (offsets == NULL) + { + printf("** Failed to get %d bytes of memory for offsets vector\n", + size_offsets_max * sizeof(int)); + return 1; + } + } + use_size_offsets = n; + if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ + continue; + + case 'P': + options |= PCRE_PARTIAL; + continue; + + case 'S': + show_malloc = 1; + continue; + + case 'Z': + options |= PCRE_NOTEOL; + continue; + + case '?': + options |= PCRE_NO_UTF8_CHECK; + continue; + } + *q++ = c; + } + *q = 0; + len = q - dbuffer; + + /* Handle matching via the POSIX interface, which does not + support timing or playing with the match limit or callout data. */ + +#if !defined NOPOSIX + if (posix || do_posix) + { + int rc; + int eflags = 0; + regmatch_t *pmatch = NULL; + if (use_size_offsets > 0) + pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); + if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; + if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; + + rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); + + if (rc != 0) + { + (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); + fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); + } + else + { + size_t i; + for (i = 0; i < (size_t)use_size_offsets; i++) + { + if (pmatch[i].rm_so >= 0) + { + fprintf(outfile, "%2d: ", (int)i); + (void)pchars(dbuffer + pmatch[i].rm_so, + pmatch[i].rm_eo - pmatch[i].rm_so, outfile); + fprintf(outfile, "\n"); + if (i == 0 && do_showrest) + { + fprintf(outfile, " 0+ "); + (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, + outfile); + fprintf(outfile, "\n"); + } + } + } + } + free(pmatch); + } + + /* Handle matching via the native interface - repeats for /g and /G */ + + else +#endif /* !defined NOPOSIX */ + + for (;; gmatched++) /* Loop for /g or /G */ + { + if (timeit) + { + register int i; + clock_t time_taken; + clock_t start_time = clock(); + for (i = 0; i < LOOPREPEAT; i++) + count = pcre_exec(re, extra, (char *)bptr, len, + start_offset, options | g_notempty, use_offsets, use_size_offsets); + time_taken = clock() - start_time; + fprintf(outfile, "Execute time %.3f milliseconds\n", + (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / + (double)CLOCKS_PER_SEC); + } + + /* If find_match_limit is set, we want to do repeated matches with + varying limits in order to find the minimum value. */ + + if (find_match_limit) + { + int min = 0; + int mid = 64; + int max = -1; + + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_MATCH_LIMIT; + + for (;;) + { + extra->match_limit = mid; + count = pcre_exec(re, extra, (char *)bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); + if (count == PCRE_ERROR_MATCHLIMIT) + { + /* fprintf(outfile, "Testing match limit = %d\n", mid); */ + min = mid; + mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; + } + else if (count >= 0 || count == PCRE_ERROR_NOMATCH || + count == PCRE_ERROR_PARTIAL) + { + if (mid == min + 1) + { + fprintf(outfile, "Minimum match limit = %d\n", mid); + break; + } + /* fprintf(outfile, "Testing match limit = %d\n", mid); */ + max = mid; + mid = (min + mid)/2; + } + else break; /* Some other error */ + } + + extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT; + } + + /* If callout_data is set, use the interface with additional data */ + + else if (callout_data_set) + { + if (extra == NULL) + { + extra = (pcre_extra *)malloc(sizeof(pcre_extra)); + extra->flags = 0; + } + extra->flags |= PCRE_EXTRA_CALLOUT_DATA; + extra->callout_data = &callout_data; + count = pcre_exec(re, extra, (char *)bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); + extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; + } + + /* The normal case is just to do the match once, with the default + value of match_limit. */ + + else + { + count = pcre_exec(re, extra, (char *)bptr, len, + start_offset, options | g_notempty, use_offsets, use_size_offsets); + } + + if (count == 0) + { + fprintf(outfile, "Matched, but too many substrings\n"); + count = use_size_offsets/3; + } + + /* Matched */ + + if (count >= 0) + { + int i; + for (i = 0; i < count * 2; i += 2) + { + if (use_offsets[i] < 0) + fprintf(outfile, "%2d: \n", i/2); + else + { + fprintf(outfile, "%2d: ", i/2); + (void)pchars(bptr + use_offsets[i], + use_offsets[i+1] - use_offsets[i], outfile); + fprintf(outfile, "\n"); + if (i == 0) + { + if (do_showrest) + { + fprintf(outfile, " 0+ "); + (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], + outfile); + fprintf(outfile, "\n"); + } + } + } + } + + for (i = 0; i < 32; i++) + { + if ((copystrings & (1 << i)) != 0) + { + char copybuffer[16]; + int rc = pcre_copy_substring((char *)bptr, use_offsets, count, + i, copybuffer, sizeof(copybuffer)); + if (rc < 0) + fprintf(outfile, "copy substring %d failed %d\n", i, rc); + else + fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); + } + } + + for (i = 0; i < 32; i++) + { + if ((getstrings & (1 << i)) != 0) + { + const char *substring; + int rc = pcre_get_substring((char *)bptr, use_offsets, count, + i, &substring); + if (rc < 0) + fprintf(outfile, "get substring %d failed %d\n", i, rc); + else + { + fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); + /* free((void *)substring); */ + pcre_free_substring(substring); + } + } + } + + if (getlist) + { + const char **stringlist; + int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, + &stringlist); + if (rc < 0) + fprintf(outfile, "get substring list failed %d\n", rc); + else + { + for (i = 0; i < count; i++) + fprintf(outfile, "%2dL %s\n", i, stringlist[i]); + if (stringlist[i] != NULL) + fprintf(outfile, "string list not terminated by NULL\n"); + /* free((void *)stringlist); */ + pcre_free_substring_list(stringlist); + } + } + } + + /* There was a partial match */ + + else if (count == PCRE_ERROR_PARTIAL) + { + fprintf(outfile, "Partial match\n"); + break; /* Out of the /g loop */ + } + + /* Failed to match. If this is a /g or /G loop and we previously set + g_notempty after a null match, this is not necessarily the end. + We want to advance the start offset, and continue. In the case of UTF-8 + matching, the advance must be one character, not one byte. Fudge the + offset values to achieve this. We won't be at the end of the string - + that was checked before setting g_notempty. */ + + else + { + if (g_notempty != 0) + { + int onechar = 1; + use_offsets[0] = start_offset; + if (use_utf8) + { + while (start_offset + onechar < len) + { + int tb = bptr[start_offset+onechar]; + if (tb <= 127) break; + tb &= 0xc0; + if (tb != 0 && tb != 0xc0) onechar++; + } + } + use_offsets[1] = start_offset + onechar; + } + else + { + if (count == PCRE_ERROR_NOMATCH) + { + if (gmatched == 0) fprintf(outfile, "No match\n"); + } + else fprintf(outfile, "Error %d\n", count); + break; /* Out of the /g loop */ + } + } + + /* If not /g or /G we are done */ + + if (!do_g && !do_G) break; + + /* If we have matched an empty string, first check to see if we are at + the end of the subject. If so, the /g loop is over. Otherwise, mimic + what Perl's /g options does. This turns out to be rather cunning. First + we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the + same point. If this fails (picked up above) we advance to the next + character. */ + + g_notempty = 0; + if (use_offsets[0] == use_offsets[1]) + { + if (use_offsets[0] == len) break; + g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; + } + + /* For /g, update the start offset, leaving the rest alone */ + + if (do_g) start_offset = use_offsets[1]; + + /* For /G, update the pointer and length */ + + else + { + bptr += use_offsets[1]; + len -= use_offsets[1]; + } + } /* End of loop for /g and /G */ + } /* End of loop for data lines */ + + CONTINUE: + +#if !defined NOPOSIX + if (posix || do_posix) regfree(&preg); +#endif + + if (re != NULL) free(re); + if (extra != NULL) free(extra); + if (tables != NULL) + { + free((void *)tables); + setlocale(LC_CTYPE, "C"); + } + } + +if (infile == stdin) fprintf(outfile, "\n"); +return 0; +} + +/* End */ diff --git a/trunk/srclib/pcre/perltest b/trunk/srclib/pcre/perltest new file mode 100755 index 0000000000..44afbea63c --- /dev/null +++ b/trunk/srclib/pcre/perltest @@ -0,0 +1,211 @@ +#! /usr/bin/perl + +# Program for testing regular expressions with perl to check that PCRE handles +# them the same. This is the version that supports /8 for UTF-8 testing. As it +# stands, it requires at least Perl 5.8 for UTF-8 support. For Perl 5.6, it +# can be used as is for non-UTF-8 testing, but you have to uncomment the +# "use utf8" lines in order to to UTF-8 stuff (and you mustn't uncomment them +# for non-UTF-8 use). + + +# Function for turning a string into a string of printing chars. There are +# currently problems with UTF-8 strings; this fudges round them. + +sub pchars { +my($t) = ""; + +if ($utf8) + { +# use utf8; <=============== For UTF-8 in Perl 5.6 + @p = unpack('U*', $_[0]); + foreach $c (@p) + { + if ($c >= 32 && $c < 127) { $t .= chr $c; } + else { $t .= sprintf("\\x{%02x}", $c); } + } + } + +else + { + foreach $c (split(//, $_[0])) + { + if (ord $c >= 32 && ord $c < 127) { $t .= $c; } + else { $t .= sprintf("\\x%02x", ord $c); } + } + } + +$t; +} + + + +# Read lines from named file or stdin and write to named file or stdout; lines +# consist of a regular expression, in delimiters and optionally followed by +# options, followed by a set of test data, terminated by an empty line. + +# Sort out the input and output files + +if (@ARGV > 0) + { + open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; + $infile = "INFILE"; + } +else { $infile = "STDIN"; } + +if (@ARGV > 1) + { + open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; + $outfile = "OUTFILE"; + } +else { $outfile = "STDOUT"; } + +printf($outfile "Perl $] Regular Expressions\n\n"); + +# Main loop + +NEXT_RE: +for (;;) + { + printf " re> " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + next if ($_ eq ""); + + $pattern = $_; + + while ($pattern !~ /^\s*(.).*\1/s) + { + printf " > " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + $pattern .= $_; + } + + chomp($pattern); + $pattern =~ s/\s+$//; + + # The private /+ modifier means "print $' afterwards". + + $showrest = ($pattern =~ s/\+(?=[a-z]*$)//); + + # The private /8 modifier means "operate in UTF-8". Currently, Perl + # has bugs that we try to work around using this flag. + + $utf8 = ($pattern =~ s/8(?=[a-z]*$)//); + + # Check that the pattern is valid + + if ($utf8) + { +# use utf8; <=============== For UTF-8 in Perl 5.6 + eval "\$_ =~ ${pattern}"; + } + else + { + eval "\$_ =~ ${pattern}"; + } + + if ($@) + { + printf $outfile "Error: $@"; + next NEXT_RE; + } + + # If the /g modifier is present, we want to put a loop round the matching; + # otherwise just a single "if". + + $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; + + # If the pattern is actually the null string, Perl uses the most recently + # executed (and successfully compiled) regex is used instead. This is a + # nasty trap for the unwary! The PCRE test suite does contain null strings + # in places - if they are allowed through here all sorts of weird and + # unexpected effects happen. To avoid this, we replace such patterns with + # a non-null pattern that has the same effect. + + $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); + + # Read data lines and test them + + for (;;) + { + printf "data> " if $infile eq "STDIN"; + last NEXT_RE if ! ($_ = <$infile>); + chomp; + printf $outfile "$_\n" if $infile ne "STDIN"; + + s/\s+$//; + s/^\s+//; + + last if ($_ eq ""); + + $x = eval "\"$_\""; # To get escapes processed + + # Empty array for holding results, then do the matching. + + @subs = (); + + $pushes = "push \@subs,\$&;" . + "push \@subs,\$1;" . + "push \@subs,\$2;" . + "push \@subs,\$3;" . + "push \@subs,\$4;" . + "push \@subs,\$5;" . + "push \@subs,\$6;" . + "push \@subs,\$7;" . + "push \@subs,\$8;" . + "push \@subs,\$9;" . + "push \@subs,\$10;" . + "push \@subs,\$11;" . + "push \@subs,\$12;" . + "push \@subs,\$13;" . + "push \@subs,\$14;" . + "push \@subs,\$15;" . + "push \@subs,\$16;" . + "push \@subs,\$'; }"; + + if ($utf8) + { +# use utf8; <=============== For UTF-8 in Perl 5.6 + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + } + else + { + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + } + + if ($@) + { + printf $outfile "Error: $@\n"; + next NEXT_RE; + } + elsif (scalar(@subs) == 0) + { + printf $outfile "No match\n"; + } + else + { + while (scalar(@subs) != 0) + { + printf $outfile (" 0: %s\n", &pchars($subs[0])); + printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; + $last_printed = 0; + for ($i = 1; $i <= 16; $i++) + { + if (defined $subs[$i]) + { + while ($last_printed++ < $i-1) + { printf $outfile ("%2d: \n", $last_printed); } + printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); + $last_printed = $i; + } + } + splice(@subs, 0, 18); + } + } + } + } + +# printf $outfile "\n"; + +# End diff --git a/trunk/srclib/pcre/perltest8 b/trunk/srclib/pcre/perltest8 new file mode 100755 index 0000000000..2fe522d60d --- /dev/null +++ b/trunk/srclib/pcre/perltest8 @@ -0,0 +1,208 @@ +#! /usr/bin/perl + +# Program for testing regular expressions with perl to check that PCRE handles +# them the same. This is the version that supports /8 for UTF-8 testing. It +# requires at least Perl 5.6. + + +# Function for turning a string into a string of printing chars. There are +# currently problems with UTF-8 strings; this fudges round them. + +sub pchars { +my($t) = ""; + +if ($utf8) + { + use utf8; + @p = unpack('U*', $_[0]); + foreach $c (@p) + { + if ($c >= 32 && $c < 127) { $t .= chr $c; } + else { $t .= sprintf("\\x{%02x}", $c); } + } + } + +else + { + foreach $c (split(//, $_[0])) + { + if (ord $c >= 32 && ord $c < 127) { $t .= $c; } + else { $t .= sprintf("\\x%02x", ord $c); } + } + } + +$t; +} + + + +# Read lines from named file or stdin and write to named file or stdout; lines +# consist of a regular expression, in delimiters and optionally followed by +# options, followed by a set of test data, terminated by an empty line. + +# Sort out the input and output files + +if (@ARGV > 0) + { + open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; + $infile = "INFILE"; + } +else { $infile = "STDIN"; } + +if (@ARGV > 1) + { + open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; + $outfile = "OUTFILE"; + } +else { $outfile = "STDOUT"; } + +printf($outfile "Perl $] Regular Expressions\n\n"); + +# Main loop + +NEXT_RE: +for (;;) + { + printf " re> " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + next if ($_ eq ""); + + $pattern = $_; + + while ($pattern !~ /^\s*(.).*\1/s) + { + printf " > " if $infile eq "STDIN"; + last if ! ($_ = <$infile>); + printf $outfile "$_" if $infile ne "STDIN"; + $pattern .= $_; + } + + chomp($pattern); + $pattern =~ s/\s+$//; + + # The private /+ modifier means "print $' afterwards". + + $showrest = ($pattern =~ s/\+(?=[a-z]*$)//); + + # The private /8 modifier means "operate in UTF-8". Currently, Perl + # has bugs that we try to work around using this flag. + + $utf8 = ($pattern =~ s/8(?=[a-z]*$)//); + + # Check that the pattern is valid + + if ($utf8) + { + use utf8; + eval "\$_ =~ ${pattern}"; + } + else + { + eval "\$_ =~ ${pattern}"; + } + + if ($@) + { + printf $outfile "Error: $@"; + next NEXT_RE; + } + + # If the /g modifier is present, we want to put a loop round the matching; + # otherwise just a single "if". + + $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; + + # If the pattern is actually the null string, Perl uses the most recently + # executed (and successfully compiled) regex is used instead. This is a + # nasty trap for the unwary! The PCRE test suite does contain null strings + # in places - if they are allowed through here all sorts of weird and + # unexpected effects happen. To avoid this, we replace such patterns with + # a non-null pattern that has the same effect. + + $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); + + # Read data lines and test them + + for (;;) + { + printf "data> " if $infile eq "STDIN"; + last NEXT_RE if ! ($_ = <$infile>); + chomp; + printf $outfile "$_\n" if $infile ne "STDIN"; + + s/\s+$//; + s/^\s+//; + + last if ($_ eq ""); + + $x = eval "\"$_\""; # To get escapes processed + + # Empty array for holding results, then do the matching. + + @subs = (); + + $pushes = "push \@subs,\$&;" . + "push \@subs,\$1;" . + "push \@subs,\$2;" . + "push \@subs,\$3;" . + "push \@subs,\$4;" . + "push \@subs,\$5;" . + "push \@subs,\$6;" . + "push \@subs,\$7;" . + "push \@subs,\$8;" . + "push \@subs,\$9;" . + "push \@subs,\$10;" . + "push \@subs,\$11;" . + "push \@subs,\$12;" . + "push \@subs,\$13;" . + "push \@subs,\$14;" . + "push \@subs,\$15;" . + "push \@subs,\$16;" . + "push \@subs,\$'; }"; + + if ($utf8) + { + use utf8; + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + } + else + { + eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; + } + + if ($@) + { + printf $outfile "Error: $@\n"; + next NEXT_RE; + } + elsif (scalar(@subs) == 0) + { + printf $outfile "No match\n"; + } + else + { + while (scalar(@subs) != 0) + { + printf $outfile (" 0: %s\n", &pchars($subs[0])); + printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; + $last_printed = 0; + for ($i = 1; $i <= 16; $i++) + { + if (defined $subs[$i]) + { + while ($last_printed++ < $i-1) + { printf $outfile ("%2d: \n", $last_printed); } + printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); + $last_printed = $i; + } + } + splice(@subs, 0, 18); + } + } + } + } + +printf $outfile "\n"; + +# End diff --git a/trunk/srclib/pcre/pgrep.c b/trunk/srclib/pcre/pgrep.c new file mode 100644 index 0000000000..ad1b87eae9 --- /dev/null +++ b/trunk/srclib/pcre/pgrep.c @@ -0,0 +1,225 @@ +/************************************************* +* PCRE grep program * +*************************************************/ + +#include +#include +#include +#include +#include "config.h" +#include "pcre.h" + +#define FALSE 0 +#define TRUE 1 + +typedef int BOOL; + + + +/************************************************* +* Global variables * +*************************************************/ + +static pcre *pattern; +static pcre_extra *hints; + +static BOOL count_only = FALSE; +static BOOL filenames_only = FALSE; +static BOOL invert = FALSE; +static BOOL number = FALSE; +static BOOL silent = FALSE; +static BOOL whole_lines = FALSE; + + + +#if ! HAVE_STRERROR +/************************************************* +* Provide strerror() for non-ANSI libraries * +*************************************************/ + +/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() +in their libraries, but can provide the same facility by this simple +alternative function. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(int n) +{ +if (n < 0 || n >= sys_nerr) return "unknown error number"; +return sys_errlist[n]; +} +#endif /* HAVE_STRERROR */ + + + +/************************************************* +* Grep an individual file * +*************************************************/ + +static int +pgrep(FILE *in, char *name) +{ +int rc = 1; +int linenumber = 0; +int count = 0; +int offsets[99]; +char buffer[BUFSIZ]; + +while (fgets(buffer, sizeof(buffer), in) != NULL) + { + BOOL match; + int length = (int)strlen(buffer); + if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0; + linenumber++; + + match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0; + if (match && whole_lines && offsets[1] != length) match = FALSE; + + if (match != invert) + { + if (count_only) count++; + + else if (filenames_only) + { + fprintf(stdout, "%s\n", (name == NULL)? "" : name); + return 0; + } + + else if (silent) return 0; + + else + { + if (name != NULL) fprintf(stdout, "%s:", name); + if (number) fprintf(stdout, "%d:", linenumber); + fprintf(stdout, "%s\n", buffer); + } + + rc = 0; + } + } + +if (count_only) + { + if (name != NULL) fprintf(stdout, "%s:", name); + fprintf(stdout, "%d\n", count); + } + +return rc; +} + + + + +/************************************************* +* Usage function * +*************************************************/ + +static int +usage(int rc) +{ +fprintf(stderr, "Usage: pgrep [-Vchilnsvx] pattern [file] ...\n"); +return rc; +} + + + + +/************************************************* +* Main program * +*************************************************/ + +int +main(int argc, char **argv) +{ +int i; +int rc = 1; +int options = 0; +int errptr; +const char *error; +BOOL filenames = TRUE; + +/* Process the options */ + +for (i = 1; i < argc; i++) + { + char *s; + if (argv[i][0] != '-') break; + s = argv[i] + 1; + while (*s != 0) + { + switch (*s++) + { + case 'c': count_only = TRUE; break; + case 'h': filenames = FALSE; break; + case 'i': options |= PCRE_CASELESS; break; + case 'l': filenames_only = TRUE; + case 'n': number = TRUE; break; + case 's': silent = TRUE; break; + case 'v': invert = TRUE; break; + case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; + + case 'V': + fprintf(stderr, "PCRE version %s\n", pcre_version()); + break; + + default: + fprintf(stderr, "pgrep: unknown option %c\n", s[-1]); + return usage(2); + } + } + } + +/* There must be at least a regexp argument */ + +if (i >= argc) return usage(0); + +/* Compile the regular expression. */ + +pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL); +if (pattern == NULL) + { + fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error); + return 2; + } + +/* Study the regular expression, as we will be running it may times */ + +hints = pcre_study(pattern, 0, &error); +if (error != NULL) + { + fprintf(stderr, "pgrep: error while studing regex: %s\n", error); + return 2; + } + +/* If there are no further arguments, do the business on stdin and exit */ + +if (i >= argc) return pgrep(stdin, NULL); + +/* Otherwise, work through the remaining arguments as files. If there is only +one, don't give its name on the output. */ + +if (i == argc - 1) filenames = FALSE; +if (filenames_only) filenames = TRUE; + +for (; i < argc; i++) + { + FILE *in = fopen(argv[i], "r"); + if (in == NULL) + { + fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno)); + rc = 2; + } + else + { + int frc = pgrep(in, filenames? argv[i] : NULL); + if (frc == 0 && rc == 1) rc = 0; + fclose(in); + } + } + +return rc; +} + +/* End */ diff --git a/trunk/srclib/pcre/printint.c b/trunk/srclib/pcre/printint.c new file mode 100644 index 0000000000..8e5da42684 --- /dev/null +++ b/trunk/srclib/pcre/printint.c @@ -0,0 +1,461 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains a debugging function for printing out the internal form +of a compiled regular expression. It is kept in a separate file so that it can +be #included both in the pcretest program, and in the library itself when +compiled with the debugging switch. */ + + +static const char *OP_names[] = { OP_NAME_LIST }; + + +/************************************************* +* Print single- or multi-byte character * +*************************************************/ + +/* These tables are actually copies of ones in pcre.c. If we compile the +library with debugging, they are included twice, but that isn't really a +problem - compiling with debugging is pretty rare and these are very small. */ + +static const int utf8_t3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +static const uschar utf8_t4[] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; + +static int +print_char(FILE *f, uschar *ptr, BOOL utf8) +{ +int c = *ptr; + +if (!utf8 || (c & 0xc0) != 0xc0) + { + if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); + return 0; + } +else + { + int i; + int a = utf8_t4[c & 0x3f]; /* Number of additional bytes */ + int s = 6*a; + c = (c & utf8_t3[a]) << s; + for (i = 1; i <= a; i++) + { + /* This is a check for malformed UTF-8; it should only occur if the sanity + check has been turned off. Rather than swallow random bytes, just stop if + we hit a bad one. Print it with \X instead of \x as an indication. */ + + if ((ptr[i] & 0xc0) != 0x80) + { + fprintf(f, "\\X{%x}", c); + return i - 1; + } + + /* The byte is OK */ + + s -= 6; + c |= (ptr[i] & 0x3f) << s; + } + if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); + return a; + } +} + + + + +/************************************************* +* Find Unicode property name * +*************************************************/ + +static const char * +get_ucpname(int property) +{ +int i; +for (i = sizeof(utt)/sizeof(ucp_type_table); i >= 0; i--) + { + if (property == utt[i].value) break; + } +return (i >= 0)? utt[i].name : "??"; +} + + + +/************************************************* +* Print compiled regex * +*************************************************/ + +/* Make this function work for a regex with integers either byte order. +However, we assume that what we are passed is a compiled regex. */ + +static void +print_internals(pcre *external_re, FILE *f) +{ +real_pcre *re = (real_pcre *)external_re; +uschar *codestart, *code; +BOOL utf8; + +unsigned int options = re->options; +int offset = re->name_table_offset; +int count = re->name_count; +int size = re->name_entry_size; + +if (re->magic_number != MAGIC_NUMBER) + { + offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); + count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); + size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); + options = ((options << 24) & 0xff000000) | + ((options << 8) & 0x00ff0000) | + ((options >> 8) & 0x0000ff00) | + ((options >> 24) & 0x000000ff); + } + +code = codestart = (uschar *)re + offset + count * size; +utf8 = (options & PCRE_UTF8) != 0; + +for(;;) + { + uschar *ccode; + int c; + int extra = 0; + + fprintf(f, "%3d ", code - codestart); + + if (*code >= OP_BRA) + { + if (*code - OP_BRA > EXTRACT_BASIC_MAX) + fprintf(f, "%3d Bra extra\n", GET(code, 1)); + else + fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA); + code += OP_lengths[OP_BRA]; + continue; + } + + switch(*code) + { + case OP_END: + fprintf(f, " %s\n", OP_names[*code]); + fprintf(f, "------------------------------------------------------------------\n"); + return; + + case OP_OPT: + fprintf(f, " %.2x %s", code[1], OP_names[*code]); + break; + + case OP_CHAR: + { + fprintf(f, " "); + do + { + code++; + code += 1 + print_char(f, code, utf8); + } + while (*code == OP_CHAR); + fprintf(f, "\n"); + continue; + } + break; + + case OP_CHARNC: + { + fprintf(f, " NC "); + do + { + code++; + code += 1 + print_char(f, code, utf8); + } + while (*code == OP_CHARNC); + fprintf(f, "\n"); + continue; + } + break; + + case OP_KETRMAX: + case OP_KETRMIN: + case OP_ALT: + case OP_KET: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_COND: + case OP_REVERSE: + fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); + break; + + case OP_BRANUMBER: + printf("%3d %s", GET2(code, 1), OP_names[*code]); + break; + + case OP_CREF: + if (GET2(code, 1) == CREF_RECURSE) + fprintf(f, " Cond recurse"); + else + fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + fprintf(f, " "); + if (*code >= OP_TYPESTAR) + { + fprintf(f, "%s", OP_names[code[1]]); + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[2])); + extra = 1; + } + } + else extra = print_char(f, code+1, utf8); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + fprintf(f, " "); + extra = print_char(f, code+3, utf8); + fprintf(f, "{"); + if (*code != OP_EXACT) fprintf(f, ","); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_MINUPTO) fprintf(f, "?"); + break; + + case OP_TYPEEXACT: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + fprintf(f, " %s", OP_names[code[3]]); + if (code[3] == OP_PROP || code[3] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[4])); + extra = 1; + } + fprintf(f, "{"); + if (*code != OP_TYPEEXACT) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); + break; + + case OP_NOT: + if (isprint(c = code[1])) fprintf(f, " [^%c]", c); + else fprintf(f, " [^\\x%02x]", c); + break; + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + if (isprint(c = code[1])) fprintf(f, " [^%c]", c); + else fprintf(f, " [^\\x%02x]", c); + fprintf(f, "%s", OP_names[*code]); + break; + + case OP_NOTEXACT: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + if (isprint(c = code[3])) fprintf(f, " [^%c]{", c); + else fprintf(f, " [^\\x%02x]{", c); + if (*code != OP_NOTEXACT) fprintf(f, ","); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_NOTMINUPTO) fprintf(f, "?"); + break; + + case OP_RECURSE: + fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); + break; + + case OP_REF: + fprintf(f, " \\%d", GET2(code,1)); + ccode = code + OP_lengths[*code]; + goto CLASS_REF_REPEAT; + + case OP_CALLOUT: + fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2), + GET(code, 2 + LINK_SIZE)); + break; + + case OP_PROP: + case OP_NOTPROP: + fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1])); + break; + + /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in + having this code always here, and it makes it less messy without all those + #ifdefs. */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + int i, min, max; + BOOL printmap; + + fprintf(f, " ["); + + if (*code == OP_XCLASS) + { + extra = GET(code, 1); + ccode = code + LINK_SIZE + 1; + printmap = (*ccode & XCL_MAP) != 0; + if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); + } + else + { + printmap = TRUE; + ccode = code + 1; + } + + /* Print a bit map */ + + if (printmap) + { + for (i = 0; i < 256; i++) + { + if ((ccode[i/8] & (1 << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((ccode[j/8] & (1 << (j&7))) == 0) break; + if (i == '-' || i == ']') fprintf(f, "\\"); + if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i); + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == ']') fprintf(f, "\\"); + if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j); + } + i = j; + } + } + ccode += 32; + } + + /* For an XCLASS there is always some additional data */ + + if (*code == OP_XCLASS) + { + int ch; + while ((ch = *ccode++) != XCL_END) + { + if (ch == XCL_PROP) + { + fprintf(f, "\\p{%s}", get_ucpname(*ccode++)); + } + else if (ch == XCL_NOTPROP) + { + fprintf(f, "\\P{%s}", get_ucpname(*ccode++)); + } + else + { + ccode += 1 + print_char(f, ccode, TRUE); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, TRUE); + } + } + } + } + + /* Indicate a non-UTF8 class which was created by negation */ + + fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); + + /* Handle repeats after a class or a back reference */ + + CLASS_REF_REPEAT: + switch(*ccode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + fprintf(f, "%s", OP_names[*ccode]); + extra += OP_lengths[*ccode]; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(ccode,1); + max = GET2(ccode,3); + if (max == 0) fprintf(f, "{%d,}", min); + else fprintf(f, "{%d,%d}", min, max); + if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); + extra += OP_lengths[*ccode]; + break; + } + } + break; + + /* Anything else is just an item with no data*/ + + default: + fprintf(f, " %s", OP_names[*code]); + break; + } + + code += OP_lengths[*code] + extra; + fprintf(f, "\n"); + } +} + +/* End of printint.c */ diff --git a/trunk/srclib/pcre/study.c b/trunk/srclib/pcre/study.c new file mode 100644 index 0000000000..d67070a4b3 --- /dev/null +++ b/trunk/srclib/pcre/study.c @@ -0,0 +1,484 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. +----------------------------------------------------------------------------- +*/ + + +/* Include the internals header, which itself includes Standard C headers plus +the external pcre header. */ + +#include "internal.h" + + + +/************************************************* +* Set a bit and maybe its alternate case * +*************************************************/ + +/* Given a character, set its bit in the table, and also the bit for the other +version of a letter if we are caseless. + +Arguments: + start_bits points to the bit map + c is the character + caseless the caseless flag + cd the block with char table pointers + +Returns: nothing +*/ + +static void +set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd) +{ +start_bits[c/8] |= (1 << (c&7)); +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) + start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7)); +} + + + +/************************************************* +* Create bitmap of starting chars * +*************************************************/ + +/* This function scans a compiled unanchored expression and attempts to build a +bitmap of the set of initial characters. If it can't, it returns FALSE. As time +goes by, we may be able to get more clever at doing this. + +Arguments: + code points to an expression + start_bits points to a 32-byte table, initialized to 0 + caseless the current state of the caseless flag + utf8 TRUE if in UTF-8 mode + cd the block with char table pointers + +Returns: TRUE if table built, FALSE otherwise +*/ + +static BOOL +set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, + BOOL utf8, compile_data *cd) +{ +register int c; + +/* This next statement and the later reference to dummy are here in order to +trick the optimizer of the IBM C compiler for OS/2 into generating correct +code. Apparently IBM isn't going to fix the problem, and we would rather not +disable optimization (in this module it actually makes a big difference, and +the pcre module can use all the optimization it can get). */ + +volatile int dummy; + +do + { + const uschar *tcode = code + 1 + LINK_SIZE; + BOOL try_next = TRUE; + + while (try_next) + { + /* If a branch starts with a bracket or a positive lookahead assertion, + recurse to set bits from within them. That's all for this branch. */ + + if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT) + { + if (!set_start_bits(tcode, start_bits, caseless, utf8, cd)) + return FALSE; + try_next = FALSE; + } + + else switch(*tcode) + { + default: + return FALSE; + + /* Skip over callout */ + + case OP_CALLOUT: + tcode += 2 + 2*LINK_SIZE; + break; + + /* Skip over extended extraction bracket number */ + + case OP_BRANUMBER: + tcode += 3; + break; + + /* Skip over lookbehind and negative lookahead assertions */ + + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + do tcode += GET(tcode, 1); while (*tcode == OP_ALT); + tcode += 1+LINK_SIZE; + break; + + /* Skip over an option setting, changing the caseless flag */ + + case OP_OPT: + caseless = (tcode[1] & PCRE_CASELESS) != 0; + tcode += 2; + break; + + /* BRAZERO does the bracket, but carries on. */ + + case OP_BRAZERO: + case OP_BRAMINZERO: + if (!set_start_bits(++tcode, start_bits, caseless, utf8, cd)) + return FALSE; + dummy = 1; + do tcode += GET(tcode,1); while (*tcode == OP_ALT); + tcode += 1+LINK_SIZE; + break; + + /* Single-char * or ? sets the bit and tries the next item */ + + case OP_STAR: + case OP_MINSTAR: + case OP_QUERY: + case OP_MINQUERY: + set_bit(start_bits, tcode[1], caseless, cd); + tcode += 2; +#ifdef SUPPORT_UTF8 + if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; +#endif + break; + + /* Single-char upto sets the bit and tries the next */ + + case OP_UPTO: + case OP_MINUPTO: + set_bit(start_bits, tcode[3], caseless, cd); + tcode += 4; +#ifdef SUPPORT_UTF8 + if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; +#endif + break; + + /* At least one single char sets the bit and stops */ + + case OP_EXACT: /* Fall through */ + tcode += 2; + + case OP_CHAR: + case OP_CHARNC: + case OP_PLUS: + case OP_MINPLUS: + set_bit(start_bits, tcode[1], caseless, cd); + try_next = FALSE; + break; + + /* Single character type sets the bits and stops */ + + case OP_NOT_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_digit]; + try_next = FALSE; + break; + + case OP_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_digit]; + try_next = FALSE; + break; + + case OP_NOT_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_space]; + try_next = FALSE; + break; + + case OP_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_space]; + try_next = FALSE; + break; + + case OP_NOT_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_word]; + try_next = FALSE; + break; + + case OP_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_word]; + try_next = FALSE; + break; + + /* One or more character type fudges the pointer and restarts, knowing + it will hit a single character type and stop there. */ + + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + tcode++; + break; + + case OP_TYPEEXACT: + tcode += 3; + break; + + /* Zero or more repeats of character types set the bits and then + try again. */ + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + tcode += 2; /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + switch(tcode[1]) + { + case OP_ANY: + return FALSE; + + case OP_NOT_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_digit]; + break; + + case OP_DIGIT: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_digit]; + break; + + case OP_NOT_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_space]; + break; + + case OP_WHITESPACE: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_space]; + break; + + case OP_NOT_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= ~cd->cbits[c+cbit_word]; + break; + + case OP_WORDCHAR: + for (c = 0; c < 32; c++) + start_bits[c] |= cd->cbits[c+cbit_word]; + break; + } + + tcode += 2; + break; + + /* Character class where all the information is in a bit map: set the + bits and either carry on or not, according to the repeat count. If it was + a negative class, and we are operating with UTF-8 characters, any byte + with a value >= 0xc4 is a potentially valid starter because it starts a + character with a value > 255. */ + + case OP_NCLASS: + if (utf8) + { + start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ + memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ + } + /* Fall through */ + + case OP_CLASS: + { + tcode++; + + /* In UTF-8 mode, the bits in a bit map correspond to character + values, not to byte values. However, the bit map we are constructing is + for byte values. So we have to do a conversion for characters whose + value is > 127. In fact, there are only two possible starting bytes for + characters in the range 128 - 255. */ + + if (utf8) + { + for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; + for (c = 128; c < 256; c++) + { + if ((tcode[c/8] && (1 << (c&7))) != 0) + { + int d = (c >> 6) | 0xc0; /* Set bit for this starter */ + start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + } + } + } + + /* In non-UTF-8 mode, the two bit maps are completely compatible. */ + + else + { + for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; + } + + /* Advance past the bit map, and act on what follows */ + + tcode += 32; + switch (*tcode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + tcode++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; + else try_next = FALSE; + break; + + default: + try_next = FALSE; + break; + } + } + break; /* End of bitmap class handling */ + + } /* End of switch */ + } /* End of try_next loop */ + + code += GET(code, 1); /* Advance to next branch */ + } +while (*code == OP_ALT); +return TRUE; +} + + + +/************************************************* +* Study a compiled expression * +*************************************************/ + +/* This function is handed a compiled expression that it must study to produce +information that will speed up the matching. It returns a pcre_extra block +which then gets handed back to pcre_exec(). + +Arguments: + re points to the compiled expression + options contains option bits + errorptr points to where to place error messages; + set NULL unless error + +Returns: pointer to a pcre_extra block, with study_data filled in and the + appropriate flag set; + NULL on error or if no optimization possible +*/ + +EXPORT pcre_extra * +pcre_study(const pcre *external_re, int options, const char **errorptr) +{ +uschar start_bits[32]; +pcre_extra *extra; +pcre_study_data *study; +const uschar *tables; +const real_pcre *re = (const real_pcre *)external_re; +uschar *code = (uschar *)re + re->name_table_offset + + (re->name_count * re->name_entry_size); +compile_data compile_block; + +*errorptr = NULL; + +if (re == NULL || re->magic_number != MAGIC_NUMBER) + { + *errorptr = "argument is not a compiled regular expression"; + return NULL; + } + +if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) + { + *errorptr = "unknown or incorrect option bit(s) set"; + return NULL; + } + +/* For an anchored pattern, or an unanchored pattern that has a first char, or +a multiline pattern that matches only at "line starts", no further processing +at present. */ + +if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) + return NULL; + +/* Set the character tables in the block that is passed around */ + +tables = re->tables; +if (tables == NULL) + (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void*)&tables); + +compile_block.lcc = tables + lcc_offset; +compile_block.fcc = tables + fcc_offset; +compile_block.cbits = tables + cbits_offset; +compile_block.ctypes = tables + ctypes_offset; + +/* See if we can find a fixed set of initial characters for the pattern. */ + +memset(start_bits, 0, 32 * sizeof(uschar)); +if (!set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0, + (re->options & PCRE_UTF8) != 0, &compile_block)) return NULL; + +/* Get a pcre_extra block and a pcre_study_data block. The study data is put in +the latter, which is pointed to by the former, which may also get additional +data set later by the calling program. At the moment, the size of +pcre_study_data is fixed. We nevertheless save it in a field for returning via +the pcre_fullinfo() function so that if it becomes variable in the future, we +don't have to change that code. */ + +extra = (pcre_extra *)(pcre_malloc) + (sizeof(pcre_extra) + sizeof(pcre_study_data)); + +if (extra == NULL) + { + *errorptr = "failed to get memory"; + return NULL; + } + +study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); +extra->flags = PCRE_EXTRA_STUDY_DATA; +extra->study_data = study; + +study->size = sizeof(pcre_study_data); +study->options = PCRE_STUDY_MAPPED; +memcpy(study->start_bits, start_bits, sizeof(start_bits)); + +return extra; +} + +/* End of study.c */ diff --git a/trunk/srclib/pcre/testdata/testinput1 b/trunk/srclib/pcre/testdata/testinput1 new file mode 100644 index 0000000000..c4b99c66b4 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput1 @@ -0,0 +1,3841 @@ +/the quick brown fox/ + the quick brown fox + The quick brown FOX + What do you know about the quick brown fox? + What do you know about THE QUICK BROWN FOX? + +/The quick brown fox/i + the quick brown fox + The quick brown FOX + What do you know about the quick brown fox? + What do you know about THE QUICK BROWN FOX? + +/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ + abcd\t\n\r\f\a\e9;\$\\?caxyz + +/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ + abxyzpqrrrabbxyyyypqAzz + abxyzpqrrrabbxyyyypqAzz + aabxyzpqrrrabbxyyyypqAzz + aaabxyzpqrrrabbxyyyypqAzz + aaaabxyzpqrrrabbxyyyypqAzz + abcxyzpqrrrabbxyyyypqAzz + aabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypAzz + aaabcxyzpqrrrabbxyyyypqAzz + aaabcxyzpqrrrabbxyyyypqqAzz + aaabcxyzpqrrrabbxyyyypqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqAzz + aaaabcxyzpqrrrabbxyyyypqAzz + abxyzzpqrrrabbxyyyypqAzz + aabxyzzzpqrrrabbxyyyypqAzz + aaabxyzzzzpqrrrabbxyyyypqAzz + aaaabxyzzzzpqrrrabbxyyyypqAzz + abcxyzzpqrrrabbxyyyypqAzz + aabcxyzzzpqrrrabbxyyyypqAzz + aaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyypqAzz + aaabcxyzpqrrrabbxyyyypABzz + aaabcxyzpqrrrabbxyyyypABBzz + >>>aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + *** Failers + abxyzpqrrabbxyyyypqAzz + abxyzpqrrrrabbxyyyypqAzz + abxyzpqrrrabxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyypqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz + +/^(abc){1,2}zz/ + abczz + abcabczz + *** Failers + zz + abcabcabczz + >>abczz + +/^(b+?|a){1,2}?c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac + *** Failers + aaac + abbbbbbbbbbbac + +/^(b+|a){1,2}c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac + *** Failers + aaac + abbbbbbbbbbbac + +/^(b+|a){1,2}?bc/ + bbc + +/^(b*|ba){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^(ba|b*){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + +/^[ab\]cde]/ + athing + bthing + ]thing + cthing + dthing + ething + *** Failers + fthing + [thing + \\thing + +/^[]cde]/ + ]thing + cthing + dthing + ething + *** Failers + athing + fthing + +/^[^ab\]cde]/ + fthing + [thing + \\thing + *** Failers + athing + bthing + ]thing + cthing + dthing + ething + +/^[^]cde]/ + athing + fthing + *** Failers + ]thing + cthing + dthing + ething + +/^\/ + + +/^ÿ/ + ÿ + +/^[0-9]+$/ + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + *** Failers + abc + +/^.*nter/ + enter + inter + uponter + +/^xxx[0-9]+$/ + xxx0 + xxx1234 + *** Failers + xxx + +/^.+[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + *** Failers + !pqr=apquxz.ixr.zzz.ac.uk + abc!=apquxz.ixr.zzz.ac.uk + abc!pqr=apquxz:ixr.zzz.ac.uk + abc!pqr=apquxz.ixr.zzz.ac.ukk + +/:/ + Well, we need a colon: somewhere + *** Fail if we don't + +/([\da-f:]+)$/i + 0abc + abc + fed + E + :: + 5f03:12C0::932e + fed def + Any old stuff + *** Failers + 0zzz + gzzz + fed\x20 + Any old rubbish + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + A.12.123.0 + *** Failers + .1.2.3333 + 1.2.3 + 1234.2.3 + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 1 IN SOA non-sp1 non-sp2 ( + *** Failers + 1IN SOA non-sp1 non-sp2( + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + Z. + 2. + ab-c.pq-r. + sxk.zzz.ac.uk. + x-.y-. + *** Failers + -abc.peq. + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + *.b0-a + *.c3-b.c + *.c-a.b-c + *** Failers + *.0 + *.a- + *.a-b.c- + *.c-a.0-c + +/^(?=ab(de))(abd)(e)/ + abde + +/^(?!(ab)de|x)(abd)(f)/ + abdf + +/^(?=(ab(cd)))(ab)/ + abcd + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + A.B.C.D + a.b.c.1.2.3.C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + \"abcd\" ; + \"\" ; rhubarb + *** Failers + \"1234\" : things + +/^$/ + \ + *** Failers + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + *** Failers + abc + ab cde + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + *** Failers + abc + ab cde + +/^ a\ b[c ]d $/x + a bcd + a b d + *** Failers + abcd + ab d + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + +/^a*\w/ + z + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a*?\w/ + z + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a+\w/ + az + aaaz + aa + aaaa + aa+ + +/^a+?\w/ + az + aaaz + aa + aaaa + aa+ + +/^\d{8}\w{2,}/ + 1234567890 + 12345678ab + 12345678__ + *** Failers + 1234567 + +/^[aeiou\d]{4,5}$/ + uoie + 1234 + 12345 + aaaaa + *** Failers + 123456 + +/^[aeiou\d]{4,5}?/ + uoie + 1234 + 12345 + aaaaa + 123456 + +/\A(abc|def)=(\1){2,3}\Z/ + abc=abcabc + def=defdefdef + *** Failers + abc=defdef + +/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ + abcdefghijkcda2 + abcdefghijkkkkcda2 + +/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ + cataract cataract23 + catatonic catatonic23 + caterpillar caterpillar23 + + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + From abcd Mon Sep 1 12:33:02 1997 + *** Failers + From abcd Sep 01 12:33:02 1997 + +/^12.34/s + 12\n34 + 12\r34 + +/\w+(?=\t)/ + the quick brown\t fox + +/foo(?!bar)(.*)/ + foobar is foolish see? + +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + barrel + 2barrel + A barrel + +/^(\D*)(?=\d)(?!123)/ + abc456 + *** Failers + abc123 + +/^1234(?# test newlines + inside)/ + 1234 + +/^1234 #comment in extended re + /x + 1234 + +/#rhubarb + abcd/x + abcd + +/^abcd#rhubarb/x + abcd + +/^(a)\1{2,3}(.)/ + aaab + aaaab + aaaaab + aaaaaab + +/(?!^)abc/ + the abc + *** Failers + abc + +/(?=^)abc/ + abc + *** Failers + the abc + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle ]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + +/a[^a]b/ + acb + a\nb + +/a.b/ + acb + *** Failers + a\nb + +/a[^a]b/s + acb + a\nb + +/a.b/s + acb + a\nb + +/^(b+?|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/^(b+|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/(?!\A)x/m + x\nb\n + a\bx\n + +/\x0{ab}/ + \0{ab} + +/(A|B)*?CD/ + CD + +/(A|B)*CD/ + CD + +/(AB)*?\1/ + ABABAB + +/(AB)*\1/ + ABABAB + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\d\d[1-9]?))\d+/ + 1.230003938 + 1.875000282 + *** Failers + 1.235 + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d+)(\w)/ + 12345a + 12345+ + +/((?>\d+))(\w)/ + 12345a + *** Failers + 12345+ + +/(?>a+)b/ + aaab + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/(?>b)+/ + aaabbbccc + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/a(?-i)b/i + ab + Ab + *** Failers + aB + AB + +/(a (?x)b c)d e/ + a bcd e + *** Failers + a b cd e + abcd e + a bcde + +/(a b(?x)c d (?-x)e f)/ + a bcde f + *** Failers + abcdef + +/(a(?i)b)c/ + abc + aBc + *** Failers + abC + aBC + Abc + ABc + ABC + AbC + +/a(?i:b)c/ + abc + aBc + *** Failers + ABC + abC + aBC + +/a(?i:b)*c/ + aBc + aBBc + *** Failers + aBC + aBBC + +/a(?=b(?i)c)\w\wd/ + abcd + abCd + *** Failers + aBCd + abcD + +/(?s-i:more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?:(?s-i)more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?>a(?i)b+)+c/ + abc + aBbc + aBBc + *** Failers + Abc + abAb + abbC + +/(?=a(?i)b)\w\wc/ + abc + aBc + *** Failers + Ab + abC + aBC + +/(?<=a(?i)b)(\w\w)c/ + abxxc + aBxxc + *** Failers + Abxxc + ABxxc + abxxC + +/(?:(a)|b)(?(1)A|B)/ + aA + bB + *** Failers + aB + bA + +/^(a)?(?(1)a|b)+$/ + aa + b + bb + *** Failers + ab + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 12 + *** Failers + 123 + xyz + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 12 + *** Failers + 123 + xyz + +/(?(?<=foo)bar|cat)/ + foobar + cat + fcat + focat + *** Failers + foocat + +/(?(?a*)*/ + a + aa + aaaa + +/(abc|)+/ + abc + abcabc + abcabcabc + xyz + +/([a]*)*/ + a + aaaaa + +/([ab]*)*/ + a + b + ababab + aaaabcde + bbbb + +/([^a]*)*/ + b + bbbb + aaa + +/([^ab]*)*/ + cccc + abab + +/([a]*?)*/ + a + aaaa + +/([ab]*?)*/ + a + b + abab + baba + +/([^a]*?)*/ + b + bbbb + aaa + +/([^ab]*?)*/ + c + cccc + baba + +/(?>a*)*/ + a + aaabcde + +/((?>a*))*/ + aaaaa + aabbaa + +/((?>a*?))*/ + aaaaa + aabbaa + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 12-09-98 + *** Failers + sep-12-98 + +/(?<=(foo))bar\1/ + foobarfoo + foobarfootling + *** Failers + foobar + barfoo + +/(?i:saturday|sunday)/ + saturday + sunday + Saturday + Sunday + SATURDAY + SUNDAY + SunDay + +/(a(?i)bc|BB)x/ + abcx + aBCx + bbx + BBx + *** Failers + abcX + aBCX + bbX + BBX + +/^([ab](?i)[cd]|[ef])/ + ac + aC + bD + elephant + Europe + frog + France + *** Failers + Africa + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + aBd + xy + xY + zebra + Zambesi + *** Failers + aCD + XY + +/(?<=foo\n)^bar/m + foo\nbar + *** Failers + bar + baz\nbar + +/(?<=(?]&/ + <&OUT + +/^(a\1?){4}$/ + aaaaaaaaaa + *** Failers + AB + aaaaaaaaa + aaaaaaaaaaa + +/^(a(?(1)\1)){4}$/ + aaaaaaaaaa + *** Failers + aaaaaaaaa + aaaaaaaaaaa + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + +/(?<=a)b/ + ab + *** Failers + cb + b + +/(?a+)ab/ + +/(?>a+)b/ + aaab + +/([[:]+)/ + a:[b]: + +/([[=]+)/ + a=[b]= + +/([[.]+)/ + a.[b]. + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/a\Z/ + *** Failers + aaab + a\nb\n + +/b\Z/ + a\nb\n + +/b\z/ + +/b\Z/ + a\nb + +/b\z/ + a\nb + *** Failers + +/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ + a + abc + a-b + 0-9 + a.b + 5.6.7 + the.quick.brown.fox + a100.b200.300c + 12-ab.1245 + *** Failers + \ + .a + -a + a- + a. + a_b + a.- + a.. + ab..bc + the.quick.brown.fox- + the.quick.brown.fox. + the.quick.brown.fox_ + the.quick.brown.fox+ + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + endingwxyz + *** Failers + a rather long string that doesn't end with one of them + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/(?<=\d{3}(?!999))foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=(?!...999)\d{3})foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 123456foo + *** Failers + 123999foo + +/(?<=\d{3}...)(?\s*)=(?>\s*) # find Z)+|A)*/ + ZABCDEFG + +/((?>)+|A)*/ + ZABCDEFG + +/a*/g + abbab + +/^[a-\d]/ + abcde + -things + 0digit + *** Failers + bcdef + +/^[\d-a]/ + abcde + -things + 0digit + *** Failers + bcdef + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + +/a b/x + ab + +/(?!\A)x/m + a\nxb\n + +/(?!^)x/m + a\nxb\n + +/abc\Qabc\Eabc/ + abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + *** Failers + abcabcabc + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + +/\Gabc/ + abc + *** Failers + xyzabc + +/\Gabc./g + abc1abc2xyzabc3 + +/abc./g + abc1abc2xyzabc3 + +/a(?x: b c )d/ + XabcdY + *** Failers + Xa b c d Y + +/((?x)x y z | a b c)/ + XabcY + AxyzB + +/(?i)AB(?-i)C/ + XabCY + *** Failers + XabcY + +/((?i)AB(?-i)C|D)E/ + abCE + DE + *** Failers + abcE + abCe + dE + De + +/(.*)\d+\1/ + abc123abc + abc123bc + +/(.*)\d+\1/s + abc123abc + abc123bc + +/((.*))\d+\1/ + abc123abc + abc123bc + +/-- This tests for an IPv6 address in the form where it can have up to --/ +/-- eight components, one and only one of which is empty. This must be --/ +/-- an internal component. --/ + +/^(?!:) # colon disallowed at start + (?: # start of item + (?: [0-9a-f]{1,4} | # 1-4 hex digits or + (?(1)0 | () ) ) # if null previously matched, fail; else null + : # followed by colon + ){1,7} # end item; 1-7 of them required + [0-9a-f]{1,4} $ # final hex number at end of string + (?(1)|.) # check that there was an empty component + /xi + a123::a123 + a123:b342::abcd + a123:b342::324e:abcd + a123:ddde:b342::324e:abcd + a123:ddde:b342::324e:dcba:abcd + a123:ddde:9999:b342::324e:dcba:abcd + *** Failers + 1:2:3:4:5:6:7:8 + a123:bce:ddde:9999:b342::324e:dcba:abcd + a123::9999:b342::324e:dcba:abcd + abcde:2:3:4:5:6:7:8 + ::1 + abcd:fee0:123:: + :1 + 1: + +/[z\Qa-d]\E]/ + z + a + - + d + ] + *** Failers + b + +/[\z\C]/ + z + C + +/\M/ + M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + regulaer + Regex + regulär + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + Åæåäÿ + ÅæåäÀ + Åæåäß + +/(?<=Z)X./ + \x84XAZXB + +/ End of testinput1 / diff --git a/trunk/srclib/pcre/testdata/testinput2 b/trunk/srclib/pcre/testdata/testinput2 new file mode 100644 index 0000000000..d118daf8f1 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput2 @@ -0,0 +1,1396 @@ +/(a)b|/ + +/abc/ + abc + defabc + \Aabc + *** Failers + \Adefabc + ABC + +/^abc/ + abc + \Aabc + *** Failers + defabc + \Adefabc + +/a+bc/ + +/a*bc/ + +/a{3}bc/ + +/(abc|a+z)/ + +/^abc$/ + abc + *** Failers + def\nabc + +/ab\gdef/X + +/(?X)ab\gdef/X + +/x{5,4}/ + +/z{65536}/ + +/[abcd/ + +/(?X)[\B]/ + +/[z-a]/ + +/^*/ + +/(abc/ + +/(?# abc/ + +/(?z)abc/ + +/.*b/ + +/.*?b/ + +/cat|dog|elephant/ + this sentence eventually mentions a cat + this sentences rambles on and on for a while and then reaches elephant + +/cat|dog|elephant/S + this sentence eventually mentions a cat + this sentences rambles on and on for a while and then reaches elephant + +/cat|dog|elephant/iS + this sentence eventually mentions a CAT cat + this sentences rambles on and on for a while to elephant ElePhant + +/a|[bcd]/S + +/(a|[^\dZ])/S + +/(a|b)*[\s]/S + +/(ab\2)/ + +/{4,5}abc/ + +/(a)(b)(c)\2/ + abcb + \O0abcb + \O3abcb + \O6abcb + \O9abcb + \O12abcb + +/(a)bc|(a)(b)\2/ + abc + \O0abc + \O3abc + \O6abc + aba + \O0aba + \O3aba + \O6aba + \O9aba + \O12aba + +/abc$/E + abc + *** Failers + abc\n + abc\ndef + +/(a)(b)(c)(d)(e)\6/ + +/the quick brown fox/ + the quick brown fox + this is a line with the quick brown fox + +/the quick brown fox/A + the quick brown fox + *** Failers + this is a line with the quick brown fox + +/ab(?z)cd/ + +/^abc|def/ + abcdef + abcdef\B + +/.*((abc)$|(def))/ + defabc + \Zdefabc + +/abc/P + abc + *** Failers + +/^abc|def/P + abcdef + abcdef\B + +/.*((abc)$|(def))/P + defabc + \Zdefabc + +/the quick brown fox/P + the quick brown fox + *** Failers + The Quick Brown Fox + +/the quick brown fox/Pi + the quick brown fox + The Quick Brown Fox + +/abc.def/P + *** Failers + abc\ndef + +/abc$/P + abc + abc\n + +/(abc)\2/P + +/(abc\1)/P + abc + +/)/ + +/a[]b/ + +/[^aeiou ]{3,}/ + co-processors, and for + +/<.*>/ + abcghinop + +/<.*?>/ + abcghinop + +/<.*>/U + abcghinop + +/(?U)<.*>/ + abcghinop + +/<.*?>/U + abcghinop + +/={3,}/U + abc========def + +/(?U)={3,}?/ + abc========def + +/(?^abc)/m + abc + def\nabc + *** Failers + defabc + +/(?<=ab(c+)d)ef/ + +/(?<=ab(?<=c+)d)ef/ + +/(?<=ab(c|de)f)g/ + +/The next three are in testinput2 because they have variable length branches/ + +/(?<=bullock|donkey)-cart/ + the bullock-cart + a donkey-cart race + *** Failers + cart + horse-and-cart + +/(?<=ab(?i)x|y|z)/ + +/(?>.*)(?<=(abcd)|(xyz))/ + alphabetabcd + endingxyz + +/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/ + abxyZZ + abXyZZ + ZZZ + zZZ + bZZ + BZZ + *** Failers + ZZ + abXYZZ + zzz + bzz + +/(?[^()]+) # Either a sequence of non-brackets (no backtracking) + | # Or + (?R) # Recurse - i.e. nested bracketed string + )* # Zero or more contents + \) # Closing ) + /x + (abcd) + (abcd)xyz + xyz(abcd) + (ab(xy)cd)pqr + (ab(xycd)pqr + () abc () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + *** Failers + abcd + abcd) + (abcd + +/\( ( (?>[^()]+) | (?R) )* \) /xg + (ab(xy)cd)pqr + 1(abcd)(x(y)z)pqr + +/\( (?: (?>[^()]+) | (?R) ) \) /x + (abcd) + (ab(xy)cd) + (a(b(c)d)e) + ((ab)) + *** Failers + () + +/\( (?: (?>[^()]+) | (?R) )? \) /x + () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + +/\( ( (?>[^()]+) | (?R) )* \) /x + (ab(xy)cd) + +/\( ( ( (?>[^()]+) | (?R) )* ) \) /x + (ab(xy)cd) + +/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x + (ab(xy)cd) + (123ab(xy)cd) + +/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x + (ab(xy)cd) + (123ab(xy)cd) + +/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x + (ab(xy)cd) + +/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x + (abcd(xyz

    qrs)123) + +/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x + (ab(cd)ef) + (ab(cd(ef)gh)ij) + +/^[[:alnum:]]/D + +/^[[:^alnum:]]/D + +/^[[:alpha:]]/D + +/^[[:^alpha:]]/D + +/^[[:ascii:]]/D + +/^[[:^ascii:]]/D + +/^[[:blank:]]/D + +/^[[:cntrl:]]/D + +/^[[:digit:]]/D + +/^[[:graph:]]/D + +/^[[:lower:]]/D + +/^[[:print:]]/D + +/^[[:punct:]]/D + +/^[[:space:]]/D + +/^[[:upper:]]/D + +/^[[:xdigit:]]/D + +/^[[:word:]]/D + +/^[[:^cntrl:]]/D + +/^[12[:^digit:]]/D + +/^[[:^blank:]]/D + +/[01[:alpha:]%]/D + +/[[.ch.]]/ + +/[[=ch=]]/ + +/[[:rhubarb:]]/ + +/[[:upper:]]/i + A + a + +/[[:lower:]]/i + A + a + +/((?-i)[[:lower:]])[[:lower:]]/i + ab + aB + *** Failers + Ab + AB + +/[\200-\410]/ + +/^(?(0)f|b)oo/ + +/This one's here because of the large output vector needed/ + +/(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/ + \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + +/This one's here because Perl does this differently and PCRE can't at present/ + +/(main(O)?)+/ + mainmain + mainOmain + +/These are all cases where Perl does it differently (nested captures)/ + +/^(a(b)?)+$/ + aba + +/^(aa(bb)?)+$/ + aabbaa + +/^(aa|aa(bb))+$/ + aabbaa + +/^(aa(bb)??)+$/ + aabbaa + +/^(?:aa(bb)?)+$/ + aabbaa + +/^(aa(b(b))?)+$/ + aabbaa + +/^(?:aa(b(b))?)+$/ + aabbaa + +/^(?:aa(b(?:b))?)+$/ + aabbaa + +/^(?:aa(bb(?:b))?)+$/ + aabbbaa + +/^(?:aa(b(?:bb))?)+$/ + aabbbaa + +/^(?:aa(?:b(b))?)+$/ + aabbaa + +/^(?:aa(?:b(bb))?)+$/ + aabbbaa + +/^(aa(b(bb))?)+$/ + aabbbaa + +/^(aa(bb(bb))?)+$/ + aabbbbaa + +/--------------------------------------------------------------------/ + +/#/xMD + +/a#/xMD + +/[\s]/D + +/[\S]/D + +/a(?i)b/D + ab + aB + *** Failers + AB + +/(a(?i)b)/D + ab + aB + *** Failers + AB + +/ (?i)abc/xD + +/#this is a comment + (?i)abc/xD + +/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D + +/\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D + +/\Q\E/D + \ + +/\Q\Ex/D + +/ \Q\E/D + +/a\Q\E/D + abc + bca + bac + +/a\Q\Eb/D + abc + +/\Q\Eabc/D + +/x*+\w/D + *** Failers + xxxxx + +/x?+/D + +/x++/D + +/x{1,3}+/D + +/(x)*+/D + +/^(\w++|\s++)*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d++)(\w)/ + 12345a + *** Failers + 12345+ + +/a++b/ + aaab + +/(a++b)/ + aaab + +/(a++)b/ + aaab + +/([^()]++|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(([^()]++|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(abc){1,3}+/D + +/a+?+/ + +/a{2,3}?+b/ + +/(?U)a+?+/ + +/a{2,3}?+b/U + +/x(?U)a++b/D + xaaaab + +/(?U)xa++b/D + xaaaab + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/D + +/^x(?U)a+b/D + +/^x(?U)(a+)b/D + +/[.x.]/ + +/[=x=]/ + +/[:x:]/ + +/\l/ + +/\L/ + +/\N{name}/ + +/\u/ + +/\U/ + +/[/ + +/[a-/ + +/[[:space:]/ + +/[\s]/DM + +/[[:space:]]/DM + +/[[:space:]abcde]/DM + +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x + <> + + hij> + hij> + def> + + *** Failers + iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM + +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM + +/(.*)\d+\1/I + +/(.*)\d+/I + +/(.*)\d+\1/Is + +/(.*)\d+/Is + +/(.*(xyz))\d+\2/I + +/((.*))\d+\1/I + abc123bc + +/a[b]/I + +/(?=a).*/I + +/(?=abc).xyz/iI + +/(?=abc)(?i).xyz/I + +/(?=a)(?=b)/I + +/(?=.)a/I + +/((?=abcda)a)/I + +/((?=abcda)ab)/I + +/()a/I + +/(?(1)ab|ac)/I + +/(?(1)abz|acz)/I + +/(?(1)abz)/I + +/(?(1)abz)123/I + +/(a)+/I + +/(a){2,3}/I + +/(a)*/I + +/[a]/I + +/[ab]/I + +/[ab]/IS + +/[^a]/I + +/\d456/I + +/\d456/IS + +/a^b/I + +/^a/mI + abcde + xy\nabc + *** Failers + xyabc + +/c|abc/I + +/(?i)[ab]/IS + +/[ab](?i)cd/IS + +/abc(?C)def/ + abcdef + 1234abcdef + *** Failers + abcxyz + abcxyzf + +/abc(?C)de(?C1)f/ + 123abcdef + +/(?C1)\dabc(?C2)def/ + 1234abcdef + *** Failers + abcdef + +/(?C255)ab/ + +/(?C256)ab/ + +/(?Cab)xx/ + +/(?C12vr)x/ + +/abc(?C)def/ + *** Failers + \x83\x0\x61bcdef + +/(abc)(?C)de(?C1)f/ + 123abcdef + 123abcdef\C+ + 123abcdef\C- + *** Failers + 123abcdef\C!1 + +/(?C0)(abc(?C1))*/ + abcabcabc + abcabc\C!1!3 + *** Failers + abcabcabc\C!1!3 + +/(\d{3}(?C))*/ + 123\C+ + 123456\C+ + 123456789\C+ + +/((xyz)(?C)p|(?C1)xyzabc)/ + xyzabc\C+ + +/(X)((xyz)(?C)p|(?C1)xyzabc)/ + Xxyzabc\C+ + +/(?=(abc))(?C)abcdef/ + abcdef\C+ + +/(?!(abc)(?C1)d)(?C2)abcxyz/ + abcxyz\C+ + +/(?<=(abc)(?C))xyz/ + abcxyz\C+ + +/(?C)abc/ + +/(?C)^abc/ + +/(?C)a|b/S + +/(?R)/ + +/(a|(?R))/ + +/(ab|(bc|(de|(?R))))/ + +/x(ab|(bc|(de|(?R))))/ + xab + xbc + xde + xxab + xxxab + *** Failers + xyab + +/(ab|(bc|(de|(?1))))/ + +/x(ab|(bc|(de|(?1)x)x)x)/ + +/^([^()]|\((?1)*\))*$/ + abc + a(b)c + a(b(c))d + *** Failers) + a(b(c)d + +/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x + <> + + hij> + hij> + def> + + *** Failers + b|c)d(?Pe)/D + abde + acde + +/(?:a(?Pc(?Pd)))(?Pa)/D + +/(?Pa)...(?P=a)bbb(?P>a)d/D + +/^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/i + 1221 + Satan, oscillate my metallic sonatas! + A man, a plan, a canal: Panama! + Able was I ere I saw Elba. + *** Failers + The quick brown fox + +/((?(R)a|b))\1(?1)?/ + bb + bbaa + +/(.*)a/sI + +/(.*)a\1/sI + +/(.*)a(b)\2/sI + +/((.*)a|(.*)b)z/sI + +/((.*)a|(.*)b)z\1/sI + +/((.*)a|(.*)b)z\2/sI + +/((.*)a|(.*)b)z\3/sI + +/((.*)a|^(.*)b)z\3/sI + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/sI + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/sI + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/sI + +/(a)(bc)/ND + abc + +/(?Pa)(bc)/ND + abc + +/(a)(?Pbc)/ND + +/(a+)*zz/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M + aaaaaaaaaaaaaz\M + +/(aaa(?C1)bbb|ab)/ + aaabbb + aaabbb\C*0 + aaabbb\C*1 + aaabbb\C*-1 + +/ab(?Pcd)ef(?Pgh)/ + abcdefgh + abcdefgh\C1\Gtwo + abcdefgh\Cone\Ctwo + abcdefgh\Cthree + +/(?P)(?P)/D + +/(?P)(?P)/D + +/(?Pzz)(?Paa)/ + zzaa\CZ + zzaa\CA + +/(?Peks)(?Peccs)/ + +/(?Pabc(?Pdef)(?Pxyz))/ + +"\[((?P\d+)(,(?P>elem))*)\]" + [10,20,30,5,5,4,4,2,43,23,4234] + *** Failers + [] + +"\[((?P\d+)(,(?P>elem))*)?\]" + [10,20,30,5,5,4,4,2,43,23,4234] + [] + +/(a(b(?2)c))?/D + +/(a(b(?2)c))*/D + +/(a(b(?2)c)){0,2}/D + +/[ab]{1}+/D + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/i + Baby Bjorn Active Carrier - With free SHIPPING!! + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/iS + Baby Bjorn Active Carrier - With free SHIPPING!! + +/a*.*b/SD + +/(a|b)*.?c/SD + +/abc(?C255)de(?C)f/D + +/abcde/CD + abcde + abcdfe + +/a*b/CD + ab + aaaab + aaaacb + +/a+b/CD + ab + aaaab + aaaacb + +/(abc|def)x/CD + abcx + defx + abcdefzx + +/(ab|cd){3,4}/C + ababab + abcdabcd + abcdcdcdcdcd + +/([ab]{,4}c|xy)/CD + Note: that { does NOT introduce a quantifier + +/([ab]{1,4}c|xy){4,5}?123/CD + aacaacaacaacaac123 + +/\b.*/I + ab cd\>1 + +/\b.*/Is + ab cd\>1 + +/(?!.bcd).*/I + Xbcd12345 + +/abcde/ + ab\P + abc\P + abcd\P + abcde\P + the quick brown abc\P + ** Failers\P + the quick brown abxyz fox\P + +"^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$" + 13/05/04\P + 13/5/2004\P + 02/05/09\P + 1\P + 1/2\P + 1/2/0\P + 1/2/04\P + 0\P + 02/\P + 02/0\P + 02/1\P + ** Failers\P + \P + 123\P + 33/4/04\P + 3/13/04\P + 0/1/2003\P + 0/\P + 02/0/\P + 02/13\P + +/0{0,2}ABC/I + +/\d{3,}ABC/I + +/\d*ABC/I + +/[abc]+DE/I + +/[abc]?123/ + 123\P + a\P + b\P + c\P + c12\P + c123\P + +/^(?:\d){3,5}X/ + 1\P + 123\P + 123X + 1234\P + 1234X + 12345\P + 12345X + *** Failers + 1X + 123456\P + +/abc/>testsavedregex +testsavedregex +testsavedregex +testsavedregex +(.)*~smg + \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + +/^a/IF + +/ End of testinput2 / diff --git a/trunk/srclib/pcre/testdata/testinput3 b/trunk/srclib/pcre/testdata/testinput3 new file mode 100644 index 0000000000..c2abdbfdb5 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput3 @@ -0,0 +1,65 @@ +/^[\w]+/ + *** Failers + École + +/^[\w]+/Lfr_FR + École + +/^[\w]+/ + *** Failers + École + +/^[\W]+/ + École + +/^[\W]+/Lfr_FR + *** Failers + École + +/[\b]/ + \b + *** Failers + a + +/[\b]/Lfr_FR + \b + *** Failers + a + +/^\w+/ + *** Failers + École + +/^\w+/Lfr_FR + École + +/(.+)\b(.+)/ + École + +/(.+)\b(.+)/Lfr_FR + *** Failers + École + +/École/i + École + *** Failers + école + +/École/iLfr_FR + École + école + +/\w/IS + +/\w/ISLfr_FR + +/^[\xc8-\xc9]/iLfr_FR + École + école + +/^[\xc8-\xc9]/Lfr_FR + École + *** Failers + école + +/ End of testinput3 / diff --git a/trunk/srclib/pcre/testdata/testinput4 b/trunk/srclib/pcre/testdata/testinput4 new file mode 100644 index 0000000000..c16e9d9983 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput4 @@ -0,0 +1,513 @@ +/-- Do not use the \x{} construct except with patterns that have the --/ +/-- /8 option set, because PCRE doesn't recognize them as UTF-8 unless --/ +/-- that option is set. However, the latest Perls recognize them always. --/ + +/a.b/8 + acb + a\x7fb + a\x{100}b + *** Failers + a\nb + +/a(.{3})b/8 + a\x{4000}xyb + a\x{4000}\x7fyb + a\x{4000}\x{100}yb + *** Failers + a\x{4000}b + ac\ncb + +/a(.*?)(.)/ + a\xc0\x88b + +/a(.*?)(.)/8 + a\x{100}b + +/a(.*)(.)/ + a\xc0\x88b + +/a(.*)(.)/8 + a\x{100}b + +/a(.)(.)/ + a\xc0\x92bcd + +/a(.)(.)/8 + a\x{240}bcd + +/a(.?)(.)/ + a\xc0\x92bcd + +/a(.?)(.)/8 + a\x{240}bcd + +/a(.??)(.)/ + a\xc0\x92bcd + +/a(.??)(.)/8 + a\x{240}bcd + +/a(.{3})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + *** Failers + a\x{1234}b + ac\ncb + +/a(.{3,})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,5})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/a(.{3,5}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/^[a\x{c0}]/8 + *** Failers + \x{100} + +/(?<=aXb)cd/8 + aXbcd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + *** Failers + \x{100}\x{100}b + +/\x{ab}/8 + \x{ab} + \xc2\xab + *** Failers + \x00{ab} + +/(?<=(.))X/8 + WXYZ + \x{256}XYZ + *** Failers + XYZ + +/X(\C{3})/8 + X\x{1234} + +/X(\C{4})/8 + X\x{1234}YZ + +/X\C*/8 + XYZabcdce + +/X\C*?/8 + XYZabcde + +/X\C{3,5}/8 + Xabcdefg + X\x{1234} + X\x{1234}YZ + X\x{1234}\x{512} + X\x{1234}\x{512}YZ + +/X\C{3,5}?/8 + Xabcdefg + X\x{1234} + X\x{1234}YZ + X\x{1234}\x{512} + +/[^a]+/8g + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + +/^[^a]{2,}/8 + \x{100}bcAa + +/^[^a]{2,}?/8 + \x{100}bca + +/[^a]+/8ig + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + +/^[^a]{2,}/8i + \x{100}bcAa + +/^[^a]{2,}?/8i + \x{100}bca + +/\x{100}{0,0}/8 + abcd + +/\x{100}?/8 + abcd + \x{100}\x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + \x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + +/\x{100}{3,5}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/\x{100}{3,}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + +/(?<=a\x{100}{2}b)X/8+ + Xyyya\x{100}\x{100}bXzzz + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/\D/8 + 1X2 + 1\x{100}2 + +/>\S/8 + > >X Y + > >\x{100} Y + +/\d/8 + \x{100}3 + +/\s/8 + \x{100} X + +/\D+/8 + 12abcd34 + *** Failers + 1234 + +/\D{2,3}/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\D{2,3}?/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\d+/8 + 12abcd34 + *** Failers + +/\d{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\d{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\S+/8 + 12abcd34 + *** Failers + \ \ + +/\S{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/\S{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/>\s+ <34 + *** Failers + +/>\s{2,3} \s{2,3}? \xff< + +/[\xff]/8 + >\x{ff}< + +/[^\xFF]/ + XYZ + +/[^\xff]/8 + XYZ + \x{123} + +/^[ac]*b/8 + xb + +/^[ac\x{100}]*b/8 + xb + +/^[^x]*b/8i + xb + +/^[^x]*b/8 + xb + +/^\d*b/8 + xb + +/(|a)/g8 + catac + a\x{256}a + +/^\x{85}$/8i + \x{85} + +/ End of testinput4 / diff --git a/trunk/srclib/pcre/testdata/testinput5 b/trunk/srclib/pcre/testdata/testinput5 new file mode 100644 index 0000000000..fe6ee3e656 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput5 @@ -0,0 +1,263 @@ +/\x{100}/8DM + +/\x{1000}/8DM + +/\x{10000}/8DM + +/\x{100000}/8DM + +/\x{1000000}/8DM + +/\x{4000000}/8DM + +/\x{7fffFFFF}/8DM + +/[\x{ff}]/8DM + +/[\x{100}]/8DM + +/\x{ffffffff}/8 + +/\x{100000000}/8 + +/^\x{100}a\x{1234}/8 + \x{100}a\x{1234}bcd + +/\x80/8D + +/\xff/8D + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8 + \x{0041}\x{2262}\x{0391}\x{002e} + +/\x{D55c}\x{ad6d}\x{C5B4}/D8 + \x{D55c}\x{ad6d}\x{C5B4} + +/\x{65e5}\x{672c}\x{8a9e}/D8 + \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/D8 + +/\x{084}/D8 + +/\x{104}/D8 + +/\x{861}/D8 + +/\x{212ab}/D8 + +/.{3,5}X/D8 + \x{212ab}\x{212ab}\x{212ab}\x{861}X + + +/.{3,5}?/D8 + \x{212ab}\x{212ab}\x{212ab}\x{861} + +/-- These tests are here rather than in testinput4 because Perl 5.6 has --/ +/-- some problems with UTF-8 support, in the area of \x{..} where the --/ +/-- value is < 255. It grumbles about invalid UTF-8 strings. --/ + +/^[a\x{c0}]b/8 + \x{c0}b + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/^([a\x{c0}]*)aa/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/^([a\x{c0}]*)a\x{c0}/8 + a\x{c0}aaaa/ + a\x{c0}a\x{c0}aaa/ + +/-- --/ + +/(?<=\C)X/8 + Should produce an error diagnostic + +/-- This one is here not because it's different to Perl, but because the --/ +/-- way the captured single-byte is displayed. (In Perl it becomes a --/ +/-- character, and you can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + X\nabc + +/^[ab]/8D + bar + *** Failers + c + \x{ff} + \x{100} + +/^[^ab]/8D + c + \x{ff} + \x{100} + *** Failers + aaa + +/[^ab\xC0-\xF0]/8SD + \x{f1} + \x{bf} + \x{100} + \x{1000} + *** Failers + \x{c0} + \x{f0} + +/Ä€{3,4}/8SD + \x{100}\x{100}\x{100}\x{100\x{100} + +/(\x{100}+|x)/8SD + +/(\x{100}*a|x)/8SD + +/(\x{100}{0,2}a|x)/8SD + +/(\x{100}{1,2}a|x)/8SD + +/\x{100}*(\d+|"(?1)")/8 + 1234 + "1234" + \x{100}1234 + "\x{100}1234" + \x{100}\x{100}12ab + \x{100}\x{100}"12" + *** Failers + \x{100}\x{100}abcd + +/\x{100}/8D + +/\x{100}*/8D + +/a\x{100}*/8D + +/ab\x{100}*/8D + +/a\x{100}\x{101}*/8D + +/a\x{100}\x{101}+/8D + +/\x{100}*A/8D + A + +/\x{100}*\d(?R)/8D + +/[^\x{c4}]/D + +/[^\x{c4}]/8D + +/[\x{100}]/8DM + \x{100} + Z\x{100} + \x{100}Z + *** Failers + +/[Z\x{100}]/8DM + Z\x{100} + \x{100} + \x{100}Z + *** Failers + +/[\x{200}-\x{100}]/8 + +/[Ä€-Ä„]/8 + \x{100} + \x{104} + *** Failers + \x{105} + \x{ff} + +/[z-\x{100}]/8D + +/[z\Qa-d]Ä€\E]/8D + \x{100} + Ä€ + +/[\xFF]/D + >\xff< + +/[\xff]/D8 + >\x{ff}< + +/[^\xFF]/D + +/[^\xff]/8D + +/[Ä-Ãœ]/8 + Ö # Matches without Study + \x{d6} + +/[Ä-Ãœ]/8S + Ö <-- Same with Study + \x{d6} + +/[\x{c4}-\x{dc}]/8 + Ö # Matches without Study + \x{d6} + +/[\x{c4}-\x{dc}]/8S + Ö <-- Same with Study + \x{d6} + +/[Ã]/8 + +/Ã/8 + +/ÃÃÃxxx/8 + +/ÃÃÃxxx/8?D + +/abc/8 + Ã] + à + ÃÃà + ÃÃÃ\? + +/anything/8 + \xc0\x80 + \xc1\x8f + \xe0\x9f\x80 + \xf0\x8f\x80\x80 + \xf8\x87\x80\x80\x80 + \xfc\x83\x80\x80\x80\x80 + \xfe\x80\x80\x80\x80\x80 + \xff\x80\x80\x80\x80\x80 + \xc3\x8f + \xe0\xaf\x80 + \xe1\x80\x80 + \xf0\x9f\x80\x80 + \xf1\x8f\x80\x80 + \xf8\x88\x80\x80\x80 + \xf9\x87\x80\x80\x80 + \xfc\x84\x80\x80\x80\x80 + \xfd\x83\x80\x80\x80\x80 + +/\x{100}abc(xyz(?1))/8D + +/[^\x{100}]abc(xyz(?1))/8D + +/[ab\x{100}]abc(xyz(?1))/8D + +/(\x{100}(b(?2)c))?/D8 + +/(\x{100}(b(?2)c)){0,2}/D8 + +/(\x{100}(b(?1)c))?/D8 + +/(\x{100}(b(?1)c)){0,2}/D8 + +/\W/8 + A.B + A\x{100}B + +/\w/8 + \x{100}X + +/ End of testinput5 / diff --git a/trunk/srclib/pcre/testdata/testinput6 b/trunk/srclib/pcre/testdata/testinput6 new file mode 100644 index 0000000000..01a39477ac --- /dev/null +++ b/trunk/srclib/pcre/testdata/testinput6 @@ -0,0 +1,517 @@ +/^\pC\pL\pM\pN\pP\pS\pZ>>aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz + *** Failers +No match + abxyzpqrrabbxyyyypqAzz +No match + abxyzpqrrrrabbxyyyypqAzz +No match + abxyzpqrrrabxyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyypqAzz +No match + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz +No match + +/^(abc){1,2}zz/ + abczz + 0: abczz + 1: abc + abcabczz + 0: abcabczz + 1: abc + *** Failers +No match + zz +No match + abcabcabczz +No match + >>abczz +No match + +/^(b+?|a){1,2}?c/ + bc + 0: bc + 1: b + bbc + 0: bbc + 1: b + bbbc + 0: bbbc + 1: bb + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + aac + 0: aac + 1: a + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + 1: bbbbbbbbbbb + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + 1: a + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}c/ + bc + 0: bc + 1: b + bbc + 0: bbc + 1: bb + bbbc + 0: bbbc + 1: bbb + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + aac + 0: aac + 1: a + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + 1: bbbbbbbbbbb + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + 1: a + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}?bc/ + bbc + 0: bbc + 1: b + +/^(b*|ba){1,2}?bc/ + babc + 0: babc + 1: ba + bbabc + 0: bbabc + 1: ba + bababc + 0: bababc + 1: ba + *** Failers +No match + bababbc +No match + babababc +No match + +/^(ba|b*){1,2}?bc/ + babc + 0: babc + 1: ba + bbabc + 0: bbabc + 1: ba + bababc + 0: bababc + 1: ba + *** Failers +No match + bababbc +No match + babababc +No match + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + 0: \x01\x01\x1b;z + +/^[ab\]cde]/ + athing + 0: a + bthing + 0: b + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + fthing +No match + [thing +No match + \\thing +No match + +/^[]cde]/ + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + athing +No match + fthing +No match + +/^[^ab\]cde]/ + fthing + 0: f + [thing + 0: [ + \\thing + 0: \ + *** Failers + 0: * + athing +No match + bthing +No match + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^[^]cde]/ + athing + 0: a + fthing + 0: f + *** Failers + 0: * + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^\/ + + 0: \x81 + +/^ÿ/ + ÿ + 0: \xff + +/^[0-9]+$/ + 0 + 0: 0 + 1 + 0: 1 + 2 + 0: 2 + 3 + 0: 3 + 4 + 0: 4 + 5 + 0: 5 + 6 + 0: 6 + 7 + 0: 7 + 8 + 0: 8 + 9 + 0: 9 + 10 + 0: 10 + 100 + 0: 100 + *** Failers +No match + abc +No match + +/^.*nter/ + enter + 0: enter + inter + 0: inter + uponter + 0: uponter + +/^xxx[0-9]+$/ + xxx0 + 0: xxx0 + xxx1234 + 0: xxx1234 + *** Failers +No match + xxx +No match + +/^.+[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + 0: abc!pqr=apquxz.ixr.zzz.ac.uk + 1: abc + 2: pqr + *** Failers +No match + !pqr=apquxz.ixr.zzz.ac.uk +No match + abc!=apquxz.ixr.zzz.ac.uk +No match + abc!pqr=apquxz:ixr.zzz.ac.uk +No match + abc!pqr=apquxz.ixr.zzz.ac.ukk +No match + +/:/ + Well, we need a colon: somewhere + 0: : + *** Fail if we don't +No match + +/([\da-f:]+)$/i + 0abc + 0: 0abc + 1: 0abc + abc + 0: abc + 1: abc + fed + 0: fed + 1: fed + E + 0: E + 1: E + :: + 0: :: + 1: :: + 5f03:12C0::932e + 0: 5f03:12C0::932e + 1: 5f03:12C0::932e + fed def + 0: def + 1: def + Any old stuff + 0: ff + 1: ff + *** Failers +No match + 0zzz +No match + gzzz +No match + fed\x20 +No match + Any old rubbish +No match + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + 0: .1.2.3 + 1: 1 + 2: 2 + 3: 3 + A.12.123.0 + 0: A.12.123.0 + 1: 12 + 2: 123 + 3: 0 + *** Failers +No match + .1.2.3333 +No match + 1.2.3 +No match + 1234.2.3 +No match + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 0: 1 IN SOA non-sp1 non-sp2( + 1: 1 + 2: non-sp1 + 3: non-sp2 + 1 IN SOA non-sp1 non-sp2 ( + 0: 1 IN SOA non-sp1 non-sp2 ( + 1: 1 + 2: non-sp1 + 3: non-sp2 + *** Failers +No match + 1IN SOA non-sp1 non-sp2( +No match + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + 0: a. + Z. + 0: Z. + 2. + 0: 2. + ab-c.pq-r. + 0: ab-c.pq-r. + 1: .pq-r + sxk.zzz.ac.uk. + 0: sxk.zzz.ac.uk. + 1: .uk + x-.y-. + 0: x-.y-. + 1: .y- + *** Failers +No match + -abc.peq. +No match + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + 0: *.a + *.b0-a + 0: *.b0-a + 1: 0-a + *.c3-b.c + 0: *.c3-b.c + 1: 3-b + 2: .c + *.c-a.b-c + 0: *.c-a.b-c + 1: -a + 2: .b-c + 3: -c + *** Failers +No match + *.0 +No match + *.a- +No match + *.a-b.c- +No match + *.c-a.0-c +No match + +/^(?=ab(de))(abd)(e)/ + abde + 0: abde + 1: de + 2: abd + 3: e + +/^(?!(ab)de|x)(abd)(f)/ + abdf + 0: abdf + 1: + 2: abd + 3: f + +/^(?=(ab(cd)))(ab)/ + abcd + 0: ab + 1: abcd + 2: cd + 3: ab + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + 0: a.b.c.d + 1: .d + A.B.C.D + 0: A.B.C.D + 1: .D + a.b.c.1.2.3.C + 0: a.b.c.1.2.3.C + 1: .C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + 0: "1234" + \"abcd\" ; + 0: "abcd" ; + 1: ; + \"\" ; rhubarb + 0: "" ; rhubarb + 1: ; rhubarb + *** Failers +No match + \"1234\" : things +No match + +/^$/ + \ + 0: + *** Failers +No match + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/^ a\ b[c ]d $/x + a bcd + 0: a bcd + a b d + 0: a b d + *** Failers +No match + abcd +No match + ab d +No match + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + 1: abc + 2: bc + 3: c + 4: def + 5: ef + 6: f + 7: hij + 8: ij + 9: j +10: klm +11: lm +12: m + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + 1: bc + 2: c + 3: ef + 4: f + 5: ij + 6: j + 7: lm + 8: m + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + 0: a+ Z0+\x08\x0a\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + 0: .^$(*+)|{?,?} + +/^a*\w/ + z + 0: z + az + 0: az + aaaz + 0: aaaz + a + 0: a + aa + 0: aa + aaaa + 0: aaaa + a+ + 0: a + aa+ + 0: aa + +/^a*?\w/ + z + 0: z + az + 0: a + aaaz + 0: a + a + 0: a + aa + 0: a + aaaa + 0: a + a+ + 0: a + aa+ + 0: a + +/^a+\w/ + az + 0: az + aaaz + 0: aaaz + aa + 0: aa + aaaa + 0: aaaa + aa+ + 0: aa + +/^a+?\w/ + az + 0: az + aaaz + 0: aa + aa + 0: aa + aaaa + 0: aa + aa+ + 0: aa + +/^\d{8}\w{2,}/ + 1234567890 + 0: 1234567890 + 12345678ab + 0: 12345678ab + 12345678__ + 0: 12345678__ + *** Failers +No match + 1234567 +No match + +/^[aeiou\d]{4,5}$/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + aaaaa + 0: aaaaa + *** Failers +No match + 123456 +No match + +/^[aeiou\d]{4,5}?/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 1234 + aaaaa + 0: aaaa + 123456 + 0: 1234 + +/\A(abc|def)=(\1){2,3}\Z/ + abc=abcabc + 0: abc=abcabc + 1: abc + 2: abc + def=defdefdef + 0: def=defdefdef + 1: def + 2: def + *** Failers +No match + abc=defdef +No match + +/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ + abcdefghijkcda2 + 0: abcdefghijkcda2 + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: cd + abcdefghijkkkkcda2 + 0: abcdefghijkkkkcda2 + 1: a + 2: b + 3: c + 4: d + 5: e + 6: f + 7: g + 8: h + 9: i +10: j +11: k +12: cd + +/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ + cataract cataract23 + 0: cataract cataract23 + 1: cataract + 2: aract + 3: ract + 4: + 5: 3 + catatonic catatonic23 + 0: catatonic catatonic23 + 1: catatonic + 2: atonic + 3: tonic + 4: + 5: 3 + caterpillar caterpillar23 + 0: caterpillar caterpillar23 + 1: caterpillar + 2: erpillar + 3: + 4: + 5: 3 + + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + 1: abcd + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + 1: Sep + From abcd Mon Sep 1 12:33:02 1997 + 0: From abcd Mon Sep 1 12:33 + 1: Sep + *** Failers +No match + From abcd Sep 01 12:33:02 1997 +No match + +/^12.34/s + 12\n34 + 0: 12\x0a34 + 12\r34 + 0: 12\x0d34 + +/\w+(?=\t)/ + the quick brown\t fox + 0: brown + +/foo(?!bar)(.*)/ + foobar is foolish see? + 0: foolish see? + 1: lish see? + +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + 0: rowbar etc + 1: etc + barrel + 0: barrel + 1: rel + 2barrel + 0: 2barrel + 1: rel + A barrel + 0: A barrel + 1: rel + +/^(\D*)(?=\d)(?!123)/ + abc456 + 0: abc + 1: abc + *** Failers +No match + abc123 +No match + +/^1234(?# test newlines + inside)/ + 1234 + 0: 1234 + +/^1234 #comment in extended re + /x + 1234 + 0: 1234 + +/#rhubarb + abcd/x + abcd + 0: abcd + +/^abcd#rhubarb/x + abcd + 0: abcd + +/^(a)\1{2,3}(.)/ + aaab + 0: aaab + 1: a + 2: b + aaaab + 0: aaaab + 1: a + 2: b + aaaaab + 0: aaaaa + 1: a + 2: a + aaaaaab + 0: aaaaa + 1: a + 2: a + +/(?!^)abc/ + the abc + 0: abc + *** Failers +No match + abc +No match + +/(?=^)abc/ + abc + 0: abc + *** Failers +No match + the abc +No match + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + 0: aabb + 1: b + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: abbbbb + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + 0: aa + 1: a + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + 0: aabb + 1: b + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + user\@dom.ain + 0: user@dom.ain + \"A. Other\" (a comment) + 0: "A. Other" (a comment) + A. Other (a comment) + 0: Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + user\@dom.ain + 0: user@dom.ain + \"A. Other\" (a comment) + 0: "A. Other" + A. Other (a comment) + 0: Other + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff + +/P[^*]TAIRE[^*]{1,6}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/P[^*]TAIRE[^*]{1,}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/(\.\d\d[1-9]?)\d+/ + 1.230003938 + 0: .230003938 + 1: .23 + 1.875000282 + 0: .875000282 + 1: .875 + 1.235 + 0: .235 + 1: .23 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 0: .23 + 1: .23 + 2: + 1.875000282 + 0: .875 + 1: .875 + 2: 5 + *** Failers +No match + 1.235 +No match + +/a(?)b/ + ab + 0: ab + +/\b(foo)\s+(\w+)/i + Food is on the foo table + 0: foo table + 1: foo + 2: table + +/foo(.*)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: d is under the bar in the + +/foo(.*?)bar/ + The food is under the bar in the barn. + 0: food is under the bar + 1: d is under the + +/(.*)(\d*)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 53147 + 2: + +/(.*)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 + 0: + 1: + 2: + +/(.*?)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 + 1: I have + 2: 2 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: 7 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: + 2: 53147 + +/^\D*(?!123)/ + ABC123 + 0: AB + +/^(\D*)(?=\d)(?!123)/ + ABC445 + 0: ABC + 1: ABC + *** Failers +No match + ABC123 +No match + +/^[W-]46]/ + W46]789 + 0: W46] + -46]789 + 0: -46] + *** Failers +No match + Wall +No match + Zebra +No match + 42 +No match + [abcd] +No match + ]abcd[ +No match + +/^[W-\]46]/ + W46]789 + 0: W + Wall + 0: W + Zebra + 0: Z + Xylophone + 0: X + 42 + 0: 4 + [abcd] + 0: [ + ]abcd[ + 0: ] + \\backslash + 0: \ + *** Failers +No match + -46]789 +No match + well +No match + +/\d\d\/\d\d\/\d\d\d\d/ + 01/01/2000 + 0: 01/01/2000 + +/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope +No match + +/^(a){0,0}/ + bcd + 0: + abc + 0: + aab + 0: + +/^(a){0,1}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: a + 1: a + +/^(a){0,2}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){0,3}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){0,}/ + bcd + 0: + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: a + +/^(a){1,1}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: a + 1: a + +/^(a){1,2}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + +/^(a){1,3}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + +/^(a){1,}/ + bcd +No match + abc + 0: a + 1: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: a + aaaaaaaa + 0: aaaaaaaa + 1: a + +/.*\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.{0,}\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/m + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*\.gif/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*$/ + borfle\nbib.gif\nno + 0: no + +/.*$/m + borfle\nbib.gif\nno + 0: borfle + +/.*$/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + +/.*$/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + +/.*$/ + borfle\nbib.gif\nno\n + 0: no + +/.*$/m + borfle\nbib.gif\nno\n + 0: borfle + +/.*$/s + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + +/.*$/ms + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + +/(.*X|^B)/ + abcde\n1234Xyz + 0: 1234X + 1: 1234X + BarFoo + 0: B + 1: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/m + abcde\n1234Xyz + 0: 1234X + 1: 1234X + BarFoo + 0: B + 1: B + abcde\nBar + 0: B + 1: B + +/(.*X|^B)/s + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/ms + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: B + abcde\nBar + 0: B + 1: B + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + 1: abcde\x0a1234X + BarFoo + 0: B + 1: B + *** Failers +No match + abcde\nBar +No match + +/(?s:.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/^.*B/ + **** Failers +No match + abc\nB +No match + +/(?s)^.*B/ + abc\nB + 0: abc\x0aB + +/(?m)^.*B/ + abc\nB + 0: B + +/(?ms)^.*B/ + abc\nB + 0: abc\x0aB + +/(?ms)^B/ + abc\nB + 0: B + +/(?s)B$/ + B\n + 0: B + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + 0: 123456654321 + +/^\d\d\d\d\d\d\d\d\d\d\d\d/ + 123456654321 + 0: 123456654321 + +/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ + 123456654321 + 0: 123456654321 + +/^[abc]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + 0: abcabcabcabc + 1: c + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + 0: n + *** Failers +No match + z +No match + +/abcde{0,0}/ + abcd + 0: abcd + *** Failers +No match + abce +No match + +/ab[cd]{0,0}e/ + abe + 0: abe + *** Failers +No match + abcde +No match + +/ab(c){0,0}d/ + abd + 0: abd + *** Failers +No match + abcd +No match + +/a(b*)/ + a + 0: a + 1: + ab + 0: ab + 1: b + abbbb + 0: abbbb + 1: bbbb + *** Failers + 0: a + 1: + bbbbb +No match + +/ab\d{0}e/ + abe + 0: abe + *** Failers +No match + ab1e +No match + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + 0: "quick" + 1: quick + \"the \\\"quick\\\" brown fox\" + 0: "the \"quick\" brown fox" + 1: brown fox + +/.*?/g+ + abc + 0: + 0+ abc + 0: a + 0+ bc + 0: + 0+ bc + 0: b + 0+ c + 0: + 0+ c + 0: c + 0+ + 0: + 0+ + +/\b/g+ + abc + 0: + 0+ abc + 0: + 0+ + +/\b/+g + abc + 0: + 0+ abc + 0: + 0+ + +//g + abc + 0: + 0: + 0: + 0: + +/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.
    Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + 0: 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + 1: BGCOLOR='#DBE9E9' + 2: align=left valign=top + 3: 43. + 4: Word Processor
    (N-1286) + 5: + 6: + 7: + 8: align=left valign=top + 9: Lega lstaff.com +10: align=left valign=top +11: CA - Statewide + +/a[^a]b/ + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/ + acb + 0: acb + *** Failers +No match + a\nb +No match + +/a[^a]b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/^(b+?|a){1,2}?c/ + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + bbbac + 0: bbbac + 1: a + bbbbac + 0: bbbbac + 1: a + bbbbbac + 0: bbbbbac + 1: a + +/^(b+|a){1,2}?c/ + bac + 0: bac + 1: a + bbac + 0: bbac + 1: a + bbbac + 0: bbbac + 1: a + bbbbac + 0: bbbbac + 1: a + bbbbbac + 0: bbbbbac + 1: a + +/(?!\A)x/m + x\nb\n +No match + a\bx\n + 0: x + +/\x0{ab}/ + \0{ab} + 0: \x00{ab} + +/(A|B)*?CD/ + CD + 0: CD + +/(A|B)*CD/ + CD + 0: CD + +/(AB)*?\1/ + ABABAB + 0: ABAB + 1: AB + +/(AB)*\1/ + ABABAB + 0: ABABAB + 1: AB + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ +No match + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\d\d[1-9]?))\d+/ + 1.230003938 + 0: .230003938 + 1: .23 + 1.875000282 + 0: .875000282 + 1: .875 + *** Failers +No match + 1.235 +No match + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + 1: party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d+)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: a + 12345+ + 0: 12345 + 1: 1234 + 2: 5 + +/((?>\d+))(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: a + *** Failers +No match + 12345+ +No match + +/(?>a+)b/ + aaab + 0: aaab + +/((?>a+)b)/ + aaab + 0: aaab + 1: aaab + +/(?>(a+))b/ + aaab + 0: aaab + 1: aaa + +/(?>b)+/ + aaabbbccc + 0: bbb + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbc + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + 0: (abc) + 1: abc + (abc(def)xyz) + 0: (abc(def)xyz) + 1: xyz + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/a(?-i)b/i + ab + 0: ab + Ab + 0: Ab + *** Failers +No match + aB +No match + AB +No match + +/(a (?x)b c)d e/ + a bcd e + 0: a bcd e + 1: a bc + *** Failers +No match + a b cd e +No match + abcd e +No match + a bcde +No match + +/(a b(?x)c d (?-x)e f)/ + a bcde f + 0: a bcde f + 1: a bcde f + *** Failers +No match + abcdef +No match + +/(a(?i)b)c/ + abc + 0: abc + 1: ab + aBc + 0: aBc + 1: aB + *** Failers +No match + abC +No match + aBC +No match + Abc +No match + ABc +No match + ABC +No match + AbC +No match + +/a(?i:b)c/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + ABC +No match + abC +No match + aBC +No match + +/a(?i:b)*c/ + aBc + 0: aBc + aBBc + 0: aBBc + *** Failers +No match + aBC +No match + aBBC +No match + +/a(?=b(?i)c)\w\wd/ + abcd + 0: abcd + abCd + 0: abCd + *** Failers +No match + aBCd +No match + abcD +No match + +/(?s-i:more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?:(?s-i)more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?>a(?i)b+)+c/ + abc + 0: abc + aBbc + 0: aBbc + aBBc + 0: aBBc + *** Failers +No match + Abc +No match + abAb +No match + abbC +No match + +/(?=a(?i)b)\w\wc/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + Ab +No match + abC +No match + aBC +No match + +/(?<=a(?i)b)(\w\w)c/ + abxxc + 0: xxc + 1: xx + aBxxc + 0: xxc + 1: xx + *** Failers +No match + Abxxc +No match + ABxxc +No match + abxxC +No match + +/(?:(a)|b)(?(1)A|B)/ + aA + 0: aA + 1: a + bB + 0: bB + *** Failers +No match + aB +No match + bA +No match + +/^(a)?(?(1)a|b)+$/ + aa + 0: aa + 1: a + b + 0: b + bb + 0: bb + *** Failers +No match + ab +No match + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/(?(?<=foo)bar|cat)/ + foobar + 0: bar + cat + 0: cat + fcat + 0: cat + focat + 0: cat + *** Failers +No match + foocat +No match + +/(?(?a*)*/ + a + 0: a + aa + 0: aa + aaaa + 0: aaaa + +/(abc|)+/ + abc + 0: abc + 1: + abcabc + 0: abcabc + 1: + abcabcabc + 0: abcabcabc + 1: + xyz + 0: + 1: + +/([a]*)*/ + a + 0: a + 1: + aaaaa + 0: aaaaa + 1: + +/([ab]*)*/ + a + 0: a + 1: + b + 0: b + 1: + ababab + 0: ababab + 1: + aaaabcde + 0: aaaab + 1: + bbbb + 0: bbbb + 1: + +/([^a]*)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: + aaa + 0: + 1: + +/([^ab]*)*/ + cccc + 0: cccc + 1: + abab + 0: + 1: + +/([a]*?)*/ + a + 0: + 1: + aaaa + 0: + 1: + +/([ab]*?)*/ + a + 0: + 1: + b + 0: + 1: + abab + 0: + 1: + baba + 0: + 1: + +/([^a]*?)*/ + b + 0: + 1: + bbbb + 0: + 1: + aaa + 0: + 1: + +/([^ab]*?)*/ + c + 0: + 1: + cccc + 0: + 1: + baba + 0: + 1: + +/(?>a*)*/ + a + 0: a + aaabcde + 0: aaa + +/((?>a*))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/((?>a*?))*/ + aaaaa + 0: + 1: + aabbaa + 0: + 1: + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 0: 12-sep-98 + 12-09-98 + 0: 12-09-98 + *** Failers +No match + sep-12-98 +No match + +/(?<=(foo))bar\1/ + foobarfoo + 0: barfoo + 1: foo + foobarfootling + 0: barfoo + 1: foo + *** Failers +No match + foobar +No match + barfoo +No match + +/(?i:saturday|sunday)/ + saturday + 0: saturday + sunday + 0: sunday + Saturday + 0: Saturday + Sunday + 0: Sunday + SATURDAY + 0: SATURDAY + SUNDAY + 0: SUNDAY + SunDay + 0: SunDay + +/(a(?i)bc|BB)x/ + abcx + 0: abcx + 1: abc + aBCx + 0: aBCx + 1: aBC + bbx + 0: bbx + 1: bb + BBx + 0: BBx + 1: BB + *** Failers +No match + abcX +No match + aBCX +No match + bbX +No match + BBX +No match + +/^([ab](?i)[cd]|[ef])/ + ac + 0: ac + 1: ac + aC + 0: aC + 1: aC + bD + 0: bD + 1: bD + elephant + 0: e + 1: e + Europe + 0: E + 1: E + frog + 0: f + 1: f + France + 0: F + 1: F + *** Failers +No match + Africa +No match + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + 0: ab + 1: ab + aBd + 0: aBd + 1: aBd + xy + 0: xy + 1: xy + xY + 0: xY + 1: xY + zebra + 0: z + 1: z + Zambesi + 0: Z + 1: Z + *** Failers +No match + aCD +No match + XY +No match + +/(?<=foo\n)^bar/m + foo\nbar + 0: bar + *** Failers +No match + bar +No match + baz\nbar +No match + +/(?<=(?]&/ + <&OUT + 0: <& + +/^(a\1?){4}$/ + aaaaaaaaaa + 0: aaaaaaaaaa + 1: aaaa + *** Failers +No match + AB +No match + aaaaaaaaa +No match + aaaaaaaaaaa +No match + +/^(a(?(1)\1)){4}$/ + aaaaaaaaaa + 0: aaaaaaaaaa + 1: aaaa + *** Failers +No match + aaaaaaaaa +No match + aaaaaaaaaaa +No match + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + 0: foobar + 1: f + 2: o + 3: o + 4: b + 5: a + 6: r + +/(?<=a)b/ + ab + 0: b + *** Failers +No match + cb +No match + b +No match + +/(? + 2: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: abcd + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/(a*)b+/ + caab + 0: aab + 1: aa + +/([\w:]+::)?(\w+)$/ + abcd + 0: abcd + 1: + 2: abcd + xy:z:::abcd + 0: xy:z:::abcd + 1: xy:z::: + 2: abcd + *** Failers + 0: Failers + 1: + 2: Failers + abcd: +No match + abcd: +No match + +/^[^bcd]*(c+)/ + aexycd + 0: aexyc + 1: c + +/(>a+)ab/ + +/(?>a+)b/ + aaab + 0: aaab + +/([[:]+)/ + a:[b]: + 0: :[ + 1: :[ + +/([[=]+)/ + a=[b]= + 0: =[ + 1: =[ + +/([[.]+)/ + a.[b]. + 0: .[ + 1: .[ + +/((?>a+)b)/ + aaab + 0: aaab + 1: aaab + +/(?>(a+))b/ + aaab + 0: aaab + 1: aaa + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/a\Z/ + *** Failers +No match + aaab +No match + a\nb\n +No match + +/b\Z/ + a\nb\n + 0: b + +/b\z/ + +/b\Z/ + a\nb + 0: b + +/b\z/ + a\nb + 0: b + *** Failers +No match + +/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ + a + 0: a + 1: + abc + 0: abc + 1: + a-b + 0: a-b + 1: + 0-9 + 0: 0-9 + 1: + a.b + 0: a.b + 1: + 5.6.7 + 0: 5.6.7 + 1: + the.quick.brown.fox + 0: the.quick.brown.fox + 1: + a100.b200.300c + 0: a100.b200.300c + 1: + 12-ab.1245 + 0: 12-ab.1245 + 1: + *** Failers +No match + \ +No match + .a +No match + -a +No match + a- +No match + a. +No match + a_b +No match + a.- +No match + a.. +No match + ab..bc +No match + the.quick.brown.fox- +No match + the.quick.brown.fox. +No match + the.quick.brown.fox_ +No match + the.quick.brown.fox+ +No match + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + 0: alphabetabcd + 1: abcd + endingwxyz + 0: endingwxyz + 1: wxyz + *** Failers +No match + a rather long string that doesn't end with one of them +No match + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope +No match + +/(?<=\d{3}(?!999))foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=(?!...999)\d{3})foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 0: foo + 123456foo + 0: foo + *** Failers +No match + 123999foo +No match + +/(?<=\d{3}...)(? + 2: + 3: abcd +
    + 2: + 3: abcd + \s*)=(?>\s*) # find + 2: + 3: abcd + Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: A + +/((?>)+|A)*/ + ZABCDEFG + 0: + 1: + +/a*/g + abbab + 0: a + 0: + 0: + 0: a + 0: + 0: + +/^[a-\d]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/^[\d-a]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d\x0b + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09 + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + +/a b/x + ab +No match + +/(?!\A)x/m + a\nxb\n + 0: x + +/(?!^)x/m + a\nxb\n +No match + +/abc\Qabc\Eabc/ + abcabcabc + 0: abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + 0: abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + 0: abc abcabc + *** Failers +No match + abcabcabc +No match + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + 0: abc\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + 0: abc$xyz + +/\Gabc/ + abc + 0: abc + *** Failers +No match + xyzabc +No match + +/\Gabc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + +/abc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + 0: abc3 + +/a(?x: b c )d/ + XabcdY + 0: abcd + *** Failers +No match + Xa b c d Y +No match + +/((?x)x y z | a b c)/ + XabcY + 0: abc + 1: abc + AxyzB + 0: xyz + 1: xyz + +/(?i)AB(?-i)C/ + XabCY + 0: abC + *** Failers +No match + XabcY +No match + +/((?i)AB(?-i)C|D)E/ + abCE + 0: abCE + 1: abC + DE + 0: DE + 1: D + *** Failers +No match + abcE +No match + abCe +No match + dE +No match + De +No match + +/(.*)\d+\1/ + abc123abc + 0: abc123abc + 1: abc + abc123bc + 0: bc123bc + 1: bc + +/(.*)\d+\1/s + abc123abc + 0: abc123abc + 1: abc + abc123bc + 0: bc123bc + 1: bc + +/((.*))\d+\1/ + abc123abc + 0: abc123abc + 1: abc + 2: abc + abc123bc + 0: bc123bc + 1: bc + 2: bc + +/-- This tests for an IPv6 address in the form where it can have up to --/ +/-- eight components, one and only one of which is empty. This must be --/ +No match +/-- an internal component. --/ +No match + +/^(?!:) # colon disallowed at start + (?: # start of item + (?: [0-9a-f]{1,4} | # 1-4 hex digits or + (?(1)0 | () ) ) # if null previously matched, fail; else null + : # followed by colon + ){1,7} # end item; 1-7 of them required + [0-9a-f]{1,4} $ # final hex number at end of string + (?(1)|.) # check that there was an empty component + /xi + a123::a123 + 0: a123::a123 + 1: + a123:b342::abcd + 0: a123:b342::abcd + 1: + a123:b342::324e:abcd + 0: a123:b342::324e:abcd + 1: + a123:ddde:b342::324e:abcd + 0: a123:ddde:b342::324e:abcd + 1: + a123:ddde:b342::324e:dcba:abcd + 0: a123:ddde:b342::324e:dcba:abcd + 1: + a123:ddde:9999:b342::324e:dcba:abcd + 0: a123:ddde:9999:b342::324e:dcba:abcd + 1: + *** Failers +No match + 1:2:3:4:5:6:7:8 +No match + a123:bce:ddde:9999:b342::324e:dcba:abcd +No match + a123::9999:b342::324e:dcba:abcd +No match + abcde:2:3:4:5:6:7:8 +No match + ::1 +No match + abcd:fee0:123:: +No match + :1 +No match + 1: +No match + +/[z\Qa-d]\E]/ + z + 0: z + a + 0: a + - + 0: - + d + 0: d + ] + 0: ] + *** Failers + 0: a + b +No match + +/[\z\C]/ + z + 0: z + C + 0: C + +/\M/ + M + 0: M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + 0: REGular + regulaer + 0: regulaer + Regex + 0: Regex + regulär + 0: regul\xe4r + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + 0: \xc5\xe6\xe5\xe4\xe0 + Åæåäÿ + 0: \xc5\xe6\xe5\xe4\xff + ÅæåäÀ + 0: \xc5\xe6\xe5\xe4\xc0 + Åæåäß + 0: \xc5\xe6\xe5\xe4\xdf + +/(?<=Z)X./ + \x84XAZXB + 0: XB + +/ End of testinput1 / diff --git a/trunk/srclib/pcre/testdata/testoutput2 b/trunk/srclib/pcre/testdata/testoutput2 new file mode 100644 index 0000000000..f2e7d5483d --- /dev/null +++ b/trunk/srclib/pcre/testdata/testoutput2 @@ -0,0 +1,5607 @@ +PCRE version 5.0 13-Sep-2004 + +/(a)b|/ +Capturing subpattern count = 1 +No options +No first char +No need char + +/abc/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + abc + 0: abc + defabc + 0: abc + \Aabc + 0: abc + *** Failers +No match + \Adefabc +No match + ABC +No match + +/^abc/ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc + 0: abc + \Aabc + 0: abc + *** Failers +No match + defabc +No match + \Adefabc +No match + +/a+bc/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'c' + +/a*bc/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'c' + +/a{3}bc/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'c' + +/(abc|a+z)/ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char = 'a' +No need char + +/^abc$/ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc + 0: abc + *** Failers +No match + def\nabc +No match + +/ab\gdef/X +Failed: unrecognized character follows \ at offset 3 + +/(?X)ab\gdef/X +Failed: unrecognized character follows \ at offset 7 + +/x{5,4}/ +Failed: numbers out of order in {} quantifier at offset 5 + +/z{65536}/ +Failed: number too big in {} quantifier at offset 7 + +/[abcd/ +Failed: missing terminating ] for character class at offset 5 + +/(?X)[\B]/ +Failed: invalid escape sequence in character class at offset 6 + +/[z-a]/ +Failed: range out of order in character class at offset 3 + +/^*/ +Failed: nothing to repeat at offset 1 + +/(abc/ +Failed: missing ) at offset 4 + +/(?# abc/ +Failed: missing ) after comment at offset 7 + +/(?z)abc/ +Failed: unrecognized character after (? at offset 2 + +/.*b/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char at start or follows \n +Need char = 'b' + +/.*?b/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char at start or follows \n +Need char = 'b' + +/cat|dog|elephant/ +Capturing subpattern count = 0 +No options +No first char +No need char + this sentence eventually mentions a cat + 0: cat + this sentences rambles on and on for a while and then reaches elephant + 0: elephant + +/cat|dog|elephant/S +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: c d e + this sentence eventually mentions a cat + 0: cat + this sentences rambles on and on for a while and then reaches elephant + 0: elephant + +/cat|dog|elephant/iS +Capturing subpattern count = 0 +Options: caseless +No first char +No need char +Starting byte set: C D E c d e + this sentence eventually mentions a CAT cat + 0: CAT + this sentences rambles on and on for a while to elephant ElePhant + 0: elephant + +/a|[bcd]/S +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: a b c d + +/(a|[^\dZ])/S +Capturing subpattern count = 1 +No options +No first char +No need char +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = > + ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y [ \ ] ^ _ ` a b c d + e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 + \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 + \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 + \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 + \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf + \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce + \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd + \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec + \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb + \xfc \xfd \xfe \xff + +/(a|b)*[\s]/S +Capturing subpattern count = 1 +No options +No first char +No need char +Starting byte set: \x09 \x0a \x0c \x0d \x20 a b + +/(ab\2)/ +Failed: reference to non-existent subpattern at offset 6 + +/{4,5}abc/ +Failed: nothing to repeat at offset 4 + +/(a)(b)(c)\2/ +Capturing subpattern count = 3 +Max back reference = 2 +No options +First char = 'a' +Need char = 'c' + abcb + 0: abcb + 1: a + 2: b + 3: c + \O0abcb +Matched, but too many substrings + \O3abcb +Matched, but too many substrings + 0: abcb + \O6abcb +Matched, but too many substrings + 0: abcb + 1: a + \O9abcb +Matched, but too many substrings + 0: abcb + 1: a + 2: b + \O12abcb + 0: abcb + 1: a + 2: b + 3: c + +/(a)bc|(a)(b)\2/ +Capturing subpattern count = 3 +Max back reference = 2 +No options +First char = 'a' +No need char + abc + 0: abc + 1: a + \O0abc +Matched, but too many substrings + \O3abc +Matched, but too many substrings + 0: abc + \O6abc + 0: abc + 1: a + aba + 0: aba + 1: + 2: a + 3: b + \O0aba +Matched, but too many substrings + \O3aba +Matched, but too many substrings + 0: aba + \O6aba +Matched, but too many substrings + 0: aba + 1: + \O9aba +Matched, but too many substrings + 0: aba + 1: + 2: a + \O12aba + 0: aba + 1: + 2: a + 3: b + +/abc$/E +Capturing subpattern count = 0 +Options: dollar_endonly +First char = 'a' +Need char = 'c' + abc + 0: abc + *** Failers +No match + abc\n +No match + abc\ndef +No match + +/(a)(b)(c)(d)(e)\6/ +Failed: reference to non-existent subpattern at offset 17 + +/the quick brown fox/ +Capturing subpattern count = 0 +No options +First char = 't' +Need char = 'x' + the quick brown fox + 0: the quick brown fox + this is a line with the quick brown fox + 0: the quick brown fox + +/the quick brown fox/A +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + the quick brown fox + 0: the quick brown fox + *** Failers +No match + this is a line with the quick brown fox +No match + +/ab(?z)cd/ +Failed: unrecognized character after (? at offset 4 + +/^abc|def/ +Capturing subpattern count = 0 +No options +No first char +No need char + abcdef + 0: abc + abcdef\B + 0: def + +/.*((abc)$|(def))/ +Capturing subpattern count = 3 +Partial matching not supported +No options +First char at start or follows \n +No need char + defabc + 0: defabc + 1: abc + 2: abc + \Zdefabc + 0: def + 1: def + 2: + 3: def + +/abc/P + abc + 0: abc + *** Failers +No match: POSIX code 17: match failed + +/^abc|def/P + abcdef + 0: abc + abcdef\B + 0: def + +/.*((abc)$|(def))/P + defabc + 0: defabc + 1: abc + 2: abc + \Zdefabc + 0: def + 1: def + 3: def + +/the quick brown fox/P + the quick brown fox + 0: the quick brown fox + *** Failers +No match: POSIX code 17: match failed + The Quick Brown Fox +No match: POSIX code 17: match failed + +/the quick brown fox/Pi + the quick brown fox + 0: the quick brown fox + The Quick Brown Fox + 0: The Quick Brown Fox + +/abc.def/P + *** Failers +No match: POSIX code 17: match failed + abc\ndef +No match: POSIX code 17: match failed + +/abc$/P + abc + 0: abc + abc\n + 0: abc + +/(abc)\2/P +Failed: POSIX code 15: bad back reference at offset 7 + +/(abc\1)/P + abc +No match: POSIX code 17: match failed + +/)/ +Failed: unmatched parentheses at offset 0 + +/a[]b/ +Failed: missing terminating ] for character class at offset 4 + +/[^aeiou ]{3,}/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + co-processors, and for + 0: -pr + +/<.*>/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = '<' +Need char = '>' + abcghinop + 0: ghi + +/<.*?>/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = '<' +Need char = '>' + abcghinop + 0: + +/<.*>/U +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: + +/(?U)<.*>/ +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: + +/<.*?>/U +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = '<' +Need char = '>' + abcghinop + 0: ghi + +/={3,}/U +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = '=' +Need char = '=' + abc========def + 0: === + +/(?U)={3,}?/ +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = '=' +Need char = '=' + abc========def + 0: ======== + +/(?^abc)/m +Capturing subpattern count = 0 +Options: multiline +First char at start or follows \n +Need char = 'c' + abc + 0: abc + def\nabc + 0: abc + *** Failers +No match + defabc +No match + +/(?<=ab(c+)d)ef/ +Failed: lookbehind assertion is not fixed length at offset 11 + +/(?<=ab(?<=c+)d)ef/ +Failed: lookbehind assertion is not fixed length at offset 12 + +/(?<=ab(c|de)f)g/ +Failed: lookbehind assertion is not fixed length at offset 13 + +/The next three are in testinput2 because they have variable length branches/ +Capturing subpattern count = 0 +No options +First char = 'T' +Need char = 's' + +/(?<=bullock|donkey)-cart/ +Capturing subpattern count = 0 +No options +First char = '-' +Need char = 't' + the bullock-cart + 0: -cart + a donkey-cart race + 0: -cart + *** Failers +No match + cart +No match + horse-and-cart +No match + +/(?<=ab(?i)x|y|z)/ +Capturing subpattern count = 0 +No options +Case state changes +No first char +No need char + +/(?>.*)(?<=(abcd)|(xyz))/ +Capturing subpattern count = 2 +Partial matching not supported +No options +First char at start or follows \n +No need char + alphabetabcd + 0: alphabetabcd + 1: abcd + endingxyz + 0: endingxyz + 1: + 2: xyz + +/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/ +Capturing subpattern count = 0 +No options +Case state changes +First char = 'Z' +Need char = 'Z' + abxyZZ + 0: ZZ + abXyZZ + 0: ZZ + ZZZ + 0: ZZ + zZZ + 0: ZZ + bZZ + 0: ZZ + BZZ + 0: ZZ + *** Failers +No match + ZZ +No match + abXYZZ +No match + zzz +No match + bzz +No match + +/(? + 3: f + 1G a (1) + 2G (0) + 3G f (1) +get substring 4 failed -7 + 0L adef + 1L a + 2L + 3L f + bcdef\G1\G2\G3\G4\L + 0: bcdef + 1: bc + 2: bc + 3: f + 1G bc (2) + 2G bc (2) + 3G f (1) +get substring 4 failed -7 + 0L bcdef + 1L bc + 2L bc + 3L f + adefghijk\C0 + 0: adef + 1: a + 2: + 3: f + 0C adef (4) + +/^abc\00def/ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + abc\00def\L\C0 + 0: abc\x00def + 0C abc (7) + 0L abc + +/word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ +)((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ +)?)?)?)?)?)?)?)?)?otherword/M +Memory allocation (code space): 432 +Capturing subpattern count = 8 +Partial matching not supported +No options +First char = 'w' +Need char = 'd' + +/.*X/D +------------------------------------------------------------------ + 0 7 Bra 0 + 3 Any* + 5 X + 7 7 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char at start or follows \n +Need char = 'X' + +/.*X/Ds +------------------------------------------------------------------ + 0 7 Bra 0 + 3 Any* + 5 X + 7 7 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: anchored dotall +No first char +Need char = 'X' + +/(.*X|^B)/D +------------------------------------------------------------------ + 0 19 Bra 0 + 3 7 Bra 1 + 6 Any* + 8 X + 10 6 Alt + 13 ^ + 14 B + 16 13 Ket + 19 19 Ket + 22 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char at start or follows \n +No need char + +/(.*X|^B)/Ds +------------------------------------------------------------------ + 0 19 Bra 0 + 3 7 Bra 1 + 6 Any* + 8 X + 10 6 Alt + 13 ^ + 14 B + 16 13 Ket + 19 19 Ket + 22 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored dotall +No first char +No need char + +/(?s)(.*X|^B)/D +------------------------------------------------------------------ + 0 19 Bra 0 + 3 7 Bra 1 + 6 Any* + 8 X + 10 6 Alt + 13 ^ + 14 B + 16 13 Ket + 19 19 Ket + 22 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored dotall +No first char +No need char + +/(?s:.*X|^B)/D +------------------------------------------------------------------ + 0 25 Bra 0 + 3 9 Bra 0 + 6 04 Opt + 8 Any* + 10 X + 12 8 Alt + 15 04 Opt + 17 ^ + 18 B + 20 17 Ket + 23 00 Opt + 25 25 Ket + 28 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char at start or follows \n +No need char + +/\Biss\B/+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + +/\Biss\B/+P + Mississippi + 0: iss + 0+ issippi + +/iss/G+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + +/\Biss\B/G+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + +/\Biss\B/g+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + *** Failers +No match + Mississippi\A +No match + +/(?<=[Ms])iss/g+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + 0: iss + 0+ ippi + +/(?<=[Ms])iss/G+ +Capturing subpattern count = 0 +No options +First char = 'i' +Need char = 's' + Mississippi + 0: iss + 0+ issippi + +/^iss/g+ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + ississippi + 0: iss + 0+ issippi + +/.*iss/g+ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char at start or follows \n +Need char = 's' + abciss\nxyzisspqr + 0: abciss + 0+ \x0axyzisspqr + 0: xyziss + 0+ pqr + +/.i./+g +Capturing subpattern count = 0 +No options +No first char +Need char = 'i' + Mississippi + 0: Mis + 0+ sissippi + 0: sis + 0+ sippi + 0: sip + 0+ pi + Mississippi\A + 0: Mis + 0+ sissippi + 0: sis + 0+ sippi + 0: sip + 0+ pi + Missouri river + 0: Mis + 0+ souri river + 0: ri + 0+ river + 0: riv + 0+ er + Missouri river\A + 0: Mis + 0+ souri river + +/^.is/+g +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + Mississippi + 0: Mis + 0+ sissippi + +/^ab\n/g+ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + ab\nab\ncd + 0: ab\x0a + 0+ ab\x0acd + +/^ab\n/mg+ +Capturing subpattern count = 0 +Options: multiline +First char at start or follows \n +Need char = 10 + ab\nab\ncd + 0: ab\x0a + 0+ ab\x0acd + 0: ab\x0a + 0+ cd + +/abc/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/abc|bac/ +Capturing subpattern count = 0 +No options +No first char +Need char = 'c' + +/(abc|bac)/ +Capturing subpattern count = 1 +No options +No first char +Need char = 'c' + +/(abc|(c|dc))/ +Capturing subpattern count = 2 +No options +No first char +Need char = 'c' + +/(abc|(d|de)c)/ +Capturing subpattern count = 2 +No options +No first char +Need char = 'c' + +/a*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + +/a+/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/(baa|a+)/ +Capturing subpattern count = 1 +Partial matching not supported +No options +No first char +Need char = 'a' + +/a{0,3}/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + +/baa{3,}/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'b' +Need char = 'a' + +/"([^\\"]+|\\.)*"/ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char = '"' +Need char = '"' + +/(abc|ab[cd])/ +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(a|.)/ +Capturing subpattern count = 1 +No options +No first char +No need char + +/a|ba|\w/ +Capturing subpattern count = 0 +No options +No first char +No need char + +/abc(?=pqr)/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'r' + +/...(?<=abc)/ +Capturing subpattern count = 0 +No options +No first char +No need char + +/abc(?!pqr)/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/ab./ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/ab[xyz]/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/abc*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + +/ab.c*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + +/a.c*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/.c*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + +/ac*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/(a.c*|b.c*)/ +Capturing subpattern count = 1 +Partial matching not supported +No options +No first char +No need char + +/a.c*|aba/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/.+a/ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'a' + +/(?=abcda)a.*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'a' + +/(?=a)a.*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/a(b)*/ +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/a\d*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/ab\d*/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + +/a(\d)*/ +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/abcde{0,0}/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'd' + +/ab\d+/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + +/a(?(1)b)/ +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/a(?(1)bag|big)/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'g' + +/a(?(1)bag|big)*/ +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/a(?(1)bag|big)+/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'g' + +/a(?(1)b..|b..)/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/ab\d{0}e/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'e' + +/a?b?/ +Capturing subpattern count = 0 +No options +No first char +No need char + a + 0: a + b + 0: b + ab + 0: ab + \ + 0: + *** Failers + 0: + \N +No match + +/|-/ +Capturing subpattern count = 0 +No options +No first char +No need char + abcd + 0: + -abc + 0: + \Nab-c + 0: - + *** Failers + 0: + \Nabc +No match + +/a*(b+)(z)(z)/P + aaaabbbbzzzz + 0: aaaabbbbzz + 1: bbbb + 2: z + 3: z + aaaabbbbzzzz\O0 + aaaabbbbzzzz\O1 + 0: aaaabbbbzz + aaaabbbbzzzz\O2 + 0: aaaabbbbzz + 1: bbbb + aaaabbbbzzzz\O3 + 0: aaaabbbbzz + 1: bbbb + 2: z + aaaabbbbzzzz\O4 + 0: aaaabbbbzz + 1: bbbb + 2: z + 3: z + aaaabbbbzzzz\O5 + 0: aaaabbbbzz + 1: bbbb + 2: z + 3: z + +/^.?abcd/S +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'd' +Study returned NULL + +/\( # ( at start + (?: # Non-capturing bracket + (?>[^()]+) # Either a sequence of non-brackets (no backtracking) + | # Or + (?R) # Recurse - i.e. nested bracketed string + )* # Zero or more contents + \) # Closing ) + /x +Capturing subpattern count = 0 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (abcd) + 0: (abcd) + (abcd)xyz + 0: (abcd) + xyz(abcd) + 0: (abcd) + (ab(xy)cd)pqr + 0: (ab(xy)cd) + (ab(xycd)pqr + 0: (xycd) + () abc () + 0: () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + 0: (abcde(fsh)xyz(foo(bar))lmno) + *** Failers +No match + abcd +No match + abcd) +No match + (abcd +No match + +/\( ( (?>[^()]+) | (?R) )* \) /xg +Capturing subpattern count = 1 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd)pqr + 0: (ab(xy)cd) + 1: cd + 1(abcd)(x(y)z)pqr + 0: (abcd) + 1: abcd + 0: (x(y)z) + 1: z + +/\( (?: (?>[^()]+) | (?R) ) \) /x +Capturing subpattern count = 0 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (abcd) + 0: (abcd) + (ab(xy)cd) + 0: (xy) + (a(b(c)d)e) + 0: (c) + ((ab)) + 0: ((ab)) + *** Failers +No match + () +No match + +/\( (?: (?>[^()]+) | (?R) )? \) /x +Capturing subpattern count = 0 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + () + 0: () + 12(abcde(fsh)xyz(foo(bar))lmno)89 + 0: (fsh) + +/\( ( (?>[^()]+) | (?R) )* \) /x +Capturing subpattern count = 1 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: cd + +/\( ( ( (?>[^()]+) | (?R) )* ) \) /x +Capturing subpattern count = 2 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: cd + +/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x +Capturing subpattern count = 3 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: + 2: ab(xy)cd + 3: cd + (123ab(xy)cd) + 0: (123ab(xy)cd) + 1: 123 + 2: ab(xy)cd + 3: cd + +/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x +Capturing subpattern count = 3 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: + 3: cd + (123ab(xy)cd) + 0: (123ab(xy)cd) + 1: 123ab(xy)cd + 2: 123 + 3: cd + +/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x +Capturing subpattern count = 11 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(xy)cd) + 0: (ab(xy)cd) + 1: ab(xy)cd + 2: ab(xy)cd + 3: ab(xy)cd + 4: ab(xy)cd + 5: ab(xy)cd + 6: ab(xy)cd + 7: ab(xy)cd + 8: ab(xy)cd + 9: ab(xy)cd +10: ab(xy)cd +11: cd + +/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x +Capturing subpattern count = 3 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (abcd(xyz

    qrs)123) + 0: (abcd(xyz

    qrs)123) + 1: abcd(xyz

    qrs)123 + 2: 123 + 3: + +/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x +Capturing subpattern count = 3 +Partial matching not supported +Options: extended +First char = '(' +Need char = ')' + (ab(cd)ef) + 0: (ab(cd)ef) + 1: ab(cd)ef + 2: ef + 3: (cd) + (ab(cd(ef)gh)ij) + 0: (ab(cd(ef)gh)ij) + 1: ab(cd(ef)gh)ij + 2: ij + 3: (cd(ef)gh) + +/^[[:alnum:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [0-9A-Za-z] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^alnum:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-/:-@[-`{-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:alpha:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [A-Za-z] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^alpha:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-@[-`{-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:ascii:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-\x7f] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^ascii:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x80-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:blank:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x09 ] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:cntrl:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-\x1f\x7f] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:digit:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [0-9] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:graph:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [!-~] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:lower:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [a-z] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:print:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [ -~] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:punct:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [!-/:-@[-`{-~] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:space:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x09-\x0d ] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:upper:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [A-Z] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:xdigit:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [0-9A-Fa-f] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:word:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [0-9A-Z_a-z] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^cntrl:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [ -~\x80-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[12[:^digit:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-/12:-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/^[[:^blank:]]/D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-\x08\x0a-\x1f!-\xff] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/[01[:alpha:]%]/D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [%01A-Za-z] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[.ch.]]/ +Failed: POSIX collating elements are not supported at offset 1 + +/[[=ch=]]/ +Failed: POSIX collating elements are not supported at offset 1 + +/[[:rhubarb:]]/ +Failed: unknown POSIX class name at offset 3 + +/[[:upper:]]/i +Capturing subpattern count = 0 +Options: caseless +No first char +No need char + A + 0: A + a + 0: a + +/[[:lower:]]/i +Capturing subpattern count = 0 +Options: caseless +No first char +No need char + A + 0: A + a + 0: a + +/((?-i)[[:lower:]])[[:lower:]]/i +Capturing subpattern count = 1 +Options: caseless +Case state changes +No first char +No need char + ab + 0: ab + 1: a + aB + 0: aB + 1: a + *** Failers + 0: ai + 1: a + Ab +No match + AB +No match + +/[\200-\410]/ +Failed: range out of order in character class at offset 9 + +/^(?(0)f|b)oo/ +Failed: invalid condition (?(0) at offset 5 + +/This one's here because of the large output vector needed/ +Capturing subpattern count = 0 +No options +First char = 'T' +Need char = 'd' + +/(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/ +Capturing subpattern count = 271 +Max back reference = 270 +Partial matching not supported +No options +No first char +No need char + \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + 0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC + 1: 1 + 2: 2 + 3: 3 + 4: 4 + 5: 5 + 6: 6 + 7: 7 + 8: 8 + 9: 9 +10: 10 +11: 11 +12: 12 +13: 13 +14: 14 +15: 15 +16: 16 +17: 17 +18: 18 +19: 19 +20: 20 +21: 21 +22: 22 +23: 23 +24: 24 +25: 25 +26: 26 +27: 27 +28: 28 +29: 29 +30: 30 +31: 31 +32: 32 +33: 33 +34: 34 +35: 35 +36: 36 +37: 37 +38: 38 +39: 39 +40: 40 +41: 41 +42: 42 +43: 43 +44: 44 +45: 45 +46: 46 +47: 47 +48: 48 +49: 49 +50: 50 +51: 51 +52: 52 +53: 53 +54: 54 +55: 55 +56: 56 +57: 57 +58: 58 +59: 59 +60: 60 +61: 61 +62: 62 +63: 63 +64: 64 +65: 65 +66: 66 +67: 67 +68: 68 +69: 69 +70: 70 +71: 71 +72: 72 +73: 73 +74: 74 +75: 75 +76: 76 +77: 77 +78: 78 +79: 79 +80: 80 +81: 81 +82: 82 +83: 83 +84: 84 +85: 85 +86: 86 +87: 87 +88: 88 +89: 89 +90: 90 +91: 91 +92: 92 +93: 93 +94: 94 +95: 95 +96: 96 +97: 97 +98: 98 +99: 99 +100: 100 +101: 101 +102: 102 +103: 103 +104: 104 +105: 105 +106: 106 +107: 107 +108: 108 +109: 109 +110: 110 +111: 111 +112: 112 +113: 113 +114: 114 +115: 115 +116: 116 +117: 117 +118: 118 +119: 119 +120: 120 +121: 121 +122: 122 +123: 123 +124: 124 +125: 125 +126: 126 +127: 127 +128: 128 +129: 129 +130: 130 +131: 131 +132: 132 +133: 133 +134: 134 +135: 135 +136: 136 +137: 137 +138: 138 +139: 139 +140: 140 +141: 141 +142: 142 +143: 143 +144: 144 +145: 145 +146: 146 +147: 147 +148: 148 +149: 149 +150: 150 +151: 151 +152: 152 +153: 153 +154: 154 +155: 155 +156: 156 +157: 157 +158: 158 +159: 159 +160: 160 +161: 161 +162: 162 +163: 163 +164: 164 +165: 165 +166: 166 +167: 167 +168: 168 +169: 169 +170: 170 +171: 171 +172: 172 +173: 173 +174: 174 +175: 175 +176: 176 +177: 177 +178: 178 +179: 179 +180: 180 +181: 181 +182: 182 +183: 183 +184: 184 +185: 185 +186: 186 +187: 187 +188: 188 +189: 189 +190: 190 +191: 191 +192: 192 +193: 193 +194: 194 +195: 195 +196: 196 +197: 197 +198: 198 +199: 199 +200: 200 +201: 201 +202: 202 +203: 203 +204: 204 +205: 205 +206: 206 +207: 207 +208: 208 +209: 209 +210: 210 +211: 211 +212: 212 +213: 213 +214: 214 +215: 215 +216: 216 +217: 217 +218: 218 +219: 219 +220: 220 +221: 221 +222: 222 +223: 223 +224: 224 +225: 225 +226: 226 +227: 227 +228: 228 +229: 229 +230: 230 +231: 231 +232: 232 +233: 233 +234: 234 +235: 235 +236: 236 +237: 237 +238: 238 +239: 239 +240: 240 +241: 241 +242: 242 +243: 243 +244: 244 +245: 245 +246: 246 +247: 247 +248: 248 +249: 249 +250: 250 +251: 251 +252: 252 +253: 253 +254: 254 +255: 255 +256: 256 +257: 257 +258: 258 +259: 259 +260: 260 +261: 261 +262: 262 +263: 263 +264: 264 +265: 265 +266: 266 +267: 267 +268: 268 +269: 269 +270: ABC +271: ABC + +/This one's here because Perl does this differently and PCRE can't at present/ +Capturing subpattern count = 0 +No options +First char = 'T' +Need char = 't' + +/(main(O)?)+/ +Capturing subpattern count = 2 +No options +First char = 'm' +Need char = 'n' + mainmain + 0: mainmain + 1: main + mainOmain + 0: mainOmain + 1: main + 2: O + +/These are all cases where Perl does it differently (nested captures)/ +Capturing subpattern count = 1 +No options +First char = 'T' +Need char = 's' + +/^(a(b)?)+$/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aba + 0: aba + 1: a + 2: b + +/^(aa(bb)?)+$/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(aa|aa(bb))+$/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(aa(bb)??)+$/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + +/^(?:aa(bb)?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + +/^(aa(b(b))?)+$/ +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: aa + 2: bb + 3: b + +/^(?:aa(b(b))?)+$/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + 2: b + +/^(?:aa(b(?:b))?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: bb + +/^(?:aa(bb(?:b))?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bbb + +/^(?:aa(b(?:bb))?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bbb + +/^(?:aa(?:b(b))?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbaa + 0: aabbaa + 1: b + +/^(?:aa(?:b(bb))?)+$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: bb + +/^(aa(b(bb))?)+$/ +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbbaa + 0: aabbbaa + 1: aa + 2: bbb + 3: bb + +/^(aa(bb(bb))?)+$/ +Capturing subpattern count = 3 +Options: anchored +No first char +No need char + aabbbbaa + 0: aabbbbaa + 1: aa + 2: bbbb + 3: bb + +/--------------------------------------------------------------------/ +Capturing subpattern count = 0 +No options +First char = '-' +Need char = '-' + +/#/xMD +Memory allocation (code space): 7 +------------------------------------------------------------------ + 0 3 Bra 0 + 3 3 Ket + 6 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +No first char +No need char + +/a#/xMD +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra 0 + 3 a + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +First char = 'a' +No need char + +/[\s]/D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x09\x0a\x0c\x0d ] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\S]/D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x00-\x08\x0b\x0e-\x1f!-\xff] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/a(?i)b/D +------------------------------------------------------------------ + 0 9 Bra 0 + 3 a + 5 01 Opt + 7 NC b + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +Case state changes +First char = 'a' +Need char = 'b' (caseless) + ab + 0: ab + aB + 0: aB + *** Failers +No match + AB +No match + +/(a(?i)b)/D +------------------------------------------------------------------ + 0 17 Bra 0 + 3 9 Bra 1 + 6 a + 8 01 Opt + 10 NC b + 12 9 Ket + 15 00 Opt + 17 17 Ket + 20 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +Case state changes +First char = 'a' +Need char = 'b' (caseless) + ab + 0: ab + 1: ab + aB + 0: aB + 1: aB + *** Failers +No match + AB +No match + +/ (?i)abc/xD +------------------------------------------------------------------ + 0 9 Bra 0 + 3 NC abc + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless extended +First char = 'a' (caseless) +Need char = 'c' (caseless) + +/#this is a comment + (?i)abc/xD +------------------------------------------------------------------ + 0 9 Bra 0 + 3 NC abc + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless extended +First char = 'a' (caseless) +Need char = 'c' (caseless) + +/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D +------------------------------------------------------------------ + 0 603 Bra 0 + 3 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +603 603 Ket +606 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '1' +Need char = '0' + +/\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D +------------------------------------------------------------------ + 0 603 Bra 0 + 3 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +603 603 Ket +606 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '1' +Need char = '0' + +/\Q\E/D +------------------------------------------------------------------ + 0 3 Bra 0 + 3 3 Ket + 6 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + \ + 0: + +/\Q\Ex/D +------------------------------------------------------------------ + 0 5 Bra 0 + 3 x + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'x' +No need char + +/ \Q\E/D +------------------------------------------------------------------ + 0 5 Bra 0 + 3 + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = ' ' +No need char + +/a\Q\E/D +------------------------------------------------------------------ + 0 5 Bra 0 + 3 a + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + abc + 0: a + bca + 0: a + bac + 0: a + +/a\Q\Eb/D +------------------------------------------------------------------ + 0 7 Bra 0 + 3 ab + 7 7 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + abc + 0: ab + +/\Q\Eabc/D +------------------------------------------------------------------ + 0 9 Bra 0 + 3 abc + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/x*+\w/D +------------------------------------------------------------------ + 0 12 Bra 0 + 3 5 Once + 6 x* + 8 5 Ket + 11 \w + 12 12 Ket + 15 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + *** Failers + 0: F + xxxxx +No match + +/x?+/D +------------------------------------------------------------------ + 0 11 Bra 0 + 3 5 Once + 6 x? + 8 5 Ket + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/x++/D +------------------------------------------------------------------ + 0 11 Bra 0 + 3 5 Once + 6 x+ + 8 5 Ket + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'x' +No need char + +/x{1,3}+/D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 9 Once + 6 x + 8 x{,2} + 12 9 Ket + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'x' +No need char + +/(x)*+/D +------------------------------------------------------------------ + 0 18 Bra 0 + 3 12 Once + 6 Brazero + 7 5 Bra 1 + 10 x + 12 5 KetRmax + 15 12 Ket + 18 18 Ket + 21 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +No first char +No need char + +/^(\w++|\s++)*$/ +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored +No first char +No need char + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + 1: party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d++)(\w)/ +Capturing subpattern count = 2 +Partial matching not supported +No options +No first char +No need char + 12345a + 0: 12345a + 1: 12345 + 2: a + *** Failers +No match + 12345+ +No match + +/a++b/ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + +/(a++b)/ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + 1: aaab + +/(a++)b/ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char = 'a' +Need char = 'b' + aaab + 0: aaab + 1: aaa + +/([^()]++|\([^()]*\))+/ +Capturing subpattern count = 1 +Partial matching not supported +No options +No first char +No need char + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/\(([^()]++|\([^()]+\))+\)/ +Capturing subpattern count = 1 +Partial matching not supported +No options +First char = '(' +Need char = ')' + (abc) + 0: (abc) + 1: abc + (abc(def)xyz) + 0: (abc(def)xyz) + 1: xyz + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(abc){1,3}+/D +------------------------------------------------------------------ + 0 53 Bra 0 + 3 47 Once + 6 9 Bra 1 + 9 abc + 15 9 Ket + 18 Brazero + 19 28 Bra 0 + 22 9 Bra 1 + 25 abc + 31 9 Ket + 34 Brazero + 35 9 Bra 1 + 38 abc + 44 9 Ket + 47 28 Ket + 50 47 Ket + 53 53 Ket + 56 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'c' + +/a+?+/ +Failed: nothing to repeat at offset 3 + +/a{2,3}?+b/ +Failed: nothing to repeat at offset 7 + +/(?U)a+?+/ +Failed: nothing to repeat at offset 7 + +/a{2,3}?+b/U +Failed: nothing to repeat at offset 7 + +/x(?U)a++b/D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 x + 5 5 Once + 8 a+ + 10 5 Ket + 13 b + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'x' +Need char = 'b' + xaaaab + 0: xaaaab + +/(?U)xa++b/D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 x + 5 5 Once + 8 a+ + 10 5 Ket + 13 b + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: ungreedy +First char = 'x' +Need char = 'b' + xaaaab + 0: xaaaab + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/D +------------------------------------------------------------------ + 0 106 Bra 0 + 3 ^ + 4 99 Bra 1 + 7 5 Bra 2 + 10 a+ + 12 5 Ket + 15 37 Bra 3 + 18 [ab]+? + 52 37 Ket + 55 37 Bra 4 + 58 [bc]+ + 92 37 Ket + 95 5 Bra 5 + 98 \w* +100 5 Ket +103 99 Ket +106 106 Ket +109 End +------------------------------------------------------------------ +Capturing subpattern count = 5 +Partial matching not supported +Options: anchored +No first char +No need char + +/^x(?U)a+b/D +------------------------------------------------------------------ + 0 10 Bra 0 + 3 ^ + 4 x + 6 a+? + 8 b + 10 10 Ket + 13 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: anchored +No first char +Need char = 'b' + +/^x(?U)(a+)b/D +------------------------------------------------------------------ + 0 16 Bra 0 + 3 ^ + 4 x + 6 5 Bra 1 + 9 a+? + 11 5 Ket + 14 b + 16 16 Ket + 19 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored +No first char +Need char = 'b' + +/[.x.]/ +Failed: POSIX collating elements are not supported at offset 0 + +/[=x=]/ +Failed: POSIX collating elements are not supported at offset 0 + +/[:x:]/ +Failed: POSIX named classes are supported only within a class at offset 0 + +/\l/ +Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 + +/\L/ +Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 + +/\N{name}/ +Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 + +/\u/ +Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 + +/\U/ +Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 + +/[/ +Failed: missing terminating ] for character class at offset 1 + +/[a-/ +Failed: missing terminating ] for character class at offset 3 + +/[[:space:]/ +Failed: missing terminating ] for character class at offset 10 + +/[\s]/DM +Memory allocation (code space): 40 +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x09\x0a\x0c\x0d ] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[:space:]]/DM +Memory allocation (code space): 40 +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x09-\x0d ] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[[:space:]abcde]/DM +Memory allocation (code space): 40 +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x09-\x0d a-e] + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x +Capturing subpattern count = 0 +Partial matching not supported +Options: extended +First char = '<' +Need char = '>' + <> + 0: <> + + 0: + hij> + 0: hij> + hij> + 0: + def> + 0: def> + + 0: <> + *** Failers +No match + iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM +Memory allocation (code space): 826 +------------------------------------------------------------------ + 0 822 Bra 0 + 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +821 \b +822 822 Ket +825 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '8' +Need char = 'X' + +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM +Memory allocation (code space): 816 +------------------------------------------------------------------ + 0 812 Bra 0 + 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +811 \b +812 812 Ket +815 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = '$' +Need char = 'X' + +/(.*)\d+\1/I +Capturing subpattern count = 1 +Max back reference = 1 +Partial matching not supported +No options +No first char +No need char + +/(.*)\d+/I +Capturing subpattern count = 1 +Partial matching not supported +No options +First char at start or follows \n +No need char + +/(.*)\d+\1/Is +Capturing subpattern count = 1 +Max back reference = 1 +Partial matching not supported +Options: dotall +No first char +No need char + +/(.*)\d+/Is +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored dotall +No first char +No need char + +/(.*(xyz))\d+\2/I +Capturing subpattern count = 2 +Max back reference = 2 +Partial matching not supported +No options +First char at start or follows \n +Need char = 'z' + +/((.*))\d+\1/I +Capturing subpattern count = 2 +Max back reference = 1 +Partial matching not supported +No options +No first char +No need char + abc123bc + 0: bc123bc + 1: bc + 2: bc + +/a[b]/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/(?=a).*/I +Capturing subpattern count = 0 +Partial matching not supported +No options +First char = 'a' +No need char + +/(?=abc).xyz/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +Need char = 'z' (caseless) + +/(?=abc)(?i).xyz/I +Capturing subpattern count = 0 +No options +Case state changes +First char = 'a' +Need char = 'z' (caseless) + +/(?=a)(?=b)/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(?=.)a/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/((?=abcda)a)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'a' + +/((?=abcda)ab)/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + +/()a/I +Capturing subpattern count = 1 +No options +No first char +Need char = 'a' + +/(?(1)ab|ac)/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/(?(1)abz|acz)/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'z' + +/(?(1)abz)/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/(?(1)abz)123/I +Capturing subpattern count = 0 +No options +No first char +Need char = '3' + +/(a)+/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(a){2,3}/I +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'a' + +/(a)*/I +Capturing subpattern count = 1 +No options +No first char +No need char + +/[a]/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/[ab]/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/[ab]/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: a b + +/[^a]/I +Capturing subpattern count = 0 +No options +No first char +No need char + +/\d456/I +Capturing subpattern count = 0 +No options +No first char +Need char = '6' + +/\d456/IS +Capturing subpattern count = 0 +No options +No first char +Need char = '6' +Starting byte set: 0 1 2 3 4 5 6 7 8 9 + +/a^b/I +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/^a/mI +Capturing subpattern count = 0 +Options: multiline +First char at start or follows \n +Need char = 'a' + abcde + 0: a + xy\nabc + 0: a + *** Failers +No match + xyabc +No match + +/c|abc/I +Capturing subpattern count = 0 +No options +No first char +Need char = 'c' + +/(?i)[ab]/IS +Capturing subpattern count = 0 +Options: caseless +No first char +No need char +Starting byte set: A B a b + +/[ab](?i)cd/IS +Capturing subpattern count = 0 +No options +Case state changes +No first char +Need char = 'd' (caseless) +Starting byte set: a b + +/abc(?C)def/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + abcdef +--->abcdef + 0 ^ ^ d + 0: abcdef + 1234abcdef +--->1234abcdef + 0 ^ ^ d + 0: abcdef + *** Failers +No match + abcxyz +No match + abcxyzf +--->abcxyzf + 0 ^ ^ d +No match + +/abc(?C)de(?C1)f/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + 123abcdef +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f + 0: abcdef + +/(?C1)\dabc(?C2)def/ +Capturing subpattern count = 0 +No options +No first char +Need char = 'f' + 1234abcdef +--->1234abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 2 ^ ^ d + 0: 4abcdef + *** Failers +No match + abcdef +--->abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d +No match + +/(?C255)ab/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'b' + +/(?C256)ab/ +Failed: number after (?C is > 255 at offset 6 + +/(?Cab)xx/ +Failed: closing ) for (?C expected at offset 3 + +/(?C12vr)x/ +Failed: closing ) for (?C expected at offset 5 + +/abc(?C)def/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + *** Failers +No match + \x83\x0\x61bcdef +--->\x83\x00abcdef + 0 ^ ^ d + 0: abcdef + +/(abc)(?C)de(?C1)f/ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'f' + 123abcdef +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f + 0: abcdef + 1: abc + 123abcdef\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->123abcdef + ^ ^ d +Callout 1: last capture = 1 + 0: + 1: abc +--->123abcdef + ^ ^ f + 0: abcdef + 1: abc + 123abcdef\C- + 0: abcdef + 1: abc + *** Failers +No match + 123abcdef\C!1 +--->123abcdef + 0 ^ ^ d + 1 ^ ^ f +No match + +/(?C0)(abc(?C1))*/ +Capturing subpattern count = 1 +No options +No first char +No need char + abcabcabc +--->abcabcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabcabc + 1: abc + abcabc\C!1!3 +--->abcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabc + 1: abc + *** Failers +--->*** Failers + 0 ^ (abc(?C1))* + 0: + abcabcabc\C!1!3 +--->abcabcabc + 0 ^ (abc(?C1))* + 1 ^ ^ ) + 1 ^ ^ ) + 1 ^ ^ ) + 0: abcabc + 1: abc + +/(\d{3}(?C))*/ +Capturing subpattern count = 1 +Partial matching not supported +No options +No first char +No need char + 123\C+ +Callout 0: last capture = -1 + 0: +--->123 + ^ ^ ) + 0: 123 + 1: 123 + 123456\C+ +Callout 0: last capture = -1 + 0: +--->123456 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 123 +--->123456 + ^ ^ ) + 0: 123456 + 1: 456 + 123456789\C+ +Callout 0: last capture = -1 + 0: +--->123456789 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 123 +--->123456789 + ^ ^ ) +Callout 0: last capture = 1 + 0: + 1: 456 +--->123456789 + ^ ^ ) + 0: 123456789 + 1: 789 + +/((xyz)(?C)p|(?C1)xyzabc)/ +Capturing subpattern count = 2 +No options +First char = 'x' +No need char + xyzabc\C+ +Callout 0: last capture = 2 + 0: + 1: + 2: xyz +--->xyzabc + ^ ^ p +Callout 1: last capture = -1 + 0: +--->xyzabc + ^ x + 0: xyzabc + 1: xyzabc + +/(X)((xyz)(?C)p|(?C1)xyzabc)/ +Capturing subpattern count = 3 +No options +First char = 'X' +Need char = 'x' + Xxyzabc\C+ +Callout 0: last capture = 3 + 0: + 1: X + 2: + 3: xyz +--->Xxyzabc + ^ ^ p +Callout 1: last capture = 1 + 0: + 1: X +--->Xxyzabc + ^^ x + 0: Xxyzabc + 1: X + 2: xyzabc + +/(?=(abc))(?C)abcdef/ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'f' + abcdef\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->abcdef + ^ a + 0: abcdef + 1: abc + +/(?!(abc)(?C1)d)(?C2)abcxyz/ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'z' + abcxyz\C+ +Callout 1: last capture = 1 + 0: + 1: abc +--->abcxyz + ^ ^ d +Callout 2: last capture = -1 + 0: +--->abcxyz + ^ a + 0: abcxyz + +/(?<=(abc)(?C))xyz/ +Capturing subpattern count = 1 +No options +First char = 'x' +Need char = 'z' + abcxyz\C+ +Callout 0: last capture = 1 + 0: + 1: abc +--->abcxyz + ^ ) + 0: xyz + 1: abc + +/(?C)abc/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' + +/(?C)^abc/ +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?C)a|b/S +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: a b + +/(?R)/ +Failed: recursive call could loop indefinitely at offset 3 + +/(a|(?R))/ +Failed: recursive call could loop indefinitely at offset 6 + +/(ab|(bc|(de|(?R))))/ +Failed: recursive call could loop indefinitely at offset 15 + +/x(ab|(bc|(de|(?R))))/ +Capturing subpattern count = 3 +No options +First char = 'x' +No need char + xab + 0: xab + 1: ab + xbc + 0: xbc + 1: bc + 2: bc + xde + 0: xde + 1: de + 2: de + 3: de + xxab + 0: xxab + 1: xab + 2: xab + 3: xab + xxxab + 0: xxxab + 1: xxab + 2: xxab + 3: xxab + *** Failers +No match + xyab +No match + +/(ab|(bc|(de|(?1))))/ +Failed: recursive call could loop indefinitely at offset 15 + +/x(ab|(bc|(de|(?1)x)x)x)/ +Failed: recursive call could loop indefinitely at offset 16 + +/^([^()]|\((?1)*\))*$/ +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + abc + 0: abc + 1: c + a(b)c + 0: a(b)c + 1: c + a(b(c))d + 0: a(b(c))d + 1: d + *** Failers) +No match + a(b(c)d +No match + +/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) + 2: + 3: Satan, oscillate my metallic sonatas + 4: S + A man, a plan, a canal: Panama! + 0: A man, a plan, a canal: Panama! + 1: + 2: + 3: A man, a plan, a canal: Panama + 4: A + Able was I ere I saw Elba. + 0: Able was I ere I saw Elba. + 1: + 2: + 3: Able was I ere I saw Elba + 4: A + *** Failers +No match + The quick brown fox +No match + +/^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ +Capturing subpattern count = 2 +Partial matching not supported +Options: anchored +No first char +No need char + 12 + 0: 12 + 1: 12 + (((2+2)*-3)-7) + 0: (((2+2)*-3)-7) + 1: (((2+2)*-3)-7) + 2: - + -12 + 0: -12 + 1: -12 + *** Failers +No match + ((2+2)*-3)-7) +No match + +/^(x(y|(?1){2})z)/ +Capturing subpattern count = 2 +Options: anchored +No first char +No need char + xyz + 0: xyz + 1: xyz + 2: y + xxyzxyzz + 0: xxyzxyzz + 1: xxyzxyzz + 2: xyzxyz + *** Failers +No match + xxyzz +No match + xxyzxyzxyzz +No match + +/((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x +Capturing subpattern count = 2 +Partial matching not supported +Options: extended +First char = '<' +Need char = '>' + <> + 0: <> + 1: <> + 2: <> + + 0: + 1: + 2: + hij> + 0: hij> + 1: hij> + 2: hij> + hij> + 0: + 1: + 2: + def> + 0: def> + 1: def> + 2: def> + + 0: <> + 1: <> + 2: <> + *** Failers +No match + b|c)d(?Pe)/D +------------------------------------------------------------------ + 0 28 Bra 0 + 3 a + 5 5 Bra 1 + 8 b + 10 5 Alt + 13 c + 15 10 Ket + 18 d + 20 5 Bra 2 + 23 e + 25 5 Ket + 28 28 Ket + 31 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + longername2 2 + name1 1 +No options +First char = 'a' +Need char = 'e' + abde + 0: abde + 1: b + 2: e + acde + 0: acde + 1: c + 2: e + +/(?:a(?Pc(?Pd)))(?Pa)/D +------------------------------------------------------------------ + 0 35 Bra 0 + 3 21 Bra 0 + 6 a + 8 13 Bra 1 + 11 c + 13 5 Bra 2 + 16 d + 18 5 Ket + 21 13 Ket + 24 21 Ket + 27 5 Bra 3 + 30 a + 32 5 Ket + 35 35 Ket + 38 End +------------------------------------------------------------------ +Capturing subpattern count = 3 +Named capturing subpatterns: + a 3 + c 1 + d 2 +No options +First char = 'a' +Need char = 'a' + +/(?Pa)...(?P=a)bbb(?P>a)d/D +------------------------------------------------------------------ + 0 28 Bra 0 + 3 5 Bra 1 + 6 a + 8 5 Ket + 11 Any + 12 Any + 13 Any + 14 \1 + 17 bbb + 23 3 Recurse + 26 d + 28 28 Ket + 31 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Max back reference = 1 +Named capturing subpatterns: + a 1 +No options +First char = 'a' +Need char = 'd' + +/^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/i +Capturing subpattern count = 4 +Max back reference = 4 +Named capturing subpatterns: + four 4 + one 1 + three 3 + two 2 +Partial matching not supported +Options: anchored caseless +No first char +No need char + 1221 + 0: 1221 + 1: 1221 + 2: 1 + Satan, oscillate my metallic sonatas! + 0: Satan, oscillate my metallic sonatas! + 1: + 2: + 3: Satan, oscillate my metallic sonatas + 4: S + A man, a plan, a canal: Panama! + 0: A man, a plan, a canal: Panama! + 1: + 2: + 3: A man, a plan, a canal: Panama + 4: A + Able was I ere I saw Elba. + 0: Able was I ere I saw Elba. + 1: + 2: + 3: Able was I ere I saw Elba + 4: A + *** Failers +No match + The quick brown fox +No match + +/((?(R)a|b))\1(?1)?/ +Capturing subpattern count = 1 +Max back reference = 1 +No options +No first char +No need char + bb + 0: bb + 1: b + bbaa + 0: bba + 1: b + +/(.*)a/sI +Capturing subpattern count = 1 +Partial matching not supported +Options: anchored dotall +No first char +Need char = 'a' + +/(.*)a\1/sI +Capturing subpattern count = 1 +Max back reference = 1 +Partial matching not supported +Options: dotall +No first char +Need char = 'a' + +/(.*)a(b)\2/sI +Capturing subpattern count = 2 +Max back reference = 2 +Partial matching not supported +Options: anchored dotall +No first char +Need char = 'b' + +/((.*)a|(.*)b)z/sI +Capturing subpattern count = 3 +Partial matching not supported +Options: anchored dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\1/sI +Capturing subpattern count = 3 +Max back reference = 1 +Partial matching not supported +Options: dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\2/sI +Capturing subpattern count = 3 +Max back reference = 2 +Partial matching not supported +Options: dotall +No first char +Need char = 'z' + +/((.*)a|(.*)b)z\3/sI +Capturing subpattern count = 3 +Max back reference = 3 +Partial matching not supported +Options: dotall +No first char +Need char = 'z' + +/((.*)a|^(.*)b)z\3/sI +Capturing subpattern count = 3 +Max back reference = 3 +Partial matching not supported +Options: anchored dotall +No first char +Need char = 'z' + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/sI +Capturing subpattern count = 31 +Partial matching not supported +Options: anchored dotall +No first char +No need char + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/sI +Capturing subpattern count = 31 +Max back reference = 31 +Partial matching not supported +Options: dotall +No first char +No need char + +/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/sI +Capturing subpattern count = 32 +Max back reference = 32 +Partial matching not supported +Options: dotall +No first char +No need char + +/(a)(bc)/ND +------------------------------------------------------------------ + 0 21 Bra 0 + 3 5 Bra 0 + 6 a + 8 5 Ket + 11 7 Bra 0 + 14 bc + 18 7 Ket + 21 21 Ket + 24 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +First char = 'a' +Need char = 'c' + abc + 0: abc + +/(?Pa)(bc)/ND +------------------------------------------------------------------ + 0 21 Bra 0 + 3 5 Bra 1 + 6 a + 8 5 Ket + 11 7 Bra 0 + 14 bc + 18 7 Ket + 21 21 Ket + 24 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Named capturing subpatterns: + one 1 +Options: +First char = 'a' +Need char = 'c' + abc + 0: abc + 1: a + +/(a)(?Pbc)/ND +------------------------------------------------------------------ + 0 21 Bra 0 + 3 5 Bra 0 + 6 a + 8 5 Ket + 11 7 Bra 1 + 14 bc + 18 7 Ket + 21 21 Ket + 24 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Named capturing subpatterns: + named 1 +Options: +First char = 'a' +Need char = 'c' + +/(a+)*zz/ +Capturing subpattern count = 1 +Partial matching not supported +No options +No first char +Need char = 'z' + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M +Minimum match limit = 8 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaz\M +Minimum match limit = 32768 +No match + +/(aaa(?C1)bbb|ab)/ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'b' + aaabbb +--->aaabbb + 1 ^ ^ b + 0: aaabbb + 1: aaabbb + aaabbb\C*0 +--->aaabbb + 1 ^ ^ b + 0: aaabbb + 1: aaabbb + aaabbb\C*1 +--->aaabbb + 1 ^ ^ b +Callout data = 1 + 0: ab + 1: ab + aaabbb\C*-1 +--->aaabbb + 1 ^ ^ b +Callout data = -1 +No match + +/ab(?Pcd)ef(?Pgh)/ +Capturing subpattern count = 2 +Named capturing subpatterns: + one 1 + two 2 +No options +First char = 'a' +Need char = 'h' + abcdefgh + 0: abcdefgh + 1: cd + 2: gh + abcdefgh\C1\Gtwo + 0: abcdefgh + 1: cd + 2: gh + 1C cd (2) + 2G gh (2) + abcdefgh\Cone\Ctwo + 0: abcdefgh + 1: cd + 2: gh + 1C cd (2) + 2C gh (2) + abcdefgh\Cthree +no parentheses with name "three" + 0: abcdefgh + 1: cd + 2: gh + +/(?P)(?P)/D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 3 Bra 1 + 6 3 Ket + 9 3 Bra 2 + 12 3 Ket + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + Tes 1 + Test 2 +No options +No first char +No need char + +/(?P)(?P)/D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 3 Bra 1 + 6 3 Ket + 9 3 Bra 2 + 12 3 Ket + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Named capturing subpatterns: + Tes 2 + Test 1 +No options +No first char +No need char + +/(?Pzz)(?Paa)/ +Capturing subpattern count = 2 +Named capturing subpatterns: + A 2 + Z 1 +No options +First char = 'z' +Need char = 'a' + zzaa\CZ + 0: zzaa + 1: zz + 2: aa + 1C zz (2) + zzaa\CA + 0: zzaa + 1: zz + 2: aa + 2C aa (2) + +/(?Peks)(?Peccs)/ +Failed: two named groups have the same name at offset 16 + +/(?Pabc(?Pdef)(?Pxyz))/ +Failed: two named groups have the same name at offset 31 + +"\[((?P\d+)(,(?P>elem))*)\]" +Capturing subpattern count = 3 +Named capturing subpatterns: + elem 2 +Partial matching not supported +No options +First char = '[' +Need char = ']' + [10,20,30,5,5,4,4,2,43,23,4234] + 0: [10,20,30,5,5,4,4,2,43,23,4234] + 1: 10,20,30,5,5,4,4,2,43,23,4234 + 2: 10 + 3: ,4234 + *** Failers +No match + [] +No match + +"\[((?P\d+)(,(?P>elem))*)?\]" +Capturing subpattern count = 3 +Named capturing subpatterns: + elem 2 +Partial matching not supported +No options +First char = '[' +Need char = ']' + [10,20,30,5,5,4,4,2,43,23,4234] + 0: [10,20,30,5,5,4,4,2,43,23,4234] + 1: 10,20,30,5,5,4,4,2,43,23,4234 + 2: 10 + 3: ,4234 + [] + 0: [] + +/(a(b(?2)c))?/D +------------------------------------------------------------------ + 0 25 Bra 0 + 3 Brazero + 4 18 Bra 1 + 7 a + 9 10 Bra 2 + 12 b + 14 9 Recurse + 17 c + 19 10 Ket + 22 18 Ket + 25 25 Ket + 28 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/(a(b(?2)c))*/D +------------------------------------------------------------------ + 0 25 Bra 0 + 3 Brazero + 4 18 Bra 1 + 7 a + 9 10 Bra 2 + 12 b + 14 9 Recurse + 17 c + 19 10 Ket + 22 18 KetRmax + 25 25 Ket + 28 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/(a(b(?2)c)){0,2}/D +------------------------------------------------------------------ + 0 53 Bra 0 + 3 Brazero + 4 46 Bra 0 + 7 18 Bra 1 + 10 a + 12 10 Bra 2 + 15 b + 17 12 Recurse + 20 c + 22 10 Ket + 25 18 Ket + 28 Brazero + 29 18 Bra 1 + 32 a + 34 10 Bra 2 + 37 b + 39 12 Recurse + 42 c + 44 10 Ket + 47 18 Ket + 50 46 Ket + 53 53 Ket + 56 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +No options +No first char +No need char + +/[ab]{1}+/D +------------------------------------------------------------------ + 0 47 Bra 0 + 3 41 Once + 6 [ab]{1,1} + 44 41 Ket + 47 47 Ket + 50 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/i +Capturing subpattern count = 3 +Partial matching not supported +Options: caseless +No first char +Need char = 'g' (caseless) + Baby Bjorn Active Carrier - With free SHIPPING!! + 0: Baby Bjorn Active Carrier - With free SHIPPING!! + 1: Baby Bjorn Active Carrier - With free SHIPPING!! + +/((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/iS +Capturing subpattern count = 3 +Partial matching not supported +Options: caseless +No first char +Need char = 'g' (caseless) +Study returned NULL + Baby Bjorn Active Carrier - With free SHIPPING!! + 0: Baby Bjorn Active Carrier - With free SHIPPING!! + 1: Baby Bjorn Active Carrier - With free SHIPPING!! + +/a*.*b/SD +------------------------------------------------------------------ + 0 9 Bra 0 + 3 a* + 5 Any* + 7 b + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'b' +Study returned NULL + +/(a|b)*.?c/SD +------------------------------------------------------------------ + 0 21 Bra 0 + 3 Brazero + 4 5 Bra 1 + 7 a + 9 5 Alt + 12 b + 14 10 KetRmax + 17 Any? + 19 c + 21 21 Ket + 24 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +No first char +Need char = 'c' +Study returned NULL + +/abc(?C255)de(?C)f/D +------------------------------------------------------------------ + 0 27 Bra 0 + 3 abc + 9 Callout 255 10 1 + 15 de + 19 Callout 0 16 1 + 25 f + 27 27 Ket + 30 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'f' + +/abcde/CD +------------------------------------------------------------------ + 0 49 Bra 0 + 3 Callout 255 0 1 + 9 a + 11 Callout 255 1 1 + 17 b + 19 Callout 255 2 1 + 25 c + 27 Callout 255 3 1 + 33 d + 35 Callout 255 4 1 + 41 e + 43 Callout 255 5 0 + 49 49 Ket + 52 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +First char = 'a' +Need char = 'e' + abcde +--->abcde + +0 ^ a + +1 ^^ b + +2 ^ ^ c + +3 ^ ^ d + +4 ^ ^ e + +5 ^ ^ + 0: abcde + abcdfe +--->abcdfe + +0 ^ a + +1 ^^ b + +2 ^ ^ c + +3 ^ ^ d + +4 ^ ^ e +No match + +/a*b/CD +------------------------------------------------------------------ + 0 25 Bra 0 + 3 Callout 255 0 2 + 9 a* + 11 Callout 255 2 1 + 17 b + 19 Callout 255 3 0 + 25 25 Ket + 28 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: +No first char +Need char = 'b' + ab +--->ab + +0 ^ a* + +2 ^^ b + +3 ^ ^ + 0: ab + aaaab +--->aaaab + +0 ^ a* + +2 ^ ^ b + +3 ^ ^ + 0: aaaab + aaaacb +--->aaaacb + +0 ^ a* + +2 ^ ^ b + +2 ^ ^ b + +2 ^ ^ b + +2 ^^ b + +2 ^ b + +0 ^ a* + +2 ^ ^ b + +2 ^ ^ b + +2 ^^ b + +2 ^ b + +0 ^ a* + +2 ^ ^ b + +2 ^^ b + +2 ^ b + +0 ^ a* + +2 ^^ b + +2 ^ b + +0 ^ a* + +2 ^ b + +0 ^ a* + +2 ^ b + +3 ^^ + 0: b + +/a+b/CD +------------------------------------------------------------------ + 0 25 Bra 0 + 3 Callout 255 0 2 + 9 a+ + 11 Callout 255 2 1 + 17 b + 19 Callout 255 3 0 + 25 25 Ket + 28 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: +First char = 'a' +Need char = 'b' + ab +--->ab + +0 ^ a+ + +2 ^^ b + +3 ^ ^ + 0: ab + aaaab +--->aaaab + +0 ^ a+ + +2 ^ ^ b + +3 ^ ^ + 0: aaaab + aaaacb +--->aaaacb + +0 ^ a+ + +2 ^ ^ b + +2 ^ ^ b + +2 ^ ^ b + +2 ^^ b + +0 ^ a+ + +2 ^ ^ b + +2 ^ ^ b + +2 ^^ b + +0 ^ a+ + +2 ^ ^ b + +2 ^^ b + +0 ^ a+ + +2 ^^ b +No match + +/(abc|def)x/CD +------------------------------------------------------------------ + 0 92 Bra 0 + 3 Callout 255 0 9 + 9 33 Bra 1 + 12 Callout 255 1 1 + 18 a + 20 Callout 255 2 1 + 26 b + 28 Callout 255 3 1 + 34 c + 36 Callout 255 4 0 + 42 33 Alt + 45 Callout 255 5 1 + 51 d + 53 Callout 255 6 1 + 59 e + 61 Callout 255 7 1 + 67 f + 69 Callout 255 8 0 + 75 66 Ket + 78 Callout 255 9 1 + 84 x + 86 Callout 255 10 0 + 92 92 Ket + 95 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +Need char = 'x' + abcx +--->abcx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x ++10 ^ ^ + 0: abcx + 1: abc + defx +--->defx + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x ++10 ^ ^ + 0: defx + 1: def + abcdefzx +--->abcdefzx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d +No match + +/(ab|cd){3,4}/C +Capturing subpattern count = 1 +Options: +No first char +No need char + ababab +--->ababab + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c ++12 ^ ^ + 0: ababab + 1: ab + abcdabcd +--->abcdabcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdabcd + 1: cd + abcdcdcdcdcd +--->abcdcdcdcdcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdcdcd + 1: cd + +/([ab]{,4}c|xy)/CD +------------------------------------------------------------------ + 0 131 Bra 0 + 3 Callout 255 0 14 + 9 88 Bra 1 + 12 Callout 255 1 4 + 18 [ab] + 51 Callout 255 5 1 + 57 { + 59 Callout 255 6 1 + 65 , + 67 Callout 255 7 1 + 73 4 + 75 Callout 255 8 1 + 81 } + 83 Callout 255 9 1 + 89 c + 91 Callout 255 10 0 + 97 25 Alt +100 Callout 255 11 1 +106 x +108 Callout 255 12 1 +114 y +116 Callout 255 13 0 +122 113 Ket +125 Callout 255 14 0 +131 131 Ket +134 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +No need char + Note: that { does NOT introduce a quantifier +--->Note: that { does NOT introduce a quantifier + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] ++11 ^ x +No match + +/([ab]{1,4}c|xy){4,5}?123/CD +------------------------------------------------------------------ + 0 485 Bra 0 + 3 Callout 255 0 21 + 9 61 Bra 1 + 12 Callout 255 1 9 + 18 [ab]{1,4} + 56 Callout 255 10 1 + 62 c + 64 Callout 255 11 0 + 70 25 Alt + 73 Callout 255 12 1 + 79 x + 81 Callout 255 13 1 + 87 y + 89 Callout 255 14 0 + 95 86 Ket + 98 61 Bra 1 +101 Callout 255 1 9 +107 [ab]{1,4} +145 Callout 255 10 1 +151 c +153 Callout 255 11 0 +159 25 Alt +162 Callout 255 12 1 +168 x +170 Callout 255 13 1 +176 y +178 Callout 255 14 0 +184 86 Ket +187 61 Bra 1 +190 Callout 255 1 9 +196 [ab]{1,4} +234 Callout 255 10 1 +240 c +242 Callout 255 11 0 +248 25 Alt +251 Callout 255 12 1 +257 x +259 Callout 255 13 1 +265 y +267 Callout 255 14 0 +273 86 Ket +276 61 Bra 1 +279 Callout 255 1 9 +285 [ab]{1,4} +323 Callout 255 10 1 +329 c +331 Callout 255 11 0 +337 25 Alt +340 Callout 255 12 1 +346 x +348 Callout 255 13 1 +354 y +356 Callout 255 14 0 +362 86 Ket +365 Braminzero +366 61 Bra 1 +369 Callout 255 1 9 +375 [ab]{1,4} +413 Callout 255 10 1 +419 c +421 Callout 255 11 0 +427 25 Alt +430 Callout 255 12 1 +436 x +438 Callout 255 13 1 +444 y +446 Callout 255 14 0 +452 86 Ket +455 Callout 255 21 1 +461 1 +463 Callout 255 22 1 +469 2 +471 Callout 255 23 1 +477 3 +479 Callout 255 24 0 +485 485 Ket +488 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: +No first char +Need char = '3' + aacaacaacaacaac123 +--->aacaacaacaacaac123 + +0 ^ ([ab]{1,4}c|xy){4,5}? + +1 ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | ++21 ^ ^ 1 + +1 ^ ^ [ab]{1,4} ++10 ^ ^ c ++11 ^ ^ | ++21 ^ ^ 1 ++22 ^ ^ 2 ++23 ^ ^ 3 ++24 ^ ^ + 0: aacaacaacaacaac123 + 1: aac + +/\b.*/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + ab cd\>1 + 0: cd + +/\b.*/Is +Capturing subpattern count = 0 +Partial matching not supported +Options: dotall +No first char +No need char + ab cd\>1 + 0: cd + +/(?!.bcd).*/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +No need char + Xbcd12345 + 0: bcd12345 + +/abcde/ +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'e' + ab\P +Partial match + abc\P +Partial match + abcd\P +Partial match + abcde\P + 0: abcde + the quick brown abc\P +Partial match + ** Failers\P +No match + the quick brown abxyz fox\P +No match + +"^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$" +Capturing subpattern count = 3 +Options: anchored +No first char +Need char = '/' + 13/05/04\P + 0: 13/05/04 + 1: 13 + 2: 05 + 13/5/2004\P + 0: 13/5/2004 + 1: 13 + 2: 5 + 3: 20 + 02/05/09\P + 0: 02/05/09 + 1: 02 + 2: 05 + 1\P +Partial match + 1/2\P +Partial match + 1/2/0\P +Partial match + 1/2/04\P + 0: 1/2/04 + 1: 1 + 2: 2 + 0\P +Partial match + 02/\P +Partial match + 02/0\P +Partial match + 02/1\P +Partial match + ** Failers\P +No match + \P +No match + 123\P +No match + 33/4/04\P +No match + 3/13/04\P +No match + 0/1/2003\P +No match + 0/\P +No match + 02/0/\P +No match + 02/13\P +No match + +/0{0,2}ABC/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'C' + +/\d{3,}ABC/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'C' + +/\d*ABC/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'C' + +/[abc]+DE/I +Capturing subpattern count = 0 +Partial matching not supported +No options +No first char +Need char = 'E' + +/[abc]?123/ +Capturing subpattern count = 0 +No options +No first char +Need char = '3' + 123\P + 0: 123 + a\P +Partial match + b\P +Partial match + c\P +Partial match + c12\P +Partial match + c123\P + 0: c123 + +/^(?:\d){3,5}X/ +Capturing subpattern count = 0 +Options: anchored +No first char +Need char = 'X' + 1\P +Partial match + 123\P +Partial match + 123X + 0: 123X + 1234\P +Partial match + 1234X + 0: 1234X + 12345\P +Partial match + 12345X + 0: 12345X + *** Failers +No match + 1X +No match + 123456\P +No match + +/abc/>testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Compiled regex written to testsavedregex +testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Compiled regex written to testsavedregex +testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Starting byte set: a b +Compiled regex written to testsavedregex +Study data written to testsavedregex +testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Starting byte set: a b +Compiled regex written to testsavedregex +Study data written to testsavedregex +(.)*~smg +Capturing subpattern count = 3 +Max back reference = 1 +Partial matching not supported +Options: multiline dotall +First char = '<' +Need char = '>' + \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + 0: \x0a\x0aPartner der LCO\x0ade\x0aPartner der LINEAS Consulting\x0aGmbH\x0aLINEAS Consulting GmbH Hamburg\x0aPartnerfirmen\x0a30 days\x0aindex,follow\x0a\x0aja\x0a3\x0aPartner\x0a\x0a\x0aLCO\x0aLINEAS Consulting\x0a15.10.2003\x0a\x0a\x0a\x0a\x0aDie Partnerfirmen der LINEAS Consulting\x0aGmbH\x0a\x0a\x0a \x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a + 1: seite + 2: \x0a + 3: seite + +/^a/IF +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/ End of testinput2 / +Capturing subpattern count = 0 +No options +First char = ' ' +Need char = ' ' diff --git a/trunk/srclib/pcre/testdata/testoutput3 b/trunk/srclib/pcre/testdata/testoutput3 new file mode 100644 index 0000000000..225bd5bff0 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testoutput3 @@ -0,0 +1,115 @@ +PCRE version 5.0 13-Sep-2004 + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\w]+/Lfr_FR + École + 0: École + +/^[\w]+/ + *** Failers +No match + École +No match + +/^[\W]+/ + École + 0: \xc9 + +/^[\W]+/Lfr_FR + *** Failers + 0: *** + École +No match + +/[\b]/ + \b + 0: \x08 + *** Failers +No match + a +No match + +/[\b]/Lfr_FR + \b + 0: \x08 + *** Failers +No match + a +No match + +/^\w+/ + *** Failers +No match + École +No match + +/^\w+/Lfr_FR + École + 0: École + +/(.+)\b(.+)/ + École + 0: \xc9cole + 1: \xc9 + 2: cole + +/(.+)\b(.+)/Lfr_FR + *** Failers + 0: *** Failers + 1: *** + 2: Failers + École +No match + +/École/i + École + 0: \xc9cole + *** Failers +No match + école +No match + +/École/iLfr_FR + École + 0: École + école + 0: école + +/\w/IS +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + +/\w/ISLfr_FR +Capturing subpattern count = 0 +No options +No first char +No need char +Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P + Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z + µ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä + å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ + +/^[\xc8-\xc9]/iLfr_FR + École + 0: É + école + 0: é + +/^[\xc8-\xc9]/Lfr_FR + École + 0: É + *** Failers +No match + école +No match + +/ End of testinput3 / diff --git a/trunk/srclib/pcre/testdata/testoutput4 b/trunk/srclib/pcre/testdata/testoutput4 new file mode 100644 index 0000000000..e8d2603349 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testoutput4 @@ -0,0 +1,903 @@ +PCRE version 5.0 13-Sep-2004 + +/-- Do not use the \x{} construct except with patterns that have the --/ +/-- /8 option set, because PCRE doesn't recognize them as UTF-8 unless --/ +No match +/-- that option is set. However, the latest Perls recognize them always. --/ +No match + +/a.b/8 + acb + 0: acb + a\x7fb + 0: a\x{7f}b + a\x{100}b + 0: a\x{100}b + *** Failers +No match + a\nb +No match + +/a(.{3})b/8 + a\x{4000}xyb + 0: a\x{4000}xyb + 1: \x{4000}xy + a\x{4000}\x7fyb + 0: a\x{4000}\x{7f}yb + 1: \x{4000}\x{7f}y + a\x{4000}\x{100}yb + 0: a\x{4000}\x{100}yb + 1: \x{4000}\x{100}y + *** Failers +No match + a\x{4000}b +No match + ac\ncb +No match + +/a(.*?)(.)/ + a\xc0\x88b + 0: a\xc0 + 1: + 2: \xc0 + +/a(.*?)(.)/8 + a\x{100}b + 0: a\x{100} + 1: + 2: \x{100} + +/a(.*)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: \xc0\x88 + 2: b + +/a(.*)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: \x{100} + 2: b + +/a(.)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: \xc0 + 2: \x92 + +/a(.)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: \x{240} + 2: b + +/a(.?)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: \xc0 + 2: \x92 + +/a(.?)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: \x{240} + 2: b + +/a(.??)(.)/ + a\xc0\x92bcd + 0: a\xc0 + 1: + 2: \xc0 + +/a(.??)(.)/8 + a\x{240}bcd + 0: a\x{240} + 1: + 2: \x{240} + +/a(.{3})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + *** Failers +No match + a\x{1234}b +No match + ac\ncb +No match + +/a(.{3,})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: xxxxbcdefghij + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,5})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + axbxxbcdefghijb + 0: axbxxb + 1: xbxx + axxxxxbcdefghijb + 0: axxxxxb + 1: xxxxx + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/a(.{3,5}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + 1: \x{1234}xy + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + 1: \x{1234}\x{4321}y + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + 1: \x{1234}\x{4321}\x{3412} + axxxxbcdefghijb + 0: axxxxb + 1: xxxx + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + 1: \x{1234}\x{4321}\x{3412}\x{3421} + axbxxbcdefghijb + 0: axbxxb + 1: xbxx + axxxxxbcdefghijb + 0: axxxxxb + 1: xxxxx + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/^[a\x{c0}]/8 + *** Failers +No match + \x{100} +No match + +/(?<=aXb)cd/8 + aXbcd + 0: cd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + 0: cd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + 0: cd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + 0: \x{100}\x{100}\x{100}b + *** Failers +No match + \x{100}\x{100}b +No match + +/\x{ab}/8 + \x{ab} + 0: \x{ab} + \xc2\xab + 0: \x{ab} + *** Failers +No match + \x00{ab} +No match + +/(?<=(.))X/8 + WXYZ + 0: X + 1: W + \x{256}XYZ + 0: X + 1: \x{256} + *** Failers +No match + XYZ +No match + +/X(\C{3})/8 + X\x{1234} + 0: X\x{1234} + 1: \x{1234} + +/X(\C{4})/8 + X\x{1234}YZ + 0: X\x{1234}Y + 1: \x{1234}Y + +/X\C*/8 + XYZabcdce + 0: XYZabcdce + +/X\C*?/8 + XYZabcde + 0: X + +/X\C{3,5}/8 + Xabcdefg + 0: Xabcde + X\x{1234} + 0: X\x{1234} + X\x{1234}YZ + 0: X\x{1234}YZ + X\x{1234}\x{512} + 0: X\x{1234}\x{512} + X\x{1234}\x{512}YZ + 0: X\x{1234}\x{512} + +/X\C{3,5}?/8 + Xabcdefg + 0: Xabc + X\x{1234} + 0: X\x{1234} + X\x{1234}YZ + 0: X\x{1234} + X\x{1234}\x{512} + 0: X\x{1234} + +/[^a]+/8g + bcd + 0: bcd + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8 + \x{100}bcAa + 0: \x{100}bcA + +/^[^a]{2,}?/8 + \x{100}bca + 0: \x{100}b + +/[^a]+/8ig + bcd + 0: bcd + \x{100}aY\x{256}Z + 0: \x{100} + 0: Y\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + 0: \x{100}b + +/^[^a]{2,}/8i + \x{100}bcAa + 0: \x{100}bc + +/^[^a]{2,}?/8i + \x{100}bca + 0: \x{100}b + +/\x{100}{0,0}/8 + abcd + 0: + +/\x{100}?/8 + abcd + 0: + \x{100}\x{100} + 0: \x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + 0: \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + 0: + \x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100} + +/\x{100}{3,5}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100}\x{100}\x{100} + +/\x{100}{3,}/8 + abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX + 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/(?<=a\x{100}{2}b)X/8+ + Xyyya\x{100}\x{100}bXzzz + 0: X + 0+ zzz + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + +/\D/8 + 1X2 + 0: X + 1\x{100}2 + 0: \x{100} + +/>\S/8 + > >X Y + 0: >X + > >\x{100} Y + 0: >\x{100} + +/\d/8 + \x{100}3 + 0: 3 + +/\s/8 + \x{100} X + 0: + +/\D+/8 + 12abcd34 + 0: abcd + *** Failers + 0: *** Failers + 1234 +No match + +/\D{2,3}/8 + 12abcd34 + 0: abc + 12ab34 + 0: ab + *** Failers + 0: *** + 1234 +No match + 12a34 +No match + +/\D{2,3}?/8 + 12abcd34 + 0: ab + 12ab34 + 0: ab + *** Failers + 0: ** + 1234 +No match + 12a34 +No match + +/\d+/8 + 12abcd34 + 0: 12 + *** Failers +No match + +/\d{2,3}/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 123 + *** Failers +No match + 1.4 +No match + +/\d{2,3}?/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 12 + *** Failers +No match + 1.4 +No match + +/\S+/8 + 12abcd34 + 0: 12abcd34 + *** Failers + 0: *** + \ \ +No match + +/\S{2,3}/8 + 12abcd34 + 0: 12a + 1234abcd + 0: 123 + *** Failers + 0: *** + \ \ +No match + +/\S{2,3}?/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 12 + *** Failers + 0: ** + \ \ +No match + +/>\s+ <34 + 0: > < + 0+ 34 + *** Failers +No match + +/>\s{2,3} < + 0+ cd + ab> < + 0+ ce + *** Failers +No match + ab> \s{2,3}? < + 0+ cd + ab> < + 0+ ce + *** Failers +No match + ab> \xff< + 0: \xff + +/[\xff]/8 + >\x{ff}< + 0: \x{ff} + +/[^\xFF]/ + XYZ + 0: X + +/[^\xff]/8 + XYZ + 0: X + \x{123} + 0: \x{123} + +/^[ac]*b/8 + xb +No match + +/^[ac\x{100}]*b/8 + xb +No match + +/^[^x]*b/8i + xb +No match + +/^[^x]*b/8 + xb +No match + +/^\d*b/8 + xb +No match + +/(|a)/g8 + catac + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + a\x{256}a + 0: + 1: + 0: a + 1: a + 0: + 1: + 0: + 1: + 0: a + 1: a + 0: + 1: + +/^\x{85}$/8i + \x{85} + 0: \x{85} + +/ End of testinput4 / diff --git a/trunk/srclib/pcre/testdata/testoutput5 b/trunk/srclib/pcre/testdata/testoutput5 new file mode 100644 index 0000000000..b010957bc5 --- /dev/null +++ b/trunk/srclib/pcre/testdata/testoutput5 @@ -0,0 +1,1075 @@ +PCRE version 5.0 13-Sep-2004 + +/\x{100}/8DM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{100} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 196 +Need char = 128 + +/\x{1000}/8DM +Memory allocation (code space): 11 +------------------------------------------------------------------ + 0 7 Bra 0 + 3 \x{1000} + 7 7 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 225 +Need char = 128 + +/\x{10000}/8DM +Memory allocation (code space): 12 +------------------------------------------------------------------ + 0 8 Bra 0 + 3 \x{10000} + 8 8 Ket + 11 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 240 +Need char = 128 + +/\x{100000}/8DM +Memory allocation (code space): 12 +------------------------------------------------------------------ + 0 8 Bra 0 + 3 \x{100000} + 8 8 Ket + 11 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 244 +Need char = 128 + +/\x{1000000}/8DM +Memory allocation (code space): 13 +------------------------------------------------------------------ + 0 9 Bra 0 + 3 \x{1000000} + 9 9 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 249 +Need char = 128 + +/\x{4000000}/8DM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 10 Bra 0 + 3 \x{4000000} + 10 10 Ket + 13 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 252 +Need char = 128 + +/\x{7fffFFFF}/8DM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 10 Bra 0 + 3 \x{7fffffff} + 10 10 Ket + 13 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 253 +Need char = 191 + +/[\x{ff}]/8DM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{ff} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 195 +Need char = 191 + +/[\x{100}]/8DM +Memory allocation (code space): 47 +------------------------------------------------------------------ + 0 11 Bra 0 + 3 [\x{100}] + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + +/\x{ffffffff}/8 +Failed: character value in \x{...} sequence is too large at offset 11 + +/\x{100000000}/8 +Failed: character value in \x{...} sequence is too large at offset 12 + +/^\x{100}a\x{1234}/8 + \x{100}a\x{1234}bcd + 0: \x{100}a\x{1234} + +/\x80/8D +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{80} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 194 +Need char = 128 + +/\xff/8D +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{ff} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 195 +Need char = 191 + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8 +------------------------------------------------------------------ + 0 14 Bra 0 + 3 A\x{2262}\x{391}. + 14 14 Ket + 17 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 'A' +Need char = '.' + \x{0041}\x{2262}\x{0391}\x{002e} + 0: A\x{2262}\x{391}. + +/\x{D55c}\x{ad6d}\x{C5B4}/D8 +------------------------------------------------------------------ + 0 15 Bra 0 + 3 \x{d55c}\x{ad6d}\x{c5b4} + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 237 +Need char = 180 + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/D8 +------------------------------------------------------------------ + 0 15 Bra 0 + 3 \x{65e5}\x{672c}\x{8a9e} + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 230 +Need char = 158 + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/D8 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{80} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 194 +Need char = 128 + +/\x{084}/D8 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{84} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 194 +Need char = 132 + +/\x{104}/D8 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{104} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 196 +Need char = 132 + +/\x{861}/D8 +------------------------------------------------------------------ + 0 7 Bra 0 + 3 \x{861} + 7 7 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 224 +Need char = 161 + +/\x{212ab}/D8 +------------------------------------------------------------------ + 0 8 Bra 0 + 3 \x{212ab} + 8 8 Ket + 11 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 240 +Need char = 171 + +/.{3,5}X/D8 +------------------------------------------------------------------ + 0 13 Bra 0 + 3 Any{3} + 7 Any{0,2} + 11 X + 13 13 Ket + 16 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +No first char +Need char = 'X' + \x{212ab}\x{212ab}\x{212ab}\x{861}X + 0: \x{212ab}\x{212ab}\x{212ab}\x{861}X + + +/.{3,5}?/D8 +------------------------------------------------------------------ + 0 11 Bra 0 + 3 Any{3} + 7 Any{0,2}? + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +No first char +No need char + \x{212ab}\x{212ab}\x{212ab}\x{861} + 0: \x{212ab}\x{212ab}\x{212ab} + +/-- These tests are here rather than in testinput4 because Perl 5.6 has --/ +/-- some problems with UTF-8 support, in the area of \x{..} where the --/ +No match +/-- value is < 255. It grumbles about invalid UTF-8 strings. --/ +No match + +/^[a\x{c0}]b/8 + \x{c0}b + 0: \x{c0}b + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aa + 1: a\x{c0} + +/^([a\x{c0}]*?)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aa + 1: a\x{c0} + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0}aa + 1: a\x{c0}a\x{c0} + +/^([a\x{c0}]*)aa/8 + a\x{c0}aaaa/ + 0: a\x{c0}aaaa + 1: a\x{c0}aa + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0}aaa + 1: a\x{c0}a\x{c0}a + +/^([a\x{c0}]*)a\x{c0}/8 + a\x{c0}aaaa/ + 0: a\x{c0} + 1: + a\x{c0}a\x{c0}aaa/ + 0: a\x{c0}a\x{c0} + 1: a\x{c0} + +/-- --/ + +/(?<=\C)X/8 +Failed: \C not allowed in lookbehind assertion at offset 6 + +/-- This one is here not because it's different to Perl, but because the --/ +/-- way the captured single-byte is displayed. (In Perl it becomes a --/ +No match +/-- character, and you can't tell the difference.) --/ +No match + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \xe1 + 2: \x88\xb4 + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/^[ab]/8D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [ab] + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored utf8 +No first char +No need char + bar + 0: b + *** Failers +No match + c +No match + \x{ff} +No match + \x{100} +No match + +/^[^ab]/8D +------------------------------------------------------------------ + 0 37 Bra 0 + 3 ^ + 4 [\x00-`c-\xff] (neg) + 37 37 Ket + 40 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: anchored utf8 +No first char +No need char + c + 0: c + \x{ff} + 0: \x{ff} + \x{100} + 0: \x{100} + *** Failers + 0: * + aaa +No match + +/[^ab\xC0-\xF0]/8SD +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x00-`c-\xbf\xf1-\xff] (neg) + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SD +------------------------------------------------------------------ + 0 13 Bra 0 + 3 \x{100}{3} + 8 \x{100}{,1} + 13 13 Ket + 16 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +First char = 196 +Need char = 128 +Study returned NULL + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SD +------------------------------------------------------------------ + 0 17 Bra 0 + 3 6 Bra 1 + 6 \x{100}+ + 9 5 Alt + 12 x + 14 11 Ket + 17 17 Ket + 20 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: utf8 +No first char +No need char +Starting byte set: x \xc4 + +/(\x{100}*a|x)/8SD +------------------------------------------------------------------ + 0 19 Bra 0 + 3 8 Bra 1 + 6 \x{100}* + 9 a + 11 5 Alt + 14 x + 16 13 Ket + 19 19 Ket + 22 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: utf8 +No first char +No need char +Starting byte set: a x \xc4 + +/(\x{100}{0,2}a|x)/8SD +------------------------------------------------------------------ + 0 21 Bra 0 + 3 10 Bra 1 + 6 \x{100}{,2} + 11 a + 13 5 Alt + 16 x + 18 15 Ket + 21 21 Ket + 24 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: utf8 +No first char +No need char +Starting byte set: a x \xc4 + +/(\x{100}{1,2}a|x)/8SD +------------------------------------------------------------------ + 0 24 Bra 0 + 3 13 Bra 1 + 6 \x{100} + 9 \x{100}{,1} + 14 a + 16 5 Alt + 19 x + 21 18 Ket + 24 24 Ket + 27 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Partial matching not supported +Options: utf8 +No first char +No need char +Starting byte set: x \xc4 + +/\x{100}*(\d+|"(?1)")/8 + 1234 + 0: 1234 + 1: 1234 + "1234" + 0: "1234" + 1: "1234" + \x{100}1234 + 0: \x{100}1234 + 1: 1234 + "\x{100}1234" + 0: \x{100}1234 + 1: 1234 + \x{100}\x{100}12ab + 0: \x{100}\x{100}12 + 1: 12 + \x{100}\x{100}"12" + 0: \x{100}\x{100}"12" + 1: "12" + *** Failers +No match + \x{100}\x{100}abcd +No match + +/\x{100}/8D +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{100} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 196 +Need char = 128 + +/\x{100}*/8D +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{100}* + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +No first char +No need char + +/a\x{100}*/8D +------------------------------------------------------------------ + 0 8 Bra 0 + 3 a + 5 \x{100}* + 8 8 Ket + 11 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +First char = 'a' +No need char + +/ab\x{100}*/8D +------------------------------------------------------------------ + 0 10 Bra 0 + 3 ab + 7 \x{100}* + 10 10 Ket + 13 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +First char = 'a' +Need char = 'b' + +/a\x{100}\x{101}*/8D +------------------------------------------------------------------ + 0 11 Bra 0 + 3 a\x{100} + 8 \x{101}* + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +First char = 'a' +Need char = 128 + +/a\x{100}\x{101}+/8D +------------------------------------------------------------------ + 0 11 Bra 0 + 3 a\x{100} + 8 \x{101}+ + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +First char = 'a' +Need char = 129 + +/\x{100}*A/8D +------------------------------------------------------------------ + 0 8 Bra 0 + 3 \x{100}* + 6 A + 8 8 Ket + 11 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +No first char +Need char = 'A' + A + 0: A + +/\x{100}*\d(?R)/8D +------------------------------------------------------------------ + 0 10 Bra 0 + 3 \x{100}* + 6 \d + 7 0 Recurse + 10 10 Ket + 13 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Partial matching not supported +Options: utf8 +No first char +No need char + +/[^\x{c4}]/D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x01-35-bd-z|~-\xff] (neg) + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[^\x{c4}]/8D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x00-\xc3\xc5-\xff] (neg) + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + +/[\x{100}]/8DM +Memory allocation (code space): 47 +------------------------------------------------------------------ + 0 11 Bra 0 + 3 [\x{100}] + 11 11 Ket + 14 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[Z\x{100}]/8DM +Memory allocation (code space): 47 +------------------------------------------------------------------ + 0 43 Bra 0 + 3 [Z\x{100}] + 43 43 Ket + 46 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + Z\x{100} + 0: Z + \x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\x{200}-\x{100}]/8 +Failed: range out of order in character class at offset 15 + +/[Ä€-Ä„]/8 + \x{100} + 0: \x{100} + \x{104} + 0: \x{104} + *** Failers +No match + \x{105} +No match + \x{ff} +No match + +/[z-\x{100}]/8D +------------------------------------------------------------------ + 0 12 Bra 0 + 3 [z-\x{100}] + 12 12 Ket + 15 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + +/[z\Qa-d]Ä€\E]/8D +------------------------------------------------------------------ + 0 43 Bra 0 + 3 [\-\]adz\x{100}] + 43 43 Ket + 46 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + \x{100} + 0: \x{100} + Ä€ + 0: \x{100} + +/[\xFF]/D +------------------------------------------------------------------ + 0 5 Bra 0 + 3 \xff + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +First char = 255 +No need char + >\xff< + 0: \xff + +/[\xff]/D8 +------------------------------------------------------------------ + 0 6 Bra 0 + 3 \x{ff} + 6 6 Ket + 9 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +First char = 195 +Need char = 191 + >\x{ff}< + 0: \x{ff} + +/[^\xFF]/D +------------------------------------------------------------------ + 0 5 Bra 0 + 3 [^\xff] + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[^\xff]/8D +------------------------------------------------------------------ + 0 36 Bra 0 + 3 [\x00-\xfe] (neg) + 36 36 Ket + 39 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 +No first char +No need char + +/[Ä-Ãœ]/8 + Ö # Matches without Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[Ä-Ãœ]/8S + Ö <-- Same with Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[\x{c4}-\x{dc}]/8 + Ö # Matches without Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[\x{c4}-\x{dc}]/8S + Ö <-- Same with Study + 0: \x{d6} + \x{d6} + 0: \x{d6} + +/[Ã]/8 +Failed: invalid UTF-8 string at offset 2 + +/Ã/8 +Failed: invalid UTF-8 string at offset 0 + +/ÃÃÃxxx/8 +Failed: invalid UTF-8 string at offset 1 + +/ÃÃÃxxx/8?D +------------------------------------------------------------------ + 0 15 Bra 0 + 3 \X{c0}\X{c0}\X{c0}xxx + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf8 no_utf8_check +First char = 195 +Need char = 'x' + +/abc/8 + Ã] +Error -10 + à +Error -10 + ÃÃà +Error -10 + ÃÃÃ\? +No match + +/anything/8 + \xc0\x80 +Error -10 + \xc1\x8f +Error -10 + \xe0\x9f\x80 +Error -10 + \xf0\x8f\x80\x80 +Error -10 + \xf8\x87\x80\x80\x80 +Error -10 + \xfc\x83\x80\x80\x80\x80 +Error -10 + \xfe\x80\x80\x80\x80\x80 +Error -10 + \xff\x80\x80\x80\x80\x80 +Error -10 + \xc3\x8f +No match + \xe0\xaf\x80 +No match + \xe1\x80\x80 +No match + \xf0\x9f\x80\x80 +No match + \xf1\x8f\x80\x80 +No match + \xf8\x88\x80\x80\x80 +No match + \xf9\x87\x80\x80\x80 +No match + \xfc\x84\x80\x80\x80\x80 +No match + \xfd\x83\x80\x80\x80\x80 +No match + +/\x{100}abc(xyz(?1))/8D +------------------------------------------------------------------ + 0 27 Bra 0 + 3 \x{100}abc + 12 12 Bra 1 + 15 xyz + 21 12 Recurse + 24 12 Ket + 27 27 Ket + 30 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf8 +First char = 196 +Need char = 'z' + +/[^\x{100}]abc(xyz(?1))/8D +------------------------------------------------------------------ + 0 32 Bra 0 + 3 [^\x{100}] + 11 abc + 17 12 Bra 1 + 20 xyz + 26 17 Recurse + 29 12 Ket + 32 32 Ket + 35 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf8 +No first char +Need char = 'z' + +/[ab\x{100}]abc(xyz(?1))/8D +------------------------------------------------------------------ + 0 64 Bra 0 + 3 [ab\x{100}] + 43 abc + 49 12 Bra 1 + 52 xyz + 58 49 Recurse + 61 12 Ket + 64 64 Ket + 67 End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf8 +No first char +Need char = 'z' + +/(\x{100}(b(?2)c))?/D8 +------------------------------------------------------------------ + 0 26 Bra 0 + 3 Brazero + 4 19 Bra 1 + 7 \x{100} + 10 10 Bra 2 + 13 b + 15 10 Recurse + 18 c + 20 10 Ket + 23 19 Ket + 26 26 Ket + 29 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf8 +No first char +No need char + +/(\x{100}(b(?2)c)){0,2}/D8 +------------------------------------------------------------------ + 0 55 Bra 0 + 3 Brazero + 4 48 Bra 0 + 7 19 Bra 1 + 10 \x{100} + 13 10 Bra 2 + 16 b + 18 13 Recurse + 21 c + 23 10 Ket + 26 19 Ket + 29 Brazero + 30 19 Bra 1 + 33 \x{100} + 36 10 Bra 2 + 39 b + 41 13 Recurse + 44 c + 46 10 Ket + 49 19 Ket + 52 48 Ket + 55 55 Ket + 58 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf8 +No first char +No need char + +/(\x{100}(b(?1)c))?/D8 +------------------------------------------------------------------ + 0 26 Bra 0 + 3 Brazero + 4 19 Bra 1 + 7 \x{100} + 10 10 Bra 2 + 13 b + 15 4 Recurse + 18 c + 20 10 Ket + 23 19 Ket + 26 26 Ket + 29 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf8 +No first char +No need char + +/(\x{100}(b(?1)c)){0,2}/D8 +------------------------------------------------------------------ + 0 55 Bra 0 + 3 Brazero + 4 48 Bra 0 + 7 19 Bra 1 + 10 \x{100} + 13 10 Bra 2 + 16 b + 18 7 Recurse + 21 c + 23 10 Ket + 26 19 Ket + 29 Brazero + 30 19 Bra 1 + 33 \x{100} + 36 10 Bra 2 + 39 b + 41 7 Recurse + 44 c + 46 10 Ket + 49 19 Ket + 52 48 Ket + 55 55 Ket + 58 End +------------------------------------------------------------------ +Capturing subpattern count = 2 +Options: utf8 +No first char +No need char + +/\W/8 + A.B + 0: . + A\x{100}B + 0: \x{100} + +/\w/8 + \x{100}X + 0: X + +/ End of testinput5 / diff --git a/trunk/srclib/pcre/testdata/testoutput6 b/trunk/srclib/pcre/testdata/testoutput6 new file mode 100644 index 0000000000..732e5aa01f --- /dev/null +++ b/trunk/srclib/pcre/testdata/testoutput6 @@ -0,0 +1,1013 @@ +PCRE version 5.0 13-Sep-2004 + +/^\pC\pL\pM\pN\pP\pS\pZf1 | ((node->f0 & f0_chhmask) << 16); + if (cc == d) break; + if (cc < d) + { + if ((node->f0 & f0_leftexists) == 0) return -1; + node ++; + } + else + { + register int roffset = (node->f2 & f2_rightmask) >> f2_rightshift; + if (roffset == 0) return -1; + node += 1 << (roffset - 1); + } + } + +switch ((*type_ptr = ((node->f0 & f0_typemask) >> f0_typeshift))) + { + case ucp_Cc: + case ucp_Cf: + case ucp_Cn: + case ucp_Co: + case ucp_Cs: + return ucp_C; + break; + + case ucp_Ll: + case ucp_Lu: + case_offset = node->f2 & f2_casemask; + if ((case_offset & 0x0100) != 0) case_offset |= 0xfffff000; + *case_ptr = (case_offset == 0)? 0 : cc + case_offset; + return ucp_L; + + case ucp_Lm: + case ucp_Lo: + case ucp_Lt: + *case_ptr = 0; + return ucp_L; + break; + + case ucp_Mc: + case ucp_Me: + case ucp_Mn: + return ucp_M; + break; + + case ucp_Nd: + case ucp_Nl: + case ucp_No: + return ucp_N; + break; + + case ucp_Pc: + case ucp_Pd: + case ucp_Pe: + case ucp_Pf: + case ucp_Pi: + case ucp_Ps: + case ucp_Po: + return ucp_P; + break; + + case ucp_Sc: + case ucp_Sk: + case ucp_Sm: + case ucp_So: + return ucp_S; + break; + + case ucp_Zl: + case ucp_Zp: + case ucp_Zs: + return ucp_Z; + break; + + default: /* "Should never happen" */ + return -1; + break; + } +} + +/* End of ucp.c */ diff --git a/trunk/srclib/pcre/ucp.h b/trunk/srclib/pcre/ucp.h new file mode 100644 index 0000000000..c013978e23 --- /dev/null +++ b/trunk/srclib/pcre/ucp.h @@ -0,0 +1,58 @@ +/************************************************* +* libucp - Unicode Property Table handler * +*************************************************/ + +/* These are the character categories that are returned by ucp_findchar */ + +enum { + ucp_C, /* Other */ + ucp_L, /* Letter */ + ucp_M, /* Mark */ + ucp_N, /* Number */ + ucp_P, /* Punctuation */ + ucp_S, /* Symbol */ + ucp_Z /* Separator */ +}; + +/* These are the detailed character types that are returned by ucp_findchar */ + +enum { + ucp_Cc, /* Control */ + ucp_Cf, /* Format */ + ucp_Cn, /* Unassigned */ + ucp_Co, /* Private use */ + ucp_Cs, /* Surrogate */ + ucp_Ll, /* Lower case letter */ + ucp_Lm, /* Modifier letter */ + ucp_Lo, /* Other letter */ + ucp_Lt, /* Title case letter */ + ucp_Lu, /* Upper case letter */ + ucp_Mc, /* Spacing mark */ + ucp_Me, /* Enclosing mark */ + ucp_Mn, /* Non-spacing mark */ + ucp_Nd, /* Decimal number */ + ucp_Nl, /* Letter number */ + ucp_No, /* Other number */ + ucp_Pc, /* Connector punctuation */ + ucp_Pd, /* Dash punctuation */ + ucp_Pe, /* Close punctuation */ + ucp_Pf, /* Final punctuation */ + ucp_Pi, /* Initial punctuation */ + ucp_Po, /* Other punctuation */ + ucp_Ps, /* Open punctuation */ + ucp_Sc, /* Currency symbol */ + ucp_Sk, /* Modifier symbol */ + ucp_Sm, /* Mathematical symbol */ + ucp_So, /* Other symbol */ + ucp_Zl, /* Line separator */ + ucp_Zp, /* Paragraph separator */ + ucp_Zs /* Space separator */ +}; + +/* For use in PCRE we make this function static so that there is no conflict if +PCRE is linked with an application that makes use of an external version - +assuming an external version is ever released... */ + +static int ucp_findchar(const int, int *, int *); + +/* End of ucp.h */ diff --git a/trunk/srclib/pcre/ucpinternal.h b/trunk/srclib/pcre/ucpinternal.h new file mode 100644 index 0000000000..faefb030c9 --- /dev/null +++ b/trunk/srclib/pcre/ucpinternal.h @@ -0,0 +1,91 @@ +/************************************************* +* libucp - Unicode Property Table handler * +*************************************************/ + +/* Internal header file defining the layout of compact nodes in the tree. */ + +typedef struct cnode { + unsigned short int f0; + unsigned short int f1; + unsigned short int f2; +} cnode; + +/* Things for the f0 field */ + +#define f0_leftexists 0x8000 /* Left child exists */ +#define f0_typemask 0x3f00 /* Type bits */ +#define f0_typeshift 8 /* Type shift */ +#define f0_chhmask 0x00ff /* Character high bits */ + +/* Things for the f2 field */ + +#define f2_rightmask 0xf000 /* Mask for right offset bits */ +#define f2_rightshift 12 /* Shift for right offset */ +#define f2_casemask 0x0fff /* Mask for case offset */ + +/* The tree consists of a vector of structures of type cnode, with the root +node as the first element. The three short ints (16-bits) are used as follows: + +(f0) (1) The 0x8000 bit of f0 is set if a left child exists. The child's node + is the next node in the vector. + (2) The 0x4000 bits of f0 is spare. + (3) The 0x3f00 bits of f0 contain the character type; this is a number + defined by the enumeration in ucp.h (e.g. ucp_Lu). + (4) The bottom 8 bits of f0 contain the most significant byte of the + character's 24-bit codepoint. + +(f1) (1) The f1 field contains the two least significant bytes of the + codepoint. + +(f2) (1) The 0xf000 bits of f2 contain zero if there is no right child of this + node. Otherwise, they contain one plus the exponent of the power of + two of the offset to the right node (e.g. a value of 3 means 8). The + units of the offset are node items. + + (2) The 0x0fff bits of f2 contain the signed offset from this character to + its alternate cased value. They are zero if there is no such + character. + + +----------------------------------------------------------------------------- +||.|.| type (6) | ms char (8) || ls char (16) ||....| case offset (12) || +----------------------------------------------------------------------------- + | | | + | |-> spare | + | exponent of right + |-> left child exists child offset + + +The upper/lower casing information is set only for characters that come in +pairs. There are (at present) four non-one-to-one mappings in the Unicode data. +These are ignored. They are: + + 1FBE Greek Prosgegrammeni (lower, with upper -> capital iota) + 2126 Ohm + 212A Kelvin + 212B Angstrom + +Certainly for the last three, having an alternate case would seem to be a +mistake. I don't know any Greek, so cannot comment on the first one. + + +When searching the tree, proceed as follows: + +(1) Start at the first node. + +(2) Extract the character value from f1 and the bottom 8 bits of f0; + +(3) Compare with the character being sought. If equal, we are done. + +(4) If the test character is smaller, inspect the f0_leftexists flag. If it is + not set, the character is not in the tree. If it is set, move to the next + node, and go to (2). + +(5) If the test character is bigger, extract the f2_rightmask bits from f2, and + shift them right by f2_rightshift. If the result is zero, the character is + not in the tree. Otherwise, calculate the number of nodes to skip by + shifting the value 1 left by this number minus one. Go to (2). +*/ + + +/* End of internal.h */ diff --git a/trunk/srclib/pcre/ucptable.c b/trunk/srclib/pcre/ucptable.c new file mode 100644 index 0000000000..7fb3a12343 --- /dev/null +++ b/trunk/srclib/pcre/ucptable.c @@ -0,0 +1,15105 @@ +/* This source module is automatically generated from the Unicode +property table. See internal.h for a description of the layout. */ + +static cnode ucp_table[] = { + { 0x9a00, 0x2f1f, 0xe000 }, + { 0x8700, 0x1558, 0xd000 }, + { 0x8700, 0x0a99, 0xc000 }, + { 0x8500, 0x0435, 0xbfe0 }, + { 0x8500, 0x01ff, 0xafff }, + { 0x8500, 0x00ff, 0x9079 }, + { 0x8000, 0x007f, 0x8000 }, + { 0x9500, 0x003f, 0x7000 }, + { 0x8000, 0x001f, 0x6000 }, + { 0x8000, 0x000f, 0x5000 }, + { 0x8000, 0x0007, 0x4000 }, + { 0x8000, 0x0003, 0x3000 }, + { 0x8000, 0x0001, 0x2000 }, + { 0x0000, 0x0000, 0x0000 }, + { 0x0000, 0x0002, 0x0000 }, + { 0x8000, 0x0005, 0x2000 }, + { 0x0000, 0x0004, 0x0000 }, + { 0x0000, 0x0006, 0x0000 }, + { 0x8000, 0x000b, 0x3000 }, + { 0x8000, 0x0009, 0x2000 }, + { 0x0000, 0x0008, 0x0000 }, + { 0x0000, 0x000a, 0x0000 }, + { 0x8000, 0x000d, 0x2000 }, + { 0x0000, 0x000c, 0x0000 }, + { 0x0000, 0x000e, 0x0000 }, + { 0x8000, 0x0017, 0x4000 }, + { 0x8000, 0x0013, 0x3000 }, + { 0x8000, 0x0011, 0x2000 }, + { 0x0000, 0x0010, 0x0000 }, + { 0x0000, 0x0012, 0x0000 }, + { 0x8000, 0x0015, 0x2000 }, + { 0x0000, 0x0014, 0x0000 }, + { 0x0000, 0x0016, 0x0000 }, + { 0x8000, 0x001b, 0x3000 }, + { 0x8000, 0x0019, 0x2000 }, + { 0x0000, 0x0018, 0x0000 }, + { 0x0000, 0x001a, 0x0000 }, + { 0x8000, 0x001d, 0x2000 }, + { 0x0000, 0x001c, 0x0000 }, + { 0x0000, 0x001e, 0x0000 }, + { 0x9500, 0x002f, 0x5000 }, + { 0x9500, 0x0027, 0x4000 }, + { 0x9500, 0x0023, 0x3000 }, + { 0x9500, 0x0021, 0x2000 }, + { 0x1d00, 0x0020, 0x0000 }, + { 0x1500, 0x0022, 0x0000 }, + { 0x9500, 0x0025, 0x2000 }, + { 0x1700, 0x0024, 0x0000 }, + { 0x1500, 0x0026, 0x0000 }, + { 0x9900, 0x002b, 0x3000 }, + { 0x9200, 0x0029, 0x2000 }, + { 0x1600, 0x0028, 0x0000 }, + { 0x1500, 0x002a, 0x0000 }, + { 0x9100, 0x002d, 0x2000 }, + { 0x1500, 0x002c, 0x0000 }, + { 0x1500, 0x002e, 0x0000 }, + { 0x8d00, 0x0037, 0x4000 }, + { 0x8d00, 0x0033, 0x3000 }, + { 0x8d00, 0x0031, 0x2000 }, + { 0x0d00, 0x0030, 0x0000 }, + { 0x0d00, 0x0032, 0x0000 }, + { 0x8d00, 0x0035, 0x2000 }, + { 0x0d00, 0x0034, 0x0000 }, + { 0x0d00, 0x0036, 0x0000 }, + { 0x9500, 0x003b, 0x3000 }, + { 0x8d00, 0x0039, 0x2000 }, + { 0x0d00, 0x0038, 0x0000 }, + { 0x1500, 0x003a, 0x0000 }, + { 0x9900, 0x003d, 0x2000 }, + { 0x1900, 0x003c, 0x0000 }, + { 0x1900, 0x003e, 0x0000 }, + { 0x9000, 0x005f, 0x6000 }, + { 0x8900, 0x004f, 0x5020 }, + { 0x8900, 0x0047, 0x4020 }, + { 0x8900, 0x0043, 0x3020 }, + { 0x8900, 0x0041, 0x2020 }, + { 0x1500, 0x0040, 0x0000 }, + { 0x0900, 0x0042, 0x0020 }, + { 0x8900, 0x0045, 0x2020 }, + { 0x0900, 0x0044, 0x0020 }, + { 0x0900, 0x0046, 0x0020 }, + { 0x8900, 0x004b, 0x3020 }, + { 0x8900, 0x0049, 0x2020 }, + { 0x0900, 0x0048, 0x0020 }, + { 0x0900, 0x004a, 0x0020 }, + { 0x8900, 0x004d, 0x2020 }, + { 0x0900, 0x004c, 0x0020 }, + { 0x0900, 0x004e, 0x0020 }, + { 0x8900, 0x0057, 0x4020 }, + { 0x8900, 0x0053, 0x3020 }, + { 0x8900, 0x0051, 0x2020 }, + { 0x0900, 0x0050, 0x0020 }, + { 0x0900, 0x0052, 0x0020 }, + { 0x8900, 0x0055, 0x2020 }, + { 0x0900, 0x0054, 0x0020 }, + { 0x0900, 0x0056, 0x0020 }, + { 0x9600, 0x005b, 0x3000 }, + { 0x8900, 0x0059, 0x2020 }, + { 0x0900, 0x0058, 0x0020 }, + { 0x0900, 0x005a, 0x0020 }, + { 0x9200, 0x005d, 0x2000 }, + { 0x1500, 0x005c, 0x0000 }, + { 0x1800, 0x005e, 0x0000 }, + { 0x8500, 0x006f, 0x5fe0 }, + { 0x8500, 0x0067, 0x4fe0 }, + { 0x8500, 0x0063, 0x3fe0 }, + { 0x8500, 0x0061, 0x2fe0 }, + { 0x1800, 0x0060, 0x0000 }, + { 0x0500, 0x0062, 0x0fe0 }, + { 0x8500, 0x0065, 0x2fe0 }, + { 0x0500, 0x0064, 0x0fe0 }, + { 0x0500, 0x0066, 0x0fe0 }, + { 0x8500, 0x006b, 0x3fe0 }, + { 0x8500, 0x0069, 0x2fe0 }, + { 0x0500, 0x0068, 0x0fe0 }, + { 0x0500, 0x006a, 0x0fe0 }, + { 0x8500, 0x006d, 0x2fe0 }, + { 0x0500, 0x006c, 0x0fe0 }, + { 0x0500, 0x006e, 0x0fe0 }, + { 0x8500, 0x0077, 0x4fe0 }, + { 0x8500, 0x0073, 0x3fe0 }, + { 0x8500, 0x0071, 0x2fe0 }, + { 0x0500, 0x0070, 0x0fe0 }, + { 0x0500, 0x0072, 0x0fe0 }, + { 0x8500, 0x0075, 0x2fe0 }, + { 0x0500, 0x0074, 0x0fe0 }, + { 0x0500, 0x0076, 0x0fe0 }, + { 0x9600, 0x007b, 0x3000 }, + { 0x8500, 0x0079, 0x2fe0 }, + { 0x0500, 0x0078, 0x0fe0 }, + { 0x0500, 0x007a, 0x0fe0 }, + { 0x9200, 0x007d, 0x2000 }, + { 0x1900, 0x007c, 0x0000 }, + { 0x1900, 0x007e, 0x0000 }, + { 0x9500, 0x00bf, 0x7000 }, + { 0x8000, 0x009f, 0x6000 }, + { 0x8000, 0x008f, 0x5000 }, + { 0x8000, 0x0087, 0x4000 }, + { 0x8000, 0x0083, 0x3000 }, + { 0x8000, 0x0081, 0x2000 }, + { 0x0000, 0x0080, 0x0000 }, + { 0x0000, 0x0082, 0x0000 }, + { 0x8000, 0x0085, 0x2000 }, + { 0x0000, 0x0084, 0x0000 }, + { 0x0000, 0x0086, 0x0000 }, + { 0x8000, 0x008b, 0x3000 }, + { 0x8000, 0x0089, 0x2000 }, + { 0x0000, 0x0088, 0x0000 }, + { 0x0000, 0x008a, 0x0000 }, + { 0x8000, 0x008d, 0x2000 }, + { 0x0000, 0x008c, 0x0000 }, + { 0x0000, 0x008e, 0x0000 }, + { 0x8000, 0x0097, 0x4000 }, + { 0x8000, 0x0093, 0x3000 }, + { 0x8000, 0x0091, 0x2000 }, + { 0x0000, 0x0090, 0x0000 }, + { 0x0000, 0x0092, 0x0000 }, + { 0x8000, 0x0095, 0x2000 }, + { 0x0000, 0x0094, 0x0000 }, + { 0x0000, 0x0096, 0x0000 }, + { 0x8000, 0x009b, 0x3000 }, + { 0x8000, 0x0099, 0x2000 }, + { 0x0000, 0x0098, 0x0000 }, + { 0x0000, 0x009a, 0x0000 }, + { 0x8000, 0x009d, 0x2000 }, + { 0x0000, 0x009c, 0x0000 }, + { 0x0000, 0x009e, 0x0000 }, + { 0x9800, 0x00af, 0x5000 }, + { 0x9a00, 0x00a7, 0x4000 }, + { 0x9700, 0x00a3, 0x3000 }, + { 0x9500, 0x00a1, 0x2000 }, + { 0x1d00, 0x00a0, 0x0000 }, + { 0x1700, 0x00a2, 0x0000 }, + { 0x9700, 0x00a5, 0x2000 }, + { 0x1700, 0x00a4, 0x0000 }, + { 0x1a00, 0x00a6, 0x0000 }, + { 0x9400, 0x00ab, 0x3000 }, + { 0x9a00, 0x00a9, 0x2000 }, + { 0x1800, 0x00a8, 0x0000 }, + { 0x0500, 0x00aa, 0x0000 }, + { 0x8100, 0x00ad, 0x2000 }, + { 0x1900, 0x00ac, 0x0000 }, + { 0x1a00, 0x00ae, 0x0000 }, + { 0x9500, 0x00b7, 0x4000 }, + { 0x8f00, 0x00b3, 0x3000 }, + { 0x9900, 0x00b1, 0x2000 }, + { 0x1a00, 0x00b0, 0x0000 }, + { 0x0f00, 0x00b2, 0x0000 }, + { 0x8500, 0x00b5, 0x22e7 }, + { 0x1800, 0x00b4, 0x0000 }, + { 0x1a00, 0x00b6, 0x0000 }, + { 0x9300, 0x00bb, 0x3000 }, + { 0x8f00, 0x00b9, 0x2000 }, + { 0x1800, 0x00b8, 0x0000 }, + { 0x0500, 0x00ba, 0x0000 }, + { 0x8f00, 0x00bd, 0x2000 }, + { 0x0f00, 0x00bc, 0x0000 }, + { 0x0f00, 0x00be, 0x0000 }, + { 0x8500, 0x00df, 0x6000 }, + { 0x8900, 0x00cf, 0x5020 }, + { 0x8900, 0x00c7, 0x4020 }, + { 0x8900, 0x00c3, 0x3020 }, + { 0x8900, 0x00c1, 0x2020 }, + { 0x0900, 0x00c0, 0x0020 }, + { 0x0900, 0x00c2, 0x0020 }, + { 0x8900, 0x00c5, 0x2020 }, + { 0x0900, 0x00c4, 0x0020 }, + { 0x0900, 0x00c6, 0x0020 }, + { 0x8900, 0x00cb, 0x3020 }, + { 0x8900, 0x00c9, 0x2020 }, + { 0x0900, 0x00c8, 0x0020 }, + { 0x0900, 0x00ca, 0x0020 }, + { 0x8900, 0x00cd, 0x2020 }, + { 0x0900, 0x00cc, 0x0020 }, + { 0x0900, 0x00ce, 0x0020 }, + { 0x9900, 0x00d7, 0x4000 }, + { 0x8900, 0x00d3, 0x3020 }, + { 0x8900, 0x00d1, 0x2020 }, + { 0x0900, 0x00d0, 0x0020 }, + { 0x0900, 0x00d2, 0x0020 }, + { 0x8900, 0x00d5, 0x2020 }, + { 0x0900, 0x00d4, 0x0020 }, + { 0x0900, 0x00d6, 0x0020 }, + { 0x8900, 0x00db, 0x3020 }, + { 0x8900, 0x00d9, 0x2020 }, + { 0x0900, 0x00d8, 0x0020 }, + { 0x0900, 0x00da, 0x0020 }, + { 0x8900, 0x00dd, 0x2020 }, + { 0x0900, 0x00dc, 0x0020 }, + { 0x0900, 0x00de, 0x0020 }, + { 0x8500, 0x00ef, 0x5fe0 }, + { 0x8500, 0x00e7, 0x4fe0 }, + { 0x8500, 0x00e3, 0x3fe0 }, + { 0x8500, 0x00e1, 0x2fe0 }, + { 0x0500, 0x00e0, 0x0fe0 }, + { 0x0500, 0x00e2, 0x0fe0 }, + { 0x8500, 0x00e5, 0x2fe0 }, + { 0x0500, 0x00e4, 0x0fe0 }, + { 0x0500, 0x00e6, 0x0fe0 }, + { 0x8500, 0x00eb, 0x3fe0 }, + { 0x8500, 0x00e9, 0x2fe0 }, + { 0x0500, 0x00e8, 0x0fe0 }, + { 0x0500, 0x00ea, 0x0fe0 }, + { 0x8500, 0x00ed, 0x2fe0 }, + { 0x0500, 0x00ec, 0x0fe0 }, + { 0x0500, 0x00ee, 0x0fe0 }, + { 0x9900, 0x00f7, 0x4000 }, + { 0x8500, 0x00f3, 0x3fe0 }, + { 0x8500, 0x00f1, 0x2fe0 }, + { 0x0500, 0x00f0, 0x0fe0 }, + { 0x0500, 0x00f2, 0x0fe0 }, + { 0x8500, 0x00f5, 0x2fe0 }, + { 0x0500, 0x00f4, 0x0fe0 }, + { 0x0500, 0x00f6, 0x0fe0 }, + { 0x8500, 0x00fb, 0x3fe0 }, + { 0x8500, 0x00f9, 0x2fe0 }, + { 0x0500, 0x00f8, 0x0fe0 }, + { 0x0500, 0x00fa, 0x0fe0 }, + { 0x8500, 0x00fd, 0x2fe0 }, + { 0x0500, 0x00fc, 0x0fe0 }, + { 0x0500, 0x00fe, 0x0fe0 }, + { 0x8500, 0x017f, 0x8ed4 }, + { 0x8900, 0x013f, 0x7001 }, + { 0x8500, 0x011f, 0x6fff }, + { 0x8500, 0x010f, 0x5fff }, + { 0x8500, 0x0107, 0x4fff }, + { 0x8500, 0x0103, 0x3fff }, + { 0x8500, 0x0101, 0x2fff }, + { 0x0900, 0x0100, 0x0001 }, + { 0x0900, 0x0102, 0x0001 }, + { 0x8500, 0x0105, 0x2fff }, + { 0x0900, 0x0104, 0x0001 }, + { 0x0900, 0x0106, 0x0001 }, + { 0x8500, 0x010b, 0x3fff }, + { 0x8500, 0x0109, 0x2fff }, + { 0x0900, 0x0108, 0x0001 }, + { 0x0900, 0x010a, 0x0001 }, + { 0x8500, 0x010d, 0x2fff }, + { 0x0900, 0x010c, 0x0001 }, + { 0x0900, 0x010e, 0x0001 }, + { 0x8500, 0x0117, 0x4fff }, + { 0x8500, 0x0113, 0x3fff }, + { 0x8500, 0x0111, 0x2fff }, + { 0x0900, 0x0110, 0x0001 }, + { 0x0900, 0x0112, 0x0001 }, + { 0x8500, 0x0115, 0x2fff }, + { 0x0900, 0x0114, 0x0001 }, + { 0x0900, 0x0116, 0x0001 }, + { 0x8500, 0x011b, 0x3fff }, + { 0x8500, 0x0119, 0x2fff }, + { 0x0900, 0x0118, 0x0001 }, + { 0x0900, 0x011a, 0x0001 }, + { 0x8500, 0x011d, 0x2fff }, + { 0x0900, 0x011c, 0x0001 }, + { 0x0900, 0x011e, 0x0001 }, + { 0x8500, 0x012f, 0x5fff }, + { 0x8500, 0x0127, 0x4fff }, + { 0x8500, 0x0123, 0x3fff }, + { 0x8500, 0x0121, 0x2fff }, + { 0x0900, 0x0120, 0x0001 }, + { 0x0900, 0x0122, 0x0001 }, + { 0x8500, 0x0125, 0x2fff }, + { 0x0900, 0x0124, 0x0001 }, + { 0x0900, 0x0126, 0x0001 }, + { 0x8500, 0x012b, 0x3fff }, + { 0x8500, 0x0129, 0x2fff }, + { 0x0900, 0x0128, 0x0001 }, + { 0x0900, 0x012a, 0x0001 }, + { 0x8500, 0x012d, 0x2fff }, + { 0x0900, 0x012c, 0x0001 }, + { 0x0900, 0x012e, 0x0001 }, + { 0x8500, 0x0137, 0x4fff }, + { 0x8500, 0x0133, 0x3fff }, + { 0x8500, 0x0131, 0x2f18 }, + { 0x0900, 0x0130, 0x0f39 }, + { 0x0900, 0x0132, 0x0001 }, + { 0x8500, 0x0135, 0x2fff }, + { 0x0900, 0x0134, 0x0001 }, + { 0x0900, 0x0136, 0x0001 }, + { 0x8900, 0x013b, 0x3001 }, + { 0x8900, 0x0139, 0x2001 }, + { 0x0500, 0x0138, 0x0000 }, + { 0x0500, 0x013a, 0x0fff }, + { 0x8900, 0x013d, 0x2001 }, + { 0x0500, 0x013c, 0x0fff }, + { 0x0500, 0x013e, 0x0fff }, + { 0x8500, 0x015f, 0x6fff }, + { 0x8500, 0x014f, 0x5fff }, + { 0x8900, 0x0147, 0x4001 }, + { 0x8900, 0x0143, 0x3001 }, + { 0x8900, 0x0141, 0x2001 }, + { 0x0500, 0x0140, 0x0fff }, + { 0x0500, 0x0142, 0x0fff }, + { 0x8900, 0x0145, 0x2001 }, + { 0x0500, 0x0144, 0x0fff }, + { 0x0500, 0x0146, 0x0fff }, + { 0x8500, 0x014b, 0x3fff }, + { 0x8500, 0x0149, 0x2000 }, + { 0x0500, 0x0148, 0x0fff }, + { 0x0900, 0x014a, 0x0001 }, + { 0x8500, 0x014d, 0x2fff }, + { 0x0900, 0x014c, 0x0001 }, + { 0x0900, 0x014e, 0x0001 }, + { 0x8500, 0x0157, 0x4fff }, + { 0x8500, 0x0153, 0x3fff }, + { 0x8500, 0x0151, 0x2fff }, + { 0x0900, 0x0150, 0x0001 }, + { 0x0900, 0x0152, 0x0001 }, + { 0x8500, 0x0155, 0x2fff }, + { 0x0900, 0x0154, 0x0001 }, + { 0x0900, 0x0156, 0x0001 }, + { 0x8500, 0x015b, 0x3fff }, + { 0x8500, 0x0159, 0x2fff }, + { 0x0900, 0x0158, 0x0001 }, + { 0x0900, 0x015a, 0x0001 }, + { 0x8500, 0x015d, 0x2fff }, + { 0x0900, 0x015c, 0x0001 }, + { 0x0900, 0x015e, 0x0001 }, + { 0x8500, 0x016f, 0x5fff }, + { 0x8500, 0x0167, 0x4fff }, + { 0x8500, 0x0163, 0x3fff }, + { 0x8500, 0x0161, 0x2fff }, + { 0x0900, 0x0160, 0x0001 }, + { 0x0900, 0x0162, 0x0001 }, + { 0x8500, 0x0165, 0x2fff }, + { 0x0900, 0x0164, 0x0001 }, + { 0x0900, 0x0166, 0x0001 }, + { 0x8500, 0x016b, 0x3fff }, + { 0x8500, 0x0169, 0x2fff }, + { 0x0900, 0x0168, 0x0001 }, + { 0x0900, 0x016a, 0x0001 }, + { 0x8500, 0x016d, 0x2fff }, + { 0x0900, 0x016c, 0x0001 }, + { 0x0900, 0x016e, 0x0001 }, + { 0x8500, 0x0177, 0x4fff }, + { 0x8500, 0x0173, 0x3fff }, + { 0x8500, 0x0171, 0x2fff }, + { 0x0900, 0x0170, 0x0001 }, + { 0x0900, 0x0172, 0x0001 }, + { 0x8500, 0x0175, 0x2fff }, + { 0x0900, 0x0174, 0x0001 }, + { 0x0900, 0x0176, 0x0001 }, + { 0x8900, 0x017b, 0x3001 }, + { 0x8900, 0x0179, 0x2001 }, + { 0x0900, 0x0178, 0x0f87 }, + { 0x0500, 0x017a, 0x0fff }, + { 0x8900, 0x017d, 0x2001 }, + { 0x0500, 0x017c, 0x0fff }, + { 0x0500, 0x017e, 0x0fff }, + { 0x8500, 0x01bf, 0x7038 }, + { 0x8900, 0x019f, 0x60d6 }, + { 0x8900, 0x018f, 0x50ca }, + { 0x8900, 0x0187, 0x4001 }, + { 0x8500, 0x0183, 0x3fff }, + { 0x8900, 0x0181, 0x20d2 }, + { 0x0500, 0x0180, 0x0000 }, + { 0x0900, 0x0182, 0x0001 }, + { 0x8500, 0x0185, 0x2fff }, + { 0x0900, 0x0184, 0x0001 }, + { 0x0900, 0x0186, 0x00ce }, + { 0x8900, 0x018b, 0x3001 }, + { 0x8900, 0x0189, 0x20cd }, + { 0x0500, 0x0188, 0x0fff }, + { 0x0900, 0x018a, 0x00cd }, + { 0x8500, 0x018d, 0x2000 }, + { 0x0500, 0x018c, 0x0fff }, + { 0x0900, 0x018e, 0x004f }, + { 0x8900, 0x0197, 0x40d1 }, + { 0x8900, 0x0193, 0x30cd }, + { 0x8900, 0x0191, 0x2001 }, + { 0x0900, 0x0190, 0x00cb }, + { 0x0500, 0x0192, 0x0fff }, + { 0x8500, 0x0195, 0x2061 }, + { 0x0900, 0x0194, 0x00cf }, + { 0x0900, 0x0196, 0x00d3 }, + { 0x8500, 0x019b, 0x3000 }, + { 0x8500, 0x0199, 0x2fff }, + { 0x0900, 0x0198, 0x0001 }, + { 0x0500, 0x019a, 0x0000 }, + { 0x8900, 0x019d, 0x20d5 }, + { 0x0900, 0x019c, 0x00d3 }, + { 0x0500, 0x019e, 0x0082 }, + { 0x8900, 0x01af, 0x5001 }, + { 0x8900, 0x01a7, 0x4001 }, + { 0x8500, 0x01a3, 0x3fff }, + { 0x8500, 0x01a1, 0x2fff }, + { 0x0900, 0x01a0, 0x0001 }, + { 0x0900, 0x01a2, 0x0001 }, + { 0x8500, 0x01a5, 0x2fff }, + { 0x0900, 0x01a4, 0x0001 }, + { 0x0900, 0x01a6, 0x00da }, + { 0x8500, 0x01ab, 0x3000 }, + { 0x8900, 0x01a9, 0x20da }, + { 0x0500, 0x01a8, 0x0fff }, + { 0x0500, 0x01aa, 0x0000 }, + { 0x8500, 0x01ad, 0x2fff }, + { 0x0900, 0x01ac, 0x0001 }, + { 0x0900, 0x01ae, 0x00da }, + { 0x8900, 0x01b7, 0x40db }, + { 0x8900, 0x01b3, 0x3001 }, + { 0x8900, 0x01b1, 0x20d9 }, + { 0x0500, 0x01b0, 0x0fff }, + { 0x0900, 0x01b2, 0x00d9 }, + { 0x8900, 0x01b5, 0x2001 }, + { 0x0500, 0x01b4, 0x0fff }, + { 0x0500, 0x01b6, 0x0fff }, + { 0x8700, 0x01bb, 0x3000 }, + { 0x8500, 0x01b9, 0x2fff }, + { 0x0900, 0x01b8, 0x0001 }, + { 0x0500, 0x01ba, 0x0000 }, + { 0x8500, 0x01bd, 0x2fff }, + { 0x0900, 0x01bc, 0x0001 }, + { 0x0500, 0x01be, 0x0000 }, + { 0x8500, 0x01df, 0x6fff }, + { 0x8900, 0x01cf, 0x5001 }, + { 0x8900, 0x01c7, 0x4002 }, + { 0x8700, 0x01c3, 0x3000 }, + { 0x8700, 0x01c1, 0x2000 }, + { 0x0700, 0x01c0, 0x0000 }, + { 0x0700, 0x01c2, 0x0000 }, + { 0x8800, 0x01c5, 0x2000 }, + { 0x0900, 0x01c4, 0x0002 }, + { 0x0500, 0x01c6, 0x0ffe }, + { 0x8800, 0x01cb, 0x3000 }, + { 0x8500, 0x01c9, 0x2ffe }, + { 0x0800, 0x01c8, 0x0000 }, + { 0x0900, 0x01ca, 0x0002 }, + { 0x8900, 0x01cd, 0x2001 }, + { 0x0500, 0x01cc, 0x0ffe }, + { 0x0500, 0x01ce, 0x0fff }, + { 0x8900, 0x01d7, 0x4001 }, + { 0x8900, 0x01d3, 0x3001 }, + { 0x8900, 0x01d1, 0x2001 }, + { 0x0500, 0x01d0, 0x0fff }, + { 0x0500, 0x01d2, 0x0fff }, + { 0x8900, 0x01d5, 0x2001 }, + { 0x0500, 0x01d4, 0x0fff }, + { 0x0500, 0x01d6, 0x0fff }, + { 0x8900, 0x01db, 0x3001 }, + { 0x8900, 0x01d9, 0x2001 }, + { 0x0500, 0x01d8, 0x0fff }, + { 0x0500, 0x01da, 0x0fff }, + { 0x8500, 0x01dd, 0x2fb1 }, + { 0x0500, 0x01dc, 0x0fff }, + { 0x0900, 0x01de, 0x0001 }, + { 0x8500, 0x01ef, 0x5fff }, + { 0x8500, 0x01e7, 0x4fff }, + { 0x8500, 0x01e3, 0x3fff }, + { 0x8500, 0x01e1, 0x2fff }, + { 0x0900, 0x01e0, 0x0001 }, + { 0x0900, 0x01e2, 0x0001 }, + { 0x8500, 0x01e5, 0x2fff }, + { 0x0900, 0x01e4, 0x0001 }, + { 0x0900, 0x01e6, 0x0001 }, + { 0x8500, 0x01eb, 0x3fff }, + { 0x8500, 0x01e9, 0x2fff }, + { 0x0900, 0x01e8, 0x0001 }, + { 0x0900, 0x01ea, 0x0001 }, + { 0x8500, 0x01ed, 0x2fff }, + { 0x0900, 0x01ec, 0x0001 }, + { 0x0900, 0x01ee, 0x0001 }, + { 0x8900, 0x01f7, 0x4fc8 }, + { 0x8500, 0x01f3, 0x3ffe }, + { 0x8900, 0x01f1, 0x2002 }, + { 0x0500, 0x01f0, 0x0000 }, + { 0x0800, 0x01f2, 0x0000 }, + { 0x8500, 0x01f5, 0x2fff }, + { 0x0900, 0x01f4, 0x0001 }, + { 0x0900, 0x01f6, 0x0f9f }, + { 0x8500, 0x01fb, 0x3fff }, + { 0x8500, 0x01f9, 0x2fff }, + { 0x0900, 0x01f8, 0x0001 }, + { 0x0900, 0x01fa, 0x0001 }, + { 0x8500, 0x01fd, 0x2fff }, + { 0x0900, 0x01fc, 0x0001 }, + { 0x0900, 0x01fe, 0x0001 }, + { 0x8c00, 0x0318, 0x9000 }, + { 0x8500, 0x0298, 0x8000 }, + { 0x8500, 0x0258, 0x7000 }, + { 0x8500, 0x021f, 0x6fff }, + { 0x8500, 0x020f, 0x5fff }, + { 0x8500, 0x0207, 0x4fff }, + { 0x8500, 0x0203, 0x3fff }, + { 0x8500, 0x0201, 0x2fff }, + { 0x0900, 0x0200, 0x0001 }, + { 0x0900, 0x0202, 0x0001 }, + { 0x8500, 0x0205, 0x2fff }, + { 0x0900, 0x0204, 0x0001 }, + { 0x0900, 0x0206, 0x0001 }, + { 0x8500, 0x020b, 0x3fff }, + { 0x8500, 0x0209, 0x2fff }, + { 0x0900, 0x0208, 0x0001 }, + { 0x0900, 0x020a, 0x0001 }, + { 0x8500, 0x020d, 0x2fff }, + { 0x0900, 0x020c, 0x0001 }, + { 0x0900, 0x020e, 0x0001 }, + { 0x8500, 0x0217, 0x4fff }, + { 0x8500, 0x0213, 0x3fff }, + { 0x8500, 0x0211, 0x2fff }, + { 0x0900, 0x0210, 0x0001 }, + { 0x0900, 0x0212, 0x0001 }, + { 0x8500, 0x0215, 0x2fff }, + { 0x0900, 0x0214, 0x0001 }, + { 0x0900, 0x0216, 0x0001 }, + { 0x8500, 0x021b, 0x3fff }, + { 0x8500, 0x0219, 0x2fff }, + { 0x0900, 0x0218, 0x0001 }, + { 0x0900, 0x021a, 0x0001 }, + { 0x8500, 0x021d, 0x2fff }, + { 0x0900, 0x021c, 0x0001 }, + { 0x0900, 0x021e, 0x0001 }, + { 0x8500, 0x022f, 0x5fff }, + { 0x8500, 0x0227, 0x4fff }, + { 0x8500, 0x0223, 0x3fff }, + { 0x8500, 0x0221, 0x2000 }, + { 0x0900, 0x0220, 0x0f7e }, + { 0x0900, 0x0222, 0x0001 }, + { 0x8500, 0x0225, 0x2fff }, + { 0x0900, 0x0224, 0x0001 }, + { 0x0900, 0x0226, 0x0001 }, + { 0x8500, 0x022b, 0x3fff }, + { 0x8500, 0x0229, 0x2fff }, + { 0x0900, 0x0228, 0x0001 }, + { 0x0900, 0x022a, 0x0001 }, + { 0x8500, 0x022d, 0x2fff }, + { 0x0900, 0x022c, 0x0001 }, + { 0x0900, 0x022e, 0x0001 }, + { 0x8500, 0x0250, 0x4000 }, + { 0x8500, 0x0233, 0x3fff }, + { 0x8500, 0x0231, 0x2fff }, + { 0x0900, 0x0230, 0x0001 }, + { 0x0900, 0x0232, 0x0001 }, + { 0x8500, 0x0235, 0x2000 }, + { 0x0500, 0x0234, 0x0000 }, + { 0x0500, 0x0236, 0x0000 }, + { 0x8500, 0x0254, 0x3f32 }, + { 0x8500, 0x0252, 0x2000 }, + { 0x0500, 0x0251, 0x0000 }, + { 0x0500, 0x0253, 0x0f2e }, + { 0x8500, 0x0256, 0x2f33 }, + { 0x0500, 0x0255, 0x0000 }, + { 0x0500, 0x0257, 0x0f33 }, + { 0x8500, 0x0278, 0x6000 }, + { 0x8500, 0x0268, 0x5f2f }, + { 0x8500, 0x0260, 0x4f33 }, + { 0x8500, 0x025c, 0x3000 }, + { 0x8500, 0x025a, 0x2000 }, + { 0x0500, 0x0259, 0x0f36 }, + { 0x0500, 0x025b, 0x0f35 }, + { 0x8500, 0x025e, 0x2000 }, + { 0x0500, 0x025d, 0x0000 }, + { 0x0500, 0x025f, 0x0000 }, + { 0x8500, 0x0264, 0x3000 }, + { 0x8500, 0x0262, 0x2000 }, + { 0x0500, 0x0261, 0x0000 }, + { 0x0500, 0x0263, 0x0f31 }, + { 0x8500, 0x0266, 0x2000 }, + { 0x0500, 0x0265, 0x0000 }, + { 0x0500, 0x0267, 0x0000 }, + { 0x8500, 0x0270, 0x4000 }, + { 0x8500, 0x026c, 0x3000 }, + { 0x8500, 0x026a, 0x2000 }, + { 0x0500, 0x0269, 0x0f2d }, + { 0x0500, 0x026b, 0x0000 }, + { 0x8500, 0x026e, 0x2000 }, + { 0x0500, 0x026d, 0x0000 }, + { 0x0500, 0x026f, 0x0f2d }, + { 0x8500, 0x0274, 0x3000 }, + { 0x8500, 0x0272, 0x2f2b }, + { 0x0500, 0x0271, 0x0000 }, + { 0x0500, 0x0273, 0x0000 }, + { 0x8500, 0x0276, 0x2000 }, + { 0x0500, 0x0275, 0x0f2a }, + { 0x0500, 0x0277, 0x0000 }, + { 0x8500, 0x0288, 0x5f26 }, + { 0x8500, 0x0280, 0x4f26 }, + { 0x8500, 0x027c, 0x3000 }, + { 0x8500, 0x027a, 0x2000 }, + { 0x0500, 0x0279, 0x0000 }, + { 0x0500, 0x027b, 0x0000 }, + { 0x8500, 0x027e, 0x2000 }, + { 0x0500, 0x027d, 0x0000 }, + { 0x0500, 0x027f, 0x0000 }, + { 0x8500, 0x0284, 0x3000 }, + { 0x8500, 0x0282, 0x2000 }, + { 0x0500, 0x0281, 0x0000 }, + { 0x0500, 0x0283, 0x0f26 }, + { 0x8500, 0x0286, 0x2000 }, + { 0x0500, 0x0285, 0x0000 }, + { 0x0500, 0x0287, 0x0000 }, + { 0x8500, 0x0290, 0x4000 }, + { 0x8500, 0x028c, 0x3000 }, + { 0x8500, 0x028a, 0x2f27 }, + { 0x0500, 0x0289, 0x0000 }, + { 0x0500, 0x028b, 0x0f27 }, + { 0x8500, 0x028e, 0x2000 }, + { 0x0500, 0x028d, 0x0000 }, + { 0x0500, 0x028f, 0x0000 }, + { 0x8500, 0x0294, 0x3000 }, + { 0x8500, 0x0292, 0x2f25 }, + { 0x0500, 0x0291, 0x0000 }, + { 0x0500, 0x0293, 0x0000 }, + { 0x8500, 0x0296, 0x2000 }, + { 0x0500, 0x0295, 0x0000 }, + { 0x0500, 0x0297, 0x0000 }, + { 0x9800, 0x02d8, 0x7000 }, + { 0x8600, 0x02b8, 0x6000 }, + { 0x8500, 0x02a8, 0x5000 }, + { 0x8500, 0x02a0, 0x4000 }, + { 0x8500, 0x029c, 0x3000 }, + { 0x8500, 0x029a, 0x2000 }, + { 0x0500, 0x0299, 0x0000 }, + { 0x0500, 0x029b, 0x0000 }, + { 0x8500, 0x029e, 0x2000 }, + { 0x0500, 0x029d, 0x0000 }, + { 0x0500, 0x029f, 0x0000 }, + { 0x8500, 0x02a4, 0x3000 }, + { 0x8500, 0x02a2, 0x2000 }, + { 0x0500, 0x02a1, 0x0000 }, + { 0x0500, 0x02a3, 0x0000 }, + { 0x8500, 0x02a6, 0x2000 }, + { 0x0500, 0x02a5, 0x0000 }, + { 0x0500, 0x02a7, 0x0000 }, + { 0x8600, 0x02b0, 0x4000 }, + { 0x8500, 0x02ac, 0x3000 }, + { 0x8500, 0x02aa, 0x2000 }, + { 0x0500, 0x02a9, 0x0000 }, + { 0x0500, 0x02ab, 0x0000 }, + { 0x8500, 0x02ae, 0x2000 }, + { 0x0500, 0x02ad, 0x0000 }, + { 0x0500, 0x02af, 0x0000 }, + { 0x8600, 0x02b4, 0x3000 }, + { 0x8600, 0x02b2, 0x2000 }, + { 0x0600, 0x02b1, 0x0000 }, + { 0x0600, 0x02b3, 0x0000 }, + { 0x8600, 0x02b6, 0x2000 }, + { 0x0600, 0x02b5, 0x0000 }, + { 0x0600, 0x02b7, 0x0000 }, + { 0x8600, 0x02c8, 0x5000 }, + { 0x8600, 0x02c0, 0x4000 }, + { 0x8600, 0x02bc, 0x3000 }, + { 0x8600, 0x02ba, 0x2000 }, + { 0x0600, 0x02b9, 0x0000 }, + { 0x0600, 0x02bb, 0x0000 }, + { 0x8600, 0x02be, 0x2000 }, + { 0x0600, 0x02bd, 0x0000 }, + { 0x0600, 0x02bf, 0x0000 }, + { 0x9800, 0x02c4, 0x3000 }, + { 0x9800, 0x02c2, 0x2000 }, + { 0x0600, 0x02c1, 0x0000 }, + { 0x1800, 0x02c3, 0x0000 }, + { 0x8600, 0x02c6, 0x2000 }, + { 0x1800, 0x02c5, 0x0000 }, + { 0x0600, 0x02c7, 0x0000 }, + { 0x8600, 0x02d0, 0x4000 }, + { 0x8600, 0x02cc, 0x3000 }, + { 0x8600, 0x02ca, 0x2000 }, + { 0x0600, 0x02c9, 0x0000 }, + { 0x0600, 0x02cb, 0x0000 }, + { 0x8600, 0x02ce, 0x2000 }, + { 0x0600, 0x02cd, 0x0000 }, + { 0x0600, 0x02cf, 0x0000 }, + { 0x9800, 0x02d4, 0x3000 }, + { 0x9800, 0x02d2, 0x2000 }, + { 0x0600, 0x02d1, 0x0000 }, + { 0x1800, 0x02d3, 0x0000 }, + { 0x9800, 0x02d6, 0x2000 }, + { 0x1800, 0x02d5, 0x0000 }, + { 0x1800, 0x02d7, 0x0000 }, + { 0x9800, 0x02f8, 0x6000 }, + { 0x9800, 0x02e8, 0x5000 }, + { 0x8600, 0x02e0, 0x4000 }, + { 0x9800, 0x02dc, 0x3000 }, + { 0x9800, 0x02da, 0x2000 }, + { 0x1800, 0x02d9, 0x0000 }, + { 0x1800, 0x02db, 0x0000 }, + { 0x9800, 0x02de, 0x2000 }, + { 0x1800, 0x02dd, 0x0000 }, + { 0x1800, 0x02df, 0x0000 }, + { 0x8600, 0x02e4, 0x3000 }, + { 0x8600, 0x02e2, 0x2000 }, + { 0x0600, 0x02e1, 0x0000 }, + { 0x0600, 0x02e3, 0x0000 }, + { 0x9800, 0x02e6, 0x2000 }, + { 0x1800, 0x02e5, 0x0000 }, + { 0x1800, 0x02e7, 0x0000 }, + { 0x9800, 0x02f0, 0x4000 }, + { 0x9800, 0x02ec, 0x3000 }, + { 0x9800, 0x02ea, 0x2000 }, + { 0x1800, 0x02e9, 0x0000 }, + { 0x1800, 0x02eb, 0x0000 }, + { 0x8600, 0x02ee, 0x2000 }, + { 0x1800, 0x02ed, 0x0000 }, + { 0x1800, 0x02ef, 0x0000 }, + { 0x9800, 0x02f4, 0x3000 }, + { 0x9800, 0x02f2, 0x2000 }, + { 0x1800, 0x02f1, 0x0000 }, + { 0x1800, 0x02f3, 0x0000 }, + { 0x9800, 0x02f6, 0x2000 }, + { 0x1800, 0x02f5, 0x0000 }, + { 0x1800, 0x02f7, 0x0000 }, + { 0x8c00, 0x0308, 0x5000 }, + { 0x8c00, 0x0300, 0x4000 }, + { 0x9800, 0x02fc, 0x3000 }, + { 0x9800, 0x02fa, 0x2000 }, + { 0x1800, 0x02f9, 0x0000 }, + { 0x1800, 0x02fb, 0x0000 }, + { 0x9800, 0x02fe, 0x2000 }, + { 0x1800, 0x02fd, 0x0000 }, + { 0x1800, 0x02ff, 0x0000 }, + { 0x8c00, 0x0304, 0x3000 }, + { 0x8c00, 0x0302, 0x2000 }, + { 0x0c00, 0x0301, 0x0000 }, + { 0x0c00, 0x0303, 0x0000 }, + { 0x8c00, 0x0306, 0x2000 }, + { 0x0c00, 0x0305, 0x0000 }, + { 0x0c00, 0x0307, 0x0000 }, + { 0x8c00, 0x0310, 0x4000 }, + { 0x8c00, 0x030c, 0x3000 }, + { 0x8c00, 0x030a, 0x2000 }, + { 0x0c00, 0x0309, 0x0000 }, + { 0x0c00, 0x030b, 0x0000 }, + { 0x8c00, 0x030e, 0x2000 }, + { 0x0c00, 0x030d, 0x0000 }, + { 0x0c00, 0x030f, 0x0000 }, + { 0x8c00, 0x0314, 0x3000 }, + { 0x8c00, 0x0312, 0x2000 }, + { 0x0c00, 0x0311, 0x0000 }, + { 0x0c00, 0x0313, 0x0000 }, + { 0x8c00, 0x0316, 0x2000 }, + { 0x0c00, 0x0315, 0x0000 }, + { 0x0c00, 0x0317, 0x0000 }, + { 0x8500, 0x03b0, 0x8000 }, + { 0x8c00, 0x035d, 0x7000 }, + { 0x8c00, 0x0338, 0x6000 }, + { 0x8c00, 0x0328, 0x5000 }, + { 0x8c00, 0x0320, 0x4000 }, + { 0x8c00, 0x031c, 0x3000 }, + { 0x8c00, 0x031a, 0x2000 }, + { 0x0c00, 0x0319, 0x0000 }, + { 0x0c00, 0x031b, 0x0000 }, + { 0x8c00, 0x031e, 0x2000 }, + { 0x0c00, 0x031d, 0x0000 }, + { 0x0c00, 0x031f, 0x0000 }, + { 0x8c00, 0x0324, 0x3000 }, + { 0x8c00, 0x0322, 0x2000 }, + { 0x0c00, 0x0321, 0x0000 }, + { 0x0c00, 0x0323, 0x0000 }, + { 0x8c00, 0x0326, 0x2000 }, + { 0x0c00, 0x0325, 0x0000 }, + { 0x0c00, 0x0327, 0x0000 }, + { 0x8c00, 0x0330, 0x4000 }, + { 0x8c00, 0x032c, 0x3000 }, + { 0x8c00, 0x032a, 0x2000 }, + { 0x0c00, 0x0329, 0x0000 }, + { 0x0c00, 0x032b, 0x0000 }, + { 0x8c00, 0x032e, 0x2000 }, + { 0x0c00, 0x032d, 0x0000 }, + { 0x0c00, 0x032f, 0x0000 }, + { 0x8c00, 0x0334, 0x3000 }, + { 0x8c00, 0x0332, 0x2000 }, + { 0x0c00, 0x0331, 0x0000 }, + { 0x0c00, 0x0333, 0x0000 }, + { 0x8c00, 0x0336, 0x2000 }, + { 0x0c00, 0x0335, 0x0000 }, + { 0x0c00, 0x0337, 0x0000 }, + { 0x8c00, 0x0348, 0x5000 }, + { 0x8c00, 0x0340, 0x4000 }, + { 0x8c00, 0x033c, 0x3000 }, + { 0x8c00, 0x033a, 0x2000 }, + { 0x0c00, 0x0339, 0x0000 }, + { 0x0c00, 0x033b, 0x0000 }, + { 0x8c00, 0x033e, 0x2000 }, + { 0x0c00, 0x033d, 0x0000 }, + { 0x0c00, 0x033f, 0x0000 }, + { 0x8c00, 0x0344, 0x3000 }, + { 0x8c00, 0x0342, 0x2000 }, + { 0x0c00, 0x0341, 0x0000 }, + { 0x0c00, 0x0343, 0x0000 }, + { 0x8c00, 0x0346, 0x2000 }, + { 0x0c00, 0x0345, 0x0000 }, + { 0x0c00, 0x0347, 0x0000 }, + { 0x8c00, 0x0350, 0x4000 }, + { 0x8c00, 0x034c, 0x3000 }, + { 0x8c00, 0x034a, 0x2000 }, + { 0x0c00, 0x0349, 0x0000 }, + { 0x0c00, 0x034b, 0x0000 }, + { 0x8c00, 0x034e, 0x2000 }, + { 0x0c00, 0x034d, 0x0000 }, + { 0x0c00, 0x034f, 0x0000 }, + { 0x8c00, 0x0354, 0x3000 }, + { 0x8c00, 0x0352, 0x2000 }, + { 0x0c00, 0x0351, 0x0000 }, + { 0x0c00, 0x0353, 0x0000 }, + { 0x8c00, 0x0356, 0x2000 }, + { 0x0c00, 0x0355, 0x0000 }, + { 0x0c00, 0x0357, 0x0000 }, + { 0x8900, 0x038f, 0x603f }, + { 0x8c00, 0x036d, 0x5000 }, + { 0x8c00, 0x0365, 0x4000 }, + { 0x8c00, 0x0361, 0x3000 }, + { 0x8c00, 0x035f, 0x2000 }, + { 0x0c00, 0x035e, 0x0000 }, + { 0x0c00, 0x0360, 0x0000 }, + { 0x8c00, 0x0363, 0x2000 }, + { 0x0c00, 0x0362, 0x0000 }, + { 0x0c00, 0x0364, 0x0000 }, + { 0x8c00, 0x0369, 0x3000 }, + { 0x8c00, 0x0367, 0x2000 }, + { 0x0c00, 0x0366, 0x0000 }, + { 0x0c00, 0x0368, 0x0000 }, + { 0x8c00, 0x036b, 0x2000 }, + { 0x0c00, 0x036a, 0x0000 }, + { 0x0c00, 0x036c, 0x0000 }, + { 0x9800, 0x0385, 0x4000 }, + { 0x9800, 0x0375, 0x3000 }, + { 0x8c00, 0x036f, 0x2000 }, + { 0x0c00, 0x036e, 0x0000 }, + { 0x1800, 0x0374, 0x0000 }, + { 0x9500, 0x037e, 0x2000 }, + { 0x0600, 0x037a, 0x0000 }, + { 0x1800, 0x0384, 0x0000 }, + { 0x8900, 0x0389, 0x3025 }, + { 0x9500, 0x0387, 0x2000 }, + { 0x0900, 0x0386, 0x0026 }, + { 0x0900, 0x0388, 0x0025 }, + { 0x8900, 0x038c, 0x2040 }, + { 0x0900, 0x038a, 0x0025 }, + { 0x0900, 0x038e, 0x003f }, + { 0x8900, 0x039f, 0x5020 }, + { 0x8900, 0x0397, 0x4020 }, + { 0x8900, 0x0393, 0x3020 }, + { 0x8900, 0x0391, 0x2020 }, + { 0x0500, 0x0390, 0x0000 }, + { 0x0900, 0x0392, 0x0020 }, + { 0x8900, 0x0395, 0x2020 }, + { 0x0900, 0x0394, 0x0020 }, + { 0x0900, 0x0396, 0x0020 }, + { 0x8900, 0x039b, 0x3020 }, + { 0x8900, 0x0399, 0x2020 }, + { 0x0900, 0x0398, 0x0020 }, + { 0x0900, 0x039a, 0x0020 }, + { 0x8900, 0x039d, 0x2020 }, + { 0x0900, 0x039c, 0x0020 }, + { 0x0900, 0x039e, 0x0020 }, + { 0x8900, 0x03a8, 0x4020 }, + { 0x8900, 0x03a4, 0x3020 }, + { 0x8900, 0x03a1, 0x2020 }, + { 0x0900, 0x03a0, 0x0020 }, + { 0x0900, 0x03a3, 0x0020 }, + { 0x8900, 0x03a6, 0x2020 }, + { 0x0900, 0x03a5, 0x0020 }, + { 0x0900, 0x03a7, 0x0020 }, + { 0x8500, 0x03ac, 0x3fda }, + { 0x8900, 0x03aa, 0x2020 }, + { 0x0900, 0x03a9, 0x0020 }, + { 0x0900, 0x03ab, 0x0020 }, + { 0x8500, 0x03ae, 0x2fdb }, + { 0x0500, 0x03ad, 0x0fdb }, + { 0x0500, 0x03af, 0x0fdb }, + { 0x8500, 0x03f1, 0x7fb0 }, + { 0x8500, 0x03d1, 0x6fc7 }, + { 0x8500, 0x03c0, 0x5fe0 }, + { 0x8500, 0x03b8, 0x4fe0 }, + { 0x8500, 0x03b4, 0x3fe0 }, + { 0x8500, 0x03b2, 0x2fe0 }, + { 0x0500, 0x03b1, 0x0fe0 }, + { 0x0500, 0x03b3, 0x0fe0 }, + { 0x8500, 0x03b6, 0x2fe0 }, + { 0x0500, 0x03b5, 0x0fe0 }, + { 0x0500, 0x03b7, 0x0fe0 }, + { 0x8500, 0x03bc, 0x3fe0 }, + { 0x8500, 0x03ba, 0x2fe0 }, + { 0x0500, 0x03b9, 0x0fe0 }, + { 0x0500, 0x03bb, 0x0fe0 }, + { 0x8500, 0x03be, 0x2fe0 }, + { 0x0500, 0x03bd, 0x0fe0 }, + { 0x0500, 0x03bf, 0x0fe0 }, + { 0x8500, 0x03c8, 0x4fe0 }, + { 0x8500, 0x03c4, 0x3fe0 }, + { 0x8500, 0x03c2, 0x2fe1 }, + { 0x0500, 0x03c1, 0x0fe0 }, + { 0x0500, 0x03c3, 0x0fe0 }, + { 0x8500, 0x03c6, 0x2fe0 }, + { 0x0500, 0x03c5, 0x0fe0 }, + { 0x0500, 0x03c7, 0x0fe0 }, + { 0x8500, 0x03cc, 0x3fc0 }, + { 0x8500, 0x03ca, 0x2fe0 }, + { 0x0500, 0x03c9, 0x0fe0 }, + { 0x0500, 0x03cb, 0x0fe0 }, + { 0x8500, 0x03ce, 0x2fc1 }, + { 0x0500, 0x03cd, 0x0fc1 }, + { 0x0500, 0x03d0, 0x0fc2 }, + { 0x8500, 0x03e1, 0x5fff }, + { 0x8500, 0x03d9, 0x4fff }, + { 0x8500, 0x03d5, 0x3fd1 }, + { 0x8900, 0x03d3, 0x2000 }, + { 0x0900, 0x03d2, 0x0000 }, + { 0x0900, 0x03d4, 0x0000 }, + { 0x8500, 0x03d7, 0x2000 }, + { 0x0500, 0x03d6, 0x0fca }, + { 0x0900, 0x03d8, 0x0001 }, + { 0x8500, 0x03dd, 0x3fff }, + { 0x8500, 0x03db, 0x2fff }, + { 0x0900, 0x03da, 0x0001 }, + { 0x0900, 0x03dc, 0x0001 }, + { 0x8500, 0x03df, 0x2fff }, + { 0x0900, 0x03de, 0x0001 }, + { 0x0900, 0x03e0, 0x0001 }, + { 0x8500, 0x03e9, 0x4fff }, + { 0x8500, 0x03e5, 0x3fff }, + { 0x8500, 0x03e3, 0x2fff }, + { 0x0900, 0x03e2, 0x0001 }, + { 0x0900, 0x03e4, 0x0001 }, + { 0x8500, 0x03e7, 0x2fff }, + { 0x0900, 0x03e6, 0x0001 }, + { 0x0900, 0x03e8, 0x0001 }, + { 0x8500, 0x03ed, 0x3fff }, + { 0x8500, 0x03eb, 0x2fff }, + { 0x0900, 0x03ea, 0x0001 }, + { 0x0900, 0x03ec, 0x0001 }, + { 0x8500, 0x03ef, 0x2fff }, + { 0x0900, 0x03ee, 0x0001 }, + { 0x0500, 0x03f0, 0x0faa }, + { 0x8900, 0x0415, 0x6020 }, + { 0x8900, 0x0405, 0x5050 }, + { 0x8900, 0x03f9, 0x4ff9 }, + { 0x8500, 0x03f5, 0x3fa0 }, + { 0x8500, 0x03f3, 0x2000 }, + { 0x0500, 0x03f2, 0x0007 }, + { 0x0900, 0x03f4, 0x0fc4 }, + { 0x8900, 0x03f7, 0x2001 }, + { 0x1900, 0x03f6, 0x0000 }, + { 0x0500, 0x03f8, 0x0fff }, + { 0x8900, 0x0401, 0x3050 }, + { 0x8500, 0x03fb, 0x2fff }, + { 0x0900, 0x03fa, 0x0001 }, + { 0x0900, 0x0400, 0x0050 }, + { 0x8900, 0x0403, 0x2050 }, + { 0x0900, 0x0402, 0x0050 }, + { 0x0900, 0x0404, 0x0050 }, + { 0x8900, 0x040d, 0x4050 }, + { 0x8900, 0x0409, 0x3050 }, + { 0x8900, 0x0407, 0x2050 }, + { 0x0900, 0x0406, 0x0050 }, + { 0x0900, 0x0408, 0x0050 }, + { 0x8900, 0x040b, 0x2050 }, + { 0x0900, 0x040a, 0x0050 }, + { 0x0900, 0x040c, 0x0050 }, + { 0x8900, 0x0411, 0x3020 }, + { 0x8900, 0x040f, 0x2050 }, + { 0x0900, 0x040e, 0x0050 }, + { 0x0900, 0x0410, 0x0020 }, + { 0x8900, 0x0413, 0x2020 }, + { 0x0900, 0x0412, 0x0020 }, + { 0x0900, 0x0414, 0x0020 }, + { 0x8900, 0x0425, 0x5020 }, + { 0x8900, 0x041d, 0x4020 }, + { 0x8900, 0x0419, 0x3020 }, + { 0x8900, 0x0417, 0x2020 }, + { 0x0900, 0x0416, 0x0020 }, + { 0x0900, 0x0418, 0x0020 }, + { 0x8900, 0x041b, 0x2020 }, + { 0x0900, 0x041a, 0x0020 }, + { 0x0900, 0x041c, 0x0020 }, + { 0x8900, 0x0421, 0x3020 }, + { 0x8900, 0x041f, 0x2020 }, + { 0x0900, 0x041e, 0x0020 }, + { 0x0900, 0x0420, 0x0020 }, + { 0x8900, 0x0423, 0x2020 }, + { 0x0900, 0x0422, 0x0020 }, + { 0x0900, 0x0424, 0x0020 }, + { 0x8900, 0x042d, 0x4020 }, + { 0x8900, 0x0429, 0x3020 }, + { 0x8900, 0x0427, 0x2020 }, + { 0x0900, 0x0426, 0x0020 }, + { 0x0900, 0x0428, 0x0020 }, + { 0x8900, 0x042b, 0x2020 }, + { 0x0900, 0x042a, 0x0020 }, + { 0x0900, 0x042c, 0x0020 }, + { 0x8500, 0x0431, 0x3fe0 }, + { 0x8900, 0x042f, 0x2020 }, + { 0x0900, 0x042e, 0x0020 }, + { 0x0500, 0x0430, 0x0fe0 }, + { 0x8500, 0x0433, 0x2fe0 }, + { 0x0500, 0x0432, 0x0fe0 }, + { 0x0500, 0x0434, 0x0fe0 }, + { 0x8700, 0x06a4, 0xa000 }, + { 0x8500, 0x0563, 0x9fd0 }, + { 0x8900, 0x04b6, 0x8001 }, + { 0x8500, 0x0475, 0x7fff }, + { 0x8500, 0x0455, 0x6fb0 }, + { 0x8500, 0x0445, 0x5fe0 }, + { 0x8500, 0x043d, 0x4fe0 }, + { 0x8500, 0x0439, 0x3fe0 }, + { 0x8500, 0x0437, 0x2fe0 }, + { 0x0500, 0x0436, 0x0fe0 }, + { 0x0500, 0x0438, 0x0fe0 }, + { 0x8500, 0x043b, 0x2fe0 }, + { 0x0500, 0x043a, 0x0fe0 }, + { 0x0500, 0x043c, 0x0fe0 }, + { 0x8500, 0x0441, 0x3fe0 }, + { 0x8500, 0x043f, 0x2fe0 }, + { 0x0500, 0x043e, 0x0fe0 }, + { 0x0500, 0x0440, 0x0fe0 }, + { 0x8500, 0x0443, 0x2fe0 }, + { 0x0500, 0x0442, 0x0fe0 }, + { 0x0500, 0x0444, 0x0fe0 }, + { 0x8500, 0x044d, 0x4fe0 }, + { 0x8500, 0x0449, 0x3fe0 }, + { 0x8500, 0x0447, 0x2fe0 }, + { 0x0500, 0x0446, 0x0fe0 }, + { 0x0500, 0x0448, 0x0fe0 }, + { 0x8500, 0x044b, 0x2fe0 }, + { 0x0500, 0x044a, 0x0fe0 }, + { 0x0500, 0x044c, 0x0fe0 }, + { 0x8500, 0x0451, 0x3fb0 }, + { 0x8500, 0x044f, 0x2fe0 }, + { 0x0500, 0x044e, 0x0fe0 }, + { 0x0500, 0x0450, 0x0fb0 }, + { 0x8500, 0x0453, 0x2fb0 }, + { 0x0500, 0x0452, 0x0fb0 }, + { 0x0500, 0x0454, 0x0fb0 }, + { 0x8500, 0x0465, 0x5fff }, + { 0x8500, 0x045d, 0x4fb0 }, + { 0x8500, 0x0459, 0x3fb0 }, + { 0x8500, 0x0457, 0x2fb0 }, + { 0x0500, 0x0456, 0x0fb0 }, + { 0x0500, 0x0458, 0x0fb0 }, + { 0x8500, 0x045b, 0x2fb0 }, + { 0x0500, 0x045a, 0x0fb0 }, + { 0x0500, 0x045c, 0x0fb0 }, + { 0x8500, 0x0461, 0x3fff }, + { 0x8500, 0x045f, 0x2fb0 }, + { 0x0500, 0x045e, 0x0fb0 }, + { 0x0900, 0x0460, 0x0001 }, + { 0x8500, 0x0463, 0x2fff }, + { 0x0900, 0x0462, 0x0001 }, + { 0x0900, 0x0464, 0x0001 }, + { 0x8500, 0x046d, 0x4fff }, + { 0x8500, 0x0469, 0x3fff }, + { 0x8500, 0x0467, 0x2fff }, + { 0x0900, 0x0466, 0x0001 }, + { 0x0900, 0x0468, 0x0001 }, + { 0x8500, 0x046b, 0x2fff }, + { 0x0900, 0x046a, 0x0001 }, + { 0x0900, 0x046c, 0x0001 }, + { 0x8500, 0x0471, 0x3fff }, + { 0x8500, 0x046f, 0x2fff }, + { 0x0900, 0x046e, 0x0001 }, + { 0x0900, 0x0470, 0x0001 }, + { 0x8500, 0x0473, 0x2fff }, + { 0x0900, 0x0472, 0x0001 }, + { 0x0900, 0x0474, 0x0001 }, + { 0x8900, 0x0496, 0x6001 }, + { 0x8c00, 0x0485, 0x5000 }, + { 0x8500, 0x047d, 0x4fff }, + { 0x8500, 0x0479, 0x3fff }, + { 0x8500, 0x0477, 0x2fff }, + { 0x0900, 0x0476, 0x0001 }, + { 0x0900, 0x0478, 0x0001 }, + { 0x8500, 0x047b, 0x2fff }, + { 0x0900, 0x047a, 0x0001 }, + { 0x0900, 0x047c, 0x0001 }, + { 0x8500, 0x0481, 0x3fff }, + { 0x8500, 0x047f, 0x2fff }, + { 0x0900, 0x047e, 0x0001 }, + { 0x0900, 0x0480, 0x0001 }, + { 0x8c00, 0x0483, 0x2000 }, + { 0x1a00, 0x0482, 0x0000 }, + { 0x0c00, 0x0484, 0x0000 }, + { 0x8900, 0x048e, 0x4001 }, + { 0x8900, 0x048a, 0x3001 }, + { 0x8b00, 0x0488, 0x2000 }, + { 0x0c00, 0x0486, 0x0000 }, + { 0x0b00, 0x0489, 0x0000 }, + { 0x8900, 0x048c, 0x2001 }, + { 0x0500, 0x048b, 0x0fff }, + { 0x0500, 0x048d, 0x0fff }, + { 0x8900, 0x0492, 0x3001 }, + { 0x8900, 0x0490, 0x2001 }, + { 0x0500, 0x048f, 0x0fff }, + { 0x0500, 0x0491, 0x0fff }, + { 0x8900, 0x0494, 0x2001 }, + { 0x0500, 0x0493, 0x0fff }, + { 0x0500, 0x0495, 0x0fff }, + { 0x8900, 0x04a6, 0x5001 }, + { 0x8900, 0x049e, 0x4001 }, + { 0x8900, 0x049a, 0x3001 }, + { 0x8900, 0x0498, 0x2001 }, + { 0x0500, 0x0497, 0x0fff }, + { 0x0500, 0x0499, 0x0fff }, + { 0x8900, 0x049c, 0x2001 }, + { 0x0500, 0x049b, 0x0fff }, + { 0x0500, 0x049d, 0x0fff }, + { 0x8900, 0x04a2, 0x3001 }, + { 0x8900, 0x04a0, 0x2001 }, + { 0x0500, 0x049f, 0x0fff }, + { 0x0500, 0x04a1, 0x0fff }, + { 0x8900, 0x04a4, 0x2001 }, + { 0x0500, 0x04a3, 0x0fff }, + { 0x0500, 0x04a5, 0x0fff }, + { 0x8900, 0x04ae, 0x4001 }, + { 0x8900, 0x04aa, 0x3001 }, + { 0x8900, 0x04a8, 0x2001 }, + { 0x0500, 0x04a7, 0x0fff }, + { 0x0500, 0x04a9, 0x0fff }, + { 0x8900, 0x04ac, 0x2001 }, + { 0x0500, 0x04ab, 0x0fff }, + { 0x0500, 0x04ad, 0x0fff }, + { 0x8900, 0x04b2, 0x3001 }, + { 0x8900, 0x04b0, 0x2001 }, + { 0x0500, 0x04af, 0x0fff }, + { 0x0500, 0x04b1, 0x0fff }, + { 0x8900, 0x04b4, 0x2001 }, + { 0x0500, 0x04b3, 0x0fff }, + { 0x0500, 0x04b5, 0x0fff }, + { 0x8500, 0x04f9, 0x7fff }, + { 0x8500, 0x04d7, 0x6fff }, + { 0x8500, 0x04c6, 0x5fff }, + { 0x8900, 0x04be, 0x4001 }, + { 0x8900, 0x04ba, 0x3001 }, + { 0x8900, 0x04b8, 0x2001 }, + { 0x0500, 0x04b7, 0x0fff }, + { 0x0500, 0x04b9, 0x0fff }, + { 0x8900, 0x04bc, 0x2001 }, + { 0x0500, 0x04bb, 0x0fff }, + { 0x0500, 0x04bd, 0x0fff }, + { 0x8500, 0x04c2, 0x3fff }, + { 0x8900, 0x04c0, 0x2000 }, + { 0x0500, 0x04bf, 0x0fff }, + { 0x0900, 0x04c1, 0x0001 }, + { 0x8500, 0x04c4, 0x2fff }, + { 0x0900, 0x04c3, 0x0001 }, + { 0x0900, 0x04c5, 0x0001 }, + { 0x8500, 0x04ce, 0x4fff }, + { 0x8500, 0x04ca, 0x3fff }, + { 0x8500, 0x04c8, 0x2fff }, + { 0x0900, 0x04c7, 0x0001 }, + { 0x0900, 0x04c9, 0x0001 }, + { 0x8500, 0x04cc, 0x2fff }, + { 0x0900, 0x04cb, 0x0001 }, + { 0x0900, 0x04cd, 0x0001 }, + { 0x8500, 0x04d3, 0x3fff }, + { 0x8500, 0x04d1, 0x2fff }, + { 0x0900, 0x04d0, 0x0001 }, + { 0x0900, 0x04d2, 0x0001 }, + { 0x8500, 0x04d5, 0x2fff }, + { 0x0900, 0x04d4, 0x0001 }, + { 0x0900, 0x04d6, 0x0001 }, + { 0x8500, 0x04e7, 0x5fff }, + { 0x8500, 0x04df, 0x4fff }, + { 0x8500, 0x04db, 0x3fff }, + { 0x8500, 0x04d9, 0x2fff }, + { 0x0900, 0x04d8, 0x0001 }, + { 0x0900, 0x04da, 0x0001 }, + { 0x8500, 0x04dd, 0x2fff }, + { 0x0900, 0x04dc, 0x0001 }, + { 0x0900, 0x04de, 0x0001 }, + { 0x8500, 0x04e3, 0x3fff }, + { 0x8500, 0x04e1, 0x2fff }, + { 0x0900, 0x04e0, 0x0001 }, + { 0x0900, 0x04e2, 0x0001 }, + { 0x8500, 0x04e5, 0x2fff }, + { 0x0900, 0x04e4, 0x0001 }, + { 0x0900, 0x04e6, 0x0001 }, + { 0x8500, 0x04ef, 0x4fff }, + { 0x8500, 0x04eb, 0x3fff }, + { 0x8500, 0x04e9, 0x2fff }, + { 0x0900, 0x04e8, 0x0001 }, + { 0x0900, 0x04ea, 0x0001 }, + { 0x8500, 0x04ed, 0x2fff }, + { 0x0900, 0x04ec, 0x0001 }, + { 0x0900, 0x04ee, 0x0001 }, + { 0x8500, 0x04f3, 0x3fff }, + { 0x8500, 0x04f1, 0x2fff }, + { 0x0900, 0x04f0, 0x0001 }, + { 0x0900, 0x04f2, 0x0001 }, + { 0x8500, 0x04f5, 0x2fff }, + { 0x0900, 0x04f4, 0x0001 }, + { 0x0900, 0x04f8, 0x0001 }, + { 0x8900, 0x0540, 0x6030 }, + { 0x8500, 0x050f, 0x5fff }, + { 0x8500, 0x0507, 0x4fff }, + { 0x8500, 0x0503, 0x3fff }, + { 0x8500, 0x0501, 0x2fff }, + { 0x0900, 0x0500, 0x0001 }, + { 0x0900, 0x0502, 0x0001 }, + { 0x8500, 0x0505, 0x2fff }, + { 0x0900, 0x0504, 0x0001 }, + { 0x0900, 0x0506, 0x0001 }, + { 0x8500, 0x050b, 0x3fff }, + { 0x8500, 0x0509, 0x2fff }, + { 0x0900, 0x0508, 0x0001 }, + { 0x0900, 0x050a, 0x0001 }, + { 0x8500, 0x050d, 0x2fff }, + { 0x0900, 0x050c, 0x0001 }, + { 0x0900, 0x050e, 0x0001 }, + { 0x8900, 0x0538, 0x4030 }, + { 0x8900, 0x0534, 0x3030 }, + { 0x8900, 0x0532, 0x2030 }, + { 0x0900, 0x0531, 0x0030 }, + { 0x0900, 0x0533, 0x0030 }, + { 0x8900, 0x0536, 0x2030 }, + { 0x0900, 0x0535, 0x0030 }, + { 0x0900, 0x0537, 0x0030 }, + { 0x8900, 0x053c, 0x3030 }, + { 0x8900, 0x053a, 0x2030 }, + { 0x0900, 0x0539, 0x0030 }, + { 0x0900, 0x053b, 0x0030 }, + { 0x8900, 0x053e, 0x2030 }, + { 0x0900, 0x053d, 0x0030 }, + { 0x0900, 0x053f, 0x0030 }, + { 0x8900, 0x0550, 0x5030 }, + { 0x8900, 0x0548, 0x4030 }, + { 0x8900, 0x0544, 0x3030 }, + { 0x8900, 0x0542, 0x2030 }, + { 0x0900, 0x0541, 0x0030 }, + { 0x0900, 0x0543, 0x0030 }, + { 0x8900, 0x0546, 0x2030 }, + { 0x0900, 0x0545, 0x0030 }, + { 0x0900, 0x0547, 0x0030 }, + { 0x8900, 0x054c, 0x3030 }, + { 0x8900, 0x054a, 0x2030 }, + { 0x0900, 0x0549, 0x0030 }, + { 0x0900, 0x054b, 0x0030 }, + { 0x8900, 0x054e, 0x2030 }, + { 0x0900, 0x054d, 0x0030 }, + { 0x0900, 0x054f, 0x0030 }, + { 0x9500, 0x055a, 0x4000 }, + { 0x8900, 0x0554, 0x3030 }, + { 0x8900, 0x0552, 0x2030 }, + { 0x0900, 0x0551, 0x0030 }, + { 0x0900, 0x0553, 0x0030 }, + { 0x8900, 0x0556, 0x2030 }, + { 0x0900, 0x0555, 0x0030 }, + { 0x0600, 0x0559, 0x0000 }, + { 0x9500, 0x055e, 0x3000 }, + { 0x9500, 0x055c, 0x2000 }, + { 0x1500, 0x055b, 0x0000 }, + { 0x1500, 0x055d, 0x0000 }, + { 0x8500, 0x0561, 0x2fd0 }, + { 0x1500, 0x055f, 0x0000 }, + { 0x0500, 0x0562, 0x0fd0 }, + { 0x9a00, 0x060f, 0x8000 }, + { 0x8c00, 0x05ab, 0x7000 }, + { 0x8500, 0x0583, 0x6fd0 }, + { 0x8500, 0x0573, 0x5fd0 }, + { 0x8500, 0x056b, 0x4fd0 }, + { 0x8500, 0x0567, 0x3fd0 }, + { 0x8500, 0x0565, 0x2fd0 }, + { 0x0500, 0x0564, 0x0fd0 }, + { 0x0500, 0x0566, 0x0fd0 }, + { 0x8500, 0x0569, 0x2fd0 }, + { 0x0500, 0x0568, 0x0fd0 }, + { 0x0500, 0x056a, 0x0fd0 }, + { 0x8500, 0x056f, 0x3fd0 }, + { 0x8500, 0x056d, 0x2fd0 }, + { 0x0500, 0x056c, 0x0fd0 }, + { 0x0500, 0x056e, 0x0fd0 }, + { 0x8500, 0x0571, 0x2fd0 }, + { 0x0500, 0x0570, 0x0fd0 }, + { 0x0500, 0x0572, 0x0fd0 }, + { 0x8500, 0x057b, 0x4fd0 }, + { 0x8500, 0x0577, 0x3fd0 }, + { 0x8500, 0x0575, 0x2fd0 }, + { 0x0500, 0x0574, 0x0fd0 }, + { 0x0500, 0x0576, 0x0fd0 }, + { 0x8500, 0x0579, 0x2fd0 }, + { 0x0500, 0x0578, 0x0fd0 }, + { 0x0500, 0x057a, 0x0fd0 }, + { 0x8500, 0x057f, 0x3fd0 }, + { 0x8500, 0x057d, 0x2fd0 }, + { 0x0500, 0x057c, 0x0fd0 }, + { 0x0500, 0x057e, 0x0fd0 }, + { 0x8500, 0x0581, 0x2fd0 }, + { 0x0500, 0x0580, 0x0fd0 }, + { 0x0500, 0x0582, 0x0fd0 }, + { 0x8c00, 0x059a, 0x5000 }, + { 0x8c00, 0x0592, 0x4000 }, + { 0x8500, 0x0587, 0x3000 }, + { 0x8500, 0x0585, 0x2fd0 }, + { 0x0500, 0x0584, 0x0fd0 }, + { 0x0500, 0x0586, 0x0fd0 }, + { 0x9100, 0x058a, 0x2000 }, + { 0x1500, 0x0589, 0x0000 }, + { 0x0c00, 0x0591, 0x0000 }, + { 0x8c00, 0x0596, 0x3000 }, + { 0x8c00, 0x0594, 0x2000 }, + { 0x0c00, 0x0593, 0x0000 }, + { 0x0c00, 0x0595, 0x0000 }, + { 0x8c00, 0x0598, 0x2000 }, + { 0x0c00, 0x0597, 0x0000 }, + { 0x0c00, 0x0599, 0x0000 }, + { 0x8c00, 0x05a3, 0x4000 }, + { 0x8c00, 0x059e, 0x3000 }, + { 0x8c00, 0x059c, 0x2000 }, + { 0x0c00, 0x059b, 0x0000 }, + { 0x0c00, 0x059d, 0x0000 }, + { 0x8c00, 0x05a0, 0x2000 }, + { 0x0c00, 0x059f, 0x0000 }, + { 0x0c00, 0x05a1, 0x0000 }, + { 0x8c00, 0x05a7, 0x3000 }, + { 0x8c00, 0x05a5, 0x2000 }, + { 0x0c00, 0x05a4, 0x0000 }, + { 0x0c00, 0x05a6, 0x0000 }, + { 0x8c00, 0x05a9, 0x2000 }, + { 0x0c00, 0x05a8, 0x0000 }, + { 0x0c00, 0x05aa, 0x0000 }, + { 0x8700, 0x05d7, 0x6000 }, + { 0x8c00, 0x05bc, 0x5000 }, + { 0x8c00, 0x05b3, 0x4000 }, + { 0x8c00, 0x05af, 0x3000 }, + { 0x8c00, 0x05ad, 0x2000 }, + { 0x0c00, 0x05ac, 0x0000 }, + { 0x0c00, 0x05ae, 0x0000 }, + { 0x8c00, 0x05b1, 0x2000 }, + { 0x0c00, 0x05b0, 0x0000 }, + { 0x0c00, 0x05b2, 0x0000 }, + { 0x8c00, 0x05b7, 0x3000 }, + { 0x8c00, 0x05b5, 0x2000 }, + { 0x0c00, 0x05b4, 0x0000 }, + { 0x0c00, 0x05b6, 0x0000 }, + { 0x8c00, 0x05b9, 0x2000 }, + { 0x0c00, 0x05b8, 0x0000 }, + { 0x0c00, 0x05bb, 0x0000 }, + { 0x8c00, 0x05c4, 0x4000 }, + { 0x9500, 0x05c0, 0x3000 }, + { 0x9500, 0x05be, 0x2000 }, + { 0x0c00, 0x05bd, 0x0000 }, + { 0x0c00, 0x05bf, 0x0000 }, + { 0x8c00, 0x05c2, 0x2000 }, + { 0x0c00, 0x05c1, 0x0000 }, + { 0x1500, 0x05c3, 0x0000 }, + { 0x8700, 0x05d3, 0x3000 }, + { 0x8700, 0x05d1, 0x2000 }, + { 0x0700, 0x05d0, 0x0000 }, + { 0x0700, 0x05d2, 0x0000 }, + { 0x8700, 0x05d5, 0x2000 }, + { 0x0700, 0x05d4, 0x0000 }, + { 0x0700, 0x05d6, 0x0000 }, + { 0x8700, 0x05e7, 0x5000 }, + { 0x8700, 0x05df, 0x4000 }, + { 0x8700, 0x05db, 0x3000 }, + { 0x8700, 0x05d9, 0x2000 }, + { 0x0700, 0x05d8, 0x0000 }, + { 0x0700, 0x05da, 0x0000 }, + { 0x8700, 0x05dd, 0x2000 }, + { 0x0700, 0x05dc, 0x0000 }, + { 0x0700, 0x05de, 0x0000 }, + { 0x8700, 0x05e3, 0x3000 }, + { 0x8700, 0x05e1, 0x2000 }, + { 0x0700, 0x05e0, 0x0000 }, + { 0x0700, 0x05e2, 0x0000 }, + { 0x8700, 0x05e5, 0x2000 }, + { 0x0700, 0x05e4, 0x0000 }, + { 0x0700, 0x05e6, 0x0000 }, + { 0x9500, 0x05f4, 0x4000 }, + { 0x8700, 0x05f0, 0x3000 }, + { 0x8700, 0x05e9, 0x2000 }, + { 0x0700, 0x05e8, 0x0000 }, + { 0x0700, 0x05ea, 0x0000 }, + { 0x8700, 0x05f2, 0x2000 }, + { 0x0700, 0x05f1, 0x0000 }, + { 0x1500, 0x05f3, 0x0000 }, + { 0x8100, 0x0603, 0x3000 }, + { 0x8100, 0x0601, 0x2000 }, + { 0x0100, 0x0600, 0x0000 }, + { 0x0100, 0x0602, 0x0000 }, + { 0x9500, 0x060d, 0x2000 }, + { 0x1500, 0x060c, 0x0000 }, + { 0x1a00, 0x060e, 0x0000 }, + { 0x8d00, 0x0664, 0x7000 }, + { 0x8700, 0x0638, 0x6000 }, + { 0x8700, 0x0628, 0x5000 }, + { 0x9500, 0x061f, 0x4000 }, + { 0x8c00, 0x0613, 0x3000 }, + { 0x8c00, 0x0611, 0x2000 }, + { 0x0c00, 0x0610, 0x0000 }, + { 0x0c00, 0x0612, 0x0000 }, + { 0x8c00, 0x0615, 0x2000 }, + { 0x0c00, 0x0614, 0x0000 }, + { 0x1500, 0x061b, 0x0000 }, + { 0x8700, 0x0624, 0x3000 }, + { 0x8700, 0x0622, 0x2000 }, + { 0x0700, 0x0621, 0x0000 }, + { 0x0700, 0x0623, 0x0000 }, + { 0x8700, 0x0626, 0x2000 }, + { 0x0700, 0x0625, 0x0000 }, + { 0x0700, 0x0627, 0x0000 }, + { 0x8700, 0x0630, 0x4000 }, + { 0x8700, 0x062c, 0x3000 }, + { 0x8700, 0x062a, 0x2000 }, + { 0x0700, 0x0629, 0x0000 }, + { 0x0700, 0x062b, 0x0000 }, + { 0x8700, 0x062e, 0x2000 }, + { 0x0700, 0x062d, 0x0000 }, + { 0x0700, 0x062f, 0x0000 }, + { 0x8700, 0x0634, 0x3000 }, + { 0x8700, 0x0632, 0x2000 }, + { 0x0700, 0x0631, 0x0000 }, + { 0x0700, 0x0633, 0x0000 }, + { 0x8700, 0x0636, 0x2000 }, + { 0x0700, 0x0635, 0x0000 }, + { 0x0700, 0x0637, 0x0000 }, + { 0x8c00, 0x064d, 0x5000 }, + { 0x8700, 0x0645, 0x4000 }, + { 0x8700, 0x0641, 0x3000 }, + { 0x8700, 0x063a, 0x2000 }, + { 0x0700, 0x0639, 0x0000 }, + { 0x0600, 0x0640, 0x0000 }, + { 0x8700, 0x0643, 0x2000 }, + { 0x0700, 0x0642, 0x0000 }, + { 0x0700, 0x0644, 0x0000 }, + { 0x8700, 0x0649, 0x3000 }, + { 0x8700, 0x0647, 0x2000 }, + { 0x0700, 0x0646, 0x0000 }, + { 0x0700, 0x0648, 0x0000 }, + { 0x8c00, 0x064b, 0x2000 }, + { 0x0700, 0x064a, 0x0000 }, + { 0x0c00, 0x064c, 0x0000 }, + { 0x8c00, 0x0655, 0x4000 }, + { 0x8c00, 0x0651, 0x3000 }, + { 0x8c00, 0x064f, 0x2000 }, + { 0x0c00, 0x064e, 0x0000 }, + { 0x0c00, 0x0650, 0x0000 }, + { 0x8c00, 0x0653, 0x2000 }, + { 0x0c00, 0x0652, 0x0000 }, + { 0x0c00, 0x0654, 0x0000 }, + { 0x8d00, 0x0660, 0x3000 }, + { 0x8c00, 0x0657, 0x2000 }, + { 0x0c00, 0x0656, 0x0000 }, + { 0x0c00, 0x0658, 0x0000 }, + { 0x8d00, 0x0662, 0x2000 }, + { 0x0d00, 0x0661, 0x0000 }, + { 0x0d00, 0x0663, 0x0000 }, + { 0x8700, 0x0684, 0x6000 }, + { 0x8700, 0x0674, 0x5000 }, + { 0x9500, 0x066c, 0x4000 }, + { 0x8d00, 0x0668, 0x3000 }, + { 0x8d00, 0x0666, 0x2000 }, + { 0x0d00, 0x0665, 0x0000 }, + { 0x0d00, 0x0667, 0x0000 }, + { 0x9500, 0x066a, 0x2000 }, + { 0x0d00, 0x0669, 0x0000 }, + { 0x1500, 0x066b, 0x0000 }, + { 0x8c00, 0x0670, 0x3000 }, + { 0x8700, 0x066e, 0x2000 }, + { 0x1500, 0x066d, 0x0000 }, + { 0x0700, 0x066f, 0x0000 }, + { 0x8700, 0x0672, 0x2000 }, + { 0x0700, 0x0671, 0x0000 }, + { 0x0700, 0x0673, 0x0000 }, + { 0x8700, 0x067c, 0x4000 }, + { 0x8700, 0x0678, 0x3000 }, + { 0x8700, 0x0676, 0x2000 }, + { 0x0700, 0x0675, 0x0000 }, + { 0x0700, 0x0677, 0x0000 }, + { 0x8700, 0x067a, 0x2000 }, + { 0x0700, 0x0679, 0x0000 }, + { 0x0700, 0x067b, 0x0000 }, + { 0x8700, 0x0680, 0x3000 }, + { 0x8700, 0x067e, 0x2000 }, + { 0x0700, 0x067d, 0x0000 }, + { 0x0700, 0x067f, 0x0000 }, + { 0x8700, 0x0682, 0x2000 }, + { 0x0700, 0x0681, 0x0000 }, + { 0x0700, 0x0683, 0x0000 }, + { 0x8700, 0x0694, 0x5000 }, + { 0x8700, 0x068c, 0x4000 }, + { 0x8700, 0x0688, 0x3000 }, + { 0x8700, 0x0686, 0x2000 }, + { 0x0700, 0x0685, 0x0000 }, + { 0x0700, 0x0687, 0x0000 }, + { 0x8700, 0x068a, 0x2000 }, + { 0x0700, 0x0689, 0x0000 }, + { 0x0700, 0x068b, 0x0000 }, + { 0x8700, 0x0690, 0x3000 }, + { 0x8700, 0x068e, 0x2000 }, + { 0x0700, 0x068d, 0x0000 }, + { 0x0700, 0x068f, 0x0000 }, + { 0x8700, 0x0692, 0x2000 }, + { 0x0700, 0x0691, 0x0000 }, + { 0x0700, 0x0693, 0x0000 }, + { 0x8700, 0x069c, 0x4000 }, + { 0x8700, 0x0698, 0x3000 }, + { 0x8700, 0x0696, 0x2000 }, + { 0x0700, 0x0695, 0x0000 }, + { 0x0700, 0x0697, 0x0000 }, + { 0x8700, 0x069a, 0x2000 }, + { 0x0700, 0x0699, 0x0000 }, + { 0x0700, 0x069b, 0x0000 }, + { 0x8700, 0x06a0, 0x3000 }, + { 0x8700, 0x069e, 0x2000 }, + { 0x0700, 0x069d, 0x0000 }, + { 0x0700, 0x069f, 0x0000 }, + { 0x8700, 0x06a2, 0x2000 }, + { 0x0700, 0x06a1, 0x0000 }, + { 0x0700, 0x06a3, 0x0000 }, + { 0x8700, 0x0926, 0x9000 }, + { 0x8700, 0x0725, 0x8000 }, + { 0x8c00, 0x06e4, 0x7000 }, + { 0x8700, 0x06c4, 0x6000 }, + { 0x8700, 0x06b4, 0x5000 }, + { 0x8700, 0x06ac, 0x4000 }, + { 0x8700, 0x06a8, 0x3000 }, + { 0x8700, 0x06a6, 0x2000 }, + { 0x0700, 0x06a5, 0x0000 }, + { 0x0700, 0x06a7, 0x0000 }, + { 0x8700, 0x06aa, 0x2000 }, + { 0x0700, 0x06a9, 0x0000 }, + { 0x0700, 0x06ab, 0x0000 }, + { 0x8700, 0x06b0, 0x3000 }, + { 0x8700, 0x06ae, 0x2000 }, + { 0x0700, 0x06ad, 0x0000 }, + { 0x0700, 0x06af, 0x0000 }, + { 0x8700, 0x06b2, 0x2000 }, + { 0x0700, 0x06b1, 0x0000 }, + { 0x0700, 0x06b3, 0x0000 }, + { 0x8700, 0x06bc, 0x4000 }, + { 0x8700, 0x06b8, 0x3000 }, + { 0x8700, 0x06b6, 0x2000 }, + { 0x0700, 0x06b5, 0x0000 }, + { 0x0700, 0x06b7, 0x0000 }, + { 0x8700, 0x06ba, 0x2000 }, + { 0x0700, 0x06b9, 0x0000 }, + { 0x0700, 0x06bb, 0x0000 }, + { 0x8700, 0x06c0, 0x3000 }, + { 0x8700, 0x06be, 0x2000 }, + { 0x0700, 0x06bd, 0x0000 }, + { 0x0700, 0x06bf, 0x0000 }, + { 0x8700, 0x06c2, 0x2000 }, + { 0x0700, 0x06c1, 0x0000 }, + { 0x0700, 0x06c3, 0x0000 }, + { 0x9500, 0x06d4, 0x5000 }, + { 0x8700, 0x06cc, 0x4000 }, + { 0x8700, 0x06c8, 0x3000 }, + { 0x8700, 0x06c6, 0x2000 }, + { 0x0700, 0x06c5, 0x0000 }, + { 0x0700, 0x06c7, 0x0000 }, + { 0x8700, 0x06ca, 0x2000 }, + { 0x0700, 0x06c9, 0x0000 }, + { 0x0700, 0x06cb, 0x0000 }, + { 0x8700, 0x06d0, 0x3000 }, + { 0x8700, 0x06ce, 0x2000 }, + { 0x0700, 0x06cd, 0x0000 }, + { 0x0700, 0x06cf, 0x0000 }, + { 0x8700, 0x06d2, 0x2000 }, + { 0x0700, 0x06d1, 0x0000 }, + { 0x0700, 0x06d3, 0x0000 }, + { 0x8c00, 0x06dc, 0x4000 }, + { 0x8c00, 0x06d8, 0x3000 }, + { 0x8c00, 0x06d6, 0x2000 }, + { 0x0700, 0x06d5, 0x0000 }, + { 0x0c00, 0x06d7, 0x0000 }, + { 0x8c00, 0x06da, 0x2000 }, + { 0x0c00, 0x06d9, 0x0000 }, + { 0x0c00, 0x06db, 0x0000 }, + { 0x8c00, 0x06e0, 0x3000 }, + { 0x8b00, 0x06de, 0x2000 }, + { 0x0100, 0x06dd, 0x0000 }, + { 0x0c00, 0x06df, 0x0000 }, + { 0x8c00, 0x06e2, 0x2000 }, + { 0x0c00, 0x06e1, 0x0000 }, + { 0x0c00, 0x06e3, 0x0000 }, + { 0x9500, 0x0704, 0x6000 }, + { 0x8d00, 0x06f4, 0x5000 }, + { 0x8c00, 0x06ec, 0x4000 }, + { 0x8c00, 0x06e8, 0x3000 }, + { 0x8600, 0x06e6, 0x2000 }, + { 0x0600, 0x06e5, 0x0000 }, + { 0x0c00, 0x06e7, 0x0000 }, + { 0x8c00, 0x06ea, 0x2000 }, + { 0x1a00, 0x06e9, 0x0000 }, + { 0x0c00, 0x06eb, 0x0000 }, + { 0x8d00, 0x06f0, 0x3000 }, + { 0x8700, 0x06ee, 0x2000 }, + { 0x0c00, 0x06ed, 0x0000 }, + { 0x0700, 0x06ef, 0x0000 }, + { 0x8d00, 0x06f2, 0x2000 }, + { 0x0d00, 0x06f1, 0x0000 }, + { 0x0d00, 0x06f3, 0x0000 }, + { 0x8700, 0x06fc, 0x4000 }, + { 0x8d00, 0x06f8, 0x3000 }, + { 0x8d00, 0x06f6, 0x2000 }, + { 0x0d00, 0x06f5, 0x0000 }, + { 0x0d00, 0x06f7, 0x0000 }, + { 0x8700, 0x06fa, 0x2000 }, + { 0x0d00, 0x06f9, 0x0000 }, + { 0x0700, 0x06fb, 0x0000 }, + { 0x9500, 0x0700, 0x3000 }, + { 0x9a00, 0x06fe, 0x2000 }, + { 0x1a00, 0x06fd, 0x0000 }, + { 0x0700, 0x06ff, 0x0000 }, + { 0x9500, 0x0702, 0x2000 }, + { 0x1500, 0x0701, 0x0000 }, + { 0x1500, 0x0703, 0x0000 }, + { 0x8700, 0x0715, 0x5000 }, + { 0x9500, 0x070c, 0x4000 }, + { 0x9500, 0x0708, 0x3000 }, + { 0x9500, 0x0706, 0x2000 }, + { 0x1500, 0x0705, 0x0000 }, + { 0x1500, 0x0707, 0x0000 }, + { 0x9500, 0x070a, 0x2000 }, + { 0x1500, 0x0709, 0x0000 }, + { 0x1500, 0x070b, 0x0000 }, + { 0x8c00, 0x0711, 0x3000 }, + { 0x8100, 0x070f, 0x2000 }, + { 0x1500, 0x070d, 0x0000 }, + { 0x0700, 0x0710, 0x0000 }, + { 0x8700, 0x0713, 0x2000 }, + { 0x0700, 0x0712, 0x0000 }, + { 0x0700, 0x0714, 0x0000 }, + { 0x8700, 0x071d, 0x4000 }, + { 0x8700, 0x0719, 0x3000 }, + { 0x8700, 0x0717, 0x2000 }, + { 0x0700, 0x0716, 0x0000 }, + { 0x0700, 0x0718, 0x0000 }, + { 0x8700, 0x071b, 0x2000 }, + { 0x0700, 0x071a, 0x0000 }, + { 0x0700, 0x071c, 0x0000 }, + { 0x8700, 0x0721, 0x3000 }, + { 0x8700, 0x071f, 0x2000 }, + { 0x0700, 0x071e, 0x0000 }, + { 0x0700, 0x0720, 0x0000 }, + { 0x8700, 0x0723, 0x2000 }, + { 0x0700, 0x0722, 0x0000 }, + { 0x0700, 0x0724, 0x0000 }, + { 0x8700, 0x0797, 0x7000 }, + { 0x8c00, 0x0745, 0x6000 }, + { 0x8c00, 0x0735, 0x5000 }, + { 0x8700, 0x072d, 0x4000 }, + { 0x8700, 0x0729, 0x3000 }, + { 0x8700, 0x0727, 0x2000 }, + { 0x0700, 0x0726, 0x0000 }, + { 0x0700, 0x0728, 0x0000 }, + { 0x8700, 0x072b, 0x2000 }, + { 0x0700, 0x072a, 0x0000 }, + { 0x0700, 0x072c, 0x0000 }, + { 0x8c00, 0x0731, 0x3000 }, + { 0x8700, 0x072f, 0x2000 }, + { 0x0700, 0x072e, 0x0000 }, + { 0x0c00, 0x0730, 0x0000 }, + { 0x8c00, 0x0733, 0x2000 }, + { 0x0c00, 0x0732, 0x0000 }, + { 0x0c00, 0x0734, 0x0000 }, + { 0x8c00, 0x073d, 0x4000 }, + { 0x8c00, 0x0739, 0x3000 }, + { 0x8c00, 0x0737, 0x2000 }, + { 0x0c00, 0x0736, 0x0000 }, + { 0x0c00, 0x0738, 0x0000 }, + { 0x8c00, 0x073b, 0x2000 }, + { 0x0c00, 0x073a, 0x0000 }, + { 0x0c00, 0x073c, 0x0000 }, + { 0x8c00, 0x0741, 0x3000 }, + { 0x8c00, 0x073f, 0x2000 }, + { 0x0c00, 0x073e, 0x0000 }, + { 0x0c00, 0x0740, 0x0000 }, + { 0x8c00, 0x0743, 0x2000 }, + { 0x0c00, 0x0742, 0x0000 }, + { 0x0c00, 0x0744, 0x0000 }, + { 0x8700, 0x0787, 0x5000 }, + { 0x8700, 0x074f, 0x4000 }, + { 0x8c00, 0x0749, 0x3000 }, + { 0x8c00, 0x0747, 0x2000 }, + { 0x0c00, 0x0746, 0x0000 }, + { 0x0c00, 0x0748, 0x0000 }, + { 0x8700, 0x074d, 0x2000 }, + { 0x0c00, 0x074a, 0x0000 }, + { 0x0700, 0x074e, 0x0000 }, + { 0x8700, 0x0783, 0x3000 }, + { 0x8700, 0x0781, 0x2000 }, + { 0x0700, 0x0780, 0x0000 }, + { 0x0700, 0x0782, 0x0000 }, + { 0x8700, 0x0785, 0x2000 }, + { 0x0700, 0x0784, 0x0000 }, + { 0x0700, 0x0786, 0x0000 }, + { 0x8700, 0x078f, 0x4000 }, + { 0x8700, 0x078b, 0x3000 }, + { 0x8700, 0x0789, 0x2000 }, + { 0x0700, 0x0788, 0x0000 }, + { 0x0700, 0x078a, 0x0000 }, + { 0x8700, 0x078d, 0x2000 }, + { 0x0700, 0x078c, 0x0000 }, + { 0x0700, 0x078e, 0x0000 }, + { 0x8700, 0x0793, 0x3000 }, + { 0x8700, 0x0791, 0x2000 }, + { 0x0700, 0x0790, 0x0000 }, + { 0x0700, 0x0792, 0x0000 }, + { 0x8700, 0x0795, 0x2000 }, + { 0x0700, 0x0794, 0x0000 }, + { 0x0700, 0x0796, 0x0000 }, + { 0x8700, 0x0906, 0x6000 }, + { 0x8c00, 0x07a7, 0x5000 }, + { 0x8700, 0x079f, 0x4000 }, + { 0x8700, 0x079b, 0x3000 }, + { 0x8700, 0x0799, 0x2000 }, + { 0x0700, 0x0798, 0x0000 }, + { 0x0700, 0x079a, 0x0000 }, + { 0x8700, 0x079d, 0x2000 }, + { 0x0700, 0x079c, 0x0000 }, + { 0x0700, 0x079e, 0x0000 }, + { 0x8700, 0x07a3, 0x3000 }, + { 0x8700, 0x07a1, 0x2000 }, + { 0x0700, 0x07a0, 0x0000 }, + { 0x0700, 0x07a2, 0x0000 }, + { 0x8700, 0x07a5, 0x2000 }, + { 0x0700, 0x07a4, 0x0000 }, + { 0x0c00, 0x07a6, 0x0000 }, + { 0x8c00, 0x07af, 0x4000 }, + { 0x8c00, 0x07ab, 0x3000 }, + { 0x8c00, 0x07a9, 0x2000 }, + { 0x0c00, 0x07a8, 0x0000 }, + { 0x0c00, 0x07aa, 0x0000 }, + { 0x8c00, 0x07ad, 0x2000 }, + { 0x0c00, 0x07ac, 0x0000 }, + { 0x0c00, 0x07ae, 0x0000 }, + { 0x8c00, 0x0902, 0x3000 }, + { 0x8700, 0x07b1, 0x2000 }, + { 0x0c00, 0x07b0, 0x0000 }, + { 0x0c00, 0x0901, 0x0000 }, + { 0x8700, 0x0904, 0x2000 }, + { 0x0a00, 0x0903, 0x0000 }, + { 0x0700, 0x0905, 0x0000 }, + { 0x8700, 0x0916, 0x5000 }, + { 0x8700, 0x090e, 0x4000 }, + { 0x8700, 0x090a, 0x3000 }, + { 0x8700, 0x0908, 0x2000 }, + { 0x0700, 0x0907, 0x0000 }, + { 0x0700, 0x0909, 0x0000 }, + { 0x8700, 0x090c, 0x2000 }, + { 0x0700, 0x090b, 0x0000 }, + { 0x0700, 0x090d, 0x0000 }, + { 0x8700, 0x0912, 0x3000 }, + { 0x8700, 0x0910, 0x2000 }, + { 0x0700, 0x090f, 0x0000 }, + { 0x0700, 0x0911, 0x0000 }, + { 0x8700, 0x0914, 0x2000 }, + { 0x0700, 0x0913, 0x0000 }, + { 0x0700, 0x0915, 0x0000 }, + { 0x8700, 0x091e, 0x4000 }, + { 0x8700, 0x091a, 0x3000 }, + { 0x8700, 0x0918, 0x2000 }, + { 0x0700, 0x0917, 0x0000 }, + { 0x0700, 0x0919, 0x0000 }, + { 0x8700, 0x091c, 0x2000 }, + { 0x0700, 0x091b, 0x0000 }, + { 0x0700, 0x091d, 0x0000 }, + { 0x8700, 0x0922, 0x3000 }, + { 0x8700, 0x0920, 0x2000 }, + { 0x0700, 0x091f, 0x0000 }, + { 0x0700, 0x0921, 0x0000 }, + { 0x8700, 0x0924, 0x2000 }, + { 0x0700, 0x0923, 0x0000 }, + { 0x0700, 0x0925, 0x0000 }, + { 0x8c00, 0x09cd, 0x8000 }, + { 0x8d00, 0x096d, 0x7000 }, + { 0x8c00, 0x0948, 0x6000 }, + { 0x8700, 0x0936, 0x5000 }, + { 0x8700, 0x092e, 0x4000 }, + { 0x8700, 0x092a, 0x3000 }, + { 0x8700, 0x0928, 0x2000 }, + { 0x0700, 0x0927, 0x0000 }, + { 0x0700, 0x0929, 0x0000 }, + { 0x8700, 0x092c, 0x2000 }, + { 0x0700, 0x092b, 0x0000 }, + { 0x0700, 0x092d, 0x0000 }, + { 0x8700, 0x0932, 0x3000 }, + { 0x8700, 0x0930, 0x2000 }, + { 0x0700, 0x092f, 0x0000 }, + { 0x0700, 0x0931, 0x0000 }, + { 0x8700, 0x0934, 0x2000 }, + { 0x0700, 0x0933, 0x0000 }, + { 0x0700, 0x0935, 0x0000 }, + { 0x8a00, 0x0940, 0x4000 }, + { 0x8c00, 0x093c, 0x3000 }, + { 0x8700, 0x0938, 0x2000 }, + { 0x0700, 0x0937, 0x0000 }, + { 0x0700, 0x0939, 0x0000 }, + { 0x8a00, 0x093e, 0x2000 }, + { 0x0700, 0x093d, 0x0000 }, + { 0x0a00, 0x093f, 0x0000 }, + { 0x8c00, 0x0944, 0x3000 }, + { 0x8c00, 0x0942, 0x2000 }, + { 0x0c00, 0x0941, 0x0000 }, + { 0x0c00, 0x0943, 0x0000 }, + { 0x8c00, 0x0946, 0x2000 }, + { 0x0c00, 0x0945, 0x0000 }, + { 0x0c00, 0x0947, 0x0000 }, + { 0x8700, 0x095d, 0x5000 }, + { 0x8c00, 0x0952, 0x4000 }, + { 0x8a00, 0x094c, 0x3000 }, + { 0x8a00, 0x094a, 0x2000 }, + { 0x0a00, 0x0949, 0x0000 }, + { 0x0a00, 0x094b, 0x0000 }, + { 0x8700, 0x0950, 0x2000 }, + { 0x0c00, 0x094d, 0x0000 }, + { 0x0c00, 0x0951, 0x0000 }, + { 0x8700, 0x0959, 0x3000 }, + { 0x8c00, 0x0954, 0x2000 }, + { 0x0c00, 0x0953, 0x0000 }, + { 0x0700, 0x0958, 0x0000 }, + { 0x8700, 0x095b, 0x2000 }, + { 0x0700, 0x095a, 0x0000 }, + { 0x0700, 0x095c, 0x0000 }, + { 0x9500, 0x0965, 0x4000 }, + { 0x8700, 0x0961, 0x3000 }, + { 0x8700, 0x095f, 0x2000 }, + { 0x0700, 0x095e, 0x0000 }, + { 0x0700, 0x0960, 0x0000 }, + { 0x8c00, 0x0963, 0x2000 }, + { 0x0c00, 0x0962, 0x0000 }, + { 0x1500, 0x0964, 0x0000 }, + { 0x8d00, 0x0969, 0x3000 }, + { 0x8d00, 0x0967, 0x2000 }, + { 0x0d00, 0x0966, 0x0000 }, + { 0x0d00, 0x0968, 0x0000 }, + { 0x8d00, 0x096b, 0x2000 }, + { 0x0d00, 0x096a, 0x0000 }, + { 0x0d00, 0x096c, 0x0000 }, + { 0x8700, 0x09a2, 0x6000 }, + { 0x8700, 0x0990, 0x5000 }, + { 0x8700, 0x0986, 0x4000 }, + { 0x8c00, 0x0981, 0x3000 }, + { 0x8d00, 0x096f, 0x2000 }, + { 0x0d00, 0x096e, 0x0000 }, + { 0x1500, 0x0970, 0x0000 }, + { 0x8a00, 0x0983, 0x2000 }, + { 0x0a00, 0x0982, 0x0000 }, + { 0x0700, 0x0985, 0x0000 }, + { 0x8700, 0x098a, 0x3000 }, + { 0x8700, 0x0988, 0x2000 }, + { 0x0700, 0x0987, 0x0000 }, + { 0x0700, 0x0989, 0x0000 }, + { 0x8700, 0x098c, 0x2000 }, + { 0x0700, 0x098b, 0x0000 }, + { 0x0700, 0x098f, 0x0000 }, + { 0x8700, 0x099a, 0x4000 }, + { 0x8700, 0x0996, 0x3000 }, + { 0x8700, 0x0994, 0x2000 }, + { 0x0700, 0x0993, 0x0000 }, + { 0x0700, 0x0995, 0x0000 }, + { 0x8700, 0x0998, 0x2000 }, + { 0x0700, 0x0997, 0x0000 }, + { 0x0700, 0x0999, 0x0000 }, + { 0x8700, 0x099e, 0x3000 }, + { 0x8700, 0x099c, 0x2000 }, + { 0x0700, 0x099b, 0x0000 }, + { 0x0700, 0x099d, 0x0000 }, + { 0x8700, 0x09a0, 0x2000 }, + { 0x0700, 0x099f, 0x0000 }, + { 0x0700, 0x09a1, 0x0000 }, + { 0x8700, 0x09b7, 0x5000 }, + { 0x8700, 0x09ab, 0x4000 }, + { 0x8700, 0x09a6, 0x3000 }, + { 0x8700, 0x09a4, 0x2000 }, + { 0x0700, 0x09a3, 0x0000 }, + { 0x0700, 0x09a5, 0x0000 }, + { 0x8700, 0x09a8, 0x2000 }, + { 0x0700, 0x09a7, 0x0000 }, + { 0x0700, 0x09aa, 0x0000 }, + { 0x8700, 0x09af, 0x3000 }, + { 0x8700, 0x09ad, 0x2000 }, + { 0x0700, 0x09ac, 0x0000 }, + { 0x0700, 0x09ae, 0x0000 }, + { 0x8700, 0x09b2, 0x2000 }, + { 0x0700, 0x09b0, 0x0000 }, + { 0x0700, 0x09b6, 0x0000 }, + { 0x8c00, 0x09c1, 0x4000 }, + { 0x8700, 0x09bd, 0x3000 }, + { 0x8700, 0x09b9, 0x2000 }, + { 0x0700, 0x09b8, 0x0000 }, + { 0x0c00, 0x09bc, 0x0000 }, + { 0x8a00, 0x09bf, 0x2000 }, + { 0x0a00, 0x09be, 0x0000 }, + { 0x0a00, 0x09c0, 0x0000 }, + { 0x8a00, 0x09c7, 0x3000 }, + { 0x8c00, 0x09c3, 0x2000 }, + { 0x0c00, 0x09c2, 0x0000 }, + { 0x0c00, 0x09c4, 0x0000 }, + { 0x8a00, 0x09cb, 0x2000 }, + { 0x0a00, 0x09c8, 0x0000 }, + { 0x0a00, 0x09cc, 0x0000 }, + { 0x8700, 0x0a2b, 0x7000 }, + { 0x8a00, 0x0a03, 0x6000 }, + { 0x8d00, 0x09ed, 0x5000 }, + { 0x8c00, 0x09e3, 0x4000 }, + { 0x8700, 0x09df, 0x3000 }, + { 0x8700, 0x09dc, 0x2000 }, + { 0x0a00, 0x09d7, 0x0000 }, + { 0x0700, 0x09dd, 0x0000 }, + { 0x8700, 0x09e1, 0x2000 }, + { 0x0700, 0x09e0, 0x0000 }, + { 0x0c00, 0x09e2, 0x0000 }, + { 0x8d00, 0x09e9, 0x3000 }, + { 0x8d00, 0x09e7, 0x2000 }, + { 0x0d00, 0x09e6, 0x0000 }, + { 0x0d00, 0x09e8, 0x0000 }, + { 0x8d00, 0x09eb, 0x2000 }, + { 0x0d00, 0x09ea, 0x0000 }, + { 0x0d00, 0x09ec, 0x0000 }, + { 0x8f00, 0x09f5, 0x4000 }, + { 0x8700, 0x09f1, 0x3000 }, + { 0x8d00, 0x09ef, 0x2000 }, + { 0x0d00, 0x09ee, 0x0000 }, + { 0x0700, 0x09f0, 0x0000 }, + { 0x9700, 0x09f3, 0x2000 }, + { 0x1700, 0x09f2, 0x0000 }, + { 0x0f00, 0x09f4, 0x0000 }, + { 0x8f00, 0x09f9, 0x3000 }, + { 0x8f00, 0x09f7, 0x2000 }, + { 0x0f00, 0x09f6, 0x0000 }, + { 0x0f00, 0x09f8, 0x0000 }, + { 0x8c00, 0x0a01, 0x2000 }, + { 0x1a00, 0x09fa, 0x0000 }, + { 0x0c00, 0x0a02, 0x0000 }, + { 0x8700, 0x0a1a, 0x5000 }, + { 0x8700, 0x0a10, 0x4000 }, + { 0x8700, 0x0a08, 0x3000 }, + { 0x8700, 0x0a06, 0x2000 }, + { 0x0700, 0x0a05, 0x0000 }, + { 0x0700, 0x0a07, 0x0000 }, + { 0x8700, 0x0a0a, 0x2000 }, + { 0x0700, 0x0a09, 0x0000 }, + { 0x0700, 0x0a0f, 0x0000 }, + { 0x8700, 0x0a16, 0x3000 }, + { 0x8700, 0x0a14, 0x2000 }, + { 0x0700, 0x0a13, 0x0000 }, + { 0x0700, 0x0a15, 0x0000 }, + { 0x8700, 0x0a18, 0x2000 }, + { 0x0700, 0x0a17, 0x0000 }, + { 0x0700, 0x0a19, 0x0000 }, + { 0x8700, 0x0a22, 0x4000 }, + { 0x8700, 0x0a1e, 0x3000 }, + { 0x8700, 0x0a1c, 0x2000 }, + { 0x0700, 0x0a1b, 0x0000 }, + { 0x0700, 0x0a1d, 0x0000 }, + { 0x8700, 0x0a20, 0x2000 }, + { 0x0700, 0x0a1f, 0x0000 }, + { 0x0700, 0x0a21, 0x0000 }, + { 0x8700, 0x0a26, 0x3000 }, + { 0x8700, 0x0a24, 0x2000 }, + { 0x0700, 0x0a23, 0x0000 }, + { 0x0700, 0x0a25, 0x0000 }, + { 0x8700, 0x0a28, 0x2000 }, + { 0x0700, 0x0a27, 0x0000 }, + { 0x0700, 0x0a2a, 0x0000 }, + { 0x8d00, 0x0a6a, 0x6000 }, + { 0x8c00, 0x0a41, 0x5000 }, + { 0x8700, 0x0a35, 0x4000 }, + { 0x8700, 0x0a2f, 0x3000 }, + { 0x8700, 0x0a2d, 0x2000 }, + { 0x0700, 0x0a2c, 0x0000 }, + { 0x0700, 0x0a2e, 0x0000 }, + { 0x8700, 0x0a32, 0x2000 }, + { 0x0700, 0x0a30, 0x0000 }, + { 0x0700, 0x0a33, 0x0000 }, + { 0x8c00, 0x0a3c, 0x3000 }, + { 0x8700, 0x0a38, 0x2000 }, + { 0x0700, 0x0a36, 0x0000 }, + { 0x0700, 0x0a39, 0x0000 }, + { 0x8a00, 0x0a3f, 0x2000 }, + { 0x0a00, 0x0a3e, 0x0000 }, + { 0x0a00, 0x0a40, 0x0000 }, + { 0x8700, 0x0a5a, 0x4000 }, + { 0x8c00, 0x0a4b, 0x3000 }, + { 0x8c00, 0x0a47, 0x2000 }, + { 0x0c00, 0x0a42, 0x0000 }, + { 0x0c00, 0x0a48, 0x0000 }, + { 0x8c00, 0x0a4d, 0x2000 }, + { 0x0c00, 0x0a4c, 0x0000 }, + { 0x0700, 0x0a59, 0x0000 }, + { 0x8d00, 0x0a66, 0x3000 }, + { 0x8700, 0x0a5c, 0x2000 }, + { 0x0700, 0x0a5b, 0x0000 }, + { 0x0700, 0x0a5e, 0x0000 }, + { 0x8d00, 0x0a68, 0x2000 }, + { 0x0d00, 0x0a67, 0x0000 }, + { 0x0d00, 0x0a69, 0x0000 }, + { 0x8700, 0x0a87, 0x5000 }, + { 0x8700, 0x0a72, 0x4000 }, + { 0x8d00, 0x0a6e, 0x3000 }, + { 0x8d00, 0x0a6c, 0x2000 }, + { 0x0d00, 0x0a6b, 0x0000 }, + { 0x0d00, 0x0a6d, 0x0000 }, + { 0x8c00, 0x0a70, 0x2000 }, + { 0x0d00, 0x0a6f, 0x0000 }, + { 0x0c00, 0x0a71, 0x0000 }, + { 0x8c00, 0x0a82, 0x3000 }, + { 0x8700, 0x0a74, 0x2000 }, + { 0x0700, 0x0a73, 0x0000 }, + { 0x0c00, 0x0a81, 0x0000 }, + { 0x8700, 0x0a85, 0x2000 }, + { 0x0a00, 0x0a83, 0x0000 }, + { 0x0700, 0x0a86, 0x0000 }, + { 0x8700, 0x0a90, 0x4000 }, + { 0x8700, 0x0a8b, 0x3000 }, + { 0x8700, 0x0a89, 0x2000 }, + { 0x0700, 0x0a88, 0x0000 }, + { 0x0700, 0x0a8a, 0x0000 }, + { 0x8700, 0x0a8d, 0x2000 }, + { 0x0700, 0x0a8c, 0x0000 }, + { 0x0700, 0x0a8f, 0x0000 }, + { 0x8700, 0x0a95, 0x3000 }, + { 0x8700, 0x0a93, 0x2000 }, + { 0x0700, 0x0a91, 0x0000 }, + { 0x0700, 0x0a94, 0x0000 }, + { 0x8700, 0x0a97, 0x2000 }, + { 0x0700, 0x0a96, 0x0000 }, + { 0x0700, 0x0a98, 0x0000 }, + { 0x8700, 0x10ef, 0xb000 }, + { 0x8700, 0x0dc6, 0xa000 }, + { 0x8700, 0x0c31, 0x9000 }, + { 0x8700, 0x0b5f, 0x8000 }, + { 0x8a00, 0x0b03, 0x7000 }, + { 0x8a00, 0x0abe, 0x6000 }, + { 0x8700, 0x0aaa, 0x5000 }, + { 0x8700, 0x0aa1, 0x4000 }, + { 0x8700, 0x0a9d, 0x3000 }, + { 0x8700, 0x0a9b, 0x2000 }, + { 0x0700, 0x0a9a, 0x0000 }, + { 0x0700, 0x0a9c, 0x0000 }, + { 0x8700, 0x0a9f, 0x2000 }, + { 0x0700, 0x0a9e, 0x0000 }, + { 0x0700, 0x0aa0, 0x0000 }, + { 0x8700, 0x0aa5, 0x3000 }, + { 0x8700, 0x0aa3, 0x2000 }, + { 0x0700, 0x0aa2, 0x0000 }, + { 0x0700, 0x0aa4, 0x0000 }, + { 0x8700, 0x0aa7, 0x2000 }, + { 0x0700, 0x0aa6, 0x0000 }, + { 0x0700, 0x0aa8, 0x0000 }, + { 0x8700, 0x0ab3, 0x4000 }, + { 0x8700, 0x0aae, 0x3000 }, + { 0x8700, 0x0aac, 0x2000 }, + { 0x0700, 0x0aab, 0x0000 }, + { 0x0700, 0x0aad, 0x0000 }, + { 0x8700, 0x0ab0, 0x2000 }, + { 0x0700, 0x0aaf, 0x0000 }, + { 0x0700, 0x0ab2, 0x0000 }, + { 0x8700, 0x0ab8, 0x3000 }, + { 0x8700, 0x0ab6, 0x2000 }, + { 0x0700, 0x0ab5, 0x0000 }, + { 0x0700, 0x0ab7, 0x0000 }, + { 0x8c00, 0x0abc, 0x2000 }, + { 0x0700, 0x0ab9, 0x0000 }, + { 0x0700, 0x0abd, 0x0000 }, + { 0x8700, 0x0ae1, 0x5000 }, + { 0x8c00, 0x0ac7, 0x4000 }, + { 0x8c00, 0x0ac2, 0x3000 }, + { 0x8a00, 0x0ac0, 0x2000 }, + { 0x0a00, 0x0abf, 0x0000 }, + { 0x0c00, 0x0ac1, 0x0000 }, + { 0x8c00, 0x0ac4, 0x2000 }, + { 0x0c00, 0x0ac3, 0x0000 }, + { 0x0c00, 0x0ac5, 0x0000 }, + { 0x8a00, 0x0acc, 0x3000 }, + { 0x8a00, 0x0ac9, 0x2000 }, + { 0x0c00, 0x0ac8, 0x0000 }, + { 0x0a00, 0x0acb, 0x0000 }, + { 0x8700, 0x0ad0, 0x2000 }, + { 0x0c00, 0x0acd, 0x0000 }, + { 0x0700, 0x0ae0, 0x0000 }, + { 0x8d00, 0x0aeb, 0x4000 }, + { 0x8d00, 0x0ae7, 0x3000 }, + { 0x8c00, 0x0ae3, 0x2000 }, + { 0x0c00, 0x0ae2, 0x0000 }, + { 0x0d00, 0x0ae6, 0x0000 }, + { 0x8d00, 0x0ae9, 0x2000 }, + { 0x0d00, 0x0ae8, 0x0000 }, + { 0x0d00, 0x0aea, 0x0000 }, + { 0x8d00, 0x0aef, 0x3000 }, + { 0x8d00, 0x0aed, 0x2000 }, + { 0x0d00, 0x0aec, 0x0000 }, + { 0x0d00, 0x0aee, 0x0000 }, + { 0x8c00, 0x0b01, 0x2000 }, + { 0x1700, 0x0af1, 0x0000 }, + { 0x0a00, 0x0b02, 0x0000 }, + { 0x8700, 0x0b28, 0x6000 }, + { 0x8700, 0x0b18, 0x5000 }, + { 0x8700, 0x0b0c, 0x4000 }, + { 0x8700, 0x0b08, 0x3000 }, + { 0x8700, 0x0b06, 0x2000 }, + { 0x0700, 0x0b05, 0x0000 }, + { 0x0700, 0x0b07, 0x0000 }, + { 0x8700, 0x0b0a, 0x2000 }, + { 0x0700, 0x0b09, 0x0000 }, + { 0x0700, 0x0b0b, 0x0000 }, + { 0x8700, 0x0b14, 0x3000 }, + { 0x8700, 0x0b10, 0x2000 }, + { 0x0700, 0x0b0f, 0x0000 }, + { 0x0700, 0x0b13, 0x0000 }, + { 0x8700, 0x0b16, 0x2000 }, + { 0x0700, 0x0b15, 0x0000 }, + { 0x0700, 0x0b17, 0x0000 }, + { 0x8700, 0x0b20, 0x4000 }, + { 0x8700, 0x0b1c, 0x3000 }, + { 0x8700, 0x0b1a, 0x2000 }, + { 0x0700, 0x0b19, 0x0000 }, + { 0x0700, 0x0b1b, 0x0000 }, + { 0x8700, 0x0b1e, 0x2000 }, + { 0x0700, 0x0b1d, 0x0000 }, + { 0x0700, 0x0b1f, 0x0000 }, + { 0x8700, 0x0b24, 0x3000 }, + { 0x8700, 0x0b22, 0x2000 }, + { 0x0700, 0x0b21, 0x0000 }, + { 0x0700, 0x0b23, 0x0000 }, + { 0x8700, 0x0b26, 0x2000 }, + { 0x0700, 0x0b25, 0x0000 }, + { 0x0700, 0x0b27, 0x0000 }, + { 0x8700, 0x0b3d, 0x5000 }, + { 0x8700, 0x0b32, 0x4000 }, + { 0x8700, 0x0b2d, 0x3000 }, + { 0x8700, 0x0b2b, 0x2000 }, + { 0x0700, 0x0b2a, 0x0000 }, + { 0x0700, 0x0b2c, 0x0000 }, + { 0x8700, 0x0b2f, 0x2000 }, + { 0x0700, 0x0b2e, 0x0000 }, + { 0x0700, 0x0b30, 0x0000 }, + { 0x8700, 0x0b37, 0x3000 }, + { 0x8700, 0x0b35, 0x2000 }, + { 0x0700, 0x0b33, 0x0000 }, + { 0x0700, 0x0b36, 0x0000 }, + { 0x8700, 0x0b39, 0x2000 }, + { 0x0700, 0x0b38, 0x0000 }, + { 0x0c00, 0x0b3c, 0x0000 }, + { 0x8a00, 0x0b48, 0x4000 }, + { 0x8c00, 0x0b41, 0x3000 }, + { 0x8c00, 0x0b3f, 0x2000 }, + { 0x0a00, 0x0b3e, 0x0000 }, + { 0x0a00, 0x0b40, 0x0000 }, + { 0x8c00, 0x0b43, 0x2000 }, + { 0x0c00, 0x0b42, 0x0000 }, + { 0x0a00, 0x0b47, 0x0000 }, + { 0x8c00, 0x0b56, 0x3000 }, + { 0x8a00, 0x0b4c, 0x2000 }, + { 0x0a00, 0x0b4b, 0x0000 }, + { 0x0c00, 0x0b4d, 0x0000 }, + { 0x8700, 0x0b5c, 0x2000 }, + { 0x0a00, 0x0b57, 0x0000 }, + { 0x0700, 0x0b5d, 0x0000 }, + { 0x8d00, 0x0be7, 0x7000 }, + { 0x8700, 0x0b9c, 0x6000 }, + { 0x8700, 0x0b83, 0x5000 }, + { 0x8d00, 0x0b6b, 0x4000 }, + { 0x8d00, 0x0b67, 0x3000 }, + { 0x8700, 0x0b61, 0x2000 }, + { 0x0700, 0x0b60, 0x0000 }, + { 0x0d00, 0x0b66, 0x0000 }, + { 0x8d00, 0x0b69, 0x2000 }, + { 0x0d00, 0x0b68, 0x0000 }, + { 0x0d00, 0x0b6a, 0x0000 }, + { 0x8d00, 0x0b6f, 0x3000 }, + { 0x8d00, 0x0b6d, 0x2000 }, + { 0x0d00, 0x0b6c, 0x0000 }, + { 0x0d00, 0x0b6e, 0x0000 }, + { 0x8700, 0x0b71, 0x2000 }, + { 0x1a00, 0x0b70, 0x0000 }, + { 0x0c00, 0x0b82, 0x0000 }, + { 0x8700, 0x0b8f, 0x4000 }, + { 0x8700, 0x0b88, 0x3000 }, + { 0x8700, 0x0b86, 0x2000 }, + { 0x0700, 0x0b85, 0x0000 }, + { 0x0700, 0x0b87, 0x0000 }, + { 0x8700, 0x0b8a, 0x2000 }, + { 0x0700, 0x0b89, 0x0000 }, + { 0x0700, 0x0b8e, 0x0000 }, + { 0x8700, 0x0b94, 0x3000 }, + { 0x8700, 0x0b92, 0x2000 }, + { 0x0700, 0x0b90, 0x0000 }, + { 0x0700, 0x0b93, 0x0000 }, + { 0x8700, 0x0b99, 0x2000 }, + { 0x0700, 0x0b95, 0x0000 }, + { 0x0700, 0x0b9a, 0x0000 }, + { 0x8700, 0x0bb7, 0x5000 }, + { 0x8700, 0x0bae, 0x4000 }, + { 0x8700, 0x0ba4, 0x3000 }, + { 0x8700, 0x0b9f, 0x2000 }, + { 0x0700, 0x0b9e, 0x0000 }, + { 0x0700, 0x0ba3, 0x0000 }, + { 0x8700, 0x0ba9, 0x2000 }, + { 0x0700, 0x0ba8, 0x0000 }, + { 0x0700, 0x0baa, 0x0000 }, + { 0x8700, 0x0bb2, 0x3000 }, + { 0x8700, 0x0bb0, 0x2000 }, + { 0x0700, 0x0baf, 0x0000 }, + { 0x0700, 0x0bb1, 0x0000 }, + { 0x8700, 0x0bb4, 0x2000 }, + { 0x0700, 0x0bb3, 0x0000 }, + { 0x0700, 0x0bb5, 0x0000 }, + { 0x8a00, 0x0bc6, 0x4000 }, + { 0x8a00, 0x0bbf, 0x3000 }, + { 0x8700, 0x0bb9, 0x2000 }, + { 0x0700, 0x0bb8, 0x0000 }, + { 0x0a00, 0x0bbe, 0x0000 }, + { 0x8a00, 0x0bc1, 0x2000 }, + { 0x0c00, 0x0bc0, 0x0000 }, + { 0x0a00, 0x0bc2, 0x0000 }, + { 0x8a00, 0x0bcb, 0x3000 }, + { 0x8a00, 0x0bc8, 0x2000 }, + { 0x0a00, 0x0bc7, 0x0000 }, + { 0x0a00, 0x0bca, 0x0000 }, + { 0x8c00, 0x0bcd, 0x2000 }, + { 0x0a00, 0x0bcc, 0x0000 }, + { 0x0a00, 0x0bd7, 0x0000 }, + { 0x8700, 0x0c0f, 0x6000 }, + { 0x9a00, 0x0bf7, 0x5000 }, + { 0x8d00, 0x0bef, 0x4000 }, + { 0x8d00, 0x0beb, 0x3000 }, + { 0x8d00, 0x0be9, 0x2000 }, + { 0x0d00, 0x0be8, 0x0000 }, + { 0x0d00, 0x0bea, 0x0000 }, + { 0x8d00, 0x0bed, 0x2000 }, + { 0x0d00, 0x0bec, 0x0000 }, + { 0x0d00, 0x0bee, 0x0000 }, + { 0x9a00, 0x0bf3, 0x3000 }, + { 0x8f00, 0x0bf1, 0x2000 }, + { 0x0f00, 0x0bf0, 0x0000 }, + { 0x0f00, 0x0bf2, 0x0000 }, + { 0x9a00, 0x0bf5, 0x2000 }, + { 0x1a00, 0x0bf4, 0x0000 }, + { 0x1a00, 0x0bf6, 0x0000 }, + { 0x8700, 0x0c06, 0x4000 }, + { 0x8a00, 0x0c01, 0x3000 }, + { 0x9700, 0x0bf9, 0x2000 }, + { 0x1a00, 0x0bf8, 0x0000 }, + { 0x1a00, 0x0bfa, 0x0000 }, + { 0x8a00, 0x0c03, 0x2000 }, + { 0x0a00, 0x0c02, 0x0000 }, + { 0x0700, 0x0c05, 0x0000 }, + { 0x8700, 0x0c0a, 0x3000 }, + { 0x8700, 0x0c08, 0x2000 }, + { 0x0700, 0x0c07, 0x0000 }, + { 0x0700, 0x0c09, 0x0000 }, + { 0x8700, 0x0c0c, 0x2000 }, + { 0x0700, 0x0c0b, 0x0000 }, + { 0x0700, 0x0c0e, 0x0000 }, + { 0x8700, 0x0c20, 0x5000 }, + { 0x8700, 0x0c18, 0x4000 }, + { 0x8700, 0x0c14, 0x3000 }, + { 0x8700, 0x0c12, 0x2000 }, + { 0x0700, 0x0c10, 0x0000 }, + { 0x0700, 0x0c13, 0x0000 }, + { 0x8700, 0x0c16, 0x2000 }, + { 0x0700, 0x0c15, 0x0000 }, + { 0x0700, 0x0c17, 0x0000 }, + { 0x8700, 0x0c1c, 0x3000 }, + { 0x8700, 0x0c1a, 0x2000 }, + { 0x0700, 0x0c19, 0x0000 }, + { 0x0700, 0x0c1b, 0x0000 }, + { 0x8700, 0x0c1e, 0x2000 }, + { 0x0700, 0x0c1d, 0x0000 }, + { 0x0700, 0x0c1f, 0x0000 }, + { 0x8700, 0x0c28, 0x4000 }, + { 0x8700, 0x0c24, 0x3000 }, + { 0x8700, 0x0c22, 0x2000 }, + { 0x0700, 0x0c21, 0x0000 }, + { 0x0700, 0x0c23, 0x0000 }, + { 0x8700, 0x0c26, 0x2000 }, + { 0x0700, 0x0c25, 0x0000 }, + { 0x0700, 0x0c27, 0x0000 }, + { 0x8700, 0x0c2d, 0x3000 }, + { 0x8700, 0x0c2b, 0x2000 }, + { 0x0700, 0x0c2a, 0x0000 }, + { 0x0700, 0x0c2c, 0x0000 }, + { 0x8700, 0x0c2f, 0x2000 }, + { 0x0700, 0x0c2e, 0x0000 }, + { 0x0700, 0x0c30, 0x0000 }, + { 0x8700, 0x0d0e, 0x8000 }, + { 0x8700, 0x0ca1, 0x7000 }, + { 0x8d00, 0x0c6c, 0x6000 }, + { 0x8c00, 0x0c47, 0x5000 }, + { 0x8c00, 0x0c3e, 0x4000 }, + { 0x8700, 0x0c36, 0x3000 }, + { 0x8700, 0x0c33, 0x2000 }, + { 0x0700, 0x0c32, 0x0000 }, + { 0x0700, 0x0c35, 0x0000 }, + { 0x8700, 0x0c38, 0x2000 }, + { 0x0700, 0x0c37, 0x0000 }, + { 0x0700, 0x0c39, 0x0000 }, + { 0x8a00, 0x0c42, 0x3000 }, + { 0x8c00, 0x0c40, 0x2000 }, + { 0x0c00, 0x0c3f, 0x0000 }, + { 0x0a00, 0x0c41, 0x0000 }, + { 0x8a00, 0x0c44, 0x2000 }, + { 0x0a00, 0x0c43, 0x0000 }, + { 0x0c00, 0x0c46, 0x0000 }, + { 0x8700, 0x0c60, 0x4000 }, + { 0x8c00, 0x0c4c, 0x3000 }, + { 0x8c00, 0x0c4a, 0x2000 }, + { 0x0c00, 0x0c48, 0x0000 }, + { 0x0c00, 0x0c4b, 0x0000 }, + { 0x8c00, 0x0c55, 0x2000 }, + { 0x0c00, 0x0c4d, 0x0000 }, + { 0x0c00, 0x0c56, 0x0000 }, + { 0x8d00, 0x0c68, 0x3000 }, + { 0x8d00, 0x0c66, 0x2000 }, + { 0x0700, 0x0c61, 0x0000 }, + { 0x0d00, 0x0c67, 0x0000 }, + { 0x8d00, 0x0c6a, 0x2000 }, + { 0x0d00, 0x0c69, 0x0000 }, + { 0x0d00, 0x0c6b, 0x0000 }, + { 0x8700, 0x0c90, 0x5000 }, + { 0x8700, 0x0c87, 0x4000 }, + { 0x8a00, 0x0c82, 0x3000 }, + { 0x8d00, 0x0c6e, 0x2000 }, + { 0x0d00, 0x0c6d, 0x0000 }, + { 0x0d00, 0x0c6f, 0x0000 }, + { 0x8700, 0x0c85, 0x2000 }, + { 0x0a00, 0x0c83, 0x0000 }, + { 0x0700, 0x0c86, 0x0000 }, + { 0x8700, 0x0c8b, 0x3000 }, + { 0x8700, 0x0c89, 0x2000 }, + { 0x0700, 0x0c88, 0x0000 }, + { 0x0700, 0x0c8a, 0x0000 }, + { 0x8700, 0x0c8e, 0x2000 }, + { 0x0700, 0x0c8c, 0x0000 }, + { 0x0700, 0x0c8f, 0x0000 }, + { 0x8700, 0x0c99, 0x4000 }, + { 0x8700, 0x0c95, 0x3000 }, + { 0x8700, 0x0c93, 0x2000 }, + { 0x0700, 0x0c92, 0x0000 }, + { 0x0700, 0x0c94, 0x0000 }, + { 0x8700, 0x0c97, 0x2000 }, + { 0x0700, 0x0c96, 0x0000 }, + { 0x0700, 0x0c98, 0x0000 }, + { 0x8700, 0x0c9d, 0x3000 }, + { 0x8700, 0x0c9b, 0x2000 }, + { 0x0700, 0x0c9a, 0x0000 }, + { 0x0700, 0x0c9c, 0x0000 }, + { 0x8700, 0x0c9f, 0x2000 }, + { 0x0700, 0x0c9e, 0x0000 }, + { 0x0700, 0x0ca0, 0x0000 }, + { 0x8c00, 0x0cc6, 0x6000 }, + { 0x8700, 0x0cb2, 0x5000 }, + { 0x8700, 0x0caa, 0x4000 }, + { 0x8700, 0x0ca5, 0x3000 }, + { 0x8700, 0x0ca3, 0x2000 }, + { 0x0700, 0x0ca2, 0x0000 }, + { 0x0700, 0x0ca4, 0x0000 }, + { 0x8700, 0x0ca7, 0x2000 }, + { 0x0700, 0x0ca6, 0x0000 }, + { 0x0700, 0x0ca8, 0x0000 }, + { 0x8700, 0x0cae, 0x3000 }, + { 0x8700, 0x0cac, 0x2000 }, + { 0x0700, 0x0cab, 0x0000 }, + { 0x0700, 0x0cad, 0x0000 }, + { 0x8700, 0x0cb0, 0x2000 }, + { 0x0700, 0x0caf, 0x0000 }, + { 0x0700, 0x0cb1, 0x0000 }, + { 0x8700, 0x0cbd, 0x4000 }, + { 0x8700, 0x0cb7, 0x3000 }, + { 0x8700, 0x0cb5, 0x2000 }, + { 0x0700, 0x0cb3, 0x0000 }, + { 0x0700, 0x0cb6, 0x0000 }, + { 0x8700, 0x0cb9, 0x2000 }, + { 0x0700, 0x0cb8, 0x0000 }, + { 0x0c00, 0x0cbc, 0x0000 }, + { 0x8a00, 0x0cc1, 0x3000 }, + { 0x8c00, 0x0cbf, 0x2000 }, + { 0x0a00, 0x0cbe, 0x0000 }, + { 0x0a00, 0x0cc0, 0x0000 }, + { 0x8a00, 0x0cc3, 0x2000 }, + { 0x0a00, 0x0cc2, 0x0000 }, + { 0x0a00, 0x0cc4, 0x0000 }, + { 0x8d00, 0x0cea, 0x5000 }, + { 0x8a00, 0x0cd6, 0x4000 }, + { 0x8a00, 0x0ccb, 0x3000 }, + { 0x8a00, 0x0cc8, 0x2000 }, + { 0x0a00, 0x0cc7, 0x0000 }, + { 0x0a00, 0x0cca, 0x0000 }, + { 0x8c00, 0x0ccd, 0x2000 }, + { 0x0c00, 0x0ccc, 0x0000 }, + { 0x0a00, 0x0cd5, 0x0000 }, + { 0x8d00, 0x0ce6, 0x3000 }, + { 0x8700, 0x0ce0, 0x2000 }, + { 0x0700, 0x0cde, 0x0000 }, + { 0x0700, 0x0ce1, 0x0000 }, + { 0x8d00, 0x0ce8, 0x2000 }, + { 0x0d00, 0x0ce7, 0x0000 }, + { 0x0d00, 0x0ce9, 0x0000 }, + { 0x8700, 0x0d05, 0x4000 }, + { 0x8d00, 0x0cee, 0x3000 }, + { 0x8d00, 0x0cec, 0x2000 }, + { 0x0d00, 0x0ceb, 0x0000 }, + { 0x0d00, 0x0ced, 0x0000 }, + { 0x8a00, 0x0d02, 0x2000 }, + { 0x0d00, 0x0cef, 0x0000 }, + { 0x0a00, 0x0d03, 0x0000 }, + { 0x8700, 0x0d09, 0x3000 }, + { 0x8700, 0x0d07, 0x2000 }, + { 0x0700, 0x0d06, 0x0000 }, + { 0x0700, 0x0d08, 0x0000 }, + { 0x8700, 0x0d0b, 0x2000 }, + { 0x0700, 0x0d0a, 0x0000 }, + { 0x0700, 0x0d0c, 0x0000 }, + { 0x8d00, 0x0d6c, 0x7000 }, + { 0x8700, 0x0d30, 0x6000 }, + { 0x8700, 0x0d1f, 0x5000 }, + { 0x8700, 0x0d17, 0x4000 }, + { 0x8700, 0x0d13, 0x3000 }, + { 0x8700, 0x0d10, 0x2000 }, + { 0x0700, 0x0d0f, 0x0000 }, + { 0x0700, 0x0d12, 0x0000 }, + { 0x8700, 0x0d15, 0x2000 }, + { 0x0700, 0x0d14, 0x0000 }, + { 0x0700, 0x0d16, 0x0000 }, + { 0x8700, 0x0d1b, 0x3000 }, + { 0x8700, 0x0d19, 0x2000 }, + { 0x0700, 0x0d18, 0x0000 }, + { 0x0700, 0x0d1a, 0x0000 }, + { 0x8700, 0x0d1d, 0x2000 }, + { 0x0700, 0x0d1c, 0x0000 }, + { 0x0700, 0x0d1e, 0x0000 }, + { 0x8700, 0x0d27, 0x4000 }, + { 0x8700, 0x0d23, 0x3000 }, + { 0x8700, 0x0d21, 0x2000 }, + { 0x0700, 0x0d20, 0x0000 }, + { 0x0700, 0x0d22, 0x0000 }, + { 0x8700, 0x0d25, 0x2000 }, + { 0x0700, 0x0d24, 0x0000 }, + { 0x0700, 0x0d26, 0x0000 }, + { 0x8700, 0x0d2c, 0x3000 }, + { 0x8700, 0x0d2a, 0x2000 }, + { 0x0700, 0x0d28, 0x0000 }, + { 0x0700, 0x0d2b, 0x0000 }, + { 0x8700, 0x0d2e, 0x2000 }, + { 0x0700, 0x0d2d, 0x0000 }, + { 0x0700, 0x0d2f, 0x0000 }, + { 0x8a00, 0x0d46, 0x5000 }, + { 0x8700, 0x0d38, 0x4000 }, + { 0x8700, 0x0d34, 0x3000 }, + { 0x8700, 0x0d32, 0x2000 }, + { 0x0700, 0x0d31, 0x0000 }, + { 0x0700, 0x0d33, 0x0000 }, + { 0x8700, 0x0d36, 0x2000 }, + { 0x0700, 0x0d35, 0x0000 }, + { 0x0700, 0x0d37, 0x0000 }, + { 0x8a00, 0x0d40, 0x3000 }, + { 0x8a00, 0x0d3e, 0x2000 }, + { 0x0700, 0x0d39, 0x0000 }, + { 0x0a00, 0x0d3f, 0x0000 }, + { 0x8c00, 0x0d42, 0x2000 }, + { 0x0c00, 0x0d41, 0x0000 }, + { 0x0c00, 0x0d43, 0x0000 }, + { 0x8700, 0x0d60, 0x4000 }, + { 0x8a00, 0x0d4b, 0x3000 }, + { 0x8a00, 0x0d48, 0x2000 }, + { 0x0a00, 0x0d47, 0x0000 }, + { 0x0a00, 0x0d4a, 0x0000 }, + { 0x8c00, 0x0d4d, 0x2000 }, + { 0x0a00, 0x0d4c, 0x0000 }, + { 0x0a00, 0x0d57, 0x0000 }, + { 0x8d00, 0x0d68, 0x3000 }, + { 0x8d00, 0x0d66, 0x2000 }, + { 0x0700, 0x0d61, 0x0000 }, + { 0x0d00, 0x0d67, 0x0000 }, + { 0x8d00, 0x0d6a, 0x2000 }, + { 0x0d00, 0x0d69, 0x0000 }, + { 0x0d00, 0x0d6b, 0x0000 }, + { 0x8700, 0x0da2, 0x6000 }, + { 0x8700, 0x0d8f, 0x5000 }, + { 0x8700, 0x0d87, 0x4000 }, + { 0x8a00, 0x0d82, 0x3000 }, + { 0x8d00, 0x0d6e, 0x2000 }, + { 0x0d00, 0x0d6d, 0x0000 }, + { 0x0d00, 0x0d6f, 0x0000 }, + { 0x8700, 0x0d85, 0x2000 }, + { 0x0a00, 0x0d83, 0x0000 }, + { 0x0700, 0x0d86, 0x0000 }, + { 0x8700, 0x0d8b, 0x3000 }, + { 0x8700, 0x0d89, 0x2000 }, + { 0x0700, 0x0d88, 0x0000 }, + { 0x0700, 0x0d8a, 0x0000 }, + { 0x8700, 0x0d8d, 0x2000 }, + { 0x0700, 0x0d8c, 0x0000 }, + { 0x0700, 0x0d8e, 0x0000 }, + { 0x8700, 0x0d9a, 0x4000 }, + { 0x8700, 0x0d93, 0x3000 }, + { 0x8700, 0x0d91, 0x2000 }, + { 0x0700, 0x0d90, 0x0000 }, + { 0x0700, 0x0d92, 0x0000 }, + { 0x8700, 0x0d95, 0x2000 }, + { 0x0700, 0x0d94, 0x0000 }, + { 0x0700, 0x0d96, 0x0000 }, + { 0x8700, 0x0d9e, 0x3000 }, + { 0x8700, 0x0d9c, 0x2000 }, + { 0x0700, 0x0d9b, 0x0000 }, + { 0x0700, 0x0d9d, 0x0000 }, + { 0x8700, 0x0da0, 0x2000 }, + { 0x0700, 0x0d9f, 0x0000 }, + { 0x0700, 0x0da1, 0x0000 }, + { 0x8700, 0x0db3, 0x5000 }, + { 0x8700, 0x0daa, 0x4000 }, + { 0x8700, 0x0da6, 0x3000 }, + { 0x8700, 0x0da4, 0x2000 }, + { 0x0700, 0x0da3, 0x0000 }, + { 0x0700, 0x0da5, 0x0000 }, + { 0x8700, 0x0da8, 0x2000 }, + { 0x0700, 0x0da7, 0x0000 }, + { 0x0700, 0x0da9, 0x0000 }, + { 0x8700, 0x0dae, 0x3000 }, + { 0x8700, 0x0dac, 0x2000 }, + { 0x0700, 0x0dab, 0x0000 }, + { 0x0700, 0x0dad, 0x0000 }, + { 0x8700, 0x0db0, 0x2000 }, + { 0x0700, 0x0daf, 0x0000 }, + { 0x0700, 0x0db1, 0x0000 }, + { 0x8700, 0x0dbb, 0x4000 }, + { 0x8700, 0x0db7, 0x3000 }, + { 0x8700, 0x0db5, 0x2000 }, + { 0x0700, 0x0db4, 0x0000 }, + { 0x0700, 0x0db6, 0x0000 }, + { 0x8700, 0x0db9, 0x2000 }, + { 0x0700, 0x0db8, 0x0000 }, + { 0x0700, 0x0dba, 0x0000 }, + { 0x8700, 0x0dc2, 0x3000 }, + { 0x8700, 0x0dc0, 0x2000 }, + { 0x0700, 0x0dbd, 0x0000 }, + { 0x0700, 0x0dc1, 0x0000 }, + { 0x8700, 0x0dc4, 0x2000 }, + { 0x0700, 0x0dc3, 0x0000 }, + { 0x0700, 0x0dc5, 0x0000 }, + { 0x8700, 0x0f55, 0x9000 }, + { 0x8700, 0x0ea5, 0x8000 }, + { 0x8700, 0x0e2d, 0x7000 }, + { 0x8700, 0x0e0d, 0x6000 }, + { 0x8a00, 0x0ddf, 0x5000 }, + { 0x8c00, 0x0dd6, 0x4000 }, + { 0x8a00, 0x0dd1, 0x3000 }, + { 0x8a00, 0x0dcf, 0x2000 }, + { 0x0c00, 0x0dca, 0x0000 }, + { 0x0a00, 0x0dd0, 0x0000 }, + { 0x8c00, 0x0dd3, 0x2000 }, + { 0x0c00, 0x0dd2, 0x0000 }, + { 0x0c00, 0x0dd4, 0x0000 }, + { 0x8a00, 0x0ddb, 0x3000 }, + { 0x8a00, 0x0dd9, 0x2000 }, + { 0x0a00, 0x0dd8, 0x0000 }, + { 0x0a00, 0x0dda, 0x0000 }, + { 0x8a00, 0x0ddd, 0x2000 }, + { 0x0a00, 0x0ddc, 0x0000 }, + { 0x0a00, 0x0dde, 0x0000 }, + { 0x8700, 0x0e05, 0x4000 }, + { 0x8700, 0x0e01, 0x3000 }, + { 0x8a00, 0x0df3, 0x2000 }, + { 0x0a00, 0x0df2, 0x0000 }, + { 0x1500, 0x0df4, 0x0000 }, + { 0x8700, 0x0e03, 0x2000 }, + { 0x0700, 0x0e02, 0x0000 }, + { 0x0700, 0x0e04, 0x0000 }, + { 0x8700, 0x0e09, 0x3000 }, + { 0x8700, 0x0e07, 0x2000 }, + { 0x0700, 0x0e06, 0x0000 }, + { 0x0700, 0x0e08, 0x0000 }, + { 0x8700, 0x0e0b, 0x2000 }, + { 0x0700, 0x0e0a, 0x0000 }, + { 0x0700, 0x0e0c, 0x0000 }, + { 0x8700, 0x0e1d, 0x5000 }, + { 0x8700, 0x0e15, 0x4000 }, + { 0x8700, 0x0e11, 0x3000 }, + { 0x8700, 0x0e0f, 0x2000 }, + { 0x0700, 0x0e0e, 0x0000 }, + { 0x0700, 0x0e10, 0x0000 }, + { 0x8700, 0x0e13, 0x2000 }, + { 0x0700, 0x0e12, 0x0000 }, + { 0x0700, 0x0e14, 0x0000 }, + { 0x8700, 0x0e19, 0x3000 }, + { 0x8700, 0x0e17, 0x2000 }, + { 0x0700, 0x0e16, 0x0000 }, + { 0x0700, 0x0e18, 0x0000 }, + { 0x8700, 0x0e1b, 0x2000 }, + { 0x0700, 0x0e1a, 0x0000 }, + { 0x0700, 0x0e1c, 0x0000 }, + { 0x8700, 0x0e25, 0x4000 }, + { 0x8700, 0x0e21, 0x3000 }, + { 0x8700, 0x0e1f, 0x2000 }, + { 0x0700, 0x0e1e, 0x0000 }, + { 0x0700, 0x0e20, 0x0000 }, + { 0x8700, 0x0e23, 0x2000 }, + { 0x0700, 0x0e22, 0x0000 }, + { 0x0700, 0x0e24, 0x0000 }, + { 0x8700, 0x0e29, 0x3000 }, + { 0x8700, 0x0e27, 0x2000 }, + { 0x0700, 0x0e26, 0x0000 }, + { 0x0700, 0x0e28, 0x0000 }, + { 0x8700, 0x0e2b, 0x2000 }, + { 0x0700, 0x0e2a, 0x0000 }, + { 0x0700, 0x0e2c, 0x0000 }, + { 0x8d00, 0x0e51, 0x6000 }, + { 0x8700, 0x0e41, 0x5000 }, + { 0x8c00, 0x0e35, 0x4000 }, + { 0x8c00, 0x0e31, 0x3000 }, + { 0x8700, 0x0e2f, 0x2000 }, + { 0x0700, 0x0e2e, 0x0000 }, + { 0x0700, 0x0e30, 0x0000 }, + { 0x8700, 0x0e33, 0x2000 }, + { 0x0700, 0x0e32, 0x0000 }, + { 0x0c00, 0x0e34, 0x0000 }, + { 0x8c00, 0x0e39, 0x3000 }, + { 0x8c00, 0x0e37, 0x2000 }, + { 0x0c00, 0x0e36, 0x0000 }, + { 0x0c00, 0x0e38, 0x0000 }, + { 0x9700, 0x0e3f, 0x2000 }, + { 0x0c00, 0x0e3a, 0x0000 }, + { 0x0700, 0x0e40, 0x0000 }, + { 0x8c00, 0x0e49, 0x4000 }, + { 0x8700, 0x0e45, 0x3000 }, + { 0x8700, 0x0e43, 0x2000 }, + { 0x0700, 0x0e42, 0x0000 }, + { 0x0700, 0x0e44, 0x0000 }, + { 0x8c00, 0x0e47, 0x2000 }, + { 0x0600, 0x0e46, 0x0000 }, + { 0x0c00, 0x0e48, 0x0000 }, + { 0x8c00, 0x0e4d, 0x3000 }, + { 0x8c00, 0x0e4b, 0x2000 }, + { 0x0c00, 0x0e4a, 0x0000 }, + { 0x0c00, 0x0e4c, 0x0000 }, + { 0x9500, 0x0e4f, 0x2000 }, + { 0x0c00, 0x0e4e, 0x0000 }, + { 0x0d00, 0x0e50, 0x0000 }, + { 0x8700, 0x0e8a, 0x5000 }, + { 0x8d00, 0x0e59, 0x4000 }, + { 0x8d00, 0x0e55, 0x3000 }, + { 0x8d00, 0x0e53, 0x2000 }, + { 0x0d00, 0x0e52, 0x0000 }, + { 0x0d00, 0x0e54, 0x0000 }, + { 0x8d00, 0x0e57, 0x2000 }, + { 0x0d00, 0x0e56, 0x0000 }, + { 0x0d00, 0x0e58, 0x0000 }, + { 0x8700, 0x0e82, 0x3000 }, + { 0x9500, 0x0e5b, 0x2000 }, + { 0x1500, 0x0e5a, 0x0000 }, + { 0x0700, 0x0e81, 0x0000 }, + { 0x8700, 0x0e87, 0x2000 }, + { 0x0700, 0x0e84, 0x0000 }, + { 0x0700, 0x0e88, 0x0000 }, + { 0x8700, 0x0e9b, 0x4000 }, + { 0x8700, 0x0e96, 0x3000 }, + { 0x8700, 0x0e94, 0x2000 }, + { 0x0700, 0x0e8d, 0x0000 }, + { 0x0700, 0x0e95, 0x0000 }, + { 0x8700, 0x0e99, 0x2000 }, + { 0x0700, 0x0e97, 0x0000 }, + { 0x0700, 0x0e9a, 0x0000 }, + { 0x8700, 0x0e9f, 0x3000 }, + { 0x8700, 0x0e9d, 0x2000 }, + { 0x0700, 0x0e9c, 0x0000 }, + { 0x0700, 0x0e9e, 0x0000 }, + { 0x8700, 0x0ea2, 0x2000 }, + { 0x0700, 0x0ea1, 0x0000 }, + { 0x0700, 0x0ea3, 0x0000 }, + { 0x9a00, 0x0f14, 0x7000 }, + { 0x8d00, 0x0ed0, 0x6000 }, + { 0x8c00, 0x0eb9, 0x5000 }, + { 0x8c00, 0x0eb1, 0x4000 }, + { 0x8700, 0x0ead, 0x3000 }, + { 0x8700, 0x0eaa, 0x2000 }, + { 0x0700, 0x0ea7, 0x0000 }, + { 0x0700, 0x0eab, 0x0000 }, + { 0x8700, 0x0eaf, 0x2000 }, + { 0x0700, 0x0eae, 0x0000 }, + { 0x0700, 0x0eb0, 0x0000 }, + { 0x8c00, 0x0eb5, 0x3000 }, + { 0x8700, 0x0eb3, 0x2000 }, + { 0x0700, 0x0eb2, 0x0000 }, + { 0x0c00, 0x0eb4, 0x0000 }, + { 0x8c00, 0x0eb7, 0x2000 }, + { 0x0c00, 0x0eb6, 0x0000 }, + { 0x0c00, 0x0eb8, 0x0000 }, + { 0x8700, 0x0ec4, 0x4000 }, + { 0x8700, 0x0ec0, 0x3000 }, + { 0x8c00, 0x0ebc, 0x2000 }, + { 0x0c00, 0x0ebb, 0x0000 }, + { 0x0700, 0x0ebd, 0x0000 }, + { 0x8700, 0x0ec2, 0x2000 }, + { 0x0700, 0x0ec1, 0x0000 }, + { 0x0700, 0x0ec3, 0x0000 }, + { 0x8c00, 0x0eca, 0x3000 }, + { 0x8c00, 0x0ec8, 0x2000 }, + { 0x0600, 0x0ec6, 0x0000 }, + { 0x0c00, 0x0ec9, 0x0000 }, + { 0x8c00, 0x0ecc, 0x2000 }, + { 0x0c00, 0x0ecb, 0x0000 }, + { 0x0c00, 0x0ecd, 0x0000 }, + { 0x9500, 0x0f04, 0x5000 }, + { 0x8d00, 0x0ed8, 0x4000 }, + { 0x8d00, 0x0ed4, 0x3000 }, + { 0x8d00, 0x0ed2, 0x2000 }, + { 0x0d00, 0x0ed1, 0x0000 }, + { 0x0d00, 0x0ed3, 0x0000 }, + { 0x8d00, 0x0ed6, 0x2000 }, + { 0x0d00, 0x0ed5, 0x0000 }, + { 0x0d00, 0x0ed7, 0x0000 }, + { 0x8700, 0x0f00, 0x3000 }, + { 0x8700, 0x0edc, 0x2000 }, + { 0x0d00, 0x0ed9, 0x0000 }, + { 0x0700, 0x0edd, 0x0000 }, + { 0x9a00, 0x0f02, 0x2000 }, + { 0x1a00, 0x0f01, 0x0000 }, + { 0x1a00, 0x0f03, 0x0000 }, + { 0x9500, 0x0f0c, 0x4000 }, + { 0x9500, 0x0f08, 0x3000 }, + { 0x9500, 0x0f06, 0x2000 }, + { 0x1500, 0x0f05, 0x0000 }, + { 0x1500, 0x0f07, 0x0000 }, + { 0x9500, 0x0f0a, 0x2000 }, + { 0x1500, 0x0f09, 0x0000 }, + { 0x1500, 0x0f0b, 0x0000 }, + { 0x9500, 0x0f10, 0x3000 }, + { 0x9500, 0x0f0e, 0x2000 }, + { 0x1500, 0x0f0d, 0x0000 }, + { 0x1500, 0x0f0f, 0x0000 }, + { 0x9500, 0x0f12, 0x2000 }, + { 0x1500, 0x0f11, 0x0000 }, + { 0x1a00, 0x0f13, 0x0000 }, + { 0x9a00, 0x0f34, 0x6000 }, + { 0x8d00, 0x0f24, 0x5000 }, + { 0x9a00, 0x0f1c, 0x4000 }, + { 0x8c00, 0x0f18, 0x3000 }, + { 0x9a00, 0x0f16, 0x2000 }, + { 0x1a00, 0x0f15, 0x0000 }, + { 0x1a00, 0x0f17, 0x0000 }, + { 0x9a00, 0x0f1a, 0x2000 }, + { 0x0c00, 0x0f19, 0x0000 }, + { 0x1a00, 0x0f1b, 0x0000 }, + { 0x8d00, 0x0f20, 0x3000 }, + { 0x9a00, 0x0f1e, 0x2000 }, + { 0x1a00, 0x0f1d, 0x0000 }, + { 0x1a00, 0x0f1f, 0x0000 }, + { 0x8d00, 0x0f22, 0x2000 }, + { 0x0d00, 0x0f21, 0x0000 }, + { 0x0d00, 0x0f23, 0x0000 }, + { 0x8f00, 0x0f2c, 0x4000 }, + { 0x8d00, 0x0f28, 0x3000 }, + { 0x8d00, 0x0f26, 0x2000 }, + { 0x0d00, 0x0f25, 0x0000 }, + { 0x0d00, 0x0f27, 0x0000 }, + { 0x8f00, 0x0f2a, 0x2000 }, + { 0x0d00, 0x0f29, 0x0000 }, + { 0x0f00, 0x0f2b, 0x0000 }, + { 0x8f00, 0x0f30, 0x3000 }, + { 0x8f00, 0x0f2e, 0x2000 }, + { 0x0f00, 0x0f2d, 0x0000 }, + { 0x0f00, 0x0f2f, 0x0000 }, + { 0x8f00, 0x0f32, 0x2000 }, + { 0x0f00, 0x0f31, 0x0000 }, + { 0x0f00, 0x0f33, 0x0000 }, + { 0x8700, 0x0f44, 0x5000 }, + { 0x9600, 0x0f3c, 0x4000 }, + { 0x9a00, 0x0f38, 0x3000 }, + { 0x9a00, 0x0f36, 0x2000 }, + { 0x0c00, 0x0f35, 0x0000 }, + { 0x0c00, 0x0f37, 0x0000 }, + { 0x9600, 0x0f3a, 0x2000 }, + { 0x0c00, 0x0f39, 0x0000 }, + { 0x1200, 0x0f3b, 0x0000 }, + { 0x8700, 0x0f40, 0x3000 }, + { 0x8a00, 0x0f3e, 0x2000 }, + { 0x1200, 0x0f3d, 0x0000 }, + { 0x0a00, 0x0f3f, 0x0000 }, + { 0x8700, 0x0f42, 0x2000 }, + { 0x0700, 0x0f41, 0x0000 }, + { 0x0700, 0x0f43, 0x0000 }, + { 0x8700, 0x0f4d, 0x4000 }, + { 0x8700, 0x0f49, 0x3000 }, + { 0x8700, 0x0f46, 0x2000 }, + { 0x0700, 0x0f45, 0x0000 }, + { 0x0700, 0x0f47, 0x0000 }, + { 0x8700, 0x0f4b, 0x2000 }, + { 0x0700, 0x0f4a, 0x0000 }, + { 0x0700, 0x0f4c, 0x0000 }, + { 0x8700, 0x0f51, 0x3000 }, + { 0x8700, 0x0f4f, 0x2000 }, + { 0x0700, 0x0f4e, 0x0000 }, + { 0x0700, 0x0f50, 0x0000 }, + { 0x8700, 0x0f53, 0x2000 }, + { 0x0700, 0x0f52, 0x0000 }, + { 0x0700, 0x0f54, 0x0000 }, + { 0x8700, 0x1013, 0x8000 }, + { 0x8c00, 0x0fa0, 0x7000 }, + { 0x8c00, 0x0f7b, 0x6000 }, + { 0x8700, 0x0f65, 0x5000 }, + { 0x8700, 0x0f5d, 0x4000 }, + { 0x8700, 0x0f59, 0x3000 }, + { 0x8700, 0x0f57, 0x2000 }, + { 0x0700, 0x0f56, 0x0000 }, + { 0x0700, 0x0f58, 0x0000 }, + { 0x8700, 0x0f5b, 0x2000 }, + { 0x0700, 0x0f5a, 0x0000 }, + { 0x0700, 0x0f5c, 0x0000 }, + { 0x8700, 0x0f61, 0x3000 }, + { 0x8700, 0x0f5f, 0x2000 }, + { 0x0700, 0x0f5e, 0x0000 }, + { 0x0700, 0x0f60, 0x0000 }, + { 0x8700, 0x0f63, 0x2000 }, + { 0x0700, 0x0f62, 0x0000 }, + { 0x0700, 0x0f64, 0x0000 }, + { 0x8c00, 0x0f73, 0x4000 }, + { 0x8700, 0x0f69, 0x3000 }, + { 0x8700, 0x0f67, 0x2000 }, + { 0x0700, 0x0f66, 0x0000 }, + { 0x0700, 0x0f68, 0x0000 }, + { 0x8c00, 0x0f71, 0x2000 }, + { 0x0700, 0x0f6a, 0x0000 }, + { 0x0c00, 0x0f72, 0x0000 }, + { 0x8c00, 0x0f77, 0x3000 }, + { 0x8c00, 0x0f75, 0x2000 }, + { 0x0c00, 0x0f74, 0x0000 }, + { 0x0c00, 0x0f76, 0x0000 }, + { 0x8c00, 0x0f79, 0x2000 }, + { 0x0c00, 0x0f78, 0x0000 }, + { 0x0c00, 0x0f7a, 0x0000 }, + { 0x8700, 0x0f8b, 0x5000 }, + { 0x8c00, 0x0f83, 0x4000 }, + { 0x8a00, 0x0f7f, 0x3000 }, + { 0x8c00, 0x0f7d, 0x2000 }, + { 0x0c00, 0x0f7c, 0x0000 }, + { 0x0c00, 0x0f7e, 0x0000 }, + { 0x8c00, 0x0f81, 0x2000 }, + { 0x0c00, 0x0f80, 0x0000 }, + { 0x0c00, 0x0f82, 0x0000 }, + { 0x8c00, 0x0f87, 0x3000 }, + { 0x9500, 0x0f85, 0x2000 }, + { 0x0c00, 0x0f84, 0x0000 }, + { 0x0c00, 0x0f86, 0x0000 }, + { 0x8700, 0x0f89, 0x2000 }, + { 0x0700, 0x0f88, 0x0000 }, + { 0x0700, 0x0f8a, 0x0000 }, + { 0x8c00, 0x0f97, 0x4000 }, + { 0x8c00, 0x0f93, 0x3000 }, + { 0x8c00, 0x0f91, 0x2000 }, + { 0x0c00, 0x0f90, 0x0000 }, + { 0x0c00, 0x0f92, 0x0000 }, + { 0x8c00, 0x0f95, 0x2000 }, + { 0x0c00, 0x0f94, 0x0000 }, + { 0x0c00, 0x0f96, 0x0000 }, + { 0x8c00, 0x0f9c, 0x3000 }, + { 0x8c00, 0x0f9a, 0x2000 }, + { 0x0c00, 0x0f99, 0x0000 }, + { 0x0c00, 0x0f9b, 0x0000 }, + { 0x8c00, 0x0f9e, 0x2000 }, + { 0x0c00, 0x0f9d, 0x0000 }, + { 0x0c00, 0x0f9f, 0x0000 }, + { 0x9a00, 0x0fc1, 0x6000 }, + { 0x8c00, 0x0fb0, 0x5000 }, + { 0x8c00, 0x0fa8, 0x4000 }, + { 0x8c00, 0x0fa4, 0x3000 }, + { 0x8c00, 0x0fa2, 0x2000 }, + { 0x0c00, 0x0fa1, 0x0000 }, + { 0x0c00, 0x0fa3, 0x0000 }, + { 0x8c00, 0x0fa6, 0x2000 }, + { 0x0c00, 0x0fa5, 0x0000 }, + { 0x0c00, 0x0fa7, 0x0000 }, + { 0x8c00, 0x0fac, 0x3000 }, + { 0x8c00, 0x0faa, 0x2000 }, + { 0x0c00, 0x0fa9, 0x0000 }, + { 0x0c00, 0x0fab, 0x0000 }, + { 0x8c00, 0x0fae, 0x2000 }, + { 0x0c00, 0x0fad, 0x0000 }, + { 0x0c00, 0x0faf, 0x0000 }, + { 0x8c00, 0x0fb8, 0x4000 }, + { 0x8c00, 0x0fb4, 0x3000 }, + { 0x8c00, 0x0fb2, 0x2000 }, + { 0x0c00, 0x0fb1, 0x0000 }, + { 0x0c00, 0x0fb3, 0x0000 }, + { 0x8c00, 0x0fb6, 0x2000 }, + { 0x0c00, 0x0fb5, 0x0000 }, + { 0x0c00, 0x0fb7, 0x0000 }, + { 0x8c00, 0x0fbc, 0x3000 }, + { 0x8c00, 0x0fba, 0x2000 }, + { 0x0c00, 0x0fb9, 0x0000 }, + { 0x0c00, 0x0fbb, 0x0000 }, + { 0x9a00, 0x0fbf, 0x2000 }, + { 0x1a00, 0x0fbe, 0x0000 }, + { 0x1a00, 0x0fc0, 0x0000 }, + { 0x8700, 0x1003, 0x5000 }, + { 0x9a00, 0x0fc9, 0x4000 }, + { 0x9a00, 0x0fc5, 0x3000 }, + { 0x9a00, 0x0fc3, 0x2000 }, + { 0x1a00, 0x0fc2, 0x0000 }, + { 0x1a00, 0x0fc4, 0x0000 }, + { 0x9a00, 0x0fc7, 0x2000 }, + { 0x0c00, 0x0fc6, 0x0000 }, + { 0x1a00, 0x0fc8, 0x0000 }, + { 0x9a00, 0x0fcf, 0x3000 }, + { 0x9a00, 0x0fcb, 0x2000 }, + { 0x1a00, 0x0fca, 0x0000 }, + { 0x1a00, 0x0fcc, 0x0000 }, + { 0x8700, 0x1001, 0x2000 }, + { 0x0700, 0x1000, 0x0000 }, + { 0x0700, 0x1002, 0x0000 }, + { 0x8700, 0x100b, 0x4000 }, + { 0x8700, 0x1007, 0x3000 }, + { 0x8700, 0x1005, 0x2000 }, + { 0x0700, 0x1004, 0x0000 }, + { 0x0700, 0x1006, 0x0000 }, + { 0x8700, 0x1009, 0x2000 }, + { 0x0700, 0x1008, 0x0000 }, + { 0x0700, 0x100a, 0x0000 }, + { 0x8700, 0x100f, 0x3000 }, + { 0x8700, 0x100d, 0x2000 }, + { 0x0700, 0x100c, 0x0000 }, + { 0x0700, 0x100e, 0x0000 }, + { 0x8700, 0x1011, 0x2000 }, + { 0x0700, 0x1010, 0x0000 }, + { 0x0700, 0x1012, 0x0000 }, + { 0x8900, 0x10a5, 0x7000 }, + { 0x8c00, 0x1039, 0x6000 }, + { 0x8700, 0x1024, 0x5000 }, + { 0x8700, 0x101b, 0x4000 }, + { 0x8700, 0x1017, 0x3000 }, + { 0x8700, 0x1015, 0x2000 }, + { 0x0700, 0x1014, 0x0000 }, + { 0x0700, 0x1016, 0x0000 }, + { 0x8700, 0x1019, 0x2000 }, + { 0x0700, 0x1018, 0x0000 }, + { 0x0700, 0x101a, 0x0000 }, + { 0x8700, 0x101f, 0x3000 }, + { 0x8700, 0x101d, 0x2000 }, + { 0x0700, 0x101c, 0x0000 }, + { 0x0700, 0x101e, 0x0000 }, + { 0x8700, 0x1021, 0x2000 }, + { 0x0700, 0x1020, 0x0000 }, + { 0x0700, 0x1023, 0x0000 }, + { 0x8c00, 0x102e, 0x4000 }, + { 0x8700, 0x1029, 0x3000 }, + { 0x8700, 0x1026, 0x2000 }, + { 0x0700, 0x1025, 0x0000 }, + { 0x0700, 0x1027, 0x0000 }, + { 0x8a00, 0x102c, 0x2000 }, + { 0x0700, 0x102a, 0x0000 }, + { 0x0c00, 0x102d, 0x0000 }, + { 0x8c00, 0x1032, 0x3000 }, + { 0x8c00, 0x1030, 0x2000 }, + { 0x0c00, 0x102f, 0x0000 }, + { 0x0a00, 0x1031, 0x0000 }, + { 0x8c00, 0x1037, 0x2000 }, + { 0x0c00, 0x1036, 0x0000 }, + { 0x0a00, 0x1038, 0x0000 }, + { 0x9500, 0x104f, 0x5000 }, + { 0x8d00, 0x1047, 0x4000 }, + { 0x8d00, 0x1043, 0x3000 }, + { 0x8d00, 0x1041, 0x2000 }, + { 0x0d00, 0x1040, 0x0000 }, + { 0x0d00, 0x1042, 0x0000 }, + { 0x8d00, 0x1045, 0x2000 }, + { 0x0d00, 0x1044, 0x0000 }, + { 0x0d00, 0x1046, 0x0000 }, + { 0x9500, 0x104b, 0x3000 }, + { 0x8d00, 0x1049, 0x2000 }, + { 0x0d00, 0x1048, 0x0000 }, + { 0x1500, 0x104a, 0x0000 }, + { 0x9500, 0x104d, 0x2000 }, + { 0x1500, 0x104c, 0x0000 }, + { 0x1500, 0x104e, 0x0000 }, + { 0x8a00, 0x1057, 0x4000 }, + { 0x8700, 0x1053, 0x3000 }, + { 0x8700, 0x1051, 0x2000 }, + { 0x0700, 0x1050, 0x0000 }, + { 0x0700, 0x1052, 0x0000 }, + { 0x8700, 0x1055, 0x2000 }, + { 0x0700, 0x1054, 0x0000 }, + { 0x0a00, 0x1056, 0x0000 }, + { 0x8900, 0x10a1, 0x3000 }, + { 0x8c00, 0x1059, 0x2000 }, + { 0x0c00, 0x1058, 0x0000 }, + { 0x0900, 0x10a0, 0x0000 }, + { 0x8900, 0x10a3, 0x2000 }, + { 0x0900, 0x10a2, 0x0000 }, + { 0x0900, 0x10a4, 0x0000 }, + { 0x8900, 0x10c5, 0x6000 }, + { 0x8900, 0x10b5, 0x5000 }, + { 0x8900, 0x10ad, 0x4000 }, + { 0x8900, 0x10a9, 0x3000 }, + { 0x8900, 0x10a7, 0x2000 }, + { 0x0900, 0x10a6, 0x0000 }, + { 0x0900, 0x10a8, 0x0000 }, + { 0x8900, 0x10ab, 0x2000 }, + { 0x0900, 0x10aa, 0x0000 }, + { 0x0900, 0x10ac, 0x0000 }, + { 0x8900, 0x10b1, 0x3000 }, + { 0x8900, 0x10af, 0x2000 }, + { 0x0900, 0x10ae, 0x0000 }, + { 0x0900, 0x10b0, 0x0000 }, + { 0x8900, 0x10b3, 0x2000 }, + { 0x0900, 0x10b2, 0x0000 }, + { 0x0900, 0x10b4, 0x0000 }, + { 0x8900, 0x10bd, 0x4000 }, + { 0x8900, 0x10b9, 0x3000 }, + { 0x8900, 0x10b7, 0x2000 }, + { 0x0900, 0x10b6, 0x0000 }, + { 0x0900, 0x10b8, 0x0000 }, + { 0x8900, 0x10bb, 0x2000 }, + { 0x0900, 0x10ba, 0x0000 }, + { 0x0900, 0x10bc, 0x0000 }, + { 0x8900, 0x10c1, 0x3000 }, + { 0x8900, 0x10bf, 0x2000 }, + { 0x0900, 0x10be, 0x0000 }, + { 0x0900, 0x10c0, 0x0000 }, + { 0x8900, 0x10c3, 0x2000 }, + { 0x0900, 0x10c2, 0x0000 }, + { 0x0900, 0x10c4, 0x0000 }, + { 0x8700, 0x10df, 0x5000 }, + { 0x8700, 0x10d7, 0x4000 }, + { 0x8700, 0x10d3, 0x3000 }, + { 0x8700, 0x10d1, 0x2000 }, + { 0x0700, 0x10d0, 0x0000 }, + { 0x0700, 0x10d2, 0x0000 }, + { 0x8700, 0x10d5, 0x2000 }, + { 0x0700, 0x10d4, 0x0000 }, + { 0x0700, 0x10d6, 0x0000 }, + { 0x8700, 0x10db, 0x3000 }, + { 0x8700, 0x10d9, 0x2000 }, + { 0x0700, 0x10d8, 0x0000 }, + { 0x0700, 0x10da, 0x0000 }, + { 0x8700, 0x10dd, 0x2000 }, + { 0x0700, 0x10dc, 0x0000 }, + { 0x0700, 0x10de, 0x0000 }, + { 0x8700, 0x10e7, 0x4000 }, + { 0x8700, 0x10e3, 0x3000 }, + { 0x8700, 0x10e1, 0x2000 }, + { 0x0700, 0x10e0, 0x0000 }, + { 0x0700, 0x10e2, 0x0000 }, + { 0x8700, 0x10e5, 0x2000 }, + { 0x0700, 0x10e4, 0x0000 }, + { 0x0700, 0x10e6, 0x0000 }, + { 0x8700, 0x10eb, 0x3000 }, + { 0x8700, 0x10e9, 0x2000 }, + { 0x0700, 0x10e8, 0x0000 }, + { 0x0700, 0x10ea, 0x0000 }, + { 0x8700, 0x10ed, 0x2000 }, + { 0x0700, 0x10ec, 0x0000 }, + { 0x0700, 0x10ee, 0x0000 }, + { 0x8700, 0x1322, 0xa000 }, + { 0x8700, 0x1205, 0x9000 }, + { 0x8700, 0x117a, 0x8000 }, + { 0x8700, 0x1135, 0x7000 }, + { 0x8700, 0x1115, 0x6000 }, + { 0x8700, 0x1105, 0x5000 }, + { 0x8700, 0x10f7, 0x4000 }, + { 0x8700, 0x10f3, 0x3000 }, + { 0x8700, 0x10f1, 0x2000 }, + { 0x0700, 0x10f0, 0x0000 }, + { 0x0700, 0x10f2, 0x0000 }, + { 0x8700, 0x10f5, 0x2000 }, + { 0x0700, 0x10f4, 0x0000 }, + { 0x0700, 0x10f6, 0x0000 }, + { 0x8700, 0x1101, 0x3000 }, + { 0x9500, 0x10fb, 0x2000 }, + { 0x0700, 0x10f8, 0x0000 }, + { 0x0700, 0x1100, 0x0000 }, + { 0x8700, 0x1103, 0x2000 }, + { 0x0700, 0x1102, 0x0000 }, + { 0x0700, 0x1104, 0x0000 }, + { 0x8700, 0x110d, 0x4000 }, + { 0x8700, 0x1109, 0x3000 }, + { 0x8700, 0x1107, 0x2000 }, + { 0x0700, 0x1106, 0x0000 }, + { 0x0700, 0x1108, 0x0000 }, + { 0x8700, 0x110b, 0x2000 }, + { 0x0700, 0x110a, 0x0000 }, + { 0x0700, 0x110c, 0x0000 }, + { 0x8700, 0x1111, 0x3000 }, + { 0x8700, 0x110f, 0x2000 }, + { 0x0700, 0x110e, 0x0000 }, + { 0x0700, 0x1110, 0x0000 }, + { 0x8700, 0x1113, 0x2000 }, + { 0x0700, 0x1112, 0x0000 }, + { 0x0700, 0x1114, 0x0000 }, + { 0x8700, 0x1125, 0x5000 }, + { 0x8700, 0x111d, 0x4000 }, + { 0x8700, 0x1119, 0x3000 }, + { 0x8700, 0x1117, 0x2000 }, + { 0x0700, 0x1116, 0x0000 }, + { 0x0700, 0x1118, 0x0000 }, + { 0x8700, 0x111b, 0x2000 }, + { 0x0700, 0x111a, 0x0000 }, + { 0x0700, 0x111c, 0x0000 }, + { 0x8700, 0x1121, 0x3000 }, + { 0x8700, 0x111f, 0x2000 }, + { 0x0700, 0x111e, 0x0000 }, + { 0x0700, 0x1120, 0x0000 }, + { 0x8700, 0x1123, 0x2000 }, + { 0x0700, 0x1122, 0x0000 }, + { 0x0700, 0x1124, 0x0000 }, + { 0x8700, 0x112d, 0x4000 }, + { 0x8700, 0x1129, 0x3000 }, + { 0x8700, 0x1127, 0x2000 }, + { 0x0700, 0x1126, 0x0000 }, + { 0x0700, 0x1128, 0x0000 }, + { 0x8700, 0x112b, 0x2000 }, + { 0x0700, 0x112a, 0x0000 }, + { 0x0700, 0x112c, 0x0000 }, + { 0x8700, 0x1131, 0x3000 }, + { 0x8700, 0x112f, 0x2000 }, + { 0x0700, 0x112e, 0x0000 }, + { 0x0700, 0x1130, 0x0000 }, + { 0x8700, 0x1133, 0x2000 }, + { 0x0700, 0x1132, 0x0000 }, + { 0x0700, 0x1134, 0x0000 }, + { 0x8700, 0x1155, 0x6000 }, + { 0x8700, 0x1145, 0x5000 }, + { 0x8700, 0x113d, 0x4000 }, + { 0x8700, 0x1139, 0x3000 }, + { 0x8700, 0x1137, 0x2000 }, + { 0x0700, 0x1136, 0x0000 }, + { 0x0700, 0x1138, 0x0000 }, + { 0x8700, 0x113b, 0x2000 }, + { 0x0700, 0x113a, 0x0000 }, + { 0x0700, 0x113c, 0x0000 }, + { 0x8700, 0x1141, 0x3000 }, + { 0x8700, 0x113f, 0x2000 }, + { 0x0700, 0x113e, 0x0000 }, + { 0x0700, 0x1140, 0x0000 }, + { 0x8700, 0x1143, 0x2000 }, + { 0x0700, 0x1142, 0x0000 }, + { 0x0700, 0x1144, 0x0000 }, + { 0x8700, 0x114d, 0x4000 }, + { 0x8700, 0x1149, 0x3000 }, + { 0x8700, 0x1147, 0x2000 }, + { 0x0700, 0x1146, 0x0000 }, + { 0x0700, 0x1148, 0x0000 }, + { 0x8700, 0x114b, 0x2000 }, + { 0x0700, 0x114a, 0x0000 }, + { 0x0700, 0x114c, 0x0000 }, + { 0x8700, 0x1151, 0x3000 }, + { 0x8700, 0x114f, 0x2000 }, + { 0x0700, 0x114e, 0x0000 }, + { 0x0700, 0x1150, 0x0000 }, + { 0x8700, 0x1153, 0x2000 }, + { 0x0700, 0x1152, 0x0000 }, + { 0x0700, 0x1154, 0x0000 }, + { 0x8700, 0x116a, 0x5000 }, + { 0x8700, 0x1162, 0x4000 }, + { 0x8700, 0x1159, 0x3000 }, + { 0x8700, 0x1157, 0x2000 }, + { 0x0700, 0x1156, 0x0000 }, + { 0x0700, 0x1158, 0x0000 }, + { 0x8700, 0x1160, 0x2000 }, + { 0x0700, 0x115f, 0x0000 }, + { 0x0700, 0x1161, 0x0000 }, + { 0x8700, 0x1166, 0x3000 }, + { 0x8700, 0x1164, 0x2000 }, + { 0x0700, 0x1163, 0x0000 }, + { 0x0700, 0x1165, 0x0000 }, + { 0x8700, 0x1168, 0x2000 }, + { 0x0700, 0x1167, 0x0000 }, + { 0x0700, 0x1169, 0x0000 }, + { 0x8700, 0x1172, 0x4000 }, + { 0x8700, 0x116e, 0x3000 }, + { 0x8700, 0x116c, 0x2000 }, + { 0x0700, 0x116b, 0x0000 }, + { 0x0700, 0x116d, 0x0000 }, + { 0x8700, 0x1170, 0x2000 }, + { 0x0700, 0x116f, 0x0000 }, + { 0x0700, 0x1171, 0x0000 }, + { 0x8700, 0x1176, 0x3000 }, + { 0x8700, 0x1174, 0x2000 }, + { 0x0700, 0x1173, 0x0000 }, + { 0x0700, 0x1175, 0x0000 }, + { 0x8700, 0x1178, 0x2000 }, + { 0x0700, 0x1177, 0x0000 }, + { 0x0700, 0x1179, 0x0000 }, + { 0x8700, 0x11bf, 0x7000 }, + { 0x8700, 0x119a, 0x6000 }, + { 0x8700, 0x118a, 0x5000 }, + { 0x8700, 0x1182, 0x4000 }, + { 0x8700, 0x117e, 0x3000 }, + { 0x8700, 0x117c, 0x2000 }, + { 0x0700, 0x117b, 0x0000 }, + { 0x0700, 0x117d, 0x0000 }, + { 0x8700, 0x1180, 0x2000 }, + { 0x0700, 0x117f, 0x0000 }, + { 0x0700, 0x1181, 0x0000 }, + { 0x8700, 0x1186, 0x3000 }, + { 0x8700, 0x1184, 0x2000 }, + { 0x0700, 0x1183, 0x0000 }, + { 0x0700, 0x1185, 0x0000 }, + { 0x8700, 0x1188, 0x2000 }, + { 0x0700, 0x1187, 0x0000 }, + { 0x0700, 0x1189, 0x0000 }, + { 0x8700, 0x1192, 0x4000 }, + { 0x8700, 0x118e, 0x3000 }, + { 0x8700, 0x118c, 0x2000 }, + { 0x0700, 0x118b, 0x0000 }, + { 0x0700, 0x118d, 0x0000 }, + { 0x8700, 0x1190, 0x2000 }, + { 0x0700, 0x118f, 0x0000 }, + { 0x0700, 0x1191, 0x0000 }, + { 0x8700, 0x1196, 0x3000 }, + { 0x8700, 0x1194, 0x2000 }, + { 0x0700, 0x1193, 0x0000 }, + { 0x0700, 0x1195, 0x0000 }, + { 0x8700, 0x1198, 0x2000 }, + { 0x0700, 0x1197, 0x0000 }, + { 0x0700, 0x1199, 0x0000 }, + { 0x8700, 0x11af, 0x5000 }, + { 0x8700, 0x11a2, 0x4000 }, + { 0x8700, 0x119e, 0x3000 }, + { 0x8700, 0x119c, 0x2000 }, + { 0x0700, 0x119b, 0x0000 }, + { 0x0700, 0x119d, 0x0000 }, + { 0x8700, 0x11a0, 0x2000 }, + { 0x0700, 0x119f, 0x0000 }, + { 0x0700, 0x11a1, 0x0000 }, + { 0x8700, 0x11ab, 0x3000 }, + { 0x8700, 0x11a9, 0x2000 }, + { 0x0700, 0x11a8, 0x0000 }, + { 0x0700, 0x11aa, 0x0000 }, + { 0x8700, 0x11ad, 0x2000 }, + { 0x0700, 0x11ac, 0x0000 }, + { 0x0700, 0x11ae, 0x0000 }, + { 0x8700, 0x11b7, 0x4000 }, + { 0x8700, 0x11b3, 0x3000 }, + { 0x8700, 0x11b1, 0x2000 }, + { 0x0700, 0x11b0, 0x0000 }, + { 0x0700, 0x11b2, 0x0000 }, + { 0x8700, 0x11b5, 0x2000 }, + { 0x0700, 0x11b4, 0x0000 }, + { 0x0700, 0x11b6, 0x0000 }, + { 0x8700, 0x11bb, 0x3000 }, + { 0x8700, 0x11b9, 0x2000 }, + { 0x0700, 0x11b8, 0x0000 }, + { 0x0700, 0x11ba, 0x0000 }, + { 0x8700, 0x11bd, 0x2000 }, + { 0x0700, 0x11bc, 0x0000 }, + { 0x0700, 0x11be, 0x0000 }, + { 0x8700, 0x11df, 0x6000 }, + { 0x8700, 0x11cf, 0x5000 }, + { 0x8700, 0x11c7, 0x4000 }, + { 0x8700, 0x11c3, 0x3000 }, + { 0x8700, 0x11c1, 0x2000 }, + { 0x0700, 0x11c0, 0x0000 }, + { 0x0700, 0x11c2, 0x0000 }, + { 0x8700, 0x11c5, 0x2000 }, + { 0x0700, 0x11c4, 0x0000 }, + { 0x0700, 0x11c6, 0x0000 }, + { 0x8700, 0x11cb, 0x3000 }, + { 0x8700, 0x11c9, 0x2000 }, + { 0x0700, 0x11c8, 0x0000 }, + { 0x0700, 0x11ca, 0x0000 }, + { 0x8700, 0x11cd, 0x2000 }, + { 0x0700, 0x11cc, 0x0000 }, + { 0x0700, 0x11ce, 0x0000 }, + { 0x8700, 0x11d7, 0x4000 }, + { 0x8700, 0x11d3, 0x3000 }, + { 0x8700, 0x11d1, 0x2000 }, + { 0x0700, 0x11d0, 0x0000 }, + { 0x0700, 0x11d2, 0x0000 }, + { 0x8700, 0x11d5, 0x2000 }, + { 0x0700, 0x11d4, 0x0000 }, + { 0x0700, 0x11d6, 0x0000 }, + { 0x8700, 0x11db, 0x3000 }, + { 0x8700, 0x11d9, 0x2000 }, + { 0x0700, 0x11d8, 0x0000 }, + { 0x0700, 0x11da, 0x0000 }, + { 0x8700, 0x11dd, 0x2000 }, + { 0x0700, 0x11dc, 0x0000 }, + { 0x0700, 0x11de, 0x0000 }, + { 0x8700, 0x11ef, 0x5000 }, + { 0x8700, 0x11e7, 0x4000 }, + { 0x8700, 0x11e3, 0x3000 }, + { 0x8700, 0x11e1, 0x2000 }, + { 0x0700, 0x11e0, 0x0000 }, + { 0x0700, 0x11e2, 0x0000 }, + { 0x8700, 0x11e5, 0x2000 }, + { 0x0700, 0x11e4, 0x0000 }, + { 0x0700, 0x11e6, 0x0000 }, + { 0x8700, 0x11eb, 0x3000 }, + { 0x8700, 0x11e9, 0x2000 }, + { 0x0700, 0x11e8, 0x0000 }, + { 0x0700, 0x11ea, 0x0000 }, + { 0x8700, 0x11ed, 0x2000 }, + { 0x0700, 0x11ec, 0x0000 }, + { 0x0700, 0x11ee, 0x0000 }, + { 0x8700, 0x11f7, 0x4000 }, + { 0x8700, 0x11f3, 0x3000 }, + { 0x8700, 0x11f1, 0x2000 }, + { 0x0700, 0x11f0, 0x0000 }, + { 0x0700, 0x11f2, 0x0000 }, + { 0x8700, 0x11f5, 0x2000 }, + { 0x0700, 0x11f4, 0x0000 }, + { 0x0700, 0x11f6, 0x0000 }, + { 0x8700, 0x1201, 0x3000 }, + { 0x8700, 0x11f9, 0x2000 }, + { 0x0700, 0x11f8, 0x0000 }, + { 0x0700, 0x1200, 0x0000 }, + { 0x8700, 0x1203, 0x2000 }, + { 0x0700, 0x1202, 0x0000 }, + { 0x0700, 0x1204, 0x0000 }, + { 0x8700, 0x1292, 0x8000 }, + { 0x8700, 0x1246, 0x7000 }, + { 0x8700, 0x1226, 0x6000 }, + { 0x8700, 0x1216, 0x5000 }, + { 0x8700, 0x120e, 0x4000 }, + { 0x8700, 0x120a, 0x3000 }, + { 0x8700, 0x1208, 0x2000 }, + { 0x0700, 0x1206, 0x0000 }, + { 0x0700, 0x1209, 0x0000 }, + { 0x8700, 0x120c, 0x2000 }, + { 0x0700, 0x120b, 0x0000 }, + { 0x0700, 0x120d, 0x0000 }, + { 0x8700, 0x1212, 0x3000 }, + { 0x8700, 0x1210, 0x2000 }, + { 0x0700, 0x120f, 0x0000 }, + { 0x0700, 0x1211, 0x0000 }, + { 0x8700, 0x1214, 0x2000 }, + { 0x0700, 0x1213, 0x0000 }, + { 0x0700, 0x1215, 0x0000 }, + { 0x8700, 0x121e, 0x4000 }, + { 0x8700, 0x121a, 0x3000 }, + { 0x8700, 0x1218, 0x2000 }, + { 0x0700, 0x1217, 0x0000 }, + { 0x0700, 0x1219, 0x0000 }, + { 0x8700, 0x121c, 0x2000 }, + { 0x0700, 0x121b, 0x0000 }, + { 0x0700, 0x121d, 0x0000 }, + { 0x8700, 0x1222, 0x3000 }, + { 0x8700, 0x1220, 0x2000 }, + { 0x0700, 0x121f, 0x0000 }, + { 0x0700, 0x1221, 0x0000 }, + { 0x8700, 0x1224, 0x2000 }, + { 0x0700, 0x1223, 0x0000 }, + { 0x0700, 0x1225, 0x0000 }, + { 0x8700, 0x1236, 0x5000 }, + { 0x8700, 0x122e, 0x4000 }, + { 0x8700, 0x122a, 0x3000 }, + { 0x8700, 0x1228, 0x2000 }, + { 0x0700, 0x1227, 0x0000 }, + { 0x0700, 0x1229, 0x0000 }, + { 0x8700, 0x122c, 0x2000 }, + { 0x0700, 0x122b, 0x0000 }, + { 0x0700, 0x122d, 0x0000 }, + { 0x8700, 0x1232, 0x3000 }, + { 0x8700, 0x1230, 0x2000 }, + { 0x0700, 0x122f, 0x0000 }, + { 0x0700, 0x1231, 0x0000 }, + { 0x8700, 0x1234, 0x2000 }, + { 0x0700, 0x1233, 0x0000 }, + { 0x0700, 0x1235, 0x0000 }, + { 0x8700, 0x123e, 0x4000 }, + { 0x8700, 0x123a, 0x3000 }, + { 0x8700, 0x1238, 0x2000 }, + { 0x0700, 0x1237, 0x0000 }, + { 0x0700, 0x1239, 0x0000 }, + { 0x8700, 0x123c, 0x2000 }, + { 0x0700, 0x123b, 0x0000 }, + { 0x0700, 0x123d, 0x0000 }, + { 0x8700, 0x1242, 0x3000 }, + { 0x8700, 0x1240, 0x2000 }, + { 0x0700, 0x123f, 0x0000 }, + { 0x0700, 0x1241, 0x0000 }, + { 0x8700, 0x1244, 0x2000 }, + { 0x0700, 0x1243, 0x0000 }, + { 0x0700, 0x1245, 0x0000 }, + { 0x8700, 0x126e, 0x6000 }, + { 0x8700, 0x125c, 0x5000 }, + { 0x8700, 0x1252, 0x4000 }, + { 0x8700, 0x124c, 0x3000 }, + { 0x8700, 0x124a, 0x2000 }, + { 0x0700, 0x1248, 0x0000 }, + { 0x0700, 0x124b, 0x0000 }, + { 0x8700, 0x1250, 0x2000 }, + { 0x0700, 0x124d, 0x0000 }, + { 0x0700, 0x1251, 0x0000 }, + { 0x8700, 0x1256, 0x3000 }, + { 0x8700, 0x1254, 0x2000 }, + { 0x0700, 0x1253, 0x0000 }, + { 0x0700, 0x1255, 0x0000 }, + { 0x8700, 0x125a, 0x2000 }, + { 0x0700, 0x1258, 0x0000 }, + { 0x0700, 0x125b, 0x0000 }, + { 0x8700, 0x1266, 0x4000 }, + { 0x8700, 0x1262, 0x3000 }, + { 0x8700, 0x1260, 0x2000 }, + { 0x0700, 0x125d, 0x0000 }, + { 0x0700, 0x1261, 0x0000 }, + { 0x8700, 0x1264, 0x2000 }, + { 0x0700, 0x1263, 0x0000 }, + { 0x0700, 0x1265, 0x0000 }, + { 0x8700, 0x126a, 0x3000 }, + { 0x8700, 0x1268, 0x2000 }, + { 0x0700, 0x1267, 0x0000 }, + { 0x0700, 0x1269, 0x0000 }, + { 0x8700, 0x126c, 0x2000 }, + { 0x0700, 0x126b, 0x0000 }, + { 0x0700, 0x126d, 0x0000 }, + { 0x8700, 0x127e, 0x5000 }, + { 0x8700, 0x1276, 0x4000 }, + { 0x8700, 0x1272, 0x3000 }, + { 0x8700, 0x1270, 0x2000 }, + { 0x0700, 0x126f, 0x0000 }, + { 0x0700, 0x1271, 0x0000 }, + { 0x8700, 0x1274, 0x2000 }, + { 0x0700, 0x1273, 0x0000 }, + { 0x0700, 0x1275, 0x0000 }, + { 0x8700, 0x127a, 0x3000 }, + { 0x8700, 0x1278, 0x2000 }, + { 0x0700, 0x1277, 0x0000 }, + { 0x0700, 0x1279, 0x0000 }, + { 0x8700, 0x127c, 0x2000 }, + { 0x0700, 0x127b, 0x0000 }, + { 0x0700, 0x127d, 0x0000 }, + { 0x8700, 0x1286, 0x4000 }, + { 0x8700, 0x1282, 0x3000 }, + { 0x8700, 0x1280, 0x2000 }, + { 0x0700, 0x127f, 0x0000 }, + { 0x0700, 0x1281, 0x0000 }, + { 0x8700, 0x1284, 0x2000 }, + { 0x0700, 0x1283, 0x0000 }, + { 0x0700, 0x1285, 0x0000 }, + { 0x8700, 0x128c, 0x3000 }, + { 0x8700, 0x128a, 0x2000 }, + { 0x0700, 0x1288, 0x0000 }, + { 0x0700, 0x128b, 0x0000 }, + { 0x8700, 0x1290, 0x2000 }, + { 0x0700, 0x128d, 0x0000 }, + { 0x0700, 0x1291, 0x0000 }, + { 0x8700, 0x12dc, 0x7000 }, + { 0x8700, 0x12b4, 0x6000 }, + { 0x8700, 0x12a2, 0x5000 }, + { 0x8700, 0x129a, 0x4000 }, + { 0x8700, 0x1296, 0x3000 }, + { 0x8700, 0x1294, 0x2000 }, + { 0x0700, 0x1293, 0x0000 }, + { 0x0700, 0x1295, 0x0000 }, + { 0x8700, 0x1298, 0x2000 }, + { 0x0700, 0x1297, 0x0000 }, + { 0x0700, 0x1299, 0x0000 }, + { 0x8700, 0x129e, 0x3000 }, + { 0x8700, 0x129c, 0x2000 }, + { 0x0700, 0x129b, 0x0000 }, + { 0x0700, 0x129d, 0x0000 }, + { 0x8700, 0x12a0, 0x2000 }, + { 0x0700, 0x129f, 0x0000 }, + { 0x0700, 0x12a1, 0x0000 }, + { 0x8700, 0x12aa, 0x4000 }, + { 0x8700, 0x12a6, 0x3000 }, + { 0x8700, 0x12a4, 0x2000 }, + { 0x0700, 0x12a3, 0x0000 }, + { 0x0700, 0x12a5, 0x0000 }, + { 0x8700, 0x12a8, 0x2000 }, + { 0x0700, 0x12a7, 0x0000 }, + { 0x0700, 0x12a9, 0x0000 }, + { 0x8700, 0x12ae, 0x3000 }, + { 0x8700, 0x12ac, 0x2000 }, + { 0x0700, 0x12ab, 0x0000 }, + { 0x0700, 0x12ad, 0x0000 }, + { 0x8700, 0x12b2, 0x2000 }, + { 0x0700, 0x12b0, 0x0000 }, + { 0x0700, 0x12b3, 0x0000 }, + { 0x8700, 0x12ca, 0x5000 }, + { 0x8700, 0x12be, 0x4000 }, + { 0x8700, 0x12ba, 0x3000 }, + { 0x8700, 0x12b8, 0x2000 }, + { 0x0700, 0x12b5, 0x0000 }, + { 0x0700, 0x12b9, 0x0000 }, + { 0x8700, 0x12bc, 0x2000 }, + { 0x0700, 0x12bb, 0x0000 }, + { 0x0700, 0x12bd, 0x0000 }, + { 0x8700, 0x12c4, 0x3000 }, + { 0x8700, 0x12c2, 0x2000 }, + { 0x0700, 0x12c0, 0x0000 }, + { 0x0700, 0x12c3, 0x0000 }, + { 0x8700, 0x12c8, 0x2000 }, + { 0x0700, 0x12c5, 0x0000 }, + { 0x0700, 0x12c9, 0x0000 }, + { 0x8700, 0x12d3, 0x4000 }, + { 0x8700, 0x12ce, 0x3000 }, + { 0x8700, 0x12cc, 0x2000 }, + { 0x0700, 0x12cb, 0x0000 }, + { 0x0700, 0x12cd, 0x0000 }, + { 0x8700, 0x12d1, 0x2000 }, + { 0x0700, 0x12d0, 0x0000 }, + { 0x0700, 0x12d2, 0x0000 }, + { 0x8700, 0x12d8, 0x3000 }, + { 0x8700, 0x12d5, 0x2000 }, + { 0x0700, 0x12d4, 0x0000 }, + { 0x0700, 0x12d6, 0x0000 }, + { 0x8700, 0x12da, 0x2000 }, + { 0x0700, 0x12d9, 0x0000 }, + { 0x0700, 0x12db, 0x0000 }, + { 0x8700, 0x12fd, 0x6000 }, + { 0x8700, 0x12ec, 0x5000 }, + { 0x8700, 0x12e4, 0x4000 }, + { 0x8700, 0x12e0, 0x3000 }, + { 0x8700, 0x12de, 0x2000 }, + { 0x0700, 0x12dd, 0x0000 }, + { 0x0700, 0x12df, 0x0000 }, + { 0x8700, 0x12e2, 0x2000 }, + { 0x0700, 0x12e1, 0x0000 }, + { 0x0700, 0x12e3, 0x0000 }, + { 0x8700, 0x12e8, 0x3000 }, + { 0x8700, 0x12e6, 0x2000 }, + { 0x0700, 0x12e5, 0x0000 }, + { 0x0700, 0x12e7, 0x0000 }, + { 0x8700, 0x12ea, 0x2000 }, + { 0x0700, 0x12e9, 0x0000 }, + { 0x0700, 0x12eb, 0x0000 }, + { 0x8700, 0x12f5, 0x4000 }, + { 0x8700, 0x12f1, 0x3000 }, + { 0x8700, 0x12ee, 0x2000 }, + { 0x0700, 0x12ed, 0x0000 }, + { 0x0700, 0x12f0, 0x0000 }, + { 0x8700, 0x12f3, 0x2000 }, + { 0x0700, 0x12f2, 0x0000 }, + { 0x0700, 0x12f4, 0x0000 }, + { 0x8700, 0x12f9, 0x3000 }, + { 0x8700, 0x12f7, 0x2000 }, + { 0x0700, 0x12f6, 0x0000 }, + { 0x0700, 0x12f8, 0x0000 }, + { 0x8700, 0x12fb, 0x2000 }, + { 0x0700, 0x12fa, 0x0000 }, + { 0x0700, 0x12fc, 0x0000 }, + { 0x8700, 0x130d, 0x5000 }, + { 0x8700, 0x1305, 0x4000 }, + { 0x8700, 0x1301, 0x3000 }, + { 0x8700, 0x12ff, 0x2000 }, + { 0x0700, 0x12fe, 0x0000 }, + { 0x0700, 0x1300, 0x0000 }, + { 0x8700, 0x1303, 0x2000 }, + { 0x0700, 0x1302, 0x0000 }, + { 0x0700, 0x1304, 0x0000 }, + { 0x8700, 0x1309, 0x3000 }, + { 0x8700, 0x1307, 0x2000 }, + { 0x0700, 0x1306, 0x0000 }, + { 0x0700, 0x1308, 0x0000 }, + { 0x8700, 0x130b, 0x2000 }, + { 0x0700, 0x130a, 0x0000 }, + { 0x0700, 0x130c, 0x0000 }, + { 0x8700, 0x1319, 0x4000 }, + { 0x8700, 0x1313, 0x3000 }, + { 0x8700, 0x1310, 0x2000 }, + { 0x0700, 0x130e, 0x0000 }, + { 0x0700, 0x1312, 0x0000 }, + { 0x8700, 0x1315, 0x2000 }, + { 0x0700, 0x1314, 0x0000 }, + { 0x0700, 0x1318, 0x0000 }, + { 0x8700, 0x131d, 0x3000 }, + { 0x8700, 0x131b, 0x2000 }, + { 0x0700, 0x131a, 0x0000 }, + { 0x0700, 0x131c, 0x0000 }, + { 0x8700, 0x1320, 0x2000 }, + { 0x0700, 0x131e, 0x0000 }, + { 0x0700, 0x1321, 0x0000 }, + { 0x8700, 0x1458, 0x9000 }, + { 0x8700, 0x13cc, 0x8000 }, + { 0x8d00, 0x1369, 0x7000 }, + { 0x8700, 0x1342, 0x6000 }, + { 0x8700, 0x1332, 0x5000 }, + { 0x8700, 0x132a, 0x4000 }, + { 0x8700, 0x1326, 0x3000 }, + { 0x8700, 0x1324, 0x2000 }, + { 0x0700, 0x1323, 0x0000 }, + { 0x0700, 0x1325, 0x0000 }, + { 0x8700, 0x1328, 0x2000 }, + { 0x0700, 0x1327, 0x0000 }, + { 0x0700, 0x1329, 0x0000 }, + { 0x8700, 0x132e, 0x3000 }, + { 0x8700, 0x132c, 0x2000 }, + { 0x0700, 0x132b, 0x0000 }, + { 0x0700, 0x132d, 0x0000 }, + { 0x8700, 0x1330, 0x2000 }, + { 0x0700, 0x132f, 0x0000 }, + { 0x0700, 0x1331, 0x0000 }, + { 0x8700, 0x133a, 0x4000 }, + { 0x8700, 0x1336, 0x3000 }, + { 0x8700, 0x1334, 0x2000 }, + { 0x0700, 0x1333, 0x0000 }, + { 0x0700, 0x1335, 0x0000 }, + { 0x8700, 0x1338, 0x2000 }, + { 0x0700, 0x1337, 0x0000 }, + { 0x0700, 0x1339, 0x0000 }, + { 0x8700, 0x133e, 0x3000 }, + { 0x8700, 0x133c, 0x2000 }, + { 0x0700, 0x133b, 0x0000 }, + { 0x0700, 0x133d, 0x0000 }, + { 0x8700, 0x1340, 0x2000 }, + { 0x0700, 0x133f, 0x0000 }, + { 0x0700, 0x1341, 0x0000 }, + { 0x8700, 0x1353, 0x5000 }, + { 0x8700, 0x134b, 0x4000 }, + { 0x8700, 0x1346, 0x3000 }, + { 0x8700, 0x1344, 0x2000 }, + { 0x0700, 0x1343, 0x0000 }, + { 0x0700, 0x1345, 0x0000 }, + { 0x8700, 0x1349, 0x2000 }, + { 0x0700, 0x1348, 0x0000 }, + { 0x0700, 0x134a, 0x0000 }, + { 0x8700, 0x134f, 0x3000 }, + { 0x8700, 0x134d, 0x2000 }, + { 0x0700, 0x134c, 0x0000 }, + { 0x0700, 0x134e, 0x0000 }, + { 0x8700, 0x1351, 0x2000 }, + { 0x0700, 0x1350, 0x0000 }, + { 0x0700, 0x1352, 0x0000 }, + { 0x9500, 0x1361, 0x4000 }, + { 0x8700, 0x1357, 0x3000 }, + { 0x8700, 0x1355, 0x2000 }, + { 0x0700, 0x1354, 0x0000 }, + { 0x0700, 0x1356, 0x0000 }, + { 0x8700, 0x1359, 0x2000 }, + { 0x0700, 0x1358, 0x0000 }, + { 0x0700, 0x135a, 0x0000 }, + { 0x9500, 0x1365, 0x3000 }, + { 0x9500, 0x1363, 0x2000 }, + { 0x1500, 0x1362, 0x0000 }, + { 0x1500, 0x1364, 0x0000 }, + { 0x9500, 0x1367, 0x2000 }, + { 0x1500, 0x1366, 0x0000 }, + { 0x1500, 0x1368, 0x0000 }, + { 0x8700, 0x13ac, 0x6000 }, + { 0x8f00, 0x1379, 0x5000 }, + { 0x8d00, 0x1371, 0x4000 }, + { 0x8d00, 0x136d, 0x3000 }, + { 0x8d00, 0x136b, 0x2000 }, + { 0x0d00, 0x136a, 0x0000 }, + { 0x0d00, 0x136c, 0x0000 }, + { 0x8d00, 0x136f, 0x2000 }, + { 0x0d00, 0x136e, 0x0000 }, + { 0x0d00, 0x1370, 0x0000 }, + { 0x8f00, 0x1375, 0x3000 }, + { 0x8f00, 0x1373, 0x2000 }, + { 0x0f00, 0x1372, 0x0000 }, + { 0x0f00, 0x1374, 0x0000 }, + { 0x8f00, 0x1377, 0x2000 }, + { 0x0f00, 0x1376, 0x0000 }, + { 0x0f00, 0x1378, 0x0000 }, + { 0x8700, 0x13a4, 0x4000 }, + { 0x8700, 0x13a0, 0x3000 }, + { 0x8f00, 0x137b, 0x2000 }, + { 0x0f00, 0x137a, 0x0000 }, + { 0x0f00, 0x137c, 0x0000 }, + { 0x8700, 0x13a2, 0x2000 }, + { 0x0700, 0x13a1, 0x0000 }, + { 0x0700, 0x13a3, 0x0000 }, + { 0x8700, 0x13a8, 0x3000 }, + { 0x8700, 0x13a6, 0x2000 }, + { 0x0700, 0x13a5, 0x0000 }, + { 0x0700, 0x13a7, 0x0000 }, + { 0x8700, 0x13aa, 0x2000 }, + { 0x0700, 0x13a9, 0x0000 }, + { 0x0700, 0x13ab, 0x0000 }, + { 0x8700, 0x13bc, 0x5000 }, + { 0x8700, 0x13b4, 0x4000 }, + { 0x8700, 0x13b0, 0x3000 }, + { 0x8700, 0x13ae, 0x2000 }, + { 0x0700, 0x13ad, 0x0000 }, + { 0x0700, 0x13af, 0x0000 }, + { 0x8700, 0x13b2, 0x2000 }, + { 0x0700, 0x13b1, 0x0000 }, + { 0x0700, 0x13b3, 0x0000 }, + { 0x8700, 0x13b8, 0x3000 }, + { 0x8700, 0x13b6, 0x2000 }, + { 0x0700, 0x13b5, 0x0000 }, + { 0x0700, 0x13b7, 0x0000 }, + { 0x8700, 0x13ba, 0x2000 }, + { 0x0700, 0x13b9, 0x0000 }, + { 0x0700, 0x13bb, 0x0000 }, + { 0x8700, 0x13c4, 0x4000 }, + { 0x8700, 0x13c0, 0x3000 }, + { 0x8700, 0x13be, 0x2000 }, + { 0x0700, 0x13bd, 0x0000 }, + { 0x0700, 0x13bf, 0x0000 }, + { 0x8700, 0x13c2, 0x2000 }, + { 0x0700, 0x13c1, 0x0000 }, + { 0x0700, 0x13c3, 0x0000 }, + { 0x8700, 0x13c8, 0x3000 }, + { 0x8700, 0x13c6, 0x2000 }, + { 0x0700, 0x13c5, 0x0000 }, + { 0x0700, 0x13c7, 0x0000 }, + { 0x8700, 0x13ca, 0x2000 }, + { 0x0700, 0x13c9, 0x0000 }, + { 0x0700, 0x13cb, 0x0000 }, + { 0x8700, 0x1418, 0x7000 }, + { 0x8700, 0x13ec, 0x6000 }, + { 0x8700, 0x13dc, 0x5000 }, + { 0x8700, 0x13d4, 0x4000 }, + { 0x8700, 0x13d0, 0x3000 }, + { 0x8700, 0x13ce, 0x2000 }, + { 0x0700, 0x13cd, 0x0000 }, + { 0x0700, 0x13cf, 0x0000 }, + { 0x8700, 0x13d2, 0x2000 }, + { 0x0700, 0x13d1, 0x0000 }, + { 0x0700, 0x13d3, 0x0000 }, + { 0x8700, 0x13d8, 0x3000 }, + { 0x8700, 0x13d6, 0x2000 }, + { 0x0700, 0x13d5, 0x0000 }, + { 0x0700, 0x13d7, 0x0000 }, + { 0x8700, 0x13da, 0x2000 }, + { 0x0700, 0x13d9, 0x0000 }, + { 0x0700, 0x13db, 0x0000 }, + { 0x8700, 0x13e4, 0x4000 }, + { 0x8700, 0x13e0, 0x3000 }, + { 0x8700, 0x13de, 0x2000 }, + { 0x0700, 0x13dd, 0x0000 }, + { 0x0700, 0x13df, 0x0000 }, + { 0x8700, 0x13e2, 0x2000 }, + { 0x0700, 0x13e1, 0x0000 }, + { 0x0700, 0x13e3, 0x0000 }, + { 0x8700, 0x13e8, 0x3000 }, + { 0x8700, 0x13e6, 0x2000 }, + { 0x0700, 0x13e5, 0x0000 }, + { 0x0700, 0x13e7, 0x0000 }, + { 0x8700, 0x13ea, 0x2000 }, + { 0x0700, 0x13e9, 0x0000 }, + { 0x0700, 0x13eb, 0x0000 }, + { 0x8700, 0x1408, 0x5000 }, + { 0x8700, 0x13f4, 0x4000 }, + { 0x8700, 0x13f0, 0x3000 }, + { 0x8700, 0x13ee, 0x2000 }, + { 0x0700, 0x13ed, 0x0000 }, + { 0x0700, 0x13ef, 0x0000 }, + { 0x8700, 0x13f2, 0x2000 }, + { 0x0700, 0x13f1, 0x0000 }, + { 0x0700, 0x13f3, 0x0000 }, + { 0x8700, 0x1404, 0x3000 }, + { 0x8700, 0x1402, 0x2000 }, + { 0x0700, 0x1401, 0x0000 }, + { 0x0700, 0x1403, 0x0000 }, + { 0x8700, 0x1406, 0x2000 }, + { 0x0700, 0x1405, 0x0000 }, + { 0x0700, 0x1407, 0x0000 }, + { 0x8700, 0x1410, 0x4000 }, + { 0x8700, 0x140c, 0x3000 }, + { 0x8700, 0x140a, 0x2000 }, + { 0x0700, 0x1409, 0x0000 }, + { 0x0700, 0x140b, 0x0000 }, + { 0x8700, 0x140e, 0x2000 }, + { 0x0700, 0x140d, 0x0000 }, + { 0x0700, 0x140f, 0x0000 }, + { 0x8700, 0x1414, 0x3000 }, + { 0x8700, 0x1412, 0x2000 }, + { 0x0700, 0x1411, 0x0000 }, + { 0x0700, 0x1413, 0x0000 }, + { 0x8700, 0x1416, 0x2000 }, + { 0x0700, 0x1415, 0x0000 }, + { 0x0700, 0x1417, 0x0000 }, + { 0x8700, 0x1438, 0x6000 }, + { 0x8700, 0x1428, 0x5000 }, + { 0x8700, 0x1420, 0x4000 }, + { 0x8700, 0x141c, 0x3000 }, + { 0x8700, 0x141a, 0x2000 }, + { 0x0700, 0x1419, 0x0000 }, + { 0x0700, 0x141b, 0x0000 }, + { 0x8700, 0x141e, 0x2000 }, + { 0x0700, 0x141d, 0x0000 }, + { 0x0700, 0x141f, 0x0000 }, + { 0x8700, 0x1424, 0x3000 }, + { 0x8700, 0x1422, 0x2000 }, + { 0x0700, 0x1421, 0x0000 }, + { 0x0700, 0x1423, 0x0000 }, + { 0x8700, 0x1426, 0x2000 }, + { 0x0700, 0x1425, 0x0000 }, + { 0x0700, 0x1427, 0x0000 }, + { 0x8700, 0x1430, 0x4000 }, + { 0x8700, 0x142c, 0x3000 }, + { 0x8700, 0x142a, 0x2000 }, + { 0x0700, 0x1429, 0x0000 }, + { 0x0700, 0x142b, 0x0000 }, + { 0x8700, 0x142e, 0x2000 }, + { 0x0700, 0x142d, 0x0000 }, + { 0x0700, 0x142f, 0x0000 }, + { 0x8700, 0x1434, 0x3000 }, + { 0x8700, 0x1432, 0x2000 }, + { 0x0700, 0x1431, 0x0000 }, + { 0x0700, 0x1433, 0x0000 }, + { 0x8700, 0x1436, 0x2000 }, + { 0x0700, 0x1435, 0x0000 }, + { 0x0700, 0x1437, 0x0000 }, + { 0x8700, 0x1448, 0x5000 }, + { 0x8700, 0x1440, 0x4000 }, + { 0x8700, 0x143c, 0x3000 }, + { 0x8700, 0x143a, 0x2000 }, + { 0x0700, 0x1439, 0x0000 }, + { 0x0700, 0x143b, 0x0000 }, + { 0x8700, 0x143e, 0x2000 }, + { 0x0700, 0x143d, 0x0000 }, + { 0x0700, 0x143f, 0x0000 }, + { 0x8700, 0x1444, 0x3000 }, + { 0x8700, 0x1442, 0x2000 }, + { 0x0700, 0x1441, 0x0000 }, + { 0x0700, 0x1443, 0x0000 }, + { 0x8700, 0x1446, 0x2000 }, + { 0x0700, 0x1445, 0x0000 }, + { 0x0700, 0x1447, 0x0000 }, + { 0x8700, 0x1450, 0x4000 }, + { 0x8700, 0x144c, 0x3000 }, + { 0x8700, 0x144a, 0x2000 }, + { 0x0700, 0x1449, 0x0000 }, + { 0x0700, 0x144b, 0x0000 }, + { 0x8700, 0x144e, 0x2000 }, + { 0x0700, 0x144d, 0x0000 }, + { 0x0700, 0x144f, 0x0000 }, + { 0x8700, 0x1454, 0x3000 }, + { 0x8700, 0x1452, 0x2000 }, + { 0x0700, 0x1451, 0x0000 }, + { 0x0700, 0x1453, 0x0000 }, + { 0x8700, 0x1456, 0x2000 }, + { 0x0700, 0x1455, 0x0000 }, + { 0x0700, 0x1457, 0x0000 }, + { 0x8700, 0x14d8, 0x8000 }, + { 0x8700, 0x1498, 0x7000 }, + { 0x8700, 0x1478, 0x6000 }, + { 0x8700, 0x1468, 0x5000 }, + { 0x8700, 0x1460, 0x4000 }, + { 0x8700, 0x145c, 0x3000 }, + { 0x8700, 0x145a, 0x2000 }, + { 0x0700, 0x1459, 0x0000 }, + { 0x0700, 0x145b, 0x0000 }, + { 0x8700, 0x145e, 0x2000 }, + { 0x0700, 0x145d, 0x0000 }, + { 0x0700, 0x145f, 0x0000 }, + { 0x8700, 0x1464, 0x3000 }, + { 0x8700, 0x1462, 0x2000 }, + { 0x0700, 0x1461, 0x0000 }, + { 0x0700, 0x1463, 0x0000 }, + { 0x8700, 0x1466, 0x2000 }, + { 0x0700, 0x1465, 0x0000 }, + { 0x0700, 0x1467, 0x0000 }, + { 0x8700, 0x1470, 0x4000 }, + { 0x8700, 0x146c, 0x3000 }, + { 0x8700, 0x146a, 0x2000 }, + { 0x0700, 0x1469, 0x0000 }, + { 0x0700, 0x146b, 0x0000 }, + { 0x8700, 0x146e, 0x2000 }, + { 0x0700, 0x146d, 0x0000 }, + { 0x0700, 0x146f, 0x0000 }, + { 0x8700, 0x1474, 0x3000 }, + { 0x8700, 0x1472, 0x2000 }, + { 0x0700, 0x1471, 0x0000 }, + { 0x0700, 0x1473, 0x0000 }, + { 0x8700, 0x1476, 0x2000 }, + { 0x0700, 0x1475, 0x0000 }, + { 0x0700, 0x1477, 0x0000 }, + { 0x8700, 0x1488, 0x5000 }, + { 0x8700, 0x1480, 0x4000 }, + { 0x8700, 0x147c, 0x3000 }, + { 0x8700, 0x147a, 0x2000 }, + { 0x0700, 0x1479, 0x0000 }, + { 0x0700, 0x147b, 0x0000 }, + { 0x8700, 0x147e, 0x2000 }, + { 0x0700, 0x147d, 0x0000 }, + { 0x0700, 0x147f, 0x0000 }, + { 0x8700, 0x1484, 0x3000 }, + { 0x8700, 0x1482, 0x2000 }, + { 0x0700, 0x1481, 0x0000 }, + { 0x0700, 0x1483, 0x0000 }, + { 0x8700, 0x1486, 0x2000 }, + { 0x0700, 0x1485, 0x0000 }, + { 0x0700, 0x1487, 0x0000 }, + { 0x8700, 0x1490, 0x4000 }, + { 0x8700, 0x148c, 0x3000 }, + { 0x8700, 0x148a, 0x2000 }, + { 0x0700, 0x1489, 0x0000 }, + { 0x0700, 0x148b, 0x0000 }, + { 0x8700, 0x148e, 0x2000 }, + { 0x0700, 0x148d, 0x0000 }, + { 0x0700, 0x148f, 0x0000 }, + { 0x8700, 0x1494, 0x3000 }, + { 0x8700, 0x1492, 0x2000 }, + { 0x0700, 0x1491, 0x0000 }, + { 0x0700, 0x1493, 0x0000 }, + { 0x8700, 0x1496, 0x2000 }, + { 0x0700, 0x1495, 0x0000 }, + { 0x0700, 0x1497, 0x0000 }, + { 0x8700, 0x14b8, 0x6000 }, + { 0x8700, 0x14a8, 0x5000 }, + { 0x8700, 0x14a0, 0x4000 }, + { 0x8700, 0x149c, 0x3000 }, + { 0x8700, 0x149a, 0x2000 }, + { 0x0700, 0x1499, 0x0000 }, + { 0x0700, 0x149b, 0x0000 }, + { 0x8700, 0x149e, 0x2000 }, + { 0x0700, 0x149d, 0x0000 }, + { 0x0700, 0x149f, 0x0000 }, + { 0x8700, 0x14a4, 0x3000 }, + { 0x8700, 0x14a2, 0x2000 }, + { 0x0700, 0x14a1, 0x0000 }, + { 0x0700, 0x14a3, 0x0000 }, + { 0x8700, 0x14a6, 0x2000 }, + { 0x0700, 0x14a5, 0x0000 }, + { 0x0700, 0x14a7, 0x0000 }, + { 0x8700, 0x14b0, 0x4000 }, + { 0x8700, 0x14ac, 0x3000 }, + { 0x8700, 0x14aa, 0x2000 }, + { 0x0700, 0x14a9, 0x0000 }, + { 0x0700, 0x14ab, 0x0000 }, + { 0x8700, 0x14ae, 0x2000 }, + { 0x0700, 0x14ad, 0x0000 }, + { 0x0700, 0x14af, 0x0000 }, + { 0x8700, 0x14b4, 0x3000 }, + { 0x8700, 0x14b2, 0x2000 }, + { 0x0700, 0x14b1, 0x0000 }, + { 0x0700, 0x14b3, 0x0000 }, + { 0x8700, 0x14b6, 0x2000 }, + { 0x0700, 0x14b5, 0x0000 }, + { 0x0700, 0x14b7, 0x0000 }, + { 0x8700, 0x14c8, 0x5000 }, + { 0x8700, 0x14c0, 0x4000 }, + { 0x8700, 0x14bc, 0x3000 }, + { 0x8700, 0x14ba, 0x2000 }, + { 0x0700, 0x14b9, 0x0000 }, + { 0x0700, 0x14bb, 0x0000 }, + { 0x8700, 0x14be, 0x2000 }, + { 0x0700, 0x14bd, 0x0000 }, + { 0x0700, 0x14bf, 0x0000 }, + { 0x8700, 0x14c4, 0x3000 }, + { 0x8700, 0x14c2, 0x2000 }, + { 0x0700, 0x14c1, 0x0000 }, + { 0x0700, 0x14c3, 0x0000 }, + { 0x8700, 0x14c6, 0x2000 }, + { 0x0700, 0x14c5, 0x0000 }, + { 0x0700, 0x14c7, 0x0000 }, + { 0x8700, 0x14d0, 0x4000 }, + { 0x8700, 0x14cc, 0x3000 }, + { 0x8700, 0x14ca, 0x2000 }, + { 0x0700, 0x14c9, 0x0000 }, + { 0x0700, 0x14cb, 0x0000 }, + { 0x8700, 0x14ce, 0x2000 }, + { 0x0700, 0x14cd, 0x0000 }, + { 0x0700, 0x14cf, 0x0000 }, + { 0x8700, 0x14d4, 0x3000 }, + { 0x8700, 0x14d2, 0x2000 }, + { 0x0700, 0x14d1, 0x0000 }, + { 0x0700, 0x14d3, 0x0000 }, + { 0x8700, 0x14d6, 0x2000 }, + { 0x0700, 0x14d5, 0x0000 }, + { 0x0700, 0x14d7, 0x0000 }, + { 0x8700, 0x1518, 0x7000 }, + { 0x8700, 0x14f8, 0x6000 }, + { 0x8700, 0x14e8, 0x5000 }, + { 0x8700, 0x14e0, 0x4000 }, + { 0x8700, 0x14dc, 0x3000 }, + { 0x8700, 0x14da, 0x2000 }, + { 0x0700, 0x14d9, 0x0000 }, + { 0x0700, 0x14db, 0x0000 }, + { 0x8700, 0x14de, 0x2000 }, + { 0x0700, 0x14dd, 0x0000 }, + { 0x0700, 0x14df, 0x0000 }, + { 0x8700, 0x14e4, 0x3000 }, + { 0x8700, 0x14e2, 0x2000 }, + { 0x0700, 0x14e1, 0x0000 }, + { 0x0700, 0x14e3, 0x0000 }, + { 0x8700, 0x14e6, 0x2000 }, + { 0x0700, 0x14e5, 0x0000 }, + { 0x0700, 0x14e7, 0x0000 }, + { 0x8700, 0x14f0, 0x4000 }, + { 0x8700, 0x14ec, 0x3000 }, + { 0x8700, 0x14ea, 0x2000 }, + { 0x0700, 0x14e9, 0x0000 }, + { 0x0700, 0x14eb, 0x0000 }, + { 0x8700, 0x14ee, 0x2000 }, + { 0x0700, 0x14ed, 0x0000 }, + { 0x0700, 0x14ef, 0x0000 }, + { 0x8700, 0x14f4, 0x3000 }, + { 0x8700, 0x14f2, 0x2000 }, + { 0x0700, 0x14f1, 0x0000 }, + { 0x0700, 0x14f3, 0x0000 }, + { 0x8700, 0x14f6, 0x2000 }, + { 0x0700, 0x14f5, 0x0000 }, + { 0x0700, 0x14f7, 0x0000 }, + { 0x8700, 0x1508, 0x5000 }, + { 0x8700, 0x1500, 0x4000 }, + { 0x8700, 0x14fc, 0x3000 }, + { 0x8700, 0x14fa, 0x2000 }, + { 0x0700, 0x14f9, 0x0000 }, + { 0x0700, 0x14fb, 0x0000 }, + { 0x8700, 0x14fe, 0x2000 }, + { 0x0700, 0x14fd, 0x0000 }, + { 0x0700, 0x14ff, 0x0000 }, + { 0x8700, 0x1504, 0x3000 }, + { 0x8700, 0x1502, 0x2000 }, + { 0x0700, 0x1501, 0x0000 }, + { 0x0700, 0x1503, 0x0000 }, + { 0x8700, 0x1506, 0x2000 }, + { 0x0700, 0x1505, 0x0000 }, + { 0x0700, 0x1507, 0x0000 }, + { 0x8700, 0x1510, 0x4000 }, + { 0x8700, 0x150c, 0x3000 }, + { 0x8700, 0x150a, 0x2000 }, + { 0x0700, 0x1509, 0x0000 }, + { 0x0700, 0x150b, 0x0000 }, + { 0x8700, 0x150e, 0x2000 }, + { 0x0700, 0x150d, 0x0000 }, + { 0x0700, 0x150f, 0x0000 }, + { 0x8700, 0x1514, 0x3000 }, + { 0x8700, 0x1512, 0x2000 }, + { 0x0700, 0x1511, 0x0000 }, + { 0x0700, 0x1513, 0x0000 }, + { 0x8700, 0x1516, 0x2000 }, + { 0x0700, 0x1515, 0x0000 }, + { 0x0700, 0x1517, 0x0000 }, + { 0x8700, 0x1538, 0x6000 }, + { 0x8700, 0x1528, 0x5000 }, + { 0x8700, 0x1520, 0x4000 }, + { 0x8700, 0x151c, 0x3000 }, + { 0x8700, 0x151a, 0x2000 }, + { 0x0700, 0x1519, 0x0000 }, + { 0x0700, 0x151b, 0x0000 }, + { 0x8700, 0x151e, 0x2000 }, + { 0x0700, 0x151d, 0x0000 }, + { 0x0700, 0x151f, 0x0000 }, + { 0x8700, 0x1524, 0x3000 }, + { 0x8700, 0x1522, 0x2000 }, + { 0x0700, 0x1521, 0x0000 }, + { 0x0700, 0x1523, 0x0000 }, + { 0x8700, 0x1526, 0x2000 }, + { 0x0700, 0x1525, 0x0000 }, + { 0x0700, 0x1527, 0x0000 }, + { 0x8700, 0x1530, 0x4000 }, + { 0x8700, 0x152c, 0x3000 }, + { 0x8700, 0x152a, 0x2000 }, + { 0x0700, 0x1529, 0x0000 }, + { 0x0700, 0x152b, 0x0000 }, + { 0x8700, 0x152e, 0x2000 }, + { 0x0700, 0x152d, 0x0000 }, + { 0x0700, 0x152f, 0x0000 }, + { 0x8700, 0x1534, 0x3000 }, + { 0x8700, 0x1532, 0x2000 }, + { 0x0700, 0x1531, 0x0000 }, + { 0x0700, 0x1533, 0x0000 }, + { 0x8700, 0x1536, 0x2000 }, + { 0x0700, 0x1535, 0x0000 }, + { 0x0700, 0x1537, 0x0000 }, + { 0x8700, 0x1548, 0x5000 }, + { 0x8700, 0x1540, 0x4000 }, + { 0x8700, 0x153c, 0x3000 }, + { 0x8700, 0x153a, 0x2000 }, + { 0x0700, 0x1539, 0x0000 }, + { 0x0700, 0x153b, 0x0000 }, + { 0x8700, 0x153e, 0x2000 }, + { 0x0700, 0x153d, 0x0000 }, + { 0x0700, 0x153f, 0x0000 }, + { 0x8700, 0x1544, 0x3000 }, + { 0x8700, 0x1542, 0x2000 }, + { 0x0700, 0x1541, 0x0000 }, + { 0x0700, 0x1543, 0x0000 }, + { 0x8700, 0x1546, 0x2000 }, + { 0x0700, 0x1545, 0x0000 }, + { 0x0700, 0x1547, 0x0000 }, + { 0x8700, 0x1550, 0x4000 }, + { 0x8700, 0x154c, 0x3000 }, + { 0x8700, 0x154a, 0x2000 }, + { 0x0700, 0x1549, 0x0000 }, + { 0x0700, 0x154b, 0x0000 }, + { 0x8700, 0x154e, 0x2000 }, + { 0x0700, 0x154d, 0x0000 }, + { 0x0700, 0x154f, 0x0000 }, + { 0x8700, 0x1554, 0x3000 }, + { 0x8700, 0x1552, 0x2000 }, + { 0x0700, 0x1551, 0x0000 }, + { 0x0700, 0x1553, 0x0000 }, + { 0x8700, 0x1556, 0x2000 }, + { 0x0700, 0x1555, 0x0000 }, + { 0x0700, 0x1557, 0x0000 }, + { 0x9900, 0x22ae, 0xc000 }, + { 0x8900, 0x1e24, 0xb001 }, + { 0x8700, 0x17a2, 0xa000 }, + { 0x8700, 0x1658, 0x9000 }, + { 0x8700, 0x15d8, 0x8000 }, + { 0x8700, 0x1598, 0x7000 }, + { 0x8700, 0x1578, 0x6000 }, + { 0x8700, 0x1568, 0x5000 }, + { 0x8700, 0x1560, 0x4000 }, + { 0x8700, 0x155c, 0x3000 }, + { 0x8700, 0x155a, 0x2000 }, + { 0x0700, 0x1559, 0x0000 }, + { 0x0700, 0x155b, 0x0000 }, + { 0x8700, 0x155e, 0x2000 }, + { 0x0700, 0x155d, 0x0000 }, + { 0x0700, 0x155f, 0x0000 }, + { 0x8700, 0x1564, 0x3000 }, + { 0x8700, 0x1562, 0x2000 }, + { 0x0700, 0x1561, 0x0000 }, + { 0x0700, 0x1563, 0x0000 }, + { 0x8700, 0x1566, 0x2000 }, + { 0x0700, 0x1565, 0x0000 }, + { 0x0700, 0x1567, 0x0000 }, + { 0x8700, 0x1570, 0x4000 }, + { 0x8700, 0x156c, 0x3000 }, + { 0x8700, 0x156a, 0x2000 }, + { 0x0700, 0x1569, 0x0000 }, + { 0x0700, 0x156b, 0x0000 }, + { 0x8700, 0x156e, 0x2000 }, + { 0x0700, 0x156d, 0x0000 }, + { 0x0700, 0x156f, 0x0000 }, + { 0x8700, 0x1574, 0x3000 }, + { 0x8700, 0x1572, 0x2000 }, + { 0x0700, 0x1571, 0x0000 }, + { 0x0700, 0x1573, 0x0000 }, + { 0x8700, 0x1576, 0x2000 }, + { 0x0700, 0x1575, 0x0000 }, + { 0x0700, 0x1577, 0x0000 }, + { 0x8700, 0x1588, 0x5000 }, + { 0x8700, 0x1580, 0x4000 }, + { 0x8700, 0x157c, 0x3000 }, + { 0x8700, 0x157a, 0x2000 }, + { 0x0700, 0x1579, 0x0000 }, + { 0x0700, 0x157b, 0x0000 }, + { 0x8700, 0x157e, 0x2000 }, + { 0x0700, 0x157d, 0x0000 }, + { 0x0700, 0x157f, 0x0000 }, + { 0x8700, 0x1584, 0x3000 }, + { 0x8700, 0x1582, 0x2000 }, + { 0x0700, 0x1581, 0x0000 }, + { 0x0700, 0x1583, 0x0000 }, + { 0x8700, 0x1586, 0x2000 }, + { 0x0700, 0x1585, 0x0000 }, + { 0x0700, 0x1587, 0x0000 }, + { 0x8700, 0x1590, 0x4000 }, + { 0x8700, 0x158c, 0x3000 }, + { 0x8700, 0x158a, 0x2000 }, + { 0x0700, 0x1589, 0x0000 }, + { 0x0700, 0x158b, 0x0000 }, + { 0x8700, 0x158e, 0x2000 }, + { 0x0700, 0x158d, 0x0000 }, + { 0x0700, 0x158f, 0x0000 }, + { 0x8700, 0x1594, 0x3000 }, + { 0x8700, 0x1592, 0x2000 }, + { 0x0700, 0x1591, 0x0000 }, + { 0x0700, 0x1593, 0x0000 }, + { 0x8700, 0x1596, 0x2000 }, + { 0x0700, 0x1595, 0x0000 }, + { 0x0700, 0x1597, 0x0000 }, + { 0x8700, 0x15b8, 0x6000 }, + { 0x8700, 0x15a8, 0x5000 }, + { 0x8700, 0x15a0, 0x4000 }, + { 0x8700, 0x159c, 0x3000 }, + { 0x8700, 0x159a, 0x2000 }, + { 0x0700, 0x1599, 0x0000 }, + { 0x0700, 0x159b, 0x0000 }, + { 0x8700, 0x159e, 0x2000 }, + { 0x0700, 0x159d, 0x0000 }, + { 0x0700, 0x159f, 0x0000 }, + { 0x8700, 0x15a4, 0x3000 }, + { 0x8700, 0x15a2, 0x2000 }, + { 0x0700, 0x15a1, 0x0000 }, + { 0x0700, 0x15a3, 0x0000 }, + { 0x8700, 0x15a6, 0x2000 }, + { 0x0700, 0x15a5, 0x0000 }, + { 0x0700, 0x15a7, 0x0000 }, + { 0x8700, 0x15b0, 0x4000 }, + { 0x8700, 0x15ac, 0x3000 }, + { 0x8700, 0x15aa, 0x2000 }, + { 0x0700, 0x15a9, 0x0000 }, + { 0x0700, 0x15ab, 0x0000 }, + { 0x8700, 0x15ae, 0x2000 }, + { 0x0700, 0x15ad, 0x0000 }, + { 0x0700, 0x15af, 0x0000 }, + { 0x8700, 0x15b4, 0x3000 }, + { 0x8700, 0x15b2, 0x2000 }, + { 0x0700, 0x15b1, 0x0000 }, + { 0x0700, 0x15b3, 0x0000 }, + { 0x8700, 0x15b6, 0x2000 }, + { 0x0700, 0x15b5, 0x0000 }, + { 0x0700, 0x15b7, 0x0000 }, + { 0x8700, 0x15c8, 0x5000 }, + { 0x8700, 0x15c0, 0x4000 }, + { 0x8700, 0x15bc, 0x3000 }, + { 0x8700, 0x15ba, 0x2000 }, + { 0x0700, 0x15b9, 0x0000 }, + { 0x0700, 0x15bb, 0x0000 }, + { 0x8700, 0x15be, 0x2000 }, + { 0x0700, 0x15bd, 0x0000 }, + { 0x0700, 0x15bf, 0x0000 }, + { 0x8700, 0x15c4, 0x3000 }, + { 0x8700, 0x15c2, 0x2000 }, + { 0x0700, 0x15c1, 0x0000 }, + { 0x0700, 0x15c3, 0x0000 }, + { 0x8700, 0x15c6, 0x2000 }, + { 0x0700, 0x15c5, 0x0000 }, + { 0x0700, 0x15c7, 0x0000 }, + { 0x8700, 0x15d0, 0x4000 }, + { 0x8700, 0x15cc, 0x3000 }, + { 0x8700, 0x15ca, 0x2000 }, + { 0x0700, 0x15c9, 0x0000 }, + { 0x0700, 0x15cb, 0x0000 }, + { 0x8700, 0x15ce, 0x2000 }, + { 0x0700, 0x15cd, 0x0000 }, + { 0x0700, 0x15cf, 0x0000 }, + { 0x8700, 0x15d4, 0x3000 }, + { 0x8700, 0x15d2, 0x2000 }, + { 0x0700, 0x15d1, 0x0000 }, + { 0x0700, 0x15d3, 0x0000 }, + { 0x8700, 0x15d6, 0x2000 }, + { 0x0700, 0x15d5, 0x0000 }, + { 0x0700, 0x15d7, 0x0000 }, + { 0x8700, 0x1618, 0x7000 }, + { 0x8700, 0x15f8, 0x6000 }, + { 0x8700, 0x15e8, 0x5000 }, + { 0x8700, 0x15e0, 0x4000 }, + { 0x8700, 0x15dc, 0x3000 }, + { 0x8700, 0x15da, 0x2000 }, + { 0x0700, 0x15d9, 0x0000 }, + { 0x0700, 0x15db, 0x0000 }, + { 0x8700, 0x15de, 0x2000 }, + { 0x0700, 0x15dd, 0x0000 }, + { 0x0700, 0x15df, 0x0000 }, + { 0x8700, 0x15e4, 0x3000 }, + { 0x8700, 0x15e2, 0x2000 }, + { 0x0700, 0x15e1, 0x0000 }, + { 0x0700, 0x15e3, 0x0000 }, + { 0x8700, 0x15e6, 0x2000 }, + { 0x0700, 0x15e5, 0x0000 }, + { 0x0700, 0x15e7, 0x0000 }, + { 0x8700, 0x15f0, 0x4000 }, + { 0x8700, 0x15ec, 0x3000 }, + { 0x8700, 0x15ea, 0x2000 }, + { 0x0700, 0x15e9, 0x0000 }, + { 0x0700, 0x15eb, 0x0000 }, + { 0x8700, 0x15ee, 0x2000 }, + { 0x0700, 0x15ed, 0x0000 }, + { 0x0700, 0x15ef, 0x0000 }, + { 0x8700, 0x15f4, 0x3000 }, + { 0x8700, 0x15f2, 0x2000 }, + { 0x0700, 0x15f1, 0x0000 }, + { 0x0700, 0x15f3, 0x0000 }, + { 0x8700, 0x15f6, 0x2000 }, + { 0x0700, 0x15f5, 0x0000 }, + { 0x0700, 0x15f7, 0x0000 }, + { 0x8700, 0x1608, 0x5000 }, + { 0x8700, 0x1600, 0x4000 }, + { 0x8700, 0x15fc, 0x3000 }, + { 0x8700, 0x15fa, 0x2000 }, + { 0x0700, 0x15f9, 0x0000 }, + { 0x0700, 0x15fb, 0x0000 }, + { 0x8700, 0x15fe, 0x2000 }, + { 0x0700, 0x15fd, 0x0000 }, + { 0x0700, 0x15ff, 0x0000 }, + { 0x8700, 0x1604, 0x3000 }, + { 0x8700, 0x1602, 0x2000 }, + { 0x0700, 0x1601, 0x0000 }, + { 0x0700, 0x1603, 0x0000 }, + { 0x8700, 0x1606, 0x2000 }, + { 0x0700, 0x1605, 0x0000 }, + { 0x0700, 0x1607, 0x0000 }, + { 0x8700, 0x1610, 0x4000 }, + { 0x8700, 0x160c, 0x3000 }, + { 0x8700, 0x160a, 0x2000 }, + { 0x0700, 0x1609, 0x0000 }, + { 0x0700, 0x160b, 0x0000 }, + { 0x8700, 0x160e, 0x2000 }, + { 0x0700, 0x160d, 0x0000 }, + { 0x0700, 0x160f, 0x0000 }, + { 0x8700, 0x1614, 0x3000 }, + { 0x8700, 0x1612, 0x2000 }, + { 0x0700, 0x1611, 0x0000 }, + { 0x0700, 0x1613, 0x0000 }, + { 0x8700, 0x1616, 0x2000 }, + { 0x0700, 0x1615, 0x0000 }, + { 0x0700, 0x1617, 0x0000 }, + { 0x8700, 0x1638, 0x6000 }, + { 0x8700, 0x1628, 0x5000 }, + { 0x8700, 0x1620, 0x4000 }, + { 0x8700, 0x161c, 0x3000 }, + { 0x8700, 0x161a, 0x2000 }, + { 0x0700, 0x1619, 0x0000 }, + { 0x0700, 0x161b, 0x0000 }, + { 0x8700, 0x161e, 0x2000 }, + { 0x0700, 0x161d, 0x0000 }, + { 0x0700, 0x161f, 0x0000 }, + { 0x8700, 0x1624, 0x3000 }, + { 0x8700, 0x1622, 0x2000 }, + { 0x0700, 0x1621, 0x0000 }, + { 0x0700, 0x1623, 0x0000 }, + { 0x8700, 0x1626, 0x2000 }, + { 0x0700, 0x1625, 0x0000 }, + { 0x0700, 0x1627, 0x0000 }, + { 0x8700, 0x1630, 0x4000 }, + { 0x8700, 0x162c, 0x3000 }, + { 0x8700, 0x162a, 0x2000 }, + { 0x0700, 0x1629, 0x0000 }, + { 0x0700, 0x162b, 0x0000 }, + { 0x8700, 0x162e, 0x2000 }, + { 0x0700, 0x162d, 0x0000 }, + { 0x0700, 0x162f, 0x0000 }, + { 0x8700, 0x1634, 0x3000 }, + { 0x8700, 0x1632, 0x2000 }, + { 0x0700, 0x1631, 0x0000 }, + { 0x0700, 0x1633, 0x0000 }, + { 0x8700, 0x1636, 0x2000 }, + { 0x0700, 0x1635, 0x0000 }, + { 0x0700, 0x1637, 0x0000 }, + { 0x8700, 0x1648, 0x5000 }, + { 0x8700, 0x1640, 0x4000 }, + { 0x8700, 0x163c, 0x3000 }, + { 0x8700, 0x163a, 0x2000 }, + { 0x0700, 0x1639, 0x0000 }, + { 0x0700, 0x163b, 0x0000 }, + { 0x8700, 0x163e, 0x2000 }, + { 0x0700, 0x163d, 0x0000 }, + { 0x0700, 0x163f, 0x0000 }, + { 0x8700, 0x1644, 0x3000 }, + { 0x8700, 0x1642, 0x2000 }, + { 0x0700, 0x1641, 0x0000 }, + { 0x0700, 0x1643, 0x0000 }, + { 0x8700, 0x1646, 0x2000 }, + { 0x0700, 0x1645, 0x0000 }, + { 0x0700, 0x1647, 0x0000 }, + { 0x8700, 0x1650, 0x4000 }, + { 0x8700, 0x164c, 0x3000 }, + { 0x8700, 0x164a, 0x2000 }, + { 0x0700, 0x1649, 0x0000 }, + { 0x0700, 0x164b, 0x0000 }, + { 0x8700, 0x164e, 0x2000 }, + { 0x0700, 0x164d, 0x0000 }, + { 0x0700, 0x164f, 0x0000 }, + { 0x8700, 0x1654, 0x3000 }, + { 0x8700, 0x1652, 0x2000 }, + { 0x0700, 0x1651, 0x0000 }, + { 0x0700, 0x1653, 0x0000 }, + { 0x8700, 0x1656, 0x2000 }, + { 0x0700, 0x1655, 0x0000 }, + { 0x0700, 0x1657, 0x0000 }, + { 0x8700, 0x16e4, 0x8000 }, + { 0x8700, 0x16a4, 0x7000 }, + { 0x8700, 0x1681, 0x6000 }, + { 0x8700, 0x1668, 0x5000 }, + { 0x8700, 0x1660, 0x4000 }, + { 0x8700, 0x165c, 0x3000 }, + { 0x8700, 0x165a, 0x2000 }, + { 0x0700, 0x1659, 0x0000 }, + { 0x0700, 0x165b, 0x0000 }, + { 0x8700, 0x165e, 0x2000 }, + { 0x0700, 0x165d, 0x0000 }, + { 0x0700, 0x165f, 0x0000 }, + { 0x8700, 0x1664, 0x3000 }, + { 0x8700, 0x1662, 0x2000 }, + { 0x0700, 0x1661, 0x0000 }, + { 0x0700, 0x1663, 0x0000 }, + { 0x8700, 0x1666, 0x2000 }, + { 0x0700, 0x1665, 0x0000 }, + { 0x0700, 0x1667, 0x0000 }, + { 0x8700, 0x1670, 0x4000 }, + { 0x8700, 0x166c, 0x3000 }, + { 0x8700, 0x166a, 0x2000 }, + { 0x0700, 0x1669, 0x0000 }, + { 0x0700, 0x166b, 0x0000 }, + { 0x9500, 0x166e, 0x2000 }, + { 0x1500, 0x166d, 0x0000 }, + { 0x0700, 0x166f, 0x0000 }, + { 0x8700, 0x1674, 0x3000 }, + { 0x8700, 0x1672, 0x2000 }, + { 0x0700, 0x1671, 0x0000 }, + { 0x0700, 0x1673, 0x0000 }, + { 0x8700, 0x1676, 0x2000 }, + { 0x0700, 0x1675, 0x0000 }, + { 0x1d00, 0x1680, 0x0000 }, + { 0x8700, 0x1691, 0x5000 }, + { 0x8700, 0x1689, 0x4000 }, + { 0x8700, 0x1685, 0x3000 }, + { 0x8700, 0x1683, 0x2000 }, + { 0x0700, 0x1682, 0x0000 }, + { 0x0700, 0x1684, 0x0000 }, + { 0x8700, 0x1687, 0x2000 }, + { 0x0700, 0x1686, 0x0000 }, + { 0x0700, 0x1688, 0x0000 }, + { 0x8700, 0x168d, 0x3000 }, + { 0x8700, 0x168b, 0x2000 }, + { 0x0700, 0x168a, 0x0000 }, + { 0x0700, 0x168c, 0x0000 }, + { 0x8700, 0x168f, 0x2000 }, + { 0x0700, 0x168e, 0x0000 }, + { 0x0700, 0x1690, 0x0000 }, + { 0x8700, 0x1699, 0x4000 }, + { 0x8700, 0x1695, 0x3000 }, + { 0x8700, 0x1693, 0x2000 }, + { 0x0700, 0x1692, 0x0000 }, + { 0x0700, 0x1694, 0x0000 }, + { 0x8700, 0x1697, 0x2000 }, + { 0x0700, 0x1696, 0x0000 }, + { 0x0700, 0x1698, 0x0000 }, + { 0x8700, 0x16a0, 0x3000 }, + { 0x9600, 0x169b, 0x2000 }, + { 0x0700, 0x169a, 0x0000 }, + { 0x1200, 0x169c, 0x0000 }, + { 0x8700, 0x16a2, 0x2000 }, + { 0x0700, 0x16a1, 0x0000 }, + { 0x0700, 0x16a3, 0x0000 }, + { 0x8700, 0x16c4, 0x6000 }, + { 0x8700, 0x16b4, 0x5000 }, + { 0x8700, 0x16ac, 0x4000 }, + { 0x8700, 0x16a8, 0x3000 }, + { 0x8700, 0x16a6, 0x2000 }, + { 0x0700, 0x16a5, 0x0000 }, + { 0x0700, 0x16a7, 0x0000 }, + { 0x8700, 0x16aa, 0x2000 }, + { 0x0700, 0x16a9, 0x0000 }, + { 0x0700, 0x16ab, 0x0000 }, + { 0x8700, 0x16b0, 0x3000 }, + { 0x8700, 0x16ae, 0x2000 }, + { 0x0700, 0x16ad, 0x0000 }, + { 0x0700, 0x16af, 0x0000 }, + { 0x8700, 0x16b2, 0x2000 }, + { 0x0700, 0x16b1, 0x0000 }, + { 0x0700, 0x16b3, 0x0000 }, + { 0x8700, 0x16bc, 0x4000 }, + { 0x8700, 0x16b8, 0x3000 }, + { 0x8700, 0x16b6, 0x2000 }, + { 0x0700, 0x16b5, 0x0000 }, + { 0x0700, 0x16b7, 0x0000 }, + { 0x8700, 0x16ba, 0x2000 }, + { 0x0700, 0x16b9, 0x0000 }, + { 0x0700, 0x16bb, 0x0000 }, + { 0x8700, 0x16c0, 0x3000 }, + { 0x8700, 0x16be, 0x2000 }, + { 0x0700, 0x16bd, 0x0000 }, + { 0x0700, 0x16bf, 0x0000 }, + { 0x8700, 0x16c2, 0x2000 }, + { 0x0700, 0x16c1, 0x0000 }, + { 0x0700, 0x16c3, 0x0000 }, + { 0x8700, 0x16d4, 0x5000 }, + { 0x8700, 0x16cc, 0x4000 }, + { 0x8700, 0x16c8, 0x3000 }, + { 0x8700, 0x16c6, 0x2000 }, + { 0x0700, 0x16c5, 0x0000 }, + { 0x0700, 0x16c7, 0x0000 }, + { 0x8700, 0x16ca, 0x2000 }, + { 0x0700, 0x16c9, 0x0000 }, + { 0x0700, 0x16cb, 0x0000 }, + { 0x8700, 0x16d0, 0x3000 }, + { 0x8700, 0x16ce, 0x2000 }, + { 0x0700, 0x16cd, 0x0000 }, + { 0x0700, 0x16cf, 0x0000 }, + { 0x8700, 0x16d2, 0x2000 }, + { 0x0700, 0x16d1, 0x0000 }, + { 0x0700, 0x16d3, 0x0000 }, + { 0x8700, 0x16dc, 0x4000 }, + { 0x8700, 0x16d8, 0x3000 }, + { 0x8700, 0x16d6, 0x2000 }, + { 0x0700, 0x16d5, 0x0000 }, + { 0x0700, 0x16d7, 0x0000 }, + { 0x8700, 0x16da, 0x2000 }, + { 0x0700, 0x16d9, 0x0000 }, + { 0x0700, 0x16db, 0x0000 }, + { 0x8700, 0x16e0, 0x3000 }, + { 0x8700, 0x16de, 0x2000 }, + { 0x0700, 0x16dd, 0x0000 }, + { 0x0700, 0x16df, 0x0000 }, + { 0x8700, 0x16e2, 0x2000 }, + { 0x0700, 0x16e1, 0x0000 }, + { 0x0700, 0x16e3, 0x0000 }, + { 0x8700, 0x1748, 0x7000 }, + { 0x8c00, 0x1714, 0x6000 }, + { 0x8700, 0x1703, 0x5000 }, + { 0x9500, 0x16ec, 0x4000 }, + { 0x8700, 0x16e8, 0x3000 }, + { 0x8700, 0x16e6, 0x2000 }, + { 0x0700, 0x16e5, 0x0000 }, + { 0x0700, 0x16e7, 0x0000 }, + { 0x8700, 0x16ea, 0x2000 }, + { 0x0700, 0x16e9, 0x0000 }, + { 0x1500, 0x16eb, 0x0000 }, + { 0x8e00, 0x16f0, 0x3000 }, + { 0x8e00, 0x16ee, 0x2000 }, + { 0x1500, 0x16ed, 0x0000 }, + { 0x0e00, 0x16ef, 0x0000 }, + { 0x8700, 0x1701, 0x2000 }, + { 0x0700, 0x1700, 0x0000 }, + { 0x0700, 0x1702, 0x0000 }, + { 0x8700, 0x170b, 0x4000 }, + { 0x8700, 0x1707, 0x3000 }, + { 0x8700, 0x1705, 0x2000 }, + { 0x0700, 0x1704, 0x0000 }, + { 0x0700, 0x1706, 0x0000 }, + { 0x8700, 0x1709, 0x2000 }, + { 0x0700, 0x1708, 0x0000 }, + { 0x0700, 0x170a, 0x0000 }, + { 0x8700, 0x1710, 0x3000 }, + { 0x8700, 0x170e, 0x2000 }, + { 0x0700, 0x170c, 0x0000 }, + { 0x0700, 0x170f, 0x0000 }, + { 0x8c00, 0x1712, 0x2000 }, + { 0x0700, 0x1711, 0x0000 }, + { 0x0c00, 0x1713, 0x0000 }, + { 0x8700, 0x172f, 0x5000 }, + { 0x8700, 0x1727, 0x4000 }, + { 0x8700, 0x1723, 0x3000 }, + { 0x8700, 0x1721, 0x2000 }, + { 0x0700, 0x1720, 0x0000 }, + { 0x0700, 0x1722, 0x0000 }, + { 0x8700, 0x1725, 0x2000 }, + { 0x0700, 0x1724, 0x0000 }, + { 0x0700, 0x1726, 0x0000 }, + { 0x8700, 0x172b, 0x3000 }, + { 0x8700, 0x1729, 0x2000 }, + { 0x0700, 0x1728, 0x0000 }, + { 0x0700, 0x172a, 0x0000 }, + { 0x8700, 0x172d, 0x2000 }, + { 0x0700, 0x172c, 0x0000 }, + { 0x0700, 0x172e, 0x0000 }, + { 0x8700, 0x1740, 0x4000 }, + { 0x8c00, 0x1733, 0x3000 }, + { 0x8700, 0x1731, 0x2000 }, + { 0x0700, 0x1730, 0x0000 }, + { 0x0c00, 0x1732, 0x0000 }, + { 0x9500, 0x1735, 0x2000 }, + { 0x0c00, 0x1734, 0x0000 }, + { 0x1500, 0x1736, 0x0000 }, + { 0x8700, 0x1744, 0x3000 }, + { 0x8700, 0x1742, 0x2000 }, + { 0x0700, 0x1741, 0x0000 }, + { 0x0700, 0x1743, 0x0000 }, + { 0x8700, 0x1746, 0x2000 }, + { 0x0700, 0x1745, 0x0000 }, + { 0x0700, 0x1747, 0x0000 }, + { 0x8700, 0x1782, 0x6000 }, + { 0x8700, 0x1764, 0x5000 }, + { 0x8700, 0x1750, 0x4000 }, + { 0x8700, 0x174c, 0x3000 }, + { 0x8700, 0x174a, 0x2000 }, + { 0x0700, 0x1749, 0x0000 }, + { 0x0700, 0x174b, 0x0000 }, + { 0x8700, 0x174e, 0x2000 }, + { 0x0700, 0x174d, 0x0000 }, + { 0x0700, 0x174f, 0x0000 }, + { 0x8700, 0x1760, 0x3000 }, + { 0x8c00, 0x1752, 0x2000 }, + { 0x0700, 0x1751, 0x0000 }, + { 0x0c00, 0x1753, 0x0000 }, + { 0x8700, 0x1762, 0x2000 }, + { 0x0700, 0x1761, 0x0000 }, + { 0x0700, 0x1763, 0x0000 }, + { 0x8700, 0x176c, 0x4000 }, + { 0x8700, 0x1768, 0x3000 }, + { 0x8700, 0x1766, 0x2000 }, + { 0x0700, 0x1765, 0x0000 }, + { 0x0700, 0x1767, 0x0000 }, + { 0x8700, 0x176a, 0x2000 }, + { 0x0700, 0x1769, 0x0000 }, + { 0x0700, 0x176b, 0x0000 }, + { 0x8c00, 0x1772, 0x3000 }, + { 0x8700, 0x176f, 0x2000 }, + { 0x0700, 0x176e, 0x0000 }, + { 0x0700, 0x1770, 0x0000 }, + { 0x8700, 0x1780, 0x2000 }, + { 0x0c00, 0x1773, 0x0000 }, + { 0x0700, 0x1781, 0x0000 }, + { 0x8700, 0x1792, 0x5000 }, + { 0x8700, 0x178a, 0x4000 }, + { 0x8700, 0x1786, 0x3000 }, + { 0x8700, 0x1784, 0x2000 }, + { 0x0700, 0x1783, 0x0000 }, + { 0x0700, 0x1785, 0x0000 }, + { 0x8700, 0x1788, 0x2000 }, + { 0x0700, 0x1787, 0x0000 }, + { 0x0700, 0x1789, 0x0000 }, + { 0x8700, 0x178e, 0x3000 }, + { 0x8700, 0x178c, 0x2000 }, + { 0x0700, 0x178b, 0x0000 }, + { 0x0700, 0x178d, 0x0000 }, + { 0x8700, 0x1790, 0x2000 }, + { 0x0700, 0x178f, 0x0000 }, + { 0x0700, 0x1791, 0x0000 }, + { 0x8700, 0x179a, 0x4000 }, + { 0x8700, 0x1796, 0x3000 }, + { 0x8700, 0x1794, 0x2000 }, + { 0x0700, 0x1793, 0x0000 }, + { 0x0700, 0x1795, 0x0000 }, + { 0x8700, 0x1798, 0x2000 }, + { 0x0700, 0x1797, 0x0000 }, + { 0x0700, 0x1799, 0x0000 }, + { 0x8700, 0x179e, 0x3000 }, + { 0x8700, 0x179c, 0x2000 }, + { 0x0700, 0x179b, 0x0000 }, + { 0x0700, 0x179d, 0x0000 }, + { 0x8700, 0x17a0, 0x2000 }, + { 0x0700, 0x179f, 0x0000 }, + { 0x0700, 0x17a1, 0x0000 }, + { 0x8700, 0x1915, 0x9000 }, + { 0x8700, 0x1837, 0x8000 }, + { 0x8d00, 0x17e4, 0x7000 }, + { 0x8a00, 0x17c2, 0x6000 }, + { 0x8700, 0x17b2, 0x5000 }, + { 0x8700, 0x17aa, 0x4000 }, + { 0x8700, 0x17a6, 0x3000 }, + { 0x8700, 0x17a4, 0x2000 }, + { 0x0700, 0x17a3, 0x0000 }, + { 0x0700, 0x17a5, 0x0000 }, + { 0x8700, 0x17a8, 0x2000 }, + { 0x0700, 0x17a7, 0x0000 }, + { 0x0700, 0x17a9, 0x0000 }, + { 0x8700, 0x17ae, 0x3000 }, + { 0x8700, 0x17ac, 0x2000 }, + { 0x0700, 0x17ab, 0x0000 }, + { 0x0700, 0x17ad, 0x0000 }, + { 0x8700, 0x17b0, 0x2000 }, + { 0x0700, 0x17af, 0x0000 }, + { 0x0700, 0x17b1, 0x0000 }, + { 0x8c00, 0x17ba, 0x4000 }, + { 0x8a00, 0x17b6, 0x3000 }, + { 0x8100, 0x17b4, 0x2000 }, + { 0x0700, 0x17b3, 0x0000 }, + { 0x0100, 0x17b5, 0x0000 }, + { 0x8c00, 0x17b8, 0x2000 }, + { 0x0c00, 0x17b7, 0x0000 }, + { 0x0c00, 0x17b9, 0x0000 }, + { 0x8a00, 0x17be, 0x3000 }, + { 0x8c00, 0x17bc, 0x2000 }, + { 0x0c00, 0x17bb, 0x0000 }, + { 0x0c00, 0x17bd, 0x0000 }, + { 0x8a00, 0x17c0, 0x2000 }, + { 0x0a00, 0x17bf, 0x0000 }, + { 0x0a00, 0x17c1, 0x0000 }, + { 0x8c00, 0x17d2, 0x5000 }, + { 0x8c00, 0x17ca, 0x4000 }, + { 0x8c00, 0x17c6, 0x3000 }, + { 0x8a00, 0x17c4, 0x2000 }, + { 0x0a00, 0x17c3, 0x0000 }, + { 0x0a00, 0x17c5, 0x0000 }, + { 0x8a00, 0x17c8, 0x2000 }, + { 0x0a00, 0x17c7, 0x0000 }, + { 0x0c00, 0x17c9, 0x0000 }, + { 0x8c00, 0x17ce, 0x3000 }, + { 0x8c00, 0x17cc, 0x2000 }, + { 0x0c00, 0x17cb, 0x0000 }, + { 0x0c00, 0x17cd, 0x0000 }, + { 0x8c00, 0x17d0, 0x2000 }, + { 0x0c00, 0x17cf, 0x0000 }, + { 0x0c00, 0x17d1, 0x0000 }, + { 0x9500, 0x17da, 0x4000 }, + { 0x9500, 0x17d6, 0x3000 }, + { 0x9500, 0x17d4, 0x2000 }, + { 0x0c00, 0x17d3, 0x0000 }, + { 0x1500, 0x17d5, 0x0000 }, + { 0x9500, 0x17d8, 0x2000 }, + { 0x0600, 0x17d7, 0x0000 }, + { 0x1500, 0x17d9, 0x0000 }, + { 0x8d00, 0x17e0, 0x3000 }, + { 0x8700, 0x17dc, 0x2000 }, + { 0x1700, 0x17db, 0x0000 }, + { 0x0c00, 0x17dd, 0x0000 }, + { 0x8d00, 0x17e2, 0x2000 }, + { 0x0d00, 0x17e1, 0x0000 }, + { 0x0d00, 0x17e3, 0x0000 }, + { 0x8d00, 0x1811, 0x6000 }, + { 0x9500, 0x1800, 0x5000 }, + { 0x8f00, 0x17f2, 0x4000 }, + { 0x8d00, 0x17e8, 0x3000 }, + { 0x8d00, 0x17e6, 0x2000 }, + { 0x0d00, 0x17e5, 0x0000 }, + { 0x0d00, 0x17e7, 0x0000 }, + { 0x8f00, 0x17f0, 0x2000 }, + { 0x0d00, 0x17e9, 0x0000 }, + { 0x0f00, 0x17f1, 0x0000 }, + { 0x8f00, 0x17f6, 0x3000 }, + { 0x8f00, 0x17f4, 0x2000 }, + { 0x0f00, 0x17f3, 0x0000 }, + { 0x0f00, 0x17f5, 0x0000 }, + { 0x8f00, 0x17f8, 0x2000 }, + { 0x0f00, 0x17f7, 0x0000 }, + { 0x0f00, 0x17f9, 0x0000 }, + { 0x9500, 0x1808, 0x4000 }, + { 0x9500, 0x1804, 0x3000 }, + { 0x9500, 0x1802, 0x2000 }, + { 0x1500, 0x1801, 0x0000 }, + { 0x1500, 0x1803, 0x0000 }, + { 0x9100, 0x1806, 0x2000 }, + { 0x1500, 0x1805, 0x0000 }, + { 0x1500, 0x1807, 0x0000 }, + { 0x8c00, 0x180c, 0x3000 }, + { 0x9500, 0x180a, 0x2000 }, + { 0x1500, 0x1809, 0x0000 }, + { 0x0c00, 0x180b, 0x0000 }, + { 0x9d00, 0x180e, 0x2000 }, + { 0x0c00, 0x180d, 0x0000 }, + { 0x0d00, 0x1810, 0x0000 }, + { 0x8700, 0x1827, 0x5000 }, + { 0x8d00, 0x1819, 0x4000 }, + { 0x8d00, 0x1815, 0x3000 }, + { 0x8d00, 0x1813, 0x2000 }, + { 0x0d00, 0x1812, 0x0000 }, + { 0x0d00, 0x1814, 0x0000 }, + { 0x8d00, 0x1817, 0x2000 }, + { 0x0d00, 0x1816, 0x0000 }, + { 0x0d00, 0x1818, 0x0000 }, + { 0x8700, 0x1823, 0x3000 }, + { 0x8700, 0x1821, 0x2000 }, + { 0x0700, 0x1820, 0x0000 }, + { 0x0700, 0x1822, 0x0000 }, + { 0x8700, 0x1825, 0x2000 }, + { 0x0700, 0x1824, 0x0000 }, + { 0x0700, 0x1826, 0x0000 }, + { 0x8700, 0x182f, 0x4000 }, + { 0x8700, 0x182b, 0x3000 }, + { 0x8700, 0x1829, 0x2000 }, + { 0x0700, 0x1828, 0x0000 }, + { 0x0700, 0x182a, 0x0000 }, + { 0x8700, 0x182d, 0x2000 }, + { 0x0700, 0x182c, 0x0000 }, + { 0x0700, 0x182e, 0x0000 }, + { 0x8700, 0x1833, 0x3000 }, + { 0x8700, 0x1831, 0x2000 }, + { 0x0700, 0x1830, 0x0000 }, + { 0x0700, 0x1832, 0x0000 }, + { 0x8700, 0x1835, 0x2000 }, + { 0x0700, 0x1834, 0x0000 }, + { 0x0700, 0x1836, 0x0000 }, + { 0x8700, 0x1877, 0x7000 }, + { 0x8700, 0x1857, 0x6000 }, + { 0x8700, 0x1847, 0x5000 }, + { 0x8700, 0x183f, 0x4000 }, + { 0x8700, 0x183b, 0x3000 }, + { 0x8700, 0x1839, 0x2000 }, + { 0x0700, 0x1838, 0x0000 }, + { 0x0700, 0x183a, 0x0000 }, + { 0x8700, 0x183d, 0x2000 }, + { 0x0700, 0x183c, 0x0000 }, + { 0x0700, 0x183e, 0x0000 }, + { 0x8600, 0x1843, 0x3000 }, + { 0x8700, 0x1841, 0x2000 }, + { 0x0700, 0x1840, 0x0000 }, + { 0x0700, 0x1842, 0x0000 }, + { 0x8700, 0x1845, 0x2000 }, + { 0x0700, 0x1844, 0x0000 }, + { 0x0700, 0x1846, 0x0000 }, + { 0x8700, 0x184f, 0x4000 }, + { 0x8700, 0x184b, 0x3000 }, + { 0x8700, 0x1849, 0x2000 }, + { 0x0700, 0x1848, 0x0000 }, + { 0x0700, 0x184a, 0x0000 }, + { 0x8700, 0x184d, 0x2000 }, + { 0x0700, 0x184c, 0x0000 }, + { 0x0700, 0x184e, 0x0000 }, + { 0x8700, 0x1853, 0x3000 }, + { 0x8700, 0x1851, 0x2000 }, + { 0x0700, 0x1850, 0x0000 }, + { 0x0700, 0x1852, 0x0000 }, + { 0x8700, 0x1855, 0x2000 }, + { 0x0700, 0x1854, 0x0000 }, + { 0x0700, 0x1856, 0x0000 }, + { 0x8700, 0x1867, 0x5000 }, + { 0x8700, 0x185f, 0x4000 }, + { 0x8700, 0x185b, 0x3000 }, + { 0x8700, 0x1859, 0x2000 }, + { 0x0700, 0x1858, 0x0000 }, + { 0x0700, 0x185a, 0x0000 }, + { 0x8700, 0x185d, 0x2000 }, + { 0x0700, 0x185c, 0x0000 }, + { 0x0700, 0x185e, 0x0000 }, + { 0x8700, 0x1863, 0x3000 }, + { 0x8700, 0x1861, 0x2000 }, + { 0x0700, 0x1860, 0x0000 }, + { 0x0700, 0x1862, 0x0000 }, + { 0x8700, 0x1865, 0x2000 }, + { 0x0700, 0x1864, 0x0000 }, + { 0x0700, 0x1866, 0x0000 }, + { 0x8700, 0x186f, 0x4000 }, + { 0x8700, 0x186b, 0x3000 }, + { 0x8700, 0x1869, 0x2000 }, + { 0x0700, 0x1868, 0x0000 }, + { 0x0700, 0x186a, 0x0000 }, + { 0x8700, 0x186d, 0x2000 }, + { 0x0700, 0x186c, 0x0000 }, + { 0x0700, 0x186e, 0x0000 }, + { 0x8700, 0x1873, 0x3000 }, + { 0x8700, 0x1871, 0x2000 }, + { 0x0700, 0x1870, 0x0000 }, + { 0x0700, 0x1872, 0x0000 }, + { 0x8700, 0x1875, 0x2000 }, + { 0x0700, 0x1874, 0x0000 }, + { 0x0700, 0x1876, 0x0000 }, + { 0x8700, 0x189f, 0x6000 }, + { 0x8700, 0x188f, 0x5000 }, + { 0x8700, 0x1887, 0x4000 }, + { 0x8700, 0x1883, 0x3000 }, + { 0x8700, 0x1881, 0x2000 }, + { 0x0700, 0x1880, 0x0000 }, + { 0x0700, 0x1882, 0x0000 }, + { 0x8700, 0x1885, 0x2000 }, + { 0x0700, 0x1884, 0x0000 }, + { 0x0700, 0x1886, 0x0000 }, + { 0x8700, 0x188b, 0x3000 }, + { 0x8700, 0x1889, 0x2000 }, + { 0x0700, 0x1888, 0x0000 }, + { 0x0700, 0x188a, 0x0000 }, + { 0x8700, 0x188d, 0x2000 }, + { 0x0700, 0x188c, 0x0000 }, + { 0x0700, 0x188e, 0x0000 }, + { 0x8700, 0x1897, 0x4000 }, + { 0x8700, 0x1893, 0x3000 }, + { 0x8700, 0x1891, 0x2000 }, + { 0x0700, 0x1890, 0x0000 }, + { 0x0700, 0x1892, 0x0000 }, + { 0x8700, 0x1895, 0x2000 }, + { 0x0700, 0x1894, 0x0000 }, + { 0x0700, 0x1896, 0x0000 }, + { 0x8700, 0x189b, 0x3000 }, + { 0x8700, 0x1899, 0x2000 }, + { 0x0700, 0x1898, 0x0000 }, + { 0x0700, 0x189a, 0x0000 }, + { 0x8700, 0x189d, 0x2000 }, + { 0x0700, 0x189c, 0x0000 }, + { 0x0700, 0x189e, 0x0000 }, + { 0x8700, 0x1905, 0x5000 }, + { 0x8700, 0x18a7, 0x4000 }, + { 0x8700, 0x18a3, 0x3000 }, + { 0x8700, 0x18a1, 0x2000 }, + { 0x0700, 0x18a0, 0x0000 }, + { 0x0700, 0x18a2, 0x0000 }, + { 0x8700, 0x18a5, 0x2000 }, + { 0x0700, 0x18a4, 0x0000 }, + { 0x0700, 0x18a6, 0x0000 }, + { 0x8700, 0x1901, 0x3000 }, + { 0x8c00, 0x18a9, 0x2000 }, + { 0x0700, 0x18a8, 0x0000 }, + { 0x0700, 0x1900, 0x0000 }, + { 0x8700, 0x1903, 0x2000 }, + { 0x0700, 0x1902, 0x0000 }, + { 0x0700, 0x1904, 0x0000 }, + { 0x8700, 0x190d, 0x4000 }, + { 0x8700, 0x1909, 0x3000 }, + { 0x8700, 0x1907, 0x2000 }, + { 0x0700, 0x1906, 0x0000 }, + { 0x0700, 0x1908, 0x0000 }, + { 0x8700, 0x190b, 0x2000 }, + { 0x0700, 0x190a, 0x0000 }, + { 0x0700, 0x190c, 0x0000 }, + { 0x8700, 0x1911, 0x3000 }, + { 0x8700, 0x190f, 0x2000 }, + { 0x0700, 0x190e, 0x0000 }, + { 0x0700, 0x1910, 0x0000 }, + { 0x8700, 0x1913, 0x2000 }, + { 0x0700, 0x1912, 0x0000 }, + { 0x0700, 0x1914, 0x0000 }, + { 0x8500, 0x1d10, 0x8000 }, + { 0x8700, 0x1963, 0x7000 }, + { 0x9a00, 0x1940, 0x6000 }, + { 0x8c00, 0x1928, 0x5000 }, + { 0x8c00, 0x1920, 0x4000 }, + { 0x8700, 0x1919, 0x3000 }, + { 0x8700, 0x1917, 0x2000 }, + { 0x0700, 0x1916, 0x0000 }, + { 0x0700, 0x1918, 0x0000 }, + { 0x8700, 0x191b, 0x2000 }, + { 0x0700, 0x191a, 0x0000 }, + { 0x0700, 0x191c, 0x0000 }, + { 0x8a00, 0x1924, 0x3000 }, + { 0x8c00, 0x1922, 0x2000 }, + { 0x0c00, 0x1921, 0x0000 }, + { 0x0a00, 0x1923, 0x0000 }, + { 0x8a00, 0x1926, 0x2000 }, + { 0x0a00, 0x1925, 0x0000 }, + { 0x0c00, 0x1927, 0x0000 }, + { 0x8a00, 0x1934, 0x4000 }, + { 0x8a00, 0x1930, 0x3000 }, + { 0x8a00, 0x192a, 0x2000 }, + { 0x0a00, 0x1929, 0x0000 }, + { 0x0a00, 0x192b, 0x0000 }, + { 0x8c00, 0x1932, 0x2000 }, + { 0x0a00, 0x1931, 0x0000 }, + { 0x0a00, 0x1933, 0x0000 }, + { 0x8a00, 0x1938, 0x3000 }, + { 0x8a00, 0x1936, 0x2000 }, + { 0x0a00, 0x1935, 0x0000 }, + { 0x0a00, 0x1937, 0x0000 }, + { 0x8c00, 0x193a, 0x2000 }, + { 0x0c00, 0x1939, 0x0000 }, + { 0x0c00, 0x193b, 0x0000 }, + { 0x8700, 0x1953, 0x5000 }, + { 0x8d00, 0x194b, 0x4000 }, + { 0x8d00, 0x1947, 0x3000 }, + { 0x9500, 0x1945, 0x2000 }, + { 0x1500, 0x1944, 0x0000 }, + { 0x0d00, 0x1946, 0x0000 }, + { 0x8d00, 0x1949, 0x2000 }, + { 0x0d00, 0x1948, 0x0000 }, + { 0x0d00, 0x194a, 0x0000 }, + { 0x8d00, 0x194f, 0x3000 }, + { 0x8d00, 0x194d, 0x2000 }, + { 0x0d00, 0x194c, 0x0000 }, + { 0x0d00, 0x194e, 0x0000 }, + { 0x8700, 0x1951, 0x2000 }, + { 0x0700, 0x1950, 0x0000 }, + { 0x0700, 0x1952, 0x0000 }, + { 0x8700, 0x195b, 0x4000 }, + { 0x8700, 0x1957, 0x3000 }, + { 0x8700, 0x1955, 0x2000 }, + { 0x0700, 0x1954, 0x0000 }, + { 0x0700, 0x1956, 0x0000 }, + { 0x8700, 0x1959, 0x2000 }, + { 0x0700, 0x1958, 0x0000 }, + { 0x0700, 0x195a, 0x0000 }, + { 0x8700, 0x195f, 0x3000 }, + { 0x8700, 0x195d, 0x2000 }, + { 0x0700, 0x195c, 0x0000 }, + { 0x0700, 0x195e, 0x0000 }, + { 0x8700, 0x1961, 0x2000 }, + { 0x0700, 0x1960, 0x0000 }, + { 0x0700, 0x1962, 0x0000 }, + { 0x9a00, 0x19f0, 0x6000 }, + { 0x9a00, 0x19e0, 0x5000 }, + { 0x8700, 0x196b, 0x4000 }, + { 0x8700, 0x1967, 0x3000 }, + { 0x8700, 0x1965, 0x2000 }, + { 0x0700, 0x1964, 0x0000 }, + { 0x0700, 0x1966, 0x0000 }, + { 0x8700, 0x1969, 0x2000 }, + { 0x0700, 0x1968, 0x0000 }, + { 0x0700, 0x196a, 0x0000 }, + { 0x8700, 0x1971, 0x3000 }, + { 0x8700, 0x196d, 0x2000 }, + { 0x0700, 0x196c, 0x0000 }, + { 0x0700, 0x1970, 0x0000 }, + { 0x8700, 0x1973, 0x2000 }, + { 0x0700, 0x1972, 0x0000 }, + { 0x0700, 0x1974, 0x0000 }, + { 0x9a00, 0x19e8, 0x4000 }, + { 0x9a00, 0x19e4, 0x3000 }, + { 0x9a00, 0x19e2, 0x2000 }, + { 0x1a00, 0x19e1, 0x0000 }, + { 0x1a00, 0x19e3, 0x0000 }, + { 0x9a00, 0x19e6, 0x2000 }, + { 0x1a00, 0x19e5, 0x0000 }, + { 0x1a00, 0x19e7, 0x0000 }, + { 0x9a00, 0x19ec, 0x3000 }, + { 0x9a00, 0x19ea, 0x2000 }, + { 0x1a00, 0x19e9, 0x0000 }, + { 0x1a00, 0x19eb, 0x0000 }, + { 0x9a00, 0x19ee, 0x2000 }, + { 0x1a00, 0x19ed, 0x0000 }, + { 0x1a00, 0x19ef, 0x0000 }, + { 0x8500, 0x1d00, 0x5000 }, + { 0x9a00, 0x19f8, 0x4000 }, + { 0x9a00, 0x19f4, 0x3000 }, + { 0x9a00, 0x19f2, 0x2000 }, + { 0x1a00, 0x19f1, 0x0000 }, + { 0x1a00, 0x19f3, 0x0000 }, + { 0x9a00, 0x19f6, 0x2000 }, + { 0x1a00, 0x19f5, 0x0000 }, + { 0x1a00, 0x19f7, 0x0000 }, + { 0x9a00, 0x19fc, 0x3000 }, + { 0x9a00, 0x19fa, 0x2000 }, + { 0x1a00, 0x19f9, 0x0000 }, + { 0x1a00, 0x19fb, 0x0000 }, + { 0x9a00, 0x19fe, 0x2000 }, + { 0x1a00, 0x19fd, 0x0000 }, + { 0x1a00, 0x19ff, 0x0000 }, + { 0x8500, 0x1d08, 0x4000 }, + { 0x8500, 0x1d04, 0x3000 }, + { 0x8500, 0x1d02, 0x2000 }, + { 0x0500, 0x1d01, 0x0000 }, + { 0x0500, 0x1d03, 0x0000 }, + { 0x8500, 0x1d06, 0x2000 }, + { 0x0500, 0x1d05, 0x0000 }, + { 0x0500, 0x1d07, 0x0000 }, + { 0x8500, 0x1d0c, 0x3000 }, + { 0x8500, 0x1d0a, 0x2000 }, + { 0x0500, 0x1d09, 0x0000 }, + { 0x0500, 0x1d0b, 0x0000 }, + { 0x8500, 0x1d0e, 0x2000 }, + { 0x0500, 0x1d0d, 0x0000 }, + { 0x0500, 0x1d0f, 0x0000 }, + { 0x8600, 0x1d50, 0x7000 }, + { 0x8600, 0x1d30, 0x6000 }, + { 0x8500, 0x1d20, 0x5000 }, + { 0x8500, 0x1d18, 0x4000 }, + { 0x8500, 0x1d14, 0x3000 }, + { 0x8500, 0x1d12, 0x2000 }, + { 0x0500, 0x1d11, 0x0000 }, + { 0x0500, 0x1d13, 0x0000 }, + { 0x8500, 0x1d16, 0x2000 }, + { 0x0500, 0x1d15, 0x0000 }, + { 0x0500, 0x1d17, 0x0000 }, + { 0x8500, 0x1d1c, 0x3000 }, + { 0x8500, 0x1d1a, 0x2000 }, + { 0x0500, 0x1d19, 0x0000 }, + { 0x0500, 0x1d1b, 0x0000 }, + { 0x8500, 0x1d1e, 0x2000 }, + { 0x0500, 0x1d1d, 0x0000 }, + { 0x0500, 0x1d1f, 0x0000 }, + { 0x8500, 0x1d28, 0x4000 }, + { 0x8500, 0x1d24, 0x3000 }, + { 0x8500, 0x1d22, 0x2000 }, + { 0x0500, 0x1d21, 0x0000 }, + { 0x0500, 0x1d23, 0x0000 }, + { 0x8500, 0x1d26, 0x2000 }, + { 0x0500, 0x1d25, 0x0000 }, + { 0x0500, 0x1d27, 0x0000 }, + { 0x8600, 0x1d2c, 0x3000 }, + { 0x8500, 0x1d2a, 0x2000 }, + { 0x0500, 0x1d29, 0x0000 }, + { 0x0500, 0x1d2b, 0x0000 }, + { 0x8600, 0x1d2e, 0x2000 }, + { 0x0600, 0x1d2d, 0x0000 }, + { 0x0600, 0x1d2f, 0x0000 }, + { 0x8600, 0x1d40, 0x5000 }, + { 0x8600, 0x1d38, 0x4000 }, + { 0x8600, 0x1d34, 0x3000 }, + { 0x8600, 0x1d32, 0x2000 }, + { 0x0600, 0x1d31, 0x0000 }, + { 0x0600, 0x1d33, 0x0000 }, + { 0x8600, 0x1d36, 0x2000 }, + { 0x0600, 0x1d35, 0x0000 }, + { 0x0600, 0x1d37, 0x0000 }, + { 0x8600, 0x1d3c, 0x3000 }, + { 0x8600, 0x1d3a, 0x2000 }, + { 0x0600, 0x1d39, 0x0000 }, + { 0x0600, 0x1d3b, 0x0000 }, + { 0x8600, 0x1d3e, 0x2000 }, + { 0x0600, 0x1d3d, 0x0000 }, + { 0x0600, 0x1d3f, 0x0000 }, + { 0x8600, 0x1d48, 0x4000 }, + { 0x8600, 0x1d44, 0x3000 }, + { 0x8600, 0x1d42, 0x2000 }, + { 0x0600, 0x1d41, 0x0000 }, + { 0x0600, 0x1d43, 0x0000 }, + { 0x8600, 0x1d46, 0x2000 }, + { 0x0600, 0x1d45, 0x0000 }, + { 0x0600, 0x1d47, 0x0000 }, + { 0x8600, 0x1d4c, 0x3000 }, + { 0x8600, 0x1d4a, 0x2000 }, + { 0x0600, 0x1d49, 0x0000 }, + { 0x0600, 0x1d4b, 0x0000 }, + { 0x8600, 0x1d4e, 0x2000 }, + { 0x0600, 0x1d4d, 0x0000 }, + { 0x0600, 0x1d4f, 0x0000 }, + { 0x8900, 0x1e04, 0x6001 }, + { 0x8600, 0x1d60, 0x5000 }, + { 0x8600, 0x1d58, 0x4000 }, + { 0x8600, 0x1d54, 0x3000 }, + { 0x8600, 0x1d52, 0x2000 }, + { 0x0600, 0x1d51, 0x0000 }, + { 0x0600, 0x1d53, 0x0000 }, + { 0x8600, 0x1d56, 0x2000 }, + { 0x0600, 0x1d55, 0x0000 }, + { 0x0600, 0x1d57, 0x0000 }, + { 0x8600, 0x1d5c, 0x3000 }, + { 0x8600, 0x1d5a, 0x2000 }, + { 0x0600, 0x1d59, 0x0000 }, + { 0x0600, 0x1d5b, 0x0000 }, + { 0x8600, 0x1d5e, 0x2000 }, + { 0x0600, 0x1d5d, 0x0000 }, + { 0x0600, 0x1d5f, 0x0000 }, + { 0x8500, 0x1d68, 0x4000 }, + { 0x8500, 0x1d64, 0x3000 }, + { 0x8500, 0x1d62, 0x2000 }, + { 0x0600, 0x1d61, 0x0000 }, + { 0x0500, 0x1d63, 0x0000 }, + { 0x8500, 0x1d66, 0x2000 }, + { 0x0500, 0x1d65, 0x0000 }, + { 0x0500, 0x1d67, 0x0000 }, + { 0x8900, 0x1e00, 0x3001 }, + { 0x8500, 0x1d6a, 0x2000 }, + { 0x0500, 0x1d69, 0x0000 }, + { 0x0500, 0x1d6b, 0x0000 }, + { 0x8900, 0x1e02, 0x2001 }, + { 0x0500, 0x1e01, 0x0fff }, + { 0x0500, 0x1e03, 0x0fff }, + { 0x8900, 0x1e14, 0x5001 }, + { 0x8900, 0x1e0c, 0x4001 }, + { 0x8900, 0x1e08, 0x3001 }, + { 0x8900, 0x1e06, 0x2001 }, + { 0x0500, 0x1e05, 0x0fff }, + { 0x0500, 0x1e07, 0x0fff }, + { 0x8900, 0x1e0a, 0x2001 }, + { 0x0500, 0x1e09, 0x0fff }, + { 0x0500, 0x1e0b, 0x0fff }, + { 0x8900, 0x1e10, 0x3001 }, + { 0x8900, 0x1e0e, 0x2001 }, + { 0x0500, 0x1e0d, 0x0fff }, + { 0x0500, 0x1e0f, 0x0fff }, + { 0x8900, 0x1e12, 0x2001 }, + { 0x0500, 0x1e11, 0x0fff }, + { 0x0500, 0x1e13, 0x0fff }, + { 0x8900, 0x1e1c, 0x4001 }, + { 0x8900, 0x1e18, 0x3001 }, + { 0x8900, 0x1e16, 0x2001 }, + { 0x0500, 0x1e15, 0x0fff }, + { 0x0500, 0x1e17, 0x0fff }, + { 0x8900, 0x1e1a, 0x2001 }, + { 0x0500, 0x1e19, 0x0fff }, + { 0x0500, 0x1e1b, 0x0fff }, + { 0x8900, 0x1e20, 0x3001 }, + { 0x8900, 0x1e1e, 0x2001 }, + { 0x0500, 0x1e1d, 0x0fff }, + { 0x0500, 0x1e1f, 0x0fff }, + { 0x8900, 0x1e22, 0x2001 }, + { 0x0500, 0x1e21, 0x0fff }, + { 0x0500, 0x1e23, 0x0fff }, + { 0x9600, 0x2045, 0xa000 }, + { 0x8500, 0x1f32, 0x9008 }, + { 0x8900, 0x1ea8, 0x8001 }, + { 0x8900, 0x1e64, 0x7001 }, + { 0x8900, 0x1e44, 0x6001 }, + { 0x8900, 0x1e34, 0x5001 }, + { 0x8900, 0x1e2c, 0x4001 }, + { 0x8900, 0x1e28, 0x3001 }, + { 0x8900, 0x1e26, 0x2001 }, + { 0x0500, 0x1e25, 0x0fff }, + { 0x0500, 0x1e27, 0x0fff }, + { 0x8900, 0x1e2a, 0x2001 }, + { 0x0500, 0x1e29, 0x0fff }, + { 0x0500, 0x1e2b, 0x0fff }, + { 0x8900, 0x1e30, 0x3001 }, + { 0x8900, 0x1e2e, 0x2001 }, + { 0x0500, 0x1e2d, 0x0fff }, + { 0x0500, 0x1e2f, 0x0fff }, + { 0x8900, 0x1e32, 0x2001 }, + { 0x0500, 0x1e31, 0x0fff }, + { 0x0500, 0x1e33, 0x0fff }, + { 0x8900, 0x1e3c, 0x4001 }, + { 0x8900, 0x1e38, 0x3001 }, + { 0x8900, 0x1e36, 0x2001 }, + { 0x0500, 0x1e35, 0x0fff }, + { 0x0500, 0x1e37, 0x0fff }, + { 0x8900, 0x1e3a, 0x2001 }, + { 0x0500, 0x1e39, 0x0fff }, + { 0x0500, 0x1e3b, 0x0fff }, + { 0x8900, 0x1e40, 0x3001 }, + { 0x8900, 0x1e3e, 0x2001 }, + { 0x0500, 0x1e3d, 0x0fff }, + { 0x0500, 0x1e3f, 0x0fff }, + { 0x8900, 0x1e42, 0x2001 }, + { 0x0500, 0x1e41, 0x0fff }, + { 0x0500, 0x1e43, 0x0fff }, + { 0x8900, 0x1e54, 0x5001 }, + { 0x8900, 0x1e4c, 0x4001 }, + { 0x8900, 0x1e48, 0x3001 }, + { 0x8900, 0x1e46, 0x2001 }, + { 0x0500, 0x1e45, 0x0fff }, + { 0x0500, 0x1e47, 0x0fff }, + { 0x8900, 0x1e4a, 0x2001 }, + { 0x0500, 0x1e49, 0x0fff }, + { 0x0500, 0x1e4b, 0x0fff }, + { 0x8900, 0x1e50, 0x3001 }, + { 0x8900, 0x1e4e, 0x2001 }, + { 0x0500, 0x1e4d, 0x0fff }, + { 0x0500, 0x1e4f, 0x0fff }, + { 0x8900, 0x1e52, 0x2001 }, + { 0x0500, 0x1e51, 0x0fff }, + { 0x0500, 0x1e53, 0x0fff }, + { 0x8900, 0x1e5c, 0x4001 }, + { 0x8900, 0x1e58, 0x3001 }, + { 0x8900, 0x1e56, 0x2001 }, + { 0x0500, 0x1e55, 0x0fff }, + { 0x0500, 0x1e57, 0x0fff }, + { 0x8900, 0x1e5a, 0x2001 }, + { 0x0500, 0x1e59, 0x0fff }, + { 0x0500, 0x1e5b, 0x0fff }, + { 0x8900, 0x1e60, 0x3001 }, + { 0x8900, 0x1e5e, 0x2001 }, + { 0x0500, 0x1e5d, 0x0fff }, + { 0x0500, 0x1e5f, 0x0fff }, + { 0x8900, 0x1e62, 0x2001 }, + { 0x0500, 0x1e61, 0x0fff }, + { 0x0500, 0x1e63, 0x0fff }, + { 0x8900, 0x1e84, 0x6001 }, + { 0x8900, 0x1e74, 0x5001 }, + { 0x8900, 0x1e6c, 0x4001 }, + { 0x8900, 0x1e68, 0x3001 }, + { 0x8900, 0x1e66, 0x2001 }, + { 0x0500, 0x1e65, 0x0fff }, + { 0x0500, 0x1e67, 0x0fff }, + { 0x8900, 0x1e6a, 0x2001 }, + { 0x0500, 0x1e69, 0x0fff }, + { 0x0500, 0x1e6b, 0x0fff }, + { 0x8900, 0x1e70, 0x3001 }, + { 0x8900, 0x1e6e, 0x2001 }, + { 0x0500, 0x1e6d, 0x0fff }, + { 0x0500, 0x1e6f, 0x0fff }, + { 0x8900, 0x1e72, 0x2001 }, + { 0x0500, 0x1e71, 0x0fff }, + { 0x0500, 0x1e73, 0x0fff }, + { 0x8900, 0x1e7c, 0x4001 }, + { 0x8900, 0x1e78, 0x3001 }, + { 0x8900, 0x1e76, 0x2001 }, + { 0x0500, 0x1e75, 0x0fff }, + { 0x0500, 0x1e77, 0x0fff }, + { 0x8900, 0x1e7a, 0x2001 }, + { 0x0500, 0x1e79, 0x0fff }, + { 0x0500, 0x1e7b, 0x0fff }, + { 0x8900, 0x1e80, 0x3001 }, + { 0x8900, 0x1e7e, 0x2001 }, + { 0x0500, 0x1e7d, 0x0fff }, + { 0x0500, 0x1e7f, 0x0fff }, + { 0x8900, 0x1e82, 0x2001 }, + { 0x0500, 0x1e81, 0x0fff }, + { 0x0500, 0x1e83, 0x0fff }, + { 0x8900, 0x1e94, 0x5001 }, + { 0x8900, 0x1e8c, 0x4001 }, + { 0x8900, 0x1e88, 0x3001 }, + { 0x8900, 0x1e86, 0x2001 }, + { 0x0500, 0x1e85, 0x0fff }, + { 0x0500, 0x1e87, 0x0fff }, + { 0x8900, 0x1e8a, 0x2001 }, + { 0x0500, 0x1e89, 0x0fff }, + { 0x0500, 0x1e8b, 0x0fff }, + { 0x8900, 0x1e90, 0x3001 }, + { 0x8900, 0x1e8e, 0x2001 }, + { 0x0500, 0x1e8d, 0x0fff }, + { 0x0500, 0x1e8f, 0x0fff }, + { 0x8900, 0x1e92, 0x2001 }, + { 0x0500, 0x1e91, 0x0fff }, + { 0x0500, 0x1e93, 0x0fff }, + { 0x8900, 0x1ea0, 0x4001 }, + { 0x8500, 0x1e98, 0x3000 }, + { 0x8500, 0x1e96, 0x2000 }, + { 0x0500, 0x1e95, 0x0fff }, + { 0x0500, 0x1e97, 0x0000 }, + { 0x8500, 0x1e9a, 0x2000 }, + { 0x0500, 0x1e99, 0x0000 }, + { 0x0500, 0x1e9b, 0x0fc5 }, + { 0x8900, 0x1ea4, 0x3001 }, + { 0x8900, 0x1ea2, 0x2001 }, + { 0x0500, 0x1ea1, 0x0fff }, + { 0x0500, 0x1ea3, 0x0fff }, + { 0x8900, 0x1ea6, 0x2001 }, + { 0x0500, 0x1ea5, 0x0fff }, + { 0x0500, 0x1ea7, 0x0fff }, + { 0x8900, 0x1ee8, 0x7001 }, + { 0x8900, 0x1ec8, 0x6001 }, + { 0x8900, 0x1eb8, 0x5001 }, + { 0x8900, 0x1eb0, 0x4001 }, + { 0x8900, 0x1eac, 0x3001 }, + { 0x8900, 0x1eaa, 0x2001 }, + { 0x0500, 0x1ea9, 0x0fff }, + { 0x0500, 0x1eab, 0x0fff }, + { 0x8900, 0x1eae, 0x2001 }, + { 0x0500, 0x1ead, 0x0fff }, + { 0x0500, 0x1eaf, 0x0fff }, + { 0x8900, 0x1eb4, 0x3001 }, + { 0x8900, 0x1eb2, 0x2001 }, + { 0x0500, 0x1eb1, 0x0fff }, + { 0x0500, 0x1eb3, 0x0fff }, + { 0x8900, 0x1eb6, 0x2001 }, + { 0x0500, 0x1eb5, 0x0fff }, + { 0x0500, 0x1eb7, 0x0fff }, + { 0x8900, 0x1ec0, 0x4001 }, + { 0x8900, 0x1ebc, 0x3001 }, + { 0x8900, 0x1eba, 0x2001 }, + { 0x0500, 0x1eb9, 0x0fff }, + { 0x0500, 0x1ebb, 0x0fff }, + { 0x8900, 0x1ebe, 0x2001 }, + { 0x0500, 0x1ebd, 0x0fff }, + { 0x0500, 0x1ebf, 0x0fff }, + { 0x8900, 0x1ec4, 0x3001 }, + { 0x8900, 0x1ec2, 0x2001 }, + { 0x0500, 0x1ec1, 0x0fff }, + { 0x0500, 0x1ec3, 0x0fff }, + { 0x8900, 0x1ec6, 0x2001 }, + { 0x0500, 0x1ec5, 0x0fff }, + { 0x0500, 0x1ec7, 0x0fff }, + { 0x8900, 0x1ed8, 0x5001 }, + { 0x8900, 0x1ed0, 0x4001 }, + { 0x8900, 0x1ecc, 0x3001 }, + { 0x8900, 0x1eca, 0x2001 }, + { 0x0500, 0x1ec9, 0x0fff }, + { 0x0500, 0x1ecb, 0x0fff }, + { 0x8900, 0x1ece, 0x2001 }, + { 0x0500, 0x1ecd, 0x0fff }, + { 0x0500, 0x1ecf, 0x0fff }, + { 0x8900, 0x1ed4, 0x3001 }, + { 0x8900, 0x1ed2, 0x2001 }, + { 0x0500, 0x1ed1, 0x0fff }, + { 0x0500, 0x1ed3, 0x0fff }, + { 0x8900, 0x1ed6, 0x2001 }, + { 0x0500, 0x1ed5, 0x0fff }, + { 0x0500, 0x1ed7, 0x0fff }, + { 0x8900, 0x1ee0, 0x4001 }, + { 0x8900, 0x1edc, 0x3001 }, + { 0x8900, 0x1eda, 0x2001 }, + { 0x0500, 0x1ed9, 0x0fff }, + { 0x0500, 0x1edb, 0x0fff }, + { 0x8900, 0x1ede, 0x2001 }, + { 0x0500, 0x1edd, 0x0fff }, + { 0x0500, 0x1edf, 0x0fff }, + { 0x8900, 0x1ee4, 0x3001 }, + { 0x8900, 0x1ee2, 0x2001 }, + { 0x0500, 0x1ee1, 0x0fff }, + { 0x0500, 0x1ee3, 0x0fff }, + { 0x8900, 0x1ee6, 0x2001 }, + { 0x0500, 0x1ee5, 0x0fff }, + { 0x0500, 0x1ee7, 0x0fff }, + { 0x8900, 0x1f0e, 0x6ff8 }, + { 0x8900, 0x1ef8, 0x5001 }, + { 0x8900, 0x1ef0, 0x4001 }, + { 0x8900, 0x1eec, 0x3001 }, + { 0x8900, 0x1eea, 0x2001 }, + { 0x0500, 0x1ee9, 0x0fff }, + { 0x0500, 0x1eeb, 0x0fff }, + { 0x8900, 0x1eee, 0x2001 }, + { 0x0500, 0x1eed, 0x0fff }, + { 0x0500, 0x1eef, 0x0fff }, + { 0x8900, 0x1ef4, 0x3001 }, + { 0x8900, 0x1ef2, 0x2001 }, + { 0x0500, 0x1ef1, 0x0fff }, + { 0x0500, 0x1ef3, 0x0fff }, + { 0x8900, 0x1ef6, 0x2001 }, + { 0x0500, 0x1ef5, 0x0fff }, + { 0x0500, 0x1ef7, 0x0fff }, + { 0x8500, 0x1f06, 0x4008 }, + { 0x8500, 0x1f02, 0x3008 }, + { 0x8500, 0x1f00, 0x2008 }, + { 0x0500, 0x1ef9, 0x0fff }, + { 0x0500, 0x1f01, 0x0008 }, + { 0x8500, 0x1f04, 0x2008 }, + { 0x0500, 0x1f03, 0x0008 }, + { 0x0500, 0x1f05, 0x0008 }, + { 0x8900, 0x1f0a, 0x3ff8 }, + { 0x8900, 0x1f08, 0x2ff8 }, + { 0x0500, 0x1f07, 0x0008 }, + { 0x0900, 0x1f09, 0x0ff8 }, + { 0x8900, 0x1f0c, 0x2ff8 }, + { 0x0900, 0x1f0b, 0x0ff8 }, + { 0x0900, 0x1f0d, 0x0ff8 }, + { 0x8500, 0x1f22, 0x5008 }, + { 0x8900, 0x1f18, 0x4ff8 }, + { 0x8500, 0x1f12, 0x3008 }, + { 0x8500, 0x1f10, 0x2008 }, + { 0x0900, 0x1f0f, 0x0ff8 }, + { 0x0500, 0x1f11, 0x0008 }, + { 0x8500, 0x1f14, 0x2008 }, + { 0x0500, 0x1f13, 0x0008 }, + { 0x0500, 0x1f15, 0x0008 }, + { 0x8900, 0x1f1c, 0x3ff8 }, + { 0x8900, 0x1f1a, 0x2ff8 }, + { 0x0900, 0x1f19, 0x0ff8 }, + { 0x0900, 0x1f1b, 0x0ff8 }, + { 0x8500, 0x1f20, 0x2008 }, + { 0x0900, 0x1f1d, 0x0ff8 }, + { 0x0500, 0x1f21, 0x0008 }, + { 0x8900, 0x1f2a, 0x4ff8 }, + { 0x8500, 0x1f26, 0x3008 }, + { 0x8500, 0x1f24, 0x2008 }, + { 0x0500, 0x1f23, 0x0008 }, + { 0x0500, 0x1f25, 0x0008 }, + { 0x8900, 0x1f28, 0x2ff8 }, + { 0x0500, 0x1f27, 0x0008 }, + { 0x0900, 0x1f29, 0x0ff8 }, + { 0x8900, 0x1f2e, 0x3ff8 }, + { 0x8900, 0x1f2c, 0x2ff8 }, + { 0x0900, 0x1f2b, 0x0ff8 }, + { 0x0900, 0x1f2d, 0x0ff8 }, + { 0x8500, 0x1f30, 0x2008 }, + { 0x0900, 0x1f2f, 0x0ff8 }, + { 0x0500, 0x1f31, 0x0008 }, + { 0x9800, 0x1fbd, 0x8000 }, + { 0x8500, 0x1f7a, 0x7070 }, + { 0x8500, 0x1f56, 0x6000 }, + { 0x8500, 0x1f42, 0x5008 }, + { 0x8900, 0x1f3a, 0x4ff8 }, + { 0x8500, 0x1f36, 0x3008 }, + { 0x8500, 0x1f34, 0x2008 }, + { 0x0500, 0x1f33, 0x0008 }, + { 0x0500, 0x1f35, 0x0008 }, + { 0x8900, 0x1f38, 0x2ff8 }, + { 0x0500, 0x1f37, 0x0008 }, + { 0x0900, 0x1f39, 0x0ff8 }, + { 0x8900, 0x1f3e, 0x3ff8 }, + { 0x8900, 0x1f3c, 0x2ff8 }, + { 0x0900, 0x1f3b, 0x0ff8 }, + { 0x0900, 0x1f3d, 0x0ff8 }, + { 0x8500, 0x1f40, 0x2008 }, + { 0x0900, 0x1f3f, 0x0ff8 }, + { 0x0500, 0x1f41, 0x0008 }, + { 0x8900, 0x1f4c, 0x4ff8 }, + { 0x8900, 0x1f48, 0x3ff8 }, + { 0x8500, 0x1f44, 0x2008 }, + { 0x0500, 0x1f43, 0x0008 }, + { 0x0500, 0x1f45, 0x0008 }, + { 0x8900, 0x1f4a, 0x2ff8 }, + { 0x0900, 0x1f49, 0x0ff8 }, + { 0x0900, 0x1f4b, 0x0ff8 }, + { 0x8500, 0x1f52, 0x3000 }, + { 0x8500, 0x1f50, 0x2000 }, + { 0x0900, 0x1f4d, 0x0ff8 }, + { 0x0500, 0x1f51, 0x0008 }, + { 0x8500, 0x1f54, 0x2000 }, + { 0x0500, 0x1f53, 0x0008 }, + { 0x0500, 0x1f55, 0x0008 }, + { 0x8900, 0x1f6a, 0x5ff8 }, + { 0x8500, 0x1f62, 0x4008 }, + { 0x8900, 0x1f5d, 0x3ff8 }, + { 0x8900, 0x1f59, 0x2ff8 }, + { 0x0500, 0x1f57, 0x0008 }, + { 0x0900, 0x1f5b, 0x0ff8 }, + { 0x8500, 0x1f60, 0x2008 }, + { 0x0900, 0x1f5f, 0x0ff8 }, + { 0x0500, 0x1f61, 0x0008 }, + { 0x8500, 0x1f66, 0x3008 }, + { 0x8500, 0x1f64, 0x2008 }, + { 0x0500, 0x1f63, 0x0008 }, + { 0x0500, 0x1f65, 0x0008 }, + { 0x8900, 0x1f68, 0x2ff8 }, + { 0x0500, 0x1f67, 0x0008 }, + { 0x0900, 0x1f69, 0x0ff8 }, + { 0x8500, 0x1f72, 0x4056 }, + { 0x8900, 0x1f6e, 0x3ff8 }, + { 0x8900, 0x1f6c, 0x2ff8 }, + { 0x0900, 0x1f6b, 0x0ff8 }, + { 0x0900, 0x1f6d, 0x0ff8 }, + { 0x8500, 0x1f70, 0x204a }, + { 0x0900, 0x1f6f, 0x0ff8 }, + { 0x0500, 0x1f71, 0x004a }, + { 0x8500, 0x1f76, 0x3064 }, + { 0x8500, 0x1f74, 0x2056 }, + { 0x0500, 0x1f73, 0x0056 }, + { 0x0500, 0x1f75, 0x0056 }, + { 0x8500, 0x1f78, 0x2080 }, + { 0x0500, 0x1f77, 0x0064 }, + { 0x0500, 0x1f79, 0x0080 }, + { 0x8800, 0x1f9c, 0x6000 }, + { 0x8800, 0x1f8c, 0x5000 }, + { 0x8500, 0x1f84, 0x4008 }, + { 0x8500, 0x1f80, 0x3008 }, + { 0x8500, 0x1f7c, 0x207e }, + { 0x0500, 0x1f7b, 0x0070 }, + { 0x0500, 0x1f7d, 0x007e }, + { 0x8500, 0x1f82, 0x2008 }, + { 0x0500, 0x1f81, 0x0008 }, + { 0x0500, 0x1f83, 0x0008 }, + { 0x8800, 0x1f88, 0x3000 }, + { 0x8500, 0x1f86, 0x2008 }, + { 0x0500, 0x1f85, 0x0008 }, + { 0x0500, 0x1f87, 0x0008 }, + { 0x8800, 0x1f8a, 0x2000 }, + { 0x0800, 0x1f89, 0x0000 }, + { 0x0800, 0x1f8b, 0x0000 }, + { 0x8500, 0x1f94, 0x4008 }, + { 0x8500, 0x1f90, 0x3008 }, + { 0x8800, 0x1f8e, 0x2000 }, + { 0x0800, 0x1f8d, 0x0000 }, + { 0x0800, 0x1f8f, 0x0000 }, + { 0x8500, 0x1f92, 0x2008 }, + { 0x0500, 0x1f91, 0x0008 }, + { 0x0500, 0x1f93, 0x0008 }, + { 0x8800, 0x1f98, 0x3000 }, + { 0x8500, 0x1f96, 0x2008 }, + { 0x0500, 0x1f95, 0x0008 }, + { 0x0500, 0x1f97, 0x0008 }, + { 0x8800, 0x1f9a, 0x2000 }, + { 0x0800, 0x1f99, 0x0000 }, + { 0x0800, 0x1f9b, 0x0000 }, + { 0x8800, 0x1fac, 0x5000 }, + { 0x8500, 0x1fa4, 0x4008 }, + { 0x8500, 0x1fa0, 0x3008 }, + { 0x8800, 0x1f9e, 0x2000 }, + { 0x0800, 0x1f9d, 0x0000 }, + { 0x0800, 0x1f9f, 0x0000 }, + { 0x8500, 0x1fa2, 0x2008 }, + { 0x0500, 0x1fa1, 0x0008 }, + { 0x0500, 0x1fa3, 0x0008 }, + { 0x8800, 0x1fa8, 0x3000 }, + { 0x8500, 0x1fa6, 0x2008 }, + { 0x0500, 0x1fa5, 0x0008 }, + { 0x0500, 0x1fa7, 0x0008 }, + { 0x8800, 0x1faa, 0x2000 }, + { 0x0800, 0x1fa9, 0x0000 }, + { 0x0800, 0x1fab, 0x0000 }, + { 0x8500, 0x1fb4, 0x4000 }, + { 0x8500, 0x1fb0, 0x3008 }, + { 0x8800, 0x1fae, 0x2000 }, + { 0x0800, 0x1fad, 0x0000 }, + { 0x0800, 0x1faf, 0x0000 }, + { 0x8500, 0x1fb2, 0x2000 }, + { 0x0500, 0x1fb1, 0x0008 }, + { 0x0500, 0x1fb3, 0x0009 }, + { 0x8900, 0x1fb9, 0x3ff8 }, + { 0x8500, 0x1fb7, 0x2000 }, + { 0x0500, 0x1fb6, 0x0000 }, + { 0x0900, 0x1fb8, 0x0ff8 }, + { 0x8900, 0x1fbb, 0x2fb6 }, + { 0x0900, 0x1fba, 0x0fb6 }, + { 0x0800, 0x1fbc, 0x0000 }, + { 0x9d00, 0x2005, 0x7000 }, + { 0x8500, 0x1fe1, 0x6008 }, + { 0x9800, 0x1fce, 0x5000 }, + { 0x8500, 0x1fc6, 0x4000 }, + { 0x9800, 0x1fc1, 0x3000 }, + { 0x9800, 0x1fbf, 0x2000 }, + { 0x0500, 0x1fbe, 0x0000 }, + { 0x1800, 0x1fc0, 0x0000 }, + { 0x8500, 0x1fc3, 0x2009 }, + { 0x0500, 0x1fc2, 0x0000 }, + { 0x0500, 0x1fc4, 0x0000 }, + { 0x8900, 0x1fca, 0x3faa }, + { 0x8900, 0x1fc8, 0x2faa }, + { 0x0500, 0x1fc7, 0x0000 }, + { 0x0900, 0x1fc9, 0x0faa }, + { 0x8800, 0x1fcc, 0x2000 }, + { 0x0900, 0x1fcb, 0x0faa }, + { 0x1800, 0x1fcd, 0x0000 }, + { 0x8900, 0x1fd8, 0x4ff8 }, + { 0x8500, 0x1fd2, 0x3000 }, + { 0x8500, 0x1fd0, 0x2008 }, + { 0x1800, 0x1fcf, 0x0000 }, + { 0x0500, 0x1fd1, 0x0008 }, + { 0x8500, 0x1fd6, 0x2000 }, + { 0x0500, 0x1fd3, 0x0000 }, + { 0x0500, 0x1fd7, 0x0000 }, + { 0x9800, 0x1fdd, 0x3000 }, + { 0x8900, 0x1fda, 0x2f9c }, + { 0x0900, 0x1fd9, 0x0ff8 }, + { 0x0900, 0x1fdb, 0x0f9c }, + { 0x9800, 0x1fdf, 0x2000 }, + { 0x1800, 0x1fde, 0x0000 }, + { 0x0500, 0x1fe0, 0x0008 }, + { 0x8500, 0x1ff3, 0x5009 }, + { 0x8900, 0x1fe9, 0x4ff8 }, + { 0x8500, 0x1fe5, 0x3007 }, + { 0x8500, 0x1fe3, 0x2000 }, + { 0x0500, 0x1fe2, 0x0000 }, + { 0x0500, 0x1fe4, 0x0000 }, + { 0x8500, 0x1fe7, 0x2000 }, + { 0x0500, 0x1fe6, 0x0000 }, + { 0x0900, 0x1fe8, 0x0ff8 }, + { 0x9800, 0x1fed, 0x3000 }, + { 0x8900, 0x1feb, 0x2f90 }, + { 0x0900, 0x1fea, 0x0f90 }, + { 0x0900, 0x1fec, 0x0ff9 }, + { 0x9800, 0x1fef, 0x2000 }, + { 0x1800, 0x1fee, 0x0000 }, + { 0x0500, 0x1ff2, 0x0000 }, + { 0x8800, 0x1ffc, 0x4000 }, + { 0x8900, 0x1ff8, 0x3f80 }, + { 0x8500, 0x1ff6, 0x2000 }, + { 0x0500, 0x1ff4, 0x0000 }, + { 0x0500, 0x1ff7, 0x0000 }, + { 0x8900, 0x1ffa, 0x2f82 }, + { 0x0900, 0x1ff9, 0x0f80 }, + { 0x0900, 0x1ffb, 0x0f82 }, + { 0x9d00, 0x2001, 0x3000 }, + { 0x9800, 0x1ffe, 0x2000 }, + { 0x1800, 0x1ffd, 0x0000 }, + { 0x1d00, 0x2000, 0x0000 }, + { 0x9d00, 0x2003, 0x2000 }, + { 0x1d00, 0x2002, 0x0000 }, + { 0x1d00, 0x2004, 0x0000 }, + { 0x9500, 0x2025, 0x6000 }, + { 0x9100, 0x2015, 0x5000 }, + { 0x8100, 0x200d, 0x4000 }, + { 0x9d00, 0x2009, 0x3000 }, + { 0x9d00, 0x2007, 0x2000 }, + { 0x1d00, 0x2006, 0x0000 }, + { 0x1d00, 0x2008, 0x0000 }, + { 0x9d00, 0x200b, 0x2000 }, + { 0x1d00, 0x200a, 0x0000 }, + { 0x0100, 0x200c, 0x0000 }, + { 0x9100, 0x2011, 0x3000 }, + { 0x8100, 0x200f, 0x2000 }, + { 0x0100, 0x200e, 0x0000 }, + { 0x1100, 0x2010, 0x0000 }, + { 0x9100, 0x2013, 0x2000 }, + { 0x1100, 0x2012, 0x0000 }, + { 0x1100, 0x2014, 0x0000 }, + { 0x9300, 0x201d, 0x4000 }, + { 0x9300, 0x2019, 0x3000 }, + { 0x9500, 0x2017, 0x2000 }, + { 0x1500, 0x2016, 0x0000 }, + { 0x1400, 0x2018, 0x0000 }, + { 0x9400, 0x201b, 0x2000 }, + { 0x1600, 0x201a, 0x0000 }, + { 0x1400, 0x201c, 0x0000 }, + { 0x9500, 0x2021, 0x3000 }, + { 0x9400, 0x201f, 0x2000 }, + { 0x1600, 0x201e, 0x0000 }, + { 0x1500, 0x2020, 0x0000 }, + { 0x9500, 0x2023, 0x2000 }, + { 0x1500, 0x2022, 0x0000 }, + { 0x1500, 0x2024, 0x0000 }, + { 0x9500, 0x2035, 0x5000 }, + { 0x8100, 0x202d, 0x4000 }, + { 0x9c00, 0x2029, 0x3000 }, + { 0x9500, 0x2027, 0x2000 }, + { 0x1500, 0x2026, 0x0000 }, + { 0x1b00, 0x2028, 0x0000 }, + { 0x8100, 0x202b, 0x2000 }, + { 0x0100, 0x202a, 0x0000 }, + { 0x0100, 0x202c, 0x0000 }, + { 0x9500, 0x2031, 0x3000 }, + { 0x9d00, 0x202f, 0x2000 }, + { 0x0100, 0x202e, 0x0000 }, + { 0x1500, 0x2030, 0x0000 }, + { 0x9500, 0x2033, 0x2000 }, + { 0x1500, 0x2032, 0x0000 }, + { 0x1500, 0x2034, 0x0000 }, + { 0x9500, 0x203d, 0x4000 }, + { 0x9400, 0x2039, 0x3000 }, + { 0x9500, 0x2037, 0x2000 }, + { 0x1500, 0x2036, 0x0000 }, + { 0x1500, 0x2038, 0x0000 }, + { 0x9500, 0x203b, 0x2000 }, + { 0x1300, 0x203a, 0x0000 }, + { 0x1500, 0x203c, 0x0000 }, + { 0x9500, 0x2041, 0x3000 }, + { 0x9000, 0x203f, 0x2000 }, + { 0x1500, 0x203e, 0x0000 }, + { 0x1000, 0x2040, 0x0000 }, + { 0x9500, 0x2043, 0x2000 }, + { 0x1500, 0x2042, 0x0000 }, + { 0x1900, 0x2044, 0x0000 }, + { 0x9900, 0x21ae, 0x9000 }, + { 0x8900, 0x211a, 0x8000 }, + { 0x9700, 0x20a7, 0x7000 }, + { 0x8f00, 0x2076, 0x6000 }, + { 0x9500, 0x2057, 0x5000 }, + { 0x9500, 0x204d, 0x4000 }, + { 0x9500, 0x2049, 0x3000 }, + { 0x9500, 0x2047, 0x2000 }, + { 0x1200, 0x2046, 0x0000 }, + { 0x1500, 0x2048, 0x0000 }, + { 0x9500, 0x204b, 0x2000 }, + { 0x1500, 0x204a, 0x0000 }, + { 0x1500, 0x204c, 0x0000 }, + { 0x9500, 0x2051, 0x3000 }, + { 0x9500, 0x204f, 0x2000 }, + { 0x1500, 0x204e, 0x0000 }, + { 0x1500, 0x2050, 0x0000 }, + { 0x9500, 0x2053, 0x2000 }, + { 0x1900, 0x2052, 0x0000 }, + { 0x1000, 0x2054, 0x0000 }, + { 0x8100, 0x206c, 0x4000 }, + { 0x8100, 0x2062, 0x3000 }, + { 0x8100, 0x2060, 0x2000 }, + { 0x1d00, 0x205f, 0x0000 }, + { 0x0100, 0x2061, 0x0000 }, + { 0x8100, 0x206a, 0x2000 }, + { 0x0100, 0x2063, 0x0000 }, + { 0x0100, 0x206b, 0x0000 }, + { 0x8f00, 0x2070, 0x3000 }, + { 0x8100, 0x206e, 0x2000 }, + { 0x0100, 0x206d, 0x0000 }, + { 0x0100, 0x206f, 0x0000 }, + { 0x8f00, 0x2074, 0x2000 }, + { 0x0500, 0x2071, 0x0000 }, + { 0x0f00, 0x2075, 0x0000 }, + { 0x8f00, 0x2086, 0x5000 }, + { 0x9200, 0x207e, 0x4000 }, + { 0x9900, 0x207a, 0x3000 }, + { 0x8f00, 0x2078, 0x2000 }, + { 0x0f00, 0x2077, 0x0000 }, + { 0x0f00, 0x2079, 0x0000 }, + { 0x9900, 0x207c, 0x2000 }, + { 0x1900, 0x207b, 0x0000 }, + { 0x1600, 0x207d, 0x0000 }, + { 0x8f00, 0x2082, 0x3000 }, + { 0x8f00, 0x2080, 0x2000 }, + { 0x0500, 0x207f, 0x0000 }, + { 0x0f00, 0x2081, 0x0000 }, + { 0x8f00, 0x2084, 0x2000 }, + { 0x0f00, 0x2083, 0x0000 }, + { 0x0f00, 0x2085, 0x0000 }, + { 0x9200, 0x208e, 0x4000 }, + { 0x9900, 0x208a, 0x3000 }, + { 0x8f00, 0x2088, 0x2000 }, + { 0x0f00, 0x2087, 0x0000 }, + { 0x0f00, 0x2089, 0x0000 }, + { 0x9900, 0x208c, 0x2000 }, + { 0x1900, 0x208b, 0x0000 }, + { 0x1600, 0x208d, 0x0000 }, + { 0x9700, 0x20a3, 0x3000 }, + { 0x9700, 0x20a1, 0x2000 }, + { 0x1700, 0x20a0, 0x0000 }, + { 0x1700, 0x20a2, 0x0000 }, + { 0x9700, 0x20a5, 0x2000 }, + { 0x1700, 0x20a4, 0x0000 }, + { 0x1700, 0x20a6, 0x0000 }, + { 0x8c00, 0x20e5, 0x6000 }, + { 0x8c00, 0x20d5, 0x5000 }, + { 0x9700, 0x20af, 0x4000 }, + { 0x9700, 0x20ab, 0x3000 }, + { 0x9700, 0x20a9, 0x2000 }, + { 0x1700, 0x20a8, 0x0000 }, + { 0x1700, 0x20aa, 0x0000 }, + { 0x9700, 0x20ad, 0x2000 }, + { 0x1700, 0x20ac, 0x0000 }, + { 0x1700, 0x20ae, 0x0000 }, + { 0x8c00, 0x20d1, 0x3000 }, + { 0x9700, 0x20b1, 0x2000 }, + { 0x1700, 0x20b0, 0x0000 }, + { 0x0c00, 0x20d0, 0x0000 }, + { 0x8c00, 0x20d3, 0x2000 }, + { 0x0c00, 0x20d2, 0x0000 }, + { 0x0c00, 0x20d4, 0x0000 }, + { 0x8b00, 0x20dd, 0x4000 }, + { 0x8c00, 0x20d9, 0x3000 }, + { 0x8c00, 0x20d7, 0x2000 }, + { 0x0c00, 0x20d6, 0x0000 }, + { 0x0c00, 0x20d8, 0x0000 }, + { 0x8c00, 0x20db, 0x2000 }, + { 0x0c00, 0x20da, 0x0000 }, + { 0x0c00, 0x20dc, 0x0000 }, + { 0x8c00, 0x20e1, 0x3000 }, + { 0x8b00, 0x20df, 0x2000 }, + { 0x0b00, 0x20de, 0x0000 }, + { 0x0b00, 0x20e0, 0x0000 }, + { 0x8b00, 0x20e3, 0x2000 }, + { 0x0b00, 0x20e2, 0x0000 }, + { 0x0b00, 0x20e4, 0x0000 }, + { 0x8500, 0x210a, 0x5000 }, + { 0x8900, 0x2102, 0x4000 }, + { 0x8c00, 0x20e9, 0x3000 }, + { 0x8c00, 0x20e7, 0x2000 }, + { 0x0c00, 0x20e6, 0x0000 }, + { 0x0c00, 0x20e8, 0x0000 }, + { 0x9a00, 0x2100, 0x2000 }, + { 0x0c00, 0x20ea, 0x0000 }, + { 0x1a00, 0x2101, 0x0000 }, + { 0x9a00, 0x2106, 0x3000 }, + { 0x9a00, 0x2104, 0x2000 }, + { 0x1a00, 0x2103, 0x0000 }, + { 0x1a00, 0x2105, 0x0000 }, + { 0x9a00, 0x2108, 0x2000 }, + { 0x0900, 0x2107, 0x0000 }, + { 0x1a00, 0x2109, 0x0000 }, + { 0x8900, 0x2112, 0x4000 }, + { 0x8500, 0x210e, 0x3000 }, + { 0x8900, 0x210c, 0x2000 }, + { 0x0900, 0x210b, 0x0000 }, + { 0x0900, 0x210d, 0x0000 }, + { 0x8900, 0x2110, 0x2000 }, + { 0x0500, 0x210f, 0x0000 }, + { 0x0900, 0x2111, 0x0000 }, + { 0x9a00, 0x2116, 0x3000 }, + { 0x9a00, 0x2114, 0x2000 }, + { 0x0500, 0x2113, 0x0000 }, + { 0x0900, 0x2115, 0x0000 }, + { 0x9a00, 0x2118, 0x2000 }, + { 0x1a00, 0x2117, 0x0000 }, + { 0x0900, 0x2119, 0x0000 }, + { 0x8e00, 0x2162, 0x7000 }, + { 0x9a00, 0x213a, 0x6000 }, + { 0x8900, 0x212a, 0x5000 }, + { 0x9a00, 0x2122, 0x4000 }, + { 0x9a00, 0x211e, 0x3000 }, + { 0x8900, 0x211c, 0x2000 }, + { 0x0900, 0x211b, 0x0000 }, + { 0x0900, 0x211d, 0x0000 }, + { 0x9a00, 0x2120, 0x2000 }, + { 0x1a00, 0x211f, 0x0000 }, + { 0x1a00, 0x2121, 0x0000 }, + { 0x8900, 0x2126, 0x3000 }, + { 0x8900, 0x2124, 0x2000 }, + { 0x1a00, 0x2123, 0x0000 }, + { 0x1a00, 0x2125, 0x0000 }, + { 0x8900, 0x2128, 0x2000 }, + { 0x1a00, 0x2127, 0x0000 }, + { 0x1a00, 0x2129, 0x0000 }, + { 0x9a00, 0x2132, 0x4000 }, + { 0x9a00, 0x212e, 0x3000 }, + { 0x8900, 0x212c, 0x2000 }, + { 0x0900, 0x212b, 0x0000 }, + { 0x0900, 0x212d, 0x0000 }, + { 0x8900, 0x2130, 0x2000 }, + { 0x0500, 0x212f, 0x0000 }, + { 0x0900, 0x2131, 0x0000 }, + { 0x8700, 0x2136, 0x3000 }, + { 0x8500, 0x2134, 0x2000 }, + { 0x0900, 0x2133, 0x0000 }, + { 0x0700, 0x2135, 0x0000 }, + { 0x8700, 0x2138, 0x2000 }, + { 0x0700, 0x2137, 0x0000 }, + { 0x0500, 0x2139, 0x0000 }, + { 0x9900, 0x214b, 0x5000 }, + { 0x9900, 0x2143, 0x4000 }, + { 0x8900, 0x213f, 0x3000 }, + { 0x8500, 0x213d, 0x2000 }, + { 0x1a00, 0x213b, 0x0000 }, + { 0x0900, 0x213e, 0x0000 }, + { 0x9900, 0x2141, 0x2000 }, + { 0x1900, 0x2140, 0x0000 }, + { 0x1900, 0x2142, 0x0000 }, + { 0x8500, 0x2147, 0x3000 }, + { 0x8900, 0x2145, 0x2000 }, + { 0x1900, 0x2144, 0x0000 }, + { 0x0500, 0x2146, 0x0000 }, + { 0x8500, 0x2149, 0x2000 }, + { 0x0500, 0x2148, 0x0000 }, + { 0x1a00, 0x214a, 0x0000 }, + { 0x8f00, 0x215a, 0x4000 }, + { 0x8f00, 0x2156, 0x3000 }, + { 0x8f00, 0x2154, 0x2000 }, + { 0x0f00, 0x2153, 0x0000 }, + { 0x0f00, 0x2155, 0x0000 }, + { 0x8f00, 0x2158, 0x2000 }, + { 0x0f00, 0x2157, 0x0000 }, + { 0x0f00, 0x2159, 0x0000 }, + { 0x8f00, 0x215e, 0x3000 }, + { 0x8f00, 0x215c, 0x2000 }, + { 0x0f00, 0x215b, 0x0000 }, + { 0x0f00, 0x215d, 0x0000 }, + { 0x8e00, 0x2160, 0x2000 }, + { 0x0f00, 0x215f, 0x0000 }, + { 0x0e00, 0x2161, 0x0000 }, + { 0x8e00, 0x2182, 0x6000 }, + { 0x8e00, 0x2172, 0x5000 }, + { 0x8e00, 0x216a, 0x4000 }, + { 0x8e00, 0x2166, 0x3000 }, + { 0x8e00, 0x2164, 0x2000 }, + { 0x0e00, 0x2163, 0x0000 }, + { 0x0e00, 0x2165, 0x0000 }, + { 0x8e00, 0x2168, 0x2000 }, + { 0x0e00, 0x2167, 0x0000 }, + { 0x0e00, 0x2169, 0x0000 }, + { 0x8e00, 0x216e, 0x3000 }, + { 0x8e00, 0x216c, 0x2000 }, + { 0x0e00, 0x216b, 0x0000 }, + { 0x0e00, 0x216d, 0x0000 }, + { 0x8e00, 0x2170, 0x2000 }, + { 0x0e00, 0x216f, 0x0000 }, + { 0x0e00, 0x2171, 0x0000 }, + { 0x8e00, 0x217a, 0x4000 }, + { 0x8e00, 0x2176, 0x3000 }, + { 0x8e00, 0x2174, 0x2000 }, + { 0x0e00, 0x2173, 0x0000 }, + { 0x0e00, 0x2175, 0x0000 }, + { 0x8e00, 0x2178, 0x2000 }, + { 0x0e00, 0x2177, 0x0000 }, + { 0x0e00, 0x2179, 0x0000 }, + { 0x8e00, 0x217e, 0x3000 }, + { 0x8e00, 0x217c, 0x2000 }, + { 0x0e00, 0x217b, 0x0000 }, + { 0x0e00, 0x217d, 0x0000 }, + { 0x8e00, 0x2180, 0x2000 }, + { 0x0e00, 0x217f, 0x0000 }, + { 0x0e00, 0x2181, 0x0000 }, + { 0x9a00, 0x219e, 0x5000 }, + { 0x9a00, 0x2196, 0x4000 }, + { 0x9900, 0x2192, 0x3000 }, + { 0x9900, 0x2190, 0x2000 }, + { 0x0e00, 0x2183, 0x0000 }, + { 0x1900, 0x2191, 0x0000 }, + { 0x9900, 0x2194, 0x2000 }, + { 0x1900, 0x2193, 0x0000 }, + { 0x1a00, 0x2195, 0x0000 }, + { 0x9900, 0x219a, 0x3000 }, + { 0x9a00, 0x2198, 0x2000 }, + { 0x1a00, 0x2197, 0x0000 }, + { 0x1a00, 0x2199, 0x0000 }, + { 0x9a00, 0x219c, 0x2000 }, + { 0x1900, 0x219b, 0x0000 }, + { 0x1a00, 0x219d, 0x0000 }, + { 0x9900, 0x21a6, 0x4000 }, + { 0x9a00, 0x21a2, 0x3000 }, + { 0x9900, 0x21a0, 0x2000 }, + { 0x1a00, 0x219f, 0x0000 }, + { 0x1a00, 0x21a1, 0x0000 }, + { 0x9a00, 0x21a4, 0x2000 }, + { 0x1900, 0x21a3, 0x0000 }, + { 0x1a00, 0x21a5, 0x0000 }, + { 0x9a00, 0x21aa, 0x3000 }, + { 0x9a00, 0x21a8, 0x2000 }, + { 0x1a00, 0x21a7, 0x0000 }, + { 0x1a00, 0x21a9, 0x0000 }, + { 0x9a00, 0x21ac, 0x2000 }, + { 0x1a00, 0x21ab, 0x0000 }, + { 0x1a00, 0x21ad, 0x0000 }, + { 0x9900, 0x222e, 0x8000 }, + { 0x9a00, 0x21ee, 0x7000 }, + { 0x9900, 0x21ce, 0x6000 }, + { 0x9a00, 0x21be, 0x5000 }, + { 0x9a00, 0x21b6, 0x4000 }, + { 0x9a00, 0x21b2, 0x3000 }, + { 0x9a00, 0x21b0, 0x2000 }, + { 0x1a00, 0x21af, 0x0000 }, + { 0x1a00, 0x21b1, 0x0000 }, + { 0x9a00, 0x21b4, 0x2000 }, + { 0x1a00, 0x21b3, 0x0000 }, + { 0x1a00, 0x21b5, 0x0000 }, + { 0x9a00, 0x21ba, 0x3000 }, + { 0x9a00, 0x21b8, 0x2000 }, + { 0x1a00, 0x21b7, 0x0000 }, + { 0x1a00, 0x21b9, 0x0000 }, + { 0x9a00, 0x21bc, 0x2000 }, + { 0x1a00, 0x21bb, 0x0000 }, + { 0x1a00, 0x21bd, 0x0000 }, + { 0x9a00, 0x21c6, 0x4000 }, + { 0x9a00, 0x21c2, 0x3000 }, + { 0x9a00, 0x21c0, 0x2000 }, + { 0x1a00, 0x21bf, 0x0000 }, + { 0x1a00, 0x21c1, 0x0000 }, + { 0x9a00, 0x21c4, 0x2000 }, + { 0x1a00, 0x21c3, 0x0000 }, + { 0x1a00, 0x21c5, 0x0000 }, + { 0x9a00, 0x21ca, 0x3000 }, + { 0x9a00, 0x21c8, 0x2000 }, + { 0x1a00, 0x21c7, 0x0000 }, + { 0x1a00, 0x21c9, 0x0000 }, + { 0x9a00, 0x21cc, 0x2000 }, + { 0x1a00, 0x21cb, 0x0000 }, + { 0x1a00, 0x21cd, 0x0000 }, + { 0x9a00, 0x21de, 0x5000 }, + { 0x9a00, 0x21d6, 0x4000 }, + { 0x9900, 0x21d2, 0x3000 }, + { 0x9a00, 0x21d0, 0x2000 }, + { 0x1900, 0x21cf, 0x0000 }, + { 0x1a00, 0x21d1, 0x0000 }, + { 0x9900, 0x21d4, 0x2000 }, + { 0x1a00, 0x21d3, 0x0000 }, + { 0x1a00, 0x21d5, 0x0000 }, + { 0x9a00, 0x21da, 0x3000 }, + { 0x9a00, 0x21d8, 0x2000 }, + { 0x1a00, 0x21d7, 0x0000 }, + { 0x1a00, 0x21d9, 0x0000 }, + { 0x9a00, 0x21dc, 0x2000 }, + { 0x1a00, 0x21db, 0x0000 }, + { 0x1a00, 0x21dd, 0x0000 }, + { 0x9a00, 0x21e6, 0x4000 }, + { 0x9a00, 0x21e2, 0x3000 }, + { 0x9a00, 0x21e0, 0x2000 }, + { 0x1a00, 0x21df, 0x0000 }, + { 0x1a00, 0x21e1, 0x0000 }, + { 0x9a00, 0x21e4, 0x2000 }, + { 0x1a00, 0x21e3, 0x0000 }, + { 0x1a00, 0x21e5, 0x0000 }, + { 0x9a00, 0x21ea, 0x3000 }, + { 0x9a00, 0x21e8, 0x2000 }, + { 0x1a00, 0x21e7, 0x0000 }, + { 0x1a00, 0x21e9, 0x0000 }, + { 0x9a00, 0x21ec, 0x2000 }, + { 0x1a00, 0x21eb, 0x0000 }, + { 0x1a00, 0x21ed, 0x0000 }, + { 0x9900, 0x220e, 0x6000 }, + { 0x9900, 0x21fe, 0x5000 }, + { 0x9900, 0x21f6, 0x4000 }, + { 0x9a00, 0x21f2, 0x3000 }, + { 0x9a00, 0x21f0, 0x2000 }, + { 0x1a00, 0x21ef, 0x0000 }, + { 0x1a00, 0x21f1, 0x0000 }, + { 0x9900, 0x21f4, 0x2000 }, + { 0x1a00, 0x21f3, 0x0000 }, + { 0x1900, 0x21f5, 0x0000 }, + { 0x9900, 0x21fa, 0x3000 }, + { 0x9900, 0x21f8, 0x2000 }, + { 0x1900, 0x21f7, 0x0000 }, + { 0x1900, 0x21f9, 0x0000 }, + { 0x9900, 0x21fc, 0x2000 }, + { 0x1900, 0x21fb, 0x0000 }, + { 0x1900, 0x21fd, 0x0000 }, + { 0x9900, 0x2206, 0x4000 }, + { 0x9900, 0x2202, 0x3000 }, + { 0x9900, 0x2200, 0x2000 }, + { 0x1900, 0x21ff, 0x0000 }, + { 0x1900, 0x2201, 0x0000 }, + { 0x9900, 0x2204, 0x2000 }, + { 0x1900, 0x2203, 0x0000 }, + { 0x1900, 0x2205, 0x0000 }, + { 0x9900, 0x220a, 0x3000 }, + { 0x9900, 0x2208, 0x2000 }, + { 0x1900, 0x2207, 0x0000 }, + { 0x1900, 0x2209, 0x0000 }, + { 0x9900, 0x220c, 0x2000 }, + { 0x1900, 0x220b, 0x0000 }, + { 0x1900, 0x220d, 0x0000 }, + { 0x9900, 0x221e, 0x5000 }, + { 0x9900, 0x2216, 0x4000 }, + { 0x9900, 0x2212, 0x3000 }, + { 0x9900, 0x2210, 0x2000 }, + { 0x1900, 0x220f, 0x0000 }, + { 0x1900, 0x2211, 0x0000 }, + { 0x9900, 0x2214, 0x2000 }, + { 0x1900, 0x2213, 0x0000 }, + { 0x1900, 0x2215, 0x0000 }, + { 0x9900, 0x221a, 0x3000 }, + { 0x9900, 0x2218, 0x2000 }, + { 0x1900, 0x2217, 0x0000 }, + { 0x1900, 0x2219, 0x0000 }, + { 0x9900, 0x221c, 0x2000 }, + { 0x1900, 0x221b, 0x0000 }, + { 0x1900, 0x221d, 0x0000 }, + { 0x9900, 0x2226, 0x4000 }, + { 0x9900, 0x2222, 0x3000 }, + { 0x9900, 0x2220, 0x2000 }, + { 0x1900, 0x221f, 0x0000 }, + { 0x1900, 0x2221, 0x0000 }, + { 0x9900, 0x2224, 0x2000 }, + { 0x1900, 0x2223, 0x0000 }, + { 0x1900, 0x2225, 0x0000 }, + { 0x9900, 0x222a, 0x3000 }, + { 0x9900, 0x2228, 0x2000 }, + { 0x1900, 0x2227, 0x0000 }, + { 0x1900, 0x2229, 0x0000 }, + { 0x9900, 0x222c, 0x2000 }, + { 0x1900, 0x222b, 0x0000 }, + { 0x1900, 0x222d, 0x0000 }, + { 0x9900, 0x226e, 0x7000 }, + { 0x9900, 0x224e, 0x6000 }, + { 0x9900, 0x223e, 0x5000 }, + { 0x9900, 0x2236, 0x4000 }, + { 0x9900, 0x2232, 0x3000 }, + { 0x9900, 0x2230, 0x2000 }, + { 0x1900, 0x222f, 0x0000 }, + { 0x1900, 0x2231, 0x0000 }, + { 0x9900, 0x2234, 0x2000 }, + { 0x1900, 0x2233, 0x0000 }, + { 0x1900, 0x2235, 0x0000 }, + { 0x9900, 0x223a, 0x3000 }, + { 0x9900, 0x2238, 0x2000 }, + { 0x1900, 0x2237, 0x0000 }, + { 0x1900, 0x2239, 0x0000 }, + { 0x9900, 0x223c, 0x2000 }, + { 0x1900, 0x223b, 0x0000 }, + { 0x1900, 0x223d, 0x0000 }, + { 0x9900, 0x2246, 0x4000 }, + { 0x9900, 0x2242, 0x3000 }, + { 0x9900, 0x2240, 0x2000 }, + { 0x1900, 0x223f, 0x0000 }, + { 0x1900, 0x2241, 0x0000 }, + { 0x9900, 0x2244, 0x2000 }, + { 0x1900, 0x2243, 0x0000 }, + { 0x1900, 0x2245, 0x0000 }, + { 0x9900, 0x224a, 0x3000 }, + { 0x9900, 0x2248, 0x2000 }, + { 0x1900, 0x2247, 0x0000 }, + { 0x1900, 0x2249, 0x0000 }, + { 0x9900, 0x224c, 0x2000 }, + { 0x1900, 0x224b, 0x0000 }, + { 0x1900, 0x224d, 0x0000 }, + { 0x9900, 0x225e, 0x5000 }, + { 0x9900, 0x2256, 0x4000 }, + { 0x9900, 0x2252, 0x3000 }, + { 0x9900, 0x2250, 0x2000 }, + { 0x1900, 0x224f, 0x0000 }, + { 0x1900, 0x2251, 0x0000 }, + { 0x9900, 0x2254, 0x2000 }, + { 0x1900, 0x2253, 0x0000 }, + { 0x1900, 0x2255, 0x0000 }, + { 0x9900, 0x225a, 0x3000 }, + { 0x9900, 0x2258, 0x2000 }, + { 0x1900, 0x2257, 0x0000 }, + { 0x1900, 0x2259, 0x0000 }, + { 0x9900, 0x225c, 0x2000 }, + { 0x1900, 0x225b, 0x0000 }, + { 0x1900, 0x225d, 0x0000 }, + { 0x9900, 0x2266, 0x4000 }, + { 0x9900, 0x2262, 0x3000 }, + { 0x9900, 0x2260, 0x2000 }, + { 0x1900, 0x225f, 0x0000 }, + { 0x1900, 0x2261, 0x0000 }, + { 0x9900, 0x2264, 0x2000 }, + { 0x1900, 0x2263, 0x0000 }, + { 0x1900, 0x2265, 0x0000 }, + { 0x9900, 0x226a, 0x3000 }, + { 0x9900, 0x2268, 0x2000 }, + { 0x1900, 0x2267, 0x0000 }, + { 0x1900, 0x2269, 0x0000 }, + { 0x9900, 0x226c, 0x2000 }, + { 0x1900, 0x226b, 0x0000 }, + { 0x1900, 0x226d, 0x0000 }, + { 0x9900, 0x228e, 0x6000 }, + { 0x9900, 0x227e, 0x5000 }, + { 0x9900, 0x2276, 0x4000 }, + { 0x9900, 0x2272, 0x3000 }, + { 0x9900, 0x2270, 0x2000 }, + { 0x1900, 0x226f, 0x0000 }, + { 0x1900, 0x2271, 0x0000 }, + { 0x9900, 0x2274, 0x2000 }, + { 0x1900, 0x2273, 0x0000 }, + { 0x1900, 0x2275, 0x0000 }, + { 0x9900, 0x227a, 0x3000 }, + { 0x9900, 0x2278, 0x2000 }, + { 0x1900, 0x2277, 0x0000 }, + { 0x1900, 0x2279, 0x0000 }, + { 0x9900, 0x227c, 0x2000 }, + { 0x1900, 0x227b, 0x0000 }, + { 0x1900, 0x227d, 0x0000 }, + { 0x9900, 0x2286, 0x4000 }, + { 0x9900, 0x2282, 0x3000 }, + { 0x9900, 0x2280, 0x2000 }, + { 0x1900, 0x227f, 0x0000 }, + { 0x1900, 0x2281, 0x0000 }, + { 0x9900, 0x2284, 0x2000 }, + { 0x1900, 0x2283, 0x0000 }, + { 0x1900, 0x2285, 0x0000 }, + { 0x9900, 0x228a, 0x3000 }, + { 0x9900, 0x2288, 0x2000 }, + { 0x1900, 0x2287, 0x0000 }, + { 0x1900, 0x2289, 0x0000 }, + { 0x9900, 0x228c, 0x2000 }, + { 0x1900, 0x228b, 0x0000 }, + { 0x1900, 0x228d, 0x0000 }, + { 0x9900, 0x229e, 0x5000 }, + { 0x9900, 0x2296, 0x4000 }, + { 0x9900, 0x2292, 0x3000 }, + { 0x9900, 0x2290, 0x2000 }, + { 0x1900, 0x228f, 0x0000 }, + { 0x1900, 0x2291, 0x0000 }, + { 0x9900, 0x2294, 0x2000 }, + { 0x1900, 0x2293, 0x0000 }, + { 0x1900, 0x2295, 0x0000 }, + { 0x9900, 0x229a, 0x3000 }, + { 0x9900, 0x2298, 0x2000 }, + { 0x1900, 0x2297, 0x0000 }, + { 0x1900, 0x2299, 0x0000 }, + { 0x9900, 0x229c, 0x2000 }, + { 0x1900, 0x229b, 0x0000 }, + { 0x1900, 0x229d, 0x0000 }, + { 0x9900, 0x22a6, 0x4000 }, + { 0x9900, 0x22a2, 0x3000 }, + { 0x9900, 0x22a0, 0x2000 }, + { 0x1900, 0x229f, 0x0000 }, + { 0x1900, 0x22a1, 0x0000 }, + { 0x9900, 0x22a4, 0x2000 }, + { 0x1900, 0x22a3, 0x0000 }, + { 0x1900, 0x22a5, 0x0000 }, + { 0x9900, 0x22aa, 0x3000 }, + { 0x9900, 0x22a8, 0x2000 }, + { 0x1900, 0x22a7, 0x0000 }, + { 0x1900, 0x22a9, 0x0000 }, + { 0x9900, 0x22ac, 0x2000 }, + { 0x1900, 0x22ab, 0x0000 }, + { 0x1900, 0x22ad, 0x0000 }, + { 0x8f00, 0x2787, 0xb000 }, + { 0x9a00, 0x250b, 0xa000 }, + { 0x9900, 0x23ae, 0x9000 }, + { 0x9a00, 0x232e, 0x8000 }, + { 0x9900, 0x22ee, 0x7000 }, + { 0x9900, 0x22ce, 0x6000 }, + { 0x9900, 0x22be, 0x5000 }, + { 0x9900, 0x22b6, 0x4000 }, + { 0x9900, 0x22b2, 0x3000 }, + { 0x9900, 0x22b0, 0x2000 }, + { 0x1900, 0x22af, 0x0000 }, + { 0x1900, 0x22b1, 0x0000 }, + { 0x9900, 0x22b4, 0x2000 }, + { 0x1900, 0x22b3, 0x0000 }, + { 0x1900, 0x22b5, 0x0000 }, + { 0x9900, 0x22ba, 0x3000 }, + { 0x9900, 0x22b8, 0x2000 }, + { 0x1900, 0x22b7, 0x0000 }, + { 0x1900, 0x22b9, 0x0000 }, + { 0x9900, 0x22bc, 0x2000 }, + { 0x1900, 0x22bb, 0x0000 }, + { 0x1900, 0x22bd, 0x0000 }, + { 0x9900, 0x22c6, 0x4000 }, + { 0x9900, 0x22c2, 0x3000 }, + { 0x9900, 0x22c0, 0x2000 }, + { 0x1900, 0x22bf, 0x0000 }, + { 0x1900, 0x22c1, 0x0000 }, + { 0x9900, 0x22c4, 0x2000 }, + { 0x1900, 0x22c3, 0x0000 }, + { 0x1900, 0x22c5, 0x0000 }, + { 0x9900, 0x22ca, 0x3000 }, + { 0x9900, 0x22c8, 0x2000 }, + { 0x1900, 0x22c7, 0x0000 }, + { 0x1900, 0x22c9, 0x0000 }, + { 0x9900, 0x22cc, 0x2000 }, + { 0x1900, 0x22cb, 0x0000 }, + { 0x1900, 0x22cd, 0x0000 }, + { 0x9900, 0x22de, 0x5000 }, + { 0x9900, 0x22d6, 0x4000 }, + { 0x9900, 0x22d2, 0x3000 }, + { 0x9900, 0x22d0, 0x2000 }, + { 0x1900, 0x22cf, 0x0000 }, + { 0x1900, 0x22d1, 0x0000 }, + { 0x9900, 0x22d4, 0x2000 }, + { 0x1900, 0x22d3, 0x0000 }, + { 0x1900, 0x22d5, 0x0000 }, + { 0x9900, 0x22da, 0x3000 }, + { 0x9900, 0x22d8, 0x2000 }, + { 0x1900, 0x22d7, 0x0000 }, + { 0x1900, 0x22d9, 0x0000 }, + { 0x9900, 0x22dc, 0x2000 }, + { 0x1900, 0x22db, 0x0000 }, + { 0x1900, 0x22dd, 0x0000 }, + { 0x9900, 0x22e6, 0x4000 }, + { 0x9900, 0x22e2, 0x3000 }, + { 0x9900, 0x22e0, 0x2000 }, + { 0x1900, 0x22df, 0x0000 }, + { 0x1900, 0x22e1, 0x0000 }, + { 0x9900, 0x22e4, 0x2000 }, + { 0x1900, 0x22e3, 0x0000 }, + { 0x1900, 0x22e5, 0x0000 }, + { 0x9900, 0x22ea, 0x3000 }, + { 0x9900, 0x22e8, 0x2000 }, + { 0x1900, 0x22e7, 0x0000 }, + { 0x1900, 0x22e9, 0x0000 }, + { 0x9900, 0x22ec, 0x2000 }, + { 0x1900, 0x22eb, 0x0000 }, + { 0x1900, 0x22ed, 0x0000 }, + { 0x9a00, 0x230e, 0x6000 }, + { 0x9900, 0x22fe, 0x5000 }, + { 0x9900, 0x22f6, 0x4000 }, + { 0x9900, 0x22f2, 0x3000 }, + { 0x9900, 0x22f0, 0x2000 }, + { 0x1900, 0x22ef, 0x0000 }, + { 0x1900, 0x22f1, 0x0000 }, + { 0x9900, 0x22f4, 0x2000 }, + { 0x1900, 0x22f3, 0x0000 }, + { 0x1900, 0x22f5, 0x0000 }, + { 0x9900, 0x22fa, 0x3000 }, + { 0x9900, 0x22f8, 0x2000 }, + { 0x1900, 0x22f7, 0x0000 }, + { 0x1900, 0x22f9, 0x0000 }, + { 0x9900, 0x22fc, 0x2000 }, + { 0x1900, 0x22fb, 0x0000 }, + { 0x1900, 0x22fd, 0x0000 }, + { 0x9a00, 0x2306, 0x4000 }, + { 0x9a00, 0x2302, 0x3000 }, + { 0x9a00, 0x2300, 0x2000 }, + { 0x1900, 0x22ff, 0x0000 }, + { 0x1a00, 0x2301, 0x0000 }, + { 0x9a00, 0x2304, 0x2000 }, + { 0x1a00, 0x2303, 0x0000 }, + { 0x1a00, 0x2305, 0x0000 }, + { 0x9900, 0x230a, 0x3000 }, + { 0x9900, 0x2308, 0x2000 }, + { 0x1a00, 0x2307, 0x0000 }, + { 0x1900, 0x2309, 0x0000 }, + { 0x9a00, 0x230c, 0x2000 }, + { 0x1900, 0x230b, 0x0000 }, + { 0x1a00, 0x230d, 0x0000 }, + { 0x9a00, 0x231e, 0x5000 }, + { 0x9a00, 0x2316, 0x4000 }, + { 0x9a00, 0x2312, 0x3000 }, + { 0x9a00, 0x2310, 0x2000 }, + { 0x1a00, 0x230f, 0x0000 }, + { 0x1a00, 0x2311, 0x0000 }, + { 0x9a00, 0x2314, 0x2000 }, + { 0x1a00, 0x2313, 0x0000 }, + { 0x1a00, 0x2315, 0x0000 }, + { 0x9a00, 0x231a, 0x3000 }, + { 0x9a00, 0x2318, 0x2000 }, + { 0x1a00, 0x2317, 0x0000 }, + { 0x1a00, 0x2319, 0x0000 }, + { 0x9a00, 0x231c, 0x2000 }, + { 0x1a00, 0x231b, 0x0000 }, + { 0x1a00, 0x231d, 0x0000 }, + { 0x9a00, 0x2326, 0x4000 }, + { 0x9a00, 0x2322, 0x3000 }, + { 0x9900, 0x2320, 0x2000 }, + { 0x1a00, 0x231f, 0x0000 }, + { 0x1900, 0x2321, 0x0000 }, + { 0x9a00, 0x2324, 0x2000 }, + { 0x1a00, 0x2323, 0x0000 }, + { 0x1a00, 0x2325, 0x0000 }, + { 0x9200, 0x232a, 0x3000 }, + { 0x9a00, 0x2328, 0x2000 }, + { 0x1a00, 0x2327, 0x0000 }, + { 0x1600, 0x2329, 0x0000 }, + { 0x9a00, 0x232c, 0x2000 }, + { 0x1a00, 0x232b, 0x0000 }, + { 0x1a00, 0x232d, 0x0000 }, + { 0x9a00, 0x236e, 0x7000 }, + { 0x9a00, 0x234e, 0x6000 }, + { 0x9a00, 0x233e, 0x5000 }, + { 0x9a00, 0x2336, 0x4000 }, + { 0x9a00, 0x2332, 0x3000 }, + { 0x9a00, 0x2330, 0x2000 }, + { 0x1a00, 0x232f, 0x0000 }, + { 0x1a00, 0x2331, 0x0000 }, + { 0x9a00, 0x2334, 0x2000 }, + { 0x1a00, 0x2333, 0x0000 }, + { 0x1a00, 0x2335, 0x0000 }, + { 0x9a00, 0x233a, 0x3000 }, + { 0x9a00, 0x2338, 0x2000 }, + { 0x1a00, 0x2337, 0x0000 }, + { 0x1a00, 0x2339, 0x0000 }, + { 0x9a00, 0x233c, 0x2000 }, + { 0x1a00, 0x233b, 0x0000 }, + { 0x1a00, 0x233d, 0x0000 }, + { 0x9a00, 0x2346, 0x4000 }, + { 0x9a00, 0x2342, 0x3000 }, + { 0x9a00, 0x2340, 0x2000 }, + { 0x1a00, 0x233f, 0x0000 }, + { 0x1a00, 0x2341, 0x0000 }, + { 0x9a00, 0x2344, 0x2000 }, + { 0x1a00, 0x2343, 0x0000 }, + { 0x1a00, 0x2345, 0x0000 }, + { 0x9a00, 0x234a, 0x3000 }, + { 0x9a00, 0x2348, 0x2000 }, + { 0x1a00, 0x2347, 0x0000 }, + { 0x1a00, 0x2349, 0x0000 }, + { 0x9a00, 0x234c, 0x2000 }, + { 0x1a00, 0x234b, 0x0000 }, + { 0x1a00, 0x234d, 0x0000 }, + { 0x9a00, 0x235e, 0x5000 }, + { 0x9a00, 0x2356, 0x4000 }, + { 0x9a00, 0x2352, 0x3000 }, + { 0x9a00, 0x2350, 0x2000 }, + { 0x1a00, 0x234f, 0x0000 }, + { 0x1a00, 0x2351, 0x0000 }, + { 0x9a00, 0x2354, 0x2000 }, + { 0x1a00, 0x2353, 0x0000 }, + { 0x1a00, 0x2355, 0x0000 }, + { 0x9a00, 0x235a, 0x3000 }, + { 0x9a00, 0x2358, 0x2000 }, + { 0x1a00, 0x2357, 0x0000 }, + { 0x1a00, 0x2359, 0x0000 }, + { 0x9a00, 0x235c, 0x2000 }, + { 0x1a00, 0x235b, 0x0000 }, + { 0x1a00, 0x235d, 0x0000 }, + { 0x9a00, 0x2366, 0x4000 }, + { 0x9a00, 0x2362, 0x3000 }, + { 0x9a00, 0x2360, 0x2000 }, + { 0x1a00, 0x235f, 0x0000 }, + { 0x1a00, 0x2361, 0x0000 }, + { 0x9a00, 0x2364, 0x2000 }, + { 0x1a00, 0x2363, 0x0000 }, + { 0x1a00, 0x2365, 0x0000 }, + { 0x9a00, 0x236a, 0x3000 }, + { 0x9a00, 0x2368, 0x2000 }, + { 0x1a00, 0x2367, 0x0000 }, + { 0x1a00, 0x2369, 0x0000 }, + { 0x9a00, 0x236c, 0x2000 }, + { 0x1a00, 0x236b, 0x0000 }, + { 0x1a00, 0x236d, 0x0000 }, + { 0x9a00, 0x238e, 0x6000 }, + { 0x9a00, 0x237e, 0x5000 }, + { 0x9a00, 0x2376, 0x4000 }, + { 0x9a00, 0x2372, 0x3000 }, + { 0x9a00, 0x2370, 0x2000 }, + { 0x1a00, 0x236f, 0x0000 }, + { 0x1a00, 0x2371, 0x0000 }, + { 0x9a00, 0x2374, 0x2000 }, + { 0x1a00, 0x2373, 0x0000 }, + { 0x1a00, 0x2375, 0x0000 }, + { 0x9a00, 0x237a, 0x3000 }, + { 0x9a00, 0x2378, 0x2000 }, + { 0x1a00, 0x2377, 0x0000 }, + { 0x1a00, 0x2379, 0x0000 }, + { 0x9900, 0x237c, 0x2000 }, + { 0x1a00, 0x237b, 0x0000 }, + { 0x1a00, 0x237d, 0x0000 }, + { 0x9a00, 0x2386, 0x4000 }, + { 0x9a00, 0x2382, 0x3000 }, + { 0x9a00, 0x2380, 0x2000 }, + { 0x1a00, 0x237f, 0x0000 }, + { 0x1a00, 0x2381, 0x0000 }, + { 0x9a00, 0x2384, 0x2000 }, + { 0x1a00, 0x2383, 0x0000 }, + { 0x1a00, 0x2385, 0x0000 }, + { 0x9a00, 0x238a, 0x3000 }, + { 0x9a00, 0x2388, 0x2000 }, + { 0x1a00, 0x2387, 0x0000 }, + { 0x1a00, 0x2389, 0x0000 }, + { 0x9a00, 0x238c, 0x2000 }, + { 0x1a00, 0x238b, 0x0000 }, + { 0x1a00, 0x238d, 0x0000 }, + { 0x9900, 0x239e, 0x5000 }, + { 0x9a00, 0x2396, 0x4000 }, + { 0x9a00, 0x2392, 0x3000 }, + { 0x9a00, 0x2390, 0x2000 }, + { 0x1a00, 0x238f, 0x0000 }, + { 0x1a00, 0x2391, 0x0000 }, + { 0x9a00, 0x2394, 0x2000 }, + { 0x1a00, 0x2393, 0x0000 }, + { 0x1a00, 0x2395, 0x0000 }, + { 0x9a00, 0x239a, 0x3000 }, + { 0x9a00, 0x2398, 0x2000 }, + { 0x1a00, 0x2397, 0x0000 }, + { 0x1a00, 0x2399, 0x0000 }, + { 0x9900, 0x239c, 0x2000 }, + { 0x1900, 0x239b, 0x0000 }, + { 0x1900, 0x239d, 0x0000 }, + { 0x9900, 0x23a6, 0x4000 }, + { 0x9900, 0x23a2, 0x3000 }, + { 0x9900, 0x23a0, 0x2000 }, + { 0x1900, 0x239f, 0x0000 }, + { 0x1900, 0x23a1, 0x0000 }, + { 0x9900, 0x23a4, 0x2000 }, + { 0x1900, 0x23a3, 0x0000 }, + { 0x1900, 0x23a5, 0x0000 }, + { 0x9900, 0x23aa, 0x3000 }, + { 0x9900, 0x23a8, 0x2000 }, + { 0x1900, 0x23a7, 0x0000 }, + { 0x1900, 0x23a9, 0x0000 }, + { 0x9900, 0x23ac, 0x2000 }, + { 0x1900, 0x23ab, 0x0000 }, + { 0x1900, 0x23ad, 0x0000 }, + { 0x8f00, 0x248b, 0x8000 }, + { 0x9a00, 0x241d, 0x7000 }, + { 0x9a00, 0x23ce, 0x6000 }, + { 0x9a00, 0x23be, 0x5000 }, + { 0x9500, 0x23b6, 0x4000 }, + { 0x9900, 0x23b2, 0x3000 }, + { 0x9900, 0x23b0, 0x2000 }, + { 0x1900, 0x23af, 0x0000 }, + { 0x1900, 0x23b1, 0x0000 }, + { 0x9600, 0x23b4, 0x2000 }, + { 0x1900, 0x23b3, 0x0000 }, + { 0x1200, 0x23b5, 0x0000 }, + { 0x9a00, 0x23ba, 0x3000 }, + { 0x9a00, 0x23b8, 0x2000 }, + { 0x1a00, 0x23b7, 0x0000 }, + { 0x1a00, 0x23b9, 0x0000 }, + { 0x9a00, 0x23bc, 0x2000 }, + { 0x1a00, 0x23bb, 0x0000 }, + { 0x1a00, 0x23bd, 0x0000 }, + { 0x9a00, 0x23c6, 0x4000 }, + { 0x9a00, 0x23c2, 0x3000 }, + { 0x9a00, 0x23c0, 0x2000 }, + { 0x1a00, 0x23bf, 0x0000 }, + { 0x1a00, 0x23c1, 0x0000 }, + { 0x9a00, 0x23c4, 0x2000 }, + { 0x1a00, 0x23c3, 0x0000 }, + { 0x1a00, 0x23c5, 0x0000 }, + { 0x9a00, 0x23ca, 0x3000 }, + { 0x9a00, 0x23c8, 0x2000 }, + { 0x1a00, 0x23c7, 0x0000 }, + { 0x1a00, 0x23c9, 0x0000 }, + { 0x9a00, 0x23cc, 0x2000 }, + { 0x1a00, 0x23cb, 0x0000 }, + { 0x1a00, 0x23cd, 0x0000 }, + { 0x9a00, 0x240d, 0x5000 }, + { 0x9a00, 0x2405, 0x4000 }, + { 0x9a00, 0x2401, 0x3000 }, + { 0x9a00, 0x23d0, 0x2000 }, + { 0x1a00, 0x23cf, 0x0000 }, + { 0x1a00, 0x2400, 0x0000 }, + { 0x9a00, 0x2403, 0x2000 }, + { 0x1a00, 0x2402, 0x0000 }, + { 0x1a00, 0x2404, 0x0000 }, + { 0x9a00, 0x2409, 0x3000 }, + { 0x9a00, 0x2407, 0x2000 }, + { 0x1a00, 0x2406, 0x0000 }, + { 0x1a00, 0x2408, 0x0000 }, + { 0x9a00, 0x240b, 0x2000 }, + { 0x1a00, 0x240a, 0x0000 }, + { 0x1a00, 0x240c, 0x0000 }, + { 0x9a00, 0x2415, 0x4000 }, + { 0x9a00, 0x2411, 0x3000 }, + { 0x9a00, 0x240f, 0x2000 }, + { 0x1a00, 0x240e, 0x0000 }, + { 0x1a00, 0x2410, 0x0000 }, + { 0x9a00, 0x2413, 0x2000 }, + { 0x1a00, 0x2412, 0x0000 }, + { 0x1a00, 0x2414, 0x0000 }, + { 0x9a00, 0x2419, 0x3000 }, + { 0x9a00, 0x2417, 0x2000 }, + { 0x1a00, 0x2416, 0x0000 }, + { 0x1a00, 0x2418, 0x0000 }, + { 0x9a00, 0x241b, 0x2000 }, + { 0x1a00, 0x241a, 0x0000 }, + { 0x1a00, 0x241c, 0x0000 }, + { 0x8f00, 0x246b, 0x6000 }, + { 0x9a00, 0x2446, 0x5000 }, + { 0x9a00, 0x2425, 0x4000 }, + { 0x9a00, 0x2421, 0x3000 }, + { 0x9a00, 0x241f, 0x2000 }, + { 0x1a00, 0x241e, 0x0000 }, + { 0x1a00, 0x2420, 0x0000 }, + { 0x9a00, 0x2423, 0x2000 }, + { 0x1a00, 0x2422, 0x0000 }, + { 0x1a00, 0x2424, 0x0000 }, + { 0x9a00, 0x2442, 0x3000 }, + { 0x9a00, 0x2440, 0x2000 }, + { 0x1a00, 0x2426, 0x0000 }, + { 0x1a00, 0x2441, 0x0000 }, + { 0x9a00, 0x2444, 0x2000 }, + { 0x1a00, 0x2443, 0x0000 }, + { 0x1a00, 0x2445, 0x0000 }, + { 0x8f00, 0x2463, 0x4000 }, + { 0x9a00, 0x244a, 0x3000 }, + { 0x9a00, 0x2448, 0x2000 }, + { 0x1a00, 0x2447, 0x0000 }, + { 0x1a00, 0x2449, 0x0000 }, + { 0x8f00, 0x2461, 0x2000 }, + { 0x0f00, 0x2460, 0x0000 }, + { 0x0f00, 0x2462, 0x0000 }, + { 0x8f00, 0x2467, 0x3000 }, + { 0x8f00, 0x2465, 0x2000 }, + { 0x0f00, 0x2464, 0x0000 }, + { 0x0f00, 0x2466, 0x0000 }, + { 0x8f00, 0x2469, 0x2000 }, + { 0x0f00, 0x2468, 0x0000 }, + { 0x0f00, 0x246a, 0x0000 }, + { 0x8f00, 0x247b, 0x5000 }, + { 0x8f00, 0x2473, 0x4000 }, + { 0x8f00, 0x246f, 0x3000 }, + { 0x8f00, 0x246d, 0x2000 }, + { 0x0f00, 0x246c, 0x0000 }, + { 0x0f00, 0x246e, 0x0000 }, + { 0x8f00, 0x2471, 0x2000 }, + { 0x0f00, 0x2470, 0x0000 }, + { 0x0f00, 0x2472, 0x0000 }, + { 0x8f00, 0x2477, 0x3000 }, + { 0x8f00, 0x2475, 0x2000 }, + { 0x0f00, 0x2474, 0x0000 }, + { 0x0f00, 0x2476, 0x0000 }, + { 0x8f00, 0x2479, 0x2000 }, + { 0x0f00, 0x2478, 0x0000 }, + { 0x0f00, 0x247a, 0x0000 }, + { 0x8f00, 0x2483, 0x4000 }, + { 0x8f00, 0x247f, 0x3000 }, + { 0x8f00, 0x247d, 0x2000 }, + { 0x0f00, 0x247c, 0x0000 }, + { 0x0f00, 0x247e, 0x0000 }, + { 0x8f00, 0x2481, 0x2000 }, + { 0x0f00, 0x2480, 0x0000 }, + { 0x0f00, 0x2482, 0x0000 }, + { 0x8f00, 0x2487, 0x3000 }, + { 0x8f00, 0x2485, 0x2000 }, + { 0x0f00, 0x2484, 0x0000 }, + { 0x0f00, 0x2486, 0x0000 }, + { 0x8f00, 0x2489, 0x2000 }, + { 0x0f00, 0x2488, 0x0000 }, + { 0x0f00, 0x248a, 0x0000 }, + { 0x9a00, 0x24cb, 0x7000 }, + { 0x9a00, 0x24ab, 0x6000 }, + { 0x8f00, 0x249b, 0x5000 }, + { 0x8f00, 0x2493, 0x4000 }, + { 0x8f00, 0x248f, 0x3000 }, + { 0x8f00, 0x248d, 0x2000 }, + { 0x0f00, 0x248c, 0x0000 }, + { 0x0f00, 0x248e, 0x0000 }, + { 0x8f00, 0x2491, 0x2000 }, + { 0x0f00, 0x2490, 0x0000 }, + { 0x0f00, 0x2492, 0x0000 }, + { 0x8f00, 0x2497, 0x3000 }, + { 0x8f00, 0x2495, 0x2000 }, + { 0x0f00, 0x2494, 0x0000 }, + { 0x0f00, 0x2496, 0x0000 }, + { 0x8f00, 0x2499, 0x2000 }, + { 0x0f00, 0x2498, 0x0000 }, + { 0x0f00, 0x249a, 0x0000 }, + { 0x9a00, 0x24a3, 0x4000 }, + { 0x9a00, 0x249f, 0x3000 }, + { 0x9a00, 0x249d, 0x2000 }, + { 0x1a00, 0x249c, 0x0000 }, + { 0x1a00, 0x249e, 0x0000 }, + { 0x9a00, 0x24a1, 0x2000 }, + { 0x1a00, 0x24a0, 0x0000 }, + { 0x1a00, 0x24a2, 0x0000 }, + { 0x9a00, 0x24a7, 0x3000 }, + { 0x9a00, 0x24a5, 0x2000 }, + { 0x1a00, 0x24a4, 0x0000 }, + { 0x1a00, 0x24a6, 0x0000 }, + { 0x9a00, 0x24a9, 0x2000 }, + { 0x1a00, 0x24a8, 0x0000 }, + { 0x1a00, 0x24aa, 0x0000 }, + { 0x9a00, 0x24bb, 0x5000 }, + { 0x9a00, 0x24b3, 0x4000 }, + { 0x9a00, 0x24af, 0x3000 }, + { 0x9a00, 0x24ad, 0x2000 }, + { 0x1a00, 0x24ac, 0x0000 }, + { 0x1a00, 0x24ae, 0x0000 }, + { 0x9a00, 0x24b1, 0x2000 }, + { 0x1a00, 0x24b0, 0x0000 }, + { 0x1a00, 0x24b2, 0x0000 }, + { 0x9a00, 0x24b7, 0x3000 }, + { 0x9a00, 0x24b5, 0x2000 }, + { 0x1a00, 0x24b4, 0x0000 }, + { 0x1a00, 0x24b6, 0x0000 }, + { 0x9a00, 0x24b9, 0x2000 }, + { 0x1a00, 0x24b8, 0x0000 }, + { 0x1a00, 0x24ba, 0x0000 }, + { 0x9a00, 0x24c3, 0x4000 }, + { 0x9a00, 0x24bf, 0x3000 }, + { 0x9a00, 0x24bd, 0x2000 }, + { 0x1a00, 0x24bc, 0x0000 }, + { 0x1a00, 0x24be, 0x0000 }, + { 0x9a00, 0x24c1, 0x2000 }, + { 0x1a00, 0x24c0, 0x0000 }, + { 0x1a00, 0x24c2, 0x0000 }, + { 0x9a00, 0x24c7, 0x3000 }, + { 0x9a00, 0x24c5, 0x2000 }, + { 0x1a00, 0x24c4, 0x0000 }, + { 0x1a00, 0x24c6, 0x0000 }, + { 0x9a00, 0x24c9, 0x2000 }, + { 0x1a00, 0x24c8, 0x0000 }, + { 0x1a00, 0x24ca, 0x0000 }, + { 0x8f00, 0x24eb, 0x6000 }, + { 0x9a00, 0x24db, 0x5000 }, + { 0x9a00, 0x24d3, 0x4000 }, + { 0x9a00, 0x24cf, 0x3000 }, + { 0x9a00, 0x24cd, 0x2000 }, + { 0x1a00, 0x24cc, 0x0000 }, + { 0x1a00, 0x24ce, 0x0000 }, + { 0x9a00, 0x24d1, 0x2000 }, + { 0x1a00, 0x24d0, 0x0000 }, + { 0x1a00, 0x24d2, 0x0000 }, + { 0x9a00, 0x24d7, 0x3000 }, + { 0x9a00, 0x24d5, 0x2000 }, + { 0x1a00, 0x24d4, 0x0000 }, + { 0x1a00, 0x24d6, 0x0000 }, + { 0x9a00, 0x24d9, 0x2000 }, + { 0x1a00, 0x24d8, 0x0000 }, + { 0x1a00, 0x24da, 0x0000 }, + { 0x9a00, 0x24e3, 0x4000 }, + { 0x9a00, 0x24df, 0x3000 }, + { 0x9a00, 0x24dd, 0x2000 }, + { 0x1a00, 0x24dc, 0x0000 }, + { 0x1a00, 0x24de, 0x0000 }, + { 0x9a00, 0x24e1, 0x2000 }, + { 0x1a00, 0x24e0, 0x0000 }, + { 0x1a00, 0x24e2, 0x0000 }, + { 0x9a00, 0x24e7, 0x3000 }, + { 0x9a00, 0x24e5, 0x2000 }, + { 0x1a00, 0x24e4, 0x0000 }, + { 0x1a00, 0x24e6, 0x0000 }, + { 0x9a00, 0x24e9, 0x2000 }, + { 0x1a00, 0x24e8, 0x0000 }, + { 0x0f00, 0x24ea, 0x0000 }, + { 0x8f00, 0x24fb, 0x5000 }, + { 0x8f00, 0x24f3, 0x4000 }, + { 0x8f00, 0x24ef, 0x3000 }, + { 0x8f00, 0x24ed, 0x2000 }, + { 0x0f00, 0x24ec, 0x0000 }, + { 0x0f00, 0x24ee, 0x0000 }, + { 0x8f00, 0x24f1, 0x2000 }, + { 0x0f00, 0x24f0, 0x0000 }, + { 0x0f00, 0x24f2, 0x0000 }, + { 0x8f00, 0x24f7, 0x3000 }, + { 0x8f00, 0x24f5, 0x2000 }, + { 0x0f00, 0x24f4, 0x0000 }, + { 0x0f00, 0x24f6, 0x0000 }, + { 0x8f00, 0x24f9, 0x2000 }, + { 0x0f00, 0x24f8, 0x0000 }, + { 0x0f00, 0x24fa, 0x0000 }, + { 0x9a00, 0x2503, 0x4000 }, + { 0x8f00, 0x24ff, 0x3000 }, + { 0x8f00, 0x24fd, 0x2000 }, + { 0x0f00, 0x24fc, 0x0000 }, + { 0x0f00, 0x24fe, 0x0000 }, + { 0x9a00, 0x2501, 0x2000 }, + { 0x1a00, 0x2500, 0x0000 }, + { 0x1a00, 0x2502, 0x0000 }, + { 0x9a00, 0x2507, 0x3000 }, + { 0x9a00, 0x2505, 0x2000 }, + { 0x1a00, 0x2504, 0x0000 }, + { 0x1a00, 0x2506, 0x0000 }, + { 0x9a00, 0x2509, 0x2000 }, + { 0x1a00, 0x2508, 0x0000 }, + { 0x1a00, 0x250a, 0x0000 }, + { 0x9a00, 0x260b, 0x9000 }, + { 0x9a00, 0x258b, 0x8000 }, + { 0x9a00, 0x254b, 0x7000 }, + { 0x9a00, 0x252b, 0x6000 }, + { 0x9a00, 0x251b, 0x5000 }, + { 0x9a00, 0x2513, 0x4000 }, + { 0x9a00, 0x250f, 0x3000 }, + { 0x9a00, 0x250d, 0x2000 }, + { 0x1a00, 0x250c, 0x0000 }, + { 0x1a00, 0x250e, 0x0000 }, + { 0x9a00, 0x2511, 0x2000 }, + { 0x1a00, 0x2510, 0x0000 }, + { 0x1a00, 0x2512, 0x0000 }, + { 0x9a00, 0x2517, 0x3000 }, + { 0x9a00, 0x2515, 0x2000 }, + { 0x1a00, 0x2514, 0x0000 }, + { 0x1a00, 0x2516, 0x0000 }, + { 0x9a00, 0x2519, 0x2000 }, + { 0x1a00, 0x2518, 0x0000 }, + { 0x1a00, 0x251a, 0x0000 }, + { 0x9a00, 0x2523, 0x4000 }, + { 0x9a00, 0x251f, 0x3000 }, + { 0x9a00, 0x251d, 0x2000 }, + { 0x1a00, 0x251c, 0x0000 }, + { 0x1a00, 0x251e, 0x0000 }, + { 0x9a00, 0x2521, 0x2000 }, + { 0x1a00, 0x2520, 0x0000 }, + { 0x1a00, 0x2522, 0x0000 }, + { 0x9a00, 0x2527, 0x3000 }, + { 0x9a00, 0x2525, 0x2000 }, + { 0x1a00, 0x2524, 0x0000 }, + { 0x1a00, 0x2526, 0x0000 }, + { 0x9a00, 0x2529, 0x2000 }, + { 0x1a00, 0x2528, 0x0000 }, + { 0x1a00, 0x252a, 0x0000 }, + { 0x9a00, 0x253b, 0x5000 }, + { 0x9a00, 0x2533, 0x4000 }, + { 0x9a00, 0x252f, 0x3000 }, + { 0x9a00, 0x252d, 0x2000 }, + { 0x1a00, 0x252c, 0x0000 }, + { 0x1a00, 0x252e, 0x0000 }, + { 0x9a00, 0x2531, 0x2000 }, + { 0x1a00, 0x2530, 0x0000 }, + { 0x1a00, 0x2532, 0x0000 }, + { 0x9a00, 0x2537, 0x3000 }, + { 0x9a00, 0x2535, 0x2000 }, + { 0x1a00, 0x2534, 0x0000 }, + { 0x1a00, 0x2536, 0x0000 }, + { 0x9a00, 0x2539, 0x2000 }, + { 0x1a00, 0x2538, 0x0000 }, + { 0x1a00, 0x253a, 0x0000 }, + { 0x9a00, 0x2543, 0x4000 }, + { 0x9a00, 0x253f, 0x3000 }, + { 0x9a00, 0x253d, 0x2000 }, + { 0x1a00, 0x253c, 0x0000 }, + { 0x1a00, 0x253e, 0x0000 }, + { 0x9a00, 0x2541, 0x2000 }, + { 0x1a00, 0x2540, 0x0000 }, + { 0x1a00, 0x2542, 0x0000 }, + { 0x9a00, 0x2547, 0x3000 }, + { 0x9a00, 0x2545, 0x2000 }, + { 0x1a00, 0x2544, 0x0000 }, + { 0x1a00, 0x2546, 0x0000 }, + { 0x9a00, 0x2549, 0x2000 }, + { 0x1a00, 0x2548, 0x0000 }, + { 0x1a00, 0x254a, 0x0000 }, + { 0x9a00, 0x256b, 0x6000 }, + { 0x9a00, 0x255b, 0x5000 }, + { 0x9a00, 0x2553, 0x4000 }, + { 0x9a00, 0x254f, 0x3000 }, + { 0x9a00, 0x254d, 0x2000 }, + { 0x1a00, 0x254c, 0x0000 }, + { 0x1a00, 0x254e, 0x0000 }, + { 0x9a00, 0x2551, 0x2000 }, + { 0x1a00, 0x2550, 0x0000 }, + { 0x1a00, 0x2552, 0x0000 }, + { 0x9a00, 0x2557, 0x3000 }, + { 0x9a00, 0x2555, 0x2000 }, + { 0x1a00, 0x2554, 0x0000 }, + { 0x1a00, 0x2556, 0x0000 }, + { 0x9a00, 0x2559, 0x2000 }, + { 0x1a00, 0x2558, 0x0000 }, + { 0x1a00, 0x255a, 0x0000 }, + { 0x9a00, 0x2563, 0x4000 }, + { 0x9a00, 0x255f, 0x3000 }, + { 0x9a00, 0x255d, 0x2000 }, + { 0x1a00, 0x255c, 0x0000 }, + { 0x1a00, 0x255e, 0x0000 }, + { 0x9a00, 0x2561, 0x2000 }, + { 0x1a00, 0x2560, 0x0000 }, + { 0x1a00, 0x2562, 0x0000 }, + { 0x9a00, 0x2567, 0x3000 }, + { 0x9a00, 0x2565, 0x2000 }, + { 0x1a00, 0x2564, 0x0000 }, + { 0x1a00, 0x2566, 0x0000 }, + { 0x9a00, 0x2569, 0x2000 }, + { 0x1a00, 0x2568, 0x0000 }, + { 0x1a00, 0x256a, 0x0000 }, + { 0x9a00, 0x257b, 0x5000 }, + { 0x9a00, 0x2573, 0x4000 }, + { 0x9a00, 0x256f, 0x3000 }, + { 0x9a00, 0x256d, 0x2000 }, + { 0x1a00, 0x256c, 0x0000 }, + { 0x1a00, 0x256e, 0x0000 }, + { 0x9a00, 0x2571, 0x2000 }, + { 0x1a00, 0x2570, 0x0000 }, + { 0x1a00, 0x2572, 0x0000 }, + { 0x9a00, 0x2577, 0x3000 }, + { 0x9a00, 0x2575, 0x2000 }, + { 0x1a00, 0x2574, 0x0000 }, + { 0x1a00, 0x2576, 0x0000 }, + { 0x9a00, 0x2579, 0x2000 }, + { 0x1a00, 0x2578, 0x0000 }, + { 0x1a00, 0x257a, 0x0000 }, + { 0x9a00, 0x2583, 0x4000 }, + { 0x9a00, 0x257f, 0x3000 }, + { 0x9a00, 0x257d, 0x2000 }, + { 0x1a00, 0x257c, 0x0000 }, + { 0x1a00, 0x257e, 0x0000 }, + { 0x9a00, 0x2581, 0x2000 }, + { 0x1a00, 0x2580, 0x0000 }, + { 0x1a00, 0x2582, 0x0000 }, + { 0x9a00, 0x2587, 0x3000 }, + { 0x9a00, 0x2585, 0x2000 }, + { 0x1a00, 0x2584, 0x0000 }, + { 0x1a00, 0x2586, 0x0000 }, + { 0x9a00, 0x2589, 0x2000 }, + { 0x1a00, 0x2588, 0x0000 }, + { 0x1a00, 0x258a, 0x0000 }, + { 0x9a00, 0x25cb, 0x7000 }, + { 0x9a00, 0x25ab, 0x6000 }, + { 0x9a00, 0x259b, 0x5000 }, + { 0x9a00, 0x2593, 0x4000 }, + { 0x9a00, 0x258f, 0x3000 }, + { 0x9a00, 0x258d, 0x2000 }, + { 0x1a00, 0x258c, 0x0000 }, + { 0x1a00, 0x258e, 0x0000 }, + { 0x9a00, 0x2591, 0x2000 }, + { 0x1a00, 0x2590, 0x0000 }, + { 0x1a00, 0x2592, 0x0000 }, + { 0x9a00, 0x2597, 0x3000 }, + { 0x9a00, 0x2595, 0x2000 }, + { 0x1a00, 0x2594, 0x0000 }, + { 0x1a00, 0x2596, 0x0000 }, + { 0x9a00, 0x2599, 0x2000 }, + { 0x1a00, 0x2598, 0x0000 }, + { 0x1a00, 0x259a, 0x0000 }, + { 0x9a00, 0x25a3, 0x4000 }, + { 0x9a00, 0x259f, 0x3000 }, + { 0x9a00, 0x259d, 0x2000 }, + { 0x1a00, 0x259c, 0x0000 }, + { 0x1a00, 0x259e, 0x0000 }, + { 0x9a00, 0x25a1, 0x2000 }, + { 0x1a00, 0x25a0, 0x0000 }, + { 0x1a00, 0x25a2, 0x0000 }, + { 0x9a00, 0x25a7, 0x3000 }, + { 0x9a00, 0x25a5, 0x2000 }, + { 0x1a00, 0x25a4, 0x0000 }, + { 0x1a00, 0x25a6, 0x0000 }, + { 0x9a00, 0x25a9, 0x2000 }, + { 0x1a00, 0x25a8, 0x0000 }, + { 0x1a00, 0x25aa, 0x0000 }, + { 0x9a00, 0x25bb, 0x5000 }, + { 0x9a00, 0x25b3, 0x4000 }, + { 0x9a00, 0x25af, 0x3000 }, + { 0x9a00, 0x25ad, 0x2000 }, + { 0x1a00, 0x25ac, 0x0000 }, + { 0x1a00, 0x25ae, 0x0000 }, + { 0x9a00, 0x25b1, 0x2000 }, + { 0x1a00, 0x25b0, 0x0000 }, + { 0x1a00, 0x25b2, 0x0000 }, + { 0x9900, 0x25b7, 0x3000 }, + { 0x9a00, 0x25b5, 0x2000 }, + { 0x1a00, 0x25b4, 0x0000 }, + { 0x1a00, 0x25b6, 0x0000 }, + { 0x9a00, 0x25b9, 0x2000 }, + { 0x1a00, 0x25b8, 0x0000 }, + { 0x1a00, 0x25ba, 0x0000 }, + { 0x9a00, 0x25c3, 0x4000 }, + { 0x9a00, 0x25bf, 0x3000 }, + { 0x9a00, 0x25bd, 0x2000 }, + { 0x1a00, 0x25bc, 0x0000 }, + { 0x1a00, 0x25be, 0x0000 }, + { 0x9900, 0x25c1, 0x2000 }, + { 0x1a00, 0x25c0, 0x0000 }, + { 0x1a00, 0x25c2, 0x0000 }, + { 0x9a00, 0x25c7, 0x3000 }, + { 0x9a00, 0x25c5, 0x2000 }, + { 0x1a00, 0x25c4, 0x0000 }, + { 0x1a00, 0x25c6, 0x0000 }, + { 0x9a00, 0x25c9, 0x2000 }, + { 0x1a00, 0x25c8, 0x0000 }, + { 0x1a00, 0x25ca, 0x0000 }, + { 0x9a00, 0x25eb, 0x6000 }, + { 0x9a00, 0x25db, 0x5000 }, + { 0x9a00, 0x25d3, 0x4000 }, + { 0x9a00, 0x25cf, 0x3000 }, + { 0x9a00, 0x25cd, 0x2000 }, + { 0x1a00, 0x25cc, 0x0000 }, + { 0x1a00, 0x25ce, 0x0000 }, + { 0x9a00, 0x25d1, 0x2000 }, + { 0x1a00, 0x25d0, 0x0000 }, + { 0x1a00, 0x25d2, 0x0000 }, + { 0x9a00, 0x25d7, 0x3000 }, + { 0x9a00, 0x25d5, 0x2000 }, + { 0x1a00, 0x25d4, 0x0000 }, + { 0x1a00, 0x25d6, 0x0000 }, + { 0x9a00, 0x25d9, 0x2000 }, + { 0x1a00, 0x25d8, 0x0000 }, + { 0x1a00, 0x25da, 0x0000 }, + { 0x9a00, 0x25e3, 0x4000 }, + { 0x9a00, 0x25df, 0x3000 }, + { 0x9a00, 0x25dd, 0x2000 }, + { 0x1a00, 0x25dc, 0x0000 }, + { 0x1a00, 0x25de, 0x0000 }, + { 0x9a00, 0x25e1, 0x2000 }, + { 0x1a00, 0x25e0, 0x0000 }, + { 0x1a00, 0x25e2, 0x0000 }, + { 0x9a00, 0x25e7, 0x3000 }, + { 0x9a00, 0x25e5, 0x2000 }, + { 0x1a00, 0x25e4, 0x0000 }, + { 0x1a00, 0x25e6, 0x0000 }, + { 0x9a00, 0x25e9, 0x2000 }, + { 0x1a00, 0x25e8, 0x0000 }, + { 0x1a00, 0x25ea, 0x0000 }, + { 0x9900, 0x25fb, 0x5000 }, + { 0x9a00, 0x25f3, 0x4000 }, + { 0x9a00, 0x25ef, 0x3000 }, + { 0x9a00, 0x25ed, 0x2000 }, + { 0x1a00, 0x25ec, 0x0000 }, + { 0x1a00, 0x25ee, 0x0000 }, + { 0x9a00, 0x25f1, 0x2000 }, + { 0x1a00, 0x25f0, 0x0000 }, + { 0x1a00, 0x25f2, 0x0000 }, + { 0x9a00, 0x25f7, 0x3000 }, + { 0x9a00, 0x25f5, 0x2000 }, + { 0x1a00, 0x25f4, 0x0000 }, + { 0x1a00, 0x25f6, 0x0000 }, + { 0x9900, 0x25f9, 0x2000 }, + { 0x1900, 0x25f8, 0x0000 }, + { 0x1900, 0x25fa, 0x0000 }, + { 0x9a00, 0x2603, 0x4000 }, + { 0x9900, 0x25ff, 0x3000 }, + { 0x9900, 0x25fd, 0x2000 }, + { 0x1900, 0x25fc, 0x0000 }, + { 0x1900, 0x25fe, 0x0000 }, + { 0x9a00, 0x2601, 0x2000 }, + { 0x1a00, 0x2600, 0x0000 }, + { 0x1a00, 0x2602, 0x0000 }, + { 0x9a00, 0x2607, 0x3000 }, + { 0x9a00, 0x2605, 0x2000 }, + { 0x1a00, 0x2604, 0x0000 }, + { 0x1a00, 0x2606, 0x0000 }, + { 0x9a00, 0x2609, 0x2000 }, + { 0x1a00, 0x2608, 0x0000 }, + { 0x1a00, 0x260a, 0x0000 }, + { 0x9a00, 0x268e, 0x8000 }, + { 0x9a00, 0x264c, 0x7000 }, + { 0x9a00, 0x262c, 0x6000 }, + { 0x9a00, 0x261c, 0x5000 }, + { 0x9a00, 0x2613, 0x4000 }, + { 0x9a00, 0x260f, 0x3000 }, + { 0x9a00, 0x260d, 0x2000 }, + { 0x1a00, 0x260c, 0x0000 }, + { 0x1a00, 0x260e, 0x0000 }, + { 0x9a00, 0x2611, 0x2000 }, + { 0x1a00, 0x2610, 0x0000 }, + { 0x1a00, 0x2612, 0x0000 }, + { 0x9a00, 0x2617, 0x3000 }, + { 0x9a00, 0x2615, 0x2000 }, + { 0x1a00, 0x2614, 0x0000 }, + { 0x1a00, 0x2616, 0x0000 }, + { 0x9a00, 0x261a, 0x2000 }, + { 0x1a00, 0x2619, 0x0000 }, + { 0x1a00, 0x261b, 0x0000 }, + { 0x9a00, 0x2624, 0x4000 }, + { 0x9a00, 0x2620, 0x3000 }, + { 0x9a00, 0x261e, 0x2000 }, + { 0x1a00, 0x261d, 0x0000 }, + { 0x1a00, 0x261f, 0x0000 }, + { 0x9a00, 0x2622, 0x2000 }, + { 0x1a00, 0x2621, 0x0000 }, + { 0x1a00, 0x2623, 0x0000 }, + { 0x9a00, 0x2628, 0x3000 }, + { 0x9a00, 0x2626, 0x2000 }, + { 0x1a00, 0x2625, 0x0000 }, + { 0x1a00, 0x2627, 0x0000 }, + { 0x9a00, 0x262a, 0x2000 }, + { 0x1a00, 0x2629, 0x0000 }, + { 0x1a00, 0x262b, 0x0000 }, + { 0x9a00, 0x263c, 0x5000 }, + { 0x9a00, 0x2634, 0x4000 }, + { 0x9a00, 0x2630, 0x3000 }, + { 0x9a00, 0x262e, 0x2000 }, + { 0x1a00, 0x262d, 0x0000 }, + { 0x1a00, 0x262f, 0x0000 }, + { 0x9a00, 0x2632, 0x2000 }, + { 0x1a00, 0x2631, 0x0000 }, + { 0x1a00, 0x2633, 0x0000 }, + { 0x9a00, 0x2638, 0x3000 }, + { 0x9a00, 0x2636, 0x2000 }, + { 0x1a00, 0x2635, 0x0000 }, + { 0x1a00, 0x2637, 0x0000 }, + { 0x9a00, 0x263a, 0x2000 }, + { 0x1a00, 0x2639, 0x0000 }, + { 0x1a00, 0x263b, 0x0000 }, + { 0x9a00, 0x2644, 0x4000 }, + { 0x9a00, 0x2640, 0x3000 }, + { 0x9a00, 0x263e, 0x2000 }, + { 0x1a00, 0x263d, 0x0000 }, + { 0x1a00, 0x263f, 0x0000 }, + { 0x9a00, 0x2642, 0x2000 }, + { 0x1a00, 0x2641, 0x0000 }, + { 0x1a00, 0x2643, 0x0000 }, + { 0x9a00, 0x2648, 0x3000 }, + { 0x9a00, 0x2646, 0x2000 }, + { 0x1a00, 0x2645, 0x0000 }, + { 0x1a00, 0x2647, 0x0000 }, + { 0x9a00, 0x264a, 0x2000 }, + { 0x1a00, 0x2649, 0x0000 }, + { 0x1a00, 0x264b, 0x0000 }, + { 0x9a00, 0x266c, 0x6000 }, + { 0x9a00, 0x265c, 0x5000 }, + { 0x9a00, 0x2654, 0x4000 }, + { 0x9a00, 0x2650, 0x3000 }, + { 0x9a00, 0x264e, 0x2000 }, + { 0x1a00, 0x264d, 0x0000 }, + { 0x1a00, 0x264f, 0x0000 }, + { 0x9a00, 0x2652, 0x2000 }, + { 0x1a00, 0x2651, 0x0000 }, + { 0x1a00, 0x2653, 0x0000 }, + { 0x9a00, 0x2658, 0x3000 }, + { 0x9a00, 0x2656, 0x2000 }, + { 0x1a00, 0x2655, 0x0000 }, + { 0x1a00, 0x2657, 0x0000 }, + { 0x9a00, 0x265a, 0x2000 }, + { 0x1a00, 0x2659, 0x0000 }, + { 0x1a00, 0x265b, 0x0000 }, + { 0x9a00, 0x2664, 0x4000 }, + { 0x9a00, 0x2660, 0x3000 }, + { 0x9a00, 0x265e, 0x2000 }, + { 0x1a00, 0x265d, 0x0000 }, + { 0x1a00, 0x265f, 0x0000 }, + { 0x9a00, 0x2662, 0x2000 }, + { 0x1a00, 0x2661, 0x0000 }, + { 0x1a00, 0x2663, 0x0000 }, + { 0x9a00, 0x2668, 0x3000 }, + { 0x9a00, 0x2666, 0x2000 }, + { 0x1a00, 0x2665, 0x0000 }, + { 0x1a00, 0x2667, 0x0000 }, + { 0x9a00, 0x266a, 0x2000 }, + { 0x1a00, 0x2669, 0x0000 }, + { 0x1a00, 0x266b, 0x0000 }, + { 0x9a00, 0x267c, 0x5000 }, + { 0x9a00, 0x2674, 0x4000 }, + { 0x9a00, 0x2670, 0x3000 }, + { 0x9a00, 0x266e, 0x2000 }, + { 0x1a00, 0x266d, 0x0000 }, + { 0x1900, 0x266f, 0x0000 }, + { 0x9a00, 0x2672, 0x2000 }, + { 0x1a00, 0x2671, 0x0000 }, + { 0x1a00, 0x2673, 0x0000 }, + { 0x9a00, 0x2678, 0x3000 }, + { 0x9a00, 0x2676, 0x2000 }, + { 0x1a00, 0x2675, 0x0000 }, + { 0x1a00, 0x2677, 0x0000 }, + { 0x9a00, 0x267a, 0x2000 }, + { 0x1a00, 0x2679, 0x0000 }, + { 0x1a00, 0x267b, 0x0000 }, + { 0x9a00, 0x2686, 0x4000 }, + { 0x9a00, 0x2682, 0x3000 }, + { 0x9a00, 0x2680, 0x2000 }, + { 0x1a00, 0x267d, 0x0000 }, + { 0x1a00, 0x2681, 0x0000 }, + { 0x9a00, 0x2684, 0x2000 }, + { 0x1a00, 0x2683, 0x0000 }, + { 0x1a00, 0x2685, 0x0000 }, + { 0x9a00, 0x268a, 0x3000 }, + { 0x9a00, 0x2688, 0x2000 }, + { 0x1a00, 0x2687, 0x0000 }, + { 0x1a00, 0x2689, 0x0000 }, + { 0x9a00, 0x268c, 0x2000 }, + { 0x1a00, 0x268b, 0x0000 }, + { 0x1a00, 0x268d, 0x0000 }, + { 0x9a00, 0x273f, 0x7000 }, + { 0x9a00, 0x271e, 0x6000 }, + { 0x9a00, 0x270e, 0x5000 }, + { 0x9a00, 0x2703, 0x4000 }, + { 0x9a00, 0x26a0, 0x3000 }, + { 0x9a00, 0x2690, 0x2000 }, + { 0x1a00, 0x268f, 0x0000 }, + { 0x1a00, 0x2691, 0x0000 }, + { 0x9a00, 0x2701, 0x2000 }, + { 0x1a00, 0x26a1, 0x0000 }, + { 0x1a00, 0x2702, 0x0000 }, + { 0x9a00, 0x2708, 0x3000 }, + { 0x9a00, 0x2706, 0x2000 }, + { 0x1a00, 0x2704, 0x0000 }, + { 0x1a00, 0x2707, 0x0000 }, + { 0x9a00, 0x270c, 0x2000 }, + { 0x1a00, 0x2709, 0x0000 }, + { 0x1a00, 0x270d, 0x0000 }, + { 0x9a00, 0x2716, 0x4000 }, + { 0x9a00, 0x2712, 0x3000 }, + { 0x9a00, 0x2710, 0x2000 }, + { 0x1a00, 0x270f, 0x0000 }, + { 0x1a00, 0x2711, 0x0000 }, + { 0x9a00, 0x2714, 0x2000 }, + { 0x1a00, 0x2713, 0x0000 }, + { 0x1a00, 0x2715, 0x0000 }, + { 0x9a00, 0x271a, 0x3000 }, + { 0x9a00, 0x2718, 0x2000 }, + { 0x1a00, 0x2717, 0x0000 }, + { 0x1a00, 0x2719, 0x0000 }, + { 0x9a00, 0x271c, 0x2000 }, + { 0x1a00, 0x271b, 0x0000 }, + { 0x1a00, 0x271d, 0x0000 }, + { 0x9a00, 0x272f, 0x5000 }, + { 0x9a00, 0x2726, 0x4000 }, + { 0x9a00, 0x2722, 0x3000 }, + { 0x9a00, 0x2720, 0x2000 }, + { 0x1a00, 0x271f, 0x0000 }, + { 0x1a00, 0x2721, 0x0000 }, + { 0x9a00, 0x2724, 0x2000 }, + { 0x1a00, 0x2723, 0x0000 }, + { 0x1a00, 0x2725, 0x0000 }, + { 0x9a00, 0x272b, 0x3000 }, + { 0x9a00, 0x2729, 0x2000 }, + { 0x1a00, 0x2727, 0x0000 }, + { 0x1a00, 0x272a, 0x0000 }, + { 0x9a00, 0x272d, 0x2000 }, + { 0x1a00, 0x272c, 0x0000 }, + { 0x1a00, 0x272e, 0x0000 }, + { 0x9a00, 0x2737, 0x4000 }, + { 0x9a00, 0x2733, 0x3000 }, + { 0x9a00, 0x2731, 0x2000 }, + { 0x1a00, 0x2730, 0x0000 }, + { 0x1a00, 0x2732, 0x0000 }, + { 0x9a00, 0x2735, 0x2000 }, + { 0x1a00, 0x2734, 0x0000 }, + { 0x1a00, 0x2736, 0x0000 }, + { 0x9a00, 0x273b, 0x3000 }, + { 0x9a00, 0x2739, 0x2000 }, + { 0x1a00, 0x2738, 0x0000 }, + { 0x1a00, 0x273a, 0x0000 }, + { 0x9a00, 0x273d, 0x2000 }, + { 0x1a00, 0x273c, 0x0000 }, + { 0x1a00, 0x273e, 0x0000 }, + { 0x9a00, 0x2767, 0x6000 }, + { 0x9a00, 0x2751, 0x5000 }, + { 0x9a00, 0x2747, 0x4000 }, + { 0x9a00, 0x2743, 0x3000 }, + { 0x9a00, 0x2741, 0x2000 }, + { 0x1a00, 0x2740, 0x0000 }, + { 0x1a00, 0x2742, 0x0000 }, + { 0x9a00, 0x2745, 0x2000 }, + { 0x1a00, 0x2744, 0x0000 }, + { 0x1a00, 0x2746, 0x0000 }, + { 0x9a00, 0x274b, 0x3000 }, + { 0x9a00, 0x2749, 0x2000 }, + { 0x1a00, 0x2748, 0x0000 }, + { 0x1a00, 0x274a, 0x0000 }, + { 0x9a00, 0x274f, 0x2000 }, + { 0x1a00, 0x274d, 0x0000 }, + { 0x1a00, 0x2750, 0x0000 }, + { 0x9a00, 0x275d, 0x4000 }, + { 0x9a00, 0x2759, 0x3000 }, + { 0x9a00, 0x2756, 0x2000 }, + { 0x1a00, 0x2752, 0x0000 }, + { 0x1a00, 0x2758, 0x0000 }, + { 0x9a00, 0x275b, 0x2000 }, + { 0x1a00, 0x275a, 0x0000 }, + { 0x1a00, 0x275c, 0x0000 }, + { 0x9a00, 0x2763, 0x3000 }, + { 0x9a00, 0x2761, 0x2000 }, + { 0x1a00, 0x275e, 0x0000 }, + { 0x1a00, 0x2762, 0x0000 }, + { 0x9a00, 0x2765, 0x2000 }, + { 0x1a00, 0x2764, 0x0000 }, + { 0x1a00, 0x2766, 0x0000 }, + { 0x8f00, 0x2777, 0x5000 }, + { 0x9200, 0x276f, 0x4000 }, + { 0x9200, 0x276b, 0x3000 }, + { 0x9200, 0x2769, 0x2000 }, + { 0x1600, 0x2768, 0x0000 }, + { 0x1600, 0x276a, 0x0000 }, + { 0x9200, 0x276d, 0x2000 }, + { 0x1600, 0x276c, 0x0000 }, + { 0x1600, 0x276e, 0x0000 }, + { 0x9200, 0x2773, 0x3000 }, + { 0x9200, 0x2771, 0x2000 }, + { 0x1600, 0x2770, 0x0000 }, + { 0x1600, 0x2772, 0x0000 }, + { 0x9200, 0x2775, 0x2000 }, + { 0x1600, 0x2774, 0x0000 }, + { 0x0f00, 0x2776, 0x0000 }, + { 0x8f00, 0x277f, 0x4000 }, + { 0x8f00, 0x277b, 0x3000 }, + { 0x8f00, 0x2779, 0x2000 }, + { 0x0f00, 0x2778, 0x0000 }, + { 0x0f00, 0x277a, 0x0000 }, + { 0x8f00, 0x277d, 0x2000 }, + { 0x0f00, 0x277c, 0x0000 }, + { 0x0f00, 0x277e, 0x0000 }, + { 0x8f00, 0x2783, 0x3000 }, + { 0x8f00, 0x2781, 0x2000 }, + { 0x0f00, 0x2780, 0x0000 }, + { 0x0f00, 0x2782, 0x0000 }, + { 0x8f00, 0x2785, 0x2000 }, + { 0x0f00, 0x2784, 0x0000 }, + { 0x0f00, 0x2786, 0x0000 }, + { 0x9900, 0x29a0, 0xa000 }, + { 0x9a00, 0x28a0, 0x9000 }, + { 0x9a00, 0x2820, 0x8000 }, + { 0x9900, 0x27dc, 0x7000 }, + { 0x9a00, 0x27aa, 0x6000 }, + { 0x9a00, 0x279a, 0x5000 }, + { 0x8f00, 0x278f, 0x4000 }, + { 0x8f00, 0x278b, 0x3000 }, + { 0x8f00, 0x2789, 0x2000 }, + { 0x0f00, 0x2788, 0x0000 }, + { 0x0f00, 0x278a, 0x0000 }, + { 0x8f00, 0x278d, 0x2000 }, + { 0x0f00, 0x278c, 0x0000 }, + { 0x0f00, 0x278e, 0x0000 }, + { 0x8f00, 0x2793, 0x3000 }, + { 0x8f00, 0x2791, 0x2000 }, + { 0x0f00, 0x2790, 0x0000 }, + { 0x0f00, 0x2792, 0x0000 }, + { 0x9a00, 0x2798, 0x2000 }, + { 0x1a00, 0x2794, 0x0000 }, + { 0x1a00, 0x2799, 0x0000 }, + { 0x9a00, 0x27a2, 0x4000 }, + { 0x9a00, 0x279e, 0x3000 }, + { 0x9a00, 0x279c, 0x2000 }, + { 0x1a00, 0x279b, 0x0000 }, + { 0x1a00, 0x279d, 0x0000 }, + { 0x9a00, 0x27a0, 0x2000 }, + { 0x1a00, 0x279f, 0x0000 }, + { 0x1a00, 0x27a1, 0x0000 }, + { 0x9a00, 0x27a6, 0x3000 }, + { 0x9a00, 0x27a4, 0x2000 }, + { 0x1a00, 0x27a3, 0x0000 }, + { 0x1a00, 0x27a5, 0x0000 }, + { 0x9a00, 0x27a8, 0x2000 }, + { 0x1a00, 0x27a7, 0x0000 }, + { 0x1a00, 0x27a9, 0x0000 }, + { 0x9a00, 0x27bb, 0x5000 }, + { 0x9a00, 0x27b3, 0x4000 }, + { 0x9a00, 0x27ae, 0x3000 }, + { 0x9a00, 0x27ac, 0x2000 }, + { 0x1a00, 0x27ab, 0x0000 }, + { 0x1a00, 0x27ad, 0x0000 }, + { 0x9a00, 0x27b1, 0x2000 }, + { 0x1a00, 0x27af, 0x0000 }, + { 0x1a00, 0x27b2, 0x0000 }, + { 0x9a00, 0x27b7, 0x3000 }, + { 0x9a00, 0x27b5, 0x2000 }, + { 0x1a00, 0x27b4, 0x0000 }, + { 0x1a00, 0x27b6, 0x0000 }, + { 0x9a00, 0x27b9, 0x2000 }, + { 0x1a00, 0x27b8, 0x0000 }, + { 0x1a00, 0x27ba, 0x0000 }, + { 0x9900, 0x27d4, 0x4000 }, + { 0x9900, 0x27d0, 0x3000 }, + { 0x9a00, 0x27bd, 0x2000 }, + { 0x1a00, 0x27bc, 0x0000 }, + { 0x1a00, 0x27be, 0x0000 }, + { 0x9900, 0x27d2, 0x2000 }, + { 0x1900, 0x27d1, 0x0000 }, + { 0x1900, 0x27d3, 0x0000 }, + { 0x9900, 0x27d8, 0x3000 }, + { 0x9900, 0x27d6, 0x2000 }, + { 0x1900, 0x27d5, 0x0000 }, + { 0x1900, 0x27d7, 0x0000 }, + { 0x9900, 0x27da, 0x2000 }, + { 0x1900, 0x27d9, 0x0000 }, + { 0x1900, 0x27db, 0x0000 }, + { 0x9a00, 0x2800, 0x6000 }, + { 0x9900, 0x27f0, 0x5000 }, + { 0x9900, 0x27e4, 0x4000 }, + { 0x9900, 0x27e0, 0x3000 }, + { 0x9900, 0x27de, 0x2000 }, + { 0x1900, 0x27dd, 0x0000 }, + { 0x1900, 0x27df, 0x0000 }, + { 0x9900, 0x27e2, 0x2000 }, + { 0x1900, 0x27e1, 0x0000 }, + { 0x1900, 0x27e3, 0x0000 }, + { 0x9600, 0x27e8, 0x3000 }, + { 0x9600, 0x27e6, 0x2000 }, + { 0x1900, 0x27e5, 0x0000 }, + { 0x1200, 0x27e7, 0x0000 }, + { 0x9600, 0x27ea, 0x2000 }, + { 0x1200, 0x27e9, 0x0000 }, + { 0x1200, 0x27eb, 0x0000 }, + { 0x9900, 0x27f8, 0x4000 }, + { 0x9900, 0x27f4, 0x3000 }, + { 0x9900, 0x27f2, 0x2000 }, + { 0x1900, 0x27f1, 0x0000 }, + { 0x1900, 0x27f3, 0x0000 }, + { 0x9900, 0x27f6, 0x2000 }, + { 0x1900, 0x27f5, 0x0000 }, + { 0x1900, 0x27f7, 0x0000 }, + { 0x9900, 0x27fc, 0x3000 }, + { 0x9900, 0x27fa, 0x2000 }, + { 0x1900, 0x27f9, 0x0000 }, + { 0x1900, 0x27fb, 0x0000 }, + { 0x9900, 0x27fe, 0x2000 }, + { 0x1900, 0x27fd, 0x0000 }, + { 0x1900, 0x27ff, 0x0000 }, + { 0x9a00, 0x2810, 0x5000 }, + { 0x9a00, 0x2808, 0x4000 }, + { 0x9a00, 0x2804, 0x3000 }, + { 0x9a00, 0x2802, 0x2000 }, + { 0x1a00, 0x2801, 0x0000 }, + { 0x1a00, 0x2803, 0x0000 }, + { 0x9a00, 0x2806, 0x2000 }, + { 0x1a00, 0x2805, 0x0000 }, + { 0x1a00, 0x2807, 0x0000 }, + { 0x9a00, 0x280c, 0x3000 }, + { 0x9a00, 0x280a, 0x2000 }, + { 0x1a00, 0x2809, 0x0000 }, + { 0x1a00, 0x280b, 0x0000 }, + { 0x9a00, 0x280e, 0x2000 }, + { 0x1a00, 0x280d, 0x0000 }, + { 0x1a00, 0x280f, 0x0000 }, + { 0x9a00, 0x2818, 0x4000 }, + { 0x9a00, 0x2814, 0x3000 }, + { 0x9a00, 0x2812, 0x2000 }, + { 0x1a00, 0x2811, 0x0000 }, + { 0x1a00, 0x2813, 0x0000 }, + { 0x9a00, 0x2816, 0x2000 }, + { 0x1a00, 0x2815, 0x0000 }, + { 0x1a00, 0x2817, 0x0000 }, + { 0x9a00, 0x281c, 0x3000 }, + { 0x9a00, 0x281a, 0x2000 }, + { 0x1a00, 0x2819, 0x0000 }, + { 0x1a00, 0x281b, 0x0000 }, + { 0x9a00, 0x281e, 0x2000 }, + { 0x1a00, 0x281d, 0x0000 }, + { 0x1a00, 0x281f, 0x0000 }, + { 0x9a00, 0x2860, 0x7000 }, + { 0x9a00, 0x2840, 0x6000 }, + { 0x9a00, 0x2830, 0x5000 }, + { 0x9a00, 0x2828, 0x4000 }, + { 0x9a00, 0x2824, 0x3000 }, + { 0x9a00, 0x2822, 0x2000 }, + { 0x1a00, 0x2821, 0x0000 }, + { 0x1a00, 0x2823, 0x0000 }, + { 0x9a00, 0x2826, 0x2000 }, + { 0x1a00, 0x2825, 0x0000 }, + { 0x1a00, 0x2827, 0x0000 }, + { 0x9a00, 0x282c, 0x3000 }, + { 0x9a00, 0x282a, 0x2000 }, + { 0x1a00, 0x2829, 0x0000 }, + { 0x1a00, 0x282b, 0x0000 }, + { 0x9a00, 0x282e, 0x2000 }, + { 0x1a00, 0x282d, 0x0000 }, + { 0x1a00, 0x282f, 0x0000 }, + { 0x9a00, 0x2838, 0x4000 }, + { 0x9a00, 0x2834, 0x3000 }, + { 0x9a00, 0x2832, 0x2000 }, + { 0x1a00, 0x2831, 0x0000 }, + { 0x1a00, 0x2833, 0x0000 }, + { 0x9a00, 0x2836, 0x2000 }, + { 0x1a00, 0x2835, 0x0000 }, + { 0x1a00, 0x2837, 0x0000 }, + { 0x9a00, 0x283c, 0x3000 }, + { 0x9a00, 0x283a, 0x2000 }, + { 0x1a00, 0x2839, 0x0000 }, + { 0x1a00, 0x283b, 0x0000 }, + { 0x9a00, 0x283e, 0x2000 }, + { 0x1a00, 0x283d, 0x0000 }, + { 0x1a00, 0x283f, 0x0000 }, + { 0x9a00, 0x2850, 0x5000 }, + { 0x9a00, 0x2848, 0x4000 }, + { 0x9a00, 0x2844, 0x3000 }, + { 0x9a00, 0x2842, 0x2000 }, + { 0x1a00, 0x2841, 0x0000 }, + { 0x1a00, 0x2843, 0x0000 }, + { 0x9a00, 0x2846, 0x2000 }, + { 0x1a00, 0x2845, 0x0000 }, + { 0x1a00, 0x2847, 0x0000 }, + { 0x9a00, 0x284c, 0x3000 }, + { 0x9a00, 0x284a, 0x2000 }, + { 0x1a00, 0x2849, 0x0000 }, + { 0x1a00, 0x284b, 0x0000 }, + { 0x9a00, 0x284e, 0x2000 }, + { 0x1a00, 0x284d, 0x0000 }, + { 0x1a00, 0x284f, 0x0000 }, + { 0x9a00, 0x2858, 0x4000 }, + { 0x9a00, 0x2854, 0x3000 }, + { 0x9a00, 0x2852, 0x2000 }, + { 0x1a00, 0x2851, 0x0000 }, + { 0x1a00, 0x2853, 0x0000 }, + { 0x9a00, 0x2856, 0x2000 }, + { 0x1a00, 0x2855, 0x0000 }, + { 0x1a00, 0x2857, 0x0000 }, + { 0x9a00, 0x285c, 0x3000 }, + { 0x9a00, 0x285a, 0x2000 }, + { 0x1a00, 0x2859, 0x0000 }, + { 0x1a00, 0x285b, 0x0000 }, + { 0x9a00, 0x285e, 0x2000 }, + { 0x1a00, 0x285d, 0x0000 }, + { 0x1a00, 0x285f, 0x0000 }, + { 0x9a00, 0x2880, 0x6000 }, + { 0x9a00, 0x2870, 0x5000 }, + { 0x9a00, 0x2868, 0x4000 }, + { 0x9a00, 0x2864, 0x3000 }, + { 0x9a00, 0x2862, 0x2000 }, + { 0x1a00, 0x2861, 0x0000 }, + { 0x1a00, 0x2863, 0x0000 }, + { 0x9a00, 0x2866, 0x2000 }, + { 0x1a00, 0x2865, 0x0000 }, + { 0x1a00, 0x2867, 0x0000 }, + { 0x9a00, 0x286c, 0x3000 }, + { 0x9a00, 0x286a, 0x2000 }, + { 0x1a00, 0x2869, 0x0000 }, + { 0x1a00, 0x286b, 0x0000 }, + { 0x9a00, 0x286e, 0x2000 }, + { 0x1a00, 0x286d, 0x0000 }, + { 0x1a00, 0x286f, 0x0000 }, + { 0x9a00, 0x2878, 0x4000 }, + { 0x9a00, 0x2874, 0x3000 }, + { 0x9a00, 0x2872, 0x2000 }, + { 0x1a00, 0x2871, 0x0000 }, + { 0x1a00, 0x2873, 0x0000 }, + { 0x9a00, 0x2876, 0x2000 }, + { 0x1a00, 0x2875, 0x0000 }, + { 0x1a00, 0x2877, 0x0000 }, + { 0x9a00, 0x287c, 0x3000 }, + { 0x9a00, 0x287a, 0x2000 }, + { 0x1a00, 0x2879, 0x0000 }, + { 0x1a00, 0x287b, 0x0000 }, + { 0x9a00, 0x287e, 0x2000 }, + { 0x1a00, 0x287d, 0x0000 }, + { 0x1a00, 0x287f, 0x0000 }, + { 0x9a00, 0x2890, 0x5000 }, + { 0x9a00, 0x2888, 0x4000 }, + { 0x9a00, 0x2884, 0x3000 }, + { 0x9a00, 0x2882, 0x2000 }, + { 0x1a00, 0x2881, 0x0000 }, + { 0x1a00, 0x2883, 0x0000 }, + { 0x9a00, 0x2886, 0x2000 }, + { 0x1a00, 0x2885, 0x0000 }, + { 0x1a00, 0x2887, 0x0000 }, + { 0x9a00, 0x288c, 0x3000 }, + { 0x9a00, 0x288a, 0x2000 }, + { 0x1a00, 0x2889, 0x0000 }, + { 0x1a00, 0x288b, 0x0000 }, + { 0x9a00, 0x288e, 0x2000 }, + { 0x1a00, 0x288d, 0x0000 }, + { 0x1a00, 0x288f, 0x0000 }, + { 0x9a00, 0x2898, 0x4000 }, + { 0x9a00, 0x2894, 0x3000 }, + { 0x9a00, 0x2892, 0x2000 }, + { 0x1a00, 0x2891, 0x0000 }, + { 0x1a00, 0x2893, 0x0000 }, + { 0x9a00, 0x2896, 0x2000 }, + { 0x1a00, 0x2895, 0x0000 }, + { 0x1a00, 0x2897, 0x0000 }, + { 0x9a00, 0x289c, 0x3000 }, + { 0x9a00, 0x289a, 0x2000 }, + { 0x1a00, 0x2899, 0x0000 }, + { 0x1a00, 0x289b, 0x0000 }, + { 0x9a00, 0x289e, 0x2000 }, + { 0x1a00, 0x289d, 0x0000 }, + { 0x1a00, 0x289f, 0x0000 }, + { 0x9900, 0x2920, 0x8000 }, + { 0x9a00, 0x28e0, 0x7000 }, + { 0x9a00, 0x28c0, 0x6000 }, + { 0x9a00, 0x28b0, 0x5000 }, + { 0x9a00, 0x28a8, 0x4000 }, + { 0x9a00, 0x28a4, 0x3000 }, + { 0x9a00, 0x28a2, 0x2000 }, + { 0x1a00, 0x28a1, 0x0000 }, + { 0x1a00, 0x28a3, 0x0000 }, + { 0x9a00, 0x28a6, 0x2000 }, + { 0x1a00, 0x28a5, 0x0000 }, + { 0x1a00, 0x28a7, 0x0000 }, + { 0x9a00, 0x28ac, 0x3000 }, + { 0x9a00, 0x28aa, 0x2000 }, + { 0x1a00, 0x28a9, 0x0000 }, + { 0x1a00, 0x28ab, 0x0000 }, + { 0x9a00, 0x28ae, 0x2000 }, + { 0x1a00, 0x28ad, 0x0000 }, + { 0x1a00, 0x28af, 0x0000 }, + { 0x9a00, 0x28b8, 0x4000 }, + { 0x9a00, 0x28b4, 0x3000 }, + { 0x9a00, 0x28b2, 0x2000 }, + { 0x1a00, 0x28b1, 0x0000 }, + { 0x1a00, 0x28b3, 0x0000 }, + { 0x9a00, 0x28b6, 0x2000 }, + { 0x1a00, 0x28b5, 0x0000 }, + { 0x1a00, 0x28b7, 0x0000 }, + { 0x9a00, 0x28bc, 0x3000 }, + { 0x9a00, 0x28ba, 0x2000 }, + { 0x1a00, 0x28b9, 0x0000 }, + { 0x1a00, 0x28bb, 0x0000 }, + { 0x9a00, 0x28be, 0x2000 }, + { 0x1a00, 0x28bd, 0x0000 }, + { 0x1a00, 0x28bf, 0x0000 }, + { 0x9a00, 0x28d0, 0x5000 }, + { 0x9a00, 0x28c8, 0x4000 }, + { 0x9a00, 0x28c4, 0x3000 }, + { 0x9a00, 0x28c2, 0x2000 }, + { 0x1a00, 0x28c1, 0x0000 }, + { 0x1a00, 0x28c3, 0x0000 }, + { 0x9a00, 0x28c6, 0x2000 }, + { 0x1a00, 0x28c5, 0x0000 }, + { 0x1a00, 0x28c7, 0x0000 }, + { 0x9a00, 0x28cc, 0x3000 }, + { 0x9a00, 0x28ca, 0x2000 }, + { 0x1a00, 0x28c9, 0x0000 }, + { 0x1a00, 0x28cb, 0x0000 }, + { 0x9a00, 0x28ce, 0x2000 }, + { 0x1a00, 0x28cd, 0x0000 }, + { 0x1a00, 0x28cf, 0x0000 }, + { 0x9a00, 0x28d8, 0x4000 }, + { 0x9a00, 0x28d4, 0x3000 }, + { 0x9a00, 0x28d2, 0x2000 }, + { 0x1a00, 0x28d1, 0x0000 }, + { 0x1a00, 0x28d3, 0x0000 }, + { 0x9a00, 0x28d6, 0x2000 }, + { 0x1a00, 0x28d5, 0x0000 }, + { 0x1a00, 0x28d7, 0x0000 }, + { 0x9a00, 0x28dc, 0x3000 }, + { 0x9a00, 0x28da, 0x2000 }, + { 0x1a00, 0x28d9, 0x0000 }, + { 0x1a00, 0x28db, 0x0000 }, + { 0x9a00, 0x28de, 0x2000 }, + { 0x1a00, 0x28dd, 0x0000 }, + { 0x1a00, 0x28df, 0x0000 }, + { 0x9900, 0x2900, 0x6000 }, + { 0x9a00, 0x28f0, 0x5000 }, + { 0x9a00, 0x28e8, 0x4000 }, + { 0x9a00, 0x28e4, 0x3000 }, + { 0x9a00, 0x28e2, 0x2000 }, + { 0x1a00, 0x28e1, 0x0000 }, + { 0x1a00, 0x28e3, 0x0000 }, + { 0x9a00, 0x28e6, 0x2000 }, + { 0x1a00, 0x28e5, 0x0000 }, + { 0x1a00, 0x28e7, 0x0000 }, + { 0x9a00, 0x28ec, 0x3000 }, + { 0x9a00, 0x28ea, 0x2000 }, + { 0x1a00, 0x28e9, 0x0000 }, + { 0x1a00, 0x28eb, 0x0000 }, + { 0x9a00, 0x28ee, 0x2000 }, + { 0x1a00, 0x28ed, 0x0000 }, + { 0x1a00, 0x28ef, 0x0000 }, + { 0x9a00, 0x28f8, 0x4000 }, + { 0x9a00, 0x28f4, 0x3000 }, + { 0x9a00, 0x28f2, 0x2000 }, + { 0x1a00, 0x28f1, 0x0000 }, + { 0x1a00, 0x28f3, 0x0000 }, + { 0x9a00, 0x28f6, 0x2000 }, + { 0x1a00, 0x28f5, 0x0000 }, + { 0x1a00, 0x28f7, 0x0000 }, + { 0x9a00, 0x28fc, 0x3000 }, + { 0x9a00, 0x28fa, 0x2000 }, + { 0x1a00, 0x28f9, 0x0000 }, + { 0x1a00, 0x28fb, 0x0000 }, + { 0x9a00, 0x28fe, 0x2000 }, + { 0x1a00, 0x28fd, 0x0000 }, + { 0x1a00, 0x28ff, 0x0000 }, + { 0x9900, 0x2910, 0x5000 }, + { 0x9900, 0x2908, 0x4000 }, + { 0x9900, 0x2904, 0x3000 }, + { 0x9900, 0x2902, 0x2000 }, + { 0x1900, 0x2901, 0x0000 }, + { 0x1900, 0x2903, 0x0000 }, + { 0x9900, 0x2906, 0x2000 }, + { 0x1900, 0x2905, 0x0000 }, + { 0x1900, 0x2907, 0x0000 }, + { 0x9900, 0x290c, 0x3000 }, + { 0x9900, 0x290a, 0x2000 }, + { 0x1900, 0x2909, 0x0000 }, + { 0x1900, 0x290b, 0x0000 }, + { 0x9900, 0x290e, 0x2000 }, + { 0x1900, 0x290d, 0x0000 }, + { 0x1900, 0x290f, 0x0000 }, + { 0x9900, 0x2918, 0x4000 }, + { 0x9900, 0x2914, 0x3000 }, + { 0x9900, 0x2912, 0x2000 }, + { 0x1900, 0x2911, 0x0000 }, + { 0x1900, 0x2913, 0x0000 }, + { 0x9900, 0x2916, 0x2000 }, + { 0x1900, 0x2915, 0x0000 }, + { 0x1900, 0x2917, 0x0000 }, + { 0x9900, 0x291c, 0x3000 }, + { 0x9900, 0x291a, 0x2000 }, + { 0x1900, 0x2919, 0x0000 }, + { 0x1900, 0x291b, 0x0000 }, + { 0x9900, 0x291e, 0x2000 }, + { 0x1900, 0x291d, 0x0000 }, + { 0x1900, 0x291f, 0x0000 }, + { 0x9900, 0x2960, 0x7000 }, + { 0x9900, 0x2940, 0x6000 }, + { 0x9900, 0x2930, 0x5000 }, + { 0x9900, 0x2928, 0x4000 }, + { 0x9900, 0x2924, 0x3000 }, + { 0x9900, 0x2922, 0x2000 }, + { 0x1900, 0x2921, 0x0000 }, + { 0x1900, 0x2923, 0x0000 }, + { 0x9900, 0x2926, 0x2000 }, + { 0x1900, 0x2925, 0x0000 }, + { 0x1900, 0x2927, 0x0000 }, + { 0x9900, 0x292c, 0x3000 }, + { 0x9900, 0x292a, 0x2000 }, + { 0x1900, 0x2929, 0x0000 }, + { 0x1900, 0x292b, 0x0000 }, + { 0x9900, 0x292e, 0x2000 }, + { 0x1900, 0x292d, 0x0000 }, + { 0x1900, 0x292f, 0x0000 }, + { 0x9900, 0x2938, 0x4000 }, + { 0x9900, 0x2934, 0x3000 }, + { 0x9900, 0x2932, 0x2000 }, + { 0x1900, 0x2931, 0x0000 }, + { 0x1900, 0x2933, 0x0000 }, + { 0x9900, 0x2936, 0x2000 }, + { 0x1900, 0x2935, 0x0000 }, + { 0x1900, 0x2937, 0x0000 }, + { 0x9900, 0x293c, 0x3000 }, + { 0x9900, 0x293a, 0x2000 }, + { 0x1900, 0x2939, 0x0000 }, + { 0x1900, 0x293b, 0x0000 }, + { 0x9900, 0x293e, 0x2000 }, + { 0x1900, 0x293d, 0x0000 }, + { 0x1900, 0x293f, 0x0000 }, + { 0x9900, 0x2950, 0x5000 }, + { 0x9900, 0x2948, 0x4000 }, + { 0x9900, 0x2944, 0x3000 }, + { 0x9900, 0x2942, 0x2000 }, + { 0x1900, 0x2941, 0x0000 }, + { 0x1900, 0x2943, 0x0000 }, + { 0x9900, 0x2946, 0x2000 }, + { 0x1900, 0x2945, 0x0000 }, + { 0x1900, 0x2947, 0x0000 }, + { 0x9900, 0x294c, 0x3000 }, + { 0x9900, 0x294a, 0x2000 }, + { 0x1900, 0x2949, 0x0000 }, + { 0x1900, 0x294b, 0x0000 }, + { 0x9900, 0x294e, 0x2000 }, + { 0x1900, 0x294d, 0x0000 }, + { 0x1900, 0x294f, 0x0000 }, + { 0x9900, 0x2958, 0x4000 }, + { 0x9900, 0x2954, 0x3000 }, + { 0x9900, 0x2952, 0x2000 }, + { 0x1900, 0x2951, 0x0000 }, + { 0x1900, 0x2953, 0x0000 }, + { 0x9900, 0x2956, 0x2000 }, + { 0x1900, 0x2955, 0x0000 }, + { 0x1900, 0x2957, 0x0000 }, + { 0x9900, 0x295c, 0x3000 }, + { 0x9900, 0x295a, 0x2000 }, + { 0x1900, 0x2959, 0x0000 }, + { 0x1900, 0x295b, 0x0000 }, + { 0x9900, 0x295e, 0x2000 }, + { 0x1900, 0x295d, 0x0000 }, + { 0x1900, 0x295f, 0x0000 }, + { 0x9900, 0x2980, 0x6000 }, + { 0x9900, 0x2970, 0x5000 }, + { 0x9900, 0x2968, 0x4000 }, + { 0x9900, 0x2964, 0x3000 }, + { 0x9900, 0x2962, 0x2000 }, + { 0x1900, 0x2961, 0x0000 }, + { 0x1900, 0x2963, 0x0000 }, + { 0x9900, 0x2966, 0x2000 }, + { 0x1900, 0x2965, 0x0000 }, + { 0x1900, 0x2967, 0x0000 }, + { 0x9900, 0x296c, 0x3000 }, + { 0x9900, 0x296a, 0x2000 }, + { 0x1900, 0x2969, 0x0000 }, + { 0x1900, 0x296b, 0x0000 }, + { 0x9900, 0x296e, 0x2000 }, + { 0x1900, 0x296d, 0x0000 }, + { 0x1900, 0x296f, 0x0000 }, + { 0x9900, 0x2978, 0x4000 }, + { 0x9900, 0x2974, 0x3000 }, + { 0x9900, 0x2972, 0x2000 }, + { 0x1900, 0x2971, 0x0000 }, + { 0x1900, 0x2973, 0x0000 }, + { 0x9900, 0x2976, 0x2000 }, + { 0x1900, 0x2975, 0x0000 }, + { 0x1900, 0x2977, 0x0000 }, + { 0x9900, 0x297c, 0x3000 }, + { 0x9900, 0x297a, 0x2000 }, + { 0x1900, 0x2979, 0x0000 }, + { 0x1900, 0x297b, 0x0000 }, + { 0x9900, 0x297e, 0x2000 }, + { 0x1900, 0x297d, 0x0000 }, + { 0x1900, 0x297f, 0x0000 }, + { 0x9200, 0x2990, 0x5000 }, + { 0x9200, 0x2988, 0x4000 }, + { 0x9200, 0x2984, 0x3000 }, + { 0x9900, 0x2982, 0x2000 }, + { 0x1900, 0x2981, 0x0000 }, + { 0x1600, 0x2983, 0x0000 }, + { 0x9200, 0x2986, 0x2000 }, + { 0x1600, 0x2985, 0x0000 }, + { 0x1600, 0x2987, 0x0000 }, + { 0x9200, 0x298c, 0x3000 }, + { 0x9200, 0x298a, 0x2000 }, + { 0x1600, 0x2989, 0x0000 }, + { 0x1600, 0x298b, 0x0000 }, + { 0x9200, 0x298e, 0x2000 }, + { 0x1600, 0x298d, 0x0000 }, + { 0x1600, 0x298f, 0x0000 }, + { 0x9200, 0x2998, 0x4000 }, + { 0x9200, 0x2994, 0x3000 }, + { 0x9200, 0x2992, 0x2000 }, + { 0x1600, 0x2991, 0x0000 }, + { 0x1600, 0x2993, 0x0000 }, + { 0x9200, 0x2996, 0x2000 }, + { 0x1600, 0x2995, 0x0000 }, + { 0x1600, 0x2997, 0x0000 }, + { 0x9900, 0x299c, 0x3000 }, + { 0x9900, 0x299a, 0x2000 }, + { 0x1900, 0x2999, 0x0000 }, + { 0x1900, 0x299b, 0x0000 }, + { 0x9900, 0x299e, 0x2000 }, + { 0x1900, 0x299d, 0x0000 }, + { 0x1900, 0x299f, 0x0000 }, + { 0x9900, 0x2aa0, 0x9000 }, + { 0x9900, 0x2a20, 0x8000 }, + { 0x9900, 0x29e0, 0x7000 }, + { 0x9900, 0x29c0, 0x6000 }, + { 0x9900, 0x29b0, 0x5000 }, + { 0x9900, 0x29a8, 0x4000 }, + { 0x9900, 0x29a4, 0x3000 }, + { 0x9900, 0x29a2, 0x2000 }, + { 0x1900, 0x29a1, 0x0000 }, + { 0x1900, 0x29a3, 0x0000 }, + { 0x9900, 0x29a6, 0x2000 }, + { 0x1900, 0x29a5, 0x0000 }, + { 0x1900, 0x29a7, 0x0000 }, + { 0x9900, 0x29ac, 0x3000 }, + { 0x9900, 0x29aa, 0x2000 }, + { 0x1900, 0x29a9, 0x0000 }, + { 0x1900, 0x29ab, 0x0000 }, + { 0x9900, 0x29ae, 0x2000 }, + { 0x1900, 0x29ad, 0x0000 }, + { 0x1900, 0x29af, 0x0000 }, + { 0x9900, 0x29b8, 0x4000 }, + { 0x9900, 0x29b4, 0x3000 }, + { 0x9900, 0x29b2, 0x2000 }, + { 0x1900, 0x29b1, 0x0000 }, + { 0x1900, 0x29b3, 0x0000 }, + { 0x9900, 0x29b6, 0x2000 }, + { 0x1900, 0x29b5, 0x0000 }, + { 0x1900, 0x29b7, 0x0000 }, + { 0x9900, 0x29bc, 0x3000 }, + { 0x9900, 0x29ba, 0x2000 }, + { 0x1900, 0x29b9, 0x0000 }, + { 0x1900, 0x29bb, 0x0000 }, + { 0x9900, 0x29be, 0x2000 }, + { 0x1900, 0x29bd, 0x0000 }, + { 0x1900, 0x29bf, 0x0000 }, + { 0x9900, 0x29d0, 0x5000 }, + { 0x9900, 0x29c8, 0x4000 }, + { 0x9900, 0x29c4, 0x3000 }, + { 0x9900, 0x29c2, 0x2000 }, + { 0x1900, 0x29c1, 0x0000 }, + { 0x1900, 0x29c3, 0x0000 }, + { 0x9900, 0x29c6, 0x2000 }, + { 0x1900, 0x29c5, 0x0000 }, + { 0x1900, 0x29c7, 0x0000 }, + { 0x9900, 0x29cc, 0x3000 }, + { 0x9900, 0x29ca, 0x2000 }, + { 0x1900, 0x29c9, 0x0000 }, + { 0x1900, 0x29cb, 0x0000 }, + { 0x9900, 0x29ce, 0x2000 }, + { 0x1900, 0x29cd, 0x0000 }, + { 0x1900, 0x29cf, 0x0000 }, + { 0x9600, 0x29d8, 0x4000 }, + { 0x9900, 0x29d4, 0x3000 }, + { 0x9900, 0x29d2, 0x2000 }, + { 0x1900, 0x29d1, 0x0000 }, + { 0x1900, 0x29d3, 0x0000 }, + { 0x9900, 0x29d6, 0x2000 }, + { 0x1900, 0x29d5, 0x0000 }, + { 0x1900, 0x29d7, 0x0000 }, + { 0x9900, 0x29dc, 0x3000 }, + { 0x9600, 0x29da, 0x2000 }, + { 0x1200, 0x29d9, 0x0000 }, + { 0x1200, 0x29db, 0x0000 }, + { 0x9900, 0x29de, 0x2000 }, + { 0x1900, 0x29dd, 0x0000 }, + { 0x1900, 0x29df, 0x0000 }, + { 0x9900, 0x2a00, 0x6000 }, + { 0x9900, 0x29f0, 0x5000 }, + { 0x9900, 0x29e8, 0x4000 }, + { 0x9900, 0x29e4, 0x3000 }, + { 0x9900, 0x29e2, 0x2000 }, + { 0x1900, 0x29e1, 0x0000 }, + { 0x1900, 0x29e3, 0x0000 }, + { 0x9900, 0x29e6, 0x2000 }, + { 0x1900, 0x29e5, 0x0000 }, + { 0x1900, 0x29e7, 0x0000 }, + { 0x9900, 0x29ec, 0x3000 }, + { 0x9900, 0x29ea, 0x2000 }, + { 0x1900, 0x29e9, 0x0000 }, + { 0x1900, 0x29eb, 0x0000 }, + { 0x9900, 0x29ee, 0x2000 }, + { 0x1900, 0x29ed, 0x0000 }, + { 0x1900, 0x29ef, 0x0000 }, + { 0x9900, 0x29f8, 0x4000 }, + { 0x9900, 0x29f4, 0x3000 }, + { 0x9900, 0x29f2, 0x2000 }, + { 0x1900, 0x29f1, 0x0000 }, + { 0x1900, 0x29f3, 0x0000 }, + { 0x9900, 0x29f6, 0x2000 }, + { 0x1900, 0x29f5, 0x0000 }, + { 0x1900, 0x29f7, 0x0000 }, + { 0x9600, 0x29fc, 0x3000 }, + { 0x9900, 0x29fa, 0x2000 }, + { 0x1900, 0x29f9, 0x0000 }, + { 0x1900, 0x29fb, 0x0000 }, + { 0x9900, 0x29fe, 0x2000 }, + { 0x1200, 0x29fd, 0x0000 }, + { 0x1900, 0x29ff, 0x0000 }, + { 0x9900, 0x2a10, 0x5000 }, + { 0x9900, 0x2a08, 0x4000 }, + { 0x9900, 0x2a04, 0x3000 }, + { 0x9900, 0x2a02, 0x2000 }, + { 0x1900, 0x2a01, 0x0000 }, + { 0x1900, 0x2a03, 0x0000 }, + { 0x9900, 0x2a06, 0x2000 }, + { 0x1900, 0x2a05, 0x0000 }, + { 0x1900, 0x2a07, 0x0000 }, + { 0x9900, 0x2a0c, 0x3000 }, + { 0x9900, 0x2a0a, 0x2000 }, + { 0x1900, 0x2a09, 0x0000 }, + { 0x1900, 0x2a0b, 0x0000 }, + { 0x9900, 0x2a0e, 0x2000 }, + { 0x1900, 0x2a0d, 0x0000 }, + { 0x1900, 0x2a0f, 0x0000 }, + { 0x9900, 0x2a18, 0x4000 }, + { 0x9900, 0x2a14, 0x3000 }, + { 0x9900, 0x2a12, 0x2000 }, + { 0x1900, 0x2a11, 0x0000 }, + { 0x1900, 0x2a13, 0x0000 }, + { 0x9900, 0x2a16, 0x2000 }, + { 0x1900, 0x2a15, 0x0000 }, + { 0x1900, 0x2a17, 0x0000 }, + { 0x9900, 0x2a1c, 0x3000 }, + { 0x9900, 0x2a1a, 0x2000 }, + { 0x1900, 0x2a19, 0x0000 }, + { 0x1900, 0x2a1b, 0x0000 }, + { 0x9900, 0x2a1e, 0x2000 }, + { 0x1900, 0x2a1d, 0x0000 }, + { 0x1900, 0x2a1f, 0x0000 }, + { 0x9900, 0x2a60, 0x7000 }, + { 0x9900, 0x2a40, 0x6000 }, + { 0x9900, 0x2a30, 0x5000 }, + { 0x9900, 0x2a28, 0x4000 }, + { 0x9900, 0x2a24, 0x3000 }, + { 0x9900, 0x2a22, 0x2000 }, + { 0x1900, 0x2a21, 0x0000 }, + { 0x1900, 0x2a23, 0x0000 }, + { 0x9900, 0x2a26, 0x2000 }, + { 0x1900, 0x2a25, 0x0000 }, + { 0x1900, 0x2a27, 0x0000 }, + { 0x9900, 0x2a2c, 0x3000 }, + { 0x9900, 0x2a2a, 0x2000 }, + { 0x1900, 0x2a29, 0x0000 }, + { 0x1900, 0x2a2b, 0x0000 }, + { 0x9900, 0x2a2e, 0x2000 }, + { 0x1900, 0x2a2d, 0x0000 }, + { 0x1900, 0x2a2f, 0x0000 }, + { 0x9900, 0x2a38, 0x4000 }, + { 0x9900, 0x2a34, 0x3000 }, + { 0x9900, 0x2a32, 0x2000 }, + { 0x1900, 0x2a31, 0x0000 }, + { 0x1900, 0x2a33, 0x0000 }, + { 0x9900, 0x2a36, 0x2000 }, + { 0x1900, 0x2a35, 0x0000 }, + { 0x1900, 0x2a37, 0x0000 }, + { 0x9900, 0x2a3c, 0x3000 }, + { 0x9900, 0x2a3a, 0x2000 }, + { 0x1900, 0x2a39, 0x0000 }, + { 0x1900, 0x2a3b, 0x0000 }, + { 0x9900, 0x2a3e, 0x2000 }, + { 0x1900, 0x2a3d, 0x0000 }, + { 0x1900, 0x2a3f, 0x0000 }, + { 0x9900, 0x2a50, 0x5000 }, + { 0x9900, 0x2a48, 0x4000 }, + { 0x9900, 0x2a44, 0x3000 }, + { 0x9900, 0x2a42, 0x2000 }, + { 0x1900, 0x2a41, 0x0000 }, + { 0x1900, 0x2a43, 0x0000 }, + { 0x9900, 0x2a46, 0x2000 }, + { 0x1900, 0x2a45, 0x0000 }, + { 0x1900, 0x2a47, 0x0000 }, + { 0x9900, 0x2a4c, 0x3000 }, + { 0x9900, 0x2a4a, 0x2000 }, + { 0x1900, 0x2a49, 0x0000 }, + { 0x1900, 0x2a4b, 0x0000 }, + { 0x9900, 0x2a4e, 0x2000 }, + { 0x1900, 0x2a4d, 0x0000 }, + { 0x1900, 0x2a4f, 0x0000 }, + { 0x9900, 0x2a58, 0x4000 }, + { 0x9900, 0x2a54, 0x3000 }, + { 0x9900, 0x2a52, 0x2000 }, + { 0x1900, 0x2a51, 0x0000 }, + { 0x1900, 0x2a53, 0x0000 }, + { 0x9900, 0x2a56, 0x2000 }, + { 0x1900, 0x2a55, 0x0000 }, + { 0x1900, 0x2a57, 0x0000 }, + { 0x9900, 0x2a5c, 0x3000 }, + { 0x9900, 0x2a5a, 0x2000 }, + { 0x1900, 0x2a59, 0x0000 }, + { 0x1900, 0x2a5b, 0x0000 }, + { 0x9900, 0x2a5e, 0x2000 }, + { 0x1900, 0x2a5d, 0x0000 }, + { 0x1900, 0x2a5f, 0x0000 }, + { 0x9900, 0x2a80, 0x6000 }, + { 0x9900, 0x2a70, 0x5000 }, + { 0x9900, 0x2a68, 0x4000 }, + { 0x9900, 0x2a64, 0x3000 }, + { 0x9900, 0x2a62, 0x2000 }, + { 0x1900, 0x2a61, 0x0000 }, + { 0x1900, 0x2a63, 0x0000 }, + { 0x9900, 0x2a66, 0x2000 }, + { 0x1900, 0x2a65, 0x0000 }, + { 0x1900, 0x2a67, 0x0000 }, + { 0x9900, 0x2a6c, 0x3000 }, + { 0x9900, 0x2a6a, 0x2000 }, + { 0x1900, 0x2a69, 0x0000 }, + { 0x1900, 0x2a6b, 0x0000 }, + { 0x9900, 0x2a6e, 0x2000 }, + { 0x1900, 0x2a6d, 0x0000 }, + { 0x1900, 0x2a6f, 0x0000 }, + { 0x9900, 0x2a78, 0x4000 }, + { 0x9900, 0x2a74, 0x3000 }, + { 0x9900, 0x2a72, 0x2000 }, + { 0x1900, 0x2a71, 0x0000 }, + { 0x1900, 0x2a73, 0x0000 }, + { 0x9900, 0x2a76, 0x2000 }, + { 0x1900, 0x2a75, 0x0000 }, + { 0x1900, 0x2a77, 0x0000 }, + { 0x9900, 0x2a7c, 0x3000 }, + { 0x9900, 0x2a7a, 0x2000 }, + { 0x1900, 0x2a79, 0x0000 }, + { 0x1900, 0x2a7b, 0x0000 }, + { 0x9900, 0x2a7e, 0x2000 }, + { 0x1900, 0x2a7d, 0x0000 }, + { 0x1900, 0x2a7f, 0x0000 }, + { 0x9900, 0x2a90, 0x5000 }, + { 0x9900, 0x2a88, 0x4000 }, + { 0x9900, 0x2a84, 0x3000 }, + { 0x9900, 0x2a82, 0x2000 }, + { 0x1900, 0x2a81, 0x0000 }, + { 0x1900, 0x2a83, 0x0000 }, + { 0x9900, 0x2a86, 0x2000 }, + { 0x1900, 0x2a85, 0x0000 }, + { 0x1900, 0x2a87, 0x0000 }, + { 0x9900, 0x2a8c, 0x3000 }, + { 0x9900, 0x2a8a, 0x2000 }, + { 0x1900, 0x2a89, 0x0000 }, + { 0x1900, 0x2a8b, 0x0000 }, + { 0x9900, 0x2a8e, 0x2000 }, + { 0x1900, 0x2a8d, 0x0000 }, + { 0x1900, 0x2a8f, 0x0000 }, + { 0x9900, 0x2a98, 0x4000 }, + { 0x9900, 0x2a94, 0x3000 }, + { 0x9900, 0x2a92, 0x2000 }, + { 0x1900, 0x2a91, 0x0000 }, + { 0x1900, 0x2a93, 0x0000 }, + { 0x9900, 0x2a96, 0x2000 }, + { 0x1900, 0x2a95, 0x0000 }, + { 0x1900, 0x2a97, 0x0000 }, + { 0x9900, 0x2a9c, 0x3000 }, + { 0x9900, 0x2a9a, 0x2000 }, + { 0x1900, 0x2a99, 0x0000 }, + { 0x1900, 0x2a9b, 0x0000 }, + { 0x9900, 0x2a9e, 0x2000 }, + { 0x1900, 0x2a9d, 0x0000 }, + { 0x1900, 0x2a9f, 0x0000 }, + { 0x9a00, 0x2e92, 0x8000 }, + { 0x9900, 0x2ae0, 0x7000 }, + { 0x9900, 0x2ac0, 0x6000 }, + { 0x9900, 0x2ab0, 0x5000 }, + { 0x9900, 0x2aa8, 0x4000 }, + { 0x9900, 0x2aa4, 0x3000 }, + { 0x9900, 0x2aa2, 0x2000 }, + { 0x1900, 0x2aa1, 0x0000 }, + { 0x1900, 0x2aa3, 0x0000 }, + { 0x9900, 0x2aa6, 0x2000 }, + { 0x1900, 0x2aa5, 0x0000 }, + { 0x1900, 0x2aa7, 0x0000 }, + { 0x9900, 0x2aac, 0x3000 }, + { 0x9900, 0x2aaa, 0x2000 }, + { 0x1900, 0x2aa9, 0x0000 }, + { 0x1900, 0x2aab, 0x0000 }, + { 0x9900, 0x2aae, 0x2000 }, + { 0x1900, 0x2aad, 0x0000 }, + { 0x1900, 0x2aaf, 0x0000 }, + { 0x9900, 0x2ab8, 0x4000 }, + { 0x9900, 0x2ab4, 0x3000 }, + { 0x9900, 0x2ab2, 0x2000 }, + { 0x1900, 0x2ab1, 0x0000 }, + { 0x1900, 0x2ab3, 0x0000 }, + { 0x9900, 0x2ab6, 0x2000 }, + { 0x1900, 0x2ab5, 0x0000 }, + { 0x1900, 0x2ab7, 0x0000 }, + { 0x9900, 0x2abc, 0x3000 }, + { 0x9900, 0x2aba, 0x2000 }, + { 0x1900, 0x2ab9, 0x0000 }, + { 0x1900, 0x2abb, 0x0000 }, + { 0x9900, 0x2abe, 0x2000 }, + { 0x1900, 0x2abd, 0x0000 }, + { 0x1900, 0x2abf, 0x0000 }, + { 0x9900, 0x2ad0, 0x5000 }, + { 0x9900, 0x2ac8, 0x4000 }, + { 0x9900, 0x2ac4, 0x3000 }, + { 0x9900, 0x2ac2, 0x2000 }, + { 0x1900, 0x2ac1, 0x0000 }, + { 0x1900, 0x2ac3, 0x0000 }, + { 0x9900, 0x2ac6, 0x2000 }, + { 0x1900, 0x2ac5, 0x0000 }, + { 0x1900, 0x2ac7, 0x0000 }, + { 0x9900, 0x2acc, 0x3000 }, + { 0x9900, 0x2aca, 0x2000 }, + { 0x1900, 0x2ac9, 0x0000 }, + { 0x1900, 0x2acb, 0x0000 }, + { 0x9900, 0x2ace, 0x2000 }, + { 0x1900, 0x2acd, 0x0000 }, + { 0x1900, 0x2acf, 0x0000 }, + { 0x9900, 0x2ad8, 0x4000 }, + { 0x9900, 0x2ad4, 0x3000 }, + { 0x9900, 0x2ad2, 0x2000 }, + { 0x1900, 0x2ad1, 0x0000 }, + { 0x1900, 0x2ad3, 0x0000 }, + { 0x9900, 0x2ad6, 0x2000 }, + { 0x1900, 0x2ad5, 0x0000 }, + { 0x1900, 0x2ad7, 0x0000 }, + { 0x9900, 0x2adc, 0x3000 }, + { 0x9900, 0x2ada, 0x2000 }, + { 0x1900, 0x2ad9, 0x0000 }, + { 0x1900, 0x2adb, 0x0000 }, + { 0x9900, 0x2ade, 0x2000 }, + { 0x1900, 0x2add, 0x0000 }, + { 0x1900, 0x2adf, 0x0000 }, + { 0x9a00, 0x2b00, 0x6000 }, + { 0x9900, 0x2af0, 0x5000 }, + { 0x9900, 0x2ae8, 0x4000 }, + { 0x9900, 0x2ae4, 0x3000 }, + { 0x9900, 0x2ae2, 0x2000 }, + { 0x1900, 0x2ae1, 0x0000 }, + { 0x1900, 0x2ae3, 0x0000 }, + { 0x9900, 0x2ae6, 0x2000 }, + { 0x1900, 0x2ae5, 0x0000 }, + { 0x1900, 0x2ae7, 0x0000 }, + { 0x9900, 0x2aec, 0x3000 }, + { 0x9900, 0x2aea, 0x2000 }, + { 0x1900, 0x2ae9, 0x0000 }, + { 0x1900, 0x2aeb, 0x0000 }, + { 0x9900, 0x2aee, 0x2000 }, + { 0x1900, 0x2aed, 0x0000 }, + { 0x1900, 0x2aef, 0x0000 }, + { 0x9900, 0x2af8, 0x4000 }, + { 0x9900, 0x2af4, 0x3000 }, + { 0x9900, 0x2af2, 0x2000 }, + { 0x1900, 0x2af1, 0x0000 }, + { 0x1900, 0x2af3, 0x0000 }, + { 0x9900, 0x2af6, 0x2000 }, + { 0x1900, 0x2af5, 0x0000 }, + { 0x1900, 0x2af7, 0x0000 }, + { 0x9900, 0x2afc, 0x3000 }, + { 0x9900, 0x2afa, 0x2000 }, + { 0x1900, 0x2af9, 0x0000 }, + { 0x1900, 0x2afb, 0x0000 }, + { 0x9900, 0x2afe, 0x2000 }, + { 0x1900, 0x2afd, 0x0000 }, + { 0x1900, 0x2aff, 0x0000 }, + { 0x9a00, 0x2e82, 0x5000 }, + { 0x9a00, 0x2b08, 0x4000 }, + { 0x9a00, 0x2b04, 0x3000 }, + { 0x9a00, 0x2b02, 0x2000 }, + { 0x1a00, 0x2b01, 0x0000 }, + { 0x1a00, 0x2b03, 0x0000 }, + { 0x9a00, 0x2b06, 0x2000 }, + { 0x1a00, 0x2b05, 0x0000 }, + { 0x1a00, 0x2b07, 0x0000 }, + { 0x9a00, 0x2b0c, 0x3000 }, + { 0x9a00, 0x2b0a, 0x2000 }, + { 0x1a00, 0x2b09, 0x0000 }, + { 0x1a00, 0x2b0b, 0x0000 }, + { 0x9a00, 0x2e80, 0x2000 }, + { 0x1a00, 0x2b0d, 0x0000 }, + { 0x1a00, 0x2e81, 0x0000 }, + { 0x9a00, 0x2e8a, 0x4000 }, + { 0x9a00, 0x2e86, 0x3000 }, + { 0x9a00, 0x2e84, 0x2000 }, + { 0x1a00, 0x2e83, 0x0000 }, + { 0x1a00, 0x2e85, 0x0000 }, + { 0x9a00, 0x2e88, 0x2000 }, + { 0x1a00, 0x2e87, 0x0000 }, + { 0x1a00, 0x2e89, 0x0000 }, + { 0x9a00, 0x2e8e, 0x3000 }, + { 0x9a00, 0x2e8c, 0x2000 }, + { 0x1a00, 0x2e8b, 0x0000 }, + { 0x1a00, 0x2e8d, 0x0000 }, + { 0x9a00, 0x2e90, 0x2000 }, + { 0x1a00, 0x2e8f, 0x0000 }, + { 0x1a00, 0x2e91, 0x0000 }, + { 0x9a00, 0x2ed3, 0x7000 }, + { 0x9a00, 0x2eb3, 0x6000 }, + { 0x9a00, 0x2ea3, 0x5000 }, + { 0x9a00, 0x2e9b, 0x4000 }, + { 0x9a00, 0x2e96, 0x3000 }, + { 0x9a00, 0x2e94, 0x2000 }, + { 0x1a00, 0x2e93, 0x0000 }, + { 0x1a00, 0x2e95, 0x0000 }, + { 0x9a00, 0x2e98, 0x2000 }, + { 0x1a00, 0x2e97, 0x0000 }, + { 0x1a00, 0x2e99, 0x0000 }, + { 0x9a00, 0x2e9f, 0x3000 }, + { 0x9a00, 0x2e9d, 0x2000 }, + { 0x1a00, 0x2e9c, 0x0000 }, + { 0x1a00, 0x2e9e, 0x0000 }, + { 0x9a00, 0x2ea1, 0x2000 }, + { 0x1a00, 0x2ea0, 0x0000 }, + { 0x1a00, 0x2ea2, 0x0000 }, + { 0x9a00, 0x2eab, 0x4000 }, + { 0x9a00, 0x2ea7, 0x3000 }, + { 0x9a00, 0x2ea5, 0x2000 }, + { 0x1a00, 0x2ea4, 0x0000 }, + { 0x1a00, 0x2ea6, 0x0000 }, + { 0x9a00, 0x2ea9, 0x2000 }, + { 0x1a00, 0x2ea8, 0x0000 }, + { 0x1a00, 0x2eaa, 0x0000 }, + { 0x9a00, 0x2eaf, 0x3000 }, + { 0x9a00, 0x2ead, 0x2000 }, + { 0x1a00, 0x2eac, 0x0000 }, + { 0x1a00, 0x2eae, 0x0000 }, + { 0x9a00, 0x2eb1, 0x2000 }, + { 0x1a00, 0x2eb0, 0x0000 }, + { 0x1a00, 0x2eb2, 0x0000 }, + { 0x9a00, 0x2ec3, 0x5000 }, + { 0x9a00, 0x2ebb, 0x4000 }, + { 0x9a00, 0x2eb7, 0x3000 }, + { 0x9a00, 0x2eb5, 0x2000 }, + { 0x1a00, 0x2eb4, 0x0000 }, + { 0x1a00, 0x2eb6, 0x0000 }, + { 0x9a00, 0x2eb9, 0x2000 }, + { 0x1a00, 0x2eb8, 0x0000 }, + { 0x1a00, 0x2eba, 0x0000 }, + { 0x9a00, 0x2ebf, 0x3000 }, + { 0x9a00, 0x2ebd, 0x2000 }, + { 0x1a00, 0x2ebc, 0x0000 }, + { 0x1a00, 0x2ebe, 0x0000 }, + { 0x9a00, 0x2ec1, 0x2000 }, + { 0x1a00, 0x2ec0, 0x0000 }, + { 0x1a00, 0x2ec2, 0x0000 }, + { 0x9a00, 0x2ecb, 0x4000 }, + { 0x9a00, 0x2ec7, 0x3000 }, + { 0x9a00, 0x2ec5, 0x2000 }, + { 0x1a00, 0x2ec4, 0x0000 }, + { 0x1a00, 0x2ec6, 0x0000 }, + { 0x9a00, 0x2ec9, 0x2000 }, + { 0x1a00, 0x2ec8, 0x0000 }, + { 0x1a00, 0x2eca, 0x0000 }, + { 0x9a00, 0x2ecf, 0x3000 }, + { 0x9a00, 0x2ecd, 0x2000 }, + { 0x1a00, 0x2ecc, 0x0000 }, + { 0x1a00, 0x2ece, 0x0000 }, + { 0x9a00, 0x2ed1, 0x2000 }, + { 0x1a00, 0x2ed0, 0x0000 }, + { 0x1a00, 0x2ed2, 0x0000 }, + { 0x9a00, 0x2ef3, 0x6000 }, + { 0x9a00, 0x2ee3, 0x5000 }, + { 0x9a00, 0x2edb, 0x4000 }, + { 0x9a00, 0x2ed7, 0x3000 }, + { 0x9a00, 0x2ed5, 0x2000 }, + { 0x1a00, 0x2ed4, 0x0000 }, + { 0x1a00, 0x2ed6, 0x0000 }, + { 0x9a00, 0x2ed9, 0x2000 }, + { 0x1a00, 0x2ed8, 0x0000 }, + { 0x1a00, 0x2eda, 0x0000 }, + { 0x9a00, 0x2edf, 0x3000 }, + { 0x9a00, 0x2edd, 0x2000 }, + { 0x1a00, 0x2edc, 0x0000 }, + { 0x1a00, 0x2ede, 0x0000 }, + { 0x9a00, 0x2ee1, 0x2000 }, + { 0x1a00, 0x2ee0, 0x0000 }, + { 0x1a00, 0x2ee2, 0x0000 }, + { 0x9a00, 0x2eeb, 0x4000 }, + { 0x9a00, 0x2ee7, 0x3000 }, + { 0x9a00, 0x2ee5, 0x2000 }, + { 0x1a00, 0x2ee4, 0x0000 }, + { 0x1a00, 0x2ee6, 0x0000 }, + { 0x9a00, 0x2ee9, 0x2000 }, + { 0x1a00, 0x2ee8, 0x0000 }, + { 0x1a00, 0x2eea, 0x0000 }, + { 0x9a00, 0x2eef, 0x3000 }, + { 0x9a00, 0x2eed, 0x2000 }, + { 0x1a00, 0x2eec, 0x0000 }, + { 0x1a00, 0x2eee, 0x0000 }, + { 0x9a00, 0x2ef1, 0x2000 }, + { 0x1a00, 0x2ef0, 0x0000 }, + { 0x1a00, 0x2ef2, 0x0000 }, + { 0x9a00, 0x2f0f, 0x5000 }, + { 0x9a00, 0x2f07, 0x4000 }, + { 0x9a00, 0x2f03, 0x3000 }, + { 0x9a00, 0x2f01, 0x2000 }, + { 0x1a00, 0x2f00, 0x0000 }, + { 0x1a00, 0x2f02, 0x0000 }, + { 0x9a00, 0x2f05, 0x2000 }, + { 0x1a00, 0x2f04, 0x0000 }, + { 0x1a00, 0x2f06, 0x0000 }, + { 0x9a00, 0x2f0b, 0x3000 }, + { 0x9a00, 0x2f09, 0x2000 }, + { 0x1a00, 0x2f08, 0x0000 }, + { 0x1a00, 0x2f0a, 0x0000 }, + { 0x9a00, 0x2f0d, 0x2000 }, + { 0x1a00, 0x2f0c, 0x0000 }, + { 0x1a00, 0x2f0e, 0x0000 }, + { 0x9a00, 0x2f17, 0x4000 }, + { 0x9a00, 0x2f13, 0x3000 }, + { 0x9a00, 0x2f11, 0x2000 }, + { 0x1a00, 0x2f10, 0x0000 }, + { 0x1a00, 0x2f12, 0x0000 }, + { 0x9a00, 0x2f15, 0x2000 }, + { 0x1a00, 0x2f14, 0x0000 }, + { 0x1a00, 0x2f16, 0x0000 }, + { 0x9a00, 0x2f1b, 0x3000 }, + { 0x9a00, 0x2f19, 0x2000 }, + { 0x1a00, 0x2f18, 0x0000 }, + { 0x1a00, 0x2f1a, 0x0000 }, + { 0x9a00, 0x2f1d, 0x2000 }, + { 0x1a00, 0x2f1c, 0x0000 }, + { 0x1a00, 0x2f1e, 0x0000 }, + { 0x8701, 0x00f0, 0xd000 }, + { 0x8700, 0xa34d, 0xc000 }, + { 0x9a00, 0x3391, 0xb000 }, + { 0x8700, 0x3149, 0xa000 }, + { 0x9500, 0x303d, 0x9000 }, + { 0x9a00, 0x2f9f, 0x8000 }, + { 0x9a00, 0x2f5f, 0x7000 }, + { 0x9a00, 0x2f3f, 0x6000 }, + { 0x9a00, 0x2f2f, 0x5000 }, + { 0x9a00, 0x2f27, 0x4000 }, + { 0x9a00, 0x2f23, 0x3000 }, + { 0x9a00, 0x2f21, 0x2000 }, + { 0x1a00, 0x2f20, 0x0000 }, + { 0x1a00, 0x2f22, 0x0000 }, + { 0x9a00, 0x2f25, 0x2000 }, + { 0x1a00, 0x2f24, 0x0000 }, + { 0x1a00, 0x2f26, 0x0000 }, + { 0x9a00, 0x2f2b, 0x3000 }, + { 0x9a00, 0x2f29, 0x2000 }, + { 0x1a00, 0x2f28, 0x0000 }, + { 0x1a00, 0x2f2a, 0x0000 }, + { 0x9a00, 0x2f2d, 0x2000 }, + { 0x1a00, 0x2f2c, 0x0000 }, + { 0x1a00, 0x2f2e, 0x0000 }, + { 0x9a00, 0x2f37, 0x4000 }, + { 0x9a00, 0x2f33, 0x3000 }, + { 0x9a00, 0x2f31, 0x2000 }, + { 0x1a00, 0x2f30, 0x0000 }, + { 0x1a00, 0x2f32, 0x0000 }, + { 0x9a00, 0x2f35, 0x2000 }, + { 0x1a00, 0x2f34, 0x0000 }, + { 0x1a00, 0x2f36, 0x0000 }, + { 0x9a00, 0x2f3b, 0x3000 }, + { 0x9a00, 0x2f39, 0x2000 }, + { 0x1a00, 0x2f38, 0x0000 }, + { 0x1a00, 0x2f3a, 0x0000 }, + { 0x9a00, 0x2f3d, 0x2000 }, + { 0x1a00, 0x2f3c, 0x0000 }, + { 0x1a00, 0x2f3e, 0x0000 }, + { 0x9a00, 0x2f4f, 0x5000 }, + { 0x9a00, 0x2f47, 0x4000 }, + { 0x9a00, 0x2f43, 0x3000 }, + { 0x9a00, 0x2f41, 0x2000 }, + { 0x1a00, 0x2f40, 0x0000 }, + { 0x1a00, 0x2f42, 0x0000 }, + { 0x9a00, 0x2f45, 0x2000 }, + { 0x1a00, 0x2f44, 0x0000 }, + { 0x1a00, 0x2f46, 0x0000 }, + { 0x9a00, 0x2f4b, 0x3000 }, + { 0x9a00, 0x2f49, 0x2000 }, + { 0x1a00, 0x2f48, 0x0000 }, + { 0x1a00, 0x2f4a, 0x0000 }, + { 0x9a00, 0x2f4d, 0x2000 }, + { 0x1a00, 0x2f4c, 0x0000 }, + { 0x1a00, 0x2f4e, 0x0000 }, + { 0x9a00, 0x2f57, 0x4000 }, + { 0x9a00, 0x2f53, 0x3000 }, + { 0x9a00, 0x2f51, 0x2000 }, + { 0x1a00, 0x2f50, 0x0000 }, + { 0x1a00, 0x2f52, 0x0000 }, + { 0x9a00, 0x2f55, 0x2000 }, + { 0x1a00, 0x2f54, 0x0000 }, + { 0x1a00, 0x2f56, 0x0000 }, + { 0x9a00, 0x2f5b, 0x3000 }, + { 0x9a00, 0x2f59, 0x2000 }, + { 0x1a00, 0x2f58, 0x0000 }, + { 0x1a00, 0x2f5a, 0x0000 }, + { 0x9a00, 0x2f5d, 0x2000 }, + { 0x1a00, 0x2f5c, 0x0000 }, + { 0x1a00, 0x2f5e, 0x0000 }, + { 0x9a00, 0x2f7f, 0x6000 }, + { 0x9a00, 0x2f6f, 0x5000 }, + { 0x9a00, 0x2f67, 0x4000 }, + { 0x9a00, 0x2f63, 0x3000 }, + { 0x9a00, 0x2f61, 0x2000 }, + { 0x1a00, 0x2f60, 0x0000 }, + { 0x1a00, 0x2f62, 0x0000 }, + { 0x9a00, 0x2f65, 0x2000 }, + { 0x1a00, 0x2f64, 0x0000 }, + { 0x1a00, 0x2f66, 0x0000 }, + { 0x9a00, 0x2f6b, 0x3000 }, + { 0x9a00, 0x2f69, 0x2000 }, + { 0x1a00, 0x2f68, 0x0000 }, + { 0x1a00, 0x2f6a, 0x0000 }, + { 0x9a00, 0x2f6d, 0x2000 }, + { 0x1a00, 0x2f6c, 0x0000 }, + { 0x1a00, 0x2f6e, 0x0000 }, + { 0x9a00, 0x2f77, 0x4000 }, + { 0x9a00, 0x2f73, 0x3000 }, + { 0x9a00, 0x2f71, 0x2000 }, + { 0x1a00, 0x2f70, 0x0000 }, + { 0x1a00, 0x2f72, 0x0000 }, + { 0x9a00, 0x2f75, 0x2000 }, + { 0x1a00, 0x2f74, 0x0000 }, + { 0x1a00, 0x2f76, 0x0000 }, + { 0x9a00, 0x2f7b, 0x3000 }, + { 0x9a00, 0x2f79, 0x2000 }, + { 0x1a00, 0x2f78, 0x0000 }, + { 0x1a00, 0x2f7a, 0x0000 }, + { 0x9a00, 0x2f7d, 0x2000 }, + { 0x1a00, 0x2f7c, 0x0000 }, + { 0x1a00, 0x2f7e, 0x0000 }, + { 0x9a00, 0x2f8f, 0x5000 }, + { 0x9a00, 0x2f87, 0x4000 }, + { 0x9a00, 0x2f83, 0x3000 }, + { 0x9a00, 0x2f81, 0x2000 }, + { 0x1a00, 0x2f80, 0x0000 }, + { 0x1a00, 0x2f82, 0x0000 }, + { 0x9a00, 0x2f85, 0x2000 }, + { 0x1a00, 0x2f84, 0x0000 }, + { 0x1a00, 0x2f86, 0x0000 }, + { 0x9a00, 0x2f8b, 0x3000 }, + { 0x9a00, 0x2f89, 0x2000 }, + { 0x1a00, 0x2f88, 0x0000 }, + { 0x1a00, 0x2f8a, 0x0000 }, + { 0x9a00, 0x2f8d, 0x2000 }, + { 0x1a00, 0x2f8c, 0x0000 }, + { 0x1a00, 0x2f8e, 0x0000 }, + { 0x9a00, 0x2f97, 0x4000 }, + { 0x9a00, 0x2f93, 0x3000 }, + { 0x9a00, 0x2f91, 0x2000 }, + { 0x1a00, 0x2f90, 0x0000 }, + { 0x1a00, 0x2f92, 0x0000 }, + { 0x9a00, 0x2f95, 0x2000 }, + { 0x1a00, 0x2f94, 0x0000 }, + { 0x1a00, 0x2f96, 0x0000 }, + { 0x9a00, 0x2f9b, 0x3000 }, + { 0x9a00, 0x2f99, 0x2000 }, + { 0x1a00, 0x2f98, 0x0000 }, + { 0x1a00, 0x2f9a, 0x0000 }, + { 0x9a00, 0x2f9d, 0x2000 }, + { 0x1a00, 0x2f9c, 0x0000 }, + { 0x1a00, 0x2f9e, 0x0000 }, + { 0x9a00, 0x2ff9, 0x7000 }, + { 0x9a00, 0x2fbf, 0x6000 }, + { 0x9a00, 0x2faf, 0x5000 }, + { 0x9a00, 0x2fa7, 0x4000 }, + { 0x9a00, 0x2fa3, 0x3000 }, + { 0x9a00, 0x2fa1, 0x2000 }, + { 0x1a00, 0x2fa0, 0x0000 }, + { 0x1a00, 0x2fa2, 0x0000 }, + { 0x9a00, 0x2fa5, 0x2000 }, + { 0x1a00, 0x2fa4, 0x0000 }, + { 0x1a00, 0x2fa6, 0x0000 }, + { 0x9a00, 0x2fab, 0x3000 }, + { 0x9a00, 0x2fa9, 0x2000 }, + { 0x1a00, 0x2fa8, 0x0000 }, + { 0x1a00, 0x2faa, 0x0000 }, + { 0x9a00, 0x2fad, 0x2000 }, + { 0x1a00, 0x2fac, 0x0000 }, + { 0x1a00, 0x2fae, 0x0000 }, + { 0x9a00, 0x2fb7, 0x4000 }, + { 0x9a00, 0x2fb3, 0x3000 }, + { 0x9a00, 0x2fb1, 0x2000 }, + { 0x1a00, 0x2fb0, 0x0000 }, + { 0x1a00, 0x2fb2, 0x0000 }, + { 0x9a00, 0x2fb5, 0x2000 }, + { 0x1a00, 0x2fb4, 0x0000 }, + { 0x1a00, 0x2fb6, 0x0000 }, + { 0x9a00, 0x2fbb, 0x3000 }, + { 0x9a00, 0x2fb9, 0x2000 }, + { 0x1a00, 0x2fb8, 0x0000 }, + { 0x1a00, 0x2fba, 0x0000 }, + { 0x9a00, 0x2fbd, 0x2000 }, + { 0x1a00, 0x2fbc, 0x0000 }, + { 0x1a00, 0x2fbe, 0x0000 }, + { 0x9a00, 0x2fcf, 0x5000 }, + { 0x9a00, 0x2fc7, 0x4000 }, + { 0x9a00, 0x2fc3, 0x3000 }, + { 0x9a00, 0x2fc1, 0x2000 }, + { 0x1a00, 0x2fc0, 0x0000 }, + { 0x1a00, 0x2fc2, 0x0000 }, + { 0x9a00, 0x2fc5, 0x2000 }, + { 0x1a00, 0x2fc4, 0x0000 }, + { 0x1a00, 0x2fc6, 0x0000 }, + { 0x9a00, 0x2fcb, 0x3000 }, + { 0x9a00, 0x2fc9, 0x2000 }, + { 0x1a00, 0x2fc8, 0x0000 }, + { 0x1a00, 0x2fca, 0x0000 }, + { 0x9a00, 0x2fcd, 0x2000 }, + { 0x1a00, 0x2fcc, 0x0000 }, + { 0x1a00, 0x2fce, 0x0000 }, + { 0x9a00, 0x2ff1, 0x4000 }, + { 0x9a00, 0x2fd3, 0x3000 }, + { 0x9a00, 0x2fd1, 0x2000 }, + { 0x1a00, 0x2fd0, 0x0000 }, + { 0x1a00, 0x2fd2, 0x0000 }, + { 0x9a00, 0x2fd5, 0x2000 }, + { 0x1a00, 0x2fd4, 0x0000 }, + { 0x1a00, 0x2ff0, 0x0000 }, + { 0x9a00, 0x2ff5, 0x3000 }, + { 0x9a00, 0x2ff3, 0x2000 }, + { 0x1a00, 0x2ff2, 0x0000 }, + { 0x1a00, 0x2ff4, 0x0000 }, + { 0x9a00, 0x2ff7, 0x2000 }, + { 0x1a00, 0x2ff6, 0x0000 }, + { 0x1a00, 0x2ff8, 0x0000 }, + { 0x9600, 0x301d, 0x6000 }, + { 0x9200, 0x300d, 0x5000 }, + { 0x8600, 0x3005, 0x4000 }, + { 0x9500, 0x3001, 0x3000 }, + { 0x9a00, 0x2ffb, 0x2000 }, + { 0x1a00, 0x2ffa, 0x0000 }, + { 0x1d00, 0x3000, 0x0000 }, + { 0x9500, 0x3003, 0x2000 }, + { 0x1500, 0x3002, 0x0000 }, + { 0x1a00, 0x3004, 0x0000 }, + { 0x9200, 0x3009, 0x3000 }, + { 0x8e00, 0x3007, 0x2000 }, + { 0x0700, 0x3006, 0x0000 }, + { 0x1600, 0x3008, 0x0000 }, + { 0x9200, 0x300b, 0x2000 }, + { 0x1600, 0x300a, 0x0000 }, + { 0x1600, 0x300c, 0x0000 }, + { 0x9200, 0x3015, 0x4000 }, + { 0x9200, 0x3011, 0x3000 }, + { 0x9200, 0x300f, 0x2000 }, + { 0x1600, 0x300e, 0x0000 }, + { 0x1600, 0x3010, 0x0000 }, + { 0x9a00, 0x3013, 0x2000 }, + { 0x1a00, 0x3012, 0x0000 }, + { 0x1600, 0x3014, 0x0000 }, + { 0x9200, 0x3019, 0x3000 }, + { 0x9200, 0x3017, 0x2000 }, + { 0x1600, 0x3016, 0x0000 }, + { 0x1600, 0x3018, 0x0000 }, + { 0x9200, 0x301b, 0x2000 }, + { 0x1600, 0x301a, 0x0000 }, + { 0x1100, 0x301c, 0x0000 }, + { 0x8c00, 0x302d, 0x5000 }, + { 0x8e00, 0x3025, 0x4000 }, + { 0x8e00, 0x3021, 0x3000 }, + { 0x9200, 0x301f, 0x2000 }, + { 0x1200, 0x301e, 0x0000 }, + { 0x1a00, 0x3020, 0x0000 }, + { 0x8e00, 0x3023, 0x2000 }, + { 0x0e00, 0x3022, 0x0000 }, + { 0x0e00, 0x3024, 0x0000 }, + { 0x8e00, 0x3029, 0x3000 }, + { 0x8e00, 0x3027, 0x2000 }, + { 0x0e00, 0x3026, 0x0000 }, + { 0x0e00, 0x3028, 0x0000 }, + { 0x8c00, 0x302b, 0x2000 }, + { 0x0c00, 0x302a, 0x0000 }, + { 0x0c00, 0x302c, 0x0000 }, + { 0x8600, 0x3035, 0x4000 }, + { 0x8600, 0x3031, 0x3000 }, + { 0x8c00, 0x302f, 0x2000 }, + { 0x0c00, 0x302e, 0x0000 }, + { 0x1100, 0x3030, 0x0000 }, + { 0x8600, 0x3033, 0x2000 }, + { 0x0600, 0x3032, 0x0000 }, + { 0x0600, 0x3034, 0x0000 }, + { 0x8e00, 0x3039, 0x3000 }, + { 0x9a00, 0x3037, 0x2000 }, + { 0x1a00, 0x3036, 0x0000 }, + { 0x0e00, 0x3038, 0x0000 }, + { 0x8600, 0x303b, 0x2000 }, + { 0x0e00, 0x303a, 0x0000 }, + { 0x0700, 0x303c, 0x0000 }, + { 0x8700, 0x30c0, 0x8000 }, + { 0x8700, 0x307e, 0x7000 }, + { 0x8700, 0x305e, 0x6000 }, + { 0x8700, 0x304e, 0x5000 }, + { 0x8700, 0x3046, 0x4000 }, + { 0x8700, 0x3042, 0x3000 }, + { 0x9a00, 0x303f, 0x2000 }, + { 0x1a00, 0x303e, 0x0000 }, + { 0x0700, 0x3041, 0x0000 }, + { 0x8700, 0x3044, 0x2000 }, + { 0x0700, 0x3043, 0x0000 }, + { 0x0700, 0x3045, 0x0000 }, + { 0x8700, 0x304a, 0x3000 }, + { 0x8700, 0x3048, 0x2000 }, + { 0x0700, 0x3047, 0x0000 }, + { 0x0700, 0x3049, 0x0000 }, + { 0x8700, 0x304c, 0x2000 }, + { 0x0700, 0x304b, 0x0000 }, + { 0x0700, 0x304d, 0x0000 }, + { 0x8700, 0x3056, 0x4000 }, + { 0x8700, 0x3052, 0x3000 }, + { 0x8700, 0x3050, 0x2000 }, + { 0x0700, 0x304f, 0x0000 }, + { 0x0700, 0x3051, 0x0000 }, + { 0x8700, 0x3054, 0x2000 }, + { 0x0700, 0x3053, 0x0000 }, + { 0x0700, 0x3055, 0x0000 }, + { 0x8700, 0x305a, 0x3000 }, + { 0x8700, 0x3058, 0x2000 }, + { 0x0700, 0x3057, 0x0000 }, + { 0x0700, 0x3059, 0x0000 }, + { 0x8700, 0x305c, 0x2000 }, + { 0x0700, 0x305b, 0x0000 }, + { 0x0700, 0x305d, 0x0000 }, + { 0x8700, 0x306e, 0x5000 }, + { 0x8700, 0x3066, 0x4000 }, + { 0x8700, 0x3062, 0x3000 }, + { 0x8700, 0x3060, 0x2000 }, + { 0x0700, 0x305f, 0x0000 }, + { 0x0700, 0x3061, 0x0000 }, + { 0x8700, 0x3064, 0x2000 }, + { 0x0700, 0x3063, 0x0000 }, + { 0x0700, 0x3065, 0x0000 }, + { 0x8700, 0x306a, 0x3000 }, + { 0x8700, 0x3068, 0x2000 }, + { 0x0700, 0x3067, 0x0000 }, + { 0x0700, 0x3069, 0x0000 }, + { 0x8700, 0x306c, 0x2000 }, + { 0x0700, 0x306b, 0x0000 }, + { 0x0700, 0x306d, 0x0000 }, + { 0x8700, 0x3076, 0x4000 }, + { 0x8700, 0x3072, 0x3000 }, + { 0x8700, 0x3070, 0x2000 }, + { 0x0700, 0x306f, 0x0000 }, + { 0x0700, 0x3071, 0x0000 }, + { 0x8700, 0x3074, 0x2000 }, + { 0x0700, 0x3073, 0x0000 }, + { 0x0700, 0x3075, 0x0000 }, + { 0x8700, 0x307a, 0x3000 }, + { 0x8700, 0x3078, 0x2000 }, + { 0x0700, 0x3077, 0x0000 }, + { 0x0700, 0x3079, 0x0000 }, + { 0x8700, 0x307c, 0x2000 }, + { 0x0700, 0x307b, 0x0000 }, + { 0x0700, 0x307d, 0x0000 }, + { 0x9100, 0x30a0, 0x6000 }, + { 0x8700, 0x308e, 0x5000 }, + { 0x8700, 0x3086, 0x4000 }, + { 0x8700, 0x3082, 0x3000 }, + { 0x8700, 0x3080, 0x2000 }, + { 0x0700, 0x307f, 0x0000 }, + { 0x0700, 0x3081, 0x0000 }, + { 0x8700, 0x3084, 0x2000 }, + { 0x0700, 0x3083, 0x0000 }, + { 0x0700, 0x3085, 0x0000 }, + { 0x8700, 0x308a, 0x3000 }, + { 0x8700, 0x3088, 0x2000 }, + { 0x0700, 0x3087, 0x0000 }, + { 0x0700, 0x3089, 0x0000 }, + { 0x8700, 0x308c, 0x2000 }, + { 0x0700, 0x308b, 0x0000 }, + { 0x0700, 0x308d, 0x0000 }, + { 0x8700, 0x3096, 0x4000 }, + { 0x8700, 0x3092, 0x3000 }, + { 0x8700, 0x3090, 0x2000 }, + { 0x0700, 0x308f, 0x0000 }, + { 0x0700, 0x3091, 0x0000 }, + { 0x8700, 0x3094, 0x2000 }, + { 0x0700, 0x3093, 0x0000 }, + { 0x0700, 0x3095, 0x0000 }, + { 0x9800, 0x309c, 0x3000 }, + { 0x8c00, 0x309a, 0x2000 }, + { 0x0c00, 0x3099, 0x0000 }, + { 0x1800, 0x309b, 0x0000 }, + { 0x8600, 0x309e, 0x2000 }, + { 0x0600, 0x309d, 0x0000 }, + { 0x0700, 0x309f, 0x0000 }, + { 0x8700, 0x30b0, 0x5000 }, + { 0x8700, 0x30a8, 0x4000 }, + { 0x8700, 0x30a4, 0x3000 }, + { 0x8700, 0x30a2, 0x2000 }, + { 0x0700, 0x30a1, 0x0000 }, + { 0x0700, 0x30a3, 0x0000 }, + { 0x8700, 0x30a6, 0x2000 }, + { 0x0700, 0x30a5, 0x0000 }, + { 0x0700, 0x30a7, 0x0000 }, + { 0x8700, 0x30ac, 0x3000 }, + { 0x8700, 0x30aa, 0x2000 }, + { 0x0700, 0x30a9, 0x0000 }, + { 0x0700, 0x30ab, 0x0000 }, + { 0x8700, 0x30ae, 0x2000 }, + { 0x0700, 0x30ad, 0x0000 }, + { 0x0700, 0x30af, 0x0000 }, + { 0x8700, 0x30b8, 0x4000 }, + { 0x8700, 0x30b4, 0x3000 }, + { 0x8700, 0x30b2, 0x2000 }, + { 0x0700, 0x30b1, 0x0000 }, + { 0x0700, 0x30b3, 0x0000 }, + { 0x8700, 0x30b6, 0x2000 }, + { 0x0700, 0x30b5, 0x0000 }, + { 0x0700, 0x30b7, 0x0000 }, + { 0x8700, 0x30bc, 0x3000 }, + { 0x8700, 0x30ba, 0x2000 }, + { 0x0700, 0x30b9, 0x0000 }, + { 0x0700, 0x30bb, 0x0000 }, + { 0x8700, 0x30be, 0x2000 }, + { 0x0700, 0x30bd, 0x0000 }, + { 0x0700, 0x30bf, 0x0000 }, + { 0x8700, 0x3105, 0x7000 }, + { 0x8700, 0x30e0, 0x6000 }, + { 0x8700, 0x30d0, 0x5000 }, + { 0x8700, 0x30c8, 0x4000 }, + { 0x8700, 0x30c4, 0x3000 }, + { 0x8700, 0x30c2, 0x2000 }, + { 0x0700, 0x30c1, 0x0000 }, + { 0x0700, 0x30c3, 0x0000 }, + { 0x8700, 0x30c6, 0x2000 }, + { 0x0700, 0x30c5, 0x0000 }, + { 0x0700, 0x30c7, 0x0000 }, + { 0x8700, 0x30cc, 0x3000 }, + { 0x8700, 0x30ca, 0x2000 }, + { 0x0700, 0x30c9, 0x0000 }, + { 0x0700, 0x30cb, 0x0000 }, + { 0x8700, 0x30ce, 0x2000 }, + { 0x0700, 0x30cd, 0x0000 }, + { 0x0700, 0x30cf, 0x0000 }, + { 0x8700, 0x30d8, 0x4000 }, + { 0x8700, 0x30d4, 0x3000 }, + { 0x8700, 0x30d2, 0x2000 }, + { 0x0700, 0x30d1, 0x0000 }, + { 0x0700, 0x30d3, 0x0000 }, + { 0x8700, 0x30d6, 0x2000 }, + { 0x0700, 0x30d5, 0x0000 }, + { 0x0700, 0x30d7, 0x0000 }, + { 0x8700, 0x30dc, 0x3000 }, + { 0x8700, 0x30da, 0x2000 }, + { 0x0700, 0x30d9, 0x0000 }, + { 0x0700, 0x30db, 0x0000 }, + { 0x8700, 0x30de, 0x2000 }, + { 0x0700, 0x30dd, 0x0000 }, + { 0x0700, 0x30df, 0x0000 }, + { 0x8700, 0x30f0, 0x5000 }, + { 0x8700, 0x30e8, 0x4000 }, + { 0x8700, 0x30e4, 0x3000 }, + { 0x8700, 0x30e2, 0x2000 }, + { 0x0700, 0x30e1, 0x0000 }, + { 0x0700, 0x30e3, 0x0000 }, + { 0x8700, 0x30e6, 0x2000 }, + { 0x0700, 0x30e5, 0x0000 }, + { 0x0700, 0x30e7, 0x0000 }, + { 0x8700, 0x30ec, 0x3000 }, + { 0x8700, 0x30ea, 0x2000 }, + { 0x0700, 0x30e9, 0x0000 }, + { 0x0700, 0x30eb, 0x0000 }, + { 0x8700, 0x30ee, 0x2000 }, + { 0x0700, 0x30ed, 0x0000 }, + { 0x0700, 0x30ef, 0x0000 }, + { 0x8700, 0x30f8, 0x4000 }, + { 0x8700, 0x30f4, 0x3000 }, + { 0x8700, 0x30f2, 0x2000 }, + { 0x0700, 0x30f1, 0x0000 }, + { 0x0700, 0x30f3, 0x0000 }, + { 0x8700, 0x30f6, 0x2000 }, + { 0x0700, 0x30f5, 0x0000 }, + { 0x0700, 0x30f7, 0x0000 }, + { 0x8600, 0x30fc, 0x3000 }, + { 0x8700, 0x30fa, 0x2000 }, + { 0x0700, 0x30f9, 0x0000 }, + { 0x1000, 0x30fb, 0x0000 }, + { 0x8600, 0x30fe, 0x2000 }, + { 0x0600, 0x30fd, 0x0000 }, + { 0x0700, 0x30ff, 0x0000 }, + { 0x8700, 0x3125, 0x6000 }, + { 0x8700, 0x3115, 0x5000 }, + { 0x8700, 0x310d, 0x4000 }, + { 0x8700, 0x3109, 0x3000 }, + { 0x8700, 0x3107, 0x2000 }, + { 0x0700, 0x3106, 0x0000 }, + { 0x0700, 0x3108, 0x0000 }, + { 0x8700, 0x310b, 0x2000 }, + { 0x0700, 0x310a, 0x0000 }, + { 0x0700, 0x310c, 0x0000 }, + { 0x8700, 0x3111, 0x3000 }, + { 0x8700, 0x310f, 0x2000 }, + { 0x0700, 0x310e, 0x0000 }, + { 0x0700, 0x3110, 0x0000 }, + { 0x8700, 0x3113, 0x2000 }, + { 0x0700, 0x3112, 0x0000 }, + { 0x0700, 0x3114, 0x0000 }, + { 0x8700, 0x311d, 0x4000 }, + { 0x8700, 0x3119, 0x3000 }, + { 0x8700, 0x3117, 0x2000 }, + { 0x0700, 0x3116, 0x0000 }, + { 0x0700, 0x3118, 0x0000 }, + { 0x8700, 0x311b, 0x2000 }, + { 0x0700, 0x311a, 0x0000 }, + { 0x0700, 0x311c, 0x0000 }, + { 0x8700, 0x3121, 0x3000 }, + { 0x8700, 0x311f, 0x2000 }, + { 0x0700, 0x311e, 0x0000 }, + { 0x0700, 0x3120, 0x0000 }, + { 0x8700, 0x3123, 0x2000 }, + { 0x0700, 0x3122, 0x0000 }, + { 0x0700, 0x3124, 0x0000 }, + { 0x8700, 0x3139, 0x5000 }, + { 0x8700, 0x3131, 0x4000 }, + { 0x8700, 0x3129, 0x3000 }, + { 0x8700, 0x3127, 0x2000 }, + { 0x0700, 0x3126, 0x0000 }, + { 0x0700, 0x3128, 0x0000 }, + { 0x8700, 0x312b, 0x2000 }, + { 0x0700, 0x312a, 0x0000 }, + { 0x0700, 0x312c, 0x0000 }, + { 0x8700, 0x3135, 0x3000 }, + { 0x8700, 0x3133, 0x2000 }, + { 0x0700, 0x3132, 0x0000 }, + { 0x0700, 0x3134, 0x0000 }, + { 0x8700, 0x3137, 0x2000 }, + { 0x0700, 0x3136, 0x0000 }, + { 0x0700, 0x3138, 0x0000 }, + { 0x8700, 0x3141, 0x4000 }, + { 0x8700, 0x313d, 0x3000 }, + { 0x8700, 0x313b, 0x2000 }, + { 0x0700, 0x313a, 0x0000 }, + { 0x0700, 0x313c, 0x0000 }, + { 0x8700, 0x313f, 0x2000 }, + { 0x0700, 0x313e, 0x0000 }, + { 0x0700, 0x3140, 0x0000 }, + { 0x8700, 0x3145, 0x3000 }, + { 0x8700, 0x3143, 0x2000 }, + { 0x0700, 0x3142, 0x0000 }, + { 0x0700, 0x3144, 0x0000 }, + { 0x8700, 0x3147, 0x2000 }, + { 0x0700, 0x3146, 0x0000 }, + { 0x0700, 0x3148, 0x0000 }, + { 0x9a00, 0x3290, 0x9000 }, + { 0x9a00, 0x3202, 0x8000 }, + { 0x8700, 0x3189, 0x7000 }, + { 0x8700, 0x3169, 0x6000 }, + { 0x8700, 0x3159, 0x5000 }, + { 0x8700, 0x3151, 0x4000 }, + { 0x8700, 0x314d, 0x3000 }, + { 0x8700, 0x314b, 0x2000 }, + { 0x0700, 0x314a, 0x0000 }, + { 0x0700, 0x314c, 0x0000 }, + { 0x8700, 0x314f, 0x2000 }, + { 0x0700, 0x314e, 0x0000 }, + { 0x0700, 0x3150, 0x0000 }, + { 0x8700, 0x3155, 0x3000 }, + { 0x8700, 0x3153, 0x2000 }, + { 0x0700, 0x3152, 0x0000 }, + { 0x0700, 0x3154, 0x0000 }, + { 0x8700, 0x3157, 0x2000 }, + { 0x0700, 0x3156, 0x0000 }, + { 0x0700, 0x3158, 0x0000 }, + { 0x8700, 0x3161, 0x4000 }, + { 0x8700, 0x315d, 0x3000 }, + { 0x8700, 0x315b, 0x2000 }, + { 0x0700, 0x315a, 0x0000 }, + { 0x0700, 0x315c, 0x0000 }, + { 0x8700, 0x315f, 0x2000 }, + { 0x0700, 0x315e, 0x0000 }, + { 0x0700, 0x3160, 0x0000 }, + { 0x8700, 0x3165, 0x3000 }, + { 0x8700, 0x3163, 0x2000 }, + { 0x0700, 0x3162, 0x0000 }, + { 0x0700, 0x3164, 0x0000 }, + { 0x8700, 0x3167, 0x2000 }, + { 0x0700, 0x3166, 0x0000 }, + { 0x0700, 0x3168, 0x0000 }, + { 0x8700, 0x3179, 0x5000 }, + { 0x8700, 0x3171, 0x4000 }, + { 0x8700, 0x316d, 0x3000 }, + { 0x8700, 0x316b, 0x2000 }, + { 0x0700, 0x316a, 0x0000 }, + { 0x0700, 0x316c, 0x0000 }, + { 0x8700, 0x316f, 0x2000 }, + { 0x0700, 0x316e, 0x0000 }, + { 0x0700, 0x3170, 0x0000 }, + { 0x8700, 0x3175, 0x3000 }, + { 0x8700, 0x3173, 0x2000 }, + { 0x0700, 0x3172, 0x0000 }, + { 0x0700, 0x3174, 0x0000 }, + { 0x8700, 0x3177, 0x2000 }, + { 0x0700, 0x3176, 0x0000 }, + { 0x0700, 0x3178, 0x0000 }, + { 0x8700, 0x3181, 0x4000 }, + { 0x8700, 0x317d, 0x3000 }, + { 0x8700, 0x317b, 0x2000 }, + { 0x0700, 0x317a, 0x0000 }, + { 0x0700, 0x317c, 0x0000 }, + { 0x8700, 0x317f, 0x2000 }, + { 0x0700, 0x317e, 0x0000 }, + { 0x0700, 0x3180, 0x0000 }, + { 0x8700, 0x3185, 0x3000 }, + { 0x8700, 0x3183, 0x2000 }, + { 0x0700, 0x3182, 0x0000 }, + { 0x0700, 0x3184, 0x0000 }, + { 0x8700, 0x3187, 0x2000 }, + { 0x0700, 0x3186, 0x0000 }, + { 0x0700, 0x3188, 0x0000 }, + { 0x8700, 0x31aa, 0x6000 }, + { 0x9a00, 0x319a, 0x5000 }, + { 0x8f00, 0x3192, 0x4000 }, + { 0x8700, 0x318d, 0x3000 }, + { 0x8700, 0x318b, 0x2000 }, + { 0x0700, 0x318a, 0x0000 }, + { 0x0700, 0x318c, 0x0000 }, + { 0x9a00, 0x3190, 0x2000 }, + { 0x0700, 0x318e, 0x0000 }, + { 0x1a00, 0x3191, 0x0000 }, + { 0x9a00, 0x3196, 0x3000 }, + { 0x8f00, 0x3194, 0x2000 }, + { 0x0f00, 0x3193, 0x0000 }, + { 0x0f00, 0x3195, 0x0000 }, + { 0x9a00, 0x3198, 0x2000 }, + { 0x1a00, 0x3197, 0x0000 }, + { 0x1a00, 0x3199, 0x0000 }, + { 0x8700, 0x31a2, 0x4000 }, + { 0x9a00, 0x319e, 0x3000 }, + { 0x9a00, 0x319c, 0x2000 }, + { 0x1a00, 0x319b, 0x0000 }, + { 0x1a00, 0x319d, 0x0000 }, + { 0x8700, 0x31a0, 0x2000 }, + { 0x1a00, 0x319f, 0x0000 }, + { 0x0700, 0x31a1, 0x0000 }, + { 0x8700, 0x31a6, 0x3000 }, + { 0x8700, 0x31a4, 0x2000 }, + { 0x0700, 0x31a3, 0x0000 }, + { 0x0700, 0x31a5, 0x0000 }, + { 0x8700, 0x31a8, 0x2000 }, + { 0x0700, 0x31a7, 0x0000 }, + { 0x0700, 0x31a9, 0x0000 }, + { 0x8700, 0x31f2, 0x5000 }, + { 0x8700, 0x31b2, 0x4000 }, + { 0x8700, 0x31ae, 0x3000 }, + { 0x8700, 0x31ac, 0x2000 }, + { 0x0700, 0x31ab, 0x0000 }, + { 0x0700, 0x31ad, 0x0000 }, + { 0x8700, 0x31b0, 0x2000 }, + { 0x0700, 0x31af, 0x0000 }, + { 0x0700, 0x31b1, 0x0000 }, + { 0x8700, 0x31b6, 0x3000 }, + { 0x8700, 0x31b4, 0x2000 }, + { 0x0700, 0x31b3, 0x0000 }, + { 0x0700, 0x31b5, 0x0000 }, + { 0x8700, 0x31f0, 0x2000 }, + { 0x0700, 0x31b7, 0x0000 }, + { 0x0700, 0x31f1, 0x0000 }, + { 0x8700, 0x31fa, 0x4000 }, + { 0x8700, 0x31f6, 0x3000 }, + { 0x8700, 0x31f4, 0x2000 }, + { 0x0700, 0x31f3, 0x0000 }, + { 0x0700, 0x31f5, 0x0000 }, + { 0x8700, 0x31f8, 0x2000 }, + { 0x0700, 0x31f7, 0x0000 }, + { 0x0700, 0x31f9, 0x0000 }, + { 0x8700, 0x31fe, 0x3000 }, + { 0x8700, 0x31fc, 0x2000 }, + { 0x0700, 0x31fb, 0x0000 }, + { 0x0700, 0x31fd, 0x0000 }, + { 0x9a00, 0x3200, 0x2000 }, + { 0x0700, 0x31ff, 0x0000 }, + { 0x1a00, 0x3201, 0x0000 }, + { 0x9a00, 0x3243, 0x7000 }, + { 0x8f00, 0x3223, 0x6000 }, + { 0x9a00, 0x3212, 0x5000 }, + { 0x9a00, 0x320a, 0x4000 }, + { 0x9a00, 0x3206, 0x3000 }, + { 0x9a00, 0x3204, 0x2000 }, + { 0x1a00, 0x3203, 0x0000 }, + { 0x1a00, 0x3205, 0x0000 }, + { 0x9a00, 0x3208, 0x2000 }, + { 0x1a00, 0x3207, 0x0000 }, + { 0x1a00, 0x3209, 0x0000 }, + { 0x9a00, 0x320e, 0x3000 }, + { 0x9a00, 0x320c, 0x2000 }, + { 0x1a00, 0x320b, 0x0000 }, + { 0x1a00, 0x320d, 0x0000 }, + { 0x9a00, 0x3210, 0x2000 }, + { 0x1a00, 0x320f, 0x0000 }, + { 0x1a00, 0x3211, 0x0000 }, + { 0x9a00, 0x321a, 0x4000 }, + { 0x9a00, 0x3216, 0x3000 }, + { 0x9a00, 0x3214, 0x2000 }, + { 0x1a00, 0x3213, 0x0000 }, + { 0x1a00, 0x3215, 0x0000 }, + { 0x9a00, 0x3218, 0x2000 }, + { 0x1a00, 0x3217, 0x0000 }, + { 0x1a00, 0x3219, 0x0000 }, + { 0x9a00, 0x321e, 0x3000 }, + { 0x9a00, 0x321c, 0x2000 }, + { 0x1a00, 0x321b, 0x0000 }, + { 0x1a00, 0x321d, 0x0000 }, + { 0x8f00, 0x3221, 0x2000 }, + { 0x0f00, 0x3220, 0x0000 }, + { 0x0f00, 0x3222, 0x0000 }, + { 0x9a00, 0x3233, 0x5000 }, + { 0x9a00, 0x322b, 0x4000 }, + { 0x8f00, 0x3227, 0x3000 }, + { 0x8f00, 0x3225, 0x2000 }, + { 0x0f00, 0x3224, 0x0000 }, + { 0x0f00, 0x3226, 0x0000 }, + { 0x8f00, 0x3229, 0x2000 }, + { 0x0f00, 0x3228, 0x0000 }, + { 0x1a00, 0x322a, 0x0000 }, + { 0x9a00, 0x322f, 0x3000 }, + { 0x9a00, 0x322d, 0x2000 }, + { 0x1a00, 0x322c, 0x0000 }, + { 0x1a00, 0x322e, 0x0000 }, + { 0x9a00, 0x3231, 0x2000 }, + { 0x1a00, 0x3230, 0x0000 }, + { 0x1a00, 0x3232, 0x0000 }, + { 0x9a00, 0x323b, 0x4000 }, + { 0x9a00, 0x3237, 0x3000 }, + { 0x9a00, 0x3235, 0x2000 }, + { 0x1a00, 0x3234, 0x0000 }, + { 0x1a00, 0x3236, 0x0000 }, + { 0x9a00, 0x3239, 0x2000 }, + { 0x1a00, 0x3238, 0x0000 }, + { 0x1a00, 0x323a, 0x0000 }, + { 0x9a00, 0x323f, 0x3000 }, + { 0x9a00, 0x323d, 0x2000 }, + { 0x1a00, 0x323c, 0x0000 }, + { 0x1a00, 0x323e, 0x0000 }, + { 0x9a00, 0x3241, 0x2000 }, + { 0x1a00, 0x3240, 0x0000 }, + { 0x1a00, 0x3242, 0x0000 }, + { 0x9a00, 0x326f, 0x6000 }, + { 0x8f00, 0x325f, 0x5000 }, + { 0x8f00, 0x3257, 0x4000 }, + { 0x8f00, 0x3253, 0x3000 }, + { 0x8f00, 0x3251, 0x2000 }, + { 0x1a00, 0x3250, 0x0000 }, + { 0x0f00, 0x3252, 0x0000 }, + { 0x8f00, 0x3255, 0x2000 }, + { 0x0f00, 0x3254, 0x0000 }, + { 0x0f00, 0x3256, 0x0000 }, + { 0x8f00, 0x325b, 0x3000 }, + { 0x8f00, 0x3259, 0x2000 }, + { 0x0f00, 0x3258, 0x0000 }, + { 0x0f00, 0x325a, 0x0000 }, + { 0x8f00, 0x325d, 0x2000 }, + { 0x0f00, 0x325c, 0x0000 }, + { 0x0f00, 0x325e, 0x0000 }, + { 0x9a00, 0x3267, 0x4000 }, + { 0x9a00, 0x3263, 0x3000 }, + { 0x9a00, 0x3261, 0x2000 }, + { 0x1a00, 0x3260, 0x0000 }, + { 0x1a00, 0x3262, 0x0000 }, + { 0x9a00, 0x3265, 0x2000 }, + { 0x1a00, 0x3264, 0x0000 }, + { 0x1a00, 0x3266, 0x0000 }, + { 0x9a00, 0x326b, 0x3000 }, + { 0x9a00, 0x3269, 0x2000 }, + { 0x1a00, 0x3268, 0x0000 }, + { 0x1a00, 0x326a, 0x0000 }, + { 0x9a00, 0x326d, 0x2000 }, + { 0x1a00, 0x326c, 0x0000 }, + { 0x1a00, 0x326e, 0x0000 }, + { 0x8f00, 0x3280, 0x5000 }, + { 0x9a00, 0x3277, 0x4000 }, + { 0x9a00, 0x3273, 0x3000 }, + { 0x9a00, 0x3271, 0x2000 }, + { 0x1a00, 0x3270, 0x0000 }, + { 0x1a00, 0x3272, 0x0000 }, + { 0x9a00, 0x3275, 0x2000 }, + { 0x1a00, 0x3274, 0x0000 }, + { 0x1a00, 0x3276, 0x0000 }, + { 0x9a00, 0x327b, 0x3000 }, + { 0x9a00, 0x3279, 0x2000 }, + { 0x1a00, 0x3278, 0x0000 }, + { 0x1a00, 0x327a, 0x0000 }, + { 0x9a00, 0x327d, 0x2000 }, + { 0x1a00, 0x327c, 0x0000 }, + { 0x1a00, 0x327f, 0x0000 }, + { 0x8f00, 0x3288, 0x4000 }, + { 0x8f00, 0x3284, 0x3000 }, + { 0x8f00, 0x3282, 0x2000 }, + { 0x0f00, 0x3281, 0x0000 }, + { 0x0f00, 0x3283, 0x0000 }, + { 0x8f00, 0x3286, 0x2000 }, + { 0x0f00, 0x3285, 0x0000 }, + { 0x0f00, 0x3287, 0x0000 }, + { 0x9a00, 0x328c, 0x3000 }, + { 0x9a00, 0x328a, 0x2000 }, + { 0x0f00, 0x3289, 0x0000 }, + { 0x1a00, 0x328b, 0x0000 }, + { 0x9a00, 0x328e, 0x2000 }, + { 0x1a00, 0x328d, 0x0000 }, + { 0x1a00, 0x328f, 0x0000 }, + { 0x9a00, 0x3311, 0x8000 }, + { 0x9a00, 0x32d0, 0x7000 }, + { 0x9a00, 0x32b0, 0x6000 }, + { 0x9a00, 0x32a0, 0x5000 }, + { 0x9a00, 0x3298, 0x4000 }, + { 0x9a00, 0x3294, 0x3000 }, + { 0x9a00, 0x3292, 0x2000 }, + { 0x1a00, 0x3291, 0x0000 }, + { 0x1a00, 0x3293, 0x0000 }, + { 0x9a00, 0x3296, 0x2000 }, + { 0x1a00, 0x3295, 0x0000 }, + { 0x1a00, 0x3297, 0x0000 }, + { 0x9a00, 0x329c, 0x3000 }, + { 0x9a00, 0x329a, 0x2000 }, + { 0x1a00, 0x3299, 0x0000 }, + { 0x1a00, 0x329b, 0x0000 }, + { 0x9a00, 0x329e, 0x2000 }, + { 0x1a00, 0x329d, 0x0000 }, + { 0x1a00, 0x329f, 0x0000 }, + { 0x9a00, 0x32a8, 0x4000 }, + { 0x9a00, 0x32a4, 0x3000 }, + { 0x9a00, 0x32a2, 0x2000 }, + { 0x1a00, 0x32a1, 0x0000 }, + { 0x1a00, 0x32a3, 0x0000 }, + { 0x9a00, 0x32a6, 0x2000 }, + { 0x1a00, 0x32a5, 0x0000 }, + { 0x1a00, 0x32a7, 0x0000 }, + { 0x9a00, 0x32ac, 0x3000 }, + { 0x9a00, 0x32aa, 0x2000 }, + { 0x1a00, 0x32a9, 0x0000 }, + { 0x1a00, 0x32ab, 0x0000 }, + { 0x9a00, 0x32ae, 0x2000 }, + { 0x1a00, 0x32ad, 0x0000 }, + { 0x1a00, 0x32af, 0x0000 }, + { 0x9a00, 0x32c0, 0x5000 }, + { 0x8f00, 0x32b8, 0x4000 }, + { 0x8f00, 0x32b4, 0x3000 }, + { 0x8f00, 0x32b2, 0x2000 }, + { 0x0f00, 0x32b1, 0x0000 }, + { 0x0f00, 0x32b3, 0x0000 }, + { 0x8f00, 0x32b6, 0x2000 }, + { 0x0f00, 0x32b5, 0x0000 }, + { 0x0f00, 0x32b7, 0x0000 }, + { 0x8f00, 0x32bc, 0x3000 }, + { 0x8f00, 0x32ba, 0x2000 }, + { 0x0f00, 0x32b9, 0x0000 }, + { 0x0f00, 0x32bb, 0x0000 }, + { 0x8f00, 0x32be, 0x2000 }, + { 0x0f00, 0x32bd, 0x0000 }, + { 0x0f00, 0x32bf, 0x0000 }, + { 0x9a00, 0x32c8, 0x4000 }, + { 0x9a00, 0x32c4, 0x3000 }, + { 0x9a00, 0x32c2, 0x2000 }, + { 0x1a00, 0x32c1, 0x0000 }, + { 0x1a00, 0x32c3, 0x0000 }, + { 0x9a00, 0x32c6, 0x2000 }, + { 0x1a00, 0x32c5, 0x0000 }, + { 0x1a00, 0x32c7, 0x0000 }, + { 0x9a00, 0x32cc, 0x3000 }, + { 0x9a00, 0x32ca, 0x2000 }, + { 0x1a00, 0x32c9, 0x0000 }, + { 0x1a00, 0x32cb, 0x0000 }, + { 0x9a00, 0x32ce, 0x2000 }, + { 0x1a00, 0x32cd, 0x0000 }, + { 0x1a00, 0x32cf, 0x0000 }, + { 0x9a00, 0x32f0, 0x6000 }, + { 0x9a00, 0x32e0, 0x5000 }, + { 0x9a00, 0x32d8, 0x4000 }, + { 0x9a00, 0x32d4, 0x3000 }, + { 0x9a00, 0x32d2, 0x2000 }, + { 0x1a00, 0x32d1, 0x0000 }, + { 0x1a00, 0x32d3, 0x0000 }, + { 0x9a00, 0x32d6, 0x2000 }, + { 0x1a00, 0x32d5, 0x0000 }, + { 0x1a00, 0x32d7, 0x0000 }, + { 0x9a00, 0x32dc, 0x3000 }, + { 0x9a00, 0x32da, 0x2000 }, + { 0x1a00, 0x32d9, 0x0000 }, + { 0x1a00, 0x32db, 0x0000 }, + { 0x9a00, 0x32de, 0x2000 }, + { 0x1a00, 0x32dd, 0x0000 }, + { 0x1a00, 0x32df, 0x0000 }, + { 0x9a00, 0x32e8, 0x4000 }, + { 0x9a00, 0x32e4, 0x3000 }, + { 0x9a00, 0x32e2, 0x2000 }, + { 0x1a00, 0x32e1, 0x0000 }, + { 0x1a00, 0x32e3, 0x0000 }, + { 0x9a00, 0x32e6, 0x2000 }, + { 0x1a00, 0x32e5, 0x0000 }, + { 0x1a00, 0x32e7, 0x0000 }, + { 0x9a00, 0x32ec, 0x3000 }, + { 0x9a00, 0x32ea, 0x2000 }, + { 0x1a00, 0x32e9, 0x0000 }, + { 0x1a00, 0x32eb, 0x0000 }, + { 0x9a00, 0x32ee, 0x2000 }, + { 0x1a00, 0x32ed, 0x0000 }, + { 0x1a00, 0x32ef, 0x0000 }, + { 0x9a00, 0x3301, 0x5000 }, + { 0x9a00, 0x32f8, 0x4000 }, + { 0x9a00, 0x32f4, 0x3000 }, + { 0x9a00, 0x32f2, 0x2000 }, + { 0x1a00, 0x32f1, 0x0000 }, + { 0x1a00, 0x32f3, 0x0000 }, + { 0x9a00, 0x32f6, 0x2000 }, + { 0x1a00, 0x32f5, 0x0000 }, + { 0x1a00, 0x32f7, 0x0000 }, + { 0x9a00, 0x32fc, 0x3000 }, + { 0x9a00, 0x32fa, 0x2000 }, + { 0x1a00, 0x32f9, 0x0000 }, + { 0x1a00, 0x32fb, 0x0000 }, + { 0x9a00, 0x32fe, 0x2000 }, + { 0x1a00, 0x32fd, 0x0000 }, + { 0x1a00, 0x3300, 0x0000 }, + { 0x9a00, 0x3309, 0x4000 }, + { 0x9a00, 0x3305, 0x3000 }, + { 0x9a00, 0x3303, 0x2000 }, + { 0x1a00, 0x3302, 0x0000 }, + { 0x1a00, 0x3304, 0x0000 }, + { 0x9a00, 0x3307, 0x2000 }, + { 0x1a00, 0x3306, 0x0000 }, + { 0x1a00, 0x3308, 0x0000 }, + { 0x9a00, 0x330d, 0x3000 }, + { 0x9a00, 0x330b, 0x2000 }, + { 0x1a00, 0x330a, 0x0000 }, + { 0x1a00, 0x330c, 0x0000 }, + { 0x9a00, 0x330f, 0x2000 }, + { 0x1a00, 0x330e, 0x0000 }, + { 0x1a00, 0x3310, 0x0000 }, + { 0x9a00, 0x3351, 0x7000 }, + { 0x9a00, 0x3331, 0x6000 }, + { 0x9a00, 0x3321, 0x5000 }, + { 0x9a00, 0x3319, 0x4000 }, + { 0x9a00, 0x3315, 0x3000 }, + { 0x9a00, 0x3313, 0x2000 }, + { 0x1a00, 0x3312, 0x0000 }, + { 0x1a00, 0x3314, 0x0000 }, + { 0x9a00, 0x3317, 0x2000 }, + { 0x1a00, 0x3316, 0x0000 }, + { 0x1a00, 0x3318, 0x0000 }, + { 0x9a00, 0x331d, 0x3000 }, + { 0x9a00, 0x331b, 0x2000 }, + { 0x1a00, 0x331a, 0x0000 }, + { 0x1a00, 0x331c, 0x0000 }, + { 0x9a00, 0x331f, 0x2000 }, + { 0x1a00, 0x331e, 0x0000 }, + { 0x1a00, 0x3320, 0x0000 }, + { 0x9a00, 0x3329, 0x4000 }, + { 0x9a00, 0x3325, 0x3000 }, + { 0x9a00, 0x3323, 0x2000 }, + { 0x1a00, 0x3322, 0x0000 }, + { 0x1a00, 0x3324, 0x0000 }, + { 0x9a00, 0x3327, 0x2000 }, + { 0x1a00, 0x3326, 0x0000 }, + { 0x1a00, 0x3328, 0x0000 }, + { 0x9a00, 0x332d, 0x3000 }, + { 0x9a00, 0x332b, 0x2000 }, + { 0x1a00, 0x332a, 0x0000 }, + { 0x1a00, 0x332c, 0x0000 }, + { 0x9a00, 0x332f, 0x2000 }, + { 0x1a00, 0x332e, 0x0000 }, + { 0x1a00, 0x3330, 0x0000 }, + { 0x9a00, 0x3341, 0x5000 }, + { 0x9a00, 0x3339, 0x4000 }, + { 0x9a00, 0x3335, 0x3000 }, + { 0x9a00, 0x3333, 0x2000 }, + { 0x1a00, 0x3332, 0x0000 }, + { 0x1a00, 0x3334, 0x0000 }, + { 0x9a00, 0x3337, 0x2000 }, + { 0x1a00, 0x3336, 0x0000 }, + { 0x1a00, 0x3338, 0x0000 }, + { 0x9a00, 0x333d, 0x3000 }, + { 0x9a00, 0x333b, 0x2000 }, + { 0x1a00, 0x333a, 0x0000 }, + { 0x1a00, 0x333c, 0x0000 }, + { 0x9a00, 0x333f, 0x2000 }, + { 0x1a00, 0x333e, 0x0000 }, + { 0x1a00, 0x3340, 0x0000 }, + { 0x9a00, 0x3349, 0x4000 }, + { 0x9a00, 0x3345, 0x3000 }, + { 0x9a00, 0x3343, 0x2000 }, + { 0x1a00, 0x3342, 0x0000 }, + { 0x1a00, 0x3344, 0x0000 }, + { 0x9a00, 0x3347, 0x2000 }, + { 0x1a00, 0x3346, 0x0000 }, + { 0x1a00, 0x3348, 0x0000 }, + { 0x9a00, 0x334d, 0x3000 }, + { 0x9a00, 0x334b, 0x2000 }, + { 0x1a00, 0x334a, 0x0000 }, + { 0x1a00, 0x334c, 0x0000 }, + { 0x9a00, 0x334f, 0x2000 }, + { 0x1a00, 0x334e, 0x0000 }, + { 0x1a00, 0x3350, 0x0000 }, + { 0x9a00, 0x3371, 0x6000 }, + { 0x9a00, 0x3361, 0x5000 }, + { 0x9a00, 0x3359, 0x4000 }, + { 0x9a00, 0x3355, 0x3000 }, + { 0x9a00, 0x3353, 0x2000 }, + { 0x1a00, 0x3352, 0x0000 }, + { 0x1a00, 0x3354, 0x0000 }, + { 0x9a00, 0x3357, 0x2000 }, + { 0x1a00, 0x3356, 0x0000 }, + { 0x1a00, 0x3358, 0x0000 }, + { 0x9a00, 0x335d, 0x3000 }, + { 0x9a00, 0x335b, 0x2000 }, + { 0x1a00, 0x335a, 0x0000 }, + { 0x1a00, 0x335c, 0x0000 }, + { 0x9a00, 0x335f, 0x2000 }, + { 0x1a00, 0x335e, 0x0000 }, + { 0x1a00, 0x3360, 0x0000 }, + { 0x9a00, 0x3369, 0x4000 }, + { 0x9a00, 0x3365, 0x3000 }, + { 0x9a00, 0x3363, 0x2000 }, + { 0x1a00, 0x3362, 0x0000 }, + { 0x1a00, 0x3364, 0x0000 }, + { 0x9a00, 0x3367, 0x2000 }, + { 0x1a00, 0x3366, 0x0000 }, + { 0x1a00, 0x3368, 0x0000 }, + { 0x9a00, 0x336d, 0x3000 }, + { 0x9a00, 0x336b, 0x2000 }, + { 0x1a00, 0x336a, 0x0000 }, + { 0x1a00, 0x336c, 0x0000 }, + { 0x9a00, 0x336f, 0x2000 }, + { 0x1a00, 0x336e, 0x0000 }, + { 0x1a00, 0x3370, 0x0000 }, + { 0x9a00, 0x3381, 0x5000 }, + { 0x9a00, 0x3379, 0x4000 }, + { 0x9a00, 0x3375, 0x3000 }, + { 0x9a00, 0x3373, 0x2000 }, + { 0x1a00, 0x3372, 0x0000 }, + { 0x1a00, 0x3374, 0x0000 }, + { 0x9a00, 0x3377, 0x2000 }, + { 0x1a00, 0x3376, 0x0000 }, + { 0x1a00, 0x3378, 0x0000 }, + { 0x9a00, 0x337d, 0x3000 }, + { 0x9a00, 0x337b, 0x2000 }, + { 0x1a00, 0x337a, 0x0000 }, + { 0x1a00, 0x337c, 0x0000 }, + { 0x9a00, 0x337f, 0x2000 }, + { 0x1a00, 0x337e, 0x0000 }, + { 0x1a00, 0x3380, 0x0000 }, + { 0x9a00, 0x3389, 0x4000 }, + { 0x9a00, 0x3385, 0x3000 }, + { 0x9a00, 0x3383, 0x2000 }, + { 0x1a00, 0x3382, 0x0000 }, + { 0x1a00, 0x3384, 0x0000 }, + { 0x9a00, 0x3387, 0x2000 }, + { 0x1a00, 0x3386, 0x0000 }, + { 0x1a00, 0x3388, 0x0000 }, + { 0x9a00, 0x338d, 0x3000 }, + { 0x9a00, 0x338b, 0x2000 }, + { 0x1a00, 0x338a, 0x0000 }, + { 0x1a00, 0x338c, 0x0000 }, + { 0x9a00, 0x338f, 0x2000 }, + { 0x1a00, 0x338e, 0x0000 }, + { 0x1a00, 0x3390, 0x0000 }, + { 0x8700, 0xa14d, 0xa000 }, + { 0x8700, 0xa04d, 0x9000 }, + { 0x9a00, 0x4dcf, 0x8000 }, + { 0x9a00, 0x33d1, 0x7000 }, + { 0x9a00, 0x33b1, 0x6000 }, + { 0x9a00, 0x33a1, 0x5000 }, + { 0x9a00, 0x3399, 0x4000 }, + { 0x9a00, 0x3395, 0x3000 }, + { 0x9a00, 0x3393, 0x2000 }, + { 0x1a00, 0x3392, 0x0000 }, + { 0x1a00, 0x3394, 0x0000 }, + { 0x9a00, 0x3397, 0x2000 }, + { 0x1a00, 0x3396, 0x0000 }, + { 0x1a00, 0x3398, 0x0000 }, + { 0x9a00, 0x339d, 0x3000 }, + { 0x9a00, 0x339b, 0x2000 }, + { 0x1a00, 0x339a, 0x0000 }, + { 0x1a00, 0x339c, 0x0000 }, + { 0x9a00, 0x339f, 0x2000 }, + { 0x1a00, 0x339e, 0x0000 }, + { 0x1a00, 0x33a0, 0x0000 }, + { 0x9a00, 0x33a9, 0x4000 }, + { 0x9a00, 0x33a5, 0x3000 }, + { 0x9a00, 0x33a3, 0x2000 }, + { 0x1a00, 0x33a2, 0x0000 }, + { 0x1a00, 0x33a4, 0x0000 }, + { 0x9a00, 0x33a7, 0x2000 }, + { 0x1a00, 0x33a6, 0x0000 }, + { 0x1a00, 0x33a8, 0x0000 }, + { 0x9a00, 0x33ad, 0x3000 }, + { 0x9a00, 0x33ab, 0x2000 }, + { 0x1a00, 0x33aa, 0x0000 }, + { 0x1a00, 0x33ac, 0x0000 }, + { 0x9a00, 0x33af, 0x2000 }, + { 0x1a00, 0x33ae, 0x0000 }, + { 0x1a00, 0x33b0, 0x0000 }, + { 0x9a00, 0x33c1, 0x5000 }, + { 0x9a00, 0x33b9, 0x4000 }, + { 0x9a00, 0x33b5, 0x3000 }, + { 0x9a00, 0x33b3, 0x2000 }, + { 0x1a00, 0x33b2, 0x0000 }, + { 0x1a00, 0x33b4, 0x0000 }, + { 0x9a00, 0x33b7, 0x2000 }, + { 0x1a00, 0x33b6, 0x0000 }, + { 0x1a00, 0x33b8, 0x0000 }, + { 0x9a00, 0x33bd, 0x3000 }, + { 0x9a00, 0x33bb, 0x2000 }, + { 0x1a00, 0x33ba, 0x0000 }, + { 0x1a00, 0x33bc, 0x0000 }, + { 0x9a00, 0x33bf, 0x2000 }, + { 0x1a00, 0x33be, 0x0000 }, + { 0x1a00, 0x33c0, 0x0000 }, + { 0x9a00, 0x33c9, 0x4000 }, + { 0x9a00, 0x33c5, 0x3000 }, + { 0x9a00, 0x33c3, 0x2000 }, + { 0x1a00, 0x33c2, 0x0000 }, + { 0x1a00, 0x33c4, 0x0000 }, + { 0x9a00, 0x33c7, 0x2000 }, + { 0x1a00, 0x33c6, 0x0000 }, + { 0x1a00, 0x33c8, 0x0000 }, + { 0x9a00, 0x33cd, 0x3000 }, + { 0x9a00, 0x33cb, 0x2000 }, + { 0x1a00, 0x33ca, 0x0000 }, + { 0x1a00, 0x33cc, 0x0000 }, + { 0x9a00, 0x33cf, 0x2000 }, + { 0x1a00, 0x33ce, 0x0000 }, + { 0x1a00, 0x33d0, 0x0000 }, + { 0x9a00, 0x33f1, 0x6000 }, + { 0x9a00, 0x33e1, 0x5000 }, + { 0x9a00, 0x33d9, 0x4000 }, + { 0x9a00, 0x33d5, 0x3000 }, + { 0x9a00, 0x33d3, 0x2000 }, + { 0x1a00, 0x33d2, 0x0000 }, + { 0x1a00, 0x33d4, 0x0000 }, + { 0x9a00, 0x33d7, 0x2000 }, + { 0x1a00, 0x33d6, 0x0000 }, + { 0x1a00, 0x33d8, 0x0000 }, + { 0x9a00, 0x33dd, 0x3000 }, + { 0x9a00, 0x33db, 0x2000 }, + { 0x1a00, 0x33da, 0x0000 }, + { 0x1a00, 0x33dc, 0x0000 }, + { 0x9a00, 0x33df, 0x2000 }, + { 0x1a00, 0x33de, 0x0000 }, + { 0x1a00, 0x33e0, 0x0000 }, + { 0x9a00, 0x33e9, 0x4000 }, + { 0x9a00, 0x33e5, 0x3000 }, + { 0x9a00, 0x33e3, 0x2000 }, + { 0x1a00, 0x33e2, 0x0000 }, + { 0x1a00, 0x33e4, 0x0000 }, + { 0x9a00, 0x33e7, 0x2000 }, + { 0x1a00, 0x33e6, 0x0000 }, + { 0x1a00, 0x33e8, 0x0000 }, + { 0x9a00, 0x33ed, 0x3000 }, + { 0x9a00, 0x33eb, 0x2000 }, + { 0x1a00, 0x33ea, 0x0000 }, + { 0x1a00, 0x33ec, 0x0000 }, + { 0x9a00, 0x33ef, 0x2000 }, + { 0x1a00, 0x33ee, 0x0000 }, + { 0x1a00, 0x33f0, 0x0000 }, + { 0x8700, 0x4db5, 0x5000 }, + { 0x9a00, 0x33f9, 0x4000 }, + { 0x9a00, 0x33f5, 0x3000 }, + { 0x9a00, 0x33f3, 0x2000 }, + { 0x1a00, 0x33f2, 0x0000 }, + { 0x1a00, 0x33f4, 0x0000 }, + { 0x9a00, 0x33f7, 0x2000 }, + { 0x1a00, 0x33f6, 0x0000 }, + { 0x1a00, 0x33f8, 0x0000 }, + { 0x9a00, 0x33fd, 0x3000 }, + { 0x9a00, 0x33fb, 0x2000 }, + { 0x1a00, 0x33fa, 0x0000 }, + { 0x1a00, 0x33fc, 0x0000 }, + { 0x9a00, 0x33ff, 0x2000 }, + { 0x1a00, 0x33fe, 0x0000 }, + { 0x0700, 0x3400, 0x0000 }, + { 0x9a00, 0x4dc7, 0x4000 }, + { 0x9a00, 0x4dc3, 0x3000 }, + { 0x9a00, 0x4dc1, 0x2000 }, + { 0x1a00, 0x4dc0, 0x0000 }, + { 0x1a00, 0x4dc2, 0x0000 }, + { 0x9a00, 0x4dc5, 0x2000 }, + { 0x1a00, 0x4dc4, 0x0000 }, + { 0x1a00, 0x4dc6, 0x0000 }, + { 0x9a00, 0x4dcb, 0x3000 }, + { 0x9a00, 0x4dc9, 0x2000 }, + { 0x1a00, 0x4dc8, 0x0000 }, + { 0x1a00, 0x4dca, 0x0000 }, + { 0x9a00, 0x4dcd, 0x2000 }, + { 0x1a00, 0x4dcc, 0x0000 }, + { 0x1a00, 0x4dce, 0x0000 }, + { 0x8700, 0xa00d, 0x7000 }, + { 0x9a00, 0x4def, 0x6000 }, + { 0x9a00, 0x4ddf, 0x5000 }, + { 0x9a00, 0x4dd7, 0x4000 }, + { 0x9a00, 0x4dd3, 0x3000 }, + { 0x9a00, 0x4dd1, 0x2000 }, + { 0x1a00, 0x4dd0, 0x0000 }, + { 0x1a00, 0x4dd2, 0x0000 }, + { 0x9a00, 0x4dd5, 0x2000 }, + { 0x1a00, 0x4dd4, 0x0000 }, + { 0x1a00, 0x4dd6, 0x0000 }, + { 0x9a00, 0x4ddb, 0x3000 }, + { 0x9a00, 0x4dd9, 0x2000 }, + { 0x1a00, 0x4dd8, 0x0000 }, + { 0x1a00, 0x4dda, 0x0000 }, + { 0x9a00, 0x4ddd, 0x2000 }, + { 0x1a00, 0x4ddc, 0x0000 }, + { 0x1a00, 0x4dde, 0x0000 }, + { 0x9a00, 0x4de7, 0x4000 }, + { 0x9a00, 0x4de3, 0x3000 }, + { 0x9a00, 0x4de1, 0x2000 }, + { 0x1a00, 0x4de0, 0x0000 }, + { 0x1a00, 0x4de2, 0x0000 }, + { 0x9a00, 0x4de5, 0x2000 }, + { 0x1a00, 0x4de4, 0x0000 }, + { 0x1a00, 0x4de6, 0x0000 }, + { 0x9a00, 0x4deb, 0x3000 }, + { 0x9a00, 0x4de9, 0x2000 }, + { 0x1a00, 0x4de8, 0x0000 }, + { 0x1a00, 0x4dea, 0x0000 }, + { 0x9a00, 0x4ded, 0x2000 }, + { 0x1a00, 0x4dec, 0x0000 }, + { 0x1a00, 0x4dee, 0x0000 }, + { 0x9a00, 0x4dff, 0x5000 }, + { 0x9a00, 0x4df7, 0x4000 }, + { 0x9a00, 0x4df3, 0x3000 }, + { 0x9a00, 0x4df1, 0x2000 }, + { 0x1a00, 0x4df0, 0x0000 }, + { 0x1a00, 0x4df2, 0x0000 }, + { 0x9a00, 0x4df5, 0x2000 }, + { 0x1a00, 0x4df4, 0x0000 }, + { 0x1a00, 0x4df6, 0x0000 }, + { 0x9a00, 0x4dfb, 0x3000 }, + { 0x9a00, 0x4df9, 0x2000 }, + { 0x1a00, 0x4df8, 0x0000 }, + { 0x1a00, 0x4dfa, 0x0000 }, + { 0x9a00, 0x4dfd, 0x2000 }, + { 0x1a00, 0x4dfc, 0x0000 }, + { 0x1a00, 0x4dfe, 0x0000 }, + { 0x8700, 0xa005, 0x4000 }, + { 0x8700, 0xa001, 0x3000 }, + { 0x8700, 0x9fa5, 0x2000 }, + { 0x0700, 0x4e00, 0x0000 }, + { 0x0700, 0xa000, 0x0000 }, + { 0x8700, 0xa003, 0x2000 }, + { 0x0700, 0xa002, 0x0000 }, + { 0x0700, 0xa004, 0x0000 }, + { 0x8700, 0xa009, 0x3000 }, + { 0x8700, 0xa007, 0x2000 }, + { 0x0700, 0xa006, 0x0000 }, + { 0x0700, 0xa008, 0x0000 }, + { 0x8700, 0xa00b, 0x2000 }, + { 0x0700, 0xa00a, 0x0000 }, + { 0x0700, 0xa00c, 0x0000 }, + { 0x8700, 0xa02d, 0x6000 }, + { 0x8700, 0xa01d, 0x5000 }, + { 0x8700, 0xa015, 0x4000 }, + { 0x8700, 0xa011, 0x3000 }, + { 0x8700, 0xa00f, 0x2000 }, + { 0x0700, 0xa00e, 0x0000 }, + { 0x0700, 0xa010, 0x0000 }, + { 0x8700, 0xa013, 0x2000 }, + { 0x0700, 0xa012, 0x0000 }, + { 0x0700, 0xa014, 0x0000 }, + { 0x8700, 0xa019, 0x3000 }, + { 0x8700, 0xa017, 0x2000 }, + { 0x0700, 0xa016, 0x0000 }, + { 0x0700, 0xa018, 0x0000 }, + { 0x8700, 0xa01b, 0x2000 }, + { 0x0700, 0xa01a, 0x0000 }, + { 0x0700, 0xa01c, 0x0000 }, + { 0x8700, 0xa025, 0x4000 }, + { 0x8700, 0xa021, 0x3000 }, + { 0x8700, 0xa01f, 0x2000 }, + { 0x0700, 0xa01e, 0x0000 }, + { 0x0700, 0xa020, 0x0000 }, + { 0x8700, 0xa023, 0x2000 }, + { 0x0700, 0xa022, 0x0000 }, + { 0x0700, 0xa024, 0x0000 }, + { 0x8700, 0xa029, 0x3000 }, + { 0x8700, 0xa027, 0x2000 }, + { 0x0700, 0xa026, 0x0000 }, + { 0x0700, 0xa028, 0x0000 }, + { 0x8700, 0xa02b, 0x2000 }, + { 0x0700, 0xa02a, 0x0000 }, + { 0x0700, 0xa02c, 0x0000 }, + { 0x8700, 0xa03d, 0x5000 }, + { 0x8700, 0xa035, 0x4000 }, + { 0x8700, 0xa031, 0x3000 }, + { 0x8700, 0xa02f, 0x2000 }, + { 0x0700, 0xa02e, 0x0000 }, + { 0x0700, 0xa030, 0x0000 }, + { 0x8700, 0xa033, 0x2000 }, + { 0x0700, 0xa032, 0x0000 }, + { 0x0700, 0xa034, 0x0000 }, + { 0x8700, 0xa039, 0x3000 }, + { 0x8700, 0xa037, 0x2000 }, + { 0x0700, 0xa036, 0x0000 }, + { 0x0700, 0xa038, 0x0000 }, + { 0x8700, 0xa03b, 0x2000 }, + { 0x0700, 0xa03a, 0x0000 }, + { 0x0700, 0xa03c, 0x0000 }, + { 0x8700, 0xa045, 0x4000 }, + { 0x8700, 0xa041, 0x3000 }, + { 0x8700, 0xa03f, 0x2000 }, + { 0x0700, 0xa03e, 0x0000 }, + { 0x0700, 0xa040, 0x0000 }, + { 0x8700, 0xa043, 0x2000 }, + { 0x0700, 0xa042, 0x0000 }, + { 0x0700, 0xa044, 0x0000 }, + { 0x8700, 0xa049, 0x3000 }, + { 0x8700, 0xa047, 0x2000 }, + { 0x0700, 0xa046, 0x0000 }, + { 0x0700, 0xa048, 0x0000 }, + { 0x8700, 0xa04b, 0x2000 }, + { 0x0700, 0xa04a, 0x0000 }, + { 0x0700, 0xa04c, 0x0000 }, + { 0x8700, 0xa0cd, 0x8000 }, + { 0x8700, 0xa08d, 0x7000 }, + { 0x8700, 0xa06d, 0x6000 }, + { 0x8700, 0xa05d, 0x5000 }, + { 0x8700, 0xa055, 0x4000 }, + { 0x8700, 0xa051, 0x3000 }, + { 0x8700, 0xa04f, 0x2000 }, + { 0x0700, 0xa04e, 0x0000 }, + { 0x0700, 0xa050, 0x0000 }, + { 0x8700, 0xa053, 0x2000 }, + { 0x0700, 0xa052, 0x0000 }, + { 0x0700, 0xa054, 0x0000 }, + { 0x8700, 0xa059, 0x3000 }, + { 0x8700, 0xa057, 0x2000 }, + { 0x0700, 0xa056, 0x0000 }, + { 0x0700, 0xa058, 0x0000 }, + { 0x8700, 0xa05b, 0x2000 }, + { 0x0700, 0xa05a, 0x0000 }, + { 0x0700, 0xa05c, 0x0000 }, + { 0x8700, 0xa065, 0x4000 }, + { 0x8700, 0xa061, 0x3000 }, + { 0x8700, 0xa05f, 0x2000 }, + { 0x0700, 0xa05e, 0x0000 }, + { 0x0700, 0xa060, 0x0000 }, + { 0x8700, 0xa063, 0x2000 }, + { 0x0700, 0xa062, 0x0000 }, + { 0x0700, 0xa064, 0x0000 }, + { 0x8700, 0xa069, 0x3000 }, + { 0x8700, 0xa067, 0x2000 }, + { 0x0700, 0xa066, 0x0000 }, + { 0x0700, 0xa068, 0x0000 }, + { 0x8700, 0xa06b, 0x2000 }, + { 0x0700, 0xa06a, 0x0000 }, + { 0x0700, 0xa06c, 0x0000 }, + { 0x8700, 0xa07d, 0x5000 }, + { 0x8700, 0xa075, 0x4000 }, + { 0x8700, 0xa071, 0x3000 }, + { 0x8700, 0xa06f, 0x2000 }, + { 0x0700, 0xa06e, 0x0000 }, + { 0x0700, 0xa070, 0x0000 }, + { 0x8700, 0xa073, 0x2000 }, + { 0x0700, 0xa072, 0x0000 }, + { 0x0700, 0xa074, 0x0000 }, + { 0x8700, 0xa079, 0x3000 }, + { 0x8700, 0xa077, 0x2000 }, + { 0x0700, 0xa076, 0x0000 }, + { 0x0700, 0xa078, 0x0000 }, + { 0x8700, 0xa07b, 0x2000 }, + { 0x0700, 0xa07a, 0x0000 }, + { 0x0700, 0xa07c, 0x0000 }, + { 0x8700, 0xa085, 0x4000 }, + { 0x8700, 0xa081, 0x3000 }, + { 0x8700, 0xa07f, 0x2000 }, + { 0x0700, 0xa07e, 0x0000 }, + { 0x0700, 0xa080, 0x0000 }, + { 0x8700, 0xa083, 0x2000 }, + { 0x0700, 0xa082, 0x0000 }, + { 0x0700, 0xa084, 0x0000 }, + { 0x8700, 0xa089, 0x3000 }, + { 0x8700, 0xa087, 0x2000 }, + { 0x0700, 0xa086, 0x0000 }, + { 0x0700, 0xa088, 0x0000 }, + { 0x8700, 0xa08b, 0x2000 }, + { 0x0700, 0xa08a, 0x0000 }, + { 0x0700, 0xa08c, 0x0000 }, + { 0x8700, 0xa0ad, 0x6000 }, + { 0x8700, 0xa09d, 0x5000 }, + { 0x8700, 0xa095, 0x4000 }, + { 0x8700, 0xa091, 0x3000 }, + { 0x8700, 0xa08f, 0x2000 }, + { 0x0700, 0xa08e, 0x0000 }, + { 0x0700, 0xa090, 0x0000 }, + { 0x8700, 0xa093, 0x2000 }, + { 0x0700, 0xa092, 0x0000 }, + { 0x0700, 0xa094, 0x0000 }, + { 0x8700, 0xa099, 0x3000 }, + { 0x8700, 0xa097, 0x2000 }, + { 0x0700, 0xa096, 0x0000 }, + { 0x0700, 0xa098, 0x0000 }, + { 0x8700, 0xa09b, 0x2000 }, + { 0x0700, 0xa09a, 0x0000 }, + { 0x0700, 0xa09c, 0x0000 }, + { 0x8700, 0xa0a5, 0x4000 }, + { 0x8700, 0xa0a1, 0x3000 }, + { 0x8700, 0xa09f, 0x2000 }, + { 0x0700, 0xa09e, 0x0000 }, + { 0x0700, 0xa0a0, 0x0000 }, + { 0x8700, 0xa0a3, 0x2000 }, + { 0x0700, 0xa0a2, 0x0000 }, + { 0x0700, 0xa0a4, 0x0000 }, + { 0x8700, 0xa0a9, 0x3000 }, + { 0x8700, 0xa0a7, 0x2000 }, + { 0x0700, 0xa0a6, 0x0000 }, + { 0x0700, 0xa0a8, 0x0000 }, + { 0x8700, 0xa0ab, 0x2000 }, + { 0x0700, 0xa0aa, 0x0000 }, + { 0x0700, 0xa0ac, 0x0000 }, + { 0x8700, 0xa0bd, 0x5000 }, + { 0x8700, 0xa0b5, 0x4000 }, + { 0x8700, 0xa0b1, 0x3000 }, + { 0x8700, 0xa0af, 0x2000 }, + { 0x0700, 0xa0ae, 0x0000 }, + { 0x0700, 0xa0b0, 0x0000 }, + { 0x8700, 0xa0b3, 0x2000 }, + { 0x0700, 0xa0b2, 0x0000 }, + { 0x0700, 0xa0b4, 0x0000 }, + { 0x8700, 0xa0b9, 0x3000 }, + { 0x8700, 0xa0b7, 0x2000 }, + { 0x0700, 0xa0b6, 0x0000 }, + { 0x0700, 0xa0b8, 0x0000 }, + { 0x8700, 0xa0bb, 0x2000 }, + { 0x0700, 0xa0ba, 0x0000 }, + { 0x0700, 0xa0bc, 0x0000 }, + { 0x8700, 0xa0c5, 0x4000 }, + { 0x8700, 0xa0c1, 0x3000 }, + { 0x8700, 0xa0bf, 0x2000 }, + { 0x0700, 0xa0be, 0x0000 }, + { 0x0700, 0xa0c0, 0x0000 }, + { 0x8700, 0xa0c3, 0x2000 }, + { 0x0700, 0xa0c2, 0x0000 }, + { 0x0700, 0xa0c4, 0x0000 }, + { 0x8700, 0xa0c9, 0x3000 }, + { 0x8700, 0xa0c7, 0x2000 }, + { 0x0700, 0xa0c6, 0x0000 }, + { 0x0700, 0xa0c8, 0x0000 }, + { 0x8700, 0xa0cb, 0x2000 }, + { 0x0700, 0xa0ca, 0x0000 }, + { 0x0700, 0xa0cc, 0x0000 }, + { 0x8700, 0xa10d, 0x7000 }, + { 0x8700, 0xa0ed, 0x6000 }, + { 0x8700, 0xa0dd, 0x5000 }, + { 0x8700, 0xa0d5, 0x4000 }, + { 0x8700, 0xa0d1, 0x3000 }, + { 0x8700, 0xa0cf, 0x2000 }, + { 0x0700, 0xa0ce, 0x0000 }, + { 0x0700, 0xa0d0, 0x0000 }, + { 0x8700, 0xa0d3, 0x2000 }, + { 0x0700, 0xa0d2, 0x0000 }, + { 0x0700, 0xa0d4, 0x0000 }, + { 0x8700, 0xa0d9, 0x3000 }, + { 0x8700, 0xa0d7, 0x2000 }, + { 0x0700, 0xa0d6, 0x0000 }, + { 0x0700, 0xa0d8, 0x0000 }, + { 0x8700, 0xa0db, 0x2000 }, + { 0x0700, 0xa0da, 0x0000 }, + { 0x0700, 0xa0dc, 0x0000 }, + { 0x8700, 0xa0e5, 0x4000 }, + { 0x8700, 0xa0e1, 0x3000 }, + { 0x8700, 0xa0df, 0x2000 }, + { 0x0700, 0xa0de, 0x0000 }, + { 0x0700, 0xa0e0, 0x0000 }, + { 0x8700, 0xa0e3, 0x2000 }, + { 0x0700, 0xa0e2, 0x0000 }, + { 0x0700, 0xa0e4, 0x0000 }, + { 0x8700, 0xa0e9, 0x3000 }, + { 0x8700, 0xa0e7, 0x2000 }, + { 0x0700, 0xa0e6, 0x0000 }, + { 0x0700, 0xa0e8, 0x0000 }, + { 0x8700, 0xa0eb, 0x2000 }, + { 0x0700, 0xa0ea, 0x0000 }, + { 0x0700, 0xa0ec, 0x0000 }, + { 0x8700, 0xa0fd, 0x5000 }, + { 0x8700, 0xa0f5, 0x4000 }, + { 0x8700, 0xa0f1, 0x3000 }, + { 0x8700, 0xa0ef, 0x2000 }, + { 0x0700, 0xa0ee, 0x0000 }, + { 0x0700, 0xa0f0, 0x0000 }, + { 0x8700, 0xa0f3, 0x2000 }, + { 0x0700, 0xa0f2, 0x0000 }, + { 0x0700, 0xa0f4, 0x0000 }, + { 0x8700, 0xa0f9, 0x3000 }, + { 0x8700, 0xa0f7, 0x2000 }, + { 0x0700, 0xa0f6, 0x0000 }, + { 0x0700, 0xa0f8, 0x0000 }, + { 0x8700, 0xa0fb, 0x2000 }, + { 0x0700, 0xa0fa, 0x0000 }, + { 0x0700, 0xa0fc, 0x0000 }, + { 0x8700, 0xa105, 0x4000 }, + { 0x8700, 0xa101, 0x3000 }, + { 0x8700, 0xa0ff, 0x2000 }, + { 0x0700, 0xa0fe, 0x0000 }, + { 0x0700, 0xa100, 0x0000 }, + { 0x8700, 0xa103, 0x2000 }, + { 0x0700, 0xa102, 0x0000 }, + { 0x0700, 0xa104, 0x0000 }, + { 0x8700, 0xa109, 0x3000 }, + { 0x8700, 0xa107, 0x2000 }, + { 0x0700, 0xa106, 0x0000 }, + { 0x0700, 0xa108, 0x0000 }, + { 0x8700, 0xa10b, 0x2000 }, + { 0x0700, 0xa10a, 0x0000 }, + { 0x0700, 0xa10c, 0x0000 }, + { 0x8700, 0xa12d, 0x6000 }, + { 0x8700, 0xa11d, 0x5000 }, + { 0x8700, 0xa115, 0x4000 }, + { 0x8700, 0xa111, 0x3000 }, + { 0x8700, 0xa10f, 0x2000 }, + { 0x0700, 0xa10e, 0x0000 }, + { 0x0700, 0xa110, 0x0000 }, + { 0x8700, 0xa113, 0x2000 }, + { 0x0700, 0xa112, 0x0000 }, + { 0x0700, 0xa114, 0x0000 }, + { 0x8700, 0xa119, 0x3000 }, + { 0x8700, 0xa117, 0x2000 }, + { 0x0700, 0xa116, 0x0000 }, + { 0x0700, 0xa118, 0x0000 }, + { 0x8700, 0xa11b, 0x2000 }, + { 0x0700, 0xa11a, 0x0000 }, + { 0x0700, 0xa11c, 0x0000 }, + { 0x8700, 0xa125, 0x4000 }, + { 0x8700, 0xa121, 0x3000 }, + { 0x8700, 0xa11f, 0x2000 }, + { 0x0700, 0xa11e, 0x0000 }, + { 0x0700, 0xa120, 0x0000 }, + { 0x8700, 0xa123, 0x2000 }, + { 0x0700, 0xa122, 0x0000 }, + { 0x0700, 0xa124, 0x0000 }, + { 0x8700, 0xa129, 0x3000 }, + { 0x8700, 0xa127, 0x2000 }, + { 0x0700, 0xa126, 0x0000 }, + { 0x0700, 0xa128, 0x0000 }, + { 0x8700, 0xa12b, 0x2000 }, + { 0x0700, 0xa12a, 0x0000 }, + { 0x0700, 0xa12c, 0x0000 }, + { 0x8700, 0xa13d, 0x5000 }, + { 0x8700, 0xa135, 0x4000 }, + { 0x8700, 0xa131, 0x3000 }, + { 0x8700, 0xa12f, 0x2000 }, + { 0x0700, 0xa12e, 0x0000 }, + { 0x0700, 0xa130, 0x0000 }, + { 0x8700, 0xa133, 0x2000 }, + { 0x0700, 0xa132, 0x0000 }, + { 0x0700, 0xa134, 0x0000 }, + { 0x8700, 0xa139, 0x3000 }, + { 0x8700, 0xa137, 0x2000 }, + { 0x0700, 0xa136, 0x0000 }, + { 0x0700, 0xa138, 0x0000 }, + { 0x8700, 0xa13b, 0x2000 }, + { 0x0700, 0xa13a, 0x0000 }, + { 0x0700, 0xa13c, 0x0000 }, + { 0x8700, 0xa145, 0x4000 }, + { 0x8700, 0xa141, 0x3000 }, + { 0x8700, 0xa13f, 0x2000 }, + { 0x0700, 0xa13e, 0x0000 }, + { 0x0700, 0xa140, 0x0000 }, + { 0x8700, 0xa143, 0x2000 }, + { 0x0700, 0xa142, 0x0000 }, + { 0x0700, 0xa144, 0x0000 }, + { 0x8700, 0xa149, 0x3000 }, + { 0x8700, 0xa147, 0x2000 }, + { 0x0700, 0xa146, 0x0000 }, + { 0x0700, 0xa148, 0x0000 }, + { 0x8700, 0xa14b, 0x2000 }, + { 0x0700, 0xa14a, 0x0000 }, + { 0x0700, 0xa14c, 0x0000 }, + { 0x8700, 0xa24d, 0x9000 }, + { 0x8700, 0xa1cd, 0x8000 }, + { 0x8700, 0xa18d, 0x7000 }, + { 0x8700, 0xa16d, 0x6000 }, + { 0x8700, 0xa15d, 0x5000 }, + { 0x8700, 0xa155, 0x4000 }, + { 0x8700, 0xa151, 0x3000 }, + { 0x8700, 0xa14f, 0x2000 }, + { 0x0700, 0xa14e, 0x0000 }, + { 0x0700, 0xa150, 0x0000 }, + { 0x8700, 0xa153, 0x2000 }, + { 0x0700, 0xa152, 0x0000 }, + { 0x0700, 0xa154, 0x0000 }, + { 0x8700, 0xa159, 0x3000 }, + { 0x8700, 0xa157, 0x2000 }, + { 0x0700, 0xa156, 0x0000 }, + { 0x0700, 0xa158, 0x0000 }, + { 0x8700, 0xa15b, 0x2000 }, + { 0x0700, 0xa15a, 0x0000 }, + { 0x0700, 0xa15c, 0x0000 }, + { 0x8700, 0xa165, 0x4000 }, + { 0x8700, 0xa161, 0x3000 }, + { 0x8700, 0xa15f, 0x2000 }, + { 0x0700, 0xa15e, 0x0000 }, + { 0x0700, 0xa160, 0x0000 }, + { 0x8700, 0xa163, 0x2000 }, + { 0x0700, 0xa162, 0x0000 }, + { 0x0700, 0xa164, 0x0000 }, + { 0x8700, 0xa169, 0x3000 }, + { 0x8700, 0xa167, 0x2000 }, + { 0x0700, 0xa166, 0x0000 }, + { 0x0700, 0xa168, 0x0000 }, + { 0x8700, 0xa16b, 0x2000 }, + { 0x0700, 0xa16a, 0x0000 }, + { 0x0700, 0xa16c, 0x0000 }, + { 0x8700, 0xa17d, 0x5000 }, + { 0x8700, 0xa175, 0x4000 }, + { 0x8700, 0xa171, 0x3000 }, + { 0x8700, 0xa16f, 0x2000 }, + { 0x0700, 0xa16e, 0x0000 }, + { 0x0700, 0xa170, 0x0000 }, + { 0x8700, 0xa173, 0x2000 }, + { 0x0700, 0xa172, 0x0000 }, + { 0x0700, 0xa174, 0x0000 }, + { 0x8700, 0xa179, 0x3000 }, + { 0x8700, 0xa177, 0x2000 }, + { 0x0700, 0xa176, 0x0000 }, + { 0x0700, 0xa178, 0x0000 }, + { 0x8700, 0xa17b, 0x2000 }, + { 0x0700, 0xa17a, 0x0000 }, + { 0x0700, 0xa17c, 0x0000 }, + { 0x8700, 0xa185, 0x4000 }, + { 0x8700, 0xa181, 0x3000 }, + { 0x8700, 0xa17f, 0x2000 }, + { 0x0700, 0xa17e, 0x0000 }, + { 0x0700, 0xa180, 0x0000 }, + { 0x8700, 0xa183, 0x2000 }, + { 0x0700, 0xa182, 0x0000 }, + { 0x0700, 0xa184, 0x0000 }, + { 0x8700, 0xa189, 0x3000 }, + { 0x8700, 0xa187, 0x2000 }, + { 0x0700, 0xa186, 0x0000 }, + { 0x0700, 0xa188, 0x0000 }, + { 0x8700, 0xa18b, 0x2000 }, + { 0x0700, 0xa18a, 0x0000 }, + { 0x0700, 0xa18c, 0x0000 }, + { 0x8700, 0xa1ad, 0x6000 }, + { 0x8700, 0xa19d, 0x5000 }, + { 0x8700, 0xa195, 0x4000 }, + { 0x8700, 0xa191, 0x3000 }, + { 0x8700, 0xa18f, 0x2000 }, + { 0x0700, 0xa18e, 0x0000 }, + { 0x0700, 0xa190, 0x0000 }, + { 0x8700, 0xa193, 0x2000 }, + { 0x0700, 0xa192, 0x0000 }, + { 0x0700, 0xa194, 0x0000 }, + { 0x8700, 0xa199, 0x3000 }, + { 0x8700, 0xa197, 0x2000 }, + { 0x0700, 0xa196, 0x0000 }, + { 0x0700, 0xa198, 0x0000 }, + { 0x8700, 0xa19b, 0x2000 }, + { 0x0700, 0xa19a, 0x0000 }, + { 0x0700, 0xa19c, 0x0000 }, + { 0x8700, 0xa1a5, 0x4000 }, + { 0x8700, 0xa1a1, 0x3000 }, + { 0x8700, 0xa19f, 0x2000 }, + { 0x0700, 0xa19e, 0x0000 }, + { 0x0700, 0xa1a0, 0x0000 }, + { 0x8700, 0xa1a3, 0x2000 }, + { 0x0700, 0xa1a2, 0x0000 }, + { 0x0700, 0xa1a4, 0x0000 }, + { 0x8700, 0xa1a9, 0x3000 }, + { 0x8700, 0xa1a7, 0x2000 }, + { 0x0700, 0xa1a6, 0x0000 }, + { 0x0700, 0xa1a8, 0x0000 }, + { 0x8700, 0xa1ab, 0x2000 }, + { 0x0700, 0xa1aa, 0x0000 }, + { 0x0700, 0xa1ac, 0x0000 }, + { 0x8700, 0xa1bd, 0x5000 }, + { 0x8700, 0xa1b5, 0x4000 }, + { 0x8700, 0xa1b1, 0x3000 }, + { 0x8700, 0xa1af, 0x2000 }, + { 0x0700, 0xa1ae, 0x0000 }, + { 0x0700, 0xa1b0, 0x0000 }, + { 0x8700, 0xa1b3, 0x2000 }, + { 0x0700, 0xa1b2, 0x0000 }, + { 0x0700, 0xa1b4, 0x0000 }, + { 0x8700, 0xa1b9, 0x3000 }, + { 0x8700, 0xa1b7, 0x2000 }, + { 0x0700, 0xa1b6, 0x0000 }, + { 0x0700, 0xa1b8, 0x0000 }, + { 0x8700, 0xa1bb, 0x2000 }, + { 0x0700, 0xa1ba, 0x0000 }, + { 0x0700, 0xa1bc, 0x0000 }, + { 0x8700, 0xa1c5, 0x4000 }, + { 0x8700, 0xa1c1, 0x3000 }, + { 0x8700, 0xa1bf, 0x2000 }, + { 0x0700, 0xa1be, 0x0000 }, + { 0x0700, 0xa1c0, 0x0000 }, + { 0x8700, 0xa1c3, 0x2000 }, + { 0x0700, 0xa1c2, 0x0000 }, + { 0x0700, 0xa1c4, 0x0000 }, + { 0x8700, 0xa1c9, 0x3000 }, + { 0x8700, 0xa1c7, 0x2000 }, + { 0x0700, 0xa1c6, 0x0000 }, + { 0x0700, 0xa1c8, 0x0000 }, + { 0x8700, 0xa1cb, 0x2000 }, + { 0x0700, 0xa1ca, 0x0000 }, + { 0x0700, 0xa1cc, 0x0000 }, + { 0x8700, 0xa20d, 0x7000 }, + { 0x8700, 0xa1ed, 0x6000 }, + { 0x8700, 0xa1dd, 0x5000 }, + { 0x8700, 0xa1d5, 0x4000 }, + { 0x8700, 0xa1d1, 0x3000 }, + { 0x8700, 0xa1cf, 0x2000 }, + { 0x0700, 0xa1ce, 0x0000 }, + { 0x0700, 0xa1d0, 0x0000 }, + { 0x8700, 0xa1d3, 0x2000 }, + { 0x0700, 0xa1d2, 0x0000 }, + { 0x0700, 0xa1d4, 0x0000 }, + { 0x8700, 0xa1d9, 0x3000 }, + { 0x8700, 0xa1d7, 0x2000 }, + { 0x0700, 0xa1d6, 0x0000 }, + { 0x0700, 0xa1d8, 0x0000 }, + { 0x8700, 0xa1db, 0x2000 }, + { 0x0700, 0xa1da, 0x0000 }, + { 0x0700, 0xa1dc, 0x0000 }, + { 0x8700, 0xa1e5, 0x4000 }, + { 0x8700, 0xa1e1, 0x3000 }, + { 0x8700, 0xa1df, 0x2000 }, + { 0x0700, 0xa1de, 0x0000 }, + { 0x0700, 0xa1e0, 0x0000 }, + { 0x8700, 0xa1e3, 0x2000 }, + { 0x0700, 0xa1e2, 0x0000 }, + { 0x0700, 0xa1e4, 0x0000 }, + { 0x8700, 0xa1e9, 0x3000 }, + { 0x8700, 0xa1e7, 0x2000 }, + { 0x0700, 0xa1e6, 0x0000 }, + { 0x0700, 0xa1e8, 0x0000 }, + { 0x8700, 0xa1eb, 0x2000 }, + { 0x0700, 0xa1ea, 0x0000 }, + { 0x0700, 0xa1ec, 0x0000 }, + { 0x8700, 0xa1fd, 0x5000 }, + { 0x8700, 0xa1f5, 0x4000 }, + { 0x8700, 0xa1f1, 0x3000 }, + { 0x8700, 0xa1ef, 0x2000 }, + { 0x0700, 0xa1ee, 0x0000 }, + { 0x0700, 0xa1f0, 0x0000 }, + { 0x8700, 0xa1f3, 0x2000 }, + { 0x0700, 0xa1f2, 0x0000 }, + { 0x0700, 0xa1f4, 0x0000 }, + { 0x8700, 0xa1f9, 0x3000 }, + { 0x8700, 0xa1f7, 0x2000 }, + { 0x0700, 0xa1f6, 0x0000 }, + { 0x0700, 0xa1f8, 0x0000 }, + { 0x8700, 0xa1fb, 0x2000 }, + { 0x0700, 0xa1fa, 0x0000 }, + { 0x0700, 0xa1fc, 0x0000 }, + { 0x8700, 0xa205, 0x4000 }, + { 0x8700, 0xa201, 0x3000 }, + { 0x8700, 0xa1ff, 0x2000 }, + { 0x0700, 0xa1fe, 0x0000 }, + { 0x0700, 0xa200, 0x0000 }, + { 0x8700, 0xa203, 0x2000 }, + { 0x0700, 0xa202, 0x0000 }, + { 0x0700, 0xa204, 0x0000 }, + { 0x8700, 0xa209, 0x3000 }, + { 0x8700, 0xa207, 0x2000 }, + { 0x0700, 0xa206, 0x0000 }, + { 0x0700, 0xa208, 0x0000 }, + { 0x8700, 0xa20b, 0x2000 }, + { 0x0700, 0xa20a, 0x0000 }, + { 0x0700, 0xa20c, 0x0000 }, + { 0x8700, 0xa22d, 0x6000 }, + { 0x8700, 0xa21d, 0x5000 }, + { 0x8700, 0xa215, 0x4000 }, + { 0x8700, 0xa211, 0x3000 }, + { 0x8700, 0xa20f, 0x2000 }, + { 0x0700, 0xa20e, 0x0000 }, + { 0x0700, 0xa210, 0x0000 }, + { 0x8700, 0xa213, 0x2000 }, + { 0x0700, 0xa212, 0x0000 }, + { 0x0700, 0xa214, 0x0000 }, + { 0x8700, 0xa219, 0x3000 }, + { 0x8700, 0xa217, 0x2000 }, + { 0x0700, 0xa216, 0x0000 }, + { 0x0700, 0xa218, 0x0000 }, + { 0x8700, 0xa21b, 0x2000 }, + { 0x0700, 0xa21a, 0x0000 }, + { 0x0700, 0xa21c, 0x0000 }, + { 0x8700, 0xa225, 0x4000 }, + { 0x8700, 0xa221, 0x3000 }, + { 0x8700, 0xa21f, 0x2000 }, + { 0x0700, 0xa21e, 0x0000 }, + { 0x0700, 0xa220, 0x0000 }, + { 0x8700, 0xa223, 0x2000 }, + { 0x0700, 0xa222, 0x0000 }, + { 0x0700, 0xa224, 0x0000 }, + { 0x8700, 0xa229, 0x3000 }, + { 0x8700, 0xa227, 0x2000 }, + { 0x0700, 0xa226, 0x0000 }, + { 0x0700, 0xa228, 0x0000 }, + { 0x8700, 0xa22b, 0x2000 }, + { 0x0700, 0xa22a, 0x0000 }, + { 0x0700, 0xa22c, 0x0000 }, + { 0x8700, 0xa23d, 0x5000 }, + { 0x8700, 0xa235, 0x4000 }, + { 0x8700, 0xa231, 0x3000 }, + { 0x8700, 0xa22f, 0x2000 }, + { 0x0700, 0xa22e, 0x0000 }, + { 0x0700, 0xa230, 0x0000 }, + { 0x8700, 0xa233, 0x2000 }, + { 0x0700, 0xa232, 0x0000 }, + { 0x0700, 0xa234, 0x0000 }, + { 0x8700, 0xa239, 0x3000 }, + { 0x8700, 0xa237, 0x2000 }, + { 0x0700, 0xa236, 0x0000 }, + { 0x0700, 0xa238, 0x0000 }, + { 0x8700, 0xa23b, 0x2000 }, + { 0x0700, 0xa23a, 0x0000 }, + { 0x0700, 0xa23c, 0x0000 }, + { 0x8700, 0xa245, 0x4000 }, + { 0x8700, 0xa241, 0x3000 }, + { 0x8700, 0xa23f, 0x2000 }, + { 0x0700, 0xa23e, 0x0000 }, + { 0x0700, 0xa240, 0x0000 }, + { 0x8700, 0xa243, 0x2000 }, + { 0x0700, 0xa242, 0x0000 }, + { 0x0700, 0xa244, 0x0000 }, + { 0x8700, 0xa249, 0x3000 }, + { 0x8700, 0xa247, 0x2000 }, + { 0x0700, 0xa246, 0x0000 }, + { 0x0700, 0xa248, 0x0000 }, + { 0x8700, 0xa24b, 0x2000 }, + { 0x0700, 0xa24a, 0x0000 }, + { 0x0700, 0xa24c, 0x0000 }, + { 0x8700, 0xa2cd, 0x8000 }, + { 0x8700, 0xa28d, 0x7000 }, + { 0x8700, 0xa26d, 0x6000 }, + { 0x8700, 0xa25d, 0x5000 }, + { 0x8700, 0xa255, 0x4000 }, + { 0x8700, 0xa251, 0x3000 }, + { 0x8700, 0xa24f, 0x2000 }, + { 0x0700, 0xa24e, 0x0000 }, + { 0x0700, 0xa250, 0x0000 }, + { 0x8700, 0xa253, 0x2000 }, + { 0x0700, 0xa252, 0x0000 }, + { 0x0700, 0xa254, 0x0000 }, + { 0x8700, 0xa259, 0x3000 }, + { 0x8700, 0xa257, 0x2000 }, + { 0x0700, 0xa256, 0x0000 }, + { 0x0700, 0xa258, 0x0000 }, + { 0x8700, 0xa25b, 0x2000 }, + { 0x0700, 0xa25a, 0x0000 }, + { 0x0700, 0xa25c, 0x0000 }, + { 0x8700, 0xa265, 0x4000 }, + { 0x8700, 0xa261, 0x3000 }, + { 0x8700, 0xa25f, 0x2000 }, + { 0x0700, 0xa25e, 0x0000 }, + { 0x0700, 0xa260, 0x0000 }, + { 0x8700, 0xa263, 0x2000 }, + { 0x0700, 0xa262, 0x0000 }, + { 0x0700, 0xa264, 0x0000 }, + { 0x8700, 0xa269, 0x3000 }, + { 0x8700, 0xa267, 0x2000 }, + { 0x0700, 0xa266, 0x0000 }, + { 0x0700, 0xa268, 0x0000 }, + { 0x8700, 0xa26b, 0x2000 }, + { 0x0700, 0xa26a, 0x0000 }, + { 0x0700, 0xa26c, 0x0000 }, + { 0x8700, 0xa27d, 0x5000 }, + { 0x8700, 0xa275, 0x4000 }, + { 0x8700, 0xa271, 0x3000 }, + { 0x8700, 0xa26f, 0x2000 }, + { 0x0700, 0xa26e, 0x0000 }, + { 0x0700, 0xa270, 0x0000 }, + { 0x8700, 0xa273, 0x2000 }, + { 0x0700, 0xa272, 0x0000 }, + { 0x0700, 0xa274, 0x0000 }, + { 0x8700, 0xa279, 0x3000 }, + { 0x8700, 0xa277, 0x2000 }, + { 0x0700, 0xa276, 0x0000 }, + { 0x0700, 0xa278, 0x0000 }, + { 0x8700, 0xa27b, 0x2000 }, + { 0x0700, 0xa27a, 0x0000 }, + { 0x0700, 0xa27c, 0x0000 }, + { 0x8700, 0xa285, 0x4000 }, + { 0x8700, 0xa281, 0x3000 }, + { 0x8700, 0xa27f, 0x2000 }, + { 0x0700, 0xa27e, 0x0000 }, + { 0x0700, 0xa280, 0x0000 }, + { 0x8700, 0xa283, 0x2000 }, + { 0x0700, 0xa282, 0x0000 }, + { 0x0700, 0xa284, 0x0000 }, + { 0x8700, 0xa289, 0x3000 }, + { 0x8700, 0xa287, 0x2000 }, + { 0x0700, 0xa286, 0x0000 }, + { 0x0700, 0xa288, 0x0000 }, + { 0x8700, 0xa28b, 0x2000 }, + { 0x0700, 0xa28a, 0x0000 }, + { 0x0700, 0xa28c, 0x0000 }, + { 0x8700, 0xa2ad, 0x6000 }, + { 0x8700, 0xa29d, 0x5000 }, + { 0x8700, 0xa295, 0x4000 }, + { 0x8700, 0xa291, 0x3000 }, + { 0x8700, 0xa28f, 0x2000 }, + { 0x0700, 0xa28e, 0x0000 }, + { 0x0700, 0xa290, 0x0000 }, + { 0x8700, 0xa293, 0x2000 }, + { 0x0700, 0xa292, 0x0000 }, + { 0x0700, 0xa294, 0x0000 }, + { 0x8700, 0xa299, 0x3000 }, + { 0x8700, 0xa297, 0x2000 }, + { 0x0700, 0xa296, 0x0000 }, + { 0x0700, 0xa298, 0x0000 }, + { 0x8700, 0xa29b, 0x2000 }, + { 0x0700, 0xa29a, 0x0000 }, + { 0x0700, 0xa29c, 0x0000 }, + { 0x8700, 0xa2a5, 0x4000 }, + { 0x8700, 0xa2a1, 0x3000 }, + { 0x8700, 0xa29f, 0x2000 }, + { 0x0700, 0xa29e, 0x0000 }, + { 0x0700, 0xa2a0, 0x0000 }, + { 0x8700, 0xa2a3, 0x2000 }, + { 0x0700, 0xa2a2, 0x0000 }, + { 0x0700, 0xa2a4, 0x0000 }, + { 0x8700, 0xa2a9, 0x3000 }, + { 0x8700, 0xa2a7, 0x2000 }, + { 0x0700, 0xa2a6, 0x0000 }, + { 0x0700, 0xa2a8, 0x0000 }, + { 0x8700, 0xa2ab, 0x2000 }, + { 0x0700, 0xa2aa, 0x0000 }, + { 0x0700, 0xa2ac, 0x0000 }, + { 0x8700, 0xa2bd, 0x5000 }, + { 0x8700, 0xa2b5, 0x4000 }, + { 0x8700, 0xa2b1, 0x3000 }, + { 0x8700, 0xa2af, 0x2000 }, + { 0x0700, 0xa2ae, 0x0000 }, + { 0x0700, 0xa2b0, 0x0000 }, + { 0x8700, 0xa2b3, 0x2000 }, + { 0x0700, 0xa2b2, 0x0000 }, + { 0x0700, 0xa2b4, 0x0000 }, + { 0x8700, 0xa2b9, 0x3000 }, + { 0x8700, 0xa2b7, 0x2000 }, + { 0x0700, 0xa2b6, 0x0000 }, + { 0x0700, 0xa2b8, 0x0000 }, + { 0x8700, 0xa2bb, 0x2000 }, + { 0x0700, 0xa2ba, 0x0000 }, + { 0x0700, 0xa2bc, 0x0000 }, + { 0x8700, 0xa2c5, 0x4000 }, + { 0x8700, 0xa2c1, 0x3000 }, + { 0x8700, 0xa2bf, 0x2000 }, + { 0x0700, 0xa2be, 0x0000 }, + { 0x0700, 0xa2c0, 0x0000 }, + { 0x8700, 0xa2c3, 0x2000 }, + { 0x0700, 0xa2c2, 0x0000 }, + { 0x0700, 0xa2c4, 0x0000 }, + { 0x8700, 0xa2c9, 0x3000 }, + { 0x8700, 0xa2c7, 0x2000 }, + { 0x0700, 0xa2c6, 0x0000 }, + { 0x0700, 0xa2c8, 0x0000 }, + { 0x8700, 0xa2cb, 0x2000 }, + { 0x0700, 0xa2ca, 0x0000 }, + { 0x0700, 0xa2cc, 0x0000 }, + { 0x8700, 0xa30d, 0x7000 }, + { 0x8700, 0xa2ed, 0x6000 }, + { 0x8700, 0xa2dd, 0x5000 }, + { 0x8700, 0xa2d5, 0x4000 }, + { 0x8700, 0xa2d1, 0x3000 }, + { 0x8700, 0xa2cf, 0x2000 }, + { 0x0700, 0xa2ce, 0x0000 }, + { 0x0700, 0xa2d0, 0x0000 }, + { 0x8700, 0xa2d3, 0x2000 }, + { 0x0700, 0xa2d2, 0x0000 }, + { 0x0700, 0xa2d4, 0x0000 }, + { 0x8700, 0xa2d9, 0x3000 }, + { 0x8700, 0xa2d7, 0x2000 }, + { 0x0700, 0xa2d6, 0x0000 }, + { 0x0700, 0xa2d8, 0x0000 }, + { 0x8700, 0xa2db, 0x2000 }, + { 0x0700, 0xa2da, 0x0000 }, + { 0x0700, 0xa2dc, 0x0000 }, + { 0x8700, 0xa2e5, 0x4000 }, + { 0x8700, 0xa2e1, 0x3000 }, + { 0x8700, 0xa2df, 0x2000 }, + { 0x0700, 0xa2de, 0x0000 }, + { 0x0700, 0xa2e0, 0x0000 }, + { 0x8700, 0xa2e3, 0x2000 }, + { 0x0700, 0xa2e2, 0x0000 }, + { 0x0700, 0xa2e4, 0x0000 }, + { 0x8700, 0xa2e9, 0x3000 }, + { 0x8700, 0xa2e7, 0x2000 }, + { 0x0700, 0xa2e6, 0x0000 }, + { 0x0700, 0xa2e8, 0x0000 }, + { 0x8700, 0xa2eb, 0x2000 }, + { 0x0700, 0xa2ea, 0x0000 }, + { 0x0700, 0xa2ec, 0x0000 }, + { 0x8700, 0xa2fd, 0x5000 }, + { 0x8700, 0xa2f5, 0x4000 }, + { 0x8700, 0xa2f1, 0x3000 }, + { 0x8700, 0xa2ef, 0x2000 }, + { 0x0700, 0xa2ee, 0x0000 }, + { 0x0700, 0xa2f0, 0x0000 }, + { 0x8700, 0xa2f3, 0x2000 }, + { 0x0700, 0xa2f2, 0x0000 }, + { 0x0700, 0xa2f4, 0x0000 }, + { 0x8700, 0xa2f9, 0x3000 }, + { 0x8700, 0xa2f7, 0x2000 }, + { 0x0700, 0xa2f6, 0x0000 }, + { 0x0700, 0xa2f8, 0x0000 }, + { 0x8700, 0xa2fb, 0x2000 }, + { 0x0700, 0xa2fa, 0x0000 }, + { 0x0700, 0xa2fc, 0x0000 }, + { 0x8700, 0xa305, 0x4000 }, + { 0x8700, 0xa301, 0x3000 }, + { 0x8700, 0xa2ff, 0x2000 }, + { 0x0700, 0xa2fe, 0x0000 }, + { 0x0700, 0xa300, 0x0000 }, + { 0x8700, 0xa303, 0x2000 }, + { 0x0700, 0xa302, 0x0000 }, + { 0x0700, 0xa304, 0x0000 }, + { 0x8700, 0xa309, 0x3000 }, + { 0x8700, 0xa307, 0x2000 }, + { 0x0700, 0xa306, 0x0000 }, + { 0x0700, 0xa308, 0x0000 }, + { 0x8700, 0xa30b, 0x2000 }, + { 0x0700, 0xa30a, 0x0000 }, + { 0x0700, 0xa30c, 0x0000 }, + { 0x8700, 0xa32d, 0x6000 }, + { 0x8700, 0xa31d, 0x5000 }, + { 0x8700, 0xa315, 0x4000 }, + { 0x8700, 0xa311, 0x3000 }, + { 0x8700, 0xa30f, 0x2000 }, + { 0x0700, 0xa30e, 0x0000 }, + { 0x0700, 0xa310, 0x0000 }, + { 0x8700, 0xa313, 0x2000 }, + { 0x0700, 0xa312, 0x0000 }, + { 0x0700, 0xa314, 0x0000 }, + { 0x8700, 0xa319, 0x3000 }, + { 0x8700, 0xa317, 0x2000 }, + { 0x0700, 0xa316, 0x0000 }, + { 0x0700, 0xa318, 0x0000 }, + { 0x8700, 0xa31b, 0x2000 }, + { 0x0700, 0xa31a, 0x0000 }, + { 0x0700, 0xa31c, 0x0000 }, + { 0x8700, 0xa325, 0x4000 }, + { 0x8700, 0xa321, 0x3000 }, + { 0x8700, 0xa31f, 0x2000 }, + { 0x0700, 0xa31e, 0x0000 }, + { 0x0700, 0xa320, 0x0000 }, + { 0x8700, 0xa323, 0x2000 }, + { 0x0700, 0xa322, 0x0000 }, + { 0x0700, 0xa324, 0x0000 }, + { 0x8700, 0xa329, 0x3000 }, + { 0x8700, 0xa327, 0x2000 }, + { 0x0700, 0xa326, 0x0000 }, + { 0x0700, 0xa328, 0x0000 }, + { 0x8700, 0xa32b, 0x2000 }, + { 0x0700, 0xa32a, 0x0000 }, + { 0x0700, 0xa32c, 0x0000 }, + { 0x8700, 0xa33d, 0x5000 }, + { 0x8700, 0xa335, 0x4000 }, + { 0x8700, 0xa331, 0x3000 }, + { 0x8700, 0xa32f, 0x2000 }, + { 0x0700, 0xa32e, 0x0000 }, + { 0x0700, 0xa330, 0x0000 }, + { 0x8700, 0xa333, 0x2000 }, + { 0x0700, 0xa332, 0x0000 }, + { 0x0700, 0xa334, 0x0000 }, + { 0x8700, 0xa339, 0x3000 }, + { 0x8700, 0xa337, 0x2000 }, + { 0x0700, 0xa336, 0x0000 }, + { 0x0700, 0xa338, 0x0000 }, + { 0x8700, 0xa33b, 0x2000 }, + { 0x0700, 0xa33a, 0x0000 }, + { 0x0700, 0xa33c, 0x0000 }, + { 0x8700, 0xa345, 0x4000 }, + { 0x8700, 0xa341, 0x3000 }, + { 0x8700, 0xa33f, 0x2000 }, + { 0x0700, 0xa33e, 0x0000 }, + { 0x0700, 0xa340, 0x0000 }, + { 0x8700, 0xa343, 0x2000 }, + { 0x0700, 0xa342, 0x0000 }, + { 0x0700, 0xa344, 0x0000 }, + { 0x8700, 0xa349, 0x3000 }, + { 0x8700, 0xa347, 0x2000 }, + { 0x0700, 0xa346, 0x0000 }, + { 0x0700, 0xa348, 0x0000 }, + { 0x8700, 0xa34b, 0x2000 }, + { 0x0700, 0xa34a, 0x0000 }, + { 0x0700, 0xa34c, 0x0000 }, + { 0x8700, 0xfc4d, 0xb000 }, + { 0x8700, 0xf97f, 0xa000 }, + { 0x8700, 0xa44d, 0x9000 }, + { 0x8700, 0xa3cd, 0x8000 }, + { 0x8700, 0xa38d, 0x7000 }, + { 0x8700, 0xa36d, 0x6000 }, + { 0x8700, 0xa35d, 0x5000 }, + { 0x8700, 0xa355, 0x4000 }, + { 0x8700, 0xa351, 0x3000 }, + { 0x8700, 0xa34f, 0x2000 }, + { 0x0700, 0xa34e, 0x0000 }, + { 0x0700, 0xa350, 0x0000 }, + { 0x8700, 0xa353, 0x2000 }, + { 0x0700, 0xa352, 0x0000 }, + { 0x0700, 0xa354, 0x0000 }, + { 0x8700, 0xa359, 0x3000 }, + { 0x8700, 0xa357, 0x2000 }, + { 0x0700, 0xa356, 0x0000 }, + { 0x0700, 0xa358, 0x0000 }, + { 0x8700, 0xa35b, 0x2000 }, + { 0x0700, 0xa35a, 0x0000 }, + { 0x0700, 0xa35c, 0x0000 }, + { 0x8700, 0xa365, 0x4000 }, + { 0x8700, 0xa361, 0x3000 }, + { 0x8700, 0xa35f, 0x2000 }, + { 0x0700, 0xa35e, 0x0000 }, + { 0x0700, 0xa360, 0x0000 }, + { 0x8700, 0xa363, 0x2000 }, + { 0x0700, 0xa362, 0x0000 }, + { 0x0700, 0xa364, 0x0000 }, + { 0x8700, 0xa369, 0x3000 }, + { 0x8700, 0xa367, 0x2000 }, + { 0x0700, 0xa366, 0x0000 }, + { 0x0700, 0xa368, 0x0000 }, + { 0x8700, 0xa36b, 0x2000 }, + { 0x0700, 0xa36a, 0x0000 }, + { 0x0700, 0xa36c, 0x0000 }, + { 0x8700, 0xa37d, 0x5000 }, + { 0x8700, 0xa375, 0x4000 }, + { 0x8700, 0xa371, 0x3000 }, + { 0x8700, 0xa36f, 0x2000 }, + { 0x0700, 0xa36e, 0x0000 }, + { 0x0700, 0xa370, 0x0000 }, + { 0x8700, 0xa373, 0x2000 }, + { 0x0700, 0xa372, 0x0000 }, + { 0x0700, 0xa374, 0x0000 }, + { 0x8700, 0xa379, 0x3000 }, + { 0x8700, 0xa377, 0x2000 }, + { 0x0700, 0xa376, 0x0000 }, + { 0x0700, 0xa378, 0x0000 }, + { 0x8700, 0xa37b, 0x2000 }, + { 0x0700, 0xa37a, 0x0000 }, + { 0x0700, 0xa37c, 0x0000 }, + { 0x8700, 0xa385, 0x4000 }, + { 0x8700, 0xa381, 0x3000 }, + { 0x8700, 0xa37f, 0x2000 }, + { 0x0700, 0xa37e, 0x0000 }, + { 0x0700, 0xa380, 0x0000 }, + { 0x8700, 0xa383, 0x2000 }, + { 0x0700, 0xa382, 0x0000 }, + { 0x0700, 0xa384, 0x0000 }, + { 0x8700, 0xa389, 0x3000 }, + { 0x8700, 0xa387, 0x2000 }, + { 0x0700, 0xa386, 0x0000 }, + { 0x0700, 0xa388, 0x0000 }, + { 0x8700, 0xa38b, 0x2000 }, + { 0x0700, 0xa38a, 0x0000 }, + { 0x0700, 0xa38c, 0x0000 }, + { 0x8700, 0xa3ad, 0x6000 }, + { 0x8700, 0xa39d, 0x5000 }, + { 0x8700, 0xa395, 0x4000 }, + { 0x8700, 0xa391, 0x3000 }, + { 0x8700, 0xa38f, 0x2000 }, + { 0x0700, 0xa38e, 0x0000 }, + { 0x0700, 0xa390, 0x0000 }, + { 0x8700, 0xa393, 0x2000 }, + { 0x0700, 0xa392, 0x0000 }, + { 0x0700, 0xa394, 0x0000 }, + { 0x8700, 0xa399, 0x3000 }, + { 0x8700, 0xa397, 0x2000 }, + { 0x0700, 0xa396, 0x0000 }, + { 0x0700, 0xa398, 0x0000 }, + { 0x8700, 0xa39b, 0x2000 }, + { 0x0700, 0xa39a, 0x0000 }, + { 0x0700, 0xa39c, 0x0000 }, + { 0x8700, 0xa3a5, 0x4000 }, + { 0x8700, 0xa3a1, 0x3000 }, + { 0x8700, 0xa39f, 0x2000 }, + { 0x0700, 0xa39e, 0x0000 }, + { 0x0700, 0xa3a0, 0x0000 }, + { 0x8700, 0xa3a3, 0x2000 }, + { 0x0700, 0xa3a2, 0x0000 }, + { 0x0700, 0xa3a4, 0x0000 }, + { 0x8700, 0xa3a9, 0x3000 }, + { 0x8700, 0xa3a7, 0x2000 }, + { 0x0700, 0xa3a6, 0x0000 }, + { 0x0700, 0xa3a8, 0x0000 }, + { 0x8700, 0xa3ab, 0x2000 }, + { 0x0700, 0xa3aa, 0x0000 }, + { 0x0700, 0xa3ac, 0x0000 }, + { 0x8700, 0xa3bd, 0x5000 }, + { 0x8700, 0xa3b5, 0x4000 }, + { 0x8700, 0xa3b1, 0x3000 }, + { 0x8700, 0xa3af, 0x2000 }, + { 0x0700, 0xa3ae, 0x0000 }, + { 0x0700, 0xa3b0, 0x0000 }, + { 0x8700, 0xa3b3, 0x2000 }, + { 0x0700, 0xa3b2, 0x0000 }, + { 0x0700, 0xa3b4, 0x0000 }, + { 0x8700, 0xa3b9, 0x3000 }, + { 0x8700, 0xa3b7, 0x2000 }, + { 0x0700, 0xa3b6, 0x0000 }, + { 0x0700, 0xa3b8, 0x0000 }, + { 0x8700, 0xa3bb, 0x2000 }, + { 0x0700, 0xa3ba, 0x0000 }, + { 0x0700, 0xa3bc, 0x0000 }, + { 0x8700, 0xa3c5, 0x4000 }, + { 0x8700, 0xa3c1, 0x3000 }, + { 0x8700, 0xa3bf, 0x2000 }, + { 0x0700, 0xa3be, 0x0000 }, + { 0x0700, 0xa3c0, 0x0000 }, + { 0x8700, 0xa3c3, 0x2000 }, + { 0x0700, 0xa3c2, 0x0000 }, + { 0x0700, 0xa3c4, 0x0000 }, + { 0x8700, 0xa3c9, 0x3000 }, + { 0x8700, 0xa3c7, 0x2000 }, + { 0x0700, 0xa3c6, 0x0000 }, + { 0x0700, 0xa3c8, 0x0000 }, + { 0x8700, 0xa3cb, 0x2000 }, + { 0x0700, 0xa3ca, 0x0000 }, + { 0x0700, 0xa3cc, 0x0000 }, + { 0x8700, 0xa40d, 0x7000 }, + { 0x8700, 0xa3ed, 0x6000 }, + { 0x8700, 0xa3dd, 0x5000 }, + { 0x8700, 0xa3d5, 0x4000 }, + { 0x8700, 0xa3d1, 0x3000 }, + { 0x8700, 0xa3cf, 0x2000 }, + { 0x0700, 0xa3ce, 0x0000 }, + { 0x0700, 0xa3d0, 0x0000 }, + { 0x8700, 0xa3d3, 0x2000 }, + { 0x0700, 0xa3d2, 0x0000 }, + { 0x0700, 0xa3d4, 0x0000 }, + { 0x8700, 0xa3d9, 0x3000 }, + { 0x8700, 0xa3d7, 0x2000 }, + { 0x0700, 0xa3d6, 0x0000 }, + { 0x0700, 0xa3d8, 0x0000 }, + { 0x8700, 0xa3db, 0x2000 }, + { 0x0700, 0xa3da, 0x0000 }, + { 0x0700, 0xa3dc, 0x0000 }, + { 0x8700, 0xa3e5, 0x4000 }, + { 0x8700, 0xa3e1, 0x3000 }, + { 0x8700, 0xa3df, 0x2000 }, + { 0x0700, 0xa3de, 0x0000 }, + { 0x0700, 0xa3e0, 0x0000 }, + { 0x8700, 0xa3e3, 0x2000 }, + { 0x0700, 0xa3e2, 0x0000 }, + { 0x0700, 0xa3e4, 0x0000 }, + { 0x8700, 0xa3e9, 0x3000 }, + { 0x8700, 0xa3e7, 0x2000 }, + { 0x0700, 0xa3e6, 0x0000 }, + { 0x0700, 0xa3e8, 0x0000 }, + { 0x8700, 0xa3eb, 0x2000 }, + { 0x0700, 0xa3ea, 0x0000 }, + { 0x0700, 0xa3ec, 0x0000 }, + { 0x8700, 0xa3fd, 0x5000 }, + { 0x8700, 0xa3f5, 0x4000 }, + { 0x8700, 0xa3f1, 0x3000 }, + { 0x8700, 0xa3ef, 0x2000 }, + { 0x0700, 0xa3ee, 0x0000 }, + { 0x0700, 0xa3f0, 0x0000 }, + { 0x8700, 0xa3f3, 0x2000 }, + { 0x0700, 0xa3f2, 0x0000 }, + { 0x0700, 0xa3f4, 0x0000 }, + { 0x8700, 0xa3f9, 0x3000 }, + { 0x8700, 0xa3f7, 0x2000 }, + { 0x0700, 0xa3f6, 0x0000 }, + { 0x0700, 0xa3f8, 0x0000 }, + { 0x8700, 0xa3fb, 0x2000 }, + { 0x0700, 0xa3fa, 0x0000 }, + { 0x0700, 0xa3fc, 0x0000 }, + { 0x8700, 0xa405, 0x4000 }, + { 0x8700, 0xa401, 0x3000 }, + { 0x8700, 0xa3ff, 0x2000 }, + { 0x0700, 0xa3fe, 0x0000 }, + { 0x0700, 0xa400, 0x0000 }, + { 0x8700, 0xa403, 0x2000 }, + { 0x0700, 0xa402, 0x0000 }, + { 0x0700, 0xa404, 0x0000 }, + { 0x8700, 0xa409, 0x3000 }, + { 0x8700, 0xa407, 0x2000 }, + { 0x0700, 0xa406, 0x0000 }, + { 0x0700, 0xa408, 0x0000 }, + { 0x8700, 0xa40b, 0x2000 }, + { 0x0700, 0xa40a, 0x0000 }, + { 0x0700, 0xa40c, 0x0000 }, + { 0x8700, 0xa42d, 0x6000 }, + { 0x8700, 0xa41d, 0x5000 }, + { 0x8700, 0xa415, 0x4000 }, + { 0x8700, 0xa411, 0x3000 }, + { 0x8700, 0xa40f, 0x2000 }, + { 0x0700, 0xa40e, 0x0000 }, + { 0x0700, 0xa410, 0x0000 }, + { 0x8700, 0xa413, 0x2000 }, + { 0x0700, 0xa412, 0x0000 }, + { 0x0700, 0xa414, 0x0000 }, + { 0x8700, 0xa419, 0x3000 }, + { 0x8700, 0xa417, 0x2000 }, + { 0x0700, 0xa416, 0x0000 }, + { 0x0700, 0xa418, 0x0000 }, + { 0x8700, 0xa41b, 0x2000 }, + { 0x0700, 0xa41a, 0x0000 }, + { 0x0700, 0xa41c, 0x0000 }, + { 0x8700, 0xa425, 0x4000 }, + { 0x8700, 0xa421, 0x3000 }, + { 0x8700, 0xa41f, 0x2000 }, + { 0x0700, 0xa41e, 0x0000 }, + { 0x0700, 0xa420, 0x0000 }, + { 0x8700, 0xa423, 0x2000 }, + { 0x0700, 0xa422, 0x0000 }, + { 0x0700, 0xa424, 0x0000 }, + { 0x8700, 0xa429, 0x3000 }, + { 0x8700, 0xa427, 0x2000 }, + { 0x0700, 0xa426, 0x0000 }, + { 0x0700, 0xa428, 0x0000 }, + { 0x8700, 0xa42b, 0x2000 }, + { 0x0700, 0xa42a, 0x0000 }, + { 0x0700, 0xa42c, 0x0000 }, + { 0x8700, 0xa43d, 0x5000 }, + { 0x8700, 0xa435, 0x4000 }, + { 0x8700, 0xa431, 0x3000 }, + { 0x8700, 0xa42f, 0x2000 }, + { 0x0700, 0xa42e, 0x0000 }, + { 0x0700, 0xa430, 0x0000 }, + { 0x8700, 0xa433, 0x2000 }, + { 0x0700, 0xa432, 0x0000 }, + { 0x0700, 0xa434, 0x0000 }, + { 0x8700, 0xa439, 0x3000 }, + { 0x8700, 0xa437, 0x2000 }, + { 0x0700, 0xa436, 0x0000 }, + { 0x0700, 0xa438, 0x0000 }, + { 0x8700, 0xa43b, 0x2000 }, + { 0x0700, 0xa43a, 0x0000 }, + { 0x0700, 0xa43c, 0x0000 }, + { 0x8700, 0xa445, 0x4000 }, + { 0x8700, 0xa441, 0x3000 }, + { 0x8700, 0xa43f, 0x2000 }, + { 0x0700, 0xa43e, 0x0000 }, + { 0x0700, 0xa440, 0x0000 }, + { 0x8700, 0xa443, 0x2000 }, + { 0x0700, 0xa442, 0x0000 }, + { 0x0700, 0xa444, 0x0000 }, + { 0x8700, 0xa449, 0x3000 }, + { 0x8700, 0xa447, 0x2000 }, + { 0x0700, 0xa446, 0x0000 }, + { 0x0700, 0xa448, 0x0000 }, + { 0x8700, 0xa44b, 0x2000 }, + { 0x0700, 0xa44a, 0x0000 }, + { 0x0700, 0xa44c, 0x0000 }, + { 0x8300, 0xf8ff, 0x8000 }, + { 0x9a00, 0xa490, 0x7000 }, + { 0x8700, 0xa46d, 0x6000 }, + { 0x8700, 0xa45d, 0x5000 }, + { 0x8700, 0xa455, 0x4000 }, + { 0x8700, 0xa451, 0x3000 }, + { 0x8700, 0xa44f, 0x2000 }, + { 0x0700, 0xa44e, 0x0000 }, + { 0x0700, 0xa450, 0x0000 }, + { 0x8700, 0xa453, 0x2000 }, + { 0x0700, 0xa452, 0x0000 }, + { 0x0700, 0xa454, 0x0000 }, + { 0x8700, 0xa459, 0x3000 }, + { 0x8700, 0xa457, 0x2000 }, + { 0x0700, 0xa456, 0x0000 }, + { 0x0700, 0xa458, 0x0000 }, + { 0x8700, 0xa45b, 0x2000 }, + { 0x0700, 0xa45a, 0x0000 }, + { 0x0700, 0xa45c, 0x0000 }, + { 0x8700, 0xa465, 0x4000 }, + { 0x8700, 0xa461, 0x3000 }, + { 0x8700, 0xa45f, 0x2000 }, + { 0x0700, 0xa45e, 0x0000 }, + { 0x0700, 0xa460, 0x0000 }, + { 0x8700, 0xa463, 0x2000 }, + { 0x0700, 0xa462, 0x0000 }, + { 0x0700, 0xa464, 0x0000 }, + { 0x8700, 0xa469, 0x3000 }, + { 0x8700, 0xa467, 0x2000 }, + { 0x0700, 0xa466, 0x0000 }, + { 0x0700, 0xa468, 0x0000 }, + { 0x8700, 0xa46b, 0x2000 }, + { 0x0700, 0xa46a, 0x0000 }, + { 0x0700, 0xa46c, 0x0000 }, + { 0x8700, 0xa47d, 0x5000 }, + { 0x8700, 0xa475, 0x4000 }, + { 0x8700, 0xa471, 0x3000 }, + { 0x8700, 0xa46f, 0x2000 }, + { 0x0700, 0xa46e, 0x0000 }, + { 0x0700, 0xa470, 0x0000 }, + { 0x8700, 0xa473, 0x2000 }, + { 0x0700, 0xa472, 0x0000 }, + { 0x0700, 0xa474, 0x0000 }, + { 0x8700, 0xa479, 0x3000 }, + { 0x8700, 0xa477, 0x2000 }, + { 0x0700, 0xa476, 0x0000 }, + { 0x0700, 0xa478, 0x0000 }, + { 0x8700, 0xa47b, 0x2000 }, + { 0x0700, 0xa47a, 0x0000 }, + { 0x0700, 0xa47c, 0x0000 }, + { 0x8700, 0xa485, 0x4000 }, + { 0x8700, 0xa481, 0x3000 }, + { 0x8700, 0xa47f, 0x2000 }, + { 0x0700, 0xa47e, 0x0000 }, + { 0x0700, 0xa480, 0x0000 }, + { 0x8700, 0xa483, 0x2000 }, + { 0x0700, 0xa482, 0x0000 }, + { 0x0700, 0xa484, 0x0000 }, + { 0x8700, 0xa489, 0x3000 }, + { 0x8700, 0xa487, 0x2000 }, + { 0x0700, 0xa486, 0x0000 }, + { 0x0700, 0xa488, 0x0000 }, + { 0x8700, 0xa48b, 0x2000 }, + { 0x0700, 0xa48a, 0x0000 }, + { 0x0700, 0xa48c, 0x0000 }, + { 0x9a00, 0xa4b0, 0x6000 }, + { 0x9a00, 0xa4a0, 0x5000 }, + { 0x9a00, 0xa498, 0x4000 }, + { 0x9a00, 0xa494, 0x3000 }, + { 0x9a00, 0xa492, 0x2000 }, + { 0x1a00, 0xa491, 0x0000 }, + { 0x1a00, 0xa493, 0x0000 }, + { 0x9a00, 0xa496, 0x2000 }, + { 0x1a00, 0xa495, 0x0000 }, + { 0x1a00, 0xa497, 0x0000 }, + { 0x9a00, 0xa49c, 0x3000 }, + { 0x9a00, 0xa49a, 0x2000 }, + { 0x1a00, 0xa499, 0x0000 }, + { 0x1a00, 0xa49b, 0x0000 }, + { 0x9a00, 0xa49e, 0x2000 }, + { 0x1a00, 0xa49d, 0x0000 }, + { 0x1a00, 0xa49f, 0x0000 }, + { 0x9a00, 0xa4a8, 0x4000 }, + { 0x9a00, 0xa4a4, 0x3000 }, + { 0x9a00, 0xa4a2, 0x2000 }, + { 0x1a00, 0xa4a1, 0x0000 }, + { 0x1a00, 0xa4a3, 0x0000 }, + { 0x9a00, 0xa4a6, 0x2000 }, + { 0x1a00, 0xa4a5, 0x0000 }, + { 0x1a00, 0xa4a7, 0x0000 }, + { 0x9a00, 0xa4ac, 0x3000 }, + { 0x9a00, 0xa4aa, 0x2000 }, + { 0x1a00, 0xa4a9, 0x0000 }, + { 0x1a00, 0xa4ab, 0x0000 }, + { 0x9a00, 0xa4ae, 0x2000 }, + { 0x1a00, 0xa4ad, 0x0000 }, + { 0x1a00, 0xa4af, 0x0000 }, + { 0x9a00, 0xa4c0, 0x5000 }, + { 0x9a00, 0xa4b8, 0x4000 }, + { 0x9a00, 0xa4b4, 0x3000 }, + { 0x9a00, 0xa4b2, 0x2000 }, + { 0x1a00, 0xa4b1, 0x0000 }, + { 0x1a00, 0xa4b3, 0x0000 }, + { 0x9a00, 0xa4b6, 0x2000 }, + { 0x1a00, 0xa4b5, 0x0000 }, + { 0x1a00, 0xa4b7, 0x0000 }, + { 0x9a00, 0xa4bc, 0x3000 }, + { 0x9a00, 0xa4ba, 0x2000 }, + { 0x1a00, 0xa4b9, 0x0000 }, + { 0x1a00, 0xa4bb, 0x0000 }, + { 0x9a00, 0xa4be, 0x2000 }, + { 0x1a00, 0xa4bd, 0x0000 }, + { 0x1a00, 0xa4bf, 0x0000 }, + { 0x8700, 0xd7a3, 0x4000 }, + { 0x9a00, 0xa4c4, 0x3000 }, + { 0x9a00, 0xa4c2, 0x2000 }, + { 0x1a00, 0xa4c1, 0x0000 }, + { 0x1a00, 0xa4c3, 0x0000 }, + { 0x9a00, 0xa4c6, 0x2000 }, + { 0x1a00, 0xa4c5, 0x0000 }, + { 0x0700, 0xac00, 0x0000 }, + { 0x8400, 0xdbff, 0x3000 }, + { 0x8400, 0xdb7f, 0x2000 }, + { 0x0400, 0xd800, 0x0000 }, + { 0x0400, 0xdb80, 0x0000 }, + { 0x8400, 0xdfff, 0x2000 }, + { 0x0400, 0xdc00, 0x0000 }, + { 0x0300, 0xe000, 0x0000 }, + { 0x8700, 0xf93f, 0x7000 }, + { 0x8700, 0xf91f, 0x6000 }, + { 0x8700, 0xf90f, 0x5000 }, + { 0x8700, 0xf907, 0x4000 }, + { 0x8700, 0xf903, 0x3000 }, + { 0x8700, 0xf901, 0x2000 }, + { 0x0700, 0xf900, 0x0000 }, + { 0x0700, 0xf902, 0x0000 }, + { 0x8700, 0xf905, 0x2000 }, + { 0x0700, 0xf904, 0x0000 }, + { 0x0700, 0xf906, 0x0000 }, + { 0x8700, 0xf90b, 0x3000 }, + { 0x8700, 0xf909, 0x2000 }, + { 0x0700, 0xf908, 0x0000 }, + { 0x0700, 0xf90a, 0x0000 }, + { 0x8700, 0xf90d, 0x2000 }, + { 0x0700, 0xf90c, 0x0000 }, + { 0x0700, 0xf90e, 0x0000 }, + { 0x8700, 0xf917, 0x4000 }, + { 0x8700, 0xf913, 0x3000 }, + { 0x8700, 0xf911, 0x2000 }, + { 0x0700, 0xf910, 0x0000 }, + { 0x0700, 0xf912, 0x0000 }, + { 0x8700, 0xf915, 0x2000 }, + { 0x0700, 0xf914, 0x0000 }, + { 0x0700, 0xf916, 0x0000 }, + { 0x8700, 0xf91b, 0x3000 }, + { 0x8700, 0xf919, 0x2000 }, + { 0x0700, 0xf918, 0x0000 }, + { 0x0700, 0xf91a, 0x0000 }, + { 0x8700, 0xf91d, 0x2000 }, + { 0x0700, 0xf91c, 0x0000 }, + { 0x0700, 0xf91e, 0x0000 }, + { 0x8700, 0xf92f, 0x5000 }, + { 0x8700, 0xf927, 0x4000 }, + { 0x8700, 0xf923, 0x3000 }, + { 0x8700, 0xf921, 0x2000 }, + { 0x0700, 0xf920, 0x0000 }, + { 0x0700, 0xf922, 0x0000 }, + { 0x8700, 0xf925, 0x2000 }, + { 0x0700, 0xf924, 0x0000 }, + { 0x0700, 0xf926, 0x0000 }, + { 0x8700, 0xf92b, 0x3000 }, + { 0x8700, 0xf929, 0x2000 }, + { 0x0700, 0xf928, 0x0000 }, + { 0x0700, 0xf92a, 0x0000 }, + { 0x8700, 0xf92d, 0x2000 }, + { 0x0700, 0xf92c, 0x0000 }, + { 0x0700, 0xf92e, 0x0000 }, + { 0x8700, 0xf937, 0x4000 }, + { 0x8700, 0xf933, 0x3000 }, + { 0x8700, 0xf931, 0x2000 }, + { 0x0700, 0xf930, 0x0000 }, + { 0x0700, 0xf932, 0x0000 }, + { 0x8700, 0xf935, 0x2000 }, + { 0x0700, 0xf934, 0x0000 }, + { 0x0700, 0xf936, 0x0000 }, + { 0x8700, 0xf93b, 0x3000 }, + { 0x8700, 0xf939, 0x2000 }, + { 0x0700, 0xf938, 0x0000 }, + { 0x0700, 0xf93a, 0x0000 }, + { 0x8700, 0xf93d, 0x2000 }, + { 0x0700, 0xf93c, 0x0000 }, + { 0x0700, 0xf93e, 0x0000 }, + { 0x8700, 0xf95f, 0x6000 }, + { 0x8700, 0xf94f, 0x5000 }, + { 0x8700, 0xf947, 0x4000 }, + { 0x8700, 0xf943, 0x3000 }, + { 0x8700, 0xf941, 0x2000 }, + { 0x0700, 0xf940, 0x0000 }, + { 0x0700, 0xf942, 0x0000 }, + { 0x8700, 0xf945, 0x2000 }, + { 0x0700, 0xf944, 0x0000 }, + { 0x0700, 0xf946, 0x0000 }, + { 0x8700, 0xf94b, 0x3000 }, + { 0x8700, 0xf949, 0x2000 }, + { 0x0700, 0xf948, 0x0000 }, + { 0x0700, 0xf94a, 0x0000 }, + { 0x8700, 0xf94d, 0x2000 }, + { 0x0700, 0xf94c, 0x0000 }, + { 0x0700, 0xf94e, 0x0000 }, + { 0x8700, 0xf957, 0x4000 }, + { 0x8700, 0xf953, 0x3000 }, + { 0x8700, 0xf951, 0x2000 }, + { 0x0700, 0xf950, 0x0000 }, + { 0x0700, 0xf952, 0x0000 }, + { 0x8700, 0xf955, 0x2000 }, + { 0x0700, 0xf954, 0x0000 }, + { 0x0700, 0xf956, 0x0000 }, + { 0x8700, 0xf95b, 0x3000 }, + { 0x8700, 0xf959, 0x2000 }, + { 0x0700, 0xf958, 0x0000 }, + { 0x0700, 0xf95a, 0x0000 }, + { 0x8700, 0xf95d, 0x2000 }, + { 0x0700, 0xf95c, 0x0000 }, + { 0x0700, 0xf95e, 0x0000 }, + { 0x8700, 0xf96f, 0x5000 }, + { 0x8700, 0xf967, 0x4000 }, + { 0x8700, 0xf963, 0x3000 }, + { 0x8700, 0xf961, 0x2000 }, + { 0x0700, 0xf960, 0x0000 }, + { 0x0700, 0xf962, 0x0000 }, + { 0x8700, 0xf965, 0x2000 }, + { 0x0700, 0xf964, 0x0000 }, + { 0x0700, 0xf966, 0x0000 }, + { 0x8700, 0xf96b, 0x3000 }, + { 0x8700, 0xf969, 0x2000 }, + { 0x0700, 0xf968, 0x0000 }, + { 0x0700, 0xf96a, 0x0000 }, + { 0x8700, 0xf96d, 0x2000 }, + { 0x0700, 0xf96c, 0x0000 }, + { 0x0700, 0xf96e, 0x0000 }, + { 0x8700, 0xf977, 0x4000 }, + { 0x8700, 0xf973, 0x3000 }, + { 0x8700, 0xf971, 0x2000 }, + { 0x0700, 0xf970, 0x0000 }, + { 0x0700, 0xf972, 0x0000 }, + { 0x8700, 0xf975, 0x2000 }, + { 0x0700, 0xf974, 0x0000 }, + { 0x0700, 0xf976, 0x0000 }, + { 0x8700, 0xf97b, 0x3000 }, + { 0x8700, 0xf979, 0x2000 }, + { 0x0700, 0xf978, 0x0000 }, + { 0x0700, 0xf97a, 0x0000 }, + { 0x8700, 0xf97d, 0x2000 }, + { 0x0700, 0xf97c, 0x0000 }, + { 0x0700, 0xf97e, 0x0000 }, + { 0x8700, 0xfb27, 0x9000 }, + { 0x8700, 0xf9ff, 0x8000 }, + { 0x8700, 0xf9bf, 0x7000 }, + { 0x8700, 0xf99f, 0x6000 }, + { 0x8700, 0xf98f, 0x5000 }, + { 0x8700, 0xf987, 0x4000 }, + { 0x8700, 0xf983, 0x3000 }, + { 0x8700, 0xf981, 0x2000 }, + { 0x0700, 0xf980, 0x0000 }, + { 0x0700, 0xf982, 0x0000 }, + { 0x8700, 0xf985, 0x2000 }, + { 0x0700, 0xf984, 0x0000 }, + { 0x0700, 0xf986, 0x0000 }, + { 0x8700, 0xf98b, 0x3000 }, + { 0x8700, 0xf989, 0x2000 }, + { 0x0700, 0xf988, 0x0000 }, + { 0x0700, 0xf98a, 0x0000 }, + { 0x8700, 0xf98d, 0x2000 }, + { 0x0700, 0xf98c, 0x0000 }, + { 0x0700, 0xf98e, 0x0000 }, + { 0x8700, 0xf997, 0x4000 }, + { 0x8700, 0xf993, 0x3000 }, + { 0x8700, 0xf991, 0x2000 }, + { 0x0700, 0xf990, 0x0000 }, + { 0x0700, 0xf992, 0x0000 }, + { 0x8700, 0xf995, 0x2000 }, + { 0x0700, 0xf994, 0x0000 }, + { 0x0700, 0xf996, 0x0000 }, + { 0x8700, 0xf99b, 0x3000 }, + { 0x8700, 0xf999, 0x2000 }, + { 0x0700, 0xf998, 0x0000 }, + { 0x0700, 0xf99a, 0x0000 }, + { 0x8700, 0xf99d, 0x2000 }, + { 0x0700, 0xf99c, 0x0000 }, + { 0x0700, 0xf99e, 0x0000 }, + { 0x8700, 0xf9af, 0x5000 }, + { 0x8700, 0xf9a7, 0x4000 }, + { 0x8700, 0xf9a3, 0x3000 }, + { 0x8700, 0xf9a1, 0x2000 }, + { 0x0700, 0xf9a0, 0x0000 }, + { 0x0700, 0xf9a2, 0x0000 }, + { 0x8700, 0xf9a5, 0x2000 }, + { 0x0700, 0xf9a4, 0x0000 }, + { 0x0700, 0xf9a6, 0x0000 }, + { 0x8700, 0xf9ab, 0x3000 }, + { 0x8700, 0xf9a9, 0x2000 }, + { 0x0700, 0xf9a8, 0x0000 }, + { 0x0700, 0xf9aa, 0x0000 }, + { 0x8700, 0xf9ad, 0x2000 }, + { 0x0700, 0xf9ac, 0x0000 }, + { 0x0700, 0xf9ae, 0x0000 }, + { 0x8700, 0xf9b7, 0x4000 }, + { 0x8700, 0xf9b3, 0x3000 }, + { 0x8700, 0xf9b1, 0x2000 }, + { 0x0700, 0xf9b0, 0x0000 }, + { 0x0700, 0xf9b2, 0x0000 }, + { 0x8700, 0xf9b5, 0x2000 }, + { 0x0700, 0xf9b4, 0x0000 }, + { 0x0700, 0xf9b6, 0x0000 }, + { 0x8700, 0xf9bb, 0x3000 }, + { 0x8700, 0xf9b9, 0x2000 }, + { 0x0700, 0xf9b8, 0x0000 }, + { 0x0700, 0xf9ba, 0x0000 }, + { 0x8700, 0xf9bd, 0x2000 }, + { 0x0700, 0xf9bc, 0x0000 }, + { 0x0700, 0xf9be, 0x0000 }, + { 0x8700, 0xf9df, 0x6000 }, + { 0x8700, 0xf9cf, 0x5000 }, + { 0x8700, 0xf9c7, 0x4000 }, + { 0x8700, 0xf9c3, 0x3000 }, + { 0x8700, 0xf9c1, 0x2000 }, + { 0x0700, 0xf9c0, 0x0000 }, + { 0x0700, 0xf9c2, 0x0000 }, + { 0x8700, 0xf9c5, 0x2000 }, + { 0x0700, 0xf9c4, 0x0000 }, + { 0x0700, 0xf9c6, 0x0000 }, + { 0x8700, 0xf9cb, 0x3000 }, + { 0x8700, 0xf9c9, 0x2000 }, + { 0x0700, 0xf9c8, 0x0000 }, + { 0x0700, 0xf9ca, 0x0000 }, + { 0x8700, 0xf9cd, 0x2000 }, + { 0x0700, 0xf9cc, 0x0000 }, + { 0x0700, 0xf9ce, 0x0000 }, + { 0x8700, 0xf9d7, 0x4000 }, + { 0x8700, 0xf9d3, 0x3000 }, + { 0x8700, 0xf9d1, 0x2000 }, + { 0x0700, 0xf9d0, 0x0000 }, + { 0x0700, 0xf9d2, 0x0000 }, + { 0x8700, 0xf9d5, 0x2000 }, + { 0x0700, 0xf9d4, 0x0000 }, + { 0x0700, 0xf9d6, 0x0000 }, + { 0x8700, 0xf9db, 0x3000 }, + { 0x8700, 0xf9d9, 0x2000 }, + { 0x0700, 0xf9d8, 0x0000 }, + { 0x0700, 0xf9da, 0x0000 }, + { 0x8700, 0xf9dd, 0x2000 }, + { 0x0700, 0xf9dc, 0x0000 }, + { 0x0700, 0xf9de, 0x0000 }, + { 0x8700, 0xf9ef, 0x5000 }, + { 0x8700, 0xf9e7, 0x4000 }, + { 0x8700, 0xf9e3, 0x3000 }, + { 0x8700, 0xf9e1, 0x2000 }, + { 0x0700, 0xf9e0, 0x0000 }, + { 0x0700, 0xf9e2, 0x0000 }, + { 0x8700, 0xf9e5, 0x2000 }, + { 0x0700, 0xf9e4, 0x0000 }, + { 0x0700, 0xf9e6, 0x0000 }, + { 0x8700, 0xf9eb, 0x3000 }, + { 0x8700, 0xf9e9, 0x2000 }, + { 0x0700, 0xf9e8, 0x0000 }, + { 0x0700, 0xf9ea, 0x0000 }, + { 0x8700, 0xf9ed, 0x2000 }, + { 0x0700, 0xf9ec, 0x0000 }, + { 0x0700, 0xf9ee, 0x0000 }, + { 0x8700, 0xf9f7, 0x4000 }, + { 0x8700, 0xf9f3, 0x3000 }, + { 0x8700, 0xf9f1, 0x2000 }, + { 0x0700, 0xf9f0, 0x0000 }, + { 0x0700, 0xf9f2, 0x0000 }, + { 0x8700, 0xf9f5, 0x2000 }, + { 0x0700, 0xf9f4, 0x0000 }, + { 0x0700, 0xf9f6, 0x0000 }, + { 0x8700, 0xf9fb, 0x3000 }, + { 0x8700, 0xf9f9, 0x2000 }, + { 0x0700, 0xf9f8, 0x0000 }, + { 0x0700, 0xf9fa, 0x0000 }, + { 0x8700, 0xf9fd, 0x2000 }, + { 0x0700, 0xf9fc, 0x0000 }, + { 0x0700, 0xf9fe, 0x0000 }, + { 0x8700, 0xfa41, 0x7000 }, + { 0x8700, 0xfa1f, 0x6000 }, + { 0x8700, 0xfa0f, 0x5000 }, + { 0x8700, 0xfa07, 0x4000 }, + { 0x8700, 0xfa03, 0x3000 }, + { 0x8700, 0xfa01, 0x2000 }, + { 0x0700, 0xfa00, 0x0000 }, + { 0x0700, 0xfa02, 0x0000 }, + { 0x8700, 0xfa05, 0x2000 }, + { 0x0700, 0xfa04, 0x0000 }, + { 0x0700, 0xfa06, 0x0000 }, + { 0x8700, 0xfa0b, 0x3000 }, + { 0x8700, 0xfa09, 0x2000 }, + { 0x0700, 0xfa08, 0x0000 }, + { 0x0700, 0xfa0a, 0x0000 }, + { 0x8700, 0xfa0d, 0x2000 }, + { 0x0700, 0xfa0c, 0x0000 }, + { 0x0700, 0xfa0e, 0x0000 }, + { 0x8700, 0xfa17, 0x4000 }, + { 0x8700, 0xfa13, 0x3000 }, + { 0x8700, 0xfa11, 0x2000 }, + { 0x0700, 0xfa10, 0x0000 }, + { 0x0700, 0xfa12, 0x0000 }, + { 0x8700, 0xfa15, 0x2000 }, + { 0x0700, 0xfa14, 0x0000 }, + { 0x0700, 0xfa16, 0x0000 }, + { 0x8700, 0xfa1b, 0x3000 }, + { 0x8700, 0xfa19, 0x2000 }, + { 0x0700, 0xfa18, 0x0000 }, + { 0x0700, 0xfa1a, 0x0000 }, + { 0x8700, 0xfa1d, 0x2000 }, + { 0x0700, 0xfa1c, 0x0000 }, + { 0x0700, 0xfa1e, 0x0000 }, + { 0x8700, 0xfa31, 0x5000 }, + { 0x8700, 0xfa27, 0x4000 }, + { 0x8700, 0xfa23, 0x3000 }, + { 0x8700, 0xfa21, 0x2000 }, + { 0x0700, 0xfa20, 0x0000 }, + { 0x0700, 0xfa22, 0x0000 }, + { 0x8700, 0xfa25, 0x2000 }, + { 0x0700, 0xfa24, 0x0000 }, + { 0x0700, 0xfa26, 0x0000 }, + { 0x8700, 0xfa2b, 0x3000 }, + { 0x8700, 0xfa29, 0x2000 }, + { 0x0700, 0xfa28, 0x0000 }, + { 0x0700, 0xfa2a, 0x0000 }, + { 0x8700, 0xfa2d, 0x2000 }, + { 0x0700, 0xfa2c, 0x0000 }, + { 0x0700, 0xfa30, 0x0000 }, + { 0x8700, 0xfa39, 0x4000 }, + { 0x8700, 0xfa35, 0x3000 }, + { 0x8700, 0xfa33, 0x2000 }, + { 0x0700, 0xfa32, 0x0000 }, + { 0x0700, 0xfa34, 0x0000 }, + { 0x8700, 0xfa37, 0x2000 }, + { 0x0700, 0xfa36, 0x0000 }, + { 0x0700, 0xfa38, 0x0000 }, + { 0x8700, 0xfa3d, 0x3000 }, + { 0x8700, 0xfa3b, 0x2000 }, + { 0x0700, 0xfa3a, 0x0000 }, + { 0x0700, 0xfa3c, 0x0000 }, + { 0x8700, 0xfa3f, 0x2000 }, + { 0x0700, 0xfa3e, 0x0000 }, + { 0x0700, 0xfa40, 0x0000 }, + { 0x8700, 0xfa61, 0x6000 }, + { 0x8700, 0xfa51, 0x5000 }, + { 0x8700, 0xfa49, 0x4000 }, + { 0x8700, 0xfa45, 0x3000 }, + { 0x8700, 0xfa43, 0x2000 }, + { 0x0700, 0xfa42, 0x0000 }, + { 0x0700, 0xfa44, 0x0000 }, + { 0x8700, 0xfa47, 0x2000 }, + { 0x0700, 0xfa46, 0x0000 }, + { 0x0700, 0xfa48, 0x0000 }, + { 0x8700, 0xfa4d, 0x3000 }, + { 0x8700, 0xfa4b, 0x2000 }, + { 0x0700, 0xfa4a, 0x0000 }, + { 0x0700, 0xfa4c, 0x0000 }, + { 0x8700, 0xfa4f, 0x2000 }, + { 0x0700, 0xfa4e, 0x0000 }, + { 0x0700, 0xfa50, 0x0000 }, + { 0x8700, 0xfa59, 0x4000 }, + { 0x8700, 0xfa55, 0x3000 }, + { 0x8700, 0xfa53, 0x2000 }, + { 0x0700, 0xfa52, 0x0000 }, + { 0x0700, 0xfa54, 0x0000 }, + { 0x8700, 0xfa57, 0x2000 }, + { 0x0700, 0xfa56, 0x0000 }, + { 0x0700, 0xfa58, 0x0000 }, + { 0x8700, 0xfa5d, 0x3000 }, + { 0x8700, 0xfa5b, 0x2000 }, + { 0x0700, 0xfa5a, 0x0000 }, + { 0x0700, 0xfa5c, 0x0000 }, + { 0x8700, 0xfa5f, 0x2000 }, + { 0x0700, 0xfa5e, 0x0000 }, + { 0x0700, 0xfa60, 0x0000 }, + { 0x8500, 0xfb06, 0x5000 }, + { 0x8700, 0xfa69, 0x4000 }, + { 0x8700, 0xfa65, 0x3000 }, + { 0x8700, 0xfa63, 0x2000 }, + { 0x0700, 0xfa62, 0x0000 }, + { 0x0700, 0xfa64, 0x0000 }, + { 0x8700, 0xfa67, 0x2000 }, + { 0x0700, 0xfa66, 0x0000 }, + { 0x0700, 0xfa68, 0x0000 }, + { 0x8500, 0xfb02, 0x3000 }, + { 0x8500, 0xfb00, 0x2000 }, + { 0x0700, 0xfa6a, 0x0000 }, + { 0x0500, 0xfb01, 0x0000 }, + { 0x8500, 0xfb04, 0x2000 }, + { 0x0500, 0xfb03, 0x0000 }, + { 0x0500, 0xfb05, 0x0000 }, + { 0x8700, 0xfb1f, 0x4000 }, + { 0x8500, 0xfb16, 0x3000 }, + { 0x8500, 0xfb14, 0x2000 }, + { 0x0500, 0xfb13, 0x0000 }, + { 0x0500, 0xfb15, 0x0000 }, + { 0x8700, 0xfb1d, 0x2000 }, + { 0x0500, 0xfb17, 0x0000 }, + { 0x0c00, 0xfb1e, 0x0000 }, + { 0x8700, 0xfb23, 0x3000 }, + { 0x8700, 0xfb21, 0x2000 }, + { 0x0700, 0xfb20, 0x0000 }, + { 0x0700, 0xfb22, 0x0000 }, + { 0x8700, 0xfb25, 0x2000 }, + { 0x0700, 0xfb24, 0x0000 }, + { 0x0700, 0xfb26, 0x0000 }, + { 0x8700, 0xfbac, 0x8000 }, + { 0x8700, 0xfb6c, 0x7000 }, + { 0x8700, 0xfb4c, 0x6000 }, + { 0x8700, 0xfb38, 0x5000 }, + { 0x8700, 0xfb2f, 0x4000 }, + { 0x8700, 0xfb2b, 0x3000 }, + { 0x9900, 0xfb29, 0x2000 }, + { 0x0700, 0xfb28, 0x0000 }, + { 0x0700, 0xfb2a, 0x0000 }, + { 0x8700, 0xfb2d, 0x2000 }, + { 0x0700, 0xfb2c, 0x0000 }, + { 0x0700, 0xfb2e, 0x0000 }, + { 0x8700, 0xfb33, 0x3000 }, + { 0x8700, 0xfb31, 0x2000 }, + { 0x0700, 0xfb30, 0x0000 }, + { 0x0700, 0xfb32, 0x0000 }, + { 0x8700, 0xfb35, 0x2000 }, + { 0x0700, 0xfb34, 0x0000 }, + { 0x0700, 0xfb36, 0x0000 }, + { 0x8700, 0xfb43, 0x4000 }, + { 0x8700, 0xfb3c, 0x3000 }, + { 0x8700, 0xfb3a, 0x2000 }, + { 0x0700, 0xfb39, 0x0000 }, + { 0x0700, 0xfb3b, 0x0000 }, + { 0x8700, 0xfb40, 0x2000 }, + { 0x0700, 0xfb3e, 0x0000 }, + { 0x0700, 0xfb41, 0x0000 }, + { 0x8700, 0xfb48, 0x3000 }, + { 0x8700, 0xfb46, 0x2000 }, + { 0x0700, 0xfb44, 0x0000 }, + { 0x0700, 0xfb47, 0x0000 }, + { 0x8700, 0xfb4a, 0x2000 }, + { 0x0700, 0xfb49, 0x0000 }, + { 0x0700, 0xfb4b, 0x0000 }, + { 0x8700, 0xfb5c, 0x5000 }, + { 0x8700, 0xfb54, 0x4000 }, + { 0x8700, 0xfb50, 0x3000 }, + { 0x8700, 0xfb4e, 0x2000 }, + { 0x0700, 0xfb4d, 0x0000 }, + { 0x0700, 0xfb4f, 0x0000 }, + { 0x8700, 0xfb52, 0x2000 }, + { 0x0700, 0xfb51, 0x0000 }, + { 0x0700, 0xfb53, 0x0000 }, + { 0x8700, 0xfb58, 0x3000 }, + { 0x8700, 0xfb56, 0x2000 }, + { 0x0700, 0xfb55, 0x0000 }, + { 0x0700, 0xfb57, 0x0000 }, + { 0x8700, 0xfb5a, 0x2000 }, + { 0x0700, 0xfb59, 0x0000 }, + { 0x0700, 0xfb5b, 0x0000 }, + { 0x8700, 0xfb64, 0x4000 }, + { 0x8700, 0xfb60, 0x3000 }, + { 0x8700, 0xfb5e, 0x2000 }, + { 0x0700, 0xfb5d, 0x0000 }, + { 0x0700, 0xfb5f, 0x0000 }, + { 0x8700, 0xfb62, 0x2000 }, + { 0x0700, 0xfb61, 0x0000 }, + { 0x0700, 0xfb63, 0x0000 }, + { 0x8700, 0xfb68, 0x3000 }, + { 0x8700, 0xfb66, 0x2000 }, + { 0x0700, 0xfb65, 0x0000 }, + { 0x0700, 0xfb67, 0x0000 }, + { 0x8700, 0xfb6a, 0x2000 }, + { 0x0700, 0xfb69, 0x0000 }, + { 0x0700, 0xfb6b, 0x0000 }, + { 0x8700, 0xfb8c, 0x6000 }, + { 0x8700, 0xfb7c, 0x5000 }, + { 0x8700, 0xfb74, 0x4000 }, + { 0x8700, 0xfb70, 0x3000 }, + { 0x8700, 0xfb6e, 0x2000 }, + { 0x0700, 0xfb6d, 0x0000 }, + { 0x0700, 0xfb6f, 0x0000 }, + { 0x8700, 0xfb72, 0x2000 }, + { 0x0700, 0xfb71, 0x0000 }, + { 0x0700, 0xfb73, 0x0000 }, + { 0x8700, 0xfb78, 0x3000 }, + { 0x8700, 0xfb76, 0x2000 }, + { 0x0700, 0xfb75, 0x0000 }, + { 0x0700, 0xfb77, 0x0000 }, + { 0x8700, 0xfb7a, 0x2000 }, + { 0x0700, 0xfb79, 0x0000 }, + { 0x0700, 0xfb7b, 0x0000 }, + { 0x8700, 0xfb84, 0x4000 }, + { 0x8700, 0xfb80, 0x3000 }, + { 0x8700, 0xfb7e, 0x2000 }, + { 0x0700, 0xfb7d, 0x0000 }, + { 0x0700, 0xfb7f, 0x0000 }, + { 0x8700, 0xfb82, 0x2000 }, + { 0x0700, 0xfb81, 0x0000 }, + { 0x0700, 0xfb83, 0x0000 }, + { 0x8700, 0xfb88, 0x3000 }, + { 0x8700, 0xfb86, 0x2000 }, + { 0x0700, 0xfb85, 0x0000 }, + { 0x0700, 0xfb87, 0x0000 }, + { 0x8700, 0xfb8a, 0x2000 }, + { 0x0700, 0xfb89, 0x0000 }, + { 0x0700, 0xfb8b, 0x0000 }, + { 0x8700, 0xfb9c, 0x5000 }, + { 0x8700, 0xfb94, 0x4000 }, + { 0x8700, 0xfb90, 0x3000 }, + { 0x8700, 0xfb8e, 0x2000 }, + { 0x0700, 0xfb8d, 0x0000 }, + { 0x0700, 0xfb8f, 0x0000 }, + { 0x8700, 0xfb92, 0x2000 }, + { 0x0700, 0xfb91, 0x0000 }, + { 0x0700, 0xfb93, 0x0000 }, + { 0x8700, 0xfb98, 0x3000 }, + { 0x8700, 0xfb96, 0x2000 }, + { 0x0700, 0xfb95, 0x0000 }, + { 0x0700, 0xfb97, 0x0000 }, + { 0x8700, 0xfb9a, 0x2000 }, + { 0x0700, 0xfb99, 0x0000 }, + { 0x0700, 0xfb9b, 0x0000 }, + { 0x8700, 0xfba4, 0x4000 }, + { 0x8700, 0xfba0, 0x3000 }, + { 0x8700, 0xfb9e, 0x2000 }, + { 0x0700, 0xfb9d, 0x0000 }, + { 0x0700, 0xfb9f, 0x0000 }, + { 0x8700, 0xfba2, 0x2000 }, + { 0x0700, 0xfba1, 0x0000 }, + { 0x0700, 0xfba3, 0x0000 }, + { 0x8700, 0xfba8, 0x3000 }, + { 0x8700, 0xfba6, 0x2000 }, + { 0x0700, 0xfba5, 0x0000 }, + { 0x0700, 0xfba7, 0x0000 }, + { 0x8700, 0xfbaa, 0x2000 }, + { 0x0700, 0xfba9, 0x0000 }, + { 0x0700, 0xfbab, 0x0000 }, + { 0x8700, 0xfc0d, 0x7000 }, + { 0x8700, 0xfbed, 0x6000 }, + { 0x8700, 0xfbdd, 0x5000 }, + { 0x8700, 0xfbd5, 0x4000 }, + { 0x8700, 0xfbb0, 0x3000 }, + { 0x8700, 0xfbae, 0x2000 }, + { 0x0700, 0xfbad, 0x0000 }, + { 0x0700, 0xfbaf, 0x0000 }, + { 0x8700, 0xfbd3, 0x2000 }, + { 0x0700, 0xfbb1, 0x0000 }, + { 0x0700, 0xfbd4, 0x0000 }, + { 0x8700, 0xfbd9, 0x3000 }, + { 0x8700, 0xfbd7, 0x2000 }, + { 0x0700, 0xfbd6, 0x0000 }, + { 0x0700, 0xfbd8, 0x0000 }, + { 0x8700, 0xfbdb, 0x2000 }, + { 0x0700, 0xfbda, 0x0000 }, + { 0x0700, 0xfbdc, 0x0000 }, + { 0x8700, 0xfbe5, 0x4000 }, + { 0x8700, 0xfbe1, 0x3000 }, + { 0x8700, 0xfbdf, 0x2000 }, + { 0x0700, 0xfbde, 0x0000 }, + { 0x0700, 0xfbe0, 0x0000 }, + { 0x8700, 0xfbe3, 0x2000 }, + { 0x0700, 0xfbe2, 0x0000 }, + { 0x0700, 0xfbe4, 0x0000 }, + { 0x8700, 0xfbe9, 0x3000 }, + { 0x8700, 0xfbe7, 0x2000 }, + { 0x0700, 0xfbe6, 0x0000 }, + { 0x0700, 0xfbe8, 0x0000 }, + { 0x8700, 0xfbeb, 0x2000 }, + { 0x0700, 0xfbea, 0x0000 }, + { 0x0700, 0xfbec, 0x0000 }, + { 0x8700, 0xfbfd, 0x5000 }, + { 0x8700, 0xfbf5, 0x4000 }, + { 0x8700, 0xfbf1, 0x3000 }, + { 0x8700, 0xfbef, 0x2000 }, + { 0x0700, 0xfbee, 0x0000 }, + { 0x0700, 0xfbf0, 0x0000 }, + { 0x8700, 0xfbf3, 0x2000 }, + { 0x0700, 0xfbf2, 0x0000 }, + { 0x0700, 0xfbf4, 0x0000 }, + { 0x8700, 0xfbf9, 0x3000 }, + { 0x8700, 0xfbf7, 0x2000 }, + { 0x0700, 0xfbf6, 0x0000 }, + { 0x0700, 0xfbf8, 0x0000 }, + { 0x8700, 0xfbfb, 0x2000 }, + { 0x0700, 0xfbfa, 0x0000 }, + { 0x0700, 0xfbfc, 0x0000 }, + { 0x8700, 0xfc05, 0x4000 }, + { 0x8700, 0xfc01, 0x3000 }, + { 0x8700, 0xfbff, 0x2000 }, + { 0x0700, 0xfbfe, 0x0000 }, + { 0x0700, 0xfc00, 0x0000 }, + { 0x8700, 0xfc03, 0x2000 }, + { 0x0700, 0xfc02, 0x0000 }, + { 0x0700, 0xfc04, 0x0000 }, + { 0x8700, 0xfc09, 0x3000 }, + { 0x8700, 0xfc07, 0x2000 }, + { 0x0700, 0xfc06, 0x0000 }, + { 0x0700, 0xfc08, 0x0000 }, + { 0x8700, 0xfc0b, 0x2000 }, + { 0x0700, 0xfc0a, 0x0000 }, + { 0x0700, 0xfc0c, 0x0000 }, + { 0x8700, 0xfc2d, 0x6000 }, + { 0x8700, 0xfc1d, 0x5000 }, + { 0x8700, 0xfc15, 0x4000 }, + { 0x8700, 0xfc11, 0x3000 }, + { 0x8700, 0xfc0f, 0x2000 }, + { 0x0700, 0xfc0e, 0x0000 }, + { 0x0700, 0xfc10, 0x0000 }, + { 0x8700, 0xfc13, 0x2000 }, + { 0x0700, 0xfc12, 0x0000 }, + { 0x0700, 0xfc14, 0x0000 }, + { 0x8700, 0xfc19, 0x3000 }, + { 0x8700, 0xfc17, 0x2000 }, + { 0x0700, 0xfc16, 0x0000 }, + { 0x0700, 0xfc18, 0x0000 }, + { 0x8700, 0xfc1b, 0x2000 }, + { 0x0700, 0xfc1a, 0x0000 }, + { 0x0700, 0xfc1c, 0x0000 }, + { 0x8700, 0xfc25, 0x4000 }, + { 0x8700, 0xfc21, 0x3000 }, + { 0x8700, 0xfc1f, 0x2000 }, + { 0x0700, 0xfc1e, 0x0000 }, + { 0x0700, 0xfc20, 0x0000 }, + { 0x8700, 0xfc23, 0x2000 }, + { 0x0700, 0xfc22, 0x0000 }, + { 0x0700, 0xfc24, 0x0000 }, + { 0x8700, 0xfc29, 0x3000 }, + { 0x8700, 0xfc27, 0x2000 }, + { 0x0700, 0xfc26, 0x0000 }, + { 0x0700, 0xfc28, 0x0000 }, + { 0x8700, 0xfc2b, 0x2000 }, + { 0x0700, 0xfc2a, 0x0000 }, + { 0x0700, 0xfc2c, 0x0000 }, + { 0x8700, 0xfc3d, 0x5000 }, + { 0x8700, 0xfc35, 0x4000 }, + { 0x8700, 0xfc31, 0x3000 }, + { 0x8700, 0xfc2f, 0x2000 }, + { 0x0700, 0xfc2e, 0x0000 }, + { 0x0700, 0xfc30, 0x0000 }, + { 0x8700, 0xfc33, 0x2000 }, + { 0x0700, 0xfc32, 0x0000 }, + { 0x0700, 0xfc34, 0x0000 }, + { 0x8700, 0xfc39, 0x3000 }, + { 0x8700, 0xfc37, 0x2000 }, + { 0x0700, 0xfc36, 0x0000 }, + { 0x0700, 0xfc38, 0x0000 }, + { 0x8700, 0xfc3b, 0x2000 }, + { 0x0700, 0xfc3a, 0x0000 }, + { 0x0700, 0xfc3c, 0x0000 }, + { 0x8700, 0xfc45, 0x4000 }, + { 0x8700, 0xfc41, 0x3000 }, + { 0x8700, 0xfc3f, 0x2000 }, + { 0x0700, 0xfc3e, 0x0000 }, + { 0x0700, 0xfc40, 0x0000 }, + { 0x8700, 0xfc43, 0x2000 }, + { 0x0700, 0xfc42, 0x0000 }, + { 0x0700, 0xfc44, 0x0000 }, + { 0x8700, 0xfc49, 0x3000 }, + { 0x8700, 0xfc47, 0x2000 }, + { 0x0700, 0xfc46, 0x0000 }, + { 0x0700, 0xfc48, 0x0000 }, + { 0x8700, 0xfc4b, 0x2000 }, + { 0x0700, 0xfc4a, 0x0000 }, + { 0x0700, 0xfc4c, 0x0000 }, + { 0x8700, 0xfeac, 0xa000 }, + { 0x8700, 0xfd5d, 0x9000 }, + { 0x8700, 0xfccd, 0x8000 }, + { 0x8700, 0xfc8d, 0x7000 }, + { 0x8700, 0xfc6d, 0x6000 }, + { 0x8700, 0xfc5d, 0x5000 }, + { 0x8700, 0xfc55, 0x4000 }, + { 0x8700, 0xfc51, 0x3000 }, + { 0x8700, 0xfc4f, 0x2000 }, + { 0x0700, 0xfc4e, 0x0000 }, + { 0x0700, 0xfc50, 0x0000 }, + { 0x8700, 0xfc53, 0x2000 }, + { 0x0700, 0xfc52, 0x0000 }, + { 0x0700, 0xfc54, 0x0000 }, + { 0x8700, 0xfc59, 0x3000 }, + { 0x8700, 0xfc57, 0x2000 }, + { 0x0700, 0xfc56, 0x0000 }, + { 0x0700, 0xfc58, 0x0000 }, + { 0x8700, 0xfc5b, 0x2000 }, + { 0x0700, 0xfc5a, 0x0000 }, + { 0x0700, 0xfc5c, 0x0000 }, + { 0x8700, 0xfc65, 0x4000 }, + { 0x8700, 0xfc61, 0x3000 }, + { 0x8700, 0xfc5f, 0x2000 }, + { 0x0700, 0xfc5e, 0x0000 }, + { 0x0700, 0xfc60, 0x0000 }, + { 0x8700, 0xfc63, 0x2000 }, + { 0x0700, 0xfc62, 0x0000 }, + { 0x0700, 0xfc64, 0x0000 }, + { 0x8700, 0xfc69, 0x3000 }, + { 0x8700, 0xfc67, 0x2000 }, + { 0x0700, 0xfc66, 0x0000 }, + { 0x0700, 0xfc68, 0x0000 }, + { 0x8700, 0xfc6b, 0x2000 }, + { 0x0700, 0xfc6a, 0x0000 }, + { 0x0700, 0xfc6c, 0x0000 }, + { 0x8700, 0xfc7d, 0x5000 }, + { 0x8700, 0xfc75, 0x4000 }, + { 0x8700, 0xfc71, 0x3000 }, + { 0x8700, 0xfc6f, 0x2000 }, + { 0x0700, 0xfc6e, 0x0000 }, + { 0x0700, 0xfc70, 0x0000 }, + { 0x8700, 0xfc73, 0x2000 }, + { 0x0700, 0xfc72, 0x0000 }, + { 0x0700, 0xfc74, 0x0000 }, + { 0x8700, 0xfc79, 0x3000 }, + { 0x8700, 0xfc77, 0x2000 }, + { 0x0700, 0xfc76, 0x0000 }, + { 0x0700, 0xfc78, 0x0000 }, + { 0x8700, 0xfc7b, 0x2000 }, + { 0x0700, 0xfc7a, 0x0000 }, + { 0x0700, 0xfc7c, 0x0000 }, + { 0x8700, 0xfc85, 0x4000 }, + { 0x8700, 0xfc81, 0x3000 }, + { 0x8700, 0xfc7f, 0x2000 }, + { 0x0700, 0xfc7e, 0x0000 }, + { 0x0700, 0xfc80, 0x0000 }, + { 0x8700, 0xfc83, 0x2000 }, + { 0x0700, 0xfc82, 0x0000 }, + { 0x0700, 0xfc84, 0x0000 }, + { 0x8700, 0xfc89, 0x3000 }, + { 0x8700, 0xfc87, 0x2000 }, + { 0x0700, 0xfc86, 0x0000 }, + { 0x0700, 0xfc88, 0x0000 }, + { 0x8700, 0xfc8b, 0x2000 }, + { 0x0700, 0xfc8a, 0x0000 }, + { 0x0700, 0xfc8c, 0x0000 }, + { 0x8700, 0xfcad, 0x6000 }, + { 0x8700, 0xfc9d, 0x5000 }, + { 0x8700, 0xfc95, 0x4000 }, + { 0x8700, 0xfc91, 0x3000 }, + { 0x8700, 0xfc8f, 0x2000 }, + { 0x0700, 0xfc8e, 0x0000 }, + { 0x0700, 0xfc90, 0x0000 }, + { 0x8700, 0xfc93, 0x2000 }, + { 0x0700, 0xfc92, 0x0000 }, + { 0x0700, 0xfc94, 0x0000 }, + { 0x8700, 0xfc99, 0x3000 }, + { 0x8700, 0xfc97, 0x2000 }, + { 0x0700, 0xfc96, 0x0000 }, + { 0x0700, 0xfc98, 0x0000 }, + { 0x8700, 0xfc9b, 0x2000 }, + { 0x0700, 0xfc9a, 0x0000 }, + { 0x0700, 0xfc9c, 0x0000 }, + { 0x8700, 0xfca5, 0x4000 }, + { 0x8700, 0xfca1, 0x3000 }, + { 0x8700, 0xfc9f, 0x2000 }, + { 0x0700, 0xfc9e, 0x0000 }, + { 0x0700, 0xfca0, 0x0000 }, + { 0x8700, 0xfca3, 0x2000 }, + { 0x0700, 0xfca2, 0x0000 }, + { 0x0700, 0xfca4, 0x0000 }, + { 0x8700, 0xfca9, 0x3000 }, + { 0x8700, 0xfca7, 0x2000 }, + { 0x0700, 0xfca6, 0x0000 }, + { 0x0700, 0xfca8, 0x0000 }, + { 0x8700, 0xfcab, 0x2000 }, + { 0x0700, 0xfcaa, 0x0000 }, + { 0x0700, 0xfcac, 0x0000 }, + { 0x8700, 0xfcbd, 0x5000 }, + { 0x8700, 0xfcb5, 0x4000 }, + { 0x8700, 0xfcb1, 0x3000 }, + { 0x8700, 0xfcaf, 0x2000 }, + { 0x0700, 0xfcae, 0x0000 }, + { 0x0700, 0xfcb0, 0x0000 }, + { 0x8700, 0xfcb3, 0x2000 }, + { 0x0700, 0xfcb2, 0x0000 }, + { 0x0700, 0xfcb4, 0x0000 }, + { 0x8700, 0xfcb9, 0x3000 }, + { 0x8700, 0xfcb7, 0x2000 }, + { 0x0700, 0xfcb6, 0x0000 }, + { 0x0700, 0xfcb8, 0x0000 }, + { 0x8700, 0xfcbb, 0x2000 }, + { 0x0700, 0xfcba, 0x0000 }, + { 0x0700, 0xfcbc, 0x0000 }, + { 0x8700, 0xfcc5, 0x4000 }, + { 0x8700, 0xfcc1, 0x3000 }, + { 0x8700, 0xfcbf, 0x2000 }, + { 0x0700, 0xfcbe, 0x0000 }, + { 0x0700, 0xfcc0, 0x0000 }, + { 0x8700, 0xfcc3, 0x2000 }, + { 0x0700, 0xfcc2, 0x0000 }, + { 0x0700, 0xfcc4, 0x0000 }, + { 0x8700, 0xfcc9, 0x3000 }, + { 0x8700, 0xfcc7, 0x2000 }, + { 0x0700, 0xfcc6, 0x0000 }, + { 0x0700, 0xfcc8, 0x0000 }, + { 0x8700, 0xfccb, 0x2000 }, + { 0x0700, 0xfcca, 0x0000 }, + { 0x0700, 0xfccc, 0x0000 }, + { 0x8700, 0xfd0d, 0x7000 }, + { 0x8700, 0xfced, 0x6000 }, + { 0x8700, 0xfcdd, 0x5000 }, + { 0x8700, 0xfcd5, 0x4000 }, + { 0x8700, 0xfcd1, 0x3000 }, + { 0x8700, 0xfccf, 0x2000 }, + { 0x0700, 0xfcce, 0x0000 }, + { 0x0700, 0xfcd0, 0x0000 }, + { 0x8700, 0xfcd3, 0x2000 }, + { 0x0700, 0xfcd2, 0x0000 }, + { 0x0700, 0xfcd4, 0x0000 }, + { 0x8700, 0xfcd9, 0x3000 }, + { 0x8700, 0xfcd7, 0x2000 }, + { 0x0700, 0xfcd6, 0x0000 }, + { 0x0700, 0xfcd8, 0x0000 }, + { 0x8700, 0xfcdb, 0x2000 }, + { 0x0700, 0xfcda, 0x0000 }, + { 0x0700, 0xfcdc, 0x0000 }, + { 0x8700, 0xfce5, 0x4000 }, + { 0x8700, 0xfce1, 0x3000 }, + { 0x8700, 0xfcdf, 0x2000 }, + { 0x0700, 0xfcde, 0x0000 }, + { 0x0700, 0xfce0, 0x0000 }, + { 0x8700, 0xfce3, 0x2000 }, + { 0x0700, 0xfce2, 0x0000 }, + { 0x0700, 0xfce4, 0x0000 }, + { 0x8700, 0xfce9, 0x3000 }, + { 0x8700, 0xfce7, 0x2000 }, + { 0x0700, 0xfce6, 0x0000 }, + { 0x0700, 0xfce8, 0x0000 }, + { 0x8700, 0xfceb, 0x2000 }, + { 0x0700, 0xfcea, 0x0000 }, + { 0x0700, 0xfcec, 0x0000 }, + { 0x8700, 0xfcfd, 0x5000 }, + { 0x8700, 0xfcf5, 0x4000 }, + { 0x8700, 0xfcf1, 0x3000 }, + { 0x8700, 0xfcef, 0x2000 }, + { 0x0700, 0xfcee, 0x0000 }, + { 0x0700, 0xfcf0, 0x0000 }, + { 0x8700, 0xfcf3, 0x2000 }, + { 0x0700, 0xfcf2, 0x0000 }, + { 0x0700, 0xfcf4, 0x0000 }, + { 0x8700, 0xfcf9, 0x3000 }, + { 0x8700, 0xfcf7, 0x2000 }, + { 0x0700, 0xfcf6, 0x0000 }, + { 0x0700, 0xfcf8, 0x0000 }, + { 0x8700, 0xfcfb, 0x2000 }, + { 0x0700, 0xfcfa, 0x0000 }, + { 0x0700, 0xfcfc, 0x0000 }, + { 0x8700, 0xfd05, 0x4000 }, + { 0x8700, 0xfd01, 0x3000 }, + { 0x8700, 0xfcff, 0x2000 }, + { 0x0700, 0xfcfe, 0x0000 }, + { 0x0700, 0xfd00, 0x0000 }, + { 0x8700, 0xfd03, 0x2000 }, + { 0x0700, 0xfd02, 0x0000 }, + { 0x0700, 0xfd04, 0x0000 }, + { 0x8700, 0xfd09, 0x3000 }, + { 0x8700, 0xfd07, 0x2000 }, + { 0x0700, 0xfd06, 0x0000 }, + { 0x0700, 0xfd08, 0x0000 }, + { 0x8700, 0xfd0b, 0x2000 }, + { 0x0700, 0xfd0a, 0x0000 }, + { 0x0700, 0xfd0c, 0x0000 }, + { 0x8700, 0xfd2d, 0x6000 }, + { 0x8700, 0xfd1d, 0x5000 }, + { 0x8700, 0xfd15, 0x4000 }, + { 0x8700, 0xfd11, 0x3000 }, + { 0x8700, 0xfd0f, 0x2000 }, + { 0x0700, 0xfd0e, 0x0000 }, + { 0x0700, 0xfd10, 0x0000 }, + { 0x8700, 0xfd13, 0x2000 }, + { 0x0700, 0xfd12, 0x0000 }, + { 0x0700, 0xfd14, 0x0000 }, + { 0x8700, 0xfd19, 0x3000 }, + { 0x8700, 0xfd17, 0x2000 }, + { 0x0700, 0xfd16, 0x0000 }, + { 0x0700, 0xfd18, 0x0000 }, + { 0x8700, 0xfd1b, 0x2000 }, + { 0x0700, 0xfd1a, 0x0000 }, + { 0x0700, 0xfd1c, 0x0000 }, + { 0x8700, 0xfd25, 0x4000 }, + { 0x8700, 0xfd21, 0x3000 }, + { 0x8700, 0xfd1f, 0x2000 }, + { 0x0700, 0xfd1e, 0x0000 }, + { 0x0700, 0xfd20, 0x0000 }, + { 0x8700, 0xfd23, 0x2000 }, + { 0x0700, 0xfd22, 0x0000 }, + { 0x0700, 0xfd24, 0x0000 }, + { 0x8700, 0xfd29, 0x3000 }, + { 0x8700, 0xfd27, 0x2000 }, + { 0x0700, 0xfd26, 0x0000 }, + { 0x0700, 0xfd28, 0x0000 }, + { 0x8700, 0xfd2b, 0x2000 }, + { 0x0700, 0xfd2a, 0x0000 }, + { 0x0700, 0xfd2c, 0x0000 }, + { 0x8700, 0xfd3d, 0x5000 }, + { 0x8700, 0xfd35, 0x4000 }, + { 0x8700, 0xfd31, 0x3000 }, + { 0x8700, 0xfd2f, 0x2000 }, + { 0x0700, 0xfd2e, 0x0000 }, + { 0x0700, 0xfd30, 0x0000 }, + { 0x8700, 0xfd33, 0x2000 }, + { 0x0700, 0xfd32, 0x0000 }, + { 0x0700, 0xfd34, 0x0000 }, + { 0x8700, 0xfd39, 0x3000 }, + { 0x8700, 0xfd37, 0x2000 }, + { 0x0700, 0xfd36, 0x0000 }, + { 0x0700, 0xfd38, 0x0000 }, + { 0x8700, 0xfd3b, 0x2000 }, + { 0x0700, 0xfd3a, 0x0000 }, + { 0x0700, 0xfd3c, 0x0000 }, + { 0x8700, 0xfd55, 0x4000 }, + { 0x8700, 0xfd51, 0x3000 }, + { 0x9200, 0xfd3f, 0x2000 }, + { 0x1600, 0xfd3e, 0x0000 }, + { 0x0700, 0xfd50, 0x0000 }, + { 0x8700, 0xfd53, 0x2000 }, + { 0x0700, 0xfd52, 0x0000 }, + { 0x0700, 0xfd54, 0x0000 }, + { 0x8700, 0xfd59, 0x3000 }, + { 0x8700, 0xfd57, 0x2000 }, + { 0x0700, 0xfd56, 0x0000 }, + { 0x0700, 0xfd58, 0x0000 }, + { 0x8700, 0xfd5b, 0x2000 }, + { 0x0700, 0xfd5a, 0x0000 }, + { 0x0700, 0xfd5c, 0x0000 }, + { 0x8c00, 0xfe09, 0x8000 }, + { 0x8700, 0xfd9f, 0x7000 }, + { 0x8700, 0xfd7d, 0x6000 }, + { 0x8700, 0xfd6d, 0x5000 }, + { 0x8700, 0xfd65, 0x4000 }, + { 0x8700, 0xfd61, 0x3000 }, + { 0x8700, 0xfd5f, 0x2000 }, + { 0x0700, 0xfd5e, 0x0000 }, + { 0x0700, 0xfd60, 0x0000 }, + { 0x8700, 0xfd63, 0x2000 }, + { 0x0700, 0xfd62, 0x0000 }, + { 0x0700, 0xfd64, 0x0000 }, + { 0x8700, 0xfd69, 0x3000 }, + { 0x8700, 0xfd67, 0x2000 }, + { 0x0700, 0xfd66, 0x0000 }, + { 0x0700, 0xfd68, 0x0000 }, + { 0x8700, 0xfd6b, 0x2000 }, + { 0x0700, 0xfd6a, 0x0000 }, + { 0x0700, 0xfd6c, 0x0000 }, + { 0x8700, 0xfd75, 0x4000 }, + { 0x8700, 0xfd71, 0x3000 }, + { 0x8700, 0xfd6f, 0x2000 }, + { 0x0700, 0xfd6e, 0x0000 }, + { 0x0700, 0xfd70, 0x0000 }, + { 0x8700, 0xfd73, 0x2000 }, + { 0x0700, 0xfd72, 0x0000 }, + { 0x0700, 0xfd74, 0x0000 }, + { 0x8700, 0xfd79, 0x3000 }, + { 0x8700, 0xfd77, 0x2000 }, + { 0x0700, 0xfd76, 0x0000 }, + { 0x0700, 0xfd78, 0x0000 }, + { 0x8700, 0xfd7b, 0x2000 }, + { 0x0700, 0xfd7a, 0x0000 }, + { 0x0700, 0xfd7c, 0x0000 }, + { 0x8700, 0xfd8d, 0x5000 }, + { 0x8700, 0xfd85, 0x4000 }, + { 0x8700, 0xfd81, 0x3000 }, + { 0x8700, 0xfd7f, 0x2000 }, + { 0x0700, 0xfd7e, 0x0000 }, + { 0x0700, 0xfd80, 0x0000 }, + { 0x8700, 0xfd83, 0x2000 }, + { 0x0700, 0xfd82, 0x0000 }, + { 0x0700, 0xfd84, 0x0000 }, + { 0x8700, 0xfd89, 0x3000 }, + { 0x8700, 0xfd87, 0x2000 }, + { 0x0700, 0xfd86, 0x0000 }, + { 0x0700, 0xfd88, 0x0000 }, + { 0x8700, 0xfd8b, 0x2000 }, + { 0x0700, 0xfd8a, 0x0000 }, + { 0x0700, 0xfd8c, 0x0000 }, + { 0x8700, 0xfd97, 0x4000 }, + { 0x8700, 0xfd93, 0x3000 }, + { 0x8700, 0xfd8f, 0x2000 }, + { 0x0700, 0xfd8e, 0x0000 }, + { 0x0700, 0xfd92, 0x0000 }, + { 0x8700, 0xfd95, 0x2000 }, + { 0x0700, 0xfd94, 0x0000 }, + { 0x0700, 0xfd96, 0x0000 }, + { 0x8700, 0xfd9b, 0x3000 }, + { 0x8700, 0xfd99, 0x2000 }, + { 0x0700, 0xfd98, 0x0000 }, + { 0x0700, 0xfd9a, 0x0000 }, + { 0x8700, 0xfd9d, 0x2000 }, + { 0x0700, 0xfd9c, 0x0000 }, + { 0x0700, 0xfd9e, 0x0000 }, + { 0x8700, 0xfdbf, 0x6000 }, + { 0x8700, 0xfdaf, 0x5000 }, + { 0x8700, 0xfda7, 0x4000 }, + { 0x8700, 0xfda3, 0x3000 }, + { 0x8700, 0xfda1, 0x2000 }, + { 0x0700, 0xfda0, 0x0000 }, + { 0x0700, 0xfda2, 0x0000 }, + { 0x8700, 0xfda5, 0x2000 }, + { 0x0700, 0xfda4, 0x0000 }, + { 0x0700, 0xfda6, 0x0000 }, + { 0x8700, 0xfdab, 0x3000 }, + { 0x8700, 0xfda9, 0x2000 }, + { 0x0700, 0xfda8, 0x0000 }, + { 0x0700, 0xfdaa, 0x0000 }, + { 0x8700, 0xfdad, 0x2000 }, + { 0x0700, 0xfdac, 0x0000 }, + { 0x0700, 0xfdae, 0x0000 }, + { 0x8700, 0xfdb7, 0x4000 }, + { 0x8700, 0xfdb3, 0x3000 }, + { 0x8700, 0xfdb1, 0x2000 }, + { 0x0700, 0xfdb0, 0x0000 }, + { 0x0700, 0xfdb2, 0x0000 }, + { 0x8700, 0xfdb5, 0x2000 }, + { 0x0700, 0xfdb4, 0x0000 }, + { 0x0700, 0xfdb6, 0x0000 }, + { 0x8700, 0xfdbb, 0x3000 }, + { 0x8700, 0xfdb9, 0x2000 }, + { 0x0700, 0xfdb8, 0x0000 }, + { 0x0700, 0xfdba, 0x0000 }, + { 0x8700, 0xfdbd, 0x2000 }, + { 0x0700, 0xfdbc, 0x0000 }, + { 0x0700, 0xfdbe, 0x0000 }, + { 0x8700, 0xfdf7, 0x5000 }, + { 0x8700, 0xfdc7, 0x4000 }, + { 0x8700, 0xfdc3, 0x3000 }, + { 0x8700, 0xfdc1, 0x2000 }, + { 0x0700, 0xfdc0, 0x0000 }, + { 0x0700, 0xfdc2, 0x0000 }, + { 0x8700, 0xfdc5, 0x2000 }, + { 0x0700, 0xfdc4, 0x0000 }, + { 0x0700, 0xfdc6, 0x0000 }, + { 0x8700, 0xfdf3, 0x3000 }, + { 0x8700, 0xfdf1, 0x2000 }, + { 0x0700, 0xfdf0, 0x0000 }, + { 0x0700, 0xfdf2, 0x0000 }, + { 0x8700, 0xfdf5, 0x2000 }, + { 0x0700, 0xfdf4, 0x0000 }, + { 0x0700, 0xfdf6, 0x0000 }, + { 0x8c00, 0xfe01, 0x4000 }, + { 0x8700, 0xfdfb, 0x3000 }, + { 0x8700, 0xfdf9, 0x2000 }, + { 0x0700, 0xfdf8, 0x0000 }, + { 0x0700, 0xfdfa, 0x0000 }, + { 0x9a00, 0xfdfd, 0x2000 }, + { 0x1700, 0xfdfc, 0x0000 }, + { 0x0c00, 0xfe00, 0x0000 }, + { 0x8c00, 0xfe05, 0x3000 }, + { 0x8c00, 0xfe03, 0x2000 }, + { 0x0c00, 0xfe02, 0x0000 }, + { 0x0c00, 0xfe04, 0x0000 }, + { 0x8c00, 0xfe07, 0x2000 }, + { 0x0c00, 0xfe06, 0x0000 }, + { 0x0c00, 0xfe08, 0x0000 }, + { 0x9900, 0xfe66, 0x7000 }, + { 0x9500, 0xfe45, 0x6000 }, + { 0x9600, 0xfe35, 0x5000 }, + { 0x8c00, 0xfe21, 0x4000 }, + { 0x8c00, 0xfe0d, 0x3000 }, + { 0x8c00, 0xfe0b, 0x2000 }, + { 0x0c00, 0xfe0a, 0x0000 }, + { 0x0c00, 0xfe0c, 0x0000 }, + { 0x8c00, 0xfe0f, 0x2000 }, + { 0x0c00, 0xfe0e, 0x0000 }, + { 0x0c00, 0xfe20, 0x0000 }, + { 0x9100, 0xfe31, 0x3000 }, + { 0x8c00, 0xfe23, 0x2000 }, + { 0x0c00, 0xfe22, 0x0000 }, + { 0x1500, 0xfe30, 0x0000 }, + { 0x9000, 0xfe33, 0x2000 }, + { 0x1100, 0xfe32, 0x0000 }, + { 0x1000, 0xfe34, 0x0000 }, + { 0x9600, 0xfe3d, 0x4000 }, + { 0x9600, 0xfe39, 0x3000 }, + { 0x9600, 0xfe37, 0x2000 }, + { 0x1200, 0xfe36, 0x0000 }, + { 0x1200, 0xfe38, 0x0000 }, + { 0x9600, 0xfe3b, 0x2000 }, + { 0x1200, 0xfe3a, 0x0000 }, + { 0x1200, 0xfe3c, 0x0000 }, + { 0x9600, 0xfe41, 0x3000 }, + { 0x9600, 0xfe3f, 0x2000 }, + { 0x1200, 0xfe3e, 0x0000 }, + { 0x1200, 0xfe40, 0x0000 }, + { 0x9600, 0xfe43, 0x2000 }, + { 0x1200, 0xfe42, 0x0000 }, + { 0x1200, 0xfe44, 0x0000 }, + { 0x9500, 0xfe56, 0x5000 }, + { 0x9000, 0xfe4d, 0x4000 }, + { 0x9500, 0xfe49, 0x3000 }, + { 0x9600, 0xfe47, 0x2000 }, + { 0x1500, 0xfe46, 0x0000 }, + { 0x1200, 0xfe48, 0x0000 }, + { 0x9500, 0xfe4b, 0x2000 }, + { 0x1500, 0xfe4a, 0x0000 }, + { 0x1500, 0xfe4c, 0x0000 }, + { 0x9500, 0xfe51, 0x3000 }, + { 0x9000, 0xfe4f, 0x2000 }, + { 0x1000, 0xfe4e, 0x0000 }, + { 0x1500, 0xfe50, 0x0000 }, + { 0x9500, 0xfe54, 0x2000 }, + { 0x1500, 0xfe52, 0x0000 }, + { 0x1500, 0xfe55, 0x0000 }, + { 0x9200, 0xfe5e, 0x4000 }, + { 0x9200, 0xfe5a, 0x3000 }, + { 0x9100, 0xfe58, 0x2000 }, + { 0x1500, 0xfe57, 0x0000 }, + { 0x1600, 0xfe59, 0x0000 }, + { 0x9200, 0xfe5c, 0x2000 }, + { 0x1600, 0xfe5b, 0x0000 }, + { 0x1600, 0xfe5d, 0x0000 }, + { 0x9900, 0xfe62, 0x3000 }, + { 0x9500, 0xfe60, 0x2000 }, + { 0x1500, 0xfe5f, 0x0000 }, + { 0x1500, 0xfe61, 0x0000 }, + { 0x9900, 0xfe64, 0x2000 }, + { 0x1100, 0xfe63, 0x0000 }, + { 0x1900, 0xfe65, 0x0000 }, + { 0x8700, 0xfe8c, 0x6000 }, + { 0x8700, 0xfe7c, 0x5000 }, + { 0x8700, 0xfe73, 0x4000 }, + { 0x9500, 0xfe6b, 0x3000 }, + { 0x9700, 0xfe69, 0x2000 }, + { 0x1500, 0xfe68, 0x0000 }, + { 0x1500, 0xfe6a, 0x0000 }, + { 0x8700, 0xfe71, 0x2000 }, + { 0x0700, 0xfe70, 0x0000 }, + { 0x0700, 0xfe72, 0x0000 }, + { 0x8700, 0xfe78, 0x3000 }, + { 0x8700, 0xfe76, 0x2000 }, + { 0x0700, 0xfe74, 0x0000 }, + { 0x0700, 0xfe77, 0x0000 }, + { 0x8700, 0xfe7a, 0x2000 }, + { 0x0700, 0xfe79, 0x0000 }, + { 0x0700, 0xfe7b, 0x0000 }, + { 0x8700, 0xfe84, 0x4000 }, + { 0x8700, 0xfe80, 0x3000 }, + { 0x8700, 0xfe7e, 0x2000 }, + { 0x0700, 0xfe7d, 0x0000 }, + { 0x0700, 0xfe7f, 0x0000 }, + { 0x8700, 0xfe82, 0x2000 }, + { 0x0700, 0xfe81, 0x0000 }, + { 0x0700, 0xfe83, 0x0000 }, + { 0x8700, 0xfe88, 0x3000 }, + { 0x8700, 0xfe86, 0x2000 }, + { 0x0700, 0xfe85, 0x0000 }, + { 0x0700, 0xfe87, 0x0000 }, + { 0x8700, 0xfe8a, 0x2000 }, + { 0x0700, 0xfe89, 0x0000 }, + { 0x0700, 0xfe8b, 0x0000 }, + { 0x8700, 0xfe9c, 0x5000 }, + { 0x8700, 0xfe94, 0x4000 }, + { 0x8700, 0xfe90, 0x3000 }, + { 0x8700, 0xfe8e, 0x2000 }, + { 0x0700, 0xfe8d, 0x0000 }, + { 0x0700, 0xfe8f, 0x0000 }, + { 0x8700, 0xfe92, 0x2000 }, + { 0x0700, 0xfe91, 0x0000 }, + { 0x0700, 0xfe93, 0x0000 }, + { 0x8700, 0xfe98, 0x3000 }, + { 0x8700, 0xfe96, 0x2000 }, + { 0x0700, 0xfe95, 0x0000 }, + { 0x0700, 0xfe97, 0x0000 }, + { 0x8700, 0xfe9a, 0x2000 }, + { 0x0700, 0xfe99, 0x0000 }, + { 0x0700, 0xfe9b, 0x0000 }, + { 0x8700, 0xfea4, 0x4000 }, + { 0x8700, 0xfea0, 0x3000 }, + { 0x8700, 0xfe9e, 0x2000 }, + { 0x0700, 0xfe9d, 0x0000 }, + { 0x0700, 0xfe9f, 0x0000 }, + { 0x8700, 0xfea2, 0x2000 }, + { 0x0700, 0xfea1, 0x0000 }, + { 0x0700, 0xfea3, 0x0000 }, + { 0x8700, 0xfea8, 0x3000 }, + { 0x8700, 0xfea6, 0x2000 }, + { 0x0700, 0xfea5, 0x0000 }, + { 0x0700, 0xfea7, 0x0000 }, + { 0x8700, 0xfeaa, 0x2000 }, + { 0x0700, 0xfea9, 0x0000 }, + { 0x0700, 0xfeab, 0x0000 }, + { 0x8700, 0xffaf, 0x9000 }, + { 0x8900, 0xff2f, 0x8020 }, + { 0x8700, 0xfeec, 0x7000 }, + { 0x8700, 0xfecc, 0x6000 }, + { 0x8700, 0xfebc, 0x5000 }, + { 0x8700, 0xfeb4, 0x4000 }, + { 0x8700, 0xfeb0, 0x3000 }, + { 0x8700, 0xfeae, 0x2000 }, + { 0x0700, 0xfead, 0x0000 }, + { 0x0700, 0xfeaf, 0x0000 }, + { 0x8700, 0xfeb2, 0x2000 }, + { 0x0700, 0xfeb1, 0x0000 }, + { 0x0700, 0xfeb3, 0x0000 }, + { 0x8700, 0xfeb8, 0x3000 }, + { 0x8700, 0xfeb6, 0x2000 }, + { 0x0700, 0xfeb5, 0x0000 }, + { 0x0700, 0xfeb7, 0x0000 }, + { 0x8700, 0xfeba, 0x2000 }, + { 0x0700, 0xfeb9, 0x0000 }, + { 0x0700, 0xfebb, 0x0000 }, + { 0x8700, 0xfec4, 0x4000 }, + { 0x8700, 0xfec0, 0x3000 }, + { 0x8700, 0xfebe, 0x2000 }, + { 0x0700, 0xfebd, 0x0000 }, + { 0x0700, 0xfebf, 0x0000 }, + { 0x8700, 0xfec2, 0x2000 }, + { 0x0700, 0xfec1, 0x0000 }, + { 0x0700, 0xfec3, 0x0000 }, + { 0x8700, 0xfec8, 0x3000 }, + { 0x8700, 0xfec6, 0x2000 }, + { 0x0700, 0xfec5, 0x0000 }, + { 0x0700, 0xfec7, 0x0000 }, + { 0x8700, 0xfeca, 0x2000 }, + { 0x0700, 0xfec9, 0x0000 }, + { 0x0700, 0xfecb, 0x0000 }, + { 0x8700, 0xfedc, 0x5000 }, + { 0x8700, 0xfed4, 0x4000 }, + { 0x8700, 0xfed0, 0x3000 }, + { 0x8700, 0xfece, 0x2000 }, + { 0x0700, 0xfecd, 0x0000 }, + { 0x0700, 0xfecf, 0x0000 }, + { 0x8700, 0xfed2, 0x2000 }, + { 0x0700, 0xfed1, 0x0000 }, + { 0x0700, 0xfed3, 0x0000 }, + { 0x8700, 0xfed8, 0x3000 }, + { 0x8700, 0xfed6, 0x2000 }, + { 0x0700, 0xfed5, 0x0000 }, + { 0x0700, 0xfed7, 0x0000 }, + { 0x8700, 0xfeda, 0x2000 }, + { 0x0700, 0xfed9, 0x0000 }, + { 0x0700, 0xfedb, 0x0000 }, + { 0x8700, 0xfee4, 0x4000 }, + { 0x8700, 0xfee0, 0x3000 }, + { 0x8700, 0xfede, 0x2000 }, + { 0x0700, 0xfedd, 0x0000 }, + { 0x0700, 0xfedf, 0x0000 }, + { 0x8700, 0xfee2, 0x2000 }, + { 0x0700, 0xfee1, 0x0000 }, + { 0x0700, 0xfee3, 0x0000 }, + { 0x8700, 0xfee8, 0x3000 }, + { 0x8700, 0xfee6, 0x2000 }, + { 0x0700, 0xfee5, 0x0000 }, + { 0x0700, 0xfee7, 0x0000 }, + { 0x8700, 0xfeea, 0x2000 }, + { 0x0700, 0xfee9, 0x0000 }, + { 0x0700, 0xfeeb, 0x0000 }, + { 0x9500, 0xff0f, 0x6000 }, + { 0x8700, 0xfefc, 0x5000 }, + { 0x8700, 0xfef4, 0x4000 }, + { 0x8700, 0xfef0, 0x3000 }, + { 0x8700, 0xfeee, 0x2000 }, + { 0x0700, 0xfeed, 0x0000 }, + { 0x0700, 0xfeef, 0x0000 }, + { 0x8700, 0xfef2, 0x2000 }, + { 0x0700, 0xfef1, 0x0000 }, + { 0x0700, 0xfef3, 0x0000 }, + { 0x8700, 0xfef8, 0x3000 }, + { 0x8700, 0xfef6, 0x2000 }, + { 0x0700, 0xfef5, 0x0000 }, + { 0x0700, 0xfef7, 0x0000 }, + { 0x8700, 0xfefa, 0x2000 }, + { 0x0700, 0xfef9, 0x0000 }, + { 0x0700, 0xfefb, 0x0000 }, + { 0x9500, 0xff07, 0x4000 }, + { 0x9500, 0xff03, 0x3000 }, + { 0x9500, 0xff01, 0x2000 }, + { 0x0100, 0xfeff, 0x0000 }, + { 0x1500, 0xff02, 0x0000 }, + { 0x9500, 0xff05, 0x2000 }, + { 0x1700, 0xff04, 0x0000 }, + { 0x1500, 0xff06, 0x0000 }, + { 0x9900, 0xff0b, 0x3000 }, + { 0x9200, 0xff09, 0x2000 }, + { 0x1600, 0xff08, 0x0000 }, + { 0x1500, 0xff0a, 0x0000 }, + { 0x9100, 0xff0d, 0x2000 }, + { 0x1500, 0xff0c, 0x0000 }, + { 0x1500, 0xff0e, 0x0000 }, + { 0x9500, 0xff1f, 0x5000 }, + { 0x8d00, 0xff17, 0x4000 }, + { 0x8d00, 0xff13, 0x3000 }, + { 0x8d00, 0xff11, 0x2000 }, + { 0x0d00, 0xff10, 0x0000 }, + { 0x0d00, 0xff12, 0x0000 }, + { 0x8d00, 0xff15, 0x2000 }, + { 0x0d00, 0xff14, 0x0000 }, + { 0x0d00, 0xff16, 0x0000 }, + { 0x9500, 0xff1b, 0x3000 }, + { 0x8d00, 0xff19, 0x2000 }, + { 0x0d00, 0xff18, 0x0000 }, + { 0x1500, 0xff1a, 0x0000 }, + { 0x9900, 0xff1d, 0x2000 }, + { 0x1900, 0xff1c, 0x0000 }, + { 0x1900, 0xff1e, 0x0000 }, + { 0x8900, 0xff27, 0x4020 }, + { 0x8900, 0xff23, 0x3020 }, + { 0x8900, 0xff21, 0x2020 }, + { 0x1500, 0xff20, 0x0000 }, + { 0x0900, 0xff22, 0x0020 }, + { 0x8900, 0xff25, 0x2020 }, + { 0x0900, 0xff24, 0x0020 }, + { 0x0900, 0xff26, 0x0020 }, + { 0x8900, 0xff2b, 0x3020 }, + { 0x8900, 0xff29, 0x2020 }, + { 0x0900, 0xff28, 0x0020 }, + { 0x0900, 0xff2a, 0x0020 }, + { 0x8900, 0xff2d, 0x2020 }, + { 0x0900, 0xff2c, 0x0020 }, + { 0x0900, 0xff2e, 0x0020 }, + { 0x8700, 0xff6f, 0x7000 }, + { 0x8500, 0xff4f, 0x6fe0 }, + { 0x9000, 0xff3f, 0x5000 }, + { 0x8900, 0xff37, 0x4020 }, + { 0x8900, 0xff33, 0x3020 }, + { 0x8900, 0xff31, 0x2020 }, + { 0x0900, 0xff30, 0x0020 }, + { 0x0900, 0xff32, 0x0020 }, + { 0x8900, 0xff35, 0x2020 }, + { 0x0900, 0xff34, 0x0020 }, + { 0x0900, 0xff36, 0x0020 }, + { 0x9600, 0xff3b, 0x3000 }, + { 0x8900, 0xff39, 0x2020 }, + { 0x0900, 0xff38, 0x0020 }, + { 0x0900, 0xff3a, 0x0020 }, + { 0x9200, 0xff3d, 0x2000 }, + { 0x1500, 0xff3c, 0x0000 }, + { 0x1800, 0xff3e, 0x0000 }, + { 0x8500, 0xff47, 0x4fe0 }, + { 0x8500, 0xff43, 0x3fe0 }, + { 0x8500, 0xff41, 0x2fe0 }, + { 0x1800, 0xff40, 0x0000 }, + { 0x0500, 0xff42, 0x0fe0 }, + { 0x8500, 0xff45, 0x2fe0 }, + { 0x0500, 0xff44, 0x0fe0 }, + { 0x0500, 0xff46, 0x0fe0 }, + { 0x8500, 0xff4b, 0x3fe0 }, + { 0x8500, 0xff49, 0x2fe0 }, + { 0x0500, 0xff48, 0x0fe0 }, + { 0x0500, 0xff4a, 0x0fe0 }, + { 0x8500, 0xff4d, 0x2fe0 }, + { 0x0500, 0xff4c, 0x0fe0 }, + { 0x0500, 0xff4e, 0x0fe0 }, + { 0x9600, 0xff5f, 0x5000 }, + { 0x8500, 0xff57, 0x4fe0 }, + { 0x8500, 0xff53, 0x3fe0 }, + { 0x8500, 0xff51, 0x2fe0 }, + { 0x0500, 0xff50, 0x0fe0 }, + { 0x0500, 0xff52, 0x0fe0 }, + { 0x8500, 0xff55, 0x2fe0 }, + { 0x0500, 0xff54, 0x0fe0 }, + { 0x0500, 0xff56, 0x0fe0 }, + { 0x9600, 0xff5b, 0x3000 }, + { 0x8500, 0xff59, 0x2fe0 }, + { 0x0500, 0xff58, 0x0fe0 }, + { 0x0500, 0xff5a, 0x0fe0 }, + { 0x9200, 0xff5d, 0x2000 }, + { 0x1900, 0xff5c, 0x0000 }, + { 0x1900, 0xff5e, 0x0000 }, + { 0x8700, 0xff67, 0x4000 }, + { 0x9200, 0xff63, 0x3000 }, + { 0x9500, 0xff61, 0x2000 }, + { 0x1200, 0xff60, 0x0000 }, + { 0x1600, 0xff62, 0x0000 }, + { 0x9000, 0xff65, 0x2000 }, + { 0x1500, 0xff64, 0x0000 }, + { 0x0700, 0xff66, 0x0000 }, + { 0x8700, 0xff6b, 0x3000 }, + { 0x8700, 0xff69, 0x2000 }, + { 0x0700, 0xff68, 0x0000 }, + { 0x0700, 0xff6a, 0x0000 }, + { 0x8700, 0xff6d, 0x2000 }, + { 0x0700, 0xff6c, 0x0000 }, + { 0x0700, 0xff6e, 0x0000 }, + { 0x8700, 0xff8f, 0x6000 }, + { 0x8700, 0xff7f, 0x5000 }, + { 0x8700, 0xff77, 0x4000 }, + { 0x8700, 0xff73, 0x3000 }, + { 0x8700, 0xff71, 0x2000 }, + { 0x0600, 0xff70, 0x0000 }, + { 0x0700, 0xff72, 0x0000 }, + { 0x8700, 0xff75, 0x2000 }, + { 0x0700, 0xff74, 0x0000 }, + { 0x0700, 0xff76, 0x0000 }, + { 0x8700, 0xff7b, 0x3000 }, + { 0x8700, 0xff79, 0x2000 }, + { 0x0700, 0xff78, 0x0000 }, + { 0x0700, 0xff7a, 0x0000 }, + { 0x8700, 0xff7d, 0x2000 }, + { 0x0700, 0xff7c, 0x0000 }, + { 0x0700, 0xff7e, 0x0000 }, + { 0x8700, 0xff87, 0x4000 }, + { 0x8700, 0xff83, 0x3000 }, + { 0x8700, 0xff81, 0x2000 }, + { 0x0700, 0xff80, 0x0000 }, + { 0x0700, 0xff82, 0x0000 }, + { 0x8700, 0xff85, 0x2000 }, + { 0x0700, 0xff84, 0x0000 }, + { 0x0700, 0xff86, 0x0000 }, + { 0x8700, 0xff8b, 0x3000 }, + { 0x8700, 0xff89, 0x2000 }, + { 0x0700, 0xff88, 0x0000 }, + { 0x0700, 0xff8a, 0x0000 }, + { 0x8700, 0xff8d, 0x2000 }, + { 0x0700, 0xff8c, 0x0000 }, + { 0x0700, 0xff8e, 0x0000 }, + { 0x8600, 0xff9f, 0x5000 }, + { 0x8700, 0xff97, 0x4000 }, + { 0x8700, 0xff93, 0x3000 }, + { 0x8700, 0xff91, 0x2000 }, + { 0x0700, 0xff90, 0x0000 }, + { 0x0700, 0xff92, 0x0000 }, + { 0x8700, 0xff95, 0x2000 }, + { 0x0700, 0xff94, 0x0000 }, + { 0x0700, 0xff96, 0x0000 }, + { 0x8700, 0xff9b, 0x3000 }, + { 0x8700, 0xff99, 0x2000 }, + { 0x0700, 0xff98, 0x0000 }, + { 0x0700, 0xff9a, 0x0000 }, + { 0x8700, 0xff9d, 0x2000 }, + { 0x0700, 0xff9c, 0x0000 }, + { 0x0600, 0xff9e, 0x0000 }, + { 0x8700, 0xffa7, 0x4000 }, + { 0x8700, 0xffa3, 0x3000 }, + { 0x8700, 0xffa1, 0x2000 }, + { 0x0700, 0xffa0, 0x0000 }, + { 0x0700, 0xffa2, 0x0000 }, + { 0x8700, 0xffa5, 0x2000 }, + { 0x0700, 0xffa4, 0x0000 }, + { 0x0700, 0xffa6, 0x0000 }, + { 0x8700, 0xffab, 0x3000 }, + { 0x8700, 0xffa9, 0x2000 }, + { 0x0700, 0xffa8, 0x0000 }, + { 0x0700, 0xffaa, 0x0000 }, + { 0x8700, 0xffad, 0x2000 }, + { 0x0700, 0xffac, 0x0000 }, + { 0x0700, 0xffae, 0x0000 }, + { 0x8701, 0x004c, 0x8000 }, + { 0x8701, 0x0008, 0x7000 }, + { 0x8700, 0xffd6, 0x6000 }, + { 0x8700, 0xffc2, 0x5000 }, + { 0x8700, 0xffb7, 0x4000 }, + { 0x8700, 0xffb3, 0x3000 }, + { 0x8700, 0xffb1, 0x2000 }, + { 0x0700, 0xffb0, 0x0000 }, + { 0x0700, 0xffb2, 0x0000 }, + { 0x8700, 0xffb5, 0x2000 }, + { 0x0700, 0xffb4, 0x0000 }, + { 0x0700, 0xffb6, 0x0000 }, + { 0x8700, 0xffbb, 0x3000 }, + { 0x8700, 0xffb9, 0x2000 }, + { 0x0700, 0xffb8, 0x0000 }, + { 0x0700, 0xffba, 0x0000 }, + { 0x8700, 0xffbd, 0x2000 }, + { 0x0700, 0xffbc, 0x0000 }, + { 0x0700, 0xffbe, 0x0000 }, + { 0x8700, 0xffcc, 0x4000 }, + { 0x8700, 0xffc6, 0x3000 }, + { 0x8700, 0xffc4, 0x2000 }, + { 0x0700, 0xffc3, 0x0000 }, + { 0x0700, 0xffc5, 0x0000 }, + { 0x8700, 0xffca, 0x2000 }, + { 0x0700, 0xffc7, 0x0000 }, + { 0x0700, 0xffcb, 0x0000 }, + { 0x8700, 0xffd2, 0x3000 }, + { 0x8700, 0xffce, 0x2000 }, + { 0x0700, 0xffcd, 0x0000 }, + { 0x0700, 0xffcf, 0x0000 }, + { 0x8700, 0xffd4, 0x2000 }, + { 0x0700, 0xffd3, 0x0000 }, + { 0x0700, 0xffd5, 0x0000 }, + { 0x9900, 0xffec, 0x5000 }, + { 0x9800, 0xffe3, 0x4000 }, + { 0x8700, 0xffdc, 0x3000 }, + { 0x8700, 0xffda, 0x2000 }, + { 0x0700, 0xffd7, 0x0000 }, + { 0x0700, 0xffdb, 0x0000 }, + { 0x9700, 0xffe1, 0x2000 }, + { 0x1700, 0xffe0, 0x0000 }, + { 0x1900, 0xffe2, 0x0000 }, + { 0x9a00, 0xffe8, 0x3000 }, + { 0x9700, 0xffe5, 0x2000 }, + { 0x1a00, 0xffe4, 0x0000 }, + { 0x1700, 0xffe6, 0x0000 }, + { 0x9900, 0xffea, 0x2000 }, + { 0x1900, 0xffe9, 0x0000 }, + { 0x1900, 0xffeb, 0x0000 }, + { 0x8701, 0x0000, 0x4000 }, + { 0x8100, 0xfffa, 0x3000 }, + { 0x9a00, 0xffee, 0x2000 }, + { 0x1a00, 0xffed, 0x0000 }, + { 0x0100, 0xfff9, 0x0000 }, + { 0x9a00, 0xfffc, 0x2000 }, + { 0x0100, 0xfffb, 0x0000 }, + { 0x1a00, 0xfffd, 0x0000 }, + { 0x8701, 0x0004, 0x3000 }, + { 0x8701, 0x0002, 0x2000 }, + { 0x0701, 0x0001, 0x0000 }, + { 0x0701, 0x0003, 0x0000 }, + { 0x8701, 0x0006, 0x2000 }, + { 0x0701, 0x0005, 0x0000 }, + { 0x0701, 0x0007, 0x0000 }, + { 0x8701, 0x002a, 0x6000 }, + { 0x8701, 0x0019, 0x5000 }, + { 0x8701, 0x0011, 0x4000 }, + { 0x8701, 0x000d, 0x3000 }, + { 0x8701, 0x000a, 0x2000 }, + { 0x0701, 0x0009, 0x0000 }, + { 0x0701, 0x000b, 0x0000 }, + { 0x8701, 0x000f, 0x2000 }, + { 0x0701, 0x000e, 0x0000 }, + { 0x0701, 0x0010, 0x0000 }, + { 0x8701, 0x0015, 0x3000 }, + { 0x8701, 0x0013, 0x2000 }, + { 0x0701, 0x0012, 0x0000 }, + { 0x0701, 0x0014, 0x0000 }, + { 0x8701, 0x0017, 0x2000 }, + { 0x0701, 0x0016, 0x0000 }, + { 0x0701, 0x0018, 0x0000 }, + { 0x8701, 0x0021, 0x4000 }, + { 0x8701, 0x001d, 0x3000 }, + { 0x8701, 0x001b, 0x2000 }, + { 0x0701, 0x001a, 0x0000 }, + { 0x0701, 0x001c, 0x0000 }, + { 0x8701, 0x001f, 0x2000 }, + { 0x0701, 0x001e, 0x0000 }, + { 0x0701, 0x0020, 0x0000 }, + { 0x8701, 0x0025, 0x3000 }, + { 0x8701, 0x0023, 0x2000 }, + { 0x0701, 0x0022, 0x0000 }, + { 0x0701, 0x0024, 0x0000 }, + { 0x8701, 0x0028, 0x2000 }, + { 0x0701, 0x0026, 0x0000 }, + { 0x0701, 0x0029, 0x0000 }, + { 0x8701, 0x003a, 0x5000 }, + { 0x8701, 0x0032, 0x4000 }, + { 0x8701, 0x002e, 0x3000 }, + { 0x8701, 0x002c, 0x2000 }, + { 0x0701, 0x002b, 0x0000 }, + { 0x0701, 0x002d, 0x0000 }, + { 0x8701, 0x0030, 0x2000 }, + { 0x0701, 0x002f, 0x0000 }, + { 0x0701, 0x0031, 0x0000 }, + { 0x8701, 0x0036, 0x3000 }, + { 0x8701, 0x0034, 0x2000 }, + { 0x0701, 0x0033, 0x0000 }, + { 0x0701, 0x0035, 0x0000 }, + { 0x8701, 0x0038, 0x2000 }, + { 0x0701, 0x0037, 0x0000 }, + { 0x0701, 0x0039, 0x0000 }, + { 0x8701, 0x0044, 0x4000 }, + { 0x8701, 0x0040, 0x3000 }, + { 0x8701, 0x003d, 0x2000 }, + { 0x0701, 0x003c, 0x0000 }, + { 0x0701, 0x003f, 0x0000 }, + { 0x8701, 0x0042, 0x2000 }, + { 0x0701, 0x0041, 0x0000 }, + { 0x0701, 0x0043, 0x0000 }, + { 0x8701, 0x0048, 0x3000 }, + { 0x8701, 0x0046, 0x2000 }, + { 0x0701, 0x0045, 0x0000 }, + { 0x0701, 0x0047, 0x0000 }, + { 0x8701, 0x004a, 0x2000 }, + { 0x0701, 0x0049, 0x0000 }, + { 0x0701, 0x004b, 0x0000 }, + { 0x8701, 0x00b0, 0x7000 }, + { 0x8701, 0x0090, 0x6000 }, + { 0x8701, 0x0080, 0x5000 }, + { 0x8701, 0x0056, 0x4000 }, + { 0x8701, 0x0052, 0x3000 }, + { 0x8701, 0x0050, 0x2000 }, + { 0x0701, 0x004d, 0x0000 }, + { 0x0701, 0x0051, 0x0000 }, + { 0x8701, 0x0054, 0x2000 }, + { 0x0701, 0x0053, 0x0000 }, + { 0x0701, 0x0055, 0x0000 }, + { 0x8701, 0x005a, 0x3000 }, + { 0x8701, 0x0058, 0x2000 }, + { 0x0701, 0x0057, 0x0000 }, + { 0x0701, 0x0059, 0x0000 }, + { 0x8701, 0x005c, 0x2000 }, + { 0x0701, 0x005b, 0x0000 }, + { 0x0701, 0x005d, 0x0000 }, + { 0x8701, 0x0088, 0x4000 }, + { 0x8701, 0x0084, 0x3000 }, + { 0x8701, 0x0082, 0x2000 }, + { 0x0701, 0x0081, 0x0000 }, + { 0x0701, 0x0083, 0x0000 }, + { 0x8701, 0x0086, 0x2000 }, + { 0x0701, 0x0085, 0x0000 }, + { 0x0701, 0x0087, 0x0000 }, + { 0x8701, 0x008c, 0x3000 }, + { 0x8701, 0x008a, 0x2000 }, + { 0x0701, 0x0089, 0x0000 }, + { 0x0701, 0x008b, 0x0000 }, + { 0x8701, 0x008e, 0x2000 }, + { 0x0701, 0x008d, 0x0000 }, + { 0x0701, 0x008f, 0x0000 }, + { 0x8701, 0x00a0, 0x5000 }, + { 0x8701, 0x0098, 0x4000 }, + { 0x8701, 0x0094, 0x3000 }, + { 0x8701, 0x0092, 0x2000 }, + { 0x0701, 0x0091, 0x0000 }, + { 0x0701, 0x0093, 0x0000 }, + { 0x8701, 0x0096, 0x2000 }, + { 0x0701, 0x0095, 0x0000 }, + { 0x0701, 0x0097, 0x0000 }, + { 0x8701, 0x009c, 0x3000 }, + { 0x8701, 0x009a, 0x2000 }, + { 0x0701, 0x0099, 0x0000 }, + { 0x0701, 0x009b, 0x0000 }, + { 0x8701, 0x009e, 0x2000 }, + { 0x0701, 0x009d, 0x0000 }, + { 0x0701, 0x009f, 0x0000 }, + { 0x8701, 0x00a8, 0x4000 }, + { 0x8701, 0x00a4, 0x3000 }, + { 0x8701, 0x00a2, 0x2000 }, + { 0x0701, 0x00a1, 0x0000 }, + { 0x0701, 0x00a3, 0x0000 }, + { 0x8701, 0x00a6, 0x2000 }, + { 0x0701, 0x00a5, 0x0000 }, + { 0x0701, 0x00a7, 0x0000 }, + { 0x8701, 0x00ac, 0x3000 }, + { 0x8701, 0x00aa, 0x2000 }, + { 0x0701, 0x00a9, 0x0000 }, + { 0x0701, 0x00ab, 0x0000 }, + { 0x8701, 0x00ae, 0x2000 }, + { 0x0701, 0x00ad, 0x0000 }, + { 0x0701, 0x00af, 0x0000 }, + { 0x8701, 0x00d0, 0x6000 }, + { 0x8701, 0x00c0, 0x5000 }, + { 0x8701, 0x00b8, 0x4000 }, + { 0x8701, 0x00b4, 0x3000 }, + { 0x8701, 0x00b2, 0x2000 }, + { 0x0701, 0x00b1, 0x0000 }, + { 0x0701, 0x00b3, 0x0000 }, + { 0x8701, 0x00b6, 0x2000 }, + { 0x0701, 0x00b5, 0x0000 }, + { 0x0701, 0x00b7, 0x0000 }, + { 0x8701, 0x00bc, 0x3000 }, + { 0x8701, 0x00ba, 0x2000 }, + { 0x0701, 0x00b9, 0x0000 }, + { 0x0701, 0x00bb, 0x0000 }, + { 0x8701, 0x00be, 0x2000 }, + { 0x0701, 0x00bd, 0x0000 }, + { 0x0701, 0x00bf, 0x0000 }, + { 0x8701, 0x00c8, 0x4000 }, + { 0x8701, 0x00c4, 0x3000 }, + { 0x8701, 0x00c2, 0x2000 }, + { 0x0701, 0x00c1, 0x0000 }, + { 0x0701, 0x00c3, 0x0000 }, + { 0x8701, 0x00c6, 0x2000 }, + { 0x0701, 0x00c5, 0x0000 }, + { 0x0701, 0x00c7, 0x0000 }, + { 0x8701, 0x00cc, 0x3000 }, + { 0x8701, 0x00ca, 0x2000 }, + { 0x0701, 0x00c9, 0x0000 }, + { 0x0701, 0x00cb, 0x0000 }, + { 0x8701, 0x00ce, 0x2000 }, + { 0x0701, 0x00cd, 0x0000 }, + { 0x0701, 0x00cf, 0x0000 }, + { 0x8701, 0x00e0, 0x5000 }, + { 0x8701, 0x00d8, 0x4000 }, + { 0x8701, 0x00d4, 0x3000 }, + { 0x8701, 0x00d2, 0x2000 }, + { 0x0701, 0x00d1, 0x0000 }, + { 0x0701, 0x00d3, 0x0000 }, + { 0x8701, 0x00d6, 0x2000 }, + { 0x0701, 0x00d5, 0x0000 }, + { 0x0701, 0x00d7, 0x0000 }, + { 0x8701, 0x00dc, 0x3000 }, + { 0x8701, 0x00da, 0x2000 }, + { 0x0701, 0x00d9, 0x0000 }, + { 0x0701, 0x00db, 0x0000 }, + { 0x8701, 0x00de, 0x2000 }, + { 0x0701, 0x00dd, 0x0000 }, + { 0x0701, 0x00df, 0x0000 }, + { 0x8701, 0x00e8, 0x4000 }, + { 0x8701, 0x00e4, 0x3000 }, + { 0x8701, 0x00e2, 0x2000 }, + { 0x0701, 0x00e1, 0x0000 }, + { 0x0701, 0x00e3, 0x0000 }, + { 0x8701, 0x00e6, 0x2000 }, + { 0x0701, 0x00e5, 0x0000 }, + { 0x0701, 0x00e7, 0x0000 }, + { 0x8701, 0x00ec, 0x3000 }, + { 0x8701, 0x00ea, 0x2000 }, + { 0x0701, 0x00e9, 0x0000 }, + { 0x0701, 0x00eb, 0x0000 }, + { 0x8701, 0x00ee, 0x2000 }, + { 0x0701, 0x00ed, 0x0000 }, + { 0x0701, 0x00ef, 0x0000 }, + { 0x8501, 0xd459, 0xb000 }, + { 0x9a01, 0xd080, 0xa000 }, + { 0x8701, 0x045f, 0x9000 }, + { 0x8701, 0x0349, 0x8000 }, + { 0x9a01, 0x013c, 0x7000 }, + { 0x8f01, 0x0119, 0x6000 }, + { 0x8f01, 0x0109, 0x5000 }, + { 0x8701, 0x00f8, 0x4000 }, + { 0x8701, 0x00f4, 0x3000 }, + { 0x8701, 0x00f2, 0x2000 }, + { 0x0701, 0x00f1, 0x0000 }, + { 0x0701, 0x00f3, 0x0000 }, + { 0x8701, 0x00f6, 0x2000 }, + { 0x0701, 0x00f5, 0x0000 }, + { 0x0701, 0x00f7, 0x0000 }, + { 0x9501, 0x0101, 0x3000 }, + { 0x8701, 0x00fa, 0x2000 }, + { 0x0701, 0x00f9, 0x0000 }, + { 0x1501, 0x0100, 0x0000 }, + { 0x8f01, 0x0107, 0x2000 }, + { 0x1a01, 0x0102, 0x0000 }, + { 0x0f01, 0x0108, 0x0000 }, + { 0x8f01, 0x0111, 0x4000 }, + { 0x8f01, 0x010d, 0x3000 }, + { 0x8f01, 0x010b, 0x2000 }, + { 0x0f01, 0x010a, 0x0000 }, + { 0x0f01, 0x010c, 0x0000 }, + { 0x8f01, 0x010f, 0x2000 }, + { 0x0f01, 0x010e, 0x0000 }, + { 0x0f01, 0x0110, 0x0000 }, + { 0x8f01, 0x0115, 0x3000 }, + { 0x8f01, 0x0113, 0x2000 }, + { 0x0f01, 0x0112, 0x0000 }, + { 0x0f01, 0x0114, 0x0000 }, + { 0x8f01, 0x0117, 0x2000 }, + { 0x0f01, 0x0116, 0x0000 }, + { 0x0f01, 0x0118, 0x0000 }, + { 0x8f01, 0x0129, 0x5000 }, + { 0x8f01, 0x0121, 0x4000 }, + { 0x8f01, 0x011d, 0x3000 }, + { 0x8f01, 0x011b, 0x2000 }, + { 0x0f01, 0x011a, 0x0000 }, + { 0x0f01, 0x011c, 0x0000 }, + { 0x8f01, 0x011f, 0x2000 }, + { 0x0f01, 0x011e, 0x0000 }, + { 0x0f01, 0x0120, 0x0000 }, + { 0x8f01, 0x0125, 0x3000 }, + { 0x8f01, 0x0123, 0x2000 }, + { 0x0f01, 0x0122, 0x0000 }, + { 0x0f01, 0x0124, 0x0000 }, + { 0x8f01, 0x0127, 0x2000 }, + { 0x0f01, 0x0126, 0x0000 }, + { 0x0f01, 0x0128, 0x0000 }, + { 0x8f01, 0x0131, 0x4000 }, + { 0x8f01, 0x012d, 0x3000 }, + { 0x8f01, 0x012b, 0x2000 }, + { 0x0f01, 0x012a, 0x0000 }, + { 0x0f01, 0x012c, 0x0000 }, + { 0x8f01, 0x012f, 0x2000 }, + { 0x0f01, 0x012e, 0x0000 }, + { 0x0f01, 0x0130, 0x0000 }, + { 0x9a01, 0x0138, 0x3000 }, + { 0x8f01, 0x0133, 0x2000 }, + { 0x0f01, 0x0132, 0x0000 }, + { 0x1a01, 0x0137, 0x0000 }, + { 0x9a01, 0x013a, 0x2000 }, + { 0x1a01, 0x0139, 0x0000 }, + { 0x1a01, 0x013b, 0x0000 }, + { 0x8701, 0x031c, 0x6000 }, + { 0x8701, 0x030c, 0x5000 }, + { 0x8701, 0x0304, 0x4000 }, + { 0x8701, 0x0300, 0x3000 }, + { 0x9a01, 0x013e, 0x2000 }, + { 0x1a01, 0x013d, 0x0000 }, + { 0x1a01, 0x013f, 0x0000 }, + { 0x8701, 0x0302, 0x2000 }, + { 0x0701, 0x0301, 0x0000 }, + { 0x0701, 0x0303, 0x0000 }, + { 0x8701, 0x0308, 0x3000 }, + { 0x8701, 0x0306, 0x2000 }, + { 0x0701, 0x0305, 0x0000 }, + { 0x0701, 0x0307, 0x0000 }, + { 0x8701, 0x030a, 0x2000 }, + { 0x0701, 0x0309, 0x0000 }, + { 0x0701, 0x030b, 0x0000 }, + { 0x8701, 0x0314, 0x4000 }, + { 0x8701, 0x0310, 0x3000 }, + { 0x8701, 0x030e, 0x2000 }, + { 0x0701, 0x030d, 0x0000 }, + { 0x0701, 0x030f, 0x0000 }, + { 0x8701, 0x0312, 0x2000 }, + { 0x0701, 0x0311, 0x0000 }, + { 0x0701, 0x0313, 0x0000 }, + { 0x8701, 0x0318, 0x3000 }, + { 0x8701, 0x0316, 0x2000 }, + { 0x0701, 0x0315, 0x0000 }, + { 0x0701, 0x0317, 0x0000 }, + { 0x8701, 0x031a, 0x2000 }, + { 0x0701, 0x0319, 0x0000 }, + { 0x0701, 0x031b, 0x0000 }, + { 0x8701, 0x0339, 0x5000 }, + { 0x8701, 0x0331, 0x4000 }, + { 0x8f01, 0x0321, 0x3000 }, + { 0x8701, 0x031e, 0x2000 }, + { 0x0701, 0x031d, 0x0000 }, + { 0x0f01, 0x0320, 0x0000 }, + { 0x8f01, 0x0323, 0x2000 }, + { 0x0f01, 0x0322, 0x0000 }, + { 0x0701, 0x0330, 0x0000 }, + { 0x8701, 0x0335, 0x3000 }, + { 0x8701, 0x0333, 0x2000 }, + { 0x0701, 0x0332, 0x0000 }, + { 0x0701, 0x0334, 0x0000 }, + { 0x8701, 0x0337, 0x2000 }, + { 0x0701, 0x0336, 0x0000 }, + { 0x0701, 0x0338, 0x0000 }, + { 0x8701, 0x0341, 0x4000 }, + { 0x8701, 0x033d, 0x3000 }, + { 0x8701, 0x033b, 0x2000 }, + { 0x0701, 0x033a, 0x0000 }, + { 0x0701, 0x033c, 0x0000 }, + { 0x8701, 0x033f, 0x2000 }, + { 0x0701, 0x033e, 0x0000 }, + { 0x0701, 0x0340, 0x0000 }, + { 0x8701, 0x0345, 0x3000 }, + { 0x8701, 0x0343, 0x2000 }, + { 0x0701, 0x0342, 0x0000 }, + { 0x0701, 0x0344, 0x0000 }, + { 0x8701, 0x0347, 0x2000 }, + { 0x0701, 0x0346, 0x0000 }, + { 0x0701, 0x0348, 0x0000 }, + { 0x8901, 0x041f, 0x7028 }, + { 0x9501, 0x039f, 0x6000 }, + { 0x8701, 0x038e, 0x5000 }, + { 0x8701, 0x0386, 0x4000 }, + { 0x8701, 0x0382, 0x3000 }, + { 0x8701, 0x0380, 0x2000 }, + { 0x0e01, 0x034a, 0x0000 }, + { 0x0701, 0x0381, 0x0000 }, + { 0x8701, 0x0384, 0x2000 }, + { 0x0701, 0x0383, 0x0000 }, + { 0x0701, 0x0385, 0x0000 }, + { 0x8701, 0x038a, 0x3000 }, + { 0x8701, 0x0388, 0x2000 }, + { 0x0701, 0x0387, 0x0000 }, + { 0x0701, 0x0389, 0x0000 }, + { 0x8701, 0x038c, 0x2000 }, + { 0x0701, 0x038b, 0x0000 }, + { 0x0701, 0x038d, 0x0000 }, + { 0x8701, 0x0396, 0x4000 }, + { 0x8701, 0x0392, 0x3000 }, + { 0x8701, 0x0390, 0x2000 }, + { 0x0701, 0x038f, 0x0000 }, + { 0x0701, 0x0391, 0x0000 }, + { 0x8701, 0x0394, 0x2000 }, + { 0x0701, 0x0393, 0x0000 }, + { 0x0701, 0x0395, 0x0000 }, + { 0x8701, 0x039a, 0x3000 }, + { 0x8701, 0x0398, 0x2000 }, + { 0x0701, 0x0397, 0x0000 }, + { 0x0701, 0x0399, 0x0000 }, + { 0x8701, 0x039c, 0x2000 }, + { 0x0701, 0x039b, 0x0000 }, + { 0x0701, 0x039d, 0x0000 }, + { 0x8901, 0x040f, 0x5028 }, + { 0x8901, 0x0407, 0x4028 }, + { 0x8901, 0x0403, 0x3028 }, + { 0x8901, 0x0401, 0x2028 }, + { 0x0901, 0x0400, 0x0028 }, + { 0x0901, 0x0402, 0x0028 }, + { 0x8901, 0x0405, 0x2028 }, + { 0x0901, 0x0404, 0x0028 }, + { 0x0901, 0x0406, 0x0028 }, + { 0x8901, 0x040b, 0x3028 }, + { 0x8901, 0x0409, 0x2028 }, + { 0x0901, 0x0408, 0x0028 }, + { 0x0901, 0x040a, 0x0028 }, + { 0x8901, 0x040d, 0x2028 }, + { 0x0901, 0x040c, 0x0028 }, + { 0x0901, 0x040e, 0x0028 }, + { 0x8901, 0x0417, 0x4028 }, + { 0x8901, 0x0413, 0x3028 }, + { 0x8901, 0x0411, 0x2028 }, + { 0x0901, 0x0410, 0x0028 }, + { 0x0901, 0x0412, 0x0028 }, + { 0x8901, 0x0415, 0x2028 }, + { 0x0901, 0x0414, 0x0028 }, + { 0x0901, 0x0416, 0x0028 }, + { 0x8901, 0x041b, 0x3028 }, + { 0x8901, 0x0419, 0x2028 }, + { 0x0901, 0x0418, 0x0028 }, + { 0x0901, 0x041a, 0x0028 }, + { 0x8901, 0x041d, 0x2028 }, + { 0x0901, 0x041c, 0x0028 }, + { 0x0901, 0x041e, 0x0028 }, + { 0x8501, 0x043f, 0x6fd8 }, + { 0x8501, 0x042f, 0x5fd8 }, + { 0x8901, 0x0427, 0x4028 }, + { 0x8901, 0x0423, 0x3028 }, + { 0x8901, 0x0421, 0x2028 }, + { 0x0901, 0x0420, 0x0028 }, + { 0x0901, 0x0422, 0x0028 }, + { 0x8901, 0x0425, 0x2028 }, + { 0x0901, 0x0424, 0x0028 }, + { 0x0901, 0x0426, 0x0028 }, + { 0x8501, 0x042b, 0x3fd8 }, + { 0x8501, 0x0429, 0x2fd8 }, + { 0x0501, 0x0428, 0x0fd8 }, + { 0x0501, 0x042a, 0x0fd8 }, + { 0x8501, 0x042d, 0x2fd8 }, + { 0x0501, 0x042c, 0x0fd8 }, + { 0x0501, 0x042e, 0x0fd8 }, + { 0x8501, 0x0437, 0x4fd8 }, + { 0x8501, 0x0433, 0x3fd8 }, + { 0x8501, 0x0431, 0x2fd8 }, + { 0x0501, 0x0430, 0x0fd8 }, + { 0x0501, 0x0432, 0x0fd8 }, + { 0x8501, 0x0435, 0x2fd8 }, + { 0x0501, 0x0434, 0x0fd8 }, + { 0x0501, 0x0436, 0x0fd8 }, + { 0x8501, 0x043b, 0x3fd8 }, + { 0x8501, 0x0439, 0x2fd8 }, + { 0x0501, 0x0438, 0x0fd8 }, + { 0x0501, 0x043a, 0x0fd8 }, + { 0x8501, 0x043d, 0x2fd8 }, + { 0x0501, 0x043c, 0x0fd8 }, + { 0x0501, 0x043e, 0x0fd8 }, + { 0x8501, 0x044f, 0x5fd8 }, + { 0x8501, 0x0447, 0x4fd8 }, + { 0x8501, 0x0443, 0x3fd8 }, + { 0x8501, 0x0441, 0x2fd8 }, + { 0x0501, 0x0440, 0x0fd8 }, + { 0x0501, 0x0442, 0x0fd8 }, + { 0x8501, 0x0445, 0x2fd8 }, + { 0x0501, 0x0444, 0x0fd8 }, + { 0x0501, 0x0446, 0x0fd8 }, + { 0x8501, 0x044b, 0x3fd8 }, + { 0x8501, 0x0449, 0x2fd8 }, + { 0x0501, 0x0448, 0x0fd8 }, + { 0x0501, 0x044a, 0x0fd8 }, + { 0x8501, 0x044d, 0x2fd8 }, + { 0x0501, 0x044c, 0x0fd8 }, + { 0x0501, 0x044e, 0x0fd8 }, + { 0x8701, 0x0457, 0x4000 }, + { 0x8701, 0x0453, 0x3000 }, + { 0x8701, 0x0451, 0x2000 }, + { 0x0701, 0x0450, 0x0000 }, + { 0x0701, 0x0452, 0x0000 }, + { 0x8701, 0x0455, 0x2000 }, + { 0x0701, 0x0454, 0x0000 }, + { 0x0701, 0x0456, 0x0000 }, + { 0x8701, 0x045b, 0x3000 }, + { 0x8701, 0x0459, 0x2000 }, + { 0x0701, 0x0458, 0x0000 }, + { 0x0701, 0x045a, 0x0000 }, + { 0x8701, 0x045d, 0x2000 }, + { 0x0701, 0x045c, 0x0000 }, + { 0x0701, 0x045e, 0x0000 }, + { 0x9a01, 0xd000, 0x8000 }, + { 0x8d01, 0x04a1, 0x7000 }, + { 0x8701, 0x047f, 0x6000 }, + { 0x8701, 0x046f, 0x5000 }, + { 0x8701, 0x0467, 0x4000 }, + { 0x8701, 0x0463, 0x3000 }, + { 0x8701, 0x0461, 0x2000 }, + { 0x0701, 0x0460, 0x0000 }, + { 0x0701, 0x0462, 0x0000 }, + { 0x8701, 0x0465, 0x2000 }, + { 0x0701, 0x0464, 0x0000 }, + { 0x0701, 0x0466, 0x0000 }, + { 0x8701, 0x046b, 0x3000 }, + { 0x8701, 0x0469, 0x2000 }, + { 0x0701, 0x0468, 0x0000 }, + { 0x0701, 0x046a, 0x0000 }, + { 0x8701, 0x046d, 0x2000 }, + { 0x0701, 0x046c, 0x0000 }, + { 0x0701, 0x046e, 0x0000 }, + { 0x8701, 0x0477, 0x4000 }, + { 0x8701, 0x0473, 0x3000 }, + { 0x8701, 0x0471, 0x2000 }, + { 0x0701, 0x0470, 0x0000 }, + { 0x0701, 0x0472, 0x0000 }, + { 0x8701, 0x0475, 0x2000 }, + { 0x0701, 0x0474, 0x0000 }, + { 0x0701, 0x0476, 0x0000 }, + { 0x8701, 0x047b, 0x3000 }, + { 0x8701, 0x0479, 0x2000 }, + { 0x0701, 0x0478, 0x0000 }, + { 0x0701, 0x047a, 0x0000 }, + { 0x8701, 0x047d, 0x2000 }, + { 0x0701, 0x047c, 0x0000 }, + { 0x0701, 0x047e, 0x0000 }, + { 0x8701, 0x048f, 0x5000 }, + { 0x8701, 0x0487, 0x4000 }, + { 0x8701, 0x0483, 0x3000 }, + { 0x8701, 0x0481, 0x2000 }, + { 0x0701, 0x0480, 0x0000 }, + { 0x0701, 0x0482, 0x0000 }, + { 0x8701, 0x0485, 0x2000 }, + { 0x0701, 0x0484, 0x0000 }, + { 0x0701, 0x0486, 0x0000 }, + { 0x8701, 0x048b, 0x3000 }, + { 0x8701, 0x0489, 0x2000 }, + { 0x0701, 0x0488, 0x0000 }, + { 0x0701, 0x048a, 0x0000 }, + { 0x8701, 0x048d, 0x2000 }, + { 0x0701, 0x048c, 0x0000 }, + { 0x0701, 0x048e, 0x0000 }, + { 0x8701, 0x0497, 0x4000 }, + { 0x8701, 0x0493, 0x3000 }, + { 0x8701, 0x0491, 0x2000 }, + { 0x0701, 0x0490, 0x0000 }, + { 0x0701, 0x0492, 0x0000 }, + { 0x8701, 0x0495, 0x2000 }, + { 0x0701, 0x0494, 0x0000 }, + { 0x0701, 0x0496, 0x0000 }, + { 0x8701, 0x049b, 0x3000 }, + { 0x8701, 0x0499, 0x2000 }, + { 0x0701, 0x0498, 0x0000 }, + { 0x0701, 0x049a, 0x0000 }, + { 0x8701, 0x049d, 0x2000 }, + { 0x0701, 0x049c, 0x0000 }, + { 0x0d01, 0x04a0, 0x0000 }, + { 0x8701, 0x081a, 0x6000 }, + { 0x8701, 0x080a, 0x5000 }, + { 0x8d01, 0x04a9, 0x4000 }, + { 0x8d01, 0x04a5, 0x3000 }, + { 0x8d01, 0x04a3, 0x2000 }, + { 0x0d01, 0x04a2, 0x0000 }, + { 0x0d01, 0x04a4, 0x0000 }, + { 0x8d01, 0x04a7, 0x2000 }, + { 0x0d01, 0x04a6, 0x0000 }, + { 0x0d01, 0x04a8, 0x0000 }, + { 0x8701, 0x0803, 0x3000 }, + { 0x8701, 0x0801, 0x2000 }, + { 0x0701, 0x0800, 0x0000 }, + { 0x0701, 0x0802, 0x0000 }, + { 0x8701, 0x0805, 0x2000 }, + { 0x0701, 0x0804, 0x0000 }, + { 0x0701, 0x0808, 0x0000 }, + { 0x8701, 0x0812, 0x4000 }, + { 0x8701, 0x080e, 0x3000 }, + { 0x8701, 0x080c, 0x2000 }, + { 0x0701, 0x080b, 0x0000 }, + { 0x0701, 0x080d, 0x0000 }, + { 0x8701, 0x0810, 0x2000 }, + { 0x0701, 0x080f, 0x0000 }, + { 0x0701, 0x0811, 0x0000 }, + { 0x8701, 0x0816, 0x3000 }, + { 0x8701, 0x0814, 0x2000 }, + { 0x0701, 0x0813, 0x0000 }, + { 0x0701, 0x0815, 0x0000 }, + { 0x8701, 0x0818, 0x2000 }, + { 0x0701, 0x0817, 0x0000 }, + { 0x0701, 0x0819, 0x0000 }, + { 0x8701, 0x082a, 0x5000 }, + { 0x8701, 0x0822, 0x4000 }, + { 0x8701, 0x081e, 0x3000 }, + { 0x8701, 0x081c, 0x2000 }, + { 0x0701, 0x081b, 0x0000 }, + { 0x0701, 0x081d, 0x0000 }, + { 0x8701, 0x0820, 0x2000 }, + { 0x0701, 0x081f, 0x0000 }, + { 0x0701, 0x0821, 0x0000 }, + { 0x8701, 0x0826, 0x3000 }, + { 0x8701, 0x0824, 0x2000 }, + { 0x0701, 0x0823, 0x0000 }, + { 0x0701, 0x0825, 0x0000 }, + { 0x8701, 0x0828, 0x2000 }, + { 0x0701, 0x0827, 0x0000 }, + { 0x0701, 0x0829, 0x0000 }, + { 0x8701, 0x0832, 0x4000 }, + { 0x8701, 0x082e, 0x3000 }, + { 0x8701, 0x082c, 0x2000 }, + { 0x0701, 0x082b, 0x0000 }, + { 0x0701, 0x082d, 0x0000 }, + { 0x8701, 0x0830, 0x2000 }, + { 0x0701, 0x082f, 0x0000 }, + { 0x0701, 0x0831, 0x0000 }, + { 0x8701, 0x0837, 0x3000 }, + { 0x8701, 0x0834, 0x2000 }, + { 0x0701, 0x0833, 0x0000 }, + { 0x0701, 0x0835, 0x0000 }, + { 0x8701, 0x083c, 0x2000 }, + { 0x0701, 0x0838, 0x0000 }, + { 0x0701, 0x083f, 0x0000 }, + { 0x9a01, 0xd040, 0x7000 }, + { 0x9a01, 0xd020, 0x6000 }, + { 0x9a01, 0xd010, 0x5000 }, + { 0x9a01, 0xd008, 0x4000 }, + { 0x9a01, 0xd004, 0x3000 }, + { 0x9a01, 0xd002, 0x2000 }, + { 0x1a01, 0xd001, 0x0000 }, + { 0x1a01, 0xd003, 0x0000 }, + { 0x9a01, 0xd006, 0x2000 }, + { 0x1a01, 0xd005, 0x0000 }, + { 0x1a01, 0xd007, 0x0000 }, + { 0x9a01, 0xd00c, 0x3000 }, + { 0x9a01, 0xd00a, 0x2000 }, + { 0x1a01, 0xd009, 0x0000 }, + { 0x1a01, 0xd00b, 0x0000 }, + { 0x9a01, 0xd00e, 0x2000 }, + { 0x1a01, 0xd00d, 0x0000 }, + { 0x1a01, 0xd00f, 0x0000 }, + { 0x9a01, 0xd018, 0x4000 }, + { 0x9a01, 0xd014, 0x3000 }, + { 0x9a01, 0xd012, 0x2000 }, + { 0x1a01, 0xd011, 0x0000 }, + { 0x1a01, 0xd013, 0x0000 }, + { 0x9a01, 0xd016, 0x2000 }, + { 0x1a01, 0xd015, 0x0000 }, + { 0x1a01, 0xd017, 0x0000 }, + { 0x9a01, 0xd01c, 0x3000 }, + { 0x9a01, 0xd01a, 0x2000 }, + { 0x1a01, 0xd019, 0x0000 }, + { 0x1a01, 0xd01b, 0x0000 }, + { 0x9a01, 0xd01e, 0x2000 }, + { 0x1a01, 0xd01d, 0x0000 }, + { 0x1a01, 0xd01f, 0x0000 }, + { 0x9a01, 0xd030, 0x5000 }, + { 0x9a01, 0xd028, 0x4000 }, + { 0x9a01, 0xd024, 0x3000 }, + { 0x9a01, 0xd022, 0x2000 }, + { 0x1a01, 0xd021, 0x0000 }, + { 0x1a01, 0xd023, 0x0000 }, + { 0x9a01, 0xd026, 0x2000 }, + { 0x1a01, 0xd025, 0x0000 }, + { 0x1a01, 0xd027, 0x0000 }, + { 0x9a01, 0xd02c, 0x3000 }, + { 0x9a01, 0xd02a, 0x2000 }, + { 0x1a01, 0xd029, 0x0000 }, + { 0x1a01, 0xd02b, 0x0000 }, + { 0x9a01, 0xd02e, 0x2000 }, + { 0x1a01, 0xd02d, 0x0000 }, + { 0x1a01, 0xd02f, 0x0000 }, + { 0x9a01, 0xd038, 0x4000 }, + { 0x9a01, 0xd034, 0x3000 }, + { 0x9a01, 0xd032, 0x2000 }, + { 0x1a01, 0xd031, 0x0000 }, + { 0x1a01, 0xd033, 0x0000 }, + { 0x9a01, 0xd036, 0x2000 }, + { 0x1a01, 0xd035, 0x0000 }, + { 0x1a01, 0xd037, 0x0000 }, + { 0x9a01, 0xd03c, 0x3000 }, + { 0x9a01, 0xd03a, 0x2000 }, + { 0x1a01, 0xd039, 0x0000 }, + { 0x1a01, 0xd03b, 0x0000 }, + { 0x9a01, 0xd03e, 0x2000 }, + { 0x1a01, 0xd03d, 0x0000 }, + { 0x1a01, 0xd03f, 0x0000 }, + { 0x9a01, 0xd060, 0x6000 }, + { 0x9a01, 0xd050, 0x5000 }, + { 0x9a01, 0xd048, 0x4000 }, + { 0x9a01, 0xd044, 0x3000 }, + { 0x9a01, 0xd042, 0x2000 }, + { 0x1a01, 0xd041, 0x0000 }, + { 0x1a01, 0xd043, 0x0000 }, + { 0x9a01, 0xd046, 0x2000 }, + { 0x1a01, 0xd045, 0x0000 }, + { 0x1a01, 0xd047, 0x0000 }, + { 0x9a01, 0xd04c, 0x3000 }, + { 0x9a01, 0xd04a, 0x2000 }, + { 0x1a01, 0xd049, 0x0000 }, + { 0x1a01, 0xd04b, 0x0000 }, + { 0x9a01, 0xd04e, 0x2000 }, + { 0x1a01, 0xd04d, 0x0000 }, + { 0x1a01, 0xd04f, 0x0000 }, + { 0x9a01, 0xd058, 0x4000 }, + { 0x9a01, 0xd054, 0x3000 }, + { 0x9a01, 0xd052, 0x2000 }, + { 0x1a01, 0xd051, 0x0000 }, + { 0x1a01, 0xd053, 0x0000 }, + { 0x9a01, 0xd056, 0x2000 }, + { 0x1a01, 0xd055, 0x0000 }, + { 0x1a01, 0xd057, 0x0000 }, + { 0x9a01, 0xd05c, 0x3000 }, + { 0x9a01, 0xd05a, 0x2000 }, + { 0x1a01, 0xd059, 0x0000 }, + { 0x1a01, 0xd05b, 0x0000 }, + { 0x9a01, 0xd05e, 0x2000 }, + { 0x1a01, 0xd05d, 0x0000 }, + { 0x1a01, 0xd05f, 0x0000 }, + { 0x9a01, 0xd070, 0x5000 }, + { 0x9a01, 0xd068, 0x4000 }, + { 0x9a01, 0xd064, 0x3000 }, + { 0x9a01, 0xd062, 0x2000 }, + { 0x1a01, 0xd061, 0x0000 }, + { 0x1a01, 0xd063, 0x0000 }, + { 0x9a01, 0xd066, 0x2000 }, + { 0x1a01, 0xd065, 0x0000 }, + { 0x1a01, 0xd067, 0x0000 }, + { 0x9a01, 0xd06c, 0x3000 }, + { 0x9a01, 0xd06a, 0x2000 }, + { 0x1a01, 0xd069, 0x0000 }, + { 0x1a01, 0xd06b, 0x0000 }, + { 0x9a01, 0xd06e, 0x2000 }, + { 0x1a01, 0xd06d, 0x0000 }, + { 0x1a01, 0xd06f, 0x0000 }, + { 0x9a01, 0xd078, 0x4000 }, + { 0x9a01, 0xd074, 0x3000 }, + { 0x9a01, 0xd072, 0x2000 }, + { 0x1a01, 0xd071, 0x0000 }, + { 0x1a01, 0xd073, 0x0000 }, + { 0x9a01, 0xd076, 0x2000 }, + { 0x1a01, 0xd075, 0x0000 }, + { 0x1a01, 0xd077, 0x0000 }, + { 0x9a01, 0xd07c, 0x3000 }, + { 0x9a01, 0xd07a, 0x2000 }, + { 0x1a01, 0xd079, 0x0000 }, + { 0x1a01, 0xd07b, 0x0000 }, + { 0x9a01, 0xd07e, 0x2000 }, + { 0x1a01, 0xd07d, 0x0000 }, + { 0x1a01, 0xd07f, 0x0000 }, + { 0x9a01, 0xd18d, 0x9000 }, + { 0x9a01, 0xd10a, 0x8000 }, + { 0x9a01, 0xd0c0, 0x7000 }, + { 0x9a01, 0xd0a0, 0x6000 }, + { 0x9a01, 0xd090, 0x5000 }, + { 0x9a01, 0xd088, 0x4000 }, + { 0x9a01, 0xd084, 0x3000 }, + { 0x9a01, 0xd082, 0x2000 }, + { 0x1a01, 0xd081, 0x0000 }, + { 0x1a01, 0xd083, 0x0000 }, + { 0x9a01, 0xd086, 0x2000 }, + { 0x1a01, 0xd085, 0x0000 }, + { 0x1a01, 0xd087, 0x0000 }, + { 0x9a01, 0xd08c, 0x3000 }, + { 0x9a01, 0xd08a, 0x2000 }, + { 0x1a01, 0xd089, 0x0000 }, + { 0x1a01, 0xd08b, 0x0000 }, + { 0x9a01, 0xd08e, 0x2000 }, + { 0x1a01, 0xd08d, 0x0000 }, + { 0x1a01, 0xd08f, 0x0000 }, + { 0x9a01, 0xd098, 0x4000 }, + { 0x9a01, 0xd094, 0x3000 }, + { 0x9a01, 0xd092, 0x2000 }, + { 0x1a01, 0xd091, 0x0000 }, + { 0x1a01, 0xd093, 0x0000 }, + { 0x9a01, 0xd096, 0x2000 }, + { 0x1a01, 0xd095, 0x0000 }, + { 0x1a01, 0xd097, 0x0000 }, + { 0x9a01, 0xd09c, 0x3000 }, + { 0x9a01, 0xd09a, 0x2000 }, + { 0x1a01, 0xd099, 0x0000 }, + { 0x1a01, 0xd09b, 0x0000 }, + { 0x9a01, 0xd09e, 0x2000 }, + { 0x1a01, 0xd09d, 0x0000 }, + { 0x1a01, 0xd09f, 0x0000 }, + { 0x9a01, 0xd0b0, 0x5000 }, + { 0x9a01, 0xd0a8, 0x4000 }, + { 0x9a01, 0xd0a4, 0x3000 }, + { 0x9a01, 0xd0a2, 0x2000 }, + { 0x1a01, 0xd0a1, 0x0000 }, + { 0x1a01, 0xd0a3, 0x0000 }, + { 0x9a01, 0xd0a6, 0x2000 }, + { 0x1a01, 0xd0a5, 0x0000 }, + { 0x1a01, 0xd0a7, 0x0000 }, + { 0x9a01, 0xd0ac, 0x3000 }, + { 0x9a01, 0xd0aa, 0x2000 }, + { 0x1a01, 0xd0a9, 0x0000 }, + { 0x1a01, 0xd0ab, 0x0000 }, + { 0x9a01, 0xd0ae, 0x2000 }, + { 0x1a01, 0xd0ad, 0x0000 }, + { 0x1a01, 0xd0af, 0x0000 }, + { 0x9a01, 0xd0b8, 0x4000 }, + { 0x9a01, 0xd0b4, 0x3000 }, + { 0x9a01, 0xd0b2, 0x2000 }, + { 0x1a01, 0xd0b1, 0x0000 }, + { 0x1a01, 0xd0b3, 0x0000 }, + { 0x9a01, 0xd0b6, 0x2000 }, + { 0x1a01, 0xd0b5, 0x0000 }, + { 0x1a01, 0xd0b7, 0x0000 }, + { 0x9a01, 0xd0bc, 0x3000 }, + { 0x9a01, 0xd0ba, 0x2000 }, + { 0x1a01, 0xd0b9, 0x0000 }, + { 0x1a01, 0xd0bb, 0x0000 }, + { 0x9a01, 0xd0be, 0x2000 }, + { 0x1a01, 0xd0bd, 0x0000 }, + { 0x1a01, 0xd0bf, 0x0000 }, + { 0x9a01, 0xd0e0, 0x6000 }, + { 0x9a01, 0xd0d0, 0x5000 }, + { 0x9a01, 0xd0c8, 0x4000 }, + { 0x9a01, 0xd0c4, 0x3000 }, + { 0x9a01, 0xd0c2, 0x2000 }, + { 0x1a01, 0xd0c1, 0x0000 }, + { 0x1a01, 0xd0c3, 0x0000 }, + { 0x9a01, 0xd0c6, 0x2000 }, + { 0x1a01, 0xd0c5, 0x0000 }, + { 0x1a01, 0xd0c7, 0x0000 }, + { 0x9a01, 0xd0cc, 0x3000 }, + { 0x9a01, 0xd0ca, 0x2000 }, + { 0x1a01, 0xd0c9, 0x0000 }, + { 0x1a01, 0xd0cb, 0x0000 }, + { 0x9a01, 0xd0ce, 0x2000 }, + { 0x1a01, 0xd0cd, 0x0000 }, + { 0x1a01, 0xd0cf, 0x0000 }, + { 0x9a01, 0xd0d8, 0x4000 }, + { 0x9a01, 0xd0d4, 0x3000 }, + { 0x9a01, 0xd0d2, 0x2000 }, + { 0x1a01, 0xd0d1, 0x0000 }, + { 0x1a01, 0xd0d3, 0x0000 }, + { 0x9a01, 0xd0d6, 0x2000 }, + { 0x1a01, 0xd0d5, 0x0000 }, + { 0x1a01, 0xd0d7, 0x0000 }, + { 0x9a01, 0xd0dc, 0x3000 }, + { 0x9a01, 0xd0da, 0x2000 }, + { 0x1a01, 0xd0d9, 0x0000 }, + { 0x1a01, 0xd0db, 0x0000 }, + { 0x9a01, 0xd0de, 0x2000 }, + { 0x1a01, 0xd0dd, 0x0000 }, + { 0x1a01, 0xd0df, 0x0000 }, + { 0x9a01, 0xd0f0, 0x5000 }, + { 0x9a01, 0xd0e8, 0x4000 }, + { 0x9a01, 0xd0e4, 0x3000 }, + { 0x9a01, 0xd0e2, 0x2000 }, + { 0x1a01, 0xd0e1, 0x0000 }, + { 0x1a01, 0xd0e3, 0x0000 }, + { 0x9a01, 0xd0e6, 0x2000 }, + { 0x1a01, 0xd0e5, 0x0000 }, + { 0x1a01, 0xd0e7, 0x0000 }, + { 0x9a01, 0xd0ec, 0x3000 }, + { 0x9a01, 0xd0ea, 0x2000 }, + { 0x1a01, 0xd0e9, 0x0000 }, + { 0x1a01, 0xd0eb, 0x0000 }, + { 0x9a01, 0xd0ee, 0x2000 }, + { 0x1a01, 0xd0ed, 0x0000 }, + { 0x1a01, 0xd0ef, 0x0000 }, + { 0x9a01, 0xd102, 0x4000 }, + { 0x9a01, 0xd0f4, 0x3000 }, + { 0x9a01, 0xd0f2, 0x2000 }, + { 0x1a01, 0xd0f1, 0x0000 }, + { 0x1a01, 0xd0f3, 0x0000 }, + { 0x9a01, 0xd100, 0x2000 }, + { 0x1a01, 0xd0f5, 0x0000 }, + { 0x1a01, 0xd101, 0x0000 }, + { 0x9a01, 0xd106, 0x3000 }, + { 0x9a01, 0xd104, 0x2000 }, + { 0x1a01, 0xd103, 0x0000 }, + { 0x1a01, 0xd105, 0x0000 }, + { 0x9a01, 0xd108, 0x2000 }, + { 0x1a01, 0xd107, 0x0000 }, + { 0x1a01, 0xd109, 0x0000 }, + { 0x9a01, 0xd14d, 0x7000 }, + { 0x9a01, 0xd12d, 0x6000 }, + { 0x9a01, 0xd11a, 0x5000 }, + { 0x9a01, 0xd112, 0x4000 }, + { 0x9a01, 0xd10e, 0x3000 }, + { 0x9a01, 0xd10c, 0x2000 }, + { 0x1a01, 0xd10b, 0x0000 }, + { 0x1a01, 0xd10d, 0x0000 }, + { 0x9a01, 0xd110, 0x2000 }, + { 0x1a01, 0xd10f, 0x0000 }, + { 0x1a01, 0xd111, 0x0000 }, + { 0x9a01, 0xd116, 0x3000 }, + { 0x9a01, 0xd114, 0x2000 }, + { 0x1a01, 0xd113, 0x0000 }, + { 0x1a01, 0xd115, 0x0000 }, + { 0x9a01, 0xd118, 0x2000 }, + { 0x1a01, 0xd117, 0x0000 }, + { 0x1a01, 0xd119, 0x0000 }, + { 0x9a01, 0xd122, 0x4000 }, + { 0x9a01, 0xd11e, 0x3000 }, + { 0x9a01, 0xd11c, 0x2000 }, + { 0x1a01, 0xd11b, 0x0000 }, + { 0x1a01, 0xd11d, 0x0000 }, + { 0x9a01, 0xd120, 0x2000 }, + { 0x1a01, 0xd11f, 0x0000 }, + { 0x1a01, 0xd121, 0x0000 }, + { 0x9a01, 0xd126, 0x3000 }, + { 0x9a01, 0xd124, 0x2000 }, + { 0x1a01, 0xd123, 0x0000 }, + { 0x1a01, 0xd125, 0x0000 }, + { 0x9a01, 0xd12b, 0x2000 }, + { 0x1a01, 0xd12a, 0x0000 }, + { 0x1a01, 0xd12c, 0x0000 }, + { 0x9a01, 0xd13d, 0x5000 }, + { 0x9a01, 0xd135, 0x4000 }, + { 0x9a01, 0xd131, 0x3000 }, + { 0x9a01, 0xd12f, 0x2000 }, + { 0x1a01, 0xd12e, 0x0000 }, + { 0x1a01, 0xd130, 0x0000 }, + { 0x9a01, 0xd133, 0x2000 }, + { 0x1a01, 0xd132, 0x0000 }, + { 0x1a01, 0xd134, 0x0000 }, + { 0x9a01, 0xd139, 0x3000 }, + { 0x9a01, 0xd137, 0x2000 }, + { 0x1a01, 0xd136, 0x0000 }, + { 0x1a01, 0xd138, 0x0000 }, + { 0x9a01, 0xd13b, 0x2000 }, + { 0x1a01, 0xd13a, 0x0000 }, + { 0x1a01, 0xd13c, 0x0000 }, + { 0x9a01, 0xd145, 0x4000 }, + { 0x9a01, 0xd141, 0x3000 }, + { 0x9a01, 0xd13f, 0x2000 }, + { 0x1a01, 0xd13e, 0x0000 }, + { 0x1a01, 0xd140, 0x0000 }, + { 0x9a01, 0xd143, 0x2000 }, + { 0x1a01, 0xd142, 0x0000 }, + { 0x1a01, 0xd144, 0x0000 }, + { 0x9a01, 0xd149, 0x3000 }, + { 0x9a01, 0xd147, 0x2000 }, + { 0x1a01, 0xd146, 0x0000 }, + { 0x1a01, 0xd148, 0x0000 }, + { 0x9a01, 0xd14b, 0x2000 }, + { 0x1a01, 0xd14a, 0x0000 }, + { 0x1a01, 0xd14c, 0x0000 }, + { 0x8a01, 0xd16d, 0x6000 }, + { 0x9a01, 0xd15d, 0x5000 }, + { 0x9a01, 0xd155, 0x4000 }, + { 0x9a01, 0xd151, 0x3000 }, + { 0x9a01, 0xd14f, 0x2000 }, + { 0x1a01, 0xd14e, 0x0000 }, + { 0x1a01, 0xd150, 0x0000 }, + { 0x9a01, 0xd153, 0x2000 }, + { 0x1a01, 0xd152, 0x0000 }, + { 0x1a01, 0xd154, 0x0000 }, + { 0x9a01, 0xd159, 0x3000 }, + { 0x9a01, 0xd157, 0x2000 }, + { 0x1a01, 0xd156, 0x0000 }, + { 0x1a01, 0xd158, 0x0000 }, + { 0x9a01, 0xd15b, 0x2000 }, + { 0x1a01, 0xd15a, 0x0000 }, + { 0x1a01, 0xd15c, 0x0000 }, + { 0x8a01, 0xd165, 0x4000 }, + { 0x9a01, 0xd161, 0x3000 }, + { 0x9a01, 0xd15f, 0x2000 }, + { 0x1a01, 0xd15e, 0x0000 }, + { 0x1a01, 0xd160, 0x0000 }, + { 0x9a01, 0xd163, 0x2000 }, + { 0x1a01, 0xd162, 0x0000 }, + { 0x1a01, 0xd164, 0x0000 }, + { 0x8c01, 0xd169, 0x3000 }, + { 0x8c01, 0xd167, 0x2000 }, + { 0x0a01, 0xd166, 0x0000 }, + { 0x0c01, 0xd168, 0x0000 }, + { 0x9a01, 0xd16b, 0x2000 }, + { 0x1a01, 0xd16a, 0x0000 }, + { 0x1a01, 0xd16c, 0x0000 }, + { 0x8c01, 0xd17d, 0x5000 }, + { 0x8101, 0xd175, 0x4000 }, + { 0x8a01, 0xd171, 0x3000 }, + { 0x8a01, 0xd16f, 0x2000 }, + { 0x0a01, 0xd16e, 0x0000 }, + { 0x0a01, 0xd170, 0x0000 }, + { 0x8101, 0xd173, 0x2000 }, + { 0x0a01, 0xd172, 0x0000 }, + { 0x0101, 0xd174, 0x0000 }, + { 0x8101, 0xd179, 0x3000 }, + { 0x8101, 0xd177, 0x2000 }, + { 0x0101, 0xd176, 0x0000 }, + { 0x0101, 0xd178, 0x0000 }, + { 0x8c01, 0xd17b, 0x2000 }, + { 0x0101, 0xd17a, 0x0000 }, + { 0x0c01, 0xd17c, 0x0000 }, + { 0x8c01, 0xd185, 0x4000 }, + { 0x8c01, 0xd181, 0x3000 }, + { 0x8c01, 0xd17f, 0x2000 }, + { 0x0c01, 0xd17e, 0x0000 }, + { 0x0c01, 0xd180, 0x0000 }, + { 0x9a01, 0xd183, 0x2000 }, + { 0x0c01, 0xd182, 0x0000 }, + { 0x1a01, 0xd184, 0x0000 }, + { 0x8c01, 0xd189, 0x3000 }, + { 0x8c01, 0xd187, 0x2000 }, + { 0x0c01, 0xd186, 0x0000 }, + { 0x0c01, 0xd188, 0x0000 }, + { 0x8c01, 0xd18b, 0x2000 }, + { 0x0c01, 0xd18a, 0x0000 }, + { 0x1a01, 0xd18c, 0x0000 }, + { 0x9a01, 0xd32f, 0x8000 }, + { 0x9a01, 0xd1cd, 0x7000 }, + { 0x8c01, 0xd1ad, 0x6000 }, + { 0x9a01, 0xd19d, 0x5000 }, + { 0x9a01, 0xd195, 0x4000 }, + { 0x9a01, 0xd191, 0x3000 }, + { 0x9a01, 0xd18f, 0x2000 }, + { 0x1a01, 0xd18e, 0x0000 }, + { 0x1a01, 0xd190, 0x0000 }, + { 0x9a01, 0xd193, 0x2000 }, + { 0x1a01, 0xd192, 0x0000 }, + { 0x1a01, 0xd194, 0x0000 }, + { 0x9a01, 0xd199, 0x3000 }, + { 0x9a01, 0xd197, 0x2000 }, + { 0x1a01, 0xd196, 0x0000 }, + { 0x1a01, 0xd198, 0x0000 }, + { 0x9a01, 0xd19b, 0x2000 }, + { 0x1a01, 0xd19a, 0x0000 }, + { 0x1a01, 0xd19c, 0x0000 }, + { 0x9a01, 0xd1a5, 0x4000 }, + { 0x9a01, 0xd1a1, 0x3000 }, + { 0x9a01, 0xd19f, 0x2000 }, + { 0x1a01, 0xd19e, 0x0000 }, + { 0x1a01, 0xd1a0, 0x0000 }, + { 0x9a01, 0xd1a3, 0x2000 }, + { 0x1a01, 0xd1a2, 0x0000 }, + { 0x1a01, 0xd1a4, 0x0000 }, + { 0x9a01, 0xd1a9, 0x3000 }, + { 0x9a01, 0xd1a7, 0x2000 }, + { 0x1a01, 0xd1a6, 0x0000 }, + { 0x1a01, 0xd1a8, 0x0000 }, + { 0x8c01, 0xd1ab, 0x2000 }, + { 0x0c01, 0xd1aa, 0x0000 }, + { 0x0c01, 0xd1ac, 0x0000 }, + { 0x9a01, 0xd1bd, 0x5000 }, + { 0x9a01, 0xd1b5, 0x4000 }, + { 0x9a01, 0xd1b1, 0x3000 }, + { 0x9a01, 0xd1af, 0x2000 }, + { 0x1a01, 0xd1ae, 0x0000 }, + { 0x1a01, 0xd1b0, 0x0000 }, + { 0x9a01, 0xd1b3, 0x2000 }, + { 0x1a01, 0xd1b2, 0x0000 }, + { 0x1a01, 0xd1b4, 0x0000 }, + { 0x9a01, 0xd1b9, 0x3000 }, + { 0x9a01, 0xd1b7, 0x2000 }, + { 0x1a01, 0xd1b6, 0x0000 }, + { 0x1a01, 0xd1b8, 0x0000 }, + { 0x9a01, 0xd1bb, 0x2000 }, + { 0x1a01, 0xd1ba, 0x0000 }, + { 0x1a01, 0xd1bc, 0x0000 }, + { 0x9a01, 0xd1c5, 0x4000 }, + { 0x9a01, 0xd1c1, 0x3000 }, + { 0x9a01, 0xd1bf, 0x2000 }, + { 0x1a01, 0xd1be, 0x0000 }, + { 0x1a01, 0xd1c0, 0x0000 }, + { 0x9a01, 0xd1c3, 0x2000 }, + { 0x1a01, 0xd1c2, 0x0000 }, + { 0x1a01, 0xd1c4, 0x0000 }, + { 0x9a01, 0xd1c9, 0x3000 }, + { 0x9a01, 0xd1c7, 0x2000 }, + { 0x1a01, 0xd1c6, 0x0000 }, + { 0x1a01, 0xd1c8, 0x0000 }, + { 0x9a01, 0xd1cb, 0x2000 }, + { 0x1a01, 0xd1ca, 0x0000 }, + { 0x1a01, 0xd1cc, 0x0000 }, + { 0x9a01, 0xd30f, 0x6000 }, + { 0x9a01, 0xd1dd, 0x5000 }, + { 0x9a01, 0xd1d5, 0x4000 }, + { 0x9a01, 0xd1d1, 0x3000 }, + { 0x9a01, 0xd1cf, 0x2000 }, + { 0x1a01, 0xd1ce, 0x0000 }, + { 0x1a01, 0xd1d0, 0x0000 }, + { 0x9a01, 0xd1d3, 0x2000 }, + { 0x1a01, 0xd1d2, 0x0000 }, + { 0x1a01, 0xd1d4, 0x0000 }, + { 0x9a01, 0xd1d9, 0x3000 }, + { 0x9a01, 0xd1d7, 0x2000 }, + { 0x1a01, 0xd1d6, 0x0000 }, + { 0x1a01, 0xd1d8, 0x0000 }, + { 0x9a01, 0xd1db, 0x2000 }, + { 0x1a01, 0xd1da, 0x0000 }, + { 0x1a01, 0xd1dc, 0x0000 }, + { 0x9a01, 0xd307, 0x4000 }, + { 0x9a01, 0xd303, 0x3000 }, + { 0x9a01, 0xd301, 0x2000 }, + { 0x1a01, 0xd300, 0x0000 }, + { 0x1a01, 0xd302, 0x0000 }, + { 0x9a01, 0xd305, 0x2000 }, + { 0x1a01, 0xd304, 0x0000 }, + { 0x1a01, 0xd306, 0x0000 }, + { 0x9a01, 0xd30b, 0x3000 }, + { 0x9a01, 0xd309, 0x2000 }, + { 0x1a01, 0xd308, 0x0000 }, + { 0x1a01, 0xd30a, 0x0000 }, + { 0x9a01, 0xd30d, 0x2000 }, + { 0x1a01, 0xd30c, 0x0000 }, + { 0x1a01, 0xd30e, 0x0000 }, + { 0x9a01, 0xd31f, 0x5000 }, + { 0x9a01, 0xd317, 0x4000 }, + { 0x9a01, 0xd313, 0x3000 }, + { 0x9a01, 0xd311, 0x2000 }, + { 0x1a01, 0xd310, 0x0000 }, + { 0x1a01, 0xd312, 0x0000 }, + { 0x9a01, 0xd315, 0x2000 }, + { 0x1a01, 0xd314, 0x0000 }, + { 0x1a01, 0xd316, 0x0000 }, + { 0x9a01, 0xd31b, 0x3000 }, + { 0x9a01, 0xd319, 0x2000 }, + { 0x1a01, 0xd318, 0x0000 }, + { 0x1a01, 0xd31a, 0x0000 }, + { 0x9a01, 0xd31d, 0x2000 }, + { 0x1a01, 0xd31c, 0x0000 }, + { 0x1a01, 0xd31e, 0x0000 }, + { 0x9a01, 0xd327, 0x4000 }, + { 0x9a01, 0xd323, 0x3000 }, + { 0x9a01, 0xd321, 0x2000 }, + { 0x1a01, 0xd320, 0x0000 }, + { 0x1a01, 0xd322, 0x0000 }, + { 0x9a01, 0xd325, 0x2000 }, + { 0x1a01, 0xd324, 0x0000 }, + { 0x1a01, 0xd326, 0x0000 }, + { 0x9a01, 0xd32b, 0x3000 }, + { 0x9a01, 0xd329, 0x2000 }, + { 0x1a01, 0xd328, 0x0000 }, + { 0x1a01, 0xd32a, 0x0000 }, + { 0x9a01, 0xd32d, 0x2000 }, + { 0x1a01, 0xd32c, 0x0000 }, + { 0x1a01, 0xd32e, 0x0000 }, + { 0x8901, 0xd418, 0x7000 }, + { 0x9a01, 0xd34f, 0x6000 }, + { 0x9a01, 0xd33f, 0x5000 }, + { 0x9a01, 0xd337, 0x4000 }, + { 0x9a01, 0xd333, 0x3000 }, + { 0x9a01, 0xd331, 0x2000 }, + { 0x1a01, 0xd330, 0x0000 }, + { 0x1a01, 0xd332, 0x0000 }, + { 0x9a01, 0xd335, 0x2000 }, + { 0x1a01, 0xd334, 0x0000 }, + { 0x1a01, 0xd336, 0x0000 }, + { 0x9a01, 0xd33b, 0x3000 }, + { 0x9a01, 0xd339, 0x2000 }, + { 0x1a01, 0xd338, 0x0000 }, + { 0x1a01, 0xd33a, 0x0000 }, + { 0x9a01, 0xd33d, 0x2000 }, + { 0x1a01, 0xd33c, 0x0000 }, + { 0x1a01, 0xd33e, 0x0000 }, + { 0x9a01, 0xd347, 0x4000 }, + { 0x9a01, 0xd343, 0x3000 }, + { 0x9a01, 0xd341, 0x2000 }, + { 0x1a01, 0xd340, 0x0000 }, + { 0x1a01, 0xd342, 0x0000 }, + { 0x9a01, 0xd345, 0x2000 }, + { 0x1a01, 0xd344, 0x0000 }, + { 0x1a01, 0xd346, 0x0000 }, + { 0x9a01, 0xd34b, 0x3000 }, + { 0x9a01, 0xd349, 0x2000 }, + { 0x1a01, 0xd348, 0x0000 }, + { 0x1a01, 0xd34a, 0x0000 }, + { 0x9a01, 0xd34d, 0x2000 }, + { 0x1a01, 0xd34c, 0x0000 }, + { 0x1a01, 0xd34e, 0x0000 }, + { 0x8901, 0xd408, 0x5000 }, + { 0x8901, 0xd400, 0x4000 }, + { 0x9a01, 0xd353, 0x3000 }, + { 0x9a01, 0xd351, 0x2000 }, + { 0x1a01, 0xd350, 0x0000 }, + { 0x1a01, 0xd352, 0x0000 }, + { 0x9a01, 0xd355, 0x2000 }, + { 0x1a01, 0xd354, 0x0000 }, + { 0x1a01, 0xd356, 0x0000 }, + { 0x8901, 0xd404, 0x3000 }, + { 0x8901, 0xd402, 0x2000 }, + { 0x0901, 0xd401, 0x0000 }, + { 0x0901, 0xd403, 0x0000 }, + { 0x8901, 0xd406, 0x2000 }, + { 0x0901, 0xd405, 0x0000 }, + { 0x0901, 0xd407, 0x0000 }, + { 0x8901, 0xd410, 0x4000 }, + { 0x8901, 0xd40c, 0x3000 }, + { 0x8901, 0xd40a, 0x2000 }, + { 0x0901, 0xd409, 0x0000 }, + { 0x0901, 0xd40b, 0x0000 }, + { 0x8901, 0xd40e, 0x2000 }, + { 0x0901, 0xd40d, 0x0000 }, + { 0x0901, 0xd40f, 0x0000 }, + { 0x8901, 0xd414, 0x3000 }, + { 0x8901, 0xd412, 0x2000 }, + { 0x0901, 0xd411, 0x0000 }, + { 0x0901, 0xd413, 0x0000 }, + { 0x8901, 0xd416, 0x2000 }, + { 0x0901, 0xd415, 0x0000 }, + { 0x0901, 0xd417, 0x0000 }, + { 0x8901, 0xd438, 0x6000 }, + { 0x8501, 0xd428, 0x5000 }, + { 0x8501, 0xd420, 0x4000 }, + { 0x8501, 0xd41c, 0x3000 }, + { 0x8501, 0xd41a, 0x2000 }, + { 0x0901, 0xd419, 0x0000 }, + { 0x0501, 0xd41b, 0x0000 }, + { 0x8501, 0xd41e, 0x2000 }, + { 0x0501, 0xd41d, 0x0000 }, + { 0x0501, 0xd41f, 0x0000 }, + { 0x8501, 0xd424, 0x3000 }, + { 0x8501, 0xd422, 0x2000 }, + { 0x0501, 0xd421, 0x0000 }, + { 0x0501, 0xd423, 0x0000 }, + { 0x8501, 0xd426, 0x2000 }, + { 0x0501, 0xd425, 0x0000 }, + { 0x0501, 0xd427, 0x0000 }, + { 0x8501, 0xd430, 0x4000 }, + { 0x8501, 0xd42c, 0x3000 }, + { 0x8501, 0xd42a, 0x2000 }, + { 0x0501, 0xd429, 0x0000 }, + { 0x0501, 0xd42b, 0x0000 }, + { 0x8501, 0xd42e, 0x2000 }, + { 0x0501, 0xd42d, 0x0000 }, + { 0x0501, 0xd42f, 0x0000 }, + { 0x8901, 0xd434, 0x3000 }, + { 0x8501, 0xd432, 0x2000 }, + { 0x0501, 0xd431, 0x0000 }, + { 0x0501, 0xd433, 0x0000 }, + { 0x8901, 0xd436, 0x2000 }, + { 0x0901, 0xd435, 0x0000 }, + { 0x0901, 0xd437, 0x0000 }, + { 0x8901, 0xd448, 0x5000 }, + { 0x8901, 0xd440, 0x4000 }, + { 0x8901, 0xd43c, 0x3000 }, + { 0x8901, 0xd43a, 0x2000 }, + { 0x0901, 0xd439, 0x0000 }, + { 0x0901, 0xd43b, 0x0000 }, + { 0x8901, 0xd43e, 0x2000 }, + { 0x0901, 0xd43d, 0x0000 }, + { 0x0901, 0xd43f, 0x0000 }, + { 0x8901, 0xd444, 0x3000 }, + { 0x8901, 0xd442, 0x2000 }, + { 0x0901, 0xd441, 0x0000 }, + { 0x0901, 0xd443, 0x0000 }, + { 0x8901, 0xd446, 0x2000 }, + { 0x0901, 0xd445, 0x0000 }, + { 0x0901, 0xd447, 0x0000 }, + { 0x8501, 0xd450, 0x4000 }, + { 0x8901, 0xd44c, 0x3000 }, + { 0x8901, 0xd44a, 0x2000 }, + { 0x0901, 0xd449, 0x0000 }, + { 0x0901, 0xd44b, 0x0000 }, + { 0x8501, 0xd44e, 0x2000 }, + { 0x0901, 0xd44d, 0x0000 }, + { 0x0501, 0xd44f, 0x0000 }, + { 0x8501, 0xd454, 0x3000 }, + { 0x8501, 0xd452, 0x2000 }, + { 0x0501, 0xd451, 0x0000 }, + { 0x0501, 0xd453, 0x0000 }, + { 0x8501, 0xd457, 0x2000 }, + { 0x0501, 0xd456, 0x0000 }, + { 0x0501, 0xd458, 0x0000 }, + { 0x8702, 0xf876, 0xb000 }, + { 0x8901, 0xd670, 0xa000 }, + { 0x8901, 0xd570, 0x9000 }, + { 0x8901, 0xd4e4, 0x8000 }, + { 0x8501, 0xd499, 0x7000 }, + { 0x8901, 0xd479, 0x6000 }, + { 0x8901, 0xd469, 0x5000 }, + { 0x8501, 0xd461, 0x4000 }, + { 0x8501, 0xd45d, 0x3000 }, + { 0x8501, 0xd45b, 0x2000 }, + { 0x0501, 0xd45a, 0x0000 }, + { 0x0501, 0xd45c, 0x0000 }, + { 0x8501, 0xd45f, 0x2000 }, + { 0x0501, 0xd45e, 0x0000 }, + { 0x0501, 0xd460, 0x0000 }, + { 0x8501, 0xd465, 0x3000 }, + { 0x8501, 0xd463, 0x2000 }, + { 0x0501, 0xd462, 0x0000 }, + { 0x0501, 0xd464, 0x0000 }, + { 0x8501, 0xd467, 0x2000 }, + { 0x0501, 0xd466, 0x0000 }, + { 0x0901, 0xd468, 0x0000 }, + { 0x8901, 0xd471, 0x4000 }, + { 0x8901, 0xd46d, 0x3000 }, + { 0x8901, 0xd46b, 0x2000 }, + { 0x0901, 0xd46a, 0x0000 }, + { 0x0901, 0xd46c, 0x0000 }, + { 0x8901, 0xd46f, 0x2000 }, + { 0x0901, 0xd46e, 0x0000 }, + { 0x0901, 0xd470, 0x0000 }, + { 0x8901, 0xd475, 0x3000 }, + { 0x8901, 0xd473, 0x2000 }, + { 0x0901, 0xd472, 0x0000 }, + { 0x0901, 0xd474, 0x0000 }, + { 0x8901, 0xd477, 0x2000 }, + { 0x0901, 0xd476, 0x0000 }, + { 0x0901, 0xd478, 0x0000 }, + { 0x8501, 0xd489, 0x5000 }, + { 0x8901, 0xd481, 0x4000 }, + { 0x8901, 0xd47d, 0x3000 }, + { 0x8901, 0xd47b, 0x2000 }, + { 0x0901, 0xd47a, 0x0000 }, + { 0x0901, 0xd47c, 0x0000 }, + { 0x8901, 0xd47f, 0x2000 }, + { 0x0901, 0xd47e, 0x0000 }, + { 0x0901, 0xd480, 0x0000 }, + { 0x8501, 0xd485, 0x3000 }, + { 0x8501, 0xd483, 0x2000 }, + { 0x0501, 0xd482, 0x0000 }, + { 0x0501, 0xd484, 0x0000 }, + { 0x8501, 0xd487, 0x2000 }, + { 0x0501, 0xd486, 0x0000 }, + { 0x0501, 0xd488, 0x0000 }, + { 0x8501, 0xd491, 0x4000 }, + { 0x8501, 0xd48d, 0x3000 }, + { 0x8501, 0xd48b, 0x2000 }, + { 0x0501, 0xd48a, 0x0000 }, + { 0x0501, 0xd48c, 0x0000 }, + { 0x8501, 0xd48f, 0x2000 }, + { 0x0501, 0xd48e, 0x0000 }, + { 0x0501, 0xd490, 0x0000 }, + { 0x8501, 0xd495, 0x3000 }, + { 0x8501, 0xd493, 0x2000 }, + { 0x0501, 0xd492, 0x0000 }, + { 0x0501, 0xd494, 0x0000 }, + { 0x8501, 0xd497, 0x2000 }, + { 0x0501, 0xd496, 0x0000 }, + { 0x0501, 0xd498, 0x0000 }, + { 0x8501, 0xd4c3, 0x6000 }, + { 0x8901, 0xd4b1, 0x5000 }, + { 0x8901, 0xd4a6, 0x4000 }, + { 0x8901, 0xd49e, 0x3000 }, + { 0x8501, 0xd49b, 0x2000 }, + { 0x0501, 0xd49a, 0x0000 }, + { 0x0901, 0xd49c, 0x0000 }, + { 0x8901, 0xd4a2, 0x2000 }, + { 0x0901, 0xd49f, 0x0000 }, + { 0x0901, 0xd4a5, 0x0000 }, + { 0x8901, 0xd4ac, 0x3000 }, + { 0x8901, 0xd4aa, 0x2000 }, + { 0x0901, 0xd4a9, 0x0000 }, + { 0x0901, 0xd4ab, 0x0000 }, + { 0x8901, 0xd4af, 0x2000 }, + { 0x0901, 0xd4ae, 0x0000 }, + { 0x0901, 0xd4b0, 0x0000 }, + { 0x8501, 0xd4b9, 0x4000 }, + { 0x8901, 0xd4b5, 0x3000 }, + { 0x8901, 0xd4b3, 0x2000 }, + { 0x0901, 0xd4b2, 0x0000 }, + { 0x0901, 0xd4b4, 0x0000 }, + { 0x8501, 0xd4b7, 0x2000 }, + { 0x0501, 0xd4b6, 0x0000 }, + { 0x0501, 0xd4b8, 0x0000 }, + { 0x8501, 0xd4bf, 0x3000 }, + { 0x8501, 0xd4bd, 0x2000 }, + { 0x0501, 0xd4bb, 0x0000 }, + { 0x0501, 0xd4be, 0x0000 }, + { 0x8501, 0xd4c1, 0x2000 }, + { 0x0501, 0xd4c0, 0x0000 }, + { 0x0501, 0xd4c2, 0x0000 }, + { 0x8901, 0xd4d4, 0x5000 }, + { 0x8501, 0xd4cc, 0x4000 }, + { 0x8501, 0xd4c8, 0x3000 }, + { 0x8501, 0xd4c6, 0x2000 }, + { 0x0501, 0xd4c5, 0x0000 }, + { 0x0501, 0xd4c7, 0x0000 }, + { 0x8501, 0xd4ca, 0x2000 }, + { 0x0501, 0xd4c9, 0x0000 }, + { 0x0501, 0xd4cb, 0x0000 }, + { 0x8901, 0xd4d0, 0x3000 }, + { 0x8501, 0xd4ce, 0x2000 }, + { 0x0501, 0xd4cd, 0x0000 }, + { 0x0501, 0xd4cf, 0x0000 }, + { 0x8901, 0xd4d2, 0x2000 }, + { 0x0901, 0xd4d1, 0x0000 }, + { 0x0901, 0xd4d3, 0x0000 }, + { 0x8901, 0xd4dc, 0x4000 }, + { 0x8901, 0xd4d8, 0x3000 }, + { 0x8901, 0xd4d6, 0x2000 }, + { 0x0901, 0xd4d5, 0x0000 }, + { 0x0901, 0xd4d7, 0x0000 }, + { 0x8901, 0xd4da, 0x2000 }, + { 0x0901, 0xd4d9, 0x0000 }, + { 0x0901, 0xd4db, 0x0000 }, + { 0x8901, 0xd4e0, 0x3000 }, + { 0x8901, 0xd4de, 0x2000 }, + { 0x0901, 0xd4dd, 0x0000 }, + { 0x0901, 0xd4df, 0x0000 }, + { 0x8901, 0xd4e2, 0x2000 }, + { 0x0901, 0xd4e1, 0x0000 }, + { 0x0901, 0xd4e3, 0x0000 }, + { 0x8501, 0xd529, 0x7000 }, + { 0x8901, 0xd504, 0x6000 }, + { 0x8501, 0xd4f4, 0x5000 }, + { 0x8501, 0xd4ec, 0x4000 }, + { 0x8901, 0xd4e8, 0x3000 }, + { 0x8901, 0xd4e6, 0x2000 }, + { 0x0901, 0xd4e5, 0x0000 }, + { 0x0901, 0xd4e7, 0x0000 }, + { 0x8501, 0xd4ea, 0x2000 }, + { 0x0901, 0xd4e9, 0x0000 }, + { 0x0501, 0xd4eb, 0x0000 }, + { 0x8501, 0xd4f0, 0x3000 }, + { 0x8501, 0xd4ee, 0x2000 }, + { 0x0501, 0xd4ed, 0x0000 }, + { 0x0501, 0xd4ef, 0x0000 }, + { 0x8501, 0xd4f2, 0x2000 }, + { 0x0501, 0xd4f1, 0x0000 }, + { 0x0501, 0xd4f3, 0x0000 }, + { 0x8501, 0xd4fc, 0x4000 }, + { 0x8501, 0xd4f8, 0x3000 }, + { 0x8501, 0xd4f6, 0x2000 }, + { 0x0501, 0xd4f5, 0x0000 }, + { 0x0501, 0xd4f7, 0x0000 }, + { 0x8501, 0xd4fa, 0x2000 }, + { 0x0501, 0xd4f9, 0x0000 }, + { 0x0501, 0xd4fb, 0x0000 }, + { 0x8501, 0xd500, 0x3000 }, + { 0x8501, 0xd4fe, 0x2000 }, + { 0x0501, 0xd4fd, 0x0000 }, + { 0x0501, 0xd4ff, 0x0000 }, + { 0x8501, 0xd502, 0x2000 }, + { 0x0501, 0xd501, 0x0000 }, + { 0x0501, 0xd503, 0x0000 }, + { 0x8901, 0xd518, 0x5000 }, + { 0x8901, 0xd50f, 0x4000 }, + { 0x8901, 0xd509, 0x3000 }, + { 0x8901, 0xd507, 0x2000 }, + { 0x0901, 0xd505, 0x0000 }, + { 0x0901, 0xd508, 0x0000 }, + { 0x8901, 0xd50d, 0x2000 }, + { 0x0901, 0xd50a, 0x0000 }, + { 0x0901, 0xd50e, 0x0000 }, + { 0x8901, 0xd513, 0x3000 }, + { 0x8901, 0xd511, 0x2000 }, + { 0x0901, 0xd510, 0x0000 }, + { 0x0901, 0xd512, 0x0000 }, + { 0x8901, 0xd516, 0x2000 }, + { 0x0901, 0xd514, 0x0000 }, + { 0x0901, 0xd517, 0x0000 }, + { 0x8501, 0xd521, 0x4000 }, + { 0x8901, 0xd51c, 0x3000 }, + { 0x8901, 0xd51a, 0x2000 }, + { 0x0901, 0xd519, 0x0000 }, + { 0x0901, 0xd51b, 0x0000 }, + { 0x8501, 0xd51f, 0x2000 }, + { 0x0501, 0xd51e, 0x0000 }, + { 0x0501, 0xd520, 0x0000 }, + { 0x8501, 0xd525, 0x3000 }, + { 0x8501, 0xd523, 0x2000 }, + { 0x0501, 0xd522, 0x0000 }, + { 0x0501, 0xd524, 0x0000 }, + { 0x8501, 0xd527, 0x2000 }, + { 0x0501, 0xd526, 0x0000 }, + { 0x0501, 0xd528, 0x0000 }, + { 0x8901, 0xd54f, 0x6000 }, + { 0x8901, 0xd539, 0x5000 }, + { 0x8501, 0xd531, 0x4000 }, + { 0x8501, 0xd52d, 0x3000 }, + { 0x8501, 0xd52b, 0x2000 }, + { 0x0501, 0xd52a, 0x0000 }, + { 0x0501, 0xd52c, 0x0000 }, + { 0x8501, 0xd52f, 0x2000 }, + { 0x0501, 0xd52e, 0x0000 }, + { 0x0501, 0xd530, 0x0000 }, + { 0x8501, 0xd535, 0x3000 }, + { 0x8501, 0xd533, 0x2000 }, + { 0x0501, 0xd532, 0x0000 }, + { 0x0501, 0xd534, 0x0000 }, + { 0x8501, 0xd537, 0x2000 }, + { 0x0501, 0xd536, 0x0000 }, + { 0x0901, 0xd538, 0x0000 }, + { 0x8901, 0xd543, 0x4000 }, + { 0x8901, 0xd53e, 0x3000 }, + { 0x8901, 0xd53c, 0x2000 }, + { 0x0901, 0xd53b, 0x0000 }, + { 0x0901, 0xd53d, 0x0000 }, + { 0x8901, 0xd541, 0x2000 }, + { 0x0901, 0xd540, 0x0000 }, + { 0x0901, 0xd542, 0x0000 }, + { 0x8901, 0xd54b, 0x3000 }, + { 0x8901, 0xd546, 0x2000 }, + { 0x0901, 0xd544, 0x0000 }, + { 0x0901, 0xd54a, 0x0000 }, + { 0x8901, 0xd54d, 0x2000 }, + { 0x0901, 0xd54c, 0x0000 }, + { 0x0901, 0xd54e, 0x0000 }, + { 0x8501, 0xd560, 0x5000 }, + { 0x8501, 0xd558, 0x4000 }, + { 0x8501, 0xd554, 0x3000 }, + { 0x8501, 0xd552, 0x2000 }, + { 0x0901, 0xd550, 0x0000 }, + { 0x0501, 0xd553, 0x0000 }, + { 0x8501, 0xd556, 0x2000 }, + { 0x0501, 0xd555, 0x0000 }, + { 0x0501, 0xd557, 0x0000 }, + { 0x8501, 0xd55c, 0x3000 }, + { 0x8501, 0xd55a, 0x2000 }, + { 0x0501, 0xd559, 0x0000 }, + { 0x0501, 0xd55b, 0x0000 }, + { 0x8501, 0xd55e, 0x2000 }, + { 0x0501, 0xd55d, 0x0000 }, + { 0x0501, 0xd55f, 0x0000 }, + { 0x8501, 0xd568, 0x4000 }, + { 0x8501, 0xd564, 0x3000 }, + { 0x8501, 0xd562, 0x2000 }, + { 0x0501, 0xd561, 0x0000 }, + { 0x0501, 0xd563, 0x0000 }, + { 0x8501, 0xd566, 0x2000 }, + { 0x0501, 0xd565, 0x0000 }, + { 0x0501, 0xd567, 0x0000 }, + { 0x8901, 0xd56c, 0x3000 }, + { 0x8501, 0xd56a, 0x2000 }, + { 0x0501, 0xd569, 0x0000 }, + { 0x0501, 0xd56b, 0x0000 }, + { 0x8901, 0xd56e, 0x2000 }, + { 0x0901, 0xd56d, 0x0000 }, + { 0x0901, 0xd56f, 0x0000 }, + { 0x8501, 0xd5f0, 0x8000 }, + { 0x8901, 0xd5b0, 0x7000 }, + { 0x8501, 0xd590, 0x6000 }, + { 0x8901, 0xd580, 0x5000 }, + { 0x8901, 0xd578, 0x4000 }, + { 0x8901, 0xd574, 0x3000 }, + { 0x8901, 0xd572, 0x2000 }, + { 0x0901, 0xd571, 0x0000 }, + { 0x0901, 0xd573, 0x0000 }, + { 0x8901, 0xd576, 0x2000 }, + { 0x0901, 0xd575, 0x0000 }, + { 0x0901, 0xd577, 0x0000 }, + { 0x8901, 0xd57c, 0x3000 }, + { 0x8901, 0xd57a, 0x2000 }, + { 0x0901, 0xd579, 0x0000 }, + { 0x0901, 0xd57b, 0x0000 }, + { 0x8901, 0xd57e, 0x2000 }, + { 0x0901, 0xd57d, 0x0000 }, + { 0x0901, 0xd57f, 0x0000 }, + { 0x8501, 0xd588, 0x4000 }, + { 0x8901, 0xd584, 0x3000 }, + { 0x8901, 0xd582, 0x2000 }, + { 0x0901, 0xd581, 0x0000 }, + { 0x0901, 0xd583, 0x0000 }, + { 0x8501, 0xd586, 0x2000 }, + { 0x0901, 0xd585, 0x0000 }, + { 0x0501, 0xd587, 0x0000 }, + { 0x8501, 0xd58c, 0x3000 }, + { 0x8501, 0xd58a, 0x2000 }, + { 0x0501, 0xd589, 0x0000 }, + { 0x0501, 0xd58b, 0x0000 }, + { 0x8501, 0xd58e, 0x2000 }, + { 0x0501, 0xd58d, 0x0000 }, + { 0x0501, 0xd58f, 0x0000 }, + { 0x8901, 0xd5a0, 0x5000 }, + { 0x8501, 0xd598, 0x4000 }, + { 0x8501, 0xd594, 0x3000 }, + { 0x8501, 0xd592, 0x2000 }, + { 0x0501, 0xd591, 0x0000 }, + { 0x0501, 0xd593, 0x0000 }, + { 0x8501, 0xd596, 0x2000 }, + { 0x0501, 0xd595, 0x0000 }, + { 0x0501, 0xd597, 0x0000 }, + { 0x8501, 0xd59c, 0x3000 }, + { 0x8501, 0xd59a, 0x2000 }, + { 0x0501, 0xd599, 0x0000 }, + { 0x0501, 0xd59b, 0x0000 }, + { 0x8501, 0xd59e, 0x2000 }, + { 0x0501, 0xd59d, 0x0000 }, + { 0x0501, 0xd59f, 0x0000 }, + { 0x8901, 0xd5a8, 0x4000 }, + { 0x8901, 0xd5a4, 0x3000 }, + { 0x8901, 0xd5a2, 0x2000 }, + { 0x0901, 0xd5a1, 0x0000 }, + { 0x0901, 0xd5a3, 0x0000 }, + { 0x8901, 0xd5a6, 0x2000 }, + { 0x0901, 0xd5a5, 0x0000 }, + { 0x0901, 0xd5a7, 0x0000 }, + { 0x8901, 0xd5ac, 0x3000 }, + { 0x8901, 0xd5aa, 0x2000 }, + { 0x0901, 0xd5a9, 0x0000 }, + { 0x0901, 0xd5ab, 0x0000 }, + { 0x8901, 0xd5ae, 0x2000 }, + { 0x0901, 0xd5ad, 0x0000 }, + { 0x0901, 0xd5af, 0x0000 }, + { 0x8501, 0xd5d0, 0x6000 }, + { 0x8501, 0xd5c0, 0x5000 }, + { 0x8901, 0xd5b8, 0x4000 }, + { 0x8901, 0xd5b4, 0x3000 }, + { 0x8901, 0xd5b2, 0x2000 }, + { 0x0901, 0xd5b1, 0x0000 }, + { 0x0901, 0xd5b3, 0x0000 }, + { 0x8901, 0xd5b6, 0x2000 }, + { 0x0901, 0xd5b5, 0x0000 }, + { 0x0901, 0xd5b7, 0x0000 }, + { 0x8501, 0xd5bc, 0x3000 }, + { 0x8501, 0xd5ba, 0x2000 }, + { 0x0901, 0xd5b9, 0x0000 }, + { 0x0501, 0xd5bb, 0x0000 }, + { 0x8501, 0xd5be, 0x2000 }, + { 0x0501, 0xd5bd, 0x0000 }, + { 0x0501, 0xd5bf, 0x0000 }, + { 0x8501, 0xd5c8, 0x4000 }, + { 0x8501, 0xd5c4, 0x3000 }, + { 0x8501, 0xd5c2, 0x2000 }, + { 0x0501, 0xd5c1, 0x0000 }, + { 0x0501, 0xd5c3, 0x0000 }, + { 0x8501, 0xd5c6, 0x2000 }, + { 0x0501, 0xd5c5, 0x0000 }, + { 0x0501, 0xd5c7, 0x0000 }, + { 0x8501, 0xd5cc, 0x3000 }, + { 0x8501, 0xd5ca, 0x2000 }, + { 0x0501, 0xd5c9, 0x0000 }, + { 0x0501, 0xd5cb, 0x0000 }, + { 0x8501, 0xd5ce, 0x2000 }, + { 0x0501, 0xd5cd, 0x0000 }, + { 0x0501, 0xd5cf, 0x0000 }, + { 0x8901, 0xd5e0, 0x5000 }, + { 0x8901, 0xd5d8, 0x4000 }, + { 0x8901, 0xd5d4, 0x3000 }, + { 0x8501, 0xd5d2, 0x2000 }, + { 0x0501, 0xd5d1, 0x0000 }, + { 0x0501, 0xd5d3, 0x0000 }, + { 0x8901, 0xd5d6, 0x2000 }, + { 0x0901, 0xd5d5, 0x0000 }, + { 0x0901, 0xd5d7, 0x0000 }, + { 0x8901, 0xd5dc, 0x3000 }, + { 0x8901, 0xd5da, 0x2000 }, + { 0x0901, 0xd5d9, 0x0000 }, + { 0x0901, 0xd5db, 0x0000 }, + { 0x8901, 0xd5de, 0x2000 }, + { 0x0901, 0xd5dd, 0x0000 }, + { 0x0901, 0xd5df, 0x0000 }, + { 0x8901, 0xd5e8, 0x4000 }, + { 0x8901, 0xd5e4, 0x3000 }, + { 0x8901, 0xd5e2, 0x2000 }, + { 0x0901, 0xd5e1, 0x0000 }, + { 0x0901, 0xd5e3, 0x0000 }, + { 0x8901, 0xd5e6, 0x2000 }, + { 0x0901, 0xd5e5, 0x0000 }, + { 0x0901, 0xd5e7, 0x0000 }, + { 0x8901, 0xd5ec, 0x3000 }, + { 0x8901, 0xd5ea, 0x2000 }, + { 0x0901, 0xd5e9, 0x0000 }, + { 0x0901, 0xd5eb, 0x0000 }, + { 0x8501, 0xd5ee, 0x2000 }, + { 0x0901, 0xd5ed, 0x0000 }, + { 0x0501, 0xd5ef, 0x0000 }, + { 0x8501, 0xd630, 0x7000 }, + { 0x8901, 0xd610, 0x6000 }, + { 0x8501, 0xd600, 0x5000 }, + { 0x8501, 0xd5f8, 0x4000 }, + { 0x8501, 0xd5f4, 0x3000 }, + { 0x8501, 0xd5f2, 0x2000 }, + { 0x0501, 0xd5f1, 0x0000 }, + { 0x0501, 0xd5f3, 0x0000 }, + { 0x8501, 0xd5f6, 0x2000 }, + { 0x0501, 0xd5f5, 0x0000 }, + { 0x0501, 0xd5f7, 0x0000 }, + { 0x8501, 0xd5fc, 0x3000 }, + { 0x8501, 0xd5fa, 0x2000 }, + { 0x0501, 0xd5f9, 0x0000 }, + { 0x0501, 0xd5fb, 0x0000 }, + { 0x8501, 0xd5fe, 0x2000 }, + { 0x0501, 0xd5fd, 0x0000 }, + { 0x0501, 0xd5ff, 0x0000 }, + { 0x8901, 0xd608, 0x4000 }, + { 0x8501, 0xd604, 0x3000 }, + { 0x8501, 0xd602, 0x2000 }, + { 0x0501, 0xd601, 0x0000 }, + { 0x0501, 0xd603, 0x0000 }, + { 0x8501, 0xd606, 0x2000 }, + { 0x0501, 0xd605, 0x0000 }, + { 0x0501, 0xd607, 0x0000 }, + { 0x8901, 0xd60c, 0x3000 }, + { 0x8901, 0xd60a, 0x2000 }, + { 0x0901, 0xd609, 0x0000 }, + { 0x0901, 0xd60b, 0x0000 }, + { 0x8901, 0xd60e, 0x2000 }, + { 0x0901, 0xd60d, 0x0000 }, + { 0x0901, 0xd60f, 0x0000 }, + { 0x8901, 0xd620, 0x5000 }, + { 0x8901, 0xd618, 0x4000 }, + { 0x8901, 0xd614, 0x3000 }, + { 0x8901, 0xd612, 0x2000 }, + { 0x0901, 0xd611, 0x0000 }, + { 0x0901, 0xd613, 0x0000 }, + { 0x8901, 0xd616, 0x2000 }, + { 0x0901, 0xd615, 0x0000 }, + { 0x0901, 0xd617, 0x0000 }, + { 0x8901, 0xd61c, 0x3000 }, + { 0x8901, 0xd61a, 0x2000 }, + { 0x0901, 0xd619, 0x0000 }, + { 0x0901, 0xd61b, 0x0000 }, + { 0x8901, 0xd61e, 0x2000 }, + { 0x0901, 0xd61d, 0x0000 }, + { 0x0901, 0xd61f, 0x0000 }, + { 0x8501, 0xd628, 0x4000 }, + { 0x8501, 0xd624, 0x3000 }, + { 0x8501, 0xd622, 0x2000 }, + { 0x0901, 0xd621, 0x0000 }, + { 0x0501, 0xd623, 0x0000 }, + { 0x8501, 0xd626, 0x2000 }, + { 0x0501, 0xd625, 0x0000 }, + { 0x0501, 0xd627, 0x0000 }, + { 0x8501, 0xd62c, 0x3000 }, + { 0x8501, 0xd62a, 0x2000 }, + { 0x0501, 0xd629, 0x0000 }, + { 0x0501, 0xd62b, 0x0000 }, + { 0x8501, 0xd62e, 0x2000 }, + { 0x0501, 0xd62d, 0x0000 }, + { 0x0501, 0xd62f, 0x0000 }, + { 0x8901, 0xd650, 0x6000 }, + { 0x8901, 0xd640, 0x5000 }, + { 0x8501, 0xd638, 0x4000 }, + { 0x8501, 0xd634, 0x3000 }, + { 0x8501, 0xd632, 0x2000 }, + { 0x0501, 0xd631, 0x0000 }, + { 0x0501, 0xd633, 0x0000 }, + { 0x8501, 0xd636, 0x2000 }, + { 0x0501, 0xd635, 0x0000 }, + { 0x0501, 0xd637, 0x0000 }, + { 0x8901, 0xd63c, 0x3000 }, + { 0x8501, 0xd63a, 0x2000 }, + { 0x0501, 0xd639, 0x0000 }, + { 0x0501, 0xd63b, 0x0000 }, + { 0x8901, 0xd63e, 0x2000 }, + { 0x0901, 0xd63d, 0x0000 }, + { 0x0901, 0xd63f, 0x0000 }, + { 0x8901, 0xd648, 0x4000 }, + { 0x8901, 0xd644, 0x3000 }, + { 0x8901, 0xd642, 0x2000 }, + { 0x0901, 0xd641, 0x0000 }, + { 0x0901, 0xd643, 0x0000 }, + { 0x8901, 0xd646, 0x2000 }, + { 0x0901, 0xd645, 0x0000 }, + { 0x0901, 0xd647, 0x0000 }, + { 0x8901, 0xd64c, 0x3000 }, + { 0x8901, 0xd64a, 0x2000 }, + { 0x0901, 0xd649, 0x0000 }, + { 0x0901, 0xd64b, 0x0000 }, + { 0x8901, 0xd64e, 0x2000 }, + { 0x0901, 0xd64d, 0x0000 }, + { 0x0901, 0xd64f, 0x0000 }, + { 0x8501, 0xd660, 0x5000 }, + { 0x8501, 0xd658, 0x4000 }, + { 0x8901, 0xd654, 0x3000 }, + { 0x8901, 0xd652, 0x2000 }, + { 0x0901, 0xd651, 0x0000 }, + { 0x0901, 0xd653, 0x0000 }, + { 0x8501, 0xd656, 0x2000 }, + { 0x0901, 0xd655, 0x0000 }, + { 0x0501, 0xd657, 0x0000 }, + { 0x8501, 0xd65c, 0x3000 }, + { 0x8501, 0xd65a, 0x2000 }, + { 0x0501, 0xd659, 0x0000 }, + { 0x0501, 0xd65b, 0x0000 }, + { 0x8501, 0xd65e, 0x2000 }, + { 0x0501, 0xd65d, 0x0000 }, + { 0x0501, 0xd65f, 0x0000 }, + { 0x8501, 0xd668, 0x4000 }, + { 0x8501, 0xd664, 0x3000 }, + { 0x8501, 0xd662, 0x2000 }, + { 0x0501, 0xd661, 0x0000 }, + { 0x0501, 0xd663, 0x0000 }, + { 0x8501, 0xd666, 0x2000 }, + { 0x0501, 0xd665, 0x0000 }, + { 0x0501, 0xd667, 0x0000 }, + { 0x8501, 0xd66c, 0x3000 }, + { 0x8501, 0xd66a, 0x2000 }, + { 0x0501, 0xd669, 0x0000 }, + { 0x0501, 0xd66b, 0x0000 }, + { 0x8501, 0xd66e, 0x2000 }, + { 0x0501, 0xd66d, 0x0000 }, + { 0x0501, 0xd66f, 0x0000 }, + { 0x8501, 0xd774, 0x9000 }, + { 0x8901, 0xd6f4, 0x8000 }, + { 0x8901, 0xd6b4, 0x7000 }, + { 0x8501, 0xd690, 0x6000 }, + { 0x8901, 0xd680, 0x5000 }, + { 0x8901, 0xd678, 0x4000 }, + { 0x8901, 0xd674, 0x3000 }, + { 0x8901, 0xd672, 0x2000 }, + { 0x0901, 0xd671, 0x0000 }, + { 0x0901, 0xd673, 0x0000 }, + { 0x8901, 0xd676, 0x2000 }, + { 0x0901, 0xd675, 0x0000 }, + { 0x0901, 0xd677, 0x0000 }, + { 0x8901, 0xd67c, 0x3000 }, + { 0x8901, 0xd67a, 0x2000 }, + { 0x0901, 0xd679, 0x0000 }, + { 0x0901, 0xd67b, 0x0000 }, + { 0x8901, 0xd67e, 0x2000 }, + { 0x0901, 0xd67d, 0x0000 }, + { 0x0901, 0xd67f, 0x0000 }, + { 0x8901, 0xd688, 0x4000 }, + { 0x8901, 0xd684, 0x3000 }, + { 0x8901, 0xd682, 0x2000 }, + { 0x0901, 0xd681, 0x0000 }, + { 0x0901, 0xd683, 0x0000 }, + { 0x8901, 0xd686, 0x2000 }, + { 0x0901, 0xd685, 0x0000 }, + { 0x0901, 0xd687, 0x0000 }, + { 0x8501, 0xd68c, 0x3000 }, + { 0x8501, 0xd68a, 0x2000 }, + { 0x0901, 0xd689, 0x0000 }, + { 0x0501, 0xd68b, 0x0000 }, + { 0x8501, 0xd68e, 0x2000 }, + { 0x0501, 0xd68d, 0x0000 }, + { 0x0501, 0xd68f, 0x0000 }, + { 0x8501, 0xd6a0, 0x5000 }, + { 0x8501, 0xd698, 0x4000 }, + { 0x8501, 0xd694, 0x3000 }, + { 0x8501, 0xd692, 0x2000 }, + { 0x0501, 0xd691, 0x0000 }, + { 0x0501, 0xd693, 0x0000 }, + { 0x8501, 0xd696, 0x2000 }, + { 0x0501, 0xd695, 0x0000 }, + { 0x0501, 0xd697, 0x0000 }, + { 0x8501, 0xd69c, 0x3000 }, + { 0x8501, 0xd69a, 0x2000 }, + { 0x0501, 0xd699, 0x0000 }, + { 0x0501, 0xd69b, 0x0000 }, + { 0x8501, 0xd69e, 0x2000 }, + { 0x0501, 0xd69d, 0x0000 }, + { 0x0501, 0xd69f, 0x0000 }, + { 0x8901, 0xd6ac, 0x4000 }, + { 0x8901, 0xd6a8, 0x3000 }, + { 0x8501, 0xd6a2, 0x2000 }, + { 0x0501, 0xd6a1, 0x0000 }, + { 0x0501, 0xd6a3, 0x0000 }, + { 0x8901, 0xd6aa, 0x2000 }, + { 0x0901, 0xd6a9, 0x0000 }, + { 0x0901, 0xd6ab, 0x0000 }, + { 0x8901, 0xd6b0, 0x3000 }, + { 0x8901, 0xd6ae, 0x2000 }, + { 0x0901, 0xd6ad, 0x0000 }, + { 0x0901, 0xd6af, 0x0000 }, + { 0x8901, 0xd6b2, 0x2000 }, + { 0x0901, 0xd6b1, 0x0000 }, + { 0x0901, 0xd6b3, 0x0000 }, + { 0x8501, 0xd6d4, 0x6000 }, + { 0x8501, 0xd6c4, 0x5000 }, + { 0x8901, 0xd6bc, 0x4000 }, + { 0x8901, 0xd6b8, 0x3000 }, + { 0x8901, 0xd6b6, 0x2000 }, + { 0x0901, 0xd6b5, 0x0000 }, + { 0x0901, 0xd6b7, 0x0000 }, + { 0x8901, 0xd6ba, 0x2000 }, + { 0x0901, 0xd6b9, 0x0000 }, + { 0x0901, 0xd6bb, 0x0000 }, + { 0x8901, 0xd6c0, 0x3000 }, + { 0x8901, 0xd6be, 0x2000 }, + { 0x0901, 0xd6bd, 0x0000 }, + { 0x0901, 0xd6bf, 0x0000 }, + { 0x8501, 0xd6c2, 0x2000 }, + { 0x1901, 0xd6c1, 0x0000 }, + { 0x0501, 0xd6c3, 0x0000 }, + { 0x8501, 0xd6cc, 0x4000 }, + { 0x8501, 0xd6c8, 0x3000 }, + { 0x8501, 0xd6c6, 0x2000 }, + { 0x0501, 0xd6c5, 0x0000 }, + { 0x0501, 0xd6c7, 0x0000 }, + { 0x8501, 0xd6ca, 0x2000 }, + { 0x0501, 0xd6c9, 0x0000 }, + { 0x0501, 0xd6cb, 0x0000 }, + { 0x8501, 0xd6d0, 0x3000 }, + { 0x8501, 0xd6ce, 0x2000 }, + { 0x0501, 0xd6cd, 0x0000 }, + { 0x0501, 0xd6cf, 0x0000 }, + { 0x8501, 0xd6d2, 0x2000 }, + { 0x0501, 0xd6d1, 0x0000 }, + { 0x0501, 0xd6d3, 0x0000 }, + { 0x8901, 0xd6e4, 0x5000 }, + { 0x8501, 0xd6dc, 0x4000 }, + { 0x8501, 0xd6d8, 0x3000 }, + { 0x8501, 0xd6d6, 0x2000 }, + { 0x0501, 0xd6d5, 0x0000 }, + { 0x0501, 0xd6d7, 0x0000 }, + { 0x8501, 0xd6da, 0x2000 }, + { 0x0501, 0xd6d9, 0x0000 }, + { 0x1901, 0xd6db, 0x0000 }, + { 0x8501, 0xd6e0, 0x3000 }, + { 0x8501, 0xd6de, 0x2000 }, + { 0x0501, 0xd6dd, 0x0000 }, + { 0x0501, 0xd6df, 0x0000 }, + { 0x8901, 0xd6e2, 0x2000 }, + { 0x0501, 0xd6e1, 0x0000 }, + { 0x0901, 0xd6e3, 0x0000 }, + { 0x8901, 0xd6ec, 0x4000 }, + { 0x8901, 0xd6e8, 0x3000 }, + { 0x8901, 0xd6e6, 0x2000 }, + { 0x0901, 0xd6e5, 0x0000 }, + { 0x0901, 0xd6e7, 0x0000 }, + { 0x8901, 0xd6ea, 0x2000 }, + { 0x0901, 0xd6e9, 0x0000 }, + { 0x0901, 0xd6eb, 0x0000 }, + { 0x8901, 0xd6f0, 0x3000 }, + { 0x8901, 0xd6ee, 0x2000 }, + { 0x0901, 0xd6ed, 0x0000 }, + { 0x0901, 0xd6ef, 0x0000 }, + { 0x8901, 0xd6f2, 0x2000 }, + { 0x0901, 0xd6f1, 0x0000 }, + { 0x0901, 0xd6f3, 0x0000 }, + { 0x8901, 0xd734, 0x7000 }, + { 0x8501, 0xd714, 0x6000 }, + { 0x8501, 0xd704, 0x5000 }, + { 0x8501, 0xd6fc, 0x4000 }, + { 0x8901, 0xd6f8, 0x3000 }, + { 0x8901, 0xd6f6, 0x2000 }, + { 0x0901, 0xd6f5, 0x0000 }, + { 0x0901, 0xd6f7, 0x0000 }, + { 0x8901, 0xd6fa, 0x2000 }, + { 0x0901, 0xd6f9, 0x0000 }, + { 0x1901, 0xd6fb, 0x0000 }, + { 0x8501, 0xd700, 0x3000 }, + { 0x8501, 0xd6fe, 0x2000 }, + { 0x0501, 0xd6fd, 0x0000 }, + { 0x0501, 0xd6ff, 0x0000 }, + { 0x8501, 0xd702, 0x2000 }, + { 0x0501, 0xd701, 0x0000 }, + { 0x0501, 0xd703, 0x0000 }, + { 0x8501, 0xd70c, 0x4000 }, + { 0x8501, 0xd708, 0x3000 }, + { 0x8501, 0xd706, 0x2000 }, + { 0x0501, 0xd705, 0x0000 }, + { 0x0501, 0xd707, 0x0000 }, + { 0x8501, 0xd70a, 0x2000 }, + { 0x0501, 0xd709, 0x0000 }, + { 0x0501, 0xd70b, 0x0000 }, + { 0x8501, 0xd710, 0x3000 }, + { 0x8501, 0xd70e, 0x2000 }, + { 0x0501, 0xd70d, 0x0000 }, + { 0x0501, 0xd70f, 0x0000 }, + { 0x8501, 0xd712, 0x2000 }, + { 0x0501, 0xd711, 0x0000 }, + { 0x0501, 0xd713, 0x0000 }, + { 0x8901, 0xd724, 0x5000 }, + { 0x8901, 0xd71c, 0x4000 }, + { 0x8501, 0xd718, 0x3000 }, + { 0x8501, 0xd716, 0x2000 }, + { 0x1901, 0xd715, 0x0000 }, + { 0x0501, 0xd717, 0x0000 }, + { 0x8501, 0xd71a, 0x2000 }, + { 0x0501, 0xd719, 0x0000 }, + { 0x0501, 0xd71b, 0x0000 }, + { 0x8901, 0xd720, 0x3000 }, + { 0x8901, 0xd71e, 0x2000 }, + { 0x0901, 0xd71d, 0x0000 }, + { 0x0901, 0xd71f, 0x0000 }, + { 0x8901, 0xd722, 0x2000 }, + { 0x0901, 0xd721, 0x0000 }, + { 0x0901, 0xd723, 0x0000 }, + { 0x8901, 0xd72c, 0x4000 }, + { 0x8901, 0xd728, 0x3000 }, + { 0x8901, 0xd726, 0x2000 }, + { 0x0901, 0xd725, 0x0000 }, + { 0x0901, 0xd727, 0x0000 }, + { 0x8901, 0xd72a, 0x2000 }, + { 0x0901, 0xd729, 0x0000 }, + { 0x0901, 0xd72b, 0x0000 }, + { 0x8901, 0xd730, 0x3000 }, + { 0x8901, 0xd72e, 0x2000 }, + { 0x0901, 0xd72d, 0x0000 }, + { 0x0901, 0xd72f, 0x0000 }, + { 0x8901, 0xd732, 0x2000 }, + { 0x0901, 0xd731, 0x0000 }, + { 0x0901, 0xd733, 0x0000 }, + { 0x8501, 0xd754, 0x6000 }, + { 0x8501, 0xd744, 0x5000 }, + { 0x8501, 0xd73c, 0x4000 }, + { 0x8501, 0xd738, 0x3000 }, + { 0x8501, 0xd736, 0x2000 }, + { 0x1901, 0xd735, 0x0000 }, + { 0x0501, 0xd737, 0x0000 }, + { 0x8501, 0xd73a, 0x2000 }, + { 0x0501, 0xd739, 0x0000 }, + { 0x0501, 0xd73b, 0x0000 }, + { 0x8501, 0xd740, 0x3000 }, + { 0x8501, 0xd73e, 0x2000 }, + { 0x0501, 0xd73d, 0x0000 }, + { 0x0501, 0xd73f, 0x0000 }, + { 0x8501, 0xd742, 0x2000 }, + { 0x0501, 0xd741, 0x0000 }, + { 0x0501, 0xd743, 0x0000 }, + { 0x8501, 0xd74c, 0x4000 }, + { 0x8501, 0xd748, 0x3000 }, + { 0x8501, 0xd746, 0x2000 }, + { 0x0501, 0xd745, 0x0000 }, + { 0x0501, 0xd747, 0x0000 }, + { 0x8501, 0xd74a, 0x2000 }, + { 0x0501, 0xd749, 0x0000 }, + { 0x0501, 0xd74b, 0x0000 }, + { 0x8501, 0xd750, 0x3000 }, + { 0x8501, 0xd74e, 0x2000 }, + { 0x0501, 0xd74d, 0x0000 }, + { 0x1901, 0xd74f, 0x0000 }, + { 0x8501, 0xd752, 0x2000 }, + { 0x0501, 0xd751, 0x0000 }, + { 0x0501, 0xd753, 0x0000 }, + { 0x8901, 0xd764, 0x5000 }, + { 0x8901, 0xd75c, 0x4000 }, + { 0x8901, 0xd758, 0x3000 }, + { 0x8901, 0xd756, 0x2000 }, + { 0x0501, 0xd755, 0x0000 }, + { 0x0901, 0xd757, 0x0000 }, + { 0x8901, 0xd75a, 0x2000 }, + { 0x0901, 0xd759, 0x0000 }, + { 0x0901, 0xd75b, 0x0000 }, + { 0x8901, 0xd760, 0x3000 }, + { 0x8901, 0xd75e, 0x2000 }, + { 0x0901, 0xd75d, 0x0000 }, + { 0x0901, 0xd75f, 0x0000 }, + { 0x8901, 0xd762, 0x2000 }, + { 0x0901, 0xd761, 0x0000 }, + { 0x0901, 0xd763, 0x0000 }, + { 0x8901, 0xd76c, 0x4000 }, + { 0x8901, 0xd768, 0x3000 }, + { 0x8901, 0xd766, 0x2000 }, + { 0x0901, 0xd765, 0x0000 }, + { 0x0901, 0xd767, 0x0000 }, + { 0x8901, 0xd76a, 0x2000 }, + { 0x0901, 0xd769, 0x0000 }, + { 0x0901, 0xd76b, 0x0000 }, + { 0x8501, 0xd770, 0x3000 }, + { 0x8901, 0xd76e, 0x2000 }, + { 0x0901, 0xd76d, 0x0000 }, + { 0x1901, 0xd76f, 0x0000 }, + { 0x8501, 0xd772, 0x2000 }, + { 0x0501, 0xd771, 0x0000 }, + { 0x0501, 0xd773, 0x0000 }, + { 0x8d01, 0xd7f8, 0x8000 }, + { 0x8501, 0xd7b4, 0x7000 }, + { 0x8901, 0xd794, 0x6000 }, + { 0x8501, 0xd784, 0x5000 }, + { 0x8501, 0xd77c, 0x4000 }, + { 0x8501, 0xd778, 0x3000 }, + { 0x8501, 0xd776, 0x2000 }, + { 0x0501, 0xd775, 0x0000 }, + { 0x0501, 0xd777, 0x0000 }, + { 0x8501, 0xd77a, 0x2000 }, + { 0x0501, 0xd779, 0x0000 }, + { 0x0501, 0xd77b, 0x0000 }, + { 0x8501, 0xd780, 0x3000 }, + { 0x8501, 0xd77e, 0x2000 }, + { 0x0501, 0xd77d, 0x0000 }, + { 0x0501, 0xd77f, 0x0000 }, + { 0x8501, 0xd782, 0x2000 }, + { 0x0501, 0xd781, 0x0000 }, + { 0x0501, 0xd783, 0x0000 }, + { 0x8501, 0xd78c, 0x4000 }, + { 0x8501, 0xd788, 0x3000 }, + { 0x8501, 0xd786, 0x2000 }, + { 0x0501, 0xd785, 0x0000 }, + { 0x0501, 0xd787, 0x0000 }, + { 0x8501, 0xd78a, 0x2000 }, + { 0x1901, 0xd789, 0x0000 }, + { 0x0501, 0xd78b, 0x0000 }, + { 0x8901, 0xd790, 0x3000 }, + { 0x8501, 0xd78e, 0x2000 }, + { 0x0501, 0xd78d, 0x0000 }, + { 0x0501, 0xd78f, 0x0000 }, + { 0x8901, 0xd792, 0x2000 }, + { 0x0901, 0xd791, 0x0000 }, + { 0x0901, 0xd793, 0x0000 }, + { 0x8901, 0xd7a4, 0x5000 }, + { 0x8901, 0xd79c, 0x4000 }, + { 0x8901, 0xd798, 0x3000 }, + { 0x8901, 0xd796, 0x2000 }, + { 0x0901, 0xd795, 0x0000 }, + { 0x0901, 0xd797, 0x0000 }, + { 0x8901, 0xd79a, 0x2000 }, + { 0x0901, 0xd799, 0x0000 }, + { 0x0901, 0xd79b, 0x0000 }, + { 0x8901, 0xd7a0, 0x3000 }, + { 0x8901, 0xd79e, 0x2000 }, + { 0x0901, 0xd79d, 0x0000 }, + { 0x0901, 0xd79f, 0x0000 }, + { 0x8901, 0xd7a2, 0x2000 }, + { 0x0901, 0xd7a1, 0x0000 }, + { 0x0901, 0xd7a3, 0x0000 }, + { 0x8501, 0xd7ac, 0x4000 }, + { 0x8901, 0xd7a8, 0x3000 }, + { 0x8901, 0xd7a6, 0x2000 }, + { 0x0901, 0xd7a5, 0x0000 }, + { 0x0901, 0xd7a7, 0x0000 }, + { 0x8501, 0xd7aa, 0x2000 }, + { 0x1901, 0xd7a9, 0x0000 }, + { 0x0501, 0xd7ab, 0x0000 }, + { 0x8501, 0xd7b0, 0x3000 }, + { 0x8501, 0xd7ae, 0x2000 }, + { 0x0501, 0xd7ad, 0x0000 }, + { 0x0501, 0xd7af, 0x0000 }, + { 0x8501, 0xd7b2, 0x2000 }, + { 0x0501, 0xd7b1, 0x0000 }, + { 0x0501, 0xd7b3, 0x0000 }, + { 0x8d01, 0xd7d8, 0x6000 }, + { 0x8501, 0xd7c4, 0x5000 }, + { 0x8501, 0xd7bc, 0x4000 }, + { 0x8501, 0xd7b8, 0x3000 }, + { 0x8501, 0xd7b6, 0x2000 }, + { 0x0501, 0xd7b5, 0x0000 }, + { 0x0501, 0xd7b7, 0x0000 }, + { 0x8501, 0xd7ba, 0x2000 }, + { 0x0501, 0xd7b9, 0x0000 }, + { 0x0501, 0xd7bb, 0x0000 }, + { 0x8501, 0xd7c0, 0x3000 }, + { 0x8501, 0xd7be, 0x2000 }, + { 0x0501, 0xd7bd, 0x0000 }, + { 0x0501, 0xd7bf, 0x0000 }, + { 0x8501, 0xd7c2, 0x2000 }, + { 0x0501, 0xd7c1, 0x0000 }, + { 0x1901, 0xd7c3, 0x0000 }, + { 0x8d01, 0xd7d0, 0x4000 }, + { 0x8501, 0xd7c8, 0x3000 }, + { 0x8501, 0xd7c6, 0x2000 }, + { 0x0501, 0xd7c5, 0x0000 }, + { 0x0501, 0xd7c7, 0x0000 }, + { 0x8d01, 0xd7ce, 0x2000 }, + { 0x0501, 0xd7c9, 0x0000 }, + { 0x0d01, 0xd7cf, 0x0000 }, + { 0x8d01, 0xd7d4, 0x3000 }, + { 0x8d01, 0xd7d2, 0x2000 }, + { 0x0d01, 0xd7d1, 0x0000 }, + { 0x0d01, 0xd7d3, 0x0000 }, + { 0x8d01, 0xd7d6, 0x2000 }, + { 0x0d01, 0xd7d5, 0x0000 }, + { 0x0d01, 0xd7d7, 0x0000 }, + { 0x8d01, 0xd7e8, 0x5000 }, + { 0x8d01, 0xd7e0, 0x4000 }, + { 0x8d01, 0xd7dc, 0x3000 }, + { 0x8d01, 0xd7da, 0x2000 }, + { 0x0d01, 0xd7d9, 0x0000 }, + { 0x0d01, 0xd7db, 0x0000 }, + { 0x8d01, 0xd7de, 0x2000 }, + { 0x0d01, 0xd7dd, 0x0000 }, + { 0x0d01, 0xd7df, 0x0000 }, + { 0x8d01, 0xd7e4, 0x3000 }, + { 0x8d01, 0xd7e2, 0x2000 }, + { 0x0d01, 0xd7e1, 0x0000 }, + { 0x0d01, 0xd7e3, 0x0000 }, + { 0x8d01, 0xd7e6, 0x2000 }, + { 0x0d01, 0xd7e5, 0x0000 }, + { 0x0d01, 0xd7e7, 0x0000 }, + { 0x8d01, 0xd7f0, 0x4000 }, + { 0x8d01, 0xd7ec, 0x3000 }, + { 0x8d01, 0xd7ea, 0x2000 }, + { 0x0d01, 0xd7e9, 0x0000 }, + { 0x0d01, 0xd7eb, 0x0000 }, + { 0x8d01, 0xd7ee, 0x2000 }, + { 0x0d01, 0xd7ed, 0x0000 }, + { 0x0d01, 0xd7ef, 0x0000 }, + { 0x8d01, 0xd7f4, 0x3000 }, + { 0x8d01, 0xd7f2, 0x2000 }, + { 0x0d01, 0xd7f1, 0x0000 }, + { 0x0d01, 0xd7f3, 0x0000 }, + { 0x8d01, 0xd7f6, 0x2000 }, + { 0x0d01, 0xd7f5, 0x0000 }, + { 0x0d01, 0xd7f7, 0x0000 }, + { 0x8702, 0xf836, 0x7000 }, + { 0x8702, 0xf816, 0x6000 }, + { 0x8702, 0xf806, 0x5000 }, + { 0x8702, 0x0000, 0x4000 }, + { 0x8d01, 0xd7fc, 0x3000 }, + { 0x8d01, 0xd7fa, 0x2000 }, + { 0x0d01, 0xd7f9, 0x0000 }, + { 0x0d01, 0xd7fb, 0x0000 }, + { 0x8d01, 0xd7fe, 0x2000 }, + { 0x0d01, 0xd7fd, 0x0000 }, + { 0x0d01, 0xd7ff, 0x0000 }, + { 0x8702, 0xf802, 0x3000 }, + { 0x8702, 0xf800, 0x2000 }, + { 0x0702, 0xa6d6, 0x0000 }, + { 0x0702, 0xf801, 0x0000 }, + { 0x8702, 0xf804, 0x2000 }, + { 0x0702, 0xf803, 0x0000 }, + { 0x0702, 0xf805, 0x0000 }, + { 0x8702, 0xf80e, 0x4000 }, + { 0x8702, 0xf80a, 0x3000 }, + { 0x8702, 0xf808, 0x2000 }, + { 0x0702, 0xf807, 0x0000 }, + { 0x0702, 0xf809, 0x0000 }, + { 0x8702, 0xf80c, 0x2000 }, + { 0x0702, 0xf80b, 0x0000 }, + { 0x0702, 0xf80d, 0x0000 }, + { 0x8702, 0xf812, 0x3000 }, + { 0x8702, 0xf810, 0x2000 }, + { 0x0702, 0xf80f, 0x0000 }, + { 0x0702, 0xf811, 0x0000 }, + { 0x8702, 0xf814, 0x2000 }, + { 0x0702, 0xf813, 0x0000 }, + { 0x0702, 0xf815, 0x0000 }, + { 0x8702, 0xf826, 0x5000 }, + { 0x8702, 0xf81e, 0x4000 }, + { 0x8702, 0xf81a, 0x3000 }, + { 0x8702, 0xf818, 0x2000 }, + { 0x0702, 0xf817, 0x0000 }, + { 0x0702, 0xf819, 0x0000 }, + { 0x8702, 0xf81c, 0x2000 }, + { 0x0702, 0xf81b, 0x0000 }, + { 0x0702, 0xf81d, 0x0000 }, + { 0x8702, 0xf822, 0x3000 }, + { 0x8702, 0xf820, 0x2000 }, + { 0x0702, 0xf81f, 0x0000 }, + { 0x0702, 0xf821, 0x0000 }, + { 0x8702, 0xf824, 0x2000 }, + { 0x0702, 0xf823, 0x0000 }, + { 0x0702, 0xf825, 0x0000 }, + { 0x8702, 0xf82e, 0x4000 }, + { 0x8702, 0xf82a, 0x3000 }, + { 0x8702, 0xf828, 0x2000 }, + { 0x0702, 0xf827, 0x0000 }, + { 0x0702, 0xf829, 0x0000 }, + { 0x8702, 0xf82c, 0x2000 }, + { 0x0702, 0xf82b, 0x0000 }, + { 0x0702, 0xf82d, 0x0000 }, + { 0x8702, 0xf832, 0x3000 }, + { 0x8702, 0xf830, 0x2000 }, + { 0x0702, 0xf82f, 0x0000 }, + { 0x0702, 0xf831, 0x0000 }, + { 0x8702, 0xf834, 0x2000 }, + { 0x0702, 0xf833, 0x0000 }, + { 0x0702, 0xf835, 0x0000 }, + { 0x8702, 0xf856, 0x6000 }, + { 0x8702, 0xf846, 0x5000 }, + { 0x8702, 0xf83e, 0x4000 }, + { 0x8702, 0xf83a, 0x3000 }, + { 0x8702, 0xf838, 0x2000 }, + { 0x0702, 0xf837, 0x0000 }, + { 0x0702, 0xf839, 0x0000 }, + { 0x8702, 0xf83c, 0x2000 }, + { 0x0702, 0xf83b, 0x0000 }, + { 0x0702, 0xf83d, 0x0000 }, + { 0x8702, 0xf842, 0x3000 }, + { 0x8702, 0xf840, 0x2000 }, + { 0x0702, 0xf83f, 0x0000 }, + { 0x0702, 0xf841, 0x0000 }, + { 0x8702, 0xf844, 0x2000 }, + { 0x0702, 0xf843, 0x0000 }, + { 0x0702, 0xf845, 0x0000 }, + { 0x8702, 0xf84e, 0x4000 }, + { 0x8702, 0xf84a, 0x3000 }, + { 0x8702, 0xf848, 0x2000 }, + { 0x0702, 0xf847, 0x0000 }, + { 0x0702, 0xf849, 0x0000 }, + { 0x8702, 0xf84c, 0x2000 }, + { 0x0702, 0xf84b, 0x0000 }, + { 0x0702, 0xf84d, 0x0000 }, + { 0x8702, 0xf852, 0x3000 }, + { 0x8702, 0xf850, 0x2000 }, + { 0x0702, 0xf84f, 0x0000 }, + { 0x0702, 0xf851, 0x0000 }, + { 0x8702, 0xf854, 0x2000 }, + { 0x0702, 0xf853, 0x0000 }, + { 0x0702, 0xf855, 0x0000 }, + { 0x8702, 0xf866, 0x5000 }, + { 0x8702, 0xf85e, 0x4000 }, + { 0x8702, 0xf85a, 0x3000 }, + { 0x8702, 0xf858, 0x2000 }, + { 0x0702, 0xf857, 0x0000 }, + { 0x0702, 0xf859, 0x0000 }, + { 0x8702, 0xf85c, 0x2000 }, + { 0x0702, 0xf85b, 0x0000 }, + { 0x0702, 0xf85d, 0x0000 }, + { 0x8702, 0xf862, 0x3000 }, + { 0x8702, 0xf860, 0x2000 }, + { 0x0702, 0xf85f, 0x0000 }, + { 0x0702, 0xf861, 0x0000 }, + { 0x8702, 0xf864, 0x2000 }, + { 0x0702, 0xf863, 0x0000 }, + { 0x0702, 0xf865, 0x0000 }, + { 0x8702, 0xf86e, 0x4000 }, + { 0x8702, 0xf86a, 0x3000 }, + { 0x8702, 0xf868, 0x2000 }, + { 0x0702, 0xf867, 0x0000 }, + { 0x0702, 0xf869, 0x0000 }, + { 0x8702, 0xf86c, 0x2000 }, + { 0x0702, 0xf86b, 0x0000 }, + { 0x0702, 0xf86d, 0x0000 }, + { 0x8702, 0xf872, 0x3000 }, + { 0x8702, 0xf870, 0x2000 }, + { 0x0702, 0xf86f, 0x0000 }, + { 0x0702, 0xf871, 0x0000 }, + { 0x8702, 0xf874, 0x2000 }, + { 0x0702, 0xf873, 0x0000 }, + { 0x0702, 0xf875, 0x0000 }, + { 0x8702, 0xf976, 0x9000 }, + { 0x8702, 0xf8f6, 0x8000 }, + { 0x8702, 0xf8b6, 0x7000 }, + { 0x8702, 0xf896, 0x6000 }, + { 0x8702, 0xf886, 0x5000 }, + { 0x8702, 0xf87e, 0x4000 }, + { 0x8702, 0xf87a, 0x3000 }, + { 0x8702, 0xf878, 0x2000 }, + { 0x0702, 0xf877, 0x0000 }, + { 0x0702, 0xf879, 0x0000 }, + { 0x8702, 0xf87c, 0x2000 }, + { 0x0702, 0xf87b, 0x0000 }, + { 0x0702, 0xf87d, 0x0000 }, + { 0x8702, 0xf882, 0x3000 }, + { 0x8702, 0xf880, 0x2000 }, + { 0x0702, 0xf87f, 0x0000 }, + { 0x0702, 0xf881, 0x0000 }, + { 0x8702, 0xf884, 0x2000 }, + { 0x0702, 0xf883, 0x0000 }, + { 0x0702, 0xf885, 0x0000 }, + { 0x8702, 0xf88e, 0x4000 }, + { 0x8702, 0xf88a, 0x3000 }, + { 0x8702, 0xf888, 0x2000 }, + { 0x0702, 0xf887, 0x0000 }, + { 0x0702, 0xf889, 0x0000 }, + { 0x8702, 0xf88c, 0x2000 }, + { 0x0702, 0xf88b, 0x0000 }, + { 0x0702, 0xf88d, 0x0000 }, + { 0x8702, 0xf892, 0x3000 }, + { 0x8702, 0xf890, 0x2000 }, + { 0x0702, 0xf88f, 0x0000 }, + { 0x0702, 0xf891, 0x0000 }, + { 0x8702, 0xf894, 0x2000 }, + { 0x0702, 0xf893, 0x0000 }, + { 0x0702, 0xf895, 0x0000 }, + { 0x8702, 0xf8a6, 0x5000 }, + { 0x8702, 0xf89e, 0x4000 }, + { 0x8702, 0xf89a, 0x3000 }, + { 0x8702, 0xf898, 0x2000 }, + { 0x0702, 0xf897, 0x0000 }, + { 0x0702, 0xf899, 0x0000 }, + { 0x8702, 0xf89c, 0x2000 }, + { 0x0702, 0xf89b, 0x0000 }, + { 0x0702, 0xf89d, 0x0000 }, + { 0x8702, 0xf8a2, 0x3000 }, + { 0x8702, 0xf8a0, 0x2000 }, + { 0x0702, 0xf89f, 0x0000 }, + { 0x0702, 0xf8a1, 0x0000 }, + { 0x8702, 0xf8a4, 0x2000 }, + { 0x0702, 0xf8a3, 0x0000 }, + { 0x0702, 0xf8a5, 0x0000 }, + { 0x8702, 0xf8ae, 0x4000 }, + { 0x8702, 0xf8aa, 0x3000 }, + { 0x8702, 0xf8a8, 0x2000 }, + { 0x0702, 0xf8a7, 0x0000 }, + { 0x0702, 0xf8a9, 0x0000 }, + { 0x8702, 0xf8ac, 0x2000 }, + { 0x0702, 0xf8ab, 0x0000 }, + { 0x0702, 0xf8ad, 0x0000 }, + { 0x8702, 0xf8b2, 0x3000 }, + { 0x8702, 0xf8b0, 0x2000 }, + { 0x0702, 0xf8af, 0x0000 }, + { 0x0702, 0xf8b1, 0x0000 }, + { 0x8702, 0xf8b4, 0x2000 }, + { 0x0702, 0xf8b3, 0x0000 }, + { 0x0702, 0xf8b5, 0x0000 }, + { 0x8702, 0xf8d6, 0x6000 }, + { 0x8702, 0xf8c6, 0x5000 }, + { 0x8702, 0xf8be, 0x4000 }, + { 0x8702, 0xf8ba, 0x3000 }, + { 0x8702, 0xf8b8, 0x2000 }, + { 0x0702, 0xf8b7, 0x0000 }, + { 0x0702, 0xf8b9, 0x0000 }, + { 0x8702, 0xf8bc, 0x2000 }, + { 0x0702, 0xf8bb, 0x0000 }, + { 0x0702, 0xf8bd, 0x0000 }, + { 0x8702, 0xf8c2, 0x3000 }, + { 0x8702, 0xf8c0, 0x2000 }, + { 0x0702, 0xf8bf, 0x0000 }, + { 0x0702, 0xf8c1, 0x0000 }, + { 0x8702, 0xf8c4, 0x2000 }, + { 0x0702, 0xf8c3, 0x0000 }, + { 0x0702, 0xf8c5, 0x0000 }, + { 0x8702, 0xf8ce, 0x4000 }, + { 0x8702, 0xf8ca, 0x3000 }, + { 0x8702, 0xf8c8, 0x2000 }, + { 0x0702, 0xf8c7, 0x0000 }, + { 0x0702, 0xf8c9, 0x0000 }, + { 0x8702, 0xf8cc, 0x2000 }, + { 0x0702, 0xf8cb, 0x0000 }, + { 0x0702, 0xf8cd, 0x0000 }, + { 0x8702, 0xf8d2, 0x3000 }, + { 0x8702, 0xf8d0, 0x2000 }, + { 0x0702, 0xf8cf, 0x0000 }, + { 0x0702, 0xf8d1, 0x0000 }, + { 0x8702, 0xf8d4, 0x2000 }, + { 0x0702, 0xf8d3, 0x0000 }, + { 0x0702, 0xf8d5, 0x0000 }, + { 0x8702, 0xf8e6, 0x5000 }, + { 0x8702, 0xf8de, 0x4000 }, + { 0x8702, 0xf8da, 0x3000 }, + { 0x8702, 0xf8d8, 0x2000 }, + { 0x0702, 0xf8d7, 0x0000 }, + { 0x0702, 0xf8d9, 0x0000 }, + { 0x8702, 0xf8dc, 0x2000 }, + { 0x0702, 0xf8db, 0x0000 }, + { 0x0702, 0xf8dd, 0x0000 }, + { 0x8702, 0xf8e2, 0x3000 }, + { 0x8702, 0xf8e0, 0x2000 }, + { 0x0702, 0xf8df, 0x0000 }, + { 0x0702, 0xf8e1, 0x0000 }, + { 0x8702, 0xf8e4, 0x2000 }, + { 0x0702, 0xf8e3, 0x0000 }, + { 0x0702, 0xf8e5, 0x0000 }, + { 0x8702, 0xf8ee, 0x4000 }, + { 0x8702, 0xf8ea, 0x3000 }, + { 0x8702, 0xf8e8, 0x2000 }, + { 0x0702, 0xf8e7, 0x0000 }, + { 0x0702, 0xf8e9, 0x0000 }, + { 0x8702, 0xf8ec, 0x2000 }, + { 0x0702, 0xf8eb, 0x0000 }, + { 0x0702, 0xf8ed, 0x0000 }, + { 0x8702, 0xf8f2, 0x3000 }, + { 0x8702, 0xf8f0, 0x2000 }, + { 0x0702, 0xf8ef, 0x0000 }, + { 0x0702, 0xf8f1, 0x0000 }, + { 0x8702, 0xf8f4, 0x2000 }, + { 0x0702, 0xf8f3, 0x0000 }, + { 0x0702, 0xf8f5, 0x0000 }, + { 0x8702, 0xf936, 0x7000 }, + { 0x8702, 0xf916, 0x6000 }, + { 0x8702, 0xf906, 0x5000 }, + { 0x8702, 0xf8fe, 0x4000 }, + { 0x8702, 0xf8fa, 0x3000 }, + { 0x8702, 0xf8f8, 0x2000 }, + { 0x0702, 0xf8f7, 0x0000 }, + { 0x0702, 0xf8f9, 0x0000 }, + { 0x8702, 0xf8fc, 0x2000 }, + { 0x0702, 0xf8fb, 0x0000 }, + { 0x0702, 0xf8fd, 0x0000 }, + { 0x8702, 0xf902, 0x3000 }, + { 0x8702, 0xf900, 0x2000 }, + { 0x0702, 0xf8ff, 0x0000 }, + { 0x0702, 0xf901, 0x0000 }, + { 0x8702, 0xf904, 0x2000 }, + { 0x0702, 0xf903, 0x0000 }, + { 0x0702, 0xf905, 0x0000 }, + { 0x8702, 0xf90e, 0x4000 }, + { 0x8702, 0xf90a, 0x3000 }, + { 0x8702, 0xf908, 0x2000 }, + { 0x0702, 0xf907, 0x0000 }, + { 0x0702, 0xf909, 0x0000 }, + { 0x8702, 0xf90c, 0x2000 }, + { 0x0702, 0xf90b, 0x0000 }, + { 0x0702, 0xf90d, 0x0000 }, + { 0x8702, 0xf912, 0x3000 }, + { 0x8702, 0xf910, 0x2000 }, + { 0x0702, 0xf90f, 0x0000 }, + { 0x0702, 0xf911, 0x0000 }, + { 0x8702, 0xf914, 0x2000 }, + { 0x0702, 0xf913, 0x0000 }, + { 0x0702, 0xf915, 0x0000 }, + { 0x8702, 0xf926, 0x5000 }, + { 0x8702, 0xf91e, 0x4000 }, + { 0x8702, 0xf91a, 0x3000 }, + { 0x8702, 0xf918, 0x2000 }, + { 0x0702, 0xf917, 0x0000 }, + { 0x0702, 0xf919, 0x0000 }, + { 0x8702, 0xf91c, 0x2000 }, + { 0x0702, 0xf91b, 0x0000 }, + { 0x0702, 0xf91d, 0x0000 }, + { 0x8702, 0xf922, 0x3000 }, + { 0x8702, 0xf920, 0x2000 }, + { 0x0702, 0xf91f, 0x0000 }, + { 0x0702, 0xf921, 0x0000 }, + { 0x8702, 0xf924, 0x2000 }, + { 0x0702, 0xf923, 0x0000 }, + { 0x0702, 0xf925, 0x0000 }, + { 0x8702, 0xf92e, 0x4000 }, + { 0x8702, 0xf92a, 0x3000 }, + { 0x8702, 0xf928, 0x2000 }, + { 0x0702, 0xf927, 0x0000 }, + { 0x0702, 0xf929, 0x0000 }, + { 0x8702, 0xf92c, 0x2000 }, + { 0x0702, 0xf92b, 0x0000 }, + { 0x0702, 0xf92d, 0x0000 }, + { 0x8702, 0xf932, 0x3000 }, + { 0x8702, 0xf930, 0x2000 }, + { 0x0702, 0xf92f, 0x0000 }, + { 0x0702, 0xf931, 0x0000 }, + { 0x8702, 0xf934, 0x2000 }, + { 0x0702, 0xf933, 0x0000 }, + { 0x0702, 0xf935, 0x0000 }, + { 0x8702, 0xf956, 0x6000 }, + { 0x8702, 0xf946, 0x5000 }, + { 0x8702, 0xf93e, 0x4000 }, + { 0x8702, 0xf93a, 0x3000 }, + { 0x8702, 0xf938, 0x2000 }, + { 0x0702, 0xf937, 0x0000 }, + { 0x0702, 0xf939, 0x0000 }, + { 0x8702, 0xf93c, 0x2000 }, + { 0x0702, 0xf93b, 0x0000 }, + { 0x0702, 0xf93d, 0x0000 }, + { 0x8702, 0xf942, 0x3000 }, + { 0x8702, 0xf940, 0x2000 }, + { 0x0702, 0xf93f, 0x0000 }, + { 0x0702, 0xf941, 0x0000 }, + { 0x8702, 0xf944, 0x2000 }, + { 0x0702, 0xf943, 0x0000 }, + { 0x0702, 0xf945, 0x0000 }, + { 0x8702, 0xf94e, 0x4000 }, + { 0x8702, 0xf94a, 0x3000 }, + { 0x8702, 0xf948, 0x2000 }, + { 0x0702, 0xf947, 0x0000 }, + { 0x0702, 0xf949, 0x0000 }, + { 0x8702, 0xf94c, 0x2000 }, + { 0x0702, 0xf94b, 0x0000 }, + { 0x0702, 0xf94d, 0x0000 }, + { 0x8702, 0xf952, 0x3000 }, + { 0x8702, 0xf950, 0x2000 }, + { 0x0702, 0xf94f, 0x0000 }, + { 0x0702, 0xf951, 0x0000 }, + { 0x8702, 0xf954, 0x2000 }, + { 0x0702, 0xf953, 0x0000 }, + { 0x0702, 0xf955, 0x0000 }, + { 0x8702, 0xf966, 0x5000 }, + { 0x8702, 0xf95e, 0x4000 }, + { 0x8702, 0xf95a, 0x3000 }, + { 0x8702, 0xf958, 0x2000 }, + { 0x0702, 0xf957, 0x0000 }, + { 0x0702, 0xf959, 0x0000 }, + { 0x8702, 0xf95c, 0x2000 }, + { 0x0702, 0xf95b, 0x0000 }, + { 0x0702, 0xf95d, 0x0000 }, + { 0x8702, 0xf962, 0x3000 }, + { 0x8702, 0xf960, 0x2000 }, + { 0x0702, 0xf95f, 0x0000 }, + { 0x0702, 0xf961, 0x0000 }, + { 0x8702, 0xf964, 0x2000 }, + { 0x0702, 0xf963, 0x0000 }, + { 0x0702, 0xf965, 0x0000 }, + { 0x8702, 0xf96e, 0x4000 }, + { 0x8702, 0xf96a, 0x3000 }, + { 0x8702, 0xf968, 0x2000 }, + { 0x0702, 0xf967, 0x0000 }, + { 0x0702, 0xf969, 0x0000 }, + { 0x8702, 0xf96c, 0x2000 }, + { 0x0702, 0xf96b, 0x0000 }, + { 0x0702, 0xf96d, 0x0000 }, + { 0x8702, 0xf972, 0x3000 }, + { 0x8702, 0xf970, 0x2000 }, + { 0x0702, 0xf96f, 0x0000 }, + { 0x0702, 0xf971, 0x0000 }, + { 0x8702, 0xf974, 0x2000 }, + { 0x0702, 0xf973, 0x0000 }, + { 0x0702, 0xf975, 0x0000 }, + { 0x810e, 0x0077, 0x9000 }, + { 0x8702, 0xf9f6, 0x8000 }, + { 0x8702, 0xf9b6, 0x7000 }, + { 0x8702, 0xf996, 0x6000 }, + { 0x8702, 0xf986, 0x5000 }, + { 0x8702, 0xf97e, 0x4000 }, + { 0x8702, 0xf97a, 0x3000 }, + { 0x8702, 0xf978, 0x2000 }, + { 0x0702, 0xf977, 0x0000 }, + { 0x0702, 0xf979, 0x0000 }, + { 0x8702, 0xf97c, 0x2000 }, + { 0x0702, 0xf97b, 0x0000 }, + { 0x0702, 0xf97d, 0x0000 }, + { 0x8702, 0xf982, 0x3000 }, + { 0x8702, 0xf980, 0x2000 }, + { 0x0702, 0xf97f, 0x0000 }, + { 0x0702, 0xf981, 0x0000 }, + { 0x8702, 0xf984, 0x2000 }, + { 0x0702, 0xf983, 0x0000 }, + { 0x0702, 0xf985, 0x0000 }, + { 0x8702, 0xf98e, 0x4000 }, + { 0x8702, 0xf98a, 0x3000 }, + { 0x8702, 0xf988, 0x2000 }, + { 0x0702, 0xf987, 0x0000 }, + { 0x0702, 0xf989, 0x0000 }, + { 0x8702, 0xf98c, 0x2000 }, + { 0x0702, 0xf98b, 0x0000 }, + { 0x0702, 0xf98d, 0x0000 }, + { 0x8702, 0xf992, 0x3000 }, + { 0x8702, 0xf990, 0x2000 }, + { 0x0702, 0xf98f, 0x0000 }, + { 0x0702, 0xf991, 0x0000 }, + { 0x8702, 0xf994, 0x2000 }, + { 0x0702, 0xf993, 0x0000 }, + { 0x0702, 0xf995, 0x0000 }, + { 0x8702, 0xf9a6, 0x5000 }, + { 0x8702, 0xf99e, 0x4000 }, + { 0x8702, 0xf99a, 0x3000 }, + { 0x8702, 0xf998, 0x2000 }, + { 0x0702, 0xf997, 0x0000 }, + { 0x0702, 0xf999, 0x0000 }, + { 0x8702, 0xf99c, 0x2000 }, + { 0x0702, 0xf99b, 0x0000 }, + { 0x0702, 0xf99d, 0x0000 }, + { 0x8702, 0xf9a2, 0x3000 }, + { 0x8702, 0xf9a0, 0x2000 }, + { 0x0702, 0xf99f, 0x0000 }, + { 0x0702, 0xf9a1, 0x0000 }, + { 0x8702, 0xf9a4, 0x2000 }, + { 0x0702, 0xf9a3, 0x0000 }, + { 0x0702, 0xf9a5, 0x0000 }, + { 0x8702, 0xf9ae, 0x4000 }, + { 0x8702, 0xf9aa, 0x3000 }, + { 0x8702, 0xf9a8, 0x2000 }, + { 0x0702, 0xf9a7, 0x0000 }, + { 0x0702, 0xf9a9, 0x0000 }, + { 0x8702, 0xf9ac, 0x2000 }, + { 0x0702, 0xf9ab, 0x0000 }, + { 0x0702, 0xf9ad, 0x0000 }, + { 0x8702, 0xf9b2, 0x3000 }, + { 0x8702, 0xf9b0, 0x2000 }, + { 0x0702, 0xf9af, 0x0000 }, + { 0x0702, 0xf9b1, 0x0000 }, + { 0x8702, 0xf9b4, 0x2000 }, + { 0x0702, 0xf9b3, 0x0000 }, + { 0x0702, 0xf9b5, 0x0000 }, + { 0x8702, 0xf9d6, 0x6000 }, + { 0x8702, 0xf9c6, 0x5000 }, + { 0x8702, 0xf9be, 0x4000 }, + { 0x8702, 0xf9ba, 0x3000 }, + { 0x8702, 0xf9b8, 0x2000 }, + { 0x0702, 0xf9b7, 0x0000 }, + { 0x0702, 0xf9b9, 0x0000 }, + { 0x8702, 0xf9bc, 0x2000 }, + { 0x0702, 0xf9bb, 0x0000 }, + { 0x0702, 0xf9bd, 0x0000 }, + { 0x8702, 0xf9c2, 0x3000 }, + { 0x8702, 0xf9c0, 0x2000 }, + { 0x0702, 0xf9bf, 0x0000 }, + { 0x0702, 0xf9c1, 0x0000 }, + { 0x8702, 0xf9c4, 0x2000 }, + { 0x0702, 0xf9c3, 0x0000 }, + { 0x0702, 0xf9c5, 0x0000 }, + { 0x8702, 0xf9ce, 0x4000 }, + { 0x8702, 0xf9ca, 0x3000 }, + { 0x8702, 0xf9c8, 0x2000 }, + { 0x0702, 0xf9c7, 0x0000 }, + { 0x0702, 0xf9c9, 0x0000 }, + { 0x8702, 0xf9cc, 0x2000 }, + { 0x0702, 0xf9cb, 0x0000 }, + { 0x0702, 0xf9cd, 0x0000 }, + { 0x8702, 0xf9d2, 0x3000 }, + { 0x8702, 0xf9d0, 0x2000 }, + { 0x0702, 0xf9cf, 0x0000 }, + { 0x0702, 0xf9d1, 0x0000 }, + { 0x8702, 0xf9d4, 0x2000 }, + { 0x0702, 0xf9d3, 0x0000 }, + { 0x0702, 0xf9d5, 0x0000 }, + { 0x8702, 0xf9e6, 0x5000 }, + { 0x8702, 0xf9de, 0x4000 }, + { 0x8702, 0xf9da, 0x3000 }, + { 0x8702, 0xf9d8, 0x2000 }, + { 0x0702, 0xf9d7, 0x0000 }, + { 0x0702, 0xf9d9, 0x0000 }, + { 0x8702, 0xf9dc, 0x2000 }, + { 0x0702, 0xf9db, 0x0000 }, + { 0x0702, 0xf9dd, 0x0000 }, + { 0x8702, 0xf9e2, 0x3000 }, + { 0x8702, 0xf9e0, 0x2000 }, + { 0x0702, 0xf9df, 0x0000 }, + { 0x0702, 0xf9e1, 0x0000 }, + { 0x8702, 0xf9e4, 0x2000 }, + { 0x0702, 0xf9e3, 0x0000 }, + { 0x0702, 0xf9e5, 0x0000 }, + { 0x8702, 0xf9ee, 0x4000 }, + { 0x8702, 0xf9ea, 0x3000 }, + { 0x8702, 0xf9e8, 0x2000 }, + { 0x0702, 0xf9e7, 0x0000 }, + { 0x0702, 0xf9e9, 0x0000 }, + { 0x8702, 0xf9ec, 0x2000 }, + { 0x0702, 0xf9eb, 0x0000 }, + { 0x0702, 0xf9ed, 0x0000 }, + { 0x8702, 0xf9f2, 0x3000 }, + { 0x8702, 0xf9f0, 0x2000 }, + { 0x0702, 0xf9ef, 0x0000 }, + { 0x0702, 0xf9f1, 0x0000 }, + { 0x8702, 0xf9f4, 0x2000 }, + { 0x0702, 0xf9f3, 0x0000 }, + { 0x0702, 0xf9f5, 0x0000 }, + { 0x810e, 0x0037, 0x7000 }, + { 0x8702, 0xfa16, 0x6000 }, + { 0x8702, 0xfa06, 0x5000 }, + { 0x8702, 0xf9fe, 0x4000 }, + { 0x8702, 0xf9fa, 0x3000 }, + { 0x8702, 0xf9f8, 0x2000 }, + { 0x0702, 0xf9f7, 0x0000 }, + { 0x0702, 0xf9f9, 0x0000 }, + { 0x8702, 0xf9fc, 0x2000 }, + { 0x0702, 0xf9fb, 0x0000 }, + { 0x0702, 0xf9fd, 0x0000 }, + { 0x8702, 0xfa02, 0x3000 }, + { 0x8702, 0xfa00, 0x2000 }, + { 0x0702, 0xf9ff, 0x0000 }, + { 0x0702, 0xfa01, 0x0000 }, + { 0x8702, 0xfa04, 0x2000 }, + { 0x0702, 0xfa03, 0x0000 }, + { 0x0702, 0xfa05, 0x0000 }, + { 0x8702, 0xfa0e, 0x4000 }, + { 0x8702, 0xfa0a, 0x3000 }, + { 0x8702, 0xfa08, 0x2000 }, + { 0x0702, 0xfa07, 0x0000 }, + { 0x0702, 0xfa09, 0x0000 }, + { 0x8702, 0xfa0c, 0x2000 }, + { 0x0702, 0xfa0b, 0x0000 }, + { 0x0702, 0xfa0d, 0x0000 }, + { 0x8702, 0xfa12, 0x3000 }, + { 0x8702, 0xfa10, 0x2000 }, + { 0x0702, 0xfa0f, 0x0000 }, + { 0x0702, 0xfa11, 0x0000 }, + { 0x8702, 0xfa14, 0x2000 }, + { 0x0702, 0xfa13, 0x0000 }, + { 0x0702, 0xfa15, 0x0000 }, + { 0x810e, 0x0027, 0x5000 }, + { 0x810e, 0x0001, 0x4000 }, + { 0x8702, 0xfa1a, 0x3000 }, + { 0x8702, 0xfa18, 0x2000 }, + { 0x0702, 0xfa17, 0x0000 }, + { 0x0702, 0xfa19, 0x0000 }, + { 0x8702, 0xfa1c, 0x2000 }, + { 0x0702, 0xfa1b, 0x0000 }, + { 0x0702, 0xfa1d, 0x0000 }, + { 0x810e, 0x0023, 0x3000 }, + { 0x810e, 0x0021, 0x2000 }, + { 0x010e, 0x0020, 0x0000 }, + { 0x010e, 0x0022, 0x0000 }, + { 0x810e, 0x0025, 0x2000 }, + { 0x010e, 0x0024, 0x0000 }, + { 0x010e, 0x0026, 0x0000 }, + { 0x810e, 0x002f, 0x4000 }, + { 0x810e, 0x002b, 0x3000 }, + { 0x810e, 0x0029, 0x2000 }, + { 0x010e, 0x0028, 0x0000 }, + { 0x010e, 0x002a, 0x0000 }, + { 0x810e, 0x002d, 0x2000 }, + { 0x010e, 0x002c, 0x0000 }, + { 0x010e, 0x002e, 0x0000 }, + { 0x810e, 0x0033, 0x3000 }, + { 0x810e, 0x0031, 0x2000 }, + { 0x010e, 0x0030, 0x0000 }, + { 0x010e, 0x0032, 0x0000 }, + { 0x810e, 0x0035, 0x2000 }, + { 0x010e, 0x0034, 0x0000 }, + { 0x010e, 0x0036, 0x0000 }, + { 0x810e, 0x0057, 0x6000 }, + { 0x810e, 0x0047, 0x5000 }, + { 0x810e, 0x003f, 0x4000 }, + { 0x810e, 0x003b, 0x3000 }, + { 0x810e, 0x0039, 0x2000 }, + { 0x010e, 0x0038, 0x0000 }, + { 0x010e, 0x003a, 0x0000 }, + { 0x810e, 0x003d, 0x2000 }, + { 0x010e, 0x003c, 0x0000 }, + { 0x010e, 0x003e, 0x0000 }, + { 0x810e, 0x0043, 0x3000 }, + { 0x810e, 0x0041, 0x2000 }, + { 0x010e, 0x0040, 0x0000 }, + { 0x010e, 0x0042, 0x0000 }, + { 0x810e, 0x0045, 0x2000 }, + { 0x010e, 0x0044, 0x0000 }, + { 0x010e, 0x0046, 0x0000 }, + { 0x810e, 0x004f, 0x4000 }, + { 0x810e, 0x004b, 0x3000 }, + { 0x810e, 0x0049, 0x2000 }, + { 0x010e, 0x0048, 0x0000 }, + { 0x010e, 0x004a, 0x0000 }, + { 0x810e, 0x004d, 0x2000 }, + { 0x010e, 0x004c, 0x0000 }, + { 0x010e, 0x004e, 0x0000 }, + { 0x810e, 0x0053, 0x3000 }, + { 0x810e, 0x0051, 0x2000 }, + { 0x010e, 0x0050, 0x0000 }, + { 0x010e, 0x0052, 0x0000 }, + { 0x810e, 0x0055, 0x2000 }, + { 0x010e, 0x0054, 0x0000 }, + { 0x010e, 0x0056, 0x0000 }, + { 0x810e, 0x0067, 0x5000 }, + { 0x810e, 0x005f, 0x4000 }, + { 0x810e, 0x005b, 0x3000 }, + { 0x810e, 0x0059, 0x2000 }, + { 0x010e, 0x0058, 0x0000 }, + { 0x010e, 0x005a, 0x0000 }, + { 0x810e, 0x005d, 0x2000 }, + { 0x010e, 0x005c, 0x0000 }, + { 0x010e, 0x005e, 0x0000 }, + { 0x810e, 0x0063, 0x3000 }, + { 0x810e, 0x0061, 0x2000 }, + { 0x010e, 0x0060, 0x0000 }, + { 0x010e, 0x0062, 0x0000 }, + { 0x810e, 0x0065, 0x2000 }, + { 0x010e, 0x0064, 0x0000 }, + { 0x010e, 0x0066, 0x0000 }, + { 0x810e, 0x006f, 0x4000 }, + { 0x810e, 0x006b, 0x3000 }, + { 0x810e, 0x0069, 0x2000 }, + { 0x010e, 0x0068, 0x0000 }, + { 0x010e, 0x006a, 0x0000 }, + { 0x810e, 0x006d, 0x2000 }, + { 0x010e, 0x006c, 0x0000 }, + { 0x010e, 0x006e, 0x0000 }, + { 0x810e, 0x0073, 0x3000 }, + { 0x810e, 0x0071, 0x2000 }, + { 0x010e, 0x0070, 0x0000 }, + { 0x010e, 0x0072, 0x0000 }, + { 0x810e, 0x0075, 0x2000 }, + { 0x010e, 0x0074, 0x0000 }, + { 0x010e, 0x0076, 0x0000 }, + { 0x8c0e, 0x0177, 0x8000 }, + { 0x8c0e, 0x0137, 0x7000 }, + { 0x8c0e, 0x0117, 0x6000 }, + { 0x8c0e, 0x0107, 0x5000 }, + { 0x810e, 0x007f, 0x4000 }, + { 0x810e, 0x007b, 0x3000 }, + { 0x810e, 0x0079, 0x2000 }, + { 0x010e, 0x0078, 0x0000 }, + { 0x010e, 0x007a, 0x0000 }, + { 0x810e, 0x007d, 0x2000 }, + { 0x010e, 0x007c, 0x0000 }, + { 0x010e, 0x007e, 0x0000 }, + { 0x8c0e, 0x0103, 0x3000 }, + { 0x8c0e, 0x0101, 0x2000 }, + { 0x0c0e, 0x0100, 0x0000 }, + { 0x0c0e, 0x0102, 0x0000 }, + { 0x8c0e, 0x0105, 0x2000 }, + { 0x0c0e, 0x0104, 0x0000 }, + { 0x0c0e, 0x0106, 0x0000 }, + { 0x8c0e, 0x010f, 0x4000 }, + { 0x8c0e, 0x010b, 0x3000 }, + { 0x8c0e, 0x0109, 0x2000 }, + { 0x0c0e, 0x0108, 0x0000 }, + { 0x0c0e, 0x010a, 0x0000 }, + { 0x8c0e, 0x010d, 0x2000 }, + { 0x0c0e, 0x010c, 0x0000 }, + { 0x0c0e, 0x010e, 0x0000 }, + { 0x8c0e, 0x0113, 0x3000 }, + { 0x8c0e, 0x0111, 0x2000 }, + { 0x0c0e, 0x0110, 0x0000 }, + { 0x0c0e, 0x0112, 0x0000 }, + { 0x8c0e, 0x0115, 0x2000 }, + { 0x0c0e, 0x0114, 0x0000 }, + { 0x0c0e, 0x0116, 0x0000 }, + { 0x8c0e, 0x0127, 0x5000 }, + { 0x8c0e, 0x011f, 0x4000 }, + { 0x8c0e, 0x011b, 0x3000 }, + { 0x8c0e, 0x0119, 0x2000 }, + { 0x0c0e, 0x0118, 0x0000 }, + { 0x0c0e, 0x011a, 0x0000 }, + { 0x8c0e, 0x011d, 0x2000 }, + { 0x0c0e, 0x011c, 0x0000 }, + { 0x0c0e, 0x011e, 0x0000 }, + { 0x8c0e, 0x0123, 0x3000 }, + { 0x8c0e, 0x0121, 0x2000 }, + { 0x0c0e, 0x0120, 0x0000 }, + { 0x0c0e, 0x0122, 0x0000 }, + { 0x8c0e, 0x0125, 0x2000 }, + { 0x0c0e, 0x0124, 0x0000 }, + { 0x0c0e, 0x0126, 0x0000 }, + { 0x8c0e, 0x012f, 0x4000 }, + { 0x8c0e, 0x012b, 0x3000 }, + { 0x8c0e, 0x0129, 0x2000 }, + { 0x0c0e, 0x0128, 0x0000 }, + { 0x0c0e, 0x012a, 0x0000 }, + { 0x8c0e, 0x012d, 0x2000 }, + { 0x0c0e, 0x012c, 0x0000 }, + { 0x0c0e, 0x012e, 0x0000 }, + { 0x8c0e, 0x0133, 0x3000 }, + { 0x8c0e, 0x0131, 0x2000 }, + { 0x0c0e, 0x0130, 0x0000 }, + { 0x0c0e, 0x0132, 0x0000 }, + { 0x8c0e, 0x0135, 0x2000 }, + { 0x0c0e, 0x0134, 0x0000 }, + { 0x0c0e, 0x0136, 0x0000 }, + { 0x8c0e, 0x0157, 0x6000 }, + { 0x8c0e, 0x0147, 0x5000 }, + { 0x8c0e, 0x013f, 0x4000 }, + { 0x8c0e, 0x013b, 0x3000 }, + { 0x8c0e, 0x0139, 0x2000 }, + { 0x0c0e, 0x0138, 0x0000 }, + { 0x0c0e, 0x013a, 0x0000 }, + { 0x8c0e, 0x013d, 0x2000 }, + { 0x0c0e, 0x013c, 0x0000 }, + { 0x0c0e, 0x013e, 0x0000 }, + { 0x8c0e, 0x0143, 0x3000 }, + { 0x8c0e, 0x0141, 0x2000 }, + { 0x0c0e, 0x0140, 0x0000 }, + { 0x0c0e, 0x0142, 0x0000 }, + { 0x8c0e, 0x0145, 0x2000 }, + { 0x0c0e, 0x0144, 0x0000 }, + { 0x0c0e, 0x0146, 0x0000 }, + { 0x8c0e, 0x014f, 0x4000 }, + { 0x8c0e, 0x014b, 0x3000 }, + { 0x8c0e, 0x0149, 0x2000 }, + { 0x0c0e, 0x0148, 0x0000 }, + { 0x0c0e, 0x014a, 0x0000 }, + { 0x8c0e, 0x014d, 0x2000 }, + { 0x0c0e, 0x014c, 0x0000 }, + { 0x0c0e, 0x014e, 0x0000 }, + { 0x8c0e, 0x0153, 0x3000 }, + { 0x8c0e, 0x0151, 0x2000 }, + { 0x0c0e, 0x0150, 0x0000 }, + { 0x0c0e, 0x0152, 0x0000 }, + { 0x8c0e, 0x0155, 0x2000 }, + { 0x0c0e, 0x0154, 0x0000 }, + { 0x0c0e, 0x0156, 0x0000 }, + { 0x8c0e, 0x0167, 0x5000 }, + { 0x8c0e, 0x015f, 0x4000 }, + { 0x8c0e, 0x015b, 0x3000 }, + { 0x8c0e, 0x0159, 0x2000 }, + { 0x0c0e, 0x0158, 0x0000 }, + { 0x0c0e, 0x015a, 0x0000 }, + { 0x8c0e, 0x015d, 0x2000 }, + { 0x0c0e, 0x015c, 0x0000 }, + { 0x0c0e, 0x015e, 0x0000 }, + { 0x8c0e, 0x0163, 0x3000 }, + { 0x8c0e, 0x0161, 0x2000 }, + { 0x0c0e, 0x0160, 0x0000 }, + { 0x0c0e, 0x0162, 0x0000 }, + { 0x8c0e, 0x0165, 0x2000 }, + { 0x0c0e, 0x0164, 0x0000 }, + { 0x0c0e, 0x0166, 0x0000 }, + { 0x8c0e, 0x016f, 0x4000 }, + { 0x8c0e, 0x016b, 0x3000 }, + { 0x8c0e, 0x0169, 0x2000 }, + { 0x0c0e, 0x0168, 0x0000 }, + { 0x0c0e, 0x016a, 0x0000 }, + { 0x8c0e, 0x016d, 0x2000 }, + { 0x0c0e, 0x016c, 0x0000 }, + { 0x0c0e, 0x016e, 0x0000 }, + { 0x8c0e, 0x0173, 0x3000 }, + { 0x8c0e, 0x0171, 0x2000 }, + { 0x0c0e, 0x0170, 0x0000 }, + { 0x0c0e, 0x0172, 0x0000 }, + { 0x8c0e, 0x0175, 0x2000 }, + { 0x0c0e, 0x0174, 0x0000 }, + { 0x0c0e, 0x0176, 0x0000 }, + { 0x8c0e, 0x01b7, 0x7000 }, + { 0x8c0e, 0x0197, 0x6000 }, + { 0x8c0e, 0x0187, 0x5000 }, + { 0x8c0e, 0x017f, 0x4000 }, + { 0x8c0e, 0x017b, 0x3000 }, + { 0x8c0e, 0x0179, 0x2000 }, + { 0x0c0e, 0x0178, 0x0000 }, + { 0x0c0e, 0x017a, 0x0000 }, + { 0x8c0e, 0x017d, 0x2000 }, + { 0x0c0e, 0x017c, 0x0000 }, + { 0x0c0e, 0x017e, 0x0000 }, + { 0x8c0e, 0x0183, 0x3000 }, + { 0x8c0e, 0x0181, 0x2000 }, + { 0x0c0e, 0x0180, 0x0000 }, + { 0x0c0e, 0x0182, 0x0000 }, + { 0x8c0e, 0x0185, 0x2000 }, + { 0x0c0e, 0x0184, 0x0000 }, + { 0x0c0e, 0x0186, 0x0000 }, + { 0x8c0e, 0x018f, 0x4000 }, + { 0x8c0e, 0x018b, 0x3000 }, + { 0x8c0e, 0x0189, 0x2000 }, + { 0x0c0e, 0x0188, 0x0000 }, + { 0x0c0e, 0x018a, 0x0000 }, + { 0x8c0e, 0x018d, 0x2000 }, + { 0x0c0e, 0x018c, 0x0000 }, + { 0x0c0e, 0x018e, 0x0000 }, + { 0x8c0e, 0x0193, 0x3000 }, + { 0x8c0e, 0x0191, 0x2000 }, + { 0x0c0e, 0x0190, 0x0000 }, + { 0x0c0e, 0x0192, 0x0000 }, + { 0x8c0e, 0x0195, 0x2000 }, + { 0x0c0e, 0x0194, 0x0000 }, + { 0x0c0e, 0x0196, 0x0000 }, + { 0x8c0e, 0x01a7, 0x5000 }, + { 0x8c0e, 0x019f, 0x4000 }, + { 0x8c0e, 0x019b, 0x3000 }, + { 0x8c0e, 0x0199, 0x2000 }, + { 0x0c0e, 0x0198, 0x0000 }, + { 0x0c0e, 0x019a, 0x0000 }, + { 0x8c0e, 0x019d, 0x2000 }, + { 0x0c0e, 0x019c, 0x0000 }, + { 0x0c0e, 0x019e, 0x0000 }, + { 0x8c0e, 0x01a3, 0x3000 }, + { 0x8c0e, 0x01a1, 0x2000 }, + { 0x0c0e, 0x01a0, 0x0000 }, + { 0x0c0e, 0x01a2, 0x0000 }, + { 0x8c0e, 0x01a5, 0x2000 }, + { 0x0c0e, 0x01a4, 0x0000 }, + { 0x0c0e, 0x01a6, 0x0000 }, + { 0x8c0e, 0x01af, 0x4000 }, + { 0x8c0e, 0x01ab, 0x3000 }, + { 0x8c0e, 0x01a9, 0x2000 }, + { 0x0c0e, 0x01a8, 0x0000 }, + { 0x0c0e, 0x01aa, 0x0000 }, + { 0x8c0e, 0x01ad, 0x2000 }, + { 0x0c0e, 0x01ac, 0x0000 }, + { 0x0c0e, 0x01ae, 0x0000 }, + { 0x8c0e, 0x01b3, 0x3000 }, + { 0x8c0e, 0x01b1, 0x2000 }, + { 0x0c0e, 0x01b0, 0x0000 }, + { 0x0c0e, 0x01b2, 0x0000 }, + { 0x8c0e, 0x01b5, 0x2000 }, + { 0x0c0e, 0x01b4, 0x0000 }, + { 0x0c0e, 0x01b6, 0x0000 }, + { 0x8c0e, 0x01d7, 0x6000 }, + { 0x8c0e, 0x01c7, 0x5000 }, + { 0x8c0e, 0x01bf, 0x4000 }, + { 0x8c0e, 0x01bb, 0x3000 }, + { 0x8c0e, 0x01b9, 0x2000 }, + { 0x0c0e, 0x01b8, 0x0000 }, + { 0x0c0e, 0x01ba, 0x0000 }, + { 0x8c0e, 0x01bd, 0x2000 }, + { 0x0c0e, 0x01bc, 0x0000 }, + { 0x0c0e, 0x01be, 0x0000 }, + { 0x8c0e, 0x01c3, 0x3000 }, + { 0x8c0e, 0x01c1, 0x2000 }, + { 0x0c0e, 0x01c0, 0x0000 }, + { 0x0c0e, 0x01c2, 0x0000 }, + { 0x8c0e, 0x01c5, 0x2000 }, + { 0x0c0e, 0x01c4, 0x0000 }, + { 0x0c0e, 0x01c6, 0x0000 }, + { 0x8c0e, 0x01cf, 0x4000 }, + { 0x8c0e, 0x01cb, 0x3000 }, + { 0x8c0e, 0x01c9, 0x2000 }, + { 0x0c0e, 0x01c8, 0x0000 }, + { 0x0c0e, 0x01ca, 0x0000 }, + { 0x8c0e, 0x01cd, 0x2000 }, + { 0x0c0e, 0x01cc, 0x0000 }, + { 0x0c0e, 0x01ce, 0x0000 }, + { 0x8c0e, 0x01d3, 0x3000 }, + { 0x8c0e, 0x01d1, 0x2000 }, + { 0x0c0e, 0x01d0, 0x0000 }, + { 0x0c0e, 0x01d2, 0x0000 }, + { 0x8c0e, 0x01d5, 0x2000 }, + { 0x0c0e, 0x01d4, 0x0000 }, + { 0x0c0e, 0x01d6, 0x0000 }, + { 0x8c0e, 0x01e7, 0x5000 }, + { 0x8c0e, 0x01df, 0x4000 }, + { 0x8c0e, 0x01db, 0x3000 }, + { 0x8c0e, 0x01d9, 0x2000 }, + { 0x0c0e, 0x01d8, 0x0000 }, + { 0x0c0e, 0x01da, 0x0000 }, + { 0x8c0e, 0x01dd, 0x2000 }, + { 0x0c0e, 0x01dc, 0x0000 }, + { 0x0c0e, 0x01de, 0x0000 }, + { 0x8c0e, 0x01e3, 0x3000 }, + { 0x8c0e, 0x01e1, 0x2000 }, + { 0x0c0e, 0x01e0, 0x0000 }, + { 0x0c0e, 0x01e2, 0x0000 }, + { 0x8c0e, 0x01e5, 0x2000 }, + { 0x0c0e, 0x01e4, 0x0000 }, + { 0x0c0e, 0x01e6, 0x0000 }, + { 0x8c0e, 0x01ef, 0x4000 }, + { 0x8c0e, 0x01eb, 0x3000 }, + { 0x8c0e, 0x01e9, 0x2000 }, + { 0x0c0e, 0x01e8, 0x0000 }, + { 0x0c0e, 0x01ea, 0x0000 }, + { 0x8c0e, 0x01ed, 0x2000 }, + { 0x0c0e, 0x01ec, 0x0000 }, + { 0x0c0e, 0x01ee, 0x0000 }, + { 0x830f, 0xfffd, 0x2000 }, + { 0x030f, 0x0000, 0x0000 }, + { 0x0310, 0x0000, 0x1000 }, + { 0x0310, 0xfffd, 0x0000 }, +}; diff --git a/trunk/srclib/pcre/ucptypetable.c b/trunk/srclib/pcre/ucptypetable.c new file mode 100644 index 0000000000..129529b5d6 --- /dev/null +++ b/trunk/srclib/pcre/ucptypetable.c @@ -0,0 +1,93 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* +This is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. See +the file Tech.Notes for some information on the internals. + +Written by: Philip Hazel + + Copyright (c) 1997-2004 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains a table for translating Unicode property names into +code values for the ucp_findchar function. It is in a separate module so that +it can be included both in the main pcre library, and into pcretest (for +printing out internals). */ + +typedef struct { + const char *name; + int value; +} ucp_type_table; + +static ucp_type_table utt[] = { + { "C", 128 + ucp_C }, + { "Cc", ucp_Cc }, + { "Cf", ucp_Cf }, + { "Cn", ucp_Cn }, + { "Co", ucp_Co }, + { "Cs", ucp_Cs }, + { "L", 128 + ucp_L }, + { "Ll", ucp_Ll }, + { "Lm", ucp_Lm }, + { "Lo", ucp_Lo }, + { "Lt", ucp_Lt }, + { "Lu", ucp_Lu }, + { "M", 128 + ucp_M }, + { "Mc", ucp_Mc }, + { "Me", ucp_Me }, + { "Mn", ucp_Mn }, + { "N", 128 + ucp_N }, + { "Nd", ucp_Nd }, + { "Nl", ucp_Nl }, + { "No", ucp_No }, + { "P", 128 + ucp_P }, + { "Pc", ucp_Pc }, + { "Pd", ucp_Pd }, + { "Pe", ucp_Pe }, + { "Pf", ucp_Pf }, + { "Pi", ucp_Pi }, + { "Po", ucp_Po }, + { "Ps", ucp_Ps }, + { "S", 128 + ucp_S }, + { "Sc", ucp_Sc }, + { "Sk", ucp_Sk }, + { "Sm", ucp_Sm }, + { "So", ucp_So }, + { "Z", 128 + ucp_Z }, + { "Zl", ucp_Zl }, + { "Zp", ucp_Zp }, + { "Zs", ucp_Zs } +}; + +/* End of ucptypetable.c */ diff --git a/trunk/support/.indent.pro b/trunk/support/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/support/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/support/Makefile.in b/trunk/support/Makefile.in new file mode 100644 index 0000000000..25dda638c1 --- /dev/null +++ b/trunk/support/Makefile.in @@ -0,0 +1,67 @@ +DISTCLEAN_TARGETS = apxs apachectl dbmmanage log_server_status \ + logresolve.pl phf_abuse_log.cgi split-logfile envvars-std + +CLEAN_TARGETS = suexec + +PROGRAMS = htpasswd htdigest rotatelogs logresolve ab checkgid htdbm htcacheclean +TARGETS = $(PROGRAMS) + +PROGRAM_LDADD = $(UTIL_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS) +PROGRAM_DEPENDENCIES = + +include $(top_builddir)/build/rules.mk + +install: + @test -d $(DESTDIR)$(bindir) || $(MKINSTALLDIRS) $(DESTDIR)$(bindir) + @test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir) + @test -d $(DESTDIR)$(libexecdir) || $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir) + @cp -p $(top_builddir)/server/httpd.exp $(DESTDIR)$(libexecdir) + @for i in apxs apachectl dbmmanage; do \ + if test -f "$(builddir)/$$i"; then \ + cp -p $$i $(DESTDIR)$(sbindir); \ + chmod 755 $(DESTDIR)$(sbindir)/$$i; \ + fi ; \ + done + @if test -f "$(builddir)/envvars-std"; then \ + cp -p envvars-std $(DESTDIR)$(sbindir); \ + if test ! -f $(DESTDIR)$(sbindir)/envvars; then \ + cp -p envvars-std $(DESTDIR)$(sbindir)/envvars ; \ + fi ; \ + fi + +htpasswd_OBJECTS = htpasswd.lo +htpasswd: $(htpasswd_OBJECTS) + $(LINK) $(htpasswd_LTFLAGS) $(htpasswd_OBJECTS) $(PROGRAM_LDADD) + +htdigest_OBJECTS = htdigest.lo +htdigest: $(htdigest_OBJECTS) + $(LINK) $(htdigest_LTFLAGS) $(htdigest_OBJECTS) $(PROGRAM_LDADD) + +rotatelogs_OBJECTS = rotatelogs.lo +rotatelogs: $(rotatelogs_OBJECTS) + $(LINK) $(rotatelogs_LTFLAGS) $(rotatelogs_OBJECTS) $(PROGRAM_LDADD) + +logresolve_OBJECTS = logresolve.lo +logresolve: $(logresolve_OBJECTS) + $(LINK) $(logresolve_LTFLAGS) $(logresolve_OBJECTS) $(PROGRAM_LDADD) + +htdbm_OBJECTS = htdbm.lo +htdbm: $(htdbm_OBJECTS) + $(LINK) $(htdbm_LTFLAGS) $(htdbm_OBJECTS) $(PROGRAM_LDADD) + +ab_OBJECTS = ab.lo +ab_LDADD = $(PROGRAM_LDADD) $(SSL_LIBS) +ab: $(ab_OBJECTS) + $(LINK) $(ab_LTFLAGS) $(ab_OBJECTS) $(ab_LDADD) + +checkgid_OBJECTS = checkgid.lo +checkgid: $(checkgid_OBJECTS) + $(LINK) $(checkgid_LTFLAGS) $(checkgid_OBJECTS) $(PROGRAM_LDADD) + +suexec_OBJECTS = suexec.lo +suexec: $(suexec_OBJECTS) + $(LINK) $(suexec_OBJECTS) + +htcacheclean_OBJECTS = htcacheclean.lo +htcacheclean: $(htcacheclean_OBJECTS) + $(LINK) $(htcacheclean_LTFLAGS) $(htcacheclean_OBJECTS) $(PROGRAM_LDADD) diff --git a/trunk/support/NWGNUab b/trunk/support/NWGNUab new file mode 100644 index 0000000000..9f94eebde8 --- /dev/null +++ b/trunk/support/NWGNUab @@ -0,0 +1,254 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(AP_WORK)/include \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = ab + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Benchmark Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = ab + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +#NLM_SCREEN_NAME = Apache Bench +NLM_SCREEN_NAME = DEFAULT + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/ab.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/ab.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUhtcacheclean b/trunk/support/NWGNUhtcacheclean new file mode 100644 index 0000000000..17d03d362a --- /dev/null +++ b/trunk/support/NWGNUhtcacheclean @@ -0,0 +1,252 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = htcacheclean + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) HT Disk Cache Cleanup Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = htcacheclean + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = DEFAULT + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/htcacheclean.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/htcacheclean.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUhtdbm b/trunk/support/NWGNUhtdbm new file mode 100644 index 0000000000..492d22924e --- /dev/null +++ b/trunk/support/NWGNUhtdbm @@ -0,0 +1,252 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = htdbm + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) HT Database Management Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = htdbm + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = htdbm Password Management + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/htdbm.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/htdbm.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUhtdigest b/trunk/support/NWGNUhtdigest new file mode 100644 index 0000000000..4fbdc040cc --- /dev/null +++ b/trunk/support/NWGNUhtdigest @@ -0,0 +1,252 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = htdigest + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) HT Digest Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = htdigest + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = Digest Password Management + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/htdigest.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/htdigest.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUhtpasswd b/trunk/support/NWGNUhtpasswd new file mode 100644 index 0000000000..2b692db4b8 --- /dev/null +++ b/trunk/support/NWGNUhtpasswd @@ -0,0 +1,252 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = htpasswd + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) HT Password Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = htpasswd + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = htpasswd Password Management + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 8192 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/htpasswd.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/htpasswd.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUlogres b/trunk/support/NWGNUlogres new file mode 100644 index 0000000000..982cdb78b1 --- /dev/null +++ b/trunk/support/NWGNUlogres @@ -0,0 +1,259 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(AP_WORK)/include \ + $(APR)/include \ + $(APRUTIL)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = logres + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Logresolve Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = logres + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = Log Resolve + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 65536 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/logres.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/logresolve.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# Don't link with Winsock if standard sockets are being used +ifndef USE_STDSOCKETS +FILES_nlm_Ximports += @ws2nlm.imp \ + $(EOLIST) +endif + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/NWGNUmakefile b/trunk/support/NWGNUmakefile new file mode 100644 index 0000000000..d98bcf42ef --- /dev/null +++ b/trunk/support/NWGNUmakefile @@ -0,0 +1,250 @@ +# +# Declare the sub-directories to be built here +# + +SUBDIRS = \ + $(EOLIST) + +# +# Get the 'head' of the build environment. This includes default targets and +# paths to tools +# + +include $(AP_WORK)\build\NWGNUhead.inc + +# +# build this level's files + +# +# Make sure all needed macro's are defined +# + +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/ab.nlm \ + $(OBJDIR)/htpasswd.nlm \ + $(OBJDIR)/htdigest.nlm \ + $(OBJDIR)/htdbm.nlm \ + $(OBJDIR)/htcacheclean.nlm \ + $(OBJDIR)/logres.nlm \ + $(OBJDIR)/rotlogs.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\bin\*.* + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + + diff --git a/trunk/support/NWGNUrotlogs b/trunk/support/NWGNUrotlogs new file mode 100644 index 0000000000..9a55095208 --- /dev/null +++ b/trunk/support/NWGNUrotlogs @@ -0,0 +1,251 @@ +# +# Make sure all needed macro's are defined +# + +# +# Get the 'head' of the build environment if necessary. This includes default +# targets and paths to tools +# + +ifndef EnvironmentDefined +include $(AP_WORK)\build\NWGNUhead.inc +endif + +# +# These directories will be at the beginning of the include list, followed by +# INCDIRS +# +XINCDIRS += \ + $(NWOS) \ + $(APR)/include \ + $(APR)/misc/netware \ + $(APR) \ + $(EOLIST) + +# +# These flags will come after CFLAGS +# +XCFLAGS += \ + $(EOLIST) + +# +# These defines will come after DEFINES +# +XDEFINES += \ + $(EOLIST) + +# +# These flags will be added to the link.opt file +# +XLFLAGS += \ + $(EOLIST) + +# +# These values will be appended to the correct variables based on the value of +# RELEASE +# +ifeq "$(RELEASE)" "debug" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "noopt" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +ifeq "$(RELEASE)" "release" +XINCDIRS += \ + $(EOLIST) + +XCFLAGS += \ + $(EOLIST) + +XDEFINES += \ + $(EOLIST) + +XLFLAGS += \ + $(EOLIST) +endif + +# +# These are used by the link target if an NLM is being generated +# This is used by the link 'name' directive to name the nlm. If left blank +# TARGET_nlm (see below) will be used. +# +NLM_NAME = rotlogs + +# +# This is used by the link '-desc ' directive. +# If left blank, NLM_NAME will be used. +# +NLM_DESCRIPTION = Apache $(VERSION_STR) Log Rotation Utility for NetWare + +# +# This is used by the '-threadname' directive. If left blank, +# NLM_NAME Thread will be used. +# +NLM_THREAD_NAME = rotlogs + +# +# This is used by the '-screenname' directive. If left blank, +# 'Apache for NetWare' Thread will be used. +# +NLM_SCREEN_NAME = DEFAULT + +# +# If this is specified, it will override VERSION value in +# $(AP_WORK)\build\NWGNUenvironment.inc +# +NLM_VERSION = + +# +# If this is specified, it will override the default of 64K +# +NLM_STACK_SIZE = 98304 + + +# +# If this is specified it will be used by the link '-entry' directive +# +NLM_ENTRY_SYM = _LibCPrelude + +# +# If this is specified it will be used by the link '-exit' directive +# +NLM_EXIT_SYM = _LibCPostlude + +# +# If this is specified it will be used by the link '-check' directive +# +NLM_CHECK_SYM = + +# +# If these are specified it will be used by the link '-flags' directive +# +NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION, MULTIPLE + +# +# If this is specified it will be linked in with the XDCData option in the def +# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled +# by setting APACHE_UNIPROC in the environment +# +XDCDATA = + +# +# If there is an NLM target, put it here +# +TARGET_nlm = \ + $(OBJDIR)/rotlogs.nlm \ + $(EOLIST) + +# +# If there is an LIB target, put it here +# +TARGET_lib = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the NLM target above. +# Paths must all use the '/' character +# +FILES_nlm_objs = \ + $(OBJDIR)/rotatelogs.o \ + $(EOLIST) + +# +# These are the LIB files needed to create the NLM target above. +# These will be added as a library command in the link.opt file. +# +FILES_nlm_libs = \ + libcpre.o \ + $(EOLIST) + +# +# These are the modules that the above NLM target depends on to load. +# These will be added as a module command in the link.opt file. +# +FILES_nlm_modules = \ + aprlib \ + libc \ + $(EOLIST) + +# +# If the nlm has a msg file, put it's path here +# +FILE_nlm_msg = + +# +# If the nlm has a hlp file put it's path here +# +FILE_nlm_hlp = + +# +# If this is specified, it will override $(NWOS)\copyright.txt. +# +FILE_nlm_copyright = + +# +# Any additional imports go here +# +FILES_nlm_Ximports = \ + @$(APR)/aprlib.imp \ + @libc.imp \ + $(EOLIST) + +# +# Any symbols exported to here +# +FILES_nlm_exports = \ + $(EOLIST) + +# +# These are the OBJ files needed to create the LIB target above. +# Paths must all use the '/' character +# +FILES_lib_objs = \ + $(EOLIST) + +# +# implement targets and dependancies (leave this section alone) +# + +libs :: $(OBJDIR) $(TARGET_lib) + +nlms :: libs $(TARGET_nlm) + +# +# Updated this target to create necessary directories and copy files to the +# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) +# +install :: nlms FORCE + +# +# Any specialized rules here +# + +# +# Include the 'tail' makefile that has targets that depend on variables defined +# in this makefile +# + +include $(AP_WORK)\build\NWGNUtail.inc + diff --git a/trunk/support/README b/trunk/support/README new file mode 100644 index 0000000000..80e9cafde0 --- /dev/null +++ b/trunk/support/README @@ -0,0 +1,62 @@ +Support files: + +ab + ABuse your server with this benchmarker. Rudimentary + command line testing tool. + +apachectl + Apache run-time Control script. To facilitate the + administrator and/or your rc.d scripts to control the + functioning of the Apache httpd daemon. + +apxs + APache eXtenSion tool. Eases building and installing + DSO style modules. + +dbmmanage + Create and update user authentication files in the faster + DBM format used by mod_auth_db. + +htdigest + Create and update user authentication files used in + DIGEST authentification. See mod_auth_digest. + +htpasswd + Create and update user authentication files used in + BASIC authentification. I.e. the htpasswd files. + See mod_auth. + +httpd.8 + General apache man page. + +log_server_status + This script is designed to be run at a frequent interval by something + like cron. It connects to the server and downloads the status + information. It reformats the information to a single line and logs + it to a file. + +logresolve + resolve hostnames for IP-adresses in Apache logfiles + +phf_abuse_log.cgi + This script can be used to detect people trying to abuse an ancient + and long plugged security hole which existed in a CGI script distributed + with Apache 1.0.3 and earlier versions. + +rotatelogs + rotate Apache logs without having to kill the server. + +split-logfile + This script will take a combined virtual hosts access + log file and break its contents into separate files. + +suexec + Switch User For Exec. Used internally by apache, + see the document `Apache suEXEC Support' + under http://www.apache.org/docs/suexec.html . + +SHA1 + This directory includes some utilities to allow Apache 1.3.6 to + recognize passwords in SHA1 format, as used by Netscape web + servers. It is not installed by default. + diff --git a/trunk/support/SHA1/README.sha1 b/trunk/support/SHA1/README.sha1 new file mode 100644 index 0000000000..3998e1fdd9 --- /dev/null +++ b/trunk/support/SHA1/README.sha1 @@ -0,0 +1,34 @@ +This directory includes some utilities to allow Apache 1.3.6 to +recognize passwords in SHA1 format, as used by Netscape web servers. + +From Netscape's admin interface, export the password database to an +ldif file and then use convert.pl in this distribution to generate +apache style password files. + +Note: SHA1 support is useful for migration purposes, but is less + secure than Apache's password format, since Apache's (MD5) + password format uses a random eight character salt to generate + one of many possible hashes for the same password. Netscape + uses plain SHA1 without a salt, so the same password + will always generate the same hash, making it easier + to break since the search space is smaller. + +This code was contributed by Clinton Wong . + +README.sha1 + this file + +convert-sha1.pl + takes an ldif dump from Netscape's web server on + standard in, outputs apache htpasswd format on standard out. + + Usage: convert.pl < ldif > passwords + +htpasswd-sha1.pl + perl script to generate entries in apache htpasswd format. + + Usage: htpasswd-sha1.pl some_user some_password + +ldif-sha1.example + sample ldif dump with one sha1 password and one crypt password. + diff --git a/trunk/support/SHA1/convert-sha1.pl b/trunk/support/SHA1/convert-sha1.pl new file mode 100644 index 0000000000..35228022a0 --- /dev/null +++ b/trunk/support/SHA1/convert-sha1.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl -w +use strict; + +# This is public domain code. Do whatever you want with it. +# It was originally included in Clinton Wong's Apache 1.3.6 SHA1/ldif +# patch distribution as sample code for converting accounts from +# ldif format (as used by Netscape web servers) to Apache password format. + +my $uid=''; +my $passwd=''; + +while (my $line = <>) { + chomp $line; + if ( $line =~ /uid:\s*(.+)/) { $uid = $1 } + if ( $line =~ /userpassword:\s*(\{\w+\}.+)/) { + $passwd = $1; + $passwd =~ s/^\{crypt\}//i; # Apache stores crypt without a magic string + } + + if (length($line)==0) { + + if (length $uid and length $passwd) { + print $uid, ':', $passwd, "\n"; + } # output if we have something to print + + $uid = ''; + $passwd = ''; + + } # if newline +} # while something to read + +# handle last entry if there isn't a newline before EOF + if (length $uid and length $passwd) { + print $uid, ':', $passwd, "\n"; +} + diff --git a/trunk/support/SHA1/htpasswd-sha1.pl b/trunk/support/SHA1/htpasswd-sha1.pl new file mode 100644 index 0000000000..ad624d1101 --- /dev/null +++ b/trunk/support/SHA1/htpasswd-sha1.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl -w +use strict; +# +# Utility which takes a username and password +# on the command line and generates a username +# sha1-encrytped password on the stdout. +# +# Typical useage: +# ./htpasswd-sha1.pl dirkx MySecret >> sha1-passwd +# +# This is public domain code. Do whatever you want with it. +# It was originally included in Clinton Wong's Apache 1.3.6 SHA1/ldif +# patch distribution as sample code for generating entries for +# Apache password files using SHA1. + +use MIME::Base64; # http://www.cpan.org/modules/by-module/MIME/ +use Digest::SHA1; # http://www.cpan.org/modules/by-module/MD5/ + +if ($#ARGV!=1) { die "Usage $0: user password\n" } + +print $ARGV[0], ':{SHA}', encode_base64( Digest::SHA1::sha1($ARGV[1]) ); + diff --git a/trunk/support/SHA1/ldif-sha1.example b/trunk/support/SHA1/ldif-sha1.example new file mode 100644 index 0000000000..b8fe917eaf --- /dev/null +++ b/trunk/support/SHA1/ldif-sha1.example @@ -0,0 +1,19 @@ +dn: cn=someuser +cn: someuser +sn: someuser +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: someuser +userpassword: {SHA}GvF+c3IdvgxAARuC7Uuxp9vjzik= + +dn: cn=anotheruser +cn: anotheruser +sn: anotheruser +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: anotheruser +userpassword: {crypt}eFnp.4sz5XnH6 diff --git a/trunk/support/ab.c b/trunk/support/ab.c new file mode 100644 index 0000000000..50c15476cf --- /dev/null +++ b/trunk/support/ab.c @@ -0,0 +1,2165 @@ +/* Copyright 1996-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + ** 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 , March 1996 + ** with input from Mike Belshe and + ** Michael Campanella + ** - Enhanced by Dean Gaudet , November 1997 + ** - Cleaned up by Ralf S. Engelschall , March 1998 + ** - POST and verbosity by Kurt Sussman , August 1998 + ** - HTML table output added by David N. Welton , January 1999 + ** - Added Cookie, Arbitrary header and auth support. , April 1999 + ** Version 1.3d + ** - Increased version number - as some of the socket/error handling has + ** fundamentally changed - and will give fundamentally different results + ** in situations where a server is dropping requests. Therefore you can + ** no longer compare results of AB as easily. Hence the inc of the version. + ** They should be closer to the truth though. Sander & , End 2000. + ** - Fixed proxy functionality, added median/mean statistics, added gnuplot + ** output option, added _experimental/rudimentary_ SSL support. Added + ** confidence guestimators and warnings. Sander & , End 2000 + ** - Fixed serious int overflow issues which would cause realistic (longer + ** than a few minutes) run's to have wrong (but believable) results. Added + ** trapping of connection errors which influenced measurements. + ** Contributed by Sander Temme, Early 2001 + ** Version 1.3e + ** - Changed timeout behavour during write to work whilst the sockets + ** are filling up and apr_write() does writes a few - but not all. + ** This will potentially change results. , April 2001 + ** Version 2.0.36-dev + ** Improvements to concurrent processing: + ** - Enabled non-blocking connect()s. + ** - Prevent blocking calls to apr_socket_recv() (thereby allowing AB to + ** manage its entire set of socket descriptors). + ** - Any error returned from apr_socket_recv() that is not EAGAIN or EOF + ** is now treated as fatal. + ** Contributed by Aaron Bannert, April 24, 2002 + ** + ** Version 2.0.36-2 + ** Internalized the version string - this string is part + ** of the Agent: header and the result output. + ** + ** Version 2.0.37-dev + ** Adopted SSL code by Madhu Mathihalli + ** [PATCH] ab with SSL support Posted Wed, 15 Aug 2001 20:55:06 GMT + ** Introduces four 'if (int == value)' tests per non-ssl request. + ** + ** Version 2.0.40-dev + ** Switched to the new abstract pollset API, allowing ab to + ** take advantage of future apr_pollset_t scalability improvements. + ** Contributed by Brian Pane, August 31, 2002 + **/ + +/* Note: this version string should start with \d+[\d\.]* and be a valid + * string for an HTTP Agent: header when prefixed with 'ApacheBench/'. + * It should reflect the version of AB - and not that of the apache server + * it happens to accompany. And it should be updated or changed whenever + * the results are no longer fundamentally comparable to the results of + * a previous version of ab. Either due to a change in the logic of + * ab - or to due to a change in the distribution it is compiled with + * (such as an APR change in for example blocking). + */ +#define AP_AB_BASEREVISION "2.0.40-dev" + +/* + * BUGS: + * + * - uses strcpy/etc. + * - has various other poor buffer attacks related to the lazy parsing of + * response headers from the server + * - doesn't implement much of HTTP/1.x, only accepts certain forms of + * responses + * - (performance problem) heavy use of strstr shows up top in profile + * only an issue for loopback usage + */ + +/* -------------------------------------------------------------------- */ + +#if 'A' != 0x41 +/* Hmmm... This source code isn't being compiled in ASCII. + * In order for data that flows over the network to make + * sense, we need to translate to/from ASCII. + */ +#define NOT_ASCII +#endif + +/* affects include files on Solaris */ +#define BSD_COMP + +#include "apr.h" +#include "apr_signal.h" +#include "apr_strings.h" +#include "apr_network_io.h" +#include "apr_file_io.h" +#include "apr_time.h" +#include "apr_getopt.h" +#include "apr_general.h" +#include "apr_lib.h" +#include "apr_portable.h" +#include "ap_release.h" +#include "apr_poll.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "apr_base64.h" +#ifdef NOT_ASCII +#include "apr_xlate.h" +#endif +#if APR_HAVE_STDIO_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include /* for getpid() */ +#endif + +#if !defined(WIN32) && !defined(NETWARE) +#include "ap_config_auto.h" +#endif + +#if defined(HAVE_SSLC) + +/* Libraries for RSA SSL-C */ +#include +#include +#include +#include +#include +#include +#include +#define USE_SSL +#define RSAREF +#define SK_NUM(x) sk_num(x) +#define SK_VALUE(x,y) sk_value(x,y) +typedef STACK X509_STACK_TYPE; + +#elif defined(HAVE_OPENSSL) + +/* Libraries on most systems.. */ +#include +#include +#include +#include +#include +#include +#include +#define USE_SSL +#define SK_NUM(x) sk_X509_num(x) +#define SK_VALUE(x,y) sk_X509_value(x,y) +typedef STACK_OF(X509) X509_STACK_TYPE; + +#endif + +#include +#if APR_HAVE_CTYPE_H +#include +#endif + +/* ------------------- DEFINITIONS -------------------------- */ + +#ifndef LLONG_MAX +#define AB_MAX APR_INT64_C(0x7fffffffffffffff) +#else +#define AB_MAX LLONG_MAX +#endif + +/* maximum number of requests on a time limited test */ +#define MAX_REQUESTS 50000 + +/* good old state hostname */ +#define STATE_UNCONNECTED 0 +#define STATE_CONNECTING 1 /* TCP connect initiated, but we don't + * know if it worked yet + */ +#define STATE_CONNECTED 2 /* we know TCP connect completed */ +#define STATE_READ 3 + +#define CBUFFSIZE (2048) + +struct connection { + apr_pool_t *ctx; + apr_socket_t *aprsock; + int state; + apr_size_t read; /* amount of bytes read */ + apr_size_t bread; /* amount of body read */ + apr_size_t rwrite, rwrote; /* keep pointers in what we write - across + * EAGAINs */ + apr_size_t 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 */ + apr_time_t start, /* Start of connection */ + connect, /* Connected, start writing */ + endwrite, /* Request written */ + beginread, /* First byte of input */ + done; /* Connection closed */ + + int socknum; +#ifdef USE_SSL + SSL *ssl; +#endif +}; + +struct data { + int read; /* number of bytes read */ + apr_time_t starttime; /* start time of connection in seconds since + * Jan. 1, 1970 */ + apr_interval_time_t waittime; /* Between writing request and reading + * response */ + apr_interval_time_t ctime; /* time in ms to connect */ + apr_interval_time_t time; /* time in ms for connection */ +}; + +#define ap_min(a,b) ((a)<(b))?(a):(b) +#define ap_max(a,b) ((a)>(b))?(a):(b) +#define MAX_CONCURRENCY 20000 + +/* --------------------- GLOBALS ---------------------------- */ + +int verbosity = 0; /* no verbosity by default */ +int posting = 0; /* GET by default */ +int requests = 1; /* Number of requests to make */ +int heartbeatres = 100; /* How often do we say we're alive */ +int concurrency = 1; /* Number of multiple requests to make */ +int percentile = 1; /* Show percentile served */ +int confidence = 1; /* Show confidence estimator and warnings */ +int tlimit = 0; /* time limit in secs */ +int keepalive = 0; /* try and do keepalive connections */ +char servername[1024]; /* name that server reports */ +char *hostname; /* host name from URL */ +char *host_field; /* value of "Host:" header field */ +char *path; /* path name */ +char postfile[1024]; /* name of file containing post data */ +char *postdata; /* *buffer containing data from postfile */ +apr_size_t postlen = 0; /* length of data to be POSTed */ +char content_type[1024];/* content type to put in POST header */ +char *cookie, /* optional cookie line */ + *auth, /* optional (basic/uuencoded) auhentication */ + *hdrs; /* optional arbitrary headers */ +apr_port_t port; /* port number */ +char proxyhost[1024]; /* proxy host name */ +int proxyport = 0; /* proxy port */ +char *connecthost; +apr_port_t connectport; +char *gnuplot; /* GNUplot file */ +char *csvperc; /* CSV Percentile file */ +char url[1024]; +char * fullurl, * colonhost; +int isproxy = 0; +apr_interval_time_t aprtimeout = apr_time_from_sec(30); /* timeout value */ + /* + * XXX - this is now a per read/write transact type of value + */ + +int use_html = 0; /* use html in the report */ +const char *tablestring; +const char *trstring; +const char *tdstring; + +apr_size_t doclen = 0; /* the length the document should be */ +long started = 0; /* number of requests started, so no excess */ +long totalread = 0; /* total number of bytes read */ +long totalbread = 0; /* totoal amount of entity body read */ +long totalposted = 0; /* total number of bytes posted, inc. headers */ +long done = 0; /* number of requests we have done */ +long doneka = 0; /* number of keep alive connections done */ +long good = 0, bad = 0; /* number of good and bad requests */ +long epipe = 0; /* number of broken pipe writes */ + +#ifdef USE_SSL +int is_ssl; +SSL_CTX *ssl_ctx; +char *ssl_cipher = NULL; +char *ssl_info = NULL; +BIO *bio_out,*bio_err; +#endif + +/* store error cases */ +int err_length = 0, err_conn = 0, err_except = 0; +int err_response = 0; + +apr_time_t start, endtime; + +/* global request (and its length) */ +char _request[2048]; +char *request = _request; +apr_size_t reqlen; + +/* one global throw-away buffer to read stuff into */ +char buffer[8192]; + +/* interesting percentiles */ +int percs[] = {50, 66, 75, 80, 90, 95, 98, 99, 100}; + +struct connection *con; /* connection array */ +struct data *stats; /* date for each request */ +apr_pool_t *cntxt; + +apr_pollset_t *readbits; + +apr_sockaddr_t *destsa; + +#ifdef NOT_ASCII +apr_xlate_t *from_ascii, *to_ascii; +#endif + +static void write_request(struct connection * c); +static void close_connection(struct connection * c); + +/* --------------------------------------------------------- */ + +/* simple little function to write an error string and exit */ + +static void err(char *s) +{ + fprintf(stderr, "%s\n", s); + if (done) + printf("Total of %ld requests completed\n" , done); + exit(1); +} + +/* simple little function to write an APR error string and exit */ + +static void apr_err(char *s, apr_status_t rv) +{ + char buf[120]; + + fprintf(stderr, + "%s: %s (%d)\n", + s, apr_strerror(rv, buf, sizeof buf), rv); + if (done) + printf("Total of %ld requests completed\n" , done); + exit(rv); +} + +/* --------------------------------------------------------- */ +/* write out request to a connection - assumes we can write + * (small) request out in one go into our new socket buffer + * + */ +#ifdef USE_SSL +static long ssl_print_cb(BIO *bio,int cmd,const char *argp,int argi,long argl,long ret) +{ + BIO *out; + + out=(BIO *)BIO_get_callback_arg(bio); + if (out == NULL) return(ret); + + if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) { + BIO_printf(out,"read from %08X [%08lX] (%d bytes => %ld (0x%X))\n", + bio,argp,argi,ret,ret); + BIO_dump(out,(char *)argp,(int)ret); + return(ret); + } + else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) { + BIO_printf(out,"write to %08X [%08lX] (%d bytes => %ld (0x%X))\n", + bio,argp,argi,ret,ret); + BIO_dump(out,(char *)argp,(int)ret); + } + return ret; +} + +static void ssl_state_cb(const SSL *s, int w, int r) +{ + if (w & SSL_CB_ALERT) { + BIO_printf(bio_err, "SSL/TLS Alert [%s] %s:%s\n", + (w & SSL_CB_READ ? "read" : "write"), + SSL_alert_type_string_long(r), + SSL_alert_desc_string_long(r)); + } else if (w & SSL_CB_LOOP) { + BIO_printf(bio_err, "SSL/TLS State [%s] %s\n", + (SSL_in_connect_init((SSL*)s) ? "connect" : "-"), + SSL_state_string_long(s)); + } else if (w & (SSL_CB_HANDSHAKE_START|SSL_CB_HANDSHAKE_DONE)) { + BIO_printf(bio_err, "SSL/TLS Handshake [%s] %s\n", + (w & SSL_CB_HANDSHAKE_START ? "Start" : "Done"), + SSL_state_string_long(s)); + } +} + +#ifndef RAND_MAX +#include +#define RAND_MAX INT_MAX +#endif + +static int ssl_rand_choosenum(int l, int h) +{ + int i; + char buf[50]; + + srand((unsigned int)time(NULL)); + apr_snprintf(buf, sizeof(buf), "%.0f", + (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l))); + i = atoi(buf)+1; + if (i < l) i = l; + if (i > h) i = h; + return i; +} + +static void ssl_rand_seed(void) +{ + int nDone = 0; + int n, l; + time_t t; + pid_t pid; + unsigned char stackdata[256]; + + /* + * seed in the current time (usually just 4 bytes) + */ + t = time(NULL); + l = sizeof(time_t); + RAND_seed((unsigned char *)&t, l); + nDone += l; + + /* + * seed in the current process id (usually just 4 bytes) + */ + pid = getpid(); + l = sizeof(pid_t); + RAND_seed((unsigned char *)&pid, l); + nDone += l; + + /* + * seed in some current state of the run-time stack (128 bytes) + */ + n = ssl_rand_choosenum(0, sizeof(stackdata)-128-1); + RAND_seed(stackdata+n, 128); + nDone += 128; +} + +static int ssl_print_connection_info(BIO *bio, SSL *ssl) +{ + SSL_CIPHER *c; + int alg_bits,bits; + + c = SSL_get_current_cipher(ssl); + BIO_printf(bio,"Cipher Suite Protocol :%s\n", SSL_CIPHER_get_version(c)); + BIO_printf(bio,"Cipher Suite Name :%s\n",SSL_CIPHER_get_name(c)); + + bits = SSL_CIPHER_get_bits(c,&alg_bits); + BIO_printf(bio,"Cipher Suite Cipher Bits:%d (%d)\n",bits,alg_bits); + + return(1); +} + +static void ssl_print_cert_info(BIO *bio, X509 *cert) +{ + X509_NAME *dn; + char buf[1024]; + + BIO_printf(bio, "Certificate version: %d\n", X509_get_version(cert)+1); + BIO_printf(bio,"Valid from: "); + ASN1_UTCTIME_print(bio, X509_get_notBefore(cert)); + BIO_printf(bio,"\n"); + + BIO_printf(bio,"Valid to : "); + ASN1_UTCTIME_print(bio, X509_get_notAfter(cert)); + BIO_printf(bio,"\n"); + + BIO_printf(bio,"Public key is %d bits\n", + EVP_PKEY_bits(X509_get_pubkey(cert))); + + dn = X509_get_issuer_name(cert); + X509_NAME_oneline(dn, buf, sizeof(buf)); + BIO_printf(bio,"The issuer name is %s\n", buf); + + dn=X509_get_subject_name(cert); + X509_NAME_oneline(dn, buf, sizeof(buf)); + BIO_printf(bio,"The subject name is %s\n", buf); + + /* dump the extension list too */ + BIO_printf(bio, "Extension Count: %d\n", X509_get_ext_count(cert)); +} + +static void ssl_print_info(struct connection *c) +{ + X509_STACK_TYPE *sk; + X509 *cert; + int count; + + BIO_printf(bio_err, "\n"); + sk = SSL_get_peer_cert_chain(c->ssl); + if ((count = SK_NUM(sk)) > 0) { + int i; + for (i=1; issl); + if (cert == NULL) { + BIO_printf(bio_out, "Anon DH\n"); + } else { + BIO_printf(bio_out, "Peer certificate\n"); + ssl_print_cert_info(bio_out, cert); + X509_free(cert); + } + ssl_print_connection_info(bio_err,c->ssl); + SSL_SESSION_print(bio_err, SSL_get_session(c->ssl)); + } + +static void ssl_proceed_handshake(struct connection *c) +{ + int do_next = 1; + + while (do_next) { + int ret, ecode; + apr_pollfd_t new_pollfd; + + ret = SSL_do_handshake(c->ssl); + ecode = SSL_get_error(c->ssl, ret); + + switch (ecode) { + case SSL_ERROR_NONE: + if (verbosity >= 2) + ssl_print_info(c); + if (ssl_info == NULL) { + SSL_CIPHER *ci; + X509 *cert; + int sk_bits, pk_bits, swork; + + ci = SSL_get_current_cipher(c->ssl); + sk_bits = SSL_CIPHER_get_bits(ci, &swork); + cert = SSL_get_peer_certificate(c->ssl); + if (cert) + pk_bits = EVP_PKEY_bits(X509_get_pubkey(cert)); + else + pk_bits = 0; /* Anon DH */ + + ssl_info = malloc(128); + apr_snprintf(ssl_info, 128, "%s,%s,%d,%d", + SSL_CIPHER_get_version(ci), + SSL_CIPHER_get_name(ci), + pk_bits, sk_bits); + } + write_request(c); + do_next = 0; + break; + case SSL_ERROR_WANT_READ: + new_pollfd.desc_type = APR_POLL_SOCKET; + new_pollfd.reqevents = APR_POLLIN; + new_pollfd.desc.s = c->aprsock; + new_pollfd.client_data = c; + apr_pollset_add(readbits, &new_pollfd); + do_next = 0; + break; + case SSL_ERROR_WANT_WRITE: + /* Try again */ + do_next = 1; + break; + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_SSL: + case SSL_ERROR_SYSCALL: + /* Unexpected result */ + BIO_printf(bio_err, "SSL handshake failed (%d).\n", ecode); + ERR_print_errors(bio_err); + close_connection(c); + do_next = 0; + break; + } + } +} + +#endif /* USE_SSL */ + +static void write_request(struct connection * c) +{ + do { + apr_time_t tnow = apr_time_now(); + apr_size_t l = c->rwrite; + apr_status_t e = APR_SUCCESS; /* prevent gcc warning */ + + /* + * First time round ? + */ + if (c->rwrite == 0) { + apr_socket_timeout_set(c->aprsock, 0); + c->connect = tnow; + c->rwrite = reqlen; + c->rwrote = 0; + if (posting) + c->rwrite += postlen; + } + else if (tnow > c->connect + aprtimeout) { + printf("Send request timed out!\n"); + close_connection(c); + return; + } + +#ifdef USE_SSL + if (c->ssl) { + apr_size_t e_ssl; + e_ssl = SSL_write(c->ssl,request + c->rwrote, l); + if (e_ssl != l) { + BIO_printf(bio_err, "SSL write failed - closing connection\n"); + ERR_print_errors(bio_err); + close_connection (c); + return; + } + l = e_ssl; + e = APR_SUCCESS; + } + else +#endif + e = apr_socket_send(c->aprsock, request + c->rwrote, &l); + + /* + * Bail early on the most common case + */ + if (l == c->rwrite) + break; + + if (e != APR_SUCCESS) { + /* + * Let's hope this traps EWOULDBLOCK too ! + */ + if (!APR_STATUS_IS_EAGAIN(e)) { + epipe++; + printf("Send request failed!\n"); + close_connection(c); + } + return; + } + c->rwrote += l; + c->rwrite -= l; + } while (1); + + totalposted += c->rwrite; + c->state = STATE_READ; + c->endwrite = apr_time_now(); + { + apr_pollfd_t new_pollfd; + new_pollfd.desc_type = APR_POLL_SOCKET; + new_pollfd.reqevents = APR_POLLIN; + new_pollfd.desc.s = c->aprsock; + new_pollfd.client_data = c; + apr_pollset_add(readbits, &new_pollfd); + } +} + +/* --------------------------------------------------------- */ + +/* calculate and output results */ + +static int compradre(struct data * a, struct data * b) +{ + if ((a->ctime) < (b->ctime)) + return -1; + if ((a->ctime) > (b->ctime)) + return +1; + return 0; +} + +static int comprando(struct data * a, struct data * b) +{ + if ((a->time) < (b->time)) + return -1; + if ((a->time) > (b->time)) + return +1; + return 0; +} + +static int compri(struct data * a, struct data * b) +{ + apr_interval_time_t p = a->time - a->ctime; + apr_interval_time_t q = b->time - b->ctime; + if (p < q) + return -1; + if (p > q) + return +1; + return 0; +} + +static int compwait(struct data * a, struct data * b) +{ + if ((a->waittime) < (b->waittime)) + return -1; + if ((a->waittime) > (b->waittime)) + return 1; + return 0; +} + +static void output_results(void) +{ + apr_interval_time_t timetakenusec; + float timetaken; + + endtime = apr_time_now(); + timetakenusec = endtime - start; + timetaken = ((float)apr_time_sec(timetakenusec)) + + ((float)apr_time_usec(timetakenusec)) / 1000000.0F; + + printf("\n\n"); + printf("Server Software: %s\n", servername); + printf("Server Hostname: %s\n", hostname); + printf("Server Port: %hd\n", port); +#ifdef USE_SSL + if (is_ssl && ssl_info) { + printf("SSL/TLS Protocol: %s\n", ssl_info); + } +#endif + printf("\n"); + printf("Document Path: %s\n", path); + printf("Document Length: %" APR_SIZE_T_FMT " bytes\n", doclen); + printf("\n"); + printf("Concurrency Level: %d\n", concurrency); + printf("Time taken for tests: %ld.%03ld seconds\n", + (long) apr_time_sec(timetakenusec), + (long) apr_time_usec(timetakenusec)); + printf("Complete requests: %ld\n", done); + printf("Failed requests: %ld\n", bad); + if (bad) + printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", + err_conn, err_length, err_except); + printf("Write errors: %ld\n", epipe); + if (err_response) + printf("Non-2xx responses: %d\n", err_response); + if (keepalive) + printf("Keep-Alive requests: %ld\n", doneka); + printf("Total transferred: %ld bytes\n", totalread); + if (posting > 0) + printf("Total POSTed: %ld\n", totalposted); + printf("HTML transferred: %ld bytes\n", totalbread); + + /* avoid divide by zero */ + if (timetaken) { + printf("Requests per second: %.2f [#/sec] (mean)\n", + (float) (done / timetaken)); + printf("Time per request: %.3f [ms] (mean)\n", + (float) (1000 * concurrency * timetaken / done)); + printf("Time per request: %.3f [ms] (mean, across all concurrent requests)\n", + (float) (1000 * timetaken / done)); + printf("Transfer rate: %.2f [Kbytes/sec] received\n", + (float) (totalread / 1024 / timetaken)); + if (posting > 0) { + printf(" %.2f kb/s sent\n", + (float) (totalposted / timetaken / 1024)); + printf(" %.2f kb/s total\n", + (float) ((totalread + totalposted) / timetaken / 1024)); + } + } + + if (requests) { + /* work out connection times */ + long i; + apr_time_t totalcon = 0, total = 0, totald = 0, totalwait = 0; + apr_time_t meancon, meantot, meand, meanwait; + apr_interval_time_t mincon = AB_MAX, mintot = AB_MAX, mind = AB_MAX, + minwait = AB_MAX; + apr_interval_time_t maxcon = 0, maxtot = 0, maxd = 0, maxwait = 0; + apr_interval_time_t mediancon = 0, mediantot = 0, mediand = 0, medianwait = 0; + double sdtot = 0, sdcon = 0, sdd = 0, sdwait = 0; + + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + mincon = ap_min(mincon, s.ctime); + mintot = ap_min(mintot, s.time); + mind = ap_min(mind, s.time - s.ctime); + minwait = ap_min(minwait, s.waittime); + + maxcon = ap_max(maxcon, s.ctime); + maxtot = ap_max(maxtot, s.time); + maxd = ap_max(maxd, s.time - s.ctime); + maxwait = ap_max(maxwait, s.waittime); + + totalcon += s.ctime; + total += s.time; + totald += s.time - s.ctime; + totalwait += s.waittime; + } + meancon = totalcon / requests; + meantot = total / requests; + meand = totald / requests; + meanwait = totalwait / requests; + + /* calculating the sample variance: the sum of the squared deviations, divided by n-1 */ + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + double a; + a = ((double)s.time - meantot); + sdtot += a * a; + a = ((double)s.ctime - meancon); + sdcon += a * a; + a = ((double)s.time - (double)s.ctime - meand); + sdd += a * a; + a = ((double)s.waittime - meanwait); + sdwait += a * a; + } + + sdtot = (requests > 1) ? sqrt(sdtot / (requests - 1)) : 0; + sdcon = (requests > 1) ? sqrt(sdcon / (requests - 1)) : 0; + sdd = (requests > 1) ? sqrt(sdd / (requests - 1)) : 0; + sdwait = (requests > 1) ? sqrt(sdwait / (requests - 1)) : 0; + + if (gnuplot) { + FILE *out = fopen(gnuplot, "w"); + long i; + apr_time_t sttime; + char tmstring[1024];/* XXXX */ + if (!out) { + perror("Cannot open gnuplot output file"); + exit(1); + } + fprintf(out, "starttime\tseconds\tctime\tdtime\tttime\twait\n"); + for (i = 0; i < requests; i++) { + apr_time_t diff = stats[i].time - stats[i].ctime; + + sttime = stats[i].starttime; + (void) apr_ctime(tmstring, sttime); + fprintf(out, "%s\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\n", + tmstring, + sttime, + stats[i].ctime, + diff, + stats[i].time, + stats[i].waittime); + } + fclose(out); + } + /* + * XXX: what is better; this hideous cast of the compradre function; or + * the four warnings during compile ? dirkx just does not know and + * hates both/ + */ + qsort(stats, requests, sizeof(struct data), + (int (*) (const void *, const void *)) compradre); + if ((requests > 1) && (requests % 2)) + mediancon = (stats[requests / 2].ctime + stats[requests / 2 + 1].ctime) / 2; + else + mediancon = stats[requests / 2].ctime; + + qsort(stats, requests, sizeof(struct data), + (int (*) (const void *, const void *)) compri); + if ((requests > 1) && (requests % 2)) + mediand = (stats[requests / 2].time + stats[requests / 2 + 1].time \ + -stats[requests / 2].ctime - stats[requests / 2 + 1].ctime) / 2; + else + mediand = stats[requests / 2].time - stats[requests / 2].ctime; + + qsort(stats, requests, sizeof(struct data), + (int (*) (const void *, const void *)) compwait); + if ((requests > 1) && (requests % 2)) + medianwait = (stats[requests / 2].waittime + stats[requests / 2 + 1].waittime) / 2; + else + medianwait = stats[requests / 2].waittime; + + qsort(stats, requests, sizeof(struct data), + (int (*) (const void *, const void *)) comprando); + if ((requests > 1) && (requests % 2)) + mediantot = (stats[requests / 2].time + stats[requests / 2 + 1].time) / 2; + else + mediantot = stats[requests / 2].time; + + printf("\nConnection Times (ms)\n"); + + if (confidence) { +#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4d %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n" + printf(" min mean[+/-sd] median max\n"); + printf("Connect: " CONF_FMT_STRING, + mincon, (int) (meancon + 0.5), sdcon, mediancon, maxcon); + printf("Processing: " CONF_FMT_STRING, + mind, (int) (meand + 0.5), sdd, mediand, maxd); + printf("Waiting: " CONF_FMT_STRING, + minwait, (int) (meanwait + 0.5), sdwait, medianwait, maxwait); + printf("Total: " CONF_FMT_STRING, + mintot, (int) (meantot + 0.5), sdtot, mediantot, maxtot); +#undef CONF_FMT_STRING + +#define SANE(what,mean,median,sd) \ + { \ + double d = (double)mean - median; \ + if (d < 0) d = -d; \ + if (d > 2 * sd ) \ + printf("ERROR: The median and mean for " what " are more than twice the standard\n" \ + " deviation apart. These results are NOT reliable.\n"); \ + else if (d > sd ) \ + printf("WARNING: The median and mean for " what " are not within a normal deviation\n" \ + " These results are probably not that reliable.\n"); \ + } + SANE("the initial connection time", meancon, mediancon, sdcon); + SANE("the processing time", meand, mediand, sdd); + SANE("the waiting time", meanwait, medianwait, sdwait); + SANE("the total time", meantot, mediantot, sdtot); + } + else { + printf(" min avg max\n"); +#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "\n" + printf("Connect: " CONF_FMT_STRING, + mincon, meancon, maxcon); + printf("Processing: " CONF_FMT_STRING, + mintot - mincon, meantot - meancon, maxtot - maxcon); + printf("Total: " CONF_FMT_STRING, + mintot, meantot, maxtot); +#undef CONF_FMT_STRING + } + + + /* Sorted on total connect times */ + if (percentile && (requests > 1)) { + printf("\nPercentage of the requests served within a certain time (ms)\n"); + for (i = 0; i < sizeof(percs) / sizeof(int); i++) { + if (percs[i] <= 0) + printf(" 0%% <0> (never)\n"); + else if (percs[i] >= 100) + printf(" 100%% %5" APR_TIME_T_FMT " (longest request)\n", + stats[requests - 1].time); + else + printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], + stats[(int) (requests * percs[i] / 100)].time); + } + } + if (csvperc) { + FILE *out = fopen(csvperc, "w"); + int i; + if (!out) { + perror("Cannot open CSV output file"); + exit(1); + } + fprintf(out, "" "Percentage served" "," "Time in ms" "\n"); + for (i = 0; i < 100; i++) { + apr_time_t t; + if (i == 0) + t = stats[0].time; + else if (i == 100) + t = stats[requests - 1].time; + else + t = stats[(int) (0.5 + requests * i / 100.0)].time; + fprintf(out, "%d,%e\n", i, (double)t); + } + fclose(out); + } + + } +} + +/* --------------------------------------------------------- */ + +/* calculate and output results in HTML */ + +static void output_html_results(void) +{ + long timetaken; + + endtime = apr_time_now(); + timetaken = (long)((endtime - start) / 1000); + + printf("\n\n\n", tablestring); + printf("" + "\n", + trstring, tdstring, tdstring, servername); + printf("" + "\n", + trstring, tdstring, tdstring, hostname); + printf("" + "\n", + trstring, tdstring, tdstring, port); + printf("" + "\n", + trstring, tdstring, tdstring, path); + printf("" + "\n", + trstring, tdstring, tdstring, doclen); + printf("" + "\n", + trstring, tdstring, tdstring, concurrency); + printf("" + "\n", + trstring, tdstring, tdstring, apr_time_sec(timetaken), + (long)apr_time_usec(timetaken)); + printf("" + "\n", + trstring, tdstring, tdstring, done); + printf("" + "\n", + trstring, tdstring, tdstring, bad); + if (bad) + printf("\n", + trstring, tdstring, err_conn, err_length, err_except); + if (err_response) + printf("" + "\n", + trstring, tdstring, tdstring, err_response); + if (keepalive) + printf("" + "\n", + trstring, tdstring, tdstring, doneka); + printf("" + "\n", + trstring, tdstring, tdstring, totalread); + if (posting > 0) + printf("" + "\n", + trstring, tdstring, tdstring, totalposted); + printf("" + "\n", + trstring, tdstring, tdstring, totalbread); + + /* avoid divide by zero */ + if (timetaken) { + printf("" + "\n", + trstring, tdstring, tdstring, 1000 * (float) (done) / timetaken); + printf("" + "\n", + trstring, tdstring, tdstring, (float) (totalread) / timetaken); + if (posting > 0) { + printf("" + "\n", + trstring, tdstring, tdstring, + (float) (totalposted) / timetaken); + printf("" + "\n", + trstring, tdstring, tdstring, + (float) (totalread + totalposted) / timetaken); + } + } + { + /* work out connection times */ + long i; + apr_interval_time_t totalcon = 0, total = 0; + apr_interval_time_t mincon = AB_MAX, mintot = AB_MAX; + apr_interval_time_t 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; + } + + if (requests > 0) { /* avoid division by zero (if 0 requests) */ + printf("\n", + trstring, tdstring); + printf("\n", + trstring, tdstring, tdstring, tdstring, tdstring); + printf("" + "" + "" + "\n", + trstring, tdstring, tdstring, mincon, tdstring, totalcon / requests, tdstring, maxcon); + printf("" + "" + "" + "\n", + trstring, tdstring, tdstring, mintot - mincon, tdstring, + (total / requests) - (totalcon / requests), tdstring, maxtot - maxcon); + printf("" + "" + "" + "\n", + trstring, tdstring, tdstring, mintot, tdstring, total / requests, tdstring, maxtot); + } + printf("
    Server Software:%s
    Server Hostname:%s
    Server Port:%hd
    Document Path:%s
    Document Length:%" APR_SIZE_T_FMT " bytes
    Concurrency Level:%d
    Time taken for tests:%" APR_INT64_T_FMT ".%03ld seconds
    Complete requests:%ld
    Failed requests:%ld
    (Connect: %d, Length: %d, Exceptions: %d)
    Non-2xx responses:%d
    Keep-Alive requests:%ld
    Total transferred:%ld bytes
    Total POSTed:%ld
    HTML transferred:%ld bytes
    Requests per second:%.2f
    Transfer rate:%.2f kb/s received
     %.2f kb/s sent
     %.2f kb/s total
    Connnection Times (ms)
      min avg max
    Connect:%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "
    Processing:%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "
    Total:%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "
    \n"); + } +} + +/* --------------------------------------------------------- */ + +/* start asnchronous non-blocking connection */ + +static void start_connect(struct connection * c) +{ + apr_status_t rv; + + if (!(started < requests)) + return; + + c->read = 0; + c->bread = 0; + c->keepalive = 0; + c->cbx = 0; + c->gotheader = 0; + c->rwrite = 0; + if (c->ctx) + apr_pool_destroy(c->ctx); + apr_pool_create(&c->ctx, cntxt); + + if ((rv = apr_socket_create(&c->aprsock, destsa->family, + SOCK_STREAM, 0, c->ctx)) != APR_SUCCESS) { + apr_err("socket", rv); + } + if ((rv = apr_socket_opt_set(c->aprsock, APR_SO_NONBLOCK, 1)) + != APR_SUCCESS) { + apr_err("socket nonblock", rv); + } + c->start = apr_time_now(); +#ifdef USE_SSL + if (is_ssl) { + BIO *bio; + apr_os_sock_t fd; + + if ((c->ssl = SSL_new(ssl_ctx)) == NULL) { + BIO_printf(bio_err, "SSL_new failed.\n"); + ERR_print_errors(bio_err); + exit(1); + } + ssl_rand_seed(); + apr_os_sock_get(&fd, c->aprsock); + bio = BIO_new_socket(fd, BIO_NOCLOSE); + SSL_set_bio(c->ssl, bio, bio); + SSL_set_connect_state(c->ssl); + if (verbosity >= 4) { + BIO_set_callback(bio, ssl_print_cb); + BIO_set_callback_arg(bio, bio_err); + } + } else { + c->ssl = NULL; + } +#endif + if ((rv = apr_socket_connect(c->aprsock, destsa)) != APR_SUCCESS) { + if (APR_STATUS_IS_EINPROGRESS(rv)) { + apr_pollfd_t new_pollfd; + c->state = STATE_CONNECTING; + c->rwrite = 0; + new_pollfd.desc_type = APR_POLL_SOCKET; + new_pollfd.reqevents = APR_POLLOUT; + new_pollfd.desc.s = c->aprsock; + new_pollfd.client_data = c; + apr_pollset_add(readbits, &new_pollfd); + return; + } + else { + apr_pollfd_t remove_pollfd; + remove_pollfd.desc_type = APR_POLL_SOCKET; + remove_pollfd.desc.s = c->aprsock; + apr_pollset_remove(readbits, &remove_pollfd); + apr_socket_close(c->aprsock); + err_conn++; + if (bad++ > 10) { + fprintf(stderr, + "\nTest aborted after 10 failures\n\n"); + apr_err("apr_socket_connect()", rv); + } + c->state = STATE_UNCONNECTED; + start_connect(c); + return; + } + } + + /* connected first time */ + c->state = STATE_CONNECTED; + started++; +#ifdef USE_SSL + if (c->ssl) { + ssl_proceed_handshake(c); + } else +#endif + { + write_request(c); + } +} + +/* --------------------------------------------------------- */ + +/* close down connection and save stats */ + +static void close_connection(struct connection * c) +{ + if (c->read == 0 && c->keepalive) { + /* + * server has legitimately shut down an idle keep alive request + */ + if (good) + good--; /* connection never happened */ + } + 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; + if ((done) && heartbeatres && !(done % heartbeatres)) { + fprintf(stderr, "Completed %ld requests\n", done); + fflush(stderr); + } + c->done = apr_time_now(); + s.read = c->read; + s.starttime = c->start; + s.ctime = ap_max(0, (c->connect - c->start) / 1000); + s.time = ap_max(0, (c->done - c->start) / 1000); + s.waittime = ap_max(0, (c->beginread - c->endwrite) / 1000); + stats[done++] = s; + } + } + + { + apr_pollfd_t remove_pollfd; + remove_pollfd.desc_type = APR_POLL_SOCKET; + remove_pollfd.desc.s = c->aprsock; + apr_pollset_remove(readbits, &remove_pollfd); +#ifdef USE_SSL + if (c->ssl) { + SSL_shutdown(c->ssl); + SSL_free(c->ssl); + c->ssl = NULL; + } +#endif + apr_socket_close(c->aprsock); + } + c->state = STATE_UNCONNECTED; + + /* connect again */ + start_connect(c); + return; +} + +/* --------------------------------------------------------- */ + +/* read data from connection */ + +static void read_connection(struct connection * c) +{ + apr_size_t r; + apr_status_t status; + char *part; + char respcode[4]; /* 3 digits and null */ + + r = sizeof(buffer); +#ifdef USE_SSL + if (c->ssl) { + status = SSL_read(c->ssl, buffer, r); + if (status <= 0) { + int scode = SSL_get_error(c->ssl, status); + + if (scode == SSL_ERROR_ZERO_RETURN) { + /* connection closed cleanly: */ + good++; + close_connection(c); + } + else if (scode != SSL_ERROR_WANT_WRITE + && scode != SSL_ERROR_WANT_READ) { + /* some fatal error: */ + c->read = 0; + BIO_printf(bio_err, "SSL read failed - closing connection\n"); + ERR_print_errors(bio_err); + close_connection(c); + } + return; + } + r = status; + } + else +#endif + { + status = apr_socket_recv(c->aprsock, buffer, &r); + if (APR_STATUS_IS_EAGAIN(status)) + return; + else if (r == 0 && APR_STATUS_IS_EOF(status)) { + good++; + close_connection(c); + return; + } + /* catch legitimate fatal apr_socket_recv errors */ + else if (status != APR_SUCCESS) { + err_except++; /* XXX: is this the right error counter? */ + /* XXX: Should errors here be fatal, or should we allow a + * certain number of them before completely failing? -aaron */ + apr_err("apr_socket_recv", status); + } + } + + totalread += r; + if (c->read == 0) { + c->beginread = apr_time_now(); + } + c->read += r; + + + if (!c->gotheader) { + char *s; + int l = 4; + apr_size_t space = CBUFFSIZE - c->cbx - 1; /* -1 allows for \0 term */ + int tocopy = (space < r) ? space : r; +#ifdef NOT_ASCII + apr_size_t inbytes_left = space, outbytes_left = space; + + status = apr_xlate_conv_buffer(from_ascii, buffer, &inbytes_left, + c->cbuff + c->cbx, &outbytes_left); + if (status || inbytes_left || outbytes_left) { + fprintf(stderr, "only simple translation is supported (%d/%u/%u)\n", + status, inbytes_left, outbytes_left); + exit(1); + } +#else + memcpy(c->cbuff + c->cbx, buffer, space); +#endif /* NOT_ASCII */ + c->cbx += tocopy; + space -= tocopy; + c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ + if (verbosity >= 2) { + 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 */ + apr_pollfd_t remove_pollfd; + remove_pollfd.desc_type = APR_POLL_SOCKET; + remove_pollfd.desc.s = c->aprsock; + apr_pollset_remove(readbits, &remove_pollfd); + apr_socket_close(c->aprsock); + err_response++; + if (bad++ > 10) { + err("\nTest aborted after 10 failures\n\n"); + } + 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_ */ + if (part && strlen(part) > strlen("HTTP/1.x_")) { + strncpy(respcode, (part + strlen("HTTP/1.x_")), 3); + respcode[3] = '\0'; + } + else { + strcpy(respcode, "500"); + } + + 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); + } + 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; + } + + if (c->keepalive && (c->bread >= c->length)) { + /* finished a keep-alive connection */ + good++; + /* 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; + doneka++; + if (done && heartbeatres && !(done % heartbeatres)) { + fprintf(stderr, "Completed %ld requests\n", done); + fflush(stderr); + } + c->done = apr_time_now(); + s.read = c->read; + s.starttime = c->start; + s.ctime = ap_max(0, (c->connect - c->start) / 1000); + s.waittime = ap_max(0, (c->beginread - c->endwrite) / 1000); + s.time = ap_max(0, (c->done - c->start) / 1000); + stats[done++] = s; + } + c->keepalive = 0; + c->length = 0; + c->gotheader = 0; + c->cbx = 0; + c->read = c->bread = 0; + c->start = c->connect = apr_time_now(); /* zero connect time with keep-alive */ + write_request(c); + } +} + +/* --------------------------------------------------------- */ + +/* run the tests */ + +static void test(void) +{ + apr_time_t now; + apr_int16_t rv; + long i; + apr_status_t status; + int snprintf_res = 0; +#ifdef NOT_ASCII + apr_size_t inbytes_left, outbytes_left; +#endif + + if (isproxy) { + connecthost = apr_pstrdup(cntxt, proxyhost); + connectport = proxyport; + } + else { + connecthost = apr_pstrdup(cntxt, hostname); + connectport = port; + } + + if (!use_html) { + printf("Benchmarking %s ", hostname); + if (isproxy) + printf("[through %s:%d] ", proxyhost, proxyport); + printf("(be patient)%s", + (heartbeatres ? "\n" : "...")); + fflush(stdout); + } + + now = apr_time_now(); + + con = calloc(concurrency, sizeof(struct connection)); + + stats = calloc(requests, sizeof(struct data)); + + if ((status = apr_pollset_create(&readbits, concurrency, cntxt, 0)) != APR_SUCCESS) { + apr_err("apr_pollset_create failed", status); + } + + /* setup request */ + if (posting <= 0) { + snprintf_res = apr_snprintf(request, sizeof(_request), + "%s %s HTTP/1.0\r\n" + "User-Agent: ApacheBench/%s\r\n" + "%s" "%s" "%s" + "Host: %s%s\r\n" + "Accept: */*\r\n" + "%s" "\r\n", + (posting == 0) ? "GET" : "HEAD", + (isproxy) ? fullurl : path, + AP_AB_BASEREVISION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + cookie, auth, host_field, colonhost, hdrs); + } + else { + snprintf_res = apr_snprintf(request, sizeof(_request), + "POST %s HTTP/1.0\r\n" + "User-Agent: ApacheBench/%s\r\n" + "%s" "%s" "%s" + "Host: %s%s\r\n" + "Accept: */*\r\n" + "Content-length: %" APR_SIZE_T_FMT "\r\n" + "Content-type: %s\r\n" + "%s" + "\r\n", + (isproxy) ? fullurl : path, + AP_AB_BASEREVISION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + cookie, auth, + host_field, colonhost, postlen, + (content_type[0]) ? content_type : "text/plain", hdrs); + } + if (snprintf_res >= sizeof(_request)) { + err("Request too long\n"); + } + + if (verbosity >= 2) + printf("INFO: POST header == \n---\n%s\n---\n", request); + + reqlen = strlen(request); + + /* + * Combine headers and (optional) post file into one contineous buffer + */ + if (posting == 1) { + char *buff = malloc(postlen + reqlen + 1); + if (!buff) { + fprintf(stderr, "error creating request buffer: out of memory\n"); + return; + } + strcpy(buff, request); + memcpy(buff + reqlen, postdata, postlen); + request = buff; + } + +#ifdef NOT_ASCII + inbytes_left = outbytes_left = reqlen; + status = apr_xlate_conv_buffer(to_ascii, request, &inbytes_left, + request, &outbytes_left); + if (status || inbytes_left || outbytes_left) { + fprintf(stderr, "only simple translation is supported (%d/%u/%u)\n", + status, inbytes_left, outbytes_left); + exit(1); + } +#endif /* NOT_ASCII */ + + /* This only needs to be done once */ + if ((rv = apr_sockaddr_info_get(&destsa, connecthost, APR_UNSPEC, connectport, 0, cntxt)) + != APR_SUCCESS) { + char buf[120]; + apr_snprintf(buf, sizeof(buf), + "apr_sockaddr_info_get() for %s", connecthost); + apr_err(buf, rv); + } + + /* ok - lets start */ + start = apr_time_now(); + + /* initialise lots of requests */ + for (i = 0; i < concurrency; i++) { + con[i].socknum = i; + start_connect(&con[i]); + } + + while (done < requests) { + apr_int32_t n; + apr_int32_t timed; + const apr_pollfd_t *pollresults; + + /* check for time limit expiry */ + now = apr_time_now(); + timed = (apr_int32_t)apr_time_sec(now - start); + if (tlimit && timed >= tlimit) { + requests = done; /* so stats are correct */ + break; /* no need to do another round */ + } + + n = concurrency; + status = apr_pollset_poll(readbits, aprtimeout, &n, &pollresults); + if (status != APR_SUCCESS) + apr_err("apr_poll", status); + + if (!n) { + err("\nServer timed out\n\n"); + } + + for (i = 0; i < n; i++) { + const apr_pollfd_t *next_fd = &(pollresults[i]); + struct connection *c; + + c = next_fd->client_data; + + /* + * If the connection isn't connected how can we check it? + */ + if (c->state == STATE_UNCONNECTED) + continue; + + rv = next_fd->rtnevents; + +#ifdef USE_SSL + if (c->state == STATE_CONNECTED && c->ssl && SSL_in_init(c->ssl)) { + ssl_proceed_handshake(c); + continue; + } +#endif + + /* + * Notes: APR_POLLHUP is set after FIN is received on some + * systems, so treat that like APR_POLLIN so that we try to read + * again. + * + * Some systems return APR_POLLERR with APR_POLLHUP. We need to + * call read_connection() for APR_POLLHUP, so check for + * APR_POLLHUP first so that a closed connection isn't treated + * like an I/O error. If it is, we never figure out that the + * connection is done and we loop here endlessly calling + * apr_poll(). + */ + if ((rv & APR_POLLIN) || (rv & APR_POLLPRI) || (rv & APR_POLLHUP)) + read_connection(c); + if ((rv & APR_POLLERR) || (rv & APR_POLLNVAL)) { + bad++; + err_except++; + start_connect(c); + continue; + } + if (rv & APR_POLLOUT) { + if (c->state == STATE_CONNECTING) { + apr_pollfd_t remove_pollfd; + rv = apr_socket_connect(c->aprsock, destsa); + remove_pollfd.desc_type = APR_POLL_SOCKET; + remove_pollfd.desc.s = c->aprsock; + apr_pollset_remove(readbits, &remove_pollfd); + if (rv != APR_SUCCESS) { + apr_socket_close(c->aprsock); + err_conn++; + if (bad++ > 10) { + fprintf(stderr, + "\nTest aborted after 10 failures\n\n"); + apr_err("apr_socket_connect()", rv); + } + c->state = STATE_UNCONNECTED; + start_connect(c); + continue; + } + else { + c->state = STATE_CONNECTED; +#ifdef USE_SSL + if (c->ssl) + ssl_proceed_handshake(c); + else +#endif + write_request(c); + } + } + else { + write_request(c); + } + } + + /* + * When using a select based poll every time we check the bits + * are reset. In 1.3's ab we copied the FD_SET's each time + * through, but here we're going to check the state and if the + * connection is in STATE_READ or STATE_CONNECTING we'll add the + * socket back in as APR_POLLIN. + */ + if (c->state == STATE_READ) { + apr_pollfd_t new_pollfd; + new_pollfd.desc_type = APR_POLL_SOCKET; + new_pollfd.reqevents = APR_POLLIN; + new_pollfd.desc.s = c->aprsock; + new_pollfd.client_data = c; + apr_pollset_add(readbits, &new_pollfd); + } + } + } + + if (heartbeatres) + fprintf(stderr, "Finished %ld requests\n", done); + else + printf("..done\n"); + + if (use_html) + output_html_results(); + else + output_results(); +} + +/* ------------------------------------------------------- */ + +/* display copyright information */ +static void copyright(void) +{ + if (!use_html) { + printf("This is ApacheBench, Version %s\n", AP_AB_BASEREVISION " <$Revision: 1.146 $> apache-2.0"); + printf("Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n"); + printf("Copyright 1997-2005 The Apache Software Foundation, http://www.apache.org/\n"); + printf("\n"); + } + else { + printf("

    \n"); + printf(" This is ApacheBench, Version %s <%s> apache-2.0
    \n", AP_AB_BASEREVISION, "$Revision: 1.146 $"); + printf(" Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    \n"); + printf(" Copyright 1997-2005 The Apache Software Foundation, http://www.apache.org/
    \n"); + printf("

    \n

    \n"); + } +} + +/* display usage information */ +static void usage(const char *progname) +{ + fprintf(stderr, "Usage: %s [options] [http" +#ifdef USE_SSL + "[s]" +#endif + "://]hostname[:port]/path\n", progname); + fprintf(stderr, "Options are:\n"); + fprintf(stderr, " -n requests Number of requests to perform\n"); + fprintf(stderr, " -c concurrency Number of multiple requests to make\n"); + fprintf(stderr, " -t timelimit Seconds to max. wait for responses\n"); + fprintf(stderr, " -p postfile File containing 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, " -i Use HEAD instead of GET\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, " -C attribute Add cookie, eg. 'Apache=1234. (repeatable)\n"); + fprintf(stderr, " -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip'\n"); + fprintf(stderr, " Inserted after all normal header lines. (repeatable)\n"); + fprintf(stderr, " -A attribute Add Basic WWW Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); + fprintf(stderr, " -P attribute Add Basic Proxy Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); + fprintf(stderr, " -X proxy:port Proxyserver and port number to use\n"); + fprintf(stderr, " -V Print version number and exit\n"); + fprintf(stderr, " -k Use HTTP KeepAlive feature\n"); + fprintf(stderr, " -d Do not show percentiles served table.\n"); + fprintf(stderr, " -S Do not show confidence estimators and warnings.\n"); + fprintf(stderr, " -g filename Output collected data to gnuplot format file.\n"); + fprintf(stderr, " -e filename Output CSV file with percentages served\n"); + fprintf(stderr, " -h Display usage information (this message)\n"); +#ifdef USE_SSL + fprintf(stderr, " -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)\n"); + fprintf(stderr, " -f protocol Specify SSL/TLS protocol (SSL2, SSL3, TLS1, or ALL)\n"); +#endif + exit(EINVAL); +} + +/* ------------------------------------------------------- */ + +/* split URL into parts */ + +static int parse_url(char *url) +{ + char *cp; + char *h; + char *scope_id; + apr_status_t rv; + + /* Save a copy for the proxy */ + fullurl = apr_pstrdup(cntxt, url); + + if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0) { + url += 7; +#ifdef USE_SSL + is_ssl = 0; +#endif + } + else +#ifdef USE_SSL + if (strlen(url) > 8 && strncmp(url, "https://", 8) == 0) { + url += 8; + is_ssl = 1; + } +#else + if (strlen(url) > 8 && strncmp(url, "https://", 8) == 0) { + fprintf(stderr, "SSL not compiled in; no https support\n"); + exit(1); + } +#endif + + if ((cp = strchr(url, '/')) == NULL) + return 1; + h = apr_palloc(cntxt, cp - url + 1); + memcpy(h, url, cp - url); + h[cp - url] = '\0'; + rv = apr_parse_addr_port(&hostname, &scope_id, &port, h, cntxt); + if (rv != APR_SUCCESS || !hostname || scope_id) { + return 1; + } + path = apr_pstrdup(cntxt, cp); + *cp = '\0'; + if (*url == '[') { /* IPv6 numeric address string */ + host_field = apr_psprintf(cntxt, "[%s]", hostname); + } + else { + host_field = hostname; + } + + if (port == 0) { /* no port specified */ +#ifdef USE_SSL + if (is_ssl) + port = 443; + else +#endif + port = 80; + } + + if (( +#ifdef USE_SSL + is_ssl && (port != 443)) || (!is_ssl && +#endif + (port != 80))) + { + colonhost = apr_psprintf(cntxt,":%d",port); + } else + colonhost = ""; + return 0; +} + +/* ------------------------------------------------------- */ + +/* read data to POST from file, save contents and length */ + +static int open_postfile(const char *pfile) +{ + apr_file_t *postfd; + apr_finfo_t finfo; + apr_status_t rv; + char errmsg[120]; + + rv = apr_file_open(&postfd, pfile, APR_READ, APR_OS_DEFAULT, cntxt); + if (rv != APR_SUCCESS) { + fprintf(stderr, "ab: Could not open POST data file (%s): %s\n", pfile, + apr_strerror(rv, errmsg, sizeof errmsg)); + return rv; + } + + apr_file_info_get(&finfo, APR_FINFO_NORM, postfd); + postlen = (apr_size_t)finfo.size; + postdata = malloc(postlen); + if (!postdata) { + fprintf(stderr, "ab: Could not allocate POST data buffer\n"); + return APR_ENOMEM; + } + rv = apr_file_read_full(postfd, postdata, postlen, NULL); + if (rv != APR_SUCCESS) { + fprintf(stderr, "ab: Could not read POST data file: %s\n", + apr_strerror(rv, errmsg, sizeof errmsg)); + return rv; + } + apr_file_close(postfd); + return 0; +} + +/* ------------------------------------------------------- */ + +/* sort out command-line args and call test */ +int main(int argc, const char * const argv[]) +{ + int r, l; + char tmp[1024]; + apr_status_t status; + apr_getopt_t *opt; + const char *optarg; + char c; +#ifdef USE_SSL + SSL_METHOD *meth = SSLv23_client_method(); +#endif + + /* table defaults */ + tablestring = ""; + trstring = ""; + tdstring = "bgcolor=white"; + cookie = ""; + auth = ""; + proxyhost[0] = '\0'; + hdrs = ""; + + apr_app_initialize(&argc, &argv, NULL); + atexit(apr_terminate); + apr_pool_create(&cntxt, NULL); + +#ifdef NOT_ASCII + status = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, cntxt); + if (status) { + fprintf(stderr, "apr_xlate_open(to ASCII)->%d\n", status); + exit(1); + } + status = apr_xlate_open(&from_ascii, APR_DEFAULT_CHARSET, "ISO-8859-1", cntxt); + if (status) { + fprintf(stderr, "apr_xlate_open(from ASCII)->%d\n", status); + exit(1); + } + status = apr_base64init_ebcdic(to_ascii, from_ascii); + if (status) { + fprintf(stderr, "apr_base64init_ebcdic()->%d\n", status); + exit(1); + } +#endif + + apr_getopt_init(&opt, cntxt, argc, argv); + while ((status = apr_getopt(opt, "n:c:t:T:p:v:kVhwix:y:z:C:H:P:A:g:X:de:Sq" +#ifdef USE_SSL + "Z:f:" +#endif + ,&c, &optarg)) == APR_SUCCESS) { + switch (c) { + case 'n': + requests = atoi(optarg); + if (!requests) { + err("Invalid number of requests\n"); + } + break; + case 'k': + keepalive = 1; + break; + case 'q': + heartbeatres = 0; + break; + case 'c': + concurrency = atoi(optarg); + break; + case 'i': + if (posting == 1) + err("Cannot mix POST and HEAD\n"); + posting = -1; + break; + case 'g': + gnuplot = strdup(optarg); + break; + case 'd': + percentile = 0; + break; + case 'e': + csvperc = strdup(optarg); + break; + case 'S': + confidence = 0; + break; + case 'p': + if (posting != 0) + err("Cannot mix POST and HEAD\n"); + if (0 == (r = open_postfile(optarg))) { + posting = 1; + } + else if (postdata) { + 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 'C': + cookie = apr_pstrcat(cntxt, "Cookie: ", optarg, "\r\n", NULL); + break; + case 'A': + /* + * assume username passwd already to be in colon separated form. + * Ready to be uu-encoded. + */ + while (apr_isspace(*optarg)) + optarg++; + if (apr_base64_encode_len(strlen(optarg)) > sizeof(tmp)) { + err("Authentication credentials too long\n"); + } + l = apr_base64_encode(tmp, optarg, strlen(optarg)); + tmp[l] = '\0'; + + auth = apr_pstrcat(cntxt, auth, "Authorization: Basic ", tmp, + "\r\n", NULL); + break; + case 'P': + /* + * assume username passwd already to be in colon separated form. + */ + while (apr_isspace(*optarg)) + optarg++; + if (apr_base64_encode_len(strlen(optarg)) > sizeof(tmp)) { + err("Proxy credentials too long\n"); + } + l = apr_base64_encode(tmp, optarg, strlen(optarg)); + tmp[l] = '\0'; + + auth = apr_pstrcat(cntxt, auth, "Proxy-Authorization: Basic ", + tmp, "\r\n", NULL); + break; + case 'H': + hdrs = apr_pstrcat(cntxt, hdrs, optarg, "\r\n", NULL); + 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 'X': + { + char *p; + /* + * assume proxy-name[:port] + */ + if ((p = strchr(optarg, ':'))) { + *p = '\0'; + p++; + proxyport = atoi(p); + } + strcpy(proxyhost, optarg); + isproxy = 1; + } + break; + case 'y': + use_html = 1; + trstring = optarg; + break; + case 'z': + use_html = 1; + tdstring = optarg; + break; + case 'h': + usage(argv[0]); + break; + case 'V': + copyright(); + return 0; +#ifdef USE_SSL + case 'Z': + ssl_cipher = strdup(optarg); + break; + case 'f': + if (strncasecmp(optarg, "ALL", 3) == 0) { + meth = SSLv23_client_method(); + } else if (strncasecmp(optarg, "SSL2", 4) == 0) { + meth = SSLv2_client_method(); + } else if (strncasecmp(optarg, "SSL3", 4) == 0) { + meth = SSLv3_client_method(); + } else if (strncasecmp(optarg, "TLS1", 4) == 0) { + meth = TLSv1_client_method(); + } + break; +#endif + } + } + + if (opt->ind != argc - 1) { + fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); + usage(argv[0]); + } + + if (parse_url(apr_pstrdup(cntxt, opt->argv[opt->ind++]))) { + fprintf(stderr, "%s: invalid URL\n", argv[0]); + usage(argv[0]); + } + + if ((concurrency < 0) || (concurrency > MAX_CONCURRENCY)) { + fprintf(stderr, "%s: Invalid Concurrency [Range 0..%d]\n", + argv[0], MAX_CONCURRENCY); + usage(argv[0]); + } + + if (concurrency > requests) { + fprintf(stderr, "%s: Cannot use concurrency level greater than " + "total number of requests\n", argv[0]); + usage(argv[0]); + } + + if ((heartbeatres) && (requests > 150)) { + heartbeatres = requests / 10; /* Print line every 10% of requests */ + if (heartbeatres < 100) + heartbeatres = 100; /* but never more often than once every 100 + * connections. */ + } + else + heartbeatres = 0; + +#ifdef USE_SSL +#ifdef RSAREF + R_malloc_init(); +#else + CRYPTO_malloc_init(); +#endif + SSL_load_error_strings(); + SSL_library_init(); + bio_out=BIO_new_fp(stdout,BIO_NOCLOSE); + bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); + + if (!(ssl_ctx = SSL_CTX_new(meth))) { + BIO_printf(bio_err, "Could not initialize SSL Context.\n"); + ERR_print_errors(bio_err); + exit(1); + } + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); + if (ssl_cipher != NULL) { + if (!SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher)) { + fprintf(stderr, "error setting cipher list [%s]\n", ssl_cipher); + ERR_print_errors_fp(stderr); + exit(1); + } + } + if (verbosity >= 3) { + SSL_CTX_set_info_callback(ssl_ctx, ssl_state_cb); + } +#endif +#ifdef SIGPIPE + apr_signal(SIGPIPE, SIG_IGN); /* Ignore writes to connections that + * have been closed at the other end. */ +#endif + copyright(); + test(); + apr_pool_destroy(cntxt); + + return 0; +} diff --git a/trunk/support/ab.dsp b/trunk/support/ab.dsp new file mode 100644 index 0000000000..2d613119f5 --- /dev/null +++ b/trunk/support/ab.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="ab" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ab - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ab.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ab.mak" CFG="ab - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ab - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ab - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ab - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/ab_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "ab - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/ab_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "ab - Win32 Release" +# Name "ab - Win32 Debug" +# Begin Source File + +SOURCE=.\ab.c +# End Source File +# Begin Source File + +SOURCE=.\ab.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "ab - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\ab.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk ab.exe "ApacheBench Utility" ../include/ap_release.h > .\ab.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "ab - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\ab.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk ab.exe "ApacheBench Utility" ../include/ap_release.h > .\ab.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/abs.dsp b/trunk/support/abs.dsp new file mode 100644 index 0000000000..3207f389de --- /dev/null +++ b/trunk/support/abs.dsp @@ -0,0 +1,134 @@ +# Microsoft Developer Studio Project File - Name="abs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=abs - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "abs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "abs.mak" CFG="abs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "abs - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "abs - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "abs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "SSL" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" /I "../srclib/openssl/inc32" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "HAVE_OPENSSL" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /Fd"Release/abs_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /machine:I386 /libpath:"../srclib/openssl/out32dll" +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"../srclib/openssl/out32dll" /opt:ref + +!ELSEIF "$(CFG)" == "abs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "SSL" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /I "../include" /I "../srclib/openssl/inc32" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "HAVE_OPENSSL" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /Fd"Debug/abs_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /libpath:"../srclib/openssl/out32dll" +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib ssleay32.lib libeay32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /libpath:"../srclib/openssl/out32dll" + +!ENDIF + +# Begin Target + +# Name "abs - Win32 Release" +# Name "abs - Win32 Debug" +# Begin Source File + +SOURCE=.\ab.c + +!IF "$(CFG)" == "abs - Win32 Release" + +# ADD CPP /Fo"Release/abs.obj" + +!ELSEIF "$(CFG)" == "abs - Win32 Debug" + +# ADD CPP /Fo"Debug/abs.obj" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\abs.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "abs - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\abs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk ab.exe "ApacheBench/SSL Utility" ../include/ap_release.h > .\abs.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "abs - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\abs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk ab.exe "ApacheBench/SSL Utility" ../include/ap_release.h > .\abs.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/apachectl.in b/trunk/support/apachectl.in new file mode 100644 index 0000000000..8a2b6dba4a --- /dev/null +++ b/trunk/support/apachectl.in @@ -0,0 +1,105 @@ +#!/bin/sh +# +# Copyright 2000-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Apache control script designed to allow an easy command line interface +# to controlling Apache. Written by Marc Slemko, 1997/08/23 +# +# The exit codes returned are: +# XXX this doc is no longer correct now that the interesting +# XXX functions are handled by httpd +# 0 - operation completed successfully +# 1 - +# 2 - usage error +# 3 - httpd could not be started +# 4 - httpd could not be stopped +# 5 - httpd could not be started during a restart +# 6 - httpd could not be restarted during a restart +# 7 - httpd could not be restarted during a graceful restart +# 8 - configuration syntax error +# +# When multiple arguments are given, only the error from the _last_ +# one is reported. Run "apachectl help" for usage info +# +ARGV="$@" +# +# |||||||||||||||||||| START CONFIGURATION SECTION |||||||||||||||||||| +# -------------------- -------------------- +# +# the path to your httpd binary, including options if necessary +HTTPD='@exp_sbindir@/@progname@' +# +# pick up any necessary environment variables +if test -f @exp_sbindir@/envvars; then + . @exp_sbindir@/envvars +fi +# +# a command that outputs a formatted text version of the HTML at the +# url given on the command line. Designed for lynx, however other +# programs may work. +LYNX="@LYNX_PATH@ -dump" +# +# the URL to your server's mod_status status page. If you do not +# have one, then status and fullstatus will not work. +STATUSURL="http://localhost:@PORT@/server-status" +# +# Set this variable to a command that increases the maximum +# number of file descriptors allowed per child process. This is +# critical for configurations that use many file descriptors, +# such as mass vhosting, or a multithreaded server. +ULIMIT_MAX_FILES="@APACHECTL_ULIMIT@" +# -------------------- -------------------- +# |||||||||||||||||||| END CONFIGURATION SECTION |||||||||||||||||||| + +# Set the maximum number of file descriptors allowed per child process. +if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then + $ULIMIT_MAX_FILES +fi + +ERROR=0 +if [ "x$ARGV" = "x" ] ; then + ARGV="-h" +fi + +case $ARGV in +start|stop|restart|graceful) + $HTTPD -k $ARGV + ERROR=$? + ;; +startssl|sslstart|start-SSL) + echo The startssl option is no longer supported. + echo Please edit httpd.conf to include the SSL configuration settings + echo and then use "apachectl start". + ERROR=2 + ;; +configtest) + $HTTPD -t + ERROR=$? + ;; +status) + $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } ' + ;; +fullstatus) + $LYNX $STATUSURL + ;; +*) + $HTTPD $ARGV + ERROR=$? +esac + +exit $ERROR + diff --git a/trunk/support/apxs.in b/trunk/support/apxs.in new file mode 100644 index 0000000000..f1a5a3c900 --- /dev/null +++ b/trunk/support/apxs.in @@ -0,0 +1,766 @@ +#!@perlbin@ -w +# +# Copyright 1999-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 5.004; +use strict; +package apxs; + +## +## Configuration +## + +my %config_vars = (); + +my $installbuilddir = "@exp_installbuilddir@"; +get_config_vars("$installbuilddir/config_vars.mk",\%config_vars); + +# read the configuration variables once + +my $prefix = get_vars("prefix"); +my $CFG_PREFIX = $prefix; +my $exec_prefix = get_vars("exec_prefix"); +my $datadir = get_vars("datadir"); +my $localstatedir = get_vars("localstatedir"); +my $CFG_TARGET = get_vars("progname"); +my $CFG_SYSCONFDIR = get_vars("sysconfdir"); +my $CFG_CFLAGS = join ' ', map { get_vars($_) } + qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS); +my $includedir = get_vars("includedir"); +my $CFG_INCLUDEDIR = eval qq("$includedir"); +my $CFG_CC = get_vars("CC"); +my $libexecdir = get_vars("libexecdir"); +my $CFG_LIBEXECDIR = eval qq("$libexecdir"); +my $sbindir = get_vars("sbindir"); +my $CFG_SBINDIR = eval qq("$sbindir"); +my $ltflags = $ENV{'LTFLAGS'}; +$ltflags or $ltflags = "--silent"; + +my %internal_vars = map {$_ => 1} + qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB + PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR); + +## +## parse argument line +## + +# defaults for parameters +my $opt_n = ''; +my $opt_g = ''; +my $opt_c = 0; +my $opt_o = ''; +my @opt_D = (); +my @opt_I = (); +my @opt_L = (); +my @opt_l = (); +my @opt_W = (); +my @opt_S = (); +my $opt_e = 0; +my $opt_i = 0; +my $opt_a = 0; +my $opt_A = 0; +my $opt_q = 0; +my $opt_h = 0; +my $opt_p = 0; + +# this subroutine is derived from Perl's getopts.pl with the enhancement of +# the "+" metacharacter at the format string to allow a list to be built by +# subsequent occurrences of the same option. +sub Getopts { + my ($argumentative, @ARGV) = @_; + my $errs = 0; + local $_; + local $[ = 0; + + my @args = split / */, $argumentative; + while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) { + my ($first, $rest) = ($1,$2); + if ($_ =~ m|^--$|) { + shift @ARGV; + last; + } + my $pos = index($argumentative,$first); + if ($pos >= $[) { + if ($pos < $#args && $args[$pos+1] eq ':') { + shift @ARGV; + if ($rest eq '') { + unless (@ARGV) { + error("Incomplete option: $first (needs an argument)"); + $errs++; + } + $rest = shift(@ARGV); + } + eval "\$opt_$first = \$rest;"; + } + elsif ($pos < $#args && $args[$pos+1] eq '+') { + shift @ARGV; + if ($rest eq '') { + unless (@ARGV) { + error("Incomplete option: $first (needs an argument)"); + $errs++; + } + $rest = shift(@ARGV); + } + eval "push(\@opt_$first, \$rest);"; + } + else { + eval "\$opt_$first = 1"; + if ($rest eq '') { + shift(@ARGV); + } + else { + $ARGV[0] = "-$rest"; + } + } + } + else { + error("Unknown option: $first"); + $errs++; + if ($rest ne '') { + $ARGV[0] = "-$rest"; + } + else { + shift(@ARGV); + } + } + } + return ($errs == 0, @ARGV); +} + +sub usage { + print STDERR "Usage: apxs -g [-S =] -n \n"; + print STDERR " apxs -q [-S =] ...\n"; + print STDERR " apxs -c [-S =] [-o ] [-D [=]]\n"; + print STDERR " [-I ] [-L ] [-l ] [-Wc,]\n"; + print STDERR " [-Wl,] [-p] ...\n"; + print STDERR " apxs -i [-S =] [-a] [-A] [-n ] ...\n"; + print STDERR " apxs -e [-S =] [-a] [-A] [-n ] ...\n"; + exit(1); +} + +# option handling +my $rc; +($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaAp", @ARGV); +&usage if ($rc == 0); +&usage if ($#ARGV == -1 and not $opt_g); +&usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c and not $opt_e); + +# argument handling +my @args = @ARGV; +my $name = 'unknown'; +$name = $opt_n if ($opt_n ne ''); + +if (@opt_S) { + my ($opt_S); + foreach $opt_S (@opt_S) { + if ($opt_S =~ m/^([^=]+)=(.*)$/) { + my ($var) = $1; + my ($val) = $2; + my $oldval = eval "\$CFG_$var"; + + unless ($var and $oldval) { + print STDERR "apxs:Error: no config variable $var\n"; + &usage; + } + + eval "\$CFG_${var}=\"${val}\""; + } else { + print STDERR "apxs:Error: malformatted -S option\n"; + &usage; + } + } +} + +## +## Initial shared object support check +## +my $httpd = get_vars("sbindir") . "/" . get_vars("progname"); +$httpd = eval qq("$httpd"); +$httpd = eval qq("$httpd"); +my $envvars = get_vars("sbindir") . "/envvars"; +$envvars = eval qq("$envvars"); +$envvars = eval qq("$envvars"); + +#allow apxs to be run from the source tree, before installation +if ($0 =~ m:support/apxs$:) { + ($httpd = $0) =~ s:support/apxs$::; +} + +unless (-x "$httpd") { + error("$httpd not found or not executable"); + exit 1; +} + +unless (grep /mod_so/, `. $envvars && $httpd -l`) { + error("Sorry, no shared object support for Apache"); + error("available under your platform. Make sure"); + error("the Apache module mod_so is compiled into"); + error("your server binary `$httpd'."); + exit 1; +} + +sub get_config_vars{ + my ($file, $rh_config) = @_; + + open IN, $file or die "cannot open $file: $!"; + while (){ + if (/^\s*(.*?)\s*=\s*(.*)$/){ + $rh_config->{$1} = $2; + } + } + close IN; +} + +sub get_vars { + my $result = ''; + my $ok = 0; + my $arg; + foreach $arg (@_) { + if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) { + my $val = exists $config_vars{$arg} + ? $config_vars{$arg} + : $config_vars{lc $arg}; + $val =~ s/[()]//g; + $result .= eval "qq($val)" if defined $val; + $result .= ";;"; + $ok = 1; + } + if (not $ok) { + if (exists $internal_vars{$arg} or exists $internal_vars{lc $arg}) { + my $val = exists $internal_vars{$arg} ? $arg : lc $arg; + $val = eval "\$CFG_$val"; + $result .= eval "qq($val)" if defined $val; + $result .= ";;"; + $ok = 1; + } + if (not $ok) { + error("Invalid query string `$arg'"); + exit(1); + } + } + } + $result =~ s|;;$||; + $result =~ s|:| |; + return $result; +} + +## +## Operation +## + +# helper function for executing a list of +# system command with return code checks +sub execute_cmds { + my (@cmds) = @_; + my ($cmd, $rc); + + foreach $cmd (@cmds) { + notice($cmd); + $rc = system $cmd; + if ($rc) { + error(sprintf "Command failed with rc=%d\n", $rc << 8); + exit 1 ; + } + } +} + +if ($opt_g) { + ## + ## SAMPLE MODULE SOURCE GENERATION + ## + + if (-d $name) { + error("Directory `$name' already exists. Remove first"); + exit(1); + } + + my $data = join('', ); + $data =~ s|%NAME%|$name|sg; + $data =~ s|%TARGET%|$CFG_TARGET|sg; + $data =~ s|%PREFIX%|$prefix|sg; + $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg; + + my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); + + notice("Creating [DIR] $name"); + system("mkdir $name"); + notice("Creating [FILE] $name/Makefile"); + open(FP, ">${name}/Makefile") || die; + print FP $mkf; + close(FP); + notice("Creating [FILE] $name/modules.mk"); + open(FP, ">${name}/modules.mk") || die; + print FP $mods; + close(FP); + notice("Creating [FILE] $name/mod_$name.c"); + open(FP, ">${name}/mod_${name}.c") || die; + print FP $src; + close(FP); + notice("Creating [FILE] $name/.deps"); + system("touch ${name}/.deps"); + + exit(0); +} + + +if ($opt_q) { + ## + ## QUERY INFORMATION + ## + my $result = get_vars(@args); + print "$result\n"; +} + +my $apr_config = get_vars("APR_CONFIG"); + +if (! -x "$apr_config") { + error("$apr_config not found!"); + exit(1); +} + +my $apu_config = get_vars("APU_CONFIG"); + +if (! -x "$apu_config") { + error("$apu_config not found!"); + exit(1); +} + +my $libtool = `$apr_config --apr-libtool`; +chomp($libtool); + +my $apr_includedir = `$apr_config --includes`; +chomp($apr_includedir); +my $apu_includedir = `$apu_config --includes`; +chomp($apu_includedir); + +if ($opt_c) { + ## + ## SHARED OBJECT COMPILATION + ## + + # split files into sources and objects + my @srcs = (); + my @objs = (); + my $f; + foreach $f (@args) { + if ($f =~ m|\.c$|) { + push(@srcs, $f); + } + else { + push(@objs, $f); + } + } + + # determine output file + my $dso_file; + if ($opt_o eq '') { + if ($#srcs > -1) { + $dso_file = $srcs[0]; + $dso_file =~ s|\.[^.]+$|.la|; + } + elsif ($#objs > -1) { + $dso_file = $objs[0]; + $dso_file =~ s|\.[^.]+$|.la|; + } + else { + $dso_file = "mod_unknown.la"; + } + } + else { + $dso_file = $opt_o; + $dso_file =~ s|\.[^.]+$|.la|; + } + + # create compilation commands + my @cmds = (); + my $opt = ''; + my ($opt_Wc, $opt_I, $opt_D); + foreach $opt_Wc (@opt_W) { + $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|); + } + foreach $opt_I (@opt_I) { + $opt .= "-I$opt_I "; + } + foreach $opt_D (@opt_D) { + $opt .= "-D$opt_D "; + } + my $cflags = "$CFG_CFLAGS"; + my $s; + my $mod; + foreach $s (@srcs) { + my $slo = $s; + $slo =~ s|\.c$|.slo|; + my $lo = $s; + $lo =~ s|\.c$|.lo|; + my $la = $s; + $la =~ s|\.c$|.la|; + my $o = $s; + $o =~ s|\.c$|.o|; + push(@cmds, "$libtool $ltflags --mode=compile $CFG_CC $cflags -I$CFG_INCLUDEDIR $apr_includedir $apu_includedir $opt -c -o $lo $s && touch $slo"); + unshift(@objs, $lo); + } + + # create link command + my $o; + my $lo; + foreach $o (@objs) { + $lo .= " $o"; + } + my ($opt_Wl, $opt_L, $opt_l); + $opt = ''; + foreach $opt_Wl (@opt_W) { + $opt .= "$1 " if ($opt_Wl =~ m|^\s*l,(.*)$|); + } + foreach $opt_L (@opt_L) { + $opt .= " -L$opt_L"; + } + foreach $opt_l (@opt_l) { + $opt .= " -l$opt_l"; + } + + if ($opt_p == 1) { + + my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`; + chomp($apr_libs); + my $apu_libs=`$apu_config --ldflags --link-libtool --libs`; + chomp($apu_libs); + + $opt .= " ".$apu_libs." ".$apr_libs; + } + else { + my $apr_ldflags=`$apr_config --ldflags`; + chomp($apr_ldflags); + $opt .= " -rpath $CFG_LIBEXECDIR -module -avoid-version $apr_ldflags"; + } + + push(@cmds, "$libtool $ltflags --mode=link $CFG_CC -o $dso_file $opt $lo"); + + # execute the commands + &execute_cmds(@cmds); + + # allow one-step compilation and installation + if ($opt_i or $opt_e) { + @args = ( $dso_file ); + } +} + +if ($opt_i or $opt_e) { + ## + ## SHARED OBJECT INSTALLATION + ## + + # determine installation commands + # and corresponding LoadModule directive + my @lmd = (); + my @cmds = (); + my $f; + foreach $f (@args) { + # ack all potential gcc, hp/ux, win32+os2+aix and os/x extensions + if ($f !~ m#(\.so$|\.la$|\.sl$|\.dll$|\.dylib$|)#) { + error("file $f is not a shared object"); + exit(1); + } + my $t = $f; + $t =~ s|^.+/([^/]+)$|$1|; + # use .so unambigiously for installed shared library modules + $t =~ s|\.[^./\\]+$|\.so|; + if ($opt_i) { + push(@cmds, "$installbuilddir/instdso.sh SH_LIBTOOL='" . + "$libtool' $f $CFG_LIBEXECDIR"); + push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t"); + } + + # determine module symbolname and filename + my $filename = ''; + if ($name eq 'unknown') { + $name = ''; + my $base = $f; + $base =~ s|\.[^.]+$||; + if (-f "$base.c") { + open(FP, "<$base.c"); + my $content = join('', ); + close(FP); + if ($content =~ m|.*module\s+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) { + $name = "$1"; + $filename = "$base.c"; + $filename =~ s|^[^/]+/||; + } + } + if ($name eq '') { + if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) { + $name = "$1"; + $filename = $base; + $filename =~ s|^[^/]+/||; + } + } + if ($name eq '') { + error("Sorry, cannot determine bootstrap symbol name"); + error("Please specify one with option `-n'"); + exit(1); + } + } + if ($filename eq '') { + $filename = "mod_${name}.c"; + } + my $dir = $CFG_LIBEXECDIR; + $dir =~ s|^$CFG_PREFIX/?||; + $dir =~ s|(.)$|$1/|; + $t =~ s|\.la$|.so|; + push(@lmd, sprintf("LoadModule %-18s %s", "${name}_module", "$dir$t")); + } + + # execute the commands + &execute_cmds(@cmds); + + # activate module via LoadModule/AddModule directive + if ($opt_a or $opt_A) { + if (not -f "$CFG_SYSCONFDIR/$CFG_TARGET.conf") { + error("Config file $CFG_SYSCONFDIR/$CFG_TARGET.conf not found"); + exit(1); + } + + open(FP, "<$CFG_SYSCONFDIR/$CFG_TARGET.conf") || die; + my $content = join('', ); + close(FP); + + if ($content !~ m|\n#?\s*LoadModule\s+|) { + error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_TARGET.conf file."); + error("At least one `LoadModule' directive already has to exist."); + exit(1); + } + + my $lmd; + my $c = ''; + $c = '#' if ($opt_A); + foreach $lmd (@lmd) { + my $what = $opt_A ? "preparing" : "activating"; + if ($content !~ m|\n#?\s*$lmd|) { + # check for open , so that the new LoadModule + # directive always appears *outside* of an . + + my $before = ($content =~ m|^(.*\n)#?\s*LoadModule\s+[^\n]+\n|s)[0]; + + # the '()=' trick forces list context and the scalar + # assignment counts the number of list members (aka number + # of matches) then + my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg); + my $cntclose = () = ($before =~ m|^\s*$CFG_SYSCONFDIR/$CFG_TARGET.conf.new")) { + print FP $content; + close(FP); + system("cp $CFG_SYSCONFDIR/$CFG_TARGET.conf $CFG_SYSCONFDIR/$CFG_TARGET.conf.bak && " . + "cp $CFG_SYSCONFDIR/$CFG_TARGET.conf.new $CFG_SYSCONFDIR/$CFG_TARGET.conf && " . + "rm $CFG_SYSCONFDIR/$CFG_TARGET.conf.new"); + } else { + notice("unable to open configuration file"); + } + } + } +} + +sub error{ + print STDERR "apxs:Error: $_[0].\n"; +} + +sub notice{ + print STDERR "$_[0]\n"; +} + +##EOF## +__DATA__ +## +## Makefile -- Build procedure for sample %NAME% Apache module +## Autogenerated via ``apxs -n %NAME% -g''. +## + +builddir=. +top_srcdir=%PREFIX% +top_builddir=%PREFIX% +include %INSTALLBUILDDIR%/special.mk + +# the used tools +APXS=apxs +APACHECTL=apachectl + +# additional defines, includes and libraries +#DEFS=-Dmy_define=my_value +#INCLUDES=-Imy/include/dir +#LIBS=-Lmy/lib/dir -lmylib + +# the default target +all: local-shared-build + +# install the shared object file into Apache +install: install-modules + +# cleanup +clean: + -rm -f mod_%NAME%.o mod_%NAME%.lo mod_%NAME%.slo mod_%NAME%.la + +# simple test +test: reload + lynx -mime_header http://localhost/%NAME% + +# install and activate shared object by reloading Apache to +# force a reload of the shared object file +reload: install restart + +# the general Apache start/restart/stop +# procedures +start: + $(APACHECTL) start +restart: + $(APACHECTL) restart +stop: + $(APACHECTL) stop + +-=#=- +mod_%NAME%.la: mod_%NAME%.slo + $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_%NAME%.lo +DISTCLEAN_TARGETS = modules.mk +shared = mod_%NAME%.la +-=#=- +/* +** mod_%NAME%.c -- Apache sample %NAME% module +** [Autogenerated via ``apxs -n %NAME% -g''] +** +** To play with this sample module first compile it into a +** DSO file and install it into Apache's modules directory +** by running: +** +** $ apxs -c -i mod_%NAME%.c +** +** Then activate it in Apache's %TARGET%.conf file for instance +** for the URL /%NAME% in as follows: +** +** # %TARGET%.conf +** LoadModule %NAME%_module modules/mod_%NAME%.so +** +** SetHandler %NAME% +** +** +** Then after restarting Apache via +** +** $ apachectl restart +** +** you immediately can request the URL /%NAME% and watch for the +** output of this module. This can be achieved for instance via: +** +** $ lynx -mime_header http://localhost/%NAME% +** +** The output should be similar to the following one: +** +** HTTP/1.1 200 OK +** Date: Tue, 31 Mar 1998 14:42:22 GMT +** Server: Apache/1.3.4 (Unix) +** Connection: close +** Content-Type: text/html +** +** The sample page from mod_%NAME%.c +*/ + +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "ap_config.h" + +/* The sample content handler */ +static int %NAME%_handler(request_rec *r) +{ + if (strcmp(r->handler, "%NAME%")) { + return DECLINED; + } + r->content_type = "text/html"; + + if (!r->header_only) + ap_rputs("The sample page from mod_%NAME%.c\n", r); + return OK; +} + +static void %NAME%_register_hooks(apr_pool_t *p) +{ + ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +/* Dispatch list for API hooks */ +module AP_MODULE_DECLARE_DATA %NAME%_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + %NAME%_register_hooks /* register hooks */ +}; + diff --git a/trunk/support/check_forensic b/trunk/support/check_forensic new file mode 100755 index 0000000000..3c8123fcbb --- /dev/null +++ b/trunk/support/check_forensic @@ -0,0 +1,51 @@ +#!/bin/sh + +# check_forensic + +# check the forensic log for requests that did not complete +# output the request log for each one + +F=$1 + +temp_create_method=file +if test -f `which mktemp`; then + temp_create_method=mktemp +elif test -f `which tempfile`; then + temp_create_method=tempfile +fi + +create_temp() +{ + prefix=$1 + case "$temp_create_method" in + file) + name="/tmp/$1.$$" + ;; + mktemp) + name=`mktemp -t $1.XXXXXX` + ;; + tempfile) + name=`tempfile --prefix=$1` + ;; + *) + echo "$0: Cannot create temporary file" + exit 1 + ;; + esac +} + +create_temp fcall +all=$name +create_temp fcin +in=$name +create_temp fcout +out=$name +trap "rm -f -- \"$all\" \"$in\" \"$out\";" 0 1 2 3 13 15 + +cut -f 1 -d '|' $F > $all +grep + < $all | cut -c2- | sort > $in +grep -- - < $all | cut -c2- | sort > $out + +# use -i instead of -I for GNU xargs +join -v 1 $in $out | xargs -I xx egrep "^\\+xx" $F +exit 0 diff --git a/trunk/support/checkgid.c b/trunk/support/checkgid.c new file mode 100644 index 0000000000..704ac57f23 --- /dev/null +++ b/trunk/support/checkgid.c @@ -0,0 +1,110 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Given one or more group identifers on the command line (e.g., + * "httpd" or "#-1"), figure out whether they'll be valid for + * the server to use at run-time. + * + * If a groupname isn't found, or we can't setgid() to it, return + * -1. If all groups are valid, return 0. + * + * This may need to be run as the superuser for the setgid() to + * succeed; running it as any other user may result in a false + * negative. + */ + +#include "ap_config.h" +#if APR_HAVE_STDIO_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_GRP_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +int main(int argc, char *argv[]) +{ + int i; + int result; + gid_t gid; + struct group *grent; + struct group fake_grent; + + /* + * Assume success. :-) + */ + result = 0; + for (i = 1; i < argc; ++i) { + char *arg; + arg = argv[i]; + + /* + * If it's from a 'Group #-1' statement, get the numeric value + * and skip the group lookup stuff. + */ + if (*arg == '#') { + gid = atoi(&arg[1]); + fake_grent.gr_gid = gid; + grent = &fake_grent; + } + else { + grent = getgrnam(arg); + } + + /* + * A NULL return means no such group was found, so we're done + * with this one. + */ + if (grent == NULL) { + fprintf(stderr, "%s: group '%s' not found\n", argv[0], arg); + result = -1; + } + else { + int check; + + /* + * See if we can switch to the numeric GID we have. If so, + * all well and good; if not, well.. + */ + gid = grent->gr_gid; + check = setgid(gid); + if (check != 0) { + fprintf(stderr, "%s: invalid group '%s'\n", argv[0], arg); + perror(argv[0]); + result = -1; + } + } + } + /* + * Worst-case return value. + */ + return result; +} +/* + * Local Variables: + * mode: C + * c-file-style: "bsd" + * End: + */ diff --git a/trunk/support/config.m4 b/trunk/support/config.m4 new file mode 100644 index 0000000000..cb2322ec8c --- /dev/null +++ b/trunk/support/config.m4 @@ -0,0 +1,104 @@ +htpasswd_LTFLAGS="" +htdigest_LTFLAGS="" +rotatelogs_LTFLAGS="" +logresolve_LTFLAGS="" +htdbm_LTFLAGS="" +ab_LTFLAGS="" +checkgid_LTFLAGS="" + +AC_ARG_ENABLE(static-support,APACHE_HELP_STRING(--enable-static-support,Build a statically linked version of the support binaries),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(htpasswd_LTFLAGS, [-static]) + APR_ADDTO(htdigest_LTFLAGS, [-static]) + APR_ADDTO(rotatelogs_LTFLAGS, [-static]) + APR_ADDTO(logresolve_LTFLAGS, [-static]) + APR_ADDTO(htdbm_LTFLAGS, [-static]) + APR_ADDTO(ab_LTFLAGS, [-static]) + APR_ADDTO(checkgid_LTFLAGS, [-static]) +fi +]) + +AC_ARG_ENABLE(static-htpasswd,APACHE_HELP_STRING(--enable-static-htpasswd,Build a statically linked version of htpasswd),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(htpasswd_LTFLAGS, [-static]) +else + APR_REMOVEFROM(htpasswd_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(htpasswd_LTFLAGS) + +AC_ARG_ENABLE(static-htdigest,APACHE_HELP_STRING(--enable-static-htdigest,Build a statically linked version of htdigest),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(htdigest_LTFLAGS, [-static]) +else + APR_REMOVEFROM(htdigest_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(htdigest_LTFLAGS) + +AC_ARG_ENABLE(static-rotatelogs,APACHE_HELP_STRING(--enable-static-rotatelogs,Build a statically linked version of rotatelogs),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(rotatelogs_LTFLAGS, [-static]) +else + APR_REMOVEFROM(rotatelogs_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(rotatelogs_LTFLAGS) + +AC_ARG_ENABLE(static-logresolve,APACHE_HELP_STRING(--enable-static-logresolve,Build a statically linked version of logresolve),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(logresolve_LTFLAGS, [-static]) +else + APR_REMOVEFROM(logresolve_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(logresolve_LTFLAGS) + +AC_ARG_ENABLE(static-htdbm,APACHE_HELP_STRING(--enable-static-htdbm,Build a statically linked version of htdbm),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(htdbm_LTFLAGS, [-static]) +else + APR_REMOVEFROM(htdbm_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(htdbm_LTFLAGS) + +AC_ARG_ENABLE(static-ab,APACHE_HELP_STRING(--enable-static-ab,Build a statically linked version of ab),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(ab_LTFLAGS, [-static]) +else + APR_REMOVEFROM(ab_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(ab_LTFLAGS) + +AC_ARG_ENABLE(static-checkgid,APACHE_HELP_STRING(--enable-static-checkgid,Build a statically linked version of checkgid),[ +if test "$enableval" = "yes" ; then + APR_ADDTO(checkgid_LTFLAGS, [-static]) +else + APR_REMOVEFROM(checkgid_LTFLAGS, [-static]) +fi +]) +APACHE_SUBST(checkgid_LTFLAGS) + +case $host in + *aix*) + # this works in any locale, unlike the default command below, which + # fails in a non-English locale if the hard limit is unlimited + # since the display of the limit will translate "unlimited", but + # ulimit only accepts English "unlimited" on input + APACHECTL_ULIMIT="ulimit -S -n unlimited" + ;; + *alpha*-dec-osf*) + # Tru64: -H is for setting, not retrieving + APACHECTL_ULIMIT="ulimit -S -n \`ulimit -h -n\`" + ;; + *) + if TMP_ULIMIT=`ulimit -H -n` && ulimit -S -n $TMP_ULIMIT ; then + APACHECTL_ULIMIT="ulimit -S -n \`ulimit -H -n\`" + else + APACHECTL_ULIMIT="" + fi + ;; +esac +APACHE_SUBST(APACHECTL_ULIMIT) diff --git a/trunk/support/dbmmanage.in b/trunk/support/dbmmanage.in new file mode 100644 index 0000000000..2db00afe6c --- /dev/null +++ b/trunk/support/dbmmanage.in @@ -0,0 +1,312 @@ +#!@perlbin@ +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#for more functionality see the HTTPD::UserAdmin module: +# http://www.perl.com/CPAN/modules/by-module/HTTPD/HTTPD-Tools-x.xx.tar.gz +# +# usage: dbmmanage + +package dbmmanage; +# -ldb -lndbm -lgdbm -lsdbm +BEGIN { @AnyDBM_File::ISA = qw(DB_File NDBM_File GDBM_File SDBM_File) } +use strict; +use Fcntl; +use AnyDBM_File (); + +sub usage { + my $cmds = join "|", sort keys %dbmc::; + die <$command(); +untie %DB; + + +my $x; +sub genseed { + my $psf; + if ($not_unix) { + srand (time ^ $$ or time ^ ($$ + ($$ << 15))); + } + else { + for (qw(-xlwwa -le)) { + `ps $_ 2>/dev/null`; + $psf = $_, last unless $?; + } + srand (time ^ $$ ^ unpack("%L*", `ps $psf | gzip -f`)); + } + @range = (qw(. /), '0'..'9','a'..'z','A'..'Z'); + $x = int scalar @range; +} + +sub randchar { + join '', map $range[rand $x], 1..shift||1; +} + +sub saltpw_crypt { + genseed() unless @range; + return $newstyle_salt ? + join '', "_", randchar, "a..", randchar(4) : + randchar(2); +} + +sub cryptpw_crypt { + my ($pw, $salt) = @_; + $salt = saltpw_crypt unless $salt; + crypt $pw, $salt; +} + +sub saltpw_md5 { + genseed() unless @range; + randchar(8); +} + +sub cryptpw_md5 { + my($pw, $salt) = @_; + $salt = saltpw_md5 unless $salt; + Crypt::PasswdMD5::apache_md5_crypt($pw, $salt); +} + +sub cryptpw_sha1 { + my($pw, $salt) = @_; + '{SHA}' . Digest::SHA1::sha1_base64($pw) . "="; +} + +sub cryptpw { + if ($crypt_method eq "md5") { + return cryptpw_md5(@_); + } elsif ($crypt_method eq "sha1") { + return cryptpw_sha1(@_); + } elsif ($crypt_method eq "crypt") { + return cryptpw_crypt(@_); + } + @_[0]; # otherwise return plaintext +} + +sub getpass { + my $prompt = shift || "Enter password:"; + + unless($not_unix) { + open STDIN, "/dev/tty" or warn "couldn't open /dev/tty $!\n"; + system "stty -echo;"; + } + + my($c,$pwd); + print STDERR $prompt; + while (($c = getc(STDIN)) ne '' and $c ne "\n" and $c ne "\r") { + $pwd .= $c; + } + + system "stty echo" unless $not_unix; + print STDERR "\n"; + die "Can't use empty password!\n" unless length $pwd; + return $pwd; +} + +sub dbmc::update { + die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; + $crypted_pwd = (split /:/, $DB{$key}, 3)[0] if $crypted_pwd eq '.'; + $groups = (split /:/, $DB{$key}, 3)[1] if !$groups || $groups eq '.'; + $comment = (split /:/, $DB{$key}, 3)[2] if !$comment || $comment eq '.'; + if (!$crypted_pwd || $crypted_pwd eq '-') { + dbmc->adduser; + } + else { + dbmc->add; + } +} + +sub dbmc::add { + die "Can't use empty password!\n" unless $crypted_pwd; + unless($is_update) { + die "Sorry, user `$key' already exists!\n" if $DB{$key}; + } + $groups = '' if $groups eq '-'; + $comment = '' if $comment eq '-'; + $groups .= ":" . $comment if $comment; + $crypted_pwd .= ":" . $groups if $groups; + $DB{$key} = $crypted_pwd; + my $action = $is_update ? "updated" : "added"; + print "User $key $action with password encrypted to $DB{$key} using $crypt_method\n"; +} + +sub dbmc::adduser { + my $value = getpass "New password:"; + die "They don't match, sorry.\n" unless getpass("Re-type new password:") eq $value; + $crypted_pwd = cryptpw $value; + dbmc->add; +} + +sub dbmc::delete { + die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; + delete $DB{$key}, print "`$key' deleted\n"; +} + +sub dbmc::view { + print $key ? "$key:$DB{$key}\n" : map { "$_:$DB{$_}\n" if $DB{$_} } keys %DB; +} + +sub dbmc::check { + die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; + my $chkpass = (split /:/, $DB{$key}, 3)[0]; + my $testpass = getpass(); + if (substr($chkpass, 0, 6) eq '$apr1$') { + need_md5_crypt; + $crypt_method = "md5"; + } elsif (substr($chkpass, 0, 5) eq '{SHA}') { + need_sha1_crypt; + $crypt_method = "sha1"; + } elsif (length($chkpass) == 13 && $chkpass ne $testpass) { + $crypt_method = "crypt"; + } else { + $crypt_method = "plain"; + } + print $crypt_method . (cryptpw($testpass, $chkpass) eq $chkpass + ? " password ok\n" : " password mismatch\n"); +} + +sub dbmc::import { + while(defined($_ = ) and chomp) { + ($key,$crypted_pwd,$groups,$comment) = split /:/, $_, 4; + dbmc->add; + } +} + diff --git a/trunk/support/envvars-std.in b/trunk/support/envvars-std.in new file mode 100644 index 0000000000..762231c92b --- /dev/null +++ b/trunk/support/envvars-std.in @@ -0,0 +1,24 @@ +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# envvars-std - default environment variables for apachectl +# +# This file is generated from envvars-std.in +# +@SHLIBPATH_VAR@="@exp_libdir@:$@SHLIBPATH_VAR@" +export @SHLIBPATH_VAR@ +# +@OS_SPECIFIC_VARS@ diff --git a/trunk/support/htcacheclean.c b/trunk/support/htcacheclean.c new file mode 100644 index 0000000000..39294cf23b --- /dev/null +++ b/trunk/support/htcacheclean.c @@ -0,0 +1,1031 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * htcacheclean.c: simple program for cleaning of + * the disk cache of the Apache HTTP server + * + * Contributed by Andreas Steinmetz + * 8 Oct 2004 + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_file_info.h" +#include "apr_pools.h" +#include "apr_hash.h" +#include "apr_thread_proc.h" +#include "apr_signal.h" +#include "apr_getopt.h" +#include "apr_ring.h" +#include "apr_date.h" + +#if APR_HAVE_UNISTD_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif + +/* mod_disk_cache.c extract start */ + +#define DISK_FORMAT_VERSION 0 +typedef struct { + /* Indicates the format of the header struct stored on-disk. */ + int format; + /* The HTTP status code returned for this response. */ + int status; + /* The size of the entity name that follows. */ + apr_size_t name_len; + /* The number of times we've cached this entity. */ + apr_size_t entity_version; + /* Miscellaneous time values. */ + apr_time_t date; + apr_time_t expire; + apr_time_t request_time; + apr_time_t response_time; +} disk_cache_info_t; + +#define CACHE_HEADER_SUFFIX ".header" +#define CACHE_DATA_SUFFIX ".data" +/* mod_disk_cache.c extract end */ + +/* mod_disk_cache.c related definitions start */ + +/* + * this is based on #define AP_TEMPFILE "/aptmpXXXXXX" + * + * the above definition could be reworked into the following: + * + * #define AP_TEMPFILE_PREFIX "/" + * #define AP_TEMPFILE_BASE "aptmp" + * #define AP_TEMPFILE_SUFFIX "XXXXXX" + * #define AP_TEMPFILE_BASELEN strlen(AP_TEMPFILE_BASE) + * #define AP_TEMPFILE_NAMELEN strlen(AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX) + * #define AP_TEMPFILE AP_TEMPFILE_PREFIX AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX + * + * these definitions would then match the definitions below: + */ + +#define AP_TEMPFILE_BASE "aptmp" +#define AP_TEMPFILE_SUFFIX "XXXXXX" +#define AP_TEMPFILE_BASELEN strlen(AP_TEMPFILE_BASE) +#define AP_TEMPFILE_NAMELEN strlen(AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX) + +/* mod_disk_cache.c related definitions end */ + +/* define the following for debugging */ +#undef DEBUG + +/* + * Note: on Linux delays <= 2ms are busy waits without + * scheduling, so never use a delay <= 2ms below + */ + +#define NICE_DELAY 10000 /* usecs */ +#define DELETE_NICE 10 /* be nice after this amount of delete ops */ +#define STAT_ATTEMPTS 10 /* maximum stat attempts for a file */ +#define STAT_DELAY 5000 /* usecs */ +#define HEADER 1 /* headers file */ +#define DATA 2 /* body file */ +#define TEMP 4 /* temporary file */ +#define HEADERDATA (HEADER|DATA) +#define MAXDEVIATION 3600 /* secs */ +#define SECS_PER_MIN 60 +#define KBYTE 1024 +#define MBYTE 1048576 + +#define DIRINFO (APR_FINFO_MTIME|APR_FINFO_SIZE|APR_FINFO_TYPE|APR_FINFO_LINK) + +typedef struct _direntry { + APR_RING_ENTRY(_direntry) link; + int type; /* type of file/fileset: TEMP, HEADER, DATA, HEADERDATA */ + apr_time_t htime; /* headers file modification time */ + apr_time_t dtime; /* body file modification time */ + apr_off_t hsize; /* headers file size */ + apr_off_t dsize; /* body or temporary file size */ + char *basename; /* file/fileset base name */ +} DIRENTRY; + +typedef struct _entry { + APR_RING_ENTRY(_entry) link; + apr_time_t expire; /* cache entry exiration time */ + apr_time_t response_time; /* cache entry time of last response to client */ + apr_time_t htime; /* headers file modification time */ + apr_time_t dtime; /* body file modification time */ + apr_off_t hsize; /* headers file size */ + apr_off_t dsize; /* body or temporary file size */ + char *basename; /* fileset base name */ +} ENTRY; + + +static int delcount; /* file deletion count for nice mode */ +static int interrupted; /* flag: true if SIGINT or SIGTERM occurred */ +static int realclean; /* flag: true means user said apache is not running */ +static int verbose; /* flag: true means print statistics */ +static int benice; /* flag: true means nice mode is activated */ +static int dryrun; /* flag: true means dry run, don't actually delete + anything */ +static int baselen; /* string length of the path to the proxy directory */ +static apr_time_t now; /* start time of this processing run */ + +static apr_file_t *errfile; /* stderr file handle */ +static apr_off_t unsolicited; /* file size summary for deleted unsolicited + files */ +static APR_RING_ENTRY(_entry) root; /* ENTRY ring anchor */ + +/* short program name as called */ +static const char *shortname = "htcacheclean"; + +#ifdef DEBUG +/* + * fake delete for debug purposes + */ +#define apr_file_remove fake_file_remove +static void fake_file_remove(char *pathname, apr_pool_t *p) +{ + apr_finfo_t info; + + /* stat and printing to simulate some deletion system load and to + display what would actually have happened */ + apr_stat(&info, pathname, DIRINFO, p); + apr_file_printf(errfile, "would delete %s" APR_EOL_STR, pathname); +} +#endif + +/* + * called on SIGINT or SIGTERM + */ +static void setterm(int unused) +{ +#ifdef DEBUG + apr_file_printf(errfile, "interrupt" APR_EOL_STR); +#endif + interrupted = 1; +} + +/* + * called in out of memory condition + */ +static int oom(int unused) +{ + static int called = 0; + + /* be careful to call exit() only once */ + if (!called) { + called = 1; + exit(1); + } + return APR_ENOMEM; +} + +/* + * print purge statistics + */ +static void printstats(apr_off_t total, apr_off_t sum, apr_off_t max, + apr_off_t etotal, apr_off_t entries) +{ + char ttype, stype, mtype, utype; + apr_off_t tfrag, sfrag, ufrag; + + if (!verbose) { + return; + } + + ttype = 'K'; + tfrag = ((total * 10) / KBYTE) % 10; + total /= KBYTE; + if (total >= KBYTE) { + ttype = 'M'; + tfrag = ((total * 10) / KBYTE) % 10; + total /= KBYTE; + } + + stype = 'K'; + sfrag = ((sum * 10) / KBYTE) % 10; + sum /= KBYTE; + if (sum >= KBYTE) { + stype = 'M'; + sfrag = ((sum * 10) / KBYTE) % 10; + sum /= KBYTE; + } + + mtype = 'K'; + max /= KBYTE; + if (max >= KBYTE) { + mtype = 'M'; + max /= KBYTE; + } + + apr_file_printf(errfile, "Statistics:" APR_EOL_STR); + if (unsolicited) { + utype = 'K'; + ufrag = ((unsolicited * 10) / KBYTE) % 10; + unsolicited /= KBYTE; + if (unsolicited >= KBYTE) { + utype = 'M'; + ufrag = ((unsolicited * 10) / KBYTE) % 10; + unsolicited /= KBYTE; + } + if (!unsolicited && !ufrag) { + ufrag = 1; + } + apr_file_printf(errfile, "unsolicited size %d.%d%c" APR_EOL_STR, + (int)(unsolicited), (int)(ufrag), utype); + } + apr_file_printf(errfile, "size limit %d.0%c" APR_EOL_STR, + (int)(max), mtype); + apr_file_printf(errfile, "total size was %d.%d%c, total size now " + "%d.%d%c" APR_EOL_STR, + (int)(total), (int)(tfrag), ttype, (int)(sum), + (int)(sfrag), stype); + apr_file_printf(errfile, "total entries was %d, total entries now %d" + APR_EOL_STR, (int)(etotal), (int)(entries)); +} + +/* + * delete a single file + */ +static void delete_file(char *path, char *basename, apr_pool_t *pool) +{ + char *nextpath; + apr_pool_t *p; + + if (dryrun) { + return; + } + + /* temp pool, otherwise lots of memory could be allocated */ + apr_pool_create(&p, pool); + nextpath = apr_pstrcat(p, path, "/", basename, NULL); + apr_file_remove(nextpath, p); + apr_pool_destroy(p); + + if (benice) { + if (++delcount >= DELETE_NICE) { + apr_sleep(NICE_DELAY); + delcount = 0; + } + } +} + +/* + * delete cache file set + */ +static void delete_entry(char *path, char *basename, apr_pool_t *pool) +{ + char *nextpath; + apr_pool_t *p; + + if (dryrun) { + return; + } + + /* temp pool, otherwise lots of memory could be allocated */ + apr_pool_create(&p, pool); + + nextpath = apr_pstrcat(p, path, "/", basename, CACHE_HEADER_SUFFIX, NULL); + apr_file_remove(nextpath, p); + + nextpath = apr_pstrcat(p, path, "/", basename, CACHE_DATA_SUFFIX, NULL); + apr_file_remove(nextpath, p); + + apr_pool_destroy(p); + + if (benice) { + delcount += 2; + if (delcount >= DELETE_NICE) { + apr_sleep(NICE_DELAY); + delcount = 0; + } + } +} + +/* + * walk the cache directory tree + */ +static int process_dir(char *path, apr_pool_t *pool) +{ + apr_dir_t *dir; + apr_pool_t *p; + apr_hash_t *h; + apr_hash_index_t *i; + apr_file_t *fd; + apr_status_t status; + apr_finfo_t info; + apr_size_t len; + apr_time_t current, deviation; + char *nextpath, *base, *ext; + APR_RING_ENTRY(_direntry) anchor; + DIRENTRY *d, *t, *n; + ENTRY *e; + int skip, retries; + disk_cache_info_t disk_info; + + APR_RING_INIT(&anchor, _direntry, link); + apr_pool_create(&p, pool); + h = apr_hash_make(p); + fd = NULL; + skip = 0; + deviation = MAXDEVIATION * APR_USEC_PER_SEC; + + if (apr_dir_open(&dir, path, p) != APR_SUCCESS) { + return 1; + } + + while (apr_dir_read(&info, 0, dir) == APR_SUCCESS && !interrupted) { + if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) { + continue; + } + d = apr_pcalloc(p, sizeof(DIRENTRY)); + d->basename = apr_pstrcat(p, path, "/", info.name, NULL); + APR_RING_INSERT_TAIL(&anchor, d, _direntry, link); + } + + apr_dir_close(dir); + + if (interrupted) { + return 1; + } + + skip = baselen + 1; + + for (d = APR_RING_FIRST(&anchor); + !interrupted && d != APR_RING_SENTINEL(&anchor, _direntry, link); + d=n) { + n = APR_RING_NEXT(d, link); + base = strrchr(d->basename, '/'); + if (!base++) { + base = d->basename; + } + ext = strchr(base, '.'); + + /* there may be temporary files which may be gone before + * processing, always skip these if not in realclean mode + */ + if (!ext && !realclean) { + if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN) + && strlen(base) == AP_TEMPFILE_NAMELEN) { + continue; + } + } + + /* this may look strange but apr_stat() may return errno which + * is system dependent and there may be transient failures, + * so just blindly retry for a short while + */ + retries = STAT_ATTEMPTS; + status = APR_SUCCESS; + do { + if (status != APR_SUCCESS) { + apr_sleep(STAT_DELAY); + } + status = apr_stat(&info, d->basename, DIRINFO, p); + } while (status != APR_SUCCESS && !interrupted && --retries); + + /* what may happen here is that apache did create a file which + * we did detect but then does delete the file before we can + * get file information, so if we don't get any file information + * we will ignore the file in this case + */ + if (status != APR_SUCCESS) { + if (!realclean && !interrupted) { + continue; + } + return 1; + } + + if (info.filetype == APR_DIR) { + if (process_dir(d->basename, pool)) { + return 1; + } + continue; + } + + if (info.filetype != APR_REG) { + continue; + } + + if (!ext) { + if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN) + && strlen(base) == AP_TEMPFILE_NAMELEN) { + d->basename += skip; + d->type = TEMP; + d->dsize = info.size; + apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); + } + continue; + } + + if (!strcasecmp(ext, CACHE_HEADER_SUFFIX)) { + *ext = '\0'; + d->basename += skip; + /* if a user manually creates a '.header' file */ + if (d->basename[0] == '\0') { + continue; + } + t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING); + if (t) { + d = t; + } + d->type |= HEADER; + d->htime = info.mtime; + d->hsize = info.size; + apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); + continue; + } + + if (!strcasecmp(ext, CACHE_DATA_SUFFIX)) { + *ext = '\0'; + d->basename += skip; + /* if a user manually creates a '.data' file */ + if (d->basename[0] == '\0') { + continue; + } + t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING); + if (t) { + d = t; + } + d->type |= DATA; + d->dtime = info.mtime; + d->dsize = info.size; + apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); + } + } + + if (interrupted) { + return 1; + } + + path[baselen] = '\0'; + + for (i = apr_hash_first(p, h); i && !interrupted; i = apr_hash_next(i)) { + void *hvalue; + + apr_hash_this(i, NULL, NULL, &hvalue); + d = hvalue; + + switch(d->type) { + case HEADERDATA: + nextpath = apr_pstrcat(p, path, "/", d->basename, + CACHE_HEADER_SUFFIX, NULL); + if (apr_file_open(&fd, nextpath, APR_READ, APR_OS_DEFAULT, + p) == APR_SUCCESS) { + len = sizeof(disk_cache_info_t); + if (apr_file_read_full(fd, &disk_info, len, + &len) == APR_SUCCESS) { + apr_file_close(fd); + if (disk_info.format == DISK_FORMAT_VERSION) { + e = apr_palloc(pool, sizeof(ENTRY)); + APR_RING_INSERT_TAIL(&root, e, _entry, link); + e->expire = disk_info.expire; + e->response_time = disk_info.response_time; + e->htime = d->htime; + e->dtime = d->dtime; + e->hsize = d->hsize; + e->dsize = d->dsize; + e->basename = apr_palloc(pool, + strlen(d->basename) + 1); + strcpy(e->basename, d->basename); + break; + } + } + else { + apr_file_close(fd); + } + } + /* we have a somehow unreadable headers file which is associated + * with a data file. this may be caused by apache currently + * rewriting the headers file. thus we may delete the file set + * either in realclean mode or if the headers file modification + * timestamp is not within a specified positive or negative offset + * to the current time. + */ + current = apr_time_now(); + if (realclean || d->htime < current - deviation + || d->htime > current + deviation) { + delete_entry(path, d->basename, p); + unsolicited += d->hsize; + unsolicited += d->dsize; + } + break; + + /* single data and header files may be deleted either in realclean + * mode or if their modification timestamp is not within a + * specified positive or negative offset to the current time. + * this handling is necessary due to possible race conditions + * between apache and this process + */ + case HEADER: + current = apr_time_now(); + if (realclean || d->htime < current - deviation + || d->htime > current + deviation) { + delete_entry(path, d->basename, p); + unsolicited += d->hsize; + } + break; + + case DATA: + current = apr_time_now(); + if (realclean || d->dtime < current - deviation + || d->dtime > current + deviation) { + delete_entry(path, d->basename, p); + unsolicited += d->dsize; + } + break; + + /* temp files may only be deleted in realclean mode which + * is asserted above if a tempfile is in the hash array + */ + case TEMP: + delete_file(path, d->basename, p); + unsolicited += d->dsize; + break; + } + } + + if (interrupted) { + return 1; + } + + apr_pool_destroy(p); + + if (benice) { + apr_sleep(NICE_DELAY); + } + + if (interrupted) { + return 1; + } + + return 0; +} + +/* + * purge cache entries + */ +static void purge(char *path, apr_pool_t *pool, apr_off_t max) +{ + apr_off_t sum, total, entries, etotal; + ENTRY *e, *n, *oldest; + + sum = 0; + entries = 0; + + for (e = APR_RING_FIRST(&root); + e != APR_RING_SENTINEL(&root, _entry, link); + e = APR_RING_NEXT(e, link)) { + sum += e->hsize; + sum += e->dsize; + entries++; + } + + total = sum; + etotal = entries; + + if (sum <= max) { + printstats(total, sum, max, etotal, entries); + return; + } + + /* process all entries with a timestamp in the future, this may + * happen if a wrong system time is corrected + */ + + for (e = APR_RING_FIRST(&root); + e != APR_RING_SENTINEL(&root, _entry, link) && !interrupted;) { + n = APR_RING_NEXT(e, link); + if (e->response_time > now || e->htime > now || e->dtime > now) { + delete_entry(path, e->basename, pool); + sum -= e->hsize; + sum -= e->dsize; + entries--; + APR_RING_REMOVE(e, link); + if (sum <= max) { + if (!interrupted) { + printstats(total, sum, max, etotal, entries); + } + return; + } + } + e = n; + } + + if (interrupted) { + return; + } + + /* process all entries with are expired */ + for (e = APR_RING_FIRST(&root); + e != APR_RING_SENTINEL(&root, _entry, link) && !interrupted;) { + n = APR_RING_NEXT(e, link); + if (e->expire != APR_DATE_BAD && e->expire < now) { + delete_entry(path, e->basename, pool); + sum -= e->hsize; + sum -= e->dsize; + entries--; + APR_RING_REMOVE(e, link); + if (sum <= max) { + if (!interrupted) { + printstats(total, sum, max, etotal, entries); + } + return; + } + } + e = n; + } + + if (interrupted) { + return; + } + + /* process remaining entries oldest to newest, the check for an emtpy + * ring actually isn't necessary except when the compiler does + * corrupt 64bit arithmetics which happend to me once, so better safe + * than sorry + */ + while (sum > max && !interrupted && !APR_RING_EMPTY(&root, _entry, link)) { + oldest = APR_RING_FIRST(&root); + + for (e = APR_RING_NEXT(oldest, link); + e != APR_RING_SENTINEL(&root, _entry, link); + e = APR_RING_NEXT(e, link)) { + if (e->dtime < oldest->dtime) { + oldest = e; + } + } + + delete_entry(path, oldest->basename, pool); + sum -= oldest->hsize; + sum -= oldest->dsize; + entries--; + APR_RING_REMOVE(oldest, link); + } + + if (!interrupted) { + printstats(total, sum, max, etotal, entries); + } +} + +/* + * usage info + */ +#define NL APR_EOL_STR +static void usage(void) +{ + apr_file_printf(errfile, + "%s -- program for cleaning the disk cache." NL + "Usage: %s [-Dvrn] -pPATH -lLIMIT" NL + " %s [-ni] -dINTERVAL -pPATH -lLIMIT" NL + NL + "Options:" NL + " -d Daemonize and repeat cache cleaning every INTERVAL minutes." NL + " This option is mutually exclusive with the -D, -v and -r" NL + " options." NL + NL + " -D Do a dry run and don't delete anything. This option is mutually" NL + " exclusive with the -d option." NL + NL + " -v Be verbose and print statistics. This option is mutually" NL + " exclusive with the -d option." NL + NL + " -r Clean thoroughly. This assumes that the Apache web server is " NL + " not running. This option is mutually exclusive with the -d" NL + " option." NL + NL + " -n Be nice. This causes slower processing in favour of other" NL + " processes." NL + NL + " -p Specify PATH as the root directory of the disk cache." NL + NL + " -l Specify LIMIT as the total disk cache size limit. Attach 'K'" NL + " or 'M' to the number for specifying KBytes or MBytes." NL + NL + " -i Be intelligent and run only when there was a modification of" NL + " the disk cache. This option is only possible together with the" NL + " -d option." NL, + shortname, + shortname, + shortname + ); + + exit(1); +} +#undef NL + +/* + * main + */ +int main(int argc, const char * const argv[]) +{ + apr_off_t max; + apr_time_t current, repeat, delay, previous; + apr_status_t status; + apr_pool_t *pool, *instance; + apr_getopt_t *o; + apr_finfo_t info; + int retries, isdaemon, limit_found, intelligent, dowork; + char opt; + const char *arg; + char *proxypath, *path; + + interrupted = 0; + repeat = 0; + isdaemon = 0; + dryrun = 0; + limit_found = 0; + max = 0; + verbose = 0; + realclean = 0; + benice = 0; + intelligent = 0; + previous = 0; /* avoid compiler warning */ + proxypath = NULL; + + if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) { + return 1; + } + atexit(apr_terminate); + + if (argc) { + shortname = apr_filepath_name_get(argv[0]); + } + + if (apr_pool_create(&pool, NULL) != APR_SUCCESS) { + return 1; + } + apr_pool_abort_set(oom, pool); + apr_file_open_stderr(&errfile, pool); + apr_signal(SIGINT, setterm); + apr_signal(SIGTERM, setterm); + + apr_getopt_init(&o, pool, argc, argv); + + while (1) { + status = apr_getopt(o, "iDnvrd:l:L:p:", &opt, &arg); + if (status == APR_EOF) { + break; + } + else if (status != APR_SUCCESS) { + usage(); + } + else { + switch (opt) { + case 'i': + if (intelligent) { + usage(); + } + intelligent = 1; + break; + + case 'D': + if (dryrun) { + usage(); + } + dryrun = 1; + break; + + case 'n': + if (benice) { + usage(); + } + benice = 1; + break; + + case 'v': + if (verbose) { + usage(); + } + verbose = 1; + break; + + case 'r': + if (realclean) { + usage(); + } + realclean = 1; + break; + + case 'd': + if (isdaemon) { + usage(); + } + isdaemon = 1; + repeat = apr_atoi64(arg); + repeat *= SECS_PER_MIN; + repeat *= APR_USEC_PER_SEC; + break; + + case 'l': + if (limit_found) { + usage(); + } + limit_found = 1; + + do { + apr_status_t rv; + char *end; + + rv = apr_strtoff(&max, arg, &end, 10); + if (rv == APR_SUCCESS) { + if ((*end == 'K' || *end == 'k') && !end[1]) { + max *= KBYTE; + } + else if ((*end == 'M' || *end == 'm') && !end[1]) { + max *= MBYTE; + } + else if (*end && /* neither empty nor [Bb] */ + ((*end != 'B' && *end != 'b') || end[1])) { + rv = APR_EGENERAL; + } + } + if (rv != APR_SUCCESS) { + apr_file_printf(errfile, "Invalid limit: %s" + APR_EOL_STR APR_EOL_STR, arg); + usage(); + } + } while(0); + break; + + case 'p': + if (proxypath) { + usage(); + } + proxypath = apr_pstrdup(pool, arg); + if (apr_filepath_set(proxypath, pool) != APR_SUCCESS) { + usage(); + } + break; + } /* switch */ + } /* else */ + } /* while */ + + if (o->ind != argc) { + usage(); + } + + if (isdaemon && (repeat <= 0 || verbose || realclean || dryrun)) { + usage(); + } + + if (!isdaemon && intelligent) { + usage(); + } + + if (!proxypath || max <= 0) { + usage(); + } + + if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) { + usage(); + } + baselen = strlen(path); + +#ifndef DEBUG + if (isdaemon) { + apr_file_close(errfile); + apr_proc_detach(APR_PROC_DETACH_DAEMONIZE); + } +#endif + + do { + apr_pool_create(&instance, pool); + + now = apr_time_now(); + APR_RING_INIT(&root, _entry, link); + delcount = 0; + unsolicited = 0; + dowork = 0; + + switch (intelligent) { + case 0: + dowork = 1; + break; + + case 1: + retries = STAT_ATTEMPTS; + status = APR_SUCCESS; + + do { + if (status != APR_SUCCESS) { + apr_sleep(STAT_DELAY); + } + status = apr_stat(&info, path, APR_FINFO_MTIME, instance); + } while (status != APR_SUCCESS && !interrupted && --retries); + + if (status == APR_SUCCESS) { + previous = info.mtime; + intelligent = 2; + } + dowork = 1; + break; + + case 2: + retries = STAT_ATTEMPTS; + status = APR_SUCCESS; + + do { + if (status != APR_SUCCESS) { + apr_sleep(STAT_DELAY); + } + status = apr_stat(&info, path, APR_FINFO_MTIME, instance); + } while (status != APR_SUCCESS && !interrupted && --retries); + + if (status == APR_SUCCESS) { + if (previous != info.mtime) { + dowork = 1; + } + previous = info.mtime; + break; + } + intelligent = 1; + dowork = 1; + break; + } + + if (dowork && !interrupted) { + if (!process_dir(path, instance) && !interrupted) { + purge(path, instance, max); + } + else if (!isdaemon && !interrupted) { + apr_file_printf(errfile, "An error occurred, cache cleaning " + "aborted." APR_EOL_STR); + return 1; + } + + if (intelligent && !interrupted) { + retries = STAT_ATTEMPTS; + status = APR_SUCCESS; + do { + if (status != APR_SUCCESS) { + apr_sleep(STAT_DELAY); + } + status = apr_stat(&info, path, APR_FINFO_MTIME, instance); + } while (status != APR_SUCCESS && !interrupted && --retries); + + if (status == APR_SUCCESS) { + previous = info.mtime; + intelligent = 2; + } + else { + intelligent = 1; + } + } + } + + apr_pool_destroy(instance); + + current = apr_time_now(); + if (current < now) { + delay = repeat; + } + else if (current - now >= repeat) { + delay = repeat; + } + else { + delay = now + repeat - current; + } + + /* we can't sleep the whole delay time here apiece as this is racy + * with respect to interrupt delivery - think about what happens + * if we have tested for an interrupt, then get scheduled + * before the apr_sleep() call and while waiting for the cpu + * we do get an interrupt + */ + if (isdaemon) { + while (delay && !interrupted) { + if (delay > APR_USEC_PER_SEC) { + apr_sleep(APR_USEC_PER_SEC); + delay -= APR_USEC_PER_SEC; + } + else { + apr_sleep(delay); + delay = 0; + } + } + } + } while (isdaemon && !interrupted); + + if (!isdaemon && interrupted) { + apr_file_printf(errfile, "Cache cleaning aborted due to user " + "request." APR_EOL_STR); + return 1; + } + + return 0; +} diff --git a/trunk/support/htdbm.c b/trunk/support/htdbm.c new file mode 100644 index 0000000000..69c0d2db82 --- /dev/null +++ b/trunk/support/htdbm.c @@ -0,0 +1,582 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * htdbm.c: simple program for manipulating DBM + * password databases for the Apache HTTP server + * + * Contributed by Mladen Turk + * 12 Oct 2001 + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_file_io.h" +#include "apr_file_info.h" +#include "apr_pools.h" +#include "apr_signal.h" +#include "apr_md5.h" +#include "apr_sha1.h" +#include "apr_dbm.h" + +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif +#if APR_HAVE_STRINGS_H +#include +#endif +#include + +#if APR_CHARSET_EBCDIC +#include "apr_xlate.h" +#endif /*APR_CHARSET_EBCDIC*/ + +#if APR_HAVE_CRYPT_H +#include +#endif + + +#if !APR_CHARSET_EBCDIC +#define LF 10 +#define CR 13 +#else /*APR_CHARSET_EBCDIC*/ +#define LF '\n' +#define CR '\r' +#endif /*APR_CHARSET_EBCDIC*/ + +#define MAX_STRING_LEN 256 +#define ALG_PLAIN 0 +#define ALG_APMD5 1 +#define ALG_APSHA 2 + +#if APR_HAVE_CRYPT_H +#define ALG_CRYPT 3 +#endif + + +#define ERR_FILEPERM 1 +#define ERR_SYNTAX 2 +#define ERR_PWMISMATCH 3 +#define ERR_INTERRUPTED 4 +#define ERR_OVERFLOW 5 +#define ERR_BADUSER 6 +#define ERR_EMPTY 7 + + +typedef struct htdbm_t htdbm_t; + +struct htdbm_t { + apr_dbm_t *dbm; + apr_pool_t *pool; +#if APR_CHARSET_EBCDIC + apr_xlate_t *to_ascii; +#endif + char *filename; + char *username; + char *userpass; + char *comment; + char *type; + int create; + int rdonly; + int alg; +}; + + +#define HTDBM_MAKE 0 +#define HTDBM_DELETE 1 +#define HTDBM_VERIFY 2 +#define HTDBM_LIST 3 +#define HTDBM_NOFILE 4 +#define HTDBM_STDIN 5 + +static void terminate(void) +{ + apr_terminate(); +#ifdef NETWARE + pressanykey(); +#endif +} + +static void htdbm_terminate(htdbm_t *htdbm) +{ + if (htdbm->dbm) + apr_dbm_close(htdbm->dbm); + htdbm->dbm = NULL; +} + +static htdbm_t *h; + +static void htdbm_interrupted(void) +{ + htdbm_terminate(h); + fprintf(stderr, "htdbm Interrupted !\n"); + exit(ERR_INTERRUPTED); +} + +static apr_status_t htdbm_init(apr_pool_t **pool, htdbm_t **hdbm) +{ + +#if APR_CHARSET_EBCDIC + apr_status_t rv; +#endif + + apr_pool_create( pool, NULL); + apr_signal(SIGINT, (void (*)(int)) htdbm_interrupted); + + (*hdbm) = (htdbm_t *)apr_pcalloc(*pool, sizeof(htdbm_t)); + (*hdbm)->pool = *pool; + +#if APR_CHARSET_EBCDIC + rv = apr_xlate_open(&((*hdbm)->to_ascii), "ISO-8859-1", APR_DEFAULT_CHARSET, (*hdbm)->pool); + if (rv) { + fprintf(stderr, "apr_xlate_open(to ASCII)->%d\n", rv); + return APR_EGENERAL; + } + rv = apr_SHA1InitEBCDIC((*hdbm)->to_ascii); + if (rv) { + fprintf(stderr, "apr_SHA1InitEBCDIC()->%d\n", rv); + return APR_EGENERAL; + } + rv = apr_MD5InitEBCDIC((*hdbm)->to_ascii); + if (rv) { + fprintf(stderr, "apr_MD5InitEBCDIC()->%d\n", rv); + return APR_EGENERAL; + } +#endif /*APR_CHARSET_EBCDIC*/ + + /* Set MD5 as default */ + (*hdbm)->alg = ALG_APMD5; + (*hdbm)->type = "default"; + return APR_SUCCESS; +} + +static apr_status_t htdbm_open(htdbm_t *htdbm) +{ + if (htdbm->create) + return apr_dbm_open_ex(&htdbm->dbm, htdbm->type, htdbm->filename, APR_DBM_RWCREATE, + APR_OS_DEFAULT, htdbm->pool); + else + return apr_dbm_open_ex(&htdbm->dbm, htdbm->type, htdbm->filename, + htdbm->rdonly ? APR_DBM_READONLY : APR_DBM_READWRITE, + APR_OS_DEFAULT, htdbm->pool); +} + +static apr_status_t htdbm_save(htdbm_t *htdbm, int *changed) +{ + apr_datum_t key, val; + + if (!htdbm->username) + return APR_SUCCESS; + + key.dptr = htdbm->username; + key.dsize = strlen(htdbm->username); + if (apr_dbm_exists(htdbm->dbm, key)) + *changed = 1; + + val.dsize = strlen(htdbm->userpass); + if (!htdbm->comment) + val.dptr = htdbm->userpass; + else { + val.dptr = apr_pstrcat(htdbm->pool, htdbm->userpass, ":", + htdbm->comment, NULL); + val.dsize += (strlen(htdbm->comment) + 1); + } + return apr_dbm_store(htdbm->dbm, key, val); +} + +static apr_status_t htdbm_del(htdbm_t *htdbm) +{ + apr_datum_t key; + + key.dptr = htdbm->username; + key.dsize = strlen(htdbm->username); + if (!apr_dbm_exists(htdbm->dbm, key)) + return APR_ENOENT; + + return apr_dbm_delete(htdbm->dbm, key); +} + +static apr_status_t htdbm_verify(htdbm_t *htdbm) +{ + apr_datum_t key, val; + char pwd[MAX_STRING_LEN] = {0}; + char *rec, *cmnt; + + key.dptr = htdbm->username; + key.dsize = strlen(htdbm->username); + if (!apr_dbm_exists(htdbm->dbm, key)) + return APR_ENOENT; + if (apr_dbm_fetch(htdbm->dbm, key, &val) != APR_SUCCESS) + return APR_ENOENT; + rec = apr_pstrndup(htdbm->pool, val.dptr, val.dsize); + cmnt = strchr(rec, ';'); + if (cmnt) + strncpy(pwd, rec, cmnt - rec); + else + strcpy(pwd, rec); + return apr_password_validate(htdbm->userpass, pwd); +} + +static apr_status_t htdbm_list(htdbm_t *htdbm) +{ + apr_status_t rv; + apr_datum_t key, val; + char *rec, *cmnt; + char kb[MAX_STRING_LEN]; + int i = 0; + + rv = apr_dbm_firstkey(htdbm->dbm, &key); + if (rv != APR_SUCCESS) { + fprintf(stderr, "Empty database -- %s\n", htdbm->filename); + return APR_ENOENT; + } + rec = apr_pcalloc(htdbm->pool, HUGE_STRING_LEN); + + fprintf(stderr, "Dumping records from database -- %s\n", htdbm->filename); + fprintf(stderr, " %-32sComment\n", "Username"); + while (key.dptr != NULL) { + rv = apr_dbm_fetch(htdbm->dbm, key, &val); + if (rv != APR_SUCCESS) { + fprintf(stderr, "Failed getting data from %s\n", htdbm->filename); + return APR_EGENERAL; + } + strncpy(kb, key.dptr, key.dsize); + kb[key.dsize] = '\0'; + fprintf(stderr, " %-32s", kb); + strncpy(rec, val.dptr, val.dsize); + rec[val.dsize] = '\0'; + cmnt = strchr(rec, ':'); + if (cmnt) + fprintf(stderr, "%s", cmnt + 1); + fprintf(stderr, "\n"); + rv = apr_dbm_nextkey(htdbm->dbm, &key); + if (rv != APR_SUCCESS) + fprintf(stderr, "Failed getting NextKey\n"); + ++i; + } + + fprintf(stderr, "Total #records : %d\n", i); + return APR_SUCCESS; +} + +static void to64(char *s, unsigned long v, int n) +{ + static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +static apr_status_t htdbm_make(htdbm_t *htdbm) +{ + char cpw[MAX_STRING_LEN]; + char salt[9]; + + switch (htdbm->alg) { + case ALG_APSHA: + /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */ + apr_sha1_base64(htdbm->userpass,strlen(htdbm->userpass),cpw); + break; + + case ALG_APMD5: + (void) srand((int) time((time_t *) NULL)); + to64(&salt[0], rand(), 8); + salt[8] = '\0'; + apr_md5_encode((const char *)htdbm->userpass, (const char *)salt, + cpw, sizeof(cpw)); + break; + case ALG_PLAIN: + /* XXX this len limitation is not in sync with any HTTPd len. */ + apr_cpystrn(cpw,htdbm->userpass,sizeof(cpw)); + break; +#if APR_HAVE_CRYPT_H + case ALG_CRYPT: + (void) srand((int) time((time_t *) NULL)); + to64(&salt[0], rand(), 8); + salt[8] = '\0'; + apr_cpystrn(cpw, (char *)crypt(htdbm->userpass, salt), sizeof(cpw) - 1); + fprintf(stderr, "CRYPT is now deprecated, use MD5 instead!\n"); +#endif + default: + break; + } + htdbm->userpass = apr_pstrdup(htdbm->pool, cpw); + return APR_SUCCESS; +} + +static apr_status_t htdbm_valid_username(htdbm_t *htdbm) +{ + if (!htdbm->username || (strlen(htdbm->username) > 64) || (strlen(htdbm->username) < 1)) { + fprintf(stderr, "Invalid username length\n"); + return APR_EINVAL; + } + if (strchr(htdbm->username, ':')) { + fprintf(stderr, "Username contains invalid characters\n"); + return APR_EINVAL; + } + return APR_SUCCESS; +} + +static void htdbm_usage(void) +{ + +#if APR_HAVE_CRYPT_H +#define CRYPT_OPTION "d" +#else +#define CRYPT_OPTION "" +#endif + fprintf(stderr, "htdbm -- program for manipulating DBM password databases.\n\n"); + fprintf(stderr, "Usage: htdbm [-cm"CRYPT_OPTION"pstvx] [-TDBTYPE] database username\n"); + fprintf(stderr, " -b[cm"CRYPT_OPTION"ptsv] [-TDBTYPE] database username password\n"); + fprintf(stderr, " -n[m"CRYPT_OPTION"pst] username\n"); + fprintf(stderr, " -nb[m"CRYPT_OPTION"pst] username password\n"); + fprintf(stderr, " -v[m"CRYPT_OPTION"ps] [-TDBTYPE] database username\n"); + fprintf(stderr, " -vb[m"CRYPT_OPTION"ps] [-TDBTYPE] database username password\n"); + fprintf(stderr, " -x[m"CRYPT_OPTION"ps] [-TDBTYPE] database username\n"); + fprintf(stderr, " -l [-TDBTYPE] database\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -b Use the password from the command line rather " + "than prompting for it.\n"); + fprintf(stderr, " -c Create a new database.\n"); + fprintf(stderr, " -n Don't update database; display results on stdout.\n"); + fprintf(stderr, " -m Force MD5 encryption of the password (default).\n"); +#if APR_HAVE_CRYPT_H + fprintf(stderr, " -d Force CRYPT encryption of the password (now deprecated).\n"); +#endif + fprintf(stderr, " -p Do not encrypt the password (plaintext).\n"); + fprintf(stderr, " -s Force SHA encryption of the password.\n"); + fprintf(stderr, " -T DBM Type (SDBM|GDBM|DB|default).\n"); + fprintf(stderr, " -l Display usernames from database on stdout.\n"); + fprintf(stderr, " -t The last param is username comment.\n"); + fprintf(stderr, " -v Verify the username/password.\n"); + fprintf(stderr, " -x Remove the username record from database.\n"); + exit(ERR_SYNTAX); + +} + + +int main(int argc, const char * const argv[]) +{ + apr_pool_t *pool; + apr_status_t rv; + apr_size_t l; + char pwi[MAX_STRING_LEN]; + char pwc[MAX_STRING_LEN]; + char errbuf[MAX_STRING_LEN]; + const char *arg; + int need_file = 1; + int need_user = 1; + int need_pwd = 1; + int need_cmnt = 0; + int pwd_supplied = 0; + int changed; + int cmd = HTDBM_MAKE; + int i; + int args_left = 2; + + apr_app_initialize(&argc, &argv, NULL); + atexit(terminate); + + if ((rv = htdbm_init(&pool, &h)) != APR_SUCCESS) { + fprintf(stderr, "Unable to initialize htdbm terminating!\n"); + apr_strerror(rv, errbuf, sizeof(errbuf)); + exit(1); + } + /* + * 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) + htdbm_usage(); + /* + * Go through the argument list and pick out any options. They + * have to precede any other arguments. + */ + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (*arg != '-') + break; + + while (*++arg != '\0') { + switch (*arg) { + case 'b': + pwd_supplied = 1; + need_pwd = 0; + args_left++; + break; + case 'c': + h->create = 1; + break; + case 'n': + need_file = 0; + cmd = HTDBM_NOFILE; + args_left--; + break; + case 'l': + need_pwd = 0; + need_user = 0; + cmd = HTDBM_LIST; + h->rdonly = 1; + args_left--; + break; + case 't': + need_cmnt = 1; + args_left++; + break; + case 'T': + h->type = apr_pstrdup(h->pool, ++arg); + while (*arg != '\0') + ++arg; + --arg; /* so incrementing this in the loop with find a null */ + break; + case 'v': + h->rdonly = 1; + cmd = HTDBM_VERIFY; + break; + case 'x': + need_pwd = 0; + cmd = HTDBM_DELETE; + break; + case 'm': + h->alg = ALG_APMD5; + break; + case 'p': + h->alg = ALG_PLAIN; + break; + case 's': + h->alg = ALG_APSHA; + break; +#if APR_HAVE_CRYPT_H + case 'd': + h->alg = ALG_CRYPT; + break; +#endif + default: + htdbm_usage(); + break; + } + } + } + /* + * Make sure we still have exactly the right number of arguments left + * (the filename, the username, and possibly the password if -b was + * specified). + */ + if ((argc - i) != args_left) + htdbm_usage(); + + if (!need_file) + i--; + else { + h->filename = apr_pstrdup(h->pool, argv[i]); + if ((rv = htdbm_open(h)) != APR_SUCCESS) { + fprintf(stderr, "Error opening database %s\n", argv[i]); + apr_strerror(rv, errbuf, sizeof(errbuf)); + fprintf(stderr,"%s\n",errbuf); + exit(ERR_FILEPERM); + } + } + if (need_user) { + h->username = apr_pstrdup(pool, argv[i+1]); + if (htdbm_valid_username(h) != APR_SUCCESS) + exit(ERR_BADUSER); + } + if (pwd_supplied) + h->userpass = apr_pstrdup(pool, argv[i+2]); + + if (need_pwd) { + l = sizeof(pwc); + if (apr_password_get("Enter password : ", pwi, &l) != APR_SUCCESS) { + fprintf(stderr, "Password too long\n"); + exit(ERR_OVERFLOW); + } + l = sizeof(pwc); + if (apr_password_get("Re-type password : ", pwc, &l) != APR_SUCCESS) { + fprintf(stderr, "Password too long\n"); + exit(ERR_OVERFLOW); + } + if (strcmp(pwi, pwc) != 0) { + fprintf(stderr, "Password verification error\n"); + exit(ERR_PWMISMATCH); + } + + h->userpass = apr_pstrdup(pool, pwi); + } + if (need_cmnt && pwd_supplied) + h->comment = apr_pstrdup(pool, argv[i+3]); + else if (need_cmnt) + h->comment = apr_pstrdup(pool, argv[i+2]); + + switch (cmd) { + case HTDBM_VERIFY: + if ((rv = htdbm_verify(h)) != APR_SUCCESS) { + if(rv == APR_ENOENT) { + fprintf(stderr, "The user '%s' could not be found in database\n", h->username); + exit(ERR_BADUSER); + } + else { + fprintf(stderr, "Password mismatch for user '%s'\n", h->username); + exit(ERR_PWMISMATCH); + } + } + else + fprintf(stderr, "Password validated for user '%s'\n", h->username); + break; + case HTDBM_DELETE: + if (htdbm_del(h) != APR_SUCCESS) { + fprintf(stderr, "Cannot find user '%s' in database\n", h->username); + exit(ERR_BADUSER); + } + h->username = NULL; + changed = 1; + break; + case HTDBM_LIST: + htdbm_list(h); + break; + default: + htdbm_make(h); + break; + + } + if (need_file && !h->rdonly) { + if ((rv = htdbm_save(h, &changed)) != APR_SUCCESS) { + apr_strerror(rv, errbuf, sizeof(errbuf)); + exit(ERR_FILEPERM); + } + fprintf(stdout, "Database %s %s.\n", h->filename, + h->create ? "created" : (changed ? "modified" : "updated")); + } + if (cmd == HTDBM_NOFILE) { + if (!need_cmnt) { + fprintf(stderr, "%s:%s\n", h->username, h->userpass); + } + else { + fprintf(stderr, "%s:%s:%s\n", h->username, h->userpass, + h->comment); + } + } + htdbm_terminate(h); + + return 0; /* Suppress compiler warning. */ +} diff --git a/trunk/support/htdbm.dsp b/trunk/support/htdbm.dsp new file mode 100644 index 0000000000..ac2425f845 --- /dev/null +++ b/trunk/support/htdbm.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="htdbm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=htdbm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "htdbm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "htdbm.mak" CFG="htdbm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "htdbm - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "htdbm - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "htdbm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/htdbm_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "htdbm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/htdbm_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "htdbm - Win32 Release" +# Name "htdbm - Win32 Debug" +# Begin Source File + +SOURCE=.\htdbm.c +# End Source File +# Begin Source File + +SOURCE=.\htdbm.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "htdbm - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htdbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htdbm.exe "htdbm Utility" ../include/ap_release.h > .\htdbm.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "htdbm - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htdbm.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htdbm.exe "htdbm Utility" ../include/ap_release.h > .\htdbm.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/htdigest.c b/trunk/support/htdigest.c new file mode 100644 index 0000000000..f90a672c59 --- /dev/null +++ b/trunk/support/htdigest.c @@ -0,0 +1,291 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + ****************************************************************************** + * NOTE! This program is not safe as a setuid executable! Do not make it + * setuid! + ****************************************************************************** + *****************************************************************************/ +/* + * htdigest.c: simple program for manipulating digest passwd file for Apache + * + * by Alexei Kosut, based on htpasswd.c, by Rob McCool + */ + +#include "apr.h" +#include "apr_file_io.h" +#include "apr_md5.h" +#include "apr_lib.h" /* for apr_getpass() */ +#include "apr_general.h" +#include "apr_signal.h" +#include "apr_strings.h" /* for apr_pstrdup() */ + +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#if APR_HAVE_SYS_TYPES_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif + +#ifdef WIN32 +#include +#endif + + +#if APR_CHARSET_EBCDIC +#define LF '\n' +#define CR '\r' +#else +#define LF 10 +#define CR 13 +#endif /* APR_CHARSET_EBCDIC */ + +#define MAX_STRING_LEN 256 + +apr_file_t *tfp = NULL; +apr_file_t *errfile; +apr_pool_t *cntxt; +#if APR_CHARSET_EBCDIC +apr_xlate_t *to_ascii; +#endif + +static void cleanup_tempfile_and_exit(int rc) +{ + if (tfp) { + apr_file_close(tfp); + } + exit(rc); +} + +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 get_line(char *s, int n, apr_file_t *f) +{ + register int i = 0; + char ch; + apr_status_t rv = APR_EINVAL; + + while (i < (n - 1) && + ((rv = apr_file_getc(&ch, f)) == APR_SUCCESS) && (ch != '\n')) { + s[i++] = ch; + } + if (ch == '\n') + s[i++] = ch; + s[i] = '\0'; + + if (rv != APR_SUCCESS) + return 1; + + return 0; +} + +static void putline(apr_file_t *f, char *l) +{ + int x; + + for (x = 0; l[x]; x++) + apr_file_putc(l[x], f); +} + + +static void add_password(const char *user, const char *realm, apr_file_t *f) +{ + char *pw; + apr_md5_ctx_t context; + unsigned char digest[16]; + char string[MAX_STRING_LEN]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; + unsigned int i; + apr_size_t len = sizeof(pwin); + + if (apr_password_get("New password: ", pwin, &len) != APR_SUCCESS) { + apr_file_printf(errfile, "password too long"); + cleanup_tempfile_and_exit(5); + } + len = sizeof(pwin); + apr_password_get("Re-type new password: ", pwv, &len); + if (strcmp(pwin, pwv) != 0) { + apr_file_printf(errfile, "They don't match, sorry.\n"); + cleanup_tempfile_and_exit(1); + } + pw = pwin; + apr_file_printf(f, "%s:%s:", user, realm); + + /* Do MD5 stuff */ + sprintf(string, "%s:%s:%s", user, realm, pw); + + apr_md5_init(&context); +#if APR_CHARSET_EBCDIC + apr_md5_set_xlate(&context, to_ascii); +#endif + apr_md5_update(&context, (unsigned char *) string, strlen(string)); + apr_md5_final(digest, &context); + + for (i = 0; i < 16; i++) + apr_file_printf(f, "%02x", digest[i]); + + apr_file_printf(f, "\n"); +} + +static void usage(void) +{ + apr_file_printf(errfile, "Usage: htdigest [-c] passwordfile realm username\n"); + apr_file_printf(errfile, "The -c flag creates a new file.\n"); + exit(1); +} + +static void interrupted(void) +{ + apr_file_printf(errfile, "Interrupted.\n"); + cleanup_tempfile_and_exit(1); +} + +static void terminate(void) +{ + apr_terminate(); +#ifdef NETWARE + pressanykey(); +#endif +} + +int main(int argc, const char * const argv[]) +{ + apr_file_t *f; + apr_status_t rv; + char tn[] = "htdigest.tmp.XXXXXX"; + char *dirname; + char user[MAX_STRING_LEN]; + char realm[MAX_STRING_LEN]; + char line[MAX_STRING_LEN]; + char l[MAX_STRING_LEN]; + char w[MAX_STRING_LEN]; + char x[MAX_STRING_LEN]; + int found; + + apr_app_initialize(&argc, &argv, NULL); + atexit(terminate); + apr_pool_create(&cntxt, NULL); + apr_file_open_stderr(&errfile, cntxt); + +#if APR_CHARSET_EBCDIC + rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, cntxt); + if (rv) { + apr_file_printf(errfile, "apr_xlate_open(): %s (%d)\n", + apr_strerror(rv, line, sizeof(line)), rv); + exit(1); + } +#endif + + apr_signal(SIGINT, (void (*)(int)) interrupted); + if (argc == 5) { + if (strcmp(argv[1], "-c")) + usage(); + rv = apr_file_open(&f, argv[2], APR_WRITE | APR_CREATE, + APR_OS_DEFAULT, cntxt); + if (rv != APR_SUCCESS) { + char errmsg[120]; + + apr_file_printf(errfile, "Could not open passwd file %s for writing: %s\n", + argv[2], + apr_strerror(rv, errmsg, sizeof errmsg)); + exit(1); + } + apr_file_printf(errfile, "Adding password for %s in realm %s.\n", + argv[4], argv[3]); + add_password(argv[4], argv[3], f); + apr_file_close(f); + exit(0); + } + else if (argc != 4) + usage(); + + if (apr_temp_dir_get((const char**)&dirname, cntxt) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: could not determine temp dir\n", + argv[0]); + exit(1); + } + dirname = apr_psprintf(cntxt, "%s/%s", dirname, tn); + + if (apr_file_mktemp(&tfp, dirname, 0, cntxt) != APR_SUCCESS) { + apr_file_printf(errfile, "Could not open temp file %s.\n", dirname); + exit(1); + } + + if (apr_file_open(&f, argv[1], APR_READ, APR_OS_DEFAULT, cntxt) != APR_SUCCESS) { + apr_file_printf(errfile, + "Could not open passwd file %s for reading.\n", argv[1]); + apr_file_printf(errfile, "Use -c option to create new one.\n"); + cleanup_tempfile_and_exit(1); + } + apr_cpystrn(user, argv[3], sizeof(user)); + apr_cpystrn(realm, argv[2], sizeof(realm)); + + found = 0; + while (!(get_line(line, MAX_STRING_LEN, f))) { + if (found || (line[0] == '#') || (!line[0])) { + putline(tfp, line); + continue; + } + strcpy(l, line); + getword(w, l, ':'); + getword(x, l, ':'); + if (strcmp(user, w) || strcmp(realm, x)) { + putline(tfp, line); + continue; + } + else { + apr_file_printf(errfile, "Changing password for user %s in realm %s\n", + user, realm); + add_password(user, realm, tfp); + found = 1; + } + } + if (!found) { + apr_file_printf(errfile, "Adding user %s in realm %s\n", user, realm); + add_password(user, realm, tfp); + } + apr_file_close(f); + + /* The temporary file has all the data, just copy it to the new location. + */ + if (apr_file_copy(dirname, argv[1], APR_FILE_SOURCE_PERMS, cntxt) != + APR_SUCCESS) { + apr_file_printf(errfile, "%s: unable to update file %s\n", + argv[0], argv[1]); + } + apr_file_close(tfp); + + return 0; +} diff --git a/trunk/support/htdigest.dsp b/trunk/support/htdigest.dsp new file mode 100644 index 0000000000..6669101c40 --- /dev/null +++ b/trunk/support/htdigest.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="htdigest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=htdigest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "htdigest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "htdigest.mak" CFG="htdigest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "htdigest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "htdigest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "htdigest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/htdigest_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "htdigest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/htdigest_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "htdigest - Win32 Release" +# Name "htdigest - Win32 Debug" +# Begin Source File + +SOURCE=.\htdigest.c +# End Source File +# Begin Source File + +SOURCE=.\htdigest.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "htdigest - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htdigest.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htdigest.exe "htdigest Utility" ../include/ap_release.h > .\htdigest.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "htdigest - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htdigest.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htdigest.exe "htdigest Utility" ../include/ap_release.h > .\htdigest.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/htpasswd.c b/trunk/support/htpasswd.c new file mode 100644 index 0000000000..20764636a2 --- /dev/null +++ b/trunk/support/htpasswd.c @@ -0,0 +1,612 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + ****************************************************************************** + * NOTE! This program is not safe as a setuid executable! Do not make it + * setuid! + ****************************************************************************** + *****************************************************************************/ +/* + * htpasswd.c: simple program for manipulating password file for + * the Apache HTTP server + * + * 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) + * 6: Failure; username contains illegal or reserved characters + * 7: Failure; file is not a valid htpasswd file + */ + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_errno.h" +#include "apr_file_io.h" +#include "apr_general.h" +#include "apr_signal.h" + +#if APR_HAVE_STDIO_H +#include +#endif + +#include "apr_md5.h" +#include "apr_sha1.h" +#include + +#if APR_HAVE_CRYPT_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif +#if APR_HAVE_UNISTD_H +#include +#endif + +#ifdef WIN32 +#include +#define unlink _unlink +#endif + +#if !APR_CHARSET_EBCDIC +#define LF 10 +#define CR 13 +#else /*APR_CHARSET_EBCDIC*/ +#define LF '\n' +#define CR '\r' +#endif /*APR_CHARSET_EBCDIC*/ + +#define MAX_STRING_LEN 256 +#define ALG_PLAIN 0 +#define ALG_CRYPT 1 +#define ALG_APMD5 2 +#define ALG_APSHA 3 + +#define ERR_FILEPERM 1 +#define ERR_SYNTAX 2 +#define ERR_PWMISMATCH 3 +#define ERR_INTERRUPTED 4 +#define ERR_OVERFLOW 5 +#define ERR_BADUSER 6 +#define ERR_INVALID 7 + +#define APHTP_NEWFILE 1 +#define APHTP_NOFILE 2 +#define APHTP_NONINTERACTIVE 4 +#define APHTP_DELUSER 8 + +apr_file_t *errfile; +apr_file_t *ftemp = NULL; + +#define NL APR_EOL_STR + +static void to64(char *s, unsigned long v, int n) +{ + static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +static void putline(apr_file_t *f, const char *l) +{ + apr_file_puts(l, f); +} + +/* + * 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, apr_size_t rlen, char *passwd, + int alg) +{ + char *pw; + char cpw[120]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; + char salt[9]; + apr_size_t bufsize; + + if (passwd != NULL) { + pw = passwd; + } + else { + bufsize = sizeof(pwin); + if (apr_password_get("New password: ", pwin, &bufsize) != 0) { + apr_snprintf(record, (rlen - 1), "password too long (>%" + APR_SIZE_T_FMT ")", sizeof(pwin) - 1); + return ERR_OVERFLOW; + } + bufsize = sizeof(pwv); + apr_password_get("Re-type new password: ", pwv, &bufsize); + if (strcmp(pwin, pwv) != 0) { + apr_cpystrn(record, "password verification error", (rlen - 1)); + return ERR_PWMISMATCH; + } + pw = pwin; + memset(pwv, '\0', sizeof(pwin)); + } + switch (alg) { + + case ALG_APSHA: + /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */ + apr_sha1_base64(pw,strlen(pw),cpw); + break; + + case ALG_APMD5: + (void) srand((int) time((time_t *) NULL)); + to64(&salt[0], rand(), 8); + salt[8] = '\0'; + + apr_md5_encode((const char *)pw, (const char *)salt, + cpw, sizeof(cpw)); + break; + + case ALG_PLAIN: + /* XXX this len limitation is not in sync with any HTTPd len. */ + apr_cpystrn(cpw,pw,sizeof(cpw)); + break; + +#if !(defined(WIN32) || defined(NETWARE)) + case ALG_CRYPT: + default: + (void) srand((int) time((time_t *) NULL)); + to64(&salt[0], rand(), 8); + salt[8] = '\0'; + + apr_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); + break; +#endif + } + memset(pw, '\0', strlen(pw)); + + /* + * Check to see if the buffer is large enough to hold the username, + * hash, and delimiters. + */ + if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { + apr_cpystrn(record, "resultant record too long", (rlen - 1)); + return ERR_OVERFLOW; + } + strcpy(record, user); + strcat(record, ":"); + strcat(record, cpw); + strcat(record, "\n"); + return 0; +} + +static void usage(void) +{ + apr_file_printf(errfile, "Usage:" NL); + apr_file_printf(errfile, "\thtpasswd [-cmdpsD] passwordfile username" NL); + apr_file_printf(errfile, "\thtpasswd -b[cmdpsD] passwordfile username " + "password" NL NL); + apr_file_printf(errfile, "\thtpasswd -n[mdps] username" NL); + apr_file_printf(errfile, "\thtpasswd -nb[mdps] username password" NL); + apr_file_printf(errfile, " -c Create a new file." NL); + apr_file_printf(errfile, " -n Don't update file; display results on " + "stdout." NL); + apr_file_printf(errfile, " -m Force MD5 encryption of the password" +#if defined(WIN32) || defined(TPF) || defined(NETWARE) + " (default)" +#endif + "." NL); + apr_file_printf(errfile, " -d Force CRYPT encryption of the password" +#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE))) + " (default)" +#endif + "." NL); + apr_file_printf(errfile, " -p Do not encrypt the password (plaintext)." NL); + apr_file_printf(errfile, " -s Force SHA encryption of the password." NL); + apr_file_printf(errfile, " -b Use the password from the command line " + "rather than prompting for it." NL); + apr_file_printf(errfile, " -D Delete the specified user." NL); + apr_file_printf(errfile, + "On Windows, NetWare and TPF systems the '-m' flag is used by " + "default." NL); + apr_file_printf(errfile, + "On all other systems, the '-p' flag will probably not work." NL); + exit(ERR_SYNTAX); +} + +/* + * Check to see if the specified file can be opened for the given + * access. + */ +static int accessible(apr_pool_t *pool, char *fname, int mode) +{ + apr_file_t *f = NULL; + + if (apr_file_open(&f, fname, mode, APR_OS_DEFAULT, pool) != APR_SUCCESS) { + return 0; + } + apr_file_close(f); + return 1; +} + +/* + * Return true if the named file exists, regardless of permissions. + */ +static int exists(char *fname, apr_pool_t *pool) +{ + apr_finfo_t sbuf; + apr_status_t check; + + check = apr_stat(&sbuf, fname, APR_FINFO_TYPE, pool); + return ((check || sbuf.filetype != APR_REG) ? 0 : 1); +} + +static void terminate(void) +{ + apr_terminate(); +#ifdef NETWARE + pressanykey(); +#endif +} + +static void check_args(apr_pool_t *pool, int argc, const char *const argv[], + int *alg, int *mask, char **user, char **pwfilename, + char **password) +{ + const char *arg; + int args_left = 2; + int i; + + /* + * 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(); + } + + /* + * Go through the argument list and pick out any options. They + * have to precede any other arguments. + */ + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (*arg != '-') { + break; + } + while (*++arg != '\0') { + if (*arg == 'c') { + *mask |= APHTP_NEWFILE; + } + else if (*arg == 'n') { + *mask |= APHTP_NOFILE; + args_left--; + } + else if (*arg == 'm') { + *alg = ALG_APMD5; + } + else if (*arg == 's') { + *alg = ALG_APSHA; + } + else if (*arg == 'p') { + *alg = ALG_PLAIN; + } + else if (*arg == 'd') { + *alg = ALG_CRYPT; + } + else if (*arg == 'b') { + *mask |= APHTP_NONINTERACTIVE; + args_left++; + } + else if (*arg == 'D') { + *mask |= APHTP_DELUSER; + } + else { + usage(); + } + } + } + + if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_NOFILE)) { + apr_file_printf(errfile, "%s: -c and -n options conflict" NL, argv[0]); + exit(ERR_SYNTAX); + } + if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_DELUSER)) { + apr_file_printf(errfile, "%s: -c and -D options conflict" NL, argv[0]); + exit(ERR_SYNTAX); + } + if ((*mask & APHTP_NOFILE) && (*mask & APHTP_DELUSER)) { + apr_file_printf(errfile, "%s: -n and -D options conflict" NL, argv[0]); + exit(ERR_SYNTAX); + } + /* + * Make sure we still have exactly the right number of arguments left + * (the filename, the username, and possibly the password if -b was + * specified). + */ + if ((argc - i) != args_left) { + usage(); + } + + if (*mask & APHTP_NOFILE) { + i--; + } + else { + if (strlen(argv[i]) > (APR_PATH_MAX - 1)) { + apr_file_printf(errfile, "%s: filename too long" NL, argv[0]); + exit(ERR_OVERFLOW); + } + *pwfilename = apr_pstrdup(pool, argv[i]); + if (strlen(argv[i + 1]) > (MAX_STRING_LEN - 1)) { + apr_file_printf(errfile, "%s: username too long (> %d)" NL, + argv[0], MAX_STRING_LEN - 1); + exit(ERR_OVERFLOW); + } + } + *user = apr_pstrdup(pool, argv[i + 1]); + if ((arg = strchr(*user, ':')) != NULL) { + apr_file_printf(errfile, "%s: username contains illegal " + "character '%c'" NL, argv[0], *arg); + exit(ERR_BADUSER); + } + if (*mask & APHTP_NONINTERACTIVE) { + if (strlen(argv[i + 2]) > (MAX_STRING_LEN - 1)) { + apr_file_printf(errfile, "%s: password too long (> %d)" NL, + argv[0], MAX_STRING_LEN); + exit(ERR_OVERFLOW); + } + *password = apr_pstrdup(pool, argv[i + 2]); + } +} + +/* + * 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, const char * const argv[]) +{ + apr_file_t *fpw = NULL; + char record[MAX_STRING_LEN]; + char line[MAX_STRING_LEN]; + char *password = NULL; + char *pwfilename = NULL; + char *user = NULL; + char tn[] = "htpasswd.tmp.XXXXXX"; + char *dirname; + char *scratch, cp[MAX_STRING_LEN]; + int found = 0; + int i; + int alg = ALG_CRYPT; + int mask = 0; + apr_pool_t *pool; + int existing_file = 0; +#if APR_CHARSET_EBCDIC + apr_status_t rv; + apr_xlate_t *to_ascii; +#endif + + apr_app_initialize(&argc, &argv, NULL); + atexit(terminate); + apr_pool_create(&pool, NULL); + apr_file_open_stderr(&errfile, pool); + +#if APR_CHARSET_EBCDIC + rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, pool); + if (rv) { + apr_file_printf(errfile, "apr_xlate_open(to ASCII)->%d" NL, rv); + exit(1); + } + rv = apr_SHA1InitEBCDIC(to_ascii); + if (rv) { + apr_file_printf(errfile, "apr_SHA1InitEBCDIC()->%d" NL, rv); + exit(1); + } + rv = apr_MD5InitEBCDIC(to_ascii); + if (rv) { + apr_file_printf(errfile, "apr_MD5InitEBCDIC()->%d" NL, rv); + exit(1); + } +#endif /*APR_CHARSET_EBCDIC*/ + + check_args(pool, argc, argv, &alg, &mask, &user, &pwfilename, &password); + + +#if defined(WIN32) || defined(NETWARE) + if (alg == ALG_CRYPT) { + alg = ALG_APMD5; + apr_file_printf(errfile, "Automatically using MD5 format." NL); + } +#endif + +#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE))) + if (alg == ALG_PLAIN) { + apr_file_printf(errfile,"Warning: storing passwords as plain text " + "might just not work on this platform." NL); + } +#endif + + /* + * Only do the file checks if we're supposed to frob it. + */ + if (!(mask & APHTP_NOFILE)) { + existing_file = exists(pwfilename, pool); + if (existing_file) { + /* + * Check that this existing file is readable and writable. + */ + if (!accessible(pool, pwfilename, APR_READ | APR_APPEND)) { + apr_file_printf(errfile, "%s: cannot open file %s for " + "read/write access" NL, argv[0], pwfilename); + exit(ERR_FILEPERM); + } + } + else { + /* + * Error out if -c was omitted for this non-existant file. + */ + if (!(mask & APHTP_NEWFILE)) { + apr_file_printf(errfile, + "%s: cannot modify file %s; use '-c' to create it" NL, + argv[0], pwfilename); + exit(ERR_FILEPERM); + } + /* + * As it doesn't exist yet, verify that we can create it. + */ + if (!accessible(pool, pwfilename, APR_CREATE | APR_WRITE)) { + apr_file_printf(errfile, "%s: cannot create file %s" NL, + argv[0], pwfilename); + exit(ERR_FILEPERM); + } + } + } + + /* + * All the file access checks (if any) 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 (!(mask & APHTP_DELUSER)) { + i = mkrecord(user, record, sizeof(record) - 1, + password, alg); + if (i != 0) { + apr_file_printf(errfile, "%s: %s" NL, argv[0], record); + exit(i); + } + if (mask & APHTP_NOFILE) { + printf("%s" NL, record); + exit(0); + } + } + + /* + * We can access the files the right way, and we have a record + * to add or update. Let's do it.. + */ + if (apr_temp_dir_get((const char**)&dirname, pool) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: could not determine temp dir" NL, + argv[0]); + exit(ERR_FILEPERM); + } + dirname = apr_psprintf(pool, "%s/%s", dirname, tn); + + if (apr_file_mktemp(&ftemp, dirname, 0, pool) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: unable to create temporary file %s" NL, + argv[0], dirname); + 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 (existing_file && !(mask & APHTP_NEWFILE)) { + if (apr_file_open(&fpw, pwfilename, APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, pool) != APR_SUCCESS) { + apr_file_printf(errfile, "%s: unable to read file %s" NL, + argv[0], pwfilename); + exit(ERR_FILEPERM); + } + while (apr_file_gets(line, sizeof(line), fpw) == APR_SUCCESS) { + char *colon; + + strcpy(cp, line); + scratch = cp; + while (apr_isspace(*scratch)) { + ++scratch; + } + + if (!*scratch || (*scratch == '#')) { + putline(ftemp, line); + continue; + } + /* + * See if this is our user. + */ + colon = strchr(scratch, ':'); + if (colon != NULL) { + *colon = '\0'; + } + else { + /* + * If we've not got a colon on the line, this could well + * not be a valid htpasswd file. + * We should bail at this point. + */ + apr_file_printf(errfile, "%s: The file %s does not appear " + "to be a valid htpasswd file." NL, + argv[0], pwfilename); + apr_file_close(fpw); + exit(ERR_INVALID); + } + if (strcmp(user, scratch) != 0) { + putline(ftemp, line); + continue; + } + else { + if (!(mask & APHTP_DELUSER)) { + /* We found the user we were looking for. + * Add him to the file. + */ + apr_file_printf(errfile, "Updating "); + putline(ftemp, record); + found++; + } + else { + /* We found the user we were looking for. + * Delete them from the file. + */ + apr_file_printf(errfile, "Deleting "); + found++; + } + } + } + apr_file_close(fpw); + } + if (!found && !(mask & APHTP_DELUSER)) { + apr_file_printf(errfile, "Adding "); + putline(ftemp, record); + } + else if (!found && (mask & APHTP_DELUSER)) { + apr_file_printf(errfile, "User %s not found" NL, user); + exit(0); + } + apr_file_printf(errfile, "password for user %s" NL, user); + + /* The temporary file has all the data, just copy it to the new location. + */ + if (apr_file_copy(dirname, pwfilename, APR_FILE_SOURCE_PERMS, pool) != + APR_SUCCESS) { + apr_file_printf(errfile, "%s: unable to update file %s" NL, + argv[0], pwfilename); + exit(ERR_FILEPERM); + } + apr_file_close(ftemp); + return 0; +} diff --git a/trunk/support/htpasswd.dsp b/trunk/support/htpasswd.dsp new file mode 100644 index 0000000000..aa16425716 --- /dev/null +++ b/trunk/support/htpasswd.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="htpasswd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=htpasswd - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "htpasswd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "htpasswd.mak" CFG="htpasswd - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "htpasswd - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "htpasswd - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "htpasswd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/htpasswd_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "htpasswd - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/htpasswd_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "htpasswd - Win32 Release" +# Name "htpasswd - Win32 Debug" +# Begin Source File + +SOURCE=.\htpasswd.c +# End Source File +# Begin Source File + +SOURCE=.\htpasswd.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "htpasswd - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htpasswd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htpasswd.exe "htpasswd Utility" ../include/ap_release.h > .\htpasswd.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "htpasswd - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\htpasswd.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk htpasswd.exe "htpasswd Utility" ../include/ap_release.h > .\htpasswd.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/list_hooks.pl b/trunk/support/list_hooks.pl new file mode 100755 index 0000000000..8d54778a25 --- /dev/null +++ b/trunk/support/list_hooks.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl -w +# +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; + +use Carp; + +my $path=shift || '.'; + +findInDir($path); + +foreach my $hook (sort keys %::Hooks) { + my $h=$::Hooks{$hook}; + for my $x (qw(declared implemented type args)) { + print "$hook datum '$x' missing\n" if !exists $h->{$x}; + } + print "$hook\n"; + print " declared in $h->{declared}\n" if defined $h->{declared}; + print " implemented in $h->{implemented}\n" if defined $h->{implemented}; + print " type is $h->{type}\n" if defined $h->{type}; + print " $h->{ret} $hook($h->{args})\n" if defined $h->{args}; + print "\n"; +} + +sub findInDir { + my $path=shift; + + local(*D); + opendir(D,$path) || croak "Can't open $path: $!"; + while(my $f=readdir D) { + next if $f=~/^\./; + my $file="$path/$f"; + + if(-d $file) { + findInDir($file); + next; + } + next if $file !~ /\.[ch]$/; + + scanFile($file); + } + closedir D; +} + +sub scanFile { + my $file=shift; + +# print "scanning $file\n"; + + open(F,$file) || croak "Can't open $file: $!"; + while() { + next if /\#define/; + next if /\@deffunc/; + if(/AP_DECLARE_HOOK\((.*)\)/) { + my $def=$1; + my($ret,$name,$args)=$def=~/([^,\s]+)\s*,\s*([^,\s]+)\s*,\s*\((.*)\)/; + croak "Don't understand $def in $file" if !defined $args; +# print "found $ret $name($args) in $file\n"; + + croak "$name declared twice! ($_)" + if exists $::Hooks{$name}->{declared}; + $::Hooks{$name}->{declared}=$file; + $::Hooks{$name}->{ret}=$ret; + $::Hooks{$name}->{args}=$args; + } elsif(/AP_DECLARE_HOOK\((\s*[^,\s]+)\s*,\s*([^,\s]+)/) { +# really we should swallow subsequent lines to get the arguments... + my $name=$2; + my $ret=$1; + croak "$name declared twice! ($_)" + if exists $::Hooks{$name}->{declared}; + $::Hooks{$name}->{declared}=$file; + $::Hooks{$name}->{ret}=$ret; + $::Hooks{$name}->{args}='???'; + } + if(/AP_IMPLEMENT_HOOK_()(VOID)\(([^,\s]+)/ + || /AP_IMPLEMENT(_OPTIONAL|)_HOOK_(.*?)\([^,]+?\s*,\s*([^,\s]+)/) { + my($type,$name)=($1 ? "OPTIONAL $2" : $2,$3); + +# print "found $name $type in $file\n"; + + croak "$name implemented twice ($::Hooks{$name}->{implemented} and $file) ($_)" + if exists $::Hooks{$name}->{implemented}; + $::Hooks{$name}->{implemented}=$file; + $::Hooks{$name}->{type}=$type; + } + } +} diff --git a/trunk/support/log_server_status.in b/trunk/support/log_server_status.in new file mode 100644 index 0000000000..ed07510f8c --- /dev/null +++ b/trunk/support/log_server_status.in @@ -0,0 +1,78 @@ +#!@perlbin@ +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Log Server Status +# Mark J Cox, UK Web Ltd 1996, mark ukweb.com +# +# This script is designed to be run at a frequent interval by something +# like cron. It connects to the server and downloads the status +# information. It reformats the information to a single line and logs +# it to a file. Make sure the directory $wherelog is writable by the +# user who runs this script. +# +require 'sys/socket.ph'; + +$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/19960312" +$server = "localhost"; # Name of server, could be "www.foo.com" +$port = "80"; # Port on server +$request = "/status/?auto"; # Request to send + +sub tcp_connect +{ + local($host,$port) =@_; + $sockaddr='S n a4 x8'; + chop($hostname=`hostname`); + $port=(getservbyname($port, 'tcp'))[2] unless $port =~ /^\d+$/; + $me=pack($sockaddr,&AF_INET,0,(gethostbyname($hostname))[4]); + $them=pack($sockaddr,&AF_INET,$port,(gethostbyname($host))[4]); + socket(S,&PF_INET,&SOCK_STREAM,(getprotobyname('tcp'))[2]) || + die "socket: $!"; + bind(S,$me) || return "bind: $!"; + connect(S,$them) || return "connect: $!"; + select(S); + $| = 1; + select(stdout); + return ""; +} + +### Main + +{ + $year=`date +%y`; + chomp($year); + $year += ($year < 70) ? 2000 : 1900; + $date = $year . `date +%m%d:%H%M%S`; + chomp($date); + ($day,$time)=split(/:/,$date); + $res=&tcp_connect($server,$port); + open(OUT,">>$wherelog$day"); + if ($res) { + print OUT "$time:-1:-1:-1:-1:$res\n"; + exit 1; + } + print S "GET $request\n"; + while () { + $requests=$1 if ( m|^BusyServers:\ (\S+)|); + $idle=$1 if ( m|^IdleServers:\ (\S+)|); + $number=$1 if ( m|sses:\ (\S+)|); + $cpu=$1 if (m|^CPULoad:\ (\S+)|); + } + print OUT "$time:$requests:$idle:$number:$cpu\n"; +} + + diff --git a/trunk/support/logresolve.c b/trunk/support/logresolve.c new file mode 100644 index 0000000000..e497d2e0c3 --- /dev/null +++ b/trunk/support/logresolve.c @@ -0,0 +1,387 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * logresolve 1.1 + * + * Tom Rathborne - tomr uunet.ca - http://www.uunet.ca/~tomr/ + * UUNET Canada, April 16, 1995 + * + * Rewritten by David Robinson. (drtr ast.cam.ac.uk) + * + * Usage: logresolve [-s filename] [-c] < access_log > new_log + * + * Arguments: + * -s filename name of a file to record statistics + * -c check the DNS for a matching A record for the host. + * + * Notes: + * + * To generate meaningful statistics from an HTTPD log file, it's good + * to have the domain name of each machine that accessed your site, but + * doing this on the fly can slow HTTPD down. + * + * Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname + * resolution off. Before running your stats program, just run your log + * file through this program (logresolve) and all of your IP numbers will + * be resolved into hostnames (where possible). + * + * logresolve takes an HTTPD access log (in the COMMON log file format, + * or any other format that has the IP number/domain name as the first + * field for that matter), and outputs the same file with all of the + * domain names looked up. Where no domain name can be found, the IP + * number is left in. + * + * To minimize impact on your nameserver, logresolve has its very own + * internal hash-table cache. This means that each IP number will only + * be looked up the first time it is found in the log file. + * + * The -c option causes logresolve to apply the same check as httpd + * compiled with -DMAXIMUM_DNS; after finding the hostname from the IP + * address, it looks up the IP addresses for the hostname and checks + * that one of these matches the original address. + */ + +#include "apr_lib.h" +#if APR_HAVE_STDIO_H +#include +#endif +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_CTYPE_H +#include +#endif +#if APR_HAVE_NETDB_H +#include +#endif +#if APR_HAVE_NETINET_IN_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif +#if APR_HAVE_SYS_SOCKET_H +#include +#endif +#if APR_HAVE_ARPA_INET_H +#include +#endif + +static void cgethost(struct in_addr ipnum, char *string, int check); +static int get_line(char *s, int n); +static void stats(FILE *output); + +#ifdef BEOS +#define NO_ADDRESS NO_DATA +#endif + + +/* maximum line length */ +#ifndef MAXLINE +#define MAXLINE 1024 +#endif + +/* maximum length of a domain name */ +#ifndef MAXDNAME +#define MAXDNAME 256 +#endif + +/* number of buckets in cache hash apr_table_t */ +#define BUCKETS 256 + +/* + * struct nsrec - record of nameservice for cache linked list + * + * ipnum - IP number hostname - hostname noname - nonzero if IP number has no + * hostname, i.e. hostname=IP number + */ + +struct nsrec { + struct in_addr ipnum; + char *hostname; + int noname; + struct nsrec *next; +} *nscache[BUCKETS]; + +/* + * statistics - obvious + */ + +#ifndef h_errno +#ifdef __CYGWIN__ +extern __declspec(dllimport) int h_errno; +#else +extern int h_errno; /* some machines don't have this in their headers */ +#endif +#endif + +/* largest value for h_errno */ + +#define MAX_ERR (NO_ADDRESS) +#define UNKNOWN_ERR (MAX_ERR+1) +#define NO_REVERSE (MAX_ERR+2) + +static int cachehits = 0; +static int cachesize = 0; +static int entries = 0; +static int resolves = 0; +static int withname = 0; +static int errors[MAX_ERR + 3]; + +/* + * cgethost - gets hostname by IP address, caching, and adding unresolvable + * IP numbers with their IP number as hostname, setting noname flag + */ + +static void cgethost (struct in_addr ipnum, char *string, int check) +{ + struct nsrec **current, *new; + struct hostent *hostdata; + char *name; + + current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) + + (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)]; + + while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr) + current = &(*current)->next; + + if (*current == NULL) { + cachesize++; + new = (struct nsrec *) malloc(sizeof(struct nsrec)); + if (new == NULL) { + perror("malloc"); + fprintf(stderr, "Insufficient memory\n"); + exit(1); + } + *current = new; + new->next = NULL; + + new->ipnum = ipnum; + + hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr), + AF_INET); + if (hostdata == NULL) { + if (h_errno > MAX_ERR) + errors[UNKNOWN_ERR]++; + else + errors[h_errno]++; + new->noname = h_errno; + name = strdup(inet_ntoa(ipnum)); + } + else { + new->noname = 0; + name = strdup(hostdata->h_name); + if (check) { + if (name == NULL) { + perror("strdup"); + fprintf(stderr, "Insufficient memory\n"); + exit(1); + } + hostdata = gethostbyname(name); + if (hostdata != NULL) { + char **hptr; + + for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++) + if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr) + break; + if (*hptr == NULL) + hostdata = NULL; + } + if (hostdata == NULL) { + fprintf(stderr, "Bad host: %s != %s\n", name, + inet_ntoa(ipnum)); + new->noname = NO_REVERSE; + free(name); + name = strdup(inet_ntoa(ipnum)); + errors[NO_REVERSE]++; + } + } + } + new->hostname = name; + if (new->hostname == NULL) { + perror("strdup"); + fprintf(stderr, "Insufficient memory\n"); + exit(1); + } + } + else + cachehits++; + + /* size of string == MAXDNAME +1 */ + strncpy(string, (*current)->hostname, MAXDNAME); + string[MAXDNAME] = '\0'; +} + +/* + * prints various statistics to output + */ + +static void stats (FILE *output) +{ + int i; + char *ipstring; + struct nsrec *current; + char *errstring[MAX_ERR + 3]; + + for (i = 0; i < MAX_ERR + 3; i++) + errstring[i] = "Unknown error"; + errstring[HOST_NOT_FOUND] = "Host not found"; + errstring[TRY_AGAIN] = "Try again"; + errstring[NO_RECOVERY] = "Non recoverable error"; + errstring[NO_DATA] = "No data record"; + errstring[NO_ADDRESS] = "No address"; + errstring[NO_REVERSE] = "No reverse entry"; + + fprintf(output, "logresolve Statistics:\n"); + + fprintf(output, "Entries: %d\n", entries); + fprintf(output, " With name : %d\n", withname); + fprintf(output, " Resolves : %d\n", resolves); + if (errors[HOST_NOT_FOUND]) + fprintf(output, " - Not found : %d\n", errors[HOST_NOT_FOUND]); + if (errors[TRY_AGAIN]) + fprintf(output, " - Try again : %d\n", errors[TRY_AGAIN]); + if (errors[NO_DATA]) + fprintf(output, " - No data : %d\n", errors[NO_DATA]); + if (errors[NO_ADDRESS]) + fprintf(output, " - No address: %d\n", errors[NO_ADDRESS]); + if (errors[NO_REVERSE]) + fprintf(output, " - No reverse: %d\n", errors[NO_REVERSE]); + fprintf(output, "Cache hits : %d\n", cachehits); + fprintf(output, "Cache size : %d\n", cachesize); + fprintf(output, "Cache buckets : IP number * hostname\n"); + + for (i = 0; i < BUCKETS; i++) + for (current = nscache[i]; current != NULL; current = current->next) { + ipstring = inet_ntoa(current->ipnum); + if (current->noname == 0) + fprintf(output, " %3d %15s - %s\n", i, ipstring, + current->hostname); + else { + if (current->noname > MAX_ERR + 2) + fprintf(output, " %3d %15s : Unknown error\n", i, + ipstring); + else + fprintf(output, " %3d %15s : %s\n", i, ipstring, + errstring[current->noname]); + } + } +} + + +/* + * gets a line from stdin + */ + +static int get_line (char *s, int n) +{ + char *cp; + + if (!fgets(s, n, stdin)) + return (0); + cp = strchr(s, '\n'); + if (cp) + *cp = '\0'; + return (1); +} + +int main (int argc, char *argv[]) +{ + struct in_addr ipnum; + char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile; + int i, check; + +#if defined(WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) + /* If we apr'ify this code, apr_pool_create/apr_pool_destroy + * should perform the WSAStartup/WSACleanup for us. + */ + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 0), &wsaData); +#endif + + check = 0; + statfile = NULL; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) + check = 1; + else if (strcmp(argv[i], "-s") == 0) { + if (i == argc - 1) { + fprintf(stderr, "logresolve: missing filename to -s\n"); + exit(1); + } + i++; + statfile = argv[i]; + } + else { + fprintf(stderr, "Usage: logresolve [-s statfile] [-c] < input > output\n"); + exit(0); + } + } + + for (i = 0; i < BUCKETS; i++) + nscache[i] = NULL; + for (i = 0; i < MAX_ERR + 2; i++) + errors[i] = 0; + + while (get_line(line, MAXLINE)) { + if (line[0] == '\0') + continue; + entries++; + if (!apr_isdigit(line[0])) { /* short cut */ + puts(line); + withname++; + continue; + } + bar = strchr(line, ' '); + if (bar != NULL) + *bar = '\0'; + ipnum.s_addr = inet_addr(line); + if (ipnum.s_addr == 0xffffffffu) { + if (bar != NULL) + *bar = ' '; + puts(line); + withname++; + continue; + } + + resolves++; + + cgethost(ipnum, hoststring, check); + if (bar != NULL) + printf("%s %s\n", hoststring, bar + 1); + else + puts(hoststring); + } + +#if defined(WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) + WSACleanup(); +#endif + + if (statfile != NULL) { + FILE *fp; + fp = fopen(statfile, "w"); + if (fp == NULL) { + fprintf(stderr, "logresolve: could not open statistics file '%s'\n" + ,statfile); + exit(1); + } + stats(fp); + fclose(fp); + } + + return (0); +} diff --git a/trunk/support/logresolve.dsp b/trunk/support/logresolve.dsp new file mode 100644 index 0000000000..2b83b09c0e --- /dev/null +++ b/trunk/support/logresolve.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="logresolve" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=logresolve - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "logresolve.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "logresolve.mak" CFG="logresolve - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "logresolve - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "logresolve - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "logresolve - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/logresolve_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "logresolve - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/logresolve_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "logresolve - Win32 Release" +# Name "logresolve - Win32 Debug" +# Begin Source File + +SOURCE=.\logresolve.c +# End Source File +# Begin Source File + +SOURCE=.\logresolve.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "logresolve - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\logresolve.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk logresolve.exe "logresolve Utility" ../include/ap_release.h > .\logresolve.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "logresolve - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\logresolve.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk logresolve.exe "logresolve Utility" ../include/ap_release.h > .\logresolve.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/logresolve.pl.in b/trunk/support/logresolve.pl.in new file mode 100644 index 0000000000..eb143e9723 --- /dev/null +++ b/trunk/support/logresolve.pl.in @@ -0,0 +1,225 @@ +#!@perlbin@ +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# logresolve.pl +# +# v 1.2 by robh imdb.com +# +# usage: logresolve.pl outfile +# +# input = Apache/NCSA/.. logfile with IP numbers at start of lines +# output = same logfile with IP addresses resolved to hostnames where +# name lookups succeeded. +# +# this differs from the C based 'logresolve' in that this script +# spawns a number ($CHILDREN) of subprocesses to resolve addresses +# concurrently and sets a short timeout ($TIMEOUT) for each lookup in +# order to keep things moving quickly. +# +# the parent process handles caching of IP->hostnames using a Perl hash +# it also avoids sending the same IP to multiple child processes to be +# resolved multiple times concurrently. +# +# Depending on the settings of $CHILDREN and $TIMEOUT you should see +# significant reductions in the overall time taken to resolve your +# logfiles. With $CHILDREN=40 and $TIMEOUT=5 I've seen 200,000 - 300,000 +# logfile lines processed per hour compared to ~45,000 per hour +# with 'logresolve'. +# +# I haven't yet seen any noticable reduction in the percentage of IPs +# that fail to get resolved. Your mileage will no doubt vary. 5s is long +# enough to wait IMO. +# +# Known to work with FreeBSD 2.2 +# Known to have problems with Solaris +# +# 980417 - use 'sockaddr_un' for bind/connect to make the script work +# with linux. Fix from Luuk de Boer + +require 5.004; + +$|=1; + +use FileHandle; +use Socket; + +use strict; +no strict 'refs'; + +use vars qw($PROTOCOL); +$PROTOCOL = 0; + +my $CHILDREN = 40; +my $TIMEOUT = 5; + +my $filename; +my %hash = (); +my $parent = $$; + +my @children = (); +for (my $child = 1; $child <=$CHILDREN; $child++) { + my $f = fork(); + if (!$f) { + $filename = "./.socket.$parent.$child"; + if (-e $filename) { unlink($filename) || warn "$filename .. $!\n";} + &child($child); + exit(0); + } + push(@children, $f); +} + +&parent; +&cleanup; + +## remove all temporary files before shutting down +sub cleanup { + # die kiddies, die + kill(15, @children); + for (my $child = 1; $child <=$CHILDREN; $child++) { + if (-e "./.socket.$parent.$child") { + unlink("./.socket.$parent.$child") + || warn ".socket.$parent.$child $!"; + } + } +} + +sub parent { + # Trap some possible signals to trigger temp file cleanup + $SIG{'KILL'} = $SIG{'INT'} = $SIG{'PIPE'} = \&cleanup; + + my %CHILDSOCK; + my $filename; + + ## fork child processes. Each child will create a socket connection + ## to this parent and use an unique temp filename to do so. + for (my $child = 1; $child <=$CHILDREN; $child++) { + $CHILDSOCK{$child}= FileHandle->new; + + if (!socket($CHILDSOCK{$child}, AF_UNIX, SOCK_STREAM, $PROTOCOL)) { + warn "parent socket to child failed $!"; + } + $filename = "./.socket.$parent.$child"; + my $response; + do { + $response = connect($CHILDSOCK{$child}, sockaddr_un($filename)); + if ($response != 1) { + sleep(1); + } + } while ($response != 1); + $CHILDSOCK{$child}->autoflush; + } + ## All child processes should now be ready or at worst warming up + + my (@buffer, $child, $ip, $rest, $hostname, $response); + ## read the logfile lines from STDIN + while() { + @buffer = (); # empty the logfile line buffer array. + $child = 1; # children are numbered 1..N, start with #1 + + # while we have a child to talk to and data to give it.. + do { + push(@buffer, $_); # buffer the line + ($ip, $rest) = split(/ /, $_, 2); # separate IP form rest + + unless ($hash{$ip}) { # resolve if unseen IP + $CHILDSOCK{$child}->print("$ip\n"); # pass IP to next child + $hash{$ip} = $ip; # don't look it up again. + $child++; + } + } while (($child < ($CHILDREN-1)) and ($_ = )); + + ## now poll each child for a response + while (--$child > 0) { + $response = $CHILDSOCK{$child}->getline; + chomp($response); + # child sends us back both the IP and HOSTNAME, no need for us + # to remember what child received any given IP, and no worries + # what order we talk to the children + ($ip, $hostname) = split(/\|/, $response, 2); + $hash{$ip} = $hostname; + } + + # resolve all the logfiles lines held in the log buffer array.. + for (my $line = 0; $line <=$#buffer; $line++) { + # get next buffered line + ($ip, $rest) = split(/ /, $buffer[$line], 2); + # separate IP from rest and replace with cached hostname + printf STDOUT ("%s %s", $hash{$ip}, $rest); + } + } +} + +######################################## + +sub child { + # arg = numeric ID - how the parent refers to me + my $me = shift; + + # add trap for alarm signals. + $SIG{'ALRM'} = sub { die "alarmed"; }; + + # create a socket to communicate with parent + socket(INBOUND, AF_UNIX, SOCK_STREAM, $PROTOCOL) + || die "Error with Socket: !$\n"; + $filename = "./.socket.$parent.$me"; + bind(INBOUND, sockaddr_un($filename)) + || die "Error Binding $filename: $!\n"; + listen(INBOUND, 5) || die "Error Listening: $!\n"; + + my ($ip, $send_back); + my $talk = FileHandle->new; + + # accept a connection from the parent process. We only ever have + # have one connection where we exchange 1 line of info with the + # parent.. 1 line in (IP address), 1 line out (IP + hostname). + accept($talk, INBOUND) || die "Error Accepting: $!\n"; + # disable I/O buffering just in case + $talk->autoflush; + # while the parent keeps sending data, we keep responding.. + while(($ip = $talk->getline)) { + chomp($ip); + # resolve the IP if time permits and send back what we found.. + $send_back = sprintf("%s|%s", $ip, &nslookup($ip)); + $talk->print($send_back."\n"); + } +} + +# perform a time restricted hostname lookup. +sub nslookup { + # get the IP as an arg + my $ip = shift; + my $hostname = undef; + + # do the hostname lookup inside an eval. The eval will use the + # already configured SIGnal handler and drop out of the {} block + # regardless of whether the alarm occured or not. + eval { + alarm($TIMEOUT); + $hostname = gethostbyaddr(gethostbyname($ip), AF_INET); + alarm(0); + }; + if ($@ =~ /alarm/) { + # useful for debugging perhaps.. + # print "alarming, isn't it? ($ip)"; + } + + # return the hostname or the IP address itself if there is no hostname + $hostname ne "" ? $hostname : $ip; +} + + diff --git a/trunk/support/phf_abuse_log.cgi.in b/trunk/support/phf_abuse_log.cgi.in new file mode 100644 index 0000000000..b004b15010 --- /dev/null +++ b/trunk/support/phf_abuse_log.cgi.in @@ -0,0 +1,38 @@ +#!@perlbin@ +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# This script is used to detect people trying to abuse the security hole which +# existed in A CGI script direstributed with Apache 1.0.3 and earlier versions. +# You can redirect them to here using the "" suggestion +# in httpd.conf. +# +# The format logged to is +# "[date] remote_addr remote_host [date] referrer user_agent". + +$LOG = "/var/log/phf_log"; + +require "ctime.pl"; +$when = &ctime(time); +$when =~ s/\n//go; +$ENV{HTTP_USER_AGENT} .= " via $ENV{HTTP_VIA}" if($ENV{HTTP_VIA}); + +open(LOG, ">>$LOG") || die "boo hoo, phf_log $!"; +print LOG "[$when] $ENV{REMOTE_ADDR} $ENV{REMOTE_HOST} $ENV{$HTTP_REFERER} $ENV{HTTP_USER_AGENT}\n"; +close(LOG); + +print "Content-type: text/html\r\n\r\nSmile, you're on Candid Camera.\n"; diff --git a/trunk/support/rotatelogs.c b/trunk/support/rotatelogs.c new file mode 100644 index 0000000000..14a56e8a64 --- /dev/null +++ b/trunk/support/rotatelogs.c @@ -0,0 +1,261 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Simple program to rotate Apache logs without having to kill the server. + * + * Contributed by Ben Laurie + * + * 12 Mar 1996 + * + * Ported to APR by Mladen Turk + * + * 23 Sep 2001 + * + * -l option added 2004-06-11 + * + * -l causes the use of local time rather than GMT as the base for the + * interval. NB: Using -l in an environment which changes the GMT offset + * (such as for BST or DST) can lead to unpredictable results! + * + */ + + +#include "apr.h" +#include "apr_lib.h" +#include "apr_strings.h" +#include "apr_errno.h" +#include "apr_file_io.h" +#include "apr_file_info.h" +#include "apr_general.h" +#include "apr_time.h" + +#if APR_HAVE_STDLIB_H +#include +#endif +#if APR_HAVE_STRING_H +#include +#endif +#if APR_HAVE_STRINGS_H +#include +#endif + +#define BUFSIZE 65536 +#define ERRMSGSZ 82 + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + +int main (int argc, const char * const argv[]) +{ + char buf[BUFSIZE], buf2[MAX_PATH], errbuf[ERRMSGSZ]; + int tLogEnd = 0, tRotation = 0, utc_offset = 0; + unsigned int sRotation = 0; + int nMessCount = 0; + apr_size_t nRead, nWrite; + int use_strftime = 0; + int use_localtime = 0; + int now = 0; + const char *szLogRoot; + apr_file_t *f_stdin, *nLogFD = NULL, *nLogFDprev = NULL; + apr_pool_t *pool; + char *ptr = NULL; + int argBase = 0; + int argFile = 1; + int argIntv = 2; + int argOffset = 3; + + apr_app_initialize(&argc, &argv, NULL); + atexit(apr_terminate); + + apr_pool_create(&pool, NULL); + if ((argc > 2) && (strcmp(argv[1], "-l") == 0)) { + argBase++; + argFile += argBase; + argIntv += argBase; + argOffset += argBase; + use_localtime = 1; + } + if (argc < (argBase + 3) || argc > (argBase + 4)) { + fprintf(stderr, + "Usage: %s [-l] " + "[offset minutes from UTC] or \n\n", + argv[0]); +#ifdef OS2 + fprintf(stderr, + "Add this:\n\nTransferLog \"|%s.exe /some/where 86400\"\n\n", + argv[0]); +#else + fprintf(stderr, + "Add this:\n\nTransferLog \"|%s /some/where 86400\"\n\n", + argv[0]); + fprintf(stderr, + "or \n\nTransferLog \"|%s /some/where 5M\"\n\n", argv[0]); +#endif + fprintf(stderr, + "to httpd.conf. The generated name will be /some/where.nnnn " + "where nnnn is the\nsystem time at which the log nominally " + "starts (N.B. if using a rotation time,\nthe time will always " + "be a multiple of the rotation time, so you can synchronize\n" + "cron scripts with it). At the end of each rotation time or " + "when the file size\nis reached a new log is started.\n"); + exit(1); + } + + szLogRoot = argv[argFile]; + + ptr = strchr(argv[argIntv], 'M'); + if (ptr) { + if (*(ptr+1) == '\0') { + sRotation = atoi(argv[argIntv]) * 1048576; + } + if (sRotation == 0) { + fprintf(stderr, "Invalid rotation size parameter\n"); + exit(1); + } + } + else { + if (argc >= (argBase + 4)) { + utc_offset = atoi(argv[argOffset]) * 60; + } + tRotation = atoi(argv[argIntv]); + if (tRotation <= 0) { + fprintf(stderr, "Rotation time must be > 0\n"); + exit(6); + } + } + + use_strftime = (strchr(szLogRoot, '%') != NULL); + if (apr_file_open_stdin(&f_stdin, pool) != APR_SUCCESS) { + fprintf(stderr, "Unable to open stdin\n"); + exit(1); + } + + for (;;) { + nRead = sizeof(buf); + if (apr_file_read(f_stdin, buf, &nRead) != APR_SUCCESS) { + exit(3); + } + if (tRotation) { + /* + * Check for our UTC offset every time through the loop, since + * it might change if there's a switch between standard and + * daylight savings time. + */ + if (use_localtime) { + apr_time_exp_t lt; + apr_time_exp_lt(<, apr_time_now()); + utc_offset = lt.tm_gmtoff; + } + now = (int)(apr_time_now() / APR_USEC_PER_SEC) + utc_offset; + if (nLogFD != NULL && now >= tLogEnd) { + nLogFDprev = nLogFD; + nLogFD = NULL; + } + } + else if (sRotation) { + apr_finfo_t finfo; + apr_off_t current_size = -1; + + if ((nLogFD != NULL) && + (apr_file_info_get(&finfo, APR_FINFO_SIZE, nLogFD) == APR_SUCCESS)) { + current_size = finfo.size; + } + + if (current_size > sRotation) { + nLogFDprev = nLogFD; + nLogFD = NULL; + } + } + else { + fprintf(stderr, "No rotation time or size specified\n"); + exit(2); + } + + if (nLogFD == NULL) { + int tLogStart; + + if (tRotation) { + tLogStart = (now / tRotation) * tRotation; + } + else { + tLogStart = (int)apr_time_sec(apr_time_now()); + } + + if (use_strftime) { + apr_time_t tNow = apr_time_from_sec(tLogStart); + apr_time_exp_t e; + apr_size_t rs; + + apr_time_exp_gmt(&e, tNow); + apr_strftime(buf2, &rs, sizeof(buf2), szLogRoot, &e); + } + else { + sprintf(buf2, "%s.%010d", szLogRoot, tLogStart); + } + tLogEnd = tLogStart + tRotation; + apr_file_open(&nLogFD, buf2, APR_READ | APR_WRITE | APR_CREATE | APR_APPEND, + APR_OS_DEFAULT, pool); + if (nLogFD == NULL) { + /* Uh-oh. Failed to open the new log file. Try to clear + * the previous log file, note the lost log entries, + * and keep on truckin'. */ + if (nLogFDprev == NULL) { + fprintf(stderr, "1 Previous file handle doesn't exists %s\n", buf2); + exit(2); + } + else { + nLogFD = nLogFDprev; + sprintf(errbuf, + "Resetting log file due to error opening " + "new log file. %10d messages lost.\n", + nMessCount); + nWrite = strlen(errbuf); + apr_file_trunc(nLogFD, 0); + if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) { + fprintf(stderr, "Error writing to the file %s\n", buf2); + exit(2); + } + } + } + else if (nLogFDprev) { + apr_file_close(nLogFDprev); + } + nMessCount = 0; + } + nWrite = nRead; + apr_file_write(nLogFD, buf, &nWrite); + if (nWrite != nRead) { + nMessCount++; + sprintf(errbuf, + "Error writing to log file. " + "%10d messages lost.\n", + nMessCount); + nWrite = strlen(errbuf); + apr_file_trunc(nLogFD, 0); + if (apr_file_write(nLogFD, errbuf, &nWrite) != APR_SUCCESS) { + fprintf(stderr, "Error writing to the file %s\n", buf2); + exit(2); + } + } + else { + nMessCount++; + } + } + /* Of course we never, but prevent compiler warnings */ + return 0; +} diff --git a/trunk/support/rotatelogs.dsp b/trunk/support/rotatelogs.dsp new file mode 100644 index 0000000000..43fc8fb948 --- /dev/null +++ b/trunk/support/rotatelogs.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="rotatelogs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rotatelogs - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rotatelogs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rotatelogs.mak" CFG="rotatelogs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rotatelogs - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "rotatelogs - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rotatelogs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/rotatelogs_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "rotatelogs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/rotatelogs_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib advapi32.lib wsock32.lib ws2_32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "rotatelogs - Win32 Release" +# Name "rotatelogs - Win32 Debug" +# Begin Source File + +SOURCE=.\rotatelogs.c +# End Source File +# Begin Source File + +SOURCE=.\rotatelogs.rc +# End Source File +# Begin Source File + +SOURCE=..\build\win32\win32ver.awk + +!IF "$(CFG)" == "rotatelogs - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\rotatelogs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk rotatelogs.exe "rotatelogs Utility" ../include/ap_release.h > .\rotatelogs.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "rotatelogs - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\build\win32\win32ver.awk + +".\rotatelogs.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../build/win32/win32ver.awk rotatelogs.exe "rotatelogs Utility" ../include/ap_release.h > .\rotatelogs.rc + +# End Custom Build + +!ENDIF + +# End Source File +# End Target +# End Project diff --git a/trunk/support/split-logfile.in b/trunk/support/split-logfile.in new file mode 100644 index 0000000000..37f639d41b --- /dev/null +++ b/trunk/support/split-logfile.in @@ -0,0 +1,67 @@ +#!@perlbin@ +# +# Copyright 2001-2005 The Apache Software Foundation or its licensors, as +# applicable. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# This script will take a combined Web server access +# log file and break its contents into separate files. +# It assumes that the first field of each line is the +# virtual host identity (put there by "%v"), and that +# the logfiles should be named that+".log" in the current +# directory. +# +# The combined log file is read from stdin. Records read +# will be appended to any existing log files. +# +%is_open = (); + +while ($log_line = ) { + # + # Get the first token from the log record; it's the + # identity of the virtual host to which the record + # applies. + # + ($vhost) = split (/\s/, $log_line); + # + # Normalize the virtual host name to all lowercase. + # If it's blank, the request was handled by the default + # server, so supply a default name. This shouldn't + # happen, but caution rocks. + # + $vhost = lc ($vhost) or "access"; + # + # if the vhost contains a "/" or "\", it is illegal so just use + # the default log to avoid any security issues due if it is interprted + # as a directory separator. + if ($vhost =~ m#[/\\]#) { $vhost = "access" } + # + # If the log file for this virtual host isn't opened + # yet, do it now. + # + if (! $is_open{$vhost}) { + open $vhost, ">>${vhost}.log" + or die ("Can't open ${vhost}.log"); + $is_open{$vhost} = 1; + } + # + # Strip off the first token (which may be null in the + # case of the default server), and write the edited + # record to the current log file. + # + $log_line =~ s/^\S*\s+//; + printf $vhost "%s", $log_line; +} +exit 0; diff --git a/trunk/support/suexec.c b/trunk/support/suexec.c new file mode 100644 index 0000000000..ed69226e10 --- /dev/null +++ b/trunk/support/suexec.c @@ -0,0 +1,636 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * suexec.c -- "Wrapper" support program for suEXEC behaviour for Apache + * + *********************************************************************** + * + * NOTE! : DO NOT edit this code!!! Unless you know what you are doing, + * editing this code might open up your system in unexpected + * ways to would-be crackers. Every precaution has been taken + * to make this code as safe as possible; alter it at your own + * risk. + * + *********************************************************************** + * + * + */ + +#include "apr.h" +#include "ap_config.h" +#include "suexec.h" + +#include +#include +#include +#include +#include +#if APR_HAVE_UNISTD_H +#include +#endif + +#include +#include +#include + +#ifdef HAVE_PWD_H +#include +#endif + +#ifdef HAVE_GRP_H +#include +#endif + +/* + *********************************************************************** + * There is no initgroups() in QNX, so I believe this is safe :-) + * Use cc -osuexec -3 -O -mf -DQNX suexec.c to compile. + * + * May 17, 1997. + * Igor N. Kovalenko -- infoh mail.wplus.net + *********************************************************************** + */ + +#if defined(NEED_INITGROUPS) +int initgroups(const char *name, gid_t basegid) +{ + /* QNX and MPE do not appear to support supplementary groups. */ + return 0; +} +#endif + +#if defined(SUNOS4) +extern char *sys_errlist[]; +#define strerror(x) sys_errlist[(x)] +#endif + +#if defined(PATH_MAX) +#define AP_MAXPATH PATH_MAX +#elif defined(MAXPATHLEN) +#define AP_MAXPATH MAXPATHLEN +#else +#define AP_MAXPATH 8192 +#endif + +#define AP_ENVBUF 256 + +extern char **environ; +static FILE *log = NULL; + +static const char *const safe_env_lst[] = +{ + /* variable name starts with */ + "HTTP_", + "SSL_", + + /* variable name is */ + "AUTH_TYPE=", + "CONTENT_LENGTH=", + "CONTENT_TYPE=", + "DATE_GMT=", + "DATE_LOCAL=", + "DOCUMENT_NAME=", + "DOCUMENT_PATH_INFO=", + "DOCUMENT_ROOT=", + "DOCUMENT_URI=", + "GATEWAY_INTERFACE=", + "HTTPS=", + "LAST_MODIFIED=", + "PATH_INFO=", + "PATH_TRANSLATED=", + "QUERY_STRING=", + "QUERY_STRING_UNESCAPED=", + "REMOTE_ADDR=", + "REMOTE_HOST=", + "REMOTE_IDENT=", + "REMOTE_PORT=", + "REMOTE_USER=", + "REDIRECT_HANDLER=", + "REDIRECT_QUERY_STRING=", + "REDIRECT_REMOTE_USER=", + "REDIRECT_STATUS=", + "REDIRECT_URL=", + "REQUEST_METHOD=", + "REQUEST_URI=", + "SCRIPT_FILENAME=", + "SCRIPT_NAME=", + "SCRIPT_URI=", + "SCRIPT_URL=", + "SERVER_ADMIN=", + "SERVER_NAME=", + "SERVER_ADDR=", + "SERVER_PORT=", + "SERVER_PROTOCOL=", + "SERVER_SIGNATURE=", + "SERVER_SOFTWARE=", + "UNIQUE_ID=", + "USER_NAME=", + "TZ=", + NULL +}; + + +static void err_output(int is_error, const char *fmt, va_list ap) +{ +#ifdef AP_LOG_EXEC + time_t timevar; + struct tm *lt; + + if (!log) { + if ((log = fopen(AP_LOG_EXEC, "a")) == NULL) { + fprintf(stderr, "suexec failure: could not open log file\n"); + perror("fopen"); + exit(1); + } + } + + if (is_error) { + fprintf(stderr, "suexec policy violation: see suexec log for more " + "details\n"); + } + + time(&timevar); + lt = localtime(&timevar); + + fprintf(log, "[%d-%.2d-%.2d %.2d:%.2d:%.2d]: ", + lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, + lt->tm_hour, lt->tm_min, lt->tm_sec); + + vfprintf(log, fmt, ap); + + fflush(log); +#endif /* AP_LOG_EXEC */ + return; +} + +static void log_err(const char *fmt,...) +{ +#ifdef AP_LOG_EXEC + va_list ap; + + va_start(ap, fmt); + err_output(1, fmt, ap); /* 1 == is_error */ + va_end(ap); +#endif /* AP_LOG_EXEC */ + return; +} + +static void log_no_err(const char *fmt,...) +{ +#ifdef AP_LOG_EXEC + va_list ap; + + va_start(ap, fmt); + err_output(0, fmt, ap); /* 0 == !is_error */ + va_end(ap); +#endif /* AP_LOG_EXEC */ + return; +} + +static void clean_env(void) +{ + char pathbuf[512]; + char **cleanenv; + char **ep; + int cidx = 0; + int idx; + + /* While cleaning the environment, the environment should be clean. + * (e.g. malloc() may get the name of a file for writing debugging info. + * Bad news if MALLOC_DEBUG_FILE is set to /etc/passwd. Sprintf() may be + * susceptible to bad locale settings....) + * (from PR 2790) + */ + char **envp = environ; + char *empty_ptr = NULL; + + environ = &empty_ptr; /* VERY safe environment */ + + if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) { + log_err("failed to malloc memory for environment\n"); + exit(120); + } + + sprintf(pathbuf, "PATH=%s", AP_SAFE_PATH); + cleanenv[cidx] = strdup(pathbuf); + cidx++; + + for (ep = envp; *ep && cidx < AP_ENVBUF-1; ep++) { + for (idx = 0; safe_env_lst[idx]; idx++) { + if (!strncmp(*ep, safe_env_lst[idx], + strlen(safe_env_lst[idx]))) { + cleanenv[cidx] = *ep; + cidx++; + break; + } + } + } + + cleanenv[cidx] = NULL; + + environ = cleanenv; +} + +int main(int argc, char *argv[]) +{ + int userdir = 0; /* ~userdir flag */ + uid_t uid; /* user information */ + gid_t gid; /* target group placeholder */ + char *target_uname; /* target user name */ + char *target_gname; /* target group name */ + char *target_homedir; /* target home directory */ + char *actual_uname; /* actual user name */ + char *actual_gname; /* actual group name */ + char *prog; /* name of this program */ + char *cmd; /* command to be executed */ + char cwd[AP_MAXPATH]; /* current working directory */ + char dwd[AP_MAXPATH]; /* docroot working directory */ + struct passwd *pw; /* password entry holder */ + struct group *gr; /* group entry holder */ + struct stat dir_info; /* directory info holder */ + struct stat prg_info; /* program info holder */ + + /* + * Start with a "clean" environment + */ + clean_env(); + + prog = argv[0]; + /* + * Check existence/validity of the UID of the user + * running this program. Error out if invalid. + */ + uid = getuid(); + if ((pw = getpwuid(uid)) == NULL) { + log_err("crit: invalid uid: (%ld)\n", uid); + exit(102); + } + /* + * See if this is a 'how were you compiled' request, and + * comply if so. + */ + if ((argc > 1) + && (! strcmp(argv[1], "-V")) + && ((uid == 0) +#ifdef _OSD_POSIX + /* User name comparisons are case insensitive on BS2000/OSD */ + || (! strcasecmp(AP_HTTPD_USER, pw->pw_name))) +#else /* _OSD_POSIX */ + || (! strcmp(AP_HTTPD_USER, pw->pw_name))) +#endif /* _OSD_POSIX */ + ) { +#ifdef AP_DOC_ROOT + fprintf(stderr, " -D AP_DOC_ROOT=\"%s\"\n", AP_DOC_ROOT); +#endif +#ifdef AP_GID_MIN + fprintf(stderr, " -D AP_GID_MIN=%d\n", AP_GID_MIN); +#endif +#ifdef AP_HTTPD_USER + fprintf(stderr, " -D AP_HTTPD_USER=\"%s\"\n", AP_HTTPD_USER); +#endif +#ifdef AP_LOG_EXEC + fprintf(stderr, " -D AP_LOG_EXEC=\"%s\"\n", AP_LOG_EXEC); +#endif +#ifdef AP_SAFE_PATH + fprintf(stderr, " -D AP_SAFE_PATH=\"%s\"\n", AP_SAFE_PATH); +#endif +#ifdef AP_SUEXEC_UMASK + fprintf(stderr, " -D AP_SUEXEC_UMASK=%03o\n", AP_SUEXEC_UMASK); +#endif +#ifdef AP_UID_MIN + fprintf(stderr, " -D AP_UID_MIN=%d\n", AP_UID_MIN); +#endif +#ifdef AP_USERDIR_SUFFIX + fprintf(stderr, " -D AP_USERDIR_SUFFIX=\"%s\"\n", AP_USERDIR_SUFFIX); +#endif + exit(0); + } + /* + * If there are a proper number of arguments, set + * all of them to variables. Otherwise, error out. + */ + if (argc < 4) { + log_err("too few arguments\n"); + exit(101); + } + target_uname = argv[1]; + target_gname = argv[2]; + cmd = argv[3]; + + /* + * Check to see if the user running this program + * is the user allowed to do so as defined in + * suexec.h. If not the allowed user, error out. + */ +#ifdef _OSD_POSIX + /* User name comparisons are case insensitive on BS2000/OSD */ + if (strcasecmp(AP_HTTPD_USER, pw->pw_name)) { + log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER); + exit(103); + } +#else /*_OSD_POSIX*/ + if (strcmp(AP_HTTPD_USER, pw->pw_name)) { + log_err("user mismatch (%s instead of %s)\n", pw->pw_name, AP_HTTPD_USER); + exit(103); + } +#endif /*_OSD_POSIX*/ + + /* + * Check for a leading '/' (absolute path) in the command to be executed, + * or attempts to back up out of the current directory, + * to protect against attacks. If any are + * found, error out. Naughty naughty crackers. + */ + if ((cmd[0] == '/') || (!strncmp(cmd, "../", 3)) + || (strstr(cmd, "/../") != NULL)) { + log_err("invalid command (%s)\n", cmd); + exit(104); + } + + /* + * Check to see if this is a ~userdir request. If + * so, set the flag, and remove the '~' from the + * target username. + */ + if (!strncmp("~", target_uname, 1)) { + target_uname++; + userdir = 1; + } + + /* + * Error out if the target username is invalid. + */ + if (strspn(target_uname, "1234567890") != strlen(target_uname)) { + if ((pw = getpwnam(target_uname)) == NULL) { + log_err("invalid target user name: (%s)\n", target_uname); + exit(105); + } + } + else { + if ((pw = getpwuid(atoi(target_uname))) == NULL) { + log_err("invalid target user id: (%s)\n", target_uname); + exit(121); + } + } + + /* + * Error out if the target group name is invalid. + */ + if (strspn(target_gname, "1234567890") != strlen(target_gname)) { + if ((gr = getgrnam(target_gname)) == NULL) { + log_err("invalid target group name: (%s)\n", target_gname); + exit(106); + } + gid = gr->gr_gid; + actual_gname = strdup(gr->gr_name); + } + else { + gid = atoi(target_gname); + 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; + actual_uname = strdup(pw->pw_name); + target_homedir = strdup(pw->pw_dir); + + /* + * Log the transaction here to be sure we have an open log + * before we setuid(). + */ + log_no_err("uid: (%s/%s) gid: (%s/%s) cmd: %s\n", + target_uname, actual_uname, + target_gname, actual_gname, + cmd); + + /* + * Error out if attempt is made to execute as root or as + * a UID less than AP_UID_MIN. Tsk tsk. + */ + if ((uid == 0) || (uid < AP_UID_MIN)) { + log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd); + exit(107); + } + + /* + * Error out if attempt is made to execute as root group + * or as a GID less than AP_GID_MIN. Tsk tsk. + */ + if ((gid == 0) || (gid < AP_GID_MIN)) { + log_err("cannot run as forbidden gid (%d/%s)\n", gid, cmd); + exit(108); + } + + /* + * Change UID/GID here so that the following tests work over NFS. + * + * Initialize the group access list for the target user, + * and setgid() to the target group. If unsuccessful, error out. + */ + if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0)) { + log_err("failed to setgid (%ld: %s)\n", gid, cmd); + exit(109); + } + + /* + * setuid() to the target user. Error out on fail. + */ + if ((setuid(uid)) != 0) { + log_err("failed to setuid (%ld: %s)\n", uid, cmd); + exit(110); + } + + /* + * Get the current working directory, as well as the proper + * document root (dependant upon whether or not it is a + * ~userdir request). Error out if we cannot get either one, + * or if the current working directory is not in the docroot. + * Use chdir()s and getcwd()s to avoid problems with symlinked + * directories. Yuck. + */ + if (getcwd(cwd, AP_MAXPATH) == NULL) { + log_err("cannot get current working directory\n"); + exit(111); + } + + if (userdir) { + if (((chdir(target_homedir)) != 0) || + ((chdir(AP_USERDIR_SUFFIX)) != 0) || + ((getcwd(dwd, AP_MAXPATH)) == NULL) || + ((chdir(cwd)) != 0)) { + log_err("cannot get docroot information (%s)\n", target_homedir); + exit(112); + } + } + else { + if (((chdir(AP_DOC_ROOT)) != 0) || + ((getcwd(dwd, AP_MAXPATH)) == NULL) || + ((chdir(cwd)) != 0)) { + log_err("cannot get docroot information (%s)\n", AP_DOC_ROOT); + exit(113); + } + } + + if ((strncmp(cwd, dwd, strlen(dwd))) != 0) { + log_err("command not in docroot (%s/%s)\n", cwd, cmd); + exit(114); + } + + /* + * Stat the cwd and verify it is a directory, or error out. + */ + if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) { + log_err("cannot stat directory: (%s)\n", cwd); + exit(115); + } + + /* + * Error out if cwd is writable by others. + */ + if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) { + log_err("directory is writable by others: (%s)\n", cwd); + exit(116); + } + + /* + * Error out if we cannot stat the program. + */ + if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) { + log_err("cannot stat program: (%s)\n", cmd); + exit(117); + } + + /* + * Error out if the program is writable by others. + */ + if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) { + log_err("file is writable by others: (%s/%s)\n", cwd, cmd); + exit(118); + } + + /* + * Error out if the file is setuid or setgid. + */ + if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) { + log_err("file is either setuid or setgid: (%s/%s)\n", cwd, cmd); + exit(119); + } + + /* + * Error out if the target name/group is different from + * the name/group of the cwd or the program. + */ + if ((uid != dir_info.st_uid) || + (gid != dir_info.st_gid) || + (uid != prg_info.st_uid) || + (gid != prg_info.st_gid)) { + log_err("target uid/gid (%ld/%ld) mismatch " + "with directory (%ld/%ld) or program (%ld/%ld)\n", + uid, gid, + dir_info.st_uid, dir_info.st_gid, + prg_info.st_uid, prg_info.st_gid); + exit(120); + } + /* + * Error out if the program is not executable for the user. + * Otherwise, she won't find any error in the logs except for + * "[error] Premature end of script headers: ..." + */ + if (!(prg_info.st_mode & S_IXUSR)) { + log_err("file has no execute permission: (%s/%s)\n", cwd, cmd); + exit(121); + } + +#ifdef AP_SUEXEC_UMASK + /* + * umask() uses inverse logic; bits are CLEAR for allowed access. + */ + if ((~AP_SUEXEC_UMASK) & 0022) { + log_err("notice: AP_SUEXEC_UMASK of %03o allows " + "write permission to group and/or other\n", AP_SUEXEC_UMASK); + } + umask(AP_SUEXEC_UMASK); +#endif /* AP_SUEXEC_UMASK */ + + /* + * Be sure to close the log file so the CGI can't + * mess with it. If the exec fails, it will be reopened + * automatically when log_err is called. Note that the log + * might not actually be open if AP_LOG_EXEC isn't defined. + * However, the "log" cell isn't ifdef'd so let's be defensive + * and assume someone might have done something with it + * outside an ifdef'd AP_LOG_EXEC block. + */ + if (log != NULL) { + fclose(log); + log = NULL; + } + + /* + * 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.) + * + * Uh oh. Still here. Where's the kaboom? There was supposed to be an + * EARTH-shattering kaboom! + * + * Oh well, log the failure and error out. + */ + log_err("(%d)%s: exec failed (%s)\n", errno, strerror(errno), cmd); + exit(255); +} diff --git a/trunk/support/suexec.h b/trunk/support/suexec.h new file mode 100644 index 0000000000..a1b5f81323 --- /dev/null +++ b/trunk/support/suexec.h @@ -0,0 +1,108 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * suexec.h -- user-definable variables for the suexec wrapper code. + * (See README.configure on how to customize these variables.) + */ + + +#ifndef _SUEXEC_H +#define _SUEXEC_H + +/* + * Include ap_config_layout so we can work out where the default htdocsdir + * and logsdir are. + */ +#include "ap_config_layout.h" + +/* + * HTTPD_USER -- Define as the username under which Apache normally + * runs. This is the only user allowed to execute + * this program. + */ +#ifndef AP_HTTPD_USER +#define AP_HTTPD_USER "www" +#endif + +/* + * UID_MIN -- Define this as the lowest UID allowed to be a target user + * for suEXEC. For most systems, 500 or 100 is common. + */ +#ifndef AP_UID_MIN +#define AP_UID_MIN 100 +#endif + +/* + * GID_MIN -- Define this as the lowest GID allowed to be a target group + * for suEXEC. For most systems, 100 is common. + */ +#ifndef AP_GID_MIN +#define AP_GID_MIN 100 +#endif + +/* + * USERDIR_SUFFIX -- Define to be the subdirectory under users' + * home directories where suEXEC access should + * be allowed. All executables under this directory + * will be executable by suEXEC as the user so + * they should be "safe" programs. If you are + * using a "simple" UserDir directive (ie. one + * without a "*" in it) this should be set to + * the same value. suEXEC will not work properly + * in cases where the UserDir directive points to + * a location that is not the same as the user's + * home directory as referenced in the passwd file. + * + * If you have VirtualHosts with a different + * UserDir for each, you will need to define them to + * all reside in one parent directory; then name that + * parent directory here. IF THIS IS NOT DEFINED + * PROPERLY, ~USERDIR CGI REQUESTS WILL NOT WORK! + * See the suEXEC documentation for more detailed + * information. + */ +#ifndef AP_USERDIR_SUFFIX +#define AP_USERDIR_SUFFIX "public_html" +#endif + +/* + * LOG_EXEC -- Define this as a filename if you want all suEXEC + * transactions and errors logged for auditing and + * debugging purposes. + */ +#ifndef AP_LOG_EXEC +#define AP_LOG_EXEC DEFAULT_EXP_LOGFILEDIR "/suexec_log" /* Need me? */ +#endif + +/* + * DOC_ROOT -- Define as the DocumentRoot set for Apache. This + * will be the only hierarchy (aside from UserDirs) + * that can be used for suEXEC behavior. + */ +#ifndef AP_DOC_ROOT +#define AP_DOC_ROOT DEFAULT_EXP_HTDOCSDIR +#endif + +/* + * SAFE_PATH -- Define a safe PATH environment to pass to CGI executables. + * + */ +#ifndef AP_SAFE_PATH +#define AP_SAFE_PATH "/usr/local/bin:/usr/bin:/bin" +#endif + +#endif /* _SUEXEC_H */ diff --git a/trunk/support/utilitiesnw.def b/trunk/support/utilitiesnw.def new file mode 100644 index 0000000000..426b8c96be --- /dev/null +++ b/trunk/support/utilitiesnw.def @@ -0,0 +1,3 @@ +MODULE APRLIB.NLM +MODULE LIBC.NLM + diff --git a/trunk/support/win32/ApacheMonitor.c b/trunk/support/win32/ApacheMonitor.c new file mode 100644 index 0000000000..a35313ba78 --- /dev/null +++ b/trunk/support/win32/ApacheMonitor.c @@ -0,0 +1,1765 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ==================================================================== + * ApacheMonitor.c Simple program to manage and monitor Apache services. + * + * Contributed by Mladen Turk + * + * 05 Aug 2001 + * ==================================================================== + */ + +#define _WIN32_WINNT 0x0400 +#ifndef STRICT +#define STRICT +#endif +#ifndef OEMRESOURCE +#define OEMRESOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "ApacheMonitor.h" + + +#define OS_VERSION_WIN9X 1 +#define OS_VERSION_WINNT 2 +#define OS_VERSION_WIN2K 3 +/* Should be enough */ +#define MAX_APACHE_SERVICES 128 +#define MAX_APACHE_COMPUTERS 32 + +#define WM_TRAYMESSAGE (WM_APP+1) +#define WM_UPDATEMESSAGE (WM_USER+1) +#define WM_MANAGEMESSAGE (WM_USER+2) +#define WM_TIMER_REFRESH 10 +#define WM_TIMER_RESCAN 11 +#define SERVICE_APACHE_RESTART 128 +#define XBITMAP 16 +#define YBITMAP 16 +#define MAX_LOADSTRING 100 +#define REFRESH_TIME 2000 /* service refresh time (ms) */ +#define RESCAN_TIME 20000 /* registry rescan time (ms) */ + +typedef struct _st_APACHE_SERVICE +{ + LPSTR szServiceName; + LPSTR szDisplayName; + LPSTR szDescription; + LPSTR szImagePath; + LPSTR szComputerName; + DWORD dwPid; +} ST_APACHE_SERVICE; + +typedef struct _st_MONITORED_COMPUTERS +{ + LPSTR szComputerName; + HKEY hRegistry; +} ST_MONITORED_COMP; + +/* Global variables */ +HINSTANCE g_hInstance = NULL; +CHAR *g_szTitle; /* The title bar text */ +CHAR *g_szWindowClass; /* Window Class Name */ +HICON g_icoStop; +HICON g_icoRun; +UINT g_bUiTaskbarCreated; +DWORD g_dwOSVersion; +BOOL g_bDlgServiceOn = FALSE; +BOOL g_bConsoleRun = FALSE; +ST_APACHE_SERVICE g_stServices[MAX_APACHE_SERVICES]; +ST_MONITORED_COMP g_stComputers[MAX_APACHE_COMPUTERS]; + +HBITMAP g_hBmpStart, g_hBmpStop; +HBITMAP g_hBmpPicture, g_hBmpOld; +BOOL g_bRescanServices; +HWND g_hwndServiceDlg; +HWND g_hwndMain; +HWND g_hwndStdoutList; +HWND g_hwndConnectDlg; +HCURSOR g_hCursorHourglass; +HCURSOR g_hCursorArrow; + +HANDLE g_hpipeOutRead; +HANDLE g_hpipeOutWrite; +HANDLE g_hpipeInRead; +HANDLE g_hpipeInWrite; +HANDLE g_hpipeStdError; +LANGID g_LangID; +PROCESS_INFORMATION g_lpRedirectProc; +CRITICAL_SECTION g_stcSection; +LPSTR g_szLocalHost; + +/* locale language support */ +static CHAR *g_lpMsg[IDS_MSG_LAST - IDS_MSG_FIRST + 1]; + + +void am_ClearServicesSt() +{ + int i; + for (i = 0; i < MAX_APACHE_SERVICES; i++) + { + if (g_stServices[i].szServiceName) { + free(g_stServices[i].szServiceName); + } + if (g_stServices[i].szDisplayName) { + free(g_stServices[i].szDisplayName); + } + if (g_stServices[i].szDescription) { + free(g_stServices[i].szDescription); + } + if (g_stServices[i].szImagePath) { + free(g_stServices[i].szImagePath); + } + if (g_stServices[i].szComputerName) { + free(g_stServices[i].szComputerName); + } + + } + memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES); + +} + + +void am_ClearComputersSt() +{ + int i; + for (i = 0; i < MAX_APACHE_COMPUTERS; i++) { + if (g_stComputers[i].szComputerName) { + free(g_stComputers[i].szComputerName); + RegCloseKey(g_stComputers[i].hRegistry); + } + } + memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS); + +} + + +BOOL am_IsComputerConnected(LPSTR szComputerName) +{ + int i = 0; + while (g_stComputers[i].szComputerName != NULL) { + if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) { + return TRUE; + } + ++i; + } + return FALSE; +} + + +void am_DisconnectComputer(LPSTR szComputerName) +{ + int i = 0, j; + while (g_stComputers[i].szComputerName != NULL) { + if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) { + break; + } + ++i; + } + if (g_stComputers[i].szComputerName != NULL) { + free(g_stComputers[i].szComputerName); + RegCloseKey(g_stComputers[i].hRegistry); + for (j = i; j < MAX_APACHE_COMPUTERS - 1; j++) { + g_stComputers[i].szComputerName= g_stComputers[i+1].szComputerName; + g_stComputers[i].hRegistry = g_stComputers[i+1].hRegistry; + } + for (i = j; i < MAX_APACHE_COMPUTERS; i++) { + g_stComputers[i].szComputerName = NULL; + g_stComputers[i].hRegistry = NULL; + } + } + +} + + +void ErrorMessage(LPCSTR szError, BOOL bFatal) +{ + LPVOID lpMsgBuf = NULL; + if (szError) { + MessageBox(NULL, szError, g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST], + MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION)); + } + else { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), g_LangID, + (LPSTR) &lpMsgBuf, 0, NULL); + MessageBox(NULL, (LPCSTR)lpMsgBuf, + g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST], + MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION)); + LocalFree(lpMsgBuf); + } + if (bFatal) { + PostQuitMessage(0); + } +} + + +BOOL am_ConnectComputer(LPSTR szComputerName) +{ + int i = 0; + HKEY hKeyRemote; + char szTmp[MAX_PATH]; + + while (g_stComputers[i].szComputerName != NULL) { + if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) { + return FALSE; + } + ++i; + } + if (i > MAX_APACHE_COMPUTERS - 1) { + return FALSE; + } + if (RegConnectRegistry(szComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote) + != ERROR_SUCCESS) { + sprintf(szTmp, g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST], + szComputerName); + ErrorMessage(szTmp, FALSE); + return FALSE; + } + else { + g_stComputers[i].szComputerName = strdup(szComputerName); + g_stComputers[i].hRegistry = hKeyRemote; + return TRUE; + } +} + + +LPSTR GetStringRes(int id) +{ + static CHAR buffer[MAX_PATH]; + + buffer[0] = 0; + LoadString(GetModuleHandle(NULL), id, buffer, MAX_PATH); + return buffer; +} + + +BOOL GetSystemOSVersion(LPDWORD dwVersion) +{ + OSVERSIONINFO osvi; + /* + Try calling GetVersionEx using the OSVERSIONINFOEX structure. + If that fails, try using the OSVERSIONINFO structure. + */ + memset(&osvi, 0, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if (!GetVersionEx(&osvi)) { + return FALSE; + } + + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + if (osvi.dwMajorVersion <= 4) { + *dwVersion = OS_VERSION_WINNT; + } + else if (osvi.dwMajorVersion == 5) { + *dwVersion = OS_VERSION_WIN2K; + } + else { + return FALSE; + } + break; + + case VER_PLATFORM_WIN32_WINDOWS: + *dwVersion = OS_VERSION_WIN9X; + break; + + case VER_PLATFORM_WIN32s: + default: + *dwVersion = 0; + return FALSE; + } + return TRUE; +} + + +static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage) +{ + NOTIFYICONDATA nid; + int i = 0, n = 0; + + memset(&nid, 0, sizeof(nid)); + nid.cbSize = sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = 0xFF; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + nid.uCallbackMessage = WM_TRAYMESSAGE; + + while (g_stServices[i].szServiceName != NULL) + { + if (g_stServices[i].dwPid != 0) { + ++n; + } + ++i; + } + if (dwMessage != NIM_DELETE) + { + if (n) { + nid.hIcon = g_icoRun; + } + else { + nid.hIcon = g_icoStop; + } + } + else { + nid.hIcon = NULL; + } + if (n == i && n > 0) { + lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]); + } + else if (n) { + sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i); + } + else if (i) { + sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i); + } + else { + lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES - IDS_MSG_FIRST]); + } + Shell_NotifyIcon(dwMessage, &nid); +} + + +void appendMenuItem(HMENU hMenu, UINT uMenuId, LPSTR szName, + BOOL fDefault, BOOL fEnabled) +{ + MENUITEMINFO mii; + + memset(&mii, 0, sizeof(MENUITEMINFO)); + mii.cbSize = sizeof(MENUITEMINFO); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + if (lstrlen(szName)) + { + mii.fType = MFT_STRING; + mii.wID = uMenuId; + if (fDefault) { + mii.fState = MFS_DEFAULT; + } + if (!fEnabled) { + mii.fState |= MFS_DISABLED; + } + mii.dwTypeData = szName; + } + else { + mii.fType = MFT_SEPARATOR; + } + InsertMenuItem(hMenu, uMenuId, FALSE, &mii); +} + + +void appendServiceMenu(HMENU hMenu, UINT uMenuId, + LPSTR szServiceName, BOOL fRunning) +{ + MENUITEMINFO mii; + HMENU smh; + + smh = CreatePopupMenu(); + + appendMenuItem(smh, IDM_SM_START + uMenuId, + g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST], FALSE, !fRunning); + appendMenuItem(smh, IDM_SM_STOP + uMenuId, + g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST], FALSE, fRunning); + appendMenuItem(smh, IDM_SM_RESTART + uMenuId, + g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST], FALSE, fRunning); + + memset(&mii, 0, sizeof(MENUITEMINFO)); + mii.cbSize = sizeof(MENUITEMINFO); + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU + | MIIM_CHECKMARKS; + mii.fType = MFT_STRING; + mii.wID = uMenuId; + mii.hbmpChecked = g_hBmpStart; + mii.hbmpUnchecked = g_hBmpStop; + mii.dwTypeData = szServiceName; + mii.hSubMenu = smh; + mii.fState = fRunning ? MFS_CHECKED : MFS_UNCHECKED; + InsertMenuItem(hMenu, IDM_SM_SERVICE + uMenuId, FALSE, &mii); +} + + +void ShowTryPopupMenu(HWND hWnd) +{ + /* create popup menu */ + HMENU hMenu = CreatePopupMenu(); + POINT pt; + + if (hMenu) + { + appendMenuItem(hMenu, IDM_RESTORE, + g_lpMsg[IDS_MSG_MNUSHOW - IDS_MSG_FIRST], + TRUE, TRUE); + if (g_dwOSVersion >= OS_VERSION_WINNT) { + appendMenuItem(hMenu, IDC_SMANAGER, + g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST], + FALSE, TRUE); + } + appendMenuItem(hMenu, 0, "", FALSE, TRUE); + appendMenuItem(hMenu, IDM_EXIT, + g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST], + FALSE, TRUE); + + if (!SetForegroundWindow(hWnd)) { + SetForegroundWindow(NULL); + } + GetCursorPos(&pt); + TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, + pt.x, pt.y, 0, hWnd, NULL); + DestroyMenu(hMenu); + } +} + + +void ShowTryServicesMenu(HWND hWnd) +{ + /* create services list popup menu and submenus */ + HMENU hMenu = CreatePopupMenu(); + POINT pt; + int i = 0; + + if (hMenu) + { + while (g_stServices[i].szServiceName != NULL) + { + appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName, + g_stServices[i].dwPid != 0); + ++i; + } + if (i) + { + if (!SetForegroundWindow(hWnd)) { + SetForegroundWindow(NULL); + } + GetCursorPos(&pt); + TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, + pt.x, pt.y, 0, hWnd, NULL); + DestroyMenu(hMenu); + } + } +} + + +BOOL CenterWindow(HWND hwndChild) +{ + RECT rChild, rWorkArea; + int wChild, hChild; + 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 limits of the 'workarea' */ + bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), + &rWorkArea, 0); + if (!bResult) { + rWorkArea.left = rWorkArea.top = 0; + rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); + rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); + } + + /* Calculate new X and Y position*/ + xNew = (rWorkArea.right - wChild) / 2; + yNew = (rWorkArea.bottom - hChild) / 2; + return SetWindowPos(hwndChild, HWND_TOP, xNew, yNew, 0, 0, + SWP_NOSIZE | SWP_SHOWWINDOW); +} + + +static void addListBoxItem(HWND hDlg, LPSTR lpStr, HBITMAP hBmp) +{ + LRESULT nItem; + + nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr); + SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp); +} + + +static void addListBoxString(HWND hListBox, LPSTR lpStr) +{ + static int nItems = 0; + if (!g_bDlgServiceOn) { + return; + } + ++nItems; + if (nItems > MAX_LOADSTRING) + { + SendMessage(hListBox, LB_RESETCONTENT, 0, 0); + nItems = 1; + } + ListBox_SetCurSel(hListBox, + ListBox_AddString(hListBox, lpStr)); + +} + + +static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter) +{ + static BYTE lpBuffer[MAX_PATH+1]; + int nPtr = 0; + BYTE ch; + DWORD dwReaded; + + while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE) + { + if (dwReaded > 0) + { + if (ch == '\n' || nPtr >= MAX_PATH) + { + lpBuffer[nPtr] = '\0'; + addListBoxString(g_hwndStdoutList, lpBuffer); + nPtr = 0; + } + else if (ch == '\t' && nPtr < (MAX_PATH - 4)) + { + int i; + for (i = 0; i < 4; ++i) { + lpBuffer[nPtr++] = ' '; + } + } + else if (ch != '\r') { + lpBuffer[nPtr++] = ch; + } + } + } + CloseHandle(g_hpipeInWrite); + CloseHandle(g_hpipeOutRead); + CloseHandle(g_hpipeStdError); + return 0; +} + + +DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter) +{ + WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE); + CloseHandle(g_lpRedirectProc.hThread); + MessageBeep(100); + g_bConsoleRun = FALSE; + SetCursor(g_hCursorArrow); + return 0; +} + + +BOOL RunRedirectedConsole(LPSTR szCmdLine) +{ + DWORD dwThreadId; + HANDLE hProc; + STARTUPINFO stInfo; + BOOL bResult; + + memset(&stInfo, 0, sizeof(stInfo)); + stInfo.cb = sizeof(stInfo); + stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; + stInfo.wShowWindow = SW_HIDE; + + hProc = GetCurrentProcess(); + + if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH)) { + ErrorMessage(NULL, TRUE); + } + if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8)) { + ErrorMessage(NULL, TRUE); + } + DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE, + DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); + DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE, + DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); + DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE, + DUPLICATE_SAME_ACCESS); + if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError) { + ErrorMessage(NULL, TRUE); + } + stInfo.hStdInput = g_hpipeInRead; + stInfo.hStdOutput = g_hpipeOutWrite; + stInfo.hStdError = g_hpipeStdError; + + bResult = CreateProcess(NULL, + szCmdLine, + NULL, + NULL, + TRUE, + CREATE_SUSPENDED, + NULL, + NULL, + &stInfo, + &g_lpRedirectProc); + + + CloseHandle(g_hpipeInRead); + CloseHandle(g_hpipeOutWrite); + CloseHandle(g_hpipeStdError); + + if (!bResult) + { + CloseHandle(g_hpipeInWrite); + CloseHandle(g_hpipeOutRead); + CloseHandle(g_hpipeStdError); + return FALSE; + } + + CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread, + 0, 0, &dwThreadId)); + ResumeThread(g_lpRedirectProc.hThread); + CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread, + 0, 0, &dwThreadId)); + + return TRUE; +} + + +BOOL RunAndForgetConsole(LPSTR szCmdLine, BOOL bRedirectConsole) +{ + STARTUPINFO stInfo; + PROCESS_INFORMATION prInfo; + BOOL bResult; + + if (bRedirectConsole) { + return RunRedirectedConsole(szCmdLine); + } + + memset(&stInfo, 0, sizeof(stInfo)); + stInfo.cb = sizeof(stInfo); + stInfo.dwFlags = STARTF_USESHOWWINDOW; + stInfo.wShowWindow = SW_HIDE; + + bResult = CreateProcess(NULL, + szCmdLine, + NULL, + NULL, + TRUE, + CREATE_NEW_CONSOLE, + NULL, + NULL, + &stInfo, + &prInfo); + + if (!bResult) { + return FALSE; + } + if (g_dwOSVersion == OS_VERSION_WIN9X) { + /* give some time to rescan the status */ + Sleep(2000); + } + CloseHandle(prInfo.hThread); + CloseHandle(prInfo.hProcess); + return TRUE; +} + + +BOOL ApacheManageService(LPCSTR szServiceName, LPCSTR szImagePath, + LPSTR szComputerName, DWORD dwCommand) +{ + CHAR szBuf[MAX_PATH]; + CHAR szMsg[MAX_PATH]; + LPSTR sPos; + BOOL retValue; + BOOL serviceFlag = TRUE; + SC_HANDLE schService; + SC_HANDLE schSCManager; + SERVICE_STATUS schSStatus; + int ticks; + + if (g_dwOSVersion == OS_VERSION_WIN9X) + { + sPos = strstr(szImagePath, "-k start"); + if (sPos) + { + lstrcpyn(szBuf, szImagePath, (int)(sPos - szImagePath)); + switch (dwCommand) + { + case SERVICE_CONTROL_STOP: + lstrcat(szBuf, " -k shutdown -n "); + break; + + case SERVICE_CONTROL_CONTINUE: + sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + lstrcat(szBuf, " -k start -n "); + serviceFlag = FALSE; + break; + + case SERVICE_APACHE_RESTART: + lstrcat(szBuf, " -k restart -n "); + break; + + default: + return FALSE; + } + lstrcat(szBuf, szServiceName); + } + else { + return FALSE; + } + g_bConsoleRun = TRUE; + SetCursor(g_hCursorHourglass); + if (!RunAndForgetConsole(szBuf, serviceFlag)) + { + ErrorMessage(NULL, FALSE); + g_bConsoleRun = FALSE; + SetCursor(g_hCursorArrow); + return FALSE; + } + else if (!serviceFlag) + { + sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + g_bConsoleRun = FALSE; + SetCursor(g_hCursorArrow); + return TRUE; + } + } + else + { + schSCManager = OpenSCManager(szComputerName, NULL, + SC_MANAGER_CONNECT); + if (!schSCManager) { + return FALSE; + } + + schService = OpenService(schSCManager, szServiceName, + SERVICE_QUERY_STATUS | SERVICE_START | + SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL); + if (schService != NULL) + { + retValue = FALSE; + g_bConsoleRun = TRUE; + SetCursor(g_hCursorHourglass); + switch (dwCommand) + { + case SERVICE_CONTROL_STOP: + sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + if (ControlService(schService, SERVICE_CONTROL_STOP, + &schSStatus)) { + Sleep(1000); + while (QueryServiceStatus(schService, &schSStatus)) + { + if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING) + { + Sleep(1000); + } + else { + break; + } + } + } + if (QueryServiceStatus(schService, &schSStatus)) + { + if (schSStatus.dwCurrentState == SERVICE_STOPPED) + { + retValue = TRUE; + sprintf(szMsg, + g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + } + } + break; + + case SERVICE_CONTROL_CONTINUE: + sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + + if (StartService(schService, 0, NULL)) + { + Sleep(1000); + while (QueryServiceStatus(schService, &schSStatus)) + { + if (schSStatus.dwCurrentState == SERVICE_START_PENDING) + { + Sleep(1000); + } + else { + break; + } + } + } + if (QueryServiceStatus(schService, &schSStatus)) + { + if (schSStatus.dwCurrentState == SERVICE_RUNNING) + { + retValue = TRUE; + sprintf(szMsg, + g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + } + } + break; + + case SERVICE_APACHE_RESTART: + sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + if (ControlService(schService, SERVICE_APACHE_RESTART, + &schSStatus)) + { + ticks = 60; + while (schSStatus.dwCurrentState == SERVICE_START_PENDING) + { + Sleep(1000); + if (!QueryServiceStatus(schService, &schSStatus)) + { + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + g_bConsoleRun = FALSE; + SetCursor(g_hCursorArrow); + return FALSE; + } + if (!--ticks) { + break; + } + } + } + if (schSStatus.dwCurrentState == SERVICE_RUNNING) + { + retValue = TRUE; + sprintf(szMsg, + g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST], + szServiceName); + addListBoxString(g_hwndStdoutList, szMsg); + } + break; + } + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + if (!retValue) { + ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], + FALSE); + } + g_bConsoleRun = FALSE; + SetCursor(g_hCursorArrow); + return retValue; + } + else { + g_bRescanServices = TRUE; + } + CloseServiceHandle(schSCManager); + return FALSE; + } + + return FALSE; +} + + +BOOL IsServiceRunning(LPCSTR szServiceName, LPCSTR szComputerName, + LPDWORD lpdwPid) +{ + DWORD dwPid; + HWND hWnd; + SC_HANDLE schService; + SC_HANDLE schSCManager; + SERVICE_STATUS schSStatus; + + if (g_dwOSVersion == OS_VERSION_WIN9X) + { + hWnd = FindWindow("ApacheWin95ServiceMonitor", szServiceName); + if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid)) + { + *lpdwPid = 1; + return TRUE; + } + else { + return FALSE; + } + } + else + { + dwPid = 0; + schSCManager = OpenSCManager(szComputerName, NULL, + SC_MANAGER_CONNECT); + if (!schSCManager) { + return FALSE; + } + + schService = OpenService(schSCManager, szServiceName, + SERVICE_QUERY_STATUS); + if (schService != NULL) + { + if (QueryServiceStatus(schService, &schSStatus)) + { + dwPid = schSStatus.dwCurrentState; + if (lpdwPid) { + *lpdwPid = 1; + } + } + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return dwPid == SERVICE_RUNNING ? TRUE : FALSE; + } + else { + g_bRescanServices = TRUE; + } + CloseServiceHandle(schSCManager); + return FALSE; + + } + + return FALSE; +} + + +BOOL FindRunningServices(void) +{ + int i = 0; + DWORD dwPid; + BOOL rv = FALSE; + while (g_stServices[i].szServiceName != NULL) + { + if (!IsServiceRunning(g_stServices[i].szServiceName, + g_stServices[i].szComputerName, &dwPid)) { + dwPid = 0; + } + if (g_stServices[i].dwPid != dwPid) { + rv = TRUE; + } + g_stServices[i].dwPid = dwPid; + ++i; + } + return rv; +} + + +BOOL GetApacheServicesStatus() +{ + CHAR szKey[MAX_PATH]; + CHAR achKey[MAX_PATH]; + CHAR szImagePath[MAX_PATH]; + CHAR szBuf[MAX_PATH]; + CHAR szTmp[MAX_PATH]; + HKEY hKey, hSubKey, hKeyRemote; + DWORD retCode, rv, dwKeyType; + DWORD dwBufLen = MAX_PATH; + int i, stPos = 0; + int computers = 0; + + g_bRescanServices = FALSE; + + am_ClearServicesSt(); + while (g_stComputers[computers].szComputerName != NULL) { + hKeyRemote = g_stComputers[computers].hRegistry; + retCode = RegOpenKeyEx(hKeyRemote, + "System\\CurrentControlSet\\Services\\", + 0, KEY_READ, &hKey); + if (retCode != ERROR_SUCCESS) + { + ErrorMessage(NULL, FALSE); + return FALSE; + } + for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++) + { + retCode = RegEnumKey(hKey, i, achKey, MAX_PATH); + if (retCode == ERROR_SUCCESS) + { + lstrcpy(szKey, "System\\CurrentControlSet\\Services\\"); + lstrcat(szKey, achKey); + + if (RegOpenKeyEx(hKeyRemote, szKey, 0, + KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS) + { + dwBufLen = MAX_PATH; + rv = RegQueryValueEx(hSubKey, "ImagePath", NULL, + &dwKeyType, szImagePath, &dwBufLen); + + if (rv == ERROR_SUCCESS + && (dwKeyType == REG_SZ + || dwKeyType == REG_EXPAND_SZ) + && dwBufLen) + { + lstrcpy(szBuf, szImagePath); + CharLower(szBuf); + /* the service name could be httpd*.exe or Apache*.exe */ + if (((strstr(szBuf, "\\apache") != NULL) + || (strstr(szBuf, "\\httpd") != NULL)) + && strstr(szBuf, ".exe") + && (strstr(szBuf, "--ntservice") != NULL + || strstr(szBuf, "-k ") != NULL)) + { + g_stServices[stPos].szServiceName = strdup(achKey); + g_stServices[stPos].szImagePath = + strdup(szImagePath); + g_stServices[stPos].szComputerName = + strdup(g_stComputers[computers].szComputerName); + dwBufLen = MAX_PATH; + if (RegQueryValueEx(hSubKey, "Description", NULL, + &dwKeyType, szBuf, &dwBufLen) + == ERROR_SUCCESS) { + g_stServices[stPos].szDescription = + strdup(szBuf); + } + dwBufLen = MAX_PATH; + if (RegQueryValueEx(hSubKey, "DisplayName", NULL, + &dwKeyType, szBuf, &dwBufLen) + == ERROR_SUCCESS) + { + if (strcmp(g_stComputers[computers] + .szComputerName, g_szLocalHost) != 0) + { + strcpy(szTmp, g_stComputers[computers] + .szComputerName + 2); + strcat(szTmp, "@"); + strcat(szTmp, szBuf); + } + else { + strcpy(szTmp, szBuf); + } + g_stServices[stPos].szDisplayName + = strdup(szTmp); + + } + ++stPos; + if (stPos >= MAX_APACHE_SERVICES) { + retCode = !ERROR_SUCCESS; + } + } + } + RegCloseKey(hSubKey); + } + } + } + ++computers; + } + RegCloseKey(hKey); + FindRunningServices(); + return TRUE; +} + + +LRESULT CALLBACK ConnectDlgProc(HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam) +{ + CHAR szCmp[MAX_COMPUTERNAME_LENGTH+4]; + switch (message) + { + case WM_INITDIALOG: + ShowWindow(hDlg, SW_HIDE); + g_hwndConnectDlg = hDlg; + CenterWindow(hDlg); + ShowWindow(hDlg, SW_SHOW); + SetFocus(GetDlgItem(hDlg, IDC_COMPUTER)); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + memset(szCmp, 0, MAX_COMPUTERNAME_LENGTH+4); + strcpy(szCmp, "\\\\"); + SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), WM_GETTEXT, + (WPARAM) MAX_COMPUTERNAME_LENGTH, + (LPARAM) szCmp+2); + + strupr(szCmp); + if (strlen(szCmp) < 3) { + EndDialog(hDlg, TRUE); + return TRUE; + } + am_ConnectComputer(szCmp); + SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0); + + case IDCANCEL: + EndDialog(hDlg, TRUE); + return TRUE; + + case IDC_LBROWSE: + { + BROWSEINFO bi; + ITEMIDLIST *il; + LPMALLOC pMalloc; + memset(&bi, 0, sizeof(BROWSEINFO)); + SHGetSpecialFolderLocation(hDlg, CSIDL_NETWORK, &il); + + bi.lpszTitle = "ApacheMonitor :\nSelect Network Computer!"; + bi.pszDisplayName = szCmp; + bi.hwndOwner = hDlg; + bi.ulFlags = BIF_BROWSEFORCOMPUTER; + bi.lpfn = NULL; + bi.lParam = 0; + bi.iImage = 0; + bi.pidlRoot = il; + + if (SHBrowseForFolder(&bi) != NULL) { + SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), + WM_SETTEXT, + (WPARAM) NULL, (LPARAM) szCmp); + } + if (SHGetMalloc(&pMalloc)) { + pMalloc->lpVtbl->Free(pMalloc, il); + pMalloc->lpVtbl->Release(pMalloc); + } + return TRUE; + } + } + break; + + case WM_QUIT: + case WM_CLOSE: + EndDialog(hDlg, TRUE); + return TRUE; + + default: + return FALSE; + } + return FALSE; + +} + + +LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message, + WPARAM wParam, LPARAM lParam) +{ + CHAR szBuf[MAX_PATH]; + HWND hListBox; + static HWND hStatusBar; + TEXTMETRIC tm; + int i, y; + HDC hdcMem; + RECT rcBitmap; + LRESULT nItem; + LPMEASUREITEMSTRUCT lpmis; + LPDRAWITEMSTRUCT lpdis; + + memset(szBuf, 0, MAX_PATH); + switch (message) + { + case WM_INITDIALOG: + ShowWindow(hDlg, SW_HIDE); + g_hwndServiceDlg = hDlg; + SetWindowText(hDlg, g_szTitle); + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); + SetWindowText(GetDlgItem(hDlg, IDC_SSTART), + g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST]); + SetWindowText(GetDlgItem(hDlg, IDC_SSTOP), + g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST]); + SetWindowText(GetDlgItem(hDlg, IDC_SRESTART), + g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST]); + SetWindowText(GetDlgItem(hDlg, IDC_SMANAGER), + g_lpMsg[IDS_MSG_SERVICES - IDS_MSG_FIRST]); + SetWindowText(GetDlgItem(hDlg, IDC_SCONNECT), + g_lpMsg[IDS_MSG_CONNECT - IDS_MSG_FIRST]); + SetWindowText(GetDlgItem(hDlg, IDC_SEXIT), + g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST]); + if (g_dwOSVersion < OS_VERSION_WINNT) + { + ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_SCONNECT), SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_SDISCONN), SW_HIDE); + } + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT); + hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */ + | WS_CHILD | WS_VISIBLE, + "", hDlg, IDC_STATBAR); + if (GetApacheServicesStatus()) + { + i = 0; + while (g_stServices[i].szServiceName != NULL) + { + addListBoxItem(hListBox, g_stServices[i].szDisplayName, + g_stServices[i].dwPid == 0 ? g_hBmpStop + : g_hBmpStart); + ++i; + } + } + CenterWindow(hDlg); + ShowWindow(hDlg, SW_SHOW); + SetFocus(hListBox); + SendMessage(hListBox, LB_SETCURSEL, 0, 0); + return TRUE; + break; + + case WM_MANAGEMESSAGE: + ApacheManageService(g_stServices[LOWORD(wParam)].szServiceName, + g_stServices[LOWORD(wParam)].szImagePath, + g_stServices[LOWORD(wParam)].szComputerName, + LOWORD(lParam)); + + return TRUE; + break; + + case WM_UPDATEMESSAGE: + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + SendMessage(hListBox, LB_RESETCONTENT, 0, 0); + SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)""); + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); + i = 0; + while (g_stServices[i].szServiceName != NULL) + { + addListBoxItem(hListBox, g_stServices[i].szDisplayName, + g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart); + ++i; + } + SendMessage(hListBox, LB_SETCURSEL, 0, 0); + /* Dirty hack to bring the window to the foreground */ + SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + SetFocus(hListBox); + return TRUE; + break; + + case WM_MEASUREITEM: + lpmis = (LPMEASUREITEMSTRUCT) lParam; + lpmis->itemHeight = YBITMAP; + return TRUE; + + case WM_SETCURSOR: + if (g_bConsoleRun) { + SetCursor(g_hCursorHourglass); + } + else { + SetCursor(g_hCursorArrow); + } + return TRUE; + + case WM_DRAWITEM: + lpdis = (LPDRAWITEMSTRUCT) lParam; + if (lpdis->itemID == -1) { + break; + } + switch (lpdis->itemAction) + { + case ODA_SELECT: + case ODA_DRAWENTIRE: + g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem, + LB_GETITEMDATA, + lpdis->itemID, (LPARAM) 0); + + hdcMem = CreateCompatibleDC(lpdis->hDC); + g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture); + + BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, + lpdis->rcItem.right - lpdis->rcItem.left, + lpdis->rcItem.bottom - lpdis->rcItem.top, + hdcMem, 0, 0, SRCCOPY); + SendMessage(lpdis->hwndItem, LB_GETTEXT, + lpdis->itemID, (LPARAM) szBuf); + + GetTextMetrics(lpdis->hDC, &tm); + y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; + + SelectObject(hdcMem, g_hBmpOld); + DeleteDC(hdcMem); + + rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2; + rcBitmap.top = lpdis->rcItem.top; + rcBitmap.right = lpdis->rcItem.right; + rcBitmap.bottom = lpdis->rcItem.top + YBITMAP; + + if (lpdis->itemState & ODS_SELECTED) + { + if (g_hBmpPicture == g_hBmpStop) + { + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE); + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); + } + else if (g_hBmpPicture == g_hBmpStart) + { + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE); + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE); + } + else { + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); + } + if (strcmp(g_stServices[lpdis->itemID].szComputerName, + g_szLocalHost) == 0) { + Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); + } + else { + Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), TRUE); + } + + if (g_stServices[lpdis->itemID].szDescription) { + SendMessage(hStatusBar, SB_SETTEXT, 0, + (LPARAM)g_stServices[lpdis->itemID].szDescription); + } + else { + SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)""); + } + SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); + FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT)); + } + else + { + SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); + SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW)); + FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1)); + } + TextOut(lpdis->hDC, XBITMAP + 6, y, szBuf, (int)strlen(szBuf)); + break; + + case ODA_FOCUS: + break; + } + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDL_SERVICES: + switch (HIWORD(wParam)) + { + case LBN_DBLCLK: + /* if started then stop, if stopped then start */ + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); + if (nItem != LB_ERR) + { + g_hBmpPicture = (HBITMAP)SendMessage(hListBox, + LB_GETITEMDATA, + nItem, (LPARAM) 0); + if (g_hBmpPicture == g_hBmpStop) { + SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, + SERVICE_CONTROL_CONTINUE); + } + else { + SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, + SERVICE_CONTROL_STOP); + } + + } + return TRUE; + } + break; + + case IDOK: + EndDialog(hDlg, TRUE); + return TRUE; + + case IDC_SSTART: + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); + if (nItem != LB_ERR) { + SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, + SERVICE_CONTROL_CONTINUE); + } + Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE); + return TRUE; + + case IDC_SSTOP: + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); + if (nItem != LB_ERR) { + SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, + SERVICE_CONTROL_STOP); + } + Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE); + return TRUE; + + case IDC_SRESTART: + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); + if (nItem != LB_ERR) { + SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, + SERVICE_APACHE_RESTART); + } + Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE); + return TRUE; + + case IDC_SMANAGER: + if (g_dwOSVersion >= OS_VERSION_WIN2K) { + ShellExecute(hDlg, "open", "services.msc", "/s", + NULL, SW_NORMAL); + } + else { + WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL); + } + return TRUE; + + case IDC_SEXIT: + EndDialog(hDlg, TRUE); + SendMessage(g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0); + return TRUE; + + case IDC_SCONNECT: + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGCONNECT), + hDlg, (DLGPROC)ConnectDlgProc); + return TRUE; + + case IDC_SDISCONN: + hListBox = GetDlgItem(hDlg, IDL_SERVICES); + nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); + if (nItem != LB_ERR) { + am_DisconnectComputer(g_stServices[nItem].szComputerName); + SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0); + } + return TRUE; + } + break; + + case WM_SIZE: + switch (LOWORD(wParam)) + { + case SIZE_MINIMIZED: + EndDialog(hDlg, TRUE); + return TRUE; + break; + } + break; + + case WM_QUIT: + case WM_CLOSE: + EndDialog(hDlg, TRUE); + return TRUE; + + default: + return FALSE; + } + return FALSE; +} + + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + if (message == g_bUiTaskbarCreated) + { + /* restore the tray icon on shell restart */ + ShowNotifyIcon(hWnd, NIM_ADD); + return DefWindowProc(hWnd, message, wParam, lParam); + } + switch (message) + { + case WM_CREATE: + GetApacheServicesStatus(); + ShowNotifyIcon(hWnd, NIM_ADD); + SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL); + SetTimer(hWnd, WM_TIMER_RESCAN, RESCAN_TIME, NULL); + break; + + case WM_TIMER: + switch (wParam) + { + case WM_TIMER_RESCAN: + { + int nPrev = 0, nNew = 0; + EnterCriticalSection(&g_stcSection); + if (FindRunningServices() || g_bRescanServices) + { + ShowNotifyIcon(hWnd, NIM_MODIFY); + if (g_hwndServiceDlg) + PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); + } + /* check if services list changed */ + while (g_stServices[nPrev].szServiceName != NULL) + ++nPrev; + GetApacheServicesStatus(); + while (g_stServices[nNew].szServiceName != NULL) + ++nNew; + if (nPrev != nNew) + { + ShowNotifyIcon(hWnd, NIM_MODIFY); + if (g_hwndServiceDlg) { + PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); + } + } + LeaveCriticalSection(&g_stcSection); + break; + } + + case WM_TIMER_REFRESH: + { + int nPrev = 0, nNew = 0; + EnterCriticalSection(&g_stcSection); + if (g_bRescanServices) + { + GetApacheServicesStatus(); + ShowNotifyIcon(hWnd, NIM_MODIFY); + if (g_hwndServiceDlg) { + PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); + } + } + else if (FindRunningServices()) + { + ShowNotifyIcon(hWnd, NIM_MODIFY); + if (g_hwndServiceDlg) { + PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); + } + } + LeaveCriticalSection(&g_stcSection); + break; + } + } + break; + + case WM_QUIT: + ShowNotifyIcon(hWnd, NIM_DELETE); + break; + + case WM_TRAYMESSAGE: + switch (lParam) + { + case WM_LBUTTONDBLCLK: + if (!g_bDlgServiceOn) + { + g_bDlgServiceOn = TRUE; + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES), + hWnd, (DLGPROC)ServiceDlgProc); + g_bDlgServiceOn = FALSE; + g_hwndServiceDlg = NULL; + } + else if (IsWindow(g_hwndServiceDlg)) + { + /* Dirty hack to bring the window to the foreground */ + SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + SetFocus(g_hwndServiceDlg); + } + break; + + case WM_LBUTTONUP: + ShowTryServicesMenu(hWnd); + break; + + case WM_RBUTTONUP: + ShowTryPopupMenu(hWnd); + break; + } + break; + + case WM_COMMAND: + if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START) + { + ApacheManageService(g_stServices[LOWORD(wParam) + - IDM_SM_START].szServiceName, + g_stServices[LOWORD(wParam) + - IDM_SM_START].szImagePath, + g_stServices[LOWORD(wParam) + - IDM_SM_START].szComputerName, + SERVICE_CONTROL_CONTINUE); + return TRUE; + } + else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP) + { + ApacheManageService(g_stServices[LOWORD(wParam) + - IDM_SM_STOP].szServiceName, + g_stServices[LOWORD(wParam) + - IDM_SM_STOP].szImagePath, + g_stServices[LOWORD(wParam) + - IDM_SM_STOP].szComputerName, + SERVICE_CONTROL_STOP); + return TRUE; + } + else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART) + { + ApacheManageService(g_stServices[LOWORD(wParam) + - IDM_SM_RESTART].szServiceName, + g_stServices[LOWORD(wParam) + - IDM_SM_RESTART].szImagePath, + g_stServices[LOWORD(wParam) + - IDM_SM_RESTART].szComputerName, + SERVICE_APACHE_RESTART); + return TRUE; + } + switch (LOWORD(wParam)) + { + case IDM_RESTORE: + if (!g_bDlgServiceOn) + { + g_bDlgServiceOn = TRUE; + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES), + hWnd, (DLGPROC)ServiceDlgProc); + g_bDlgServiceOn = FALSE; + g_hwndServiceDlg = NULL; + } + else if (IsWindow(g_hwndServiceDlg)) { + SetFocus(g_hwndServiceDlg); + } + break; + + case IDC_SMANAGER: + if (g_dwOSVersion >= OS_VERSION_WIN2K) { + ShellExecute(NULL, "open", "services.msc", "/s", + NULL, SW_NORMAL); + } + else { + WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL); + } + return TRUE; + + case IDM_EXIT: + ShowNotifyIcon(hWnd, NIM_DELETE); + PostQuitMessage(0); + return TRUE; + } + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return FALSE; +} + + +/* Create main invisible window */ +HWND CreateMainWindow(HINSTANCE hInstance) +{ + HWND hWnd = NULL; + WNDCLASSEX wcex; + + if (!GetSystemOSVersion(&g_dwOSVersion)) + { + ErrorMessage(NULL, TRUE); + return hWnd; + } + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON), + IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + wcex.hCursor = g_hCursorArrow; + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = 0; + wcex.lpszClassName = g_szWindowClass; + wcex.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON), + IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + + if (RegisterClassEx(&wcex)) { + hWnd = CreateWindow(g_szWindowClass, g_szTitle, + 0, 0, 0, 0, 0, + NULL, NULL, hInstance, NULL); + } + return hWnd; + +} + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + CHAR szTmp[MAX_LOADSTRING]; + CHAR szCmp[MAX_COMPUTERNAME_LENGTH+4]; + MSG msg; + /* single instance mutex */ + HANDLE hMutex; + int i; + DWORD d; + + g_LangID = GetUserDefaultLangID(); + if ((g_LangID & 0xFF) != LANG_ENGLISH) { + g_LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + } + for (i = IDS_MSG_FIRST; i <= IDS_MSG_LAST; ++i) { + LoadString(hInstance, i, szTmp, MAX_LOADSTRING); + g_lpMsg[i - IDS_MSG_FIRST] = strdup(szTmp); + } + LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING); + d = MAX_COMPUTERNAME_LENGTH+1; + strcpy(szCmp, "\\\\"); + GetComputerName(szCmp + 2, &d); + strupr(szCmp); + g_szLocalHost = strdup(szCmp); + + memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS); + g_stComputers[0].szComputerName = strdup(szCmp); + g_stComputers[0].hRegistry = HKEY_LOCAL_MACHINE; + g_szTitle = strdup(szTmp); + LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING); + g_szWindowClass = strdup(szTmp); + + g_icoStop = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICOSTOP), + IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + g_icoRun = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICORUN), + IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + g_hCursorHourglass = LoadImage(NULL, MAKEINTRESOURCE(OCR_WAIT), + IMAGE_CURSOR, LR_DEFAULTSIZE, + LR_DEFAULTSIZE, LR_SHARED); + g_hCursorArrow = LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), + IMAGE_CURSOR, LR_DEFAULTSIZE, + LR_DEFAULTSIZE, LR_SHARED); + g_hBmpStart = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPRUN), + IMAGE_BITMAP, XBITMAP, YBITMAP, + LR_DEFAULTCOLOR); + g_hBmpStop = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPSTOP), + IMAGE_BITMAP, XBITMAP, YBITMAP, + LR_DEFAULTCOLOR); + + hMutex = CreateMutex(NULL, FALSE, "APSRVMON_MUTEX"); + if ((hMutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) + { + ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING - IDS_MSG_FIRST], FALSE); + if (hMutex) { + CloseHandle(hMutex); + } + return 0; + } + + memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES); + CoInitialize(NULL); + InitCommonControls(); + g_hInstance = hInstance; + g_hwndMain = CreateMainWindow(hInstance); + g_bUiTaskbarCreated = RegisterWindowMessage("TaskbarCreated"); + InitializeCriticalSection(&g_stcSection); + g_hwndServiceDlg = NULL; + if (g_hwndMain != NULL) + { + while (GetMessage(&msg, NULL, 0, 0) == TRUE) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + am_ClearServicesSt(); + } + am_ClearComputersSt(); + DeleteCriticalSection(&g_stcSection); + CloseHandle(hMutex); + DestroyIcon(g_icoStop); + DestroyIcon(g_icoRun); + DestroyCursor(g_hCursorHourglass); + DestroyCursor(g_hCursorArrow); + DeleteObject(g_hBmpStart); + DeleteObject(g_hBmpStop); + CoUninitialize(); + return 0; +} diff --git a/trunk/support/win32/ApacheMonitor.dsp b/trunk/support/win32/ApacheMonitor.dsp new file mode 100644 index 0000000000..14616aa991 --- /dev/null +++ b/trunk/support/win32/ApacheMonitor.dsp @@ -0,0 +1,131 @@ +# Microsoft Developer Studio Project File - Name="ApacheMonitor" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=ApacheMonitor - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ApacheMonitor.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ApacheMonitor.mak" CFG="ApacheMonitor - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ApacheMonitor - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "ApacheMonitor - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ApacheMonitor - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /Oy- /Zi /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /Fd"Release/ApacheMonitor_src" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /i "../../include" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "ApacheMonitor - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "STRICT" /Fd"Debug/ApacheMonitor_src" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /i "../../include" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib /nologo /subsystem:windows /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "ApacheMonitor - Win32 Release" +# Name "ApacheMonitor - Win32 Debug" +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\apache_header.bmp +# End Source File +# Begin Source File + +SOURCE=.\ApacheMonitor.ico +# End Source File +# Begin Source File + +SOURCE=.\aprun.ico +# End Source File +# Begin Source File + +SOURCE=.\apstop.ico +# End Source File +# Begin Source File + +SOURCE=.\srun.bmp +# End Source File +# Begin Source File + +SOURCE=.\sstop.bmp +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ApacheMonitor.c +# End Source File +# Begin Source File + +SOURCE=.\ApacheMonitor.h +# End Source File +# Begin Source File + +SOURCE=.\ApacheMonitor.rc +# End Source File +# End Target +# End Project diff --git a/trunk/support/win32/ApacheMonitor.h b/trunk/support/win32/ApacheMonitor.h new file mode 100644 index 0000000000..190295477d --- /dev/null +++ b/trunk/support/win32/ApacheMonitor.h @@ -0,0 +1,75 @@ +/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Resource definitions for ApacheMonitor.rc and ApacheMonitor.c + */ + +#define IDD_DLGSERVICES 101 +#define IDS_APMONITORTITLE 102 +#define IDS_APMONITORCLASS 103 +#define IDM_RESTORE 104 +#define IDM_EXIT 105 +#define IDI_APSRVMON 106 +#define IDI_ICOSTOP 107 +#define IDI_ICORUN 108 +#define IDC_STATBAR 109 +#define IDC_SSTATUS 110 +#define IDB_BMPSTOP 111 +#define IDB_BMPRUN 112 +#define IDB_BMPHEADER 114 +#define IDL_SERVICES 115 +#define IDL_STDOUT 116 +#define IDC_SSTART 117 +#define IDC_SSTOP 118 +#define IDC_SRESTART 119 +#define IDC_SEXIT 120 +#define IDC_SMANAGER 121 +#define IDD_DLGCONNECT 122 +#define IDC_LREMOTE 123 +#define IDC_LBROWSE 124 +#define IDC_COMPUTER 125 +#define IDC_SCONNECT 126 +#define IDC_SDISCONN 127 +#define IDS_MSG_FIRST 256 +#define IDS_MSG_APPRUNNING 256 +#define IDS_MSG_ERROR 257 +#define IDS_MSG_RUNNINGALL 258 +#define IDS_MSG_RUNNING 259 +#define IDS_MSG_RUNNINGNONE 260 +#define IDS_MSG_NOSERVICES 261 +#define IDS_MSG_MNUSERVICES 262 +#define IDS_MSG_MNUSHOW 263 +#define IDS_MSG_MNUEXIT 264 +#define IDS_MSG_SRVSTART 265 +#define IDS_MSG_SRVSTARTED 266 +#define IDS_MSG_SRVSTOP 267 +#define IDS_MSG_SRVSTOPPED 268 +#define IDS_MSG_SRVRESTART 269 +#define IDS_MSG_SRVRESTARTED 270 +#define IDS_MSG_SRVFAILED 271 +#define IDS_MSG_SSTART 272 +#define IDS_MSG_SSTOP 273 +#define IDS_MSG_SRESTART 274 +#define IDS_MSG_SERVICES 275 +#define IDS_MSG_CONNECT 276 +#define IDS_MSG_ECONNECT 277 +#define IDS_MSG_LAST 277 +#define IDM_SM_SERVICE 0x1100 +#define IDM_SM_START 0x1200 +#define IDM_SM_STOP 0x1400 +#define IDM_SM_RESTART 0x1800 +#define IDC_STATIC -1 + diff --git a/trunk/support/win32/ApacheMonitor.ico b/trunk/support/win32/ApacheMonitor.ico new file mode 100644 index 0000000000000000000000000000000000000000..cd28dc520c46b6b6bae3d12fd47d6084b98702e9 GIT binary patch literal 1078 zcma)5J&W5w5Pf^Ta8VOkW7=xeCBs zOkX@V68?4EFEE8_LWAu$Fh#A~G|P_sRkw+TN3Oc%4xY~?)a`M1}`TGP? zeHXso-&d-1V#WCP1hPu2Io~_)ZWAn4lQrE@S0OOGlEX_ucUt*}(Hxw+Ay1Q&Xk2ph z^k;qCjK#j-U%sBL{H(i|ccj*O>5qUUKfG&v{RC_Bf~P=~i*% z^! + +#include "ApacheMonitor.h" + +#include "ap_release.h" + +IDI_APSRVMON ICON DISCARDABLE "ApacheMonitor.ico" +IDI_ICOSTOP ICON DISCARDABLE "apstop.ico" +IDI_ICORUN ICON DISCARDABLE "aprun.ico" + +IDD_DLGSERVICES DIALOGEX 0, 0, 350, 188 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_MINIMIZEBOX | WS_VISIBLE | + WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Apache Service Monitor" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "&OK",IDOK,298,49,50,14 + LTEXT "Service St&atus :",IDC_SSTATUS,3,40,272,8 + LISTBOX IDL_SERVICES,2,49,285,73,LBS_OWNERDRAWFIXED | + LBS_HASSTRINGS | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | + LBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP + LISTBOX IDL_STDOUT,2,124,285,51,LBS_NOINTEGRALHEIGHT | + LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL + PUSHBUTTON "&Start",IDC_SSTART,298,65,50,14 + PUSHBUTTON "S&top",IDC_SSTOP,298,81,50,14 + PUSHBUTTON "&Restart",IDC_SRESTART,298,97,50,14 + PUSHBUTTON "Ser&vices",IDC_SMANAGER,298,113,50,14 + CONTROL IDB_BMPHEADER,IDC_STATIC,"Static",SS_BITMAP,0,0,349,38 + PUSHBUTTON "&Connect",IDC_SCONNECT,298,129,50,14 + PUSHBUTTON "&Disconnect",IDC_SDISCONN,298,145,50,14 + PUSHBUTTON "E&xit",IDC_SEXIT,298,161,50,14 +END + +IDD_DLGCONNECT DIALOGEX 0, 0, 240, 54 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_VISIBLE | WS_CLIPCHILDREN | + WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Connect To A Remote Computer" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Computer &Name:",IDC_LREMOTE,7,4,155,8 + EDITTEXT IDC_COMPUTER,7,14,169,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "&OK",IDOK,183,14,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,183,34,50,14 + PUSHBUTTON "&Browse",IDC_LBROWSE,7,34,50,14 +END + +IDB_BMPSTOP BITMAP DISCARDABLE "sstop.bmp" +IDB_BMPRUN BITMAP DISCARDABLE "srun.bmp" +IDB_BMPHEADER BITMAP DISCARDABLE "apache_header.bmp" + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APMONITORTITLE "Apache Service Monitor" + IDS_APMONITORCLASS "ApacheServiceMonitorClass" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_MSG_APPRUNNING "Apache monitor is already started" + IDS_MSG_ERROR "Error" + IDS_MSG_RUNNINGALL "Running all Apache services" + IDS_MSG_RUNNING "Running %d of %d Apache services" + IDS_MSG_RUNNINGNONE "Running none of %d Apache services" + IDS_MSG_NOSERVICES "No services installed" + IDS_MSG_MNUSERVICES "Open &Services" + IDS_MSG_MNUSHOW "&Open Apache Monitor" + IDS_MSG_MNUEXIT "E&xit" + IDS_MSG_SRVSTART "The %s service is starting." + IDS_MSG_SRVSTARTED "The %s service has started." + IDS_MSG_SRVSTOP "The %s service is stopping." + IDS_MSG_SRVSTOPPED "The %s service has stopped." + IDS_MSG_SRVRESTART "The %s service is restarting." + IDS_MSG_SRVRESTARTED "The %s service has restarted." + IDS_MSG_SRVFAILED "The requested operation has failed!" + IDS_MSG_SSTART "&Start" + IDS_MSG_SSTOP "S&top" + IDS_MSG_SRESTART "&Restart" + IDS_MSG_SERVICES "Ser&vices" + IDS_MSG_CONNECT "&Connect" + IDS_MSG_ECONNECT "Unable to connect to the remote registry on %s" +END + +1 VERSIONINFO + FILEVERSION AP_SERVER_PATCHLEVEL_CSV,0 + PRODUCTVERSION AP_SERVER_PATCHLEVEL_CSV,0 + FILEFLAGSMASK 0x3fL +#if defined(_DEBUG) + FILEFLAGS 0x03L +#else +#if AP_SERVER_DEVBUILD_BOOLEAN + FILEFLAGS 0x02L +#else + FILEFLAGS 0x0L +#endif +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this file except in compliance with the License. You may obtain a copy of the License at\r\n\r\nhttp://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an ""AS IS"" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\0" + VALUE "CompanyName", AP_SERVER_BASEVENDOR "\0" + VALUE "FileDescription", "Apache HTTP Server Monitor\0" + VALUE "FileVersion", AP_SERVER_BASEREVISION "\0" + VALUE "InternalName", "ApacheMonitor.exe\0" + VALUE "LegalCopyright", "Copyright 2001-2004 The Apache Software Foundation\0" + VALUE "OriginalFilename", "ApacheMonitor.exe\0" + VALUE "ProductName", "Apache HTTP Server\0" + VALUE "ProductVersion", AP_SERVER_BASEREVISION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/trunk/support/win32/apache_header.bmp b/trunk/support/win32/apache_header.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7340fac2acc7ba165617fa4e277abc3162e9d673 GIT binary patch literal 6498 zcmeHMORwu#R$klowiDZl<)ocGJB*yeP*G`Td@Aa*3ee1Dv zUw!y{ZBjpLgDA&4S0g&(RZs;7(S3{P#)ntMz9}qQO z+vz^C~4Eq#pN*RNmGn>TOh?OS}V@;RRS6s!FQ z-hUr!J;Tm3(d4^CS9sk$Q{&AiL~p)B^cJ6a^*y|QrdRYCj%Td)Jsf!E)6a-L!RP-S z#}{7`{pT~i1G;yx{tQ&l>h&$2`UJ;k^eL`<7q8Fs9r}X4kK-A?U(lE8^-Fs9?j3#p z`RDZfjP-u<^AiUCA2aX+`T;VSaQ?r(UX#)ANlHSsA<^X2Yg~PNdU~2`bs}%RSZo#&H~h_JzYoaA-R17E+lm?qX{^Y~ zP|wI2lbPFN(tEv>OcI*W6)vx@4{vX86Rdx2O{;gLKRi6p#m)`xHlF75dBfDmlmfpE z$)-%0+U)%%QL{Mg4qIPJU8+NuO=BfeNg_3J$0gYw_j(=JgCE^)ckm+?jVb9#l8_vc zRUeJ`-+SA)BpUX-x)23Ft6cK~BBR*t4(^U^zz4R0yDn_>z}k=V$(VjkahBq)JC_SF zv)-?_SzCp<6oC-RBdmMaSs9tT-DvXLgb3v5Jqs?rq$dq~FrL_*$)(Ph<~j5*0i zSb$^}!mqyYQP>cQzds(20ao|)?E$OfV_1B*l2m>1Ko`2kolKKmqw~X7nEk7(E0Wj3 zzSx=&Su+Iu5h{W$Xm}kpqS%)l8NIhMMDAksTs}(2O~H+e!?O5| z>*!9_c6B{=Ez$0DTqzw5R+>hNjCX`1Q*z?;@@rWdn1yGtK-QxkB*L)BO6)7rClmX< zwV3E$Llep0L5-`8so4|iUzE|)u4N%I`fVu4;; zhuPds;ZHVZn7BAjoqUy99sK10few#)u@j?$RNRhh^@lgrYCqPsJ{;=z#Xl>1h{KCh^_qE!?ojG}Um>3h!fnYO7+0irb_}j_g;TXpAyp3!43}8v%0dsKG zft%gfLh$15pku{@zTO#hL_Cc3n;R5x@sG+f^5idtSvTuW?yB7?uR)aXm5Sm#N#)ST~{_rpY6%V!g!$__VhpmH@T{$ql$|UNAzddYq zq#E;}uHoEV0#g%wfu5YX2N4|$l0cd5=xqSP;Q*L}XjJ>dVHIc+E$IuiDEgb1NH}JF zaz7%Y?xE3vsT8+K*mlkIMkCW-uaC$(AONb}*4Z5Pa&z3GFYc(t!P+T&ONQ$&@v$YL zlg%G#(YV^s4r z@-Q_^Sp*am>-AD@HftOke}4c`{_)7??cv~~#qFHs@enW=gb*=f)$qYk+B)7tL;4F0 z1PqZH4Eq&Ci424ON})hDbRdSBH@ZWMoftS@o7eYuci^NZu*Dc^5{0IArXoNV#<|1ZY$pfYF3>z|43ILV7V0w+FR$2Ud45G^W#pcOI81v zBroaVL7flN8u+M7)cmK%M@=>~jez7MO#>ERfS15uANPUW?AJaB*%gRI@Ls(|3KcoK z%vbUO8Hfo(7_(e^v5Um1+)fi=|An%T?macl8W7yqJitIHxSx1F%JE_`_kEl&Xv`M# z+2bQMv;>t-lTstUDC81s$m4OZ9}n9AhYx)?+k>x?n!|wuH7OrkTt6`3fPf)X&^M+w z{n?B4LaR?EbyOnGPE!EIYC;H=(k#tI0pU-93?{s2U zH~Patx7TS~C~b@?a}e0$5o*J#OC-U5;|D4*GYKq}$A+3u8pflcVbTpX&7T1XCSMLr zfUFI+$de?6NOv-47-)oCu)6)^HfjBl!Z0Z5E9X<|RGy=Htx_?JmflG#~E`GkC7B&-u~0wni9ve;Y-$bP?OY3#NEr%cAONZTw5DAPfC zI{l$SF)ium&aKckblpv}JO_2E?Kv60&144ahdn3YzL0!gBOr@8s|4z3K&A~23+$^} zmdjb;17(3~0p29e%k>V5NFhxH04dqk&DPhI^~aL*lhxtAK1CbXF(ITV>xe?iT?!SL ztKYFepMcs0@^pqoG&U48V1CA7fO(V+5TFsNTM7b-8Dh2HYdF^H1M)O0pokQD=bGRS zsx2}~5&n)s@Kn;3=fu!~Rq3G1CWt||!-EW}d=sE|yTIkTf9qh(-TOeI9OIIqRH`tj zJVEio{wW0mn~jDI5vDvO>6S}3vSY>UyPd98mgQM60#ls7sxT}{`tTe@W~E;>YSZcM z?XZga4Hht)07iMW87l6u}mn@Sz1{D%Y&1CymJf6E#eOny<}x@Z8A# zejDtMhkbC^F$>Lh&jpAup3mjUOY&%~?!3u=4PZg-z1i(jYf%WC&MAL&7}8TjJ!xdfohP$ zQFJ=40LbJ5!rl~|`ATr;5RWjaY1j?MT0_nk{<;XuGn{F8LYQ6{dGzbb-s_UAC;|}E zCL^J&g7Z~kRNye2V}Z3XRjqv1HcX=KsU#z0dP9i|Ayxz<)4{E&Y4b)|8YW@m>mi=r z={J;}ua)#uU=!D`kVRmTm5jXtwk4S5)yxFxa7{zs1cyxI#U;px>ll=SIl3+)o)k%V zCbIN>hWu_xNDpwRu|)bRMcX=4rMHo#s1;nUu=Ek#gL^4NhuqW_EKJqRHAF{*R!f8z zw0}_2^(hK9F8s(gWvaye`C4E2lmm2yRG1@MTHz*QRG*?`ps8i?WXUfmSYZ>hDuQPSw# z8kt&!X-xFE3lSm0q`P*HoNkDZh&Ym!M6*(E5${EdRf1zao7gd7&0I9(L<=Ot}hc2dDkc7UA3SjVZ^ zMQ9Zoj1W4Dr@#~dtp@A8S4I-y^UfiEZv{M;e0y6`Bl4>Kn|^HB>|9@uf#oLSB6~?Q zpn*J4EDm0YiWElX2_-ueyc-wd{42_@zbK{sKM({1dCS&L( zXj}I5rec&-4MP)U;Cwz)tt7L>|5tJPihAasN^(xED6(zybc#;sgJegZ2v1=do=;v$ z@`NvvTJ(YX^uOS)2AU%eW$fgaWSm3tenH*)9QV+%$`iuVYPCv%y!v@{=UTl`v4nBVUbH^n@&>XC20<{4z>Y{;0sbl5ZB#{ zAc(s+GrKd(0g5|{B1p{?FcD>lGi50F%z$zHk2sOgm_e9%WEfa$IUx5yBol*METL}& zM4fEu;PdK?fF6Yezk2%QWy%8(UKj2>^qVBv0p+rAU+0aJ(K>fpZJeN54N5_sy>y*D m)qdM!jvkuPGGg7qL#Hlib*$UKhou|NbjOimJthw^9lSU6pI$Bi literal 0 HcmV?d00001 diff --git a/trunk/support/win32/srun.bmp b/trunk/support/win32/srun.bmp new file mode 100644 index 0000000000000000000000000000000000000000..90ecd46f178a3444a81a1ef511b643d5b1400a3e GIT binary patch literal 246 zcmZupF%p0<2*W$~`V6=J!QJmT^PVn#p-=KUIJm?B?YT%B5(u#Ew?rJIl~_6^ncYy& ze~FHnszJ<@gi5WI2K)&q+xxh1{}np-1Z}0R)>Wr literal 0 HcmV?d00001 diff --git a/trunk/support/win32/sstop.bmp b/trunk/support/win32/sstop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ba73d87aecb8d15cf2270fa70d185c05e980234d GIT binary patch literal 246 zcmZ?r{l)+RWk5;;hy|dSk%0v)(Eui~5kMJ`WJ3dl0+K)`5H~O!IB) + * + * Note: this implementation is _very_ experimental, and error handling + * is far from complete. Using it as a cgi or pipe process allows the + * programmer to discover if facilities such as reliable piped logs + * are working as expected, or answer operator prompts that would + * otherwise be discarded by the service process. + * + * Also note the isservice detection semantics, which far exceed any + * mechanism we have discovered thus far. + * + * -------------------------------------------------------------------- + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +const char *options = +"\nwintty: a utility for echoing the stdin stream to a new console window,\n" +"\teven when invoked from within a service (such as the Apache server.)\n" +"\tAlso reflects the console input back to the stdout stream, allowing\n" +"\tthe operator to respond to prompts from the context of a service.\n\n" +"Syntax: %s [opts] [-t \"Window Title\"]\n\n" +" opts: -c{haracter} or -l{ine} input\n" +"\t-q{uiet} or -e{cho} input\n" +"\t-u{nprocessed} or -p{rocessed} input\n" +"\t-n{owrap} or -w{rap} output lines\n" +"\t-f{ormatted} or -r{aw} output lines\n" +"\t-O{output} [number of seconds]\n" +"\t-v{erbose} error reporting (for debugging)\n" +"\t-? for this message\n\n"; + +BOOL verbose = FALSE; + +void printerr(char *fmt, ...) +{ + char str[1024]; + va_list args; + if (!verbose) + return; + va_start(args, fmt); + wvsprintf(str, fmt, args); + OutputDebugString(str); +} + +DWORD WINAPI feedback(LPVOID args); + +typedef struct feedback_args_t { + HANDLE in; + HANDLE out; +} feedback_args_t; + +int main(int argc, char** argv) +{ + char str[1024], *contitle = NULL; + HANDLE hproc, thread; + HANDLE hwinsta = NULL, hsavewinsta; + HANDLE hdesk = NULL, hsavedesk = NULL; + HANDLE conin, conout; + HANDLE hstdin, hstdout, hstderr, hdup; + feedback_args_t feed; + DWORD conmode; + DWORD newinmode = 0, notinmode = 0; + DWORD newoutmode = 0, notoutmode = 0; + DWORD tid; + DWORD len; + DWORD timeout = INFINITE; + BOOL isservice = FALSE; + char *arg0 = argv[0]; + + while (--argc) { + ++argv; + if (**argv == '/' || **argv == '-') { + switch (tolower((*argv)[1])) { + case 'c': + notinmode |= ENABLE_LINE_INPUT; break; + case 'l': + newinmode |= ENABLE_LINE_INPUT; break; + case 'q': + notinmode |= ENABLE_ECHO_INPUT; break; + case 'e': + newinmode |= ENABLE_ECHO_INPUT; break; + case 'u': + notinmode |= ENABLE_PROCESSED_INPUT; break; + case 'p': + newinmode |= ENABLE_PROCESSED_INPUT; break; + case 'n': + notoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break; + case 'w': + newoutmode |= ENABLE_WRAP_AT_EOL_OUTPUT; break; + case 'r': + notoutmode |= ENABLE_PROCESSED_OUTPUT; break; + case 'f': + newoutmode |= ENABLE_PROCESSED_OUTPUT; break; + case 'o': + if (*(argv + 1) && *(argv + 1)[0] != '-') { + *(++argv); + timeout = atoi(*argv) / 1000; + --argc; + } + else { + timeout = 0; + } + break; + case 'v': + verbose = TRUE; + break; + case 't': + contitle = *(++argv); + --argc; + break; + case '?': + printf(options, arg0); + exit(1); + default: + printf("wintty option %s not recognized, use -? for help.\n\n", *argv); + exit(1); + } + } + else { + printf("wintty argument %s not understood, use -? for help.\n\n", *argv); + exit(1); + } + } + + hproc = GetCurrentProcess(); + hsavewinsta = GetProcessWindowStation(); + if (!hsavewinsta || hsavewinsta == INVALID_HANDLE_VALUE) { + printerr("GetProcessWindowStation() failed (%d)\n", GetLastError()); + } + else if (!GetUserObjectInformation(hsavewinsta, UOI_NAME, str, sizeof(str), &len)) { + printerr("GetUserObjectInfoformation(hWinSta) failed (%d)\n", GetLastError()); + } + else if (strnicmp(str, "Service-", 8) == 0) { + printerr("WindowStation Name %s is a service\n", str); + isservice = TRUE; + } + SetLastError(0); + + hstdin = GetStdHandle(STD_INPUT_HANDLE); + if (!hstdin || hstdin == INVALID_HANDLE_VALUE) { + printerr("GetStdHandle(STD_INPUT_HANDLE) failed (%d)\n", + GetLastError()); + } + else if (DuplicateHandle(hproc, hstdin, hproc, &hdup, 0, + isservice, DUPLICATE_SAME_ACCESS)) { + CloseHandle(hstdin); + hstdin = hdup; + } + else { + printerr("DupHandle(stdin [%x]) failed (%d)\n", + hstdin, GetLastError()); + } + + hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (!hstdout || hstdout == INVALID_HANDLE_VALUE) { + printerr("GetStdHandle(STD_OUTPUT_HANDLE) failed (%d)\n", + GetLastError()); + } + else if (DuplicateHandle(hproc, hstdout, hproc, &hdup, 0, + isservice, DUPLICATE_SAME_ACCESS)) { + CloseHandle(hstdout); + hstdout = hdup; + } + else { + printerr("DupHandle(stdout [%x]) failed (%d)\n", + hstdout, GetLastError()); + } + + hstderr = GetStdHandle(STD_ERROR_HANDLE); + if (!hstderr || hstderr == INVALID_HANDLE_VALUE) { + printerr("GetStdHandle(STD_ERROR_HANDLE) failed (%d)\n", + GetLastError()); + } + else if (DuplicateHandle(hproc, hstderr, hproc, &hdup, 0, + isservice, DUPLICATE_SAME_ACCESS)) { + CloseHandle(hstderr); + hstderr = hdup; + } + else { + printerr("DupHandle(stderr [%x]) failed (%d)\n", + hstderr, GetLastError()); + } + + /* You can't close the console till all the handles above were + * rescued by DuplicateHandle() + */ + if (!FreeConsole()) + printerr("FreeConsole() failed (%d)\n", GetLastError()); + + if (isservice) { +#ifdef WE_EVER_FIGURE_OUT_WHY_THIS_DOESNT_WORK + hsavedesk = GetThreadDesktop(GetCurrentThreadId()); + if (!hsavedesk || hsavedesk == INVALID_HANDLE_VALUE) { + printerr("GetThreadDesktop(GetTID()) failed (%d)\n", GetLastError()); + } + CloseWindowStation(hwinsta); + hwinsta = OpenWindowStation("WinSta0", TRUE, MAXIMUM_ALLOWED); + if (!hwinsta || hwinsta == INVALID_HANDLE_VALUE) { + printerr("OpenWinSta(WinSta0) failed (%d)\n", GetLastError()); + } + else if (!SetProcessWindowStation(hwinsta)) { + printerr("SetProcWinSta(WinSta0) failed (%d)\n", GetLastError()); + } + hdesk = OpenDesktop("Default", 0, TRUE, MAXIMUM_ALLOWED); + if (!hdesk || hdesk == INVALID_HANDLE_VALUE) { + printerr("OpenDesktop(Default) failed (%d)\n", GetLastError()); + } + else if (!SetThreadDesktop(hdesk)) { + printerr("SetThreadDesktop(Default) failed (%d)\n", GetLastError()); + } +#else + PROCESS_INFORMATION pi; + STARTUPINFO si; + DWORD exitcode = 1; + char appbuff[MAX_PATH]; + char *appname = NULL; + char *cmdline = GetCommandLine(); + + if (!GetModuleFileName(NULL, appbuff, sizeof(appbuff))) { + appname = appbuff; + } + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW + | STARTF_USESTDHANDLES; + si.lpDesktop = "WinSta0\\Default"; + si.wShowWindow = 1; /* SW_SHOWNORMAL */ + si.hStdInput = hstdin; + si.hStdOutput = hstdout; + si.hStdError = hstderr; + + /* Instantly, upon creating the new process, we will close our + * copies of the handles so our parent isn't confused when the + * child closes their copy of the handle. Without this action, + * we would hold a copy of the handle, and the parent would not + * receive their EOF notification. + */ + if (CreateProcess(appname, cmdline, NULL, NULL, TRUE, + CREATE_SUSPENDED | CREATE_NEW_CONSOLE, + NULL, NULL, &si, &pi)) { + CloseHandle(si.hStdInput); + CloseHandle(si.hStdOutput); + CloseHandle(si.hStdError); + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &exitcode); + CloseHandle(pi.hProcess); + return exitcode; + } + return 1; +#endif + } + + if (!AllocConsole()) { + printerr("AllocConsole(Default) failed (%d)\n", GetLastError()); + } + + if (contitle && !SetConsoleTitle(contitle)) { + printerr("SetConsoleTitle() failed (%d)\n", GetLastError()); + } + + conout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FALSE, OPEN_EXISTING, 0, NULL); + if (!conout || conout == INVALID_HANDLE_VALUE) { + printerr("CreateFile(CONOUT$) failed (%d)\n", GetLastError()); + } + else if (!GetConsoleMode(conout, &conmode)) { + printerr("GetConsoleMode(CONOUT) failed (%d)\n", GetLastError()); + } + else if (!SetConsoleMode(conout, conmode = ((conmode | newoutmode) + & ~notoutmode))) { + printerr("SetConsoleMode(CONOUT, 0x%x) failed (%d)\n", + conmode, GetLastError()); + } + + conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FALSE, OPEN_EXISTING, 0, NULL); + if (!conin || conin == INVALID_HANDLE_VALUE) { + printerr("CreateFile(CONIN$) failed (%d)\n", GetLastError()); + } + else if (!GetConsoleMode(conin, &conmode)) { + printerr("GetConsoleMode(CONIN) failed (%d)\n", GetLastError()); + } + else if (!SetConsoleMode(conin, conmode = ((conmode | newinmode) + & ~notinmode))) { + printerr("SetConsoleMode(CONIN, 0x%x) failed (%d)\n", + conmode, GetLastError()); + } + + feed.in = conin; + feed.out = hstdout; + thread = CreateThread(NULL, 0, feedback, (LPVOID)&feed, 0, &tid); + + while (ReadFile(hstdin, str, sizeof(str), &len, NULL)) + if (!len || !WriteFile(conout, str, len, &len, NULL)) + break; + + printerr("[EOF] from stdin (%d)\n", GetLastError()); + + CloseHandle(stdout); + if (!GetConsoleTitle(str, sizeof(str))) { + printerr("SetConsoleTitle() failed (%d)\n", GetLastError()); + } + else { + strcat(str, " - [Finished]"); + if (!SetConsoleTitle(str)) { + printerr("SetConsoleTitle() failed (%d)\n", GetLastError()); + } + } + + WaitForSingleObject(thread, timeout); + FreeConsole(); + if (isservice) { + if (!SetProcessWindowStation(hsavewinsta)) { + len = GetLastError(); + } + if (!SetThreadDesktop(hsavedesk)) { + len = GetLastError(); + } + CloseDesktop(hdesk); + CloseWindowStation(hwinsta); + } + return 0; +} + + +DWORD WINAPI feedback(LPVOID arg) +{ + feedback_args_t *feed = (feedback_args_t*)arg; + char *str[1024]; + DWORD len; + + while (ReadFile(feed->in, str, sizeof(str), &len, NULL)) + if (!len || !WriteFile(feed->out, str, len, &len, NULL)) + break; + + printerr("[EOF] from Console (%d)\n", GetLastError()); + + return 0; +} diff --git a/trunk/support/win32/wintty.dsp b/trunk/support/win32/wintty.dsp new file mode 100644 index 0000000000..a6926fe421 --- /dev/null +++ b/trunk/support/win32/wintty.dsp @@ -0,0 +1,123 @@ +# Microsoft Developer Studio Project File - Name="wintty" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=wintty - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "wintty.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "wintty.mak" CFG="wintty - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "wintty - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "wintty - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "wintty - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Release/wintty_src" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref + +!ELSEIF "$(CFG)" == "wintty - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../srclib/apr/include" /I "../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /Fd"Debug/wintty_src" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "wintty - Win32 Release" +# Name "wintty - Win32 Debug" +# Begin Source File + +SOURCE=..\..\build\win32\win32ver.awk + +!IF "$(CFG)" == "wintty - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\wintty.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk wintty.exe "wintty Console Utility" ../../include/ap_release.h > .\wintty.rc + +# End Custom Build + +!ELSEIF "$(CFG)" == "wintty - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Creating Version Resource +InputPath=..\..\build\win32\win32ver.awk + +".\wintty.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + awk -f ../../build/win32/win32ver.awk wintty.exe "wintty Console Utility" ../../include/ap_release.h > .\wintty.rc + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\wintty.c +# End Source File +# Begin Source File + +SOURCE=.\wintty.rc +# End Source File +# End Target +# End Project diff --git a/trunk/test/.indent.pro b/trunk/test/.indent.pro new file mode 100644 index 0000000000..a9fbe9f9a1 --- /dev/null +++ b/trunk/test/.indent.pro @@ -0,0 +1,54 @@ +-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 +-TBUFF +-TFILE +-TTRANS +-TUINT4 +-T_trans +-Tallow_options_t +-Tapache_sfio +-Tarray_header +-Tbool_int +-Tbuf_area +-Tbuff_struct +-Tbuffy +-Tcmd_how +-Tcmd_parms +-Tcommand_rec +-Tcommand_struct +-Tconn_rec +-Tcore_dir_config +-Tcore_server_config +-Tdir_maker_func +-Tevent +-Tglobals_s +-Thandler_func +-Thandler_rec +-Tjoblist_s +-Tlisten_rec +-Tmerger_func +-Tmode_t +-Tmodule +-Tmodule_struct +-Tmutex +-Tn_long +-Tother_child_rec +-Toverrides_t +-Tparent_score +-Tpid_t +-Tpiped_log +-Tpool +-Trequest_rec +-Trequire_line +-Trlim_t +-Tscoreboard +-Tsemaphore +-Tserver_addr_rec +-Tserver_rec +-Tserver_rec_chain +-Tshort_score +-Ttable +-Ttable_entry +-Tthread +-Tu_wide_int +-Tvtime_t +-Twide_int diff --git a/trunk/test/Makefile.in b/trunk/test/Makefile.in new file mode 100644 index 0000000000..6d83405477 --- /dev/null +++ b/trunk/test/Makefile.in @@ -0,0 +1,20 @@ + +# no targets: we don't want to build anything by default. if you want the +# test programs, then "make test" +TARGETS = + +PROGRAMS = + +PROGRAM_LDADD = $(EXTRA_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) +PROGRAM_DEPENDENCIES = \ + $(top_srcdir)/srclib/apr-util/libaprutil.la \ + $(top_srcdir)/srclib/apr/libapr.la + +include $(top_builddir)/build/rules.mk + +test: $(PROGRAMS) + +# example for building a test proggie +# dbu_OBJECTS = dbu.lo +# dbu: $(dbu_OBJECTS) +# $(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD) diff --git a/trunk/test/README b/trunk/test/README new file mode 100644 index 0000000000..9f8be502b8 --- /dev/null +++ b/trunk/test/README @@ -0,0 +1,3 @@ +This directory contains useful test code for testing various bits +of Apache functionality. This stuff is for the developers only, +so we might remove it on public releases. diff --git a/trunk/test/check_chunked b/trunk/test/check_chunked new file mode 100644 index 0000000000..7dc5fa287d --- /dev/null +++ b/trunk/test/check_chunked @@ -0,0 +1,57 @@ +#!/usr/bin/perl -w +# +# Copyright 2000-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# This is meant to be used on the raw output of an HTTP/1.1 connection +# to check that the chunks are all correctly laid out. It's easiest +# to use a tool like netcat to generate the output. This script +# *insists* that \r exist in the output. +# +# You can find netcat at avian.org:/src/hacks/nc110.tgz. + +use strict; + +my $is_chunked = 0; + +# must toss headers +while(<>) { + if (/^Transfer-Encoding:\s+chunked/i) { + $is_chunked = 1; + } + last if ($_ eq "\r\n"); +} + +$is_chunked || die "wasn't chunked\n"; + +for(;;) { + $_ = <> || die "unexpected end of file!\n"; + + m#^([0-9a-f]+) *\r$#i || die "bogus chunklen: $_"; + + my $chunklen = hex($1); + + exit 0 if ($chunklen == 0); + + chop; chop; + print "$_ "; + + my $data = ''; + read(ARGV, $data, $chunklen) == $chunklen || die "short read!\n"; + + $_ = <> || die "unexpected end of file!\n"; + + $_ eq "\r\n" || die "missing chunk trailer!\n"; +} diff --git a/trunk/test/cls.c b/trunk/test/cls.c new file mode 100644 index 0000000000..f2b0192929 --- /dev/null +++ b/trunk/test/cls.c @@ -0,0 +1,182 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +/* + * Compare a string to a mask + * Mask characters: + * @ - uppercase letter + * # - lowercase letter + * & - hex digit + * # - digit + * * - swallow remaining characters + * - exact match for any other character + */ +static int checkmask(const char *data, const char *mask) +{ + int i, ch, d; + + for (i = 0; mask[i] != '\0' && mask[i] != '*'; i++) { + ch = mask[i]; + d = data[i]; + if (ch == '@') { + if (!isupper(d)) + return 0; + } + else if (ch == '$') { + if (!islower(d)) + return 0; + } + else if (ch == '#') { + if (!isdigit(d)) + return 0; + } + else if (ch == '&') { + if (!isxdigit(d)) + return 0; + } + else if (ch != d) + return 0; + } + + if (mask[i] == '*') + return 1; + else + return (data[i] == '\0'); +} + +/* + * Converts 8 hex digits to a time integer + */ +static int hex2sec(const char *x) +{ + int i, ch; + unsigned int j; + + for (i = 0, j = 0; i < 8; i++) { + ch = x[i]; + j <<= 4; + if (isdigit(ch)) + j |= ch - '0'; + else if (isupper(ch)) + j |= ch - ('A' - 10); + else + j |= ch - ('a' - 10); + } + if (j == 0xffffffff) + return -1; /* so that it works with 8-byte ints */ + else + return j; +} + +int main(int argc, char **argv) +{ + int i, ver; + DIR *d; + struct dirent *e; + const char *s; + FILE *fp; + char path[FILENAME_MAX + 1]; + char line[1035]; + time_t date, lmod, expire; + unsigned int len; + struct tm ts; + char sdate[30], slmod[30], sexpire[30]; + const char time_format[] = "%e %b %Y %R"; + + if (argc != 2) { + printf("Usage: cls directory\n"); + exit(0); + } + + d = opendir(argv[1]); + if (d == NULL) { + perror("opendir"); + exit(1); + } + + for (;;) { + e = readdir(d); + if (e == NULL) + break; + s = e->d_name; + if (s[0] == '.' || s[0] == '#') + continue; + sprintf(path, "%s/%s", argv[1], s); + fp = fopen(path, "r"); + if (fp == NULL) { + perror("fopen"); + continue; + } + if (fgets(line, 1034, fp) == NULL) { + perror("fgets"); + fclose(fp); + continue; + } + if (!checkmask(line, "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&\n")) { + fprintf(stderr, "Bad cache file\n"); + fclose(fp); + continue; + } + date = hex2sec(line); + lmod = hex2sec(line + 9); + expire = hex2sec(line + 18); + ver = hex2sec(line + 27); + len = hex2sec(line + 35); + if (fgets(line, 1034, fp) == NULL) { + perror("fgets"); + fclose(fp); + continue; + } + fclose(fp); + i = strlen(line); + if (strncmp(line, "X-URL: ", 7) != 0 || line[i - 1] != '\n') { + fprintf(stderr, "Bad cache file\n"); + continue; + } + line[i - 1] = '\0'; + if (date != -1) { + ts = *gmtime(&date); + strftime(sdate, 30, time_format, &ts); + } + else + strcpy(sdate, "-"); + + if (lmod != -1) { + ts = *gmtime(&lmod); + strftime(slmod, 30, time_format, &ts); + } + else + strcpy(slmod, "-"); + + if (expire != -1) { + ts = *gmtime(&expire); + strftime(sexpire, 30, time_format, &ts); + } + else + strcpy(sexpire, "-"); + + printf("%s: %d; %s %s %s\n", line + 7, ver, sdate, slmod, sexpire); + } + + closedir(d); + return 0; +} diff --git a/trunk/test/tcpdumpscii.txt b/trunk/test/tcpdumpscii.txt new file mode 100644 index 0000000000..9c1060edab --- /dev/null +++ b/trunk/test/tcpdumpscii.txt @@ -0,0 +1,50 @@ + +From marcs@znep.com Fri Apr 17 15:16:16 1998 +Date: Sat, 22 Nov 1997 20:44:10 -0700 (MST) +From: Marc Slemko +To: TLOSAP +Subject: Re: Getting ethernet packets content under FreeBSD? (fwd) +Reply-To: new-httpd@apache.org + +Anyone too lazy to hack tcpdump (eg. my tcpdump has a -X option to display +the data in ASCII) can use something like the below to grab HTTP headers +when debugging broken clients. + +Nothing complicated, but handy. + +---------- Forwarded message ---------- +Date: Sat, 22 Nov 1997 14:35:23 PST +From: Bill Fenner +To: Nate Williams +Cc: bmah@ca.sandia.gov, hackers@FreeBSD.ORG +Subject: Re: Getting ethernet packets content under FreeBSD? + +I usually just use this perl script, which I call "tcpdumpscii". +Then run "tcpdumpscii -s 1500 -x [other tcpdump args]". + + Bill + +#!/import/misc/bin/perl +# +# +open(TCPDUMP,"tcpdump -l @ARGV|"); +while () { + if (/^\s+(\S\S)+/) { + $sav = $_; + $asc = ""; + while (s/\s*(\S\S)\s*//) { + $i = hex($1); + if ($i < 32 || $i > 126) { + $asc .= "."; + } else { + $asc .= pack(C,hex($1)); + } + } + $foo = "." x length($asc); + $_ = $sav; + s/\t/ /g; + s/^$foo/$asc/; + } + print; +} + diff --git a/trunk/test/test-writev.c b/trunk/test/test-writev.c new file mode 100644 index 0000000000..072689a3c5 --- /dev/null +++ b/trunk/test/test-writev.c @@ -0,0 +1,101 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + test-writev: use this to figure out if your writev() does intelligent + things on the network. Some writev()s when given multiple buffers + will break them up into multiple packets, which is a waste. + + Linux prior to 2.0.31 has this problem. + + Solaris 2.5, 2.5.1 doesn't appear to, 2.6 hasn't been tested. + + IRIX 5.3 doesn't have this problem. + + To use this you want to snoop the wire with tcpdump, and then run + "test-writev a.b.c.d port#" ... against some TCP service on another + box. For example you can run it against port 80 on another server. + You want to look to see how many data packets are sent, you're hoping + only one of size 300 is sent. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef INADDR_NONE +#define INADDR_NONE (-1ul) +#endif + +void main( int argc, char **argv ) +{ + struct sockaddr_in server_addr; + int s; + struct iovec vector[3]; + char buf[100]; + int i; + const int just_say_no = 1; + + if( argc != 3 ) { +usage: + fprintf( stderr, "usage: test-writev a.b.c.d port#\n" ); + exit( 1 ); + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr( argv[1] ); + if( server_addr.sin_addr.s_addr == INADDR_NONE ) { + fprintf( stderr, "bogus address\n" ); + goto usage; + } + server_addr.sin_port = htons( atoi( argv[2] ) ); + + s = socket( AF_INET, SOCK_STREAM, 0 ); + if( s < 0 ) { + perror("socket"); + exit(1); + } + if( connect( s, (struct sockaddr *)&server_addr, sizeof( server_addr ) ) + != 0 ) { + perror("connect"); + exit(1); + } + + if( setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&just_say_no, + sizeof(just_say_no)) != 0 ) { + perror( "TCP_NODELAY" ); + exit(1); + } + /* now build up a two part writev and write it out */ + for( i = 0; i < sizeof( buf ); ++i ) { + buf[i] = 'x'; + } + vector[0].iov_base = buf; + vector[0].iov_len = sizeof(buf); + vector[1].iov_base = buf; + vector[1].iov_len = sizeof(buf); + vector[2].iov_base = buf; + vector[2].iov_len = sizeof(buf); + + i = writev( s, &vector[0], 3 ); + fprintf( stdout, "i=%d, errno=%d\n", i, errno ); + exit(0); +} diff --git a/trunk/test/test_find.c b/trunk/test/test_find.c new file mode 100644 index 0000000000..1c4346dc58 --- /dev/null +++ b/trunk/test/test_find.c @@ -0,0 +1,78 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This program tests the ap_find_list_item routine in ../main/util.c. + * + * The defines in this sample compile line are specific to Roy's system. + * They should match whatever was used to compile Apache first. + * + gcc -g -O2 -I../os/unix -I../include -o test_find \ + -DSOLARIS2=250 -Wall -DALLOC_DEBUG -DPOOL_DEBUG \ + ../main/alloc.o ../main/buff.o ../main/util.o \ + ../ap/libap.a -lsocket -lnsl test_find.c + * + * Roy Fielding, 1999 + */ +#include +#include +#include "httpd.h" +#include "apr_general.h" + +/* + * Dummy a bunch of stuff just to get a compile + */ +uid_t ap_user_id; +gid_t ap_group_id; +void *ap_dummy_mutex = &ap_dummy_mutex; +char *ap_server_argv0; + +AP_DECLARE(void) ap_block_alarms(void) +{ + ; +} + +AP_DECLARE(void) ap_unblock_alarms(void) +{ + ; +} + +AP_DECLARE(void) ap_log_error(const char *file, int line, int level, + const request_rec *r, const char *fmt, ...) +{ + ; +} + +int main (void) +{ + apr_pool_t *p; + char line[512]; + char tok[512]; + + p = apr_pool_alloc_init(); + + printf("Enter field value to find items within:\n"); + if (!gets(line)) + exit(0); + + printf("Enter search item:\n"); + while (gets(tok)) { + printf(" [%s] == %s\n", tok, ap_find_list_item(p, line, tok) + ? "Yes" : "No"); + printf("Enter search item:\n"); + } + + exit(0); +} diff --git a/trunk/test/test_limits.c b/trunk/test/test_limits.c new file mode 100644 index 0000000000..8dca825b21 --- /dev/null +++ b/trunk/test/test_limits.c @@ -0,0 +1,200 @@ +/************************************************************** + * test_limits.c + * + * A simple program for sending abusive requests to a server, based + * on the sioux.c exploit code that this nimrod posted (see below). + * Roy added options for testing long header fieldsize (-t h), long + * request-lines (-t r), and a long request body (-t b). + * + * FreeBSD 2.2.x, FreeBSD 3.0, IRIX 5.3, IRIX 6.2: + * gcc -o test_limits test_limits.c + * + * Solaris 2.5.1: + * gcc -o test_limits test_limits.c -lsocket -lnsl + * + * + * Message-ID: <861zqspvtw.fsf@niobe.ewox.org> + * Date: Fri, 7 Aug 1998 19:04:27 +0200 + * Sender: Bugtraq List + * From: Dag-Erling Coidan =?ISO-8859-1?Q?Sm=F8rgrav?= + * Subject: YA Apache DoS attack + * + * Copyright (c) 1998 Dag-Erling Codan Smrgrav + * 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 + * in this position and unchanged. + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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. + * + */ + +/* + * Kudos to Mark Huizer who originally suggested this on freebsd-current + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define TEST_LONG_REQUEST_LINE 1 +#define TEST_LONG_REQUEST_FIELDS 2 +#define TEST_LONG_REQUEST_FIELDSIZE 3 +#define TEST_LONG_REQUEST_BODY 4 + +void +usage(void) +{ + fprintf(stderr, + "usage: test_limits [-t (r|n|h|b)] [-a address] [-p port] [-n num]\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct sockaddr_in sin; + struct hostent *he; + FILE *f; + int o, sd; + + /* default parameters */ + char *addr = "localhost"; + int port = 80; + int num = 1000; + int testtype = TEST_LONG_REQUEST_FIELDS; + + /* get options */ + while ((o = getopt(argc, argv, "t:a:p:n:")) != EOF) + switch (o) { + case 't': + if (*optarg == 'r') + testtype = TEST_LONG_REQUEST_LINE; + else if (*optarg == 'n') + testtype = TEST_LONG_REQUEST_FIELDS; + else if (*optarg == 'h') + testtype = TEST_LONG_REQUEST_FIELDSIZE; + else if (*optarg == 'b') + testtype = TEST_LONG_REQUEST_BODY; + break; + case 'a': + addr = optarg; + break; + case 'p': + port = atoi(optarg); + break; + case 'n': + num = atoi(optarg); + break; + default: + usage(); + } + + if (argc != optind) + usage(); + + /* connect */ + if ((he = gethostbyname(addr)) == NULL) { + perror("gethostbyname"); + exit(1); + } + bzero(&sin, sizeof(sin)); + bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); + sin.sin_family = he->h_addrtype; + sin.sin_port = htons(port); + + if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { + perror("socket"); + exit(1); + } + + if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + perror("connect"); + exit(1); + } + + if ((f = fdopen(sd, "r+")) == NULL) { + perror("fdopen"); + exit(1); + } + + /* attack! */ + fprintf(stderr, "Testing like a plague of locusts on %s\n", addr); + + if (testtype == TEST_LONG_REQUEST_LINE) { + fprintf(f, "GET "); + while (num-- && !ferror(f)) { + fprintf(f, "/123456789"); + fflush(f); + } + fprintf(f, " HTTP/1.0\r\n\r\n"); + } + else { + fprintf(f, "GET /fred/foo HTTP/1.0\r\n"); + + if (testtype == TEST_LONG_REQUEST_FIELDSIZE) { + while (num-- && !ferror(f)) { + fprintf(f, "User-Agent: sioux"); + fflush(f); + } + fprintf(f, "\r\n"); + } + else if (testtype == TEST_LONG_REQUEST_FIELDS) { + while (num-- && !ferror(f)) + fprintf(f, "User-Agent: sioux\r\n"); + fprintf(f, "\r\n"); + } + else if (testtype == TEST_LONG_REQUEST_BODY) { + fprintf(f, "User-Agent: sioux\r\n"); + fprintf(f, "Content-Length: 33554433\r\n"); + fprintf(f, "\r\n"); + while (num-- && !ferror(f)) + fprintf(f, "User-Agent: sioux\r\n"); + } + else { + fprintf(f, "\r\n"); + } + } + fflush(f); + + { + apr_ssize_t len; + char buff[512]; + + while ((len = read(sd, buff, 512)) > 0) + len = write(1, buff, len); + } + if (ferror(f)) { + perror("fprintf"); + exit(1); + } + + fclose(f); + exit(0); +} diff --git a/trunk/test/test_parser.c b/trunk/test/test_parser.c new file mode 100644 index 0000000000..a7a4a740a6 --- /dev/null +++ b/trunk/test/test_parser.c @@ -0,0 +1,75 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This program tests the ap_get_list_item routine in ../main/util.c. + * + * The defines in this sample compile line are specific to Roy's system. + * They should match whatever was used to compile Apache first. + * + gcc -g -O2 -I../os/unix -I../include -o test_parser \ + -DSOLARIS2=250 -Wall -DALLOC_DEBUG -DPOOL_DEBUG \ + ../main/alloc.o ../main/buff.o ../main/util.o \ + ../ap/libap.a -lsocket -lnsl test_parser.c + * + * Roy Fielding, 1999 + */ +#include +#include +#include "httpd.h" +#include "apr_general.h" + +/* + * Dummy a bunch of stuff just to get a compile + */ +uid_t ap_user_id; +gid_t ap_group_id; +void *ap_dummy_mutex = &ap_dummy_mutex; +char *ap_server_argv0; + +AP_DECLARE(void) ap_block_alarms(void) +{ + ; +} + +AP_DECLARE(void) ap_unblock_alarms(void) +{ + ; +} + +AP_DECLARE(void) ap_log_error(const char *file, int line, int level, + const request_rec *r, const char *fmt, ...) +{ + ; +} + +int main (void) +{ + apr_pool_t *p; + const char *field; + char *newstr; + char instr[512]; + + p = apr_pool_alloc_init(); + + while (gets(instr)) { + printf(" [%s] ==\n", instr); + field = instr; + while ((newstr = ap_get_list_item(p, &field)) != NULL) + printf(" <%s> ..\n", newstr); + } + + exit(0); +} diff --git a/trunk/test/test_select.c b/trunk/test/test_select.c new file mode 100644 index 0000000000..c0c5adc566 --- /dev/null +++ b/trunk/test/test_select.c @@ -0,0 +1,46 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This is just a quick test program to see how long a wait is + * produced by a select loop with an exponential backoff. + * + * gcc -g -O2 -o test_select test_select.c + * test_select + * + * Roy Fielding, 1996 + */ + +#include +#include +#include + +int main (void) +{ + int srv; + long waittime = 4096; + struct timeval tv; + + printf("Start\n"); + while ((waittime > 0) && (waittime < 3000000)) { + printf("%d\n", waittime); + tv.tv_sec = waittime/1000000; + tv.tv_usec = waittime%1000000; + waittime <<= 1; + srv = select(0, NULL, NULL, NULL, &tv); + } + printf("End\n"); + exit(0); +} diff --git a/trunk/test/time-sem.c b/trunk/test/time-sem.c new file mode 100644 index 0000000000..6f6e5da556 --- /dev/null +++ b/trunk/test/time-sem.c @@ -0,0 +1,591 @@ +/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +time-sem.c has the basics of the semaphores we use in http_main.c. It's +intended for timing differences between various methods on an +architecture. In practice we've found many things affect which semaphore +to be used: + + - NFS filesystems absolutely suck for fcntl() and flock() + + - uslock absolutely sucks on single-processor IRIX boxes, but + absolutely rocks on multi-processor boxes. The converse + is true for fcntl. sysvsem seems a moderate balance. + + - Under Solaris you can't have too many processes use SEM_UNDO, there + might be a tuneable somewhere that increases the limit from 29. + We're not sure what the tunable is, so there's a define + NO_SEM_UNDO which can be used to simulate us trapping/blocking + signals to be able to properly release the semaphore on a clean + child death. You'll also need to define NEED_UNION_SEMUN + under solaris. + +You'll need to define USE_SHMGET_SCOREBOARD if anonymous shared mmap() +doesn't work on your system (i.e. linux). + +argv[1] is the #children, argv[2] is the #iterations per child + +You should run each over many different #children inputs, and choose +#iter such that the program runs for at least a second or so... or even +longer depending on your patience. + +compile with: + +gcc -o time-FCNTL -Wall -O time-sem.c -DUSE_FCNTL_SERIALIZED_ACCEPT +gcc -o time-FLOCK -Wall -O time-sem.c -DUSE_FLOCK_SERIALIZED_ACCEPT +gcc -o time-SYSVSEM -Wall -O time-sem.c -DUSE_SYSVSEM_SERIALIZED_ACCEPT +gcc -o time-SYSVSEM2 -Wall -O time-sem.c -DUSE_SYSVSEM_SERIALIZED_ACCEPT -DNO_SEM_UNDO +gcc -o time-PTHREAD -Wall -O time-sem.c -DUSE_PTHREAD_SERIALIZED_ACCEPT -lpthread +gcc -o time-USLOCK -Wall -O time-sem.c -DUSE_USLOCK_SERIALIZED_ACCEPT + +not all versions work on all systems. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(USE_FCNTL_SERIALIZED_ACCEPT) + +static struct flock lock_it; +static struct flock unlock_it; + +static int fcntl_fd=-1; + +#define accept_mutex_child_init() +#define accept_mutex_cleanup() + +/* + * Initialize mutex lock. + * Must be safe to call this on a restart. + */ +void +accept_mutex_init(void) +{ + + lock_it.l_whence = SEEK_SET; /* from current point */ + lock_it.l_start = 0; /* -"- */ + lock_it.l_len = 0; /* until end of file */ + lock_it.l_type = F_WRLCK; /* set exclusive/write lock */ + lock_it.l_pid = 0; /* pid not actually interesting */ + unlock_it.l_whence = SEEK_SET; /* from current point */ + unlock_it.l_start = 0; /* -"- */ + unlock_it.l_len = 0; /* until end of file */ + unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */ + unlock_it.l_pid = 0; /* pid not actually interesting */ + + printf("opening test-lock-thing in current directory\n"); + fcntl_fd = open("test-lock-thing", O_CREAT | O_WRONLY | O_EXCL, 0644); + if (fcntl_fd == -1) + { + perror ("open"); + fprintf (stderr, "Cannot open lock file: %s\n", "test-lock-thing"); + exit (1); + } + unlink("test-lock-thing"); +} + +void accept_mutex_on(void) +{ + int ret; + + while ((ret = fcntl(fcntl_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR) + continue; + + if (ret < 0) { + perror ("fcntl lock_it"); + exit(1); + } +} + +void accept_mutex_off(void) +{ + if (fcntl (fcntl_fd, F_SETLKW, &unlock_it) < 0) + { + perror ("fcntl unlock_it"); + exit(1); + } +} + +#elif defined(USE_FLOCK_SERIALIZED_ACCEPT) + +#include + +static int flock_fd=-1; + +#define FNAME "test-lock-thing" + +/* + * Initialize mutex lock. + * Must be safe to call this on a restart. + */ +void accept_mutex_init(void) +{ + + printf("opening " FNAME " in current directory\n"); + flock_fd = open(FNAME, O_CREAT | O_WRONLY | O_EXCL, 0644); + if (flock_fd == -1) + { + perror ("open"); + fprintf (stderr, "Cannot open lock file: %s\n", "test-lock-thing"); + exit (1); + } +} + +void accept_mutex_child_init(void) +{ + flock_fd = open(FNAME, O_WRONLY, 0600); + if (flock_fd == -1) { + perror("open"); + exit(1); + } +} + +void accept_mutex_cleanup(void) +{ + unlink(FNAME); +} + +void accept_mutex_on(void) +{ + int ret; + + while ((ret = flock(flock_fd, LOCK_EX)) < 0 && errno == EINTR) + continue; + + if (ret < 0) { + perror ("flock(LOCK_EX)"); + exit(1); + } +} + +void accept_mutex_off(void) +{ + if (flock (flock_fd, LOCK_UN) < 0) + { + perror ("flock(LOCK_UN)"); + exit(1); + } +} + +#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) + +#include +#include +#include + +static int sem_id = -1; +#ifdef NO_SEM_UNDO +static sigset_t accept_block_mask; +static sigset_t accept_previous_mask; +#endif + +#define accept_mutex_child_init() +#define accept_mutex_cleanup() + +void accept_mutex_init(void) +{ +#ifdef NEED_UNION_SEMUN + /* believe it or not, you need to define this under solaris */ + union semun { + int val; + struct semid_ds *buf; + ushort *array; + }; +#endif + + union semun ick; + + sem_id = semget(999, 1, IPC_CREAT | 0666); + if (sem_id < 0) { + perror ("semget"); + exit (1); + } + ick.val = 1; + if (semctl(sem_id, 0, SETVAL, ick) < 0) { + perror ("semctl"); + exit(1); + } +#ifdef NO_SEM_UNDO + sigfillset(&accept_block_mask); + sigdelset(&accept_block_mask, SIGHUP); + sigdelset(&accept_block_mask, SIGTERM); + sigdelset(&accept_block_mask, SIGUSR1); +#endif +} + +void accept_mutex_on() +{ + struct sembuf op; + +#ifdef NO_SEM_UNDO + if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { + perror("sigprocmask(SIG_BLOCK)"); + exit (1); + } + op.sem_flg = 0; +#else + op.sem_flg = SEM_UNDO; +#endif + op.sem_num = 0; + op.sem_op = -1; + if (semop(sem_id, &op, 1) < 0) { + perror ("accept_mutex_on"); + exit (1); + } +} + +void accept_mutex_off() +{ + struct sembuf op; + + op.sem_num = 0; + op.sem_op = 1; +#ifdef NO_SEM_UNDO + op.sem_flg = 0; +#else + op.sem_flg = SEM_UNDO; +#endif + if (semop(sem_id, &op, 1) < 0) { + perror ("accept_mutex_off"); + exit (1); + } +#ifdef NO_SEM_UNDO + if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { + perror("sigprocmask(SIG_SETMASK)"); + exit (1); + } +#endif +} + +#elif defined (USE_PTHREAD_SERIALIZED_ACCEPT) + +/* note: pthread mutexes aren't released on child death, hence the + * signal goop ... in a real implementation we'd do special things + * during hup, term, usr1. + */ + +#include + +static pthread_mutex_t *mutex; +static sigset_t accept_block_mask; +static sigset_t accept_previous_mask; + +#define accept_mutex_child_init() +#define accept_mutex_cleanup() + +void accept_mutex_init(void) +{ + pthread_mutexattr_t mattr; + int fd; + + fd = open ("/dev/zero", O_RDWR); + if (fd == -1) { + perror ("open(/dev/zero)"); + exit (1); + } + mutex = (pthread_mutex_t *)mmap ((caddr_t)0, sizeof (*mutex), + PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (mutex == (void *)(caddr_t)-1) { + perror ("mmap"); + exit (1); + } + close (fd); + if (pthread_mutexattr_init(&mattr)) { + perror ("pthread_mutexattr_init"); + exit (1); + } + if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) { + perror ("pthread_mutexattr_setpshared"); + exit (1); + } + if (pthread_mutex_init(mutex, &mattr)) { + perror ("pthread_mutex_init"); + exit (1); + } + sigfillset(&accept_block_mask); + sigdelset(&accept_block_mask, SIGHUP); + sigdelset(&accept_block_mask, SIGTERM); + sigdelset(&accept_block_mask, SIGUSR1); +} + +void accept_mutex_on() +{ + if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { + perror("sigprocmask(SIG_BLOCK)"); + exit (1); + } + if (pthread_mutex_lock (mutex)) { + perror ("pthread_mutex_lock"); + exit (1); + } +} + +void accept_mutex_off() +{ + if (pthread_mutex_unlock (mutex)) { + perror ("pthread_mutex_unlock"); + exit (1); + } + if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { + perror("sigprocmask(SIG_SETMASK)"); + exit (1); + } +} + +#elif defined (USE_USLOCK_SERIALIZED_ACCEPT) + +#include + +static usptr_t *us = NULL; +static ulock_t uslock = NULL; + +#define accept_mutex_child_init() +#define accept_mutex_cleanup() + +void accept_mutex_init(void) +{ + ptrdiff_t old; + /* default is 8 */ +#define CONF_INITUSERS_MAX 15 + if ((old = usconfig(CONF_INITUSERS, CONF_INITUSERS_MAX)) == -1) { + perror("usconfig"); + exit(-1); + } + if ((old = usconfig(CONF_LOCKTYPE, US_NODEBUG)) == -1) { + perror("usconfig"); + exit(-1); + } + if ((old = usconfig(CONF_ARENATYPE, US_SHAREDONLY)) == -1) { + perror("usconfig"); + exit(-1); + } + if ((us = usinit("/dev/zero")) == NULL) { + perror("usinit"); + exit(-1); + } + if ((uslock = usnewlock(us)) == NULL) { + perror("usnewlock"); + exit(-1); + } +} +void accept_mutex_on() +{ + switch(ussetlock(uslock)) { + case 1: + /* got lock */ + break; + case 0: + fprintf(stderr, "didn't get lock\n"); + exit(-1); + case -1: + perror("ussetlock"); + exit(-1); + } +} +void accept_mutex_off() +{ + if (usunsetlock(uslock) == -1) { + perror("usunsetlock"); + exit(-1); + } +} +#endif + + +#ifndef USE_SHMGET_SCOREBOARD +static void *get_shared_mem(apr_size_t size) +{ + void *result; + + /* allocate shared memory for the shared_counter */ + result = (unsigned long *)mmap ((caddr_t)0, size, + PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); + if (result == (void *)(caddr_t)-1) { + perror ("mmap"); + exit (1); + } + return result; +} +#else +#include +#include +#ifdef HAVE_SYS_MUTEX_H +#include +#endif +#include + +static void *get_shared_mem(apr_size_t size) +{ + key_t shmkey = IPC_PRIVATE; + int shmid = -1; + void *result; +#ifdef MOVEBREAK + char *obrk; +#endif + + if ((shmid = shmget(shmkey, size, IPC_CREAT | SHM_R | SHM_W)) == -1) { + perror("shmget"); + exit(1); + } + +#ifdef MOVEBREAK + /* + * Some SysV systems place the shared segment WAY too close + * to the dynamic memory break point (sbrk(0)). This severely + * limits the use of malloc/sbrk in the program since sbrk will + * refuse to move past that point. + * + * To get around this, we move the break point "way up there", + * attach the segment and then move break back down. Ugly + */ + if ((obrk = sbrk(MOVEBREAK)) == (char *) -1) { + perror("sbrk"); + } +#endif + +#define BADSHMAT ((void *)(-1)) + if ((result = shmat(shmid, 0, 0)) == BADSHMAT) { + perror("shmat"); + } + /* + * We must avoid leaving segments in the kernel's + * (small) tables. + */ + if (shmctl(shmid, IPC_RMID, NULL) != 0) { + perror("shmctl(IPC_RMID)"); + } + if (result == BADSHMAT) /* now bailout */ + exit(1); + +#ifdef MOVEBREAK + if (obrk == (char *) -1) + return; /* nothing else to do */ + if (sbrk(-(MOVEBREAK)) == (char *) -1) { + perror("sbrk 2"); + } +#endif + return result; +} +#endif + +#ifdef _POSIX_PRIORITY_SCHEDULING +/* don't ask */ +#define _P __P +#include +#define YIELD sched_yield() +#else +#define YIELD do { struct timeval zero; zero.tv_sec = zero.tv_usec = 0; select(0,0,0,0,&zero); } while(0) +#endif + +void main (int argc, char **argv) +{ + int num_iter; + int num_child; + int i; + struct timeval first; + struct timeval last; + long ms; + int pid; + unsigned long *shared_counter; + + if (argc != 3) { + fprintf (stderr, "Usage: time-sem num-child num iter\n"); + exit (1); + } + + num_child = atoi (argv[1]); + num_iter = atoi (argv[2]); + + /* allocate shared memory for the shared_counter */ + shared_counter = get_shared_mem(sizeof(*shared_counter)); + + /* initialize counter to 0 */ + *shared_counter = 0; + + accept_mutex_init (); + + /* parent grabs mutex until done spawning children */ + accept_mutex_on (); + + for (i = 0; i < num_child; ++i) { + pid = fork(); + if (pid == 0) { + /* child, do our thing */ + accept_mutex_child_init(); + for (i = 0; i < num_iter; ++i) { + unsigned long tmp; + + accept_mutex_on (); + tmp = *shared_counter; + YIELD; + *shared_counter = tmp + 1; + accept_mutex_off (); + } + exit (0); + } else if (pid == -1) { + perror ("fork"); + exit (1); + } + } + + /* a quick test to see that nothing is screwed up */ + if (*shared_counter != 0) { + puts ("WTF! shared_counter != 0 before the children have been started!"); + exit (1); + } + + gettimeofday (&first, NULL); + /* launch children into action */ + accept_mutex_off (); + for (i = 0; i < num_child; ++i) { + if (wait(NULL) == -1) { + perror ("wait"); + } + } + gettimeofday (&last, NULL); + + if (*shared_counter != num_child * num_iter) { + printf ("WTF! shared_counter != num_child * num_iter!\n" + "shared_counter = %lu\nnum_child = %d\nnum_iter=%d\n", + *shared_counter, + num_child, num_iter); + } + + last.tv_sec -= first.tv_sec; + ms = last.tv_usec - first.tv_usec; + if (ms < 0) { + --last.tv_sec; + ms += 1000000; + } + last.tv_usec = ms; + printf ("%8lu.%06lu\n", last.tv_sec, last.tv_usec); + + accept_mutex_cleanup(); + + exit(0); +} + diff --git a/trunk/test/zb.c b/trunk/test/zb.c new file mode 100644 index 0000000000..93a6f6a9cb --- /dev/null +++ b/trunk/test/zb.c @@ -0,0 +1,567 @@ + +/* ZeusBench V1.01 + =============== + +This program is Copyright (C) Zeus Technology Limited 1996. + +This program may be used and copied freely providing this copyright notice +is not removed. + +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. + + Written by Adam Twiss (adam@zeus.co.uk). March 1996 + +Thanks to the following people for their input: + Mike Belshe (mbelshe@netscape.com) + Michael Campanella (campanella@stevms.enet.dec.com) + +*/ + +/* -------------------- Notes on compiling ------------------------------ + +This should compile unmodified using gcc on HP-UX, FreeBSD, Linux, +IRIX, Solaris, AIX and Digital Unix (OSF). On Solaris 2.x you will +need to compile with "-lnsl -lsocket" options. If you have any +difficulties compiling then let me know. + +On SunOS 4.x.x you may need to compile with -DSUNOS4 to add the following +two lines of code which appear not to exist in my SunOS headers */ + +#ifdef SUNOS4 +extern char *optarg; +extern int optind, opterr, optopt; +#endif + +/* -------------------------------------------------------------------- */ + +/* affects include files on Solaris */ +#define BSD_COMP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ------------------- DEFINITIONS -------------------------- */ + +/* maximum number of requests on a time limited test */ +#define MAX_REQUESTS 50000 + +/* good old state machine */ +#define STATE_UNCONNECTED 0 +#define STATE_CONNECTING 1 +#define STATE_READ 2 + +#define CBUFFSIZE 512 + +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 */ + 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 */ +}; + +#define min(a,b) ((a)<(b))?(a):(b) +#define max(a,b) ((a)>(b))?(a):(b) + +/* --------------------- GLOBALS ---------------------------- */ + +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 *machine; /* Machine name */ +char *file; /* file name to use */ +char server_name[80]; /* name that server reports */ +int port = 80; /* port to use */ + +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 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; + +struct timeval start, endtime; + +/* global request (and its length) */ +char request[512]; +int reqlen; + +/* one global throw-away buffer to read stuff into */ +char buffer[4096]; + +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 */ + +/* --------------------------------------------------------- */ + +/* simple little function to perror and exit */ + +static void err(char *s) +{ + perror(s); + exit(errno); +} + +/* --------------------------------------------------------- */ + +/* write out request to a connection - assumes we can write + (small) request out in one go into our new socket buffer */ + +void write_request(struct connection *c) +{ + gettimeofday(&c->connect,0); + write(c->fd,request, reqlen); + c->state = STATE_READ; + FD_SET(c->fd, &readbits); + FD_CLR(c->fd, &writebits); +} + +/* --------------------------------------------------------- */ + +/* make an fd non blocking */ + +void nonblock(int fd) +{ + int i=1; + ioctl(fd, FIONBIO, &i); +} + +/* --------------------------------------------------------- */ + +/* returns the time in ms between two timevals */ + +int timedif(struct timeval a, struct timeval b) +{ + register int us,s; + + us = a.tv_usec - b.tv_usec; + us /= 1000; + s = a.tv_sec - b.tv_sec; + s *= 1000; + return s+us; +} + +/* --------------------------------------------------------- */ + +/* calculate and output results and exit */ + +void output_results() +{ + int timetaken; + + gettimeofday(&endtime,0); + timetaken = timedif(endtime, start); + + printf("\n---\n"); + printf("Server: %s\n", server_name); + printf("Document Length: %d\n", doclen); + printf("Concurency Level: %d\n", concurrency); + printf("Time taken for tests: %d.%03d seconds\n", + 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); + if(keepalive) printf("Keep-Alive requests: %d\n", doneka); + printf("Bytes transferred: %d\n", totalread); + printf("HTML transferred: %d\n", totalbread); + + /* avoid divide by zero */ + if(timetaken) { + printf("Requests per seconds: %.2f\n", 1000*(float)(done)/timetaken); + printf("Transfer rate: %.2f kb/s\n", + (float)(totalread)/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; iread = 0; + c->bread = 0; + c->keepalive = 0; + c->cbx = 0; + c->gotheader = 0; + + c->fd = socket(AF_INET, SOCK_STREAM, 0); + if(c->fd<0) 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) { + printf("\nTest aborted after 10 failures\n\n"); + exit(1); + } + start_connect(c); + } + } + + /* connected first time */ + write_request(c); +} + +/* --------------------------------------------------------- */ + +/* close down connection and save stats */ + +void close_connection(struct connection *c) +{ + if(c->read == 0 && c->keepalive) { + /* server has legitiamately 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; + } + } + + close(c->fd); + FD_CLR(c->fd, &readbits); + FD_CLR(c->fd, &writebits); + + /* connect again */ + start_connect(c); + return; +} + +/* --------------------------------------------------------- */ + +/* read data from connection */ + +void read_connection(struct connection *c) +{ + int r; + + r=read(c->fd,buffer,sizeof(buffer)); + if(r==0 || (r<0 && errno!=EAGAIN)) { + good++; + close_connection(c); + return; + } + + if(r<0 && errno==EAGAIN) 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 = (spacecbuff+c->cbx, buffer, space); + c->cbx += tocopy; space -= tocopy; + c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ + 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) { + printf("\nTest aborted after 10 failures\n\n"); + exit(1); + } + 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 = server_name; + if(p) { p+=8; while(*p>32) *q++ = *p++; } + *q = 0; + } + + 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:"); + /* for cacky servers like NCSA which break the spec and send a + lower case 'l' */ + 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; + } + + 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 */ + } +} + +/* --------------------------------------------------------- */ + +/* run the tests */ + +int test() +{ + struct timeval timeout, now; + fd_set sel_read, sel_except, sel_write; + int i; + + { + /* get server information */ + struct hostent *he; + he = gethostbyname(machine); + if (!he) err("gethostbyname"); + 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)); + memset(con,0,concurrency*sizeof(struct connection)); + + stats = malloc(requests * sizeof(struct data)); + + FD_ZERO(&readbits); + FD_ZERO(&writebits); + + /* setup request */ + sprintf(request,"GET %s HTTP/1.0\r\nUser-Agent: ZeusBench/1.0\r\n" + "%sHost: %s\r\nAccept: */*\r\n\r\n", file, + keepalive?"Connection: Keep-Alive\r\n":"", machine ); + + reqlen = strlen(request); + + /* ok - lets start */ + gettimeofday(&start,0); + + /* initialise lots of requests */ + for(i=0; i (tlimit*1000)) { + requests=done; /* so stats are correct */ + output_results(); + } + + /* Timeout of 30 seconds. */ + timeout.tv_sec=30; timeout.tv_usec=0; + n=select(256, &sel_read, &sel_write, &sel_except, &timeout); + if(!n) { + printf("\nServer timed out\n\n"); + exit(1); + } + if(n<1) err("select"); + + for(i=0; i=requests) output_results(); + } + return 0; +} + +/* ------------------------------------------------------- */ + +/* display usage information */ + +void usage(char *progname) { + printf("\nZeusBench v1.0\n\n"); + printf("Usage: %s [-k] [-n requests | -t timelimit (sec)]" + "\n\t\t[-c concurrency] [-p port] \n",progname); + printf("Filename should start with a '/' e.g. /index.html\n\n"); + exit(EINVAL); +} + +/* ------------------------------------------------------- */ + +/* sort out command-line args and call test */ + +int main(int argc, char **argv) { + int c; + if (argc < 3) usage(argv[0]); + + machine = argv[1]; + file = argv[2]; + optind = 3; + while ((c = getopt(argc,argv,"p:n:c:d:t:d:k"))>0) { + switch(c) { + case 'd': + break; + case 'n': + requests = atoi(optarg); + if(!requests) { + printf("Invalid number of requests\n"); + exit(1); + } + break; + case 'k': + keepalive=1; + break; + case 'c': + concurrency = atoi(optarg); + break; + case 'p': + port = atoi(optarg); + break; + case 't': + tlimit = atoi(optarg); + requests = MAX_REQUESTS; /* need to size data array on something */ + break; + default: + usage(argv[0]); + break; + } + } + test(); + return 0; +} + + + + + + -- GitLab